diff --git a/OpenDSSC/.clang-format b/OpenDSSC/.clang-format new file mode 100644 index 0000000..2103f9a --- /dev/null +++ b/OpenDSSC/.clang-format @@ -0,0 +1,12 @@ +Language: Cpp +BasedOnStyle: "Webkit" +UseTab: Never +IndentWidth: 4 +BreakBeforeBraces: Allman +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: false +ColumnLimit: 0 +BreakInheritanceList: BeforeColon +BreakConstructorInitializers: AfterColon +SpacesInAngles: Never +#InsertTrailingCommas: Wrapped diff --git a/OpenDSSC/.vs/CMake Overview b/OpenDSSC/.vs/CMake Overview new file mode 100644 index 0000000..e69de29 diff --git a/OpenDSSC/.vs/ProjectSettings.json b/OpenDSSC/.vs/ProjectSettings.json new file mode 100644 index 0000000..18596cd --- /dev/null +++ b/OpenDSSC/.vs/ProjectSettings.json @@ -0,0 +1,3 @@ +{ + "CurrentProjectSetting": "Windows x64 Release" +} \ No newline at end of file diff --git a/OpenDSSC/.vs/VSWorkspaceState.json b/OpenDSSC/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..6a6cb67 --- /dev/null +++ b/OpenDSSC/.vs/VSWorkspaceState.json @@ -0,0 +1,13 @@ +{ + "OutputFoldersPerTargetSystem": { + "Local Machine": [ + "out\\build\\windows-default", + "out\\install\\windows-default" + ] + }, + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\CMakeLists.txt", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/OpenDSSC/.vs/VersionC/FileContentIndex/5f1dd722-323a-47d6-a7ca-80175c6b6c7b.vsidx b/OpenDSSC/.vs/VersionC/FileContentIndex/5f1dd722-323a-47d6-a7ca-80175c6b6c7b.vsidx new file mode 100644 index 0000000..ffc64a3 Binary files /dev/null and b/OpenDSSC/.vs/VersionC/FileContentIndex/5f1dd722-323a-47d6-a7ca-80175c6b6c7b.vsidx differ diff --git a/OpenDSSC/.vs/VersionC/FileContentIndex/c895c19d-f563-4325-82a1-cd4b535f63ed.vsidx b/OpenDSSC/.vs/VersionC/FileContentIndex/c895c19d-f563-4325-82a1-cd4b535f63ed.vsidx new file mode 100644 index 0000000..4465986 Binary files /dev/null and b/OpenDSSC/.vs/VersionC/FileContentIndex/c895c19d-f563-4325-82a1-cd4b535f63ed.vsidx differ diff --git a/OpenDSSC/.vs/VersionC/v17/.wsuo b/OpenDSSC/.vs/VersionC/v17/.wsuo new file mode 100644 index 0000000..4e582a6 Binary files /dev/null and b/OpenDSSC/.vs/VersionC/v17/.wsuo differ diff --git a/OpenDSSC/.vs/VersionC/v17/Browse.VC.db b/OpenDSSC/.vs/VersionC/v17/Browse.VC.db new file mode 100644 index 0000000..472603e Binary files /dev/null and b/OpenDSSC/.vs/VersionC/v17/Browse.VC.db differ diff --git a/OpenDSSC/.vs/VersionC/v17/DocumentLayout.backup.json b/OpenDSSC/.vs/VersionC/v17/DocumentLayout.backup.json new file mode 100644 index 0000000..dc9198d --- /dev/null +++ b/OpenDSSC/.vs/VersionC/v17/DocumentLayout.backup.json @@ -0,0 +1,70 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\OpenDSS_rep\\VersionC\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\OpenDSS_rep\\VersionC\\CMakePresets.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:CMakePresets.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:CMakeLists.txt||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|CMake Overview Pages||{B1CAA5B0-FEB1-4350-8AB9-F895876842F2}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "CMakePresets.json", + "DocumentMoniker": "C:\\OpenDSS_rep\\VersionC\\CMakePresets.json", + "RelativeDocumentMoniker": "CMakePresets.json", + "ToolTip": "C:\\OpenDSS_rep\\VersionC\\CMakePresets.json", + "RelativeToolTip": "CMakePresets.json", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAsAAAAzAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2024-09-13T14:25:30.543Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "CMakeLists.txt", + "DocumentMoniker": "C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt", + "RelativeDocumentMoniker": "CMakeLists.txt", + "ToolTip": "C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt", + "RelativeToolTip": "CMakeLists.txt", + "ViewState": "AgIAAAYAAAAAAAAAAAAAABoAAAAYAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|", + "WhenOpened": "2024-09-03T12:38:00.586Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "CMake Overview Pages", + "DocumentMoniker": "CMake Overview Pages", + "ToolTip": "CMake Overview Pages", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|", + "WhenOpened": "2024-09-03T12:37:51.237Z" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/OpenDSSC/.vs/VersionC/v17/DocumentLayout.json b/OpenDSSC/.vs/VersionC/v17/DocumentLayout.json new file mode 100644 index 0000000..dc9198d --- /dev/null +++ b/OpenDSSC/.vs/VersionC/v17/DocumentLayout.json @@ -0,0 +1,70 @@ +{ + "Version": 1, + "WorkspaceRootPath": "C:\\OpenDSS_rep\\VersionC\\", + "Documents": [ + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\OpenDSS_rep\\VersionC\\CMakePresets.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:CMakePresets.json||{90A6B3A7-C1A3-4009-A288-E2FF89E96FA0}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt||{8B382828-6202-11D1-8870-0000F87579D2}", + "RelativeMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|solutionrelative:CMakeLists.txt||{8B382828-6202-11D1-8870-0000F87579D2}" + }, + { + "AbsoluteMoniker": "D:0:0:{A2FE74E1-B743-11D0-AE1A-00A0C90FFFC3}|\u003CMiscFiles\u003E|CMake Overview Pages||{B1CAA5B0-FEB1-4350-8AB9-F895876842F2}" + } + ], + "DocumentGroupContainers": [ + { + "Orientation": 0, + "VerticalTabListWidth": 256, + "DocumentGroups": [ + { + "DockedWidth": 200, + "SelectedChildIndex": 0, + "Children": [ + { + "$type": "Document", + "DocumentIndex": 0, + "Title": "CMakePresets.json", + "DocumentMoniker": "C:\\OpenDSS_rep\\VersionC\\CMakePresets.json", + "RelativeDocumentMoniker": "CMakePresets.json", + "ToolTip": "C:\\OpenDSS_rep\\VersionC\\CMakePresets.json", + "RelativeToolTip": "CMakePresets.json", + "ViewState": "AgIAAAAAAAAAAAAAAAAAAAsAAAAzAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001642|", + "WhenOpened": "2024-09-13T14:25:30.543Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "CMakeLists.txt", + "DocumentMoniker": "C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt", + "RelativeDocumentMoniker": "CMakeLists.txt", + "ToolTip": "C:\\OpenDSS_rep\\VersionC\\CMakeLists.txt", + "RelativeToolTip": "CMakeLists.txt", + "ViewState": "AgIAAAYAAAAAAAAAAAAAABoAAAAYAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.003109|", + "WhenOpened": "2024-09-03T12:38:00.586Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "CMake Overview Pages", + "DocumentMoniker": "CMake Overview Pages", + "ToolTip": "CMake Overview Pages", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.001001|", + "WhenOpened": "2024-09-03T12:37:51.237Z" + }, + { + "$type": "Bookmark", + "Name": "ST:0:0:{cce594b6-0c39-4442-ba28-10c64ac7e89f}" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/OpenDSSC/.vs/VersionC/v17/workspaceFileList.bin b/OpenDSSC/.vs/VersionC/v17/workspaceFileList.bin new file mode 100644 index 0000000..ec3a785 Binary files /dev/null and b/OpenDSSC/.vs/VersionC/v17/workspaceFileList.bin differ diff --git a/OpenDSSC/.vs/cmake.db b/OpenDSSC/.vs/cmake.db new file mode 100644 index 0000000..7200834 Binary files /dev/null and b/OpenDSSC/.vs/cmake.db differ diff --git a/OpenDSSC/.vs/slnx.sqlite b/OpenDSSC/.vs/slnx.sqlite new file mode 100644 index 0000000..2cd023e Binary files /dev/null and b/OpenDSSC/.vs/slnx.sqlite differ diff --git a/OpenDSSC/CMD/OpenDSSC.cpp b/OpenDSSC/CMD/OpenDSSC.cpp new file mode 100644 index 0000000..a38b064 --- /dev/null +++ b/OpenDSSC/CMD/OpenDSSC.cpp @@ -0,0 +1,486 @@ +// OpenDSSX.cpp : Defines the entry point for the application. +// + +#pragma hdrstop + +#include +#include "OpenDSSC.h" +#include +#include +#include +#include +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "Arraydef.h" +#include "Command.h" +#include "HashList.h" +#include "PointerList.h" +#include "RPN.h" +#include "ParserDel.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "CktElement.h" +#include "CktElementClass.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Bus.h" +#include "klusolve.h" +#include "PCClass.h" +#include "PCElement.h" +#include "PDClass.h" +#include "PDElement.h" +#include "CktTree.h" +#include "Pstcalc.h" +#include "StackDef.h" +#include "Terminal.h" +#include "mathutil.h" + +#include "XYcurve.h" +#include "XfmrCode.h" +#include "WireData.h" +#include "TSLineConstants.h" +#include "CNData.h" +#include "TSData.h" +#include "TempShape.h" +#include "TCC_Curve.h" +#include "Spectrum.h" +#include "PriceShape.h" +#include "OHLineConstants.h" +#include "NamedObject.h" +#include "LoadShape.h" +#include "LineSpacing.h" +#include "LineGeometry.h" +#include "LineConstants.h" +#include "LineCode.h" +#include "GrowthShape.h" +#include "ConductorData.h" +#include "CNLineConstants.h" +#include "CableData.h" +#include "CableConstants.h" + +#include "LineUnits.h" +#include "Conductor.h" +#include "Line.h" +#include "Transformer.h" +#include "Capacitor.h" +#include "Reactor.h" +#include "GICTransformer.h" +#include "fuse.h" +#include "Fault.h" +#include "AutoTrans.h" + +#include "WindGenVars.h" +#include "WindGen.h" +#include "WindGenUserModel.h" +#include "VSource.h" +#include "VSConverter.h" +#include "vccs.h" +#include "UPFC.h" +#include "StorageVars.h" +#include "Storage.h" +#include "StoreUserModel.h" +#include "PVsystem.h" +#include "PVSystemUserModel.h" +#include "Load.h" +#include "Isource.h" +#include "IndMach012.h" +#include "GICsource.h" +#include "GICLine.h" +#include "GenUserModel.h" +#include "Generic5OrderMach.h" +#include "GeneratorVars.h" +#include "generator.h" +#include "Equivalent.h" + +#include "UPFCControl.h" +#include "SwtControl.h" +#include "StorageController.h" +#include "Relay.h" +#include "RegControl.h" +#include "Recloser.h" +#include "InvControl.h" +#include "GenDispatcher.h" +#include "ExpControl.h" +#include "ESPVLControl.h" +#include "CapControlVars.h" +#include "CapControl.h" +#include "CapUserControl.h" + +#include "VLNodeVars.h" +#include "Sensor.h" +#include "ReduceAlgs.h" +#include "Monitor.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "MemoryMap_lib.h" +#include "LD_fm_infos.h" +#include "fMonitor.h" +#include "EnergyMeter.h" + +#include "AutoAdd.h" +#include "Solution.h" +#include "SolutionAlgs.h" +#include "Circuit.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "ControlQueue.h" +#include "DSSCallBackRoutines.h" + +#include "Dynamics.h" +#include "InvDynamics.h" +#include "EventQueue.h" +#include "ExecCommands.h" +#include "ExecHelper.h" +#include "ExecOptions.h" +#include "Executive.h" +#include "ExportCIMXML.h" +#include "ExportOptions.h" +#include "ExportResults.h" +#include "Feeder.h" +#include "IniRegSave.h" +#include "MyDSSClassDefs.h" +#include "Notes.h" +#include "ShowOptions.h" +#include "ShowResults.h" +#include "TOPExport.h" +#include "Utilities.h" +#include "YMatrix.h" +#include "ConnectOptions.h" +#include "Diakoptics.h" +#include "Sparse_Math.h" +#include "MeTIS_Exec.h" +#include "GISCommands.h" +#include "djson.h" +#include "CmdForms.h" +#include "myCmdUtils.h" +#include "myCmdUtils.cpp" + +#ifdef OPENDSSX_CPP_EXTRA_HEADER +// Include another file from a parent project. +// For details, see the note about PARENT PROJECTS at the end of this file. +#include OPENDSSX_CPP_EXTRA_HEADER +#endif + + +//#pragma resource "*.RES" +#define MAXIDX(x) (sizeof(x)/sizeof(x[0]))-1 + + +//class TMyApplication; + +using namespace std; + + +class TMyApplication { + +public: + void DoRun(vector < string > myParam); + TMyApplication(); + ~TMyApplication(); + virtual void WriteHelp(); + virtual void WriteLicensing(); + int GetOptionIdx(string myCMD); + void Execute(string myCMD); +}; + + + +const string ExeName = "OpenDSSCMD"; + + +bool UserFinished(string Cmd) +{ + bool result = false; + result = false; + Cmd = LowerCase(Cmd); + if (Cmd == "exit") result = true; + else if (Cmd[0] == 'q') result = true; + return result; +} + + +void TMyApplication::DoRun(vector myParam) +{ + string ErrorMsg, Cmd; +// Char* LNresult = NULL; + int i = 0, CmdIdx = 0; + NoFormsAllowed = true; + ActiveActor = 1; + IsDLL = false; + DSSExecutive[ActiveActor] = new TExecutive(); // Make a DSS object + DSSExecutive[ActiveActor]->CreateDefaultDSSItems(); + CoutLn(""); + CoutLn("Startup Directory: " + StartupDirectory); + CoutLn("Data Directory: " + DataDirectory[ActiveActor]); + CoutLn("Output Directory: " + OutputDirectory[ActiveActor]); + CoutLn("GetCurrentDir: " + GetCurrentDir()); + CoutLn("---------------------"); + CoutLn(""); + CoutLn("Type '-help' for options"); + CoutLn(""); + CoutLn("******************************************************************"); + DataDirectory[ActiveActor] = StartupDirectory; + OutputDirectory[ActiveActor] = StartupDirectory; + SetCurrentDir(DataDirectory[ActiveActor]); + NoFormsAllowed = false; // messages will go to the console + if (myParam.size() > 0) + { + for (int stop = (int) myParam.size(), i = 0; i < stop; i++) + { + Cmd = myParam[i]; + CoutLn(myParam[i]); + Execute(Cmd); + } + } + else + { + do + { + { // this has no command history + cout << CRLF; + cout << ">>"; + getline(cin,Cmd); + + if (!Cmd.empty()) + Execute(Cmd); + } + } while (!(UserFinished(Cmd))); + } +} + + +void TMyApplication::Execute(string myCMD) +{ + int CmdIdx = 0; + CmdIdx = GetOptionIdx(myCMD); + if (CmdIdx == 0) + { + DSSExecutive[ActiveActor]->Set_Command(myCMD); + if (DSSExecutive[ActiveActor]->Get_LastError() != "") + CoutLn(DSSExecutive[ActiveActor]->Get_LastError()); + else + CoutLn(GlobalResult); + } + else + { + switch (CmdIdx) + { + case 1: + WriteHelp(); + break; + case 2: + cout << "OpenDSS console " + VersionString; + break; + case 3: case 4: + cout << "Not implemented in Embarcadero version"; + break; + case 5: + WriteLicensing(); + break; + case 6: case 7: + cout << "Leaving the program"; + break; + default: + cout << "option not recognized"; + } + } +} + + +TMyApplication::TMyApplication() +{ + // inherited::Create(); + // StopOnException:=True; +} + + +TMyApplication::~TMyApplication() +{ + // todo check: inherited::Destroy; +} + + +int TMyApplication::GetOptionIdx(string myCMD) +{ + int result = 0; + myCMD = LowerCase(myCMD); + result = 0; + if ((myCMD == "-help") || (myCMD == "-h")) + result = 1; + if (myCMD == "-v") + result = 2; + if (myCMD == "-f") + result = 3; + if (myCMD == "-l") + result = 4; + if (myCMD == "-lic") + result = 5; + if (myCMD == "exit") + result = 6; + if (myCMD == "q") + result = 7; + return result; +} + + +void TMyApplication::WriteHelp() +{ + CoutLn("Usage: " + ExeName + " [-v | -h | -f | -l] [stop_time] [filename]"); + CoutLn(" [filename] -> optional DSS command file."); + CoutLn(" If provided, runs this file and exits."); + CoutLn(" If not provided, accepts user commands at the >> prompt."); + CoutLn(" -h -> displays this message and exits"); + CoutLn(" -v -> displays the version and exits"); + CoutLn(" -Lic -> displays the license agreement"); + CoutLn(" exit, q -> leaves the program"); +} + +void TMyApplication::WriteLicensing() +{ + CoutLn("Copyright (c) 2008-2024, Electric Power Research Institute, Inc." + + CRLF + "All rights reserved." + + CRLF + "" + + CRLF + "Redistribution and use in source and binary forms, with or without" + + CRLF + "modification, are permitted provided that the following conditions are met:" + + CRLF + " * Redistributions of source code must retain the above copyright" + + CRLF + " notice, this list of conditions and the following disclaimer." + + CRLF + " * Redistributions in binary form must reproduce the above copyright" + + CRLF + " notice, this list of conditions and the following disclaimer in the" + + CRLF + " documentation and/or other materials provided with the distribution." + + CRLF + " * Neither the name of the Electric Power Research Institute, Inc., nor" + + CRLF + " the names of its contributors may be used to endorse or promote" + + CRLF + " products derived from this software without specific prior written" + + CRLF + " permission." + + CRLF + "" + + CRLF + "THIS SOFTWARE IS PROVIDED BY Electric Power Research Institute, Inc., \"AS IS\"" + + CRLF + "AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE" + + CRLF + "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR" + + CRLF + "PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Electric Power Research Institute, Inc.," + + CRLF + "OR ANY OTHER ENTITY CONTRIBUTING TO OR INVOLVED IN THE PROVISION OF THE SOFTWARE," + + CRLF + "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR" + + CRLF + "CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF" + + CRLF + "SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS" + + CRLF + "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN" + + CRLF + "CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)" + + CRLF + "ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE" + + CRLF + "POSSIBILITY OF SUCH DAMAGE." + + CRLF); +} + +int main(int argc, char* argv[]) +{ + std::vector myParam; + + //int i=1 is starting value, because argv[0] is the program's name. + std::string mypath = ""; + + //if (argc == 1) // To force redirecting to default script when debugging and to not override external args + //{ + //mypath = "compile D:\\Projects-D\\INDUCES\\Examples\\Kundur\\Dynamic_Kundur.dss"; + //argc = 2; + //argv[1] = const_cast(mypath.c_str()); + //} + + for (int i = 1; i < argc; i++) + { + std::string myStr(argv[i]); + myParam.push_back(myStr); + } + + using namespace DSSGlobals; + + TMyApplication Application; + + CoutLn("**********************EPRI OpenDSS simulator**********************"); + CoutLn("* OpenDSS console " + VersionString + " *"); + CoutLn("*Copyright (c) 2008-2024, Electric Power Research Institute, Inc.*"); + CoutLn("******************************************************************"); + +#ifdef OPENDSSX_CPP_MAIN_AFTER_INIT + // Include additional code after our initialization: + OPENDSSX_CPP_MAIN_AFTER_INIT +#endif + +#ifndef OPENDSSX_CPP_MAIN_ALTERNATE + + // Added - DM 12/12/2022 +// myParam.resize(0); // for regular rebugging + + // This is the normal application event loop and return value: + Application.DoRun(myParam); + ExitCode = DSSExecutive[ActiveActor]->Get_ErrorResult(); + + return ExitCode; +#else + // Replace the normal application event loop and return value: + OPENDSSX_CPP_MAIN_ALTERNATE +#endif +} + +/* NOTE: PARENT PROJECTS +A note regarding these three #define's used in this source file: + OPENDSSX_CPP_EXTRA_HEADER + OPENDSSX_CPP_MAIN_AFTER_INIT + OPENDSSX_CPP_MAIN_ALTERNATE + +These names are optional and normally undefined to produce a standard build of +OpenDSS-X, but they permit any other project to act as a "parent" to import and +extend OpenDSS-X, with minimal (no?) changes to OpenDSS-X's code. + +OPENDSSX_CPP_EXTRA_HEADER + Specifies a header to #include at the top of this file. This header + will likely define either OPENDSSX_CPP_MAIN_AFTER_INIT or + OPENDSSX_CPP_MAIN_ALTERNATE to modify the execution within int main(). + + Example lines to go into this header: + // Print out additional text after the startup banner: + #define OPENDSSX_CPP_MAIN_AFTER_INIT std::cout << "Enhanced!\n"; + + Alternatively, this header is free to make more drastic modifications, + such as using a #define to rename our main() in order to replace it + with the parent project's main() instead. + +OPENDSSX_CPP_MAIN_AFTER_INIT + Specifies additional code to include within our main() just after the + normal initialization and command line parsing, but before the main + application loop. + +OPENDSSX_CPP_MAIN_ALTERNATE + Specifies code to completely replace the main Application.DoRun loop. + + +Example usage: + +For example if the parent project is also using CMake, then it may import and +extend OpenDSS-X by adding these lines to it's (the parent's) CMakeLists.txt +and not have to change OpenDSS-X's CMakeLists.txt file. + +# Example commands for a parent project's CMakeLists.txt +add_subdirectory(opendss-x) +set_target_properties(OpenDSSX PROPERTIES + # Rename the output executable binary: + OUTPUT_NAME "OpenDSSX-with-extra-features" + # Place this target with our other executables: + RUNTIME_OUTPUT_DIRECTORY ".." +) +# Add more #include search directories: +target_include_directories(OpenDSSX PRIVATE + other_include_dir + another_include_dir +) +# Include a specific header in opendss-x/CMD/OpenDSSX.cpp: +target_compile_definitions(OpenDSSX PRIVATE + OPENDSSX_CPP_EXTRA_HEADER="extend_opendssx_main.h" + # Example text to go in this header to inject additional text after the normal startup banner: + # #define OPENDSSX_CPP_MAIN_AFTER_INIT std::cout << "Extensions!\n"; +) +# Add more sources to be compiled into the OpenDSS-X executable: +sources(OpenDSSX PRIVATE + src-dirA/featureA.cpp + src-dirB/featureB.cpp +) +*/ diff --git a/OpenDSSC/CMD/OpenDSSC.h b/OpenDSSC/CMD/OpenDSSC.h new file mode 100644 index 0000000..b78d337 --- /dev/null +++ b/OpenDSSC/CMD/OpenDSSC.h @@ -0,0 +1,8 @@ +// OpenDSSX.h : Include file for standard system include files, +// or project specific include files. + +#pragma once + +#include + +// TODO: Reference additional headers your program requires here. diff --git a/OpenDSSC/CMakeLists.txt b/OpenDSSC/CMakeLists.txt new file mode 100644 index 0000000..0fc9073 --- /dev/null +++ b/OpenDSSC/CMakeLists.txt @@ -0,0 +1,455 @@ +# CMakeList.txt : CMake project for OpenDSSX, include source and define +# project specific logic here. +# +cmake_minimum_required (VERSION 3.15) + +project("OpenDSSX" VERSION 0.0.0 DESCRIPTION "OpenDSS-X") + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(Threads) + +add_subdirectory(klusolve EXCLUDE_FROM_ALL) +set_target_properties(klusolve_all PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ".." +) +# Use this variable to define what type of output will be generated by the compiler +if(NOT DEFINED MyOutputType) + # Allow defining MyOutputType in scripts/CLI. + # TODO: move to a cached variable later (avoid that so we don't need to update build docs yet) + set(MyOutputType "DLL") # Output type, DLL or EXE +endif() + +if(MyOutputType STREQUAL "EXE") + add_executable(OpenDSSC + CMD/OpenDSSC.cpp + Support/d2c_system.cpp + Support/d2c_syscurr.cpp + Support/d2c_sysstring.cpp + Support/d2c_sysmath.cpp + Support/d2c_sysdate.cpp + Support/d2c_sysexcept.cpp + Support/d2c_sysfile.cpp + Support/Sysutils.cpp + Support/d2c_structures.cpp + Shared/Arraydef.cpp + Shared/CktTree.cpp + Shared/Command.cpp + Shared/Dynamics.cpp + Shared/InvDynamics.cpp + Shared/HashList.cpp + Shared/IniRegSave.cpp + Shared/LineUnits.cpp + Shared/mathutil.cpp + Shared/PointerList.cpp + Shared/Pstcalc.cpp + Shared/StackDef.cpp + Shared/Ucmatrix.cpp + Shared/Ucomplex.cpp + Parser/RPN.cpp + Parser/ParserDel.cpp + Common/AutoAdd.cpp + Common/Bus.cpp + Common/Circuit.cpp + Common/CktElement.cpp + Common/Conductor.cpp + Common/CktElementClass.cpp + Common/ControlQueue.cpp + Common/Diakoptics.cpp + Common/DSSCallBackRoutines.cpp + Common/DSSClass.cpp + Common/DSSClassDefs.cpp + Common/DSSGlobals.cpp + Common/ExportCIMXML.cpp + Common/ExportResults.cpp + Common/Feeder.cpp + Common/MeTIS_Exec.cpp + Common/ShowResults.cpp + Common/Solution.cpp + Common/SolutionAlgs.cpp + Common/Sparse_Math.cpp + Common/Terminal.cpp + Common/Utilities.cpp + Common/YMatrix.cpp + Forms/CmdForms.cpp + GISCommands/GISCommands.cpp + Executive/ConnectOptions.cpp + Executive/ExecCommands.cpp + Executive/ExecHelper.cpp + Executive/ExecOptions.cpp + Executive/Executive.cpp + Executive/ExportOptions.cpp + Executive/ShowOptions.cpp + Executive/PlotOptions.cpp + Meters/MeterClass.cpp + Meters/EnergyMeter.cpp + Meters/fMonitor.cpp + Meters/MemoryMap_lib.cpp + Meters/MeterElement.cpp + Meters/Monitor.cpp + Meters/ReduceAlgs.cpp + Meters/Sensor.cpp + Meters/VLNodeVars.cpp + Controls/CapControl.cpp + Controls/CapControlVars.cpp + Controls/CapUserControl.cpp + Controls/ControlClass.cpp + Controls/ControlElem.cpp + Controls/ESPVLControl.cpp + Controls/ExpControl.cpp + Controls/GenDispatcher.cpp + Controls/InvControl.cpp + Controls/Recloser.cpp + Controls/RegControl.cpp + Controls/Relay.cpp + Controls/StorageController.cpp + Controls/SwtControl.cpp + Controls/UPFCControl.cpp + PCElements/Equivalent.cpp + PCElements/generator.cpp + PCElements/GeneratorVars.cpp + PCElements/Generic5OrderMach.cpp + PCElements/GenUserModel.cpp + PCElements/GICLine.cpp + PCElements/GICsource.cpp + PCElements/IndMach012.cpp + PCElements/Isource.cpp + PCElements/Load.cpp + PCElements/PCClass.cpp + PCElements/PCElement.cpp + PCElements/PVsystem.cpp + PCElements/PVSystemUserModel.cpp + PCElements/Storage.cpp + PCElements/StorageVars.cpp + PCElements/StoreUserModel.cpp + PCElements/UPFC.cpp + PCElements/vccs.cpp + PCElements/VSConverter.cpp + PCElements/VSource.cpp + PCElements/WindGen.cpp + PCElements/WindGenUserModel.cpp + PCElements/WindGenVars.cpp + PCElements/WTG3_Model.cpp + PDElements/AutoTrans.cpp + PDElements/Capacitor.cpp + PDElements/Fault.cpp + PDElements/fuse.cpp + PDElements/GICTransformer.cpp + PDElements/Line.cpp + PDElements/PDClass.cpp + PDElements/PDElement.cpp + PDElements/Reactor.cpp + PDElements/Transformer.cpp + General/CableConstants.cpp + General/CableData.cpp + General/CNData.cpp + General/CNLineConstants.cpp + General/ConductorData.cpp + General/DSSObject.cpp + General/DynamicExp.cpp + General/GrowthShape.cpp + General/LineCode.cpp + General/LineConstants.cpp + General/LineGeometry.cpp + General/LineSpacing.cpp + General/LoadShape.cpp + General/NamedObject.cpp + General/OHLineConstants.cpp + General/PriceShape.cpp + General/Spectrum.cpp + General/TCC_Curve.cpp + General/TempShape.cpp + General/TSData.cpp + General/TSLineConstants.cpp + General/WireData.cpp + General/XfmrCode.cpp + General/XYcurve.cpp + PCElements/PCElement.cpp + MyOpenDSS/MyDSSClassDefs.cpp + GenModels/gencls.cpp + GenModels/genrou.cpp + GenControls/Exciter/ExcSexs.cpp + GenControls/Governor/tgov.cpp + #Shared/IntegrationMethods.cpp + Plot/DSSPlot.cpp + Plot/DSSGraph.cpp + "PCElements/WTG3_Model.h" "PCElements/WTG3_Model.cpp") +else() + add_library(OpenDSSC SHARED + DLL/OpenDSSCDLL.cpp + Support/d2c_system.cpp + Support/d2c_syscurr.cpp + Support/d2c_sysstring.cpp + Support/d2c_sysmath.cpp + Support/d2c_sysdate.cpp + Support/d2c_sysexcept.cpp + Support/d2c_sysfile.cpp + Support/Sysutils.cpp + Support/d2c_structures.cpp + Shared/Arraydef.cpp + Shared/CktTree.cpp + Shared/Command.cpp + Shared/Dynamics.cpp + Shared/InvDynamics.cpp + Shared/HashList.cpp + Shared/IniRegSave.cpp + Shared/LineUnits.cpp + Shared/mathutil.cpp + Shared/PointerList.cpp + Shared/Pstcalc.cpp + Shared/StackDef.cpp + Shared/Ucmatrix.cpp + Shared/Ucomplex.cpp + Parser/RPN.cpp + Parser/ParserDel.cpp + Common/AutoAdd.cpp + Common/Bus.cpp + Common/Circuit.cpp + Common/CktElement.cpp + Common/Conductor.cpp + Common/CktElementClass.cpp + Common/ControlQueue.cpp + Common/Diakoptics.cpp + Common/DSSCallBackRoutines.cpp + Common/DSSClass.cpp + Common/DSSClassDefs.cpp + Common/DSSGlobals.cpp + Common/ExportCIMXML.cpp + Common/ExportResults.cpp + Common/Feeder.cpp + Common/MeTIS_Exec.cpp + Common/ShowResults.cpp + Common/Solution.cpp + Common/SolutionAlgs.cpp + Common/Sparse_Math.cpp + Common/Terminal.cpp + Common/Utilities.cpp + Common/YMatrix.cpp + Forms/CmdForms.cpp + GISCommands/GISCommands.cpp + Executive/ConnectOptions.cpp + Executive/ExecCommands.cpp + Executive/ExecHelper.cpp + Executive/ExecOptions.cpp + Executive/Executive.cpp + Executive/ExportOptions.cpp + Executive/ShowOptions.cpp + Executive/PlotOptions.cpp + Meters/MeterClass.cpp + Meters/EnergyMeter.cpp + Meters/fMonitor.cpp + Meters/MemoryMap_lib.cpp + Meters/MeterElement.cpp + Meters/Monitor.cpp + Meters/ReduceAlgs.cpp + Meters/Sensor.cpp + Meters/VLNodeVars.cpp + Controls/CapControl.cpp + Controls/CapControlVars.cpp + Controls/CapUserControl.cpp + Controls/ControlClass.cpp + Controls/ControlElem.cpp + Controls/ESPVLControl.cpp + Controls/ExpControl.cpp + Controls/GenDispatcher.cpp + Controls/InvControl.cpp + Controls/Recloser.cpp + Controls/RegControl.cpp + Controls/Relay.cpp + Controls/StorageController.cpp + Controls/SwtControl.cpp + Controls/UPFCControl.cpp + PCElements/Equivalent.cpp + PCElements/generator.cpp + PCElements/GeneratorVars.cpp + PCElements/Generic5OrderMach.cpp + PCElements/GenUserModel.cpp + PCElements/GICLine.cpp + PCElements/GICsource.cpp + PCElements/IndMach012.cpp + PCElements/Isource.cpp + PCElements/Load.cpp + PCElements/PCClass.cpp + PCElements/PCElement.cpp + PCElements/PVsystem.cpp + PCElements/PVSystemUserModel.cpp + PCElements/Storage.cpp + PCElements/StorageVars.cpp + PCElements/StoreUserModel.cpp + PCElements/UPFC.cpp + PCElements/vccs.cpp + PCElements/VSConverter.cpp + PCElements/VSource.cpp + PCElements/WindGen.cpp + PCElements/WindGenUserModel.cpp + PCElements/WindGenVars.cpp + PCElements/WTG3_Model.cpp + PDElements/AutoTrans.cpp + PDElements/Capacitor.cpp + PDElements/Fault.cpp + PDElements/fuse.cpp + PDElements/GICTransformer.cpp + PDElements/Line.cpp + PDElements/PDClass.cpp + PDElements/PDElement.cpp + PDElements/Reactor.cpp + PDElements/Transformer.cpp + General/CableConstants.cpp + General/CableData.cpp + General/CNData.cpp + General/CNLineConstants.cpp + General/ConductorData.cpp + General/DSSObject.cpp + General/DynamicExp.cpp + General/GrowthShape.cpp + General/LineCode.cpp + General/LineConstants.cpp + General/LineGeometry.cpp + General/LineSpacing.cpp + General/LoadShape.cpp + General/NamedObject.cpp + General/OHLineConstants.cpp + General/PriceShape.cpp + General/Spectrum.cpp + General/TCC_Curve.cpp + General/TempShape.cpp + General/TSData.cpp + General/TSLineConstants.cpp + General/WireData.cpp + General/XfmrCode.cpp + General/XYcurve.cpp + PCElements/PCElement.cpp + MyOpenDSS/MyDSSClassDefs.cpp + GenModels/gencls.cpp + GenModels/genrou.cpp + GenControls/Exciter/ExcSexs.cpp + GenControls/Governor/tgov.cpp + #Shared/IntegrationMethods.cpp + Plot/DSSPlot.cpp + Plot/DSSGraph.cpp + ) +endif() + +target_compile_options(OpenDSSC PRIVATE + $<$: + # Options for MSVC: + /permissive- + > + $<$,$>: + # Options for Clang or GCC: + # -fms-extensions + $<$: + -Wall + -Wextra + # These are temporarilly disabled: + -Wno-unused-variable + -Wno-unused-parameter + -Wno-sign-compare + -Wno-unused-private-field + -Wno-unused-const-variable + + # Options for Clang-only: + $<$: + # Purposefully fill uninitialized variables with a pattern, to help catch errors faster: + -ftrivial-auto-var-init=pattern + # Enable Clang's Address Sanitizer: https://clang.llvm.org/docs/AddressSanitizer.html + -fsanitize=address + $<$: + -fsanitize-address-use-after-return=always + > + -fsanitize-address-use-after-scope + # Strive for understandable stack traces by disabling a few optimizations: + -fno-omit-frame-pointer + -fno-inline-functions + -fno-optimize-sibling-calls + > + > + > +) +target_link_options(OpenDSSC PRIVATE + $<$: + $<$: + # Clang's Address Sanitizer also needs this link switch: https://clang.llvm.org/docs/AddressSanitizer.html + # -fsanitize=address + > + > +) +target_compile_features(OpenDSSC PUBLIC +# Require C11 support when we're compiling C code. + c_std_11 +# Require C++11 for std::filesystem. (If C++11 support is needed, use Boost.) + cxx_std_11 +) +# Disallowing extensions would help check the code for compatibility with other compilers: +#set_property(OpenDSSC tgt PROPERTY CXX_EXTENSIONS OFF) + +if(MSVC) +message("Platform assumption: Microsoft Visual C++ (or compatible)") +# Regarding DECLSPEC_[23]D, Clang doesn't want extra []'s for multi-dimensional +# __declspec getters & putters. +target_compile_definitions(OpenDSSC PRIVATE + DECLSPEC_2D=[] + DECLSPEC_3D=[][] +) +target_compile_options(OpenDSSC PRIVATE + #/fsanitize=address +) +else() +message("Platform assumption: Linux or UNIX") +# Regarding DECLSPEC_[23]D, Visual C++ wants extra []'s for multi-dimensional +# __declspec getters & putters. +# +# Define _D2C_SYSFILE_H_LONG_IS_INT64 if long is the same as int64_t for d2c_sysfile.{h,cpp} +# TODO: How may _D2C_SYSFILE_H_LONG_IS_INT64 be checked at compile time? The +# cleanest way would be to rewrite that mess with a few C++ templates. +# +# _COMPLEX_DEFINED is to prevent klusolve.h from defining complex with a +# conflicting set of names. +target_compile_definitions(OpenDSSC PRIVATE + _D2C_SYSFILE_H_LONG_IS_INT64 + _COMPLEX_DEFINED +) +endif() + +target_include_directories(OpenDSSC PRIVATE + Common + Controls + Executive + Forms + General + GISCommands + Meters + MyOpenDSS + Parser + PCElements + PDElements + Shared + Support + MyOpenDSS + GenModels + GenControls/Exciter + GenControls/Governor + Plot +) + +if((MSVC) OR (MINGW)) +# Windows: +target_link_libraries(OpenDSSC + ${CMAKE_THREAD_LIBS_INIT} + klusolve_all +) +else() +# Linux: +target_link_libraries(OpenDSSC + ${CMAKE_THREAD_LIBS_INIT} + klusolve_all + stdc++fs + dl + uuid + # iconv # iconv seems to be required on more recent compilers +) +endif() + +# TODO: Add tests and install targets if needed. +install (TARGETS OpenDSSC DESTINATION "openDSSX/bin") diff --git a/OpenDSSC/CMakePresets.json b/OpenDSSC/CMakePresets.json new file mode 100644 index 0000000..e3feb8d --- /dev/null +++ b/OpenDSSC/CMakePresets.json @@ -0,0 +1,21 @@ +{ + "version": 2, + "configurePresets": [ + { + "architecture": { + "strategy": "external", + "value": "x64" + }, + "binaryDir": "${sourceDir}/out/build/${presetName}", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}" + }, + "description": "Target Windows with the Visual Studio development environment.", + "displayName": "Windows x64 Debug", + "generator": "Ninja", + "name": "windows-default", + "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { "hostOS": [ "Windows" ] } } + } + ] +} \ No newline at end of file diff --git a/OpenDSSC/Common/AutoAdd.cpp b/OpenDSSC/Common/AutoAdd.cpp new file mode 100644 index 0000000..85f93f2 --- /dev/null +++ b/OpenDSSC/Common/AutoAdd.cpp @@ -0,0 +1,725 @@ + +#pragma hdrstop + +#include "AutoAdd.h" + +#include "EnergyMeter.h" +#include "generator.h" +#include "DSSGlobals.h" +#include "PDElement.h" +#include "Utilities.h" +#include "Executive.h" +#include "CmdForms.h" +#include "Solution.h" + +namespace AutoAdd +{ + + + + + double SumSelectedRegisters(TEnergyMeterObj Mtr, pIntegerArray Regs, int count) + { + double result = 0.0; + int i = 0; + result = 0.0; + /*# with Mtr do */ + auto with0 = Mtr; + for (int stop = count, i = 1; i <= stop; i++) + { + result = result + with0.Registers[(Regs)[i - 1]] * with0.TotalsMask[(Regs)[i - 1]]; + } + return result; + } + + + TAutoAdd::TAutoAdd() + : BusIdxListSize(0), + BusIdxListCreated(false), + LastAddedGenerator(0), + LastAddedCapacitor(0), + BusIndex(0), + Phases(0), + Ycap(0.0), + kWLosses(0.0), + BaseLosses(0.0), + puLossImprovement(0.0), + kWEEN(0.0), + BaseEEN(0.0), + puEENImprovement(0.0), + ProgressCount(0), + GenkW(0.0), + GenPF(0.0), + Genkvar(0.0), + Capkvar(0.0), + AddType(0), + ModeChanged(false) + { + CapacitorClass = (TCapacitor*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("capacitor")); + + // AutoAdd defaults + GenkW = 1000.0; + GenPF = 1.0; + Capkvar = 600.0; + AddType = GENADD; + LastAddedGenerator = 0; + LastAddedCapacitor = 0; + ModeChanged = true; + } + + + TAutoAdd::~TAutoAdd() + { + if (BusIdxListCreated) + free(BusIdxList); + // todo check: inherited::Destroy(); + } + + + void TAutoAdd::MakeBusList(int ActorID) + // Make a list of unique busnames + // IF AutoAddBusList in ActiveCircuit[ActorID] is not nil, use this list. + // ELSE, Use the element lists in Energy Meters + // IF no Energy Meters, use all the buses in the active circuit + + { + TEnergyMeterObj* pMeter; + int retval = 0; + String Bname; + int i = 0; + TPDElement* PDElem; + THashList FBusList; + bool FBusListCreatedHere = false; + if (BusIdxListCreated) + free(BusIdxList); + FBusListCreatedHere = false; + BusIdxListCreated = false; + + // Autoaddbuslist exists in Active Circuit, use it (see set Autobuslist=) + if (ActiveCircuit[ActorID]->AutoAddBusList.Get_NumElements() > 0) + FBusList = ActiveCircuit[ActorID]->AutoAddBusList; + else + if (ActiveCircuit[ActorID]->EnergyMeters.get_myNumList() == 0) + { + // No energymeters in circuit + // Include all buses in the circuit + BusIdxListSize = ActiveCircuit[ActorID]->BusList.Get_NumElements(); + BusIdxList = (pIntegerArray) realloc(BusIdxList, sizeof(long) * BusIdxListSize); + for (int stop = BusIdxListSize, i = 1; i <= stop; i++) + { + (BusIdxList)[i - 1] = i; + } + BusIdxListCreated = true; + return; + } + else + { + /*Construct Bus List from Energy Meters Zone Lists*/ + // Include only buses in EnergyMeter lists + // Consider all meters + FBusListCreatedHere = true; + FBusList = THashList(ActiveCircuit[ActorID]->NumBuses); + pMeter = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while (pMeter != NULL) + { + if (pMeter->BranchList != NULL) + { + PDElem = (TPDElement*) pMeter->BranchList->Get_First(); + while (PDElem != NULL) + { // add only unique busnames + for (int stop = ( (TDSSCktElement*) PDElem )->Get_NTerms(), i = 1; i <= stop; i++) + { + Bname = StripExtension( ( (TDSSCktElement*) PDElem )->GetBus(i)); + retval = FBusList.Find(Bname); + if (retval == 0) + { + FBusList.Add(Bname); // return value is index of bus + } + } + PDElem = (TPDElement*) pMeter->BranchList->Get_Forward(); + } + } + pMeter = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + } + + // Make busIdxList from FBusList + BusIdxListSize = FBusList.Get_NumElements(); + BusIdxList = (pIntegerArray)realloc(BusIdxList, sizeof(long) * BusIdxListSize); + for (int stop = BusIdxListSize, i = 1; i <= stop; i++) + { + (BusIdxList)[i - 1] = ActiveCircuit[ActorID]->BusList.Find(FBusList.Get(i)); + } + if (FBusListCreatedHere) + FBusList.Clear(); + BusIdxListCreated = true; + } + + + double TAutoAdd::Get_WeightedLosses() + + // Returns losses in metered part of circuit + + // weighted EEN values + + /*If no meters, returns just total losses in circuit*/ + + /*Base everything on gen kW*/ + + { + double result = 0.0; + ComputekWLosses_EEN(ActiveActor); + if (ActiveCircuit[ActiveActor]->EnergyMeters.get_myNumList() == 0) + { + // No energymeters in circuit + // Just go by total system losses + puLossImprovement = (BaseLosses - kWLosses) / GenkW; + puEENImprovement = 0.0; + result = puLossImprovement; + } + else + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + puLossImprovement = (BaseLosses - kWLosses) / GenkW; + puEENImprovement = (BaseEEN - kWEEN) / GenkW; + result = with0->LossWeight * puLossImprovement + with0->UEWeight * puEENImprovement; + } + } + return result; + } + + + void TAutoAdd::AppendToFile(const String WhichFile, const String S) + { + TTextRec F; + String Fname; + try + { + Fname = GetOutputDirectory() + CircuitName_[ActiveActor] + "AutoAdded" + WhichFile + ".txt"; + AssignFile(F, Fname); + if (FileExists(Fname)) + Append(F); + else + Rewrite(F); + IOResultToException(); + WriteLn(F, S); + } + catch (std::exception &E) + { + DoSimpleMsg(String("Error TRYing to append to ") + Fname + CRLF + (std::string) E.what(), 438); + } + CloseFile(F); + } + + + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String TAutoAdd::GetUniqueGenName() + { + String result; + + + // TimeStmp: TTimeStamp; + + String TrialName; + bool Done = false; + do + { + Done = true; + LastAddedGenerator++; + TrialName = "Gadd" + IntToStr(LastAddedGenerator); + if ( ( (TDSSClass*) GeneratorClass )->Find(TrialName) != NULL) + Done = false; + } while (!(Done)); + result = TrialName; + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String TAutoAdd::GetUniqueCapName() + { + String result; + + + // TimeStmp: TTimeStamp; + + String TrialName; + bool Done = false; + // TimeStmp := DateTimeToTimeStamp(Now); + // Result := IntToStr(TimeStmp.date-730000)+'_'+IntToStr(TimeStmp.time); + do + { + Done = true; + LastAddedCapacitor++; + TrialName = "Cadd" + IntToStr(LastAddedCapacitor); + if ( ( (TDSSClass*) CapacitorClass )->Find(TrialName) != NULL) + Done = false; + } while (!(Done)); + result = TrialName; + return result; + } + + int TAutoAdd::Solve(int ActorID) // Automatically add caps or generators + /* + Automatically add a specified size of generator or capacitor at the location + that results in the lowest losses in either metered part of circuit or + total circuit, if no meters. + + If metered, EEN is also added in WITH a selected weighting factor (see + set ueweight= ... command). + + Thus, this algorithm placed generators and capacitors to minimize losses and + potential unserved energy. + + */ + + { + int result = 0; + double LossImproveFactor = 0.0, MaxLossImproveFactor = 0.0; + int MinLossBus = 0, MinBusPhases = 0; + String Testbus; + int i = 0; + String CommandString; + double kVrat = 0.0, TestGenkW = 0.0, TestCapkvar = 0.0; + int ProgressMax = 0; + + /* Algorithm: + 1) makes a list of buses to check, either + a. Previously defined list + b. Meter zone lists + c. All buses, if neither of the above + 2) Inject a current corresponding to the generator + 3) Check test criteria + 4) Save result + 5) Add generator/capacitor to circuit + + */ + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + if (with1->LoadModel == ADMITTANCE) + { + with1->LoadModel = POWERFLOW; + with1->SystemYChanged = true; // Force rebuild of System Y without Loads + } + + /*Do a preliminary snapshot solution to Force definition of meter zones + And set bus lists*/ + EnergyMeterClass[ActorID]->ResetAll(ActorID); + if (with1->SystemYChanged || with0->get_FBusNameRedefined()) + { + with1->SolveSnap(ActorID); + ModeChanged = true; + } + EnergyMeterClass[ActorID]->SampleAll(ActorID); + + /* Check to see if bus base voltages have been defined */ + if (with0->Buses[with0->NumBuses - 1]->kVBase == 0.0) + with1->SetVoltageBases(ActorID); + if (ModeChanged) + { + MakeBusList(ActorID); // Make list of buses to check + ModeChanged = false; /*Keep same BusIdxList if no changes*/ + } + with1->IntervalHrs = 1.0; + + /*Start up Log File*/ + AssignFile(FLog, GetOutputDirectory() + CircuitName_[ActiveActor] + "AutoAddLog.CSV"); + Rewrite(FLog); + IOResultToException(); + WriteLn(FLog, "\"Bus\", \"Base kV\", \"kW Losses\", \"% Improvement\", \"kW UE\", \"% Improvement\", \"Weighted Total\", \"Iterations\""); + CloseFile(FLog); // Close it now after clearing it out + + // for this solution mode, only the peak load condition is taken into account + // load is adjusted for growth by year. + with1->SetGeneratorDispRef(ActorID); + + /*Turn regulators and caps off while we are searching*/ + with1->ControlMode = CONTROLSOFF; + SetBaseLosses(); /*Establish base values*/ + switch (AddType) + { + case GENADD: + { + if (with0->PositiveSequence) + TestGenkW = GenkW / 3.0; + else + TestGenkW = GenkW; + if (GenPF != 0.0) + { + Genkvar = TestGenkW * sqrt(1.0 / sqr(GenPF) - 1.0); + if (GenPF < 0.0) + Genkvar = -Genkvar; + } + else + { // Someone goofed and specified 0.0 PF + GenPF = 1.0; + Genkvar = 0.0; + } + MinLossBus = 0; // null string + MaxLossImproveFactor = -1.0e50; // Some very large neg number + MinBusPhases = 3; + + + + /*Progress meter*/ + // {$IFDEF MSWINDOWS} + // ProgressCaption( 'AutoAdding Generators', ActorID); + // {$ENDIF} + ProgressMax = BusIdxListSize; + ProgressCount = 0; + // {$IFDEF MSWINDOWS} + // ProgressFormCaption( Format('Testing %d buses. Please Wait... ',[BusIdxListSize]), ActorID); + // {$ENDIF} + // ShowPctProgress(0, ActorID); + for (int stop = BusIdxListSize, i = 1; i <= stop; i++) + { + ProgressCount++; + BusIndex = (BusIdxList)[i - 1]; + if (BusIndex > 0) + { + Testbus = with0->BusList.Get(BusIndex); + // ProgressFormCaption( 'Testing bus ' + TestBus); + if (((ProgressCount % 20) == 0) || (i == BusIdxListSize)) + { + + // ProgressFormCaption( Format('Testing bus %d/%d. ',[i,BusIdxListSize]), ActorID); + // ShowPctProgress (Round((100 * ProgressCount)/ProgressMax), ActorID); + } + EnergyMeterClass[ActorID]->ResetAll(ActorID); + + /*Get the Number of Phases at this bus and the Node Ref and add into the Aux Current Array*/ + + /*Assume either a 3-phase or 1-phase generator*/ + if (with0->Buses[BusIndex - 1]->get_FNumNodesThisBus() < 3) + Phases = 1; + else + Phases = 3; + GenVA = cmplx(1000.0 * TestGenkW / Phases, 1000.0 * Genkvar / Phases); + + /* - -- - - - - - - Solution - - - - - - - - - - - - - - -*/ + with0->Issolved = false; + with1->UseAuxCurrents = true; // Calls InjCurrents on callback + with1->SolveSnap(ActorID); + if (with0->Issolved) + { + /*Only do this if solution converged ELSE something might break + in meter sampling*/ + EnergyMeterClass[ActorID]->SampleAll(ActorID); + LossImproveFactor = Get_WeightedLosses(); + try + { + Append(FLog); + IOResultToException(); + Write(FLog, Format("\"%s\", %-g", Testbus.c_str(), with0->Buses[BusIndex - 1]->kVBase* SQRT3)); + Write(FLog, Format(", %-g, %-g", kWLosses, puLossImprovement * 100.0)); + Write(FLog, Format(", %-g, %-g", kWEEN, puEENImprovement * 100.0)); + WriteLn(FLog, Format(", %-g, %d", LossImproveFactor, with1->Iteration)); + /* } + __finally + {*/ + CloseFile(FLog); + } + catch (...) + { + // + } + if (LossImproveFactor > MaxLossImproveFactor) + { + MaxLossImproveFactor = LossImproveFactor; + MinLossBus = BusIndex; + MinBusPhases = Phases; + } + } + } + if (SolutionAbort) + break; + } + + /*Put Control mode back to default before inserting Generator for real*/ + with1->ControlMode = CTRLSTATIC; + with1->UseAuxCurrents = false; + if (MinLossBus > 0) + /*# with DSSExecutive[ActorID] do */ + { + auto with2 = DSSExecutive[ActorID]; + { + if (MinBusPhases >= 3) + kVrat = with0->Buses[MinLossBus - 1]->kVBase * SQRT3; + else + kVrat = with0->Buses[MinLossBus - 1]->kVBase; + CommandString = String("New, generator.") + GetUniqueGenName() + ", bus1=\"" + with0->BusList.Get(MinLossBus) + "\", phases=" + IntToStr(MinBusPhases) + ", kv=" + Format("%-g", kVrat) + ", kw=" + Format("%-g", TestGenkW) + ", " + + Format("%5.2f", GenPF) + Format("! Factor = %-g (%-.3g, %-.3g)", MaxLossImproveFactor, with0->LossWeight, with0->UEWeight); + with2->Set_Command(CommandString); // Defines Generator + + // AppEnd this command to '...AutoAddedGenerators.Txt' + AppendToFile("Generators", CommandString); + with1->SolveSnap(ActorID); // Force rebuilding of lists + } + } + // Return location of added generator so that it can + // be picked up through the result string of the COM interface + GlobalResult = with0->BusList.Get(MinLossBus) + Format(", %-g", MaxLossImproveFactor); + //{$IFDEF MSWINDOWS} + // ProgressHide(ActorID); + //{$ENDIF} + + // note that the command that added the generator can be + // picked up from the Command property of the COM interface. + } + break; + case CAPADD: + { + MinLossBus = 0; // null string + MaxLossImproveFactor = -1.0e50; // Some very large number + MinBusPhases = 3; + if (with0->PositiveSequence) + TestCapkvar = Capkvar / 3.0; + else + TestCapkvar = Capkvar; + + /*Progress meter*/ + // ProgressCaption ( 'AutoAdding Capacitors', ActorID); + ProgressMax = BusIdxListSize; + ProgressCount = 0; + for (int stop = BusIdxListSize, i = 1; i <= stop; i++) + { + ProgressCount++; + /*Make sure testbus is actually in the circuit*/ + BusIndex = (BusIdxList)[i - 1]; + if (BusIndex > 0) + { + Testbus = with0->BusList.Get(BusIndex); + // ProgressFormCaption('Testing bus ' + TestBus, ActorID); + // ShowPctProgress ( Round((100 * ProgressCount)/ProgressMax), ActorID); + EnergyMeterClass[ActorID]->ResetAll(ActorID); + + /*Get the Number of Phases at this bus and the Node Ref and add into the Aux Current Array*/ + + /*Assume either a 3-phase or 1-phase Capacitor*/ + if (with0->Buses[BusIndex - 1]->get_FNumNodesThisBus() < 3) + Phases = 1; + else + Phases = 3; + + // Apply the capacitor at the bus rating + kVrat = with0->Buses[BusIndex - 1]->kVBase; // L-N Base kV + Ycap = (TestCapkvar * 0.001 / Phases) / (kVrat * kVrat); + + + /* - -- - - - - - - Solution - - - - - - - - - - - - - - -*/ + with0->Issolved = false; + with1->UseAuxCurrents = true; // Calls InjCurrents on callback + with1->SolveSnap(ActorID); + if (with0->Issolved) + { + /*Only do this if solution converged ELSE something might break + in meter sampling*/ + EnergyMeterClass[ActorID]->SampleAll(ActorID); + LossImproveFactor = Get_WeightedLosses(); + try + { + Append(FLog); + IOResultToException(); + Write(FLog, Format("\"%s\", %-g", Testbus.c_str(), with0->Buses[BusIndex - 1]->kVBase * SQRT3)); + Write(FLog, Format(", %-g, %-g", kWLosses, puLossImprovement * 100.0)); + Write(FLog, Format(", %-g, %-g", kWEEN, puEENImprovement * 100.0)); + WriteLn(FLog, Format(", %-g, %d", LossImproveFactor, with1->Iteration)); + /* } + __finally + {*/ + CloseFile(FLog); + } + catch (...) + { + // + } + if (LossImproveFactor > MaxLossImproveFactor) + { + MaxLossImproveFactor = LossImproveFactor; + MinLossBus = BusIndex; + MinBusPhases = Phases; + } + } + } + if (SolutionAbort) + break; + } + + + /*Put Control mode back to default before inserting Capacitor for real*/ + with1->ControlMode = CTRLSTATIC; + with1->UseAuxCurrents = false; + if (MinLossBus > 0) + /*# with DSSExecutive[ActorID] do */ + { + auto with2 = DSSExecutive[ActorID]; + { + if (MinBusPhases >= 3) + kVrat = with0->Buses[MinLossBus - 1]->kVBase * SQRT3; + else + kVrat = with0->Buses[MinLossBus - 1]->kVBase; + CommandString = String("New, Capacitor.") + GetUniqueCapName() + ", bus1=\"" + with0->BusList.Get(MinLossBus) + "\", phases=" + IntToStr(MinBusPhases) + ", kvar=" + Format("%-g", TestCapkvar) + ", kv=" + Format("%-g", kVrat); + with2->Set_Command(CommandString); // Defines capacitor + + // AppEnd this command to 'DSSAutoAddedCapacitors.Txt' + AppendToFile("Capacitors", CommandString); + with1->SolveSnap(ActorID); // for rebuilding of lists, etc. + } + } + // Return location of added generator so that it can + // be picked up through the result string of the COM interface + GlobalResult = with0->BusList.Get(MinLossBus); + + // note that the command that added the generator can be + // picked up from the Command property of the COM interface. + } + break; + } + } + } + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void TAutoAdd::AddCurrents(int SolveType, int ActorID) + + /* Compute injection Currents for generator or capacitor and add into + system Currents array + */ + { + complex BusV; + int i = 0, Nref = 0; + switch (AddType) + { + case GENADD: + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + /*For buses with voltage <> 0, add into aux current array*/ + for (int stop = Phases, i = 1; i <= stop; i++) + { + Nref = with0->Buses[BusIndex - 1]->GetRef(i); + if (Nref > 0) + { // add in only non-ground currents + if (!ADiakoptics | (ActorID == 1)) + BusV = with1->NodeV[Nref]; + else // In the context of actor 1 + BusV = with1->VoltInActor1(Nref); + if ((BusV.re != 0.0) || (BusV.im != 0.0)) + /*Current INTO the system network*/ + switch (SolveType) + { + case NEWTONSOLVE: + caccum(with1->Currents[Nref], cnegate(conjg(cdiv(GenVA, BusV)))); + break; // Terminal Current + + case NORMALSOLVE: + caccum(with1->Currents[Nref], conjg(cdiv(GenVA, BusV))); + break; // Injection Current + } + } + } + } + } + break; + case CAPADD: + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + + /*For buses with voltage <> 0, add into aux current array*/ + for (int stop = Phases, i = 1; i <= stop; i++) + { + Nref = with0->Buses[BusIndex - 1]->GetRef(i); + if (Nref > 0) + { + if (!ADiakoptics || (ActorID == 1)) + BusV = with1->NodeV[Nref]; + else // In the context of actor 1 + BusV = with1->VoltInActor1(Nref); + if ((BusV.re != 0.0) || (BusV.im != 0.0)) + /*Current INTO the system network*/ + switch (SolveType) + { + case NEWTONSOLVE: + caccum(with1->Currents[Nref], cmul(cmplx(0.0, Ycap), BusV)); + break; // Terminal Current + + case NORMALSOLVE: + caccum(with1->Currents[Nref], cmul(cmplx(0.0, -Ycap), BusV)); + break; // Injection Current + } // Constant Y model + } + } + } + } + break; + } /*CASE*/ + } + + + void TAutoAdd::ComputekWLosses_EEN(int ActorID) + { + TEnergyMeterObj* pMeter; + if (ActiveCircuit[ActorID]->EnergyMeters.get_myNumList() == 0) + { + + // No energymeters in circuit + // Just go by total system losses + kWLosses = ActiveCircuit[ActorID]->Get_Losses(ActorID).re * 0.001; + kWEEN = 0.0; + } + else + { // Sum losses in energy meters and add EEN + kWLosses = 0.0; + kWEEN = 0.0; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + pMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_First(); + while (pMeter != NULL) + { + kWLosses = kWLosses + SumSelectedRegisters(*pMeter, with0->LossRegs, with0->NumLossRegs); + kWEEN = kWEEN + SumSelectedRegisters(*pMeter, with0->UEregs, with0->NumUEregs); + pMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_Next(); + } + } + } + } + } + + void TAutoAdd::SetBaseLosses() + { + ComputekWLosses_EEN(ActiveActor); + BaseLosses = kWLosses; + BaseEEN = kWEEN; + } + +} // namespace AutoAdd + + + + + + + diff --git a/OpenDSSC/Common/AutoAdd.h b/OpenDSSC/Common/AutoAdd.h new file mode 100644 index 0000000..9370def --- /dev/null +++ b/OpenDSSC/Common/AutoAdd.h @@ -0,0 +1,94 @@ +#ifndef AutoAddH +#define AutoAddH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* Unit for processing the AutoAdd Solution FUNCTIONs + + Note: Make sure this class in instantiated after energymeter class + + There is one of these per circuit + + 6/11/00 - reorganized object + 6/14/00 - resolved sign issue with normal and Newton solution in AddCurrents + 9/13/03 - Modified to use pu improvement in losses and EEN instead of kW +*/ + +/*$M+*/ + + +#include "System.h" + +#include "Ucomplex.h" +#include "HashList.h" +#include "Arraydef.h" +#include "DSSClassDefs.h" +#include "Sysutils.h" +#include "Capacitor.h" + + + +//class TAutoAdd; + + +namespace AutoAdd +{ + + class TAutoAdd { + private: + //**** GeneratorClass :TGenerator; + TCapacitor* CapacitorClass; + pIntegerArray BusIdxList; + int BusIdxListSize; + bool BusIdxListCreated; + int LastAddedGenerator, LastAddedCapacitor; + int BusIndex, Phases; + double Ycap; + complex GenVA; + double kWLosses, BaseLosses, puLossImprovement; + double kWEEN, BaseEEN, puEENImprovement; + TTextRec FLog; // Log File + int ProgressCount; + double Get_WeightedLosses(); + void ComputekWLosses_EEN(int ActorID); + void SetBaseLosses(); + String GetUniqueGenName(); + String GetUniqueCapName(); + protected: + public: + + /*Autoadd mode Variables*/ + double GenkW, GenPF, Genkvar, Capkvar; + int AddType; + bool ModeChanged; + TAutoAdd(); + virtual ~TAutoAdd(); + void MakeBusList(int ActorID); + void AppendToFile(const String WhichFile, const String S); + void AddCurrents(int SolveType, int ActorID); + int Solve(int ActorID); // Automatically add caps or generators + // __published: + }; + +} // namespace autoadd + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace AutoAdd; +#endif + +#endif // AutoAddH + + + + + + + + + + + diff --git a/OpenDSSC/Common/Bus.cpp b/OpenDSSC/Common/Bus.cpp new file mode 100644 index 0000000..afcebd1 --- /dev/null +++ b/OpenDSSC/Common/Bus.cpp @@ -0,0 +1,246 @@ + + +#pragma hdrstop + +#include "Bus.h" + +#include "DSSGlobals.h" + +namespace Bus +{ + + TDSSBus::TDSSBus() + : inherited("Bus"), + FNumNodesThisBus(0), + Allocation(3), + lat(0.0), + longitude(0.0), + x(0.0), + y(0.0), + kVBase(0.0), + DistFromMeter(0.0), + GISCoordDefined(false), + CoordDefined(false), + BusChecked(false), + Keep(false), + IsRadialBus(false), + BusFltRate(0.0), + Bus_Num_Interrupt(0.0), + Bus_Int_Duration(0.0), + BusCustInterrupts(0.0), + BusCustDurations(0.0), + BusTotalNumCustomers(0), + BusTotalMiles(0.0), + BusSectionID(0) + { + Nodes.resize( Allocation ); + RefNo.resize( Allocation ); + FNumNodesThisBus = 0; + Ysc = TcMatrix(0); + Zsc = TcMatrix(0); + Zsc012 = TcMatrix(0); + VBus.clear(); + BusCurrent.clear(); + kVBase = 0.0; // Signify that it has not been set + x = 0.0; + y = 0.0; + DistFromMeter = 0.0; + BusFltRate = 0.0; // accummulated failure rate + Bus_Int_Duration = 0.0; + BusCustInterrupts = 0.0; // Accumulated Number of customer interruptions from this bus + BusCustDurations = 0.0; // Accumulated Customer outage durations + BusTotalNumCustomers = 0; + BusTotalMiles = 0.0; // total length of line downstream + CoordDefined = false; + Keep = false; + IsRadialBus = false; + // GIS data + lat = 0; + longitude = 0; + GISCoordDefined = false; + } + + + TDSSBus::~TDSSBus() + { + if (Nodes.size() != 0) + Nodes.clear(); +// if (RefNo != nullptr) +// free(RefNo); +/* if (VBus != NULL) + free(VBus); + if (BusCurrent != NULL) + free(BusCurrent);*/ + // todo check: inherited::Destroy; + + VBus.clear(); + BusCurrent.clear(); + } + + int TDSSBus::get_FNumNodesThisBus() + { + return FNumNodesThisBus; + } + + void TDSSBus::AddANode() + { + FNumNodesThisBus++; + if (FNumNodesThisBus > Allocation) + { + ++Allocation; + Nodes.resize( Allocation ); + RefNo.resize( Allocation ); + } + } + + + int TDSSBus::Add(int NodeNum, int ActorID) + { + int result = 0; + if (NodeNum == 0) + result = 0; + else + { + result = Find(NodeNum); + if (result == 0) + { + // Add a node to the bus + AddANode(); + Nodes[FNumNodesThisBus - 1] = NodeNum; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + with0->NumNodes++; // Global node number for circuit + RefNo[FNumNodesThisBus - 1] = with0->NumNodes; + result = with0->NumNodes; // Return global node number + } + } + } + } + return result; + } + + + int TDSSBus::Find(int NodeNum) + // Returns reference number + + { + int result = 0; + int i = 0; + for (int stop = FNumNodesThisBus, i = 1; i <= stop; i++) + { + if (Nodes[i - 1] == NodeNum) + { + result = RefNo[i - 1]; + return result; + } + } + result = 0; + return result; + } + + + int TDSSBus::GetRef(int NodeIndex) + { + int result = 0; + result = 0; + if ((NodeIndex > 0) && (NodeIndex <= FNumNodesThisBus)) + result = RefNo[NodeIndex - 1]; + return result; + } + + + int TDSSBus::GetNum(int NodeIndex) + { + int result = 0; + result = 0; + if ((NodeIndex > 0) && (NodeIndex <= FNumNodesThisBus)) + result = Nodes[NodeIndex - 1]; + return result; + } + + + void TDSSBus::AllocateBusQuantities() + // Have to perform a short circuit study to get this allocated + + { + Ysc = TcMatrix(FNumNodesThisBus); + Zsc = TcMatrix(FNumNodesThisBus); + Zsc012 = TcMatrix(3); // can only be 3x3 -- 0, 1, 2 + AllocateBusVoltages(); + AllocateBusCurrents(); + } + + complex TDSSBus::Get_Zsc0() + // = Zs + 2 Zm + + { + complex result; + if ((Zsc.Norder != 0)) + result = cadd(Zsc.AvgDiagonal(), cmulreal(Zsc.AvgOffDiagonal(), 2.0)); + else + result = CZero; + return result; + } + + + complex TDSSBus::Get_Zsc1() + // = Zs-Zm + + { + complex result; + if ((Zsc.Norder != 0)) + result = csub(Zsc.AvgDiagonal(), Zsc.AvgOffDiagonal()); + else + result = CZero; + return result; + } + + + int TDSSBus::FindIdx(int NodeNum) + // Returns Index + + { + int result = 0; + int i = 0; + for (int stop = FNumNodesThisBus, i = 1; i <= stop; i++) + { + if (Nodes[i - 1] == NodeNum) + { + result = i; + return result; + } + } + result = 0; + return result; + } + + void TDSSBus::AllocateBusVoltages() + { + int i = 0; + VBus.resize(FNumNodesThisBus + 1); + for (int stop = FNumNodesThisBus, i = 1; i <= stop; i++) + VBus[i - 1] = CZero; + } + + + void TDSSBus::AllocateBusCurrents() + { + int i = 0; + BusCurrent.resize(FNumNodesThisBus + 1); + for (int stop = FNumNodesThisBus, i = 1; i <= stop; i++) + BusCurrent[i - 1] = CZero; + } + +} + + + + + + + + + + diff --git a/OpenDSSC/Common/Bus.h b/OpenDSSC/Common/Bus.h new file mode 100644 index 0000000..5e82e08 --- /dev/null +++ b/OpenDSSC/Common/Bus.h @@ -0,0 +1,113 @@ +#ifndef BusH +#define BusH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 2/4/03 added Zsc and Zsc1, Zsc0 properties +*/ + + +#include "System.h" + +#include "Arraydef.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "NamedObject.h" + + + + +//class TDSSBus; +//struct TNodeBus; + +namespace Bus +{ + + + class TDSSBus : public TNamedObject { + typedef TNamedObject inherited; + public: +// private: + int FNumNodesThisBus; + std::vector Nodes; + int Allocation; + std::vector RefNo; + void AddANode(); + complex Get_Zsc0(); + complex Get_Zsc1(); + public: + vector VBus, BusCurrent; + TcMatrix Zsc, Ysc, Zsc012; // GIS coords + // coordinates + // Base kV for each node to ground (0) + double lat, longitude, x, y, kVBase, DistFromMeter; + bool GISCoordDefined, CoordDefined, BusChecked, Keep, IsRadialBus; // Flag for general use in bus searches + + // ***** Reliability Variables + double BusFltRate; // Accumulated failure rate downstream from this bus faults per year + double Bus_Num_Interrupt; // Number of interruptions this bus per year + double Bus_Int_Duration; // Avg Annual Interruption duration for this bus + double BusCustInterrupts; // Accumulated Number of customer interruptions from this bus + double BusCustDurations; // Accumulated Customer outage durations + int BusTotalNumCustomers; // Total Number of customers served from this bus + double BusTotalMiles; // Total length of lines downstream from this bus for Duke siting algorithm + int BusSectionID; // ID of the feeder section this bus belongs to + TDSSBus(); + virtual ~TDSSBus(); + void AllocateBusQuantities(); + void AllocateBusVoltages(); + void AllocateBusCurrents(); + int Add(int NodeNum, int ActorID); + int Find(int NodeNum); // Returns reference num for node by node number + int FindIdx(int NodeNum); // Returns index of node by node number + int GetRef(int NodeIndex); // Returns reference Num for node by node index + int GetNum(int NodeIndex); // Returns ith node number designation + int get_FNumNodesThisBus(); + + private: + // Private copy constructor and assignment, because + // copying leads to multiple ownership of VBus and BusCurrent arrays, + // which leads to double-free when we try to delete them. + TDSSBus(const TDSSBus&); + TDSSBus& operator=(const TDSSBus&); + }; + + // Bus Collection + + + + typedef vector pTBusArray; + typedef TDSSBus* TBusArray[10/*# range 1..10*/]; + + struct TNodeBus { + int BusRef; // Ref to Bus in circuit's BusList, 1-based + int NodeNum; + }; + + + typedef vector pTNodeBusArray; + typedef TNodeBus TNodeBusArray[2/*# range 1..2*/]; + +} // namespace Bus + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Bus; +#endif + +#endif // BusH + + + + + + + + + + + diff --git a/OpenDSSC/Common/Circuit.cpp b/OpenDSSC/Common/Circuit.cpp new file mode 100644 index 0000000..d85e378 --- /dev/null +++ b/OpenDSSC/Common/Circuit.cpp @@ -0,0 +1,2548 @@ +#pragma hdrstop + +#include "Circuit.h" + +#include "DSSGlobals.h" +#include +#include +#include "dirsep.h" + +using namespace std; + +//---------------------------------------------------------------------------- + +namespace Circuit +{ + + TDSSCircuit::TDSSCircuit(const String aName) + + // Var Retval:Integer; + + : inherited("Circuit"), + NodeBufferMax(0), + FBusNameRedefined(false), + SavedNumBuses(0), + FLoadMultiplier(0.0), + AbortBusProcess(false), + ActiveBusIndex(0), + Fundamental(0.0), + Control_BusNameRedefined(false), + UEWeight(0.0), + LossWeight(0.0), + NumUEregs(0), + NumLossRegs(0), + CapacityStart(0.0), + CapacityIncrement(0.0), + TrapezoidalIntegration(false), + LogEvents(false), + NumDevices(0), + NumBuses(0), + NumNodes(0), + MaxDevices(0), + MaxBuses(0), + MaxNodes(0), + IncDevices(0), + IncBuses(0), + IncNodes(0), + Coverage(0.0), + Actual_Coverage(0.0), + Num_SubCkts(0), + VIndex(0), + VLength(0), + AD_Init(false), + Issolved(false), + DuplicatesAllowed(false), + ZonesLocked(false), + MeterZonesComputed(false), + PositiveSequence(false), + NeglectLoadY(false), + NormalMinVolts(0.0), + NormalMaxVolts(0.0), + EmergMaxVolts(0.0), + EmergMinVolts(0.0), + GeneratorDispatchReference(0.0), + DefaultGrowthFactor(0.0), + DefaultGrowthRate(0.0), + GenMultiplier(0.0), + HarmMult(0.0), + PriceSignal(0.0), + ReductionStrategy(rsDefault), + ReductionZmag(0.0), + ReduceLateralsKeepLoad(false), + PctNormalFactor(0.0), + NodeMarkerCode(0), + NodeMarkerWidth(0), + SwitchMarkerCode(0), + TransMarkerSize(0), + CapMarkerSize(0), + RegMarkerSize(0), + PVMarkerSize(0), + StoreMarkerSize(0), + FuseMarkerSize(0), + RecloserMarkerSize(0), + RelayMarkerSize(0), + TransMarkerCode(0), + CapMarkerCode(0), + RegMarkerCode(0), + PVMarkerCode(0), + StoreMarkerCode(0), + FuseMarkerCode(0), + RecloserMarkerCode(0), + RelayMarkerCode(0), + MarkSwitches(false), + MarkTransformers(false), + MarkCapacitors(false), + MarkRegulators(false), + MarkPVSystems(false), + MarkStorage(false), + MarkFuses(false), + MarkReclosers(false), + MarkRelays(false), + NumCircuits(0), + ActiveLoadShapeClass(0) + { + DeviceRef.clear(); + SolutionClass[ActiveActor]->NewObject(Get_Name()); + Solution = ActiveSolutionObj; + Set_myLName(LowerCase(aName)); + Set_CaseName(aName); // Default case name to circuitname + // Sets CircuitName_ + Fundamental = DefaultBaseFreq; + Set_ActiveCktElement(NULL); + ActiveBusIndex = 0; // Always a bus + + // initial allocations increased from 100 to 1000 to speed things up + MaxBuses = 1000; // good sized allocation to start + MaxDevices = 1000; + MaxNodes = 3 * MaxBuses; + IncDevices = 1000; + IncBuses = 1000; + IncNodes = 3000; + + // Allocate some nominal sizes + BusList = THashList(900); // Bus name list Nominal size to start; gets reallocated + DeviceList = THashList(900); + AutoAddBusList = THashList(100); + NumBuses = 0; // Eventually allocate a single source + NumDevices = 0; + NumNodes = 0; + Faults = TPointerList(2); + CktElements = TPointerList(1000); + PDElements = TPointerList(1000); + PCElements = TPointerList(1000); + DSSControls = TPointerList(10); + Sources = TPointerList(10); + MeterElements = TPointerList(20); + Monitors = TPointerList(20); + /*by Dahei*/ + FMonitors = TPointerList(20); + /**/ + EnergyMeters = TPointerList(5); + Sensors = TPointerList(5); + Generators = TPointerList(5); + WindGens = TPointerList(5); + StorageElements = TPointerList(5); + + PVSystems = TPointerList(5); + InvControls2 = TPointerList(5); + ExpControls = TPointerList(5); + Feeders = TPointerList(10); + Substations = TPointerList(5); + Transformers = TPointerList(10); + AutoTransformers = TPointerList(10); + CapControls = TPointerList(10); + SwtControls = TPointerList(50); + RegControls = TPointerList(5); + Lines = TPointerList(1000); + Loads = TPointerList(1000); + ShuntCapacitors = TPointerList(20); + Reactors = TPointerList(5); + Reclosers = TPointerList(10); + Relays = TPointerList(10); + Fuses = TPointerList(50); + + // BHSL + Gencls = TPointerList(50); + Genrou = TPointerList(50); + //JT + ExcSexs = TPointerList(50); + Tgov = TPointerList(50); + + Buses.resize(MaxBuses); + MapNodeToBus.resize(MaxNodes); + DeviceRef.resize(static_cast(MaxDevices) + 1); + ControlQueue = TControlQueue(); + LegalVoltageBases.resize(8); + // Default Voltage Bases + LegalVoltageBases[0] = 0.208; + LegalVoltageBases[1] = 0.480; + LegalVoltageBases[2] = 12.47; + LegalVoltageBases[3] = 24.9; + LegalVoltageBases[4] = 34.5; + LegalVoltageBases[5] = 115.0; + LegalVoltageBases[6] = 230.0; + LegalVoltageBases[7] = 0.0; // terminates array + ActiveLoadShapeClass = USENONE; // Signify not set + NodeBufferMax = 50; + NodeBuffer.resize(static_cast(NodeBufferMax) + 1); // A place to hold the nodes + + // Init global circuit load and harmonic source multipliers + FLoadMultiplier = 1.0; + GenMultiplier = 1.0; + HarmMult = 1.0; + PriceSignal = 25.0; // $25/MWH + + // Factors for Autoadd stuff + UEWeight = 1.0; // Default to weighting UE same as losses + LossWeight = 1.0; + NumUEregs = 1; + NumLossRegs = 1; + UEregs = NULL; // set to something so it wont break reallocmem + LossRegs = NULL; + UEregs = new longInt[NumUEregs]; + LossRegs = new longInt[NumLossRegs]; + UEregs[1 - 1] = 10; // Overload UE + LossRegs[1 - 1] = 13; // Zone Losses + CapacityStart = 0.9; // for Capacity search + CapacityIncrement = 0.005; + LoadDurCurve = ""; + LoadDurCurveObj = NULL; + PriceCurve = ""; + PriceCurveObj = NULL; + + // Flags + DuplicatesAllowed = false; + ZonesLocked = false; // Meter zones recomputed after each change + MeterZonesComputed = false; + PositiveSequence = false; + NeglectLoadY = false; + LongLineCorrection = false; + NormalMinVolts = 0.95; + NormalMaxVolts = 1.05; + EmergMaxVolts = 1.08; + EmergMinVolts = 0.90; + NodeMarkerCode = 16; + NodeMarkerWidth = 1; + MarkSwitches = false; + MarkTransformers = false; + MarkCapacitors = false; + MarkRegulators = false; + MarkPVSystems = false; + // MarkPVSystems2 := FALSE; + MarkStorage = false; + // MarkStorage2 := FALSE; + MarkFuses = false; + MarkReclosers = false; + SwitchMarkerCode = 5; + TransMarkerCode = 35; + CapMarkerCode = 38; + RegMarkerCode = 17; //47; + PVMarkerCode = 15; + StoreMarkerCode = 9; + FuseMarkerCode = 25; + RecloserMarkerCode = 17; + RelayMarkerCode = 17; + TransMarkerSize = 1; + CapMarkerSize = 3; + RegMarkerSize = 5; //1; + PVMarkerSize = 1; + StoreMarkerSize = 1; + FuseMarkerSize = 1; + RecloserMarkerSize = 5; + RelayMarkerSize = 5; + BusMarkerList.clear(); + TrapezoidalIntegration = false; // Default to Euler method + LogEvents = false; + GeneratorDispatchReference = 0.0; + DefaultGrowthRate = 1.025; + DefaultGrowthFactor = 1.0; + DefaultDailyShapeObj = ((TLoadShapeObj*)LoadShapeClass[ActiveActor]->Find("default")); + DefaultYearlyShapeObj = ((TLoadShapeObj*)LoadShapeClass[ActiveActor]->Find("default")); + CurrentDirectory = ""; + Set_BusNameRedefined(true); // set to force rebuild of buslists, nodelists + SavedBuses.clear(); + SavedBusNames = NULL; + ReductionStrategy = rsDefault; + // ReductionMaxAngle := 15.0; + ReductionZmag = 0.02; + NumCircuits = 0; + ReduceLateralsKeepLoad = true; + + /*Misc objects*/ + AutoAddObj = TAutoAdd(); + Branch_List = NULL; + BusAdjPC.clear(); + BusAdjPD.clear(); + + // tearing algorithm vars initialization + Coverage = 0.9; // 90% coverage expected by default + Actual_Coverage = -1; //No coverage + Num_SubCkts = CPU_Cores - 1; + Longest_paths.clear(); + Path_Idx.clear(); + Buses_Covered.clear(); + Path_Size.clear(); + + // Diakoptics variables + Contours = TSparse_Complex(); + ZLL = TSparse_Complex(); + ZCC = TSparse_Complex(); + ZCT = TSparse_Complex(); + Y4 = TSparse_Complex(); + V_0 = TSparse_Complex(); + Ic = TSparse_Complex(); + } + + + TDSSCircuit::~TDSSCircuit() + { + int i = 0; + TDSSCktElement* pCktElem; + String ElemName; + for (int stop = NumDevices, i = 1; i <= stop; i++) + { + try + { + pCktElem = (TDSSCktElement*)CktElements.Get(i); + // ElemName := pCktElem.ParentClass.name + '.' + pCktElem.Name; + ElemName = ((TDSSObject*)pCktElem)->Get_myPName() + "." + ((TDSSObject*)pCktElem)->get_Name(); + delete pCktElem; //pCktElem->~TDSSCktElement(); + } + catch (exception& E) + { + DoSimpleMsg("Exception Freeing Circuit Element:" + ElemName + CRLF + (std::string)E.what(), 423); + } + } + for (int stop = NumBuses, i = 1; i <= stop; i++) + delete Buses[i - 1]; // added 10-29-00 + /*(DeviceRef, 0); + ReallocMem( Buses, 0 ); + ReallocMem( MapNodeToBus, 0 ); + ReallocMem( NodeBuffer, 0 ); + ReallocMem( UEregs, 0 ); + ReallocMem( LossRegs, 0 ); + ReallocMem( LegalVoltageBases, 0 );*/ // sounds irrelevant in this context - I may be wrong + delete Solution; + // Storage2Elements.Free; + // PVSystems2.Free; + /*by Dahei*/ + /**/ + ClearBusMarkers(); + FreeTopology(); + + // Release all ADiakoptics matrixes + /*Contours.Free; // problematic for now 12/15/2021 + ZLL.Free; + ZCC.Free; + ZCT.Free; + Y4.Free; + V_0.Free; + Ic.Free;*/ + // todo check: inherited::Destroy; + if (SavedBusNames != NULL) + delete[] SavedBusNames; + + delete[] UEregs; + delete[] LossRegs; + + } + + /******************************************************************************** + * Routine created to empty a recently created folder * + *********************************************************************************/ + + + void DelFilesFromDir(String Directory, String FileMask, bool DelSubDirs) + { + /* + String SourceLst; + TSHFileOpStruct FOS; + FillChar( FOS, sizeof( FOS ), 0 ); + FOS.wFunc = FO_DELETE; + SourceLst = Directory + DIRSEP_STR + FileMask + "\x00"; + FOS.pFrom = SourceLst.c_str(); + if ( ! DelSubDirs ) + FOS.fFlags = FOS.fFlags | FOF_FILESONLY; + // Remove the next line if you want a confirmation dialog box + FOS.fFlags = FOS.fFlags | FOF_NOCONFIRMATION; + // Add the next line for a "silent operation" (no progress box) + FOS.fFlags = FOS.fFlags | FOF_SILENT; + SHFileOperation( FOS ); + */ + } + + /******************************************************************************** + * This routine retuns the index of the element within the array * + *********************************************************************************/ +#define MAXIDX(x) (sizeof(x)/sizeof(x[0]))-1 + + + int get_element_Idx(pIntegerArray graph_in, int graph_in_maxidx, int element) + { + int result = 0; + + // To indicate that the element was found + + bool Found = false, End_Flag = false; + int Graph_size = 0, Local_idx = 0; + result = -1; // In case the element is not in the array + End_Flag = true; // To control the algorithm execution (while based) + Local_idx = 0; + Found = false; // Not found yet + Graph_size = (graph_in_maxidx + 1); + while ((End_Flag) && (Local_idx < Graph_size)) + { + if ((graph_in)[Local_idx] == element) + { + End_Flag = false; + Found = true; + } + else + { + Local_idx++; + } + } + if (Found) + result = Local_idx; + return result; + } + /******************************************************************************** + * This routine calculates the longest path within a linearized * + * graph considering the zero level buses as the beginning of * + * new path * + *********************************************************************************/ + + + void TDSSCircuit::get_longest_path() + { + bool End_Flag = false; // Terminates the process + // Stores the Index value of the current level + + int Current_Idx = 0 // Stores the current level traced + , Current_level = 0; + /*# with Solution do */ + TSolutionObj with0 = *Solution; + { + Current_level = MaxIntValue(&with0.Inc_Mat_levels); // Init level + Current_Idx = get_element_Idx((pIntegerArray)&with0.Inc_Mat_levels, MAXIDX(with0.Inc_Mat_levels), Current_level); // Init Index + End_Flag = true; + New_Graph.clear(); + while (End_Flag) + { + //Checks the termination cirteria + if ((Current_level > with0.Inc_Mat_levels[Current_Idx]) || (with0.Inc_Mat_levels[Current_Idx] == 0)) + End_Flag = false; + // Is the current bus part of the new backbone? + if (with0.Inc_Mat_levels[Current_Idx] == Current_level) + { + Current_level--; + New_Graph.push_back(Current_Idx); + } + Current_Idx--; + } + } + } + /******************************************************************************** + * This routine appends an array to the paths array and returns its index * + *********************************************************************************/ + + + int TDSSCircuit::Append2PathsArray(std::vector < int >* New_Path, int New_Path_maxidx) + { + int result = 0; + int Local_idx = 0; + result = Longest_paths.size(); + for (int stop = New_Path_maxidx /*# High(New_Path) */, Local_idx = 0; Local_idx <= stop; Local_idx++) + { + Longest_paths.push_back((*New_Path)[Local_idx]); + } + return result; + } + + void TDSSCircuit::AggregateProfiles(String mode) + { + //TBD + } + /******************************************************************************** + * This routine normalizes the Inc_matrix levels * + *********************************************************************************/ + + + void TDSSCircuit::Normalize_graph() + { + + // To set the active level + + int Curr_level = 0 // + , idx = 0; + bool Ref_detected = false; // To detect if there is a zero + Curr_level = -1; // Initializing values + Ref_detected = false; + /*# with Solution do */ + TSolutionObj with0 = *Solution; + { + for (int stop = (with0.Inc_Mat_levels.size() - 1), idx = 0; idx <= stop; idx++) // Sweeps the whole graph + { + if (with0.Inc_Mat_levels[idx] == 0) + Ref_detected = true; + else + { + if ((Curr_level >= with0.Inc_Mat_levels[idx]) || Ref_detected) + { + Ref_detected = false; + Curr_level = with0.Inc_Mat_levels[idx] - 1; + with0.Inc_Mat_levels[idx] = 1; + } + else + with0.Inc_Mat_levels[idx] = with0.Inc_Mat_levels[idx] - Curr_level; + } + } + } + } + + /******************************************************************************** + * Traces the paths (0) in the graph to guarantee the desired coverage * + *********************************************************************************/ +#define MAXIDX(x) (sizeof(x)/sizeof(x[0]))-1 + + + void TDSSCircuit::Get_paths_4_Coverage() + { + + // For storing temoprary doubles + + double DBLTemp = 0.0 // Stores the number of buses contained in the system + , Sys_Size = 0.0; + bool SMEnd = false; // Terminates the state machine + + int i = 0 // The current state of the state machine + , State = 0; + std::vector < int > Candidates; // Array for 0 level buses idx + TSolutionObj with0 = *Solution; + { + SMEnd = true; + State = 0; + Sys_Size = ((double)with0.Inc_Mat_Cols.size()); + Buses_Covered.resize(1); + Path_Idx.resize(1); + Actual_Coverage = -1; + while (SMEnd) // The state machine starts + { + switch (State) + { + case 0: + { // Processes the first path + Candidates.clear(); + for (int stop = ((with0.Inc_Mat_levels.size()) - 1), i = 0; i <= stop; i++) //Extracts the 0 Level Buses + { + if (with0.Inc_Mat_levels[i] == 0) + { + Candidates.push_back(i); + } + } + Longest_paths.clear(); + Buses_Covered[0] = MaxIntValue(&Candidates); // Extracts the maximum level covered + Path_Idx[0] = Append2PathsArray(&Candidates, MAXIDX(Candidates)); // No shifting in the graph + State = 1; // Go to the next state + } + break; + case 1: + { // Extracts a new path from the longest branch to + get_longest_path(); // the backbone (Zeros) + Path_Idx.push_back(Append2PathsArray(&New_Graph, MAXIDX(New_Graph))); // Adds the new candidates + // Estimates the amount of buses covered in this path + Buses_Covered.push_back(New_Graph[0] - New_Graph.back()); + // Replaces the latest path with 0 in the Bus levels array + for (int stop = (Longest_paths.size() - 1), i = Path_Idx[Path_Idx.back()]; i <= stop; i++) + with0.Inc_Mat_levels[Longest_paths[i]] = 0; + Normalize_graph(); + // remains in the same state + } + break; + } + // Checks the coverage index to stablish if is necessary to keep tracing paths to increase the coverage + DBLTemp = 0.0; + for (int stop = (Buses_Covered.size() - 1), i = 0; i <= stop; i++) + DBLTemp = DBLTemp + (0.0 + Buses_Covered[i]); + DBLTemp = DBLTemp / Sys_Size; + /* If the New coverage is different from the previous one and is below the expected coverage keep going + The first criteria is to avoid keep working on a path that will not contribute to improve the coverage*/ + if ((DBLTemp != Actual_Coverage) && (DBLTemp >= Coverage)) + SMEnd = false; + Actual_Coverage = DBLTemp; + } + } + } + + /******************************************************************************** + * Appends single phase ISources to the each node of bus specified * + * if the given linkBranch. This actions take place within the given file. * + ******************************************************************************** + */ + + TDSSCktElement* TDSSCircuit::get_FActiveCktElement() + { + return FActiveCktElement; + } + + void TDSSCircuit::AppendIsources(String myPath, int BusNum, String LinkBranch) + { + size_t jj = 0; + int kk = 0; + String text, BusName; + TTextRec myFile; + System::AssignFile(myFile, myPath); + System::Append(myFile); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + SetElementActive(LinkBranch); + BusName = with0->get_FActiveCktElement()->GetBus(BusNum); + jj = BusName.find('.'); // removes the dot + if (jj != String::npos) + BusName = BusName.substr(0, jj); + SetActiveBus(BusName); + Bus::TDSSBus& pBus = *Buses[ActiveBusIndex]; + for (int stop = pBus.get_FNumNodesThisBus(), kk = 1; kk <= stop; kk++) + { + text = "New ISource." + IntToStr(BusNum) + "_" + IntToStr(kk) + " phases=1 bus1=" + BusName + "." + IntToStr(kk) + " amps=0.000001 angle=0"; + System::WriteLn(myFile, text); + } + } + } + System::CloseFile(myFile); + } + + /******************************************************************************** + * This routine reads the master file of the torn circuit and creates the * + * header definitions for declaring separate subcircuits in OpenDSS * + * The flag AddISrc indicates if its necessary to create * + * Isources at the edges of the link branches, the ISource * + * magnitude is equal to 0.000001, angle 0 (for A-Diakoptics) * + *********************************************************************************/ + + + void TDSSCircuit::Format_SubCircuits(String Path, int NumCkts, bool AddISrc) + { + TTextRec myFile; + String Temp_txt, Temp_txt2, text; + std::vector < String > Xtra, File_Struc; + bool Str_Found = false; + size_t Local_Temp = 0; + int FS_Idx = 0, FS_Idx1 = 0, FS_Idx2 = 0; + String Reference[6/*# range 0..5*/]; + Reference[0] = "Redirect EnergyM"; + Reference[1] = "Redirect Monitor"; + Reference[2] = "MakeBu"; + Reference[3] = "Redirect BusVolta"; + Reference[4] = "Buscoords busco"; + Reference[5] = "Redirect zone"; + // Reads the master file + System::AssignFile(myFile, Path + DIRSEP_STR "master.dss"); + System::Reset(myFile); // Prepares for reading + IOResultToException(); + File_Struc.clear(); + FS_Idx = 0; + while (!Eof(myFile)) // Extracts the file content as an array of strings + { + System::ReadLn(myFile, text); + File_Struc.push_back(text); + FS_Idx++; + } + System::CloseFile(myFile); + // Creates the copy for the interconnected system + Xtra.clear(); + System::AssignFile(myFile, Path + DIRSEP_STR "Master_Interconnected.dss"); + System::Rewrite(myFile); // Prepares for writing + IOResultToException(); + for (int stop = (File_Struc.size() - 1), FS_Idx = 0; FS_Idx <= stop; FS_Idx++) + { + Str_Found = false; + for (int stop = 5, FS_Idx1 = 0; FS_Idx1 <= stop; FS_Idx1++) + { + Local_Temp = File_Struc[FS_Idx].find(Reference[FS_Idx1]); + Str_Found = (Local_Temp != String::npos) || Str_Found; + } + if (Str_Found) + { + Xtra.push_back(File_Struc[FS_Idx]); + } + else + System::WriteLn(myFile, File_Struc[FS_Idx]); + } + // Adds the zones and the rest to the file + for (int stop = (Xtra.size() - 1), FS_Idx = 0; FS_Idx <= stop; FS_Idx++) + { + System::WriteLn(myFile, Xtra[FS_Idx]); + } + System::CloseFile(myFile); + + // removes the unnecessary information from the master file (deletes the other zones) + System::AssignFile(myFile, Path + DIRSEP_STR "master.dss"); + System::Rewrite(myFile); // Prepares for writing + IOResultToException(); + for (int stop = (File_Struc.size() - 1), FS_Idx = 0; FS_Idx <= stop; FS_Idx++) + { + Local_Temp = File_Struc[FS_Idx].find("Redirect zone"); + if (Local_Temp == String::npos) + { + Local_Temp = File_Struc[FS_Idx].find("Redirect EnergyM"); + if (Local_Temp == String::npos) + { + Local_Temp = File_Struc[FS_Idx].find("Redirect Monitor"); + if (Local_Temp == String::npos) + System::WriteLn(myFile, File_Struc[FS_Idx]); + } + } + } + System::CloseFile(myFile); + + // Adds Isources at the link branch edges if requested + if (AddISrc) + AppendIsources(Path + DIRSEP_STR "master.dss", 1, Link_Branches[1]); + + // Copies the support files to the zones directories + FS_Idx = 0; + while (FS_Idx != -1) + { + Local_Temp = File_Struc[FS_Idx].find("Redirect zone"); + if (Local_Temp == String::npos) + { + Local_Temp = File_Struc[FS_Idx].find("Redirect "); + if (Local_Temp != String::npos) + { + text = regex_replace(File_Struc[FS_Idx], std::regex("Redirect "), ""); + for (int stop = NumCkts, FS_Idx1 = 2; FS_Idx1 <= stop; FS_Idx1++) + CopyFile(AnsiString(Path + DIRSEP_STR + text).c_str(), AnsiString(Path + DIRSEP_STR "zone_" + IntToStr(FS_Idx1) + DIRSEP_STR + text).c_str(), true); + } + FS_Idx++; + } + else + FS_Idx = -1; // Ends the routine + } + // Creates the master file for each subcircuit + for (int stop = NumCkts, FS_Idx = 2; FS_Idx <= stop; FS_Idx++) + { + System::AssignFile(myFile, Path + DIRSEP_STR "zone_" + IntToStr(FS_Idx) + DIRSEP_STR "master.dss"); + System::Rewrite(myFile); + IOResultToException(); + System::WriteLn(myFile, "Clear"); + System::WriteLn(myFile, "New Circuit.Zone_" + IntToStr(FS_Idx)); + FS_Idx1 = 2; + while (FS_Idx1 != -1) // Writes the global files + { + Local_Temp = File_Struc[FS_Idx1].find("Redirect zone"); + if (Local_Temp == String::npos) + { + System::WriteLn(myFile, File_Struc[FS_Idx1]); + FS_Idx1++; + } + else + FS_Idx1 = -1; + } + for (int stop = (File_Struc.size() - 1), FS_Idx1 = 0; FS_Idx1 <= stop; FS_Idx1++) // Writes the zone files + { + Local_Temp = File_Struc[FS_Idx1].find("Redirect zone_" + IntToStr(FS_Idx)); + if (Local_Temp != String::npos) + { + text = regex_replace(File_Struc[FS_Idx1], std::regex("zone_" + IntToStr(FS_Idx) + DIRSEP_STR), ""); + System::WriteLn(myFile, text); + } + } + System::CloseFile(myFile); + + // Adds Isources at the link branch edges if requested + if (AddISrc) + { + text = Path + DIRSEP_STR "zone_" + IntToStr(FS_Idx) + DIRSEP_STR "master.dss"; + AppendIsources(text, 2, Link_Branches[FS_Idx]); + // If there is another link branch, means that this zone conencts with other through ZCC + // Add Another current source at the point of connection + if (Link_Branches.size() > FS_Idx) + AppendIsources(text, 1, Link_Branches[FS_Idx]); + } + } + // Sets the properties of the VSource on each subcricuit based on the latest voltage measured + FS_Idx1 = 0; + for (int stop = NumCkts, FS_Idx = 1; FS_Idx <= stop; FS_Idx++) + { + if (FS_Idx == 1) + System::AssignFile(myFile, Path + DIRSEP_STR "VSource.dss"); + else + System::AssignFile(myFile, Path + DIRSEP_STR "zone_" + IntToStr(FS_Idx) + DIRSEP_STR "VSource.dss"); + System::Rewrite(myFile); + IOResultToException(); + for (int stop = 3, FS_Idx2 = 1; FS_Idx2 <= stop; FS_Idx2++) + { + if (FS_Idx2 == 1) + { + Temp_txt = "source"; + Temp_txt2 = "Edit "; + } + else + { + Temp_txt = "Vph_" + IntToStr(FS_Idx2); + Temp_txt2 = "New "; + } + text = Temp_txt2 + "Vsource." + Temp_txt + " bus1=" + PConn_Names[FS_Idx] + "." + IntToStr(FS_Idx2) + " phases=1 pu=1.0" + " basekv=" + FloatToStrF(static_cast(PConn_Voltages[FS_Idx1]), ffGeneral, 8, 3) + " angle=" + + FloatToStrF(static_cast(PConn_Voltages[static_cast>::size_type>(FS_Idx1) + 1]), ffGeneral, 8, 3) + " R1=0 X1=0.001 R0=0 X0=0.001"; + + System::WriteLn(myFile, text); + FS_Idx1 = FS_Idx1 + 2; + } + System::CloseFile(myFile); + } + } + + /******************************************************************************** + * Saves the subcircuits created in memory into the hard drive * + * The flag AddISrc indicates if its necessary to create * + * Isources at the edges of the link branches, the ISource * + * magnitude is equal to 0.000001, angle 0 (for A-Diakoptics) * + ******************************************************************************** + */ + + + void TDSSCircuit::Save_SubCircuits(bool AddISrc) + { + String Fileroot; + // Prepares everything to save the base of the torn circuit on a separate folder + Fileroot = GetCurrentDir(); + Fileroot = Fileroot + DIRSEP_STR "Torn_Circuit"; + CreateDir(Fileroot); // Creates the folder for storing the modified circuit + DelFilesFromDir(Fileroot, "*", true); // Removes all the files inside the new directory (if exists) + DSSExecutive[ActiveActor]->Set_Command(String("save circuit Dir=\"") + Fileroot + "\""); + // This routine extracts and modifies the file content to separate the subsystems as OpenDSS projects indepedently + Format_SubCircuits(Fileroot, Locations.size(), AddISrc); + } + + /******************************************************************************** + * Delivers the name of the bus at the specific line and terminal * + ********************************************************************************/ + + + String TDSSCircuit::get_Line_Bus(String LName, int NBus) + { + String result; + int i = 0, activesave = 0; + TLineObj* pLine; + String S; + bool Found = false; + String* NBuses; + NBuses = new std::string[2]; + if (ActiveCircuit[ActiveActor] != NULL) + { // Search list of Lines in active circuit for name + /*# with ActiveCircuit[ActiveActor].Lines do */ + TPointerList with0 = ActiveCircuit[ActiveActor]->Lines; + { + S = LName; // Convert to Pascal String + Found = false; + activesave = with0.get_myActiveItem(); + pLine = (TLineObj*)with0.Get_First(); + while (pLine != NULL) + { + if (CompareText(((TDSSObject*)pLine)->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + Found = true; + break; + } + pLine = (TLineObj*)with0.Get_Next(); + } + if (!Found) + { + DoSimpleMsg(String("Line \"") + S + "\" Not Found in Active Circuit.", 5008); + pLine = (TLineObj*)with0.Get(activesave); // Restore active Line + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + } + } + for (int stop = ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Get_NTerms(), i = 1; i <= stop; i++) + NBuses[i] = ActiveCircuit[ActiveActor]->get_FActiveCktElement()->GetBus(i); + // returns the name of the desired bus + result = NBuses[NBus]; + } + return result; + } + + /******************************************************************************** + * Generates the graph file for MeTIS within the project's folder * + ********************************************************************************/ + + + String TDSSCircuit::Create_MeTIS_graph() + { + String result; + bool exists = false; + int myIntVar = 0, k = 0, jj = 0, i = 0; + String myClass, myName, Filename; + TTextRec F; + std::vector < String > myPDEList, MyGraph; + std::vector < int > MyIdx; + /*# with Solution do */ + TSolutionObj with0 = *Solution; + { + // Calculates the incidence matrix and laplacian to generate the graph file to be + // send to MeTiS + with0.Calc_Inc_Matrix_Org(ActiveActor); //Calculates the ordered incidence matrix + // Initializes the METIS related variables + myPDEList.clear(); + MyGraph.clear(); + with0.Laplacian = with0.IncMat.Transpose(); // Transposes the Incidence Matrix + with0.Laplacian = with0.Laplacian.multiply(&(with0.IncMat)); // Laplacian Matrix calculated + // Filters the incidence matrix to remove duplicated branches (parallel) + for (int stop = (with0.Inc_Mat_Cols.size() - 1), i = 0; i <= stop; i++) + { + MyIdx.clear(); + myName = with0.Inc_Mat_Cols[i]; + // first, get the name of all PDE conencted to this Bus + for (int stop = (with0.IncMat.NZero() - 1), jj = 0; jj <= stop; jj++) + { + if (with0.IncMat.data[jj][1] == i) + { + // Check if this is not a parallel branch + exists = false; + if (MyIdx.size() > 1) // Only if it's not the first time + { + for (int stop = (MyIdx.size() - 2) / 2, k = 0; k <= stop; k++) + { + // Checks for the other terminal + if (jj < (with0.IncMat.data.size() - 1)) + { + if (static_cast(jj + 1) < with0.IncMat.data.size() && static_cast(1) < with0.IncMat.data[static_cast(jj) + 1].size()) { + myIntVar = with0.IncMat.data[static_cast(jj + 1)][static_cast(1)]; + } + else + myIntVar = with0.IncMat.data[jj][1]; + } + else + myIntVar = with0.IncMat.data[jj][1]; + if (MyIdx[static_cast(k) * 2] == myIntVar) + { + exists = true; + break; + } + } + } + if (!exists) + { + // Stores the name of the PDE + myName = with0.Inc_Mat_Rows[with0.IncMat.data[jj][0]]; + myPDEList.push_back(myName); + //myPDEList.size() = myPDEList.size() + 1; + // Checks for the other terminal + if (jj < (with0.IncMat.data.size() - 1)) + { + if (with0.IncMat.data[static_cast(jj) + 1][0] == with0.IncMat.data[jj][0]) + MyIdx[MyIdx.size()] = with0.IncMat.data[static_cast(jj) + 1][1]; + else + MyIdx[MyIdx.size()] = with0.IncMat.data[jj][1]; + } + else + MyIdx.push_back(with0.IncMat.data[jj][1]); + //MyIdx.Length = MyIdx.Length + 1; + // Now, get the number of Phases + myIntVar = myName.find("."); + myClass = myName.substr(0, static_cast(myIntVar)); + // if transformer, the weigth is the lowest + if (myClass != "Transformer") + { + ActiveCircuit[ActiveActor]->SetElementActive(myName); + myIntVar = ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Get_NPhases(); + } + else + myIntVar = 1; + MyIdx.push_back(myIntVar); + //MyIdx.Length = MyIdx.Length + 1; + } + } + } + //MyIdx.Length = MyIdx.Length - 1; + myName = ""; + for (int stop = (MyIdx.size() - 1), jj = 0; jj <= stop; jj++) + myName = myName + IntToStr(MyIdx[jj]) + " "; + MyGraph.push_back(myName); + //MyGraph.Length = MyGraph.Length + 1; + } + MyGraph.resize(MyGraph.size() - 1); + myPDEList.resize(myPDEList.size() - 1); + /******************************************************************************** + Generates the graph file + *********************************************************************************/ + // Get_First(), get the number of branches in the model excluding parallel branches + jj = 0; + for (int stop = (with0.Inc_Mat_Rows.size() - 1), i = 0; i <= stop; i++) + { + // check if it's on the list + for (int stop = (myPDEList.size() - 1), k = 0; k <= stop; k++) + { + if (LowerCase(with0.Inc_Mat_Rows[i]) == LowerCase(myPDEList[k])) + { + jj++; + break; + } + } + } + Filename = GetOutputDirectory() + CircuitName_[ActiveActor] + ".graph"; + System::AssignFile(F, Filename); + System::Rewrite(F); + IOResultToException(); + System::WriteLn(F, IntToStr(with0.Inc_Mat_Cols.size()) + " " + IntToStr(jj) + " 1"); // it should be the rank of the incidence matrix + for (int stop = (MyGraph.size() - 1), i = 1; i <= stop; i++) + System::WriteLn(F, MyGraph[i]); + System::CloseFile(F); + } + result = Filename; + return result; + } + + /******************************************************************************** + * Executes MeTIS and gets the names of the link branches between zones * + *********************************************************************************/ + + + String TDSSCircuit::Create_MeTIS_Zones(String Filename) + { + String result; + bool Flag; + // For debugging + + String TreeNm, MeTISCmd, BusName, Terminal, TextCmd, PDElement; // Active Location + + int NodeIdx = 0, Num_Pieces = 0, Location_idx = 0, j = 0, jj = 0, dbg = 0, dbg2 = 0, i = 0; + TFileSearchReplace* Replacer; + Num_Pieces = Num_SubCkts; + /*# with Solution do */ + TSolutionObj with0 = *Solution; + { + /********************************************************************************************/ + // if Num_pieces <= 8 then MeTISCmd := 'kmetis.exe' // For less than 8 zones use pMeTIS + // else MeTISCmd := 'kmetis.exe'; // For more than 8 zonez use k-Way (kMeTIS) + // In the past we use to use pmetis and kmetis, however, in our latest update we realized kmetis is enough + // update 09-24-2020 by Davis Montenegro + MeTISCmd = "kmetis.exe"; + /********************************************************************************************/ + if (FileExists(AnsiString(Filename + ".part." + IntToStr(Num_Pieces)).c_str())) // Checks if the file exists before + DeleteFile(AnsiString(Filename + ".part." + IntToStr(Num_Pieces)).c_str()); + do + { + TextCmd = RunMeTIS(DSSDirectory + MeTISCmd + " \"" + Filename + "\" " + IntToStr(Num_Pieces)); // Executes MeTIS + Flag = (TextCmd.find("I detected an error") == String::npos); + if (Flag) // The # of edges was wrong, use the one proposed by MeTIS + { + TextCmd = GetNumEdges(TextCmd); // Gest the # of edges proposed by MeTIS + jj = IntToStr(with0.Inc_Mat_Cols.size()).size() + 2;// Caculates the index for replacing the number in the Graph File + // Replaces the old data with the new at the file header + Replacer = new TFileSearchReplace(Filename); + try + { + TReplaceFlags myreplaceFlags; + Replacer->Replace(IntToStr(with0.Inc_Mat_Cols.size()) + " " + IntToStr(with0.Inc_Mat_Cols.size() - 1), IntToStr(with0.Inc_Mat_Cols.size()) + + " " + TextCmd, myreplaceFlags); + // } + // __finally + // { + delete Replacer; + } + catch (...) + { + // Nothing to match with the DElphi implementation + } + } + } while (!(!Flag)); + /********************************************************************************************/ + // Verifies if there was no error executing MeTIS and the zones file was created + if ((TextCmd != "**Error**") && FileExists((Filename + ".part." + IntToStr(Num_Pieces)).c_str())) + { + std::string mypath = Filename + ".part." + IntToStr(Num_Pieces); + std::ifstream inf(mypath.c_str()); + std::string line; + while (getline(inf, line)) + MeTISZones.push_back(line); + + std::vector < std::string > temp; + TextCmd = MeTISZones[1]; + temp.push_back(TextCmd); + auto it2 = temp.begin(); + auto it3 = temp.end(); + auto it = MeTISZones.begin(); + MeTISZones.erase(it); + MeTISZones.insert(it, it2, it3); + Locations.resize(1); + BusZones.resize(1); + for (int stop = (MeTISZones.size() - 1), i = 0; i <= stop; i++) + { + if (i == 0) + { + Locations[i] = 0; + BusZones[i] = MeTISZones[i]; + } + else + { + if (MeTISZones[i] != BusZones[BusZones.size()]) // Moving to another zone in the file + { + j = 0; + if (i < (MeTISZones.size() - 1)) // If not lower means the zone is only 1 bus + j = ((int)(MeTISZones[i] == MeTISZones[static_cast(i) + 1])); + if (j == 1) // Varifies that the zone is big enough + { + j = 0; // Verifies that this zone hasn't been counted before + for (int stop = (BusZones.size() - 1), jj = 0; jj <= stop; jj++) + { + if (MeTISZones[i] == BusZones[jj]) + { + j++; + break; + } + } + if (j == 0) // Is not in the list, add the new location + { + // Locations.Length = Locations.Length + 1; // not needed with the adopted structures + // BusZones.Length = BusZones.Length + 1; + Locations.push_back(i); + BusZones.push_back(MeTISZones[i]); + } + } + } + } + } + } + for (int stop = (Locations.size() - 1), j = 0; j <= stop; j++) + Locations[j]++; //Adjust the location coords + } + result = TextCmd; + return result; + } + + /******************************************************************************** + * Disables all DER present in the model * + *********************************************************************************/ + + + void TDSSCircuit::Disable_All_DER() + { + int myDERIdx = 0, MyIdx = 0, DevClassIndex = 0; + vector < String > myDERList; + myDERList.resize(3); + { + String Circuit__0[3] = { "PVSystem" ,"Generator" , "Storage" }; + for (int stop = 2, MyIdx = 0; MyIdx <= stop; MyIdx++) + myDERList[MyIdx] = Circuit__0[MyIdx]; + } + for (int stop = (myDERList.size() - 1), myDERIdx = 0; myDERIdx <= stop; myDERIdx++) + { + DevClassIndex = ClassNames[ActiveActor].Find(myDERList[myDERIdx]); + LastClassReferenced[ActiveActor] = DevClassIndex; + ActiveDSSClass[ActiveActor] = (TDSSClass*)DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if (ActiveDSSClass[ActiveActor]->Get_ElementCount() > 0) + { + MyIdx = ActiveDSSClass[ActiveActor]->Get_First(); + do + { + get_FActiveCktElement()->Set_Enabled(false); + MyIdx = ActiveDSSClass[ActiveActor]->Get_Next(); + } while (!(MyIdx <= 0)); + } + } + } + /******************************************************************************** + * Returns the list of all PDE connected to the bus nam given at BusName * + *********************************************************************************/ + + + DynStringArray TDSSCircuit::getPDEatBus(String BusName) + { + DynStringArray result; + TDSSClass* Dss_Class; + int j = 0, i = 0; + vector < String > myBus; + DynStringArray myBusList; + myBus.resize(2); + result.clear(); + + BusName = LowerCase(BusName); + for (int stop = DSSClassList[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + { + Dss_Class = (TDSSClass*)DSSClassList[ActiveActor].Get(i); + if (dynamic_cast(Dss_Class)) + { + // Checks if it is a PCE class + if (dynamic_cast(Dss_Class)) + { + // If it is, checks all the elements to verify if one or more are + // connected to the bus given + Dss_Class->Get_First(); + for (int stop = Dss_Class->Get_ElementCount(), j = 1; j <= stop; j++) + { + myBus[0] = LowerCase(StripExtension(get_FActiveCktElement()->GetBus(1))); + myBus[1] = LowerCase(StripExtension(get_FActiveCktElement()->GetBus(2))); + if (((myBus[0] == BusName) || (myBus[1] == BusName)) && (myBus[0] != myBus[1])) + { + result.push_back(Dss_Class->get_myClass_name() + "." + ((TDSSObject*)get_FActiveCktElement())->get_Name()); + } + Dss_Class->Get_Next(); + } + } + } + } + if (result.empty()) + { + result.resize(1); + result[0] = "None"; + } + return result; + } + /******************************************************************************** + * Returns the list of all PCE connected to the bus nam given at BusName * + *********************************************************************************/ + + + DynStringArray TDSSCircuit::getPCEatBus(String BusName) + { + DynStringArray result; + TDSSClass* Dss_Class; + int j = 0, i = 0; + String myBus; + DynStringArray myBusList; + result.clear(); + + BusName = LowerCase(BusName); + for (int stop = DSSClassList[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + { + Dss_Class = (TDSSClass*)DSSClassList[ActiveActor].Get(i); + if (dynamic_cast(Dss_Class)) + { + // Checks if it is a PCE class + if ((dynamic_cast(Dss_Class) != nullptr) || (Dss_Class->get_myClass_name() == "Capacitor") || (Dss_Class->get_myClass_name() == "Reactor")) + { + // If it is, checks all the elements to verify if one or more are + // connected to the bus given + Dss_Class->Get_First(); + for (int stop = Dss_Class->Get_ElementCount(), j = 1; j <= stop; j++) + { + myBus = LowerCase(StripExtension(get_FActiveCktElement()->GetBus(1))); + if (myBus == BusName) + { + result.push_back(Dss_Class->get_myClass_name() + "." + ((TDSSObject*)get_FActiveCktElement())->get_Name()); + } + Dss_Class->Get_Next(); + } + } + } + } + if (result.empty()) + { + result.resize(1); + result[0] = "None"; + } + return result; + } + + /******************************************************************************** + * Gets all PCE at given bus and returns the list as string * + *********************************************************************************/ + + + String TDSSCircuit::ReportPCEatBus(String BusName) + { + String result; + int i = 0; + DynStringArray myPCEList; + myPCEList = getPCEatBus(BusName); + result = ""; + for (int stop = (myPCEList.size() - 1), i = 0; i <= stop; i++) + if (myPCEList[i] != "") + result = result + myPCEList[i] + ","; + return result; + } + + /******************************************************************************** + * Gets all PDE at given bus and returns the list as string * + *********************************************************************************/ + + + String TDSSCircuit::ReportPDEatBus(String BusName) + { + String result; + int i = 0; + DynStringArray myPDEList; + myPDEList = getPDEatBus(BusName); + result = ""; + for (int stop = (myPDEList.size() - 1), i = 0; i <= stop; i++) + if (myPDEList[i] != "") + result = result + myPDEList[i] + ","; + return result; + } + + /******************************************************************************** + * This routine tears the circuit into many pieces as CPUs are * + * available in the local computer (in the best case) * + *********************************************************************************/ + + + int TDSSCircuit::Tear_Circuit() + { + int result = 0; + bool FileCreated = false; + TTextRec Ftree{}, F{}; // For debugging + + String TreeNm, BusName, Terminal, TextCmd, PDElement, Filename; // Active Location + + int NodeIdx = 0 // Generic counter variables + , Num_Pieces = 0, Location_idx = 0, j = 0, jj = 0, dbg = 0, dbg2 = 0, k = 0, l = 0, i = 0; + int* Candidates = new int[1]; // Array for 0 level buses idx + + TEnergyMeterObj* EMeter; + polar Volts; + vector Term_volts; // To verify the connection of the branch + + TVsourceObj pVSource; + TFileSearchReplace* Replacer = nullptr; + DynStringArray myPDEList; + + + if (UseUserLinks && (Link_Branches.size() > 0)) + Num_Pieces = Link_Branches.size() + 1; + else + Num_Pieces = Num_SubCkts; + /*# with Solution do */ + TSolutionObj with0 = *Solution; + { + if (UseUserLinks && Link_Branches.size() > 0) // usando ramas de enlace ingresadas manualmente + // using link branches entered manually + { + with0.Calc_Inc_Matrix_Org(ActiveActor); //Calculates the ordered incidence matrix + Locations.resize(Link_Branches.size()); + Locations[0] = 0; + for (int stop = (Link_Branches.size() - 1), i = 1; i <= stop; i++) + /*# with Solution do */ + Locations[i] = with0.get_PDE_Bus1_Location(Link_Branches[i]); + } + else + { + Filename = Create_MeTIS_graph(); + TextCmd = Create_MeTIS_Zones(Filename); + UseUserLinks = false; + } + /********************************************************************************************/ + // Verifies if there was no error executing MeTIS and the zones file was created + if (((TextCmd != "**Error**") && FileExists((Filename + ".part." + IntToStr(Num_Pieces)).c_str())) || UseUserLinks) + { + //***********The directory is ready for storing the new circuit**************** + EMeter = (TEnergyMeterObj*)EnergyMeters.Get_First(); + while (EMeter != NULL) + { + ((TDSSCktElement*)EMeter)->Set_Enabled(false); + EMeter = (TEnergyMeterObj*)EnergyMeters.Get_Next(); + } + //************ Creates the meters at the tearing locations ******************** + result = 1; // Resets the result variable (Return) + PConn_Voltages.resize(Locations.size() * 6); // Sets the memory space for storing the voltage at the point of conn + Link_Branches.resize(Locations.size()); // Sets the memory space for storing the link branches names + PConn_Names.resize(Locations.size()); // Sets the memory space for storing the Bus names + SolutionAbort = false; + j = 0; + for (int stop = (Locations.size() - 1), i = 0; i <= stop; i++) + { + if (i > 0) + { + result++; + // Gets the name of the PDE for placing the EnergyMeter + /*# with Solution do */ + { + PDElement = with0.Inc_Mat_Rows[with0.get_IncMatrix_Row(Locations[i])]; + Link_Branches[i] = PDElement; + dbg = with0.get_IncMatrix_Col(Locations[i]); // Temporary stores the given location + // Checks the branch orientation across the feeder by substracting the voltages around the branch + // Start with Bus 1 + Term_volts.resize(2); + for (int stop = 1, dbg = 0; dbg <= stop; dbg++) + { + BusName = with0.Inc_Mat_Cols[with0.Active_Cols[dbg]]; + SetActiveBus(BusName); // Activates the Bus + TDSSBus& pBus = *Buses[static_cast(ActiveBusIndex) - 1]; + jj = 1; + // this code so nodes come out in order from smallest to larges + do + { + NodeIdx = pBus.FindIdx(jj); // Get the index of the Node that matches jj + jj++; + } while (!(NodeIdx > 0)); + Volts = ctopolardeg(Solution->NodeV[pBus.GetRef(NodeIdx)]); // referenced to pBus + Term_volts[dbg] = Volts.mag; + } + + // Determines the best place to connect the EnergyMeter + Term_volts[0] = Term_volts[0] - Term_volts[1]; + jj = Link_Branches[i].find("."); + BusName = get_Line_Bus(Link_Branches[i].substr(jj + 1), 2); + jj = BusName.find("."); // removes the dot + if (jj > 0) + BusName = BusName.substr(0, static_cast(jj)); + Terminal = "terminal=1"; + PConn_Names[i] = BusName; + SetActiveBus(BusName); // Activates the Bus + TDSSBus& pBus2 = *(Buses[ActiveBusIndex]); + for (int stop = 3, jj = 1; jj <= stop; jj++) + { + // this code so nodes come out in order from smallest to larges + NodeIdx = pBus2.FindIdx(jj); // Get the index of the Node that matches jj + Volts = ctopolardeg(Solution->NodeV[pBus2.GetRef(NodeIdx)]); // referenced to pBus + PConn_Voltages[j] = (double(Volts.mag) / 1000); + j++; + PConn_Voltages[j] = Volts.ang; + j++; + } + } + // Generates the OpenDSS Command; + DSSExecutive[ActiveActor]->Set_Command("New EnergyMeter.Zone_" + IntToStr(i + 1) + " element=" + PDElement + " " + Terminal + " option=R action=C"); + } + else + { + // The reference bus (Actor 1) + BusName = with0.Inc_Mat_Cols[0]; + PConn_Names[i] = BusName; + SetActiveBus(BusName); // Activates the Bus + TDSSBus& pBus3 = *(Buses[ActiveBusIndex]); + // Stores the voltages for the Reference bus first + for (int stop = 3, jj = 1; jj <= stop; jj++) + { + // this code so nodes come out in order from smallest to larges + NodeIdx = pBus3.FindIdx(jj); // Get the index of the Node that matches jj + Volts = ctopolardeg(Solution->NodeV[pBus3.GetRef(NodeIdx)]); // referenced to pBus + PConn_Voltages[j] = (double(Volts.mag) / 1000); + j++; + PConn_Voltages[j] = Volts.ang; + j++; + } + } + } + } + else + { + if (TextCmd == "**Error**") + DoErrorMsg("Tear_Circuit", "MeTIS cannot start.", "The MeTIS program (pmetis.exe/kmetis.exe) cannot be executed/found.", 7006); + else + DoErrorMsg("Tear_Circuit", "The graph file is incorrect.", String("MeTIS cannot process the graph file because is incorrect") + "(The number of edges is incorrect).", 7007); + } + } + return result; + } + + //---------------------------------------------------------------------------- + + //---------------------------------------------------------------------------- + + + void TDSSCircuit::ProcessBusDefs(int ActorID) + { + String BusName; + int NNodes = 0, NP = 0, Ncond = 0, i = 0, j = 0, iTerm = 0, retval = 0; + bool NodesOK = false; + /*# with ActiveCktElement do */ + TDSSCktElement* with0 = get_FActiveCktElement(); + { + NP = with0->Get_NPhases(); + Ncond = with0->Get_NConds(); + Parser[ActorID]->set_Token(with0->Get_FirstBus()); // use parser functions to decode + for (int stop = with0->Get_NTerms(), iTerm = 1; iTerm <= stop; iTerm++) + { + NodesOK = true; + // Assume normal phase rotation for default + for (int stop = NP, i = 1; i <= stop; i++) + NodeBuffer[i - 1] = i; // set up buffer with defaults + + // Default all other conductors to a ground connection + // If user wants them ungrounded, must be specified explicitly! + for (int stop = Ncond, i = NP + 1; i <= stop; i++) + NodeBuffer[i - 1] = 0; + + // Parser will override bus connection if any specified + BusName = Parser[ActorID]->ParseAsBusName(NNodes, (pIntegerArray) & (NodeBuffer[0]), ActorID); + + // Check for error in node specification + for (int stop = NNodes, j = 1; j <= stop; j++) + { + if (NodeBuffer[j - 1] < 0) + { + retval = DSSMessageDlg("Error in Node specification for Element: \"" + with0->ParentClass->get_myClass_name() + "." + Get_Name() + "\"" + CRLF + "Bus Spec: \"" + Parser[ActorID]->get_Token() + "\"", false); + NodesOK = false; + if (retval == -1) + { + AbortBusProcess = true; + AppendGlobalResult("Aborted bus process."); + return; + } + break; + } + } + + // Node -Terminal Connnections + // Caution: Magic -- AddBus replaces values in nodeBuffer to correspond + // with global node reference number. + if (NodesOK) + { + with0->Set_ActiveTerminal(iTerm); + with0->ActiveTerminal->BusRef = AddBus(BusName, Ncond, ActorID); + with0->SetNodeRef(iTerm, (pIntegerArray) & (NodeBuffer[0])); // for active circuit + } + Parser[ActorID]->set_Token(with0->Get_NextBus()); + } + } + } + + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::AddABus() + { + if (NumBuses > MaxBuses) + { + MaxBuses += IncBuses; + Buses.resize(MaxBuses); + } + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::AddANodeBus() + { + if (NumNodes > MaxNodes) + { + MaxNodes += IncNodes; + MapNodeToBus.resize(MaxNodes); + } + } + + //---------------------------------------------------------------------------- + + + + int TDSSCircuit::AddBus(const String BusName, int NNodes, int ActorID) + { + int result = 0; + int NodeRef = 0, i = 0; + + // Trap error in bus name + if (BusName.size() == 0) + { // Error in busname + DoErrorMsg("TDSSCircuit.AddBus", "BusName for Object \"" + get_FActiveCktElement()->get_Name() + "\" is null.", "Error in definition of object.", 424); + for (int stop = get_FActiveCktElement()->Get_NConds(), i = 1; i <= stop; i++) + NodeBuffer[i - 1] = 0; + result = 0; + return result; + } + result = BusList.Find(BusName); + if (result == 0) + { + result = BusList.Add(BusName); // Result is index of bus + NumBuses++; + AddABus(); // Allocates more memory if necessary + Buses[static_cast(NumBuses) - 1] = new TDSSBus(); + + } + + /*Define nodes belonging to the bus*/ + /*Replace Nodebuffer values with global reference number*/ + /*# with Buses^[Result] do */ + { + auto with0 = Buses[static_cast(result) - 1]; + { + for (int stop = NNodes, i = 1; i <= stop; i++) + { + NodeRef = with0->Add(NodeBuffer[i - 1], ActorID); + if (NodeRef == NumNodes) + { // This was a new node so Add a NodeToBus element ???? + AddANodeBus(); // Allocates more memory if necessary + MapNodeToBus[static_cast(NumNodes) - 1].BusRef = result; + MapNodeToBus[static_cast(NumNodes) - 1].NodeNum = NodeBuffer[i - 1]; + } + NodeBuffer[i - 1] = NodeRef; // Swap out in preparation to setnoderef call + } + } + } + return result; + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::AddDeviceHandle(int Handle) + { + if (NumDevices > MaxDevices) + { + MaxDevices = MaxDevices + IncDevices; + DeviceRef.resize(static_cast(MaxDevices) + 1); + } + DeviceRef[static_cast(NumDevices) - 1].devHandle = Handle; + DeviceRef[static_cast(NumDevices) - 1].CktElementClass = LastClassReferenced[ActiveActor]; + } + + + //---------------------------------------------------------------------------- + + + + int TDSSCircuit::SetElementActive(const String FullObjectName) + + // Fast way to set a cktelement active + + { + int result = 0; + int Devindex = 0; + int DevClassIndex = 0; + String DevType, DevName; + result = 0; + ParseObjectClassandName(FullObjectName, DevType, DevName); + DevClassIndex = ClassNames[ActiveActor].Find(DevType); + if (DevClassIndex == 0) + DevClassIndex = LastClassReferenced[ActiveActor]; + if (!DevName.empty()) + { + Devindex = DeviceList.Find(DevName) - 1; + while (Devindex >= 0) + { + if (DeviceRef[Devindex].CktElementClass == DevClassIndex) // we got a match + { + ActiveDSSClass[ActiveActor] = (TDSSClass*)DSSClassList[ActiveActor].Get(DevClassIndex); + LastClassReferenced[ActiveActor] = DevClassIndex; + result = DeviceRef[Devindex].devHandle; + // ActiveDSSClass[ActiveActor].Active := Result; + // ActiveCktElement := ActiveDSSClass.GetActiveObj; + Set_ActiveCktElement((TDSSCktElement*)(CktElements.Get(result))); + break; + } + Devindex = DeviceList.FindNext() - 1; // Could be duplicates + } + } + CmdResult = result; + return result; + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::Set_ActiveCktElement(TDSSCktElement* Value) + { + FActiveCktElement = Value; + ActiveDSSObject[ActiveActor] = Value; + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::AddCktElement(int Handle) + { + + // Update lists that keep track of individual circuit elements + NumDevices++; + + // Resize DeviceList if no. of devices greatly exceeds allocation + if (((unsigned int)NumDevices) > 2 * DeviceList.InitialAllocation) + ReallocDeviceList(ActiveActor); + DeviceList.Add(((TDSSObject*)get_FActiveCktElement())->get_Name()); + CktElements.Add(get_FActiveCktElement()); + + /*Build Lists of PC and PD elements*/ + switch (((TDSSObject*)get_FActiveCktElement())->DSSObjType & BaseClassMask) + { + case PD_ELEMENT: PDElements.Add(get_FActiveCktElement()); + break; + case PC_ELEMENT: PCElements.Add(get_FActiveCktElement()); + break; + case CTRL_ELEMENT: DSSControls.Add(get_FActiveCktElement()); + break; + case METER_ELEMENT: MeterElements.Add(get_FActiveCktElement()); + break; + default: {} + /*Nothing*/ + } + /*Build lists of Special elements and generic types*/ + switch (((TDSSObject*)get_FActiveCktElement())->DSSObjType & CLASSMASK) + { + case MON_ELEMENT: Monitors.Add(get_FActiveCktElement()); + break; + case ENERGY_METER: EnergyMeters.Add(get_FActiveCktElement()); + break; + case SENSOR_ELEMENT: Sensors.Add(get_FActiveCktElement()); + break; + case GEN_ELEMENT: Generators.Add(get_FActiveCktElement()); + break; + case SOURCE: Sources.Add(get_FActiveCktElement()); + break; + case CAP_CONTROL: CapControls.Add(get_FActiveCktElement()); + break; + case SWT_CONTROL: SwtControls.Add(get_FActiveCktElement()); + break; + case REG_CONTROL: RegControls.Add(get_FActiveCktElement()); + break; + case LOAD_ELEMENT: Loads.Add(get_FActiveCktElement()); + break; + case CAP_ELEMENT: ShuntCapacitors.Add(get_FActiveCktElement()); + break; + case REACTOR_ELEMENT: Reactors.Add(get_FActiveCktElement()); + break; + case RELAY_CONTROL: Relays.Add(get_FActiveCktElement()); + break; + case FUSE_CONTROL: Fuses.Add(get_FActiveCktElement()); + break; + case RECLOSER_CONTROL: Reclosers.Add(get_FActiveCktElement()); + break; + case FMON_ELEMENT: FMonitors.Add(get_FActiveCktElement()); + break; + case WINDGEN_ELEMENT: WindGens.Add(get_FActiveCktElement()); + break; + + /* Keep Lines, Transformer, and Lines and Faults in PDElements and separate lists + so we can find them quickly.*/ + case AUTOTRANS_ELEMENT: AutoTransformers.Add(get_FActiveCktElement()); + break; + case XFMR_ELEMENT: Transformers.Add(get_FActiveCktElement()); + break; + case LINE_ELEMENT: Lines.Add(get_FActiveCktElement()); + break; + case FAULTOBJECT: Faults.Add(get_FActiveCktElement()); + break; + case FEEDER_ELEMENT: Feeders.Add(get_FActiveCktElement()); + break; + case STORAGE_ELEMENT: StorageElements.Add(get_FActiveCktElement()); + break; + // STORAGE2_ELEMENT:Storage2Elements.Add(ActiveCktElement); + + case PVSYSTEM_ELEMENT: PVSystems.Add(get_FActiveCktElement()); + break; + // PVSYSTEM2_ELEMENT:PVSystems2.Add(ActiveCktElement); + // INV_CONTROL :InvControls.Add(ActiveCktElement); + + case INV_CONTROL2: InvControls2.Add(get_FActiveCktElement()); + break; + case EXP_CONTROL: ExpControls.Add(get_FActiveCktElement()); + break; + } + + // AddDeviceHandle(Handle); // Keep Track of this device result is handle + AddDeviceHandle(CktElements.get_myNumList()); // Handle is global index into CktElements + get_FActiveCktElement()->Set_Handle(CktElements.get_myNumList()); + } + + void TDSSCircuit::DoResetMeterZones(int ActorID) + { + + /* Do this only if meterzones unlocked . Normally, Zones will remain unlocked + so that all changes to the circuit will result in rebuilding the lists*/ + if (!MeterZonesComputed || !ZonesLocked) + { + if (LogEvents) + LogThisEvent("Resetting Meter Zones", ActorID); + EnergyMeterClass[ActorID]->ResetMeterZonesAll(ActorID); + MeterZonesComputed = true; + if (LogEvents) + LogThisEvent("Done Resetting Meter Zones", ActorID); + } + FreeTopology(); + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::SaveBusInfo() + { + int i = 0; + + /*Save existing bus definitions and names for info that needs to be restored*/ + SavedBuses.resize(NumBuses); + if (SavedBusNames != NULL) + delete[] SavedBusNames; + SavedBusNames = new String[NumBuses]; + for (int stop = NumBuses, i = 1; i <= stop; i++) + { + SavedBuses[static_cast(i) - 1] = Buses[static_cast(i) - 1]; + (SavedBusNames)[i - 1] = BusList.Get(i); + } + SavedNumBuses = NumBuses; + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::RestoreBusInfo() + { + int i = 0, j = 0, idx = 0, jdx = 0; + + // Restore kV bases, other values to buses still in the list + for (int stop = SavedNumBuses, i = 1; i <= stop; i++) + { + idx = BusList.Find((SavedBusNames)[i - 1]); + if (idx != 0) + /*# with Buses^[idx - 1] do */ + { + auto with0 = Buses[static_cast(idx) - 1]; + { + TDSSBus& pBus(*(SavedBuses[static_cast(i) - 1])); + with0->kVBase = pBus.kVBase; + with0->x = pBus.x; + with0->y = pBus.y; + with0->CoordDefined = pBus.CoordDefined; + with0->lat = pBus.lat; + with0->longitude = pBus.longitude; + with0->GISCoordDefined = pBus.GISCoordDefined; + with0->Keep = pBus.Keep; + /*Restore Voltages in new bus def that existed in old bus def*/ + if (!(pBus.VBus.empty())) + { + for (int stop = pBus.get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + jdx = with0->FindIdx(pBus.GetNum(j)); // Find index in new bus for j-th node in old bus + if (jdx > 0) + with0->VBus[jdx - 1] = pBus.VBus[j - 1]; + } + } + } + } + (SavedBusNames)[i - 1] = ""; // De-allocate string + } + if ((SavedBuses.size() != 0)) + for (int stop = SavedNumBuses, i = 1; i <= stop; i++) + delete SavedBuses[i - 1]; // gets rid of old bus voltages, too + //ReallocMem( SavedBuses, 0 ); + //ReallocMem( SavedBusNames, 0 ); + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::ReProcessBusDefs(int ActorID) + + // Redo all Buslists, nodelists + + { + TDSSCktElement* CktElementSave; + TDSSCktElement* CktElementTmp; + int i = 0; + if (LogEvents) + LogThisEvent("Reprocessing Bus Definitions", ActorID); + AbortBusProcess = false; + SaveBusInfo(); // So we don't have to keep re-doing this + // Keeps present definitions of bus objects until new ones created + + // get rid of old bus lists + BusList = THashList(NumDevices); // won't have many more buses than this + NumBuses = 0; // Leave allocations same, but start count over + NumNodes = 0; + + // Now redo all enabled circuit elements + CktElementSave = get_FActiveCktElement(); + Set_ActiveCktElement((TDSSCktElement*)CktElements.Get_First()); + while (get_FActiveCktElement() != NULL) + { + if (get_FActiveCktElement()->Get_Enabled()) + ProcessBusDefs(ActorID); + if (AbortBusProcess) + return; + Set_ActiveCktElement((TDSSCktElement*)CktElements.Get_Next()); + CktElementTmp = get_FActiveCktElement(); + } + Set_ActiveCktElement(CktElementSave); // restore active circuit element + for (int stop = NumBuses, i = 1; i <= stop; i++) + Buses[static_cast(i) - 1]->AllocateBusVoltages(); + for (int stop = NumBuses, i = 1; i <= stop; i++) + Buses[static_cast(i) - 1]->AllocateBusVoltages(); + RestoreBusInfo(); // frees old bus info, too + DoResetMeterZones(ActorID); // Fix up meter zones to correspond + Set_BusNameRedefined(false); // Get ready for next time + } + + //---------------------------------------------------------------------------- + + + + void TDSSCircuit::Set_BusNameRedefined(bool Value) + { + FBusNameRedefined = Value; + if (Value) + { + Solution->SystemYChanged = true; // Force Rebuilding of SystemY if bus def has changed + Control_BusNameRedefined = true; // So controls will know buses redefined + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + complex TDSSCircuit::Get_Losses(int ActorID) + { + complex result; + TPDElement* PDElem; + + /*Return total losses in all PD Elements*/ + PDElem = (TPDElement*)PDElements.Get_First(); + result = CZero; + while (PDElem != NULL) + { + if (PDElem->Get_Enabled()) + { + /*Ignore Shunt Elements*/ + if (!PDElem->IsShunt) + caccum(result, PDElem->Get_Losses(ActorID)); + } + PDElem = (TPDElement*)PDElements.Get_Next(); + } + return result; + } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCircuit::DebugDump(Textfile& F) + { + int i = 0, j = 0; + System::Write(F, "NumBuses= "); WriteLn(NumBuses, 0); + System::Write(F, "NumNodes= "); WriteLn(NumNodes, 0); + System::Write(F, "NumDevices= "); WriteLn(NumDevices, 0); + System::WriteLn(F, "BusList:"); + for (int stop = NumBuses, i = 1; i <= stop; i++) + { + System::Write(F, " "); Write(F, Pad(BusList.Get(i), 12)); + System::Write(F, " ("); + Write(F, Buses[static_cast(i) - 1]->get_FNumNodesThisBus(), 0); + Write(F, " Nodes)"); + for (int stop = Buses[static_cast(i) - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + System::Write(F, ' '); + Write(Buses[static_cast(i) - 1]->GetNum(j), 0); + } + WriteLn(F); + } + System::WriteLn(F, "DeviceList:"); + for (int stop = NumDevices, i = 1; i <= stop; i++) + { + System::Write(F, " "); Write(F, Pad(DeviceList.Get(i), 12)); + Set_ActiveCktElement((TDSSCktElement*)CktElements.Get(i)); + if (!get_FActiveCktElement()->Get_Enabled()) + { + System::Write(F, " DISABLED"); + } + WriteLn(F); + } + System::WriteLn(F, "NodeToBus Array:"); + for (int stop = NumNodes, i = 1; i <= stop; i++) + { + j = MapNodeToBus[static_cast(i) - 1].BusRef; + System::Write(F, " "); + System::Write(F, i, 2); + System::Write(F, ' '); + System::Write(F, j, 2); + System::Write(F, " (="); + System::Write(F, BusList.Get(j)); + System::Write(F, "."); + System::Write(F, MapNodeToBus[static_cast(i) - 1].NodeNum, 0); + System::Write(F, ")"); + WriteLn(F); + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCircuit::InvalidateAllPCElements() + { + TDSSCktElement* p; + p = (TDSSCktElement*)PCElements.Get_First(); + while (p != NULL) + { + p->Set_YprimInvalid(ActiveActor, true); + p = (TDSSCktElement*)PCElements.Get_Next(); + } + Solution->SystemYChanged = true; // Force rebuild of matrix on next solution + } + + + // - - ------------------------------------------------------ + + + + void TDSSCircuit::Set_LoadMultiplier(double Value) + { + if (Value != FLoadMultiplier) // We may have to change the Y matrix if the load multiplier has changed + switch (Solution->LoadModel) + { + case ADMITTANCE: + InvalidateAllPCElements(); + break; + default: {} + /*nada*/ + } + FLoadMultiplier = Value; + } + + + void TDSSCircuit::TotalizeMeters() + + /* Totalize all energymeters in the problem*/ + { + TEnergyMeterObj* pEM; + int i = 0; + for (int stop = NumEMRegisters, i = 1; i <= stop; i++) + RegisterTotals[i - 1] = 0.; + pEM = (TEnergyMeterObj*)EnergyMeters.Get_First(); + while (pEM != NULL) + /*# with pEM do */ + { + for (int stop = NumEMRegisters, i = 1; i <= stop; i++) + RegisterTotals[i - 1] = RegisterTotals[i - 1] + pEM->Registers[i - 1] * pEM->TotalsMask[i - 1]; + pEM = (TEnergyMeterObj*)EnergyMeters.Get_Next(); + } + } + + //---------------------------------------------------------------------------- + + double TDSSCircuit::get_FLoadMultiplier() + { + return FLoadMultiplier; + } + + //---------------------------------------------------------------------------- + + bool TDSSCircuit::get_FBusNameRedefined() + { + return FBusNameRedefined; + } + + //---------------------------------------------------------------------------- + + std::string TDSSCircuit::get_FCaseName() + { + return FCaseName; + } + + //---------------------------------------------------------------------------- + + double SumSelectedRegisters(const TRegisterArray mtrRegisters, pIntegerArray Regs, int count) + { + double result = 0.0; + int i = 0; + result = 0.0; + for (int stop = count, i = 1; i <= stop; i++) + { + result = result + mtrRegisters[(Regs)[i - 1]]; + } + return result; + } + + + bool TDSSCircuit::ComputeCapacity(int ActorID) + { + bool result = false; + bool CapacityFound = false; + result = false; + if (EnergyMeters.get_myNumList() == 0) + { + DoSimpleMsg("Cannot compute system capacity with EnergyMeter objects!", 430); + return result; + } + if (NumUEregs == 0) + { + DoSimpleMsg("Cannot compute system capacity with no UE resisters defined. Use SET UEREGS=(...) command.", 431); + return result; + } + Solution->Set_Mode(SNAPSHOT); + Set_LoadMultiplier(CapacityStart); + CapacityFound = false; + do + { + EnergyMeterClass[ActorID]->ResetAll(ActorID); + Solution->Solve(ActorID); + EnergyMeterClass[ActorID]->SampleAll(ActorID); + TotalizeMeters(); + + // Check for non-zero in UEregs + if (SumSelectedRegisters(RegisterTotals, UEregs, NumUEregs) != 0.0) + CapacityFound = true; + // LoadMultiplier is a property ... + if (!CapacityFound) + Set_LoadMultiplier(get_FLoadMultiplier() + CapacityIncrement); + } while (!((get_FLoadMultiplier() > 1.0) || CapacityFound)); + + if (get_FLoadMultiplier() > 1.0) + Set_LoadMultiplier(1.0); + result = true; + return result; + } + + /*Save the present circuit - Enabled devices only*/ + bool TDSSCircuit::Save(String Dir) + { + bool result = false; + int i = 0; + bool Success = false; + String CurrDir, SaveDir; + result = false; + + // Make a new subfolder in the present folder based on the circuit name and + // a unique sequence number + SaveDir = GetCurrentDir(); // remember where to come back to + Success = false; + if (Dir.size() == 0) + { + Dir = Get_Name(); + CurrDir = Dir; + for (int stop = 999, i = 0; i <= stop; i++) // Find a unique dir name + { + if (!DirectoryExists(CurrDir)) + { + if (CreateDir(CurrDir)) + { + SetCurrentDir(CurrDir); + Success = true; + break; + } + } + CurrDir = Dir + Format("%.3d", i); + } + } + else + { + if (!DirectoryExists(Dir)) + { + CurrDir = Dir; + if (CreateDir(CurrDir)) + { + SetCurrentDir(CurrDir); + Success = true; + } + } + else + { // Exists - overwrite + CurrDir = Dir; + SetCurrentDir(CurrDir); + Success = true; + } + } + if (!Success) + { + DoSimpleMsg(String("Could not create a folder \"") + Dir + "\" for saving the circuit.", 432); + return result; + } + SavedFileList[ActiveActor].clear(); /*This list keeps track of all files saved*/ + + // Initialize so we will know when we have saved the circuit elements + for (int stop = CktElements.get_myNumList(), i = 1; i <= stop; i++) + ((TDSSObject*)(CktElements.Get(i)))->HasBeenSaved = false; + + // Initialize so we don't save a class twice + for (int stop = DSSClassList[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + ((TDSSClass*)(DSSClassList[ActiveActor].Get(i)))->Saved = false; + + /*Ignore Feeder Class -- gets saved with Energymeters*/ + // FeederClass.Saved := TRUE; // will think this class is already saved + + /*Define voltage sources first*/ + Success = WriteVsourceClassFile((*(TDSSClass*)GetDSSClassPtr("vsource")), true); + /*Write library files so that they will be available to lines, loads, etc*/ + /*Use default filename=classname*/ + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("wiredata")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("cndata")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("tsdata")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("linegeometry")), "", false); + // If Success Then Success := WriteClassFile(GetDssClassPtr('linecode'),'', FALSE); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("linespacing")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("linecode")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("xfmrcode")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("loadshape")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("TShape")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("priceshape")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("growthshape")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("XYcurve")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("TCC_Curve")), "", false); + if (Success) + Success = WriteClassFile((*(TDSSClass*)GetDSSClassPtr("Spectrum")), "", false); + if (Success) + Success = SaveFeeders(); // Save feeders first + if (Success) + Success = SaveDSSObjects(); // Save rest ot the objects + if (Success) + Success = SaveVoltageBases(); + if (Success) + Success = SaveBusCoords(); + if (Success) + Success = SaveGISCoords(); + if (Success) + Success = SaveMasterFile(); + /* + If Success Then DoSimpleMsg('Circuit saved in directory: ' + GetCurrentDir, 433) + Else DoSimpleMsg('Error attempting to save circuit in ' + GetCurrentDir, 434); + */ + if (Success) + GlobalResult = GetCurrentDir() + DIRSEP_STR "Master.DSS"; + else + GlobalResult = "Error 434 attempting to save circuit in " + GetCurrentDir(); + + // Return to Original directory + SetCurrentDir(SaveDir); + result = true; + return result; + } + + //---------------------------------------------------------------------------- + + + + bool TDSSCircuit::SaveDSSObjects() + { + bool result = false; + TDSSClass* Dss_Class; + int i = 0; + result = false; + + // Write Files for all populated DSS Classes Except Solution Class + for (int stop = DSSClassList[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + { + Dss_Class = (TDSSClass*)DSSClassList[ActiveActor].Get(i); + if ((Dss_Class == SolutionClass[ActiveActor]) || Dss_Class->Saved) + continue; // Cycle to next + /*use default filename=classname*/ + if (!WriteClassFile(*Dss_Class, "", (dynamic_cast(Dss_Class)))) + return result; // bail on error + Dss_Class->Saved = true; + } + result = true; + return result; + } + + + + bool TDSSCircuit::SaveVoltageBases() + { + bool result = false; + TTextRec F; + int i = 0; + String VBases; + result = false; + try + { + AssignFile(F, "BusVoltageBases.DSS"); + Rewrite(F); + IOResultToException(); + + // For i := 1 to NumBuses do + // If Buses^[i].kVBase > 0.0 Then + // Writeln(F, Format('SetkVBase Bus=%s kvln=%.7g ', [BusList.Get(i), Buses^[i].kVBase])); + DSSExecutive[ActiveActor]->Set_Command("get voltagebases"); + VBases = GlobalResult; + WriteLn(F, String("Set Voltagebases=") + VBases); + WriteLn(F, "CalcVoltagebases"); + CloseFile(F); + result = true; + } + catch (exception& E) + { + DoSimpleMsg("Error Saving BusVoltageBases File: " + (std::string)E.what(), 43501); + } + return result; + } + + + + bool TDSSCircuit::SaveMasterFile() + { + bool result = false; + TTextRec F; + int i = 0; + result = false; + try + { + AssignFile(F, "Master.DSS"); + Rewrite(F); + IOResultToException(); + WriteLn(F, "Clear"); + WriteLn(F, String("New Circuit.") + Get_Name()); + WriteLn(F); + if (PositiveSequence) + WriteLn(F, "Set Cktmodel=Positive"); + if (DuplicatesAllowed) + WriteLn(F, "set allowdup=yes"); + WriteLn(F); + + // Write Redirect for all populated DSS Classes Except Solution Class + for (int stop = SavedFileList[ActiveActor].size(), i = 1; i <= stop; i++) + { + Write(F, "Redirect "); WriteLn(F, SavedFileList[ActiveActor][static_cast(i) - 1]); + } + WriteLn(F, "MakeBusList"); + WriteLn(F, "Redirect BusVoltageBases.dss ! set voltage bases"); + if (FileExists("buscoords.dss")) + { + WriteLn(F, "Buscoords buscoords.dss"); + } + if (FileExists("GIScoords.dss")) + { + WriteLn(F, "GIScoords GIScoords.dss"); + } + CloseFile(F); + result = true; + } + catch (exception& E) + { + DoSimpleMsg("Error Saving Master File: " + (std::string)E.what(), 435); + } + return result; + } + + + bool TDSSCircuit::SaveFeeders() + { + bool result = false; + int i = 0; + String SaveDir, CurrDir; + TEnergyMeterObj* Meter; + result = true; + /*Write out all energy meter zones to separate subdirectories*/ + SaveDir = GetCurrentDir(); + for (int stop = EnergyMeters.get_myNumList(), i = 1; i <= stop; i++) + { + Meter = ((TEnergyMeterObj*)EnergyMeters.Get(i)); // Recast pointer + CurrDir = ((TDSSObject*)Meter)->get_Name(); + if (((TDSSCktElement*)Meter)->Get_Enabled()) // Only active meters + { + if (DirectoryExists(CurrDir)) + { + SetCurrentDir(CurrDir); + Meter->SaveZone(CurrDir); + SetCurrentDir(SaveDir); + } + else + { + if (CreateDir(CurrDir)) + { + SetCurrentDir(CurrDir); + Meter->SaveZone(CurrDir); + SetCurrentDir(SaveDir); + } + else + { + DoSimpleMsg(String("Cannot create directory: ") + CurrDir, 436); + result = false; + SetCurrentDir(SaveDir); // back to whence we came + break; + } + } + } + } /*For*/ + return result; + } + + + bool TDSSCircuit::SaveBusCoords() + { + bool result = false; + TTextRec F; + int i = 0; + result = false; + try + { + AssignFile(F, "BusCoords.dss"); + Rewrite(F); + IOResultToException(); + for (int stop = NumBuses, i = 1; i <= stop; i++) + { + if (Buses[static_cast(i) - 1]->CoordDefined) + { + Write(F, CheckForBlanks(BusList.Get(i))); WriteLn(F, Format(", %-g, %-g", Buses[static_cast(i) - 1]->x, Buses[static_cast(i) - 1]->y)); + } + } + CloseFile(F); + result = true; + } + catch (std::exception &E) + { + DoSimpleMsg("Error creating Buscoords.dss.", 437); + } + return result; + } + + //---------------------------------------------------------------------------- + + + + bool TDSSCircuit::SaveGISCoords() + { + bool result = false; + TTextRec F; + int i = 0; + result = false; + try + { + AssignFile(F, "GISCoords.dss"); + Rewrite(F); + IOResultToException(); + for (int stop = NumBuses, i = 1; i <= stop; i++) + { + if (Buses[static_cast(i) - 1]->CoordDefined) + { + Write(F, CheckForBlanks(BusList.Get(i))); WriteLn(F, Format(", %-g, %-g", Buses[static_cast(i) - 1]->lat, Buses[static_cast(i) - 1]->longitude)); + } + } + CloseFile(F); + result = true; + } + catch (std::exception &E) + { + DoSimpleMsg("Error creating Buscoords.dss.", 437); + } + return result; + } + + + void TDSSCircuit::ReallocDeviceList(int ActorID) + { + THashList TempList; + int i = 0; + /*Reallocate the device list to improve the performance of searches*/ + if (LogEvents) + LogThisEvent("Reallocating Device List", ActorID); + TempList = THashList(2 * NumDevices); + for (int stop = DeviceList.Get_NumElements(), i = 1; i <= stop; i++) + { + TempList.Add(DeviceList.Get(i)); + } + DeviceList = TempList; + } + + + void TDSSCircuit::Set_CaseName(const String Value) + { + FCaseName = Value; + CircuitName_[ActiveActor] = Value + "_"; + } + + + String TDSSCircuit::Get_Name() + { + String result; + result = Get_myLName(); + return result; + } + + + TAdjArray TDSSCircuit::GetBusAdjacentPDLists(int ActorID) + { + TAdjArray result; + if (BusAdjPD.empty()) + BuildActiveBusAdjacencyLists(BusAdjPD, BusAdjPC, ActorID); + result = BusAdjPD; + + if (BusAdjPD.empty()) + BuildActiveBusAdjacencyLists(BusAdjPD, BusAdjPC, ActorID); + result = BusAdjPD; + + return result; + } + + + TAdjArray TDSSCircuit::GetBusAdjacentPCLists(int ActorID) + { + TAdjArray result; + if (BusAdjPC.empty()) + BuildActiveBusAdjacencyLists(BusAdjPD, BusAdjPC, ActorID); + result = BusAdjPC; + return result; + } + + + TCktTree& TDSSCircuit::GetTopology() + { + int i = 0; + TDSSCktElement* elem; + if (!(Branch_List != NULL)) + { + /*Initialize all Circuit Elements and Buses to not checked, then build a new tree*/ + elem = (TDSSCktElement*)CktElements.Get_First(); + while ((elem != NULL)) + { + elem->Checked = false; + for (int stop = elem->Get_NTerms(), i = 1; i <= stop; i++) + elem->Terminals[static_cast(i) - 1].Checked = false; + elem->IsIsolated = true; // till proven otherwise + elem = (TDSSCktElement*)CktElements.Get_Next(); + } + for (int stop = NumBuses, i = 1; i <= stop; i++) + Buses[static_cast(i) - 1]->BusChecked = false; + Branch_List = GetIsolatedSubArea((TDSSCktElement*)Sources.Get_First(), true); // calls back to build adjacency lists + } + return *Branch_List; + } + + + void TDSSCircuit::FreeTopology() + { + if ((Branch_List != NULL)) + delete Branch_List; + Branch_List = NULL; + if ((BusAdjPC.empty())) + FreeAndNilBusAdjacencyLists(BusAdjPD, BusAdjPC); + } + + + void TDSSCircuit::ClearBusMarkers() + { + int i = 0; + for (int stop = BusMarkerList.size(), i = 1; i <= stop; i++) + free((TBusMarker*)BusMarkerList[static_cast(i) - 1]); + BusMarkerList.clear(); + } + + /*====================================================================*/ + /* TBusMarker */ + /*====================================================================*/ + + + TBusMarker::TBusMarker() + : BusName(""), + AddMarkerColor(0), + AddMarkerCode(4), + AddMarkerSize(1) + { + // inherited::Create(); + } + + + TBusMarker::~TBusMarker() + { + BusName = ""; + // todo check: inherited::Destroy(); + } + +} //namespace Circuit + + + + + + + diff --git a/OpenDSSC/Common/Circuit.h b/OpenDSSC/Common/Circuit.h new file mode 100644 index 0000000..ae227a1 --- /dev/null +++ b/OpenDSSC/Common/Circuit.h @@ -0,0 +1,373 @@ +#ifndef CircuitH +#define CircuitH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 10-12-99 Added DuplicatesAllowed and ZonesLocked + 10-24-99 Added Losses Property + 12-15-99 Added Default load shapes and generator dispatch reference + 4-17=00 Add Loads List + 5-30-00 Added Positive Sequence Flag + 8-24-00 Added PriceCurve stuff Updated 3-6-11 + 8-1-01 Modified Compute Capacity to report up to loadmult=1 + 9-25-15 Fixed broken repository +*/ + +/*$WARN UNIT_PLATFORM OFF*/ + + +#include "System.h" +#include "Sysutils.h" + +#include "Solution.h" +#include "Arraydef.h" +#include "HashList.h" +#include "PointerList.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Bus.h" +#include "LoadShape.h" +#include "PriceShape.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "AutoAdd.h" +#include "EnergyMeter.h" +#include "NamedObject.h" +#include "CktTree.h" +#include "Monitor.h" +#include "PCClass.h" +#include "PDClass.h" +#include "MeTIS_Exec.h" +#include "ControlQueue.h" +#include +#include +#include "Sparse_Math.h" +#include "d2c_structures.h" +#include +#include +#include +#include + + + + +namespace Circuit +{ + + enum TReductionStrategy { + rsDefault, + rsShortlines, + rsMergeParallel, + rsBreakLoop, + rsDangling, + rsSwitches, + rsLaterals + }; + + struct CktElementDef { + int CktElementClass; + int devHandle; + }; + + typedef CktElementDef CktElementDefArray[1/*# range 1..1*/]; + typedef std::vector pCktElementDefArray; + + + + // for adding markers to Plot + + + class TBusMarker : public TObject + // Must be defined before calling circuit plot + { + typedef TObject inherited; + friend class TDSSCircuit; + private: + public: + String BusName; + int AddMarkerColor, AddMarkerCode, AddMarkerSize; + TBusMarker(); + virtual ~TBusMarker(); + }; + + + class TDSSCircuit : public TNamedObject { + typedef TNamedObject inherited; + friend class TBusMarker; + public: + std::vector NodeBuffer; + int NodeBufferMax; + bool FBusNameRedefined; + TDSSCktElement* FActiveCktElement; + String FCaseName; + + // Temp arrays for when the bus swap takes place + pTBusArray SavedBuses; + pStringArray SavedBusNames; + int SavedNumBuses; + double FLoadMultiplier; // global multiplier for every load + bool AbortBusProcess; + TCktTree* Branch_List; // topology from the first source, lazy evaluation + TAdjArray BusAdjPC; + TAdjArray BusAdjPD; // bus adjacency lists of PD and PC elements + void AddDeviceHandle(int Handle); + void AddABus(); + void AddANodeBus(); + int AddBus(const String BusName, int NNodes, int ActorID); + void Set_ActiveCktElement(TDSSCktElement* Value); + void Set_BusNameRedefined(bool Value); + complex Get_Losses(int ActorID); //Total Circuit losses + void Set_LoadMultiplier(double Value); + void SaveBusInfo(); + void RestoreBusInfo(); + bool SaveMasterFile(); + bool SaveDSSObjects(); + bool SaveFeeders(); + bool SaveBusCoords(); + bool SaveGISCoords(); + bool SaveVoltageBases(); + void ReallocDeviceList(int ActorID); + void Set_CaseName(const String Value); + String Get_Name(); + public: + int ActiveBusIndex; + double Fundamental; // fundamental and default base frequency + bool Control_BusNameRedefined; // Flag for use by control elements to detect redefinition of buses + THashList BusList, AutoAddBusList, DeviceList; + pCktElementDefArray DeviceRef; //Type and handle of device + bool LongLineCorrection; + // lists of pointers to different elements by class + + //by dahei + + //Generic5OrderMach, + // + + // Storage2Elements, + + // PVSystems2, + // added for CIM XML export + TPointerList Faults; + TPointerList PDElements; + TPointerList PCElements; + TPointerList DSSControls; + TPointerList Sources; + TPointerList MeterElements; + TPointerList Sensors; + TPointerList Monitors; + TPointerList FMonitors; + TPointerList EnergyMeters; + TPointerList Generators; + TPointerList WindGens; + TPointerList StorageElements; + TPointerList PVSystems; + TPointerList Substations; + TPointerList Transformers; + TPointerList CapControls; + TPointerList RegControls; + TPointerList Lines; + TPointerList Loads; + TPointerList ShuntCapacitors; + TPointerList AutoTransformers; + TPointerList Feeders; + TPointerList Reactors; + TPointerList Relays; + TPointerList Fuses; + TPointerList Reclosers; + TPointerList SwtControls; + TPointerList InvControls2; + TPointerList ExpControls; + TPointerList CktElements; + + // BHSL + TPointerList Gencls; + TPointerList Genrou; + + + TPointerList ExcSexs; + TPointerList Tgov; + + ControlQueue::TControlQueue ControlQueue; + TSolutionObj* Solution; + TAutoAdd AutoAddObj; + + // For AutoAdd stuff + double UEWeight, LossWeight; + int NumUEregs, NumLossRegs; + pIntegerArray UEregs, LossRegs; + double CapacityStart, CapacityIncrement; // flag for trapezoidal integratio + bool TrapezoidalIntegration, LogEvents; + String LoadDurCurve; + TLoadShapeObj* LoadDurCurveObj; + String PriceCurve; + TPriceShapeObj* PriceCurveObj; + int NumDevices, NumBuses, NumNodes; + int MaxDevices, MaxBuses, MaxNodes; + int IncDevices, IncBuses, IncNodes; + + // Variables for the tearing Algorithm + // Used for the user to stablish the coverage for the algorithm + double Coverage, Actual_Coverage; // Indicates the actual coverage of the circuit after running the tearing algorithm + std::vector < int > Longest_paths; //Stores the coordinates of the longest paths in the circuit + std::vector < int > Path_Idx; //Stores the indexes from where the areas where formed on the linearized graph + std::vector < int > Buses_Covered; //Stores the number of buses (estimated - 1 quadrant) per path + std::vector < int > Path_Size; //Stores the estimated size of each path + std::vector < int > New_Graph; //Stores the latest weighted graph + int Num_SubCkts; // Stores the number of subcircuits for tearing the circuit when executing the "tear_Circuit" command + std::vector < String > Link_Branches; // Stores the names of the Link branches for Diakoptics + std::vector < String > PConn_Names; // Stores the names of the buses (bus1) of the link branches + std::vector < double > PConn_Voltages; // Stores the voltages at the point of connection of the subcircuits + std::vector < int > Locations; // Stores the indexes of the locations + std::vector < String > BusZones; + + // Variables for Diakoptics + TSparse_Complex ContoursT; // Contours matrix transposed + TSparse_Complex Contours; // Contours matrix + TSparse_Complex ZLL; // Link branch matrix + TSparse_Complex ZCT; // The transformation matrix (to go from one to other domain) + TSparse_Complex ZCC; // Interconnections matrix + TSparse_Complex Y4; // The inverse of the interconnections matrix + TSparse_Complex V_0; // The voltages of the partial solutions + TSparse_Complex Ic; // The complementary Currents vector + int VIndex; // To store the index of the sub-circuit in the interconnected system + int VLength; // To store the length of the sub-circuit in the interconnected system + bool AD_Init; // This is used only by the A-Diakoptics coordiantor (ID = 1) + + // Bus and Node stuff + pTBusArray Buses; + pTNodeBusArray MapNodeToBus; + + // Flags + bool Issolved; + bool DuplicatesAllowed; + bool ZonesLocked; + bool MeterZonesComputed; + bool PositiveSequence; // Model is to be interpreted as Pos seq + bool NeglectLoadY; + + // Voltage limits + double NormalMinVolts, NormalMaxVolts, EmergMaxVolts, EmergMinVolts; //per unit voltage restraints for this circuit + std::vector LegalVoltageBases; + + // Global circuit multipliers + // global multiplier for every generator + double GeneratorDispatchReference, DefaultGrowthFactor, DefaultGrowthRate, GenMultiplier, HarmMult; + complex DefaultHourMult; + double PriceSignal; // price signal for entire circuit + + // EnergyMeter Totals + TRegisterArray RegisterTotals; + TLoadShapeObj* DefaultDailyShapeObj; + TLoadShapeObj* DefaultYearlyShapeObj; + String CurrentDirectory; + TReductionStrategy ReductionStrategy; + /*ReductionMaxAngle,*/ + double ReductionZmag; + bool ReduceLateralsKeepLoad; + String ReductionStrategyString; + double PctNormalFactor; + + /*------Plot Marker Circuit Globals---------*/ + int NodeMarkerCode; + int NodeMarkerWidth; + int SwitchMarkerCode; + int TransMarkerSize; + int CapMarkerSize; + int RegMarkerSize; + int PVMarkerSize; + int StoreMarkerSize; + int FuseMarkerSize; + int RecloserMarkerSize; + int RelayMarkerSize; + int TransMarkerCode; + int CapMarkerCode; + int RegMarkerCode; + int PVMarkerCode; + int StoreMarkerCode; + int FuseMarkerCode; + int RecloserMarkerCode; + int RelayMarkerCode; + bool MarkSwitches; + bool MarkTransformers; + bool MarkCapacitors; + bool MarkRegulators; + bool MarkPVSystems; + // MarkPVSystems2 :Boolean; + bool MarkStorage; + // MarkStorage2 :Boolean; + bool MarkFuses; + bool MarkReclosers; + bool MarkRelays; + int NumCircuits; + TList BusMarkerList; // list of buses to mark + + /*---------------------------------*/ + int ActiveLoadShapeClass; + TStringList MeTISZones; // The list for assigning a zone to a bus after tearing + TDSSCircuit(const String aName); + virtual ~TDSSCircuit(); + void AddCktElement(int Handle); // Adds last DSS object created to circuit + void ClearBusMarkers(); + void TotalizeMeters(); + bool ComputeCapacity(int ActorID); + bool Save(String Dir); + void ProcessBusDefs(int ActorID); + void ReProcessBusDefs(int ActorID); + void DoResetMeterZones(int ActorID); + int SetElementActive(const String FullObjectName); + void InvalidateAllPCElements(); + void DebugDump(Textfile& F); + + // Access to topology from the first source + TCktTree& GetTopology(); + void FreeTopology(); + TAdjArray GetBusAdjacentPDLists(int ActorID); + TAdjArray GetBusAdjacentPCLists(int ActorID); + int Tear_Circuit(); // Tears the circuit considering the number of Buses of the original Circuit + String Create_MeTIS_graph(); // Generates the graph dscribing the model for MeTiS + String Create_MeTIS_Zones(String Filename); // Executes MeTiS and loads the zones into memory for further use + void AggregateProfiles(String mode); + void Disable_All_DER(); + void Save_SubCircuits(bool AddISrc); + DynStringArray getPCEatBus(String BusName); + DynStringArray getPDEatBus(String BusName); + String ReportPCEatBus(String BusName); + String ReportPDEatBus(String BusName); + String get_Line_Bus(String LName, int NBus); + void get_longest_path(); + int Append2PathsArray(std::vector < int >* New_Path, int New_Path_maxidx);// appends a new path to the array and returns the index(1D) + void Normalize_graph(); + void Get_paths_4_Coverage(); // Calculates the paths inside the graph + TDSSCktElement* get_FActiveCktElement(); + double get_FLoadMultiplier(); + bool get_FBusNameRedefined(); + std::string get_FCaseName(); + // To guarantee the desired coverage when tearing the system + // Arrange the files of the subcircuits to make them independent + void Format_SubCircuits(String Path, int NumCkts, bool AddISrc); + // Appends single phase ISources at the end of the given + void AppendIsources(String myPath, int BusNum, String LinkBranch); + }; + +} // namespace Circuit + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Circuit; +#endif + +#endif // CircuitH + + + + + + + + + diff --git a/OpenDSSC/Common/CktElement.cpp b/OpenDSSC/Common/CktElement.cpp new file mode 100644 index 0000000..07a2d9d --- /dev/null +++ b/OpenDSSC/Common/CktElement.cpp @@ -0,0 +1,1485 @@ + + +#pragma hdrstop + + +#include "CktElement.h" + +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "d2c_structures.h" +#include + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +namespace CktElement +{ + TDSSCktElement::TDSSCktElement(String ClassName) : inherited(ClassName) {} + TDSSCktElement::TDSSCktElement() {} + + int TDSSCktElement::InitializeStates(int ActorID) + { + // Should not get to this point, or error ocurred! + return 0; + } + + TDSSCktElement::TDSSCktElement(TDSSClass* ParClass ) + : inherited(ParClass), + FEnabled(false), + FEnabledProperty(0), + FActiveTerminal(0), + FYPrimInvalid(false), + FHandle(0), + Fnterms(0), + Fnconds(0), + Fnphases(0), + BusIndex(0), + FYprimFreq(0.0), + NodeRef(0), + Yorder(0), + LastTerminalChecked(0), + Checked(false), + HasEnergyMeter(false), + HasSensorObj(false), + IsIsolated(false), + HasControl(false), + IsMonitored(false), + IsPartofFeeder(false), + Drawn(false), + HasOCPDevice(false), + HasAutoOCPDevice(false), + HasSwtControl(false), + BaseFrequency(0.0), + PublicDataSize(0), + PublicDataStruct(NULL) + { + int i = 0; + // + YPrim_Series = NULL; + YPrim_Shunt = NULL; + YPrim = NULL; + Terminals.clear(); + FBusNames.clear(); + Vterminal.clear(); + Iterminal.clear(); // present value of terminal current + ComplexBuffer.clear(); + PublicDataStruct = NULL; // pointer to fixed struct of data to be shared + PublicDataSize = 0; + FHandle = - 1; + BusIndex = 0; + Fnterms = 0; + Fnconds = 0; + Fnphases = 0; + DSSObjType = 0; + Yorder = 0; + Set_YprimInvalid(ActiveActor,true); + FEnabled = true; + HasEnergyMeter = false; + HasSensorObj = false; + HasOCPDevice = false; + HasAutoOCPDevice = false; + HasSwtControl = false; + HasControl = false; + IsMonitored = false; + IsPartofFeeder = false; + IsIsolated = false; + Drawn = false; + GFM_Mode = false; + // Make list for a small number of controls with an increment of 1 + ControlElementList = TPointerList( 1 ); + FActiveTerminal = 1; + LastTerminalChecked = 0; + + /* Indicates which solution Itemp is computed for */ + IterminalSolutionCount = new int[CPU_Cores + 1]; + for ( int stop = CPU_Cores, i = 0; i <= stop; i++) + IterminalSolutionCount[i] = - 1; + BaseFrequency = ActiveCircuit[ActiveActor]->Fundamental; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + TDSSCktElement::~TDSSCktElement( ) + { + int i = 0; + Terminals.clear(); + FBusNames.clear(); + Iterminal.clear(); + Vterminal.clear(); + NodeRef.clear(); + ComplexBuffer.clear(); + //if (( ControlElementList != NULL ) ) + + + /*Dispose YPrims*/ + //if ( YPrim_Series != NULL ) + // delete YPrim_Series; //YPrim_Series->~TcMatrix(); + //if ( YPrim_Shunt != NULL ) + // delete YPrim_Shunt; //YPrim_Shunt->~TcMatrix(); + //if ( YPrim != NULL ) + // delete YPrim; // YPrim->~TcMatrix(); + // todo check: inherited::Destroy; + + delete[] IterminalSolutionCount; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TDSSCktElement::get_FActiveTerminal() + { + return FActiveTerminal; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + bool TDSSCktElement::Get_YprimInvalid( int ActorID, const bool Value) + { + bool result = false; + result = FYPrimInvalid; + return result; + } + + + void TDSSCktElement::Set_YprimInvalid( int ActorID, const bool Value ) + { + FYPrimInvalid = Value; + if ( Value ) + { + + // If this device is in the circuit, then we have to rebuild Y on a change in Yprim + if ( FEnabled ) + ActiveCircuit[ActorID]->Solution->SystemYChanged = true; + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_ActiveTerminal( int Value ) + { + if ( ( Value > 0 ) && ( Value <= Fnterms ) ) + { + FActiveTerminal = Value; + ActiveTerminal = &(Terminals[Value - 1]); + } + } + + int TDSSCktElement::Get_ActiveTerminal() + { + return FActiveTerminal; + } + + + void TDSSCktElement::Set_Handle( int Value ) + { + FHandle = Value; + } + + + bool TDSSCktElement::Get_ConductorClosed( int Index, int ActorID, bool Value) + + // return state of selected conductor + // if index=0 return true if all phases closed, else false + + { + bool result = false; + int i = 0; + if ( Index == 0 ) + { + result = true; + for ( int stop = Fnphases, i = 1; i <= stop; i++) + { + if ( ! (Terminals[(FActiveTerminal) - 1].Conductors[i - 1].Closed) ) + { + result = false; + break; + } + } + } + else + if ( ( Index > 0 ) && ( Index <= Fnconds ) ) + result = Terminals[(FActiveTerminal) - 1].Conductors[(Index) - 1].Closed; + else + result = false; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TDSSCktElement::Get_Handle() + { + return FHandle; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + bool TDSSCktElement::Get_Enabled() + { + return FEnabled; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + double TDSSCktElement::Get_YPrimFreq() + { + return FYprimFreq; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TDSSCktElement::Get_NTerms() + { + return Fnterms; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TDSSCktElement::Get_NConds() + { + return Fnconds; + + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TDSSCktElement::Get_NPhases() + { + return Fnphases; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void TDSSCktElement::Set_ConductorClosed( int Index, int ActorID, bool Value ) + { + int i = 0; + if ( Index == 0 ) + { // Do all conductors + for ( int stop = Fnphases, i = 1; i <= stop; i++) + Terminals[(FActiveTerminal) - 1].Conductors[i- 1].Closed = Value; + ActiveCircuit[ActorID]->Solution->SystemYChanged = true; // force Y matrix rebuild + Set_YprimInvalid(ActorID,true); + } + else + { + if ( ( Index > 0 ) && ( Index <= Fnconds ) ) + { + Terminals[(FActiveTerminal) - 1].Conductors[(Index) - 1].Closed = Value; + ActiveCircuit[ActorID]->Solution->SystemYChanged = true; + Set_YprimInvalid(ActorID,true); + } + } + } + + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_Nconds( int Value ) + { + // Check for an almost certain programming error + if ( Value <= 0 ) + { + DoSimpleMsg( "Invalid number of terminals (" + to_string(Value) + ") for " + ParentClass->get_myClass_name() + "." + get_Name() , 749 ); + return; + } + if ( Value != Fnconds ) + ActiveCircuit[ActiveActor]->Set_BusNameRedefined(true); + Fnconds = Value; + Set_NTerms( Fnterms ); // ReallocTerminals NEED MORE EFFICIENT WAY TO DO THIS + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_NPhases( int Value ) + { + if ( Value > 0 ) + Fnphases = Value; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_NTerms( int Value ) + { + int i = 0; + pStringArray NewBusNames; + + // Check for an almost certain programming error + if ( Value <= 0 ) + { + DoSimpleMsg( ("Invalid number of terminals (" + to_string(Value) + ") for " + ParentClass->get_myClass_name() + "." + get_Name()), 749 ); + return; + } + + // If value is same as present value, no reallocation necessary; + // If either Nterms or Nconds has changed then reallocate + if ( ( Value != Fnterms ) || ( Value * Fnconds != Yorder ) ) + { + + /*Sanity Check*/ + if ( Fnconds > 101 ) + { + DoSimpleMsg( "Warning: Number of conductors is very large (" + to_string(Fnconds) + + ") for Circuit Element: " + ParentClass->get_myClass_name() + "." + get_Name() + "." + + "Possible error in specifying the Number of Phases for element.", 750 ); + } + + + /*ReAllocate BusNames */ + // because they are Strings, we have to do it differently + if ( Value < Fnterms ) + FBusNames.resize(Value); // Keeps old values; truncates storage + else + { + if ( FBusNames.empty() ) + { + // First allocation + /* Always allocate arrays of strings with AllocMem so that the pointers are all nil + else Delphi thinks non-zero values are pointing to an existing string.*/ + FBusNames.resize( Value ); // fill with zeros or strings will crash + for ( int stop = Value, i = 1; i <= stop; i++) + FBusNames[i- 1] = get_Name() + "_" + IntToStr( i ); // Make up a bus name to stick in. + // This is so devices like transformers which may be defined on multiple commands + // will have something in the BusNames array. + } + else + { + + NewBusNames = new string[ Value ]; // make some new space + for ( int stop = Fnterms, i = 1; i <= stop; i++) + NewBusNames[i - 1] = FBusNames[i- 1]; // copy old into new +// for ( int stop = Fnterms, i = 1; i <= stop; i++) +// FBusNames[i - 1] = ""; // decrement usage counts by setting to nil string + for ( int stop = Value, i = Fnterms + 1; i <= stop; i++) + NewBusNames[i - 1] = get_Name() + "_" + IntToStr( i ); // Make up a bus name to stick in. + + FBusNames.resize(Value); + if (Value >= (Fnterms + 1)) + { + for (int stop = Value, i = Fnterms + 1; i <= stop; i++) + FBusNames[i- 1] = NewBusNames[i - 1]; + } + delete[] NewBusNames; + } + } + + /*Reallocate Terminals if Nconds or NTerms changed*/ + if (Terminals.size() != 0) + Terminals.clear(); + Terminals.resize(Value + 1); + Fnterms = Value; // Set new number of terminals + Yorder = Fnterms * Fnconds; + Vterminal.resize((Yorder)); + Iterminal.resize((Yorder)); + ComplexBuffer.resize((Yorder) + 1 ); // used by both PD and PC elements + for ( int stop = Value, i = 1; i <= stop; i++) + Terminals[i- 1] = TPowerTerminal( Fnconds ); + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_Enabled( bool Value ) + // If disabled, but defined, just have to processBusDefs. Adding a bus OK + // If being removed from circuit, could remove a node or bus so have to rebuild + //VAR + // NumNodesSaved:Integer; + + { + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + if ( Value != FEnabled ) + { // don't change unless this represents a change + + // This code was too cute and prevented rebuilding of meter zones + // Removed 7/24/01 + /*IF Value THEN Begin + + NumNodesSaved := NumNodes; + ProcessBusDefs; // If we create new nodes, force rebuild of bus lists + If NumNodes>NumNodesSaved Then BusNameRedefined := True + ELSE Solution->SystemYChanged:= True; // just rebuild of yPrim + End + ELSE BusNameRedefined := True; // Force Rebuilding of BusLists anyway + */ + FEnabled = Value; + with0->Set_BusNameRedefined(true); // forces rebuilding of Y matrix and bus lists + } + } + } + + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + int TDSSCktElement::GetYPrim( TcMatrix& Ymatrix, int Opt ) + //returns pointer to actual YPrim + + { + int result = 0; + switch ( Opt ) + { + case ALL_YPRIM: + Ymatrix = *YPrim; + break; + case SERIES: + Ymatrix = *YPrim_Series; + break; + case SHUNT: + Ymatrix = *YPrim_Shunt; + break; + } + result = 0; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + pComplexArray TDSSCktElement::GetYPrimValues( int Opt ) + // Return a pointer to the Beginning the storage arrays for fast access + + { + pComplexArray result; + int Norder = 0; + result = NULL; + switch ( Opt ) + { + case ALL_YPRIM: + if ( YPrim != NULL ) + result = YPrim->GetValuesArrayPtr( Norder ); + break; + case SERIES: + if ( YPrim_Series != NULL ) + result = YPrim_Series->GetValuesArrayPtr( Norder ); + break; + case SHUNT: + if ( YPrim_Shunt != NULL ) + result = YPrim_Shunt->GetValuesArrayPtr( Norder ); + break; + } + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::GetCurrents( pComplexArray Curr, int ActorID ) //Get present value of terminal Curr for reports + + { + DoErrorMsg( "Something is Wrong. Got to base CktElement GetCurrents for Object:" + CRLF + Get_myPName() + "." + get_Name(), "N/A", "Should not be able to get here. Probable Programming Error.", 751 ); + } + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::GetInjCurrents( pComplexArray Curr, int ActorID ) + { + DoErrorMsg( "Something is Wrong. Got to base CktElement GetInjCurrents for Object:" + CRLF + Get_myPName() + "." + get_Name(), "****", "Should not be able to get here. Probable Programming Error.", 752 ); + } + + + void TDSSCktElement::GetLosses( complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID ) + { + /*For no override, Default behavior is: + Just return total losses and set LoadLosses=total losses and noload losses =0*/ + TotalLosses = Get_Losses(ActorID); // Watts, vars + LoadLosses = TotalLosses; + NoLoadLosses = CZero; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + int TDSSCktElement::InjCurrents( int ActorID ) // Applies to PC Elements + + { + int result = 0; + result = 0; + DoErrorMsg( ( "Improper call to InjCurrents for Element: " + get_Name() + "." ), "****", "Called CktElement class base function instead of actual.", 753 ); + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::SetNodeRef( int iTerm, pIntegerArray NodeRefArray ) + + // Also allocates VTemp & Itemp + + { + int Size = 0, Size2 = 0; + // Allocate NodeRef and move new values into it. + Size = Yorder * sizeof( longInt ); + Size2 = sizeof( longInt ) * Fnconds; // Size for one terminal + NodeRef.resize(Yorder); // doesn't do anything if already properly allocated + + Move( NodeRefArray, &(NodeRef[((iTerm - 1) * Fnconds)]), Size2); // Zap + Move( NodeRefArray, &(Terminals[iTerm - 1].TermNodeRef[0]), Size2); // Copy in Terminal as well + + // Allocate temp array used to hold voltages and currents for calcs + Vterminal.resize(Yorder); + Iterminal.resize(Yorder); + ComplexBuffer.resize((Yorder) + 1 ); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + String TDSSCktElement::Get_FirstBus( ) + { + String result; + if ( Fnterms > 0 ) + { + BusIndex = 1; + result = FBusNames[BusIndex - 1]; + } + else + result = ""; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + String TDSSCktElement::Get_NextBus( ) + { + String result; + result = ""; + if ( Fnterms > 0 ) + { + BusIndex++; + if ( BusIndex <= Fnterms ) + result = FBusNames[(BusIndex) - 1]; + else + BusIndex = Fnterms; + } + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + String TDSSCktElement::GetBus( int i ) // Get bus name by index + + { + String result; + if ( i <= Fnterms ) + result = FBusNames[i - 1]; + else + result = ""; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::SetBus( int i, const String S ) // Set bus name by index + + { + if ( i <= Fnterms ) + { + if (FBusNames.size() < Fnterms) + FBusNames.resize(Fnterms); + FBusNames[i - 1] = LowerCase( S ); + ActiveCircuit[ActiveActor]->Set_BusNameRedefined(true); // Set Global Flag to signal circuit to rebuild busdefs + } + else + DoSimpleMsg( Format( "Attempt to set bus name for non-existent circuit element terminal(%d): \"%s\"", i, S.c_str()), 7541 ); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Set_Freq( double Value ) + { + if ( Value > 0.0 ) + FYprimFreq = Value; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::RecalcElementData( int ActorID ) + { + DoSimpleMsg( "Virtual proc RecalcElementData in Base CktElement Class Called for Device = \"" + get_Name() + "\"", 754 ); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::CalcYPrim( int ActorID ) + { + if ( YPrim_Series != NULL ) + DoYprimCalcs( YPrim_Series ); + if ( YPrim_Shunt != NULL ) + DoYprimCalcs( YPrim_Shunt ); + if ( YPrim != NULL ) + DoYprimCalcs( YPrim ); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::ComputeIterminal( int ActorID ) + { + + // to save time, only recompute if a different solution than last time it was computed. + if ( IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount && Yorder > 0) + { + GetCurrents( &(Iterminal[0]), ActorID); + IterminalSolutionCount[ActorID] = ActiveCircuit[ActorID]->Solution->SolutionCount; + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + double TDSSCktElement::MaxTerminalOneIMag( int ActorID ) + + /* Get max of phase currents on the first terminal; Requires computing Iterminal + */ + { + double result = 0.0; + int i = 0; + result = 0.0; + if ( FEnabled ) + for ( int stop = Fnphases, i = 1; i <= stop; i++) + result = max( result, cabs( Iterminal[i - 1] ) ); + // Result := Sqrt(MaxI); // just do the sqrt once and save a little time + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::Get_Current_Mags( pDoubleArray cMBuffer, int ActorID ) + { + int i = 0; + for ( int stop = Fnphases, i = 1; i <= stop; i++) + cMBuffer[i - 1] = cabs( Iterminal[i - 1] ); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + complex TDSSCktElement::Get_Power( int idxTerm, int ActorID ) // Get total complex power in active terminal + + { + complex result = cmplx(0,0); + complex cPower = cmplx(0,0); + int i = 0, k = 0, n = 0; + cPower = CZero; + Set_ActiveTerminal(idxTerm); + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + + // Method: Sum complex power going into phase conductors of active terminal + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + k = ( idxTerm - 1 ) * Fnconds; + for ( int stop = Fnconds, i = 1; i <= stop; i++) // 11-7-08 Changed from Fnphases - was not accounting for all conductors + { + n = ActiveTerminal->TermNodeRef[i - 1]; // don't bother for grounded node + double re = with0->Solution->NodeV[n].re; + double im = with0->Solution->NodeV[n].im; + if ( (!ADiakoptics) || (ActorID == 1)) + { + if ( n > 0 ) + caccum(cPower, cmul(with0->Solution->NodeV[n], conjg(Iterminal[(k) + i - 1]))); + else + if ( n > 0 ) + caccum( cPower, cmul(with0->Solution->VoltInActor1( n ), conjg( Iterminal[(k) + i - 1] ) ) ); + } + } + } + + /*If this is a positive sequence circuit, then we need to multiply by 3 to get the 3-phase power*/ + if ( with0->PositiveSequence ) + cPower = cmulreal( cPower, 3.0 ); + } + result = cPower; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::LossCalc( int& ActorID, complex& cLoss, int& k, int& n ) // of k-th conductor + + { + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + n = (NodeRef)[k - 1]; + if ( n > 0 ) + { + if ( (! ADiakoptics) || ( ActorID == 1 ) ) + { + if (with0->PositiveSequence ) + caccum( cLoss, cmulreal( cmul( with0->Solution->NodeV[n], conjg( (Iterminal)[(k) - 1] ) ), 3.0 ) ); + else + caccum( cLoss, cmul( with0->Solution->NodeV[n], conjg( (Iterminal)[(k) - 1] ) ) ); + } + else + { + // In the context of actor 1 voltages + if ( with0->PositiveSequence ) + caccum( cLoss, cmulreal( cmul( with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[(k) - 1] ) ), 3.0 ) ); + else + caccum( cLoss, cmul(with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[(k) - 1] ) ) ); + } + } + } + } + + + complex TDSSCktElement::Get_Losses( int ActorID ) + // get total losses in circuit element, all phases, all terminals. + // Returns complex losses (watts, vars) + + { + complex result; + complex cLoss; + int k = 0 + + /*Local nested Procedure*/, i = 0, j = 0, n = 0; + cLoss = CZero; + if ( FEnabled && Yorder > 0) + { + ComputeIterminal( ActorID ); + + // Method: Sum complex power going into all conductors of all terminals + /*Special for AutoTransformer - sum based on NPhases rather then Yorder*/ + if ( ( ( CLASSMASK & this->DSSObjType ) ) == AUTOTRANS_ELEMENT ) + { + k = 0; + for ( int stop = Get_NTerms(), j = 1; j <= stop; j++) + { + for ( int stop = Get_NPhases(), i = 1; i <= stop; i++) + { + k++; + LossCalc(ActorID, cLoss, k, n); + } + k += Get_NPhases(); + } + } + else // for all other elements + { + for ( int stop = Yorder, k = 1; k <= stop; k++) + { + LossCalc(ActorID, cLoss, k, n); + } + } + } + result = cLoss; + return result; + } + + + double TDSSCktElement::Get_MaxVoltage( int idxTerm, int ActorID ) + /*Get Voltage at the specified terminal 09/17/2019*/ + { + double result = 0.0; + complex Volts, VN{}, cPower{}; + int ClassIdx = 0, i = 0, k = 0, l = 0, m = 0, nrefN = 0, Nref = 0; + double MaxCurr = 0.0, CurrMag = 0.0; + int MaxPhase = 0; + Set_ActiveTerminal(idxTerm); // set active Terminal + cPower = CZero; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + + // Method: Checks what's the phase with maximum current + // retunrs the voltage for that phase + MaxCurr = 0.0; + MaxPhase = 1; // Init this so it has a non zero value + k = ( idxTerm - 1 ) * Fnconds; // starting index of terminal + for ( int stop = Fnphases, i = 1; i <= stop; i++) + { + CurrMag = cabs( Iterminal[((k) + i) - 1] ); + if ( CurrMag > MaxCurr ) + { + MaxCurr = CurrMag; + MaxPhase = i; + } + } + ClassIdx = DSSObjType & CLASSMASK; // gets the parent class descriptor (int) + Nref = (ActiveTerminal->TermNodeRef)[MaxPhase - 1]; // reference to the phase voltage with the max current + nrefN = (ActiveTerminal->TermNodeRef)[Fnconds - 1]; // reference to the ground terminal (GND or other phase) + /*# with ActiveCircuit[ActorID].Solution do */ // Get power into max phase of active terminal + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + if ( (!ADiakoptics ) || (ActorID == 1)) + { + if ( ! ( ClassIdx == XFMR_ELEMENT ) ) // Only for transformers + Volts = with0->Solution->NodeV[Nref]; + else + Volts = csub(with0->Solution->NodeV[Nref], with0->Solution->NodeV[nrefN] ); + } + else + { + if ( ! ( ClassIdx == XFMR_ELEMENT ) ) // Only for transformers + Volts = with0->Solution->VoltInActor1( Nref ); + else + Volts = csub(with0->Solution->VoltInActor1( Nref ), with0->Solution->VoltInActor1( nrefN ) ); + } + } + } + result = cabs( Volts ); + return result; + } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + double TDSSCktElement::Get_MaxCurrentAng(int idxTerm, int ActorID) + { + int i, k, nref{}, MaxPhase = 0; + double CurrAng, MaxCurr, CurrMag, Result = 0.0; + + Set_ActiveTerminal(idxTerm); + MaxCurr = 0.0; + CurrAng = 0.0; + if (FEnabled) + { + ComputeIterminal(ActorID); + MaxPhase = 1; + k = (idxTerm - 1) * Fnconds; + for (i = 1; i <= Fnphases; i++) + { + CurrMag = cabs(Iterminal[(k) + i - 1]); + if (CurrMag > MaxCurr) + { + MaxCurr = CurrMag; + CurrMag = cang(Iterminal[(k) + i - 1]); + MaxPhase = i; + } + } + } + return Result; + } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + double TDSSCktElement::Get_MaxVoltageAng(int idxTerm, int ActorID) + { + double result = 0.0; + complex Volts, VN{}, cPower; + int ClassIdx = 0, i = 0, k = 0, l = 0, m = 0, nrefN = 0, Nref = 0; + double MaxCurr = 0.0, CurrMag = 0.0; + int MaxPhase = 0; + Set_ActiveTerminal(idxTerm); // set active Terminal + cPower = CZero; + if (FEnabled) + { + ComputeIterminal(ActorID); + + // Method: Checks what's the phase with maximum current + // retunrs the voltage for that phase + MaxCurr = 0.0; + MaxPhase = 1; // Init this so it has a non zero value + k = (idxTerm - 1) * Fnconds; // starting index of terminal + for (int stop = Fnphases, i = 1; i <= stop; i++) + { + CurrMag = cabs(Iterminal[((k) + i) - 1]); + if (CurrMag > MaxCurr) + { + MaxCurr = CurrMag; + MaxPhase = i; + } + } + ClassIdx = DSSObjType & CLASSMASK; // gets the parent class descriptor (int) + Nref = (ActiveTerminal->TermNodeRef)[MaxPhase - 1]; // reference to the phase voltage with the max current + nrefN = (ActiveTerminal->TermNodeRef)[Fnconds - 1]; // reference to the ground terminal (GND or other phase) + /*# with ActiveCircuit[ActorID].Solution do */ // Get power into max phase of active terminal + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + if ((!ADiakoptics) || (ActorID == 1)) + { + if (!(ClassIdx == XFMR_ELEMENT)) // Only for transformers + Volts = with0->Solution->NodeV[Nref]; + else + Volts = csub(with0->Solution->NodeV[Nref], with0->Solution->NodeV[nrefN]); + } + else + { + if (!(ClassIdx == XFMR_ELEMENT)) // Only for transformers + Volts = with0->Solution->VoltInActor1(Nref); + else + Volts = csub(with0->Solution->VoltInActor1(Nref), with0->Solution->VoltInActor1(nrefN)); + } + } + } + result = cang(Volts); + return result; + } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + complex TDSSCktElement::Get_MaxPower( int idxTerm, int ActorID ) + /*Get power in the phase with the max current and return equivalent power as if it were balanced in all phases + 2/12/2019*/ + { + complex result; + complex Volts, VN{}, cPower; + int ClassIdx = 0, i = 0, k = 0, l = 0, m = 0, nrefN = 0, Nref = 0; + double MaxCurr = 0.0, CurrMag = 0.0; + int MaxPhase = 0; + Set_ActiveTerminal(idxTerm); // set active Terminal + cPower = CZero; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + + // Method: Get power in the phase with max current of active terminal + // Multiply by Nphases and return + MaxCurr = 0.0; + MaxPhase = 1; // Init this so it has a non zero value + k = ( idxTerm - 1 ) * Fnconds; // starting index of terminal + for ( int stop = Fnphases, i = 1; i <= stop; i++) + { + CurrMag = cabs( (Iterminal)[(k) + i - 1] ); + if ( CurrMag > MaxCurr ) + { + MaxCurr = CurrMag; + MaxPhase = i; + } + } + ClassIdx = DSSObjType & CLASSMASK; // gets the parent class descriptor (int) + Nref = (ActiveTerminal->TermNodeRef)[MaxPhase - 1]; // reference to the phase voltage with the max current + nrefN = (ActiveTerminal->TermNodeRef)[Fnconds - 1]; // reference to the ground terminal (GND or other phase) + /*# with ActiveCircuit[ActorID].Solution do */ // Get power into max phase of active terminal + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + if ( (! ADiakoptics) || ( ActorID == 1 ) ) + { + if ( ! ( ClassIdx == XFMR_ELEMENT ) ) // Only for transformers + Volts = with0->Solution->NodeV[Nref]; + else + Volts = csub(with0->Solution->NodeV[Nref], with0->Solution->NodeV[nrefN] ); + } + else + { + if ( ! ( ClassIdx == XFMR_ELEMENT ) ) // Only for transformers + Volts = with0->Solution->VoltInActor1( Nref ); + else + Volts = csub(with0->Solution->VoltInActor1( Nref ), with0->Solution->VoltInActor1( nrefN ) ); + } + cPower = cmul( Volts, conjg( (Iterminal)[(k) + MaxPhase - 1] ) ); + } + + // Compute equivalent total power of all phases assuming equal to max power in all phases + /*# with cPower do */ + { + cPower.re = cPower.re * Fnphases; // let compiler handle type coercion + cPower.im = cPower.im * Fnphases; + } + + /*If this is a positive sequence circuit (Fnphases=1), + then we need to multiply by 3 to get the 3-phase power*/ + if (with0->PositiveSequence ) + cPower = cmulreal( cPower, 3.0 ); + } + result = cPower; + return result; + } + + + double TDSSCktElement::Get_MaxCurrent( int idxTerm, int ActorID ) + { + double result = 0.0; + int i = 0, k = 0, Nref = 0; + double MaxCurr = 0.0, CurrMag = 0.0; + int MaxPhase = 0; + Set_ActiveTerminal(idxTerm); // set active Terminal + MaxCurr = 0.0; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + // Method: Get max current at terminal (magnitude) + MaxCurr = 0.0; + MaxPhase = 1; // Init this so it has a non zero value + k = ( idxTerm - 1 ) * Fnconds; // starting index of terminal + for ( int stop = Fnphases, i = 0; i < stop; i++) + { + CurrMag = cabs( (Iterminal)[(k) + i] ); + if ( CurrMag > MaxCurr ) + { + MaxCurr = CurrMag; + MaxPhase = i + 1; + } + } + } + result = MaxCurr; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::GetPhasePower( pComplexArray PowerBuffer, int ActorID ) + // Get the power in each phase (complex losses) of active terminal + // neutral conductors are ignored by this routine + + { + int i = 0, n = 0; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + for ( int stop = Yorder, i = 1; i <= stop; i++) + { + n = (NodeRef)[i - 1]; // increment through terminals + if ( n > 0 ) + { + if ( (!ADiakoptics) || (ActorID == 1)) + { + if (with0->PositiveSequence ) + (PowerBuffer)[i - 1] = cmulreal( cmul(with0->Solution->NodeV[n], conjg( (Iterminal)[i - 1] ) ), 3.0 ); + else + (PowerBuffer)[i - 1] = cmul(with0->Solution->NodeV[n], conjg( (Iterminal)[i - 1] ) ); + } + else + { + // In the context of actor 1 votlages + if (with0->PositiveSequence ) + (PowerBuffer)[i - 1] = cmulreal( cmul(with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[i - 1] ) ), 3.0 ); + else + (PowerBuffer)[i - 1] = cmul(with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[i - 1] ) ); + } + } + } + } + else + for ( int stop = Yorder, i = 1; i <= stop; i++) + (PowerBuffer)[i - 1] = CZero; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::GetPhaseLosses( int& Num_Phases, pComplexArray LossBuffer, int ActorID ) + // Get the losses in each phase (complex losses); Power difference coming out + // each phase. Note: This can be misleading if the nodev voltage is greatly unbalanced. + // neutral conductors are ignored by this routine + + { + int i = 0, j = 0, k = 0, n = 0; + complex cLoss; + Num_Phases = Fnphases; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + for ( int stop = Num_Phases, i = 1; i <= stop; i++) + { + cLoss = cmplx( 0.0, 0.0 ); + for ( int stop = Fnterms, j = 1; j <= stop; j++) + { + k = ( j - 1 ) * Fnconds + i - 1; + n = (NodeRef)[k]; // increment through terminals + if ( n > 0 ) + { + if ( (! ADiakoptics) || ( ActorID == 1 ) ) + { + if (with0->PositiveSequence ) + caccum( cLoss, cmulreal( cmul(with0->Solution->NodeV[n], conjg( (Iterminal)[k] ) ), 3.0 ) ); + else + caccum( cLoss, cmul(with0->Solution->NodeV[n], conjg( (Iterminal)[k] ) ) ); + } + else + { + // In the context of actor 1 voltage + if (with0->PositiveSequence ) + caccum( cLoss, cmulreal( cmul(with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[k] ) ), 3.0 ) ); + else + caccum( cLoss, cmul(with0->Solution->VoltInActor1( n ), conjg( (Iterminal)[k] ) ) ); + } + } + } + (LossBuffer)[i - 1] = cLoss; + } + } + else + for ( int stop = Num_Phases, i = 1; i <= stop; i++) + (LossBuffer)[i - 1] = CZero; + } + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::DumpProperties( Textfile& F, bool Complete ) + { + int i = 0, j = 0; + inherited::DumpProperties( F, Complete ); + if ( FEnabled ) + { + WriteLn( F , "! ENABLED" ); + } + else + { + WriteLn( F , "! DISABLED" ); + } + if ( Complete ) + { + Write( F, "! NPhases = " ); WriteLn( F, Fnphases, 0 ); + Write( F, "! Nconds = " ); WriteLn( F, Fnconds, 0 ); + Write( F, "! Nterms = " ); WriteLn( F, Fnterms, 0 ); + Write( F, "! Yorder = " ); WriteLn( F, to_string(Yorder), 0 ); + Write( F, "! NodeRef = \"" ); + if ( NodeRef.empty()) + { + Write( F, "nil" ); + } + else + for ( int stop = Yorder, i = 1; i <= stop; i++) + { + Write( F, NodeRef[i - 1], 0 ); Write( F, ' ' ); + } + WriteLn( F, '\"' ); + Write( F, "! Terminal Status: [" ); + for ( int stop = Fnterms, i = 1; i <= stop; i++) + for ( int stop = Fnconds, j = 1; j <= stop; j++) + { + if ( Terminals[i - 1].Conductors[j - 1].Closed ) + { + Write( F, "C " ); + } + else + { + Write( F, "O " ); + } + } + WriteLn( F, ']' ); + Write( F, "! Terminal Bus Ref: [" ); + for ( int stop = Fnterms, i = 1; i <= stop; i++) + for ( int stop = Fnconds, j = 1; j <= stop; j++) + { + Write( F, Terminals[i - 1].BusRef, 0 ); Write( F, ' ' ); + } + WriteLn( F, ']' ); + WriteLn( F ); + if ( YPrim != NULL ) + { + WriteLn( F, "! YPrim (G matrix)" ); + for ( int stop = Yorder, i = 1; i <= stop; i++) + { + Write( F, "! " ); + for ( int stop = Yorder, j = 1; j <= stop; j++) + { + Write( F, Format( " %13.10g |", YPrim->GetElement( i, j ).re) ); + } + WriteLn( F ); + } + WriteLn( F, "! YPrim (B Matrix) = " ); + for ( int stop = Yorder, i = 1; i <= stop; i++) + { + Write( F, "! " ); + for ( int stop = Yorder, j = 1; j <= stop; j++) + { + Write( F, Format( " %13.10g |", YPrim->GetElement( i, j ).im ) ); + } + WriteLn( F ); + } + } + } /*If complete*/ + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TDSSCktElement::DoYprimCalcs( TcMatrix* Ymatrix ) + { + int i = 0, j = 0, k = 0, ii = 0, jj = 0, ElimRow = 0; + complex Ynn, Yij, Yin, Ynj; + std::vector RowEliminated; + bool ElementOpen = false; + complex cEpsilon; + /*Now Account for Open Conductors + Perform a Kron Reduction on rows where I is forced to zero. + Then for any conductor that is open, zero out row and column. + */ + /*# with Ymatrix do */ + { + ElementOpen = false; + k = 0; + for ( int stop = Fnterms, i = 1; i <= stop; i++) + { + for ( int stop = Fnconds, j = 1; j <= stop; j++) + { + if ( ! Terminals[i - 1].Conductors[(j) - 1].Closed ) + { + if ( ! ElementOpen ) + { + RowEliminated.resize( Yorder ); + ElementOpen = true; + cEpsilon = cmplx( EPSILON, 0.0 ); + } + // First do Kron Reduction + ElimRow = j + k; + Ynn = Ymatrix->GetElement( ElimRow, ElimRow ); + if ( cabs( Ynn ) == 0.0 ) + Ynn.re = EPSILON; + RowEliminated[(ElimRow) - 1] = 1; + for ( int stop = Yorder, ii = 1; ii <= stop; ii++) + { + if ( RowEliminated[(ii) - 1] == 0 ) + { + Yin = Ymatrix->GetElement( ii, ElimRow ); + for ( int stop = Yorder, jj = ii; jj <= stop; jj++) + if ( RowEliminated[(jj) - 1] == 0 ) + { + Yij = Ymatrix->GetElement( ii, jj ); + Ynj = Ymatrix->GetElement( ElimRow, jj ); + Ymatrix->SetElemsym( ii, jj, csub( Yij, cdiv( cmul( Yin, Ynj ), Ynn ) ) ); + } + } + } + // Now zero out row and column + Ymatrix->ZeroRow( ElimRow ); + Ymatrix->ZeroCol( ElimRow ); + // put a small amount on the diagonal in case node gets isolated + Ymatrix->SetElement( ElimRow, ElimRow, cEpsilon ); + } + } + k = k + Fnconds; + } + /* Clean up at end of loop. + Add in cEpsilon to diagonal elements of remaining rows to avoid leaving a bus hanging. + This happens on low-impedance simple from-to elements when one terminal opened. + */ + if ( ElementOpen ) + { + for ( int stop = Yorder, ii = 1; ii <= stop; ii++) + if ( RowEliminated[(ii) - 1] == 0 ) + Ymatrix->AddElement( ii, ii, cEpsilon ); + RowEliminated.clear(); + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void TDSSCktElement::SumCurrents( int ActorID ) + + // sum Terminal Currents into System Currents Array + // Primarily for Newton Iteration + + { + int i = 0; + if ( FEnabled ) + { + ComputeIterminal( ActorID ); + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + for ( int stop = Yorder, i = 1; i <= stop; i++) + caccum(with0->Solution->Currents[NodeRef[i - 1]], Iterminal[i - 1] ); // Noderef=0 is OK + } + } + + + void TDSSCktElement::GetTermVoltages( int iTerm, pComplexArray VBuffer, int ActorID ) + + // Bus Voltages at indicated terminal + // Fill Vbuffer array which must be adequately allocated by calling routine + + { + int Ncond = 0, i = 0, j = 0; + try + { + Ncond = Get_NConds(); + + /*return Zero if terminal number improperly specified*/ + if ( ( iTerm < 1 ) || ( iTerm > Fnterms ) ) + { + for ( int stop = Ncond, i = 1; i <= stop; i++) + (VBuffer)[i - 1] = CZero; + return; + } + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + if ( (! ADiakoptics) || ( ActorID == 1 ) ) + VBuffer[i - 1] = with0->Solution->NodeV[ Terminals[(iTerm) - 1].TermNodeRef[i - 1]]; + else + VBuffer[i - 1] = with0->Solution->VoltInActor1( Terminals[(iTerm) - 1].TermNodeRef[i - 1] ); + } + } + catch( exception & E ) + { + DoSimpleMsg( "Error filling voltage buffer in GetTermVoltages for Circuit Element:" + Get_myPName() + "." + get_Name() + CRLF + "Probable Cause: Invalid definition of element." + CRLF + "System Error Message: " + (string) E.what(), 755 ); + } + } + + + void TDSSCktElement::InitPropertyValues( int ArrayOffset ) + { + Set_PropertyValue(ArrayOffset + 1, to_string( BaseFrequency )); // Base freq + Set_PropertyValue(ArrayOffset + 2, "true"); // Enabled + FEnabledProperty = ArrayOffset + 2; // keep track of this + inherited::InitPropertyValues( ArrayOffset + 2 ); + } + + + String TDSSCktElement::GetPropertyValue( int Index ) + { + String result = ""; + if ( Index == FEnabledProperty ) + { + if ( Get_Enabled() ) + result = "true"; + else + result = "false"; + // *** RCD 6-18-03 commented out PropertyValue[FEnabledProperty] := Result; // Keep this in synch + } + else + result = inherited::GetPropertyValue( Index ); + return result; + } + + + void TDSSCktElement::GetSeqLosses( complex& PosSeqLosses, complex& NegSeqLosses, complex& ZeroModeLosses, int ActorID ) + { + + /* For the base class, just return CZERO*/ + + /*Derived classes have to supply appropriate function*/ + PosSeqLosses = CZero; + NegSeqLosses = CZero; + ZeroModeLosses = CZero; + } + + + bool IsGroundBus( const String S ) + { + bool result = false; + size_t i = 0; + result = true; + i = S.find( ".1" ); + if ( i != String::npos ) + result = false; + i = S.find( ".2" ); + if ( i != String::npos ) + result = false; + i = S.find( ".3" ); + if ( i != String::npos ) + result = false; + i = S.find( "." ); + if ( i == String::npos ) + result = false; + return result; + } + + double TDSSCktElement::Get_PCEValue(int idxTerm, int ValType, int ActorID) + { + double Result = 0.0; + switch (ValType) + { + case 0: + case 7: Result = -1 * Get_Power(1,ActorID).re; // P, P0 + break; + case 1: + case 8: Result = -1 * Get_Power(1, ActorID).im; // Q, Q0 + break; + case 2: Result = Get_MaxVoltage(1,ActorID); // VMag + break; + case 3: Result = Get_MaxVoltageAng(1,ActorID); // VAng + break; + case 4: Result = Get_MaxCurrent(1,ActorID); // IMag + break; + case 5: Result = Get_MaxCurrentAng(1,ActorID); // IAng + break; + case 6: Result = cabs(Get_Power(1,ActorID)); // S + break; + default: Result = 0.0; + break; + } + return Result; + } + + + void TDSSCktElement::MakePosSequence( int ActorID ) + { + int i = 0; + bool grnd = false; + for ( int stop = Fnterms, i = 1; i <= stop; i++) + { + grnd = IsGroundBus( FBusNames[i - 1] ); + FBusNames[i - 1] = StripExtension( FBusNames[i - 1] ); + if ( grnd ) + FBusNames[i - 1] = FBusNames[i - 1] + ".0"; + } + } + + + void TDSSCktElement::ComputeVterminal( int ActorID ) + + /*Put terminal voltages in an array*/ + { + int i = 0, j = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + for ( int stop = Yorder, i = 1; i <= stop; i++) + if ( (! ADiakoptics) || ( ActorID == 1 ) ) + Vterminal[i - 1] = with0->Solution->NodeV[ NodeRef[i - 1] ]; + else + Vterminal[i - 1] = with0->Solution->VoltInActor1( NodeRef[i - 1] ); + } + + + void TDSSCktElement::ZeroITerminal( ) + { + int i = 0; + for ( int stop = Yorder, i = 1; i <= stop; i++) + Iterminal[i - 1] = CZero; + } + +} + + + + + + diff --git a/OpenDSSC/Common/CktElement.h b/OpenDSSC/Common/CktElement.h new file mode 100644 index 0000000..3dab27f --- /dev/null +++ b/OpenDSSC/Common/CktElement.h @@ -0,0 +1,183 @@ +#ifndef CktElementH +#define CktElementH + + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + /* + 2-17-00 Modified Get_ConductorClosed to handle Index=0 + 7-14-01 Changed way Enabled property works. + 8-17-06 Caught BusnameRedefined error when nconds changed + */ + + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "Arraydef.h" +#include "Terminal.h" +#include "DSSObject.h" +#include "DSSClass.h" +#include "PointerList.h" + +using namespace std; + +namespace CktElement +{ + + class TDSSCktElement : public TDSSObject { + typedef TDSSObject inherited; + public: +// private: + std::vector < std::string > FBusNames; + bool FEnabled; + int FEnabledProperty; + int FActiveTerminal; + bool FYPrimInvalid; + int FHandle; + void Set_Freq(double Value); // set freq and recompute YPrim. + void Set_Nconds(int Value); + void Set_NPhases(int Value); + void Set_ActiveTerminal(int Value); + int Get_ActiveTerminal(); + bool Get_ConductorClosed(int Index, int ActorID, bool Value = false); + void Set_YprimInvalid(int ActorID, const bool Value); + bool Get_YprimInvalid(int ActorID, const bool Value); + std::string Get_FirstBus(); + std::string Get_NextBus(); // null string if no more values + complex Get_Losses(int ActorID); // Get total losses for property... + complex Get_Power(int idxTerm, int ActorID); // Get total complex power in active terminal + complex Get_MaxPower(int idxTerm, int ActorID); // Get equivalent total complex power in active terminal based on phase with max current + double Get_MaxCurrent(int idxTerm, int ActorID); // Get equivalent total complex current on phase with max current + double Get_MaxVoltage(int idxTerm, int ActorID); // Get equivalent total complex voltage on phase + double Get_MaxCurrentAng(int idxTerm, int ActorID); + double Get_MaxVoltageAng(int idxTerm, int ActorID); + void DoYprimCalcs(TcMatrix* Ymatrix); + //protected: + int Fnterms; + int Fnconds; // no. conductors per terminal + int Fnphases; // Phases, this device + std::vector ComplexBuffer; + int* IterminalSolutionCount; + int BusIndex; + TcMatrix* YPrim_Series; + TcMatrix* YPrim_Shunt; + TcMatrix* YPrim; // Order will be NTerms * Ncond + double FYprimFreq; // Frequency at which YPrim has been computed + virtual void Set_Enabled(bool Value); + void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void Set_NTerms(int Value); + void Set_Handle(int Value); + public: + void LossCalc(int& ActorID, complex& cLoss, int& k, int& n); + /*Total Noderef array for element*/ + std::vector NodeRef; // Need fast access to this + longInt Yorder; + int LastTerminalChecked; // Flag used in tree searches + bool Checked, HasEnergyMeter, HasSensorObj, IsIsolated, HasControl, IsMonitored, IsPartofFeeder, Drawn; // Flag used in tree searches etc + bool HasOCPDevice; // Fuse, Relay, or Recloser + bool HasAutoOCPDevice; // Relay or Recloser only + bool HasSwtControl; // Has a remotely-controlled Switch + PointerList::TPointerList ControlElementList; //Pointer to control for this device + std::vector Iterminal; // Others need this + std::vector Vterminal; + double BaseFrequency; + pTerminalList Terminals; + TPowerTerminal* ActiveTerminal; + int PublicDataSize; // size of PublicDataStruct + void* PublicDataStruct; // Generic Pointer to public data Block that may be access by other classes of elements + // Accessing app has to know the structure + // Inited to Nil. If Nil, accessing app should ignore + + bool GFM_Mode; + TDSSCktElement(TDSSClass* ParClass); + virtual ~TDSSCktElement(); + virtual int GetYPrim(TcMatrix& Ymatrix, int Opt) //returns values of array + ; + virtual pComplexArray GetYPrimValues(int Opt); + double MaxTerminalOneIMag(int ActorID); // Max of Iterminal 1 phase currents + virtual void ComputeIterminal(int ActorID) // Computes Iterminal for this device + ; + void ComputeVterminal(int ActorID); + void ZeroITerminal(); + virtual void GetCurrents(pComplexArray Curr, int ActorID) //Get present value of terminal Curr for reports + ; + virtual void GetInjCurrents(pComplexArray Curr, int ActorID) // Returns Injextion currents + ; + virtual int InjCurrents(int ActorID) // Applies to PC Elements Puts straight into Solution Array + ; + String GetBus(int i); // Get bus name by index + void SetBus(int i, const String S); // Set bus name by index + virtual void SetNodeRef(int iTerm, pIntegerArray NodeRefArray) // Set NodeRef Array for fast solution with intrinsics + ; + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID) + // radial solution removed PROCEDURE BackwardSweep; Virtual; + ; + virtual void MakePosSequence(int ActorID) // Make a positive Sequence Model + ; + int Get_Handle(); + bool Get_Enabled(); + double Get_YPrimFreq(); + int Get_NTerms(); + int Get_NConds(); + int Get_NPhases(); + void GetTermVoltages(int iTerm, pComplexArray VBuffer, int ActorID); + int get_FActiveTerminal(); + + virtual void GetPhasePower(pComplexArray PowerBuffer, int ActorID); + virtual void GetPhaseLosses(int& Num_Phases, pComplexArray LossBuffer, int ActorID); + virtual void GetLosses(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID); + virtual void GetSeqLosses(complex& PosSeqLosses, complex& NegSeqLosses, complex& ZeroModeLosses, int ActorID); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(Textfile& F, bool Complete); + virtual double Get_PCEValue(int idxTerm, int ValType, int ActorID); + //__declspec (property ( get = Get_YprimInvalid, put = Set_YprimInvalid ) ) bool YprimInvalid[]DECLSPEC_2D; + //__declspec (property (get = Get_Enabled, put = Set_Enabled) ) bool Enabled; + //__declspec (property (get = Get_NTerms, put = Set_NTerms)) int NTerms; + //__declspec (property (get = Get_NConds, put = Set_NConds)) int NConds; + //__declspec (property (get = Get_NPhases, put = Set_NPhases)) int NPhases; + //__declspec (property(get = Get_Power)) complex Power[][]; + //__declspec (property(get = Get_MaxPower)) complex MaxPower[][]; + //__declspec (property(get = Get_MaxCurrent)) double MaxCurrent[][]; + //__declspec (property(get = Get_MaxVoltage)) double MaxVoltage[][]; + + //__declspec (property(get = Get_MaxCurrentAng)) double MaxCurrentAng[][]; + //__declspec (property(get = Get_MaxVoltageAng)) double MaxVoltageAng[][]; + //__declspec (property(get = Get_ActiveTerminal, put = Set_ActiveTerminal)) int ActiveTerminalIdx; + //__declspec (property(get = Get_ConductorClosed, put = Set_ConductorClosed)) bool Closed[][][]; + + //__declspec (property (get = Get_PCEValue)) double PCEValue[][][]; + void SumCurrents(int ActorID); + void Get_Current_Mags(pDoubleArray cMBuffer, int ActorID); // Returns the Currents vector in magnitude + + TDSSCktElement(String ClassName); + TDSSCktElement(); + virtual int InitializeStates(int ActorID); + }; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CktElement; +#endif + +#endif // CktElementH + + + + + + + + + diff --git a/OpenDSSC/Common/CktElementClass.cpp b/OpenDSSC/Common/CktElementClass.cpp new file mode 100644 index 0000000..d646642 --- /dev/null +++ b/OpenDSSC/Common/CktElementClass.cpp @@ -0,0 +1,100 @@ + + +#pragma hdrstop + +#include "CktElementClass.h" + +#include "CktElement.h" +#include "ParserDel.h" +#include "Utilities.h" +#include "DSSGlobals.h" + + +/* TCktElementClass */ + +namespace CktElementClass +{ + + int TCktElementClass::ClassEdit(const void* ActiveCktElemObj, const int ParamPointer) + { + int result = 0; + result = 0; + // continue parsing with contents of Parser + if (ParamPointer > 0) + /*# with TDSSCktElement(ActiveCktElemObj) do */ + { + auto with0 = (TDSSCktElement*)ActiveCktElemObj; + { + switch (ParamPointer) + { + case 1: + with0->BaseFrequency = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + with0->Set_Enabled(InterpretYesNo(Parser[ActiveActor]->MakeString_())); + break; + default: + inherited::ClassEdit(ActiveCktElemObj, ParamPointer - NumCktElemClassProps); + } + } + } + return result; + } + + + void TCktElementClass::ClassMakeLike(const void* OtherObj) + { + TDSSCktElement* OtherCktObj; + OtherCktObj = (TDSSCktElement*) OtherObj; + /*# with TDSSCktElement(ActiveDSSObject[ActiveActor]) do */ + { + auto with0 = (TDSSCktElement*) ActiveDSSObject[ActiveActor]; + { + with0->BaseFrequency = OtherCktObj->BaseFrequency; + with0->Set_Enabled(true); + } + } + } + + + void TCktElementClass::CountProperties() + { + NumProperties = NumProperties + NumCktElemClassProps; + inherited::CountProperties(); + } + + + TCktElementClass::TCktElementClass() + : NumCktElemClassProps(2) + { + inherited(); + } + + + void TCktElementClass::DefineProperties() + + // Define the properties for the base power delivery element class + + { + PropertyName[ActiveProperty + 1] = "basefreq"; + PropertyName[ActiveProperty + 2] = "enabled"; + PropertyHelp[ActiveProperty + 1] = "Base Frequency for ratings."; + PropertyHelp[ActiveProperty + 2] = "{Yes|No or True|False} Indicates whether this element is enabled."; + ActiveProperty = ActiveProperty + NumCktElemClassProps; + inherited::DefineProperties(); + } + + + TCktElementClass::~TCktElementClass() + { + // todo check: inherited::Destroy; + } + +}// namespace CktElementClass + + + + + + + diff --git a/OpenDSSC/Common/CktElementClass.h b/OpenDSSC/Common/CktElementClass.h new file mode 100644 index 0000000..d155c03 --- /dev/null +++ b/OpenDSSC/Common/CktElementClass.h @@ -0,0 +1,55 @@ +#ifndef CktElementClassH +#define CktElementClassH + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + /* Created 5/17/01 RCD to balance inheritance tree for Circuit Elements*/ + + /*$M+*/ + + +#include "System.h" +#include "DSSClass.h" + + + +namespace CktElementClass +{ + + + class TCktElementClass : public TDSSClass { + typedef TDSSClass inherited; + private: + protected: + int virtual ClassEdit(const void* ActiveCktElemObj, const int ParamPointer); + void ClassMakeLike(const void* OtherObj); + void CountProperties(); // Add no. of intrinsic properties + void DefineProperties(); // Add Properties of this class to propName + public: + int NumCktElemClassProps; + TCktElementClass(); + virtual ~TCktElementClass(); + //__published: + }; + +} // namespace CktElementClass + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) + using namespace CktElementClass; +#endif + +#endif // CktElementClassH + + + + + + + + + diff --git a/OpenDSSC/Common/Conductor.cpp b/OpenDSSC/Common/Conductor.cpp new file mode 100644 index 0000000..1c8aa22 --- /dev/null +++ b/OpenDSSC/Common/Conductor.cpp @@ -0,0 +1,67 @@ + + +#pragma hdrstop + +#include "Conductor.h" + +#include "DSSGlobals.h" + +namespace Conductor +{ + + TConductor::TConductor() + : AmbientTemp(0.0), + Accum_Isqt(0.0), + Closed(true), + FuseBlown(false) + { + // inherited::Create(); + Accum_Isqt = 0.0; + //TCC := nil; + TCCName = ""; + } + + + TConductor::~TConductor() + { + // todo check: inherited::Destroy; + } + + + void TConductor::Set_Ambient(double Value) + { + AmbientTemp = Value; + } + + std::string TConductor::Get_TCCName() + { + return TCCName; + } + + void TConductor::Set_TCCname(const String Value) + { + TCCName = LowerCase(Value); + } + + + void TConductor::CalcIsqt(double CurrentMag) // Computes whether conductor has burned down + + { + DoSimpleMsg("Need to implement Tconductor.CalcIsqrt", 770); + } + + + void TConductor::ResetIsqt() // restore the conductor and reset the i2t calcs + + { + DoSimpleMsg("Need to implement Tconductor.ResetIsqt", 771); + } + + + +} // namespace conductor + + + + + diff --git a/OpenDSSC/Common/Conductor.h b/OpenDSSC/Common/Conductor.h new file mode 100644 index 0000000..7b27440 --- /dev/null +++ b/OpenDSSC/Common/Conductor.h @@ -0,0 +1,65 @@ +#ifndef ConductorH +#define ConductorH + +#include "System.h" +#include "Sysutils.h" +#include + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +//#include + +/*USES + TCC_Curve;*/ + + +//class TConductor; + +namespace Conductor +{ + + class TConductor { + private: + std::string TCCName; + //TCC:TTCC_Curve; // pointer to TCC curve or nil + double AmbientTemp; + double Accum_Isqt; // Accumulated I2t + // ThermalConstant:Double; // Meaure of how fast heat can be conducted away + void Set_Ambient(double Value); + void Set_TCCname(const String Value); + std::string Get_TCCName(); + public: + bool Closed; // change this variable to indicate open or closed switch + bool FuseBlown; + void CalcIsqt(double CurrentMag); // Computes whether conductor has burned down + void ResetIsqt(); // restore the conductor and reset the i2t calcs + TConductor(); + virtual ~TConductor(); + }; + + + typedef std::vector pTConductorArray; + typedef std::vector TConductorArray; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Conductor; +#endif + +#endif // ConductorH + + + + + + + + + diff --git a/OpenDSSC/Common/ControlQueue.cpp b/OpenDSSC/Common/ControlQueue.cpp new file mode 100644 index 0000000..98c36bb --- /dev/null +++ b/OpenDSSC/Common/ControlQueue.cpp @@ -0,0 +1,549 @@ + + +#pragma hdrstop + +#include "ControlQueue.h" + + + +#include "DSSGlobals.h" +#include "Sysutils.h" +#include "Utilities.h" +#include "System.h" +#include +#include + +/* TControlQueue */ + +namespace ControlQueue +{ + + int TControlQueue::Push(const int Hour, const double Sec, const int Code, const int ProxyHdl, TControlElem* Owner, int ActorID) + { + int result = 0; + result = Push(Hour, Sec, (EControlAction) Code, ProxyHdl, Owner, ActorID); + return result; + } + + + int TControlQueue::Push(const int Hour, const double Sec, const EControlAction Code, const int ProxyHdl, TControlElem* Owner, int ActorID) + + /*Add a control action to the queue, sorted by lowest time first*/ + /*Returns handle to the action*/ + { + int result = 0; + int i = 0, Hr = 0; + double ThisActionTime = 0.0, S = 0.0; + TTimeRec Trec; + pActionRecord pAction = NULL; + bool ActionInserted = false; + ctrlHandle++; // just a serial number + + /*Normalize the time */ + Hr = Hour; + S = Sec; + if (S > 3600.0){ + do + { + Hr = Hr + 1; + S = S - 3600.0; + } while (!(S < 3600.0)); + } + Trec.Hour = Hr; + Trec.Sec = S; + ThisActionTime = TimeRecToTime(Trec); + pAction = new TActionRecord; // Make a new Action + + /*Insert the action in the list in order of time*/ + ActionInserted = false; + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + { + if (ThisActionTime <= TimeRecToTime(((pActionRecord)ActionList[i])->ActionTime)) + { + TList::iterator it; + it = ActionList.begin(); + it = ActionList.insert(it + i, pAction); + ActionInserted = true; + break; + } + } + if (!ActionInserted) + ActionList.push_back(pAction); + /*# with pAction^ do */ + { + pAction->ActionTime = Trec; + pAction->ActionCode = Code; + pAction->ActionHandle = ctrlHandle; + pAction->ProxyHandle = ProxyHdl; + pAction->ControlElement = Owner; + } + result = ctrlHandle; + if (DebugTrace) + WriteTraceRecord(((TDSSCktElement*)Owner)->get_Name(), Code, Owner->DblTraceParameter, Format("Handle %d Pushed onto Stack", ctrlHandle), ActorID); + return result; + } + + void TControlQueue::Clear() + { + int i = 0; + /*# with ActionList do */ /*Free Allocated memory*/ + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + free(ActionList[i]); + ActionList.clear(); + } + + + TControlQueue::TControlQueue() + : ActionList(TList()), + DebugTrace(false), + ctrlHandle(0) + { + // inherited::Create(); + ActionList.clear(); + ctrlHandle = 0; + DebugTrace = false; + } + + + TControlQueue::~TControlQueue() + { + Clear(); + ActionList.clear(); + // todo check: inherited::Destroy; + } + + + void TControlQueue::DoAllActions(int ActorID) + { + int i = 0; + /*# with ActionList do */ + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + /*# with pActionRecord(Items[i])^ do */ + { + TActionRecord* with0 = ((pActionRecord)ActionList[i]); + with0->ControlElement->DoPendingAction(with0->ActionCode, with0->ProxyHandle, ActorID); + } + ActionList.clear(); + } + + + bool TControlQueue::DoNearestActions(int& Hour, double& Sec, int ActorID) + + // Do only those actions with the same delay time as the first action time + // Return time + + { + bool result = false; + TControlElem* pElem; + TTimeRec t; + int Code = 0, Hdl = 0, ProxyHdl = 0; + result = false; + /*# with ActionList do */ + if (ActionList.size() > 0) + { + t = ((pActionRecord)ActionList[0])->ActionTime; + Hour = t.Hour; + Sec = t.Sec; + pElem = Pop(t, Code, ProxyHdl, Hdl, ActorID); + while (pElem != NULL) + { + if (DebugTrace) + WriteTraceRecord(pElem->get_Name(), Code, pElem->DblTraceParameter, Format("Pop Handle %d Do Nearest Action", Hdl), ActorID); + pElem->DoPendingAction(Code, ProxyHdl, ActorID); + result = true; + pElem = Pop(t, Code, ProxyHdl, Hdl, ActorID); + } + } + return result; + } + + + bool TControlQueue::IsEmpty() + { + bool result = false; + if (ActionList.empty()) + result = true; + else + result = false; + return result; + } + + + TControlElem* TControlQueue::Pop(const TTimeRec& ActionTime, int& Code, int& ProxyHdl, int& Hdl, int ActorID) + // pop off next control action with an action time <= ActionTime (sec) + + { + TControlElem* result; + int i = 0; + double t = 0.0; + result = NULL; + t = TimeRecToTime(ActionTime); + /*# with ActionList do */ + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + { + /*# with pActionRecord(Items[i])^ do */ + { + TActionRecord* with0 = ((pActionRecord)ActionList[i]); + if (TimeRecToTime(with0->ActionTime) <= t) + { + result = with0->ControlElement; + Code = with0->ActionCode; + ProxyHdl = with0->ProxyHandle; + Hdl = with0->ActionHandle; + DeleteFromQueue(i, true, ActorID); + break; + } + } + } + return result; + } + + TControlElem* TControlQueue::Pop_Time(const TTimeRec& ActionTime, int& Code, int& ProxyHdl, int& Hdl, double& ATime, bool KeepIn, int ActorID) // Pop action from queue <= given time + // pop off next control action with an action time <= ActionTime (sec) + + { + TControlElem* result; + int i = 0; + double t = 0.0; + result = NULL; + t = TimeRecToTime(ActionTime); + /*# with ActionList do */ + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + { + /*# with pActionRecord(Items[i])^ do */ + { + TActionRecord* with0 = ((pActionRecord)ActionList[i]); + if (TimeRecToTime(with0->ActionTime) <= t) + { + result = with0->ControlElement; + Code = with0->ActionCode; + ProxyHdl = with0->ProxyHandle; + Hdl = with0->ActionHandle; + ATime = TimeRecToTime(with0->ActionTime); + if (!KeepIn) + DeleteFromQueue(i, true, ActorID); + break; + } + } + } + return result; + } + + + void TControlQueue::DeleteFromQueue(int i, bool popped, int ActorID) + // Delete i-th element from the Queue + + { + TControlElem* pElem; + String S; + /*# with pActionRecord(ActionList.Items[i])^ do */ + { + TActionRecord* with0 = ((pActionRecord)ActionList[i]); + { + pElem = with0->ControlElement; + if (DebugTrace) + { + if (popped) + S = "by Pop function"; + else + S = "by control device"; + WriteTraceRecord(pElem->get_Name(), with0->ActionCode, pElem->DblTraceParameter, Format("Handle %d deleted from Queue ", with0->ActionHandle) + S, ActorID); + } + } + } + delete static_cast(ActionList[i]); + TList::iterator it2; + it2 = ActionList.begin(); + it2 = ActionList.erase(it2 + i); + } + + + bool TControlQueue::DoActions(const int Hour, const double Sec, int ActorID) + + // Do all actions having an action time <= t + + { + bool result = false; + TControlElem* pElem; + TTimeRec t; + int Code = 0, Hdl = 0, ProxyHdl = 0; + result = false; + if (ActionList.size() > 0) + { + t.Hour = Hour; + t.Sec = Sec; + pElem = Pop(t, Code, ProxyHdl, Hdl, ActorID); + while (pElem != NULL) + { + if (DebugTrace) + WriteTraceRecord(pElem->get_Name(), Code, pElem->DblTraceParameter, Format("Pop Handle %d Do Action", Hdl), ActorID); + pElem->DoPendingAction(Code, ProxyHdl, ActorID); + result = true; + pElem = Pop(t, Code, ProxyHdl, Hdl, ActorID); + } + } + return result; + } + + //----------------------------------------------------------------------------------------------------- + + bool TControlQueue::get_DebugTrace() + { + return DebugTrace; + } + + //----------------------------------------------------------------------------------------------------- + + bool TControlQueue::DoMultiRate(const int Hour, const double Sec, int ActorID) + + // Do all actions having an action time <= t and solves the circuit after each control action + + { + bool result = false; + TControlElem* pElem; + int Code = 0, Hdl = 0, ProxyHdl = 0, idx = 0; + result = false; + for (int stop = 1, idx = 0; idx <= stop; idx++) + Temp_Int[idx] = 0; // Temporary register for hour + for (int stop = 3, idx = 0; idx <= stop; idx++) + Temp_dbl[idx] = 0.0; + /* Temp_dbl[0] Temporary register for the secs + Temp_dbl[1] Temporary register for Time accumulator + Temp_dbl[2] Temporary register for Time upper boundary + Temp_dbl[3] Temporary register for the control action time */ + if (ActionList.size() > 0) + { + Ltimer.Hour = Hour; + Ltimer.Sec = Sec; + Temp_dbl[4] = ActiveCircuit[ActorID]->Solution->DynaVars.h; // Simulation step time (Time window size) + Temp_dbl[6] = TimeRecToTime(Ltimer); // Simulation step time incremental + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], false, ActorID); + while (pElem != NULL) + { + if (DebugTrace) + WriteTraceRecord(pElem->get_Name(), Code, pElem->DblTraceParameter, Format("Pop Handle %d Do Action", Hdl), ActorID); + pElem->DoPendingAction(Code, ProxyHdl, ActorID); + result = true; + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], false, ActorID); + } + //**************After this point, the additional control actions are performed************ + Temp_dbl[7] = ActiveCircuit[ActorID]->Solution->DynaVars.T; // Saving the current time (secs) + /*# with ActiveCircuit[ActorID]->Solution->DynaVars do */ + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + Temp_Int[2] = with0.intHour; // Saving the current time (hour) + Temp_dbl[2] = Temp_dbl[6]; + //*************** Simulation time is recalculated considering the next control action event ************ + Recalc_Time_Step(ActorID); + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], true, ActorID); // Downloads the next CtrlAction without + while (pElem != NULL) // removing it from the Queue + { + while (Temp_dbl[3] >= 3600.0) + Temp_dbl[3] = Temp_dbl[3] - 3600.0; // CtrlAction Time is adjusted + Temp_dbl[5] = (Temp_dbl[3] - Temp_dbl[6]) + Temp_dbl[1]; // Recalculates the CtrlAction occurrence time + if (Temp_dbl[5] < Temp_dbl[4]) // Checks if the CtrlAction is within the + { // time window + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], false, ActorID); // Removes the CtrlAction from The Queue + if (DebugTrace) + WriteTraceRecord(pElem->get_Name(), Code, pElem->DblTraceParameter, Format("Pop Handle %d Do Action", Hdl), ActorID); + pElem->DoPendingAction(Code, ProxyHdl, ActorID); + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], true, ActorID); // Downloads the next CtrlAction without + } // removing it from the Queue + else + { + pElem->DoPendingAction(Code, ProxyHdl, ActorID); // Executes the CtrlAction + pElem = NULL; // The next CtrlAction is outside the time window + Temp_Int[1] = 1; // Preparing everything to exit + } + if ((pElem == NULL) && (Temp_Int[1] == 0)) // The last CtrlAction was within the time + { // Time window, keep scanning + /*# with ActiveCircuit[ActorID]->Solution do */ + auto with1 = ActiveCircuit[ActorID]->Solution; + { + Temp_dbl[1] = Temp_dbl[1] + (Temp_dbl[3] - Temp_dbl[6]); // The Accumulated time is calculated + Temp_dbl[6] = Temp_dbl[6] + Temp_dbl[4]; // Time reference moves forward + while (Temp_dbl[6] >= 3600.0) + Temp_dbl[6] = Temp_dbl[6] - 3600.0;// Time reference is adjusted + //******************** Updates the circuit after applying the control actions ************************** + with1->SolveCircuit(ActorID); + Restore_Time_Step(ActorID); // Restores Time for sampling devices + with1->SampleControlDevices(ActorID); + Recalc_Time_Step(ActorID); // Recalculating Time for next iteration + pElem = Pop_Time(Ltimer, Code, ProxyHdl, Hdl, Temp_dbl[3], true, ActorID); // Downloads the next CtrlAction without + } // removing it from the Queue + } + } + Restore_Time_Step(ActorID); // Restores Time to keep going with the simulation + } + return result; + } + + + void TControlQueue::Recalc_Time_Step(int ActorID) + { + Temp_dbl[2] = Temp_dbl[2] + Temp_dbl[4]; // Time window moves forward + while (Temp_dbl[2] >= 3600.0) // Adjusts the window + { + Temp_Int[0]++; + Temp_dbl[2] = Temp_dbl[2] - 3600.0; + } + Ltimer.Hour = Temp_Int[0]; + Ltimer.Sec = Temp_dbl[2]; + /*# with ActiveCircuit[ActorID]->Solution->DynaVars do */ + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + with0.intHour = Temp_Int[0]; // Sets the simulation time + ActiveCircuit[ActorID]->Solution->DynaVars.T = Temp_dbl[2]; + ActiveCircuit[ActorID]->Solution->Update_dblHour(); + } + + + void TControlQueue::Restore_Time_Step(int ActorID) + { + /*# with ActiveCircuit[ActorID]->Solution->DynaVars do */ + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + with0.intHour = Temp_Int[2]; + ActiveCircuit[ActorID]->Solution->DynaVars.T = Temp_dbl[7]; + ActiveCircuit[ActorID]->Solution->Update_dblHour(); + } + + double TControlQueue::TimeRecToTime(TTimeRec Trec) + { + double result = 0.0; + /*# with Trec do */ + result = Trec.Hour * 3600.0 + Trec.Sec; + return result; + } + + + void TControlQueue::Set_Trace( bool Value) + { + DebugTrace = Value; + if (DebugTrace) + { + AssignFile(Tracefile, GetOutputDirectory() + "Trace_ControlQueue.CSV"); + Rewrite(Tracefile); + IOResultToException(); + WriteLn(Tracefile, "\"Hour\", \"sec\", \"Control Iteration\", \"Element\", \"Action Code\", \"Trace Parameter\", \"Description\""); + CloseFile(Tracefile); + } + } + + + void TControlQueue::ShowQueue(const String Filenm) + { + TTextRec F; + int i = 0; + pActionRecord pAction = NULL; + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + WriteLn(F, "Handle, Hour, Sec, ActionCode, ProxyDevRef, Device"); + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + { + pAction = (pActionRecord) ActionList[i]; + if (pAction != NULL) + /*# with pAction^ do */ + { + WriteLn(F, Format("%d, %d, %-1.0f, %d, %d, ", + pAction->ActionHandle, + pAction->ActionTime.Hour, + pAction->ActionTime.Sec, + pAction->ActionCode, + pAction->ProxyHandle) + + pAction->ControlElement->get_Name() + " "); + } + } +/* } + __finally + {*/ + CloseFile(F); + if (AutoDisplayShowReport) + FireOffEditor(Filenm); + } + catch (...) + { + // + } + } + + + void TControlQueue::WriteTraceRecord(const String ElementName, const int Code, double TraceParameter, const String S, int ActorID) + { + try + { + if (!InShowResults) + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile, Format("%d, %.6g, %d, ", + ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour, + ActiveCircuit[ActiveActor]->Solution->DynaVars.T, + ActiveCircuit[ActiveActor]->Solution->ControlIteration) + + ElementName + + Format(" % d, % -.g, % s", Code, TraceParameter) + + S); + CloseFile(Tracefile); + } + } + catch (std::exception &E) + { + { + } + } + } + + + void TControlQueue::Delete(int Hdl, int ActorID) + + /*Delete an item by its Handle reference*/ + { + int i = 0; + /*# with ActionList do */ + for (int stop = ActionList.size() - 1, i = 0; i <= stop; i++) + { + if (((pActionRecord)ActionList[i])->ActionHandle == Hdl) + { + DeleteFromQueue(i, false, ActorID); + return; + } + } + } + + + int TControlQueue::Get_QueueSize() + { + int result = 0; + result = ActionList.size(); + return result; + } + + + String TControlQueue::QueueItem(int Qidx) + { + String result; + pActionRecord pAction = NULL; + pAction = (pActionRecord) ActionList[Qidx]; + if (pAction != NULL) + /*# with pAction^ do */ + { + result = Format("%d, %d, %f, %d, %d, ", + pAction->ActionHandle, + pAction->ActionTime.Hour, + pAction->ActionTime.Sec, + pAction->ActionCode, + pAction->ProxyHandle) + pAction->ControlElement->get_Name() + " "; + } + else + result = ""; + return result; + } + + +}// namespace ControlQueue + + + + + + diff --git a/OpenDSSC/Common/ControlQueue.h b/OpenDSSC/Common/ControlQueue.h new file mode 100644 index 0000000..a3649e9 --- /dev/null +++ b/OpenDSSC/Common/ControlQueue.h @@ -0,0 +1,107 @@ +#ifndef ControlQueueH +#define ControlQueueH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 11-1-00 added Handle and delete function +*/ + +/*$M+*/ + + +#include "System.h" + +#include "Arraydef.h" +#include "ControlElem.h" +#include "ControlActionsDefs.h" + +namespace ControlQueue +{ + + + struct TActionRecord; + class TControlQueue; + struct TTimeRec; + + + + + struct TTimeRec { + int Hour; + double Sec; + }; + + + typedef TActionRecord* pActionRecord; + + struct TActionRecord { + TTimeRec ActionTime; + int ActionCode; + int ActionHandle; + int ProxyHandle; + TControlElem* ControlElement; + }; + + + class TControlQueue : public TObject { + typedef TObject inherited; + public: +// private: + TList ActionList; + bool DebugTrace; + TTextRec Tracefile; + int ctrlHandle; + int Temp_Int[4/*# range 0..3*/]; // Temporary registers, Int Type + double Temp_dbl[8/*# range 0..7*/]; // Temporary registers, dbl type + TTimeRec Ltimer; + TControlElem* Pop(const TTimeRec& ActionTime, int& Code, int& ProxyHdl, int& Hdl, int ActorID); // Pop action from queue <= given time + TControlElem* Pop_Time(const TTimeRec& ActionTime, int& Code, int& ProxyHdl, int& Hdl, double& ATime, bool KeepIn, int ActorID); // Pop action from queue <= given time + void DeleteFromQueue(int i, bool popped, int ActorID); + double TimeRecToTime(TTimeRec Trec); + void Set_Trace( bool Value); + void WriteTraceRecord(const String ElementName, const int Code, double TraceParameter, const String S, int ActorID); + int Get_QueueSize(); + void Recalc_Time_Step(int ActorID); + void Restore_Time_Step(int ActorID); + public: + TControlQueue(); + virtual ~TControlQueue(); + int Push(const int Hour, const double Sec, const int Code, const int ProxyHdl, TControlElem* Owner, int ActorID) /*# overload */; + int Push(const int Hour, const double Sec, const EControlAction Code, const int ProxyHdl, TControlElem* Owner, int ActorID) /*# overload */; + // int Push( const int Hour, const double Sec, const EControlAction Code, const int ProxyHdl, const TControlElem Owner, int ActorID ) /*# overload */; + void Clear(); + void DoAllActions(int ActorID); + bool DoNearestActions(int& Hour, double& Sec, int ActorID); // Do only actions with lowest time + bool DoActions(const int Hour, const double Sec, int ActorID); // Do actions with time <= t + bool DoMultiRate(const int Hour, const double Sec, int ActorID); // Do actions with time <= t + bool IsEmpty(); + void Delete(int Hdl, int ActorID); // Delete queue item by handle + void ShowQueue(const String Filenm); + + bool get_DebugTrace(); + + String QueueItem(int Qidx); + }; + + +} // namespace ControlQueue + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ControlQueue; +#endif + +#endif // ControlQueueH + + + + + + + + + diff --git a/OpenDSSC/Common/DSSCallBackRoutines.cpp b/OpenDSSC/Common/DSSCallBackRoutines.cpp new file mode 100644 index 0000000..c43529d --- /dev/null +++ b/OpenDSSC/Common/DSSCallBackRoutines.cpp @@ -0,0 +1,590 @@ + +#pragma hdrstop + +#include "DSSCallBackRoutines.h" + + + +#include "ParserDel.h" +#include "DSSGlobals.h" +#include "Executive.h" +#include "Sysutils.h" +#include "CktElement.h" +#include +#include "PDElement.h" + +#include "System.h" + + +typedef unsigned int unsignedint; + + + + +TDSSCallBacks CallBackRoutines; + + + +TParser CallBackParser; +String CB_ParamName, CB_Param; + +/*====================================================================================================================*/ + + +void __stdcall DoSimpleMsgCallback( char* S, unsignedint maxlen ) // Call back for user-written models + +{ + DoSimpleMsg( ((String) S ), 9000 ); +} + + /*These routines should work well with Fortran as well as C and VB*/ +void __stdcall DoSimpleMsgCallback() // Call back for user-written models +{ + +} + +/*====================================================================================================================*/ + + +void __stdcall ParserLoad( char* S, unsignedint maxlen ) +{ + CallBackParser.SetCmdString((String) S ); +} + +/*====================================================================================================================*/ + + +void __stdcall ParserIntValue( int& i ) +{ + /*# with CallBackParser do */ + { + i = CallBackParser.MakeInteger_(); + } +} + + +/*====================================================================================================================*/ + + +void __stdcall ParserDblValue( double& x ) +{ + /*# with CallBackParser do */ + { + x = CallBackParser.MakeDouble_(); + } +} + +/*====================================================================================================================*/ + + +void __stdcall ParserStrValue( char* S, unsignedint maxlen ) + +/*Copies null-terminated string into location pointed to by S up to the max chars specified*/ +{ + /*# with CallBackParser do */ + { + S = new char[maxlen + 1]; + StrLCopy( S, ((AnsiString) CB_Param ).c_str(), maxlen ); + S[maxlen] = 0; + } +} + +/*====================================================================================================================*/ + + +int __stdcall ParserNextParam( char* ParamName, unsignedint maxlen ) +{ + int result = 0; + /*# with CallBackParser do */ + { + CB_ParamName = CallBackParser.GetNextParam(); + CB_Param = CallBackParser.MakeString_(); + } + StrLCopy( ParamName, ((AnsiString) CB_ParamName ).c_str(), maxlen ); // Copies up to Maxlen + result = CB_Param.size( ); + return result; +} + +/*====================================================================================================================*/ + + +void __stdcall DoDSSCommandCallBack( char* S, unsignedint maxlen ) +{ + SolutionAbort = false; + DSSExecutive[ActiveActor]->Set_Command( (String) S ); +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementBusNamesCallBack( char* Name1, unsignedint Len1, char* Name2, unsignedint Len2 ) + /*Get first two bus names of active Circuit Element for labeling graphs, etc.*/ + /*Coordinate must be defined else returns null string*/ +{ + int BusIdx = 0; + StrLCopy( Name1, ( PAnsiChar ) ( "" ), Len1 ); // Initialize to null + StrLCopy( Name2, ( PAnsiChar ) ( "" ), Len2 ); + if ( ActiveCircuit[ActiveActor] != NULL ) + { + if ( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) + { + TDSSCktElement &CktElement = *(ActiveCircuit[ActiveActor]->get_FActiveCktElement()); + /*First bus*/ + BusIdx = CktElement.Terminals[1 - 1].BusRef; + if ( BusIdx > 0 ) + /*# with ActiveCircuit[ActiveActor]->Buses^[BusIdx] do */ + + if (ActiveCircuit[ActiveActor]->Buses[BusIdx - 1]->CoordDefined ) + StrLCopy( Name1, ((AnsiString) ActiveCircuit[ActiveActor]->BusList.Get( BusIdx ) ).c_str(), Len1 ); + /*Second bus*/ + BusIdx = CktElement.Terminals[2 - 1].BusRef; + if ( BusIdx > 0 ) + /*# with ActiveCircuit[ActiveActor]->Buses^[BusIdx] do */ + if (ActiveCircuit[ActiveActor]->Buses[BusIdx - 1]->CoordDefined ) + StrLCopy( Name2, ((AnsiString) ActiveCircuit[ActiveActor]->BusList.Get( BusIdx ) ).c_str(), Len2 ); + } + } /*If ActiveCircuit[ActiveActor]*/ +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementVoltagesCallBack( int& NumVoltages, pComplexArray V ) +/*NumVoltages is size of the V buffer*/ +{ + int i = 0, j = 0; + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + /*# with ActiveCktElement do */ + auto with1 = with0->get_FActiveCktElement(); + { + NumVoltages = min( with1->Yorder, NumVoltages ); // reset buffer size + for ( int stop = NumVoltages, i = 1; i <= stop; i++) + { + if ( (!ADiakoptics) || (ActiveActor == 1) ) + (V)[i - 1] = with0->Solution->NodeV[with1->NodeRef[i - 1]]; + else + (V)[i - 1] = with0->Solution->VoltInActor1( with1->NodeRef[i - 1] ); + } + } + } + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementCurrentsCallBack( int& NumCurrents, pComplexArray Curr, int ActorID ) +{ + int i = 0; + if (( ActiveCircuit[ActorID]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + /*# with ActiveCktElement do */ + { + auto with1 = with0->get_FActiveCktElement(); + with1->ComputeIterminal( ActorID ); + NumCurrents = min( with1->Yorder, NumCurrents ); // Reset to actual number of elements returned + for ( int stop = NumCurrents, i = 1; i <= stop; i++) + Curr[i - 1] = with1->Iterminal[i - 1]; + } + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementLossesCallBack( complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID ) +{ + TotalLosses = CZero; + LoadLosses = CZero; + NoLoadLosses = CZero; + if (( ActiveCircuit[ActorID]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + /*# with ActiveCktElement do */ + { + with0->get_FActiveCktElement()->GetLosses( TotalLosses, LoadLosses, NoLoadLosses, ActorID ); + } + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementPowerCallBack( int Terminal, complex& TotalPower ) +{ + TotalPower = CZero; + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + /*# with ActiveCktElement do */ + { + //----ActiveTerminalIdx := Terminal; + TotalPower = with0->get_FActiveCktElement()->Get_Power(Terminal, ActiveActor); + } + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementNumCustCallBack( int& Numcust, int& TotalCust ) +{ + TPDElement PDElem; + Numcust = 0; + TotalCust = 0; + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + if ( dynamic_cast< TPDElement* >( ActiveCircuit[ActiveActor]->get_FActiveCktElement() ) ) + { + PDElem = *( ( TPDElement* ) ActiveCircuit[ActiveActor]->get_FActiveCktElement() ); + Numcust = PDElem.BranchNumCustomers; + TotalCust = PDElem.BranchTotalCustomers; + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementNodeRefCallBack( int Maxsize, pIntegerArray NodeReferenceArray )// calling program must allocate + +{ + int i = 0; + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + /*# with ActiveCktElement do */ + { + auto with1 = with0->get_FActiveCktElement(); + for ( int stop = min( with1->Yorder, Maxsize ), i = 1; i <= stop; i++) + NodeReferenceArray[i - 1] = with1->NodeRef[i - 1]; + } + } +} + +/*====================================================================================================================*/ + + +int __stdcall GetActiveElementBusRefCallBack( int Terminal ) +{ + int result = 0; + result = 0; + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + /*# with ActiveCktElement do */ + { + result = with0->get_FActiveCktElement()->Terminals[Terminal - 1].BusRef; + } + } + return result; +} + +/*====================================================================================================================*/ + + +void __stdcall GetActiveElementTerminalInfoCallBack( int& NumTerminals, int& NumConds, int& NumPhases ) +{ + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + /*# with ActiveCktElement do */ + { + NumTerminals = with0->get_FActiveCktElement()->Get_NTerms(); + NumConds = with0->get_FActiveCktElement()->Get_NConds(); + NumPhases = with0->get_FActiveCktElement()->Get_NPhases(); + } + } +} + +/*====================================================================================================================*/ + + +void __stdcall GetPtrToSystemVarrayCallBack( void*& V, int& iNumNodes ) // Returns pointer to Solution.V and size + +{ + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + /*# with ActiveCktElement do */ + { + V = &(with0->Solution->NodeV[0]); // Return Pointer to Node Voltage array + iNumNodes = with0->NumNodes; + } + } +} + +/*====================================================================================================================*/ + + +int __stdcall GetActiveElementIndexCallBack( ) + /*Usually just checking to see if this result >0*/ +{ + int result = 0; + result = 0; + if (( ActiveCircuit[ActiveActor] != NULL ) ) + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + result = ( (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement() )->ClassIndex; + return result; +} + +/*====================================================================================================================*/ + + +bool __stdcall IsActiveElementEnabledCallBack( ) +{ + bool result = false; + result = false; + if (( ActiveCircuit[ActiveActor] != NULL ) ) + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + result = ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Get_Enabled(); + return result; +} + +/*====================================================================================================================*/ + + +bool __stdcall IsBusCoordinateDefinedCallback( int BusRef, int ActorID ) +{ + bool result = false; + result = false; + if (( ActiveCircuit[ActorID] != NULL ) && ( BusRef > 0 ) ) + result = ActiveCircuit[ActorID]->Buses[BusRef - 1]->CoordDefined; + return result; +} + +/*====================================================================================================================*/ + + +void __stdcall GetBusCoordinateCallback( int BusRef, double& x, double& y, int ActorID ) +{ + x = 0.0; + y = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) && ( BusRef > 0 ) ) + { + x = ActiveCircuit[ActorID]->Buses[BusRef - 1]->x; + y = ActiveCircuit[ActorID]->Buses[BusRef - 1]->y; + } +} + +/*====================================================================================================================*/ + + +double __stdcall GetBuskVBaseCallback( int BusRef, int ActorID ) +{ + double result = 0.0; + result = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) && ( BusRef > 0 ) ) + { + result = ActiveCircuit[ActorID]->Buses[BusRef - 1]->kVBase; + } + return result; +} + +/*====================================================================================================================*/ + + +double __stdcall GetBusDistFromMeterCallback( int BusRef, int ActorID ) +{ + double result = 0.0; + result = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) && ( BusRef > 0 ) ) + { + result = ActiveCircuit[ActorID]->Buses[BusRef - 1]->DistFromMeter; + } + return result; +} + +/*====================================================================================================================*/ + + +void __stdcall GetDynamicsStructCallBack( void*& DynamicsStruct, int ActorID ) +{ + if (( ActiveCircuit[ActorID] != NULL ) ) + { + DynamicsStruct = &ActiveCircuit[ActorID]->Solution->DynaVars; + } +} + +/*====================================================================================================================*/ + + +double __stdcall GetStepSizeCallBack( int ActorID ) +{ + double result = 0.0; + result = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) ) + { + result = ActiveCircuit[ActorID]->Solution->DynaVars.h; + } + return result; +} + +/*====================================================================================================================*/ + + +double __stdcall GetTimeSecCallBack( int ActorID ) +{ + double result = 0.0; + result = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) ) + { + result = ActiveCircuit[ActorID]->Solution->DynaVars.T; + } + return result; +} + +/*====================================================================================================================*/ + + +double __stdcall GetTimeHrCallBack( int ActorID ) +{ + double result = 0.0; + result = 0.0; + if (( ActiveCircuit[ActorID] != NULL ) ) + { + result = ActiveCircuit[ActorID]->Solution->DynaVars.dblHour; + } + return result; +} + +/*====================================================================================================================*/ + + +void __stdcall GetPublicDataPtrCallBack( void*& pPublicData, int& PublicDataBytes, int ActorID ) +{ + if (( ActiveCircuit[ActorID]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + /*# with ActiveCktElement do */ + { + pPublicData = with0->get_FActiveCktElement()->PublicDataStruct; + PublicDataBytes = with0->get_FActiveCktElement()->PublicDataSize; + } + } +} + + +int __stdcall GetActiveElementNameCallBack( char* FullName, unsignedint maxlen, int ActorID ) +/*Maxlen is num of chars the calling program allocates for the string*/ +{ + int result = 0; + String S; + result = 0; + if (( ActiveCircuit[ActorID]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + /*# with ActiveCktElement do */ + { + S = ( (TDSSObject*) with0->get_FActiveCktElement() )->ParentClass->get_myClass_name() + "." + ((TDSSObject*)with0->get_FActiveCktElement())->get_Name(); + StrLCopy( FullName, ((AnsiString) S ).c_str(), maxlen ); + result = maxlen; + } + } + return result; +} + + +void* __stdcall GetActiveElementPtrCallBack( int ActorID ) // Returns pointer to active circuit element + +{ + void* result = NULL; + result = ((void*) ActiveCircuit[ActorID]->get_FActiveCktElement() ); + return result; +} + + +int __stdcall ControlQueuePushCallBack( const int Hour, const double Sec, const int Code, const int ProxyHdl, void* Owner, int ActorID ) +{ + int result = 0; + result = ActiveCircuit[ActorID]->ControlQueue.Push( Hour, Sec, (EControlAction) Code, ProxyHdl, (TControlElem*) Owner, ActorID ); + return result; +} + + +void __stdcall GetResultStrCallBack( char* S, unsignedint maxlen ) +{ + StrLCopy( S, ((AnsiString) GlobalResult ).c_str(), maxlen ); +} + +/*====================================================================================================================*/ + +/*Initialize Function Interface variables for user-Written Callbacks*/ + +void DSSCallBackRoutines_initialization() +{ + /*# with CallBackRoutines do */ + { + auto &with0 = CallBackRoutines; + //with0.MsgCallBack = (void*);// &((int)DoSimpleMsgCallback()); // for user-written callbacks + with0.GetIntValue = ParserIntValue; + with0.GetDblValue = ParserDblValue; + with0.GetStrValue = ParserStrValue; + with0.LoadParser = ParserLoad; + with0.NextParam = ParserNextParam; + with0.DoDSSCommand = DoDSSCommandCallBack; + with0.GetActiveElementBusNames = GetActiveElementBusNamesCallBack; + with0.GetActiveElementVoltages = GetActiveElementVoltagesCallBack; + with0.GetActiveElementCurrents = GetActiveElementCurrentsCallBack; + with0.GetActiveElementLosses = GetActiveElementLossesCallBack; + with0.GetActiveElementPower = GetActiveElementPowerCallBack; + with0.GetActiveElementNumCust = GetActiveElementNumCustCallBack; + with0.GetActiveElementNodeRef = GetActiveElementNodeRefCallBack; + with0.GetActiveElementBusRef = GetActiveElementBusRefCallBack; + with0.GetActiveElementTerminalInfo = GetActiveElementTerminalInfoCallBack; + with0.GetPtrToSystemVarray = GetPtrToSystemVarrayCallBack; + with0.GetActiveElementIndex = GetActiveElementIndexCallBack; + with0.IsActiveElementEnabled = IsActiveElementEnabledCallBack; + with0.IsBusCoordinateDefined = IsBusCoordinateDefinedCallback; + with0.GetBusCoordinate = GetBusCoordinateCallback; + with0.GetBuskVBase = GetBuskVBaseCallback; + with0.GetBusDistFromMeter = GetBusDistFromMeterCallback; + + // Added 4-9-2012 + with0.GetDynamicsStruct = GetDynamicsStructCallBack; + with0.GetStepSize = GetStepSizeCallBack; + with0.GetTimeSec = GetTimeSecCallBack; + with0.GetTimeHr = GetTimeHrCallBack; + with0.GetPublicDataPtr = GetPublicDataPtrCallBack; + with0.GetActiveElementName = GetActiveElementNameCallBack; + with0.GetActiveElementPtr = GetActiveElementPtrCallBack; + with0.ControlQueuePush = ControlQueuePushCallBack; + with0.GetResultStr = GetResultStrCallBack; + } +/*====================================================================================================================*/ +} + +void DSSCallBackRoutines_finalization() +{ +} + +class DSSCallBackRoutines_unit +{ +public: +DSSCallBackRoutines_unit() +{ + DSSCallBackRoutines_initialization(); +} +~DSSCallBackRoutines_unit(){ DSSCallBackRoutines_finalization(); } +}; +DSSCallBackRoutines_unit _DSSCallBackRoutines_unit; + + + + + + + + diff --git a/OpenDSSC/Common/DSSCallBackRoutines.h b/OpenDSSC/Common/DSSCallBackRoutines.h new file mode 100644 index 0000000..9eb34a6 --- /dev/null +++ b/OpenDSSC/Common/DSSCallBackRoutines.h @@ -0,0 +1,32 @@ +#ifndef DSSCallBackRoutinesH +#define DSSCallBackRoutinesH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +#include "System.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "DSSCallBackStructDef.h" + + + +typedef unsigned int unsignedint; + + +extern TDSSCallBacks CallBackRoutines; +void __stdcall DoSimpleMsgCallback( char* S, unsignedint maxlen ); // Call back for user-written models + +#endif // DSSCallBackRoutinesH + + + + + + + + diff --git a/OpenDSSC/Common/DSSCallBackStructDef.cpp b/OpenDSSC/Common/DSSCallBackStructDef.cpp new file mode 100644 index 0000000..c5f2262 --- /dev/null +++ b/OpenDSSC/Common/DSSCallBackStructDef.cpp @@ -0,0 +1,58 @@ + + + +#include "DSSCallBackStructDef.h" + +#pragma pack(push, 1) + +void (*MsgCallBack)(pUTF8Char S, unsignedint maxlen); /*Make use of DSS Message handling*/ + + /*Routines for using DSS Parser. This allows you to write models that accept + syntax like other DSS scripts.*/ +void (*GetIntValue)(int& i); /*Get next param as an integer*/ +void (*GetDblValue)(double& x); /*Get next param as a double*/ +void (*GetStrValue)(pUTF8Char S, unsignedint maxlen); +/*Get next param as a string <= maxlen characters (Cardinal = 32-bit unsigned)*/ +/*caller must allocate space for s (Maxlen chars)*/ +void (*LoadParser)(pUTF8Char S, unsignedint maxlen); // Copies a string into a special instance of the DSS parser +int (*NextParam)(pUTF8Char ParamName, unsignedint maxlen); +/*Advance to the next parameter and + Get name of the param just retrieved, if one was given. + Returns length of parameter found. If 0, then end of string. + This is to handle the syntax "paramname=paramvalue" commonly used in DSS scripts + Copies the string to the location specified by s up to maxlen characters. + Caller must allocate space (Maxlen chars)*/ +void (*DoDSSCommand)(pUTF8Char S, unsignedint maxlen); +void (*GetActiveElementBusNames)(pUTF8Char Name1, unsignedint Len1, pUTF8Char Name2, unsignedint Len2); +void (*GetActiveElementVoltages)(int& NumVoltages, pComplexArray V); +void (*GetActiveElementCurrents)(int& NumCurrents, pComplexArray Curr, int ActorID); +void (*GetActiveElementLosses)(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID); +void (*GetActiveElementPower)(int Terminal, complex& TotalPower); +void (*GetActiveElementNumCust)(int& Numcust, int& TotalCust); +void (*GetActiveElementNodeRef)(int Maxsize, pIntegerArray NodeReferenceArray);// calling program must allocate +int (*GetActiveElementBusRef)(int Terminal); +void (*GetActiveElementTerminalInfo)(int& NumTerminals, int& NumConds, int& NumPhases); +void (*GetPtrToSystemVarray)(void*& V, int& iNumNodes); // Returns pointer to Solution.V and size +int (*GetActiveElementIndex)(); +bool (*IsActiveElementEnabled)(); +bool (*IsBusCoordinateDefined)(int BusRef, int ActorID); +void (*GetBusCoordinate)(int BusRef, double& x, double& y, int ActorID); +double (*GetBuskVBase)(int BusRef, int ActorID); +double (*GetBusDistFromMeter)(int BusRef, int ActorID); +void (*GetDynamicsStruct)(void*& pDynamicsStruct, int ActorID); // Returns pointer to dynamics variables structure +double (*GetStepSize)(int ActorID); // Return just 'h' from dynamics record +double (*GetTimeSec)(int ActorID); // returns t in sec from top of hour +double (*GetTimeHr)(int ActorID); // returns time as a double in hours +void (*GetPublicDataPtr)(void*& pPublicData, int& PublicDataBytes, int ActorID); +int (*GetActiveElementName)(pUTF8Char FullName, unsignedint MaxNameLen, int ActorID); +void* (*GetActiveElementPtr)(int ActorID); // Returns pointer to active circuit element +int (*ControlQueuePush)(const int Hour, const double Sec, const int Code, const int ProxyHdl, void* Owner, int ActorID); +void (*GetResultStr)(pUTF8Char S, unsignedint maxlen); + + + + + + + + diff --git a/OpenDSSC/Common/DSSCallBackStructDef.h b/OpenDSSC/Common/DSSCallBackStructDef.h new file mode 100644 index 0000000..512c763 --- /dev/null +++ b/OpenDSSC/Common/DSSCallBackStructDef.h @@ -0,0 +1,59 @@ +#ifndef DSSCALLBACKSTRUCTDEFH +#define DSSCALLBACKSTRUCTDEFH + + +#include "System.h" +#include "d2c_structures.h" + +struct TDSSCallBacks { + void (__stdcall *MsgCallBack)(pUTF8Char S, unsignedint maxlen); /*Make use of DSS Message handling*/ + + /*Routines for using DSS Parser. This allows you to write models that accept + syntax like other DSS scripts.*/ + void (__stdcall *GetIntValue)(int& i); /*Get next param as an integer*/ + void (__stdcall *GetDblValue)(double& x); /*Get next param as a double*/ + void (__stdcall *GetStrValue)(pUTF8Char S, unsignedint maxlen); + /*Get next param as a string <= maxlen characters (Cardinal = 32-bit unsigned)*/ + /*caller must allocate space for s (Maxlen chars)*/ + void (__stdcall *LoadParser)(pUTF8Char S, unsignedint maxlen); // Copies a string into a special instance of the DSS parser + int (__stdcall *NextParam)(pUTF8Char ParamName, unsignedint maxlen); + /*Advance to the next parameter and + Get name of the param just retrieved, if one was given. + Returns length of parameter found. If 0, then end of string. + This is to handle the syntax "paramname=paramvalue" commonly used in DSS scripts + Copies the string to the location specified by s up to maxlen characters. + Caller must allocate space (Maxlen chars)*/ + void (__stdcall *DoDSSCommand)(pUTF8Char S, unsignedint maxlen); + void (__stdcall *GetActiveElementBusNames)(pUTF8Char Name1, unsignedint Len1, pUTF8Char Name2, unsignedint Len2); + void (__stdcall *GetActiveElementVoltages)(int& NumVoltages, pComplexArray V); + void (__stdcall *GetActiveElementCurrents)(int& NumCurrents, pComplexArray Curr, int ActorID); + void (__stdcall *GetActiveElementLosses)(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID); + void (__stdcall *GetActiveElementPower)(int Terminal, complex& TotalPower); + void (__stdcall *GetActiveElementNumCust)(int& Numcust, int& TotalCust); + void (__stdcall *GetActiveElementNodeRef)(int Maxsize, pIntegerArray NodeReferenceArray);// calling program must allocate + int (__stdcall *GetActiveElementBusRef)(int Terminal); + void (__stdcall *GetActiveElementTerminalInfo)(int& NumTerminals, int& NumConds, int& NumPhases); + void (__stdcall *GetPtrToSystemVarray)(void*& V, int& iNumNodes); // Returns pointer to Solution.V and size + int (__stdcall *GetActiveElementIndex)(); + bool (__stdcall *IsActiveElementEnabled)(); + bool (__stdcall *IsBusCoordinateDefined)(int BusRef, int ActorID); + void (__stdcall *GetBusCoordinate)(int BusRef, double& x, double& y, int ActorID); + double (__stdcall *GetBuskVBase)(int BusRef, int ActorID); + double (__stdcall *GetBusDistFromMeter)(int BusRef, int ActorID); + void (__stdcall *GetDynamicsStruct)(void*& pDynamicsStruct, int ActorID); // Returns pointer to dynamics variables structure + double (__stdcall *GetStepSize)(int ActorID); // Return just 'h' from dynamics record + double (__stdcall *GetTimeSec)(int ActorID); // returns t in sec from top of hour + double (__stdcall *GetTimeHr)(int ActorID); // returns time as a double in hours + void (__stdcall *GetPublicDataPtr)(void*& pPublicData, int& PublicDataBytes, int ActorID); + int (__stdcall *GetActiveElementName)(pUTF8Char FullName, unsignedint MaxNameLen, int ActorID); + void* (__stdcall *GetActiveElementPtr)(int ActorID); // Returns pointer to active circuit element + int (__stdcall *ControlQueuePush)(const int Hour, const double Sec, const int Code, const int ProxyHdl, void* Owner, int ActorID); + void (__stdcall *GetResultStr)(pUTF8Char S, unsignedint maxlen); +}; + +/*NOTE: Maxlen argument is to better accommodate Fortran strings. VB also*/ +/* Caller must allocate space for pchar values */ +typedef TDSSCallBacks* pDSSCallBacks; /*Pointer to callback structure*/ + +#endif // DSSCALLBACKSTRUCTDEFH + diff --git a/OpenDSSC/Common/DSSClass.cpp b/OpenDSSC/Common/DSSClass.cpp new file mode 100644 index 0000000..2369814 --- /dev/null +++ b/OpenDSSC/Common/DSSClass.cpp @@ -0,0 +1,395 @@ + + +#pragma hdrstop + +#include "DSSClass.h" + +#include "DSSObject.h" +#include "CktElement.h" +#include "DSSGlobals.h" + + +namespace DSSClass +{ + + + /*--------------------------------------------------------------*/ + /* DSSClasses Implementation + {--------------------------------------------------------------*/ + + + + //TDSSClasses::TDSSClasses() {}; + + TDSSClasses::TDSSClasses() + { + //inherited(); + } + + /*--------------------------------------------------------------*/ + + TDSSClasses::~TDSSClasses() + { + // todo check: inherited::Destroy; + } + + /*--------------------------------------------------------------*/ + + + + void TDSSClasses::Set_New(void* Value) + { + DSSClassList[ActiveActor].Set_New(Value); // Add to pointer list + ActiveDSSClass[ActiveActor] = (TDSSClass*)Value; // Declare to be active + ClassNames[ActiveActor].Add(ActiveDSSClass[ActiveActor]->get_myClass_name()); // Add to classname list + } + + + /*--------------------------------------------------------------*/ + /* DSSClass Implementation + {--------------------------------------------------------------*/ + + + TDSSClass::TDSSClass() + : ElementNameList(THashList(100)), + ElementList(TPointerList(20)) + { + ActiveElement = 0; + ActiveProperty = 0; + NumProperties = 0; + DSSClassType = 0; + ElementNamesOutOfSynch = false; + Saved = false; + + // inherited::Create(); + PropertyName = NULL; + PropertyHelp = NULL; + PropertyIdxMap = NULL; + RevPropertyIdxMap = NULL; + ActiveElement = 0; + ActiveProperty = 0; + + ElementNamesOutOfSynch = false; + } + + /*--------------------------------------------------------------*/ + + + TDSSClass::~TDSSClass() + { + int i = 0; + // Get rid of space occupied by strings + /*for (int stop = NumProperties, i = 1; i <= stop; i++) + PropertyName[i] = ""; + for (int stop = NumProperties, i = 1; i <= stop; i++) + PropertyHelp[i] = ""; + delete[] PropertyName; + delete[] PropertyHelp; + delete[] PropertyIdxMap; + delete[] RevPropertyIdxMap; */ + // todo check: inherited::Destroy; + } + + + /*--------------------------------------------------------------*/ + + int TDSSClass::get_ActiveElement() + { + return ActiveElement; + } + + /*--------------------------------------------------------------*/ + + int TDSSClass::NewObject(std::string ObjName) + { + int result = 0; + result = 0; + DoErrorMsg(String("Reached base class of TDSSClass for device \"") + ObjName + "\"", "N/A", "Should be overridden.", 780); + return result; + } + + + void TDSSClass::Set_Active(int Value) + { + if ((Value > 0) && (Value <= ElementList.get_myNumList())) + { + ActiveElement = Value; + ActiveDSSObject[ActiveActor] = ElementList.Get(ActiveElement); + // Make sure Active Ckt Element agrees if is a ckt element + // So COM interface will work + if (dynamic_cast((TDSSObject*)ActiveDSSObject[ActiveActor]) != nullptr) + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)ActiveDSSObject[ActiveActor]); + } + } + + + int TDSSClass::Edit(int ActorID) + { + int result = 0; + result = 0; + DoSimpleMsg("virtual function TDSSClass.Edit called. Should be overriden.", 781); + return result; + } + + + int TDSSClass::Init(int Handle, int ActorID) + { + int result = 0; + result = 0; + DoSimpleMsg("virtual function TDSSClass.Init called. Should be overriden.", 782); + return result; + } + + + int TDSSClass::AddObjectToList(void* Obj) + { + int result = 0; + ElementList.Set_New(Obj); // Stuff it in this collection's element list + ElementNameList.Add(((TDSSObject*)Obj)->get_Name()); + if (((unsigned int)ElementList.get_myNumList()) > 2 * ElementNameList.InitialAllocation) + ReallocateElementNameList(); + ActiveElement = ElementList.get_myNumList(); + result = ActiveElement; // Return index of object in list + return result; + } + + + bool TDSSClass::SetActive(string ObjName) + { + bool result = false; + int idx = 0; + result = false; + // Faster to look in hash list 7/7/03 + if (ElementNamesOutOfSynch) + ResynchElementNameList(); + idx = ElementNameList.Find(ObjName); + if (idx > 0) + { + ActiveElement = idx; + ActiveDSSObject[ActiveActor] = ElementList.Get(idx); + result = true; + } + return result; + } + + + void* TDSSClass::Find(string ObjName) + { + void* result = NULL; + int idx = 0; + result = NULL; + if (ElementNamesOutOfSynch) + ResynchElementNameList(); + // Faster to look in hash list 7/7/03 + idx = ElementNameList.Find(ObjName); + if (idx > 0) + { + ActiveElement = idx; + result = ElementList.Get(idx); + } + return result; + } + + + void* TDSSClass::GetActiveObj() // Get address of active obj of this class + + { + void* result = NULL; + ActiveElement = ElementList.get_myActiveItem(); + if (ActiveElement > 0) + result = ElementList.Get(ActiveElement); + else + result = NULL; + return result; + } + + String TDSSClass::Get_FirstPropertyName() + { + String result; + ActiveProperty = 0; + result = Get_NextPropertyName(); + return result; + } + + + String TDSSClass::Get_NextPropertyName() + { + String result; + ActiveProperty++; + if (ActiveProperty <= NumProperties) + result = PropertyName[ActiveProperty]; + else + result = ""; + return result; + } + + string TDSSClass::get_myClass_name() + { + return Class_Name; + } + + + int TDSSClass::PropertyIndex(string Prop) + // find property value by string + + { + int result = 0; // Default result if not found + int i = 0; + + for (i = 0; i < NumProperties; i++) + { + if (CompareText(Prop, PropertyName[i]) == 0) + { + result = PropertyIdxMap[i]; + break; + } + } + return result; + } + + + void TDSSClass::CountProperties() + { + NumProperties = NumProperties + 1; + } + + + void TDSSClass::DefineProperties() + { + ActiveProperty = ActiveProperty + 1; + PropertyName[ActiveProperty] = "like"; + PropertyHelp[ActiveProperty] = "Make like another object, e.g.:" + CRLF + CRLF + "New Capacitor.C2 like=c1 ..."; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + int TDSSClass::ClassEdit(const void* ActiveObj, const int ParamPointer) + { + int result = 0; + // continue parsing with contents of Parser + result = 0; + if (ParamPointer > 0) + /*# with TDSSObject(ActiveObj) do */ + { + const TDSSObject& with0 = *(TDSSObject*)ActiveObj; + { + switch (ParamPointer) + { + case 1: + MakeLike(Parser[ActiveActor]->MakeString_()); + break; // Like command (virtual) + } + } + } + return result; + } + + + int TDSSClass::MakeLike(string ObjName) + { + int result = 0; + result = 0; + DoSimpleMsg("virtual function TDSSClass.MakeLike called. Should be overriden.", 784); + return result; + } + + + int TDSSClass::Get_ElementCount() + { + int result = 0; + result = ElementList.get_myNumList(); + return result; + } + + + int TDSSClass::Get_First() + { + int result = 0; + if (ElementList.get_myNumList() == 0) + result = 0; + else + { + ActiveElement = 1; + ActiveDSSObject[ActiveActor] = ElementList.Get_First(); + // Make sure Active Ckt Element agrees if is a ckt element + // So COM interface will work + if (dynamic_cast((TDSSObject*)ActiveDSSObject[ActiveActor]) != nullptr) + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)(ActiveDSSObject[ActiveActor])); + result = ActiveElement; + } + return result; + } + + int TDSSClass::Get_Next() + { + int result = 0; + ActiveElement++; + if (ActiveElement > ElementList.get_myNumList()) + result = 0; + else + { + ActiveDSSObject[ActiveActor] = ElementList.Get_Next(); + // Make sure Active Ckt Element agrees if is a ckt element + // So COM interface will work + if (dynamic_cast((TDSSObject*)ActiveDSSObject[ActiveActor]) != nullptr) + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)(ActiveDSSObject[ActiveActor])); + result = ActiveElement; + } + return result; + } + + + void TDSSClass::AddProperty(string PropName, int CmdMapIndex, string HelpString) + { + ActiveProperty++; + PropertyName[ActiveProperty - 1] = PropName; + PropertyHelp[ActiveProperty - 1] = HelpString; + PropertyIdxMap[ActiveProperty - 1] = CmdMapIndex; // Maps to internal object property index + RevPropertyIdxMap[CmdMapIndex - 1] = ActiveProperty; + } + + + void TDSSClass::AllocatePropertyArrays() + { + int i = 0; + PropertyName = new string[NumProperties + 1]; + PropertyHelp = new string[NumProperties + 1]; + PropertyIdxMap = new int[NumProperties + 1]; + RevPropertyIdxMap = new int[NumProperties + 1]; + ActiveProperty = 0; // initialize for AddPropert + /*initialize PropertyIdxMap to take care of legacy items*/ + for (int stop = NumProperties, i = 1; i <= stop; i++) + PropertyIdxMap[i - 1] = i; + for (int stop = NumProperties, i = 1; i <= stop; i++) + RevPropertyIdxMap[i - 1] = i; + } + + + void TDSSClass::ReallocateElementNameList() + { + int i = 0; + /*Reallocate the device name list to improve the performance of searches*/ + ElementNameList = THashList(2 * ElementList.get_myNumList()); // make a new one + + // Do this using the Names of the Elements rather than the old list because it might be + // messed up if an element gets renamed + for (int stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + ElementNameList.Add((*(TDSSObject*)(ElementList.Get(i))).get_Name()); + } + + + void TDSSClass::ResynchElementNameList() + { + ReallocateElementNameList(); + ElementNamesOutOfSynch = false; + } + + +}// namespace DSSClass + + + + + diff --git a/OpenDSSC/Common/DSSClass.h b/OpenDSSC/Common/DSSClass.h new file mode 100644 index 0000000..ec6551b --- /dev/null +++ b/OpenDSSC/Common/DSSClass.h @@ -0,0 +1,118 @@ +#ifndef DSSClassH +#define DSSClassH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + Base Class for all DSS collection classes. + Keeps track of objects of each class, dispatches edits, etc +*/ + + +#include "System.h" +#include "Sysutils.h" +#include "Command.h" +#include "Arraydef.h" +#include "HashList.h" +#include "PointerList.h" +#include "ParserDel.h" + + + +//class TDSSClass; +//class TDSSClasses; + +using namespace std; + +namespace DSSClass +{ + + // Collection of all DSS Classes + + class TDSSClasses + { + + friend class TDSSClass; + public: +// private: + void Set_New(void* Value); + public: + TDSSClasses( ); + ~TDSSClasses( ); + }; + + // Base for all collection classes + + + + class TDSSClass: public TObject{ + friend class TDSSClasses; + //private: + public: + void Set_Active( int Value ); + int Get_ElementCount( ); + int Get_First( ); + int Get_Next( ); + void ResynchElementNameList( ); + //protected: + std::string Class_Name; + int ActiveElement; // index of present ActiveElement + TCommandList CommandList; + int ActiveProperty; + THashList ElementNameList; + int AddObjectToList( void* Obj ); // Used by NewObject + std::string Get_FirstPropertyName( ); + std::string Get_NextPropertyName( ); + virtual int MakeLike( std::string ObjName ); + void CountProperties( ); // Add no. of intrinsic properties + void AllocatePropertyArrays( ); + void DefineProperties( ); // Add Properties of this class to propName + int ClassEdit( const void* ActiveObj, const int ParamPointer ); + public: + int NumProperties; + std::string *PropertyName; + std::string *PropertyHelp; + int *PropertyIdxMap; + int *RevPropertyIdxMap; // maps property to internal command number + int DSSClassType; + TPointerList ElementList; + bool ElementNamesOutOfSynch; // When device gets renamed + bool Saved; + TDSSClass( ); + virtual ~TDSSClass(); + + /*Helper routine for building Property strings*/; + void AddProperty( std::string PropName, int CmdMapIndex, std::string HelpString ); + void ReallocateElementNameList( ); + virtual int Edit( int ActorID ) // uses global parser + ; + std::string get_myClass_name(); + virtual int Init( int Handle, int ActorID ); + virtual int NewObject( std::string ObjName ); + bool SetActive( std::string ObjName ); + void* GetActiveObj( ); // Get address of active obj of this class + virtual void* Find( std::string ObjName ) // Find an obj of this class by name + ; + int PropertyIndex( std::string Prop ); + int get_ActiveElement(); + }; + +} +//VAR +// DSSClasses : TDSSClasses; +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSClass; +#endif + +#endif // DSSClassH + + + + + + + + diff --git a/OpenDSSC/Common/DSSClassDefs.cpp b/OpenDSSC/Common/DSSClassDefs.cpp new file mode 100644 index 0000000..674a60e --- /dev/null +++ b/OpenDSSC/Common/DSSClassDefs.cpp @@ -0,0 +1,366 @@ + +#pragma hdrstop + +#include "DSSClassDefs.h" + +#include "DSSGlobals.h" +#include "DSSObject.h" +#include "ParserDel.h" +#include "MyDSSClassDefs.h" +#include "Solution.h" +#include "Bus.h" +#include "Line.h" +#include "VSource.h" +#include "Isource.h" +#include "vccs.h" +#include "LineCode.h" +#include "Spectrum.h" +#include "WireData.h" +#include "CNData.h" +#include "TSData.h" +#include "LineGeometry.h" +#include "LineSpacing.h" +#include "Load.h" +#include "LoadShape.h" +#include "TempShape.h" +#include "PriceShape.h" +#include "XYcurve.h" +#include "Monitor.h" +#include "EnergyMeter.h" +#include "GrowthShape.h" +#include "TCC_Curve.h" +#include "Transformer.h" +#include "Capacitor.h" +#include "Reactor.h" +#include "Fault.h" +#include "generator.h" +#include "WindGen.h" +#include "RegControl.h" +#include "CapControl.h" +#include "GenDispatcher.h" +#include "Relay.h" +#include "Recloser.h" +#include "fuse.h" +#include "Sensor.h" +#include "Feeder.h" +#include "XfmrCode.h" +#include "Storage.h" +#include "StorageController.h" +#include "SwtControl.h" +#include "PVsystem.h" +#include "InvControl.h" +#include "GICLine.h" +#include "GICTransformer.h" +#include "VSConverter.h" +#include "ExpControl.h" +#include "UPFC.h" +#include "UPFCControl.h" +#include "ESPVLControl.h" +#include "IndMach012.h" +#include "GICsource.h" +#include "AutoTrans.h" +#include "DynamicExp.h" + //by Dahei +#include "Generic5OrderMach.h" + // By Dahei +#include "fMonitor.h" +// BHSL +#include "gencls.h" +#include "genrou.h" + // JT +#include "ExcSexs.h" +// BLS +#include "tgov.h" + +namespace DSSClassDefs +{ + + unsigned int BaseClassMask = 0x00000007; + unsigned int CLASSMASK = 0xFFFFFFF8; + + /*Basic element types*/ + int NumIntrinsicClasses = 0, NumUserClasses = 0; + + /*--------------------------------------------------------------*/ + + void CreateDSSClasses() + { + ClassNames[ActiveActor] = THashList(25); // Makes 5 sub lists + DSSClassList[ActiveActor] = TPointerList(10); // 10 is initial size and increment + if (!(DSSClasses != NULL)) + DSSClasses = new TDSSClasses(); // class to handle junk for defining DSS classes + + /*General DSS objects, not circuit elements*/ + DSSObjs[ActiveActor] = TPointerList(25); // 25 is initial size and increment + + /*instantiate all Intrinsic Object Classes*/ + + /*Generic Object classes first in case others refer to them*/ + DSSClasses->Set_New(new TDSSSolution()); + SolutionClass[ActiveActor] = (TDSSSolution*) ActiveDSSClass[ActiveActor]; // this is a special class + DSSClasses->Set_New(new TLineCode()); + LoadShapeClass[ActiveActor] = new TLoadShape(); + DSSClasses->Set_New(LoadShapeClass[ActiveActor]); + TShapeClass[ActiveActor] = new TTShape(); + DSSClasses->Set_New(TShapeClass[ActiveActor]); + PriceShapeClass[ActiveActor] = new TPriceShape(); + DSSClasses->Set_New(PriceShapeClass[ActiveActor]); + XYCurveClass[ActiveActor] = new TXYcurve(); + DSSClasses->Set_New(XYCurveClass[ActiveActor]); + GrowthShapeClass[ActiveActor] = new TGrowthShape(); + DSSClasses->Set_New(GrowthShapeClass[ActiveActor]); + TCC_CurveClass[ActiveActor] = new TTCC_Curve(); + DSSClasses->Set_New(TCC_CurveClass[ActiveActor]); + SpectrumClass[ActiveActor] = new TSpectrum(); + DSSClasses->Set_New(SpectrumClass[ActiveActor]); + WireDataClass[ActiveActor] = new TWireData(); + DSSClasses->Set_New(WireDataClass[ActiveActor]); + CNDataClass[ActiveActor] = new TCNData(); + DSSClasses->Set_New(CNDataClass[ActiveActor]); + TSDataClass[ActiveActor] = new TTSData(); + DSSClasses->Set_New(TSDataClass[ActiveActor]); + DSSClasses->Set_New(new TLineGeometry()); + LineSpacingClass[ActiveActor] = new TLineSpacing(); + DSSClasses->Set_New(LineSpacingClass[ActiveActor]); + DSSClasses->Set_New(new TXfmrCode()); + + /*Circuit Element Classes*/ + DSSClasses->Set_New(new TLine()); + ActiveVSource[ActiveActor] = new TVsource(); + DSSClasses->Set_New(ActiveVSource[ActiveActor]); // 2-terminal Vsource + DSSClasses->Set_New(new TIsource()); // 2-terminal Isource + DSSClasses->Set_New(new TVCCS()); + DSSClasses->Set_New(new TLoad()); + DSSClasses->Set_New(new TTransf()); + DSSClasses->Set_New(new TRegControl()); + DSSClasses->Set_New(new TCapacitor()); + ReactorClass[ActiveActor] = new TReactor(); + DSSClasses->Set_New(ReactorClass[ActiveActor]); + DSSClasses->Set_New(new TCapControl()); + DSSClasses->Set_New(new TFault()); + DSSClasses->Set_New(new TGenerator()); + WindGenClass[ActiveActor] = new TWindGen(); + DSSClasses->Set_New(WindGenClass[ActiveActor]); + DSSClasses->Set_New(new TGenDispatcher()); + StorageClass[ActiveActor] = new TStorage(); + DSSClasses->Set_New(StorageClass[ActiveActor]); + // Storage2Class[ActiveActor] := new TStorage2.Create; + // DSSClasses->New := new Storage2Class[ActiveActor]; + DSSClasses->Set_New(new TStorageController()); + // DSSClasses->New := new TStorageController2.Create; + DSSClasses->Set_New(new TRelay()); + DSSClasses->Set_New(new TRecloser()); + DSSClasses->Set_New(new TFuse()); + // FeederClass := new TFeeder.Create; + // DSSClasses->New := new FeederClass; + DSSClasses->Set_New(new TSwtControl()); + PVSystemClass[ActiveActor] = new TPVSystem(); + DSSClasses->Set_New(PVSystemClass[ActiveActor]); + // PVSystem2Class[ActiveActor] := new TPVSystem2.Create; + // DSSClasses->New := new PVSystem2Class[ActiveActor]; + DSSClasses->Set_New(new TUPFC()); + DSSClasses->Set_New(new TUPFCControl()); + DSSClasses->Set_New(new TESPVLControl()); + DSSClasses->Set_New(new TIndMach012()); + DSSClasses->Set_New(new TGICsource()); // GIC source + DSSClasses->Set_New(new TAutoTrans()); // Auto Transformer + InvControlClass[ActiveActor] = new TInvControl(); + DSSClasses->Set_New(InvControlClass[ActiveActor]); + // InvControl2Class[ActiveActor]:= new TInvControl2(); + // DSSClasses->New := new InvControl2Class[ActiveActor]; + ExpControlClass[ActiveActor] = new TExpControl(); + DSSClasses->Set_New(ExpControlClass[ActiveActor]); + DSSClasses->Set_New(new TGICLine()); + DSSClasses->Set_New(new TGICTransformer()); + DSSClasses->Set_New(new TVSConverter()); + MonitorClass[ActiveActor] = new TDSSMonitor(); // Have to do this AFTER Generator + DSSClasses->Set_New(MonitorClass[ActiveActor]); + EnergyMeterClass[ActiveActor] = new TEnergyMeter(); // Have to do this AFTER Generator + DSSClasses->Set_New(EnergyMeterClass[ActiveActor]); + SensorClass[ActiveActor] = new TSensor(); // Create state estimation sensors + DSSClasses->Set_New(SensorClass[ActiveActor]); + + /*Add user-defined objects*/ + //by Dahei (UCF) + FMonitorClass[ActiveActor] = new TDSSFMonitor(); // Have to do this AFTER Generator + DSSClasses->Set_New(FMonitorClass[ActiveActor]); + DSSClasses->Set_New(new TGeneric5()); + + TDynamicExpClass[ActiveActor] = new TDynamicExp(); + DSSClasses->Set_New(TDynamicExpClass[ActiveActor]); + + /* Add new dynamic model capability */ + DSSClasses->Set_New(new TGencls()); + DSSClasses->Set_New(new TGenrou()); + DSSClasses->Set_New(new TExcSexs()); + DSSClasses->Set_New(new TTgov()); + + /* Create Classes for custom implementations */ + CreateMyDSSClasses(); + NumIntrinsicClasses = DSSClassList[ActiveActor].get_myNumList(); + NumUserClasses = 0; + + + /*This feature has been disabled - doesn't work in IIS*/ + + // Check all DLLs in present directory and home DSS directory to see if they + // are a user-defined DSS class + + //**** LoadUserClasses; + } + + //---------------------------------------------------------------------------- + + + void DisposeDSSClasses(bool AllActors) + { + int k = 0, DSSCidx = 0, temp = 0, i = 0; + TDSSObject* DSSObj; + TDSSClass* DSSClass_idx; + String TraceName, SuccessFree; + if (!AllActors) + { + try + { + SuccessFree = "Get_First() Object"; + for (int stop = DSSObjs[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + { + DSSObj = (TDSSObject*) DSSObjs[ActiveActor].Get(i); + TraceName = DSSObj->Get_myPName() + "." + DSSObj->get_Name(); + delete DSSObj; + SuccessFree = TraceName; + } + TraceName = "(DSSObjs Class)"; + DSSObjs[ActiveActor].Clear(); + } + catch (exception& E) + { + DoSimpleMsg(String("Exception disposing of DSS Obj \"") + TraceName + "\". " + CRLF + + "Last Successful dispose was for object \"" + SuccessFree + "\" " + CRLF + + (std::string) E.what(), 901); + } + try + { + for (int stop = DSSClassList[ActiveActor].get_myNumList(), i = 1; i <= stop; i++) + { + DSSClass_idx = (TDSSClass*) DSSClassList[ActiveActor].Get(i); + TraceName = DSSClass_idx->get_myClass_name(); + delete DSSClass_idx; + } + TraceName = "(DSS Class List)"; + DSSClassList[ActiveActor].Clear(); + TraceName = "(DSS Classes)"; + delete DSSClasses; + DSSClasses = NULL; + TraceName = "(ClassNames)"; + ClassNames[ActiveActor].Clear(); + } + catch (exception& E) + { + DoSimpleMsg(String("Exception disposing of DSS Class\"") + TraceName + "\". " + CRLF + + (std::string) E.what(), 902); + } + } + else + { + temp = ActiveActor; + for (int stop = NumOfActors, DSSCidx = 1; DSSCidx <= stop; DSSCidx++) + { + ActiveActor = DSSCidx; + DisposeDSSClasses(false); + } + TraceName = "(DSS Classes)"; + delete DSSClasses; + DSSClasses = NULL; + ActiveActor = 1; + } + } + + + /*--------------------------------------------------------------*/ + + + void AddUserClass() + { + // ***** ADD STUFF HERE **** + + /*Assumes DLL has been loaded by call to LoadLibrary and the Handle is stored + in LastUserDLLHandle. Also, assumes DSSRegisterProc has the address of + the user.*/ + + + /* ***** Needs to be re-done ****** */ + } + + /*--------------------------------------------------------------*/ + + void LoadUserClasses() + { + TSearchRec F; + + /* Rework This !!!!*/ + + // Check All DLLs in present directory + if (FindFirst("*.dll", 0, F) == 0) + { + do + { + if (IsDSSDLL(F.Name)) + AddUserClass(); // Attempt to add (ignored if classname already exists) + } while (!(FindNext(F) != 0)); + } + + // Check All DLLs in DSS Directory unless that is the directory we just checked + if (CompareText(StartupDirectory, DSSDirectory) != 0) + if (FindFirst(DSSDirectory + "*.dll", 0, F) == 0) + { + do + { + if (IsDSSDLL(F.Name)) + AddUserClass(); // Attempt to add (ignored if classname already exists) + } while (!(FindNext(F) != 0)); + } + } + + //---------------------------------------------------------------------------- + + + + bool SetObjectClass(const String ObjType) + + // set LastClassReferenced variable by class name + + { + bool result = false; + int Classref = 0; + Classref = ClassNames[ActiveActor].Find(ObjType); + switch (Classref) + { + case 0: + { + DoSimpleMsg(String("Error! Object Class \"") + ObjType + "\" not found." + CRLF + Parser[ActiveActor]->get_CmdBuffer(), 903); + result = false; + return result; + } + break;/*Error*/ + default: + LastClassReferenced[ActiveActor] = Classref; + } + result = true; + return result; + } + + //---------------------------------------------------------------------------- + + + + void* GetDSSClassPtr(const String ClassName) + { + TDSSClass* result; + result = (TDSSClass*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find(LowerCase(ClassName))); + return result; + } + + +}// namespace DSSClassDefs + diff --git a/OpenDSSC/Common/DSSClassDefs.h b/OpenDSSC/Common/DSSClassDefs.h new file mode 100644 index 0000000..8b21664 --- /dev/null +++ b/OpenDSSC/Common/DSSClassDefs.h @@ -0,0 +1,112 @@ +#ifndef DSSClassDefsH +#define DSSClassDefsH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PointerList.h" +#include "HashList.h" + +namespace DSSClassDefs +{ + + extern unsigned int BaseClassMask; + extern unsigned int CLASSMASK; + const int NON_PCPD_ELEM = 1; // A circuit Element we don't want enumerated in PD and PC Elements + + const int PD_ELEMENT = 2; + const int PC_ELEMENT = 3; + const int CTRL_ELEMENT = 4; + const int METER_ELEMENT = 5; + const int HIDDEN_ELEMENT = 6; + + /*Specific element Types*/ + const int MON_ELEMENT = 1 * 8; + const int DSS_OBJECT = 2 * 8; // Just a general DSS object, accessible to all circuits + + const int SOURCE = 3 * 8; + const int XFMR_ELEMENT = 4 * 8; + const int SUBSTATION = 5 * 8; // not used + + const int LINE_ELEMENT = 6 * 8; + const int LOAD_ELEMENT = 7 * 8; + const int FAULTOBJECT = 8 * 8; + const int ENERGY_METER = 9 * 8; + const int GEN_ELEMENT = 10 * 8; + const int CAP_CONTROL = 11 * 8; + const int REG_CONTROL = 12 * 8; + const int CAP_ELEMENT = 13 * 8; + const int RELAY_CONTROL = 14 * 8; + const int RECLOSER_CONTROL = 15 * 8; + const int FUSE_CONTROL = 16 * 8; + const int REACTOR_ELEMENT = 17 * 8; + const int FEEDER_ELEMENT = 18 * 8; + const int GEN_CONTROL = 19 * 8; + const int SENSOR_ELEMENT = 20 * 8; + const int STORAGE_ELEMENT = 21 * 8; + const int STORAGE_CONTROL = 22 * 8; + const int SWT_CONTROL = 23 * 8; + const int PVSYSTEM_ELEMENT = 24 * 8; + // PVSYSTEM2_ELEMENT = 25 * 8; // Using 25 (PR) + // Deleted --- VV_CONTROL = 25 * 8; + + const int GIC_Line = 26 * 8; + const int GIC_Transformer = 27 * 8; + const int INV_CONTROL = 28 * 8; + const int VS_CONVERTER = 29 * 8; + const int EXP_CONTROL = 30 * 8; + const int UPFC_ELEMENT = 31 * 8; + const int UPFC_CONTROL = 32 * 8; + const int VCCS_ELEMENT = 33 * 8; + const int ESPVL_CONTROL = 34 * 8; + const int INDMACH012_ELEMENT = 35 * 8; + const int GIC_SOURCE = 36 * 8; + const int AUTOTRANS_ELEMENT = 37 * 8; + const int FMON_ELEMENT = 38 * 8; /*BY Dahei UCF*/ + const int Generic5OrderMach_ELEMENT = 39 * 8; /*BY Dahei UCF*/ + const int INV_CONTROL2 = 40 * 8; + // STORAGE2_ELEMENT = 41 * 8; + // STORAGE2_CONTROL = 42 * 8; + + const int WINDGEN_ELEMENT = 43 * 8; + + // BHSL + const int GENMODELS_ELEMENT = 44 * 8; + const int GENCLS_ELEMENT = 45 * 8; + const int GENROU_ELEMENT = 46 * 8; + + const int EXCSEXS_ELEMENT = 50 * 8; + + const int TGOV_ELEMENT = 51 * 8; + + extern int NumIntrinsicClasses, NumUserClasses; + void CreateDSSClasses(); + void DisposeDSSClasses(bool AllActors); + void* GetDSSClassPtr(const String ClassName); + bool SetObjectClass(const String ObjType); + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSClassDefs; +#endif + + +#endif // DSSClassDefsH + + + + + + + + diff --git a/OpenDSSC/Common/DSSGlobals.cpp b/OpenDSSC/Common/DSSGlobals.cpp new file mode 100644 index 0000000..5234cd2 --- /dev/null +++ b/OpenDSSC/Common/DSSGlobals.cpp @@ -0,0 +1,1527 @@ + + +#pragma hdrstop + +#include "DSSGlobals.h" +#include "DynamicExp.h" + +#include +#include +#include +#ifndef windows +#include // getenv +#include // access +#endif +#include "dirsep.h" + +namespace DSSGlobals +{ + + bool DLLFirstTime; + TTextRec DLLDebugFile; + String ProgramName; + TIniRegSave DSS_Registry; // Registry (See Executive) + + // Global variables for the OpenDSS Viewer + + bool DSS_Viz_installed; // OpenDSS viewer (flag to mark a local installation) + + String DSS_Viz_path; + bool DSS_Viz_enable; + + // Global variables for OpenDSS-GIS + + bool DSS_GIS_installed; // OpenDSS-GIS (flag to mark a local installation) + + String DSS_GIS_path; + bool IsDLL, NoFormsAllowed; + std::vector < TDSSCircuit* > ActiveCircuit; + std::vector < TDSSClass* > ActiveDSSClass; + std::vector < int > LastClassReferenced; // index of class of last thing edited + + std::vector < void* > ActiveDSSObject; + int NumCircuits; + int MaxCircuits; + int MaxBusLimit; // Set in Validation + + int MaxAllocationIterations; + TPointerList Circuits; + std::vector < TPointerList > DSSObjs; + std::vector < TParser* > AuxParser; // Auxiliary parser for use by anybody for reparsing values + + //{****} DebugTrace:TextFile; + + bool ErrorPending; + int CmdResult, ErrorNumber; + String LastErrorMessage; + int DefaultEarthModel; + std::vector < int > ActiveEarthModel; + String LastFileCompiled; + bool LastCommandWasCompile; + complex CALPHA; /*120-degree shift constant*/ + double SQRT2; + double SQRT3; + double InvSQRT3; + double InvSQRT3x1000; + bool SolutionAbort; + bool InShowResults; + bool Redirect_Abort; + bool In_Redirect; + std::vector < bool > DIFilesAreOpen; + bool AutoShowExport; + bool AutoDisplayShowReport; + std::vector < bool > SolutionWasAttempted; + String GlobalHelpString; + String GlobalPropertyValue; + String GlobalResult; + String LastResultFile; + String VersionString; + bool LogQueries; + bool QueryFirstTime; + String QueryLogFileName; + TTextRec QueryLogFile; + String DefaultEditor; // normally, Notepad + + int DefaultFontSize; + String DefaultFontName; + TFontStyles DefaultFontStyles; + String DSSFileName; // Name of current exe or DLL + + String DSSDirectory; // where the current exe resides + + String StartupDirectory; // Where we started + + std::vector < String > DataDirectory; // used to be DSSDataDirectory + + std::vector < String > OutputDirectory; // output files go here, same as DataDirectory if writable + + std::vector < String > CircuitName_; // Name of Circuit with a "_" appended + + std::vector < pComplexArray > ActiveYPrim; // Created to solve the problems + + double DefaultBaseFreq; + double DaisySize; + + // Some commonly used classes so we can find them easily + + std::vector < TLoadShape* > LoadShapeClass; + std::vector < TTShape* > TShapeClass; + std::vector < TPriceShape* > PriceShapeClass; + std::vector < TXYcurve* > XYCurveClass; + std::vector < TGrowthShape* > GrowthShapeClass; + std::vector < TSpectrum* > SpectrumClass; + std::vector < TDSSSolution* > SolutionClass; + std::vector < TEnergyMeter* > EnergyMeterClass; + std::vector < TDSSFMonitor* > FMonitorClass; // By dahei UCF + std::vector < TDynamicExp* > TDynamicExpClass; + // FeederClass :TFeeder; + + std::vector < TDSSMonitor* > MonitorClass; + std::vector < TSensor* > SensorClass; + std::vector < TTCC_Curve* > TCC_CurveClass; + std::vector < TWireData* > WireDataClass; + std::vector < TCNData* > CNDataClass; + std::vector < TTSData* > TSDataClass; + std::vector < TLineSpacing* > LineSpacingClass; + std::vector < TStorage* > StorageClass; + std::vector < TPVSystem* > PVSystemClass; + std::vector WindGenClass; + std::vector ReactorClass; + std::vector < TInvControl* > InvControlClass; + std::vector < TExpControl* > ExpControlClass; + std::vector < TVsource* > ActiveVSource; // created on 01/14/2019 to facilitate actors to modify VSources while simulating + + std::vector < TStringList > EventStrings; + std::vector < TStringList > SavedFileList; + std::vector < TStringList > ErrorStrings; + std::vector < TPointerList > DSSClassList; // pointers to the base class types + + std::vector < THashList > ClassNames; + bool UpdateRegistry; // update on program exit + +#ifdef windows + __int64 CPU_Freq; // Used to store the CPU frequency +#else + int64_t CPU_Freq; // Used to store the CPU frequency +#endif + + const int32 max_CPU_Cores = 256; + int32 CPU_Cores; + int NumNUMA; // To store the number of NUMA nodes (should be the same as sockets) + bool EventLogDefault = false; + int32 CPU_Physical; + int ActiveActor; + int NumOfActors; + std::vector < int > ActorCPU; + std::vector < std::atomic > ActorStatus(max_CPU_Cores+1); + std::vector < int > ActorProgressCount; + // TProgress* ActorProgress; + std::vector < int > ActorPctProgress; + std::vector < TSolver* > ActorHandle; + std::vector < TThread* > ActorThread; + + //***********************A-Diakoptics suite globals***************************** + // To indicate if the tearing process will take place using the link branches given by the user + + bool AllActors, ADiakoptics, ADiak_Init, ADiak_PCInj, UseUserLinks, Parallel_enabled, ConcatenateReports, ProgressCmd, IncMat_Ordered; + std::vector < TParser* > Parser; + std::vector < TEvent > ActorMA_Msg; // Array to handle the events of each actor + + // Default ports + + int DSSPrgPort, DSSGISPort; + + + /******************************************************************************** + * Nomenclature: * + * OV_ Overloads * + * VR_ Voltage report * + * DI_ Demand interval for each meter. Moved to EnergyMeter.pas* + * SDI_ System Demand interval * + * TDI_ DI Totals * + * FM_ Meter Totals * + * SM_ System Meter * + * EMT_ Energy Meter Totals * + * PHV_ Phase Voltage Report. Moved to EnergyMeter.pas * + * These prefixes are applied to the variables of each file mapped into * + * Memory using the MemoryMap_Lib * + ******************************************************************************** + */ + std::vector < TBytesStream* > OV_MHandle; // a. Handle to the file in memory + + std::vector < TBytesStream* > VR_MHandle; + std::vector < TBytesStream* > SDI_MHandle; + std::vector < TBytesStream* > TDI_MHandle; + std::vector < TBytesStream* > SM_MHandle; + std::vector < TBytesStream* > EMT_MHandle; + std::vector < TBytesStream* > FM_MHandle; + + //*********** Flags for appending Files***************************************** + + std::vector < bool > OV_Append; + std::vector < bool > VR_Append; + std::vector < bool > DI_Append; + std::vector < bool > SDI_Append; + std::vector < bool > TDI_Append; + std::vector < bool > SM_Append; + std::vector < bool > EMT_Append; + std::vector < bool > PHV_Append; + std::vector < bool > FM_Append; + + string RepTermination = ".csv"; + + //***********************Seasonal QSTS variables******************************** + + bool SeasonalRating; // Tells the energy meter if the seasonal rating feature is active + + String SeasonSignal; // Stores the name of the signal for selecting the rating dynamically + + std::vector < TExecutive* > DSSExecutive; + TDSSClasses* DSSClasses; + std::vector < TIsource* > IsourceClass; + std::vector < TVsource* > VSourceClass; + + //************************ Progress actor Global defs*************************** + + bool DSSProgressFrm, IsProgressON; + std::vector < TProgressActor* > Progress_Actor; + String DSSProgressPath; + + //************************ OpenDSS-GIS Global defs*************************** + + bool IsGISON; + String GISThickness, GISColor; + pDoubleArray GISCoords; + + TCommandList LineTypeList; + + vector myStrArray; + vector myDblArray; + vector myCmplxArray; + vector myPolarArray; + vector myIntArray; + int FPropIndex; + + // For functions previously in DYMatrix.pas + void* Yhandle; + unsignedint NumNZ, NumBuses; + int* YColumns; + int* YRows; + complex *YValues; + + //typedef int THandle; + typedef int (*TDSSRegister)(Char*&); // Returns base class 1 or 2 are defined + // Users can only define circuit elements at present + + + THandle LastUserDLLHandle = 0; + TDSSRegister DSSRegisterProc; // of last library loaded + + //TIdTCPClient IdTCPClient; // ... TIdThreadComponent + + //TIdThreadComponent IdThreadComponent; + + + string GetHomeDir() + { +#ifdef windows + // These are static so that we only call getenv once or report if unset: + static const char* home_path = getenv("HOMEPATH"); + static const char* home_drive = getenv("HOMEDRIVE"); + + if (!home_drive || !home_path) { // getenv returned NULL indicating the variable was unset, + if (!home_drive) + DoSimpleMsg(String("Cannot determine user home drive from " "HOMEDRIVE" " environment variable."), 0); // TODO: replace last 0 parameter with unique number? + if (!home_path) + DoSimpleMsg(String("Cannot determine user home path from " "HOMEPATH" " environment variable."), 0); // TODO: replace last 0 parameter with unique number? + DoSimpleMsg(String("Falling back to using the current working directory."), 0); // TODO: replace last 0 parameter with unique number? + home_path = "."; // so fall back to using the current working directory. + home_drive = ""; // so fall back to using the current drive. + } + string home_dir = string(home_drive) + string(home_path); + if (!DirectoryExists(home_dir.c_str())) { + DoSimpleMsg(string("Cannot find user home directory: ")+home_dir, 0); // TODO: replace last 0 parameter with unique number? + } + return home_dir; +#else + // home_dir is static so that we only call getenv once or report if unset + static const char* home_dir = getenv("HOME"); + + if (!home_dir) { // getenv returned NULL indicating the variable was unset, + DoSimpleMsg(String("Cannot determine user home directory from " "HOME" " environment variable."), 0); // TODO: replace last 0 parameter with unique number? + DoSimpleMsg(String("Falling back to using the current working directory."), 0); // TODO: replace last 0 parameter with unique number? + home_dir = "."; // so fall back to using the current working directory. + } + if (!DirectoryExists(home_dir)) { + DoSimpleMsg(string("Cannot find user home directory: ")+home_dir, 0); // TODO: replace last 0 parameter with unique number? + } + return string(home_dir); +#endif + } + + + inline String GetDefaultDataDirectory() + { + return GetHomeDir(); + } + + + inline String GetDefaultScratchDirectory() + { + return GetHomeDir(); + } + + + String GetOutputDirectory() + { + String result; + result = OutputDirectory[ActiveActor]; + return result; + } + + /*--------------------------------------------------------------*/ + + + bool IsDSSDLL(String Fname) + { + bool result = false; + result = false; + /* + // Ignore if "DSSLIB.DLL" + if ( CompareText( ExtractFileName( Fname ), "dsslib.dll" ) == 0 ) + return result; + LastUserDLLHandle = LoadLibrary( Fname.c_str()); + if ( LastUserDLLHandle != 0 ) + { + + // Assign the address of the DSSRegister proc to DSSRegisterProc variable + DSSRegisterProc = GetProcAddress( LastUserDLLHandle, "DSSRegister" ); + if ( DSSRegisterProc != NULL ) + result = true; + else + FreeLibrary( LastUserDLLHandle ); + }*/ + return result; + } + + +//***********************DirectDLL interfacing globals************************** + + void WriteStr2Array(String myStr) + { + int i = 0; + for (i = 0; i < myStr.size(); i++) + { + myStrArray.push_back(uint8_t(myStr[i])); + } + } + + String BArray2Str(void* myPtr, int* idx) + { + string S = "", + result = ""; + uint8_t* PChar; + int i = *idx; + + PChar = (uint8_t*)myPtr; + while (PChar[i] != 0) + { + S = S + char(PChar[i]); + i++; + *idx = *idx + 1; + } + return S; + } + + String Char0() + { + string S(1, char(0)); + return S; + } + + //---------------------------------------------------------------------------- + + void DoErrorMsg(const String S, const String Emsg, const String ProbCause, int ErrNum) + { + String Msg; + int Retval = 0; + Msg = "Error " + to_string(ErrNum) + " Reported From OpenDSS Intrinsic Function : " + CRLF + S + CRLF + CRLF + "Error Description : " + CRLF + Emsg + CRLF + CRLF + "Probable Cause : " + + CRLF + ProbCause; + if (!NoFormsAllowed) + { + if (In_Redirect) + { + Retval = DSSMessageDlg(Msg, false); + if (Retval == -1) + Redirect_Abort = true; + } + else + DSSMessageDlg(Msg, true); + } + LastErrorMessage = Msg; + ErrorNumber = ErrNum; + AppendGlobalResultCRLF(Msg); + SolutionAbort = true; + } + + //---------------------------------------------------------------------------- + + + + void AppendGlobalResultCRLF(String S) + { + if (GlobalResult.length() > 0) + GlobalResult = GlobalResult + CRLF + S; + else + GlobalResult = S; + ErrorStrings[ActiveActor].insert(ErrorStrings[ActiveActor].end(), to_string(ErrorNumber) + S); // Add to Error log + } + + //---------------------------------------------------------------------------- + + + + void DoSimpleMsg(const String S, int ErrNum) + { + int Retval = 0; + if (!NoFormsAllowed) + { + if (In_Redirect) + { + Retval = DSSMessageDlg(to_string(ErrNum) + " OpenDSS " + CRLF + S, false); + if (Retval == -1) + Redirect_Abort = true; + } + else + DSSInfoMessageDlg(to_string(ErrNum) + " OpenDSS " + CRLF + S); + } + LastErrorMessage = S; + ErrorNumber = ErrNum; + AppendGlobalResultCRLF(S); + } + + //---------------------------------------------------------------------------- + + + + void DoThreadSafeMsg(const String S, int ErrNum) + // generates a dialog window thread safe using windows API + + { + int Retval = 0; + if (!NoFormsAllowed) + { + if (In_Redirect) + { + Retval = DSSMessageDlg(to_string(ErrNum) + " OpenDSS " + CRLF + S, false); + if (Retval == 3) + Redirect_Abort = true; + } + else + DSSInfoMessageDlg(to_string(ErrNum) + " OpenDSS " + CRLF + S); + } + LastErrorMessage = S; + ErrorNumber = ErrNum; + AppendGlobalResultCRLF(S); + } + //---------------------------------------------------------------------------- + + + + void SetObject(const String param) + + /*Set object active by name*/ + { + String ObjName, ObjClass; + + // Split off Obj class and name + size_t dotpos = param.find("."); + switch (dotpos) + { + case String::npos: + ObjName = param.substr(0, param.length()); + break; // assume it is all name; class defaults + default: + { + ObjClass = param.substr(0, dotpos); + ObjName = param.substr(dotpos + 1, param.length()); + } + } + if (ObjClass.length() > 0) + SetObjectClass(ObjClass); + ActiveDSSClass[ActiveActor] = (TDSSClass*)DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if (ActiveDSSClass[ActiveActor] != NULL) + { + if (!ActiveDSSClass[ActiveActor]->SetActive(ObjName)) + { // scroll through list of objects untill a match + DoSimpleMsg(String("Error! Object \"") + ObjName + "\" not found." + CRLF + Parser[ActiveActor]->get_CmdBuffer(), 904); + } + else + { + /*# with ActiveCircuit[ActiveActor] do */ + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + switch (((TDSSObject*)ActiveDSSObject[ActiveActor])->DSSObjType) + { + case DSS_OBJECT: + break; // do nothing for general DSS object + default: + { // for circuit types, set ActiveCircuit Element, too + with0->Set_ActiveCktElement((TDSSCktElement*)ActiveDSSClass[ActiveActor]->GetActiveObj()); + } + } + } + } + } + else + DoSimpleMsg("Error! Active object type/class is not set.", 905); + } + + int SetActiveBus(const String BusName) + { + int result = 0; + + // Now find the bus and set active + result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + if (with0->BusList.Get_NumElements() == 0) + return result; // Buslist not yet built + with0->ActiveBusIndex = with0->BusList.Find(BusName) - 1; + if (with0->ActiveBusIndex < 0) + { + result = 1; + AppendGlobalResult(String("SetActiveBus: Bus ") + BusName + " Not Found."); + } + } + } + return result; + } + + + void ClearAllCircuits() + { + bool isJoinable; + int I = 0; + for (int stop = NumOfActors, I = 1; I <= stop; I++) + { + if (ActiveCircuit[I] != NULL) + { + ActiveActor = I; + ActiveCircuit[I]->NumCircuits = 0; + delete ActiveCircuit[I]; + ActiveCircuit[I] = NULL; + + // In case the actor hasn't been destroyed + if (ActorHandle[I] != NULL) + { + ActorHandle[I]->Send_Message(EXIT_ACTOR); + ActorHandle[I] = NULL; + } + } + } + Circuits = TPointerList(2); // Make a new list of circuits + // Revert on key global flags to Original States + DefaultEarthModel = DERI; + LogQueries = false; + MaxAllocationIterations = 2; + ActiveActor = 1; + } + + + void MakeNewCircuit(const String Name) + + //Var + // handle :Integer; + + { + String S; + if (ActiveActor <= CPU_Cores) + { + if (ActiveCircuit[ActiveActor] == NULL) + { + ActiveCircuit[ActiveActor] = new TDSSCircuit(Name); + ActiveDSSObject[ActiveActor] = ActiveSolutionObj; + /**Handle := **/ + Circuits.Add(ActiveCircuit[ActiveActor]); + ActiveCircuit[ActiveActor]->NumCircuits++; + S = Parser[ActiveActor]->Get_Remainder(); // Pass remainder of string on to vsource. + /*Create a default Circuit*/ + SolutionAbort = false; + /*Voltage source named "source" connected to SourceBus*/ + DSSExecutive[ActiveActor]->Set_Command( String("New object=vsource.source Bus1=SourceBus ") + S); // Load up the parser as if it were read in + // Creates the thread for the actor if not created before + if (ActorHandle[ActiveActor] == NULL) + New_Actor(ActiveActor); + } + else + { + DoErrorMsg("MakeNewCircuit", "Cannot create new circuit.", "Max. Circuits Exceeded." + CRLF + "(Max no. of circuits=" + to_string(MaxCircuits) + ")", 906); + } + } + else + { + DoErrorMsg("MakeNewCircuit", "Cannot create new circuit.", "All the available CPUs have being assigned", 7000); + } + } + + //---------------------------------------------------------------------------- + + void AppendGlobalResult(const String S) + + // Append a string to Global result, separated by commas + + { + if (GlobalResult.length() == 0) + GlobalResult = S; + else + GlobalResult = GlobalResult + ", " + S; + } + + + std::string GetDSSVersion() + { + String result; + //DWORD InfoSize = 0, Wnd = 0; + //void* VerBuf = NULL; + //PVSFixedFileInfo FI; + //DWORD VerSize = 0; + //DWORD MajorVer = 0, MinorVer = 0, BuildNo = 0, RelNo = 0; + //DWORD iLastError = 0; + //result = "Unknown."; + //InfoSize = GetFileVersionInfoSize( DSSFileName.c_str(), Wnd ); + //if ( InfoSize != 0 ) + //{ + // GetMem( VerBuf, InfoSize ); + // try + // { + // if ( GetFileVersionInfo( DSSFileName.c_str(), Wnd, InfoSize, VerBuf ) ) + // if ( VerQueryValue( VerBuf, DIRSEP_CHAR, ((void*) FI ), VerSize ) ) + // { + // MinorVer = FI.dwFileVersionMS & 0xFFFF; + // MajorVer = ( FI.dwFileVersionMS & 0xFFFF0000 ) >> 16; + // BuildNo = FI.dwFileVersionLS & 0xFFFF; + // RelNo = ( FI.dwFileVersionLS & 0xFFFF0000 ) >> 16; + // result = Format( "%d.%d.%d.%d", ARRAYOFCONST(( MajorVer, MinorVer, RelNo, BuildNo )) ); + // } + // } + // __finally + // { + // FreeMem( VerBuf ); + // } + //} + //else + //{ + // iLastError = GetLastError; + // result = Format( "GetFileVersionInfo failed: (%d) %s", ARRAYOFCONST(( iLastError, SysErrorMessage( iLastError ) )) ); + //} + result = "10.0.0.1 @ C++"; // returns a string for now + return result; + } + + void WriteDLLDebugFile(const String S) + { + AssignFile(DLLDebugFile, OutputDirectory[ActiveActor] + "DSSDLLDebug.TXT"); + if (DLLFirstTime) + { + Rewrite(DLLDebugFile); + DLLFirstTime = false; + } + else + Append(DLLDebugFile); + IOResultToException(); + WriteLn(DLLDebugFile, S); + CloseFile(DLLDebugFile); + } + + + bool IsDirectoryWritable(const String Dir) + { + + bool result = false; + + using namespace std::chrono; + milliseconds ms = duration_cast(system_clock::now().time_since_epoch()); + std::string myTS = to_string(ms.count()); + + std::string myPath = Dir + myTS; + + std::ofstream outfile(myPath.c_str()); + outfile.close(); + + if (!outfile.fail() && !outfile.bad()) + result = DeleteFile(myPath); + else + result = false; + return result; + } + + void SetDataPath(const String PathName) + { + String ScratchPath; + // Pathname may be null + if ((PathName.length() > 0) && !DirectoryExists(PathName)) + { + // Try to create the directory + if (!CreateDir(PathName)) + { + DoSimpleMsg(String("Cannot create ") + PathName + " directory.", 907); + return; + } + } + DataDirectory[ActiveActor] = PathName; + + // Put a \ on the end if not supplied. Allow a null specification. + if (DataDirectory[ActiveActor].length() > 0) + { + ChDir(DataDirectory[ActiveActor]); // Change to specified directory + if (DataDirectory[ActiveActor][DataDirectory[ActiveActor].size() - 1] != DIRSEP_CHAR) + DataDirectory[ActiveActor] = DataDirectory[ActiveActor] + DIRSEP_STR; + } + + // see if DataDirectory is writable. If not, set OutputDirectory to the user's appdata + if (IsDirectoryWritable(DataDirectory[ActiveActor])) + { + OutputDirectory[ActiveActor] = DataDirectory[ActiveActor]; + } + else + { + ScratchPath = GetDefaultScratchDirectory() + DIRSEP_STR + ProgramName + DIRSEP_STR "Scratch" DIRSEP_STR; + if (!DirectoryExists(ScratchPath)) + CreateDir(ScratchPath); + OutputDirectory[ActiveActor] = ScratchPath; + } + } + +#ifndef windows + static std::string FindDefaultEditor() + { + const char *editors[] = { + getenv("VISUAL"), + getenv("EDITOR"), + "/usr/local/bin/nano", // See if there's a friendly editor available. + "/usr/bin/nano", + "/usr/bin/vi", // This editor is friendly but picky about its friends. + }; + unsigned num_editors = sizeof(editors)/sizeof(editors[0]); + for (unsigned ndx=0; ndxSolution->DynaVars.dblHour) + Prop + ", " + S); + CloseFile(QueryLogFile); + } + catch (exception& E) + { + DoSimpleMsg("Error writing Query Log file: " + (string)E.what(), 908); + } + } + + + void SetLastResultFile(const String Fname) + { + LastResultFile = Fname; + ParserVars->Add("@lastfile", Fname); + } + + + void* MyAllocMem(unsignedint nbytes) + { + void* result = NULL; + result = malloc(nbytes); + WriteDLLDebugFile(Format("Allocating %d bytes @ %p", nbytes, 0)); + return result; + } + + void MyReallocMem(void*& p, int newsize) + { + WriteDLLDebugFile(Format("Reallocating @ %p, new size= %d", p, newsize)); + ReallocMem(p, newsize); + } + + // Function to validate the installation and path of the OpenDSS Viewer + + + + String GetIni(String S, String k, String d, String f = "") /*# overload */ + { + String result; + /*TMemIniFile ini; + result = d; + if ( f.IsEmpty()) + { + ini = TMemIniFile.Create( lowercase( ChangeFileExt( ParamStr( 0 ), ".ini" ) ) ); + } + else + { + if ( ! FileExists( f ) ) + return result; + ini = TMemIniFile.Create( f ); + } + if ( ini.ReadString( S, k, "" ) == "" ) + { + ini.WriteString( S, k, d ); + ini.UpdateFile; + } + result = ini.ReadString( S, k, d ); + delete ini; + ini = NULL;*/ + result = d; // constant for now + return result; + } + + + //****************************************************************************** + // + // Waits for all the actors running tasks + // + void Wait4Actors(int WType) + { + int I = 0; + bool Flag = false; + // WType defines the starting point in which the actors will be evaluated, + // modification introduced in 01-10-2019 to facilitate the coordination + // between actors when a simulation is performed using A-Diakoptics + if (!NoFormsAllowed) + CoutLn("Waiting..."); + for (int stop = NumOfActors, I = (WType + 1); I <= stop; I++) + { + try + { + while (ActorStatus[I] == 0) + { + Flag = true; + // while Flag do + // Flag := ActorMA_Msg[i].WaitFor(1) = TWaitResult.wrTimeout; + } + } + catch (EOutOfMemory&) + { + DoSimpleMsg("Exception Waiting for the parallel thread to finish a job", 7006); + } + } + } + + void DoClone() + { + String dummy; + int I = 0, NumClones = 0; + String Ref_Ckt; + Ref_Ckt = LastFileCompiled; + dummy = Parser[ActiveActor]->GetNextParam(); + NumClones = Parser[ActiveActor]->MakeInteger_(); + Parallel_enabled = false; + if (((NumOfActors + NumClones) <= CPU_Cores) && (NumClones > 0)) + { + for (int stop = NumClones, I = 1; I <= stop; I++) + { + New_Actor_Slot(); + DSSExecutive[ActiveActor]->Set_Command( String("compile \"") + Ref_Ckt + "\""); + // sets the previous maxiterations and controliterations + ActiveCircuit[ActiveActor]->Solution->MaxIterations = ActiveCircuit[1]->Solution->MaxIterations; + ActiveCircuit[ActiveActor]->Solution->MaxControlIterations = ActiveCircuit[1]->Solution->MaxControlIterations; + // Solves the circuit + CmdResult = ExecOptions::DoSetCmd(1); + } + } + else + { + if (NumClones > 0) + DoSimpleMsg("There are no more CPUs available", 7001); + else + DoSimpleMsg("The number of clones requested is invalid", 7004); + } + } + + // Prepares memory to host a new actor + + + + void New_Actor_Slot() + { + if (NumOfActors < CPU_Cores) + { + NumOfActors++; + GlobalResult = to_string(NumOfActors); + ActiveActor = NumOfActors; + ActorCPU[ActiveActor] = -1; // By default, the actor will have affinity to all processors (-1) + DSSExecutive[ActiveActor] = new TExecutive(); // Make a DSS object + Parser[ActiveActor] = new TParser(); + AuxParser[ActiveActor] = new TParser(); + DSSExecutive[ActiveActor]->CreateDefaultDSSItems(); + } + else + DoSimpleMsg("There are no more CPUs available", 7001); + } + + // Creates a new actor + + + void New_Actor(int ActorID) + { + ActorHandle[ActorID] = new TSolver(ActorCPU[ActorID], ActorID); // TEMC: TODO: text-mode callback + ActorStatus[ActorID] = 1; + } + + + static string remove_duplicate_directory_separators(const string& in) + { // This function is static, because it is not called from any other compilation unit. + string out = in; + String doubleslash = DIRSEP_STR DIRSEP_STR; + size_t ndx = out.find(doubleslash); + while (ndx != string::npos) { + out.replace(ndx, doubleslash.length(), DIRSEP_STR); + ndx = out.find(doubleslash); + } + return out; + } + + + // Validates the installation and path of the OpenDSS Viewer + + + bool CheckOpenDSSViewer(String App_Folder) + { + bool result = false; + String FileName; + // to make it compatible with the function + App_Folder = LowerCase(App_Folder); + + string home_dir = GetHomeDir(); + + // Stores the + if (App_Folder == "opendss_viewer") + { + DSS_Viz_path = GetIni("Application", "path", "", home_dir + (string)DIRSEP_STR + App_Folder + DIRSEP_STR "settings.ini"); + FileName = remove_duplicate_directory_separators(DSS_Viz_path); + } + else + { + DSS_GIS_path = GetIni("Application", "path", "", home_dir + (string)DIRSEP_STR + App_Folder + DIRSEP_STR "settings.ini"); + FileName = remove_duplicate_directory_separators(DSS_GIS_path); + } + FileName = regex_replace(FileName, regex("\""), ""); + + // returns true only if the executable exists + result = FileExists(FileName); + return result; + } + + void Delay(int TickTime) + { + int Past = 0; + Past = (int) GetTickCount64(); + do + { + } while (!((GetTickCount64() - Past) >= ((int)TickTime))); + } + + //*********Downloads a file from the internet into the folder specified********* + + + bool DownLoadInternetFile(String Source, String Dest) + { + bool result = false; + try + { +// result = URLDownloadToFile(NULL, Source.c_str(), Dest.c_str(), 0, NULL) == 0; + } + catch (...) + { + result = false; + } + return result; + } + + //******Verifies the OpenDSS version using the reference at Sourceforge********* + + + +#ifdef windows + void Check_DSS_WebVersion() + { + String myVersion, myText, myWebSrc, myPath; + TTextRec myFile; + int myIdx = 0; + char fpath[MAX_PATH + 20]; + + GetTempPath(sizeof(fpath), fpath); + std::string s; + std::stringstream ss; + + ss << fpath; + ss >> s; + + myPath = s + (string)DIRSEP_STR "myDSSVersion.txt"; + myWebSrc = "https://sourceforge.net/p/electricdss/code/HEAD/tree/trunk/Version8/Source/Current_ver.txt"; + // Download the file into the Windows temporary folder + if (DownLoadInternetFile(myWebSrc, myPath)) + { + AssignFile(myFile, myPath); + Reset(myFile); + IOResultToException(); + while (!Eof(myFile)) + { + ReadLn(myFile, myText); + myIdx = Pos("mydssversion=", LowerCase(myText)); + if (myIdx > 0) + break; + } + CloseFile(myFile); + } + myText = myText.substr(myIdx + 12); + myVersion = VersionString.substr(8); + myIdx = (int) myVersion.find(" "); + myVersion = myVersion.substr(0, myIdx - 1); + if (myText != myVersion) + { + myPath = "There is a new version of OpenDSS avaialable for download" + CRLF + "The new version can be located at:" + CRLF + CRLF + "https://sourceforge.net/projects/electricdss/"; + DoSimpleMsg(myPath, 0); + } + } +#endif + + //**********************Launches the COM Help file****************************** + + +#ifdef windows + void Show_COM_Help() + { + ShellExecute(0, "open", AnsiString(DSSDirectory + DIRSEP_STR "OpenDSS_COM.chm").c_str(), NULL, NULL, SW_SHOWNORMAL); + } +#endif + + //*********************Gets the processor information*************************** + + + void Get_Processor_Info() + { + int idx = 0; + NumNUMA = 1; + + #ifdef _WIN32 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + + CPU_Physical = std::thread::hardware_concurrency(); + CPU_Cores = sysinfo.dwNumberOfProcessors; // for now is the same + #elif _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + + CPU_Physical = std::thread::hardware_concurrency(); + CPU_Cores = sysinfo.dwNumberOfProcessors; // for now is the same + #elif __linux__ + CPU_Physical = std::thread::hardware_concurrency(); + CPU_Cores = sysconf(_SC_NPROCESSORS_ONLN); + #endif + if(CPU_Cores > max_CPU_Cores) { + std::cerr << "CPU_Cores exceeds max_CPU_Cores. Please increase max_CPU_Cores to " << CPU_Cores; + // limit CPU_Cores because size of ActorStatus is fixed by`max_CPU_Cores + CPU_Cores = max_CPU_Cores; + } + } + + + TProgressActor::TProgressActor() + { + int J = 0; // Does nothing in this version + /* ShellExecute(NULL, "open", DSSProgressPath.c_str(), NULL, NULL, SW_SHOWNORMAL); + sleep(200); + // ... create TIdTCPClient + IdTCPClient = TIdTCPClient.Create( ); + // ... set properties + IdTCPClient.Host = "localhost"; + IdTCPClient.Port = DSSPrgPort; + IdThreadComponent = TIdThreadComponent.Create( ); + if ( ADiakoptics && ( ActiveActor == 1 ) ) + J = 1; + else + J = NumOfActors; + try + { + IdTCPClient.Connect; + IdTCPClient.IOHandler.Writeln( "num" + inttostr( J ) ); + IsProgressON = true; + } + catch( Exception & E ) + { + { + IsProgressON = false; + throw; + } + } + */ + } + + void TProgressActor::Execute() + { + int I = 0, J = 0; + String AbortBtn, progStr; + bool RunFlag = false; + /* // Does nothing for now + if ( IsProgressON ) + { + RunFlag = true; + while ( RunFlag ) + { + Sleep( 100 ); + progStr = ""; + RunFlag = false; + if ( ADiakoptics && ( ActiveActor == 1 ) ) + J = 1; + else + J = NumOfActors; + for ( int stop = J, I = 1; I <= stop; I++) + { + progStr = progStr + Format( "%.*d", 3, ActorPctProgress[I] ) ); + RunFlag = RunFlag || ( ActorStatus[I] == 0 ); + } + IdTCPClient.IOHandler.Writeln( String( "prg" ) + progStr ); + AbortBtn = IdTCPClient.IOHandler.ReadLn; + if ( AbortBtn.substr( 0, 1 ) == "T") + SolutionAbort = true; + } + IdTCPClient.IOHandler.Writeln( "ext" ); + } + */ + } + + void TProgressActor::Doterminate() // Is the end of the thread + + { + IsProgressON = false; + //inherited::Doterminate(); + } + + + TProgressActor::~TProgressActor() + { + // todo check: inherited::Destroy; + } + + + void GetDefaultPorts() + { + /* TTextRec f; + + TdJSON JSONCfg; + String JSONStr, iniFilePath; + iniFilePath = DSSDirectory + "ComPorts.ini"; + if ( FileExists( iniFilePath ) ) + { + AssignFile( f, iniFilePath ); + Reset( f ); + IOResultToException(); + ReadLn( f, JSONStr ); + CloseFile( f ); + // parse the JSON string and extract the values + JSONCfg = TdJSON.Parse( JSONStr ); + DSSPrgPort = JSONCfg["dssprogress"].AsInteger; + DSSGISPort = JSONCfg["dssgis"].AsInteger; + } + else + { */ // Since the Cfg file is missing, use the defaults + DSSPrgPort = 20010; // uses defaults for now + DSSGISPort = 20011; + // } + } + + //***************Initialization for Parallel Processing************************* + + void DSSGlobals_initialization() + { + Get_Processor_Info(); + ActiveCircuit.resize(CPU_Cores + 1); + ActorCPU.resize(CPU_Cores + 1); + ActorProgressCount.resize(CPU_Cores + 1); + ActiveDSSClass.resize(CPU_Cores + 1); + DataDirectory.resize(CPU_Cores + 1); + OutputDirectory.resize(CPU_Cores + 1); + CircuitName_.resize(CPU_Cores + 1); + ActorPctProgress.resize(CPU_Cores + 1); + ActiveDSSObject.resize(CPU_Cores + 1); + LastClassReferenced.resize(CPU_Cores + 1); + DSSObjs.resize(CPU_Cores + 1); + ActiveEarthModel.resize(CPU_Cores + 1); + ClassNames.resize(CPU_Cores + 1); + DSSClassList.resize(CPU_Cores + 1); + MonitorClass.resize(CPU_Cores + 1); + LoadShapeClass.resize(CPU_Cores + 1); + TShapeClass.resize(CPU_Cores + 1); + PriceShapeClass.resize(CPU_Cores + 1); + XYCurveClass.resize(CPU_Cores + 1); + GrowthShapeClass.resize(CPU_Cores + 1); + SpectrumClass.resize(CPU_Cores + 1); + SolutionClass.resize(CPU_Cores + 1); + EnergyMeterClass.resize(CPU_Cores + 1); + SensorClass.resize(CPU_Cores + 1); + TCC_CurveClass.resize(CPU_Cores + 1); + WireDataClass.resize(CPU_Cores + 1); + CNDataClass.resize(CPU_Cores + 1); + TSDataClass.resize(CPU_Cores + 1); + LineSpacingClass.resize(CPU_Cores + 1); + StorageClass.resize(CPU_Cores + 1); + PVSystemClass.resize(CPU_Cores + 1); + WindGenClass.resize(CPU_Cores + 1); + ReactorClass.resize(CPU_Cores + 1); + InvControlClass.resize(CPU_Cores + 1); + ExpControlClass.resize(CPU_Cores + 1); + EventStrings.resize(CPU_Cores + 1); + SavedFileList.resize(CPU_Cores + 1); + ErrorStrings.resize(CPU_Cores + 1); + ActorHandle.resize(CPU_Cores + 1); + Parser.resize(CPU_Cores + 1); + AuxParser.resize(CPU_Cores + 1); + ActiveYPrim.resize(CPU_Cores + 1); + SolutionWasAttempted.resize(CPU_Cores + 1); + TDynamicExpClass.resize(CPU_Cores + 1); + + // ActorStatus was changed from vector to vector> for + // memory-ordering guarantees when threads are signaling between each + // other. So ActorStatus no longer supports .resize() since atomic + // is not copyable or movable. + // + // ActorStatus.resize(CPU_Cores + 1); + if(ActorStatus.size() < CPU_Cores+1) + throw std::runtime_error("CPU_Cores+1 exceeds ActorStatus.size()"); + + ActorMA_Msg.resize(CPU_Cores + 1); + ActiveVSource.resize(CPU_Cores + 1); + FMonitorClass.resize(CPU_Cores + 1); // by Dahei UCF + // Init pointer repositories for the EnergyMeter in multiple cores + OV_MHandle.resize(CPU_Cores + 1); + VR_MHandle.resize(CPU_Cores + 1); + SDI_MHandle.resize(CPU_Cores + 1); + TDI_MHandle.resize(CPU_Cores + 1); + SM_MHandle.resize(CPU_Cores + 1); + EMT_MHandle.resize(CPU_Cores + 1); + FM_MHandle.resize(CPU_Cores + 1); + OV_Append.resize(CPU_Cores + 1); + VR_Append.resize(CPU_Cores + 1); + DI_Append.resize(CPU_Cores + 1); + SDI_Append.resize(CPU_Cores + 1); + TDI_Append.resize(CPU_Cores + 1); + SM_Append.resize(CPU_Cores + 1); + EMT_Append.resize(CPU_Cores + 1); + PHV_Append.resize(CPU_Cores + 1); + FM_Append.resize(CPU_Cores + 1); + DIFilesAreOpen.resize(CPU_Cores + 1); + DSSExecutive.resize(CPU_Cores + 1); + IsourceClass.resize(CPU_Cores + 1); + VSourceClass.resize(CPU_Cores + 1); + for ( int stop = CPU_Cores, ActiveActor = 1; ActiveActor <= stop; ActiveActor++) + { + ActiveCircuit[ActiveActor] = nullptr; + ActiveDSSClass[ActiveActor] = NULL; + EventStrings[ActiveActor].clear(); + SavedFileList[ActiveActor].clear(); + ErrorStrings[ActiveActor].clear(); + ActorHandle[ActiveActor] = NULL; + Parser[ActiveActor] = NULL; + ActorStatus[ActiveActor] = 1; + OV_MHandle[ActiveActor] = NULL; + VR_MHandle[ActiveActor] = NULL; + SDI_MHandle[ActiveActor] = NULL; + TDI_MHandle[ActiveActor] = NULL; + SM_MHandle[ActiveActor] = NULL; + EMT_MHandle[ActiveActor] = NULL; + FM_MHandle[ActiveActor] = NULL; + DIFilesAreOpen[ActiveActor] = false; + ActiveVSource[ActiveActor] = NULL; + // DSSObjs[ActiveActor] = NULL; + // DSSClassList[ActiveActor] = NULL; + } + + AutoDisplayShowReport = true; + DefaultBaseFreq = 60; + GISThickness = "3"; + GISColor = "FF0000"; + GISCoords = new double[ 4 ]; + UseUserLinks = false; + IsProgressON = false; + //Progress_Actor = NULL; + DSSClasses = NULL; + ProgressCmd = false; + AllActors = false; + ActiveActor = 1; + NumOfActors = 1; + ActorCPU[ActiveActor] = - 1; + Parser[ActiveActor] = new TParser(); + ProgramName = "OpenDSS"; + DSSFileName = GetDSSExeFile(); + DSSDirectory = ExtractFilePath( DSSFileName ); + ADiakoptics = false; // Disabled by default + ADiak_Init = false; + GetDefaultPorts( ); // Gets the default ports to get connected to other add-ons + SeasonalRating = false; + SeasonSignal = ""; + + /*Various Constants and Switches*/ + CALPHA = cmplx( - 0.5, - 0.866025 ); // -120 degrees phase shift + SQRT2 = sqrt( 2.0 ); + SQRT3 = sqrt( 3.0 ); + InvSQRT3 = 1.0 / SQRT3; + InvSQRT3x1000 = InvSQRT3 * 1000.0; + CmdResult = 0; + //DIFilesAreOpen := FALSE; + ErrorNumber = 0; + ErrorPending = false; + GlobalHelpString = ""; + GlobalPropertyValue = ""; + LastResultFile = ""; + In_Redirect = false; + InShowResults = false; + IsDLL = false; + LastCommandWasCompile = false; + LastErrorMessage = ""; + MaxCircuits = 1; // Not required anymore. planning to remove it + MaxAllocationIterations = 2; + SolutionAbort = false; + AutoShowExport = false; + + SolutionWasAttempted[ActiveActor] = false; + DefaultBaseFreq = 60.0; + DaisySize = 1.0; + DefaultEarthModel = DERI; + ActiveEarthModel[ActiveActor] = DefaultEarthModel; + Parallel_enabled = false; + ConcatenateReports = false; + + ProgramName = "OpenDSS"; + DSSFileName = GetDSSExeFile(); + DSSDirectory = ExtractFilePath( DSSFileName ); + // want to know if this was built for 64-bit, not whether running on 64 bits + // (i.e. we could have a 32-bit build running on 64 bits; not interested in that + VersionString = "Version " + GetDSSVersion() + " (" + std::to_string(sizeof(void*)*8u) + "-bit build)"; + + StartupDirectory = GetCurrentDir() + DIRSEP_STR; + SetDataPath( GetDefaultDataDirectory() + DIRSEP_STR + ProgramName + DIRSEP_STR ); + //DSS_Registry = TIniRegSave.Create( DataDirectory[ActiveActor] + "opendsscmd.ini" ); + AuxParser[ActiveActor] = new TParser(); + +#ifdef windows + DefaultEditor = "NotePad.exe"; +#else + DefaultEditor = FindDefaultEditor(); +#endif + DefaultFontSize = 8; + DefaultFontName = "MS Sans Serif"; + LogQueries = false; + QueryLogFileName = ""; + UpdateRegistry = true; +#ifdef windows + QueryPerformanceFrequency( ((LARGE_INTEGER*) &CPU_Freq) ); +#endif + + string myList[12] = { "OH", "UG", "UG_TS", "UG_CN", "SWT_LDBRK", "SWT_FUSE", "SWT_SECT", "SWT_REC", "SWT_DISC", "SWT_BRK", "SWT_ELBOW", "BUSBAR"}; + LineTypeList = TCommandList(myList, 12); + LineTypeList.set_AbbrevAllowed(true); // Allow abbreviations for line type code + + myStrArray.resize(0); + myDblArray.resize(0); + myCmplxArray.resize(0); + myPolarArray.resize(0); + myIntArray.resize(0); + FPropIndex = 0; + + Yhandle = nullptr; + NumNZ = 0; + NumBuses = 0; + YColumns = nullptr; + YRows = nullptr; + YValues = nullptr; + + + //IsMultithread = true; + DSS_Viz_installed = CheckOpenDSSViewer( "OpenDSS_Viewer" ); // OpenDSS Viewer (flag for detected installation) + DSS_GIS_installed = CheckOpenDSSViewer( "OpenDSS_GIS" ); // OpenDSS GIS (flag for detected installation) +#ifdef windows + if ( ! IsDLL ) + { +// Check_DSS_WebVersion(); // to be checked + } +#endif + + } + + string GetLineTypes() + { + // Returns a string containing the line types + // the string format is the standard DSS array format (comma separated) + int idx = 0; + string separator = "", + Result = ""; + + Result = "["; + for (idx = 1; idx <= LineTypeList.Get_NumCommands(); idx++) + { + Result = Result + separator + LineTypeList.Get(idx); + separator = ", "; + } + Result = Result + "]"; + + return Result; + } + + void DSSGlobals_finalization() + { + ClearAllCircuits(); + for (int stop = NumOfActors, ActiveActor = 1; ActiveActor <= stop; ActiveActor++) + { + /*# with DSSExecutive[ActiveActor] do */ + { + auto with0 = DSSExecutive[ActiveActor]; + if (with0 != NULL && with0->get_FRecorderOn()) + with0->Set_RecorderOn(false); + } + delete DSSExecutive[ActiveActor]; /*Writes to Registry*/ + /*TODO: Close Registry? */ + EventStrings[ActiveActor].clear(); + SavedFileList[ActiveActor].clear(); + ErrorStrings[ActiveActor].clear(); + if (ActorHandle[ActiveActor] != NULL) + { + delete ActorHandle[ActiveActor]; + ActorHandle[ActiveActor] = NULL; + } + delete AuxParser[ActiveActor];//AuxParser[ActiveActor]->~TParser(); + if (Parser[ActiveActor] != NULL){ + delete Parser[ActiveActor]; + Parser[ActiveActor] = NULL; + } + } + } + + class DSSGlobals_unit + { + public: + DSSGlobals_unit() + { + //AssertSystemInitialization(); + DSSGlobals_initialization(); + } + ~DSSGlobals_unit() { DSSGlobals_finalization(); } + }; + DSSGlobals_unit _DSSGlobals_unit; + +} + + + + + + + + + diff --git a/OpenDSSC/Common/DSSGlobals.h b/OpenDSSC/Common/DSSGlobals.h new file mode 100644 index 0000000..a7c2523 --- /dev/null +++ b/OpenDSSC/Common/DSSGlobals.h @@ -0,0 +1,474 @@ +#ifndef DSSGlobalsH +#define DSSGlobalsH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +/* Change Log + 8-14-99 SolutionAbort Added + + 10-12-99 AutoAdd constants added; + 4-17-00 Added IsShuntCapacitor routine, Updated constants + 10-08-02 Moved Control Panel Instantiation and show to here + 11-6-02 Removed load user DLL because it was causing a conflict +*/ + +/*$WARN UNIT_PLATFORM OFF*/ + +#include "System.h" +#include "DSSClassDefs.h" +#include "DSSObject.h" +#include "DSSClass.h" +#include "ParserDel.h" +#include "HashList.h" +#include "PointerList.h" +#include "PDElement.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "CktElement.h" +#include "Circuit.h" +#include "IniRegSave.h" +#include "Solution.h" +#include "Spectrum.h" +#include "LoadShape.h" +#include "TempShape.h" +#include "PriceShape.h" +#include "XYcurve.h" +#include "GrowthShape.h" +#include "Monitor.h" +#include "EnergyMeter.h" +#include "Sensor.h" +#include "TCC_Curve.h" +#include "Feeder.h" +#include "WireData.h" +#include "CNData.h" +#include "TSData.h" +#include "LineSpacing.h" +#include "TempShape.h" +#include "Storage.h" +#include "PVsystem.h" +#include "WindGen.h" +#include "Isource.h" +#include "InvControl.h" +#include "ExpControl.h" +#ifndef linux +#include +#define NOMINMAX +#include +#else +#include "windows2posix.h" +#endif +#include +#include +#include +#include +#ifndef linux +#include +#include +#endif +#include "YMatrix.h" // by Dahei +#include "fMonitor.h" +#include "VSource.h" +#include "Executive.h" +#include "ExecOptions.h" +#include "IniRegSave.h" +#include "Isource.h" +#include "CmdForms.h" +#include "myCmdUtils.h" +#include "Sysutils.h" +#include "DynamicExp.h" +#include +#include +#include +#include + +#define _USE_MATH_DEFINES + +#include + +using namespace std; +using namespace Executive; + +namespace DSSGlobals +{ + +// class TProgressActor; + typedef unsigned int unsignedint; + + + const std::string CRLF = "\n"; // cross-platform + + const double PI = M_PI; //3.141592653589793238462643383279502884L; + const double TwoPi = 2.0 * PI; + const double RadiansToDegrees = 180.0 / PI; + const double EPSILON = 1.0e-12; // Default tiny floating point + + const double EPSILON2 = 1.0e-3; // Default for Real number mismatch testing + + const int POWERFLOW = 1; // Load model types for solution + + const int ADMITTANCE = 2; + + const std::string CHAR10(1, (char)10); + + // For YPrim matrices + + const int ALL_YPRIM = 0; + const int SERIES = 1; + const int SHUNT = 2; + + /*Control Modes*/ + const int CONTROLSOFF = -1; + const int EVENTDRIVEN = 1; + const int TIMEDRIVEN = 2; + const int MULTIRATE = 3; + const int CTRLSTATIC = 0; + + /*Randomization Constants*/ + const int GAUSSIAN = 1; + const int UNIFORM = 2; + const int LOGNORMAL = 3; + + /*Autoadd Constants*/ + const int GENADD = 1; + const int CAPADD = 2; + + /*ERRORS*/ + const int SOLUTION_ABORT = 99; + + /*For General Sequential Time Simulations*/ + const int USEDAILY = 0; + const int USEYEARLY = 1; + const int USEDUTY = 2; + const int USENONE = -1; + + /*Earth Model*/ + const int SIMPLECARSON = 1; + const int FULLCARSON = 2; + const int DERI = 3; + + /*Profile Plot Constants*/ + const int PROFILE3PH = 9999; // some big number > likely no. of phases + + const int PROFILEALL = 9998; + const int PROFILEALLPRI = 9997; + const int PROFILELLALL = 9996; + const int PROFILELLPRI = 9995; + const int PROFILELL = 9994; + const int PROFILEPUKM = 9993; // not mutually exclusive to the other choices 9999..9994 + + const int PROFILE120KFT = 9992; // not mutually exclusive to the other choices 9999..9994 + + + class TProgressActor // Global actor for progress form + { +// typedef TThread inherited; + public: + TProgressActor() /*# overload */; + virtual void Execute(); + virtual void Doterminate(); + ~TProgressActor() + + //*******************************Private components***************************** + ; + protected: + std::string FMessage, Msg_Cmd; + //*******************************Public components****************************** + public: + }; + + + + extern bool DLLFirstTime; + extern TTextRec DLLDebugFile; + extern String ProgramName; + extern TIniRegSave DSS_Registry; // Registry (See Executive) + + // Global variables for the OpenDSS Viewer + + extern bool DSS_Viz_installed; // OpenDSS viewer (flag to mark a local installation) + + extern String DSS_Viz_path; + extern bool DSS_Viz_enable; + + // Global variables for OpenDSS-GIS + + extern bool DSS_GIS_installed; // OpenDSS-GIS (flag to mark a local installation) + + extern String DSS_GIS_path; + extern bool IsDLL, NoFormsAllowed; + extern std::vector < TDSSCircuit* > ActiveCircuit; + extern std::vector < TDSSClass* > ActiveDSSClass; + extern std::vector < int > LastClassReferenced; // index of class of last thing edited + + extern std::vector < void* > ActiveDSSObject; + extern int NumCircuits; + extern int MaxCircuits; + extern int MaxBusLimit; // Set in Validation + + extern int MaxAllocationIterations; + extern TPointerList Circuits; + extern std::vector < TPointerList > DSSObjs; + extern std::vector < TParser* > AuxParser; // Auxiliary parser for use by anybody for reparsing values + + //{****} DebugTrace:TextFile; + + extern bool ErrorPending; + extern int CmdResult, ErrorNumber; + extern String LastErrorMessage; + extern int DefaultEarthModel; + extern std::vector < int > ActiveEarthModel; + extern String LastFileCompiled; + extern bool LastCommandWasCompile; + extern complex CALPHA; /*120-degree shift constant*/ + extern double SQRT2; + extern double SQRT3; + extern double InvSQRT3; + extern double InvSQRT3x1000; + extern bool SolutionAbort; + extern bool InShowResults; + extern bool Redirect_Abort; + extern bool In_Redirect; + extern std::vector < bool > DIFilesAreOpen; + extern bool AutoShowExport; + extern bool AutoDisplayShowReport; + extern std::vector < bool > SolutionWasAttempted; + extern String GlobalHelpString; + extern String GlobalPropertyValue; + extern String GlobalResult; + extern String LastResultFile; + extern String VersionString; + extern bool LogQueries; + extern bool QueryFirstTime; + extern String QueryLogFileName; + extern TTextRec QueryLogFile; + extern String DefaultEditor; // normally, Notepad + + extern int DefaultFontSize; + extern String DefaultFontName; + extern TFontStyles DefaultFontStyles; + extern String DSSFileName; // Name of current exe or DLL + + extern String DSSDirectory; // where the current exe resides + + extern String StartupDirectory; // Where we started + + extern std::vector < String > DataDirectory; // used to be DSSDataDirectory + + extern std::vector < String > OutputDirectory; // output files go here, same as DataDirectory if writable + + extern std::vector < String > CircuitName_; // Name of Circuit with a "_" appended + + extern std::vector < pComplexArray > ActiveYPrim; // Created to solve the problems + + extern double DefaultBaseFreq; + extern double DaisySize; + + // Some commonly used classes so we can find them easily + + extern std::vector < TLoadShape* > LoadShapeClass; + extern std::vector < TTShape* > TShapeClass; + extern std::vector < TPriceShape* > PriceShapeClass; + extern std::vector < TXYcurve* > XYCurveClass; + extern std::vector < TGrowthShape *> GrowthShapeClass; + extern std::vector < TSpectrum* > SpectrumClass; + extern std::vector < TDSSSolution* > SolutionClass; + extern std::vector < TEnergyMeter* > EnergyMeterClass; + extern std::vector < TDSSFMonitor* > FMonitorClass; // By dahei UCF + extern std::vector < TDynamicExp* > TDynamicExpClass; + // FeederClass :TFeeder; + + extern std::vector < TDSSMonitor* > MonitorClass; + extern std::vector < TSensor* > SensorClass; + extern std::vector < TTCC_Curve* > TCC_CurveClass; + extern std::vector < TWireData* > WireDataClass; + extern std::vector < TCNData* > CNDataClass; + extern std::vector < TTSData* > TSDataClass; + extern std::vector < TLineSpacing* > LineSpacingClass; + extern std::vector < TStorage* > StorageClass; + extern std::vector < TPVSystem* > PVSystemClass; + extern std::vector WindGenClass; + extern std::vector ReactorClass; + extern std::vector < TInvControl* > InvControlClass; + extern std::vector < TExpControl* > ExpControlClass; + extern std::vector < TVsource* > ActiveVSource; // created on 01/14/2019 to facilitate actors to modify VSources while simulating + + extern std::vector < TStringList > EventStrings; + extern std::vector < TStringList > SavedFileList; + extern std::vector < TStringList > ErrorStrings; + extern std::vector < TPointerList > DSSClassList; // pointers to the base class types + + extern std::vector < THashList > ClassNames; + extern bool UpdateRegistry; // update on program exit + +#ifdef windows + extern __int64 CPU_Freq; // Used to store the CPU frequency +#else + extern int64_t CPU_Freq; // Used to store the CPU frequency +#endif + extern bool EventLogDefault; + extern int32 CPU_Cores; + extern int NumNUMA; // To store the number of NUMA nodes (should be the same as sockets) + + extern int32 CPU_Physical; + extern int ActiveActor; + extern int NumOfActors; + extern std::vector < int > ActorCPU; + extern std::vector < std::atomic > ActorStatus; + extern std::vector < int > ActorProgressCount; + //extern TProgress* ActorProgress; + extern std::vector < int > ActorPctProgress; + extern std::vector < TSolver* > ActorHandle; + + extern string RepTermination; + + //***********************A-Diakoptics suite globals***************************** + // To indicate if the tearing process will take place using the link branches given by the user + + extern bool AllActors, ADiakoptics, ADiak_Init, ADiak_PCInj, UseUserLinks, Parallel_enabled, ConcatenateReports, ProgressCmd, IncMat_Ordered; + extern std::vector < TParser* > Parser; + extern std::vector < TEvent > ActorMA_Msg; // Array to handle the events of each actor + + // Default ports + + extern int DSSPrgPort, DSSGISPort; + + + /******************************************************************************** + * Nomenclature: * + * OV_ Overloads * + * VR_ Voltage report * + * DI_ Demand interval for each meter. Moved to EnergyMeter.pas* + * SDI_ System Demand interval * + * TDI_ DI Totals * + * FM_ Meter Totals * + * SM_ System Meter * + * EMT_ Energy Meter Totals * + * PHV_ Phase Voltage Report. Moved to EnergyMeter.pas * + * These prefixes are applied to the variables of each file mapped into * + * Memory using the MemoryMap_Lib * + ******************************************************************************** + */ + extern std::vector < TBytesStream* > OV_MHandle; // a. Handle to the file in memory + + extern std::vector < TBytesStream* > VR_MHandle; + extern std::vector < TBytesStream* > SDI_MHandle; + extern std::vector < TBytesStream* > TDI_MHandle; + extern std::vector < TBytesStream* > SM_MHandle; + extern std::vector < TBytesStream* > EMT_MHandle; + extern std::vector < TBytesStream* > FM_MHandle; + + //*********** Flags for appending Files***************************************** + + extern std::vector < bool > OV_Append; + extern std::vector < bool > VR_Append; + extern std::vector < bool > DI_Append; + extern std::vector < bool > SDI_Append; + extern std::vector < bool > TDI_Append; + extern std::vector < bool > SM_Append; + extern std::vector < bool > EMT_Append; + extern std::vector < bool > PHV_Append; + extern std::vector < bool > FM_Append; + + //***********************Seasonal QSTS variables******************************** + + extern bool SeasonalRating; // Tells the energy meter if the seasonal rating feature is active + + extern String SeasonSignal; // Stores the name of the signal for selecting the rating dynamically + + extern std::vector < TExecutive* > DSSExecutive; + extern TDSSClasses* DSSClasses; + extern std::vector < TIsource* > IsourceClass; + extern std::vector < TVsource* > VSourceClass; + + //************************ Progress actor Global defs*************************** + + extern bool DSSProgressFrm, IsProgressON; + extern std::vector < TProgressActor* > Progress_Actor; + extern String DSSProgressPath; + + //************************ OpenDSS-GIS Global defs*************************** + + extern bool IsGISON; + extern String GISThickness, GISColor; + extern pDoubleArray GISCoords; + + //************************ Line related Global defs*************************** + + extern TCommandList LineTypeList; + + //********************* Globals for DirectDLL Interface *********************** + + extern vector myStrArray; + extern vector myDblArray; + extern vector myCmplxArray; + extern vector myPolarArray; + extern vector myIntArray; + extern int FPropIndex; // for DSSProperties API + + // For functions previously in DYMatrix.pas + extern void* Yhandle; + extern unsignedint NumNZ, NumBuses; + extern int* YColumns; + extern int* YRows; + extern complex* YValues; + + + void WriteStr2Array(String myStr); + String BArray2Str(void* myPtr, int* idx); + String Char0(); + + void DoErrorMsg(const String S, const String Emsg, const String ProbCause, int ErrNum); + void DoSimpleMsg(const String S, int ErrNum); + void DoThreadSafeMsg(const String S, int ErrNum); + void ClearAllCircuits(); + void SetObject(const String param); + int SetActiveBus(const String BusName); + void SetDataPath(const String PathName); + void SetLastResultFile(const String Fname); + void MakeNewCircuit(const String Name); + void AppendGlobalResult(const String S); + void AppendGlobalResultCRLF(String S); // Separate by CRLF + + void ResetQueryLogFile(); + void WriteQueryLogFile(const String Prop, const String S); + void WriteDLLDebugFile(const String S); + void ReadDSS_Registry(); + void WriteDSS_Registry(); + bool IsDSSDLL(String Fname); + std::string GetOutputDirectory(); + void MyReallocMem(void*& p, int newsize); + void* MyAllocMem(unsignedint nbytes); + void New_Actor_Slot(); + void New_Actor(int ActorID); + void Wait4Actors(int WType); + void DoClone(); + void Delay(int TickTime); + void GetDefaultPorts(); +#ifdef windows + void Show_COM_Help(); +#endif + string GetLineTypes(); + void DSSGlobals_initialization(); + void DSSGlobals_finalization(); + +} // DSSGlobals + + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSGlobals; +#endif + +#endif // DSSGlobalsH + + + + + + + + diff --git a/OpenDSSC/Common/Diakoptics.cpp b/OpenDSSC/Common/Diakoptics.cpp new file mode 100644 index 0000000..47e29ce --- /dev/null +++ b/OpenDSSC/Common/Diakoptics.cpp @@ -0,0 +1,778 @@ + + +#pragma hdrstop + +#include "Diakoptics.h" + +#include "Circuit.h" +#include "Solution.h" +#include "DSSGlobals.h" +#include "DSSClassDefs.h" +#include "EnergyMeter.h" +#include "SolutionAlgs.h" +#include "Line.h" +#include "CmdForms.h" + +#include "ExecHelper.h" +#include "Executive.h" +#include "ParserDel.h" +#include "YMatrix.h" +#include "klusolve.h" +#include "Ucomplex.h" +#include "Sparse_Math.h" +#include "Ucmatrix.h" +#include +#include "dirsep.h" + + + + +/******************************************************************************** +* This is the A-Diakoptics algorithm executed by the * +* Coordinator (Actor = 1) * +********************************************************************************/ + + +int Solve_Diakoptics( ) +{ + int result = 0; + int i = 0, myRow = 0; + TSparse_Complex Vpartial; + /*Space left empty to implement the simplified Diakoptics algorithm*/ + /*# with ActiveCircuit[1], ActiveCircuit[1]->Solution do */ + { + auto with0 = ActiveCircuit[1]; + auto with1 = ActiveCircuit[1]->Solution; + { + + // Solves the partial systems to find the voltages at the edges of the sub-systems + with1->SendCmd2Actors( SOLVE_AD1 ); + Vpartial = TSparse_Complex(); + Vpartial.sparse_matrix_Cmplx( with0->Contours.NCols(), 1); + // Does the voltage diff calculation using the partial results + myRow = 0; + for ( int stop = (with0->Contours.NCols() - 1), i = 0; i <= stop; i++) + { + Vpartial.Insert( i, 0, csub( with1->NodeV[with0->Contours.CData[myRow].Row + 1], with1->NodeV[with0->Contours.CData[myRow + 1].Row + 1] ) ); + myRow = myRow + 2; + } + // Loads the partial solution considering the previous iteration + Vpartial = with0->Y4.multiply( &Vpartial ); + with0->Ic = with0->Contours.multiply( &Vpartial ); // Calculates the new Injecting Currents + + // Commands the actors to complement the solution + with1->SendCmd2Actors( SOLVE_AD2 ); + } + } + ActiveCircuit[1]->Issolved = true; + ActiveCircuit[1]->Set_BusNameRedefined(false); + if ( SolutionAbort ) + ActiveCircuit[1]->Issolved = false; + ActiveActor = 1; // Returns the control to Actor 1 + result = 0; + //free(Vpartial); + return result; +} + +/******************************************************************************** +* Returns a string with the partitioning statistics * +* It only works if the partitioning was succesful * +********************************************************************************/ + + +String get_Statistics( ) +{ + String result; + std::vector unbalance; + std::vector ASize; + int idx = 0; + double GReduct = 0.0, MaxImbal = 0.0, AvgImbal = 0.0; + ASize.clear(); + for ( int stop = NumOfActors, idx = 2; idx <= stop; idx++) + { + ASize.push_back( ActiveCircuit[idx]->NumNodes ); + } + GReduct = ( 1 - ( double( MaxValue( &ASize ) ) / ActiveCircuit[1]->NumNodes ) ) * 100; // The biggest actor + unbalance.resize( ASize.size() ); + for ( int stop = ASize.size() - 1, idx = 0; idx <= stop; idx++) + unbalance[idx] = ( 1 - ( ASize[idx] / MaxValue( &ASize ) ) ) * 100; // All the unbalances + MaxImbal = MaxValue( &unbalance ); // Max imbalance + AvgImbal = mean( &unbalance ); // Average + // publishes the results + result = CRLF + "Circuit reduction (%): " + FloatToStrF( GReduct, ffGeneral, 4, 2 ) + CRLF + + "Max imbalance (%): " + FloatToStrF( MaxImbal, ffGeneral, 4, 2 ) + CRLF + + "Average imbalance(%): " + FloatToStrF( AvgImbal, ffGeneral, 4, 2 ) + CRLF; + return result; +} + +/******************************************************************************** +* Sets the memory index for each actor so they can write * +* directly into the coordinator's Voltage vector * +********************************************************************************/ + + +void SendIdx2Actors( ) +{ + int i = 0, j = 0, k = 0; + String BusName; + std::vector AllNNames; +// Gets the names of the nodes in the interconnected system + AllNNames.resize( 0 ); + /*# with ActiveCircuit[1] do */ + { + auto with0 = ActiveCircuit[1]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + BusName = with0->BusList.Get( i ); + for ( int stop = with0->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + AllNNames.push_back( BusName + "." + IntToStr(with0->Buses[i - 1]->GetNum( j ) ) ); + } + } + } + } +// Sets the index for each actor +// The feeder head first + ActiveCircuit[2]->VIndex = 0; +// Then checks the rest of the actors + for ( int stop = NumOfActors, i = 3; i <= stop; i++) + { + BusName = ActiveCircuit[i]->BusList.Get( 1 ) + ".1"; + // Looks for the node within all the Node Names in the interconnected model + for ( int stop = AllNNames.size() - 1, j = 0; j <= stop; j++) + if ( BusName == AllNNames[j] ) + break; + ActiveCircuit[i]->VIndex = j; + } + // Initializes the Ic vector with zeros + ActiveCircuit[1]->Ic.sparse_matrix_Cmplx( AllNNames.size(), 1 ); + ActiveCircuit[1]->V_0.sparse_matrix_Cmplx( AllNNames.size(), 1 ); + for ( int stop = AllNNames.size() - 1, i = 0; i <= stop; i++) + { + ActiveCircuit[1]->Ic.Insert( i, 0, CZero ); + ActiveCircuit[1]->V_0.Insert( i, 0, CZero ); + } +} + +/******************************************************************************** +* Inverts ZCC to obtain its admittance equivalent Y4 * +* This is the heart of A-Diakoptics * +********************************************************************************/ + + +void Calc_Y4( ) +{ + complex Value; + int NumRows = 0, NumCols = 0, col = 0, idx = 0; + TcMatrix TempMat; +// 4 Debugging +// myFile : TextFile; +// Text : String; + /*# with ActiveCircuit[1], ActiveCircuit[1]->Solution do */ + { + auto with0 = ActiveCircuit[1]; + { + // Moves ZCC into an equivalent compatible with TcMatrix + TempMat = TcMatrix(with0->ZCC.NRows() ); + for ( int stop = with0->ZCC.CData.size() - 1, idx = 0; idx <= stop; idx++) + { + TempMat.SetElement(with0->ZCC.CData[idx].Row + 1, with0->ZCC.CData[idx].col + 1, with0->ZCC.CData[idx].Value ); + } + // Inverts the ZCC equivalent + TempMat.Invert(); + with0->Y4.sparse_matrix_Cmplx(with0->ZCC.NRows(), with0->ZCC.NCols()); + NumRows = with0->ZCC.NRows() - 1; + NumCols = with0->ZCC.NCols() - 1; + // Moves the inverse into Y4 for furhter use + for ( int stop = NumRows, idx = 0; idx <= stop; idx++) + { + for ( int stop = NumCols, col = 0; col <= stop; col++) + { + Value = TempMat.GetElement( idx + 1, col + 1 ); + if ( ( Value.re != 0 ) && ( Value.re != 0 ) ) + with0->Y4.Insert( idx, col, Value ); + } + } +//********************Dbug************************************ +/* + AssignFile(myFile, 'C:\Temp\Y4Mat.csv'); + ReWrite(myFile); + IOResultToException(); + Text := ''; + for idx := 0 to (length(Y4.CData)- 1) do + Begin + Text := inttostr(Y4.CData[idx].Row) + ',' + inttostr(Y4.CData[idx].Col) + + ',' + floattostr(Y4.CData[idx].Value.re); + if Y4.CData[idx].Value.im < 0 then + Text := Text + '-i' + floattostr(-1*Y4.CData[idx].Value.im) + else + Text := Text + '+i' + floattostr(Y4.CData[idx].Value.im); + WriteLn(myFile,Text); + End; + CloseFile(myFile); +*/ + } + } +} + +/******************************************************************************** +* Calculates the Connections matrix ZCC in the * +* contours-contours domain * +********************************************************************************/ + + +void Calc_ZCC( int Links ) +{ + int Row = 0, col = 0, idx3 = 0, idx2 = 0, idx = 0; + unsigned int NNodes = 0; + pComplexArray CVector, ZVector; + complex Ctemp; +// 4 Debugging +// myFile : TextFile; +// Text : String; + /*# with ActiveCircuit[1], ActiveCircuit[1]->Solution do */ + { + auto with0 = ActiveCircuit[1]; + { + GetSize(with0->Solution->hY, &NNodes ); + col = NNodes; + Links--; + with0->ZCT.sparse_matrix_Cmplx( col, Links * 3 ); + CVector = new complex[ (col + 1) ]; + ZVector = new complex[ (col + 1) ]; + idx3 = Links * 3 - 1; + for ( int stop = idx3, idx2 = 0; idx2 <= stop; idx2++) + { + for ( int stop = col, idx = 1; idx <= stop; idx++) + CVector[idx] = CZero; // Makes it zero + for ( int stop = Length( &( with0->Contours.CData ) ), idx = 1; idx <= stop; idx++) + { + if ( with0->Contours.CData[idx - 1].col == idx2 ) + { + Row = with0->Contours.CData[idx - 1].Row + 1; + CVector[Row] = with0->Contours.CData[idx - 1].Value; + } + } + SolveSparseSet(with0->Solution->hY,(complex*) &(ZVector[1]), (complex*) (&CVector[1]) ); + for ( int stop = col, idx = 1; idx <= stop; idx++) // inserts result into the ZCT matrix + { + Ctemp = ZVector[idx]; + if ( ( Ctemp.re != 0 ) && ( Ctemp.im != 0 ) ) + with0->ZCT.Insert( ( idx - 1 ), idx2, ZVector[idx] ); + } + idx = col; + } + // At this point we have calculated the right side of the equation + // ZCC = CTZ(TT)C -> Z(TT)C + // It is needed transpose the contours matrix and multiply it + with0->ContoursT = with0->Contours.Transpose(); + with0->ZCC = with0->ContoursT.multiply(&with0->ZCT ); // Calculates ZCC with no Link impedances + with0->ZCC = with0->ZCC.Add(&with0->ZLL ); // Adds the link impedance + free( CVector ); + free( ZVector ); +//********************Dbug************************************ +/* + AssignFile(myFile, 'C:\Temp\ZCCMat.csv'); + ReWrite(myFile); + IOResultToException(); + Text := ''; + for idx2 := 0 to (length(ZCC.CData)- 1) do + Begin + Text := inttostr(ZCC.CData[idx2].Row) + ',' + inttostr(ZCC.CData[idx2].Col) + + ',' + floattostr(ZCC.CData[idx2].Value.re); + if ZCC.CData[idx2].Value.im < 0 then + Text := Text + '-i' + floattostr(-1*ZCC.CData[idx2].Value.im) + else + Text := Text + '+i' + floattostr(ZCC.CData[idx2].Value.im); + WriteLn(myFile,Text); + End; + CloseFile(myFile); +*/ + } + } +} + +/******************************************************************************** +* Calculates the contours matrix based * +* on the location in the graph of the link branches * +* if there is an error returns <> 0 * +********************************************************************************/ + + +int Calc_C_Matrix( PString PLinks, int NLinks ) +{ + int result = 0; + int LIdx = 0, k = 0, l = 0, j = 0, CDirection = 0, NumPhases = 0, i = 0; + std::vector < std::string> Elem_Buses, Node_Names; + String temp; + bool Go_Flag = false; + TTextRec myFile; // For debugging + ActiveActor = 1; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + result = 0; + Elem_Buses.resize( 2 ); + Node_Names.clear(); + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + /*# with MapNodeToBus^[i] do */ + { + auto with1 = with0->MapNodeToBus[i - 1]; + Node_Names.push_back( Format( "%s.%-d", LowerCase( with0->BusList.Get( with1.BusRef ) ).c_str(), with1.NodeNum)); + } + } + with0->Contours.sparse_matrix_Cmplx( Node_Names.size(), ( NLinks - 1 ) * 3 ); + for ( int stop = ( NLinks - 1 ), LIdx = 1; LIdx <= stop; LIdx++) + { + PLinks++; // Pointing to the Next link branch (starting in 1) + temp = ( *PLinks ); + j = ansipos( ".", temp ); + temp = LowerCase( temp.substr( 0, ( j - 1 ) ) ); + if ( temp == "line" ) + { + i = with0->SetElementActive( (*PLinks ) ); + // Gest the names of the buses fot this PDElement + // If it is something different from a Transformer reports an error + // Since a link branch cannot be a transformer + for ( int stop = with0->get_FActiveCktElement()->Get_NTerms(), i = 1; i <= stop; i++) + { + Elem_Buses[i - 1] = with0->get_FActiveCktElement()->GetBus( i ); + j = ansipos( ".", Elem_Buses[i - 1] ); + if ( j != 0 ) + Elem_Buses[i - 1] = Elem_Buses[i - 1].substr( 0, j - 1 ); + else + Elem_Buses[i - 1] = Elem_Buses[i - 1] + "."; + } + // Marks the connection point in the contours matrix + NumPhases = with0->get_FActiveCktElement()->Get_NPhases(); + for ( int stop = NumPhases, l = 1; l <= stop; l++) + { + for ( int stop = 1, i = 0; i <= stop; i++) + { + temp = Elem_Buses[i] + IntToStr( l ); + Go_Flag = true; + j = 0; + while ( Go_Flag && ( j <= Node_Names.size() - 1 ) ) + { + k = ansipos( temp, Node_Names[j] ); + if ( k != 0 ) + { + if ( i == 0 ) + CDirection = 1; + else + CDirection = - 1; + with0->Contours.Insert( j, ( ( l - 1 ) + ( LIdx - 1 ) * 3 ), cmplx( CDirection, 0 ) ); + Go_Flag = false; + } + j++; + } + } + } + } + else + { + result = - 1; // There was an error when selecting the link branches (MeTIS) + break; // Abort + } + } + // More error checking + if ( result == 0 ) + { + if ( with0->Contours.NZero() != 0) + result = 0; + else + result = 1; + } + } + } + return result; +} + +/******************************************************************************** +* Calculates the Link branches matrix for further use * +* if there is an error returns <> 0 * +********************************************************************************/ + + +int Calc_ZLL( PString PLinks, int NLinks ) +{ + int result = 0; + int NValues = 0, idx = 0, k = 0, j = 0, Row = 0, col = 0, count = 0, i = 0; + pComplexArray cValues; + bool ErrorFlag = false; + TSparse_Complex localMat; + TcMatrix LinkPrim; + NLinks--; + ErrorFlag = false; + LinkPrim = TcMatrix( 3 ); + ActiveActor = 1; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + with0->ZLL.sparse_matrix_Cmplx( NLinks * 3, NLinks * 3 ); + for ( int stop = NLinks, i = 1; i <= stop; i++) + { + PLinks++; + idx = with0->SetElementActive( (*PLinks ) ); + if (with0->get_FActiveCktElement() != NULL ) + /*# with ActiveCktElement do */ + { + auto with1 = with0->get_FActiveCktElement(); + NValues = sqr( with1->Yorder ); + cValues = with1->GetYPrimValues( ALL_YPRIM ); // Get pointer to complex array of values + if ( cValues != NULL ) + { + k = 1; + idx = ( i - 1 ) * 3; + Row = 1; + col = 1; + count = 0; + // Extracts the YPrim of the Link branch + for ( int stop = ( NValues / 4 ), j = 1; j <= stop; j++) + { + LinkPrim.SetElement( Row, col, cValues[k] ); + count++; + if ( count > 2 ) + { + Row++; + col = 1; + count = 0; + k = k + 4; + } + else + { + col++; + k++; + } + } + // Inverts the Y primitive + LinkPrim.Invert(); + // Inserts the Z primitive values into ZLL + Row = 0; + col = 0; + count = 0; +/**/ + for ( int stop = ( NValues / 4 ), j = 1; j <= stop; j++) + { + with0->ZLL.Insert( ( Row + idx ), ( col + idx ), LinkPrim.GetElement( Row + 1, col + 1 ) ); + count++; + if ( count > 2 ) + { + Row++; + col = 0; + count = 0; + } + else + col++; + } +/* */ + } + else + ErrorFlag = true; + } + } + if ( ErrorFlag ) + result = 1; + else + result = 0; + } + } + return result; +} + +/******************************************************************************** +* Tears the system using considering the number of * +* circuits specified by the user * +* The flag AddISrc indicates if its necessary to create * +* Isources at the edges of the link branches, the ISource * +* magnitude is equal to 0.000001, angle 0 (for A-Diakoptics) * +********************************************************************************/ + + +int ADiakoptics_Tearing( bool AddISrc ) +{ + int result = 0; + + // Stores the previous solution mode + + int Prev_Mode = 0 // Stores the number of Sub-Circuits created + , Num_Ckts = 0; + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = ActiveCircuit[ActiveActor]->Solution; + { + ActiveActor = 1; + Num_Ckts = with0->Tear_Circuit( ); + Prev_Mode = with1->DynaVars.SolutionMode; + with1->DynaVars.SolutionMode = 0; // Shapshot mode + DSSExecutive[ActiveActor]->Set_Command("set controlmode=off"); + BuildYMatrix( WHOLEMATRIX, false, ActiveActor ); +// DoSolveCmd(); + if ( ! SolutionAbort ) + { + with0->Save_SubCircuits( AddISrc ); + with1->DynaVars.SolutionMode = Prev_Mode; // Goes back to the previous solution mode + ActiveCircuit[1]->Num_SubCkts = Num_Ckts; + GlobalResult = "Sub-Circuits Created: " + IntToStr( Num_Ckts ); + result = 0; + } + else + { + GlobalResult = "There was an error when tearing the circuit "; + result = 1; + } + } + } + return result; +} + +/******************************************************************************** +* Generates the subsystems, actors and memory space * +* For using the A-Diakoptics parallelism * +********************************************************************************/ + + +void ADiakopticsInit( ) +{ + TEnergyMeterObj* EMeter; + int j = 0, Local_State = 0, Num_States = 0, ErrorCode = 0, DIdx = 0, Diak_Actors = 0; + String Dir, Proj_Dir, prog_Str, ErrorStr, Fileroot; + std::vector Links; // List of the Link Branches + + bool MQuit = false; // To quit the State Machine + +// The program is built as a state machine to facilitate the error detection +// and quitting the routines after an error is detected wihtout killing the prog + MQuit = false; + Num_States = 9; // Number of states of the machine + Local_State = 0; // Current state + prog_Str = "A-Diakoptics initialization summary:" + CRLF + CRLF; + ActiveActor = 1; + // Checks if the number of actors is within a reasonable limit + if ( ActiveCircuit[1]->Num_SubCkts > ( CPU_Cores - 2 ) ) + ActiveCircuit[1]->Num_SubCkts = CPU_Cores - 2; + while ( ! MQuit ) + { + switch ( Local_State ) + { + case 0: + { // Create subcircuits + prog_Str = prog_Str + "- Creating Sub-Circuits..." + CRLF; + ErrorCode = ADiakoptics_Tearing( false ); + if ( ErrorCode != 0 ) + ErrorStr = "Error" + CRLF + "The circuit cannot be decomposed" + CRLF; + else + ErrorStr = " " + IntToStr( ActiveCircuit[1]->Num_SubCkts ) + " Sub-Circuits Created" + CRLF; + prog_Str = prog_Str + ErrorStr; + } + break; + case 1: + { // Saves the Link Branch list locally + Diak_Actors = ActiveCircuit[1]->Num_SubCkts + 1; + prog_Str = prog_Str + "- Indexing link branches..."; + Links.resize( ActiveCircuit[1]->Link_Branches.size() ); + for ( int stop = Links.size() - 1, DIdx = 0; DIdx <= stop; DIdx++) + Links[DIdx] = ActiveCircuit[1]->Link_Branches[DIdx]; + prog_Str = prog_Str + "Done"; + ErrorCode = 0; // No error handling here + } + break; + case 2: + { // Compile subsystems + ErrorCode = 0; + prog_Str = prog_Str + CRLF + "- Setting up the Actors..."; + // Clears everything to create the actors and compile the subsystems + Parallel_enabled = false; + DSSExecutive[ActiveActor]->ClearAll(); + Fileroot = GetCurrentDir(); // Gets the current directory + SolutionAbort = false; + + // Compiles the interconnected Circuit for further calculations on actor 1 + ActiveActor = 1; + Proj_Dir = String( "compile \"" ) + Fileroot + DIRSEP_STR "Torn_Circuit" DIRSEP_STR "master_interconnected.dss\""; + DSSExecutive[ActiveActor]->Set_Command(Proj_Dir); + DSSExecutive[ActiveActor]->Set_Command("set controlmode=Off"); + // Disables the Energymeters for the zones + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + EMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_First(); + while ( EMeter != NULL ) + { + j = ansipos( "zone_", ( (TDSSObject*) EMeter )->get_Name() ); + if ( j != 0 ) + ( (TDSSCktElement*) EMeter )->Set_Enabled(false); + EMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_Next(); + } + } + } + BuildYMatrix( WHOLEMATRIX, false, ActiveActor ); + DoSolveCmd(); + ActiveActor = 1; + // Creates the other actors + for ( int stop = Diak_Actors, DIdx = 2; DIdx <= stop; DIdx++) + { + New_Actor_Slot( ); + if ( DIdx == 2 ) + Dir = ""; + else + Dir = "zone_" + IntToStr( DIdx - 1 ) + DIRSEP_STR; + Proj_Dir = String( "compile \"" ) + Fileroot + DIRSEP_STR "Torn_Circuit" DIRSEP_STR + Dir + "master.dss\""; + DSSExecutive[ActiveActor]->Set_Command(Proj_Dir); + if ( DIdx > 2 ) + DSSExecutive[ActiveActor]->Set_Command(Links[DIdx - 2] + ".enabled=False"); + DSSExecutive[ActiveActor]->Set_Command("set controlmode=Off"); + DoSolveCmd(); + if ( SolutionAbort ) + { + ErrorCode = 1; + break; + } + } + if ( ErrorCode != 0 ) + ErrorStr = "Error" + CRLF + "One or sub-systems cannot be compiled" + CRLF; + else + { + ErrorStr = "Done"; + } + prog_Str = prog_Str + ErrorStr; + } + break; + case 3: + { + // Opens the link branches in the interconnected Circuit and recalculates the YBus + // The opening happens by replacing the line with a very high series impedance + ActiveActor = 1; + prog_Str = prog_Str + CRLF + "- Opening link branches..."; + for ( int stop = Links.size() - 1, DIdx = 1; DIdx <= stop; DIdx++) + { + ActiveCircuit[ActiveActor]->SetElementActive( ((String) Links[DIdx] ) ); + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_Enabled(false); + } + ActiveCircuit[ActiveActor]->Set_BusNameRedefined(false); + BuildYMatrix( WHOLEMATRIX, false, ActiveActor ); + prog_Str = prog_Str + "Done"; + ErrorCode = 0; // No error handling here + } + break; + case 4: + { // Creates the contours matrix + ActiveActor = 1; + prog_Str = prog_Str + CRLF + "- Building Contours..."; + // Builds the contour matrix + ErrorCode = Calc_C_Matrix( &Links[0], Links.size() ); + if ( ErrorCode != 0 ) + ErrorStr = "Error" + CRLF + "One or more link branches are not lines" + CRLF; + else + ErrorStr = "Done"; + prog_Str = prog_Str + ErrorStr; + } + break; + case 5: + { // Builds the ZLL matrix + ActiveActor = 1; + prog_Str = prog_Str + CRLF + "- Building ZLL..."; + ErrorCode = Calc_ZLL( &Links[0], Links.size() ); + if ( ErrorCode != 0 ) + ErrorStr = "Error"; + else + ErrorStr = "Done"; + prog_Str = prog_Str + ErrorStr; + } + break; + case 6: + { // Builds the ZCC matrix + prog_Str = prog_Str + CRLF + "- Building ZCC..."; + Calc_ZCC( Links.size() ); + prog_Str = prog_Str + "Done"; + } + break; + case 7: + { // Inverts ZCC to get Y4 + prog_Str = prog_Str + CRLF + "- Building Y4 ..."; + Calc_Y4( ); + prog_Str = prog_Str + "Done"; + // Moves back the link branches list into actor 1 for further use + ActiveCircuit[1]->Link_Branches.resize( Links.size() ); + for ( int stop = Links.size() - 1, DIdx = 0; DIdx <= stop; DIdx++) + ActiveCircuit[1]->Link_Branches[DIdx] = Links[DIdx]; + } + break; + case 8: + { // Sends the index to the actors for uploading info + prog_Str = prog_Str + CRLF + "- Assigning indexes to actors ..."; + SendIdx2Actors( ); + prog_Str = prog_Str + "Done"; + } + break; + case 9: + { // Prints the statistics of the partitioning + prog_Str = prog_Str + CRLF + CRLF + "Partitioning statistics"; + prog_Str = prog_Str + get_Statistics( ); + // Assigns the processor per actor + for ( int stop = NumOfActors, DIdx = 1; DIdx <= stop; DIdx++) + { + ActorCPU[DIdx] = DIdx; + if ( ActorHandle[DIdx] != NULL ) + { + //ActorHandle[DIdx]->CPU = ActorCPU[DIdx]; + //ActorHandle[DIdx]->Priority = 6; + } + } + // Compiles the interconnected Circuit for further calculations on actor 1 + ActiveActor = 1; + prog_Str = prog_Str + CRLF + "- Closing link branches..."; + for ( int stop = Links.size() - 1, DIdx = 1; DIdx <= stop; DIdx++) + { + ActiveCircuit[ActiveActor]->SetElementActive( ((String) Links[DIdx] ) ); + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_Enabled(true); + } + ActiveCircuit[ActiveActor]->Set_BusNameRedefined(false); + BuildYMatrix( WHOLEMATRIX, false, ActiveActor ); + ActiveCircuit[ActiveActor]->Solution->SendCmd2Actors( INIT_ADIAKOPTICS ); + ADiak_Init = true; + } + break; + default: + { + } + } + Local_State++; + MQuit = ( Local_State > Num_States ) || ( ErrorCode != 0 ); + } + ActiveActor = 1; + if ( ErrorCode != 0 ) + { + ErrorStr = "One or more errors found"; + ADiakoptics = false; + } + else + { + ErrorStr = "A-Diakoptics initialized"; + Parallel_enabled = true; + ADiakoptics = true; + ADiak_Init = false; // Needed to force the subzones to remove VSource.Source + } + ProgressCmd = true; + prog_Str = CRLF + prog_Str + CRLF + ErrorStr + CRLF; + GlobalResult = ErrorStr; + GlobalResult = prog_Str; + // TEMc: TODO: should we report something here under FPC? + // Davis: Done: This will add the needed report + SolutionAbort = false; +} + + + + + + + + + diff --git a/OpenDSSC/Common/Diakoptics.h b/OpenDSSC/Common/Diakoptics.h new file mode 100644 index 0000000..326168f --- /dev/null +++ b/OpenDSSC/Common/Diakoptics.h @@ -0,0 +1,38 @@ +#ifndef DiakopticsH +#define DiakopticsH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + +*/ + + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + + +int Solve_Diakoptics( ); +int ADiakoptics_Tearing( bool AddISrc ); +void ADiakopticsInit( ); +int Calc_C_Matrix( PString PLinks, int NLinks ); +int Calc_ZLL( PString PLinks, int NLinks ); +void Calc_ZCC( int Links ); +void Calc_Y4( ); +void SendIdx2Actors( ); +String get_Statistics( ); + +#endif // DiakopticsH + + + + + + + + diff --git a/OpenDSSC/Common/EventQueue.h b/OpenDSSC/Common/EventQueue.h new file mode 100644 index 0000000..32cf75d --- /dev/null +++ b/OpenDSSC/Common/EventQueue.h @@ -0,0 +1,11 @@ + +//#include +//#pragma hdrstop + + + + + + + + diff --git a/OpenDSSC/Common/ExportCIMXML.cpp b/OpenDSSC/Common/ExportCIMXML.cpp new file mode 100644 index 0000000..99db6cf --- /dev/null +++ b/OpenDSSC/Common/ExportCIMXML.cpp @@ -0,0 +1,4620 @@ +#include "ExportCIMXML.h" + +#include "Sysutils.h" +#include "Utilities.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "CktElement.h" +#include "PDElement.h" +#include "PCElement.h" +#include "generator.h" +#include "Load.h" +#include "RegControl.h" +#include "VSource.h" +#include "Line.h" +#include "Transformer.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "LineCode.h" +#include "fuse.h" +#include "Capacitor.h" +#include "CapControl.h" +#include "CapControlVars.h" +#include "Reactor.h" +#include "Feeder.h" +#include "ConductorData.h" +#include "LineUnits.h" +#include "LineGeometry.h" +#include +#include "HashList.h" +#include "WireData.h" +#include "XfmrCode.h" +#include "LineSpacing.h" +#include "CableData.h" +#include "CNData.h" +#include "TSData.h" +#include "Storage.h" +#include "PVsystem.h" +#include "Relay.h" +#include "Recloser.h" +#include "AutoTrans.h" +#include "InvControl.h" +#include "ExpControl.h" +#include "DSSObject.h" +#include "DSSClass.h" + +#include "System.h" +#include + +/* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Write a CIM XML file using RDF Schema for the Common Distribution + Power System Model, IEC 61968-13.*/ + +enum UuidChoice {Bank, Wdg, XfCore, XfMesh, WdgInf, ScTest, OcTest, + BaseV, LinePhase, LoadPhase, GenPhase, CapPhase, SolarPhase, BatteryPhase, + XfLoc, LoadLoc, LineLoc, CapLoc, Topo, ReacLoc, SolarLoc, BatteryLoc, + OpLimV, OpLimI, LoadResp, CIMVer, PosPt, CoordSys, TopoIsland, Station, + GeoRgn, SubGeoRgn, ZData, OpLimT, XfInfo, FdrLoc, OpLimAHi, OpLimALo, + OpLimBHi, OpLimBLo, MachLoc, PVPanels, Battery, SrcLoc, TankInfo, + TapCtrl, PUZ, WirePos, NormAmps, EmergAmps, + I1547NameplateData, I1547NameplateDataApplied, I1547Signal, I1547VoltVar, + I1547WattVar, I1547ConstPF, I1547VoltWatt, I1547ConstQ, ECProfile}; + +enum ProfileChoice {FunPrf, EpPrf, GeoPrf, TopoPrf, CatPrf, SshPrf, DynPrf, NUM_PROFILE_CHOICES}; + +class TBankObject: public TNamedObject { + typedef TNamedObject inherited; +public: + String vectorGroup; + int maxWindings; + int nWindings; + std::vector connections; + bool bAuto; + std::vector angles; + std::vector phaseA; + std::vector phaseB; + std::vector phaseC; + std::vector ground; + TPDElement* pd_unit; // save this for writing the bank coordinates + TBankObject(int MaxWdg); + virtual ~TBankObject(); + void AddTransformer(TTransfObj& pXf); + void AddAutoTransformer(TAutoTransObj& pAuto); + void BuildVectorGroup(); +}; + +class TOpLimitObject: public TNamedObject { + typedef TNamedObject inherited; +public: + double NormAmps; + double EmergAmps; + TOpLimitObject(double norm, double emerg); + virtual ~TOpLimitObject(); +}; + +enum ECPChoice {LoadEcp, PvEcp, GenEcp, BatEcp}; + +class TECPObject: public TNamedObject { + typedef TNamedObject inherited; +public: + ECPChoice connType; + std::vector connections; + int nconn; + + String daily; + String duty; + String yearly; + String spectrum; + String cvr; + String growth; + String Tdaily; + String Tduty; + String Tyearly; + + TECPObject(ECPChoice choice); + virtual ~TECPObject(); + void AddConnection(TNamedObject& pObj); +}; + +class TFileDealer: public TObject { + typedef TObject inherited; +private: + // the Combined XML can be broken into seven separate profiles + TTextRec F_FUN; + TTextRec F_EP; + TTextRec F_SSH; + TTextRec F_CAT; + TTextRec F_GEO; + TTextRec F_TOPO; + TTextRec F_DYN; + String roots[NUM_PROFILE_CHOICES]; + TUuid ids[NUM_PROFILE_CHOICES]; +public: + bool Separate; + TFileDealer(bool Combined, const String& Filename); + virtual ~TFileDealer(); + void WriteCimLn(ProfileChoice prf, const String& S); + void StartInstance(ProfileChoice prf, const String& Root, TNamedObject& Obj); + void StartInstance(ProfileChoice prf, const String& Root, TNamedObject* Obj); + void StartFreeInstance( ProfileChoice prf, const String& Root, TUuid uuid); + void EndInstance(ProfileChoice prf, const String& Root); +}; + +class TRemoteSignalObject: public TNamedObject { + typedef TNamedObject inherited; +public: + String busName; + TDSSCktElement *pElem; + int trm; + String phase; // want A, B, C, s1 or s2 + TRemoteSignalObject(const String& aBusName, int seq, const String& invName); + virtual ~TRemoteSignalObject(); +}; + +class TIEEE1547Controller { +private: + double ND_acVmax, ND_acVmin, AD_pMax, AD_pMaxOverPF, AD_overPF, AD_pMaxUnderPF; + double AD_underPF, AD_sMax, AD_qMaxInj, AD_qMaxAbs, AD_pMaxCharge; + double AD_apparentPowerChargeMax, AD_acVnom; + double VV_vRef, VV_vRefOlrt, VV_curveV1, VV_curveV2, VV_curveV3, VV_curveV4; + double VV_olrt, VV_curveQ1, VV_curveQ2, VV_curveQ3, VV_curveQ4; + double Q_reactivePower, PF_powerFactor, VW_olrt, VW_curveV1, VW_curveV2; + double VW_curveP1, VW_curveP2gen, VW_curveP2load; + double WV_curveP1gen, WV_curveP2gen, WV_curveP3gen; + double WV_curveP1load, WV_curveP2load, WV_curveP3load; + double WV_curveQ1gen, WV_curveQ2gen, WV_curveQ3gen; + double WV_curveQ1load, WV_curveQ2load, WV_curveQ3load; + + String ND_normalOPcatKind, PF_constPFexcitationKind; + bool VV_enabled, WV_enabled, PF_enabled, Q_enabled, VW_enabled; + bool VV_vRefAutoModeEnabled; + + TNamedObject* pInvName; + TNamedObject* pPlateName; + TNamedObject* pSetName; + std::vector pDERNames; + std::vector pMonBuses; + std::vector Signals; + + bool bNameplateSet; + + void FinishNameplate(); + void SetStorageNameplate(TStorageObj& pBat); + void SetPhotovoltaicNameplate(TPVsystemObj& pPV); + void SetElementNameplate(TDSSCktElement& pElem); + void SetDefaults(bool bCatB); + void FindSignalTerminals(); + bool CheckSignalMatch(TRemoteSignalObject& sig, TDSSCktElement& pElm, int seq); +public: + TIEEE1547Controller(); + virtual ~TIEEE1547Controller(); + + void PullFromInvControl(TInvControlObj& pInv); + void PullFromExpControl(TExpControlObj& pExp); + void WriteCIM(ProfileChoice prf); +}; + +THashList uuidHash; // index is 1-based +std::vector UuidList; // index is 0-based +std::vector UuidKeyList; +THashList BankHash; +std::vector BankList; +THashList ECPHash; +std::vector ECPList; +THashList OpLimitHash; +std::vector OpLimitList; +TFileDealer* FD = nullptr; + +const string CIM_NS = "http://iec.ch/TC57/CIM100"; +const double CatBQmin = 0.43; // for IEEE 1547 Category B estimate + +TECPObject::TECPObject(ECPChoice choice): inherited("ECProfile") +{ + connType = choice; + nconn = 0; + connections.resize(10); +} + +TECPObject::~TECPObject() +{ +} + +void TECPObject::AddConnection(TNamedObject &pObj) +{ + int size = connections.size(); + if (nconn > size) + connections.resize(2 * size); + connections[nconn] = pObj.Get_UUID(); + nconn++; +} + +void StartCIMFile(Textfile& F, const String &Filenm, ProfileChoice prf); + +void TFileDealer::WriteCimLn(ProfileChoice prf, const String& s) +{ + if (Separate) + { + if (prf != FunPrf) + { + if (roots[prf].size() < 1) + { + StartFreeInstance(prf, roots[FunPrf], ids[FunPrf]); + } + } + switch(prf) + { + case FunPrf: + WriteLn(F_FUN, s); + break; + case EpPrf: + WriteLn(F_EP, s); + break; + case GeoPrf: + WriteLn(F_GEO, s); + break; + case TopoPrf: + WriteLn(F_TOPO, s); + break; + case CatPrf: + WriteLn(F_CAT, s); + break; + case SshPrf: + WriteLn(F_SSH, s); + break; + case DynPrf: + WriteLn(F_DYN, s); + break; + } + } + else + { + WriteLn(F_FUN, s); + } +} + +TFileDealer::TFileDealer(bool Combined, const String& FileName) +{ + int i; + Separate = !Combined; + if (Separate) + { + for (i = 0; i < NUM_PROFILE_CHOICES; ++i) + roots[i] = ""; + StartCIMFile(F_FUN, FileName + "_FUN.XML", FunPrf); + StartCIMFile(F_GEO, FileName + "_GEO.XML", GeoPrf); + StartCIMFile(F_TOPO, FileName + "_TOPO.XML", TopoPrf); + StartCIMFile(F_SSH, FileName + "_SSH.XML", SshPrf); + StartCIMFile(F_CAT, FileName + "_CAT.XML", CatPrf); + StartCIMFile(F_EP, FileName + "_EP.XML", EpPrf); + StartCIMFile(F_DYN, FileName + "_DYN.XML", EpPrf); + } + else + { + StartCIMFile(F_FUN, FileName, FunPrf); + } +} + +void TFileDealer::StartInstance(ProfileChoice prf, const String& Root, TNamedObject& Obj) +{ + if (Separate) + { // must be first to avoid stack overflow in WriteCimLn + roots[prf] = Root; + ids[prf] = Obj.Get_UUID(); + } + WriteCimLn(prf, Format("", Root.c_str(), Obj.Get_CIM_ID().c_str())); + WriteCimLn(prf, Format(" %s", Obj.Get_CIM_ID().c_str())); + WriteCimLn(prf, Format(" %s", Obj.LName.c_str())); +} + +void TFileDealer::StartInstance(ProfileChoice prf, const String& Root, TNamedObject* Obj) +{ + StartInstance(prf, Root, *Obj); +} + +void TFileDealer::StartFreeInstance(ProfileChoice prf, const String& Root, TUuid uuid) +{ + if (Separate) + { // must be first to avoid stack overflow in WriteCimLn + roots[prf] = Root; + ids[prf] = uuid; + } + WriteCimLn(prf, Format("", Root.c_str(), UUIDToCIMString(uuid).c_str())); +} + +void TFileDealer::EndInstance(ProfileChoice prf, const String& Root) +{ + int i; + if (Separate) + { + for (i = 0; i < NUM_PROFILE_CHOICES; ++i) + { + if (roots[i].size() > 0) + { + WriteCimLn((ProfileChoice) i, Format("", Root.c_str())); + roots[i] = ""; + } + } + } + else + { + WriteCimLn(prf, Format("", Root.c_str())); + } +} + +TFileDealer::~TFileDealer() +{ + WriteLn(F_FUN, ""); + CloseFile(F_FUN); + if (Separate) + { + WriteLn(F_GEO, ""); + WriteLn(F_CAT, ""); + WriteLn(F_SSH, ""); + WriteLn(F_TOPO, ""); + WriteLn(F_EP, ""); + WriteLn(F_DYN, ""); + CloseFile(F_GEO); + CloseFile(F_CAT); + CloseFile(F_SSH); + CloseFile(F_TOPO); + CloseFile(F_EP); + CloseFile(F_DYN); + } +} + +void ParseSwitchClass(TLineObj& pLine, String& swtCls, double& ratedAmps, double& breakingAmps) +{ + TFuseObj* pFuse; + TRelayObj* pRelay; + TRecloserObj* pRecloser; + + swtCls = "LoadBreakSwitch"; + ratedAmps = pLine.NormAmps; + breakingAmps = ratedAmps; + pFuse = (TFuseObj*) ActiveCircuit[ActiveActor]->Fuses.Get_First(); + while ((pFuse != nullptr)) + { + if (pFuse->FControlledElement == &pLine) + { + swtCls = "Fuse"; + ratedAmps = pFuse->RatedCurrent; + breakingAmps = 0.0; + return; + } + pFuse = (TFuseObj*) ActiveCircuit[ActiveActor]->Fuses.Get_Next(); + } + pRelay = (TRelayObj*) ActiveCircuit[ActiveActor]->Relays.Get_First(); + while ((pRelay != nullptr)) + { + if (pRelay->FControlledElement == &pLine) + { + swtCls = "Breaker"; + return; + } + pRelay = (TRelayObj*) ActiveCircuit[ActiveActor]->Relays.Get_Next(); + } + pRecloser = (TRecloserObj*) ActiveCircuit[ActiveActor]->Reclosers.Get_First(); + while ((pRecloser != nullptr)) + { + if (pRecloser->FControlledElement == &pLine) + { + swtCls = "Recloser"; + return; + } + pRecloser = (TRecloserObj*) ActiveCircuit[ActiveActor]->Reclosers.Get_Next(); + } +} + +// this returns s1, s2, or a combination of ABCN +String PhaseString(TDSSCktElement &pElem, int bus, bool bAllowSec = true) // if order doesn't matter +{ + String val, phs; + int dot; + bool bSec; + + phs = pElem.Get_FirstBus(); + for (dot = 2; dot <= bus; ++dot) + phs = pElem.Get_NextBus(); + bSec = false; + if (bAllowSec) + { + if (pElem.Fnphases == 2) + if (ActiveCircuit[ActiveActor]->Buses[pElem.Terminals[bus - 1].BusRef - 1]->kVBase < 0.25) + bSec = true; + if (pElem.Fnphases == 1) + if (ActiveCircuit[ActiveActor]->Buses[pElem.Terminals[bus - 1].BusRef - 1]->kVBase < 0.13) + bSec = true; + } + + dot = Pos(".", phs); + if (dot < 1) + { + val = "ABC"; + } + else + { + phs = phs.substr(dot); + if (Pos("3", phs) > 0) + bSec = false; // i.e. it's a three-phase secondary, not split-phase + if (bSec) + { + if (Pos("1", phs) > 0) + { + val = "s1"; + if (Pos("2", phs) > 0) + val = val + "2"; + } + else if (Pos("2", phs) > 0) + val = "s2"; + } + else + { + val = ""; + if (Pos("1", phs) > 0) + val = val + "A"; + if (Pos("2", phs) > 0) + val = val + "B"; + if (Pos("3", phs) > 0) + val = val + "C"; + if (Pos("4", phs) > 0) + val = val + "N"; + } + } + return val; +} + +// returns s1, s12, s2, or an ordered combination of ABC +String PhaseOrderString(TDSSCktElement& pElem, int bus, bool bAllowSec = true) // for transposition +{ + String phs, Result; + int dot; + bool bSec; + + phs = pElem.Get_FirstBus(); + for (dot = 2; dot <= bus; ++dot) + phs = pElem.Get_NextBus(); + + bSec = false; + if (bAllowSec) + { + if (pElem.Fnphases == 2) + if (ActiveCircuit[ActiveActor]->Buses[pElem.Terminals[bus - 1].BusRef - 1]->kVBase < 0.25) + bSec = true; + if (pElem.Fnphases == 1) + if (ActiveCircuit[ActiveActor]->Buses[pElem.Terminals[bus - 1].BusRef - 1]->kVBase < 0.13) + bSec = true; + } + + dot = Pos(".", phs); + if (dot < 1) + { + Result = "ABC"; + } + else + { + phs = phs.substr(dot); + if (Pos("3", phs) > 0) + bSec = false; // i.e. it's a three-phase secondary, not split-phase + if (bSec) + { + if (Pos("1", phs) > 0) + { + Result = "s1"; + if (Pos("2", phs) > 0) + Result = Result + "2"; + } + else if (Pos("2", phs) > 0) + Result = "s2"; + } + else if (Pos("1.2.3", phs) > 0) + Result = "ABC"; + else if (Pos("1.3.2", phs) > 0) + Result = "ACB"; + else if (Pos("2.3.1", phs) > 0) + Result = "BCA"; + else if (Pos("2.1.3", phs) > 0) + Result = "BAC"; + else if (Pos("3.2.1", phs) > 0) + Result = "CBA"; + else if (Pos("3.1.2", phs) > 0) + Result = "CAB"; + else if (Pos("1.2", phs) > 0) + Result = "AB"; + else if (Pos("1.3", phs) > 0) + Result = "AC"; + else if (Pos("2.3", phs) > 0) + Result = "BC"; + else if (Pos("2.1", phs) > 0) + Result = "BA"; + else if (Pos("3.2", phs) > 0) + Result = "CB"; + else if (Pos("3.1", phs) > 0) + Result = "CA"; + else if (Pos("1", phs) > 0) + Result = "A"; + else if (Pos("2", phs) > 0) + Result = "B"; + else + Result = "C"; + } + + return Result; +} + +String DeltaPhaseString(TDSSCktElement& pElem) +{ + String phs, Result; + int dot; + + phs = pElem.Get_FirstBus(); + + dot = Pos(".", phs); + if ((dot < 1) || (pElem.Fnphases == 3)) + { + Result = "ABC"; // if Nphases < 3 this would be a user input error + } + else + { + phs = phs.substr(dot); + if (pElem.Fnphases == 1) + { + if (Pos("1.2", phs) > 0) + Result = "A"; + else if (Pos("2.1", phs) > 0) + Result = "A"; + else if (Pos("2.3", phs) > 0) + Result = "B"; + else if (Pos("3.2", phs) > 0) + Result = "B"; + else if (Pos("1.3", phs) > 0) + Result = "C"; + else if (Pos("3.1", phs) > 0) + Result = "C"; + } + else + { + if (Pos("1.2.3", phs) > 0) + Result = "AB"; + else if (Pos("1.3.2", phs) > 0) + Result = "CB"; + else if (Pos("2.1.3", phs) > 0) + Result = "AC"; + else if (Pos("2.3.1", phs) > 0) + Result = "BC"; + else if (Pos("3.1.2", phs) > 0) + Result = "CA"; + else if (Pos("3.2.1", phs) > 0) + Result = "BA"; + } + } + + return Result; +} + +TBankObject::TBankObject(int MaxWdg): inherited("Bank") +{ + maxWindings = MaxWdg; + nWindings = 0; + bAuto = false; + connections.resize(MaxWdg); + angles.resize(MaxWdg); + phaseA.resize(MaxWdg); + phaseB.resize(MaxWdg); + phaseC.resize(MaxWdg); + ground.resize(MaxWdg); +} + +TBankObject::~TBankObject() +{ +} + +void TBankObject::BuildVectorGroup() +{ + int i; + if (bAuto) + { + if (nWindings < 3) + vectorGroup = "YNa"; + else + vectorGroup = "YNad1"; + return; + } + vectorGroup = ""; + i = 0; // dynamic arrays are zero-based + while (i < nWindings) + { + if ((phaseA[i] > 0) && (phaseB[i] > 0) && (phaseC[i] > 0)) + { + if (connections[i] > 0) + vectorGroup = vectorGroup + "d"; + else + vectorGroup = vectorGroup + "y"; + if (ground[i] > 0) + vectorGroup = vectorGroup + "n"; + if (angles[i] > 0) + vectorGroup = vectorGroup + IntToStr(angles[i]); + } + else + vectorGroup = vectorGroup + "i"; + i++; + } + if (vectorGroup.size() > 0) + vectorGroup = UpperCase(vectorGroup.substr(0, 1)) + vectorGroup.substr(1); +} + +void TBankObject::AddTransformer(TTransfObj& pXf) +{ + int i; + String phs; + + if (pXf.get_NumWindings() > nWindings) + nWindings = pXf.get_NumWindings(); + + pd_unit = &pXf; + for (i = 1; i <= pXf.get_NumWindings(); ++i) + { + phs = PhaseString(pXf, i); + if (Pos("A", phs) > 0) + phaseA[i - 1] = 1; + if (Pos("B", phs) > 0) + phaseB[i - 1] = 1; + if (Pos("C", phs) > 0) + phaseC[i - 1] = 1; + connections[i - 1] = pXf.Get_WdgConnection(i); + if (connections[i - 1] != connections[0]) + angles[i - 1] = 1; + if ((pXf.Get_WdgRneutral(i) >= 0.0) || (pXf.Get_WdgXneutral(i) > 0.0)) + if (connections[i - 1] < 1) + ground[i - 1] = 1; + } +} + +void TBankObject::AddAutoTransformer(TAutoTransObj& pAuto) // 3-phase, 2 or 3 windings +{ + int i; + if (pAuto.get_NumWindings() > nWindings) + nWindings = pAuto.get_NumWindings(); + bAuto = true; + pd_unit = &pAuto; + for (i = 1; i <= pAuto.get_NumWindings(); ++i) + { + phaseA[i - 1] = 1; + phaseB[i - 1] = 1; + phaseC[i - 1] = 1; + connections[i - 1] = pAuto.Get_WdgConnection(i); + if (i == 2) + ground[i - 1] = 1; + } +} + +TOpLimitObject::TOpLimitObject(double norm, double emerg): inherited("OpLimI") +{ + NormAmps = norm; + EmergAmps = emerg; +} + +TOpLimitObject::~TOpLimitObject() +{ +} + +// the CIM transformer model requires some identified objects that don't have +// a counterpart in the DSS named objects. These include banks, windings, and +// winding info. So we create temporary UUIDs on the fly, and use a hash list when we +// need the UUIDs for later reference +void StartUuidList(int size) +{ + if (!UuidList.empty()) + FreeUuidList(); + uuidHash = THashList(size); + UuidList.resize(size); + UuidKeyList.resize(size); +} + +void StartBankList(int size) +{ + BankHash = THashList(size); + BankList.clear(); +} + +void StartECPList(int size) +{ + ECPHash = THashList(size); + ECPList.clear(); +} + +void StartOpLimitList(int size) +{ + OpLimitHash = THashList(size); + OpLimitList.clear(); +} + +void FreeUuidList() +{ + // uuidHash.Free; + UuidList.clear(); + UuidKeyList.clear(); +} + +void FreeBankList() +{ + int i; + // BankHash.Free; + for (i = 0; i < BankList.size(); ++i) + if (BankList[i] != nullptr) + delete BankList[i]; + BankList.clear(); +} + +void FreeECPList() +{ + // ECPHash.Free; + for (int i = 0; i < ECPList.size(); ++i) + if (ECPList[i] != nullptr) + delete ECPList[i]; + ECPList.clear();; +} + +void FreeOpLimitList() +{ + // OpLimitHash.Free; + for (int i = 0; i < OpLimitList.size(); ++i) + if (OpLimitList[i] != nullptr) + delete OpLimitList[i]; + OpLimitList.clear(); +} + +void AddBank(TBankObject* pBank) +{ + BankHash.Add(pBank->LName); + BankList.push_back(pBank); +} + +TBankObject* GetBank(const String& sBank) +{ + int ref; + TBankObject* Result = nullptr; + ref = BankHash.Find(sBank); + if (ref > 0) + Result = BankList[ref - 1]; + + return Result; +} + +void AddECP(TECPObject* pECP) +{ + ECPHash.Add(pECP->LName); + ECPList.push_back(pECP); +} + +TECPObject* GetECP(const String& key) +{ + int ref; + + TECPObject* Result = nullptr; + ref = ECPHash.Find(key); + if (ref > 0) + Result = ECPList[ref - 1]; + + return Result; +} + +void AddOpLimit(TOpLimitObject* pLimit) +{ + OpLimitHash.Add(pLimit->LName); + OpLimitList.push_back(pLimit); +} + +TOpLimitObject* GetOpLimit(const String& sLimit) +{ + TOpLimitObject* Result = nullptr; + int ref; + ref = OpLimitHash.Find(sLimit); + if (ref > 0) + Result = OpLimitList[ref - 1]; + + return Result; +} + +TUuid GetHashedUuid(const String& key) +{ + TUuid Result; + int ref, size; + ref = uuidHash.Find(key); + if (ref == 0) + { + ref = uuidHash.Add(key); + CreateUUID4(Result); // this should be the ONLY place to call CreateUUID4 + size = UuidList.size(); + if (ref > size) + { + UuidList.resize(2 * (size + 1)); + UuidKeyList.resize(2 * (size + 1)); + } + UuidList[ref - 1] = Result; + UuidKeyList[ref - 1] = key; + } + else + { + Result = UuidList[ref - 1]; + } + return Result; +} + +void AddHashedUUID(const String& key, const String& UuidVal) +{ + int ref, size; + ref = uuidHash.Find(key); + if (ref == 0) + { + ref = uuidHash.Add(key); + size = UuidList.size(); + if (ref > size) + { + UuidList.resize(2 * (size + 1)); + UuidKeyList.resize(2 * (size + 1)); + } + UuidList[ref - 1] = StringToUUID(UuidVal); + UuidKeyList[ref - 1] = key; + } + else + { + UuidList[ref - 1] = StringToUUID(UuidVal); + } +} + +// any temporary object (not managed by DSS) should have "=" prepended to the Name +TUuid GetDevUuid(UuidChoice which, const String& Name, int Seq) +{ + String key; + switch(which) + { + case Bank: + key = "Bank="; + break; + case Wdg: + key = "Wdg="; + break; + case XfCore: + key = "XfCore="; + break; + case XfMesh: + key = "XfMesh="; + break; + case WdgInf: + key = "WdgInf="; + break; + case ScTest: + key = "ScTest="; + break; + case OcTest: + key = "OcTest="; + break; + case BaseV: + key = "BaseV="; + break; + case OpLimV: + key = "OpLimV="; + break; + case OpLimI: + key = "OpLimI="; + break; + case LinePhase: + key = "LinePhase="; + break; + case LoadPhase: + key = "LoadPhase="; + break; + case GenPhase: + key = "GenPhase="; + break; + case SolarPhase: + key = "PVPhase="; + break; + case BatteryPhase: + key = "BattPhase="; + break; + case CapPhase: + key = "CapPhase="; + break; + case XfLoc: + key = "XfLoc="; + break; + case LoadLoc: + key = "LoadLoc="; + break; + case LineLoc: + key = "LineLoc="; + break; + case ReacLoc: + key = "ReacLoc="; + break; + case CapLoc: + key = "CapLoc="; + break; + case Topo: + key = "Topo="; + break; + case SolarLoc: + key = "SolarLoc="; + break; + case BatteryLoc: + key = "BatteryLoc="; + break; + case LoadResp: + key = "LoadResp="; + break; + case CIMVer: + key = "CIMVer="; + break; + case ZData: + key = "ZData="; + break; + case PosPt: + key = "PosPt="; + break; + case CoordSys: + key = "CoordSys="; + break; + case TopoIsland: + key = "TopoIsland="; + break; + case OpLimT: + key = "OpLimT="; + break; + case Station: + key = "Station="; + break; + case GeoRgn: + key = "GeoRgn="; + break; + case SubGeoRgn: + key = "SubGeoRgn="; + break; + case FdrLoc: + key = "FdrLoc="; + break; + case XfInfo: + key = "XfInfo="; + break; + case OpLimAHi: + key = "OpLimAHi="; + break; + case OpLimALo: + key = "OpLimALo="; + break; + case OpLimBHi: + key = "OpLimBHi="; + break; + case OpLimBLo: + key = "OpLimBLo="; + break; + case MachLoc: + key = "MachLoc="; + break; + case SrcLoc: + key = "SrcLoc="; + break; + case PVPanels: + key = "PVPanels="; + break; + case Battery: + key = "Battery="; + break; + case TankInfo: + key = "TankInfo="; + break; + case TapCtrl: + key = "TapCtrl="; + break; + case PUZ: + key = "PUZ="; + break; + case WirePos: + key = "WirePos="; + break; + case NormAmps: + key = "NormAmps="; + break; + case EmergAmps: + key = "EmergAmps="; + break; + case I1547NameplateData: + key = "INameplate="; + break; + case I1547NameplateDataApplied: + key = "IApplied="; + break; + case I1547Signal: + key = "ISignal="; + break; + case I1547VoltVar: + key = "IVVar="; + break; + case I1547WattVar: + key = "IWVar="; + break; + case I1547ConstPF: + key = "IPF="; + break; + case I1547VoltWatt: + key = "IVWatt="; + break; + case I1547ConstQ: + key = "IQ="; + break; + case ECProfile: + key = "ECP="; + break; + } + key = key + Name + "=" + IntToStr(Seq); + return GetHashedUuid(key); +} + +void AddLoadECP(TLoadObj& pLoad) +{ + String key; + TECPObject* pECP; + + if (((pLoad.DailyShape != "") || (pLoad.DutyShape != "") || (pLoad.GrowthShape != "") || (pLoad.YearlyShape != "") || (pLoad.CVRshape != "") || (pLoad.Spectrum != "defaultload"))) + { + key = Format("Load:%s:%s:%s:%s:%s:%s", pLoad.DailyShape.c_str(), pLoad.DutyShape.c_str(), pLoad.GrowthShape.c_str(), pLoad.YearlyShape.c_str(), pLoad.CVRshape.c_str(), pLoad.Spectrum.c_str()); + pECP = GetECP(key); + if (pECP == nullptr) + { + pECP = new TECPObject(LoadEcp); + pECP->LName = key; + pECP->Set_UUID(GetDevUuid(ECProfile, key, 0)); + pECP->daily = pLoad.DailyShape; + pECP->duty = pLoad.DutyShape; + pECP->growth = pLoad.GrowthShape; + pECP->cvr = pLoad.CVRshape; + pECP->yearly = pLoad.YearlyShape; + if (pLoad.Spectrum != "defaultload") + pECP->spectrum = pLoad.Spectrum; + AddECP(pECP); + } + pECP->AddConnection(pLoad); + } +} + +void AddSolarECP(TPVsystemObj& pPV) +{ + String key; + TECPObject* pECP; + if (((pPV.DailyShape != "") || (pPV.DutyShape != "") || (pPV.YearlyShape != "") || (pPV.DailyTShape != "") || (pPV.DutyTShape != "") || (pPV.YearlyTShape != "") || (pPV.Spectrum != ""))) + { + key = Format("PV:%s:%s:%s:%s:%s:%s:%s", pPV.DailyShape.c_str(), pPV.DutyShape.c_str(), pPV.YearlyShape.c_str(), pPV.DailyTShape.c_str(), pPV.DutyTShape.c_str(), pPV.YearlyTShape.c_str(), pPV.Spectrum.c_str()); + pECP = GetECP(key); + if (pECP == nullptr) + { + pECP = new TECPObject(PvEcp); + pECP->LName = key; + pECP->Set_UUID(GetDevUuid(ECProfile, key, 0)); + pECP->daily = pPV.DailyShape; + pECP->duty = pPV.DutyShape; + pECP->yearly = pPV.YearlyShape; + pECP->Tdaily = pPV.DailyTShape; + pECP->Tduty = pPV.DutyTShape; + pECP->Tyearly = pPV.YearlyTShape; + pECP->spectrum = pPV.Spectrum; + AddECP(pECP); + } + pECP->AddConnection(pPV); + } +} + +void AddStorageECP(TStorageObj& pBat) +{ + String key; + TECPObject* pECP; + + if (((pBat.DailyShape != "") || (pBat.DutyShape != "") || (pBat.YearlyShape != "") || (pBat.Spectrum != ""))) + { + key = Format("Bat:%s:%s:%s:%s", pBat.DailyShape.c_str(), pBat.DutyShape.c_str(), pBat.YearlyShape.c_str(), pBat.Spectrum.c_str()); + pECP = GetECP(key); + if (pECP == nullptr) + { + pECP = new TECPObject(BatEcp); + pECP->LName = key; + pECP->Set_UUID(GetDevUuid(ECProfile, key, 0)); + pECP->daily = pBat.DailyShape; + pECP->duty = pBat.DutyShape; + pECP->yearly = pBat.YearlyShape; + pECP->spectrum = pBat.Spectrum; + AddECP(pECP); + } + pECP->AddConnection(pBat); + } +} + +void AddGeneratorECP(TGeneratorObj& pGen) +{ + String key; + TECPObject* pECP; + + if (((pGen.DailyDispShape != "") || (pGen.DutyShape != "") || (pGen.YearlyShape != "") || (pGen.Spectrum != "defaultgen"))) + { + key = Format("Gen:%s:%s:%s:%s", pGen.DailyDispShape.c_str(), pGen.DutyShape.c_str(), pGen.YearlyShape.c_str(), pGen.Spectrum.c_str()); + pECP = GetECP(key); + if (pECP == nullptr) + { + pECP = new TECPObject(GenEcp); + pECP->LName = key; + pECP->Set_UUID(GetDevUuid(ECProfile, key, 0)); + pECP->daily = pGen.DailyDispShape; + pECP->duty = pGen.DutyShape; + pECP->yearly = pGen.YearlyShape; + if (pGen.Spectrum != "defaultgen") + pECP->spectrum = pGen.Spectrum; + AddECP(pECP); + } + pECP->AddConnection(pGen); + } +} + +void DefaultCircuitUUIDs(TUuid& fdrID, TUuid& subID, TUuid& rgnID, TUuid&subGeoID) +{ + if (UuidList.empty()) + StartUuidList(ActiveCircuit[ActiveActor]->NumBuses + 2 * ActiveCircuit[ActiveActor]->NumDevices); + fdrID = ActiveCircuit[ActiveActor]->Get_UUID(); + subID = GetDevUuid(Station, "Station", 1); + rgnID = GetDevUuid(GeoRgn, "GeoRgn", 1); + subGeoID = GetDevUuid(SubGeoRgn, "SubGeoRgn", 1); +} + +void WriteHashedUUIDs(Textfile& F) +{ + for (int i = 0; i < UuidList.size(); ++i) + { + if (UuidKeyList[i].size() < 1) + break; + WriteLn(F, Format("%s %s", UuidKeyList[i].c_str(), UUIDToString(UuidList[i]).c_str())); + } +} + +// terminals are uniquely identified by class (DSSObjType), plus name and sequence +TUuid GetTermUuid(TDSSCktElement& pElem, int Seq) +{ + String key = IntToStr(pElem.DSSObjType) + "=" + pElem.get_Name() + "=" + IntToStr(Seq); + return GetHashedUuid(key); +} + +String GetBaseVName(double val) +{ +// Result = Format("BaseV_%.3f", [val]); + return "BaseV_" + FloatToStrF(val, ffFixed, 6, 4); +} + +TUuid GetBaseVUuid(double val) +{ + return GetDevUuid(BaseV, GetBaseVName(val), 1); +} + +String GetOpLimVName(double val) +{ + return "OpLimV_" + FloatToStrF(val, ffFixed, 6, 4); +} + +TUuid GetOpLimVUuid(double val) +{ + return GetDevUuid(OpLimV, GetOpLimVName(val), 1); +} + +String GetOpLimIName(double norm, double emerg) +{ + return "OpLimI_" + FloatToStrF(norm, ffFixed, 6, 1) + "_" + FloatToStrF(emerg, ffFixed, 6, 1); +} + +TUuid GetOpLimIUuid(double norm, double emerg) +{ + return GetDevUuid(OpLimI, GetOpLimIName(norm, emerg), 1); +} + +void DoubleNode(ProfileChoice prf, const String& Node, double val) +{ + FD->WriteCimLn(prf, Format(" %.8g", Node.c_str(), val, Node.c_str())); +} + +void IntegerNode(ProfileChoice prf, const String& Node, int val) +{ + FD->WriteCimLn(prf, Format(" %d", Node.c_str(), val, Node.c_str())); +} + +void BooleanNode(ProfileChoice prf, const String& Node, bool val) +{ + String i; + + if (val) + i = "true"; + else + i = "false"; + FD->WriteCimLn(prf, Format(" %s", Node.c_str(), i.c_str(), Node.c_str())); +} + +void RefNode(ProfileChoice prf, const String& Node, TNamedObject& Obj) +{ + FD->WriteCimLn(prf, Format(" ", Node.c_str(), Obj.Get_CIM_ID().c_str())); +} + +void RefNode(ProfileChoice prf, const String& Node, TNamedObject* Obj) +{ + RefNode(prf, Node, *Obj); +} + +void UuidNode(ProfileChoice prf, const String& Node, TUuid ID) +{ + FD->WriteCimLn(prf, Format(" ", Node.c_str(), UUIDToCIMString(ID).c_str())); +} + +void LineCodeRefNode(ProfileChoice prf, TLineCode& List, const String& Name) +{ + if (List.SetActive(Name)) + { + TLineCodeObj *Obj = (TLineCodeObj *) List.GetActiveObj(); + FD->WriteCimLn(prf, Format(" ", Obj->Get_CIM_ID().c_str())); + } +} + +void LineSpacingRefNode(ProfileChoice prf, TDSSClass& List, const String &Name) +{ + if (List.SetActive(Name)) + { + TDSSObject* Obj = (TDSSObject*) List.GetActiveObj(); // should be a TLineGeometryObj or TLineSpacingObj + FD->WriteCimLn(prf, Format(" ", Obj->Get_CIM_ID().c_str())); + } +} + +void PhaseWireRefNode(ProfileChoice prf, TConductorDataObj& Obj) +{ + FD->WriteCimLn(prf, Format(" ", Obj.Get_CIM_ID().c_str())); +} + +void CircuitNode(ProfileChoice prf, TNamedObject& Obj) +{ + FD->WriteCimLn(prf, Format(" ", Obj.Get_CIM_ID().c_str())); +} + +void CircuitNode(ProfileChoice prf, TNamedObject* Obj) +{ + CircuitNode(prf, *Obj); +} + +String FirstPhaseString(TDSSCktElement& pElem, int bus) +{ + String val = PhaseString(pElem, bus); + if (val != "") + return val.substr(0, 1); + else + return "A"; +} + +void GeneratorControlEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void BatteryStateEnum(ProfileChoice prf, int val) +{ + String str = "waiting"; + if (val == STORE_CHARGING) + str = "charging"; + else if (val == STORE_DISCHARGING) + str = "discharging"; + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), str.c_str())); +} + +void ConverterControlEnum(ProfileChoice prf, int varMode, bool CIMdynamics) +{ + String str = "constantPowerFactor"; // VARMODEPF + if (CIMdynamics) + str = "dynamic"; + else if (varMode == VARMODEKVAR) + str = "constantReactivePower"; + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), str.c_str())); +} + +void SynchMachTypeEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void SynchMachModeEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void RegulatingControlEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void WindingConnectionEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void ConductorInsulationEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void ConductorUsageEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void CableShieldMaterialEnum(ProfileChoice prf, const String& val) +{ +// FD->WriteCimLn (prf, Format (" ", +// [CIM_NS, val])); +} + +void ConductorMaterialEnum(ProfileChoice prf, const String& val) +{ +// FD->WriteCimLn (prf, Format (" ", +// [CIM_NS, val])); +} + +void CableOuterJacketEnum(ProfileChoice prf, const String& val) +{ +// FD->WriteCimLn (prf, Format (" ", +// [CIM_NS, val])); +} + +void CableConstructionEnum(ProfileChoice prf, const String& val) +{ +// FD->WriteCimLn (prf, Format (" ", +// [CIM_NS, val])); +} + +void TransformerControlEnum(ProfileChoice prf, const String& val) +{ +// FD->WriteCimLn (prf, Format (" ", +// [CIM_NS, val])); +} + +void MonitoredPhaseNode(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void OpLimitDirectionEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +// next several for DERIEEEType1 CIM dynamics +void NormalOpCatEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +/* +void SupportedModesEnum (ProfileChoice prf, const String& val) +{ + FD->WriteCimLn (prf, Format (" ", + [CIM_NS, val])); +} +*/ +void PowerFactorExcitationEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +void RemoteInputSignalEnum(ProfileChoice prf, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} +// end of Enums for DERIEEEType1 CIM dynamics + +void StringNode(ProfileChoice prf, const String& Node, const String& val) +{ + FD->WriteCimLn(prf, Format(" %s", Node.c_str(), val.c_str(), Node.c_str())); +} + +void StartInstance(ProfileChoice prf, const String& Root, TNamedObject& Obj) +{ + FD->StartInstance(prf, Root, Obj); +} + +void StartInstance(ProfileChoice prf, const String& Root, TNamedObject* Obj) +{ + FD->StartInstance(prf, Root, *Obj); +} + +void StartFreeInstance(ProfileChoice prf, const String& Root, TUuid uuid) +{ + FD->StartFreeInstance(prf, Root, uuid); +} + +void EndInstance(ProfileChoice prf, const String& Root) +{ + FD->EndInstance(prf, Root); +} + +void XfmrTankPhasesAndGround(ProfileChoice fprf, ProfileChoice eprf, TTransfObj& pXf, int bus) +{ + String ordered_phs; + int j1, j2; + bool reverse_ground, wye_ground, wye_unground; + + j1 = (bus - 1) * pXf.Fnconds + 1; + j2 = j1 + pXf.Fnphases; + reverse_ground = false; + wye_ground = false; + wye_unground = false; + // WriteLn(Format(" Testing %d and %d", [j1, j2])); + if ((pXf.WINDING_[bus - 1].Connection == 1)) + { // delta + BooleanNode(fprf, "TransformerEnd.grounded", false); + } + else if ((pXf.NodeRef[j2 - 1] == 0)) + { // last conductor is grounded solidly + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", 0.0); + DoubleNode(EpPrf, "TransformerEnd.xground", 0.0); + wye_ground = true; + } + else if ((pXf.NodeRef[j1 - 1] == 0)) + { // first conductor is grounded solidly, but should be reversed + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", 0.0); + DoubleNode(EpPrf, "TransformerEnd.xground", 0.0); + reverse_ground = true; + } + else if ((pXf.WINDING_[bus - 1].Rneut < 0.0)) + { // probably wye ungrounded + BooleanNode(FunPrf, "TransformerEnd.grounded", false); + wye_unground = true; + } + else + { // not delta, not wye solidly grounded or ungrounded + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", pXf.WINDING_[bus - 1].Rneut); + DoubleNode(EpPrf, "TransformerEnd.xground", pXf.WINDING_[bus - 1].Xneut); + } + ordered_phs = PhaseOrderString(pXf, bus); + if ((ordered_phs == "s1")) + ordered_phs = "s1N"; + else if ((ordered_phs == "s2")) + ordered_phs = "Ns2"; + else if (reverse_ground) + ordered_phs = "N" + ordered_phs; + else if (wye_ground) + ordered_phs = ordered_phs + "N"; + else if (wye_unground) + ordered_phs = ordered_phs + "N"; + + FD->WriteCimLn(fprf, Format(" ", CIM_NS.c_str(), ordered_phs.c_str())); +} + +void PhaseNode(ProfileChoice prf, const String& Root, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", Root.c_str(), CIM_NS.c_str(), val.c_str())); +} + +void PhaseKindNode(ProfileChoice prf, const String& Root, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", Root.c_str(), CIM_NS.c_str(), val.c_str())); +} + +void PhaseSideNode(ProfileChoice prf, const String& Root, int Side, const String& val) +{ + FD->WriteCimLn(prf, Format(" ", Root.c_str(), Side, CIM_NS.c_str(), val.c_str())); +} + +void ShuntConnectionKindNode(ProfileChoice prf, const String& Root, const String& val) // D, Y, Yn, I +{ + FD->WriteCimLn(prf, Format(" ", Root.c_str(), CIM_NS.c_str(), val.c_str())); +} + +void WindingConnectionKindNode(ProfileChoice prf, const String& val) // D, Y, Z, Yn, Zn, A, I +{ + FD->WriteCimLn(prf, Format(" ", CIM_NS.c_str(), val.c_str())); +} + +// we specify phases except for balanced three-phase +void AttachLinePhases(TLineObj& pLine) +{ + String s, phs; + int i; + TNamedObject* pPhase; + + pPhase = new TNamedObject("dummy"); + s = PhaseOrderString(pLine, 1); + if (pLine.NumConductorData() > s.size()) + s = s + "N"; // so we can specify the neutral conductor + for (i = 1; i <= s.size(); ++i) + { + phs = s[i - 1]; + if (phs == "s") + continue; + if (phs == "1") + phs = "s1"; + if (phs == "2") + phs = "s2"; + pPhase->LName = pLine.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(LinePhase, pPhase->LName, 1)); + StartInstance(FunPrf, "ACLineSegmentPhase", *pPhase); + PhaseKindNode(FunPrf, "ACLineSegmentPhase", phs); + IntegerNode(FunPrf, "ACLineSegmentPhase.sequenceNumber", i); + if (i <= pLine.NumConductorData()) + PhaseWireRefNode(CatPrf, *pLine.FetchConductorData(i)); + RefNode(FunPrf, "ACLineSegmentPhase.ACLineSegment", pLine); + UuidNode(GeoPrf, "PowerSystemResource.Location", + GetDevUuid(LineLoc, pLine.get_Name(), 1)); + EndInstance(FunPrf, "ACLineSegmentPhase"); + } + delete pPhase; +} + +void AttachSwitchPhases(TLineObj& pLine) +{ + String s1, s2, phs1, phs2; + int i; + TNamedObject* pPhase; + + // also write the switch phases if needed to support transpositions + s1 = PhaseOrderString(pLine, 1); + s2 = PhaseOrderString(pLine, 2); + if ((pLine.Fnphases == 3) && (s1.size() == 3) && (s1 == s2)) + return; + pPhase = new TNamedObject("dummy"); + for (i = 0; i < s1.size(); ++i) + { + phs1 = s1[i]; + phs2 = s2[i]; + if (phs1 == "s") + continue; + if (phs2 == "s") + continue; + if (phs1 == "1") + phs1 = "s1"; + if (phs1 == "2") + phs1 = "s2"; + if (phs2 == "1") + phs2 = "s1"; + if (phs2 == "2") + phs2 = "s2"; + pPhase->LName = pLine.get_Name() + "_" + phs1; + pPhase->Set_UUID(GetDevUuid(LinePhase, pPhase->LName, 1)); + StartInstance(FunPrf, "SwitchPhase", pPhase); + BooleanNode(SshPrf, "SwitchPhase.closed", pLine.Get_ConductorClosed(0, ActiveActor)); + BooleanNode(FunPrf, "SwitchPhase.normalOpen", !pLine.Get_ConductorClosed(0, ActiveActor)); + PhaseSideNode(FunPrf, "SwitchPhase", 1, phs1); + PhaseSideNode(FunPrf, "SwitchPhase", 2, phs2); + RefNode(FunPrf, "SwitchPhase.Switch", pLine); + UuidNode(GeoPrf, "PowerSystemResource.Location", GetDevUuid(LineLoc, pLine.get_Name(), 1)); + EndInstance(FunPrf, "SwitchPhase"); + } + delete pPhase; +} + +void AttachCapPhases(TCapacitorObj& pCap, const TUuid& geoUUID, double sections) +{ + String s, phs; + int i; + TNamedObject* pPhase; + double bph; + + if (pCap.Fnphases == 3) + return; + pPhase = new TNamedObject("dummy"); + s = PhaseString(pCap, 1); + // with pCap do + { + bph = 0.001 * pCap.Ftotalkvar / pCap.kvrating / pCap.kvrating / pCap.FNumSteps / pCap.Fnphases; + if (pCap.Connection == 1) + s = DeltaPhaseString(pCap); + } + for (i = 0; i < s.size(); ++i) + { + phs = s[i]; + pPhase->LName = pCap.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(CapPhase, pPhase->LName, 1)); + StartInstance(FunPrf, "LinearShuntCompensatorPhase", pPhase); + PhaseKindNode(FunPrf, "ShuntCompensatorPhase", phs); + DoubleNode(EpPrf, "LinearShuntCompensatorPhase.bPerSection", bph); + DoubleNode(EpPrf, "LinearShuntCompensatorPhase.gPerSection", 0.0); + IntegerNode(EpPrf, "ShuntCompensatorPhase.normalSections", pCap.FNumSteps); + IntegerNode(EpPrf, "ShuntCompensatorPhase.maximumSections", pCap.FNumSteps); + DoubleNode(SshPrf, "ShuntCompensatorPhase.sections", sections); + RefNode(FunPrf, "ShuntCompensatorPhase.ShuntCompensator", pCap); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "LinearShuntCompensatorPhase"); + } + delete pPhase; +} + +void AttachSecondaryPhases(TLoadObj &pLoad, const TUuid& geoUUID, TNamedObject& pPhase, double p, double q, const String& phs) +{ + pPhase.LName = pLoad.get_Name() + "_" + phs; + pPhase.Set_UUID(GetDevUuid(LoadPhase, pPhase.LName, 1)); + StartInstance(FunPrf, "EnergyConsumerPhase", pPhase); + PhaseKindNode(FunPrf, "EnergyConsumerPhase", phs); + DoubleNode(SshPrf, "EnergyConsumerPhase.p", p); + DoubleNode(SshPrf, "EnergyConsumerPhase.q", q); + RefNode(FunPrf, "EnergyConsumerPhase.EnergyConsumer", pLoad); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "EnergyConsumerPhase"); +} + +void AttachLoadPhases(TLoadObj& pLoad, const TUuid& geoUUID) +{ + String s, phs; + int i; + TNamedObject* pPhase; + double p, q; + bool bAllowSec; + + if (pLoad.Fnphases == 3) + return; + // TODO - use a more robust filter than pLoad.LoadClass, which is > 1 only for PNNL taxonomy imports + if (pLoad.LoadClass <= 1) + bAllowSec = true; + else + bAllowSec = false; + p = 1000.0 * pLoad.kWBase / pLoad.Fnphases; + q = 1000.0 * pLoad.kvarBase / pLoad.Fnphases; + if (pLoad.Connection == 1) + s = DeltaPhaseString(pLoad); + else + s = PhaseString(pLoad, 1, bAllowSec); + + pPhase = new TNamedObject("dummy"); + // first, filter out what appear to be split secondary loads + // these can be 2-phase loads (balanced) nominally 0.208 kV, or + // 1-phase loads (possibly unbalanced) nominally 0.12 kV + // TODO - handle s1 to s2 240-volt loads; these would be s12, which is not a valid SinglePhaseKind + if ((pLoad.kVLoadBase < 0.25) && bAllowSec) + { + if (pLoad.Fnphases == 2) + { + AttachSecondaryPhases(pLoad, geoUUID, *pPhase, p, q, "s1"); + AttachSecondaryPhases(pLoad, geoUUID, *pPhase, p, q, "s2"); + delete pPhase; + return; + } + else + { + AttachSecondaryPhases(pLoad, geoUUID, *pPhase, p, q, s); + delete pPhase; + return; + } + } + + for (i = 0; i < s.size(); ++i) + { + phs = s[i]; + pPhase->LName = pLoad.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(LoadPhase, pPhase->LName, 1)); + StartInstance(FunPrf, "EnergyConsumerPhase", pPhase); + PhaseKindNode(FunPrf, "EnergyConsumerPhase", phs); + DoubleNode(SshPrf, "EnergyConsumerPhase.p", p); + DoubleNode(SshPrf, "EnergyConsumerPhase.q", q); + RefNode(FunPrf, "EnergyConsumerPhase.EnergyConsumer", pLoad); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "EnergyConsumerPhase"); + } + delete pPhase; +} + +void AttachSecondaryGenPhases(TGeneratorObj& pGen, const TUuid& geoUUID, TNamedObject& pPhase, double p, double q, const String& phs) +{ + pPhase.LName = pGen.get_Name() + "_" + phs; + pPhase.Set_UUID(GetDevUuid(GenPhase, pPhase.LName, 1)); + StartInstance(FunPrf, "SynchronousMachinePhase", pPhase); + PhaseKindNode(FunPrf, "SynchronousMachinePhase", phs); + DoubleNode(SshPrf, "SynchronousMachinePhase.p", p); + DoubleNode(SshPrf, "SynchronousMachinePhase.q", q); + RefNode(FunPrf, "SynchronousMachinePhase.SynchronousMachine", pGen); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "SynchronousMachinePhase"); +} + +void AttachGeneratorPhases(TGeneratorObj& pGen, const TUuid& geoUUID) +{ + String s, phs; + int i; + TNamedObject* pPhase; + double p, q; + + if (pGen.Fnphases == 3) + return; + + p = 1000.0 * pGen.Get_PresentkW() / pGen.Fnphases; + q = 1000.0 * pGen.Get_Presentkvar() / pGen.Fnphases; + if (pGen.Connection == 1) + s = DeltaPhaseString(pGen); + else + s = PhaseString(pGen, 1); + + pPhase = new TNamedObject("dummy"); + // TODO - handle s1 to s2 240-volt loads; these would be s12, which is not a valid SinglePhaseKind + if (pGen.Get_PresentkV() < 0.25) + { + if (pGen.Fnphases == 2) + { + AttachSecondaryGenPhases(pGen, geoUUID, *pPhase, p, q, "s1"); + AttachSecondaryGenPhases(pGen, geoUUID, *pPhase, p, q, "s2"); + delete pPhase; + return; + } + else + { + AttachSecondaryGenPhases(pGen, geoUUID, *pPhase, p, q, s); + delete pPhase; + return; + } + } + + for (int i = 0; i < s.size(); ++i) + { + phs = s[i]; + pPhase->LName = pGen.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(GenPhase, pPhase->LName, 1)); + StartInstance(FunPrf, "SynchronousMachinePhase", pPhase); + PhaseKindNode(FunPrf, "SynchronousMachinePhase", phs); + DoubleNode(SshPrf, "SynchronousMachinePhase.p", p); + DoubleNode(SshPrf, "SynchronousMachinePhase.q", q); + RefNode(FunPrf, "SynchronousMachinePhase.SynchronousMachine", pGen); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "SynchronousMachinePhase"); + } + delete pPhase; +} + +void AttachSecondarySolarPhases(TPVsystemObj& pPV, const TUuid& geoUUID, TNamedObject& pPhase, double p, double q, const String &phs) +{ + pPhase.LName = pPV.get_Name() + "_" + phs; + pPhase.Set_UUID(GetDevUuid(SolarPhase, pPhase.LName, 1)); + StartInstance(FunPrf, "PowerElectronicsConnectionPhase", pPhase); + PhaseKindNode(FunPrf, "PowerElectronicsConnectionPhase", phs); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.p", p); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.q", q); + RefNode(FunPrf, "PowerElectronicsConnectionPhase.PowerElectronicsConnection", pPV); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnectionPhase"); +} + +void AttachSolarPhases(TPVsystemObj& pPV, const TUuid& geoUUID) +{ + String s, phs; + int i; + TNamedObject* pPhase; + double p, q; + + if (pPV.Fnphases == 3) + return; + p = 1000.0 * pPV.Get_PresentkW() / pPV.Fnphases; + q = 1000.0 * pPV.Get_Presentkvar() / pPV.Fnphases; + if (pPV.Connection == 1) + s = DeltaPhaseString(pPV); + else + s = PhaseString(pPV, 1); + + pPhase = new TNamedObject("dummy"); + // TODO - handle s1 to s2 240-volt loads; these would be s12, which is not a valid SinglePhaseKind + if (pPV.Get_PresentkV() < 0.25) + { + if (pPV.Fnphases == 2) + { + AttachSecondarySolarPhases(pPV, geoUUID, *pPhase, p, q, "s1"); + AttachSecondarySolarPhases(pPV, geoUUID, *pPhase, p, q, "s2"); + delete pPhase; + return; + } + else + { + AttachSecondarySolarPhases(pPV, geoUUID, *pPhase, p, q, s); + delete pPhase; + return; + } + } + + for (i = 0; i < s.size(); ++i) + { + phs = s[i]; + pPhase->LName = pPV.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(SolarPhase, pPhase->LName, 1)); + StartInstance(FunPrf, "PowerElectronicsConnectionPhase", pPhase); + PhaseKindNode(FunPrf, "PowerElectronicsConnectionPhase", phs); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.p", p); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.q", q); + RefNode(FunPrf, "PowerElectronicsConnectionPhase.PowerElectronicsConnection", pPV); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnectionPhase"); + } + delete pPhase; +} + +void AttachSecondaryStoragePhases(TStorageObj& pBat, const TUuid& geoUUID, TNamedObject& pPhase, double p, double q, const String& phs) +{ + pPhase.LName = pBat.get_Name() + "_" + phs; + pPhase.Set_UUID(GetDevUuid(BatteryPhase, pPhase.LName, 1)); + StartInstance(FunPrf, "PowerElectronicsConnectionPhase", pPhase); + PhaseKindNode(FunPrf, "PowerElectronicsConnectionPhase", phs); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.p", p); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.q", q); + RefNode(FunPrf, "PowerElectronicsConnectionPhase.PowerElectronicsConnection", pBat); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnectionPhase"); +} + +void AttachStoragePhases(TStorageObj& pBat, const TUuid& geoUUID) +{ + String s, phs; + int i; + TNamedObject* pPhase; + double p, q; + + if (pBat.Fnphases == 3) + return; + p = 1000.0 * pBat.Get_PresentkW() / pBat.Fnphases; + q = 1000.0 * pBat.Get_Presentkvar() / pBat.Fnphases; + if (pBat.Connection == 1) + s = DeltaPhaseString(pBat); + else + s = PhaseString(pBat, 1); + + pPhase = new TNamedObject("dummy"); + // TODO - handle s1 to s2 240-volt loads; these would be s12, which is not a valid SinglePhaseKind + if (pBat.Get_PresentkV() < 0.25) + { + if (pBat.Fnphases == 2) + { + AttachSecondaryStoragePhases(pBat, geoUUID, *pPhase, p, q, "s1"); + AttachSecondaryStoragePhases(pBat, geoUUID, *pPhase, p, q, "s2"); + delete pPhase; + return; + } + else + { + AttachSecondaryStoragePhases(pBat, geoUUID, *pPhase, p, q, s); + delete pPhase; + return; + } + } + + for (i = 0; i < s.size(); ++i) + { + phs = s[i]; + pPhase->LName = pBat.get_Name() + "_" + phs; + pPhase->Set_UUID(GetDevUuid(BatteryPhase, pPhase->LName, 1)); + StartInstance(FunPrf, "PowerElectronicsConnectionPhase", *pPhase); + PhaseKindNode(FunPrf, "PowerElectronicsConnectionPhase", phs); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.p", p); + DoubleNode(SshPrf, "PowerElectronicsConnectionPhase.q", q); + RefNode(FunPrf, "PowerElectronicsConnectionPhase.PowerElectronicsConnection", pBat); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnectionPhase"); + } + delete pPhase; +} + +void WriteLoadModel(const String& Name, TUuid ID, double zP, double iP, double pP, double zQ, double iQ, double pQ, double eP, double eQ) +{ + FD->WriteCimLn(FunPrf, Format("", UUIDToCIMString(ID).c_str())); + StringNode(FunPrf, "IdentifiedObject.mRID", UUIDToCIMString(ID)); + StringNode(FunPrf, "IdentifiedObject.name", Name); + if ((eP > 0.0) || (eQ > 0.0)) + BooleanNode(FunPrf, "LoadResponseCharacteristic.exponentModel", true); + else + BooleanNode(FunPrf, "LoadResponseCharacteristic.exponentModel", false); + + DoubleNode(FunPrf, "LoadResponseCharacteristic.pConstantImpedance", zP); + DoubleNode(FunPrf, "LoadResponseCharacteristic.pConstantCurrent", iP); + DoubleNode(FunPrf, "LoadResponseCharacteristic.pConstantPower", pP); + + DoubleNode(FunPrf, "LoadResponseCharacteristic.qConstantImpedance", zQ); + DoubleNode(FunPrf, "LoadResponseCharacteristic.qConstantCurrent", iQ); + DoubleNode(FunPrf, "LoadResponseCharacteristic.qConstantPower", pQ); + + DoubleNode(FunPrf, "LoadResponseCharacteristic.pVoltageExponent", eP); + DoubleNode(FunPrf, "LoadResponseCharacteristic.qVoltageExponent", eQ); + DoubleNode(FunPrf, "LoadResponseCharacteristic.pFrequencyExponent", 0.0); + DoubleNode(FunPrf, "LoadResponseCharacteristic.qFrequencyExponent", 0.0); + FD->WriteCimLn(FunPrf, ""); +} + +bool IsGroundBus(const String& S) +{ + int i; + bool Result = true; + i = Pos(".1", S); + if (i > 0) + Result = false; + i = Pos(".2", S); + if (i > 0) + Result = false; + i = Pos(".3", S); + if (i > 0) + Result = false; + i = Pos(".", S); + if (i == 0) + Result = false; + + return Result; +} + +void WritePositions(TDSSCktElement& pElem, const TUuid& geoUUID, TUuid crsUUID) +{ + int Nterm, j, ref; + String BusName; + + Nterm = pElem.Fnterms; + BusName = pElem.Get_FirstBus(); + StartFreeInstance(GeoPrf, "Location", geoUUID); + StringNode(GeoPrf, "IdentifiedObject.mRID", UUIDToCIMString(geoUUID)); + StringNode(GeoPrf, "IdentifiedObject.name", pElem.LName + "_Loc"); + UuidNode(GeoPrf, "Location.CoordinateSystem", crsUUID); + EndInstance(GeoPrf, "Location"); + + for (j = 1; j <= Nterm; ++j) + { + if (!IsGroundBus(BusName)) + { + ref = pElem.Terminals[j - 1].BusRef - 1; + StartFreeInstance(GeoPrf, "PositionPoint", GetDevUuid(PosPt, pElem.ParentClass->get_myClass_name() + "." + pElem.LName, j)); + UuidNode(GeoPrf, "PositionPoint.Location", geoUUID); + IntegerNode(GeoPrf, "PositionPoint.sequenceNumber", j); + StringNode(GeoPrf, "PositionPoint.xPosition", FloatToStr(ActiveCircuit[ActiveActor]->Buses[ref]->x)); + StringNode(GeoPrf, "PositionPoint.yPosition", FloatToStr(ActiveCircuit[ActiveActor]->Buses[ref]->y)); + EndInstance(GeoPrf, "PositionPoint"); + } + BusName = pElem.Get_NextBus(); + } +} + +void WriteReferenceTerminals(TDSSCktElement& pElem, TUuid RefUuid, double norm = 0.0, double emerg = 0.0) +{ + int Nterm, j, ref; + String BusName, TermName, LimitName; + TUuid TermUuid, LimiTUuid; + TOpLimitObject* pLimit; + + Nterm = pElem.Fnterms; + BusName = pElem.Get_FirstBus(); + for (j = 1; j <= Nterm; ++j) + { + if (!IsGroundBus(BusName)) + { + ref = pElem.Terminals[j - 1].BusRef - 1; + TermName = pElem.get_Name() + "_T" + IntToStr(j); + TermUuid = GetTermUuid(pElem, j); + StartFreeInstance(FunPrf, "Terminal", TermUuid); + StringNode(FunPrf, "IdentifiedObject.mRID", UUIDToCIMString(TermUuid)); + StringNode(FunPrf, "IdentifiedObject.name", TermName); + UuidNode(FunPrf, "Terminal.ConductingEquipment", RefUuid); + IntegerNode(FunPrf, "ACDCTerminal.sequenceNumber", j); + FD->WriteCimLn(TopoPrf, Format(" ", ActiveCircuit[ActiveActor]->Buses[ref]->Get_CIM_ID().c_str())); + if ((j == 1) && (norm > 0.0)) + { + if (emerg < norm) + emerg = norm; + LimitName = GetOpLimIName(norm, emerg); + pLimit = GetOpLimit(LimitName); + if (pLimit == nullptr) + { + pLimit = new TOpLimitObject(norm, emerg); + pLimit->LName = LimitName; + pLimit->Set_UUID(GetDevUuid(OpLimI, LimitName, 0)); + AddOpLimit(pLimit); + } + LimiTUuid = GetDevUuid(OpLimI, LimitName, 0); + UuidNode(FunPrf, "ACDCTerminal.OperationalLimitSet", LimiTUuid); + } + EndInstance(FunPrf, "Terminal"); + } + BusName = pElem.Get_NextBus(); + } +} + +void WriteTerminals(TDSSCktElement &pElem, const TUuid& geoUUID, TUuid crsUUID, double norm = 0.0, double emerg = 0.0) +{ + WriteReferenceTerminals(pElem, pElem.Get_UUID(), norm, emerg); + WritePositions(pElem, geoUUID, crsUUID); +} + +void VbaseNode(ProfileChoice prf, TDSSCktElement& pElem) +{ + int j = pElem.Terminals[0].BusRef - 1; + UuidNode(prf, "ConductingEquipment.BaseVoltage", GetBaseVUuid(sqrt(3.0) * ActiveCircuit[ActiveActor]->Buses[j]->kVBase)); +} + +void WriteXfmrCode(TXfmrCodeObj& pXfCd) +{ + TNamedObject* pName; + double ratShort, ratEmerg, val, r, x, Zbase, TestKVA, pctIexc; + int i, j, seq; + + pName = new TNamedObject("dummy"); + // with pXfCd do + { + StartInstance(CatPrf, "TransformerTankInfo", pXfCd); + EndInstance(CatPrf, "TransformerTankInfo"); + ratShort = pXfCd.NormMaxHkVA / pXfCd.WINDING_[0].kVA; + ratEmerg = pXfCd.EmergMaxHkVA / pXfCd.WINDING_[0].kVA; + for (i = 1; i <= pXfCd.NumWindings; ++i) + { + Zbase = pXfCd.WINDING_[i - 1].kVLL; + Zbase = 1000.0 * Zbase * Zbase / pXfCd.WINDING_[0].kVA; + pName->LName = pXfCd.get_Name() + "_" + IntToStr(i); + pName->Set_UUID(GetDevUuid(WdgInf, pXfCd.get_Name(), i)); + StartInstance(CatPrf, "TransformerEndInfo", pName); + RefNode(CatPrf, "TransformerEndInfo.TransformerTankInfo", pXfCd); + IntegerNode(CatPrf, "TransformerEndInfo.endNumber", i); + if (pXfCd.Fnphases < 3) + { + WindingConnectionEnum(CatPrf, "I"); + if ((i == 3) && (pXfCd.WINDING_[i - 1].kVLL < 0.3)) // for center-tap secondary + IntegerNode(CatPrf, "TransformerEndInfo.phaseAngleClock", 6); + else + IntegerNode(CatPrf, "TransformerEndInfo.phaseAngleClock", 0); + } + else + { + if (pXfCd.WINDING_[i - 1].Connection == 1) + WindingConnectionEnum(CatPrf, "D"); + else if ((pXfCd.WINDING_[i - 1].Rneut > 0.0) || (pXfCd.WINDING_[i - 1].Xneut > 0.0)) + WindingConnectionEnum(CatPrf, "Yn"); + else + WindingConnectionEnum(CatPrf, "Y"); + if (pXfCd.WINDING_[i - 1].Connection != pXfCd.WINDING_[0].Connection) + IntegerNode(CatPrf, "TransformerEndInfo.phaseAngleClock", 1); + else + IntegerNode(CatPrf, "TransformerEndInfo.phaseAngleClock", 0); + } + DoubleNode(CatPrf, "TransformerEndInfo.ratedU", 1000 * pXfCd.WINDING_[i - 1].kVLL); + DoubleNode(CatPrf, "TransformerEndInfo.ratedS", 1000 * pXfCd.WINDING_[i - 1].kVA); + DoubleNode(CatPrf, "TransformerEndInfo.shortTermS", 1000 * pXfCd.WINDING_[i - 1].kVA * ratShort); + DoubleNode(CatPrf, "TransformerEndInfo.emergencyS", 1000 * pXfCd.WINDING_[i - 1].kVA * ratEmerg); + DoubleNode(CatPrf, "TransformerEndInfo.r", pXfCd.WINDING_[i - 1].Rpu * Zbase); + DoubleNode(CatPrf, "TransformerEndInfo.insulationU", 0.0); + EndInstance(CatPrf, "TransformerEndInfo"); + } + pName->LName = pXfCd.get_Name() + "_" + IntToStr(1); + pName->Set_UUID(GetDevUuid(OcTest, pXfCd.get_Name(), 1)); + StartInstance(CatPrf, "NoLoadTest", pName); + UuidNode(CatPrf, "NoLoadTest.EnergisedEnd", GetDevUuid(WdgInf, pXfCd.get_Name(), 1)); + DoubleNode(CatPrf, "NoLoadTest.energisedEndVoltage", 1000.0 * pXfCd.WINDING_[0].kVLL); + pctIexc = sqrt(pXfCd.pctImag * pXfCd.pctImag + pXfCd.pctNoLoadLoss * pXfCd.pctNoLoadLoss); + DoubleNode(CatPrf, "NoLoadTest.excitingCurrent", pctIexc); + DoubleNode(CatPrf, "NoLoadTest.excitingCurrentZero", pctIexc); + val = 0.01 * pXfCd.pctNoLoadLoss * pXfCd.WINDING_[0].kVA; // losses to be in kW + DoubleNode(CatPrf, "NoLoadTest.loss", val); + DoubleNode(CatPrf, "NoLoadTest.lossZero", val); + DoubleNode(CatPrf, "TransformerTest.basePower", 1000.0 * pXfCd.WINDING_[0].kVA); + DoubleNode(CatPrf, "TransformerTest.temperature", 50.0); + EndInstance(CatPrf, "NoLoadTest"); + seq = 0; + for (i = 1; i <= pXfCd.NumWindings; ++i) + { + for (j = (i + 1); j <= pXfCd.NumWindings; ++j) + { + seq++; + pName->LName = pXfCd.get_Name() + "_" + IntToStr(seq); + pName->Set_UUID(GetDevUuid(ScTest, pXfCd.get_Name(), seq)); + StartInstance(CatPrf, "ShortCircuitTest", pName); + UuidNode(CatPrf, "ShortCircuitTest.EnergisedEnd", GetDevUuid(WdgInf, pXfCd.get_Name(), i)); + // NOTE: can insert more than one GroundedEnds for three-winding short-circuit tests + UuidNode(CatPrf, "ShortCircuitTest.GroundedEnds", GetDevUuid(WdgInf, pXfCd.get_Name(), j)); + IntegerNode(CatPrf, "ShortCircuitTest.energisedEndStep", pXfCd.WINDING_[i - 1].NumTaps / 2); + IntegerNode(CatPrf, "ShortCircuitTest.groundedEndStep", pXfCd.WINDING_[j - 1].NumTaps / 2); + // TestKVA = min(Winding[i - 1].kVA, Winding[j - 1].kva); + TestKVA = pXfCd.WINDING_[0].kVA; + Zbase = pXfCd.WINDING_[i - 1].kVLL; + Zbase = 1000.0 * Zbase * Zbase / TestKVA; // all DSS impedances are on winding 1 kva base + // windings are not overloaded during short-circuit tests, but in OpenDSS Sbase is on Winding 1 always + x = pXfCd.XSC[seq - 1]; + r = pXfCd.WINDING_[i - 1].Rpu + pXfCd.WINDING_[j - 1].Rpu; + val = sqrt(r * r + x * x) * Zbase; + DoubleNode(CatPrf, "ShortCircuitTest.leakageImpedance", val); + DoubleNode(CatPrf, "ShortCircuitTest.leakageImpedanceZero", val); + val = r * TestKVA; + DoubleNode(CatPrf, "ShortCircuitTest.loss", val); + DoubleNode(CatPrf, "ShortCircuitTest.lossZero", val); + DoubleNode(CatPrf, "TransformerTest.basePower", 1000.0 * TestKVA); + DoubleNode(CatPrf, "TransformerTest.temperature", 50.0); + EndInstance(CatPrf, "ShortCircuitTest"); + } + } + } + delete pName; +} + +void WriteCableData(TCableDataObj& pCab) +{ + double v1; + // with pCab do { + v1 = To_Meters(pCab.FRadiusUnits); + BooleanNode(CatPrf, "WireInfo.insulated", true); + DoubleNode(CatPrf, "WireInfo.insulationThickness", v1 * pCab.FInsLayer); + ConductorInsulationEnum(CatPrf, "crosslinkedPolyethylene"); // TODO - code EpsR + CableOuterJacketEnum(CatPrf, "none"); + CableConstructionEnum(CatPrf, "stranded"); + BooleanNode(CatPrf, "CableInfo.isStrandFill", false); // we don't really know this + DoubleNode(CatPrf, "CableInfo.diameterOverCore", v1 * (pCab.FDiaIns - 2.0 * pCab.FInsLayer)); + DoubleNode(CatPrf, "CableInfo.diameterOverInsulation", v1 * pCab.FDiaIns); + DoubleNode(CatPrf, "CableInfo.diameterOverJacket", v1 * pCab.FDiaCable); + DoubleNode(CatPrf, "CableInfo.nominalTemperature", 90.0); // we don't really know this + DoubleNode(CatPrf, "CableInfo.relativePermittivity", pCab.FEpsR); + // } +} + +void WriteTapeData(TTSDataObj& pCab) +{ + double v1; + // with pCab do { + v1 = To_Meters(pCab.FRadiusUnits); + DoubleNode(CatPrf, "CableInfo.diameterOverScreen", v1 * (pCab.FDiaShield - 2.0 * pCab.FTapeLayer)); + DoubleNode(CatPrf, "TapeShieldCableInfo.tapeLap", pCab.FTapeLap); + DoubleNode(CatPrf, "TapeShieldCableInfo.tapeThickness", v1 * pCab.FTapeLayer); + CableShieldMaterialEnum(CatPrf, "copper"); + BooleanNode(CatPrf, "CableInfo.sheathAsNeutral", true); + // } +} + +void WriteConcData(TCNDataObj& pCab) +{ + double v1; + // with pCab do { + v1 = To_Meters(pCab.FRadiusUnits); + DoubleNode(CatPrf, "CableInfo.diameterOverScreen", v1 * (pCab.FDiaCable - 2.0 * pCab.FDiaStrand)); + DoubleNode(CatPrf, "ConcentricNeutralCableInfo.diameterOverNeutral", v1 * pCab.FDiaCable); + DoubleNode(CatPrf, "ConcentricNeutralCableInfo.neutralStrandRadius", v1 * 0.5 * pCab.FDiaStrand); + DoubleNode(CatPrf, "ConcentricNeutralCableInfo.neutralStrandGmr", v1 * pCab.FGmrStrand); + v1 = To_per_Meter(pCab.FResistanceUnits); + DoubleNode(CatPrf, "ConcentricNeutralCableInfo.neutralStrandRDC20", v1 * pCab.FRStrand); + IntegerNode(CatPrf, "ConcentricNeutralCableInfo.neutralStrandCount", pCab.FkStrand); + BooleanNode(CatPrf, "CableInfo.sheathAsNeutral", false); + // } +} + +void WriteWireData(TConductorDataObj& pWire) +{ + double v1; + // with pWire do { + StringNode(CatPrf, "WireInfo.sizeDescription", pWire.Get_DisplayName()); + if (CompareText(pWire.get_Name().substr(0, 2), "AA") == 0) + ConductorMaterialEnum(CatPrf, "aluminum"); + else if (CompareText(pWire.get_Name().substr(0, 4), "ACSR") == 0) + ConductorMaterialEnum(CatPrf, "acsr"); + else if (CompareText(pWire.get_Name().substr(0, 2), "CU") == 0) + ConductorMaterialEnum(CatPrf, "copper"); + else if (CompareText(pWire.get_Name().substr(0, 3), "EHS") == 0) + ConductorMaterialEnum(CatPrf, "steel"); + else + ConductorMaterialEnum(CatPrf, "other"); + v1 = To_Meters(pWire.FGMRUnits); + DoubleNode(CatPrf, "WireInfo.gmr", pWire.FGMR60 * v1); + v1 = To_Meters(pWire.FRadiusUnits); + DoubleNode(CatPrf, "WireInfo.radius", pWire.Fradius * v1); + v1 = To_per_Meter(pWire.FResistanceUnits); + DoubleNode(CatPrf, "WireInfo.rDC20", pWire.FRDC * v1); + DoubleNode(CatPrf, "WireInfo.rAC25", pWire.FR60 * v1); + DoubleNode(CatPrf, "WireInfo.rAC50", pWire.FR60 * v1); + DoubleNode(CatPrf, "WireInfo.rAC75", pWire.FR60 * v1); + DoubleNode(CatPrf, "WireInfo.ratedCurrent", std::max(pWire.NormAmps, 0.0)); + IntegerNode(CatPrf, "WireInfo.strandCount", 0); + IntegerNode(CatPrf, "WireInfo.coreStrandCount", 0); + DoubleNode(CatPrf, "WireInfo.coreRadius", 0.0); + // } +} + +void StartCIMFile(Textfile& F, const String &Filenm, ProfileChoice prf) +{ + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + WriteLn(F, ""); + WriteLn(F, ""); + WriteLn(F, ""); + WriteLn(F, ""); + WriteLn(F, Format("", UUIDToCIMString(GetDevUuid(CIMVer, "IEC", 1)).c_str())); + WriteLn(F, Format(" %s", "IEC61970CIM100")); + WriteLn(F, Format(" %s", "2019-04-01")); + WriteLn(F, ""); +} + +void ListXfmrCodes(TXfmrCode &clsXfCd, String lbl) // for debugging +{ + TXfmrCodeObj* pXfCd; + WriteLn("xfmrcodes at " + lbl); + pXfCd = (TXfmrCodeObj*) clsXfCd.ElementList.Get_First(); + while (pXfCd != nullptr) + { + WriteLn(" " + pXfCd->LName + " " + pXfCd->get_Name() + " " + UUIDToString(pXfCd->Get_UUID())); + pXfCd = (TXfmrCodeObj*) clsXfCd.ElementList.Get_Next(); + } +} + +///////// { helper class for exporting IEEE 1547 model parameters ///////////// + +TRemoteSignalObject::TRemoteSignalObject(const String& aBusName, int seq, const String& invName): inherited("ISignal") +{ + busName = aBusName; + pElem = nullptr; + trm = -1; + phase = "A"; + LName = invName + "_" + IntToStr(seq); + Set_UUID(GetDevUuid(I1547Signal, LName, seq)); +} + +TRemoteSignalObject::~TRemoteSignalObject() +{ +} + +bool TIEEE1547Controller::CheckSignalMatch(TRemoteSignalObject& sig, TDSSCktElement& pElm, int seq) +{ + String elmPhases, trmBus; + int dotpos; + + bool Result = false; + trmBus = pElm.GetBus(seq); + dotpos = AnsiPos(".", trmBus); + if (dotpos > 0) + { + trmBus = trmBus.substr(0, dotpos - 1); + } + + if (CompareText(sig.busName, trmBus) == 0) + { + elmPhases = PhaseString(pElm, seq, true); + if (Pos(sig.phase, elmPhases) > 0) + { + sig.trm = seq; + sig.pElem = &pElm; + Result = true; + } + else if ((Pos("1", elmPhases) > 0) && (sig.phase == "A")) + { // switch to secondary phasing + sig.trm = seq; + sig.pElem = &pElm; + sig.phase = "s1"; + Result = true; + } + else if ((Pos("2", elmPhases) > 0) && (sig.phase == "B")) + { // switch to secondary phasing + sig.trm = seq; + sig.pElem = &pElm; + sig.phase = "s2"; + Result = true; + } + } + + return Result; +} + +void TIEEE1547Controller::FindSignalTerminals() +{ + int i, j, k, dotpos; + String bus, phase; + std::vector elements; + bool found; + TDSSCktElement* pElem; + + if (pMonBuses.size() < 1) + { + Signals.clear(); + return; + } + + // create just one remote signal for the main bus, based on the first MonBus + // IEEE 1547 doesn't allow different main buses + // IEEE 1547 also specifies that the average (pos seq) of all applicable voltages be used + // Signals.resize(1); // pMonBuses.size()); + + for (i = 0; i < 1; ++i) + { + bus = pMonBuses[i]; + Signals.emplace_back(bus, i + 1, pInvName->LName); + dotpos = AnsiPos(".", bus); // removes the dot + if (dotpos > 0) + { + phase = bus.substr(0, dotpos - 1); + if (Pos("3", phase) > 0) + Signals[i].phase = "C"; + else if (Pos("2", phase) > 0) + Signals[i].phase = "B"; + else + Signals[i].phase = "A"; + Signals[i].busName = bus.substr(0, dotpos - 1); + } + else + { // this is a three-phase bus, which must be ABC, not s1 and/or s2 + Signals[i].phase = "A"; // if user wants B and/or C as well, the MonBus input should have specified + } + + found = false; + // with ActiveCircuit[ActiveActor] do + { + elements = ActiveCircuit[ActiveActor]->getPDEatBus(Signals[i].busName); + for (j = 0; j < elements.size(); ++j) + { + if (found) + break; + if (ActiveCircuit[ActiveActor]->SetElementActive(elements[j]) > 0) + { + pElem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + for (k = 1; k <= pElem->Fnterms; ++k) + { + if (CheckSignalMatch(Signals[i], *pElem, k)) + { + found = true; + break; + } + } + } + } + if (!found) + { + elements = ActiveCircuit[ActiveActor]->getPCEatBus(bus); + for (j = 0; j < elements.size(); ++j) + { + if (found) + break; + if (ActiveCircuit[ActiveActor]->SetElementActive(elements[j]) > 0) + { + pElem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + for (k = 1; k <= pElem->Fnterms; ++k) + { + if (CheckSignalMatch(Signals[i], *pElem, k)) + { + found = true; + break; + } + } + } + } + } + } + } +} + +TIEEE1547Controller::TIEEE1547Controller() +{ + SetDefaults(false); + pInvName = new TNamedObject("Inv"); + pPlateName = new TNamedObject("Nameplate"); + pSetName = new TNamedObject("Settings"); +} + +TIEEE1547Controller::~TIEEE1547Controller() +{ + delete pInvName; + delete pPlateName; + delete pSetName; +} + +void TIEEE1547Controller::PullFromInvControl(TInvControlObj& pInv) +{ + TXYcurveObj* xy; + bool bCatB, bValid, bSet1, bSet2, bSet3, bSet4, bSet5, bSet6; + int mode, combi, i; + double v, p, q, qvslope; + + pInvName->LName = pInv.get_Name(); + pInvName->Set_UUID(pInv.Get_UUID()); + pDERNames = pInv.FDERNameList; + if (pInv.FMonBusesNameList.size() > 0) + pMonBuses = pInv.FMonBusesNameList; + else + pMonBuses.clear(); + + bCatB = false; + xy = pInv.Fvvc_curve; + if (xy != nullptr) + { + for (i = 1; i <= xy->FNumPoints; ++i) + { + if (xy->Get_YValue(i) < -CatBQmin) + { + bCatB = true; + break; + } + } + } + SetDefaults(bCatB); + + VV_olrt = pInv.get_FLPFTau() * 2.3026; + VW_olrt = VV_olrt; + + if (xy != nullptr) + { + i = 1; + bValid = false; + bSet1 = false; + bSet2 = false; + bSet3 = false; + bSet4 = false; + while (i <= xy->FNumPoints) + { + v = xy->Get_XValue(i); + if ((v >= 0.77) && (v <= 1.25)) + bValid = true; + if (bValid) + { + if (!bSet1) + { + VV_curveV1 = v; + VV_curveQ1 = xy->Get_YValue(i); + bSet1 = true; + } + else if (!bSet2) + { + if (v > 1.05) + { + VV_curveV2 = 1.0; + VV_curveQ2 = 0.0; + if (v > 1.08) + { + VV_curveV3 = 1.0; + VV_curveQ3 = 0.0; + bSet3 = true; + VV_curveV4 = v; + VV_curveQ4 = xy->Get_YValue(i); + bSet4 = true; + } + } + else + { + VV_curveV2 = v; + VV_curveQ2 = xy->Get_YValue(i); + } + bSet2 = true; + } + else if (!bSet3) + { + VV_curveV3 = v; + VV_curveQ3 = xy->Get_YValue(i); + bSet3 = true; + } + else if (!bSet4) + { + VV_curveV4 = v; + VV_curveQ4 = xy->Get_YValue(i); + bSet4 = true; + } + } + i++; + } + } + + xy = pInv.Fvoltwatt_curve; + if ((xy != nullptr)) + { + i = 1; + bValid = false; + bSet1 = false; + bSet2 = false; + while (i <= xy->FNumPoints) + { + v = xy->Get_XValue(i); + p = xy->Get_YValue(i); + if ((v >= 1.00) && (v <= 1.10)) + bValid = true; // TODO: per standard, v should be >= 1.05 but we loosen that criteria for testing + if (bValid) + { + if (!bSet1) + { + VW_curveV1 = v; + VW_curveP1 = p; // this is actually supposed to be 1.0 always + bSet1 = true; + } + else if (!bSet2) + { + VW_curveV2 = v; + if (p < 0.0) + { + VW_curveP2gen = 0.2; // TODO: should have a pMin + VW_curveP2load = p; + } + else + { + VW_curveP2gen = p; + VW_curveP2load = 0.0; + } + bSet2 = true; + } + } + i++; + } + } + + xy = pInv.FvoltwattCH_curve; + if ((xy != nullptr)) + { + p = 0.0; + i = 1; + while (i <= xy->FNumPoints) + { + if (xy->Get_YValue(i) > p) + p = xy->Get_YValue(i); + i++; + } + if ((-p < VW_curveP2load)) + VW_curveP2load = -p; + } + + xy = pInv.Fwattvar_curve; + if ((xy != nullptr)) + { + i = 1; + bValid = false; + bSet1 = false; + bSet2 = false; + bSet3 = false; + bSet4 = false; + bSet5 = false; + bSet6 = false; + while (i <= xy->FNumPoints) + { + p = xy->Get_XValue(i); + q = xy->Get_YValue(i); + if ((p >= -1.0) && (p <= 1.0)) + bValid = true; + if (bValid) + { + if (!bSet1) + { + if (p <= -0.5) + { + WV_curveP3load = p; + WV_curveQ3load = q; + } + else + { + WV_curveP3load = -1.0; + WV_curveQ3load = 0.0; + i--; // re-scan + } + bSet1 = true; + } + else if (!bSet2) + { + if (p <= -0.4) + { + WV_curveP2load = p; + WV_curveQ2load = q; + } + else + { + WV_curveP2load = -0.5; + WV_curveQ2load = 0.0; + i--; // re-scan + } + bSet2 = true; + } + else if (!bSet3) + { + if (p <= 0.0) + { + WV_curveP1load = p; + WV_curveQ1load = q; + } + else + { + WV_curveP1load = -0.2; + WV_curveQ1load = 0.0; + i--; // re-scan + } + bSet3 = true; + } + else if (!bSet4) + { + if (p <= 0.7) + { + WV_curveP1gen = p; + WV_curveQ1gen = q; + } + else + { + WV_curveP1gen = 0.2; + WV_curveQ1gen = 0.0; + i--; // re-scan + } + bSet4 = true; + } + else if (!bSet5) + { + if (p <= 0.8) + { + WV_curveP2gen = p; + WV_curveQ2gen = q; + } + else + { + WV_curveP2gen = 0.5; + WV_curveQ2gen = 0.0; + i--; // re-scan + } + bSet5 = true; + } + else if (!bSet6) + { + if (p <= 1.0) + { + WV_curveP3gen = p; + WV_curveQ3gen = q; + } + else + { + WV_curveP3gen = 1.0; + WV_curveQ3gen = 0.0; + i--; // re-scan + } + bSet6 = true; + } + } + i++; + } + // handle the edge cases when default zero watt-var points were not input + if (WV_curveP1gen >= WV_curveP2gen) + WV_curveP1gen = WV_curveP2gen - 0.1; + if (WV_curveP1load <= WV_curveP2load) + WV_curveP1load = WV_curveP2load + 0.1; + } + + /* copied from InvControl!! + // Modes + NONE_MODE = 0; + VOLTWATT = 2; + DRC = 3; + WATTPF = 4; + WATTVAR = 5; + AVR = 6; + + // Combi Modes + NONE_COMBMODE = 0; + VV_VW = 1; + VV_DRC = 2; + */ + mode = pInv.ControlMode; + combi = pInv.CombiControlMode; + if (combi == 1) + { + PF_enabled = false; + VV_enabled = true; + VW_enabled = true; + } + else if (combi == 2) + { + PF_enabled = false; + VV_enabled = true; + } + else if (mode == 1) + { + PF_enabled = false; + VV_enabled = true; + } + else if (mode == 2) + { + PF_enabled = false; + VW_enabled = true; + } + else if (mode == 3) + { // approximating AVR with DRC + PF_enabled = false; + VV_enabled = true; + VV_vRefAutoModeEnabled = true; + VV_vRefOlrt = pInv.get_FDRCRollAvgWindowLength(); + qvslope = 0.5 * (pInv.get_FArGraLowV() + pInv.get_FArGraHiV()); + if (qvslope > 12.5) + bCatB = true; // for catA, maximum slope would be 12.5 + if (bCatB) + q = 0.44; + else + q = 0.25; + VV_curveQ1 = q; + VV_curveQ2 = VV_curveQ1; + VV_curveQ3 = -VV_curveQ1; + VV_curveQ4 = VV_curveQ3; + VV_curveV1 = 0.50; + VV_curveV2 = 1.0 - VV_curveQ2 / qvslope; + VV_curveV3 = 1.0 - VV_curveQ3 / qvslope; // - because Q3 should be negative + VV_curveV4 = 1.50; + } + else if (mode == 5) + { + PF_enabled = false; + WV_enabled = true; + } +} + +void TIEEE1547Controller::PullFromExpControl(TExpControlObj& pExp) +{ + int i; + pInvName->LName = pExp.get_Name(); + pInvName->Set_UUID(pExp.Get_UUID()); + i = 0; + while (i < pExp.FDERNameList->size()) + { + pDERNames.push_back((*pExp.FDERNameList)[i]); + i++; + } + pMonBuses.clear(); + + if (pExp.FQmaxLead > CatBQmin) // catB estimate + SetDefaults(true); + else + SetDefaults(false); + + PF_enabled = false; + VV_enabled = true; + VV_vRefAutoModeEnabled = true; + VV_vRefOlrt = pExp.FVregTau; + VV_olrt = pExp.FTresponse; + VV_curveQ1 = pExp.FQmaxLead; + VV_curveQ2 = VV_curveQ1; + VV_curveQ3 = -pExp.FQmaxLag; + VV_curveQ4 = VV_curveQ3; + VV_curveV1 = 0.50; + VV_curveV2 = 1.0 - VV_curveQ2 / pExp.FSlope; + VV_curveV3 = 1.0 - VV_curveQ3 / pExp.FSlope; // - because Q3 should be negative + VV_curveV4 = 1.50; +} + +void TIEEE1547Controller::SetDefaults(bool bCatB) +{ + bNameplateSet = false; + ND_acVmax = 1.05; + ND_acVmin = 0.95; + AD_pMax = 0.0; + AD_pMaxOverPF = 0.0; + AD_overPF = 0.0; + AD_pMaxUnderPF = 0.0; + AD_underPF = 0.0; + AD_sMax = 0.0; + AD_pMaxCharge = 0.0; + AD_apparentPowerChargeMax = 0.0; + AD_acVnom = 0.0; + AD_qMaxInj = 0.44; + if (bCatB) + { + ND_normalOPcatKind = "catB"; + AD_qMaxAbs = 0.44; + VV_curveV1 = 0.92; + VV_curveV2 = 0.98; + VV_curveV3 = 1.02; + VV_curveV4 = 1.08; + VV_curveQ1 = 0.44; + VV_curveQ2 = 0.0; + VV_curveQ3 = 0.0; + VV_curveQ4 = -0.44; + VV_olrt = 5.0; + WV_curveQ3load = 0.44; + } + else + { + ND_normalOPcatKind = "catA"; + AD_qMaxAbs = 0.25; + VV_curveV1 = 0.90; + VV_curveV2 = 1.00; + VV_curveV3 = 1.00; + VV_curveV4 = 1.10; + VV_curveQ1 = 0.25; + VV_curveQ2 = 0.0; + VV_curveQ3 = 0.0; + VV_curveQ4 = -0.25; + VV_olrt = 10.0; + WV_curveQ3load = 0.25; + } + VV_vRef = 1.0; + VV_vRefOlrt = 300.0; + Q_reactivePower = 0.0; + PF_powerFactor = 1.0; + VW_olrt = 10.0; + VW_curveV1 = 1.06; + VW_curveV2 = 1.10; + VW_curveP1 = 1.0; + VW_curveP2gen = 0.2; + VW_curveP2load = 0.0; // for storage, -1.0 + + WV_curveP1gen = 0.2; + WV_curveP2gen = 0.5; + WV_curveP3gen = 1.0; + WV_curveP1load = 0.0; // for storage, 0.2, 0.5, 1.0 + WV_curveP2load = 0.0; + WV_curveP3load = 0.0; + WV_curveQ1gen = 0.0; + WV_curveQ2gen = 0.0; + WV_curveQ3gen = 0.44; + WV_curveQ1load = 0.0; + WV_curveQ2load = 0.0; + + PF_constPFexcitationKind = "inj"; + VV_enabled = false; + WV_enabled = false; + PF_enabled = true; + Q_enabled = false; + VW_enabled = false; + VV_vRefAutoModeEnabled = false; +} + +void TIEEE1547Controller::FinishNameplate() +{ + AD_overPF = AD_pMaxOverPF / AD_sMax; + AD_underPF = AD_pMaxUnderPF / AD_sMax; + bNameplateSet = true; +} + +void TIEEE1547Controller::SetStorageNameplate(TStorageObj& pBat) +{ + AD_acVnom = pBat.Get_acVnom() * 1000.0; + ND_acVmax = pBat.Get_acVmax() * 1000.0; + ND_acVmin = pBat.Get_acVmin() * 1000.0; + AD_sMax = pBat.Get_FkVARating() * 1000.0; + AD_pMax = pBat.Get_Pmax() * 1000.0; + AD_pMaxOverPF = pBat.Get_pMaxOverPF() * 1000.0; + AD_pMaxUnderPF = pBat.Get_pMaxUnderPF() * 1000.0; + AD_pMaxCharge = pBat.Get_pMaxCharge() * 1000.0; + AD_apparentPowerChargeMax = pBat.Get_sMaxCharge() * 1000.0; + AD_qMaxInj = pBat.Get_qMaxInj() * 1000.0; + AD_qMaxAbs = pBat.Get_qMaxAbs() * 1000.0; + FinishNameplate(); +} + +void TIEEE1547Controller::SetPhotovoltaicNameplate(TPVsystemObj& pPV) +{ + AD_acVnom = pPV.Get_acVnom() * 1000.0; + ND_acVmax = pPV.Get_acVmax() * 1000.0; + ND_acVmin = pPV.Get_acVmin() * 1000.0; + AD_sMax = pPV.Get_FkVArating() * 1000.0; + AD_pMax = pPV.Get_Pmax() * 1000.0; + AD_pMaxOverPF = pPV.Get_pMaxOverPF() * 1000.0; + AD_pMaxUnderPF = pPV.Get_pMaxUnderPF() * 1000.0; + AD_pMaxCharge = pPV.Get_pMaxCharge() * 1000.0; + AD_apparentPowerChargeMax = pPV.Get_sMaxCharge() * 1000.0; + AD_qMaxInj = pPV.Get_qMaxInj() * 1000.0; + AD_qMaxAbs = pPV.Get_qMaxAbs() * 1000.0; + FinishNameplate(); +} + +void TIEEE1547Controller::SetElementNameplate(TDSSCktElement& pElem) +{ + if (bNameplateSet) + return; + if (pElem.DSSObjType == (PC_ELEMENT + PVSYSTEM_ELEMENT)) + SetPhotovoltaicNameplate(*((TPVsystemObj*)(&pElem))); + if (pElem.DSSObjType == (PC_ELEMENT + STORAGE_ELEMENT)) + SetStorageNameplate(*((TStorageObj*)(&pElem))); + FinishNameplate(); +} + +void TIEEE1547Controller::WriteCIM(ProfileChoice prf) +{ + int i; + TPVsystemObj* pPV; + TStorageObj* pBat; + + FindSignalTerminals(); + StartInstance(prf, "DERIEEEType1", pInvName); + BooleanNode(prf, "DynamicsFunctionBlock.enabled", true); + BooleanNode(prf, "DERIEEEType1.phaseToGroundApplicable", true); // seems to be the only OpenDSS option + BooleanNode(prf, "DERIEEEType1.phaseToNeutralApplicable", false); + BooleanNode(prf, "DERIEEEType1.phaseToPhaseApplicable", false); + // with ActiveCircuit[ActiveActor] do { + if (pDERNames.size() < 1) + { + pBat = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + while (pBat != nullptr) + { + if (pBat->FEnabled) + { + RefNode(prf, "DERDynamics.PowerElectronicsConnection", pBat); + SetStorageNameplate(*pBat); + } + pBat = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } + pPV = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + while (pPV != nullptr) + { + if (pPV->FEnabled) + { + RefNode(prf, "DERDynamics.PowerElectronicsConnection", pPV); + SetPhotovoltaicNameplate(*pPV); + } + pPV = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } + } + else + { + for (i = 1; i <= pDERNames.size(); ++i) + { + ActiveCircuit[ActiveActor]->SetElementActive(pDERNames[i - 1]); + RefNode(prf, "DERDynamics.PowerElectronicsConnection", ActiveCircuit[ActiveActor]->FActiveCktElement); + SetElementNameplate(*ActiveCircuit[ActiveActor]->FActiveCktElement); + } + } + // } + + for (i = 0; i < Signals.size(); ++i) + RefNode(prf, "DERDynamics.RemoteInputSignal", Signals[i]); + EndInstance(prf, "DERIEEEType1"); + + for (i = 0; i < Signals.size(); ++i) + { + StartInstance(prf, "RemoteInputSignal", Signals[i]); + RemoteInputSignalEnum(prf, "remoteBusVoltageAmplitude"); + UuidNode(prf, "RemoteInputSignal.Terminal", GetTermUuid(*Signals[i].pElem, Signals[i].trm)); + EndInstance(prf, "RemoteInputSignal"); + } + + pPlateName->LName = pInvName->LName; + pPlateName->Set_UUID(GetDevUuid(I1547NameplateData, pInvName->LName, 1)); + StartInstance(prf, "DERNameplateData", pPlateName); + RefNode(prf, "DERNameplateData.DERIEEEType1", pInvName); + NormalOpCatEnum(prf, ND_normalOPcatKind); + BooleanNode(prf, "DERNameplateData.supportsConstPFmode", true); + BooleanNode(prf, "DERNameplateData.supportsConstQmode", true); + BooleanNode(prf, "DERNameplateData.supportsQVmode", true); + if (ND_normalOPcatKind == "catB") + { + BooleanNode(prf, "DERNameplateData.supportsPVmode", true); + BooleanNode(prf, "DERNameplateData.supportsQPmode", true); + } + else + { + BooleanNode(prf, "DERNameplateData.supportsPVmode", false); + BooleanNode(prf, "DERNameplateData.supportsQPmode", false); + } + BooleanNode(prf, "DERNameplateData.supportsPFmode", false); // no frequency response in GridAPPS-D + DoubleNode(prf, "DERNameplateData.acVmax", ND_acVmax); + DoubleNode(prf, "DERNameplateData.acVmin", ND_acVmin); + EndInstance(prf, "DERNameplateData"); + + pSetName->LName = pInvName->LName; + pSetName->Set_UUID(GetDevUuid(I1547NameplateDataApplied, pSetName->LName, 1)); + StartInstance(prf, "DERNameplateDataApplied", pSetName); + RefNode(prf, "DERNameplateDataApplied.DERNameplateData", pPlateName); + DoubleNode(prf, "DERNameplateDataApplied.pMax", AD_pMax); + DoubleNode(prf, "DERNameplateDataApplied.pMaxOverPF", AD_pMaxOverPF); + DoubleNode(prf, "DERNameplateDataApplied.overPF", AD_overPF); + DoubleNode(prf, "DERNameplateDataApplied.pMaxUnderPF", AD_pMaxUnderPF); + DoubleNode(prf, "DERNameplateDataApplied.underPF", AD_underPF); + DoubleNode(prf, "DERNameplateDataApplied.sMax", AD_sMax); + DoubleNode(prf, "DERNameplateDataApplied.qMaxInj", AD_qMaxInj); + DoubleNode(prf, "DERNameplateDataApplied.qMaxAbs", AD_qMaxAbs); + DoubleNode(prf, "DERNameplateDataApplied.pMaxCharge", AD_pMaxCharge); + DoubleNode(prf, "DERNameplateDataApplied.apparentPowerChargeMax", AD_apparentPowerChargeMax); + DoubleNode(prf, "DERNameplateDataApplied.acVnom", AD_acVnom); + EndInstance(prf, "DERNameplateDataApplied"); + + pSetName->Set_UUID(GetDevUuid(I1547VoltVar, pSetName->LName, 1)); + StartInstance(prf, "VoltVarSettings", pSetName); + RefNode(prf, "VoltVarSettings.DERIEEEType1", pInvName); + BooleanNode(prf, "VoltVarSettings.enabled", VV_enabled); + BooleanNode(prf, "VoltVarSettings.vRefAutoModeEnabled", VV_vRefAutoModeEnabled); + DoubleNode(prf, "VoltVarSettings.vRef", VV_vRef); + DoubleNode(prf, "VoltVarSettings.vRefOlrt", VV_vRefOlrt); + DoubleNode(prf, "VoltVarSettings.curveV1", VV_curveV1); + DoubleNode(prf, "VoltVarSettings.curveV2", VV_curveV2); + DoubleNode(prf, "VoltVarSettings.curveV3", VV_curveV3); + DoubleNode(prf, "VoltVarSettings.curveV4", VV_curveV4); + DoubleNode(prf, "VoltVarSettings.curveQ1", VV_curveQ1); + DoubleNode(prf, "VoltVarSettings.curveQ2", VV_curveQ2); + DoubleNode(prf, "VoltVarSettings.curveQ3", VV_curveQ3); + DoubleNode(prf, "VoltVarSettings.curveQ4", VV_curveQ4); + DoubleNode(prf, "VoltVarSettings.olrt", VV_olrt); + EndInstance(prf, "VoltVarSettings"); + + pSetName->Set_UUID(GetDevUuid(I1547WattVar, pSetName->LName, 1)); + StartInstance(prf, "WattVarSettings", pSetName); + RefNode(prf, "WattVarSettings.DERIEEEType1", pInvName); + BooleanNode(prf, "WattVarSettings.enabled", WV_enabled); + DoubleNode(prf, "WattVarSettings.curveP1gen", WV_curveP1gen); + DoubleNode(prf, "WattVarSettings.curveP2gen", WV_curveP2gen); + DoubleNode(prf, "WattVarSettings.curveP3gen", WV_curveP3gen); + DoubleNode(prf, "WattVarSettings.curveQ1gen", WV_curveQ1gen); + DoubleNode(prf, "WattVarSettings.curveQ2gen", WV_curveQ2gen); + DoubleNode(prf, "WattVarSettings.curveQ3gen", WV_curveQ3gen); + DoubleNode(prf, "WattVarSettings.curveP1load", WV_curveP1load); + DoubleNode(prf, "WattVarSettings.curveP2load", WV_curveP2load); + DoubleNode(prf, "WattVarSettings.curveP3load", WV_curveP3load); + DoubleNode(prf, "WattVarSettings.curveQ1load", WV_curveQ1load); + DoubleNode(prf, "WattVarSettings.curveQ2load", WV_curveQ2load); + DoubleNode(prf, "WattVarSettings.curveQ3load", WV_curveQ3load); + EndInstance(prf, "WattVarSettings"); + + pSetName->Set_UUID(GetDevUuid(I1547ConstPF, pSetName->LName, 1)); + StartInstance(prf, "ConstantPowerFactorSettings", pSetName); + RefNode(prf, "ConstantPowerFactorSettings.DERIEEEType1", pInvName); + BooleanNode(prf, "ConstantPowerFactorSettings.enabled", PF_enabled); + PowerFactorExcitationEnum(prf, PF_constPFexcitationKind); + DoubleNode(prf, "ConstantPowerFactorSettings.powerFactor", PF_powerFactor); + EndInstance(prf, "ConstantPowerFactorSettings"); + + pSetName->Set_UUID(GetDevUuid(I1547ConstQ, pSetName->LName, 1)); + StartInstance(prf, "ConstantReactivePowerSettings", pSetName); + RefNode(prf, "ConstantReactivePowerSettings.DERIEEEType1", pInvName); + BooleanNode(prf, "ConstantReactivePowerSettings.enabled", Q_enabled); + DoubleNode(prf, "ConstantReactivePowerSettings.reactivePower", Q_reactivePower); + EndInstance(prf, "ConstantReactivePowerSettings"); + + pSetName->Set_UUID(GetDevUuid(I1547VoltWatt, pSetName->LName, 1)); + StartInstance(prf, "VoltWattSettings", pSetName); + RefNode(prf, "VoltWattSettings.DERIEEEType1", pInvName); + BooleanNode(prf, "VoltWattSettings.enabled", VW_enabled); + DoubleNode(prf, "VoltWattSettings.curveV1", VW_curveV1); + DoubleNode(prf, "VoltWattSettings.curveV2", VW_curveV2); + DoubleNode(prf, "VoltWattSettings.curveP1", VW_curveP1); + DoubleNode(prf, "VoltWattSettings.curveP2gen", VW_curveP2gen); + DoubleNode(prf, "VoltWattSettings.curveP2load", VW_curveP2load); + DoubleNode(prf, "VoltWattSettings.olrt", VW_olrt); + EndInstance(prf, "VoltWattSettings"); +} + +///////// } helper class for exporting IEEE 1547 model parameters ///////////// + +void ExportCDPSM(String Filenm, String Substation, String SubGeographicRegion, String GeographicRegion, TUuid FdrUUID, TUuid SubUUID, TUuid SubGeoUUID, TUuid RgnUUID, bool Combined) +{ + int i, j, k; + int seq; + double val; + bool bval; + double v1, v2; + int i1, i2; + complex Zs, Zm; + double Rs, Rm, Xs, Xm, R1, R0, X1, X0; + TNamedObject *pName1, *pName2; + TNamedObject *pIsland, *pSwing; // island and ref node + TNamedObject *pRegion, *pSubRegion, *pLocation, *pSubstation, *pCRS; + + TOpLimitObject *pILimit; + TNamedObject *pNormLimit, *pEmergLimit, *pRangeAHiLimit, *pRangeALoLimit, *pRangeBHiLimit, *pRangeBLoLimit; // OperationalLimitType + String LimitName; + TUuid LimiTUuid; + + double zbase; + String s; + String swtCls; // based on controls, if any, attached to a line having switch=yes + double ratedAmps, breakingAmps; + + TBankObject* pBank; + int maxWdg; + std::vector WdgList; + std::vector CoreList; + std::vector MeshList; + String sBank; + bool bTanks; + + TLoadObj* pLoad; + TVsourceObj* pVsrc; + TGeneratorObj* pGen; + TPVsystemObj* pPV; + TStorageObj* pBat; + TECPObject *pECP; + + TCapacitorObj* pCap; + TCapControlObj* pCapC; + TTransfObj* pXf; + TAutoTransObj* pAuto; + TRegControlObj* pReg; + TLineObj* pLine; + TReactorObj* pReac; + TInvControlObj* pInv; + TExpControlObj* pExp; + TIEEE1547Controller* pI1547; + + TLineCode* clsLnCd; + TLineGeometry* clsGeom; + TWireData* clsWire; + TXfmrCode* clsXfCd; + TLineSpacing* clsSpac; + TTSData* clsTape; + TCNData* clsConc; + + TLineCodeObj* pLnCd; + TLineGeometryObj* pGeom; + TWireDataObj* pWire; + TXfmrCodeObj* pXfCd; + TLineSpacingObj* pSpac; + TTSDataObj* pTape; + TCNDataObj* pConc; + + // DSS-like load models + TUuid id1_ConstkVA; + TUuid id2_ConstZ; + TUuid id3_ConstPQuadQ; + TUuid id4_LinPQuadQ; + TUuid id5_ConstI; + TUuid id6_ConstPConstQ; // P can vary, Q not + TUuid id7_ConstPConstX; + + // for CIM Locations + TUuid geoUUID; + TUuid crsUUID; + + try + { + clsLnCd = (TLineCode*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("linecode")); + clsWire = (TWireData*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("wiredata")); + clsGeom = (TLineGeometry*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("linegeometry")); + clsXfCd = (TXfmrCode*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("xfmrcode")); + clsSpac = (TLineSpacing*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("linespacing")); + clsTape = (TTSData*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("TSData")); + clsConc = (TCNData*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("CNData")); + pName1 = new TNamedObject("Temp1"); + pName2 = new TNamedObject("Temp2"); + if (UuidList.empty()) + { // this may have been done already from the uuids command + i1 = clsXfCd->Get_ElementCount() * 6; // 3 wdg info, 3 sctest + i2 = ActiveCircuit[ActiveActor]->Transformers.NumInList * 11; // bank, info, 3 wdg, 3 wdg info, 3sctest + StartUuidList(i1 + i2); + } + StartBankList(ActiveCircuit[ActiveActor]->Transformers.NumInList + ActiveCircuit[ActiveActor]->AutoTransformers.NumInList); + StartECPList(ActiveCircuit[ActiveActor]->Loads.NumInList + ActiveCircuit[ActiveActor]->Generators.NumInList + ActiveCircuit[ActiveActor]->StorageElements.NumInList + ActiveCircuit[ActiveActor]->PVSystems.NumInList); + StartOpLimitList(ActiveCircuit[ActiveActor]->Lines.NumInList + ActiveCircuit[ActiveActor]->Transformers.NumInList + ActiveCircuit[ActiveActor]->AutoTransformers.NumInList + 1); + + + FD = new TFileDealer(Combined, Filenm); + + pCRS = new TNamedObject("CoordinateSystem"); + crsUUID = GetDevUuid(CoordSys, "Local", 1); + pCRS->Set_UUID(crsUUID); + pCRS->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_CrsUrn"; + StartInstance(GeoPrf, "CoordinateSystem", pCRS); + StringNode(GeoPrf, "CoordinateSystem.crsUrn", "OpenDSSLocalBusCoordinates"); + EndInstance(GeoPrf, "CoordinateSystem"); + + pRegion = new TNamedObject("GeographicalRegion"); + pRegion->Set_UUID(RgnUUID); + pRegion->LName = GeographicRegion; + StartInstance(FunPrf, "GeographicalRegion", pRegion); + EndInstance(FunPrf, "GeographicalRegion"); + + pSubRegion = new TNamedObject("SubGeographicalRegion"); + pSubRegion->Set_UUID(SubGeoUUID); + pSubRegion->LName = SubGeographicRegion; + StartInstance(FunPrf, "SubGeographicalRegion", pSubRegion); + RefNode(FunPrf, "SubGeographicalRegion.Region", pRegion); + EndInstance(FunPrf, "SubGeographicalRegion"); + + pSubstation = new TNamedObject("Substation"); + pSubstation->Set_UUID(SubUUID); + pSubstation->LName = Substation; + StartInstance(FunPrf, "Substation", pSubstation); + RefNode(FunPrf, "Substation.Region", pSubRegion); + EndInstance(FunPrf, "Substation"); + + pLocation = new TNamedObject("Location"); + pLocation->Set_UUID(GetDevUuid(FdrLoc, ActiveCircuit[ActiveActor]->Get_Name(), 1)); + pLocation->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_Location"; + StartInstance(GeoPrf, "Location", pLocation); + UuidNode(GeoPrf, "Location.CoordinateSystem", crsUUID); + EndInstance(GeoPrf, "Location"); + + ActiveCircuit[ActiveActor]->Set_UUID(FdrUUID); + StartInstance(FunPrf, "Feeder", ActiveCircuit[ActiveActor]); + RefNode(FunPrf, "Feeder.NormalEnergizingSubstation", pSubstation); + RefNode(FunPrf, "PowerSystemResource.Location", pLocation); + EndInstance(FunPrf, "Feeder"); + + // the whole system will be a topo island + pIsland = new TNamedObject("Island"); + pIsland->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_Island"; + pIsland->Set_UUID(GetDevUuid(TopoIsland, "Island", 1)); + pSwing = new TNamedObject("SwingBus"); + pSwing->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_SwingBus"; + + pNormLimit = new TNamedObject("NormalAmpsType"); + pNormLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_NormAmpsType"; + pNormLimit->Set_UUID(GetDevUuid(OpLimT, "NormalAmps", 1)); + StartInstance(FunPrf, "OperationalLimitType", pNormLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 5.0e9); // more than 100 years + OpLimitDirectionEnum(FunPrf, "absoluteValue"); + EndInstance(FunPrf, "OperationalLimitType"); + + pEmergLimit = new TNamedObject("EmergencyAmpsType"); + pEmergLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_EmergencyAmpsType"; + pEmergLimit->Set_UUID(GetDevUuid(OpLimT, "EmergencyAmps", 1)); + StartInstance(FunPrf, "OperationalLimitType", pEmergLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 2.0 * 3600.0); // 2 hours + OpLimitDirectionEnum(FunPrf, "absoluteValue"); + EndInstance(FunPrf, "OperationalLimitType"); + + pRangeAHiLimit = new TNamedObject("RangeAHiType"); + pRangeAHiLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_RangeAHiType"; + pRangeAHiLimit->Set_UUID(GetDevUuid(OpLimT, "AHi", 1)); + StartInstance(FunPrf, "OperationalLimitType", pRangeAHiLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 5.0e9); + OpLimitDirectionEnum(FunPrf, "high"); + EndInstance(FunPrf, "OperationalLimitType"); + + pRangeALoLimit = new TNamedObject("RangeALoType"); + pRangeALoLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_RangeALoType"; + pRangeALoLimit->Set_UUID(GetDevUuid(OpLimT, "ALo", 1)); + StartInstance(FunPrf, "OperationalLimitType", pRangeALoLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 5.0e9); + OpLimitDirectionEnum(FunPrf, "low"); + EndInstance(FunPrf, "OperationalLimitType"); + + pRangeBHiLimit = new TNamedObject("RangeBHiType"); + pRangeBHiLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_RangeBHiType"; + pRangeBHiLimit->Set_UUID(GetDevUuid(OpLimT, "BHi", 1)); + StartInstance(FunPrf, "OperationalLimitType", pRangeBHiLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 24.0 * 3600.0); + OpLimitDirectionEnum(FunPrf, "high"); + EndInstance(FunPrf, "OperationalLimitType"); + + pRangeBLoLimit = new TNamedObject("RangeBLoType"); + pRangeBLoLimit->LName = ActiveCircuit[ActiveActor]->Get_Name() + "_RangeBLoType"; + pRangeBLoLimit->Set_UUID(GetDevUuid(OpLimT, "BLo", 1)); + StartInstance(FunPrf, "OperationalLimitType", pRangeBLoLimit); + DoubleNode(FunPrf, "OperationalLimitType.acceptableDuration", 24.0 * 3600.0); + OpLimitDirectionEnum(FunPrf, "low"); + EndInstance(FunPrf, "OperationalLimitType"); + + // with ActiveCircuit[ActiveActor] do + // build the lists of base voltages and operational voltage limits + i = 0; + while (ActiveCircuit[ActiveActor]->LegalVoltageBases[i] > 0.0) + { + s = GetBaseVName(ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + pName1->LName = s; + pName1->Set_UUID(GetBaseVUuid(ActiveCircuit[ActiveActor]->LegalVoltageBases[i])); + StartInstance(FunPrf, "BaseVoltage", pName1); + DoubleNode(FunPrf, "BaseVoltage.nominalVoltage", 1000.0 * ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + EndInstance(FunPrf, "BaseVoltage"); + + pName1->LName = GetOpLimVName(ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + pName1->Set_UUID(GetOpLimVUuid(ActiveCircuit[ActiveActor]->LegalVoltageBases[i])); + StartInstance(FunPrf, "OperationalLimitSet", pName1); + EndInstance(FunPrf, "OperationalLimitSet"); + + pName2->LName = pName1->LName + "_RangeAHi"; + pName2->Set_UUID(GetDevUuid(OpLimAHi, s, 1)); + StartInstance(FunPrf, "VoltageLimit", pName2); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pName1); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pRangeAHiLimit); + DoubleNode(FunPrf, "VoltageLimit.value", 1.05 * 1000.0 * ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + EndInstance(FunPrf, "VoltageLimit"); + + pName2->LName = pName1->LName + "_RangeALo"; + pName2->Set_UUID(GetDevUuid(OpLimALo, s, 1)); + StartInstance(FunPrf, "VoltageLimit", pName2); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pName1); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pRangeALoLimit); + DoubleNode(FunPrf, "VoltageLimit.value", 0.95 * 1000.0 * ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + EndInstance(FunPrf, "VoltageLimit"); + + pName2->LName = pName1->LName + "_RangeBHi"; + pName2->Set_UUID(GetDevUuid(OpLimBHi, s, 1)); + StartInstance(FunPrf, "VoltageLimit", pName2); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pName1); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pRangeBHiLimit); + DoubleNode(FunPrf, "VoltageLimit.value", 1.0583333 * 1000.0 * ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + EndInstance(FunPrf, "VoltageLimit"); + + pName2->LName = pName1->LName + "_RangeBLo"; + pName2->Set_UUID(GetDevUuid(OpLimBLo, s, 1)); + StartInstance(FunPrf, "VoltageLimit", pName2); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pName1); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pRangeBLoLimit); + DoubleNode(FunPrf, "VoltageLimit.value", 0.9166667 * 1000.0 * ActiveCircuit[ActiveActor]->LegalVoltageBases[i]); + EndInstance(FunPrf, "VoltageLimit"); + + i++; + } + + for (i = 1; i <= ActiveCircuit[ActiveActor]->NumBuses; ++i) + { + ActiveCircuit[ActiveActor]->Buses[i - 1]->LName = ActiveCircuit[ActiveActor]->BusList.Get(i); + } + + // each bus corresponds to a topo node (TODO, do we need topo nodes anymore?) and connectivity node + for (i = 1; i <= ActiveCircuit[ActiveActor]->NumBuses; ++i) + { + geoUUID = GetDevUuid(Topo, ActiveCircuit[ActiveActor]->Buses[i - 1]->LName, 1); + StartFreeInstance(TopoPrf, "TopologicalNode", geoUUID); + StringNode(TopoPrf, "IdentifiedObject.mRID", UUIDToCIMString(geoUUID)); + StringNode(TopoPrf, "IdentifiedObject.name", ActiveCircuit[ActiveActor]->Buses[i - 1]->LName); + UuidNode(TopoPrf, "TopologicalNode.TopologicalIsland", pIsland->Get_UUID()); + EndInstance(TopoPrf, "TopologicalNode"); + + StartFreeInstance(TopoPrf, "ConnectivityNode", ActiveCircuit[ActiveActor]->Buses[i - 1]->Get_UUID()); + StringNode(TopoPrf, "IdentifiedObject.mRID", UUIDToCIMString(ActiveCircuit[ActiveActor]->Buses[i - 1]->Get_UUID())); + StringNode(TopoPrf, "IdentifiedObject.name", ActiveCircuit[ActiveActor]->Buses[i - 1]->LName); + UuidNode(TopoPrf, "ConnectivityNode.TopologicalNode", geoUUID); + UuidNode(TopoPrf, "ConnectivityNode.OperationalLimitSet", GetOpLimVUuid(sqrt(3.0) * ActiveCircuit[ActiveActor]->Buses[i - 1]->kVBase)); + FD->WriteCimLn(TopoPrf, Format(" ", ActiveCircuit[ActiveActor]->Get_CIM_ID().c_str())); + EndInstance(TopoPrf, "ConnectivityNode"); + } + + // find the swing bus ==> first voltage source + pVsrc = (TVsourceObj*) ActiveCircuit[ActiveActor]->Sources.Get_First(); // pIsrc are in the same list + while (pVsrc != nullptr) + { + // if (pVsrc->ClassNameIs("TVSourceObj")) + { + if (pVsrc->FEnabled) + { + i = pVsrc->Terminals[0].BusRef - 1; + geoUUID = GetDevUuid(Topo, ActiveCircuit[ActiveActor]->Buses[i]->LName, 1); + pSwing->Set_UUID(geoUUID); + StartInstance(TopoPrf, "TopologicalIsland", pIsland); + RefNode(TopoPrf, "TopologicalIsland.AngleRefTopologicalNode", pSwing); + EndInstance(TopoPrf, "TopologicalIsland"); + break; + } + } + pVsrc = (TVsourceObj*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_First(); + while (pGen != nullptr) + { + if (pGen->FEnabled) + { + StartInstance(FunPrf, "SynchronousMachine", pGen); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + DoubleNode(SshPrf, "RotatingMachine.p", pGen->Get_PresentkW() * 1000.0); + DoubleNode(SshPrf, "RotatingMachine.q", pGen->Get_Presentkvar() * 1000.0); + DoubleNode(EpPrf, "RotatingMachine.ratedS", pGen->GenVars.kVArating * 1000.0); + DoubleNode(EpPrf, "RotatingMachine.ratedU", pGen->Get_PresentkV() * 1000.0); + // SynchMachTypeEnum (F, "generator"); + // SynchMachModeEnum (F, "generator"); + geoUUID = GetDevUuid(MachLoc, pGen->LName, 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "SynchronousMachine"); + AttachGeneratorPhases(*pGen, geoUUID); + WriteTerminals(*pGen, geoUUID, crsUUID); + AddGeneratorECP(*pGen); + } + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + + pPV = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + while (pPV != nullptr) + { + if (pPV->FEnabled) + { + pName1->LName = pPV->get_Name(); // + "_PVPanels"; + pName1->Set_UUID(GetDevUuid(PVPanels, pPV->LName, 1)); + StartInstance(FunPrf, "PhotovoltaicUnit", pName1); + geoUUID = GetDevUuid(SolarLoc, pPV->LName, 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + DoubleNode(EpPrf, "PowerElectronicsUnit.maxP", pPV->Get_Pmax() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsUnit.minP", pPV->Get_Pmin() * 1000.0); + EndInstance(FunPrf, "PhotovoltaicUnit"); + StartInstance(FunPrf, "PowerElectronicsConnection", pPV); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + RefNode(FunPrf, "PowerElectronicsConnection.PowerElectronicsUnit", pName1); + DoubleNode(EpPrf, "PowerElectronicsConnection.maxIFault", 1.0 / pPV->Vminpu); + // if (FD->Separate) StartFreeInstance (SshPrf, "PowerElectronicsConnection", pPV->Get_UUID()); + DoubleNode(SshPrf, "PowerElectronicsConnection.p", pPV->Get_PresentkW() * 1000.0); + DoubleNode(SshPrf, "PowerElectronicsConnection.q", pPV->Get_Presentkvar() * 1000.0); + ConverterControlEnum(SshPrf, pPV->FvarMode, pPV->Get_CIMDynamicMode()); + // if (FD->Separate) EndInstance (SshPrf, "PowerElectronicsConnection"); + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedS", pPV->PVSystemVars.FkVArating * 1000.0); + if (pPV->Fnphases == 1) + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedU", pPV->Get_PresentkV() * 1000.0 * sqrt(3.0)); + else + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedU", pPV->Get_PresentkV() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsConnection.maxQ", pPV->Get_qMaxInj() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsConnection.minQ", -pPV->Get_qMaxAbs() * 1000.0); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnection"); + AttachSolarPhases(*pPV, geoUUID); + // we want the location using PV unit name + WriteReferenceTerminals(*pPV, pPV->Get_UUID()); + s = pPV->LName; + pPV->LName = pName1->LName; + WritePositions(*pPV, geoUUID, crsUUID); + pPV->LName = s; + AddSolarECP(*pPV); + } + pPV = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } + + pBat = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + while (pBat != nullptr) + { + if (pBat->FEnabled) + { + pName1->LName = pBat->get_Name(); // + "_Cells"; + pName1->Set_UUID(GetDevUuid(Battery, pBat->LName, 1)); + StartInstance(FunPrf, "BatteryUnit", pName1); + DoubleNode(EpPrf, "PowerElectronicsUnit.maxP", pBat->Get_Pmax() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsUnit.minP", pBat->Get_Pmin() * 1000.0); + DoubleNode(SshPrf, "BatteryUnit.ratedE", pBat->StorageVars.kWhRating * 1000.0); + DoubleNode(SshPrf, "BatteryUnit.storedE", pBat->StorageVars.kWhStored * 1000.0); + BatteryStateEnum(SshPrf, pBat->fState); + geoUUID = GetDevUuid(BatteryLoc, pBat->LName, 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "BatteryUnit"); + StartInstance(FunPrf, "PowerElectronicsConnection", pBat); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + RefNode(FunPrf, "PowerElectronicsConnection.PowerElectronicsUnit", pName1); + DoubleNode(EpPrf, "PowerElectronicsConnection.maxIFault", 1.0 / pBat->Vminpu); + DoubleNode(SshPrf, "PowerElectronicsConnection.p", pBat->Get_PresentkW() * 1000.0); + DoubleNode(SshPrf, "PowerElectronicsConnection.q", pBat->Get_Presentkvar() * 1000.0); + ConverterControlEnum(SshPrf, pBat->FvarMode, pBat->Get_CIMDynamicMode()); + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedS", pBat->Get_FkVARating() * 1000.0); + if (pBat->Fnphases == 1) + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedU", pBat->Get_PresentkV() * 1000.0 * sqrt(3.0)); + else + DoubleNode(EpPrf, "PowerElectronicsConnection.ratedU", pBat->Get_PresentkV() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsConnection.maxQ", pBat->Get_qMaxInj() * 1000.0); + DoubleNode(EpPrf, "PowerElectronicsConnection.minQ", -pBat->Get_qMaxAbs() * 1000.0); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "PowerElectronicsConnection"); + AttachStoragePhases(*pBat, geoUUID); + // we want the location using battery unit name + WriteReferenceTerminals(*pBat, pBat->Get_UUID()); + s = pBat->LName; + pBat->LName = pName1->LName; + WritePositions(*pBat, geoUUID, crsUUID); + pBat->LName = s; + AddStorageECP(*pBat); + } + pBat = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } + + // with ActiveCircuit[ActiveActor] do { + if ((ActiveCircuit[ActiveActor]->InvControls2.NumInList > 0) || (ActiveCircuit[ActiveActor]->ExpControls.NumInList > 0)) + { + pI1547 = new TIEEE1547Controller(); + pInv = (TInvControlObj*) ActiveCircuit[ActiveActor]->InvControls2.Get_First(); + while (pInv != nullptr) + { + if (pInv->FEnabled) + { + pI1547->PullFromInvControl(*pInv); + pI1547->WriteCIM(DynPrf); + } + pInv = (TInvControlObj*) ActiveCircuit[ActiveActor]->InvControls2.Get_Next(); + } + pExp = (TExpControlObj*) ActiveCircuit[ActiveActor]->ExpControls.Get_First(); + while (pExp != nullptr) + { + if (pExp->FEnabled) + { + pI1547->PullFromExpControl(*pExp); + pI1547->WriteCIM(DynPrf); + } + pExp = (TExpControlObj*) ActiveCircuit[ActiveActor]->ExpControls.Get_Next(); + } + delete pI1547; + } + // } + + pVsrc = (TVsourceObj*) ActiveCircuit[ActiveActor]->Sources.Get_First(); // pIsrc are in the same list + while (pVsrc != nullptr) + { + // if (pVsrc->ClassNameIs("TVSourceObj")) + { + if (pVsrc->FEnabled) // with pVsrc do + { + Zs = pVsrc->Z->AvgDiagonal(); + Zm = pVsrc->Z->AvgOffDiagonal(); + Rs = Zs.re; + Rm = Zm.re; + Xs = Zs.im; + Xm = Zm.im; + v1 = pVsrc->Fnphases; + if (v1 > 1.0) + { + R1 = Rs - Rm; + X1 = Xs - Xm; + R0 = Rs + (v1 - 1.0) * Rm; + X0 = Xs + (v1 - 1.0) * Xm; + } + else + { + R1 = Rs; + X1 = Xs; + R0 = Rs; + X0 = Xs; + } + + StartInstance(FunPrf, "EnergySource", pVsrc); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pVsrc); + DoubleNode(EpPrf, "EnergySource.nominalVoltage", 1000 * pVsrc->kVBase); + DoubleNode(SshPrf, "EnergySource.voltageMagnitude", 1000 * pVsrc->kVBase * pVsrc->PerUnit); + DoubleNode(SshPrf, "EnergySource.voltageAngle", TwoPi * pVsrc->Angle / 360.0); + DoubleNode(EpPrf, "EnergySource.r", R1); + DoubleNode(EpPrf, "EnergySource.x", X1); + DoubleNode(EpPrf, "EnergySource.r0", R0); + DoubleNode(EpPrf, "EnergySource.x0", X0); + geoUUID = GetDevUuid(SrcLoc, pVsrc->LName, 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "EnergySource"); + // AttachPhases (F, pVsrc, 1, "EnergySource"); + WriteTerminals(*pVsrc, geoUUID, crsUUID); + } + } + pVsrc = (TVsourceObj*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + pCap = (TCapacitorObj*) ActiveCircuit[ActiveActor]->ShuntCapacitors.Get_First(); + while (pCap != nullptr) + { + if (pCap->FEnabled) + { + StartInstance(FunPrf, "LinearShuntCompensator", pCap); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pCap); + // with pCap do { + val = 0.001 * pCap->Ftotalkvar / pCap->kvrating / pCap->kvrating / pCap->FNumSteps; + DoubleNode(EpPrf, "ShuntCompensator.nomU", 1000.0 * pCap->kvrating); + DoubleNode(EpPrf, "LinearShuntCompensator.bPerSection", val); + DoubleNode(EpPrf, "LinearShuntCompensator.gPerSection", 0.0); + if (pCap->Connection == 0) + { + ShuntConnectionKindNode(FunPrf, "ShuntCompensator", "Y"); + BooleanNode(FunPrf, "ShuntCompensator.grounded", true); // TODO - check bus 2 + DoubleNode(EpPrf, "LinearShuntCompensator.b0PerSection", val); + } + else + { + ShuntConnectionKindNode(FunPrf, "ShuntCompensator", "D"); + BooleanNode(FunPrf, "LinearShuntCompensator.grounded", false); + DoubleNode(EpPrf, "LinearShuntCompensator.b0PerSection", 0.0); + } + DoubleNode(EpPrf, "LinearShuntCompensator.g0PerSection", 0.0); + IntegerNode(EpPrf, "ShuntCompensator.normalSections", pCap->FNumSteps); + IntegerNode(EpPrf, "ShuntCompensator.maximumSections", pCap->FNumSteps); + + val = 0.0; + pCapC = (TCapControlObj*) ActiveCircuit[ActiveActor]->CapControls.Get_First(); + while ((pCapC != nullptr)) + { + if (pCapC->Get_Capacitor() == pCap) + val = pCapC->ControlVars.OnDelay; + pCapC = (TCapControlObj*) ActiveCircuit[ActiveActor]->CapControls.Get_Next(); + } + DoubleNode(EpPrf, "ShuntCompensator.aVRDelay", val); + + val = 0; + for (i = 1; i <= pCap->FNumSteps; ++i) + if (pCap->get_States(i, ActiveActor) > 0) + val = val + 1.0; + DoubleNode(SshPrf, "ShuntCompensator.sections", val); + geoUUID = GetDevUuid(CapLoc, pCap->LName, 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "LinearShuntCompensator"); + AttachCapPhases(*pCap, geoUUID, val); + WriteTerminals(*pCap, geoUUID, crsUUID, pCap->NormAmps, pCap->EmergAmps); + // } + } + pCap = (TCapacitorObj*) ActiveCircuit[ActiveActor]->ShuntCapacitors.Get_Next(); + } + + pCapC = (TCapControlObj*) ActiveCircuit[ActiveActor]->CapControls.Get_First(); + while ((pCapC != nullptr)) + { + // with pCapC do { + StartInstance(FunPrf, "RegulatingControl", pCapC); + UuidNode(GeoPrf, "PowerSystemResource.Location", GetDevUuid(CapLoc, pCapC->Get_Capacitor()->get_Name(), 1)); + RefNode(FunPrf, "RegulatingControl.RegulatingCondEq", pCapC->Get_Capacitor()); + i1 = GetCktElementIndex(pCapC->ElementName); // Global function + UuidNode(FunPrf, "RegulatingControl.Terminal", GetTermUuid(*(TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get(i1), pCapC->ElementTerminal)); + s = FirstPhaseString(*(TDSSCktElement*)ActiveCircuit[ActiveActor]->CktElements.Get(i1), 1); + if (pCapC->ControlVars.FPTPhase > 0) + { + s.resize(1); + s[0] += pCapC->ControlVars.FPTPhase - 1; + MonitoredPhaseNode(FunPrf, s); + } + else + { + s.resize(1); + MonitoredPhaseNode(FunPrf, s); // TODO - average, min and max unsupported in CIM + } + val = 1.0; + if (pCapC->get_ControlType() == PFCONTROL) + { + v1 = pCapC->ControlVars.PFON_Value; + v2 = pCapC->ControlVars.PFOFF_Value; + } + else + { + v1 = pCapC->ControlVars.ON_Value; + v2 = pCapC->ControlVars.OFF_Value; + if (pCapC->get_ControlType() == KVARCONTROL) + val = 1000.0; + if (pCapC->get_ControlType() == CURRENTCONTROL) + val = pCapC->ControlVars.CTRatio; + if (pCapC->get_ControlType() == VOLTAGECONTROL) + val = pCapC->ControlVars.PTRatio; + } + switch (pCapC->get_ControlType()) + { + case CURRENTCONTROL: + RegulatingControlEnum(EpPrf, "currentFlow"); + break; + case VOLTAGECONTROL: + RegulatingControlEnum(EpPrf, "voltage"); + break; + case KVARCONTROL: + RegulatingControlEnum(EpPrf, "reactivePower"); + break; + case TIMECONTROL: + RegulatingControlEnum(EpPrf, "timeScheduled"); + break; + case PFCONTROL: + RegulatingControlEnum(EpPrf, "powerFactor"); + break; + case USERCONTROL: + RegulatingControlEnum(EpPrf, "userDefined"); // i.e. unsupported in CIM + break; + } + BooleanNode(EpPrf, "RegulatingControl.discrete", true); + BooleanNode(EpPrf, "RegulatingControl.enabled", pCapC->FEnabled); + DoubleNode(EpPrf, "RegulatingControl.targetValue", val * 0.5 * (v1 + v2)); + DoubleNode(EpPrf, "RegulatingControl.targetDeadband", val * (v2 - v1)); + EndInstance(FunPrf, "RegulatingControl"); + // } + pCapC = (TCapControlObj*) ActiveCircuit[ActiveActor]->CapControls.Get_Next(); + } + + // size the auxiliary winding, mesh, and core lists for transformer export + maxWdg = 3; // start with the size of autos + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + while (pXf != nullptr) + { + if (pXf->FEnabled) + if (pXf->get_NumWindings() > maxWdg) + maxWdg = pXf->get_NumWindings(); + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + + if (maxWdg > 0) + { + WdgList.resize(maxWdg); + CoreList.resize(maxWdg); + MeshList.resize(XSCSize(maxWdg)); + for (i = 1; i <= maxWdg; ++i) + WdgList[i - 1] = new TNamedObject("dummy"); + CoreList[0] = new TNamedObject("dummy"); + for (i = 1; i <= XSCSize(maxWdg); ++i) + MeshList[i - 1] = new TNamedObject("dummy"); + } + + // do the autotransformers as balanced, three-phase autos, PowerTransformerEnd(s), mesh impedances and core admittances + // only considering 2 windings, vector group YNa, or 3 windings, vector group YNad1 + pAuto = (TAutoTransObj*) ActiveCircuit[ActiveActor]->AutoTransformers.Get_First(); + while (pAuto != nullptr) + { + if (pAuto->FEnabled) // with pAuto do + { + if (pAuto->XfmrBank == "") + sBank = "=" + pAuto->get_Name(); + else + sBank = pAuto->XfmrBank; + pBank = GetBank(sBank); + if (pBank == nullptr) + { + pBank = new TBankObject(maxWdg); + pBank->LName = sBank; + pBank->Set_UUID(GetDevUuid(Bank, sBank, 0)); + AddBank(pBank); + } + pBank->AddAutoTransformer(*pAuto); + geoUUID = GetDevUuid(XfLoc, pAuto->get_Name(), 1); + WritePositions(*pAuto, geoUUID, crsUUID); + // pre-make the winding, mesh and core name objects for easy reference + for (i = 1; i <= pAuto->get_NumWindings(); ++i) + { + WdgList[i - 1]->LName = pAuto->get_Name() + "_End_" + IntToStr(i); + WdgList[i - 1]->Set_UUID(GetDevUuid(Wdg, pAuto->get_Name(), i)); + } + CoreList[0]->LName = pAuto->get_Name() + "_Yc"; + CoreList[0]->Set_UUID(GetDevUuid(XfCore, pAuto->get_Name(), 1)); + for (i = 1; i <= XSCSize(maxWdg); ++i) + { + MeshList[i - 1]->LName = pAuto->get_Name() + "_Zsc_" + IntToStr(i); + MeshList[i - 1]->Set_UUID(GetDevUuid(XfMesh, pAuto->get_Name(), i)); + } + val = pAuto->Get_BasekVLL(1); // write core Y + zbase = 1000.0 * val * val / pAuto->Get_WdgkVA(1); + StartInstance(EpPrf, "TransformerCoreAdmittance", CoreList[0]); + val = pAuto->pctNoLoadLoss / 100.0 / zbase; + DoubleNode(EpPrf, "TransformerCoreAdmittance.g", val); + DoubleNode(EpPrf, "TransformerCoreAdmittance.g0", val); + val = -pAuto->pctImag / 100.0 / zbase; // inductive B < 0 + DoubleNode(EpPrf, "TransformerCoreAdmittance.b", val); + DoubleNode(EpPrf, "TransformerCoreAdmittance.b0", val); + RefNode(EpPrf, "TransformerCoreAdmittance.TransformerEnd", WdgList[0]); + EndInstance(EpPrf, "TransformerCoreAdmittance"); + seq = 1; // write mesh Z + for (i = 1; i <= pAuto->get_NumWindings(); ++i) + { + for (k = i + 1; k <= pAuto->get_NumWindings(); ++k) + { + val = pAuto->Get_BasekVLL(i); + zbase = 1000.0 * val * val / pAuto->Get_WdgkVA(1); // always based on Winding 1 kVA + StartInstance(EpPrf, "TransformerMeshImpedance", MeshList[seq - 1]); + val = zbase * (pAuto->Get_WdgResistance(i) + pAuto->Get_WdgResistance(k)); + DoubleNode(EpPrf, "TransformerMeshImpedance.r", val); + DoubleNode(EpPrf, "TransformerMeshImpedance.r0", val); + val = zbase * pAuto->Get_Xsc(seq); + seq++; + DoubleNode(EpPrf, "TransformerMeshImpedance.x", val); + DoubleNode(EpPrf, "TransformerMeshImpedance.x0", val); + RefNode(EpPrf, "TransformerMeshImpedance.FromTransformerEnd", WdgList[i - 1]); + RefNode(EpPrf, "TransformerMeshImpedance.ToTransformerEnd", WdgList[k - 1]); + EndInstance(EpPrf, "TransformerMeshImpedance"); + } + } + // write the Ends, and a Terminal with operational limit for each End + for (i = 1; i <= pAuto->get_NumWindings(); ++i) + { + StartInstance(FunPrf, "PowerTransformerEnd", WdgList[i - 1]); + RefNode(FunPrf, "PowerTransformerEnd.PowerTransformer", pBank); + DoubleNode(EpPrf, "PowerTransformerEnd.ratedS", 1000 * pAuto->Get_WdgkVA(i)); + DoubleNode(EpPrf, "PowerTransformerEnd.ratedU", 1000 * pAuto->WINDING_[i - 1].kVLL); + zbase = 1000.0 * pAuto->Get_BasekVLL(i) * pAuto->Get_BasekVLL(i) / pAuto->Get_WdgkVA(i); + DoubleNode(EpPrf, "PowerTransformerEnd.r", zbase * pAuto->Get_WdgResistance(i)); + if (i == 1) + { + WindingConnectionKindNode(FunPrf, "Y"); + IntegerNode(FunPrf, "PowerTransformerEnd.phaseAngleClock", 0); + BooleanNode(FunPrf, "TransformerEnd.grounded", false); + } + else if (i == 2) + { + WindingConnectionKindNode(FunPrf, "A"); + IntegerNode(FunPrf, "PowerTransformerEnd.phaseAngleClock", 0); + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", 0.0); // no rneut or xneut for autotrans + DoubleNode(EpPrf, "TransformerEnd.xground", 0.0); + } + else + { + WindingConnectionKindNode(FunPrf, "D"); + IntegerNode(FunPrf, "PowerTransformerEnd.phaseAngleClock", 1); + BooleanNode(FunPrf, "TransformerEnd.grounded", false); + } + IntegerNode(FunPrf, "TransformerEnd.endNumber", i); + j = pAuto->Terminals[i - 1].BusRef - 1; + pName2->LName = pAuto->get_Name() + "_T" + IntToStr(i); + pName2->Set_UUID(GetTermUuid(*pAuto, i)); + RefNode(FunPrf, "TransformerEnd.Terminal", pName2); + UuidNode(FunPrf, "TransformerEnd.BaseVoltage", GetBaseVUuid(sqrt(3.0) * ActiveCircuit[ActiveActor]->Buses[j]->kVBase)); + EndInstance(FunPrf, "PowerTransformerEnd"); + // write the Terminal for this End + StartInstance(FunPrf, "Terminal", pName2); + RefNode(FunPrf, "Terminal.ConductingEquipment", pBank); + IntegerNode(FunPrf, "ACDCTerminal.sequenceNumber", i); + FD->WriteCimLn(TopoPrf, Format(" ", ActiveCircuit[ActiveActor]->Buses[j]->Get_CIM_ID().c_str())); + if (i == 1) + { // write the current limit on HV winding, assuming that's winding 1 + LimitName = GetOpLimIName(pAuto->NormAmps, pAuto->EmergAmps); + pILimit = GetOpLimit(LimitName); + if (pILimit == nullptr) + { + pILimit = new TOpLimitObject(pAuto->NormAmps, pAuto->EmergAmps); + pILimit->LName = LimitName; + pILimit->Set_UUID(GetDevUuid(OpLimI, LimitName, 0)); + AddOpLimit(pILimit); + } + LimiTUuid = GetDevUuid(OpLimI, LimitName, 0); + UuidNode(FunPrf, "ACDCTerminal.OperationalLimitSet", LimiTUuid); + } + EndInstance(FunPrf, "Terminal"); + } + } + pAuto = (TAutoTransObj*) ActiveCircuit[ActiveActor]->AutoTransformers.Get_Next(); + } + + // { the transformers; + // 1. if balanced three-phase and no XfmrCode, use PowerTransformerEnd(s), mesh impedances and core admittances with no tanks + // 2. with XfmrCode, write TransformerTank, TransformerTankEnd(s) and references to TransformerTankInfoInfo + // 3. otherwise, write TransformerTank, then create and reference TransformerTankInfo classes + + // for case 3, it's better to identify and create the info classes first + // TODO: side effect is that these transformers will reference XfmrCode until the text file is reloaded. Solution results should be the same. + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + while (pXf != nullptr) + { + if (pXf->FEnabled) + { + if ((pXf->XfmrCode.size() < 1) && (pXf->Fnphases != 3)) + { + sBank = "CIMXfmrCode_" + pXf->get_Name(); + clsXfCd->NewObject(sBank); + clsXfCd->Set_Code(sBank); + pXfCd = ActiveXfmrCodeObj; + DSSObjs[ActiveActor].Add(pXfCd); // this is how ExecHelper.pas keeps track of \"General Objects\" for cleanup + pXfCd->Set_UUID(GetDevUuid(TankInfo, pXfCd->get_Name(), 1)); + pXfCd->PullFromTransformer(pXf); + pXf->XfmrCode = pXfCd->get_Name(); + } + } + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + + // write all the XfmrCodes first (CIM TransformerTankInfo) + pXfCd = (TXfmrCodeObj*) clsXfCd->ElementList.Get_First(); + while (pXfCd != nullptr) + { + WriteXfmrCode(*pXfCd); + pXfCd = (TXfmrCodeObj*) clsXfCd->ElementList.Get_Next(); + } + + // create all the banks (CIM PowerTransformer) for regular transformers + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + while (pXf != nullptr) + { + if (pXf->FEnabled) + { + if (pXf->XfmrBank == "") + sBank = "=" + pXf->get_Name(); + else + sBank = pXf->XfmrBank; + pBank = GetBank(sBank); + if (pBank == nullptr) + { + pBank = new TBankObject(maxWdg); + pBank->LName = sBank; + pBank->Set_UUID(GetDevUuid(Bank, sBank, 0)); + AddBank(pBank); + } + } + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + + // write all the transformers, according to the three cases + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + while (pXf != nullptr) + { + if (pXf->FEnabled) // with pXf do + { + // collect this transformer into tanks and banks, and make a location + if (pXf->XfmrBank == "") + sBank = "=" + pXf->get_Name(); + else + sBank = pXf->XfmrBank; + bTanks = true; // defaults to case 2 or 3 if XfmrCode exists + if ((pXf->XfmrCode.size() < 1) && (pXf->Fnphases == 3)) + bTanks = false; // case 1, balanced three-phase + + pBank = GetBank(sBank); + pBank->AddTransformer(*pXf); + geoUUID = GetDevUuid(XfLoc, pXf->get_Name(), 1); + + if (bTanks) + { + StartInstance(FunPrf, "TransformerTank", pXf); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + pXfCd = (TXfmrCodeObj*) clsXfCd->Find(pXf->XfmrCode); + RefNode(FunPrf, "TransformerTank.TransformerTankInfo", pXfCd); + RefNode(FunPrf, "TransformerTank.PowerTransformer", pBank); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "TransformerTank"); + WritePositions(*pXf, geoUUID, crsUUID); + } + else + { + WritePositions(*pXf, geoUUID, crsUUID); + } + + // make the winding, mesh and core name objects for easy reference + for (i = 1; i <= pXf->get_NumWindings(); ++i) + { + WdgList[i - 1]->LName = pXf->get_Name() + "_End_" + IntToStr(i); + WdgList[i - 1]->Set_UUID(GetDevUuid(Wdg, pXf->get_Name(), i)); + } + CoreList[0]->LName = pXf->get_Name() + "_Yc"; + CoreList[0]->Set_UUID(GetDevUuid(XfCore, pXf->get_Name(), 1)); + for (i = 1; i <= XSCSize(maxWdg); ++i) + { + MeshList[i - 1]->LName = pXf->get_Name() + "_Zsc_" + IntToStr(i); + MeshList[i - 1]->Set_UUID(GetDevUuid(XfMesh, pXf->get_Name(), i)); + } + + if (!bTanks) + { // write the mesh impedances and core admittances + val = pXf->Get_BasekVLL(1); + zbase = 1000.0 * val * val / pXf->Get_WdgkVA(1); + StartInstance(EpPrf, "TransformerCoreAdmittance", CoreList[0]); + val = pXf->pctNoLoadLoss / 100.0 / zbase; + DoubleNode(EpPrf, "TransformerCoreAdmittance.g", val); + DoubleNode(EpPrf, "TransformerCoreAdmittance.g0", val); + val = pXf->pctImag / 100.0 / zbase; + DoubleNode(EpPrf, "TransformerCoreAdmittance.b", val); + DoubleNode(EpPrf, "TransformerCoreAdmittance.b0", val); + RefNode(EpPrf, "TransformerCoreAdmittance.TransformerEnd", WdgList[0]); + EndInstance(EpPrf, "TransformerCoreAdmittance"); + seq = 1; // write mesh Z + for (i = 1; i <= pXf->get_NumWindings(); ++i) + { + for (k = i + 1; k <= pXf->get_NumWindings(); ++k) + { + val = pXf->Get_BasekVLL(i); + zbase = 1000.0 * val * val / pXf->Get_WdgkVA(1); // always based on Winding 1 kVA + StartInstance(EpPrf, "TransformerMeshImpedance", MeshList[seq - 1]); + val = zbase * (pXf->Get_WdgResistance(i) + pXf->Get_WdgResistance(k)); + DoubleNode(EpPrf, "TransformerMeshImpedance.r", val); + DoubleNode(EpPrf, "TransformerMeshImpedance.r0", val); + val = zbase * pXf->Get_Xsc(seq); + seq++; + DoubleNode(EpPrf, "TransformerMeshImpedance.x", val); + DoubleNode(EpPrf, "TransformerMeshImpedance.x0", val); + RefNode(EpPrf, "TransformerMeshImpedance.FromTransformerEnd", WdgList[i - 1]); + RefNode(EpPrf, "TransformerMeshImpedance.ToTransformerEnd", WdgList[k - 1]); + EndInstance(EpPrf, "TransformerMeshImpedance"); + } + } + } + + // write the Ends, and a Terminal for each End + for (i = 1; i <= pXf->get_NumWindings(); ++i) + { + if (bTanks) + { + StartInstance(FunPrf, "TransformerTankEnd", WdgList[i - 1]); + XfmrTankPhasesAndGround(FunPrf, EpPrf, *pXf, i); + RefNode(FunPrf, "TransformerTankEnd.TransformerTank", pXf); + } + else + { + StartInstance(FunPrf, "PowerTransformerEnd", WdgList[i - 1]); + RefNode(FunPrf, "PowerTransformerEnd.PowerTransformer", pBank); + DoubleNode(EpPrf, "PowerTransformerEnd.ratedS", 1000 * pXf->Get_WdgkVA(i)); + DoubleNode(EpPrf, "PowerTransformerEnd.ratedU", 1000 * pXf->WINDING_[i - 1].kVLL); + zbase = 1000.0 * pXf->Get_BasekVLL(i) * pXf->Get_BasekVLL(i) / pXf->Get_WdgkVA(i); + DoubleNode(EpPrf, "PowerTransformerEnd.r", zbase * pXf->Get_WdgResistance(i)); + if (pXf->WINDING_[i - 1].Connection == 1) + WindingConnectionKindNode(FunPrf, "D"); + else if ((pXf->WINDING_[i - 1].Rneut > 0.0) || (pXf->WINDING_[i - 1].Xneut > 0.0)) + WindingConnectionKindNode(FunPrf, "Yn"); + else + WindingConnectionKindNode(FunPrf, "Y"); + if (pXf->WINDING_[i - 1].Connection != pXf->WINDING_[0].Connection) // TODO - this assumes HV winding first, and normal usages + IntegerNode(FunPrf, "PowerTransformerEnd.phaseAngleClock", 1); + else + IntegerNode(FunPrf, "PowerTransformerEnd.phaseAngleClock", 0); + j = (i - 1) * pXf->Fnconds + pXf->Fnphases + 1; + if ((pXf->WINDING_[i - 1].Connection == 1)) + { // delta + BooleanNode(FunPrf, "TransformerEnd.grounded", false); + } + else if ((pXf->NodeRef[j - 1] == 0)) + { // last conductor is grounded solidly + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", 0.0); + DoubleNode(EpPrf, "TransformerEnd.xground", 0.0); + } + else if ((pXf->WINDING_[i - 1].Rneut < 0.0)) + { // probably wye ungrounded + BooleanNode(FunPrf, "TransformerEnd.grounded", false); + } + else + { // not delta, not wye solidly grounded or ungrounded + BooleanNode(FunPrf, "TransformerEnd.grounded", true); + DoubleNode(EpPrf, "TransformerEnd.rground", pXf->WINDING_[i - 1].Rneut); + DoubleNode(EpPrf, "TransformerEnd.xground", pXf->WINDING_[i - 1].Xneut); + } + } + IntegerNode(FunPrf, "TransformerEnd.endNumber", i); + j = pXf->Terminals[i - 1].BusRef - 1; + pName2->LName = pXf->get_Name() + "_T" + IntToStr(i); + pName2->Set_UUID(GetTermUuid(*pXf, i)); + RefNode(FunPrf, "TransformerEnd.Terminal", pName2); + UuidNode(FunPrf, "TransformerEnd.BaseVoltage", GetBaseVUuid(sqrt(3.0) * ActiveCircuit[ActiveActor]->Buses[j]->kVBase)); + if (bTanks) + EndInstance(FunPrf, "TransformerTankEnd"); + else + EndInstance(FunPrf, "PowerTransformerEnd"); + // write the Terminal for this End + StartInstance(FunPrf, "Terminal", pName2); + RefNode(FunPrf, "Terminal.ConductingEquipment", pBank); + IntegerNode(FunPrf, "ACDCTerminal.sequenceNumber", i); + FD->WriteCimLn(TopoPrf, Format(" ", ActiveCircuit[ActiveActor]->Buses[j]->Get_CIM_ID().c_str())); + if (i == 1) + { // write the current limit on HV winding, assuming that's winding 1 + LimitName = GetOpLimIName(pXf->NormAmps, pXf->EmergAmps); + pILimit = GetOpLimit(LimitName); + if (pILimit == nullptr) + { + pILimit = new TOpLimitObject(pXf->NormAmps, pXf->EmergAmps); + pILimit->LName = LimitName; + pILimit->Set_UUID(GetDevUuid(OpLimI, LimitName, 0)); + AddOpLimit(pILimit); + } + LimiTUuid = GetDevUuid(OpLimI, LimitName, 0); + UuidNode(FunPrf, "ACDCTerminal.OperationalLimitSet", LimiTUuid); + } + EndInstance(FunPrf, "Terminal"); + } + } + pXf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + + // finally, write all the transformer banks (CIM PowerTransformer), including autotransformers + for (i = 0; i < BankList.size(); ++i) + { + pBank = BankList[i]; + if (pBank == nullptr) + break; + pBank->BuildVectorGroup(); + // we don't want = sign in the name. These should still be unique names + if (AnsiPos("=", pBank->LName) == 1) + pBank->LName = pBank->LName.substr(1); + StartInstance(FunPrf, "PowerTransformer", pBank); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + StringNode(FunPrf, "PowerTransformer.vectorGroup", pBank->vectorGroup); + UuidNode(GeoPrf, "PowerSystemResource.Location", GetDevUuid(XfLoc, pBank->pd_unit->get_Name(), 1)); + EndInstance(FunPrf, "PowerTransformer"); + } + + if (!WdgList.empty()) + { + for (i = 0; i < WdgList.size(); ++i) + if (WdgList[i] != nullptr) + delete WdgList[i]; + WdgList.clear(); + } + if (!CoreList.empty()) + { + for (i = 0; i < CoreList.size(); ++i) + if (CoreList[i] != nullptr) + delete CoreList[i]; + CoreList.clear(); + } + if (!MeshList.empty()) + { + for (i = 0; i < MeshList.size(); ++i) + if (MeshList[i] != nullptr) + delete MeshList[i]; + MeshList.clear(); + } + + // voltage regulators + pReg = (TRegControlObj*) ActiveCircuit[ActiveActor]->RegControls.Get_First(); + while ((pReg != nullptr)) + { + // with pReg do + // { + v1 = pReg->Get_Transformer()->Get_BaseVoltage(pReg->TapWinding) / pReg->get_PTRatio(); + pName2->LName = pReg->LName + "_Ctrl"; + pName2->Set_UUID(GetDevUuid(TapCtrl, pReg->LName, 1)); + StartInstance(FunPrf, "TapChangerControl", pName2); + RegulatingControlEnum(FunPrf, "voltage"); + UuidNode(FunPrf, "RegulatingControl.Terminal", GetTermUuid(*pReg->Get_Transformer(), pReg->TapWinding)); + MonitoredPhaseNode(FunPrf, FirstPhaseString(*pReg->Get_Transformer(), pReg->TapWinding)); + BooleanNode(FunPrf, "RegulatingControl.enabled", pReg->FEnabled); + BooleanNode(EpPrf, "RegulatingControl.discrete", true); + DoubleNode(EpPrf, "RegulatingControl.targetValue", pReg->Vreg); + DoubleNode(EpPrf, "RegulatingControl.targetDeadband", pReg->Bandwidth); + BooleanNode(EpPrf, "TapChangerControl.lineDropCompensation", pReg->LDCActive); + DoubleNode(EpPrf, "TapChangerControl.lineDropR", pReg->R); + DoubleNode(EpPrf, "TapChangerControl.lineDropX", pReg->X); + if (pReg->IsReversible) + { + BooleanNode(EpPrf, "TapChangerControl.reversible", true); + BooleanNode(EpPrf, "TapChangerControl.reverseToNeutral", pReg->ReverseNeutral); + DoubleNode(EpPrf, "TapChangerControl.reversingDelay", pReg->revDelay); + DoubleNode(EpPrf, "TapChangerControl.reversingPowerThreshold", pReg->RevPowerThreshold); + DoubleNode(EpPrf, "TapChangerControl.reverseLineDropR", pReg->revR); + DoubleNode(EpPrf, "TapChangerControl.reverseLineDropX", pReg->revX); + DoubleNode(EpPrf, "RegulatingControl.reverseTargetValue", pReg->revVreg); + DoubleNode(EpPrf, "RegulatingControl.reverseTargetDeadband", pReg->revBandwidth); + } + else + { + BooleanNode(EpPrf, "TapChangerControl.reversible", false); + } + if (pReg->VLimitActive) + { // maxLimitVoltage only in OpenDSS + DoubleNode(EpPrf, "TapChangerControl.maxLimitVoltage", pReg->Vlimit); + } + else + { + DoubleNode(EpPrf, "TapChangerControl.maxLimitVoltage", pReg->Get_MaxTap() * v1); + } + DoubleNode(EpPrf, "TapChangerControl.minLimitVoltage", pReg->Get_MinTap() * v1); + UuidNode(GeoPrf, "PowerSystemResource.Location", GetDevUuid(XfLoc, pReg->Get_Transformer()->get_Name(), 1)); + EndInstance(FunPrf, "TapChangerControl"); + + StartInstance(FunPrf, "RatioTapChanger", *pReg); + UuidNode(FunPrf, "RatioTapChanger.TransformerEnd", GetDevUuid(Wdg, pReg->Get_Transformer()->get_Name(), pReg->TapWinding)); + UuidNode(FunPrf, "TapChanger.TapChangerControl", pName2->Get_UUID()); + DoubleNode(EpPrf, "RatioTapChanger.stepVoltageIncrement", 100.0 * pReg->Get_TapIncrement()); + TransformerControlEnum(FunPrf, "volt"); + IntegerNode(EpPrf, "TapChanger.highStep", pReg->Get_NumTaps() / 2); + IntegerNode(EpPrf, "TapChanger.lowStep", -pReg->Get_NumTaps() / 2); + IntegerNode(EpPrf, "TapChanger.neutralStep", 0); + IntegerNode(EpPrf, "TapChanger.normalStep", 0); + DoubleNode(EpPrf, "TapChanger.neutralU", v1 * pReg->get_PTRatio()); + DoubleNode(EpPrf, "TapChanger.initialDelay", pReg->TimeDelay); + DoubleNode(EpPrf, "TapChanger.subsequentDelay", pReg->TapDelay); + BooleanNode(EpPrf, "TapChanger.ltcFlag", true); + BooleanNode(SshPrf, "TapChanger.controlEnabled", pReg->FEnabled); + DoubleNode(SshPrf, "TapChanger.step", pReg->Get_TapNum()); + DoubleNode(EpPrf, "TapChanger.ptRatio", pReg->get_PTRatio()); + DoubleNode(EpPrf, "TapChanger.ctRatio", pReg->get_CTRating() / 0.2); + DoubleNode(EpPrf, "TapChanger.ctRating", pReg->get_CTRating()); + UuidNode(GeoPrf, "PowerSystemResource.Location", GetDevUuid(XfLoc, pReg->Get_Transformer()->get_Name(), 1)); + EndInstance(FunPrf, "RatioTapChanger"); + //} + pReg = (TRegControlObj*) ActiveCircuit[ActiveActor]->RegControls.Get_Next(); + } + + // done with the transformers + + // series reactors, exported as SeriesCompensators + pReac = (TReactorObj*) ActiveCircuit[ActiveActor]->Reactors.Get_First(); + while (pReac != nullptr) + { + if (pReac->FEnabled) + { + StartInstance(FunPrf, "SeriesCompensator", pReac); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pReac); + geoUUID = GetDevUuid(ReacLoc, pReac->get_Name(), 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + DoubleNode(EpPrf, "SeriesCompensator.r", pReac->R); + DoubleNode(EpPrf, "SeriesCompensator.x", pReac->X); + DoubleNode(EpPrf, "SeriesCompensator.r0", pReac->R); + DoubleNode(EpPrf, "SeriesCompensator.x0", pReac->X); + EndInstance(FunPrf, "SeriesCompensator"); + // AttachLinePhases (F_, pReac); // for the 8500-node circuit, we only need 3 phase series reactors + WriteTerminals(*pReac, geoUUID, crsUUID, pReac->NormAmps, pReac->EmergAmps); + } + pReac = (TReactorObj*) ActiveCircuit[ActiveActor]->Reactors.Get_Next(); + } + + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != nullptr) + { + if (pLine->FEnabled) + // with pLine do + { + bval = false; // flag to write a \"line code\" of PULengthPhaseZ + v1 = To_Meters(pLine->FUserLengthUnits); + geoUUID = GetDevUuid(LineLoc, pLine->get_Name(), 1); + if (pLine->IsSwitch) + { + ParseSwitchClass(*pLine, swtCls, ratedAmps, breakingAmps); + StartInstance(FunPrf, swtCls, pLine); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pLine); + if (breakingAmps > 0.0) + DoubleNode(EpPrf, "ProtectedSwitch.breakingCapacity", breakingAmps); // Fuse and Sectionaliser don't have this, others do + DoubleNode(EpPrf, "Switch.ratedCurrent", ratedAmps); + // some OpenDSS models have enabled=false to signal open switches, but we can't actually + // export them because disabled elements don't have terminal references in memory + if (pLine->FEnabled) + { + BooleanNode(FunPrf, "Switch.normalOpen", !pLine->Get_ConductorClosed(0, ActiveActor)); + BooleanNode(SshPrf, "Switch.open", !pLine->Get_ConductorClosed(0, ActiveActor)); + } + else + { + BooleanNode(FunPrf, "Switch.normalOpen", true); + BooleanNode(SshPrf, "Switch.open", true); + } + BooleanNode(FunPrf, "Switch.retained", true); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, swtCls); + AttachSwitchPhases(*pLine); + } + else + { + StartInstance(FunPrf, "ACLineSegment", pLine); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pLine); + if (pLine->FLineCodeSpecified) + { + if ((pLine->FUserLengthUnits == UNITS_NONE)) + v1 = To_Meters(pLine->FLineCodeUnits); + DoubleNode(FunPrf, "Conductor.length", pLine->Len * v1); + LineCodeRefNode(EpPrf, *clsLnCd, pLine->CondCode); + } + else if (pLine->GeometrySpecified) + { + DoubleNode(FunPrf, "Conductor.length", pLine->Len * v1); + LineSpacingRefNode(CatPrf, *clsGeom, pLine->GeometryCode); + } + else if (pLine->SpacingSpecified) + { + DoubleNode(FunPrf, "Conductor.length", pLine->Len * v1); + LineSpacingRefNode(CatPrf, *clsSpac, pLine->SpacingCode); + } + else + { + if (pLine->SymComponentsModel && (pLine->Fnphases == 3)) + { + val = 1.0e-9 * TwoPi * pLine->BaseFrequency; // convert nF to mhos + DoubleNode(FunPrf, "Conductor.length", 1.0); // we don't know the physical length + DoubleNode(EpPrf, "ACLineSegment.r", pLine->Len * pLine->R1); // total ohms + DoubleNode(EpPrf, "ACLineSegment.x", pLine->Len * pLine->X1); + DoubleNode(EpPrf, "ACLineSegment.bch", pLine->Len * pLine->C1 * val); + DoubleNode(EpPrf, "ACLineSegment.gch", 0.0); + DoubleNode(EpPrf, "ACLineSegment.r0", pLine->Len * pLine->R0); + DoubleNode(EpPrf, "ACLineSegment.x0", pLine->Len * pLine->X0); + DoubleNode(EpPrf, "ACLineSegment.b0ch", pLine->Len * pLine->C0 * val); + DoubleNode(EpPrf, "ACLineSegment.b0ch", 0.0); + } + else + { + bval = true; + pName1->LName = pLine->get_Name() + "_PUZ"; + pName1->Set_UUID(GetDevUuid(PUZ, pLine->get_Name(), 1)); + RefNode(EpPrf, "ACLineSegment.PerLengthImpedance", pName1); + // TODO - we no longer have proper length units if matrices were specified + DoubleNode(FunPrf, "Conductor.length", pLine->Len * v1); + } + } + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "ACLineSegment"); + if (!(pLine->SymComponentsModel && (pLine->Fnphases == 3))) + AttachLinePhases(*pLine); + if (bval) + { // writing PuZ on the fly + StartInstance(EpPrf, "PerLengthPhaseImpedance", pName1); + IntegerNode(EpPrf, "PerLengthPhaseImpedance.conductorCount", pLine->Fnphases); + EndInstance(EpPrf, "PerLengthPhaseImpedance"); + seq = 1; + for (i = 1; i <= pLine->Fnphases; ++i) + { + for (j = 1; j <= i; ++j) + { + StartFreeInstance(EpPrf, "PhaseImpedanceData", GetDevUuid(ZData, pName1->LName, seq)); + RefNode(EpPrf, "PhaseImpedanceData.PhaseImpedance", pName1); + IntegerNode(EpPrf, "PhaseImpedanceData.row", i); + IntegerNode(EpPrf, "PhaseImpedanceData.column", j); + DoubleNode(EpPrf, "PhaseImpedanceData.r", pLine->Z->GetElement(i, j).re / 1609.34); + DoubleNode(EpPrf, "PhaseImpedanceData.x", pLine->Z->GetElement(i, j).im / 1609.34); + DoubleNode(EpPrf, "PhaseImpedanceData.b", pLine->YC->GetElement(i, j).im / 1609.34); + EndInstance(EpPrf, "PhaseImpedanceData"); + seq++; + } + } + } + } + WriteTerminals(*pLine, geoUUID, crsUUID, pLine->NormAmps, pLine->EmergAmps); + } + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + + // create the DSS-like load models + id1_ConstkVA = GetDevUuid(LoadResp, "ConstkVA", 1); + id2_ConstZ = GetDevUuid(LoadResp, "ConstZ", 1); + id3_ConstPQuadQ = GetDevUuid(LoadResp, "ConstPQuadQ", 1); + id4_LinPQuadQ = GetDevUuid(LoadResp, "LinPQuadQ", 1); + id5_ConstI = GetDevUuid(LoadResp, "ConstI", 1); + id6_ConstPConstQ = GetDevUuid(LoadResp, "ConstQ", 1); // P can vary, Q not + id7_ConstPConstX = GetDevUuid(LoadResp, "ConstX", 1); + + WriteLoadModel("Constant kVA", id1_ConstkVA, + 0, 0, 100, + 0, 0, 100, + 0, 0); + WriteLoadModel("Constant Z", id2_ConstZ, + 100, 0, 0, + 100, 0, 0, + 0, 0); + WriteLoadModel("Motor", id3_ConstPQuadQ, + 0, 0, 100, + 100, 0, 0, + 0, 0); + WriteLoadModel("Mix Motor/Res", id4_LinPQuadQ, + 0, 0, 0, + 0, 0, 0, + 1, 2); + WriteLoadModel("Constant I", id5_ConstI, + 0, 100, 0, + 0, 100, 0, + 0, 0); + WriteLoadModel("Variable P, Fixed Q", id6_ConstPConstQ, + 0, 0, 100, + 0, 0, 100, + 0, 0); + WriteLoadModel("Variable P, Fixed X", id7_ConstPConstX, + 0, 0, 100, + 100, 0, 0, + 0, 0); + + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while (pLoad != nullptr) + { + if (pLoad->FEnabled) + // with pLoad do + { + StartInstance(FunPrf, "EnergyConsumer", pLoad); + CircuitNode(FunPrf, ActiveCircuit[ActiveActor]); + VbaseNode(FunPrf, *pLoad); + switch (pLoad->FLoadModel) + { + case 1: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id1_ConstkVA); + break; + case 2: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id2_ConstZ); + break; + case 3: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id3_ConstPQuadQ); + break; + case 4: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id4_LinPQuadQ); + break; + case 5: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id5_ConstI); + break; + case 6: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id6_ConstPConstQ); + break; + case 7: + UuidNode(FunPrf, "EnergyConsumer.LoadResponse", id7_ConstPConstX); + break; + } + DoubleNode(SshPrf, "EnergyConsumer.p", 1000.0 * pLoad->kWBase); + DoubleNode(SshPrf, "EnergyConsumer.q", 1000.0 * pLoad->kvarBase); + IntegerNode(FunPrf, "EnergyConsumer.customerCount", pLoad->NumCustomers); + if (pLoad->Connection == 0) + { + ShuntConnectionKindNode(FunPrf, "EnergyConsumer", "Y"); + BooleanNode(FunPrf, "EnergyConsumer.grounded", true); // TODO - check bus 2 + } + else + { + ShuntConnectionKindNode(FunPrf, "EnergyConsumer", "D"); + BooleanNode(FunPrf, "EnergyConsumer.grounded", false); + } + geoUUID = GetDevUuid(LoadLoc, pLoad->get_Name(), 1); + UuidNode(GeoPrf, "PowerSystemResource.Location", geoUUID); + EndInstance(FunPrf, "EnergyConsumer"); + AttachLoadPhases(*pLoad, geoUUID); + WriteTerminals(*pLoad, geoUUID, crsUUID); + AddLoadECP(*pLoad); + } + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + + pLnCd = (TLineCodeObj*) clsLnCd->ElementList.Get_First(); + while (pLnCd != nullptr) + { + // with pLnCd do + { + if (pLnCd->Units == UNITS_NONE) + { // we need the real units for CIM + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != nullptr) + { + if (pLine->FEnabled) + { + if (pLine->CondCode == pLnCd->LName) + { + pLnCd->Units = pLine->FUserLengthUnits; + // WriteLn ("Setting Units on " + pLnCd.LName + " to " + LineUnitsStr(pLnCd.Units)); + break; + } + } + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + } + v1 = To_per_Meter(pLnCd->Units); // TODO: warn if still UNITS_NONE + if (pLnCd->SymComponentsModel && (pLnCd->Fnphases == 3)) + { + v2 = 1.0e-9 * TwoPi * pLnCd->BaseFrequency; // convert nF to mhos + StartInstance(EpPrf, "PerLengthSequenceImpedance", pLnCd); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.r", pLnCd->R1 * v1); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.x", pLnCd->X1 * v1); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.bch", pLnCd->C1 * v1 * v2); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.gch", 0.0); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.r0", pLnCd->R0 * v1); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.x0", pLnCd->X0 * v1); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.b0ch", pLnCd->C0 * v1 * v2); + DoubleNode(EpPrf, "PerLengthSequenceImpedance.g0ch", 0.0); + EndInstance(EpPrf, "PerLengthSequenceImpedance"); + } + else + { + StartInstance(EpPrf, "PerLengthPhaseImpedance", pLnCd); + IntegerNode(EpPrf, "PerLengthPhaseImpedance.conductorCount", pLnCd->Fnphases); + EndInstance(EpPrf, "PerLengthPhaseImpedance"); + seq = 1; + for (i = 1; i <= pLnCd->Fnphases; ++i) + { + for (j = 1; j <= i; ++j) + { + StartFreeInstance(EpPrf, "PhaseImpedanceData", GetDevUuid(ZData, pLnCd->LName, seq)); + RefNode(EpPrf, "PhaseImpedanceData.PhaseImpedance", pLnCd); + IntegerNode(EpPrf, "PhaseImpedanceData.row", i); + IntegerNode(EpPrf, "PhaseImpedanceData.column", j); + DoubleNode(EpPrf, "PhaseImpedanceData.r", pLnCd->Z->GetElement(i, j).re * v1); + DoubleNode(EpPrf, "PhaseImpedanceData.x", pLnCd->Z->GetElement(i, j).im * v1); + DoubleNode(EpPrf, "PhaseImpedanceData.b", pLnCd->YC->GetElement(i, j).im * v1); + EndInstance(EpPrf, "PhaseImpedanceData"); + seq++; + } + } + } + } + pLnCd = (TLineCodeObj*) clsLnCd->ElementList.Get_Next(); + } + + pWire = (TWireDataObj*) clsWire->ElementList.Get_First(); + while (pWire != nullptr) + { + StartInstance(CatPrf, "OverheadWireInfo", pWire); + WriteWireData(*pWire); + BooleanNode(CatPrf, "WireInfo.insulated", false); + EndInstance(CatPrf, "OverheadWireInfo"); + pWire = (TWireDataObj*) clsWire->ElementList.Get_Next(); + } + + pTape = (TTSDataObj*) clsTape->ElementList.Get_First(); + while (pTape != nullptr) + { + StartInstance(CatPrf, "TapeShieldCableInfo", pTape); + WriteWireData(*pTape); + WriteCableData(*pTape); + WriteTapeData(*pTape); + EndInstance(CatPrf, "TapeShieldCableInfo"); + pTape = (TTSDataObj*) clsTape->ElementList.Get_Next(); + } + + pConc = (TCNDataObj*) clsConc->ElementList.Get_First(); + while (pConc != nullptr) + { + StartInstance(CatPrf, "ConcentricNeutralCableInfo", pConc); + WriteWireData(*pConc); + WriteCableData(*pConc); + WriteConcData(*pConc); + EndInstance(CatPrf, "ConcentricNeutralCableInfo"); + pConc = (TCNDataObj*) clsConc->ElementList.Get_Next(); + } + + pGeom = (TLineGeometryObj*) clsGeom->ElementList.Get_First(); + while (pGeom != nullptr) + { + // with pGeom do + { + StartInstance(CatPrf, "WireSpacingInfo", pGeom); + ConductorUsageEnum(CatPrf, "distribution"); + IntegerNode(CatPrf, "WireSpacingInfo.phaseWireCount", 1); + DoubleNode(CatPrf, "WireSpacingInfo.phaseWireSpacing", 0.0); + if (pGeom->FPhaseChoice[0] == Overhead) + BooleanNode(CatPrf, "WireSpacingInfo.isCable", false); + else + BooleanNode(CatPrf, "WireSpacingInfo.isCable", true); + EndInstance(CatPrf, "WireSpacingInfo"); + + for (i = 1; i <= pGeom->Fnconds; ++i) + { + pName1->LName = "WP_" + pGeom->get_Name() + "_" + IntToStr(i); + pName1->Set_UUID(GetDevUuid(WirePos, pName1->LName, 1)); // 1 for pGeom + StartInstance(CatPrf, "WirePosition", pName1); + RefNode(CatPrf, "WirePosition.WireSpacingInfo", pGeom); + IntegerNode(CatPrf, "WirePosition.sequenceNumber", i); + v1 = To_Meters(pGeom->FUnits[i - 1]); + DoubleNode(CatPrf, "WirePosition.xCoord", pGeom->Get_FX(i) * v1); + DoubleNode(CatPrf, "WirePosition.yCoord", pGeom->Get_FY(i) * v1); + EndInstance(CatPrf, "WirePosition"); + } + } + pGeom = (TLineGeometryObj*) clsGeom->ElementList.Get_Next(); + } + + pSpac = (TLineSpacingObj*) clsSpac->ElementList.Get_First(); + while (pSpac != nullptr) + { + // with pSpac do + { + v1 = To_Meters(pSpac->FUnits); + StartInstance(CatPrf, "WireSpacingInfo", pSpac); + ConductorUsageEnum(CatPrf, "distribution"); + IntegerNode(CatPrf, "WireSpacingInfo.phaseWireCount", 1); + DoubleNode(CatPrf, "WireSpacingInfo.phaseWireSpacing", 0.0); + if (pSpac->Get_FY(1) > 0.0) + BooleanNode(CatPrf, "WireSpacingInfo.isCable", false); + else + BooleanNode(CatPrf, "WireSpacingInfo.isCable", true); + EndInstance(CatPrf, "WireSpacingInfo"); + + for (i = 1; i < pSpac->Fnconds; ++i) + { + pName1->LName = "WP_" + pSpac->get_Name() + "_" + IntToStr(i); + pName1->Set_UUID(GetDevUuid(WirePos, pName1->LName, 2)); // 2 for pSpac + StartInstance(CatPrf, "WirePosition", pName1); + RefNode(CatPrf, "WirePosition.WireSpacingInfo", pSpac); + IntegerNode(CatPrf, "WirePosition.sequenceNumber", i); + DoubleNode(CatPrf, "WirePosition.xCoord", pSpac->Get_FX(i) * v1); + DoubleNode(CatPrf, "WirePosition.yCoord", pSpac->Get_FY(i) * v1); + EndInstance(CatPrf, "WirePosition"); + } + } + pSpac = (TLineSpacingObj*) clsSpac->ElementList.Get_Next(); + } + + for (i = 0; i < ECPList.size(); ++i) + { + pECP = ECPList[i]; + if (pECP == nullptr) + break; + StartInstance(SshPrf, "EnergyConnectionProfile", pECP); + if (pECP->daily != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssDaily", pECP->daily); + if (pECP->duty != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssDuty", pECP->duty); + if (pECP->yearly != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssYearly", pECP->yearly); + if (pECP->growth != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssLoadGrowth", pECP->growth); + if (pECP->spectrum != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssSpectrum", pECP->spectrum); + if (pECP->cvr != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssLoadCvrCurve", pECP->cvr); + if (pECP->Tdaily != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssPVTDaily", pECP->Tdaily); + if (pECP->Tduty != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssPVTDuty", pECP->Tduty); + if (pECP->Tyearly != "") + StringNode(SshPrf, "EnergyConnectionProfile.dssPVTYearly", pECP->Tyearly); + for (j = 0; j < pECP->nconn; ++j) + UuidNode(SshPrf, "EnergyConnectionProfile.EnergyConnections", pECP->connections[j]); + EndInstance(SshPrf, "EnergyConnectionProfile"); + } + + // export the operational current limits that were created on-the-fly + for (i = 0; i < OpLimitList.size(); ++i) + { + pILimit = OpLimitList[i]; + if (pILimit == nullptr) + break; + StartInstance(FunPrf, "OperationalLimitSet", pILimit); + EndInstance(FunPrf, "OperationalLimitSet"); + pName1->LName = pILimit->LName + "_Norm"; + pName1->Set_UUID(GetDevUuid(NormAmps, pILimit->LName, 1)); + StartInstance(FunPrf, "CurrentLimit", pName1); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pILimit); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pNormLimit); + DoubleNode(FunPrf, "CurrentLimit.value", pILimit->NormAmps); + EndInstance(FunPrf, "CurrentLimit"); + pName2->LName = pILimit->LName + "_Emerg"; + pName2->Set_UUID(GetDevUuid(EmergAmps, pILimit->LName, 1)); + StartInstance(FunPrf, "CurrentLimit", pName2); + RefNode(FunPrf, "OperationalLimit.OperationalLimitSet", pILimit); + RefNode(FunPrf, "OperationalLimit.OperationalLimitType", pEmergLimit); + DoubleNode(FunPrf, "CurrentLimit.value", pILimit->EmergAmps); + EndInstance(FunPrf, "CurrentLimit"); + } + + delete pName1; + delete pName2; + delete pCRS; + delete pRegion; + delete pSubRegion; + delete pLocation; + delete pSubstation; + delete pSwing; + delete pIsland; + delete pNormLimit; + delete pEmergLimit; + delete pRangeALoLimit; + delete pRangeAHiLimit; + delete pRangeBLoLimit; + delete pRangeBHiLimit; + + // FreeUuidList; // this is deferred for UUID export + FreeBankList(); + FreeECPList(); + FreeOpLimitList(); + + GlobalResult = Filenm; + } + catch (...) { + delete FD; + throw; + } + + delete FD; +} diff --git a/OpenDSSC/Common/ExportCIMXML.h b/OpenDSSC/Common/ExportCIMXML.h new file mode 100644 index 0000000..63b2978 --- /dev/null +++ b/OpenDSSC/Common/ExportCIMXML.h @@ -0,0 +1,35 @@ +#ifndef ExportCIMXMLH +#define ExportCIMXMLH + +/* + ---------------------------------------------------------V- + Copyright (c) 2009-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Write a CIM XML file using RDF Schema for the Common Distribution + Power System Model, IEC 61968-13.*/ + + +//#include + +#include "NamedObject.h" + // for TUuid + +void ExportCDPSM( String Filenm, String SUBSTATION, String SubGeographicRegion, String GeographicRegion, TUuid FdrUUID, TUuid SubUUID, TUuid SubGeoUUID, TUuid RgnUUID, bool Combined = true ); +void StartUuidList( int Size ); +void FreeUuidList( ); +void WriteHashedUUIDs( Textfile& F ); +void AddHashedUUID( const String& key, const String& UuidVal ); +void DefaultCircuitUUIDs( TUuid& fdrID, TUuid& subID, TUuid& rgnID, TUuid& subGeoID ); + +#endif // ExportCIMXMLH + + + + + + + + diff --git a/OpenDSSC/Common/ExportResults.cpp b/OpenDSSC/Common/ExportResults.cpp new file mode 100644 index 0000000..c52114e --- /dev/null +++ b/OpenDSSC/Common/ExportResults.cpp @@ -0,0 +1,4586 @@ + + +#pragma hdrstop + +#include "ExportResults.h" + + + +#include "Ucomplex.h" +#include "Arraydef.h" +#include "Sysutils.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucmatrix.h" +#include "Solution.h" +#include "CktElement.h" +#include "Utilities.h" +#include "Bus.h" +#include "mathutil.h" +#include "DSSClass.h" +#include "PDElement.h" +#include "PCElement.h" +#include "generator.h" +#include "Sensor.h" +#include "Load.h" +#include "RegControl.h" +#include "Transformer.h" +#include "ParserDel.h" +#include +#include "YMatrix.h" +#include "LineGeometry.h" +#include "WireData.h" +#include "LineCode.h" +#include "XfmrCode.h" +#include "NamedObject.h" +#include "GICTransformer.h" +#include "PVsystem.h" +#include "Storage.h" +#include "klusolve.h" +#include "ExportCIMXML.h" +#include "LineSpacing.h" +#include "CNData.h" +#include "TSData.h" + +#include "System.h" + + +namespace ExportResults +{ + std::vector Registers(67,0); + + + void WriteElementVoltagesExportFile( Textfile& F, TDSSCktElement* pElem, int MaxNumNodes ) + { + int Ncond = 0, Nterm = 0, i = 0, j = 0, k = 0, m = 0, Nref = 0, bref = 0; + String BusName; + complex Volts; + double Vpu = 0.0, Vmag = 0.0; + + Ncond = pElem->Get_NConds(); + Nterm = pElem->Get_NTerms(); + k = 0; + BusName = ( StripExtension( pElem->Get_FirstBus() ) ); + Write( F, ( (TNamedObject*) pElem )->Get_myPName() + "." + ((TDSSObject*)pElem)->get_Name() ); + Write( F, Format( ",%d", Nterm )); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Write( F, Format( ",%d,", j )); + Write( F, Format( "%d,%d,", Ncond, pElem->Get_NPhases() )); + Write( F, UpperCase( BusName ) ); + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + k++; + Nref = (pElem->NodeRef)[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Vmag = cabs( Volts ) * 0.001; + if ( Nref == 0 ) + Vpu = 0.0; + else + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + bref = with0->MapNodeToBus[Nref - 1].BusRef; + if ( with0->Buses[bref - 1]->kVBase != 0.0 ) + Vpu = Vmag / with0->Buses[bref - 1]->kVBase; + else + Vpu = 0.0; + if ( i == 1 ) + { + Write( F, Format("%6.3f", with0->Buses[bref - 1]->kVBase * sqrt(3))); + } + } + } + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with1 = ActiveCircuit[ActiveActor]; + { + Write( F, Format(", %d, %10.6g, %6.3f, %9.5g", k, Vmag, cdang(Volts), Vpu)); + } + } //end with ActiveCircuit + } //end numconductors + + /*Zero Fill row*/ + for ( int stop = ( MaxNumNodes ), m = ( Ncond + 1 ); m <= stop; m++) + { + Write( F, ", 0, 0, 0, 0" ); + } + BusName = StripExtension( pElem->Get_NextBus() ); + } // end for numterminals + } //end procedure + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportSeqVoltages( String Filenm ) + + // Export Symmetrical Component bus voltages + + { + TTextRec F = {}; + int i = 0, + j = 0, + Nref = 0; + complex Vph[4] = {cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0)}, + VphLL[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }, + V012[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }; + double V0 = 0.0, + v1 = 0.0, + V2 = 0.0, + Vpu = 0.0, + V2V1 = 0.0, + V0V1 = 0.0, + V_NEMA = 0.0; + complex Vresidual = cmplx(0,0); + + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Bus, V1, p.u.,Base kV, V2, %V2/V1, V0, %V0/V1, Vresidual, %NEMA" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + if ( with0->Buses[i - 1]->get_FNumNodesThisBus() < 3 ) + { + V0 = 0.0; + V2 = 0.0; + V_NEMA = 0.0; + if ( ( with0->Buses[i - 1]->get_FNumNodesThisBus() == 1 ) && with0->PositiveSequence ) + { // first node + Nref = with0->Buses[i - 1]->GetRef( 1 ); + Vph[1 - 1] = with0->Solution->NodeV[Nref]; + v1 = cabs( Vph[1 - 1] ); + } + else + v1 = 0.0; + } + else + { + /*# with ActiveCircuit[ActiveActor]->Solution, Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + auto with2 = with0->Solution; + for ( int stop = 3, j = 1; j <= stop; j++) + { // first nodes named 1, 2, 3 + Vph[j - 1] = with2->NodeV[with1->GetRef( with1->FindIdx( j ) )]; + } + } + + /*Compute LL voltages for Nema unbalance calc*/ + VphLL[1 - 1] = csub( Vph[1 - 1], Vph[2 - 1] ); + VphLL[2 - 1] = csub( Vph[2 - 1], Vph[3 - 1] ); + VphLL[3 - 1] = csub( Vph[3 - 1], Vph[1 - 1] ); + Phase2SymComp( &Vph[0], &V012[0]); + V0 = cabs( V012[1 - 1] ); + v1 = cabs( V012[2 - 1] ); + V2 = cabs( V012[3 - 1] ); + V_NEMA = PctNemaUnbalance( &VphLL[0]); + } + if ( with0->Buses[i-1]->kVBase != 0.0 ) + Vpu = 0.001 * v1 / with0->Buses[i-1]->kVBase; + else + Vpu = 0.0; + if ( v1 > 0.0 ) + { + V2V1 = 100.0 * V2 / v1; + V0V1 = 100.0 * V0 / v1; + } + else + { + V2V1 = 0.0; + V0V1 = 0.0; + } + Vresidual = CZero; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + for ( int stop = with0->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + caccum( Vresidual, with0->Solution->NodeV[with0->Buses[i - 1]->GetRef( j )] ); + + WriteLn( F, Format("\"%s\", %10.6g, %9.5g, %8.2f, %10.6g, %8.4g, %10.6g, %8.4g, %10.6g, %8.4g", + UpperCase(with0->BusList.Get(i)).c_str(), v1, Vpu, + (with0->Buses[i - 1]->kVBase * SQRT3), V2, V2V1, V0, V0V1, cabs(Vresidual), V_NEMA)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + //------------------------------------------------------------------- + + + + void ExportVoltages( String Filenm ) + + // Export Symmetrical Component bus voltages + + { + int MaxNumNodes = 0; + TTextRec F; + int i = 0, j = 0, jj = 0; + String BusName; + complex Volts; + int Nref = 0; + int NodeIdx = 0; + double Vmag = 0.0, Vpu = 0.0; + + + /*Find max nodes at a bus*/ + MaxNumNodes = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + MaxNumNodes = max( MaxNumNodes, with0->Buses[i - 1]->get_FNumNodesThisBus() ); + } + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Write( F, "Bus, BasekV" ); + for (int stop = MaxNumNodes, i = 1; i <= stop; i++) + { + Write(F, Format(", Node%d, Magnitude%d, Angle%d, pu%d", i, i, i, i)); + } + WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with1 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with1->NumBuses, i = 1; i <= stop; i++) + { + BusName = with1->BusList.Get( i ); + + Write( F, Format("\"%s\", %.5g", UpperCase(BusName).c_str(), with1->Buses[i - 1]->kVBase * SQRT3)); + jj = 1; + /*# with Buses^[i] do */ + { + auto with2 = with1->Buses[i - 1]; + for ( int stop = with2->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + do + { + NodeIdx = with2->FindIdx( jj ); // Try to find nodes in order + jj++; + } + while ( ! ( NodeIdx > 0 ) ); + Nref = with2->GetRef( NodeIdx ); + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Vmag = cabs( Volts ); + if ( with2->kVBase != 0.0 ) + Vpu = 0.001 * Vmag / with2->kVBase; + else + Vpu = 0.0; + + Write( F, Format(", %d, %10.6g, %6.1f, %9.5g", with2->GetNum(NodeIdx), Vmag, cdang(Volts), Vpu)); + } + } + /*Zero Fill row*/ + for ( int stop = MaxNumNodes, j = with1->Buses[i - 1]->get_FNumNodesThisBus() + 1; j <= stop; j++) + Write( F, ", 0, 0, 0, 0" ); + WriteLn( F ); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void CalcAndWriteSeqCurrents( Textfile& F, int j, TDSSCktElement* pElem, pComplexArray cBuffer, bool DoRatings ) + { + double I0 = 0.0, + I1 = 0.0, + I2 = 0.0, + I2I1 = 0.0, + I0I1 = 0.0, + iNormal = 0.0, + iEmerg = 0.0, + I_NEMA = 0.0; + int i = 0, + k = 0, + Ncond = 0; + complex Iph[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + I012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + complex Iresidual = cmplx(0,0); + + + Ncond = pElem->Get_NConds(); + + if ( pElem->Get_NPhases() >= 3 ) + { + for ( int stop = 3, i = 1; i <= stop; i++) + { + k = ( j - 1 ) * Ncond + i; + Iph[i - 1] = cBuffer[k - 1]; + } + Phase2SymComp( &Iph[0], &I012[0]); + I0 = cabs( I012[1 - 1] ); + I1 = cabs( I012[2 - 1] ); + I2 = cabs( I012[3 - 1] ); + I_NEMA = PctNemaUnbalance(&Iph[0]); + } + else + { + I0 = 0.0; + I1 = 0.0; + I2 = 0.0; + I_NEMA = 0.0; + if // Use phase 1 only + ( ActiveCircuit[ActiveActor]->PositiveSequence ) + I1 = cabs( Iph[1 - 1] ); + } + if ( I1 > 0.0 ) + { + I2I1 = 100.0 * I2 / I1; + I0I1 = 100.0 * I0 / I1; + } + else + { + I2I1 = 0.0; + I0I1 = 0.0; + } + if // Only for 1st Terminal + ( DoRatings && ( j == 1 ) ) + { + iNormal = ( (TPDElement*) pElem )->NormAmps; + if ( iNormal > 0.0 ) + iNormal = I1 / iNormal * 100.0; + iEmerg = ( (TPDElement*) pElem )->EmergAmps; + if ( iEmerg > 0.0 ) + iEmerg = I1 / iEmerg * 100.0; + } + else + { + iNormal = 0.0; + iEmerg = 0.0; + } + Iresidual = CZero; + for ( int stop = Ncond, i = 1; i <= stop; i++) + caccum( Iresidual, cBuffer[i - 1] ); + + WriteLn( F, Format("\"%s\", %3d, %10.6g, %8.4g, %8.4g, %10.6g, %8.4g, %10.6g, %8.4g, %10.6g, %8.4g", + (pElem->Get_myPName() + "." + UpperCase(pElem->get_Name())).c_str(), + j, I1, iNormal, iEmerg, I2, I2I1, I0, I0I1, cabs(Iresidual), I_NEMA)); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportSeqCurrents( String Filenm ) + { + TTextRec F; + int j = 0; + TDSSCktElement* pElem; + TPDElement* PDElem; + TPCElement* PCelem; + pComplexArray cBuffer; // Allocate to max total conductors + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + + /*Sequence Currents*/ + WriteLn( F, "Element, Terminal, I1, %Normal, %Emergency, I2, %I2/I1, I0, %I0/I1, Iresidual, %NEMA" ); + + /*Allocate cBuffer big enough for largest circuit element*/ + cBuffer = new complex[ GetMaxCktElementSize() ]; + + + //Sources Get_First() + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + for ( int stop = pElem->Get_NTerms(), j = 1; j <= stop; j++) + CalcAndWriteSeqCurrents( F, j, pElem, cBuffer, false ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS Next + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + { + PDElem->GetCurrents( cBuffer, ActiveActor ); + for ( int stop = PDElem->Get_NTerms(), j = 1; j <= stop; j++) + CalcAndWriteSeqCurrents( F, j, PDElem, cBuffer, true ); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCelemENTS next + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( ( (TDSSCktElement*) PCelem )->Get_Enabled() ) + { + PCelem->GetCurrents( cBuffer, ActiveActor ); + for ( int stop = ((TDSSCktElement*)PCelem)->Get_NTerms(), j = 1; j <= stop; j++) + CalcAndWriteSeqCurrents( F, j, PCelem, cBuffer, false ); + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + + + //Faults Get_Next() + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + for ( int stop = pElem->Get_NTerms(), j = 1; j <= stop; j++) + CalcAndWriteSeqCurrents( F, j, pElem, cBuffer, false ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + if (( cBuffer != NULL ) ) + free( cBuffer ); + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void CalcAndWriteCurrents( Textfile& F, TDSSCktElement* pElem, pComplexArray cBuffer, int CondWidth, int TermWidth ) + { + int i = 0, j = 0, k = 0; + complex Iresid; + + + k = 0; + Write( F, pElem->Get_myPName() + "." + UpperCase(pElem->get_Name() )); + for ( int stop = pElem->Get_NTerms(), j = 1; j <= stop; j++) + { + Iresid = CZero; + for ( int stop = pElem->Get_NConds(), i = 1; i <= stop; i++) + { + k++; + + Write( F, Format(", %10.6g, %8.2f", cabs(cBuffer[k - 1]), cdang(cBuffer[k - 1]))); + caccum( Iresid, cBuffer[k - 1] ); + } + for ( int stop = CondWidth, i = pElem->Get_NConds() + 1; i <= stop; i++) + { + Write( F, Format(", %10.6g, %8.2f", 0.0, 0.0)); + } + + Write( F, Format(", %10.6g, %8.2f", cabs(Iresid), cdang(Iresid))); + } + + /*Filler if no. terms less than termwidth*/ + for ( int stop = TermWidth, j = pElem->Get_NTerms() + 1; j <= stop; j++) + for ( int stop = CondWidth + 1, i = 1; i <= stop; i++) + { + Write( F, Format(", %10.6g, %8.2f", 0.0, 0.0)); + } + WriteLn( F ); + } + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void CalcAndWriteMaxCurrents( Textfile& F, TPDElement* pElem, pComplexArray cBuffer ) + { + int RatingIdx = 0, i = 0; + double EmergAmps = 0.0, NormAmps = 0.0, CurrMag = 0.0, MaxCurrent = 0.0; + complex LocalPower; + TXYcurveObj* RSignal; + + // Initializes NomrAmps and EmergAmps with the default values for the PDElement + NormAmps = pElem->NormAmps; + EmergAmps = pElem->EmergAmps; + if ( SeasonalRating ) + { + if ( SeasonSignal != "" ) + { + RSignal = (TXYcurveObj*) XYCurveClass[ActiveActor]->Find( SeasonSignal ); + if ( RSignal != NULL ) + { + RatingIdx = trunc( RSignal->GetYValue_( ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour ) ); + // Brings the seasonal ratings for the PDElement + if ( ( RatingIdx <= pElem->NumAmpRatings ) && ( pElem->NumAmpRatings > 1 ) ) + { + NormAmps = pElem->AmpRatings[RatingIdx]; + EmergAmps = pElem->AmpRatings[RatingIdx]; + } + } + else + SeasonalRating = false; // The XYCurve defined doesn't exist + } + else + SeasonalRating = false; // The user didn't define the seasonal signal + } + Write( F, pElem->Get_myPName() + "." + UpperCase(pElem->get_Name())); + MaxCurrent = 0.0; + for ( int stop = pElem->Get_NPhases(), i = 1; i <= stop; i++) + { + CurrMag = cabs( cBuffer[i - 1] ); + if ( CurrMag > MaxCurrent ) + MaxCurrent = CurrMag; + } + //----pElem.ActiveTerminalIdx := 1; + LocalPower = cmulreal( pElem->Get_Power(1, ActiveActor), 0.001 ); + if ( ( pElem->NormAmps == 0.0 ) || ( pElem->EmergAmps == 0.0 ) ) + { + Write( F, Format(", %10.6g, %8.2f, %8.2f", MaxCurrent, 0.0, 0.0)); + } + else + { + Write( F, Format(", %10.6g, %8.2f, %8.2f", MaxCurrent, MaxCurrent / NormAmps * 100.0, MaxCurrent / EmergAmps * 100.0)); + } + + Write( F, Format(", %10.6g, %10.6g, %d, %d, %d", LocalPower.re, LocalPower.im, pElem->BranchNumCustomers, pElem->BranchTotalCustomers, pElem->Get_NPhases())); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, Format(", %-.3g ", (with0->Buses[with0->MapNodeToBus[pElem->NodeRef[0] - 1].BusRef - 1]->kVBase))); + } + } + WriteLn( F ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportCurrents( String Filenm ) + { + TTextRec F; + pComplexArray cBuffer; + TDSSCktElement* pElem; + int MaxCond = 0, MaxTerm = 0; + int i = 0, j = 0; + + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + cBuffer = new complex[ GetMaxCktElementSize() ]; + + /*Calculate the width of the file*/ + MaxCond = 1; + MaxTerm = 2; + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_NTerms() > MaxTerm ) + MaxTerm = pElem->Get_NTerms(); + if ( pElem->Get_NConds() > MaxCond ) + MaxCond = pElem->Get_NConds(); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + + + /*Branch Currents*/ + Write( F, "Element" ); + for ( int stop = MaxTerm, i = 1; i <= stop; i++) + { + for (int stop = MaxCond, j = 1; j <= stop; j++) + { + Write(F, Format(", I%d_%d, Ang%d_%d", i, j, i, j)); + } + + Write( F, Format(", Iresid%d, AngResid%d", i, i)); + } + WriteLn( F ); + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + CalcAndWriteCurrents( F, pElem, cBuffer, MaxCond, MaxTerm ); + } + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + CalcAndWriteCurrents( F, pElem, cBuffer, MaxCond, MaxTerm ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + CalcAndWriteCurrents( F, pElem, cBuffer, MaxCond, MaxTerm ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + CalcAndWriteCurrents( F, pElem, cBuffer, MaxCond, MaxTerm ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + if (( cBuffer != NULL ) ) + free( cBuffer ); + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteNodeList( Textfile& F, const String CktElementName ) + { + int NValues = 0, i = 0; + + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ! ActiveCircuit[ActiveActor]->Issolved ) + { + DoSimpleMsg( "Circuit must be solved for this command to execute properly.", 222001 ); + return; + } + if ( CktElementName.size( ) > 0 ) + { + SetObject( CktElementName ); + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor]->ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + + Write( F, Format("\"%s\", %d, %d", CktElementName.c_str(), with0->Get_NTerms(), with0->Get_NConds())); + NValues = with0->Get_NConds() * with0->Get_NTerms(); + for ( int stop = NValues, i = 1; i <= stop; i++) + { + Write( F, Format(", %d", GetNodeNum(with0->NodeRef[i - 1]))); + } + WriteLn( F ); + } + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportNodeOrder( String Filenm ) + + /* Writes NodeLists in same order as Export Currents function + */ + { + TTextRec F; + TDSSCktElement* pElem; + String strName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Header Record*/ + Write( F, "Element, Nterminals, Nconductors, Node-1, Node-2, Node-3, ..." ); + WriteLn( F ); + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*) pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*) pElem)->get_Name(); + WriteNodeList( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteNodeList( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteNodeList( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteNodeList( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteElemCurrents( Textfile& F, const String CktElementName ) + { + int NValues = 0, i = 0; + + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ! ActiveCircuit[ActiveActor]->Issolved ) + { + DoSimpleMsg( "Circuit must be solved for this command to execute properly.", 222001 ); + return; + } + if ( CktElementName.size( ) > 0 ) + { + SetObject( CktElementName ); + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor]->ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + + with0->ComputeIterminal( ActiveActor ); + + Write( F, Format("\"%s\", %d, %d", CktElementName.c_str(), with0->Get_NTerms(), with0->Get_NConds())); + NValues = with0->Get_NConds() * with0->Get_NTerms(); + for ( int stop = NValues, i = 1; i <= stop; i++) + { + Write( F, Format(", %10.6g, %8.2f", cabs(with0->Iterminal[i - 1]), cdang(with0->Iterminal[i - 1]))); + } + WriteLn( F ); + } + } + } + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportElemCurrents( String Filenm ) + + /* Export currents in same order as NodeOrder export + */ + { + TTextRec F; + TDSSCktElement* pElem; + String strName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Header Record*/ + Write( F, "Element, Nterminals, Nconductors, I_1, Ang_1, ..." ); + WriteLn( F ); + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*) pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemCurrents( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemCurrents( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemCurrents( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemCurrents( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteElemVoltages( Textfile& F, const String CktElementName ) + { + int NValues = 0, i = 0; + + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ! ActiveCircuit[ActiveActor]->Issolved ) + { + DoSimpleMsg( "Circuit must be solved for this command to execute properly.", 222001 ); + return; + } + if ( CktElementName.size( ) > 0 ) + { + SetObject( CktElementName ); + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor]->ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + + with0->ComputeVterminal( ActiveActor ); + + Write( F, Format("\"%s\", %d, %d", CktElementName.c_str(), with0->Get_NTerms(), with0->Get_NConds())); + NValues = with0->Get_NConds() * with0->Get_NTerms(); + for ( int stop = NValues, i = 1; i <= stop; i++) + { + Write( F, Format(", %10.6g, %8.2f", cabs(with0->Vterminal[i - 1]), cdang(with0->Vterminal[i - 1]))); + } + WriteLn( F ); + } + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportElemVoltages( String Filenm ) + /* Export conductor voltages in same order as NodeOrder export + */ + { + TTextRec F; + TDSSCktElement* pElem; + String strName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Header Record*/ + Write( F, "Element, Nterminals, Nconductors, V_1, Ang_1, ..." ); + WriteLn( F ); + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemVoltages( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemVoltages( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemVoltages( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemVoltages( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteElemPowers( Textfile& F, const String CktElementName ) + { + int NValues = 0, i = 0; + + complex S; + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ! ActiveCircuit[ActiveActor]->Issolved ) + { + DoSimpleMsg( "Circuit must be solved for this command to execute properly.", 222001 ); + return; + } + if ( CktElementName.size( ) > 0 ) + { + SetObject( CktElementName ); + if (( ActiveCircuit[ActiveActor]->get_FActiveCktElement() != NULL ) ) + /*# with ActiveCircuit[ActiveActor]->ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + with0->ComputeVterminal( ActiveActor ); + with0->ComputeIterminal( ActiveActor ); + + Write( F, Format("\"%s\", %d, %d", CktElementName.c_str(), with0->Get_NTerms(), with0->Get_NConds())); + NValues = with0->Get_NConds() * with0->Get_NTerms(); + for ( int stop = NValues, i = 1; i <= stop; i++) + { + S = cmul( with0->Vterminal[i - 1], conjg( with0->Iterminal[i - 1] ) ); + + Write( F, Format(", %10.6g, %10.6g", S.re * 0.001, S.im * 0.001)); + } + WriteLn( F ); + } + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportElemPowers( String Filenm ) + + /* Export conductor powers in same order as NodeOrder export + */ + { + TTextRec F; + TDSSCktElement* pElem; + String strName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Header Record*/ + Write( F, "Element, Nterminals, Nconductors, P_1, Q_1, ..." ); + WriteLn( F ); + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemPowers( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemPowers( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemPowers( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + strName = ((TDSSObject*)pElem)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)pElem)->get_Name(); + WriteElemPowers( F, strName ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportPowers( String Filenm, int Opt ) + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + TTextRec F; + int Nterm = 0, j = 0; + TPDElement* PDElem; + TPCElement* PCelem; + complex S; + String Separator; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Separator = ", "; + switch ( Opt ) + { + case 1: + WriteLn( F, "Element, Terminal, P(MW), Q(Mvar), P_Normal, Q_Normal, P_Emergency, Q_Emergency" ); + break; + default: + WriteLn( F, "Element, Terminal, P(kW), Q(kvar), P_Normal, Q_Normal, P_Emergency, Q_Emergency" ); + } + + // PDELEMENTS first + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if (UpperCase(PDElem->get_Name()) == "TPX2224490448C0") + int a = 10; + if ( PDElem->Get_Enabled() ) + { + Nterm = PDElem->Get_NTerms(); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Write( F, Pad( "\"" + PDElem->Get_myPName() + "." + UpperCase(PDElem->get_Name() ) + "\"", 24 ) ); Write( F, Separator ); Write( F, j, 3 ); + //----PDElem.ActiveTerminalIdx := j; + S = PDElem->Get_Power(j, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F,Format( "%8.1f",S.re * 0.001)); + Write( F, Separator ); Write( F, Format("%8.1f", S.im * 0.001)); + if ( j == 1 ) + { + //----PDelem.ActiveTerminalIdx := 1; + S = PDElem->Get_ExcessKVANorm(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write(F, Separator); Write(F, Format("%8.1f", Abs(S.re))); + Write(F, Separator); Write(F, Format("%8.1f", Abs(S.im))); + S = PDElem->Get_ExcessKVAEmerg(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%8.1f", Abs( S.re ))); + Write( F, Separator ); Write( F, Format("%8.1f", Abs( S.im ))); + } + WriteLn( F ); + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( ( (TDSSCktElement*) PCelem)->Get_Enabled() ) + { + Nterm = ((TDSSCktElement*)PCelem)->Get_NTerms(); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Write( F, Pad( "\"" + PCelem->Get_myPName() + "." + UpperCase(PCelem->get_Name()) + "\"", 24 ) ); Write( F, Separator ); Write( F, j, 3 ); + //----pcElem.ActiveTerminalIdx := j; + S = ((TDSSCktElement*)PCelem)->Get_Power(j, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%8.1f", S.re * 0.001)); + Write( F, Separator ); Write( F, Format("%8.1f", S.im * 0.001)); + WriteLn( F ); + } + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportLosses( String Filenm ) + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + TTextRec F; + TPDElement* PDElem; + + complex S_total, S_Load, S_NoLoad; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Element, Total(W), Total(var), I2R(W), I2X(var), No-load(W), No-load(var)" ); + // PDELEMENTS first + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + { + PDElem->GetLosses( S_total, S_Load, S_NoLoad, ActiveActor ); + + WriteLn( F, Format("%s.%s, %.7g, %.7g, %.7g, %.7g, %.7g, %.7g", + PDElem->ParentClass->get_myClass_name().c_str(), + UpperCase(PDElem->get_Name()).c_str(), + S_total.re, S_total.im, S_Load.re, S_Load.im, S_NoLoad.re, S_NoLoad.im)); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // =============================================================================== + + + + void ExportPbyphase( String Filenm, int Opt ) + + /* Export Powers by phase */ + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + TTextRec F; + int i = 0; + + TPDElement* PDElem; + TPCElement* PCelem; + complex S; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + switch ( Opt ) + { + case 1: + WriteLn( F, "Element, NumTerminals, NumConductors, NumPhases, MW1, Mvar1, MW2, Mvar2, MW3, Mvar3, ... " ); + break; + default: + WriteLn( F, "Element, NumTerminals, NumConductors, NumPhases, kW1, kvar1, kW2, kvar2, kW3, kvar3, ... " ); + } + + // PDELEMENTS first + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + { + /*# with PDElem do */ + { + auto with0 = PDElem; + with0->ComputeIterminal( ActiveActor ); + with0->ComputeVterminal( ActiveActor ); + + Write( F, Format("\"%s.%s\", %d, %d, %d", + with0->Get_myPName().c_str(), + UpperCase(((TDSSObject*)with0)->get_Name()).c_str(), + with0->Get_NTerms(), with0->Get_NConds(), with0->Get_NPhases())); + for ( int stop = with0->Yorder, i = 1; i <= stop; i++) + { + S = cmulreal( cmul( with0->Vterminal[i - 1], conjg( with0->Iterminal[i - 1] ) ), 0.001 ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); // convert to MVA + + Write( F, Format(", %10.3f, %10.3f", S.re, S.im)); + } + } + WriteLn( F ); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( ( (TDSSCktElement*) PCelem )->Get_Enabled() ) + { + /*# with PCelem do */ + { + auto with0 = PCelem; + with0->ComputeIterminal( ActiveActor ); + with0->ComputeVterminal( ActiveActor ); + + Write( F, Format("\"%s.%s\", %d, %d, %d", + with0->Get_myPName().c_str(), + UpperCase(with0->get_Name()).c_str(), + with0->Get_NTerms(), with0->Get_NConds(), with0->Get_NPhases())); + + for ( int stop = with0->Yorder, i = 1; i <= stop; i++) + { + S = cmulreal( cmul((with0->Vterminal)[i - 1], conjg((with0->Iterminal)[i - 1] ) ), 0.001 ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); // convert to MVA + + Write( F, Format(", %10.3f, %10.3f", S.re, S.im)); + } + } + WriteLn( F ); + } + PCelem = (TPCElement*)ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportSeqPowers( String Filenm, int Opt ) + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + TTextRec F; + vector cBuffer; + int Ncond = 0, + Nterm = 0, + i = 0, + j = 0, + k = 0, + Nref = 0; + TPDElement* PDElem = nullptr; + TPCElement* PCelem = nullptr; + complex Volts = cmplx(0,0), + S = cmplx(0, 0); + complex Vph[4] = { cmplx(0,0),cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }, + V012[4] = { cmplx(0,0),cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }; + complex Iph[4] = { cmplx(0,0),cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }, + I012[4] = { cmplx(0,0),cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }; + String Separator; + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Separator = ", "; + cBuffer.resize(GetMaxCktElementSize() + 1); + switch ( Opt ) + { + case 1: + WriteLn( F, "Element, Terminal, P1(MW), Q1(Mvar), P2, Q2, P0, Q0, P_Normal, Q_Normal, P_Emergency, Q_Emergency" ); + break; + default: + WriteLn( F, "Element, Terminal, P1(kW), Q1(kvar), P2, Q2, P0, Q0, P_Normal, Q_Normal, P_Emergency, Q_Emergency" ); + } + + // PDELEMENTS first + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + { + Ncond = PDElem->Get_NConds(); + Nterm = PDElem->Get_NTerms(); + PDElem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Write( F, Pad( "\"" + ( (TDSSObject*) PDElem )->Get_myPName() + "." + UpperCase( ( (TDSSObject*) PDElem )->get_Name() ) + "\"", 24 ) ); Write( F, Separator ); Write( F, j, 3 ); + for ( int stop = PDElem->Get_NPhases(), i = 1; i <= stop; i++) + { + k = ( j - 1 ) * Ncond + i; + Nref = (PDElem->NodeRef)[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + if (cBuffer[k].re < -1e+10 && cBuffer[k].im < -1e+10) + { + cBuffer[k].re = 0; + cBuffer[k].im = 0; + } + Iph[i - 1] = (cBuffer)[k-1]; + Vph[i - 1] = Volts; + } + if ( PDElem->Get_NPhases() >= 3 ) + { + Phase2SymComp( &Iph[0], &I012[0]); + Phase2SymComp( &Vph[0], &V012[0]); + } + else + { + V012[1 - 1] = CZero; + I012[1 - 1] = CZero; + V012[3 - 1] = CZero; + I012[3 - 1] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[2 - 1] = Vph[1 - 1]; + I012[2 - 1] = Iph[1 - 1]; + } + else + { + V012[2 - 1] = CZero; + I012[2 - 1] = CZero; + } + } + S = cmul( V012[2 - 1], conjg( I012[2 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f",S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%10.1f", S.im * 0.003)); + S = cmul( V012[3 - 1], conjg( I012[3 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%10.1f", S.im * 0.003)); + S = cmul( V012[1 - 1], conjg( I012[1 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%8.1f", S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%8.1f", S.im * 0.003)); + if ( j == 1 ) + { + //----PDelem.ActiveTerminalIdx := 1; + S = PDElem->Get_ExcessKVANorm(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", Abs( S.re ))); + Write( F, Separator ); Write( F, Format("%10.1f", Abs( S.im ))); + S = PDElem->Get_ExcessKVAEmerg(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", Abs( S.re ))); + Write( F, Separator ); Write( F, Format("%10.1f", Abs( S.im ))); + } + WriteLn( F ); + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( ( (TDSSCktElement*) PCelem )->Get_Enabled() ) + { + Ncond = ((TDSSCktElement*)PCelem)->Get_NConds(); + Nterm = ((TDSSCktElement*)PCelem)->Get_NTerms(); + PCelem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Write( F, Pad( "\"" + ((TDSSObject*)PCelem)->Get_myPName() + "." + UpperCase(((TDSSObject*)PCelem)->get_Name() ) + "\"", 24 ) ); Write( F, Separator ); Write( F, j, 3 ); + for ( int stop = ((TDSSCktElement*)PCelem)->Get_NPhases(), i = 1; i <= stop; i++) + { + k = ( j - 1 ) * Ncond + i; + Nref = (((TDSSCktElement*)PCelem)->NodeRef)[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Iph[i - 1] = (cBuffer)[k-1]; + Vph[i - 1] = Volts; + } + if (((TDSSCktElement*)PCelem)->Get_NPhases() >= 3 ) + { + Phase2SymComp( &Iph[0], &I012[0]); + Phase2SymComp( &Vph[0], &V012[0]); + } + else + { + V012[1 - 1] = CZero; + I012[1 - 1] = CZero; + V012[3 - 1] = CZero; + I012[3 - 1] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[2 - 1] = Vph[1 - 1]; + I012[2 - 1] = Iph[1 - 1]; + } + else + { + V012[2 - 1] = CZero; + I012[2 - 1] = CZero; + } + } + S = cmul( V012[2 - 1], conjg( I012[2 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%10.1f", S.im * 0.003)); + S = cmul( V012[3 - 1], conjg( I012[3 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%10.1f", S.im * 0.003)); + S = cmul( V012[1 - 1], conjg( I012[1 - 1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + Write( F, Separator ); Write( F, Format("%10.1f", S.re * 0.003)); + Write( F, Separator ); Write( F, Format("%10.1f", S.im * 0.003)); + WriteLn( F ); + } + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + GlobalResult = Filenm; + /*} + __finally + {*/ + cBuffer.resize(0); + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportFaultStudy( String Filenm ) + { + int i = 0, + iBus = 0, + iphs = 0, + iphs2 = 0; + TcMatrix YFault = {}; + vector Vfault; /*Big temp array*/ + TTextRec F = {}; + complex GFault = CZero; + String Separator = ""; + double MaxCurr = 0.0, + CurrMag = 0.0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Separator = ", "; + + /* Set source voltage injection currents */ + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + /*# with Solution do */ + { + auto with1 = ActiveCircuit[ActiveActor]->Solution; + /*All Phase Faults*/ + WriteLn( F, "Bus, 3-Phase, 1-Phase, L-L" ); + for ( int stop = with0->NumBuses, iBus = 1; iBus <= stop; iBus++) + /*Bus Norton Equivalent Current, Isc has been previously computed*/ + /*# with Buses^[iBus] do */ + { + auto& with2 = with0->Buses[iBus - 1]; + { + Write( F, Pad( UpperCase(with0->BusList.Get( iBus ) ), 12 ) ); + MaxCurr = 0.0; + for ( int stop = with2->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + if ( MaxCurr < cabs(with2->BusCurrent[i - 1] ) ) + MaxCurr = cabs( with2->BusCurrent[i - 1] ); + } + Write( F, Separator ); Write( F, Format("%10.0f", MaxCurr)); + + /*One Phase Faults*/ + + /* Solve for Fault Injection Currents*/ + YFault = TcMatrix( with2->get_FNumNodesThisBus() ); + Vfault.resize(with2->get_FNumNodesThisBus() + 1); + + /*Build YscTemp*/ + GFault = cmplx( 10000.0, 0.0 ); + MaxCurr = 0.0; + for ( int stop = with2->get_FNumNodesThisBus(), iphs = 1; iphs <= stop; iphs++) + { + YFault.CopyFrom( &(with2->Ysc) ); + YFault.AddElement( iphs, iphs, GFault ); + + /* Solve for Injection Currents*/ + YFault.Invert(); + YFault.MVmult( &Vfault[0], &(with2->BusCurrent[0])); /*Gets voltage appearing at fault*/ + CurrMag = cabs( cmul( Vfault[iphs - 1], GFault ) ); + if ( CurrMag > MaxCurr ) + MaxCurr = CurrMag; + } /*For iphase*/ + /*Now, Stuff it in the Css Array where it belongs*/ + Write( F, Separator ); Write( F, Format("%10.0f",MaxCurr)); + Vfault.clear(); + + /*Node-Node Faults*/ + + /*Bus Norton Equivalent Current, Isc has been previously computed*/ + YFault = TcMatrix( with2->get_FNumNodesThisBus() ); + Vfault.resize(with2->get_FNumNodesThisBus() + 1); + GFault = cmplx( 10000.0, 0.0 ); + MaxCurr = 0.0; + for ( int stop = with2->get_FNumNodesThisBus(), iphs = 1; iphs <= stop; iphs++) + { + YFault.CopyFrom( &(with2->Ysc) ); + + if (iphs == with2->get_FNumNodesThisBus()) + iphs2 = 1; + else + iphs2 = iphs + 1; + + YFault.AddElement( iphs, iphs, GFault ); + YFault.AddElement( iphs2, iphs2, GFault ); + YFault.AddElemsym( iphs, iphs2, cnegate( GFault ) ); + + /* Solve for Injection Currents*/ + YFault.Invert(); + YFault.MVmult(&(Vfault[0]), &(with2->BusCurrent[0])); /*Gets voltage appearing at fault*/ + CurrMag = cabs( cmul( csub( Vfault[iphs - 1], Vfault[iphs2 - 1] ), GFault ) ); + if ( CurrMag > MaxCurr ) + MaxCurr = CurrMag; + } /*For iphase*/ + /*Now, Stuff it in the Css Array where it belongs*/ + Write( F, Separator ); Write( F, Format("%10.0f", MaxCurr)); + Vfault.clear(); + WriteLn( F ); + } + } /*With bus*/ + } /*With Solution*/ + } + } /*With ActiveCircuit*/ + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ZeroTempXArray( double* TempX ) + { + int ii = 0; + for ( int stop = 3, ii = 1; ii <= stop; ii++) + TempX[ii - 1] = 0.0; + } + + + void ExportEstimation( String Filenm ) + { + TTextRec F; + int i = 0; + TEnergyMeterObj* pEnergyMeterObj; + TSensorObj* pSensorObj; + + double TempX[ 4/*# range 1..3*/ ]; // temp number buffer + try + { + AssignFile( F, Filenm ); + Rewrite( F ); // clears file + IOResultToException(); + + /*Do the EnergyMeters first*/ + WriteLn( F, "\"Energy Meters\" " ); + WriteLn( F, "\"energyMeter\", \"I1 Target\", \"I2 Target\", \"I3 Target\", \"I1 Calc\", \"I2 Calc\", \"I3 Calc\", \"I1 %Err\", \"I2 %Err\", \"I3 %Err\""/*, "I1 Factor", "I2 Factor", "I3 Factor"'*/ ); + pEnergyMeterObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + pEnergyMeterObj->TakeSample(ActiveActor); + while ( pEnergyMeterObj != NULL ) + { + if ( ( (TDSSCktElement*) pEnergyMeterObj)->Get_Enabled() ) + { + Write( F, "\"Energymeter." + ( (TDSSObject*) pEnergyMeterObj)->get_Name() + "\""); + /*Sensor currents (Target)*/ + ZeroTempXArray( TempX ); + for ( i =0; i < pEnergyMeterObj->Get_NPhases(); i++) + TempX[i] = (pEnergyMeterObj->SensorCurrent)[i]; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Calculated Currents*/ + ZeroTempXArray(TempX); + for ( i = 0; i < pEnergyMeterObj->Get_NPhases(); i++) + TempX[i] = cabs( (pEnergyMeterObj->CalculatedCurrent)[i] ); + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Percent Error*/ + for ( i = 0; i < pEnergyMeterObj->Get_NPhases(); i++) + TempX[i] = ( 1.0 - TempX[i] / max( 0.001, (pEnergyMeterObj->SensorCurrent)[i] ) ) * 100.0; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + + /**** Not all that useful + {Allocation Factors} + ZeroTempXArray; + For i := 1 to pEnergyMeterObj.Nphases do TempX[i] := pEnergyMeterObj.PhsAllocationFactor^[i - 1]; + For i := 1 to 3 do Write(F, Format(' %.6g,',[TempX[i]])); + *****/ + WriteLn( F ); + } + pEnergyMeterObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + + /*Do the Sensors Get_Next()*/ + WriteLn( F ); + WriteLn( F, "\"Sensors\" " ); + Write( F, "\"Sensor\", \"I1 Target\", \"I2 Target\", \"I3 Target\", \"I1 Calc\", \"I2 Calc\", \"I3 Calc\", \"I1 %Err\", \"I2 %Err\", \"I3 %Err\"," ); + WriteLn( F, " \"V1 Target\", \"V2 Target\", \"V3 Target\", \"V1 Calc\", \"V2 Calc\", \"V3 Calc\", \"V1 %Err\", \"V2 %Err\", \"V3 %Err\", \"WLS Voltage Err\", \"WLS Current Err\"" ); + pSensorObj = (TSensorObj*) ActiveCircuit[ActiveActor]->Sensors.Get_First(); + while ( pSensorObj != NULL ) + { + if ( ( (TDSSCktElement*) pSensorObj )->Get_Enabled() ) + { + Write( F, "Sensor." + UpperCase( ( (TDSSObject*) pSensorObj )->get_Name() ) ); + /*Sensor currents (Target)*/ + ZeroTempXArray(TempX); + for ( i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = (pSensorObj->SensorCurrent)[i]; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Calculated Currents*/ + ZeroTempXArray(TempX); + for ( i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = cabs( pSensorObj->CalculatedCurrent[i] ); + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Percent Error*/ + for ( i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = ( 1.0 - TempX[i] / max( 0.001, pSensorObj->SensorCurrent[i] ) ) * 100.0; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Sensor Voltage (Target)*/ + ZeroTempXArray(TempX); + for ( i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = pSensorObj->SensorVoltage[i]; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Calculated Voltage*/ + ZeroTempXArray(TempX); + for (i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = cabs( pSensorObj->CalculatedVoltage[i] ); + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*Percent Error*/ + for (i = 0; i < pSensorObj->Get_NPhases(); i++) + TempX[i] = ( 1.0 - TempX[i] / max( 0.001, (pSensorObj->SensorVoltage)[i] ) ) * 100.0; + for (i = 0; i < 3; i++) + { + Write(F, Format(", %.6g", TempX[i])); + } + /*WLS Errors*/ + ZeroTempXArray(TempX); + Write( F, Format(", %.6g, %.6g", pSensorObj->Get_WLSVoltageError(), pSensorObj->Get_WLSCurrentError())); + WriteLn( F ); + } + pSensorObj = (TSensorObj*) ActiveCircuit[ActiveActor]->Sensors.Get_Next(); + } + /* } + __finally + {*/ + AppendGlobalResult( Filenm ); + CloseFile( F ); + } + catch (...) + { + // + } + } + + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteMultipleMeterFiles( ) + { + TTextRec F; + int i = 0, + j = 0; + TEnergyMeterObj* pElem = nullptr; + TEnergyMeter* MeterClass = nullptr; + String Filenm = "", + Separator = ""; + + MeterClass = (TEnergyMeter*) GetDSSClassPtr( "Energymeter" ); + if ( MeterClass == NULL ) + return; // oops somewhere!! + Separator = ", "; + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + { + try + { + Filenm = GetOutputDirectory() + "EXP_MTR_" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + RepTermination; + if ( ! FileExists( Filenm ) ) + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, Meter" ); + for ( int stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + pElem->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + CloseFile( F ); + } + AssignFile( F, Filenm ); + Append( F ); + IOResultToException(); + Write( F, ActiveCircuit[ActiveActor]->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, ActiveCircuit[ActiveActor]->LoadDurCurve ); Write( F, Separator ); + Write( F, ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = NumEMRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, pElem->Registers[j - 1], 10, 0 ); + } + WriteLn( F ); + AppendGlobalResult( Filenm ); + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteSingleMeterFile( const String Filenm ) + { + TTextRec F; + int i = 0, + j = 0; + TEnergyMeterObj* pElem = nullptr; + String TestStr = "", + Separator = ", "; + bool RewriteFile = false; + + try + { + if ( FileExists( Filenm ) ) + { // See if it has already been written on + AssignFile( F, Filenm ); + Reset( F ); + IOResultToException(); + if ( ! Eof( F ) ) + { + Read( F, TestStr ); + /*See if it likely that the file is OK*/ + if ( CompareText( TestStr.substr( 0, 4 ), "Year" ) == 0 ) + RewriteFile = false; // Assume the file is OK + else + RewriteFile = true; + } + else + RewriteFile = true; + CloseFile( F ); + } + else + { + RewriteFile = true; + AssignFile( F, Filenm ); + } + + /*Either open or append the file*/ + if ( RewriteFile ) + { + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + Write( F, "Year, LDCurve, Hour, Meter" ); + for ( int stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + pElem->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + } + else + { + Append( F ); + IOResultToException(); + } + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + { + Write( F, ActiveCircuit[ActiveActor]->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, ActiveCircuit[ActiveActor]->LoadDurCurve ); Write( F, Separator ); + Write( F, ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + //pElem->ResetRegisters(); + //pElem->TakeSample(ActiveActor); +/* +==============This code was added by another group and can be discarded, the original DSS doesn't do this.================= + + auto with1 = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_First(); + auto with2 = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_First(); + auto with3 = (TLineObj*)ActiveCircuit[ActiveActor]->Lines.Get_First(); + + with1->Get_ExceedsNormal(ActiveActor); + with1->Get_Unserved(ActiveActor); + with3->Get_Losses(ActiveActor); + + if (with2->HasEnergyMeter) + { + pElem->Registers[5] = with1->kWBase + with2->kWBase; + pElem->Registers[6] = with1->kvarBase + with2->kvarBase; + pElem->Registers[7] = with1->kWBase + with2->kWBase; + pElem->Registers[8] = with1->kVABase; + pElem->Registers[11] = with1->EEN_Factor; + pElem->Registers[12] = with1->UE_Factor; + pElem->Registers[62] = with1->kWBase + with2->kWBase; + } + else + { + pElem->Registers[5] = with1->kWBase; + pElem->Registers[6] = with1->kvarBase; + pElem->Registers[7] = with1->kWBase; + pElem->Registers[8] = with1->kVABase; + pElem->Registers[11] = with1->EEN_Factor; + pElem->Registers[12] = with1->UE_Factor; + pElem->Registers[62] = with1->kWBase; + + } + */ + for ( int stop = NumEMRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); + Write( F, Format("%10.0f", pElem->Registers[j - 1])); + } + WriteLn( F ); + } + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportMeters( String Filenm ) + + // Export Values of Meter Elements + + // These records are appended to an existing file so a running account is kept for some kinds of simulations + + // If switch /m is specified, a separate file is created for each meter using the meter's name + + { + if ( LowerCase( Filenm.substr( 0, 2 ) ) == "/m" ) + WriteMultipleMeterFiles(); + else + WriteSingleMeterFile( Filenm ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteMultipleGenMeterFiles( ) + { + TTextRec F; + int i = 0, j = 0; + TGeneratorObj* pElem; + //**** GeneratorClass:TGenerator; + + String Filenm, Separator; + + //***** GeneratorClass := TGenerator(GetDSSClassPtr('generator')); + if ( GeneratorClass == NULL ) + return; // oops somewhere!! + Separator = ", "; + pElem = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + try + { + Filenm = GetOutputDirectory() + "EXP_GEN_" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + RepTermination; + if ( ! FileExists( Filenm ) ) + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, Generator" ); + for ( int stop = Generator::NumGenRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + GeneratorClass->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + CloseFile( F ); + } + AssignFile( F, Filenm ); + Append( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = Generator::NumGenRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, Format("%8.0f",pElem->Registers[j - 1])); + } + WriteLn( F ); + } + } + AppendGlobalResult( Filenm ); + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + pElem = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteSingleGenMeterFile( String Filenm ) + { + TTextRec F; + int i = 0, j = 0; + TGeneratorObj* pElem; + //**** GeneratorClass:TGenerator; + + String Separator, TestStr; + bool RewriteFile = false; + + + //**** GeneratorClass := TGenerator(GetDSSClassPtr('generator')); + if ( GeneratorClass == NULL ) + return; // oops somewhere!! + Separator = ", "; + try + { + if ( FileExists( Filenm ) ) + { // See if it has already been written on + AssignFile( F, Filenm ); + Reset( F ); + IOResultToException(); + if ( ! Eof( F ) ) + { + Read( F, TestStr ); + /*See if it likely that the file is OK*/ + if ( CompareText( TestStr.substr( 0, 4 ), "Year" ) == 0 ) + RewriteFile = false; // Assume the file is OK + else + RewriteFile = true; + } + else + RewriteFile = true; + CloseFile( F ); + } + else + { + RewriteFile = true; + AssignFile( F, Filenm ); + } + + /*Either open or append the file*/ + if ( RewriteFile ) + { + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, Generator" ); + for ( int stop = Generator::NumGenRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + GeneratorClass->RegisterNames[i-1] + "\"" ); + } + WriteLn( F ); + } + else + { + Append( F ); + IOResultToException(); + } + pElem = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_First(); + //(TGeneratorObj*)ActiveGeneratorObj->TakeSample(ActiveActor); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + pElem->ResetRegisters(); + pElem->TakeSample(ActiveActor); + for ( int stop = Generator::NumGenRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, Format("%8.0f", pElem->Registers[j - 1])); + } + WriteLn( F ); + } + } + pElem = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteMultiplePVSystemMeterFiles( ) + { + TTextRec F; + int i = 0, j = 0; + TPVsystemObj* pElem; + String Filenm, Separator; + if ( PVSystemClass[ActiveActor] == NULL ) + return; // oops somewhere!! + Separator = ", "; + pElem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + { + try + { + Filenm = GetOutputDirectory() + "EXP_PV_" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + RepTermination; + if ( ! FileExists( Filenm ) ) + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, PVSystem" ); + for ( int stop = NumPVSystemRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + PVSystemClass[ActiveActor]->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + CloseFile( F ); + } + AssignFile( F, Filenm ); + Append( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = NumPVSystemRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, pElem->Registers[j - 1], 10, 0 ); + } + WriteLn( F ); + } + } + AppendGlobalResult( Filenm ); + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + pElem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteSinglePVSystemMeterFile( String Filenm ) + { + TTextRec F; + int i = 0, j = 0; + TPVsystemObj* pElem; + String Separator, TestStr; + bool RewriteFile = false; + if ( PVSystemClass[ActiveActor] == NULL ) return; // oops somewhere!! + Separator = ", "; + try + { + if ( FileExists( Filenm ) ) + { // See if it has already been written on + AssignFile( F, Filenm ); + Reset( F ); + IOResultToException(); + if ( ! Eof( F ) ) + { + Read( F, TestStr ); + /*See if it likely that the file is OK*/ + if ( CompareText( TestStr.substr( 0, 4 ), "Year" ) == 0 ) + RewriteFile = false; // Assume the file is OK + else + RewriteFile = true; + } + else + RewriteFile = true; + CloseFile( F ); + } + else + { + RewriteFile = true; + AssignFile( F, Filenm ); + } + + /*Either open or append the file*/ + if ( RewriteFile ) + { + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, PVSystem" ); + for ( int stop = Generator::NumGenRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + PVSystemClass[ActiveActor]->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + } + else + { + Append( F ); + IOResultToException(); + } + pElem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = NumPVSystemRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, pElem->Registers[j - 1], 10, 0 ); + } + WriteLn( F ); + } + } + pElem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteMultipleStorageMeterFiles( ) + { + TTextRec F; + int i = 0, j = 0; + TStorageObj* pElem; + String Filenm, Separator; + if ( StorageClass[ActiveActor] == NULL ) return; // oops somewhere!! + Separator = ", "; + pElem = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + { + try + { + Filenm = GetOutputDirectory() + "EXP_PV_" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + RepTermination; + if ( ! FileExists( Filenm ) ) + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, Storage" ); + for ( int stop = NumStorageRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + StorageClass[ActiveActor]->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + CloseFile( F ); + } + AssignFile( F, Filenm ); + Append( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = NumStorageRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, pElem->Registers[j - 1], 10, 0 ); + } + WriteLn( F ); + } + } + AppendGlobalResult( Filenm ); + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + pElem = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteSingleStorageMeterFile( String Filenm ) + { + TTextRec F; + int i = 0, j = 0; + TStorageObj* pElem; + String Separator, TestStr; + bool RewriteFile = false; + if ( StorageClass[ActiveActor] == NULL ) return; // oops somewhere!! + Separator = ", "; + try + { + if ( FileExists( Filenm ) ) + { // See if it has already been written on + AssignFile( F, Filenm ); + Reset( F ); + IOResultToException(); + if ( ! Eof( F ) ) + { + Read( F, TestStr ); + /*See if it likely that the file is OK*/ + if ( CompareText( TestStr.substr( 0, 4 ), "Year" ) == 0 ) + RewriteFile = false; // Assume the file is OK + else + RewriteFile = true; + } + else + RewriteFile = true; + CloseFile( F ); + } + else + { + RewriteFile = true; + AssignFile( F, Filenm ); + } + + /*Either open or append the file*/ + if ( RewriteFile ) + { + Rewrite( F ); + IOResultToException(); + /*Write New Header*/ + Write( F, "Year, LDCurve, Hour, Storage" ); + for ( int stop = NumStorageRegisters, i = 1; i <= stop; i++) + { + Write( F, Separator ); Write( F, "\"" + StorageClass[ActiveActor]->RegisterNames[i - 1] + "\"" ); + } + WriteLn( F ); + } + else + { + Append( F ); + IOResultToException(); + } + pElem = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + while ( pElem != NULL ) + { + if ( ( (TDSSCktElement*) pElem )->Get_Enabled() ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Write( F, with0->Solution->get_Fyear(), 0 ); Write( F, Separator ); + Write( F, with0->LoadDurCurve ); Write( F, Separator ); + Write( F, with0->Solution->DynaVars.intHour, 0 ); Write( F, Separator ); + Write( F, Pad( "\"" + UpperCase( ( (TDSSObject*) pElem )->get_Name() ) + "\"", 14 ) ); + for ( int stop = NumStorageRegisters, j = 1; j <= stop; j++) + { + Write( F, Separator ); Write( F, pElem->Registers[j - 1], 10, 0 ); + } + WriteLn( F ); + } + } + pElem = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportGenMeters( String Filenm ) + + // Export Values of Generator Meter Elements + // If switch /m is specified, a separate file is created for each generator using the generator's name + + { + if ( LowerCase( Filenm.substr( 0, 2 ) ) == "/m" ) + WriteMultipleGenMeterFiles(); + else + WriteSingleGenMeterFile( Filenm ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportPVSystemMeters( String Filenm ) + + // Export Values of Generator Meter Elements + // If switch /m is specified, a separate file is created for each generator using the generator's name + + { + if ( LowerCase( Filenm.substr( 0, 2 ) ) == "/m" ) + WriteMultiplePVSystemMeterFiles(); + else + WriteSinglePVSystemMeterFile( Filenm ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportStorageMeters( String Filenm ) + + // Export Values of Generator Meter Elements + // If switch /m is specified, a separate file is created for each generator using the generator's name + + { + if ( LowerCase( Filenm.substr( 0, 2 ) ) == "/m" ) + WriteMultipleStorageMeterFiles(); + else + WriteSingleStorageMeterFile( Filenm ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportLoads( String Filenm ) + + // Export Loads to view present allocation + + { + TTextRec F; + TLoadObj* pElem; + String Separator; + Separator = ", "; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*Write Header*/ + WriteLn( F, "Load, Connected KVA, Allocation Factor, Phases, kW, kvar, PF, Model" ); + pElem = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while ( pElem != NULL ) + { + if (((TDSSCktElement*)pElem)->Get_Enabled()) + /*# with pElem do */ + { + auto with1 = pElem; + Write( F, UpperCase( ( (TDSSObject*) with1 )->get_Name() ) ); + Write( F, Separator ); Write( F, Format("%8.1f", with1->get_FConnectedkVA())); + Write( F, Separator ); Write( F, Format("%8.1f", with1->get_FkVAAllocationFactor())); + Write( F, Separator ); Write( F, ( (TDSSCktElement*) with1 )->Get_NPhases(), 0 ); + Write( F, Separator ); Write( F, Format("%8.1f", with1->kWBase)); + Write( F, Separator ); Write( F, Format("%8.1f", with1->kvarBase)); + Write( F, Separator ); Write( F, Format("%8.1f", with1->PFNominal) ); + Write( F, Separator ); Write(F, with1->FLoadModel); + } + WriteLn( F ); + pElem = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportCapacity( String Filenm ) + + /* + Similar to export currents except does only max of the phases and compares that + to the Normamps and Emergamps rating + */ + { + TTextRec F; + pComplexArray cBuffer; + TPDElement* pElem = nullptr; + TPCElement* pLoads = nullptr; + int* TotalCust = 0; // Pointer to count the number of times the bus is. + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + cBuffer = new complex[ GetMaxCktElementSize() ]; + WriteLn( F, "Name, Imax, %normal, %emergency, kW, kvar, NumCustomers, TotalCustomers, NumPhases, kVBase" ); + + + + + // PDELEMENTS ONLY + pElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + pElem->GetCurrents( cBuffer, ActiveActor ); + CalcAndWriteMaxCurrents( F, pElem, cBuffer ); + } + pElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + if (( cBuffer != NULL ) ) + free( cBuffer ); + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportOverloads( String Filenm ) + { + TTextRec F; + vector cBuffer ; // Allocate to max total conductors + + int Ncond = 0, + i = 0, + j = 0; + TPDElement* PDElem = nullptr; + complex Iph[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0)}, + I012[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0)}; + double I0 = 0.0, + I1 = 0.0, + I2 = 0.0, + iNormal = 0.0, + iEmerg = 0.0, + Cmax = 0.0, + Spower = 0.0; + String Separator = ""; + + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Allocate cBuffer big enough for largest circuit element*/ + cBuffer.resize(GetMaxCktElementSize() + 1); + + /*Sequence Currents*/ + WriteLn( F, "Element, Terminal, I1, AmpsOver, kVAOver, %Normal, %Emergency, I2, %I2/I1, I0, %I0/I1" ); + Separator = ", "; + + // PDELEMENTS Only + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + if // ignore caps + ( ( ( CLASSMASK & ( (TDSSObject*) PDElem )->DSSObjType ) ) != CAP_ELEMENT ) + { + Ncond = PDElem->Get_NConds(); + PDElem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = 1, j = 1; j <= stop; j++) // only for terminal 1 + { + Cmax = 0.0; + int stop1 = 3; + if (PDElem->Get_NPhases() <= 3) + stop1 = PDElem->Get_NPhases(); + for ( i = 1; i <= stop1; i++) + { // Check only first 3 phases + Iph[i - 1] = cBuffer[(( j - 1 ) * Ncond + (i - 1))]; + Cmax = max( Cmax, cabs( Iph[i - 1] ) ); + } + if ( PDElem->Get_NPhases() >= 3 ) + { // Report Symmetrical Component Currents for + Phase2SymComp( &Iph[0], &I012[0]); + I0 = cabs( I012[0] ); // Get abs values to report + I1 = cabs( I012[1] ); + I2 = cabs( I012[2] ); + } + else + { // Other than 3-phase + I0 = 0.0; + I1 = cabs( Iph[0] ); // Ambiguous: Report only first phase + I2 = 0.0; + Cmax = I1; + } + if ( ( PDElem->NormAmps > 0.0 ) || ( PDElem->EmergAmps > 0.0 ) ) + if ( ( Cmax > PDElem->NormAmps ) || ( Cmax > PDElem->EmergAmps ) ) + { + // Get terminal 1 power + Spower = cabs( PDElem->Get_Power(1, ActiveActor) ) * 0.001; // kW + Write( F, Format("%s, %d, ", Pad(("\"" + PDElem->Get_myPName() + "." + UpperCase(PDElem->get_Name()) + "\""), 22).c_str(), j)); + + Write( F, Format("%8.2f, ", I1)); + if ( j == 1 ) + { // Only for 1st Terminal + iNormal = PDElem->NormAmps; + if ( iNormal > 0.0 ) + { + Write( F, Format("%8.2f, %10.2f", (Cmax - iNormal), (Spower * (Cmax - iNormal) / iNormal))); + Write( F, Separator ); Write( F, Format ( "%8.1f", Cmax / iNormal * 100.0)); + } + else + { + Write( F, Separator ); Write( F, " 0.0" ); + } + iEmerg = PDElem->EmergAmps; + if ( iEmerg > 0.0 ) + { + Write( F, Separator ); Write( F, Format("%8.1f",Cmax / iEmerg * 100.0)); + } + else + { + Write( F, Separator ); Write( F, " 0.0" ); + } + } + else + { + Write( F, Separator ); Write( F, " 0" ); Write( F, Separator ); Write( F, " 0" ); + } + Write( F, Separator ); Write( F, Format("%8.1f", I2)); + if ( I1 > 0.0 ) + { + Write( F, Separator ); Write( F, Format("%8.1f", 100.0 * I2 / I1)); + } + else + { + Write( F, Separator ); Write( F, "0.0" ); + } + Write( F, Separator ); Write( F, Format("%8.1f", I0)); + if ( I1 > 0.0 ) + { + Write( F, Separator ); Write( F, Format("%8.1f", 100.0 * I0 / I1)); + } + else + { + Write( F, Separator ); Write( F, "0.0" ); + } + WriteLn( F ); + } + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + DSSGlobals::GlobalResult = Filenm; + /* } + __finally + {*/ + cBuffer.resize(0); + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportUnserved( String Filenm, bool UE_Only ) + { + TTextRec F; + TLoadObj* pLoad; + bool DoIt = false; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Load, Bus, kW, EEN_Factor, UE_Factor" ); + + // Load + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while ( pLoad != NULL ) + { + if ( ( (TDSSCktElement*) pLoad )->Get_Enabled() ) + { + DoIt = false; + if ( UE_Only ) + { + if ( pLoad->Get_Unserved(ActiveActor) ) + DoIt = true; + } + else + if ( pLoad->Get_ExceedsNormal( ActiveActor ) ) + DoIt = true; + if ( DoIt ) + { + Write( F, UpperCase( ( (TDSSObject*) pLoad )->get_Name() ) ); Write( F, ", " ); + Write( F, ( (TDSSCktElement*) pLoad )->GetBus( 1 ) ); Write( F, ", " ); + Write( F, Format("%8.3f", pLoad->kWBase)); Write(F, ", "); + Write( F, Format("%8.3f", pLoad->EEN_Factor)); Write( F, ", " ); + Write( F, Format("%8.3f", pLoad->UE_Factor)); + WriteLn( F ); + } + } + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void ExportYprim( String Filenm ) + + /*Exports YPrim matrices for all Circuit Elements*/ + { + TTextRec F; + int i = 0, j = 0, k = 0; + pComplexArray cValues; + if ( ActiveCircuit[ActiveActor] == NULL ) + return; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumDevices, k = 1; k <= stop; k++) + { + with0->Set_ActiveCktElement((TDSSCktElement*) with0->CktElements.Get( k )); + if (with0->get_FActiveCktElement()->Get_Enabled() ) + { + if ( ( dynamic_cast< TPDElement* >(with0->get_FActiveCktElement() ) ) || ( dynamic_cast< TPCElement* >(with0->get_FActiveCktElement() ) ) ) + /*# with ActiveCktElement do */ + { + auto with1 = with0->get_FActiveCktElement(); + Write( F, with1->ParentClass->get_myClass_name() ); Write( F, '.' ); WriteLn( F, UpperCase( with1->get_Name() ) ); + cValues = with1->GetYPrimValues( ALL_YPRIM ); + for ( int stop = with1->Yorder, i = 1; i <= stop; i++) + { + for (int stop = with1->Yorder, j = 1; j <= stop; j++) + { + Write(F, Format(" % -13.10g, % -13.10g, ", cValues[(i + (j - 1) * with1->Yorder) - 1].re, cValues[(i + (j - 1) * with1->Yorder) - 1].im)); + } + WriteLn( F ); + } + } + } + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // Exports the Jacobian matrix calculated when using NCIM solution algorithm + void ExportJacobian(String Filenm) + { + TTextRec F; + unsigned int i = 0, j = 0, p = 0; + klusparseset_t hY; + unsigned int NBus = 0, nNZ = 0; + std::vector ColPtr; + std::vector RowIdx; + std::vector cVals; + + if (ActiveCircuit[ActiveActor] == NULL) + return; + hY = ActiveCircuit[ActiveActor]->Solution->Jacobian; + if (!hY) + { + DoSimpleMsg("Jacobian Matrix not Built.", 222); + return; + } + // this compresses the entries if necessary - no extra work if already solved + FactorSparseMatrix(hY); + GetNNZ(hY, &nNZ); + GetSize(hY, &NBus); // we should already know this + + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + ColPtr.resize(nNZ); + RowIdx.resize(nNZ); + cVals.resize(nNZ); + GetTripletMatrix(hY, nNZ, &(RowIdx[0]), &(ColPtr[0]), &(cVals[0])); + WriteLn(F, "Row,Col,Value"); + for (i = 0; i < nNZ; i++) + { + WriteLn(F, Format("%d,%d,%.10g", RowIdx[i], ColPtr[i], cVals[i].re)); + } + DSSGlobals::GlobalResult = Filenm; + CloseFile(F); + } + catch (...) + { + // + } + } + + // Exports the deltaF vector obtained in the last iteration of the NCIM solution algorithm (if used) + void ExportdeltaF(String Filenm) + { + TTextRec F; + double re = 0.0; + auto& mydeltaF = ActiveCircuit[ActiveActor]->Solution->deltaF; + if (ActiveCircuit[ActiveActor] == NULL) + return; + if (mydeltaF.size() == 0) + return; + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + int stop = mydeltaF.size(); + for (int i = 0; i < stop; i++) + { + re = mydeltaF[i].re; + WriteLn(F, Format("%.10g", re)); + } + DSSGlobals::GlobalResult = Filenm; + CloseFile(F); + } + catch (...) + { + // + } + } + + // Exports the deltaZ vector obtained in the last iteration of the NCIM solution algorithm (if used) + void ExportdeltaZ(String Filenm) + { + TTextRec F; + double re = 0.0; + auto& mydeltaZ = ActiveCircuit[ActiveActor]->Solution->deltaZ; + if (ActiveCircuit[ActiveActor] == NULL) + return; + if (mydeltaZ.size() == 0) + return; + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + int stop = mydeltaZ.size(); + for (int i = 0; i < stop; i++) + { + re = mydeltaZ[i].re; + WriteLn(F, Format("%.10g", re)); + } + DSSGlobals::GlobalResult = Filenm; + CloseFile(F); + } + catch (...) + { + // + } + } + + // illustrate retrieval of System Y using compressed column format + void ExportY( String Filenm, bool TripletOpt ) + + /*Exports System Y Matrix in Node Order*/ + { + TTextRec F; + unsigned int i = 0, j = 0, p = 0; + unsigned int col = 0, Row = 0; + klusparseset_t hY; + unsigned int NBus = 0, nNZ = 0; + unsigned int* ColPtr = nullptr; + unsigned int* RowIdx = nullptr; + complex* cVals = nullptr; + double re = 0.0, im = 0.0; + if ( ActiveCircuit[ActiveActor] == NULL ) + return; + hY = ActiveCircuit[ActiveActor]->Solution->hY; + if ( ! hY ) + { + DoSimpleMsg( "Y Matrix not Built.", 222 ); + return; + } + // this compresses the entries if necessary - no extra work if already solved + FactorSparseMatrix(hY); + GetNNZ(hY, &nNZ ); + GetSize(hY, &NBus ); // we should already know this + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + if ( TripletOpt ) + { + ColPtr = new unsigned[nNZ]; + RowIdx = new unsigned[nNZ]; + cVals = new complex[nNZ]; + GetTripletMatrix( hY, nNZ, RowIdx, ColPtr, &(cVals[0])); + WriteLn( F, "Row,Col,G,B" ); + for ( int stop = nNZ - 1, i = 0; i <= stop; i++) + { + col = ColPtr[i] + 1; + Row = RowIdx[i] + 1; + if ( Row >= col ) + { + re = cVals[i].re; + im = cVals[i].im; + WriteLn( F, Format("%d,%d,%.10g,%.10g", Row, col, re, im)); + } + } + } + else + { + ColPtr = new unsigned[NBus + 1]; + RowIdx = new unsigned[nNZ]; + cVals = new complex[nNZ]; + + GetCompressedMatrix( hY, NBus + 1, nNZ, ColPtr, RowIdx, cVals); + /*Write out fully qualified Bus Names*/ + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + WriteLn( F, Format("% d, ", with0->NumNodes ) ); + /* For i := 1 to NumNodes DO BEGIN + j := MapNodeToBus^[i].BusRef; + Write(F, Format('%s.%-d, +j,',[BusList.Get(j), MapNodeToBus^[i].NodeNum])); + END; + Writeln(F); + */ + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + j = with0->MapNodeToBus[i - 1].BusRef; + Write( F, Format("\"% s.%-d\", ", UpperCase(with0->BusList.Get(j)).c_str(), with0->MapNodeToBus[i - 1].NodeNum) ); + for ( int stop = with0->NumNodes, j = 1; j <= stop; j++) + { + re = 0.0; + im = 0.0; + // search for a non-zero element [i,j] + // DSS indices are 1-based, KLU indices are 0-based + for ( int stop = ColPtr[j] - 1, p = ColPtr[j - 1]; p <= stop; p++) + { + if ( RowIdx[p] + 1 == i ) + { + re = cVals[p].re; + im = cVals[p].im; + } + } + Write( F, Format("%-13.10g, +j %-13.10g,", re, im)); + } + WriteLn( F ); + } + } + } + } + DSSGlobals::GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportSeqZ( String Filenm ) + + // Export Symmetrical Component Impedances at each bus + + { + TTextRec F; + int i = 0; + complex Z1, Z0; + double X1R1 = 0.0, X0R0 = 0.0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Bus, NumNodes, R1, X1, R0, X0, Z1, Z0, \"X1/R1\", \"X0/R0\"" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + Z1 = with0->Buses[i - 1]->Get_Zsc1(); + Z0 = with0->Buses[i - 1]->Get_Zsc0(); + if ( Z1.re != 0.0 ) + X1R1 = double( Z1.im ) / Z1.re; + else + X1R1 = 1000.0; + if ( Z0.re != 0.0 ) + X0R0 = double( Z0.im ) / Z0.re; + else + X0R0 = 1000.0; + WriteLn( F, Format("\"%s\", %d, %10.6g, %10.6g, %10.6g, %10.6g, %10.6g, %10.6g, %8.4g, %8.4g", + UpperCase(with0->BusList.Get(i)).c_str(), + with0->Buses[i - 1]->get_FNumNodesThisBus(), + Z1.re, Z1.im, Z0.re, Z0.im, + cabs(Z1), cabs(Z0), X1R1, X0R0)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void ExportUuids( String Filenm ) + { + TTextRec F; + TLineCode* clsLnCd; + TLineGeometry* clsGeom; + TWireData* clsWire; + TXfmrCode* clsXfCd; + TLineSpacing* clsSpac; + TTSData* clsTape; + TCNData* clsConc; + TNamedObject* pName; + int i = 0; + try + { + clsLnCd = (TLineCode*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "linecode" ) ); + clsWire = (TWireData*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "wiredata" ) ); + clsGeom = (TLineGeometry*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "linegeometry" ) ); + clsXfCd = (TXfmrCode*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "xfmrcode" ) ); + clsSpac = (TLineSpacing*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "linespacing" ) ); + clsTape = (TTSData*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "TSData" ) ); + clsConc = (TCNData*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "CNData" ) ); + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + pName = (TNamedObject*) ActiveCircuit[ActiveActor]; + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID() ); + for ( int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + pName = ActiveCircuit[ActiveActor]->Buses[0]; + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + } + pName = (TNamedObject*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsLnCd )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsLnCd )->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsWire )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsWire )->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsGeom )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsGeom )->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsXfCd )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsXfCd)->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsSpac )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsSpac )->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsTape )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsTape )->ElementList.Get_Next(); + } + pName = (TNamedObject*) ( (TDSSClass*) clsConc )->ElementList.Get_First(); + while ( pName != NULL ) + { + WriteLn( F, pName->Get_myPName() + "." + pName->Get_myLName() + " " + pName->Get_ID()); + pName = (TNamedObject*) ( (TDSSClass*) clsConc )->ElementList.Get_Next(); + } + WriteHashedUUIDs( F ); + /* } + __finally + {*/ + CloseFile( F ); + FreeUuidList(); + } + catch (...) + { + // + } + } + + void ExportCounts( String Filenm ) + { + TTextRec F; + TDSSClass* cls; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Format: DSS Class Name = Instance Count" ); + WriteLn( F ); + cls = (TDSSClass*) DSSClassList[ActiveActor].Get_First(); + while ( cls != NULL ) + { + WriteLn( F, Format("%s = %d", cls->get_myClass_name().c_str(), cls->Get_ElementCount())); + cls = (TDSSClass*) DSSClassList[ActiveActor].Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void ExportSummary( String Filenm ) + { + TTextRec F; + complex cPower, cLosses; + try + { + AssignFile( F, Filenm ); + if ( FileExists( Filenm ) ) + { + Append( F ); + IOResultToException(); + } + else + { // Create and write the header + Rewrite( F ); + IOResultToException(); + Write( F, "DateTime, CaseName, " ); + Write( F, "Status, Mode, Number, LoadMult, NumDevices, NumBuses, NumNodes" ); + Write( F, ", Iterations, ControlMode, ControlIterations" ); + Write( F, ", MostIterationsDone" ); + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ActiveCircuit[ActiveActor]->Issolved && !ActiveCircuit[ActiveActor]->get_FBusNameRedefined() ) + { + Write( F, ", Year, Hour, MaxPuVoltage, MinPuVoltage, TotalMW, TotalMvar" ); + Write( F, ", MWLosses, pctLosses, MvarLosses, Frequency" ); + } + WriteLn( F ); + } + std::time_t t = std::time(nullptr); + std::tm tm = *std::localtime(&t); + + // Format hour + char buffer[20]; + std::strftime(buffer, sizeof(buffer), "%m/%d/%Y %I:%M:%S", &tm); + + // remove trailing zeros to the left (matchign delphi) + char buffer2[20]; + int idx2 = 0; + bool writeD = false; + for (int idx = 0; idx < 20; idx++) + { + writeD = false; + if (buffer[idx] == '0') + { + if (idx != 0) + writeD = (buffer[idx - 1] != ' '); + } + else + writeD = true; + if (writeD) + { + buffer2[idx2] = buffer[idx]; + idx2++; + } + } + + // Create string object from buffer + std::string am_pm = (tm.tm_hour < 12 ) ? "AM" : "PM"; + std::string formattedTime(buffer2); + formattedTime += " " + am_pm; + //Write( F, "\"" + DateTimeToStr(Now()) + "\"" + ", " ); + Write(F, "\"" + formattedTime + "\"" + ", "); + + if ( ActiveCircuit[ActiveActor] != NULL ) + Write( F, ActiveCircuit[ActiveActor]->get_FCaseName() + ", "); + else + Write( F, "NONE, " ); + if ( ActiveCircuit[ActiveActor]->Issolved ) + Write( F, "SOLVED" ); + else + Write( F, "UnSolved" ); + Write( F, ", " + GetSolutionModeID() ); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->NumberOfTimes)); + Write(F, Format(", %8.3f", ActiveCircuit[ActiveActor]->get_FLoadMultiplier())); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->NumDevices)); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->NumBuses)); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->NumNodes)); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->Iteration)); + Write(F, ", " + GetControlModeID() ); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->ControlIteration)); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->MostIterationsDone)); + + if ( ActiveCircuit[ActiveActor] != NULL ) + if ( ActiveCircuit[ActiveActor]->Issolved && !ActiveCircuit[ActiveActor]->get_FBusNameRedefined() ) + { + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->get_Fyear())); + Write(F, Format(", %d", ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour)); + Write(F, Format(", %-.5g", GetMaxPUVoltage())); + Write(F, Format(", %-.5g", GetMinPUVoltage(true))); + + cPower = cmulreal( GetTotalPowerFromSources( ActiveActor ), 0.000001 ); // MVA + Write(F, Format(", %-.6g", cPower.re)); + Write(F, Format(", %-.6g", cPower.im)); + + cLosses = cmulreal( ActiveCircuit[ActiveActor]->Get_Losses(ActiveActor), 0.000001 ); + if (cPower.re != 0.0) + { + Write(F, Format(", %-.6g, %-.4g", cLosses.re, (double(cLosses.re) / cPower.re * 100.0))); + } + else + Write(F, "Total Active Losses: ****** MW, (*** %%)"); + + Write(F, Format(", %-.6g", cLosses.im)); + Write(F, Format(", %-g", ActiveCircuit[ActiveActor]->Solution->get_FFrequency())); + } + WriteLn( F ); + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportBusCoords( String Filenm ) + // Export bus x, y coordinates + + { + TTextRec F; + int i = 0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + if (with0->Buses[i - 1]->CoordDefined) + { + WriteLn(F, Format("%s, %-13.11g, %-13.11g", CheckForBlanks(UpperCase(with0->BusList.Get(i))).c_str(), with0->Buses[i - 1]->x, with0->Buses[i - 1]->y)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void WriteNewLine( Textfile& F, const String CktElementName, double DistFromMeter1, double puV1, double DistFromMeter2, double puV2, int ColorCode, int Thickness, int LineType, int MarkCenter, int CenterMarkerCode, int NodeMarkerCode, int NodeMarkerWidth ) + { + Write( F, Format( "%s, %.6g, %.6g, %.6g, %.6g,", UpperCase( CktElementName ).c_str(), DistFromMeter1, puV1, DistFromMeter2, puV2 )); + Write( F, Format( "%d, %d, %d, ", ColorCode, Thickness, LineType )); + Write( F, Format( "%d, ", MarkCenter )); + Write( F, Format( "%d, %d, %d", CenterMarkerCode, NodeMarkerCode, NodeMarkerWidth )); + WriteLn( F ); + } + + void ExportProfile( String Filenm, int PhasesToPlot ) + { + int iEnergyMeter = 0; + TEnergyMeterObj* ActiveEnergyMeter; + TDSSCktElement* PresentCktElement; + TDSSBus* Bus1; + TDSSBus* Bus2; + double puV1 = 0.0, puV2 = 0.0; + int iphs = 0; + int iphs2 = 0; + String S; + TTextRec F; + int LineType = 0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Write( F, "Name, Distance1, puV1, Distance2, puV2, Color, Thickness, Linetype, Markcenter, Centercode, NodeCode, NodeWidth," ); + + /*New graph created before this routine is entered*/ + switch ( PhasesToPlot ) + { + case PROFILELL: case PROFILELLALL: case PROFILELLPRI: + S = "L-L Voltage Profile"; + break; + default: + S = "L-N Voltage Profile"; + } + Write( F, "Title=" ); Write( F, S ); WriteLn( F, ", Distance in km" ); + iEnergyMeter = EnergyMeterClass[ActiveActor]->Get_First(); + while ( iEnergyMeter > 0 ) + { + ActiveEnergyMeter = (TEnergyMeterObj*) EnergyMeterClass[ActiveActor]->GetActiveObj(); + /*Go down each branch list and draw a line*/ + PresentCktElement = (TDSSCktElement*) ActiveEnergyMeter->BranchList->Get_First(); + while ( PresentCktElement != NULL ) + { + if ( IslineElement( PresentCktElement ) ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + Bus1 = with0->Buses[PresentCktElement->Terminals[1 - 1].BusRef - 1]; + Bus2 = with0->Buses[PresentCktElement->Terminals[2 - 1].BusRef - 1]; + /*Now determin which phase to plot*/ + if ( ( Bus1->kVBase > 0.0 ) && ( Bus2->kVBase > 0.0 ) ) + switch ( PhasesToPlot ) + { + case + /*3ph only*/ PROFILE3PH: + if ( ( PresentCktElement->Get_NPhases() >= 3 ) && ( Bus1->kVBase > 1.0 ) ) + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + puV1 = double( double( cabs(with0->Solution->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )] ) ) ) / Bus1->kVBase / 1000.0; + puV2 = double( double( cabs(with0->Solution->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )] ) ) ) / Bus2->kVBase / 1000.0; + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, 0, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + break; + /*Plot all phases present (between 1 and 3)*/ + case PROFILEALL: + { + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + puV1 = double( double( cabs(with0->Solution->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )] ) ) ) / Bus1->kVBase / 1000.0; + puV2 = double( double( cabs(with0->Solution->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )] ) ) ) / Bus2->kVBase / 1000.0; + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + break; + /*Plot all phases present (between 1 and 3) for Primary only*/ + case PROFILEALLPRI: + { + if ( Bus1->kVBase > 1.0 ) + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + puV1 = double( double( cabs(with0->Solution->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )] ) ) ) / Bus1->kVBase / 1000.0; + puV2 = double( double( cabs(with0->Solution->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )] ) ) ) / Bus2->kVBase / 1000.0; + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + break; + case PROFILELL: + { + if ( ( (TDSSCktElement*) PresentCktElement )->Get_NPhases() >= 3 ) + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if ( iphs2 > 3 ) + iphs2 = 1; + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) && ( Bus1->FindIdx( iphs2 ) > 0 ) && ( Bus2->FindIdx( iphs2 ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + /*# with Solution do */ + { + auto with1 = with0->Solution; + puV1 = double( double( cabs( csub( with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )], with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs2 ) )] ) ) ) ) / Bus1->kVBase / 1732.0; + puV2 = double( double( cabs( csub( with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )], with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs2 ) )] ) ) ) ) / Bus2->kVBase / 1732.0; + } + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + } + break; + case PROFILELLALL: + { + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if ( iphs2 > 3 ) + iphs2 = 1; + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) && ( Bus1->FindIdx( iphs2 ) > 0 ) && ( Bus2->FindIdx( iphs2 ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + /*# with Solution do */ + { + auto with1 = with0->Solution; + puV1 = double( double( cabs( csub( with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )], with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs2 ) )] ) ) ) ) / Bus1->kVBase / 1732.0; + puV2 = double( double( cabs( csub(with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )], with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs2 ) )] ) ) ) ) / Bus2->kVBase / 1732.0; + } + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + } + break; + case PROFILELLPRI: + { + if ( Bus1->kVBase > 1.0 ) + for ( int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if ( iphs2 > 3 ) + iphs2 = 1; + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) && ( Bus1->FindIdx( iphs2 ) > 0 ) && ( Bus2->FindIdx( iphs2 ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + /*# with Solution do */ + { + auto with1 = with0->Solution; + puV1 = double( double( cabs( csub( with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )], with1->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs2 ) )] ) ) ) ) / Bus1->kVBase / 1732.0; + puV2 = double( double( cabs( csub(with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )], with1->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs2 ) )] ) ) ) ) / Bus2->kVBase / 1732.0; + } + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + } + break; + default: // plot just the selected phase + iphs = PhasesToPlot; + if ( ( Bus1->FindIdx( iphs ) > 0 ) && ( Bus2->FindIdx( iphs ) > 0 ) ) + { + if ( Bus1->kVBase < 1.0 ) + LineType = 2; + else + LineType = 0; + puV1 = double( double( cabs( with0->Solution->NodeV[Bus1->GetRef( Bus1->FindIdx( iphs ) )] ) ) ) / Bus1->kVBase / 1000.0; + puV2 = double( double( cabs( with0->Solution->NodeV[Bus2->GetRef( Bus2->FindIdx( iphs ) )] ) ) ) / Bus2->kVBase / 1000.0; + WriteNewLine( F, ( (TDSSObject*) PresentCktElement )->get_Name(), Bus1->DistFromMeter, puV1, Bus2->DistFromMeter, puV2, iphs, 2, LineType, 0, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth ); + } + } + } + } + PresentCktElement = (TDSSCktElement*) ActiveEnergyMeter->BranchList->Get_Forward(); + } + iEnergyMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportEventLog( String Filenm ) + // Export the present set of EventStrings + + { + //EventStrings[ActiveActor].SaveToFile( Filenm ); + SaveStrArr2File(&(EventStrings[ActiveActor]), Filenm); + GlobalResult = Filenm; + } + + + void ExportErrorLog( String Filenm ) + // Export the present set of ErrorStrings + + { + //ErrorStrings[ActiveActor].SaveToFile( Filenm ); + SaveStrArr2File(&(EventStrings[ActiveActor]), Filenm); + GlobalResult = Filenm; + } + + + void ExportIncMatrix( String Filenm ) + { + TTextRec F; + int i = 0; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value" ); + for ( int stop = ( with0->IncMat.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr( with0->IncMat.data[i][0] ) + "," + IntToStr( with0->IncMat.data[i][1] ) + "," + IntToStr( with0->IncMat.data[i][2] ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + + + void ExportIncMatrixRows( String Filenm ) + { + TTextRec F; + int i = 0; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "B2N Incidence Matrix Row Names (PDElements)" ); + for ( int stop = ( with0->Inc_Mat_Rows.size() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, with0->Inc_Mat_Rows[i] ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + //------------------------------------------------------------------- + + + + void ExportIncMatrixCols( String Filenm ) + { + TTextRec F; + int i = 0; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "B2N Incidence Matrix Column Names (Buses)" ); + for ( int stop = ( with0->Inc_Mat_Cols.size() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, with0->Inc_Mat_Cols[i] ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + //------------------------------------------------------------------- + + + + void ExportBusLevels( String Filenm ) + { + TTextRec F; + int i = 0; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "B2N Incidence Matrix Column Names (Buses) and their level within the matrix" ); + WriteLn( F, "Bus Name,Bus Level" ); + for ( int stop = ( with0->Inc_Mat_Cols.size() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, with0->Inc_Mat_Cols[i] + "," + IntToStr( with0->Inc_Mat_levels[i] ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + + //------------------------------------------------------------------- + + + + void ExportLaplacian( String Filenm ) + { + TTextRec F; + int i = 0; + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value" ); + for ( int stop = ( with0->Laplacian.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr( with0->Laplacian.data[i][0] ) + "," + IntToStr(with0->Laplacian.data[i][1] ) + "," + IntToStr(with0->Laplacian.data[i][2] ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + //------------------------------------------------------------------- + + + + void ExportZLL( String Filenm ) + { + TTextRec F; + int i = 0; + if ( ADiakoptics ) + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = ActiveCircuit[ActiveActor]->Solution; + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value(Real), Value(Imag)" ); + for ( int stop = ( with0->ZLL.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr(with0->ZLL.CData[i].Row ) + "," + IntToStr(with0->ZLL.CData[i].col ) + "," + to_string( with0->ZLL.CData[i].Value.re ) + "," + to_string( with0->ZLL.CData[i].Value.im ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + } + } + //------------------------------------------------------------------- + + + + void ExportZCC( String Filenm ) + { + TTextRec F; + int i = 0; + if ( ADiakoptics ) + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value(Real), Value(Imag)" ); + for ( int stop = ( with0->ZCC.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr( with0->ZCC.CData[i].Row ) + "," + IntToStr( with0->ZCC.CData[i].col ) + "," + to_string( with0->ZCC.CData[i].Value.re ) + "," + to_string( with0->ZCC.CData[i].Value.im ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + } + } + //------------------------------------------------------------------- + + + + void ExportY4( String Filenm ) + { + TTextRec F; + int i = 0; + if ( ADiakoptics ) + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value(Real), Value(Imag)" ); + for ( int stop = (with0->Y4.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr( with0->Y4.CData[i].Row ) + "," + IntToStr( with0->Y4.CData[i].col ) + + "," + to_string( with0->Y4.CData[i].Value.re ) + "," + to_string( with0->Y4.CData[i].Value.im ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + } + } + //------------------------------------------------------------------- + + + + void ExportC( String Filenm ) + { + TTextRec F; + int i = 0; + if ( ADiakoptics ) + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Row,Col,Value" ); + for ( int stop = ( with0->Contours.NZero() - 1 ), i = 0; i <= stop; i++) + { + WriteLn( F, IntToStr( with0->Contours.CData[i].Row ) + "," + + IntToStr( with0->Contours.CData[i].col ) + + "," + to_string( with0->Contours.CData[i].Value.re ) ); + } + GlobalResult = Filenm; + CloseFile( F ); + } + } + } + } + + //------------------------------------------------------------------- + + + + void ExportVoltagesElements( String Filenm ) + + // Export element voltages, by terminal and node/bus + + { + int MaxNumNodes = 0; + int MaxNumTerminals = 0; + TTextRec F; + int i = 0, j = 0; + TDSSCktElement* pElem; + MaxNumTerminals = 2; + MaxNumNodes = 0; + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while ( pElem != NULL ) + { + MaxNumTerminals = max( MaxNumTerminals, pElem->Get_NTerms() ); + MaxNumNodes = max( MaxNumNodes, pElem->Get_NConds() ); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + /* + MaxNumNodes := 0; + With ActiveCircuit Do + For j := 1 to NumBuses Do + MaxNumNodes := max(MaxNumNodes, Buses^[j].NumNodesThisBus); + */ + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + Write( F, "Element,NumTerminals" ); + + //Write out the header + for ( int stop = MaxNumTerminals, i = 1; i <= stop; i++) + { + Write( F, Format(", Terminal%d", i)); + Write( F, ",NumConductors,NPhases," ); + Write( F, "Bus, BasekV" ); + for (int stop = MaxNumNodes, j = 1; j <= stop; j++) + { + Write(F, Format(", Node%d_%d, Magnitude%d_%d, Angle%d_%d, pu%d_%d", i, j, i, j, i, j, i, j)); + } + } + WriteLn( F ); + + //Go through all the sources + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + pElem = (TDSSCktElement*) with0->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + WriteElementVoltagesExportFile( F, pElem, MaxNumNodes ); + WriteLn( F ); + } + pElem = (TDSSCktElement*) with0->Sources.Get_Next(); + } + + + //Go through all the PDElements + pElem = (TDSSCktElement*) with0->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + WriteElementVoltagesExportFile( F, pElem, MaxNumNodes ); + WriteLn( F ); + } + pElem = (TDSSCktElement*) with0->PDElements.Get_Next(); + } + + + + //Go through all the PCElements + pElem = (TDSSCktElement*) with0->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + WriteElementVoltagesExportFile( F, pElem, MaxNumNodes ); + WriteLn( F ); + } + pElem = (TDSSCktElement*) with0->PCElements.Get_Next(); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportGICMvar( String Filenm ) + { + TTextRec F; + TGICTransformerObj* pElem; + TGICTransformer* GICClass; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + GICClass = (TGICTransformer*) GetDSSClassPtr( "GICTransformer" ); + WriteLn( F, "Bus, Mvar, GIC Amps per phase" ); + pElem = (TGICTransformerObj*) ( (TDSSClass*) GICClass )->ElementList.Get_First() ; + while ( pElem != NULL ) + { + pElem->WriteVarOutputRecord( F, ActiveActor ); + pElem = (TGICTransformerObj*) ((TDSSClass*)GICClass)->ElementList.Get_Next() ; + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportBusReliability( String Filenm ) + { + TTextRec F = {}; + int i = 0; + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Bus, Lambda, Num-Interruptions, Num-Customers, Cust-Interruptions, Duration, Total-Miles" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + { + WriteLn( F, Format("%s, %-.11g, %-.11g, %d, %-.11g, %-.11g, %-.11g", + CheckForBlanks(UpperCase(with0->BusList.Get(i))).c_str(), + with1->BusFltRate, + with1->Bus_Num_Interrupt, + with1->BusTotalNumCustomers, + with1->BusCustInterrupts, + with1->Bus_Int_Duration, + with1->BusTotalMiles)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportBranchReliability( String Filenm ) + { + TTextRec F; + TPDElement* pElem; + double SAIFI = 0.0; + int MaxCustomers = 0; + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Element, Lambda, \"Accumulated-Lambda\", Num-Customers, Total-Customers, Num-Interrupts, Cust-Interruptions, Cust-Durations, Total-Miles, Cust-Miles, SAIFI" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + + // Find Maxcustomers of any PDElement for Duke Recloser siting algorithm + MaxCustomers = 0; + pElem = (TPDElement*) with0->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + /*# with pElem do */ + { + TDSSBus& pBus (*( with0->Buses[pElem->Terminals[pElem->FromTerminal - 1].BusRef - 1] )); + /*# with pBus do */ + if ( pBus.BusTotalNumCustomers > MaxCustomers ) + MaxCustomers = pBus.BusTotalNumCustomers; + } + pElem = (TPDElement*) with0->PDElements.Get_Next(); + } + + + // write report for PDELEMENTS only + pElem = (TPDElement*) with0->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + /*# with pElem do */ + { + TDSSBus& pBus(*( with0->Buses[pElem->Terminals[pElem->FromTerminal - 1].BusRef - 1] )); + /*# with pBus do */ + if ( pBus.BusTotalNumCustomers > 0 ) + SAIFI = double( pBus.BusCustInterrupts ) / pBus.BusTotalNumCustomers; + else + SAIFI = 0.0; + WriteLn( F, Format("%s.%s, %-.11g, %-.11g, %d, %d, %-.11g, %-.11g, %-.11g, %-.11g, %-.11g, %-.11g", + pElem->ParentClass->get_myClass_name().c_str(), pElem->get_Name().c_str(), pElem->BranchFltRate, pElem->AccumulatedBrFltRate, + pElem->BranchNumCustomers, pElem->BranchTotalCustomers, pBus.Bus_Num_Interrupt, + pElem->BranchTotalCustomers * pBus.Bus_Num_Interrupt, pBus.BusCustDurations, + pElem->AccumulatedMilesDownStream, (MaxCustomers - pElem->BranchTotalCustomers) * pElem->AccumulatedMilesDownStream, SAIFI)); + } + pElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportNodeNames( String Filenm ) + { + TTextRec F; + int i = 0; + int j = 0; + + String BusName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Node_Name" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + BusName = with0->BusList.Get( i ); + /*# with Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + for ( int stop = with1->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + WriteLn( F, Format("%s.%d ", BusName.c_str(), with1->GetNum(j))); + } + } + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int TapPosition( const TTransfObj* Transformer, int iWind ) + + /*Assumes 0 is 1.0 per unit tap*/ + { + int result = 0; + /*# with Transformer do */ + auto with0 = Transformer; + result = Round( double( (with0->Get_PresentTap(iWind,ActiveActor) - double( (with0->Get_MaxTap(iWind) + with0->Get_MinTap(iWind) ) ) / 2.0 ) ) / with0->Get_TapIncrement(iWind) ); + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ExportTaps( String Filenm ) + { + TTextRec F; + int iWind = 0; + TRegControlObj* pReg; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + WriteLn( F, "Name, Tap, Min, Max, Step, Position" ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + pReg = (TRegControlObj*) with0->RegControls.Get_First(); + while ( pReg != NULL ) + { + /*# with pReg.Transformer do */ + { + auto with1 = pReg->Get_Transformer(); + iWind = pReg->Get_Winding(); + Write( F, with1->get_Name() ); + WriteLn( F, Format(", %8.5f, %8.5f, %8.5f, %8.5f, %d", with1->Get_PresentTap(iWind,ActiveActor), with1->Get_MinTap(iWind), + with1->Get_MaxTap(iWind), with1->Get_TapIncrement(iWind), TapPosition((pReg->Get_Transformer()), iWind))); + } + pReg = (TRegControlObj*) with0->RegControls.Get_Next(); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportResult( String Filenm ) + { + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + ParserVars->Lookup( "@result" ); + WriteLn( F, ParserVars->Get_Value() ); + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void ExportYNodeList( String Filenm ) + { + int i = 0; + + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + if ( ActiveCircuit[ActiveActor] != NULL ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + /*# with MapNodeToBus^[i] do */ + { + auto with1 = with0->MapNodeToBus[i - 1]; + WriteLn( F, Format("\"%s.%-d\"", UpperCase(with0->BusList.Get(with1.BusRef)).c_str(), with1.NodeNum)); + } + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + + void ExportYVoltages( String Filenm ) + { + int i = 0; + + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + if ( ActiveCircuit[ActiveActor] != NULL ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + /*# with Solution->NodeV^[i] do */ + auto with1 = with0->Solution->NodeV[i]; + WriteLn( F, Format(" % 10.6g, % 10.6g", with1.re, with1.im)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + + void ExportYCurrents( String Filenm ) + { + int i = 0; + + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + if ( ActiveCircuit[ActiveActor] != NULL ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + complex with1 = cmplx(0, 0); + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + with1 = with0->Solution->Currents[i]; + WriteLn( F, Format(" % 10.6g, % 10.6g", with1.re, with1.im)); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile(F); + } + catch (...) + { + // + } + } + + + void ExportSections( String Filenm, TEnergyMeterObj pMeter ) + { + TEnergyMeterObj* MyMeterPtr; + int iMeter = 0, i = 0; + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + // Write Header + WriteLn( F, "Meter, SectionID, SeqIndex, DeviceType, NumCustomers, NumBranches, AvgRepairHrs, TotalDownlineCust, SectFaultRate, SumFltRatesXRepairHrs, SumBranchFltRates, HeadBranch " ); +// if (( &pMeter != NULL ) ) // always evaluates to true + if ( true ) + // If a meter is specified, export that meter only + /*# with pMeter do */ + { + auto with0 = pMeter; + for ( int stop = with0.SectionCount, i = 1; i <= stop; i++) + /*# with FeederSections^[i] do */ + { + auto& with1 = with0.FeederSections[i]; + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*) (with0.SequenceList->Get(with1.SeqIndex ) )); + WriteLn( F, with0.get_Name() + + Format( ", %d, %d, %s, %d, %d, %-.6g, %d, %-.6g, %-.6g, %-.6g, %s", + i, + with1.SeqIndex, + GetOCPDeviceTypeString(with1.OCPDeviceType ).c_str(), + with1.NCustomers, + with1.NBranches, + with1.AverageRepairTime, + with1.TotalCustomers, + with1.SectFaultRate, + with1.SumFltRatesXRepairHrs, + with1.SumBranchFltRates ) + + FullName( ActiveCircuit[ActiveActor]->get_FActiveCktElement()).c_str() ); + } + } + } + else // export sections for all meters + { + iMeter = EnergyMeterClass[ActiveActor]->Get_First(); + while ( iMeter > 0 ) + { + MyMeterPtr = (TEnergyMeterObj*) EnergyMeterClass[ActiveActor]->GetActiveObj(); + /*# with MyMeterPtr do */ + { + for ( int stop = MyMeterPtr->SectionCount, i = 1; i <= stop; i++) + /*# with FeederSections^[i] do */ + { + auto& with1 = MyMeterPtr->FeederSections[i]; + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)( MyMeterPtr->SequenceList->Get( with1.SeqIndex ) )); + WriteLn( F, MyMeterPtr->get_Name() + + Format( ", %d, %d, %s, %d, %d, %-.6g, %d, %-.6g, %-.6g, %-.6g, %s", + i, with1.SeqIndex, + GetOCPDeviceTypeString(with1.OCPDeviceType ).c_str(), + with1.NCustomers, + with1.NBranches, + with1.AverageRepairTime, + with1.TotalCustomers, + with1.SectFaultRate, + with1.SumFltRatesXRepairHrs, + with1.SumBranchFltRates) + + FullName( ActiveCircuit[ActiveActor]->get_FActiveCktElement() ).c_str() ); + } + } + iMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + } + } + } + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + } + catch (...) + { + // + } + } + +}// Namespace ExportResults + + + + + + diff --git a/OpenDSSC/Common/ExportResults.h b/OpenDSSC/Common/ExportResults.h new file mode 100644 index 0000000..6862d44 --- /dev/null +++ b/OpenDSSC/Common/ExportResults.h @@ -0,0 +1,99 @@ +#ifndef ExportResultsH +#define ExportResultsH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + 2-25-00 Created + 5-30-00 Added code for handling positive sequence mode +*/ + + +//#include + +#include "EnergyMeter.h" +#include "XYcurve.h" + +namespace ExportResults +{ + + + void ExportVoltages(String Filenm); + void ExportSeqVoltages(String Filenm); + void ExportCurrents(String Filenm); + void ExportEstimation(String Filenm); + void ExportSeqCurrents(String Filenm); + void ExportPowers(String Filenm, int Opt); + void ExportPbyphase(String Filenm, int Opt); + void ExportSeqPowers(String Filenm, int Opt); + void ExportFaultStudy(String Filenm); + void ExportMeters(String Filenm); + void ExportGenMeters(String Filenm); + void ExportPVSystemMeters(String Filenm); + //Procedure ExportPVSystem2Meters(FileNm:String); + + void ExportStorageMeters(String Filenm); + //Procedure ExportStorage2Meters(FileNm:String); + + void ExportLoads(String Filenm); + void ExportCapacity(String Filenm); + void ExportOverloads(String Filenm); + void ExportUnserved(String Filenm, bool UE_Only); + void ExportYprim(String Filenm); + void ExportY(String Filenm, bool TripletOpt); + void ExportSeqZ(String Filenm); + void ExportBusCoords(String Filenm); + void ExportLosses(String Filenm); + void ExportUuids(String Filenm); + void ExportCounts(String Filenm); + void ExportSummary(String Filenm); + void ExportProfile(String Filenm, int PhasesToPlot); + void ExportEventLog(String Filenm); + void ExportVoltagesElements(String Filenm); + void ExportGICMvar(String Filenm); + void ExportBusReliability(String Filenm); + void ExportBranchReliability(String Filenm); + void ExportNodeNames(String Filenm); + void ExportTaps(String Filenm); + void ExportNodeOrder(String Filenm); + void ExportElemCurrents(String Filenm); + void ExportElemVoltages(String Filenm); + void ExportElemPowers(String Filenm); + void ExportResult(String Filenm); + void ExportYNodeList(String Filenm); + void ExportYVoltages(String Filenm); + void ExportYCurrents(String Filenm); + void ExportSections(String Filenm, TEnergyMeterObj pMeter); + void ExportErrorLog(String Filenm); + void ExportIncMatrix(String Filenm); + void ExportIncMatrixRows(String Filenm); + void ExportIncMatrixCols(String Filenm); + void ExportBusLevels(String Filenm); + void ExportLaplacian(String Filenm); + void ExportZLL(String Filenm); + void ExportZCC(String Filenm); + void ExportY4(String Filenm); + void ExportC(String Filenm); + void ExportJacobian(String Filenm); + void ExportdeltaF(String Filenm); + void ExportdeltaZ(String Filenm); + +}// namespace ExportResults + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExportResults; +#endif + +#endif // ExportResultsH + + + + + + + + diff --git a/OpenDSSC/Common/Feeder.cpp b/OpenDSSC/Common/Feeder.cpp new file mode 100644 index 0000000..214dcd7 --- /dev/null +++ b/OpenDSSC/Common/Feeder.cpp @@ -0,0 +1,453 @@ + +#pragma hdrstop + +#include "Feeder.h" + + + +#include "ParserDel.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Sysutils.h" +#include "Command.h" +#include "EnergyMeter.h" +#include "PDElement.h" + +#include "System.h" + + + + +namespace Feeder +{ + TFeederObj* ActiveFeederObj = NULL; + int NumPropsThisClass = 0; + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + TFeeder::TFeeder() // Creates superstructure for all Line objects + :inherited() + { + Class_Name = "Feeder"; + DSSClassType = FEEDER_ELEMENT; /*+ PC_ELEMENT; */ // add to PCElement list + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + TFeeder::~TFeeder() + { + // ElementList and CommandList freed in inherited destroy + // todo check: inherited::Destroy; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + void TFeeder::DefineProperties() + { + NumPropsThisClass = 0; + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Can't Think of any properties we want the user to be able to set + + // Define Property names + // PropertyName[1] := 'bus1'; + + // define Property help values + // PropertyHelp[1] := 'Name of bus to which source is connected.'+CRLF+'bus1=busname'+CRLF+'bus1=busname.1.2.3'; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + int TFeeder::NewObject(const String ObjName) + + // Called from EnergyMeter + + { + int result = 0; + TFeederObj* Obj = NULL; + //Make a new Feeder object + // Get_First() see if this one already exists. If so, just reinitialize + Obj = (TFeederObj*) Find(ObjName); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + if (Obj != NULL) + { + with0->Set_ActiveCktElement(Obj); + result = 0; + } + else + { + with0->Set_ActiveCktElement(new TFeederObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + ActiveCircuit[ActiveActor]->AddCktElement(result); + // done here because feeder objects are instantiated from energy meters + } + } + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + int TFeeder::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName, Param; + // continue parsing with contents of Parser + ActiveFeederObj = (TFeederObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveFeederObj); + result = 0; + /*# with ActiveFeederObj do */ + { + auto with1 = ActiveFeederObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ParamPointer++; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with1->Set_PropertyValue(ParamPointer, Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Object \"" + Class_Name + "." + get_myClass_name() + "\"", 630); + break; + default: + ClassEdit(ActiveFeederObj, ParamPointer - NumPropsThisClass); + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + ActiveFeederObj->RecalcElementData(ActorID); + with1->Set_YprimInvalid(ActorID,true); + } + return result; + } + + //---------------------------------------------------------------------------- + + + + int TFeeder::MakeLike(const String OtherFeederName) + { + int result = 0; + TFeederObj* OtherFeeder = NULL; + int i = 0; + result = 0; + /*See if we can find this name in the present collection*/ + OtherFeeder = (TFeederObj*) Find(OtherFeederName); + if (OtherFeeder != NULL) + /*# with ActiveFeederObj do */ + { + auto with0 = ActiveFeederObj; + if ( ( ( TDSSCktElement*) with0 )->Fnphases != ( (TDSSCktElement*) OtherFeeder )->Fnphases) + { + ((TDSSCktElement*)with0)->Set_NPhases(((TDSSCktElement*)OtherFeeder)->Fnphases); + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)OtherFeeder)->Fnphases); // Forces reallocation of terminal stuff + ((TDSSCktElement*)with0)->Yorder = ((TDSSCktElement*)OtherFeeder)->Fnconds * ((TDSSCktElement*)OtherFeeder)->Fnterms; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActiveActor,true); + } + + // Put properties to copy here + ClassMakeLike(OtherFeeder); // set spectrum, base frequency + for (int stop = ( (TDSSObject*) with0 )->ParentClass->NumProperties, i = 1; i <= stop; i++) + ((TDSSObject*)with0)->Set_PropertyValue(i, ((TDSSObject*)OtherFeeder)->Get_PropertyValue(i)); + result = 1; + } + else + DoSimpleMsg(String("Error in Feeder MakeLike: \"") + OtherFeederName + "\" Not Found.", 631); + return result; + } + + //---------------------------------------------------------------------------- + + + + int TFeeder::Init(int Handle, int ActorID) + { + int result = 0; + DoSimpleMsg("Need to implement TFeeder.Init", -1); + result = 0; + return result; + } + + //---------------------------------------------------------------------------- + + + + TFeederObj::TFeederObj(TDSSClass* ParClass, const String MeterName) + : inherited(ParClass), + FromTerminalOffset(0), + IsSynched(false) + { + + Set_Name(LowerCase(MeterName)); + DSSObjType = ParClass->DSSClassType; // This will be a current source (PCElement) + sequenceList = TPointerList(50); + ShuntList = TPointerList(50); + IsSynched = false; + + // Bus names and Nphases, etc are set up from EnergyMeter + + // Ready to rock 'n roll + RecalcElementData(ActiveActor); + InitPropertyValues(0); + } + + + //---------------------------------------------------------------------------- + + + + TFeederObj::~TFeederObj() + { + // todo check: inherited::Destroy; + } + + + void TFeederObj::InitializeFeeder( TCktTree BranchList, int ActorID) + { + int i = 0, bref = 0; + TDSSCktElement* pElement; + TDSSCktElement* pShunt; + sequenceList.Clear(); // Get rid of any previous definitions + ShuntList.Clear(); + IsSynched = false; + // Now set up Feeder terminals and BusRef to match the from node of the first branch + // if (&BranchList != NULL) // original Delphi code was "If BranchList <> Nil Then Begin", but here BranchList is a copy passed via the stack, so this pointer is always non-NULL + { + RootElement = *( (TDSSCktElement*) BranchList.Get_First() ); + Set_NPhases(RootElement.Get_NPhases()); // Take care of allocating Terminal stuff + Fnconds = RootElement.Get_NConds(); + Set_NTerms(1); + Yorder = Fnterms * Fnconds; + Terminals[0].BusRef = BranchList.PresentBranch->FromBusReference; + SetBus(1, RootElement.GetBus(BranchList.PresentBranch->FromTerminal)); // set bus name same as first element + FromTerminalOffset = (BranchList.PresentBranch->FromTerminal - 1) * Fnconds; + SetNodeRef(1, *(pIntegerArray*) & RootElement.NodeRef[FromTerminalOffset]); + + // Build The Sequence List and ShuntList + pElement = &RootElement; + while (pElement != NULL) + { + sequenceList.Add(pElement); + + // Mark all the To buses for this branch as radial buses + BranchList.PresentBranch->ResetToBusList(); // reset pointer to first to bus + for (int stop = pElement->Get_NTerms() - 1, i = 1; i <= stop; i++) + { + bref = BranchList.PresentBranch->Get_ToBusReference(); // each call pops off a new one + if (bref > 0) + ActiveCircuit[ActorID]->Buses[bref - 1]->IsRadialBus = true; + } + pShunt = (TDSSCktElement*) BranchList.PresentBranch->Get_FirstObject(); + while (pShunt != NULL) + { + ShuntList.Add(pShunt); + pShunt = (TDSSCktElement*) BranchList.PresentBranch->Get_NextObject(); + } + pElement = (TDSSCktElement*) BranchList.Get_Forward(); + } + IsSynched = true; + SetCktElementFeederFlags(true); + } + } + + //---------------------------------------------------------------------------- + + + + void TFeederObj::RecalcElementData(int ActorID) + { + + /*Nothing to Do?? - Maybe remake bus lists*/ + } + + //---------------------------------------------------------------------------- + + + + void TFeederObj::CalcYPrim(int ActorID) + { + + // For now, YPrim is null + + // Build only YPrim Series + if (Get_YprimInvalid(ActorID, 0)) + { + if (YPrim_Series != NULL) + delete YPrim_Series; // YPrim_Series->~TcMatrix(); + YPrim_Series = new TcMatrix(Yorder); + if (YPrim != NULL) + delete YPrim; // YPrim->~TcMatrix(); + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + + + /*Yprim = 0 for Ideal Current Source; just leave it zeroed*/ + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); + } + + + int TFeederObj::InjCurrents(int ActorID) + + /*Sum Currents directly into solution array*/ + + /* This is where we do the backward Sweep - computing the currents from the present voltages*/ + { + int result = 0; + + + // old implementation deleted. + result = 0; + return result; + } + + + void TFeederObj::GetCurrents(pComplexArray Curr, int ActorID) + + /*Total currents into a feeder which are equal to the currents into the first element*/ + /*Return the currents in the From terminal of the first element in the sequence list*/ + { + int i = 0; + // cBuffer:pComplexArray; + // pElem :TCktElement; + + // If the feeder exists and we switch away from radial solution we don' want + // to report a current + // Do this only if doing a radial solution + /* If ActiveCircuit[ActiveActor].RadialSolution Then + Begin + TRY + pElem := TCktElement(SequenceList.Get(1)); + Getmem(cBuffer, Sizeof(cBuffer^[1])*pElem.Yorder ); + pElem.GetCurrents(cBuffer); // get all currents in first element in sequence list + + // Return only FROM terminal current + FOR i := 1 TO Yorder DO Curr^[i] := cBuffer^[i+FromTerminalOffset]; + + Freemem(cBuffer); // dump temp buffer + + EXCEPT + On E: Exception + Do DoErrorMsg(('GetCurrents for Feeder Element: ' + Name + '.'), E.Message, + 'Inadequate storage allotted for circuit element?', 632); + End; + End Else + */ + for (int stop = Yorder, i = 1; i <= stop; i++) + (Curr)[i - 1] = CZero; // no contribution if not radial solution + } + + void TFeederObj::GetInjCurrents(pComplexArray Curr, int ActorID) + + /*Fill Up an array of injection currents*/ + + /*Only thing this is used for is for GetCurrents. Ignore for Feeder*/ + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + + /***** Do Nothing!*/ + } + } + + + void TFeederObj::DumpProperties(Textfile& F, bool Complete) + { + inherited::DumpProperties(F, Complete); + + /*Do Not dump any properties for a Feeder unless Debug*/ + /* With ParentClass Do + For i := 1 to NumProperties Do + Begin + Writeln(F,'~ ',PropertyName^[i],'=',PropertyValue[i]); + End; + */ + if (Complete) + { + /*Dump sequence lists, etc here...*/ + WriteLn(F); + WriteLn(F); + } + } + + + void TFeederObj::InitPropertyValues(int ArrayOffset) + { + + // PropertyValue[1] := GetBus(1); + inherited::InitPropertyValues(NumPropsThisClass); + } + + + void TFeederObj::MakePosSequence(int ActorID) + { + /* Do Nothing + If Fnphases>1 Then + Begin + Parser.CmdString := 'phases=1'; + Edit; + End; + inherited; + */ + } + + + void TFeederObj::SetCktElementFeederFlags(bool Value) + { + int i = 0; + for (int stop = ShuntList.get_myNumList(), i = 1; i <= stop; i++) + { + ( (TDSSCktElement*) ShuntList.Get(i) )->IsPartofFeeder = Value; + } + for (int stop = sequenceList.get_myNumList(), i = 1; i <= stop; i++) + { + ( (TDSSCktElement*) sequenceList.Get(i) )->IsPartofFeeder = Value; + } + } + +}// namespace Feeder + + + + + + + diff --git a/OpenDSSC/Common/Feeder.h b/OpenDSSC/Common/Feeder.h new file mode 100644 index 0000000..0f88e9b --- /dev/null +++ b/OpenDSSC/Common/Feeder.h @@ -0,0 +1,116 @@ +#ifndef FeederH +#define FeederH + /* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Feeder Class + + User cannot instantiate this object. Feeders are created on the fly when + a radial system is specified. Feeders are created from Energymeters and are + given the same name. + + + 6-24-04 Created from Isource (a simple PC Element) + 8-13-2006 Radial circuit solution removed + + Feeders get created from energy meters if Radial is set to yes and meter zones + are already computed. If Radial=Yes and the meterzones are reset, then the feeders + are redefined. If Radial is subsequently set to NO or a solution mode is used + that doesn't utilize feeders, the get currents routines will not do anything. + + Feeders cannot be re-enabled unless the energymeter object allows them to be. + + Feeders are not saved. This is implicit with the Energymeter saving. + +*/ + + +//#include + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "CktElement.h" +#include "CktTree.h" + +namespace Feeder +{ + + //class TFeeder; + //class TFeederObj; + + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + class TFeeder : public TPCClass { + public: + typedef TPCClass inherited; + friend class TFeederObj; +// private: + protected: + void DefineProperties(); + virtual int MakeLike(const String OtherFeederName); + public: + TFeeder(); + virtual ~TFeeder(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + }; + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + using namespace DSSClass; + + class TFeederObj : public PCElement::TPCElement { + typedef TPCElement inherited; + friend class TFeeder; + public: + // private: + PointerList::TPointerList sequenceList, ShuntList; + TDSSCktElement RootElement; + int FromTerminalOffset; + public: + bool IsSynched; + void InitializeFeeder(TCktTree BranchList, int ActorID); + void SetCktElementFeederFlags(bool Value); + TFeederObj(DSSClass::TDSSClass* ParClass, const String MeterName); + virtual ~TFeederObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID) // Make a positive Sequence Model - N/A + ; + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(pComplexArray Curr, int ActorID); + virtual void GetCurrents(pComplexArray Curr, int ActorID); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(Textfile& F, bool Complete); + }; + + + extern TFeederObj* ActiveFeederObj; + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Feeder; +#endif + +#endif // FeederH + + + + + + + + diff --git a/OpenDSSC/Common/GraphProperties.h b/OpenDSSC/Common/GraphProperties.h new file mode 100644 index 0000000..cf9b5c5 --- /dev/null +++ b/OpenDSSC/Common/GraphProperties.h @@ -0,0 +1,41 @@ +#ifndef GraphPropertiesH +#define GraphPropertiesH + + +#include + +#include +#include "rchart.h" + + + +struct TDSSGraphProperties; + + + + +// GridStyleType = (gsNone, gsPoints, gsVertLines, gsHorizLines, gsLines, gsHorizDotLines, gsVertDotLines, gsDotLines); + +#pragma pack(push, 1) +struct TDSSGraphProperties { + double Xmin; + double Xmax; + double Ymin; + double YMax; + TColor ChartColor; + TColor WindColor; + bool Isometric; + GridStyleType GridStyle; +}; +#pragma pack(pop) + + +#endif // GraphPropertiesH + + + + + + + + diff --git a/OpenDSSC/Common/MeTIS_Exec.cpp b/OpenDSSC/Common/MeTIS_Exec.cpp new file mode 100644 index 0000000..6daaf8c --- /dev/null +++ b/OpenDSSC/Common/MeTIS_Exec.cpp @@ -0,0 +1,251 @@ + +#pragma hdrstop + +#include "MeTIS_Exec.h" + +namespace METIS_Exec +{ + +/* int max(const int A, const int b) + { + int result = 0; + if (A > b) + result = A; + else + result = b; + return result; + }*/ + + /* TFileSearchReplace */ + + + TFileSearchReplace::TFileSearchReplace(const String AFileName) + { + // inherited::Create(); + } + + + TFileSearchReplace::~TFileSearchReplace() + { +/* String tmpFileName; + if ((FtmpFile != NULL)) + tmpFileName = FtmpFile.Filename; + delete FtmpFile; + FtmpFile = NULL; + delete FSourceFile; + FSourceFile = NULL; + TFile.Delete(tmpFileName);*/ + // todo check: inherited::Destroy(); + } + +/* + void TFileSearchReplace::CopyPreamble() + { + int PreambleSize = 0; + TBytes PreambleBuf; + // Copy Encoding preamble + SetLength(PreambleBuf, 100); + FSourceFile.Read(PreambleBuf, Length(PreambleBuf)); + FSourceFile.Seek(0, soBeginning); + PreambleSize = TEncoding.GetBufferEncoding(PreambleBuf, FEncoding); + if (PreambleSize != 0) + FtmpFile.CopyFrom(FSourceFile, PreambleSize); + } + + + int TFileSearchReplace::GetLastIndex(const String str, const String SubStr, TReplaceFlags& ReplaceFlags) + { + int result = 0; + int i = 0; + String tmpSubStr, tmpStr; + if (!(ReplaceFlags.Contains(rfIgnoreCase))) + { + i = str.Pos(SubStr); + result = i; + while (i > 0) + { + i = PosEx(SubStr, str, i + 1); + if (i > 0) + result = i; + } + if (result > 0) + result += SubStr.Length() - 1; + } + else + { + tmpStr = UpperCase(str); + tmpSubStr = UpperCase(SubStr); + i = tmpStr.Pos(tmpSubStr); + result = i; + while (i > 0) + { + i = PosEx(tmpSubStr, tmpStr, i + 1); + if (i > 0) + result = i; + } + if (result > 0) + result += tmpSubStr.Length() - 1; + } + return result; + } + + + void TFileSearchReplace::ParseBuffer(TBytes Buf, bool& IsReplaced, const String& AFrom, const String& ATo, TReplaceFlags& ReplaceFlags) + { + int i = 0; + int ReadedBufLen = 0; + String BufStr; + TBytes DestBytes; + int LastIndex = 0; + if (IsReplaced && (!(ReplaceFlags.Contains(rfReplaceAll)))) + { + FtmpFile.Write(Buf, Length(Buf)); + return; + } + + // 1. Get chars from buffer + ReadedBufLen = 0; + for (int stop = 0, i = Length(Buf); i >= stop; i--) + if (FEncoding.GetCharCount(Buf, 0, i) != 0) + { + ReadedBufLen = i; + Break; + } + if (ReadedBufLen == 0) + throw EEncodingError.Create("Cant convert bytes to str"); + FSourceFile.Seek(ReadedBufLen - Length(Buf), soCurrent); + BufStr = FEncoding.GetString(Buf, 0, ReadedBufLen); + if (ReplaceFlags.Contains(rfIgnoreCase)) + IsReplaced = ContainsText(BufStr, AFrom); + else + IsReplaced = ContainsStr(BufStr, AFrom); + if (IsReplaced) + { + LastIndex = GetLastIndex(BufStr, AFrom, ReplaceFlags); + LastIndex = max(LastIndex, BufStr.Length() - AFrom.Length() + 1); + } + else + LastIndex = BufStr.Length(); + BufStr.SetLength(LastIndex); + FSourceFile.Seek(FEncoding.GetByteCount(BufStr) - ReadedBufLen, soCurrent); + BufStr = stringreplace(BufStr, AFrom, ATo, ReplaceFlags); + DestBytes = FEncoding.GetBytes(BufStr); + FtmpFile.Write(DestBytes, Length(DestBytes)); + } + */ + + void TFileSearchReplace::Replace(const String AFrom, const String ATo, TReplaceFlags ReplaceFlags) + { +/* __int64 SourceSize = 0; + TBytes Buf; + int BufLen = 0; + bool bReplaced = false; + FSourceFile.Seek(0, soBeginning); + FtmpFile.Size = 0; + CopyPreamble(); + SourceSize = FSourceFile.Size; + BufLen = max(FEncoding.GetByteCount(AFrom) * 5, 2048); + BufLen = max(FEncoding.GetByteCount(ATo) * 5, BufLen); + SetLength(Buf, BufLen); + bReplaced = false; + while (FSourceFile.Position < SourceSize) + { + BufLen = FSourceFile.Read(Buf, Length(Buf)); + SetLength(Buf, BufLen); + ParseBuffer(Buf, bReplaced, AFrom, ATo, ReplaceFlags); + } + FSourceFile.Size = 0; + FSourceFile.CopyFrom(FtmpFile, 0);*/ + } + + String GetNumEdges(String MeTISSrc) + { +/* + String result; + int i = 0, j = 0; + const int SOffset = 13; + i = MeTISSrc.Pos("I only found "); + j = MeTISSrc.Pos(" edges in the file."); + result = MeTISSrc.SubString((i + SOffset), (j - (i + SOffset)));// Gets the # of edges proposed by MeTIS + return result; +*/ + return ""; + } + + + String RunMeTIS(String DosApp) + { +/* + String result; + const int READ_BUFFER_SIZE = 2400; + TSecurityAttributes Security; + THandle readableEndOfPipe, writeableEndOfPipe; + TStartUpInfo start; + TProcessInformation ProcessInfo; + char* Buffer = NULL; + DWORD BytesRead = 0; + DWORD AppRunning = 0; + String AppReturn; + Security.nLength = sizeof(TSecurityAttributes); + Security.bInheritHandle = true; + Security.lpSecurityDescriptor = NULL; + if (CreatePipe(readableEndOfPipe, writeableEndOfPipe, &Security, 0)) + { + Buffer = AllocMem(READ_BUFFER_SIZE + 1); + FillChar(start, sizeof(start), '\x00'); + start.cb = sizeof(start); + // Set up members of the STARTUPINFO structure. + // This structure specifies the STDIN and STDOUT handles for redirection. + // - Redirect the output and error to the writeable end of our pipe. + // - We must still supply a valid StdInput handle (because we used STARTF_USESTDHANDLES to swear that all three handles will be valid) + start.dwFlags = start.dwFlags | STARTF_USESTDHANDLES; + start.hStdInput = GetStdHandle(STD_INPUT_HANDLE); //we're not redirecting stdInput; but we still have to give it a valid handle + start.hStdOutput = writeableEndOfPipe; //we give the writeable end of the pipe to the child process; we read from the readable end + start.hStdError = writeableEndOfPipe; + + //We can also choose to say that the wShowWindow member contains a value. + //In our case we want to force the console window to be hidden. + start.dwFlags = start.dwFlags + STARTF_USESHOWWINDOW; + start.wShowWindow = SW_HIDE; + + // Don't forget to set up members of the PROCESS_INFORMATION structure. + ProcessInfo = Default(TProcessInformation); + + //WARNING: The unicode version of CreateProcess (CreateProcessW) can modify the command-line "DosApp" string. + //Therefore "DosApp" cannot be a pointer to read-only memory, or an ACCESS_VIOLATION will occur. + //We can ensure it's not read-only with the RTL function: UniqueString + UniqueString(DosApp); + if (CreateProcess(NULL, DosApp.c_str(), NULL, NULL, true, NORMAL_PRIORITY_CLASS, NULL, NULL, start, ProcessInfo)) + { + //Wait for the application to terminate, as it writes it's output to the pipe. + //WARNING: If the console app outputs more than 2400 bytes (ReadBuffer), + //it will block on writing to the pipe and *never* close. + do + { + AppRunning = WaitForSingleObject(ProcessInfo.hProcess, 100); + } while (!(AppRunning != WAIT_TIMEOUT)); + //Read the contents of the pipe out of the readable end + //WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return + do + { + BytesRead = 0; + ReadFile(readableEndOfPipe, Buffer[0], READ_BUFFER_SIZE, BytesRead, NULL); + Buffer[BytesRead] = '\x00'; + OemToAnsi(Buffer, Buffer); + result = result + ((String)Buffer); + } while (!(BytesRead < READ_BUFFER_SIZE)); + } + else + result = "**Error**"; + free(Buffer); + CloseHandle(ProcessInfo.hProcess); + CloseHandle(ProcessInfo.hThread); + CloseHandle(readableEndOfPipe); + CloseHandle(writeableEndOfPipe); + } + return result; +*/ + return ""; + } +} + diff --git a/OpenDSSC/Common/MeTIS_Exec.h b/OpenDSSC/Common/MeTIS_Exec.h new file mode 100644 index 0000000..2bb78e4 --- /dev/null +++ b/OpenDSSC/Common/MeTIS_Exec.h @@ -0,0 +1,45 @@ +#ifndef MeTIS_ExecH +#define MeTIS_ExecH + + +#include "System.h" +#include "Sysutils.h" + +namespace METIS_Exec +{ + + + + class TFileSearchReplace : public TObject { + typedef TObject inherited; + public: + // private: + System::file FSourceFile; + System::file FtmpFile; + //TEncoding FEncoding; + public: + TFileSearchReplace(const String AFileName); + virtual ~TFileSearchReplace(); + void Replace(const String AFrom, const String ATo, TReplaceFlags ReplaceFlags); + + }; + + + String RunMeTIS(String DosApp); + String GetNumEdges(String MeTISSrc); + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace METIS_Exec; +#endif + +#endif // MeTIS_ExecH + + + + + + + + diff --git a/OpenDSSC/Common/Notes.cpp b/OpenDSSC/Common/Notes.cpp new file mode 100644 index 0000000..e6729d0 --- /dev/null +++ b/OpenDSSC/Common/Notes.cpp @@ -0,0 +1,776 @@ + +#include +#pragma hdrstop + +#include "../Common/Notes.h" + + + +/* +TO DO: + + * = done + + *1. Fix so changing solution modes that requires changing the System Y matrix + causes the Y matrix to be rebuilt. + *2. Add capacitor. + *3. Add Harmonic source injection to the general load model + 4. Add a specific harmonic source. + *5. Create a monitor mode that takes only magnitudes. + 6. Create a monitor mode that does statistics on the fly. + 7. Test other transformer connections. + *8. Add parsing of winding quantities as arrays Buses="HBus LBus Tbus" etc. + *9. Fix PCElement GetCurrent routine so that after a Solve Direct, it doesn't use inj currents. + Add a LastSolutionType variable. + *10. (Done this in conjunction with 14 - bus lists get rebuilt if changes) + Make Bus reference a usage count so that if bus.node is deleted from the network, + it is eliminated from the matrix. OR, add a small conductance to diagonal of the + System Y so that it will always solve although there is nothing connected to the node. + *11. Consolidate the Mode command interpreter in Solution and Exec into one function in Exec?, + *12. Add enable/disable property to all circuit elements. + *13. Code for opening and closing terminal switches? + *14. Handle reorder of system nodelist if a circuit element is disabled (or any other + change to the terminal connections.) + 15. Add persistence - would make a great OO circuit database. + *16. Check power factor designation on load to see if leading (-) will work. + *16a. Make sure that the power factor is interpreted correctly for negative kW. + 17. Resolve how multiple circuits will be handled. 2nd, 3rd, circuits are created with + a source with the same name as the first circuit. Edit command can find only first. + Also, some circuits might share elements with another circuit. + *18. help panel showing properties in a device's command list (Create a new form and let it + float freely). + *19. Add properties for symmetrical component quantities. + *20. Change syntax parser to allow default Edit command. + *21. Add Select to Interface. + *22. Check consistency of voltage definition between devices + 23. Revise DSS design to have user-written stuff implemented as COM instead of DLL. + 24. Look into Aggregation for ActiveX. + *25. Add UE-type calculations; Return in interface. + *26. Add EDC-like generator model that is negative load following load curves or dispatched + 27. Current report prints a bogus number for single-phase loads. + ?28. The Disable/Enable and Open/Close commands do not differentiate between objects of the same name in different ckts. + 29. Problem with open terminal logic with delta-connected loads. IF open 2 phases, leaves 1 by 1 which is not correct. + *30. Monitor is not searching for full element name -- neither is Meter + *31. Monitor defaults to 3-phases, not the number of phases of the element. + *32. Set Yprim in Monitor to 1.e-12 on diagonal so it won't cause problem when misapplied + *33. Check Vsource short circuit data for correct computation. + *34. Add history window or file from which you can cut and paste commands or select and + execute commands. + *35. Monitor not indexing the currents right on transformers if not on the first terminal. + *36. Add Cancel button to simple error message and abort redirects and compile commands + 37. Repair time should be part of base ckt element. + 38. check the open terminal logic of loads + 39. Save circuit will not save circuit over top of existing one. + 40. Finish Equivalent model + 41. Finish Sensor model for DSE + 42. Connect Loadloss property on transformer to %R property + 43. Implement NoLoadLoss property on transformer to insert a shunt resistance across a winding (1?) + +LOG: + +7-2-98: Notes unit added. Transformer was completed night before. Short circuit + testing done for 3-phase transformer. Need to test other configurations. Solve + Direct mode added. However, it was noted that there was no flag/logic to figure + out that the system Y needed to be rebuilt +7-4-98: Modified transformer to allow entry of connections and buses as arrays. +7-6-98: Added single quote and parens as legal for enclosing parameters with white space in the parser +7-9-98: Fixed bug where setting nphases for load was resetting the bus name to default value + Reversed order on Phases and Bus1 in Load. + Revised way reallocation of the BusNames array is done so that previous changes are preserved + and default names are only put in on initial allocation. +8-1-98: Added Capacitor, Tested. + Added Enabled flag to CktElement Class. No way to turn it off yet. + Fixed error in load connection interpretation (lower case) + Fixed up display in ShowResults + Removed Dynasolve command. Use 'set mode=dynamic' instead + Added 'enable' and 'disable' commands to Exec. + Changed Type=xxxx and Name=zzzz To Object=Class.Name to agree with IEEE PSAD. +8-2-98: Revised processing of bus lists so that bus name can be changed on the fly and + devices can be enabled and disabled. + Modified HashList to add a Clear Function, which leaves allocation alone, but + zeroes out the counters. Should be fast way to reestablish buslists, etc. + Enable/disable tested and refined. BusNameRedefined made property. Also sets + the flag to rebuild the SystemY. + Fixed up Show Voltages to order voltages by bus and node. + Added Open/Close command. + Moved check for open conductors to Base CktElement Class and called + 'Inherited CalcYPrim' near the end of the routine. Works. + Tested Redirect. + Added facilities to handle blank lines and comments: + '//'at beginning of lines '/' may work as an abbreviation + Parser also allows ! anywhere on line. + Changed global systemY matrix flag to SystemYChanged. +8-3-98 Fixed bug where Enable was not always causing SystemY to be rebuilt +8-5-98 Add code to invalidate yprims of PCelements whenever solution is changed + from DIRECT mode to any of the power flow modes. + Added Substation classification as an option for Transformer class. + Set Sub=yes. Then when we look for substation losses, we can find them + by checking the IsSubstation value of a transformer. + Add lists of lines and transformers to the Circuit object so we can find + them more quickly too. Both are also kept in PDElement lists. + Found and fixed error in YEQ in load model - imaginary part had wrong sign. +8-6-98 Built VCL object. + Added DSSClass string to all elements because there was no way to figure out + the class of an object if you found it. (for reporting back through interface) +8-7-87 Built ActiveX control. + DSSXIMpl1.pas. Delphi converted most every thing but methods with arguments. + Fixed GetCurrents in monitor because it was default to base class. Had it report + current of monitored object terminal. Seems too work. + Wrote VB test app. Seems to work OK, except had to explicitely add + chdrive and chdir statements to get program to switch to working directory. + Discovered why when doing a new circuit twice the solution appeared to be messed up. + You can't have two objects with the same fully qualified name in the problem set + or the Edit command will only work on the first. Changed the TestForm to use the + More command instead of the Edit for changing the source. +8-12-98 + Added Help command. + Added Compile as a synonym for Redirect. + Fixed bug in the bus redefinition that was not handling cases where not all + terminal-node connections were specified (in Circuit). + Fixed bug in transformer model where 1-phase wye connected voltage base + was being misinterpreted. (Recalc...) + Added Select Command to Executive + Added assumed 'edit' capability and parsing of element properties. + Added a TreeView box for Help that will automatically show all the property names. + Moved the Editcommand array to the DSSClass base class and dynamically allocated it +8-22-98 + Added Fault object + Added Monte Carlo Fault Study. + Added modes to monitor to save various quantities other then just V&I. + Changed the way the buffer in Monitor object works. +8-23-98 + Debugged monitor - indexing problem in MonBuffer. All modes check out. + Tested MFault algorithm. Seems to work. Kind of slow because rebuilds Y + matrix for each solution. + fixed bug in solution where the old sparseset was not being thrown away before + building a new one. This caused Esolve32 to crash after a bit, which was trapped + nicely by the raise exception in BuildYMatrix. +8-26-09 + Fixed bug where fault random multiplier was inverse of what it should have been. + +10-14-98 + Delphi 4 introduced a Tmonitor to the system so I had to change the name of + the monitor type to TDSSMonitor. + Added Max kVA ratings to Transformer. + Added kvas= array parameter to transformer. + Changed way transformer voltage ratings are interpreted. Now like capacitor. + +10-23-98 to 10-24-98 + + Added Property values, PropHelp to objects. + Added ? command to display a message dlg with the value of a property + Modified Dump command to dump only properties of an element when there + is a parameter on the Dump command line. + Modified Monitor to include the Mode on the header record. + +10-26-98 + Started addition of kWHMeter. + Completed revision of properties. + Made double-paned Help panel. + +10-27-98 + Fixed problem with sign of power factor in load. + Worked more on energy meter in prep for Poland IRP study. + +10-28-98 + Continued work on kWHMeter. Got zone established. + Changed voltage base in Load to agree with capacitor. + Got all help notes in. + Found some issues with multiple circuits. + Fixed load class/model issues. +10-29-98 + Modified Ucmatrix to give Order property. + Issue worked at correcting load model. + Added solution counter to minimize recalc of current for UE search. +11-3/98 + Moved NormAmps and EmergAmps to PDElement. + Added NormAmps, EmergAmps calculation to the Transformer based on the + first winding. +12-1-98 + Fixed NormAmps calc in Transformer to properly account for line amps in 1-phase + L-L transformers. + Fixed the neutral definition of transformer Wye windings so that it automatically + gets set to something if neutral Z is specified. + +12-2-98 - 12-5-98 Added kWhMeter + +12-5-98 + Found power flow algorithm had trouble converging if source was not somewhat grounded. + Solved just fine in Admittance mode, but not in current injection mode. Solved just + fine if a grounding transformer were added. + +12-7-09 + Fixed CktTree so that the correct pointers were being saved. + Added Save option to energy meter. MTR_metername.CSV + Added Take Action to Monitor to be consistent with meter. + +12-21-98 Fixed indexing problem in transformer which resulted in improper YPrim for + 3-winding transformer. +12-22-98 Removed base frequency conversion upon transferring data from Linecode to Line. + Set Line.Basefrequency = LineCode.BaseFrequency. thus, frequency compensation + is automatic in CalcYPrim. + +12-30-98 + Fixed bug in 3-winding transformer that caused the impedances to be rotated + by one winding. + +1-4-99 Converted energy meter to trapezoidal integration so we can do load duration solutions. +1-9-99 Fixed offset in Monitor so it would properly index the currents when connected to + other than the first terminal of transformers etc which do not have numconds=numphases +1-11-99 to 1-13-99 Added generator and control panel. Miriad of misc fixes. New interface (4). + +1-18-99 .. 1-20-99 + Fixed DSSGlobal function to report Mode to interface correctly + Open command resulted in short circuit by eliminating row and column. + Fixed by doing a Kron reduction before eliminating row. + Set ErrorResult on ActiveElement property. =0 then it doesn't work! + NormalAmps and EmergAmps were not being brought over from line code + +2-23-99 + Added Abort to message dialog when in Redirect or Compile command. + Moved HelpFormX variable to Globals so we can dispose of the Form when we quit. + +6/7/99 + Fixed assignment problem in ImplSolution + Fixed bug in transformer creation that would sporadically give an overflow. + Added DefaultGrowthFactor. (%Growth) +6/8/99 + Found that the Ellipse function in DSSGraph messed up the pen or brush or something. + Drew nodes after drawing the lines and it worked. +6/15/99 + Added Version to interface and About box to DSS + Added startup validation and checking. + +6/23/99 Fixed bug in which disabled device gets checked by energy meter + before energy meter is ready to be used. +6/24/99 Added IsOpen function to DSS Interface + +4/18/03 Added propertysequence array and then implemented the SAVE command. + +4/3/06 Changed Error Handling and Error Number +} + +(* Debugging for MakePosSeq + FUNCTION DoMakePosSeq:Integer; + + Var + CktElem:TDSSCktElement; + + Begin + Result := 0; + + ActiveCircuit.PositiveSequence := TRUE; + + CktElem := ActiveCircuit.CktElements.Get_First(); + While CktElem<>Nil Do + Begin + CktElem.MakePosSequence; + CktElem := ActiveCircuit.CktElements.Get_Next(); + End; + + End; + + function IsGroundBus (const S: String) : Boolean; + var + i : Integer; + begin + Result := True; + i := pos ('.1', S); + if i > 0 then Result := False; + i := pos ('.2', S); + if i > 0 then Result := False; + i := pos ('.3', S); + if i > 0 then Result := False; + i := pos ('.', S); + if i = 0 then Result := False; + end; + + procedure TDSSCktElement.MakePosSequence; + Var + i:Integer; + grnd: Boolean; + begin + For i := 1 to FNterms Do begin + grnd := IsGroundBus (FBusNames^[i]); + FBusNames^[i] := StripExtension(FBusNames^[i]); + if grnd then + FBusNames^[i] := FBusNames^[i] + '.0'; + end; + end; + + procedure TSwtControlObj.MakePosSequence; + begin + if ControlledElement <> Nil then begin + Nphases := ControlledElement.NPhases; + Nconds := FNphases; + Setbus(1, ControlledElement.GetBus(ElementTerminal)); + end; + inherited; + end; + + procedure TStorageControllerObj.MakePosSequence; + begin + if MonitoredElement <> Nil then begin + Nphases := MonitoredElement.NPhases; + Nconds := FNphases; + Setbus(1, MonitoredElement.GetBus(ElementTerminal)); + end; + inherited; + end; + + //---------------------------------------------------------------------------- + PROCEDURE TStorageObj.MakePosSequence; + + VAR + S :String; + V :Double; + + Begin + + S := 'Phases=1 conn=wye'; + + // Make sure voltage is line-neutral + If (Fnphases>1) or (connection<>0) + Then V := kVStorageBase/SQRT3 + Else V := kVStorageBase; + + S := S + Format(' kV=%-.5g',[V]); + + If Fnphases>1 Then + Begin + S := S + Format(' kWrating=%-.5g PF=%-.5g',[kWrating/Fnphases, PFNominal]); + End; + + Parser.CmdString := S; + Edit; + + inherited; // write out other properties + End; + + //============================================================================= + procedure TVsourceObj.MakePosSequence; + + Var + S:String; + begin + + S :='Phases=1 '; + S := S + Format('BasekV=%-.5g ', [kVbase/SQRT3]); + S := S + Format('R1=%-.5g ', [R1]); + S := S + Format('X1=%-.5g ', [X1]); + + Parser.CmdString := S; + Edit; + + inherited; + + end; + + procedure TSensorObj.MakePosSequence; + begin + if MeteredElement <> Nil then begin + Setbus(1, MeteredElement.GetBus(MeteredTerminal)); + Nphases := MeteredElement.NPhases; + Nconds := MeteredElement.Nconds; + ClearSensor; + ValidSensor := TRUE; + AllocateSensorObjArrays; + ZeroSensorArrays; + RecalcVbase; + end; + Inherited; + end; + + + procedure TRelayObj.MakePosSequence; + begin + if MonitoredElement <> Nil then begin + Nphases := MonitoredElement.NPhases; + Nconds := FNphases; + Setbus(1, MonitoredElement.GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + ReAllocMem(cBuffer, SizeOF(cbuffer^[1]) * MonitoredElement.Yorder ); + CondOffset := (ElementTerminal-1) * MonitoredElement.NConds; // for speedy sampling + end; + CASE FNPhases of + 1: vbase := kVBase * 1000.0; + ELSE + vbase := kVBase/SQRT3 * 1000.0 ; + END; + PickupVolts47 := vbase * PctPickup47 * 0.01; + inherited; + end; + + procedure TRegControlObj.MakePosSequence; + begin + if ControlledElement <> Nil then begin + Enabled := ControlledElement.Enabled; + If UsingRegulatedBus Then + Nphases := 1 + Else + Nphases := ControlledElement.NPhases; + Nconds := FNphases; + IF Comparetext(ControlledElement.DSSClassName, 'transformer') = 0 THEN Begin + // Sets name of i-th terminal's connected bus in RegControl's buslist + // This value will be used to set the NodeRef array (see Sample function) + IF UsingRegulatedBus Then + Setbus(1, RegulatedBus) // hopefully this will actually exist + Else + Setbus(1, ControlledElement.GetBus(ElementTerminal)); + ReAllocMem(VBuffer, SizeOF(Vbuffer^[1]) * ControlledElement.NPhases ); // buffer to hold regulator voltages + ReAllocMem(CBuffer, SizeOF(CBuffer^[1]) * ControlledElement.Yorder ); + End; + end; + inherited; + end; + + procedure TRecloserObj.MakePosSequence; + begin + if MonitoredElement <> Nil then begin + Nphases := MonitoredElement.NPhases; + Nconds := FNphases; + Setbus(1, MonitoredElement.GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + ReAllocMem(cBuffer, SizeOF(cbuffer^[1]) * MonitoredElement.Yorder ); + CondOffset := (ElementTerminal-1) * MonitoredElement.NConds; // for speedy sampling + end; + inherited; + end; + + procedure TReactorObj.MakePosSequence; + Var + S:String; + kvarperphase,phasekV, Rs, Rm:Double; + i,j:Integer; + + begin + If FnPhases>1 Then + Begin + CASE SpecType OF + + 1:BEGIN // kvar + kvarPerPhase := kvarRating/Fnphases; + If (FnPhases>1) or ( Connection<>0) Then PhasekV := kVRating / SQRT3 + Else PhasekV := kVRating; + + S := 'Phases=1 ' + Format(' kV=%-.5g kvar=%-.5g',[PhasekV, kvarPerPhase]); + {Leave R as specified} + + END; + 2:BEGIN // R + j X + S := 'Phases=1 '; + END; + 3:BEGIN // Matrices + S := 'Phases=1 '; + // R1 + Rs := 0.0; // Avg Self + For i := 1 to FnPhases Do Rs := Rs + Rmatrix^[(i-1)*Fnphases + i]; + Rs := Rs/FnPhases; + Rm := 0.0; //Avg mutual + For i := 2 to FnPhases Do + For j := i to FnPhases Do Rm := Rm + Rmatrix^[(i-1)*Fnphases + j]; + Rm := Rm/(FnPhases*(Fnphases-1.0)/2.0); + + S := S + Format(' R=%-.5g',[(Rs-Rm)]); + + // X1 + Rs := 0.0; // Avg Self + For i := 1 to FnPhases Do Rs := Rs + Xmatrix^[(i-1)*Fnphases + i]; + Rs := Rs/FnPhases; + Rm := 0.0; //Avg mutual + For i := 2 to FnPhases Do + For j := i to FnPhases Do Rm := Rm + Xmatrix^[(i-1)*Fnphases + j]; + Rm := Rm/(FnPhases*(Fnphases-1.0)/2.0); + + S := S + Format(' X=%-.5g',[(Rs-Rm)]); + + END; + END; + + Parser.CmdString := S; + Edit; + + End; + + + inherited; + + end; + + procedure TMonitorObj.MakePosSequence; + begin + if MeteredElement <> Nil then begin + Setbus(1, MeteredElement.GetBus(MeteredTerminal)); + Nphases := MeteredElement.NPhases; + Nconds := MeteredElement.Nconds; + Case (Mode and MODEMASK) of + 3: Begin + NumStateVars := TPCElement(MeteredElement).Numvariables; + ReallocMem(StateBuffer, Sizeof(StateBuffer^[1])*NumStatevars); + End; + Else + ReallocMem(CurrentBuffer, SizeOf(CurrentBuffer^[1])*MeteredElement.Yorder); + ReallocMem(VoltageBuffer, SizeOf(VoltageBuffer^[1])*MeteredElement.NConds); + End; + ClearMonitorStream; + ValidMonitor := TRUE; + end; + Inherited; + end; + + + + procedure TLoadObj.MakePosSequence; + Var + S:String; + V:Double; + + begin + + S := 'Phases=1 conn=wye'; + + // Make sure voltage is line-neutral + If (Fnphases>1) or (connection<>0) Then V := kVLoadBase/SQRT3 + Else V := kVLoadBase; + + S := S + Format(' kV=%-.5g',[V]); + + // Divide the load by no. phases + If Fnphases>1 Then + Begin + S := S + Format(' kW=%-.5g kvar=%-.5g',[kWbase/Fnphases, kvarbase/Fnphases]); + If FConnectedKVA>0.0 Then + S := S + Format(' xfkVA=%-.5g ',[FConnectedkVA/Fnphases]); + End; + + + Parser.CmdString := S; + Edit; + + inherited; + end; + + procedure TLineObj.MakePosSequence; + Var + S:String; + C1_new, Cs, Cm:Double; + Z1, ZS, Zm:Complex; + i,j:Integer; + begin + // set to single phase and make sure R1, X1, C1 set. + // If already single phase, let alone + If FnPhases>1 Then Begin + // Kill certain propertyvalue elements to get a cleaner looking save + PrpSequence^[3] := 0; + For i := 6 to 14 Do PrpSequence^[i] := 0; + + If IsSwitch then begin + S := ' R1=1 X1=1 C1=1.1 Phases=1 Len=0.001' + end else begin + if SymComponentsModel then begin // keep the same Z1 and C1 + Z1.re := R1; + Z1.im := X1; + C1_new := C1 * 1.0e9; // convert to nF + end else begin // matrix was input directly, or built from physical data + // average the diagonal and off-dialgonal elements + Zs := CZERO; + For i := 1 to FnPhases Do Caccum(Zs, Z.GetElement(i,i)); + Zs := CdivReal(Zs, Fnphases); + Zm := CZERO; + For i := 1 to FnPhases-1 Do // Corrected 6-21-04 + For j := i+1 to FnPhases Do Caccum(Zm, Z.GetElement(i,j)); + Zm := CdivReal(Zm, (Fnphases*(FnPhases-1.0)/2.0)); + Z1 := CSub(Zs, Zm); + + // Do same for Capacitances + Cs := 0.0; + For i := 1 to FnPhases Do Cs := Cs + Yc.GetElement(i,i).im; + Cm := 0.0; + For i := 2 to FnPhases Do + For j := i+1 to FnPhases Do Cm := Cm + Yc.GetElement(i,j).im; + C1_new := (Cs - Cm)/TwoPi/BaseFrequency/(Fnphases*(FnPhases-1.0)/2.0) * 1.0e9; // nanofarads + end; + S := Format(' R1=%-.5g %-.5g C1=%-.5g Phases=1',[Z1.re, Z1.im, C1_new]); + end; + // Conductor Current Ratings + S := S + Format(' Normamps=%-.5g %-.5g',[NormAmps, EmergAmps]); + Parser.CmdString := S; + Edit; + End; + + Inherited MakePosSequence; + end; + + procedure TIsourceObj.MakePosSequence; + begin + + If Fnphases>1 Then + Begin + Parser.CmdString := 'phases=1'; + Edit; + End; + inherited; + + end; + + procedure TGeneratorObj.MakePosSequence; + + Var + S :String; + V :Double; + + begin + + S := 'Phases=1 conn=wye'; + + // Make sure voltage is line-neutral + If (Fnphases>1) or (connection<>0) Then V := GenVars.kVGeneratorBase/SQRT3 + Else V := GenVars.kVGeneratorBase; + + S := S + Format(' kV=%-.5g',[V]); + + // Divide the load by no. phases + If Fnphases>1 Then + Begin + S := S + Format(' kW=%-.5g PF=%-.5g',[kWbase/Fnphases, PFNominal]); + If (PrpSequence^[19]<>0) or (PrpSequence^[20]<>0) Then S := S + Format(' maxkvar=%-.5g minkvar=%-.5g',[kvarmax/Fnphases, kvarmin/Fnphases]); + If PrpSequence^[26]>0 Then S := S + Format(' kva=%-.5g ',[genvars.kvarating/Fnphases]); + If PrpSequence^[27]>0 Then S := S + Format(' MVA=%-.5g ',[genvars.kvarating/1000.0/Fnphases]); + End; + + Parser.CmdString := S; + Edit; + + inherited; + end; + + procedure TGenDispatcherObj.MakePosSequence; + begin + if MonitoredElement <> Nil then begin + Nphases := ControlledElement.NPhases; + Nconds := FNphases; + Setbus(1, MonitoredElement.GetBus(ElementTerminal)); + end; + inherited; + end; + + procedure TEquivalentObj.MakePosSequence; + + Var + S:String; + begin + + + /// ???? + + + S :='Phases=1 '; + S := S + Format('BasekV=%-.5g ', [kVbase/SQRT3]); + S := S + Format('R1=%-.5g ', [R1]); + S := S + Format('X1=%-.5g ', [X1]); + + Parser.CmdString := S; + Edit; + + inherited; + + end; + + + procedure TEnergyMeterobj.MakePosSequence; + begin + if MeteredElement <> Nil then begin + Setbus(1, MeteredElement.GetBus(MeteredTerminal)); + Nphases := MeteredElement.NPhases; + Nconds := MeteredElement.Nconds; + AllocateSensorArrays; + IF BranchList <> NIL Then BranchList.Free; + BranchList := Nil; + end; + If HasFeeder Then MakeFeederObj; + Inherited; + end; + + procedure TCapControlObj.MakePosSequence; + begin + if ControlledElement <> Nil then begin + Enabled := ControlledElement.Enabled; + Nphases := ControlledElement.NPhases; + Nconds := FNphases; + end; + if MonitoredElement <> Nil then begin + Setbus(1, MonitoredElement.GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + ReAllocMem(cBuffer, SizeOF(cbuffer^[1]) * MonitoredElement.Yorder ); + CondOffset := (ElementTerminal-1) * MonitoredElement.NConds; // for speedy sampling + end; + inherited; + end; + + + procedure TCapacitorObj.MakePosSequence; + Var + S:String; + kvarperphase,phasekV, Cs, Cm:Double; + i,j:Integer; + + begin + If FnPhases>1 Then + Begin + CASE SpecType OF + + 1:BEGIN // kvar + + If (FnPhases>1) or ( Connection <> 0) Then PhasekV := kVRating / SQRT3 + Else PhasekV := kVRating; + + S := 'Phases=1 ' + Format(' kV=%-.5g kvar=(',[PhasekV]); + + For i := 1 to FNumSteps Do Begin + kvarPerPhase := FkvarRating^[i]/Fnphases; + S := S+ Format(' %-.5g',[kvarPerPhase]); + End; + + S := S +')'; + + {Leave R as specified} + + END; + 2:BEGIN // + S := 'Phases=1 '; + END; + 3:BEGIN // C Matrix + S := 'Phases=1 '; + // R1 + Cs := 0.0; // Avg Self + For i := 1 to FnPhases Do Cs := Cs + Cmatrix^[(i-1)*Fnphases + i]; + Cs := Cs/FnPhases; + + Cm := 0.0; //Avg mutual + For i := 2 to FnPhases Do + For j := i to FnPhases Do Cm := Cm + Cmatrix^[(i-1)*Fnphases + j]; + Cm := Cm/(FnPhases*(Fnphases-1.0)/2.0); + + S := S + Format(' Cuf=%-.5g',[(Cs-Cm)]); + + END; + END; + + Parser.CmdString := S; + Edit; + + End; + + inherited; + + end; + +*/ + + + + + + + + diff --git a/OpenDSSC/Common/Notes.h b/OpenDSSC/Common/Notes.h new file mode 100644 index 0000000..eac3dfe --- /dev/null +++ b/OpenDSSC/Common/Notes.h @@ -0,0 +1,22 @@ +#ifndef NotesH +#define NotesH + /* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/*Dummy module just for development notes.*/ + + +//#include + +#endif // NotesH + + + + + + + + diff --git a/OpenDSSC/Common/ShowResults.cpp b/OpenDSSC/Common/ShowResults.cpp new file mode 100644 index 0000000..08796af --- /dev/null +++ b/OpenDSSC/Common/ShowResults.cpp @@ -0,0 +1,4221 @@ + +#pragma hdrstop + +#include "ShowResults.h" +#include +#include +#include + + + +#include "Ucomplex.h" +#include "Arraydef.h" +#include "Sysutils.h" +#include "Circuit.h" +#include "DSSClass.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucmatrix.h" +#include "Solution.h" +#include "CktElement.h" +#include "Utilities.h" +#include "Bus.h" +#include "mathutil.h" +#include "PDElement.h" +#include "PCElement.h" +#include "generator.h" +#include "Transformer.h" +#include "EnergyMeter.h" +#include "Load.h" +#include "RegControl.h" +#include "ParserDel.h" +#include "CktTree.h" +#include "CmdForms.h" +#include +#include "Line.h" +#include "LineUnits.h" +#include "LineGeometry.h" +#include "YMatrix.h" +#include "SwtControl.h" +#include "klusolve.h" +#include "System.h" + + +namespace ShowResults +{ + + + int MaxBusNameLength = 0; + int MaxDeviceNameLength = 0; + + + Char TABCHAR = Char( 9 ); + + + void SetMaxBusNameLength( ) + { + int i = 0; + MaxBusNameLength = 4; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + MaxBusNameLength = max( MaxBusNameLength, with0->BusList.Get( i ).size() ); + } + } + + + void SetMaxDeviceNameLength( ) + { + int i = 0; + String DevName, DevClassName; + MaxDeviceNameLength = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumDevices, i = 1; i <= stop; i++) + { + DevName = with0->DeviceList.Get( i ); + DevClassName = ((TDSSClass*) DSSClassList[ActiveActor].Get( with0->DeviceRef[i - 1].CktElementClass))->get_myClass_name(); + MaxDeviceNameLength = max( MaxDeviceNameLength, ( DevName.size( ) + DevClassName.size( ) + 1 ) ); + } + } + } + + void WriteSeqVoltages( Textfile& F, int i, bool LL ) + { + int j = 0, k = 0; + std::vector Vph; + std::vector VLL; + std::vector V012; + + + double V0 = 0.0, v1 = 0.0, V2 = 0.0, Vpu = 0.0, V2V1 = 0.0, V0V1 = 0.0; + /*# with ActiveCircuit[ActiveActor] do */ + { + Vph.resize(3 + 1); + VLL.resize(3 + 1); + V012.resize(3 + 1); + + auto with0 = ActiveCircuit[ActiveActor]; + { + if ( with0->Buses[i - 1]->get_FNumNodesThisBus() >= 3 ) + { + + // compute sequence voltages for Nodes 1, 2, and 3 only + /*# with Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + for ( int stop = 3, j = 1; j <= stop; j++) + Vph[j] = with0->Solution->NodeV[with1->GetRef( with1->FindIdx( j ) )]; + } + if ( LL ) + { + for ( int stop = 3, j = 1; j <= stop; j++) + { + k = j + 1; + if ( k > 3 ) + k = 1; + VLL[j] = csub( Vph[j], Vph[k] ); + } + Phase2SymComp( &VLL[1], &V012[1]); + } + else + { + Phase2SymComp( &Vph[1], &V012[1] ); + } + V0 = cabs( V012[1] ); + v1 = cabs( V012[2] ); + V2 = cabs( V012[3] ); + } + else + { + Vph[1] = with0->Solution->NodeV[with0->Buses[i - 1]->GetRef( 1 )]; + V0 = 0.0; + v1 = cabs( Vph[1] ); // Use first phase value for non-three phase buses + V2 = 0.0; + } + v1 = v1 / 1000.0; /*Convert to kV*/ + V2 = V2 / 1000.0; + V0 = V0 / 1000.0; + + // Calc per unit value + if ( with0->Buses[i - 1]->kVBase != 0.0 ) + Vpu = v1 / with0->Buses[i - 1]->kVBase; + else + Vpu = 0.0; + if ( LL ) + Vpu = Vpu / SQRT3; + if ( v1 > 0.0 ) + { + V2V1 = 100.0 * V2 / v1; + V0V1 = 100.0 * V0 / v1; + } + else + { + V2V1 = 0.0; + V0V1 = 0.0; + } + System::WriteLn(F, Format("%s %9.4g %9.4g %9.4g %9.4g %9.4g %9.4g", + Pad(with0->BusList.Get(i), MaxBusNameLength).c_str(), v1, Vpu, V2, V2V1, V0, V0V1)); + } + } /*With*/ + Vph.clear(); + VLL.clear(); + V012.clear(); + } + + string trim(const std::string& str) { + size_t first = str.find_first_not_of(' '); + if (std::string::npos == first) { + return str; + } + size_t last = str.find_last_not_of(' '); + return str.substr(first, (last - first + 1)); + } + + + void WriteBusVoltages( Textfile& F, int i, bool LL ) + + // 6/11/14 Modified to write both LL and LN voltages out for LN case + + { + int nref1 = 0, nref2 = 0, j = 0, k = 0; + complex Volts, VoltsLL; + double Vmag = 0.0, VmagLL = 0.0, Vpu = 0.0, VpuLL = 0.0; + String Bname; + + int NodeIdx = 0; + int jj = 0, kk = 0; + char NodeName[1000]; + char NodeNameLL[1000]; + + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + jj = 1; + /*# with Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + for ( int stop = with1->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + // Get the index of the next Node in numerical sequence + do + { + NodeIdx = with1->FindIdx( jj ); // Get the index of the Node that matches jj + jj++; + } + while ( ! ( NodeIdx > 0 ) ); + nref1 = with1->GetRef( NodeIdx ); // Get the onverall node reference number + Volts = with0->Solution->NodeV[nref1]; + kk = 1; // keep compiler from complaining + if /*LL and*/ ( jj <= 4 ) + // Line-to-line voltages + { // Convert to Line-Line assuming no more than 3 phases + // k is 1, 2, or 3 + k = jj; + if ( k > 3 ) + k = 1; + kk = with1->FindIdx( k ); + if ( kk <= with1->get_FNumNodesThisBus() ) + { + nref2 = with0->Buses[i - 1]->GetRef( kk ); // reference for next phase in sequence + VoltsLL = csub( Volts, with0->Solution->NodeV[nref2] ); + } + } + Vmag = cabs( Volts ) * 0.001; + VmagLL = cabs( VoltsLL ) * 0.001; + if ( with1->kVBase != 0.0 ) + { + Vpu = Vmag / with1->kVBase; + VpuLL = double( VmagLL ) / with1->kVBase / SQRT3; + } + else + { + Vpu = 0.0; + VpuLL = 0.0; + } + if /*LL and*/ ( jj <= 4 ) + { + // Vpu := Vpu/SQRT3; + sprintf(NodeNameLL,"%d-%d", with1->GetNum( NodeIdx ), with1->GetNum( kk ) ); + } + sprintf(NodeName,"%d ",with1->GetNum( NodeIdx ) ); + + if ( j == 1 ) + Bname = Paddots( with0->BusList.Get( i ), MaxBusNameLength ); + if ( LL ) + { + if ( kk > 0 ) + { + System::WriteLn( F, Format("%s %s %10.5g /_ %6.1f %9.5g %9.3f", UpperCase(Bname).c_str(), NodeNameLL, VmagLL, cdang(VoltsLL), VpuLL, with1->kVBase * SQRT3)); + Bname = Pad( " -", MaxBusNameLength ); + } + } + else + { + System::Write(F, Format("%s %s %10.5g /_ %6.1f %9.5g %9.3f", UpperCase(Bname).c_str(), NodeName, Vmag, cdang(Volts), Vpu, with1->kVBase * SQRT3)); + + if ( ( with1->get_FNumNodesThisBus() > 1 ) && ( kk > 0 ) && ( jj <= 4 ) ) + { + System::Write( F, Format(" %s %10.5g /_ %6.1f %9.5g", NodeNameLL, VmagLL, cdang(VoltsLL), VpuLL)); + } + System::WriteLn( F ); + Bname = Pad( " -", MaxBusNameLength ); + } + } + } + } + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteElementVoltages( Textfile& F, TDSSCktElement* pElem, bool LL ) + { + int Ncond = 0, Nterm = 0, i = 0, j = 0, k = 0, Nref = 0, bref = 0; + String BusName; + complex Volts; + double Vpu = 0.0, Vmag = 0.0; + Ncond = pElem->Get_NConds(); + Nterm = pElem->Get_NTerms(); + + + k = 0; + BusName = Pad( StripExtension( pElem->Get_FirstBus() ), MaxBusNameLength ); + System::WriteLn(F, "ELEMENT = \"" + pElem->Get_myPName() + "." + UpperCase( pElem->get_Name() ) + "\"" ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + k++; + Nref = pElem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Vmag = cabs( Volts ) * 0.001; + /*# with ActiveCircuit[ActiveActor] do */ + { + int myNodeNum = 0; + auto with0 = ActiveCircuit[ActiveActor]; + { + if ( Nref == 0 ) + Vpu = 0.0; + else + { + bref = with0->MapNodeToBus[Nref - 1].BusRef; + if ( with0->Buses[bref - 1]->kVBase != 0.0 ) + Vpu = Vmag / with0->Buses[bref - 1]->kVBase; + else + Vpu = 0.0; + } + if ( LL ) + Vpu = Vpu / SQRT3; + if (Nref != 0) myNodeNum = with0->MapNodeToBus[Nref - 1].NodeNum; + else myNodeNum = 0; + + System::WriteLn(F, Format("%s (%3d) %4d %13.5g (%8.4g) /_ %6.1f", UpperCase(BusName).c_str(), Nref, myNodeNum, Vmag, Vpu, cdang(Volts))); + } + } + } + if ( j < Nterm ) + { + System::WriteLn(F, "------------" ); + } + BusName = Pad( StripExtension( pElem->Get_NextBus() ), MaxBusNameLength ); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteElementDeltaVoltages( Textfile& F, TDSSCktElement* pElem ) + { + int Ncond = 0, Node1 = 0, Node2 = 0, Bus1 = 0, Bus2 = 0, i = 0; + double Vmag = 0.0; + complex Volts1, Volts2; + String ElemName; + + + Ncond = pElem->Get_NConds(); + ElemName = Pad( pElem->Get_myPName() + "." + UpperCase( pElem->get_Name() ), MaxDeviceNameLength ); + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + Node1 = (pElem->NodeRef)[i - 1]; + Node2 = (pElem->NodeRef)[i + Ncond - 1]; + auto with0 = ActiveCircuit[ActiveActor]; + if ( Node1 > 0 ) + Bus1 = ActiveCircuit[ActiveActor]->MapNodeToBus[Node1-1].BusRef; + else + Bus1 = 0; + if ( Node2 > 0 ) + Bus2 = ActiveCircuit[ActiveActor]->MapNodeToBus[Node2-1].BusRef; + else + Bus2 = 0; + if ( ( Bus1 > 0 ) && ( Bus2 > 0 ) ) + { + Volts1 = ActiveCircuit[ActiveActor]->Solution->NodeV[Node1]; // OK if Node1 or Node2 = 0 + Volts2 = ActiveCircuit[ActiveActor]->Solution->NodeV[Node2]; + Volts1 = csub( Volts1, Volts2 ); // diff voltage + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + if ( with0->Buses[Bus1 - 1]->kVBase != with0->Buses[Bus2 - 1]->kVBase ) + Vmag = 0.0; + else + { + if ( with0->Buses[Bus1 - 1]->kVBase > 0.0 ) + Vmag = double( cabs( Volts1 ) ) / ( 1000.0 * with0->Buses[Bus1 - 1]->kVBase ) * 100.0; + else + Vmag = 0.0; + } + System::WriteLn( F, Format("%s, %4d, %12.5g, %12.5g, %12.5g, %6.1f", ElemName.c_str(), i, cabs(Volts1), Vmag, with0->Buses[Bus1 - 1]->kVBase, cdang(Volts1))); + } + } + } + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowVoltages(String Filenm, bool LL, int ShowOptionCode) + + // Show bus voltages by circuit element terminal + + { + TTextRec F = {}; + int i = 0; + TDSSCktElement* pElem = nullptr; + try + { + SetMaxBusNameLength(); + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + switch (ShowOptionCode) + { + case 0: + { + System::WriteLn(F); + if (LL) + System::WriteLn(F, "SYMMETRICAL COMPONENT PHASE-PHASE VOLTAGES BY BUS (for 3-phase buses)"); + else + System::WriteLn(F, "SYMMETRICAL COMPONENT VOLTAGES BY BUS (for 3-phase buses)"); + System::WriteLn(F); + System::Write(F, Pad("Bus", MaxBusNameLength)); System::WriteLn(F, " Mag: V1 (kV) p.u. V2 (kV) %V2/V1 V0 (kV) %V0/V1"); + System::WriteLn(F); + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + WriteSeqVoltages(F, i, LL); + } + break; /*ShowOptionCode Case 0*/ + case 1: + { + System::WriteLn(F); + if (LL) + System::WriteLn(F, "LINE-LINE VOLTAGES BY BUS & NODE"); + else + System::WriteLn(F, "LINE-GROUND and LINE-LINE VOLTAGES BY BUS & NODE"); + System::WriteLn(F); + if (LL) + { + System::Write(F, Pad("Bus", MaxBusNameLength)); System::WriteLn(F, " Node VLN (kV) Angle pu Base kV "); + } + else + { + System::Write(F, Pad("Bus", MaxBusNameLength)); System::WriteLn(F, " Node VLN (kV) Angle pu Base kV Node-Node VLL (kV) Angle pu"); + } + System::WriteLn(F); + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + WriteBusVoltages(F, i, LL); + } + break; /*ShowOptionCode Case 1*/ + case 2: + { + System::WriteLn(F); + System::WriteLn(F, "NODE-GROUND VOLTAGES BY CIRCUIT ELEMENT"); + System::WriteLn(F); + System::WriteLn(F, "Power Delivery Elements"); + System::WriteLn(F); + System::Write(F, Pad("Bus", MaxBusNameLength)); System::WriteLn(F, " (node ref) Phase Magnitude, kV (pu) Angle"); + System::WriteLn(F); + + + // SOURCES first + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Sources.Get_First(); + while (pElem != NULL) + { + if (pElem->Get_Enabled()) + WriteElementVoltages(F, pElem, LL); + System::WriteLn(F); + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + // PDELEMENTS first + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while (pElem != NULL) + { + if (pElem->Get_Enabled()) + WriteElementVoltages(F, pElem, LL); + System::WriteLn(F); + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + System::WriteLn(F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ="); + System::WriteLn(F); + System::WriteLn(F, "Power Conversion Elements"); + System::WriteLn(F); + System::Write(F, Pad("Bus", MaxBusNameLength)); System::WriteLn(F, " (node ref) Phase Magnitude, kV (pu) Angle"); + System::WriteLn(F); + + // PCELEMENTS next + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while (pElem != NULL) + { + if (pElem->Get_Enabled()) + WriteElementVoltages(F, pElem, LL); + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + System::WriteLn(F); + } + } + break; /*ShowOptionCode Case 2*/ + default: {} + /*nada*/ + } + // } + // __finally + // { + CloseFile(F); + if (AutoDisplayShowReport) + FireOffEditor(Filenm); + ParserVars->Add("@lastshowfile", Filenm); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void GetI0I1I2( double& I0, double& I1, double& I2, double& Cmax, int NPhases, int koffset, pComplexArray cBuffer ) + { + double cmag = 0.0; + int i = 0; + complex Iph[3] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0)}, + I012[3] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0) }; + if ( NPhases >= 3 ) + { + Cmax = 0.0; + for ( int stop = 3, i = 0; i < stop; i++) + { + Iph[i] = (cBuffer)[koffset + i]; + cmag = cabs( Iph[i] ); + if ( cmag > Cmax ) + Cmax = cmag; + } + Phase2SymComp( & Iph[0], &I012[0]); + I0 = cabs( I012[0] ); + I1 = cabs( I012[1] ); + I2 = cabs( I012[2] ); + } + else + { + I0 = 0.0; + I1 = cabs( (cBuffer)[1 + koffset - 1] ); + I2 = 0.0; + Cmax = I1; + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteSeqCurrents( Textfile& F, const String PaddedBrName, double I0, double I1, double I2, double Cmax, double NormAmps, double EmergAmps, int j, int DSSObjType ) + { + double iNormal = 0.0, iEmerg = 0.0, I2I1 = 0.0, I0I1 = 0.0; + String Name; + iNormal = 0.0; + iEmerg = 0.0; + if ( j == 1 ) + Name = PaddedBrName; + else + Name = Pad( " -", PaddedBrName.size( ) ); + if ( I1 > 0.0 ) + I2I1 = 100.0 * I2 / I1; + else + I2I1 = 0.0; + if ( I1 > 0.0 ) + I0I1 = 100.0 * I0 / I1; + else + I0I1 = 0.0; + if ( ( ( ( CLASSMASK & DSSObjType ) ) != CAP_ELEMENT ) && ( j == 1 ) ) + { // only write overloads for non-capacitors and terminal 1 + if ( NormAmps > 0.0 ) + iNormal = Cmax / NormAmps * 100.0; + if ( EmergAmps > 0.0 ) + iEmerg = Cmax / EmergAmps * 100.0; + } + + System::WriteLn( F, Format( "%s %3d %10.5g %10.5g %8.2f %10.5g %8.2f %8.2f %8.2f", UpperCase(Name).c_str(), j, I1, I2, I2I1, I0, I0I1, iNormal, iEmerg)); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteTerminalCurrents( Textfile& F, TDSSCktElement* pElem, bool ShowResidual ) + { + int j = 0, i = 0, k = 0, Ncond = 0, Nterm = 0; + pComplexArray cBuffer; + String FromBus; + complex Ctotal; + polar ResidPolar; + int Ntimes = 0; + //cBuffer = NULL; + Ncond = pElem->Get_NConds(); + Nterm = pElem->Get_NTerms(); + try + { + cBuffer = (pComplexArray) malloc( sizeof(complex) * Ncond * Nterm ); + pElem->GetCurrents( cBuffer, ActiveActor ); + k = 0; + FromBus = Pad( StripExtension( pElem->Get_FirstBus() ), MaxBusNameLength ); + System::Write( F, "ELEMENT = " ); System::WriteLn( F, FullName( pElem ) ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Ctotal = CZero; + if ( ( ( CLASSMASK & pElem->DSSObjType ) ) == AUTOTRANS_ELEMENT ) + Ntimes = pElem->Get_NPhases(); // Special case for AutoTrans + else + Ntimes = Ncond; + for ( int stop = Ntimes, i = 1; i <= stop; i++) + { + k++; + if ( ShowResidual ) + caccum( Ctotal, (cBuffer)[k-1] ); + System::WriteLn( F, Format( "%s %4d %13.5g /_ %6.1f = %9.5g +j %9.5g", UpperCase(FromBus).c_str(), GetNodeNum((pElem->NodeRef)[k - 1]), cabs((cBuffer)[k - 1]), cdang((cBuffer)[k - 1]), (cBuffer)[k - 1].re, (cBuffer)[k - 1].im)); + } + if ( ShowResidual && ( pElem->Get_NPhases() > 1 ) ) + { + ResidPolar = ctopolardeg( cnegate( Ctotal ) ); + System::WriteLn( F, Format( "%s Resid %13.5g /_ %6.1f = %9.5g +j %9.5g", UpperCase( FromBus).c_str(), ResidPolar.mag, ResidPolar.ang, -Ctotal.re, -Ctotal.im)); + } + if ( j < Nterm ) + { + System::WriteLn( F, "------------" ); + } + FromBus = Pad( StripExtension( pElem->Get_NextBus() ), MaxBusNameLength ); + if ( ( ( CLASSMASK & pElem->DSSObjType ) ) == AUTOTRANS_ELEMENT ) + k += Ntimes; // Special case for AutoTrans + } + System::WriteLn( F ); + // } + // __finally + // { + if (( cBuffer != NULL ) ) + free( cBuffer ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowCurrents( String Filenm, bool ShowResidual, int ShowOptionCode ) + { + TTextRec F; + vector cBuffer; + int Ncond = 0, + Nterm = 0, + j = 0; + TDSSCktElement* pElem = nullptr; + TPDElement* PDElem = nullptr; + TPCElement* PCelem = nullptr; + double I0 = 0.0, + I1 = 0.0, + I2 = 0.0, + Cmax = 0.0; + SetMaxDeviceNameLength(); + SetMaxBusNameLength(); + try + { + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + switch ( ShowOptionCode ) + { + case 0: + { /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "SYMMETRICAL COMPONENT CURRENTS BY CIRCUIT ELEMENT (first 3 phases)" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element", MaxDeviceNameLength + 2 ) ); System::WriteLn( F, " Term I1 I2 %I2/I1 I0 %I0/I1 %Normal %Emergency" ); + System::WriteLn( F ); + + + //Sources Get_First() + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + Ncond = pElem->Get_NConds(); + Nterm = pElem->Get_NTerms(); + cBuffer.resize( Ncond * Nterm + 1); + pElem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, pElem->Get_NPhases(), ( j - 1 ) * Ncond, &cBuffer[0]); + /*# with pElem do */ + WriteSeqCurrents( F, Paddots( FullName( pElem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, pElem->DSSObjType ); + } + cBuffer.resize(0); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS Get_Next() + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if (((TDSSCktElement*)PDElem)->Get_Enabled() ) + { + Ncond = ((TDSSCktElement*)PDElem)->Get_NConds(); + Nterm = ((TDSSCktElement*)PDElem)->Get_NTerms(); + cBuffer.resize(Ncond * Nterm + 1); + PDElem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, ((TDSSCktElement*)PDElem)->Get_NPhases(), ( j - 1 ) * Ncond, &cBuffer[0]); + /*# with PDElem do */ + WriteSeqCurrents( F, Paddots( FullName( PDElem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, PDElem->NormAmps, PDElem->EmergAmps, j, ((TDSSCktElement*)PDElem)->DSSObjType ); + } /*For*/ + cBuffer.resize(0); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCelemENTS next + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if (((TDSSCktElement*)PCelem)->Get_Enabled() ) + { + Ncond = ((TDSSCktElement*)PCelem)->Get_NConds(); + Nterm = ((TDSSCktElement*)PCelem)->Get_NTerms(); + cBuffer.resize(Ncond * Nterm + 1); + PCelem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, ((TDSSCktElement*)PCelem)->Get_NPhases(), ( j - 1 ) * Ncond, &cBuffer[0]); + /*# with PCelem do */ + WriteSeqCurrents( F, Paddots( FullName( PCelem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, ((TDSSCktElement*)PCelem)->DSSObjType ); + } + cBuffer.resize(0); + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + + + //Faults next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + Ncond = pElem->Get_NConds(); + Nterm = pElem->Get_NTerms(); + cBuffer.resize(Ncond * Nterm + 1); + pElem->GetCurrents( &cBuffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, pElem->Get_NPhases(), ( j - 1 ) * Ncond, &cBuffer[0]); + /*# with pElem do */ + WriteSeqCurrents( F, Paddots( FullName( pElem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, pElem->DSSObjType ); + } + cBuffer.resize(0); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + } + break; /*Code 0:*/ + case 1: + { /*Element branch Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "CIRCUIT ELEMENT CURRENTS" ); + System::WriteLn( F ); + System::WriteLn( F, "(Currents into element from indicated bus)" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( " Bus", MaxBusNameLength ) ); System::WriteLn( F, " Phase Magnitude, A Angle (Real) +j (Imag)" ); + System::WriteLn( F ); + + + + // Sources first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + WriteTerminalCurrents( F, pElem, false ); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + WriteTerminalCurrents( F, pElem, ShowResidual ); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // Faults + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + WriteTerminalCurrents( F, pElem, false ); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + System::WriteLn( F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Conversion Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( " Bus", MaxBusNameLength ) ); System::WriteLn( F, " Phase Magnitude, A Angle (Real) +j (Imag)" ); + System::WriteLn( F ); + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + WriteTerminalCurrents( F, pElem, false ); + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; /*code:1*/ + default: {} + } /*CASE*/ + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + catch( std::exception & E ) + { + DoSimpleMsg( "Exception raised in ShowCurrents: " + (std::string) E.what(), 2190 ); + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowPowers( String Filenm, int Opt, int ShowOptionCode ) + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + String FromBus = ""; + TTextRec F = {}; + std::vector c_Buffer; + int Ncond = 0, + Nterm = 0, + i = 0, + j = 0, + k = 0, + Nref = 0, + Ntimes = 0; + TDSSCktElement* p_Elem = nullptr; + TPDElement* PDElem = nullptr; + TPCElement* PCelem = nullptr; + complex Volts = cmplx(0,0), + S = cmplx(0,0), + Saccum = cmplx(0,0); + complex Vph[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + V012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + Iph[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + I012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + + c_Buffer.resize(0); + SetMaxDeviceNameLength(); + SetMaxBusNameLength(); + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Allocate c_Buffer big enough for largest circuit element*/ + c_Buffer.resize(GetMaxCktElementSize() + 1); + switch ( ShowOptionCode ) + { + case 0: + { + /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "SYMMETRICAL COMPONENT POWERS BY CIRCUIT ELEMENT (first 3 phases) Excess Power" ); + System::WriteLn( F ); + switch ( Opt ) + { + case 1: + { + System::Write( F, Pad( "Element", MaxDeviceNameLength + 2 ) ); System::WriteLn( F, " Term P1(MW) Q1(Mvar) P2 Q2 P0 Q0 P_Norm Q_Norm P_Emerg Q_Emerg" ); + } + break; + default: + { + System::Write( F, Pad( "Element", MaxDeviceNameLength + 2 ) ); System::WriteLn( F, " Term P1(kW) Q1(kvar) P2 Q2 P0 Q0 P_Norm Q_Norm P_Emerg Q_Emerg" ); + } + } + System::WriteLn( F ); + + // Sources first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + { + Ncond = p_Elem->Get_NConds(); + Nterm = p_Elem->Get_NTerms(); + p_Elem->GetCurrents( &( c_Buffer[0] ), ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + System::Write( F, Pad( FullName( p_Elem ), MaxDeviceNameLength + 2 ) ); System::Write( F, j, 3 ); + int stop1 = 3; + if (p_Elem->Get_NPhases() <= 3) + stop1 = p_Elem->Get_NPhases(); + for ( i = 1; i <= stop1; i++) + { + k = ( j - 1 ) * Ncond + i; + Nref = (p_Elem->NodeRef)[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Iph[i] = (c_Buffer)[k - 1]; + Vph[i] = Volts; + } + if ( p_Elem->Get_NPhases() >= 3 ) + { + Phase2SymComp( &(Iph[1]), &(I012[1])); + Phase2SymComp( &(Vph[1]), &(V012[1]) ); + } + else + { // Handle single phase and pos seq models + V012[1] = CZero; + I012[1] = CZero; + V012[3] = CZero; + I012[3] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[2] = Vph[1]; + I012[2] = Iph[1]; + } + else + { + V012[2] = CZero; + I012[2] = CZero; + } + } + S = cmul( V012[2], conjg( I012[2] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[3], conjg( I012[3] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[1], conjg( I012[1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%8.1f", S.re * 0.003)); + System::Write( F, Format("%8.1f", S.im * 0.003)); + System::WriteLn( F ); + } + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS next + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if (PDElem->Get_Enabled() ) + { + Ncond = PDElem->Get_NConds(); + Nterm = PDElem->Get_NTerms(); + PDElem->GetCurrents(&(c_Buffer[0]), ActiveActor ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + System::Write( F, Pad( FullName( PDElem ), MaxDeviceNameLength + 2 ) ); System::Write( F, j, 3 ); + for ( int stop = min( 3, PDElem->Get_NPhases() ), i = 1; i <= stop; i++) + { + k = ( j - 1 ) * Ncond + i; + Nref = PDElem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Iph[i] = c_Buffer[k - 1]; + Vph[i] = Volts; + } + if (PDElem->Get_NPhases() >= 3 ) + { + Phase2SymComp( &(Iph[1]), &(I012[1]) ); + Phase2SymComp( &(Vph[1]), &(V012[1]) ); + } + else + { // Handle single phase and pos seq models + V012[1] = CZero; + I012[1] = CZero; + V012[3] = CZero; + I012[3] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[2] = Vph[1]; + I012[2] = Iph[1]; + } + else + { + V012[2] = CZero; + I012[2] = CZero; + } + } + S = cmul( V012[2], conjg( I012[2] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[3], conjg( I012[3] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[1], conjg( I012[1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%8.1f", S.re * 0.003)); + System::Write( F, Format("%8.1f", S.im * 0.003)); + if ( j == 1 ) + { + //----PDelem.ActiveTerminalIdx := 1; + S = PDElem->Get_ExcessKVANorm(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re)); + System::Write( F, Format("%11.1f", S.im)); + S = PDElem->Get_ExcessKVAEmerg(1, ActiveActor); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re)); + System::Write( F, Format("%11.1f", S.im)); + } + System::WriteLn( F ); + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if (PCelem->Get_Enabled() ) + { + Ncond = PCelem->Get_NConds(); + Nterm = PCelem->Get_NTerms(); + PCelem->GetCurrents(&(c_Buffer[0]), ActiveActor ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + System::Write( F, Pad( FullName( PCelem ), MaxDeviceNameLength + 2 ) ); System::Write( F, j, 3 ); + for ( int stop = min( 3, (PCelem)->Get_NPhases() ), i = 1; i <= stop; i++) + { + k = ( j - 1 ) * Ncond + i; + Nref = PCelem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Iph[i] = c_Buffer[k - 1]; + Vph[i] = Volts; + } + if (((TDSSCktElement*)PCelem)->Get_NPhases() >= 3 ) + { + Phase2SymComp(&(Iph[1]), &(I012[1]) ); + Phase2SymComp(&(Vph[1]), &(V012[1]) ); + } + else + { // Handle single phase and pos seq models + V012[1] = CZero; + I012[1] = CZero; + V012[3] = CZero; + I012[3] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[2] = Vph[1]; + I012[2] = Iph[1]; + } + else + { + V012[2] = CZero; + I012[2] = CZero; + } + } + S = cmul( V012[2], conjg( I012[2] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[3], conjg( I012[3] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%11.1f", S.re * 0.003)); + System::Write( F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[1], conjg( I012[1] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, Format("%8.1f", S.re * 0.003)); + System::Write( F, Format("%8.1f", S.im * 0.003)); + System::WriteLn( F ); + } + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; /*ShowOptionCode=0*/ + case 1: + { + + /*Branch Powers*/ + System::WriteLn( F ); + System::WriteLn( F, "CIRCUIT ELEMENT POWER FLOW" ); + System::WriteLn( F ); + System::WriteLn( F, "(Power Flow into element from indicated Bus)" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Elements" ); + System::WriteLn( F ); + switch ( Opt ) + { + case 1: + { + System::Write( F, Pad( " Bus", MaxBusNameLength ) ); System::WriteLn( F, " Phase MW +j Mvar MVA PF" ); + } + break; + default: + { + System::Write( F, Pad( " Bus", MaxBusNameLength ) ); System::WriteLn( F, " Phase kW +j kvar kVA PF" ); + } + } + System::WriteLn( F ); + + // Sources first + p_Elem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Sources.Get_First(); + while (p_Elem != NULL) + { + if (p_Elem->Get_Enabled()) + { + Ncond = p_Elem->Get_NConds(); + Nterm = p_Elem->Get_NTerms(); + p_Elem->GetCurrents(&(c_Buffer[0]), ActiveActor); + k = 0; + FromBus = Pad(StripExtension(p_Elem->Get_FirstBus()), MaxBusNameLength); + System::Write(F, "ELEMENT = "); System::WriteLn(F, FullName(p_Elem)); + + for (int stop = Nterm, j = 1; j <= stop; j++) + { + Saccum = CZero; + for (int stop = Ncond, i = 1; i <= stop; i++) + { + ++k; + Nref = p_Elem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + S = cmul(Volts, conjg(c_Buffer[k - 1])); + if /* (p_Elem.nphases=1) and */ (ActiveCircuit[ActiveActor]->PositiveSequence) + S = cmulreal(S, 3.0); + if (Opt == 1) + S = cmulreal(S, 0.001); + caccum(Saccum, S); + System::Write(F, UpperCase(FromBus)); + System::Write(F, " "); + System::Write(F, GetNodeNum(p_Elem->NodeRef[k - 1]), 4); + System::Write(F, " "); + System::Write(F, Format("%8.1f", S.re / 1000.0)); + System::Write(F, " +j "); + System::Write(F, Format("%8.1f", S.im / 1000.0)); + System::Write(F, " "); + System::Write(F, Format("%8.1f", cabs(S) / 1000.0)); + System::Write(F, " "); + System::WriteLn(F, Format("%8.4f", PowerFactor(S))); + } + System::Write(F, Paddots(" TERMINAL TOTAL", MaxBusNameLength + 10)); + System::Write(F, Format("%8.1f", Saccum.re / 1000.0)); + System::Write(F, " +j "); + System::Write(F, Format("%8.1f", Saccum.im / 1000.0)); + System::Write(F, " "); + System::Write(F, Format("%8.1f", cabs(Saccum) / 1000.0)); + System::Write(F, " "); + System::WriteLn(F, Format("%8.4f", PowerFactor(Saccum))); + FromBus = Pad(StripExtension(p_Elem->Get_NextBus()), MaxBusNameLength); + } + System::WriteLn(F); + } + p_Elem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + // PDELEMENTS first + p_Elem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_First(); + int Ntimes = 0; + while (p_Elem != NULL) + { + if (p_Elem->Get_Enabled()) + { + Ncond = p_Elem->Get_NConds(); + Nterm = p_Elem->Get_NTerms(); + p_Elem->GetCurrents(&(c_Buffer[0]), ActiveActor); + k = 0; + FromBus = Pad(StripExtension(p_Elem->Get_FirstBus()), MaxBusNameLength); + System::Write(F, "ELEMENT = "); System::WriteLn(F, FullName(p_Elem)); + + if ((CLASSMASK & p_Elem->DSSObjType) == AUTOTRANS_ELEMENT) Ntimes = p_Elem->Get_NPhases(); + else Ntimes = Ncond; + + for (int stop = Nterm, j = 1; j <= stop; j++) + { + Saccum = CZero; + for (int stop = Ntimes, i = 1; i <= stop; i++) + { + ++k; + Nref = p_Elem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + S = cmul(Volts, conjg(c_Buffer[k - 1])); + if /* (p_Elem.nphases=1) and */ (ActiveCircuit[ActiveActor]->PositiveSequence) + S = cmulreal(S, 3.0); + if (Opt == 1) + S = cmulreal(S, 0.001); + caccum(Saccum, S); + System::Write(F, UpperCase(FromBus)); + System::Write(F, " "); + System::Write(F, GetNodeNum(p_Elem->NodeRef[k - 1]), 4); + System::Write(F, " "); + System::Write(F, Format("%8.1f", S.re / 1000.0)); + System::Write(F, " +j "); + System::Write(F, Format("%8.1f", S.im / 1000.0)); + System::Write(F, " "); + System::Write(F, Format("%8.1f", cabs(S) / 1000.0)); + System::Write(F, " "); + System::WriteLn(F, Format("%8.4f", PowerFactor(S))); + } + System::Write(F, Paddots(" TERMINAL TOTAL", MaxBusNameLength + 10)); + System::Write(F, Format("%8.1f", Saccum.re / 1000.0)); + System::Write(F, " +j "); + System::Write(F, Format("%8.1f", Saccum.im / 1000.0)); + System::Write(F, " "); + System::Write(F, Format("%8.1f", cabs(Saccum) / 1000.0)); + System::Write(F, " "); + System::WriteLn(F, Format("%8.4f", PowerFactor(Saccum))); + FromBus = Pad(StripExtension(p_Elem->Get_NextBus()), MaxBusNameLength); + + if ((CLASSMASK & p_Elem->DSSObjType) == AUTOTRANS_ELEMENT) k += Ntimes; + } + System::WriteLn(F); + } + p_Elem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + System::WriteLn(F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ="); + System::WriteLn(F); + System::WriteLn(F, "Power Conversion Elements"); + System::WriteLn(F); + switch (Opt) + { + case 1: + System::WriteLn(F, Pad(" Bus", MaxBusNameLength) + " Phase MW +j Mvar MVA PF"); + break; + default: + System::WriteLn(F, Pad(" Bus", MaxBusNameLength) + " Phase kW +j kvar kVA PF"); + } + System::WriteLn(F); + + // PCELEMENTS next + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + { + Ncond = p_Elem->Get_NConds(); + Nterm = p_Elem->Get_NTerms(); + p_Elem->GetCurrents(&(c_Buffer[0]), ActiveActor ); + k = 0; + FromBus = Pad( StripExtension( p_Elem->Get_FirstBus() ), MaxBusNameLength ); + System::Write( F, "ELEMENT = " ); System::WriteLn( F, FullName( p_Elem ) ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + Saccum = CZero; + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + k++; + Nref = p_Elem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + S = cmul( Volts, conjg( c_Buffer[k - 1] ) ); + if /* (p_Elem.nphases=1) and */ ( ActiveCircuit[ActiveActor]->PositiveSequence ) + S = cmulreal( S, 3.0 ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + caccum( Saccum, S ); + System::Write( F, UpperCase( FromBus ) ); + System::Write( F, " " ); + System::Write( F, GetNodeNum( p_Elem->NodeRef[k - 1] ), 4 ); + System::Write( F, " " ); + System::Write( F, Format("%6.1f", S.re / 1000.0)); + System::Write( F, " +j " ); + System::Write( F, Format("%6.1f", S.im / 1000.0)); + System::Write( F, " " ); + System::Write( F, Format("%8.1f", cabs(S) / 1000.0)); + System::Write( F, " " ); + System::WriteLn( F, Format("%8.4f", PowerFactor(S)) ); + } + System::Write( F, Paddots( " TERMINAL TOTAL ", MaxBusNameLength + 10 ) ); + System::Write( F, Format("%8.1f", Saccum.re / 1000.0 ) ); + System::Write( F, " +j " ); + System::Write( F, Format("%8.1f", Saccum.im / 1000.0) ); + System::Write( F, " " ); + System::Write( F, Format("%8.1f", cabs(Saccum) / 1000.0) ); + System::Write( F, " " ); + System::WriteLn( F, Format("%8.4f", PowerFactor( Saccum ))); + FromBus = Pad( StripExtension( p_Elem->Get_NextBus() ), MaxBusNameLength ); + } + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; /*ShowOptionCode=1*/ + default: {} + } /*CASE*/ + System::WriteLn( F ); + S = cmulreal( ActiveCircuit[ActiveActor]->Get_Losses(ActiveActor), 0.001 ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write( F, "Total Circuit Losses = " ); System::Write( F, Format("%6.1f",S.re)); System::Write(F, " +j "); System::WriteLn(F, Format("%6.1f", S.im)); + // } + // __finally + // { + if (!c_Buffer.empty()) + c_Buffer.clear(); + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + bool CheckBusReference( TDSSCktElement* cktElem, int BusReference, int& TerminalIndex ) + + /*Check all terminals of cktelement to see if bus connected to busreference*/ + { + bool result = false; + int i = 0; + result = false; + /*# with cktElem do */ + auto with0 = cktElem; + for ( int stop = with0->Get_NTerms(), i = 1; i <= stop; i++) + { + if ( with0->Terminals[i-1].BusRef == BusReference ) + { + TerminalIndex = i; + result = true; + break; + } + } + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void WriteTerminalPowerSeq( Textfile& F, TDSSCktElement* cktElem, int j, int Opt ) + { + int i = 0, + k = 0, + Ncond = 0, + Nref = 0; + complex Volts = cmplx(0,0), + S = cmplx(0,0); + complex Vph[4] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }, + V012[4] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }; + complex Iph[ 4] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }, + I012[4] = { cmplx(0,0), cmplx(0,0) ,cmplx(0,0) ,cmplx(0,0) }; + vector c_Buffer; // Allocate to max total conductors + + try + { + /*Allocate c_Buffer big enough for this circuit element*/ + c_Buffer.resize(cktElem->Yorder + 1); + Ncond = cktElem->Get_NConds(); + cktElem->GetCurrents( &c_Buffer[0], ActiveActor); + System::Write( F, Pad( FullName( cktElem ), MaxDeviceNameLength + 2 ) ); System::Write(F, j, 3 ); + for ( int stop = min( cktElem->Get_NPhases(), 3 ), i = 1; i <= stop; i++) + { + k = (j - 1) * Ncond + i; + Nref = cktElem->NodeRef[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + Iph[i-1] = c_Buffer[k-1]; + Vph[i-1] = Volts; + } + if ( cktElem->Get_NPhases() >= 3 ) + { + Phase2SymComp( &(Iph[0]), &(I012[0]) ); + Phase2SymComp( &(Vph[0]), &(V012[0]) ); } + else + { // Handle single phase and pos seq models + V012[0] = CZero; + I012[0] = CZero; + V012[2] = CZero; + I012[2] = CZero; + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + { + V012[1] = Vph[0]; + I012[1] = Iph[0]; + } + else + { + V012[1] = CZero; + I012[1] = CZero; + } + } + + + // Pos Seq or Single Phase + switch ( cktElem->Get_NPhases() ) + { + case 1: + S = cmul( Vph[1], conjg( Iph[1] ) ); + break; + case 2: + S = cadd( cmul( Vph[1], conjg( Iph[1] ) ), cmul( Vph[2], conjg( Iph[3] ) ) ); + break; + default: + S = cmul( V012[1], conjg( I012[1] ) ); + } + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write(F, Format("%11.1f",S.re * 0.003)); + System::Write(F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[2], conjg( I012[2] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write(F, Format("%11.1f", S.re * 0.003)); + System::Write(F, Format("%11.1f", S.im * 0.003)); + S = cmul( V012[0], conjg( I012[0] ) ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + System::Write(F, Format("%11.1f", S.re * 0.003)); + System::Write(F, Format("%11.1f", S.im * 0.003)); + System::WriteLn( F ); + // } + // __finally + // { + c_Buffer.resize(0); + } + catch (...) + { + // + } + } + + void WriteTerminalPower( Textfile& F, TDSSCktElement* cktElem, int jTerm, int Opt ) + { + int i = 0, k = 0, Ncond = 0, Nref = 0; + complex Volts, S; + complex Saccum; + pComplexArray c_Buffer; // Allocate to max total conductors + + String FromBus; + c_Buffer = NULL; + try + { + c_Buffer = (pComplexArray) malloc(sizeof(complex) * cktElem->Yorder); + Ncond = cktElem->Get_NConds(); + cktElem->GetCurrents( c_Buffer, ActiveActor ); + FromBus = Pad( StripExtension( cktElem->GetBus( jTerm ) ), 12 ); + System::Write(F, "ELEMENT = " ); System::WriteLn(F, Pad( FullName( cktElem ), MaxDeviceNameLength + 2 ) ); + Saccum = CZero; + for ( int stop = Ncond, i = 1; i <= stop; i++) + { + k = ( jTerm - 1 ) * Ncond + i; + Nref = (cktElem->NodeRef)[k - 1]; + Volts = ActiveCircuit[ActiveActor]->Solution->NodeV[Nref]; + S = cmul( Volts, conjg( (c_Buffer)[k - 1] ) ); + if /* (CktElem.nphases=1) and */ ( ActiveCircuit[ActiveActor]->PositiveSequence ) + S = cmulreal( S, 3.0 ); + if ( Opt == 1 ) + S = cmulreal( S, 0.001 ); + caccum( Saccum, S ); + System::WriteLn(F, Format( "%s %4d %10.5g +j %10.5g %10.5g %8.4f", UpperCase( FromBus ).c_str(), GetNodeNum((cktElem->NodeRef)[k - 1]), double(S.re) / 1000.0, double(S.im) / 1000.0, double(cabs(S)) / 1000.0, PowerFactor(S))); + } + System::WriteLn(F, Format( " TERMINAL TOTAL %10.5g +j %10.5g %10.5g %8.4f", double( Saccum.re ) / 1000.0, double( Saccum.im ) / 1000.0, double( cabs( Saccum ) ) / 1000.0, PowerFactor( Saccum ) )); + // } + // __finally + // { + if (( c_Buffer != NULL ) ) + free( c_Buffer ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowBusPowers( String Filenm, String BusName, int Opt, int ShowOptionCode ) + + /*Report power flow around a specified Bus*/ + + /*Opt = 0: kVA + opt = 1: MVA + */ + { + TTextRec F; + int j = 0, + Ncond = 0, + Nterm = 0, + BusReference = 0, + jTerm = 0; + TDSSCktElement* p_Elem = nullptr; + TPDElement* PDElem = nullptr; + TPCElement* PCelem = nullptr; + double I0 = 0.0, + I1 = 0.0, + I2 = 0.0, + Cmax = 0.0; + vector c_Buffer; // Allocate to max total conductors + + + SetMaxDeviceNameLength(); + + + /*Get Bus Reference*/ + BusReference = ActiveCircuit[ActiveActor]->BusList.Find( BusName ); + if ( BusReference == 0 ) + { + DoSimpleMsg( "Bus \"" + UpperCase( BusName ) + "\" not found.", 219 ); + return; + } + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Allocate c_Buffer big enough for largest circuit element*/ + c_Buffer.resize(GetMaxCktElementSize()); + switch ( ShowOptionCode ) + { + case 0: + { + + /*System::Write Bus Voltage*/ + System::WriteLn( F ); + System::WriteLn( F, "Bus V1 (kV) p.u. V2 (kV) %V2/V1 V0 (kV) %V0/V1" ); + System::WriteLn( F ); + WriteSeqVoltages( F, BusReference, false ); + + /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "SYMMETRICAL COMPONENT CURRENTS BY CIRCUIT ELEMENT (first 3 phases)" ); + System::WriteLn( F ); + System::WriteLn( F, "Element Term I1 I2 %I2/I1 I0 %I0/I1 %Normal %Emergency" ); + System::WriteLn( F ); + + // Sources first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + + /*Use j set by CheckBusReference*/ + Ncond = p_Elem->Get_NConds(); + Nterm = p_Elem->Get_NTerms(); + p_Elem->GetCurrents( &c_Buffer[0], ActiveActor); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, p_Elem->Get_NPhases(), ( j - 1 ) * Ncond, &c_Buffer[0]); + /*# with p_Elem do */ + WriteSeqCurrents( F, Paddots( FullName( p_Elem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, p_Elem->DSSObjType ); + } + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS next + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( PDElem->Get_Enabled() ) + if ( CheckBusReference( PDElem, BusReference, j ) ) + { // Is this connected to the bus + /*Use j set by CheckBusReference*/ + Ncond = PDElem->Get_NConds(); + Nterm = PDElem->Get_NTerms(); + PDElem->GetCurrents(&c_Buffer[0], ActiveActor ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, PDElem->Get_NPhases(), ( j - 1 ) * Ncond, &c_Buffer[0]); + /*# with PDElem do */ + WriteSeqCurrents( F, Paddots( FullName( PDElem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, PDElem->DSSObjType ); + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if (PCelem->Get_Enabled() ) + if ( CheckBusReference(PCelem, BusReference, j ) ) + { + Ncond = PCelem->Get_NConds(); + Nterm = PCelem->Get_NTerms(); + PCelem->GetCurrents(&c_Buffer[0], ActiveActor ); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + GetI0I1I2( I0, I1, I2, Cmax, PCelem->Get_NPhases(), ( j - 1 ) * Ncond, &c_Buffer[0]); + /*# with PCelem do */ + WriteSeqCurrents( F, Paddots( FullName( PCelem ), MaxDeviceNameLength + 2 ), I0, I1, I2, Cmax, 0.0, 0.0, j, PCelem->DSSObjType ); + } + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + + /*Sequence Powers */ + System::WriteLn( F ); + System::WriteLn( F, "SYMMETRICAL COMPONENT POWERS BY CIRCUIT ELEMENT (first 3 phases)" ); + System::WriteLn( F ); + switch ( Opt ) + { + case 1: + System::WriteLn( F, "Element Term P1(MW) Q1(Mvar) P2 Q2 P0 Q0 " ); + break; + default: + System::WriteLn( F, "Element Term P1(kW) Q1(kvar) P2 Q2 P0 Q0 " ); + } + System::WriteLn( F ); + + + + // Sources first ((TDSSCktElement*)PCelem)-> + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + /*Use j set by CheckBusReference*/ + WriteTerminalPowerSeq( F, p_Elem, j, Opt ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS next + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( (PDElem)->Get_Enabled() ) + if ( CheckBusReference(PDElem, BusReference, j ) ) + { // Is this connected to the bus + WriteTerminalPowerSeq( F, PDElem, j, Opt ); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + // PCELEMENTS Get_Next() + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( ((TDSSCktElement*)PCelem)->Get_Enabled() ) + if ( CheckBusReference(PCelem, BusReference, j ) ) + { + WriteTerminalPowerSeq( F, PCelem, j, Opt ); + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; /*ShowOptionCode=0 */ + case 1: + { + + /*System::Write Bus Voltage */ + System::WriteLn( F ); + System::WriteLn( F, " Bus (node ref) Node V (kV) Angle p.u. Base kV" ); + System::WriteLn( F ); + WriteBusVoltages( F, BusReference, false ); + + /*Element Currents --10*/ + System::WriteLn( F ); + System::WriteLn( F, "CIRCUIT ELEMENT CURRENTS" ); + System::WriteLn( F ); + System::WriteLn( F, "(Currents into element from indicated bus)" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Elements" ); + System::WriteLn( F ); + System::WriteLn( F, " Bus Phase Magnitude, A Angle (Real) +j (Imag)" ); + System::WriteLn( F ); + + + // Sources first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + WriteTerminalCurrents( F, p_Elem, false ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + WriteTerminalCurrents( F, p_Elem, true ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + System::WriteLn( F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Conversion Elements" ); + System::WriteLn( F ); + System::WriteLn( F, " Bus Phase Magnitude, A Angle (Real) +j (Imag)" ); + System::WriteLn( F ); + + // PCELEMENTS next + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + WriteTerminalCurrents( F, p_Elem, false ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + + // FAULTs next + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + WriteTerminalCurrents( F, p_Elem, false ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Faults.Get_Next(); + } + + /*Branch Powers */ + System::WriteLn( F ); + System::WriteLn( F, "CIRCUIT ELEMENT POWER FLOW" ); + System::WriteLn( F ); + System::WriteLn( F, "(Power Flow into element from indicated Bus)" ); + System::WriteLn( F ); + switch ( Opt ) + { + case 1: + System::WriteLn( F, " Bus Phase MW +j Mvar MVA PF" ); + break; + default: + System::WriteLn( F, " Bus Phase kW +j kvar kVA PF" ); + } + System::WriteLn( F ); + // Sources first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, j ) ) + { + WriteTerminalPower( F, p_Elem, j, Opt ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + + + // PDELEMENTS first + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, jTerm ) ) + { + WriteTerminalPower( F, p_Elem, jTerm, Opt ); + + /*Get the other buses for the report --18*/ + for ( int stop = p_Elem->Get_NTerms(), j = 1; j <= stop; j++) + if ( j != jTerm ) + { + System::WriteLn( F, "------------" ); + WriteTerminalPower( F, p_Elem, j, Opt ); + } + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + System::WriteLn( F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Conversion Elements" ); + System::WriteLn( F ); + switch ( Opt ) + { + case 1: + System::WriteLn( F, " Bus Phase MW +j Mvar MVA PF" ); + break; + default: + System::WriteLn( F, " Bus Phase kW +j kvar kVA PF" ); + } + System::WriteLn( F ); + + // PCELEMENTS next + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( p_Elem != NULL ) + { + if ( p_Elem->Get_Enabled() ) + if ( CheckBusReference( p_Elem, BusReference, jTerm ) ) + { + WriteTerminalPower( F, p_Elem, jTerm, Opt ); + System::WriteLn( F ); + } + p_Elem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; /*ShowOptionCode=1 */ + default: {} + } /*CASE*/ + // } + // __finally + // { + c_Buffer.clear(); + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowFaultStudy( String Filenm ) + { + int i = 0, + iBus = 0, + iphs = 0, + iphs2 = 0; + TcMatrix YFault, + ZFault; + vector Vfault; /*Big temp array*/ + TTextRec F = {}; + complex GFault = CZero, + IFault = CZero; + double Vphs = 0.0, + CurrMag = 0.0; + String S = ""; + SetMaxBusNameLength(); + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /* Set source voltage injection currents */ + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = ActiveCircuit[ActiveActor]->Solution; + { + /*# with Solution do */ + { + + /*All Phase Faults*/ + System::WriteLn( F, "FAULT STUDY REPORT" ); + System::WriteLn( F ); + System::WriteLn( F, "ALL-Node Fault Currents" ); + System::WriteLn( F ); + string Fheader = Pad("Bus", MaxBusNameLength) + "Node" + Pad(" ", 12) + "Amps" + Pad(" ", 3) + "X/R " + + "Node" + Pad(" ", 12) + "Amps" + Pad(" ", 3) + "X/R " + "Node" + Pad(" ", 12) + "Amps" + Pad(" ", 3) + "X/R ..."; + System::WriteLn( F, Fheader); + System::WriteLn( F ); + for ( int stop = with0->NumBuses, iBus = 1; iBus <= stop; iBus++) + /*Bus Norton Equivalent Current, Isc has been previously computed*/ + /*# with Buses^[iBus] do */ + { + auto& with2 = with0->Buses[iBus - 1]; + { + System::Write( F, Pad( EncloseQuotes( UpperCase(with0->BusList.Get( iBus ) ) ) + " ", MaxBusNameLength + 2)); + for ( int stop = with2->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + CurrMag = cabs( with2->BusCurrent[i - 1] ); + if ( i > 1 ) + System::Write( F, " " ); + System::Write(F, with2->GetNum(i)); + System::Write(F, " "); + System::Write( F, Format("%15.0f", CurrMag)); + if ( CurrMag > 0.0 ) + { + System::Write( F, " " ); System::Write( F, Format("%5.1f", GetXR(cdiv(with2->VBus[i - 1], with2->BusCurrent[i - 1])))); + } + else + System::Write( F, " N/A" ); + } + System::WriteLn( F ); + } + } + System::WriteLn( F ); + + // One Phase Faults + System::WriteLn( F ); + System::WriteLn( F, "ONE-Node to ground Faults" ); + System::WriteLn( F ); + System::WriteLn( F, " pu Node Voltages (L-N Volts if no base)" ); + System::Write( F, Pad( "Bus", MaxBusNameLength ) ); System::WriteLn( F, " Node Amps Node 1 Node 2 Node 3 ..." ); + System::WriteLn( F ); + + // Solve for Fault Injection Currents + for ( int stop = with0->NumBuses, iBus = 1; iBus <= stop; iBus++) + //Bus Norton Equivalent Current, Isc has been previously computed + // # with Buses^[iBus] do + { + auto& with2 = with0->Buses[iBus - 1]; + { + ZFault = TcMatrix(with2->get_FNumNodesThisBus() ); + ZFault.CopyFrom(&with2->Zsc ); + for ( int stop = with2->get_FNumNodesThisBus(), iphs = 1; iphs <= stop; iphs++) + { + IFault = cdiv( (with2->VBus)[iphs - 1], with2->Zsc.GetElement( iphs, iphs ) ); + S = Format( "%s %4u %12.0f ", Pad( EncloseQuotes( UpperCase(with0->BusList.Get( iBus ) ) ).c_str(), MaxBusNameLength + 2).c_str(), with2->GetNum(iphs), cabs(IFault)); + System::Write( F, S ); System::Write( F, " " ); + for ( int stop = with2->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + Vphs = cabs( csub( (with2->VBus)[i - 1], cmul(with2->Zsc.GetElement( i, iphs ), IFault ) ) ); + if (with2->kVBase > 0.0 ) + { + Vphs = 0.001 * Vphs / with2->kVBase; + System::Write( F, ' ' ); System::Write( F, Format("%10.3f", Vphs)); + } + else + { + System::Write( F, ' ' ); System::Write( F, Format("%10.1f",Vphs)); + } + } + System::WriteLn( F ); + } // For iphase + // Now, Stuff it in the Css Array where it belongs + } + } // With bus + + // Node-Node Faults + System::WriteLn( F ); + System::WriteLn( F, "Adjacent Node-Node Faults" ); + System::WriteLn( F ); + System::WriteLn( F, " pu Node Voltages (L-N Volts if no base)" ); + System::WriteLn( F, "Bus Node-Node Amps Node 1 Node 2 Node 3 ..." ); + System::WriteLn( F ); + + // Solve for Fault Injection Currents + for ( int stop = with0->NumBuses, iBus = 1; iBus <= stop; iBus++) + // Bus Norton Equivalent Current, Isc has been previously computed + // # with Buses^[iBus] do + { + auto& with3 = with0->Buses[iBus - 1]; + { + YFault = TcMatrix(with3->get_FNumNodesThisBus() ); + Vfault.resize(with3->get_FNumNodesThisBus() + 1); + GFault = cmplx( 10000.0, 0.0 ); + + for ( int stop = with3->get_FNumNodesThisBus(), iphs = 1; iphs <= stop; iphs++) + { + for (iphs2 = 1; iphs2 <= with3->get_FNumNodesThisBus(); iphs2++) + { + if (iphs < iphs2) + { + YFault.CopyFrom(&(with3->Ysc)); + YFault.AddElement(iphs, iphs, GFault); + YFault.AddElement(iphs2, iphs2, GFault); + YFault.AddElemsym(iphs, iphs2, cnegate(GFault)); + + // Solve for Injection Currents + YFault.Invert(); + YFault.MVmult(&Vfault[0], &(with3->BusCurrent[0])); // Gets voltage appearing at fault + System::Write(F, Pad(EncloseQuotes(UpperCase(with0->BusList.Get(iBus))), MaxBusNameLength + 2)); + System::Write(F, with3->GetNum(iphs), 4); + System::Write(F, with3->GetNum(iphs2), 4); + System::Write(F, Format("%12.0f", cabs(cmul(csub(Vfault[iphs - 1], Vfault[iphs2 - 1]), GFault)))); + System::Write(F, " "); + for (int stop = with3->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + Vphs = cabs(Vfault[i - 1]); + if (with3->kVBase > 0.0) + { + Vphs = 0.001 * Vphs / with3->kVBase; + System::Write(F, ' '); System::Write(F, Format("%10.3f", Vphs)); + } + else + { + System::Write(F, ' '); System::Write(F, Format("%10.1f", Vphs)); + } + } + System::WriteLn(F); + } + } + } //For iphase + // Now, Stuff it in the Css Array where it belongs + Vfault.clear(); + } + } // With bus + } // With Solution + } + } // With ActiveCircuit[ActiveActor] + // } + // __finally + // { + + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void WriteElementRecord( Textfile& F, TDSSCktElement* pElem ) + { + int Nterm = 0, + j = 0; + String BusName = ""; + String EName = ""; + + Nterm = pElem->Get_NTerms(); + BusName = Pad( StripExtension( pElem->Get_FirstBus() ), MaxBusNameLength ); + System::Write(F, Pad( FullName( pElem ), MaxDeviceNameLength + 2 ) ); + System::Write(F," "); + for ( int stop = Nterm, j = 1; j <= stop; j++) + { + System::Write(F, UpperCase(BusName)); + System::Write(F," "); + BusName = Pad( StripExtension( pElem->Get_NextBus() ), MaxBusNameLength ); + } + System::WriteLn( F ); + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowElements( String Filenm, String ClassName ) + + // Show Elements and bus connections + + { + TTextRec F = {}, + FDisabled = {}; + int i = 0; + String DisabledFileNm = ""; + TDSSCktElement* pElem = nullptr; + + SetMaxBusNameLength(); + SetMaxDeviceNameLength(); + try + { + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + } + catch( std::exception & E ) + { + DoSimpleMsg( String( "Error Trying to open element file \"" ) + Filenm + "\" file:" + (std::string) E.what(), 219000 ); + } + try + { + DisabledFileNm = StripExtension( Filenm ) + "_Disabled.txt"; + AssignFile( FDisabled, DisabledFileNm ); + Rewrite( FDisabled ); + IOResultToException(); + } + catch (std::exception &E) + { + DoSimpleMsg( String( "Error Trying to open disabled element file \"" ) + DisabledFileNm + "\" file:" + (std::string) E.what(), 219000 ); + } + if ( ClassName.size( ) > 0 ) + { // Just give a list of Active elements of a particular Class + if ( SetObjectClass( ClassName ) ) + { + System::Write( F, "All Elements in Class \"" ); System::Write( F, ClassName ); System::WriteLn( F, '\"' ); + System::WriteLn( F ); + System::Write( FDisabled, "All DISABLED Elements in Class \"" ); System::Write( FDisabled, ClassName ); System::WriteLn( FDisabled, '\"' ); + System::WriteLn( FDisabled ); + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get( LastClassReferenced[ActiveActor] ); + for ( int stop = ActiveDSSClass[ActiveActor]->Get_ElementCount(), i = 1; i <= stop; i++) + { + ActiveDSSClass[ActiveActor]->Set_Active(i); + if ( ( ( ActiveDSSClass[ActiveActor]->DSSClassType & BaseClassMask ) ) > 0 ) + { + if (((TDSSCktElement*)ActiveDSSObject[ActiveActor])->Get_Enabled()) + System::WriteLn( F, UpperCase( (( TDSSCktElement* ) ActiveDSSObject[ActiveActor] )->get_Name() ) ); + else + System::WriteLn( FDisabled, UpperCase( ( ( TDSSCktElement* ) ActiveDSSObject[ActiveActor] )->get_Name() ) ); + } + else + System::WriteLn( F, UpperCase(((TDSSCktElement*)ActiveDSSObject[ActiveActor])->get_Name()) ); // non cktelements + } + } + } + else + { // Default - Just do PD and PC Element in active circuit + System::WriteLn( F ); + System::WriteLn( F, "Elements in Active Circuit: " + ActiveCircuit[ActiveActor]->Get_Name() ); + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element", MaxDeviceNameLength + 2 ) ); System::Write( F, Pad( " Bus1", MaxBusNameLength ) ); System::Write( F, Pad( " Bus2", MaxBusNameLength ) ); System::Write( F, Pad( " Bus3", MaxBusNameLength ) ); System::WriteLn( F, " ..." ); + System::WriteLn( F ); + System::WriteLn( FDisabled ); + System::WriteLn( FDisabled, "DISABLED Elements in Active Circuit: " + ActiveCircuit[ActiveActor]->Get_Name() ); + System::WriteLn( FDisabled ); + System::WriteLn( FDisabled, "DISABLED Power Delivery Elements" ); + System::WriteLn( FDisabled ); + System::Write( FDisabled, Pad( "DISABLED Element", MaxDeviceNameLength + 2 ) ); System::Write( FDisabled, Pad( " Bus1", MaxBusNameLength ) ); System::Write( FDisabled, Pad( " Bus2", MaxBusNameLength ) ); System::Write( FDisabled, Pad( " Bus3", MaxBusNameLength ) ); System::WriteLn( FDisabled, " ..." ); + System::WriteLn( FDisabled ); + + // PDELEMENTS first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( ASSIGNED(pElem) ) + { + if ( pElem->Get_Enabled() ) + { + WriteElementRecord( F, pElem ); + } + else + { + WriteElementRecord(FDisabled, pElem); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + + System::WriteLn( F ); + System::WriteLn( F, "Power Conversion Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element", MaxDeviceNameLength + 2 ) ); System::Write( F, Pad( " Bus1", MaxBusNameLength ) ); System::Write( F, Pad( " Bus2", MaxBusNameLength ) ); System::Write( F, Pad( " Bus3", MaxBusNameLength ) ); System::WriteLn( F, " ..." ); + System::WriteLn( F ); + + + System::WriteLn( FDisabled ); + System::WriteLn( FDisabled, "DISABLED Power Conversion Elements" ); + System::WriteLn( FDisabled ); + System::Write( FDisabled, Pad( "DISABLED Element", MaxDeviceNameLength + 2 ) ); System::Write( FDisabled, Pad( " Bus1", MaxBusNameLength ) ); System::Write( FDisabled, Pad( " Bus2", MaxBusNameLength ) ); System::Write( FDisabled, Pad( " Bus3", MaxBusNameLength ) ); + System::WriteLn(FDisabled, " ..." ); + System::WriteLn( FDisabled ); + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + { + WriteElementRecord( F, pElem ); + } + else + { + WriteElementRecord( FDisabled, pElem ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + + } + // } + // __finally + // { + CloseFile(FDisabled); + if (AutoDisplayShowReport) + FireOffEditor( DisabledFileNm ); + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowBuses( String Filenm ) + + // Show bus names and nodes in uses + + { + TTextRec F; + int i = 0, j = 0; + try + { + SetMaxBusNameLength(); + MaxBusNameLength += 2; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F ); + System::WriteLn( F, "BUSES AND NODES IN ACTIVE CIRCUIT: " + ActiveCircuit[ActiveActor]->Get_Name() ); + System::WriteLn( F ); + System::Write( F, Pad( " ", MaxBusNameLength ) ); System::WriteLn( F, " Coord Number of Nodes" ); + System::Write( F, Pad( " Bus", MaxBusNameLength ) ); System::WriteLn( F, " Base kV (x, y) Keep? Nodes connected ..." ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + System::Write( F, Pad( EncloseQuotes( with0->BusList.Get( i ) ), MaxBusNameLength ) ); System::Write( F, ' ' ); + TDSSBus& pBus (*( with0->Buses[i - 1] )); + if ( pBus.kVBase > 0.0 ) + System::Write( F, Format("%8.3f",(pBus.kVBase * SQRT3))); + else + System::Write( F, " NA " ); + System::Write( F, " (" ); + if ( pBus.CoordDefined ) + System::Write( F, Format( " %-13.11g, %-13.11g)", pBus.x, pBus.y )); + else + System::Write( F, " NA, NA )" ); + if ( pBus.Keep ) + System::Write( F, " Yes " ); + else + System::Write( F, " No " ); + System::Write( F, " " ); + System::Write( F, pBus.get_FNumNodesThisBus(), 5 ); + System::Write( F, " " ); + for ( int stop = pBus.get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + System::Write( F, pBus.GetNum( j ), 4 ); System::Write( F, ' ' ); + } + System::WriteLn( F ); + } + } + } + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowMeters( String Filenm ) + + // Show Values of Meter Elements + + { + TTextRec F; + int i = 0, j = 0; + TEnergyMeterObj* pElem; + TEnergyMeter* MeterClass; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F ); + System::WriteLn( F, "ENERGY METER VALUES" ); + System::WriteLn( F ); + System::WriteLn( F, "Registers:" ); + MeterClass = (TEnergyMeter*) GetDSSClassPtr( "Energymeter" ); + if ( MeterClass == NULL ) + return; // oops somewhere!! + if ( ( (TDSSClass*) MeterClass )->Get_ElementCount() == 0 ) + { + System::WriteLn( F, "No Energymeter Elements Defined." ); + } + else + { ; + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); // write registernames for first meter only + for ( int stop = NumEMRegisters, i = 1; i <= stop; i++) + { + System::Write( F, "Reg " + IntToStr( i ) + " = " ); System::WriteLn( F, pElem->RegisterNames[i - 1] ); + } + System::WriteLn( F ); + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + if ( pElem != NULL ) + { + System::Write( F, "Meter " ); + for ( int stop = NumEMRegisters, i = 1; i <= stop; i++) + System::Write( F, Pad( " Reg " + IntToStr( i ), 11 ) ); + System::WriteLn( F ); + System::WriteLn( F ); + while ( pElem != NULL ) + { + if ( ( (TMeterElement*) pElem )->Get_Enabled() ) + { + System::Write( F, Pad( ( ( TMeterElement* )pElem )->get_Name(), 12 ) ); + + + for ( int stop = NumEMRegisters, j = 1; j <= stop; j++) + { + System::Write( F, Format("%8.0f", pElem->Registers[j - 1])); System::Write(F, ' '); + } + } + pElem = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + System::WriteLn( F ); + } + } + } + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + /// + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowGenMeters( String Filenm ) + + // Show Values of Generator Meter Elements + + { + TTextRec F; + int i = 0, j = 0; + TGeneratorObj* pElem; + TGenerator* GeneratorClass; + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + System::WriteLn(F); + System::WriteLn(F, "GENERATOR ENERGY METER VALUES"); + System::WriteLn(F); + pElem = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_First(); + if (pElem != NULL) + { + GeneratorClass = (TGenerator*)pElem->ParentClass; + System::Write(F, "Generator "); + for (int stop = Generator::NumGenRegisters, i = 1; i <= stop; i++) + System::Write(F, Pad(GeneratorClass->RegisterNames[i - 1], 11)); + System::WriteLn(F); + System::WriteLn(F); + while (pElem != NULL) + { + if (((TDSSCktElement*)pElem)->Get_Enabled()) + { + System::Write(F, Pad(((TDSSCktElement*)pElem)->get_Name(), 12)); + auto with0 = ActiveCircuit[ActiveActor]->Solution; + pElem->Registers[0] = pElem->kWBase; + pElem->Registers[1] = pElem->kvarBase; + pElem->Registers[4] = with0->IntervalHrs; + pElem->Registers[5] = ActiveCircuit[ActiveActor]->PriceSignal; + + for (int stop = Generator::NumGenRegisters-1, j = 0; j <= stop; j++) + { + if (pElem->Registers[j] < -6.2e+10) + { + System::Write(F, 0); System::Write(F, ' '); + } + else + { + System::Write(F, Format("%8.0f", pElem->Registers[j])); System::Write(F, ' '); + } + } + } + pElem = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_Next(); + System::WriteLn(F); + } + } + // } + // __finally + // { + CloseFile(F); + if (AutoDisplayShowReport) + FireOffEditor(Filenm); + ParserVars->Add("@lastshowfile", Filenm); + } + catch (...) + { + // + } + } + + + int TapPosition( TTransfObj* Transformer, int iWind ) + + /*Assumes 0 is 1.0 per unit tap*/ + { + int result = 0; + /*# with Transformer do */ + auto with0 = Transformer; + result = Round( double( ( with0->Get_PresentTap(iWind,ActiveActor) - double( ( with0->Get_MaxTap(iWind) + with0->Get_MinTap(iWind) ) ) / 2.0 ) ) / with0->Get_TapIncrement(iWind) ); + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowRegulatorTaps( String Filenm ) + { + TTextRec F; + TRegControlObj* pReg; + int iWind = 0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F ); + System::WriteLn( F, "CONTROLLED TRANSFORMER TAP SETTINGS" ); + System::WriteLn( F ); + System::WriteLn( F, "Name RegControl Tap Min Max Step Position Winding Direction CogenMode" ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + pReg = (TRegControlObj*) with0->RegControls.Get_First(); + while ( pReg != NULL ) + { + /*# with pReg.Transformer do */ + { + auto with1 = pReg->Get_Transformer(); + iWind = pReg->Get_Winding(); + //System::Write( F, Pad( ( (TDSSObject*) with1 )->get_Name(), 12 ) ); System::Write( F, ' ' ); + System::Write( F, Pad( ( with1 )->get_Name(), 12 ) ); System::Write( F, ' ' ); + System::Write(F, pReg->LName); System::Write(F, " "); + + string direction = ""; + if (with1->DeltaDirection == 1) direction = "Forward"; + else direction = "Backwards"; + + System::Write(F, Format("%8.5f %8.5f %8.5f %8.5f %d %d", with1->Get_PresentTap(iWind, ActiveActor), with1->Get_MinTap(iWind), with1->Get_MaxTap(iWind), with1->Get_TapIncrement(iWind), TapPosition(pReg->Get_Transformer(), iWind), iWind)); + string CGEn = " "; + System::Write(F, CGEn); + System::Write(F, direction); + if (pReg->CogenEnabled) CGEn += "True"; else CGEn += "False"; + System::Write(F, CGEn); + System::Write(F, "\n"); + } + pReg = (TRegControlObj*) with0->RegControls.Get_Next(); + } + } + } + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ShowMeterZone( String Filenm ) + { + TTextRec F; + int i = 0; + TEnergyMeterObj* pMtr = nullptr; + TEnergyMeterObj* pMeter = nullptr; + TEnergyMeter* pMtrClass = nullptr; + TPDElement* PDElem = nullptr; + TLoadObj* LoadElem = nullptr; + String ParamName = "", + Param = ""; + try + { + Filenm = StripExtension( Filenm ); + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + Filenm = Filenm + "_" + Param + ".txt"; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + GlobalResult = Filenm; + pMtrClass = (TEnergyMeter*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "energymeter" ) ); + if ( Param.size( ) > 0 ) + { + pMtr = (TEnergyMeterObj*) pMtrClass->Find( Param ); + if ( pMtr == NULL ) + DoSimpleMsg( String( "EnergyMeter \"" ) + Param + "\" not found.", 220 ); + else + if ( pMtr->BranchList != NULL ) + { + System::Write( F, "Branches and Load in Zone for EnergyMeter " ); System::WriteLn( F, Param ); + System::WriteLn( F ); + PDElem = (TPDElement* ) pMtr->BranchList->Get_First(); + while ( PDElem != NULL ) + { + for ( int stop = pMtr->BranchList->Get_Level(), i = 1; i <= stop; i++) + System::Write( F, TABCHAR ); + //System::Write(F, pMtr.BranchList.Level:0,' '); + System::Write( F,PDElem->ParentClass->get_myClass_name() ); + System::Write( F, '.' ); + System::Write( F, PDElem->LName); + /*# with pMtr.BranchList.PresentBranch do */ + { + auto with0 = pMtr->BranchList->PresentBranch; + if ( with0->IsParallel ) + System::Write( F, "(PARALLEL:" + ( (TDSSCktElement*) with0->LoopLineObj )->get_Name() + ")" ); + if (with0->IsLoopedHere ) + System::Write( F, "(LOOP:" + ((TDSSCktElement*)with0->LoopLineObj)->ParentClass->get_myClass_name() + "." + ( (TDSSCktElement*) with0->LoopLineObj )->get_Name() + ")" ); + } + if (( PDElem->SensorObj != NULL ) ) + System::Write( F, " (Sensor: " + PDElem->SensorObj->ParentClass->get_myClass_name() + "." + PDElem->SensorObj->get_Name() + ") " ); + else + System::Write( F, " (Sensor: NIL)" ); + + System::WriteLn( F ); + LoadElem = (TLoadObj*) pMtr->BranchList->Get_FirstObject(); + while (LoadElem != NULL) + { + for (int stop = pMtr->BranchList->Get_Level() + 1, i = 1; i <= stop; i++) + System::Write(F, TABCHAR); + System::Write(F, LoadElem->ParentClass->get_myClass_name()); System::Write(F, '.'); System::Write(F, LoadElem->get_Name()); + if (ASSIGNED(LoadElem->SensorObj)) + System::Write(F, " (Sensor: " + LoadElem->SensorObj->ParentClass->get_myClass_name() + "." + LoadElem->SensorObj->get_Name() + ") "); + else + System::Write(F, " (Sensor: NIL)"); + System::WriteLn(F); + LoadElem = (TLoadObj*)pMtr->BranchList->Get_NextObject(); + } + PDElem = (TPDElement*)pMtr->BranchList->Get_Forward(); + } + } + } + else + DoSimpleMsg( "Meter Name Not Specified." + CRLF + Parser[ActiveActor]->get_CmdBuffer(), 221 ); + // } + // __finally + // { + CloseFile( F ); + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + switch ( Param.size( ) ) + { + case 0: + { + if (AutoDisplayShowReport) + FireOffEditor(Filenm); + } + break; + default: + ShowTreeView( Filenm ); + } + ParserVars->Add( "@lastshowfile", Filenm ); + // + } + catch (...) + { + // + } + } + + void ShowOverloads( String Filenm ) + { + TTextRec F; + vector c_Buffer; // Allocate to max total conductors + + int Ncond = 0, + i = 0, + j = 0, + k = 0; + TPDElement* PDElem = nullptr; + complex Iph[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }, + I012[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + double I0 = 0.0, + I1 = 0.0, + I2 = 0.0, + cmag = 0.0, + Cmax = 0.0; + + SetMaxDeviceNameLength(); + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Allocate c_Buffer big enough for largest circuit element*/ + c_Buffer.resize(GetMaxCktElementSize() + 1); + + /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Element Overload Report" ); + System::WriteLn( F ); + System::WriteLn( F, "SYMMETRICAL COMPONENT CURRENTS BY CIRCUIT ELEMENT " ); + System::WriteLn( F ); + System::WriteLn( F, "Element Term I1 IOver %Normal %Emerg I2 %I2/I1 I0 %I0/I1" ); + System::WriteLn( F ); + + + + // PDELEMENTS + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( ( (TDSSCktElement*) PDElem )->Get_Enabled() ) + if // Ignore capacitors + ( ( ( CLASSMASK & ((TDSSCktElement*)PDElem)->DSSObjType ) ) != CAP_ELEMENT ) + { + Ncond = ((TDSSCktElement*)PDElem)->Get_NConds(); + PDElem->GetCurrents( &c_Buffer[0], ActiveActor); + for ( int stop = 1, j = 1; j <= stop; j++) // Check only terminal 1 for overloads + { + if (((TDSSCktElement*)PDElem)->Get_NPhases() >= 3 ) + { + Cmax = 0.0; + for ( int stop = 3, i = 0; i < stop; i++) + { + k = ( j - 1 ) * Ncond + i + 1; + Iph[i] = (c_Buffer)[k-1]; + cmag = cabs( Iph[i] ); + if ( cmag > Cmax ) + Cmax = cmag; + } + Phase2SymComp( & Iph[0], &I012[0]); + I0 = cabs( I012[0] ); + I1 = cabs( I012[1] ); + I2 = cabs( I012[2] ); + } + else + { + I0 = 0.0; + I1 = cabs( c_Buffer[1 + ( j - 1 ) * Ncond] ); + I2 = 0.0; + Cmax = I1; + } + if ( ( PDElem->NormAmps > 0.0 ) || ( PDElem->EmergAmps > 0.0 ) ) + if ( ( Cmax > PDElem->NormAmps ) || ( Cmax > PDElem->EmergAmps ) ) + { + System::Write( F, Pad( FullName( PDElem ), MaxDeviceNameLength + 2 ) ); System::Write( F, j, 3 ); + System::Write( F, Format("%8.1f", I1)); + if ( PDElem->NormAmps > 0.0 ) + System::Write( F, Format("%8.2f", Cmax - PDElem->NormAmps )); + else + System::Write( F, " 0.0" ); + if ( PDElem->NormAmps > 0.0 ) + System::Write( F, Format("%8.1f", Cmax / PDElem->NormAmps * 100.0)); + else + System::Write( F, " 0.0" ); + if ( PDElem->EmergAmps > 0.0 ) + System::Write( F, Format("%8.1f", Cmax / PDElem->EmergAmps * 100.0)); + else + System::Write( F, " 0.0" ); + System::Write( F, Format("%8.1f", I2)); + if ( I1 > 0.0 ) + System::Write( F, Format("%8.1f", 100.0 * I2 / I1)); + else + System::Write( F, " 0.0" ); + System::Write( F, Format("%8.1f", I0)); + if ( I1 > 0.0 ) + System::Write( F, Format("%8.1f", 100.0 * I0 / I1)); + else + System::Write( F, " 0.0" ); + System::WriteLn( F ); + } + } /*For*/ + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + // } + // __finally + // { + c_Buffer.resize(0); + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + /* - -- - - - - ------------------------------*/ + + + void ShowUnserved( String Filenm, bool UE_Only ) + { + TTextRec F; + TLoadObj* pLoad; + bool DoIt = false; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F ); + System::WriteLn( F, "UNSERVED LOAD REPORT" ); + System::WriteLn( F ); + System::WriteLn( F, "Load Element Bus Load kW EEN Factor UE Factor" ); + System::WriteLn( F ); + + // Load + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while ( pLoad != NULL ) + { + if ( ( (TDSSCktElement*) pLoad)->Get_Enabled() ) + { + DoIt = false; + if ( UE_Only ) + { + if ( pLoad->Get_Unserved(ActiveActor) ) + DoIt = true; + } + else + if ( pLoad->Get_ExceedsNormal( ActiveActor ) ) + DoIt = true; + if ( DoIt ) + { + //pLoad->Get_Unserved(ActiveActor); + //pLoad->Get_ExceedsNormal(ActiveActor); + System::Write( F, Pad( pLoad->get_Name(), 20)); + System::Write( F, Pad( ( (TDSSCktElement*) pLoad )->GetBus( 1 ), 10 ) ); + System::Write( F, Format("%8.0f", pLoad->kWBase)); + System::Write( F, Format("%8.3f", pLoad->EEN_Factor)); + System::Write( F, Format("%8.3f", pLoad->UE_Factor)); + System::WriteLn( F ); + } + } + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowLosses( String Filenm ) + { + TTextRec F; + TPDElement* PDElem = nullptr; + TPCElement* PCelem = nullptr; + complex kLosses = cmplx(0, 0), + TotalLosses = cmplx(0, 0), + LineLosses = cmplx(0, 0), + TransLosses = cmplx(0, 0), + TermPower = cmplx(0, 0), + LoadPower = cmplx(0, 0); + SetMaxDeviceNameLength(); + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "LOSSES REPORT" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Element Loss Report" ); + System::WriteLn( F ); + System::WriteLn( F, "Element kW Losses % of Power kvar Losses" ); + System::WriteLn( F ); + TotalLosses = CZero; + LineLosses = CZero; + TransLosses = CZero; + + // PDELEMENTS + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if + /*THEN IF (CLASSMASK AND PDElem.DSSObjType) <> CAP_ELEMENT */ // Ignore capacitors + ( ( PDElem )->Get_Enabled() ) + { + //----PDelem.ActiveTerminalIdx := 1; // activate 1st terminal for Power call + kLosses = cmulreal( ( PDElem )->Get_Losses(ActiveActor), 0.001 ); // kW Losses in element + caccum( TotalLosses, kLosses ); + TermPower = cmulreal( ( PDElem )->Get_Power(1, ActiveActor), 0.001 ); // Terminal 1 power + if ( ( ( CLASSMASK & ( PDElem )->DSSObjType ) ) == XFMR_ELEMENT ) caccum( TransLosses, kLosses ); + if ( ( ( CLASSMASK & (PDElem)->DSSObjType ) ) == AUTOTRANS_ELEMENT ) caccum( TransLosses, kLosses ); + if ( ( ( CLASSMASK & (PDElem)->DSSObjType ) ) == LINE_ELEMENT ) caccum( LineLosses, kLosses ); + + System::Write( F, Pad( FullName( PDElem ), MaxDeviceNameLength + 2 ) ); + System::Write( F, Format( "%10.5f, ", kLosses.re )); + + if ( ( TermPower.re != 0.0 ) && ( kLosses.re > 0.0009 ) ) + System::Write(F, Format("%8.2f", (kLosses.re / Abs(TermPower.re)) * 100.0)); + else + System::Write( F, Format("%8.1f", CZero.re)); + + System::Write( F, Format( " %.6g", kLosses.im )); + System::WriteLn( F ); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } /*While*/ + System::WriteLn( F ); + System::Write( F, Pad( "LINE LOSSES=", 30 ) ); System::Write( F, Format("%10.1f", LineLosses.re)); System::WriteLn(F, " kW"); + System::Write( F, Pad( "TRANSFORMER LOSSES=", 30 ) ); System::Write( F, Format("%10.1f", TransLosses.re)); System::WriteLn( F, " kW" ); + System::WriteLn( F ); + System::Write( F, Pad( "TOTAL LOSSES=", 30 ) ); System::Write( F, Format("%10.1f", TotalLosses.re)); System::WriteLn( F, " kW" ); + LoadPower = CZero; + // Sum the total load kW being served in the Ckt Model + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while ( PCelem != NULL ) + { + if ( ( PCelem )->Get_Enabled() ) + { + caccum( LoadPower, ( PCelem )->Get_Power(1, ActiveActor) ); + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + LoadPower = cmulreal( LoadPower, 0.001 ); + System::WriteLn( F ); + System::Write( F, Pad( "TOTAL LOAD POWER = ", 30 ) ); System::Write( F, Format("%10.1f", Abs( LoadPower.re ))); System::WriteLn( F, " kW" ); + System::Write( F, Pad( "Percent Losses for Circuit = ", 30 ) ); + if ( LoadPower.re != 0.0 ) + { + System::Write( F, Format("%8.2f", Abs(TotalLosses.re / LoadPower.re ) * 100.0)); System::WriteLn( F, " %" ); + } + // } + // __finally + // { + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + + void ShowVariables( String Filenm ) + { + TTextRec F; + TPCElement* PCelem; + int i = 0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Sequence Currents*/ + System::WriteLn( F ); + System::WriteLn( F, "VARIABLES REPORT" ); + System::WriteLn( F ); + System::WriteLn( F, "Present values of all variables in PC Elements in the circuit." ); + System::WriteLn( F ); + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( PCelem->Get_Enabled() && ( PCelem->NumVariables() > 0 ) ) + { + System::Write( F, "ELEMENT: " ); System::Write( F, PCelem->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, PCelem->get_Name() ); + System::Write( F, "No. of variables: " ); System::WriteLn( F, PCelem->NumVariables(), 0 ); + for ( int stop = PCelem->NumVariables(), i = 1; i <= stop; i++) + { + string varname = PCelem->VariableName(i); + if (PCelem->Get_Variable(i) < 1.2e-10 || PCelem->Get_Variable(i) > 1.2e+10) + { + //PCelem->Set_Variable(i,0); + System::Write(F, " "); System::Write(F, PCelem->VariableName(i)); System::Write(F, " = "); System::WriteLn(F, 0); + } + else + { + System::Write(F, " "); System::Write(F, PCelem->VariableName(i)); System::Write(F, " = "); System::WriteLn(F, Format("%1.6g", PCelem->Get_Variable(i))); + } + } + System::WriteLn( F ); + } + PCelem = (TPCElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowIsolated( String Filenm ) + + /*Show isolated buses/branches in present circuit*/ + { + TCktTree* Branch_List = nullptr; + TCktTree* SubArea = nullptr; // Pointers to all circuit elements + + TTextRec F = {}; + TDSSCktElement* TestElement = nullptr; + TDSSCktElement* TestBranch = nullptr; + TDSSCktElement* pElem = nullptr; + int i = 0, + j = 0; + + // Make sure bus list is built + if ( ActiveCircuit[ActiveActor]->get_FBusNameRedefined() ) + ActiveCircuit[ActiveActor]->ReProcessBusDefs( ActiveActor ); + ActiveCircuit[ActiveActor]->ReProcessBusDefs( ActiveActor ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + + /*Initialize all Circuit Elements to not checked*/ + TestElement = (TDSSCktElement*) with0->CktElements.Get_First(); + while ( TestElement != NULL ) + { + /*# with TestElement do */ + auto with1 = TestElement; + { + with1->Checked = false; + for ( int stop = with1->Get_NTerms(), i = 1; i <= stop; i++) + with1->Terminals[i - 1].Checked = false; + } + TestElement = (TDSSCktElement*) with0->CktElements.Get_Next(); + } + + // initialize the Checked Flag for all Buses + for ( int stop = with0->NumBuses, j = 1; j <= stop; j++) + with0->Buses[j - 1]->BusChecked = false; + } + } + + // Get Started at main voltage source + TestElement = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + Branch_List = (TCktTree*)( GetIsolatedSubArea( TestElement ) ); + + /*Show Report of Elements connected and not connected*/ + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F ); + System::WriteLn( F, "ISOLATED CIRCUIT ELEMENT REPORT" ); + System::WriteLn( F ); + System::WriteLn( F ); + System::WriteLn( F, "*** THE FOLLOWING BUSES HAVE NO CONNECTION TO THE SOURCE ***" ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with1 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with1->NumBuses, j = 1; j <= stop; j++) + if ( ! with1->Buses[j - 1]->BusChecked ) + System::WriteLn( F, EncloseQuotes( with1->BusList.Get( j ) ) ); + } + } + System::WriteLn( F ); + System::WriteLn( F, "*********** THE FOLLOWING SUB NETWORKS ARE ISOLATED ************" ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with2 = ActiveCircuit[ActiveActor]; + { + TestElement = (TDSSCktElement*) with2->CktElements.Get_First(); + while ( ASSIGNED(TestElement) ) + { + if ( TestElement->Get_Enabled() ) + if ( ! TestElement->Checked ) + if ( ( ( TestElement->DSSObjType & BaseClassMask ) ) == PD_ELEMENT ) + { + SubArea = (TCktTree*)( GetIsolatedSubArea( TestElement ) ); + System::WriteLn( F, "*** START SUBAREA ***" ); + TestBranch = (TDSSCktElement*) SubArea->Get_First(); + while ( TestBranch != NULL ) + { + System::Write( F, '(' ); System::Write( F, SubArea->Get_Level(), 0 ); System::Write( F, ") " ); System::Write( F, TestBranch->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, TestBranch->get_Name() ); + pElem = (TDSSCktElement*) SubArea->Get_FirstObject(); + while ( pElem != NULL ) + { + System::Write( F, "[SHUNT], " ); System::Write( F, pElem->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, pElem->get_Name() ); + pElem = (TDSSCktElement*) SubArea->Get_NextObject(); + } + TestBranch = (TDSSCktElement*) SubArea->Get_Forward(); + } + delete SubArea; // SubArea->~TCktTree(); + System::WriteLn( F ); + } + TestElement = (TDSSCktElement*) with2->CktElements.Get_Next(); + } + } + } + System::WriteLn( F ); + System::WriteLn( F, "*********** THE FOLLOWING ENABLED ELEMENTS ARE ISOLATED ************" ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with3 = ActiveCircuit[ActiveActor]; + { + + /*Mark all controls, energy meters and monitors as checked so they don't show up*/ + for ( int stop = with3->DSSControls.get_myNumList(), i = 1; i <= stop; i++) + ((TDSSCktElement*) with3->DSSControls.Get( i ) )->Checked = true; + + for ( int stop = with3->MeterElements.get_myNumList(), i = 1; i <= stop; i++) + ( (TDSSCktElement*) with3->MeterElements.Get( i ) )->Checked = true; + + TestElement = (TDSSCktElement*) with3->CktElements.Get_First(); + while ( TestElement != NULL ) + { + if ( TestElement->Get_Enabled() ) + if ( ! TestElement->Checked ) + { + System::Write( F, '\"' ); System::Write( F, TestElement->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::Write( F, TestElement->get_Name() ); System::Write( F, '\"' ); + System::Write( F, " Buses:" ); + for ( int stop = TestElement->Get_NTerms(), j = 1; j <= stop; j++) + { + System::Write( F, " \"" ); System::Write( F, TestElement->GetBus( j ) ); System::Write( F, '\"' ); + } + System::WriteLn( F ); + } + TestElement = (TDSSCktElement*) with3->CktElements.Get_Next(); + } + } + } + System::WriteLn( F ); + System::WriteLn( F, "*** THE FOLLOWING BUSES ARE NOT CONNECTED TO ANY POWER DELIVERY ELEMENT ***" ); + System::WriteLn( F ); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with4 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with4->NumBuses, j = 1; j <= stop; j++) + if ( ! with4->Buses[j - 1]->BusChecked ) + System::WriteLn( F, EncloseQuotes( with4->BusList.Get( j ) ) ); + } + } + System::WriteLn( F ); + System::WriteLn( F, "*********** CONNECTED CIRCUIT ELEMENT TREE ************" ); + System::WriteLn( F ); + System::WriteLn( F, "(Lexical Level) Element name" ); + System::WriteLn( F ); + TestBranch = (TDSSCktElement*) Branch_List->Get_First(); + while ( TestBranch != NULL ) + { + System::Write( F, '(' ); System::Write( F, Branch_List->Get_Level(), 0 ); System::Write( F, ") " ); System::Write( F, TestBranch->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, TestBranch->get_Name() ); + TestElement = (TDSSCktElement*) Branch_List->Get_FirstObject(); + while ( TestElement != NULL ) + { + System::Write( F, "[SHUNT], " ); System::Write( F, TestElement->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, TestElement->get_Name() ); + TestElement = (TDSSCktElement*) Branch_List->Get_NextObject(); + } + TestBranch = (TDSSCktElement*) Branch_List->Get_Forward(); + } + /* } + __finally + {*/ + CloseFile( F ); + free(Branch_List); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowRatings( String Filenm ) + { + TTextRec F; + TPDElement* PDElem; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F, "Power Delivery Elements Normal and Emergency (max) Ratings" ); + System::WriteLn( F ); + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + System::Write( F, '\"' ); System::Write( F, (PDElem )->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::Write( F, PDElem->get_Name() ); System::Write( F, "\", normamps=" ); + System::Write( F, Format( "%-.4g, %-.4g !Amps", PDElem->NormAmps, PDElem->EmergAmps )); + System::WriteLn( F ); + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + + void ShowLoops( String Filenm ) + /*Show loops and paralleled branches in Meter zones*/ + { + TTextRec F; + TPDElement* PDElem; + int hMeter = 0; + TEnergyMeterObj* pMtr; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F, "Loops and Paralleled Lines in all EnergyMeter Zones" ); + System::WriteLn( F ); + hMeter = EnergyMeterClass[ActiveActor]->Get_First(); + while ( hMeter > 0 ) + { + pMtr = (TEnergyMeterObj*)ActiveDSSObject[ActiveActor]; + if ( pMtr->BranchList!= NULL ) + { + PDElem = (TPDElement*)pMtr->BranchList->Get_First(); + + while ( PDElem != NULL ) + { + auto with0 = pMtr->BranchList->PresentBranch; + + if (with0 != NULL) + { + if (with0->IsParallel) + { + System::Write(F, '('); + System::Write(F, pMtr->get_Name()); + System::Write(F, ") "); + System::Write(F, PDElem->ParentClass->get_myClass_name()); + System::Write(F, '.'); + System::Write(F, UpperCase(PDElem->get_Name())); + System::Write(F, ": PARALLEL WITH "); + System::Write(F, ((TDSSCktElement*)with0->LoopLineObj)->ParentClass->get_myClass_name()); + System::Write(F, '.'); System::WriteLn(F, ((TDSSCktElement*)with0->LoopLineObj)->get_Name()); + } + if (with0->IsLoopedHere) + { + System::Write(F, '('); + System::Write(F, pMtr->get_Name()); + System::Write(F, ") "); + System::Write(F, PDElem->ParentClass->get_myClass_name()); + System::Write(F, '.'); + System::Write(F, UpperCase(PDElem->get_Name())); System::Write(F, ": LOOPED TO "); + System::Write(F, ((TDSSCktElement*)with0->LoopLineObj)->ParentClass->get_myClass_name()); + System::Write(F, '.'); System::WriteLn(F, ((TDSSCktElement*)with0->LoopLineObj)->get_Name()); + } + } + PDElem = (TPDElement*)pMtr->BranchList->Get_Forward(); + } + } + hMeter = ( (TDSSClass*) EnergyMeterClass[ActiveActor] )->Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void TopoLevelTabs( Textfile& F, int nLevel ) + { + int nTabs = 0, i = 0; + nTabs = 30; + if ( nLevel < nTabs ) + nTabs = nLevel; + for ( int stop = nTabs, i = 1; i <= stop; i++) + { + System::Write(F,TABCHAR ); + } + if ( nLevel > nTabs ) + { + System::Write(F, Format( "(* %d *)", nLevel )); + } + } + + + void ShowTopology( String Fileroot ) + { + TTextRec F, Ftree; + String Filenm, TreeNm; + TPDElement* PDElem; + TDSSCktElement* pControlElem; + TLoadObj* LoadElem; + TCktTree* Topo; + int nLoops = 0, nParallel = 0, nLevels = 0, nIsolated = 0, nSwitches = 0; + try + { + Filenm = Fileroot + "TopoSumm.Txt"; + TreeNm = Fileroot + "TopoTree.Txt"; + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F, "Topology analysis for switch control algorithms" ); + System::WriteLn( F ); + AssignFile( Ftree, TreeNm ); + Rewrite( Ftree ); + IOResultToException(); + System::WriteLn( Ftree, "Branches and Loads in Circuit " + ActiveCircuit[ActiveActor]->Get_Name() ); + System::WriteLn( Ftree ); + Topo = &(ActiveCircuit[ActiveActor]->GetTopology()); + nLoops = 0; + nParallel = 0; + nLevels = 0; + nIsolated = 0; + nSwitches = 0; + if (( Topo != NULL ) ) + { + PDElem = (TPDElement*) Topo->Get_First(); + while (( PDElem != NULL ) ) + { + if ( Topo->Get_Level() > nLevels ) + nLevels = Topo->Get_Level(); + TopoLevelTabs( Ftree, Topo->Get_Level() ); + System::Write( Ftree, ( (TDSSCktElement*) PDElem )->ParentClass->get_myClass_name() ); System::Write( Ftree, '.' ); System::Write( Ftree, ( (TDSSCktElement*) PDElem )->get_Name() ); + /*# with Topo.PresentBranch do */ + { + auto with0 = Topo->PresentBranch; + if ( with0->IsParallel ) + { + nParallel++; + System::Write( Ftree, "(PARALLEL:" + ( (TDSSCktElement*) with0->LoopLineObj )->get_Name() + ")" ); + } + if ( with0->IsLoopedHere ) + { + nLoops++; + System::Write( Ftree, "(LOOP:" + ( (TDSSCktElement*) with0->LoopLineObj )->ParentClass->get_myClass_name() + "." + ( (TDSSCktElement*) with0->LoopLineObj )->get_Name() + ")" ); + } + if ( ( (TDSSCktElement*) PDElem )->HasSensorObj ) + System::Write( Ftree, "Sensor: " + PDElem->SensorObj->ParentClass->get_myClass_name() + PDElem->SensorObj->get_Name() + "." + ") "); + if ( ( (TDSSCktElement*) PDElem )->HasControl ) + { + pControlElem = (TDSSCktElement*) ( (TDSSCktElement*) PDElem )->ControlElementList.Get_First(); + while ( pControlElem != NULL ) + { // accommodate multiple controls on same branch + System::Write( Ftree," (Control: " + pControlElem->ParentClass->get_myClass_name() + "." + pControlElem->get_Name() + ") "); + if ( ( ( pControlElem->DSSObjType & CLASSMASK ) ) == SWT_CONTROL ) + nSwitches++; + pControlElem = (TDSSCktElement*) ( (TDSSCktElement*) PDElem )->ControlElementList.Get_Next(); + } + } + if ( ( (TDSSCktElement*) PDElem )->HasEnergyMeter ) + System::Write( Ftree, " (Meter:" + PDElem->MeterObj->get_Name() + ") "); + } + System::WriteLn( Ftree ); + LoadElem = (TLoadObj*) Topo->Get_FirstObject(); + while (( LoadElem != NULL ) ) + { + TopoLevelTabs( Ftree, Topo->Get_Level() + 1 ); + System::Write( Ftree, ( (TDSSCktElement*) LoadElem )->ParentClass->get_myClass_name() ); System::Write( Ftree, '.' ); System::Write( Ftree, ( (TDSSCktElement*) LoadElem )->get_Name() ); + if ( ( (TDSSCktElement*) LoadElem )->HasSensorObj ) + System::Write( Ftree, " (Sensor: " + LoadElem->SensorObj->ParentClass->get_myClass_name() + "." + LoadElem->SensorObj->get_Name() + ") "); + if ( ( (TDSSCktElement*) LoadElem )->HasControl ) + { + pControlElem = (TDSSCktElement*) ( (TDSSCktElement*) LoadElem )->ControlElementList.Get_First(); + while ( pControlElem != NULL ) + { // accommodate multiple controls on same branch + System::Write( Ftree, " (Control: " + pControlElem->ParentClass->get_myClass_name() + "." + pControlElem->get_Name() + ") "); + if ( ( ( pControlElem->DSSObjType & CLASSMASK ) ) == SWT_CONTROL ) + nSwitches++; + pControlElem = (TDSSCktElement*) ( (TDSSCktElement*) LoadElem )->ControlElementList.Get_Next(); + } + } + if ( ( (TDSSCktElement*) LoadElem )->HasEnergyMeter ) + System::Write( Ftree, " (Meter: " + LoadElem->MeterObj->get_Name() + ") "); + System::WriteLn( Ftree ); + LoadElem = (TLoadObj*) Topo->Get_NextObject(); + } + PDElem = (TPDElement*) Topo->Get_Forward(); + } + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while (( PDElem != NULL ) ) + { + if ( ( PDElem )->IsIsolated ) + { + System::Write( Ftree, "Isolated: " + ( PDElem )->ParentClass->get_myClass_name() + ( PDElem )->get_Name() ); + if ((PDElem)->HasSensorObj ) + System::Write( Ftree, " (Sensor: " + PDElem->SensorObj->ParentClass->get_myClass_name() + PDElem->SensorObj->get_Name() + "." + ") " ); + if ((PDElem)->HasControl ) + { + pControlElem = (TDSSCktElement*) (PDElem)->ControlElementList.Get_First(); + while ( pControlElem != NULL ) + { // accommodate multiple controls on same branch + System::Write( Ftree, " (Control: " + pControlElem->ParentClass->get_myClass_name() + "." + pControlElem->get_Name() + ") "); + if ( ( ( pControlElem->DSSObjType & CLASSMASK ) ) == SWT_CONTROL ) + nSwitches++; + pControlElem = (TDSSCktElement*)PDElem->ControlElementList.Get_Next(); + } + } + if ((PDElem)->HasEnergyMeter ) + System::Write( Ftree, " (Meter: " + PDElem->MeterObj->get_Name() + ") " ); + System::WriteLn( Ftree ); + nIsolated++; + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + nLoops = nLoops / 2; // TODO, see if parallel lines also counted twice + System::WriteLn( F, Format( "%d Levels Deep", nLevels )); + System::WriteLn( F, Format( "%d Loops", nLoops )); + System::WriteLn( F, Format( "%d Parallel PD elements", nParallel )); + System::WriteLn( F, Format( "%d Isolated PD components", nIsolated )); + System::WriteLn( F, Format( "%d Controlled Switches", nSwitches )); + /* } + __finally + {*/ + CloseFile( F ); + CloseFile( Ftree ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + ShowTreeView( TreeNm ); + } + catch (...) + { + // + } + } + + void ShowLineConstants( String Filenm, double Freq, int Units, double Rho ) + { + TTextRec F, F2; + int p = 0, + i = 0, + j = 0; + TLineGeometryObj* pElem = nullptr; + TcMatrix Z, YC; + complex ZS, + ZM, + Z1, + Z0; + complex YCM; + double w = 0.0, + CS = 0.0, + CM = 0.0, + C1 = 0.0, + C0 = 0.0, + XCM = 0.0, + CCM = 0.0; // Common mode capacitance + + String LineCodesFileNm; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F, "LINE CONSTANTS" ); + System::WriteLn( F, Format( "Frequency = %.6g Hz, Earth resistivity = %.6g ohm-m", Freq, Rho )); + System::Write( F, "Earth Model = " ); System::WriteLn( F, GetEarthModel( DefaultEarthModel ) ); + System::WriteLn( F ); + LineCodesFileNm = "LineConstantsCode.DSS"; + AssignFile( F2, LineCodesFileNm ); + Rewrite( F2 ); + IOResultToException(); + System::WriteLn( F2, "!--- OpenDSS Linecodes file generated from Show LINECONSTANTS command" ); + System::WriteLn( F2, Format( "!--- Frequency = %.6g Hz, Earth resistivity = %.6g ohm-m", Freq, Rho )); + System::Write( F2, "!--- Earth Model = " ); System::WriteLn( F2, GetEarthModel( DefaultEarthModel ) ); + LineGeometryClass = (TLineGeometry*) DSSClassList[ActiveActor].Get( ClassNames[ActiveActor].Find( "LineGeometry" ) ); + ActiveEarthModel[ActiveActor] = DefaultEarthModel; + p = ( (TDSSClass*) LineGeometryClass )->Get_First(); + while ( p > 0 ) + { + pElem = (TLineGeometryObj*) ((TDSSClass*)LineGeometryClass)->GetActiveObj(); + try + { + // Get impedances per unit length + pElem->Set_RhoEarth(Rho); + Z = *pElem->Get_Zmatrix(Freq,1.0, Units); + YC = *pElem->Get_YCmatrix(Freq,1.0, Units); + } + catch( std::exception & E ) + { + DoSimpleMsg( "Error computing line constants for LineGeometry." + ( (TDSSObject*) pElem )->get_Name() + "; Error message: " + (std::string) E.what(), 9934 ); + } + System::WriteLn( F ); + System::WriteLn( F, "--------------------------------------------------" ); + System::Write( F, "Geometry Code = " ); System::WriteLn( F, ( (TDSSObject*) pElem )->get_Name() ); + System::WriteLn( F ); + System::Write( F, "R MATRIX, ohms per " ); System::WriteLn( F, LineUnitsStr( Units ) ); + for ( int stop = Z.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%.6g, ", Z.GetElement( i, j ).re )); + } + System::WriteLn( F ); + } + System::WriteLn( F ); + System::Write( F, "jX MATRIX, ohms per " ); System::WriteLn( F, LineUnitsStr( Units ) ); + for ( int stop = Z.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%.6g, ", Z.GetElement( i, j ).im )); + } + System::WriteLn( F ); + } + System::WriteLn( F ); + System::Write( F, "Susceptance (jB) MATRIX, S per " ); System::WriteLn( F, LineUnitsStr( Units ) ); + for ( int stop = YC.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%.6g, ", YC.GetElement( i, j ).im )); + } + System::WriteLn( F ); + } + w = double( Freq ) * TwoPi / 1.0E3; + System::WriteLn( F ); + System::Write( F, "L MATRIX, mH per " ); System::WriteLn( F, LineUnitsStr( Units ) ); + for ( int stop = Z.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%.6g, ", double( Z.GetElement( i, j ).im ) / w )); + } + System::WriteLn( F ); + } + w = double( Freq ) * TwoPi / 1.0E9; + System::WriteLn( F ); + System::Write( F, "C MATRIX, nF per " ); System::WriteLn( F, LineUnitsStr( Units ) ); + for ( int stop = YC.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%.6g, ", double( YC.GetElement( i, j ).im ) / w )); + } + System::WriteLn( F ); + } + + /*System::Write DSS LineCode record*/ + //System::Writeln(F); + //System::Writeln(F,'-------------------------------------------------------------------'); + //System::Writeln(F,'-------------------DSS Linecode Definition-------------------------'); + //System::Writeln(F,'-------------------------------------------------------------------'); + System::WriteLn( F2 ); + System::WriteLn( F2, Format("New Linecode.%s nphases=%d Units=%s", pElem->get_Name().c_str(), Z.get_Norder(), LineUnitsStr(Units).c_str())); + System::Write( F2, "~ Rmatrix=[" ); + for ( int stop = Z.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + System::Write( F2, Format( "%.6g ", Z.GetElement( i, j ).re )); + if ( i < Z.get_Norder() ) + System::Write( F2, '|' ); + } + System::WriteLn( F2, ']' ); + System::Write( F2, "~ Xmatrix=[" ); + for ( int stop = Z.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + System::Write( F2, Format( "%.6g ", Z.GetElement( i, j ).im )); + if ( i < Z.get_Norder() ) + System::Write( F2, '|' ); + } + System::WriteLn( F2, ']' ); + w = double( Freq ) * TwoPi / 1.0E9; + System::Write( F2, "~ Cmatrix=[" ); + for ( int stop = YC.get_Norder(), i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + System::Write( F2, Format( "%.6g ", double( YC.GetElement( i, j ).im ) / w )); + if ( i < YC.get_Norder() ) + System::Write( F2, '|' ); + } + System::WriteLn( F2, ']' ); + + /*Add pos- and zero-sequence approximation here*/ + /*Kron reduce to 3 phases first*/ + /*Average diagonals and off-diagonals*/ + ZS = CZero; + ZM = CZero; + CS = 0.0; + CM = 0.0; + if ( Z.get_Norder() == 3 ) + { + System::WriteLn( F ); + System::WriteLn( F, "-------------------------------------------------------------------" ); + System::WriteLn( F, "-------------------Equiv Symmetrical Component --------------------" ); + System::WriteLn( F, "-------------------------------------------------------------------" ); + System::WriteLn( F ); + for ( int stop = 3, i = 1; i <= stop; i++) + caccum( ZS, Z.GetElement( i, i ) ); + for ( int stop = 3, i = 1; i <= stop; i++) + for ( int stop = i - 1, j = 1; j <= stop; j++) + caccum( ZM, Z.GetElement( i, j ) ); + Z1 = cdivreal( csub( ZS, ZM ), 3.0 ); + Z0 = cdivreal( cadd( cmulreal( ZM, 2.0 ), ZS ), 3.0 ); + w = double( Freq ) * TwoPi / 1000.0; + System::WriteLn( F ); + System::Write( F, "Z1, ohms per " ); System::Write( F, LineUnitsStr( Units ) ); System::WriteLn( F, Format( " = %.6g + j %.6g (L1 = %.6g mH) ", Z1.re, Z1.im, double( Z1.im ) / w )); + System::Write( F, "Z0, ohms per " ); System::Write( F, LineUnitsStr( Units ) ); System::WriteLn( F, Format( " = %.6g + j %.6g (L0 = %.6g mH) ", Z0.re, Z0.im, double( Z0.im ) / w )); + System::WriteLn( F ); + + /*Compute Common Mode Series Impedance*/ + Z.Invert(); + YCM = CZero; + for ( int stop = 3, i = 1; i <= stop; i++) // Add up all elements of Z inverse + for ( int stop = 3, j = 1; j <= stop; j++) + caccum( YCM, Z.GetElement( i, j ) ); + XCM = cinv( YCM ).im; + w = double( Freq ) * TwoPi / 1.0E9; + /*Capacitance*/ + for ( int stop = 3, i = 1; i <= stop; i++) + CS = CS + YC.GetElement( i, i ).im; + for ( int stop = 3, i = 1; i <= stop; i++) + for ( int stop = i - 1, j = 1; j <= stop; j++) + CM = CM + YC.GetElement( i, j ).im; + C1 = ( CS - CM ) / 3.0 / w; // nF + C0 = ( CS + 2.0 * CM ) / 3.0 / w; + + /*Compute Common Mode Shunt Capacitance*/ + YCM = CZero; + for ( int stop = 3, i = 1; i <= stop; i++) // Add up all elements of Z inverse + for ( int stop = 3, j = 1; j <= stop; j++) + caccum( YCM, YC.GetElement( i, j ) ); + CCM = double( YCM.im ) / w; + System::Write( F, "C1, nF per " ); System::Write( F, LineUnitsStr( Units ) ); System::WriteLn( F, Format( " = %.6g", C1 )); + System::Write( F, "C0, nF per " ); System::Write( F, LineUnitsStr( Units ) ); System::WriteLn( F, Format( " = %.6g", C0 )); + System::WriteLn( F ); + w = Freq * TwoPi; + System::WriteLn( F, "Surge Impedance:" ); + System::WriteLn( F, Format( " Positive sequence = %.6g ohms", sqrt( double( Z1.im ) / w / ( C1 * 1.0e-9) ) )); + System::WriteLn( F, Format( " Zero sequence = %.6g ohms", sqrt( double( Z0.im ) / w / ( C0 * 1.0e-9) ) )); + System::WriteLn( F, Format( " Common Mode = %.6g ohms", sqrt( XCM / w / ( CCM * 1.0e-9) ) )); + System::WriteLn( F ); + System::WriteLn( F, "Propagation Velocity (Percent of speed of light):" ); + System::WriteLn( F, Format( " Positive sequence = %.6g ", double( 1.0 ) / ( sqrt( double( Z1.im ) / w * ( C1 * 1.0e-9) ) ) / 299792458.0 / To_per_Meter( Units ) * 100.0 )); + System::WriteLn( F, Format( " Zero sequence = %.6g ", double( 1.0 ) / ( sqrt( double( Z0.im ) / w * ( C0 * 1.0e-9) ) ) / 299792458.0 / To_per_Meter( Units ) * 100.0 )); + System::WriteLn( F ); + } + p = ((TDSSClass*)LineGeometryClass)->Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + CloseFile( F2 ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + if (AutoDisplayShowReport) + FireOffEditor( LineCodesFileNm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowYPrim( String Filenm ) + { + TTextRec F; + pComplexArray cValues; + int i = 0, j = 0; + if ( ActiveCircuit[ActiveActor] != NULL ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + if ( with0->get_FActiveCktElement() != NULL ) + { + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*# with ActiveCktElement do */ + { + auto with1 = with0->get_FActiveCktElement(); + System::Write( F, "Yprim of active circuit element: " ); System::Write( F, with1->ParentClass->get_myClass_name() ); System::Write( F, '.' ); System::WriteLn( F, with1->get_Name() ); + System::WriteLn( F ); + cValues = with1->GetYPrimValues( ALL_YPRIM ); + if ( cValues != NULL ) + { + System::WriteLn( F ); + System::WriteLn( F, "G matrix (conductance), S" ); + System::WriteLn( F ); + for ( int stop = with1->Yorder, i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + System::Write( F, Format( "%13.10g ", (cValues-1)[i + ( j - 1 ) * with1->Yorder].re )); + System::WriteLn( F ); + } + System::WriteLn( F ); + System::WriteLn( F, "jB matrix (Susceptance), S" ); + System::WriteLn( F ); + for ( int stop = with1->Yorder, i = 1; i <= stop; i++) + { + for ( int stop = i, j = 1; j <= stop; j++) + System::Write( F, Format( "%13.10g ", (cValues-1)[i + ( j - 1 ) * with1->Yorder].im )); + System::WriteLn( F ); + } + } + else + System::WriteLn( F, "Yprim matrix is Nil" ); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + } + } + } + + // shows how to retrieve the System Y in Triplet form + + + + void ShowY( String Filenm ) + { + TTextRec F; + klusparseset_t hY; + unsigned int nNZ = 0, NBus = 0; + unsigned int i = 0, Row = 0, col = 0; + double re = 0.0, im = 0.0; + unsigned int* ColIdx; + unsigned int* RowIdx; + complex* cVals; + if ( ActiveCircuit[ActiveActor] == NULL ) + return; + hY = ActiveCircuit[ActiveActor]->Solution->hY; + if ( ! hY ) + { + DoSimpleMsg( "Y Matrix not Built.", 222 ); + return; + } + // print lower triangle of G and B using new functions + // this compresses the entries if necessary - no extra work if already solved + FactorSparseMatrix( hY ); + GetNNZ( hY, &nNZ ); + GetSize( hY, &NBus ); // we should already know this + try + { + ColIdx = new unsigned[nNZ]; + RowIdx = new unsigned[nNZ]; + cVals = new complex[nNZ]; + GetTripletMatrix( hY, nNZ, RowIdx, ColIdx, cVals ); + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + System::WriteLn( F, "System Y Matrix (Lower Triangle by Columns)" ); + System::WriteLn( F ); + System::WriteLn( F, " Row Col G B" ); + System::WriteLn( F ); + + // shows how to easily traverse the triplet format + for ( int stop = nNZ - 1, i = 0; i <= stop; i++) + { + col = ColIdx[i] + 1; + Row = RowIdx[i] + 1; + if ( Row >= col ) + { + re = cVals[i].re; + im = cVals[i].im; + System::WriteLn( F, Format( "[%4d,%4d] = %13.10g + j%13.10g", Row, col, re, im )); + } + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowNodeCurrentSum( String Filenm ) + { + + + TTextRec F; + int i = 0, + j = 0, + k = 0, + Nref = 0; + String Bname = "", + pctError = ""; + TDSSCktElement* pCktElement = nullptr; + vector MaxNodeCurrent; + complex Ctemp = CZero; + + double dTemp = 0.0; + + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor]->Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with2 = ActiveCircuit[ActiveActor]->Solution; + { + // Zero out the nodal current array + for (i = 0; i <= with0->NumNodes; i++) + with2->Currents[i] = CZero; + // Make temp storage for max current at node + MaxNodeCurrent.resize(with0->NumNodes + 1); + for (i = 0; i <= with0->NumNodes; i++) + MaxNodeCurrent[i] = 0.0; + // Now Sum in each device current, keep track of the largest current at a node. + pCktElement = (TDSSCktElement*) with0->CktElements.Get_First(); + while ( pCktElement != NULL ) + { + if ( pCktElement->Get_Enabled() ) + /*# with pCktElement do */ + { + auto with1 = pCktElement; + with1->ComputeIterminal( ActiveActor ); + if ( ( CLASSMASK & with1->DSSObjType ) == AUTOTRANS_ELEMENT ) + { + k = 0; /*Special for Autotransformer*/ + for ( int stop = with1->Get_NTerms(), i = 0; i <= stop; i++) + { + for ( int stop = with1->Get_NPhases(), j = 0; j <= stop; j++) + { + + Ctemp = (with1->Iterminal)[k]; + Nref = (with1->NodeRef)[k]; + caccum(with2->Currents[Nref], Ctemp ); // Noderef=0 is OK + if ( cabs( Ctemp ) > MaxNodeCurrent[Nref] ) + MaxNodeCurrent[Nref] = cabs( Ctemp ); + k++; + } + k += with1->Get_NPhases(); + } + } + else + for (i = 1; i <= with1->Yorder; i++) + { + Ctemp = with1->Iterminal[i - 1]; + Nref = with1->NodeRef[i - 1]; + caccum( with2->Currents[Nref], Ctemp ); // Noderef=0 is OK + if ( cabs( Ctemp ) > MaxNodeCurrent[Nref] ) + MaxNodeCurrent[Nref] = cabs( Ctemp ); + } + } + pCktElement = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + + // Now write report + SetMaxBusNameLength(); + MaxBusNameLength = MaxBusNameLength + 2; + System::WriteLn( F ); + System::WriteLn( F, "Node Current Mismatch Report" ); + System::WriteLn( F ); + System::WriteLn( F ); + System::Write( F, Pad( "Bus,", MaxBusNameLength ) ); System::WriteLn( F, " Node, \"Current Sum (A)\", \"%error\", \"Max Current (A)\"" ); + + // Ground Bus + Nref = 0; + dTemp = cabs( with2->Currents[Nref] ); + if ( ( MaxNodeCurrent[Nref] == 0.0 ) || ( MaxNodeCurrent[Nref] == dTemp ) ) + pctError = Format( "%10.1f", 0.0 ); + else + pctError = Format( "%10.6f", dTemp / MaxNodeCurrent[Nref] * 100.0 ); + Bname = Pad( "\"System Ground\"", MaxBusNameLength ); + System::WriteLn( F, Format( "%s, %2d, %10.5f, %s, %10.5f", Bname.c_str(), Nref, dTemp, pctError.c_str(), MaxNodeCurrent[Nref] )); + for ( int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + for ( int stop = with0->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + Nref = with0->Buses[i - 1]->GetRef( j ); + dTemp = cabs( with2->Currents[Nref] ); + if ( ( MaxNodeCurrent[Nref] == 0.0 ) || ( MaxNodeCurrent[Nref] == dTemp ) ) + pctError = Format( "%10.1f", 0.0 ); + else + pctError = Format( "%10.6f", dTemp / MaxNodeCurrent[Nref] * 100.0 ); + if ( j == 1 ) + Bname = Paddots( EncloseQuotes(with0->BusList.Get( i ) ), MaxBusNameLength ); + else + Bname = Pad( "\" -\"", MaxBusNameLength ); + System::WriteLn( F, Format( "%s, %2d, %10.5f, %s, %10.5f", Bname.c_str(), with0->Buses[i - 1]->GetNum( j ), dTemp, pctError.c_str(), MaxNodeCurrent[Nref] )); + } + } + } + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + MaxNodeCurrent.clear(); // Dispose of temp memory + } + catch (...) + { + // + } + } + + void ShowkVBaseMismatch( String Filenm ) + { + TTextRec F; + TLoadObj* pLoad; + TGeneratorObj* pGen; + TDSSBus* pBus; + double BuskV = 0.0; + String BusName; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + + /*Check Loads*/ + if ( ActiveCircuit[ActiveActor]->Loads.get_myNumList() > 0 ) + { + System::WriteLn( F ); + System::WriteLn( F, "!!! LOAD VOLTAGE BASE MISMATCHES" ); + System::WriteLn( F ); + } + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while ( pLoad != NULL ) + { + /*Find Bus To Which Load Connected*/ + //pBus = ActiveCircuit[ActiveActor]->Buses[( pLoad->BusIndex )->Terminals[1 - 1].BusRef - 1]; + pBus = ActiveCircuit[ActiveActor]->Buses[pLoad->BusIndex - 1]; + BusName = ActiveCircuit[ActiveActor]->BusList.Get( ( pLoad )->Terminals[1 - 1].BusRef ); + if ( pBus->kVBase != 0.0 ) + { + if ( (((TDSSCktElement*)pLoad)->Get_NPhases() == 1 ) && ( pLoad->Connection == 0 ) ) + { + if ( Abs( pLoad->kVLoadBase - pBus->kVBase ) > 0.10 * pBus->kVBase ) + { + System::WriteLn( F, Format( "!!!!! Voltage Base Mismatch, Load.%s.kV=%.6g, Bus %s LN kvBase = %.3g", (pLoad)->get_Name().c_str(), pLoad->kVLoadBase, (pLoad)->GetBus(1).c_str(), pBus->kVBase)); + System::WriteLn( F, Format( "!setkvbase %s kVLN=%.3g", BusName.c_str(), pLoad->kVLoadBase )); + System::WriteLn( F, Format( "!Load.%s.kV=%.3g", (pLoad)->get_Name().c_str(), pBus->kVBase )); + } + } + else + { + BuskV = pBus->kVBase / SQRT3; + if ( Abs( pLoad->kVLoadBase - BuskV ) > 0.10 * BuskV ) + { + System::WriteLn( F, Format( "!!!!! Voltage Base Mismatch, Load.%s.kV=%.6g, Bus %s kvBase = %.3g", (pLoad)->get_Name().c_str(), pLoad->kVLoadBase, pLoad->GetBus(1).c_str(), BuskV)); + System::WriteLn( F, Format( "!setkvbase %s kVLL=%.3g", BusName.c_str(), pLoad->kVLoadBase )); + System::WriteLn( F, Format( "!Load.%s.kV=%.3g", pLoad->get_Name().c_str(), BuskV)); + } + } + } + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + + + /*Check Generators*/ + if ( ActiveCircuit[ActiveActor]->Generators.get_myNumList() > 0 ) + { + System::WriteLn( F ); + System::WriteLn( F, "!!! GENERATOR VOLTAGE BASE MISMATCHES" ); + System::WriteLn( F ); + } + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_First(); + while ( pGen != NULL ) + { + /*Find Bus To Which Generator Connected*/ + pBus = ActiveCircuit[ActiveActor]->Buses[( pGen )->Terminals[1 - 1].BusRef - 1]; + BusName = ActiveCircuit[ActiveActor]->BusList.Get((pGen)->Terminals[1 - 1].BusRef ); + if ( pBus->kVBase != 0.0 ) + { + if ( (((TDSSCktElement*)pGen)->Get_NPhases() == 1 ) && ( pGen->Connection == 0 ) ) + { + if ( Abs( pGen->GenVars.kVGeneratorBase - pBus->kVBase ) > 0.10 * pBus->kVBase ) + { + System::WriteLn( F, Format( "!!! Voltage Base Mismatch, Generator.%s.kV=%.6g, Bus %s LN kvBase = %.3g", pGen->get_Name().c_str(), pGen->GenVars.kVGeneratorBase, pGen->GetBus(1).c_str(), pBus->kVBase)); + System::WriteLn( F, Format( "!setkvbase %s kVLN=%.3g", BusName.c_str(), pGen->GenVars.kVGeneratorBase )); + System::WriteLn( F, Format( "!Generator.%s.kV=%.3g", pGen->get_Name().c_str(), pBus->kVBase)); + } + } + else + { + BuskV = pBus->kVBase * SQRT3; + if ( Abs( pGen->GenVars.kVGeneratorBase - BuskV ) > 0.10 * BuskV ) + { + System::WriteLn( F, Format( "!!! Voltage Base Mismatch, Generator.%s.kV=%.6g, Bus %s kvBase = %.2g", pGen->get_Name().c_str(), pGen->GenVars.kVGeneratorBase, pGen->GetBus(1).c_str(), BuskV)); + System::WriteLn( F, Format( "!setkvbase %s kVLL=%.2g", BusName.c_str(), pGen->GenVars.kVGeneratorBase )); + System::WriteLn( F, Format( "!Generator.%s.kV=%.2g", pGen->get_Name().c_str(), BuskV)); + } + } + } + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowDeltaV( String Filenm ) + { + TTextRec F; + TDSSCktElement* pElem; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + SetMaxDeviceNameLength(); + System::WriteLn( F ); + System::WriteLn( F, "VOLTAGES ACROSS CIRCUIT ELEMENTS WITH 2 TERMINALS" ); + System::WriteLn( F ); + System::WriteLn( F, "Source Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element,", MaxDeviceNameLength ) ); System::WriteLn( F, " Conductor, Volts, Percent, kVBase, Angle" ); + System::WriteLn( F ); + + + // SOURCES first + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() && ( pElem->Get_NTerms() == 2 ) ) + { + WriteElementDeltaVoltages( F, pElem ); + System::WriteLn( F ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next(); + } + System::WriteLn( F ); + System::WriteLn( F, "Power Delivery Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element,", MaxDeviceNameLength ) ); System::WriteLn( F, " Conductor, Volts, Percent, kVBase, Angle" ); + System::WriteLn( F ); + + + // PDELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() && ( pElem->Get_NTerms() == 2 ) ) + { + WriteElementDeltaVoltages( F, pElem ); + System::WriteLn( F ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + System::WriteLn( F, "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =" ); + System::WriteLn( F ); + System::WriteLn( F, "Power Conversion Elements" ); + System::WriteLn( F ); + System::Write( F, Pad( "Element,", MaxDeviceNameLength ) ); System::WriteLn( F, " Conductor, Volts, Percent, kVBase, Angle" ); + System::WriteLn( F ); + + // PCELEMENTS next + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() && ( pElem->Get_NTerms() == 2 ) ) + { + WriteElementDeltaVoltages( F, pElem ); + System::WriteLn( F ); + } + pElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + + void ShowControlledElements( String Filenm ) + { + TTextRec F; + TPDElement* PDElem; + TDSSCktElement* pctrlelem; + int i = 0; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while ( PDElem != NULL ) + { + if ( ( (TDSSCktElement*) PDElem )->HasControl ) + { + /*# with PDElem do */ + System::Write( F, ( (TDSSCktElement*) PDElem )->ParentClass->get_myClass_name() + "." + ( (TDSSCktElement*) PDElem )->get_Name() ); + for ( int stop = ((TDSSCktElement*)PDElem)->ControlElementList.get_myNumList(), i = 1; i <= stop; i++) + { + pctrlelem = (TDSSCktElement*) ((TDSSCktElement*)PDElem)->ControlElementList.Get( i ); + /*# with pctrlelem do */ + System::Write( F, ", " + pctrlelem->ParentClass->get_myClass_name() + "." + pctrlelem->get_Name() + " "); + } + System::WriteLn( F ); + } + PDElem = (TPDElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + void ShowResult( String Filenm ) + { + TTextRec F; + try + { + AssignFile( F, Filenm ); + Rewrite( F ); + IOResultToException(); + ParserVars->Lookup( "@result" ); + System::WriteLn( F, ParserVars->Get_Value() ); + GlobalResult = Filenm; + /* } + __finally + {*/ + CloseFile( F ); + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + + void ShowEventLog( String Filenm ) + { + try + { + // EventStrings[ActiveActor].SaveToFile( Filenm ); + // replacing with an equivalent in C++ + TTextRec F; + int i; + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + + for (i = 0; i < EventStrings[ActiveActor].size(); i++) + { + System::WriteLn(F, EventStrings[ActiveActor][i]); + } + CloseFile(F); + + GlobalResult = Filenm; + /* } + __finally + {*/ + if (AutoDisplayShowReport) + FireOffEditor( Filenm ); + ParserVars->Add( "@lastshowfile", Filenm ); + } + catch (...) + { + // + } + } + + //-----Shows the list of generators converted from PV to PQ bus during an NCIM solution step -------------- + void ShowPV2PQGen(String Filenm) + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = with0->Solution; + TGeneratorObj* pGen = nullptr; + int NumGens = with0->Generators.get_myNumList(), + BIdx = 0; + + TTextRec F = {}; + try + { + AssignFile(F, Filenm); + Rewrite(F); + IOResultToException(); + Write(F, "------------------------------------------------------------------------------"); + Write(F, CRLF); + Write(F, "LIST OF GENERATORS CONVERTED FROM PV TO PQ BUS DURING THE LAST SOLUTION (NCIM)"); + Write(F, CRLF); + Write(F, "------------------------------------------------------------------------------"); + Write(F, CRLF); + Write(F, CRLF); + if (NumGens > 0) + { + pGen = (TGeneratorObj*)with0->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + if (pGen->Get_Enabled()) + { + BIdx = Find(&with1->PV2PQList, i); + if (BIdx >= 0) + { + Write(F, "Generator." + pGen->get_Name()); + Write(F, CRLF); + } + } + pGen = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + CloseFile(F); + GlobalResult = Filenm; + if (AutoDisplayShowReport) + FireOffEditor(Filenm); + ParserVars->Add("@lastshowfile", Filenm); + } + catch (std::exception& E) + { + DoSimpleMsg(String("Error writing file ") + Filenm + CRLF + (std::string)E.what(), 438); + } + } + + void ShowResults_initialization() + { + MaxDeviceNameLength = 30; + MaxBusNameLength = 12; + } + + class ShowResults_unit + { + public: + ShowResults_unit() + { + ShowResults_initialization(); + } + }; + ShowResults_unit _ShowResults_unit; + +}// namespace ShowResults \ No newline at end of file diff --git a/OpenDSSC/Common/ShowResults.h b/OpenDSSC/Common/ShowResults.h new file mode 100644 index 0000000..764435d --- /dev/null +++ b/OpenDSSC/Common/ShowResults.h @@ -0,0 +1,68 @@ +#ifndef ShowResultsH +#define ShowResultsH + +#include "System.h" +#include "Sysutils.h" + +using namespace std; + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + 5-30-00 Added code for handling positive sequence mode +*/ +namespace ShowResults +{ + + + //#include + void ShowVoltages(String Filenm, bool LL, int ShowOptionCode); + void ShowCurrents(String Filenm, bool ShowResidual, int ShowOptionCode); + void ShowPowers(String Filenm, int Opt, int ShowOptionCode); + void ShowBusPowers(String Filenm, String BusName, int Opt, int ShowOptionCode); + void ShowFaultStudy(String Filenm); + void ShowElements(String Filenm, String ClassName); + void ShowBuses(String Filenm); + void ShowMeters(String Filenm); + void ShowGenMeters(String Filenm); + void ShowMeterZone(String Filenm); + void ShowLosses(String Filenm); + void ShowRegulatorTaps(String Filenm); + void ShowOverloads(String Filenm); + void ShowUnserved(String Filenm, bool UE_Only); + void ShowVariables(String Filenm); + void ShowIsolated(String Filenm); + void ShowRatings(String Filenm); + void ShowLoops(String Filenm); + void ShowLineConstants(String Filenm, double Freq, int Units, double Rho); + void ShowYPrim(String Filenm); + void ShowY(String Filenm); + void ShowTopology(String Fileroot); // summary and tree-view to separate files + + void ShowNodeCurrentSum(String Filenm); + void ShowkVBaseMismatch(String Filenm); + void ShowDeltaV(String Filenm); + void ShowControlledElements(String Filenm); + void ShowResult(String Filenm); + void ShowEventLog(String Filenm); + void ShowPV2PQGen(String Filenm); + +} // namespace ShowResults + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ShowResults; +#endif + +#endif // ShowResultsH + + + + + + + + diff --git a/OpenDSSC/Common/Solution.cpp b/OpenDSSC/Common/Solution.cpp new file mode 100644 index 0000000..bfc44b8 --- /dev/null +++ b/OpenDSSC/Common/Solution.cpp @@ -0,0 +1,4430 @@ + +#pragma hdrstop + +#include +#include "Solution.h" + +#include "SolutionAlgs.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "CmdForms.h" +#include "PDElement.h" +#include "ControlElem.h" +#include "Fault.h" +#include "AutoAdd.h" +#include "YMatrix.h" +#include "Load.h" +#include "CktTree.h" +#include "ParserDel.h" +#include "generator.h" +#include "Capacitor.h" +//#include "ImplGlobals.h" // to fire events +#include +#include "Circuit.h" +#include "Utilities.h" +#include "klusolve.h" +#include "PointerList.h" +#include "Line.h" +#include "Transformer.h" +#include "Reactor.h" +#include "Diakoptics.h" +#include "d2c_structures.h" +#include "ExecHelper.h" +#include "dirsep.h" + + +TSolutionObj* ActiveSolutionObj = NULL; + + + +const int NumPropsThisClass = 1; + + +namespace Solution +{ + +// =========================================================================================== + + TSolutionObj* ActiveSolutionObj; + + EControlProblem::EControlProblem(const String &Msg) : inherited(Msg) {} + ESolveError::ESolveError(const String &Msg) : inherited(Msg) {} + + TDSSSolution::TDSSSolution( ) // Collection of all solution objects + + { + ; + Class_Name = "Solution"; + DSSClassType = DSS_OBJECT + HIDDEN_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice( PropertyName, NumProperties ); + CommandList = TCommandList(slc , NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + } + + // =========================================================================================== + + + + TDSSSolution::~TDSSSolution( ) + { + // ElementList and CommandList freed in inherited destroy + // todo check: inherited::Destroy; + } + + // =========================================================================================== + + + + void TDSSSolution::DefineProperties( ) + { + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "-------"; + + + // define Property help values + PropertyHelp[1 - 1] = "Use Set Command to set Solution properties."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + // =========================================================================================== + + + + int TDSSSolution::NewObject( const String ObjName ) + { + int result = 0; + // Make a new Solution Object and add it to Solution class list + ActiveSolutionObj = new TSolutionObj( this, ObjName ); + // this one is different than the rest of the objects. + result = AddObjectToList( ActiveSolutionObj ); + return result; + } + + // =========================================================================================== + + + // =========================================================================================== + TSolutionObj::TSolutionObj( TDSSClass* ParClass, const String solutionname ) + : inherited(ParClass), + dV(NULL), + nNZ_yii(0), + Algorithm(0), + ControlActionsDone(false), + ControlIteration(0), + ControlMode(0), + ConvergenceTolerance(0.0), + ConvergedFlag(false), + DefaultControlMode(0), + DefaultLoadModel(0), + DoAllHarmonics(false), + DynamicsAllowed(false), + FirstIteration(false), + FrequencyChanged(false), + Fyear(0), + Harmonic(0.0), + HarmonicListSize(0), + IntervalHrs(0.0), + Iteration(0), + LoadModel(0), + VoltageBaseChanged(false), + SampleTheMeters(false), + SeriesYInvalid(false), + SolutionInitialized(false), + DynamicsInitialized(false), + SystemYChanged(false), + UseAuxCurrents(false), + PreserveNodeVoltages(false), + IsDynamicModel(false), + IsHarmonicModel(false), + LastSolutionWasDirect(false), + LoadsNeedUpdating(false), + ActorVIdx(0), + NumberOfTimes(0), + RandomType(0), + SolutionCount(0), + MaxIterations(0), + MinIterations(0), + MostIterationsDone(0), + MaxControlIterations(0), + MaxError(0.0), + NodeYiiEmpty(false), + clstr_num_hghst(0), + clstr_num_lwst(0), + bCurtl(false), + Total_Time_Elapsed(0.0), + Solve_Time_Elapsed(0.0), + Total_Solve_Time_Elapsed(0.0), + Step_Time_Elapsed(0.0), + temp_counter(0), + ADiakoptics_ready(false), + ADiakoptics_Actors(0) + { + Set_Name(LowerCase( solutionname )); + + // i := SetLogFile ('c:\\temp\\KLU_Log.txt', 1); + + SolveStartTime = { 0 }; + SolveEndtime = { 0 }; + GStartTime = { 0 }; + Gendtime = { 0 }; + LoopEndtime = { 0 }; + Fyear = 0; + DynaVars.intHour = 0; + DynaVars.T = 0.0; + DynaVars.dblHour = 0.0; + DynaVars.tstart = 0.0; + DynaVars.tstop = 0.0; + //duration := 0.0; + DynaVars.h = 0.001; // default for dynasolve + LoadsNeedUpdating = true; + VoltageBaseChanged = true; // Forces Building of convergence check arrays + MaxIterations = 15; + MinIterations = 2; + MaxControlIterations = 10; + ConvergenceTolerance = 0.0001; + ConvergedFlag = false; + SampleTheMeters = false; // Flag to tell solution algorithm to sample the Energymeters + IsDynamicModel = false; + IsHarmonicModel = false; + if (DefaultBaseFreq == 0) + DefaultBaseFreq = 60; + FFrequency = -1; // initialize to avoid potential issues and warnings + Set_Frequency(DefaultBaseFreq); + /*Fundamental := 60.0; Moved to Circuit and used as default base frequency*/ + Harmonic = 1.0; + FrequencyChanged = true; // Force Building of YPrim matrices + DoAllHarmonics = true; + FirstIteration = true; + DynamicsAllowed = false; + SystemYChanged = true; + SeriesYInvalid = true; + NodeV.clear(); + Currents.clear(); + Node_dV.clear(); + Ic_Local.clear(); + NodeYii.clear(); + + + /*Define default harmonic list*/ + HarmonicListSize = 5; + HarmonicList = new double[ HarmonicListSize ]; + HarmonicList[0] = 1.0; + HarmonicList[1] = 5.0; + HarmonicList[2] = 7.0; + HarmonicList[3] = 11.0; + HarmonicList[4] = 13.0; + SolutionInitialized = false; + LoadModel = POWERFLOW; + DefaultLoadModel = LoadModel; + LastSolutionWasDirect = false; + hYseries = 0; + hYsystem = 0; + hY = 0; + Jacobian = 0; + NodeV.clear(); + dV = NULL; + Currents.clear(); + AuxCurrents = NULL; + VmagSaved.clear(); + ErrorSaved.clear(); + NodeVbase.clear(); + UseAuxCurrents = false; + SolutionCount = 0; + DynaVars.SolutionMode = SNAPSHOT; + ControlMode = CTRLSTATIC; + DefaultControlMode = ControlMode; + Algorithm = NORMALSOLVE; + RandomType = GAUSSIAN; // default to gaussian + NumberOfTimes = 100; + IntervalHrs = 1.0; + InitPropertyValues( 0 ); + ADiakoptics_ready = false; // A-Diakoptics needs to be initialized + + /* --pending to implement--DM + + if ( !( ActorMA_Msg[ActiveActor] != NULL ) ) + ActorMA_Msg[ActiveActor] = TEvent( NULL, true, false, "" ); */ + pColIdx_Yii.clear(); + pRowIdx_Yii.clear(); + pcVals_Yii.clear(); + deltaF.clear(); + deltaZ.clear(); + NCIMY.clear(); + NCIMYRow.clear(); + NCIMYCol.clear(); + NCIMRdy = false; + PV2PQList.clear(); + IgnoreQLimit = false; + GenGainNCIM = 1.0; + InitGenQ = true; + } + + // =========================================================================================== + + + TSolutionObj::~TSolutionObj( ) + { + free(AuxCurrents); + Currents.clear(); + //dV = (pNodeVarray) realloc(dV, 0); + free(dV); + ErrorSaved.clear(); + NodeV.clear(); + NodeVbase.clear(); + VmagSaved.clear(); + if ( hYsystem != 0 ) + DeleteSparseSet( hYsystem ); + if ( hYseries != 0 ) + DeleteSparseSet( hYseries ); + /*by Dahei: */ + NodeYii.clear(); // for bii + pColIdx_Yii.clear(); + pRowIdx_Yii.clear(); + pcVals_Yii.clear(); + /*---------------------------*/ + // SetLogFile ('c:\\temp\\KLU_Log.txt', 0); + delete[] HarmonicList; + //ActorMA_Msg[ActiveActor].SetEvent; + + // Sends a message to the working actor + if ( ActorHandle[ActiveActor] != NULL ) + { + delete ActorHandle[ActiveActor]; + ActorHandle[ActiveActor] = NULL; + } + //free(ActorMA_Msg[ActiveActor]); + ActorMA_Msg[ActiveActor] = 0; + // todo check: inherited::Destroy; + Node_dV.clear(); + Ic_Local.clear(); + NCIMY.clear(); + NCIMYRow.clear(); + NCIMYCol.clear(); + } + + + // =========================================================================================== + + + + int TDSSSolution::Edit( int ActorID ) + { + int result = 0; + result = 0; + ActiveSolutionObj = ActiveCircuit[ActorID]->Solution; + /*# with ActiveSolutionObj do */ + { + + // This is all we do here now... + ActiveSolutionObj->Solve( ActorID ); + } /*WITH*/ + return result; + } + + // =========================================================================================== + + + + void TSolutionObj::Solve( int ActorID ) + { + //TScriptEdit ScriptEd; + ActiveCircuit[ActorID]->Issolved = false; + SolutionWasAttempted[ActorID] = true; + + /*Check of some special conditions that must be met before executing solutions*/ + if ( ActiveCircuit[ActorID]->EmergMinVolts >= ActiveCircuit[ActorID]->NormalMinVolts ) + { + DoThreadSafeMsg( "Error: Emergency Min Voltage Must Be Less Than Normal Min Voltage!" + CRLF + "Solution Not Executed.", 480 ); + return; + } + if ( SolutionAbort ) + { + GlobalResult = "Solution aborted."; + CmdResult = SOLUTION_ABORT; + ErrorNumber = CmdResult; + return; + } + try + { + /*Main solution Algorithm dispatcher*/ + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + switch ( get_Fyear() ) + { + case 0: + with0->DefaultGrowthFactor = 1.0; + break; // RCD 8-17-00 + default: + with0->DefaultGrowthFactor = pow(with0->DefaultGrowthRate, ( get_Fyear() - 1 ) ); + } + } + } + // Creates the actor again in case of being terminated due to an error before + if ((!ActorHandle[ActorID]->ActorActive) || (ActorHandle[ActorID] == NULL)) + { + if ( !ActorHandle[ActorID]->ActorActive) + free(ActorHandle[ActorID]); + New_Actor( ActorID ); + } + + // Resets the event for receiving messages from the active actor + // Updates the status of the Actor in the GUI + ActorStatus[ActorID] = 0; // Global to indicate that the actor is busy + //ActorMA_Msg[ActorID]->ResetEvent; + QueryPerformanceCounter( &GStartTime ); + if ( ! NoFormsAllowed ) + { + if ( ! IsProgressON && DSSProgressFrm ) + { + switch ( DynaVars.SolutionMode ) + { + case YEARLYMODE: case DUTYCYCLE: case LOADDURATION1: case LOADDURATION2: case HARMONICMODE: case HARMONICMODET: + { + if ( Progress_Actor[ActorID] != NULL ) + { + //Progress_Actor[ActorID]->Terminate; + Progress_Actor[ActorID] = NULL; + } + //Progress_Actor = TProgressActor.Create( ); + } + break; + default: + { + // Just other simulation modes, nothing to do + } + } + } + } + + // Sends message to start the Simulation + ActorHandle[ActorID]->Send_Message( SIMULATE ); + // If the parallel mode is not active, Waits until the actor finishes + if (!Parallel_enabled) + { + Wait4Actors( ALL_ACTORS ); + } + } + catch( std::exception & E ) + { + DoThreadSafeMsg( "Error Encountered in Solve: " + (std::string) E.what(), 482 ); + SolutionAbort = true; + } + } + + // =========================================================================================== + + + + bool TSolutionObj::Converged( int ActorID ) + { + bool result = false; + int i = 0; + double VMag = 0.0; + + if (ActiveCircuit[ActorID]->Solution->Algorithm != NCIMSOLVE) + { + + // base convergence on voltage magnitude + MaxError = 0.0; + for (int stop = ActiveCircuit[ActorID]->NumNodes, i = 1; i <= stop; i++) + { + if (!ADiakoptics || (ActorID == 1)) + VMag = cabs(NodeV[i]); + else + VMag = cabs(VoltInActor1(i)); + + /* If base specified, use it; otherwise go on present magnitude */ + if (NodeVbase[i] > 0.0) + ErrorSaved[i] = Abs(VMag - VmagSaved[i]) / NodeVbase[i]; + else + if (VMag != 0.0) + ErrorSaved[i] = Abs(1.0 - (VmagSaved[i] / VMag)); + VmagSaved[i] = VMag; // for next go-'round + MaxError = max(MaxError, ErrorSaved[i]); // update max error + } + if (MaxError <= ConvergenceTolerance) + result = true; + + } + else + { + for (i = 0; i < deltaF.size(); i++) + { + result = Abs(deltaF[i].re) <= ConvergenceTolerance; + if (!result) + break; + } + + } + + ConvergedFlag = result; + return result; + } + + + // =========================================================================================== + + + + void TSolutionObj::GetSourceInjCurrents( int ActorID ) + + // Add in the contributions of all source type elements to the global solution vector InjCurr + + { + TDSSCktElement* pElem; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + pElem = (TDSSCktElement*) with0->Sources.Get_First(); + while ( pElem != NULL ) + { + if ( pElem->Get_Enabled() ) + pElem->InjCurrents( ActorID ); // uses NodeRef to add current into InjCurr Array; + pElem = (TDSSCktElement*) with0->Sources.Get_Next(); + } + + // Adds GFM PCE as well + GetPCInjCurr(ActorID, true); + } + } + } + + // =========================================================================================== + + + + void TSolutionObj::SetGeneratorDispRef( int ActorID ) + + // Set the global generator dispatch reference + + { + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + switch ( DynaVars.SolutionMode ) + { + case SNAPSHOT: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case YEARLYMODE: + with0->GeneratorDispatchReference = with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case DAILYMODE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case DUTYCYCLE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case GENERALTIME: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case DYNAMICMODE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case EMPMODE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case EMPDAILYMODE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case HARMONICMODE: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case MONTECARLO1: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case MONTECARLO2: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case MONTECARLO3: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case PEAKDAY: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case LOADDURATION1: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case LOADDURATION2: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + case DIRECT: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor; + break; + case MONTEFAULT: + with0->GeneratorDispatchReference = 1.0; + break; // Monte Carlo Fault Cases solve at peak load only base case + + case FAULTSTUDY: + with0->GeneratorDispatchReference = 1.0; + break; + case AUTOADDFLAG: + with0->GeneratorDispatchReference = with0->DefaultGrowthFactor; + break; // peak load only + + case HARMONICMODET: + with0->GeneratorDispatchReference = with0->get_FLoadMultiplier() * with0->DefaultGrowthFactor * with0->DefaultHourMult.re; + break; + default: + DoSimpleMsg( "Unknown solution mode.", 483 ); + } + } + } + + // =========================================================================================== + + + + void TSolutionObj::SetGeneratordQdV( int ActorID ) + { + TGeneratorObj* pGen; + bool Did_One = false; + double GenDispSave = 0.0; + Did_One = false; + + // Save the generator dispatch level and set on high enough to + // turn all generators on + GenDispSave = ActiveCircuit[ActorID]->GeneratorDispatchReference; + ActiveCircuit[ActorID]->GeneratorDispatchReference = 1000.0; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + pGen = (TGeneratorObj*) with0->Generators.Get_First(); + while ( pGen != NULL ) + { + if ( ( (TDSSCktElement*) pGen )->Get_Enabled() ) + { + + // for PV generator models only ... + if ( pGen->GenModel == 3 ) + { + pGen->InitDQDVCalc(); + + // solve at base var setting + Iteration = 0; + do + { + Iteration++; + ZeroInjCurr( ActorID ); + GetSourceInjCurrents( ActorID ); + pGen->InjCurrents( ActorID ); // get generator currents with nominal vars + SolveSystem( &NodeV[0], ActorID); + } + while ( ! ( Converged( ActorID ) || ( Iteration >= MaxIterations ) ) ); + pGen->RememberQV( ActorID ); // Remember Q and V + pGen->BumpUpQ(); + + // solve after changing vars + Iteration = 0; + do + { + Iteration++; + ZeroInjCurr( ActorID ); + GetSourceInjCurrents( ActorID ); + pGen->InjCurrents( ActorID ); // get generator currents with nominal vars + SolveSystem( &NodeV[0], ActorID); + } + while ( ! ( Converged( ActorID ) || ( Iteration >= MaxIterations ) ) ); + pGen->CalcDQDV( ActorID ); // bssed on remembered Q and V and present values of same + pGen->ResetStartPoint(); + Did_One = true; + } + } + pGen = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + } + + // Restore generator dispatch reference + ActiveCircuit[ActorID]->GeneratorDispatchReference = GenDispSave; + try + { + if // Reset Initial Solution + ( Did_One ) + SolveZeroLoadSnapShot( ActorID ); + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg( "From SetGenerator DQDV, SolveZeroLoadSnapShot: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes( ActorID ), 7071 ); + //throw @ESolveError ::( "Aborting" ); + } + } + } + + // =========================================================================================== + + + + void TSolutionObj::SendCmd2Actors( int Msg ) + { + int i = 0; + for ( int stop = NumOfActors, i = 2; i <= stop; i++) + { + ActorStatus[i] = 0; + ActorHandle[i]->Send_Message( Msg ); + } + Wait4Actors( AD_ACTORS ); + } + // =========================================================================================== + void TSolutionObj::DoNormalSolution( int ActorID ) + + /* Normal fixed-point solution + + Vn+1 = [Y]-1 Injcurr + + Where Injcurr includes only PC elements (loads, generators, etc.) + i.e., the shunt elements. + + Injcurr are the current injected INTO the NODE + (need to reverse current direction for loads) + */ + { + int i = 0; + Iteration = 0; + /***** Main iteration loop *****/ + { + auto with0 = ActiveCircuit[ActorID]; +// DOForceFlatStart(ActorID); + do + { + Iteration++; + if ( with0->LogEvents ) + LogThisEvent( "Solution Iteration " + IntToStr( Iteration ), ActorID ); + if ( ( ! ADiakoptics ) || ( ActorID != 1 ) ) // Normal simulation + { // In A-Diakoptics, all other actors do normal solution + /* Get injcurrents for all PC devices */ + ZeroInjCurr( ActorID ); + GetSourceInjCurrents( ActorID ); // sources + GetPCInjCurr( ActorID ); // Get the injection currents from all the power conversion devices and feeders + + // The above call could change the primitive Y matrix, so have to check + if ( SystemYChanged ) + { + BuildYMatrix( WHOLEMATRIX, false, ActorID ); // Does not realloc V, I + } + /*by Dahei*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); + if ( UseAuxCurrents ) + AddInAuxCurrents( NORMALSOLVE, ActorID ); + + // Solve for voltages {Note:NodeV[0] = 0 + j0 always} + if ( with0->LogEvents ) + LogThisEvent( "Solve Sparse Set DoNormalSolution ...", ActorID ); + SolveSystem( &NodeV[0], ActorID); + LoadsNeedUpdating = false; + } + else + { + ADiak_PCInj = true; + Solve_Diakoptics( ); // A-Diakoptics + } + } + while ( ! ( ( Converged( ActorID ) && ( Iteration >= MinIterations ) ) || ( Iteration >= MaxIterations ) ) ); + } + } + + // =========================================================================================== + void TSolutionObj::DoNCIMSolution(int ActorID) + { + /* Implements the N conductor current injection method (NCIM) for solving the power flow problem. + + This mehtod is a Newton-Raphson like solution method, and is implemented here to address + transmission system-like simulations. For more info, check: + + https://www.sciencedirect.com/science/article/abs/pii/S0142061512004310 + + */ + auto with0 = ActiveCircuit[ActorID]; + bool Solved = false; + complex dV = CZero; + + Iteration = 0; // Initializes iteration counter + + if (InitGenQ) // If the system needs to be initialized + { + InitPQGen(ActorID); // Initialize PQ like generators + PV2PQList.clear(); + } + + if (SystemYChanged || !NCIMRdy) + NCIMNodes = InitNCIM(ActorID, InitGenQ); // Initializes the NCIM environment vars and structures (takes time) + + /***** Main iteration loop *****/ + do + { + Iteration++; + CalcInjCurr(ActorID, InitGenQ); // Calc Injection currents using the latest solution ( I = Y * V ) + BuildJacobian(ActorID); // Resets the jacobian's diagonal for the next iteration + GetNCIMPowers(ActorID); // Populate the total power vector + ApplyCurrNCIM(ActorID); // Adjust Jacobian and populate the currents vector + if (with0->LogEvents) + LogThisEvent("Solve Power flow DoNCIMSolution ...", ActorID); + // Solves the Jacobian + SolveSparseSet(Jacobian, &(deltaZ[0]), &(deltaF[0])); + + //Updates the Voltage vector + int dVIdx = 0; + dV = CZero; + for (int i = 1; i <= with0->NumNodes; i++) + { + dVIdx = (i - 1) * 2; + dV = cmplx(deltaZ[dVIdx].re, deltaZ[dVIdx + 1].re); + NodeV[i] = csub(NodeV[i], dV); + } + Solved = Converged(ActorID); + // Updates the Generator's Q using the calculated deltaQ + UpdateGenQ(ActorID); + InitGenQ = false; + + } while (!((Solved && (Iteration >= MinIterations)) || (Iteration >= MaxIterations))); + + + DistGenClusters(ActorID); // Distributes the power among all the clustered generators (if any) + // To reverse what we did for the next simulation step + // ReversePQ2PV(ActorID); - not needed for now (04/01/2024) + + } + + // =========================================================================================== + void TSolutionObj::DoNewtonSolution( int ActorID ) + + /* Newton Iteration + + Vn+1 = Vn - [Y]-1 Termcurr + + Where Termcurr includes currents from all elements and we are + attempting to get the currents to sum to zero at all nodes. + + Termcurr is the sum of all currents going INTO THE TERMINALS of + the elements. + + For PD Elements, Termcurr = Yprim*V + + For Loads, Termcurr = (Sload/V)* + For Generators, Termcurr = -(Sgen/V)* + + */ + { + int i = 0; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + ReallocMem( dV, sizeof( dV[1] ) * ( with0->NumNodes + 1 ) ); // Make sure this is always big enough + if ( ControlIteration == 1 ) + GetPCInjCurr( ActorID ); // Update the load multipliers for this solution + Iteration = 0; + do + { + Iteration++; + SolutionCount++; // SumAllCurrents Uses ITerminal So must force a recalc + + // Get sum of currents at all nodes for all devices + ZeroInjCurr( ActorID ); + SumAllCurrents( ActorID ); + + // Call to current calc could change YPrim for some devices + if ( SystemYChanged ) + { + BuildYMatrix( WHOLEMATRIX, false, ActorID ); // Does not realloc V, I + } + /*by Dahei*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); // + if ( UseAuxCurrents ) + AddInAuxCurrents( NEWTONSOLVE, ActorID ); + + // Solve for change in voltages + SolveSystem( dV, ActorID ); + LoadsNeedUpdating = false; + + // Compute new guess at voltages + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) // 0 node is always 0 + /*# with NodeV^[i] do */ + { + complex with1 = NodeV[i]; + { + with1.re = with1.re - dV[i].re; + with1.im = with1.im - dV[i].im; + } + } + } + while ( ! ( ( Converged( ActorID ) && ( Iteration >= MinIterations ) ) || ( Iteration >= MaxIterations ) ) ); + } + } + } + + // =========================================================================================== +/* Populates the current injections vector and updates the jacobian matrix as needed */ + + void TSolutionObj::ApplyCurrNCIM(int ActorID) + { + auto with0 = ActiveCircuit[ActorID]->Solution; + for (int i = 1; i < pNodePower.size(); i++) + { + if ((pNodePower[i].re != 0) || (pNodePower[i].im != 0)) + { + if (pNodeType[i] == PV_Node) + DoPVBusNCIM(ActorID, i, pNodePVTarget[i], pNodePower[i]); + else + DoPQBusNCIM(ActorID, i, with0->NodeV[i], pNodePower[i]); + } + } + } + + // =========================================================================================== +/* Populates the total power vector before solving the NCIM algorithm */ + + void TSolutionObj::GetNCIMPowers(int ActorID) + { + TDSSCktElement* pElem = nullptr; + TCapacitorObj* pCap = nullptr; + TReactorObj* pReact = nullptr; + bool valid = false; + int NodeIdx = 0; + + auto with0 = ActiveCircuit[ActorID]; + /* Get inj currents from all enabled PC devices */ + { + { + complex LdPower = CZero, + LdVolt = CZero, + GenS = CZero; + pElem = (TDSSCktElement*)with0->PCElements.Get_First(); + while (pElem != NULL) + { + /*# with pElem do */ + if (pElem->Get_Enabled()) + { + for (int idx = 1; idx <= pElem->Fnphases; idx++) + { + NodeIdx = pElem->NodeRef[idx - 1]; + switch (pElem->DSSObjType & CLASSMASK) + { + case LOAD_ELEMENT: + { + LdPower = cmplx(((TLoadObj*)pElem)->WNominal, ((TLoadObj*)pElem)->varNominal); + LdVolt = with0->Solution->NodeV[NodeIdx]; + + if (((TLoadObj*)pElem)->FLoadModel == 2) + DoZBusNCIM(ActorID, NodeIdx, LdVolt, ((TLoadObj*)pElem)->YPrim); + else + { + if (pNodeType[NodeIdx] == PV_Node) + pNodePower[NodeIdx] = csub(pNodePower[NodeIdx], LdPower); + else + pNodePower[NodeIdx] = cadd(pNodePower[NodeIdx], LdPower); + for (int idx = 0; idx < pElem->Get_NPhases(); idx++) + pElem->Iterminal[idx] = conjg(cdiv(LdPower, LdVolt)); + } + } + break; + case GEN_ELEMENT: + { + auto with2 = (TGeneratorObj*)pElem; + auto& with1 = with2->GenVars; + + // Checks the reactive power limits in this node + switch (with2->GenModel) + { + case 3: // Generator is a PV bus + { + with1.Qnominalperphase = with1.deltaQNom[idx - 1]; + + GenS = cmplx(with1.Pnominalperphase, with1.Qnominalperphase); + if (pNodeType[NodeIdx] == PQ_Node) + pNodePower[NodeIdx] = cnegate(pNodePower[NodeIdx]); + + pNodeType[NodeIdx] = PV_Node; // Forces the node to be PV + pNodePower[NodeIdx] = cadd(GenS, pNodePower[NodeIdx]); + pGenPower[NodeIdx] = cadd(GenS, pGenPower[NodeIdx]); + + pNodePVTarget[NodeIdx] = with1.VTarget; // Updates the target for the Bus, just in case + PVBusIdx[NodeIdx] = with2->NCIMIdx + idx; // Stores the generator IDX in the NCIM array + } + break; + case 4: // Generator acts like PQ bus + { + LdVolt = with0->Solution->NodeV[NodeIdx]; + if (with1.deltaQNom.empty()) + GenS = cmplx(with1.Pnominalperphase, with1.Qnominalperphase); + else + GenS = cmplx(with1.Pnominalperphase, with1.deltaQNom[0]); + if (pNodeType[NodeIdx] == PQ_Node) + pNodePower[NodeIdx] = csub(pNodePower[NodeIdx], GenS); + else + pNodePower[NodeIdx] = cadd(pNodePower[NodeIdx], GenS); + + pGenPower[NodeIdx] = cadd(GenS, pGenPower[NodeIdx]); + } + break; + default: // Constant impedance + { + LdVolt = with0->Solution->NodeV[NodeIdx]; + DoZBusNCIM(ActorID, NodeIdx, LdVolt, with2->YPrim); + } + break; + } + } + break; + case FAULTOBJECT: + { + auto with2 = (TFaultObj*)pElem; + LdVolt = with0->Solution->NodeV[NodeIdx]; + DoZBusNCIM(ActorID, NodeIdx, LdVolt, with2->YPrim); + } + break; + default: + { + // Ignore the others + } + break; + } + } + } + pElem = (TDSSCktElement*)with0->PCElements.Get_Next(); + } + } + } + } + // =========================================================================================== +/* Apply the PV bus current injection for NCIM */ + + void TSolutionObj::DoPVBusNCIM(int ActorID, int i, double VTarget, complex Power) + { + complex Pow = CZero, + FaVr = CZero, + FaVm = CZero, + Temp = CZero, + Vc2 = CZero; + double myVal = 0.0; + int LCoords[4][2] = { {0,0}, {1,1}, {0,1}, {1,0} }; + int GCoord = 0, GCoordY = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + Pow = conjg(Power); + complex V = with0->NodeV[i]; + complex PowN = Power; + complex Curr = conjg(cdiv(PowN, V)); + Vc2 = cmul(conjg(V), conjg(V)); + FaVr = cdiv(cmplx(-1, 0), Vc2); + FaVm = cdiv(cmplx(0, 1), Vc2); + GCoord = (i * 2) - 1; + // Updates the Jacobian + for (int j = 0; j < 4; j++) + { + // Add the derivatives + switch (j) + { + case 0: // dImdVr + Temp.re = -1.0 * cmul(FaVr, Pow).im; + break; + case 1: // dIrdVm + Temp.re = -1.0 * cmul(FaVm, Pow).re; + break; + case 2: // dImdVm + Temp.re = -1.0 * cmul(FaVm, Pow).im; + break; + case 3: // dIrdVr + Temp.re = -1.0 * cmul(FaVr, Pow).re; + break; + default: + break; + } + SetMatrixElement(with0->Jacobian, GCoord + LCoords[j][0], GCoord + LCoords[j][1], &Temp); + } + + // Add current injection contributions to deltaF + GCoord--; // Removes the additional index added by DSS + with0->deltaF[GCoord].re = with0->deltaF[GCoord].re - Curr.im; // Respecting the decoupled distribution + with0->deltaF[GCoord + 1].re = with0->deltaF[GCoord + 1].re - Curr.re; // Prioritizing reactive power over the diagonal + + // Add delta V to deltaF in the voltage regulation subsection + double VMag = ctopolar(V).mag; + GCoord = (ActiveCircuit[ActorID]->NumNodes * 2) + PVBusIdx[i] - 1; + double VError = VTarget - VMag; + + with0->deltaF[GCoord - 1].re = VError; + + // Calculate the voltage regulation coefficients (Z) + GCoordY = (i * 2) - 1; + for (int j = 0; j < 2; j++) + { + // Adds the regulation coefficients + if (j == 0) + myVal = -1 * V.re / VMag; + else + myVal = -1 * V.im / VMag; + Temp = cmplx(myVal, 0); + SetMatrixElement(with0->Jacobian, GCoord, GCoordY + j, &Temp); + } + // Calculate the power regulation coefficients (X) + double den = pow(VMag, 2); + for (int j = 0; j < 2; j++) + { + // Adds the regulation coefficients + if (j == 0) + myVal = conjg(V).re / den; + else + myVal = conjg(V).im / den; + Temp = cmplx(myVal, 0); + SetMatrixElement(with0->Jacobian, GCoordY + j, GCoord, &Temp); + } + } + + // =========================================================================================== +/* Apply the PQ bus current injection for NCIM */ + + void TSolutionObj::DoPQBusNCIM(int ActorID, int i, complex V, complex Power) + { + complex Pow = CZero, + FaVr = CZero, + FaVm = CZero, + Temp = CZero, + Vc2 = CZero; + + int LCoords[4][2] = { {0,0}, {1,1}, {0,1}, {1,0} }; + int GCoord = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + Pow = conjg(Power); + Vc2 = cmul(conjg(V), conjg(V)); + FaVr = cdiv(cmplx(-1.0, 0), Vc2); + FaVm = cdiv(cmplx(0, 1.0), Vc2); + complex Curr = CZero; + Curr = conjg(cdiv(Power, V)); + GCoord = (i * 2) - 1; + // Updates the Jacobian + for (int j = 0; j < 4; j++) + { + // Add the derivatives + switch (j) + { + case 0: // dImdVr + Temp.re = cmul(FaVr, Pow).im; + break; + case 1: // dIrdVm + Temp.re = cmul(FaVm, Pow).re; + break; + case 2: // dImdVm + Temp.re = cmul(FaVm, Pow).im; + break; + case 3: // dIrdVr + Temp.re = cmul(FaVr, Pow).re; + break; + default: + break; + } + SetMatrixElement(with0->Jacobian, GCoord + LCoords[j][0], GCoord + LCoords[j][1], &Temp); + } + + // Add current injection contributions to deltaF + GCoord--; // Removes the additional index added by DSS + with0->deltaF[GCoord].re = with0->deltaF[GCoord].re + Curr.im; // Respecting the decoupled distribution + with0->deltaF[GCoord + 1].re = with0->deltaF[GCoord + 1].re + Curr.re; // Prioritizing reactive power over the diagonal + } + + // =========================================================================================== +/* Apply the Constannt impedance bus current injection for NCIM */ + + void TSolutionObj::DoZBusNCIM(int ActorID, int i, complex V, TcMatrix* YPrim) + { + complex Temp = CZero; + + int LCoords[4][2] = { {0,0}, {1,1}, {0,1}, {1,0} }; + int GCoord = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + complex Curr = CZero; + Curr = cmul(V, YPrim->Values[0]); + GCoord = (i * 2) - 1; + // Updates the Jacobian + for (int j = 0; j < 4; j++) + { + // Add the derivatives + switch (j) + { + case 0: // dImdVr + Temp.re = YPrim->Values[0].im; + break; + case 1: // dIrdVm + Temp.re = -1 * (YPrim->Values[0].im); + break; + case 2: // dImdVm + Temp.re = YPrim->Values[0].re; + break; + case 3: // dIrdVr + Temp.re = YPrim->Values[0].re; + break; + default: + break; + } + SetMatrixElement(with0->Jacobian, GCoord + LCoords[j][0], GCoord + LCoords[j][1], &Temp); + } + + // Add current injection contributions to deltaF + GCoord--; // Removes the additional index added by DSS + with0->deltaF[GCoord].re = with0->deltaF[GCoord].re + Curr.im; // Respecting the decoupled distribution + with0->deltaF[GCoord + 1].re = with0->deltaF[GCoord + 1].re + Curr.re; // Prioritizing reactive power over the diagonal + } + // =========================================================================================== +/* Initializes the node vectors used for storing the total power per node during the simulation */ + + void TSolutionObj::InitNCIMVectors(int ActorID) + { + pNodePower.resize(1); + pGenPower.resize(1); + pNodeType.resize(1); + pNodePVTarget.resize(1); + PVBusIdx.resize(1); + pNodeLimits.resize(1); + pNodeNumGen.resize(1); + + pNodePower[0] = CZero; + pNodeType[0] = -1; // means ignore + + auto with0 = ActiveCircuit[ActorID]; + string myBName = ""; + for (int i = 0; i < with0->NumBuses; i++) + { + myBName = with0->BusList.Get(i + 1); + auto with1 = with0->Buses[i]; + for (int j = 0; j < with1->FNumNodesThisBus; j++) + { + pNodePower.push_back(CZero); + pGenPower.push_back(CZero); + pNodeType.push_back(PQ_Node); // Initially, all the buses are PQ + PVBusIdx.push_back(0); + pNodePVTarget.push_back(0); + pNodeLimits.push_back(CZero); + pNodeNumGen.push_back(0); + } + } + } + + // =========================================================================================== + /*Forces the voltage vector to a flat start (magnitude only)*/ + + void TSolutionObj::DOForceFlatStart(int ActorID) + { + auto with0 = ActiveCircuit[ActorID]; + + // Sets the initial solution using the calculated angles and the buses voltage bases + polar TempPolar = ctopolar(CZero); + double mykVBase = 0.0; + double myAng[3] = { 0.0, 4 * PI / 3, 2 * PI / 3 }; + int AIdx = 0; + + // Ignores the nodes attached to the slack bus + int SlackNumNodes = 1; // with0->Buses[with0->MapNodeToBus[0].BusRef - 1]->get_FNumNodesThisBus() + 1; + for (int i = SlackNumNodes; i <= with0->NumNodes; i++) + { + auto with1 = with0->MapNodeToBus[i - 1]; + mykVBase = (with0->Buses[with1.BusRef - 1]->kVBase) * 1000; + TempPolar = ctopolar(NodeV[i]); + TempPolar.mag = mykVBase; + TempPolar.ang = myAng[AIdx]; + NodeV[i] = ptocomplex(TempPolar); + AIdx++; + if (AIdx >= 3) + AIdx = 0; + } + // Now add the slack bus data + auto pElem = (TVsourceObj*)ActiveCircuit[ActorID]->CktElements.Get_First(); + TempPolar.mag = ((pElem->kVBase * 1000) / SQRT3) * pElem->PerUnit; + double BaseAng = pElem->Angle * PI / 180; + for (int i = 1; i <= 3; i++) + { + TempPolar.ang = pElem->Angle * PI / 180 + myAng[i - 1]; + NodeV[i] = ptocomplex(TempPolar); + } + } + + // =========================================================================================== +/* Initializes the registries for generators declared as PQ buses (Mode 4) by loading up their deltaQ + with the q nominal per phase given at the generator's declaration*/ + void TSolutionObj::InitPQGen(int ActorID) + { + auto with0 = ActiveCircuit[ActorID]; + TGeneratorObj* pGen = nullptr; + int NumGens = with0->Generators.get_myNumList(); + + pGen = (TGeneratorObj*)with0->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + if (pGen->Get_Enabled() && (pGen->GenModel != 3)) + { + pGen->GenVars.deltaQNom.resize(1); + pGen->GenVars.deltaQNom[0] = pGen->GenVars.Qnominalperphase; + pGen->GenVars.deltaQNomPtr = pGen->GenVars.deltaQNom.data(); + } + pGen = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + + // =========================================================================================== +/* St the end of the solution step, distributes the reactive power among existing clusters of generators*/ + void TSolutionObj::DistGenClusters(int ActorID) + { + auto with0 = ActiveCircuit[ActorID]; + TGeneratorObj* pGen = nullptr; + int NumGens = with0->Generators.get_myNumList(); + complex Volt = CZero; + double QLocal = 0.0; + + pGen = (TGeneratorObj*)with0->Generators.Get_First(); + for (int idx = 1; idx <= NumGens; idx++) + { + if (pGen->Get_Enabled()) + { + if ((pNodeNumGen[pGen->NodeRef[0]] > 1) && ((pGen->GenModel == 3) || (pGen->GenModel == 4))) + { + for (int j = 1; j <= pGen->Get_NPhases(); j++) + { + QLocal = Abs(pGen->GenVars.Pnominalperphase / pGenPower[pGen->NodeRef[j - 1]].re) * pGenPower[pGen->NodeRef[j - 1]].im; + + Volt = NodeV[pGen->NodeRef[j - 1]]; + pGen->Iterminal[j - 1] = cnegate(conjg(cdiv(cmplx(pGen->GenVars.Pnominalperphase, QLocal), Volt))); + } + } + } + pGen = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + + // =========================================================================================== +/* Reverses to model 3 all the gnerators turned into model 4 automatically when the option AvoidPV2PQ is + disabled, this to take the model back to its original values after these type of changes take place*/ + void TSolutionObj::ReversePQ2PV(int ActorID) + { + auto with0 = ActiveCircuit[ActorID]; + TGeneratorObj* pGen = nullptr; + int NumGens = with0->Generators.get_myNumList(), + GenIdx = 0; + + pGen = (TGeneratorObj*)with0->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + auto it = find(PV2PQList.begin(), PV2PQList.end(), GenIdx); + // If element was found + if (it != PV2PQList.end()) + pGen->GenModel = 3; // Takes it back to model 3 + + GenIdx++; + pGen = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + + // =========================================================================================== +/* Initializes NCIM is when required, all the structures are created and redefined in this algorithm + returns the number of buses for the system */ + int TSolutionObj::InitNCIM(int ActorID, bool InitY) + { + auto with0 = ActiveCircuit[ActorID]; + unsigned int NNodes = 0; + int i = 0; + + // 1. Calculate the Y Bus, PDE only + BuildYMatrix(PDE_ONLY, false, ActorID); // Does not realloc V, I + InitNCIMVectors(ActorID); + // 2. Performs a flat solution to get the initial voltage estimation + ZeroInjCurr(ActorID); // All to 0 + GetSourceInjCurrents(ActorID); // sources + // Solve for voltages {Note:NodeV[0] = 0 + j0 always} + if (with0->LogEvents) + LogThisEvent("Solve Sparse Set DoNCIMSolution ...", ActorID); + if (InitY) + { + // Estimate the initial values for the solution + SolveSystem(&NodeV[0], ActorID); + // 3. Move the Y bus matrix into its sparse lib equivalent for linear algebra ops + DOForceFlatStart(ActorID); + } + // Gets the number of buses for the system + GetSize(hY, &NNodes); + + // 4. Setup the Y admittance matrix equivalent for lienar algebra orperations + LoadYBusNCIM(ActorID); + NCIMRdy = true; + return NNodes; + } + + // =========================================================================================== + /* Loads the active Y bus matrix (sparse) into its equivalent for sparse linear algebra ops */ + void TSolutionObj::LoadYBusNCIM(int ActorID) + { + unsigned int NBus = 0, nNZ = 0; + vector ColPtr, + RowIdx; + vector cVals; + double re = 0.0, im = 0.0; + unsigned int col = 0, Row = 0; + + if (ActiveCircuit[ActorID] == NULL) + return; + klusparseset_t myhY = hY; + if (!myhY) + { + DoSimpleMsg("Y Matrix not Built.", 222); + } + else + { + // this compresses the entries if necessary - no extra work if already solved + FactorSparseMatrix(myhY); + GetNNZ(myhY, &nNZ); + GetSize(myhY, &NBus); // we should already know this + + NCIMYCol.resize(nNZ); + NCIMYRow.resize(nNZ); + NCIMY.resize(nNZ); + GetTripletMatrix(myhY, nNZ, &(NCIMYRow[0]), &(NCIMYCol[0]), &(NCIMY[0])); + } + } + + /* Calculates the injection currents based on the voltages at the nodes using + I = YE, this is later used for estimating the convergence in terms of power + */ + + void TSolutionObj::CalcInjCurr(int ActorID, bool InitGenQ) + { + longInt NBus = 0; + complex myvalue = cmplx(0, 0); + + int GSize = (NCIMNodes * 2) + GetNumGenerators(ActorID, InitGenQ); + + // 4. Resize the input/output vectors + deltaF.resize(GSize); // Resizes the InjCurr mismatch vector to host also voltage control + deltaZ.resize(GSize); // Resizes the voltage mismatch vector including delta Q spaces + + for (int j = 0; j < deltaF.size(); j++) + { + deltaF[j] = CZero; + } + + // Multiplies the latest solution (V) by the Y Matrix + for (int i = 0; i < NCIMY.size(); i++) + { + // First the value found + myvalue = cmul(NCIMY[i], NodeV[NCIMYCol[i] + 1]); + deltaF[NCIMYRow[i] * 2].re += myvalue.im; + deltaF[(NCIMYRow[i] * 2) + 1].re += myvalue.re; + } + + // The first 6 elements are equal to 0 + for (int i = 0; i < 6; i++) + deltaF[i] = CZero; + } + + /* Gets the number of generators in the modeland their number of phases + Returns the number of generators times their number of phases + This form allocating memory within the Jacobian matrix for voltage control (PV buses) + Use it ONLY for initializing the structures within the NCIM algorithm*/ + int TSolutionObj::GetNumGenerators(int ActorID, bool InitQ) + { + TGeneratorObj* pGen = nullptr; + int NumGens = ActiveCircuit[ActorID]->Generators.get_myNumList(), + BIdx = 0, + result = 0; + vector BusRefs; + double qMax = 0.0, + qMin = 0.0; + bool Add2Limits = false; + + BusRefs.clear(); + // Restarts the generator related values + for (int idx = 0; idx < pNodeNumGen.size(); idx++) + { + pNodeNumGen[idx] = 0; + pNodeLimits[idx] = CZero; + } + + if (NumGens > 0) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + Add2Limits = false; + if (pGen->Get_Enabled()) + { + qMax = (pGen->kvarMax * 1e3) / pGen->Get_NPhases(); // Stores the Q limits for further use + qMin = (pGen->kvarMin * 1e3) / pGen->Get_NPhases(); + if (pGen->GenModel == 3) + { + if (InitQ) + { + pGen->GenVars.deltaQNom.resize(pGen->Get_NPhases()); + pGen->GenVars.deltaQNomPtr = pGen->GenVars.deltaQNom.data(); + for (int k = 0; k < pGen->Get_NPhases(); k++) + pGen->GenVars.deltaQNom[k] = 0.0; // Initializes delta Q = 0 for all the generators (PV buses) + } + if ((pGen->kvarMax == 0) && (pGen->kvarMin == 0)) + { + pGen->GenModel = 4; + if (InitQ) + PV2PQList.push_back(i); + } + else + { + BIdx = Find(&BusRefs, pGen->NodeRef[0]); + if (BIdx < 0) + { + pGen->NCIMIdx = result + 1; // It'll be used later by the generator to locate its voltage control signals (PV bus) + result = result + pGen->Get_NPhases(); + for (int j = 1; j <= pGen->Get_NPhases(); j++) + BusRefs.push_back(pGen->NodeRef[j - 1]); + } + else + pGen->NCIMIdx = BIdx + 1; + + Add2Limits = true; + } + } + else + { + Add2Limits = (pGen->GenModel == 4); + } + + if (Add2Limits) + { + for (int j = 1; j <= pGen->Get_NPhases(); j++) + { + pNodeLimits[pGen->NodeRef[j - 1]] = cadd(pNodeLimits[pGen->NodeRef[j - 1]], cmplx(qMax, qMin)); + pNodeNumGen[pGen->NodeRef[j - 1]]++; + } + } + } + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_Next(); + } + } + return result; + } + + /* Updates the reactive power delivery for generators model 3, + this will be reflected in the next solution step. */ + void TSolutionObj::UpdateGenQ(int ActorID) + { + TGeneratorObj* pGen = nullptr; + auto with0 = ActiveCircuit[ActorID]; + int NumGens = with0->Generators.get_myNumList(), + GenIdx = 0, // Index of the generator within the node space + Shift = 0; // shift of the Q delta within the solution space + complex Volt = CZero; // Votlage at the generator's terminals (per phase) + vector QDelta; // Vector to copy deltaZ and assign Q updates incrementally + double qMax = 0.0, // For storing the Q max limit of the active generator + qMin = 0.0, // For storing the Q min limit of the active generator + GenQ = 0.0, // Temporary register for storing the unbound expected Q for the active generator + VNode = 0.0, // To remporarily store the voltage at the active Node + myVMax = 0.0; // Stores the active generator's scheduled voltage + bool myPVOK = true, + myPQOK = true; + vector qNodeRef, + qNodeRefPQ, + PQChecked; + int BIdx = 0; + + if (NumGens > 0) + { + GenIdx = (ActiveCircuit[ActorID]->NumNodes * 2); + + QDelta.clear(); + QDelta.push_back(0); // leaves the first one as zero, to avoid subtractions in the below + for (int i = GenIdx; i < deltaZ.size(); i++) + QDelta.push_back(-1.0 * deltaZ[i].re); // Moves deltaZ (only delta Q section) into the backup vector + + qNodeRef.clear(); + qNodeRefPQ.clear(); + PQChecked.clear(); + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + if (pGen->Get_Enabled()) + { + if (pGen->GenModel == 3) + { + myPVOK = true; + BIdx = Find(&qNodeRef, pGen->NodeRef[0]); + if (BIdx < 0) + { + for (int j = 0; j < pGen->Get_NPhases(); j++) + { + qMax = pNodeLimits[pGen->NodeRef[j]].re; // gets the upper kvar limit per phase + qMin = pNodeLimits[pGen->NodeRef[j]].im; // gets the lower kvar limit per phase + // Update the current at the gnerator's terminal for reporting purposes + + Volt = NodeV[pGen->NodeRef[j]]; + // Updates Q per generator + Shift = pGen->NCIMIdx + j; + GenQ = pGen->GenVars.deltaQNom[j] + (QDelta[Shift] * GenGainNCIM); + + if (!IgnoreQLimit) + { + if (GenQ >= 0) + myPVOK = myPVOK && (GenQ < qMax); + else + myPVOK = myPVOK && (GenQ > qMin); + } + else + { + if ((pGen->kvarMax == 0) && (pGen->kvarMin == 0)) // this if the limits are 0 + GenQ = 0; + } + QDelta[Shift] = 0; + pGen->GenVars.deltaQNom[j] = GenQ; + pGen->Iterminal[j] = cnegate(conjg(cdiv(cmplx(pGen->GenVars.Pnominalperphase, pGen->GenVars.deltaQNom[j]), Volt))); + } + } + else + myPVOK = false; + + //-------------- Changes the model type for generator if needed ---------------------------- + if (!myPVOK) + { + pGen->GenModel = 4; // If exceeds the limits changes the generator to model 4 (PQ bus) + auto& with3 = pGen->GenVars; + + if (BIdx < 0) + { // add all the node refs to the temp array if not there already + for (int j = 0; j < pGen->Get_NPhases(); j++) + qNodeRef.push_back(pGen->NodeRef[j]); + + qMax = pNodeLimits[pGen->NodeRef[0]].re; // gets the upper kvar limit per phase + qMin = pNodeLimits[pGen->NodeRef[0]].im; // gets the lower kvar limit per phase + } + else + { + qMax = 0.0; + qMin = 0.0; + } + for (int j = 0; j < pGen->Get_NPhases(); j++) + { + if (with3.deltaQNom[0] >= 0) // and fixes the values for the next solution try + with3.deltaQNom[j] = qMax; + else + with3.deltaQNom[j] = qMin; + } + + PV2PQList.push_back(i); + } + } + else + { + if (pGen->GenModel == 4) + { + if ((pGen->kvarMax != 0) && (pGen->kvarMin != 0)) + { + myPQOK = true; + BIdx = Find(&qNodeRefPQ, pGen->NodeRef[0]); + if (BIdx < 0) + { + int Checked = Find(&PQChecked, pGen->NodeRef[0]); + if (Checked < 0) + { + myVMax = pGen->VBase * pGen->Vpu; + for (int j = 0; j < pGen->Get_NPhases(); j++) + { + Volt = NodeV[pGen->NodeRef[j]]; + VNode = ctopolar(Volt).mag; + if (pGen->GenVars.deltaQNom[0] > 0) + myPQOK = myPQOK && (VNode <= myVMax); + else + myPQOK = myPQOK && (VNode >= myVMax); + + PQChecked.push_back(pGen->NodeRef[j]); + } + } + } + else + myPQOK = false; // belongs to a cluster and needs to be changed + //----------------------------- this in case we need to go back to PV --------------------------- + if (!myPQOK) + { + pGen->GenModel = 3; + auto& with3 = pGen->GenVars; + + for (int j = 0; j < pGen->Get_NPhases(); j++) + { + if (BIdx < 0) + { + qMax = pNodeLimits[pGen->NodeRef[j]].re; // gets the upper kvar limit per phase + qMin = pNodeLimits[pGen->NodeRef[j]].im; // gets the lower kvar limit per phase + qNodeRefPQ.push_back(pGen->NodeRef[j]); + } + else + { + qMax = 0; // If it's part of a cluster it needs to inject only P + qMin = 0; + } + if (with3.deltaQNom[0] >= 0) // and fixes the values for the next solution try + with3.deltaQNom[j] = qMax; + else + with3.deltaQNom[j] = qMin; + } + + int PQIdx = Find(&PV2PQList, i); + if (PQIdx >= 0) + { // If the generator is indexed in the list of converter PV buses, remove it + vector IdxTmp; + IdxTmp.clear(); + for (int j = 0; j < PV2PQList.size(); j++) + { + if (j != PQIdx) + IdxTmp.push_back(PV2PQList[j]); + } + PV2PQList = IdxTmp; + IdxTmp.clear(); + } + } + } + } + // Update currents for all the other gen models + for (int j = 0; j < pGen->Get_NPhases(); j++) + { + Volt = NodeV[pGen->NodeRef[j]]; + pGen->Iterminal[j] = cnegate(conjg(cdiv(cmplx(pGen->GenVars.Pnominalperphase, pGen->GenVars.deltaQNom[0]), Volt))); + } + } + } + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_Next(); + } + } + } + + // =========================================================================================== + /* Builds the Jacobian matrix using the data already allocated within the Y Bus matrix */ + void TSolutionObj::BuildJacobian(int ActorID) + { + int GCoords[4][2] = { {0, 0}, {0, 1}, {1, 0}, {1, 1} }; + double Values[4] = { 0 ,0 ,0 ,0 }; + int GRow = 0, + GCol = 0; + complex myValue = cmplx(0, 0); + + if (Jacobian != nullptr) + { + DeleteSparseSet(Jacobian); + Jacobian = nullptr; + } + Jacobian = NewSparseSet(deltaF.size()); + for (int i = 0; i < NCIMY.size(); i++) + { + GRow = NCIMYRow[i] * 2; + GCol = NCIMYCol[i] * 2; + if ((GRow == GCol) && (GRow < 6)) + { + // This is a diagonal for the swing bus, always 1 + myValue.re = 1; + GRow++; // Needed to match with the indexes within the library + GCol++; + SetMatrixElement(Jacobian, GRow, GCol, &myValue); + SetMatrixElement(Jacobian, GRow + 1, GCol + 1, &myValue); + } + else + { + if ((GRow >= 6) && (GCol >= 6)) // Elements beyond the swing bus + { + Values[0] = NCIMY[i].im; // B + Values[1] = NCIMY[i].re; // G + Values[2] = NCIMY[i].re; // G + Values[3] = (-1) * NCIMY[i].im; // -B + GRow++; // Needed to match with the indexes within the library + GCol++; + for (int j = 0; j < 4; j++) + { + myValue.re = Values[j]; + SetMatrixElement(Jacobian, (GCoords[j][0] + GRow), (GCoords[j][1] + GCol), &myValue); + } + } + } + } + + // Add the Voltage regulation cells to the Jacobian for later use by PV buses + // Update 03/05/2024 - not needed any more + + TGeneratorObj* pGen; + int NumGens = ActiveCircuit[ActorID]->Generators.get_myNumList(); + + if (NumGens > 0) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_First(); + for (int i = 0; i < NumGens; i++) + { + if (pGen->Get_Enabled() && (pGen->GenModel == 3)) + pGen->InitPVBusJac(ActorID); + + pGen = (TGeneratorObj*)ActiveCircuit[ActorID]->Generators.Get_Next(); + } + } + + // Clears the total power vector + for (int j = 0; j < pNodePower.size(); j++) + { + pNodePower[j] = CZero; + pGenPower[j] = CZero; + pNodeType[j] = PQ_Node; + } + } + + // =========================================================================================== + + void TSolutionObj::DoPFLOWsolution( int ActorID ) + { + SolutionCount++; //Unique number for this solution + if ( VoltageBaseChanged ) + InitializeNodeVbase( ActorID ); // for convergence test + if ( ! SolutionInitialized ) + { + if ( ActiveCircuit[ActorID]->LogEvents ) + LogThisEvent( "Initializing Solution", ActorID ); + try + { + //SolveZeroLoadSnapShot; + SolveYDirect( ActorID ); // 8-14-06 This should give a better answer than zero load snapshot + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg("From DoPFLOWsolution.SolveYDirect: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes(ActorID), 7072); + //throw @ESolveError ::( "Aborting" ); + } + } + if ( SolutionAbort ) + return; // Initialization can result in abort + try + { + if (Algorithm != NCIMSOLVE) + SetGeneratordQdV( ActorID ); // Set dQdV for Model 3 generators + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg( "From DoPFLOWsolution.SetGeneratordQdV: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes( ActorID ), 7073 ); + //throw @ESolveError ::( "Aborting" ); + } + } + + /* The above resets the active sparse set to hY */ + SolutionInitialized = true; + } + switch ( Algorithm ) + { + case NEWTONSOLVE: + DoNewtonSolution( ActorID ); + break; + case NCIMSOLVE: + DoNCIMSolution(ActorID); + break; + default: + DoNormalSolution(ActorID); + break; + } + ActiveCircuit[ActorID]->Issolved = ConvergedFlag; + LastSolutionWasDirect = false; + } + + // =========================================================================================== + + + + int TSolutionObj::SolveZeroLoadSnapShot( int ActorID ) + + // Solve without load for initialization purposes; + + { + int result = 0; + result = 0; + if ( SystemYChanged || SeriesYInvalid ) + { + BuildYMatrix( SERIESONLY, true, ActorID ); // Side Effect: Allocates V + } + pTBusArray withtmp = ActiveCircuit[ActorID]->Buses; + SolutionCount++; //Unique number for this solution + ZeroInjCurr( ActorID ); // Side Effect: Allocates InjCurr + GetSourceInjCurrents( ActorID ); // Vsource, Isource and VCCS only + + /*Make the series Y matrix the active matrix*/ + if ( hYseries == 0 ) + DoThreadSafeMsg( "Series Y matrix not built yet in SolveZeroLoadSnapshot." , 50004); + hY = hYseries; + if ( ActiveCircuit[ActiveActor]->LogEvents ) + LogThisEvent( "Solve Sparse Set ZeroLoadSnapshot ...", ActorID ); + SolveSystem( &NodeV[0], ActorID); // also sets voltages in radial part of the circuit if radial solution + + /* Reset the main system Y as the solution matrix*/ + if ( hYsystem && ! SolutionAbort ) + hY = hYsystem; + return result; + } + + // =========================================================================================== + + + + void TSolutionObj::SetVoltageBases( int ActorID ) + + // Set voltage bases using voltage at first node (phase) of a bus + + { + int i = 0; + bool bZoneCalc = false, bZoneLock = false; + try + { + // don't allow the meter zones to auto-build in this load flow solution, because the + // voltage bases are not available yet + bZoneCalc = ActiveCircuit[ActorID]->MeterZonesComputed; + bZoneLock = ActiveCircuit[ActorID]->ZonesLocked; + ActiveCircuit[ActorID]->MeterZonesComputed = true; + ActiveCircuit[ActorID]->ZonesLocked = true; + SolveZeroLoadSnapShot( ActorID ); + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto& with1 = with0->Buses[i - 1]; + with1->kVBase = NearestBasekV( cabs( NodeV[ with1->GetRef( 1 ) ] ) * 0.001732 ) / SQRT3; + } + } // l-n base kV + InitializeNodeVbase( ActorID ); // for convergence test + ActiveCircuit[ActorID]->Issolved = true; + + // now build the meter zones + ActiveCircuit[ActorID]->MeterZonesComputed = bZoneCalc; + ActiveCircuit[ActorID]->ZonesLocked = bZoneLock; + ActiveCircuit[ActorID]->DoResetMeterZones( ActorID ); + } + catch( std::exception & E ) + { + { + DoSimpleMsg( "From SetVoltageBases.SolveZeroLoadSnapShot: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes( ActorID ), 7075 ); + //throw @ESolveError ::( "Aborting" ); + } + } + } + + + void TSolutionObj::SnapShotInit( int ActorID ) + { + SetGeneratorDispRef( ActorID ); + ControlIteration = 0; + ControlActionsDone = false; + MostIterationsDone = 0; + LoadsNeedUpdating = true; // Force the loads to update at least once + } + + + void TSolutionObj::CheckControls( int ActorID ) + { + int i = 0; + if ( ! ADiakoptics || ( ActorID != 1 ) ) + { + if ( ControlIteration < MaxControlIterations ) + { + if ( ConvergedFlag ) + { + if ( ActiveCircuit[ActorID]->LogEvents ) + LogThisEvent( "Control Iteration " + IntToStr( ControlIteration ), ActorID ); + Sample_DoControlActions( ActorID ); + Check_Fault_Status( ActorID ); + } + else + ControlActionsDone = true; // Stop solution process if failure to converge + } + if ( SystemYChanged ) + { + if (Algorithm == NCIMSOLVE) + NCIMRdy = false; + else + BuildYMatrix( WHOLEMATRIX, false, ActorID ); // Rebuild Y matrix, but V stays same + + } + /*by Dahei*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); + } + else + { + if ( ControlIteration < MaxControlIterations ) + { + if ( ActiveCircuit[ActorID]->LogEvents ) + LogThisEvent( "Control Iteration " + IntToStr( ControlIteration ), ActorID ); + SendCmd2Actors( DO_CTRL_ACTIONS ); + // Checks if there are pending ctrl actions at the actors + ControlActionsDone = true; + for ( int stop = NumOfActors, i = 2; i <= stop; i++) + ControlActionsDone = ControlActionsDone && ActiveCircuit[i]->Solution->ControlActionsDone; + } + } + } + + // =========================================================================================== + + + + int TSolutionObj::SolveAD( int ActorID, bool Initialize ) // solves a step for Adiakoptics locally + + { + int result = 0; + int i = 0; + if ( Initialize ) + { + ZeroInjCurr( ActorID ); + GetSourceInjCurrents( ActorID ); // sources + if ( ADiak_PCInj ) + { + LoadsNeedUpdating = true; // Force the loads to update at least once + GetPCInjCurr( ActorID ); // Get the injection currents from all the power conversion devices and feeders + } + else + if ( IsDynamicModel || IsHarmonicModel ) + { + LoadsNeedUpdating = true; // Force the loads to update at least once + GetPCInjCurr( ActorID ); // for direct solve + } + // The above call could change the primitive Y matrix, so have to check + // The above call could change the primitive Y matrix, so have to check + if ( SystemYChanged ) + { + BuildYMatrix( WHOLEMATRIX, false, ActorID ); // Does not realloc V, I + } + /*by Dahei*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); + if ( UseAuxCurrents ) + AddInAuxCurrents( NORMALSOLVE, ActorID ); + } + else + UpdateISrc( ActorID ); + + // Solve for voltages {Note:NodeV[0] = 0 + j0 always} + SolveSystem( &(ActiveCircuit[1]->Solution->NodeV[0]), ActorID); + LoadsNeedUpdating = false; + LastSolutionWasDirect = true; + ActiveCircuit[ActorID]->Issolved = true; + return result; + } + + // =========================================================================================== + + + + int TSolutionObj::SolveSnap( int ActorID ) // solve for now once + + { + longInt result = 0; + int TotalIterations = 0; + // if Solution then + SnapShotInit( ActorID ); + TotalIterations = 0; + QueryPerformanceCounter( &SolveStartTime ); + do + { + ControlIteration++; + result = SolveCircuit( ActorID ); // Do circuit solution w/o checking controls + /*Now Check controls*/ +// if ( IsDLL ) +// Fire_CheckControls; + CheckControls( ActorID ); + + /*For reporting max iterations per control iteration*/ + if ( Iteration > MostIterationsDone ) + MostIterationsDone = Iteration; + TotalIterations = TotalIterations + Iteration; + } + while ( ! ( ControlActionsDone || ( ControlIteration >= MaxControlIterations ) ) ); + if ( ! ControlActionsDone && ( ControlIteration >= MaxControlIterations ) ) + { + DoThreadSafeMsg( "Warning Max Control Iterations Exceeded. " + CRLF + "Tip: Show Eventlog to debug control settings.", 485 ); + SolutionAbort = true; // this will stop this message in dynamic power flow modes + } + if ( ActiveCircuit[ActorID]->LogEvents ) + LogThisEvent( "Solution Done", ActorID ); + //if ( isDLL ) + // Fire_StepControls; + QueryPerformanceCounter( &SolveEndtime ); +#ifndef windows + Solve_Time_Elapsed = SolveEndtime - SolveStartTime; +#else + Solve_Time_Elapsed = ( double( ( SolveEndtime.QuadPart ) - ( SolveStartTime.QuadPart ) ) / CPU_Freq ) * 1000000; +#endif + Iteration = TotalIterations; /* so that it reports a more interesting number */ + return result; + } + + // =========================================================================================== + + + + int TSolutionObj::SolveDirect( int ActorID ) // solve for now once, direct solution + + { + int result = 0; + result = 0; + LoadsNeedUpdating = true; // Force possible update of loads and generators + QueryPerformanceCounter( &SolveStartTime ); + SolutionCount++; // Unique number for this solution + if ( ! ADiakoptics || ( ActorID != 1 ) ) + { + if ( SystemYChanged ) + { + BuildYMatrix( WHOLEMATRIX, true, ActorID ); // Side Effect: Allocates V + } + /*by Dahei*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); // + ZeroInjCurr( ActorID ); // Side Effect: Allocates InjCurr + GetSourceInjCurrents( ActorID ); + + // Pick up PCELEMENT injections for Harmonics mode and Dynamics mode + // Ignore these injections for powerflow; Use only admittance in Y matrix + if ( IsDynamicModel || IsHarmonicModel ) + GetPCInjCurr( ActorID ); + if // Solve with Zero injection current + ( SolveSystem( &NodeV[0], ActorID) == 1) + { + ActiveCircuit[ActorID]->Issolved = true; + ConvergedFlag = true; + } + } + else + { + ADiak_PCInj = false; + Solve_Diakoptics( ); // A-Diakoptics + ActiveCircuit[ActorID]->Issolved = true; + ConvergedFlag = true; + } + QueryPerformanceCounter( &SolveEndtime ); +#ifndef windows + Solve_Time_Elapsed = SolveEndtime - SolveStartTime; +#else + Solve_Time_Elapsed = ( double( ( SolveEndtime.QuadPart - SolveStartTime.QuadPart ) ) / CPU_Freq ) * 1000000; +#endif + Total_Time_Elapsed = Total_Time_Elapsed + Solve_Time_Elapsed; + Iteration = 1; + LastSolutionWasDirect = true; + return result; + } + + + int TSolutionObj::SolveCircuit( int ActorID ) + { + int result = 0; + result = 0; + if ( LoadModel == ADMITTANCE ) + try + { + SolveDirect( ActorID ); // no sense horsing around when it's all admittance + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg( "From SolveSnap.SolveDirect: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes( ActorID ), 7075 ); + //throw @ESolveError ::( "Aborting" ); + } + } + else + { + try + { + if ( SystemYChanged ) + { + if ( ! ADiakoptics || ( ActorID != 1 ) ) + BuildYMatrix( WHOLEMATRIX, true, ActorID ); // Side Effect: Allocates V + } + /*by Dahei: Get Y matrix for solution*/ + if ( NodeYiiEmpty ) + Get_Yiibus(); //IF SystemYChanged + /*-------------------------------------*/ + DoPFLOWsolution( ActorID ); + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg( "From SolveSnap.DoPflowSolution: " + CRLF + (std::string) E.what() + CheckYMatrixforZeroes( ActorID ), 7074 ); + //throw @ESolveError ::( "Aborting" ); + } + } + } + return result; + } + + // =========================================================================================== + + + + void TSolutionObj::ZeroInjCurr( int ActorID ) + { + int i = 0; + for ( int stop = ActiveCircuit[ActorID]->NumNodes, i = 0; i <= stop; i++) + Currents[i] = CZero; + } + // =========================================================================================== + + + + void TSolutionObj::Upload2IncMatrix( ) + { + int CIdx = 0; + // Uploads the values to the incidence matrix + IncMat.Insert( ( ActiveIncCell[0] - 1 ), ( ActiveIncCell[1] - 2 ), ActiveIncCell[2] ); + ActiveIncCell[2] = - 1; + } + // =========================================================================================== + + + + void TSolutionObj::AddLines2IncMatrix( int ActorID ) + { + String LineBus; + TLineObj* elem; + int TermIdx = 0, CIdx = 0; + size_t BusdotIdx = 0; + bool EndFlag = false; + int counter = 0; + // This rouitne adds the Lines to the incidence matrix vectors + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + elem = (TLineObj*) with0->Lines.Get_First(); + // Counter := 0; + while ( elem != NULL ) + { + if ( elem->Get_Enabled() ) + { + ActiveIncCell[2] = 1; + temp_counter++; + Inc_Mat_Rows.resize(temp_counter); + Inc_Mat_Rows[temp_counter - 1] = "Line." + elem->get_Name(); + for ( int stop = 2, TermIdx = 1; TermIdx <= stop; TermIdx++) + { + LineBus = elem->GetBus( TermIdx ); + BusdotIdx = LineBus.find( '.'); + if ( BusdotIdx != String::npos ) + LineBus = LineBus.substr( 0, BusdotIdx ); // removes the dot from the Bus Name + // Evaluates the position of the Bus in the array + ActiveIncCell[1] = 1; + EndFlag = true; + while ( ( ActiveIncCell[1] <= with0->NumBuses ) && ( EndFlag ) ) + { + if ( LineBus == with0->BusList.Get( ActiveIncCell[1] ) ) + EndFlag = false; + ActiveIncCell[1] = ActiveIncCell[1] + 1; + } + Upload2IncMatrix(); + // inc(Counter); + } + ActiveIncCell[0]++; + } + else + { + counter = 0; + } + elem = (TLineObj*) with0->Lines.Get_Next(); + } + // Counter := Counter; + } + } + } + // =========================================================================================== + + + + void TSolutionObj::AddXfmr2IncMatrix( int ActorID ) + { + String LineBus; + TTransfObj* elem; + int TermIdx = 0, CIdx = 0; + size_t BusdotIdx = 0; + bool EndFlag = false; + int counter = 0; + // This rouitne adds the Transformers to the incidence matrix vectors + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + TPointerList& lst = ActiveCircuit[ActorID]->Transformers; + elem = (TTransfObj*) lst.Get_First(); + while ( elem != NULL ) + { + if ( elem->Get_Enabled() ) + { + ActiveIncCell[2] = 1; + temp_counter++; + Inc_Mat_Rows.resize(temp_counter); + Inc_Mat_Rows[temp_counter - 1] = "Transformer." + elem->get_Name(); + for ( int stop = elem->get_NumWindings(), TermIdx = 1; TermIdx <= stop; TermIdx++) + { + LineBus = elem->GetBus( TermIdx ); + BusdotIdx = LineBus.find( '.' ); + if ( BusdotIdx != String::npos ) + LineBus = LineBus.substr( 0, BusdotIdx ); // removes the dot from the Bus Name + // Evaluates the position of the Bus in the array + ActiveIncCell[1] = 1; + EndFlag = true; + while ( ( ActiveIncCell[1] <= with0->NumBuses ) && ( EndFlag ) ) + { + if ( LineBus == with0->BusList.Get( ActiveIncCell[1] ) ) + EndFlag = false; + ActiveIncCell[1] = ActiveIncCell[1] + 1; + } + Upload2IncMatrix(); + } + ActiveIncCell[0]++; + } + elem = (TTransfObj*) lst.Get_Next(); + } + } + } + } + + // =========================================================================================== + + + + void TSolutionObj::AddSeriesCap2IncMatrix( int ActorID ) + { + String CapBus; + TCapacitorObj* elem; + int CapTermIdx = 0, CIdx = 0; + size_t BusdotIdx = 0; + bool CapEndFlag = false; + // This rouitne adds the series capacitors to the incidence matrix vectors + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + TPointerList& lst = with0->ShuntCapacitors; + elem = (TCapacitorObj*) lst.Get_First(); + while ( elem != NULL ) + { + if ( elem->Get_NumTerm() > 1 ) + { + if ( elem->Get_Enabled() ) + { + temp_counter++; + Inc_Mat_Rows.resize(temp_counter); + Inc_Mat_Rows[temp_counter - 1] = "Capacitor." + elem->get_Name(); + ActiveIncCell[2] = 1; + for ( int stop = 2, CapTermIdx = 1; CapTermIdx <= stop; CapTermIdx++) + { + CapBus = elem->GetBus( CapTermIdx ); + BusdotIdx = CapBus.find( '.' ); + if ( BusdotIdx != String::npos ) + CapBus = CapBus.substr( 0, BusdotIdx ); // removes the dot from the Bus Name + // Evaluates the position of the Bus in the array + ActiveIncCell[1] = 1; + CapEndFlag = true; + while ( ( ActiveIncCell[1] <= with0->NumBuses ) && ( CapEndFlag ) ) + { + if ( CapBus == with0->BusList.Get( ActiveIncCell[1] ) ) + CapEndFlag = false; + ActiveIncCell[1] = ActiveIncCell[1] + 1; + } + Upload2IncMatrix(); + } + ActiveIncCell[0]++; + } + } + elem = (TCapacitorObj*) lst.Get_Next(); + } + } + } + } + // =========================================================================================== + + + + void TSolutionObj::AddSeriesReac2IncMatrix( int ActorID ) + { + String RBus; + int elem = 0, DevClassIndex = 0; + int TermIdx = 0, CIdx = 0; + size_t BusdotIdx = 0; + bool EndFlag = false; + // This rouitne adds the series reactors to the incidence matrix vectors + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + DevClassIndex = ClassNames[ActorID].Find( "reactor" ); + LastClassReferenced[ActorID] = DevClassIndex; + ActiveDSSClass[ActorID] = (TDSSClass*) DSSClassList[ActorID].Get( LastClassReferenced[ActorID] ); + elem = ActiveDSSClass[ActorID]->Get_First(); + while ( elem != 0 ) + { + RBus = with0->get_FActiveCktElement()->GetBus( 2 ); + BusdotIdx = RBus.find( ".0" ); + if ( BusdotIdx == String::npos ) + { + temp_counter++; + Inc_Mat_Rows.resize(temp_counter); + Inc_Mat_Rows[temp_counter - 1] = "Reactor." + with0->get_FActiveCktElement()->get_Name(); + ActiveIncCell[2] = 1; + for ( int stop = 2, TermIdx = 1; TermIdx <= stop; TermIdx++) + { + RBus = with0->get_FActiveCktElement()->GetBus( TermIdx ); + BusdotIdx = RBus.find( '.' ); + if ( BusdotIdx != String::npos ) + RBus = RBus.substr( 0, BusdotIdx ); // removes the dot from the Bus Name + // Evaluates the position of the Bus in the array + ActiveIncCell[1] = 1; + EndFlag = true; + while ( ( ActiveIncCell[1] <= with0->NumBuses ) && ( EndFlag ) ) + { + if ( RBus == with0->BusList.Get( ActiveIncCell[1] ) ) + EndFlag = false; + ActiveIncCell[1] = ActiveIncCell[1] + 1; + } + Upload2IncMatrix(); + } + } + elem = ActiveDSSClass[ActorID]->Get_Next(); + ActiveIncCell[0]++; + } + } + } + } + //*********Routine for extracting the Branch to Node incidence matrix*********** + //* The order depends on the way the lines, xfmr, series cap and reactors * + //****************************************************************************** + + + void TSolutionObj::Calc_Inc_Matrix( int ActorID ) + { + int dlong = 0; + // If the sparse matrix obj doesn't exists creates it, otherwise deletes the content + //if ( IncMat == NULL ) + IncMat = Tsparse_matrix(); + //else + IncMat.Reset(); + if ( ActiveCircuit[ActorID] != NULL ) + /*# with ActiveCircuit[ActorID] do */ + { +// TDSSCircuit* with0 = ActiveCircuit[ActorID]; +// { + temp_counter = 0; + ActiveIncCell[0] = 1; // Activates row 1 of the incidence matrix + // Now we proceed to evaluate the link branches + AddLines2IncMatrix( ActorID ); // Includes the Lines + AddXfmr2IncMatrix( ActorID ); // Includes the Xfmrs + AddSeriesCap2IncMatrix( ActorID ); // Includes Series Cap + AddSeriesReac2IncMatrix( ActorID ); // Includes Series Reactors + IncMat_Ordered = false; +// } + } + } + + /******************************************************************************** + * This function returns the index of bus 1 with the Incidence * + * matrix for the given PDE * + *********************************************************************************/ + + + int TSolutionObj::get_PDE_Bus1_Location( String myPDE ) + { + int result = 0; + int i = 0; + size_t j = 0; + String myBUS; + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + with0->SetElementActive( myPDE ); + myBUS = with0->get_FActiveCktElement()->GetBus( 2 ); + j = myBUS.find( '.' ); + if ( j != String::npos ) + myBUS = myBUS.substr( 0, j ); + for ( int stop = (Inc_Mat_Cols.size() - 1), i = 0; i <= stop; i++) + if ( Inc_Mat_Cols[i] == myBUS ) + break; + result = i; + } + } + return result; + } + + /******************************************************************************** + * This function delivers the Row index connected to the Column at the input * + * Inside the B2N incidence Matrix * + *********************************************************************************/ + + + int TSolutionObj::get_IncMatrix_Row( int Col ) + { + int result = 0; + bool Tflag = false; + int idx_1 = 0; + result = - 1; + Tflag = true; + for ( int stop = ( IncMat.NZero() - 1 ), idx_1 = 1; idx_1 <= stop; idx_1++) //Looks for the Column in the IncMatrix + { + if ( ( IncMat.data[idx_1][1] == Col ) && Tflag ) + { + result = IncMat.data[idx_1][0]; + Tflag = false; + } + } + return result; + } + /******************************************************************************** + * This function delivers the Column index connected to the Row at the input * + * Inside the B2N incidence Matrix * + *********************************************************************************/ + + + int TSolutionObj::get_IncMatrix_Col( int Row ) + { + int result = 0; + bool Tflag = false; + int idx_1 = 0; + result = - 1; + Tflag = true; // Detection Flag + for ( int stop = ( IncMat.NZero() - 1 ), idx_1 = 1; idx_1 <= stop; idx_1++) //Looks for the row in the IncMatrix + { + if ( ( IncMat.data[idx_1][0] == Row ) && Tflag ) + { + Active_Cols.resize(2); + Active_Cols_Idx.resize(2); + Active_Cols[0] = IncMat.data[idx_1][1]; //Stores the indexes of both columns for the link branch + Active_Cols[1] = IncMat.data[idx_1 + 1][1]; //In case they need to be used in the future by the caller + Active_Cols_Idx[0] = IncMat.data[idx_1 - 1][2]; //Stores the indexes of both columns for the link branch + Active_Cols_Idx[1] = IncMat.data[idx_1][2]; //In case they need to be used in the future by the caller + result = IncMat.data[idx_1][1]; + Tflag = false; + } + } + return result; + } + + //*********Routine for extracting the Branch to Node incidence matrix*********** + //* Organized hierarchically. This routine also calculates the * + //* Levels vector for defining the proximity of the bus to the circuit's * + //* Backbone. To do it, this routine uses the CktTree class * + //****************************************************************************** + + + void TSolutionObj::Calc_Inc_Matrix_Org( int ActorID ) + { + + + // Ftree : TextFile; // For debugging + + TPDElement* pdElem; + TCktTree topo; + // TreeNm, // For debugging + // FileRoot, // For debugging + + String PDE_Name; // Name of the PDElement + + std::vector PDE_Buses; // Buses of the PDElement + //String* PDE_Buses; + + std::vector Temp_Array; // Local Shared variable + // Current number of levels for the active Bus + // Default counter + // Default counter + // Default counter + // Number of Zero level Buses + // Local Shared variable + + int nLevels = 0 // PDElements index + , i = 0, j = 0, j2 = 0, ZeroLevel = 0, BusdotIdx = 0, Row = 0, Col = 0, val = 0, nPDE = 0; + size_t BusdotIdx2 = 0; + try + { + if ( ActiveCircuit[ActorID] != NULL ) + { + // TreeNm := FileRoot + 'TopoTree_Cols.csv'; // For debuging + topo = ActiveCircuit[ActiveActor]->GetTopology(); + nLevels = 0; + nPDE = 0; + Inc_Mat_Cols.resize( 0 ); + //Init the spaser matrix +// if ( IncMat == NULL ) + IncMat = Tsparse_matrix(); +// else + IncMat.Reset(); + ActiveIncCell[0] = - 1; // Activates row 1 of the incidence matrix + if (( topo.Get_First() != NULL ) ) + { + pdElem = (TPDElement*) topo.Get_First(); + while (( pdElem != NULL ) ) + { + nLevels = topo.Get_Level(); + PDE_Name = pdElem->ParentClass->get_myClass_name() + "." + pdElem->get_Name(); + //******************Gets the buses to which the PDE is connected**************** + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + with0->SetElementActive( PDE_Name ); + PDE_Buses.resize(with0->get_FActiveCktElement()->Get_NTerms()); + for ( int stop = with0->get_FActiveCktElement()->Get_NTerms(), i = 1; i <= stop; i++) + { + PDE_Buses[i - 1] = with0->get_FActiveCktElement()->GetBus( i ); + BusdotIdx2 = PDE_Buses[i - 1].find( '.' ); + if ( BusdotIdx2 != String::npos ) + PDE_Buses[i - 1] = PDE_Buses[i - 1].substr( 0, BusdotIdx2 ); // removes the dot from the Bus Name + } + if ( Inc_Mat_Cols.size() == 0 ) //Get_First() iteration so the Cols array will be loaded + { + Inc_Mat_Cols.resize( 1 ); + Inc_Mat_levels.resize( 1 ); + Inc_Mat_Cols[0] = PDE_Buses[0]; + Inc_Mat_levels[0] = nLevels; + } + else //The Cols array is populated with something + { + nPDE++; + Inc_Mat_Rows.resize( nPDE ); + Inc_Mat_Rows[nPDE - 1] = PDE_Name; + for ( int stop = with0->get_FActiveCktElement()->Get_NTerms() - 1, j = 0; j <= stop; j++) + { + Row = ActiveIncCell[0]; //Sets the row + BusdotIdx = - 1; // Flag to not create a new variable + for ( int stop = (Inc_Mat_Cols.size() - 1), i = 0; i <= stop; i++) // Checks if the bus already exists in the Cols array + if ( Inc_Mat_Cols[i] == PDE_Buses[j] ) + BusdotIdx = i; + if ( BusdotIdx >= 0 ) + Col = BusdotIdx; //Sets the Col + else + { + Inc_Mat_Cols.push_back( PDE_Buses[j] ); + Inc_Mat_levels.push_back( nLevels ); + Col = Inc_Mat_Cols.size() - 1; //Sets the Col + } + if ( j == 0 ) + val = 1; //Sets the value + else + val = - 1; + IncMat.Insert( Row, Col, val ); + } + } + } + } + ActiveIncCell[0]++; + pdElem = (TPDElement*) topo.Get_Forward(); + } + } + /******************************************************************************** + * Now the levels array needs to be reprocessed to get the 0 level buses, * + * they are on a continuous path from the feeder head to the feeder end * + *********************************************************************************/ + BusdotIdx = MaxIntValue( &Inc_Mat_levels ); + for ( int stop = Inc_Mat_levels.size(), i = 0; i <= stop; i++) + if ( Inc_Mat_levels[i] == BusdotIdx ) + nLevels = i; + for ( int stop = BusdotIdx - 1, j = 1; j <= stop; j++) + { + for ( int stop = nLevels, i = 0; i <= stop; i++) + { + if ( Inc_Mat_levels[i] == j ) + ZeroLevel = i; + } + Inc_Mat_levels[ZeroLevel] = 0; + } + //**********Normalize the branches of the level between zero level buses******** + BusdotIdx = 0; + j = 0; + ZeroLevel = 0; + Temp_Array.resize( 0 ); + for ( int stop = (Inc_Mat_levels.size() - 1), i = 0; i <= stop; i++) + { + if ( Inc_Mat_levels[i] == 0 ) + { + if ( Temp_Array.size() > 0 ) // The array subset is large enough for + { //Normalizing it + BusdotIdx = MinIntValue( &Temp_Array ) - 1; + for ( int stop = ( Temp_Array.size() + ZeroLevel - 1 ), j2 = ZeroLevel; j2 <= stop; j2++) + Inc_Mat_levels[j2] = Inc_Mat_levels[j2] - BusdotIdx; + Temp_Array.resize( 0 ); + } + ZeroLevel = i + 1; + } + else + { + Temp_Array.push_back( Inc_Mat_levels[i] ); + } + } + //************Verifies is something else was missing at the end***************** + if ( ZeroLevel < ( Inc_Mat_levels.size() - 1 ) ) + { + BusdotIdx = 0; // Counter for defining the level + j = 0; // Stores the previous value (shift reg) + for ( int stop = (Inc_Mat_levels.size() - 1), j2 = ZeroLevel; j2 <= stop; j2++) + { + if ( Inc_Mat_levels[j2] >= j ) + BusdotIdx++; + else + { + ActiveIncCell[1] = get_IncMatrix_Row( j2 ); //Looks for the Column in the IncMatrix + if ( ActiveIncCell[1] < 0 ) //Checks if the col was located (just in case) + BusdotIdx = 1; + else + { + ActiveIncCell[2] = get_IncMatrix_Col( ActiveIncCell[1] ); //Looks for the row in the IncMatrix + if ( Active_Cols[0] == j2 ) + BusdotIdx = Inc_Mat_levels[Active_Cols[1]] + 1; + else + BusdotIdx = Inc_Mat_levels[ActiveIncCell[2]] + 1; + } + } + j = Inc_Mat_levels[j2]; + Inc_Mat_levels[j2] = BusdotIdx; + } + } + IncMat_Ordered = true; + } + } +// __finally + catch(...) + { + // to match with the try def in delphi + } + } + + /******************************************************************************** + * Routine created to empty a recently created folder * + *********************************************************************************/ + + + void DelFilesFromDir( String Directory, String FileMask, bool DelSubDirs ) + { + String SourceLst; + /* + TSHFileOpStruct FOS; + FillChar( FOS, sizeof( FOS ), 0 ); + FOS.wFunc = FO_DELETE; + SourceLst = Directory + DIRSEP_STR + FileMask + "\x00"; + FOS.pFrom = SourceLst.c_str(); + if ( ! DelSubDirs ) + FOS.fFlags = FOS.fFlags | FOF_FILESONLY; + // Remove the next line if you want a confirmation dialog box + FOS.fFlags = FOS.fFlags | FOF_NOCONFIRMATION; + // Add the next line for a "silent operation" (no progress box) + FOS.fFlags = FOS.fFlags | FOF_SILENT; + SHFileOperation( FOS ); + */ + } + /******************************************************************************** + * This routine evaluates if the current location is the best or if its * + * Necessary to move back one PDE just to cover a wider area * + *********************************************************************************/ + + + int TSolutionObj::CheckLocationIdx( int Idx ) + { + int result = 0; + if ( Inc_Mat_levels[Idx - 1] == 0 ) + result = Idx - 1; + else + result = Idx; + return result; + } + + //---------------------------------------------------------------------------- + + + + int TDSSSolution::Init( int Handle, int ActorID ) + { + int result = 0; + DoSimpleMsg( "Need to implement TSolution.Init", - 1 ); + result = 0; + return result; + } + + // =========================================================================================== + + double TSolutionObj::get_Solve_Time_Elapsed() + { + return Solve_Time_Elapsed; + } + + // =========================================================================================== + + double TSolutionObj::get_Total_Solve_Time_Elapsed() + { + return Total_Solve_Time_Elapsed; + } + + // =========================================================================================== + + double TSolutionObj::get_Step_Time_Elapsed() + { + return Step_Time_Elapsed; + } + + // =========================================================================================== + + double TSolutionObj::get_Total_Time_Elapsed() + { + return Total_Time_Elapsed; + } + + // =========================================================================================== + + + + void TSolutionObj::GetPCInjCurr( int ActorID, bool GFMOnly) + { + TDSSCktElement* pElem = nullptr; + bool valid = false; + + /* Get inj currents from all enabled PC devices */ + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + pElem = (TDSSCktElement *) with0->PCElements.Get_First(); + while ( pElem != NULL ) + { + valid = !(GFMOnly ^ pElem->GFM_Mode); + + /*# with pElem do */ + if ( pElem->Get_Enabled() && valid ) + pElem->InjCurrents( ActorID ); // uses NodeRef to add current into InjCurr Array; + pElem = (TDSSCktElement*) with0->PCElements.Get_Next(); + } + } + } + } + + void TSolutionObj::DumpProperties( TTextRec& F, bool Complete ) + { + int i = 0 + + // for dumping the matrix in compressed columns + , j = 0; + unsigned int p = 0; + klusparseset_t hY; + unsigned int nBus = 0, nNZ = 0; + std::vector < unsigned int > ColPtr; + std::vector < unsigned int > RowIdx; + complex* cVals; + WriteLn( F, "! OPTIONS" ); + + // Inherited DumpProperties(F,Complete); + Write( F, "! NumNodes = " ); WriteLn( F, ActiveCircuit[ActiveActor]->NumNodes, 0 ); + + /*WITH ParentClass Do + FOR i := 1 to NumProperties Do + Begin + Writeln(F,'Set ',PropertyName^[i],'=',PropertyValue^[i]); + End; + */ + Write( F, "Set Mode=" ); WriteLn( F, GetSolutionModeID() ); + Write( F, "Set ControlMode=" ); WriteLn( F, GetControlModeID() ); + Write( F, "Set Random=" ); WriteLn( F, GetRandomModeID() ); + Write( F, "Set hour=" ); WriteLn( F, DynaVars.intHour, 0 ); + Write( F, "Set sec=" ); WriteLn( F, Format( "%-g", DynaVars.T )); + Write( F, "Set year=" ); WriteLn( F, get_Fyear(), 0 ); + Write( F, "Set frequency=" ); WriteLn( F, Format( "%-g", get_FFrequency() )); + Write( F, "Set stepsize=" ); WriteLn( F, Format( "%-g", DynaVars.h )); + Write( F, "Set number=" ); WriteLn( F, NumberOfTimes, 0 ); + Write( F, "Set circuit=" ); WriteLn( F, ActiveCircuit[ActiveActor]->Get_Name() ); + Write( F, "Set editor=" ); WriteLn( F, DefaultEditor ); + Write( F, "Set tolerance=" ); WriteLn( F, Format( "%-g", ConvergenceTolerance )); + Write( F, "Set maxiterations=" ); WriteLn( F, MaxIterations, 0 ); + Write( F, "Set miniterations=" ); WriteLn( F, MinIterations, 0 ); + Write( F, "Set loadmodel=" ); WriteLn( F, GetLoadModel() ); + Write( F, "Set loadmult=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->get_FLoadMultiplier() )); + Write( F, "Set Normvminpu=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->NormalMinVolts )); + Write( F, "Set Normvmaxpu=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->NormalMaxVolts )); + Write( F, "Set Emergvminpu=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->EmergMinVolts )); + Write( F, "Set Emergvmaxpu=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->EmergMaxVolts )); + Write( F, "Set %mean=" ); WriteLn( F, Format( "%-.4g", ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Get_Mean() * 100.0 )); + Write( F, "Set %stddev=" ); WriteLn( F, Format( "%-.4g", ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Get_StdDev() * 100.0 )); + Write( F, "Set LDCurve=" ); WriteLn( F, ActiveCircuit[ActiveActor]->LoadDurCurve ); // Load Duration Curve + Write( F, "Set %growth=" ); WriteLn( F, Format( "%-.4g", ( ( ActiveCircuit[ActiveActor]->DefaultGrowthRate - 1.0 ) * 100.0 ) )); // default growth rate + /*# with ActiveCircuit[ActiveActor].AutoAddObj do */ + { + auto& with1 = ActiveCircuit[ActiveActor]->AutoAddObj; + Write( F, "Set genkw=" ); WriteLn( F, Format( "%-g", with1.GenkW )); + Write( F, "Set genpf=" ); WriteLn( F, Format( "%-g", with1.GenPF )); + Write( F, "Set capkvar=" ); WriteLn( F, Format( "%-g", with1.Capkvar )); + Write( F, "Set addtype=" ); + switch (with1.AddType ) + { + case GENADD: + WriteLn( F, "generator" ); + break; + case CAPADD: + WriteLn( F, "capacitor" ); + break; + } + } + Write( F, "Set allowduplicates=" ); + if ( ActiveCircuit[ActiveActor]->DuplicatesAllowed ) + WriteLn( F, "Yes" ); + else + WriteLn( F, "No" ); + Write( F, "Set zonelock=" ); + if ( ActiveCircuit[ActiveActor]->ZonesLocked ) + WriteLn( F, "Yes" ); + else + WriteLn( F, "No" ); + Write( F, "Set ueweight=" ); WriteLn( F, ActiveCircuit[ActiveActor]->UEWeight, 8, 2 ); + Write( F, "Set lossweight=" ); WriteLn( F, ActiveCircuit[ActiveActor]->LossWeight, 8, 2 ); + Write( F, "Set ueregs=" ); WriteLn( F, IntArrayToString( ActiveCircuit[ActiveActor]->UEregs, ActiveCircuit[ActiveActor]->NumUEregs ) ); + Write( F, "Set lossregs=" ); WriteLn( F, IntArrayToString( ActiveCircuit[ActiveActor]->LossRegs, ActiveCircuit[ActiveActor]->NumLossRegs ) ); + Write( F, "Set voltagebases=(" ); // changes the default voltage base rules + i = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + while ((with0->LegalVoltageBases)[i] > 0.0 ) + { + Write( F, (with0->LegalVoltageBases)[i], 10, 2 ); + i++; + } + } + WriteLn( F, ')' ); + switch ( Algorithm ) + { + case NORMALSOLVE: + WriteLn( F, "Set algorithm=normal" ); + break; + case NEWTONSOLVE: + WriteLn( F, "Set algorithm=newton" ); + break; + } + Write( F, "Set Trapezoidal=" ); + if ( ActiveCircuit[ActiveActor]->TrapezoidalIntegration ) + WriteLn( F, "yes" ); + else + WriteLn( F, "no" ); + Write( F, "Set genmult=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->GenMultiplier )); + Write( F, "Set Basefrequency=" ); WriteLn( F, Format( "%-g", ActiveCircuit[ActiveActor]->Fundamental )); + Write( F, "Set harmonics=(" ); // changes the default voltage base rules + if ( DoAllHarmonics ) + Write( F, "ALL" ); + else + for ( int stop = HarmonicListSize, i = 1; i <= stop; i++) + Write( F, Format( "%-g, ", (HarmonicList)[i] )); + WriteLn( F, ')' ); + Write( F, "Set maxcontroliter=" ); WriteLn( F, MaxControlIterations, 0 ); + WriteLn( F ); + if ( Complete ) + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with2 = ActiveCircuit[ActiveActor]; + { + hY = /*# Solution::*/ with2->Solution->hY; + + // get the compressed columns out of KLU + FactorSparseMatrix( hY ); // no extra work if already done + GetNNZ( hY, &nNZ ); + GetSize( hY, &nBus ); + ColPtr.resize( nBus + 1 ); + RowIdx.resize( nNZ ); + cVals = new complex[nNZ]; + GetCompressedMatrix( hY, nBus + 1, nNZ, &ColPtr[0], &RowIdx[0], cVals); + WriteLn( F, "System Y Matrix (Lower Triangle by Columns)" ); + WriteLn( F ); + WriteLn( F, " Row Col G B" ); + WriteLn( F ); + + // traverse the compressed column format + for ( int stop = nBus - 1, j = 0; j <= stop; j++) + { /// the zero-based column + for ( int stop = ColPtr[j + 1] - 1, p = ColPtr[j]; p <= stop; p++) + { + i = RowIdx[p]; // the zero-based row + WriteLn( F, Format( "[%4d,%4d] = %12.5g + j%12.5g", i + 1, j + 1, cVals[p].re, cVals[p].im )); + } + } + } + } + } + + + complex TSolutionObj::VDiff( int i, int j, int ActorID ) + { + complex result; + int k = 0; + if ( ADiakoptics && ( ActorID != 1 ) ) + result = csub( VoltInActor1( i ), VoltInActor1( j ) ); // V1-V2 + else + result = csub( NodeV[i], NodeV[j] ); // V1-V2 + return result; + } + + void TSolutionObj::WriteConvergenceReport(const String Fname) + { + int i = 0; + TTextRec F; + try + { + AssignFile(F, Fname); + Rewrite(F); + IOResultToException(); + WriteLn(F); + WriteLn(F, "-------------------"); + WriteLn(F, "Convergence Report:"); + WriteLn(F, "-------------------"); + WriteLn(F, "\"Bus.Node\", \"Error\", \"|V|\",\"Vbase\""); + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + for (int stop = with0->NumNodes, i = 1; i <= stop; i++) + /*# with MapNodeToBus^[i] do */ + { + TNodeBus with1 = with0->MapNodeToBus[i-1]; + { + Write(F, '\"'); Write(F, Pad((with0->BusList.Get(with1.BusRef) + "." + IntToStr(with1.NodeNum) + "\""), 18)); + Write(F, ", "); Write(F, Format("%8.5f", (ErrorSaved)[i])); + Write(F, ", "); Write(F, (VmagSaved)[i], 1, 5); + Write(F, ", "); Write(F, (NodeVbase)[i], 1, 5); + WriteLn(F); + } + } + } + WriteLn(F); + Write(F, "Max Error = "); WriteLn(F, Format("%8.5f", MaxError)); + //} + // __finally + // { + CloseFile(F); + if (AutoDisplayShowReport) + FireOffEditor(Fname); + } + catch (...) + { + // matches with delphi, there is no finally in native C + } + } + + // =========================================================================================== = + + + + void TSolutionObj::SumAllCurrents( int ActorID ) + { + TDSSCktElement* pElem; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + pElem = (TDSSCktElement*) with0->CktElements.Get_First(); + while ( pElem != NULL ) + { + pElem->SumCurrents( ActorID ); // sum terminal currents into system Currents Array + pElem = (TDSSCktElement*) with0->CktElements.Get_Next(); + } + } + } + } + + // =========================================================================================== = + + + + void TSolutionObj::DoControlActions( int ActorID ) + { + int XHour = 0; + double XSec = 0.0; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + switch ( ControlMode ) + { + case CTRLSTATIC: + { // execute the nearest set of control actions but leaves time where it is + if ( with0->ControlQueue.IsEmpty() ) + ControlActionsDone = true; + else + with0->ControlQueue.DoNearestActions( XHour, XSec, ActorID ); // ignore time advancement + } + break; + case EVENTDRIVEN: + { // execute the nearest set of control actions and advance time to that time + // **** Need to update this to set the "Intervalhrs" variable for EnergyMeters for Event-Driven Simulation **** + if // these arguments are var type + ( ! with0->ControlQueue.DoNearestActions( DynaVars.intHour, DynaVars.T, ActorID ) ) + ControlActionsDone = true;// Advances time to the next event + } + break; + case TIMEDRIVEN: + { // Do all actions having an action time <= specified time + if ( ! with0->ControlQueue.DoActions( DynaVars.intHour, DynaVars.T, ActorID ) ) + ControlActionsDone = true; + } + break; + case MULTIRATE: + { // execute the nearest set of control actions but leaves time where it is + if ( ! with0->ControlQueue.DoMultiRate( DynaVars.intHour, DynaVars.T, ActorID ) ) + ControlActionsDone = true; + } + break; + } + } + } + } + + // =========================================================================================== = + + + + void TSolutionObj::SampleControlDevices( int ActorID ) + { + TControlElem* ControlDevice; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + ControlDevice = NULL; + try + { + // Sample all controls and set action times in control Queue + ControlDevice = (TControlElem*) with0->DSSControls.Get_First(); + while ( ControlDevice != NULL ) + { + if ( ControlDevice->Get_Enabled() ) + ControlDevice->sample( ActorID ); + ControlDevice = (TControlElem*) with0->DSSControls.Get_Next(); + } + } + catch( std::exception & E ) + { + { + DoThreadSafeMsg("Error Sampling Control Device "+ ControlDevice->ParentClass->get_myClass_name() + + "." + ControlDevice->get_Name() + " Error = " + (std::string) E.what(), 484); +// throw @EControlProblem ::( "Solution aborted." ); + } + } + } + } + } + + // =========================================================================================== = + + + + void TSolutionObj::Sample_DoControlActions( int ActorID ) + { + if ( ControlMode == CONTROLSOFF ) + ControlActionsDone = true; + else + { + SampleControlDevices( ActorID ); + DoControlActions( ActorID ); + + /*This variable lets control devices know the bus list has changed*/ + ActiveCircuit[ActorID]->Control_BusNameRedefined = false; // Reset until next change + } + } + + + int TSolutionObj::Get_SolMode() + { + return DynaVars.SolutionMode; + } + + void TSolutionObj::Set_Mode( const int Value ) + { + DynaVars.intHour = 0; + DynaVars.T = 0.0; + Update_dblHour(); + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = false; + if ( ! OK_for_Dynamics( Value ) ) + return; + if ( ! OK_for_Harmonics( Value ) ) + return; + DynaVars.SolutionMode = Value; + ControlMode = DefaultControlMode; // Revert to default mode + LoadModel = DefaultLoadModel; + IsDynamicModel = false; + IsHarmonicModel = false; + SolutionInitialized = false; // reinitialize solution when mode set (except dynamics) + PreserveNodeVoltages = false; // don't do this unless we have to + SampleTheMeters = false; + + // Reset defaults for solution modes + switch ( DynaVars.SolutionMode ) + { + case PEAKDAY: case DAILYMODE: + { + DynaVars.h = 3600.0; + NumberOfTimes = 24; + SampleTheMeters = true; + } + break; + case SNAPSHOT: + { + IntervalHrs = 1.0; + NumberOfTimes = 1; + } + break; + case YEARLYMODE: + { + IntervalHrs = 1.0; + DynaVars.h = 3600.0; + NumberOfTimes = 8760; + SampleTheMeters = true; + } + break; + case DUTYCYCLE: + { + DynaVars.h = 1.0; + ControlMode = TIMEDRIVEN; + } + break; + case DYNAMICMODE: + { + DynaVars.h = 0.001; + ControlMode = TIMEDRIVEN; + IsDynamicModel = true; + PreserveNodeVoltages = true; // need to do this in case Y changes during this mode + } + break; + case EMPMODE: + { + DynaVars.h = 0.001; // Integration time step + ControlMode = TIMEDRIVEN; + IsDynamicModel = true; + PreserveNodeVoltages = true; // need to do this in case Y changes during this mode + } + break; + case EMPDAILYMODE: + { + DynaVars.h = 3600.0; // Integration time step + NumberOfTimes = 24; + SampleTheMeters = true; + // IsDynamicModel = false; + // PreserveNodeVoltages = true; // need to do this in case Y changes during this mode + } + break; + case GENERALTIME: + { + IntervalHrs = 1.0; + DynaVars.h = 3600.0; + NumberOfTimes = 1; // just one time step per Solve call expected + } + break; + case MONTECARLO1: + { + IntervalHrs = 1.0; + SampleTheMeters = true; + } + break; + case MONTECARLO2: + { + DynaVars.h = 3600.0; + SampleTheMeters = true; + } + break; + case MONTECARLO3: + { + IntervalHrs = 1.0; + SampleTheMeters = true; + } + break; + case MONTEFAULT: + { + IsDynamicModel = true; + } + break; + case FAULTSTUDY: + { + IsDynamicModel = true; + } + break; + case LOADDURATION1: + { + DynaVars.h = 3600.0; + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = true; + SampleTheMeters = true; + } + break; + case LOADDURATION2: + { + DynaVars.intHour = 1; + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = true; + SampleTheMeters = true; + } + break; + case AUTOADDFLAG: + { + IntervalHrs = 1.0; + ActiveCircuit[ActiveActor]->AutoAddObj.ModeChanged = true; + } + break; + case HARMONICMODE: + { + ControlMode = CONTROLSOFF; + IsHarmonicModel = true; + LoadModel = ADMITTANCE; + PreserveNodeVoltages = true; // need to do this in case Y changes during this mode + } + break; + case HARMONICMODET: + { + IntervalHrs = 1.0; + DynaVars.h = 3600.0; + NumberOfTimes = 1; + ControlMode = CONTROLSOFF; + IsHarmonicModel = true; + LoadModel = ADMITTANCE; + PreserveNodeVoltages = true; // need to do this in case Y changes during this mode + } + break; + } + + /*Moved here 9-8-2007 so that mode is changed before reseting monitors, etc.*/ + + // Reset Meters and Monitors + MonitorClass[ActiveActor]->ResetAll( ActiveActor ); + /*by Dahei*/ + FMonitorClass[ActiveActor]->ResetAll( ActiveActor ); + EnergyMeterClass[ActiveActor]->ResetAll( ActiveActor ); + DoResetFaults(); + DoResetControls(); + } + + + void TSolutionObj::AddInAuxCurrents( int SolveType, int ActorID ) + { + /*FOR i := 1 to ActiveCircuit[ActiveActor].NumNodes Do Caccum(Currents^[i], AuxCurrents^[i]);*/ + // For Now, only AutoAdd Obj uses this + if ( DynaVars.SolutionMode == AUTOADDFLAG ) + ActiveCircuit[ActorID]->AutoAddObj.AddCurrents( SolveType, ActorID ); + } + + void TSolutionObj::ZeroAuxCurrents( int ActorID ) + { + int i = 0; + // FOR i := 1 to ActiveCircuit[ActorID].NumNodes Do AuxCurrents^[i] := CZERO; + } + + + void TSolutionObj::Check_Fault_Status( int ActorID ) + { + TFaultObj* pFault; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + pFault = (TFaultObj*) with0->Faults.Get_First() ; + while ( pFault != NULL ) + { + pFault->CheckStatus( ControlMode, ActorID ); + pFault = ( TFaultObj* ) with0->Faults.Get_Next() ; + } + } + } /*End With*/ + } + + + /* This procedure is called for Solve Direct and any other solution method + that does not get the injection currents for PC elements normally. In Dynamics mode, + Generators are voltage sources ... + + Procedure TSolutionObj.GetMachineInjCurrents; + + Var + pElem:TDSSCktElement; + + begin + // do machines in Dynamics Mode + IF IsDynamicModel THEN + With ActiveCircuit[ActiveActor] DO Begin + + pElem := Generators.Get_First(); + WHILE pElem<>nil Do Begin + IF pElem.Enabled THEN pElem.InjCurrents; // uses NodeRef to add current into InjCurr Array; + pElem := Generators.Get_Next(); + End; + + End; + + end; + */ + + + bool TSolutionObj::OK_for_Dynamics( const int Value ) + { + bool result = false; + bool ValueIsDynamic = false; + result = true; + switch ( Value ) + { + case MONTEFAULT: case DYNAMICMODE: case FAULTSTUDY: case EMPMODE: + ValueIsDynamic = true; + break; + default: + ValueIsDynamic = false; + } + + /*When we go in and out of Dynamics mode, we have to do some special things*/ + if ( IsDynamicModel && ! ValueIsDynamic ) + InvalidateAllPCElements(); // Force Recomp of YPrims when we leave Dynamics mode + if ( ! IsDynamicModel && ValueIsDynamic ) + { // see if conditions right for going into dynamics + if ( ActiveCircuit[ActiveActor]->Issolved ) + switch (Value) + { + case EMPMODE: + break; + // Don't initialize states. All that is handled later, before the run is initiated + default: // This remains the same for all other modes: DYNAMICMODE, MONTEFAULT, FAULTSTUDY + CalcInitialMachineStates(); // set state variables for machines (loads and generators) + } + else + { + /*Raise Error Message if not solved*/ + DoSimpleMsg( "Circuit must be solved in a non-dynamic mode before entering Dynamics or Fault study modes!" + CRLF + + "If you attempted to solve, then the solution has not yet converged.", 486 ); + if ( In_Redirect ) + Redirect_Abort = true; // Get outta here + result = false; + } + } + return result; + } + + bool TSolutionObj::OK_for_Harmonics( const int Value ) + + /*When we go in and out of Harmonics mode, we have to do some special things*/ + { + bool result = false; + result = true; + if ( IsHarmonicModel && ! ( ( Value == HARMONICMODE ) || ( Value == HARMONICMODET ) ) ) + { + InvalidateAllPCElements(); // Force Recomp of YPrims when we leave Harmonics mode + Set_Frequency(ActiveCircuit[ActiveActor]->Fundamental); // Resets everything to norm + } + if ( ! IsHarmonicModel && ( ( Value == HARMONICMODE ) || ( Value == HARMONICMODET ) ) ) + { // see if conditions right for going into Harmonics + if ( ( ActiveCircuit[ActiveActor]->Issolved ) && ( get_FFrequency() == ActiveCircuit[ActiveActor]->Fundamental ) ) + { + if // set state variables for machines (loads and generators) and sources + ( ! InitializeForHarmonics( ActiveActor ) ) + { + result = false; + if ( In_Redirect ) + Redirect_Abort = true; // Get outta here + } + } + else + { + DoSimpleMsg( "Circuit must be solved in a fundamental frequency power flow or direct mode before entering Harmonics mode!", 487 ); + if ( In_Redirect ) + Redirect_Abort = true; // Get outta here + result = false; + } + } + return result; + } + + + void TSolutionObj::Set_Frequency( const double Value ) + { + if ( FFrequency != Value ) + { + FrequencyChanged = true; // Force Rebuild of all Y Primitives + SystemYChanged = true; // Force rebuild of System Y + } + FFrequency = Value; + if ( ActiveCircuit[ActiveActor] != NULL ) + Harmonic = FFrequency / ActiveCircuit[ActiveActor]->Fundamental; // Make Sure Harmonic stays in synch + } + + + void TSolutionObj::Increment_time( ) + { + /*# with DynaVars do */ + { + auto& with0 = DynaVars; + with0.T = with0.T + with0.h; + while (with0.T >= 3600.0 ) + { + with0.intHour++; + with0.T = with0.T - 3600.0; + } + Update_dblHour(); + } + } + + + void TSolutionObj::InitPropertyValues( int ArrayOffset ) + { + Set_PropertyValue(1, ""); + inherited::InitPropertyValues( NumPropsThisClass ); + } + + + void TSolutionObj::Set_Year( const int Value ) + { + if ( DIFilesAreOpen[ActiveActor] ) + EnergyMeterClass[ActiveActor]->CloseAllDIFiles( ActiveActor ); + Fyear = Value; + DynaVars.intHour = 0; /*Change year, start over*/ + DynaVars.T = 0.0; + Update_dblHour(); + EnergyMeterClass[ActiveActor]->ResetAll( ActiveActor ); // force any previous year data to complete + } + + + void TSolutionObj::Set_Total_Time( const double Value ) + { + Total_Time_Elapsed = Value; + } + + + + void TSolutionObj::SaveVoltages() + { + TTextRec F; + complex Volts; + int i = 0, j = 0; + String BusName; + try + { + AssignFile(F, CircuitName_[ActiveActor] + "SavedVoltages.Txt"); + Rewrite(F); + IOResultToException(); + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + for (int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + BusName = with0->BusList.Get(i); + for (int stop = with0->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + Volts = NodeV[with0->Buses[i - 1]->GetRef(j)]; + Write(F, BusName); + Write(F, ", "); + Write(F, with0->Buses[i - 1]->GetNum(j), 0); + WriteLn(F, Format(", %-.7g, %-.7g", cabs(Volts), cdang(Volts))); + } + } + } + + CloseFile(F); + GlobalResult = CircuitName_[ActiveActor] + "SavedVoltages.Txt"; + } + catch (std::exception& E) + { + DoSimpleMsg("Error opening Saved Voltages File: " + (std::string)E.what(), 488); + return; + } + catch (...) + { + // to match with delphi + } + } + + + /* ************* MAIN SOLVER CALL *************************/ + + + int TSolutionObj::SolveSystem( pNodeVarray V, int ActorID ) + { + int result = 0; + longInt RetCode = 0; + // iRes : LongWord; + // dRes : Double; + + String myMsg; + + /*Note: NodeV[0] = 0 + j0 always. Therefore, pass the address of the element 1 of the array. + */ + try + { + // new function to log KLUSolve.DLL function calls; same information as stepping through in Delphi debugger + // SetLogFile ('KLU_Log.txt', 1); + if ( ! ADiakoptics || ( ActorID == 1 ) ) + RetCode = SolveSparseSet( hY, &(V[1]), &(Currents[1])); // Solve for present InjCurr + else + RetCode = SolveSparseSet( hY, &(V[LocalBusIdx[0]]), &(Currents[1]) ); // Solve for present InjCurr in Actor 1 context + /** Commented out because results are not logged currently -- but left in just in case + // new information functions + GetFlops(hY, @dRes); + GetRGrowth(hY, @dRes); + GetRCond(hY, @dRes); + // GetCondEst (hY, @dRes); // this can be expensive + GetSize(hY, @iRes); + GetNNZ(hY, @iRes); + GetSparseNNZ(hY, @iRes); + GetSingularCol(hY, @iRes); + **/ + } + catch (std::exception & E) + { //Raise + { + myMsg = "Error Solving System Y Matrix. Sparse matrix solver reports numerical error: " + (std::string) E.what(); + DoThreadSafeMsg( myMsg, 0 ); + SolutionAbort = true; + } + } + result = RetCode; + return result; + } + + + void TSolutionObj::Update_dblHour( ) + { + DynaVars.dblHour = DynaVars.intHour + double( DynaVars.T ) / 3600.0; + } + + + void TSolutionObj::UpdateLoopTime( ) + { + + // Update Loop time is called from end of time step cleanup + // Timer is based on beginning of SolveSnap time + QueryPerformanceCounter( &LoopEndtime ); +#ifndef windows + Step_Time_Elapsed = LoopEndtime - SolveStartTime; +#else + Step_Time_Elapsed = ( double( ( LoopEndtime.QuadPart - SolveStartTime.QuadPart ) ) / CPU_Freq ) * 1000000; +#endif + } + + + void TSolutionObj::UpdateVBus( int ActorID ) + + // Save present solution vector values to buses + + { + int i = 0, j = 0; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto& with1 = with0->Buses[i - 1]; + if (!( with1->VBus.empty() ) ) + for ( int stop = with1->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + (with1->VBus)[j - 1] = NodeV[with1->GetRef( j )]; + } + } + } + } + + + void TSolutionObj::RestoreNodeVfromVbus( ) + { + int i = 0, j = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto& with1 = with0->Buses[i - 1]; + if (!( with1->VBus.empty() ) ) + for ( int stop = with1->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + NodeV[with1->GetRef( j )] = (with1->VBus)[j - 1]; + } + } + } + + + int TSolutionObj::SolveYDirect( int ActorID ) + + /* Solves present Y matrix with no injection sources except voltage and current sources */ + { + int result = 0; + result = 0; + if ( (!ADiakoptics) || (ActorID != 1) ) + { + ZeroInjCurr( ActorID ); // Side Effect: Allocates InjCurr + GetSourceInjCurrents( ActorID ); + if ( IsDynamicModel ) + GetPCInjCurr( ActorID ); // Need this in dynamics mode to pick up additional injections + SolveSystem( &NodeV[0], ActorID); // Solve with Zero injection current + } + else + { + ADiak_PCInj = false; + Solve_Diakoptics( ); // A-Diakoptics + } + return result; + } + + + void TSolutionObj::Get_Yiibus( ) + { + unsigned int nNZ = 0; + longInt result = 0; + unsigned int i = 0, Row = 0, Col = 0; + double re = 0.0, im = 0.0; + std::vector ColIdx; + std::vector RowIdx; + std::vector cVals; + int sf = 0; + if ( ! hY ) + { + DoSimpleMsg( "Y Matrix not Built.", 222 ); + return; + } + // print lower triangle of G and B using new functions + // this compresses the entries if necessary - no extra work if already solved + result = FactorSparseMatrix( hY ); + result = GetNNZ( hY, &nNZ ); + //GetSize (temphY, @nBus); // we should already know this + try + { + ColIdx.resize(nNZ); + RowIdx.resize(nNZ); + cVals.resize(nNZ); + nNZ_yii = nNZ;//how many lines of Y sparse + if ( !pColIdx_Yii.empty() ) + pColIdx_Yii.clear(); + pColIdx_Yii.resize( nNZ_yii + 1 ); + if ( !pRowIdx_Yii.empty() ) + pRowIdx_Yii.clear(); + pRowIdx_Yii.resize( nNZ_yii + 1 ); + if ( !pcVals_Yii.empty() ) + pcVals_Yii.clear(); + pcVals_Yii.resize( nNZ_yii + 1 ); + sf = GetTripletMatrix( hY, nNZ, &(ColIdx[0]), &(RowIdx[0]), &(cVals[0])); + // shows how to easily traverse the triplet format + for ( int stop = nNZ - 1, i = 0; i <= stop; i++) + { + Col = ColIdx[i] + 1; + Row = RowIdx[i] + 1; + if ( Row == Col ) + { //diagnal + re = cVals[i].re; + im = cVals[i].im; + NodeYii[Row] = cmplx( re, im ); + } + // pColIdx_Yii, pRowIdx_Yii, pcVals_Yii + pColIdx_Yii[i + 1] = Col; // begin from 1 + pRowIdx_Yii[i + 1] = Row; + pcVals_Yii[i + 1] = cVals[i]; + } + NodeYiiEmpty = false; + cVals.clear(); + ColIdx.clear(); + RowIdx.clear(); + } + //__finally + //{ + catch(...) + { + //To match with delphi (try) + } + } + + //---------------------------------------------------------------------------------------------------- + + double TSolutionObj::get_FFrequency() + { + return FFrequency; + } + + //---------------------------------------------------------------------------------------------------- + + int TSolutionObj::get_Fyear() + { + return Fyear; + } + + //---------------------------------------------------------------------------------------------------- + + complex TSolutionObj::Get_Yij( int node_ref_i, int node_ref_j ) // get Gij + j Bij + + { + complex result; + int i = 0 + //nNZ_yii :LongWord; //how many lines in Yii + //pColIdx_Yii, pRowIdx_Yii :pLongIntArray;//array of LongWord; //cols and rows + //pcVals_Yii :pComplexArray; //vals of yii + , Col = 0, Row = 0; + for ( int stop = nNZ_yii, i = 1; i <= stop; i++) + { + Col = (pColIdx_Yii)[i]; + Row = (pRowIdx_Yii)[i]; + if ( ( Row == node_ref_i ) && ( Col == node_ref_j ) ) + result = (pcVals_Yii)[i]; + } + return result; + } + + /******************************************************************************** + * Used to create the OpenDSS Solver thread * + ******************************************************************************** + */ + + int TSolver::TMessageQueue::recv() + { + // wait_for should check every 100ms in case we miss the notify: +#if __cplusplus >= 201402L + using namespace std::chrono_literals; + const auto wait_timeout = 100ms; // C++14 permits a shorter syntax. +#else + // C++11 is needed by a customer for older RHEL 7.x systems + const auto wait_timeout = std::chrono::milliseconds(100); +#endif + + std::unique_lock mlock(m_mutex); + while(m_queue.empty()) + { + // wait_for will unlock m_mutex until m_convar is notified or + // wait_timeout expires. + m_condVar.wait_for(mlock, wait_timeout); + } + + int msg = m_queue.front(); + m_queue.pop(); + return msg; // m_mutex is unlocked here when mlock goes out of scope. + } + + void TSolver::TMessageQueue::send(int msg) + { + std::unique_lock mlock(m_mutex); + m_queue.push(msg); + m_condVar.notify_one(); + } + + TSolver::TSolver( int local_CPU, int ID ) + : ActorID(ID), + MsgType(-1), + AD_Init(false), + ActorActive(true), + Processing(false), + ActorThread(&TSolver::Execute, this) // initialize this last; it starts the execution thread + { + } + + /*--------------------------------------------------------- + | Send a message to the actor | + ----------------------------------------------------------*/ + + + void TSolver::Send_Message( int Msg ) + { + MyMessages.send(Msg); // Notifies that there is a new simulation job + } + + /*--------------------------------------------------------- + | Checks if the actor has power injection Obj | + ----------------------------------------------------------*/ + + + bool TSolver::HasInjObj( ) + { + bool result = false; + int ListSize = 0, jj = 0; + TVsourceObj* VSourceObj; + TIsourceObj* ISourceObj; + if ( ActorID == 2 ) + result = true; + else + { + result = false; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + TSolutionObj* with1 = ActiveCircuit[ActorID]->Solution; + { + // Starts looking for VSource + VSourceObj = (TVsourceObj*) VSourceClass[ActorID]->ElementList.Get_First(); + while ( VSourceObj != NULL ) + { + if ( VSourceObj->Get_Enabled() ) + { + result = true; + break; + } + VSourceObj = (TVsourceObj *) VSourceClass[ActorID]->ElementList.Get_Next(); + } + if ( ! result ) + { + // Goes for ISources + ISourceObj = (TIsourceObj*) IsourceClass[ActorID]->ElementList.Get_First(); + while ( ISourceObj != NULL ) + { + if ( ISourceObj->Get_Enabled() ) + { + result = true; + break; + } + ISourceObj = (TIsourceObj*) IsourceClass[ActorID]->ElementList.Get_Next(); + } + } + } + } + } + return result; + } + + /*--------------------------------------------------------- + | locates the local buses into actor 1's bus array | + ----------------------------------------------------------*/ + + + void TSolver::IndexBuses( ) + { + bool Found = false; + int k = 0, i = 0, j = 0; + String myBUS; + std::vector LclBus; + std::vector SrcBus; + String Ids [ 2/*# range 0..1*/ ]; + Ids[0] = "1_"; + Ids[1] = "2_"; + // Get_First(), get the list of buses in actor 1 + SrcBus.resize( 1 ); + if ( ActiveCircuit[1] != NULL ) + { + /*# with ActiveCircuit[1] do */ + { + TDSSCircuit* with0 = ActiveCircuit[1]; + { + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + /*# with MapNodeToBus^[i] do */ + { + auto& with1 = with0->MapNodeToBus[i - 1]; + SrcBus[SrcBus.size() - 1] = ToUpperCaseStr(with0->BusList.Get(with1.BusRef)) + Format(".%-d", with1.NodeNum ); + } + SrcBus.resize( SrcBus.size() + 1 ); + } + } + } + } + // rebuilds the Y matrix to relocate the local buses + BuildYMatrix( WHOLEMATRIX, true, ActorID ); // Side Effect: Allocates V + // Then, get the list of buses in my actor + LclBus.resize( 1 ); + if ( ActiveCircuit[ActorID] != NULL ) + { + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with2 = ActiveCircuit[ActorID]; + { + for ( int stop = with2->NumNodes, i = 1; i <= stop; i++) + { + /*# with MapNodeToBus^[i] do */ + { + auto& with3 = with2->MapNodeToBus[i - 1]; + LclBus[LclBus.size() - 1] = ToUpperCaseStr(with2->BusList.Get(with3.BusRef)) + Format(".%-d", with3.NodeNum ); + } + LclBus.resize( LclBus.size() + 1 ); + } + } + } + } + // Initializes the bus index vector + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto& with4 = ActiveCircuit[ActorID]->Solution; + + with4->LocalBusIdx.resize( LclBus.size() - 1 ); + for ( int stop = (with4->LocalBusIdx.size() - 1 ), i = 0; i <= stop; i++) + { + for ( int stop = ( SrcBus.size() - 1 ), j = 0; j <= stop; j++) + if ( LclBus[i] == SrcBus[j] ) + break; + with4->LocalBusIdx[i] = j + 1; + } + + // Initializes the list for easy accessing the ADiakoptics Isources + // if AD_IBus = nil then AD_IBus := TList.Create ELSE AD_IBus.Clear; + // if AD_ISrcIdx = nil then AD_ISrcIdx := TList.Create ELSE AD_ISrcIdx.Clear; + // Locates the ISource used for the local ADiakoptics algorithm + for ( int stop = ( ActiveCircuit[1]->Contours.NZero() - 1 ), j = 0; j <= stop; j++) + { + myBUS = SrcBus[ActiveCircuit[1]->Contours.CData[j].Row]; + // checks if the bus in in this circuit + Found = false; + for ( int stop = ( LclBus.size() - 1 ), k = 0; k <= stop; k++) + { + if ( LclBus[k] == myBUS ) + { + Found = true; + break; + } + } + if ( Found ) // If found, add it to the indexed list + { +// with4->AD_IBus.Add( k + 1 ); +// with4->AD_ISrcIdx.Add( ActiveCircuit[1]->Contours.CData[j].Row ); + } + } + } + } + + /*--------------------------------------------------------- + | Sets the local busy flag | + ----------------------------------------------------------*/ + + + void TSolver::Set_Processing( bool Nval ) + { + Processing = Nval; + } + + /*--------------------------------------------------------- + | Gets the local busy flag | + ----------------------------------------------------------*/ + + + bool TSolver::Get_Processing( ) + { + bool result = false; + result = Processing; + return result; + } + + /*--------------------------------------------------------- + | Returns the CPU assigned to the actor | + ----------------------------------------------------------*/ + + + int TSolver::Get_CPU( ) + { + int result = 0; + result = ActorCPU[ActorID]; + return result; + } + + /*--------------------------------------------------------- + | Sets the CPU assigned to the actor | + ----------------------------------------------------------*/ + + + void TSolver::Set_CPU( int CPU ) + { + ActorCPU[ActorID] = CPU; + } + + /*--------------------------------------------------------- + | Zeroes the local voltage array | + ----------------------------------------------------------*/ + + + void TSolver::ZeroLocalV( ) + { + int i = 0; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + ActiveCircuit[ActorID]->Solution->NodeV[i] = CZero; + } + } + } + + /*--------------------------------------------------------- + | Uploads the local voltage array in the masters | + | using the index map obtained in previous steps | + ----------------------------------------------------------*/ + + + void TSolutionObj::UploadV2Master( int ActorID ) + { + int Idx = 0, i = 0; + // if ActorID = 2 then + // Begin + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + for ( int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + Idx = LocalBusIdx[i - 1]; + ActiveCircuit[1]->Solution->NodeV[Idx] = ActiveCircuit[ActorID]->Solution->NodeV[i]; + } + } + } + + // End; + } + + + /*--------------------------------------------------------- + | Retunrs the voltage at the node given at NodeIdx in | + | context of actor 1 (A-Diakoptics) | + ----------------------------------------------------------*/ + + + complex TSolutionObj::VoltInActor1( int NodeIdx ) + { + complex result; + if ( NodeIdx != 0 ) + NodeIdx = NodeIdx + ( LocalBusIdx[0] - 1 ); + // In the context of actor 1 + result = ActiveCircuit[1]->Solution->NodeV[NodeIdx]; + return result; + } + + /*--------------------------------------------------------- + | Updates the local ISources using the data obtained | + | for Ic in actor 1 | + ----------------------------------------------------------*/ + + + void TSolutionObj::UpdateISrc( int ActorID ) + { + int LclIdx = 0, Idx = 0, i = 0; + bool Found = false; + complex myCmplx; + /* + # with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + TSolutionObj* with1 = ActiveCircuit[ActorID]->Solution; + { + for ( int stop = ( with1->AD_IBus.Count - 1 ), i = 0; i <= stop; i++) + { + for ( int stop = ( ActiveCircuit[1].Ic.NZero - 1 ), Idx = 0; Idx <= stop; Idx++) + { + if ( ActiveCircuit[1].Ic.CData[Idx].Row == AD_ISrcIdx.Items[i] ) + { + Found = true; + break; + } + } + if ( Found ) + { + // Adds the present current with the adjustment + myCmplx = cmulreal( ActiveCircuit[1]->Ic.CData[Idx].Value, ( - 1.0 ) ); + Currents[AD_IBus.Items[i]] = cadd( myCmplx, Currents[AD_IBus.Items[i]] ); + } // Otherwise is just another ISource in the zone + } + } + } + */ + } + + /******************************************************************************** + * executes the selected solution algorithm * + ******************************************************************************** + */ + + + void TSolver::Execute( ) + { + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + ActorActive = true; // for now, sequential + while ( ActorActive ) + { + { + MsgType = MyMessages.recv(); + Processing = true; + switch ( MsgType ) + { + case // Evaluates the incomming message + SIMULATE: // Simulates the active ciruit on this actor + try + { + { // Checks if this is the coordinator actor in A-Diakoptics mode + // Normal solution routine + switch ( with1->DynaVars.SolutionMode ) + { + case SNAPSHOT: + with1->SolveSnap( ActorID ); + break; + case YEARLYMODE: + SolveYearly( ActorID ); + break; + case DAILYMODE: + SolveDaily( ActorID ); + break; + case DUTYCYCLE: + SolveDuty( ActorID ); + break; + case DYNAMICMODE: + SolveDynamic( ActorID ); + break; + case MONTECARLO1: + SolveMonte1( ActorID ); + break; + case MONTECARLO2: + SolveMonte2( ActorID ); + break; + case MONTECARLO3: + SolveMonte3( ActorID ); + break; + case PEAKDAY: + SolvePeakDay( ActorID ); + break; + case LOADDURATION1: + SolveLD1( ActorID ); + break; + case LOADDURATION2: + SolveLD2( ActorID ); + break; + case DIRECT: + with1->SolveDirect( ActorID ); + break; + case MONTEFAULT: + SolveMonteFault( ActorID ); + break; // Monte Carlo Fault Cases + + case FAULTSTUDY: + SolveFaultStudy( ActorID ); + break; + case AUTOADDFLAG: + ActiveCircuit[ActorID]->AutoAddObj.Solve( ActorID ); + break; + case HARMONICMODE: + SolveHarmonic( ActorID ); + break; + case GENERALTIME: + SolveGeneralTime( ActorID ); + break; + case HARMONICMODET: + SolveHarmonicT( ActorID ); + break; //Declares the Hsequential-time harmonics + case EMPMODE: + SolveEMP(ActorID); + break; + case EMPDAILYMODE: + SolveEMPDaily(ActorID); + break; + default: + DoThreadSafeMsg( "Unknown solution mode.", 481 ); + } + QueryPerformanceCounter( &with1->Gendtime); +#ifndef windows + with1->Total_Solve_Time_Elapsed = with1->Gendtime - with1->GStartTime; +#else + with1->Total_Solve_Time_Elapsed = ( double( ( with1->Gendtime.QuadPart - with1->GStartTime.QuadPart ) ) / CPU_Freq ) * 1000000; +#endif + with1->Total_Time_Elapsed = with1->Total_Time_Elapsed + with1->Total_Solve_Time_Elapsed; + Processing = false; + FMessage = "1"; + } + + if (!NoFormsAllowed) + { + CoutLn("Actor " + to_string(ActorID) + ": Job done"); + cout << ">>"; + } + } + catch( std::exception & E ) + { + { + FMessage = "1"; + ActorStatus[ActorID] = 1; // Global to indicate that the actor is ready + SolutionAbort = true; + if ( ! Parallel_enabled ) + DoThreadSafeMsg( "Error Encountered in Solve: " + (std::string) E.what(), 482 ); + } + } + break; + case INIT_ADIAKOPTICS: + { + if ( ActorID > 2 ) + Start_Diakoptics(); // Initializes the actor for Diakoptics (if needed) + IndexBuses(); + } + break; + case SOLVE_AD1: + with1->SolveAD( ActorID, true ); + break; // Solves the model if the actor has PIE + + case SOLVE_AD2: + with1->SolveAD( ActorID, false ); + break; // Complements the solution + + case ZEROIVECTOR: + with1->ZeroInjCurr( ActorID ); + break; + case GETCURRINJ: + with1->GetSourceInjCurrents( ActorID ); + break; + case CALC_INJ_CURR: + with1->GetPCInjCurr( ActorID ); + break; + case DO_CTRL_ACTIONS: + { + with1->ControlActionsDone = false; + with1->Sample_DoControlActions( ActorID ); + MyMessages.send( CHECK_FAULT ); + MyMessages.send( CHECKYBUS ); + } + break; + case CHECK_FAULT: + with1->Check_Fault_Status( ActorID ); + break; + case CHECKYBUS: + { + if (with1->SystemYChanged ) + { + BuildYMatrix( WHOLEMATRIX, false, ActorID ); // Does not realloc V, I + } + /*by Dahei*/ + if (with1->NodeYiiEmpty ) + with1->Get_Yiibus(); + } + break; + case GETCTRLMODE: + { + // Brings the control mode from actor 1 + with1->ControlMode = ActiveCircuit[1]->Solution->ControlMode; + with1->DefaultControlMode = with1->ControlMode; + with1->MaxControlIterations = ActiveCircuit[1]->Solution->MaxControlIterations; + } + break; + case EXIT_ACTOR: // Terminates the thread + { + ActorActive = false; + Doterminate(); + + if (!NoFormsAllowed) + { + CoutLn("Actor " + to_string(ActorID) + " terminated"); + cout << ">>"; + } + } + break; + default: // I don't know what the message is + DoThreadSafeMsg( "Unknown message. ", 7010 ); + } + } + ActorStatus[ActorID] = 1; // Global to indicate that the actor is ready + } + } + } + } + + void TSolver::CallCallBack( ) + { +// if (( FInfoProc != NULL ) ) +// FInfoProc( FMessage ); + } + + // Initializes the variables of the A-Diakoptics worker + + + + void TSolver::Start_Diakoptics( ) + { + size_t jj = 0; + TVsourceObj* VSourceObj; + String BusName; + DynStringArray myPDEList; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + TSolutionObj* with1 = ActiveCircuit[ActorID]->Solution; + { + // Select the main voltage source + VSourceObj = (TVsourceObj*) VSourceClass[ActorID]->ElementList.Get_First(); + // Gets the name of the branch directly connected to the feeder head to remove it + // (applies to all actors but actor 2 - first chunk of the system) + BusName = VSourceObj->GetBus( 1 ); + jj = BusName.find( '.' ); // removes the dot + if ( jj != String::npos ) + BusName = BusName.substr( 0, jj ); + SetActiveBus( BusName ); // Activates the Bus + myPDEList = with0->getPDEatBus( with0->BusList.Get( with0->ActiveBusIndex + 1 ) ); + // Disables the link branch + DSSExecutive[ActorID]->Set_Command( myPDEList[0] + ".enabled=False"); + // Now disables all the VSources added artificially + while ( VSourceObj != NULL ) + { + BusName = ToLowerCaseStr( VSourceObj->get_Name() ); + if ( BusName == "source" ) + VSourceObj->Set_Enabled(false); // Disables the artificial VSource phase 1 + else + if ( BusName == "vph_2" ) + VSourceObj->Set_Enabled(false); // Disables the artificial VSource phase 2 + else + if ( BusName == "vph_3" ) + VSourceObj->Set_Enabled(false); // Disables the artificial VSource phase 3 + VSourceObj = (TVsourceObj*) VSourceClass[ActorID]->ElementList.Get_Next(); + } + } + } + } + + + void TSolver::Notify_Main( ) + { + complex CNum; + int i = 0, j = 0, Idx = 0; + // Will do something + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + TSolutionObj* with1 = ActiveCircuit[ActorID]->Solution; + { + i = with0->NumNodes; + for ( int stop = i, Idx = 1; Idx <= stop; Idx++) + { + // if it doesn't includes any power injection element (Isource, VSource) + // returns dV to correct the interconnection equation + if ( ActorID > 2 ) + CNum = csub( with1->NodeV[Idx], with1->Node_dV[Idx] ); + else + CNum = with1->NodeV[Idx]; + ActiveCircuit[1]->V_0.Insert( ( Idx + with0->VIndex - 1 ), 0, CNum ); + } + } + } + } + + + void TSolver::Doterminate( ) // Is the end of the thread + { + TObject* ex = NULL; + ActorActive = false; + Processing = false; + ActorStatus[ActorID] = 1; // Global to indicate that the actor is ready + } + + + TSolver::~TSolver( ) + { + // todo check: inherited::Destroy; + Send_Message( EXIT_ACTOR ); + ActorThread.join(); + } + + void Solution_initialization() + { +// IsMultiThread = true; + } + + class Solution_unit + { + public: + Solution_unit() + { + Solution_initialization(); + } + }; + + Solution_unit _Solution_unit; + + +}// namespace Solution + + + + + + diff --git a/OpenDSSC/Common/Solution.h b/OpenDSSC/Common/Solution.h new file mode 100644 index 0000000..2b473f8 --- /dev/null +++ b/OpenDSSC/Common/Solution.h @@ -0,0 +1,485 @@ +#ifndef SolutionH +#define SolutionH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + 8-14-99 Added progress display and abort on longer solution types + 11-3-99 added calc voltage base + 11-21-99 modified to calc the voltage bases at the current load level set by the user. + 12-1-99 Added code to estimate starting point for P-V Generators + 12-2-99 Made more properties visible + 12-6-99 Merged properties with Set Command and removed from here + 12-15-99 Added global generatordispatchreference + 1-8-00 Fixed bug in autoadd generators to work with new generator model + set vminpu=0 and vmaxpu=1000000 + 1-30-00 to 2-1-00 Implemented control action check in solution + 2-19-00 Frequency changed reset to FALSE after being used (was causing all YPrims to be recomputed) + 2-23-00 Modified so that reset of meters and monitors is done upon setting the solution mode property. + After that the user must reset else the monitors just accumulate. + 3-20-00 Fixed bug with setting generator disp reference - made uniform for all types + 6-11-00 Split into two modules + moved auto add stuff to AutoAdd + 9-20-00 Added Dynamic Mode + 10-25-00 Added Fundamental Freq and other stuff for Harmonics Solution + 5-30-01 Added control iterations check, mostIterationsdone. + Fixed bug with controls off doing the solution too many times. + + 8-14-01 Reset IntervalHrs on Mode change + 7-11-02 Added check for system Y change after computing currents + + 9-28-03 Redefined V to NodeV and changed from an array from 1..n to 0..n where + 0-th element is alway ground(complex zero volts). + 8-14-06 Revised power flow initialization; removed forward/backward sweep + + 9-14-16 Added SampleTheMeters Flag to allow sampling energy meters in Time and DutyCycle mode + +*/ + + +#include "System.h" +#include "Sysutils.h" +#ifndef windows +#include // Assume POSIX so we have clock_gettime +static inline BOOL QueryPerformanceCounter(struct timespec *t) { + // Emulate MS Windows function with clock_gettime. The MS function + // returns 0 on failure, and nonzero on success, but clock_gettime + // returns 0 on success. + return 0==clock_gettime(CLOCK_MONOTONIC, t); +} +static inline double operator-(const struct timespec &a, const struct timespec &b) { + //a.tv_sec + a.tv_nsec/1e9 - ( b.tv_sec + b.tv_nsec/1e9 ) + //a.tv_sec - b.tv_sec + (a.tv_nsec - b.tv_nsec)/1e9 + return double(a.tv_sec - b.tv_sec) + double(a.tv_nsec - b.tv_nsec)/1e9; +} +#endif + +#include "Ucomplex.h" +#include "Arraydef.h" +#include "Command.h" +#include "Monitor.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Dynamics.h" +#include "EnergyMeter.h" +#include "VSource.h" +#include "Isource.h" + +#include "Sparse_Math.h" + +#include "CktElement.h" +#include +#include +#include +#include +#include +#include "klusolve.h" // klusparseset_t +#include + + +namespace Solution +{ + + class EControlProblem; + class ESolveError; + class TDSSSolution; + struct TLDs_sys_fms; + class TSolutionObj; + class TSolver; + + + const int NORMALSOLVE = 0; + const int NEWTONSOLVE = 1; + const int NCIMSOLVE = 2; + // Constants for the actor's messaging + + const int SIMULATE = 0; + const int EXIT_ACTOR = 1; + const int INIT_ADIAKOPTICS = 2; // Initializes the environment for the children actors + const int SOLVE_AD1 = 3; // solves for the actors with Power Injections -> E(0) + const int SOLVE_AD2 = 4; // Solves the sub-system and adds to the partial solution + const int CALC_INJ_CURR = 5; // Uses the total solution to estiamte the injection currents + const int DO_CTRL_ACTIONS = 6; // Does the control actions distributedly + const int ZEROIVECTOR = 8; // Zeroes the actor's I std::vector + const int GETCURRINJ = 9; // Gets the current injections for the actor and uploades them in the local I std::vector + const int CHECKYBUS = 10; // Rebuilds the YBus if needed at local level + const int CHECK_FAULT = 11; // Checks the fault status at local level + const int GETCTRLMODE = 12; // Sync the local control mode with actor 1 + const int ALL_ACTORS = 0; // Wait flag for all the actors + const int AD_ACTORS = 1; // Wait flag to wait only for the A-Diakoptics actors + + // Constants for the NCIM solution algorithm + const int PQ_Node = 0; // For indicating if the node is PQ (NCIM solver) + const int PV_Node = 1; // For indicating if the node is PV (NCIM solver) + + class EControlProblem : public std::runtime_error { + typedef std::runtime_error inherited; + EControlProblem(const String &Msg); + }; + + + class ESolveError : public std::runtime_error { + typedef std::runtime_error inherited; + ESolveError(const String &Msg); + }; // Raised when solution aborted + + + + typedef complex* TNodeVarray; + typedef complex* pNodeVarray; + /////////////////////////////////// + /*define LD_FM_Arry-by dahei*/ + +#pragma pack(push, 1) + //properties for Nodes + // highest voltage node + struct TLDs_sys_fms { + int clstr_num_hghst; + int ndnum_hghst; + bool b_ctrl_hghst; //can contribute more to the high volt problem + double volt_hghst; //p.u. + double volt_hgh_lmt; //p.u. + double Pinjec_hghst; //net P injection on this node + // lowest voltage node + int clstr_num_lwst; + int ndnum_lwst; + bool b_ctrl_lwst; //can contribute more to the high volt problem + double volt_lwst; //p.u. + double volt_lw_lmt; //p.u. + double Pinjec_lwst; // net P injection on this node + }; +#pragma pack(pop) + ////////////////////////////////////// + + + + class TDSSSolution : public DSSClass::TDSSClass { + typedef TDSSClass inherited; + friend class EControlProblem; + friend class ESolveError; + friend class TSolutionObj; + friend class TSolver; +// private: + // CommandList:TCommandlist; + protected: + void DefineProperties(); + public: + TDSSSolution(); + virtual ~TDSSSolution(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + }; + + + //typedef void ( __closure * TInfoMessageCall )( const String ); // Creates the procedure for sending a message + +#ifndef NULL +#define NULL 0 +#endif + class TSolver // pending to define thread behavior and inheriatance + { + //typedef TThread inherited; + friend class EControlProblem; + friend class ESolveError; + friend class TDSSSolution; + friend class TSolutionObj; + + class TMessageQueue + { + std::mutex m_mutex; + std::condition_variable m_condVar; + std::queue m_queue; // A queue for messaging to actors, the aim is to reduce inconsistency + public: + // These lines prevent TMessageQueue objects from being copied: + TMessageQueue(const TMessageQueue&) = delete; + TMessageQueue& operator=(const TMessageQueue&) = delete; + // Normal constructor: + TMessageQueue() = default; // Let the compiler give us the default. + int recv(); + void send(int); + }; + TMessageQueue MyMessages; + + public: + TSolver(int local_CPU, int ID) /*# overload */; + virtual void Execute(); + virtual void Doterminate(); + virtual ~TSolver(); + + //*******************************Private components***************************** + protected: + String FMessage, Msg_Cmd; + //TInfoMessageCall UINotifier, FInfoProc; + int ActorID, MsgType; + TEvent UIEvent, ActorMsg; // used to know if the actors require a partial solution + bool AD_Init, ActorActive, Processing; + TThread ActorThread; + void Start_Diakoptics(); + void Notify_Main(); + bool Get_Processing(); + void Set_Processing(bool Nval); + int Get_CPU(); + void Set_CPU(int CPU); + void IndexBuses(); // Locates the actor buses within the bus array in Actor 1 (interconnected) + bool HasInjObj(); // returns true if the actor has natural injection objects + void ZeroLocalV(); // Sets the local voltage std::vector (solution) equal to zero + + //*******************************Public components****************************** + public: + void Send_Message(int Msg); + void CallCallBack(); + }; + + + class TSolutionObj : public TDSSObject { + public: + typedef TDSSObject inherited; + friend class EControlProblem; + friend class ESolveError; + friend class TDSSSolution; + friend class TSolver; + // private: + pNodeVarray dV; // Array of delta V for Newton iteration + double FFrequency; + // //by Dahei + unsigned int nNZ_yii; //how many lines in Yii + std::vector pColIdx_Yii; + std::vector pRowIdx_Yii;//array of LongWord; //cols and rows + std::vector pcVals_Yii; //vals of yii + TSparse_Complex* MathYBus; // FOr operating the Y bus matrix using sparse algebra + // ========= + bool Converged(int ActorID); + bool OK_for_Dynamics(const int Value); + bool OK_for_Harmonics(const int Value); + void DoNewtonSolution(int ActorID); + void DoNormalSolution(int ActorID); + void DoNCIMSolution(int ActorID); + // PROCEDURE GetMachineInjCurrents; + void SetGeneratordQdV(int ActorID); + void SumAllCurrents(int ActorID); + void Set_Frequency(const double Value); + void Set_Mode(const int Value); + int Get_SolMode(); + void Set_Year(const int Value); + void Set_Total_Time(const double Value); + //============================================================================================================================================================= + /* NCIM algorithm rotuines and variables */ + vector deltaZ, // delta for Injection currents + deltaF, // delta for Voltages + pNodePower, // Array of complex storing the total power per node + pGenPower, // Stores the total generation power per iteration + NCIMY, // Stores the Non-zero values of the YBus Marix for multiplication + pNodeLimits; // Stores the total Q limits for PV buses using all the nodes in the model + bool InitGenQ; // Used to initialize variables the first time the algorithm runs or needs to be reinitialized + vector NCIMYRow, // Rows index of the Non-zero values of the Y Bus matrix + NCIMYCol; // Cols index of the Non-zero values of Y + vector pNodeType, // Array with the node type (PQ/PV) + pNodeNumGen; // Stores the number of generators per node for further use + vector pNodePVTarget; // Array with the target (voltage) of the PV Buses + vector PVBusIdx, // Stores the PVBus current index when indexing the jacobian matrix + PV2PQList; // To list the generators converted from PV to PQ when the condition is forced + klusparseset_t Jacobian; // Sparse Jacobian matrix + bool NCIMRdy; // Indicates if the NCIM environment and structures are initialized + bool IgnoreQLimit; // To indicate if the user wants to ignore the Q limits for generators + double GenGainNCIM; // Global gain for reactive power injection/absorption when using NCIM + longInt NCIMNodes; // Stores the number of nodes within the YBus matrix with only PDE + void LoadYBusNCIM(int ActorID); // Loads the Y bus admittance matrix into another structure for linear algebra purposes + void CalcInjCurr(int ActorID, bool InitGenQ); // Calculates the injection currents using the actual voltages ( I = Y * V ) + int GetNumGenerators(int ActorID, bool InitQ); // Gets and initializes all the generators in the model as PV buses + void BuildJacobian(int ActorID); // BUilds the jacobian matrix + int InitNCIM(int ActorID, bool InitY); // Host all the initialization routines for NCIM + void DOForceFlatStart(int ActorID); // Forces the voltage vector to a flat start (magnitude only). + void InitNCIMVectors(int ActorID); // Initializes the vectors for the node total power in NCIM + void GetNCIMPowers(int ActorID); // Populate the total power vector before solving + // Apply the PV bus current injection for NCIM + void DoPVBusNCIM(int ActorID, int i, double VTarget, complex Power); + // Apply the PQ bus current injection for NCIM + void DoPQBusNCIM(int ActorID, int i, complex V, complex Power); + // Apply the COnstant impedance bus current injection for NCIM + void DoZBusNCIM(int ActorID, int i, complex V, TcMatrix* YPrim); + + void ApplyCurrNCIM(int ActorID); // Apply the current injections before solving NCIM + void UpdateGenQ(int ActorID); // Updates the reacitve power delta for all the generators in the model. + void InitPQGen(int ActorID); // Initializes the generators declared as PQ type + void DistGenClusters(int ActorID); // Distributes the reactive power among clustered generators + void ReversePQ2PV(int ActorID); // Reverses the generators converted from PV 2 PQ for the next solution + //============================================================================================================================================================= + public: + int Algorithm; // NORMALSOLVE or NEWTONSOLVE + pComplexArray AuxCurrents;// For injections like AutoAdd + bool ControlActionsDone; + int ControlIteration, ControlMode; // EVENTDRIVEN, TIMEDRIVEN + double ConvergenceTolerance; + bool ConvergedFlag; + int DefaultControlMode; // EVENTDRIVEN, TIMEDRIVEN + int DefaultLoadModel; // 1=POWERFLOW 2=ADMITTANCE + bool DoAllHarmonics; + bool DynamicsAllowed; + TDynamicsRec DynaVars; + std::vector ErrorSaved; + bool FirstIteration, FrequencyChanged; // Flag set to true if something has altered the frequency + int Fyear; + double Harmonic; + pDoubleArray HarmonicList; + int HarmonicListSize; /*Handle for main (system) Y matrix*/ /*Handle for series Y matrix*/ + klusparseset_t hYsystem, hYseries, hY; /*either hYsystem or hYseries*/ + double IntervalHrs; // Solution interval since last solution, hrs. + int Iteration, LoadModel; // 1=POWERFLOW 2=ADMITTANCE + // Flag to allow sampling of EnergyMeters + bool VoltageBaseChanged, SampleTheMeters, SeriesYInvalid, SolutionInitialized, SystemYChanged, UseAuxCurrents, PreserveNodeVoltages, IsDynamicModel, IsHarmonicModel, LastSolutionWasDirect, LoadsNeedUpdating; // Index of the actor within the interconnected model (ADiakoptics) + // Number of times to solve + // 0 = none; 1 = gaussian; 2 = UNIFORM + // Counter incremented for each solution + bool DynamicsInitialized; + int ActorVIdx, NumberOfTimes, RandomType, SolutionCount, MaxIterations, MinIterations, MostIterationsDone, MaxControlIterations; + double MaxError; + std::vector NodeVbase; + std::vector VmagSaved; + + /*Voltage and Current Arrays*/ // Main System Voltage Array allows NodeV^[0]=0 + vector NodeV, Currents; // Main System Currents Array + + /*A-Diakoptics variables*/ // Used to store the partial solution voltage + vector Node_dV, Ic_Local; // Used to store the complementary curret + + //****************************************************************************** + // Incidence sparse matrix + Tsparse_matrix IncMat, Laplacian; // Laplacian sparse matrix + /*by Dahei for FMonitor*/ + /*------------------*/ + std::vector NodeYii; // Main System Y = G + jB, Bii for all nodes + bool NodeYiiEmpty; + /*Leaders of all FMonitors*/ + int clstr_num_hghst, clstr_num_lwst; + TLDs_sys_fms LD_FM[4/*# range 0..3*/]; + bool bCurtl; + //****************************Timing variables********************************** +#if ! ( defined( WIN32 ) || defined( WIN64 ) ) + struct timespec SolveStartTime; + struct timespec SolveEndtime; + struct timespec GStartTime; + struct timespec Gendtime; + struct timespec LoopEndtime; +#else + LARGE_INTEGER SolveStartTime; + LARGE_INTEGER SolveEndtime; + LARGE_INTEGER GStartTime; + LARGE_INTEGER Gendtime; + LARGE_INTEGER LoopEndtime; +#endif + double Total_Time_Elapsed; + double Solve_Time_Elapsed; + double Total_Solve_Time_Elapsed; + double Step_Time_Elapsed; + //****************************************************************************** + // ActiveCell of the Incidence Matrix: + // [0] = row + // [1] = col + // [2] = value + int ActiveIncCell[3/*# range 0..2*/]; + //****************************************************************************** + // IncMatrix Row and column descriptors + // Rows array (array of strings that tells what is the order of the PDElements) + // Columns array (array of strigns with the names of the cols of the Inc matrix)' + // Levels array (array of integers that describes the proximity level for each + // bus to the circuit's backbone) + std::vector < std::string > Inc_Mat_Rows; + std::vector < std::string > Inc_Mat_Cols; + std::vector < int > Inc_Mat_levels; + int temp_counter; + std::vector < int > Active_Cols; + std::vector < int > Active_Cols_Idx; + //****************************************************************************** + //********************Diakoptics solution mode variables************************ + bool ADiakoptics_ready; + int ADiakoptics_Actors; + std::vector LocalBusIdx; + // AD_IBus : TList; // Location of the Current injection bus + // AD_ISrcIdx : TList; // Locator of the ISource bus in actor 1 + //****************************************************************************** + TSolutionObj(DSSClass::TDSSClass* ParClass, const String solutionname); + virtual ~TSolutionObj(); + void ZeroAuxCurrents(int ActorID); + int SolveZeroLoadSnapShot(int ActorID); + void DoPFLOWsolution(int ActorID); + void Solve(int ActorID); // Main Solution dispatch + void SnapShotInit(int ActorID); + int SolveSnap(int ActorID); // solve for now once + int SolveDirect(int ActorID); // solve for now once, direct solution + int SolveYDirect(int ActorID); // Similar to SolveDirect; used for initialization + int SolveCircuit(int ActorID); // SolveSnap sans control iteration + void CheckControls(int ActorID); // Snapshot checks with matrix rebuild + void SampleControlDevices(int ActorID); + void DoControlActions(int ActorID); + void Sample_DoControlActions(int ActorID); // Sample and Do + void Check_Fault_Status(int ActorID); + int SolveAD(int ActorID, bool Initialize); // solve one of the A-Diakoptics stages locally + void SetGeneratorDispRef(int ActorID); + void SetVoltageBases(int ActorID); + void SaveVoltages(); + void UpdateVBus(int ActorID); // updates voltages for each bus from NodeV + void RestoreNodeVfromVbus(); // opposite of updatebus + complex VDiff(int i, int j, int ActorID); // Difference between two node voltages + /*by Dahei*/ + void Get_Yiibus(); // updates voltages for each bus from NodeV + complex Get_Yij(int node_ref_i, int node_ref_j); // get Gij + j Bij + /**/ + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(TTextRec& F, bool Complete); + void WriteConvergenceReport(const String Fname); + void Update_dblHour(); + void Increment_time(); + void UpdateLoopTime(); + double get_FFrequency(); + int get_Fyear(); + + double get_Solve_Time_Elapsed(); + double get_Total_Solve_Time_Elapsed(); + double get_Step_Time_Elapsed(); + double get_Total_Time_Elapsed(); + + // Procedures that use to be private before 01-20-2016 + void AddInAuxCurrents(int SolveType, int ActorID); + int SolveSystem(pNodeVarray V, int ActorID); + void GetPCInjCurr(int ActorID, bool GFMOnly = false); + void GetSourceInjCurrents(int ActorID); + void ZeroInjCurr(int ActorID); + void Upload2IncMatrix(); + void Calc_Inc_Matrix(int ActorID); // Calculates the incidence matrix for the Circuit + void Calc_Inc_Matrix_Org(int ActorID); // Calculates the incidence matrix hierarchically organized for the Circuit + int get_IncMatrix_Row(int Col); // Gets the index of the Row connected to the specified Column + int get_IncMatrix_Col(int Row); // Gets the index of the Column connected to the specified Row + int CheckLocationIdx(int Idx); // Evaluates the area covered by the tearing point to see if there is a better one + int get_PDE_Bus1_Location(String myPDE); // Gets the index of myPDE -> bus1 within the Inc matrix + void AddLines2IncMatrix(int ActorID); // Adds the Lines to the Incidence matrix arrays + void AddXfmr2IncMatrix(int ActorID); // Adds the Xfmrs to the Incidence matrix arrays + void AddSeriesCap2IncMatrix(int ActorID); // Adds capacitors in series to the Incidence matrix arrays + void AddSeriesReac2IncMatrix(int ActorID); // Adds Reactors in series to the Incidence matrix arrays + void SendCmd2Actors(int Msg); // Sends a message to other actors different than 1 + void UploadV2Master(int ActorID); // Uploads the local solution into the master's (actor 1) voltage array + void UpdateISrc(int ActorID); // Updates the local ISources using the dat available at Ic for actor 1 + complex VoltInActor1(int NodeIdx); // returns the voltage indicated in NodeIdx in the context of the actor 1 + }; + /*==========================================================================*/ + + + extern TSolutionObj* ActiveSolutionObj; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Solution; +#endif + +#endif // SolutionH + + + + + + + diff --git a/OpenDSSC/Common/SolutionAlgs.cpp b/OpenDSSC/Common/SolutionAlgs.cpp new file mode 100644 index 0000000..5e1f99b --- /dev/null +++ b/OpenDSSC/Common/SolutionAlgs.cpp @@ -0,0 +1,1724 @@ + +#pragma hdrstop + +#include "SolutionAlgs.h" + + + +#include "Arraydef.h" +#include "DSSGlobals.h" +#include "CmdForms.h" +#include "Utilities.h" +#include "Sysutils.h" +#include "System.h" +#include "mathutil.h" +#include +#include "Fault.h" +#include "Ucomplex.h" +#include "YMatrix.h" +#include "PCElement.h" +#include "Spectrum.h" +#include "VSource.h" +#include "Isource.h" +#include "klusolve.h" + + + +namespace SolutionAlgs +{ + + int ProgressCount = 0; + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void FinishTimeStep( int ActorID ) + /* + Cample Cleanup and increment time + + For custom solutions. + + */ + { + MonitorClass[ActorID]->SampleAll( ActorID ); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if ( with0->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Save Demand interval Files + EndOfTimeStepCleanup( ActorID ); + with0->Increment_time(); + } + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void EndOfTimeStepCleanup( int ActorID ) + /* + Put stuff in this procedure that needs to happen at the end of the time step + in main solution loops (see below) + */ + { + StorageClass[ActorID]->UpdateAll( ActorID ); + // Storage2Class[ActorID]->UpdateAll(ActorID); + InvControlClass[ActorID]->UpdateAll( ActorID ); + // InvControl2Class[ActorID]->UpdateAll(ActorID); + ExpControlClass[ActorID]->UpdateAll( ActorID ); + + // End of Time Step Timer + ActiveCircuit[ActorID]->Solution->UpdateLoopTime(); + MonitorClass[ActorID]->SampleAllMode5( ActorID ); // sample all mode 5 monitors to get timings + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void Show10PctProgress( int i, int n, int ActorID ) + { + if ( NoFormsAllowed ) + return; + if ( ( ( i * 10 ) / n ) > ProgressCount ) + { + ProgressCount++; + // ShowPctProgress( ProgressCount * 10, ActorID); + } + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveYearly( int ActorID ) + { + int result = 0; + int n = 0, Twopct = 0, i = 0; + result = 0; + + /* ProgressCaption( 'Solving Year '+ IntToStr(ActiveCircuit[ActorID].Solution.Year) + ' Actor: ' + IntToStr(ActorID) + ' CPU: ' + IntToStr(ActorCPU[ActorID]),ActorID); + ActorProgressCount[ActorID] := 0; + ShowPctProgress(ActorProgressCount[ActorID],ActorID); + */ + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + with1->IntervalHrs = double(with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage elements + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired Creates DI_Totals + Twopct = max(with1->NumberOfTimes / 50, 1 ); + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + + if ( ADiakoptics && ( ActorID == 1 ) ) + for ( int stop = NumOfActors, i = 2; i <= stop; i++) + ActiveCircuit[i]->Solution->Increment_time(); + with0->DefaultHourMult = with0->DefaultYearlyShapeObj->GetMult( with2.dblHour ); + if ( with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->GetPrice( with2.dblHour ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all Energy Meters take a sample + EndOfTimeStepCleanup( ActorID ); + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + // If (N mod Twopct)=0 Then ShowPctProgress((N*100) div NumberofTimes,ActorID); + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + // EnergyMeterClass[ActorID]->CloseAllDIFiles(ActorID); // Save Demand interval Files See DIFilesAreOpen Logic + } + catch (...) + { + // To match delphi + } + } + } + return result; + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveDaily( int ActorID ) + + /* + Solves following the daily load curve. + Stepsize defaults to 1 hr and number of times = 24. + Load is modified by yearly growth, time of day, and global load multiplier. + */ + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + // t:=0.0; + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + try + { + with1->IntervalHrs = double( with1->DynaVars.h ) / 3600.0; // needed for energy meters + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Append Demand Interval Files, if desired + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + if ( with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->GetPrice( with2.dblHour ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all Energy Meters take a sample + EndOfTimeStepCleanup( ActorID ); + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + } /*Try*/ + catch (...) + { + //matching with delphi + } + } + } /*WITH*/ + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveEMPDaily(int ActorID) + + /* + This is an identical routine to the the SolveDaily routine with a few differences. + The main difference is that the initial power output for all generating units is carried over from + the dynamic simulation perfromed in the EMP mode. + + All other functionality, such as loadshape and generation shapes should work the same way. + + Solves following the daily load curve. + Stepsize defaults to 1 hr and number of times = 24. + Load is modified by yearly grBowth, time of day, and global load multiplier. + */ + { + int result = 0; + int n = 0; + result = 0; + + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + with1->IntervalHrs = double(with1->DynaVars.h) / 3600.0; // needed for energy meters + if (!DIFilesAreOpen[ActorID]) + EnergyMeterClass[ActorID]->OpenAllDIFiles(ActorID); // Append Demand Interval Files, if desired + for (int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if (!SolutionAbort) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult(with2.dblHour); + if (with0->PriceCurveObj != NULL) + with0->PriceSignal = with0->PriceCurveObj->GetPrice(with2.dblHour); + + with1->SolveSnap(ActorID); + + MonitorClass[ActorID]->SampleAll(ActorID); // Make all monitors take a sample + if (with1->SampleTheMeters) + EnergyMeterClass[ActorID]->SampleAll(ActorID); // Make all Energy Meters take a sample + EndOfTimeStepCleanup(ActorID); + ActorPctProgress[ActorID] = (n * 100) / with1->NumberOfTimes; + } + MonitorClass[ActorID]->SaveAll(ActorID); + if (with1->SampleTheMeters) + EnergyMeterClass[ActorID]->CloseAllDIFiles(ActorID); // Save Demand interval Files + } /*Try*/ + catch (...) + { + //matching with delphi + } + } + return result; + } + + //= = = = + + + int SolvePeakDay( int ActorID ) + + /* + Solves peak day + + Takes the given load kW and assumes it represents the peak value. + Load is modified by daily load curve and growth factor for the year. + 'h' defaults to 3600 (1 hr) but can be reset to anything. + Differs from Daily mode in that the global load multiplier is ignored. + */ + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + with1->DynaVars.T = 0.0; + + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + try + { + with1->DynaVars.intHour = 0; + with1->DynaVars.dblHour = 0.0; + with1->IntervalHrs = double( with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + if ( with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->GetPrice( with2.dblHour ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all Energy Meters take a sample + EndOfTimeStepCleanup( ActorID ); + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + } + catch (...) + { + // to match with the try requirements on C + } + } + } /*WITH*/ + return result; + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveDuty( int ActorID ) + { + int result = 0; + int n = 0, Twopct = 0, Temp0 = 0; + bool Temp1 = false; + result = 0; + + /* ProgressCaption( 'Duty Cycle Solution', ActorID); + ProgressCount := 0; + ShowPctProgress(0, ActorID); */ + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + // t:=0.0; + // MonitorClass.ResetAll; + Twopct = max( 1, with1->NumberOfTimes / 50 ); + try + { + with1->IntervalHrs = double( with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + // Assume pricesignal stays constant for dutycycle calcs + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all Energy Meters take a sample + EndOfTimeStepCleanup( ActorID ); + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + if ( with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + // If (N mod Twopct)=0 Then ShowPctProgress((N*100) div NumberofTimes, ActorID); + } +// } +// __finally + // { + MonitorClass[ActorID]->SaveAll( ActorID ); + // ProgressHide(ActorID); + } + catch (...) + { + //to match delphi + } + } + } + return result; + } + + int SolveGeneralTime( int ActorID ) + + /* + For Rolling your own solution modes + */ + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + with1->IntervalHrs = double( with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + /*Compute basic multiplier from Default loadshape to use in generator dispatch, if any*/ + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + with1->SolveSnap( ActorID ); + FinishTimeStep( ActorID ); + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + } + } + } + return result; + } + + + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void IntegratePCStates( int ActorID ) + /*Integrate states in all PC Elements. At present, only PC Elements + can have dynamic states*/ + { + TPCElement* PCelem; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + PCelem = (TPCElement*) with0->PCElements.Get_First(); + while ( PCelem != NULL ) + { + PCelem->IntegrateStates( ActorID ); + PCelem = (TPCElement*) with0->PCElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + void InitializePCStates(int ActorID) + /* + This functino will initialize all states associated with dynamic models in each PC Element. + At present, only PC Elements can have dynamic states + */ + { + TPCElement* PCelem; + { + auto with0 = ActiveCircuit[ActorID]; // Get active circuit + { + PCelem = (TPCElement*)with0->PCElements.Get_First(); // Get first PC element + while (PCelem != NULL) + { + PCelem->InitializeStates(ActorID); // Call PC element InitializeState function + PCelem = (TPCElement*)with0->PCElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + void CalculateStateDerivatives(int ActorID) + /* + This functino will calculate all state derivatives associated with dynamic models in each PC Element. + At present, only PC Elements can have dynamic states + */ + { + TPCElement* PCelem; + { + auto with0 = ActiveCircuit[ActorID]; // Get active circuit + { + PCelem = (TPCElement*)with0->PCElements.Get_First(); // Get first PC element + while (PCelem != NULL) + { + PCelem->CalculateRate(ActorID); // Call PC element InitializeState function + PCelem = (TPCElement*)with0->PCElements.Get_Next(); + } + } + } + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + void StateIntegration(int ActorID) + /*Integrate states in all PC Elements. At present, only PC Elements + can have dynamic states*/ + { + TPCElement* PCelem; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + PCelem = (TPCElement*)with0->PCElements.Get_First(); + while (PCelem != NULL) + { + PCelem->StateIntegration(ActorID); + PCelem = (TPCElement*)with0->PCElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + void StateIntegration_correction(int ActorID) + /*Integrate states in all PC Elements. At present, only PC Elements + can have dynamic states*/ + { + TPCElement* PCelem; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + PCelem = (TPCElement*)with0->PCElements.Get_First(); + while (PCelem != NULL) + { + PCelem->StateIntegration_correction(ActorID); + PCelem = (TPCElement*)with0->PCElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + int SolveDynamic( int ActorID ) + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = with0->Solution; + { + try + { + with1->SolutionInitialized = true; // If we're in dynamics mode, no need to re-initialize. + with1->IntervalHrs = double(with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + // Assume price signal stays constant for dynamic calcs + /*Predictor*/ + with2.IterationFlag = 0; + IntegratePCStates( ActorID ); + with1->SolveSnap( ActorID ); + /*Corrector*/ + with2.IterationFlag = 1; + IntegratePCStates( ActorID ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + FMonitorClass[ActorID]->update_sys_ld_info( ActorID );//get current value in INFO Broker -> UCF + + // attack and defense -> UCF + FMonitorClass[ActorID]->update_atks( ActorID ); + FMonitorClass[ActorID]->update_defense_layer( ActorID ); + //------------------------------- + EndOfTimeStepCleanup( ActorID ); + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + } + catch (...) + { + // + } + } + } + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + // SOLVE EMP MODE + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + int SolveEMP(int ActorID) + { + + int n = 0; + int nfinal; + bool ret; + int errcode; + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = with0->Solution; + + { + try + { + try { + // Check if all generators have a dynamic model associated with them, if not, the throw exception + ret = GeneratorsHaveDynamicModel(ActorID); + if (!ret) { + errcode = 911; + throw errcode; + } + } + catch(...){ + DoErrorMsg( "SolveEMP", + "Simulation engine cannot find dynamic models for all generators in the case", + "User must provide dynamic models for ALL generators in the case", errcode); + throw errcode; + return -1; + } + // This will initialize all state variables of all PCElements + if (!with1->DynamicsInitialized) { + InitializePCStates(ActorID); + with1->DynamicsInitialized = true; // If we're in dynamics mode, no need to re-initialize. + } + with1->IntervalHrs = double(with1->DynaVars.h) / 3600.0; // needed for energy meters and storage devices + for (int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if (!SolutionAbort) + { + // This will calculate all state derivatives + CalculateStateDerivatives(ActorID); + auto& with2 = with1->DynaVars; + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult(with2.dblHour); + with2.IterationFlag = 0; + + // This will integrate states on all models - ab2 is the standard method + StateIntegration(ActorID); + // This will solve the network with the updated current injections from all models + + // Add E1 + E3 impacts + + // Add Harmonics impacts + + // Add other weapons effects + //// This will solve the network with the updated current injections from all models + with1->SolveSnap(ActorID); + + /* + * + * This code can be enabled if we want to implement Heun's method (explicit trapezoidal) + * To do so, we need to change the integraiton method used by StateIntegratino to Euler + * since default is AB2 + * + * + // This will calculate all state derivatives + CalculateStateDerivatives(ActorID); + //// This will integrate states on all models*/ + //StateIntegration_correction(ActorID); + + //// This will solve the network with the updated current injections from all models + //with1->SolveSnap(ActorID); + + // Output variables from models + MonitorClass[ActorID]->SampleAll(ActorID); // Make all monitors take a sample + FMonitorClass[ActorID]->update_sys_ld_info(ActorID);//get current value in INFO Broker -> UCF + + // attack and defense -> UCF + FMonitorClass[ActorID]->update_atks(ActorID); + FMonitorClass[ActorID]->update_defense_layer(ActorID); + //------------------------------- + EndOfTimeStepCleanup(ActorID); + nfinal = n; + } + // } + // __finally + // { + MonitorClass[ActorID]->SaveAll(ActorID); + } + catch (...) + { + // + } + } + } + return 0; + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + int SolveMonte1( int ActorID ) + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + with0->Set_LoadMultiplier(1.0); // Always set with prop in case matrix must be rebuilt + with1->IntervalHrs = 1.0; // needed for energy meters and storage devices + with1->DynaVars.intHour = 0; + with1->DynaVars.dblHour = 0.0;// Use hour to denote Case number + with1->DynaVars.T = 0.0; + + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + + /* ProgressCaption( 'Monte Carlo Mode 1, ' + IntToStr(NumberofTimes) + ' Random Loads.', ActorID); + ProgressCount := 0; */ + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + { + with1->DynaVars.intHour++; + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all meters take a sample + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + // Show10PctProgress(N, NumberOfTimes, ActorID); + } + else + { + ErrorNumber = SOLUTION_ABORT; + CmdResult = ErrorNumber; + GlobalResult = "Solution Aborted"; + break; + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); + // ProgressHide(ActorID); + } + catch (...) + { + // + } + } + } + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveMonte2( int ActorID ) + + // Do a daily load solution for several Random days + + { + int result = 0; + int i = 0, n = 0, Ndaily = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + with1->DynaVars.T = 0.0; + with1->DynaVars.intHour = 0; + with1->DynaVars.dblHour = 0.0; + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + with1->IntervalHrs = double(with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + Ndaily = Round( 24.0 / with1->IntervalHrs ); + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired + + /* ProgressCaption('Monte Carlo Mode 2, ' + IntToStr(NumberofTimes) + ' Days.', ActorID); + ProgressCount := 0; */ + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + { // Number of Days + + // Always set LoadMultiplier WITH prop in case matrix must be rebuilt + switch (with1->RandomType ) + { + case UNIFORM: + with0->Set_LoadMultiplier(Random()); + break; // number between 0 and 1 + + case GAUSSIAN: + with0->Set_LoadMultiplier(Gauss(with0->DefaultDailyShapeObj->Get_Mean(), with0->DefaultDailyShapeObj->Get_StdDev() )); + break; + } + /*# with DynaVars do */ + auto& with2 = with1->DynaVars; + for ( int stop = Ndaily, i = 1; i <= stop; i++) + { + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all meters take a sample + EndOfTimeStepCleanup( ActorID ); + } + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + // Show10PctProgress(N, NumberOfTimes, ActorID); + } + else + { + ErrorNumber = SOLUTION_ABORT; + CmdResult = ErrorNumber; + GlobalResult = "Solution Aborted."; + break; + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + // ProgressHide(ActorID); + } + catch (...) + { + // + } + } + } + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveMonte3( int ActorID ) + + // Hold time fixed and just vary the global load multiplier + + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + // Time must be set beFore entering this routine + try + { + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + with1->IntervalHrs = 1.0; // just get per unit energy and multiply result as necessary + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired + + /* ProgressCaption( 'Monte Carlo Mode 3, ' + IntToStr(NumberofTimes) + ' Different Load Levels.', ActorID); + ProgressCount := 0; */ + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult(with1->DynaVars.dblHour ); + if (with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->GetPrice(with1->DynaVars.dblHour ); + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + { + + // Always set LoadMultiplier WITH prop in case matrix must be rebuilt + switch (with1->RandomType ) + { + case UNIFORM: + with0->Set_LoadMultiplier(Random()); + break; // number between 0 and 1 + + case GAUSSIAN: + with0->Set_LoadMultiplier(Gauss(with0->DefaultDailyShapeObj->Get_Mean(), with0->DefaultDailyShapeObj->Get_StdDev() )); + break; + case LOGNORMAL: + with0->Set_LoadMultiplier(QuasiLogNormal(with0->DefaultDailyShapeObj->Get_Mean() )); + break; + } + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all meters take a sample + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + // Show10PctProgress(N, NumberOfTimes, ActorID); + } + else + { + CmdResult = SOLUTION_ABORT; + ErrorNumber = CmdResult; + GlobalResult = "Solution Aborted"; + break; + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + // ProgressHide(ActorID); + } + catch (...) + { + // + } + } + } /*WITH*/ + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveLD1( int ActorID ) + + // Do a Daily Simulation based on a load duration curve + + { + int result = 0; + int n = 0, Ndaily = 0, i = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + if ( with0->LoadDurCurveObj == NULL ) + { + DoSimpleMsg( "Load Duration Curve Not Defined (Set LDCurve=... command). Cannot perForm solution.", 470 ); + return result; + } + + // Time must be set beFore entering this routine + + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + Ndaily = Round( 24.0 / with1->DynaVars.h * 3600.0 ); + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired + + // ProgressCaption( 'Load-Duration Mode 1 Solution. ', ActorID); + + // (set in Solve method) DefaultGrowthFactor := IntPower(DefaultGrowthRate, (Year-1)); + with1->DynaVars.intHour = 0; + /*# with DynaVars do */ + for ( int stop = Ndaily, i = 1; i <= stop; i++) + { + auto& with2 = with1->DynaVars; + // Set the time + with1->Increment_time(); + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with2.dblHour ); + if ( ! SolutionAbort ) + { + for ( int stop = with0->LoadDurCurveObj->get_FNumPoints(), n = 1; n <= stop; n++) + { + with0->Set_LoadMultiplier(with0->LoadDurCurveObj->Mult( n )); // Always set LoadMultiplier with prop in case matrix must be rebuilt + // Adjust meter interval to interval on value of present Load-Duration Curve + with1->IntervalHrs = with0->LoadDurCurveObj->Get_Interval(); + + // Price curve must correspond to load-duration curve + if (with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->Price( n ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all meters take a sample + EndOfTimeStepCleanup( ActorID ); + } + ActorPctProgress[ActorID] = ( i * 100 ) / Ndaily; + // ShowPctProgress((i * 100) div NDaily, ActorID); + } + else + { + CmdResult = SOLUTION_ABORT; + ErrorNumber = CmdResult; + GlobalResult = "Solution Aborted"; + break; + } + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + // ProgressHide(ActorID); + } + catch (...) + { + // + } + } + } /*WITH ActiveCircuit[ActiveActor]*/ + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveLD2( int ActorID ) + + // Hold time fixed and just vary the global load multiplier according to the global + // Load-Duration Curve + + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + if ( with0->LoadDurCurveObj == NULL ) + { + DoSimpleMsg( "Load Duration Curve Not Defined (Set LDCurve=... command). Cannot perForm solution.", 471 ); + return result; + } + + // Time must be set beFore entering this routine + + + // MonitorClass.ResetAll; + // EnergyMeterClass.ResetAll; + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with1->DynaVars.dblHour ); + if ( ! DIFilesAreOpen[ActorID] ) + EnergyMeterClass[ActorID]->OpenAllDIFiles( ActorID ); // Open Demand Interval Files, if desired + + // (set in Solve Method) DefaultGrowthFactor := IntPower(DefaultGrowthRate, (Year-1)); + try + { + if ( SolutionAbort ) + { + CmdResult = SOLUTION_ABORT; + ErrorNumber = CmdResult; + GlobalResult = "Solution Aborted."; + return result; + } + for ( int stop = with0->LoadDurCurveObj->get_FNumPoints(), n = 1; n <= stop; n++) + { + + // Adjust meter interval to interval on value of present Load-Duration Curve + with0->Set_LoadMultiplier(with0->LoadDurCurveObj->Mult( n )); // Always set LoadMultiplier WITH prop in case matrix must be rebuilt + with1->IntervalHrs = with0->LoadDurCurveObj->Get_Interval(); + + // Price curve must correspond to load-duration curve + if (with0->PriceCurveObj != NULL ) + with0->PriceSignal = with0->PriceCurveObj->Price( n ); + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->SampleAll( ActorID ); // Make all meters take a sample + EndOfTimeStepCleanup( ActorID ); + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + if (with1->SampleTheMeters ) + EnergyMeterClass[ActorID]->CloseAllDIFiles( ActorID ); // Save Demand interval Files + } + catch (...) + { + // + } + } + } /*WITH ActiveCircuit[ActiveActor]*/ + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void PickAFault( int ActorID ) + // Enable one of the faults in the circuit. Disable the rest + + { + int NumFaults = 0, i = 0, Whichone = 0; + TFaultObj* FaultObj; + NumFaults = ActiveCircuit[ActorID]->Faults.get_myNumList(); + Whichone = trunc( Random() * NumFaults ) + 1; + if ( Whichone > NumFaults ) + Whichone = NumFaults; + for ( int stop = NumFaults, i = 1; i <= stop; i++) + { + FaultObj = (TFaultObj*) ActiveCircuit[ActorID]->Faults.Get( i ); + if ( i == Whichone ) + { + ActiveFaultObj = FaultObj; // in Fault Unit + FaultObj->Set_Enabled(true); + } + else + FaultObj->Set_Enabled(false); + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveMonteFault( int ActorID ) + { + int result = 0; + int n = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + with1->LoadModel = ADMITTANCE; // All Direct solution + with0->Set_LoadMultiplier(1.0); // Always set LoadMultiplier WITH prop in case matrix must be rebuilt + with1->DynaVars.intHour = 0; + with1->DynaVars.dblHour = 0.0; // Use hour to denote Case number + with1->DynaVars.T = 0.0; + + + // MonitorClass.ResetAll; + + /* ProgressCaption( 'Monte Carlo Fault Study: ' + IntToStr(NumberofTimes) + ' Different Faults.', ActorID); + ProgressCount := 0; */ + with1->SetGeneratorDispRef( ActorID ); + for ( int stop = with1->NumberOfTimes, n = 1; n <= stop; n++) + if ( ! SolutionAbort ) + { + with1->DynaVars.intHour++; + PickAFault( ActorID ); // Randomly enable one of the faults + ActiveFaultObj->Randomize( ActorID ); // Randomize the fault resistance + with1->SolveDirect( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Make all monitors take a sample + ActorPctProgress[ActorID] = ( n * 100 ) / with1->NumberOfTimes; + // Show10PctProgress(N, NumberOfTimes, ActorID); + } +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + // ProgressHide(ActorID); + } + catch (...) + { + // + } + } + } + return result; + } + + /*--------------------------------------------------------------------------*/ + + + void AllocateAllSCParms( int ActorID ) + { + int i = 0; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + with0->Buses[i - 1]->AllocateBusQuantities(); + } + } + } + + + /*--------------------------------------------------------------------------*/ + + + void ComputeIsc( int ActorID ) + /* Compute Isc at all buses for current values of Voc and Ysc */ + { + int i = 0; + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto& with1 = with0->Buses[i - 1]; + { + with1->Ysc.MVmult( &(with1->BusCurrent[0]), &(with1->VBus[0])); + } + } + } + } + } + + + /*--------------------------------------------------------------------------*/ + + + void ComputeYsc( int iB, int ActorID ) + + /*Compute YSC for I-th bus*/ + /*Assume InjCurr is zeroed*/ + { + int i = 0, j = 0, ref1 = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + /*# with Buses^[iB] do */ + { + auto& with2 = with0->Buses[iB]; + { + with2->Zsc.Clear(); + for ( int stop = with2->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + ref1 = with2->GetRef( i ); + if ( ref1 > 0 ) + { + with1->Currents[ref1] = cONE; + /*SparseSet expects 1st element of voltage array, not 0-th element*/ + if (SolveSparseSet(with1->hYsystem, &(with1->NodeV[1]), &(with1->Currents[1])) < 1) + { + // throw EEsolv32Problem.Create( "Error Solving System Y Matrix in ComputeYsc. Problem with Sparse matrix solver." ); + } + /*Extract Voltage Vector = column of Zsc*/ + for ( int stop = with2->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + with2->Zsc.SetElement( j, i, with1->NodeV[with2->GetRef( j )] ); + } + with1->Currents[ref1] = CZero; + } /*IF ref...*/ + } + with2->Ysc.CopyFrom( &( with2->Zsc ) ); + with2->Ysc.Invert(); /*Save as admittance*/ + } + } + } + } + } + + + /*--------------------------------------------------------------------------*/ + + + void ComputeAllYsc( int ActorID ) + { + int iB = 0, j = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + for ( int stop = with0->NumNodes, j = 1; j <= stop; j++) + with1->Currents[j] = CZero; + ActorProgressCount[ActorID] = 0; + for ( int stop = with0->NumBuses, iB = 1; iB <= stop; iB++) + { + ComputeYsc( iB - 1, ActorID ); // Compute YSC for iB-th Bus + if ( ( ( iB * 10 ) / with0->NumBuses ) > ProgressCount ) + { + ActorProgressCount[ActorID]++; + // ShowPctProgress(30 + ActorProgressCount[ActorID] * 5, ActorID); + } + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void DisableAllFaults( int ActorID ) + { + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + ActiveFaultObj = (TFaultObj*) with0->Faults.Get_First(); + while ( ActiveFaultObj != NULL ) + { + ActiveFaultObj->Set_Enabled(false); + ActiveFaultObj = (TFaultObj*) with0->Faults.Get_Next(); + } + } + } + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveFaultStudy( int ActorID ) + { + int result = 0; + result = 0; + ActorPctProgress[ActorID] = 0; + // ShowPctProgress( 0, ActorID); + // ProgressCaption( 'Computing Open-Circuit Voltages', ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + with1->LoadModel = ADMITTANCE; + DisableAllFaults( ActorID ); + with1->SolveDirect( ActorID ); // This gets the open circuit voltages and bus lists corrected + AllocateAllSCParms( ActorID ); // Reallocate bus quantities + with1->UpdateVBus( ActorID ); // Put present solution Voc's in bus quantities + } + ActorPctProgress[ActorID] = 30; + /* ProgressCaption ('Computing Ysc Matrices for Each Bus', ActorID); + ShowPctProgress (30, ActorID);*/ + ComputeAllYsc( ActorID ); + ActorPctProgress[ActorID] = 80; + /* ProgressCaption( 'Computing Short-circuit currents.', ActorID); + ShowPctProgress (80, ActorID);*/ + ComputeIsc( ActorID ); + ActorPctProgress[ActorID] = 100; + /* ShowPctProgress ( 100, ActorID); + ProgressCaption ('Done.', ActorID);*/ + // ProgressHide(ActorID); + // Now should have all we need to make a short circuit report + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void AddFrequency( pDoubleArray& FreqList, int& NumFreq, int& MaxFreq, double F ) + + /*Add unique Frequency, F to list in ascending order, reallocating if necessary*/ + { + int i = 0, j = 0; + + /*See if F is in List*/ + for ( int stop = NumFreq, i = 1; i <= stop; i++) + { + /*Allow a little tolerance (0.1 hz) for the Frequency for round off error*/ + if ( Abs( F - FreqList[i] ) < 0.1 ) + return; // Already in List, nothing to do + } + + /*OK, it's not in list, so let's Add it*/ + NumFreq++; + if ( NumFreq > MaxFreq ) + { // Let's make a little more room + std::vector myTmp; + int oldSize = MaxFreq; + for (i = 0; i <= MaxFreq; i++) + myTmp.push_back(FreqList[i]); + MaxFreq += 20; + FreqList = (pDoubleArray) realloc(FreqList, ( sizeof(double) * MaxFreq ) + 2); + for (i = 0; i <= oldSize; i++) + FreqList[i] = myTmp[i]; + } + + /*Let's add it in ascending order*/ + for ( int stop = NumFreq - 1, i = 1; i <= stop; i++) + { + if ( F < (FreqList)[i] ) + { + /*Push down array and insert it*/ + for ( int stop = i, j = NumFreq - 1; j >= stop; j--) + FreqList[j + 1] = FreqList[j]; + (FreqList)[i] = F; + return; // We're done! + } + } + + /*If we fall through, tack it on to the end*/ + (FreqList)[NumFreq] = F; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + double GetSourceFrequency( TPCElement* pc ) // TODO - applicable to VCCS? + + { + double result = 0.0; + TVsourceObj* pVsrc; + TIsourceObj* pIsrc; + if ( CompareText( pc->Get_myPName(), "vsource" ) == 0 ) + { + pVsrc = ( TVsourceObj* ) pc; + result = pVsrc->SrcFrequency; + } + else + { + pIsrc = ( TIsourceObj* ) pc; + result = pIsrc->SrcFrequency; + } + return result; + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void CollectAllFrequencies( pDoubleArray& FreqList, int& NumFreq, int ActorID ) + { + std::vector SpectrumInUse; + TPCElement* p; + int MaxFreq = 0, i = 0, j = 0; + TSpectrumObj* pSpectrum; + double F = 0.0; + /*Make a List of all frequencies in Use*/ + + /*accumulate all unique Frequencies*/ + MaxFreq = 20; // Initial List size + NumFreq = 0; + FreqList = (pDoubleArray) realloc(FreqList, ( sizeof(double) * MaxFreq ) + 2); + /*# with ActiveCircuit[ActorID] do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + /*Check Sources -- each could have a different base frequency*/ + p = (TPCElement*) with0->Sources.Get_First(); + while ( p != NULL ) + { + if ( p->Get_Enabled() ) + if ( SpectrumClass[ActorID]->Find( p->Spectrum ) != NULL ) + { + pSpectrum = (TSpectrumObj*) SpectrumClass[ActorID]->GetActiveObj(); + F = GetSourceFrequency( p ); + for ( int stop = pSpectrum->NumHarm, j = 1; j <= stop; j++) + { + AddFrequency( FreqList, NumFreq, MaxFreq, (pSpectrum->HarmArray)[j - 1] * F ); + } + } + p = (TPCElement*) with0->Sources.Get_Next(); + } + } + } + + /*Mark Spectra being used*/ + /*Check loads and generators - these are assumed to be at fundamental frequency*/ + SpectrumInUse.resize( SpectrumClass[ActorID]->Get_ElementCount() + 1); //Allocate and zero + /*# with ActiveCircuit[ActorID] do */ + { + auto with1 = ActiveCircuit[ActorID]; + { + p = (TPCElement*) with1->PCElements.Get_First(); + while ( p != NULL ) + { + if ( p->Get_Enabled() ) + if ( SpectrumClass[ActorID]->Find( p->Spectrum ) != NULL ) + { + (SpectrumInUse)[SpectrumClass[ActorID]->get_ActiveElement()] = 1; + } + p = (TPCElement*) with1->PCElements.Get_Next(); + } + } + } /*With*/ + + /*Add marked Spectra to list*/ + for ( int stop = SpectrumClass[ActorID]->Get_ElementCount(), i = 1; i <= stop; i++) + { + if ( (SpectrumInUse)[i] == 1 ) + { + SpectrumClass[ActorID]->Set_Active(i); + pSpectrum = (TSpectrumObj*) SpectrumClass[ActorID]->GetActiveObj(); + for ( int stop = pSpectrum->NumHarm, j = 1; j <= stop; j++) + { + AddFrequency( FreqList, NumFreq, MaxFreq, (pSpectrum->HarmArray)[j - 1] * ActiveCircuit[ActorID]->Fundamental ); + } + } + } + SpectrumInUse.clear(); + } + + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + int SolveHarmonic( int ActorID ) + { + int result = 0; + pDoubleArray FrequencyList; + int i = 0, NFreq = 0; + result = 0; + FrequencyList = NULL; // Set up for Reallocmem + /* ShowPctProgress ( 0, ActorID); + ProgressCaption( 'Performing Harmonic Solution', ActorID); */ + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + try + { + if ( with1->get_FFrequency() != with0->Fundamental ) + { // Last solution was something other than fundamental + with1->Set_Frequency(with0->Fundamental); + if ( ! RetrieveSavedVoltages() ) + return result; /*Get Saved fundamental frequency solution*/ + } + MonitorClass[ActorID]->SampleAll( ActorID ); // Store the fundamental frequency in the monitors + + /* Get the list of Harmonic Frequencies to solve at*/ + if (with1->DoAllHarmonics ) + CollectAllFrequencies( FrequencyList, NFreq, ActorID ); // Allocates FrequencyList + else + { + FrequencyList = (pDoubleArray) realloc(FrequencyList, sizeof(double) * with1->HarmonicListSize + 1); + NFreq = with1->HarmonicListSize; + for ( int stop = NFreq, i = 1; i <= stop; i++) + (FrequencyList)[i] = with0->Fundamental * (with1->HarmonicList)[i]; + } + + for ( int stop = NFreq, i = 1; i <= stop; i++) + { + with1->Set_Frequency((FrequencyList)[i]); + if ( Abs( with1->Harmonic - 1.0 ) > EPSILON ) + { // Skip fundamental + /* ProgressCaption ( 'Solving at Frequency = ' + Format('%-g', [Frequency]), ActorID); + ShowPctProgress ( Round((100.0*i)/Nfreq), ActorID);*/ + ActorPctProgress[ActorID] = Round( ( 100.0 * i ) / NFreq ); + with1->SolveDirect( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); + // Storage devices are assumed to stay the same since there is no time variation in this mode + } + } /*FOR*/ + + /* ShowPctProgress ( 100, ActorID); + ProgressCaption ( 'Done.',ActorID); */ +// } +// __finally +// { + // ProgressHide(ActorID); + MonitorClass[ActorID]->SaveAll( ActorID ); + free(FrequencyList); + } + catch (...) + { + // + } + // Now should have all we need to make a short circuit report + } + } + return result; + } + + //======================================================================================== + + + + int SolveHarmTime( int ActorID ) // It is based in SolveGeneralTime routine + + { + int result = 0; + result = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + with1->IntervalHrs = double( with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + if ( ! SolutionAbort ) + /*# with DynaVars do */ + { + /*Compute basic multiplier from Default loadshape to use in generator dispatch, if any*/ + with0->DefaultHourMult = with0->DefaultDailyShapeObj->GetMult( with1->DynaVars.dblHour ); + with1->SolveSnap( ActorID ); + // Increment_time; // This function is handeled from SolveHarmonics (04-10-2013) + } + } + } + return result; + } + //============================================================================= + + + + int SolveHarmonicT( int ActorID ) + { + int result = 0; + pDoubleArray FrequencyList; + int i = 0, NFreq = 0; + result = 0; + FrequencyList = NULL; // Set up for Reallocmem + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + with1->IntervalHrs = double(with1->DynaVars.h ) / 3600.0; // needed for energy meters and storage devices + try + { + if (with1->get_FFrequency() != with0->Fundamental ) + { // Last solution was something other than fundamental + with1->Set_Frequency(with0->Fundamental); + if ( ! RetrieveSavedVoltages() ) + return result; /*Get Saved fundamental frequency solution*/ + } + // DefaultHourMult := DefaultDailyShapeObj->GetMult(DynaVars.dblHour); + // IF Load_Changed THEN Begin //Added to update the current sources of all frequencies any time + InitializeForHarmonics( ActorID ); //the value of a load changes in a proportional way + // Load_Changed:=FALSE; // Added 05 dec 2013 - D. Montenegro + // End; + with1->SolveSnap( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); // Store the fundamental frequency in the monitors + /* Get the list of Harmonic Frequencies to solve at*/ + if (with1->DoAllHarmonics ) + CollectAllFrequencies( FrequencyList, NFreq, ActorID ); // Allocates FrequencyList + else + { + FrequencyList = (pDoubleArray) realloc(FrequencyList, ( sizeof(double) * with1->HarmonicListSize ) + 2); + NFreq = with1->HarmonicListSize; + for ( int stop = NFreq, i = 1; i <= stop; i++) + (FrequencyList)[i] = with0->Fundamental * (with1->HarmonicList)[i]; + } + + std::vector myTmp; + for (i = 0; i <= NFreq; i++) + myTmp.push_back(FrequencyList[i]); + + for ( int stop = NFreq, i = 1; i <= stop; i++) + { + with1->Set_Frequency((FrequencyList)[i]); + if ( Abs(with1->Harmonic - 1.0 ) > EPSILON ) + { // Skip fundamental + // DefaultHourMult := DefaultDailyShapeObj->GetMult(DynaVars.dblHour); + SolveHarmTime( ActorID ); + MonitorClass[ActorID]->SampleAll( ActorID ); + EndOfTimeStepCleanup( ActorID ); + // Storage devices are assumed to stay the same since there is no time variation in this mode (Not necessarelly now) + } + } /*FOR*/ + with1->Increment_time(); +// } +// __finally +// { + MonitorClass[ActorID]->SaveAll( ActorID ); + free(FrequencyList); + } + catch (...) + { + // + } + } + } + return result; + } + + //================================================================================================================ + bool GeneratorsHaveDynamicModel(int ActorID) + /* + This function will loop over all PCElements that are of generator type + and check if they have a dynamic model associated with them. If they do, it will allow + simulation initialization, if not, then an error will be thrown directing the + user to correct the issue. + */ + { + bool is_gen = false; + bool gen_exists = false; + + TPCElement* PCelem; + { + auto with0 = ActiveCircuit[ActorID]; // Get active circuit + { + PCelem = (TPCElement*)with0->PCElements.Get_First(); // Get first PC element + while (PCelem != NULL) + { + // First, check if the PC is a generator + is_gen = PCelem->IsGenerator(); + + // If it is, then check for a dynamic model + if (is_gen) + { + gen_exists = PCelem->CheckForGeneratorModel(); + // If generator model doesn't exist, then throw an error and break loop + if (!gen_exists) { + return false; + } + } + + // Go to next element if current element is not a generator + PCelem = (TPCElement*)with0->PCElements.Get_Next(); + } + } + } + return true; + } + + //================================================================================================================ + + void SolutionAlgs_initialization() + { + //IsMultiThread = true; + } + + class SolutionAlgs_unit + { + public: + SolutionAlgs_unit() + { + SolutionAlgs_initialization(); + } + }; + SolutionAlgs_unit _SolutionAlgs_unit; + +} + diff --git a/OpenDSSC/Common/SolutionAlgs.h b/OpenDSSC/Common/SolutionAlgs.h new file mode 100644 index 0000000..bfb2b26 --- /dev/null +++ b/OpenDSSC/Common/SolutionAlgs.h @@ -0,0 +1,81 @@ +#ifndef SolutionAlgsH +#define SolutionAlgsH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Solution Algorithms*/ + +/* + 9-20-00 Added SolveDynamic + + 1/22/01 Added SolutionAbort Check wherever solution in a potentially long loop + 4/2/04 Updated SolutionAbort to work through redirect files and long scripts +*/ + +namespace SolutionAlgs +{ + //#include + int SolveMonte1(int ActorID); // Solve Monte Carlo Solution + + int SolveMonte2(int ActorID); // Solve Monte Carlo Solution + + int SolveMonte3(int ActorID); // Solve Monte Carlo Solution + + int SolveMonteFault(int ActorID); // Solve Monte Carlo Fault Study + + int SolveFaultStudy(int ActorID); // Full Fault Study + + int SolveDaily(int ActorID); // Solve Following Daily Cycle + + int SolvePeakDay(int ActorID); // Solve Following Daily Cycle at peak load + + int SolveYearly(int ActorID); // Solve Following Yearly Cycle + + int SolveDuty(int ActorID); // Solve Following Duty Cycle + + int SolveDynamic(int ActorID); // Solve Dynamics + + int SolveEMP(int ActorID); // Solve EMP + + int SolveEMPDaily(int ActorID); // Solve EMP + + int SolveLD1(int ActorID); // solve Load-Duration Curve, 1 + + int SolveLD2(int ActorID); // solve Load-Duration Curve, 2 + + int SolveHarmonic(int ActorID); + int SolveHarmonicT(int ActorID); // Sequential-Time Harmonics, Added 07-06-2015 + + int SolveHarmTime(int ActorID); // solve harmonics vs time (like general time mode) created by Davis Montenegro 25/06/2014 + + int SolveGeneralTime(int ActorID); + void ComputeYsc(int iB, int ActorID); + void ComputeAllYsc(int ActorID); + void IntegratePCStates(int ActorID); + void EndOfTimeStepCleanup(int ActorID); + void FinishTimeStep(int ActorID); + + void InitializePCStates(int ActorID); + void CalculateStateDerivatives(int ActorID); + void StateIntegration(int ActorID); + void StateIntegration_correction(int ActorID); + bool GeneratorsHaveDynamicModel(int ActorID); +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace SolutionAlgs; +#endif + +#endif // SolutionAlgsH + + + + + + + + diff --git a/OpenDSSC/Common/Sparse_Math.cpp b/OpenDSSC/Common/Sparse_Math.cpp new file mode 100644 index 0000000..3d4d305 --- /dev/null +++ b/OpenDSSC/Common/Sparse_Math.cpp @@ -0,0 +1,981 @@ + +#pragma hdrstop + +#include "Sparse_Math.h" + + + +// Evaluates of both rows are equal + + +#include "System.h" + +namespace Sparse_Math +{ + + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } + + + + bool Tsparse_matrix::R_equal(PData acols, PData avals, PData bcols, PData bvals) + { + bool result = false; + int idx = 0, rlen = 0; + result = false; // In case they are not equal + if (acols->size() == bcols->size()) // If they have the same # of Cols + { + rlen = 0; // First, verify if the cols are the same + for (int stop = (acols->size() - 1), idx = 0; idx <= stop; idx++) + if (((*acols)[idx] - (*bcols)[idx] ) != 0) + rlen++; + if (rlen == 0) + result = true; + } + return result; + } + + // Gets the columns and values at each columns for the row specified + +/* + + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } + */ + + + void Tsparse_matrix::getrow(int Index, PData cols, PData vals) + { + TData rowcols, rowvals; + int j = 0; + rowcols.clear(); + rowvals.clear(); + for (int stop = (len - 1), j = 0; j <= stop; j++) + { + if (data[j][0] == Index) + { + rowcols.push_back(data[j][1]); + rowvals.push_back(data[j][2]); + } + } + *cols = rowcols; + *vals = rowvals; + } + + + int Tsparse_matrix::Rank() // Added 08/16/2018 by DM for calculating the + + { + int result = 0; + + // Rank of the sparse matrix + + int i = 0, j = 0; + bool Flag = false; // Row under evaluation + // Reference row + + TData acols, avals, bcols, bvals; + result = 0; + for (int stop = (Row - 1), i = 0; i <= stop; i++) + { + getrow(i, &acols, &avals); + if (i > 0) + { + j = i - 1; + Flag = true; + while (Flag && (j >= 0)) + { + getrow(j, &bcols, &bvals); // sweeps the matrix bottom up + Flag = !R_equal(&acols, &avals, &bcols, &bvals); + j--; + } + if (Flag) + result++; + } + else + result++; + } + return result; + } +/* + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } +*/ + + + + int Tsparse_matrix::NCols() + { + int result = 0; + result = col; + return result; + } + + + int Tsparse_matrix::NRows() + { + int result = 0; + result = Row; + return result; + } + + + int Tsparse_matrix::checkifexists(int r, int c) + { + int result = 0; + int i = 0; + result = -1; // Default in case the value doesn't exist + if (len > 0) + { + for (int stop = (len - 1), i = 0; i <= stop; i++) + { + if ((data[i][0] == r) && (data[i][1] == c)) + result = i; // If the value exists returns the index ( >=0 ) + } + } + return result; + } + + + void Tsparse_matrix::sparse_matrix(int r, int c) + { + Row = r; // Initialize row + col = c; // Initialize Col + len = 0; // Initialize length to 0 + data.clear(); + } + + //Inserts elements into the sparse matrix + + + + int Tsparse_matrix::Insert(int r, int c, int val) + { + int result = 0; + int lrow = 0 // To store the current lenght of the data matrix + , lcol = 0; + result = 1; + lrow = checkifexists(r, c); + if (lrow >= 0) + { + data[lrow][2] = val; // Assigns the new value to the existing cell + } + else + { + // Reshapes the memory space + lrow = data.size(); + data.resize( lrow + 1 ); + data[lrow].resize(3); + // Adds the data to the new memory space + data[data.size() - 1][0] = r; + data[data.size() - 1][1] = c; + data[data.size() - 1][2] = val; + len++; + if (col < c) + col = c; + if (Row < r) + Row = r; + } + return result; + } + /* + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } + */ + + Tsparse_matrix Tsparse_matrix::Add(Tsparse_matrix* b) + { + Tsparse_matrix result; // Creates a memory space to store the result + int addeval = 0, apos = 0, bpos = 0; + + // First checks if the matrices have the same dimensions + if ((Row != b->Row) || (col != b->col)) + { + result.sparse_matrix(1, 1); + result.Insert(0, 0, -1); + } + else + { + apos = 0; + bpos = 0; + result.sparse_matrix(Row, col); + while ((apos < len) && (bpos < b->len)) + { + if ((data[apos][0] > b->data[bpos][0]) || ((data[apos][0] == b->data[bpos][0]) && (data[apos][1] > b->data[bpos][1]))) + { + result.Insert(b->data[bpos][0], b->data[bpos][1], b->data[bpos][2]); + bpos++; + } + else + { + if ((data[apos][0] < b->data[bpos][0]) || ((data[apos][0] == b->data[bpos][0]) && (data[apos][1] < b->data[bpos][1]))) + { + result.Insert(data[apos][0], data[apos][1], data[apos][2]); + apos++; + } + else + { + addeval = data[apos][2] + b->data[bpos][2]; + if (addeval != 0) + result.Insert(data[apos][0], data[apos][1], addeval); + apos++; + bpos++; + } + } + } + // Inserts the remaining elements + while (apos < (len - 1)) + { + result.Insert(data[apos][0], data[apos][1], data[apos + 1][2]); + apos++; + } + while (bpos < (b->len - 1)) + { + result.Insert(b->data[bpos][0], b->data[bpos][1], b->data[bpos + 1][2]); + bpos++; + } + } + return result; + } + + // Transposes the sparse matrix + + + + Tsparse_matrix Tsparse_matrix::Transpose() + { + Tsparse_matrix result; // Creates a memory space to store the result + std::vector < int > count, Index; + int i = 0, rpos = 0; + // new matrix with inversed row X col + result.sparse_matrix(col, Row); + // same number of elements + for (int stop = len, i = 1; i <= stop; i++) + result.Insert(i, 0, 0); + count.resize(col + 1); + Index.resize(col + 1); + // Initialize all to 0 + for (int stop = col, i = 0; i <= stop; i++) + count[i] = 0; + for (int stop = (len - 1), i = 0; i <= stop; i++) + count[data[i][1]]++; + // to count number of elements having col smaller + // than particular i + // as there is no col with value < 1 + Index[0] = 0; + // initialize rest of the indices + for (int stop = col, i = 1; i <= stop; i++) + Index[i] = Index[i - 1] + count[i - 1]; + for (int stop = (len - 1), i = 0; i <= stop; i++) + { + // insert a data at rpos and increment its value + rpos = Index[data[i][1]]; + Index[data[i][1]]++; + // transpose row=col + result.data[rpos][0] = data[i][1]; + + // transpose col=row + result.data[rpos][1] = data[i][0]; + + // same value + result.data[rpos][2] = data[i][2]; + } + + // the above method ensures + // sorting of transpose matrix + // according to row-col value + return result; + } + + // Multiplies another sparse matrix by this matrix + + /* + + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } + */ + + + + Tsparse_matrix Tsparse_matrix::multiply(Tsparse_matrix* B) + { + Tsparse_matrix result; // Creates a memory space to store the result + int sum = 0, c = 0, tempa = 0, tempb = 0, r = 0, apos = 0, bpos = 0; + // First checks if the matrices have the right dimensions + if (col != B->Row) + { + result.sparse_matrix(1, 1); + result.Insert(0, 0, -1); //Invalid multiplication + } + else + { + // transpose b to compare row + // and col values and to add them at the end + Tsparse_matrix b_ = B->Transpose(); + Tsparse_matrix *b = &b_; // added to minimize changes to the code + // result matrix of dimension row X b.col + // however b has been transposed, hence row X b.row + result.sparse_matrix(Row, b->Row); + // iterate over all elements of A (this matrix) + apos = 0; + while (apos < len) + { + r = data[apos][0]; + // iterate over all elements of B + bpos = 0; + while (bpos < b->len) + { + // current column of result matrix + // data[][0] used as b is transposed + c = b->data[bpos][0]; + + // temporary pointers created to add all + // multiplied values to obtain current + // element of result matrix + tempa = apos; + tempb = bpos; + sum = 0; + + // iterate over all elements with + // same row and col value + // to calculate result[r] + while ((tempa < len) && (data[tempa][0] == r) && (tempb < b->len) && (b->data[tempb][0] == c)) + { + if (data[tempa][1] < b->data[tempb][1]) + tempa++; //skip a + else + { + if (data[tempa][1] > b->data[tempb][1]) + tempb++; //skip b + else + { + // same col, so multiply and increment + sum = sum + data[tempa][2] * b->data[tempb][2]; + tempa++; + tempb++; + } + } + } + // insert sum obtained in result[r] + // if its not equal to 0 + if (sum != 0) + result.Insert(r, c, sum); + while ((bpos < b->len) && (b->data[bpos][0] == c)) + bpos++; // Jump to next column + } + while ((apos < len) && (data[apos][0] == r)) + apos++; // Jump to next row + } + } + return result; + } + + // Sorts the content of the matrix by rows, important for multiplications + + void Tsparse_matrix::Sort() + { + Tsparse_matrix myTemp; + + myTemp.Reset(); + + for (int idx = 0; idx <= Row; idx++) + { + for (int i = 0; i < data.size(); i++) + { + if (data[i][0] == idx) + myTemp.Insert(data[i][0], data[i][1], data[i][2]); + } + } + // moves the new data into the local object + for (int i = 0; i < myTemp.data.size(); i++) + { + data[i][0] = myTemp.data[i][0]; + data[i][1] = myTemp.data[i][1]; + data[i][2] = myTemp.data[i][2]; + } + } + + + // Resets the sparse matrix (makes it empty) + + + + void Tsparse_matrix::Reset() + { + data.clear(); + len = 0; + } + // Returns the lenght of the sparse matrix (number of non-zero elements) + + + + int Tsparse_matrix::NZero() + { + int result = 0; + result = len; + return result; + } + + //****************************************************************************** + //* Complex sparse matrices + //****************************************************************************** + + // Evaluates of both rows are equal + + bool TSparse_Complex::R_equal(PData acols, PData bcols, PComplexArr avals, PComplexArr bvals) + { + bool result = false; + int idx = 0, rlen = 0; + result = false; // In case they are not equal + if (acols->size() == bcols->size()) // If they have the same # of Cols + { + rlen = 0; // First, verify if the cols are the same + for (int stop = (acols->size() - 1), idx = 0; idx <= stop; idx++) + if (((*acols)[idx] - (*bcols)[idx]) != 0) + rlen++; + if (rlen == 0) + result = true; + } + return result; + } + + // Returns the value contained at the specific position + + + + complex TSparse_Complex::getvalue(int Row, int col) + { + complex result; + bool Go_Flag = false; + int i = 0; + result = cmplx(0, 0); + Go_Flag = true; + i = 0; + while (Go_Flag) + { + if ((CData[i].Row == Row) && (CData[i].col == col)) + { + result = CData[i].Value; + Go_Flag = false; + } + else + { + i++; + if (i > ( CData.size() - 1 ) ) + Go_Flag = false; + } + } + return result; + } + + // Gets the columns and values at each columns for the row specified + + + + void TSparse_Complex::getrow(int Index, PData cols, PComplexArr vals) + { + TData rowcols; + TComplexArr rowvals; + int j = 0; + rowcols.clear(); + rowvals.clear(); + for (int stop = (len - 1), j = 0; j <= stop; j++) + { + if (CData[j].Row == Index) + { + rowcols.push_back( CData[j].col ); + rowvals.push_back( CData[j].Value ); + } + } + *cols = rowcols; + *vals = rowvals; + } + + int TSparse_Complex::Rank() // Added 08/16/2018 by DM for calculating the + + { + int result = 0; + + // Rank of the sparse matrix + + int i = 0, j = 0; + bool Flag = false; // Row under evaluation + + TData acols, bcols; // Reference row + + TComplexArr avals, bvals; + result = 0; + for (int stop = (Row - 1), i = 0; i <= stop; i++) + { + getrow(i, &acols, &avals); + if (i > 0) + { + j = i - 1; + Flag = true; + while (Flag && (j >= 0)) + { + getrow(j, &bcols, &bvals); // sweeps the matrix bottom up + Flag = !R_equal(&acols, &bcols, &avals, &bvals); + j--; + } + if (Flag) + result++; + } + else + result++; + } + return result; + } + + + int TSparse_Complex::NCols() + { + int result = 0; + result = col; + return result; + } + + + int TSparse_Complex::NRows() + { + int result = 0; + result = Row; + return result; + } + + + int TSparse_Complex::checkifexists(int r, int c) + { + int result = 0; + int i = 0; + result = -1; // Default in case the value doesn't exist + if (len > 0) + { + for (int stop = (len - 1), i = 0; i <= stop; i++) + { + if ((CData[i].Row == r) && (CData[i].col == c)) + result = i; // If the value exists returns the index ( >=0 ) + } + } + return result; + } + + + void TSparse_Complex::sparse_matrix_Cmplx(int r, int c) + { + Row = r; // Initialize row + col = c; // Initialize Col + len = 0; // Initialize length to 0 + CData.clear(); + } + + //Inserts elements into the sparse matrix + + int TSparse_Complex::Insert(int r, int c, complex val) + { + int result = 0; + int lrow = 0 // To store the current lenght of the data matrix + , lcol = 0; + result = 1; + lrow = checkifexists(r, c); + if (lrow >= 0) + { + CData[lrow].Value = val; // Assigns the new value to the existing cell + } + else + { + // Reshapes the memory space + lrow = CData.size(); + CData.resize( lrow + 1 ); + // Adds the data to the new memory space + CData[CData.size() - 1].Row = r; + CData[CData.size() - 1].col = c; + CData[CData.size() - 1].Value = val; + len++; + if (col < c) + col = c; + if (Row < r) + Row = r; + } + return result; + } + + // Adds another sparse matrix to this matrix + + + + TSparse_Complex TSparse_Complex::Add(TSparse_Complex* b) + { + TSparse_Complex result; // Creates a memory space to store the result + complex addeval; + int apos = 0, bpos = 0; + // First checks if the matrices have the same dimensions + if ((Row != b->Row) || (col != b->col)) + { + result.sparse_matrix_Cmplx(1, 1); + result.Insert(0, 0, cmplx(-1, 0)); + } + else + { + apos = 0; + bpos = 0; + result.sparse_matrix_Cmplx(Row, col); + while ((apos < len) && (bpos < b->len)) + { + if ((CData[apos].Row > b->CData[bpos].Row) || ((CData[apos].Row == b->CData[bpos].Row) && (CData[apos].col > b->CData[bpos].col))) + { + result.Insert(b->CData[bpos].Row, b->CData[bpos].col, b->CData[bpos].Value); + bpos++; + } + else + { + if ((CData[apos].Row < b->CData[bpos].Row) || ((CData[apos].Row == b->CData[bpos].Row) && (CData[apos].col < b->CData[bpos].col))) + { + result.Insert(CData[apos].Row, CData[apos].col, CData[apos].Value); + apos++; + } + else + { + addeval = cadd(CData[apos].Value, b->CData[bpos].Value); + if ((addeval.re != 0) && (addeval.im != 0)) + result.Insert(CData[apos].Row, CData[apos].col, addeval); + apos++; + bpos++; + } + } + } + // Inserts the remaining elements + while (apos < (len - 1)) + { + result.Insert(CData[apos].Row, CData[apos].col, CData[apos + 1].Value); + apos++; + } + while (bpos < (b->len - 1)) + { + result.Insert(b->CData[bpos].Row, b->CData[bpos].col, b->CData[bpos + 1].Value); + bpos++; + } + } + return result; + } + + // Transposes the sparse matrix + + /* + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + }*/ + + + + TSparse_Complex TSparse_Complex::Transpose() + { + TSparse_Complex result; // Creates a memory space to store the result + std::vector < int > count, Index; + int i = 0, j = 0, k = 0, rpos = 0; + + // new matrix with inversed row X col + result.sparse_matrix_Cmplx(col, Row); + // same number of elements + j = 0; + k = 0; + for (int stop = len, i = 1; i <= stop; i++) + { + result.Insert(j, k, CZero); + k++; + if (k == Row) + { + j++; + k = 0; + } + } + count.resize( col + 1 ); + Index.resize( col + 1 ); + // Initialize all to 0 + for (int stop = col, i = 0; i <= stop; i++) + count[i] = 0; + for (int stop = (len - 1), i = 0; i <= stop; i++) + count[CData[i].col]++; + // to count number of elements having col smaller + // than particular i + // as there is no col with value < 1 + Index[0] = 0; + // initialize rest of the indices + for (int stop = col, i = 1; i <= stop; i++) + Index[i] = Index[i - 1] + count[i - 1]; + for (int stop = (len - 1), i = 0; i <= stop; i++) + { + // insert a data at rpos and increment its value + rpos = Index[CData[i].col]; + Index[CData[i].col]++; + // transpose row=col + result.CData[rpos].Row = CData[i].col; + + // transpose col=row + result.CData[rpos].col = CData[i].Row; + + // same value + result.CData[rpos].Value = CData[i].Value; + } + + // the above method ensures + // sorting of transpose matrix + // according to row-col value + return result; + } + + // Transposes and conjugates the sparse matrix + + + + TSparse_Complex TSparse_Complex::TransposeConj() + { + TSparse_Complex result; // Creates a memory space to store the result + std::vector < int > count, Index; + int i = 0, rpos = 0; + + // new matrix with inversed row X col + result.sparse_matrix_Cmplx(col, Row); + // same number of elements + for (int stop = len, i = 1; i <= stop; i++) + result.Insert(i, 0, cmplx(0, 0)); + count.resize( col + 1 ); + Index.resize( col + 1 ); + // Initialize all to 0 + for (int stop = col, i = 0; i <= stop; i++) + count[i] = 0; + for (int stop = (len - 1), i = 0; i <= stop; i++) + count[CData[i].col]++; + // to count number of elements having col smaller + // than particular i + // as there is no col with value < 1 + Index[0] = 0; + // initialize rest of the indices + for (int stop = col, i = 1; i <= stop; i++) + Index[i] = Index[i - 1] + count[i - 1]; + for (int stop = (len - 1), i = 0; i <= stop; i++) + { + // insert a data at rpos and increment its value + rpos = Index[CData[i].col]; + Index[CData[i].col]++; + // transpose row=col + result.CData[rpos].Row = CData[i].col; + + // transpose col=row + result.CData[rpos].col = CData[i].Row; + + // same value + result.CData[rpos].Value = conjg(CData[i].Value); + } + + // the above method ensures + // sorting of transpose matrix + // according to row-col value + return result; + } + + // Multiplies another sparse matrix by this matrix + +/* + + Tsparse_matrix::Tsparse_matrix() + : Row(0), + col(0), + len(0) + { + } + TSparse_Complex::TSparse_Complex() + : Row(0), + col(0), + len(0) + { + } + */ + + + TSparse_Complex TSparse_Complex::multiply(TSparse_Complex* B) + { + TSparse_Complex result; // Creates a memory space to store the result + complex sum; + int c = 0, tempa = 0, tempb = 0, r = 0, apos = 0, bpos = 0; + + // First checks if the matrices have the right dimensions + if (col != B->Row) + { + result.sparse_matrix_Cmplx(1, 1); + result.Insert(0, 0, cmplx(-1, 0)); //Invalid multiplication + } + else + { + // transpose b to compare row + // and col values and to add them at the end + TSparse_Complex b_ = B->Transpose(); + TSparse_Complex *b = &b_; // added to minimize changes to the code + + // result matrix of dimension row X b.col + // however b has been transposed, hence row X b.row + result.sparse_matrix_Cmplx(Row, b->Row); + // iterate over all elements of A (this matrix) + apos = 0; + while (apos < len) + { + r = CData[apos].Row; + // iterate over all elements of B + bpos = 0; + while (bpos < b->len) + { + // current column of result matrix + // data[][0] used as b is transposed + c = b->CData[bpos].Row; + + // temporary pointers created to add all + // multiplied values to obtain current + // element of result matrix + tempa = apos; + tempb = bpos; + sum = cmplx(0, 0); + + // iterate over all elements with + // same row and col value + // to calculate result[r] + while ((tempa < len) && (CData[tempa].Row == r) && (tempb < b->len) && (b->CData[tempb].Row == c)) + { + if (CData[tempa].col < b->CData[tempb].col) + tempa++; //skip a + else + { + if (CData[tempa].col > b->CData[tempb].col) + tempb++; //skip b + else + { + // same col, so multiply and increment + sum = cadd(sum, cmul(CData[tempa].Value, b->CData[tempb].Value)); + tempa++; + tempb++; + } + } + } + // insert sum obtained in result[r] + // if its not equal to 0 + if ((sum.re != 0) && (sum.im != 0)) + result.Insert(r, c, sum); + while ((bpos < b->len) && (b->CData[bpos].Row == c)) + bpos++; // Jump to next column + } + while ((apos < len) && (CData[apos].Row == r)) + apos++; // Jump to next row + } + } + return result; + } + + // Sorts the content of the matrix by rows, important for multiplications + + void TSparse_Complex::Sort() + { + TSparse_Complex myTemp; + + myTemp.Reset(); + + for (int idx = 0; idx <= Row; idx++) + { + for (int i = 0; i < CData.size(); i++) + { + if (CData[i].Row == idx) + myTemp.Insert(CData[i].Row, CData[i].col, CData[i].Value); + } + } + // moves the new data into the local object + for (int i = 0; i < myTemp.CData.size(); i++) + { + CData[i].Row = myTemp.CData[i].Row; + CData[i].col = myTemp.CData[i].col; + CData[i].Value = myTemp.CData[i].Value; + } + } + + // Resets the sparse matrix (makes it empty) + + void TSparse_Complex::Reset() + { + CData.clear(); + len = 0; + } + // Returns the lenght of the sparse matrix (number of non-zero elements) + + + + int TSparse_Complex::NZero() + { + int result = 0; + result = len; + return result; + } + +} // namespace Sparse_Math + + + + + + + diff --git a/OpenDSSC/Common/Sparse_Math.h b/OpenDSSC/Common/Sparse_Math.h new file mode 100644 index 0000000..2cc7825 --- /dev/null +++ b/OpenDSSC/Common/Sparse_Math.h @@ -0,0 +1,117 @@ + +/******************************************************************************** + Electric Power Resarch Insitute EPRI 2022 + + Library created to handle sparse matrix linear algebra ops, the arguments need + to be sparse and provided in compressed coordiante format + Created by Davis Montenegro for EPRI 08/01/2018 + based on the code provided by Sudarshan Khasnis in Java at + https://www.geeksforgeeks.org/operations-sparse-matrices/ +********************************************************************************/ +#ifndef Sparse_MathH +#define Sparse_MathH + + +#include "System.h" + +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include + + + +namespace Sparse_Math +{ + +struct TCmplx_Data; +class TSparse_Complex; +class Tsparse_matrix; + + + + +struct TCmplx_Data { + int Row, col; + complex Value; +}; + + + +typedef std::vector < int > TData; +typedef TData* PData; +typedef TCmplx_Data TComplex; +typedef TComplex* PComplex; +typedef std::vector < complex > TComplexArr; +typedef TComplexArr* PComplexArr; + + +class Tsparse_matrix{ + friend class TSparse_Complex; +public: + // private: + int Row, col, len; + int checkifexists( int r, int c ); + void getrow( int Index, PData cols, PData vals ); + bool R_equal( PData acols, PData avals, PData bcols, PData bvals ); + public: + typedef int* Sparse_Math__0; + std::vector < TData > data; + void sparse_matrix( int r, int c ); + int Insert( int r, int c, int val ); + Tsparse_matrix Add( Tsparse_matrix* b ); + Tsparse_matrix Transpose( ); + Tsparse_matrix multiply( Tsparse_matrix* b ); + void Reset( ); + int NZero( ); + int NCols( ); + int NRows( ); + int Rank( ); + void Sort(); + public: + Tsparse_matrix(); +}; + + +class TSparse_Complex: public TObject { + typedef TObject inherited; + friend class Tsparse_matrix; +public: + //private: + int Row, col, len; + int checkifexists( int r, int c ); + void getrow( int Index, PData cols, PComplexArr vals ); + complex getvalue( int Row, int col ); + bool R_equal( PData acols, PData bcols, PComplexArr avals, PComplexArr bvals ); + public: + std::vector < TCmplx_Data > CData; + void sparse_matrix_Cmplx( int r, int c ); + int Insert( int r, int c, complex val ); + TSparse_Complex Add( TSparse_Complex* b ); + TSparse_Complex Transpose( ); + TSparse_Complex TransposeConj( ); + TSparse_Complex multiply( TSparse_Complex* b ); + void Reset( ); + int NZero( ); + int NCols( ); + int NRows( ); + int Rank( ); + void Sort(); + public: + TSparse_Complex(); +}; + +} // namespace Sparse_Math + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Sparse_Math; +#endif + +#endif // Sparse_MathH + + + + + + + + diff --git a/OpenDSSC/Common/TOPExport.cpp b/OpenDSSC/Common/TOPExport.cpp new file mode 100644 index 0000000..2f50fe0 --- /dev/null +++ b/OpenDSSC/Common/TOPExport.cpp @@ -0,0 +1,236 @@ + +#pragma hdrstop + +#include "TOPExport.h" + + + +#include +#include "AnsiStrings.h" +#include +#include "../Forms/CmdForms.h" +#include +#include "../Common/DSSGlobals.h" + + + +#include + + +TOutFile32* TOPTransferFile = NULL; +Variant TOP_Object; + + + + +TOutFile32::TOutFile32() +{ +} + + + +bool TOP_Inited = false; + + +void StartTop( ) +{ + TOP_Object = CreateOleObject( "TOP2000.MAIN" ); + TOP_Inited = true; +} + + +void TOutFile32::SendToTop( ) +{ + try + { + if ( ! TOP_Inited ) + StartTop(); + try + { + TOP_Object.OpenFile( TOPTransferFile->Fname ); + } /*Top has become disconnected*/ + // Oops. Connection to TOP is not valid; + catch(...) + { + try + { + StartTop(); + TOP_Object.OpenFile( TOPTransferFile->Fname ); + } + catch(...) + { + DSSInfoMessageDlg( "Export to TOP failed. Connection lost?" ); + } + } + } + catch( EXCEPTion & E ) + { + DSSInfoMessageDlg( "Error Connecting to TOP: " + E.Message ); + } +} + +//------------------------------------------------------------------------------------- + +std::string TOutFile32::get_Fname() +{ + return Fname; +} + +//------------------------------------------------------------------------------------- + +void TOutFile32::set_Fname(std::string S) +{ + Fname = S; +} + +//------------------------------------------------------------------------------------- + + +void TOutFile32::Open( ) +{ + AssignFile( Fout, Fname ); + Rewrite( Fout, 1 ); /*Open untyped file with a recordsize of 1 byte*/ + IOResultToException(); +} + + +void TOutFile32::Close( ) +{ + CloseFile( Fout ); /*Close the output file*/ +} + + +void TOutFile32::WriteHeader( const double t_start, const double t_stop, const double h, const int NV, const int NI, const int NameSize, const String Title ) +{ + int NumWrite = 0; + /*# with Header do */ + { + Header.Size = sizeof( ToutfileHdr ); + strcpy( Header.Signature, "SuperTran V1.00\x00" ); + Header.VersionMajor = 1; + Header.VersionMinor = 1; + Header.FBase = DefaultBaseFreq; + Header.VBase = 1.0; + Header.tStart = 0; + Header.tFinish = 0; + Header.StartTime = t_start; + Header.StopT = t_stop; + Header.DeltaT = h; + Header.Nsteps = trunc( t_stop / h ) + 1; + Header.NVoltages = NV; + Header.NCurrents = NI; + Header.VoltNameSize = NameSize; + Header.CurrNameSize = NameSize; + Header.IdxVoltNames = Header.Size; + Header.IdxCurrentNames = Header.IdxVoltNames + Header.NVoltages * Header.VoltNameSize; + Header.IdxData = Header.IdxCurrentNames + Header.NCurrents * Header.CurrNameSize; + Header.IdxBaseData = 0; +// {$IFDEF MSWINDOWS} + SysUtils.StrCopy( Header.Title1, Title.c_str()); +// {$ELSE} +// sysutils.StrCopy(Title1,pWidechar(Title)); +// {$ENDIF} + Header.Title2[0] = '\x00'; + Header.Title3[0] = '\x00'; + Header.Title4[0] = '\x00'; + Header.Title5[0] = '\x00'; + } + + /* Zap the header to disk */ + BlockWrite( Fout, Header, sizeof( Header ), NumWrite ); +} + +void TOutFile32::WriteNames( TStringList& Vnames, TStringList& Cnames ) +{ + int NumWrite = 0; + int i = 0; + wchar_t Buf[ 121/*# range 0..120*/ ]; //120 char buffer to hold names + null terminator + if ( Header.NVoltages > 0 ) + for ( int stop = Vnames.count - 1, i = 0; i <= stop; i++) + { + SysUtils.StrCopy( Buf, ((AnsiString) Vnames.Strings[i] ).c_str()); // Assign string to a buffer + BlockWrite( Fout, Buf, Header.VoltNameSize, NumWrite ); // Strings is default property of TStrings + } + if ( Header.NCurrents > 0 ) + for ( int stop = Cnames.count - 1, i = 0; i <= stop; i++) + { + SysUtils.StrCopy( Buf, ((AnsiString) Cnames.Strings[i] ).c_str()); // Assign string to a buffer + BlockWrite( Fout, Buf, Header.CurrNameSize, NumWrite ); + } +} + + +void TOutFile32::WriteData( const double t, const pDoubleArray V, const pDoubleArray Curr ) +{ + int NumWrite = 0; + BlockWrite( Fout, t, sizeof( double ), NumWrite ); + if ( Header.NVoltages > 0 ) + BlockWrite( Fout, V[1], sizeof( double ) * Header.NVoltages, NumWrite ); + if ( Header.NCurrents > 0 ) + BlockWrite( Fout, Curr[1], sizeof( double ) * Header.NCurrents, NumWrite ); +} + + +void TOutFile32::OpenR( ) /*Open for Read Only*/ +{ + AssignFile( Fout, Fname ); + Reset( Fout, 1 ); + IOResultToException(); +} + + +void TOutFile32::ReadHeader( ) /*Opposite of WriteHeader*/ +{ + int NumRead = 0; + BlockRead( Fout, Header, sizeof( Header ), NumRead ); +} + +void TOutFile32::GetVoltage( pDoubleArray t, pDoubleArray V, int idx, int MaxPts ) /*Read a voltage from disk*/ + +/*Gets a specified voltage from an STO file for plotting. Idx specifies the index into the voltage array*/ +{ + pDoubleArray Vtemp, Ctemp; + int i = 0; + int NumRead = 0; + /*Assumes V is Allocated to hold result*/ + i = 0; + Seek( Fout, Header.IdxData ); + Getmem( Vtemp, sizeof( double ) * Header.NVoltages ); + Getmem( Ctemp, sizeof( double ) * Header.NCurrents ); + while ( ( ! Eof( Fout ) ) & ( i < MaxPts ) ) + { + i++; + BlockRead( Fout, t[i], sizeof( double ), NumRead ); + BlockRead( Fout, Vtemp[1], sizeof( double ) * Header.NVoltages, NumRead ); + BlockRead( Fout, Ctemp[1], sizeof( double ) * Header.NCurrents, NumRead ); + V[i] = Vtemp[idx]; + } + Freemem( Vtemp, sizeof( double ) * Header.NVoltages ); + Freemem( Ctemp, sizeof( double ) * Header.NCurrents ); +} + +void TOPExport_initialization() +{ + TOP_Inited = false; + TOPTransferFile = new TOutFile32; + TOPTransferFile->Fname = "DSSTransfer.STO"; + CoInitialize( NULL ); +} + +class TOPExport_unit +{ +public: +TOPExport_unit() +{ + TOPExport_initialization(); +} +}; +TOPExport_unit _TOPExport_unit; + + + + + + + + diff --git a/OpenDSSC/Common/TOPExport.h b/OpenDSSC/Common/TOPExport.h new file mode 100644 index 0000000..0ae579d --- /dev/null +++ b/OpenDSSC/Common/TOPExport.h @@ -0,0 +1,88 @@ +#ifndef TOPExportH +#define TOPExportH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Supports Creation of a STO file for interfacing to TOP and the + invoking of TOP.*/ + + +#include "System.h" + +#include "Arraydef.h" + + + +//class TOutFile32; +//struct ToutfileHdr; + + + +namespace TOPExport +{ + //typedef int time_t; + +#pragma pack(push, 1) + struct ToutfileHdr { + WORD Size; + Char Signature[16/*# range 0..15*/]; + WORD VersionMajor, VersionMinor; + double FBase, VBase; + int tStart, tFinish; + double StartTime, StopT, DeltaT; + unsigned int Nsteps; + WORD NVoltages, NCurrents, VoltNameSize, CurrNameSize; + int IdxVoltNames, IdxCurrentNames, IdxBaseData, IdxData; + char Title1[80/*# range 0..79*/], Title2[80/*# range 0..79*/], Title3[80/*# range 0..79*/], Title4[80/*# range 0..79*/], Title5[80/*# range 0..79*/]; // Fixed length 80-byte string space + }; +#pragma pack(pop) + + + class TOutFile32 : public TObject { + typedef TObject inherited; + public: + ToutfileHdr Header; + String Fname; /*Default is RLCWOUT.STO'*/ + file Fout; + private: + public: + /*constructor Create(Owner: TObject);*/ + void Open(); + void Close(); + void WriteHeader(const double t_start, const double t_stop, const double h, const int NV, const int NI, const int NameSize, const String Title); + void WriteNames(TStringList& Vnames, TStringList& Cnames); + void WriteData(const double t, const pDoubleArray V, const pDoubleArray Curr); + void OpenR(); /*Open for Read Only*/ + void ReadHeader(); /*Opposite of WriteHeader*/ + void GetVoltage(pDoubleArray t, pDoubleArray V, int idx, int MaxPts); /*Read a single node voltage from disk*/ + void SendToTop(); + std::string get_Fname(); + void set_Fname(std::string S); + + public: + TOutFile32(); + }; + + + extern TOutFile32* TOPTransferFile; + extern Variant TOP_Object; // For Top Automation + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace TOPExport; +#endif + +#endif // TOPExportH + + + + + + + + diff --git a/OpenDSSC/Common/Terminal.cpp b/OpenDSSC/Common/Terminal.cpp new file mode 100644 index 0000000..67d6d78 --- /dev/null +++ b/OpenDSSC/Common/Terminal.cpp @@ -0,0 +1,73 @@ + + +#pragma hdrstop + +#include "Terminal.h" + + + +/*TPowerTerminal*/ + +TPowerTerminal::TPowerTerminal() + : FNumCond(1), + ActiveConductor(0), + BusRef(-1), + Checked(false) +{ + int i = 0; + // inherited::Create(); + TermNodeRef.resize( 2 ); + Conductors.resize( 2 ); + for (int stop = 1, i = 1; i <= stop; i++) + Conductors[i - 1] = TConductor(); + ActiveConductor = 1; +} + +TPowerTerminal::TPowerTerminal( int Ncond ) + : FNumCond(Ncond), + ActiveConductor(0), + BusRef(- 1), + Checked(false) +{ + int i = 0; + // inherited::Create(); + TermNodeRef.resize( FNumCond + 1 ); + Conductors.resize( FNumCond + 1 ); + for ( int stop = FNumCond, i = 1; i <= stop; i++) + Conductors[i - 1] = TConductor(); + ActiveConductor = 1; +} + + +TPowerTerminal::~TPowerTerminal( ) +{ + int i = 0; + Conductors.clear(); + if(!TermNodeRef.empty()) + TermNodeRef.clear(); + // todo check: inherited::Destroy; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +void TPowerTerminal::Set_ActiveConductor( int Value ) +{ + if ( ( Value > 0 ) && ( Value <= FNumCond ) ) + ActiveConductor = Value; +} + +int TPowerTerminal::get_ActiveConductor() +{ + return ActiveConductor; +} + + + + + + + + + diff --git a/OpenDSSC/Common/Terminal.h b/OpenDSSC/Common/Terminal.h new file mode 100644 index 0000000..18f1b90 --- /dev/null +++ b/OpenDSSC/Common/Terminal.h @@ -0,0 +1,61 @@ +#ifndef TerminalH +#define TerminalH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Definition of classes for all terminals of a DSS element*/ + + +//#include + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Conductor.h" + + + +//class TPowerTerminal; + + + + +class TPowerTerminal: public TObject { + typedef TObject inherited; + private: + int FNumCond; + int ActiveConductor; + int get_ActiveConductor(); + void Set_ActiveConductor( int Value ); + public: + int BusRef; + std::vector TermNodeRef; // Need to get to this fast + pTConductorArray Conductors; + bool Checked; + TPowerTerminal( int Ncond ); + virtual ~TPowerTerminal( ); + TPowerTerminal(); +}; + + +typedef std::vector pTerminalList; +//typedef TPowerTerminal* TerminalList [ 3/*# range 1..3*/ ]; + + /* + Control Terminal is managed by override functions in classes that are derived from this class + */ + +#endif // TerminalH + + + + + + + + diff --git a/OpenDSSC/Common/Utilities.cpp b/OpenDSSC/Common/Utilities.cpp new file mode 100644 index 0000000..58124a6 --- /dev/null +++ b/OpenDSSC/Common/Utilities.cpp @@ -0,0 +1,3984 @@ + +//#include +#pragma hdrstop + +#include "Utilities.h" +#include +#include +#include +#include +#ifndef windows +#include // errno +#include // uselocale +#include // abort +#include // strerror_l, strsignal +#include // stringstream +#include // fork, waitpid +#include // waitpid +#include // execvp, fork +#endif + +namespace Utilities +{ + + char* ZERONULL = NULL; + String padString = " "; //50 blanks + + String paddotsString = " ................................................."; //50 dots + bool show = true; + + + void IOResultToException() + { + WORD res = IOResult(); + // The original IOResult from d2c didn't actually clear the error state, although it does in the original Delphi function! + // We modified to behave correctly. In case that is reverted, remember to uncomment the following line: + // System::InOutRes = 0; + switch (res) + { + case 100: throw std::runtime_error("I/O error 100: Disk read error"); + case 101: throw std::runtime_error("I/O error 101: Disk write error"); + case 102: throw std::runtime_error("I/O error 102: File not assigned"); + case 103: throw std::runtime_error("I/O error 103: File not open"); + case 104: throw std::runtime_error("I/O error 104: File not open for input"); + case 105: throw std::runtime_error("I/O error 105: File not open for output"); + case 106: throw std::runtime_error("I/O error 106: Invalid numeric format"); + case 0: return; + default: throw std::runtime_error("I/O error"); + } + } + + int CompareTextShortest( const String s1, const String s2 ) + { + int result = 0; + String TestStr; + if ( s1.size() < s2.size() ) + { + TestStr = s2.substr( 0, s1.size() ); + result = CompareText( TestStr, s1 ); + } + else + { + TestStr = s1.substr( 0, s2.size() ); + result = CompareText( TestStr, s2 ); + } + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + string Pad(const String S, int Width) + // Pad out a string with blanks to Width characters + + { + String result = "", StrXtra = ""; + /* + if (S.find('$') != String::npos) + { + S._Equal(" "); + StrXtra._Equal(" "); + } + */ + int myLen = Width - S.size(); + if (myLen < 0) + StrXtra = ""; + else + StrXtra = padString.substr(0, (Width - S.size())); + result = S.substr(0, S.size()) + StrXtra; + // For i := 1 to Width-Length(S) DO Result := Result + ' '; + return result; + } + + + + + String Paddots( const String S, int Width ) + // Pad out a string with dots to Width characters + + { + String result, StrXtra; + int myLen = Width - S.size(); + if (myLen < 0) + StrXtra = ""; + else + StrXtra = paddotsString.substr(0, (Width - S.size())); + result = S.substr( 0, S.size() ) + StrXtra; + return result; + } + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String PadTrunc( const String S, int Width ) + // Pad out a string with blanks to Width characters or truncate to Width Chars + + { + String result; + result = Pad( S, Width ).substr( 0, Width ); + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String FullName( TDSSCktElement* pElem ) + { + String result; + result = EncloseQuotes( pElem->Get_myPName() + "." + UpperCase( pElem->get_Name() ) ); + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String StripExtension( const String S ) + + /*Strips off everything up to a period.*/ + { + String result; + size_t dotpos = 0; + dotpos = S.find( "." ); + if ( dotpos == String::npos ) + dotpos = S.size( ); + result = S.substr( 0, dotpos ); + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String StripClassName( const String S ) + /*Returns everything past the first period*/ + { + String result; + size_t dotpos = 0; + dotpos = S.find( "." ); + result = S.substr(( dotpos) + 1, S.size() ); + return result; + } + +#ifndef windows + static int fork_execvp(const char* file, const char* argv[], int* _wstatus, std::string* _error_message) + { + // return 0 on success, or -1 on failure with errno set. + // on success, *_wstatus is set to value from waitpid. + // on failure, *_error_message is set to the name of the library function which failed and set errno. + + pid_t pid = fork(); + if (! pid) { + // We're the fork'ed child process.cw + // + // Don't bother checking the return of execvp(), because it shouldn't + // return, and if it does, then it is an error. + errno = 0; // clearing for paranoia w/ execvp() + + /* int retval = */ execvp(file, (char*const*)argv); + + // Here, we'll use "/bin/sh -c" to parse and execute the string, but if + // we ever want to parse this string within this code, check out the + // wordexp() function. + // + // Also, someday, if we want to detect if we're running in a Linux + // graphics desktop, which most likely would be powered by X Windows, + // we can detect X by testing if the DISPLAY environment variable is + // set: + // + // if( getenv("DISPLAY") ) ... + // + // Then we can exec this process by spawning a new terminal window, + // such as "xterm" or "rxvt" if available. + + // Handle errors here: + int the_errno = errno; + char *errno_message = strerror_l(the_errno, uselocale(locale_t(0))); + std::cerr << "fork_execvp error: execvp() returned with errno=" << the_errno << ": " << errno_message << "\n"; + + // We must not allow any return to the caller. + std::abort(); + } + + // If we're here, then we're the original, parent process. + if (pid==-1) { + int the_errno = errno; + if (_error_message) + *_error_message = "fork()"; + errno = the_errno; + return -1; + } + + // If we're here, then fork() succeeded, and pid contains the ID for the + // new process. We need to wait for it to exit. + int wstatus=0; + do { + wstatus=0; + pid_t pid_ret = waitpid(pid, &wstatus, 0 /*options*/); + + if (pid_ret == -1) { + // waitpid() returned an error. + int the_errno = errno; + if (_error_message) + *_error_message = "waitpid()"; + errno = the_errno; + return -1; + } + + // Ignoring WIFSTOPPED(wstatus) and WIFCONTINUED(wstatus) + } while (!WIFEXITED(wstatus) && !WIFSIGNALED(wstatus)); + + if (_wstatus) + *_wstatus=wstatus; + + return 0; + } +#endif + + void ShowReport(bool ShowR) + { + if (ShowR == true) + { + show = true; + } + else + show = false; + } + + void FireOffEditor( String Filenm ) + { +#ifdef windows + WORD retval = 0; + try + { + if (FileExists(Filenm)) + { + AnsiString Utilities__1(EncloseQuotes(Filenm)); + { + AnsiString Utilities__0(EncloseQuotes(DefaultEditor)); + if (show == true) + { + ShellExecuteA(0, 0, Utilities__0.c_str(), Utilities__1.c_str(), 0, SW_SHOW); + } + retval = 100; + }; + SetLastResultFile(Filenm); + switch (retval) + { + case 0: + DoSimpleMsg("System out of memory. Cannot start Editor.", 700); + break; + case ERROR_BAD_FORMAT: + DoSimpleMsg("Editor File is Invalid.", 701); + break; + case ERROR_FILE_NOT_FOUND: + DoSimpleMsg("Editor \"" + DefaultEditor + "\" Not Found." + CRLF + "Did you set complete path name?", 702); + break; + case ERROR_PATH_NOT_FOUND: + DoSimpleMsg("Path for Editor \"" + DefaultEditor + "\" Not Found.", 703); + break; + } + } + } + catch (std::exception &E) + { + DoErrorMsg( "FireOffEditor.", E.what(), "Default Editor correctly specified???", 704 ); + } +#else + const char* argv[] = { DefaultEditor.c_str(), Filenm.c_str(), NULL }; + int wstatus = 0; + std::string error_message; + int the_errno = fork_execvp(argv[0], argv, &wstatus, &error_message); + if (the_errno) { + // fork_execvp() returned an error. + char *errno_message = strerror_l(the_errno, uselocale(locale_t(0))); + std::stringstream error_string; + error_string << "FireOffEditor Error: " << error_message << " returned with errno=" << the_errno << ": " << errno_message; + DoSimpleMsg( error_string.str().c_str(), 704 ); + } else { + if (WIFEXITED(wstatus)) { + // the child terminated normally. + int exit_status = WEXITSTATUS(wstatus); + if (exit_status) { + // The command finished with a nonzero status, which indicates an error. + std::stringstream error_string; + error_string << "FireOffEditor Error: command exited with nonzero status " << exit_status << ". The original command was: " << argv[0] << ' ' << argv[1]; + DoSimpleMsg( error_string.str().c_str(), 704 ); + } + } + + if (WIFSIGNALED(wstatus)) { + // the child process was terminated by a signal. + int exit_signal = WTERMSIG(wstatus); + std::stringstream error_string; + const char *exit_signal_name = strsignal(exit_signal); + if (!exit_signal_name) + exit_signal_name = "invalid signal number"; + error_string << "FireOffEditor Error: command terminated due to signal " << exit_signal << ", \"" << exit_signal_name << "\". The original command was: " << argv[0] << ' ' << argv[1]; + DoSimpleMsg( error_string.str().c_str(), 704 ); + } + } +#endif + } + + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void DoDOSCmd( String CmdString ) + { +#ifdef windows + HWND Handle = 0; + try + { + Handle = 0; + ShellExecute( Handle, "open", ( PChar ) ( "cmd.exe" ), CmdString.c_str(), NULL, SW_SHOW ); + } + catch (std::exception& E) + { + DoSimpleMsg( "DoDOSCmd Error:" + (string) E.what() + ".Error in Command " + CmdString, 704 ); + } +#else + const char* argv[] = { "/bin/sh", "-c", CmdString.c_str(), NULL }; + int wstatus = 0; + std::string error_message; + int the_errno = fork_execvp(argv[0], argv, &wstatus, &error_message); + if (the_errno) { + // fork_execvp() returned an error. + char *errno_message = strerror_l(the_errno, uselocale(locale_t(0))); + std::stringstream error_string; + error_string << "DoDOSCmd Error: " << error_message << " returned with errno=" << the_errno << ": " << errno_message; + DoSimpleMsg( error_string.str().c_str(), 704 ); + } else { + if (WIFEXITED(wstatus)) { + // the child terminated normally. + int exit_status = WEXITSTATUS(wstatus); + if (exit_status) { + // The command finished with a nonzero status, which indicates an error. + std::stringstream error_string; + error_string << "DoDOSCmd Error: command exited with nonzero status " << exit_status << ". The original command was: " << CmdString.c_str(); + DoSimpleMsg( error_string.str().c_str(), 704 ); + } + } + + if (WIFSIGNALED(wstatus)) { + // the child process was terminated by a signal. + int exit_signal = WTERMSIG(wstatus); + std::stringstream error_string; + const char *exit_signal_name = strsignal(exit_signal); + if (!exit_signal_name) + exit_signal_name = "invalid signal number"; + error_string << "DoDOSCmd Error: command terminated due to signal " << exit_signal << ", \"" << exit_signal_name << "\". The original command was: " << CmdString.c_str(); + DoSimpleMsg( error_string.str().c_str(), 704 ); + } + } +#endif + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + String IntArrayToString( pIntegerArray iarray, int count ) + // Put array values in parentheses separated by commas. + + { + String result; + int i = 0; + result = "[NULL]"; + if ( count > 0 ) + { + result = "["; + for ( int stop = count, i = 1; i <= stop; i++) + { + result = result + to_string( (iarray)[i] ); + if ( i != count ) + result = result + ", "; + } + result = result + "]"; + } + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String DblArrayToString( pDoubleArray dblarray, int count ) + // Put array values in brackets separated by commas. + + { + String result; + int i = 0; + result = "[NULL]"; + if (count > 0) + { + result = Format( "[%.10g", dblarray[1] ); + for ( int stop = count, i = 2; i <= stop; i++) + result = result + Format( ", %.10g", dblarray[i]); + result = result + "]"; + } + return result; + } + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + String CmplxArrayToString( pComplexArray cpxarray, int count ) + // Put array values in brackets separated by commas. + + { + String result; + int i = 0; + result = "[NULL]"; + if ( count > 0 ) + { + result = Format("[%.10g +j %.10g", cpxarray[1].re, cpxarray[1].im); + for ( int stop = count, i = 2; i <= stop; i++) + result = result + Format( ", %.10g +j %.10g", (cpxarray)[i].re, ((cpxarray)[i].im ) ); + result = result + "]"; + } + return result; + } + + + String EncloseQuotes( const String S ) + { + String result; + result = String( "\"" ) + S + "\""; + return result; + } + + + + //---------------------------------------------------------------------------- + + + + int InterpretSolveMode( const String S ) + + // interpret solution mode + // could be "nominal" "daily" "yearly" "montecarlo" "dutycycle" "loadduration" "peakdays" , etc. + + { + int result = 0; + String SLC; + SLC = ToLowerCaseStr( S ); + switch ( SLC[0] ) + { + case 's': + result = SNAPSHOT; + break; + case 'd': + switch ( SLC[1] ) + { + case 'u': + result = DUTYCYCLE; + break; + case 'i': + result = DIRECT; + break; + case 'y': + result = DYNAMICMODE; + break; + default: + result = DAILYMODE; + } + break; + case 'e': + switch (SLC.size() > 3 ? SLC[3] : '\0') + { + case 'd': + result = EMPDAILYMODE; + break; + default: + result = EMPMODE; + } + break; + case 'f': + result = FAULTSTUDY; + break; + case 'h': + switch (SLC.size() > 8 ? SLC[8] : '\0') + { + case //Modification added by Davis Montenegro 25/06/2014 + 't': + result = HARMONICMODET; + break; // For adding the harmoncis mode in time domain + default: + result = HARMONICMODE; + } + break; + case 'y': + result = YEARLYMODE; + break; + case 'm': + switch ( SLC[1] ) + { + case '1': + result = MONTECARLO1; + break; + case '2': + result = MONTECARLO2; + break; + case '3': + result = MONTECARLO3; + break; + case 'f': + result = MONTEFAULT; + break; + default: + result = MONTECARLO1; + } + break; + case 'p': + result = PEAKDAY; + break; + case 'a': + result = AUTOADDFLAG; + break; + case 'l': + switch ( SLC[1] ) + { + case 'd': + switch (SLC.size() > 2 ? SLC[2] : '\0') + { + case '1': + result = LOADDURATION1; + break; + case '2': + result = LOADDURATION2; + break; + default: + result = LOADDURATION1; + } + break; + default: + result = LOADDURATION1; + } + break; + case 't': + result = GENERALTIME; + break; + default: + result = SNAPSHOT; + } + return result; + } + + //---------------------------------------------------------------------------- + + + int InterpretControlMode( const String S ) + + // interpret solution control mode + + { + int result = 0; + String SLC; + SLC = ToLowerCaseStr( S ); + switch ( SLC[0] ) + { + case 'o': + result = CONTROLSOFF; + break; + case 'e': + result = EVENTDRIVEN; + break; // "event" + + case 't': + result = TIMEDRIVEN; + break; // "time" + + case 'm': + result = MULTIRATE; + break; // "MultiRate" + default: + result = CTRLSTATIC; + } + return result; + } + //---------------------------------------------------------------------------- + + + + int InterpretLoadModel( const String S ) + { + int result = 0; + String s2; + s2 = ToLowerCaseStr( S ); + switch ( s2[0] ) + { + case 'a': + result = ADMITTANCE; + break; + case 'p': + result = POWERFLOW; + break; + default: + result = ADMITTANCE; + } + /* If this represents a change, invalidate all the PC Yprims*/ + if ( result != (*(ActiveCircuit[ActiveActor])).Solution->LoadModel ) + (*(ActiveCircuit[ActiveActor])).InvalidateAllPCElements(); + return result; + } + + //---------------------------------------------------------------------------- + + + + bool InterpretYesNo( const String S ) + + //' Interpret Yes / no properties - can also be True/False + + { + bool result = false; + Char s2 = '\0'; + s2 = ToLowerCaseStr( S )[0]; + switch ( s2 ) + { + case 'y': case 't': + result = true; + break; + case 'n': case 'f': + result = false; + break; + default: + result = false; + } + return result; + } + + //---------------------------------------------------------------------------- + + + + int InterpretRandom( const String S ) + + // interpret the type of random variation in the load + // none|gaussian|uniform |lognormal + + { + int result = 0; + String SLC; + SLC = ToLowerCaseStr( S ); + switch ( SLC[0] ) + { + case 'g': + result = GAUSSIAN; + break; //gaussian + + case 'u': + result = UNIFORM; + break; //uniform + + case 'l': + result = LOGNORMAL; + break; // Log-Normal + default: + result = 0; // no variation for any other entry + } + return result; + } + + + //---------------------------------------------------------------------------- + + + + int InterpretAddType( const String S ) + // type of device to automatically add. Default is capacitor + + { + int result = 0; + String SLC; + SLC = ToLowerCaseStr( S ); + switch ( SLC[0] ) + { + case 'g': + result = GENADD; + break; + default: + result = CAPADD; + } + return result; + } + + //---------------------------------------------------------------------------- + + + + int InterpretConnection( const String S ) + /* Accepts (Case insensitive) + delta or LL Result=1 + Y, wye, or LN Result=0 + */ + { + int result = 0; + result = 0; + switch ( ToLowerCaseStr( S )[0] ) + { + case 'y': case 'w': + result = 0; + break; /*Wye*/ + case 'd': + result = 1; + break; /*Delta or line-Line*/ + case 'l': + switch ( ToLowerCaseStr( S )[1] ) + { + case 'n': + result = 0; + break; + case 'l': + result = 1; + break; + } + break; + } + return result; + } + + //---------------------------------------------------------------------------- + + + + int InterpretSolveAlg( const String S ) + { + int result = 0; + string mytemp = S; + mytemp = ToLowerCaseStr(mytemp).substr(0,2); + if (mytemp == "ne") // Newton method + result = NEWTONSOLVE; + else if (mytemp == "nc") // NCIM method + result = NCIMSOLVE; + else // floating-point method (default) + result = NORMALSOLVE; + + return result; + } + + + //---------------------------------------------------------------------------- + + + + bool InterpretCktModel( const String S ) + + /*Returns True if Positive Sequence*/ + { + bool result = false; + switch ( S[0] ) + { + case 'p': case 'P': + result = true; + break; + default: + result = false; + } + return result; + } + + //---------------------------------------------------------------------------- + + + + complex InterpretComplex( const String S ) + + // interpret first two entries as complex numbers + + { + complex result = CZero; + String ParmName; + AuxParser[ActiveActor]->SetCmdString(S); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + result.re = AuxParser[ActiveActor]->MakeDouble_(); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + result.im = AuxParser[ActiveActor]->MakeDouble_(); + return result; + } + + //---------------------------------------------------------------------------- + + + void InitDblArray( int NumValues, pDoubleArray Xarray, double Value ) + { + int i = 0; + /*Set all elements of a double array*/ + for ( int stop = NumValues, i = 1; i <= stop; i++) + Xarray[i - 1] = Value; + } + + //---------------------------------------------------------------------------- + + + + void InitIntArray( int NumValues, pIntegerArray Xarray, int Value ) + { + int i = 0; + /*Set all elements of a Integer array*/ + for ( int stop = NumValues, i = 1; i <= stop; i++) + Xarray[i - 1] = Value; + } + + //---------------------------------------------------------------------------- + + + + int InterpretDblArray( const String S, int MaxValues, pDoubleArray ResultArray ) + + /* Get numeric values from an array specified either as a list on numbers or a text file spec. + ResultArray must be allocated to MaxValues by calling routine. + + 9/7/2011 Modified to allow multi-column CSV files and result file + + CSV File my have one value per line or multiple columns and a header row. + Example: + ... mult=[file = myfilename, column=2, header=yes] + ... mult=[file = %result%, column=2, header=yes] // last result file + + file= must be first + the %result% variable implies the last result file + + or + + Use the Array=@lastfile variable syntax and the parser will automativally replace with last file name + + */ + { + int result = 0; + String ParmName, Param; + TTextRec F; + char* MyStream = nullptr; + int i = 0; + float temp = 0.0; + String CSVFileName; + int CSVColumn = 0; + bool CSVHeader = false; + String InputLIne; + int iskip = 0; + AuxParser[ActiveActor]->SetCmdString(S); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + result = MaxValues; // Default Return Value; + + /*Syntax can be either a list of numeric values or a file specification: File= ...*/ + if ( CompareText( ParmName, "file" ) == 0 ) + { + /*Default values*/ + if ( CompareText( Param, "%result%" ) == 0 ) + CSVFileName = LastResultFile; + else + CSVFileName = Param; + if ( ! FileExists( CSVFileName ) ) + { + DoSimpleMsg( "CSV file " + CSVFileName + " does not exist", 70401 ); + return result; + } + + // Default options + CSVColumn = 1; + CSVHeader = false; + + // Look for other options (may be in either order) + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + while ( Param.size() > 0 ) + { + if ( CompareTextShortest( ParmName, "column" ) == 0 ) + CSVColumn = AuxParser[ActiveActor]->MakeInteger_(); + if ( CompareTextShortest( ParmName, "header" ) == 0 ) + CSVHeader = InterpretYesNo( Param ); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + + // load the list from a file + try + { + System::AssignFile( F, CSVFileName ); + System::Reset( F ); + IOResultToException(); + if ( CSVHeader ) + System::ReadLn( F, InputLIne ); // skip the header row + for ( int stop = MaxValues, i = 1; i <= stop; i++) + { + try + { + if ( ! Eof( F ) ) + { + System::ReadLn( F, InputLIne ); + AuxParser[ActiveActor]->SetCmdString(InputLIne); + for ( int stop = CSVColumn, iskip = 1; iskip <= stop; iskip++) + ParmName = AuxParser[ActiveActor]->GetNextParam(); + ResultArray[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + } + else + { + result = i - 1; // This will be different if less found; + break; + } + } + catch( exception & E ) + { + { + DoSimpleMsg("Error reading " + to_string(i) + "-th numeric array value from file: " + Param + " Error is:" + (string)E.what(), 705 ); + result = i - 1; + break; + } + } + } + System::CloseFile(F); + } + catch (exception &E) + { + DoSimpleMsg("An error has occurred: " + (string)E.what(), 760); + } + } + else + if ( ( ParmName.size() > 0 ) && ( CompareTextShortest( ParmName, "dblfile" ) == 0 ) ) + { + // load the list from a file of doubles (no checking done on type of data) + //MyStream = TMemoryStream.Create; + if ( FileExists( Param ) ) + { + int i = 0; + streampos size; + ifstream file( AdjustPath(Param), std::ios::binary ); + if (file.is_open()) + { + file.seekg(0, ios_base::end); + size = file.tellg(); + MyStream = new char[size]; + file.seekg(0, ios::beg); + file.read(MyStream, size); + file.close(); + double* double_values = (double*)MyStream; + int totaldata = (int)( size / sizeof( ResultArray[0] ) ); + // Now move the doubles from the file into the destination array + for (i = 0; i < totaldata; i++) + { + ResultArray[i] = double_values[i]; + } + } + } + else + DoSimpleMsg( "File of doubles " + Param +" not found.", 70501 ); + free(MyStream); + } + else + if ( ( ParmName.size() > 0 ) && ( CompareTextShortest( ParmName, "sngfile" ) == 0 ) ) + { + // load the list from a file of singles (no checking done on type of data) + if (FileExists(Param)) + { + int i = 0; + streampos size; + ifstream file(AdjustPath(Param), std::ios::binary); + if (file.is_open()) + { + file.seekg(0, ios_base::end); + size = file.tellg(); + MyStream = new char[size]; + file.seekg(0, ios::beg); + file.read(MyStream, size); + file.close(); + float* single_values = (float*)MyStream; + int totaldata = (int)(size / sizeof(float)); + // Now move the doubles from the file into the destination array + for (i = 0; i < totaldata; i++) + { + ResultArray[i] = (double) single_values[i]; + } + } + } + else + DoSimpleMsg("File of doubles " + Param + " not found.", 70501); + free(MyStream); + } + else + { // Parse list of values off input string + + // Parse Values of array list + for ( int stop = MaxValues, i = 1; i <= stop; i++) + { + ResultArray[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); // Fills array with zeros if we run out of numbers + String dummy = AuxParser[ActiveActor]->GetNextParam(); + } + } + return result; + } + + //---------------------------------------------------------------------------- + + + double InterpretDblArrayMMF( unsigned char* myMap, int FileType, int Column, int Index, int DataSize ) + + /* Gets the value for the value at INDEX within the file mapped (myMap) + Considers the flags FileType, Column for locating the data within the file + FileType : + 0 - normal file (ANSI char) + 1 - dblfile + 2 - sngfile + */ + { + double result = 0.0; + unsigned char DBLByteArray[8/*# range 0..7*/]{}; + unsigned char SGLByteArray[4/*# range 0..3*/]{}; + String InputLIne, myContent; + unsigned char myByte = 0; + int OffSet = 0, i = 0, j = 0; + result = 1.0; // Default Return Value; + OffSet = ( Index - 1 ) * DataSize; + if ( FileType == 0 ) // Normal file (CSV, txt, ASCII based file) + { + myContent = ""; + myByte = 0; + i = OffSet; + if ( myMap[i] == 0x0A ) + i++; // in case we are at the end of the previous line + j = 0; + while ( myByte != 0x0A ) + { + myByte = myMap[i]; + // Concatenates avoiding special chars (EOL) + if ( ( myByte >= 46 ) && ( myByte < 58 ) ) + myContent = myContent + ( AnsiChar ) ( myByte ); + if ( myByte == 44 ) // a comma char was found + { // If we are at the column, exit, otherwise, keep looking + j++; // discarding the previous number (not needed anyway) + if ( j == Column ) + break; + else + myContent = ""; + } + i++; + } + try + { + // checks if the extraction was OK, othwerwise, forces the default value + if ( myContent.empty()) + myContent = "1.0"; + result = stod(myContent); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error reading " + to_string(i) + "- th numeric array value.Error is : " + (string) E.what(), 785 ); + result = i - 1; + } + } + } + else + if ( FileType == 1 ) // DBL files + { + // load the list from a file of doubles (no checking done on type of data) + for ( int stop = ( DataSize - 1 ), i = 0; i <= stop; i++) + DBLByteArray[i] = myMap[i + OffSet]; // Load data into the temporary buffer + result = *(double*) DBLByteArray; // returns the number (double) + } + else + if ( FileType == 2 ) // SGL files + { + // load the list from a file of doubles (no checking done on type of data) + for ( int stop = ( DataSize - 1 ), i = 0; i <= stop; i++) + SGLByteArray[i] = myMap[i + OffSet]; // Load data into the temporary buffer + result = (double) *(float*)SGLByteArray; // returns the number formatted as double + } + return result; + } + + + int InterpretIntArray( const String S, int MaxValues, pIntegerArray ResultArray ) + + /* Get numeric values from an array specified either as a list on numbers or a text file spec. + ResultArray must be allocated to MaxValues by calling routine. + File is assumed to have one value per line.*/ + { + int result = 0; + String ParmName, Param; + TTextRec F; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(S); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + result = MaxValues; // Default return value + + /*Syntax can be either a list of numeric values or a file specification: File= ...*/ + if ( CompareText( ParmName, "file" ) == 0 ) + { + // load the list from a file + try + { + System::AssignFile( F, Param ); + System::Reset( F ); + IOResultToException(); + for ( int stop = MaxValues, i = 1; i <= stop; i++) + { + if (!Eof(F)) + { + System::ReadLn(F, (char*) &ResultArray[i]); + } + else + { + result = i - 1; + break; + } + } + System::CloseFile( F ); + } + catch( exception & E ) + { + DoSimpleMsg( "Error trying to read numeric array values from file: " + Param + " Error is: " + (string) E.what(), 706 ); + } + } + else + { // Parse list of values off input string + + // Parse Values of array list + for ( int stop = MaxValues, i = 1; i <= stop; i++) + { + ResultArray[i - 1] = AuxParser[ActiveActor]->MakeInteger_(); // Fills array with zeros if we run out of numbers + String dummy = AuxParser[ActiveActor]->GetNextParam(); + } + } + return result; + } + + double InterpretTimeStepSize( const String S ) + /*Return stepsize in seconds*/ + { + double result = 0.0; + int Code = 0; + Char ch = '\0'; + String s2; + /*Try to convert and see if we get an error*/ + val( S, &result, &Code ); + if ( Code == 0 ) + return result; // Only a number was specified, so must be seconds + + /*Error occurred so must have a units specifier*/ + ch = S[S.size() - 1]; // get last character + s2 = S.substr( 0, S.size() - 1 ); + val( s2, &result, &Code ); + if ( Code > 0 ) + { /*check for error*/ + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.h; // Don't change it + DoSimpleMsg( "Error in specification of StepSize: " + S, 99933 ); + return result; + } + switch ( ch ) + { + case 'h': + result = result * 3600.0; + break; + case 'm': + result = result * 60.0; + break; + case 's': + break; // Do nothing + default: + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.h; // Don't change it + DoSimpleMsg( String( "Error in specification of StepSize: \"" ) + S + "\" Units can only be h, m, or s (single char only) ", 99934 ); + } + return result; + } + + + //---------------------------------------------------------------------------- + + + + void InitStringToNull( String& S ) + { + Move( ZERONULL, S, 4 ); + } + + //---------------------------------------------------------------------------- + + + + void ReallocStringArray( int& Maxsize, pStringArray ResultArray, int& Size ) + { + int j = 0; + ResultArray = (pStringArray) realloc(ResultArray, sizeof(ResultArray[0]) * Maxsize); + for ( int stop = Maxsize, j = Size + 1; j <= stop; j++) + InitStringToNull( ResultArray[j] ); // Init string values + } + + + void BumpUpStringArray( int& Maxsize, pStringArray ResultArray, int& Size ) + { + Maxsize += 100; + ReallocStringArray(Maxsize, ResultArray, Size); + } + + + void FreeStringArray( pStringArray ResultArray, int& Size ) + { + int j = 0; + if (( ResultArray != NULL)) + { + for ( int stop = Size, j = 1; j <= stop; j++) + { + (ResultArray)[j] = ""; + } + free(ResultArray); + } + } + + + void InterpretAndAllocStrArray( const String S, int& Size, pStringArray ResultArray ) + + /* Get string values from an array specified either as a list on strings or a text file spec. + ResultArray is allocated as needed. + File is assumed to have one value per line.*/ + { + String ParmName, Param; + TTextRec F; + int Maxsize = 0; + + // Throw Away any Previous Allocation + Arraydef::FreeStringArray(ResultArray, Size); + + // Now Reallocate + Maxsize = 100; // initialize + Size = 0; + ReallocStringArray(Maxsize, ResultArray, Size); + AuxParser[ActiveActor]->SetCmdString(S); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + + /*Syntax can be either a list of string values or a file specification: File= ...*/ + if ( CompareText( ParmName, "file" ) == 0 ) + { + // load the list from a file + try + { + System::AssignFile( F, Param ); + System::Reset( F ); + IOResultToException(); + while ( ! Eof( F ) ) + { + System::ReadLn( F, Param ); + if ( !Param.empty()) + { // Ignore Blank Lines in File + Size++; + if ( Size > Maxsize ) + BumpUpStringArray(Maxsize, ResultArray, Size); + ResultArray[Size] = Param; + } + } + System::CloseFile( F ); + } + catch( exception & E ) + { + DoSimpleMsg( "Error trying to read numeric array values from a file. Error is: " + (string) E.what(), 707 ); + } + } + else + { // Parse list of values off input string + + // Parse Values of array list + while ( !Param.empty()) + { + Size++; + if ( Size > Maxsize ) + BumpUpStringArray(Maxsize, ResultArray, Size); + ResultArray[Size] = Param; + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } + Maxsize = Size; // Get rid of Excess Allocation + ReallocStringArray(Maxsize, ResultArray, Size); + } + + //---------------------------------------------------------------------------- + + + void InterpretTStringListArray( const String S, TStringList& ResultList ) + + /* Get string values from an array specified either as a list on strings or a text file spec. + ResultArray is allocated as needed. + File is assumed to have one value per line.*/ + { + String ParmName, Param, NextParam; + TTextRec F; + + // Throw Away any Previous Allocation + ResultList.clear(); + AuxParser[ActiveActor]->SetCmdString(S); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + + /*Syntax can be either a list of string values or a file specification: File= ...*/ + if ( CompareText( ParmName, "file" ) == 0 ) + { + // load the list from a file + try + { + System::AssignFile( F, Param ); + System::Reset( F ); + IOResultToException(); + while ( ! Eof( F ) ) + { + System::ReadLn( F, Param ); + AuxParser[ActiveActor]->SetCmdString(Param); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + NextParam = AuxParser[ActiveActor]->MakeString_(); + if ( NextParam.size() > 0 ) + { // Ignore Blank Lines in File + ResultList.push_back( NextParam ); + } + } + System::CloseFile( F ); + } + catch( exception & E ) + { + DoSimpleMsg( "Error trying to read numeric array values from a file. Error is: " + (string) E.what(), 708 ); + } + } + else + { // Parse list of values off input string + + // Parse Values of array list + while ( !Param.empty()) + { + ResultList.push_back( Param ); + ParmName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } + } + + + int InterpretCoreType( const String str ) + { + int result = 0; + switch ( str[1] ) + { + case '1': + result = 1; + break; // 1-phase + + case '3': + result = 3; + break; // 3-Leg + + case '4': + result = 4; + break; // 4-Leg + + case '5': + result = 5; + break; // 5-Leg + + case 'c': case 'C': + result = 9; + break; // Core-1-phase + default: + result = 0; // shell + } + return result; + } + + //---------------------------------------------------------------------------- + + + void ParseObjectClassandName( const String FullObjName, String& ClassName, String& ObjName ) + { + size_t dotpos = 0; + + // Split off Obj class and name + dotpos = FullObjName.find( "." ); + switch ( dotpos ) + { + case String::npos: + { + ObjName = FullObjName.substr( 0, FullObjName.size() ); // assume it is all objname; class defaults + ClassName = ""; + } + break; + default: + { + ClassName = FullObjName.substr( 0, dotpos ); + ObjName = FullObjName.substr((dotpos) + 1, FullObjName.size() ); + } + } + + // Check object name in case it is a variable + Parser[ActiveActor]->CheckforVar( ObjName ); + } + + + String GetSolutionModeIDName( int idx ) + { + String result; + switch ( idx ) + { + case SNAPSHOT: + result = "Snap"; + break; + case DAILYMODE: + result = "Daily"; + break; + case YEARLYMODE: + result = "Yearly"; + break; + case MONTECARLO1: + result = "M1"; + break; + case MONTECARLO2: + result = "M2"; + break; + case MONTECARLO3: + result = "M3"; + break; + case LOADDURATION1: + result = "LD1"; + break; + case LOADDURATION2: + result = "LD2"; + break; + case PEAKDAY: + result = "Peakday"; + break; + case DUTYCYCLE: + result = "DUtycycle"; + break; + case DIRECT: + result = "DIrect"; + break; + case DYNAMICMODE: + result = "DYnamic"; + break; + case MONTEFAULT: + result = "MF"; + break; + case FAULTSTUDY: + result = "Faultstudy"; + break; + case AUTOADDFLAG: + result = "Autoadd"; + break; + case HARMONICMODE: + result = "Harmonic"; + break; + case HARMONICMODET: + result = "HarmonicT"; + break; + case GENERALTIME: + result = "Time"; + break; + case EMPMODE: + result = "EMPMODE"; + break; + case EMPDAILYMODE: + result = "EMPDAILYMODE"; + break; + default: + result = "UNKNOWN"; + } + return result; + } + + + String GetSolutionModeID( ) + { + String result; + result = "UNKNOWN"; + if ( ActiveCircuit[ActiveActor] != NULL ) + result = GetSolutionModeIDName(ActiveCircuit[ActiveActor]->Solution->Get_SolMode() ); + return result; + } + + + String GetControlModeID( ) + { + String result; + result = "Unknown"; + if ( ActiveCircuit[ActiveActor] != NULL ) + switch ( ActiveCircuit[ActiveActor]->Solution->ControlMode ) + { + case CTRLSTATIC: + result = "STATIC"; + break; + case EVENTDRIVEN: + result = "EVENT"; + break; + case TIMEDRIVEN: + result = "TIME"; + break; + case CONTROLSOFF: + result = "OFF"; + break; + case MULTIRATE: + result = "MULTIRATE"; + break; + default: + result = "UNKNOWN"; + } + return result; + } + + + String GetRandomModeID( ) + { + String result; + result = "Unknown"; + if ( ActiveCircuit[ActiveActor] != NULL ) + switch ( ActiveCircuit[ActiveActor]->Solution->RandomType ) + { + case 0: + result = "None"; + break; + case GAUSSIAN: + result = "Gaussian"; + break; + case UNIFORM: + result = "Uniform"; + break; + case LOGNORMAL: + result = "LogNormal"; + break; + default: + result = "Unknown"; + } + return result; + } + + + String GetLoadModel( ) + { + String result; + switch ( ActiveCircuit[ActiveActor]->Solution->LoadModel ) + { + case ADMITTANCE: + result = "Admittance"; + break; + default: + result = "PowerFlow"; + } + return result; + } + + void ParseIntArray( pIntegerArray iarray, int& count, const String S ) + { + String ParamName; + String Param; + int i = 0; + + // Parse the line once to get the count of tokens on string, S + AuxParser[ActiveActor]->SetCmdString(S); + count = 0; + do + { + ParamName = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + if ( Param.size() > 0 ) + count++; + } + while ( ! ( Param.size() == 0 ) ); + + // reallocate iarray to new size + iarray = (pIntegerArray) realloc( iarray, sizeof(iarray[0]) * count); + + // Parse again for real + AuxParser[ActiveActor]->SetCmdString(S); + for ( int stop = count, i = 1; i <= stop; i++) + { + ParamName = AuxParser[ActiveActor]->GetNextParam(); + (iarray)[i] = AuxParser[ActiveActor]->MakeInteger_(); + } + } + + + bool IsShuntElement( const TDSSCktElement* elem ) + { + bool result = false; + switch ( elem->DSSObjType & CLASSMASK ) + { + case CAP_ELEMENT: + { + result = ( ( TCapacitorObj* ) elem )->IsShunt; + break; + } + case REACTOR_ELEMENT: + { + result = ( ( TReactorObj* ) elem )->IsShunt; + break; + } + default: + result = false; + } + return result; + } + + + bool IslineElement( const TDSSCktElement* elem ) + { + bool result = false; + if ( ( ( elem->DSSObjType & CLASSMASK ) ) == LINE_ELEMENT ) + result = true; + else + result = false; + return result; + } + + + bool IsTransformerElement( const TDSSCktElement* elem ) + { + bool result = false; + if ( ( ( elem->DSSObjType & CLASSMASK ) ) == XFMR_ELEMENT ) + result = true; + else + result = false; + return result; + } + + + + //---------------------------------------------------------------------------- + + + + int GetCktElementIndex( const String FullObjName ) + + // Given the full object name, return the index to the circuit element in the + // active circuit. Use full name if given. Else assume last class referenced. + + { + int result = 0; + int DevClassIndex = 0, Devindex = 0; + String DevClassName, DevName; + result = 0; // Default return value + ParseObjectClassandName( FullObjName, DevClassName, DevName ); + DevClassIndex = ClassNames[ActiveActor].Find( DevClassName ); + if ( DevClassIndex == 0 ) + DevClassIndex = LastClassReferenced[ActiveActor]; + + // Since there could be devices of the same name of different classes, + // loop until we find one of the correct class + /*# with ActiveCircuit[ActiveActor] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + Devindex = with0->DeviceList.Find( DevName ); + while ( Devindex > 0 ) + { + if (with0->DeviceRef[(Devindex) - 1].CktElementClass == DevClassIndex ) // we got a match + { + result = Devindex; + return result; + } + Devindex = with0->DeviceList.FindNext(); + } + } + } + return result; + } + + //---------------------------------------------------------------------------- + + + + String Str_Real( const double Value, int NumDecimals ) + { + String result; + try + { + // Str(Value:0:NumDecimals, Result); + result = FloatToStrF( Value, ffFixed, 0, NumDecimals ); + } + catch(...) + { + result = "*****"; + } + return result; + } + + + + + // - - - - - -------------------------------------------------- + + + + String ReplaceCRLF( const String S ) + { + String result; + size_t nPos = 0; + /*Replace CRLF with a \n character sequence*/ + result = S; + nPos = result.find( CRLF ); + while ( nPos != String::npos ) + { + result[nPos] = '\\'; + result[(nPos) + 1] = 'n'; + nPos = result.find( CRLF ); + } + return result; + } + + // - - - - - -------------------------------------------------- + + + String RestoreCRLF( const String S ) + { + String result; + size_t nPos = 0; + /*Replace CRLF with a \n character sequence*/ + result = S; + nPos = result.find( "\\n" ); + while ( nPos != String::npos ) + { + result[nPos] = Char( 13 ); + result[(nPos) + 1] = Char( 10 ); + nPos = result.find( "\\n" ); + } + return result; + } + + // - - - - - -------------------------------------------------- + + + + void DumpAllocationFactors( String& Filename ) + { + TTextRec F; + TLoadObj* pLoad; + try + { + System::AssignFile( F, Filename ); + System::Rewrite( F ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoErrorMsg( String( "Error opening " ) + Filename + " for writing.", (string) E.what(), " File protected or other file error.", 709 ); + return; + } + } + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + pLoad = (TLoadObj*) with0->Loads.Get_First(); + std::stringstream stream; + while ( pLoad != NULL ) + { + switch ( (*pLoad).LoadSpecType ) + { + case 3: + { + System::Write( F, "Load." + ( (TDSSCktElement*) pLoad )->get_Name() + ".AllocationFactor=" ); + stream << std::fixed << std::setprecision(2) << pLoad->get_FkVAAllocationFactor(); + System::WriteLn( F, stream.str()); + } + break; + case 4: + { + System::Write( F, "Load." + ( (TDSSCktElement*) pLoad)->get_Name() + ".CFactor=" ); + stream << std::fixed << std::setprecision(2) << pLoad->get_FCFactor(); + System::WriteLn(F, stream.str()); + } + break; + } + pLoad = (TLoadObj*) with0->Loads.Get_Next(); + } /*While*/ + } + } /*With*/ + System::CloseFile(F); + GlobalResult = Filename; + } + + + // - - - - - -------------------------------------------------- + + + + void DumpAllDSSCommands( String& Filename ) + { + TTextRec F; + TDSSClass* pClass; + int i = 0; + try + { + Filename = GetOutputDirectory() + "DSSCommandsDump.Txt"; + System::AssignFile( F, Filename ); + System::Rewrite( F ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoErrorMsg( String( "Error opening " ) + Filename + " for writing.", (string) E.what(), "Disk protected or other file error", 710 ); + return; + } + } + + // dump Executive commands + System::WriteLn( F, "[execcommands]" ); + for ( int stop = NumExecCommands, i = 1; i <= stop; i++) + { + System::Write( F, i, 0 ); + System::Write( F, ", \"" ); + System::Write( F, ExecCommand[i] ); + System::Write( F, "\", \"" ); + System::Write( F, ReplaceCRLF( CommandHelp[i] ) ); + System::WriteLn( F, '\"' ); + } + + // Dump Executive Options + System::WriteLn( F, "[execoptions]" ); + for ( int stop = NumExecOptions, i = 1; i <= stop; i++) + { + System::Write( F, i, 0 ); + System::Write( F, ", \"" ); + System::Write( F, ExecOption[i] ); + System::Write( F, "\", \"" ); + System::Write( F, ReplaceCRLF( OptionHelp[i] ) ); + System::WriteLn( F, '\"' ); + } + + // Dump All presend DSSClasses + pClass = (TDSSClass*) (DSSClassList[ActiveActor].Get_First()); + while ( pClass != NULL ) + { + System::Write( F, '[' ); + System::Write( F, (*pClass).get_myClass_name() ); + System::WriteLn( F, ']' ); + for ( int stop = (*pClass).NumProperties, i = 1; i <= stop; i++) + { + System::Write( F, i, 0 ); + System::Write( F, ", \"" ); + System::Write( F, (*pClass).PropertyName[i] ); + System::Write( F, "\", \"" ); + System::Write( F, ReplaceCRLF( (*pClass).PropertyHelp[i] ) ); + System::WriteLn( F, '\"' ); + } + pClass = (TDSSClass*) DSSClassList[ActiveActor].Get_Next(); + } + System::CloseFile( F ); + } + + //---------------------------------------------------------------------------- + + + + double NearestBasekV( double kV ) + + /*Find closest base voltage*/ + { + double result = 0.0; + double TestkV = 0.0; + int count = 0; + double Diff = 0.0, MinDiff = 0.0; + count = 0; + TestkV = ActiveCircuit[ActiveActor]->LegalVoltageBases[1 - 1]; + result = TestkV; + MinDiff = 1.0e50; // Big whompin number + while ( TestkV != 0.0 ) + { + Diff = Abs( 1.0 - kV / TestkV ); // Get Per unit difference + if ( Diff < MinDiff ) + { + MinDiff = Diff; + result = TestkV; + } + ++count; + if (count < ActiveCircuit[ActiveActor]->LegalVoltageBases.size()) + TestkV = ActiveCircuit[ActiveActor]->LegalVoltageBases[count]; + else + TestkV = 0; + } + return result; + } + + //---------------------------------------------------------------------------- + + + + bool SavePresentVoltages( ) + { + bool result = false; + TTypedFile< double > F; + int i = 0; + double dNumNodes = 0.0; + result = true; + try + { + System::AssignFile( F, GetOutputDirectory() + CircuitName_[ActiveActor] + "SavedVoltages.dbl" ); + System::Rewrite( F ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error opening/creating file to save voltages: " + (string) E.what(), 711 ); + result = false; + return result; + } + } + try + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor].Solution do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + dNumNodes = (*with0).NumNodes; + System::Write( F, &dNumNodes ); + for ( int stop = (*with0).NumNodes, i = 1; i <= stop; i++) + { + System::Write( F, &( with0->Solution->NodeV[i].re ) ); + System::Write( F, &( with0->Solution->NodeV[i].im ) ); + } + } + } + System::CloseFile( F ); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error writing file to save voltages: " + (string) E.what(), 712 ); + result = false; + } + } + return result; + } + + //---------------------------------------------------------------------------- + + + bool RetrieveSavedVoltages( ) + { + bool result = false; + TTypedFile< double > F; + int i = 0; + double dNumNodes = 0.0; + result = true; + try + { + System::AssignFile( F, GetOutputDirectory() + CircuitName_[ActiveActor] + "SavedVoltages.dbl" ); + System::Reset( F ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error opening file to retrieve saved voltages: " + (string) E.what(), 713 ); + result = false; + return result; + } + } + try + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor].Solution do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + Read( F, &dNumNodes ); + if ( (*with0).NumNodes == Round( dNumNodes ) ) + for ( int stop = (*with0).NumNodes, i = 1; i <= stop; i++) + { + Read( F, &( with0->Solution->NodeV[i].re ) ); Read( F, &( with0->Solution->NodeV[i].im ) ); + } + else + { + DoSimpleMsg( "Saved results do not match present circuit. Aborting.", 714 ); + result = false; + } + } + } + System::CloseFile( F ); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error reading file to retrieve saved voltages: " + (string) E.what(), 715 ); + result = false; + } + } + return result; + } + + //---------------------------------------------------------------------------- + + + + bool InitializeForHarmonics( int ActorID ) + + /*Intialize PCELEMENT base values for harmonics analysis*/ + { + bool result = false; + TPCElement* PCelem; + if // Zap voltage vector to disk + ( SavePresentVoltages() ) + /*# with ActiveCircuit[ActorID] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + // Go through all PC Elements + PCelem = (TPCElement*) with0->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( PCelem->Get_Enabled() ) + PCelem->InitHarmonics( ActorID ); // Virtual function + PCelem = (TPCElement*) with0->PCElements.Get_Next(); + } + result = true; + } + } /*With*/ + else + result = false; + return result; + } + + + //---------------------------------------------------------------------------- + + + + void CalcInitialMachineStates( ) + { + TPCElement* PCelem; + + // Do All PC Elements + + // If state variables not defined for a PC class, does nothing + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + PCelem = (TPCElement*) with0->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ( PCelem->Get_Enabled() ) + PCelem->InitStateVars( ActiveActor ); + PCelem = (TPCElement*) with0->PCElements.Get_Next(); + } + } + } + } + + //---------------------------------------------------------------------------- + + + + void InvalidateAllPCElements( ) + { + TPCElement* PCelem; + + // Invalidate All PC Elements; Any could be a machine + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + PCelem = (TPCElement*) with0->PCElements.Get_First(); + while ( PCelem != NULL ) + { + if ((*PCelem).Get_Enabled() ) + (*PCelem).Set_YprimInvalid(ActiveActor,true); + PCelem = (TPCElement*) with0->PCElements.Get_Next(); + } + } + } + } + + + double PresentTimeInSec( int ActorID ) + { + double result = 0.0; + /*# with ActiveCircuit[ActorID].Solution do */ + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.T + ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour * 3600.0; + return result; + } + + + //---------------------------------------------------------------------------- + + + + int DoResetFaults( ) + { + int result = 0; + TFaultObj* pFault; + result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + pFault = (TFaultObj*) with0->Faults.Get_First(); + while ( pFault != NULL ) + { + pFault->Reset(); + pFault = (TFaultObj*) with0->Faults.Get_Next(); + } + } + } /*End With*/ + return result; + } + + + //---------------------------------------------------------------------------- + + + + int DoResetControls( ) + { + int result = 0; + TControlElem* ControlDevice; + result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + ControlDevice = (TControlElem*) with0 -> DSSControls.Get_First(); + while ( ControlDevice != NULL ) + { + if ( ControlDevice->Get_Enabled() ) + ControlDevice->Reset( ActiveActor ); + ControlDevice = (TControlElem*) with0-> DSSControls.Get_Next(); + } + } + } /*End With*/ + return result; + } + + //---------------------------------------------------------------------------- + + + + int GetNodeNum( int NodeRef ) + { + int result = 0; + if ( NodeRef == 0 ) + result = 0; + else + result = ActiveCircuit[ActiveActor]->MapNodeToBus[(NodeRef) - 1].NodeNum; + return result; + } + + + //---------------------------------------------------------------------------- + + + + void RotatePhasorDeg( complex& Phasor, const double h, const double AngleDeg ) + + // rotate a phasor by an angle and harmonic + + { + Phasor = cmul( Phasor, pdegtocomplex( 1.0, h * AngleDeg ) ); + } + + + void RotatePhasorRad( complex& Phasor, const double h, const double AngleRad ) + + // rotate a phasor by an angle and harmonic + + { + Phasor = cmul( Phasor, pclx( 1.0, h * AngleRad ) ); + } + + //---------------------------------------------------------------------------- + + + double PFSign( const complex S ) + { + double result = 0.0; + if ( S.re * S.im < 0.0 ) + result = - 1.0; + else + result = 1.0; + return result; + } + + + void ConvertComplexArrayToPowerandPF( const pComplexArray Buffer, int n ) + + /*Creates continous PF function from 1 to 2 where 1-2 range is leading (opposite sign)*/ + { + double mag = 0.0, PF = 0.0; + int i = 0; + + /*Assume we get P + jQ*/ + for ( int stop = n, i = 1; i <= stop; i++) + { + mag = cabs( Buffer[i] ); + if ( mag > 0.0 ) + { + PF = double( PFSign( Buffer[i] ) ) * abs( Buffer[i].re ) / mag; + if ( PF < 0.0 ) + PF = 2.0 - Abs( PF ); + } + else + PF = 1.0; // for zero power + Buffer[i].im = PF; + } + } + + + + //---------------------------------------------------------------------------- + + + + void ConvertComplexArrayToPolar( const pComplexArray Buffer, int n ) + { + polar x; + int i = 0; + for ( int stop = n, i = 1; i <= stop; i++) + { + x = ctopolardeg( Buffer[i - 1] ); + /*# with Buffer^[i], x do */ + { + Buffer[i - 1].re = x.mag; + Buffer[i - 1].im = x.ang; + } + } + } + + //---------------------------------------------------------------------------- + + + + complex Residual( void* p, int Nph ) + // Assume p points to complex array + // compute residual of the number of phases specified and convert to polar + + { + complex result; + pComplexArray pc; + int i = 0; + pc = (pComplexArray) p; + result = CZero; + for ( int stop = Nph, i = 1; i <= stop; i++) + caccum( result, pc[i] ); + return result; + } + + //---------------------------------------------------------------------------- + + + + complex ResidualPolar( void* p, int Nph ) + // Assume p points to complex array + // compute residual of the number of phases specified and convert to polar + + { + complex result = CZero; + complex x = CZero; + x = Residual( p, Nph ); + result.re = cabs( x ); + result.im = cdang( x ); + return result; + } + + + double Sign( double x ) + { + double result = 0.0; + if ( x < 0.0 ) + result = - 1.0; + else + result = 1.0; + return result; + } + + + double PowerFactor( const complex S ) + { + double result = 0.0; + if ( ( S.re != 0.0 ) && ( S.im != 0.0 ) ) + result = double( Sign( S.re * S.im ) ) * Abs( S.re ) / cabs( S ); + else + result = 1.0; + return result; + } + + + double ConvertPFToPFRange2( const double Value ) + /*Convert PF from +/- 1 to 0..2 Where 1..2 is leading*/ + { + double result = 0.0; + if ( Value < 0.0 ) + result = 2.0 + Value; + else + result = Value; + return result; + } + + + double ConvertPFRange2ToPF( const double Value ) + { + double result = 0.0; + if ( Value > 1.0 ) + result = Value - 2.0; + else + result = Value; + return result; + } + + + void ClearEventLog( ) + { + try + { + /***** WriteDLLDebugFile(Format('ClearEventLog: EventStrings= %p', [@EventStrings])); */ + EventStrings[ActiveActor].clear(); + } + catch( exception & E ) + { + DoSimpleMsg( "Exception clearing event log: " + (string)E.what() + ", @EventStrings=" /* + to_string(EventStrings[ActiveActor] */, 7151); + } + } + + + void ClearErrorLog( ) + { + try + { + /***** WriteDLLDebugFile(Format('ClearEventLog: EventStrings= %p', [@EventStrings])); */ + ErrorStrings[ActiveActor].clear(); + } + catch( exception & E ) + { + DoSimpleMsg( "Exception clearing error log: " + (string) E.what() + ", @EventStrings=" /* + &EventStrings */, 71511 ); + } + } + + + void LogThisEvent( const String EventName, const int ActorID ) + { + /***** WriteDLLDebugFile(Format('LogThisEvent: EventStrings= %p', [@EventStrings])); */ + /*# with ActiveCircuit[ActorID].Solution do */ + auto with0 = ActiveCircuit[ActiveActor]; + EventStrings[ActorID].push_back( "Hour=" + to_string(with0->Solution->DynaVars.intHour) + + ", Sec=" + to_string(with0->Solution->DynaVars.T) + + ", Iteration=" + to_string(with0->Solution->Iteration) + + ", ControlIter=" + to_string(with0->Solution->ControlIteration) + + ", Event=" + EventName); + + // 'Time=' + TimeToStr(Time)+': '+EventName); + /***** ShowMessageForm(EventStrings); */ + } + + void AppendToEventLog( const String opdev, const String Action, const int ActorID ) + { + String S; + /***** WriteDLLDebugFile(Format('LogThisEvent: EventStrings= %p', [@EventStrings])); */ + /*# with ActiveCircuit[ActorID].Solution do */ + auto with0 = ActiveCircuit[ActiveActor]; + S = Format("Hour=%d, Sec=%-.5g, ControlIter=%d, Element=%s, Action=%s", with0->Solution->DynaVars.intHour, with0->Solution->DynaVars.T, with0->Solution->ControlIteration, opdev.c_str(), UpperCase(Action).c_str()); + EventStrings[ActorID].push_back( S ); + /***** ShowMessageForm(EventStrings); */ + } + + + void DumpComplexMatrix( Textfile& F, TcMatrix* AMatrix ) + { + int i = 0, j = 0; + try + { + if (AMatrix != NULL) + { + System::WriteLn( F, "!(Real part)" ); + /*# with AMatrix do */ + { + for ( int stop = AMatrix->get_Norder(), i = 1; i <= stop; i++) + { + System::Write(F, "! " ); + for ( int stop = i, j = 1; j <= stop; j++) + { + System::Write( F, Format( "%g ", AMatrix->GetElement( i, j ).re )); + } + WriteLn( F ); + } + System::WriteLn( F, "!(Imaginary part) = " ); + for ( int stop = AMatrix->get_Norder(), i = 1; i <= stop; i++) + { + System::Write( F, "! " ); + for ( int stop = i, j = 1; j <= stop; j++) + { + Write( F, Format( "%g ", AMatrix->GetElement( i, j ).im )); + } + WriteLn( F ); + } + } + } + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error in Dump Complex Matrix: " + (string) E.what() + " Write aborted.", 716 ); + } + } + } + + + bool AllTerminalsClosed( TDSSCktElement* ThisElement ) + // check all conductors of this element to see IF it is closed. + // Make sure at least one phase on each terminal is closed. + + { + bool result = false; + int i = 0, j = 0; + result = false; + for ( int stop = ThisElement->Get_NTerms(), i = 1; i <= stop; i++) + { + result = false; + ThisElement->Set_ActiveTerminal(i); + for ( int stop = ThisElement->Get_NPhases(), j = 1; j <= stop; j++) + if ( ThisElement->Get_ConductorClosed(j, ActiveActor) ) + { + result = true; + break; + } + if ( ! result ) + return result; // didn't find a closed phase on this terminal + } + return result; + } + + + bool WriteVsourceClassFile(TDSSClass &Dss_Class, bool IsCktElement) + { + bool result = false; + TTextRec F; + String ClassName; + result = true; + if (Dss_Class.Get_ElementCount() == 0) + return result; + try + { + ClassName = Dss_Class.get_myClass_name(); + Assign(F, ClassName + ".dss"); + Rewrite(F); + IOResultToException(); + SavedFileList[ActiveActor].push_back(ClassName + ".dss"); + Dss_Class.Get_First(); // Sets ActiveDSSObject + WriteActiveDSSObject(F, "Edit"); // Write Get_First() Vsource out as an Edit + while (Dss_Class.Get_Next() > 0) + { + // Skip Cktelements that have been checked before and written out by something else + if (((TDSSCktElement*)ActiveDSSObject[ActiveActor])->HasBeenSaved) + continue; + // Skip disabled circuit elements; write all general DSS objects + WriteActiveDSSObject(F, "New"); // sets HasBeenSaved := TRUE + } + CloseFile(F); + Dss_Class.Saved = true; + } + catch (exception& E) + { + DoSimpleMsg("WriteClassFile Error: " + (string)E.what(), 717); + result = false; + } + return true; + } + bool WriteClassFile(TDSSClass &Dss_Class, String Filename, bool IsCktElement) + { + bool result = false; + TTextRec F; + String ClassName; + bool IsEnabled; + result = true; + int Nrecords = 0; + if (Dss_Class.Get_ElementCount() == 0) + return result; + try + { + ClassName = Dss_Class.get_myClass_name(); + Assign(F, ClassName + ".dss"); + Rewrite(F); + IOResultToException(); + Dss_Class.Get_First(); // Sets ActiveDSSObject + do + { + // Skip Cktelements that have been checked before and written out by something else + if (IsCktElement && ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->HasBeenSaved) + { + continue; + } + IsEnabled = true; + + if (LowerCase(Dss_Class.Class_Name) == "loadshape") + { + IsEnabled = ((TLoadShapeObj*)ActiveDSSObject[ActiveActor])->Enabled; + } + + // Skip disabled circuit elements; write all general DSS objects + if (IsEnabled) + { + WriteActiveDSSObject(F, "New"); // sets HasBeenSaved := TRUE + Nrecords++; + } + } + while (Dss_Class.Get_Next() > 0); + CloseFile(F); + Dss_Class.Saved = true; + if (Nrecords > 0) + { + SavedFileList[ActiveActor].push_back(ClassName + ".dss"); + } + else + { +#ifdef WIN32 + Assign(F, ClassName + ".dss"); + Erase(F); + IOResultToException(); +#endif + } + } + catch (exception& E) + { + DoSimpleMsg("WriteClassFile Error: " + (string)E.what(), 717); + result = false; + } + return true; + } + + + String CheckForBlanks( const String &S ) + /*Checks for blanks in the name and puts quotes around it*/ + { + String result = S; + if ( S.find( " " ) != String::npos) + if ( S[0] != '(' ) // Ignore if already quoted + if ( S[0] != '[' ) // Ignore if already quoted + if ( S[0] != '{' ) // Ignore if already quoted + result = String( "\"" ) + S + "\""; + return result; + } + + + void WriteActiveDSSObject( Textfile& F, const String NeworEdit ) + { + TDSSClass &ParClass = *((TDSSCktElement*)ActiveDSSObject[ActiveActor])->ParentClass; + //Write(F, NeworEdit, ' "', ParClass.Name + '.' + ActiveDSSObject[ActiveActor].Name,'"'); + System::Write(F, NeworEdit + " " + ParClass.get_myClass_name() + "." + ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->get_Name()); + ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->SaveWrite( F ); + + + + // Handle disabled circuit elements; Modified to allow applets to save disabled elements 12-28-06 + if ( ( (((TDSSCktElement*)ActiveDSSObject[ActiveActor])->DSSObjType & CLASSMASK ) ) != DSS_OBJECT ) + if ( !((TDSSCktElement*)ActiveDSSObject[ActiveActor])->Get_Enabled() ) + { + System::Write( F, " ENABLED=NO" ); + } + WriteLn( F ); // Terminate line + ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->HasBeenSaved = true; + } + + + void DoResetKeepList( ) + { + int i = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + with0->Buses[(i) - 1]->Keep = false; + } + } + + + String ExtractComment( const String S ) + { + String result; + result = S.substr( S.find( "!" ), S.size() ); + return result; + } + + + bool RewriteAlignedFile( const String Filename ) + { + bool result = false; + TTextRec Fin, Fout; + String SaveDelims, Line, Field, AlignedFile; + pIntegerArray FieldLength; + int ArraySize = 0, FieldLen = 0, FieldNum = 0; + result = true; + try + { + AssignFile( Fin, Filename ); + Reset( Fin ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error opening file: " + Filename + ", " + (string) E.what(), 719 ); + result = false; + return result; + } + } + try + { + AlignedFile = ExtractFilePath( Filename ) + "Aligned_" + ExtractFileName( Filename ); + AssignFile( Fout, AlignedFile ); + Rewrite( Fout ); + IOResultToException(); + } + catch( exception & E ) + { + { + DoSimpleMsg( "Error opening file: " + AlignedFile + ", " + (string) E.what(), 720 ); + CloseFile( Fin ); + result = false; + return result; + } + } + SaveDelims = AuxParser[ActiveActor]->get_delimchars(); + AuxParser[ActiveActor]->set_delimchars(", "); + ArraySize = 10; + FieldLength = new longInt[ ArraySize ]; + try + { + /*Scan once to set field lengths*/ + while (!Eof(Fin)) + { + ReadLn(Fin, Line); + AuxParser[ActiveActor]->SetCmdString(Line); // Load the parsr + FieldNum = 0; + do + { + String dummy = AuxParser[ActiveActor]->GetNextParam(); + Field = AuxParser[ActiveActor]->MakeString_(); + FieldLen = Field.length(); + if (Field.find(" ") != String::npos) + FieldLen = FieldLen + 2; + if (FieldLen > 0) + { + FieldNum++; + if (FieldNum > ArraySize) + { + ArraySize = FieldNum; + FieldLength = (pIntegerArray)realloc(FieldLength, sizeof(FieldLength[0]) * ArraySize); + FieldLength[FieldNum] = FieldLen; + } + else + if (FieldLen > FieldLength[FieldNum]) + FieldLength[FieldNum] = FieldLen; + } + } while (!(FieldLen == 0)); + } + + /*Now go back and re-read while writing the new file*/ + Reset(Fin); + IOResultToException(); + while (!Eof(Fin)) + { + ReadLn(Fin, Line); + AuxParser[ActiveActor]->SetCmdString(Line); // Load the parser + FieldNum = 0; + do + { + String dummy = AuxParser[ActiveActor]->GetNextParam(); + Field = AuxParser[ActiveActor]->MakeString_(); + if (Field.find(" ") != String::npos) + Field = String("\"") + Field + "\""; // add quotes if a space in field + FieldLen = Field.length(); + if (FieldLen > 0) + { + FieldNum++; + Write(Fout, Pad(Field, FieldLength[FieldNum] + 1)); + } + } while (!(FieldLen == 0)); + if (Line.find("!") != String::npos) + Write(Fout, ExtractComment(Line)); + WriteLn(Fout); + } + // } + // __finally + // { + /*Make sure we do this stuff ...*/ + CloseFile( Fin ); + CloseFile( Fout ); + free(FieldLength); + AuxParser[ActiveActor]->set_delimchars(SaveDelims); + } + catch (std::exception &E) + { + // added to facilitate implementation in C++ native statements + // It does nothing though + } + GlobalResult = AlignedFile; + return result; + } + + int DoExecutiveCommand( const String S ) + { + int result = 0; + DSSExecutive[ActiveActor]->Set_Command(S); + result = DSSExecutive[ActiveActor]->Get_ErrorResult(); + return result; + } + + + bool CheckParallel( const TDSSCktElement* Line1, const TDSSCktElement* Line2 ) + /*Check to see if two lines are in parallel*/ + { + bool result = false; + result = false; + if ( Line1->Terminals[0].BusRef == Line2->Terminals[0].BusRef ) + if ( Line1->Terminals[1].BusRef == Line2->Terminals[1].BusRef ) + { + result = true; + return result; + } + if ( Line1->Terminals[1].BusRef == Line2->Terminals[0].BusRef ) + if ( Line1->Terminals[0].BusRef == Line2->Terminals[1].BusRef ) + { + result = true; + return result; + } + return result; + } + + + double GetMaxPUVoltage( ) + { + double result = 0.0; + int i = 0, j = 0, Nref = 0; + result = - 1.0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + { + if ((with0->Buses[i - 1 ]->kVBase) > 0.0 ) + { + for ( int stop = with0->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + Nref = with0->Buses[i - 1]->GetRef( j ); + if ( Nref > 0 ) + result = max( result, double( cabs(with0->Solution->NodeV[Nref] ) ) / (with0->Buses[i - 1]->kVBase) ); + } + } + } + result = result * 0.001; + } + } + return result; + } + + + double GetMinPUVoltage( bool IgnoreNeutrals ) + { + double result = 0.0; + int i = 0, j = 0, Nref = 0; + bool MinFound = false; + double Vmagpu = 0.0; + result = 1.0e50; // start with big number + MinFound = false; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = with0->NumBuses, i = 1; i <= stop; i++) + /*# with Buses^[i] do */ + { + auto with1 = with0->Buses[i - 1]; + if ( with1->kVBase > 0.0 ) + { + for ( int stop = with1->get_FNumNodesThisBus(), j = 1; j <= stop; j++) + { + Nref = with1->GetRef( j ); + if ( Nref > 0 ) + { + Vmagpu = double( cabs( with0->Solution->NodeV[Nref] ) ) / with1->kVBase; + if ( IgnoreNeutrals ) + { + if ( Vmagpu > 100.0 ) + { // 0.1 pu + result = min( result, Vmagpu ); // only check buses greater than 10% + MinFound = true; + } + } + else + { + result = min( result, Vmagpu ); + MinFound = true; + } + } + } + } + } + result = result * 0.001; + } + } + if ( ! MinFound ) + result = - 1.0; + return result; + } + + + complex GetTotalPowerFromSources( int ActorID ) + { + complex result; + TDSSCktElement* cktElem; + result = CZero; + cktElem = (TDSSCktElement*) ActiveCircuit[ActorID]->Sources.Get_First(); + while ( cktElem != NULL ) + { + //----CktElem.ActiveTerminalIdx := 1; + caccum( result, cnegate( cktElem->Get_Power(1, ActorID) ) ); + cktElem = (TDSSCktElement*) ActiveCircuit[ActorID]->Sources.Get_Next(); + } + return result; + } + + + void WriteUniformGenerators( Textfile& F, double kW, double PF, bool DoGenerators ) + /* Distribute the generators uniformly amongst the feeder nodes that have loads*/ + { + double kWeach = 0.0; + TDSSClass LoadClass; + TLoadObj* pLoad; + int count = 0, i = 0; + LoadClass = * ( (TDSSClass*) GetDSSClassPtr( "load" ) ); + count = LoadClass.ElementList.get_myNumList(); + kWeach = kW / max( 1, count ); + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + kWeach = kWeach / 3.0; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = (TLoadObj*) LoadClass.ElementList.Get( i ) ; + if ( ( (TDSSCktElement*) pLoad )->Get_Enabled() ) + { + if ( DoGenerators ) + { + System::Write( F, "new generator.DG_" + to_string(i) + "bus1=" + pLoad->GetBus( 1 )); + } + else + { + System::Write( F, "new load.DL_" + to_string(i) + " bus1=" + pLoad->GetBus( 1 )); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor];; + { + System::Write( F, Format( " phases=%d kV=%-g", pLoad->Get_NPhases(), pLoad->kVLoadBase )); + System::Write( F, Format( " kW=%-g", kWeach )); + System::Write( F, Format( " PF=%-.3g", PF )); + } + } + System::Write( F, " model=1" ); + System::WriteLn( F ); + } + } + } + + void WriteRandomGenerators( Textfile& F, double kW, double PF, bool DoGenerators ) + /*Distribute Generators randomly to loaded buses*/ + { + double kWeach = 0.0; + TDSSClass LoadClass; + TLoadObj* pLoad; + int count = 0, i = 0, LoadCount = 0; + LoadClass = *( (TDSSClass*) GetDSSClassPtr( "load" ) ); + count = LoadClass.ElementList.get_myNumList(); + /*Count enabled loads*/ + LoadCount = 0; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = (TLoadObj*) LoadClass.ElementList.Get( i ); + if (((TDSSCktElement*)pLoad)->Get_Enabled() ) + LoadCount++; + } + kWeach = kW / LoadCount; // median sized generator + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + kWeach = kWeach / 3.0; + //Randomize; // pending to verify if such function has an eq in C++ + + /*Place random sizes on load buses so that total is approximately what was spec'd*/ + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = (TLoadObj*) LoadClass.ElementList.Get( i ) ; + if (((TDSSCktElement*)pLoad)->Get_Enabled() ) + { + if ( DoGenerators ) + { + System::Write( F, "new generator.DG_" + to_string(i) + " bus1=" + (pLoad)->GetBus( 1 )); + } + else + { + System::Write( F, "new load.DL_" + to_string(i) + " bus1=" + (pLoad)->GetBus( 1 )); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + System::Write( F, Format( " phases=%d kV=%-g", pLoad->Get_NPhases(), pLoad->kVLoadBase )); + System::Write( F, Format(" kW=%-g", kWeach * rand() * 2.0)); + System::Write( Format( " PF=%-.3g", PF )); + } + } + System::Write( " model=1" ); + System::WriteLn( F ); + } + } + } + + + void WriteEveryOtherGenerators( Textfile& F, double kW, double PF, int Skip, bool DoGenerators ) + + /*distribute generators on every other load, skipping the number specified*/ + + /*Distribute the generator Proportional to load*/ + { + double kWeach = 0.0, TotalkW = 0.0; + TDSSClass LoadClass; + TLoadObj* pLoad; + int count = 0, i = 0, skipcount = 0; + LoadClass = *( (TDSSClass*) GetDSSClassPtr( "load" ) ); + count = LoadClass.ElementList.get_myNumList(); + /*Add up the rated load in the enabled loads where gens will be placed*/ + TotalkW = 0.0; + skipcount = Skip; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = (TLoadObj*) LoadClass.ElementList.Get( i ) ; + if (((TDSSCktElement*)pLoad)->Get_Enabled() ) + { + /*Do not count skipped loads*/ + if ( skipcount == 0 ) + { + TotalkW = TotalkW + pLoad->kWBase; // will be right value if pos seq, too + skipcount = Skip; // start counter over again + } + else + skipcount--; + } + } + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + kWeach = kW / TotalkW / 3.0; + else + kWeach = kW / TotalkW; + skipcount = Skip; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = (TLoadObj*) LoadClass.ElementList.Get( i ) ; + if (((TDSSCktElement*)pLoad)->Get_Enabled() ) + { + if ( skipcount == 0 ) + { + if ( DoGenerators ) + { + System::Write( F, "new generator.DG_" + to_string(i) + " bus1=" + (pLoad)->GetBus( 1 )); + } + else + { + System::Write( F, "new load.DL_" + to_string(i) + " bus1=" + (pLoad)->GetBus( 1 )); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + System::Write( F, Format( " phases=%d kV=%-g", (pLoad)->Get_NPhases(), pLoad->kVLoadBase )); + System::Write( F, Format( " kW=%-g ", kWeach * pLoad->kWBase )); + System::Write( F, Format( " PF=%-.3g", PF )); + } + } + System::Write( F, " model=1" ); + WriteLn( F ); + skipcount = Skip; + } + else + skipcount--; + } + } + } + + + void WriteProportionalGenerators( Textfile& F, double kW, double PF, bool DoGenerators ) + /*Distribute the generator Proportional to load*/ + { + double kWeach = 0.0, TotalkW = 0.0; + TDSSClass LoadClass; + TLoadObj pLoad; + int count = 0, i = 0; + LoadClass = *( (TDSSClass*) GetDSSClassPtr( "load" ) ); + count = LoadClass.ElementList.get_myNumList(); + /*Add up the rated load in the enabled loads*/ + TotalkW = 0.0; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = *(TLoadObj*) LoadClass.ElementList.Get( i ); // showing other way to do it, just to make it fun :) + if (((TDSSCktElement*) &pLoad)->Get_Enabled() ) + { + TotalkW = TotalkW + pLoad.kWBase; // will be right value if pos seq, too + } + } + if ( ActiveCircuit[ActiveActor]->PositiveSequence ) + kWeach = kW / TotalkW / 3.0; + else + kWeach = kW / TotalkW; + for ( int stop = count, i = 1; i <= stop; i++) + { + pLoad = *(TLoadObj*)LoadClass.ElementList.Get( i ) ; + if (((TDSSCktElement*) &pLoad)->Get_Enabled() ) + { + if ( DoGenerators ) + { + System::Write( F, "new generator.DG_" + to_string(i) + " bus1=" + (pLoad).GetBus( 1 )); + } + else + { + System::Write( F, "new load.DL_" + to_string(i) + " bus1=" + pLoad.GetBus( 1 )); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + System::Write( F, Format( " phases=%d kV=%-g", pLoad.Get_NPhases(), pLoad.kVLoadBase )); + System::Write( F, Format( " kW=%-g", kWeach * pLoad.kWBase )); + System::Write( F, Format( " PF=%-.3g", PF )); + } + } + System::Write( F, " model=1" ); + System::WriteLn( F ); + } + } + } + + + void MakeDistributedGenerators( double kW, double PF, String How, int Skip, String Fname, bool DoGenerators ) + { + TTextRec F; + String WhatStr; + /*Write outputfile and then redirect command parser to it.*/ + try + { + if ( FileExists( Fname ) ) + DoSimpleMsg( String( "File \"" ) + Fname + "\" is about to be overwritten. Rename it now before continuing if you wish to keep it.", 721 ); + AssignFile( F, Fname ); + Rewrite( F ); + IOResultToException(); + } + catch( exception &E ) + { + { + DoSimpleMsg( String( "Error opening \"" ) + Fname + "\" for writing. Aborting.", 722 ); + return; + } + } + try + { + if ( DoGenerators ) + WhatStr = "Generators"; + else + WhatStr = "Loads"; + System::WriteLn( F, "! Created with Distribute Command:" ); + System::WriteLn( F, "! Distribute kW=" + to_string(kW) + + " PF=" + to_string(PF) + + " How=" + How + + " Skip=" + to_string(Skip) + + " file=" + Fname + " what=" + WhatStr); + System::WriteLn( F ); + // Writeln(F, 'Set allowduplicates=yes'); + if ( How.size() == 0 ) + How = "P"; + switch ( UpperCase( How )[0] ) + { + case 'U': + WriteUniformGenerators( F, kW, PF, DoGenerators ); + break; + case 'R': + WriteRandomGenerators( F, kW, PF, DoGenerators ); + break; + case 'S': + WriteEveryOtherGenerators( F, kW, PF, Skip, DoGenerators ); + break; + default: + WriteProportionalGenerators( F, kW, PF, DoGenerators ); + } + GlobalResult = Fname; + // } + // __finally + // { + // Writeln(F, 'Set allowduplicates=no'); + CloseFile( F ); + SetLastResultFile( Fname ); + } + catch (exception &E) + { + //Inserted to facilitate adoption under native C + } + } + + /*Feeder Utilities*/ + + + void EnableFeeders( ) + { + TEnergyMeterObj* pMeter; + + // Let EnergyMeter Objects control re-enabling of Feeders + // Feeder could have been dumped in meantime by setting Feeder=False in EnergyMeter + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + pMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_First(); + while ( pMeter != NULL ) + { + pMeter->EnableFeeder(); // also sets CktElement feeder flags true if a valid feeder + pMeter = (TEnergyMeterObj * )with0->EnergyMeters.Get_Next(); + } + } + } + } + + + void DisableFeeders( ) + { + TFeederObj* pFeeder; + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + pFeeder = (TFeederObj*)with0->Feeders.Get_First(); + while ( pFeeder != NULL ) + { + pFeeder->Set_Enabled(false); + pFeeder->SetCktElementFeederFlags( false ); + pFeeder = (TFeederObj*)with0->Feeders.Get_Next(); + } + } + } + } + + + void InitializeFeeders( ) + // Var i:Integer; + + { + /* Do Nothing for now + With ActiveCircuit[ActiveActor] Do + For i := 1 to Feeders.get_myNumList() Do Begin + If Not SolutionAbort Then TFeederObj(Feeders.Get(i)).InitForSweep; + End; + */ + } + + + void ForwardSweepAllFeeders( ) + // Var i:Integer; + + { + /* Do Nothing for now + With ActiveCircuit[ActiveActor] Do + For i := 1 to Feeders.get_myNumList() Do Begin + If Not SolutionAbort Then TFeederObj(Feeders.Get(i)).ForwardSweep; + End; + */ + } + + + void BackwardSweepAllFeeders( ) + // Var i:Integer; + + { + /* Do Nothing for now + With ActiveCircuit[ActiveActor] Do + For i := 1 to Feeders.get_myNumList() Do Begin + If Not SolutionAbort Then TFeederObj(Feeders.Get(i)).BackwardSweep; + End; + */ + } + + + String GetDSSArray_Real( int n, pDoubleArray dbls ) + { + String result; + int i = 0; + result = "["; + for ( int stop = n, i = 1; i <= stop; i++) + result = result + Format(" %-.6g", dbls[i - 1] ); + result = result + "]"; + return result; + } + + + String GetDSSArray_Integer( int n, pIntegerArray ints ) + { + String result; + int i = 0; + result = "["; + for ( int stop = n, i = 1; i <= stop; i++) + result = result + Format( " %-.d", ints[i - 1] ); + result = result + "]"; + return result; + } + + + complex CmulReal_im( const complex A, const double Mult ) // Multiply only imaginary part by a real + + { + complex result; + result = cmplx( A.re, A.im * Mult ); + return result; + } + + + void CmulArray( pComplexArray pc, double Multiplier, int Size ) // Multiply a complex array times a double + + { + int i = 0; + for ( int stop = Size, i = 1; i <= stop; i++) + pc[i] = cmulreal( pc[i], Multiplier ); + } + + + longInt GetMaxCktElementSize( ) + { + longInt result = 0; + int i = 0; + result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + for ( int stop = with0->NumDevices, i = 1; i <= stop; i++) + result = max( result, ((TDSSCktElement*)with0->CktElements.Get( i ))->Yorder ); + } + return result; + } + + /* + FUNCTION IsValidNumericField(const NumberField:TEdit):Boolean; + + Var + Code :Integer; + Value :Double; + + Begin + Result := TRUE; + Val(NumberField.Text, Value, Code); + If Code>0 Then Begin + Beep; + NumberField.SetFocus; + Result := FALSE; + End; + End; + */ + + + int GetUniqueNodeNumber( const String sBusName, int StartNode ) + /*To help avoid collisions of neutral numbers, this function returns a node number that is not being used, + Starting at the StartNode value*/ + { + int result = 0; + int iBusidx = 0; + result = StartNode; + iBusidx = ActiveCircuit[ActiveActor]->BusList.Find( sBusName ); + if ( iBusidx > 0 ) + while ( ActiveCircuit[ActiveActor]->Buses[(iBusidx) - 1]->FindIdx( result ) != 0 ) + result++; + ActiveCircuit[ActiveActor]->Buses[(iBusidx) - 1]->Add( result, ActiveActor ); // add it to the list so next call will be unique + return result; + } + + void ShowMessageBeep( const String S ) + { + cout << '\a'; // equivalent to beep in C++ +// DSSInfoMessageDlg( S ); + } + + + bool IsPathBetween( TPDElement* FromLine, TPDElement* ToLine ) + { + bool result = false; + TPDElement* PDElem; + PDElem = FromLine; + result = false; + while ( PDElem != NULL ) + { + if ( PDElem == ToLine ) + { + result = true; + return result; + } + PDElem = PDElem->ParentPDElement; + } + return result; + } + + + void TraceAndEdit( TPDElement* FromLine, TPDElement* ToLine, int NPhases, String EditStr ) + /*Trace back up a tree and execute an edit command string*/ + { + TPDElement* pLine; + pLine = FromLine; + while ( pLine != NULL ) + { + if ( ( pLine->Get_NPhases() == NPhases ) || ( NPhases == 0 ) ) + { + Parser[ActiveActor]->SetCmdString(EditStr); + pLine->Edit( ActiveActor ); // Uses Parser + } + if ( pLine == ToLine ) + break; + pLine = pLine->ParentPDElement; + } + } + + + void GoForwardAndRephase( TPDElement* FromLine, const String PhaseString, const String EditStr, const String ScriptFileName, bool TransStop ) + /*Trace forward down a tree and Generate a script file to change the phase*/ + { + TPDElement* pPDelem; + TDSSCktElement* pShuntObject; + TEnergyMeterObj* pMeter; + int i = 0; + String S; + TTextRec Fout; + String Filename; + int XfmrLevel = 0; + pMeter = (TEnergyMeterObj*)FromLine->MeterObj; + + /*Search for starting line in branchlist*/ + pPDelem = (TPDElement*) pMeter->BranchList->Get_First(); + while ( pPDelem != NULL ) + { + if ( FromLine == pPDelem ) + { + break; + } + pPDelem = (TPDElement*) pMeter->BranchList->Get_Forward(); + } + + /*Error check*/ + if ( pPDelem == NULL ) + { + DoSimpleMsg( FromLine->ParentClass->get_myClass_name() + "." + FromLine->get_Name() + " Not found in Meter Zone.", 723 ); + return; + } + try + { + Filename = GetOutputDirectory() + CircuitName_[ActiveActor] + ScriptFileName; + GlobalResult = Filename; + System::AssignFile( Fout, Filename ); + System::Rewrite( Fout ); + IOResultToException(); + pMeter->BranchList->StartHere(); + pPDelem = (TPDElement *) pMeter->BranchList->Get_Forward(); + while ( pPDelem != NULL ) + { + S = "edit " + pPDelem->ParentClass->get_myClass_name() + "." + pPDelem->get_Name(); + + /*----------------LINES---------------------------------------------------*/ + if ( IslineElement( pPDelem ) ) + { + for ( int stop = pPDelem->Get_NTerms(), i = 1; i <= stop; i++) + { + S = S + " Bus" + to_string(i) + "=" + StripExtension(pPDelem->GetBus(i)) + PhaseString; + // Parser.CmdString := Format('Bus$d=%s%s',[i, StripExtension(pPDelem.GetBus(i)), PhaseString]); + // pPDelem.Edit; + } + + /*When we're done with that, we'll send the Edit string*/ + if ( EditStr.size() > 0 ) + { + S = S + " " + EditStr; + // Parser.CmdString := EditStr; + // pPDelem.Edit; // Uses Parser + } + WriteLn( Fout, S ); + + /*Now get all shunt objects connected to this branch*/ + pShuntObject = (TDSSCktElement *) pMeter->BranchList->Get_FirstObject(); + while ( pShuntObject != NULL ) + { + /*1st Terminal Only*/ + i = 1; + S = "edit " + pShuntObject->ParentClass->get_myClass_name() + "." + pShuntObject->get_Name(); + S = S + " Bus" + to_string(i) + "=" + StripExtension(pShuntObject->GetBus(i)) + PhaseString; + if ( EditStr.size() > 0 ) + S = S + " " + EditStr; + WriteLn( Fout, S ); + // Parser.CmdString := Format('Bus$d=%s%s',[i, StripExtension(pShuntObject.GetBus(1)), PhaseString]); + // pShuntObject.Edit; + pShuntObject = (TPDElement*) pMeter->BranchList->Get_NextObject(); + } + pPDelem = (TPDElement*) pMeter->BranchList->Get_Forward(); + } /*IsLine*/ + + /*----------------TRANSFORMERS---------------------------------------------------*/ + else + if ( IsTransformerElement( pPDelem ) ) + { + + /* + We'll stop at transformers and change only the primary winding. + Then we'll cycle forward until the lexical level is less or we're done + */ + XfmrLevel = pMeter->BranchList->Get_Level(); + S = S + " wdg=1 Bus=" + StripExtension(pPDelem->GetBus(1)) + PhaseString + EditStr; + if ( ! TransStop ) + S = S + " wdg=2 Bus=" + StripExtension(pPDelem->GetBus(2)) + PhaseString + EditStr; + WriteLn( Fout, S ); + + /*Be default Go forward in the tree until we bounce back up to a line section above the transformer*/ + if ( TransStop ) + { + do + { + pPDelem = (TPDElement *) pMeter->BranchList->Get_Forward(); + } + while ( ! ( ( pPDelem == NULL ) || ( pMeter->BranchList->Get_Level() <= XfmrLevel ) ) ); + } + else + pPDelem = (TPDElement*)pMeter->BranchList->Get_Forward(); /*Then we get lines and loads beyond transformer*/ + } + } + // } + // __finally + // { + CloseFile( Fout ); + FireOffEditor( Filename ); + } + catch (std::exception &E) + { + // added for compatibility with native C + } + } + + double MaxdblArrayValue( int npts, pDoubleArray dbls ) + // returns max value of an array of doubles + + { + double result = 0.0; + int i = 0; + result = 0.0; + if ( npts == 0 ) + return result; + result = dbls[1]; + for ( int stop = npts, i = 2; i <= stop; i++) + result = max( result, dbls[i] ); + return result; + } + + + int iMaxAbsdblArrayValue( int npts, pDoubleArray dbls ) + // Returns index of max array value in abs value + + { + int result = 0; + int i = 0; + double MaxValue = 0.0; + result = 0; + if ( npts == 0 ) + return result; + result = 1; + MaxValue = Abs( (dbls)[0] ); + for ( int stop = npts, i = 2; i <= stop; i++) + if ( Abs( (dbls)[i - 1] ) > MaxValue ) + { + MaxValue = Abs( (dbls)[i - 1] ); + result = i; // save index + } + return result; + } + + + int InterpretLoadShapeClass( const String S ) + { + int result = 0; + String ss; + ss = ToLowerCaseStr( S ); + result = USENONE; + switch ( ss[0] ) + { + case 'd': + switch ( ss[1] ) + { + case 'a': + result = USEDAILY; + break; + case 'u': + result = USEDUTY; + break; + } + break; + case 'y': + result = USEYEARLY; + break; + case 'n': + result = USENONE; + break; + } + return result; + } + + + int InterpretEarthModel( const String S ) + { + int result = 0; + String ss; + ss = ToLowerCaseStr( S ); + result = SIMPLECARSON; + switch ( ss[0] ) + { + case 'c': + result = SIMPLECARSON; + break; + case 'f': + result = FULLCARSON; + break; + case 'd': + result = DERI; + break; + } + return result; + } + + + String GetActiveLoadShapeClass( ) + { + String result; + switch ( ActiveCircuit[ActiveActor]->ActiveLoadShapeClass ) + { + case USEDAILY: + result = "Daily"; + break; + case USEYEARLY: + result = "Yearly"; + break; + case USEDUTY: + result = "Duty"; + break; + case USENONE: + result = "None"; + break; + } + return result; + } + + + String GetEarthModel( int n ) + { + String result; + switch ( n ) + { + case SIMPLECARSON: + result = "Carson"; + break; + case FULLCARSON: + result = "FullCarson"; + break; + case DERI: + result = "Deri"; + break; + } + return result; + } + + + int InterpretColorName( const String S ) + { + if (CompareTextShortest(S, "black") == 0) + return clBlack; + + if (CompareTextShortest(S, "Maroon") == 0) + return clMaroon; + + if (CompareTextShortest(S, "Green") == 0) + return clGreen; + + if (CompareTextShortest(S, "Olive") == 0) + return clOlive; + + if (CompareTextShortest(S, "Navy") == 0) + return clNavy; + + if (CompareTextShortest(S, "Purple") == 0) + return clPurple; + + if (CompareTextShortest(S, "Teal") == 0) + return clTeal; + + if (CompareTextShortest(S, "Gray") == 0) + return clGray; + + if (CompareTextShortest(S, "Silver") == 0) + return clSilver; + + if (CompareTextShortest(S, "Red") == 0) + return clRed; + + if (CompareTextShortest(S, "Lime") == 0) + return clLime; + + if (CompareTextShortest(S, "Yellow") == 0) + return clYellow; + + if (CompareTextShortest(S, "Blue") == 0) + return clBlue; + + if (CompareTextShortest(S, "Fuchsia") == 0) + return clFuchsia; + + if (CompareTextShortest(S, "Aqua") == 0) + return clAqua; + + if (CompareTextShortest(S, "LtGray") == 0) + return clLtGray; + + if (CompareTextShortest(S, "DkGray") == 0) + return clDkGray; + + if (CompareTextShortest(S, "White") == 0) + return clWhite; + + if (S.size() && S[0] == '$') + { + return stoi(S.substr(1), nullptr, 16); + } + return StrToInt(S); + } + + String MakeNewCktElemName( const String oldname ) + { + String result; + SetObject( oldname ); // set opject active + /*# with ActiveDSSObject[ActiveActor] do */ + { + auto with0 = (TDSSObject*) ActiveDSSObject[ActiveActor];/* + result = Format( "%s.%s%d", with0->ParentClass->get_Name(), copy( 1, 4 , with0->ParentClass->get_Name()), with0->ClassIndex )) );*/ + } + return result; + } + + + String ConstructElemName( const String Param ) + /*Construct an element name, sustituting @var values if any*/ + { + String result; + String FClassName, FObjName; + ParseObjectClassandName( ToLowerCaseStr( Param ), FClassName, FObjName ); // insert @var test + result = FClassName + "." + FObjName; + return result; + } + + + void RenameCktElem( TDSSCktElement pElem ) // local proc + + { + /*# with pElem do */ + { + pElem.Set_Name(pElem.ParentClass->get_myClass_name().substr(0,4) + Format("%d", pElem.ClassIndex)); + ActiveCircuit[ActiveActor]->DeviceList.Add(pElem.get_Name() ); // Make a new device list corresponding to the CktElements List + + + /*-------------------------------------------------------------*/ + + /*Make sure buslist exists*/ + pElem.Checked = true; + } + } + + + void Obfuscate( ) + /*Rename Buses and element names to generic names to remove identifiable names*/ + { + int i = 0, bref = 0; + size_t dotpos = 0; + int DevListSize = 0; + THashList TempBusList; + TDSSCktElement* pCktElem; + TDSSCktElement* pctrlelem; + String S, Nodes; + String OldBusName; + String NewBusName; + int Baseclass = 0; + int ElemClass = 0; + TStringList ControlUpDateStrings; + list ControlUpDatePtrs; + + /*-------------------------------------------------------------*/ + if ( ActiveCircuit[ActiveActor] == NULL ) + return; + if ( ActiveCircuit[ActiveActor]->BusList.Get_NumElements() <= 0 ) + return; + /*# with ActiveCircuit[ActiveActor] do */ + { + Circuit::TDSSCircuit* with0 = ActiveCircuit[ActiveActor]; + { + TempBusList = THashList(with0->BusList.Get_NumElements() ); + + /*Rename Buses*/ + for ( int stop = with0->BusList.Get_NumElements(), i = 1; i <= stop; i++) + TempBusList.Add( Format( "B_%d", i )); + with0->BusList.Clear(); + with0->BusList = TempBusList; // Reassign + + /*Rename the bus names in each circuit element before renaming the elements*/ + pCktElem = (TDSSCktElement*)with0->CktElements.Get_First(); + while ( pCktElem != NULL ) + { + Baseclass = (pCktElem->DSSObjType && BaseClassMask); + if ( ( Baseclass == PC_ELEMENT ) || ( Baseclass == PD_ELEMENT ) ) + { + S = ""; + for ( int stop = pCktElem->Get_NTerms(), i = 1; i <= stop; i++) + { + OldBusName = pCktElem->GetBus( i ); + dotpos = OldBusName.find( "." ); + if ( dotpos == String::npos ) + Nodes = ""; + else + Nodes = OldBusName.substr( dotpos, OldBusName.size() ); // preserve node designations if any + bref = pCktElem->Terminals[i - 1].BusRef; + NewBusName = "B_" + to_string(bref) + Nodes; + //Check for Transformer because that will be an exception + switch ( pCktElem->DSSObjType & CLASSMASK ) + { + case XFMR_ELEMENT: + S = S + "Wdg=" + to_string(i) + " Bus=" + NewBusName; + break; + default: + S = S + "Bus" + to_string(i) + "=" +NewBusName; + } + } + Parser[ActiveActor]->SetCmdString(S); + pCktElem->Edit( ActiveActor ); + } + pCktElem = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + + /*Rename the circuit elements to generic values*/ + /*Have to catch the control elements and edit some of their parameters*/ + + /*first, make scripts to change the monitored element names in the controls to what they will be*/ + ControlUpDateStrings = TStringList(); + // ControlUpDatePtrs = list(); + pCktElem = (TDSSCktElement*)with0->CktElements.Get_First(); + while ( pCktElem != NULL ) + { + switch ( pCktElem->DSSObjType & CLASSMASK ) + { + case CAP_CONTROL: + { + S = "Element=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 )); + ControlUpDateStrings.push_back( S + "Capacitor=" + MakeNewCktElemName( "capacitor." + pCktElem->GetPropertyValue( 3 ) ).substr( 10, 100 ) ); + ControlUpDatePtrs.push_back(pCktElem); + } + break; + case REG_CONTROL: + break; // handled below + + case RELAY_CONTROL: + { + S = "MonitoredObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 )); + ControlUpDateStrings.push_back( S + "SwitchedObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 3 ))); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + case RECLOSER_CONTROL: + { + S = "MonitoredObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 ) ); + ControlUpDateStrings.push_back( S + "SwitchedObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 3 ) )); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + case FUSE_CONTROL: + { + S = "MonitoredObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 ) ); + ControlUpDateStrings.push_back( S + "SwitchedObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 3 ) ) ); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + case GEN_CONTROL: + { + ControlUpDateStrings.push_back( "Element=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 ) ) ); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + case STORAGE_CONTROL: + { + ControlUpDateStrings.push_back( "Element=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 ) ) ); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + case SWT_CONTROL: + { + ControlUpDateStrings.push_back( "SwitchedObj=" + MakeNewCktElemName( pCktElem->GetPropertyValue( 1 ) ) ); + ControlUpDatePtrs.push_back( pCktElem ); + } + break; + } + pCktElem = (TDSSCktElement*) with0->CktElements.Get_Next(); + } + pCktElem = (TDSSCktElement*)with0->CktElements.Get_First(); + while ( pCktElem != NULL ) + { + pCktElem -> Checked = false; // Initialize to not checked + pCktElem = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + DevListSize = with0 -> DeviceList.Get_NumElements(); + with0 -> DeviceList.Clear(); + with0 -> DeviceList = THashList( DevListSize ); + pCktElem = (TDSSCktElement*)with0 -> CktElements.Get_First(); + while ( pCktElem != NULL ) + { + if ( ! pCktElem->Checked ) + { + ElemClass = ( pCktElem->DSSObjType & CLASSMASK ); + RenameCktElem( *pCktElem ); + switch ( ElemClass ) + { + case XFMR_ELEMENT: + if ( pCktElem->HasControl ) + { + pctrlelem = (TDSSCktElement*)pCktElem->ControlElementList.Get_First(); + while (( pctrlelem != NULL ) ) + { + if ( ( ( pctrlelem->DSSObjType & CLASSMASK ) ) == REG_CONTROL ) + { + Parser[ActiveActor]->SetCmdString("Transformer=" + pCktElem->get_Name()); + pctrlelem->Edit( ActiveActor ); + } + pctrlelem = (TDSSCktElement*) pCktElem->ControlElementList.Get_Next(); + } + } + break; + default: {} + /*nada*/ + } + } + pCktElem = (TDSSCktElement*) with0 -> CktElements.Get_Next(); + } + + + /*Run the control update scripts now that everything is renamed*/ + auto myPtr = ControlUpDatePtrs.begin(); + auto myPtr2 = ControlUpDateStrings.begin(); + for ( int stop = ControlUpDatePtrs.size() - 1, i = 0; i <= stop; i++) + { + myPtr = std::next(ControlUpDatePtrs.begin(), i); + myPtr2 = std::next(ControlUpDateStrings.begin(), i); + pCktElem = (TDSSCktElement*) (*myPtr); + Parser[ActiveActor]->SetCmdString(*myPtr2); + pCktElem->Edit( ActiveActor ); + } + ControlUpDateStrings.clear(); + ControlUpDatePtrs.clear(); + } + } /*With*/ + } + /*Rename Buses and element names to generic names to remove identifiable names*/ + + + double QuadSolver( const double A, const double b, const double c ) // returns largest of two answers + + { + double result = 0.0; + double Ans1 = 0.0, Ans2 = 0.0, MidTerm = 0.0, a2 = 0.0; + result = 0.0; // default return + if ( A == 0.0 ) + { + if ( b != 0.0 ) + result = - c / b; + } + else + { + MidTerm = sqrt( b * b - 4.0 * A * c ); + a2 = 2.0 * A; + Ans1 = ( - b + MidTerm ) / a2; + Ans2 = ( - b - MidTerm ) / a2; + // return most positive number + if ( Ans1 > Ans2 ) + result = Ans1; + else + result = Ans2; + } + return result; + } + + /*-------------------------------------------------------------------------------*/ + + + int GetOCPDeviceType( TDSSCktElement* pElem ) + { + int result = 0; + int i = 0; + TDSSCktElement* pCktElement; + result = 0; + i = 1; + do + { + pCktElement = (TDSSCktElement*) pElem->ControlElementList.Get( i ); + if ( pCktElement != NULL ) + switch ( pCktElement->DSSObjType & CLASSMASK ) + { + case FUSE_CONTROL: + result = 1; + break; + case RECLOSER_CONTROL: + result = 2; + break; + case RELAY_CONTROL: + result = 3; + break; + } + i++; + } + while ( ! ( ( i > pElem->ControlElementList.get_myNumList() ) || ( result > 0 ) ) ); + return result; + } + + + String GetOCPDeviceTypeString( int icode ) + { + String result; + switch ( icode ) + { + case 1: + result = "FUSE"; + break; + case 2: + result = "RECLOSER"; + break; + case 3: + result = "RELAY"; + break; + default: + result = "Unknown"; + } + return result; + } + + + String GetNodeString( const String BusName ) + { + String result; + size_t dotpos = 0; + dotpos = BusName.find( "." ); + if ( dotpos == String::npos ) + result = ""; + else + result = BusName.substr( dotpos, BusName.size() ); // preserve node designations if any + return result; + } + +} // namesspace Utilities + + + + + + + + + diff --git a/OpenDSSC/Common/Utilities.h b/OpenDSSC/Common/Utilities.h new file mode 100644 index 0000000..0f1cd5a --- /dev/null +++ b/OpenDSSC/Common/Utilities.h @@ -0,0 +1,243 @@ +#ifndef UtilitiesH +#define UtilitiesH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +/* + 12-18-2002 RCD Converted Eventlog to in-memory rather than file +*/ + +#include +//#include "Arraydef.h" +#include "Capacitor.h" +#include "CktElement.h" +#include "CmdForms.h" +#include "ControlElem.h" +#include "DSSClass.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "DSSObject.h" +#include "Dynamics.h" +#include "EnergyMeter.h" +#include "ExecCommands.h" +#include "Executive.h" +#include "ExecOptions.h" +#include "Fault.h" +#include "Feeder.h" +#include "generator.h" +#include "HashList.h" +#include +#include "Line.h" +#include "Load.h" +#include "LoadShape.h" +#include +#include "ParserDel.h" +#include "PCElement.h" +#include "PDElement.h" +#include "Reactor.h" +#include "Solution.h" +#include +#include +#include "System.h" +#include "Sysutils.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" + +namespace Utilities +{ + enum LineStyle { + psSolid, + psDash, + psDot, + psDashDot, + psDashDotDot, + psClear, + psInsideFrame + }; + + const int + clAqua = 0xFFFF00, + clBlack = 0x000000, + clBlue = 0xFF0000, + clDkGray = 0x808080, + clFuchsia = 0xFF00FF, + clGray = 0x808080, + clGreen = 0x008000, + clLime = 0x00FF00, + clLtGray = 0xC0C0C0, + clMaroon = 0x000080, + clNavy = 0x800000, + clOlive = 0x008080, + clPurple = 0x800080, + clRed = 0x0000FF, + clSilver = 0xC0C0C0, + clTeal = 0x808000, + clWhite = 0xFFFFFF, + clYellow = 0x00FFFF; + + /// Map IOResult from d2c to a C++ exception; required for compatibility. + /// Without this, we never get exceptions in case of file errors. + void IOResultToException(); + + int CompareTextShortest(const String s1, const String s2); + void FireOffEditor(String Filenm); + void ShowReport(bool ShowR); + void DoDOSCmd(String CmdString); + String StripExtension(const String S); + String StripClassName(const String S); // Return only element name sans class. + + String GetNodeString(const String BusName); + String Pad(const String S, int Width); + String Paddots(const String S, int Width); + String PadTrunc(const String S, int Width); + String IntArrayToString(pIntegerArray iarray, int count); + String DblArrayToString(pDoubleArray dblarray, int count); + String CmplxArrayToString(pComplexArray cpxarray, int count); + String EncloseQuotes(const String S); + void ShowMessageBeep(const String S); + String FullName(TDSSCktElement* pElem); + + /*Parsing Utilities*/ + void ParseObjectClassandName(const String FullObjName, String& ClassName, String& ObjName); + void ParseIntArray(pIntegerArray iarray, int& count, const String S); + int InterpretSolveMode(const String S); + int InterpretControlMode(const String S); + int InterpretLoadModel(const String S); + bool InterpretYesNo(const String S); + int InterpretRandom(const String S); + int InterpretAddType(const String S); + int InterpretConnection(const String S); + int InterpretSolveAlg(const String S); + bool InterpretCktModel(const String S); + void InitDblArray(int NumValues, pDoubleArray Xarray, double Value); + void InitIntArray(int NumValues, pIntegerArray Xarray, int Value); + int InterpretDblArray(const String S, int MaxValues, pDoubleArray ResultArray); + int InterpretIntArray(const String S, int MaxValues, pIntegerArray ResultArray); + void InterpretAndAllocStrArray(const String S, int& Size, pStringArray ResultArray); + void InterpretTStringListArray(const String S, TStringList& ResultList); + double InterpretTimeStepSize(const String S); + int InterpretLoadShapeClass(const String S); + int InterpretEarthModel(const String S); + int InterpretColorName(const String S); + complex InterpretComplex(const String S); + String ConstructElemName(const String Param); + int InterpretCoreType(const String str); + String GetSolutionModeID(); + String GetSolutionModeIDName(int idx); + String GetControlModeID(); + String GetRandomModeID(); + String GetLoadModel(); + String GetActiveLoadShapeClass(); + String GetDSSArray_Real(int n, pDoubleArray dbls); + String GetDSSArray_Integer(int n, pIntegerArray ints); + String GetEarthModel(int n); + int GetOCPDeviceType(TDSSCktElement* pElem); + String GetOCPDeviceTypeString(int icode); + // Addition to deal with Memory mapped data + + double InterpretDblArrayMMF(unsigned char* myMap, int FileType, int Column, int Index, int DataSize); + + /*misc functions*/ + int DoExecutiveCommand(const String S); + int GetCktElementIndex(const String FullObjName); + bool IsShuntElement(const TDSSCktElement* elem); + bool IslineElement(const TDSSCktElement* elem); + bool IsTransformerElement(const TDSSCktElement* elem); + // --- moved to ReduceAlgs 2/13/19 Function IsStubLine(const Elem:TDSSCktElement):Boolean; + + bool CheckParallel(const TDSSCktElement* Line1, const TDSSCktElement* Line2); + bool AllTerminalsClosed(TDSSCktElement* ThisElement); + String Str_Real(const double Value, int NumDecimals); + void DumpAllDSSCommands(String& Filename); + void DumpAllocationFactors(String& Filename); + void DumpComplexMatrix(Textfile& F, TcMatrix* AMatrix); + double NearestBasekV(double kV); + double PresentTimeInSec(int ActorID); + int DoResetFaults(); + int DoResetControls(); + void DoResetKeepList(); + int GetNodeNum(int NodeRef); + void InitStringToNull(String& S); + complex CmulReal_im(const complex A, const double Mult); // Multiply only imaginary part by a real + //FUNCTION IsValidNumericField(const NumberField:TEdit):Boolean; + + double MaxdblArrayValue(int npts, pDoubleArray dbls); + int iMaxAbsdblArrayValue(int npts, pDoubleArray dbls); + double QuadSolver(const double A, const double b, const double c); // returns largest of two answers + + + /*Save Function Helper*/ + + bool WriteClassFile(TDSSClass &Dss_Class, String Filename, bool IsCktElement); + bool WriteVsourceClassFile(TDSSClass &Dss_Class, bool IsCktElement); + void WriteActiveDSSObject(Textfile& F, String NeworEdit); + String CheckForBlanks(const String &S); + bool RewriteAlignedFile(const String Filename); + + /*Event Log*/ + void ClearEventLog(); + void AppendToEventLog(const String opdev, const String Action, const int ActorID); + void LogThisEvent(const String EventName, const int ActorID); + void ClearErrorLog(); + + /*Routines for doing common things to complex numbers*/ + void RotatePhasorDeg(complex& Phasor, const double h, const double AngleDeg); + void RotatePhasorRad(complex& Phasor, const double h, const double AngleRad); + void ConvertComplexArrayToPolar(const pComplexArray Buffer, int n); + void ConvertComplexArrayToPowerandPF(const pComplexArray Buffer, int n); + complex Residual(void* p, int Nph); + complex ResidualPolar(void* p, int Nph); + double PowerFactor(const complex S); + double ConvertPFToPFRange2(const double Value); + double ConvertPFRange2ToPF(const double Value); + void CmulArray(pComplexArray pc, double Multiplier, int Size); // Multiply a complex array times a double + + /*Support for going in and out of Dynamics Mode and Harmonics Mode*/ + + void CalcInitialMachineStates(); + void InvalidateAllPCElements(); + bool InitializeForHarmonics(int ActorID); + bool SavePresentVoltages(); + bool RetrieveSavedVoltages(); + double GetMaxPUVoltage(); + double GetMinPUVoltage(bool IgnoreNeutrals); + complex GetTotalPowerFromSources(int ActorID); + longInt GetMaxCktElementSize(); + int GetUniqueNodeNumber(const String sBusName, int StartNode); + + /*TraceBack Functions*/ + bool IsPathBetween(TPDElement* FromLine, TPDElement* ToLine); + void TraceAndEdit(TPDElement* FromLine, TPDElement* ToLine, int NPhases, String EditStr); + void GoForwardAndRephase(TPDElement* FromLine, const String PhaseString, const String EditStr, const String ScriptFileName, bool TransStop); + void MakeDistributedGenerators(double kW, double PF, String How, int Skip, String Fname, bool DoGenerators); + void Obfuscate(); + + + /*Feeder Utilities*/ // not currently used + + void EnableFeeders(); + void DisableFeeders(); + void InitializeFeeders(); + void ForwardSweepAllFeeders(); + void BackwardSweepAllFeeders(); + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Utilities; +#endif + +#endif // UtilitiesH + + + + + + + + diff --git a/OpenDSSC/Common/YMatrix.cpp b/OpenDSSC/Common/YMatrix.cpp new file mode 100644 index 0000000..05f89d2 --- /dev/null +++ b/OpenDSSC/Common/YMatrix.cpp @@ -0,0 +1,371 @@ + + +#pragma hdrstop + +#include "YMatrix.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "CktElement.h" +#include "Utilities.h" +#include "klusolve.h" + + + +namespace YMatrix +{ + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ReCalcAllYPrims(int ActorID) + { + TDSSCktElement* pElem; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + if (with0->LogEvents) + LogThisEvent("Recalc All Yprims", ActorID); + pElem = (TDSSCktElement*) with0->CktElements.Get_First(); + while (pElem != NULL) + { + pElem->CalcYPrim(ActorID); + pElem = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ReCalcInvalidYPrims(int ActorID) + /*Recalc YPrims only for those circuit elements that have had changes since last + solution*/ + { + TDSSCktElement* pElem; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + if (with0->LogEvents) + LogThisEvent("Recalc Invalid Yprims", ActorID); + pElem = (TDSSCktElement*)with0->CktElements.Get_First(); + while (pElem != NULL) + { + /*# with pElem do */ + if (pElem->Get_YprimInvalid(ActorID,false)) + pElem->CalcYPrim(ActorID); + pElem = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + } + } + } + + //= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + void ResetSparseMatrix(klusparseset_t* hY, int Size, int ActorID) + { + if (*hY != 0) + { + if /*Get rid of existing one beFore making a new one*/ (DeleteSparseSet(*hY) < 1) + DoSimpleMsg("Error Deleting System Y Matrix in ResetSparseMatrix. Problem with Sparse matrix solver.", 50001); + *hY = 0; + } + + // Make a new sparse set + *hY = NewSparseSet(Size); + if (! *hY) + { // Raise and exception + DoSimpleMsg("Error Creating System Y Matrix. Problem WITH Sparse matrix solver.", 50000); + } + } + + + void InitializeNodeVbase(int ActorID) + { + int i = 0; + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + for (int stop = with0->NumNodes, i = 1; i <= stop; i++) + /*# with MapNodeToBus^[i] do */ + { + TNodeBus with1 = with0->MapNodeToBus[i - 1]; + { + with0->Solution->NodeVbase[i] = with0->Buses[with1.BusRef - 1]->kVBase * 1000.0; + } + } + with0->Solution->VoltageBaseChanged = false; + } + } + } + //===================================================================================================================================== + void AddPDEShunt(int ActorID) + /* Adds capacitors and rectors connected in shunt to the active Y Bus Matrix (expected to be series) + This routine was created especifically to fill the needs of the NCIM solution algorithm */ + { + + } + //===================================================================================================================================== + void BuildYMatrix(int BuildOption, bool AllocateVI, int ActorID) + + /*Builds designated Y matrix for system and allocates solution arrays*/ + { + int YMatrixsize = 0; + // CmatArray :pComplexArray; Replaced with a global array for thread safe operation + + TDSSCktElement* pElem; + + //{****} FTrace: TextFile; + + //{****} AssignFile(Ftrace, 'YmatrixTrace.txt'); + //{****} Rewrite(FTrace); + //{****} IOResultToException(); + ActiveYPrim[ActorID] = pComplexArray(); //Replaces the previous local declaration CmatArray := Nil; for thread safe + ActiveYPrim[ActorID] = NULL; + // new function to log KLUSolve.DLL function calls + // SetLogFile ('KLU_Log.txt', 1); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]; + { + if (with0->Solution->PreserveNodeVoltages) + with0->Solution->UpdateVBus(ActorID); // Update voltage values stored with Bus object + + // the following re counts the number of buses and resets meter zones and feeders + // If radial but systemNodeMap not set then init for radial got skipped due to script sequence + if (with0->get_FBusNameRedefined()) + with0->ReProcessBusDefs(ActorID); // This changes the node references into the system Y matrix!! + YMatrixsize = with0->NumNodes; + if (AllocateVI) + { + if (with0->LogEvents) + LogThisEvent("ReAllocating Solution Arrays", ActorID); + with0->Solution->NodeV.resize(with0->NumNodes + 1); // Allocate System Voltage array - allow for zero element + (with0->Solution->NodeV)[0] = CZero; + with0->Solution->Currents.resize(with0->NumNodes + 1); // Allocate System current array + with0->Solution->AuxCurrents = (pNodeVarray)realloc(with0->Solution->AuxCurrents, sizeof(complex) * (with0->NumNodes + 1)); // Allocate System current array + + /*A-Diakoptics vectors memory allocation*/ + with0->Solution->Node_dV.resize(with0->NumNodes + 1); // Allocate the partial solution voltage + with0->Solution->Ic_Local.resize(with0->NumNodes + 1); // Allocate the Complementary currents + } + switch (BuildOption) + { + case WHOLEMATRIX: + { + ResetSparseMatrix(&with0->Solution->hYsystem, YMatrixsize, ActorID); + with0->Solution->hY = with0->Solution->hYsystem; + } + break; + case SERIESONLY: + { + ResetSparseMatrix(&with0->Solution->hYseries, YMatrixsize, ActorID); + with0->Solution->hY = with0->Solution->hYseries; + } + break; + case PDE_ONLY: + { + ResetSparseMatrix(&with0->Solution->hYseries, YMatrixsize, ActorID); + with0->Solution->hY = with0->Solution->hYseries; + } + break; + } + // tune up the Yprims if necessary + if (with0->Solution->FrequencyChanged) + ReCalcAllYPrims(ActorID); + else + ReCalcInvalidYPrims(ActorID); + if (SolutionAbort) + { + DoSimpleMsg("Y matrix build aborted due to error in primitive Y calculations.", 11001); + return; // Some problem occured building Yprims + } + with0->Solution->FrequencyChanged = false; + if (with0->LogEvents) + switch (BuildOption) + { + case WHOLEMATRIX: + LogThisEvent("Building Whole Y Matrix", ActorID); + break; + case SERIESONLY: + LogThisEvent("Building Series Y Matrix", ActorID); + break; + case PDE_ONLY: + LogThisEvent("Building PDE only Y Matrix", ActorID); + break; + } + // Add in Yprims for all devices + pElem = (TDSSCktElement*) with0->CktElements.Get_First(); + while (pElem != NULL) + { + /*# with pElem do */ + if (pElem->Get_Enabled()) + { // Add stuff only if enabled + switch (BuildOption) + { + case PDE_ONLY: + { + // First check if the element is PDE or source + bool ValidElm = ((pElem->ParentClass->DSSClassType & BaseClassMask) == PD_ELEMENT); + // If not PDE, check if it is a VSource + ValidElm = ValidElm || ((pElem->DSSObjType & CLASSMASK) == SOURCE); + + if (ValidElm) + ActiveYPrim[ActorID] = pElem->GetYPrimValues(ALL_YPRIM); + else + ActiveYPrim[ActorID] = NULL; + } + break; + case SERIESONLY: + ActiveYPrim[ActorID] = pElem->GetYPrimValues(SERIES); + break; + default: // Whole matrix + ActiveYPrim[ActorID] = pElem->GetYPrimValues(ALL_YPRIM); + break; + } + // new function adding primitive Y matrix to KLU system Y matrix + if (ActiveYPrim[ActorID] != NULL) + { + if ( AddPrimitiveMatrix( with0->Solution->hY, pElem->Yorder, &( pElem->NodeRef[0] ), &( ActiveYPrim[ActorID][0] ) ) < 1) + DoSimpleMsg("Node index out of range adding to System Y Matrix", 50002); + } + } // If Enabled + pElem = (TDSSCktElement*) with0->CktElements.Get_Next(); + } + //{****} CloseFile(Ftrace); + //{****} FireOffEditor( 'YmatrixTrace.txt'); + + // Allocate voltage and current vectors if requested + if (AllocateVI) + { + if (!with0->Solution->VmagSaved.empty()) with0->Solution->VmagSaved.clear(); + if (!with0->Solution->ErrorSaved.empty()) with0->Solution->ErrorSaved.clear(); + if (!with0->Solution->NodeVbase.empty()) with0->Solution->NodeVbase.clear(); + if (!with0->Solution->NodeYii.empty()) with0->Solution->NodeYii.clear(); /*by Dahei -> UCF*/ + + with0->Solution->VmagSaved.resize(with0->NumNodes + 1); + + with0->Solution->ErrorSaved.resize(with0->NumNodes + 1); + + with0->Solution->NodeVbase.resize(with0->NumNodes + 1); + + with0->Solution->NodeYii.resize(with0->NumNodes + 1); // zero fill //Bii {by Dahei -> UCF} + with0->Solution->NodeYiiEmpty = true; /*by Dahei -> UCF*/ + InitializeNodeVbase(ActorID); + } + switch (BuildOption) + { + case WHOLEMATRIX: + { + with0->Solution->SeriesYInvalid = true; // Indicate that the Series matrix may not match + with0->Solution->SystemYChanged = false; + } + break; + case SERIESONLY: + with0->Solution->SeriesYInvalid = false; + break; // SystemYChange unchanged + case PDE_ONLY: + { + with0->Solution->SeriesYInvalid = true; // Indicate that the Series matrix may not match + with0->Solution->SystemYChanged = false; + } + break; + + } + // Deleted RCD only done now on mode change + // SolutionInitialized := False; //Require initialization of voltages if Y changed + if (with0->Solution->PreserveNodeVoltages) + with0->Solution->RestoreNodeVfromVbus(); + } + } + } + + // leave the call to GetMatrixElement, but add more diagnostics + + + + String CheckYMatrixforZeroes(int ActorID) + { + String result; + unsigned int i = 0; + complex c; + klusparseset_t hY; + unsigned int sCol = 0; + unsigned int nIslands = 0, iCount = 0, iFirst = 0, p = 0; + vector < unsigned int > Cliques; + result = ""; + /*# with ActiveCircuit[ActorID] do */ + { + TDSSCircuit* with0 = ActiveCircuit[ActorID]; + { + hY = with0->Solution->hY; + for (int stop = with0->NumNodes, i = 1; i <= stop; i++) + { + GetMatrixElement(hY, i, i, (pcomplex) &c); + if (cabs(c) == 0.0) + /*# with MapNodeToBus^[i] do */ + { + TNodeBus with1 = with0->MapNodeToBus[i - 1]; + { + result = result + Format("%sZero diagonal for bus %s, node %d", CRLF.c_str(), with0->BusList.Get(with1.BusRef).c_str(), with1.NodeNum); + } + } + } + + // new diagnostics + GetSingularCol(hY, &sCol); // returns a 1-based node number + if (sCol > 0) + /*# with MapNodeToBus^[sCol] do */ + { + TNodeBus with1 = with0->MapNodeToBus[sCol - 1]; + { + result = result + Format("%sMatrix singularity at bus %s, node %d", CRLF.c_str(), with0->BusList.Get(with1.BusRef).c_str(), sCol); + } + } + Cliques.resize(with0->NumNodes); + nIslands = FindIslands(hY, with0->NumNodes, &Cliques[0]); + if (nIslands > 1) + { + result = result + Format("%sFound %d electrical islands:", CRLF.c_str(), nIslands); + for (int stop = nIslands, i = 1; i <= stop; i++) + { + iCount = 0; + iFirst = 0; + for (int stop = with0->NumNodes - 1, p = 0; p <= stop; p++) + { + if (Cliques[p] == i) + { + iCount += 1; + if (iFirst == 0) + iFirst = p + 1; + } + } + /*# with MapNodeToBus^[iFirst] do */ + { + TNodeBus with1 = with0->MapNodeToBus[iFirst - 1]; + { + result = result + Format("%s #%d has %d nodes, including bus %s (node %d)", CRLF.c_str(), i, iCount, with0->BusList.Get(with1.BusRef).c_str(), iFirst); + } + } + } + } + } + } + return result; + } + +} // namespace YMatrix + + + + + + + + diff --git a/OpenDSSC/Common/YMatrix.h b/OpenDSSC/Common/YMatrix.h new file mode 100644 index 0000000..86b1c11 --- /dev/null +++ b/OpenDSSC/Common/YMatrix.h @@ -0,0 +1,68 @@ +#ifndef YmatrixH +#define YmatrixH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Unit to manage System Y matrix + + 6-11-00 Created from Solution.Pas +*/ + + +#include "System.h" +#include "Sysutils.h" + +#include "Ucomplex.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "klusolve.h" // klusparseset_t + + + +/*Options for building Y matrix*/ + +namespace YMatrix +{ + + //class EEsolv32Problem; + + + const int SERIESONLY = 1; + const int WHOLEMATRIX = 2; + const int PDE_ONLY = 3; + + + //class EEsolv32Problem: public EXCEPTion { + // typedef EXCEPTion inherited; + //}; + // removed given the lack of EXCEPTion + class EEsolv32Problem { + + }; + + + void BuildYMatrix(int BuildOption, bool AllocateVI, int ActorID); + void ResetSparseMatrix(klusparseset_t* hY, int Size, int ActorID); + void InitializeNodeVbase(int ActorID); + String CheckYMatrixforZeroes(int ActorID); + +} // namespace Ymatrix + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace YMatrix; +#endif + +#endif // YmatrixH + + + + + + + + diff --git a/OpenDSSC/Common/djson.h b/OpenDSSC/Common/djson.h new file mode 100644 index 0000000..e9502cf --- /dev/null +++ b/OpenDSSC/Common/djson.h @@ -0,0 +1,42 @@ +#ifndef djsonH +#define djsonH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +//#include + +#include "../Shared/Command.h" +//#include +//#include +//#include +#include "../Common/DSSGlobals.h" +//#include +//#include +#include "../Common/djson.h" +#include "../PDElements/Line.h" +#include "../Common/Utilities.h" +#include "../Shared/Arraydef.h" +//#include +//#include "DSSForms.h" + // TCP Indy libraries +#include "../Executive/ExecHelper.h" +//#include +//#include +//#include +//#include +//#include "IdThreadComponent.h" +//#include "TCP_IP.h" + +#endif // djsonH + + + + + + diff --git a/OpenDSSC/Common/filesystem.hpp b/OpenDSSC/Common/filesystem.hpp new file mode 100644 index 0000000..5d3b17c --- /dev/null +++ b/OpenDSSC/Common/filesystem.hpp @@ -0,0 +1,6050 @@ +//--------------------------------------------------------------------------------------- +// +// ghc::filesystem - A C++17-like filesystem implementation for C++11/C++14/C++17/C++20 +// +//--------------------------------------------------------------------------------------- +// +// Copyright (c) 2018, Steffen Schümann +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//--------------------------------------------------------------------------------------- +// +// To dynamically select std::filesystem where available on most platforms, +// you could use: +// +// #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)) && defined(__has_include) +// #if __has_include() && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) +// #define GHC_USE_STD_FS +// #include +// namespace fs = std::filesystem; +// #endif +// #endif +// #ifndef GHC_USE_STD_FS +// #include +// namespace fs = ghc::filesystem; +// #endif +// +//--------------------------------------------------------------------------------------- +#ifndef GHC_FILESYSTEM_H +#define GHC_FILESYSTEM_H + +// #define BSD manifest constant only in +// sys/param.h +#ifndef _WIN32 +#include +#endif + +#ifndef GHC_OS_DETECTED +#if defined(__APPLE__) && defined(__MACH__) +#define GHC_OS_MACOS +#elif defined(__linux__) +#define GHC_OS_LINUX +#if defined(__ANDROID__) +#define GHC_OS_ANDROID +#endif +#elif defined(_WIN64) +#define GHC_OS_WINDOWS +#define GHC_OS_WIN64 +#elif defined(_WIN32) +#define GHC_OS_WINDOWS +#define GHC_OS_WIN32 +#elif defined(__CYGWIN__) +#define GHC_OS_CYGWIN +#elif defined(__sun) && defined(__SVR4) +#define GHC_OS_SOLARIS +#elif defined(__svr4__) +#define GHC_OS_SYS5R4 +#elif defined(BSD) +#define GHC_OS_BSD +#elif defined(__EMSCRIPTEN__) +#define GHC_OS_WEB +#include +#elif defined(__QNX__) +#define GHC_OS_QNX +#else +#error "Operating system currently not supported!" +#endif +#define GHC_OS_DETECTED +#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#if _MSVC_LANG == 201703L +#define GHC_FILESYSTEM_RUNNING_CPP17 +#else +#define GHC_FILESYSTEM_RUNNING_CPP20 +#endif +#elif (defined(__cplusplus) && __cplusplus >= 201703L) +#if __cplusplus == 201703L +#define GHC_FILESYSTEM_RUNNING_CPP17 +#else +#define GHC_FILESYSTEM_RUNNING_CPP20 +#endif +#endif +#endif + +#if defined(GHC_FILESYSTEM_IMPLEMENTATION) +#define GHC_EXPAND_IMPL +#define GHC_INLINE +#ifdef GHC_OS_WINDOWS +#ifndef GHC_FS_API +#define GHC_FS_API +#endif +#ifndef GHC_FS_API_CLASS +#define GHC_FS_API_CLASS +#endif +#else +#ifndef GHC_FS_API +#define GHC_FS_API __attribute__((visibility("default"))) +#endif +#ifndef GHC_FS_API_CLASS +#define GHC_FS_API_CLASS __attribute__((visibility("default"))) +#endif +#endif +#elif defined(GHC_FILESYSTEM_FWD) +#define GHC_INLINE +#ifdef GHC_OS_WINDOWS +#ifndef GHC_FS_API +#define GHC_FS_API extern +#endif +#ifndef GHC_FS_API_CLASS +#define GHC_FS_API_CLASS +#endif +#else +#ifndef GHC_FS_API +#define GHC_FS_API extern +#endif +#ifndef GHC_FS_API_CLASS +#define GHC_FS_API_CLASS +#endif +#endif +#else +#define GHC_EXPAND_IMPL +#define GHC_INLINE inline +#ifndef GHC_FS_API +#define GHC_FS_API +#endif +#ifndef GHC_FS_API_CLASS +#define GHC_FS_API_CLASS +#endif +#endif + +#ifdef GHC_EXPAND_IMPL + +#ifdef GHC_OS_WINDOWS +#define NOMINMAX +#include +// additional includes +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GHC_OS_ANDROID +#include +#if __ANDROID_API__ < 12 +#include +#endif +#include +#define statvfs statfs +#else +#include +#endif +#ifdef GHC_OS_CYGWIN +#include +#endif +#if !defined(__ANDROID__) || __ANDROID_API__ >= 26 +#include +#endif +#endif +#ifdef GHC_OS_MACOS +#include +#endif + +#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) +#if __has_include() +#define GHC_HAS_THREEWAY_COMP +#include +#endif +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else // GHC_EXPAND_IMPL + +#if defined(__cpp_impl_three_way_comparison) && defined(__has_include) +#if __has_include() +#define GHC_HAS_THREEWAY_COMP +#include +#endif +#endif +#include +#include +#include +#include +#include +#include +#include +#ifdef GHC_OS_WINDOWS +#include +#endif +#endif // GHC_EXPAND_IMPL + +// After standard library includes. +// Standard library support for std::string_view. +#if defined(__cpp_lib_string_view) +#define GHC_HAS_STD_STRING_VIEW +#elif defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 4000) && (__cplusplus >= 201402) +#define GHC_HAS_STD_STRING_VIEW +#elif defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE >= 7) && (__cplusplus >= 201703) +#define GHC_HAS_STD_STRING_VIEW +#elif defined(_MSC_VER) && (_MSC_VER >= 1910 && _MSVC_LANG >= 201703) +#define GHC_HAS_STD_STRING_VIEW +#endif + +// Standard library support for std::experimental::string_view. +#if defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 3700 && _LIBCPP_VERSION < 7000) && (__cplusplus >= 201402) +#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW +#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)) && (__cplusplus >= 201402) +#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW +#elif defined(__GLIBCXX__) && defined(_GLIBCXX_USE_DUAL_ABI) && (__cplusplus >= 201402) +// macro _GLIBCXX_USE_DUAL_ABI is always defined in libstdc++ from gcc-5 and newer +#define GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW +#endif + +#if defined(GHC_HAS_STD_STRING_VIEW) +#include +#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) +#include +#endif + +#if !defined(GHC_OS_WINDOWS) && !defined(PATH_MAX) +#define PATH_MAX 4096 +#endif + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Behaviour Switches (see README.md, should match the config in test/filesystem_test.cpp): +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Enforce C++17 API where possible when compiling for C++20, handles the following cases: +// * fs::path::u8string() returns std::string instead of std::u8string +// #define GHC_FILESYSTEM_ENFORCE_CPP17_API +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// LWG #2682 disables the since then invalid use of the copy option create_symlinks on directories +// configure LWG conformance () +#define LWG_2682_BEHAVIOUR +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// LWG #2395 makes crate_directory/create_directories not emit an error if there is a regular +// file with that name, it is superseded by P1164R1, so only activate if really needed +// #define LWG_2935_BEHAVIOUR +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// LWG #2936 enables new element wise (more expensive) path comparison +// * if this->root_name().native().compare(p.root_name().native()) != 0 return result +// * if this->has_root_directory() and !p.has_root_directory() return -1 +// * if !this->has_root_directory() and p.has_root_directory() return -1 +// * else result of element wise comparison of path iteration where first comparison is != 0 or 0 +// if all comparisons are 0 (on Windows this implementation does case-insensitive root_name() +// comparison) +#define LWG_2936_BEHAVIOUR +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// LWG #2937 enforces that fs::equivalent emits an error, if !fs::exists(p1)||!exists(p2) +#define LWG_2937_BEHAVIOUR +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// UTF8-Everywhere is the original behaviour of ghc::filesystem. But since v1.5 the Windows +// version defaults to std::wstring storage backend. Still all std::string will be interpreted +// as UTF-8 encoded. With this define you can enforce the old behavior on Windows, using +// std::string as backend and for fs::path::native() and char for fs::path::c_str(). This +// needs more conversions, so it is (and was before v1.5) slower, bot might help keeping source +// homogeneous in a multi-platform project. +// #define GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Raise errors/exceptions when invalid unicode codepoints or UTF-8 sequences are found, +// instead of replacing them with the unicode replacement character (U+FFFD). +// #define GHC_RAISE_UNICODE_ERRORS +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Automatic prefix windows path with "\\?\" if they would break the MAX_PATH length. +// instead of replacing them with the unicode replacement character (U+FFFD). +#ifndef GHC_WIN_DISABLE_AUTO_PREFIXES +#define GHC_WIN_AUTO_PREFIX_LONG_PATH +#endif // GHC_WIN_DISABLE_AUTO_PREFIXES +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// ghc::filesystem version in decimal (major * 10000 + minor * 100 + patch) +#define GHC_FILESYSTEM_VERSION 10512L + +#if !defined(GHC_WITH_EXCEPTIONS) && (defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)) +#define GHC_WITH_EXCEPTIONS +#endif +#if !defined(GHC_WITH_EXCEPTIONS) && defined(GHC_RAISE_UNICODE_ERRORS) +#error "Can't raise unicode errors with exception support disabled" +#endif + +namespace ghc { +namespace filesystem { + +#if defined(GHC_HAS_CUSTOM_STRING_VIEW) +#define GHC_WITH_STRING_VIEW +#elif defined(GHC_HAS_STD_STRING_VIEW) +#define GHC_WITH_STRING_VIEW +using std::basic_string_view; +#elif defined(GHC_HAS_STD_EXPERIMENTAL_STRING_VIEW) +#define GHC_WITH_STRING_VIEW +using std::experimental::basic_string_view; +#endif + +// temporary existing exception type for yet unimplemented parts +class GHC_FS_API_CLASS not_implemented_exception : public std::logic_error +{ +public: + not_implemented_exception() + : std::logic_error("function not implemented yet.") + { + } +}; + +template +class path_helper_base +{ +public: + using value_type = char_type; +#ifdef GHC_OS_WINDOWS + static constexpr value_type preferred_separator = '\\'; +#else + static constexpr value_type preferred_separator = '/'; +#endif +}; + +#if __cplusplus < 201703L +template +constexpr char_type path_helper_base::preferred_separator; +#endif + +#ifdef GHC_OS_WINDOWS +class path; +namespace detail { +bool has_executable_extension(const path& p); +} +#endif + +// [fs.class.path] class path +class GHC_FS_API_CLASS path +#if defined(GHC_OS_WINDOWS) && !defined(GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) +#define GHC_USE_WCHAR_T +#define GHC_NATIVEWP(p) p.c_str() +#define GHC_PLATFORM_LITERAL(str) L##str + : private path_helper_base +{ +public: + using path_helper_base::value_type; +#else +#define GHC_NATIVEWP(p) p.wstring().c_str() +#define GHC_PLATFORM_LITERAL(str) str + : private path_helper_base +{ +public: + using path_helper_base::value_type; +#endif + using string_type = std::basic_string; + using path_helper_base::preferred_separator; + + // [fs.enum.path.format] enumeration format + /// The path format in which the constructor argument is given. + enum format { + generic_format, ///< The generic format, internally used by + ///< ghc::filesystem::path with slashes + native_format, ///< The format native to the current platform this code + ///< is build for + auto_format, ///< Try to auto-detect the format, fallback to native + }; + + template + struct _is_basic_string : std::false_type + { + }; + template + struct _is_basic_string> : std::true_type + { + }; + template + struct _is_basic_string, std::allocator>> : std::true_type + { + }; +#ifdef GHC_WITH_STRING_VIEW + template + struct _is_basic_string> : std::true_type + { + }; + template + struct _is_basic_string>> : std::true_type + { + }; +#endif + + template + using path_type = typename std::enable_if::value, path>::type; + template +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) + using path_from_string = + typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || + std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || + std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || + std::is_same::type>::value, + path>::type; + template + using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; +#else + using path_from_string = + typename std::enable_if<_is_basic_string::value || std::is_same::type>::value || std::is_same::type>::value || + std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value || + std::is_same::type>::value || std::is_same::type>::value || std::is_same::type>::value, + path>::type; + template + using path_type_EcharT = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, path>::type; +#endif + // [fs.path.construct] constructors and destructor + path() noexcept; + path(const path& p); + path(path&& p) noexcept; + path(string_type&& source, format fmt = auto_format); + template > + path(const Source& source, format fmt = auto_format); + template + path(InputIterator first, InputIterator last, format fmt = auto_format); +#ifdef GHC_WITH_EXCEPTIONS + template > + path(const Source& source, const std::locale& loc, format fmt = auto_format); + template + path(InputIterator first, InputIterator last, const std::locale& loc, format fmt = auto_format); +#endif + ~path(); + + // [fs.path.assign] assignments + path& operator=(const path& p); + path& operator=(path&& p) noexcept; + path& operator=(string_type&& source); + path& assign(string_type&& source); + template + path& operator=(const Source& source); + template + path& assign(const Source& source); + template + path& assign(InputIterator first, InputIterator last); + + // [fs.path.append] appends + path& operator/=(const path& p); + template + path& operator/=(const Source& source); + template + path& append(const Source& source); + template + path& append(InputIterator first, InputIterator last); + + // [fs.path.concat] concatenation + path& operator+=(const path& x); + path& operator+=(const string_type& x); +#ifdef GHC_WITH_STRING_VIEW + path& operator+=(basic_string_view x); +#endif + path& operator+=(const value_type* x); + path& operator+=(value_type x); + template + path_from_string& operator+=(const Source& x); + template + path_type_EcharT& operator+=(EcharT x); + template + path& concat(const Source& x); + template + path& concat(InputIterator first, InputIterator last); + + // [fs.path.modifiers] modifiers + void clear() noexcept; + path& make_preferred(); + path& remove_filename(); + path& replace_filename(const path& replacement); + path& replace_extension(const path& replacement = path()); + void swap(path& rhs) noexcept; + + // [fs.path.native.obs] native format observers + const string_type& native() const noexcept; + const value_type* c_str() const noexcept; + operator string_type() const; + template , class Allocator = std::allocator> + std::basic_string string(const Allocator& a = Allocator()) const; + std::string string() const; + std::wstring wstring() const; +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) + std::u8string u8string() const; +#else + std::string u8string() const; +#endif + std::u16string u16string() const; + std::u32string u32string() const; + + // [fs.path.generic.obs] generic format observers + template , class Allocator = std::allocator> + std::basic_string generic_string(const Allocator& a = Allocator()) const; + std::string generic_string() const; + std::wstring generic_wstring() const; +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) + std::u8string generic_u8string() const; +#else + std::string generic_u8string() const; +#endif + std::u16string generic_u16string() const; + std::u32string generic_u32string() const; + + // [fs.path.compare] compare + int compare(const path& p) const noexcept; + int compare(const string_type& s) const; +#ifdef GHC_WITH_STRING_VIEW + int compare(basic_string_view s) const; +#endif + int compare(const value_type* s) const; + + // [fs.path.decompose] decomposition + path root_name() const; + path root_directory() const; + path root_path() const; + path relative_path() const; + path parent_path() const; + path filename() const; + path stem() const; + path extension() const; + + // [fs.path.query] query + bool empty() const noexcept; + bool has_root_name() const; + bool has_root_directory() const; + bool has_root_path() const; + bool has_relative_path() const; + bool has_parent_path() const; + bool has_filename() const; + bool has_stem() const; + bool has_extension() const; + bool is_absolute() const; + bool is_relative() const; + + // [fs.path.gen] generation + path lexically_normal() const; + path lexically_relative(const path& base) const; + path lexically_proximate(const path& base) const; + + // [fs.path.itr] iterators + class iterator; + using const_iterator = iterator; + iterator begin() const; + iterator end() const; + +private: + using impl_value_type = value_type; + using impl_string_type = std::basic_string; + friend class directory_iterator; + void append_name(const value_type* name); + static constexpr impl_value_type generic_separator = '/'; + template + class input_iterator_range + { + public: + typedef InputIterator iterator; + typedef InputIterator const_iterator; + typedef typename InputIterator::difference_type difference_type; + + input_iterator_range(const InputIterator& first, const InputIterator& last) + : _first(first) + , _last(last) + { + } + + InputIterator begin() const { return _first; } + InputIterator end() const { return _last; } + + private: + InputIterator _first; + InputIterator _last; + }; + friend void swap(path& lhs, path& rhs) noexcept; + friend size_t hash_value(const path& p) noexcept; + friend path canonical(const path& p, std::error_code& ec); + friend bool create_directories(const path& p, std::error_code& ec) noexcept; + string_type::size_type root_name_length() const noexcept; + void postprocess_path_with_format(format fmt); + void check_long_path(); + impl_string_type _path; +#ifdef GHC_OS_WINDOWS + void handle_prefixes(); + friend bool detail::has_executable_extension(const path& p); +#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH + string_type::size_type _prefixLength{0}; +#else // GHC_WIN_AUTO_PREFIX_LONG_PATH + static const string_type::size_type _prefixLength{0}; +#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH +#else + static const string_type::size_type _prefixLength{0}; +#endif +}; + +// [fs.path.nonmember] path non-member functions +GHC_FS_API void swap(path& lhs, path& rhs) noexcept; +GHC_FS_API size_t hash_value(const path& p) noexcept; +#ifdef GHC_HAS_THREEWAY_COMP +GHC_FS_API std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept; +#endif +GHC_FS_API bool operator==(const path& lhs, const path& rhs) noexcept; +GHC_FS_API bool operator!=(const path& lhs, const path& rhs) noexcept; +GHC_FS_API bool operator<(const path& lhs, const path& rhs) noexcept; +GHC_FS_API bool operator<=(const path& lhs, const path& rhs) noexcept; +GHC_FS_API bool operator>(const path& lhs, const path& rhs) noexcept; +GHC_FS_API bool operator>=(const path& lhs, const path& rhs) noexcept; +GHC_FS_API path operator/(const path& lhs, const path& rhs); + +// [fs.path.io] path inserter and extractor +template +std::basic_ostream& operator<<(std::basic_ostream& os, const path& p); +template +std::basic_istream& operator>>(std::basic_istream& is, path& p); + +// [pfs.path.factory] path factory functions +template > +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) +[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] +#endif +path u8path(const Source& source); +template +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) +[[deprecated("use ghc::filesystem::path::path() with std::u8string instead")]] +#endif +path u8path(InputIterator first, InputIterator last); + +// [fs.class.filesystem_error] class filesystem_error +class GHC_FS_API_CLASS filesystem_error : public std::system_error +{ +public: + filesystem_error(const std::string& what_arg, std::error_code ec); + filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec); + filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec); + const path& path1() const noexcept; + const path& path2() const noexcept; + const char* what() const noexcept override; + +private: + std::string _what_arg; + std::error_code _ec; + path _p1, _p2; +}; + +class GHC_FS_API_CLASS path::iterator +{ +public: + using value_type = const path; + using difference_type = std::ptrdiff_t; + using pointer = const path*; + using reference = const path&; + using iterator_category = std::bidirectional_iterator_tag; + + iterator(); + iterator(const path& p, const impl_string_type::const_iterator& pos); + iterator& operator++(); + iterator operator++(int); + iterator& operator--(); + iterator operator--(int); + bool operator==(const iterator& other) const; + bool operator!=(const iterator& other) const; + reference operator*() const; + pointer operator->() const; + +private: + friend class path; + impl_string_type::const_iterator increment(const impl_string_type::const_iterator& pos) const; + impl_string_type::const_iterator decrement(const impl_string_type::const_iterator& pos) const; + void updateCurrent(); + impl_string_type::const_iterator _first; + impl_string_type::const_iterator _last; + impl_string_type::const_iterator _prefix; + impl_string_type::const_iterator _root; + impl_string_type::const_iterator _iter; + path _current; +}; + +struct space_info +{ + uintmax_t capacity; + uintmax_t free; + uintmax_t available; +}; + +// [fs.enum] enumerations +// [fs.enum.file_type] +enum class file_type { + none, + not_found, + regular, + directory, + symlink, + block, + character, + fifo, + socket, + unknown, +}; + +// [fs.enum.perms] +enum class perms : uint16_t { + none = 0, + + owner_read = 0400, + owner_write = 0200, + owner_exec = 0100, + owner_all = 0700, + + group_read = 040, + group_write = 020, + group_exec = 010, + group_all = 070, + + others_read = 04, + others_write = 02, + others_exec = 01, + others_all = 07, + + all = 0777, + set_uid = 04000, + set_gid = 02000, + sticky_bit = 01000, + + mask = 07777, + unknown = 0xffff +}; + +// [fs.enum.perm.opts] +enum class perm_options : uint16_t { + replace = 3, + add = 1, + remove = 2, + nofollow = 4, +}; + +// [fs.enum.copy.opts] +enum class copy_options : uint16_t { + none = 0, + + skip_existing = 1, + overwrite_existing = 2, + update_existing = 4, + + recursive = 8, + + copy_symlinks = 0x10, + skip_symlinks = 0x20, + + directories_only = 0x40, + create_symlinks = 0x80, +#ifndef GHC_OS_WEB + create_hard_links = 0x100 +#endif +}; + +// [fs.enum.dir.opts] +enum class directory_options : uint16_t { + none = 0, + follow_directory_symlink = 1, + skip_permission_denied = 2, +}; + +// [fs.class.file_status] class file_status +class GHC_FS_API_CLASS file_status +{ +public: + // [fs.file_status.cons] constructors and destructor + file_status() noexcept; + explicit file_status(file_type ft, perms prms = perms::unknown) noexcept; + file_status(const file_status&) noexcept; + file_status(file_status&&) noexcept; + ~file_status(); + // assignments: + file_status& operator=(const file_status&) noexcept; + file_status& operator=(file_status&&) noexcept; + // [fs.file_status.mods] modifiers + void type(file_type ft) noexcept; + void permissions(perms prms) noexcept; + // [fs.file_status.obs] observers + file_type type() const noexcept; + perms permissions() const noexcept; + friend bool operator==(const file_status& lhs, const file_status& rhs) noexcept { return lhs.type() == rhs.type() && lhs.permissions() == rhs.permissions(); } + +private: + file_type _type; + perms _perms; +}; + +using file_time_type = std::chrono::time_point; + +// [fs.class.directory_entry] Class directory_entry +class GHC_FS_API_CLASS directory_entry +{ +public: + // [fs.dir.entry.cons] constructors and destructor + directory_entry() noexcept = default; + directory_entry(const directory_entry&) = default; + directory_entry(directory_entry&&) noexcept = default; +#ifdef GHC_WITH_EXCEPTIONS + explicit directory_entry(const path& p); +#endif + directory_entry(const path& p, std::error_code& ec); + ~directory_entry(); + + // assignments: + directory_entry& operator=(const directory_entry&) = default; + directory_entry& operator=(directory_entry&&) noexcept = default; + + // [fs.dir.entry.mods] modifiers +#ifdef GHC_WITH_EXCEPTIONS + void assign(const path& p); + void replace_filename(const path& p); + void refresh(); +#endif + void assign(const path& p, std::error_code& ec); + void replace_filename(const path& p, std::error_code& ec); + void refresh(std::error_code& ec) noexcept; + + // [fs.dir.entry.obs] observers + const filesystem::path& path() const noexcept; + operator const filesystem::path&() const noexcept; +#ifdef GHC_WITH_EXCEPTIONS + bool exists() const; + bool is_block_file() const; + bool is_character_file() const; + bool is_directory() const; + bool is_fifo() const; + bool is_other() const; + bool is_regular_file() const; + bool is_socket() const; + bool is_symlink() const; + uintmax_t file_size() const; + file_time_type last_write_time() const; + file_status status() const; + file_status symlink_status() const; +#endif + bool exists(std::error_code& ec) const noexcept; + bool is_block_file(std::error_code& ec) const noexcept; + bool is_character_file(std::error_code& ec) const noexcept; + bool is_directory(std::error_code& ec) const noexcept; + bool is_fifo(std::error_code& ec) const noexcept; + bool is_other(std::error_code& ec) const noexcept; + bool is_regular_file(std::error_code& ec) const noexcept; + bool is_socket(std::error_code& ec) const noexcept; + bool is_symlink(std::error_code& ec) const noexcept; + uintmax_t file_size(std::error_code& ec) const noexcept; + file_time_type last_write_time(std::error_code& ec) const noexcept; + file_status status(std::error_code& ec) const noexcept; + file_status symlink_status(std::error_code& ec) const noexcept; + +#ifndef GHC_OS_WEB +#ifdef GHC_WITH_EXCEPTIONS + uintmax_t hard_link_count() const; +#endif + uintmax_t hard_link_count(std::error_code& ec) const noexcept; +#endif + +#ifdef GHC_HAS_THREEWAY_COMP + std::strong_ordering operator<=>(const directory_entry& rhs) const noexcept; +#endif + bool operator<(const directory_entry& rhs) const noexcept; + bool operator==(const directory_entry& rhs) const noexcept; + bool operator!=(const directory_entry& rhs) const noexcept; + bool operator<=(const directory_entry& rhs) const noexcept; + bool operator>(const directory_entry& rhs) const noexcept; + bool operator>=(const directory_entry& rhs) const noexcept; + +private: + friend class directory_iterator; +#ifdef GHC_WITH_EXCEPTIONS + file_type status_file_type() const; +#endif + file_type status_file_type(std::error_code& ec) const noexcept; + filesystem::path _path; + file_status _status; + file_status _symlink_status; + uintmax_t _file_size = static_cast(-1); +#ifndef GHC_OS_WINDOWS + uintmax_t _hard_link_count = static_cast(-1); +#endif + time_t _last_write_time = 0; +}; + +// [fs.class.directory.iterator] Class directory_iterator +class GHC_FS_API_CLASS directory_iterator +{ +public: + class GHC_FS_API_CLASS proxy + { + public: + const directory_entry& operator*() const& noexcept { return _dir_entry; } + directory_entry operator*() && noexcept { return std::move(_dir_entry); } + + private: + explicit proxy(const directory_entry& dir_entry) + : _dir_entry(dir_entry) + { + } + friend class directory_iterator; + friend class recursive_directory_iterator; + directory_entry _dir_entry; + }; + using iterator_category = std::input_iterator_tag; + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = const directory_entry*; + using reference = const directory_entry&; + + // [fs.dir.itr.members] member functions + directory_iterator() noexcept; +#ifdef GHC_WITH_EXCEPTIONS + explicit directory_iterator(const path& p); + directory_iterator(const path& p, directory_options options); +#endif + directory_iterator(const path& p, std::error_code& ec) noexcept; + directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; + directory_iterator(const directory_iterator& rhs); + directory_iterator(directory_iterator&& rhs) noexcept; + ~directory_iterator(); + directory_iterator& operator=(const directory_iterator& rhs); + directory_iterator& operator=(directory_iterator&& rhs) noexcept; + const directory_entry& operator*() const; + const directory_entry* operator->() const; +#ifdef GHC_WITH_EXCEPTIONS + directory_iterator& operator++(); +#endif + directory_iterator& increment(std::error_code& ec) noexcept; + + // other members as required by [input.iterators] +#ifdef GHC_WITH_EXCEPTIONS + proxy operator++(int) + { + proxy p{**this}; + ++*this; + return p; + } +#endif + bool operator==(const directory_iterator& rhs) const; + bool operator!=(const directory_iterator& rhs) const; + +private: + friend class recursive_directory_iterator; + class impl; + std::shared_ptr _impl; +}; + +// [fs.dir.itr.nonmembers] directory_iterator non-member functions +GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept; +GHC_FS_API directory_iterator end(const directory_iterator&) noexcept; + +// [fs.class.re.dir.itr] class recursive_directory_iterator +class GHC_FS_API_CLASS recursive_directory_iterator +{ +public: + using iterator_category = std::input_iterator_tag; + using value_type = directory_entry; + using difference_type = std::ptrdiff_t; + using pointer = const directory_entry*; + using reference = const directory_entry&; + + // [fs.rec.dir.itr.members] constructors and destructor + recursive_directory_iterator() noexcept; +#ifdef GHC_WITH_EXCEPTIONS + explicit recursive_directory_iterator(const path& p); + recursive_directory_iterator(const path& p, directory_options options); +#endif + recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept; + recursive_directory_iterator(const path& p, std::error_code& ec) noexcept; + recursive_directory_iterator(const recursive_directory_iterator& rhs); + recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept; + ~recursive_directory_iterator(); + + // [fs.rec.dir.itr.members] observers + directory_options options() const; + int depth() const; + bool recursion_pending() const; + + const directory_entry& operator*() const; + const directory_entry* operator->() const; + + // [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& + recursive_directory_iterator& operator=(const recursive_directory_iterator& rhs); + recursive_directory_iterator& operator=(recursive_directory_iterator&& rhs) noexcept; +#ifdef GHC_WITH_EXCEPTIONS + recursive_directory_iterator& operator++(); +#endif + recursive_directory_iterator& increment(std::error_code& ec) noexcept; + +#ifdef GHC_WITH_EXCEPTIONS + void pop(); +#endif + void pop(std::error_code& ec); + void disable_recursion_pending(); + + // other members as required by [input.iterators] +#ifdef GHC_WITH_EXCEPTIONS + directory_iterator::proxy operator++(int) + { + directory_iterator::proxy proxy{**this}; + ++*this; + return proxy; + } +#endif + bool operator==(const recursive_directory_iterator& rhs) const; + bool operator!=(const recursive_directory_iterator& rhs) const; + +private: + struct recursive_directory_iterator_impl + { + directory_options _options; + bool _recursion_pending; + std::stack _dir_iter_stack; + recursive_directory_iterator_impl(directory_options options, bool recursion_pending) + : _options(options) + , _recursion_pending(recursion_pending) + { + } + }; + std::shared_ptr _impl; +}; + +// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions +GHC_FS_API recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept; +GHC_FS_API recursive_directory_iterator end(const recursive_directory_iterator&) noexcept; + +// [fs.op.funcs] filesystem operations +#ifdef GHC_WITH_EXCEPTIONS +GHC_FS_API path absolute(const path& p); +GHC_FS_API path canonical(const path& p); +GHC_FS_API void copy(const path& from, const path& to); +GHC_FS_API void copy(const path& from, const path& to, copy_options options); +GHC_FS_API bool copy_file(const path& from, const path& to); +GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option); +GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink); +GHC_FS_API bool create_directories(const path& p); +GHC_FS_API bool create_directory(const path& p); +GHC_FS_API bool create_directory(const path& p, const path& attributes); +GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink); +GHC_FS_API void create_symlink(const path& to, const path& new_symlink); +GHC_FS_API path current_path(); +GHC_FS_API void current_path(const path& p); +GHC_FS_API bool exists(const path& p); +GHC_FS_API bool equivalent(const path& p1, const path& p2); +GHC_FS_API uintmax_t file_size(const path& p); +GHC_FS_API bool is_block_file(const path& p); +GHC_FS_API bool is_character_file(const path& p); +GHC_FS_API bool is_directory(const path& p); +GHC_FS_API bool is_empty(const path& p); +GHC_FS_API bool is_fifo(const path& p); +GHC_FS_API bool is_other(const path& p); +GHC_FS_API bool is_regular_file(const path& p); +GHC_FS_API bool is_socket(const path& p); +GHC_FS_API bool is_symlink(const path& p); +GHC_FS_API file_time_type last_write_time(const path& p); +GHC_FS_API void last_write_time(const path& p, file_time_type new_time); +GHC_FS_API void permissions(const path& p, perms prms, perm_options opts = perm_options::replace); +GHC_FS_API path proximate(const path& p, const path& base = current_path()); +GHC_FS_API path read_symlink(const path& p); +GHC_FS_API path relative(const path& p, const path& base = current_path()); +GHC_FS_API bool remove(const path& p); +GHC_FS_API uintmax_t remove_all(const path& p); +GHC_FS_API void rename(const path& from, const path& to); +GHC_FS_API void resize_file(const path& p, uintmax_t size); +GHC_FS_API space_info space(const path& p); +GHC_FS_API file_status status(const path& p); +GHC_FS_API file_status symlink_status(const path& p); +GHC_FS_API path temp_directory_path(); +GHC_FS_API path weakly_canonical(const path& p); +#endif +GHC_FS_API path absolute(const path& p, std::error_code& ec); +GHC_FS_API path canonical(const path& p, std::error_code& ec); +GHC_FS_API void copy(const path& from, const path& to, std::error_code& ec) noexcept; +GHC_FS_API void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept; +GHC_FS_API bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept; +GHC_FS_API bool copy_file(const path& from, const path& to, copy_options option, std::error_code& ec) noexcept; +GHC_FS_API void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept; +GHC_FS_API bool create_directories(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool create_directory(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept; +GHC_FS_API void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; +GHC_FS_API void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept; +GHC_FS_API path current_path(std::error_code& ec); +GHC_FS_API void current_path(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool exists(file_status s) noexcept; +GHC_FS_API bool exists(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept; +GHC_FS_API uintmax_t file_size(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_block_file(file_status s) noexcept; +GHC_FS_API bool is_block_file(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_character_file(file_status s) noexcept; +GHC_FS_API bool is_character_file(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_directory(file_status s) noexcept; +GHC_FS_API bool is_directory(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_empty(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_fifo(file_status s) noexcept; +GHC_FS_API bool is_fifo(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_other(file_status s) noexcept; +GHC_FS_API bool is_other(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_regular_file(file_status s) noexcept; +GHC_FS_API bool is_regular_file(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_socket(file_status s) noexcept; +GHC_FS_API bool is_socket(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool is_symlink(file_status s) noexcept; +GHC_FS_API bool is_symlink(const path& p, std::error_code& ec) noexcept; +GHC_FS_API file_time_type last_write_time(const path& p, std::error_code& ec) noexcept; +GHC_FS_API void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept; +GHC_FS_API void permissions(const path& p, perms prms, std::error_code& ec) noexcept; +GHC_FS_API void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept; +GHC_FS_API path proximate(const path& p, std::error_code& ec); +GHC_FS_API path proximate(const path& p, const path& base, std::error_code& ec); +GHC_FS_API path read_symlink(const path& p, std::error_code& ec); +GHC_FS_API path relative(const path& p, std::error_code& ec); +GHC_FS_API path relative(const path& p, const path& base, std::error_code& ec); +GHC_FS_API bool remove(const path& p, std::error_code& ec) noexcept; +GHC_FS_API uintmax_t remove_all(const path& p, std::error_code& ec) noexcept; +GHC_FS_API void rename(const path& from, const path& to, std::error_code& ec) noexcept; +GHC_FS_API void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept; +GHC_FS_API space_info space(const path& p, std::error_code& ec) noexcept; +GHC_FS_API file_status status(const path& p, std::error_code& ec) noexcept; +GHC_FS_API bool status_known(file_status s) noexcept; +GHC_FS_API file_status symlink_status(const path& p, std::error_code& ec) noexcept; +GHC_FS_API path temp_directory_path(std::error_code& ec) noexcept; +GHC_FS_API path weakly_canonical(const path& p, std::error_code& ec) noexcept; + +#ifndef GHC_OS_WEB +#ifdef GHC_WITH_EXCEPTIONS +GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link); +GHC_FS_API uintmax_t hard_link_count(const path& p); +#endif +GHC_FS_API void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept; +GHC_FS_API uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept; +#endif + +// Non-C++17 add-on std::fstream wrappers with path +template > +class basic_filebuf : public std::basic_filebuf +{ +public: + basic_filebuf() {} + ~basic_filebuf() override {} + basic_filebuf(const basic_filebuf&) = delete; + const basic_filebuf& operator=(const basic_filebuf&) = delete; + basic_filebuf* open(const path& p, std::ios_base::openmode mode) + { +#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) + return std::basic_filebuf::open(p.wstring().c_str(), mode) ? this : 0; +#else + return std::basic_filebuf::open(p.string().c_str(), mode) ? this : 0; +#endif + } +}; + +template > +class basic_ifstream : public std::basic_ifstream +{ +public: + basic_ifstream() {} +#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) + explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) + : std::basic_ifstream(p.wstring().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.wstring().c_str(), mode); } +#else + explicit basic_ifstream(const path& p, std::ios_base::openmode mode = std::ios_base::in) + : std::basic_ifstream(p.string().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::in) { std::basic_ifstream::open(p.string().c_str(), mode); } +#endif + basic_ifstream(const basic_ifstream&) = delete; + const basic_ifstream& operator=(const basic_ifstream&) = delete; + ~basic_ifstream() override {} +}; + +template > +class basic_ofstream : public std::basic_ofstream +{ +public: + basic_ofstream() {} +#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) + explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) + : std::basic_ofstream(p.wstring().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.wstring().c_str(), mode); } +#else + explicit basic_ofstream(const path& p, std::ios_base::openmode mode = std::ios_base::out) + : std::basic_ofstream(p.string().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::out) { std::basic_ofstream::open(p.string().c_str(), mode); } +#endif + basic_ofstream(const basic_ofstream&) = delete; + const basic_ofstream& operator=(const basic_ofstream&) = delete; + ~basic_ofstream() override {} +}; + +template > +class basic_fstream : public std::basic_fstream +{ +public: + basic_fstream() {} +#if defined(GHC_OS_WINDOWS) && !defined(__GLIBCXX__) + explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) + : std::basic_fstream(p.wstring().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.wstring().c_str(), mode); } +#else + explicit basic_fstream(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) + : std::basic_fstream(p.string().c_str(), mode) + { + } + void open(const path& p, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { std::basic_fstream::open(p.string().c_str(), mode); } +#endif + basic_fstream(const basic_fstream&) = delete; + const basic_fstream& operator=(const basic_fstream&) = delete; + ~basic_fstream() override {} +}; + +typedef basic_filebuf filebuf; +typedef basic_filebuf wfilebuf; +typedef basic_ifstream ifstream; +typedef basic_ifstream wifstream; +typedef basic_ofstream ofstream; +typedef basic_ofstream wofstream; +typedef basic_fstream fstream; +typedef basic_fstream wfstream; + +class GHC_FS_API_CLASS u8arguments +{ +public: + u8arguments(int& argc, char**& argv); + ~u8arguments() + { + _refargc = _argc; + _refargv = _argv; + } + + bool valid() const { return _isvalid; } + +private: + int _argc; + char** _argv; + int& _refargc; + char**& _refargv; + bool _isvalid; +#ifdef GHC_OS_WINDOWS + std::vector _args; + std::vector _argp; +#endif +}; + +//------------------------------------------------------------------------------------------------- +// Implementation +//------------------------------------------------------------------------------------------------- + +namespace detail { +enum utf8_states_t { S_STRT = 0, S_RJCT = 8 }; +GHC_FS_API void appendUTF8(std::string& str, uint32_t unicode); +GHC_FS_API bool is_surrogate(uint32_t c); +GHC_FS_API bool is_high_surrogate(uint32_t c); +GHC_FS_API bool is_low_surrogate(uint32_t c); +GHC_FS_API unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint); +enum class portable_error { + none = 0, + exists, + not_found, + not_supported, + not_implemented, + invalid_argument, + is_a_directory, +}; +GHC_FS_API std::error_code make_error_code(portable_error err); +#ifdef GHC_OS_WINDOWS +GHC_FS_API std::error_code make_system_error(uint32_t err = 0); +#else +GHC_FS_API std::error_code make_system_error(int err = 0); + +template +struct has_d_type : std::false_type{}; + +template +struct has_d_type : std::true_type {}; + +template +GHC_INLINE file_type file_type_from_dirent_impl(const T&, std::false_type) +{ + return file_type::none; +} + +template +GHC_INLINE file_type file_type_from_dirent_impl(const T& t, std::true_type) +{ + switch (t.d_type) { +#ifdef DT_BLK + case DT_BLK: + return file_type::block; +#endif +#ifdef DT_CHR + case DT_CHR: + return file_type::character; +#endif +#ifdef DT_DIR + case DT_DIR: + return file_type::directory; +#endif +#ifdef DT_FIFO + case DT_FIFO: + return file_type::fifo; +#endif +#ifdef DT_LNK + case DT_LNK: + return file_type::symlink; +#endif +#ifdef DT_REG + case DT_REG: + return file_type::regular; +#endif +#ifdef DT_SOCK + case DT_SOCK: + return file_type::socket; +#endif +#ifdef DT_UNKNOWN + case DT_UNKNOWN: + return file_type::none; +#endif + default: + return file_type::unknown; + } +} + +template +GHC_INLINE file_type file_type_from_dirent(const T& t) +{ + return file_type_from_dirent_impl(t, has_d_type{}); +} +#endif +} // namespace detail + +namespace detail { + +#ifdef GHC_EXPAND_IMPL + +GHC_INLINE std::error_code make_error_code(portable_error err) +{ +#ifdef GHC_OS_WINDOWS + switch (err) { + case portable_error::none: + return std::error_code(); + case portable_error::exists: + return std::error_code(ERROR_ALREADY_EXISTS, std::system_category()); + case portable_error::not_found: + return std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()); + case portable_error::not_supported: + return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); + case portable_error::not_implemented: + return std::error_code(ERROR_CALL_NOT_IMPLEMENTED, std::system_category()); + case portable_error::invalid_argument: + return std::error_code(ERROR_INVALID_PARAMETER, std::system_category()); + case portable_error::is_a_directory: +#ifdef ERROR_DIRECTORY_NOT_SUPPORTED + return std::error_code(ERROR_DIRECTORY_NOT_SUPPORTED, std::system_category()); +#else + return std::error_code(ERROR_NOT_SUPPORTED, std::system_category()); +#endif + } +#else + switch (err) { + case portable_error::none: + return std::error_code(); + case portable_error::exists: + return std::error_code(EEXIST, std::system_category()); + case portable_error::not_found: + return std::error_code(ENOENT, std::system_category()); + case portable_error::not_supported: + return std::error_code(ENOTSUP, std::system_category()); + case portable_error::not_implemented: + return std::error_code(ENOSYS, std::system_category()); + case portable_error::invalid_argument: + return std::error_code(EINVAL, std::system_category()); + case portable_error::is_a_directory: + return std::error_code(EISDIR, std::system_category()); + } +#endif + return std::error_code(); +} + +#ifdef GHC_OS_WINDOWS +GHC_INLINE std::error_code make_system_error(uint32_t err) +{ + return std::error_code(err ? static_cast(err) : static_cast(::GetLastError()), std::system_category()); +} +#else +GHC_INLINE std::error_code make_system_error(int err) +{ + return std::error_code(err ? err : errno, std::system_category()); +} +#endif + +#endif // GHC_EXPAND_IMPL + +template +using EnableBitmask = typename std::enable_if::value || std::is_same::value || std::is_same::value || std::is_same::value, Enum>::type; +} // namespace detail + +template +constexpr detail::EnableBitmask operator&(Enum X, Enum Y) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(X) & static_cast(Y)); +} + +template +constexpr detail::EnableBitmask operator|(Enum X, Enum Y) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(X) | static_cast(Y)); +} + +template +constexpr detail::EnableBitmask operator^(Enum X, Enum Y) +{ + using underlying = typename std::underlying_type::type; + return static_cast(static_cast(X) ^ static_cast(Y)); +} + +template +constexpr detail::EnableBitmask operator~(Enum X) +{ + using underlying = typename std::underlying_type::type; + return static_cast(~static_cast(X)); +} + +template +detail::EnableBitmask& operator&=(Enum& X, Enum Y) +{ + X = X & Y; + return X; +} + +template +detail::EnableBitmask& operator|=(Enum& X, Enum Y) +{ + X = X | Y; + return X; +} + +template +detail::EnableBitmask& operator^=(Enum& X, Enum Y) +{ + X = X ^ Y; + return X; +} + +#ifdef GHC_EXPAND_IMPL + +namespace detail { + +GHC_INLINE bool in_range(uint32_t c, uint32_t lo, uint32_t hi) +{ + return (static_cast(c - lo) < (hi - lo + 1)); +} + +GHC_INLINE bool is_surrogate(uint32_t c) +{ + return in_range(c, 0xd800, 0xdfff); +} + +GHC_INLINE bool is_high_surrogate(uint32_t c) +{ + return (c & 0xfffffc00) == 0xd800; +} + +GHC_INLINE bool is_low_surrogate(uint32_t c) +{ + return (c & 0xfffffc00) == 0xdc00; +} + +GHC_INLINE void appendUTF8(std::string& str, uint32_t unicode) +{ + if (unicode <= 0x7f) { + str.push_back(static_cast(unicode)); + } + else if (unicode >= 0x80 && unicode <= 0x7ff) { + str.push_back(static_cast((unicode >> 6) + 192)); + str.push_back(static_cast((unicode & 0x3f) + 128)); + } + else if ((unicode >= 0x800 && unicode <= 0xd7ff) || (unicode >= 0xe000 && unicode <= 0xffff)) { + str.push_back(static_cast((unicode >> 12) + 224)); + str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); + str.push_back(static_cast((unicode & 0x3f) + 128)); + } + else if (unicode >= 0x10000 && unicode <= 0x10ffff) { + str.push_back(static_cast((unicode >> 18) + 240)); + str.push_back(static_cast(((unicode & 0x3ffff) >> 12) + 128)); + str.push_back(static_cast(((unicode & 0xfff) >> 6) + 128)); + str.push_back(static_cast((unicode & 0x3f) + 128)); + } + else { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal code point for unicode character.", str, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + appendUTF8(str, 0xfffd); +#endif + } +} + +// Thanks to Bjoern Hoehrmann (https://bjoern.hoehrmann.de/utf-8/decoder/dfa/) +// and Taylor R Campbell for the ideas to this DFA approach of UTF-8 decoding; +// Generating debugging and shrinking my own DFA from scratch was a day of fun! +GHC_INLINE unsigned consumeUtf8Fragment(const unsigned state, const uint8_t fragment, uint32_t& codepoint) +{ + static const uint32_t utf8_state_info[] = { + // encoded states + 0x11111111u, 0x11111111u, 0x77777777u, 0x77777777u, 0x88888888u, 0x88888888u, 0x88888888u, 0x88888888u, 0x22222299u, 0x22222222u, 0x22222222u, 0x22222222u, 0x3333333au, 0x33433333u, 0x9995666bu, 0x99999999u, + 0x88888880u, 0x22818108u, 0x88888881u, 0x88888882u, 0x88888884u, 0x88888887u, 0x88888886u, 0x82218108u, 0x82281108u, 0x88888888u, 0x88888883u, 0x88888885u, 0u, 0u, 0u, 0u, + }; + uint8_t category = fragment < 128 ? 0 : (utf8_state_info[(fragment >> 3) & 0xf] >> ((fragment & 7) << 2)) & 0xf; + codepoint = (state ? (codepoint << 6) | (fragment & 0x3fu) : (0xffu >> category) & fragment); + return state == S_RJCT ? static_cast(S_RJCT) : static_cast((utf8_state_info[category + 16] >> (state << 2)) & 0xf); +} + +GHC_INLINE bool validUtf8(const std::string& utf8String) +{ + std::string::const_iterator iter = utf8String.begin(); + unsigned utf8_state = S_STRT; + std::uint32_t codepoint = 0; + while (iter < utf8String.end()) { + if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_RJCT) { + return false; + } + } + if (utf8_state) { + return false; + } + return true; +} + +} // namespace detail + +#endif + +namespace detail { + +template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 1)>::type* = nullptr> +inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + return StringType(utf8String.begin(), utf8String.end(), alloc); +} + +template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 2)>::type* = nullptr> +inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + StringType result(alloc); + result.reserve(utf8String.length()); + auto iter = utf8String.cbegin(); + unsigned utf8_state = S_STRT; + std::uint32_t codepoint = 0; + while (iter < utf8String.cend()) { + if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { + if (codepoint <= 0xffff) { + result += static_cast(codepoint); + } + else { + codepoint -= 0x10000; + result += static_cast((codepoint >> 10) + 0xd800); + result += static_cast((codepoint & 0x3ff) + 0xdc00); + } + codepoint = 0; + } + else if (utf8_state == S_RJCT) { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + result += static_cast(0xfffd); + utf8_state = S_STRT; + codepoint = 0; +#endif + } + } + if (utf8_state) { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + result += static_cast(0xfffd); +#endif + } + return result; +} + +template ::value && (sizeof(typename Utf8String::value_type) == 1) && (sizeof(typename StringType::value_type) == 4)>::type* = nullptr> +inline StringType fromUtf8(const Utf8String& utf8String, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + StringType result(alloc); + result.reserve(utf8String.length()); + auto iter = utf8String.cbegin(); + unsigned utf8_state = S_STRT; + std::uint32_t codepoint = 0; + while (iter < utf8String.cend()) { + if ((utf8_state = consumeUtf8Fragment(utf8_state, static_cast(*iter++), codepoint)) == S_STRT) { + result += static_cast(codepoint); + codepoint = 0; + } + else if (utf8_state == S_RJCT) { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + result += static_cast(0xfffd); + utf8_state = S_STRT; + codepoint = 0; +#endif + } + } + if (utf8_state) { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal byte sequence for unicode character.", utf8String, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + result += static_cast(0xfffd); +#endif + } + return result; +} + +template +inline StringType fromUtf8(const charT (&utf8String)[N]) +{ +#ifdef GHC_WITH_STRING_VIEW + return fromUtf8(basic_string_view(utf8String, N - 1)); +#else + return fromUtf8(std::basic_string(utf8String, N - 1)); +#endif +} + +template ::value && (sizeof(typename strT::value_type) == 1), int>::type size = 1> +inline std::string toUtf8(const strT& unicodeString) +{ + return std::string(unicodeString.begin(), unicodeString.end()); +} + +template ::value && (sizeof(typename strT::value_type) == 2), int>::type size = 2> +inline std::string toUtf8(const strT& unicodeString) +{ + std::string result; + for (auto iter = unicodeString.begin(); iter != unicodeString.end(); ++iter) { + char32_t c = *iter; + if (is_surrogate(c)) { + ++iter; + if (iter != unicodeString.end() && is_high_surrogate(c) && is_low_surrogate(*iter)) { + appendUTF8(result, (char32_t(c) << 10) + *iter - 0x35fdc00); + } + else { +#ifdef GHC_RAISE_UNICODE_ERRORS + throw filesystem_error("Illegal code point for unicode character.", result, std::make_error_code(std::errc::illegal_byte_sequence)); +#else + appendUTF8(result, 0xfffd); + if (iter == unicodeString.end()) { + break; + } +#endif + } + } + else { + appendUTF8(result, c); + } + } + return result; +} + +template ::value && (sizeof(typename strT::value_type) == 4), int>::type size = 4> +inline std::string toUtf8(const strT& unicodeString) +{ + std::string result; + for (auto c : unicodeString) { + appendUTF8(result, static_cast(c)); + } + return result; +} + +template +inline std::string toUtf8(const charT* unicodeString) +{ +#ifdef GHC_WITH_STRING_VIEW + return toUtf8(basic_string_view>(unicodeString)); +#else + return toUtf8(std::basic_string>(unicodeString)); +#endif +} + +#ifdef GHC_USE_WCHAR_T +template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 1), bool>::type = false> +inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + auto temp = toUtf8(wString); + return StringType(temp.begin(), temp.end(), alloc); +} + +template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 2), bool>::type = false> +inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + return StringType(wString.begin(), wString.end(), alloc); +} + +template ::value && (sizeof(typename WString::value_type) == 2) && (sizeof(typename StringType::value_type) == 4), bool>::type = false> +inline StringType fromWChar(const WString& wString, const typename StringType::allocator_type& alloc = typename StringType::allocator_type()) +{ + auto temp = toUtf8(wString); + return fromUtf8(temp, alloc); +} + +template ::value && (sizeof(typename strT::value_type) == 1), bool>::type = false> +inline std::wstring toWChar(const strT& unicodeString) +{ + return fromUtf8(unicodeString); +} + +template ::value && (sizeof(typename strT::value_type) == 2), bool>::type = false> +inline std::wstring toWChar(const strT& unicodeString) +{ + return std::wstring(unicodeString.begin(), unicodeString.end()); +} + +template ::value && (sizeof(typename strT::value_type) == 4), bool>::type = false> +inline std::wstring toWChar(const strT& unicodeString) +{ + auto temp = toUtf8(unicodeString); + return fromUtf8(temp); +} + +template +inline std::wstring toWChar(const charT* unicodeString) +{ +#ifdef GHC_WITH_STRING_VIEW + return toWChar(basic_string_view>(unicodeString)); +#else + return toWChar(std::basic_string>(unicodeString)); +#endif +} +#endif // GHC_USE_WCHAR_T + +} // namespace detail + +#ifdef GHC_EXPAND_IMPL + +namespace detail { + +template ::value, bool>::type = true> +GHC_INLINE bool startsWith(const strT& what, const strT& with) +{ + return with.length() <= what.length() && equal(with.begin(), with.end(), what.begin()); +} + +template ::value, bool>::type = true> +GHC_INLINE bool endsWith(const strT& what, const strT& with) +{ + return with.length() <= what.length() && what.compare(what.length() - with.length(), with.size(), with) == 0; +} + +} // namespace detail + +GHC_INLINE void path::check_long_path() +{ +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { + postprocess_path_with_format(native_format); + } +#endif +} + +GHC_INLINE void path::postprocess_path_with_format(path::format fmt) +{ +#ifdef GHC_RAISE_UNICODE_ERRORS + if (!detail::validUtf8(_path)) { + path t; + t._path = _path; + throw filesystem_error("Illegal byte sequence for unicode character.", t, std::make_error_code(std::errc::illegal_byte_sequence)); + } +#endif + switch (fmt) { +#ifdef GHC_OS_WINDOWS + case path::native_format: + case path::auto_format: + case path::generic_format: + for (auto& c : _path) { + if (c == generic_separator) { + c = preferred_separator; + } + } +#ifdef GHC_WIN_AUTO_PREFIX_LONG_PATH + if (is_absolute() && _path.length() >= MAX_PATH - 12 && !detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\")))) { + _path = GHC_PLATFORM_LITERAL("\\\\?\\") + _path; + } +#endif + handle_prefixes(); + break; +#else + case path::auto_format: + case path::native_format: + case path::generic_format: + // nothing to do + break; +#endif + } + if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator) { + impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength) + 2, _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); + _path.erase(new_end, _path.end()); + } + else { + impl_string_type::iterator new_end = std::unique(_path.begin() + static_cast(_prefixLength), _path.end(), [](path::value_type lhs, path::value_type rhs) { return lhs == rhs && lhs == preferred_separator; }); + _path.erase(new_end, _path.end()); + } +} + +#endif // GHC_EXPAND_IMPL + +template +inline path::path(const Source& source, format fmt) +#ifdef GHC_USE_WCHAR_T + : _path(detail::toWChar(source)) +#else + : _path(detail::toUtf8(source)) +#endif +{ + postprocess_path_with_format(fmt); +} + +template +inline path u8path(const Source& source) +{ + return path(source); +} +template +inline path u8path(InputIterator first, InputIterator last) +{ + return path(first, last); +} + +template +inline path::path(InputIterator first, InputIterator last, format fmt) + : path(std::basic_string::value_type>(first, last), fmt) +{ + // delegated +} + +#ifdef GHC_EXPAND_IMPL + +namespace detail { + +GHC_INLINE bool equals_simple_insensitive(const path::value_type* str1, const path::value_type* str2) +{ +#ifdef GHC_OS_WINDOWS +#ifdef __GNUC__ + while (::tolower((unsigned char)*str1) == ::tolower((unsigned char)*str2++)) { + if (*str1++ == 0) + return true; + } + return false; +#else // __GNUC__ +#ifdef GHC_USE_WCHAR_T + return 0 == ::_wcsicmp(str1, str2); +#else // GHC_USE_WCHAR_T + return 0 == ::_stricmp(str1, str2); +#endif // GHC_USE_WCHAR_T +#endif // __GNUC__ +#else // GHC_OS_WINDOWS + return 0 == ::strcasecmp(str1, str2); +#endif // GHC_OS_WINDOWS +} + +GHC_INLINE int compare_simple_insensitive(const path::value_type* str1, size_t len1, const path::value_type* str2, size_t len2) +{ + while (len1 > 0 && len2 > 0 && ::tolower(static_cast(*str1)) == ::tolower(static_cast(*str2))) { + --len1; + --len2; + ++str1; + ++str2; + } + if (len1 && len2) { + return *str1 < *str2 ? -1 : 1; + } + if (len1 == 0 && len2 == 0) { + return 0; + } + return len1 == 0 ? -1 : 1; +} + +GHC_INLINE const char* strerror_adapter(char* gnu, char*) +{ + return gnu; +} + +GHC_INLINE const char* strerror_adapter(int posix, char* buffer) +{ + if (posix) { + return "Error in strerror_r!"; + } + return buffer; +} + +template +GHC_INLINE std::string systemErrorText(ErrorNumber code = 0) +{ +#if defined(GHC_OS_WINDOWS) + LPVOID msgBuf; + DWORD dw = code ? static_cast(code) : ::GetLastError(); + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&msgBuf, 0, NULL); + std::string msg = toUtf8(std::wstring((LPWSTR)msgBuf)); + LocalFree(msgBuf); + return msg; +#else + char buffer[512]; + return strerror_adapter(strerror_r(code ? code : errno, buffer, sizeof(buffer)), buffer); +#endif +} + +#ifdef GHC_OS_WINDOWS +using CreateSymbolicLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, DWORD); +using CreateHardLinkW_fp = BOOLEAN(WINAPI*)(LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES); + +GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool to_directory, std::error_code& ec) +{ + std::error_code tec; + auto fs = status(target_name, tec); + if ((fs.type() == file_type::directory && !to_directory) || (fs.type() == file_type::regular && to_directory)) { + ec = detail::make_error_code(detail::portable_error::not_supported); + return; + } +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + static CreateSymbolicLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateSymbolicLinkW")); +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + if (api_call) { + if (api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 1 : 0) == 0) { + auto result = ::GetLastError(); + if (result == ERROR_PRIVILEGE_NOT_HELD && api_call(GHC_NATIVEWP(new_symlink), GHC_NATIVEWP(target_name), to_directory ? 3 : 2) != 0) { + return; + } + ec = detail::make_system_error(result); + } + } + else { + ec = detail::make_system_error(ERROR_NOT_SUPPORTED); + } +} + +GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) +{ +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + static CreateHardLinkW_fp api_call = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW")); +#if defined(__GNUC__) && __GNUC__ >= 8 +#pragma GCC diagnostic pop +#endif + if (api_call) { + if (api_call(GHC_NATIVEWP(new_hardlink), GHC_NATIVEWP(target_name), NULL) == 0) { + ec = detail::make_system_error(); + } + } + else { + ec = detail::make_system_error(ERROR_NOT_SUPPORTED); + } +} + +GHC_INLINE path getFullPathName(const wchar_t* p, std::error_code& ec) +{ + ULONG size = ::GetFullPathNameW(p, 0, 0, 0); + if (size) { + std::vector buf(size, 0); + ULONG s2 = GetFullPathNameW(p, size, buf.data(), nullptr); + if (s2 && s2 < size) { + return path(std::wstring(buf.data(), s2)); + } + } + ec = detail::make_system_error(); + return path(); +} + +#else +GHC_INLINE void create_symlink(const path& target_name, const path& new_symlink, bool, std::error_code& ec) +{ + if (::symlink(target_name.c_str(), new_symlink.c_str()) != 0) { + ec = detail::make_system_error(); + } +} + +#ifndef GHC_OS_WEB +GHC_INLINE void create_hardlink(const path& target_name, const path& new_hardlink, std::error_code& ec) +{ + if (::link(target_name.c_str(), new_hardlink.c_str()) != 0) { + ec = detail::make_system_error(); + } +} +#endif +#endif + +template +GHC_INLINE file_status file_status_from_st_mode(T mode) +{ +#ifdef GHC_OS_WINDOWS + file_type ft = file_type::unknown; + if ((mode & _S_IFDIR) == _S_IFDIR) { + ft = file_type::directory; + } + else if ((mode & _S_IFREG) == _S_IFREG) { + ft = file_type::regular; + } + else if ((mode & _S_IFCHR) == _S_IFCHR) { + ft = file_type::character; + } + perms prms = static_cast(mode & 0xfff); + return file_status(ft, prms); +#else + file_type ft = file_type::unknown; + if (S_ISDIR(mode)) { + ft = file_type::directory; + } + else if (S_ISREG(mode)) { + ft = file_type::regular; + } + else if (S_ISCHR(mode)) { + ft = file_type::character; + } + else if (S_ISBLK(mode)) { + ft = file_type::block; + } + else if (S_ISFIFO(mode)) { + ft = file_type::fifo; + } + else if (S_ISLNK(mode)) { + ft = file_type::symlink; + } + else if (S_ISSOCK(mode)) { + ft = file_type::socket; + } + perms prms = static_cast(mode & 0xfff); + return file_status(ft, prms); +#endif +} + +#ifdef GHC_OS_WINDOWS + +class unique_handle +{ +public: + typedef HANDLE element_type; + + unique_handle() noexcept + : _handle(INVALID_HANDLE_VALUE) + { + } + explicit unique_handle(element_type h) noexcept + : _handle(h) + { + } + unique_handle(unique_handle&& u) noexcept + : _handle(u.release()) + { + } + ~unique_handle() { reset(); } + unique_handle& operator=(unique_handle&& u) noexcept + { + reset(u.release()); + return *this; + } + element_type get() const noexcept { return _handle; } + explicit operator bool() const noexcept { return _handle != INVALID_HANDLE_VALUE; } + element_type release() noexcept + { + element_type tmp = _handle; + _handle = INVALID_HANDLE_VALUE; + return tmp; + } + void reset(element_type h = INVALID_HANDLE_VALUE) noexcept + { + element_type tmp = _handle; + _handle = h; + if (tmp != INVALID_HANDLE_VALUE) { + CloseHandle(tmp); + } + } + void swap(unique_handle& u) noexcept { std::swap(_handle, u._handle); } + +private: + element_type _handle; +}; + +#ifndef REPARSE_DATA_BUFFER_HEADER_SIZE +typedef struct _REPARSE_DATA_BUFFER +{ + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union + { + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct + { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + } DUMMYUNIONNAME; +} REPARSE_DATA_BUFFER; +#ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE +#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE (16 * 1024) +#endif +#endif + +template +struct free_deleter +{ + void operator()(T* p) const { std::free(p); } +}; + +GHC_INLINE std::unique_ptr> getReparseData(const path& p, std::error_code& ec) +{ + unique_handle file(CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0)); + if (!file) { + ec = detail::make_system_error(); + return nullptr; + } + + std::unique_ptr> reparseData(reinterpret_cast(std::calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE))); + ULONG bufferUsed; + if (DeviceIoControl(file.get(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseData.get(), MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bufferUsed, 0)) { + return reparseData; + } + else { + ec = detail::make_system_error(); + } + return nullptr; +} +#endif + +GHC_INLINE path resolveSymlink(const path& p, std::error_code& ec) +{ +#ifdef GHC_OS_WINDOWS + path result; + auto reparseData = detail::getReparseData(p, ec); + if (!ec) { + if (reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag)) { + switch (reparseData->ReparseTag) { + case IO_REPARSE_TAG_SYMLINK: { + auto printName = std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR)); + auto substituteName = + std::wstring(&reparseData->SymbolicLinkReparseBuffer.PathBuffer[reparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); + if (detail::endsWith(substituteName, printName) && detail::startsWith(substituteName, std::wstring(L"\\??\\"))) { + result = printName; + } + else { + result = substituteName; + } + if (reparseData->SymbolicLinkReparseBuffer.Flags & 0x1 /*SYMLINK_FLAG_RELATIVE*/) { + result = p.parent_path() / result; + } + break; + } + case IO_REPARSE_TAG_MOUNT_POINT: + result = detail::getFullPathName(GHC_NATIVEWP(p), ec); + // result = std::wstring(&reparseData->MountPointReparseBuffer.PathBuffer[reparseData->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], reparseData->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)); + break; + default: + break; + } + } + } + return result; +#else + size_t bufferSize = 256; + while (true) { + std::vector buffer(bufferSize, static_cast(0)); + auto rc = ::readlink(p.c_str(), buffer.data(), buffer.size()); + if (rc < 0) { + ec = detail::make_system_error(); + return path(); + } + else if (rc < static_cast(bufferSize)) { + return path(std::string(buffer.data(), static_cast(rc))); + } + bufferSize *= 2; + } + return path(); +#endif +} + +#ifdef GHC_OS_WINDOWS +GHC_INLINE time_t timeFromFILETIME(const FILETIME& ft) +{ + ULARGE_INTEGER ull; + ull.LowPart = ft.dwLowDateTime; + ull.HighPart = ft.dwHighDateTime; + return static_cast(ull.QuadPart / 10000000ULL - 11644473600ULL); +} + +GHC_INLINE void timeToFILETIME(time_t t, FILETIME& ft) +{ + LONGLONG ll; + ll = Int32x32To64(t, 10000000) + 116444736000000000; + ft.dwLowDateTime = static_cast(ll); + ft.dwHighDateTime = static_cast(ll >> 32); +} + +template +GHC_INLINE uintmax_t hard_links_from_INFO(const INFO* info) +{ + return static_cast(-1); +} + +template <> +GHC_INLINE uintmax_t hard_links_from_INFO(const BY_HANDLE_FILE_INFORMATION* info) +{ + return info->nNumberOfLinks; +} + +template +GHC_INLINE DWORD reparse_tag_from_INFO(const INFO*) +{ + return 0; +} + +template <> +GHC_INLINE DWORD reparse_tag_from_INFO(const WIN32_FIND_DATAW* info) +{ + return info->dwReserved0; +} + +template +GHC_INLINE file_status status_from_INFO(const path& p, const INFO* info, std::error_code& ec, uintmax_t* sz = nullptr, time_t* lwt = nullptr) +{ + file_type ft = file_type::unknown; + if (sizeof(INFO) == sizeof(WIN32_FIND_DATAW)) { + if (detail::reparse_tag_from_INFO(info) == IO_REPARSE_TAG_SYMLINK) { + ft = file_type::symlink; + } + } + else { + if ((info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + auto reparseData = detail::getReparseData(p, ec); + if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + ft = file_type::symlink; + } + } + } + if (ft == file_type::unknown) { + if ((info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + ft = file_type::directory; + } + else { + ft = file_type::regular; + } + } + perms prms = perms::owner_read | perms::group_read | perms::others_read; + if (!(info->dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { + prms = prms | perms::owner_write | perms::group_write | perms::others_write; + } + if (has_executable_extension(p)) { + prms = prms | perms::owner_exec | perms::group_exec | perms::others_exec; + } + if (sz) { + *sz = static_cast(info->nFileSizeHigh) << (sizeof(info->nFileSizeHigh) * 8) | info->nFileSizeLow; + } + if (lwt) { + *lwt = detail::timeFromFILETIME(info->ftLastWriteTime); + } + return file_status(ft, prms); +} + +#endif + +GHC_INLINE bool is_not_found_error(std::error_code& ec) +{ +#ifdef GHC_OS_WINDOWS + return ec.value() == ERROR_FILE_NOT_FOUND || ec.value() == ERROR_PATH_NOT_FOUND || ec.value() == ERROR_INVALID_NAME; +#else + return ec.value() == ENOENT || ec.value() == ENOTDIR; +#endif +} + +GHC_INLINE file_status symlink_status_ex(const path& p, std::error_code& ec, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr) noexcept +{ +#ifdef GHC_OS_WINDOWS + file_status fs; + WIN32_FILE_ATTRIBUTE_DATA attr; + if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { + ec = detail::make_system_error(); + } + else { + ec.clear(); + fs = detail::status_from_INFO(p, &attr, ec, sz, lwt); + if (nhl) { + *nhl = 0; + } + } + if (detail::is_not_found_error(ec)) { + return file_status(file_type::not_found); + } + return ec ? file_status(file_type::none) : fs; +#else + (void)sz; + (void)nhl; + (void)lwt; + struct ::stat fs; + auto result = ::lstat(p.c_str(), &fs); + if (result == 0) { + ec.clear(); + file_status f_s = detail::file_status_from_st_mode(fs.st_mode); + return f_s; + } + ec = detail::make_system_error(); + if (detail::is_not_found_error(ec)) { + return file_status(file_type::not_found, perms::unknown); + } + return file_status(file_type::none); +#endif +} + +GHC_INLINE file_status status_ex(const path& p, std::error_code& ec, file_status* sls = nullptr, uintmax_t* sz = nullptr, uintmax_t* nhl = nullptr, time_t* lwt = nullptr, int recurse_count = 0) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + if (recurse_count > 16) { + ec = detail::make_system_error(0x2A9 /*ERROR_STOPPED_ON_SYMLINK*/); + return file_status(file_type::unknown); + } + WIN32_FILE_ATTRIBUTE_DATA attr; + if (!::GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { + ec = detail::make_system_error(); + } + else if (attr.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + auto reparseData = detail::getReparseData(p, ec); + if (!ec && reparseData && IsReparseTagMicrosoft(reparseData->ReparseTag) && reparseData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + path target = resolveSymlink(p, ec); + file_status result; + if (!ec && !target.empty()) { + if (sls) { + *sls = status_from_INFO(p, &attr, ec); + } + return detail::status_ex(target, ec, nullptr, sz, nhl, lwt, recurse_count + 1); + } + return file_status(file_type::unknown); + } + } + if (ec) { + if (detail::is_not_found_error(ec)) { + return file_status(file_type::not_found); + } + return file_status(file_type::none); + } + if (nhl) { + *nhl = 0; + } + return detail::status_from_INFO(p, &attr, ec, sz, lwt); +#else + (void)recurse_count; + struct ::stat st; + auto result = ::lstat(p.c_str(), &st); + if (result == 0) { + ec.clear(); + file_status fs = detail::file_status_from_st_mode(st.st_mode); + if (sls) { + *sls = fs; + } + if (fs.type() == file_type::symlink) { + result = ::stat(p.c_str(), &st); + if (result == 0) { + fs = detail::file_status_from_st_mode(st.st_mode); + } + else { + ec = detail::make_system_error(); + if (detail::is_not_found_error(ec)) { + return file_status(file_type::not_found, perms::unknown); + } + return file_status(file_type::none); + } + } + if (sz) { + *sz = static_cast(st.st_size); + } + if (nhl) { + *nhl = st.st_nlink; + } + if (lwt) { + *lwt = st.st_mtime; + } + return fs; + } + else { + ec = detail::make_system_error(); + if (detail::is_not_found_error(ec)) { + return file_status(file_type::not_found, perms::unknown); + } + return file_status(file_type::none); + } +#endif +} + +} // namespace detail + +GHC_INLINE u8arguments::u8arguments(int& argc, char**& argv) + : _argc(argc) + , _argv(argv) + , _refargc(argc) + , _refargv(argv) + , _isvalid(false) +{ +#ifdef GHC_OS_WINDOWS + LPWSTR* p; + p = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + _args.reserve(static_cast(argc)); + _argp.reserve(static_cast(argc)); + for (size_t i = 0; i < static_cast(argc); ++i) { + _args.push_back(detail::toUtf8(std::wstring(p[i]))); + _argp.push_back((char*)_args[i].data()); + } + argv = _argp.data(); + ::LocalFree(p); + _isvalid = true; +#else + std::setlocale(LC_ALL, ""); +#if defined(__ANDROID__) && __ANDROID_API__ < 26 + _isvalid = true; +#else + if (detail::equals_simple_insensitive(::nl_langinfo(CODESET), "UTF-8")) { + _isvalid = true; + } +#endif +#endif +} + +//----------------------------------------------------------------------------- +// [fs.path.construct] constructors and destructor + +GHC_INLINE path::path() noexcept {} + +GHC_INLINE path::path(const path& p) + : _path(p._path) +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + , _prefixLength(p._prefixLength) +#endif +{ +} + +GHC_INLINE path::path(path&& p) noexcept + : _path(std::move(p._path)) +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + , _prefixLength(p._prefixLength) +#endif +{ +} + +GHC_INLINE path::path(string_type&& source, format fmt) + : _path(std::move(source)) +{ + postprocess_path_with_format(fmt); +} + +#endif // GHC_EXPAND_IMPL + +#ifdef GHC_WITH_EXCEPTIONS +template +inline path::path(const Source& source, const std::locale& loc, format fmt) + : path(source, fmt) +{ + std::string locName = loc.name(); + if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { + throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); + } +} + +template +inline path::path(InputIterator first, InputIterator last, const std::locale& loc, format fmt) + : path(std::basic_string::value_type>(first, last), fmt) +{ + std::string locName = loc.name(); + if (!(locName.length() >= 5 && (locName.substr(locName.length() - 5) == "UTF-8" || locName.substr(locName.length() - 5) == "utf-8"))) { + throw filesystem_error("This implementation only supports UTF-8 locales!", path(_path), detail::make_error_code(detail::portable_error::not_supported)); + } +} +#endif + +#ifdef GHC_EXPAND_IMPL + +GHC_INLINE path::~path() {} + +//----------------------------------------------------------------------------- +// [fs.path.assign] assignments + +GHC_INLINE path& path::operator=(const path& p) +{ + _path = p._path; +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + _prefixLength = p._prefixLength; +#endif + return *this; +} + +GHC_INLINE path& path::operator=(path&& p) noexcept +{ + _path = std::move(p._path); +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + _prefixLength = p._prefixLength; +#endif + return *this; +} + +GHC_INLINE path& path::operator=(path::string_type&& source) +{ + return assign(source); +} + +GHC_INLINE path& path::assign(path::string_type&& source) +{ + _path = std::move(source); + postprocess_path_with_format(native_format); + return *this; +} + +#endif // GHC_EXPAND_IMPL + +template +inline path& path::operator=(const Source& source) +{ + return assign(source); +} + +template +inline path& path::assign(const Source& source) +{ +#ifdef GHC_USE_WCHAR_T + _path.assign(detail::toWChar(source)); +#else + _path.assign(detail::toUtf8(source)); +#endif + postprocess_path_with_format(native_format); + return *this; +} + +template <> +inline path& path::assign(const path& source) +{ + _path = source._path; +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + _prefixLength = source._prefixLength; +#endif + return *this; +} + +template +inline path& path::assign(InputIterator first, InputIterator last) +{ + _path.assign(first, last); + postprocess_path_with_format(native_format); + return *this; +} + +#ifdef GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.path.append] appends + +GHC_INLINE path& path::operator/=(const path& p) +{ + if (p.empty()) { + // was: if ((!has_root_directory() && is_absolute()) || has_filename()) + if (!_path.empty() && _path[_path.length() - 1] != preferred_separator && _path[_path.length() - 1] != ':') { + _path += preferred_separator; + } + return *this; + } + if ((p.is_absolute() && (_path != root_name()._path || p._path != "/")) || (p.has_root_name() && p.root_name() != root_name())) { + assign(p); + return *this; + } + if (p.has_root_directory()) { + assign(root_name()); + } + else if ((!has_root_directory() && is_absolute()) || has_filename()) { + _path += preferred_separator; + } + auto iter = p.begin(); + bool first = true; + if (p.has_root_name()) { + ++iter; + } + while (iter != p.end()) { + if (!first && !(!_path.empty() && _path[_path.length() - 1] == preferred_separator)) { + _path += preferred_separator; + } + first = false; + _path += (*iter++).native(); + } + check_long_path(); + return *this; +} + +GHC_INLINE void path::append_name(const value_type* name) +{ + if (_path.empty()) { + this->operator/=(path(name)); + } + else { + if (_path.back() != path::preferred_separator) { + _path.push_back(path::preferred_separator); + } + _path += name; + check_long_path(); + } +} + +#endif // GHC_EXPAND_IMPL + +template +inline path& path::operator/=(const Source& source) +{ + return append(source); +} + +template +inline path& path::append(const Source& source) +{ + return this->operator/=(path(source)); +} + +template <> +inline path& path::append(const path& p) +{ + return this->operator/=(p); +} + +template +inline path& path::append(InputIterator first, InputIterator last) +{ + std::basic_string::value_type> part(first, last); + return append(part); +} + +#ifdef GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.path.concat] concatenation + +GHC_INLINE path& path::operator+=(const path& x) +{ + return concat(x._path); +} + +GHC_INLINE path& path::operator+=(const string_type& x) +{ + return concat(x); +} + +#ifdef GHC_WITH_STRING_VIEW +GHC_INLINE path& path::operator+=(basic_string_view x) +{ + return concat(x); +} +#endif + +GHC_INLINE path& path::operator+=(const value_type* x) +{ +#ifdef GHC_WITH_STRING_VIEW + basic_string_view part(x); +#else + string_type part(x); +#endif + return concat(part); +} + +GHC_INLINE path& path::operator+=(value_type x) +{ +#ifdef GHC_OS_WINDOWS + if (x == generic_separator) { + x = preferred_separator; + } +#endif + if (_path.empty() || _path.back() != preferred_separator) { + _path += x; + } + check_long_path(); + return *this; +} + +#endif // GHC_EXPAND_IMPL + +template +inline path::path_from_string& path::operator+=(const Source& x) +{ + return concat(x); +} + +template +inline path::path_type_EcharT& path::operator+=(EcharT x) +{ +#ifdef GHC_WITH_STRING_VIEW + basic_string_view part(&x, 1); +#else + std::basic_string part(1, x); +#endif + concat(part); + return *this; +} + +template +inline path& path::concat(const Source& x) +{ + path p(x); + _path += p._path; + postprocess_path_with_format(native_format); + return *this; +} +template +inline path& path::concat(InputIterator first, InputIterator last) +{ + _path.append(first, last); + postprocess_path_with_format(native_format); + return *this; +} + +#ifdef GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.path.modifiers] modifiers +GHC_INLINE void path::clear() noexcept +{ + _path.clear(); +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + _prefixLength = 0; +#endif +} + +GHC_INLINE path& path::make_preferred() +{ + // as this filesystem implementation only uses generic_format + // internally, this must be a no-op + return *this; +} + +GHC_INLINE path& path::remove_filename() +{ + if (has_filename()) { + _path.erase(_path.size() - filename()._path.size()); + } + return *this; +} + +GHC_INLINE path& path::replace_filename(const path& replacement) +{ + remove_filename(); + return append(replacement); +} + +GHC_INLINE path& path::replace_extension(const path& replacement) +{ + if (has_extension()) { + _path.erase(_path.size() - extension()._path.size()); + } + if (!replacement.empty() && replacement._path[0] != '.') { + _path += '.'; + } + return concat(replacement); +} + +GHC_INLINE void path::swap(path& rhs) noexcept +{ + _path.swap(rhs._path); +#if defined(GHC_OS_WINDOWS) && defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + std::swap(_prefixLength, rhs._prefixLength); +#endif +} + +//----------------------------------------------------------------------------- +// [fs.path.native.obs] native format observers +GHC_INLINE const path::string_type& path::native() const noexcept +{ + return _path; +} + +GHC_INLINE const path::value_type* path::c_str() const noexcept +{ + return native().c_str(); +} + +GHC_INLINE path::operator path::string_type() const +{ + return native(); +} + +#endif // GHC_EXPAND_IMPL + +template +inline std::basic_string path::string(const Allocator& a) const +{ +#ifdef GHC_USE_WCHAR_T + return detail::fromWChar>(_path, a); +#else + return detail::fromUtf8>(_path, a); +#endif +} + +#ifdef GHC_EXPAND_IMPL + +GHC_INLINE std::string path::string() const +{ +#ifdef GHC_USE_WCHAR_T + return detail::toUtf8(native()); +#else + return native(); +#endif +} + +GHC_INLINE std::wstring path::wstring() const +{ +#ifdef GHC_USE_WCHAR_T + return native(); +#else + return detail::fromUtf8(native()); +#endif +} + +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) +GHC_INLINE std::u8string path::u8string() const +{ +#ifdef GHC_USE_WCHAR_T + return std::u8string(reinterpret_cast(detail::toUtf8(native()).c_str())); +#else + return std::u8string(reinterpret_cast(c_str())); +#endif +} +#else +GHC_INLINE std::string path::u8string() const +{ +#ifdef GHC_USE_WCHAR_T + return detail::toUtf8(native()); +#else + return native(); +#endif +} +#endif + +GHC_INLINE std::u16string path::u16string() const +{ + // TODO: optimize + return detail::fromUtf8(string()); +} + +GHC_INLINE std::u32string path::u32string() const +{ + // TODO: optimize + return detail::fromUtf8(string()); +} + +#endif // GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.path.generic.obs] generic format observers +template +inline std::basic_string path::generic_string(const Allocator& a) const +{ +#ifdef GHC_OS_WINDOWS +#ifdef GHC_USE_WCHAR_T + auto result = detail::fromWChar, path::string_type>(_path, a); +#else + auto result = detail::fromUtf8>(_path, a); +#endif + for (auto& c : result) { + if (c == preferred_separator) { + c = generic_separator; + } + } + return result; +#else + return detail::fromUtf8>(_path, a); +#endif +} + +#ifdef GHC_EXPAND_IMPL + +GHC_INLINE std::string path::generic_string() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return _path; +#endif +} + +GHC_INLINE std::wstring path::generic_wstring() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return detail::fromUtf8(_path); +#endif +} // namespace filesystem + +#if defined(__cpp_lib_char8_t) && !defined(GHC_FILESYSTEM_ENFORCE_CPP17_API) +GHC_INLINE std::u8string path::generic_u8string() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return std::u8string(reinterpret_cast(_path.c_str())); +#endif +} +#else +GHC_INLINE std::string path::generic_u8string() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return _path; +#endif +} +#endif + +GHC_INLINE std::u16string path::generic_u16string() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return detail::fromUtf8(_path); +#endif +} + +GHC_INLINE std::u32string path::generic_u32string() const +{ +#ifdef GHC_OS_WINDOWS + return generic_string(); +#else + return detail::fromUtf8(_path); +#endif +} + +//----------------------------------------------------------------------------- +// [fs.path.compare] compare +GHC_INLINE int path::compare(const path& p) const noexcept +{ +#ifdef LWG_2936_BEHAVIOUR + auto rnl1 = root_name_length(); + auto rnl2 = p.root_name_length(); +#ifdef GHC_OS_WINDOWS + auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); +#else + auto rnc = _path.compare(0, rnl1, p._path, 0, (std::min(rnl1, rnl2))); +#endif + if (rnc) { + return rnc; + } + bool hrd1 = has_root_directory(), hrd2 = p.has_root_directory(); + if (hrd1 != hrd2) { + return hrd1 ? 1 : -1; + } + if (hrd1) { + ++rnl1; + ++rnl2; + } + auto iter1 = _path.begin() + static_cast(rnl1); + auto iter2 = p._path.begin() + static_cast(rnl2); + while (iter1 != _path.end() && iter2 != p._path.end() && *iter1 == *iter2) { + ++iter1; + ++iter2; + } + if (iter1 == _path.end()) { + return iter2 == p._path.end() ? 0 : -1; + } + if (iter2 == p._path.end()) { + return 1; + } + if (*iter1 == preferred_separator) { + return -1; + } + if (*iter2 == preferred_separator) { + return 1; + } + return *iter1 < *iter2 ? -1 : 1; +#else // LWG_2936_BEHAVIOUR +#ifdef GHC_OS_WINDOWS + auto rnl1 = root_name_length(); + auto rnl2 = p.root_name_length(); + auto rnc = detail::compare_simple_insensitive(_path.c_str(), rnl1, p._path.c_str(), rnl2); + if (rnc) { + return rnc; + } + return _path.compare(rnl1, std::string::npos, p._path, rnl2, std::string::npos); +#else + return _path.compare(p._path); +#endif +#endif +} + +GHC_INLINE int path::compare(const string_type& s) const +{ + return compare(path(s)); +} + +#ifdef GHC_WITH_STRING_VIEW +GHC_INLINE int path::compare(basic_string_view s) const +{ + return compare(path(s)); +} +#endif + +GHC_INLINE int path::compare(const value_type* s) const +{ + return compare(path(s)); +} + +//----------------------------------------------------------------------------- +// [fs.path.decompose] decomposition +#ifdef GHC_OS_WINDOWS +GHC_INLINE void path::handle_prefixes() +{ +#if defined(GHC_WIN_AUTO_PREFIX_LONG_PATH) + _prefixLength = 0; + if (_path.length() >= 6 && _path[2] == '?' && std::toupper(static_cast(_path[4])) >= 'A' && std::toupper(static_cast(_path[4])) <= 'Z' && _path[5] == ':') { + if (detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\\\?\\"))) || detail::startsWith(_path, impl_string_type(GHC_PLATFORM_LITERAL("\\??\\")))) { + _prefixLength = 4; + } + } +#endif // GHC_WIN_AUTO_PREFIX_LONG_PATH +} +#endif + +GHC_INLINE path::string_type::size_type path::root_name_length() const noexcept +{ +#ifdef GHC_OS_WINDOWS + if (_path.length() >= _prefixLength + 2 && std::toupper(static_cast(_path[_prefixLength])) >= 'A' && std::toupper(static_cast(_path[_prefixLength])) <= 'Z' && _path[_prefixLength + 1] == ':') { + return 2; + } +#endif + if (_path.length() > _prefixLength + 2 && _path[_prefixLength] == preferred_separator && _path[_prefixLength + 1] == preferred_separator && _path[_prefixLength + 2] != preferred_separator && std::isprint(_path[_prefixLength + 2])) { + impl_string_type::size_type pos = _path.find(preferred_separator, _prefixLength + 3); + if (pos == impl_string_type::npos) { + return _path.length(); + } + else { + return pos; + } + } + return 0; +} + +GHC_INLINE path path::root_name() const +{ + return path(_path.substr(_prefixLength, root_name_length()), native_format); +} + +GHC_INLINE path path::root_directory() const +{ + if (has_root_directory()) { + static const path _root_dir(std::string(1, preferred_separator), native_format); + return _root_dir; + } + return path(); +} + +GHC_INLINE path path::root_path() const +{ + return path(root_name().string() + root_directory().string(), native_format); +} + +GHC_INLINE path path::relative_path() const +{ + auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); + return path(_path.substr((std::min)(rootPathLen, _path.length())), generic_format); +} + +GHC_INLINE path path::parent_path() const +{ + auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); + if (rootPathLen < _path.length()) { + if (empty()) { + return path(); + } + else { + auto piter = end(); + auto iter = piter.decrement(_path.end()); + if (iter > _path.begin() + static_cast(rootPathLen) && *iter != preferred_separator) { + --iter; + } + return path(_path.begin(), iter, native_format); + } + } + else { + return *this; + } +} + +GHC_INLINE path path::filename() const +{ + return !has_relative_path() ? path() : path(*--end()); +} + +GHC_INLINE path path::stem() const +{ + impl_string_type fn = filename().native(); + if (fn != "." && fn != "..") { + impl_string_type::size_type pos = fn.rfind('.'); + if (pos != impl_string_type::npos && pos > 0) { + return path{fn.substr(0, pos), native_format}; + } + } + return path{fn, native_format}; +} + +GHC_INLINE path path::extension() const +{ + if (has_relative_path()) { + auto iter = end(); + const auto& fn = *--iter; + impl_string_type::size_type pos = fn._path.rfind('.'); + if (pos != std::string::npos && pos > 0) { + return path(fn._path.substr(pos), native_format); + } + } + return path(); +} + +#ifdef GHC_OS_WINDOWS +namespace detail { +GHC_INLINE bool has_executable_extension(const path& p) +{ + if (p.has_relative_path()) { + auto iter = p.end(); + const auto& fn = *--iter; + auto pos = fn._path.find_last_of('.'); + if (pos == std::string::npos || pos == 0 || fn._path.length() - pos != 3) { + return false; + } + const path::value_type* ext = fn._path.c_str() + pos + 1; + if (detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("exe")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("cmd")) || detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("bat")) || + detail::equals_simple_insensitive(ext, GHC_PLATFORM_LITERAL("com"))) { + return true; + } + } + return false; +} +} // namespace detail +#endif + +//----------------------------------------------------------------------------- +// [fs.path.query] query +GHC_INLINE bool path::empty() const noexcept +{ + return _path.empty(); +} + +GHC_INLINE bool path::has_root_name() const +{ + return root_name_length() > 0; +} + +GHC_INLINE bool path::has_root_directory() const +{ + auto rootLen = _prefixLength + root_name_length(); + return (_path.length() > rootLen && _path[rootLen] == preferred_separator); +} + +GHC_INLINE bool path::has_root_path() const +{ + return has_root_name() || has_root_directory(); +} + +GHC_INLINE bool path::has_relative_path() const +{ + auto rootPathLen = _prefixLength + root_name_length() + (has_root_directory() ? 1 : 0); + return rootPathLen < _path.length(); +} + +GHC_INLINE bool path::has_parent_path() const +{ + return !parent_path().empty(); +} + +GHC_INLINE bool path::has_filename() const +{ + return has_relative_path() && !filename().empty(); +} + +GHC_INLINE bool path::has_stem() const +{ + return !stem().empty(); +} + +GHC_INLINE bool path::has_extension() const +{ + return !extension().empty(); +} + +GHC_INLINE bool path::is_absolute() const +{ +#ifdef GHC_OS_WINDOWS + return has_root_name() && has_root_directory(); +#else + return has_root_directory(); +#endif +} + +GHC_INLINE bool path::is_relative() const +{ + return !is_absolute(); +} + +//----------------------------------------------------------------------------- +// [fs.path.gen] generation +GHC_INLINE path path::lexically_normal() const +{ + path dest; + bool lastDotDot = false; + for (string_type s : *this) { + if (s == ".") { + dest /= ""; + continue; + } + else if (s == ".." && !dest.empty()) { + auto root = root_path(); + if (dest == root) { + continue; + } + else if (*(--dest.end()) != "..") { + if (dest._path.back() == preferred_separator) { + dest._path.pop_back(); + } + dest.remove_filename(); + continue; + } + } + if (!(s.empty() && lastDotDot)) { + dest /= s; + } + lastDotDot = s == ".."; + } + if (dest.empty()) { + dest = "."; + } + return dest; +} + +GHC_INLINE path path::lexically_relative(const path& base) const +{ + if (root_name() != base.root_name() || is_absolute() != base.is_absolute() || (!has_root_directory() && base.has_root_directory())) { + return path(); + } + const_iterator a = begin(), b = base.begin(); + while (a != end() && b != base.end() && *a == *b) { + ++a; + ++b; + } + if (a == end() && b == base.end()) { + return path("."); + } + int count = 0; + for (const auto& element : input_iterator_range(b, base.end())) { + if (element != "." && element != "" && element != "..") { + ++count; + } + else if (element == "..") { + --count; + } + } + if (count < 0) { + return path(); + } + path result; + for (int i = 0; i < count; ++i) { + result /= ".."; + } + for (const auto& element : input_iterator_range(a, end())) { + result /= element; + } + return result; +} + +GHC_INLINE path path::lexically_proximate(const path& base) const +{ + path result = lexically_relative(base); + return result.empty() ? *this : result; +} + +//----------------------------------------------------------------------------- +// [fs.path.itr] iterators +GHC_INLINE path::iterator::iterator() {} + +GHC_INLINE path::iterator::iterator(const path& p, const impl_string_type::const_iterator& pos) + : _first(p._path.begin()) + , _last(p._path.end()) + , _prefix(_first + static_cast(p._prefixLength)) + , _root(p.has_root_directory() ? _first + static_cast(p._prefixLength + p.root_name_length()) : _last) + , _iter(pos) +{ + if (pos != _last) { + updateCurrent(); + } +} + +GHC_INLINE path::impl_string_type::const_iterator path::iterator::increment(const path::impl_string_type::const_iterator& pos) const +{ + path::impl_string_type::const_iterator i = pos; + bool fromStart = i == _first || i == _prefix; + if (i != _last) { + if (fromStart && i == _first && _prefix > _first) { + i = _prefix; + } + else if (*i++ == preferred_separator) { + // we can only sit on a slash if it is a network name or a root + if (i != _last && *i == preferred_separator) { + if (fromStart && !(i + 1 != _last && *(i + 1) == preferred_separator)) { + // leadind double slashes detected, treat this and the + // following until a slash as one unit + i = std::find(++i, _last, preferred_separator); + } + else { + // skip redundant slashes + while (i != _last && *i == preferred_separator) { + ++i; + } + } + } + } + else { + if (fromStart && i != _last && *i == ':') { + ++i; + } + else { + i = std::find(i, _last, preferred_separator); + } + } + } + return i; +} + +GHC_INLINE path::impl_string_type::const_iterator path::iterator::decrement(const path::impl_string_type::const_iterator& pos) const +{ + path::impl_string_type::const_iterator i = pos; + if (i != _first) { + --i; + // if this is now the root slash or the trailing slash, we are done, + // else check for network name + if (i != _root && (pos != _last || *i != preferred_separator)) { +#ifdef GHC_OS_WINDOWS + static const impl_string_type seps = GHC_PLATFORM_LITERAL("\\:"); + i = std::find_first_of(std::reverse_iterator(i), std::reverse_iterator(_first), seps.begin(), seps.end()).base(); + if (i > _first && *i == ':') { + i++; + } +#else + i = std::find(std::reverse_iterator(i), std::reverse_iterator(_first), preferred_separator).base(); +#endif + // Now we have to check if this is a network name + if (i - _first == 2 && *_first == preferred_separator && *(_first + 1) == preferred_separator) { + i -= 2; + } + } + } + return i; +} + +GHC_INLINE void path::iterator::updateCurrent() +{ + if ((_iter == _last) || (_iter != _first && _iter != _last && (*_iter == preferred_separator && _iter != _root) && (_iter + 1 == _last))) { + _current.clear(); + } + else { + _current.assign(_iter, increment(_iter)); + } +} + +GHC_INLINE path::iterator& path::iterator::operator++() +{ + _iter = increment(_iter); + while (_iter != _last && // we didn't reach the end + _iter != _root && // this is not a root position + *_iter == preferred_separator && // we are on a separator + (_iter + 1) != _last // the slash is not the last char + ) { + ++_iter; + } + updateCurrent(); + return *this; +} + +GHC_INLINE path::iterator path::iterator::operator++(int) +{ + path::iterator i{*this}; + ++(*this); + return i; +} + +GHC_INLINE path::iterator& path::iterator::operator--() +{ + _iter = decrement(_iter); + updateCurrent(); + return *this; +} + +GHC_INLINE path::iterator path::iterator::operator--(int) +{ + auto i = *this; + --(*this); + return i; +} + +GHC_INLINE bool path::iterator::operator==(const path::iterator& other) const +{ + return _iter == other._iter; +} + +GHC_INLINE bool path::iterator::operator!=(const path::iterator& other) const +{ + return _iter != other._iter; +} + +GHC_INLINE path::iterator::reference path::iterator::operator*() const +{ + return _current; +} + +GHC_INLINE path::iterator::pointer path::iterator::operator->() const +{ + return &_current; +} + +GHC_INLINE path::iterator path::begin() const +{ + return iterator(*this, _path.begin()); +} + +GHC_INLINE path::iterator path::end() const +{ + return iterator(*this, _path.end()); +} + +//----------------------------------------------------------------------------- +// [fs.path.nonmember] path non-member functions +GHC_INLINE void swap(path& lhs, path& rhs) noexcept +{ + swap(lhs._path, rhs._path); +} + +GHC_INLINE size_t hash_value(const path& p) noexcept +{ + return std::hash()(p.generic_string()); +} + +#ifdef GHC_HAS_THREEWAY_COMP +GHC_INLINE std::strong_ordering operator<=>(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) <=> 0; +} +#endif + +GHC_INLINE bool operator==(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) == 0; +} + +GHC_INLINE bool operator!=(const path& lhs, const path& rhs) noexcept +{ + return !(lhs == rhs); +} + +GHC_INLINE bool operator<(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) < 0; +} + +GHC_INLINE bool operator<=(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) <= 0; +} + +GHC_INLINE bool operator>(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) > 0; +} + +GHC_INLINE bool operator>=(const path& lhs, const path& rhs) noexcept +{ + return lhs.compare(rhs) >= 0; +} + +GHC_INLINE path operator/(const path& lhs, const path& rhs) +{ + path result(lhs); + result /= rhs; + return result; +} + +#endif // GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.path.io] path inserter and extractor +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const path& p) +{ + os << "\""; + auto ps = p.string(); + for (auto c : ps) { + if (c == '"' || c == '\\') { + os << '\\'; + } + os << c; + } + os << "\""; + return os; +} + +template +inline std::basic_istream& operator>>(std::basic_istream& is, path& p) +{ + std::basic_string tmp; + charT c; + is >> c; + if (c == '"') { + auto sf = is.flags(); + is >> std::noskipws; + while (is) { + auto c2 = is.get(); + if (is) { + if (c2 == '\\') { + c2 = is.get(); + if (is) { + tmp += static_cast(c2); + } + } + else if (c2 == '"') { + break; + } + else { + tmp += static_cast(c2); + } + } + } + if ((sf & std::ios_base::skipws) == std::ios_base::skipws) { + is >> std::skipws; + } + p = path(tmp); + } + else { + is >> tmp; + p = path(static_cast(c) + tmp); + } + return is; +} + +#ifdef GHC_EXPAND_IMPL + +//----------------------------------------------------------------------------- +// [fs.class.filesystem_error] Class filesystem_error +GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, std::error_code ec) + : std::system_error(ec, what_arg) + , _what_arg(what_arg) + , _ec(ec) +{ +} + +GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, std::error_code ec) + : std::system_error(ec, what_arg) + , _what_arg(what_arg) + , _ec(ec) + , _p1(p1) +{ + if (!_p1.empty()) { + _what_arg += ": '" + _p1.string() + "'"; + } +} + +GHC_INLINE filesystem_error::filesystem_error(const std::string& what_arg, const path& p1, const path& p2, std::error_code ec) + : std::system_error(ec, what_arg) + , _what_arg(what_arg) + , _ec(ec) + , _p1(p1) + , _p2(p2) +{ + if (!_p1.empty()) { + _what_arg += ": '" + _p1.string() + "'"; + } + if (!_p2.empty()) { + _what_arg += ", '" + _p2.string() + "'"; + } +} + +GHC_INLINE const path& filesystem_error::path1() const noexcept +{ + return _p1; +} + +GHC_INLINE const path& filesystem_error::path2() const noexcept +{ + return _p2; +} + +GHC_INLINE const char* filesystem_error::what() const noexcept +{ + return _what_arg.c_str(); +} + +//----------------------------------------------------------------------------- +// [fs.op.funcs] filesystem operations +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path absolute(const path& p) +{ + std::error_code ec; + path result = absolute(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE path absolute(const path& p, std::error_code& ec) +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + if (p.empty()) { + return absolute(current_path(ec), ec) / ""; + } + ULONG size = ::GetFullPathNameW(GHC_NATIVEWP(p), 0, 0, 0); + if (size) { + std::vector buf(size, 0); + ULONG s2 = GetFullPathNameW(GHC_NATIVEWP(p), size, buf.data(), nullptr); + if (s2 && s2 < size) { + path result = path(std::wstring(buf.data(), s2)); + if (p.filename() == ".") { + result /= "."; + } + return result; + } + } + ec = detail::make_system_error(); + return path(); +#else + path base = current_path(ec); + if (!ec) { + if (p.empty()) { + return base / p; + } + if (p.has_root_name()) { + if (p.has_root_directory()) { + return p; + } + else { + return p.root_name() / base.root_directory() / base.relative_path() / p.relative_path(); + } + } + else { + if (p.has_root_directory()) { + return base.root_name() / p; + } + else { + return base / p; + } + } + } + ec = detail::make_system_error(); + return path(); +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path canonical(const path& p) +{ + std::error_code ec; + auto result = canonical(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE path canonical(const path& p, std::error_code& ec) +{ + if (p.empty()) { + ec = detail::make_error_code(detail::portable_error::not_found); + return path(); + } + path work = p.is_absolute() ? p : absolute(p, ec); + path result; + + auto fs = status(work, ec); + if (ec) { + return path(); + } + if (fs.type() == file_type::not_found) { + ec = detail::make_error_code(detail::portable_error::not_found); + return path(); + } + bool redo; + do { + auto rootPathLen = work._prefixLength + work.root_name_length() + (work.has_root_directory() ? 1 : 0); + redo = false; + result.clear(); + for (auto pe : work) { + if (pe.empty() || pe == ".") { + continue; + } + else if (pe == "..") { + result = result.parent_path(); + continue; + } + else if ((result / pe).string().length() <= rootPathLen) { + result /= pe; + continue; + } + auto sls = symlink_status(result / pe, ec); + if (ec) { + return path(); + } + if (is_symlink(sls)) { + redo = true; + auto target = read_symlink(result / pe, ec); + if (ec) { + return path(); + } + if (target.is_absolute()) { + result = target; + continue; + } + else { + result /= target; + continue; + } + } + else { + result /= pe; + } + } + work = result; + } while (redo); + ec.clear(); + return result; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void copy(const path& from, const path& to) +{ + copy(from, to, copy_options::none); +} + +GHC_INLINE void copy(const path& from, const path& to, copy_options options) +{ + std::error_code ec; + copy(from, to, options, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); + } +} +#endif + +GHC_INLINE void copy(const path& from, const path& to, std::error_code& ec) noexcept +{ + copy(from, to, copy_options::none, ec); +} + +GHC_INLINE void copy(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept +{ + std::error_code tec; + file_status fs_from, fs_to; + ec.clear(); + if ((options & (copy_options::skip_symlinks | copy_options::copy_symlinks | copy_options::create_symlinks)) != copy_options::none) { + fs_from = symlink_status(from, ec); + } + else { + fs_from = status(from, ec); + } + if (!exists(fs_from)) { + if (!ec) { + ec = detail::make_error_code(detail::portable_error::not_found); + } + return; + } + if ((options & (copy_options::skip_symlinks | copy_options::create_symlinks)) != copy_options::none) { + fs_to = symlink_status(to, tec); + } + else { + fs_to = status(to, tec); + } + if (is_other(fs_from) || is_other(fs_to) || (is_directory(fs_from) && is_regular_file(fs_to)) || (exists(fs_to) && equivalent(from, to, ec))) { + ec = detail::make_error_code(detail::portable_error::invalid_argument); + } + else if (is_symlink(fs_from)) { + if ((options & copy_options::skip_symlinks) == copy_options::none) { + if (!exists(fs_to) && (options & copy_options::copy_symlinks) != copy_options::none) { + copy_symlink(from, to, ec); + } + else { + ec = detail::make_error_code(detail::portable_error::invalid_argument); + } + } + } + else if (is_regular_file(fs_from)) { + if ((options & copy_options::directories_only) == copy_options::none) { + if ((options & copy_options::create_symlinks) != copy_options::none) { + create_symlink(from.is_absolute() ? from : canonical(from, ec), to, ec); + } +#ifndef GHC_OS_WEB + else if ((options & copy_options::create_hard_links) != copy_options::none) { + create_hard_link(from, to, ec); + } +#endif + else if (is_directory(fs_to)) { + copy_file(from, to / from.filename(), options, ec); + } + else { + copy_file(from, to, options, ec); + } + } + } +#ifdef LWG_2682_BEHAVIOUR + else if (is_directory(fs_from) && (options & copy_options::create_symlinks) != copy_options::none) { + ec = detail::make_error_code(detail::portable_error::is_a_directory); + } +#endif + else if (is_directory(fs_from) && (options == copy_options::none || (options & copy_options::recursive) != copy_options::none)) { + if (!exists(fs_to)) { + create_directory(to, from, ec); + if (ec) { + return; + } + } + for (auto iter = directory_iterator(from, ec); iter != directory_iterator(); iter.increment(ec)) { + if (!ec) { + copy(iter->path(), to / iter->path().filename(), options | static_cast(0x8000), ec); + } + if (ec) { + return; + } + } + } + return; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool copy_file(const path& from, const path& to) +{ + return copy_file(from, to, copy_options::none); +} + +GHC_INLINE bool copy_file(const path& from, const path& to, copy_options option) +{ + std::error_code ec; + auto result = copy_file(from, to, option, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); + } + return result; +} +#endif + +GHC_INLINE bool copy_file(const path& from, const path& to, std::error_code& ec) noexcept +{ + return copy_file(from, to, copy_options::none, ec); +} + +GHC_INLINE bool copy_file(const path& from, const path& to, copy_options options, std::error_code& ec) noexcept +{ + std::error_code tecf, tect; + auto sf = status(from, tecf); + auto st = status(to, tect); + bool overwrite = false; + ec.clear(); + if (!is_regular_file(sf)) { + ec = tecf; + return false; + } + if (exists(st) && (!is_regular_file(st) || equivalent(from, to, ec) || (options & (copy_options::skip_existing | copy_options::overwrite_existing | copy_options::update_existing)) == copy_options::none)) { + ec = tect ? tect : detail::make_error_code(detail::portable_error::exists); + return false; + } + if (exists(st)) { + if ((options & copy_options::update_existing) == copy_options::update_existing) { + auto from_time = last_write_time(from, ec); + if (ec) { + ec = detail::make_system_error(); + return false; + } + auto to_time = last_write_time(to, ec); + if (ec) { + ec = detail::make_system_error(); + return false; + } + if (from_time <= to_time) { + return false; + } + } + overwrite = true; + } +#ifdef GHC_OS_WINDOWS + if (!::CopyFileW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), !overwrite)) { + ec = detail::make_system_error(); + return false; + } + return true; +#else + std::vector buffer(16384, '\0'); + int in = -1, out = -1; + if ((in = ::open(from.c_str(), O_RDONLY)) < 0) { + ec = detail::make_system_error(); + return false; + } + int mode = O_CREAT | O_WRONLY | O_TRUNC; + if (!overwrite) { + mode |= O_EXCL; + } + if ((out = ::open(to.c_str(), mode, static_cast(sf.permissions() & perms::all))) < 0) { + ec = detail::make_system_error(); + ::close(in); + return false; + } + ssize_t br, bw; + while ((br = ::read(in, buffer.data(), buffer.size())) > 0) { + ssize_t offset = 0; + do { + if ((bw = ::write(out, buffer.data() + offset, static_cast(br))) > 0) { + br -= bw; + offset += bw; + } + else if (bw < 0) { + ec = detail::make_system_error(); + ::close(in); + ::close(out); + return false; + } + } while (br); + } + ::close(in); + ::close(out); + return true; +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink) +{ + std::error_code ec; + copy_symlink(existing_symlink, new_symlink, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), existing_symlink, new_symlink, ec); + } +} +#endif + +GHC_INLINE void copy_symlink(const path& existing_symlink, const path& new_symlink, std::error_code& ec) noexcept +{ + ec.clear(); + auto to = read_symlink(existing_symlink, ec); + if (!ec) { + if (exists(to, ec) && is_directory(to, ec)) { + create_directory_symlink(to, new_symlink, ec); + } + else { + create_symlink(to, new_symlink, ec); + } + } +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool create_directories(const path& p) +{ + std::error_code ec; + auto result = create_directories(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE bool create_directories(const path& p, std::error_code& ec) noexcept +{ + path current; + ec.clear(); + bool didCreate = false; + auto rootPathLen = p._prefixLength + p.root_name_length() + (p.has_root_directory() ? 1 : 0); + current = p.native().substr(0, rootPathLen); + path folders(p._path.substr(rootPathLen)); + for (path::string_type part : folders) { + current /= part; + std::error_code tec; + auto fs = status(current, tec); + if (tec && fs.type() != file_type::not_found) { + ec = tec; + return false; + } + if (!exists(fs)) { + create_directory(current, ec); + if (ec) { + std::error_code tmp_ec; + if (is_directory(current, tmp_ec)) { + ec.clear(); + } + else { + return false; + } + } + didCreate = true; + } +#ifndef LWG_2935_BEHAVIOUR + else if (!is_directory(fs)) { + ec = detail::make_error_code(detail::portable_error::exists); + return false; + } +#endif + } + return didCreate; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool create_directory(const path& p) +{ + std::error_code ec; + auto result = create_directory(p, path(), ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE bool create_directory(const path& p, std::error_code& ec) noexcept +{ + return create_directory(p, path(), ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool create_directory(const path& p, const path& attributes) +{ + std::error_code ec; + auto result = create_directory(p, attributes, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE bool create_directory(const path& p, const path& attributes, std::error_code& ec) noexcept +{ + std::error_code tec; + ec.clear(); + auto fs = status(p, tec); +#ifdef LWG_2935_BEHAVIOUR + if (status_known(fs) && exists(fs)) { + return false; + } +#else + if (status_known(fs) && exists(fs) && is_directory(fs)) { + return false; + } +#endif +#ifdef GHC_OS_WINDOWS + if (!attributes.empty()) { + if (!::CreateDirectoryExW(GHC_NATIVEWP(attributes), GHC_NATIVEWP(p), NULL)) { + ec = detail::make_system_error(); + return false; + } + } + else if (!::CreateDirectoryW(GHC_NATIVEWP(p), NULL)) { + ec = detail::make_system_error(); + return false; + } +#else + ::mode_t attribs = static_cast(perms::all); + if (!attributes.empty()) { + struct ::stat fileStat; + if (::stat(attributes.c_str(), &fileStat) != 0) { + ec = detail::make_system_error(); + return false; + } + attribs = fileStat.st_mode; + } + if (::mkdir(p.c_str(), attribs) != 0) { + ec = detail::make_system_error(); + return false; + } +#endif + return true; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink) +{ + std::error_code ec; + create_directory_symlink(to, new_symlink, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); + } +} +#endif + +GHC_INLINE void create_directory_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept +{ + detail::create_symlink(to, new_symlink, true, ec); +} + +#ifndef GHC_OS_WEB +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link) +{ + std::error_code ec; + create_hard_link(to, new_hard_link, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), to, new_hard_link, ec); + } +} +#endif + +GHC_INLINE void create_hard_link(const path& to, const path& new_hard_link, std::error_code& ec) noexcept +{ + detail::create_hardlink(to, new_hard_link, ec); +} +#endif + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void create_symlink(const path& to, const path& new_symlink) +{ + std::error_code ec; + create_symlink(to, new_symlink, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), to, new_symlink, ec); + } +} +#endif + +GHC_INLINE void create_symlink(const path& to, const path& new_symlink, std::error_code& ec) noexcept +{ + detail::create_symlink(to, new_symlink, false, ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path current_path() +{ + std::error_code ec; + auto result = current_path(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), ec); + } + return result; +} +#endif + +GHC_INLINE path current_path(std::error_code& ec) +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + DWORD pathlen = ::GetCurrentDirectoryW(0, 0); + std::unique_ptr buffer(new wchar_t[size_t(pathlen) + 1]); + if (::GetCurrentDirectoryW(pathlen, buffer.get()) == 0) { + ec = detail::make_system_error(); + return path(); + } + return path(std::wstring(buffer.get()), path::native_format); +#else + size_t pathlen = static_cast(std::max(int(::pathconf(".", _PC_PATH_MAX)), int(PATH_MAX))); + std::unique_ptr buffer(new char[pathlen + 1]); + if (::getcwd(buffer.get(), pathlen) == nullptr) { + ec = detail::make_system_error(); + return path(); + } + return path(buffer.get()); +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void current_path(const path& p) +{ + std::error_code ec; + current_path(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } +} +#endif + +GHC_INLINE void current_path(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + if (!::SetCurrentDirectoryW(GHC_NATIVEWP(p))) { + ec = detail::make_system_error(); + } +#else + if (::chdir(p.string().c_str()) == -1) { + ec = detail::make_system_error(); + } +#endif +} + +GHC_INLINE bool exists(file_status s) noexcept +{ + return status_known(s) && s.type() != file_type::not_found; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool exists(const path& p) +{ + return exists(status(p)); +} +#endif + +GHC_INLINE bool exists(const path& p, std::error_code& ec) noexcept +{ + file_status s = status(p, ec); + if (status_known(s)) { + ec.clear(); + } + return exists(s); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool equivalent(const path& p1, const path& p2) +{ + std::error_code ec; + bool result = equivalent(p1, p2, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p1, p2, ec); + } + return result; +} +#endif + +GHC_INLINE bool equivalent(const path& p1, const path& p2, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + detail::unique_handle file1(::CreateFileW(GHC_NATIVEWP(p1), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + auto e1 = ::GetLastError(); + detail::unique_handle file2(::CreateFileW(GHC_NATIVEWP(p2), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + if (!file1 || !file2) { +#ifdef LWG_2937_BEHAVIOUR + ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); +#else + if (file1 == file2) { + ec = detail::make_system_error(e1 ? e1 : ::GetLastError()); + } +#endif + return false; + } + BY_HANDLE_FILE_INFORMATION inf1, inf2; + if (!::GetFileInformationByHandle(file1.get(), &inf1)) { + ec = detail::make_system_error(); + return false; + } + if (!::GetFileInformationByHandle(file2.get(), &inf2)) { + ec = detail::make_system_error(); + return false; + } + return inf1.ftLastWriteTime.dwLowDateTime == inf2.ftLastWriteTime.dwLowDateTime && inf1.ftLastWriteTime.dwHighDateTime == inf2.ftLastWriteTime.dwHighDateTime && inf1.nFileIndexHigh == inf2.nFileIndexHigh && inf1.nFileIndexLow == inf2.nFileIndexLow && + inf1.nFileSizeHigh == inf2.nFileSizeHigh && inf1.nFileSizeLow == inf2.nFileSizeLow && inf1.dwVolumeSerialNumber == inf2.dwVolumeSerialNumber; +#else + struct ::stat s1, s2; + auto rc1 = ::stat(p1.c_str(), &s1); + auto e1 = errno; + auto rc2 = ::stat(p2.c_str(), &s2); + if (rc1 || rc2) { +#ifdef LWG_2937_BEHAVIOUR + ec = detail::make_system_error(e1 ? e1 : errno); +#else + if (rc1 && rc2) { + ec = detail::make_system_error(e1 ? e1 : errno); + } +#endif + return false; + } + return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime; +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE uintmax_t file_size(const path& p) +{ + std::error_code ec; + auto result = file_size(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE uintmax_t file_size(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + WIN32_FILE_ATTRIBUTE_DATA attr; + if (!GetFileAttributesExW(GHC_NATIVEWP(p), GetFileExInfoStandard, &attr)) { + ec = detail::make_system_error(); + return static_cast(-1); + } + return static_cast(attr.nFileSizeHigh) << (sizeof(attr.nFileSizeHigh) * 8) | attr.nFileSizeLow; +#else + struct ::stat fileStat; + if (::stat(p.c_str(), &fileStat) == -1) { + ec = detail::make_system_error(); + return static_cast(-1); + } + return static_cast(fileStat.st_size); +#endif +} + +#ifndef GHC_OS_WEB +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE uintmax_t hard_link_count(const path& p) +{ + std::error_code ec; + auto result = hard_link_count(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE uintmax_t hard_link_count(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + uintmax_t result = static_cast(-1); + detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)); + BY_HANDLE_FILE_INFORMATION inf; + if (!file) { + ec = detail::make_system_error(); + } + else { + if (!::GetFileInformationByHandle(file.get(), &inf)) { + ec = detail::make_system_error(); + } + else { + result = inf.nNumberOfLinks; + } + } + return result; +#else + uintmax_t result = 0; + file_status fs = detail::status_ex(p, ec, nullptr, nullptr, &result, nullptr); + if (fs.type() == file_type::not_found) { + ec = detail::make_error_code(detail::portable_error::not_found); + } + return ec ? static_cast(-1) : result; +#endif +} +#endif + +GHC_INLINE bool is_block_file(file_status s) noexcept +{ + return s.type() == file_type::block; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_block_file(const path& p) +{ + return is_block_file(status(p)); +} +#endif + +GHC_INLINE bool is_block_file(const path& p, std::error_code& ec) noexcept +{ + return is_block_file(status(p, ec)); +} + +GHC_INLINE bool is_character_file(file_status s) noexcept +{ + return s.type() == file_type::character; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_character_file(const path& p) +{ + return is_character_file(status(p)); +} +#endif + +GHC_INLINE bool is_character_file(const path& p, std::error_code& ec) noexcept +{ + return is_character_file(status(p, ec)); +} + +GHC_INLINE bool is_directory(file_status s) noexcept +{ + return s.type() == file_type::directory; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_directory(const path& p) +{ + return is_directory(status(p)); +} +#endif + +GHC_INLINE bool is_directory(const path& p, std::error_code& ec) noexcept +{ + return is_directory(status(p, ec)); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_empty(const path& p) +{ + if (is_directory(p)) { + return directory_iterator(p) == directory_iterator(); + } + else { + return file_size(p) == 0; + } +} +#endif + +GHC_INLINE bool is_empty(const path& p, std::error_code& ec) noexcept +{ + auto fs = status(p, ec); + if (ec) { + return false; + } + if (is_directory(fs)) { + directory_iterator iter(p, ec); + if (ec) { + return false; + } + return iter == directory_iterator(); + } + else { + auto sz = file_size(p, ec); + if (ec) { + return false; + } + return sz == 0; + } +} + +GHC_INLINE bool is_fifo(file_status s) noexcept +{ + return s.type() == file_type::fifo; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_fifo(const path& p) +{ + return is_fifo(status(p)); +} +#endif + +GHC_INLINE bool is_fifo(const path& p, std::error_code& ec) noexcept +{ + return is_fifo(status(p, ec)); +} + +GHC_INLINE bool is_other(file_status s) noexcept +{ + return exists(s) && !is_regular_file(s) && !is_directory(s) && !is_symlink(s); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_other(const path& p) +{ + return is_other(status(p)); +} +#endif + +GHC_INLINE bool is_other(const path& p, std::error_code& ec) noexcept +{ + return is_other(status(p, ec)); +} + +GHC_INLINE bool is_regular_file(file_status s) noexcept +{ + return s.type() == file_type::regular; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_regular_file(const path& p) +{ + return is_regular_file(status(p)); +} +#endif + +GHC_INLINE bool is_regular_file(const path& p, std::error_code& ec) noexcept +{ + return is_regular_file(status(p, ec)); +} + +GHC_INLINE bool is_socket(file_status s) noexcept +{ + return s.type() == file_type::socket; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_socket(const path& p) +{ + return is_socket(status(p)); +} +#endif + +GHC_INLINE bool is_socket(const path& p, std::error_code& ec) noexcept +{ + return is_socket(status(p, ec)); +} + +GHC_INLINE bool is_symlink(file_status s) noexcept +{ + return s.type() == file_type::symlink; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool is_symlink(const path& p) +{ + return is_symlink(symlink_status(p)); +} +#endif + +GHC_INLINE bool is_symlink(const path& p, std::error_code& ec) noexcept +{ + return is_symlink(symlink_status(p, ec)); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_time_type last_write_time(const path& p) +{ + std::error_code ec; + auto result = last_write_time(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE file_time_type last_write_time(const path& p, std::error_code& ec) noexcept +{ + time_t result = 0; + ec.clear(); + file_status fs = detail::status_ex(p, ec, nullptr, nullptr, nullptr, &result); + return ec ? (file_time_type::min)() : std::chrono::system_clock::from_time_t(result); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void last_write_time(const path& p, file_time_type new_time) +{ + std::error_code ec; + last_write_time(p, new_time, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } +} +#endif + +GHC_INLINE void last_write_time(const path& p, file_time_type new_time, std::error_code& ec) noexcept +{ + ec.clear(); + auto d = new_time.time_since_epoch(); +#ifdef GHC_OS_WINDOWS + detail::unique_handle file(::CreateFileW(GHC_NATIVEWP(p), FILE_WRITE_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL)); + FILETIME ft; + auto tt = std::chrono::duration_cast(d).count() * 10 + 116444736000000000; + ft.dwLowDateTime = static_cast(tt); + ft.dwHighDateTime = static_cast(tt >> 32); + if (!::SetFileTime(file.get(), 0, 0, &ft)) { + ec = detail::make_system_error(); + } +#elif defined(GHC_OS_MACOS) +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED +#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101300 + struct ::stat fs; + if (::stat(p.c_str(), &fs) == 0) { + struct ::timeval tv[2]; + tv[0].tv_sec = fs.st_atimespec.tv_sec; + tv[0].tv_usec = static_cast(fs.st_atimespec.tv_nsec / 1000); + tv[1].tv_sec = std::chrono::duration_cast(d).count(); + tv[1].tv_usec = static_cast(std::chrono::duration_cast(d).count() % 1000000); + if (::utimes(p.c_str(), tv) == 0) { + return; + } + } + ec = detail::make_system_error(); + return; +#else + struct ::timespec times[2]; + times[0].tv_sec = 0; + times[0].tv_nsec = UTIME_OMIT; + times[1].tv_sec = std::chrono::duration_cast(d).count(); + times[1].tv_nsec = 0; // std::chrono::duration_cast(d).count() % 1000000000; + if (::utimensat(AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { + ec = detail::make_system_error(); + } + return; +#endif +#endif +#else +#ifndef UTIME_OMIT +#define UTIME_OMIT ((1l << 30) - 2l) +#endif + struct ::timespec times[2]; + times[0].tv_sec = 0; + times[0].tv_nsec = UTIME_OMIT; + times[1].tv_sec = static_cast(std::chrono::duration_cast(d).count()); + times[1].tv_nsec = static_cast(std::chrono::duration_cast(d).count() % 1000000000); +#if defined(__ANDROID_API__) && __ANDROID_API__ < 12 + if (syscall(__NR_utimensat, AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { +#else + if (::utimensat((int)AT_FDCWD, p.c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { +#endif + ec = detail::make_system_error(); + } + return; +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void permissions(const path& p, perms prms, perm_options opts) +{ + std::error_code ec; + permissions(p, prms, opts, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } +} +#endif + +GHC_INLINE void permissions(const path& p, perms prms, std::error_code& ec) noexcept +{ + permissions(p, prms, perm_options::replace, ec); +} + +GHC_INLINE void permissions(const path& p, perms prms, perm_options opts, std::error_code& ec) noexcept +{ + if (static_cast(opts & (perm_options::replace | perm_options::add | perm_options::remove)) == 0) { + ec = detail::make_error_code(detail::portable_error::invalid_argument); + return; + } + auto fs = symlink_status(p, ec); + if ((opts & perm_options::replace) != perm_options::replace) { + if ((opts & perm_options::add) == perm_options::add) { + prms = fs.permissions() | prms; + } + else { + prms = fs.permissions() & ~prms; + } + } +#ifdef GHC_OS_WINDOWS +#ifdef __GNUC__ + auto oldAttr = GetFileAttributesW(GHC_NATIVEWP(p)); + if (oldAttr != INVALID_FILE_ATTRIBUTES) { + DWORD newAttr = ((prms & perms::owner_write) == perms::owner_write) ? oldAttr & ~(static_cast(FILE_ATTRIBUTE_READONLY)) : oldAttr | FILE_ATTRIBUTE_READONLY; + if (oldAttr == newAttr || SetFileAttributesW(GHC_NATIVEWP(p), newAttr)) { + return; + } + } + ec = detail::make_system_error(); +#else + int mode = 0; + if ((prms & perms::owner_read) == perms::owner_read) { + mode |= _S_IREAD; + } + if ((prms & perms::owner_write) == perms::owner_write) { + mode |= _S_IWRITE; + } + if (::_wchmod(p.wstring().c_str(), mode) != 0) { + ec = detail::make_system_error(); + } +#endif +#else + if ((opts & perm_options::nofollow) != perm_options::nofollow) { + if (::chmod(p.c_str(), static_cast(prms)) != 0) { + ec = detail::make_system_error(); + } + } +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path proximate(const path& p, std::error_code& ec) +{ + auto cp = current_path(ec); + if (!ec) { + return proximate(p, cp, ec); + } + return path(); +} +#endif + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path proximate(const path& p, const path& base) +{ + return weakly_canonical(p).lexically_proximate(weakly_canonical(base)); +} +#endif + +GHC_INLINE path proximate(const path& p, const path& base, std::error_code& ec) +{ + return weakly_canonical(p, ec).lexically_proximate(weakly_canonical(base, ec)); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path read_symlink(const path& p) +{ + std::error_code ec; + auto result = read_symlink(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE path read_symlink(const path& p, std::error_code& ec) +{ + file_status fs = symlink_status(p, ec); + if (fs.type() != file_type::symlink) { + ec = detail::make_error_code(detail::portable_error::invalid_argument); + return path(); + } + auto result = detail::resolveSymlink(p, ec); + return ec ? path() : result; +} + +GHC_INLINE path relative(const path& p, std::error_code& ec) +{ + return relative(p, current_path(ec), ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path relative(const path& p, const path& base) +{ + return weakly_canonical(p).lexically_relative(weakly_canonical(base)); +} +#endif + +GHC_INLINE path relative(const path& p, const path& base, std::error_code& ec) +{ + return weakly_canonical(p, ec).lexically_relative(weakly_canonical(base, ec)); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool remove(const path& p) +{ + std::error_code ec; + auto result = remove(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE bool remove(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS +#ifdef GHC_USE_WCHAR_T + auto cstr = p.c_str(); +#else + std::wstring np = detail::fromUtf8(p.u8string()); + auto cstr = np.c_str(); +#endif + DWORD attr = GetFileAttributesW(cstr); + if (attr == INVALID_FILE_ATTRIBUTES) { + auto error = ::GetLastError(); + if (error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND) { + return false; + } + ec = detail::make_system_error(error); + } + else if (attr & FILE_ATTRIBUTE_READONLY) { + auto new_attr = attr & ~static_cast(FILE_ATTRIBUTE_READONLY); + if (!SetFileAttributesW(cstr, new_attr)) { + auto error = ::GetLastError(); + ec = detail::make_system_error(error); + } + } + if (!ec) { + if (attr & FILE_ATTRIBUTE_DIRECTORY) { + if (!RemoveDirectoryW(cstr)) { + ec = detail::make_system_error(); + } + } + else { + if (!DeleteFileW(cstr)) { + ec = detail::make_system_error(); + } + } + } +#else + if (::remove(p.c_str()) == -1) { + auto error = errno; + if (error == ENOENT) { + return false; + } + ec = detail::make_system_error(); + } +#endif + return ec ? false : true; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE uintmax_t remove_all(const path& p) +{ + std::error_code ec; + auto result = remove_all(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE uintmax_t remove_all(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); + uintmax_t count = 0; + if (p == "/") { + ec = detail::make_error_code(detail::portable_error::not_supported); + return static_cast(-1); + } + std::error_code tec; + auto fs = symlink_status(p, tec); + if (exists(fs) && is_directory(fs)) { + for (auto iter = directory_iterator(p, ec); iter != directory_iterator(); iter.increment(ec)) { + if (ec && !detail::is_not_found_error(ec)) { + break; + } + bool is_symlink_result = iter->is_symlink(ec); + if (ec) + return static_cast(-1); + if (!is_symlink_result && iter->is_directory(ec)) { + count += remove_all(iter->path(), ec); + if (ec) { + return static_cast(-1); + } + } + else { + if (!ec) { + remove(iter->path(), ec); + } + if (ec) { + return static_cast(-1); + } + ++count; + } + } + } + if (!ec) { + if (remove(p, ec)) { + ++count; + } + } + if (ec) { + return static_cast(-1); + } + return count; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void rename(const path& from, const path& to) +{ + std::error_code ec; + rename(from, to, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), from, to, ec); + } +} +#endif + +GHC_INLINE void rename(const path& from, const path& to, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + if (from != to) { + if (!MoveFileExW(GHC_NATIVEWP(from), GHC_NATIVEWP(to), (DWORD)MOVEFILE_REPLACE_EXISTING)) { + ec = detail::make_system_error(); + } + } +#else + if (from != to) { + if (::rename(from.c_str(), to.c_str()) != 0) { + ec = detail::make_system_error(); + } + } +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void resize_file(const path& p, uintmax_t size) +{ + std::error_code ec; + resize_file(p, size, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } +} +#endif + +GHC_INLINE void resize_file(const path& p, uintmax_t size, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + LARGE_INTEGER lisize; + lisize.QuadPart = static_cast(size); + if (lisize.QuadPart < 0) { +#ifdef ERROR_FILE_TOO_LARGE + ec = detail::make_system_error(ERROR_FILE_TOO_LARGE); +#else + ec = detail::make_system_error(223); +#endif + return; + } + detail::unique_handle file(CreateFileW(GHC_NATIVEWP(p), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL)); + if (!file) { + ec = detail::make_system_error(); + } + else if (SetFilePointerEx(file.get(), lisize, NULL, FILE_BEGIN) == 0 || SetEndOfFile(file.get()) == 0) { + ec = detail::make_system_error(); + } +#else + if (::truncate(p.c_str(), static_cast(size)) != 0) { + ec = detail::make_system_error(); + } +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE space_info space(const path& p) +{ + std::error_code ec; + auto result = space(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE space_info space(const path& p, std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + ULARGE_INTEGER freeBytesAvailableToCaller = {{ 0, 0 }}; + ULARGE_INTEGER totalNumberOfBytes = {{ 0, 0 }}; + ULARGE_INTEGER totalNumberOfFreeBytes = {{ 0, 0 }}; + if (!GetDiskFreeSpaceExW(GHC_NATIVEWP(p), &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { + ec = detail::make_system_error(); + return {static_cast(-1), static_cast(-1), static_cast(-1)}; + } + return {static_cast(totalNumberOfBytes.QuadPart), static_cast(totalNumberOfFreeBytes.QuadPart), static_cast(freeBytesAvailableToCaller.QuadPart)}; +#else + struct ::statvfs sfs; + if (::statvfs(p.c_str(), &sfs) != 0) { + ec = detail::make_system_error(); + return {static_cast(-1), static_cast(-1), static_cast(-1)}; + } + return {static_cast(sfs.f_blocks) * static_cast(sfs.f_frsize), static_cast(sfs.f_bfree) * static_cast(sfs.f_frsize), static_cast(sfs.f_bavail) * static_cast(sfs.f_frsize)}; +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_status status(const path& p) +{ + std::error_code ec; + auto result = status(p, ec); + if (result.type() == file_type::none) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE file_status status(const path& p, std::error_code& ec) noexcept +{ + return detail::status_ex(p, ec); +} + +GHC_INLINE bool status_known(file_status s) noexcept +{ + return s.type() != file_type::none; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_status symlink_status(const path& p) +{ + std::error_code ec; + auto result = symlink_status(p, ec); + if (result.type() == file_type::none) { + throw filesystem_error(detail::systemErrorText(ec.value()), ec); + } + return result; +} +#endif + +GHC_INLINE file_status symlink_status(const path& p, std::error_code& ec) noexcept +{ + return detail::symlink_status_ex(p, ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path temp_directory_path() +{ + std::error_code ec; + path result = temp_directory_path(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), ec); + } + return result; +} +#endif + +GHC_INLINE path temp_directory_path(std::error_code& ec) noexcept +{ + ec.clear(); +#ifdef GHC_OS_WINDOWS + wchar_t buffer[512]; + auto rc = GetTempPathW(511, buffer); + if (!rc || rc > 511) { + ec = detail::make_system_error(); + return path(); + } + return path(std::wstring(buffer)); +#else + static const char* temp_vars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR", nullptr}; + const char* temp_path = nullptr; + for (auto temp_name = temp_vars; *temp_name != nullptr; ++temp_name) { + temp_path = std::getenv(*temp_name); + if (temp_path) { + return path(temp_path); + } + } + return path("/tmp"); +#endif +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE path weakly_canonical(const path& p) +{ + std::error_code ec; + auto result = weakly_canonical(p, ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), p, ec); + } + return result; +} +#endif + +GHC_INLINE path weakly_canonical(const path& p, std::error_code& ec) noexcept +{ + path result; + ec.clear(); + bool scan = true; + for (auto pe : p) { + if (scan) { + std::error_code tec; + if (exists(result / pe, tec)) { + result /= pe; + } + else { + if (ec) { + return path(); + } + scan = false; + if (!result.empty()) { + result = canonical(result, ec) / pe; + if (ec) { + break; + } + } + else { + result /= pe; + } + } + } + else { + result /= pe; + } + } + if (scan) { + if (!result.empty()) { + result = canonical(result, ec); + } + } + return ec ? path() : result.lexically_normal(); +} + +//----------------------------------------------------------------------------- +// [fs.class.file_status] class file_status +// [fs.file_status.cons] constructors and destructor +GHC_INLINE file_status::file_status() noexcept + : file_status(file_type::none) +{ +} + +GHC_INLINE file_status::file_status(file_type ft, perms prms) noexcept + : _type(ft) + , _perms(prms) +{ +} + +GHC_INLINE file_status::file_status(const file_status& other) noexcept + : _type(other._type) + , _perms(other._perms) +{ +} + +GHC_INLINE file_status::file_status(file_status&& other) noexcept + : _type(other._type) + , _perms(other._perms) +{ +} + +GHC_INLINE file_status::~file_status() {} + +// assignments: +GHC_INLINE file_status& file_status::operator=(const file_status& rhs) noexcept +{ + _type = rhs._type; + _perms = rhs._perms; + return *this; +} + +GHC_INLINE file_status& file_status::operator=(file_status&& rhs) noexcept +{ + _type = rhs._type; + _perms = rhs._perms; + return *this; +} + +// [fs.file_status.mods] modifiers +GHC_INLINE void file_status::type(file_type ft) noexcept +{ + _type = ft; +} + +GHC_INLINE void file_status::permissions(perms prms) noexcept +{ + _perms = prms; +} + +// [fs.file_status.obs] observers +GHC_INLINE file_type file_status::type() const noexcept +{ + return _type; +} + +GHC_INLINE perms file_status::permissions() const noexcept +{ + return _perms; +} + +//----------------------------------------------------------------------------- +// [fs.class.directory_entry] class directory_entry +// [fs.dir.entry.cons] constructors and destructor +// directory_entry::directory_entry() noexcept = default; +// directory_entry::directory_entry(const directory_entry&) = default; +// directory_entry::directory_entry(directory_entry&&) noexcept = default; +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE directory_entry::directory_entry(const filesystem::path& p) + : _path(p) + , _file_size(static_cast(-1)) +#ifndef GHC_OS_WINDOWS + , _hard_link_count(static_cast(-1)) +#endif + , _last_write_time(0) +{ + refresh(); +} +#endif + +GHC_INLINE directory_entry::directory_entry(const filesystem::path& p, std::error_code& ec) + : _path(p) + , _file_size(static_cast(-1)) +#ifndef GHC_OS_WINDOWS + , _hard_link_count(static_cast(-1)) +#endif + , _last_write_time(0) +{ + refresh(ec); +} + +GHC_INLINE directory_entry::~directory_entry() {} + +// assignments: +// directory_entry& directory_entry::operator=(const directory_entry&) = default; +// directory_entry& directory_entry::operator=(directory_entry&&) noexcept = default; + +// [fs.dir.entry.mods] directory_entry modifiers +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void directory_entry::assign(const filesystem::path& p) +{ + _path = p; + refresh(); +} +#endif + +GHC_INLINE void directory_entry::assign(const filesystem::path& p, std::error_code& ec) +{ + _path = p; + refresh(ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p) +{ + _path.replace_filename(p); + refresh(); +} +#endif + +GHC_INLINE void directory_entry::replace_filename(const filesystem::path& p, std::error_code& ec) +{ + _path.replace_filename(p); + refresh(ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void directory_entry::refresh() +{ + std::error_code ec; + refresh(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), _path, ec); + } +} +#endif + +GHC_INLINE void directory_entry::refresh(std::error_code& ec) noexcept +{ +#ifdef GHC_OS_WINDOWS + _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, nullptr, &_last_write_time); +#else + _status = detail::status_ex(_path, ec, &_symlink_status, &_file_size, &_hard_link_count, &_last_write_time); +#endif +} + +// [fs.dir.entry.obs] directory_entry observers +GHC_INLINE const filesystem::path& directory_entry::path() const noexcept +{ + return _path; +} + +GHC_INLINE directory_entry::operator const filesystem::path&() const noexcept +{ + return _path; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_type directory_entry::status_file_type() const +{ + return _status.type() != file_type::none ? _status.type() : filesystem::status(path()).type(); +} +#endif + +GHC_INLINE file_type directory_entry::status_file_type(std::error_code& ec) const noexcept +{ + if (_status.type() != file_type::none) { + ec.clear(); + return _status.type(); + } + return filesystem::status(path(), ec).type(); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::exists() const +{ + return status_file_type() != file_type::not_found; +} +#endif + +GHC_INLINE bool directory_entry::exists(std::error_code& ec) const noexcept +{ + return status_file_type(ec) != file_type::not_found; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_block_file() const +{ + return status_file_type() == file_type::block; +} +#endif +GHC_INLINE bool directory_entry::is_block_file(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::block; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_character_file() const +{ + return status_file_type() == file_type::character; +} +#endif + +GHC_INLINE bool directory_entry::is_character_file(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::character; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_directory() const +{ + return status_file_type() == file_type::directory; +} +#endif + +GHC_INLINE bool directory_entry::is_directory(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::directory; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_fifo() const +{ + return status_file_type() == file_type::fifo; +} +#endif + +GHC_INLINE bool directory_entry::is_fifo(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::fifo; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_other() const +{ + auto ft = status_file_type(); + return ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(); +} +#endif + +GHC_INLINE bool directory_entry::is_other(std::error_code& ec) const noexcept +{ + auto ft = status_file_type(ec); + bool other = ft != file_type::none && ft != file_type::not_found && ft != file_type::regular && ft != file_type::directory && !is_symlink(ec); + return !ec && other; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_regular_file() const +{ + return status_file_type() == file_type::regular; +} +#endif + +GHC_INLINE bool directory_entry::is_regular_file(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::regular; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_socket() const +{ + return status_file_type() == file_type::socket; +} +#endif + +GHC_INLINE bool directory_entry::is_socket(std::error_code& ec) const noexcept +{ + return status_file_type(ec) == file_type::socket; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE bool directory_entry::is_symlink() const +{ + return _symlink_status.type() != file_type::none ? _symlink_status.type() == file_type::symlink : filesystem::is_symlink(symlink_status()); +} +#endif + +GHC_INLINE bool directory_entry::is_symlink(std::error_code& ec) const noexcept +{ + if (_symlink_status.type() != file_type::none) { + ec.clear(); + return _symlink_status.type() == file_type::symlink; + } + return filesystem::is_symlink(symlink_status(ec)); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE uintmax_t directory_entry::file_size() const +{ + if (_file_size != static_cast(-1)) { + return _file_size; + } + return filesystem::file_size(path()); +} +#endif + +GHC_INLINE uintmax_t directory_entry::file_size(std::error_code& ec) const noexcept +{ + if (_file_size != static_cast(-1)) { + ec.clear(); + return _file_size; + } + return filesystem::file_size(path(), ec); +} + +#ifndef GHC_OS_WEB +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE uintmax_t directory_entry::hard_link_count() const +{ +#ifndef GHC_OS_WINDOWS + if (_hard_link_count != static_cast(-1)) { + return _hard_link_count; + } +#endif + return filesystem::hard_link_count(path()); +} +#endif + +GHC_INLINE uintmax_t directory_entry::hard_link_count(std::error_code& ec) const noexcept +{ +#ifndef GHC_OS_WINDOWS + if (_hard_link_count != static_cast(-1)) { + ec.clear(); + return _hard_link_count; + } +#endif + return filesystem::hard_link_count(path(), ec); +} +#endif + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_time_type directory_entry::last_write_time() const +{ + if (_last_write_time != 0) { + return std::chrono::system_clock::from_time_t(_last_write_time); + } + return filesystem::last_write_time(path()); +} +#endif + +GHC_INLINE file_time_type directory_entry::last_write_time(std::error_code& ec) const noexcept +{ + if (_last_write_time != 0) { + ec.clear(); + return std::chrono::system_clock::from_time_t(_last_write_time); + } + return filesystem::last_write_time(path(), ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_status directory_entry::status() const +{ + if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { + return _status; + } + return filesystem::status(path()); +} +#endif + +GHC_INLINE file_status directory_entry::status(std::error_code& ec) const noexcept +{ + if (_status.type() != file_type::none && _status.permissions() != perms::unknown) { + ec.clear(); + return _status; + } + return filesystem::status(path(), ec); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE file_status directory_entry::symlink_status() const +{ + if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { + return _symlink_status; + } + return filesystem::symlink_status(path()); +} +#endif + +GHC_INLINE file_status directory_entry::symlink_status(std::error_code& ec) const noexcept +{ + if (_symlink_status.type() != file_type::none && _symlink_status.permissions() != perms::unknown) { + ec.clear(); + return _symlink_status; + } + return filesystem::symlink_status(path(), ec); +} + +#ifdef GHC_HAS_THREEWAY_COMP +GHC_INLINE std::strong_ordering directory_entry::operator<=>(const directory_entry& rhs) const noexcept +{ + return _path <=> rhs._path; +} +#endif + +GHC_INLINE bool directory_entry::operator<(const directory_entry& rhs) const noexcept +{ + return _path < rhs._path; +} + +GHC_INLINE bool directory_entry::operator==(const directory_entry& rhs) const noexcept +{ + return _path == rhs._path; +} + +GHC_INLINE bool directory_entry::operator!=(const directory_entry& rhs) const noexcept +{ + return _path != rhs._path; +} + +GHC_INLINE bool directory_entry::operator<=(const directory_entry& rhs) const noexcept +{ + return _path <= rhs._path; +} + +GHC_INLINE bool directory_entry::operator>(const directory_entry& rhs) const noexcept +{ + return _path > rhs._path; +} + +GHC_INLINE bool directory_entry::operator>=(const directory_entry& rhs) const noexcept +{ + return _path >= rhs._path; +} + +//----------------------------------------------------------------------------- +// [fs.class.directory_iterator] class directory_iterator + +#ifdef GHC_OS_WINDOWS +class directory_iterator::impl +{ +public: + impl(const path& p, directory_options options) + : _base(p) + , _options(options) + , _dirHandle(INVALID_HANDLE_VALUE) + { + if (!_base.empty()) { + ZeroMemory(&_findData, sizeof(WIN32_FIND_DATAW)); + if ((_dirHandle = FindFirstFileW(GHC_NATIVEWP((_base / "*")), &_findData)) != INVALID_HANDLE_VALUE) { + if (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L"..") { + increment(_ec); + } + else { + _dir_entry._path = _base / std::wstring(_findData.cFileName); + copyToDirEntry(_ec); + } + } + else { + auto error = ::GetLastError(); + _base = filesystem::path(); + if (error != ERROR_ACCESS_DENIED || (options & directory_options::skip_permission_denied) == directory_options::none) { + _ec = detail::make_system_error(); + } + } + } + } + impl(const impl& other) = delete; + ~impl() + { + if (_dirHandle != INVALID_HANDLE_VALUE) { + FindClose(_dirHandle); + _dirHandle = INVALID_HANDLE_VALUE; + } + } + void increment(std::error_code& ec) + { + if (_dirHandle != INVALID_HANDLE_VALUE) { + do { + if (FindNextFileW(_dirHandle, &_findData)) { + _dir_entry._path = _base; +#ifdef GHC_USE_WCHAR_T + _dir_entry._path.append_name(_findData.cFileName); +#else +#ifdef GHC_RAISE_UNICODE_ERRORS + try { + _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); + } + catch (filesystem_error& fe) { + ec = fe.code(); + return; + } +#else + _dir_entry._path.append_name(detail::toUtf8(_findData.cFileName).c_str()); +#endif +#endif + copyToDirEntry(ec); + } + else { + auto err = ::GetLastError(); + if (err != ERROR_NO_MORE_FILES) { + _ec = ec = detail::make_system_error(err); + } + FindClose(_dirHandle); + _dirHandle = INVALID_HANDLE_VALUE; + _dir_entry._path.clear(); + break; + } + } while (std::wstring(_findData.cFileName) == L"." || std::wstring(_findData.cFileName) == L".."); + } + else { + ec = _ec; + } + } + void copyToDirEntry(std::error_code& ec) + { + if (_findData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + _dir_entry._status = detail::status_ex(_dir_entry._path, ec, &_dir_entry._symlink_status, &_dir_entry._file_size, nullptr, &_dir_entry._last_write_time); + } + else { + _dir_entry._status = detail::status_from_INFO(_dir_entry._path, &_findData, ec, &_dir_entry._file_size, &_dir_entry._last_write_time); + _dir_entry._symlink_status = _dir_entry._status; + } + if (ec) { + if (_dir_entry._status.type() != file_type::none && _dir_entry._symlink_status.type() != file_type::none) { + ec.clear(); + } + else { + _dir_entry._file_size = static_cast(-1); + _dir_entry._last_write_time = 0; + } + } + } + path _base; + directory_options _options; + WIN32_FIND_DATAW _findData; + HANDLE _dirHandle; + directory_entry _dir_entry; + std::error_code _ec; +}; +#else +// POSIX implementation +class directory_iterator::impl +{ +public: + impl(const path& path, directory_options options) + : _base(path) + , _options(options) + , _dir(nullptr) + , _entry(nullptr) + { + if (!path.empty()) { + _dir = ::opendir(path.native().c_str()); + if (!_dir) { + auto error = errno; + _base = filesystem::path(); + if ((error != EACCES && error != EPERM) || (options & directory_options::skip_permission_denied) == directory_options::none) { + _ec = detail::make_system_error(); + } + } + else { + increment(_ec); + } + } + } + impl(const impl& other) = delete; + ~impl() + { + if (_dir) { + ::closedir(_dir); + } + } + void increment(std::error_code& ec) + { + if (_dir) { + bool skip; + do { + skip = false; + errno = 0; + _entry = ::readdir(_dir); + if (_entry) { + _dir_entry._path = _base; + _dir_entry._path.append_name(_entry->d_name); + copyToDirEntry(); + if (ec && (ec.value() == EACCES || ec.value() == EPERM) && (_options & directory_options::skip_permission_denied) == directory_options::skip_permission_denied) { + ec.clear(); + skip = true; + } + } + else { + ::closedir(_dir); + _dir = nullptr; + _dir_entry._path.clear(); + if (errno) { + ec = detail::make_system_error(); + } + break; + } + } while (skip || std::strcmp(_entry->d_name, ".") == 0 || std::strcmp(_entry->d_name, "..") == 0); + } + } + + void copyToDirEntry() + { + _dir_entry._symlink_status.permissions(perms::unknown); + auto ft = detail::file_type_from_dirent(*_entry); + _dir_entry._symlink_status.type(ft); + if (ft != file_type::symlink) { + _dir_entry._status = _dir_entry._symlink_status; + } + else { + _dir_entry._status.type(file_type::none); + _dir_entry._status.permissions(perms::unknown); + } + _dir_entry._file_size = static_cast(-1); + _dir_entry._hard_link_count = static_cast(-1); + _dir_entry._last_write_time = 0; + } + path _base; + directory_options _options; + DIR* _dir; + struct ::dirent* _entry; + directory_entry _dir_entry; + std::error_code _ec; +}; +#endif + +// [fs.dir.itr.members] member functions +GHC_INLINE directory_iterator::directory_iterator() noexcept + : _impl(new impl(path(), directory_options::none)) +{ +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE directory_iterator::directory_iterator(const path& p) + : _impl(new impl(p, directory_options::none)) +{ + if (_impl->_ec) { + throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); + } + _impl->_ec.clear(); +} + +GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options) + : _impl(new impl(p, options)) +{ + if (_impl->_ec) { + throw filesystem_error(detail::systemErrorText(_impl->_ec.value()), p, _impl->_ec); + } +} +#endif + +GHC_INLINE directory_iterator::directory_iterator(const path& p, std::error_code& ec) noexcept + : _impl(new impl(p, directory_options::none)) +{ + if (_impl->_ec) { + ec = _impl->_ec; + } +} + +GHC_INLINE directory_iterator::directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept + : _impl(new impl(p, options)) +{ + if (_impl->_ec) { + ec = _impl->_ec; + } +} + +GHC_INLINE directory_iterator::directory_iterator(const directory_iterator& rhs) + : _impl(rhs._impl) +{ +} + +GHC_INLINE directory_iterator::directory_iterator(directory_iterator&& rhs) noexcept + : _impl(std::move(rhs._impl)) +{ +} + +GHC_INLINE directory_iterator::~directory_iterator() {} + +GHC_INLINE directory_iterator& directory_iterator::operator=(const directory_iterator& rhs) +{ + _impl = rhs._impl; + return *this; +} + +GHC_INLINE directory_iterator& directory_iterator::operator=(directory_iterator&& rhs) noexcept +{ + _impl = std::move(rhs._impl); + return *this; +} + +GHC_INLINE const directory_entry& directory_iterator::operator*() const +{ + return _impl->_dir_entry; +} + +GHC_INLINE const directory_entry* directory_iterator::operator->() const +{ + return &_impl->_dir_entry; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE directory_iterator& directory_iterator::operator++() +{ + std::error_code ec; + _impl->increment(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_entry._path, ec); + } + return *this; +} +#endif + +GHC_INLINE directory_iterator& directory_iterator::increment(std::error_code& ec) noexcept +{ + _impl->increment(ec); + return *this; +} + +GHC_INLINE bool directory_iterator::operator==(const directory_iterator& rhs) const +{ + return _impl->_dir_entry._path == rhs._impl->_dir_entry._path; +} + +GHC_INLINE bool directory_iterator::operator!=(const directory_iterator& rhs) const +{ + return _impl->_dir_entry._path != rhs._impl->_dir_entry._path; +} + +// [fs.dir.itr.nonmembers] directory_iterator non-member functions + +GHC_INLINE directory_iterator begin(directory_iterator iter) noexcept +{ + return iter; +} + +GHC_INLINE directory_iterator end(const directory_iterator&) noexcept +{ + return directory_iterator(); +} + +//----------------------------------------------------------------------------- +// [fs.class.rec.dir.itr] class recursive_directory_iterator + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator() noexcept + : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) +{ + _impl->_dir_iter_stack.push(directory_iterator()); +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p) + : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) +{ + _impl->_dir_iter_stack.push(directory_iterator(p)); +} + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options) + : _impl(new recursive_directory_iterator_impl(options, true)) +{ + _impl->_dir_iter_stack.push(directory_iterator(p, options)); +} +#endif + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, directory_options options, std::error_code& ec) noexcept + : _impl(new recursive_directory_iterator_impl(options, true)) +{ + _impl->_dir_iter_stack.push(directory_iterator(p, options, ec)); +} + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const path& p, std::error_code& ec) noexcept + : _impl(new recursive_directory_iterator_impl(directory_options::none, true)) +{ + _impl->_dir_iter_stack.push(directory_iterator(p, ec)); +} + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(const recursive_directory_iterator& rhs) + : _impl(rhs._impl) +{ +} + +GHC_INLINE recursive_directory_iterator::recursive_directory_iterator(recursive_directory_iterator&& rhs) noexcept + : _impl(std::move(rhs._impl)) +{ +} + +GHC_INLINE recursive_directory_iterator::~recursive_directory_iterator() {} + +// [fs.rec.dir.itr.members] observers +GHC_INLINE directory_options recursive_directory_iterator::options() const +{ + return _impl->_options; +} + +GHC_INLINE int recursive_directory_iterator::depth() const +{ + return static_cast(_impl->_dir_iter_stack.size() - 1); +} + +GHC_INLINE bool recursive_directory_iterator::recursion_pending() const +{ + return _impl->_recursion_pending; +} + +GHC_INLINE const directory_entry& recursive_directory_iterator::operator*() const +{ + return *(_impl->_dir_iter_stack.top()); +} + +GHC_INLINE const directory_entry* recursive_directory_iterator::operator->() const +{ + return &(*(_impl->_dir_iter_stack.top())); +} + +// [fs.rec.dir.itr.members] modifiers recursive_directory_iterator& +GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(const recursive_directory_iterator& rhs) +{ + _impl = rhs._impl; + return *this; +} + +GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator=(recursive_directory_iterator&& rhs) noexcept +{ + _impl = std::move(rhs._impl); + return *this; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator++() +{ + std::error_code ec; + increment(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); + } + return *this; +} +#endif + +GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept +{ + bool isSymLink = (*this)->is_symlink(ec); + bool isDir = !ec && (*this)->is_directory(ec); + if (isSymLink && detail::is_not_found_error(ec)) { + ec.clear(); + } + if (!ec) { + if (recursion_pending() && isDir && (!isSymLink || (options() & directory_options::follow_directory_symlink) != directory_options::none)) { + _impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec)); + } + else { + _impl->_dir_iter_stack.top().increment(ec); + } + if (!ec) { + while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()) { + _impl->_dir_iter_stack.pop(); + _impl->_dir_iter_stack.top().increment(ec); + } + } + else if (!_impl->_dir_iter_stack.empty()) { + _impl->_dir_iter_stack.pop(); + } + _impl->_recursion_pending = true; + } + return *this; +} + +#ifdef GHC_WITH_EXCEPTIONS +GHC_INLINE void recursive_directory_iterator::pop() +{ + std::error_code ec; + pop(ec); + if (ec) { + throw filesystem_error(detail::systemErrorText(ec.value()), _impl->_dir_iter_stack.empty() ? path() : _impl->_dir_iter_stack.top()->path(), ec); + } +} +#endif + +GHC_INLINE void recursive_directory_iterator::pop(std::error_code& ec) +{ + if (depth() == 0) { + *this = recursive_directory_iterator(); + } + else { + do { + _impl->_dir_iter_stack.pop(); + _impl->_dir_iter_stack.top().increment(ec); + } while (depth() && _impl->_dir_iter_stack.top() == directory_iterator()); + } +} + +GHC_INLINE void recursive_directory_iterator::disable_recursion_pending() +{ + _impl->_recursion_pending = false; +} + +// other members as required by [input.iterators] +GHC_INLINE bool recursive_directory_iterator::operator==(const recursive_directory_iterator& rhs) const +{ + return _impl->_dir_iter_stack.top() == rhs._impl->_dir_iter_stack.top(); +} + +GHC_INLINE bool recursive_directory_iterator::operator!=(const recursive_directory_iterator& rhs) const +{ + return _impl->_dir_iter_stack.top() != rhs._impl->_dir_iter_stack.top(); +} + +// [fs.rec.dir.itr.nonmembers] directory_iterator non-member functions +GHC_INLINE recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept +{ + return iter; +} + +GHC_INLINE recursive_directory_iterator end(const recursive_directory_iterator&) noexcept +{ + return recursive_directory_iterator(); +} + +#endif // GHC_EXPAND_IMPL + +} // namespace filesystem +} // namespace ghc + +// cleanup some macros +#undef GHC_INLINE +#undef GHC_EXPAND_IMPL + +#endif // GHC_FILESYSTEM_H diff --git a/OpenDSSC/Common/windows2posix.h b/OpenDSSC/Common/windows2posix.h new file mode 100644 index 0000000..f118cdd --- /dev/null +++ b/OpenDSSC/Common/windows2posix.h @@ -0,0 +1,138 @@ +#ifndef _WINDOWS2POSIX_H +#define _WINDOWS2POSIX_H + +// This file should only be pulled in for compiling on POSIX platforms +// excluding MS Windows. +#include // assert +#include // errno +#include // uint_least64_t +#include // memset +#include "filesystem.hpp" +#include // cerr +#include +#include // readlink +#include // clock_gettime + +// Notes / Requirements: +// +// To minimize surprises, all functions must emulate their MS Windows +// equivalents in inputs, outputs, error reporting, and exception safety. +// +// Thus for functions which are not documented to throw exceptions (like +// CopyFile), these functions must be marked with the noexcept keyword. +// +// Also, every function shall have "static inline". "static" is needed because +// we're keeping these functions in a header file at the moment, and we don't +// want name collisions between multiple source (.cpp or .c) files. "inline" +// is a hint to the compiler to request inlining the functions wherever they're +// called, but the compiler is still free to not inline. +// +// If a function deviates from the docs, please note it with a brief +// explanation. + +static inline bool CopyFile(const char *ExistingFileName, const char *NewFileName, bool FailIfExists) noexcept +{ + // Emulate behavior of this description: + // https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfile + // return nonzero on success, and zero on failure with an error + // number available via GetLastError + + // Here, we're assuming C++17. If we only have C++11 available such as + // possibly on RHEL 7.x, then the Boost library has the same + // functionality. + +#if 0 + std::error_code ec; + bool retval = ghc::filesystem::copy_file( + ExistingFileName, + NewFileName, + FailIfExists ? ghc::filesystem::copy_options::none : ghc::filesystem::copy_options::overwrite_existing, + ec); + // need to do: Put ec into errno since this is what Support/d2c_sysexcept.cpp will use for emulating GetLastError + // This bug report gives for detail: (read it for history) + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60555 + + // Instead of all that, do this: +#endif + try { + return ghc::filesystem::copy_file( + ExistingFileName, + NewFileName, + FailIfExists ? ghc::filesystem::copy_options::none : ghc::filesystem::copy_options::overwrite_existing + ); + } + catch (const std::system_error &e) { + errno = e.code().value(); // Will this always return an errno-compatible value on Linux systems? How about other POSIX systems? + return false; + } + catch (const std::exception &e) { + + // TODO: Extend our GetLastError mechanism to let us + // dynamically allocate new error values as we encounter new + // e.what() messages. + + std::cerr << "Encountered error in CopyFile(\"" << + ExistingFileName << "\", \"" << NewFileName << "\", \"" + << FailIfExists << "\"): message=\"" << e.what() << "\"\n"; + + errno = -1; // This will cause strerror(errno) to return "Unknown error". (or the equivalent for the locale) + return false; + } + catch (...) { + std::cerr << "Encountered unknown error in CopyFile(\"" << + ExistingFileName << "\", \"" << NewFileName << "\", \"" + << FailIfExists << "\")\n"; + + errno = -1; // This will cause strerror(errno) to return "Unknown error". (or the equivalent for the locale) + return false; + } +} + + +template +static inline size_t GetModuleFileName(const T& must_be_zero, char *Filename, size_t max_Filename_len) noexcept +{ + // https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea + + assert( !must_be_zero /* This function assumes the first parameter is zero or NULL. */ ); + + // Deviation: This function does not try to emulate the behavior of + // Windows XP when the buffer size is too small. + + // Deviation: When max_Filename_len is too small, this function sets + // errno = ENOMEM (Out of memory) instead of ERROR_INSUFFICIENT_BUFFER, + // because we don't have ERROR_INSUFFICIENT_BUFFER in POSIX. Is there + // a better standard value for errno? + + // GetDSSExeFile( ) in Forms/CmdForms.cpp happens to have similar code: + ssize_t len = readlink("/proc/self/exe", Filename, max_Filename_len); + if(len != -1) + return 0; // readlink() has already set errno, so this covers GetLastError. + + // Emulate the rest of the MS behavior as best we can: + if (size_t(len) +#include "Utilities.h" + +using namespace std; +using namespace Bus; +using namespace CapControlVars; +using namespace CapUserControl; +using namespace Capacitor; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace CapControl +{ + +TCapControlObj::TCapControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TCapControlObj::TCapControlObj(String ClassName) : inherited(ClassName) {} +TCapControlObj::TCapControlObj() {} + + +TCapControlObj* ActiveCapControlObj = nullptr; +const int AVGPHASES = -1; +const int MAXPHASE = -2; +const int MINPHASE = -3; +const int NumPropsThisClass = 23; + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all CapControl objects + +TCapControl::TCapControl() +{ + ; + Class_Name = "CapControl"; + DSSClassType = DSSClassType + CAP_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TCapControl::~TCapControl() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "element"; + PropertyName[2 - 1] = "terminal"; + PropertyName[3 - 1] = "capacitor"; + PropertyName[4 - 1] = "type"; + PropertyName[5 - 1] = "PTratio"; + PropertyName[6 - 1] = "CTratio"; + PropertyName[7 - 1] = "ONsetting"; + PropertyName[8 - 1] = "OFFsetting"; + PropertyName[9 - 1] = "Delay"; + PropertyName[10 - 1] = "VoltOverride"; + PropertyName[11 - 1] = "Vmax"; + PropertyName[12 - 1] = "Vmin"; + PropertyName[13 - 1] = "DelayOFF"; + PropertyName[14 - 1] = "DeadTime"; + PropertyName[15 - 1] = "CTPhase"; + PropertyName[16 - 1] = "PTPhase"; + PropertyName[17 - 1] = "VBus"; + PropertyName[18 - 1] = "EventLog"; + PropertyName[19 - 1] = "UserModel"; + PropertyName[20 - 1] = "UserData"; + PropertyName[21 - 1] = "pctMinkvar"; + PropertyName[22 - 1] = "Reset"; + PropertyName[23 - 1] = "ControlSignal"; + PropertyHelp[1 - 1] = "Full object name of the circuit element, typically a line or transformer, " + "to which the capacitor control's PT and/or CT are connected." + "There is no default; must be specified."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the CapControl is connected. " + "1 or 2, typically. Default is 1."; + PropertyHelp[3 - 1] = String("Name of Capacitor element which the CapControl controls. No Default; Must be specified." "Do not specify the full object name; \"Capacitor\" is assumed for " "the object class. Example:") + CRLF + + CRLF + + "Capacitor=cap1"; + PropertyHelp[4 - 1] = "{Current | voltage | kvar | PF | time | Follow } Control type. Specify the ONsetting and OFFsetting " + "appropriately with the type of control. (See help for ONsetting)"; + PropertyHelp[5 - 1] = "Ratio of the PT that converts the monitored voltage to the control voltage. " + "Default is 60. If the capacitor is Wye, the 1st phase line-to-neutral voltage is monitored. Else, the line-to-line " + "voltage (1st - 2nd phase) is monitored."; + PropertyHelp[6 - 1] = "Ratio of the CT from line amps to control ampere setting for current and kvar control types. "; + PropertyHelp[7 - 1] = String("Value at which the control arms to switch the capacitor ON (or ratchet up a step). ") + CRLF + + CRLF + + "Type of Control:" + + CRLF + + CRLF + + "Current: Line Amps / CTratio" + + CRLF + + "Voltage: Line-Neutral (or Line-Line for delta) Volts / PTratio" + + CRLF + + "kvar: Total kvar, all phases (3-phase for pos seq model). This is directional. " + + CRLF + + "PF: Power Factor, Total power in monitored terminal. Negative for Leading. " + + CRLF + + "Time: Hrs from Midnight as a floating point number (decimal). 7:30am would be entered as 7.5." + + CRLF + + "Follow: Follows a loadshape(ControlSignal) to determine when to turn ON / OFF the capacitor.If the value is different than 0 the cap will connect to the grid, otherwise, it will be disconnected."; + PropertyHelp[8 - 1] = "Value at which the control arms to switch the capacitor OFF. (See help for ONsetting)" + "For Time control, is OK to have Off time the next day ( < On time)"; + PropertyHelp[9 - 1] = "Time delay, in seconds, from when the control is armed before it sends out the switching " + "command to turn ON. The control may reset before the action actually occurs. " + "This is used to determine which capacity control will act first. Default is 15. You may specify any " + "floating point number to achieve a model of whatever condition is necessary."; + PropertyHelp[10 - 1] = "{Yes | No} Default is No. Switch to indicate whether VOLTAGE OVERRIDE is to be considered. " + "Vmax and Vmin must be set to reasonable values if this property is Yes."; + PropertyHelp[11 - 1] = "Maximum voltage, in volts. If the voltage across the capacitor divided by the PTRATIO is greater " + "than this voltage, the capacitor will switch OFF regardless of other control settings. " + "Default is 126 (goes with a PT ratio of 60 for 12.47 kV system)."; + PropertyHelp[12 - 1] = "Minimum voltage, in volts. If the voltage across the capacitor divided by the PTRATIO is less " + "than this voltage, the capacitor will switch ON regardless of other control settings. " + "Default is 115 (goes with a PT ratio of 60 for 12.47 kV system)."; + PropertyHelp[13 - 1] = "Time delay, in seconds, for control to turn OFF when present state is ON. Default is 15."; + PropertyHelp[14 - 1] = "Dead time after capacitor is turned OFF before it can be turned back ON. Default is 300 sec."; + PropertyHelp[15 - 1] = "Number of the phase being monitored for CURRENT control or one of {AVG | MAX | MIN} for all phases. Default=1. " + "If delta or L-L connection, enter the first or the two phases being monitored [1-2, 2-3, 3-1]. " + "Must be less than the number of phases. Does not apply to kvar control which uses all phases by default."; + PropertyHelp[16 - 1] = "Number of the phase being monitored for VOLTAGE control or one of {AVG | MAX | MIN} for all phases. Default=1. " + "If delta or L-L connection, enter the first or the two phases being monitored [1-2, 2-3, 3-1]. " + "Must be less than the number of phases. Does not apply to kvar control which uses all phases by default."; + PropertyHelp[17 - 1] = "Name of bus to use for voltage override function. Default is bus at monitored terminal. " + "Sometimes it is useful to monitor a bus in another location to emulate various DMS control algorithms."; + PropertyHelp[18 - 1] = "{Yes/True* | No/False} Default is YES for CapControl. Log control actions to Eventlog."; + PropertyHelp[19 - 1] = "Name of DLL containing user-written CapControl model, overriding the default model. Set to \"none\" to negate previous setting. "; + PropertyHelp[20 - 1] = "String (in quotes or parentheses if necessary) that gets passed to the user-written CapControl model Edit function for defining the data required for that model. "; + PropertyHelp[21 - 1] = "For PF control option, min percent of total bank kvar at which control will close capacitor switch. Default = 50."; + PropertyHelp[22 - 1] = "{Yes | No} If Yes, forces Reset of this CapControl."; + PropertyHelp[23 - 1] = "Is the name of the load shape used for controlling the connection / disconnection of the capacitor to the grid, " + "when the load shape is DIFFERENT than ZERO (0) the capacitor will be ON and connected to the grid." + "Otherwise, if the load shape value is EQUAL to ZERO(0) the capacitor bank will be OFF and disconnected from the grid."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TCapControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new CapControl and add it to CapControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TCapControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TCapControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + + // continue parsing WITH contents of Parser + ActiveCapControlObj = (TCapControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveCapControlObj); + result = 0; + /*# with ActiveCapControlObj do */ + { + auto with0 = ActiveCapControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 352); + break; + case 1: + with0->ElementName = ConstructElemName(LowerCase(Param)); + break; // substitute @var value if any + case 2: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->ControlVars.CapacitorName = String("capacitor.") + Param; + with0->ControlVars.CapacitorNamePtr = with0->ControlVars.CapacitorName.data(); + break; // will automatically substitute @var value + case 4: + switch(LowerCase(Param)[0]) + { + case L'c': + with0->ControlType = CURRENTCONTROL; + break; + case L'v': + with0->ControlType = VOLTAGECONTROL; + break; + case L'k': + with0->ControlType = KVARCONTROL; + break; + case L't': + with0->ControlType = TIMECONTROL; + break; + case L'p': + with0->ControlType = PFCONTROL; + break; + case L'f': + with0->ControlType = FOLLOWCONTROL; + break; + default: + DoSimpleMsg("Unrecognized CapControl Type: " + Param + " (Capcontrol.)" + ActiveCapControlObj->get_Name(), 352); + break; + } + break; + case 5: + with0->ControlVars.PTRatio = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->ControlVars.CTRatio = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->ControlVars.ON_Value = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->ControlVars.OFF_Value = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->ControlVars.OnDelay = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->ControlVars.Voverride = InterpretYesNo(Param); + break; + case 11: + with0->ControlVars.Vmax = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->ControlVars.Vmin = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->ControlVars.OFFDelay = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->ControlVars.DeadTime = Parser[ActorID]->MakeDouble_(); + break; + case 15: + if(CompareTextShortest(Param, "avg") == 0) + with0->ControlVars.FCTPhase = AVGPHASES; + else + { + if(CompareTextShortest(Param, "max") == 0) + with0->ControlVars.FCTPhase = MAXPHASE; + else + { + if(CompareTextShortest(Param, "min") == 0) + with0->ControlVars.FCTPhase = MINPHASE; + else + with0->ControlVars.FCTPhase = max(1, Parser[ActorID]->MakeInteger_()); + } + } + break; + case 16: + if(CompareTextShortest(Param, "avg") == 0) + with0->ControlVars.FPTPhase = AVGPHASES; + else + { + if(CompareTextShortest(Param, "max") == 0) + with0->ControlVars.FPTPhase = MAXPHASE; + else + { + if(CompareTextShortest(Param, "min") == 0) + with0->ControlVars.FPTPhase = MINPHASE; + else + with0->ControlVars.FPTPhase = max(1, Parser[ActorID]->MakeInteger_()); + } + } + break; + case 17: + { + with0->ControlVars.VoverrideBusSpecified = true; + with0->ControlVars.VOverrideBusName = Param; + with0->ControlVars.VOverrideBusNamePtr = with0->ControlVars.VOverrideBusName.data(); + } + break; + case 18: + with0->ShowEventLog = InterpretYesNo(Param); + break; + case 19: + with0->UserModel->Set_Name(Parser[ActorID]->MakeString_()); + break; // Connect to user written model + case 20: + with0->UserModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; // Send edit string to user model + case 21: + with0->FpctMinkvar = Parser[ActorID]->MakeDouble_(); + break; + case 22: + if(InterpretYesNo(Param)) // force a reset + { + with0->Reset(ActorID); + with0->Set_PropertyValue(22, "n"); // so it gets reported properly + } + break; + case 23: + with0->myShapeName = Param; + break; + // Inherited parameters + default: + ClassEdit(ActiveCapControlObj, ParamPointer - NumPropsThisClass); + break; + } + + + /*PF Controller changes*/ + auto& with1 = with0->ControlVars; + if(with0->ControlType == PFCONTROL) + /*# with ControlVars do */ + { + switch(ParamPointer) + { + case 1: + with0->Set_PropertyValue(1, with0->ElementName); + break; // Synch up with change + case 4: + { + with1.PFON_Value = 0.95; // defaults + with1.PFOFF_Value = 1.05; + } + break; + case 7: + { + if((with1.ON_Value >= - 1.0) && (with1.ON_Value <= 1.0)) + { + if(with1.ON_Value < 0.0) + with1.PFON_Value = 2.0 + with1.ON_Value; + else + with1.PFON_Value = with1.ON_Value; + } + else + { + DoSimpleMsg(String("Invalid PF ON value for CapControl.") + ActiveCapControlObj->get_Name(), 353); + } + } + break; + case 8: + { + if((with1.OFF_Value >= - 1.0) && (with1.OFF_Value <= 1.0)) + { + if(with1.OFF_Value < 0.0) + with1.PFOFF_Value = 2.0 + with1.OFF_Value; + else + with1.PFOFF_Value = with1.OFF_Value; + } + else + { + DoSimpleMsg(String("Invalid PF OFF value for CapControl.") + ActiveCapControlObj->get_Name(), 35301); + } + } + break; + default: + ; + break; + } + } + + switch (ParamPointer) + { + case 15: + { + if (with1.FCTPhase > with0->Fnphases) + { + DoSimpleMsg(Format("Error: Monitored phase(%d) must be less than or equal to number of phases(%d). ", with1.FCTPhase, with0->Fnphases), 35302); + with1.FCTPhase = 1; + } + } + break; + case 16: + { + if (with1.FPTPhase > with0->Fnphases) + { + DoSimpleMsg(Format("Error: Monitored phase(%d) must be less than or equal to number of phases(%d). ", with1.FPTPhase, with0->Fnphases), 35303); + with1.FPTPhase = 1; + } + } + break; + case 19: + with0->IsUserModel = with0->UserModel->Get_Exists(); + break; + case 23: + with0->myShapeObj = (TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->myShapeName); + break; + default: + ; + break; + } + if(with0->IsUserModel) + with0->ControlType = USERCONTROL; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TCapControl::MakeLike(const String CapControlName) +{ + int result = 0; + TCapControlObj* OtherCapControl = nullptr; + int i = 0; + result = 0; + /*See if we can find this CapControl name in the present collection*/ + OtherCapControl = ((TCapControlObj*) Find(CapControlName)); + if(OtherCapControl != nullptr) + /*# with ActiveCapControlObj do */ + { + auto with0 = ActiveCapControlObj; + int stop = 0; + with0->Set_NPhases(OtherCapControl->Fnphases); + with0->Set_Nconds(OtherCapControl->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherCapControl->ElementName; + with0->ControlVars.CapacitorName = OtherCapControl->ControlVars.CapacitorName; + with0->ControlVars.CapacitorNamePtr = with0->ControlVars.CapacitorName.data(); + with0->Set_ControlledElement(OtherCapControl->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherCapControl->get_FMonitoredElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherCapControl->ElementTerminal; + /*# with ControlVars do */ + { + auto& with1 = with0->ControlVars; + with1.PTRatio = OtherCapControl->ControlVars.PTRatio; + with1.CTRatio = OtherCapControl->ControlVars.CTRatio; + with0->ControlType = OtherCapControl->ControlType; + with1.PresentState = OtherCapControl->ControlVars.PresentState; + with1.ShouldSwitch = OtherCapControl->ControlVars.ShouldSwitch; + with1.CondOffset = OtherCapControl->ControlVars.CondOffset; + with1.ON_Value = OtherCapControl->ControlVars.ON_Value; + with1.OFF_Value = OtherCapControl->ControlVars.OFF_Value; + with1.PFON_Value = OtherCapControl->ControlVars.PFON_Value; + with1.PFOFF_Value = OtherCapControl->ControlVars.PFOFF_Value; + with1.FCTPhase = OtherCapControl->ControlVars.FCTPhase; + with1.FPTPhase = OtherCapControl->ControlVars.FPTPhase; + with1.Voverride = OtherCapControl->ControlVars.Voverride; + with1.VoverrideBusSpecified = OtherCapControl->ControlVars.VoverrideBusSpecified; // Added 8-11-11 + with1.VOverrideBusName = OtherCapControl->ControlVars.VOverrideBusName; + with1.VOverrideBusNamePtr = with1.VOverrideBusName.data(); + } + with0->UserModel->Set_Name(OtherCapControl->UserModel->get_FName()); // Connect to user written models + with0->IsUserModel = OtherCapControl->IsUserModel; + with0->FpctMinkvar = OtherCapControl->FpctMinkvar; + with0->ShowEventLog = OtherCapControl->ShowEventLog; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i, OtherCapControl->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in CapControl MakeLike: \"") + CapControlName + + "\" Not Found.", 360); + return result; +} + + +/*==========================================================================*/ +/* TCapControlObj */ +/*==========================================================================*/ + + +/*--------------------------------------------------------------------------*/ + +TCapControlObj::TCapControlObj(TDSSClass* ParClass, const String CapControlName) + : inherited(ParClass), + ControlType(CURRENTCONTROL), + ControlledCapacitor(nullptr), + IsUserModel(false), + UserModel(nullptr), + FpctMinkvar(0.0) +{ + Set_Name(LowerCase(CapControlName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + /*# with ControlVars do */ + cBuffer.clear(); + { + auto& with0 = ControlVars; + with0.FCTPhase = 1; + with0.FPTPhase = 1; + with0.PTRatio = 60.0; + with0.CTRatio = 60.0; + ControlType = CURRENTCONTROL; + with0.OnDelay = 15.0; + with0.OFFDelay = 15.0; + with0.DeadTime = 300.0; + with0.LastOpenTime = -with0.DeadTime; + with0.ON_Value = 300.0; + with0.OFF_Value = 200.0; + with0.PFON_Value = 0.95; + with0.PFOFF_Value = 1.05; + with0.Voverride = false; + with0.VoverrideEvent = false; + with0.VoverrideBusSpecified = false; + with0.VOverrideBusName = ""; // This is not in public data Struct at this time + with0.VOverrideBusNamePtr = nullptr; + with0.Vmax = 126; + with0.Vmin = 115; + with0.PresentState = CTRL_CLOSE; + with0.ShouldSwitch = false; + with0.Armed = false; + with0.AvailableSteps = 0; + Set_PendingChange(CTRL_NONE); + } + PublicDataStruct = &ControlVars; // So User-written models can access + PublicDataSize = sizeof(TCapControlVars); + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + ControlVars.CapacitorName = ""; + ControlVars.CapacitorNamePtr = nullptr; + Set_MonitoredElement(nullptr); + myShapeName = ""; + myShapeObj = nullptr; + + FpctMinkvar = 50.0; + IsUserModel = false; + UserModel = new TCapUserControl(); // Inits handles, FID + ControlVars.ControlActionHandle = 0; + DSSObjType = ParClass->DSSClassType; //cap_CONTROL; + InitPropertyValues(0); + + // RecalcElementData; +} + +TCapControlObj::~TCapControlObj() +{ + ElementName = ""; + ControlVars.CapacitorName = ""; + if(!cBuffer.empty()) + cBuffer.clear(); + try + { + delete UserModel; +/* } + __finally + {*/ + UserModel = nullptr; // do nothing + } + catch (...) + { + // + } + // inherited::Destroy(); +} + + + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + +/*Check for existence of capacitor*/ + +// 5-21-01 RCD moved this section ahead of monitored element so Nphases gets defined first + DevIndex = GetCktElementIndex(ControlVars.CapacitorName); // Global function + if(DevIndex > 0) // Both capacitor and monitored element must already exist + { + Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + ControlledCapacitor = Get_Capacitor(); + Set_NPhases(get_FControlledElement()->Get_NPhases()); // Force number of phases to be same Added 5/21/01 RCD + Set_Nconds(Fnphases); + get_FControlledElement()->Set_ActiveTerminal(1); // Make the 1 st terminal active + // Get control synched up with capacitor + /*# with ControlledCapacitor do */ + { + auto with0 = ControlledCapacitor; + if(ControlVars.AvailableSteps == with0->Get_FNumSteps()) + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); + else + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); + } + if(get_FControlledElement()->Get_ConductorClosed(0, ActorID)) + ControlVars.PresentState = CTRL_CLOSE; + else + ControlVars.PresentState = CTRL_OPEN; + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("CapControl: \"") + this->get_Name() + "\"", String("Capacitor Element \"") + ControlVars.CapacitorName + + "\" Not Found.", " Element must be defined previously.", 361); + } + ControlVars.InitialState = ControlVars.PresentState; + +/*Check for existence of monitored element - if needed*/ + bool ElmReq = true; + ElmReq = ( ElmReq && (ControlType != TIMECONTROL) ) && (ControlType != FOLLOWCONTROL); + if (ElmReq) + { + DevIndex = GetCktElementIndex(ElementName); // Global function + if (DevIndex > 0) + { + Set_MonitoredElement(((TDSSCktElement*)ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + if (ElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("CapControl.") + get_Name() + ":", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 362); + } + else + + // Sets name of i-th terminal's connected bus in CapControl's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer.resize(get_FMonitoredElement()->Yorder + 1); + ControlVars.CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + } + else + DoSimpleMsg(String("Monitored Element in CapControl.") + get_Name() + + " does not exist:\"" + + ElementName + + "\"", 363); + } + else + { + SetBus(1, get_FControlledElement()->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer.resize(get_FControlledElement()->Yorder + 1); + ControlVars.CondOffset = (ElementTerminal - 1) * get_FControlledElement()->Get_NConds(); // for speedy sampling + } + /*Alternative override bus*/ + if(ControlVars.VoverrideBusSpecified) + /*# with ControlVars do */ + { + auto& with1 = ControlVars; + with1.VOverrideBusIndex = ActiveCircuit[ActorID]->BusList.Find(with1.VOverrideBusName); + if(with1.VOverrideBusIndex == 0) + { + DoSimpleMsg("CapControl." + get_Name() + ": Voltage override Bus " + with1.VOverrideBusName + " not found. Did you wait until buses were defined? Reverting to default.", 10361); + with1.VoverrideBusSpecified = false; + } + } + + // User model property update, if necessary + if(UserModel->Get_Exists()) + UserModel->UpdateModel(); // Checks for existence and Selects +} + +void TCapControlObj::MakePosSequence(int ActorID) +{ + if(get_FControlledElement() != nullptr) + { + Set_Enabled(get_FControlledElement()->Get_Enabled()); + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + } + if(get_FMonitoredElement() != nullptr) + { + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer.resize(get_FMonitoredElement()->Yorder + 1); + ControlVars.CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::GetBusVoltages(TDSSBus* pBus, pComplexArray Buff, int ActorID) +{ + int j = 0; + int k = 0; + /*# with pBus do */ + { + auto with0 = pBus; + if(!(with0->VBus.empty())) // uses nphases from CapControlObj + { + if(!ADiakoptics || (ActorID == 1)) + { + int stop = 0; + for(stop = Get_NPhases(), j = 1; j <= stop; j++) + { + (cBuffer)[j - 1] = ActiveCircuit[ActorID]->Solution->NodeV[with0->GetRef(j)]; + } + } + else + { + int stop = 0; + for(stop = Get_NPhases(), j = 1; j <= stop; j++) + { // In the context of actor 1 + (cBuffer)[j - 1] = ActiveCircuit[ActorID]->Solution->VoltInActor1(with0->GetRef(j)); + } + } + } + } +} + +// Get current to control on based on type of control specified. + +void TCapControlObj::GetControlCurrent(double& ControlCurrent) +{ + int i = 0; + /*# with ControlVars do */ + { + auto& with0 = ControlVars; + switch(with0.FCTPhase) + { + case AVGPHASES: + { + int stop = 0; + ControlCurrent = 0.0; // Get avg of all phases + for(stop = (Fnphases + with0.CondOffset), i = (1 + with0.CondOffset); i <= stop; i++) + { + ControlCurrent = ControlCurrent + cabs((cBuffer)[i - 1]); + } + ControlCurrent = ControlCurrent / Fnphases / with0.CTRatio; + } + break; + case MAXPHASE: + { + int stop = 0; + ControlCurrent = 0.0; // Get max of all phases + for(stop = (Fnphases + with0.CondOffset), i = (1 + with0.CondOffset); i <= stop; i++) + { + ControlCurrent = max(ControlCurrent, cabs((cBuffer)[i - 1])); + } + ControlCurrent = ControlCurrent / with0.CTRatio; + } + break; + case MINPHASE: + { + int stop = 0; + ControlCurrent = 1.0e50; // Get min of all phases + for(stop = (Fnphases + with0.CondOffset), i = (1 + with0.CondOffset); i <= stop; i++) + { + ControlCurrent = min(ControlCurrent, cabs((cBuffer)[i - 1])); + } + ControlCurrent = ControlCurrent / with0.CTRatio; + } + break; + /*Just use one phase because that's what most controls do.*/ + default: + ControlCurrent = cabs((cBuffer)[with0.FCTPhase - 1]) / with0.CTRatio; // monitored phase only + break; + } + } +} + +void TCapControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TCapControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + get_FControlledElement()->Set_ActiveTerminal(1); // Set active terminal of capacitor to terminal 1 + + /*Allow user control to do something*/ + switch(ControlType) + { + case USERCONTROL: + if(UserModel->Get_Exists()) + { + UserModel->DoPending(Code, ProxyHdl); + // If control action changes last step in service, force update of Yprim and Fstates array + ControlledCapacitor->set_LastStepInService(ControlVars.LastStepInService); + // Usermodel could override Pending change so the rest of this procedure is ignored. + } + break; + default: + ; + break; + } + /*# with ControlVars do */ + { + auto& with0 = ControlVars; + switch(Get_PendingChange()) + { + case CTRL_OPEN: + switch(ControlledCapacitor->Get_FNumSteps()) + { + case 1: + { + if(with0.PresentState == CTRL_CLOSE) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); // Open all phases of active terminal + ControlledCapacitor->SubtractStep(ActorID); + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Opened**", ActorID); + with0.PresentState = CTRL_OPEN; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + with0.LastOpenTime = with1->DynaVars.T + 3600.0 * with1->DynaVars.intHour; + } + } + } + break; + default: + if(with0.PresentState == CTRL_CLOSE) // Do this only if at least one step is closed + { + if(!ControlledCapacitor->SubtractStep(ActorID)) + { + with0.PresentState = CTRL_OPEN; + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); // Open all phases of active terminal + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Opened**", ActorID); + } + else + { + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Step Down**", ActorID); + } + } + break; + } + break; + case CTRL_CLOSE: + { + if(with0.PresentState == CTRL_OPEN) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); // Close all phases of active terminal + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Closed**", ActorID); + with0.PresentState = CTRL_CLOSE; + ControlledCapacitor->AddStep(ActorID); + } + else + { + if(ControlledCapacitor->AddStep(ActorID)) + { + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Step Up**", ActorID); + } + } + } + break; + /*Do Nothing for NONE if the control has reset*/ + default: + ; + break; + } + } + /*# with ControlVars do */ + { + auto& with2 = ControlVars; + with2.VoverrideEvent = false; + with2.ShouldSwitch = false; + with2.Armed = false; // reset control + } +} + +// Get Voltage used for voltage control based on specified options + +void TCapControlObj::GetControlVoltage(double& ControlVoltage) +{ + int i = 0; + + auto NextDeltaPhase = [&](int iPhs) -> int + { + int result = 0; + result = iPhs + 1; + if(result > Fnphases) + result = 1; + return result; + }; + /*# with ControlVars do */ + { + auto& with0 = ControlVars; + switch(with0.FPTPhase) + { + case AVGPHASES: + { + int stop = 0; + ControlVoltage = 0.0; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + ControlVoltage = ControlVoltage + cabs(cBuffer[i - 1]); + } + ControlVoltage = ControlVoltage / get_FMonitoredElement()->Get_NPhases() / with0.PTRatio; + } + break; + case MAXPHASE: + { + int stop = 0; + ControlVoltage = 0.0; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + ControlVoltage = max(ControlVoltage, cabs((cBuffer)[i - 1])); + } + ControlVoltage = ControlVoltage / with0.PTRatio; + } + break; + case MINPHASE: + { + int stop = 0; + ControlVoltage = 1.0e50; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + ControlVoltage = min(ControlVoltage, cabs((cBuffer)[i - 1])); + } + ControlVoltage = ControlVoltage / with0.PTRatio; + } + break; + /*Just use one phase because that's what most controls do.*/ + // Use L-L aB if capacitor is delta connected!! + default: + switch(((TCapacitorObj*) get_FControlledElement())->Connection) + { + case 1: + ControlVoltage = cabs(csub((cBuffer)[with0.FPTPhase - 1], (cBuffer)[NextDeltaPhase(with0.FPTPhase) - 1])) / with0.PTRatio; + break; // Delta + default: + ControlVoltage = cabs((cBuffer)[with0.FPTPhase - 1]) / with0.PTRatio; // Wye - Default + break; + } + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TCapControlObj::sample(int ActorID) +{ + double PF = 0.0; + double Sabs = 0.0; + double CurrTest = 0.0; + double Vtest = 0.0; + double NormalizedTime = 0.0; + double Q = 0.0; + complex s = {}; + + auto PF1to2 = [&](const complex& Spower) -> double + { + double result = 0.0; + Sabs = cabs(Spower); + if(Sabs != 0.0) + result = double(Abs(Spower.re)) / Sabs; + else + result = 1.0; // default to unity + if(Spower.im < 0.0) + result = 2.0 - result; + return result; + }; // return PF in range of 1 to 2 + get_FControlledElement()->Set_ActiveTerminal(1); + if(get_FControlledElement()->Get_ConductorClosed(0, ActorID)) + ControlVars.PresentState = CTRL_CLOSE; + else + ControlVars.PresentState = CTRL_OPEN; + /*# with MonitoredElement, ControlVars do */ + { + auto with0 = get_FMonitoredElement(); + auto& with1 = ControlVars; + with1.ShouldSwitch = false; + + // Get_First() Check voltage override + if(with1.Voverride) + { + if(ControlType != VOLTAGECONTROL) // Don't bother for voltage control + { + if(with1.VoverrideBusSpecified) + { + GetBusVoltages( ActiveCircuit[ActorID]->Buses[with1.VOverrideBusIndex - 1], &(cBuffer[0]), ActorID); + } + else + get_FMonitoredElement()->GetTermVoltages(ElementTerminal, &(cBuffer[0]), ActorID); + GetControlVoltage(Vtest); + switch(with1.PresentState) + { + case CTRL_OPEN: + if(Vtest < with1.Vmin) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + with1.VoverrideEvent = true; + if(ShowEventLog) + AppendToEventLog(String("Capacitor.") + get_FControlledElement()->get_Name(), Format("Low Voltage Override: %.8g V", Vtest), ActorID); + } + break; + case CTRL_CLOSE: + if(Vtest > with1.Vmax) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + with1.VoverrideEvent = true; + if(ShowEventLog) + AppendToEventLog(String("Capacitor.") + get_FControlledElement()->get_Name(), Format("High Voltage Override: %.8g V", Vtest), ActorID); + } + break; + default: + ; + break; + } + } + } + if(!with1.ShouldSwitch) + switch(ControlType) + { // Else skip other control evaluations + case CURRENTCONTROL: /*Current*/ + + // Check largest Current of all phases of monitored element + { + get_FMonitoredElement()->GetCurrents(&(cBuffer[0]), ActorID); + GetControlCurrent(CurrTest); + switch(with1.PresentState) + { + case CTRL_OPEN: + if(CurrTest > with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + break; + case CTRL_CLOSE: + if(CurrTest < with1.OFF_Value) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if(CurrTest > with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + break; + default: + ; + break; + } + } + break; /*Voltage*/ + case VOLTAGECONTROL: + { + get_FMonitoredElement()->GetTermVoltages(ElementTerminal, &(cBuffer[0]), ActorID); + GetControlVoltage(Vtest); + switch(with1.PresentState) + { + case CTRL_OPEN: + if(Vtest < with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + break; + case CTRL_CLOSE: + { + Set_PendingChange(CTRL_NONE); + if(Vtest > with1.OFF_Value) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if(Vtest < with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + } + } + } + break; + default: + ; + break; + } + } + break; /*kvar*/ + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + case KVARCONTROL: + { + s = get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID); + Q = s.im * 0.001; // kvar + switch(with1.PresentState) + { + case CTRL_OPEN: + if(Q > with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + break; + case CTRL_CLOSE: + if(Q < with1.OFF_Value) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if(Q > with1.ON_Value) + { + Set_PendingChange(CTRL_CLOSE); // We can go some more + with1.ShouldSwitch = true; + } + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + break; + default: + ; + break; + } + } + break; + + /*User Control*/ + case USERCONTROL: + if(UserModel->Get_Exists()) // selects the model associated with this control + + // Load up test data into the public data record + { + with1.SampleP = cmulreal(get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID), 0.001); // kW kvar + get_FMonitoredElement()->GetTermVoltages(ElementTerminal, &(cBuffer[0]), ActorID); + GetControlVoltage(with1.SampleV); + get_FMonitoredElement()->GetCurrents(&(cBuffer[0]), ActorID); + GetControlCurrent(with1.SampleCurr); + with1.NumCapSteps = ControlledCapacitor->Get_FNumSteps(); + with1.AvailableSteps = ControlledCapacitor->AvailableSteps(); + with1.LastStepInService = ControlledCapacitor->Get_FLastStepInService(); + UserModel->sample(); // Sets the switching flags + } + break; /*time*/ + /*7-8-10 NormalizeToTOD Algorithm modified to close logic hole between 11 PM and midnight*/ + case TIMECONTROL: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + NormalizedTime = NormalizeToTOD(with2->DynaVars.intHour, with2->DynaVars.T); + } + /* 1/28/09 Code modified to accommodate OFF_Value < ON_Value */ + switch(with1.PresentState) + { + case CTRL_OPEN: + if(with1.OFF_Value > with1.ON_Value) + { + if((NormalizedTime >= with1.ON_Value) && (NormalizedTime < with1.OFF_Value)) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + else + // OFF time is next day + { + if((NormalizedTime >= with1.ON_Value) && (NormalizedTime < 24.0)) + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + break; + case CTRL_CLOSE: + if(with1.OFF_Value > with1.ON_Value) + { + if((NormalizedTime >= with1.OFF_Value) || (NormalizedTime < with1.ON_Value)) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if((NormalizedTime >= with1.ON_Value) && (NormalizedTime < with1.OFF_Value)) + { + Set_PendingChange(CTRL_CLOSE); // We can go some more + with1.ShouldSwitch = true; + } + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + } + else + // OFF time is next day + { + if((NormalizedTime >= with1.OFF_Value) && (NormalizedTime < with1.ON_Value)) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if((NormalizedTime >= with1.ON_Value) && (NormalizedTime < 24.0)) + { + Set_PendingChange(CTRL_CLOSE); // We can go some more + with1.ShouldSwitch = true; + } + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + } + break; + default: + ; + break; + } + } + break; /*PF*/ + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + case PFCONTROL: + { + s = get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID); + PF = PF1to2(s); + + /*PF is in range of 0 .. 2; Leading is 1..2*/ + /*When turning on make sure there is at least half the kvar of the bank*/ + switch(with1.PresentState) + { + case CTRL_OPEN: + if((PF < with1.PFON_Value) && (s.im * 0.001 > ControlledCapacitor->Get_Ftotalkvar() * FpctMinkvar * 0.01)) // make sure we don't go too far leading + { + Set_PendingChange(CTRL_CLOSE); + with1.ShouldSwitch = true; + } + else + // Reset + Set_PendingChange(CTRL_NONE); + break; + case CTRL_CLOSE: + if(PF > with1.PFOFF_Value) + { + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + else + { + if(ControlledCapacitor->AvailableSteps() > 0) + { + if((PF < with1.PFON_Value) && (s.im * 0.001 > ControlledCapacitor->Get_Ftotalkvar() / ControlledCapacitor->Get_FNumSteps() * 0.5)) + { + Set_PendingChange(CTRL_CLOSE); // We can go some more + with1.ShouldSwitch = true; + } + } + else + // Reset + Set_PendingChange(CTRL_NONE); + } + break; + default: + ; + break; + } + } + break; + case FOLLOWCONTROL: + { + auto with3 = ActiveCircuit[ActorID]->Solution; + double NextState = myShapeObj->GetMult(with3->DynaVars.dblHour).re; + if ( (NextState != 0) == (with1.PresentState == CTRL_OPEN) ) + { + if (with1.PresentState == CTRL_OPEN) + Set_PendingChange(CTRL_CLOSE); + else + Set_PendingChange(CTRL_OPEN); + with1.ShouldSwitch = true; + } + } + default: + ; + break; + } + } + /*# with ActiveCircuit[ActorID], ControlVars do */ + { + + auto& with4 = ControlVars; + if(with4.ShouldSwitch && !with4.Armed) + { + if(Get_PendingChange() == CTRL_CLOSE) + { + if((ActiveCircuit[ActorID]->Solution->DynaVars.T + ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600.0 - with4.LastOpenTime) < with4.DeadTime) // delay the close operation + /*2-6-09 Added ONDelay to Deadtime so that all caps do not close back in at same time*/ + TimeDelay = max(with4.OnDelay, (with4.DeadTime + with4.OnDelay) - (ActiveCircuit[ActorID]->Solution->DynaVars.T + ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600.0 - with4.LastOpenTime)); + else + TimeDelay = with4.OnDelay; + } + else + TimeDelay = with4.OFFDelay; + with4.ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TimeDelay, Get_PendingChange(), 0, this, ActorID); + with4.Armed = true; + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), Format("**Armed**, Delay= %.5g sec", TimeDelay), ActorID); + } + if(with4.Armed && (Get_PendingChange() == CTRL_NONE)) + { + ActiveCircuit[ActorID]->ControlQueue.Delete(with4.ControlActionHandle, ActorID); + with4.Armed = false; + if(ShowEventLog) + AppendToEventLog("Capacitor." + get_FControlledElement()->get_Name(), "**Reset**", ActorID); + } + } /*With*/ +} + +//------------------------------------------------------------------------------------ + +ECapControlType TCapControlObj::get_ControlType() +{ + return ControlType; +} + +//------------------------------------------------------------------------------------ + +void TCapControlObj::set_ControlType(CapControlVars::ECapControlType value) +{ + ControlType = value; +} + +//------------------------------------------------------------------------------------ + +TCapacitorObj* TCapControlObj::Get_Capacitor() +{ + TCapacitorObj* result = nullptr; + result = (TCapacitorObj*) get_FControlledElement(); + return result; +} + +EControlAction TCapControlObj::Get_PendingChange() +{ + EControlAction result; + result = ControlVars.FPendingChange; + return result; +} +// Normalize time to a floating point number representing time of day if Hour > 24 +// Resulting time should be 0:00+ to 24:00 inclusive. + +double TCapControlObj::NormalizeToTOD(int h, double Sec) +{ + double result = 0.0; + int HourOfDay = 0; + if(h > 24) // creates numbers 1..24 + HourOfDay = (int) (h - ((h - 1) / 24) * 24); + else + HourOfDay = h; + result = HourOfDay + Sec / 3600.0; + + // If the TOD is at least slightly greater than 24:00 wrap around to 0:00 + if(result - 24.0 > EPSILON) + result = result - 24.0; // Wrap around + return result; +} + +void TCapControlObj::Reset(int ActorID) +{ + Set_PendingChange(CTRL_NONE); + get_FControlledElement()->Set_ActiveTerminal(1); + /*# with ControlVars do */ + { + auto& with0 = ControlVars; + switch(with0.InitialState) + { + case CTRL_OPEN: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); + break; // Open all phases of active terminal + case CTRL_CLOSE: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); + break; // Close all phases of active terminal + default: + ; + break; + } + with0.ShouldSwitch = false; + with0.LastOpenTime = -with0.DeadTime; + with0.PresentState = with0.InitialState; + } +} + +void TCapControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); //'element'; + Set_PropertyValue(2, "1"); //'terminal'; + Set_PropertyValue(3, ""); + Set_PropertyValue(4, "current"); + Set_PropertyValue(5, "60"); + Set_PropertyValue(6, "60"); + Set_PropertyValue(7, "300"); + Set_PropertyValue(8, "200"); + Set_PropertyValue(9, "15"); + Set_PropertyValue(10, "NO"); + Set_PropertyValue(11, "126"); + Set_PropertyValue(12, "115"); + Set_PropertyValue(13, "15"); + Set_PropertyValue(14, "300"); + Set_PropertyValue(15, "1"); + Set_PropertyValue(16, "1"); + Set_PropertyValue(17, ""); + Set_PropertyValue(18, ShowEventLog ? "YES" : "NO"); + Set_PropertyValue(19, ""); + Set_PropertyValue(20, ""); + Set_PropertyValue(21, "50"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TCapControlObj::Set_PendingChange(const EControlAction Value) +{ + ControlVars.FPendingChange = Value; + DblTraceParameter = (double) (Value); +} + +// return functions for properties + +double TCapControlObj::GetON_Value() +{ + return ControlVars.ON_Value; +} +double TCapControlObj::GetOFF_Value() +{ + return ControlVars.OFF_Value; +} + +double TCapControlObj::GetPFON_Value() +{ + return ControlVars.PFON_Value; +} + +double TCapControlObj::GetPFOFF_Value() +{ + return ControlVars.PFOFF_Value; +} + +double TCapControlObj::GetPTRatio_Value() +{ + return ControlVars.PTRatio; +} + +double TCapControlObj::GetCTRatio_Value() +{ + return ControlVars.CTRatio; +} + +double TCapControlObj::GetONDelay_Value() +{ + return ControlVars.OnDelay; +} + +double TCapControlObj::GetOFFDelay_Value() +{ + return ControlVars.OFFDelay; +} + +double TCapControlObj::GetVmin_Value() +{ + return ControlVars.Vmin; +} + +double TCapControlObj::GetVmax_Value() +{ + return ControlVars.Vmax; +} + +bool TCapControlObj::GetVoverride_Value() +{ + return ControlVars.Voverride; +} + +double TCapControlObj::GetDeadTime_Value() +{ + return ControlVars.DeadTime; +} + +int TCapControlObj::GetFPTPhase_Value() +{ + return ControlVars.FPTPhase; +} + + +} // namespace CapControl + + + + + + diff --git a/OpenDSSC/Controls/CapControl.h b/OpenDSSC/Controls/CapControl.h new file mode 100644 index 0000000..1f863fa --- /dev/null +++ b/OpenDSSC/Controls/CapControl.h @@ -0,0 +1,157 @@ +#ifndef CapControlH +#define CapControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "Bus.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "Capacitor.h" +#include "LoadShape.h" +#include "CapControlVars.h" +#include "CapUserControl.h" +#include "d2c_structures.h" + + +namespace CapControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 2-14-00 Created + + 3-1-00 Added Voltage override + 5/21/01 Fixed bug with number of phases + 5/30/01 Eliminated extra event queue reports +*/ + +/* + A CapControl is a control element that is connected to a terminal of another + circuit element and controls a capacitor. The control is usually placed in the + terminal of a line or transformer, although a voltage control device could be placed + in the terminal of the capacitor it controls + + A CapControl is defined by a New command: + + New CapControl.Name=myname Element=devclass.name terminal=[ 1|2|...] Capacitor = name + + Capacitor to be controlled must already exist. +*/ + + + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TCapControl : public ControlClass::TControlClass +{ + friend class TCapControlObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String CapControlName); +public: + TCapControl(); + virtual ~TCapControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TCapControlObj : public ControlElem::TControlElem +{ + friend class TCapControl; +public: + typedef ControlElem::TControlElem inherited; +//private: + CapControlVars::ECapControlType ControlType; + CapControlVars::TCapControlVars ControlVars; + Capacitor::TCapacitorObj* ControlledCapacitor; + std::vector cBuffer; // Complexarray buffer + bool IsUserModel; + CapUserControl::TCapUserControl* UserModel; + double FpctMinkvar; + Capacitor::TCapacitorObj* Get_Capacitor(); // Pointer to controlled Capacitor + double NormalizeToTOD(int h, double Sec); + void Set_PendingChange(const EControlAction Value); + EControlAction Get_PendingChange(); + void GetControlVoltage(double& ControlVoltage); + void GetControlCurrent(double& ControlCurrent); + void GetBusVoltages(Bus::TDSSBus* pBus, Ucomplex::pComplexArray Buff, int ActorID); + + double GetON_Value(); + double GetOFF_Value(); + double GetPFON_Value(); + double GetPFOFF_Value(); + double GetPTRatio_Value(); + double GetCTRatio_Value(); + double GetONDelay_Value(); + double GetOFFDelay_Value(); + double GetVmin_Value(); + double GetVmax_Value(); + bool GetVoverride_Value(); + double GetDeadTime_Value(); + int GetFPTPhase_Value(); + +public: + String myShapeName; // Name of the shape for this controller + TLoadShapeObj* myShapeObj; // Shape for this controller + + TCapControlObj(DSSClass::TDSSClass* ParClass, const String CapControlName); + virtual ~TCapControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a CapControl + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + ECapControlType get_ControlType(); + void set_ControlType(CapControlVars::ECapControlType value); + + // for CIM export, which doesn't yet use the delays, CT, PT, and voltage override + // (properties removed, use getters/setters) + + TCapControlObj(DSSClass::TDSSClass* ParClass); + TCapControlObj(String ClassName); + TCapControlObj(); +}; +extern TCapControlObj* ActiveCapControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace CapControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CapControl; +#endif + +#endif // CapControlH + + + + + + diff --git a/OpenDSSC/Controls/CapControlVars.cpp b/OpenDSSC/Controls/CapControlVars.cpp new file mode 100644 index 0000000..f5d4cd0 --- /dev/null +++ b/OpenDSSC/Controls/CapControlVars.cpp @@ -0,0 +1,23 @@ + +#pragma hdrstop + +#include "CapControlVars.h" + +using namespace std; +using namespace System; +using namespace Ucomplex; + +namespace CapControlVars +{ + + + + + + +} // namespace CapControlVars + + + + + diff --git a/OpenDSSC/Controls/CapControlVars.h b/OpenDSSC/Controls/CapControlVars.h new file mode 100644 index 0000000..7bdda08 --- /dev/null +++ b/OpenDSSC/Controls/CapControlVars.h @@ -0,0 +1,92 @@ +#ifndef CapControlVarsH +#define CapControlVarsH + +#include "System.h" +#include "Sysutils.h" + +#include "Ucomplex.h" +#include "ControlElem.h" +#include "ControlActionsDefs.h" + +namespace CapControlVars +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/*Header file for CapControlVars*/ + +/* For user DLL, import Definitions of control actions directly */ +enum ECapControlType {CURRENTCONTROL, + VOLTAGECONTROL, + KVARCONTROL, + TIMECONTROL, + PFCONTROL, + FOLLOWCONTROL, + USERCONTROL }; + + + + /*Fixed record structure for Public CapControl variables*/ +#pragma pack (push, 1) + + +struct TCapControlVars +{ + int FCTPhase; + int FPTPhase; // "ALL" is -1 + double ON_Value; + double OFF_Value; + double PFON_Value; + double PFOFF_Value; + double CTRatio; + double PTRatio; + double OnDelay; + double OFFDelay; + double DeadTime; + double LastOpenTime; + bool Voverride; + bool VoverrideEvent; + bool VoverrideBusSpecified; // Added 8-11-11 + int VOverrideBusIndex; + double Vmax; + double Vmin; + EControlAction FPendingChange; + bool ShouldSwitch; // True: action is pending + bool Armed; // Control is armed for switching unless reset + EControlAction PresentState; + EControlAction InitialState; + Ucomplex::complex SampleP; // two 64-bit numbers, kW, kvar + double SampleV; + double SampleCurr; + int NumCapSteps; + int AvailableSteps; // available steps in controlled capacitor + int LastStepInService; // Change this to force an update of cap states + char const* VOverrideBusNamePtr; // Required for backwards compatibility, points to VOverrideBusName's data + char const* CapacitorNamePtr; // Required for backwards compatibility, points to CapacitorName's data + int ControlActionHandle; + int CondOffset; // Offset for monitored terminal + + String VOverrideBusName; + String CapacitorName; +}; +#pragma pack (pop) + + + +} // namespace CapControlVars + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CapControlVars; +#endif + +#endif // CapControlVarsH + + + + + diff --git a/OpenDSSC/Controls/CapUserControl.cpp b/OpenDSSC/Controls/CapUserControl.cpp new file mode 100644 index 0000000..09af74d --- /dev/null +++ b/OpenDSSC/Controls/CapUserControl.cpp @@ -0,0 +1,192 @@ + +#pragma hdrstop + +#include "CapUserControl.h" + +#include "DSSGlobals.h" + +using namespace std; +using namespace DSSGlobals; +using namespace System; + + +namespace CapUserControl +{ + + + +/* TCapUserControl */ + +void* TCapUserControl::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("CapControl User Model Does Not Have Required Function: ") + FuncName, 569); + FuncError = true; + } + result = Addr; + return result; +} + +TCapUserControl::TCapUserControl() + : FHandle(0), + FID(0), + FuncError(false) +{ + FID = 0; + FName = ""; +} + +TCapUserControl::~TCapUserControl() +{ + try + { + if(FID != 0) + FDelete(FID); // Clean up all memory associated with this instance +/* } + __finally + {*/ + if( (HMODULE) FHandle != 0) + FreeLibrary( (HMODULE) FHandle); + } + catch (...) + { + // + } + // inherited; +} + +//---------------------------------------------------------------------------- + +String TCapUserControl::get_FName() +{ + return FName; +} + +//---------------------------------------------------------------------------- + +// do the pending control Action + +void TCapUserControl::DoPending(int Code, int ProxyHdl) +{ + int varCode = 0; + int varProxyHdl = 0; + if(FID != 0) + { + varCode = Code; // Can't pass a const + varProxyHdl = ProxyHdl; + FDoPending(varCode, varProxyHdl); + } +} + +bool TCapUserControl::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} +// Sample the cap control + +void TCapUserControl::sample() +{ + if(FID != 0) + FSample(); +} + +void TCapUserControl::select() +{ + FSelect(FID); +} + +void TCapUserControl::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit(PAnsiChar(Value.c_str()), Value.size()); +} + +void TCapUserControl::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if( (HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + FreeLibrary( (HMODULE) FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if( (HMODULE) FHandle == 0) // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary( (DSSDirectory + Value).c_str() ); + } + if( (HMODULE) FHandle == 0) + DoSimpleMsg(String("CapControl User Model ") + Value + + " Load Library Failed. DSS Directory = " + + DSSDirectory, 570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (CapUserControlProc__0) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("New")), "New"); + if(!FuncError) + FSelect = (CapUserControlProc__2) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("Select")), "Select"); + if(!FuncError) + FSample = (CapUserControlProc__4) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("Sample")), "Sample"); + if(!FuncError) + FDoPending = (CapUserControlProc__5) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("DoPending")), "DoPending"); + if(!FuncError) + FEdit = (CapUserControlProc__6) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (CapUserControlProc__3) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (CapUserControlProc__1) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, ("Delete")), "Delete"); + if(FuncError) + { + if(!FreeLibrary( (HMODULE) FHandle)) + DoSimpleMsg(String("Error Freeing DLL: ") + FName, 10570); // decrement the reference count + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew(CallBackRoutines); // Create new instance of user model + } + } +} + +void TCapUserControl::UpdateModel() +{ + if(FID != 0) + FUpdateModel(); +} + + + + +} // namespace CapUserControl + + + + + diff --git a/OpenDSSC/Controls/CapUserControl.h b/OpenDSSC/Controls/CapUserControl.h new file mode 100644 index 0000000..3e6478f --- /dev/null +++ b/OpenDSSC/Controls/CapUserControl.h @@ -0,0 +1,101 @@ +#ifndef CapUserControlH +#define CapUserControlH + +#include "System.h" +#include "Sysutils.h" + +#include "CapControlVars.h" +#include "Dynamics.h" +#include "DSSCallBackRoutines.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "d2c_structures.h" + +namespace CapUserControl +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + Interface to user-written CapControl DLL +*/ + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2012, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + 3-31-12 + Converted from GenUserModel.Pas + +*/ + +class TCapUserControl : public System::TObject +{ +public: + typedef TObject inherited; +//private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + // OK for this to be Wide String, since not passed to DLLs + String FName; // Name of the DLL file containing user model + bool FuncError; + + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *CapUserControlProc__0)(TDSSCallBacks&); + CapUserControlProc__0 FNew; // deletes specified instance + typedef void (__stdcall *CapUserControlProc__1)(int&); + CapUserControlProc__1 FDelete; // Select active instance + typedef int (__stdcall *CapUserControlProc__2)(int&); + CapUserControlProc__2 FSelect; // Called when props of CapControl updated + typedef void (__stdcall *CapUserControlProc__3)(); + CapUserControlProc__3 FUpdateModel; + typedef void (__stdcall *CapUserControlProc__4)(); + CapUserControlProc__4 FSample; + typedef void (__stdcall *CapUserControlProc__5)(int&, int&); + CapUserControlProc__5 FDoPending; + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + // Wide string OK here + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); +protected: +public: // send string to user model to handle + typedef void (__stdcall *CapUserControlProc__6)(System::PAnsiChar, unsigned int); + CapUserControlProc__6 FEdit; + void select(); + void UpdateModel(); + void DoPending(int Code, int ProxyHdl); + void sample(); + TCapUserControl(); + virtual ~TCapUserControl(); + + String get_FName(); + +//__published: +}; + + +} // namespace CapUserControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CapUserControl; +#endif + +#endif // CapUserControlH + + + + + diff --git a/OpenDSSC/Controls/ControlActionsDefs.h b/OpenDSSC/Controls/ControlActionsDefs.h new file mode 100644 index 0000000..b5f8b1a --- /dev/null +++ b/OpenDSSC/Controls/ControlActionsDefs.h @@ -0,0 +1,13 @@ +#ifndef ControlActionDefsH +#define ControlActionDefsH + +enum EControlAction {CTRL_NONE, + CTRL_OPEN, + CTRL_CLOSE, + CTRL_RESET, + CTRL_LOCK, + CTRL_UNLOCK, + CTRL_TAPUP, + CTRL_TAPDOWN }; + +#endif // ControlActionDefsH diff --git a/OpenDSSC/Controls/ControlClass.cpp b/OpenDSSC/Controls/ControlClass.cpp new file mode 100644 index 0000000..67d6d2d --- /dev/null +++ b/OpenDSSC/Controls/ControlClass.cpp @@ -0,0 +1,101 @@ + +#pragma hdrstop + +#include "ControlClass.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace CktElementClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace ParserDel; +using namespace System; + +namespace ControlClass +{ + + + +TControlClass::TControlClass() + : NumControlClassProps(0) +{ + ; + DSSClassType = CTRL_ELEMENT; +} + +TControlClass::~TControlClass() +{ + // inherited::Destroy(); +} + + +void TControlClass::CountProperties() +{ + NumProperties = NumProperties + NumControlClassProps; + inherited::CountProperties(); +} + +// Define the properties for the base power delivery element class + +void TControlClass::DefineProperties() +{ + + // no properties + // PropertyName^[ActiveProperty + 1] := 'propname'; + // PropertyHelp^[ActiveProperty + 1] := 'prop help'; + ActiveProperty = ActiveProperty + NumControlClassProps; + inherited::DefineProperties(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TControlClass::ClassEdit(const void* ActiveControlObj, int ParamPointer) +{ + int result = 0; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TControlElem(ActiveControlObj) do */ + { + auto with0 = ((TControlElem*) ActiveControlObj); + + //CASE ParamPointer OF + //1: BaseFrequency := Parser.Dblvalue; + //ELSE + + //END; + inherited::ClassEdit(ActiveControlObj, ParamPointer - NumControlClassProps); + } + return result; +} + +//Var +// OtherControlObj : TControlElem; + +void TControlClass::ClassMakeLike(const void* OtherObj) +{ + + +// OtherControlObj := TControlElem(OtherObj); + TControlElem(((TDSSClass*) OtherObj)); + + //With TPCElement(ActiveDSSObject) Do + //Begin + // value:= OtherControlObj.value; + //End; +} + + + + +} // namespace ControlClass + + + + + diff --git a/OpenDSSC/Controls/ControlClass.h b/OpenDSSC/Controls/ControlClass.h new file mode 100644 index 0000000..ea0f18c --- /dev/null +++ b/OpenDSSC/Controls/ControlClass.h @@ -0,0 +1,56 @@ +#ifndef ControlClassH +#define ControlClassH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElementClass.h" + +#include "ControlElem.h" + +namespace ControlClass +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + Base for control classes +*/ + +/*$M+*/ + +class TControlClass : public CktElementClass::TCktElementClass +{ +public: + typedef CktElementClass::TCktElementClass inherited; +private: +protected: + int ClassEdit(const void* ActiveControlObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); + void CountProperties(); // Add no. of intrinsic properties + void DefineProperties(); // Add Properties of this class to propName +public: + int NumControlClassProps; + TControlClass(); + virtual ~TControlClass(); +//__published: +}; + + +} // namespace ControlClass + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ControlClass; +#endif + +#endif // ControlClassH + + + + + diff --git a/OpenDSSC/Controls/ControlElem.cpp b/OpenDSSC/Controls/ControlElem.cpp new file mode 100644 index 0000000..c64724c --- /dev/null +++ b/OpenDSSC/Controls/ControlElem.cpp @@ -0,0 +1,296 @@ + +#pragma hdrstop + +#include "ControlElem.h" + + +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "PointerList.h" + +using namespace std; +using namespace Bus; +using namespace CktElement; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace NamedObject; +using namespace PointerList; +using namespace System; + + +namespace ControlElem +{ + +TControlElem::TControlElem(String ClassName) : inherited(ClassName) {} +TControlElem::TControlElem() {} + +int TControlElem::InitializeStates(int ActorID) +{ + // Nothing here, should default to individual model function + return 0; +} +int TControlElem::CalculateRate(int ActorID) +{ + // Nothing here, should default to individual model function + return 0; +} + +int TControlElem::StateIntegration(int ActorID) +{ + // Nothing here, should default to individual model function + return 0; +} + +int TControlElem::StateIntegration_correction(int ActorID) +{ + return 0; +} + +complex* TControlElem::CalculateIsorce(int ActorID, complex *pI012) +{ + complex* p = nullptr; + + return p; +} + +complex TControlElem::GetIsorce1(int ActorID) +{ + return complex{}; +} + +complex TControlElem::GetIsorce2(int ActorID) +{ + return complex{}; +} + +complex TControlElem::dq2seq(complex vin, double angle) +{ + double voutr = 0.; + double vouti = 0.; + + voutr = vin.re * sin(angle) + vin.im * cos(angle); + vouti = -vin.re * cos(angle) + vin.im * sin(angle); + return complex{voutr, vouti}; +} + +complex TControlElem::seq2dq(complex vin, double angle) +{ + double voutd = 0.; + double voutq = 0.; + + voutd = vin.re * sin(angle) - vin.im * cos(angle); + voutq = vin.re * cos(angle) + vin.im * sin(angle); + + return complex{ voutd, voutq }; +} + +double TControlElem::get_channel(int channel_num) +{ + return 0.0; +} + +int64_t TControlElem::get_number_channels() +{ + // should never get here but rather direct to child class + return 0; +} + +String TControlElem::get_channel_header(int i) +{ + return String(); +} + +double TControlElem::get_efield() +{ + // Should never get here + return 0.0; +} + +void TControlElem::set_efield(double efield) +{ + // Should never get here + return; +} + +double TControlElem::get_pmech() +{ + // Should never get here + return 0.0; +} + +void TControlElem::set_pmech(double pmech) +{ + // Should never get here + return; +} + +double TControlElem::get_dspd() +{ + // Should never get here + return 0.0; +} + +void TControlElem::set_dspd(double dspd) +{ + // Should never get here + return; +} + +double TControlElem::get_plast() +{ + // Should never get here + return 0.0; +} + +double TControlElem::get_qlast() +{ + // Should never get here + return 0.0; +} + +TControlElem::TControlElem(TDSSClass* ParClass) + : inherited(ParClass), + FControlledElement(nullptr), + FMonitoredElement(nullptr), + ElementTerminal(0), + ControlledBus(nullptr), + MonitorVarIndex(0), + TimeDelay(0.0), + DblTraceParameter(0.0), + ShowEventLog(false) +{ + DSSObjType = CTRL_ELEMENT; + DblTraceParameter = 0.0; + TimeDelay = 0.0; + MonitorVariable = ""; + MonitorVarIndex = 0; + ShowEventLog = EventLogDefault; +} + +TControlElem::~TControlElem() +{ + // inherited::Destroy(); +} + +//--------------------------------------------------------------------------------------- + +TDSSCktElement* TControlElem::get_FControlledElement() +{ + return FControlledElement; +} + +//--------------------------------------------------------------------------------------- + +TDSSCktElement* TControlElem::get_FMonitoredElement() +{ + return FMonitoredElement; +} + +//--------------------------------------------------------------------------------------- + +void TControlElem::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + + // virtual function - should be overridden + DoSimpleMsg(String("Programming Error: Reached base class for DoPendingAction.") + CRLF + + "Device: " + + Get_myPName() + + "." + + get_Name(), 460); +} +/*Remove this control from the controlelementlist of the designated element*/ + +void TControlElem::RemoveSelfFromControlelementList(TDSSCktElement* CktElem) +{ + TControlElem* Ptr = nullptr; + PointerList::TPointerList* TempList = nullptr; + int i = 0; + /*# with CktElem do */ + { + auto with0 = CktElem; + // Make a new copy of the control element list + int stop = 0; + TempList = new PointerList::TPointerList(1); + for(stop = with0->ControlElementList.get_myNumList(), i = 1; i <= stop; i++) + { + Ptr = ((TControlElem*) with0->ControlElementList.Get(i)); + if(Ptr != this) + TempList->Add(Ptr); // skip Self in copying list + } + with0->ControlElementList.Clear(); + with0->ControlElementList = *TempList; + } +} + +void TControlElem::Reset(int ActorID) +{ + DoSimpleMsg(String("Programming Error: Reached base class for Reset.") + CRLF + + "Device: " + + Get_myPName() + + "." + + get_Name(), 461); +} + +void TControlElem::sample(int ActorID) +{ + + // virtual function - should be overridden + DoSimpleMsg(String("Programming Error: Reached base class for Sample.") + CRLF + + "Device: " + + Get_myPName() + + "." + + get_Name(), 462); +} + +void TControlElem::Set_ControlledElement(TDSSCktElement* const Value) +{ + try + + // Check for reassignment of Controlled element and remove from list + { + if(ASSIGNED(FControlledElement)) + /*# with FControlledElement do */ + { + auto with0 = FControlledElement; + if(with0->ControlElementList.get_myNumList() == 1) + with0->HasControl = false; + RemoveSelfFromControlelementList(FControlledElement); + } +/* } + __finally + {*/ + FControlledElement = const_cast(Value); + if(ASSIGNED(FControlledElement)) + /*# with FControlledElement do */ + { + auto with1 = FControlledElement; + with1->HasControl = true; + with1->ControlElementList.Add(this); + } + } + catch (...) + { + // + } +} + +void TControlElem::Set_MonitoredElement(TDSSCktElement* const Value) +{ + FMonitoredElement = const_cast(Value); + if(ASSIGNED(FMonitoredElement)) + FMonitoredElement->IsMonitored = true; +} + + + + + + +} // namespace ControlElem + + + + + diff --git a/OpenDSSC/Controls/ControlElem.h b/OpenDSSC/Controls/ControlElem.h new file mode 100644 index 0000000..e2180f9 --- /dev/null +++ b/OpenDSSC/Controls/ControlElem.h @@ -0,0 +1,102 @@ +#ifndef ControlElemH +#define ControlElemH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElement.h" +#include "Bus.h" +#include "Ucomplex.h" +#include "DSSClass.h" + + +namespace ControlElem +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TControlElem : public CktElement::TDSSCktElement +{ +public: + typedef CktElement::TDSSCktElement inherited; +//private: + CktElement::TDSSCktElement* FControlledElement; + CktElement::TDSSCktElement* FMonitoredElement; + void Set_ControlledElement(CktElement::TDSSCktElement* const Value); // Pointer to target circuit element + void RemoveSelfFromControlelementList(CktElement::TDSSCktElement* CktElem); + void Set_MonitoredElement(CktElement::TDSSCktElement* const Value); + +public: + String ElementName; + int ElementTerminal; + String ControlledBusName; // If different than terminal + Bus::TDSSBus* ControlledBus; + String MonitorVariable; + int MonitorVarIndex; + double TimeDelay; + double DblTraceParameter; + bool ShowEventLog; + TControlElem(DSSClass::TDSSClass* ParClass); + virtual ~TControlElem(); + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); + TDSSCktElement* get_FControlledElement(); + TDSSCktElement* get_FMonitoredElement(); + + TControlElem(String ClassName); + TControlElem(); + + + // Functions added to support new dynamics module + int64_t nstates; + int64_t nchannels; + virtual int InitializeStates(int ActorID); + virtual int CalculateRate(int ActorID); + virtual int StateIntegration(int ActorID); + virtual int StateIntegration_correction(int ActorID); + virtual complex* CalculateIsorce(int ActorID, complex *pI012); + virtual complex GetIsorce1(int ActorID); + virtual complex GetIsorce2(int ActorID); + complex dq2seq(complex vin, double angle); + complex seq2dq(complex vin, double angle); + virtual double get_channel(int channel_num); + virtual int64_t get_number_channels(); + virtual String get_channel_header(int channel_num); + + // Functions related to excitation systems + virtual double get_efield(); + virtual void set_efield(double efield); + + // Function related to governor systems + virtual double get_pmech(); + virtual void set_pmech(double pmech); + virtual double get_dspd(); + virtual void set_dspd(double dspd); + + // Functions to extract quantities from dynamic models + virtual double get_plast(); + virtual double get_qlast(); + +}; +const int USER_BASE_ACTION_CODE = 100; + + +} // namespace ControlElem + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ControlElem; +#endif + +#endif // ControlElemH + + + + + diff --git a/OpenDSSC/Controls/ESPVLControl.cpp b/OpenDSSC/Controls/ESPVLControl.cpp new file mode 100644 index 0000000..604e808 --- /dev/null +++ b/OpenDSSC/Controls/ESPVLControl.cpp @@ -0,0 +1,628 @@ + +#pragma hdrstop + +#include "ESPVLControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "generator.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Generator; +using namespace LoadShape; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace ESPVLControl +{ + +TESPVLControlObj::TESPVLControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TESPVLControlObj::TESPVLControlObj(String ClassName) : inherited(ClassName) {} +TESPVLControlObj::TESPVLControlObj() {} + + +TESPVLControl* ESPVLControlClass = nullptr; +TESPVLControlObj* ActiveESPVLControlObj = nullptr; +const int NumPropsThisClass = 12; + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all ESPVLControl objects + +TESPVLControl::TESPVLControl() +{ + ; + Class_Name = "ESPVLControl"; + DSSClassType = DSSClassType + ESPVL_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + ESPVLControlClass = this; +} + +/*--------------------------------------------------------------------------*/ + +TESPVLControl::~TESPVLControl() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TESPVLControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "Element"; + PropertyName[2 - 1] = "Terminal"; + PropertyName[3 - 1] = "Type"; + PropertyName[4 - 1] = "kWBand"; + PropertyName[5 - 1] = "kvarlimit"; + PropertyName[6 - 1] = "LocalControlList"; + PropertyName[7 - 1] = "LocalControlWeights"; + PropertyName[8 - 1] = "PVSystemList"; + PropertyName[9 - 1] = "PVSystemWeights"; + PropertyName[10 - 1] = "StorageList"; + PropertyName[11 - 1] = "StorageWeights"; + PropertyName[12 - 1] = "Forecast"; + PropertyHelp[1 - 1] = "Full object name of the circuit element, typically a line or transformer, " + "which the control is monitoring. There is no default; must be specified."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the ESPVLControl control is connected. " + "1 or 2, typically. Default is 1. Make sure you have the direction on the power matching the sign of kWLimit."; + PropertyHelp[3 - 1] = "Type of controller. 1= System Controller; 2= Local controller. "; + PropertyHelp[4 - 1] = "Bandwidth (kW) of the dead band around the target limit." + "No dispatch changes are attempted if the power in the monitored terminal stays within this band."; + PropertyHelp[5 - 1] = "Max kvar to be delivered through the element. Uses same dead band as kW."; + PropertyHelp[6 - 1] = "Array list of ESPVLControl local controller objects to be dispatched by System Controller. " + "If not specified, all ESPVLControl devices with type=local in the circuit not attached to another " + "controller are assumed to be part of this controller's fleet."; + PropertyHelp[7 - 1] = "Array of proportional weights corresponding to each ESPVLControl local controller in the LocalControlList."; + PropertyHelp[8 - 1] = "Array list of PVSystem objects to be dispatched by a Local Controller. "; + PropertyHelp[9 - 1] = "Array of proportional weights corresponding to each PVSystem in the PVSystemList."; + PropertyHelp[10 - 1] = "Array list of Storage objects to be dispatched by Local Controller. "; + PropertyHelp[11 - 1] = "Array of proportional weights corresponding to each Storage object in the StorageControlList."; + PropertyHelp[12 - 1] = "Loadshape object containing daily forecast."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TESPVLControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new ESPVLControl and add it to ESPVLControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TESPVLControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TESPVLControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + + // continue parsing WITH contents of Parser + ActiveESPVLControlObj = (TESPVLControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveESPVLControlObj); + result = 0; + /*# with ActiveESPVLControlObj do */ + { + auto with0 = ActiveESPVLControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 364); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + switch(LowerCase(Param)[0]) + { + case L's': + with0->fType = 1; + break; /*for System Controller*/ + case L'l': + with0->fType = 2; + break; /*for Local Controller*/ + default: + ; + break; + } + break; + case 4: + with0->FkWBand = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->Fkvarlimit = Parser[ActorID]->MakeDouble_(); + break; + case 6: + InterpretTStringListArray(Param, *(with0->FLocalControlNameList)); + break; + case 7: + { + with0->FLocalControlListSize = with0->FLocalControlNameList->size(); + if(with0->FLocalControlListSize > 0) + { + with0->FLocalControlWeights = (pDoubleArray) realloc(with0->FLocalControlWeights, sizeof(double) * with0->FLocalControlListSize); + with0->FLocalControlListSize = InterpretDblArray(Param, with0->FLocalControlListSize, with0->FLocalControlWeights); + } + } + break; + case 8: + InterpretTStringListArray(Param, *(with0->FPVSystemNameList)); + break; + case 9: + { + with0->FPVsystemListSize = with0->FPVSystemNameList->size(); + if(with0->FPVsystemListSize > 0) + { + with0->FPVSystemWeights = (pDoubleArray)realloc(with0->FPVSystemWeights, sizeof(double) * with0->FPVsystemListSize); + with0->FPVsystemListSize = InterpretDblArray(Param, with0->FPVsystemListSize, with0->FPVSystemWeights); + } + } + break; + case 10: + InterpretTStringListArray(Param, *(with0->FStorageNameList)); + break; + case 11: + { + with0->FStorageListSize = with0->FStorageNameList->size(); + if(with0->FStorageListSize > 0) + { + with0->FStorageWeights = (pDoubleArray)realloc(with0->FStorageWeights, sizeof(double) * with0->FStorageListSize); + with0->FStorageListSize = InterpretDblArray(Param, with0->FStorageListSize, with0->FStorageWeights); + } + } + break; + // Inherited parameters + default: + ClassEdit(ActiveESPVLControlObj, ParamPointer - NumPropsThisClass); + break; + } + + // Side Effects + switch(ParamPointer) + { + case 6: // levelize the list + { + int stop = 0; + with0->FLocalControlPointerList->Clear(); // clear this for resetting on first sample + with0->FLocalControlListSize = with0->FLocalControlNameList->size(); + with0->FLocalControlWeights = (pDoubleArray)realloc(with0->FLocalControlWeights, sizeof(double) * with0->FLocalControlListSize); + for(stop = with0->FLocalControlListSize, i = 1; i <= stop; i++) + { + (with0->FLocalControlWeights)[i - 1] = 1.0; + } + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TESPVLControl::MakeLike(const String ESPVLControlName) +{ + int result = 0; + TESPVLControlObj* OtherESPVLControl = nullptr; + int i = 0; + result = 0; + /*See if we can find this ESPVLControl name in the present collection*/ + OtherESPVLControl = ((TESPVLControlObj*) Find(ESPVLControlName)); + if(OtherESPVLControl != nullptr) + /*# with ActiveESPVLControlObj do */ + { + auto with0 = ActiveESPVLControlObj; + int stop = 0; + with0->Set_NPhases(OtherESPVLControl->Fnphases); + with0->Set_Nconds(OtherESPVLControl->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherESPVLControl->ElementName; + with0->Set_ControlledElement(OtherESPVLControl->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherESPVLControl->get_FMonitoredElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherESPVLControl->ElementTerminal; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i, OtherESPVLControl->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in ESPVLControl MakeLike: \"") + ESPVLControlName + + "\" Not Found.", 370); + return result; +} + + + + +/*==========================================================================*/ +/* TESPVLControlObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TESPVLControlObj::TESPVLControlObj(TDSSClass* ParClass, const String ESPVLControlName) + : inherited(ParClass), + fType(0), + FLocalControlListSize(0), + FLocalControlNameList(nullptr), + FLocalControlPointerList(nullptr), + FLocalControlWeights(nullptr), + FPVsystemListSize(0), + FPVSystemNameList(nullptr), + FPVSystemPointerList(nullptr), + FPVSystemWeights(nullptr), + FStorageListSize(0), + FStorageNameList(nullptr), + FStoragePointerList(nullptr), + FStorageWeights(nullptr), + FkWLimit(0.0), + FkWBand(0.0), + HalfkWBand(0.0), + Fkvarlimit(0.0), + TotalWeight(0.0), + DailyForecasstShapeObj(nullptr) +{ + Set_Name(LowerCase(ESPVLControlName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementName = ""; + Set_ControlledElement(nullptr); // not used in this control + ElementTerminal = 1; + Set_MonitoredElement(nullptr); + FLocalControlNameList = new TStringList(); + FLocalControlWeights = nullptr; + FLocalControlPointerList = new PointerList::TPointerList(20); // Default size and increment + FLocalControlListSize = 0; + FPVSystemNameList = new TStringList(); + FPVSystemWeights = nullptr; + FPVSystemPointerList = new PointerList::TPointerList(20); // Default size and increment + FPVsystemListSize = 0; + FStorageNameList = new TStringList(); + FStorageWeights = nullptr; + FStoragePointerList = new PointerList::TPointerList(20); // Default size and increment + FStorageListSize = 0; + FkWLimit = 8000.0; + FkWBand = 100.0; + TotalWeight = 1.0; + HalfkWBand = FkWBand / 2.0; + InitPropertyValues(0); + Fkvarlimit = FkWLimit / 2.0; + + + // RecalcElementData; +} + +TESPVLControlObj::~TESPVLControlObj() +{ + ElementName = ""; + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + + +/*Check for existence of monitored element*/ + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) + { + Set_MonitoredElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + if(ElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("ESPVLControl: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 371); + } + else + + // Sets name of i-th terminal's connected bus in ESPVLControl's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + } + else + DoSimpleMsg(String("Monitored Element in ESPVLControl.") + get_Name() + + " does not exist:\"" + + ElementName + + "\"", 372); +} + +void TESPVLControlObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + + + + + + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TESPVLControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + + + /*Do Nothing*/ +} + +/*--------------------------------------------------------------------------*/ + +void TESPVLControlObj::sample(int ActorID) +{ + int i = 0; + double PDiff = 0.0; + double QDiff = 0.0; + complex s = {}; + TGeneratorObj* Gen = nullptr; + bool GenkWChanged = false; + bool Genkvarchanged = false; + double GenkW = 0.0; + double Genkvar = 0.0; + // If list is not define, go make one from all generators in circuit + if(FLocalControlPointerList->get_myNumList() == 0) + MakeLocalControlList(); + if(FLocalControlListSize > 0) + + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + { + s = get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID); // Power in active terminal + PDiff = s.re * 0.001 - FkWLimit; + QDiff = s.im * 0.001 - Fkvarlimit; + + // Redispatch the vars. + GenkWChanged = false; + Genkvarchanged = false; + if(Abs(PDiff) > HalfkWBand) // Redispatch Generators + // PDiff is kW needed to get back into band + { + int stop = 0; + for(stop = FLocalControlListSize, i = 1; i <= stop; i++) + { + Gen = (TGeneratorObj*) FLocalControlPointerList->Get(i); + // compute new dispatch value for this generator ... + GenkW = max(1.0, (Gen->kWBase + PDiff * ((FLocalControlWeights)[i - 1] / TotalWeight))); + if(GenkW != Gen->kWBase) + { + Gen->kWBase = GenkW; + GenkWChanged = true; + } + } + } + /* + If Abs(QDiff) > HalfkWBand Then Begin // Redispatch Generators + // QDiff is kvar needed to get back into band + For i := 1 to FLocalControlListSize Do Begin + Gen := FLocalControlPointerList.Get(i); + // compute new dispatch value for this generator ... + Genkvar := Max(0.0, (Gen.kvarBase + QDiff *(FWeights^[i]/TotalWeight))); + If Genkvar <> Gen.kvarBase Then Begin + Gen.kvarBase := Genkvar; + Genkvarchanged := TRUE; + End; + End; + End; + + If GenkWChanged or Genkvarchanged Then // Only push onto controlqueue if there has been a change + With ActiveCircuit, ActiveCircuit.Solution Do Begin + LoadsNeedUpdating := TRUE; // Force recalc of power parms + // Push present time onto control queue to force re solve at new dispatch value + ControlQueue.Push(DynaVars.intHour, DynaVars.t, 0, 0, Self); + End; + */ + + /*Else just continue*/ + } +} + +void TESPVLControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); //'element'; + Set_PropertyValue(2, "1"); //'terminal'; + Set_PropertyValue(3, "8000"); + Set_PropertyValue(4, "100"); + Set_PropertyValue(5, "0"); + Set_PropertyValue(6, ""); + Set_PropertyValue(7, ""); + inherited::InitPropertyValues(NumPropsThisClass); +} + +bool TESPVLControlObj::MakeLocalControlList() +{ + bool result = false; + TESPVLControlObj* pESPVLControl = nullptr; + int i = 0; + result = false; + if(fType == 1) // only for System controller + { + int stop = 0; + if(FLocalControlListSize > 0) // Name list is defined - Use it + { + int stop = 0; + for(stop = FLocalControlListSize, i = 1; i <= stop; i++) + { + pESPVLControl = ((TESPVLControlObj*) ESPVLControlClass->Find(String( ( *FLocalControlNameList )[i - 1]))); + if(ASSIGNED(pESPVLControl) && pESPVLControl->Get_Enabled()) + FLocalControlPointerList->Set_New(pESPVLControl); + } + } + else + + /*Search through the entire circuit for enabled generators and add them to the list*/ + { + int stop = 0; + for(stop = ESPVLControlClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + pESPVLControl = (TESPVLControlObj*) ESPVLControlClass->ElementList.Get(i); + if(pESPVLControl->Get_Enabled()) + FLocalControlPointerList->Set_New(pESPVLControl); + } + + /*Allocate uniform weights*/ + FLocalControlListSize = FLocalControlPointerList->get_myNumList(); + FLocalControlWeights = (pDoubleArray)realloc(FLocalControlWeights, sizeof(double) * FLocalControlListSize); + for(stop = FLocalControlListSize, i = 1; i <= stop; i++) + { + (FLocalControlWeights)[i - 1] = 1.0; + } + } + + // Add up total weights ?????? + TotalWeight = 0.0; + for(stop = FLocalControlListSize, i = 1; i <= stop; i++) + { + TotalWeight = TotalWeight + (FLocalControlWeights)[i - 1]; + } + if(FLocalControlPointerList->get_myNumList() > 0) + result = true; + } + return result; +} + +void TESPVLControlObj::Reset(int ActorID) +{ + + // inherited; +} + + + + +} // namespace ESPVLControl + + + + + diff --git a/OpenDSSC/Controls/ESPVLControl.h b/OpenDSSC/Controls/ESPVLControl.h new file mode 100644 index 0000000..41374dd --- /dev/null +++ b/OpenDSSC/Controls/ESPVLControl.h @@ -0,0 +1,146 @@ +#ifndef ESPVLControlH +#define ESPVLControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "LoadShape.h" +#include "d2c_structures.h" + + +namespace ESPVLControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + An ESPVLControl is a control element that is connected to a terminal of another + circuit element (a PVSystem) and sends dispatch kW signals to a set of Storage Elements it controls + + An ESPVLControl is either a System Controller or a Local Controller, set by the "Type" property. + A System Controller controls one or more Local Controllers + A Local Controller controls one or more PVSystem elements and one or more Storage elements. + + An ESPVLControl is defined by a New command: + + New ESPVLControl.Name=myname Element=devclass.name terminal=[ 1|2|...] StorageList = (gen1 gen2 ...) + + +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TESPVLControl : public ControlClass::TControlClass +{ + friend class TESPVLControlObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String ESPVLControlName); +public: + TESPVLControl(); + virtual ~TESPVLControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TESPVLControlObj : public ControlElem::TControlElem +{ + friend class TESPVLControl; +public: + typedef ControlElem::TControlElem inherited; +private: + int fType; /*1=System controller; 2=Local controller*/ + + /*System Controller Variables*/ + + // Local Controllers under supervision of System Controller + int FLocalControlListSize; + TStringList* FLocalControlNameList; + PointerList::TPointerList* FLocalControlPointerList; + Arraydef::pDoubleArray FLocalControlWeights; + + + /*Local Controller Variables*/ + + // PVSystems under supervision of this Local Controller + int FPVsystemListSize; + TStringList* FPVSystemNameList; + PointerList::TPointerList* FPVSystemPointerList; + Arraydef::pDoubleArray FPVSystemWeights; + + // Storage Devices under supervision of this Local Controller + int FStorageListSize; + TStringList* FStorageNameList; + PointerList::TPointerList* FStoragePointerList; + Arraydef::pDoubleArray FStorageWeights; + +// dead band control parameters + double FkWLimit; + double FkWBand; + double HalfkWBand; + double Fkvarlimit; + double TotalWeight; + + + + // YearlyShape :String; // ='fixed' means no variation on all the time + // YearlyShapeObj :TLoadShapeObj; // Shape for this Storage element + String DailyForecastShape; // Daily (24 HR) Storage element shape + LoadShape::TLoadShapeObj* DailyForecasstShapeObj; // Daily Storage element Shape for this load + // DutyShape :String; // Duty cycle load shape for changes typically less than one hour + // DutyShapeObj :TLoadShapeObj; // Shape for this Storage element + Ucomplex::complex LoadShapeMult; +public: + TESPVLControlObj(DSSClass::TDSSClass* ParClass, const String ESPVLControlName); + virtual ~TESPVLControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a ESPVLControl + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + bool MakeLocalControlList(); + TESPVLControlObj(DSSClass::TDSSClass* ParClass); + TESPVLControlObj(String ClassName); + TESPVLControlObj(); +}; +extern TESPVLControl* ESPVLControlClass; +extern TESPVLControlObj* ActiveESPVLControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace ESPVLControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ESPVLControl; +#endif + +#endif // ESPVLControlH + + + + + diff --git a/OpenDSSC/Controls/ExpControl.cpp b/OpenDSSC/Controls/ExpControl.cpp new file mode 100644 index 0000000..b2da24d --- /dev/null +++ b/OpenDSSC/Controls/ExpControl.cpp @@ -0,0 +1,947 @@ + +#pragma hdrstop + +#include "ExpControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PVSystem; +using namespace ParserDel; +using namespace PointerList; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace ExpControl +{ + +TExpControlObj::TExpControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TExpControlObj::TExpControlObj(String ClassName) : inherited(ClassName) {} +TExpControlObj::TExpControlObj() {} + + +TExpControlObj* ActiveExpControlObj = nullptr; +const int NumPropsThisClass = 14; +const int None = 0; +const int CHANGEVARLEVEL = 1; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all ExpControl objects + +TExpControl::TExpControl() +{ + ; + Class_Name = "ExpControl"; + DSSClassType = DSSClassType + EXP_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TExpControl::~TExpControl() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TExpControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "PVSystemList"; + PropertyName[2 - 1] = "Vreg"; + PropertyName[3 - 1] = "Slope"; + PropertyName[4 - 1] = "VregTau"; + PropertyName[5 - 1] = "Qbias"; + PropertyName[6 - 1] = "VregMin"; + PropertyName[7 - 1] = "VregMax"; + PropertyName[8 - 1] = "QmaxLead"; + PropertyName[9 - 1] = "QmaxLag"; + PropertyName[10 - 1] = "EventLog"; + PropertyName[11 - 1] = "DeltaQ_factor"; + PropertyName[12 - 1] = "PreferQ"; + PropertyName[13 - 1] = "Tresponse"; + PropertyName[14 - 1] = "DERList"; + PropertyHelp[1 - 1] = String("Array list of PVSystems to be controlled.") + CRLF + + CRLF + + "If not specified, all PVSystems in the circuit are assumed to be controlled by this ExpControl."; + PropertyHelp[2 - 1] = String("Per-unit voltage at which reactive power is zero; defaults to 1.0.") + CRLF + + CRLF + + "This may dynamically self-adjust when VregTau > 0, limited by VregMin and VregMax." + + "If imput as 0, Vreg will be initialized from a snapshot solution with no inverter Q." + + "The equilibrium point of reactive power is also affected by Qbias"; + PropertyHelp[3 - 1] = String("Per-unit reactive power injection / per-unit voltage deviation from Vreg; defaults to 50.") + CRLF + + CRLF + + "Unlike InvControl, base reactive power is constant at the inverter kva rating."; + PropertyHelp[4 - 1] = String("Time constant for adaptive Vreg. Defaults to 1200 seconds.") + CRLF + + CRLF + + "When the control injects or absorbs reactive power due to a voltage deviation from the Q=0 crossing of the volt-var curve, " + + "the Q=0 crossing will move toward the actual terminal voltage with this time constant. " + + "Over time, the effect is to gradually bring inverter reactive power to zero as the grid voltage changes due to non-solar effects. " + + "If zero, then Vreg stays fixed. " + + "IEEE1547-2018 requires adjustability from 300s to 5000s"; + PropertyHelp[5 - 1] = String("Equilibrium per-unit reactive power when V=Vreg; defaults to 0.") + CRLF + + CRLF + + "Enter > 0 for lagging (capacitive) bias, < 0 for leading (inductive) bias."; + PropertyHelp[6 - 1] = "Lower limit on adaptive Vreg; defaults to 0.95 per-unit"; + PropertyHelp[7 - 1] = "Upper limit on adaptive Vreg; defaults to 1.05 per-unit"; + PropertyHelp[8 - 1] = String("Limit on leading (inductive) reactive power injection, in per-unit of base kva; defaults to 0.44." "For Category A inverters per P1547/D7, set this value to 0.25.") + CRLF + + CRLF + + "Regardless of QmaxLead, the reactive power injection is still " + + "limited by dynamic headroom when actual real power output exceeds 0%"; + PropertyHelp[9 - 1] = String("Limit on lagging (capacitive) reactive power injection, in per-unit of base kva; defaults to 0.44.") + CRLF + + CRLF + + "For Category A inverters per P1547/D7, set this value to 0.25." + + "Regardless of QmaxLag, the reactive power injection is still " + + "limited by dynamic headroom when actual real power output exceeds 0%"; + PropertyHelp[10 - 1] = "{Yes/True* | No/False} Default is No for ExpControl. Log control actions to Eventlog."; + PropertyHelp[11 - 1] = String("Convergence parameter; Defaults to 0.7. ") + CRLF + + CRLF + + "Sets the maximum change (in per unit) from the prior var output level to the desired var output level during each control iteration. " + + "If numerical instability is noticed in solutions such as var sign changing from one control iteration to the next and voltages oscillating between two values with some separation, " + + "this is an indication of numerical instability (use the EventLog to diagnose). " + + "If the maximum control iterations are exceeded, and no numerical instability is seen in the EventLog of via monitors, then try increasing the value of this parameter to reduce the number " + + "of control iterations needed to achieve the control criteria, and move to the power flow solution."; + PropertyHelp[12 - 1] = String("{Yes/True* | No/False} Default is No for ExpControl.") + CRLF + + CRLF + + "Curtails real power output as needed to meet the reactive power requirement. " + + "IEEE1547-2018 requires Yes, but the default is No for backward compatibility of OpenDSS models."; + PropertyHelp[13 - 1] = String("Open-loop response time for changes in Q.") + CRLF + + CRLF + + "The value of Q reaches 90% of the target change within Tresponse, which " + + "corresponds to a low-pass filter having tau = Tresponse / 2.3026. " + + "The behavior is similar to LPFTAU in InvControl, but here the response time is " + + "input instead of the time constant. " + + "IEEE1547-2018 default is 10s for Catagory A and 5s for Category B, " + + "adjustable from 1s to 90s for both categories. However, the default is 0 for " + + "backward compatibility of OpenDSS models."; + PropertyHelp[14 - 1] = "Alternative to PVSystemList for CIM export and import." + CRLF + CRLF + + "However, storage is not actually implemented yet. " + + "Use fully qualified PVSystem names."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TExpControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new ExpControl and add it to ExpControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TExpControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TExpControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + ActiveExpControlObj = (TExpControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveExpControlObj); + result = 0; + /*# with ActiveExpControlObj do */ + { + auto with0 = ActiveExpControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 364); + break; + case 1: + { + InterpretTStringListArray(Param, *(with0->FPVSystemNameList)); + // Reset FDERNameList + with0->FDERNameList->clear(); + for(int stop = with0->FPVSystemNameList->size(), i = 0; i < stop; i++) + { + with0->FDERNameList->push_back("PVSystem." + (*with0->FPVSystemNameList)[i]); + } + with0->FPVSystemPointerList->Clear(); // clear this for resetting on first sample + with0->FListSize = with0->FPVSystemNameList->size(); + } + break; + case 2: + if(Parser[ActorID]->MakeDouble_() >= 0) + with0->FVregInit = Parser[ActorID]->MakeDouble_(); + break; + case 3: + if(Parser[ActorID]->MakeDouble_() > 0) + with0->FSlope = Parser[ActorID]->MakeDouble_(); + break; + case 4: + if(Parser[ActorID]->MakeDouble_() >= 0) + with0->FVregTau = Parser[ActorID]->MakeDouble_(); + break; // zero means fixed Vreg + case 5: + with0->FQbias = Parser[ActorID]->MakeDouble_(); + break; + case 6: + if(Parser[ActorID]->MakeDouble_() > 0) + with0->FVregMin = Parser[ActorID]->MakeDouble_(); + break; + case 7: + if(Parser[ActorID]->MakeDouble_() > 0) + with0->FVregMax = Parser[ActorID]->MakeDouble_(); + break; + case 8: + if(Parser[ActorID]->MakeDouble_() >= 0) + with0->FQmaxLead = Parser[ActorID]->MakeDouble_(); + break; + case 9: + if(Parser[ActorID]->MakeDouble_() >= 0) + with0->FQmaxLag = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->ShowEventLog = InterpretYesNo(Param); + break; + case 11: + with0->FdeltaQ_factor = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FPreferQ = InterpretYesNo(Param); + break; + case 13: + if(Parser[ActorID]->MakeDouble_() >= 0) + with0->FTresponse = Parser[ActorID]->MakeDouble_(); + break; + case 14: + InterpretTStringListArray(Param, *(with0->FDERNameList)); + // Reset FPVSystemNameList + with0->FPVSystemNameList->clear(); + for(int stop = (*with0->FDERNameList).size(), i = 0; i < stop; i++) + { + with0->FPVSystemNameList->push_back((*with0->FDERNameList)[i]); + } + with0->FPVSystemPointerList->Clear(); + with0->FListSize = with0->FPVSystemNameList->size(); // To match the new size + break; + // Inherited parameters + default: + ClassEdit(ActiveExpControlObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +int TExpControl::MakeLike(const String ExpControlName) +{ + int result = 0; + TExpControlObj* OtherExpControl = nullptr; + int i = 0; + int j = 0; + result = 0; + /*See if we can find this ExpControl name in the present collection*/ + OtherExpControl = ((TExpControlObj*) Find(ExpControlName)); + if(OtherExpControl != nullptr) + /*# with ActiveExpControlObj do */ + { + auto with0 = ActiveExpControlObj; + int stop = 0; + with0->Set_NPhases(OtherExpControl->Fnphases); + with0->Set_Nconds(OtherExpControl->Fnconds); // Force Reallocation of terminal stuff + for(stop = with0->FPVSystemPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + with0->ControlledElement[i] = OtherExpControl->ControlledElement[i]; + with0->FWithinTol[i] = OtherExpControl->FWithinTol[i]; + } + with0->FListSize = OtherExpControl->FListSize; + with0->FVoltageChangeTolerance = OtherExpControl->FVoltageChangeTolerance; + with0->FVarChangeTolerance = OtherExpControl->FVarChangeTolerance; + with0->FVregInit = OtherExpControl->FVregInit; + with0->FSlope = OtherExpControl->FSlope; + with0->FVregTau = OtherExpControl->FVregTau; + with0->FQbias = OtherExpControl->FQbias; + with0->FVregMin = OtherExpControl->FVregMin; + with0->FVregMax = OtherExpControl->FVregMax; + with0->FQmaxLead = OtherExpControl->FQmaxLead; + with0->FQmaxLag = OtherExpControl->FQmaxLag; + with0->FdeltaQ_factor = OtherExpControl->FdeltaQ_factor; + with0->FPreferQ = OtherExpControl->FPreferQ; + with0->FTresponse = OtherExpControl->FTresponse; + with0->FOpenTau = with0->FTresponse / 2.3026; // not sure if RecalcElementData will be invoked from the call stack + for(stop = with0->ParentClass->NumProperties, j = 1; j <= stop; j++) + { + with0->Set_PropertyValue(j, OtherExpControl->Get_PropertyValue(j)); + } + } + else + DoSimpleMsg(String("Error in ExpControl MakeLike: \"") + ExpControlName + + "\" Not Found.", 370); + return result; +} + +/*==========================================================================*/ +/* TExpControlObj */ +/*==========================================================================*/ + +TExpControlObj::TExpControlObj(TDSSClass* ParClass, const String ExpControlName) + : inherited(ParClass), + ControlActionHandle(0), + FListSize(0), + FVregInit(0.0), + FSlope(0.0), + FVregTau(0.0), + FQbias(0.0), + FVregMin(0.0), + FVregMax(0.0), + FQmaxLead(0.0), + FQmaxLag(0.0), + FdeltaQ_factor(0.0), + FVoltageChangeTolerance(0.0), + FVarChangeTolerance(0.0), + FPreferQ(false), + FTresponse(0.0), + FOpenTau(0.0) +{ + Set_Name(LowerCase(ExpControlName)); + DSSObjType = ParClass->DSSClassType; + ElementName = ""; + //FPVSystemNameList->clear(); + //FPVSystemPointerList = NULL, + + /* + Control elements are zero current sources that attach to a terminal of a + power-carrying device, but do not alter voltage or current flow. + Define a default number of phases and conductors here and update in + RecalcElementData routine if necessary. This allocates arrays for voltages + and currents and gives more direct access to the values, if needed + */ + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // This general feature should not be used for ExpControl, + // because it controls more than one PVSystem + ShowEventLog = false; + ControlledElement.clear(); + //FPVSystemNameList->clear(); + FPVSystemPointerList = NULL; + cBuffer.clear(); + FPriorVpu = NULL; + FPresentVpu = NULL; + FPendingChange = NULL; + FLastIterQ = NULL; + FLastStepQ = NULL; + FTargetQ = NULL; + FWithinTol = NULL; + FVoltageChangeTolerance = 0.0001; // per-unit + FVarChangeTolerance = 0.0001; // per-unit + FDERNameList = new TStringList(); + FPVSystemNameList = new TStringList(); + FPVSystemPointerList = new PointerList::TPointerList(20); // Default size and increment + + ElementTerminal = 1; + + // user parameters for dynamic Vreg + FVregInit = 1.0; // 0 means to find it during initialization + FSlope = 50.0; + FVregTau = 1200.0; + FVregs = NULL; + FQbias = 0.0; + FVregMin = 0.95; + FVregMax = 1.05; + FQmaxLead = 0.44; + FQmaxLag = 0.44; + FdeltaQ_factor = 0.7; // only on control iterations, not the final solution + FPreferQ = false; + FTresponse = 0.0; + FOpenTau = 0.0; + + //generic for control + FPendingChange = NULL; + InitPropertyValues(0); +} + +TExpControlObj::~TExpControlObj() +{ + ElementName = ""; + ControlledElement.clear(); + cBuffer.clear(); + FDERNameList->clear(); + FPVSystemNameList->clear(); + FPVSystemPointerList = NULL; + free(FPriorVpu); + free(FPresentVpu); + free(FPendingChange); + free(FLastIterQ); + free(FLastStepQ); + free(FTargetQ); + free(FWithinTol); + free(FVregs); + // inherited::Destroy(); +} + + +void TExpControlObj::RecalcElementData(int ActorID) +{ + int i = 0; + int maxord = 0; + int stop = 0; + FOpenTau = FTresponse / 2.3026; + if(FPVSystemPointerList->get_myNumList() == 0) + MakePVSystemList(); + if(FPVSystemPointerList->get_myNumList() > 0) + /*Setting the terminal of the ExpControl device to same as the 1st PVSystem element*/ + { + Set_MonitoredElement(((TDSSCktElement*) FPVSystemPointerList->Get(1))); // Set MonitoredElement to 1st PVSystem in lise + SetBus(1, get_FMonitoredElement()->Get_FirstBus()); + } + maxord = 0; // will be the size of cBuffer + for(stop = FPVSystemPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + // User ControlledElement[] as the pointer to the PVSystem elements + ControlledElement[i] = ((TPVsystemObj*) FPVSystemPointerList->Get(i)); // pointer to i-th PVSystem + Set_NPhases(( (TDSSCktElement*) ControlledElement[i] )->Get_NPhases()); // TEMC TODO - what if these are different sizes (same concern exists with InvControl) + Set_Nconds(Get_NPhases()); + if(ControlledElement[i] == nullptr) + DoErrorMsg(String("ExpControl: \"") + this->get_Name() + "\"", String("Controlled Element \"") + ( *FPVSystemNameList )[i - 1] + + "\" Not Found.", " PVSystem object must be defined previously.", 361); + if(((TDSSCktElement*)ControlledElement[i])->Yorder > maxord) + maxord = ((TDSSCktElement*)ControlledElement[i])->Yorder; + ((TDSSCktElement*)ControlledElement[i])->Set_ActiveTerminal(1); // Make the 1 st terminal active + } + if(maxord > 0) + cBuffer.resize( maxord ); +} +// *** This assumes the PVSystem devices have already been converted to pos seq + +void TExpControlObj::MakePosSequence(int ActorID) +{ + if(FPVSystemPointerList->get_myNumList() == 0) + RecalcElementData(ActorID); + // TEMC - from here to inherited was copied from InvControl + Set_NPhases(3); + Set_Nconds(3); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + if(FPVSystemPointerList->get_myNumList() > 0) + /*Setting the terminal of the ExpControl device to same as the 1st PVSystem element*/ + /* This sets it to a realistic value to avoid crashes later */ + { + Set_MonitoredElement(((TDSSCktElement*) FPVSystemPointerList->Get(1))); // Set MonitoredElement to 1st PVSystem in lise + SetBus(1, get_FMonitoredElement()->Get_FirstBus()); + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); + Set_Nconds(Get_NPhases()); + } + inherited::MakePosSequence(ActorID); +} + +void TExpControlObj::CalcYPrim(int ActorID) +{ +} + +void TExpControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; +// Control is a zero current source + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TExpControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; +// Control is a zero current source + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TExpControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +void TExpControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + int i = 0; + double Qset = 0.0; + double DeltaQ = 0.0; + double Qmaxpu = 0.0; + double Qpu = 0.0; + double Qbase = 0.0; + double Qinvmaxpu = 0.0; + double Plimit = 0.0; + double DT = 0.0; + TPVsystemObj* PVSys = nullptr; + int stop = 0; + for(stop = FPVSystemPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + PVSys = ControlledElement[i]; // Use local variable in loop + if(Get_PendingChange(i) == CHANGEVARLEVEL) + { + PVSys->Set_VWmode(false); + ( (TDSSCktElement*) PVSys )->Set_ActiveTerminal(1); // Set active terminal of PVSystem to terminal 1 + PVSys->Set_Varmode(VARMODEKVAR); // Set var mode to VARMODEKVAR to indicate we might change kvar + FTargetQ[i] = 0.0; + Qbase = PVSys->Get_FkVArating(); + Qinvmaxpu = PVSys->Get_Fkvarlimit() / Qbase; + Qpu = PVSys->Get_Presentkvar() / Qbase; // no change for now + if(FWithinTol[i] == false) + // look up Qpu from the slope crossing at Vreg, and add the bias + { + Qpu = -FSlope * (FPresentVpu[i] - FVregs[i]) + FQbias; + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + "," + + PVSys->get_Name(), Format(" Setting Qpu= %.5g at FVreg= %.5g, Vpu= %.5g",Qpu, FVregs[i], FPresentVpu[i]), ActorID); + } + + // apply limits on Qpu, then define the target in kVAR + PVSys->SetNominalPVSystemOuput(ActorID); // as does InvControl + if(FPreferQ) + Qmaxpu = 1.0; + else + Qmaxpu = sqrt(1.0L - Sqr(PVSys->Get_PresentkW() / Qbase)); // dynamic headroom + if(Qmaxpu > Qinvmaxpu) + Qmaxpu = Qinvmaxpu; + if(Abs(Qpu) > Qmaxpu) + Qpu = Qmaxpu * Sign(Qpu); + if(Qpu < - FQmaxLead) + Qpu = -FQmaxLead; + if(Qpu > FQmaxLag) + Qpu = FQmaxLag; + FTargetQ[i] = Qbase * Qpu; + if(FPreferQ) + { + Plimit = Qbase * sqrt(1 - Qpu * Qpu); + if(Plimit < PVSys->Get_PresentkW()) + { + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + "," + ( (TDSSObject*) PVSys )->get_Name(), Format(" curtailing %.3f to %.3f kW",PVSys->Get_PresentkW(), Plimit), ActorID); + PVSys->Set_PresentkW(Plimit); + PVSys->Set_puPmpp(Plimit / PVSys->Get_FPmpp()); + } + } + + // put FTargetQ through the low-pass open-loop filter + if(FOpenTau > 0.0 && ActiveCircuit[ActorID]->Solution->ControlMode != CTRLSTATIC) + { + DT = ActiveCircuit[ActorID]->Solution->DynaVars.h; + FTargetQ[i] = FLastStepQ[i] + (FTargetQ[i] - FLastStepQ[i]) * (1 - exp(-DT / FOpenTau)); // TODO - precalculate? + } + + // only move the non-bias component by deltaQ_factor in this control iteration + DeltaQ = FTargetQ[i] - FLastIterQ[i]; + Qset = FLastIterQ[i] + DeltaQ * FdeltaQ_factor; + // Qset := FQbias * Qbase; + if(PVSys->Get_Presentkvar() != Qset) + PVSys->Set_Presentkvar(Qset); + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + "," + PVSys->get_Name(), Format(" Setting PVSystem output kvar= %.5g",PVSys->Get_Presentkvar()), ActorID); + FLastIterQ[i] = Qset; + FPriorVpu[i] = FPresentVpu[i]; + ActiveCircuit[ActorID]->Solution->LoadsNeedUpdating = true; + // Force recalc of power parms + Set_PendingChange(None, i); + } + } +} + +void TExpControlObj::sample(int ActorID) +{ + int i = 0; + int j = 0; + double BaseKV = 0.0; + double Vpresent = 0.0; + double Verr = 0.0; + double Qerr = 0.0; + TPVsystemObj* PVSys = nullptr; + // If list is not defined, go make one from all PVSystem in circuit + if(FPVSystemPointerList->get_myNumList() == 0) + RecalcElementData(ActorID); + if(FListSize > 0) + // If an ExpControl controls more than one PV, control each one + // separately based on the PVSystem's terminal voltages, etc. + { + int stop = 0; + for(stop = FPVSystemPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + int stop1 = 0; + PVSys = ControlledElement[i]; // Use local variable in loop + // Calculate the present average voltage magnitude + PVSys->ComputeVterminal(ActorID); + for(stop1 = PVSys->Yorder, j = 1; j <= stop1; j++) + { + cBuffer[j - 1] = (PVSys)->Vterminal[j - 1]; + } + BaseKV = ActiveCircuit[ActorID]->Buses[((TDSSCktElement*)PVSys)->Terminals[0].BusRef - 1]->kVBase; + + Vpresent = 0; + for(stop1 = ((TDSSCktElement*)PVSys)->Get_NPhases(), j = 1; j <= stop1; j++) + { + Vpresent = Vpresent + cabs(cBuffer[j - 1]); + } + FPresentVpu[i] = (Vpresent / ((TDSSCktElement*)PVSys)->Get_NPhases()) / (BaseKV * 1000.0); + // if initializing with Vreg=0 in static mode, we want to FIND Vreg + if((ActiveCircuit[ActorID]->Solution->ControlMode == CTRLSTATIC) && (FVregInit <= 0.0)) + { + FVregs[i] = FPresentVpu[i]; + + if (FVregs[i] < FVregMin) + { + FVregs[i] = FVregMin; + FVregInit = 0.01; // Don't let it outside the band + } + if (FVregs[i] > FVregMax) + { + FVregs[i] = FVregMax; + FVregInit = 0.01; // Don't let it outside the band + } + } + // both errors are in per-unit + Verr = Abs(FPresentVpu[i] - FPriorVpu[i]); + Qerr = double(Abs( (PVSys->Get_Presentkvar() - FTargetQ[i])) / PVSys->Get_FkVArating()); + // process the sample + if((PVSys->Get_InverterON() == false) && (PVSys->Get_VarFollowInverter() == true)) // not injecting + { + if((FVregTau > 0.0) && (FVregs[i] <= 0.0)) + FVregs[i] = FPresentVpu[i]; // wake up to the grid voltage, otherwise track it while not injecting + continue; + } + PVSys->Set_VWmode(false); + if((Verr > FVoltageChangeTolerance) || (Qerr > FVarChangeTolerance) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + { + FWithinTol[i] = false; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with0.intHour, with0.T + TimeDelay, (EControlAction) Get_PendingChange(i), 0, this, ActorID); + } + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + " " + PVSys->get_Name(), Format(" outside Hit Tolerance, Verr= %.5g, Qerr=%.5g",Verr, Qerr), ActorID); + } + else + { + FWithinTol[i] = true; + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + " " + PVSys->get_Name(), Format(" within Hit Tolerance, Verr= %.5g, Qerr=%.5g",Verr, Qerr), ActorID); + } + } /*For*/ + } /*If FlistSize*/ +} + +void TExpControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); // PVSystem list + Set_PropertyValue(2, "1"); // initial Vreg + Set_PropertyValue(3, "50"); // slope + Set_PropertyValue(4, "1200.0");// VregTau + Set_PropertyValue(5, "0"); // Q bias + Set_PropertyValue(6, "0.95"); // Vreg min + Set_PropertyValue(7, "1.05"); // Vreg max + Set_PropertyValue(8, "0.44"); // Qmax leading + Set_PropertyValue(9, "0.44"); // Qmax lagging + Set_PropertyValue(10, ShowEventLog ? "YES" : "NO"); // write event log? + Set_PropertyValue(11, "0.7"); // DeltaQ_factor + Set_PropertyValue(12, "no"); // PreferQ + Set_PropertyValue(13, "0"); // TResponse + Set_PropertyValue(14, ""); // Der Name List + inherited::InitPropertyValues(NumPropsThisClass); +} + +bool TExpControlObj::MakePVSystemList() +{ + bool result = false; + TDSSClass* PVSysClass = nullptr; + TPVsystemObj* PVSys = nullptr; + int i = 0; + int stop = 0; + result = false; + PVSysClass = (TDSSClass*)GetDSSClassPtr("PVsystem"); + if(FListSize > 0) // Name list is defined - Use it + { + int stop = 0; + ControlledElement.resize( FListSize + 1 ); // Use this as the main pointer to PVSystem Elements + FPriorVpu = new double[FListSize + 1]; + FPresentVpu = new double[FListSize + 1]; + FPendingChange = new int[FListSize + 1]; + FLastIterQ = new double[FListSize + 1]; + FLastStepQ = new double[FListSize + 1]; + FTargetQ = new double[FListSize + 1]; + FWithinTol = new bool[FListSize + 1]; + FVregs = new double[FListSize + 1]; + for(stop = FListSize, i = 1; i <= stop; i++) + { + PVSys = ((TPVsystemObj*) PVSysClass->Find(String( (*FPVSystemNameList )[i - 1]))); + if(ASSIGNED(PVSys) && ( (TDSSCktElement*) PVSys )->Get_Enabled()) + { + FPVSystemPointerList->Set_New(PVSys); + PVSys->Set_AVRmode(true); + PVSys->Set_Variable(5, FVregInit); + } + } + } + else + + /*Search through the entire circuit for enabled pvsysten objects and add them to the list*/ + { + int stop = 0; + for(stop = PVSysClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + PVSys = (TPVsystemObj*) PVSysClass->ElementList.Get(i); + if( ( (TDSSCktElement*) PVSys )->Get_Enabled()) + FPVSystemPointerList->Set_New(PVSys); + FPVSystemNameList->push_back( ( (TDSSObject*) PVSys )->get_Name()); + } + FListSize = FPVSystemPointerList->get_myNumList(); + ControlledElement.resize( FListSize + 1 ); + FPriorVpu = new double[FListSize + 1]; + FPresentVpu = new double[FListSize + 1]; + FPendingChange = new int[FListSize + 1]; + FLastIterQ = new double[FListSize + 1]; + FLastStepQ = new double[FListSize + 1]; + FTargetQ = new double[FListSize + 1]; + FWithinTol = new bool[FListSize + 1]; + FVregs = new double[FListSize + 1]; + } /*Else*/ + + //Initialize arrays + for(stop = FListSize, i = 1; i <= stop; i++) + { +// PVSys := PVSysClass.Find(FPVSystemNameList.Strings[i-1]); +// Set_NTerms(PVSys.NTerms); // TODO - what is this for? + FPriorVpu[i] = 0.0; + FPresentVpu[i] = 0.0; + FLastIterQ[i] = -1.0; + FLastStepQ[i] = -1.0; + FTargetQ[i] = 0.0; + FWithinTol[i] = false; + FVregs[i] = FVregInit; + FPendingChange[i] = None; + } /*For*/ + RecalcElementData(ActiveActor); + if(FPVSystemPointerList->get_myNumList() > 0) + result = true; + return result; +} + +void TExpControlObj::Reset(int ActorID) +{ + + // inherited; +} + +String TExpControlObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = ReturnElementsList(); + break; + case 2: + result = Format("%.6g",FVregInit); + break; + case 3: + result = Format("%.6g",FSlope); + break; + case 4: + result = Format("%.6g",FVregTau); + break; + case 5: + result = Format("%.6g",FQbias); + break; + case 6: + result = Format("%.6g",FVregMin); + break; + case 7: + result = Format("%.6g",FVregMax); + break; + case 8: + result = Format("%.6g",FQmaxLead); + break; + case 9: + result = Format("%.6g",FQmaxLag); + break; + case 11: + result = Format("%.6g",FdeltaQ_factor); + break; + case 12: + if(FPreferQ) + result = "yes"; + else + result = "no"; + break; + case 13: + result = Format("%.6g",FTresponse); + break; + // 10 skipped, EventLog always went to the default handler + // take the generic handler + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +String TExpControlObj::ReturnElementsList() +{ + String result; + int i = 0; + int stop = 0; + if(FListSize == 0) + { + result = ""; + return result; + } + result = String("[") + ( *FPVSystemNameList )[0]; + for(stop = FListSize - 1, i = 1; i <= stop; i++) + { + result = result + ", " + String(( *FPVSystemNameList )[i]); + } + result = result + "]"; // terminate the array + return result; +} + +void TExpControlObj::Set_Enabled(bool Value) +{ + inherited::Set_Enabled(Value); + /*Reset controlled PVSystems to original PF*/ +} + +void TExpControlObj::Set_PendingChange(int Value, int DevIndex) +{ + FPendingChange[DevIndex] = Value; + DblTraceParameter = (double) Value; +} + +void TExpControlObj::UpdateExpControl(int i, int ActorID) +{ + int j = 0; + TPVsystemObj* PVSys = nullptr; + double DT = 0.0; + double Verr = 0.0; // for DYNAMICVREG + int stop = 0; + for(stop = FPVSystemPointerList->get_myNumList(), j = 1; j <= stop; j++) + { + PVSys = ControlledElement[j]; + FLastStepQ[j] = PVSys->Get_Presentkvar(); + if(FVregTau > 0.0) + { + DT = ActiveCircuit[ActorID]->Solution->DynaVars.h; + Verr = FPresentVpu[j] - FVregs[j]; + FVregs[j] = FVregs[j] + Verr * (1 - exp(-DT / FVregTau)); // TODO - precalculate? + } + else + { + Verr = 0.0; + } + if(FVregs[j] < FVregMin) + FVregs[j] = FVregMin; + if(FVregs[j] > FVregMax) + FVregs[j] = FVregMax; + PVSys->Set_Variable(5, FVregs[j]); + if(ShowEventLog) + AppendToEventLog(String("ExpControl.") + this->get_Name() + "," + ( (TDSSObject*) PVSys )->get_Name(), Format(" Setting new Vreg= %.5g Vpu=%.5g Verr=%.5g",FVregs[j], FPresentVpu[j], Verr), ActorID); + } +} + +int TExpControlObj::Get_PendingChange(int DevIndex) +{ + int result = 0; + result = FPendingChange[DevIndex]; + return result; +} + +//Called at end of main power flow solution loop + +void TExpControl::UpdateAll(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TExpControlObj(ElementList.Get(i)) do */ + { + auto with0 = ((TExpControlObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->UpdateExpControl(i, ActorID); + } + } +} + + + + +} // namespace ExpControl + + + + + diff --git a/OpenDSSC/Controls/ExpControl.h b/OpenDSSC/Controls/ExpControl.h new file mode 100644 index 0000000..ff610e5 --- /dev/null +++ b/OpenDSSC/Controls/ExpControl.h @@ -0,0 +1,141 @@ +#ifndef ExpControlH +#define ExpControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "PVsystem.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "Dynamics.h" +#include "PointerList.h" +#include "d2c_structures.h" + +class TIEEE1547Controller; + +namespace ExpControl +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2015-2022, University of Pittsburgh + Copyright (c) 2019-2022, Battelle Memorial Institute + All rights reserved. + ---------------------------------------------------------- + + Notes: adapted and simplified from InvControl for adaptive controller research +*/ + +class TExpControl : public ControlClass::TControlClass +{ + friend class TExpControlObj; +public: + typedef ControlClass::TControlClass inherited; +protected: + void DefineProperties(); + virtual int MakeLike(const String ExpControlName); +public: + TExpControl(); + virtual ~TExpControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); + void UpdateAll(int ActorID); +}; + +class TExpControlObj : public ControlElem::TControlElem +{ + friend class TExpControl; + friend class ::TIEEE1547Controller; +public: + typedef ControlElem::TControlElem inherited; +private: + int ControlActionHandle; + std::vector ControlledElement; // list of pointers to controlled PVSystem elements + + // PVSystemList information + int FListSize; + TStringList* FPVSystemNameList; + TStringList* FDERNameList; + PointerList::TPointerList* FPVSystemPointerList; + + // working storage for each PV system under management + double* FPriorVpu; + double* FPresentVpu; + int* FPendingChange; + double* FVregs; + double* FLastIterQ; // for DeltaQFactor + double* FLastStepQ; // for FOpenTau + double* FTargetQ; + bool* FWithinTol; + + // temp storage for biggest PV system, not each one + std::vector cBuffer; + + // user-supplied parameters (also PVSystemList and EventLog) + double FVregInit; + double FSlope; + double FVregTau; + double FQbias; + double FVregMin; + double FVregMax; + double FQmaxLead; + double FQmaxLag; + double FdeltaQ_factor; + double FVoltageChangeTolerance; // no user adjustment + double FVarChangeTolerance; // no user adjustment + bool FPreferQ; + double FTresponse; + double FOpenTau; + void Set_PendingChange(int Value, int DevIndex); + int Get_PendingChange(int DevIndex); + String ReturnElementsList(); + void UpdateExpControl(int i, int ActorID); +protected: + virtual void Set_Enabled(bool Value); +public: + TExpControlObj(DSSClass::TDSSClass* ParClass, const String ExpControlName); + virtual ~TExpControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for an ExpControl + + // Sample control quantities and set action times in Control Queue + virtual void sample(int ActorID); + + // Do the action that is pending from last sample + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + bool MakePVSystemList(); + virtual String GetPropertyValue(int Index); + TExpControlObj(DSSClass::TDSSClass* ParClass); + TExpControlObj(String ClassName); + TExpControlObj(); +}; +extern TExpControlObj* ActiveExpControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace ExpControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExpControl; +#endif + +#endif // ExpControlH + + + + + diff --git a/OpenDSSC/Controls/GenDispatcher.cpp b/OpenDSSC/Controls/GenDispatcher.cpp new file mode 100644 index 0000000..4bea5b9 --- /dev/null +++ b/OpenDSSC/Controls/GenDispatcher.cpp @@ -0,0 +1,558 @@ + +#pragma hdrstop + +#include "GenDispatcher.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "generator.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Generator; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace GenDispatcher +{ + +TGenDispatcherObj::TGenDispatcherObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGenDispatcherObj::TGenDispatcherObj(String ClassName) : inherited(ClassName) {} +TGenDispatcherObj::TGenDispatcherObj() {} + + +TGenDispatcherObj* ActiveGenDispatcherObj = nullptr; +const int NumPropsThisClass = 6; + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all GenDispatcher objects + +TGenDispatcher::TGenDispatcher() +{ + ; + Class_Name = "GenDispatcher"; + DSSClassType = DSSClassType + GEN_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TGenDispatcher::~TGenDispatcher() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGenDispatcher::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "Element"; + PropertyName[2 - 1] = "Terminal"; + PropertyName[3 - 1] = "kWLimit"; + PropertyName[4 - 1] = "kWBand"; + PropertyName[5 - 1] = "kvarlimit"; + PropertyName[6 - 1] = "GenList"; + PropertyName[7 - 1] = "Weights"; + PropertyHelp[1 - 1] = "Full object name of the circuit element, typically a line or transformer, " + "which the control is monitoring. There is no default; must be specified."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the GenDispatcher control is connected. " + "1 or 2, typically. Default is 1. Make sure you have the direction on the power matching the sign of kWLimit."; + PropertyHelp[3 - 1] = "kW Limit for the monitored element. The generators are dispatched to hold the power in band."; + PropertyHelp[4 - 1] = "Bandwidth (kW) of the dead band around the target limit." + "No dispatch changes are attempted if the power in the monitored terminal stays within this band."; + PropertyHelp[5 - 1] = "Max kvar to be delivered through the element. Uses same dead band as kW."; + PropertyHelp[6 - 1] = "Array list of generators to be dispatched. If not specified, all generators in the circuit are assumed dispatchable."; + PropertyHelp[7 - 1] = "Array of proportional weights corresponding to each generator in the GenList." + " The needed kW to get back to center band is dispatched to each generator according to these weights. " + "Default is to set all weights to 1.0."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TGenDispatcher::NewObject(const String ObjName) +{ + int result = 0; + // Make a new GenDispatcher and add it to GenDispatcher class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGenDispatcherObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TGenDispatcher::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + + // continue parsing WITH contents of Parser + ActiveGenDispatcherObj = (TGenDispatcherObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGenDispatcherObj); + result = 0; + /*# with ActiveGenDispatcherObj do */ + { + auto with0 = ActiveGenDispatcherObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 364); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->FkWLimit = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->FkWBand = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->Fkvarlimit = Parser[ActorID]->MakeDouble_(); + break; + case 6: + InterpretTStringListArray(Param, *(with0->FGeneratorNameList)); + break; + case 7: + { + with0->FListSize = with0->FGeneratorNameList->size(); + if(with0->FListSize > 0) + { + with0->FWeights = (pDoubleArray)realloc(with0->FWeights, sizeof(double) * with0->FListSize); + with0->FListSize = InterpretDblArray(Param, with0->FListSize, with0->FWeights); + } + } + break; + // Inherited parameters + default: + ClassEdit(ActiveGenDispatcherObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 4: + with0->HalfkWBand = with0->FkWBand / 2.0; + break; // levelize the list + case 6: + { + int stop = 0; + with0->FGenPointerList->Clear(); // clear this for resetting on first sample + with0->FListSize = with0->FGeneratorNameList->size(); + with0->FWeights = (pDoubleArray)realloc(with0->FWeights, sizeof(double) * with0->FListSize); + for(stop = with0->FListSize, i = 1; i <= stop; i++) + { + (with0->FWeights)[i - 1] = 1.0; + } + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TGenDispatcher::MakeLike(const String GenDispatcherName) +{ + int result = 0; + TGenDispatcherObj* OtherGenDispatcher = nullptr; + int i = 0; + result = 0; + /*See if we can find this GenDispatcher name in the present collection*/ + OtherGenDispatcher = ((TGenDispatcherObj*) Find(GenDispatcherName)); + if(OtherGenDispatcher != nullptr) + /*# with ActiveGenDispatcherObj do */ + { + auto with0 = ActiveGenDispatcherObj; + int stop = 0; + with0->Set_NPhases(OtherGenDispatcher->Fnphases); + with0->Set_Nconds(OtherGenDispatcher->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherGenDispatcher->ElementName; + with0->Set_ControlledElement(OtherGenDispatcher->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherGenDispatcher->get_FMonitoredElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherGenDispatcher->ElementTerminal; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i, OtherGenDispatcher->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in GenDispatcher MakeLike: \"") + GenDispatcherName + + "\" Not Found.", 370); + return result; +} + + + + +/*==========================================================================*/ +/* TGenDispatcherObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TGenDispatcherObj::TGenDispatcherObj(TDSSClass* ParClass, const String GenDispatcherName) + : inherited(ParClass), + FkWLimit(8000.0), + FkWBand(100.0), + HalfkWBand(FkWBand / 2.0), + Fkvarlimit(FkWLimit / 2.0), + TotalWeight(0.0), + FListSize(0), + FGeneratorNameList(nullptr), + FGenPointerList(nullptr), + FWeights(nullptr) +{ + Set_Name(LowerCase(GenDispatcherName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementName = ""; + Set_ControlledElement(nullptr); // not used in this control + ElementTerminal = 1; + Set_MonitoredElement(nullptr); + FGeneratorNameList = new TStringList(); + FWeights = nullptr; + FGenPointerList = new PointerList::TPointerList(20); // Default size and increment + FListSize = 0; + TotalWeight = 1.0; + InitPropertyValues(0); +} + +TGenDispatcherObj::~TGenDispatcherObj() +{ + ElementName = ""; + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + + +/*Check for existence of monitored element*/ + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) + { + Set_MonitoredElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + if(ElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("GenDispatcher: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 371); + } + else + + // Sets name of i-th terminal's connected bus in GenDispatcher's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + } + else + DoSimpleMsg(String("Monitored Element in GenDispatcher.") + get_Name() + + " does not exist:\"" + + ElementName + + "\"", 372); +} + +void TGenDispatcherObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + + + + + + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TGenDispatcherObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + + + /*Do Nothing*/ +} + +/*--------------------------------------------------------------------------*/ + +void TGenDispatcherObj::sample(int ActorID) +{ + int i = 0; + double PDiff = 0.0; + double QDiff = 0.0; + complex s = {}; + TGeneratorObj* Gen = nullptr; + bool GenkWChanged = false; + bool Genkvarchanged = false; + double GenkW = 0.0; + double Genkvar = 0.0; + // If list is not define, go make one from all generators in circuit + if(FGenPointerList->get_myNumList() == 0) + MakeGenList(); + if(FListSize > 0) + + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + { + s = get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID); // Power in active terminal + PDiff = s.re * 0.001 - FkWLimit; + QDiff = s.im * 0.001 - Fkvarlimit; + + // Redispatch the vars. + GenkWChanged = false; + Genkvarchanged = false; + if(Abs(PDiff) > HalfkWBand) // Redispatch Generators + // PDiff is kW needed to get back into band + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + Gen = (TGeneratorObj*) FGenPointerList->Get(i); + // compute new dispatch value for this generator ... + GenkW = max(1.0, (Gen->kWBase + PDiff * ((FWeights)[i - 1] / TotalWeight))); + if(GenkW != Gen->kWBase) + { + Gen->kWBase = GenkW; + GenkWChanged = true; + } + } + } + if(Abs(QDiff) > HalfkWBand) // Redispatch Generators + // QDiff is kvar needed to get back into band + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + Gen = (TGeneratorObj*) FGenPointerList->Get(i); + // compute new dispatch value for this generator ... + Genkvar = max(0.0, (Gen->kvarBase + QDiff * ((FWeights)[i - 1] / TotalWeight))); + if(Genkvar != Gen->kvarBase) + { + Gen->kvarBase = Genkvar; + Genkvarchanged = true; + } + } + } + if(GenkWChanged || Genkvarchanged) + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; // Only push onto controlqueue if there has been a change + with1->LoadsNeedUpdating = true; // Force recalc of power parms + // Push present time onto control queue to force re solve at new dispatch value + ActiveCircuit[ActorID]->ControlQueue.Push(with1->DynaVars.intHour, with1->DynaVars.T, (EControlAction) 0, 0, this, ActorID); + } + + + /*Else just continue*/ + } +} + +void TGenDispatcherObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); //'element'; + Set_PropertyValue(2, "1"); //'terminal'; + Set_PropertyValue(3, "8000"); + Set_PropertyValue(4, "100"); + Set_PropertyValue(5, "0"); + Set_PropertyValue(6, ""); + Set_PropertyValue(7, ""); + inherited::InitPropertyValues(NumPropsThisClass); +} + +bool TGenDispatcherObj::MakeGenList() +{ + bool result = false; + TDSSClass* GenClass = nullptr; + TGeneratorObj* Gen = nullptr; + int i = 0; + int stop = 0; + result = false; + GenClass = (TDSSClass*)GetDSSClassPtr("generator"); + if(FListSize > 0) // Name list is defined - Use it + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + Gen = ((TGeneratorObj*) GenClass->Find( String( (*FGeneratorNameList)[i - 1] ) ) ); + if(ASSIGNED(Gen) && ( (TDSSCktElement*) Gen )->Get_Enabled()) + FGenPointerList->Set_New(Gen); + } + } + else + + /*Search through the entire circuit for enabled generators and add them to the list*/ + { + int stop = 0; + for(stop = GenClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + Gen = (TGeneratorObj*) GenClass->ElementList.Get(i); + if( ( (TDSSCktElement*) Gen )->Get_Enabled()) + FGenPointerList->Set_New(Gen); + } + + /*Allocate uniform weights*/ + FListSize = FGenPointerList->get_myNumList(); + FWeights = (pDoubleArray)realloc(FWeights, sizeof(double) * FListSize); + for(stop = FListSize, i = 1; i <= stop; i++) + { + (FWeights)[i - 1] = 1.0; + } + } + + // Add up total weights + TotalWeight = 0.0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + TotalWeight = TotalWeight + (FWeights)[i - 1]; + } + if(FGenPointerList->get_myNumList() > 0) + result = true; + return result; +} + +void TGenDispatcherObj::Reset(int ActorID) +{ + + // inherited; +} + + + + +} // namespace GenDispatcher + + + + + diff --git a/OpenDSSC/Controls/GenDispatcher.h b/OpenDSSC/Controls/GenDispatcher.h new file mode 100644 index 0000000..b021ebc --- /dev/null +++ b/OpenDSSC/Controls/GenDispatcher.h @@ -0,0 +1,107 @@ +#ifndef GenDispatcherH +#define GenDispatcherH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" + +namespace GenDispatcher +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + A GenDispatcher is a control element that is connected to a terminal of another + circuit element and sends dispatch kW signals to a set of generators it controls + + A GenDispatcher is defined by a New command: + + New GenDispatcher.Name=myname Element=devclass.name terminal=[ 1|2|...] CapacitorList = (gen1 gen2 ...) + + +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGenDispatcher : public ControlClass::TControlClass +{ + friend class TGenDispatcherObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String GenDispatcherName); +public: + TGenDispatcher(); + virtual ~TGenDispatcher(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGenDispatcherObj : public ControlElem::TControlElem +{ + friend class TGenDispatcher; +public: + typedef ControlElem::TControlElem inherited; +private: + double FkWLimit; + double FkWBand; + double HalfkWBand; + double Fkvarlimit; + double TotalWeight; + int FListSize; + TStringList* FGeneratorNameList; + PointerList::TPointerList* FGenPointerList; + Arraydef::pDoubleArray FWeights; +public: + TGenDispatcherObj(DSSClass::TDSSClass* ParClass, const String GenDispatcherName); + virtual ~TGenDispatcherObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a GenDispatcher + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + bool MakeGenList(); + TGenDispatcherObj(DSSClass::TDSSClass* ParClass); + TGenDispatcherObj(String ClassName); + TGenDispatcherObj(); +}; +extern TGenDispatcherObj* ActiveGenDispatcherObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace GenDispatcher + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GenDispatcher; +#endif + +#endif // GenDispatcherH + + + + + diff --git a/OpenDSSC/Controls/InvControl.cpp b/OpenDSSC/Controls/InvControl.cpp new file mode 100644 index 0000000..c4efef3 --- /dev/null +++ b/OpenDSSC/Controls/InvControl.cpp @@ -0,0 +1,4750 @@ + +#pragma hdrstop + +#include "InvControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PCElement; +using namespace PVSystem; +using namespace ParserDel; +using namespace PointerList; +using namespace Storage; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace InvControl +{ + +TInvControlObj::TInvControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TInvControlObj::TInvControlObj(String ClassName) : inherited(ClassName) {} +TInvControlObj::TInvControlObj() {} + + +TInvControlObj* ActiveInvControlObj = nullptr; +const int NumPropsThisClass = 34, + None = 0, + CHANGEVARLEVEL = 1, + CHANGEWATTLEVEL = 2, + CHANGEWATTVARLEVEL = 3, + CHANGEDRCVVARLEVEL = 4, + AVGPHASES = -1, + MAXPHASE = -2, + MINPHASE = -3; + +const double FLAGDELTAQ = -1.0, + FLAGDELTAP = -1.0, + DELTAQDEFAULT = 0.5, + DELTAPDEFAULT = 0.5; + + // Modes +const int NONE_MODE = 0, + VOLTVAR = 1, + VOLTWATT = 2, + DRC = 3, + WATTPF = 4, + WATTVAR = 5, + AVR = 6, + GFM = 7; + +// Modes in string type +const std::string myCtrlMode[7] = +{ "voltvar", "voltwatt", "dynamicreaccurr", "wattpf", "wattvar", "avr", "gfm" }; + +const std::string myDERTypes[2] = +{ "PVSystem", "Storage" }; + +const int PVSys = 0, + EStorage = 1; + + // Combi Modes +const int NONE_COMBMODE = 0, + VV_VW = 1, + VV_DRC = 2; // Creates superstructure for all InvControl objects + +TInvControl::TInvControl() + : XY_CurveClass((TDSSClass*) GetDSSClassPtr("XYCurve")) +{ + ; + Class_Name = "InvControl"; + DSSClassType = DSSClassType + INV_CONTROL2; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +TInvControl::~TInvControl() +{ + // inherited::Destroy(); +} + + +void TInvControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[0] = "DERList"; + PropertyName[1] = "Mode"; + PropertyName[2] = "CombiMode"; + PropertyName[3] = "vvc_curve1"; + PropertyName[4] = "hysteresis_offset"; + PropertyName[5] = "voltage_curvex_ref"; + PropertyName[6] = "avgwindowlen"; + PropertyName[7] = "voltwatt_curve"; + + //following for dynamic reactive current mode + PropertyName[8] = "DbVMin"; + PropertyName[9] = "DbVMax"; + PropertyName[10] = "ArGraLowV"; + PropertyName[11] = "ArGraHiV"; + PropertyName[12] = "DynReacavgwindowlen"; + PropertyName[13] = "deltaQ_Factor"; + PropertyName[14] = "VoltageChangeTolerance"; + PropertyName[15] = "VarChangeTolerance"; + PropertyName[16] = "VoltwattYAxis"; + PropertyName[17] = "RateofChangeMode"; + PropertyName[18] = "LPFTau"; + PropertyName[19] = "RiseFallLimit"; + PropertyName[20] = "deltaP_Factor"; + PropertyName[21] = "EventLog"; + PropertyName[22] = "RefReactivePower"; + PropertyName[23] = "ActivePChangeTolerance"; + PropertyName[24] = "monVoltageCalc"; + PropertyName[25] = "monBus"; + PropertyName[26] = "MonBusesVbase"; + PropertyName[27] = "voltwattCH_curve"; + PropertyName[28] = "wattpf_curve"; + PropertyName[29] = "wattvar_curve"; + PropertyName[30] = "VV_RefReactivePower"; + PropertyName[31] = "PVSystemList"; + PropertyName[32] = "Vsetpoint"; + PropertyName[33] = "ControlModel"; + PropertyHelp[0] = String("Array list of PVSystem and/or Storage elements to be controlled. " "If not specified, all PVSystem and Storage in the circuit are assumed to be controlled by this control. ") + CRLF + + CRLF + + "No capability of hierarchical control between two controls for a single element is implemented at this time."; + PropertyHelp[1] = String("Smart inverter function in which the InvControl will control the PC elements specified in DERList, according to the options below:") + CRLF + + CRLF + + "Must be one of: {VOLTVAR* | VOLTWATT | DYNAMICREACCURR | WATTPF | WATTVAR | GFM} " + + CRLF + "if the user desires to use modes simultaneously, then set the CombiMode property. Setting the Mode to any valid value disables combination mode." + + CRLF + CRLF + + "In volt-var mode (Default). This mode attempts to CONTROL the vars, according to one or two volt-var curves, depending on the monitored voltages, present active power output, and the capabilities of the PVSystem/Storage. " + + CRLF + CRLF + + "In volt-watt mode. This mode attempts to LIMIT the watts, according to one defined volt-watt curve, depending on the monitored voltages and the capabilities of the PVSystem/Storage. " + + CRLF + CRLF + + "In dynamic reactive current mode. This mode attempts to increasingly counter deviations by CONTROLLING vars, depending on the monitored voltages, present active power output, and the capabilities of the of the PVSystem/Storage." + + CRLF + CRLF + + "In watt-pf mode. This mode attempts to CONTROL the vars, according to a watt-pf curve, depending on the present active power output, and the capabilities of the PVSystem/Storage. " + + CRLF + CRLF + + "In watt-var mode. This mode attempts to CONTROL the vars, according to a watt-var curve, depending on the present active power output, and the capabilities of the PVSystem/Storage. " + + CRLF + CRLF + + "In GFM mode this control will trigger the GFM control routine for the DERs within the DERList.The GFM actiosn will only take place if the pointed DERs are in GFM mode.The controller parameters are locally setup at the DER. "; +// CRLF+', any limits set on maximum reactive power. '+ +// CRLF+'Precedence will be given to either watt production or var production based on the setting of RefReactivePower.'+ + PropertyHelp[2] = String("Combination of smart inverter functions in which the InvControl will control the PC elements in DERList, according to the options below: ") + CRLF + + CRLF + + "Must be a combination of the following: {VV_VW | VV_DRC}. Default is to not set this property, in which case the single control mode in Mode is active. " + + CRLF + + CRLF + + "In combined VV_VW mode, both volt-var and volt-watt control modes are active simultaneously. See help individually for volt-var mode and volt-watt mode in Mode property." + + CRLF + + "Note that the PVSystem/Storage will attempt to achieve both the volt-watt and volt-var set-points based on the capabilities of the inverter in the PVSystem/Storage (kVA rating, etc), any limits set on maximum active power," + + CRLF + + CRLF + + "In combined VV_DRC, both the volt-var and the dynamic reactive current modes are simultaneously active."; +// CRLF+CRLF+'The volt-var function will attempt to achieve its set-point based on the volt-var curve, and present voltage. The dynamic '+ +// CRLF+'reactive power mode function will also be active and it will add or subtract from the reactive power set-point desired by the volt-var function.'+ +// CRLF+'Note that the precedence of active and reactive power production is defined by the RefReactivePower property. In no event will the reactive '+ +// CRLF+'power exceed the maximum var limit of the PVSystem, and the combination of the active and reactive power output will not exceed the kVA rating of '+ +// CRLF+'the inverter (set in the PVSystem/Storage).'; + PropertyHelp[3] = String("Required for VOLTVAR mode. ") + CRLF + + CRLF + + "Name of the XYCurve object containing the volt-var curve. The positive values of the y-axis of the volt-var curve represent values in pu of the provided base reactive power. " + + "The negative values of the y-axis are values in pu of the absorbed base reactive power. " + + CRLF + + "Provided and absorbed base reactive power values are defined in the RefReactivePower property" + + CRLF + + CRLF + + "Units for the x-axis are per-unit voltage, which may be in per unit of the rated voltage for the PVSystem/Storage, or may be in per unit of the average voltage at the terminals over a user-defined number of prior solutions. "; + PropertyHelp[4] = String("Required for VOLTVAR mode, and defaults to 0. ") + CRLF + + CRLF + + "for the times when the terminal voltage is decreasing, this is the off-set in per-unit voltage of a curve whose shape is the same as vvc_curve. " + + "It is offset by a certain negative value of per-unit voltage, which is defined by the base quantity for the x-axis of the volt-var curve (see help for voltage_curvex_ref)" + + CRLF + + CRLF + + "if the PVSystem/Storage terminal voltage has been increasing, and has not changed directions, utilize vvc_curve1 for the volt-var response. " + + CRLF + + CRLF + + "if the PVSystem/Storage terminal voltage has been increasing and changes directions and begins to decrease, then move from utilizing vvc_curve1 to a volt-var curve of the same shape, but offset by a certain per-unit voltage value. " + + CRLF + + CRLF + + "Maintain the same per-unit available var output level (unless head-room has changed due to change in active power or kva rating of PVSystem/Storage). Per-unit var values remain the same for this internally constructed second curve (hysteresis curve). " + + CRLF + + CRLF + + "if the terminal voltage has been decreasing and changes directions and begins to increase , then move from utilizing the offset curve, back to the vvc_curve1 for volt-var response, but stay at the same per-unit available vars output level."; + PropertyHelp[5] = String("Required for VOLTVAR and VOLTWATT modes, and defaults to rated. Possible values are: {rated|avg|ravg}. ") + CRLF + + CRLF + + "Defines whether the x-axis values (voltage in per unit) for vvc_curve1 and the volt-watt curve corresponds to:" + + CRLF + + CRLF + + "rated. The rated voltage for the PVSystem/Storage object (1.0 in the volt-var curve equals rated voltage)." + + CRLF + + CRLF + + "avg. The average terminal voltage recorded over a certain number of prior power-flow solutions." + + CRLF + + "with the avg setting, 1.0 per unit on the x-axis of the volt-var curve(s) corresponds to the average voltage." + + CRLF + + "from a certain number of prior intervals. See avgwindowlen parameter." + + CRLF + + CRLF + + "ravg. Same as avg, with the exception that the avgerage terminal voltage is divided by the rated voltage."; + PropertyHelp[6] = String("Required for VOLTVAR mode and VOLTWATT mode, and defaults to 0 seconds (0s). ") + CRLF + + CRLF + + "Sets the length of the averaging window over which the average PVSystem/Storage terminal voltage is calculated. " + + CRLF + + CRLF + + "Units are indicated by appending s, m, or h to the integer value. " + + CRLF + + CRLF + + "The averaging window will calculate the average PVSystem/Storage terminal voltage over the specified period of time, up to and including the last power flow solution. " + + CRLF + + CRLF + + "Note, if the solution stepsize is larger than the window length, then the voltage will be assumed to have been constant over the time-frame specified by the window length."; + PropertyHelp[7] = String("Required for VOLTWATT mode. ") + CRLF + + CRLF + + "Name of the XYCurve object containing the volt-watt curve. " + + CRLF + + CRLF + + "Units for the x-axis are per-unit voltage, which may be in per unit of the rated voltage for the PVSystem/Storage, or may be in per unit of the average voltage at the terminals over a user-defined number of prior solutions. " + + CRLF + + CRLF + + "Units for the y-axis are either in one of the options described in the VoltwattYAxis property. "; + PropertyHelp[8] = String("Required for the dynamic reactive current mode (DYNAMICREACCURR), and defaults to 0.95 per-unit voltage (referenced to the PVSystem/Storage object rated voltage or a windowed average value). ") + CRLF + + CRLF + + "This parameter is the minimum voltage that defines the voltage dead-band within which no reactive power is allowed to be generated. "; + PropertyHelp[9] = String("Required for the dynamic reactive current mode (DYNAMICREACCURR), and defaults to 1.05 per-unit voltage (referenced to the PVSystem object rated voltage or a windowed average value). ") + CRLF + + CRLF + + "This parameter is the maximum voltage that defines the voltage dead-band within which no reactive power is allowed to be generated. "; + PropertyHelp[10] = String("Required for the dynamic reactive current mode (DYNAMICREACCURR), and defaults to 0.1 ") + CRLF + + CRLF + + "This is a gradient, expressed in unit-less terms of %/%, to establish the ratio by which percentage capacitive reactive power production is increased as the percent delta-voltage decreases below DbVMin. " + + CRLF + + CRLF + + "Percent delta-voltage is defined as the present PVSystem/Storage terminal voltage minus the moving average voltage, expressed as a percentage of the rated voltage for the PVSystem/Storage object. " + + CRLF + + CRLF + + "Note, the moving average voltage for the dynamic reactive current mode is different than the moving average voltage for the volt-watt and volt-var modes."; + PropertyHelp[11] = String("Required for the dynamic reactive current mode (DYNAMICREACCURR), and defaults to 0.1 ") + CRLF + + CRLF + + "This is a gradient, expressed in unit-less terms of %/%, to establish the ratio by which percentage inductive reactive power production is increased as the percent delta-voltage decreases above DbVMax. " + + CRLF + + CRLF + + "Percent delta-voltage is defined as the present PVSystem/Storage terminal voltage minus the moving average voltage, expressed as a percentage of the rated voltage for the PVSystem/Storage object. " + + CRLF + + CRLF + + "Note, the moving average voltage for the dynamic reactive current mode is different than the mmoving average voltage for the volt-watt and volt-var modes."; + PropertyHelp[12] = String("Required for the dynamic reactive current mode (DYNAMICREACCURR), and defaults to 1 seconds (1s). do not use a value smaller than 1.0 ") + CRLF + + CRLF + + "Sets the length of the averaging window over which the average PVSystem/Storage terminal voltage is calculated " + + "for the dynamic reactive current mode. " + + CRLF + + CRLF + + "Units are indicated by appending s, m, or h to the integer value. " + + CRLF + + CRLF + + "Typically this will be a shorter averaging window than the volt-var and volt-watt averaging window." + + CRLF + + CRLF + + "The averaging window will calculate the average PVSystem/Storage terminal voltage over the specified period of time, up to and including the last power flow solution. Note, if the solution stepsize is larger than " + + "the window length, then the voltage will be assumed to have been constant over the time-frame specified by the window length."; + PropertyHelp[13] = String("Required for the VOLTVAR and DYNAMICREACCURR modes. Defaults to -1.0. ") + CRLF + + CRLF + + "Defining -1.0, OpenDSS takes care internally of delta_Q itself. It tries to improve convergence as well as speed up process" + + CRLF + + CRLF + + "Sets the maximum change (in per unit) from the prior var output level to the desired var output level during each control iteration. " + + CRLF + + CRLF + + CRLF + + "if numerical instability is noticed in solutions such as var sign changing from one control iteration to the next and voltages oscillating between two values with some separation, " + + "this is an indication of numerical instability (use the EventLog to diagnose). " + + CRLF + + CRLF + + "if the maximum control iterations are exceeded, and no numerical instability is seen in the EventLog of via monitors, then try increasing the value of this parameter to reduce the number " + + "of control iterations needed to achieve the control criteria, and move to the power flow solution."; + PropertyHelp[14] = String("Defaults to 0.0001 per-unit voltage. This parameter should only be modified by advanced users of the InvControl. ") + CRLF + + CRLF + + "Tolerance in pu of the control loop convergence associated to the monitored voltage in pu. " + + "This value is compared with the difference of the monitored voltage in pu of the current and previous control iterations of the control loop" + + CRLF + + CRLF + + "This voltage tolerance value plus the var/watt tolerance value (VarChangeTolerance/ActivePChangeTolerance) determine, together, when to stop control iterations by the InvControl. " + + CRLF + + CRLF + + "If an InvControl is controlling more than one PVSystem/Storage, each PVSystem/Storage has this quantity calculated independently, and so an individual " + + "PVSystem/Storage may reach the tolerance within different numbers of control iterations."; + PropertyHelp[15] = String("Required for VOLTVAR and DYNAMICREACCURR modes. Defaults to 0.025 per unit of the base provided or absorbed reactive power described in the RefReactivePower property " "This parameter should only be modified by advanced users of the InvControl. ") + CRLF + + CRLF + + "Tolerance in pu of the convergence of the control loop associated with reactive power. " + + "For the same control iteration, this value is compared to the difference, as an absolute value (without sign), between the desired reactive power value in pu and the output reactive power in pu of the controlled element." + + CRLF + + CRLF + + "This reactive power tolerance value plus the voltage tolerance value (VoltageChangeTolerance) determine, together, when to stop control iterations by the InvControl. " + + CRLF + + CRLF + + "If an InvControl is controlling more than one PVSystem/Storage, each PVSystem/Storage has this quantity calculated independently, and so an individual " + + "PVSystem/Storage may reach the tolerance within different numbers of control iterations."; + PropertyHelp[16] = String("Required for VOLTWATT mode. Must be one of: {PMPPPU* | PAVAILABLEPU| PCTPMPPPU | KVARATINGPU}. The default is PMPPPU. ") + CRLF + + CRLF + + "Units for the y-axis of the volt-watt curve while in volt-watt mode. " + + CRLF + + CRLF + + "When set to PMPPPU. The y-axis corresponds to the value in pu of Get_FPmpp() property of the PVSystem. " + + CRLF + + CRLF + + "When set to PAVAILABLEPU. The y-axis corresponds to the value in pu of the available active power of the PVSystem. " + + CRLF + + CRLF + + "When set to PCTPMPPPU. The y-axis corresponds to the value in pu of the power Pmpp multiplied by 1/100 of the %Get_FPmpp() property of the PVSystem." + + CRLF + + CRLF + + "When set to KVARATINGPU. The y-axis corresponds to the value in pu of the kVA property of the PVSystem."; + PropertyHelp[17] = String("Required for VOLTWATT and VOLTVAR mode. Must be one of: {INACTIVE* | LPF | RISEFALL }. The default is INACTIVE. ") + CRLF + + CRLF + + "Auxiliary option that aims to limit the changes of the desired reactive power and the active power limit between time steps, the alternatives are listed below: " + + CRLF + + CRLF + + "INACTIVE. It indicates there is no limit on rate of change imposed for either active or reactive power output. " + + CRLF + + CRLF + + "LPF. A low-pass RC filter is applied to the desired reactive power and/or the active power limit to determine the output power as a function of a time constant defined in the LPFTau property. " + + CRLF + + CRLF + + "RISEFALL. A rise and fall limit in the change of active and/or reactive power expressed in terms of pu power per second, defined in the RiseFallLimit, is applied to the desired reactive power and/or the active power limit. "; + PropertyHelp[18] = String("Not required. Defaults to 0 seconds. ") + CRLF + + CRLF + + "Filter time constant of the LPF option of the RateofChangeMode property. " + + "The time constant will cause the low-pass filter to achieve 95% of the target value in 3 time constants."; + PropertyHelp[19] = String("Not required. Defaults to no limit (-1). Must be -1 (no limit) or a positive value. ") + CRLF + + CRLF + + "Limit in power in pu per second used by the RISEFALL option of the RateofChangeMode property." + + "The base value for this ramp is defined in the RefReactivePower property and/or in VoltwattYAxis."; + PropertyHelp[20] = String("Required for the VOLTWATT modes. Defaults to -1.0. ") + CRLF + + CRLF + + "Defining -1.0, OpenDSS takes care internally of delta_P itself. It tries to improve convergence as well as speed up process" + + CRLF + + CRLF + + "Defining between 0.05 and 1.0, it sets the maximum change (in unit of the y-axis) from the prior active power output level to the desired active power output level during each control iteration. " + + CRLF + + CRLF + + CRLF + + "If numerical instability is noticed in solutions such as active power changing substantially from one control iteration to the next and/or voltages oscillating between two values with some separation, " + + "this is an indication of numerical instability (use the EventLog to diagnose). " + + CRLF + + CRLF + + "If the maximum control iterations are exceeded, and no numerical instability is seen in the EventLog of via monitors, then try increasing the value of this parameter to reduce the number " + + "of control iterations needed to achieve the control criteria, and move to the power flow solution."; + PropertyHelp[21] = "{Yes/True* | No/False} Default is YES for InvControl. Log control actions to Eventlog."; + PropertyHelp[22] = String("Required for any mode that has VOLTVAR, DYNAMICREACCURR and WATTVAR. Defaults to VARAVAL.") + CRLF + + CRLF + + "Defines the base reactive power for both the provided and absorbed reactive power, according to one of the following options: " + + CRLF + + CRLF + + "VARAVAL. The base values for the provided and absorbed reactive power are equal to the available reactive power." + + CRLF + + CRLF + + "VARMAX: The base values of the provided and absorbed reactive power are equal to the value defined in the kvarMax and kvarMaxAbs properties, respectively."; + PropertyHelp[23] = String("Required for VOLTWATT. Default is 0.01") + CRLF + + CRLF + + "Tolerance in pu of the convergence of the control loop associated with active power. " + + "For the same control iteration, this value is compared to the difference between the active power limit in pu resulted from the convergence process and the one resulted from the volt-watt function." + + CRLF + + CRLF + + "This reactive power tolerance value plus the voltage tolerance value (VoltageChangeTolerance) determine, together, when to stop control iterations by the InvControl. " + + CRLF + + CRLF + + "If an InvControl is controlling more than one PVSystem/Storage, each PVSystem/Storage has this quantity calculated independently, and so an individual " + + "PVSystem/Storage may reach the tolerance within different numbers of control iterations."; + PropertyHelp[24] = "Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=AVG. "; + PropertyHelp[25] = "Name of monitored bus used by the voltage-dependente control modes. Default is bus of the controlled PVSystem/Storage or Storage."; + PropertyHelp[26] = "Array list of rated voltages of the buses and their nodes presented in the monBus property. This list may have different line-to-line and/or line-to-ground voltages."; + PropertyHelp[27] = String("Required for VOLTWATT mode for Storage element in CHARGING state. ") + CRLF + + CRLF + + "The name of an XYCurve object that describes the variation in active power output (in per unit of maximum active power outut for the Storage). " + + CRLF + + CRLF + + "Units for the x-axis are per-unit voltage, which may be in per unit of the rated voltage for the Storage, or may be in per unit of the average voltage at the terminals over a user-defined number of prior solutions. " + + CRLF + + CRLF + + "Units for the y-axis are either in: (1) per unit of maximum active power output capability of the Storage, or (2) maximum available active power output capability (defined by the parameter: VoltwattYAxis), " + + "corresponding to the terminal voltage (x-axis value in per unit). " + + CRLF + + CRLF + + "No default -- must be specified for VOLTWATT mode for Storage element in CHARGING state."; + PropertyHelp[28] = String("Required for WATTPF mode.") + CRLF + + CRLF + + "Name of the XYCurve object containing the watt-pf curve." + + CRLF + + "The positive values of the y-axis are positive power factor values. " + + "The negative values of the the y-axis are negative power factor values. " + + "When positive, the output reactive power has the same direction of the output active power, and when negative, it has the opposite direction." + + CRLF + + "Units for the x-axis are per-unit output active power, and the base active power is the Get_FPmpp() for PVSystem and kWrated for Storage." + + CRLF + + CRLF + + "The y-axis represents the power factor and the reference is power factor equal to 0. " + + CRLF + + CRLF + + "For example, if the user wants to define the following XY coordinates: (0, 0.9); (0.2, 0.9); (0.5, -0.9); (1, -0.9)." + + CRLF + + "Try to plot them considering the y-axis reference equal to unity power factor." + + CRLF + + CRLF + + "The user needs to translate this curve into a plot in which the y-axis reference is equal to 0 power factor." + + "It means that two new XY coordinates need to be included, in this case they are: (0.35, 1); (0.35, -1)." + + CRLF + + "Try to plot them considering the y-axis reference equal to 0 power factor." + + CRLF + + "The discontinity in 0.35pu is not a problem since var is zero for either power factor equal to 1 or -1."; + PropertyHelp[29] = String("Required for WATTVAR mode. ") + CRLF + + CRLF + + "Name of the XYCurve object containing the watt-var curve. The positive values of the y-axis of the watt-var curve represent values in pu of the provided base reactive power. " + + "The negative values of the y-axis are values in pu of the absorbed base reactive power. " + + CRLF + + "Provided and absorbed base reactive power values are defined in the RefReactivePower property." + + CRLF + + CRLF + + "Units for the x-axis are per-unit output active power, and the base active power is the Pmpp for PVSystem and kWrated for Storage."; + PropertyHelp[30] = "Deprecated, use RefReactivePower instead."; + PropertyHelp[31] = "Deprecated, use DERList instead."; + PropertyHelp[32] = "Required for Active Voltage Regulation (AVR)."; + PropertyHelp[33] = "Integer defining the method for moving across the control curve.It can be one of the following : " + CRLF + CRLF + + "0 = Linear mode (default)" + CRLF + + "1 = Exponential" + CRLF + CRLF + + "Use this property for better tunning your controllerand improve the controller response in terms of control iterations needed to reach the target." + CRLF + + "This property alters the meaning of deltaQ_factor and deltaP_factor properties accroding to its value(Check help).The method can also be combined with the controller tolerance for improving performance."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +int TInvControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new InvControl and add it to InvControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TInvControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +int TInvControl::Edit(int ActorID) +{ + int result = 0, + CharPos = 0, + ParamPointer = 0, + i = 0, + j = 0, + NNode = 0; + String StrTemp, + ParamName, + Param; + + int NodeBuffer[11/*# range 1..10*/]; + + // continue parsing with contents of Parser + ActiveInvControlObj = (TInvControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveInvControlObj); + result = 0; + /*# with ActiveInvControlObj do */ + { + auto with0 = ActiveInvControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 364); + break; + case 1: + InterpretTStringListArray(Param, (with0->FDERNameList)); + break; // Read list of PVSystem and Storage objects in OpenDSS format and add to FDERNameList StringList. + case 2: + { + StrTemp = Parser[ActorID]->MakeString_(); + j = 0; + for (i = 0; i < myCtrlMode->size(); i++) + { + if (CompareTextShortest(StrTemp, myCtrlMode[i]) == 0) + { + with0->ControlMode = i + 1; + with0->CombiControlMode = NONE_COMBMODE; + j = 1; + break; + } + } + if (j == 0) + { + if (with0->ControlMode == NONE_MODE) + DoSimpleMsg("Invalid Control Mode selected", 1366); + with0->CombiControlMode = NONE_COMBMODE; + SolutionAbort = true; + return result; + } + + } + break; + case 3: + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "vv_vw") == 0) + { + with0->ControlMode = NONE_MODE; + with0->CombiControlMode = VV_VW; + } + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "vv_drc") == 0) + { + with0->ControlMode = NONE_MODE; + with0->CombiControlMode = VV_DRC; + } + else + { + if(with0->CombiControlMode == NONE_COMBMODE) + DoSimpleMsg("Invalid CombiControl Mode selected", 1367); + with0->CombiControlMode = NONE_COMBMODE; + SolutionAbort = true; + return result; + } + } + } + break; + case 4: + { + with0->Fvvc_curvename = Parser[ActorID]->MakeString_(); + if(with0->Fvvc_curvename.size() > 0) + { + with0->Fvvc_curve = GetXYCurve(with0->Fvvc_curvename, VOLTVAR); + with0->Fvvc_curve_size = with0->Fvvc_curve->get_FNumPoints(); + } + } + break; + case 5: + { + if(Parser[ActorID]->MakeDouble_() > 0.0) + DoSimpleMsg(String("Hysteresis offset should be a negative value, or 0 \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 1364); + else + with0->Fvvc_curveOffset = Parser[ActorID]->MakeDouble_(); + } + break; + case 6: + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "rated") == 0) + with0->FVoltage_CurveX_ref = 0; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "avg") == 0) + with0->FVoltage_CurveX_ref = 1; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "ravg") == 0) + with0->FVoltage_CurveX_ref = 2; + } + } + } + break; + case 7: + with0->FRollAvgWindowLength = with0->InterpretAvgVWindowLen(Param); + break; + case 8: + { + with0->Fvoltwatt_curvename = Parser[ActorID]->MakeString_(); + if(with0->Fvoltwatt_curvename.size() > 0) + { + with0->Fvoltwatt_curve = GetXYCurve(with0->Fvoltwatt_curvename, VOLTWATT); + with0->Fvoltwatt_curve_size = with0->Fvoltwatt_curve->get_FNumPoints(); + } + } + break; + case 9: + { + with0->FDbVMin = Parser[ActorID]->MakeDouble_(); + if((with0->FDbVMax > 0.0) && (with0->FDbVMin > with0->FDbVMax)) + { + DoSimpleMsg(String("Minimum dead-band voltage value should be less than the maximum dead-band voltage value. Value set to 0.0 \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 1365); + with0->FDbVMin = 0.0; + } + } + break; + case 10: + { + with0->FDbVMax = Parser[ActorID]->MakeDouble_(); + if((with0->FDbVMin > 0.0) && (with0->FDbVMax < with0->FDbVMin)) + { + DoSimpleMsg(String("Maximum dead-band voltage value should be greater than the minimum dead-band voltage value. Value set to 0.0 \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 1366); + with0->FDbVMax = 0.0; + } + } + break; + case 11: + with0->FArGraLowV = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FArGraHiV = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->FDRCRollAvgWindowLength = with0->InterpretDRCAvgVWindowLen(Param); + break; + case 14: + with0->FdeltaQ_factor = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->FVoltageChangeTolerance = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->FVarChangeTolerance = Parser[ActorID]->MakeDouble_(); + break; + case 17: + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "pavailablepu") == 0) + with0->FVoltwattYAxis = 0; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "pmpppu") == 0) + with0->FVoltwattYAxis = 1; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "pctpmpppu") == 0) + with0->FVoltwattYAxis = 2; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "kvaratingpu") == 0) + with0->FVoltwattYAxis = 3; + } + } + } + } + break; + case 18: + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "inactive") == 0) + with0->RateofChangeMode = Inactive; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "lpf") == 0) + with0->RateofChangeMode = LPF; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "risefall") == 0) + with0->RateofChangeMode = RISEFALL; + } + } + } + break; + case 19: + { + if(Parser[ActorID]->MakeDouble_() > 0) + with0->FLPFTau = Parser[ActorID]->MakeDouble_(); + else + with0->RateofChangeMode = Inactive; + } + break; + case 20: + { + if(Parser[ActorID]->MakeDouble_() > 0) + with0->FRiseFallLimit = Parser[ActorID]->MakeDouble_(); + else + with0->RateofChangeMode = Inactive; + } + break; + case 21: + with0->FdeltaP_factor = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->ShowEventLog = InterpretYesNo(Param); + break; + case 23: + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "varaval") == 0) + with0->FReacPower_ref = "VARAVAL"; + else + { + if(CompareTextShortest(Parser[ActorID]->MakeString_(), "varmax") == 0) + with0->FReacPower_ref = "VARMAX"; + } + } + break; + case 24: + with0->FActivePChangeTolerance = Parser[ActorID]->MakeDouble_(); + break; + case 25: + { + if(CompareTextShortest(Param, "avg") == 0) + with0->FMonBusesPhase = AVGPHASES; + else + { + if(CompareTextShortest(Param, "max") == 0) + with0->FMonBusesPhase = MAXPHASE; + else + { + if(CompareTextShortest(Param, "min") == 0) + with0->FMonBusesPhase = MINPHASE; + else + with0->FMonBusesPhase = max(1, Parser[ActorID]->MakeInteger_()); + } + } + } + break; //FMonBuses := Param; + case 26: + { + int stop = 0; + InterpretTStringListArray(Param, ( with0->FMonBusesNameList ) ); + with0->FMonBuses.resize( with0->FMonBusesNameList.size() ); + with0->FMonBusesNodes.resize( with0->FMonBusesNameList.size() ); + AuxParser[ActiveActor]->SetCmdString(Param); //Parser[ActorID].MakeString_(); // load AuxParser + for(stop = with0->FMonBusesNameList.size() - 1, i = 0; i <= stop; i++) + { + int stop1 = 0; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // Gets the next token + with0->FMonBuses[i] = AuxParser[ActiveActor]->ParseAsBusName(NNode, (pIntegerArray) &NodeBuffer, ActiveActor); + with0->FMonBusesNodes[i].resize( NNode ); + for(stop1 = NNode - 1, j = 0; j <= stop1; j++) + { + with0->FMonBusesNodes[i][j] = NodeBuffer[j]; + } + } + } + break; + case 27: + { + with0->FMonBusesVbase.resize( with0->FMonBusesNameList.size() ); + Parser[ActiveActor]->ParseAsVector(with0->FMonBusesNameList.size(), &(with0->FMonBusesVbase[0]) ); + } + break; + case 28: + { + with0->FvoltwattCH_curvename = Parser[ActorID]->MakeString_(); + if(with0->FvoltwattCH_curvename.size() > 0) + { + with0->FvoltwattCH_curve = GetXYCurve(with0->FvoltwattCH_curvename, VOLTWATT); + with0->FvoltwattCH_curve_size = with0->FvoltwattCH_curve->get_FNumPoints(); + } + } + break; + case 29: + { + with0->Fwattpf_curvename = Parser[ActorID]->MakeString_(); + if(with0->Fwattpf_curvename.size() > 0) + { + with0->Fwattpf_curve = GetXYCurve(with0->Fwattpf_curvename, WATTPF); + with0->Fwattpf_curve_size = with0->Fwattpf_curve->get_FNumPoints(); + } + } + break; + case 30: + { + with0->Fwattvar_curvename = Parser[ActorID]->MakeString_(); + if(with0->Fwattvar_curvename.size() > 0) + { + with0->Fwattvar_curve = GetXYCurve(with0->Fwattvar_curvename, WATTVAR); + with0->Fwattvar_curve_size = with0->Fwattvar_curve->get_FNumPoints(); + } + } + break; + case 31: + { + StrTemp = Parser[ActorID]->MakeString_(); + CharPos = AnsiPos("_", StrTemp); + if(CharPos != 0) + StrTemp = StrTemp.substr(0, CharPos - 1); + if(CompareTextShortest(StrTemp, "varaval") == 0) + with0->FReacPower_ref = "VARAVAL"; + else + { + if(CompareTextShortest(StrTemp, "varmax") == 0) + with0->FReacPower_ref = "VARMAX"; + } + } + break; + case 32: + { + int stop = 0; + InterpretTStringListArray(Param, ( with0->FDERNameList ) ); // Read list of PVSystem and Storage objects in OpenDSS format and add to FDERNameList StringList. + // Because is using this command from the previous version of InvControl, we assume that the list includes only + // PVSystems, so the list is updated + for(stop = (with0->FDERNameList.size() - 1), CharPos = 0; CharPos <= stop; CharPos++) + { + ( with0->FDERNameList )[CharPos] = String("PVSystem.") + ( with0->FDERNameList )[CharPos]; + } + } + break; + case 33: + with0->Fv_setpoint = Parser[ActorID]->MakeDouble_(); + break; + case 34: + with0->CtrlModel = Parser[ActorID]->MakeInteger_(); + break; + // Inherited parameters + default: + ClassEdit(ActiveInvControlObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: // re-alloc based on + { + with0->FDERPointerList->Clear(); + with0->FListSize = with0->FDERNameList.size(); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +int TInvControl::MakeLike(const String InvControlName) +{ + int result = 0; + TInvControlObj* OtherInvControl = nullptr; + int i = 0; + int j = 0; + result = 0; + /*See if we can find this InvControl name in the present collection*/ + OtherInvControl = ((TInvControlObj*) Find(InvControlName)); + if(OtherInvControl != nullptr) + /*# with ActiveInvControlObj do */ + { + auto with0 = ActiveInvControlObj; + int stop = 0; + with0->Set_NPhases(OtherInvControl->Fnphases); + with0->Set_Nconds(OtherInvControl->Fnconds); // Force Reallocation of terminal stuff + for(stop = with0->FDERPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + auto& with1 = with0->CtrlVars[i]; + with1.ControlledElement = OtherInvControl->CtrlVars[i].ControlledElement; + with1.CondOffset = OtherInvControl->CtrlVars[i].CondOffset; + with1.FVBase = OtherInvControl->CtrlVars[i].FVBase; + with1.FVarFollowInverter = OtherInvControl->CtrlVars[i].FVarFollowInverter; + with1.FInverterON = OtherInvControl->CtrlVars[i].FInverterON; + with1.FpresentkW = OtherInvControl->CtrlVars[i].FpresentkW; + with1.FkVArating = OtherInvControl->CtrlVars[i].FkVArating; + with1.Fpresentkvar = OtherInvControl->CtrlVars[i].Fpresentkvar; + with1.Fkvarlimit = OtherInvControl->CtrlVars[i].Fkvarlimit; + with1.FkvarLimitNeg = OtherInvControl->CtrlVars[i].FkvarLimitNeg; + with1.FCurrentkvarLimit = OtherInvControl->CtrlVars[i].FCurrentkvarLimit; + with1.FCurrentkvarLimitNeg = OtherInvControl->CtrlVars[i].FCurrentkvarLimitNeg; + with1.FDCkWRated = OtherInvControl->CtrlVars[i].FDCkWRated; + with1.FpctDCkWRated = OtherInvControl->CtrlVars[i].FpctDCkWRated; + with1.FEffFactor = OtherInvControl->CtrlVars[i].FEffFactor; + with1.FDCkW = OtherInvControl->CtrlVars[i].FDCkW; + with1.FPPriority = OtherInvControl->CtrlVars[i].FPPriority; + with1.FActiveVVCurve = OtherInvControl->CtrlVars[i].FActiveVVCurve; + } + with0->ControlMode = OtherInvControl->ControlMode; + with0->CombiControlMode = OtherInvControl->CombiControlMode; + with0->FListSize = OtherInvControl->FListSize; + with0->Fvvc_curve_size = OtherInvControl->Fvvc_curve_size; + with0->Fvvc_curve = OtherInvControl->Fvvc_curve; + with0->Fvvc_curvename = OtherInvControl->Fvvc_curvename; + with0->Fvvc_curveOffset = OtherInvControl->Fvvc_curveOffset; + with0->FVoltage_CurveX_ref = OtherInvControl->FVoltage_CurveX_ref; + with0->FDRCVAvgWindowLengthSec = OtherInvControl->FDRCVAvgWindowLengthSec; + with0->FVAvgWindowLengthSec = OtherInvControl->FVAvgWindowLengthSec; + with0->Fvoltwatt_curve_size = OtherInvControl->Fvoltwatt_curve_size; + with0->Fvoltwatt_curve = OtherInvControl->Fvoltwatt_curve; + with0->Fvoltwatt_curvename = OtherInvControl->Fvoltwatt_curvename; + with0->FvoltwattCH_curve_size = OtherInvControl->FvoltwattCH_curve_size; + with0->FvoltwattCH_curve = OtherInvControl->FvoltwattCH_curve; + with0->FvoltwattCH_curvename = OtherInvControl->FvoltwattCH_curvename; + with0->Fwattpf_curve_size = OtherInvControl->Fwattpf_curve_size; + with0->Fwattpf_curve = OtherInvControl->Fwattpf_curve; + with0->Fwattpf_curvename = OtherInvControl->Fwattpf_curvename; + with0->Fwattvar_curve_size = OtherInvControl->Fwattvar_curve_size; + with0->Fwattvar_curve = OtherInvControl->Fwattvar_curve; + with0->Fwattvar_curvename = OtherInvControl->Fwattvar_curvename; + with0->FDbVMin = OtherInvControl->FDbVMin; + with0->pf_wp_nominal = OtherInvControl->pf_wp_nominal; + with0->FDbVMax = OtherInvControl->FDbVMax; + with0->FArGraLowV = OtherInvControl->FArGraLowV; + with0->FArGraHiV = OtherInvControl->FArGraHiV; + with0->FRollAvgWindowLength = OtherInvControl->FRollAvgWindowLength; + with0->FRollAvgWindowLengthIntervalUnit = OtherInvControl->FRollAvgWindowLengthIntervalUnit; + with0->FDRCRollAvgWindowLength = OtherInvControl->FDRCRollAvgWindowLength; + with0->FDRCRollAvgWindowLengthIntervalUnit = OtherInvControl->FDRCRollAvgWindowLengthIntervalUnit; + with0->FActivePChangeTolerance = OtherInvControl->FActivePChangeTolerance; + with0->FdeltaQ_factor = OtherInvControl->FdeltaQ_factor; + with0->FdeltaP_factor = OtherInvControl->FdeltaP_factor; + with0->FVoltageChangeTolerance = OtherInvControl->FVoltageChangeTolerance; + with0->FVarChangeTolerance = OtherInvControl->FVarChangeTolerance; + with0->FVoltwattYAxis = OtherInvControl->FVoltwattYAxis; + with0->RateofChangeMode = OtherInvControl->RateofChangeMode; + with0->FLPFTau = OtherInvControl->FLPFTau; + with0->FRiseFallLimit = OtherInvControl->FRiseFallLimit; + with0->FMonBusesPhase = OtherInvControl->FMonBusesPhase; + with0->FMonBuses = OtherInvControl->FMonBuses; + with0->FMonBusesNodes = OtherInvControl->FMonBusesNodes; + with0->FMonBusesVbase.resize( with0->FMonBusesNameList.size() ); + for(stop = with0->FMonBusesNameList.size(), j = 1; j <= stop; j++) + { + (with0->FMonBusesVbase)[j - 1] = (OtherInvControl->FMonBusesVbase)[j - 1]; + } + with0->TimeDelay = OtherInvControl->TimeDelay; + for(stop = with0->ParentClass->NumProperties, j = 1; j <= stop; j++) + { + with0->Set_PropertyValue(j, OtherInvControl->Get_PropertyValue(j)); + } + } + else + DoSimpleMsg(String("Error in InvControl MakeLike: \"") + InvControlName + + "\" Not Found.", 370); + return result; +} + +/*==========================================================================*/ +/* TInvControlObj */ +/*==========================================================================*/ + +TInvControlObj::TInvControlObj(TDSSClass* ParClass, const String InvControlName) + : inherited(ParClass) +{ + Set_Name(LowerCase(InvControlName)); + DSSObjType = ParClass->DSSClassType; + ElementName = ""; + FDERNameList.clear(); + FMonBusesNameList.clear(); + FListSize = 0; + /* + Control elements are zero current sources that attach to a terminal of a + power-carrying device, but do not alter voltage or current flow. + Define a default number of phases and conductors here and update in + RecalcElementData routine if necessary. This allocates arrays for voltages + and currents and gives more direct access to the values,if needed + */ + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementTerminal = 1; + + /*Variables for voltages*/ + FVpuSolutionIdx = 0; + /*Variables for convergence process*/ + FdeltaQ_factor = FLAGDELTAQ; + FdeltaP_factor = FLAGDELTAP; + FVoltageChangeTolerance = 0.0001; + FVarChangeTolerance = 0.025; + FActivePChangeTolerance = 0.01; + + /*Variables of DER element*/ + FDERNameList.clear(); + FDERPointerList = NULL; + FDERPointerList = new TPointerList(20); // Default size and increment + + /*Variables for monitored Bus/buses*/ + FMonBusesNameList.clear(); + FMonBusesPhase = AVGPHASES; + FMonBuses.clear(); + FMonBusesVbase.clear(); + FMonBusesNodes.clear(); + + /*Variables for LPF and RF options*/ + RateofChangeMode = Inactive; + FLPFTau = 0.001; + FRiseFallLimit = 0.001; + + /*Variables of the smart inverter functions*/ + FVoltage_CurveX_ref = 0; + FReacPower_ref = "VARAVAL"; + FVoltwattYAxis = 1; + + // volt-var + Fvvc_curve_size = 0; + Fvvc_curve = nullptr; + Fvvc_curvename = ""; + Fvvc_curveOffset = 0.0; + Fvvc_curve2 = nullptr; + FVAvgWindowLengthSec = 1.0; + FRollAvgWindowLength = 1; + FRollAvgWindowLengthIntervalUnit = "s"; + + // watt-pf + Fwattpf_curve_size = 0; + Fwattpf_curve = nullptr; + Fwattpf_curvename = ""; + pf_wp_nominal = 0.0; + + // watt-var + Fwattvar_curve_size = 0; + Fwattvar_curve = nullptr; + Fwattvar_curvename = ""; + + // DRC + FDbVMin = 0.95; + FDbVMax = 1.05; + FArGraLowV = 0.1; + FArGraHiV = 0.1; + FDRCRollAvgWindowLength = 1; + FDRCRollAvgWindowLengthIntervalUnit = "s"; + FDRCVAvgWindowLengthSec = 1.0; + + // volt-watt + Fvoltwatt_curve_size = 0; + Fvoltwatt_curve = nullptr; + Fvoltwatt_curvename = ""; + FvoltwattCH_curve_size = 0; + FvoltwattCH_curve = nullptr; + FvoltwattCH_curvename = ""; + + // AVR + Fv_setpoint = 1.0; + CtrlModel = 0; // Linear mode + InitPropertyValues(0); +} + +TInvControlObj::~TInvControlObj() +{ + ElementName = ""; + + FMonBuses.clear(); + FMonBusesNodes.clear(); + CtrlVars.resize(0); + if(!(FMonBusesVbase.empty())) + FMonBusesVbase.clear(); + // inherited::Destroy(); +} + + +void TInvControlObj::RecalcElementData(int ActorID) +{ + int i = 0; + int stop = 0; + if(FDERPointerList->get_myNumList() == 0) + MakeDERList(); + if(FDERPointerList->get_myNumList() > 0) + /*Setting the terminal of the InvControl device to same as the 1st PVSystem/Storage element*/ + /* This sets it to a realistic value to avoid crashes later */ + { + MonitoredElement = ((TDSSCktElement*) FDERPointerList->Get(1)); // Set MonitoredElement to 1st elemnent in list + SetBus(1, MonitoredElement->Get_FirstBus()); + } + for(stop = FDERPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + auto& with1 = CtrlVars[i]; + // User (ControlledElement)[] as the pointer to the PVSystem/Storage elements + with1.ControlledElement = (TPCElement*) FDERPointerList->Get(i); // pointer to i-th PVSystem/Storage element + with1.cBuffer.resize( ( (TDSSCktElement*) with1.ControlledElement )->Yorder + 1 ); + ( (TDSSCktElement*) with1.ControlledElement )->Set_ActiveTerminal(1); // Make the 1 st terminal active + Set_NPhases(((TDSSCktElement*)(with1.ControlledElement))->Get_NPhases()); + Set_Nconds(Get_NPhases()); + with1.FRollAvgWindow->Set_BuffLength(FRollAvgWindowLength); // TEMc + with1.FDRCRollAvgWindow->Set_BuffLength(FDRCRollAvgWindowLength); + + // for all modes other than VW and WATTPF, PF priority is not allowed + if(( ControlMode != VOLTWATT) && (ControlMode != WATTPF)) + { + if(((TNamedObject*)(with1.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*) (with1.ControlledElement))->PVSystemVars.PF_Priority = false; + else + { + if(((TNamedObject*)(with1.ControlledElement))->Get_myPName() == myDERTypes[EStorage]) + ((TStorageObj*) (with1.ControlledElement))->StorageVars.PF_Priority = false; + } + } + + //FdeltaQFactor[i] := FdeltaQ_factor; + //FdeltaPFactor[i] := FdeltaP_factor; + if(FMonBuses.size() == 0) + FUsingMonBuses = false; + else + FUsingMonBuses = true; + if(ASSIGNED(with1.ControlledElement)) + UpdateDERParameters(i); + else + { + (with1.ControlledElement) = nullptr; + DoErrorMsg(String("InvControl: \"") + this->get_Name() + "\"", String("Controlled Element \"") + (FDERNameList)[i - 1] + + "\" Not Found.", " PVSystem or Storage object must be defined previously.", 361); + } + } +} + +// *** This assumes the PVSystem/Storage devices have already been converted to pos seq + +void TInvControlObj::MakePosSequence(int ActorID) +{ + if(FDERPointerList->get_myNumList() == 0) + RecalcElementData(ActorID); + Set_NPhases(3); + Set_Nconds(3); + SetBus(1, MonitoredElement->GetBus(ElementTerminal)); + if(FDERPointerList->get_myNumList() > 0) + /*Setting the terminal of the InvControl device to same as the 1st PVSystem/Storage element*/ + /* This sets it to a realistic value to avoid crashes later */ + { + MonitoredElement = ((TDSSCktElement*) FDERPointerList->Get(1)); // Set MonitoredElement to 1st PVSystem/Storage in list + SetBus(1, MonitoredElement->Get_FirstBus()); + Set_NPhases(MonitoredElement->Get_NPhases()); + Set_Nconds(Get_NPhases()); + } + inherited::MakePosSequence(ActorID); +} + +void TInvControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // if YPrim=nil then YPrim := TcMatrix.CreateMatrix(Yorder); +} + +void TInvControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + // Control is a zero current source + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TInvControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + // Control is a zero current source + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TInvControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +void TInvControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + int k = 0; + TPCElement* DERelem = nullptr; + int stop = 0; + for(stop = FDERPointerList->get_myNumList(), k = 1; k <= stop; k++) + { + auto& with0 = CtrlVars[k]; + DERelem = with0.ControlledElement; + + // Calculates QHeadRoom + Calc_QHeadRoom(k, ActorID); + if(with0.QHeadRoom != 0.0) + with0.FPriorvarspu = with0.FPriorvars / with0.QHeadRoom ; + + // Calculates PBase + Calc_PBase(k, ActorID); + with0.FPriorWattspu = with0.FPriorwatts / with0.PBase ; + + // Calculates kW_out_desiredpu. Used for VW and VV_VW + with0.kW_out_desiredpu = with0.kW_out_desired / with0.PBase ; + + // -------------------Smart Inverter Functions------------------------// + /*Smart Inverter volt-var function*/ + if ((ControlMode == VOLTVAR) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEVARLEVEL)) + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if( ( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*) DERelem)->Set_VVmode(true); + } + else + { + ((TStorageObj*) DERelem)->Set_VWmode(false); + ((TStorageObj*) DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*) DERelem)->Set_VVmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireVVpu[k] + CalcQVVcurve_desiredpu(k, ActorID); + + // LPF or RF activated + if(RateofChangeMode == LPF) + { + CalcLPF(k, "VARS", with0.QDesireVVpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + } + else + { + if(RateofChangeMode == RISEFALL) + { + CalcRF(k, "VARS", with0.QDesireVVpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign( with0.QDesireOptionpu ); + } + else + + // Checks kVA (watt priority) and kvarlimit limits + { + Check_Qlimits(k, with0.QDesireVVpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireVVpu ), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireVVpu ); + } + + // Calculates QDesiredVV[k] through the convergence algorithm + } + CalcVoltVar_vars(k, ActorID); + + //--------------------------------------------- end Main process ---------------------------------------------// + + // Sets PVSystem/Storage's kvar_out + if( ( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*)DERelem)->Set_Presentkvar(with0.QDesiredVV); + else + ((TStorageObj*) DERelem)->Set_kvarRequested(with0.QDesiredVV); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if( ( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredVV >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredVV >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputVVpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + + // Values used in CalcQVVcurve_desiredpu + if( ( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + ( ( (TNamedObject*) DERelem) )->Get_QualifiedName(), Format("VOLTVAR mode requested PVSystem output var level to**, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVV, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)DERelem)->Get_QualifiedName(), Format("VOLTVAR mode requested Storage output var level to **, kvar = %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVV, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + /*Smart Inverter active voltage regulation function*/ + } + else + { + if ((ControlMode == AVR) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEVARLEVEL)) + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if( ( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_AVRmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(false); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*)DERelem)->Set_AVRmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + if(ActiveCircuit[ActorID]->Solution->ControlIteration == 1) + { + with0.FAvgpVpuPrior = with0.FPresentVpu; + with0.FAvgpAVRVpuPrior = with0.FPresentVpu; + + // Sets PVSystem/Storage's kvar_out + if( ( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*) DERelem)->Set_Presentkvar(with0.QHeadRoom / 2); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QHeadRoom / 2); + } + else + { + if(ActiveCircuit[ActorID]->Solution->ControlIteration == 2) + // Sets PVSystem/Storage's kvar_out + { + if( ( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + with0.DQDV = Abs( (((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom / (with0.FPresentVpu - with0.FAvgpVpuPrior ))); + else + with0.DQDV = Abs( (double(((TStorageObj*) DERelem)->Get_kvarRequested()) / with0.QHeadRoom / (with0.FPresentVpu - with0.FAvgpVpuPrior ))); + } + else + + // Calculates QDesireAVRpu[k] + { + CalcQAVR_desiredpu(k, ActorID); + + + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireAVRpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireAVRpu ), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireAVRpu ); + if(Abs( (with0.QDesireEndpu - with0.QDesireLimitedpu )) < 0.05) + with0.Fv_setpointLimited = with0.FPresentVpu ; + else + with0.Fv_setpointLimited = Fv_setpoint; + + // Calculates QDesiredVV[k] through the convergence algorithm + CalcAVR_vars(k, ActorID); + + //--------------------------------------------- end Main process ---------------------------------------------// + + // Sets PVSystem/Storage's kvar_out + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*) DERelem)->Set_Presentkvar(with0.QDesiredAVR); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredAVR); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredAVR >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredAVR >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputAVRpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + + // Values used in CalcQVVcurve_desiredpu + if(( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldAVR = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + ( (TNamedObject*) DERelem)->Get_QualifiedName(), Format("VOLTVAR mode requested PVSystem output var level to**, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredAVR, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldAVR = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)DERelem)->Get_QualifiedName(), Format("VOLTVAR mode requested Storage output var level to **, kvar = %.5g. Actual output set to kvar= %.5g.", with0.QDesiredAVR, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + } + + /*Smart Inverter watt-pf function*/ + } + } + else + { + if ((ControlMode == WATTPF) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEVARLEVEL)) + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if(( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_WPmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(false); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*)DERelem)->Set_WPmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireWPpu[k] + CalcQWPcurve_desiredpu(k, ActorID); + + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireWPpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireWPpu ), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireWPpu ); + + // Calculates QDesiredWP[k] through the convergence algorithm + CalcWATTPF_vars(k, ActorID); + + //--------------------------------------------- end Main process ---------------------------------------------// + // Sets PVSystem/Storage's pf_wp_nominal + if(( (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*)DERelem)->Set_pf_wp_nominal(pf_wp_nominal); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredWP); + + // Sets PVSystem/Storage's kvar_out + if((with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*)DERelem)->Set_Presentkvar(with0.QDesiredWP); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredWP); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if((with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredWP >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredWP >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputVVpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + + // Values used in CalcQVVcurve_desiredpu + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("WATTPF mode requested PVSystem output var level to**, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredWP, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)DERelem)->Get_QualifiedName(), Format("WATTPF mode requested Storage output var level to **, kvar = %.5g. Actual output set to kvar= %.5g.", with0.QDesiredWP, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + /*Smart Inverter watt-var function*/ + } + else + { + if ((ControlMode == WATTVAR) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEVARLEVEL)) + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_WVmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(false); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*) DERelem)->Set_WVmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireWVpu[k] + CalcQWVcurve_desiredpu(k, ActorID); + + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits_WV(k, with0.QDesireWVpu, ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireWVpu), Abs(with0.QDesireLimitedpu)) * Sign(with0.QDesireWVpu); + + // It checks kVA or Q limits and makes sure the final P and Q stay in the watt-var curve (PauloRadatz - 2/16/2021) + Calc_PQ_WV(k, ActorID); + + //--------------------------------------------- end Main process ---------------------------------------------// + + // Sets PVSystem/Storage's kvar_out + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_Presentkvar(with0.QDesiredWV); + ((TPVsystemObj*)DERelem)->Set_PresentkW(with0.PLimitEndpu * min(with0.FkVArating, with0.FDCkWRated)); + } + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredWV); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredWV >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredWV >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputVVpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + + // Values used in CalcQVVcurve_desiredpu + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("WATTVAR mode requested PVSystem output var level to**, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredWV, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + DERelem->Get_QualifiedName(), Format("WATTVAR mode requested Storage output var level to **, kvar = %.5g. Actual output set to kvar= %.5g.", with0.QDesiredWV, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + /*Smart Inverter DRC function*/ + } + else + { + if ((ControlMode == DRC) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEVARLEVEL)) + + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_DRCmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(false); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*)DERelem)->Set_DRCmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireDRCpu[k] + CalcQDRC_desiredpu(k, ActorID); + + // LPF or RF activated + if(RateofChangeMode == LPF) + { + CalcLPF(k, "VARS", with0.QDesireDRCpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + } + else + { + if(RateofChangeMode == RISEFALL) + { + CalcRF(k, "VARS", with0.QDesireDRCpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + } + else + + // Checks kVA (watt priority) and kvarlimit limits + { + Check_Qlimits(k, with0.QDesireDRCpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireDRCpu ), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireDRCpu ); + } + + // Calculates QDesiredDRC[k] + } + CalcDRC_vars(k, ActorID); + + //--------------------------------------------- end main process ---------------------------------------------// + + // Sets DER kvar_out + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*)DERelem)->Set_Presentkvar(with0.QDesiredDRC); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredDRC); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredDRC >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredDRC >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputDRCpu = with0.Qoutputpu ; + with0.FAvgpDRCVpuPrior = with0.FPresentDRCVpu ; + + // Values used in CalcDRC_vars + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldDRC = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("DRC mode requested PVSystem output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredDRC, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldDRC = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + DERelem->Get_QualifiedName(), Format("DRC mode requested Storage output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredDRC, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + /*Smart Inverter VV_DRC function*/ + } + else + { + if ((ControlMode == NONE_MODE) && (CombiControlMode == VV_DRC) && (Get_PendingChange(k) == CHANGEDRCVVARLEVEL)) + + // Set var mode to VARMODEKVAR to indicate we might change kvar + { + if(( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(false); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_VVmode(true); + ((TPVsystemObj*)DERelem)->Set_DRCmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(false); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*)DERelem)->Set_VVmode(true); + ((TStorageObj*)DERelem)->Set_DRCmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireVVpu[k] and QDesireDRCpu[k] + CalcQVVcurve_desiredpu(k, ActorID); + CalcQDRC_desiredpu(k, ActorID); + + // LPF or RF activated + if(RateofChangeMode == LPF) + { + CalcLPF(k, "VARS", with0.QDesireVVpu + with0.QDesireDRCpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + } + else + { + if(RateofChangeMode == RISEFALL) + { + CalcRF(k, "VARS", with0.QDesireVVpu + with0.QDesireDRCpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + } + else + + // Checks kVA (watt priority) and kvarlimit limits + { + Check_Qlimits(k, with0.QDesireVVpu + with0.QDesireDRCpu , ActorID); + with0.QDesireEndpu = min(Abs( (with0.QDesireVVpu + with0.QDesireDRCpu )), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireVVpu + with0.QDesireDRCpu ); + } + + // Calculates QDesiredVVDRC[k] + } + CalcVVDRC_vars(k, ActorID); + + //--------------------------------------------- end main process ---------------------------------------------// + + // Sets DER kvar_out + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + ((TPVsystemObj*)DERelem)->Set_Presentkvar(with0.QDesiredVVDRC); + else + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredVVDRC); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredVVDRC >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredVVDRC >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputVVDRCpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + with0.FAvgpDRCVpuPrior = with0.FPresentDRCVpu ; + + // Values used in CalcQVVcurve_desiredpu and CalcVVDRC_vars + if(( (TNamedObject*)with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldVVDRC = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("**VV_DRC mode requested PVSystem output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVVDRC, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldVVDRC = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + DERelem->Get_QualifiedName(), Format("**VV_DRC mode requested Storage output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVVDRC, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + /*Smart Inverter volt-watt function*/ + } + else + { + if ((ControlMode == VOLTWATT) && (CombiControlMode == NONE_COMBMODE) && (Get_PendingChange(k) == CHANGEWATTLEVEL)) + { + if(( (TNamedObject*) with0.ControlledElement )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QVWcurve_limitpu[k] + CalcPVWcurve_limitpu(k, ActorID); + + // LPF or RF activated + if(RateofChangeMode == LPF) + { + CalcLPF(k, "WATTS", with0.PLimitVWpu , ActorID); + // Checks kVA (var priority) and pctPmpp limits + Check_Plimits(k, with0.PLimitOptionpu , ActorID); + with0.PLimitEndpu = min(with0.PLimitLimitedpu , with0.PLimitOptionpu ); + } + else + { + if(RateofChangeMode == RISEFALL) + { + CalcRF(k, "WATTS", with0.PLimitVWpu , ActorID); + // Checks kVA (var priority) and pctPmpp limits + Check_Plimits(k, with0.PLimitOptionpu , ActorID); + with0.PLimitEndpu = min(with0.PLimitLimitedpu , with0.PLimitOptionpu ); + } + else + + // Checks kVA (var priority) and pctPmpp limits + { + Check_Plimits(k, with0.PLimitVWpu , ActorID); + with0.PLimitEndpu = min(Abs(with0.PLimitLimitedpu ), Abs(with0.PLimitVWpu )) * Sign(with0.PLimitVWpu ); + } + + // Calculates PLimitVW[k] through the convergence algorithm + } + CalcVoltWatt_watts(k, ActorID); + + //--------------------------------------------- end main process ---------------------------------------------// + + // Sets DER kW_out + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_PresentkW(with0.PLimitVW); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + } + else + { + ((TStorageObj*)DERelem)->Set_kWRequested(with0.PLimitVW); + + // Uptates PresentkW and Presentkvar considering watt and var priorities + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + } + + + // Values used in convergence + with0.FAvgpVpuPrior = with0.FPresentVpu ; + with0.POldVWpu = with0.PLimitVW / with0.PBase ; + + // Flag has to do set to 0 when kW_out is lower than Ptemp (max power allowed from volt-watt function) + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + if((Abs(with0.PLimitVW ) > 0.0) && (double(Abs( (((TPVsystemObj*) DERelem)->Get_PresentkW() - with0.PLimitVW))) / with0.PLimitVW > 0.0001)) + with0.FVWOperation = 0; // 0.01% is the value chosen at the moment + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("**VOLTWATT mode set PVSystem kw output limit to **, kw= %.5g. Actual output is kw= %.5g.", with0.PLimitVW, ((TPVsystemObj*)DERelem)->Get_PresentkW()), ActorID); + } + else + { + if(double(Abs(Abs( ((TStorageObj*) DERelem)->Get_PresentkW()) - with0.PLimitVW )) / with0.PLimitVW > 0.0001) + with0.FVWOperation = 0; // 0.01% is the value chosen at the moment + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + DERelem->Get_QualifiedName(), Format("**VOLTWATT mode set Storage kw output limit to ** kw= %.5g. Actual output is kw= %.5g.", with0.PLimitVW, ((TStorageObj*)DERelem)->Get_PresentkW()), ActorID); + } + } + else + { + if ((ControlMode == NONE_MODE) && (CombiControlMode == VV_VW) && (Get_PendingChange(k) == CHANGEWATTVARLEVEL)) + { + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*)DERelem)->Set_VWmode(true); + ((TPVsystemObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TPVsystemObj*)DERelem)->Set_VVmode(true); + } + else + { + ((TStorageObj*)DERelem)->Set_VWmode(true); + ((TStorageObj*)DERelem)->Set_Varmode(VARMODEKVAR); + ((TStorageObj*)DERelem)->Set_VVmode(true); + } + + //--------------------------------------------- Main process ---------------------------------------------// + + // Calculates QDesireVVpu[k] and QVWcurve_limitpu + CalcPVWcurve_limitpu(k, ActorID); + CalcQVVcurve_desiredpu(k, ActorID); + + // LPF or RF activated + if(RateofChangeMode == LPF) + { + CalcLPF(k, "VARS", with0.QDesireVVpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + CalcLPF(k, "WATTS", with0.PLimitVWpu , ActorID); + // Checks kVA (var priority) and pctPmpp limits + Check_Plimits(k, with0.PLimitOptionpu , ActorID); + with0.PLimitEndpu = min(with0.PLimitLimitedpu , with0.PLimitOptionpu ); + } + else + { + if(RateofChangeMode == RISEFALL) + { + CalcRF(k, "VARS", with0.QDesireVVpu , ActorID); + // Checks kVA (watt priority) and kvarlimit limits + Check_Qlimits(k, with0.QDesireOptionpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireLimitedpu ), Abs(with0.QDesireOptionpu )) * Sign(with0.QDesireOptionpu ); + CalcRF(k, "WATTS", with0.PLimitVWpu , ActorID); + // Checks kVA (var priority) and pctPmpp limits + Check_Plimits(k, with0.PLimitOptionpu , ActorID); + with0.PLimitEndpu = min(with0.PLimitLimitedpu , with0.PLimitOptionpu ); + } + else + + // Checks kVA (watt priority) and kvarlimit limits + { + Check_Qlimits(k, with0.QDesireVVpu , ActorID); + with0.QDesireEndpu = min(Abs(with0.QDesireVVpu ), Abs(with0.QDesireLimitedpu )) * Sign(with0.QDesireVVpu ); + + // Checks kVA (var priority) and pctPmpp limits + Check_Plimits(k, with0.PLimitVWpu , ActorID); + with0.PLimitEndpu = min(Abs(with0.PLimitLimitedpu ), Abs(with0.PLimitVWpu )) * Sign(with0.PLimitVWpu ); + } + + // Calculates PLimitVW[k] and QDesiredVV[k] through the convergence algorithm + } + CalcVoltWatt_watts(k, ActorID); + CalcVoltVar_vars(k, ActorID); + + //--------------------------------------------- end main process ---------------------------------------------// + + // Sets DER kvar_out and kW_out + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->Set_Presentkvar(with0.QDesiredVV); + ((TPVsystemObj*) DERelem)->Set_PresentkW(with0.PLimitVW); + } + else + { + ((TStorageObj*)DERelem)->Set_kvarRequested(with0.QDesiredVV); + ((TStorageObj*)DERelem)->Set_kWRequested(with0.PLimitVW); + } + + // Uptates PresentkW and Presentkvar considering watt and var priorities + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + ((TPVsystemObj*) DERelem)->SetNominalPVSystemOuput(ActorID); + if(with0.QDesiredVV >= 0.0) + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TPVsystemObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + else + { + ((TStorageObj*) DERelem)->SetNominalStorageOutput(ActorID); + if(with0.QDesiredVV >= 0.0) + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoom ; + else + with0.Qoutputpu = ((TStorageObj*) DERelem)->Get_Presentkvar() / with0.QHeadRoomNeg ; + } + + // Values used in convergence + with0.QoutputVVpu = with0.Qoutputpu ; + with0.FAvgpVpuPrior = with0.FPresentVpu ; + with0.POldVWpu = with0.PLimitVW / with0.PBase ; + + // Values used in CalcQVVcurve_desiredpu + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + with0.QOld = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TPVsystemObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + DERelem->Get_QualifiedName(), Format("**VV_VW mode requested PVSystem output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVV, ((TPVsystemObj*)DERelem)->Get_Presentkvar()), ActorID); + } + else + { + with0.QOld = ((TStorageObj*) DERelem)->Get_Presentkvar(); + with0.QOldVV = ((TStorageObj*) DERelem)->Get_Presentkvar(); + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)DERelem)->Get_QualifiedName(), Format("**VV_VW mode requested Storage output var level to **, kvar= %.5g. Actual output set to kvar= %.5g.", with0.QDesiredVV, ((TStorageObj*)DERelem)->Get_Presentkvar()), ActorID); + } + + // Flag has to do set to 0 when kW_out is lower than Ptemp (max power allowed from volt-watt function) + if(( (TNamedObject*) (with0.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + { + if(double(Abs( (((TPVsystemObj*) DERelem)->Get_PresentkW() - with0.PLimitVW))) / with0.PLimitVW > 0.0001) + with0.FVWOperation = 0; // 0.01% is the value chosen at the moment + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + + ", " + + ((TNamedObject*) DERelem)->Get_QualifiedName(), Format("**VV_VW mode set PVSystem kw output limit to **, kw= %.5g. Actual output is kw= %.5g.", with0.PLimitVW, ((TPVsystemObj*)DERelem)->Get_PresentkW()), ActorID); + } + else + { + if(double(Abs(Abs( ((TStorageObj*) DERelem)->Get_PresentkW()) - with0.PLimitVW )) / with0.PLimitVW > 0.0001) + with0.FVWOperation = 0; // 0.01% is the value chosen at the moment + if(ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)DERelem)->Get_QualifiedName(), Format("**VV_VW mode set Storage kw output limit to** kw= %.5g. Actual output is kw= %.5g.", with0.PLimitVW, ((TStorageObj*)DERelem)->Get_PresentkW()), ActorID); + } + } + else + { + if (ControlMode == GFM) + { + auto& WS = ActiveCircuit[ActiveActor]->Solution; + + bool DER_OL = false; + if (with0.ControlledElement->GFM_Mode) + { + if (with0.ControlledElement->Get_myPName() == myDERTypes[EStorage]) + { + if (((TStorageObj*)with0.ControlledElement)->myDynVars.ILimit <= 0) // If there is no Amps limit, check OL + { + if (((TStorageObj*)with0.ControlledElement)->CheckOLInverter(ActorID)) + { + if (!WS->IsDynamicModel) + { + DER_OL = true; + ((TStorageObj*)with0.ControlledElement)->Set_StorageState(0); // It's burning, Turn it off + ((TStorageObj*)with0.ControlledElement)->FStateChanged = true; + } + else + ((TStorageObj*)with0.ControlledElement)->myDynVars.ResetIBR = true; // The dynamic alg will take it to safety + } + } + } + else + { + if (!WS->IsDynamicModel) + DER_OL = ((TPVsystemObj*)with0.ControlledElement)->CheckOLInverter(ActorID); + else + { + if (((TPVsystemObj*)with0.ControlledElement)->CheckOLInverter(ActorID)) + ((TPVsystemObj*)with0.ControlledElement)->myDynVars.ResetIBR = true; + } + } + if (DER_OL) + { + with0.ControlledElement->GFM_Mode = false; + with0.ControlledElement->Set_YprimInvalid(ActorID, true); + } + } + } + } + } + } + } + } + } + } + } + ActiveCircuit[ActorID]->Solution->LoadsNeedUpdating = true; + Set_PendingChange(None, k); + DERelem = nullptr; + } +} + +void TInvControlObj::GetmonVoltage(int ActorID, double& Vpresent, int i, double BaseKV) +{ + int j = 0; + TDSSBus* rBus = nullptr; + int NumNodes = 0; + complex V = {}; + complex vi = {}; + complex vj = {}; + + auto& withi = CtrlVars[i]; + if(FUsingMonBuses) + { + int stop = 0; + for(stop = FMonBuses.size() - 1, j = 0; j <= stop; j++) + { + FMonBusesIndex = ActiveCircuit[ActorID]->BusList.Find((FMonBuses)[j]); + rBus = ActiveCircuit[ActorID]->Buses[FMonBusesIndex - 1]; + if(FMonBusesNodes[j].size() == 2) + { + if(!ADiakoptics || (ActorID == 1)) + { + vi = (ActiveCircuit[ActorID]->Solution->NodeV[rBus->GetRef(FMonBusesNodes[j][0])]); + vj = (ActiveCircuit[ActorID]->Solution->NodeV[rBus->GetRef(FMonBusesNodes[j][1])]); + } + else + { + vi = (ActiveCircuit[ActorID]->Solution->VoltInActor1(rBus->GetRef(FMonBusesNodes[j][0]))); + vj = (ActiveCircuit[ActorID]->Solution->VoltInActor1(rBus->GetRef(FMonBusesNodes[j][1]))); + } + withi.cBuffer[j] = cmulreal(csub(vi, vj), BaseKV * 1000.0 / (FMonBusesVbase)[j + 1 - 1]); + V = withi.cBuffer[j]; + } + else + { + if(!ADiakoptics || (ActorID == 1)) + withi.cBuffer[j] = cmulreal(ActiveCircuit[ActorID]->Solution->NodeV[rBus->GetRef(FMonBusesNodes[j][0])], BaseKV * 1000.0 / (FMonBusesVbase)[j + 1 - 1]); + else + withi.cBuffer[j] = cmulreal(ActiveCircuit[ActorID]->Solution->VoltInActor1(rBus->GetRef(FMonBusesNodes[j][0])), BaseKV * 1000.0 / (FMonBusesVbase)[j + 1 - 1]); + V = withi.cBuffer[j]; + } + } + switch(FMonBusesPhase) + { + case AVGPHASES: + { + int stop = 0; + Vpresent = 0.0; + for(stop = FMonBuses.size() - 1, j = 0; j <= stop; j++) + { + Vpresent = Vpresent + cabs(withi.cBuffer[j]); + } + Vpresent = Vpresent / FMonBuses.size(); + } + break; + case MAXPHASE: + { + int stop = 0; + Vpresent = 0.0; + for(stop = FMonBuses.size() - 1, j = 0; j <= stop; j++) + { + Vpresent = max(Vpresent, cabs(withi.cBuffer[j])); + } + } + break; + case MINPHASE: + { + int stop = 0; + Vpresent = 1.0e50; + for(stop = FMonBuses.size() - 1, j = 0; j <= stop; j++) + { + Vpresent = min(Vpresent, cabs(withi.cBuffer[j])); + } + } + break; + default: + Vpresent = cabs(withi.cBuffer[FMonBusesPhase - 1]); + break; + } + } + else + { + int stop = 0; + ( (TDSSCktElement*) withi.ControlledElement )->ComputeVterminal(ActorID); + NumNodes = ( (TDSSCktElement*) (withi.ControlledElement) )->Get_NPhases(); + for(stop = NumNodes, j = 1; j <= stop; j++) + { + withi.cBuffer[j - 1] = (withi.ControlledElement)->Vterminal[j - 1]; + } + switch(FMonBusesPhase) + { + case AVGPHASES: + { + int stop = 0; + Vpresent = 0.0; + for(stop = NumNodes, j = 1; j <= stop; j++) + { + Vpresent = Vpresent + cabs(withi.cBuffer[j - 1]); + } + Vpresent = Vpresent / NumNodes; + } + break; + case MAXPHASE: + { + int stop = 0; + Vpresent = 0.0; + for(stop = NumNodes, j = 1; j <= stop; j++) + { + Vpresent = max(Vpresent, cabs(withi.cBuffer[j - 1])); + } + } + break; + case MINPHASE: + { + int stop = 0; + Vpresent = 1.0e50; + for(stop = NumNodes, j = 1; j <= stop; j++) + { + Vpresent = min(Vpresent, cabs(withi.cBuffer[j - 1])); + } + } + break; + default: + Vpresent = cabs(withi.cBuffer[FMonBusesPhase - 1]); + break; + } + } +} + +void TInvControlObj::UpdateDERParameters(int i) +{ + /*# with (ControlledElement)[i] do */ + { + auto& withi = CtrlVars[i]; + if( ( (TNamedObject*) (withi.ControlledElement) )->Get_myPName() == "PVSystem") + { + /*# with TPVsystemObj((ControlledElement)[i]) do */ + { + auto with1 = ((TPVsystemObj*) (withi.ControlledElement) ); + withi.CondOffset = ( ( (TDSSCktElement*) with1 )->Get_NTerms() - 1) * withi.NCondsDER ; // for speedy sampling + withi.FVBase = with1->VBase; + withi.FVarFollowInverter = with1->Get_VarFollowInverter(); + withi.FInverterON = with1->Get_InverterON(); + withi.FpresentkW = with1->Get_PresentkW(); + withi.FkVArating = with1->Get_FkVArating(); + withi.Fpresentkvar = with1->Get_Presentkvar(); + withi.Fkvarlimit = with1->Get_Fkvarlimit(); + withi.FkvarLimitNeg = with1->get_Fkvarlimitneg(); + withi.FCurrentkvarLimit = with1->CurrentkvarLimit; + withi.FCurrentkvarLimitNeg = with1->CurrentkvarLimitNeg; + withi.FDCkWRated = with1->Get_FPmpp(); + withi.FpctDCkWRated = with1->Get_FpuPmpp(); + withi.FEffFactor = with1->PVSystemVars.EffFactor; + withi.FDCkW = with1->PVSystemVars.PanelkW; + withi.FPPriority = with1->PVSystemVars.P_priority; + } + } + else + { + if(( (TNamedObject*) (withi.ControlledElement) )->Get_myPName() == myDERTypes[EStorage]) + { + /*# with TStorageObj((ControlledElement) ) do */ + { + auto with2 = ((TStorageObj*) (withi.ControlledElement) ); + withi.FVBase = with2->VBase; + withi.FVarFollowInverter = with2->Get_VarFollowInverter(); + withi.FInverterON = with2->Get_InverterON(); + withi.FpresentkW = with2->Get_PresentkW(); + withi.FkVArating = with2->Get_FkVARating(); + withi.Fpresentkvar = with2->Get_Presentkvar(); + withi.Fkvarlimit = with2->Get_Fkvarlimit(); + withi.FkvarLimitNeg = with2->Get_Fkvarlimitneg(); + withi.FCurrentkvarLimit = with2->CurrentkvarLimit; + withi.FCurrentkvarLimitNeg = with2->CurrentkvarLimitNeg; + withi.FDCkWRated = with2->StorageVars.kWrating; + withi.FpctDCkWRated = with2->Get_FpctkWrated(); + withi.FEffFactor = with2->StorageVars.EffFactor; + withi.FDCkW = 0.0; // not using it (using TStorageObj.DCkW directly) + withi.FPPriority = with2->StorageVars.P_Priority; + } + } + } + } +} + +void TInvControlObj::sample(int ActorID) +{ + int i = 0; + double BaseKV = 0.0, + Vpresent = 0.0; + TPVsystemObj* PVSyst = nullptr; + TStorageObj* Storage = nullptr; + // if list is not defined, go make one from all PVSystem/Storage in circuit + if(FDERPointerList->get_myNumList() == 0) + RecalcElementData(ActorID); + if(FListSize > 0) + // if an InvControl controls more than one PVSystem/Storage, control each one + // separately based on the PVSystem/Storage's terminal voltages, etc. + { + int stop = 0; + for(stop = FDERPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + auto& withi = CtrlVars[i]; + UpdateDERParameters(i); + if(( (TNamedObject*) (withi.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + PVSyst = (TPVsystemObj*) withi.ControlledElement; + else + Storage = (TStorageObj*) withi.ControlledElement; + BaseKV = withi.FVBase / 1000.0; // It's a line-to-ground voltage + GetmonVoltage(ActorID, Vpresent, i, BaseKV); + + // for reporting Vpriorpu correctly in EventLog (this update is normally perform at DoPendingAction) + if(ActiveCircuit[ActorID]->Solution->ControlIteration == 1) + { + withi.FAvgpVpuPrior = withi.FPresentVpu ; + withi.FAvgpDRCVpuPrior = withi.FPresentDRCVpu ; + } + withi.kW_out_desired = withi.FpresentkW ; // necessary to update kW_out_desired at every control iteration for Storage with SC + + // Help says that it must be used just for vv and vw + // convert to per-unit on bus' kvbase, or + // if using averaging window values, then set prior voltage to averaging window + if((FVoltage_CurveX_ref == 1) && (withi.FRollAvgWindow->Get_AvgVal() != 0.0)) + withi.FPresentVpu = Vpresent / (withi.FRollAvgWindow->Get_AvgVal()); + else + { + if((FVoltage_CurveX_ref == 2) && (withi.FRollAvgWindow->Get_AvgVal() != 0.0)) + withi.FPresentVpu = (withi.FRollAvgWindow->Get_AvgVal()) / (BaseKV * 1000.0); + else + withi.FPresentVpu = Vpresent / (BaseKV * 1000.0); + } + withi.FPresentDRCVpu = Vpresent / (BaseKV * 1000.0); + + // Sets internal variables of controlled element. + // FVreg is the pu voltage used in the volt-var and volt-watt curves + FVreg = withi.FPresentVpu; + // First, determine what control mode are we + if (CombiControlMode != 0) + { + // IT's CombiControl mode + switch (CombiControlMode) + { + case VV_DRC: + // Sets internal variables of controlled element. + // FVVDRCOperation is a flag which indicates if VVDRC function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(6, withi.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0)); // save rolling average voltage in monitor + PVSyst->Set_Variable(10, withi.FVVDRCOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(15, withi.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0)); // save rolling average voltage in monitor + Storage->Set_Variable(19, withi.FVVDRCOperation); + } + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + + // if the volt-var curve does not exist, exit + if (Fvvc_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing vvc1_curve does not exist or is not tied to InvControl.", 382); + return; + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_VVmode(true); + PVSyst->Set_DRCmode(true); + } + else + { + Storage->Set_VVmode(true); + Storage->Set_DRCmode(true); + } + //DRC triggers + if (withi.priorDRCRollAvgWindow == 0.0) + { + if ((Abs((withi.FPresentDRCVpu - withi.FAvgpDRCVpuPrior)) > FVoltageChangeTolerance) || (Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance)) + // Resets DER state variable only if it has not converged yet + { + withi.FVVDRCOperation = 0.0; + Set_PendingChange(CHANGEDRCVVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with0.intHour, with0.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to DRC trigger in VV_DRC mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentDRCVpu, withi.FAvgpDRCVpuPrior), ActorID); + } + } + //Trigger from volt-var mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || (Abs((withi.FPresentDRCVpu - withi.FAvgpDRCVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.QoutputVVDRCpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance))) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + // Resets DER state variable only if it has not converged yet + { + withi.FVVDRCOperation = 0.0; + Set_PendingChange(CHANGEDRCVVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with1 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with1.intHour, with1.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + ((TNamedObject*)withi.ControlledElement)->Get_QualifiedName(), Format("**Ready to change VV_DRC output due to volt-var trigger in VV_DRC mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + case VV_VW: + // Sets internal variables of controlled element. + // FVVOperation is a flag which indicates if volt-var function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + // FVWOperation is a flag which indicates if volt-watt function operates or not + // Combined modes operation is shown through TWO flags. It allows us to verify which of the individual function operates or not + if (((TNamedObject*)withi.ControlledElement)->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(7, withi.FVVOperation); + PVSyst->Set_Variable(8, withi.FVWOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(16, withi.FVVOperation); + Storage->Set_Variable(17, withi.FVWOperation); + } + + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + // if volt-watt curve does not exist, exit + if (((TNamedObject*)withi.ControlledElement)->Get_myPName() == myDERTypes[PVSys]) + { + if (Fvoltwatt_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing voltwatt_curve does not exist or is not tied to InvControl.", 381); + return; + } + } + else + { + if ((Fvoltwatt_curvename.size() == 0) && (FvoltwattCH_curvename.size() == 0)) + { + DoSimpleMsg("XY Curve object representing voltwatt_curve does not exist or is not tied to InvControl.", 381); + return; + } + } + // if the volt-var curve does not exist, exit + if (Fvvc_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing vvc1_curve does not exist or is not tied to InvControl.", 382); + return; + } + if (((TNamedObject*)withi.ControlledElement)->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_VVmode(true); + PVSyst->Set_VWmode(true); + } + else + { + Storage->Set_VVmode(true); + Storage->Set_VWmode(true); + } + // Trigger from volt-watt mode + if ((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || (Abs((withi.PLimitEndpu - withi.POldVWpu)) > FActivePChangeTolerance) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FVWOperation = 0; + Set_PendingChange(CHANGEWATTVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with2 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with2.intHour, with2.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change VV_VW output due to volt-watt trigger**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + //Trigger from volt-var mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.Qoutputpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance))) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FVVOperation = 0; + Set_PendingChange(CHANGEWATTVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with3 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with3.intHour, with3.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change VV_VW output due to volt-var trigger**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + default: + //Do nothing + break; + } + } + else + { + if (ControlMode != 0) + { + switch (ControlMode) + { + case VOLTWATT: // volt-watt control mode + // Sets internal variables of controlled element. + // FVWOperation is a flag which indicates if volt-watt function operates or not + if (withi.ControlledElement->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(8, withi.FVWOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(17, withi.FVWOperation); + } + if (withi.FInverterON == false) + continue; + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + if (Fvoltwatt_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing voltwatt_curve does not exist or is not tied to InvControl.", 381); + return; + } + } + else + { + if ((Fvoltwatt_curvename.size() == 0) && (FvoltwattCH_curvename.size() == 0)) + { + DoSimpleMsg("XY Curve object representing voltwatt_curve does not exist or is not tied to InvControl.", 381); + return; + } + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_VWmode(true); + else + Storage->Set_VWmode(true); + if ((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || (Abs((withi.PLimitEndpu - withi.POldVWpu)) > FActivePChangeTolerance) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FVWOperation = 0; + Set_PendingChange(CHANGEWATTLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with4 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with4.intHour, with4.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to limit watt output due to VOLTWATT mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + case AVR: // Active voltage regulation control mode + // Sets internal variables of PVSystem/Storage. + // FAVROperation is a flag which indicates if volt-var function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_AVRmode(true); + else + Storage->Set_VVmode(true); + + //Trigger from AVR mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.QoutputAVRpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance)) || (Abs((withi.FPresentVpu - withi.Fv_setpointLimited)) > FVoltageChangeTolerance)) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FAVROperation = 0; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with5 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with5.intHour, with5.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to AVR trigger in AVR mode**, Vavgpu= %.5g, VPriorpu=%.5g, Vsetpoint=%.5g, VsetpointLimited=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior, Fv_setpoint, withi.Fv_setpointLimited), ActorID); + } + break; + case VOLTVAR: // volt-var control mode + // Sets internal variables of PVSystem/Storage. + // FVVOperation is a flag which indicates if volt-var function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(7, withi.FVVOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(16, withi.FVVOperation); + } + + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + if (Fvvc_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing vvc1_curve does not exist or is not tied to InvControl.", 382); + return; + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_VVmode(true); + else + Storage->Set_VVmode(true); + + //Trigger from volt-var mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.QoutputVVpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance))) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FVVOperation = 0; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with6 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with6.intHour, with6.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to volt-var trigger in volt-var mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + case WATTPF: // watt-pf control mode + // Sets internal variables of PVSystem/Storage. + // FWPOperation is a flag which indicates if watt-pf function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(11, withi.FWPOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(16, withi.FWPOperation); + } + + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + if (Fwattpf_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing wattpf_curve does not exist or is not tied to InvControl.", 382); + return; + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == "PVSystem") + PVSyst->Set_WPmode(true); + else + Storage->Set_WPmode(true); + + //Trigger from volt-var mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.QoutputVVpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance))) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FWPOperation = 0; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with7 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with7.intHour, with7.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to watt-pf trigger in watt-pf mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + case WATTVAR: // watt-var control mode + // Sets internal variables of PVSystem/Storage. + // FWVOperation is a flag which indicates if watt-var function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(12, withi.FWVOperation); //CHANGE HERE + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(16, withi.FWVOperation); + } + + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + if (Fwattvar_curvename.size() == 0) + { + DoSimpleMsg("XY Curve object representing wattvar_curve does not exist or is not tied to InvControl.", 382); + return; + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_WVmode(true); + else + Storage->Set_WVmode(true); + + //Trigger from volt-var mode + if (((Abs((withi.FPresentVpu - withi.FAvgpVpuPrior)) > FVoltageChangeTolerance) || ((Abs(Abs(withi.QoutputVVpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance))) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) + + // Resets DER state variable only if it has not converged yet + { + withi.FWVOperation = 0; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with8 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with8.intHour, with8.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to watt-var trigger in watt-var mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentVpu, withi.FAvgpVpuPrior), ActorID); + } + break; + case DRC: // dynamic reactive current control mode + // Sets internal variables of PVSystem/Storage. + // FDRCOperation is a flag which indicates if DRC function operates or not (-1=absorbing Q, 1=injecting Q, 0=No operation) + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + { + PVSyst->Set_Variable(5, FVreg); + PVSyst->Set_Variable(6, withi.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0)); // save rolling average voltage in monitor + PVSyst->Set_Variable(9, withi.FDRCOperation); + } + else + { + Storage->Set_Variable(14, FVreg); + Storage->Set_Variable(15, withi.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0)); // save rolling average voltage in monitor + Storage->Set_Variable(18, withi.FDRCOperation); + } + + // if inverter is off then exit + if ((withi.FInverterON == false) && (withi.FVarFollowInverter == true)) + continue; + + //DRC triggers + if (withi.priorDRCRollAvgWindow == 0.0) + { + if ((Abs((withi.FPresentDRCVpu - withi.FAvgpDRCVpuPrior)) > FVoltageChangeTolerance)) + + // Resets DER state variable only if it has not converged yet + { + withi.FDRCOperation = 0; + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with9 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with9.intHour, with9.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to DRC trigger in DRC mode**, Vavgpu= %.5g, VPriorpu=%.5g", withi.FPresentDRCVpu, withi.FAvgpDRCVpuPrior), ActorID); + } + } + if (((TNamedObject*)(withi.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_DRCmode(true); + else + Storage->Set_DRCmode(true); + if ((Abs((withi.FPresentDRCVpu - withi.FAvgpDRCVpuPrior)) > FVoltageChangeTolerance) || (Abs(Abs(withi.QoutputDRCpu) - Abs(withi.QDesireEndpu)) > FVarChangeTolerance) || (ActiveCircuit[ActorID]->Solution->ControlIteration == 1)) // TEMc; also tried checking against QDesireEndpu + { + Set_PendingChange(CHANGEVARLEVEL, i); + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with10 = ActiveCircuit[ActorID]->Solution->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(with10.intHour, with10.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + if (ShowEventLog) + AppendToEventLog(String("InvControl.") + this->get_Name() + ", " + + withi.ControlledElement->Get_QualifiedName(), Format("**Ready to change var output due to DRC trigger in DRC mode**, Vavgpu= %.5g, VPriorpu=%.5g, QoutPU=%.3g, QDesiredEndpu=%.3g", withi.FPresentDRCVpu, withi.FAvgpDRCVpuPrior, withi.QoutputDRCpu, withi.QDesireEndpu), ActorID); + } + break; + case GFM: // Grid forming inverter supervision + { + auto& WS = ActiveCircuit[ActorID]->Solution; + bool Valid = false; + if (withi.ControlledElement->GFM_Mode) + { + // Check if it's in GFM mode + if (withi.ControlledElement->Get_myPName() == myDERTypes[EStorage]) + { + // storage case + if (((TStorageObj*)withi.ControlledElement)->get_fState() == 1) // Check if it's in discharging mode + { + if (((TStorageObj*)withi.ControlledElement)->myDynVars.ILimit > 0) + Valid = ((TStorageObj*)withi.ControlledElement)->CheckAmpsLimit(ActorID); // Checks if reached the Amps limit + else + Valid = ((TStorageObj*)withi.ControlledElement)->CheckOLInverter(ActorID); // Checks if Inv OL + } + Valid = Valid && !(((TStorageObj*)withi.ControlledElement)->myDynVars.ResetIBR); // Check if we are not resetting + } + else + { + // PVSystem case + if (((TPVsystemObj*)withi.ControlledElement)->myDynVars.ILimit > 0) + Valid = ((TPVsystemObj*)withi.ControlledElement)->CheckAmpsLimit(ActorID); // Checks if reached the Amps limit + else + Valid = ((TPVsystemObj*)withi.ControlledElement)->CheckOLInverter(ActorID); // Checks if Inv OL + Valid = Valid && !(((TPVsystemObj*)withi.ControlledElement)->myDynVars.ResetIBR); // Check if we are not resetting + } + + if (Valid) + { + auto& DynV = WS->DynaVars; + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push( + DynV.intHour, DynV.T + TimeDelay, (EControlAction)Get_PendingChange(i), 0, this, ActorID); + } + } + } + break; + default: + // Do nothing + break; + } + } + } + } + } +} + +void TInvControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); //PVSystem/Storage list + Set_PropertyValue(2, "VOLTVAR"); // initial mode + Set_PropertyValue(3, ""); // initial combination mode + Set_PropertyValue(4, ""); + Set_PropertyValue(5, "0"); + Set_PropertyValue(6, "rated"); + Set_PropertyValue(7, "0s"); + Set_PropertyValue(8, "NONE"); // voltwatt_curve + Set_PropertyValue(9, "0.95"); //'DbVMin'; + Set_PropertyValue(10, "1.05"); // 'DbVMax'; + Set_PropertyValue(11, "0.1"); // 'ArGraLowV'; + Set_PropertyValue(12, "0.1"); // 'ArGraHiV'; + Set_PropertyValue(13, "0s"); // 'Rollingavgwindowlen'; + Set_PropertyValue(14, FloatToStr(FLAGDELTAQ)); // FdeltaQFactor + Set_PropertyValue(15, "0.0001"); //VoltageChangeTolerance + Set_PropertyValue(16, "0.025"); // Varchangetolerance + Set_PropertyValue(17, "PMPPPU"); // Voltwatt y axis units + Set_PropertyValue(18, "INACTIVE"); //rate of change limit + Set_PropertyValue(19, "0.0"); // LPF tau constant, in seconds + Set_PropertyValue(20, "-1.0"); // Rise/fall Limit + Set_PropertyValue(21, FloatToStr(FLAGDELTAP)); // FdeltaPFactor + Set_PropertyValue(22, ShowEventLog ? "YES" : "NO"); // show event log + Set_PropertyValue(23, "VARAVAL"); // y-axis reference (and power precedence) for volt-var + Set_PropertyValue(24, "0.01"); + Set_PropertyValue(28, "NONE"); // voltwattCH_curve + inherited::InitPropertyValues(NumPropsThisClass); +} + +bool TInvControlObj::MakeDERList() +{ + bool result = false; + TDSSClass* PVSysClass = nullptr; + TDSSClass* StorageClass = nullptr; + TPVsystemObj* PVSyst = nullptr; + TStorageObj* Storage = nullptr; + TPCElement* DERelem = nullptr; + int i = 0; + int j = 0; + int stop = 0; + result = false; + PVSysClass = (TDSSClass*) GetDSSClassPtr("PVSystem"); + StorageClass = (TDSSClass*) GetDSSClassPtr("Storage"); + if (FListSize > 0) // Name list is defined - Use it + { + CtrlVars.resize(FListSize + 1); + + for (i = 1; i <= FListSize; i++) + { + auto& withi = CtrlVars[i]; + + withi.FVpuSolution.resize(3); + withi.cBuffer.resize(7); + + if (StripExtension(LowerCase(String((FDERNameList)[i - 1]))) == LowerCase(myDERTypes[PVSys])) + { + PVSyst = ((TPVsystemObj*)PVSysClass->Find(StripClassName(String((FDERNameList)[i - 1])))); + if (ASSIGNED(PVSyst)) + { + if (((TDSSCktElement*)PVSyst)->Get_Enabled()) + FDERPointerList->Set_New(PVSyst); + } + else + { + DoSimpleMsg(String("Error: PVSystem Element \"") + (FDERNameList)[i - 1] + + "\" not found.", 14403); + return result; + } + } + else + { + if (StripExtension(LowerCase(String((FDERNameList)[i - 1]))) == LowerCase(myDERTypes[EStorage])) + { + Storage = ((TStorageObj*)StorageClass->Find(StripClassName(String((FDERNameList)[i - 1])))); + if (ASSIGNED(Storage)) + { + if (((TDSSCktElement*)Storage)->Get_Enabled()) + FDERPointerList->Set_New(Storage); + } + else + { + DoSimpleMsg(String("Error: Storage Element \"") + (FDERNameList)[i - 1] + + "\" not found.", 14403); + return result; + } + } + } + } + } + else + + /*Search through the entire circuit for enabled PVSystem and Storage objects and add them to the list*/ + // Adding PVSystem elements + { + int stop = 0; + for(stop = PVSysClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + PVSyst = (TPVsystemObj*) PVSysClass->ElementList.Get(i); + if( ( (TDSSCktElement*) PVSyst )->Get_Enabled()) + FDERPointerList->Set_New(PVSyst); + FDERNameList.push_back( ( (TNamedObject*) PVSyst )->Get_QualifiedName()); + } + // Adding Storage elements + for(stop = StorageClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + Storage = (TStorageObj*) StorageClass->ElementList.Get(i); + if( ( (TDSSCktElement*) Storage )->Get_Enabled()) + FDERPointerList->Set_New(Storage); + FDERNameList.push_back( ( (TNamedObject*) Storage )->Get_QualifiedName()); + } + FListSize = FDERPointerList->get_myNumList(); + CtrlVars.resize(FListSize + 1); + + + } /*else*/ + + //Initialize arrays + for(stop = FListSize, i = 1; i <= stop; i++) + { + if(StripExtension(LowerCase(String((FDERNameList)[i - 1]))) == LowerCase(myDERTypes[PVSys])) + { + PVSyst = ((TPVsystemObj*) PVSysClass->Find(StripClassName(String((FDERNameList)[i - 1])))); + if(PVSyst != nullptr) + DERelem = ((TPCElement*) PVSyst); + } + else + { + Storage = ((TStorageObj*) StorageClass->Find(StripClassName(String((FDERNameList)[i - 1])))); + if(Storage != nullptr) + DERelem = ((TPCElement*) Storage); + } + + auto& withi = CtrlVars[i]; + // Sets the constants for the PI controller + withi.PICtrl = TPICtrl(); + withi.PICtrl.Kp = 1; // Uses deltaQ-factor as sample time for tunning the controller + + withi.FVpuSolution.resize(3); + withi.cBuffer.resize(7); + + for (j = 1; j < 7; j++) withi.cBuffer[j] = CZero; + + withi.FRollAvgWindow = new TRollAvgWindow; + withi.FDRCRollAvgWindow = new TRollAvgWindow; + + Set_NTerms( ( (TDSSCktElement*) DERelem )->Get_NTerms()); + withi.CondOffset = 0; + withi.NPhasesDER = DERelem->Get_NPhases(); + withi.NCondsDER = DERelem->Get_NConds(); + withi.FAvgpVpuPrior = 0.0; + withi.FAvgpDRCVpuPrior = 0.0; + withi.FPresentVpu = 0.0; + withi.FPresentDRCVpu = 0.0; + withi.QDesiredVV = 0.0; + withi.QDesiredWP = 0.0; + withi.QDesiredWV = 0.0; + withi.QOld = -1.0; + withi.QOldVV = -1.0; + if (!ASSIGNED(PVSyst)) withi.QOldAVR = 0.0; + else withi.QOldAVR = -PVSyst->get_Fkvarlimitneg() / 2.0; + withi.QOldDRC = -1.0; + withi.QOldVVDRC = -1.0; + withi.QDesiredDRC = 0.0; + withi.QDesiredVVDRC = 0.0; + withi.PLimitVW = 0.0; + withi.POldVWpu = 0.0; + withi.PBase = 0.0; + withi.QHeadRoom = 0.0; + withi.QHeadRoomNeg = 0.0; + withi.Qoutputpu = 0.0; + withi.QoutputVVpu = 0.0; + withi.QoutputAVRpu = 0.0; + withi.QoutputDRCpu = 0.0; + withi.QoutputVVDRCpu = 0.0; + withi.QDesireEndpu = 0.0; + withi.QDesireVVpu = 0.0; + withi.QDesireWPpu = 0.0; + withi.QDesireWVpu = 0.0; + withi.QDesireAVRpu = 0.0; + withi.QDesireLimitedpu = 0.0; + withi.QDesireOptionpu = 0.0; + withi.PLimitVWpu = 0.0; + withi.PLimitLimitedpu = 0.0; + withi.PLimitEndpu = 0.0; + withi.PLimitOptionpu = 0.0; + withi.QDesireDRCpu = 0.0; + + withi.FdeltaQFactor = DELTAQDEFAULT; + withi.FdeltaPFactor = DELTAPDEFAULT; + withi.DeltaV_old = -1.0; + + withi.deltaVDynReac = 0.0; + withi.FlagChangeCurve = false; + withi.FActiveVVCurve = 1; + withi.priorRollAvgWindow = 0.0; + withi.priorDRCRollAvgWindow = 0.0; + withi.FPriorWattspu = 0.0; + withi.FPriorwatts = 0.0; + withi.FPriorPLimitOptionpu = 0.0; + withi.FPriorQDesireOptionpu = 0.0; + withi.kW_out_desiredpu = 0.0; + withi.kW_out_desired = 0.0; + withi.FPriorvarspu = 0.0; + withi.FPriorvars = 0.0; + + withi.FFlagVWOperates = false; + + withi.FVVOperation = 0.0; + withi.FVWOperation = 0.0; + withi.FDRCOperation = 0.0; + withi.FVVDRCOperation = 0.0; + withi.FWPOperation = 0.0; + withi.FWVOperation = 0.0; + withi.FAVROperation = 0.0; + + for (j = 1; j <= 2; j++) withi.FVpuSolution[j] = 0.0; + + withi.FPendingChange = None; + withi.FVBase = 0.0; + withi.FVarFollowInverter= false; + withi.FInverterON = true; + withi.FpresentkW = 0.0; + withi.FkVArating = 0.0; + withi.Fpresentkvar = 0.0; + withi.Fkvarlimit = 0.0; + withi.FkvarLimitNeg = 0.0; + withi.FCurrentkvarLimit = 0.0; + withi.FCurrentkvarLimitNeg = 0.0; + withi.FDCkWRated = 0.0; + withi.FpctDCkWRated = 0.0; + withi.FEffFactor = 0.0; + withi.FDCkW = 0.0; + withi.FPPriority = false; + withi.DQDV = 0.0; + withi.Fv_setpointLimited= 0.0; + withi.FAvgpAVRVpuPrior = 0.0; + } /*for*/ + RecalcElementData(ActiveActor); + if(FDERPointerList->get_myNumList() > 0) + result = true; + return result; +} + +void TInvControlObj::Reset(int ActorID) +{ + + // inherited; +} + +TXYcurveObj* TInvControl::GetXYCurve(const String CurveName, int InvControlMode) +{ + TXYcurveObj* result = nullptr; + int i = 0; + result = ((TXYcurveObj*) XY_CurveClass->Find(CurveName)); + if(result == nullptr) + { + DoSimpleMsg(String("XY Curve object: \"") + CurveName + + "\" representing VOLTWATT or VOLTVAR curve (depending on mode) not found.", 380); + return result; + } + + + // if VOLTWATT control mode then check for any negative watt values (pu) + // and values greater than 1.0 per-unit (=100 percent output) + if(InvControlMode == VOLTWATT) + { + int stop = 0; + for(stop = result->get_FNumPoints(), i = 1; i <= stop; i++) + { + if((result->Get_YValue(i) < 0.0) || (result->Get_YValue(i) > 1.0)) + { + DoSimpleMsg(String("XY Curve object: \"") + CurveName + + "\" has active power value(s) greater than 1.0 per-unit or less than -1.0 per-unit. Not allowed for VOLTWATT control mode for PVSystem/Storages", 381); + result = nullptr; + break; + } + } + } + + // if WATTPF control mode then check for any negative pf values + // and values greater than 1.0 + if(InvControlMode == WATTPF) + { + int stop = 0; + for(stop = result->get_FNumPoints(), i = 1; i <= stop; i++) + { + if((result->Get_YValue(i) < - 1.0) || (result->Get_YValue(i) > 1.0)) + { + DoSimpleMsg(String("XY Curve object: \"") + CurveName + + "\" has power factor value(s) greater than 1.0 or less than -1.0. Not allowed for WATTPF control mode for PVSystem/Storages", 381); + result = nullptr; + break; + } + } + } + + // if WATTVAR control mode then check for any negative pf values + // and values greater than 1.0 + if(InvControlMode == WATTVAR) + { + int stop = 0; + for(stop = result->get_FNumPoints(), i = 1; i <= stop; i++) + { + if((result->Get_YValue(i) < - 1.0) || (result->Get_YValue(i) > 1.0)) + { + DoSimpleMsg(String("XY Curve object: \"") + CurveName + + "\" has reactive power value(s) greater than 1.0 per-unit or less than -1.0 per-unit. Not allowed for WATTVAR control mode for PVSystem/Storages", 381); + result = nullptr; + break; + } + } + } + return result; +} + +int TInvControlObj::InterpretAvgVWindowLen(const String s) +{ + int result = 0; + int Code = 0; + Char ch = L'\0'; + String S2; + /*Try to convert and see if we get an error*/ + Val(s, &result, Code); + if(Code == 0) + { + FRollAvgWindowLengthIntervalUnit = "s"; // Only a number was specified, so must be seconds + FVAvgWindowLengthSec = result * 1.0; + return result; + } + + /*Error occurred so must have a units specifier*/ + ch = s[s.size() - 1]; // get last character + S2 = s.substr(0, s.size() - 1); + Val(S2, &result, Code); + if(Code > 0) /*check for error*/ + { + FRollAvgWindowLengthIntervalUnit = "s"; // Only a number was specified, so must be seconds + FVAvgWindowLengthSec = 1.0; + result = 1; + DoSimpleMsg(String("Error in specification of Voltage Averaging Window Length: ") + s, 1134); + return result; + } + switch(ch) + { + case L'h': + { + FRollAvgWindowLengthIntervalUnit = "h"; + FVAvgWindowLengthSec = result * 3600.0; + } + break; + case L'm': + { + FRollAvgWindowLengthIntervalUnit = "m"; + FVAvgWindowLengthSec = result * 60.0; + } + break; + case L's': + { + FRollAvgWindowLengthIntervalUnit = "s"; + FVAvgWindowLengthSec = result * 1.0; + } + break; + default: + FRollAvgWindowLengthIntervalUnit = "s"; + FVAvgWindowLengthSec = result * 1.0; + result = 0; // Don't change it + DoSimpleMsg(String("Error in specification of voltage sample interval size: \"") + s + + "\" Units can only be h, m, or s (single char only) ", 99934); + break; + } + return result; +} + +int TInvControlObj::InterpretDRCAvgVWindowLen(const String s) +{ + int result = 0; + int Code = 0; + Char ch = L'\0'; + String S2; + /*Try to convert and see if we get an error*/ + Val(s, &result, Code); + if(Code == 0) + { + FDRCRollAvgWindowLengthIntervalUnit = "s"; // Only a number was specified, so must be seconds + FDRCVAvgWindowLengthSec = result * 1.0; + return result; + } + + /*Error occurred so must have a units specifier*/ + ch = s[s.size() - 1]; // get last character + S2 = s.substr(0, s.size() - 1); + Val(S2, &result, Code); + if(Code > 0) /*check for error*/ + { + FDRCRollAvgWindowLengthIntervalUnit = "s"; // Only a number was specified, so must be seconds + FDRCVAvgWindowLengthSec = 1.0; + result = 1; + DoSimpleMsg(String("Error in specification of Voltage Averaging Window Length: ") + s, 1134); + return result; + } + switch(ch) + { + case L'h': + { + FDRCRollAvgWindowLengthIntervalUnit = "h"; + FDRCVAvgWindowLengthSec = result * 3600.0; + } + break; + case L'm': + { + FDRCRollAvgWindowLengthIntervalUnit = "m"; + FDRCVAvgWindowLengthSec = result * 60.0; + } + break; + case L's': + { + FDRCRollAvgWindowLengthIntervalUnit = "s"; + FDRCVAvgWindowLengthSec = result * 1.0; + } + break; + default: + FDRCRollAvgWindowLengthIntervalUnit = "s"; + FDRCVAvgWindowLengthSec = result * 1.0; + result = 0; // Don't change it + DoSimpleMsg(String("Error in specification of voltage sample interval size: \"") + s + + "\" Units can only be h, m, or s (single char only) ", 99934); + break; + } + return result; +} + +String TInvControlObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = ReturnElementsList(); + break; +// 2 : +// begin +// if ControlMode = VOLTVAR then Result := VOLTVAR; +// if ControlMode = VOLTWATT then Result := VOLTWATT; +// if ControlMode = DRC then Result := DRC; +// end; + case 4: + result = Fvvc_curvename; + break; + case 5: + result = Format("%-.6g", Fvvc_curveOffset); + break; + case 6: + { + if(FVoltage_CurveX_ref == 0) + result = "rated"; + else + { + if(FVoltage_CurveX_ref == 1) + result = "avg"; + else + { + if(FVoltage_CurveX_ref == 2) + result = "avgrated"; + } + } + } + break; + case 7: + result = Format("%d", FRollAvgWindowLength) + FRollAvgWindowLengthIntervalUnit; + break; + case 8: + result = Fvoltwatt_curvename; + break; + case 9: + result = Format("%.6g", FDbVMin); + break; + case 10: + result = Format("%.6g", FDbVMax); + break; + case 11: + result = Format("%.6g", FArGraLowV); + break; + case 12: + result = Format("%.6g", FArGraHiV); + break; + case 13: + result = Format("%d", FDRCRollAvgWindowLength ) + FDRCRollAvgWindowLengthIntervalUnit; + break; + case 14: + result = Format("%.6g", FdeltaQ_factor); + break; + case 15: + result = Format("%.6g", FVoltageChangeTolerance); + break; + case 16: + result = Format("%.6g", FVarChangeTolerance); + break; + case 17: + { + if(FVoltwattYAxis == 0) + result = "PAVAILABLEPU"; + if(FVoltwattYAxis == 1) + result = "PMPPPU"; + if(FVoltwattYAxis == 2) + result = "PCTPMPPPU"; + if(FVoltwattYAxis == 3) + result = "KVARATINGPU"; + } + break; + case 18: + { + if(RateofChangeMode == Inactive) + result = "INACTIVE"; + else + { + if(RateofChangeMode == LPF) + result = "LPF"; + else + { + if(RateofChangeMode == RISEFALL) + result = "RISEFALL"; + } + } + } + break; + case 21: + result = Format("%.6g", FdeltaP_factor); + break; + case 23: + result = FReacPower_ref; + break; + case 24: + result = Format("%.6g", FActivePChangeTolerance); + break; + case 28: + result = FvoltwattCH_curvename; + break; + case 34: + result = Format("%d", CtrlModel); + break; + default: // take the generic handler + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +String TInvControlObj::ReturnElementsList() +{ + String result; + int i = 0; + int stop = 0; + if(FListSize == 0) + { + result = ""; + return result; + } + result = String("[") + (FDERNameList)[0]; + for(stop = FListSize - 1, i = 1; i <= stop; i++) + { + result = result + ", " + String((FDERNameList)[i]); // we need to pass the full name.. + } + result = result + "]"; // terminate the array + return result; +} + +void TInvControlObj::Set_Enabled(bool Value) +{ + inherited::Set_Enabled(Value); + + /*Reset controlled PVSystem/Storages to original PF*/ +} + +void TInvControlObj::Set_PendingChange(int Value, int DevIndex) +{ + CtrlVars[DevIndex].FPendingChange = Value; + DblTraceParameter = (double) Value; +} + +void TInvControlObj::UpdateInvControl(int i, int ActorID) +{ + int j = 0; + int k = 0; + double solnvoltage = 0.0; + std::vector tempVbuffer = {}; + TPVsystemObj* PVSyst = nullptr; + TStorageObj* Storage = nullptr; + double BaseKV = 0.0; + int stop = 0; + for(stop = FDERPointerList->get_myNumList(), j = 1; j <= stop; j++) + { + auto& withj = CtrlVars[j]; + // only update solution idx one time through this routine + int stop1 = 0; + if((j == 1) && (i == 1)) + //update solution voltage in per-unit for hysteresis + { + if(FVpuSolutionIdx == 2) + FVpuSolutionIdx = 1; + else + FVpuSolutionIdx = FVpuSolutionIdx + 1; + } + if( ( (TNamedObject*) (withj.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + PVSyst = (TPVsystemObj*) (withj.ControlledElement); + else + Storage = (TStorageObj*) (withj.ControlledElement); + BaseKV = withj.FVBase / 1000.0; + + // FPriorvars[j] := PVSys.Presentkvar; + // FPriorWatts[j] := PVSys.PresentkW; + withj.FPriorPLimitOptionpu = withj.PLimitOptionpu; + withj.FPriorQDesireOptionpu = withj.QDesireOptionpu; + + // Used to update the VW resquested kW + if(((TNamedObject*)(withj.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_VWmode(false); + else + Storage->Set_VWmode(false); + if(((TNamedObject*)(withj.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_VVmode(false); + else + Storage->Set_VVmode(false); + if(((TNamedObject*)(withj.ControlledElement))->Get_myPName() == myDERTypes[PVSys]) + PVSyst->Set_DRCmode(false); + else + Storage->Set_DRCmode(false); + withj.FFlagVWOperates = false; + + // Reset DQDV - We might not need it + withj.DQDV = 0.0; + + // Reset the operation flags for the new time step + withj.FVVOperation = 0; + withj.FVWOperation = 0; + withj.FDRCOperation = 0; + withj.FVVDRCOperation = 0; + withj.FWPOperation = 0; + withj.FWVOperation = 0; + withj.FAVROperation = 0; + + // Reinitialize convergence arrays. + //FdeltaQFactor[j] := DELTAQDEFAULT; + withj.FdeltaPFactor = DELTAPDEFAULT; + + // allocated enough memory to buffer to hold voltages and initialize to cZERO + tempVbuffer.resize( ( withj.ControlledElement)->Get_NConds() * sizeof(complex) ); + for(stop1 = ( (TDSSCktElement*) (withj.ControlledElement) )->Get_NConds(), k = 1; k <= stop1; k++) + tempVbuffer[k - 1] = CZero; + + withj.priorRollAvgWindow = withj.FRollAvgWindow->Get_AvgVal(); + withj.priorDRCRollAvgWindow = withj.FDRCRollAvgWindow->Get_AvgVal(); + + // compute the present terminal voltage + ( (TDSSCktElement*) withj.ControlledElement )->ComputeVterminal(ActorID); + //PVSys.Set_Variable(5,FDRCRollAvgWindow[j].Get_AvgVal); // save rolling average voltage in monitor + solnvoltage = 0.0; + GetmonVoltage(ActorID, solnvoltage, j, BaseKV); + + //for k := 1 to localControlledElement.Yorder do tempVbuffer[k] := localControlledElement.Vterminal^[k]; + + + //for k := 1 to localControlledElement.Nphases do solnvoltage := solnvoltage + Cabs(tempVbuffer[k]); + //solnvoltage := solnvoltage / (localControlledElement.Nphases*1.0); // average of voltages if more than one phase + + // add present power flow solution voltage to the rolling average window + withj.FRollAvgWindow->Add(solnvoltage, ActiveCircuit[ActorID]->Solution->DynaVars.h, FVAvgWindowLengthSec); + withj.FDRCRollAvgWindow->Add(solnvoltage, ActiveCircuit[ActorID]->Solution->DynaVars.h, FDRCVAvgWindowLengthSec); + withj.FVpuSolution[FVpuSolutionIdx] = solnvoltage / ((ActiveCircuit[ActorID]->Buses[withj.ControlledElement->Terminals[0].BusRef - 1]->kVBase) * 1000.0); + tempVbuffer.resize(0); // Clean up memory + } +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_ControlMode() +{ + return ControlMode; +} + +//------------------------------------------------------------------------------------------------- + + +int TInvControlObj::get_CombiControlMode() +{ + return CombiControlMode; +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_FVoltage_CurveX_ref() +{ + return FVoltage_CurveX_ref; +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_FRollAvgWindowLength() +{ + return FRollAvgWindowLength; +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_FDRCRollAvgWindowLength() +{ + return FDRCRollAvgWindowLength; +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_FMonBusesPhase() +{ + return FMonBusesPhase; +} + +//------------------------------------------------------------------------------------------------- + +int TInvControlObj::get_FVoltwattYAxis() +{ + return FVoltwattYAxis; +} + +//------------------------------------------------------------------------------------------------- + + +TStringList* TInvControlObj::get_FDERNameList() +{ + return &FDERNameList; +} + +//------------------------------------------------------------------------------------------------- + +TStringList* TInvControlObj::get_FMonBusesNameList() +{ + return &FMonBusesNameList; +} + +//------------------------------------------------------------------------------------------------- + + +String TInvControlObj::get_Fvvc_curvename() +{ + return Fvvc_curvename; +} + +//------------------------------------------------------------------------------------------------- + +String TInvControlObj::get_Fvoltwatt_curvename() +{ + return Fvoltwatt_curvename; +} + +//------------------------------------------------------------------------------------------------- + +String TInvControlObj::get_FvoltwattCH_curvename() +{ + return FvoltwattCH_curvename; +} + +//------------------------------------------------------------------------------------------------- + +String TInvControlObj::get_FReacPower_ref() +{ + return FReacPower_ref; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_Fvvc_curveOffset() +{ + return Fvvc_curveOffset; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FDbVMin() +{ + return FDbVMin; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FDbVMax() +{ + return FDbVMax; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FArGraLowV() +{ + return FArGraLowV; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FArGraHiV() +{ + return FArGraHiV; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FdeltaQ_factor() +{ + return FdeltaQ_factor; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FVoltageChangeTolerance() +{ + return FVoltageChangeTolerance; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FVarChangeTolerance() +{ + return FVarChangeTolerance; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FLPFTau() +{ + return FLPFTau; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FRiseFallLimit() +{ + return FRiseFallLimit; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FdeltaP_factor() +{ + return FdeltaP_factor; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_FActivePChangeTolerance() +{ + return FActivePChangeTolerance; +} + +//------------------------------------------------------------------------------------------------- + +double TInvControlObj::get_Fv_setpoint() +{ + return Fv_setpoint; +} + +//------------------------------------------------------------------------------------------------- + +pDoubleArray TInvControlObj::get_FMonBusesVbase() +{ + return &(FMonBusesVbase[0]); +} + +//------------------------------------------------------------------------------------------------- + + +int TInvControlObj::Get_PendingChange(int DevIndex) +{ + int result = 0; + result = CtrlVars[DevIndex].FPendingChange; + return result; +} + +void TInvControlObj::CalcVoltWatt_watts(int j, int ActorID) +{ + double DeltaPpu = 0.0; + auto& withj = CtrlVars[j]; + // PLimitEndpu[j] <= abs(kW_out_desiredpu[j] will always be true when we are in 'resquest' region of VW + // That's what we want. In this region, VW will work similarly to VV. So we need to move slowly towards the VW curve point. + if(((withj.PLimitEndpu < 1.0) && (withj.PLimitEndpu <= Abs(withj.kW_out_desiredpu))) || (withj.FFlagVWOperates)) + { + if(ActiveCircuit[ActorID]->Solution->ControlIteration == 1) + withj.POldVWpu = Abs(withj.kW_out_desiredpu); // take abs(kW_out_desiredpu) because might be in charging mode. + withj.FFlagVWOperates = true; + + // PLimitEndpu might be negative here in 'requesting' region. Do we need to give POldVW a sign in this case? + // Yes, it will naturally evolve to a negative value with the process. It will always positive only in the 1st control iteration. + DeltaPpu = withj.PLimitEndpu - withj.POldVWpu; + if(FdeltaP_factor == FLAGDELTAP) + Change_deltaP_factor(ActorID, j); + else + withj.FdeltaPFactor = FdeltaP_factor; + withj.PLimitVW = (withj.POldVWpu + DeltaPpu * withj.FdeltaPFactor) * withj.PBase; + } + else + { + withj.PLimitVW = withj.PLimitEndpu * withj.PBase; + } +} + +void TInvControlObj::Check_Plimits(int j, double P, int ActorID) +{ + double P_Ppriority = 0.0; + double pctDCkWRatedlimit = 0.0; + auto& withj = CtrlVars[j]; + + withj.PLimitLimitedpu = 1.0; // Not limited + + // volt-watt states + if(P < 1.0) + withj.FVWOperation = 1.0; + pctDCkWRatedlimit = withj.FpctDCkWRated * withj.FDCkWRated; + + // PLimitEndpu should be less than the P avaliable under var priority (works for VV_VW) + if(withj.FPPriority == false) + { + P_Ppriority = sqrt(Sqr(withj.FkVArating) - Sqr(withj.Fpresentkvar)); + if(P_Ppriority < (Abs( P) * withj.PBase)) // P might be negative in requesting region for storage + { + withj.PLimitLimitedpu = P_Ppriority / withj.PBase * Sign(P); + withj.FVWOperation = 0.0; // kVA exceeded under watt priority + } + } + + // PLimitEndpu should be less than pctPmpp + if((Abs( P) * withj.PBase) > pctDCkWRatedlimit) + { + withj.FVWOperation = 0.0; // pctPmpp exceeded under watt priority + withj.PLimitLimitedpu = pctDCkWRatedlimit / withj.PBase * Sign(P); + } +} + +void TInvControlObj::CalcVoltVar_vars(int j, int ActorID) +{ + double DeltaQ = 0.0; + auto& withj = CtrlVars[j]; + if(withj.FlagChangeCurve == false) + { + if(withj.QDesireEndpu >= 0.0) + DeltaQ = withj.QDesireEndpu * withj.QHeadRoom; + else + DeltaQ = withj.QDesireEndpu * withj.QHeadRoomNeg; + if (CtrlModel == 0) + { + DeltaQ = DeltaQ - withj.QOldVV; + if (FdeltaQ_factor == FLAGDELTAQ) + Change_deltaQ_factor(ActorID, j); + else + withj.FdeltaQFactor = FdeltaQ_factor; + withj.QDesiredVV = withj.QOldVV + DeltaQ * withj.FdeltaQFactor; + } + else + { + withj.PICtrl.kDen = exp(-1 * abs(FdeltaQ_factor)); + withj.PICtrl.kNum = 1 - withj.PICtrl.kDen; + withj.QDesiredVV = withj.PICtrl.SolvePI(DeltaQ); + } + // else, stay at present var output level + } + else + { + withj.QDesiredVV = withj.Fpresentkvar; + } +} + +void TInvControlObj::CalcAVR_vars(int j, int ActorID) +{ + double DeltaQ = 0.0; + auto& withj = CtrlVars[j]; + + if(withj.QDesireEndpu >= 0.0) + DeltaQ = withj.QDesireEndpu * withj.QHeadRoom; + else + DeltaQ = withj.QDesireEndpu * withj.QHeadRoomNeg; + if (CtrlModel == 0) + { + DeltaQ = DeltaQ - withj.QOldAVR; + if (FdeltaQ_factor == FLAGDELTAQ) + Change_deltaQ_factor(ActorID, j); + else + withj.FdeltaQFactor = FdeltaQ_factor; + withj.QDesiredAVR = withj.QOldAVR + 0.2 * DeltaQ; + } + else + { + withj.PICtrl.kDen = exp(-1 * abs(FdeltaQ_factor)); + withj.PICtrl.kNum = 1 - withj.PICtrl.kDen; + withj.QDesiredAVR = withj.PICtrl.SolvePI(DeltaQ); + } +} + +void TInvControlObj::CalcWATTPF_vars(int j, int ActorID) +{ + auto& withj = CtrlVars[j]; + if(withj.QDesireEndpu >= 0.0) + withj.QDesiredWP = withj.QDesireEndpu * withj.QHeadRoom; + else + withj.QDesiredWP = withj.QDesireEndpu * withj.QHeadRoomNeg; +} + +void TInvControlObj::CalcWATTVAR_vars(int j, int ActorID) +{ + auto& withj = CtrlVars[j]; + if(withj.QDesireEndpu >= 0.0) + withj.QDesiredWV = withj.QDesireEndpu * withj.QHeadRoom; + else + withj.QDesiredWV = withj.QDesireEndpu * withj.QHeadRoomNeg; +} + +void TInvControlObj::CalcDRC_vars(int j, int ActorID) +{ + double DeltaQ = 0.0; + auto& withj = CtrlVars[j]; + + if(withj.QDesireEndpu >= 0.0) + DeltaQ = withj.QDesireEndpu * withj.QHeadRoom; + else + DeltaQ = withj.QDesireEndpu * withj.QHeadRoomNeg; + if (CtrlModel == 0) + { + DeltaQ = DeltaQ - withj.QOldDRC; + if (FdeltaQ_factor == FLAGDELTAQ) + Change_deltaQ_factor(ActorID, j); + else + withj.FdeltaQFactor = FdeltaQ_factor; + withj.QDesiredDRC = withj.QOldDRC + DeltaQ * withj.FdeltaQFactor; + } + else + { + withj.PICtrl.kDen = exp(-1 * abs(FdeltaQ_factor)); + withj.PICtrl.kNum = 1 - withj.PICtrl.kDen; + withj.QDesiredDRC = withj.PICtrl.SolvePI(DeltaQ); + } +} + +void TInvControlObj::CalcVVDRC_vars(int j, int ActorID) +{ + double DeltaQ = 0.0; + auto& withj = CtrlVars[j]; + + if(withj.QDesireEndpu >= 0.0) + DeltaQ = withj.QDesireEndpu * withj.QHeadRoom; + else + DeltaQ = withj.QDesireEndpu * withj.QHeadRoomNeg; + + if (CtrlModel == 0) + { + DeltaQ = DeltaQ - withj.QOldVVDRC; + if (FdeltaQ_factor == FLAGDELTAQ) + Change_deltaQ_factor(ActorID, j); + else + withj.FdeltaQFactor = FdeltaQ_factor; + withj.QDesiredVVDRC = withj.QOldVVDRC + DeltaQ * withj.FdeltaQFactor; + } + else + { + withj.PICtrl.kDen = exp(-1 * abs(FdeltaQ_factor)); + withj.PICtrl.kNum = 1 - withj.PICtrl.kDen; + withj.QDesiredVVDRC = withj.PICtrl.SolvePI(DeltaQ); + } +} + +void TInvControlObj::Calc_PBase(int j, int ActorID) +{ + TPCElement* DERelem = nullptr; + auto& withj = CtrlVars[j]; + + DERelem = (withj.ControlledElement); + if( ( (TNamedObject*) DERelem )->Get_myPName() == myDERTypes[PVSys]) + { + if(FVoltwattYAxis == 0) + withj.PBase = withj.FDCkW * withj.FEffFactor; + else + { + if(FVoltwattYAxis == 1) + withj.PBase = withj.FDCkWRated; + else + { + if(FVoltwattYAxis == 2) + withj.PBase = withj.FDCkWRated * withj.FpctDCkWRated; + else + { + if(FVoltwattYAxis == 3) + withj.PBase = withj.FkVArating; + } + } + } + } + else + { + if(FVoltwattYAxis == 0) + withj.PBase = ((TStorageObj*) DERelem)->Get_DCkW() * withj.FEffFactor; + else + { + if(FVoltwattYAxis == 1) + withj.PBase = withj.FDCkWRated; + else + { + if(FVoltwattYAxis == 2) + withj.PBase = withj.FDCkWRated * withj.FpctDCkWRated; + else + { + if(FVoltwattYAxis == 3) + withj.PBase = withj.FkVArating; + } + } + } + } +} + +void TInvControlObj::CalcLPF(int m, String powertype, double LPF_desiredpu, int ActorID) +{ + double Alpha = 0.0; + auto& withm = CtrlVars[m]; + + // Applies the LPF: + // Return value is in kvar for VARS + // Return value is in puPmpp for WATTS + + // Qoutput(t) = Qdesired(t) x {1- exp[-(t-t0)/tau]} + Qoutput(t-t0) x exp[-(t-t0)/tau] + // calculate the alpha constant: alpha = exp[-(t-t0)/tau] + Alpha = exp(-1.0 * ActiveCircuit[ActorID]->Solution->DynaVars.h / FLPFTau); + if(powertype == "VARS") + withm.QDesireOptionpu = LPF_desiredpu * (1 - Alpha) + withm.FPriorQDesireOptionpu * Alpha; + if(powertype == "WATTS") + withm.PLimitOptionpu = LPF_desiredpu * (1 - Alpha) + withm.FPriorPLimitOptionpu * Alpha; +} + +void TInvControlObj::CalcRF(int m, String powertype, double RF_desiredpu, int ActorID) +{ + auto& withm = CtrlVars[m]; + // Applies the Rise/Fall limiting function: + if(powertype == "VARS") + // rate of change rise/fall limit + { + if((RF_desiredpu - withm.FPriorQDesireOptionpu) > (FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h)) + withm.QDesireOptionpu = withm.FPriorQDesireOptionpu + FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h; + else + { + if((RF_desiredpu - withm.FPriorQDesireOptionpu) < (-1 * FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h)) + withm.QDesireOptionpu = withm.FPriorQDesireOptionpu - FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h; + else + withm.QDesireOptionpu = RF_desiredpu; + } + } + if(powertype == "WATTS") + // rate of change rise/fall limit + { + if((RF_desiredpu - withm.FPriorPLimitOptionpu) > (FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h)) + withm.PLimitOptionpu = withm.FPriorPLimitOptionpu + (FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h); + else + { + if((RF_desiredpu - withm.FPriorPLimitOptionpu) < (-1 * FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h)) + withm.PLimitOptionpu = withm.FPriorPLimitOptionpu - (FRiseFallLimit * ActiveCircuit[ActorID]->Solution->DynaVars.h); + else + withm.PLimitOptionpu = RF_desiredpu; + } + } +} + +void TInvControlObj::CalcPVWcurve_limitpu(int j, int ActorID) +{ + auto& withj = CtrlVars[j]; + + if( ( (TNamedObject*) (withj.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + withj.PLimitVWpu = Fvoltwatt_curve->GetYValue_(withj.FPresentVpu); + else + { + if(((TStorageObj*) (withj.ControlledElement))->get_fState() == STORE_DISCHARGING) + { + if(((TStorageObj*) (withj.ControlledElement))->FVWStateRequested) + withj.PLimitVWpu = FvoltwattCH_curve->GetYValue_(withj.FPresentVpu); + else + withj.PLimitVWpu = Fvoltwatt_curve->GetYValue_(withj.FPresentVpu); + } + else + { + if((((TStorageObj*) (withj.ControlledElement))->get_fState() == STORE_CHARGING) && (FvoltwattCH_curve != nullptr)) + { + if(((TStorageObj*) (withj.ControlledElement))->FVWStateRequested) + withj.PLimitVWpu = Fvoltwatt_curve->GetYValue_(withj.FPresentVpu); + else + // try with positive PlimitVWpu + withj.PLimitVWpu = FvoltwattCH_curve->GetYValue_(withj.FPresentVpu); + } + else + withj.PLimitVWpu = 1.0; // don't limit if in idling state + } + } +} + +void TInvControlObj::CalcQVVcurve_desiredpu(int j, int ActorID) +{ + double voltagechangesolution = 0.0; + double QPresentpu = 0.0; + double VpuFromCurve = 0.0; + auto& withj = CtrlVars[j]; + + withj.QDesireVVpu = 0.0; + if(withj.Fpresentkvar >= 0.0) + QPresentpu = withj.Fpresentkvar / withj.QHeadRoom; + else + QPresentpu = withj.Fpresentkvar / withj.QHeadRoomNeg; + voltagechangesolution = 0.0; + + // for first two seconds, keep voltagechangesolution equal to zero + // we don't have solutions from the time-series power flow, yet + if((ActiveCircuit[ActorID]->Solution->DynaVars.dblHour * 3600.0 / ActiveCircuit[ActorID]->Solution->DynaVars.h) < 3.0) + voltagechangesolution = 0.0; + else + { + if(FVpuSolutionIdx == 1) + voltagechangesolution = withj.FVpuSolution[1] - withj.FVpuSolution[2]; + else + { + if(FVpuSolutionIdx == 2) + voltagechangesolution = withj.FVpuSolution[2] - withj.FVpuSolution[1]; + } + + // if no hysteresis (Fvvc_curveOffset == 0), then just look up the value + // from the volt-var curve + } + if(Fvvc_curveOffset == 0.0) // no hysteresis + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu); // end of logic for the no-hysteresis case + + // else if we're going in the positive direction and on curve 1, stay + // with curve 1 + } + else + { + if((voltagechangesolution > 0) && (withj.FActiveVVCurve == 1)) + { + if(withj.FlagChangeCurve == true) + { + VpuFromCurve = Fvvc_curve->GetXValue(QPresentpu); + if(Abs( (withj.FPresentVpu - VpuFromCurve)) < FVoltageChangeTolerance / 2.0) + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu); //Y value = in per-unit of headroom + withj.FlagChangeCurve = false; + } + else + { + withj.QDesireVVpu = QPresentpu; // (PR) look at here + withj.FlagChangeCurve = false; + } + } + else + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu); //Y value = in per-unit of headroom + } + + // with hysteresis if we're going in the positive direction on voltages + // from last two power flow solutions, and we're using curve 2, keep vars + // the same, and change to curve1 active + } + else + { + if((voltagechangesolution > 0) && (withj.FActiveVVCurve == 2)) + { + withj.QDesireVVpu = QPresentpu; + withj.FActiveVVCurve = 1; + withj.FlagChangeCurve = true; + + // with hysteresis if we're going in the negative direction on voltages + // from last two power flow solutions, and we're using curve 2, either + // lookup the vars for the voltage we're at (with offset on curve1), + // or if we've not just changed curves, stay at the current p.u. + // var output + } + else + { + if((voltagechangesolution < 0) && (withj.FActiveVVCurve == 2)) + { + if(withj.FlagChangeCurve == true) + { + VpuFromCurve = Fvvc_curve->GetXValue(QPresentpu); + VpuFromCurve = VpuFromCurve - Fvvc_curveOffset; + if(Abs( (withj.FPresentVpu - VpuFromCurve)) < FVoltageChangeTolerance / 2.0) + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu - Fvvc_curveOffset); //Y value = in per-unit of headroom + withj.FlagChangeCurve = false; + } + else + { + withj.QDesireVVpu = QPresentpu; + withj.FlagChangeCurve = false; + } + } + else + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu - Fvvc_curveOffset); //Y value = in per-unit of headroom + } + + // with hysteresis if we're going in the negative direction on voltages + // from last two power flow solutions, and we're using curve 1, then + // stay wjth present output vars and make curve2 active, set curve change + // flag + } + else + { + if((voltagechangesolution < 0) && (withj.FActiveVVCurve == 1)) + { + withj.QDesireVVpu = QPresentpu; + withj.FActiveVVCurve = 2; + withj.FlagChangeCurve = true; + + + // if no change in voltage from one powerflow to the next, then + // do one of the following + } + else + { + if((voltagechangesolution == 0) && (withj.FActiveVVCurve == 1) && (withj.FlagChangeCurve == false)) + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu); + } + else + { + if((voltagechangesolution == 0) && (withj.FlagChangeCurve == true)) + { + withj.QDesireVVpu = QPresentpu; + } + else + { + if((voltagechangesolution == 0) && (withj.FActiveVVCurve == 2) && (withj.FlagChangeCurve == false)) + { + withj.QDesireVVpu = Fvvc_curve->GetYValue_(withj.FPresentVpu - Fvvc_curveOffset); + } + } + } + } + } + } + } + } +} + +void TInvControlObj::CalcQWVcurve_desiredpu(int j, int ActorID) +{ + double voltagechangesolution = 0.0; + double PBase = 0.0; + auto& withj = CtrlVars[j]; + + withj.QDesireWVpu = 0.0; + voltagechangesolution = 0.0; + + // for first two seconds, keep voltagechangesolution equal to zero + // we don't have solutions from the time-series power flow, yet + if((ActiveCircuit[ActorID]->Solution->DynaVars.dblHour * 3600.0 / ActiveCircuit[ActorID]->Solution->DynaVars.h) < 3.0) + voltagechangesolution = 0.0; + else + { + if(FVpuSolutionIdx == 1) + voltagechangesolution = withj.FVpuSolution[1] - withj.FVpuSolution[2]; + else + { + if(FVpuSolutionIdx == 2) + voltagechangesolution = withj.FVpuSolution[2] - withj.FVpuSolution[1]; + } + } + PBase = min(withj.FkVArating, withj.FDCkWRated); // Should include DC-to-AC and kW-to-KVA ratios to avoid to quick fix like this + withj.QDesireWVpu = Fwattvar_curve->GetYValue_(withj.FDCkW * withj.FEffFactor * withj.FpctDCkWRated / PBase); +} + +void TInvControlObj::CalcQAVR_desiredpu(int j, int ActorID) +{ + double voltagechangesolution = 0.0; + double DQ = 0.0; + double QPresentpu = 0.0; + double DQmax = 0.0; + double DeltaV = 0.0; + double V = 0.0; + auto& withj = CtrlVars[j]; + + DQmax = 0.1 * withj.Fkvarlimit / withj.QHeadRoomNeg; + withj.QDesireAVRpu = 0.0; + +// if (((Fv_setpoint - FAvgpVpuPrior[j]) > 0) and (ActiveCircuit[ActorID].Solution.ControlIteration = 3)) then +// Fpresentkvar[j] := 0 //abs(Fpresentkvar[j]) +// else +// Fpresentkvar[j] := 0; //-1 * abs(Fpresentkvar[j]); + +// if (ActiveCircuit[ActorID].Solution.ControlIteration = 3) then +// begin +// Fpresentkvar[j] := 0; //abs(Fpresentkvar[j]) +// if (((Fv_setpoint - FAvgpAVRVpuPrior[j]) > 0)) then +// Fpresentkvar[j] := abs(Fpresentkvar[j]) +// else +// Fpresentkvar[j] := -1 * abs(Fpresentkvar[j]); +// +// end; + if(withj.Fpresentkvar >= 0.0) + QPresentpu = withj.Fpresentkvar / withj.QHeadRoom; + else + QPresentpu = withj.Fpresentkvar / withj.QHeadRoomNeg; + if(ActiveCircuit[ActorID]->Solution->ControlIteration == 3) + { + V = withj.FAvgpAVRVpuPrior; + QPresentpu = 0.0; + withj.QOldAVR = 0.0; + } + else + V = withj.FPresentVpu; + voltagechangesolution = 0.0; + + // for first two seconds, keep voltagechangesolution equal to zero + // we don't have solutions from the time-series power flow, yet + if((ActiveCircuit[ActorID]->Solution->DynaVars.dblHour * 3600.0 / ActiveCircuit[ActorID]->Solution->DynaVars.h) < 3.0) + voltagechangesolution = 0.0; + else + { + if(FVpuSolutionIdx == 1) + voltagechangesolution = withj.FVpuSolution[1] - withj.FVpuSolution[2]; + else + { + if(FVpuSolutionIdx == 2) + voltagechangesolution = withj.FVpuSolution[2] - withj.FVpuSolution[1]; + } + +// if (abs(FPresentVpu[j] - FAvgpVpuPrior[j]) = FVoltageChangeTolerance) then DQ := 0.0 +// else if Fv_setpoint <= FPresentVpu[j] then DQ := - abs((Fv_setpoint - FPresentVpu[j] / QHeadRoom[j]) * (QPresentpu - Fkvarlimitneg[j]) / (FPresentVpu[j] - FAvgpVpuPrior[j])) +// else DQ := abs((Fv_setpoint - FPresentVpu[j]) * (QPresentpu - Fkvarlimit[j] / QHeadRoomNeg[j]) / (FPresentVpu[j] - FAvgpVpuPrior[j])); +// +// If (DQ > Fkvarlimit[j] / QHeadRoom[j]) then DQ := Fkvarlimit[j] / QHeadRoom[j] +// else if (DQ > Fkvarlimitneg[j] / QHeadRoomNeg[j]) then DQ := - Fkvarlimitneg[j] / QHeadRoomNeg[j]; +// +// QDesireAVRpu[j] := QPresentpu + DQ; + } + DeltaV = Abs( (Fv_setpoint - withj.FAvgpVpuPrior)); + if((Abs( DeltaV) < 0.005) && (withj.FdeltaQFactor > 0.2)) + withj.FdeltaQFactor = withj.FdeltaQFactor + 0.1; + else + { + if((Abs( DeltaV) < 0.02) && (withj.FdeltaQFactor > 0.2)) + withj.FdeltaQFactor = withj.FdeltaQFactor + 0.05; + else + { + if((Abs( DeltaV) > 0.02) && (withj.FdeltaQFactor < 0.9)) + withj.FdeltaQFactor = withj.FdeltaQFactor - 0.05; + else + { + if((Abs( DeltaV) < 0.05) && (withj.FdeltaQFactor < 0.9)) + withj.FdeltaQFactor = withj.FdeltaQFactor - 0.1; + } + } + } + withj.FdeltaQFactor = 0.2; + withj.DeltaV_old = Abs( (withj.FPresentVpu - withj.FAvgpVpuPrior)); + if(withj.FPresentVpu - withj.FAvgpVpuPrior == 0) + DQ = 0; + else + DQ = withj.FdeltaQFactor * withj.DQDV * (Fv_setpoint - V); + if(Abs( DQ) > DQmax) + { + if(DQ < 0.0) + DQ = -DQmax; + else + DQ = DQmax; + } + withj.QDesireAVRpu = QPresentpu + DQ; +} + +void TInvControlObj::CalcQWPcurve_desiredpu(int j, int ActorID) +{ + double voltagechangesolution = 0.0; + double P = 0.0; + bool PF_Priority = false; + double QDesiredWP = 0.0; + auto& withj = CtrlVars[j]; + // Pbase :Double; + withj.QDesireWPpu = 0.0; + voltagechangesolution = 0.0; + + // for first two seconds, keep voltagechangesolution equal to zero + // we don't have solutions from the time-series power flow, yet + if((ActiveCircuit[ActorID]->Solution->DynaVars.dblHour * 3600.0 / ActiveCircuit[ActorID]->Solution->DynaVars.h) < 3.0) + voltagechangesolution = 0.0; + else + { + if(FVpuSolutionIdx == 1) + voltagechangesolution = withj.FVpuSolution[1] - withj.FVpuSolution[2]; + else + { + if(FVpuSolutionIdx == 2) + voltagechangesolution = withj.FVpuSolution[2] - withj.FVpuSolution[1]; + } + + // Pbase = min(FpctDCkWRated[j] / FDCkWRated[j], FkVARating[j]) + } + pf_wp_nominal = Fwattpf_curve->GetYValue_(withj.FDCkW * withj.FEffFactor * withj.FpctDCkWRated / withj.FDCkWRated); + if( ( (TNamedObject*) (withj.ControlledElement) )->Get_myPName() == myDERTypes[PVSys]) + PF_Priority = ((TPVsystemObj*) (withj.ControlledElement))->PVSystemVars.PF_Priority; + else + { + if( ( (TNamedObject*) (withj.ControlledElement) )->Get_myPName() == myDERTypes[EStorage]) + PF_Priority = ((TStorageObj*) (withj.ControlledElement))->StorageVars.PF_Priority; + } + if((withj.FPPriority == false) && (PF_Priority == false)) + P = withj.FDCkW * withj.FEffFactor * withj.FpctDCkWRated; + else + P = withj.kW_out_desired; + QDesiredWP = P * sqrt(double(1) / (pf_wp_nominal * pf_wp_nominal) - 1) * Sign(pf_wp_nominal); + if(QDesiredWP >= 0.0) + withj.QDesireWPpu = QDesiredWP / withj.QHeadRoom; + else + withj.QDesireWPpu = QDesiredWP / withj.QHeadRoomNeg; +} + +void TInvControlObj::CalcQDRC_desiredpu(int j, int ActorID) +{ + double BaseKV = 0.0; + auto& withj = CtrlVars[j]; + + withj.QDesireDRCpu = 0.0; + BaseKV = withj.FVBase / 1000.0; // It's a line-to-ground voltage + + // calculate deltaV quantity in per-unit from subtracting the rolling average + // value (in p.u.) from the present p.u. terminal voltage (average of line-ground) + // if more than one phase + if((withj.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0)) == 0.0L) + withj.deltaVDynReac = 0; + else + withj.deltaVDynReac = withj.FPresentDRCVpu - withj.FDRCRollAvgWindow->Get_AvgVal() / (BaseKV * 1000.0); + + // if below the lower deadband and deltaV quantity is non-zero then + // calculate desired pu var output. In per-unit of kva rating (also + // ampere rating), per report specifications. + if((withj.deltaVDynReac != 0) && (withj.FPresentDRCVpu < FDbVMin)) + + // if above the upper deadband and deltaV quantity is non-zero then + // calculate desired pu var output. In per-unit of kva rating (also + // ampere rating), per report specifications. + withj.QDesireDRCpu = -withj.deltaVDynReac * FArGraLowV; + else + { + if((withj.deltaVDynReac != 0) && (withj.FPresentDRCVpu > FDbVMax)) + withj.QDesireDRCpu = -withj.deltaVDynReac * FArGraHiV; + else + { + if(withj.deltaVDynReac == 0.0) + withj.QDesireDRCpu = 0.0; + } + } + if(ActiveCircuit[ActorID]->Solution->DynaVars.T == 1) + withj.QDesireDRCpu = 0.0; +} + +void TInvControlObj::Check_Qlimits_WV(int j, double Q, int ActorID) +{ + double Q_Ppriority = 0.0; + double currentkvarlimitpu = 0.0; + double currentkvarlimitnegpu = 0.0; + double FOperation = 0.0; + double Error = 0.0; + auto& withj = CtrlVars[j]; + + // Will organize this part into functions later + + // states + Error = 0; + if(ControlMode == WATTVAR) + Error = 0.005; + if(Q < - Error) + FOperation = -1.0; + else + { + if(Q > Error) + FOperation = 1.0; + else + FOperation = 0.0; + } + withj.QDesireLimitedpu = 1.0; // Not limited + currentkvarlimitpu = withj.FCurrentkvarLimit / withj.QHeadRoom; + currentkvarlimitnegpu = withj.FCurrentkvarLimitNeg / withj.QHeadRoomNeg; + if(currentkvarlimitpu > withj.QDesireLimitedpu) + currentkvarlimitpu = withj.QDesireLimitedpu; + if(currentkvarlimitnegpu > withj.QDesireLimitedpu) + currentkvarlimitnegpu = withj.QDesireLimitedpu; + + // Q curve desiredpu should be less than currentkvarlimit(neg) + if((Q > 0.0) && (Abs( Q) >= Abs( currentkvarlimitpu))) + { + FOperation = 0.2 * Sign(Q); // When kvarlimit is exceeded + withj.QDesireLimitedpu = currentkvarlimitpu * Sign(Q); + } + else + { + if((Q < 0.0) && (Abs( Q) >= Abs( currentkvarlimitnegpu))) + { + FOperation = 0.2 * Sign(Q); // When kvarlimitneg is exceeded + withj.QDesireLimitedpu = currentkvarlimitnegpu * Sign(Q); + } + + // States Flags + } + if(ControlMode == WATTVAR) + withj.FWVOperation = FOperation; +} + +void TInvControlObj::Calc_PQ_WV(int j, int ActorID) +{ + double QPratio = 0.0; + TCoeff Coeff; + double pre_S = 0.0; + double var_limit_operation_value = 0.0; + double Qbase = 0.0; + double Qbasesign = 0.0; + double PBase = 0.0; + double A = 0.0; + double B = 0.0; + double C = 0.0; + double a_line = 0.0; + double b_line = 0.0; + auto& withj = CtrlVars[j]; + + PBase = min(withj.FkVArating, withj.FDCkWRated); + if(withj.QDesiredWV >= 0.0) + { + Qbase = withj.QHeadRoom; + Qbasesign = 1.0; + } + else + { + Qbase = withj.QHeadRoomNeg; + Qbasesign = -1.0; + } + var_limit_operation_value = 0.2; + if(Abs(withj.FWVOperation) == var_limit_operation_value) + withj.PLimitEndpu = Fwattvar_curve->GetXValue(withj.QDesireEndpu); + else + withj.PLimitEndpu = 1.0; + CalcWATTVAR_vars(j, ActorID); + + // Qdesiredpu should be less than the Q avaliable under watt priority (works just for varmax) + if(sqrt(Sqr(withj.FDCkW * withj.FEffFactor * withj.FpctDCkWRated * withj.PLimitEndpu) + Sqr(withj.QDesiredWV)) > withj.FkVArating) + { + Coeff = Fwattvar_curve->GetCoefficients(withj.FDCkW * withj.FEffFactor * withj.FpctDCkWRated / PBase); + a_line = Coeff[0] * Qbase / PBase; + b_line = Coeff[1] * Qbase; + A = 1.0 + Sqr(a_line); + B = 2 * a_line * b_line; + C = Sqr(b_line) - Sqr(withj.FkVArating); + withj.PLimitEndpu = (-B + sqrt(Sqr(B) - 4.0 * A * C)) / (2 * A * PBase); + withj.QDesireEndpu = Fwattvar_curve->GetYValue_(withj.PLimitEndpu); + } + CalcWATTVAR_vars(j, ActorID); +} + +void TInvControlObj::Check_Qlimits(int j, double Q, int ActorID) +{ + double Q_Ppriority = 0.0; + double currentkvarlimitpu = 0.0; + double currentkvarlimitnegpu = 0.0; + double FOperation = 0.0; + double Error = 0.0; + auto& withj = CtrlVars[j]; + // states + Error = 0; + if(ControlMode == VOLTVAR) + Error = 0.005; + if(ControlMode == WATTPF) + Error = 0.005; + if(ControlMode == WATTVAR) + Error = 0.005; + if(ControlMode == DRC) + Error = 0.0005; + if(ControlMode == AVR) + Error = 0.005; + if(CombiControlMode == VV_DRC) + Error = 0.005; + if(CombiControlMode == VV_VW) + Error = 0.005; + if(Q < - Error) + FOperation = -1.0; + else + { + if(Q > Error) + FOperation = 1.0; + else + FOperation = 0.0; + } + withj.QDesireLimitedpu = 1.0; // Not limited + currentkvarlimitpu = withj.FCurrentkvarLimit / withj.QHeadRoom; + currentkvarlimitnegpu = withj.FCurrentkvarLimitNeg / withj.QHeadRoomNeg; + if(currentkvarlimitpu > withj.QDesireLimitedpu) + currentkvarlimitpu = withj.QDesireLimitedpu; + if(currentkvarlimitnegpu > withj.QDesireLimitedpu) + currentkvarlimitnegpu = withj.QDesireLimitedpu; + + // Q curve desiredpu should be less than currentkvarlimit(neg) + if((Q > 0.0) && (Abs( Q) >= Abs( currentkvarlimitpu))) + { + FOperation = 0.2 * Sign(Q); // When kvarlimit is exceeded + withj.QDesireLimitedpu = currentkvarlimitpu * Sign(Q); + } + else + { + if((Q < 0.0) && (Abs( Q) >= Abs( currentkvarlimitnegpu))) + { + FOperation = 0.2 * Sign(Q); // When kvarlimitneg is exceeded + withj.QDesireLimitedpu = currentkvarlimitnegpu * Sign(Q); + } + + // Qdesiredpu should be less than the Q avaliable under watt priority (works just for varmax) + } + if(withj.FPPriority && ((FReacPower_ref == "VARMAX") || (ControlMode == WATTPF))) + { + if(Q >= 0.0) + Q_Ppriority = sqrt(Sqr(withj.FkVArating) - Sqr(withj.FpresentkW)) / withj.QHeadRoom; + else + Q_Ppriority = sqrt(Sqr(withj.FkVArating) - Sqr(withj.FpresentkW)) / withj.QHeadRoomNeg; + if((Abs( Q_Ppriority) < Abs(withj.QDesireLimitedpu)) && (Abs( Q_Ppriority) < Abs( Q))) + { + FOperation = 0.6 * Sign(Q); // kVA exceeded under watt priority is considered above + if((Abs( Q) < (0.01 / 100)) || (Abs( Q_Ppriority) < EPSILON)) + FOperation = 0.0; + withj.QDesireLimitedpu = Q_Ppriority * Sign(Q); + } + } + + + // States Flags + if(ControlMode == VOLTVAR) + withj.FVVOperation = FOperation; + if(ControlMode == WATTPF) + withj.FWPOperation = FOperation; + if(ControlMode == WATTVAR) + withj.FWVOperation = FOperation; + if(ControlMode == DRC) + withj.FDRCOperation = FOperation; + if(ControlMode == AVR) + withj.FAVROperation = FOperation; + if(CombiControlMode == VV_DRC) + withj.FVVDRCOperation = FOperation; + if(CombiControlMode == VV_VW) + withj.FVVOperation = FOperation; +} + +void TInvControlObj::Calc_QHeadRoom(int j, int ActorID) +{ + auto& withj = CtrlVars[j]; + + if(FReacPower_ref == "VARAVAL") + { + if(Abs(withj.FpresentkW) < withj.FkVArating) + withj.QHeadRoom = sqrt(Sqr(withj.FkVArating) - Sqr(withj.FpresentkW)); + else + withj.QHeadRoom = 0.0; + withj.QHeadRoomNeg = withj.QHeadRoom; + } + if((FReacPower_ref == "VARMAX") || (ControlMode == WATTPF)) + { + withj.QHeadRoom = withj.Fkvarlimit; + withj.QHeadRoomNeg = withj.FkvarLimitNeg; + } + if(withj.QHeadRoom == 0.0) + withj.QHeadRoom = withj.Fkvarlimit; + if(withj.QHeadRoomNeg == 0.0) + withj.QHeadRoomNeg = withj.FkvarLimitNeg; +} + +void TInvControlObj::Change_deltaQ_factor(int ActorID, int j) +{ + double DeltaV = 0.0; + auto& withj = CtrlVars[j]; + + DeltaV = Abs( (withj.FPresentVpu - withj.FAvgpVpuPrior)); + if(withj.DeltaV_old >= 0.0) + { + if((Abs( DeltaV) > 0.8 * withj.DeltaV_old) && (withj.FdeltaQFactor > 0.2)) + withj.FdeltaQFactor = withj.FdeltaQFactor - 0.1; + else + { + if((Abs( DeltaV) > 0.6 * withj.DeltaV_old) && (withj.FdeltaQFactor > 0.2)) + withj.FdeltaQFactor = withj.FdeltaQFactor - 0.05; + else + { + if((Abs( DeltaV) < 0.2 * withj.DeltaV_old) && (withj.FdeltaQFactor < 0.9)) + withj.FdeltaQFactor = withj.FdeltaQFactor + 0.1; + else + { + if((Abs( DeltaV) < 0.4 * withj.DeltaV_old) && (withj.FdeltaQFactor < 0.9)) + withj.FdeltaQFactor = withj.FdeltaQFactor + 0.05; + } + } + } + } + withj.DeltaV_old = Abs( (withj.FPresentVpu - withj.FAvgpVpuPrior)); +} + +void TInvControlObj::Change_deltaP_factor(int ActorID, int j) +{ + double DeltaV = 0.0; + auto& withj = CtrlVars[j]; + + DeltaV = Abs( (withj.FPresentVpu - withj.FAvgpVpuPrior)); + if(withj.DeltaV_old >= 0.0) + { + if((Abs( DeltaV) > 0.9 * withj.DeltaV_old) && (withj.FdeltaPFactor > 0.2)) + withj.FdeltaPFactor = withj.FdeltaPFactor - 0.1; + else + { + if((Abs( DeltaV) > 0.8 * withj.DeltaV_old) && (withj.FdeltaPFactor > 0.1)) + withj.FdeltaPFactor = withj.FdeltaPFactor - 0.05; + else + { + if((Abs( DeltaV) < 0.2 * withj.DeltaV_old) && (withj.FdeltaPFactor < 0.9)) + withj.FdeltaPFactor = withj.FdeltaPFactor + 0.05; + else + { + if((Abs( DeltaV) < 0.1 * withj.DeltaV_old) && (withj.FdeltaPFactor < 0.9)) + withj.FdeltaPFactor = withj.FdeltaPFactor + 0.1; + } + } + } + } + withj.DeltaV_old = Abs( (withj.FPresentVpu - withj.FAvgpVpuPrior)); +} + + +//Called at end of main power flow solution loop + +void TInvControl::UpdateAll(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TInvControlObj(ElementList.Get(i)) do */ + { + auto with0 = ((TInvControlObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->UpdateInvControl(i, ActorID); + } + } +} + +void TRollAvgWindow::Add(double IncomingSampleValue, double IncomingSampleTime, double VAvgWindowLengthSec) +{ + if((sample.size() > 0) && (bufferfull)) + { + runningsumsample = runningsumsample - sample.front(); + sample.pop_front(); + if(BufferLength == 0) + { + IncomingSampleValue = 0.0; + } + sample.push_back(IncomingSampleValue); + runningsumsample = runningsumsample + IncomingSampleValue; + runningsumsampletime = runningsumsampletime - sampletime.front(); + sampletime.pop_front(); + sampletime.push_back(IncomingSampleTime); + runningsumsampletime = runningsumsampletime + IncomingSampleTime; + } + else + { + if(BufferLength == 0) + { + IncomingSampleValue = 0.0; + } + sample.push_back(IncomingSampleValue); + runningsumsample = runningsumsample + IncomingSampleValue; + sampletime.push_back(IncomingSampleTime); + runningsumsampletime = runningsumsampletime + IncomingSampleTime; + if(runningsumsampletime > VAvgWindowLengthSec) + bufferfull = true; + if(sample.size() == BufferLength) + bufferfull = true; + } +} + +TRollAvgWindow::TRollAvgWindow() + : runningsumsample(0.0), + runningsumsampletime(0.0), + BufferLength(0), + bufferfull(false) +{ + sample.clear(); + sampletime.clear(); +} + +TRollAvgWindow::~TRollAvgWindow() +{ + sample.clear(); + sampletime.clear(); + // inherited; +} + + +void TRollAvgWindow::Set_BuffLength(int Value) +{ + BufferLength = Value; +} + +double TRollAvgWindow::Get_AvgVal() +{ + double result = 0.0; + if(sample.size() == 0) + result = 0.0; + else + result = runningsumsample / sample.size(); + return result; +} + +double TRollAvgWindow::Get_AccumSec() +{ + double result = 0.0; + if(sample.size() == 0) + result = 0.0; + else + result = runningsumsampletime; + return result; +} + + + + +} // namespace InvControl + + + + + diff --git a/OpenDSSC/Controls/InvControl.h b/OpenDSSC/Controls/InvControl.h new file mode 100644 index 0000000..d77d468 --- /dev/null +++ b/OpenDSSC/Controls/InvControl.h @@ -0,0 +1,408 @@ +#ifndef InvControlH +#define InvControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Bus.h" +#include "PCElement.h" +#include "PVsystem.h" +#include "Storage.h" +#include "StorageVars.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "XYcurve.h" +#include "Dynamics.h" +#include "PointerList.h" +#include "mathutil.h" +#include "InvDynamics.h" +#include "d2c_structures.h" +#include + +class TIEEE1547Controller; + +namespace InvControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + A InvControl is a control element that is connected to a terminal of another + circuit element and sends kW and/or kvar signals to a set of PVSystem objects it controls + + A InvControl is defined by a New command: + + New InvControl.Name=myname PVSystemList = (pvsystem1 PVSystem ...) + +Notes: + WGS (11/26/2012): Using dynamic arrays for many private variables in this unit. + Although dynamic arrays begin at 0 (by definition in Delphi), + this unit is using 1 to numberelements in all for loops - the 0th + element is un-used (except for Strings) in this unit. + All dynamic arrays are set to length numberelements+1 in the appropriate dimension. + All dynamic arrays are Finalize'd in the destroy procedure. + + // Updated 9/24/2015 to allow for simultaneous modes and additional functionality +*/ +enum ERateofChangeMode {Inactive, + LPF, + RISEFALL }; + +class TRollAvgWindow : public System::TObject +{ +public: + typedef TObject inherited; +//private: + std::deque sample; + std::deque sampletime; + double runningsumsample; + double runningsumsampletime; + int BufferLength; + bool bufferfull; + double Get_AvgVal(); + double Get_AccumSec(); + void Set_BuffLength(int Value); +public: + TRollAvgWindow(); + virtual ~TRollAvgWindow(); + void Add(double IncomingSampleValue, double IncomingSampleTime, double VAvgWindowLengthSec); +}; + +class TInvControl : public ControlClass::TControlClass +{ + friend class TInvControlObj; + friend class TRollAvgWindow; +public: + typedef ControlClass::TControlClass inherited; +private: + DSSClass::TDSSClass* XY_CurveClass; +protected: + void DefineProperties(); + virtual int MakeLike(const String InvControlName); +public: + TInvControl(); + virtual ~TInvControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); + XYCurve::TXYcurveObj* GetXYCurve(const String CurveName, int InvControlMode); + void UpdateAll(int ActorID); +}; + +class TInvControlObj : public ControlElem::TControlElem +{ + friend class TInvControl; + friend class ::TIEEE1547Controller; +public: + typedef ControlElem::TControlElem inherited; +private: + int ControlMode; + int CombiControlMode; + int ControlActionHandle; + + CktElement::TDSSCktElement* MonitoredElement; // First DER element for now (the first element from ControlledElement TPointerList) + + struct TInvVars + { + int CondOffset, // Offset for monitored terminal + NPhasesDER, + NCondsDER, + FPendingChange, + FActiveVVCurve; + std::vector cBuffer; // Complex array buffer + PCElement::TPCElement* ControlledElement; + std::vector FVpuSolution; + + double FAvgpVpuPrior, + FAvgpDRCVpuPrior, + FPresentVpu, + FPresentDRCVpu, + QDesiredVV, // volt-var new set-point + QDesiredWP, // watt-pf new set-point + QDesiredWV, // watt-var new set-point + QDesiredAVR, + QOld, + QOldVV, + QOldAVR, + QOldDRC, + QOldVVDRC, + QDesiredDRC, //dynamic reactive power new set-point + QDesiredVVDRC, + QHeadRoom, /*Variables of functions that CONTROL reactive power*/ + QHeadRoomNeg, + PBase, + Qoutputpu, + QoutputVVpu, + QoutputDRCpu, + QoutputVVDRCpu, + QoutputAVRpu, + QDesireEndpu, // Q value used in the convergency algorithm + QDesireVVpu, // Q desired caculated in volt-var curve + QDesireWPpu, // Q desired caculated in watt-pf curve + QDesireWVpu, // Q desired caculated in watt-var curve + QDesireDRCpu, // Q desired from the DRC equation + QDesireAVRpu, + QDesireLimitedpu, // Calculates possible Q considering kVA (watt priority) and kvarlimit limits + QDesireOptionpu, // Calculates Q Limit considering LPF and RF + PLimitEndpu, + PLimitVWpu, + PLimitLimitedpu, + PLimitOptionpu, + deltaVDynReac, + PLimitVW, + POldVWpu, + FdeltaQFactor, + FdeltaPFactor, + DeltaV_old, + FDRCRollAvgWindowpu, + priorRollAvgWindow, + priorDRCRollAvgWindow, + FPriorWattspu, + FPriorwatts, + FPriorPLimitOptionpu, + FPriorQDesireOptionpu, + kW_out_desiredpu, + kW_out_desired, + FPriorvarspu, + FPriorvars, + /*Flags used to record function states. They are interval variables of DER*/ + FVVOperation, + FVWOperation, + FDRCOperation, + FVVDRCOperation, + FWPOperation, + FWVOperation, + FAVROperation, + FVBase, + FpresentkW, + FkVArating, + Fpresentkvar, + Fkvarlimit, + FkvarLimitNeg, + FCurrentkvarLimit, + FCurrentkvarLimitNeg, + FDCkWRated, // Pmpp for PVSystem, kWRated for Storage + FpctDCkWRated, // pctPmpp for PVSystem, pctkWRated for Storage + FEffFactor, + FDCkW, // PanelkW for PVSystem, DCkW for Storage + DQDV, // Active voltage regulation (AVR) + Fv_setpointLimited, // Active voltage regulation (AVR) + FAvgpAVRVpuPrior; // Active voltage regulation (AVR) + + TRollAvgWindow* FRollAvgWindow; + TRollAvgWindow* FDRCRollAvgWindow; + bool FlagChangeCurve, + FFlagVWOperates, // Flag enabled when volt-watt Pdesired is less than 1. So volt-watt algorithm starts to work + FVarFollowInverter, + FInverterON, + FPPriority; + + TPICtrl PICtrl; + }; + + /*Variables for voltages*/ + double FVreg; + + int FVpuSolutionIdx; + /*Variables for convergence process*/ + double FdeltaQ_factor; + double FdeltaP_factor; + + double FVoltageChangeTolerance; + double FVarChangeTolerance; + double FActivePChangeTolerance; + + /*Variables of DER element*/ + PointerList::TPointerList* FDERPointerList; + int FListSize; + TStringList FDERNameList; + + /*Variables for monitored Bus/buses*/ + TStringList FMonBusesNameList; + int FMonBusesPhase; + bool FUsingMonBuses; + std::vector FMonBuses; + int FMonBusesIndex; + std::vector FMonBusesVbase; + std::vector < vector > FMonBusesNodes; + + /*Variables for LPF and RF options*/ + ERateofChangeMode RateofChangeMode; + double FLPFTau; + double FRiseFallLimit; + /*Variables of the smart inverter functions*/ + int FVoltage_CurveX_ref; // valid values are 0: = Vref (rated), 1:= avg + String FReacPower_ref; + int FVoltwattYAxis; // 1 = %Pmpp, 0 = %Available power + + // volt-var + int Fvvc_curve_size; // length of the individual curve + XYCurve::TXYcurveObj* Fvvc_curve; + String Fvvc_curvename; + double Fvvc_curveOffset; + XYCurve::TXYcurveObj* Fvvc_curve2; + + double FVAvgWindowLengthSec; // rolling average window length in seconds + + int FRollAvgWindowLength; + + String FRollAvgWindowLengthIntervalUnit; + + // watt-pf + int Fwattpf_curve_size; + XYCurve::TXYcurveObj* Fwattpf_curve; + String Fwattpf_curvename; + double pf_wp_nominal; + + // watt-var + int Fwattvar_curve_size; + XYCurve::TXYcurveObj* Fwattvar_curve; + String Fwattvar_curvename; + + // DRC + double FDbVMin; + double FDbVMax; + double FArGraLowV; + double FArGraHiV; + + int FDRCRollAvgWindowLength; + String FDRCRollAvgWindowLengthIntervalUnit; + + double FDRCVAvgWindowLengthSec; // rolling average window length in seconds + + // volt-watt + int Fvoltwatt_curve_size; + XYCurve::TXYcurveObj* Fvoltwatt_curve; + String Fvoltwatt_curvename; + + // volt-watt (charging) + int FvoltwattCH_curve_size; + XYCurve::TXYcurveObj* FvoltwattCH_curve; + String FvoltwattCH_curvename; + int CtrlModel; + std::vector CtrlVars; + // Active voltage regulation (AVR) + double Fv_setpoint; + + /*Functions and Procedures*/ + void Set_PendingChange(int Value, int DevIndex); + int Get_PendingChange(int DevIndex); + int InterpretAvgVWindowLen(const String s); + int InterpretDRCAvgVWindowLen(const String s); + String ReturnElementsList(); + void UpdateInvControl(int i, int ActorID); + void UpdateDERParameters(int i); + void CalcVoltWatt_watts(int j, int ActorID); + void CalcQVVcurve_desiredpu(int j, int ActorID); + void CalcQWPcurve_desiredpu(int j, int ActorID); + void CalcQWVcurve_desiredpu(int j, int ActorID); + void CalcQDRC_desiredpu(int j, int ActorID); + void CalcQAVR_desiredpu(int j, int ActorID); + void Check_Qlimits(int j, double Q, int ActorID); + void Check_Qlimits_WV(int j, double Q, int ActorID); + void Calc_PQ_WV(int j, int ActorID); + void Calc_QHeadRoom(int j, int ActorID); + void CalcVoltVar_vars(int j, int ActorID); + void CalcAVR_vars(int j, int ActorID); + void CalcWATTPF_vars(int j, int ActorID); + void CalcWATTVAR_vars(int j, int ActorID); + void CalcDRC_vars(int j, int ActorID); + void CalcVVDRC_vars(int j, int ActorID); + void CalcLPF(int m, String powertype, double LPF_desiredpu, int ActorID); + void CalcRF(int m, String powertype, double RF_desiredpu, int ActorID); + void Calc_PBase(int j, int ActorID); + void Check_Plimits(int j, double P, int ActorID); + void CalcPVWcurve_limitpu(int j, int ActorID); + void GetmonVoltage(int ActorID, double& Vpresent, int i, double BaseKV); + void Change_deltaQ_factor(int ActorID, int j); + void Change_deltaP_factor(int ActorID, int j); +protected: + virtual void Set_Enabled(bool Value); +public: + //System::TMemoryManagerState MyMemoryManagerState; + TInvControlObj(DSSClass::TDSSClass* ParClass, const String InvControlName); + virtual ~TInvControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a InvControl + + // Sample control quantities and set action times in Control Queue + virtual void sample(int ActorID); + + // do the action that is pending from last sample + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injection currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + bool MakeDERList(); + virtual String GetPropertyValue(int Index); + + int get_ControlMode(); + int get_CombiControlMode(); + int get_FVoltage_CurveX_ref(); + int get_FRollAvgWindowLength(); + int get_FDRCRollAvgWindowLength(); + int get_FMonBusesPhase(); + int get_FVoltwattYAxis(); + + TStringList* get_FDERNameList(); + TStringList* get_FMonBusesNameList(); + + String get_Fvvc_curvename(); + String get_Fvoltwatt_curvename(); + String get_FvoltwattCH_curvename(); + String get_FReacPower_ref(); + + double get_Fvvc_curveOffset(); + double get_FDbVMin(); + double get_FDbVMax(); + double get_FArGraLowV(); + double get_FArGraHiV(); + double get_FdeltaQ_factor(); + double get_FVoltageChangeTolerance(); + double get_FVarChangeTolerance(); + double get_FLPFTau(); + double get_FRiseFallLimit(); + double get_FdeltaP_factor(); + double get_FActivePChangeTolerance(); + double get_Fv_setpoint(); + pDoubleArray get_FMonBusesVbase(); + + + + + /*Properties that give access to this Class variables*/ + //property RateofChangeMode : String read + //property EventLog : String read + + // Need to include the new modes here + TInvControlObj(DSSClass::TDSSClass* ParClass); + TInvControlObj(String ClassName); + TInvControlObj(); +}; +extern TInvControlObj* ActiveInvControlObj; + + +} // namespace InvControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace InvControl; +#endif + +#endif // InvControlH + + + + + diff --git a/OpenDSSC/Controls/Recloser.cpp b/OpenDSSC/Controls/Recloser.cpp new file mode 100644 index 0000000..ade8605 --- /dev/null +++ b/OpenDSSC/Controls/Recloser.cpp @@ -0,0 +1,1054 @@ + +#pragma hdrstop + +#include "Recloser.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace TCC_Curve; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Recloser +{ + +TRecloserObj::TRecloserObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TRecloserObj::TRecloserObj(String ClassName) : inherited(ClassName) {} +TRecloserObj::TRecloserObj() {} + + +TRecloserObj* ActiveRecloserObj = nullptr; +TRecloser* RecloserClass = nullptr; +const int NumPropsThisClass = 24; +const int Current = 0; /*Default*/ +const int VOLTAGE = 1; +const int REVPOWER = 3; +TDSSClass* TCC_CurveClass = nullptr; + +/*General Module Function*/ + +TTCC_CurveObj* GetTccCurve(const String CurveName) +{ + TTCC_CurveObj* result = nullptr; + result = ((TTCC_CurveObj*) TCC_CurveClass->Find(CurveName)); + if(result == nullptr) + DoSimpleMsg(String("TCC Curve object: \"") + CurveName + "\" not found.", 388); + return result; +} + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all Recloser objects + +TRecloser::TRecloser() +{ + ; + Class_Name = "Recloser"; + DSSClassType = DSSClassType + RECLOSER_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + TCC_CurveClass = (TDSSClass*)GetDSSClassPtr("TCC_Curve"); + RecloserClass = this; +} + +/*--------------------------------------------------------------------------*/ + +TRecloser::~TRecloser() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TRecloser::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "MonitoredObj"; + PropertyName[2 - 1] = "MonitoredTerm"; + PropertyName[3 - 1] = "SwitchedObj"; + PropertyName[4 - 1] = "SwitchedTerm"; + PropertyName[5 - 1] = "NumFast"; + PropertyName[6 - 1] = "PhaseFast"; + PropertyName[7 - 1] = "PhaseDelayed"; + PropertyName[8 - 1] = "GroundFast"; + PropertyName[9 - 1] = "GroundDelayed"; + PropertyName[10 - 1] = "PhaseTrip"; + PropertyName[11 - 1] = "GroundTrip"; + PropertyName[12 - 1] = "PhaseInst"; + PropertyName[13 - 1] = "GroundInst"; + PropertyName[14 - 1] = "Reset"; + PropertyName[15 - 1] = "Shots"; + PropertyName[16 - 1] = "RecloseIntervals"; + PropertyName[17 - 1] = "Delay"; + PropertyName[18 - 1] = "Action"; + PropertyName[19 - 1] = "TDPhFast"; + PropertyName[20 - 1] = "TDGrFast"; + PropertyName[21 - 1] = "TDPhDelayed"; + PropertyName[22 - 1] = "TDGrDelayed"; + PropertyName[23 - 1] = "Normal"; + PropertyName[24 - 1] = "State"; + PropertyHelp[1 - 1] = "Full object name of the circuit element, typically a line, transformer, load, or generator, " + "to which the Recloser's PT and/or CT are connected." + " This is the \"monitored\" element. " + "There is no default; must be specified."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the Recloser is connected. " + "1 or 2, typically. Default is 1."; + PropertyHelp[3 - 1] = "Name of circuit element switch that the Recloser controls. " + "Specify the full object name." + "Defaults to the same as the Monitored element. " + "This is the \"controlled\" element."; + PropertyHelp[4 - 1] = "Number of the terminal of the controlled element in which the switch is controlled by the Recloser. " + "1 or 2, typically. Default is 1."; + PropertyHelp[5 - 1] = "Number of Fast (fuse saving) operations. Default is 1. (See \"Shots\")"; + PropertyHelp[6 - 1] = "Name of the TCC Curve object that determines the Phase Fast trip. Must have been previously defined as a TCC_Curve object." + " Default is \"A\". " + "Multiplying the current values in the curve by the \"phasetrip\" value gives the actual current."; + PropertyHelp[7 - 1] = "Name of the TCC Curve object that determines the Phase Delayed trip. Must have been previously defined as a TCC_Curve object." + " Default is \"D\"." + "Multiplying the current values in the curve by the \"phasetrip\" value gives the actual current."; + PropertyHelp[8 - 1] = "Name of the TCC Curve object that determines the Ground Fast trip. Must have been previously defined as a TCC_Curve object." + " Default is none (ignored). " + "Multiplying the current values in the curve by the \"groundtrip\" value gives the actual current."; + PropertyHelp[9 - 1] = "Name of the TCC Curve object that determines the Ground Delayed trip. Must have been previously defined as a TCC_Curve object." + " Default is none (ignored)." + "Multiplying the current values in the curve by the \"groundtrip\" value gives the actual current."; + PropertyHelp[10 - 1] = "Multiplier or actual phase amps for the phase TCC curve. Defaults to 1.0."; + PropertyHelp[11 - 1] = "Multiplier or actual ground amps (3I0) for the ground TCC curve. Defaults to 1.0."; + PropertyHelp[12 - 1] = "Actual amps for instantaneous phase trip which is assumed to happen in 0.01 sec + Delay Time. Default is 0.0, which signifies no inst trip. "; + PropertyHelp[13 - 1] = "Actual amps for instantaneous ground trip which is assumed to happen in 0.01 sec + Delay Time.Default is 0.0, which signifies no inst trip."; + PropertyHelp[14 - 1] = "Reset time in sec for Recloser. Default is 15. "; + PropertyHelp[15 - 1] = "Total Number of fast and delayed shots to lockout. Default is 4. This is one more than the number of reclose intervals."; + PropertyHelp[16 - 1] = "Array of reclose intervals. Default for Recloser is (0.5, 2.0, 2.0) seconds. " + "A locked out Recloser must be closed manually (action=close)."; + PropertyHelp[17 - 1] = "Fixed delay time (sec) added to Recloser trip time. Default is 0.0. Used to represent breaker time or any other delay."; + PropertyHelp[18 - 1] = "DEPRECATED. See \"State\" property"; + PropertyHelp[19 - 1] = "Time dial for Phase Fast trip curve. Multiplier on time axis of specified curve. Default=1.0."; + PropertyHelp[20 - 1] = "Time dial for Ground Fast trip curve. Multiplier on time axis of specified curve. Default=1.0."; + PropertyHelp[21 - 1] = "Time dial for Phase Delayed trip curve. Multiplier on time axis of specified curve. Default=1.0."; + PropertyHelp[22 - 1] = "Time dial for Ground Delayed trip curve. Multiplier on time axis of specified curve. Default=1.0."; + PropertyHelp[23 - 1] = "{Open | Closed} Normal state of the recloser. The recloser reverts to this state for reset, change of mode, etc. " + "Defaults to \"State\" if not specificallt declared."; + PropertyHelp[24 - 1] = "{Open | Closed} Actual state of the recloser. Upon setting, immediately forces state of the recloser, overriding the Recloser control. " + "Simulates manual control on recloser. Defaults to Closed. \"Open\" causes the controlled element to open and lock out. \"Closed\" causes the " + "controlled element to close and the recloser to reset to its first operation."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TRecloser::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Recloser and add it to Recloser class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TRecloserObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} +/*--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ + +int TRecloser::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + + // continue parsing WITH contents of Parser + ActiveRecloserObj = (TRecloserObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveRecloserObj); + result = 0; + /*# with ActiveRecloserObj do */ + { + auto with0 = ActiveRecloserObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer, Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 390); + break; + case 1: + with0->MonitoredElementName = LowerCase(Param); + break; + case 2: + with0->MonitoredElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->ElementName = LowerCase(Param); + break; + case 4: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 5: + with0->NumFast = Parser[ActorID]->MakeInteger_(); + break; + case 6: + with0->PhaseFast = GetTccCurve(Param); + break; + case 7: + with0->PhaseDelayed = GetTccCurve(Param); + break; + case 8: + with0->GroundFast = GetTccCurve(Param); + break; + case 9: + with0->GroundDelayed = GetTccCurve(Param); + break; + case 10: + with0->PhaseTrip = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->GroundTrip = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->PhaseInst = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->GroundInst = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->ResetTime = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->NumReclose = Parser[ActorID]->MakeInteger_() - 1; + break; // one less than number of shots + case 16: + with0->NumReclose = Parser[ActorID]->ParseAsVector(4, with0->RecloseIntervals); + break; // max of 4 allowed + case 17: + with0->DelayTime = Parser[ActorID]->MakeDouble_(); + break; + case 19: + with0->TDPhFast = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->TDGrFast = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->TDPhDelayed = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->TDGrDelayed = Parser[ActorID]->MakeDouble_(); + break; + case 23: + { + with0->InterpretRecloserState(ActorID, Param, ParamName); // set normal state + if(!with0->NormalStateSet) + with0->NormalStateSet = true; + } + break; + case 18: case 24: + with0->InterpretRecloserState(ActorID, Param, ParamName); + break; // set state + + // Inherited parameters + default: + ClassEdit(ActiveRecloserObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: + /*Default the controlled element to the monitored element*/ + with0->ElementName = with0->MonitoredElementName; + break; + case 2: + with0->ElementTerminal = with0->MonitoredElementTerminal; + break; + case 18: case 24: + if(!with0->NormalStateSet) + { + with0->NormalStateSet = true; // normal state will default to state only the 1st state is specified. + with0->set_NormalState(with0->FPresentState); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TRecloser::MakeLike(const String RecloserName) +{ + int result = 0; + TRecloserObj* OtherRecloser = nullptr; + int i = 0; + result = 0; + /*See if we can find this Recloser name in the present collection*/ + OtherRecloser = ((TRecloserObj*) Find(RecloserName)); + if(OtherRecloser != nullptr) + /*# with ActiveRecloserObj do */ + { + auto with0 = ActiveRecloserObj; + int stop = 0; + with0->Set_NPhases(OtherRecloser->Fnphases); + with0->Set_Nconds(OtherRecloser->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherRecloser->ElementName; + with0->ElementTerminal = OtherRecloser->ElementTerminal; + with0->Set_ControlledElement(OtherRecloser->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherRecloser->get_FMonitoredElement()); // Pointer to target circuit element + with0->MonitoredElementName = OtherRecloser->MonitoredElementName; // Pointer to target circuit element + with0->MonitoredElementTerminal = OtherRecloser->MonitoredElementTerminal; // Pointer to target circuit element + with0->PhaseDelayed = OtherRecloser->PhaseDelayed; + with0->GroundDelayed = OtherRecloser->GroundDelayed; + with0->PhaseFast = OtherRecloser->PhaseFast; + with0->GroundFast = OtherRecloser->GroundFast; + with0->PhaseTrip = OtherRecloser->PhaseTrip; + with0->GroundTrip = OtherRecloser->GroundTrip; + with0->PhaseInst = OtherRecloser->PhaseInst; + with0->GroundInst = OtherRecloser->GroundInst; + with0->ResetTime = OtherRecloser->ResetTime; + with0->NumReclose = OtherRecloser->NumReclose; + with0->NumFast = OtherRecloser->NumFast; + with0->RecloseIntervals = (pDoubleArray) realloc(with0->RecloseIntervals, sizeof(double) * 4); // Always make a max of 4 + for(stop = with0->NumReclose, i = 1; i <= stop; i++) + { + (with0->RecloseIntervals)[i - 1] = (OtherRecloser->RecloseIntervals)[i - 1]; + } + with0->LockedOut = OtherRecloser->LockedOut; + with0->FPresentState = OtherRecloser->FPresentState; + with0->set_NormalState(OtherRecloser->get_NormalState()); + with0->CondOffset = OtherRecloser->CondOffset; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherRecloser->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Recloser MakeLike: \"") + RecloserName + + "\" Not Found.", 391); + return result; +} + + + + +/*==========================================================================*/ +/* TRecloserObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TRecloserObj::TRecloserObj(TDSSClass* ParClass, const String RecloserName) + : inherited(ParClass), + PhaseDelayed(GetTccCurve("d")), + GroundDelayed(nullptr), + PhaseFast(nullptr), + GroundFast(nullptr), + ResetTime(0.0), + DelayTime(0.0), + TDGrDelayed(0.0), + TDPhDelayed(0.0), + TDGrFast(0.0), + TDPhFast(0.0), + OperationCount(0), + LockedOut(false), + ArmedForClose(false), + ArmedForOpen(false), + GroundTarget(false), + PhaseTarget(false), + NormalStateSet(false), + CondOffset(0), + cBuffer(nullptr), + RecloseIntervals(nullptr), + NumFast(0), + NumReclose(0), + MonitoredElementTerminal(0), + PhaseTrip(0.0), + GroundTrip(0.0), + PhaseInst(0.0), + GroundInst(0.0) +{ + Set_Name(LowerCase(RecloserName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + MonitoredElementName = ""; + MonitoredElementTerminal = 1; + Set_MonitoredElement(nullptr); + PhaseFast = GetTccCurve("a"); + GroundFast = nullptr; + PhaseTrip = 1.0; + GroundTrip = 1.0; + PhaseInst = 0.0; + GroundInst = 0.0; + TDGrDelayed = 1.0; + TDPhDelayed = 1.0; + TDGrFast = 1.0; + TDPhFast = 1.0; + ResetTime = 15.0; + NumReclose = 3; + NumFast = 1; + RecloseIntervals = nullptr; + RecloseIntervals = new double[4]; // fixed allocation of 4 + (RecloseIntervals)[1 - 1] = 0.5; + (RecloseIntervals)[2 - 1] = 2.0; + (RecloseIntervals)[3 - 1] = 2.0; + FPresentState = CTRL_CLOSE; + FNormalState = CTRL_CLOSE; + NormalStateSet = false; + OperationCount = 1; + LockedOut = false; + ArmedForOpen = false; + ArmedForClose = false; + GroundTarget = false; + PhaseTarget = false; + cBuffer = nullptr; // Complex buffer + DSSObjType = ParClass->DSSClassType; //cap_CONTROL; + InitPropertyValues(0); + + + + // RecalcElementData; +} + +TRecloserObj::~TRecloserObj() +{ + MonitoredElementName = ""; + free(RecloseIntervals); + free(cBuffer); + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + DevIndex = GetCktElementIndex(MonitoredElementName); // Global function + if(DevIndex > 0) + { + Set_MonitoredElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); // Force number of phases to be same + if(MonitoredElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("Recloser: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 392); + } + else + + // Sets name of i-th terminal's connected bus in Recloser's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(MonitoredElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer = (pComplexArray) realloc(cBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + CondOffset = (MonitoredElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + } + +/*Check for existence of Controlled Element*/ + + // If previously assigned, reset HasOCPDevice flag in case this is a move + if(ASSIGNED(get_FControlledElement())) + { + get_FControlledElement()->HasOCPDevice = false; + get_FControlledElement()->HasAutoOCPDevice = false; + } + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Both CktElement and monitored element must already exist + { + Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Make the 1 st terminal active + + // If the recloser becomes disabled, leave at False + if(Get_Enabled()) + { + get_FControlledElement()->HasOCPDevice = true; // For Reliability calcs + get_FControlledElement()->HasAutoOCPDevice = true; // For Reliability calcs + } + if(FPresentState == CTRL_CLOSE) // Open/Close State of controlled element based on state assigned to the control + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); + LockedOut = false; + OperationCount = 1; + ArmedForOpen = false; + } + else + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); + LockedOut = true; + OperationCount = NumReclose + 1; + ArmedForClose = false; + } + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("Recloser: \"") + this->get_Name() + "\"", String("CktElement Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 393); + } +} + +void TRecloserObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer = (pComplexArray) realloc(cBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + /*# with ControlledElement do */ + { + auto with0 = get_FControlledElement(); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal of CktElement to terminal 1 + switch(Code) + { + case ( CTRL_OPEN): + switch(FPresentState) + { + case CTRL_CLOSE: + if(ArmedForOpen) // ignore if we became disarmed in meantime + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); // Open all phases of active terminal + if(OperationCount > NumReclose) + { + LockedOut = true; + AppendToEventLog(String("Recloser.") + this->get_Name(), "Opened, Locked Out", ActorID); + } + else + { + if(OperationCount > NumFast) + AppendToEventLog(String("Recloser.") + this->get_Name(), "Opened, Delayed", ActorID); + else + AppendToEventLog(String("Recloser.") + this->get_Name(), "Opened, Fast", ActorID); + } + if(PhaseTarget) + AppendToEventLog(" ", "Phase Target", ActorID); + if(GroundTarget) + AppendToEventLog(" ", "Ground Target", ActorID); + ArmedForOpen = false; + } + break; /*nada*/ + default: + ; + break; + } + break; + case ( CTRL_CLOSE): + switch(FPresentState) + { + case CTRL_OPEN: + if(ArmedForClose && !LockedOut) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); // Close all phases of active terminal + ++OperationCount; + AppendToEventLog(String("Recloser.") + this->get_Name(), "Closed", ActorID); + ArmedForClose = false; + } + break; /*Nada*/ + default: + ; + break; + } + break; + case ( CTRL_RESET): + switch(FPresentState) + { + case CTRL_CLOSE: + if(!ArmedForOpen) + OperationCount = 1; + break; // Don't reset if we just rearmed + /*Nada*/ + default: + ; + break; + } + break; + /*Do Nothing */ + default: + ; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::InterpretRecloserState(int ActorID, const String Action, const String property_name) +{ + if((LowerCase(&(property_name[0])) == "s") || (LowerCase(&(property_name[0])) == "a")) // state or action (deprecated) + { + switch(LowerCase(Action)[0]) + { + case L'o': + case L't': + FPresentState = CTRL_OPEN; + break; + case L'c': + FPresentState = CTRL_CLOSE; + break; + default: + ; + break; + } + } + else + // Normal + { + switch(LowerCase(Action)[0]) + { + case L'o': + case L't': + FNormalState = CTRL_OPEN; + break; + case L'c': + FNormalState = CTRL_CLOSE; + break; + default: + ; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::sample(int ActorID) +{ + int i = 0; + double cmag = 0.0; + complex Csum = {}; + TTCC_CurveObj* GroundCurve = nullptr; + TTCC_CurveObj* PhaseCurve = nullptr; + double Groundtime = 0.0; + double PhaseTime = 0.0; + double TripTime = 0.0; + double TimeTest = 0.0; + double TDPhase = 0.0; + double TDGround = 0.0; + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + if(get_FControlledElement()->Get_ConductorClosed(0, ActorID)) + FPresentState = CTRL_CLOSE; + else + FPresentState = CTRL_OPEN; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + if(OperationCount > NumFast) + { + GroundCurve = GroundDelayed; + PhaseCurve = PhaseDelayed; + TDGround = TDGrDelayed; + TDPhase = TDPhDelayed; + } + else + { + GroundCurve = GroundFast; + PhaseCurve = PhaseFast; + TDGround = TDGrFast; + TDPhase = TDPhFast; + } + if(FPresentState == CTRL_CLOSE) + { + TripTime = -1.0; + Groundtime = -1.0; + PhaseTime = -1.0; /*No trip*/ + + // Check largest Current of all phases of monitored element + get_FMonitoredElement()->GetCurrents(cBuffer, ActorID); + + /*Check Ground Trip, if any*/ + if(GroundCurve != nullptr) + { + int stop = 0; + Csum = CZero; + for(stop = (with0->Fnphases + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + caccum(Csum, (cBuffer)[i - 1]); + } + cmag = cabs(Csum); + if((GroundInst > 0.0) && (cmag >= GroundInst) && (OperationCount == 1)) // Inst trip on first operation + Groundtime = 0.01 + DelayTime; + else + Groundtime = TDGround * GroundCurve->GetTCCTime(cmag / GroundTrip); + } + if(Groundtime > 0.0) + { + TripTime = Groundtime; + GroundTarget = true; + } + + // If GroundTime > 0 then we have a ground trip + + /*Check Phase Trip, if any*/ + if(PhaseCurve != nullptr) + { + int stop = 0; + for(stop = (with0->Fnphases + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + cmag = cabs((cBuffer)[i - 1]); + if((PhaseInst > 0.0) && (cmag >= PhaseInst) && (OperationCount == 1)) + { + PhaseTime = 0.01 + DelayTime; // Inst trip on first operation + break; + } + else + { + TimeTest = TDPhase * PhaseCurve->GetTCCTime(cmag / PhaseTrip); + if(TimeTest > 0.0) + { + if(PhaseTime < 0.0) + PhaseTime = TimeTest; + else + PhaseTime = min(PhaseTime, TimeTest); + } + } + } + } + // If PhaseTime > 0 then we have a phase trip + if(PhaseTime > 0.0) + { + PhaseTarget = true; + if(TripTime > 0.0) + TripTime = min(TripTime, PhaseTime); + else + TripTime = PhaseTime; + } + if(TripTime > 0.0) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // Then arm for an open operation + ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + DelayTime, CTRL_OPEN, 0, this, ActorID); + if(OperationCount <= NumReclose) + ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + DelayTime + (RecloseIntervals)[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + ArmedForOpen = true; + ArmedForClose = true; + } + } + else + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // If current dropped below pickup, disarm trip and set for reset + ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + ArmedForClose = false; + GroundTarget = false; + PhaseTarget = false; + } + } + } /*IF PresentState=CLOSE*/ + } /*With*/ +} + + + +/*--------------------------------------------------------------------------*/ + +void TRecloserObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +String TRecloserObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + result = ""; + switch(Index) + { + case 15: + result = Format("%d", NumReclose + 1); + break; + case 16: + { + int stop = 0; + result = "("; + for(stop = NumReclose, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", (RecloseIntervals)[i - 1]); + } + result = result + ")"; + } + break; + case 23: + { + switch(FNormalState) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "closed"; + break; + } + } + break; + case 18: + case 24: + { + switch(FPresentState) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "closed"; + break; + } + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TRecloserObj::Reset(int ActorID) +{ + FPresentState = FNormalState; + ArmedForOpen = false; + ArmedForClose = false; + GroundTarget = false; + PhaseTarget = false; + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(FNormalState) + { + case CTRL_OPEN: + { + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); // Open all phases of active terminal + LockedOut = true; + OperationCount = NumReclose + 1; + } + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); // Close all phases of active terminal + LockedOut = false; + OperationCount = 1; + break; + } + } +} + +EControlAction TRecloserObj::get_State() +{ + EControlAction result; + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + if(get_FControlledElement()->Get_ConductorClosed(0, ActiveActor)) { + FPresentState = CTRL_CLOSE; + } else { + FPresentState = CTRL_OPEN; + } + } + result = FPresentState; + return result; +} + +void TRecloserObj::set_State(const EControlAction Value) +{ + if(get_State() != Value) + { + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(Value) + { + case CTRL_OPEN: + { + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); + LockedOut = true; + OperationCount = NumReclose + 1; + ArmedForClose = false; + } + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); + LockedOut = false; + OperationCount = 1; + ArmedForOpen = false; + break; + } + } + FPresentState = Value; + } +} + +EControlAction TRecloserObj::get_NormalState() +{ + EControlAction result; + result = FNormalState; + return result; +} + +void TRecloserObj::set_NormalState(const EControlAction Value) +{ + if(FNormalState != Value) + { + FNormalState = Value; + } +} + +void TRecloserObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,""); + Set_PropertyValue(4,"1"); //'terminal'; + Set_PropertyValue(5,IntToStr(NumFast)); + Set_PropertyValue(6,""); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,""); + Set_PropertyValue(10,"1.0"); + Set_PropertyValue(11,"1.0"); + Set_PropertyValue(12,"0"); + Set_PropertyValue(13,"0"); + Set_PropertyValue(14,"15"); + Set_PropertyValue(15,"4"); + Set_PropertyValue(16,"(0.5, 2.0, 2.0)"); + Set_PropertyValue(17,"0.0"); + Set_PropertyValue(18,"closed"); + Set_PropertyValue(19,"1.0"); + Set_PropertyValue(20,"1.0"); + Set_PropertyValue(21,"1.0"); + Set_PropertyValue(22,"1.0"); + Set_PropertyValue(23,"closed"); + Set_PropertyValue(24,"closed"); + inherited::InitPropertyValues(NumPropsThisClass); +} + + + + +} // namespace Recloser + + + + + diff --git a/OpenDSSC/Controls/Recloser.h b/OpenDSSC/Controls/Recloser.h new file mode 100644 index 0000000..0c791f1 --- /dev/null +++ b/OpenDSSC/Controls/Recloser.h @@ -0,0 +1,146 @@ +#ifndef RecloserH +#define RecloserH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlActionsDefs.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "TCC_Curve.h" +#include +#include "d2c_structures.h" + +namespace Recloser +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Created 11-1-00 from Relay Control + + +*/ +/* + A Recloser is a control element that is connected to a terminal of a + circuit element and controls the switches in the same or another terminal. + + The control is usually placed in the + terminal of a line or transformer, but it could be any element + + CktElement to be controlled must already exist. + + 7-18-2002 Fixed typos in help + 5-1-2006 Added Time Delays to be compatible with relays + +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRecloser : public ControlClass::TControlClass +{ + friend class TRecloserObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String RecloserName); +public: + TRecloser(); + virtual ~TRecloser(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRecloserObj : public ControlElem::TControlElem +{ + friend class TRecloser; +public: + typedef ControlElem::TControlElem inherited; +//private: + TCC_Curve::TTCC_CurveObj* PhaseDelayed; + TCC_Curve::TTCC_CurveObj* GroundDelayed; + TCC_Curve::TTCC_CurveObj* PhaseFast; + TCC_Curve::TTCC_CurveObj* GroundFast; + double ResetTime; + double DelayTime; + double TDGrDelayed; + double TDPhDelayed; + double TDGrFast; + double TDPhFast; + EControlAction FPresentState; + EControlAction FNormalState; + int OperationCount; + bool LockedOut; + bool ArmedForClose; + bool ArmedForOpen; + bool GroundTarget; + bool PhaseTarget; + bool NormalStateSet; + int CondOffset; // Offset for monitored terminal + Ucomplex::pComplexArray cBuffer; // Complexarray buffer + void InterpretRecloserState(int ActorID, const String Action, const String property_name); + EControlAction get_State(); + void set_State(const EControlAction Value); + EControlAction get_NormalState(); + void set_NormalState(const EControlAction Value); +public: + Arraydef::pDoubleArray RecloseIntervals; + int NumFast; + int NumReclose; + String MonitoredElementName; + int MonitoredElementTerminal; + double PhaseTrip; + double GroundTrip; + double PhaseInst; + double GroundInst; + TRecloserObj(DSSClass::TDSSClass* ParClass, const String RecloserName); + virtual ~TRecloserObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a Recloser + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TRecloserObj(DSSClass::TDSSClass* ParClass); + TRecloserObj(String ClassName); + TRecloserObj(); +}; +extern TRecloserObj* ActiveRecloserObj; +extern TRecloser* RecloserClass; + + +/*--------------------------------------------------------------------------*/ + + +} // namespace Recloser + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Recloser; +#endif + +#endif // RecloserH + + + + + diff --git a/OpenDSSC/Controls/RegControl.cpp b/OpenDSSC/Controls/RegControl.cpp new file mode 100644 index 0000000..01e9d93 --- /dev/null +++ b/OpenDSSC/Controls/RegControl.cpp @@ -0,0 +1,1691 @@ + +#pragma hdrstop + +#include "RegControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "CktElement.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" +#include "AutoTrans.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Transformer; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace RegControl +{ + +TRegControlObj::TRegControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TRegControlObj::TRegControlObj(String ClassName) : inherited(ClassName) {} +TRegControlObj::TRegControlObj() {} + + +TRegControlObj* ActiveRegControlObj = nullptr; +const int AVGPHASES = -1; +const int MAXPHASE = -2; +const int MINPHASE = -3; +const int ACTION_TAPCHANGE = 0; +const int ACTION_REVERSE = 1; +const int NumPropsThisClass = 32; +std::vector LastChange; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all RegControl objects + +TRegControl::TRegControl() +{ + int i = 0; + ; + Class_Name = "RegControl"; + DSSClassType = DSSClassType + REG_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + LastChange.resize(CPU_Cores + 1); + for(int stop = CPU_Cores, i = 0; i <= stop; i++) + { + LastChange[i] = 0; + } +} + +/*--------------------------------------------------------------------------*/ + +TRegControl::~TRegControl() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TRegControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "transformer"; + PropertyName[2 - 1] = "winding"; + PropertyName[3 - 1] = "vreg"; + PropertyName[4 - 1] = "band"; + PropertyName[5 - 1] = "ptratio"; + PropertyName[6 - 1] = "CTprim"; + PropertyName[7 - 1] = "R"; + PropertyName[8 - 1] = "X"; + PropertyName[9 - 1] = "bus"; + PropertyName[10 - 1] = "delay"; + PropertyName[11 - 1] = "reversible"; + PropertyName[12 - 1] = "revvreg"; + PropertyName[13 - 1] = "revband"; + PropertyName[14 - 1] = "revR"; + PropertyName[15 - 1] = "revX"; + PropertyName[16 - 1] = "tapdelay"; + PropertyName[17 - 1] = "debugtrace"; + PropertyName[18 - 1] = "maxtapchange"; + PropertyName[19 - 1] = "inversetime"; + PropertyName[20 - 1] = "tapwinding"; + PropertyName[21 - 1] = "vlimit"; + PropertyName[22 - 1] = "PTphase"; + PropertyName[23 - 1] = "revThreshold"; + PropertyName[24 - 1] = "revDelay"; + PropertyName[25 - 1] = "revNeutral"; + PropertyName[26 - 1] = "EventLog"; + PropertyName[27 - 1] = "RemotePTRatio"; + PropertyName[28 - 1] = "TapNum"; + PropertyName[29 - 1] = "Reset"; + PropertyName[30 - 1] = "LDC_Z"; + PropertyName[31 - 1] = "rev_Z"; + PropertyName[32 - 1] = "Cogen"; + PropertyHelp[1 - 1] = String("Name of Transformer or AutoTrans element to which the RegControl is connected. " "Do not specify the full object name; \"Transformer\" or \"AutoTrans\" is assumed for " "the object class. Example:") + CRLF + + CRLF + + "Transformer=Xfmr1"; + PropertyHelp[2 - 1] = "Number of the winding of the transformer element that the RegControl is monitoring. " + "1 or 2, typically. Side Effect: Sets TAPWINDING property to the same winding."; + PropertyHelp[3 - 1] = "Voltage regulator setting, in VOLTS, for the winding being controlled. Multiplying this " + "value times the ptratio should yield the voltage across the WINDING of the controlled transformer." + " Default is 120.0"; + PropertyHelp[4 - 1] = "Bandwidth in VOLTS for the controlled bus (see help for ptratio property). Default is 3.0"; + PropertyHelp[5 - 1] = "Ratio of the PT that converts the controlled winding voltage to the regulator control voltage. " + "Default is 60. If the winding is Wye, the line-to-neutral voltage is used. Else, the line-to-line " + "voltage is used. SIDE EFFECT: Also sets RemotePTRatio property."; + PropertyHelp[6 - 1] = "Rating, in Amperes, of the primary CT rating for which the line amps convert to control rated amps." + "The typical default secondary ampere rating is 0.2 Amps (check with manufacturer specs). " + "Current at which the LDC voltages match the R and X settings."; + PropertyHelp[7 - 1] = "R setting on the line drop compensator in the regulator, expressed in VOLTS."; + PropertyHelp[8 - 1] = "X setting on the line drop compensator in the regulator, expressed in VOLTS."; + PropertyHelp[9 - 1] = "Name of a bus (busname.nodename) in the system to use as the controlled bus instead of the bus to which the " + "transformer winding is connected or the R and X line drop compensator settings. Do not specify this " + "value if you wish to use the line drop compensator settings. Default is null string. Assumes the base voltage for this " + "bus is the same as the transformer winding base specified above. " + "Note: This bus (1-phase) WILL BE CREATED by the regulator control upon SOLVE if not defined by some other device. " + "You can specify the node of the bus you wish to sample (defaults to 1). " + "If specified, the RegControl is redefined as a 1-phase device since only one voltage is used."; + PropertyHelp[10 - 1] = "Time delay, in seconds, from when the voltage goes out of band to when the tap changing begins. " + "This is used to determine which regulator control will act first. Default is 15. You may specify any " + "floating point number to achieve a model of whatever condition is necessary."; + PropertyHelp[11 - 1] = "{Yes |No*} Indicates whether or not the regulator can be switched to regulate in the reverse direction. Default is No." + "Typically applies only to line regulators and not to LTC on a substation transformer."; + PropertyHelp[12 - 1] = "Voltage setting in volts for operation in the reverse direction."; + PropertyHelp[13 - 1] = "Bandwidth for operating in the reverse direction."; + PropertyHelp[14 - 1] = "R line drop compensator setting for reverse direction."; + PropertyHelp[15 - 1] = "X line drop compensator setting for reverse direction."; + PropertyHelp[16 - 1] = "Delay in sec between tap changes. Default is 2. This is how long it takes between changes " + "after the first change."; + PropertyHelp[17 - 1] = "{Yes | No* } Default is no. Turn this on to capture the progress of the regulator model " + "for each control iteration. Creates a separate file for each RegControl named \"REG_name.CSV\"."; + PropertyHelp[18 - 1] = String("Maximum allowable tap change per control iteration in STATIC control mode. Default is 16. ") + CRLF + + CRLF + + "Set this to 1 to better approximate actual control action. " + + CRLF + + CRLF + + "Set this to 0 to fix the tap in the current position."; + PropertyHelp[19 - 1] = "{Yes | No* } Default is no. The time delay is adjusted inversely proportional to the amount the voltage is outside the band down to 10%."; + PropertyHelp[20 - 1] = "Winding containing the actual taps, if different than the WINDING property. Defaults to the same winding as specified by the WINDING property."; + PropertyHelp[21 - 1] = "Voltage Limit for bus to which regulated winding is connected (e.g. first customer). Default is 0.0. " + "Set to a value greater then zero to activate this function."; + PropertyHelp[22 - 1] = "For multi-phase transformers, the number of the phase being monitored or one of { MAX | MIN} for all phases. Default=1. " + "Must be less than or equal to the number of phases. Ignored for regulated bus."; + PropertyHelp[23 - 1] = "kW reverse power threshold for reversing the direction of the regulator. Default is 100.0 kw."; + PropertyHelp[24 - 1] = "Time Delay in seconds (s) for executing the reversing action once the threshold for reversing has been exceeded. Default is 60 s."; + PropertyHelp[25 - 1] = "{Yes | No*} Default is no. Set this to Yes if you want the regulator to go to neutral in the reverse direction or in cogen operation."; + PropertyHelp[26 - 1] = "{Yes/True* | No/False} Default is YES for regulator control. Log control actions to Eventlog."; + PropertyHelp[27 - 1] = "When regulating a bus (the Bus= property is set), the PT ratio required to convert actual voltage at the remote bus to control voltage. " + "Is initialized to PTratio property. Set this property after setting PTratio."; + PropertyHelp[28 - 1] = "An integer number indicating the tap position that the controlled transformer winding tap position is currently at, or is being set to. If being set, and the value is outside the range of the transformer min or max tap," + " then set to the min or max tap position as appropriate. Default is 0"; + PropertyHelp[29 - 1] = "{Yes | No} If Yes, forces Reset of this RegControl."; + PropertyHelp[30 - 1] = "Z value for Beckwith LDC_Z control option. Volts adjustment at rated control current."; + PropertyHelp[31 - 1] = "Reverse Z value for Beckwith LDC_Z control option."; + PropertyHelp[32 - 1] = "{Yes|No*} Default is No. The Cogen feature is activated. Continues looking forward if power " + "reverses, but switches to reverse-mode LDC, vreg and band values."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TRegControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new RegControl and add it to RegControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TRegControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TRegControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + + auto Max = [&](int A, int B) -> int + { + int result = 0; + if(A >= B) + result = A; + else + result = B; + return result; + }; + + // continue parsing WITH contents of Parser + ActiveRegControlObj = (TRegControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveRegControlObj); + result = 0; + /*# with ActiveRegControlObj do */ + { + auto with0 = ActiveRegControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 120); + break; + case 1: + with0->ElementName = String("Transformer.") + LowerCase(Param); + break; + case 2: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->Vreg = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->Bandwidth = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->PTRatio = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->CTRating = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->R = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->X = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->RegulatedBus = Param; + break; + case 10: + with0->TimeDelay = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->IsReversible = InterpretYesNo(Param); + break; + case 12: + with0->revVreg = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->revBandwidth = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->revR = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->revX = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->TapDelay = Parser[ActorID]->MakeDouble_(); + break; + case 17: + with0->DebugTrace = InterpretYesNo(Param); + break; + case 18: + with0->TapLimitPerChange = Max(0, Parser[ActorID]->MakeInteger_()); + break; + case 19: + with0->FInversetime = InterpretYesNo(Param); + break; + case 20: + with0->TapWinding = Parser[ActorID]->MakeInteger_(); + break; + case 21: + { + with0->Vlimit = Parser[ActorID]->MakeDouble_(); + if(with0->Vlimit > 0.0) + with0->VLimitActive = true; + else + with0->VLimitActive = false; + } + break; + case 22: + if(CompareTextShortest(Param, "max") == 0) + with0->FPTPhase = MAXPHASE; + else + { + if(CompareTextShortest(Param, "min") == 0) + with0->FPTPhase = MINPHASE; + else + with0->FPTPhase = Max(1, Parser[ActorID]->MakeInteger_()); + } + break; + case 23: + with0->kWRevPowerThreshold = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->revDelay = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->ReverseNeutral = InterpretYesNo(Param); + break; + case 26: + with0->ShowEventLog = InterpretYesNo(Param); + break; + case 27: + with0->RemotePTRatio = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->Set_TapNum(Parser[ActorID]->MakeInteger_()); + break; + case 29: + if(InterpretYesNo(Param)) // force a reset + { + with0->Reset(ActorID); + with0->Set_PropertyValue(29,"n"); // so it gets reported properly + } + break; + case 30: + with0->LDC_Z = Parser[ActorID]->MakeDouble_(); + break; + case 31: + with0->revLDC_Z = Parser[ActorID]->MakeDouble_(); + break; + case 32: + with0->CogenEnabled = InterpretYesNo(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveRegControlObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 2: + { + with0->TapWinding = with0->ElementTerminal; // Resets if property re-assigned + with0->Set_PropertyValue(20,Param); + } + break; + case 5: + with0->RemotePTRatio = with0->PTRatio; + break; // re-initialise RemotePTRatio whenever PTRatio is set + case 17: + if(with0->DebugTrace) + { + AssignFile(with0->Tracefile, GetOutputDirectory() + "REG_" + with0->get_Name() + ".CSV"); + Rewrite(with0->Tracefile); + IOResultToException(); + WriteLn(with0->Tracefile, "Hour, Sec, ControlIteration, Iterations, LoadMultiplier, Present Tap, Pending Change, Actual Change, Increment, Min Tap, Max Tap"); + CloseFile(with0->Tracefile); + } + break; + case 23: + with0->RevPowerThreshold = with0->kWRevPowerThreshold * 1000.0; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } /*With*/ + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TRegControl::MakeLike(const String RegControlName) +{ + int result = 0; + TRegControlObj* OtherRegControl = nullptr; + int i = 0; + result = 0; + /*See if we can find this RegControl name in the present collection*/ + OtherRegControl = ((TRegControlObj*) Find(RegControlName)); + if(OtherRegControl != nullptr) + /*# with ActiveRegControlObj do */ + { + auto with0 = ActiveRegControlObj; + int stop = 0; + with0->Set_NPhases(OtherRegControl->Fnphases); + with0->Set_Nconds(OtherRegControl->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherRegControl->ElementName; + with0->Set_ControlledElement(OtherRegControl->get_FControlledElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherRegControl->ElementTerminal; + with0->Vreg = OtherRegControl->Vreg; + with0->Bandwidth = OtherRegControl->Bandwidth; + with0->PTRatio = OtherRegControl->PTRatio; + with0->RemotePTRatio = OtherRegControl->RemotePTRatio; + with0->CTRating = OtherRegControl->CTRating; + with0->R = OtherRegControl->R; + with0->X = OtherRegControl->X; + with0->RegulatedBus = OtherRegControl->RegulatedBus; + with0->TimeDelay = OtherRegControl->TimeDelay; + with0->IsReversible = OtherRegControl->IsReversible; + with0->revVreg = OtherRegControl->revVreg; + with0->revBandwidth = OtherRegControl->revBandwidth; + with0->revR = OtherRegControl->revR; + with0->revX = OtherRegControl->revX; + with0->TapDelay = OtherRegControl->TapDelay; + with0->TapWinding = OtherRegControl->TapWinding; + with0->FInversetime = OtherRegControl->FInversetime; + with0->TapLimitPerChange = OtherRegControl->TapLimitPerChange; + with0->kWRevPowerThreshold = OtherRegControl->kWRevPowerThreshold; + with0->RevPowerThreshold = OtherRegControl->RevPowerThreshold; + with0->revDelay = OtherRegControl->revDelay; + with0->ReverseNeutral = OtherRegControl->ReverseNeutral; + with0->ShowEventLog = OtherRegControl->ShowEventLog; + // DebugTrace := OtherRegControl.DebugTrace; Always default to NO + with0->FPTPhase = OtherRegControl->FPTPhase; + with0->Set_TapNum(OtherRegControl->Get_TapNum()); + with0->CogenEnabled = OtherRegControl->CogenEnabled; + with0->LDC_Z = OtherRegControl->LDC_Z; + with0->revLDC_Z = OtherRegControl->revLDC_Z; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherRegControl->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in RegControl MakeLike: \"") + RegControlName + + "\" Not Found.", 121); + return result; +} + + + + +/*==========================================================================*/ +/* TRegControlObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TRegControlObj::TRegControlObj(TDSSClass* ParClass, const String RegControlName) + : inherited(ParClass), + Vreg(120.0), + Bandwidth(3.0), + PTRatio(60.0), + RemotePTRatio(PTRatio), + CTRating(300.0), + R(0.0), + X(0.0), + LDC_Z(0.0), + revVreg(120.0), + revBandwidth(3.0), + RevPowerThreshold(100000.0), + kWRevPowerThreshold(100.0), + revDelay(0.0), + revR(0.0), + revX(0.0), + revLDC_Z(0.0), + IsReversible(false), + InReverseMode(false), + ReversePending(false), + ReverseNeutral(false), + CogenEnabled(false), + InCogenMode(false), + RevHandle(0), + RevBackHandle(0), + LDCActive(false), + UsingRegulatedBus(false), + FPendingTapChange(0.0), + TapDelay(0.0), + DebugTrace(false), + Armed(false), + TapLimitPerChange(0), + TapWinding(0), + FInversetime(false), + Vlimit(0.0), + VLimitActive(false), + FPTPhase(0), + ControlledPhase(0), + ControlActionHandle(0), + VBuffer(nullptr), + cBuffer(nullptr) +{ + Set_Name(LowerCase(RegControlName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + TimeDelay = 15.0; + FPTPhase = 1; + LDCActive = false; + TapDelay = 2.0; + TapLimitPerChange = 16; + DebugTrace = false; + Armed = false; + + /*Reverse mode variables*/ + revR = 0.0; + revX = 0.0; + revLDC_Z = 0.0; + revDelay = 60.0; // Power must be reversed this long before it will reverse + IsReversible = false; + ReversePending = false; + InReverseMode = false; + ReverseNeutral = false; + InCogenMode = false; + CogenEnabled = false; + RevHandle = 0; + RevBackHandle = 0; + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + TapWinding = ElementTerminal; + VBuffer = nullptr; + cBuffer = nullptr; + DSSObjType = ParClass->DSSClassType; //REG_CONTROL; + InitPropertyValues(0); + FInversetime = false; + RegulatedBus = ""; + Vlimit = 0.0; + ControlActionHandle = 0; + + // RecalcElementData; +} + +TRegControlObj::~TRegControlObj() +{ + ElementName = ""; + if( VBuffer != nullptr) + delete[] VBuffer; + if( cBuffer != nullptr) + delete[] cBuffer; + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TRegControlObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + String TransName; + String NewElementName; + if((R != 0.0) || (X != 0.0) || (LDC_Z > 0.0)) + LDCActive = true; + else + LDCActive = false; + if(RegulatedBus.size() == 0) + UsingRegulatedBus = false; + else + UsingRegulatedBus = true; + DevIndex = GetCktElementIndex(ElementName); // Global FUNCTION + if(DevIndex == 0) // Try 'AutoTrans' instead of Transformer + { + TransName = StripClassName(ElementName); + NewElementName = String("autotrans.") + TransName; + DevIndex = GetCktElementIndex(NewElementName); + if(DevIndex > 0) + ElementName = NewElementName; + } + if(DevIndex > 0) // RegControled element must already exist + { + Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + Set_MonitoredElement(get_FControlledElement()); // same for this controller + if(UsingRegulatedBus) + { + Set_NPhases(1); // Only need one phase + Set_Nconds(2); + } + else + { + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + if(FPTPhase > Fnphases) + { + FPTPhase = 1; + Set_PropertyValue(22,"1"); + } + } + if((CompareText( get_FControlledElement()->Get_myPName(), "transformer") == 0) || (CompareText( get_FControlledElement()->Get_myPName(), "autotrans") == 0)) // either should work + { + if(ElementTerminal > get_FControlledElement()->Get_NTerms()) + { + DoErrorMsg(String("RegControl: \"") + get_Name() + "\"", "Winding no. \"" "\" does not exist.", "Respecify Monitored Winding no.", 122); + } + else + + // Sets name of i-th terminal's connected bus in RegControl's buslist + // This value will be used to set the NodeRef array (see Sample function) + { + if(UsingRegulatedBus) // hopefully this will actually exist + SetBus(1, RegulatedBus); + else + SetBus(1, get_FControlledElement()->GetBus(ElementTerminal)); + VBuffer = new complex[ get_FControlledElement()->Get_NPhases() + 1]; // buffer to hold regulator voltages + cBuffer = new complex[ get_FControlledElement()->Yorder + 1 ]; + } + } + else + { + Set_ControlledElement(nullptr); // we get here if element not found + DoErrorMsg(String("RegControl: \"") + this->get_Name() + "\"", String("Controlled Regulator Element \"") + ElementName + + "\" Is not a transformer.", " Element must be defined previously.", 123); + } + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("RegControl: \"") + this->get_Name() + "\"", String("Transformer Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 124); + } +} + +/*--------------------------------------------------------------------------*/ + +void TRegControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrim as nil and it will be ignored ... zero current source + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + + + + + + +/*--------------------------------------------------------------------------*/ + +complex TRegControlObj::GetControlVoltage(pComplexArray VBuffer, int Nphs, double PTRatio) +{ + complex result = {}; + int i = 0; + double V = 0.0; + switch(FPTPhase) + { + case MAXPHASE: +/* + AVGPHASES: Begin + Result := CZERO; + FOR i := 1 to Nphs Do Result := Result + Cabs(VBuffer^[i]); + Result := CdivReal(Result, (Nphs*PTRatio)); + End; + +*/ + { + int stop = 0; + ControlledPhase = 1; + V = cabs((VBuffer)[ControlledPhase - 1]); + for(stop = Nphs, i = 2; i <= stop; i++) + { + if(cabs((VBuffer)[i - 1]) > V) + { + V = cabs((VBuffer)[i - 1]); + ControlledPhase = i; + } + } + result = cdivreal((VBuffer)[ControlledPhase - 1], PTRatio); + } + break; + case MINPHASE: + { + int stop = 0; + ControlledPhase = 1; + V = cabs((VBuffer)[ControlledPhase - 1]); + for(stop = Nphs, i = 2; i <= stop; i++) + { + if(cabs((VBuffer)[i - 1]) < V) + { + V = cabs((VBuffer)[i - 1]); + ControlledPhase = i; + } + } + result = cdivreal((VBuffer)[ControlledPhase - 1], PTRatio); + } + break; + /*Just use one phase because that's what most controls do.*/ + default: + result = cdivreal((VBuffer)[FPTPhase - 1], PTRatio); + ControlledPhase = FPTPhase; + break; + } + return result; +} + +void TRegControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TRegControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------*/ + +String TRegControlObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 28: + result = Format("%d", Get_TapNum()); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +void TRegControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + + // Note: The PropertyValue access function calls GetPropertyValue routine. + if(Complete) + { + { Write(f, "! Bus ="); WriteLn(f, GetBus(1)); } + WriteLn(f); + } +} + +/*--------------------------------------------------------------------------*/ + +// Called in STATIC mode +// Changes 70% of the way but at least one tap, subject to maximum allowable tap change + +double TRegControlObj::AtLeastOneTap(double ProposedChange, double Increment, int ActorID) +{ + double result = 0.0; + int NumTaps = 0; + NumTaps = Trunc(0.7 * Abs(ProposedChange) / Increment); + if(NumTaps == 0) + NumTaps = 1; + if(NumTaps > TapLimitPerChange) + NumTaps = TapLimitPerChange; + LastChange[ActorID] = NumTaps; + if(ProposedChange > 0.0) // check sign on change + result = NumTaps * Increment; + else + { + result = -NumTaps * Increment; + LastChange[ActorID] = -NumTaps; + } + return result; +} + + +/*--------------------------------------------------------------------------*/ + +double OneInDirectionOf(double& ProposedChange, double Increment, int ActorID) +{ + double result = 0.0; + LastChange[ActorID] = 0; + if(ProposedChange > 0.0) + { + result = Increment; + LastChange[ActorID] = 1; + ProposedChange = ProposedChange - Increment; + } + else + { + result = -Increment; + LastChange[ActorID] = -1; + ProposedChange = ProposedChange + Increment; + } + if(Abs(ProposedChange) < 0.9 * Increment) + ProposedChange = 0.0; + return result; +} + +// Computes the amount of one tap change in the direction of the pending tapchange +// Automatically decrements the proposed change by that amount + + +/*--------------------------------------------------------------------------*/ + +// 2-23-00 Modified to change one tap at a time + +void TRegControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + double TapChangeToMake = 0.0; + switch(Code) + { + case ACTION_TAPCHANGE: + { + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord(Format("+++ %.6g s: Handling TapChange = %.8g", ActiveCircuit[ActorID]->Solution->DynaVars.T, get_FPendingTapChange())); + } + if(get_FPendingTapChange() == 0.0) /*Check to make sure control has not reset*/ + Armed = false; + else + /*# with TTransfObj(ControlledElement) do */ + { + auto with1 = ((TTransfObj*) get_FControlledElement()); + + // Transformer PresentTap property automatically limits tap + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with3 = ActiveCircuit[ActorID]->Solution; + switch(with3->ControlMode) + { + case CTRLSTATIC: + { + TapChangeToMake = AtLeastOneTap(get_FPendingTapChange(), with1->Get_TapIncrement(TapWinding), ActorID); + if(DebugTrace) + RegWriteTraceRecord(TapChangeToMake, ActorID); + with1->Set_PresentTap(TapWinding,ActorID, with1->Get_PresentTap(TapWinding,ActorID) + TapChangeToMake); + if(ShowEventLog) + AppendToEventLog(String("Regulator.") + + get_FControlledElement()->get_Name(), Format(" Changed %d taps to %-.6g.", LastChange[ActorID], with1->Get_PresentTap(TapWinding,ActorID)), ActorID); + set_PendingTapChange(0.0); // Reset to no change. Program will determine if another needed. + Armed = false; + } + break; + case EVENTDRIVEN: + { + TapChangeToMake = OneInDirectionOf(FPendingTapChange, with1->Get_TapIncrement(TapWinding), ActorID); + if(DebugTrace) + RegWriteTraceRecord(TapChangeToMake, ActorID); + with1->Set_PresentTap(TapWinding,ActorID,with1->Get_PresentTap(TapWinding,ActorID) + TapChangeToMake); + if(get_FPendingTapChange() != 0.0) + ActiveCircuit[ActorID]->ControlQueue.Push(with3->DynaVars.intHour, with3->DynaVars.T + TapDelay, (EControlAction) 0, 0, this, ActorID); + else + Armed = false; + } + break; + case TIMEDRIVEN: + { + TapChangeToMake = OneInDirectionOf(FPendingTapChange, with1->Get_TapIncrement(TapWinding), ActorID); + if(DebugTrace) + RegWriteTraceRecord(TapChangeToMake, ActorID); + with1->Set_PresentTap(TapWinding,ActorID,with1->Get_PresentTap(TapWinding,ActorID) + TapChangeToMake); + if(ShowEventLog) + AppendToEventLog(String("Regulator.") + + get_FControlledElement()->get_Name(), Format(" Changed %d tap to %-.6g.", LastChange[ActorID], with1->Get_PresentTap(TapWinding,ActorID)), ActorID); + if(DebugTrace) + RegWriteDebugRecord(Format("--- Regulator.%s Changed %d tap to %-.6g.", + get_FControlledElement()->get_Name().c_str(), LastChange[ActorID], with1->Get_PresentTap(TapWinding,ActorID))); + if(get_FPendingTapChange() != 0.0) + ActiveCircuit[ActorID]->ControlQueue.Push(with3->DynaVars.intHour, with3->DynaVars.T + TapDelay, (EControlAction) 0, 0, this, ActorID); + else + Armed = false; + } + break; + case MULTIRATE: + { + TapChangeToMake = OneInDirectionOf(FPendingTapChange, with1->Get_TapIncrement(TapWinding), ActorID); + if(DebugTrace) + RegWriteTraceRecord(TapChangeToMake, ActorID); + with1->Set_PresentTap(TapWinding,ActorID,with1->Get_PresentTap(TapWinding,ActorID) + TapChangeToMake); + if(ShowEventLog) + AppendToEventLog(String("Regulator.") + + get_FControlledElement()->get_Name(), Format(" Changed %d tap to %-.6g.", LastChange[ActorID], with1->Get_PresentTap(TapWinding,ActorID)), ActorID); + if(DebugTrace) + RegWriteDebugRecord(Format("--- Regulator.%s Changed %d tap to %-.6g.", + get_FControlledElement()->get_Name().c_str(), LastChange[ActorID], with1->Get_PresentTap(TapWinding,ActorID))); + if(get_FPendingTapChange() != 0.0) + ActiveCircuit[ActorID]->ControlQueue.Push(with3->DynaVars.intHour, with3->DynaVars.T + TapDelay, (EControlAction) 0, 0, this, ActorID); + else + Armed = false; + } + break; + default: + ; + break; + } + } + } + } + break; /*ACTION_TAPCHANGE*/ // Toggle reverse mode or Cogen mode flag + case ACTION_REVERSE: + { + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord( Format( "%-.6g, Handling Reverse Action, ReversePending=", ActiveCircuit[ActorID]->Solution->DynaVars.dblHour) + + BoolToStr(ReversePending, true) + ", InReverseMode =" + + BoolToStr(InReverseMode, true) + ", InCogenmode = " + BoolToStr(InCogenMode, true) ); + } + if(ReversePending) // check to see if action has reset + { + if(CogenEnabled) // Cogen mode takes precedence if present + { + if(InCogenMode) + InCogenMode = false; + else + InCogenMode = true; + } + else + { + if(InReverseMode) + InReverseMode = false; + else + InReverseMode = true; + } + ReversePending = false; + } + } + break; /*ACTION_REVERSE*/ + default: + ; + break; + } +} + +/*This is where it all happens ...*/ + +void TRegControlObj::sample(int ActorID) +{ + double BoostNeeded = 0.0; + double Increment = 0.0; + double Vactual = 0.0; + double VregTest = 0.0; + double BandTest = 0.0; + double Vboost = 0.0; + double VlocalBus = 0.0; + double FwdPower = 0.0; + complex Vcontrol = {}; + complex VLDC = {}; + complex ILDC = {}; + bool TapChangeIsNeeded = false; + bool LookingForward = false; + int i = 0; + int II = 0; + TTransfObj* ControlledTransformer = nullptr; + int TransformerConnection = 0; + ControlledTransformer = ((TTransfObj*) get_FControlledElement()); + if(TapLimitPerChange == 0) + { + set_PendingTapChange(0); + return; + } + LookingForward = (!InReverseMode) || InCogenMode; // Always looking forward in cogen mode + + /*Get_First(), check the direction of power flow to see if we need to reverse direction*/ + /*Don't do this if using regulated bus logic*/ + if(!UsingRegulatedBus) + { + if(IsReversible || CogenEnabled) + { + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord( Format( "%-.6g, 2-Looking forward= ", ActiveCircuit[ActorID]->Solution->DynaVars.dblHour) + + BoolToStr(LookingForward, true) + " *** Incogenmode=" + BoolToStr(InCogenMode, true) ); + } + if(LookingForward && (!InCogenMode)) // If looking forward, check to see if we should reverse + { + FwdPower = -ControlledTransformer->Get_Power(ElementTerminal, ActorID).re; // watts + if(!ReversePending) // If reverse is already pending, don't send any more messages + { + if(FwdPower < - RevPowerThreshold) + { + ReversePending = true; + /*# with ActiveCircuit[ActorID] do */ + { + + RevHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + revDelay, ACTION_REVERSE, 0, this, ActorID); + } + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord(Format("%-.6g, 1- Pushed Reverse Action, Handle=%d, FwdPower=%.8g", + ActiveCircuit[ActorID]->Solution->DynaVars.dblHour, RevHandle, FwdPower)); + } + } + } + if(ReversePending && (FwdPower >= - RevPowerThreshold)) // Reset reverse pending + { + ReversePending = false; // Reset it if power goes back + if(RevHandle > 0) + { + if(DebugTrace) + RegWriteDebugRecord(Format("Deleting Reverse Action, Handle=%d", RevHandle)); + ActiveCircuit[ActorID]->ControlQueue.Delete(RevHandle, ActorID); + RevHandle = 0; // reset for next time + } + } + } + else + // Looking the reverse direction or in cogen mode + // If reversed look to see if power is back in forward direction + { + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord( Format( "%-.6g, 3-Looking Forward=", ActiveCircuit[ActorID]->Solution->DynaVars.dblHour) + + BoolToStr(LookingForward, true) + " % s * **Incogenmode = % s" + BoolToStr(InCogenMode, true) ); + } + FwdPower = -ControlledTransformer->Get_Power(ElementTerminal, ActorID).re; // watts + if(!ReversePending) + { + if(FwdPower > RevPowerThreshold) + { + ReversePending = true; + /*# with ActiveCircuit[ActorID] do */ + { + + RevBackHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + revDelay, ACTION_REVERSE, 0, this, ActorID); + } + if(DebugTrace) + /*# with ActiveCircuit[ActorID] do */ + { + + RegWriteDebugRecord(Format("%-.6g, 4-Pushed ReverseBack Action to switch back, Handle=%d, FwdPower=%.8g", + ActiveCircuit[ActorID]->Solution->DynaVars.dblHour, RevBackHandle, FwdPower)); + } + } + } + if(ReversePending && (FwdPower <= RevPowerThreshold)) // Reset reverse pending Else + { + ReversePending = false; // Reset it if power goes back + if(RevBackHandle > 0) + { + if(DebugTrace) + RegWriteDebugRecord(Format("Deleting ReverseBack Action, Handle=%d", RevBackHandle)); + ActiveCircuit[ActorID]->ControlQueue.Delete(RevBackHandle, ActorID); + RevBackHandle = 0; // reset for next time + } + } + + /*Check for special case of Reverse Neutral where regulator is to move to neutral position*/ + /*Both Cogen Mode and Reverse operation*/ + /*# with ControlledTransformer do */ + { + auto with6 = ControlledTransformer; + if(ReverseNeutral) + { + if(!Armed) + { + set_PendingTapChange(0.0); + if(Abs(with6->Get_PresentTap(TapWinding,ActorID) - 1.0) > EPSILON) + { + Increment = with6->Get_TapIncrement(TapWinding); + set_PendingTapChange(Round((1.0 - with6->Get_PresentTap(TapWinding,ActorID)) / Increment) * Increment); + if((get_FPendingTapChange() != 0.0) && !Armed) + /*# with ActiveCircuit[ActorID] do */ + { + + if(DebugTrace) + RegWriteDebugRecord(Format("*** %.6g s: Pushing TapChange = %.8g, delay= %.8g", + ActiveCircuit[ActorID]->Solution->DynaVars.T, get_FPendingTapChange(), TapDelay)); + ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TapDelay, ACTION_TAPCHANGE, 0, this, ActorID); + Armed = true; + } + } + } + return; + } + } + } /*Else*/ + } + } + if(UsingRegulatedBus) + { + int stop = 0; + TransformerConnection = ControlledTransformer->WINDING_[ElementTerminal - 1].Connection; + ComputeVterminal(ActorID); // Computes the voltage at the bus being regulated + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(TransformerConnection) + { + case 0: // Wye + { + (VBuffer)[i - 1] = (Vterminal)[i - 1]; + } + break; // Delta + case 1: + { + II = ControlledTransformer->RotatePhases(i); // Get next phase in sequence using Transformer Obj rotate + (VBuffer)[i - 1] = csub((Vterminal)[i - 1], (Vterminal)[II - 1]); + } + break; + default: + ; + break; + } + } + Vcontrol = GetControlVoltage(VBuffer, Fnphases, RemotePTRatio); + } + else + { + ControlledTransformer->GetWindingVoltages(ElementTerminal, VBuffer, ActorID); + Vcontrol = GetControlVoltage(VBuffer, Fnphases, PTRatio); + } + + // Check Vlimit + if(VLimitActive) + { + if(UsingRegulatedBus) + { + ControlledTransformer->GetWindingVoltages(ElementTerminal, VBuffer, ActorID); + VlocalBus = cabs(cdivreal((VBuffer)[1 - 1], PTRatio)); + } + else + { + VlocalBus = cabs(Vcontrol); + } + } + else + VlocalBus = 0.0; // to get rid of warning message; + + // Check for LDC + if(!UsingRegulatedBus && LDCActive) + { + get_FControlledElement()->GetCurrents(cBuffer, ActorID); + // Convert current to control current by CTRating + ILDC = cdivreal((cBuffer)[get_FControlledElement()->Get_NConds() * (ElementTerminal - 1) + ControlledPhase - 1], CTRating); + if(LDC_Z == 0.0) // Standard R, X LDC + { + if(InReverseMode || InCogenMode) + VLDC = cmul(cmplx(revR, revX), ILDC); + else + VLDC = cmul(cmplx(R, X), ILDC); + Vcontrol = cadd(Vcontrol, VLDC); // Direction on ILDC is INTO terminal, so this is equivalent to Vterm - (R+jX)*ILDC + } + else + // Beckwith LDC_Z control mode + { + if(InReverseMode || InCogenMode) + Vcontrol = cmplx((cabs(Vcontrol) - cabs(ILDC) * revLDC_Z), 0.0); + else + Vcontrol = cmplx((cabs(Vcontrol) - cabs(ILDC) * LDC_Z), 0.0); // Just magnitudes + } + } + Vactual = cabs(Vcontrol); // Assumes looking forward; see below + /*# with ControlledTransformer do */ + { + auto with8 = ControlledTransformer; + // Check for out of band voltage + if(InReverseMode) + { + Vactual = Vactual / with8->Get_PresentTap(TapWinding,ActorID); + VregTest = revVreg; + BandTest = revBandwidth; + } + else + // Forward or Cogen Modes + { + if(InCogenMode) + { + VregTest = revVreg; // corrected Feb 25, 2021 for Huijuan Li + BandTest = revBandwidth; + } + else + { + VregTest = Vreg; + BandTest = Bandwidth; + } + } + if(Abs(VregTest - Vactual) > (BandTest / 2.0)) + TapChangeIsNeeded = true; + else + TapChangeIsNeeded = false; + if(VLimitActive) + { + if(VlocalBus > Vlimit) + TapChangeIsNeeded = true; + } + if(TapChangeIsNeeded) + // Compute tapchange + { + Vboost = (VregTest - Vactual); + if(VLimitActive) + { + if(VlocalBus > Vlimit) + Vboost = (Vlimit - VlocalBus); + } + BoostNeeded = Vboost * PTRatio / with8->Get_BaseVoltage(ElementTerminal); // per unit Winding boost needed + Increment = with8->Get_TapIncrement(TapWinding); + set_PendingTapChange(Round(BoostNeeded / Increment) * Increment); // Make sure it is an even increment + + /*If Tap is another winding or in REVERSE MODE, it has to move the other way to accomplish the change*/ + if((TapWinding != ElementTerminal) || InReverseMode) + set_PendingTapChange(-get_FPendingTapChange()); + + // Send Initial Tap Change message to control queue + // Add Delay time to solution control queue + if((get_FPendingTapChange() != 0.0) && !Armed) + // Now see if any tap change is possible in desired direction Else ignore + { + if(get_FPendingTapChange() > 0.0) + { + if(with8->Get_PresentTap(TapWinding,ActorID) < with8->Get_MaxTap(TapWinding)) + /*# with ActiveCircuit[ActorID] do */ + { + auto with100 = ActiveCircuit[ActorID]; + ControlActionHandle = with100->ControlQueue.Push(with100->Solution->DynaVars.intHour, with100->Solution->DynaVars.T + ComputeTimeDelay(Vactual), ACTION_TAPCHANGE, 0, this, ActorID); + Armed = true; // Armed to change taps + } + } + else + { + if(with8->Get_PresentTap(TapWinding,ActorID) > with8->Get_MinTap(TapWinding)) + /*# with ActiveCircuit[ActorID] do */ + { + + ControlActionHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ComputeTimeDelay(Vactual), ACTION_TAPCHANGE, 0, this, ActorID); + Armed = true; // Armed to change taps + } + } + } /*If TapChangeIsNeeded*/ + } + else + /*Reset if back in band.*/ + { + set_PendingTapChange(0.0); + if(Armed) + { + ActiveCircuit[ActorID]->ControlQueue.Delete(ControlActionHandle, ActorID); + Armed = false; + ControlActionHandle = 0; + } + } + } +} + +TTransfObj* TRegControlObj::Get_Transformer() +{ + TTransfObj* result = nullptr; + result = ((TTransfObj*) get_FControlledElement()); + return result; +} + +int TRegControlObj::Get_Winding() +{ + int result = 0; + result = TapWinding; + return result; +} + +int TRegControlObj::Get_TapNum() +{ + int result = 0; + TTransfObj* ctrldTransformer = nullptr; + int ictrldWinding = 0; + if(get_FControlledElement() != nullptr) + { + ctrldTransformer = Get_Transformer(); + ictrldWinding = Get_Winding(); + /*# with ctrldTransformer do */ + { + auto with0 = ctrldTransformer; + result = (int) Round((with0->Get_PresentTap(ictrldWinding,ActiveActor) - (with0->Get_MaxTap(ictrldWinding) + with0->Get_MinTap(ictrldWinding)) / 2.0) / with0->Get_TapIncrement(ictrldWinding)); + } + } + else + result = 0; + return result; +} + +double TRegControlObj::Get_MinTap() +{ + double result = 0.0; + result = Get_Transformer()->Get_MinTap(TapWinding); + return result; +} + +double TRegControlObj::Get_MaxTap() +{ + double result = 0.0; + result = Get_Transformer()->Get_MaxTap(TapWinding); + return result; +} + +double TRegControlObj::Get_TapIncrement() +{ + double result = 0.0; + result = Get_Transformer()->Get_TapIncrement(TapWinding); + return result; +} + +int TRegControlObj::Get_NumTaps() +{ + int result = 0; + result = Get_Transformer()->Get_NumTaps(TapWinding); + return result; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_FPendingTapChange() +{ + return FPendingTapChange; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_Vreg() +{ + return Vreg; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_Bandwidth() +{ + return Bandwidth; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_CTRating() +{ + return CTRating; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_PTRatio() +{ + return PTRatio; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_R() +{ + return R; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_X() +{ + return X; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_revR() +{ + return revR; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_revX() +{ + return revX; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_revVreg() +{ + return revVreg; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_revBandwidth() +{ + return revBandwidth; +} + +//-------------------------------------------------------------------------- + +bool TRegControlObj::get_LDCActive() +{ + return LDCActive; +} + +//-------------------------------------------------------------------------- + +bool TRegControlObj::get_IsReversible() +{ + return IsReversible; +} + +//-------------------------------------------------------------------------- + +bool TRegControlObj::get_VLimitActive() +{ + return VLimitActive; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_Vlimit() +{ + return Vlimit; +} + +//-------------------------------------------------------------------------- + +double TRegControlObj::get_TapDelay() +{ + return TapDelay; +} + +//-------------------------------------------------------------------------- + +int TRegControlObj::get_TapLimitPerChange() +{ + return TapLimitPerChange; +} + +//-------------------------------------------------------------------------- + +bool TRegControlObj::get_FInversetime() +{ + return FInversetime; +} + +//-------------------------------------------------------------------------- + +// write a general debug string + +void TRegControlObj::RegWriteDebugRecord(String s) +{ + try + { + if(!InShowResults) + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile, s); + CloseFile(Tracefile); + } + } + catch (...) + { + } +} + +void TRegControlObj::RegWriteTraceRecord(double TapChangeMade, int ActorID) +{ + String Separator; + try + { + if(!InShowResults) + { + Separator = ", "; + Append(Tracefile); + IOResultToException(); + /*# with TTransfObj(ControlledElement) do */ + { + auto with0 = ((TTransfObj*) get_FControlledElement()); + { + Write(Tracefile, ActiveCircuit[ActorID]->Solution->DynaVars.intHour, 0); + Write(Tracefile, Separator); + Write(Tracefile, ActiveCircuit[ActorID]->Solution->DynaVars.T, 0, 3); + Write(Tracefile, Separator); + Write(Tracefile, ActiveCircuit[ActorID]->Solution->ControlIteration, 0); + Write(Tracefile, Separator); + Write(Tracefile, ActiveCircuit[ActorID]->Solution->Iteration, 0); + Write(Tracefile, Separator); + Write(Tracefile, ActiveCircuit[ActorID]->get_FLoadMultiplier(), 6, 2); + Write(Tracefile, Separator); + Write(Tracefile, with0->Get_PresentTap(ElementTerminal,ActorID), 8, 5); + Write(Tracefile, Separator); + Write(Tracefile, get_FPendingTapChange(), 8, 5); + Write(Tracefile, Separator); + Write(Tracefile, TapChangeMade, 8, 5); + Write(Tracefile, Separator); + Write(Tracefile, with0->Get_TapIncrement(ElementTerminal), 8, 5); + Write(Tracefile, Separator); + Write(Tracefile, with0->Get_MinTap(ElementTerminal), 8, 5); + Write(Tracefile, Separator); + WriteLn(Tracefile, with0->Get_MaxTap(ElementTerminal), 8, 5); + } + } + CloseFile(Tracefile); + } + } + catch (...) + { + } /*Do Nothing*/ +} + +void TRegControlObj::Reset(int ActorID) +{ + set_PendingTapChange(0.0); + Armed = false; +} +/*Override standard SaveWrite*/ +/*Regcontrol structure not conducive to standard means of saving*/ + +void TRegControlObj::SaveWrite(TTextRec& f) +{ + int iProp = 0; + /*Write only properties that were explicitly set in the + final order they were actually set*/ + + // Write Transformer name out first so that it is set for later operations + iProp = 1; + if(Length(String(Get_PropertyValue(iProp))) > 0) + /*# with ParentClass do */ + { + auto with0 = ParentClass; + String PropValue = "=" + CheckForBlanks(String(Get_PropertyValue(iProp)) ); + Write( f, with0->PropertyName[with0->RevPropertyIdxMap[iProp - 1] - 1] + PropValue ); + } + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + while(iProp > 0) + /*# with ParentClass do */ + { + auto with1 = ParentClass; + if(iProp != 1) + { + if(Length(String(Get_PropertyValue(iProp))) > 0) // Don't repeat Transformer property + { + String PropValue = "=" + CheckForBlanks(String(Get_PropertyValue(iProp)) ); + Write( f, " " + with1->PropertyName[(with1->RevPropertyIdxMap)[iProp - 1] - 1] + PropValue); + } + } + iProp = GetNextPropertySet(iProp); + } +} + +void TRegControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,"120"); + Set_PropertyValue(4,"3"); + Set_PropertyValue(5,"60"); + Set_PropertyValue(6,"300"); + Set_PropertyValue(7,"0"); + Set_PropertyValue(8,"0"); + Set_PropertyValue(9,""); + Set_PropertyValue(10,"15"); + Set_PropertyValue(11,"no"); + Set_PropertyValue(12,"120"); + Set_PropertyValue(13,"3"); + Set_PropertyValue(14,"0"); + Set_PropertyValue(15,"0"); + Set_PropertyValue(16,"2"); + Set_PropertyValue(17,"no"); + Set_PropertyValue(18,"16"); + Set_PropertyValue(19,"no"); + Set_PropertyValue(20,"1"); + Set_PropertyValue(21,"0.0"); + Set_PropertyValue(22,"1"); + Set_PropertyValue(23,"100"); + Set_PropertyValue(24,"60"); + Set_PropertyValue(25,"No"); + Set_PropertyValue(26, ShowEventLog ? "YES" : "NO"); + Set_PropertyValue(27,"60"); + Set_PropertyValue(28,"0"); + Set_PropertyValue(29,"NO"); + Set_PropertyValue(30,"0"); + Set_PropertyValue(31,"0"); + Set_PropertyValue(32,"No"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TRegControlObj::set_PendingTapChange(double Value) +{ + FPendingTapChange = Value; + DblTraceParameter = Value; +} + +void TRegControlObj::Set_TapNum(int Value) +{ + TTransfObj* ctrldTransformer = nullptr; + int ictrldWinding = 0; + if(!ASSIGNED(get_FControlledElement())) + RecalcElementData(ActiveActor); + if(get_FControlledElement() != nullptr) + { + ctrldTransformer = ((TTransfObj*) get_FControlledElement()); + ictrldWinding = Get_Winding(); + /*# with ctrldTransformer do */ + { + auto with0 = ctrldTransformer; + with0->Set_PresentTap(ictrldWinding,ActiveActor,Value * with0->Get_TapIncrement(ictrldWinding) + ((with0->Get_MaxTap(ictrldWinding) + with0->Get_MinTap(ictrldWinding)) / 2.0)); + } + +// Tap range checking is done in PresentTap +// You can attempt to set the tap at an illegal value but it won't do anything + } +} + +void TRegControlObj::MakePosSequence(int ActorID) +{ + if(get_FControlledElement() != nullptr) + { + Set_Enabled(get_FControlledElement()->Get_Enabled()); + if(UsingRegulatedBus) + Set_NPhases(1); + else + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + if((CompareText( ( get_FControlledElement() )->Get_myPName(), "transformer") == 0) || (CompareText( ( get_FControlledElement() )->Get_myPName(), "autotrans") == 0)) // either should work + + // Sets name of i-th terminal's connected bus in RegControl's buslist + // This value will be used to set the NodeRef array (see Sample function) + { + if(UsingRegulatedBus) // hopefully this will actually exist + SetBus(1, RegulatedBus); + else + SetBus(1, get_FControlledElement()->GetBus(ElementTerminal)); + VBuffer = (pComplexArray)realloc(VBuffer, sizeof(complex) * get_FControlledElement()->Get_NPhases()); // buffer to hold regulator voltages + cBuffer = (pComplexArray)realloc(cBuffer, sizeof(complex) * get_FControlledElement()->Yorder); + } + } + inherited::MakePosSequence(ActorID); +} + +double TRegControlObj::ComputeTimeDelay(double Vavg) +{ + double result = 0.0; + if(FInversetime) + result = TimeDelay / min(10.0, (2.0 * Abs(Vreg - Vavg) / Bandwidth)); + else + result = TimeDelay; + return result; +} + + + + +} // namespace RegControl + + + + + diff --git a/OpenDSSC/Controls/RegControl.h b/OpenDSSC/Controls/RegControl.h new file mode 100644 index 0000000..37ec111 --- /dev/null +++ b/OpenDSSC/Controls/RegControl.h @@ -0,0 +1,191 @@ +#ifndef RegControlH +#define RegControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "Transformer.h" +#include "d2c_structures.h" + + + +namespace RegControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 1-28-00 Created + 4-29-00 fixed problem with NumPhases = # phases of controlled element + 12/17/01 Added LDC logic + 12/18/01 Added MaxTapChange property and logic + 6/18/11 Updated Rev Power logic + 12/4/2018 Added autotransformer control +*/ + +/* + A RegControl is a control element that is connected to a terminal of another + circuit element that must be a transformer. + + A RegControl is defined by a New command: + + New RegControl.Name=myname Transformer = name Terminal=[1,2,...] Controlledbus=name etc... + + Transformer to be controlled must already exist. +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRegControl : public ControlClass::TControlClass +{ + friend class TRegControlObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String RegControlName); +public: + TRegControl(); + virtual ~TRegControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRegControlObj : public ControlElem::TControlElem +{ + friend class TRegControl; +public: + typedef ControlElem::TControlElem inherited; +//private: + double Vreg; + double Bandwidth; + double PTRatio; + double RemotePTRatio; + double CTRating; + double R; + double X; + double LDC_Z; + + /*Reverse Power Variables*/ // W + double revVreg; + double revBandwidth; + double RevPowerThreshold; + double kWRevPowerThreshold; + double revDelay; + double revR; + double revX; + double revLDC_Z; + bool IsReversible; + bool InReverseMode; + bool ReversePending; + bool ReverseNeutral; + bool CogenEnabled; + bool InCogenMode; + int RevHandle; + int RevBackHandle; + bool LDCActive; + bool UsingRegulatedBus; + String RegulatedBus; // amount of tap change pending + double FPendingTapChange; + double TapDelay; // delay between taps + bool DebugTrace; + bool Armed; + System::TTextRec Tracefile; + int TapLimitPerChange; + int TapWinding; // Added 7-19-07 + bool FInversetime; + double Vlimit; + bool VLimitActive; + int FPTPhase; + int ControlledPhase; + int ControlActionHandle; + Ucomplex::pComplexArray VBuffer; + Ucomplex::pComplexArray cBuffer; + Transformer::TTransfObj* Get_Transformer(); + int Get_Winding(); + // CIM accessors + double Get_MinTap(); + double Get_MaxTap(); + double Get_TapIncrement(); + int Get_NumTaps(); + int Get_TapNum(); + void RegWriteTraceRecord(double TapChangeMade, int ActorID); + void RegWriteDebugRecord(String s); + void set_PendingTapChange(double Value); + double AtLeastOneTap(double ProposedChange, double Increment, int ActorID); + double ComputeTimeDelay(double Vavg); + Ucomplex::complex GetControlVoltage(Ucomplex::pComplexArray VBuffer, int Nphs, double PTRatio); + void Set_TapNum(int Value); +public: + TRegControlObj(DSSClass::TDSSClass* ParClass, const String RegControlName); + virtual ~TRegControlObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a RegControl + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + + double get_FPendingTapChange(); + double get_Vreg(); + double get_Bandwidth(); + double get_CTRating(); + double get_PTRatio(); + double get_R(); + double get_X(); + double get_revR(); + double get_revX(); + double get_revVreg(); + double get_revBandwidth(); + bool get_LDCActive(); + bool get_IsReversible(); + bool get_VLimitActive(); + double get_Vlimit(); + double get_TapDelay(); + int get_TapLimitPerChange(); + bool get_FInversetime(); + + // CIM XML accessors + TRegControlObj(DSSClass::TDSSClass* ParClass); + TRegControlObj(String ClassName); + TRegControlObj(); +}; +extern TRegControlObj* ActiveRegControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace RegControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace RegControl; +#endif + +#endif // RegControlH + + + + + diff --git a/OpenDSSC/Controls/Relay.cpp b/OpenDSSC/Controls/Relay.cpp new file mode 100644 index 0000000..266306b --- /dev/null +++ b/OpenDSSC/Controls/Relay.cpp @@ -0,0 +1,2868 @@ + +#pragma hdrstop + +#include "Relay.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace TCC_Curve; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Relay +{ + +TRelayObj::TRelayObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TRelayObj::TRelayObj(String ClassName) : inherited(ClassName) {} +TRelayObj::TRelayObj() {} + + +TRelayObj* ActiveRelayObj = nullptr; +TRelay* RelayClass = nullptr; +const int NumPropsThisClass = 50; +const int Current = 0; /*Default*/ +const int VOLTAGE = 1; +const int REVPOWER = 3; +const int NEGCURRENT = 4; +const int NEGVOLTAGE = 5; +const int GENERIC = 6; /*Use this for frequency, etc. Generic over/under relay*/ +const int Distance = 7; +const int TD21 = 8; +const int DOC = 9; + +const double MIN_DISTANCE_REACTANCE = -1.0e-8; /*allow near-bolted faults to be detected*/ +const double DEG_TO_RAD = M_PI / 180.0; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all Relay objects + +TRelay::TRelay() + : TCC_CurveClass( (TDSSClass*) GetDSSClassPtr("TCC_Curve")) +{ + ; + Class_Name = "Relay"; + DSSClassType = DSSClassType + RELAY_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete [] slc; + CommandList.set_AbbrevAllowed(true); + RelayClass = this; +} + +/*--------------------------------------------------------------------------*/ + +TRelay::~TRelay() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TRelay::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + + // Define Property names + // Addproperty (property name, internal property index (see Edit), Help string); + AddProperty("MonitoredObj", 1, "Full object name of the circuit element, typically a line, transformer, load, or generator, " + "to which the relay's PT and/or CT are connected." + " This is the \"monitored\" element. " + "There is no default; must be specified."); + AddProperty("MonitoredTerm", 2, "Number of the terminal of the circuit element to which the Relay is connected. " + "1 or 2, typically. Default is 1."); + AddProperty("SwitchedObj", 3, "Name of circuit element switch that the Relay controls. " + "Specify the full object name." + "Defaults to the same as the Monitored element. " + "This is the \"controlled\" element."); + AddProperty("SwitchedTerm", 4, "Number of the terminal of the controlled element in which the switch is controlled by the Relay. " + "1 or 2, typically. Default is 1."); + AddProperty("type", 5, String("One of a legal relay type:") + CRLF + + " Current" + + CRLF + + " Voltage" + + CRLF + + " Reversepower" + + CRLF + + " 46 (neg seq current)" + + CRLF + + " 47 (neg seq voltage)" + + CRLF + + " Generic (generic over/under relay)" + + CRLF + + " Distance" + + CRLF + + " TD21" + + CRLF + + " DOC (directional overcurrent)" + + CRLF + + CRLF + + "Default is overcurrent relay (Current). " + + "Specify the curve and pickup settings appropriate for each type. " + + "Generic relays monitor PC Element Control variables and trip on out of over/under range in definite time."); + AddProperty("Phasecurve", 6, "Name of the TCC Curve object that determines the phase trip. " + "Must have been previously defined as a TCC_Curve object." + " Default is none (ignored). " + "For overcurrent relay, multiplying the current values in the curve by the \"phasetrip\" value gives the actual current."); + AddProperty("Groundcurve", 7, "Name of the TCC Curve object that determines the ground trip. Must have been previously defined as a TCC_Curve object." + " Default is none (ignored)." + "For overcurrent relay, multiplying the current values in the curve by the \"groundtrip\" valuw gives the actual current."); + AddProperty("PhaseTrip", 8, "Multiplier or actual phase amps for the phase TCC curve. Defaults to 1.0."); + AddProperty("GroundTrip", 9, "Multiplier or actual ground amps (3I0) for the ground TCC curve. Defaults to 1.0."); + AddProperty("TDPhase", 28, "Time dial for Phase trip curve. Multiplier on time axis of specified curve. Default=1.0."); + AddProperty("TDGround", 29, "Time dial for Ground trip curve. Multiplier on time axis of specified curve. Default=1.0."); + AddProperty("PhaseInst", 10, "Actual amps (Current relay) or kW (reverse power relay) for instantaneous phase trip which is assumed to happen in 0.01 sec + Delay Time. Default is 0.0, which signifies no inst trip. " + "Use this value for specifying the Reverse Power threshold (kW) for reverse power relays."); + AddProperty("GroundInst", 11, "Actual amps for instantaneous ground trip which is assumed to happen in 0.01 sec + Delay Time.Default is 0.0, which signifies no inst trip."); + AddProperty("Reset", 12, "Reset time in sec for relay. Default is 15. If this much time passes between the last pickup event, and the relay has not locked out, the operation counter resets."); + AddProperty("Shots", 13, "Number of shots to lockout. Default is 4. This is one more than the number of reclose intervals."); + AddProperty("RecloseIntervals", 14, "Array of reclose intervals. If none, specify \"NONE\". Default for overcurrent relay is (0.5, 2.0, 2.0) seconds. " + "Default for a voltage relay is (5.0). In a voltage relay, this is seconds after restoration of " + "voltage that the reclose occurs. " + "Reverse power relay is one shot to lockout, " + "so this is ignored. A locked out relay must be closed manually (set action=close)."); + AddProperty("Delay", 24, "Trip time delay (sec) for DEFINITE TIME relays. Default is 0.0 for current, voltage and DOC relays. If >0 then this value is used instead of curves. " + " Used by Generic, RevPower, 46 and 47 relays. Defaults to 0.1 s for these relays."); + AddProperty("Overvoltcurve", 15, "TCC Curve object to use for overvoltage relay. Curve is assumed to be defined with per unit voltage values. " + "Voltage base should be defined for the relay. Default is none (ignored)."); + AddProperty("Undervoltcurve", 16, "TCC Curve object to use for undervoltage relay. Curve is assumed to be defined with per unit voltage values. " + "Voltage base should be defined for the relay. Default is none (ignored)."); + AddProperty("kvbase", 17, "Voltage base (kV) for the relay. Specify line-line for 3 phase devices); line-neutral for 1-phase devices. Relay assumes " + "the number of phases of the monitored element. Default is 0.0, which results in assuming the voltage " + "values in the \"TCC\" curve are specified in actual line-to-neutral volts."); + AddProperty("47%Pickup", 25, "Percent voltage pickup for 47 relay (Neg seq voltage). Default is 2. Specify also base voltage (kvbase) and delay time value. "); + AddProperty("46BaseAmps", 23, "Base current, Amps, for 46 relay (neg seq current)." + " Used for establishing pickup and per unit I-squared-t."); + AddProperty("46%Pickup", 21, "Percent pickup current for 46 relay (neg seq current). Default is 20.0. " + " When current exceeds this value * BaseAmps, I-squared-t calc starts."); + AddProperty("46isqt", 22, "Negative Sequence I-squared-t trip value for 46 relay (neg seq current)." + " Default is 1 (trips in 1 sec for 1 per unit neg seq current). Should be 1 to 99."); + AddProperty("Variable", 20, "Name of variable in PC Elements being monitored. Only applies to Generic relay."); + AddProperty("overtrip", 26, "Trip setting (high value) for Generic relay variable. Relay trips in definite time if value of variable exceeds this value."); + AddProperty("undertrip", 27, "Trip setting (low value) for Generic relay variable. Relay trips in definite time if value of variable is less than this value."); + AddProperty("Breakertime", 18, "Fixed delay time (sec) added to relay time. Default is 0.0. Designed to represent breaker time or some other delay after a trip decision is made." + "Use Delay property for setting a fixed trip time delay." + "Added to trip time of current and voltage relays. Could use in combination with inst trip value to obtain a definite time overcurrent relay."); + AddProperty("action", 19, "DEPRECATED. See \"State\" property"); + AddProperty("Z1mag", 30, "Positive sequence reach impedance in primary ohms for Distance and TD21 functions. Default=0.7"); + AddProperty("Z1ang", 31, "Positive sequence reach impedance angle in degrees for Distance and TD21 functions. Default=64.0"); + AddProperty("Z0mag", 32, "Zero sequence reach impedance in primary ohms for Distance and TD21 functions. Default=2.1"); + AddProperty("Z0ang", 33, "Zero sequence reach impedance angle in degrees for Distance and TD21 functions. Default=68.0"); + AddProperty("Mphase", 34, "Phase reach multiplier in per-unit for Distance and TD21 functions. Default=0.7"); + AddProperty("Mground", 35, "Ground reach multiplier in per-unit for Distance and TD21 functions. Default=0.7"); + AddProperty("EventLog", 36, "{Yes/True* | No/False} Default is Yes for Relay. Write trips, reclose and reset events to EventLog."); + AddProperty("DebugTrace", 37, "{Yes/True* | No/False} Default is No for Relay. Write extra details to Eventlog."); + AddProperty("DistReverse", 38, "{Yes/True* | No/False} Default is No; reverse direction for distance and td21 types."); + AddProperty("Normal", 39, "{Open | Closed} Normal state of the relay. The relay reverts to this state for reset, change of mode, etc. " + "Defaults to \"State\" if not specifically declared."); + AddProperty("State", 40, "{Open | Closed} Actual state of the relay. Upon setting, immediately forces state of the relay, overriding the Relay control. " + "Simulates manual control on relay. Defaults to Closed. \"Open\" causes the controlled element to open and lock out. \"Closed\" causes the " + "controlled element to close and the relay to reset to its first operation."); + AddProperty("DOC_TiltAngleLow", 41, "Tilt angle for low-current trip line. Default is 90."); + AddProperty("DOC_TiltAngleHigh", 42, "Tilt angle for high-current trip line. Default is 90."); + AddProperty("DOC_TripSettingLow", 43, "Resistive trip setting for low-current line. Default is 0."); + AddProperty("DOC_TripSettingHigh", 44, "Resistive trip setting for high-current line. Default is -1 (deactivated). To activate, set a positive value. Must be greater than \"DOC_TripSettingLow\"."); + AddProperty("DOC_TripSettingMag", 45, "Trip setting for current magnitude (defines a circle in the relay characteristics). Default is -1 (deactivated). To activate, set a positive value."); + AddProperty("DOC_DelayInner", 46, "Trip time delay (sec) for operation in inner region for DOC relay, defined when \"DOC_TripSettingMag\" or \"DOC_TripSettingHigh\" are activate. Default is -1.0 (deactivated), meaning that " + "the relay characteristic is insensitive in the inner region (no trip). Set to 0 for instantaneous trip and >0 for a definite time delay. " + "If \"DOC_PhaseCurveInner\" is specified, time delay from curve is utilized instead."); + AddProperty("DOC_PhaseCurveInner", 47, "Name of the TCC Curve object that determines the phase trip for operation in inner region for DOC relay. Must have been previously defined as a TCC_Curve object. " + "Default is none (ignored). Multiplying the current values in the curve by the \"DOC_PhaseTripInner\" value gives the actual current."); + AddProperty("DOC_PhaseTripInner", 48, "Multiplier for the \"DOC_PhaseCurveInner\" TCC curve. Defaults to 1.0."); + AddProperty("DOC_TDPhaseInner", 49, "Time dial for \"DOC_PhaseCurveInner\" TCC curve. Multiplier on time axis of specified curve. Default=1.0."); + AddProperty("DOC_P1Blocking", 50, "{Yes/True* | No/False} Blocking element that impedes relay from tripping if balanced net three-phase active power is in the forward direction (i.e., flowing into the monitored terminal). " + "For a delayed trip, if at any given time the reverse power flow condition stops, the tripping is reset. Default=True."); + + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TRelay::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Relay and add it to Relay class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TRelayObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} +/*--------------------------------------------------------------------------*/ + +TTCC_CurveObj* TRelay::GetTccCurve(const String CurveName) +{ + TTCC_CurveObj* result = nullptr; + result = ((TTCC_CurveObj*) TCC_CurveClass->Find(CurveName)); + if(result == nullptr) + DoSimpleMsg(String("TCC Curve object: \"") + CurveName + "\" not found.", 380); + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TRelay::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + + // continue parsing WITH contents of Parser + ActiveRelayObj = (TRelayObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveRelayObj); + result = 0; + /*# with ActiveRelayObj do */ + { + auto with0 = ActiveRelayObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1],Param); + else + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Relay \"" + + with0->get_Name() + + "\"", 381); + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 0: + /*internal Relay Property commands*/ + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 382); + break; + case 1: + with0->MonitoredElementName = LowerCase(Param); + break; + case 2: + with0->MonitoredElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->ElementName = LowerCase(Param); + break; + case 4: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 5: + with0->InterpretRelayType(Param); + break; + case 6: + with0->PhaseCurve = GetTccCurve(Param); + break; + case 7: + with0->GroundCurve = GetTccCurve(Param); + break; + case 8: + with0->PhaseTrip = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->GroundTrip = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->PhaseInst = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->GroundInst = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->ResetTime = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->NumReclose = Parser[ActorID]->MakeInteger_() - 1; + break; // one less than number of shots + case 14: + if(CompareText(Param, "NONE") == 0) + with0->NumReclose = 0; + else + with0->NumReclose = Parser[ActorID]->ParseAsVector(4, with0->RecloseIntervals); + break; // max of 4 allowed + case 15: + with0->OVcurve = GetTccCurve(Param); + break; + case 16: + with0->UVCurve = GetTccCurve(Param); + break; + case 17: + with0->kVBase = Parser[ActorID]->MakeDouble_(); + break; + case 18: + with0->Breaker_time = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->MonitorVariable = LowerCase(Param); + break; // for pc elements + case 21: + with0->PctPickup46 = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->Isqt46 = Parser[ActorID]->MakeDouble_(); + break; + case 23: + with0->BaseAmps46 = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->Delay_Time = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->PctPickup47 = Parser[ActorID]->MakeDouble_(); + break; + case 26: + with0->OverTrip = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->UnderTrip = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->TDPhase = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->TDGround = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->Z1Mag = Parser[ActorID]->MakeDouble_(); + break; + case 31: + with0->Z1Ang = Parser[ActorID]->MakeDouble_(); + break; + case 32: + with0->Z0Mag = Parser[ActorID]->MakeDouble_(); + break; + case 33: + with0->Z0Ang = Parser[ActorID]->MakeDouble_(); + break; + case 34: + with0->Mphase = Parser[ActorID]->MakeDouble_(); + break; + case 35: + with0->Mground = Parser[ActorID]->MakeDouble_(); + break; + case 36: + with0->ShowEventLog = InterpretYesNo(Param); + break; + case 37: + with0->DebugTrace = InterpretYesNo(Param); + break; + case 38: + with0->Dist_Reverse = InterpretYesNo(Param); + break; + case 39: + { + with0->InterpretRelayState(ActorID, Param, ParamName); // set normal state + if(!with0->NormalStateSet) + with0->NormalStateSet = true; + } + break; + case 19: case 40: + with0->InterpretRelayState(ActorID, Param, ParamName); + break; // set state + case 41: + with0->DOC_TiltAngleLow = Parser[ActorID]->MakeDouble_(); + break; + case 42: + with0->DOC_TiltAngleHigh = Parser[ActorID]->MakeDouble_(); + break; + case 43: + with0->DOC_TripSetLow = Parser[ActorID]->MakeDouble_(); + break; + case 44: + with0->DOC_TripSetHigh = Parser[ActorID]->MakeDouble_(); + break; + case 45: + with0->DOC_TripSetMag = Parser[ActorID]->MakeDouble_(); + break; + case 46: + with0->DOC_DelayInner = Parser[ActorID]->MakeDouble_(); + break; + case 47: + with0->DOC_PhaseCurveInner = GetTccCurve(Param); + break; + case 48: + with0->DOC_PhaseTripInner = Parser[ActorID]->MakeDouble_(); + break; + case 49: + with0->DOC_TDPhaseInner = Parser[ActorID]->MakeDouble_(); + break; + case 50: + with0->DOC_P1Blocking = InterpretYesNo(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveRelayObj, ParamPointer - NumPropsThisClass); + break; + } + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + /*Default the controlled element to the monitored element*/ + with0->ElementName = with0->MonitoredElementName; + break; + case 2: + with0->ElementTerminal = with0->MonitoredElementTerminal; + break; /*Set Default Reclose Intervals*/ + case 5: + { + switch(LowerCase(Param)[0]) + { + case L'c': + with0->Set_PropertyValue(14,"[0.5, 2.0, 2.0]"); + break; + case L'v': + with0->Set_PropertyValue(14,"[5.0]"); + break; + case 'd': + switch(Param.size() >= 2 ? LowerCase(Param)[1] : '\0') + { + case 'o': + with0->Set_PropertyValue(14,"NONE"); + with0->NumReclose = 0; + break; + default: + break; + } + break; + default: + ; + break; + } + if (with0->Get_PropertyValue(14) != "NONE") + { + AuxParser[ActorID]->SetCmdString(with0->Get_PropertyValue(14)); + ParamName = AuxParser[ActorID]->GetNextParam(); + with0->NumReclose = AuxParser[ActorID]->ParseAsVector(4, with0->RecloseIntervals); + } + } + break; + case 19: case 40: + if(!with0->NormalStateSet) + { + with0->NormalStateSet = true; // 'normal state' defaults to 'state' only when the latter is specified for the first time + with0->set_NormalState(with0->FPresentState); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TRelay::MakeLike(const String RelayName) +{ + int result = 0; + TRelayObj* OtherRelay = nullptr; + int i = 0; + result = 0; + /*See if we can find this Relay name in the present collection*/ + OtherRelay = ((TRelayObj*) Find(RelayName)); + if(OtherRelay != nullptr) + /*# with ActiveRelayObj do */ + { + auto with0 = ActiveRelayObj; + int stop = 0; + with0->Set_NPhases(OtherRelay->Fnphases); + with0->Set_Nconds(OtherRelay->Fnconds); // Force Reallocation of terminal stuff + with0->ShowEventLog = OtherRelay->ShowEventLog; // but leave DebugTrace off + with0->ElementName = OtherRelay->ElementName; + with0->ElementTerminal = OtherRelay->ElementTerminal; + with0->Set_ControlledElement(OtherRelay->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherRelay->get_FMonitoredElement()); // Pointer to target circuit element + with0->MonitoredElementName = OtherRelay->MonitoredElementName; // Pointer to target circuit element + with0->MonitoredElementTerminal = OtherRelay->MonitoredElementTerminal; // Pointer to target circuit element + with0->PhaseCurve = OtherRelay->PhaseCurve; + with0->GroundCurve = OtherRelay->GroundCurve; + with0->OVcurve = OtherRelay->OVcurve; + with0->UVCurve = OtherRelay->UVCurve; + with0->PhaseTrip = OtherRelay->PhaseTrip; + with0->GroundTrip = OtherRelay->GroundTrip; + with0->TDPhase = OtherRelay->TDPhase; + with0->TDGround = OtherRelay->TDGround; + with0->PhaseInst = OtherRelay->PhaseInst; + with0->GroundInst = OtherRelay->GroundInst; + with0->ResetTime = OtherRelay->ResetTime; + with0->NumReclose = OtherRelay->NumReclose; + with0->Delay_Time = OtherRelay->Delay_Time; + with0->Breaker_time = OtherRelay->Breaker_time; + with0->RecloseIntervals = (pDoubleArray) realloc(with0->RecloseIntervals, sizeof(double) * 4); // Always make a max of 4 + for(stop = with0->NumReclose, i = 1; i <= stop; i++) + { + (with0->RecloseIntervals)[i - 1] = (OtherRelay->RecloseIntervals)[i - 1]; + } + // deleted... if DebugTrace then AppendToEventLog ('Relay.'+self.Name, Format ('MakeLike NumReclose=%d',[NumReclose]), ActorID); + with0->kVBase = OtherRelay->kVBase; + with0->LockedOut = OtherRelay->LockedOut; + with0->FPresentState = OtherRelay->FPresentState; + with0->set_NormalState(OtherRelay->get_NormalState()); + with0->ControlType = OtherRelay->ControlType; + with0->CondOffset = OtherRelay->CondOffset; + + /*46 Relay Neg Seq Current*/ + with0->PickupAmps46 = OtherRelay->PickupAmps46; + with0->PctPickup46 = OtherRelay->PctPickup46; + with0->BaseAmps46 = OtherRelay->BaseAmps46; + with0->Isqt46 = OtherRelay->Isqt46; + + /*47 Relay*/ + with0->PickupVolts47 = OtherRelay->PickupVolts47; + with0->PctPickup47 = OtherRelay->PctPickup47; + + /*Generic Relay*/ + with0->MonitorVariable = OtherRelay->MonitorVariable; + with0->OverTrip = OtherRelay->OverTrip; + with0->UnderTrip = OtherRelay->UnderTrip; + + /*Distance Relays*/ + with0->Z1Mag = OtherRelay->Z1Mag; + with0->Z1Ang = OtherRelay->Z1Ang; + with0->Z0Mag = OtherRelay->Z0Mag; + with0->Z0Ang = OtherRelay->Z0Ang; + with0->Mphase = OtherRelay->Mphase; + with0->Mground = OtherRelay->Mground; + with0->Dist_Reverse = OtherRelay->Dist_Reverse; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherRelay->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Relay MakeLike: \"") + RelayName + "\" Not Found.", 383); + return result; +} + + + + +/*==========================================================================*/ +/* TRelayObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TRelayObj::TRelayObj(TDSSClass* ParClass, const String RelayName) + : inherited(ParClass), + ControlType(0), + PhaseCurve(nullptr), + GroundCurve(nullptr), + PhaseTrip(0.0), + GroundTrip(0.0), + PhaseInst(0.0), + GroundInst(0.0), + RecloseIntervals(nullptr), + NumReclose(0), + ResetTime(0.0), + Delay_Time(0.0), + Breaker_time(0.0), + TDPhase(0.0), + TDGround(0.0), + OVcurve(nullptr), + UVCurve(nullptr), + VBase(0.0), + kVBase(0.0), + PickupAmps46(0.0), + PctPickup46(0.0), + BaseAmps46(0.0), + Isqt46(0.0), + PickupVolts47(0.0), + PctPickup47(0.0), + Z1Mag(0.0), + Z1Ang(0.0), + Z0Mag(0.0), + Z0Ang(0.0), + Mphase(0.0), + Mground(0.0), + Dist_Reverse(false), + td21_i(0), + td21_next(0), + td21_pt(0), + td21_stride(0), + td21_quiet(0), + td21_h(nullptr), + td21_Uref(nullptr), + td21_dV(nullptr), + td21_dI(nullptr), + OverTrip(0.0), + UnderTrip(0.0), + OperationCount(0), + LockedOut(false), + ArmedForClose(false), + ArmedForOpen(false), + ArmedForReset(false), + PhaseTarget(false), + GroundTarget(false), + NormalStateSet(false), + NextTriptime(0.0), + LastEventHandle(0), + CondOffset(0), + cBuffer(nullptr), + cvBuffer(nullptr), + DebugTrace(false), + MonitoredElementTerminal(0) +{ + Set_Name(LowerCase(RelayName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + MonitoredElementName = ""; + MonitoredElementTerminal = 1; + Set_MonitoredElement(nullptr); + RelayTarget = ""; + PhaseCurve = nullptr; + GroundCurve = nullptr; + OVcurve = nullptr; + UVCurve = nullptr; + PhaseTrip = 1.0; + GroundTrip = 1.0; + TDPhase = 1.0; + TDGround = 1.0; + PhaseInst = 0.0; + GroundInst = 0.0; + ResetTime = 15.0; + NumReclose = 3; + RecloseIntervals = nullptr; + RecloseIntervals = new double[4]; // fixed allocation of 4 + (RecloseIntervals)[1 - 1] = 0.5; + (RecloseIntervals)[2 - 1] = 2.0; + (RecloseIntervals)[3 - 1] = 2.0; + FPresentState = CTRL_CLOSE; + FNormalState = CTRL_CLOSE; + NormalStateSet = false; + Isqt46 = 1.0; + BaseAmps46 = 100.0; + PctPickup46 = 20.0; + PickupAmps46 = BaseAmps46 * PctPickup46 * 0.01; + PctPickup47 = 2.0; + OverTrip = 1.2; + UnderTrip = 0.8; + Z1Mag = 0.7; + Z1Ang = 64.0; + Z0Mag = 2.1; + Z0Ang = 68.0; + Mphase = 0.7; + Mground = 0.7; + td21_i = -1; + td21_h = nullptr; + td21_dV = nullptr; + td21_Uref = nullptr; + td21_dI = nullptr; + td21_pt = 0; + td21_stride = 0; + td21_quiet = 0; + Dist_Reverse = false; + DOC_TiltAngleLow = 90.0; + DOC_TiltAngleHigh = 90.0; + DOC_TripSetLow = 0; + DOC_TripSetHigh = -1.0; + DOC_TripSetMag = -1.0; + DOC_DelayInner = -1.0; + DOC_PhaseCurveInner = nullptr; + DOC_PhaseTripInner = 1.0; + DOC_TDPhaseInner = 1.0; + DOC_P1Blocking = true; + OperationCount = 1; + LockedOut = false; + ArmedForOpen = false; + ArmedForClose = false; + ArmedForReset = false; + PhaseTarget = false; + GroundTarget = false; + NextTriptime = -1.0; // not set to trip + cBuffer = nullptr; // Complex buffer + cvBuffer = nullptr; + DSSObjType = ParClass->DSSClassType; //cap_CONTROL; + InitPropertyValues(0); + + + + // RecalcElementData; +} + +TRelayObj::~TRelayObj() +{ + MonitoredElementName = ""; + free(RecloseIntervals); + if(ASSIGNED(cBuffer)) + free(cBuffer); + if(ASSIGNED(cvBuffer)) + free(cvBuffer); + if(ASSIGNED(td21_h)) + free(td21_h); + if(ASSIGNED(td21_dV)) + free(td21_dV); + if(ASSIGNED(td21_Uref)) + free(td21_Uref); + if(ASSIGNED(td21_dI)) + free(td21_dI); + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + if(DebugTrace) + { + AppendToEventLog(String("Relay.") + this->get_Name(), Format("RecalcElementData NumReclose=%d", NumReclose), ActorID); + } + DevIndex = GetCktElementIndex(MonitoredElementName); // Global function + if(DevIndex > 0) + { + Set_MonitoredElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); // Force number of phases to be same + if(MonitoredElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("Relay: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 384); + } + else + + // Sets name of i-th terminal's connected bus in Relay's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(MonitoredElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer = (pComplexArray) realloc(cBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + if((ControlType == Distance) || (ControlType == TD21) || (ControlType == DOC)) + cvBuffer = (pComplexArray)realloc(cvBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + CondOffset = (MonitoredElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + switch(ControlType) + { + case GENERIC: + { + if(( ( (TDSSObject*) get_FMonitoredElement() )->DSSObjType & BaseClassMask) != PC_ELEMENT) + DoSimpleMsg(String("Relay ") + get_Name() + ": Monitored element for Generic relay is not a PC Element.", 385); + else + { + MonitorVarIndex = ((TPCElement*) get_FMonitoredElement())->LookupVariable(MonitorVariable); + if(MonitorVarIndex < 1) // oops + { + DoSimpleMsg(String("Relay ") + get_Name() + + ": Monitor variable \"" + + MonitorVariable + + "\" does not exist.", 386); + } + } + } + break; + default: + ; + break; + } + } + } + +/*Check for existence of Controlled Element*/ + + // If previously assigned, reset HasOCPDevice flag in case this is a move + if(ASSIGNED(get_FControlledElement())) + { + get_FControlledElement()->HasOCPDevice = false; + get_FControlledElement()->HasAutoOCPDevice = false; + } + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Both CktElement and monitored element must already exist + { + Set_ControlledElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Make the 1 st terminal active + + // If the relay becomes disabled, leave at False + if(Get_Enabled()) + { + get_FControlledElement()->HasOCPDevice = true; // For Reliability calcs + get_FControlledElement()->HasAutoOCPDevice = true; // For Reliability calcs + } + if(FPresentState == CTRL_CLOSE) // Open/Close State of controlled element based on state assigned to the control + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); + LockedOut = false; + OperationCount = 1; + ArmedForOpen = false; + } + else + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); + LockedOut = true; + OperationCount = NumReclose + 1; + ArmedForClose = false; + } + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("Relay: \"") + this->get_Name() + "\"", String("CktElement Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 387); + } + + /*Misc stuff*/ + PickupAmps46 = BaseAmps46 * PctPickup46 * 0.01; + switch(Fnphases) + { + case 1: + VBase = kVBase * 1000.0; + break; + default: + VBase = kVBase / SQRT3 * 1000.0; + break; + } + PickupVolts47 = VBase * PctPickup47 * 0.01; + if((ControlType == Distance) || (ControlType == TD21)) + { + Dist_Z1 = pclx(Z1Mag, Z1Ang / RadiansToDegrees); + Dist_Z0 = pclx(Z0Mag, Z0Ang / RadiansToDegrees); + Dist_K0 = cdiv(cdivreal(csub(Dist_Z0, Dist_Z1), 3.0), Dist_Z1); + } +} + +void TRelayObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + // Allocate a buffer big enough to hold everything from the monitored element + cBuffer = (pComplexArray)realloc(cBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + if((ControlType == Distance) || (ControlType == TD21) || (ControlType == DOC)) + cvBuffer = (pComplexArray)realloc(cvBuffer, sizeof(complex) * get_FMonitoredElement()->Yorder); + CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + switch(Fnphases) + { + case 1: + VBase = kVBase * 1000.0; + break; + default: + VBase = kVBase / SQRT3 * 1000.0; + break; + } + PickupVolts47 = VBase * PctPickup47 * 0.01; + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} +/*--------------------------------------------------------------------------*/ + +void TRelayObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + if(DebugTrace) + { + AppendToEventLog(String("Relay.") + this->get_Name(), Format("DoPendingAction Code=%d State=%d ArmedOpen=%s Close=%s Reset=%s Count=%d NumReclose=%d", + Code, ( FPresentState), BoolToStr(ArmedForOpen).c_str(), BoolToStr(ArmedForClose).c_str(), BoolToStr(ArmedForReset).c_str(), OperationCount, NumReclose), ActorID); + } + /*# with ControlledElement do */ + { + auto with0 = get_FControlledElement(); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal of CktElement to terminal 1 + switch(Code) + { + case ( CTRL_OPEN): + switch(FPresentState) + { + case CTRL_CLOSE: + if(ArmedForOpen) // ignore if we became disarmed in meantime + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); // Open all phases of active terminal + if(OperationCount > NumReclose) + { + LockedOut = true; + if(ShowEventLog) + AppendToEventLog(String("Relay.") + this->get_Name(), String("Opened on ") + RelayTarget + " & Locked Out ", ActorID); + } + else + { + if(ShowEventLog) + AppendToEventLog(String("Relay.") + this->get_Name(), String("Opened on ") + RelayTarget, ActorID); + } + if(PhaseTarget) + { + if(ShowEventLog) + AppendToEventLog(" ", "Phase Target", ActorID); + } + if(GroundTarget) + { + if(ShowEventLog) + AppendToEventLog(" ", "Ground Target", ActorID); + } + ArmedForOpen = false; + if(ControlType == TD21) + td21_quiet = td21_pt + 1; + } + break; /*nada*/ + default: + ; + break; + } + break; + case ( CTRL_CLOSE): + switch(FPresentState) + { + case CTRL_OPEN: + if(ArmedForClose && !LockedOut) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); // Close all phases of active terminal + ++OperationCount; + if(ShowEventLog) + AppendToEventLog(String("Relay.") + this->get_Name(), "Closed", ActorID); + ArmedForClose = false; + if(ControlType == TD21) + td21_quiet = (td21_pt / 2); + } + break; /*Nada*/ + default: + ; + break; + } + break; + case ( CTRL_RESET): + if(ArmedForReset && !LockedOut) + { + if(ShowEventLog) + AppendToEventLog(String("Relay.") + this->get_Name(), "Reset", ActorID); + Reset(ActorID); + if(ControlType == TD21) + td21_quiet = (td21_pt / 2); + } + else + + /*Do Nothing */ + ; + break; + default: + ; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::InterpretRelayState(int ActorID, const String Action, const String property_name) +{ + if((LowerCase(property_name)[0] == 's') || (LowerCase(property_name)[0] == 'a')) // state or action (deprecated) + { + switch(LowerCase(Action)[0]) + { + case L'o': + case L't': + FPresentState = CTRL_OPEN; + break; + case L'c': + FPresentState = CTRL_CLOSE; + break; + default: + ; + break; + } + } + else + // Normal + { + switch(LowerCase(Action)[0]) + { + case L'o': + case L't': + FNormalState = CTRL_OPEN; + break; + case L'c': + FNormalState = CTRL_CLOSE; + break; + default: + ; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TRelayObj::sample(int ActorID) +{ + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + if(get_FControlledElement()->Get_ConductorClosed(0, ActorID)) + FPresentState = CTRL_CLOSE; + else + FPresentState = CTRL_OPEN; + switch(ControlType) + { + case Current: + OvercurrentLogic(ActorID); + break; /*Current*/ + case VOLTAGE: + VoltageLogic(ActorID); + break; /*Reclosing Voltage Relay - definite time*/ + case REVPOWER: + RevPowerLogic(ActorID); + break; // one shot to lockout + case NEGCURRENT: + NegSeq46Logic(ActorID); + break; // one shot to lockout + case NEGVOLTAGE: + NegSeq47Logic(ActorID); + break; // one shot to lockout + case GENERIC: + GenericLogic(ActorID); + break;// one shot to lockout + case Distance: + DistanceLogic(ActorID); + break; + case TD21: + TD21Logic(ActorID); + break; + case DOC: + DirectionalOvercurrentLogic(ActorID); + break; + default: + ; + break; + } +} + + + +/*--------------------------------------------------------------------------*/ + +/*Note PropertyValue is aligned with the internal indices*/ + +void TRelayObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue((with0->PropertyIdxMap)[i - 1])); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +String TRelayObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + result = ""; + /*# with ParentClass do */ + { + auto with0 = ParentClass; + switch(Index) + { + case 13: + result = Format("%d", NumReclose + 1); + break; + case 14: + { + if(NumReclose == 0) + result = result + "NONE"; + else + { + int stop = 0; + result = "("; + for(stop = NumReclose, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", (RecloseIntervals)[i - 1]); + } + result = result + ")"; + } + } + break; + case 39: + { + switch(FNormalState) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "closed"; + break; + } + } + break; + case 19: + case 40: + { + switch(FPresentState) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "closed"; + break; + } + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + } + return result; +} + +void TRelayObj::Reset(int ActorID) +{ + if(ShowEventLog) + AppendToEventLog(String("Relay.") + this->get_Name(), "Resetting", ActorID); + FPresentState = FNormalState; + ArmedForOpen = false; + ArmedForClose = false; + ArmedForReset = false; + PhaseTarget = false; + GroundTarget = false; + NextTriptime = -1.0; // not set to trip + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(FNormalState) + { + case CTRL_OPEN: + { + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); // Open all phases of active terminal + LockedOut = true; + OperationCount = NumReclose + 1; + } + break; + /*CTRL_CLOSE*/ + default: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); // Close all phases of active terminal + LockedOut = false; + OperationCount = 1; + break; + } + } +} + +EControlAction TRelayObj::get_State() +{ + EControlAction result; + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + if(get_FControlledElement()->Get_ConductorClosed(0, ActiveActor)) + { + /*TRUE:*/ + FPresentState = CTRL_CLOSE; + } else { + FPresentState = CTRL_OPEN; + } + } + result = FPresentState; + return result; +} + +void TRelayObj::set_State(const EControlAction Value) +{ + if(get_State() != Value) + { + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(Value) + { + case CTRL_OPEN: + { + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); + LockedOut = true; + OperationCount = NumReclose + 1; + ArmedForClose = false; + ArmedForReset = false; + } + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); + LockedOut = false; + OperationCount = 1; + ArmedForOpen = false; + ArmedForReset = false; + break; + } + } + FPresentState = Value; + } +} + +EControlAction TRelayObj::get_NormalState() +{ + EControlAction result; + result = FNormalState; + return result; +} + +void TRelayObj::set_NormalState(const EControlAction Value) +{ + if(FNormalState != Value) + { + FNormalState = Value; + } +} + +void TRelayObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,""); + Set_PropertyValue(4,"1"); //'terminal'; + Set_PropertyValue(5,"current"); + Set_PropertyValue(6,""); + Set_PropertyValue(7,""); + Set_PropertyValue(8,"1.0"); + Set_PropertyValue(9,"1.0"); + Set_PropertyValue(10,"0.0"); + Set_PropertyValue(11,"0.0"); + Set_PropertyValue(12,"15"); + Set_PropertyValue(13,"4"); + Set_PropertyValue(14,"(0.5, 2.0, 2.0)"); + Set_PropertyValue(15,""); + Set_PropertyValue(16,""); + Set_PropertyValue(17,"0.0"); + Set_PropertyValue(18,"0.0"); + Set_PropertyValue(19,"closed"); + Set_PropertyValue(20,""); + Set_PropertyValue(21,"20"); + Set_PropertyValue(22,"1"); + Set_PropertyValue(23,"100"); + Set_PropertyValue(24,"0"); + Set_PropertyValue(25,"2"); + Set_PropertyValue(26,"1.2"); + Set_PropertyValue(27,"0.8"); + Set_PropertyValue(28,"1.0"); + Set_PropertyValue(29,"1.0"); + Set_PropertyValue(30,"0.7"); + Set_PropertyValue(31,"64.0"); + Set_PropertyValue(32,"2.1"); + Set_PropertyValue(33,"68.0"); + Set_PropertyValue(34,"0.7"); + Set_PropertyValue(35,"0.7"); + if (ShowEventLog) Set_PropertyValue(36,"YES"); else Set_PropertyValue(36,"NO"); + Set_PropertyValue(37,"No"); + Set_PropertyValue(39,"closed"); + Set_PropertyValue(40,"closed"); + Set_PropertyValue(41,"90.0"); + Set_PropertyValue(42,"90.0"); + Set_PropertyValue(43,"0.0"); + Set_PropertyValue(44,"-1.0"); + Set_PropertyValue(45,"-1.0"); + Set_PropertyValue(46,"-1.0"); + Set_PropertyValue(47,""); + Set_PropertyValue(48,"1.0"); + Set_PropertyValue(49,"1.0"); + Set_PropertyValue(50,"Yes"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TRelayObj::InterpretRelayType(const String s) +{ + switch(LowerCase(s)[0]) + { + case L'c': + ControlType = Current; + break; + case L'v': + ControlType = VOLTAGE; + break; + case L'r': + ControlType = REVPOWER; + break; + case L'4': + switch(s.size() >= 2 ? LowerCase(s)[1] : '\0') + { + case L'6': + ControlType = NEGCURRENT; + break; + case L'7': + ControlType = NEGVOLTAGE; + break; + default: + ; + break; + } + break; + case L'g': + ControlType = GENERIC; + break; + case L'd': + switch(s.size() >= 2 ? LowerCase(s)[1] : '\0') + { + case 'i': + ControlType = Distance; + break; + case 'o': + ControlType = DOC; + default: + break; + } + break; + case L't': + ControlType = TD21; + break; + default: + ControlType = Current; + break; + } + + /*Set Definite Time Defaults*/ + switch(LowerCase(s)[0]) + { + case L'c': + Delay_Time = 0.0; + break; + case L'v': + Delay_Time = 0.0; + break; + case L'r': + Delay_Time = 0.1; + break; + case L'4': + Delay_Time = 0.1; + break; + case L'g': + Delay_Time = 0.1; + break; + case L'd': + switch(s.size() >= 2 ? LowerCase(s)[1] : '\0') + { + case 'i': + Delay_Time = 0.1; + break; + case 'o': + Delay_Time = 0.0; + break; + default: + break; + } + break; + case L't': + Delay_Time = 0.1; + break; + default: + Delay_Time = 0.0; + break; + } + Set_PropertyValue(24,Format("%-.g", Delay_Time)); +} +/* Generic relays only work on PC Elements With control terminals +*/ + +void TRelayObj::GenericLogic(int ActorID) +{ + double varValue = 0.0; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + varValue = ((TPCElement*) get_FMonitoredElement())->Get_Variable(MonitorVarIndex); + + /*Check for Trip*/ + if((varValue > OverTrip) || (varValue < UnderTrip)) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // push the trip operation and arm to trip + RelayTarget = ((TPCElement*) get_FMonitoredElement())->VariableName(MonitorVarIndex); + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + Delay_Time + Breaker_time, CTRL_OPEN, 0, this, ActorID); + OperationCount = NumReclose + 1; // force a lockout + ArmedForOpen = true; + } + } + else + /*Within bounds*/ /*Less Than pickup value: reset if armed*/ + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // We became unarmed, so reset and disarm + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + } + } + } /*With MonitoredElement*/ +} + +/* + Negative Sequence Current Relay + Patterned after Basler relay +*/ + +void TRelayObj::NegSeq46Logic(int ActorID) +{ + double NegSeqCurrentMag = 0.0; + double TripTime = 0.0; + int IOffset = 0; + complex I012[3] = {cmplx(0,0), cmplx(0,0) ,cmplx(0,0) }; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + get_FMonitoredElement()->Set_ActiveTerminal(MonitoredElementTerminal); + get_FMonitoredElement()->GetCurrents(cBuffer, ActorID); + IOffset = (MonitoredElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // offset for active terminal + Phase2SymComp((pComplexArray) &(cBuffer)[IOffset + 1 - 1], &I012[0]); + NegSeqCurrentMag = cabs(I012[3 - 1]); + if(NegSeqCurrentMag >= PickupAmps46) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // push the trip operation and arm to trip + RelayTarget = "-Seq Curr"; + /*simple estimate of trip time assuming current will be constant*/ + if(Delay_Time > 0.0) + TripTime = Delay_Time; + else + TripTime = Isqt46 / Sqr(NegSeqCurrentMag / BaseAmps46); // Sec + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time, CTRL_OPEN, 0, this, ActorID); + OperationCount = NumReclose + 1; // force a lockout + ArmedForOpen = true; + } + } + else + /*Less Than pickup value: reset if armed*/ + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // We became unarmed, so reset and disarm + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + } + } + } /*With MonitoredElement*/ +} + +void TRelayObj::OvercurrentLogic(int ActorID) +{ + int i = 0; + double cmag = 0.0; + complex Csum = {}; + double Groundtime = 0.0; + double PhaseTime = 0.0; + double TripTime = 0.0; + double TimeTest = 0.0; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + if(FPresentState == CTRL_CLOSE) + { + TripTime = -1.0; + Groundtime = -1.0; + PhaseTime = -1.0; /*No trip*/ + + // Check largest Current of all phases of monitored element + get_FMonitoredElement()->GetCurrents(cBuffer, ActorID); + + /*Check Ground Trip, if any*/ + if(((GroundCurve != nullptr) || (Delay_Time > 0.0)) && (GroundTrip > 0.0)) + { + int stop = 0; + Csum = CZero; + for(stop = (with0->Fnphases + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + caccum(Csum, (cBuffer)[i - 1]); + } + cmag = cabs(Csum); + if((GroundInst > 0.0) && (cmag >= GroundInst) && (OperationCount == 1)) // Inst trip on first operation + Groundtime = 0.01 + Breaker_time; + else + { + if(Delay_Time > 0.0) // Definite Time Ground Relay + { + if(cmag >= GroundTrip) + Groundtime = Delay_Time; + else + Groundtime = -1.0; + } + else + Groundtime = TDGround * GroundCurve->GetTCCTime(cmag / GroundTrip); + } + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Ground Trip: Mag=%.3g, Mult=%.3g, Time=%.3g", + cmag, cmag / GroundTrip, Groundtime), ActorID); + } + if(Groundtime > 0.0) + { + TripTime = Groundtime; + GroundTarget = true; + } + + // If GroundTime > 0 then we have a ground trip + + /*Check Phase Trip, if any*/ + if(((PhaseCurve != nullptr) || (Delay_Time > 0.0)) && (PhaseTrip > 0.0)) + { + int stop = 0; + for(stop = (with0->Fnphases + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + cmag = cabs((cBuffer)[i - 1]); + if((PhaseInst > 0.0) && (cmag >= PhaseInst) && (OperationCount == 1)) + { + PhaseTime = 0.01 + Breaker_time; // Inst trip on first operation + break; + } + else + { + if(Delay_Time > 0.0) // Definite Time Phase Relay + { + if(cmag >= PhaseTrip) + TimeTest = Delay_Time; + else + TimeTest = -1.0; + } + else + TimeTest = TDPhase * PhaseCurve->GetTCCTime(cmag / PhaseTrip); + if(TimeTest > 0.0) + { + if(PhaseTime < 0.0) + PhaseTime = TimeTest; + else + PhaseTime = min(PhaseTime, TimeTest); + } + } + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Phase %d Trip: Mag=%.3g, Mult=%.3g, Time=%.3g", + i - CondOffset, cmag, cmag / PhaseTrip, PhaseTime), ActorID); + } + } + // If PhaseTime > 0 then we have a phase trip + if(PhaseTime > 0.0) + { + PhaseTarget = true; + if(TripTime > 0.0) + TripTime = min(TripTime, PhaseTime); + else + TripTime = PhaseTime; + } + if(TripTime > 0.0) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // Then arm for an open operation + RelayTarget = ""; + if(PhaseTime > 0.0) + RelayTarget = RelayTarget + "Ph"; + if(Groundtime > 0.0) + RelayTarget = RelayTarget + " Gnd"; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time, CTRL_OPEN, 0, this, ActorID); + if(OperationCount <= NumReclose) + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time + (RecloseIntervals)[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + ArmedForOpen = true; + ArmedForClose = true; + } + } + else + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // If current dropped below pickup, disarm trip and set for reset + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + ArmedForClose = false; + PhaseTarget = false; + GroundTarget = false; + } + } + } /*IF PresentState=CLOSE*/ + } /*With MonitoredElement*/ +} + +void TRelayObj::DistanceLogic(int ActorID) +{ + int i = 0; + int j = 0; + complex Vloop = {}; + complex Iloop = {}; + complex Zloop = {}; + complex Ires = {}; + complex kIres = {}; + complex Zreach = {}; + double I2 = 0.0; + double min_distance = 0.0; + double fault_distance = 0.0; + double t_event = 0.0; + TStringList Targets; + bool PickedUp = false; + if(!LockedOut) + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + int stop = 0; + PickedUp = false; + min_distance = 1.0e30; + get_FMonitoredElement()->GetCurrents(cBuffer, ActorID); + if(Dist_Reverse) + { + int stop = 0; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + (cBuffer)[i + CondOffset - 1] = cnegate((cBuffer)[i + CondOffset - 1]); + } + } + Ires = CZero; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + caccum(Ires, (cBuffer)[i + CondOffset - 1]); + } + kIres = cmul(Dist_K0, Ires); + get_FMonitoredElement()->GetTermVoltages(MonitoredElementTerminal, cvBuffer, ActorID); + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = get_FMonitoredElement()->Get_NPhases(), j = i; j <= stop1; j++) + { + if(i == j) + { + Vloop = (cvBuffer)[i - 1]; + Iloop = cadd((cBuffer)[i + CondOffset - 1], kIres); + Zreach = cmulreal(Dist_Z1, Mground); // not Dist_Z0 because it's included in Dist_K0 + } + else + { + Vloop = csub((cvBuffer)[i - 1], (cvBuffer)[j - 1]); + Iloop = csub((cBuffer)[i + CondOffset - 1], (cBuffer)[j + CondOffset - 1]); + Zreach = cmulreal(Dist_Z1, Mphase); + } + I2 = Iloop.re * Iloop.re + Iloop.im * Iloop.im; + if(I2 > 0.1) + { + Zloop = cdiv(Vloop, Iloop); + // start with a very simple rectangular characteristic + if (DebugTrace && (ActiveCircuit[ActiveActor]->Solution->DynaVars.T > 0.043)) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Zloop[%d,%d]=%.4f+j%.4f", + i, j, Zloop.re, Zloop.im), ActorID); + if((Zloop.re >= 0) && (Zloop.im >= MIN_DISTANCE_REACTANCE) && (Zloop.re <= Zreach.re) && (Zloop.im <= Zreach.im)) + { + if(!PickedUp) + { + Targets.clear(); + //Targets->Sorted = true; + } + if(i == j) + { + Targets.push_back(Format("G%d", i)); + } + else + { + Targets.push_back(Format("P%d%d", i, j)); + } + fault_distance = cabs2(Zloop) / cabs2(Zreach); + if(fault_distance < min_distance) + min_distance = fault_distance; + PickedUp = true; + } + } + } + } + if(PickedUp) + { + if(DebugTrace) + { + AppendToEventLog(String("Relay.") + this->get_Name(), "Picked up", ActorID); + } + if(ArmedForReset) + { + ActiveCircuit[ActorID]->ControlQueue.Delete(LastEventHandle, ActorID); + ArmedForReset = false; + } + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + RelayTarget = Format("21 %.3f pu dist", min_distance); + t_event = ActiveCircuit[ActorID]->Solution->DynaVars.T + Delay_Time + Breaker_time; + for(stop = Pred(Targets.size()), i = 0; i <= stop; i++) + { + RelayTarget = RelayTarget + " " + (Targets)[i]; + } + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, t_event, CTRL_OPEN, 0, this, ActorID); + ArmedForOpen = true; + if(OperationCount <= NumReclose) + { + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, t_event + (RecloseIntervals)[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + ArmedForClose = true; + } + } + Targets.clear(); + } + else + // not picked up; reset if necessary + { + if((OperationCount > 1) && (ArmedForReset == false)) // this implements the reset, whether picked up or not + { + ArmedForReset = true; + /*# with ActiveCircuit[ActorID] do */ + { + + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + } + } + if(ArmedForOpen) // this implements the drop-out, if picked up + { + ArmedForOpen = false; + ArmedForClose = false; + } + } + } /*With MonitoredElement*/ +} + +void TRelayObj::TD21Logic(int ActorID) +{ + int i = 0; + int j = 0; + complex Vloop = {}; + complex Iloop = {}; + complex Zhsd = {}; + complex Zdir = {}; + complex Uhsd = {}; + complex Uref = {}; + complex Ires = {}; + complex kIres = {}; + double I2 = 0.0; + double i2fault = 0.0; + double min_distance = 0.0; + double fault_distance = 0.0; + double Uref2 = 0.0; + double Uhsd2 = 0.0; + double t_event = 0.0; + double DT = 0.0; + TStringList Targets; + bool PickedUp = false; + bool FaultDetected = false; + int iB = 0; + int iv = 0; + int II = 0; + DT = ActiveCircuit[ActorID]->Solution->DynaVars.h; + if(DT > 0.0) + { + if(DT > 1.0 / ActiveCircuit[ActorID]->Solution->get_FFrequency()) + DoErrorMsg(String("Relay: \"") + get_Name() + "\"", "Has type TD21 with time step greater than one cycle.", "Reduce time step, or change type to Distance.", 388); + i = Round(1.0 / 60.0 / DT + 0.5); + if(i > td21_pt) + { + td21_i = 0; // ring buffer index to be incremented before actual use + td21_pt = i; + td21_quiet = td21_pt + 1; + td21_stride = 2 * Get_NPhases(); + td21_h = (pComplexArray)realloc(td21_h, sizeof(complex) * td21_stride * td21_pt); + td21_dV = (pComplexArray)realloc(td21_dV, sizeof(complex) * Get_NPhases()); + td21_Uref = (pComplexArray)realloc(td21_Uref, sizeof(complex) * Get_NPhases()); + td21_dI = (pComplexArray)realloc(td21_dI, sizeof(complex) * Get_NPhases()); + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("TD21 prep %d phases, %.3g dt, %d points, %d elements", + Get_NPhases(), DT, td21_pt, td21_stride * td21_pt), ActorID); + } + } + if(!LockedOut) + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + int stop = 0; + FaultDetected = false; + get_FMonitoredElement()->GetCurrents(cBuffer, ActorID); + if(Dist_Reverse) + { + int stop = 0; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + (cBuffer)[i + CondOffset - 1] = cnegate((cBuffer)[i + CondOffset - 1]); + } + } + i2fault = PhaseTrip * PhaseTrip; + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + I2 = cabs2((cBuffer)[i + CondOffset - 1]); + if(I2 > i2fault) + FaultDetected = true; + } + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), "FaultDetected=" +BoolToStr(FaultDetected), ActorID); + get_FMonitoredElement()->GetTermVoltages(MonitoredElementTerminal, cvBuffer, ActorID); + if(td21_i < 1) + { + int stop = 0; + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), "Initialize cqueue", ActorID); + for(stop = td21_pt, i = 1; i <= stop; i++) + { + int stop1 = 0; + iB = (i - 1) * td21_stride; + for(stop1 = with0->Get_NPhases(), j = 1; j <= stop1; j++) + { + iv = iB + j; + (td21_h)[iv - 1] = (cvBuffer)[j - 1]; + II = iB + with0->Get_NPhases() + j; + (td21_h)[II - 1] = (cBuffer)[j + CondOffset - 1]; + } + } + td21_i = 1; + } + td21_next = (td21_i % td21_pt) + 1; // this points to the oldest sample, and the next write location + // calculate the differential currents and voltages + iB = (td21_next - 1) * td21_stride; + for(stop = with0->Get_NPhases(), j = 1; j <= stop; j++) + { + iv = iB + j; + (td21_Uref)[j - 1] = (td21_h)[iv - 1]; + (td21_dV)[j - 1] = csub((cvBuffer)[j - 1], (td21_h)[iv - 1]); + II = iB + with0->Get_NPhases() + j; + (td21_dI)[j - 1] = csub((cBuffer)[j + CondOffset - 1], (td21_h)[II - 1]); + } +// if DebugTrace then begin +// AppendToEventLog ('Relay.'+self.Name, Format ('Sample len=%d idx=%d next=%d', [td21_pt, td21_i, td21_next])); +// AppendToEventLog ('Relay.'+self.Name, Format('Vp %10.2f+j%10.2f %10.2f+j%10.2f %10.2f+j%10.2f', +// [cvBuffer^[1].re, cvBuffer^[1].im, cvBuffer^[2].re, cvBuffer^[2].im, cvBuffer^[3].re, cvBuffer^[3].im])); +// AppendToEventLog ('Relay.'+self.Name, Format('Ip %10.2f+j%10.2f %10.2f+j%10.2f %10.2f+j%10.2f', +// [cBuffer^[1 + CondOffset].re, cBuffer^[1 + CondOffset].im, +// cBuffer^[2 + CondOffset].re, cBuffer^[2 + CondOffset].im, +// cBuffer^[3 + CondOffset].re, cBuffer^[3 + CondOffset].im])); +// AppendToEventLog ('Relay.'+self.Name, Format('DV %10.2f+j%10.2f %10.2f+j%10.2f %10.2f+j%10.2f', +// [td21_dV^[1].re, td21_dV^[1].im, td21_dV^[2].re, td21_dV^[2].im, td21_dV^[3].re, td21_dV^[3].im])); +// AppendToEventLog ('Relay.'+self.Name, Format('DI %10.2f+j%10.2f %10.2f+j%10.2f %10.2f+j%10.2f', +// [td21_dI^[1].re, td21_dI^[1].im, td21_dI^[2].re, td21_dI^[2].im, td21_dI^[3].re, td21_dI^[3].im])); +// end; + // do the relay processing + if(ActiveCircuit[ActorID]->Solution->DynaVars.IterationFlag < 1) +// if DebugTrace then AppendToEventLog ('Relay.'+self.Name, 'Advance cqueue write pointer'); + { + int stop = 0; + iB = (td21_i - 1) * td21_stride; + for(stop = with0->Get_NPhases(), j = 1; j <= stop; j++) + { + iv = iB + j; + (td21_h)[iv - 1] = (cvBuffer)[j - 1]; + II = iB + with0->Get_NPhases() + j; + (td21_h)[II - 1] = (cBuffer)[j + CondOffset - 1]; + } + td21_i = td21_next; + if(td21_quiet > 0) + --td21_quiet; + } + if(td21_quiet <= 0) // one cycle since we started, or since the last operation + { + int stop = 0; + PickedUp = false; + min_distance = 1.0e30; + Ires = CZero; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + caccum(Ires, (td21_dI)[i - 1]); + } + kIres = cmul(Dist_K0, Ires); + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = get_FMonitoredElement()->Get_NPhases(), j = i; j <= stop1; j++) + { + if(i == j) + { + Uref = (td21_Uref)[i - 1]; + Vloop = (td21_dV)[i - 1]; + Iloop = cadd((td21_dI)[i - 1], kIres); + Zhsd = cmulreal(Dist_Z1, Mground); // not Dist_Z0 because it's included in Dist_K0 + } + else + { + Uref = csub((td21_Uref)[i - 1], (td21_Uref)[j - 1]); + Vloop = csub((td21_dV)[i - 1], (td21_dV)[j - 1]); + Iloop = csub((td21_dI)[i - 1], (td21_dI)[j - 1]); + Zhsd = cmulreal(Dist_Z1, Mphase); + } + I2 = cabs2(Iloop); + Uref2 = cabs2(Uref); + if(FaultDetected && (I2 > 0.1) && (Uref2 > 0.1)) + { + Zdir = cnegate(cdiv(Vloop, Iloop)); + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Zhsd[%d,%d]=%.4f+j%.4f, Zdir=%.4f+j%.4f", + i, j, Zhsd.re, Zhsd.im, Zdir.re, Zdir.im), ActorID); + if((Zdir.re > 0.0) && (Zdir.im > 0.0)) + { + Uhsd = csub(cmul(Zhsd, Iloop), Vloop); + Uhsd2 = cabs2(Uhsd); + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format(" Uhsd=%.2f, Uref=%.2f", + cabs(Uhsd), cabs(Uref)), ActorID); + if(Uhsd2 / Uref2 > 1.0) // this loop trips + { + if(!PickedUp) + { + Targets.clear(); + //Targets->Sorted = true; + } + if(i == j) + { + Targets.push_back(Format("G%d", i)); + } + else + { + Targets.push_back(Format("P%d%d", i, j)); + } + fault_distance = 1.0L / sqrt(Uhsd2 / Uref2); + if(fault_distance < min_distance) + min_distance = fault_distance; + PickedUp = true; + } + } + } + } + } + if(PickedUp) + { + if(DebugTrace) + { + AppendToEventLog(String("Relay.") + this->get_Name(), "Picked up", ActorID); + } + if(ArmedForReset) + { + ActiveCircuit[ActorID]->ControlQueue.Delete(LastEventHandle, ActorID); + ArmedForReset = false; + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), "Dropping last event.", ActorID); + } + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + RelayTarget = Format("TD21 %.3f pu dist", min_distance); + t_event = ActiveCircuit[ActorID]->Solution->DynaVars.T + Delay_Time + Breaker_time; + for(stop = Pred(Targets.size()), i = 0; i <= stop; i++) + { + RelayTarget = RelayTarget + " " + (Targets)[i]; + } + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, t_event, CTRL_OPEN, 0, this, ActorID); + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Pushing trip event for %.3f", t_event), ActorID); + ArmedForOpen = true; + if(OperationCount <= NumReclose) + { + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, t_event + (RecloseIntervals)[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Pushing reclose event for %.3f", + t_event + (RecloseIntervals)[OperationCount - 1]), ActorID); + ArmedForClose = true; + } + } + Targets.clear(); + } + if(!FaultDetected) // not picked up; reset if necessary + { + if((OperationCount > 1) && (ArmedForReset == false)) // this implements the reset, whether picked up or not + { + ArmedForReset = true; + /*# with ActiveCircuit[ActorID] do */ + { + + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + } + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Pushing reset event for %.3f", + ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime), ActorID); + } + if(ArmedForOpen) + { + td21_quiet = td21_pt + 1; + ArmedForOpen = false; + ArmedForClose = false; + if(DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Dropping out at %.3f", ActiveCircuit[ActorID]->Solution->DynaVars.T), ActorID); + } + } + } /* td21_quiet*/ + } /*With MonitoredElement*/ +} + +// Get power to control based on active power +void TRelayObj::GetControlPower(Ucomplex::complex &ControlPower, int ActorID) +{ + int i, k; + complex Vph[3]; + complex V012[3]; + complex Iph[3]; + complex I012[3]; + + auto MonitoredElement = get_FMonitoredElement(); + if (MonitoredElement->Fnphases >= 3) + { + + MonitoredElement->GetCurrents(cBuffer, ActorID); + MonitoredElement->GetTermVoltages(MonitoredElementTerminal, cvBuffer, ActorID); + + for (i = 0; i < 3; i++) + { + k = (MonitoredElementTerminal - 1) * MonitoredElement->Fnconds + i; + Iph[i] = cBuffer[k]; + Vph[i] = cvBuffer[i]; + } + + Phase2SymComp(Iph, I012); + Phase2SymComp(Vph, V012); + + ControlPower = cmulreal(cmul(V012[1], conjg(I012[1])), 0.003); // Convert to kilo + + } + else + { + // just take the total power (works also for 1ph elements with 2 conductors) + ControlPower = MonitoredElement->Get_Power(MonitoredElementTerminal, ActorID); + } + +} + +void TRelayObj::DirectionalOvercurrentLogic(int ActorID) +{ + int i; + double TripTime, TimeTest; + double Cmag, Cangle; + complex ControlPower; + + // with MonitoredElement + if (FPresentState == CTRL_CLOSE) + { + // Identify net balanced power flow. + if (DOC_P1Blocking) + { + GetControlPower(ControlPower, ActorID); + + if (ControlPower.re >= 0.0) // Forward Power + { + + if (ArmedForOpen) + // If net balanced active power is forward, disarm trip and set for reset + { + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + ArmedForClose = false; + + if (DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("DOC - Reset on Forward Net Balanced Active Power: %.2f kW", ControlPower.re), ActorID); + + } + else + { + + if (DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("DOC - Forward Net Balanced Active Power: %.2f kW. DOC Element blocked.", ControlPower.re), ActorID); + + } + + return; // Do not evaluate trip if power is forward. + + } + } + + + TripTime = -1.0; + + auto MonitoredElement = get_FMonitoredElement(); + MonitoredElement->GetCurrents(cBuffer, ActorID); + MonitoredElement->GetTermVoltages(MonitoredElementTerminal, cvBuffer, ActorID); + + // Shift angle to cBuffer to be relative to cvBuffer + for (i = CondOffset; i < Fnphases + CondOffset; i++) + cBuffer[i] = pdegtocomplex(cabs(cBuffer[i]), cdang(cBuffer[i]) - cdang(cvBuffer[i - CondOffset])); + + for (i = CondOffset; i < Fnphases + CondOffset; i++) + { + + TimeTest = -1.0; + Cmag = cabs(cBuffer[i]); + Cangle = cdang(cBuffer[i]); + + if ((DOC_TiltAngleLow == 90.0) || (DOC_TiltAngleLow == 270.0)) + { + + if (cBuffer[i].re <= -1 * DOC_TripSetLow) + { + + if (DOC_TripSetMag > 0.0) + { // Circle Specified. + + if (Cmag <= DOC_TripSetMag) + { // Within the Circle + + if (DOC_TripSetHigh > 0.0) // High Straight-Line Specified. + { + + if ((DOC_TiltAngleHigh == 90.0) || (DOC_TiltAngleHigh == 270.0)) + { + + if (cBuffer[i].re < -1 * DOC_TripSetHigh) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleHigh)) * (cBuffer[i].re + DOC_TripSetHigh)) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + else + { // High Straight-Line Not Specified. + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { // Out of the Circle + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { // Circle not Specified + + if (DOC_TripSetHigh > 0.0) + { // High Straight-Line Specified. + + if ((DOC_TiltAngleHigh == 90.0) || (DOC_TiltAngleHigh == 270.0)) + { + + if (cBuffer[i].re < -1 * DOC_TripSetHigh) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleHigh)) * (cBuffer[i].re + DOC_TripSetHigh)) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + else + { // High Straight-Line Not Specified. + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + + } + else + { /*90, 270*/ + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleLow)) * (cBuffer[i].re + DOC_TripSetLow)) + { + + if (DOC_TripSetMag > 0.0) + { // Circle Specified. + + if (Cmag <= DOC_TripSetMag) + { // Within the Circle + + if (DOC_TripSetHigh > 0.0) // High Straight-Line Specified. + { + + if ((DOC_TiltAngleHigh == 90.0) || (DOC_TiltAngleHigh == 270.0)) + { + + if (cBuffer[i].re < -1 * DOC_TripSetHigh) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleHigh)) * (cBuffer[i].re + DOC_TripSetHigh)) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + else + { // High Straight-Line Not Specified. + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { // Out of the Circle + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { // Circle not Specified + + if (DOC_TripSetHigh > 0.0) + { // High Straight-Line Specified. + + if ((DOC_TiltAngleHigh == 90.0) || (DOC_TiltAngleHigh == 270.0)) + { + + if (cBuffer[i].re < -1 * DOC_TripSetHigh) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + else + { + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleHigh)) * (cBuffer[i].re + DOC_TripSetHigh)) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + else + { // Right-Side of High Straight-Line + + if (DOC_DelayInner > 0.0) + TimeTest = DOC_DelayInner; + else + if (DOC_PhaseCurveInner != nullptr) + TimeTest = DOC_TDPhaseInner * DOC_PhaseCurveInner->GetTCCTime(Cmag / DOC_PhaseTripInner); + else + if (DOC_DelayInner == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + else + { // High Straight-Line Not Specified. + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + else + { + // There might be an intersection between Straight Line Low and High depending on their angles. + // Straight Line High takes precedence. + if (DOC_TripSetHigh > 0.0) + { + + if ((DOC_TiltAngleHigh == 90.0) || (DOC_TiltAngleHigh == 270.0)) + { + if (cBuffer[i].re < -1 * DOC_TripSetHigh) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + } + else + { + + if (cBuffer[i].im < tan((DEG_TO_RAD * DOC_TiltAngleHigh)) * (cBuffer[i].re + DOC_TripSetHigh)) + { // Left-side of High Straight-Line + + if (Delay_Time > 0.0) + TimeTest = Delay_Time; + else + if (PhaseCurve != nullptr) + TimeTest = TDPhase * PhaseCurve->GetTCCTime(Cmag / PhaseTrip); + else + if (Delay_Time == 0.0) + TimeTest = Delay_Time; + + } + + } + + } + + + } + + + } + + if (TimeTest >= 0.0) + { + + if (DebugTrace) + AppendToEventLog(String("Relay.") + this->get_Name(), Format("Directional Overcurrent - Phase %d Trip: Mag=%.5g, Ang=%.5g, Time=%.5g", i - CondOffset, Cmag, Cangle, TimeTest), ActorID); + + if (TripTime < 0.0) + TripTime = TimeTest; + else + TripTime = min(TripTime, TimeTest); + + } + + } + + + if (TripTime >= 0.0) + { + if (!ArmedForOpen) + // Then arm for an open operation + { + RelayTarget = "DOC"; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time, CTRL_OPEN, 0, this, ActorID); + if (OperationCount <= NumReclose) + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time + RecloseIntervals[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + ArmedForOpen = true; + ArmedForClose = true; + } + } + else + { + if (ArmedForOpen) + // If current dropped below pickup, disarm trip and set for reset + { + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + ArmedForClose = false; + } + } + + + } /*IF PresentState=CLOSE*/ +} + +void TRelayObj::RevPowerLogic(int ActorID) +{ + complex s = {}; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + //----MonitoredElement.ActiveTerminalIdx := MonitoredElementTerminal; + s = get_FMonitoredElement()->Get_Power(MonitoredElementTerminal, ActorID); + if(s.re < 0.0) + { + if(Abs( s.re) > PhaseInst * 1000.0) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // push the trip operation and arm to trip + RelayTarget = "Rev P"; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + Delay_Time + Breaker_time, CTRL_OPEN, 0, this, ActorID); + OperationCount = NumReclose + 1; // force a lockout + ArmedForOpen = true; + } + } + else + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // We became unarmed, so reset and disarm + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + } + } + } + } /*With MonitoredElement*/ +} + +void TRelayObj::VoltageLogic(int ActorID) +{ + int i = 0; + double Vmax = 0.0; + double Vmin = 0.0; + double Vmag = 0.0; + double OVTime = 0.0; + double UVTime = 0.0; + double TripTime = 0.0; + if(!LockedOut) + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + /***** Fix so that fastest trip time applies *****/ + int stop = 0; + get_FMonitoredElement()->GetTermVoltages(MonitoredElementTerminal, cBuffer, ActorID); + Vmin = 1.0e50; + Vmax = 0.0; + for(stop = get_FMonitoredElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + Vmag = cabs((cBuffer)[i - 1]); + if(Vmag > Vmax) + Vmax = Vmag; + if(Vmag < Vmin) + Vmin = Vmag; + } + + /*Convert to Per Unit*/ + Vmax = Vmax / VBase; + Vmin = Vmin / VBase; + if(FPresentState == CTRL_CLOSE) + { + TripTime = -1.0; + OVTime = -1.0; + UVTime = -1.0; + + + + /*Check OverVoltage Trip, if any*/ + if(OVcurve != nullptr) + OVTime = OVcurve->GetOVTime(Vmax); + if(OVTime > 0.0) + { + TripTime = OVTime; + } + + // If OVTime > 0 then we have a OV trip + + /*Check UV Trip, if any*/ + if(UVCurve != nullptr) + { + UVTime = UVCurve->GetUVTime(Vmin); + } + + // If UVTime > 0 then we have a UV trip + if(UVTime > 0.0) + { + if(TripTime > 0.0) + { // Min of UV or OV time + TripTime = min(TripTime, UVTime); + } + else + { + TripTime = UVTime; + } + } + if(TripTime > 0.0) + /*# with ActiveCircuit[ActorID] do */ + { + + if(ArmedForOpen && ((ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time) < NextTriptime)) + { + ActiveCircuit[ActorID]->ControlQueue.Delete(LastEventHandle, ActorID); // Delete last event from Queue + ArmedForOpen = false; // force it to go through next IF + } + if(!ArmedForOpen) // Then arm for an open operation + { + if(TripTime == UVTime) + { + if(TripTime == OVTime) + RelayTarget = "UV + OV"; + else + RelayTarget = "UV"; + } + else + RelayTarget = "OV"; + NextTriptime = ActiveCircuit[ActorID]->Solution->DynaVars.T + TripTime + Breaker_time; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, NextTriptime, CTRL_OPEN, 0, this, ActorID); + ArmedForOpen = true; + } + } + else + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // If voltage dropped below pickup, disarm trip and set for reset + ActiveCircuit[ActorID]->ControlQueue.Delete(LastEventHandle, ActorID); // Delete last event from Queue + NextTriptime = -1.0; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + } + } /*IF PresentState=CLOSE*/ + } + else + /*Present state is Open, Check for Voltage and then set reclose Interval*/ + { + if(OperationCount <= NumReclose) + { + if(!ArmedForClose) + { + if(Vmax > 0.9) + /*# with ActiveCircuit[ActorID] do */ + { + // OK if voltage > 90% + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + (RecloseIntervals)[OperationCount - 1], CTRL_CLOSE, 0, this, ActorID); + ArmedForClose = true; + } + } + else + { + if(Vmax < 0.9) /*Armed, but check to see if voltage dropped before it reclosed and cancel action*/ + ArmedForClose = false; + } + } + } + } /*With MonitoredElement*/ +} + +/*Neg Seq voltage Relay*/ + +void TRelayObj::NegSeq47Logic(int ActorID) +{ + double NegSeqVoltageMag = 0.0; + complex V012[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + /*# with MonitoredElement do */ + { + auto with0 = get_FMonitoredElement(); + get_FMonitoredElement()->GetTermVoltages(MonitoredElementTerminal, cBuffer, ActorID); + Phase2SymComp(cBuffer, &V012[0]); // Phase to symmetrical components + NegSeqVoltageMag = cabs(V012[3 - 1]); + if(NegSeqVoltageMag >= PickupVolts47) + { + if(!ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // push the trip operation and arm to trip + RelayTarget = "-Seq V"; + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + Delay_Time + Breaker_time, CTRL_OPEN, 0, this, ActorID); + OperationCount = NumReclose + 1; // force a lockout + ArmedForOpen = true; + } + } + else + /*Less Than pickup value: reset if armed*/ + { + if(ArmedForOpen) + /*# with ActiveCircuit[ActorID] do */ + { + // We became unarmed, so reset and disarm + LastEventHandle = ActiveCircuit[ActorID]->ControlQueue.Push(ActiveCircuit[ActorID]->Solution->DynaVars.intHour, ActiveCircuit[ActorID]->Solution->DynaVars.T + ResetTime, CTRL_RESET, 0, this, ActorID); + ArmedForOpen = false; + } + } + } /*With MonitoredElement*/ +} + + + + +} // namespace Relay + + + + + diff --git a/OpenDSSC/Controls/Relay.h b/OpenDSSC/Controls/Relay.h new file mode 100644 index 0000000..a2a2f1e --- /dev/null +++ b/OpenDSSC/Controls/Relay.h @@ -0,0 +1,244 @@ +#ifndef RelayH +#define RelayH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "TCC_Curve.h" +#include +#include "d2c_structures.h" +#include "ControlActionsDefs.h" + +namespace Relay +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Created 8-24-00 from CktElement Control + 9-20-00 Implemented Voltage relay and updated arming logic for all relays + 10-31-00 Added Event Logging + 11-1-00 Added shots= + 3-7-03 Added new property definition process + Added Neg seq relays and Generic relay + Added capability to monitor PC Element variable + 2-16-04 Fixed address bug in symmetrical component transformation in 46 relay + 5-1-06 Added Time Dial to Phase and ground + 2-9-21 Added distance (21) and incremental distance (TD21) functions +*/ +/* + A Relay is a control element that is connected to a terminal of a + circuit element and controls the switches in the same or another terminal. + + The control is usually placed in the + terminal of a line or transformer, but it could be any element + + A Relay is defined by a New command: + + New Relay.Name=myname Element=devclass.name terminal=[ 1|2|...] Switch = devclass.name terminal=[ 1|2|...] + Type = [current | voltage] + Phase = TCCCurve + Ground = TCCCurve + OverVolt = TCCcurve + UnderVolt = TCCCurve + PhaseTrip = Multipliers times curve + GroundTrip = + PhaseInst = + GroundInst = + RecloseIntervals= (array of times, sec); + ResetTime = + + CktElement to be controlled must already exist. + + Voltage relay is a definite time relay that operates after the voltage stays out of bounds + for a fixed time interval. It will then reclose a set time after the voltage comes back in the normal range. + +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRelay : public ControlClass::TControlClass +{ + friend class TRelayObj; +public: + typedef ControlClass::TControlClass inherited; +private: + DSSClass::TDSSClass* TCC_CurveClass; +protected: + void DefineProperties(); + virtual int MakeLike(const String RelayName); +public: + TRelay(); + virtual ~TRelay(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); + TCC_Curve::TTCC_CurveObj* GetTccCurve(const String CurveName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TRelayObj : public ControlElem::TControlElem +{ + friend class TRelay; +public: + typedef ControlElem::TControlElem inherited; +//private: + int ControlType; + + + /*OverCurrent Relay*/ + TCC_Curve::TTCC_CurveObj* PhaseCurve; + TCC_Curve::TTCC_CurveObj* GroundCurve; + double PhaseTrip; + double GroundTrip; + double PhaseInst; + double GroundInst; + Arraydef::pDoubleArray RecloseIntervals; + int NumReclose; + double ResetTime; + double Delay_Time; + double Breaker_time; + double TDPhase; + double TDGround; + String RelayTarget; + + + /*over/Under Voltage Relay*/ // Curves assumed in per unit of base voltage + TCC_Curve::TTCC_CurveObj* OVcurve; + TCC_Curve::TTCC_CurveObj* UVCurve; // line-neut volts base + double VBase; + double kVBase; + + /*46 Relay Neg Seq Current*/ + double PickupAmps46; + double PctPickup46; + double BaseAmps46; + double Isqt46; + + /*47 Relay*/ + double PickupVolts47; + double PctPickup47; + + /*Distance Relay*/ + double Z1Mag; + double Z1Ang; + double Z0Mag; + double Z0Ang; + double Mphase; + double Mground; + Ucomplex::complex Dist_Z1; + Ucomplex::complex Dist_Z0; + Ucomplex::complex Dist_K0; + bool Dist_Reverse; + /*TD21 Relay*/ // present ring buffer index into td21_h + // index to one cycle back, and next write location + int td21_i; + int td21_next; + int td21_pt; // number of time samples in td21_h + int td21_stride; // length of a time sample in td21_h + int td21_quiet; // wait this many samples after an operation + Ucomplex::pComplexArray td21_h; // VI history pts, vi, phases + Ucomplex::pComplexArray td21_Uref; // reference (pre-fault) voltages + Ucomplex::pComplexArray td21_dV; // incremental voltages + Ucomplex::pComplexArray td21_dI; // incremental currents + + /*Directional Overcurrent Relay*/ + double DOC_TiltAngleLow; // Tilt angle for low-current trip line + double DOC_TiltAngleHigh; // Tilt angle for high-current trip line + double DOC_TripSetLow; // Trip setting for low-current trip line + double DOC_TripSetHigh; // Trip setting for high-current trip line + double DOC_TripSetMag; // Current magnitude trip setting (define a circle for the relay characteristics) + double DOC_DelayInner; // Delay for trip in inner region of the DOC characteristic + double DOC_PhaseTripInner; // Multiplier for TCC Curve for tripping in inner region of the DOC characteristic + double DOC_TDPhaseInner; // Time Dial for DOC_PhaseTripInner + bool DOC_P1Blocking; // Block trip if there is no net balanced reverse active power + + TTCC_CurveObj* DOC_PhaseCurveInner; // TCC Curve for tripping in inner zone of the DOC characteristic + + /*Generic Relay*/ + double OverTrip; + double UnderTrip; + EControlAction FPresentState; + EControlAction FNormalState; + int OperationCount; + bool LockedOut; + bool ArmedForClose; + bool ArmedForOpen; + bool ArmedForReset; + bool PhaseTarget; + bool GroundTarget; + bool NormalStateSet; + double NextTriptime; + int LastEventHandle; + int CondOffset; // Offset for monitored terminal + Ucomplex::pComplexArray cBuffer; // Complexarray buffer for an operating quantity + Ucomplex::pComplexArray cvBuffer; // for distance and td21 voltages, using cBuffer for hte currents + bool DebugTrace; + void InterpretRelayState(int ActorID, const String Action, const String property_name); + EControlAction get_State(); + void set_State(const EControlAction Value); + EControlAction get_NormalState(); + void set_NormalState(const EControlAction Value); + void InterpretRelayType(const String s); + void OvercurrentLogic(int ActorID); + void VoltageLogic(int ActorID); + void RevPowerLogic(int ActorID); + void NegSeq46Logic(int ActorID); + void NegSeq47Logic(int ActorID); + void GenericLogic(int ActorID); + void DistanceLogic(int ActorID); + void TD21Logic(int ActorID); + void DirectionalOvercurrentLogic(int ActorID); + void GetControlPower(Ucomplex::complex &ControlPower, int ActorID); + +public: + String MonitoredElementName; + int MonitoredElementTerminal; + TRelayObj(DSSClass::TDSSClass* ParClass, const String RelayName); + virtual ~TRelayObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a Relay + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TRelayObj(DSSClass::TDSSClass* ParClass); + TRelayObj(String ClassName); + TRelayObj(); +}; +extern TRelayObj* ActiveRelayObj; +extern TRelay* RelayClass; + +/*--------------------------------------------------------------------------*/ + + +} // namespace Relay + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Relay; +#endif + +#endif // RelayH + + + + + diff --git a/OpenDSSC/Controls/StorageController.cpp b/OpenDSSC/Controls/StorageController.cpp new file mode 100644 index 0000000..50c7092 --- /dev/null +++ b/OpenDSSC/Controls/StorageController.cpp @@ -0,0 +1,2893 @@ + + +#pragma hdrstop + +#include "StorageController.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Storage.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Dynamics.h" +#include "XYcurve.h" +#include "Utilities.h" +#include "Solution.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace ParserDel; +using namespace Storage; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace StorageController +{ + +TStorageControllerObj::TStorageControllerObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TStorageControllerObj::TStorageControllerObj(String ClassName) : inherited(ClassName) {} +TStorageControllerObj::TStorageControllerObj() {} + + +TStorageControllerObj* ActiveStorageController2Obj = nullptr; +const int propELEMENT = 1; +const int propTERMINAL = 2; +const int propMONPHASE = 3; +const int propKWTARGET = 4; +const int propKWTARGETLOW = 5; +const int propPCTKWBAND = 6; +const int propKWBAND = 7; +const int propPCTKWBANDLOW = 8; +const int propKWBANDLOW = 9; +// propPFTARGET = 7; +// propPFBAND = 8; +const int propELEMENTLIST = 10; +const int propWEIGHTS = 11; +const int propMODEDISCHARGE = 12; +const int propMODECHARGE = 13; +const int propTIMEDISCHARGETRIGGER = 14; +const int propTIMECHARGETRIGGER = 15; +const int propRATEKW = 16; +// propRATEKVAR = 16; +const int propRATECHARGE = 17; +const int propRESERVE = 18; +const int propKWHTOTAL = 19; +const int propKWTOTAL = 20; +const int propKWHACTUAL = 21; +const int propKWACTUAL = 22; +const int propKWNEED = 23; +// propPARTICIPATION = 24; +const int propYEARLY = 24; +const int propDAILY = 25; +const int propDUTY = 26; +const int propEVENTLOG = 27; +// propVARDISPATCH = 29; +const int propINHIBITTIME = 28; +const int propTUPRAMP = 29; +const int propTFLAT = 30; +const int propTDNRAMP = 31; +const int propKWTHRESHOLD = 32; +const int propDispFactor = 33; +const int propRESETLEVEL = 34; +const int propSEASONS = 35; +const int propSEASONTARGETS = 36; +const int propSEASONTARGETSLOW = 37; +const int NumPropsThisClass = 37; + +//= = = = = = = = = = = = = = DEFINE CONTROL MODE CONSTANTS = = = = = = = = = = = = = = = = = = = = = = = = = +const int MODEFOLLOW = 1; +const int MODELOADSHAPE = 2; +const int MODESUPPORT = 3; +const int MODETIME = 4; +const int MODEPEAKSHAVE = 5; +const int MODESCHEDULE = 6; +const int MODEPEAKSHAVELOW = 7; +const int CURRENTPEAKSHAVE = 8; +const int CURRENTPEAKSHAVELOW = 9; + +//= = = = = = = = = = = = = = DEFINE OTHER CONSTANTS = = = = = = = = = = = = = = = = = = = = = = = = = +const int RELEASE_INHIBIT = 999; +complex CDoubleOne = {}; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all StorageController objects + +TStorageController::TStorageController() +{ + ; + Class_Name = "StorageController"; + DSSClassType = DSSClassType + STORAGE_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TStorageController::~TStorageController() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorageController::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[propELEMENT - 1] = "Element"; + PropertyName[propTERMINAL - 1] = "Terminal"; + PropertyName[propMONPHASE - 1] = "MonPhase"; + PropertyName[propKWTARGET - 1] = "kWTarget"; + PropertyName[propKWTARGETLOW - 1] = "kWTargetLow"; + PropertyName[propPCTKWBAND - 1] = "%kWBand"; + PropertyName[propKWBAND - 1] = "kWBand"; + PropertyName[propPCTKWBANDLOW - 1] = "%kWBandLow"; + PropertyName[propKWBANDLOW - 1] = "kWBandLow"; +// PropertyName[propPFTARGET] := 'PFTarget'; +// PropertyName[propPFBAND] := 'PFBand'; + PropertyName[propELEMENTLIST - 1] = "ElementList"; + PropertyName[propWEIGHTS - 1] = "Weights"; + PropertyName[propMODEDISCHARGE - 1] = "ModeDischarge"; + PropertyName[propMODECHARGE - 1] = "ModeCharge"; + PropertyName[propTIMEDISCHARGETRIGGER - 1] = "TimeDischargeTrigger"; + PropertyName[propTIMECHARGETRIGGER - 1] = "TimeChargeTrigger"; + PropertyName[propRATEKW - 1] = "%RatekW"; +// PropertyName[propRATEKVAR] := '%Ratekvar'; + PropertyName[propRATECHARGE - 1] = "%RateCharge"; + PropertyName[propRESERVE - 1] = "%Reserve"; + PropertyName[propKWHTOTAL - 1] = "kWhTotal"; + PropertyName[propKWTOTAL - 1] = "kWTotal"; + PropertyName[propKWHACTUAL - 1] = "kWhActual"; + PropertyName[propKWACTUAL - 1] = "kWActual"; + PropertyName[propKWNEED - 1] = "kWneed"; +// PropertyName[propPARTICIPATION] := '%Participation'; + PropertyName[propYEARLY - 1] = "Yearly"; + PropertyName[propDAILY - 1] = "Daily"; + PropertyName[propDUTY - 1] = "Duty"; + PropertyName[propEVENTLOG - 1] = "EventLog"; +// PropertyName[propVARDISPATCH] := 'VarDispatch'; + PropertyName[propINHIBITTIME - 1] = "InhibitTime"; + PropertyName[propTUPRAMP - 1] = "Tup"; + PropertyName[propTFLAT - 1] = "TFlat"; + PropertyName[propTDNRAMP - 1] = "Tdn"; + PropertyName[propKWTHRESHOLD - 1] = "kWThreshold"; + PropertyName[propDispFactor - 1] = "DispFactor"; + PropertyName[propRESETLEVEL - 1] = "ResetLevel"; + PropertyName[propSEASONS - 1] = "Seasons"; + PropertyName[propSEASONTARGETS - 1] = "SeasonTargets"; + PropertyName[propSEASONTARGETSLOW - 1] = "SeasonTargetsLow"; + PropertyHelp[propELEMENT - 1] = "Full object name of the circuit element, typically a line or transformer, " + "which the control is monitoring. There is no default; Must be specified."; + PropertyHelp[propTERMINAL - 1] = "Number of the terminal of the circuit element to which the StorageController2 control is connected. " + "1 or 2, typically. Default is 1. Make sure to select the proper direction on the power for the respective dispatch mode."; + PropertyHelp[propMONPHASE - 1] = "Number of the phase being monitored or one of {AVG | MAX | MIN} for all phases. Default=MAX. " + "Must be less than the number of phases. Used in PeakShave, Follow, Support and I-PeakShave discharging modes " + "and in PeakShaveLow, I-PeakShaveLow charging modes. For modes based on active power measurements, the value " + "used by the control is the monitored one multiplied by the number of phases of the monitored element."; + PropertyHelp[propKWTARGET - 1] = "kW/kamps target for Discharging. The Storage element fleet is dispatched to try to hold the power/current in band " + "at least until the Storage is depleted. The selection of power or current depends on the Discharge mode (PeakShave->kW, I-PeakShave->kamps)."; + PropertyHelp[propKWTARGETLOW - 1] = "kW/kamps target for Charging. The Storage element fleet is dispatched to try to hold the power/current in band " + "at least until the Storage is fully charged. The selection of power or current depends on the charge mode (PeakShavelow->kW, I-PeakShavelow->kamps)."; + PropertyHelp[propPCTKWBAND - 1] = "Bandwidth (% of Target kW/kamps) of the dead band around the kW/kamps target value. Default is 2% (+/-1%)." + "No dispatch changes are attempted if the power in the monitored terminal stays within this band."; + PropertyHelp[propKWBAND - 1] = "Alternative way of specifying the bandwidth. (kW/kamps) of the dead band around the kW/kamps target value. Default is 2% of kWTarget (+/-1%)." + "No dispatch changes are attempted if the power in the monitored terminal stays within this band."; + PropertyHelp[propPCTKWBANDLOW - 1] = "Bandwidth (% of kWTargetLow) of the dead band around the kW/kamps low target value. Default is 2% (+/-1%)." + "No charging is attempted if the power in the monitored terminal stays within this band."; + PropertyHelp[propKWBANDLOW - 1] = "Alternative way of specifying the bandwidth. (kW/kamps) of the dead band around the kW/kamps low target value. Default is 2% of kWTargetLow (+/-1%)." + "No charging is attempted if the power in the monitored terminal stays within this band."; +// PropertyHelp[propPFTARGET] := +// 'Power Factor target for dispatching the reactive power. Default is 0.96. The reactive power of the storage element fleet is dispatched to try to hold the power factor in band. '+ +// 'It is assumed that the storage element inverter can produce kvar up to its kVA limit regardless of storage level.'; +// PropertyHelp[propPFBAND] := +// 'Bandwidth of the Target power factor of the monitored element. of the dead band around the kvar target value. Default is 0.04 (+/- 0.02).' + +// 'No dispatch changes of the kvar are attempted If the power factor of the monitored terminal stays within this band.'; + PropertyHelp[propELEMENTLIST - 1] = "Array list of Storage elements to be controlled. If not specified, all Storage elements in the circuit not presently dispatched by another controller " + "are assumed dispatched by this controller."; + PropertyHelp[propWEIGHTS - 1] = "Array of proportional weights corresponding to each Storage element in the ElementList. " + "The needed kW or kvar to get back to center band is dispatched to each Storage element according to these weights. " + "Default is to set all weights to 1.0."; + PropertyHelp[propMODEDISCHARGE - 1] = String("{PeakShave* | Follow | Support | Loadshape | Time | Schedule | I-PeakShave} Mode of operation for the DISCHARGE FUNCTION of this controller. ") + CRLF + + CRLF + + "In PeakShave mode (Default), the control attempts to discharge Storage to keep power in the monitored element below the kWTarget. " + + CRLF + + CRLF + + "In Follow mode, the control is triggered by time and resets the kWTarget value to the present monitored element power. " + + "It then attempts to discharge Storage to keep power in the monitored element below the new kWTarget. See TimeDischargeTrigger." + + CRLF + + CRLF + + "In Support mode, the control operates oppositely of PeakShave mode: Storage is discharged to keep kW power output up near the target. " + + CRLF + + CRLF + + "In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. " + + "Storage is discharged when the loadshape value is positive. " + + CRLF + + CRLF + + "In Time mode, the Storage discharge is turned on at the specified %RatekW at the specified discharge trigger time in fractional hours." + + CRLF + + CRLF + + "In Schedule mode, the Tup, TFlat, and Tdn properties specify the up ramp duration, flat duration, and down ramp duration for the schedule. " + + "The schedule start time is set by TimeDischargeTrigger and the rate of discharge for the flat part is determined by %RatekW." + + CRLF + + CRLF + + "In I-PeakShave mode, the control attempts to discharge Storage to keep current in the monitored element below the target given in k-amps " + + "(thousands of amps), when this control mode is active, the property kWTarget will be expressed in k-amps. "; + PropertyHelp[propMODECHARGE - 1] = String("{Loadshape | Time* | PeakShaveLow | I-PeakShaveLow} Mode of operation for the CHARGE FUNCTION of this controller. ") + CRLF + + CRLF + + "In Loadshape mode, both charging and discharging precisely follows the per unit loadshape. " + + "Storage is charged when the loadshape value is negative. " + + CRLF + + CRLF + + "In Time mode, the Storage charging FUNCTION is triggered at the specified %RateCharge at the specified charge trigger time in fractional hours." + + CRLF + + CRLF + + "In PeakShaveLow mode, the charging operation will charge the Storage fleet when the power at a" + + "monitored element is below a specified KW target (kWTarget_low). The Storage will charge as much power as necessary to keep the power within the deadband around kWTarget_low." + + CRLF + + CRLF + + "In I-PeakShaveLow mode, the charging operation will charge the Storage fleet when the current (Amps) at a" + + "monitored element is below a specified amps target (kWTarget_low). The Storage will charge as much power as necessary to keep the amps within the deadband around kWTarget_low. " + + "When this control mode is active, the property kWTarget_low will be expressed in k-amps and all the other parameters will be adjusted to match the amps (current) control criteria."; + PropertyHelp[propTIMEDISCHARGETRIGGER - 1] = "Default time of day (hr) for initiating Discharging of the fleet. During Follow or Time mode discharging is triggered at a fixed time " + "each day at this hour. If Follow mode, Storage will be discharged to attempt to hold the load at or below the power level at the time of triggering. " + "In Time mode, the discharge is based on the %RatekW property value. " + "Set this to a negative value to ignore. Default is 12.0 for Follow mode; otherwise it is -1 (ignored). "; + PropertyHelp[propTIMECHARGETRIGGER - 1] = "Default time of day (hr) for initiating charging in Time control mode. Set this to a negative value to ignore. Default is 2.0. (0200)." + "When this value is >0 the Storage fleet is set to charging at this time regardless of other control criteria to make sure Storage is " + "topped off for the next discharge cycle."; + PropertyHelp[propRATEKW - 1] = "Sets the kW discharge rate in % of rated capacity for each element of the fleet. Applies to TIME control mode, SCHEDULE mode, or anytime discharging is triggered " + "by time."; +// PropertyHelp[propRATEKVAR] := +// 'Sets the kvar discharge rate in % of rated capacity for each element of the fleet. Applies to TIME control mode or anytime discharging is triggered ' + +// 'by time.' ; + PropertyHelp[propRATECHARGE - 1] = "Sets the kW charging rate in % of rated capacity for each element of the fleet. Applies to TIME control mode and anytime charging mode is " + "entered due to a time trigger."; + PropertyHelp[propRESERVE - 1] = "Use this property to change the % reserve for each Storage element under control of this controller. This might be used, for example, to " + "allow deeper discharges of Storage or in case of emergency operation to use the remainder of the Storage element."; + PropertyHelp[propKWHTOTAL - 1] = "(Read only). Total rated kWh energy Storage capacity of Storage elements controlled by this controller."; + PropertyHelp[propKWTOTAL - 1] = "(Read only). Total rated kW power capacity of Storage elements controlled by this controller."; + PropertyHelp[propKWHACTUAL - 1] = "(Read only). Actual kWh stored of all controlled Storage elements. "; + PropertyHelp[propKWACTUAL - 1] = "(Read only). Actual kW output of all controlled Storage elements. "; + PropertyHelp[propKWNEED - 1] = "(Read only). KW needed to meet target."; +// PropertyHelp[propPARTICIPATION] := +// 'Participation factor, %. Default = 100.'; + PropertyHelp[propYEARLY - 1] = "Dispatch loadshape object, If any, for Yearly solution Mode."; + PropertyHelp[propDAILY - 1] = "Dispatch loadshape object, If any, for Daily solution mode."; + PropertyHelp[propDUTY - 1] = "Dispatch loadshape object, If any, for Dutycycle solution mode."; + PropertyHelp[propEVENTLOG - 1] = "{Yes/True | No/False} Default is No. Log control actions to Eventlog."; +// PropertyHelp[propVARDISPATCH] := +// '{Yes/True | No/False} Default is No. Flag to indicate whether or not to disatch vars as well as watts.'; + PropertyHelp[propINHIBITTIME - 1] = "Hours (integer) to inhibit Discharging after going into Charge mode. Default is 5."; + PropertyHelp[propTUPRAMP - 1] = "Duration, hrs, of upramp part for SCHEDULE mode. Default is 0.25."; + PropertyHelp[propTFLAT - 1] = "Duration, hrs, of flat part for SCHEDULE mode. Default is 2.0."; + PropertyHelp[propTDNRAMP - 1] = "Duration, hrs, of downramp part for SCHEDULE mode. Default is 0.25."; + PropertyHelp[propKWTHRESHOLD - 1] = "Threshold, kW, for Follow mode. kW has to be above this value for the Storage element " + "to be dispatched on. Defaults to 75% of the kWTarget value. Must reset this property after " + "setting kWTarget if you want a different value."; + PropertyHelp[propDispFactor - 1] = String("Defaults to 1 (disabled). Set to any value between 0 and 1 to enable this parameter.") + CRLF + + CRLF + + "Use this parameter to reduce the amount of power requested by the controller in each control iteration. " + + "It can be useful when maximum control iterations are exceeded due to numerical instability such as " + + "fleet being set to charging and idling in subsequent control iterations (check the Eventlog). "; + PropertyHelp[propRESETLEVEL - 1] = "The level of charge required for allowing the storage to discharge again after reaching " + "the reserve storage level. After reaching this level, the storage control will not allow " + "the storage device to discharge, forcing the storage to charge. Once the storage reaches this" + "level, the storage will be able to discharge again. This value is a number between 0.2 and 1"; + PropertyHelp[propSEASONS - 1] = "With this property the user can" + " specify the number of targets to be used by the controller using the list given at \"SeasonTargets\"/" + "\"SeasonTargetsLow\", which can be used to dynamically adjust the storage controller during a QSTS" + " simulation. The default value is 1. This property needs to be defined before defining SeasonTargets/SeasonTargetsLow."; + PropertyHelp[propSEASONTARGETS - 1] = "An array of doubles specifying the targets to be used during a QSTS simulation. These targets will take effect" + " only if SeasonRating=true. The number of targets cannot exceed the number of seasons defined at the SeasonSignal." + "The difference between the targets defined at SeasonTargets and SeasonTargetsLow is that SeasonTargets" + " applies to discharging modes, while SeasonTargetsLow applies to charging modes."; + PropertyHelp[propSEASONTARGETSLOW - 1] = "An array of doubles specifying the targets to be used during a QSTS simulation. These targets will take effect" + " only if SeasonRating=true. The number of targets cannot exceed the number of seasons defined at the SeasonSignal." + "The difference between the targets defined at SeasonTargets and SeasonTargetsLow is that SeasonTargets" + " applies to discharging modes, while SeasonTargetsLow applies to charging modes."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TStorageController::NewObject(const String ObjName) +{ + int result = 0; + // Make a new StorageController and add it to StorageController class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TStorageControllerObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TStorageController::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + double casemult = 0.0; + + // continue parsing with contents of Parser + ActiveStorageController2Obj = (TStorageControllerObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveStorageController2Obj); + result = 0; + /*# with ActiveStorageController2Obj do */ + { + auto with0 = ActiveStorageController2Obj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 14407); + break; + case propELEMENT: + with0->ElementName = LowerCase(Param); + break; + case propTERMINAL: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case propMONPHASE: + if(CompareTextShortest(Param, "avg") == 0) + with0->FMonPhase = AVG; + else + { + if(CompareTextShortest(Param, "max") == 0) + with0->FMonPhase = MAXPHASE; + else + { + if(CompareTextShortest(Param, "min") == 0) + with0->FMonPhase = MINPHASE; + else + with0->FMonPhase = max(1, Parser[ActorID]->MakeInteger_()); + } + } + break; + case propKWTARGET: + with0->FkWTarget = Parser[ActorID]->MakeDouble_(); + break; + case propKWTARGETLOW: + with0->FkWTargetLow = Parser[ActorID]->MakeDouble_(); + break; + case propPCTKWBAND: + with0->FpctkWBand = Parser[ActorID]->MakeDouble_(); + break; + case propKWBAND: + with0->FkWBand = Parser[ActorID]->MakeDouble_(); + break; + case propPCTKWBANDLOW: + with0->FpctkWBandLow = Parser[ActorID]->MakeDouble_(); + break; + case propKWBANDLOW: + with0->FkWBandLow = Parser[ActorID]->MakeDouble_(); + break; +// propPFTARGET: FPFTarget := ConvertPFToPFRange2(Parser[ActorID].MakeDouble_()); +// propPFBAND: FPFBand := Parser[ActorID].MakeDouble_(); + case propELEMENTLIST: + InterpretTStringListArray(Param, with0->FStorageNameList); + break; + case propWEIGHTS: + { + with0->FleetSize = with0->FStorageNameList.size(); + if(with0->FleetSize > 0) + { + with0->FWeights = (pDoubleArray) realloc(with0->FWeights, sizeof(double) * with0->FleetSize); + with0->FleetSize = InterpretDblArray(Param, with0->FleetSize, with0->FWeights); + } + } + break; + case propMODEDISCHARGE: + with0->DischargeMode = with0->InterpretMode(propMODEDISCHARGE, Param); + break; + case propMODECHARGE: + with0->ChargeMode = with0->InterpretMode(propMODECHARGE, Param); + break; + case propTIMEDISCHARGETRIGGER: + with0->DischargeTriggerTime = Parser[ActorID]->MakeDouble_(); + break; + case propTIMECHARGETRIGGER: + with0->ChargeTriggerTime = Parser[ActorID]->MakeDouble_(); + break; + case propRATEKW: + with0->pctKWRate = Parser[ActorID]->MakeDouble_(); + break; +// propRATEKVAR: pctkvarRate := Parser[ActorID].MakeDouble_(); + case propRATECHARGE: + with0->pctChargeRate = Parser[ActorID]->MakeDouble_(); + break; + case propRESERVE: + with0->pctFleetReserve = Parser[ActorID]->MakeDouble_(); + break; + case propKWHTOTAL: + ; + break; // Do nothing (Read ONly) + case propKWTOTAL: + ; + break; // Do nothing (Read ONly) + case propKWHACTUAL: + ; + break; // Do nothing (Read ONly) + case propKWACTUAL: + ; + break; // Do nothing (Read ONly) + case propKWNEED: + ; + break; // Do nothing (Read ONly) +// propPARTICIPATION: ; + case propYEARLY: + with0->YearlyShape = Param; + break; + case propDAILY: + with0->DailyShape = Param; + break; + case propDUTY: + with0->DutyShape = Param; + break; + case propEVENTLOG: + with0->ShowEventLog = InterpretYesNo(Param); + break; +// propVARDISPATCH: DispatchVars := InterpretYesNo(Param); + case propINHIBITTIME: + with0->InhibitHrs = max(1, Parser[ActorID]->MakeInteger_()); + break; // >=1 + case propTUPRAMP: + with0->UpRamptime = Parser[ActorID]->MakeDouble_(); + break; + case propTFLAT: + with0->FlatTime = Parser[ActorID]->MakeDouble_(); + break; + case propTDNRAMP: + with0->DnrampTime = Parser[ActorID]->MakeDouble_(); + break; + case propKWTHRESHOLD: + with0->FkWThreshold = Parser[ActorID]->MakeDouble_(); + break; + case propDispFactor: + if((Parser[ActorID]->MakeDouble_() > 1.0) || (Parser[ActorID]->MakeDouble_() <= 0.0)) + with0->DispFactor = 1.0; + else + with0->DispFactor = Parser[ActorID]->MakeDouble_(); + break; + case propRESETLEVEL: + with0->ResetLevel = Parser[ActorID]->MakeDouble_(); + break; + case propSEASONS: + with0->Seasons = Parser[ActorID]->MakeInteger_(); + break; + case propSEASONTARGETS: + { + if(with0->Seasons > 1) + { + with0->SeasonTargets.resize( with0->Seasons ); + with0->Seasons = InterpretDblArray(Param, with0->Seasons, ((pDoubleArray) &(with0->SeasonTargets[0]))); + } + } + break; + case propSEASONTARGETSLOW: + { + if(with0->Seasons > 1) + { + with0->SeasonTargetsLow.resize(with0->Seasons); + with0->Seasons = InterpretDblArray(Param, with0->Seasons, ((pDoubleArray) &( with0->SeasonTargetsLow[0]))); + } + } + break; + // Inherited parameters + default: + ClassEdit(ActiveStorageController2Obj, ParamPointer - NumPropsThisClass); + break; + } + + // Side effects of setting properties above + switch(ParamPointer) + { + case propKWTARGET: + { + if(with0->DischargeMode == CURRENTPEAKSHAVE) // evaluates the discharging mode to apply + // a compensation value (for kamps) + casemult = 1000.0; + else + casemult = 1.0; + with0->FkWThreshold = with0->FkWTarget * 0.75 * casemult; + with0->HalfkWBand = with0->FpctkWBand / 200.0 * with0->FkWTarget * casemult; + with0->FkWBand = 2.0 * with0->HalfkWBand; + with0->FpctkWBand = with0->FkWBand / with0->FkWTarget * 100.0; // sync FpctkWBand + } + break; + case propPCTKWBAND: + { + if(with0->DischargeMode == CURRENTPEAKSHAVE) // evaluates the discharging mode to apply + // a compensation value (for kamps) + casemult = 1000.0; + else + casemult = 1.0; + with0->HalfkWBand = with0->FpctkWBand / 200.0 * with0->FkWTarget * casemult; + with0->FkWBand = 2.0 * with0->HalfkWBand; + with0->FkWBandSpecified = false; + } + break; + case propKWBAND: + { + if(with0->DischargeMode == CURRENTPEAKSHAVE) // evaluates the discharging mode to apply + // a compensation value (for kamps) + casemult = 1000.0; + else + casemult = 1.0; + with0->HalfkWBand = with0->FkWBand / 2.0 * casemult; + with0->FpctkWBand = with0->FkWBand / with0->FkWTarget * 100.0; // sync FpctkWBand + with0->FkWBandSpecified = true; + } + break; + case propKWTARGETLOW: case propPCTKWBANDLOW: + { + if(with0->ChargeMode == CURRENTPEAKSHAVELOW) // evaluates the charging mode to apply + // a compensation value (for kamps) + casemult = 1000.0; + else + casemult = 1.0; + with0->HalfkWBandLow = with0->FpctkWBandLow / 200.0 * with0->FkWTargetLow * casemult; + with0->FkWBandLow = with0->HalfkWBandLow * 2.0; + } + break; + case propKWBANDLOW: + { + if(with0->ChargeMode == CURRENTPEAKSHAVELOW) // evaluates the charging mode to apply + // a compensation value (for kamps) + casemult = 1000.0; + else + casemult = 1.0; + with0->HalfkWBandLow = with0->FkWBandLow / 2.0 * casemult; + with0->FpctkWBand = with0->FkWBandLow / with0->FkWTarget * 100.0; // sync FpctkWBandLow + } + break; +// propPFBAND: HalfPFBand := FPFBand / 2.0; + case propMODEDISCHARGE: + if(with0->DischargeMode == MODEFOLLOW) + with0->DischargeTriggerTime = 12.0; + break; // Noon + case propMONPHASE: + if(with0->FMonPhase > with0->Fnphases) + { + DoSimpleMsg(Format("Error: Monitored phase(%d) must be less than or equal to number of phases(%d). ", with0->FMonPhase, with0->Fnphases), 35302); + with0->FMonPhase = 1; + } + break; // levelize the list + case propELEMENTLIST: + { + int stop = 0; + with0->FleetPointerList->Clear(); // clear this for resetting on first sample + with0->FleetListChanged = true; + with0->FElementListSpecified = true; + with0->FleetSize = with0->FStorageNameList.size(); + // Realloc weights to be same size as possible number of storage elements + with0->FWeights = (pDoubleArray) realloc(with0->FWeights, sizeof(double) * with0->FleetSize); + for(stop = with0->FleetSize, i = 1; i <= stop; i++) + { + (with0->FWeights)[i - 1] = 1.0; + } + } + break; + case propYEARLY: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(with0->YearlyShapeObj == nullptr) + DoSimpleMsg(String("Yearly loadshape \"") + with0->YearlyShape + "\" not found.", 14404); + } + break; + case propDAILY: + { + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + if(with0->DailyShapeObj == nullptr) + DoSimpleMsg(String("Daily loadshape \"") + with0->DailyShape + "\" not found.", 14405); + } + break; + case propDUTY: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(with0->DutyShapeObj == nullptr) + DoSimpleMsg(String("Dutycycle loadshape \"") + with0->DutyShape + "\" not found.", 14406); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TStorageController::MakeLike(const String StorageController2Name) +{ + int result = 0; + TStorageControllerObj* OtherStorageController2 = nullptr; + int i = 0; + result = 0; + /*See If we can find this StorageController name in the present collection*/ + OtherStorageController2 = ((TStorageControllerObj*) Find(StorageController2Name)); + if(OtherStorageController2 != nullptr) + /*# with ActiveStorageController2Obj do */ + { + auto with0 = ActiveStorageController2Obj; + int stop = 0; + with0->Set_NPhases(OtherStorageController2->Fnphases); + with0->Set_Nconds(OtherStorageController2->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherStorageController2->ElementName; + with0->Set_ControlledElement(OtherStorageController2->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherStorageController2->get_FMonitoredElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherStorageController2->ElementTerminal; + with0->FMonPhase = OtherStorageController2->FMonPhase; + with0->CondOffset = OtherStorageController2->CondOffset; + with0->FkWTarget = OtherStorageController2->FkWTarget; + with0->FkWTargetLow = OtherStorageController2->FkWTargetLow; + with0->FkWThreshold = OtherStorageController2->FkWThreshold; + with0->DispFactor = OtherStorageController2->DispFactor; + with0->FpctkWBand = OtherStorageController2->FpctkWBand; + with0->FkWBand = OtherStorageController2->FkWBand; + with0->FpctkWBandLow = OtherStorageController2->FpctkWBandLow; + with0->FkWBandLow = OtherStorageController2->FkWBandLow; +// FPFTarget := OtherStorageController.FPFTarget; +// FPFBand := OtherStorageController.FPFBand; +// HalfPFBand := OtherStorageController.HalfPFBand; + with0->ResetLevel = OtherStorageController2->ResetLevel; + with0->FkWBandSpecified = OtherStorageController2->FkWBandSpecified; + with0->FStorageNameList.clear(); + for(stop = OtherStorageController2->FStorageNameList.size(), i = 1; i <= stop; i++) + { + with0->FStorageNameList.push_back(OtherStorageController2->FStorageNameList[i - 1]); + } + with0->FleetSize = with0->FStorageNameList.size(); + if(with0->FleetSize > 0) + { + int stop = 0; + with0->FWeights = (pDoubleArray) realloc(with0->FWeights, sizeof(double) * with0->FleetSize); + for(stop = with0->FleetSize, i = 1; i <= stop; i++) + { + (with0->FWeights)[i - 1] = (OtherStorageController2->FWeights)[i - 1]; + } + } + with0->DischargeMode = OtherStorageController2->DischargeMode; + with0->ChargeMode = OtherStorageController2->ChargeMode; + with0->DischargeTriggerTime = OtherStorageController2->DischargeTriggerTime; + with0->ChargeTriggerTime = OtherStorageController2->ChargeTriggerTime; + with0->pctKWRate = OtherStorageController2->pctKWRate; +// pctkvarRate := OtherStorageController.pctkvarRate; + with0->pctChargeRate = OtherStorageController2->pctChargeRate; + with0->pctFleetReserve = OtherStorageController2->pctFleetReserve; + with0->YearlyShape = OtherStorageController2->YearlyShape; + with0->DailyShape = OtherStorageController2->DailyShape; + with0->DutyShape = OtherStorageController2->DutyShape; +// DispatchVars := OtherStorageController.DispatchVars; + with0->ShowEventLog = OtherStorageController2->ShowEventLog; + with0->InhibitHrs = OtherStorageController2->InhibitHrs; + with0->UpRamptime = OtherStorageController2->UpRamptime; + with0->FlatTime = OtherStorageController2->FlatTime; + with0->DnrampTime = OtherStorageController2->DnrampTime; + with0->Seasons = OtherStorageController2->Seasons; + if(with0->Seasons > 1) + { + int stop = 0; + with0->SeasonTargets.resize(with0->Seasons); + with0->SeasonTargetsLow.resize(with0->Seasons); + for(stop = (with0->Seasons - 1), i = 0; i <= stop; i++) + { + with0->SeasonTargets[i] = OtherStorageController2->SeasonTargets[i]; + with0->SeasonTargetsLow[i] = OtherStorageController2->SeasonTargetsLow[i]; + } + } + + + //**** fill in private properties + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + // Skip Read only properties + case propKWHTOTAL: + ; + break; /*Do Nothing*/ + case propKWTOTAL: + ; + break; /*Do Nothing*/ + case propKWHACTUAL: + ; + break; /*Do Nothing*/ + case propKWACTUAL: + ; + break; /*Do Nothing*/ + case propKWNEED: + ; + break; /*Do Nothing*/ + default: + with0->Set_PropertyValue(i,OtherStorageController2->Get_PropertyValue(i)); + break; + } + } + } + else + DoSimpleMsg(String("Error in StorageController2 MakeLike: \"") + StorageController2Name + + "\" Not Found.", 370); + return result; +} + + + + +/*==========================================================================*/ +/* TStorageControllerObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TStorageControllerObj::TStorageControllerObj(TDSSClass* ParClass, const String StorageController2Name) + : inherited(ParClass), + FkWTarget(8000.0), + FkWTargetLow(4000.0), + FkWThreshold(6000.0), + FpctkWBand(2.0), + //FkWBand(HalfkWBand * 2.0), + FkWBand(0.0), + FpctkWBandLow(0.0), + FkWBandLow(0.0), + HalfkWBand(0.0), + HalfkWBandLow(0.0), + TotalWeight(0.0), + UpRamptime(0.0), + FlatTime(0.0), + DnrampTime(0.0), + UpPlusFlat(0.0), + UpPlusFlatPlusDn(0.0), + DischargeTriggerTime(0.0), + ChargeTriggerTime(0.0), + pctKWRate(0.0), + pctChargeRate(0.0), + LastpctDischargeRate(0.0), + TotalkWCapacity(0.0), + TotalkWhCapacity(0.0), + pctFleetReserve(0.0), + ResetLevel(0.0), + kWNeeded(0.0), + DispFactor(0.0), + FleetPointerList(nullptr), + FleetListChanged(false), + ChargingAllowed(false), + DischargeTriggeredByTime(false), + DischargeInhibited(false), + OutOfOomph(false), + FElementListSpecified(false), + Wait4Step(false), + FkWBandSpecified(false), + Seasons(0), + FleetSize(0), + FleetState(0), + DischargeMode(0), + InhibitHrs(0), + ChargeMode(0), + FMonPhase(0), + CondOffset(0), + YearlyShapeObj(nullptr), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr) +{ + Set_Name(LowerCase(StorageController2Name)); + FStorageNameList.clear(); + FWeights = NULL; + cBuffer.clear(); // Complex buffer + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + ElementName = ""; + Set_ControlledElement(nullptr); // not used in this control + ElementTerminal = 1; + Set_MonitoredElement(nullptr); + FMonPhase = MAXPHASE; + FleetPointerList = new PointerList::TPointerList(20); // Default size and increment + FleetSize = 0; + FleetState = STORE_IDLING; + DispFactor = 1.0; + FpctkWBandLow = 2.0; + HalfkWBand = FpctkWBand / 200.0 * FkWTarget; + HalfkWBandLow = FpctkWBandLow / 200.0 * FkWTargetLow; + FkWBandLow = HalfkWBandLow * 2.0; + TotalWeight = 1.0; + +// FPFTarget := 0.96; +// FPFBand := 0.04; +// HalfPFBand := FPFBand / 2.0; + kWNeeded = 0.0; + DischargeMode = MODEPEAKSHAVE; + ChargeMode = MODETIME; + DischargeTriggerTime = -1.0; // disabled + ChargeTriggerTime = 2.0; // 2 AM + FElementListSpecified = false; + FleetListChanged = true; // force building of list + FkWBandSpecified = false; // adopt pctkWBand by default + pctKWRate = 20.0; +// pctkvarRate := 20.0; + pctChargeRate = 20.0; + pctFleetReserve = 25.0; +// DispatchVars := FALSE; + DischargeTriggeredByTime = false; + DischargeInhibited = false; + OutOfOomph = false; + InhibitHrs = 5; // No. Hours to inhibit discharging after going into charge mode + UpRamptime = 0.25; // hr + FlatTime = 2.0; + DnrampTime = 0.25; + LastpctDischargeRate = 0.0; + Wait4Step = false; // for sync discharge with charge when there is a transition + ResetLevel = 0.8; + Seasons = 1; // For dynamic targets + SeasonTargets.resize( 1 ); + SeasonTargets[0] = FkWTarget; + SeasonTargetsLow.resize( 1 ); + SeasonTargetsLow[0] = FkWTargetLow; + InitPropertyValues(0); +} + +TStorageControllerObj::~TStorageControllerObj() +{ + ElementName = ""; + YearlyShape = ""; + DailyShape = ""; + DutyShape = ""; + if(!cBuffer.empty()) + cBuffer.clear(); + +/* Don't Do this here!! Disposes of actual object; + YearlyShapeObj.Free; + DailyShapeObj.Free; + DutyShapeObj.Free; +*/ + delete FleetPointerList; // FleetPointerList->~TPointerList(); + FStorageNameList.clear(); + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(propELEMENT,""); + Set_PropertyValue(propTERMINAL,"1"); + Set_PropertyValue(propMONPHASE,"MAX"); + Set_PropertyValue(propKWTARGET,"8000"); + Set_PropertyValue(propKWTARGETLOW,"4000"); + Set_PropertyValue(propPCTKWBAND,"2"); + Set_PropertyValue(propPCTKWBANDLOW,"2"); +// Set_PropertyValue(propPFTARGET] :='.96'); +// Set_PropertyValue(propPFBAND] :='.04'); + Set_PropertyValue(propELEMENTLIST,""); + Set_PropertyValue(propWEIGHTS,""); + Set_PropertyValue(propMODEDISCHARGE,"Follow"); + Set_PropertyValue(propMODECHARGE,"Time"); + Set_PropertyValue(propTIMEDISCHARGETRIGGER,"-1"); + Set_PropertyValue(propTIMECHARGETRIGGER,"2"); + Set_PropertyValue(propRATEKW,"20"); +// Set_PropertyValue(propRATEKVAR] :='20'); + Set_PropertyValue(propRATECHARGE,"20"); + Set_PropertyValue(propRESERVE,"25"); + Set_PropertyValue(propKWHTOTAL,""); + Set_PropertyValue(propKWTOTAL,""); + Set_PropertyValue(propKWACTUAL,""); + Set_PropertyValue(propKWNEED,""); +// Set_PropertyValue(propPARTICIPATION] :=''); + Set_PropertyValue(propYEARLY,""); + Set_PropertyValue(propDAILY,""); + Set_PropertyValue(propDUTY,""); + Set_PropertyValue(propEVENTLOG, ShowEventLog ? "YES" : "NO"); + Set_PropertyValue(propINHIBITTIME,"5"); + Set_PropertyValue(propTUPRAMP,"0.25"); + Set_PropertyValue(propTFLAT,"2.0"); + Set_PropertyValue(propTDNRAMP,"0.25"); + Set_PropertyValue(propKWTHRESHOLD,"4000"); + Set_PropertyValue(propDispFactor,"1.0"); + Set_PropertyValue(propRESETLEVEL,"0.8"); + Set_PropertyValue(propSEASONS,"1"); + Set_PropertyValue(propSEASONTARGETS,"[8000,]"); + Set_PropertyValue(propSEASONTARGETSLOW,"[4000,]"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +String TStorageControllerObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case propMONPHASE: + if(FMonPhase == AVG) + result = "AVG"; + else + { + if(FMonPhase == MAXPHASE) + result = "MAX"; + else + { + if(FMonPhase == MINPHASE) + result = "MIN"; + else + result = Format("%d", FMonPhase); + } + } + break; + case propKWTARGET: + result = Format("%-.6g", FkWTarget); + break; + case propKWTARGETLOW: + result = Format("%-.6g", FkWTargetLow); + break; + case propPCTKWBAND: + result = Format("%-.6g", FpctkWBand); + break; + case propKWBAND: + result = Format("%-.6g", FkWBand); + break; + case propPCTKWBANDLOW: + result = Format("%-.6g", FpctkWBandLow); + break; + case propKWBANDLOW: + result = Format("%-.6g", FkWBandLow); + break; +// propPFTARGET : Result := Format('%-.6g',[ConvertPFRange2ToPF(FPFTarget)]); +// propPFBAND : Result := Format('%-.6g',[FPFBand]); + case propELEMENTLIST: + result = ReturnElementsList(); + break; + case propWEIGHTS: + result = ReturnWeightsList(); + break; + case propMODEDISCHARGE: + result = GetModeString(propMODEDISCHARGE, DischargeMode); + break; + case propMODECHARGE: + result = GetModeString(propMODECHARGE, ChargeMode); + break; + case propTIMEDISCHARGETRIGGER: + result = Format("%.6g", DischargeTriggerTime); + break; + case propTIMECHARGETRIGGER: + result = Format("%.6g", ChargeTriggerTime); + break; + case propRATEKW: + result = Format("%-.8g", pctKWRate); + break; +// propRATEKVAR : Result := Format('%-.8g',[pctkvarRate]); + case propRATECHARGE: + result = Format("%-.8g", pctChargeRate); + break; + case propRESERVE: + result = Format("%-.8g", pctFleetReserve); + break; + case propKWHTOTAL: + result = GetkWhTotal(TotalkWhCapacity); + break; + case propKWTOTAL: + result = GetkWTotal(TotalkWCapacity); + break; + case propKWHACTUAL: + result = GetkWhActual(); + break; + case propKWACTUAL: + result = GetkWActual(); + break; + case propKWNEED: + result = Format("%-.6g", kWNeeded); + break; + /*propPARTICIPATION : Result := PropertyValue[Index]; */ + case propYEARLY: + result = YearlyShape; + break; + case propDAILY: + result = DailyShape; + break; + case propDUTY: + result = DutyShape; + break; + case propEVENTLOG: + if(ShowEventLog) + result = "Yes"; + else + result = "No"; + break; +// propVARDISPATCH : If DispatchVars Then Result := 'Yes' Else Result := 'No'; + case propINHIBITTIME: + result = Format("%d", InhibitHrs); + break; + case propTUPRAMP: + result = Format("%.6g", UpRamptime); + break; + case propTFLAT: + result = Format("%.6g", FlatTime); + break; + case propTDNRAMP: + result = Format("%.6g", DnrampTime); + break; + case propKWTHRESHOLD: + result = Format("%.6g", FkWThreshold); + break; + case propDispFactor: + result = Format("%.6g", DispFactor); + break; + case propRESETLEVEL: + result = Format("%.6g", ResetLevel); + break; + case propSEASONS: + result = Format("%d", Seasons); + break; + case propSEASONTARGETS: + result = ReturnSeasonTarget(1); + break; + case propSEASONTARGETSLOW: + result = ReturnSeasonTarget(0); + break; // take the generic handler + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +double TStorageControllerObj::Get_FleetkW() +{ + double result = 0.0; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + result = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + result = result + pStorage->Get_PresentkW(); + } + return result; +} + +double TStorageControllerObj::Get_FleetkWh() +{ + double result = 0.0; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + result = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + result = result + pStorage->StorageVars.kWhStored; + } + return result; +} + +double TStorageControllerObj::Get_FleetkWhRating() +{ + double result = 0.0; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + result = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + result = result + pStorage->StorageVars.kWhRating; + } + return result; +} + +double TStorageControllerObj::Get_FleetReservekWh() +{ + double result = 0.0; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + result = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + result = result + pStorage->StorageVars.kWhReserve; + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +// Recalculate critical element values after changes have been made + +void TStorageControllerObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + + /*Check for existence of monitored element*/ + DevIndex = GetCktElementIndex(ElementName); // Global FUNCTION + if(DevIndex > 0) + { + Set_MonitoredElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + if(ElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("StorageController2: \"") + get_Name() + "\"", "Terminal no. \"" "\" Does not exist.", "Re-specify terminal no.", 371); + } + else + { + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); + Set_Nconds(Fnphases); + + // Sets name of i-th terminal's connected bus in StorageController's buslist + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer.resize(get_FMonitoredElement()->Yorder + 1); + CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + } + else + DoSimpleMsg(String("Monitored Element in StorageController2.") + get_Name() + + " Does not exist:\"" + + ElementName + + "\"", 372); + if(FleetListChanged) + { + if(!MakeFleetList()) + DoSimpleMsg(String("No unassigned Storage Elements found to assign to StorageController2.") + get_Name(), 37201); + } + GetkWTotal(TotalkWCapacity); + GetkWhTotal(TotalkWhCapacity); + if(FleetSize > 0) + { + SetFleetToExternal(); + SetAllFleetValues(); + } + UpPlusFlat = UpRamptime + FlatTime; + UpPlusFlatPlusDn = UpPlusFlat + DnrampTime; +} + +void TStorageControllerObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FMonitoredElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer.resize(get_FMonitoredElement()->Yorder + 1); + CondOffset = (ElementTerminal - 1) * get_FMonitoredElement()->Get_NConds(); // for speedy sampling + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TStorageControllerObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +String TStorageControllerObj::GetkWActual() +{ + String result; + result = Format("%-.8g", Get_FleetkW()); + return result; +} + +String TStorageControllerObj::GetkWhActual() +{ + String result; + result = Format("%-.8g", Get_FleetkWh()); + return result; +} + +String TStorageControllerObj::GetkWhTotal(double& Sum) +{ + String result; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + Sum = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + Sum = Sum + pStorage->StorageVars.kWhRating; + } + result = Format("%-.8g", Sum); + return result; +} + +String TStorageControllerObj::GetkWTotal(double& Sum) +{ + String result; + TStorageObj* pStorage = nullptr; + int i = 0; + int stop = 0; + Sum = 0.0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + pStorage = (TStorageObj*) FleetPointerList->Get(i); + Sum = Sum + pStorage->StorageVars.kWrating; + } + result = Format("%-.8g", Sum); + return result; +} + +String TStorageControllerObj::GetModeString(int Opt, int Mode) +{ + String result; + result = ""; + switch(Opt) + { + case propMODEDISCHARGE: + switch(Mode) + { + case MODEFOLLOW: + result = "Follow"; + break; + case MODELOADSHAPE: + result = "Loadshape"; + break; + case MODESUPPORT: + result = "Support"; + break; + case MODETIME: + result = "Time"; + break; + case MODEPEAKSHAVE: + result = "Peakshave"; + break; + case CURRENTPEAKSHAVE: + result = "I-Peakshave"; + break; + default: + result = "UNKNOWN"; + break; + } + break; + case propMODECHARGE: + switch(Mode) + { + case MODELOADSHAPE: + // 1: Result := 'Follow'; + result = "Loadshape"; + break; + // 3: Result := 'Support'; + case MODETIME: + result = "Time"; + break; + case MODEPEAKSHAVELOW: + result = "PeakshaveLow"; + break; + case CURRENTPEAKSHAVELOW: + result = "I-PeakShaveLow"; + break; + default: + result = "UNKNOWN"; + break; + } + break; + default: + DoSimpleMsg("Unknown Charge/Discharge designation", 14401); + break; + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + + + /* + Release the discharge inhibit . + Do nothing for other codes + */ + if((Code == RELEASE_INHIBIT) && (DischargeMode != MODEFOLLOW)) + DischargeInhibited = false; +} +/* + In SCHEDULE mode we ramp up the storage from zero to the specified pctkWRate. + This value is held for the flattime or until they turn themselves + off when they are either fully discharged, or ramped down + + The discharge trigger time must be greater than 0 +*/ + +void TStorageControllerObj::DoScheduleMode(int ActorID) +{ + double TDiff = 0.0; + double pctDischargeRate = 0.0; + pctDischargeRate = 0.0; // init for test + if(DischargeTriggerTime > 0.0) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + // turn on if time within 1/2 time step + if(!(FleetState == STORE_DISCHARGING)) + { + ChargingAllowed = true; + TDiff = NormalizeToTOD(with0->DynaVars.intHour, with0->DynaVars.T) - DischargeTriggerTime; + if(Abs( TDiff) < with0->DynaVars.h / 7200.0) + /*Time is within 1 time step of the trigger time*/ + { + if(ShowEventLog) + AppendToEventLog(String("StorageController2.") + this->get_Name(), "Fleet Set to Discharging (up ramp) by Schedule", ActorID); + SetFleetToDisCharge(); + SetFleetDesiredState(STORE_DISCHARGING); + ChargingAllowed = false; + pctDischargeRate = min(pctKWRate, max(pctKWRate * TDiff / UpRamptime, 0.0)); + SetFleetkWRate(pctDischargeRate); + DischargeInhibited = false; + PushTimeOntoControlQueue(STORE_DISCHARGING, ActorID); + } + } + else + // fleet is already discharging + { + TDiff = NormalizeToTOD(with0->DynaVars.intHour, with0->DynaVars.T) - DischargeTriggerTime; + if(TDiff < UpRamptime) + { + pctDischargeRate = min(pctKWRate, max(pctKWRate * TDiff / UpRamptime, 0.0)); + SetFleetDesiredState(STORE_DISCHARGING); + if(pctDischargeRate != LastpctDischargeRate) + { + SetFleetkWRate(pctDischargeRate); + SetFleetToDisCharge(); + } + } + else + { + if(TDiff < UpPlusFlat) + { + pctDischargeRate = pctKWRate; + SetFleetDesiredState(STORE_DISCHARGING); + if(pctDischargeRate != LastpctDischargeRate) + SetFleetkWRate(pctKWRate); // on the flat part + } + else + { + if(TDiff > UpPlusFlatPlusDn) + { + SetFleetToIdle(); + ChargingAllowed = true; + pctDischargeRate = 0.0; + if(ShowEventLog) + AppendToEventLog(String("StorageController2.") + this->get_Name(), "Fleet Set to Idling by Schedule", ActorID); + } + else + // We're on the down ramp + { + TDiff = UpPlusFlatPlusDn - TDiff; + pctDischargeRate = max(0.0, min(pctKWRate * TDiff / DnrampTime, pctKWRate)); + SetFleetDesiredState(STORE_DISCHARGING); + SetFleetkWRate(pctDischargeRate); + } + } + } + if(pctDischargeRate != LastpctDischargeRate) + PushTimeOntoControlQueue(STORE_DISCHARGING, ActorID); + } /*If not fleetstate ...*/ + } + LastpctDischargeRate = pctDischargeRate; // remember this value +} +/* + In Time mode we need to only turn the storage elements on. They will turn themselves + off when they are either fully discharged, fully charged, or receive another command + from the controller +*/ + +void TStorageControllerObj::DoTimeMode(int Opt, int ActorID) +{ + double RemainingkWh = 0.0; + double ReservekWh = 0.0; + double TotalRatingkWh = 0.0; + TotalRatingkWh = Get_FleetkWhRating(); + RemainingkWh = Get_FleetkWh(); + ReservekWh = Get_FleetReservekWh(); + switch(Opt) + { + case 1: + { + if(DischargeTriggerTime > 0.0) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + // turn on if time within 1/2 time step + if(Abs( (NormalizeToTOD(with0->DynaVars.intHour, with0->DynaVars.T) - DischargeTriggerTime)) < with0->DynaVars.h / 7200.0) + { + SetFleetDesiredState(STORE_DISCHARGING); + if(!(FleetState == STORE_DISCHARGING) && (RemainingkWh > ReservekWh)) + /*Time is within 1 time step of the trigger time*/ + { + if(ShowEventLog) + AppendToEventLog(String("StorageController2.") + this->get_Name(), "Fleet Set to Discharging by Time Trigger", ActorID); + SetFleetToDisCharge(); + SetFleetkWRate(pctKWRate); + DischargeInhibited = false; + if(DischargeMode == MODEFOLLOW) + DischargeTriggeredByTime = true; + else + PushTimeOntoControlQueue(STORE_DISCHARGING, ActorID); + } + } + else + ChargingAllowed = true; + } + } + break; // Discharge mode + case 2: + { + if(ChargeTriggerTime > 0.0) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + if(Abs( (NormalizeToTOD(with1->DynaVars.intHour, with1->DynaVars.T) - ChargeTriggerTime)) < with1->DynaVars.h / 7200.0) + { + SetFleetDesiredState(STORE_CHARGING); + if(!(FleetState == STORE_CHARGING) && (RemainingkWh < TotalRatingkWh)) + /*Time is within 1 time step of the trigger time*/ + { + if(ShowEventLog) + AppendToEventLog(String("StorageController2.") + this->get_Name(), "Fleet Set to Charging by Time Trigger", ActorID); + SetFleetToCharge(); + DischargeInhibited = true; + OutOfOomph = false; + PushTimeOntoControlQueue(STORE_CHARGING, ActorID); // force re-solve at this time step + // Push message onto control queue to release inhibit at a later time + /*# with ActiveCircuit[ActorID] do */ + { + + ActiveCircuit[ActorID]->Solution->LoadsNeedUpdating = true; // Force recalc of power parms + ActiveCircuit[ActorID]->ControlQueue.Push(with1->DynaVars.intHour + InhibitHrs, with1->DynaVars.T, (EControlAction) RELEASE_INHIBIT, 0, this, ActorID); + } + } + } + } + } + break; //Charge mode + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +// Normalize time to a floating point number representing time of day If Hour > 24 +// time should be 0 to 23.999999.... + +double TStorageControllerObj::NormalizeToTOD(int h, double Sec) +{ + double result = 0.0; + int HourOfDay = 0; + if(h > 23) + HourOfDay = (h - ((h / 24)) * 24); + else + HourOfDay = h; + result = HourOfDay + Sec / 3600.0; + if(result >= 24.0) + result = result - 24.0; // Wrap around + return result; +} +/* + Push present time onto control queue to force re solve at new dispatch value +*/ + +void TStorageControllerObj::PushTimeOntoControlQueue(int Code, int ActorID) +{ + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + with1->LoadsNeedUpdating = true; // Force recalc of power parms + ActiveCircuit[ActorID]->ControlQueue.Push(with1->DynaVars.intHour, with1->DynaVars.T, (EControlAction) Code, 0, this, ActorID); + } +} + +/*--------------------------------------------------------------------------*/ + +double TStorageControllerObj::Get_DynamicTarget(int THigh, int ActorID) +{ + double result = 0.0; + double Temp = 0.0; + double temp2 = 0.0; + int RatingIdx = 0; + TXYcurveObj* RSignal = nullptr; + if(SeasonSignal != "") + { + RSignal = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(SeasonSignal)); + if(RSignal != nullptr) + RatingIdx = Trunc(RSignal->GetYValue_((double) ActiveCircuit[ActorID]->Solution->DynaVars.intHour)); + if((RatingIdx <= Seasons) && (Seasons > 1)) + { + if(THigh == 1) + result = SeasonTargets[RatingIdx]; + else + result = SeasonTargetsLow[RatingIdx]; + } + else + { + if(THigh == 1) + result = FkWTarget; + else + result = FkWTargetLow; + } + } + return result; +} + + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::DoLoadFollowMode(int ActorID) +{ + int i = 0; + complex s = {}; + TStorageObj* StorageObj = nullptr; + bool StorekWChanged = false; + bool StorekvarChanged = false; + bool SkipkWDispatch = false; + pComplexArray VoltsArr; +// PFDiff, + +// Dispatchkvar, + double kWhActual = 0.0; + double ElemVolts = 0.0; + double Amps = 0.0; + double AmpsDiff = 0.0; + double PDiff = 0.0; + double DispatchkW = 0.0; + double RemainingkWh = 0.0; + double CtrlTarget = 0.0; + double ReservekWh = 0.0; + double ActualkWDispatch = 0.0; + + // If list is not defined, go make one from all storage elements in circuit + if(FleetPointerList->get_myNumList() == 0) + MakeFleetList(); + if(FleetSize > 0) + { + StorekWChanged = false; + StorekvarChanged = false; + SkipkWDispatch = false; + + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + if(DischargeMode == CURRENTPEAKSHAVE) + { + get_FMonitoredElement()->GetCurrents(&(cBuffer[0]), ActorID); + GetControlCurrent(Amps); + +// Amps := MonitoredElement.MaxCurrent[ElementTerminal,ActorID]; // Max current in active terminal // old + } + else + GetControlPower(s, ActorID); + + // In case of having seasonal targets + if(SeasonalRating) + CtrlTarget = Get_DynamicTarget(1, ActorID); + else + CtrlTarget = FkWTarget; + switch(DischargeMode) + { + case MODEFOLLOW: + // Following Load; try to keep load below kW Target + { + if(DischargeTriggeredByTime) + { + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), Format("Fleet Set to Discharging by Time Trigger; Old kWTarget = %-.6g; New = %-.6g", FkWTarget, s.re * 0.001), ActorID); + FkWTarget = max(FkWThreshold, s.re * 0.001); // Capture present kW and reset target + if(!FkWBandSpecified) + HalfkWBand = FpctkWBand / 200.0 * FkWTarget; // Update band to new target if absolute kWBand hasn`t been specified + DischargeTriggeredByTime = false; // so we don't come back in here right away + SetFleetToIdle(); + SetFleetDesiredState(STORE_IDLING); + } + PDiff = s.re * 0.001 - FkWTarget; // Assume S.re is normally positive +// PFDiff := ConvertPFToPFRange2(PowerFactor(S)) - FPFTarget; // for peak shaving + } + break; + // supporting DG; Try to keep load above kW target + case MODESUPPORT: + { + PDiff = s.re * 0.001 + FkWTarget; // assume S.re is normally negative +// PFDiff := ConvertPFToPFRange2(PowerFactor(S)) - FPFTarget; // for generator + } + break; + case MODEPEAKSHAVE: + { + PDiff = s.re * 0.001 - CtrlTarget; // Assume S.re is normally positive +// PFDiff := ConvertPFToPFRange2(PowerFactor(S)) - FPFTarget; // for peak shaving + } + break; + case CURRENTPEAKSHAVE: + { + PDiff = Amps - CtrlTarget * 1000; // Gets the difference in terms of amps +// DispatchVars := False; + } + break; + default: + PDiff = 0.0; + break; + } + if(DischargeMode == CURRENTPEAKSHAVE) // convert Pdiff from Amps to kW + { + get_FMonitoredElement()->ComputeVterminal(ActorID); + VoltsArr = &(get_FMonitoredElement()->Vterminal[0]); + ElemVolts = cabs(VoltsArr[1 - 1]); + kWNeeded = ((get_FMonitoredElement()->Get_NPhases() * PDiff * ElemVolts) / 1000.0); +// kWNeeded := ((Pdiff * ElemVolts) / 1000.0); + AmpsDiff = PDiff; + } + else + +// kWNeeded := Pdiff + FleetkW; + kWNeeded = PDiff; + + /* kW dispatch */ + + // Check if Fleet is Idling (FleetState is updated only if entire fleet is idling) + if(!(FleetState == STORE_IDLING)) + { + int stop = 0; + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) FleetPointerList->Get(i); + if(StorageObj->get_fState() != STORE_IDLING) + break; + if(i == FleetSize) + FleetState = STORE_IDLING; + } + } + if(DischargeInhibited) + SkipkWDispatch = true; + else + +// If FleetState = STORE_CHARGING Then +// Begin +// if Not (Dischargemode = CURRENTPEAKSHAVE) then +// Pdiff := Pdiff + FleetkW // ignore overload due to charging +// else +// Begin +// MonitoredElement.ComputeVterminal(ActorID); +// VoltsArr := MonitoredElement.Vterminal; +// ElemVolts := cabs(VoltsArr^[1]); +// Pdiff := Pdiff + (FleetkW * 1000 / ElemVolts); +// End; +// end; + +// If Not (FleetState = STORE_DISCHARGING) Then // ignore overload due to charging or idling (trickle charging) - FleetkW < 0 + { + if(FleetState == STORE_CHARGING) + { + if(!(DischargeMode == CURRENTPEAKSHAVE)) + PDiff = PDiff + Get_FleetkW(); + else + { + get_FMonitoredElement()->ComputeVterminal(ActorID); + VoltsArr = &(get_FMonitoredElement()->Vterminal[0]); + ElemVolts = cabs(VoltsArr[1 - 1]); + PDiff = PDiff + (Get_FleetkW() * 1000 / (ElemVolts * get_FMonitoredElement()->Get_NPhases())); +// Pdiff := Pdiff + (FleetkW * 1000 / (ElemVolts )); + } + } + switch(FleetState) + { + case STORE_CHARGING: case STORE_IDLING: + if((PDiff - HalfkWBand < 0.0) || OutOfOomph) // Don't bother trying to dispatch + { + ChargingAllowed = true; + SkipkWDispatch = true; + if(OutOfOomph) // --------------------------------- new 04/20/2020 ---------- + { + int stop = 0; + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) FleetPointerList->Get(i); + kWhActual = StorageObj->StorageVars.kWhStored / StorageObj->StorageVars.kWhRating; + OutOfOomph = OutOfOomph && (kWhActual >= ResetLevel); // If we have more than the 80% we are good to dispatch + } + OutOfOomph = !OutOfOomph; // If everybody in the fleet has at least the 80% of the storage capacity full + } // ----------------------------------------------------------------------- + } + break; + + /* STORE_DISCHARGING: If (PDiff < 0.0) or OutOfOomph Then + Begin // desired decrease is greater then present output; just cancel + SetFleetToIdle; // also sets presentkW = 0 + PushTimeOntoControlQueue(STORE_IDLING, ActorID); // force a new power flow solution + ChargingAllowed := TRUE; + SkipkWDispatch := TRUE; + Wait4Step := TRUE; // To tell to the charging section to wait for the next sim step + // useful when workin with large simulation time steps + End;*/ + default: + ; + break; + } + } + if(!SkipkWDispatch) + { + RemainingkWh = Get_FleetkWh(); + ReservekWh = Get_FleetReservekWh(); + if(RemainingkWh > ReservekWh) + // don't dispatch kW if not enough storage left or an endless control loop will occur + { + if(Abs( PDiff) > HalfkWBand) // Attempt to change storage dispatch + { + int stop = 0; + if(!(FleetState == STORE_DISCHARGING)) + { + SetFleetToDisCharge(); +// StorekWChanged:= TRUE; // if not already discharging, force new power flow. + } + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), Format("Attempting to dispatch %-.6g kW with %-.6g kWh remaining and %-.6g kWh reserve.", kWNeeded, RemainingkWh, ReservekWh), ActorID); + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) FleetPointerList->Get(i); + if(DischargeMode == CURRENTPEAKSHAVE) // Current to power + // (MonitoredElement.MaxVoltage[ElementTerminal,ActorID] / 1000) + { + if( ( (TDSSCktElement*) StorageObj )->Get_NPhases() == 1) + kWNeeded = StorageObj->Get_PresentkV() * AmpsDiff; + else + +// kWNeeded := StorageObj.PresentkV * InvSQRT3 * AmpsDiff; + kWNeeded = StorageObj->Get_PresentkV() * SQRT3 * AmpsDiff; + } + /*# with StorageObj do */ + { + auto with0 = StorageObj; + // compute new dispatch value for this storage element ... + DispatchkW = min(with0->StorageVars.kWrating, (with0->Get_PresentkW() + kWNeeded * DispFactor * (FWeights[i - 1] / TotalWeight))); // Dispatch kWNeeded + if(DispatchkW <= 0.0) // if kWNeeded is too low, DispatchkW may be negative depending on idling losses. In this case, just set it to idling + { + with0->Set_StorageState(STORE_IDLING); // overrides SetFleetToDischarge + if(Abs( with0->Get_PresentkW()) - StorageObj->kWOutIdling > EPSILON) // if not already idling + { + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + StorekWChanged = true; // if not idling at first, force a new powerflow + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW. Setting " + + StorageObj->Get_QualifiedName() + + " to idling state. Final kWOut is %-.6g kW").c_str(), DispatchkW, ActualkWDispatch), ActorID); +// DispatchkW := 0.0; + } + } + else + { + if(double(Abs( (with0->Get_kW() - DispatchkW))) / Abs( DispatchkW) > 0.0001) // redispatch only if change requested + { + if(DispatchkW < max(with0->Get_CutInkWAC(), with0->Get_CutOutkWAC())) // Necessary check to avoid the control to go into an infinite loop when DispatchkW is less than CutOutkWAC + { + if(with0->Get_InverterON() == true) // request Dispatch only if the inverter is on (only once). + + // Next time, the inverter will be OFF and the control won't dispatch a new power + { + if(with0->StorageVars.kWhStored > with0->StorageVars.kWhReserve) + { + with0->Set_kW(DispatchkW); + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + StorekWChanged = true; // This is what keeps the control iterations going + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW, less than CutIn/CutOut." + + " Final kWOut is %-.6g kW").c_str(), DispatchkW, ActualkWDispatch), ActorID); + } + } + else + + + // if inverter is already off, just override discharging state to + // idling and update current kvarlimit for usage by InvControl + { + with0->Set_StorageState(STORE_IDLING); // overrides SetFleetToDischarge + with0->SetNominalStorageOutput(ActorID); // to update current kvarLimit + ActualkWDispatch = with0->Get_PresentkW(); + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW, less than CutIn/CutOut." + + " Inverter is OFF. Final kWOut is %-.6g kW").c_str(), DispatchkW, ActualkWDispatch), ActorID); + } + } + else + { + if(with0->StorageVars.kWhStored > with0->StorageVars.kWhReserve) // Attempt to set discharge kW; Storage element will revert to idling if out of capacity + { + with0->Set_kW(DispatchkW); + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + StorekWChanged = true; // This is what keeps the control iterations going + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW. Final kWOut is %-.6g kW").c_str(), DispatchkW, ActualkWDispatch), ActorID); + } + } + } + } + } + } + } + } + else + { + if(!(FleetState == STORE_IDLING)) + { + SetFleetToIdle(); + PushTimeOntoControlQueue(STORE_IDLING, ActorID); // force a new power flow solution + } + ChargingAllowed = true; + OutOfOomph = true; + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format("Ran out of OOMPH: %-.6g kWh remaining and %-.6g reserve. Fleet has been set to idling state.", + RemainingkWh, ReservekWh), ActorID); + } + } + if(StorekWChanged || StorekvarChanged) // Only push onto controlqueue If there has been a change + PushTimeOntoControlQueue(STORE_DISCHARGING, ActorID); + + /*Else just continue*/ + } +} + +/*--------------------------------------------------------------------------*/ + // This is the peakShaving mode for controlling the charging operation of the storage fleet + // The objective is to charge the storage fleet when the power at a monitored element is bellow a specified KW target (kWTarget_low) + // The storage will charge as much power as necessary to keet the power within the deadband around kWTarget_low + + // WILL NOT IMPLEMENT REACTIVE POWER CONTROL FOR NOW + +void TStorageControllerObj::DoPeakShaveModeLow(int ActorID) +{ + int i = 0; + complex s = {}; + pComplexArray VoltsArr = nullptr; + TStorageObj* StorageObj = nullptr; + bool StorekWChanged = false; + bool SkipkWCharge = false; + double ElemVolts = 0.0; + double PDiff = 0.0; + double kWNeeded = 0.0; + double Amps = 0.0; + double AmpsDiff = 0.0; + double ChargekW = 0.0; + double ActualkWh = 0.0; + double ActualkW = 0.0; + double TotalRatingkWh = 0.0; + double KwtoPercentagekW = 0.0; + double CtrlTarget = 0.0; + double ActualkWDispatch = 0.0; + // If list is not defined, go make one from all storage elements in circuit + if(FleetPointerList->get_myNumList() == 0) + MakeFleetList(); + +// If (FleetSize>0) And(Not(FleetState = STORE_DISCHARGING)) Then + if(FleetSize > 0) + { + StorekWChanged = false; + SkipkWCharge = false; + if(SeasonalRating) + CtrlTarget = Get_DynamicTarget(0, ActorID); + else + CtrlTarget = FkWTargetLow; + + + //----MonitoredElement.ActiveTerminalIdx := ElementTerminal; + if(ChargeMode == CURRENTPEAKSHAVELOW) + { + get_FMonitoredElement()->GetCurrents(&(cBuffer[0]), ActorID); + GetControlCurrent(Amps); +// Amps := MonitoredElement.MaxCurrent[ElementTerminal,ActorID]; // Max current in active terminal + PDiff = Amps - CtrlTarget * 1000; // Gets the difference in terms of amps + } + else + { + GetControlPower(s, ActorID); + PDiff = s.re * 0.001 - CtrlTarget; // Assume S.re is normally positive + } + ActualkW = Get_FleetkW(); + ActualkWh = Get_FleetkWh(); + TotalRatingkWh = Get_FleetkWhRating(); + if(ChargeMode == CURRENTPEAKSHAVELOW) // convert Pdiff from Amps to kW + { + get_FMonitoredElement()->ComputeVterminal(ActorID); + VoltsArr = &(get_FMonitoredElement()->Vterminal[0]); + ElemVolts = cabs((VoltsArr)[1 - 1]); // LN voltage + kWNeeded = ((get_FMonitoredElement()->Get_NPhases() * PDiff * ElemVolts) / 1000.0); +// kWNeeded := (( PDiff * ElemVolts) / 1000.0); + AmpsDiff = PDiff; + } + else + +// kWNeeded := Pdiff + FleetkW; + kWNeeded = PDiff; + + + // Check if Fleet is Idling (FleetState is updated only if entire fleet is idling) + if(!(FleetState == STORE_IDLING)) + { + int stop = 0; + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) FleetPointerList->Get(i); + if(StorageObj->get_fState() != STORE_IDLING) + break; + if(i == FleetSize) + FleetState = STORE_IDLING; + } + } + +// +// CASE FleetState of +// STORE_CHARGING, +// STORE_IDLING: If (PDiff < 0.0) or OutOfOomph Then +// Begin // Don't bother trying to dispatch +// ChargingAllowed := TRUE; +// SkipkWDispatch := TRUE; +// End; +// END; + + +// If Not (FleetState = STORE_CHARGING) Then // ignore underload due to discharging (FleetkW > 0) and discount idlings losses (may delay the charging) + if(FleetState == STORE_DISCHARGING) + { + if(!(ChargeMode == CURRENTPEAKSHAVELOW)) + PDiff = PDiff + Get_FleetkW(); + else + { + get_FMonitoredElement()->ComputeVterminal(ActorID); + VoltsArr = &(get_FMonitoredElement()->Vterminal[0]); + ElemVolts = cabs((VoltsArr)[1 - 1]); + PDiff = PDiff + (Get_FleetkW() * 1000 / (ElemVolts * get_FMonitoredElement()->Get_NPhases())); // get actual Pdiff in Currents (discount FleetkW) (assuming same number of phases of Fleet and Monitored Element) +// Pdiff := Pdiff + (FleetkW * 1000 / (ElemVolts )); + } + } + switch(FleetState) + { + case STORE_DISCHARGING: + case STORE_IDLING: + if((PDiff > 0.0) || (ActualkWh >= TotalRatingkWh) || Wait4Step) // Don't bother trying to charge + { + ChargingAllowed = false; + SkipkWCharge = true; + Wait4Step = false; +// End; +// STORE_CHARGING: If (kWNeeded > 0.0) or (ActualkWh>=TotalRatingkWh) // old approach +// STORE_CHARGING: If (Pdiff + FleetkW > 0.0) or (ActualkWh >= TotalRatingkWh) Then +// Begin // desired decrease (in absolute value) is greater than present output; just cancel +// SetFleetToIdle; // also sets presentkW = 0 +// PushTimeOntoControlQueue(STORE_IDLING, ActorID); // force a new power flow solution +// ChargingAllowed := FALSE; +// SkipkWCharge := TRUE; +// End; + } + break; + default: + ; + break; + } + if(!SkipkWCharge) + { + if(ActualkWh < TotalRatingkWh) + // don't dispatch kW if fully charged or an endless control loop will occur + { + if(Abs( PDiff) > HalfkWBandLow) // Attempt to change storage kW charge + { + int stop = 0; + if(!(FleetState == STORE_CHARGING)) + { + SetFleetToCharge(); +// StorekWChanged:= TRUE; // if not already charging, force new power flow. + } + // If ShowEventLog Then AppendToEventLog('StorageController.' + Self.Name, Format('Attempting to charge %-.6g kW with %-.6g kWh remaining and %-.6g rating.', [kWNeeded, (TotalRatingkWh-ActualkWh), TotalRatingkWh]), ActorID); + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format("Attempting to charge %-.6g kW with %-.6g kWh remaining and %-.6g rating.", + kWNeeded, (TotalRatingkWh - ActualkWh), TotalRatingkWh), ActorID); + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) FleetPointerList->Get(i); + /*# with StorageObj do */ + { + auto with0 = StorageObj; + + // Checks if PDiff needs to be adjusted considering the charging mode + if(ChargeMode == CURRENTPEAKSHAVELOW) + { + if( ( (TDSSCktElement*) StorageObj )->Get_NPhases() == 1) + kWNeeded = StorageObj->Get_PresentkV() * AmpsDiff; + else + +// kWNeeded := StorageObj.PresentkV * InvSQRT3 * AmpsDiff; + kWNeeded = StorageObj->Get_PresentkV() * InvSQRT3 * AmpsDiff; + } + + + // compute new charging value for this storage element ... + // ChargekW := -1 * Min(StorageVars.kWrating, abs(Get_PresentkW() + Pdiff *(FWeights^[i]/TotalWeight))); // old approach + ChargekW = with0->Get_PresentkW() + kWNeeded * ((FWeights)[i - 1] / TotalWeight) * DispFactor; // may be positive or negative + if(ChargekW < 0) + ChargekW = max(-1 * with0->StorageVars.kWrating, ChargekW); // check against kVA rating + if(ChargekW >= 0) // chargekW may be positive if increase in demand is too high. + { + with0->Set_StorageState(STORE_IDLING); // overrides SetFleetToDischarge + if(Abs( with0->Get_PresentkW()) - StorageObj->kWOutIdling > EPSILON) // if not already idling + { + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + StorekWChanged = true; // if not idling at first, force a new powerflow + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW. Setting " + + StorageObj->Get_QualifiedName() + + " to idling state. Final kWOut is %-.6g kW").c_str(), ChargekW, ActualkWDispatch), ActorID); + } + } + else + + // If ChargekW <> PresentkW Then // do only if change requested + { + if(Abs( (StorageObj->Get_kW() - ChargekW)) / Abs(ChargekW) > 0.0001) // do only if change requested + { + if(Abs( ChargekW) < max(with0->Get_CutInkWAC(), with0->Get_CutOutkWAC())) // Necessary check to avoid the control to go into an infinite loop when ChargekW is less than CutOutkWAC + { + if(with0->Get_InverterON() == true) // request Dispatch only if the inverter is on (only once). + + // Next time the inverter will be OFF and the control won't dispatch a new power + { + if(with0->StorageVars.kWhStored > with0->StorageVars.kWhReserve) + { + with0->Set_kW(ChargekW); + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + StorekWChanged = true; // This is what keeps the control iterations going + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW, less than CutIn/CutOut." + + " Final kWOut is %-.6g kW").c_str(), ChargekW, ActualkWDispatch), ActorID); + } + } + else + + + // if inverter is already off, just override discharging state to + // idling and update current kvarlimit for usage by InvControl + { + with0->Set_StorageState(STORE_IDLING); // overrides SetFleetToCharge + with0->SetNominalStorageOutput(ActorID); // to update current kvarLimit + ActualkWDispatch = with0->Get_PresentkW(); + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW, less than CutIn/CutOut." + + " Inverter is OFF. Final kWOut is %-.6g kW").c_str(), ChargekW, ActualkWDispatch), ActorID); + } + } + else + { + if(with0->StorageVars.kWhStored < with0->StorageVars.kWhRating) // Attempt to set discharge kW; Storage element will revert to idling if out of capacity + //StorageObj.PresentkW := ChargekW; + { + with0->Set_kW(ChargekW); + with0->SetNominalStorageOutput(ActorID); + ActualkWDispatch = with0->Get_PresentkW(); + // KwtoPercentagekW := (ChargekW*100) / StorageVars.kWrating; // old approach + // StorageObj.pctkWin := abs(KwtoPercentagekW); // old approach + StorekWChanged = true; // This is what keeps the control iterations going + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format(("Requesting " + StorageObj->Get_QualifiedName() + + " to dispatch %-.6g kW. Final kWOut is %-.6g kW").c_str(), ChargekW, ActualkWDispatch), ActorID); + } + } + } + } + } + } + } + } + else + { + if(!(FleetState == STORE_IDLING)) + { + SetFleetToIdle(); + PushTimeOntoControlQueue(STORE_IDLING, ActorID); // force a new power flow solution + } + ChargingAllowed = false; + if(ShowEventLog) + AppendToEventLog(String("StorageController.") + this->get_Name(), + Format("Fully charged: %-.6g kWh of rated %-.6g.", ActualkWh, TotalRatingkWh), ActorID); + } + } + if(StorekWChanged) // Only push onto controlqueue If there has been a change + PushTimeOntoControlQueue(STORE_CHARGING, ActorID); + /*Else just continue*/ + } +} + +/*--------------------------------------------------------------------------*/ + +void TStorageControllerObj::sample(int ActorID) +{ + ChargingAllowed = false; +// UpdateFleetState; +/* + Check discharge mode first. Then if not discharging, we can check for charging +*/ + Wait4Step = false; // Initializes the variable for the new control step + switch(DischargeMode) + { + case MODEFOLLOW: + { + DoTimeMode(1, ActorID); + DoLoadFollowMode(ActorID); + } + break; + case MODELOADSHAPE: + DoLoadShapeMode(ActorID); + break; + case MODESUPPORT: + DoLoadFollowMode(ActorID); + break; + case MODETIME: + DoTimeMode(1, ActorID); + break; + case MODEPEAKSHAVE: + DoLoadFollowMode(ActorID); + break; + case CURRENTPEAKSHAVE: + DoLoadFollowMode(ActorID); + break; + case MODESCHEDULE: + DoScheduleMode(ActorID); + break; + default: + DoSimpleMsg(Format("Invalid DisCharging Mode: %d", DischargeMode), 14408); + break; + } + if(ChargingAllowed) + switch(ChargeMode) + { + case MODELOADSHAPE: + ; + break; // DoLoadShapeMode; already executed above + case MODETIME: + DoTimeMode(2, ActorID); + break; + case MODEPEAKSHAVELOW: + DoPeakShaveModeLow(ActorID); + break; + case CURRENTPEAKSHAVELOW: + DoPeakShaveModeLow(ActorID); + break; + default: + DoSimpleMsg(Format("Invalid Charging Mode: %d", ChargeMode), 14409); + break; + } +} + + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::CalcDailyMult(double hr) +{ + if(DailyShapeObj != nullptr) + { + LoadShapeMult = DailyShapeObj->GetMult(hr); + } + else + LoadShapeMult = CDoubleOne; // Default to no variation +} + + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + LoadShapeMult = DutyShapeObj->GetMult(hr); + } + else + CalcDailyMult(hr); // Default to Daily Mult If no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::CalcYearlyMult(double hr) +{ + if(YearlyShapeObj != nullptr) + { + LoadShapeMult = YearlyShapeObj->GetMult(hr); + } + else + CalcDailyMult(hr); // Defaults to Daily curve +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::DoLoadShapeMode(int ActorID) +{ + int FleetStateSaved = 0; + bool RateChanged = false; + double NewChargeRate = 0.0; + double NewkWRate = 0.0; + double NewkvarRate = 0.0; + FleetStateSaved = FleetState; + RateChanged = false; + + // Get multiplier + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + switch(with0->Get_SolMode()) + { + case DAILYMODE: + CalcDailyMult(with0->DynaVars.dblHour); + break; // Daily dispatch curve + case YEARLYMODE: + CalcYearlyMult(with0->DynaVars.dblHour); + break; + case LOADDURATION2: + CalcDailyMult(with0->DynaVars.dblHour); + break; + case PEAKDAY: + CalcDailyMult(with0->DynaVars.dblHour); + break; + case DUTYCYCLE: + CalcDutyMult(with0->DynaVars.dblHour); + break; + default: + ; + break; + } + } + if(LoadShapeMult.re < 0.0) + { + ChargingAllowed = true; + NewChargeRate = Abs( LoadShapeMult.re) * 100.0; + SetFleetDesiredState(STORE_CHARGING); + if(NewChargeRate != pctChargeRate) + { + RateChanged = true; + pctChargeRate = NewChargeRate; + SetFleetChargeRate(); + SetFleetToCharge(); + } + } + else + { + if(LoadShapeMult.re == 0.0) + SetFleetToIdle(); + else + // Set fleet to discharging at a rate + { + NewkWRate = LoadShapeMult.re * 100.0; +// NewkvarRate := LoadShapeMult.im * 100.0; + SetFleetDesiredState(STORE_DISCHARGING); + +// If (NewkWRate <> pctkWRate) or (NewkvarRate <> pctkvarRate) then + if(NewkWRate != pctKWRate) + // only set rate if it has changed. otherwise the debugtrace report will not report kWOut correctly. + { + RateChanged = true; + pctKWRate = NewkWRate; +// pctkvarRate := NewkvarRate; + SetFleetkWRate(pctKWRate); +// SetFleetkvarRate(pctkvarRate); + SetFleetToDisCharge(); + ActiveCircuit[ActorID]->Solution->LoadsNeedUpdating = true; // Force recalc of power parms + } + } + + /*Force a new power flow solution if fleet state has changed*/ + } + if((FleetState != FleetStateSaved) || RateChanged) + PushTimeOntoControlQueue(0, ActorID); +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetAllFleetValues() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TStorageObj(FleetPointerList.Get(i)) do */ + { + auto with0 = ((TStorageObj*) FleetPointerList->Get(i)); + with0->Set_pctkWIn(pctChargeRate); +// Fpctkvarout := pctkvarRate; CR + with0->Set_pctkWOut(pctKWRate); + with0->pctReserve = pctFleetReserve; + } + } +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetChargeRate() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->Set_pctkWIn(pctChargeRate); + } +} + +//---------------------------------------------------------------------------- +//PROCEDURE TStorageControllerObj.SetFleetkvarRate; +//VAR +// i :Integer; +//Begin +// {For side effects see pctkvarout property of Storage element} +//// For i := 1 to FleetPointerList->get_myNumList() Do +//// TStorageObj(FleetPointerList.Get(i)).pctkvarout := pctkvarRate; +//End; + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetkWRate(double pctkw) +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->Set_pctkWOut(pctkw); + } +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetToCharge() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->Set_StorageState(STORE_CHARGING); + } + FleetState = STORE_CHARGING; +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetToDisCharge() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->Set_StorageState(STORE_DISCHARGING); + } + FleetState = STORE_DISCHARGING; +} + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetToIdle() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TStorageObj(FleetPointerList.Get(i)) do */ + { + auto with0 = ((TStorageObj*) FleetPointerList->Get(i)); + with0->Set_StorageState(STORE_IDLING); +// PresentkW := 0.0; + with0->Set_kW(0.0); + } + } + FleetState = STORE_IDLING; +} + +//----------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetDesiredState(int State) +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->Set_StateDesired(State); + } +} + +//----------------------------------------------------------------------------- +// +//procedure TStorageControllerObj.Set_PFBand(const Value: Double); +//begin +// FPFBand := Value; +// HalfPFBand := FPFBand / 2.0; +//end; + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::SetFleetToExternal() +{ + int i = 0; + int stop = 0; + for(stop = FleetPointerList->get_myNumList(), i = 1; i <= stop; i++) + { + ((TStorageObj*) FleetPointerList->Get(i))->DispatchMode = STORE_EXTERNALMODE; + } +} + +//---------------------------------------------------------------------------- +/* + PROCEDURE TStorageControllerObj.SetPctReserve; + VAR + i :Integer; + Begin + For i := 1 to FleetPointerList->get_myNumList() Do + TStorageObj(FleetPointerList.Get(i)).pctReserve := pctFleetReserve; + End; +*/ + + +//---------------------------------------------------------------------------- + +int TStorageControllerObj::InterpretMode(int Opt, const String s) +{ + int result = 0; + result = -1; // Unknown: error + switch(Opt) + { + case propMODEDISCHARGE: + switch(LowerCase(s)[0]) + { + case L'f': + result = MODEFOLLOW; + break; + case L'l': + result = MODELOADSHAPE; + break; + case L'p': + result = MODEPEAKSHAVE; + break; + case L's': + if(LowerCase(s)[1] == L'c') + result = MODESCHEDULE; + else + result = MODESUPPORT; + break; + case L't': + result = MODETIME; + break; + case L'i': + result = CURRENTPEAKSHAVE; + break; + default: + DoSimpleMsg(String("Discharge Mode \"") + s + "\" not recognized.", 14402); + break; + } + break; + case propMODECHARGE: + switch(LowerCase(s)[0]) + { + case L'l': + // 'f': Result := MODEFOLLOW; + result = MODELOADSHAPE; + break; + // 's': Result := MODESUPPORT; + case L't': + result = MODETIME; + break; + case L'p': + result = MODEPEAKSHAVELOW; + break; + case L'i': + result = CURRENTPEAKSHAVELOW; + break; + default: + DoSimpleMsg(String("Charge Mode \"") + s + "\" not recognized.", 14402); + break; + } + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +bool TStorageControllerObj::MakeFleetList() +{ + bool result = false; + TStorageObj* StorageObj = nullptr; + int i = 0; + int stop = 0; + result = false; + if(FElementListSpecified) // Name list is defined - Use it + { + int stop = 0; + FleetPointerList->Clear(); + for(stop = FleetSize, i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) StorageClass[ActiveActor]->Find( FStorageNameList[i - 1] ); + if(ASSIGNED(StorageObj)) + { + if( ( (TDSSCktElement*) StorageObj )->Get_Enabled()) + FleetPointerList->Set_New(StorageObj); + } + else + { + DoSimpleMsg(String("Error: Storage Element \"") + FStorageNameList[i - 1] + + "\" not found.", 14403); + return result; + } + } + } + else + + + /*Search through the entire circuit for enabled Storage Elements and add them to the list*/ + { + int stop = 0; + FStorageNameList.clear(); + FleetPointerList->Clear(); + for(stop = StorageClass[ActiveActor]->Get_ElementCount(), i = 1; i <= stop; i++) + { + StorageObj = (TStorageObj*) StorageClass[ActiveActor]->ElementList.Get(i); + // Look for a storage element not already assigned + if( StorageObj->Get_Enabled() && (StorageObj->DispatchMode != STORE_EXTERNALMODE)) + { + FStorageNameList.push_back( StorageObj->get_Name()); // Add to list of names + FleetPointerList->Set_New(StorageObj); + } + } + + /*Allocate uniform weights*/ + FleetSize = FleetPointerList->get_myNumList(); + FWeights = (pDoubleArray) realloc(FWeights, sizeof(double) * FleetSize); + for(stop = FleetSize, i = 1; i <= stop; i++) + { + (FWeights)[i - 1] = 1.0; + } + } + + // Add up total weights + TotalWeight = 0.0; + for(stop = FleetSize, i = 1; i <= stop; i++) + { + TotalWeight = TotalWeight + (FWeights)[i - 1]; + } + if(FleetPointerList->get_myNumList() > 0) + result = true; + FleetListChanged = false; + return result; +} + + + +//---------------------------------------------------------------------------- + +void TStorageControllerObj::Reset(int ActorID) +{ + + // inherited; + SetFleetToIdle(); + + // do we want to set fleet to 100% charged storage? +} + + + +//---------------------------------------------------------------------------- + +String TStorageControllerObj::ReturnElementsList() +{ + String result; + int i = 0; + int stop = 0; + if(FleetSize == 0) + { + result = ""; + return result; + } + result = String("[") + FStorageNameList[0]; + for(stop = FleetSize - 1, i = 1; i <= stop; i++) + { + result = result + ", " + FStorageNameList[i]; + } + result = result + "]"; // terminate the array + return result; +} + +//---------------------------------------------------------------------------- + +String TStorageControllerObj::ReturnSeasonTarget(int THigh) +{ + String result; + int i = 0; + int stop = 0; + if(Seasons == 1) + { + result = ""; + return result; + } + result = "["; + for(stop = (Seasons - 1), i = 0; i <= stop; i++) + { + if(THigh == 1) + result = result + Format("%.6g", SeasonTargets[i]) + ", "; + else + result = result + Format("%.6g", SeasonTargetsLow[i]) + ", "; + } + result = result + "]"; // terminate the array + return result; +} + + +//---------------------------------------------------------------------------- + +String TStorageControllerObj::ReturnWeightsList() +{ + String result; + if(FleetSize == 0) + { + result = ""; + return result; + } + result = GetDSSArray_Real(FleetSize, FWeights); + return result; +} + +//---------------------------------------------------------------------------- + +// Get power to control based on active power + +void TStorageControllerObj::GetControlPower(complex& ControlPower, int ActorID) +{ + int i = 0; + int ControlPowerPhase = 0; + double TempPower = 0.0; + if(get_FMonitoredElement()->Get_NPhases() == 1) + { + ControlPower = get_FMonitoredElement()->Get_Power(ElementTerminal, ActorID); // just take the total power (works also for 1ph elements with 2 conductors) + } + else + { + get_FMonitoredElement()->GetPhasePower(&(cBuffer[0]), ActorID); + switch(FMonPhase) + { + case AVG: // Get avg of all phases + { + int stop = 0; + ControlPower = cmplx(0.0, 0.0); + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + ControlPower = cadd(ControlPower, (cBuffer)[i - 1]); + } + } + break; // Get abs max of all phases + case MAXPHASE: + { + int stop = 0; + ControlPower = cmplx(0.0, 0.0); + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + TempPower = Abs( (cBuffer)[i - 1].re); + if(TempPower > Abs( ControlPower.re)) + ControlPower = (cBuffer)[i - 1]; + ControlPowerPhase = i; + } + // Compute equivalent total power of all phases assuming equal to max power in all phases + ControlPower = cmulreal(ControlPower, (double) Fnphases); + } + break; // Get abs min of all phases + case MINPHASE: + { + int stop = 0; + ControlPower = cmplx(1.0e50, 1.0e50); + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + TempPower = Abs( (cBuffer)[i - 1].re); + if(TempPower < Abs( ControlPower.re)) + ControlPower = (cBuffer)[i - 1]; + ControlPowerPhase = i; + } + // Compute equivalent total power of all phases assuming equal to min power in all phases + ControlPower = cmulreal(ControlPower, (double) Fnphases); // sign according to phase with min abs value + } + break; + // Compute equivalent total power of all phases assuming equal to power in selected phases + default: + ControlPower = cmulreal((cBuffer)[FMonPhase - 1], (double) Fnphases); // monitored phase only + break; + } + } + + /*If this is a positive sequence circuit (Fnphases=1), + then we need to multiply by 3 to get the 3-phase power*/ + if(ActiveCircuit[ActorID]->PositiveSequence) + ControlPower = cmulreal(ControlPower, 3.0); +} + +//---------------------------------------------------------------------------- + +// Get current to control + +void TStorageControllerObj::GetControlCurrent(double& ControlCurrent) +{ + int i = 0; + switch(FMonPhase) + { + case AVG: + { + int stop = 0; + ControlCurrent = 0.0; // Get avg of all phases + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + ControlCurrent = ControlCurrent + cabs(cBuffer[i - 1]); + } + ControlCurrent = ControlCurrent / Fnphases; + } + break; + case MAXPHASE: + { + int stop = 0; + ControlCurrent = 0.0; // Get max of all phases + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + ControlCurrent = max(ControlCurrent, cabs(cBuffer[i - 1])); + } + ControlCurrent = ControlCurrent; + } + break; + case MINPHASE: + { + int stop = 0; + ControlCurrent = 1.0e50; // Get min of all phases + for(stop = (get_FMonitoredElement()->Get_NConds() + CondOffset), i = (1 + CondOffset); i <= stop; i++) + { + ControlCurrent = min(ControlCurrent, cabs(cBuffer[i - 1])); + } + ControlCurrent = ControlCurrent; + } + break; + /*Just use one phase because that's what most controls do.*/ + default: + ControlCurrent = cabs(cBuffer[FMonPhase - 1]); // monitored phase only + break; + } +} + + +/*--------------------------------------------------------------------------*/ + + +void StorageController_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class StorageController_unit + { + public: + StorageController_unit() + { + //AssertSystemInitialization(); + StorageController_initialization(); + } + }; + StorageController_unit _StorageController_unit; + +} // namespace StorageController + + + + + diff --git a/OpenDSSC/Controls/StorageController.h b/OpenDSSC/Controls/StorageController.h new file mode 100644 index 0000000..9d258ac --- /dev/null +++ b/OpenDSSC/Controls/StorageController.h @@ -0,0 +1,211 @@ +#ifndef StorageControllerH +#define StorageControllerH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "LoadShape.h" +#include "d2c_structures.h" + +namespace StorageController +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + A StorageController is a control element that is connected to a terminal of another + circuit element and sends dispatch signals to a fleet of energy storage elements it controls + + A StorageController is defined by a New command: + + New StorageController.Name=myname Element=devclass.name terminal=[ 1|2|...] Elementlist = (elem1 elem2 ...) + + or ... ElementList = [File=filename] where storage class elements are listed one to a line + If omitted, all storage elements found in the active circuit are included by default and controlled as a fleet. + + Added new control mode for charging 12/19/2018 + Proposed by Valentin Rigoni + +*/ +const int AVG = -1; +const int MAXPHASE = -2; +const int MINPHASE = -3; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TStorageController : public ControlClass::TControlClass +{ + friend class TStorageControllerObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String StorageController2Name); +public: + TStorageController(); + virtual ~TStorageController(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TStorageControllerObj : public ControlElem::TControlElem +{ + friend class TStorageController; +public: + typedef ControlElem::TControlElem inherited; +private: +// FPFTarget, // Range on this is 0..2 where 1..2 is leading + +// HalfPFBand, +// FPFBand, + +// pctkvarRate, + double FkWTarget; + double FkWTargetLow; + double FkWThreshold; + double FpctkWBand; + double FkWBand; + double FpctkWBandLow; + double FkWBandLow; + double HalfkWBand; + double HalfkWBandLow; + double TotalWeight; + double UpRamptime; + double FlatTime; + double DnrampTime; + double UpPlusFlat; + double UpPlusFlatPlusDn; + double DischargeTriggerTime; + double ChargeTriggerTime; + double pctKWRate; + double pctChargeRate; + double LastpctDischargeRate; + double TotalkWCapacity; + double TotalkWhCapacity; + double pctFleetReserve; + double ResetLevel; + double kWNeeded; + double DispFactor; // for slower convergence + TStringList FStorageNameList; + PointerList::TPointerList* FleetPointerList; + Arraydef::TRatingsArray SeasonTargets; + Arraydef::TRatingsArray SeasonTargetsLow; + Arraydef::pDoubleArray FWeights; + std::vector cBuffer; // Complex Array buffer + +// DispatchVars, + bool FleetListChanged; + bool ChargingAllowed; + bool DischargeTriggeredByTime; + bool DischargeInhibited; + bool OutOfOomph; + bool FElementListSpecified; + bool Wait4Step; + bool FkWBandSpecified; // true if kWBand specified as an absolute value (for use in Follow Discharge Mode to update the target) + int Seasons; + int FleetSize; + int FleetState; + int DischargeMode; + int InhibitHrs; + int ChargeMode; + int FMonPhase; + int CondOffset; + String YearlyShape; // ='fixed' means no variation on all the time + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this Storage element + String DailyShape; // Daily (24 HR) Storage element shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily Storage element Shape for this load + String DutyShape; // Duty cycle load shape for changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this Storage element + Ucomplex::complex LoadShapeMult; + + // PROCEDURE SetPctReserve; + void SetAllFleetValues(); + void SetFleetkWRate(double pctkw); +// PROCEDURE SetFleetkvarRate(pctkvar:Double); + void SetFleetChargeRate(); + void SetFleetToCharge(); + void SetFleetToDisCharge(); + void SetFleetToIdle(); + void SetFleetToExternal(); + void SetFleetDesiredState(int State); + int InterpretMode(int Opt, const String s); + String GetModeString(int Opt, int Mode); + String GetkWTotal(double& Sum); + String GetkWhTotal(double& Sum); + String GetkWhActual(); + String GetkWActual(); + void CalcYearlyMult(double hr); + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); + String ReturnSeasonTarget(int THigh); + String ReturnElementsList(); + String ReturnWeightsList(); + bool MakeFleetList(); + void DoLoadFollowMode(int ActorID); + void DoLoadShapeMode(int ActorID); + void DoTimeMode(int Opt, int ActorID); + void DoScheduleMode(int ActorID); + void DoPeakShaveModeLow(int ActorID); + void PushTimeOntoControlQueue(int Code, int ActorID); + double NormalizeToTOD(int h, double Sec); + void GetControlPower(Ucomplex::complex& ControlPower, int ActorID); + void GetControlCurrent(double& ControlCurrent); +// procedure Set_PFBand(const Value: Double); + double Get_FleetkW(); + double Get_FleetkWh(); + double Get_FleetkWhRating(); + double Get_FleetReservekWh(); + double Get_DynamicTarget(int THigh, int ActorID); +public: + TStorageControllerObj(DSSClass::TDSSClass* ParClass, const String StorageController2Name); + virtual ~TStorageControllerObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a StorageController + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + +// Property PFBand :Double Read FPFBand Write Set_PFBand; + TStorageControllerObj(DSSClass::TDSSClass* ParClass); + TStorageControllerObj(String ClassName); + TStorageControllerObj(); +}; +extern TStorageControllerObj* ActiveStorageController2Obj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace StorageController + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace StorageController; +#endif + +#endif // StorageControllerH + + + + + diff --git a/OpenDSSC/Controls/SwtControl.cpp b/OpenDSSC/Controls/SwtControl.cpp new file mode 100644 index 0000000..3c0bfd1 --- /dev/null +++ b/OpenDSSC/Controls/SwtControl.cpp @@ -0,0 +1,633 @@ + +#pragma hdrstop + +#include "SwtControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Utilities.h" +#include "Solution.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace Solution; +using namespace System; +using namespace Ucomplex; +using namespace Utilities; + +namespace SwtControl +{ + +TSwtControlObj::TSwtControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TSwtControlObj::TSwtControlObj(String ClassName) : inherited(ClassName) {} +TSwtControlObj::TSwtControlObj() {} + + +TSwtControlObj* ActiveSwtControlObj = nullptr; +const int NumPropsThisClass = 8; // Creates superstructure for all SwtControl objects + +TSwtControl::TSwtControl() +{ + ; + Class_Name = "SwtControl"; + DSSClassType = DSSClassType + SWT_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//---------------------------------------------------------------------------------------- + +TSwtControl::~TSwtControl() +{ + // inherited::Destroy(); +} + + +void TSwtControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + PropertyName[1 - 1] = "SwitchedObj"; + PropertyName[2 - 1] = "SwitchedTerm"; + PropertyName[3 - 1] = "Action"; + PropertyName[4 - 1] = "Lock"; + PropertyName[5 - 1] = "Delay"; + PropertyName[6 - 1] = "Normal"; + PropertyName[7 - 1] = "State"; + PropertyName[8 - 1] = "Reset"; + PropertyHelp[1 - 1] = "Name of circuit element switch that the SwtControl operates. " + "Specify the full object class and name."; + PropertyHelp[2 - 1] = "Terminal number of the controlled element switch. " "1 or 2, typically. Default is 1."; + PropertyHelp[3 - 1] = "{Open | Close} After specified delay time, and if not locked, causes the controlled switch to open or close. "; + PropertyHelp[4 - 1] = "{Yes | No} Delayed action. Sends CTRL_LOCK or CTRL_UNLOCK message to control queue. " + "After delay time, controlled switch is locked in its present open / close state or unlocked. " + "Switch will not respond to either manual (Action) or automatic (COM interface) control or internal OpenDSS Reset when locked."; + PropertyHelp[5 - 1] = "Operating time delay (sec) of the switch. Defaults to 120."; + PropertyHelp[6 - 1] = "{Open | Closed] Normal state of the switch. If not Locked, the switch reverts to this state for reset, change of mode, etc." + " Defaults to first Action or State specified if not specifically declared."; + PropertyHelp[7 - 1] = "{Open | Closed] Present state of the switch. Upon setting, immediately forces state of switch."; + PropertyHelp[8 - 1] = "{Yes | No} If Yes, forces Reset of switch to Normal state and removes Lock independently of any internal " + "reset command for mode change, etc."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +int TSwtControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new SwtControl and add it to SwtControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TSwtControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +int TSwtControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int DevIndex = 0; + + // continue parsing WITH contents of Parser + ActiveSwtControlObj = (TSwtControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveSwtControlObj); + result = 0; + /*# with ActiveSwtControlObj do */ + { + auto with0 = ActiveSwtControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + /*internal SwtControl Property commands*/ + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 382); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->InterpretSwitchAction(Param); + break; + case 4: + with0->set_Flocked(InterpretYesNo(Param)); + break; + case 5: + with0->TimeDelay = Parser[ActorID]->MakeDouble_(); + break; // set the normal state + case 6: + { + with0->InterpretSwitchAction(Param); + with0->set_NormalState(with0->ActionCommand); + } + break; // set the present state + case 7: + { + with0->InterpretSwitchAction(Param); + with0->Set_PresentState(with0->ActionCommand); + } + break; + case 8: + if(InterpretYesNo(Param)) // force a reset + { + with0->set_Flocked(false); + with0->Reset(ActorID); + with0->Set_PropertyValue(8,"n"); + } + break; + // Inherited parameters + default: + ClassEdit(ActiveSwtControlObj, ParamPointer - NumPropsThisClass); + break; + } + + /*supplemental actions*/ + switch(ParamPointer) + { + case 3: + if(with0->get_FNormalState() == CTRL_NONE) + + // Default to first action specified for legacy scripts + with0->set_NormalState(with0->ActionCommand); + break; + case 4: + if(with0->get_FLocked()) + with0->LockCommand = CTRL_LOCK; + else + with0->LockCommand = CTRL_UNLOCK; + break; + case 7: + { + if(with0->get_FNormalState() == CTRL_NONE) + with0->set_NormalState(with0->get_FPresentState()); + DevIndex = GetCktElementIndex(with0->ElementName); // Set Controlled element + if(DevIndex > 0) + { + with0->Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + if(with0->get_FControlledElement() != nullptr) + { + with0->get_FControlledElement()->Set_ActiveTerminal(with0->ElementTerminal); + switch(with0->get_FPresentState()) + { + case CTRL_OPEN: // Force state + with0->get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); + break; + case CTRL_CLOSE: + with0->get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); + break; + default: + ; + break; + } + } + } + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +int TSwtControl::MakeLike(const String SwtControlName) +{ + int result = 0; + TSwtControlObj* OtherSwtControl = nullptr; + int i = 0; + result = 0; + /*See if we can find this SwtControl name in the present collection*/ + OtherSwtControl = ((TSwtControlObj*) Find(SwtControlName)); + if(OtherSwtControl != nullptr) + /*# with ActiveSwtControlObj do */ + { + auto with0 = ActiveSwtControlObj; + int stop = 0; + with0->Set_NPhases(OtherSwtControl->Fnphases); + with0->Set_Nconds(OtherSwtControl->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherSwtControl->ElementName; + with0->ElementTerminal = OtherSwtControl->ElementTerminal; + with0->Set_ControlledElement(OtherSwtControl->get_FControlledElement()); // Pointer to target circuit element + with0->TimeDelay = OtherSwtControl->TimeDelay; + with0->set_Flocked(OtherSwtControl->get_FLocked()); + with0->Set_PresentState(OtherSwtControl->get_FPresentState()); + with0->set_NormalState(OtherSwtControl->get_FNormalState()); + with0->ActionCommand = OtherSwtControl->ActionCommand; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherSwtControl->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in SwtControl MakeLike: \"") + SwtControlName + + "\" Not Found.", 383); + return result; +} + +/*==========================================================================*/ +/* TSwtControlObj */ +/*==========================================================================*/ + +TSwtControlObj::TSwtControlObj(TDSSClass* ParClass, const String SwtControlName) + : inherited(ParClass), + FLocked(false), + Armed(false) +{ + Set_Name(LowerCase(SwtControlName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors in base class + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + Set_PresentState(CTRL_CLOSE); // default to closed + set_NormalState(CTRL_NONE); // default to unspecified; set on first setting action or anything + ActionCommand = get_FPresentState(); + LockCommand = CTRL_NONE; + set_Flocked(false); + Armed = false; + TimeDelay = 120.0; // 2 minutes + InitPropertyValues(0); +} + +TSwtControlObj::~TSwtControlObj() +{ + // inherited::Destroy(); +} + + +void TSwtControlObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + DevIndex = GetCktElementIndex(ElementName); + if(DevIndex > 0) + { + Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + get_FControlledElement()->HasSwtControl = true; // For Reliability calcs +/* + if not Locked then + Case PresentState of + CTRL_OPEN: ControlledElement.Closed[0] := FALSE; + CTRL_CLOSE: ControlledElement.Closed[0] := TRUE; + End; + +*/ + // attach controller bus to the switch bus - no space allocated for monitored variables + SetBus(1, get_FControlledElement()->GetBus(ElementTerminal)); + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("SwtControl: \"") + this->get_Name() + "\"", String("CktElement Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 387); + } +} + +void TSwtControlObj::MakePosSequence(int ActorID) +{ + if(get_FControlledElement() != nullptr) + { + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FControlledElement()->GetBus(ElementTerminal)); + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TSwtControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil +} + +void TSwtControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TSwtControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TSwtControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + EControlAction ctrl_code; + ctrl_code = EControlAction(Code); // change type + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + switch(ctrl_code) + { + case CTRL_LOCK: + set_Flocked(true); + break; + case CTRL_UNLOCK: + set_Flocked(false); + break; + default: + if(!get_FLocked()) + { + if((Code == ( CTRL_OPEN)) && (get_FPresentState() == CTRL_CLOSE)) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, false); // Open all phases of active terminal + Set_PresentState(CTRL_OPEN); + AppendToEventLog(String("SwtControl.") + this->get_Name(), "Opened", ActorID); + } + if((Code == ( CTRL_CLOSE)) && (get_FPresentState() == CTRL_OPEN)) + { + get_FControlledElement()->Set_ConductorClosed(0, ActorID, true); // Close all phases of active terminal + Set_PresentState(CTRL_CLOSE); + AppendToEventLog(String("SwtControl.") + this->get_Name(), "Closed", ActorID); + } + Armed = false; // reset the switch + } + break; + } +} + +void TSwtControlObj::InterpretSwitchAction(const String Action) +{ + if(!get_FLocked()) + { + switch(LowerCase(Action)[0]) + { + case L'o': + ActionCommand = CTRL_OPEN; + break; // default is closed + default: + ActionCommand = CTRL_CLOSE; + break; + } + + /* Changed to delayed action + if ControlledElement <> nil then begin + ControlledElement.ActiveTerminalIdx := ElementTerminal; + Case PresentState of + CTRL_OPEN: ControlledElement.Closed[0] := FALSE; + CTRL_CLOSE: ControlledElement.Closed[0] := TRUE; + End; + End; + */ + } +} + +//------------------------------------------------------------------------------------- + +EControlAction TSwtControlObj::get_FNormalState() +{ + return FNormalState; +} + +//------------------------------------------------------------------------------------- + +EControlAction TSwtControlObj::get_FPresentState() +{ + return FPresentState; +} + +//------------------------------------------------------------------------------------- + +bool TSwtControlObj::get_FLocked() +{ + return FLocked; +} + +//------------------------------------------------------------------------------------- + +EControlAction TSwtControlObj::get_ActionCommand() +{ + return ActionCommand; +} + +//------------------------------------------------------------------------------------- + +void TSwtControlObj::sample(int ActorID) +{ + + +// push on the Lock command if any at the present time delay + if(LockCommand != CTRL_NONE) + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + ActiveCircuit[ActorID]->ControlQueue.Push(with1->DynaVars.intHour, with1->DynaVars.T + TimeDelay, LockCommand, 0, this, ActorID); + LockCommand = CTRL_NONE; // reset the lock command for next time + } + if((ActionCommand != get_FPresentState()) && !Armed) + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with3 = ActiveCircuit[ActorID]->Solution; // we need to operate this switch + ActiveCircuit[ActorID]->ControlQueue.Push(with3->DynaVars.intHour, with3->DynaVars.T + TimeDelay, ActionCommand, 0, this, ActorID); + Armed = true; + } + /*ControlledElement.ActiveTerminalIdx := ElementTerminal; + IF ControlledElement.Closed [0] // Check state of phases of active terminal + THEN PresentState := CTRL_CLOSE + ELSE PresentState := CTRL_OPEN; */ +} + +void TSwtControlObj::set_Flocked(bool Value) +{ + FLocked = Value; +} + +void TSwtControlObj::Set_LastAction(const EControlAction Value) +{ + ActionCommand = Value; +} + +void TSwtControlObj::set_NormalState(const EControlAction Value) +{ + FNormalState = Value; +} + +void TSwtControlObj::Set_PresentState(const EControlAction Value) +{ + FPresentState = Value; +} + +void TSwtControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue((with0->PropertyIdxMap)[i - 1])); } + } + } + if(Complete) + WriteLn(f); +} + +String TSwtControlObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = ElementName; + break; + case 2: + result = Format("%d", ElementTerminal); + break; + case 3: + switch(ActionCommand) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "close"; + break; + } + break; + case 4: + if(get_FLocked()) + result = "Yes"; + else + result = "No"; + break; + case 5: + result = Format("%-.7g", TimeDelay); + break; + case 6: + switch(FNormalState) + { + case CTRL_OPEN: + result = "open"; + break; + /*CTRL_CLOSE:*/ + default: + result = "closed"; + break; + } + break; + case 7: + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + if(get_FControlledElement()->Get_ConductorClosed(0, ActiveActor)) + result = "Closed"; + else + result = "open"; + } + break; + case 8: + result = "n"; + break; // Always no; yes is executed immediately + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TSwtControlObj::Reset(int ActorID) +{ + if(!get_FLocked()) + { + Set_PresentState(get_FNormalState()); + ActionCommand = get_FPresentState(); + Armed = false; + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(FNormalState) + { + case CTRL_OPEN: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, false); + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(0, ActiveActor, true); // Close all phases of active terminal + break; + } + } + } +} + +void TSwtControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,"c"); + Set_PropertyValue(4,"n"); + Set_PropertyValue(5,"120.0"); + Set_PropertyValue(6,"c"); + Set_PropertyValue(7,"c"); + Set_PropertyValue(8,"n"); + inherited::InitPropertyValues(NumPropsThisClass); +} + + + + +} // namespace SwtControl + + + + + diff --git a/OpenDSSC/Controls/SwtControl.h b/OpenDSSC/Controls/SwtControl.h new file mode 100644 index 0000000..b859884 --- /dev/null +++ b/OpenDSSC/Controls/SwtControl.h @@ -0,0 +1,99 @@ +#ifndef SwtControlH +#define SwtControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "ControlActionsDefs.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" + +namespace SwtControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ----------------------------------------------------------*/ + +class TSwtControl : public ControlClass::TControlClass +{ + friend class TSwtControlObj; +public: + typedef ControlClass::TControlClass inherited; +protected: + void DefineProperties(); + virtual int MakeLike(const String SwtControlName); +public: + TSwtControl(); + virtual ~TSwtControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +class TSwtControlObj : public ControlElem::TControlElem +{ + friend class TSwtControl; +public: + typedef ControlElem::TControlElem inherited; +//private: + EControlAction FPresentState; + EControlAction FNormalState; + EControlAction ActionCommand; + EControlAction LockCommand; + bool FLocked; + bool Armed; + void InterpretSwitchAction(const String Action); + void set_NormalState(const EControlAction Value); + void set_Flocked(bool Value); + void Set_LastAction(const EControlAction Value); + void Set_PresentState(const EControlAction Value); +public: + TSwtControlObj(DSSClass::TDSSClass* ParClass, const String SwtControlName); + virtual ~TSwtControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a SwtControl + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + EControlAction get_FNormalState(); + EControlAction get_FPresentState(); + bool get_FLocked(); + EControlAction get_ActionCommand(); + + TSwtControlObj(DSSClass::TDSSClass* ParClass); + TSwtControlObj(String ClassName); + TSwtControlObj(); +}; +extern TSwtControlObj* ActiveSwtControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace SwtControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace SwtControl; +#endif + +#endif // SwtControlH + + + + + diff --git a/OpenDSSC/Controls/UPFCControl.cpp b/OpenDSSC/Controls/UPFCControl.cpp new file mode 100644 index 0000000..ff900e2 --- /dev/null +++ b/OpenDSSC/Controls/UPFCControl.cpp @@ -0,0 +1,468 @@ + +#pragma hdrstop + +#include "UPFCControl.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "UPFC.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace UPFC; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace UPFCControl +{ + +TUPFCControlObj::TUPFCControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TUPFCControlObj::TUPFCControlObj(String ClassName) : inherited(ClassName) {} +TUPFCControlObj::TUPFCControlObj() {} + + +TUPFCControlObj* ActiveUPFCControlObj = nullptr; +const int NumPropsThisClass = 1; + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all UPFCControl objects + +TUPFCControl::TUPFCControl() +{ + ; + Class_Name = "UPFCControl"; + DSSClassType = DSSClassType + UPFC_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TUPFCControl::~TUPFCControl() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TUPFCControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "UPFCList"; + PropertyHelp[1 - 1] = "The list of all the UPFC devices to be controlled by this controller, " + "If left empty, this control will apply for all UPFCs in the model."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TUPFCControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new UPFCControl and add it to UPFCControl class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TUPFCControlObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TUPFCControl::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + + // continue parsing WITH contents of Parser + ActiveUPFCControlObj = (TUPFCControlObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveUPFCControlObj); + result = 0; + /*# with ActiveUPFCControlObj do */ + { + auto with0 = ActiveUPFCControlObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 364); + break; + case 1: + InterpretTStringListArray(Param, with0->FUPFCNameList); + break; + // Inherited parameters + default: + ClassEdit(ActiveUPFCControlObj, ParamPointer - NumPropsThisClass); + break; + } + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + + //RecalcElementData(ActorID); + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TUPFCControl::MakeLike(const String UPFCControlName) +{ + int result = 0; + TUPFCControlObj* OtherUPFCControl = nullptr; + int i = 0; + result = 0; + /*See if we can find this UPFCControl name in the present collection*/ + OtherUPFCControl = ((TUPFCControlObj*) Find(UPFCControlName)); + if(OtherUPFCControl != nullptr) + /*# with ActiveUPFCControlObj do */ + { + auto with0 = ActiveUPFCControlObj; + int stop = 0; + with0->Set_NPhases(OtherUPFCControl->Fnphases); + with0->Set_Nconds(OtherUPFCControl->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherUPFCControl->ElementName; + with0->Set_ControlledElement(OtherUPFCControl->get_FControlledElement()); // Pointer to target circuit element + with0->Set_MonitoredElement(OtherUPFCControl->get_FMonitoredElement()); // Pointer to target circuit element + with0->ElementTerminal = OtherUPFCControl->ElementTerminal; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherUPFCControl->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in UPFCControl MakeLike: \"") + UPFCControlName + + "\" Not Found.", 370); + return result; +} + + + + +/*==========================================================================*/ +/* TUPFCControlObj */ +/*==========================================================================*/ +/*--------------------------------------------------------------------------*/ + +TUPFCControlObj::TUPFCControlObj(TDSSClass* ParClass, const String UPFCControlName) + : inherited(ParClass), + FUPFCNameList(), + FUPFCList(new PointerList::TPointerList(20)), + FListSize(0), + FWeights(nullptr), + TotalWeight(0.0) +{ + Set_Name(LowerCase(UPFCControlName)); + DSSObjType = ParClass->DSSClassType; + TotalWeight = 1.0; + FWeights = nullptr; +} + +TUPFCControlObj::~TUPFCControlObj() +{ + ElementName = ""; + // inherited::Destroy(); +} + +/*--------------------------------------------------------------------------*/ + +PointerList::TPointerList* TUPFCControlObj::get_FUPFCList() +{ + return FUPFCList; +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::set_FUPFCList(PointerList::TPointerList* myPtr) +{ + FUPFCList = myPtr; +} + +/*--------------------------------------------------------------------------*/ + +int TUPFCControlObj::get_FListSize() +{ + return FListSize; +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::set_FListSize(int mySize) +{ + FListSize = mySize; +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; +/*Check for existence of monitored element*/ + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) + { + Set_MonitoredElement((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + if(ElementTerminal > get_FMonitoredElement()->Get_NTerms()) + { + DoErrorMsg(String("UPFCControl: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 371); + } + else + + // Sets name of i-th terminal's connected bus in UPFCControl's buslist + { + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + } + else + DoSimpleMsg(String("Monitored Element in UPFCControl.") + get_Name() + + " does not exist:\"" + + ElementName + + "\"", 372); +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::MakePosSequence(int ActorID) +{ + if(get_FMonitoredElement() != nullptr) + { + Set_NPhases(get_FControlledElement()->Get_NPhases()); + Set_Nconds(Fnphases); + SetBus(1, get_FMonitoredElement()->GetBus(ElementTerminal)); + } + inherited::MakePosSequence(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TUPFCControlObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) +{ + bool Update = false; + int i = 0; + TDSSClass* MyClass = nullptr; + TUPFCObj* myUPFC = nullptr; + if(FListSize > 0) + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + myUPFC = (TUPFCObj*) FUPFCList->Get(i); + myUPFC->UploadCurrents(ActorID); + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TUPFCControlObj::sample(int ActorID) +{ + bool Update = false; + int i = 0; + TDSSClass* MyClass = nullptr; + TUPFCObj* myUPFC = nullptr; + // If list is not define, go make one from all generators in circuit + if(FUPFCList->get_myNumList() == 0) + MakeUPFCList(); + Update = false; + if(FListSize > 0) + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + myUPFC = (TUPFCObj*) FUPFCList->Get(i); + Update = Update || myUPFC->CheckStatus(ActorID); + } + /*Checks if at least one UPFC needs to be updated*/ + if(Update) + { + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + ActiveCircuit[ActorID]->ControlQueue.Push(with1->DynaVars.intHour, with1->DynaVars.T, (EControlAction) 0, 0, this, ActorID); + } + } + } +} + +void TUPFCControlObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"[]"); //'UPFC List'; + inherited::InitPropertyValues(NumPropsThisClass); +} + +bool TUPFCControlObj::MakeUPFCList() +{ + bool result = false; + TDSSClass* MyClass = nullptr; + TUPFCObj* UPFC = nullptr; + int i = 0; + int stop = 0; + result = false; + // Clears everything + FUPFCNameList.clear(); + FUPFCList->Clear(); + MyClass = (TDSSClass*) GetDSSClassPtr("upfc"); + if(FListSize > 0) // Name list is defined - Use it + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + UPFC = (TUPFCObj*) MyClass->Find(String((FUPFCNameList)[i - 1])); + if(ASSIGNED(UPFC) && ( (TDSSCktElement*) UPFC )->Get_Enabled()) + FUPFCList->Set_New((void*) UPFC); + } + } + else + // No list given + + /*Search through the entire circuit for enabled generators and add them to the list*/ + { + int stop = 0; + for(stop = MyClass->Get_ElementCount(), i = 1; i <= stop; i++) + { + UPFC = (TUPFCObj*) MyClass->ElementList.Get(i); + // Checks if it's enabled + if(( (TDSSCktElement*) UPFC )->Get_Enabled()) + FUPFCList->Set_New(UPFC); + } + + /*Allocate uniform weights*/ + FListSize = FUPFCList->get_myNumList(); + FWeights = (pDoubleArray)realloc(FWeights, sizeof(double) * FListSize); + for(stop = FListSize, i = 1; i <= stop; i++) + { + (FWeights)[i - 1] = 1.0; + } + } + + // Add up total weights + TotalWeight = 0.0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + TotalWeight = TotalWeight + (FWeights)[i - 1]; + } + if(FUPFCList->get_myNumList() > 0) + result = true; + return result; +} + +void TUPFCControlObj::Reset(int ActorID) +{ + + // inherited; +} + + + + +} // namespace UPFCControl + + + + + diff --git a/OpenDSSC/Controls/UPFCControl.h b/OpenDSSC/Controls/UPFCControl.h new file mode 100644 index 0000000..db96732 --- /dev/null +++ b/OpenDSSC/Controls/UPFCControl.h @@ -0,0 +1,111 @@ +#ifndef UPFCControlH +#define UPFCControlH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" + +namespace UPFCControl +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + A UPFCControl is a control element that is connected to a terminal of another + circuit element and sends dispatch kW signals to a set of generators it controls + + A UPFCControl is defined by a New command: + + New UPFCControl.Name=myname Element=devclass.name terminal=[ 1|2|...] CapacitorList = (gen1 gen2 ...) + + +*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TUPFCControl : public ControlClass::TControlClass +{ + friend class TUPFCControlObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String UPFCControlName); +public: + TUPFCControl(); + virtual ~TUPFCControl(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TUPFCControlObj : public ControlElem::TControlElem +{ + friend class TUPFCControl; +public: + typedef ControlElem::TControlElem inherited; +//private: + TStringList FUPFCNameList; + PointerList::TPointerList* FUPFCList; + int FListSize; + Arraydef::pDoubleArray FWeights; + double TotalWeight; +public: + TUPFCControlObj(DSSClass::TDSSClass* ParClass, const String UPFCControlName); + virtual ~TUPFCControlObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a UPFCControl + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + bool MakeUPFCList(); + + PointerList::TPointerList* get_FUPFCList(); + void set_FUPFCList(PointerList::TPointerList* myPtr); + + int get_FListSize(); + void set_FListSize(int mySize); + + // Public properties + TUPFCControlObj(DSSClass::TDSSClass* ParClass); + TUPFCControlObj(String ClassName); + TUPFCControlObj(); +}; +extern TUPFCControlObj* ActiveUPFCControlObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace UPFCControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace UPFCControl; +#endif + +#endif // UPFCControlH + + + + + diff --git a/OpenDSSC/Controls/VVControl.cpp b/OpenDSSC/Controls/VVControl.cpp new file mode 100644 index 0000000..916fe4c --- /dev/null +++ b/OpenDSSC/Controls/VVControl.cpp @@ -0,0 +1,910 @@ +#include +#pragma hdrstop + +#include "VVControl.h" +#include "../Parser/ParserDel.h" +#include "../Common/DSSClassDefs.h" +#include "../MyDSSClassDefs.h" +#include "../Common/DSSGlobals.h" +#include "../Common/Circuit.h" +#include "../PCElements/generator.h" +#include +#include "../Shared/Ucmatrix.h" +#include "../Shared/mathutil.h" +#include + +using namespace std; +using namespace d2c_system; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Generator; +using namespace MyDSSClassDefs; +using namespace ParserDel; +using namespace System; +using namespace System::Classes; +using namespace System::Math; +using namespace System::Sysutils; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace utilities; + +namespace VVControl +{ + +TVVControlObj::TVVControlObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TVVControlObj::TVVControlObj(String ClassName) : inherited(ClassName) {} +TVVControlObj::TVVControlObj() {} + + +TVVControlObj* ActiveVVCControlObj = nullptr; +const int NumPropsThisClass = 19; +const int None = 0; +const int CHANGEVARLEVEL = 1; + + /* -------------------------------------------------------------------------- */ // Creates superstructure for all VVCControl objects + +TVVControl::TVVControl() + : XY_CurveClass(GetDSSClassPtr(L"XYCurve")) +{ + ; + Class_Name = "VVControl"; + DSSClassType = DSSClassType + VV_CONTROL; + DefineProperties(); + CommandList = new TCommandList(SLICE((*PropertyName), NumProperties)); + CommandList->set_AbbrevAllowed(true); +} + +/* -------------------------------------------------------------------------- */ + +TVVControl::~TVVControl() +{ + // inherited::Destroy(); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TVVControl::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + (*PropertyName)[1 - 1] = L"Element"; + (*PropertyName)[2 - 1] = L"Terminal"; + (*PropertyName)[3 - 1] = L"vvc_Vmaxpu"; + (*PropertyName)[4 - 1] = L"vvc_Vminpu"; + (*PropertyName)[5 - 1] = L"kva_rating"; + (*PropertyName)[6 - 1] = L"kW_rating"; + (*PropertyName)[7 - 1] = L"kvar_full_output"; + (*PropertyName)[8 - 1] = L"pf"; + (*PropertyName)[9 - 1] = L"delay"; + (*PropertyName)[10 - 1] = L"delayoff"; + (*PropertyName)[11 - 1] = L"kW_ramp_rate"; + (*PropertyName)[12 - 1] = L"kvar_ramp_rate"; + (*PropertyName)[13 - 1] = L"kW_limit"; + (*PropertyName)[14 - 1] = L"kvar_limit"; + (*PropertyName)[15 - 1] = L"GenList"; + (*PropertyName)[16 - 1] = L"Weights"; + (*PropertyName)[17 - 1] = L"NumPts"; + (*PropertyName)[18 - 1] = L"VVC_curve"; + (*PropertyName)[19 - 1] = L"deltaQ_factor"; + (*PropertyHelp)[1 - 1] = L"Full object name of the circuit element, typically a line or transformer, " + L"which the control is monitoring. There is no default; must be specified."; + (*PropertyHelp)[2 - 1] = L"Number of the terminal of the circuit element to which the VVCControl control is connected. " + L"1 or 2, typically. Default is 1. Make sure you have the direction on the power matching the sign of kWLimit."; + (*PropertyHelp)[3 - 1] = L"Default = 0.90. Minimum per unit voltage for which the vvccurve volts property is assumed to apply. " + L"Below this value, the var output is zero (i.e., the unit will not operate)."; + (*PropertyHelp)[4 - 1] = L"Default = 1.10. Maximum per unit voltage for which the vvccurve volts property is assumed to apply. " + L"Above this value, the var output is zero (i.e., the unit will not operate)."; + (*PropertyHelp)[5 - 1] = L"Default = 1.2 times the kW_rating of the unit. Maximum steady-state apparent power output."; + (*PropertyHelp)[6 - 1] = L"Default = 4.0. Maximum steady-state active power output of the unit under control."; + (*PropertyHelp)[7 - 1] = L"Max kvar to be delivered through the element. Corresponds to the +/- 1.0 per-unit var value in the volt/var curve."; + (*PropertyHelp)[8 - 1] = L"Displacement power factor set-point of the inverter (modeled as a generator). PF set-point will not cause delivered kvar to exceed the maximum kvar limit."; + (*PropertyHelp)[9 - 1] = L"Delay in seconds for switching ON the inverter (modeled as a generator). Default is 0.0 s"; + (*PropertyHelp)[10 - 1] = L"Delay in seconds for switching OFF the inverter (modeled as a generator). Default is 0.0 s"; + (*PropertyHelp)[11 - 1] = L"Ramp rate in kW per second for turning ON and OFF the inverter. Ramps the kW from 0 or other full to kW_rating over x seconds. Default is -1 denoting immediate switch ON/OFF, after optional delay"; + (*PropertyHelp)[12 - 1] = L"Ramp rate in kvar per second for turning ON and OFF the inverter. Ramps the kW from 0 or other full to kvar_limit over x seconds. Default is -1 denoting immediate switch ON/OFF, after optional delay"; + (*PropertyHelp)[13 - 1] = L"kW Limit for the monitored element. The generators are dispatched to hold the active power to attempt to achieve this value."; + (*PropertyHelp)[14 - 1] = L"kvar Limit for the monitored element. The generators are dispatched to hold the reactive power to attempt to achieve this value."; + (*PropertyHelp)[15 - 1] = L"Array list of generators to be dispatched. If not specified, all generators in the circuit are assumed dispatchable."; + (*PropertyHelp)[16 - 1] = L"Array of proportional weights corresponding to each generator in the GenList. The needed kW to get back to center band is dispatched to each generator according to these weights. Default is to set all weights to 1.0."; + (*PropertyHelp)[17 - 1] = L"Number of points expected to be in the volt curve or the var curve (XYcurve object)."; + (*PropertyHelp)[18 - 1] = L"Name of the volt-var curve that has been previously defined using the XYcurve object."; + (*PropertyHelp)[19 - 1] = L"The maximum change in per-unit from the prior var output to the var output indicated by the volt-var curve (XYcurve object)."; + ActiveProperty = NumPropsThisClass; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/* -------------------------------------------------------------------------- */ + +TXYcurveObj* TVVControl::GetVVCCurve(const String CurveName) +{ + TXYcurveObj* result = nullptr; + result = ((TXYcurveObj*) XY_CurveClass->Find(CurveName)); + if(result == nullptr) + DoSimpleMsg(String(L"XY Curve object: \"") + CurveName + L"\" not found.", 380); + return result; +} + +/* -------------------------------------------------------------------------- */ + +/* -------------------------------------------------------------------------- */ + +int TVVControl::NewObject(const String ObjName) +{ + int result = 0; + // Make a new VVCControl and add it to VVCControl class list + /*# with ActiveCircuit do */ + { + auto& with0 = ActiveCircuit; + ActiveCktElement = new TVVControlObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/* -------------------------------------------------------------------------- */ + +int TVVControl::Edit() +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + + // continue parsing WITH contents of Parser + ActiveVVCControlObj = &ElementList.Active; + ActiveCircuit.ActiveCktElement = ActiveVVCControlObj; + result = 0; + /*# with ActiveVVCControlObj do */ + { + auto with0 = ActiveVVCControlObj; + ParamPointer = 0; + ParamName = Parser.NextParam; + Param = Parser.StrValue; + while(Param.Length() > 0) + { + if(ParamName.Length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList->Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->PropertyValue[ParamPointer] = Param; + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String(L"Unknown parameter \"") + ParamName + + L"\" for Object \"" + + Class_Name + + L"." + + with0->Name + + L"\"", 364); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->ElementTerminal = Parser.IntValue; + break; + case 3: + with0->Fvvc_Vmaxpu = Parser.DblValue; + break; + case 4: + with0->Fvvc_Vminpu = Parser.DblValue; + break; + case 5: + with0->Fkva_rating = Parser.DblValue; + break; + case 6: + with0->FkW_rating = Parser.DblValue; + break; + case 7: + with0->Fkvar_fulloutput = Parser.DblValue; + break; + case 8: + with0->Fpf = Parser.DblValue; + break; + case 9: + with0->FDelay = Parser.DblValue; + break; + case 10: + with0->Fdelayoff = Parser.DblValue; + break; + case 11: + with0->FkW_ramp_rate = Parser.DblValue; + break; + case 12: + with0->Fkvar_ramp_rate = Parser.DblValue; + break; + case 13: + with0->FkW_limit = Parser.DblValue; + break; + case 14: + with0->Fkvar_limit = Parser.DblValue; + break; + case 15: + InterpretTStringListArray(Param, with0->FGeneratorNameList); + break; + case 16: + { + with0->FListSize = with0->FGeneratorNameList->Count; + if(with0->FListSize > 0) + { + with0->FWeights = (pDoubleArray) ReallocMemory(with0->FWeights, sizeof((*with0->FWeights)[1 - 1]) * with0->FListSize); + InterpretDblArray(Param, with0->FListSize, with0->FWeights); + } + } + break; + case 17: + with0->Fvvc_curve_size = Parser.IntValue; + break; + case 18: + with0->Fvvc_curve = GetVVCCurve(Param); + break; + case 19: + with0->FdeltaQ_factor = Parser.DblValue; + break; + // Inherited parameters + default: + ClassEdit(ActiveVVCControlObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 15: // re-alloc based on + { + int stop = 0; + with0->FGenPointerList.Clear; // clear this for resetting on first sample + with0->FListSize = with0->FGeneratorNameList->Count; + with0->FWeights = (pDoubleArray) ReallocMemory(with0->FWeights, sizeof((*with0->FWeights)[1 - 1]) * with0->FListSize); + for(stop = with0->FListSize, i = 1; i <= stop; i++) + { + (*with0->FWeights)[i - 1] = 1.0; + } + } + break; // re-set the number vvc_curve_size property to the number + // of points in the curve + case 18: + { + if(with0->Fvvc_curve->NumPoints != with0->Fvvc_curve_size) + with0->Fvvc_curve_size = with0->Fvvc_curve->NumPoints; + } + break; + default: + ; + break; + } + ParamName = Parser.NextParam; + Param = Parser.StrValue; + } + with0->RecalcElementData(); + } + return result; +} + +/* -------------------------------------------------------------------------- */ + +int TVVControl::MakeLike(const String VVCControlName) +{ + int result = 0; + TVVControlObj* OtherVVCControl = nullptr; + int i = 0; + result = 0; + /* See if we can find this VVCControl name in the present collection */ + OtherVVCControl = ((TVVControlObj*) Find(VVCControlName)); + if(OtherVVCControl != nullptr) + /*# with ActiveVVCControlObj do */ + { + auto with0 = ActiveVVCControlObj; + int stop = 0; + with0->NPhases = OtherVVCControl->Fnphases; + with0->NConds = OtherVVCControl->Fnconds; // Force Reallocation of terminal stuff + with0->ElementName = OtherVVCControl->ElementName; + with0->ControlledElement = OtherVVCControl->ControlledElement; + // Pointer to target circuit element + with0->MonitoredElement = OtherVVCControl->MonitoredElement; + // Pointer to monitored circuit element + with0->ElementTerminal = OtherVVCControl->ElementTerminal; + with0->CondOffset = OtherVVCControl->CondOffset; + with0->DeltaVTolerance = OtherVVCControl->DeltaVTolerance; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->PropertyValue[i] = OtherVVCControl->PropertyValue[i]; + } + } + else + DoSimpleMsg(String(L"Error in VVCControl MakeLike: \"") + VVCControlName + + L"\" Not Found.", 370); + return result; +} + +/* ========================================================================== */ +/* TVVControlObj */ +/* ========================================================================== */ + +/* -------------------------------------------------------------------------- */ + +TVVControlObj::TVVControlObj(TDSSClass* ParClass, const String VVCControlName) + : inherited(ParClass), + Fvvc_Vmaxpu(1.1), + Fvvc_Vminpu(0.9), + Fkva_rating(7.0), + FkW_rating(5.83), + Fkvar_fulloutput(3.86), + Fpf(0.83), + FDelay(0.0), + Fdelayoff(0.0), + FkW_ramp_rate(-1.0), + Fkvar_ramp_rate(-1.0), + FkW_limit(10000), + Fkvar_limit(FkW_limit / 2.0), + DeltaVTolerance(0.00001), + TotalWeight(1.0), + QOldDeliver(0.0), + Qdeliver(0.0), + QNew(0.0), + VavgpuPrior(0.0), + Vavgpu(0.0), + presentHour(0.0), + ControlActionHandle(0), + FListSize(0), + FGeneratorNameList(nullptr), + FGenPointerList(nullptr), + FWeights(nullptr), + Fvvc_curve_size(0), + Fvvc_curve(nullptr), + FPendingChange(0), + FdeltaQ_factor(0.0), + MonitoredElement(nullptr), + cBuffer(nullptr), + CondOffset(0) +{ + Name = LowerCase(VVCControlName); + DSSObjType = ParClass->DSSClassType; + NPhases = 1; // Directly set conds and phases + Fnconds = 3; + NTerms = 1; // this forces allocation of terminals and conductors + // in base class + ElementName = L""; + ControlledElement = nullptr; + ElementTerminal = 1; + MonitoredElement = nullptr; + FGeneratorNameList = new TStringList(); + FWeights = nullptr; + FGenPointerList = new PointerList::TPointerList(20); + // Default size and increment + FListSize = 0; + FdeltaQ_factor = 0.1; + Qdeliver = 1.0; + QOldDeliver = 0.0; + QNew = 0.0; + VavgpuPrior = 0.0; + Vavgpu = 0.0; + presentHour = -1.0; + InitPropertyValues(0); + Fvvc_curve = nullptr; + Fvvc_curve_size = 0; + PendingChange = None; +} + +TVVControlObj::~TVVControlObj() +{ + ElementName = L""; + // inherited::Destroy(); +} + + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::RecalcElementData() +{ + int DevIndex = 0; + + /* Check for existence of monitored element */ + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) + { + MonitoredElement = ActiveCircuit.CktElements.Get(DevIndex); + if(ElementTerminal > MonitoredElement->NTerms) + { + DoErrorMsg(String(L"VVCControl: \"") + Name + L"\"", String(L"Terminal no. \"") + Format(L"%-d", ARRAYOFCONST((ElementTerminal))) + + L"\" does not exist.", L"Re-specify terminal no.", 371); + } + else + + // Sets name of i-th terminal's connected bus in VVCControl's buslist + { + SetBus(1, MonitoredElement->GetBus(ElementTerminal)); + } + cBuffer = (pComplexArray) ReallocMemory(cBuffer, sizeof((*cBuffer)[1 - 1]) * MonitoredElement->Yorder); + CondOffset = (ElementTerminal - 1) * MonitoredElement->NConds; + // for speedy sampling + } + else + DoSimpleMsg(String(L"Monitored Element in VVCControl.") + Name + + L" does not exist:\"" + + ElementName + + L"\"", 372); + if(FGenPointerList.get_myNumList() == 0) + MakeGenList(); + DevIndex = GetCktElementIndex(String(L"generator.") + FGeneratorNameList->Strings[0]); + // Global function + if(DevIndex > 0) + // right now we only support one controlled element (generator) per vvcontrol + // Controlled element must already exist + { + ControlledElement = ActiveCircuit.CktElements.Get(DevIndex); + ControlledElement->ActiveTerminalIdx = 1; // Make the 1 st terminal active + // Get control synched up with capacitor + } + else + { + ControlledElement = nullptr; // element not found + DoErrorMsg(String(L"VVControl: \"") + this->Name + L"\"", String(L"Controlled Element \"") + FGeneratorNameList->Strings[0] + + L"\" Not Found.", L" Element must be defined previously.", 361); + } +} + +void TVVControlObj::MakePosSequence() +{ + if(ControlledElement != nullptr) + { + Enabled = ControlledElement->Enabled; + NPhases = ControlledElement->NPhases; + Set_Nconds(Fnphases); + } + if(MonitoredElement != nullptr) + { + SetBus(1, MonitoredElement->GetBus(ElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + // ReAllocMem(cBuffer, SizeOF(cBuffer^[1]) * MonitoredElement.Yorder ); + // CondOffset := (ElementTerminal-1) * MonitoredElement.NConds; // for speedy sampling + } + inherited::MakePosSequence(); +} + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::CalcYPrim() +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::GetCurrents(pComplexArray Curr) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (*Curr)[i - 1] = CZero; + } +} + +void TVVControlObj::GetInjCurrents(pComplexArray Curr) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (*Curr)[i - 1] = CZero; + } +} + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::DumpProperties(d2c_system::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, L"~ "); Write(f, (*with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, PropertyValue[i]); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::DoPendingAction(int Code, int ProxyHdl) +{ + int i = 0; + double DeltaQ = 0.0; + double QHeadRoom = 0.0; + double Qdesiredpu = 0.0; + double QNeeded = 0.0; + double PPresentGenOutput = 0.0; + double QPresentGenOutput = 0.0; + double QMonitoredElement = 0.0; + double Genkvar = 0.0; + complex SMonitoredElement = {}; + complex SPresentGenOutput = {}; + TGeneratorObj* Gen = nullptr; + Genkvar = 0.0; + // we need P and/or we need Q + if(PendingChange == CHANGEVARLEVEL) + { + SMonitoredElement = MonitoredElement->Get_Power(ElementTerminal, ActiveActor); // s is in va + // PMonitoredElement := SMonitoredElement.re; + QMonitoredElement = SMonitoredElement.im; + + // PNeeded := FkW_limit*1000 - PMonitoredElement; + QNeeded = Fkvar_limit * 1000 - QMonitoredElement; + // If the generator list is not defined, go make one + if(FGenPointerList.get_myNumList() == 0) + MakeGenList(); + ControlledElement->ActiveTerminalIdx = 1; // Set active terminal of generator to terminal 1 + if(QNeeded != 0.0) + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + SPresentGenOutput = ControlledElement->Get_Power(1, ActiveActor); + // s is in va; we want terminal 1 of the generator + PPresentGenOutput = SPresentGenOutput.re; + QPresentGenOutput = SPresentGenOutput.im; + + // q desired pu is the desired output based on the avg pu voltage on the + // monitored element + Qdesiredpu = Fvvc_curve->GetYValue(Vavgpu); //Y value = var in pu + + // The var 'head-room' available on the inverter given its rating + // and present kW output + if(Abs( PPresentGenOutput) > Fkva_rating * 1000.0) + { + QHeadRoom = 0.0; + } + else + QHeadRoom = Sqrt(Sqr(Fkva_rating * 1000.0) - Sqr(PPresentGenOutput)); + Qdeliver = Min(Abs( (Fkvar_fulloutput * 1000.0)), Abs( QHeadRoom)); + Qdeliver = Qdeliver * Qdesiredpu; + DeltaQ = Qdeliver - QOldDeliver; + + // only allow a small movement from old delivered (prior gen Q) + // to the desired delivered Q + QNew = QOldDeliver + DeltaQ * FdeltaQ_factor; + if(QNew != QPresentGenOutput) + { + Gen = FGenPointerList.Get(i); + Genkvar = Sign(QNew) * (Min(Abs( (Fkvar_limit * 1000.0)), Abs( QNew))) / 1000.0L; + if(Genkvar != Gen->kvarBase) + { + Gen->Set_Presentkvar(Genkvar); + } + } + AppendToEventLog(String(L"VoltVarControl.") + this->Name, Format(L"**Set var output level to**, kvar= %.5g", ARRAYOFCONST((Genkvar)))); + } // end for i equals 1 to number of generators under this control + } // end if vars needed is not equal to zero + // WriteDLLDebugFile(Self.Name+','+Format('%-.5g',[ActiveCircuit.Solution.dblHour])+','+Format('%-.5g',[QPresentGenOutput])+','+Format('%-.5g',[Qdeliver])+','+Format('%-.5g',[DeltaQ])+','+Format('%-.5g',[Qnew])+','+Format('%-.5g',[Gen.Presentkvar*1000.0])+','+Format('%-.5g',[QoldDeliver])+','+Format('%-.5g',[PPresentGenOutput])+','+Format('%-.5g',[Vavgpu])+','+Format('%-.5g',[Vavgpuprior])+','+Format('%-.5g',[Qdesiredpu])); + QOldDeliver = QNew; + VavgpuPrior = Vavgpu; + ActiveCircuit.Solution.LoadsNeedUpdating = true; + // Force recalc of power parms + Set_PendingChange(None); // end if PendingChange = CHANGEVARLEVEL + } + else + // else set PendingChange to NONE + { + Set_PendingChange(None); + } +} + +/* -------------------------------------------------------------------------- */ + +void TVVControlObj::sample() +{ + int i = 0; + double BaseKV = 0.0; + double Vavg = 0.0; + // If list is not defined, go make one for all generators in circuit + if(FGenPointerList.get_myNumList() == 0) + MakeGenList(); + if((FListSize > 0) && (Fvvc_curve_size > 0)) + + // if(presentHour <> ActiveCircuit.Solution.dblHour) then begin + // WriteDLLDebugFile(Self.Name+','+Format('%-.5g',[ActiveCircuit.Solution.dblHour])+','+Format('%-.5g',[QPresentGenOutput])+','+Format('%-.5g',[Qdeliver])+','+Format('%-.5g',[QNew])+','+Format('%-.5g',[Gen.Presentkvar*1000.0])+','+Format('%-.5g',[QoldDeliver])+','+Format('%-.5g',[PPresentGenOutput])+','+Format('%-.5g',[Vavgpu])+','+Format('%-.5g',[Vavgpuprior])); + // presentHour = ActiveCircuit.Solution.dblHour; + // end; + { + int stop = 0; + MonitoredElement->ComputeVterminal(); + cBuffer = MonitoredElement->Vterminal; + + // get the basekV for the monitored bus + BaseKV = ActiveCircuit.Buses[Terminals[ElementTerminal - 1].BusRef - 1].kVBase; + Vavg = 0; + + // Calculate the average voltage + for(stop = MonitoredElement->NPhases, i = 1; i <= stop; i++) + { + Vavg = Vavg + cabs((*cBuffer)[i - 1]); + } + + // and convert to pu + Vavgpu = (Vavg / MonitoredElement->NPhases) / (BaseKV * 1000.0); + TimeDelay = FDelay; + // and + // if (ActiveCircuit.Solution.ControlIteration < ActiveCircuit.Solution.MaxControlIterations) then + // begin + if((Abs( (Vavgpu - VavgpuPrior)) > DeltaVTolerance) || (Abs(Abs( Qdeliver) - Abs( QNew)) > 0.5)) + { + Set_PendingChange(CHANGEVARLEVEL); + // ActiveCircuit.Solution.LoadsNeedUpdating := TRUE; // Force recalc of power parms + ControlActionHandle = ActiveCircuit.ControlQueue.Push(ActiveCircuit.Solution.DynaVars.intHour, ActiveCircuit.Solution.DynaVars.T + TimeDelay, PendingChange, 0, this); + AppendToEventLog(String(L"VoltVarControl.") + this->Name, Format(L"**Ready to change var output**, Vavgpu= %.5g sec,", ARRAYOFCONST((Vavgpu)))); + // end; + } + else + { + ActiveCircuit.ControlQueue.Delete(ControlActionHandle); + AppendToEventLog(String(L"VoltVarControl.") + this->Name, L"**DONE**"); + } + } + else + { + DoSimpleMsg(L"Could not find any generators, or the vvc curve size is zero. Please correct in your script.", 1234); + } +} + +void TVVControlObj::InitPropertyValues(int ArrayOffset) +{ + PropertyValue[1] = L""; // 'element'; + PropertyValue[2] = L'1'; // 'terminal'; + PropertyValue[3] = L"1.1"; // vmax_pu of the inverter + PropertyValue[4] = L"0.9"; // vmin_pu of the inverter + PropertyValue[5] = L"7.0"; + PropertyValue[6] = L"5.83"; + PropertyValue[7] = L"3.5"; + PropertyValue[8] = L"0.83"; + PropertyValue[9] = L"0.0"; + PropertyValue[10] = L"0.0"; + PropertyValue[11] = L"-1.0"; + PropertyValue[12] = L"-1.0"; + PropertyValue[13] = L"1000.0"; // kw_limit through the monitored element + PropertyValue[14] = L"500.0"; // kvar_limit through the monitored element + PropertyValue[15] = L""; + PropertyValue[16] = L""; + PropertyValue[17] = L'0'; // curve size + PropertyValue[18] = L"none"; // volt-var curve + PropertyValue[19] = L"0.1"; // deltaQ_factor + inherited::InitPropertyValues(NumPropsThisClass); +} + +// need to edit this for the : WGS +// ---------------------------------------------------------------------------- + +String TVVControlObj::GetPropertyValue(int Index) +{ + String result; + result = L""; + switch(Index) + { + case 1: + result = MonitoredElement->DisplayName; + break; + case 2: + result = Format(L"%-d", ARRAYOFCONST((ElementTerminal))); + break; + case 3: + result = Format(L"%-.3g", ARRAYOFCONST((Fvvc_Vmaxpu))); + break; + case 4: + result = Format(L"%-.3g", ARRAYOFCONST((Fvvc_Vminpu))); + break; + case 5: + result = Format(L"%-.3g", ARRAYOFCONST((Fkva_rating))); + break; + case 6: + result = Format(L"%-.3g", ARRAYOFCONST((FkW_rating))); + break; + case 7: + result = Format(L"%-.3g", ARRAYOFCONST((Fkvar_fulloutput))); + break; + case 8: + result = Format(L"%-.3g", ARRAYOFCONST((Fpf))); + break; + case 9: + result = Format(L"%-.3g", ARRAYOFCONST((FDelay))); + break; + case 10: + result = Format(L"%-.3g", ARRAYOFCONST((Fdelayoff))); + break; + case 11: + result = Format(L"%-.3g", ARRAYOFCONST((FkW_ramp_rate))); + break; + case 12: + result = Format(L"%-.3g", ARRAYOFCONST((Fkvar_ramp_rate))); + break; + case 13: + result = Format(L"%-.3g", ARRAYOFCONST((FkW_limit))); + break; + case 14: + result = Format(L"%-.3g", ARRAYOFCONST((Fkvar_limit))); + break; + case 15: + result = ReturnGensList(); + break; + case 16: + result = ReturnWeightsList(); + break; + case 17: + result = Format(L"%-d", ARRAYOFCONST((Fvvc_curve_size))); + break; + case 18: + result = ReturnVVCurve(); + break; + case 19: + result = Format(L"%-.3g", ARRAYOFCONST((FdeltaQ_factor))); + break; // take the generic handler + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +bool TVVControlObj::MakeGenList() +{ + bool result = false; + TDSSClass* GenClass = nullptr; + TGeneratorObj* Gen = nullptr; + int i = 0; + int stop = 0; + result = false; + GenClass = GetDSSClassPtr(L"generator"); + if(FListSize > 0) // Name list is defined - Use it + { + int stop = 0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + Gen = ((TGeneratorObj*) GenClass->Find(String(FGeneratorNameList->Strings[i - 1]))); + if(ASSIGNED(Gen) && Gen->Enabled) + FGenPointerList.New() = Gen; + } + } + else + + /* Search through the entire circuit for enabled generators and add them to the list */ + { + int stop = 0; + for(stop = GenClass->ElementCount, i = 1; i <= stop; i++) + { + Gen = GenClass->ElementList.Get((void*&)i); + if(Gen->Enabled) + FGenPointerList.New() = Gen; + FGeneratorNameList->Add(Gen->DisplayName); + } + + /* Allocate uniform weights */ + FListSize = FGenPointerList.get_myNumList(); + FWeights = (pDoubleArray) ReallocMemory(FWeights, sizeof((*FWeights)[1 - 1]) * FListSize); + for(stop = FListSize, i = 1; i <= stop; i++) + { + (*FWeights)[i - 1] = 1.0; + } + } + + // Add up total weights + TotalWeight = 0.0; + for(stop = FListSize, i = 1; i <= stop; i++) + { + TotalWeight = TotalWeight + (*FWeights)[i - 1]; + } + if(FGenPointerList.get_myNumList() > 0) + result = true; + return result; +} + +// ----------------------------------------------------------------------------- + +String TVVControlObj::ReturnGensList() +{ + String result; + int i = 0; + int stop = 0; + if(FListSize == 0) + { + result = L""; + return result; + } + result = String(L"[") + FGeneratorNameList->Strings[0]; + for(stop = FListSize - 1, i = 1; i <= stop; i++) + { + result = result + L", " + String(FGeneratorNameList->Strings[i]); + } + result = result + L"]"; // terminate the array + return result; +} + +// ---------------------------------------------------------------------------- + +String TVVControlObj::ReturnWeightsList() +{ + String result; + int i = 0; + int stop = 0; + if(FListSize == 0) + { + result = L""; + return result; + } + result = String(L"[") + Format(L"%-.6g", ARRAYOFCONST(((*FWeights)[1 - 1]))); + for(stop = FListSize, i = 2; i <= stop; i++) + { + result = result + Format(L", %-.6g", ARRAYOFCONST(((*FWeights)[i - 1]))); + } + result = result + L"]"; // terminate the array + return result; +} + +// ---------------------------------------------------------------------------- + +String TVVControlObj::ReturnVVCurve() +{ + String result; + int i = 0; + int stop = 0; + if(Fvvc_curve_size == 0) + { + result = L""; + return result; + } + result = String(L"[{") + Format(L"%-.3g,", ARRAYOFCONST((Fvvc_curve->Get_XValue(1)))) + + Format(L"%-.3g", ARRAYOFCONST((Fvvc_curve->Get_YValue(1)))) + + L"},"; + for(stop = Fvvc_curve_size, i = 2; i <= stop; i++) + { + result = result + + Format(L"{ %-.3g,", ARRAYOFCONST((Fvvc_curve->Get_XValue(i)))) + + Format(L"%-.3g", ARRAYOFCONST((Fvvc_curve->Get_YValue(i)))) + + L"},"; + } + result = result + L"]"; // terminate the array + return result; +} + +void TVVControlObj::Reset() +{ + PendingChange = None; +} + +void TVVControlObj::Set_PendingChange(int Value) +{ + FPendingChange = Value; + DblTraceParameter = (double) Value; +} + + + + +} // namespace VVControl + + + + + diff --git a/OpenDSSC/Controls/VVControl.h b/OpenDSSC/Controls/VVControl.h new file mode 100644 index 0000000..5d365c7 --- /dev/null +++ b/OpenDSSC/Controls/VVControl.h @@ -0,0 +1,150 @@ +#ifndef VVControlH +#define VVControlH + +#include +#include "../Support/d2c_system.h" + +#include "../Shared/Command.h" +#include "../Controls/ControlClass.h" +#include "../Controls/ControlElem.h" +#include "../Common/CktElement.h" +#include "../Common/Bus.h" +#include "../Common/DSSClass.h" +#include "../shared/Arraydef.h" +#include "../Shared/Ucomplex.h" +#include "../Common/Utilities.h" +#include "../General/XYcurve.h" +#include "../Shared/PointerList.h" +#include +#include "../Support/d2c_sysfile.h" + +namespace VVControl +{ + + + +// added using GenDispatcher as a template +/* + ---------------------------------------------------------- + Copyright (c) 2010, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + A VVCControl is a control element that is connected to a terminal of another + circuit element and sends dispatch kW signals and kvar to a set of generators it controls + + A VVCControl is defined by a New command: + + New VVCControl.Name=myname Element=devclass.name terminal=[ 1|2|...] GenList = (gen1 gen2 ...) + + +*/ + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TVVControl : public ControlClass::TControlClass +{ + friend class TVVControlObj; +public: + typedef ControlClass::TControlClass inherited; +private: + DSSClass::TDSSClass* XY_CurveClass; +protected: + void DefineProperties(); + virtual int MakeLike(const String VVCControlName); +public: + TVVControl(); + virtual ~TVVControl(); + virtual int Edit(); // uses global parser + virtual int NewObject(const String ObjName); + XYCurve::TXYcurveObj* GetVVCCurve(const String CurveName); +}; + + // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TVVControlObj : public ControlElem::TControlElem +{ + friend class TVVControl; +public: + typedef ControlElem::TControlElem inherited; +private: + // kw limit at the monitored element + // kvar limit at the monitored element + // tolerance of voltage change from one solution to the + // next for the voltage at the monitored element - in pu + double Fvvc_Vmaxpu; + double Fvvc_Vminpu; + double Fkva_rating; + double FkW_rating; + double Fkvar_fulloutput; + double Fpf; + double FDelay; + double Fdelayoff; + double FkW_ramp_rate; + double Fkvar_ramp_rate; + double FkW_limit; + double Fkvar_limit; + double DeltaVTolerance; + double TotalWeight; + double QOldDeliver; + double Qdeliver; + double QNew; + double VavgpuPrior; + double Vavgpu; + double presentHour; + int ControlActionHandle; + int FListSize; + System::Classes::TStringList* FGeneratorNameList; + PointerList::TPointerList* FGenPointerList; + Arraydef::pDoubleArray FWeights; + int Fvvc_curve_size; + XYCurve::TXYcurveObj* Fvvc_curve; + int FPendingChange; + double FdeltaQ_factor; + CktElement::TDSSCktElement* MonitoredElement; + Ucomplex::pComplexArray cBuffer; // Complexarray buffer + int CondOffset; // Offset for monitored terminal + void Set_PendingChange(int Value); +public: + __property int PendingChange = { read = FPendingChange, write = Set_PendingChange }; + TVVControlObj(DSSClass::TDSSClass* ParClass, const String VVCControlName); + virtual ~TVVControlObj(); + virtual void MakePosSequence(); // Make a positive Sequence Model + virtual void RecalcElementData(); + virtual void CalcYPrim(); // Always Zero for a VVCControl + virtual void sample(); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Code, int ProxyHdl); + // Do the action that is pending from last sample + virtual void Reset(); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr); + // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr); + // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(d2c_system::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + bool MakeGenList(); + String ReturnGensList(); + String ReturnWeightsList(); + String ReturnVVCurve(); + TVVControlObj(DSSClass::TDSSClass* ParClass); + TVVControlObj(String ClassName); + TVVControlObj(); +}; +extern TVVControlObj* ActiveVVCControlObj; + + /* -------------------------------------------------------------------------- */ + + +} // namespace VVControl + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace VVControl; +#endif + +#endif // VVControlH + + + + + diff --git a/OpenDSSC/DLL/OpenDSSCDLL.cpp b/OpenDSSC/DLL/OpenDSSCDLL.cpp new file mode 100644 index 0000000..e186258 --- /dev/null +++ b/OpenDSSC/DLL/OpenDSSCDLL.cpp @@ -0,0 +1,18497 @@ +// OpenDSSX.cpp : Defines the entry point for the application. +// + +#pragma hdrstop + +#include +#include "OpenDSSCDLL.h" +#include +#include +#include +#include +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "Arraydef.h" +#include "Command.h" +#include "HashList.h" +#include "PointerList.h" +#include "RPN.h" +#include "ParserDel.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "CktElement.h" +#include "CktElementClass.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Bus.h" +#include "klusolve.h" +#include "PCClass.h" +#include "PCElement.h" +#include "PDClass.h" +#include "PDElement.h" +#include "CktTree.h" +#include "Pstcalc.h" +#include "StackDef.h" +#include "Terminal.h" +#include "mathutil.h" + +#include "XYcurve.h" +#include "XfmrCode.h" +#include "WireData.h" +#include "TSLineConstants.h" +#include "CNData.h" +#include "TSData.h" +#include "TempShape.h" +#include "TCC_Curve.h" +#include "Spectrum.h" +#include "PriceShape.h" +#include "OHLineConstants.h" +#include "NamedObject.h" +#include "LoadShape.h" +#include "LineSpacing.h" +#include "LineGeometry.h" +#include "LineConstants.h" +#include "LineCode.h" +#include "GrowthShape.h" +#include "ConductorData.h" +#include "CNLineConstants.h" +#include "CableData.h" +#include "CableConstants.h" + +#include "LineUnits.h" +#include "Conductor.h" +#include "Line.h" +#include "Transformer.h" +#include "Capacitor.h" +#include "Reactor.h" +#include "GICTransformer.h" +#include "fuse.h" +#include "Fault.h" +#include "AutoTrans.h" + +#include "WindGenVars.h" +#include "WindGen.h" +#include "WindGenUserModel.h" +#include "VSource.h" +#include "VSConverter.h" +#include "vccs.h" +#include "UPFC.h" +#include "StorageVars.h" +#include "Storage.h" +#include "StoreUserModel.h" +#include "PVsystem.h" +#include "PVSystemUserModel.h" +#include "Load.h" +#include "Isource.h" +#include "IndMach012.h" +#include "GICsource.h" +#include "GICLine.h" +#include "GenUserModel.h" +#include "Generic5OrderMach.h" +#include "GeneratorVars.h" +#include "generator.h" +#include "Equivalent.h" + +#include "UPFCControl.h" +#include "SwtControl.h" +#include "StorageController.h" +#include "Relay.h" +#include "RegControl.h" +#include "Recloser.h" +#include "InvControl.h" +#include "GenDispatcher.h" +#include "ExpControl.h" +#include "ESPVLControl.h" +#include "CapControlVars.h" +#include "CapControl.h" +#include "CapUserControl.h" + +#include "VLNodeVars.h" +#include "Sensor.h" +#include "ReduceAlgs.h" +#include "Monitor.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "MemoryMap_lib.h" +#include "LD_fm_infos.h" +#include "fMonitor.h" +#include "EnergyMeter.h" + +#include "AutoAdd.h" +#include "Solution.h" +#include "SolutionAlgs.h" +#include "Circuit.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "ControlQueue.h" +#include "DSSCallBackRoutines.h" + +#include "Dynamics.h" +#include "InvDynamics.h" +#include "EventQueue.h" +#include "ExecCommands.h" +#include "ExecHelper.h" +#include "ExecOptions.h" +#include "Executive.h" +#include "ExportCIMXML.h" +#include "ExportOptions.h" +#include "ExportResults.h" +#include "Feeder.h" +#include "IniRegSave.h" +#include "MyDSSClassDefs.h" +#include "Notes.h" +#include "ShowOptions.h" +#include "ShowResults.h" +#include "TOPExport.h" +#include "Utilities.h" +#include "YMatrix.h" +#include "ConnectOptions.h" +#include "Diakoptics.h" +#include "Sparse_Math.h" +#include "MeTIS_Exec.h" +#include "GISCommands.h" +#include "djson.h" +#include "CmdForms.h" +#include "myCmdUtils.h" +#include "myCmdUtils.cpp" + +#ifdef OPENDSSX_CPP_EXTRA_HEADER +// Include another file from a parent project. +// For details, see the note about PARENT PROJECTS at the end of this file. +#include OPENDSSX_CPP_EXTRA_HEADER +#endif + + +//#pragma resource "*.RES" +#define MAXIDX(x) (sizeof(x)/sizeof(x[0]))-1 + + +//class TMyApplication; + +using namespace std; +using namespace DSSGlobals; + + + +class TMyApplication { + +public: + void DoRun(); + TMyApplication(); + ~TMyApplication(); + virtual string WriteLicensing(); + int GetOptionIdx(string myCMD); + string Execute(string myCMD); +}; + +TMyApplication Application; + +const string ExeName = "OpenDSSCMD"; +int VarIdx = 0; // Left this one here instead of DSSGlobals to avoid confusion in other files. + +//-------------------------------------------------------------------------------- +// Initializes OpenDSS, creates default items and implements the executive class +//-------------------------------------------------------------------------------- +void TMyApplication::DoRun() +{ + NoFormsAllowed = true; + ActiveActor = 1; + IsDLL = true; + DSSExecutive[ActiveActor] = new TExecutive(); // Make a DSS object + DSSExecutive[ActiveActor]->CreateDefaultDSSItems(); + DataDirectory[ActiveActor] = StartupDirectory; + OutputDirectory[ActiveActor] = StartupDirectory; + SetCurrentDir(DataDirectory[ActiveActor]); + NoFormsAllowed = false; // messages will go to the console +} + +//-------------------------------------------------------------------------------- +// Executes a command in the form of a string, returns the result +//-------------------------------------------------------------------------------- +string TMyApplication::Execute(string myCMD) +{ + int CmdIdx = 0; + string result = ""; + + CmdIdx = GetOptionIdx(myCMD); + if (CmdIdx == 0) + { + DSSExecutive[ActiveActor]->Set_Command(myCMD); + if (DSSExecutive[ActiveActor]->Get_LastError() != "") + result = DSSExecutive[ActiveActor]->Get_LastError(); + else + result = GlobalResult; + } + else + { + switch (CmdIdx) + { + case 1: + result = "To be defined"; + break; + case 2: + result = "OpenDSS console " + VersionString; + break; + case 3: case 4: + result = "Not implemented in Embarcadero version"; + break; + case 5: + result = WriteLicensing(); + break; + case 6: case 7: + result = "Leaving the program"; + break; + default: + result = "option not recognized"; + } + } + return result; +} + + +//-------------------------------------------------------------------------------- +// Creates the application within the caller memory space +//-------------------------------------------------------------------------------- +TMyApplication::TMyApplication() // This only happens when the app is created +{ + //DoRun(); +} + +//-------------------------------------------------------------------------------- +// Closes the App, nothing to do really +//-------------------------------------------------------------------------------- +TMyApplication::~TMyApplication() // This only hapens when the app gets destroyed +{ + // todo check: inherited::Destroy; +} + +//-------------------------------------------------------------------------------- +// Identifies special commands outside the DSS command menu, to be evaluated +//-------------------------------------------------------------------------------- +int TMyApplication::GetOptionIdx(string myCMD) // Executes command or detects special characters +{ + int result = 0; + myCMD = LowerCase(myCMD); + result = 0; + if ((myCMD == "-help") || (myCMD == "-h")) + result = 1; + if (myCMD == "-v") + result = 2; + if (myCMD == "-f") + result = 3; + if (myCMD == "-l") + result = 4; + if (myCMD == "-lic") + result = 5; + if (myCMD == "exit") + result = 6; + if (myCMD == "q") + result = 7; + return result; +} + +//-------------------------------------------------------------------------------- +// REturns the string for the license agreement +//-------------------------------------------------------------------------------- +string TMyApplication::WriteLicensing() // returns the license agreement +{ + string result = "0"; + result = ("Copyright (c) 2008-2023, Electric Power Research Institute, Inc." + + CRLF + "All rights reserved." + + CRLF + "" + + CRLF + "Redistribution and use in source and binary forms, with or without" + + CRLF + "modification, are permitted provided that the following conditions are met:" + + CRLF + " * Redistributions of source code must retain the above copyright" + + CRLF + " notice, this list of conditions and the following disclaimer." + + CRLF + " * Redistributions in binary form must reproduce the above copyright" + + CRLF + " notice, this list of conditions and the following disclaimer in the" + + CRLF + " documentation and/or other materials provided with the distribution." + + CRLF + " * Neither the name of the Electric Power Research Institute, Inc., nor" + + CRLF + " the names of its contributors may be used to endorse or promote" + + CRLF + " products derived from this software without specific prior written" + + CRLF + " permission." + + CRLF + "" + + CRLF + "THIS SOFTWARE IS PROVIDED BY Electric Power Research Institute, Inc., \"AS IS\"" + + CRLF + "AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE" + + CRLF + "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR" + + CRLF + "PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Electric Power Research Institute, Inc.," + + CRLF + "OR ANY OTHER ENTITY CONTRIBUTING TO OR INVOLVED IN THE PROVISION OF THE SOFTWARE," + + CRLF + "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR" + + CRLF + "CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF" + + CRLF + "SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS" + + CRLF + "INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN" + + CRLF + "CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)" + + CRLF + "ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE" + + CRLF + "POSSIBILITY OF SUCH DAMAGE." + + CRLF); + return result; +} + +pAction ActiveAction = nullptr; +TCOMControlProxyObj* COMControlProxyObj = new TCOMControlProxyObj(nullptr,"COM_Proxy"); + +//*********************************************Objects****************************************************** +void TCOMControlProxyObj::ClearActionList() +{ + while (PopAction()) + { + }; // spin until it is done +} + +bool TCOMControlProxyObj::PopAction() +{ + bool Result = false; + + if (ASSIGNED(ActiveAction)) + { + delete(ActiveAction); + ActiveAction = nullptr; + } + Result = true; + if (!ActionList.empty()) + { + ActiveAction = (TAction*) ActionList[0]; + ActionList.erase(ActionList.begin()); + } + else + Result = false; + + return Result; +} + +TCOMControlProxyObj::TCOMControlProxyObj(DSSClass::TDSSClass* ParClass, const String COMProxyName) +{ + Set_Name(COMProxyName); + ActionList.resize(0); +} + +void TCOMControlProxyObj::DopendingAction(const int Code, int ProxyHdl, int ActorID) +{ + pAction Action = new TAction; + + Action->ActionCode = Code; + Action->DeviceHandle = ProxyHdl; + + ActionList.push_back(Action); +} + +void TCOMControlProxyObj::Reset(int ActorID) +{ + ClearActionList(); +} + +//******************************************************************DLL commands and interfaces********************************************************** + + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the DSS integer interface +//-------------------------------------------------------------------------------- +int __stdcall DSSI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // DSS.NumCircuits + result = (ActiveCircuit[ActiveActor] != nullptr) ? ActiveCircuit[ActiveActor]->NumCircuits : 0; + break; + case 1: // DSS.ClearAll + DoClearAllCmd(); + break; + case 2: // DSS.ShowPanel + + break; + case 3: // DSS.Start + Application.DoRun(); + result = 1; + break; + case 4: // DSS.NumClasses + result = NumIntrinsicClasses; + break; + case 5: // DSS.NumUserClasses + result = NumUserClasses; + break; + case 6: // DSS.Reset + //TBD + break; + case 7: // DSS.Allowforms read + if (NoFormsAllowed) + result = 1; + else + result = 0; + break; + case 8: // DSS.Allowforms write + if (arg == 0) + NoFormsAllowed = 1; + else + NoFormsAllowed = 0; + break; + case 9: + result = 1; + break; + default: + result = -1; + } + return result; +} +//-------------------------------------------------------------------------------- +// Implements the DSS String interface +//-------------------------------------------------------------------------------- +char* __stdcall DSSS(int mode, char* arg) +{ + string result = ""; + switch (mode) + { + case 0: // DSS.NewCircuit + MakeNewCircuit(arg); + result = "New Circuit"; + break; + case 1: // DSS.Version + result = VersionString + "; license status: Open;" +#if defined(_DEBUG) || !defined(NDEBUG) + " (DEBUG VERSION)" +#endif + " built on " __DATE__ " " __TIME__; + break; + case 2: // DSS.DataPath read + result = DataDirectory[ActiveActor]; + break; + case 3: // DSS.Datapath write + SetDataPath(arg); + break; + case 4: // DSS.DefaultEditor + result = DefaultEditor; + break; + default: + result = "Error, parameter not recognized"; + } + + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//-------------------------------------------------------------------------------- +// Implements the DSS pointer (former variant) interface +//-------------------------------------------------------------------------------- +void __stdcall DSSV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int i = 0; + + switch (mode) + { + case 0: // DSS.Classes + *myType = 4; // String + myStrArray.resize(0); + for (i = 1; i < NumIntrinsicClasses; i++) + { + WriteStr2Array(((TDSSClass*)DSSClassList[ActiveActor].Get(i))->Class_Name); + WriteStr2Array(Char0()); + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: // DSS.UserClasses + *myType = 4; // String + myStrArray.resize(0); + if (NumUserClasses > 0) + { + for (i = NumIntrinsicClasses + 1; i <= DSSClassList[ActiveActor].get_myNumList(); i++) + { + WriteStr2Array(((TDSSClass*)DSSClassList[ActiveActor].Get(i))->Class_Name); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + myPtr = (uintptr_t*)&(myStrArray[0]); + } + + +} + +vector Str2StrArray(char* myStr, char Delimiter) +{ + vector Result; + char EvalChar = 0x01; + int charidx = 0; + string StElm = ""; + + Result.clear(); + + while (!(EvalChar == 0)) + { + EvalChar = myStr[charidx]; + if (!(EvalChar == 0x0A)) + StElm = StElm + EvalChar; + else + { + Result.push_back(StElm); + StElm = ""; // reset accumulator + } + charidx++; + } + Result.push_back(StElm); + return Result; +} + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the text interface for the DLL +//-------------------------------------------------------------------------------- +char* __stdcall DSSPut_Command(char* myCmd) +{ + vector myCmds; + string result = "", + DSSReply = ""; + + myCmds = Str2StrArray(myCmd, 0x0A); + for (int i = 0; i < myCmds.size(); i++) + { + DSSReply = Application.Execute(myCmds[i].c_str()); + if (!(DSSReply.empty())) + result = result + DSSReply + char(0x0A); + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the Lines interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Line Functions************************* +bool IsLine(TDSSCktElement* CktElem) +{ + bool result = false; + + result = ((CktElem->DSSObjType & CLASSMASK) == LINE_ELEMENT); + if (!result) + DoSimpleMsg("Line Type Expected, but another found.Dss Class = " + CktElem->Get_myPName() + CRLF + + "Element name = " + CktElem->get_Name(), 5007); + return result; +} + + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the Lines interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall LinesI(int mode, int arg) +{ + TLineObj* pLine = {}; + int result = 0; + + switch (mode) + { + case 0: // Lines.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLine = (TLineObj*)ActiveCircuit[ActiveActor]->Lines.Get_First(); + if (ASSIGNED(pLine)) + { + do + { + if (pLine->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + result = 1; + } + else + { + pLine = (TLineObj*)ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(pLine)))); + } + } + break; + case 1: // Lines.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLine = (TLineObj*)ActiveCircuit[ActiveActor]->Lines.Get_Next(); + if (ASSIGNED(pLine)) + { + do + { + if (pLine->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + result = ActiveCircuit[ActiveActor]->Lines.ActiveItem; + } + else + { + pLine = (TLineObj*)ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(pLine)))); + } + } + break; + case 2: // Lines.Phases read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + result = ActiveCircuit[ActiveActor]->FActiveCktElement->Get_NPhases(); + } + break; + case 3: // Lines.Phases write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->Set_NPhases(arg); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 4: // Lines.NumCust + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + result = ((TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement)->BranchNumCustomers; + } + } + break; + case 5: // Lines.Parent + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + pLine = ((TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement); + if (ASSIGNED(pLine->ParentPDElement)) + { + if (pLine->ParentPDElement->FEnabled && IsLine(pLine->ParentPDElement)) + result = ActiveCircuit[ActiveActor]->Lines.ActiveItem; + } + } + } + break; + case 6: // Lines.Count + if (ActiveCircuit[ActiveActor] != nullptr) + result = ActiveCircuit[ActiveActor]->Lines.NumInList; + break; + case 7: // Lines.Units read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + result = ((TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement)->LengthUnits; + } + break; + case 8: // Lines.Units write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + if (arg < 9) + { + Parser[ActiveActor]->SetCmdString(Format("units = %s", LineUnitsStr(arg).c_str())); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + } + break; + default: + result = -1; + break; + + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall LinesF(int mode, double arg) +{ + int RatingIdx = 0; + TXYcurveObj* RSignal = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: // Lines.Length read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + result = ((TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement)->Len; + } + } + break; + case 1: // Lines.Length write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->Len = arg; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 2: // Lines.R1 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->R1 / with0->FUnitsConvert; + } + } + break; + case 3: // Lines.R1 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->R1 = arg * with0->FUnitsConvert; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 4: // Lines.X1 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->X1 / with0->FUnitsConvert; + } + } + break; + case 5: // Lines.X1 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->X1 = arg * with0->FUnitsConvert; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 6: // Lines.R0 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->R0 / with0->FUnitsConvert; + } + } + break; + case 7: // Lines.R0 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->R0 = arg * with0->FUnitsConvert; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 8: // Lines.X0 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->X0 / with0->FUnitsConvert; + } + } + break; + case 9: // Lines.X0 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->X0 = arg * with0->FUnitsConvert; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 10: // Lines.C1 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = (with0->C1 / with0->FUnitsConvert) * 1.0e9; + } + } + break; + case 11: // Lines.C1 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->C1 = arg * with0->FUnitsConvert * 1.0e9; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 12: // Lines.C0 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = (with0->C0 / with0->FUnitsConvert) * 1.0e9; + } + } + break; + case 13: // Lines.C0 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->C0 = arg * with0->FUnitsConvert * 1.0e9; + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 14: // Lines.NormAmps read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->NormAmps; + } + } + break; + case 15: // Lines.NormAmps write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->NormAmps = arg; + } + } + break; + case 16: // Lines.EmergAmps read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->EmergAmps; + } + } + break; + case 17: // Lines.EmergAmps write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->EmergAmps = arg; + } + } + break; + case 18: // Lines.Rg read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->Rg; + } + } + break; + case 19: // Lines.Rg write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + Parser[ActiveActor]->SetCmdString(Format("rg = %.7g", arg)); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 20: // Lines.Xg read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->Xg; + } + } + break; + case 21: // Lines.Xg write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + Parser[ActiveActor]->SetCmdString(Format("xg = %.7g", arg)); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 22: // Lines.Rho read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->rho; + } + } + break; + case 23: // Lines.Xg write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + Parser[ActiveActor]->SetCmdString(Format("rho = %.7g", arg)); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 24: // Lines.SeasonRating + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + auto& with1 = ActiveCircuit[ActiveActor]->Solution->DynaVars; + result = with0->NormAmps; + if ((!SeasonSignal.empty()) && SeasonalRating) + { + RSignal = (TXYcurveObj*)XYCurveClass[ActiveActor]->Find(SeasonSignal); + if (ASSIGNED(RSignal)) + RatingIdx = trunc(RSignal->GetXValue(with1.intHour)); + // just in case + if (RatingIdx <= with0->NumAmpRatings) + result = with0->AmpRatings[RatingIdx]; + } + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall LinesS(int mode, char* arg) +{ + TDSSCktElement* pLine = nullptr; + int activesave = 0; + string S = "", + result = ""; + bool Found = false; + + switch (mode) + { + case 0: // Lines.Name read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + pLine = ActiveCircuit[ActiveActor]->FActiveCktElement; + if (ASSIGNED(pLine)) + result = pLine->get_Name(); + } + } + break; + case 1: // Lines.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Lines; + S = arg; + activesave = with0.ActiveItem; + pLine = (TDSSCktElement*)with0.Get_First(); + while (ASSIGNED(pLine)) + { + if (CompareText(pLine->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + Found = true; + break; + } + pLine = (TDSSCktElement*)with0.Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Line """ + S + """ Not Found in Active Circuit.", 5008); + pLine = (TDSSCktElement*)with0.Get(activesave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + } + } + break; + case 2: // Lines.Bus1 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + pLine = ActiveCircuit[ActiveActor]->FActiveCktElement; + if (ASSIGNED(pLine)) + result = pLine->GetBus(1); + } + } + break; + case 3: // Lines.Bus1 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->SetBus(1, arg); + } + } + break; + case 4: // Lines.Bus2 read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + pLine = ActiveCircuit[ActiveActor]->FActiveCktElement; + if (ASSIGNED(pLine)) + result = pLine->GetBus(2); + } + } + break; + case 5: // Lines.Bus2 write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->SetBus(2, arg); + } + } + break; + case 6: // Lines.LineCode read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->CondCode; + } + } + break; + case 7: // Lines.LineCode write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + with0->FetchLineCode(arg); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 8: // Lines.Geometry read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->GeometryCode; + } + } + break; + case 9: // Lines.Geometry write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + S = arg; + Parser[ActiveActor]->SetCmdString("geometry=" + S); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + case 10: // Lines.Spacing read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->SpacingCode; + } + } + break; + case 11: // Lines.Spacing write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + S = arg; + Parser[ActiveActor]->SetCmdString("spacing=" + S); + with0->Edit(ActiveActor); + with0->Set_YprimInvalid(ActiveActor, true); + } + } + break; + default: + result = "Error, parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall LinesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TLineObj* LineElem = nullptr; + complex Ztemp = cmplx(0, 0); + double Factor = 0.0; + int i = 0, + j = 0, + k = 0, + iV = 0, + NValues = 0; + complex* cValues = nullptr; + double* PDouble = nullptr; + + switch (mode) + { + case 0: // Lines.AllNames + *myType = 4; // String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Lines.NumInList > 0) + { + LineElem = (TLineObj*)with0->Lines.Get_First(); + while (ASSIGNED(LineElem)) + { + WriteStr2Array(LineElem->get_Name()); + WriteStr2Array(Char0()); + LineElem = (TLineObj*)with0->Lines.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: // Lines.RMatrix read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + myDblArray.resize(sqr(with0->Get_NPhases())); + k = 0; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + if (with0->GeometrySpecified || with0->SpacingSpecified) + myDblArray[k] = with0->Z->GetElement(i, j).re / with0->Len; + else + myDblArray[k] = with0->Z->GetElement(i, j).re / with0->FUnitsConvert; + k++; + } + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 2: // Lines.RMatrix write + *myType = 2; // Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + Ztemp = with0->Z->GetElement(i, j); + with0->Z->SetElement(i, j, cmplx(*PDouble, Ztemp.im)); + k++; + PDouble++; + } + } + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 3: // Lines.XMatrix read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + myDblArray.resize(sqr(with0->Get_NPhases())); + k = 0; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + if (with0->GeometrySpecified || with0->SpacingSpecified) + myDblArray[k] = with0->Z->GetElement(i, j).im / with0->Len; + else + myDblArray[k] = with0->Z->GetElement(i, j).im / with0->FUnitsConvert; + k++; + } + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 4: // Lines.XMatrix write + *myType = 2; // Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + Ztemp = with0->Z->GetElement(i, j); + with0->Z->SetElement(i, j, cmplx(Ztemp.re, *PDouble)); + k++; + PDouble++; + } + } + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 5: // Lines.CMatrix read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + Factor = TwoPi * with0->BaseFrequency * 1.0e-9 * with0->FUnitsConvert; + myDblArray.resize(sqr(with0->Get_NPhases())); + k = 0; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + if (with0->GeometrySpecified || with0->SpacingSpecified) + myDblArray[k] = with0->YC->GetElement(i, j).im / Factor / with0->Len; + else + myDblArray[k] = with0->YC->GetElement(i, j).im / Factor; + k++; + } + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 6: // Lines.CMatrix write + *myType = 2; // Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + Factor = TwoPi * with0->BaseFrequency * 1.0e-9; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->Get_NPhases(); i++) + { + for (j = 1; j <= with0->Get_NPhases(); j++) + { + with0->YC->SetElement(i, j, cmplx(0.0, (*PDouble) * Factor)); + k++; + PDouble++; + } + } + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 7: // Lines.YPrim read + *myType = 3; // Complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLine(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + auto with0 = (TLineObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + NValues = sqr(with0->Yorder); + cValues = with0->GetYPrimValues(ALL_YPRIM); + if (ASSIGNED(cValues)) + { + myCmplxArray.resize(NValues); + for (i = 0; i < NValues; i++) + myCmplxArray[i] = cValues[i]; + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 8: // Lines.YPrim write + if (ActiveCircuit[ActiveActor] != nullptr) + { + // {Do Nothing for now} + } + break; + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the Loads interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Load Functions************************* +bool IsLoad(TDSSCktElement* CktElem) +{ + bool result = false; + + result = ((CktElem->DSSObjType & CLASSMASK) == LOAD_ELEMENT); + if (!result) + DoSimpleMsg("Load Type Expected, but another found.Dss Class = " + CktElem->Get_myPName() + CRLF + + "Element name = " + CktElem->get_Name(), 5007); + return result; +} +TLoadObj* ActiveLoad() +{ + TLoadObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsLoad(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + result = (TLoadObj*)ActiveCircuit[ActiveActor]->FActiveCktElement; + } + } + return result; +} +void Set_Parameter(string parm, string val) +{ + string mycmd = ""; + TLoadObj* pLoad = {}; + if (ActiveCircuit[ActiveActor]) + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (pLoad != nullptr) + { + SolutionAbort = false; + auto with0 = ActiveCircuit[ActiveActor]; + mycmd = Format("load.%s.%s=%s", pLoad->get_Name().c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } + } +} +// ******************************int type properties************************* +int __stdcall DSSLoads(int mode, int arg) +{ + TLoadObj* pLoad = {}; + int result = 0; + + switch (mode) + { + case 0: // Load.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_First(); + if (ASSIGNED(pLoad)) + { + do + { + if (pLoad->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLoad); + result = 1; + } + else + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(pLoad)))); + } + } + break; + case 1: // Load.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Next(); + if (ASSIGNED(pLoad)) + { + do + { + if (pLoad->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLoad); + result = ActiveCircuit[ActiveActor]->Loads.ActiveItem; + } + else + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(pLoad)))); + } + } + break; + case 2: // Load.idx - Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->Loads.ActiveItem; + } + break; + case 3: // Load.idx - Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get(arg); + if (ASSIGNED(pLoad)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLoad); + } + } + break; + case 4: // Load.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->Loads.NumInList; + } + break; + case 5: // Load.Class - Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->LoadClass; + } + break; + case 6: // Load.Class - Write + Set_Parameter("Class", IntToStr(arg)); + break; + case 7: // Load.Model - Read + + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FLoadModel; + } + break; + case 8: // Load.Model - Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->FLoadModel = arg; + } + break; + case 9: // Load.NumCust - Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->NumCustomers; + } + break; + case 10: // Load.NumCust - Write + Set_Parameter("NumCust", IntToStr(arg)); + break; + case 11: // Load.Status - Read + result = 0; + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (pLoad->ExemptFromLDCurve) + { + result = 2; + } + else if (pLoad->FIXED) + { + result = 1; + } + break; + case 12: // Load.Status - Wirte + switch (arg) + { + case 0: + Set_Parameter("status", "v"); + break; + case 1: + Set_Parameter("status", "f"); + break; + case 2: + Set_Parameter("status", "e"); + break; + } + + break; + case 13: // Load.isDelta - Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + if (pLoad->Connection > 0) { + result = 1; + } + } + break; + case 14: // Load.isDelta- Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->Connection = Integer(arg); + } + break; + + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall DSSLoadsF(int mode, double arg) +{ + TLoadObj* pLoad = {}; + double result = 0.0; + + switch (mode) + { + case 0: // Load.kw Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->kWBase; + } + break; + case 1: // Load.kw Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->kWBase = arg; + pLoad->LoadSpecType = 0; + pLoad->RecalcElementData(ActiveActor);// sets kvar based on kW and pF + } + break; + case 2: // Load.kv Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->kVLoadBase; + } + break; + case 3: // Load.kv Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->kVLoadBase = arg; + pLoad->UpdateVoltageBases(); // side effects + } + break; + case 4: // Load.kvar Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->kvarBase; + } + break; + case 5: // Load.kvar Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->kvarBase = arg; + pLoad->LoadSpecType = 1; + pLoad->RecalcElementData(ActiveActor);// set power factor based on kW, kvar + } + break; + case 6: // Load.pf Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->PFNominal; + } + break; + case 7: // Load.pf Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->PFNominal = arg; + pLoad->LoadSpecType = 0; + pLoad->RecalcElementData(ActiveActor);// set power factor based on kW, kvar + } + break; + case 8: // Load.pctmean Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FpuMean * 100.0; + } + break; + case 9: // Load.pctmean Write + if (ASSIGNED(pLoad)) + { + Set_Parameter("%mean", FloatToStr(arg)); + } + break; + case 10: // Load.pctdev Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FpuStdDev * 100.0; + } + break; + case 11: // Load.pctdev write + Set_Parameter("%stddev", FloatToStr(arg)); + break; + case 12: // Load.AllocationFactor Read + { + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + result = pLoad->FAllocationFactor; + } + break; + case 13: // Read.AllocationFactor Write + Set_Parameter("AllocationFactor", FloatToStr(arg)); + break; + case 14: // Load.CFactor Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FCFactor; + } + break; + case 15: // Load.CFactor Write + Set_Parameter("CFactor", FloatToStr(arg)); + break; + case 16: // Load.CVRWatts Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FCVRwattFactor; + } + break; + case 17: // Load.CVRWatts Write + Set_Parameter("CVRWatts", FloatToStr(arg)); + break; + case 18: // Load.CVRvars Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FCVRvarFactor; + } + break; + case 19: // Load.CVRvars Write + Set_Parameter("CVRvars", FloatToStr(arg)); + break; + case 20: // Load.kva Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->kVABase; + } + break; + case 21: // Load.kva Write + Set_Parameter("kva", FloatToStr(arg)); + break; + case 22: // Load.kwh Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FkWh; + } + break; + case 23: // Load.kwh Write + Set_Parameter("kwh", FloatToStr(arg)); + break; + case 24: // Load.kwhDay Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FkWhDays; + } + break; + case 25: // Load.kwhDay Write + Set_Parameter("kwhDay", FloatToStr(arg)); + break; + case 26: // Load.Rneut Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->Rneut; + } + break; + case 27: // Load.Rneut Write + Set_Parameter("Rneut", FloatToStr(arg)); + break; + case 28: // Load.Vmaxpu Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->Vmaxpu; + } + break; + case 29: // Load.Vmaxpu Write + Set_Parameter("Vmaxpu", FloatToStr(arg)); + break; + case 30: // Load.VMinemerg Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->VminEmerg; + } + break; + case 31: // Load.VMinemerg Write + Set_Parameter("VMinemerg", FloatToStr(arg)); + break; + case 32: // Load.VMinNorm Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->VminNormal; + } + break; + case 33: // Load.VMinNorm Write + Set_Parameter("VMinNorm", FloatToStr(arg)); + break; + case 34: // Load.VMinpu Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->Vminpu; + } + break; + case 35: // Load.VMinpu Write + Set_Parameter("VMinpu", FloatToStr(arg)); + break; + case 36: // Load.xfKVA Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->FConnectedkVA; + } + break; + case 37: // Load.XfKVA Write NOT SURE- CHECK + Set_Parameter("XfKVA", FloatToStr(arg)); + break; + case 38: // Load.xneut Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->Xneut; + } + break; + case 39: // Load.Xneut Write + Set_Parameter("Xneut", FloatToStr(arg)); + break; + case 40: // Load.PctSeriesRL Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->puSeriesRL * 100; + } + break; + case 41: // Load.PctSeriesRL Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->puSeriesRL = arg / 100.0; + } + break; + case 42: // Load.RelWeight Read + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + result = pLoad->RelWeighting; + } + break; + case 43: // Load.RelWeight Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + pLoad->RelWeighting = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall DSSLoadsS(int mode, char* arg) +{ + TDSSCktElement* pload = {}; + TLoadObj* Load = {}; + int ActiveSave = 0; + String S = arg ? arg : ""; + bool Found = false; + string result = ""; + + switch (mode) + { + case 0: // Load.Name Read + result =""; + Load = ActiveLoad(); + if (Load != nullptr) + { + result =Load->get_Name(); + } + break; + case 1: // Load.Name Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Loads; + Found = false; + ActiveSave = with0.get_myActiveItem(); + pload = (TDSSCktElement*) with0.Get_First(); + while (pload != NULL && !Found) + { + if (CompareText(pload->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pload); + Found = true; + break; + } + pload = (TDSSCktElement*) with0.Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Load \"" + S + "\" Not Found in Active Circuit.", 5003); + pload = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Loads.Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pload); + } + } + result =""; + break; + case 2: // Load.CVRCurve Read + Load = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (Load != nullptr) + result =Load->CVRshape; + break; + case 3: // Load.CVRCurve Write + Set_Parameter("CVRcurve", S); + result =""; + break; + case 4: // Load.Daily Read + Load = ActiveLoad(); + if (Load != nullptr) + result =Load->DailyShape; + break; + case 5: // Load.Daily Write + Set_Parameter("Daily", S); + result =""; + break; + case 6: // Load.Duty Read + Load = ActiveLoad(); + if (Load != nullptr) + result =Load->DutyShape; + break; + case 7: // Load.Duty Write + Set_Parameter("Duty",S); + result =""; + break; + case 8: // Load.spectrum Read + Load = ActiveLoad(); + if (Load != nullptr) + result =Load->Spectrum; + break; + case 9: // Load.spectrum Write + Set_Parameter("Spectrum", S); + break; + case 10: // Load.yearly Read + Load = ActiveLoad(); + if (Load != nullptr) + result =Load->YearlyShape; + break; + case 11: // Load.yearly Write + Set_Parameter("Yearly", S); + break; + case 12: // Load.Growth Read + Load = ActiveLoad(); + if (Load != nullptr) + result =Load->GrowthShape; + break; + case 13: // Load.Growth Write + Set_Parameter("Growth", S); + result =""; + break; + case 14: // Load.sensor Read + result =""; + pload = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (pload != nullptr && pload->HasSensorObj) + result =Load->SensorObj->ElementName; + break; + default: + result ="Error"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall DSSLoadsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + + TLoadObj* pLoad = {}; + int k = 0, + i = 0, + LoopLimit = 0; + double* pDouble = {}; + switch (mode) + { + case 0: // Loads.AllNames + *myType = 4; // String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Loads.NumInList > 0) + { + pLoad = (TLoadObj*)with0->Loads.Get_First(); + while (ASSIGNED(pLoad)) + { + WriteStr2Array(pLoad->get_Name()); + WriteStr2Array(Char0()); + pLoad = (TLoadObj*)with0->Loads.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: // Loads.ZIPV - Read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + if (ASSIGNED(pLoad)) + { + if (pLoad->FnZIPV >= 1) + { + myDblArray.resize(pLoad->FnZIPV); + for (k = 0; k <= (pLoad->FnZIPV - 1); k++) + myDblArray[k] = pLoad->ZIPV[k]; + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + + break; + case 2: // Loads.ZIPV - Write + pLoad = (TLoadObj*)ActiveCircuit[ActiveActor]->Loads.Get_Active(); + *myType = 2; // Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLoad->SetZIPVSize(7); + if (*mySize > 7) + LoopLimit = 6; + else + LoopLimit = *mySize - 1; + pDouble = *(double**)myPtr; + for (i = 0; i <= LoopLimit; i++) + { + pLoad->ZIPV[k] = *pDouble; + k++; + pDouble++; + } + } + *mySize = k; + break; + + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + + } + +} + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the Capacitors interface for the DLL +//-------------------------------------------------------------------------------- +TCapacitorObj* __stdcall ActiveCapacitor() +{ + TCapacitorObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TCapacitorObj*)ActiveCircuit[ActiveActor]->ShuntCapacitors.Get_Active(); + } + return result; +} + +void Set_Parameter_Capacitor(string parm, string val) +{ + string mycmd = ""; + if (!ActiveCircuit[ActiveActor]) + return; + SolutionAbort = false; + auto with0 = ActiveCircuit[ActiveActor]; + mycmd = Format("capacitor.%s.%s=%s", ActiveCapacitor()->get_Name().c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); +} + +// ****************************** int type properties************************* +int __stdcall CapacitorsI(int mode, int arg) +{ + TCapacitorObj* elem; + TPointerList* lst = nullptr; + int i; + int result = 0; + switch (mode) + { + case 0: // Capacitors.NumSteps read + elem = ActiveCapacitor(); + if (elem != nullptr) + result = elem->Get_FNumSteps(); + break; + case 1: // Capacitors.NumSteps write + Set_Parameter_Capacitor("numsteps", std::to_string(arg)); + break; + case 2: // Capacitors.IsDelta read + elem = ActiveCapacitor(); + if (elem != nullptr) + { + if (elem->Connection > 0) + result = 1; + } + break; + case 3: // Capacitors.IsDelta write + elem = ActiveCapacitor(); + if (elem != nullptr) + elem->Connection = static_cast(arg); + break; + case 4: // Capacitors.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->ShuntCapacitors; + elem = (TCapacitorObj*)lst->Get_First(); + while (elem != nullptr) + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + break; + } + else + elem = (TCapacitorObj*)lst->Get_Next(); + } + } + break; + case 5: // Capacitors.Next + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->ShuntCapacitors; + elem = (TCapacitorObj*)lst->Get_Next(); + while (elem != nullptr) + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->get_myActiveItem(); + break; + } + else + elem = (TCapacitorObj*)lst->Get_Next(); + } + } + break; + case 6: // Capacitors.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + result = ActiveCircuit[ActiveActor]->ShuntCapacitors.get_myNumList(); + break; + case 7: // Capacitors.AddStep + elem = ActiveCapacitor(); + if (elem != nullptr) + { + if (elem->AddStep(ActiveActor)) + result = 1; + } + break; + case 8: // Capacitors.SubtractStep + elem = ActiveCapacitor(); + if (elem != nullptr) + { + if (elem->SubtractStep(ActiveActor)) + result = 1; + } + break; + case 9: // Capacitors.AvailableSteps + elem = ActiveCapacitor(); + if (elem != nullptr) + result = elem->AvailableSteps(); + break; + case 10: // Capacitors.Open + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = ActiveCapacitor(); + if (elem != nullptr) + { + for (i = 1; i <= elem->Get_FNumSteps(); i++) + elem->set_States(i, ActiveActor, 0); + } + } + break; + case 11: // Capacitors.Close + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = ActiveCapacitor(); + if (elem != nullptr) + { + elem->ActiveTerminal = &(elem->Terminals[0]); // make sure terminal 1 is closed + elem->Set_ConductorClosed(0, ActiveActor, true); // closes all phases + for (i = 1; i <= elem->Get_FNumSteps(); i++) + elem->set_States(i, ActiveActor, 1); + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall CapacitorsF(int mode, double arg) +{ + TCapacitorObj* elem; + double result = 0.0; // Default return value + switch (mode) + { + case 0: // Capacitors.kV read + result = 0.0; + elem = ActiveCapacitor(); + if (elem != nullptr) + result = elem->Get_kvrating(); + break; + case 1: // Capacitors.kV write + Set_Parameter_Capacitor("kv", std::to_string(arg)); + break; + case 2: // Capacitors.kvar read + result = 0.0; + elem = ActiveCapacitor(); + if (elem != nullptr) + result = elem->Get_Ftotalkvar(); + break; + case 3: // Capacitors.kvar write + Set_Parameter_Capacitor("kvar", std::to_string(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//*******************************String type properties*************************** +const char* __stdcall CapacitorsS(int mode, const char* arg) +{ + TCapacitorObj* elem = nullptr; + int ActiveSave = 0; + bool Found = false; + TPointerList* lst = nullptr; + int k = 0; + string S = "", + result = "0"; + + switch (mode) + { + case 0: // Capacitors.Name read + result = ""; + elem = ActiveCapacitor(); + if (elem != nullptr) + result = elem->get_Name().c_str(); + break; + case 1: // Capacitors.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->ShuntCapacitors; + S = arg; + Found = false; + ActiveSave = lst->get_myActiveItem(); + elem = (TCapacitorObj*) lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TCapacitorObj*)lst->Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Capacitor \"" + S + "\" Not Found in Active Circuit.", 5003); + elem = (TCapacitorObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall CapacitorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TCapacitorObj* elem = nullptr; + int ActiveSave = 0; + string S = ""; + bool Found = false; + TPointerList* lst = nullptr; + int k = 0, + i = 0, + LoopLimit = 0; + int* Pint = nullptr; + + switch (mode) + { + case 0: // Capacitors.AllNames + myStrArray.resize(0); + *mySize = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->ShuntCapacitors.get_myNumList() > 0) + { + myStrArray.resize(0); + lst = &with0->ShuntCapacitors; + k = 0; + elem = (TCapacitorObj*)lst->Get_First(); + while (elem != nullptr) + { + S = elem->get_Name(); + WriteStr2Array(S); + WriteStr2Array(Char0()); + elem = (TCapacitorObj*) lst->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myType = 4; //String + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: //Capacitors.States read + myIntArray.resize(1); + myIntArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = ActiveCapacitor(); + if (elem != nullptr) + { + myIntArray.resize(elem->Get_FNumSteps()); + k = 0; + for (i = 1; i <= elem->Get_FNumSteps(); i++) + { + myIntArray[k] = elem->get_States(i, ActiveActor); + k++; + } + } + } + *myType = 1; // Integer + *mySize = 4 * (elem->Get_FNumSteps()); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 2: // Capacitors.States write + elem = ActiveCapacitor(); + if (elem != nullptr) + { + // allocate space based on present value of NumSteps + // setting NumSteps allocates the memory + // only put as many elements as proviced up to nZIPV + // myIntArray := myPointer; + k = 0; + Pint = *(int**)myPtr; + for (i = 1; i <= elem->Get_FNumSteps(); i++) + { + elem->set_States(i, ActiveActor, *Pint); + Pint++; + } + elem->FindLastStepInService(); + } + *myType = 1; //Integer + break; + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = 0; + break; + + } +} + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the ActiveClass interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall ActiveClassI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // ActiveClass.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr && ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_First(); // sets active objects + } + break; + case 1: // ActiveClass.Next + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr && ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_Next(); // sets active objects + } + break; + case 2: // ActiveClass.NumElements + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_ElementCount(); + } + break; + case 3: // ActiveClass.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_ElementCount(); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall ActiveClassS(int mode, char* arg) +{ + TDSSObject* pelem = nullptr; + string result = ""; + + switch (mode) + { + case 0: // ActiveClass.Name Read + if (ASSIGNED(ActiveDSSObject[ActiveActor])) + { + result = ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->get_Name(); + } + break; + case 1: // ActiveClass.Name Write + if (ASSIGNED(ActiveDSSClass[ActiveActor])) + { + pelem = (TDSSObject*) ActiveDSSClass[ActiveActor]->Find(string(arg)); + if (pelem != nullptr) + { + if (dynamic_cast(pelem) != nullptr) //ASK + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)pelem); //sets ActiveDSSobject + } + else + ActiveDSSObject[ActiveActor] = pelem; + } + } + break; + case 2: // ActiveClass.ActiveClassName + if (ASSIGNED(ActiveDSSClass[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Class_Name; + } + else + result = ""; + break; + case 3: // ActiveClass.ActiveClassParent + if (ASSIGNED(ActiveDSSClass[ActiveActor])) + { + result = "Generic Object"; + if (dynamic_cast(ActiveDSSClass[ActiveActor]) != nullptr) + result = "TPCClass"; + if (dynamic_cast(ActiveDSSClass[ActiveActor]) != nullptr) + result = "TPDClass"; + if (dynamic_cast(ActiveDSSClass[ActiveActor]) != nullptr) + result = "TMeterClass"; + if (dynamic_cast(ActiveDSSClass[ActiveActor]) != nullptr) + result = "TControlClass"; + } + else + result = "Parent Class unknonwn"; + break; + default: + result = "Error, parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall ActiveClassV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int idx = 0, + i = 0; + string S = ""; + switch (mode) + { + case 0: + myStrArray.resize(0); + *mySize = 0; + + if (ActiveCircuit[ActiveActor] != nullptr && ASSIGNED(ActiveDSSClass[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + myStrArray.resize(0); + idx = ActiveDSSClass[ActiveActor]->Get_First(); + while (idx > 0) + { + S = ((TDSSObject*)ActiveDSSObject[ActiveActor])->LName; + WriteStr2Array(S); + WriteStr2Array(Char0()); + idx = ActiveDSSClass[ActiveActor]->Get_Next(); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myType = 4; // String + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *myType = -1; + break; + } + +} + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the Bus interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Bus Functions************************* +bool CheckBusReference(TDSSCktElement* CktElement, int BusReference) +{ + int i = 0; + bool result = false; + + auto with0 = CktElement; + for (int i = 0; i < with0->Fnterms; i++) + { + if (with0->Terminals[i].BusRef == BusReference) + { + result = true; + break; + } + } + return result; +} +// ******************************int type properties************************* +int __stdcall BUSI(int mode, int arg) +{ + int result = 0; + + switch (mode) + { + case 0: // Bus.NumNodes + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->get_FNumNodesThisBus(); + } + } + break; + case 1: // Bus.ZscRefresh + result = 0; // Init in case of failure + if (ExecHelper::DoZscRefresh(ActiveActor) == 0) + { + result = 1; + } + break; + case 2: // Bus.Coorddefined + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + result = 1; + } + } + } + break; + case 3: // Bus.GetUniqueNodeNumber + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = Utilities::GetUniqueNodeNumber(with0->BusList.Get(with0->ActiveBusIndex + 1), arg); + } + } + break; + case 4: // Bus.N_Customers + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = (with0->Buses[with0->ActiveBusIndex]->BusTotalNumCustomers); + } + } + break; + case 5: // Bus.SectionID + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = (with0->Buses[with0->ActiveBusIndex]->BusSectionID); + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall BUSF(int mode, double arg) +{ + double result = 0.0; + + switch (mode) + { + case 0: // Bus.kVBase + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->kVBase; + } + } + break; + case 1: // Bus.X Read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + result = with0->Buses[with0->ActiveBusIndex]->x; + } + } + } + break; + case 2: // Bus.X Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + with0->Buses[with0->ActiveBusIndex]->x = arg; + } + } + result = 0; + } + break; + case 3: // Bus.Y Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + result = with0->Buses[with0->ActiveBusIndex]->y; + } + } + } + break; + case 4: // Bus.Y Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + with0->Buses[with0->ActiveBusIndex]->CoordDefined = true; + with0->Buses[with0->ActiveBusIndex]->y = arg; + } + result = 0.0; + } + break; + case 5: // Bus.Distance + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->DistFromMeter; + } + } + break; + case 6: // Bus.Lambda + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->BusFltRate; + } + } + break; + case 7: // Bus.N_Interrupts + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->Bus_Num_Interrupt; + } + } + break; + case 8: // Bus.Int_Duration + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->Bus_Int_Duration; + } + } + break; + case 9: // Bus.Cust_interrupts + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->BusCustInterrupts; + } + } + break; + case 10: // Bus.Cust_duration + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->BusCustDurations; + } + } + break; + case 11: // Bus.Totalmiles + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->Buses[with0->ActiveBusIndex]->BusTotalMiles; + } + } + break; + case 12: // Bus.Latitude read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + result = with0->Buses[with0->ActiveBusIndex]->lat; + } + } + } + break; + case 13: // Bus.Latitude Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + with0->Buses[with0->ActiveBusIndex]->CoordDefined = true; + with0->Buses[with0->ActiveBusIndex]->lat = arg; + } + result = 0.0; + } + break; + case 14: // Bus.Longitude read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->CoordDefined) + { + result = with0->Buses[with0->ActiveBusIndex]->longitude; + } + } + } + break; + case 15: // Bus.Longitude Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + with0->Buses[with0->ActiveBusIndex]->CoordDefined = true; + with0->Buses[with0->ActiveBusIndex]->longitude = arg; + } + result = 0.0; + } + break; + + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall BUSS(int mode, char* arg) +{ + string result = "0"; + + switch (mode) + { + case 0: // Bus.Name + result = ""; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + result = with0->BusList.Get(with0->ActiveBusIndex + 1); + } + } + break; + default: + result = "Error, Parameter non recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall BUSV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int BusReference = 0, + k = 0, + LoadCount = 0, + LineCount = 0, + Nvalues = 0, + Norder = 0, + i = 0, + iV = 0, + NodeIdxi = 0, + jj = 0, + NodeIdxj = 0, + Nelements = 0, + j = 0, + NodeIdx = 0, + Voc = 0, + Z = 0, + Y1 = 0; + complex Isc = cmplx(0, 0), + Volts = cmplx(0, 0); + TDSSBus* pBus = nullptr; + complex V012[4] = { cmplx(0,0),cmplx(0,0) , cmplx(0,0), cmplx(0,0) }, + Vph[4] = { cmplx(0,0),cmplx(0,0) , cmplx(0,0), cmplx(0,0) }; + double BaseFactor = 0.0; + polar voltsp = {}; + TDSSCktElement* pElem = nullptr; + TcMatrix* Zsc012Temp = nullptr; + pDoubleArray pValues = nullptr; + DynStringArray myPXEList; + String S = ""; + + + switch (mode) + { + case 0: // Bus.Voltages + *myType = 3; //Complex + if (ActiveCircuit[ActiveActor] == nullptr || ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + } + else + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + myCmplxArray.resize(0); + pBus = with0->Buses[with0->ActiveBusIndex]; + + Nvalues = pBus->FNumNodesThisBus; + jj = 1; + auto with0 = pBus; + for (i = 0; i < Nvalues; i++) + { + do + { + NodeIdx = with0->FindIdx(jj); // Get the index of the Node that matches jj + jj++; + } + while (NodeIdx <= 0); + myCmplxArray.push_back(ActiveCircuit[ActiveActor]->Solution->NodeV[with0->GetRef(NodeIdx)]); + } + } + } + *mySize = myCmplxArray.size() * sizeof(complex); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 1: // Bus.SeqVoltages + *myType = 2; + if (ActiveCircuit[ActiveActor] == nullptr || ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + myDblArray.resize(1); + myDblArray[0] = 0.0; + } + else + { + auto with0 = ActiveCircuit[ActiveActor]; + myDblArray.resize(3); + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + Nvalues = with0->Buses[with0->ActiveBusIndex]->FNumNodesThisBus; + if (Nvalues > 3) + Nvalues = 3; + + if (Nvalues != 3) + { + for (int i = 1; i <= 3; i++) + { + myDblArray[i - 1] = -1;// Signify seq voltages n/A for less then 3 phases + } + } + else + { + iV = 0; + for (i = 1; i <= 3; i++) + { + Vph[i] = with0->Solution->NodeV[with0->Buses[with0->ActiveBusIndex]->Find(i)]; + } + Phase2SymComp(&Vph[1], &V012[1]); // Compute Symmetrical components + for (i = 1; i <= 3; i++) { + myDblArray[iV] = cabs(V012[i]); + iV++; + } + } + + } + + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(double); + break; + case 2: // Bus.Nodes + *myType = 1; + if (ActiveCircuit[ActiveActor] == nullptr) + { + myIntArray.resize(1); + myIntArray[0] = 0; + } + else + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + auto with0 = pBus; + myIntArray.resize(pBus->FNumNodesThisBus); + Nvalues = pBus->FNumNodesThisBus; + iV = 0; + jj = 1; + for (i = 1; i <= Nvalues ; i++) + { + do + { + NodeIdx = with0->FindIdx(jj); + jj++; + } + while (NodeIdx <= 0); + myIntArray[iV] = with0->GetNum(NodeIdx); + } + iV++; + } + } + *myPtr = (uintptr_t)(void*)(myIntArray.data()); + *mySize = myIntArray.size() * sizeof(int); + break; + case 3: // Bus.Voc + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (!(with0->Buses[with0->ActiveBusIndex]->VBus.empty())) + { + Nvalues = with0->Buses[with0->ActiveBusIndex]->FNumNodesThisBus; + myCmplxArray.resize(Nvalues); + for (i = 1; i <= Nvalues; i++) + { + myCmplxArray[i - 1] = with0->Buses[with0->ActiveBusIndex]->VBus[i - 1]; + } + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 4: // Bus.Isc + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + Nvalues = with0->Buses[with0->ActiveBusIndex]->FNumNodesThisBus; + myCmplxArray.resize(Nvalues, CZero); + if (!(with0->Buses[with0->ActiveBusIndex]->BusCurrent.empty())) + { + for (i = 1; i <= Nvalues; i++) + { + myCmplxArray[i - 1] = with0->Buses[with0->ActiveBusIndex]->BusCurrent[i - 1]; + } + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 5: // Bus.PuVoltages + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + Nvalues = pBus->FNumNodesThisBus; + myCmplxArray.resize(Nvalues); + iV = 0; + jj = 1; + if (pBus->kVBase > 0.0) + { + BaseFactor = 1000.0 * pBus->kVBase; + } + else + BaseFactor = 1.0; + for (i = 1; i <= Nvalues; i++) + { + // this code so nodes come out in order from smallest to larges + do + { + NodeIdx = pBus->FindIdx(jj); + jj++; + } + while (NodeIdx <= 0); + myCmplxArray[iV] = cdivreal(ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(NodeIdx)], BaseFactor); + iV++; + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 6: // Bus.ZscMatrix + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + try + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->Zsc.Norder != 0) + { + Nelements = with0->Buses[with0->ActiveBusIndex]->Zsc.Norder; + myCmplxArray.resize(Nelements * Nelements); + iV = 0; + auto with0 = ActiveCircuit[ActiveActor]->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex]; + for (i = 1; i <= Nelements; i++) + { + for (j = 1; j <= Nelements; j++) + { + myCmplxArray[iV] = with0->Zsc.GetElement(i, j); + iV++; + } + } + } + } + + } + catch (const std::exception &E) + { + DoSimpleMsg("ZscMatrix Error: " + (std::string)E.what() + CRLF, 5016); + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 7: // Bus.Zsc1 + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + myCmplxArray[0] = with0->Buses[with0->ActiveBusIndex]->Get_Zsc1(); + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 8: // Bus.Zsc0 + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + myCmplxArray[0] = with0->Buses[with0->ActiveBusIndex]->Get_Zsc0(); + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 9: // Bus.YscMatrix + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + try + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + if (with0->Buses[with0->ActiveBusIndex]->Ysc.Norder != 0) + { + Nelements = with0->Buses[with0->ActiveBusIndex]->Ysc.Norder; + myCmplxArray.resize(Nelements * Nelements); + iV = 0; + auto with0 = ActiveCircuit[ActiveActor]->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex]; + for (i = 1; i <= Nelements; i++) + { + for (j = 1; j <= Nelements; j++) + { + myCmplxArray[iV] = with0->Ysc.GetElement(i, j); + iV++; + } + } + } + } + + } + catch (const std::exception& E) + { + DoSimpleMsg("ZscMatrix Error: " + (std::string)E.what() + CRLF, 5017); + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 10: // Bus.CplxSeqVoltages + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + myCmplxArray.resize(3); + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + Nvalues = with0->Buses[with0->ActiveBusIndex]->FNumNodesThisBus; + if (Nvalues > 3) + Nvalues = 3; + + if (Nvalues != 3) + { + for (int i = 0; i <= 2; i++) + { + myCmplxArray[i] = cmplx(-1.0, -1.0);// Signify seq voltages n/A for less then 3 phases + } + } + else + { + iV = 0; + for (i = 1; i <= 3; i++) + { + Vph[i] = with0->Solution->NodeV[with0->Buses[with0->ActiveBusIndex]->Find(i)]; + } + Phase2SymComp(&Vph[1], &V012[1]); // Compute Symmetrical components + for (i = 1; i <= 3; i++) { + myCmplxArray[iV] = V012[i]; + iV++; + } + } + + } + + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 11: // Bus.VLL + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + Nvalues = pBus->FNumNodesThisBus; + myCmplxArray.resize(Nvalues); + iV = 0; + jj = 1; + if (Nvalues > 3) + Nvalues = 3; + if (Nvalues > 1) + { + if (Nvalues == 2) + Nvalues = 1;// only one L-L voltage if 2 phase + myCmplxArray.resize((2 * Nvalues) - 1); + iV = 0; + auto with1 = pBus; + if (with1->kVBase > 0.0) + { + BaseFactor = 1000.0 * with1->kVBase; + } + else + BaseFactor = 1.0; + for (i = 1; i <= Nvalues; i++) // for 2- or 3-phases + { + // this code assumes the nodes are ordered 1, 2, 3 + //------------------------------------------------------------------------------------------------ + // This section was added to prevent measuring using disconnected nodes, for example, if the + // bus has 2 nodes but those are 1 and 3, that will bring a problem. + jj = i; + do + { + NodeIdxi = with1->FindIdx(jj);// Get the index of the Node that matches i + jj++; + } + while (NodeIdxi <= 0); + do + { + NodeIdxj = with1->FindIdx(jj); // Get the index of the Node that matches i + if (jj > 3) + jj = 1; + else + jj++; + } + while (NodeIdxj <= 0); + Volts = csub(with0->Solution->NodeV[with1->GetRef(NodeIdxi)], with0->Solution->NodeV[with1->GetRef(NodeIdxj)]); + myCmplxArray[iV] = Volts; + iV++; + } + } + else // for 1-phase buses, do not attempt to compute. + { + myCmplxArray.resize(1); // just return -1"s in array + myCmplxArray[0] = cmplx(-99999.0, 0); + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 12: // Bus.PuVLL + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + Nvalues = pBus->FNumNodesThisBus; + if (Nvalues > 3) + Nvalues = 3; + if (Nvalues > 1) + { + if (Nvalues == 2) Nvalues = 1;// only one L-L voltage if 2 phase + myCmplxArray.resize((2 * Nvalues) - 1); + iV = 0; + auto with0 = pBus; + if (with0->kVBase > 0.0) + { + BaseFactor = 1000.0 * with0->kVBase * sqrt(3); + } + else + BaseFactor = 1.0; + for (i = 1; i <= Nvalues; i++) // for 2- or 3-phases + { + // this code assumes the nodes are ordered 1, 2, 3 + //------------------------------------------------------------------------------------------------ + // This section was added to prevent measuring using disconnected nodes, for example, if the + // bus has 2 nodes but those are 1 and 3, that will bring a problem. + jj = i; + do + { + NodeIdxi = with0->FindIdx(jj);// Get the index of the Node that matches i + jj++; + } + while (NodeIdxi <= 0); + do + { + NodeIdxj = with0->FindIdx(jj); // Get the index of the Node that matches i + if (jj > 3) + jj = 1; + else + jj++; + } + while (NodeIdxj <= 0); + Volts = csub(ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(NodeIdxi)], ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(NodeIdxj)]); + myCmplxArray[iV] = cdivreal(Volts, BaseFactor); + iV++; + } + + } + else // for 1-phase buses, do not attempt to compute. + { + myCmplxArray.resize(1); // just return -1"s in array + myCmplxArray[0] = cmplx(-99999.0, 0); + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 13: // Bus.VMagAngle + *myType = 3; + myPolarArray.resize(1); + myPolarArray[0] = ctopolar(CZero); + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + Nvalues = pBus->FNumNodesThisBus; + myPolarArray.resize(Nvalues); + iV = 0; + jj = 1; + for (i = 1; i <= Nvalues; i++) + { + // this code so nodes come out in order from smallest to larges + do + { + NodeIdx = pBus->FindIdx(jj); + jj++; + } + while (NodeIdx <= 0); + voltsp = ctopolardeg(ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(NodeIdx)]); + myPolarArray[iV] = voltsp; + iV++; + } + } + } + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + *mySize = sizeof(polar) * myPolarArray.size(); + break; + case 14: // Bus.PuVMagAngle + *myType = 3; + myPolarArray.resize(1); + myPolarArray[0] = ctopolar(CZero); + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + pBus = with0->Buses[with0->ActiveBusIndex]; + Nvalues = pBus->FNumNodesThisBus; + myPolarArray.resize(Nvalues); + iV = 0; + jj = 1; + if (pBus->kVBase > 0.0) BaseFactor = 1000.0 * pBus->kVBase; + else BaseFactor = 1.0; + for (i = 1; i <= Nvalues; i++) + { + do + { + NodeIdx = pBus->FindIdx(jj); + jj++; + } + while (NodeIdx <= 0); + myPolarArray[iV] = ctopolardeg(ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(NodeIdx)]); + myPolarArray[iV].mag = myPolarArray[iV].mag / BaseFactor; + iV++; + } + } + } + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + *mySize = sizeof(polar) * myPolarArray.size(); + break; + case 15: // Bus.LineList + *myType = 4; // String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + BusReference = with0->ActiveBusIndex; + LineCount = 0; + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (ASSIGNED(pElem)) + { + if (CheckBusReference(pElem, BusReference)) + { + LineCount++; + } + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + if (LineCount > 0) + { + myStrArray.resize(0); + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (ASSIGNED(pElem)) + { + if (CheckBusReference(pElem, BusReference)) + { + S = "LINE." + pElem->LName; + WriteStr2Array(S); + WriteStr2Array(Char0()); + } + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 16: // Bus.LoadList + *myType = 4; // String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + BusReference = with0->ActiveBusIndex; + LoadCount = 0; + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Loads.Get_First(); + while (ASSIGNED(pElem)) + { + if (CheckBusReference(pElem, BusReference)) + { + LoadCount++; + } + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + if (LoadCount > 0) + { + myStrArray.resize(0); + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Loads.Get_First(); + while (ASSIGNED(pElem)) + { + if (CheckBusReference(pElem, BusReference)) + { + S = "LOAD." + pElem->LName; + WriteStr2Array(S); + WriteStr2Array(Char0()); + } + pElem = (TDSSCktElement*)ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 17: // Bus.ZSC012Matrix + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pBus = with0->Buses[with0->ActiveBusIndex]; + if (pBus->FNumNodesThisBus == 3) + { + Nvalues = Sqr(pBus->FNumNodesThisBus) * 2; // Should be 9 complex numbers + // Compute ZSC012 for 3-phase buses else leave it zeros + // ZSC012 = Ap2s Zsc As2p + Zsc012Temp = pBus->Zsc.MtrxMult(As2p); // temp for intermediate result + if (pBus->Zsc012.Norder != 0) + { + pBus->Zsc012 = TcMatrix(0); + } + TcMatrix* tmp = Ap2s->MtrxMult(Zsc012Temp); + if (tmp != nullptr) + { + pBus->Zsc012 = *tmp; + free(tmp); + //Return all the elements of ZSC012 + pValues = pDoubleArray(pBus->Zsc012.GetValuesArrayPtr(Norder)); + myDblArray.resize(Nvalues); + for (i = 0; i < Nvalues; i++) + { + myDblArray[i] = pValues[i]; + } + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 18: // Bus.AllPCEatBus + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + myPXEList = with0->getPCEatBus(with0->BusList.Get(with0->ActiveBusIndex + 1)); + myStrArray.resize(0); + for (i = 0; i < myPXEList.size(); i++) + { + if (!myPXEList.empty()) + { + WriteStr2Array(myPXEList[i]); + WriteStr2Array(Char0()); + } + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 19: // Bus.AllPDEatBus + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->ActiveBusIndex >= 0) && (with0->ActiveBusIndex < with0->NumBuses)) + { + myPXEList = with0->getPDEatBus(with0->BusList.Get(with0->ActiveBusIndex + 1)); + myStrArray.resize(0); + for (i = 0; i < myPXEList.size(); i++) + { + if (!myPXEList.empty()) + { + WriteStr2Array(myPXEList[i]); + WriteStr2Array(Char0()); + } + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//**************************************************************************************************************** +//-------------------------------------------------------------------------------- +// Implements the CapControl interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************CapControls Functions************************* +TCapControlObj* ActiveCapControl() +{ + TCapControlObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TCapControlObj*) ActiveCircuit[ActiveActor]->CapControls.Get_Active(); + } + return result; +} +void Set_ParameterACC(string parm, string val) +{ + string mycmd = ""; + if (not(ASSIGNED(ActiveCircuit[ActiveActor]))) + { + // Or break? + } + else + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("capcontrol.%s.%s=%s", ActiveCapControl()->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ****************************** int type properties************************* +int __stdcall CapControlsI(int mode, int arg) +{ + TCapControlObj* elem = nullptr; + TPointerList *lst = nullptr; + + int result = 0; // Default return value + switch (mode) + { + case 0: // CapControls.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->CapControls; + elem = (TCapControlObj*)lst->Get_First(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + } + else elem = (TCapControlObj*) lst->Get_Next(); + } while (!(result == 1 || elem == nullptr)); + } + } + break; + case 1: // CapControls.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->CapControls; + elem = (TCapControlObj*)lst->Get_Next(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->get_myActiveItem(); + } + else elem = (TCapControlObj*)lst->Get_Next(); + } while (!(result > 0 || elem == nullptr)); + } + } + break; + case 2: // CapControls.Mode read + result = 1; + elem = ActiveCapControl(); + if (elem != nullptr) + { + switch (elem->get_ControlType()) + { + case CURRENTCONTROL: + result = 0; + break; + case VOLTAGECONTROL: + result = 1; + break; + case KVARCONTROL: + result = 2; + break; + case TIMECONTROL: + result = 3; + break; + case PFCONTROL: + case USERCONTROL: // both assign 4 to result + result = 4; + break; + default: + result = 1; + break; + } + } + break; + case 3: // CapControls.Mode write + result = 1; + elem = ActiveCapControl(); + if (elem != nullptr) + { + switch (arg) + { + case 0: + elem->set_ControlType(CURRENTCONTROL); + break; + case 1: + elem->set_ControlType(VOLTAGECONTROL); + break; + case 2: + elem->set_ControlType(KVARCONTROL); + break; + case 3: + elem->set_ControlType(TIMECONTROL); + break; + case 4: + elem->set_ControlType(PFCONTROL); + break; + case 5: + elem->set_ControlType(USERCONTROL); + break; + default: + result = -1; + break; + } + } + break; + case 4: // CapControls.MonitoredTerm read + result = 0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->ElementTerminal; + } + break; + case 5: // CapControls.MonitoredTerm write + Set_ParameterACC("Terminal", IntToStr(arg)); + break; + case 6: // CapControls.UseVoltOverride read + result = 0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + if (elem->GetVoverride_Value()) + result = 1; + } + break; + case 7: // CapControls.UseVoltOverride write + if (arg == 1) + Set_ParameterACC("VoltOverride", "Yes"); + else + Set_ParameterACC("VoltOverride", "No"); + break; + case 8: // CapControls.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + result = ActiveCircuit[ActiveActor]->CapControls.get_myNumList(); + break; + + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall CapControlsF(int mode, double arg) +{ + TCapControlObj* elem = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: // CapControls.CTRatio read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetCTRatio_Value(); + } + break; + case 1: // CapControls.CTRatio write + Set_ParameterACC("CTratio", FloatToStr(arg)); + break; + case 2: // CapControls.PTRatio read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetPTRatio_Value(); + } + break; + case 3: // CapControls.PTRatio write + Set_ParameterACC("PTRatio", FloatToStr(arg)); + break; + case 4: // CapControls.ONSetting read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetON_Value(); + } + break; + case 5: // CapControls.ONSetting write + Set_ParameterACC("OnSetting", FloatToStr(arg)); + break; + case 6: // CapControls.OFFSetting read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetOFF_Value(); + } + break; + case 7: // CapControls.OFFSetting write + Set_ParameterACC("OffSetting", FloatToStr(arg)); + break; + case 8: // CapControls.VMax read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetVmax_Value(); + } + break; + case 9: // CapControls.VMax write + Set_ParameterACC("Vmax", FloatToStr(arg)); + break; + case 10: // CapControls.VMin read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetVmin_Value(); + } + break; + case 11: // CapControls.VMin write + Set_ParameterACC("Vmin", FloatToStr(arg)); + break; + case 12: // CapControls.Delay read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetONDelay_Value(); + } + break; + case 13: // CapControls.Delay write + Set_ParameterACC("Delay", FloatToStr(arg)); + break; + case 14: // CapControls.DelayOff read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetOFFDelay_Value(); + } + break; + case 15: // CapControls.DelayOff write + Set_ParameterACC("DelayOff", FloatToStr(arg)); + break; + case 16: // CapControls.DeadTime read + result = 0.0; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->GetDeadTime_Value(); + + } + break; + case 17: // CapControls.DeadTime write + Set_ParameterACC("DeadTime", FloatToStr(arg)); + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall CapControlsS(int mode, char* arg) +{ + TCapControlObj* elem = nullptr; + int ActiveSave = 0; + string S = ""; + bool Found = false; + TPointerList* lst = nullptr; + string result = "0"; + + switch (mode) + { + case 0: // CapControls.Name read + result = ""; + elem = ActiveCapControl(); + if (elem != nullptr) { + result = elem->LName; + } + break; + case 1: // CapControls.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &ActiveCircuit[ActiveActor]->CapControls; + S = arg; + Found = false; + ActiveSave = lst->ActiveItem; + elem = (TCapControlObj*)lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->LName, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TCapControlObj*)lst->Get_Next(); + } + if (!(Found)) + { + DoSimpleMsg("CapControl \"" + S + "\" Not Found in Active Circuit.", 5003); + elem = (TCapControlObj*)lst->Get(ActiveSave); // Restore active Load + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 2: // CapControls.Capacitor read + result = ""; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->ControlledCapacitor->get_Name(); + } + break; + case 3: // CapControls.Capacitor write + Set_ParameterACC("Capacitor", (string)arg); + break; + case 4: // CapControls.MonitoredObj read + result = ""; + elem = ActiveCapControl(); + if (elem != nullptr) + { + result = elem->ElementName; + } + break; + case 5: // CapControls.MonitoredObj write + Set_ParameterACC("Element", (string)arg); + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall CapControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TCapControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int i = 0, + k = 0; + string S; + + switch (mode) + { + case 0: // CapControls.AllNames + *myType = 4; //string + myStrArray.resize(0); + + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->CapControls.get_myNumList() > 0) + { + lst = &with0->CapControls; + myStrArray.resize(0); + k = 0; + elem = (TCapControlObj*)lst->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TCapControlObj*)lst->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Circuit interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall CircuitI(int mode, int arg) +{ + TDSSCktElement* p = nullptr; + TDSSMonitor* Mon = nullptr; + TEnergyMeter* Mtr = nullptr; + int result = 0; + + switch (mode) + { + case 0: // Circuit.NumCktElements + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->NumDevices; + } + break; + case 1: // Circuit.NumBuses + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->NumBuses; + } + break; + case 2: // Circuit.NumNodes + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->NumNodes; + } + break; + case 3: // Circuit.FirstPCElement + if (ActiveCircuit[ActiveActor] != nullptr) + { + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PCElements.Get_First(); + if (p != nullptr) + { + do + { + if (p->FEnabled) + { + result = 1; + } + else + ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } while (!((result == 1) || (p == nullptr))); + } + else + result = 0; + } + break; + case 4: // Circuit.NextPCElement + if (ActiveCircuit[ActiveActor] != nullptr) + { + p = (TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + if (p != nullptr) + { + do + { + if (p->FEnabled) + { + result = ActiveCircuit[ActiveActor]->PCElements.ActiveItem; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(p); + } + else + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } while (!((result > 0) || (p == nullptr))); + } + } + else + result = 0; + break; + case 5: // Circuit.FirstPDElement + if (ActiveCircuit[ActiveActor] != nullptr) + { + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_First(); + if (p != nullptr) + { + do + { + if (p->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(p); + result = 1; + } + else + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } while (!((result == 1) || (p == nullptr))); + } + + } + else + result = 0; + break; + case 6: // Circuit.NextPDElement + if (ActiveCircuit[ActiveActor] != nullptr) + { + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + if (p != nullptr) + { + do + { + if (p->FEnabled) + { + result = ActiveCircuit[ActiveActor]->PDElements.ActiveItem; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(p); + } + else + p = (TDSSCktElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } while (!((result > 0) || (p == nullptr))); + } + } + else + result = 0; + break; + case 7: // Circuit.Sample + MonitorClass[ActiveActor]->SampleAll(ActiveActor); + EnergyMeterClass[ActiveActor]->SampleAll(ActiveActor); + break; + case 8: // Circuit.SaveSample + Mon = (TDSSMonitor*)DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("monitor")); + Mon->SaveAll(ActiveActor); + Mtr = (TEnergyMeter*)DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("energymeter")); + Mtr->SaveAll(ActiveActor); + break; + case 9: // Circuit.SetActiveBusi + result = -1; // Signifies Error + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (arg >= 0 && arg < with0->NumBuses) + { + with0->ActiveBusIndex = arg; + result = 0; + } + } + break; + case 10: // Circuit.FirstElement + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr && ASSIGNED(ActiveDSSClass[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_First(); + } + else + result = 0; + break; + case 11: // Circuit.NextElement + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr && ASSIGNED(ActiveDSSClass[ActiveActor])) + { + result = ActiveDSSClass[ActiveActor]->Get_Next(); + } + else + result = 0; + break; + case 12: // Circuit.UpdateStorage + StorageClass[ActiveActor]->UpdateAll(ActiveActor); + break; + case 13: // Circuit.ParentPDElement + result = 0; + if (dynamic_cast(ActiveCircuit[ActiveActor]->FActiveCktElement) != nullptr) + { + p = ((TPDElement*)ActiveCircuit[ActiveActor]->FActiveCktElement)->ParentPDElement; + if (p != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(p); + result = p->ClassIndex; //should be > 0 + } + } + break; + case 14: // Circuit.EndofTimeStepUpdate + EndOfTimeStepCleanup(ActiveActor); + result = 0; + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall CircuitF(int mode, double arg1, double arg2) +{ + double result = 0.0; //Default return value + switch (mode) // Circuit.Capacity + { + case 0: + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->CapacityStart = arg1; + with0->CapacityIncrement = arg2; + if (with0->ComputeCapacity(ActiveActor)) + { + result = with0->RegisterTotals[3 - 1] + with0->RegisterTotals[19 - 1]; + } + else + result = 0.0; + } + result = 0.0; + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall CircuitS(int mode, char* arg) +{ + int DevClassIndex = 0; + string result = ""; // Default return value + + switch (mode) + { + case 0: // Circuit.Name + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->LName; + } + else + result = ""; + break; + case 1: // Circuit.Disable + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->SetElementActive((string)arg); + if (with0->FActiveCktElement != nullptr) + { + with0->FActiveCktElement->FEnabled = false; + } + } + break; + case 2: // Circuit.Enable + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->SetElementActive((string)arg); + if (with0->FActiveCktElement != nullptr) + { + with0->FActiveCktElement->FEnabled = true; + } + } + break; + case 3: // Circuit.SetActiveElement + result = "-1"; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = IntToStr(ActiveCircuit[ActiveActor]->SetElementActive(arg) - 1);// make zero based to be compatible with collections and variant arrays + } + else + DoSimpleMsg("Create a circuit before trying to set an element active!", 5015); + break; + case 4: // Circuit.SetActiveBus + SetActiveBus(StripExtension((string)arg)); + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = IntToStr(ActiveCircuit[ActiveActor]->ActiveBusIndex); + } + else + result = "-1"; + break; + case 5: // Circuit.SetActiveClass + result = "0"; + DevClassIndex = ClassNames[ActiveActor].Find(arg); + if (DevClassIndex == 0) + { + DoSimpleMsg("Error: Class " + (string)arg + " not found.", 5016); + break; + } + LastClassReferenced[ActiveActor] = DevClassIndex; + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + result = IntToStr(LastClassReferenced[ActiveActor]); + break; + default: + result = "Error, parameter not recognized"; + break; + + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall CircuitV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + complex LossValue{}; + TLineObj* pLine = nullptr; + complex Loss{}; + TTransfObj* pTransf; + TDSSCktElement* pCktElem = {}; + complex Curr= cmplx(0,0), + cPower = cmplx(0,0), + cLoss = cmplx(0, 0), + Volts = cmplx(0, 0); + int Phase = 0, + i = 0, + j = 0, + k = 0, + NodeIdx = 0; + double VoltsD = 0.0, + BaseFactor = 0.0; + string BusName = ""; + + unsignedint nBus{}, + nNZ{}, + NValues{}, + iV{}, + p{}; + klusparseset_t hY{}; + std::vector ColPtr; + std::vector RowIdx; + std::vector cVals; + vector Temp; + vector Temp2; + int* Pint = 0; + + auto with0 = ActiveCircuit[ActiveActor]; + switch (mode) + { + case 0: // Circuit.Losses + *myType = 3; //complex + myCmplxArray.resize(1); + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + myCmplxArray[0] = ActiveCircuit[ActiveActor]->Get_Losses(ActiveActor); + } + else + myCmplxArray[0] = cmplx(0, 0); + *mySize = myCmplxArray.size() * sizeof(complex); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 1: // Circuit.LineLosses + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + pLine = (TLineObj*) with0->Lines.Get_First(); + Loss = cmplx(0.0, 0.0); + while (pLine != nullptr) + { + caccum(Loss, pLine->Get_Losses(ActiveActor)); + pLine = (TLineObj*) with0->Lines.Get_Next(); + } + myCmplxArray[0] = cmulreal(Loss, 0.001); + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 2: // Circuit.SubstationLosses + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + + pTransf = (TTransfObj*) with0->Transformers.Get_First(); + Loss = cmplx(0.0, 0.0); + while (pTransf != nullptr) + { + if (pTransf->IsSubstation) + { + caccum(Loss, pTransf->Get_Losses(ActiveActor)); + pTransf = (TTransfObj*) with0->Transformers.Get_Next(); + } + pTransf = (TTransfObj*) with0->Transformers.Get_Next(); + } + myCmplxArray[0] = cmulreal(Loss, 0.001); + + } + + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(complex); + break; + case 3: // Circuit.TotalPower + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + pCktElem = (TDSSCktElement*)with0->Sources.Get_First(); + cPower = cmplx(0.0, 0.0); + while (pCktElem != nullptr) + { + caccum(cPower, pCktElem->Get_Power(1, ActiveActor)); + pCktElem = (TDSSCktElement*)with0->Sources.Get_Next(); + } + myCmplxArray[0] = cmulreal(cPower, 0.001); + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 4: // Circuit.AllBusVolts + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + myCmplxArray.resize(with0->NumNodes); + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + for (j = 1 ; j <= with0->Buses[i - 1]->FNumNodesThisBus; j++) + { + myCmplxArray[k] = ActiveCircuit[ActiveActor]->Solution->NodeV[(with0->Buses[i - 1]->GetRef(j))]; + k++; + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 5: // Circuit.AllBusVMag + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + myDblArray.resize(with0->NumNodes); + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + for (j = 1; j <= with0->Buses[i - 1]->FNumNodesThisBus; j++) + { + + myDblArray[k] = cabs(with0->Solution->NodeV[with0->Buses[i - 1]->GetRef(j)]); + k++; + } + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 6: // Circuit.AllElementNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + for (i = 1; i <= with0->NumDevices; i++) + { + auto with1 = (TDSSCktElement*)with0->CktElements.Get(i); + WriteStr2Array(with1->ParentClass->Class_Name + "." + with1->LName); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 7: // Circuit.AllBusNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + for (i = 1; i <= with0->NumBuses; i++) + { + WriteStr2Array(with0->BusList.Get(i)); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 8: // Circuit.AllElementLosses + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + myCmplxArray.resize(with0->NumDevices); + k = 0; + pCktElem = (TDSSCktElement*)with0->CktElements.Get_First(); + while (pCktElem != nullptr) + { + myCmplxArray[k] = cmulreal(pCktElem->Get_Losses(ActiveActor), 0.001); + k++; + pCktElem = (TDSSCktElement*)with0->CktElements.Get_Next(); + } + } + + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 9: // Circuit.AllBusVMagPu + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + myDblArray.resize(with0->NumNodes); + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + if (with0->Buses[i - 1]->kVBase > 0.0) + BaseFactor = 1000.0 * with0->Buses[i - 1]->kVBase; + else + BaseFactor = 1.0; + for (j = 1; j <= with0->Buses[i - 1]->FNumNodesThisBus; j++) + { + + myDblArray[k] = cabs(with0->Solution->NodeV[with0->Buses[i - 1]->GetRef(j)]) / BaseFactor; + k++; + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 10: // Circuit.AllNodeNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + for (i = 1; i <= with0->NumBuses; i++) + { + BusName = with0->BusList.Get(i); + + for (j = 1; j <= with0->Buses[i - 1]->FNumNodesThisBus; j++) + { + WriteStr2Array(BusName + "." + IntToStr(with0->Buses[i - 1]->GetNum(j))); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 11: // Circuit.SystemY + // { Return zero length Array if no circuit or no Y matrix} + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] == nullptr) + myCmplxArray[0] = cmplx(0, 0); + else if (ActiveCircuit[ActiveActor]->Solution->hY == 0) + myCmplxArray[0] = cmplx(0, 0); + else + { + + hY = ActiveCircuit[ActiveActor]->Solution->hY; + // get the compressed columns out of KLU + FactorSparseMatrix(hY); + GetNNZ(hY, &nNZ); + GetSize(hY, &nBus); + ColPtr.resize(nBus + 1); + RowIdx.resize(nNZ); + cVals.resize(nNZ); + GetCompressedMatrix(hY, nBus + 1, nNZ, &ColPtr[0], &RowIdx[0], &cVals[0]); + + // allocate a square matrix + NValues = Sqr(with0->NumNodes); + myCmplxArray.resize(NValues);// Make variant array for complex + + // the new way, first set all elements to zero + for (iV = 0; iV < NValues; iV++) + myCmplxArray[iV] = cmplx(0, 0); + // then back-fill the non-zero values + for (j = 0; j <= nBus - 1; j++) /// the zero-based column + { + for (p = ColPtr[j]; p <= ColPtr[j + 1] - 1; p++) + { + i = RowIdx[p]; + iV = i * nBus + j; // the zero-based, row-wise, complex result index + myCmplxArray[iV] = cVals[p]; + } + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 12: // Circuit.AllBusDistances + *myType = 2; + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + myDblArray.resize(with0->NumBuses); + for (i = 1; i <= with0->NumBuses; i++) + { + myDblArray[i - 1] = with0->Buses[i - 1]->DistFromMeter; + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize =myDblArray.size() * sizeof(myDblArray[0]); + break; + case 13: // Circuit.AllNodeDistances + *myType = 2; + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + myDblArray.resize(with0->NumNodes); + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + for (j = 0; j < (with0->Buses[i - 1]->FNumNodesThisBus); j++) + { + myDblArray[k] = with0->Buses[i - 1]->DistFromMeter; + k++; + } + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 14: // Circuit.AllNodeVMagbyPhase + *myType = 2; + myDblArray.resize(1); + myDblArray[0] = 0.0; + Pint = *(int**)myPtr; + Phase = *Pint; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + // Make a Temporary Array big enough to hold all nodes + Temp.resize(with0->NumNodes); + // Find nodes connected to specified phase + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + NodeIdx = with0->Buses[i - 1]->FindIdx(Phase); + if (NodeIdx > 0) + { + Temp[k] = cabs(ActiveCircuit[ActiveActor]->Solution->NodeV[with0->Buses[i - 1]->GetRef(NodeIdx)]); + k++; + } + } + // Assign to result and free temp array + myDblArray.resize(k); + for (i = 0; i < k; i++) + { + myDblArray[i] = Temp[i]; + } + Temp.clear(); + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 15: // Circuit.AllNodeVMagPUByPhase + *myType = 2; + myDblArray.resize(1); + myDblArray[0] = 0.0; + Pint = *(int**)myPtr; + Phase = *Pint; + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + + // Make a Temporary Array big enough to hold all nodes + Temp.resize(with0->NumNodes); + // Find nodes connected to specified phase + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + NodeIdx = with0->Buses[i - 1]->FindIdx(Phase); + if (NodeIdx > 0) + { + if (with0->Buses[i - 1]->kVBase > 0.0) + BaseFactor = 1000.0 * with0->Buses[i - 1]->kVBase; + else + BaseFactor = 1.0; + Temp[k] = cabs(ActiveCircuit[ActiveActor]->Solution->NodeV[with0->Buses[i - 1]->GetRef(NodeIdx)]) / BaseFactor; + k++; + } + } + // Assign to result and free temp array + myDblArray.resize(k); + for (i = 0; i < k; i++) + { + myDblArray[i] = Temp[i]; + } + Temp.clear(); + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 16: // Circuit.AllNodeDistancesByPhase + *myType = 2; + myDblArray.resize(1); + myDblArray[0] = 0.0; + Pint = *(int**)myPtr; + Phase = *Pint; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + // Make a Temporary Array big enough to hold all nodes + Temp .resize(with0->NumNodes); + // Find nodes connected to specified phase + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + NodeIdx = with0->Buses[i - 1]->FindIdx(Phase); + if (NodeIdx > 0) + { + Temp[k] = ActiveCircuit[ActiveActor]->Buses[i - 1]->DistFromMeter; + k++; + } + } + // Assign to result and free temp array + myDblArray.resize(k); + for (i = 0; i < k ; i++) + { + myDblArray[i] = Temp[i]; + } + Temp.clear(); + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + break; + case 17: // Circuit.AllNodeNamesByPhase + *myType = 4; //string + myStrArray.resize(0); + Pint = *(int**)myPtr; + Phase = *Pint; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + // Make a Temporary Array big enough to hold all nodes + Temp2.resize(with0->NumNodes); + // Find nodes connected to specified phase + k = 0; + for (i = 1; i <= with0->NumBuses; i++) + { + NodeIdx = with0->Buses[i - 1]->FindIdx(Phase); + if (NodeIdx > 0)// Node found with this phase number + { + Temp2[k] = Format("%s.%d", with0->BusList.Get(i).c_str(), Phase); + k++; + } + } + // Assign to result and free temp array + for (i = 0; i < k; i++) + { + WriteStr2Array(Temp2[i]); + WriteStr2Array(Char0()); + } + Temp2.clear(); + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 18: // Circuit.YNodeVArray + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = sizeof(myCmplxArray[0]); + + if (ActiveCircuit[ActiveActor] != nullptr && !with0->Solution->NodeV.empty()) + { + *myPtr = (uintptr_t)(void*)&(with0->Solution->NodeV[1]); + *mySize = sizeof(ActiveCircuit[ActiveActor]->Solution->NodeV[1]) * with0->NumNodes; + } + break; + case 19: // Circuit.YNodeOrder + *myType = 4; + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + + for (i = 1; i <= with0->NumNodes; i++) + { + auto with1 = with0->MapNodeToBus[i - 1]; + WriteStr2Array(Format("%s.%-d", UpperCase(with0->BusList.Get(with1.BusRef)).c_str(), with1.NodeNum)); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 20: // Circuit.YCurrents + + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = sizeof(myCmplxArray[0]); + if (with0 != nullptr && !with0->Solution->Currents.empty()) + { + *myPtr = (uintptr_t)(void*)&(with0->Solution->Currents[1]); + *mySize = sizeof(with0->Solution->Currents[1]) * with0->NumNodes; + } + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } + +} + +//-------------------------------------------------------------------------------- +// Implements the CktElement interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************CktElement Functions************************** +void CalcSeqCurrents(TDSSCktElement* pActiveElement, complex* i012) +{ + int Nvalues = 0, + i = 0, + j = 0, + k = 0, + iV = 0; + complex IPh[4] = { cmplx(0,0),cmplx(0,0) , cmplx(0,0) ,cmplx(0,0) }, + I012a[4]= { cmplx(0,0),cmplx(0,0) , cmplx(0,0) ,cmplx(0,0) }; + vector cBuffer; + + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = pActiveElement; + Nvalues = with1->Fnphases; + if (Nvalues != 3) // {Handle non-3 phase elements} + { + if (with1->Fnphases == 1 && (with0->PositiveSequence))// {Handle non-3 phase elements} + { + Nvalues = with1->Fnconds * with1->Fnterms; + cBuffer.resize(Nvalues + 1); + with1->GetCurrents(&cBuffer[1], ActiveActor); + + for (i = 1; i <= with1->Fnterms; i++) + { + iV = 0; + // {Populate only phase 1 quantities in Pos seq} + for (j = 1; j <= with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + i012[iV] = CZero; + i012[iV + 1] = cBuffer[1 + k]; // pos seq is 2nd element in array + i012[iV + 2] = CZero; + iV += 3; + } + } + cBuffer.clear(); + } + else + { + for (i = 1; i <= 3 * with1->Fnterms; i++) + { + i012[i - 1] = cmplx(-1, 0); // Signify n/A + } + } + } + else // for 3-phase elements + { + iV = 0; + Nvalues = with1->Fnconds * with1->Fnterms; + cBuffer.resize(Nvalues); + with1->GetCurrents(&cBuffer[0], ActiveActor); + for (j = 1; j <= with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + Phase2SymComp(&cBuffer[k], &I012a[1]); + for (i = 1; i <= 3; i++) // Stuff it in the result array + { + i012[iV] = I012a[i]; + iV++; + } + + } + cBuffer.clear(); + } +} + +void CalcSeqVoltages(TDSSCktElement* pActiveElement, complex* V012) +{ + int Nvalues = 0, + i = 0, + j = 0, + k = 0, + iV = 0; + complex VPh[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }, + V012a[4]= { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }; + + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = pActiveElement; + Nvalues = with1->Fnphases; + if (Nvalues != 3) // {Handle non-3 phase elements} + { + if ((with1->Fnphases == 1) && (with0->PositiveSequence))// {Handle non-3 phase elements} + { + //Nvalues = with1->Fnconds * with1->Fnterms; + //cBuffer = MyAllocMem(sizeof(cBuffer[1]) * Nvalues); + //with1->GetCurrents(cBuffer, ActiveActor); + + for (i = 1; i <= (with1->Fnterms * 3); i++) + { + V012[i - 1] = CZero;// Initialize Result + iV = 1; // pos seq is 2nd element in array + // {Populate only phase 1 quantities in Pos seq} + for (j = 1; j <= with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + V012[iV] = with0->Solution->NodeV[with1->NodeRef[k]]; + iV += 3; + } + } + } + else //if neither 3 - phase or pos seq model, just put in - 1.0 for each element + { + for (i = 1; i <= 3 * with1->Fnterms; i++) + { + V012[i - 1] = cmplx(-1, 0); // Signify n/A + } + } + } + else // for 3-phase elements + { + iV = 0; + for (j = 1; j <= with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + for (i = 1; i <= 3; i++) + { + VPh[i] = with0->Solution->NodeV[with1->NodeRef[i + k - 1]]; + Phase2SymComp(&VPh[1], &V012a[1]); // Compute Symmetrical components + } + for (i = 1; i <= 3; i++) // Stuff it in the result array + { + V012[iV] = V012a[i]; + iV++; + } + } + } +} + +bool IsPDElement() +{ + bool result = (ActiveCircuit[ActiveActor]->FActiveCktElement->DSSObjType & 3) == PD_ELEMENT; + return result; +} +// ******************************int type properties************************* +int __stdcall CktElementI(int mode, int arg) +{ + int iControl = 0, + result = 0, + i = 0, + count = 0, + low = 0, + numcond = 0, + n = 0, + iV = 0; + TDSSCktElement* pCktElement = nullptr; + TDSSCktElement* ctrl = nullptr; + TPCElement* pPCElem = nullptr; + TPDElement* pPDElem = nullptr; + complex Volts = cmplx(0,0), + cResid = cmplx(0, 0); + bool BData = false; + + + switch (mode) + { + case 0: // CktElement.Numterminals + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->Fnterms; + } + break; + case 1: // CktElement.NumConductors + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->Fnconds; + } + break; + case 2: // CktElement.NumPhases + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->Fnphases; + } + break; + case 3: // CktElement.Open + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + with1->ActiveTerminal = &(with1->Terminals[arg - 1]); + with1->Set_ConductorClosed(3, ActiveActor, false); + } + } + break; + case 4: // CktElement.Close + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + with1->ActiveTerminal = &(with1->Terminals[arg - 1]); + with1->Set_ConductorClosed(3, ActiveActor, true); + } + } + break; + case 5: // CktElement.IsOpen + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = with0->FActiveCktElement; + with1->ActiveTerminal = &(with1->Terminals[arg - 1]); + result = 0; + for (i = 1; i <= with1->Get_NConds(); i++) + { + if (!(with0->FActiveCktElement->Get_ConductorClosed(i, ActiveActor, false))) + { + result = 1; + break; + } + } + } + break; + case 6: // CktElement.NumProperties + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + result = with1->ParentClass->NumProperties; + } + } + break; + case 7: // CktElement.HasSwitchControl + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + ctrl = (TDSSCktElement*)ActiveCircuit[ActiveActor]->FActiveCktElement->ControlElementList.Get_First(); + while (ctrl != nullptr) + { + switch (ctrl->DSSObjType & CLASSMASK) + { + case SWT_CONTROL: + result = 1; + break; + default: + result = 0; + break; + } + if (result == 1) + break; + ctrl = (TDSSCktElement*)ActiveCircuit[ActiveActor]->FActiveCktElement->ControlElementList.Get_Next(); + + } + } + break; + case 8: // CktElement.HasVoltControl + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + ctrl = (TDSSCktElement*)ActiveCircuit[ActiveActor]->FActiveCktElement->ControlElementList.Get_First(); + while (ctrl != nullptr) + { + switch (ctrl->DSSObjType & CLASSMASK) + { + case CAP_CONTROL: + result = 1; + break; + case REG_CONTROL: + result = 1; + break; + default: + result = 0; + break; + } + if (result == 1) + break; + ctrl = (TDSSCktElement*)ActiveCircuit[ActiveActor]->FActiveCktElement->ControlElementList.Get_Next(); + + } + } + break; + case 9: // CktElement.NumControls + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->ControlElementList.NumInList; + } + break; + case 10: // CktElement.OCPDevIndex + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + iControl = 1; + do + {// cycle through the list of controls until we find a fuse, recloser, or relay + pCktElement = (TDSSCktElement*)with0->FActiveCktElement->ControlElementList.Get(iControl); + if (pCktElement != nullptr) + { + switch (pCktElement->DSSObjType & CLASSMASK) + { + case FUSE_CONTROL: + result = longInt(iControl); + break; + case RECLOSER_CONTROL: + result = longInt(iControl); + break; + case RELAY_CONTROL: + result = longInt(iControl); + break; + } + } + iControl++; + } while (!((iControl > with0->FActiveCktElement->ControlElementList.NumInList) || result > 0)); + } + break; + case 11: // CktElement.OCPDevType + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + result = GetOCPDeviceType(with0->FActiveCktElement); // see Utilities + } + break; + case 12: // CktElement.Enabled - read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveCircuit[ActiveActor]->FActiveCktElement->FEnabled) + { + result = 1; + } + } + break; + case 13: // CktElement.Enabled - Write + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (arg > 0) + BData = true; + ActiveCircuit[ActiveActor]->FActiveCktElement->FEnabled = BData; + } + break; + case 14: // CktElement.ActiveVariableidx + result = -1; // Signifies an error; no variable found + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if (with1->DSSObjType == PC_ELEMENT) // BASECLASSMASK Not added + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + if ((arg > 0) && (arg <= pPCElem->NumVariables())) + { + result = 0; // the variable seems to exist + VarIdx = arg; + } + } + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall CktElementF(int mode, double arg) +{ + TDSSCktElement* ctrl = nullptr; + TPCElement* pPCElem = nullptr; + TPDElement* pPDElem = nullptr; + bool BData = false; + int Volts = 0, + i = 0, + count = 0, + low = 0, + numcond = 0, + n = 0, + iV = 0; + complex cResid = cmplx(0,0); + vector cBuffer; + string S = ""; + double result = 0.0; + + switch (mode) + { + case 0: // CktElement.NormalAmps - read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->FActiveCktElement->DSSObjType & 3) == PD_ELEMENT) + { + auto with1 = (TPDElement*)with0->FActiveCktElement; + result = with1->NormAmps; + } + } + break; + case 1: // CktElement.NormalAmps - Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsPDElement()) + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = (TPDElement*)with0->FActiveCktElement; + with1->NormAmps = arg; + } + } + break; + case 2: // CktElement.EmergAmps - read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((with0->FActiveCktElement->DSSObjType & 3) == PD_ELEMENT) + { + auto with1 = (TPDElement*)with0->FActiveCktElement; + result = with1->EmergAmps; + } + } + break; + case 3: // CktElement.EmergAmps - Write + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (IsPDElement()) + { + auto with1 = (TPDElement*)with0->FActiveCktElement; + with1->EmergAmps = arg; + } + } + break; + case 4: // CktElement.Variablei + result = 0; // means an error; no value set + i = trunc(arg); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + if (i > 0 && (i <= pPCElem->NumVariables())) + { + result = pPCElem->Get_Variable(i); + } + + } + } + } + break; + case 5: // CktElement.SetActiveVariable + result = -1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + if ((VarIdx > 0) && (VarIdx <= pPCElem->NumVariables())) //Checks that the active Idx is valid + { + result = 0; // No error, the variable exists and is set + pPCElem->Set_Variable(VarIdx, arg); + } + } + } + } + break; + case 6: // CktElement.GetActiveVariable + result = -1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + if ((VarIdx > 0) && (VarIdx <= pPCElem->NumVariables())) //Checks that the active Idx is valid + { + result = pPCElem->Get_Variable(VarIdx); + } + } + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall CktElementS(int mode, char* arg) +{ + TDSSCktElement* ctrl = nullptr; + TPCElement* pPCElem = nullptr; + TPDElement* pPDElem = nullptr; + bool BData = false; + int Volts = 0, + i = 0, + count = 0, + low = 0, + numcond = 0, + n = 0, + iV = 0; + complex cResid = cmplx(0, 0); + vector cBuffer; + string S = "", + result = "0"; + + switch (mode) + { + case 0: // CktElement.Name + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->ParentClass->Class_Name + "." + with0->LName; + } + else + result = ""; + break; + case 1: // CktElement.Display - read + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->Get_DisplayName(); + } + else + result = ""; + break; + case 2: // CktElement.Display - write + if (ActiveCircuit[ActiveActor]) + { + ActiveCircuit[ActiveActor]->FActiveCktElement->Set_DisplayName(arg); + } + else + result = ""; + break; + case 3: // CktElement.GUID + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + result = with0->Get_ID(); + } + else + result = ""; + break; + case 4: // CktElement.EnergyMeter + if (ActiveCircuit[ActiveActor]) + { + if (ActiveCircuit[ActiveActor]->FActiveCktElement->HasEnergyMeter) + { + pPDElem = (TPDElement*)ActiveCircuit[ActiveActor]->FActiveCktElement; + result = pPDElem->MeterObj->LName; + } + } + break; + case 5: // CktElement.Controller + result = ""; + i = StrToInt(arg); + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (i > 0 && i <= with0->FActiveCktElement->ControlElementList.NumInList) + { + ctrl = (TDSSCktElement*)with0->FActiveCktElement->ControlElementList.Get(i); + if (ctrl != nullptr) + { + + result = Format("%s.%s", ctrl->ParentClass->Class_Name.c_str(), ctrl->LName.c_str()); + + } + } + } + break; + case 6: // CktElement.ActiveVariableName + result = "Error"; // Signifies an error; the variable doesn"t exist + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + VarIdx = pPCElem->LookupVariable(arg); + if ((VarIdx > 0) && (VarIdx <= pPCElem->NumVariables())) + { + result = "OK"; // we are good, the variable seems + } + } + } + } + break; + default: + result = "Error"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall CktElementV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TDSSCktElement* ctrl = nullptr; + TPCElement* pPCElem = nullptr; + TPDElement* pPDElem = nullptr; + bool BData = false; + int Volts = 0, + i = 0, + count = 0, + low = 0, + numcond = 0, + n = 0, + iV = 0, + myInit = 0, + myEnd = 0, + j = 0, + k = 0, + NValues = 0; + complex cResid = cmplx(0,0); + vector cBuffer, + myBuffer; + pComplexArray cValues = nullptr; + complex VPh[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }, + IPh[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }, + I012[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }, + V012[4] = { cmplx(0,0), cmplx(0,0), cmplx(0,0), cmplx(0,0) }; + polar CMagAng = {}; + string S = ""; + + switch (mode) + { + case 0: // CktElement.NormalAmps - read + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + for (i = 1; i <= with0->FActiveCktElement->Fnterms ; i++) + { + WriteStr2Array(with0->FActiveCktElement->GetBus(i)); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // CktElement.BusNames - write + *myType = 4; //string + j = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + count = with0->FActiveCktElement->Fnterms; + for (i = 1; i <= count; i++) + { + S = BArray2Str(myPtr, &j); + if (S.empty()) + { + break; + } + else + with0->FActiveCktElement->SetBus(i, S); + } + *mySize = j; + } + break; + case 2: // CktElement.Voltages + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + numcond = with1->Fnconds * with1->Fnterms; + myCmplxArray.resize(numcond); + iV = 0; + for (i = 1; i <= numcond; i++) + { + n = with1->NodeRef[i - 1]; + myCmplxArray[iV] = with0->Solution->NodeV[n]; //ok if = 0 + iV++; + } + } + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 3: // CktElement.Currents + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + numcond = with0->Fnconds * with0->Fnterms; + myCmplxArray.resize(numcond); + cBuffer.resize(numcond + 1); + with0->GetCurrents(&cBuffer[1], ActiveActor); + iV = 0; + for (i = 1; i <= numcond ; i++) + { + myCmplxArray[iV] = cBuffer[i]; + iV++; + } + cBuffer.clear(); + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 4: // CktElement.powers + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + numcond = with0->Fnconds * with0->Fnterms; + myCmplxArray.resize(numcond); + cBuffer.resize(numcond + 1); + with0->GetPhasePower(&cBuffer[1], ActiveActor); + iV = 0; + for (i = 1; i <= numcond; i++) + { + myCmplxArray[iV] = cmulreal(cBuffer[i], 0.001); + iV++; + } + cBuffer.clear(); + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 5: // CktElement.Losses + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + myCmplxArray[0] = with0->FActiveCktElement->Get_Losses(ActiveActor); + } + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 6: // CktElement.PhaseLosses + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + numcond = with0->Fnphases; + myCmplxArray.resize(numcond); + cBuffer.resize(numcond); + with0->GetPhaseLosses(numcond, &cBuffer[0], ActiveActor); + iV = 0; + for (i = 0; i < numcond; i++) + { + myCmplxArray[iV] = cmulreal(cBuffer[i], 0.001); + iV++; + } + cBuffer.clear(); + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 7: // CktElement.SeqVoltages + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if (with1->FEnabled) + { + try + { + myDblArray.resize(with1->Fnterms * 3); + cBuffer.resize(with1->Fnterms * 3); + // get complex seq voltages + CalcSeqVoltages(with0->FActiveCktElement, &cBuffer[0]); + // return 0 based array + for (i = 0; i < 3 * with1->Fnterms ; i++) + myDblArray[i] = cabs(cBuffer[i]);// return mag only + cBuffer.clear(); + } + catch (const std::exception&E) + { + S = (string)E.what() + CRLF + + "Element=" + with1->get_Name() + CRLF + + "Nphases=" + IntToStr(with1->Get_NPhases()) + CRLF + + "NTerms=" + IntToStr(with1->Get_NTerms()) + CRLF + + "NConds =" + IntToStr(with1->Get_NConds()); + DoSimpleMsg(S, 5012); + } + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 8: // CktElement.SeqCurrents + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if (with1->FEnabled) + { + try + { + myDblArray.resize(with1->Fnterms * 3); + cBuffer.resize((with1->Fnterms * 3) + 1); + // get complex seq voltages + CalcSeqCurrents(with0->FActiveCktElement, &cBuffer[1]); + // return 0 based array + for (i = 1; i <= (3 * with1->Fnterms); i++) + myDblArray[i - 1] = cabs(cBuffer[i]);// return mag only + cBuffer.clear(); + } + catch (const std::exception& E) + { + S = (string)E.what() + CRLF + + "Element=" + with1->get_Name() + CRLF + + "Nphases=" + IntToStr(with1->Get_NPhases()) + CRLF + + "NTerms=" + IntToStr(with1->Get_NTerms()) + CRLF + + "NConds =" + IntToStr(with1->Get_NConds()); + DoSimpleMsg(S, 5012); + } + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 9: // CktElement.SeqPowers + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + myCmplxArray.resize(with1->Fnterms * 3); + if (with1->Fnphases != 3) + { + if (with1->Fnphases == 1 && with0->PositiveSequence) + { + numcond = with1->Get_NConds() * with1->Get_NTerms(); + cBuffer.resize(numcond + 1); + with1->GetCurrents(&cBuffer[1], ActiveActor); + for (i = 0; i <= 3 * with1->Fnterms; i++) + myCmplxArray[i] = cmplx(0, 0);// Initialize Result + count = 2; // Start with kW1 {put only phase 1 quantities in Pos seq} + + for (j = 0; j <= 3 * with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + n = with1->NodeRef[k]; + VPh[1] = with0->Solution->NodeV[n]; // Get voltage at node + myCmplxArray[count] = cmulreal(cmul(VPh[1], conjg(cBuffer[k + 1])), 0.003); // Compute power per phase + count++; + } + cBuffer.clear(); + } + else + { + for (i = 0; i < (3 * with1->Fnterms); i++) + { + myCmplxArray[count] = cmplx(-1.0, -1.0); // Signify n/A + count++; + } + } + } + else + { + numcond = with1->Fnconds * with1->Fnterms; + cBuffer.resize(numcond + 1); + with1->GetCurrents(&cBuffer[1], ActiveActor); + count = 0; + for (j = 1; j <= with1->Fnterms; j++) + { + k = (j - 1) * with1->Fnconds; + for (i = 1; i <= 3; i++) + { + VPh[i] = with0->Solution->NodeV[with1->NodeRef[i + k - 1]]; + } + for (i = 1; i <= 3; i++) + { + IPh[i] = cBuffer[k + i]; + } + Phase2SymComp(&IPh[1], &I012[1]); + Phase2SymComp(&VPh[1], &V012[1]); + for (i = 1; i <= 3; i++) + { + myCmplxArray[count] = cmulreal(cmul(V012[i], conjg(I012[i])), 0.003); + count++; + } + } + cBuffer.clear(); + } + + } + + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 10: // CktElement.AllPropertyNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + auto with2 = with1->ParentClass; + for (k = 0; k < with2->NumProperties; k++) + { + WriteStr2Array(with2->PropertyName[k]); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 11: // CktElement.Residuals + *myType = 3; + myPolarArray.resize(1); + myPolarArray[0] = ctopolar(CZero); + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + myPolarArray.resize(with0->Fnterms);// 2 values per terminal + cBuffer.resize(with0->Yorder + 1); + with0->GetCurrents(&cBuffer[1], ActiveActor); + iV = 0; + for (i = 1; i <= with0->Fnterms; i++) + { + cResid = CZero; + k = (i - 1) * with0->Fnconds; + for (j = 1; j <= with0->Fnconds; j++) + { + k++; + caccum(cResid, cBuffer[k]); + } + myPolarArray[iV] = ctopolardeg(cResid); + iV++; + } + cBuffer.clear(); + + } + *mySize = myPolarArray.size() * sizeof(polar); + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + break; + case 12: // CktElement.YPrim + *myType = 3; // Complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + NValues = sqr(with0->Yorder); + cValues = with0->GetYPrimValues(ALL_YPRIM);// Get pointer to complex array of values + if (cValues == nullptr) + { // check for unassigned array + return; // Get outta here + } + myCmplxArray.resize(NValues); + iV = 0; + for (i = 0; i < NValues; i++) + { + myCmplxArray[iV] = cValues[i]; + iV++; + }; + + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 13: // CktElement.CplxSeqVoltages + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if (with1->FEnabled) + { + try + { + myCmplxArray.resize(with1->Fnterms * 3); + cValues = new complex[(with1->Fnterms * 3)]; + // get complex seq voltages + CalcSeqVoltages(with0->FActiveCktElement, cValues); + // return 0 based array + iV = 0; + for (i = 0; i < (3 * with1->Fnterms); i++) + { + myCmplxArray[iV] = cValues[i]; + iV++; + } + delete[] cValues; + } + catch (const std::exception& E) + { + S = (string)E.what() + CRLF + + "Element=" + with1->get_Name() + CRLF + + "Nphases=" + IntToStr(with1->Get_NPhases()) + CRLF + + "NTerms=" + IntToStr(with1->Get_NTerms()) + CRLF + + "NConds =" + IntToStr(with1->Get_NConds()); + DoSimpleMsg(S, 5012); + } + } + } + } + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 14: // CktElement.CplxSeqCurrents + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if (with1->FEnabled) + { + try + { + myCmplxArray.resize(with1->Fnterms * 3); + cValues = new complex[(with1->Fnterms * 3)]; + // get complex seq currents + CalcSeqCurrents(with0->FActiveCktElement, cValues); + // return 0 based array + iV = 0; + for (i = 0; i < 3 * with1->Fnterms; i++) + { + myCmplxArray[iV] = cValues[i];// return mag only + iV++; + } + delete[] cValues; + } + catch (const std::exception& E) + { + S = (string)E.what() + CRLF + + "Element=" + with1->get_Name() + CRLF + + "Nphases=" + IntToStr(with1->Get_NPhases()) + CRLF + + "NTerms=" + IntToStr(with1->Get_NTerms()) + CRLF + + "NConds =" + IntToStr(with1->Get_NConds()); + DoSimpleMsg(S, 5012); + } + } + } + } + *mySize = myCmplxArray.size() * sizeof(complex); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + case 15: // CktElement.AllVariableNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with1; + for (k = 1; k <= pPCElem->NumVariables(); k++) + { + WriteStr2Array(pPCElem->VariableName(k)); + WriteStr2Array(Char0()); + } + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 16: // CktElement.AllVariableValues + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + if ((with1->DSSObjType & BaseClassMask) == PC_ELEMENT) + { + pPCElem = (TPCElement*)with0->FActiveCktElement; + myDblArray.resize(pPCElem->NumVariables()); + for (k = 1; k <= pPCElem->NumVariables(); k++) + { + myDblArray[k - 1] = pPCElem->Get_Variable(k); + } + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 17: // CktElement.Nodeorder + *myType = 1; //integer + myIntArray.resize(1); + myIntArray[0] = 0; + + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement != nullptr) + { + auto with1 = with0->FActiveCktElement; + k = 0; + myIntArray.resize(with1->Fnterms * with1->Fnconds); + for (i = 1; i <= with1->Fnterms; i++) + { + for (j = ((i - 1) * with1->Fnconds); j < i * with1->Fnconds; j++) + { + myIntArray[k] = GetNodeNum(with1->NodeRef[j]); + k++; + } + + } + + } + } + *mySize = myIntArray.size() * sizeof(int); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + + break; + case 18: // CktElement.CurrentsMagAng + *myType = 3; //complex + myPolarArray.resize(1); + myPolarArray[0] = ctopolar(CZero); + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + + NValues = with0->Fnconds * with0->Fnterms; + myPolarArray.resize(NValues); + cBuffer.resize(NValues + 1); + with0->GetCurrents(&cBuffer[1], ActiveActor); + iV = 0; + for (i = 1; i <= NValues; i++) + { + + myPolarArray[iV] = ctopolardeg(cBuffer[i]);// convert to mag/angle + iV++; + } + cBuffer.clear(); + + } + *mySize = sizeof(polar) * myPolarArray.size(); + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + break; + case 19: // CktElement.VoltagesMagAng + *myType = 3; //complex + myPolarArray.resize(1); + myPolarArray[0] = ctopolar(CZero); + if (ActiveCircuit[ActiveActor] != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->FActiveCktElement) + { + auto with1 = with0->FActiveCktElement; + numcond = with1->Fnconds * with1->Fnterms; + myPolarArray.resize(numcond); + iV = 0; + for (i = 1; i <= numcond; i++) + { + n = with1->NodeRef[i - 1]; + myPolarArray[iV] = ctopolardeg(with0->Solution->NodeV[n]); + iV++; + } + } + } + + *mySize = sizeof(polar) * myPolarArray.size(); + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + break; + case 20: // CktElement.TotalPowers + *myType = 3; + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]->FActiveCktElement; + NValues = with0->Fnconds * with0->Fnterms; + myCmplxArray.resize(with0->Fnterms); + cBuffer.resize(NValues + 1); + with0->GetPhasePower(&cBuffer[1], ActiveActor); + iV = 0; + myBuffer.resize(with0->Fnterms + 1); + for (j = 1; j <= with0->Fnterms; j++) + { + for (i = 1; i <= with0->Fnconds; i++) + myBuffer[j - 1] = cadd(myBuffer[j - 1], cBuffer[i + (j - 1) * with0->Fnconds]); + + myCmplxArray[iV] = cmulreal(myBuffer[j - 1], 0.001); + iV++; + } + cBuffer.clear(); + + } + + *mySize = sizeof(polar) * myCmplxArray.size(); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + break; + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the CmathLib interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************floating point type properties************************* +double __stdcall CmathLibF(int mode, double arg1, double arg2) +{ + double result = 0.0;// Default return value + + switch (mode) + { + case 0: // CmathLib.Cabs + result = cabs(cmplx(arg1, arg2)); + break; + case 1: // CmathLib.Cdang + result = cdang(cmplx(arg1, arg2)); + break; + default: + result = -1.0; + break; + } + return result; +} +//************************Structure type properties******************************* +void __stdcall CmathLibV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + complex* pCmplx = nullptr; + polar* pPolar = nullptr; + double* pDbl = nullptr; + double a = 0.0, + b = 0.0; + + switch (mode) + { + case 0: // CmathLib.cmplx + pDbl = (double*)myPtr; + *myType = 3; //complex + myCmplxArray.resize(1); + a = *pDbl; + pDbl++; + b = *pDbl; + myCmplxArray[0] = cmplx(a, b); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + case 1: // CmathLib.ctopolardeg + pCmplx = (complex*)myPtr; + *myType = 3; //complex + myPolarArray.resize(1); + myPolarArray[0] = ctopolardeg(*pCmplx); + *myPtr = (uintptr_t)(void*)(myPolarArray.data()); + *mySize = myPolarArray.size() * sizeof(polar); + break; + case 2: // CmathLib.pdegtocomplex + pPolar = (polar*)myPtr; + *myType = 3; //complex + myCmplxArray.resize(1); + myCmplxArray[0] = pdegtocomplex(pPolar->mag, pPolar->ang); + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = myCmplxArray.size() * sizeof(myCmplxArray[0]); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } + + + +} + +//-------------------------------------------------------------------------------- +// Implements the Generators interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall GeneratorsI(int mode, int arg) +{ + TGeneratorObj* pGen; + int result = 0; // Default return value + switch (mode) + { + case 0: // Generators.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_First(); + if (ASSIGNED(pGen)) + { + do + { + if (pGen->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pGen); + result = 1; + } + else + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(pGen)))); + } + } + break; + case 1: // Generators.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_Next(); + if (ASSIGNED(pGen)) + { + do + { + if (pGen->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pGen); + result = ActiveCircuit[ActiveActor]->Generators.get_myActiveItem(); + } + else + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(pGen)))); + } + } + break; + case 2: // Generators.ForcedON read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + if ( ((TGeneratorObj*)with0.Get_Active())->get_FForcedON()) + result = 1; + } + } + break; + case 3: // Generators.ForcedON Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + if (arg == 1) + { + ((TGeneratorObj*)with0.Get_Active())->set_FForcedON(true); + } + else + { + ((TGeneratorObj*)with0.Get_Active())->set_FForcedON(false); + } + } + } + break; + case 4: // Generators.Phases read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->Get_NPhases(); + } + } + break; + case 5: // Generators.Phases write + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Set_NPhases(arg); + } + } + break; + case 6: // Generators.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Generators.get_myNumList(); + } + break; + case 7: // Generators.Idx read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->Generators.get_myActiveItem(); + } + break; + case 8: // Generators.Idx Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get(arg); + if (pGen != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pGen); + } + } + break; + case 9: // Generators.Model read + result = -1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->GenModel; + } + } + break; + case 10: // Generators.Model Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->GenModel = arg; + if (((TGeneratorObj*)with0.Get_Active())->GenModel == 3) + { + ActiveCircuit[ActiveActor]->Solution->SolutionInitialized = false; + } + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall GeneratorsF(int mode, double arg) +{ + double result = 0.0; // Default return value + switch (mode) + { + case 0: // Generators.kV read + result = -1.0; //not set + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->GenVars.kVGeneratorBase; + } + } + break; + case 1: // Generators.kV Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Set_PresentkV(arg); + } + } + break; + case 2: // Generators.kW read + result = 0.0; //not set + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->Get_PresentkW(); + } + } + break; + case 3: // Generators.kW Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Set_PresentkW(arg); + } + } + break; + case 4: // Generators.kvar read + result = 0.0; //not set + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->Get_Presentkvar(); + } + } + break; + case 5: // Generators.kvar Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Set_Presentkvar(arg); + } + } + break; + case 6: // Generators.PF read + result = 0.0; //not set + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->get_PFNominal(); + } + } + break; + case 7: // Generators.PF Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Set_PowerFactor(arg); + } + } + break; + case 8: // Generators.KVARated read + result = -1.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->GenVars.kVArating; + } + } + break; + case 9: // Generators.KVARated Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->GenVars.kVArating = arg; + } + } + break; + case 10: // Generators.Vmaxpu read + result = -1.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->Vmaxpu; + } + } + break; + case 11: // Generators.Vmaxpu Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Vmaxpu = arg; + } + } + break; + case 12: // Generators.Vminpu read + result = -1.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + result = ((TGeneratorObj*)with0.Get_Active())->Vminpu; + } + } + break; + case 13: // Generators.Vminpu Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + if (with0.ActiveItem != 0) + { + ((TGeneratorObj*)with0.Get_Active())->Vminpu = arg; + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall GeneratorsS(int mode, char* arg) +{ + TGeneratorObj* pGen; + int ActiveSave; + TGeneratorObj* Gen; + std::string S; + bool Found; + string result = ""; // Default return value + switch (mode) + { + case 0: // Generators.Name read + result = ""; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pGen = (TGeneratorObj*)ActiveCircuit[ActiveActor]->Generators.Get_Active(); + if (pGen != nullptr) + { + result = pGen->get_Name(); + } + else + { + result = ""; // signify no name + } + } + break; + case 1: // Generators.Name Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Generators; + S = std::string(arg); + Found = false; + ActiveSave = with0.get_myActiveItem(); + Gen = (TGeneratorObj*)with0.Get_First(); + while (Gen != nullptr) + { + if (CompareText(Gen->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Gen); + Found = true; + break; + } + Gen = (TGeneratorObj*)with0.Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Generator \"" + S + "\" Not Found in Active Circuit.", 5003); + Gen = (TGeneratorObj*)with0.Get(ActiveSave); // Restore active generator + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Gen); + } + } + break; + default: + result = "Error, Parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall GeneratorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TGeneratorObj* GenElem; + TGenerator* GeneratorClass; + int k; + switch (mode) + { + case 0: // Generators.AllNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Generators.get_myNumList() > 0) + { + GenElem = (TGeneratorObj*) with0->Generators.Get_First(); + while (GenElem != nullptr) + { + WriteStr2Array(GenElem->get_Name()); + WriteStr2Array(Char0()); + GenElem = (TGeneratorObj*)with0->Generators.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + + break; + case 1: // Generators.RegisterNames + *myType = 4; //String + myStrArray.resize(0); + GeneratorClass = (TGenerator*)DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("Generator")); + for (k = 0; k < Generator::NumGenRegisters; k++) + { + WriteStr2Array(GeneratorClass->RegisterNames[k]); + WriteStr2Array(Char0()); + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 2: // Generators.RegisterValues + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + GenElem = (TGeneratorObj*)(ActiveCircuit[ActiveActor]->Generators.Get_Active()); + if (GenElem != nullptr) + { + myDblArray.resize(Generator::NumGenRegisters); + for (k = 0; k < Generator::NumGenRegisters; k++) + { + myDblArray[k] = GenElem->Registers[k]; + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the DSSElement interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall DSSElementI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // DSSElement.NumProperties + if (ActiveCircuit[ActiveActor] != nullptr) + { + TDSSObject *with0 = (TDSSObject *) ActiveDSSObject[ActiveActor]; + if (with0 != nullptr) + { + result = with0->ParentClass->NumProperties; + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall DSSElementS(int mode, char* arg) +{ + string result = ""; + + switch (mode) + { + case 0: + if (ActiveCircuit[ActiveActor] != nullptr) + { + TDSSObject *with0 = (TDSSObject *) ActiveDSSObject[ActiveActor]; + if (with0 != nullptr) + { + result = with0->ParentClass->Class_Name + "." + with0->LName; + } + } + break; + default: + result = "Error, parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall DSSElementV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int k = 0; + + switch (mode) + { + case 0: + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + TDSSObject *with0 = (TDSSObject *) ActiveDSSObject[ActiveActor]; + if (with0 != nullptr) + { + auto with1 = with0->ParentClass; + for (k = 0; k < with1->NumProperties; k++) + { + WriteStr2Array(with1->PropertyName[k]); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + + + //-------------------------------------------------------------------------------- + // Implements the DSSProgress interface for the DLL + //-------------------------------------------------------------------------------- +int __stdcall DSSProgressI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // DSSProgress.PctProgress + if (NoFormsAllowed) { + break; + } + InitProgressForm(); + break; + case 1: // DSSProgress.Show + if (NoFormsAllowed) { + InitProgressForm(); + ProgressFormCaption(""); + } + break; + case 2: // DSSProgress.Close + if (NoFormsAllowed) { + break; + } + ProgressHide(); + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall DSSProgressS(int mode, char* arg) +{ + string result = "0"; + switch (mode) + { + case 0: // DSSProgress.Caption + if (NoFormsAllowed) { + break; + } + InitProgressForm(); + ProgressCaption(arg); + break; + default: + result = "Error, parameter not recognized"; + break; + + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + +//-------------------------------------------------------------------------------- +// Implements the DSSExecutive interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall DSSExecutiveI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // DSSExecutive.NumCommands + result = NumExecCommands; + break; + case 1: // DSSExecutive.NumOptions + result = NumExecOptions; + break; + default: + result = -1; + break; + } + + return result; +} +//******************************String type properties**************************** +char* __stdcall DSSExecutiveS(int mode, char* arg) +{ + string result = ""; + int i = 0; + switch (mode) + { + case 0: // DSSExecutive.Command + i = StrToInt(arg); + result = ExecCommand[i - 1]; + break; + case 1: // DSSExecutive.Option + i = StrToInt(arg); + result = ExecOption[i - 1]; + break; + case 2: // DSSExecutive.CommandHelp + i = StrToInt(arg); + result = CommandHelp[i - 1]; + break; + case 3: // DSSExecutive.OptionHelp + i = StrToInt(arg); + result = OptionHelp[i - 1]; + break; + case 4: // DSSExecutive.OptionValue + i = StrToInt(arg); + DSSExecutive[ActiveActor]->Set_Command("get " + ExecOption[i - 1]); + result = GlobalResult; + break; + + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + +//-------------------------------------------------------------------------------- +// Implements the ErrorCode interface for the DLL +//-------------------------------------------------------------------------------- +int __cdecl ErrorCode() +{ + long int result = ErrorNumber; + ErrorNumber = 0; // Restablecer a 0 después de obtener ErrorNumber + return result; +} + +// ******************************ErrorDesc:****************************** +char* __cdecl ErrorDesc() +{ + // Suponemos que LastErrorMessage es de tipo std::string + string result = LastErrorMessage; + LastErrorMessage = ""; // Restablecer a cadena vacía después de obtener el mensaje + + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + +//-------------------------------------------------------------------------------- +// Implements the Fuses interface for the DLL +//-------------------------------------------------------------------------------- +void Set_ParameterFuse(string parm, string val) +{ + string myCmd = ""; + if (not(ASSIGNED(ActiveCircuit[ActiveActor]))) + { + return; + } + SolutionAbort = false; //Reset for commands entered from outside + myCmd = Format("Fuse.%s.%s=%s", ((TFuseObj*)(FuseClass->GetActiveObj()))->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(myCmd); +} +// ******************************int point type properties************************* +int __stdcall FusesI(int mode, int arg) +{ + TFuseObj* pElem = {}; + TFuseObj* elem = {}; + int i = 0, + result = 0; + TFuseObj* pFuse = {}; + + switch (mode) + { + case 0: + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = FuseClass->ElementList.NumInList; + } + break; + case 1: // Fuses.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TFuseObj*) FuseClass->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + pElem = (TFuseObj*)FuseClass->ElementList.Get_Next(); + } while (!(result == 1 || pElem == nullptr)); + } + } + break; + case 2: // Fuses.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TFuseObj*)FuseClass->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = FuseClass->ElementList.get_myActiveItem(); + } + else + pElem = (TFuseObj*)FuseClass->ElementList.Get_Next(); + } while (!(result > 0 || pElem == nullptr)); + } + } + break; + case 3: // Fuses.MonitoredTerm read + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementTerminal; + } + } + break; + case 4: // Fuses.MonitoredTerm write + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("monitoredterm", IntToStr(arg)); + } + } + break; + case 5: // Fuses.SwitchedTerm read + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->ElementTerminal; + } + } + break; + case 6: // Fuses.SwitchedTerm write + if(ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("switchedterm", IntToStr(arg)); + } + } + break; + case 7: // Fuses.Open + if (ActiveCircuit[ActiveActor] != nullptr) + { + pFuse = (TFuseObj*)FuseClass->GetActiveObj(); + if (pFuse != nullptr) + { + for (i = 1; i <= pFuse->FControlledElement->Fnphases; i++) + { + pFuse->set_States(i, CTRL_OPEN); // Open all phases + } + } + } + break; + case 8: // Fuses.Close + if (ActiveCircuit[ActiveActor] != nullptr) + { + pFuse = (TFuseObj*)FuseClass->GetActiveObj(); + if (pFuse != nullptr) + { + for (i = 1; i <= pFuse->FControlledElement->Fnphases; i++) + { + pFuse->set_States(i, CTRL_CLOSE); // Open all phases + } + } + } + break; + case 9: // Fuses.IsBlown + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + for (i = 1; i <= elem->Fnphases; i++) + { + if (not(elem->FControlledElement->Get_ConductorClosed(i, ActiveActor))) + { + result = 1; + } + } + } + } + break; + case 10: // Fuses.Idx read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = FuseClass->ElementList.ActiveItem; + } + break; + case 11: // Fuses.Idx write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pFuse = (TFuseObj*)FuseClass->ElementList.Get(arg); + if (pFuse != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pFuse); + } + } + break; + case 12: // Fuses.NumPhases + if (ActiveCircuit[ActiveActor] != nullptr) + { + pFuse = (TFuseObj*)FuseClass->GetActiveObj(); + if (pFuse != nullptr) + { + result = pFuse->Fnphases; + } + } + break; + case 13: // Fuses.Reset + if (ActiveCircuit[ActiveActor] != nullptr) + { + pFuse = (TFuseObj*)FuseClass->GetActiveObj(); + if (pFuse != nullptr) + { + pFuse->Reset(ActiveActor); + } + } + break; + default: + result = -1; + break; + } + + return result; +} +// ******************************floating point type properties************************* +double __stdcall FusesF(int mode, double arg) +{ + + TFuseObj* elem = nullptr; + double result = 0; + + switch (mode) + { + case 0: // Fuses.RatedCurrent read + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->RatedCurrent; + } + else + result = -1; + break; + case 1: // Fuses.RatedCurrent write + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("RatedCurrent", Format("%.8g ", arg)); + } + break; + case 2: // Fuses.Delay read + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->DelayTime; + } + else + result = -1.0; + break; + case 3: // Fuses.Delay write + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("Delay", Format("%.8g ", arg)); + } + break; + default: + result = -1.0; + break; + + } + return result; +} +//******************************String type properties**************************** +char* __stdcall FusesS(int mode, char* arg) +{ + string result = ""; // Default return value + TFuseObj* elem = {}; + switch (mode) + { + case 0: // Fuses.Name read + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->LName; + } + break; + case 1: // Fuses.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (FuseClass->SetActive((string)arg)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*) FuseClass->ElementList.Get_Active()); + } + else + DoSimpleMsg("Fuse " + (string)arg + " Not Found in Active Circuit.", 77003); + } + break; + case 2: // Fuses.MonitoredObj read + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementName; + } + break; + case 3: // Fuses.MonitoredObj write + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("monitoredObj", (string)arg); + } + break; + case 4: // Fuses.SwitchedObj read + elem = (TFuseObj*)FuseClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->MonitoredElementName; + } + break; + case 5: // Fuses.SwitchedObj write + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("SwitchedObj", (string)arg); + } + break; + case 6: // Fuses.TCCcurve read + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->FuseCurve->LName; + } + else + result = "No Fuse Active!"; + break; + case 7: // Fuses.TCCcurve write + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterFuse("FuseCurve", (string)arg); + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall FusesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TFuseObj* elem = {}; + TPointerList* pList = {}; + int k = 0, + i = 0, + LoopLimit = 0; + string S; + + switch (mode) + { + case 0: // Fuses.AllNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (FuseClass->ElementList.NumInList > 0) + { + pList = &(FuseClass->ElementList); + elem = (TFuseObj*)pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TFuseObj*)pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Fuses.States - read + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + for (i = 1; i <= elem->FControlledElement->Fnphases; i++) + { + if (elem->get_States(i) == CTRL_CLOSE) + { + WriteStr2Array("closed"); + } + else + { + WriteStr2Array("open"); + } + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 2: // Fuses.States - write + *myType = 4;//string + k = 0; + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + for (i = 1; i <= elem->FControlledElement->Fnphases; i++) + { + S = BArray2Str(myPtr, &k); + if (S.empty()) + { + break; + } + else + { + switch (LowerCase(S)[0]) + { + case 'o': + elem->set_States(i, CTRL_OPEN); + break; + case 'c': + elem->set_States(i, CTRL_CLOSE); + break; + } + } + } + } + *mySize = k; + break; + case 3: // Fuses.NormalState - read + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + for (i = 1; i <= elem->FControlledElement->Fnphases; i++) + { + if (elem->get_States(i) == CTRL_CLOSE) + { + WriteStr2Array("closed"); + } + else + { + WriteStr2Array("open"); + } + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 4: // Fuses.NormalState - write + *myType = 4;//string + k = 0; + elem = (TFuseObj*)FuseClass->GetActiveObj(); + if (elem != nullptr) + { + for (i = 1; i <= elem->FControlledElement->Fnphases; i++) + { + S = BArray2Str(myPtr, &k); + if (S.empty()) + { + break; + } + else + { + switch (LowerCase(S)[0]) + { + case 'o': + elem->set_States(i, CTRL_OPEN); + break; + case 'c': + elem->set_States(i, CTRL_CLOSE); + break; + } + } + } + } + *mySize = k; + break; + default: + myStrArray.resize(0); + WriteStr2Array("Parameter not identified"); + WriteStr2Array(Char0()); + *myType = 4; //String + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + + } +} + +//-------------------------------------------------------------------------------- +// Implements the GICSources interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall GICSourcesI(int mode, int arg) +{ + TGICSourceObj* pElem = nullptr; + int result = 0; + + switch (mode) + { + case 0: // GICSources.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = GICsourceClass->ElementList.NumInList; + } + break; + case 1: // GICSources.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Next(); + } while (!(result == 1 || pElem == nullptr)); + } + } + break; + case 2: // GICSources.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = GICsourceClass->ElementList.ActiveItem; + } + else + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Next(); + } while (!(result > 0 || pElem == nullptr)); + } + } + + break; + case 3: // GICSources.Phases read + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (pElem != nullptr) + { + result = pElem->Fnphases; + } + break; + case 4: // GICSources.Phases write + pElem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (pElem != nullptr) + { + pElem->Fnphases = arg; + pElem->Fnconds = arg; // Force reallocation of terminal info + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall GICSourcesF(int mode, double arg) +{ + TGICSourceObj* elem = nullptr; // Default return value + double result = 0.0; + + switch (mode) + { + case 0: // GICSources.EN read + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->ENorth; + } + break; + case 1: // GICSources.EN write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->ENorth = arg; + } + break; + case 2: // GICSources.EE read + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->EEast; + } + break; + case 3: // GICSources.EE write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->EEast = arg; + } + break; + case 4: // GICSources.Lat1 read + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Lat1; + } + break; + case 5: // GICSources.Lat1 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Lat1 = arg; + elem->VoltsSpecified = false; + } + break; + case 6: // GICSources.Lat2 read + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Lat2; + } + break; + case 7: // GICSources.Lat2 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Lat2 = arg; + elem->VoltsSpecified = false; + } + break; + case 8: // GICSources.Lat2 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Lon1; + } + break; + case 9: // GICSources.Lat2 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Lon1 = arg; + elem->VoltsSpecified = false; + } + break; + case 10: // GICSources.Lon2 read + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Lon2; + } + break; + case 11: // GICSources.Lon2 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Lon2 = arg; + elem->VoltsSpecified = false; + } + break; + case 12: // GICSources.Lon2 write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Volts; + } + break; + case 13: // GICSources.Volts write + elem = (TGICSourceObj*)GICsourceClass->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Volts = arg; + elem->VoltsSpecified = false; + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall GICSourcesS(int mode, char* arg) +{ + string S = "", + result = "0"; // Default return value; + + switch (mode) + { + case 0: // GICSources.Bus1 + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->GetBus(1); + } + break; + case 1: // GICSources.Bus2 + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->GetBus(2); + } + break; + case 2: // GICSources.Name read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->FActiveCktElement->LName; + } + break; + case 3: // GICSources.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + S = arg; + if (GICsourceClass->SetActive(S)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TGICSourceObj*)GICsourceClass->ElementList.Get_Active()); + } + else + DoSimpleMsg("Vsource \"" + S + "\" Not Found in Active Circuit.", 77003); + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall GICSourcesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TGICSourceObj* GICElem = {}; + TPointerList* ElementList = {}; + int k = 0; + switch (mode) + { + case 0: // GICSources.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + ElementList = &(GICsourceClass->ElementList); + if (ElementList->NumInList > 0) + { + GICElem = (TGICSourceObj*)ElementList->Get_First(); + while (GICElem != nullptr) + { + WriteStr2Array(GICElem->LName); + WriteStr2Array(Char0()); + GICElem = (TGICSourceObj*)ElementList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Isource interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall IsourceI(int mode, int arg) +{ + TIsourceObj* pElem; + int result = 0; + switch (mode) + { + case 0: // Isources.Count + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = IsourceClass[ActiveActor]->ElementList.get_myNumList(); + } + break; + case 1: // Isources.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TIsourceObj*) IsourceClass[ActiveActor]->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + { + pElem = (TIsourceObj*) IsourceClass[ActiveActor]->ElementList.Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(pElem)))); + } + } + break; + case 2: // Isources.Next + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TIsourceObj*)IsourceClass[ActiveActor]->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = IsourceClass[ActiveActor]->ElementList.get_myActiveItem(); + } + else + { + pElem = (TIsourceObj*)IsourceClass[ActiveActor]->ElementList.Get_Next(); + } + } while(!( (result > 0) || (!ASSIGNED(pElem) ) ) ) ; + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall IsourceF(int mode, double arg) +{ + TIsourceObj* elem; + double result = 0.0; + switch (mode) + { + case 0: // Isources.Amps read + result = 0.0; + elem = (TIsourceObj*) IsourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Amps; + } + break; + case 1: // Isources.Amps write + elem = (TIsourceObj*)IsourceClass[ActiveActor]->GetActiveObj(); + if (elem != nullptr) + { + elem->Amps = arg; + } + break; + case 2: // Isources.AngleDeg read + result = 0.0; + elem = (TIsourceObj*)IsourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Angle; + } + break; + case 3: // Isources.AngleDeg write + elem = (TIsourceObj*)IsourceClass[ActiveActor]->GetActiveObj(); + if (elem != nullptr) + { + elem->Angle = arg; + } + break; + case 4: // Isources.Frequency read + result = 0.0; + elem = (TIsourceObj*)IsourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->SrcFrequency; + } + break; + case 5: // Isources.Frequency write + elem = (TIsourceObj*)IsourceClass[ActiveActor]->GetActiveObj(); + if (elem != nullptr) + { + elem->SrcFrequency = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall IsourceS(int mode, char* arg) +{ + TDSSCktElement* elem = nullptr; + string result = ""; // Default return value + switch (mode) + { + case 0: // Isources.Name read + result = ""; + elem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + if (elem != nullptr) + { + result = elem->get_Name(); + } + break; + case 1: // Isoruces.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsourceClass[ActiveActor]->SetActive(string(arg))) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)IsourceClass[ActiveActor]->ElementList.Get_Active()); + } + else + { + DoSimpleMsg("Isource \"" + std::string(arg) + "\" Not Found in Active Circuit.", 77003); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall IsourceV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TIsourceObj* elem = nullptr; + TPointerList* pList = nullptr; + switch (mode) + { + case 0: // Isources.AllNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IsourceClass[ActiveActor]->ElementList.get_myNumList() > 0) + { + pList = &(IsourceClass[ActiveActor]->ElementList); + elem = (TIsourceObj*) pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->get_Name()); + WriteStr2Array(Char0()); + elem = (TIsourceObj*)pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + + +//-------------------------------------------------------------------------------- +// Implements the LineCodes interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall LineCodesI(int mode, int arg) +{ + TLineCodeObj* pLineCode = nullptr; + int result = 0; + switch (mode) + { + case 0: // LineCodes.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = LineCodeClass->Get_ElementCount(); + } + break; + case 1: // LineCodes.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = LineCodeClass->Get_First(); + } + break; + case 2: // LineCodes.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = LineCodeClass->Get_Next(); + } + break; + case 3: // LineCodes.Units Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->Units; + } + break; + case 4: // LineCodes.Units Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + if (arg < 9) + { + Parser[ActiveActor]->SetCmdString(Format("units=%s", LineUnitsStr(arg).c_str())); + with0->Edit(ActiveActor); + } + else + DoSimpleMsg("Invalid line units integer sent via DLL interface. Please enter a value within range.", 183); + } + break; + case 5: // LineCodes.Phases Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->get_Fnphases(); + } + break; + case 6: // LineCodes.Phases Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + pLineCode->Set_NPhases(arg); + } + break; + case 7: // LineCodes.IsZ1Z0 + result = 1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + if (pLineCode != nullptr) + { + if (pLineCode->SymComponentsModel) + { + result = 1; + } + else + { + result = 0; + } + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall LineCodesF(int mode, double arg) +{ + TLineCodeObj* pLineCode = nullptr; + double result = 0.0; + switch (mode) + { + case 0: // LineCodes.R1 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->R1; + } + break; + case 1: // LineCodes.R1 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("R1=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 2: // LineCodes.X1 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->X1; + } + break; + case 3: // LineCodes.X1 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("X1=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 4: // LineCodes.R0 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->R0; + } + break; + case 5: // LineCodes.R0 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("R0=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 6: // LineCodes.X0 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->X0; + } + break; + case 7: // LineCodes.X0 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("X0=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 8: // LineCodes.C1 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->C1 * 1.0e9; + } + break; + case 9: // LineCodes.C1 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("C1=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 10: // LineCodes.C0 Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->C0 * 1.0e9; + } + break; + case 11: // LineCodes.C0 Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Parser[ActiveActor]->SetCmdString(Format("C0=%g", arg)); + with0->Edit(ActiveActor); + } + break; + case 12: // LineCodes.NormAmps Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->NormAmps; + } + break; + case 13: // LineCodes.NormAmps Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + pLineCode->NormAmps = arg; + } + break; + case 14: // LineCodes.EmergAmps Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + result = pLineCode->EmergAmps; + } + break; + case 15: // LineCodes.EmergAmps Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + pLineCode->EmergAmps = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall LineCodesS(int mode, char* arg) +{ + TLineCodeObj* pLineCode = nullptr; + string result = ""; // Default return value + switch (mode) + { + case 0: // LineCodes.Name Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + if (pLineCode != nullptr) + { + result = pLineCode->get_Name(); + } + } + break; + case 1: // LineCodes.Name Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (!(LineCodeClass->SetActive(arg))) + { + DoSimpleMsg("LineCode " + (string) arg + " Not Found in Active Circuit.", 51008); + } + } + break; + default: + result = "Parameter not identified"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall LineCodesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TLineCodeObj* pLineCode = nullptr; + int i = 0, + j = 0, + k = 0; + complex Ztemp = cmplx(0,0); + double Factor = 0.0; + int* Pint = nullptr; + double* PDouble =nullptr; + switch (mode) + { + case 0: // LineCodes.Rmatrix Read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + myDblArray.resize(with0->get_Fnphases() * with0->get_Fnphases()); + k = 0; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + myDblArray[k] = with0->Z->GetElement(i, j).re; + k++; + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 1: // LineCodes.Rmatrix Write + *myType = 2; ///Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + Ztemp = with0->Z->GetElement(i, j); + with0->Z->SetElement(i, j, cmplx(*PDouble, Ztemp.im)); + k++; + PDouble++; + } + } + } + *mySize = k; + break; + case 2: // LineCodes.Xmatrix Read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + myDblArray.resize(with0->get_Fnphases() * with0->get_Fnphases()); + k = 0; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + myDblArray[k] = with0->Z->GetElement(i, j).im; + k++; + } + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 3: // LineCodes.Xmatrix Write + *myType = 2; ///Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + Ztemp = with0->Z->GetElement(i, j); + with0->Z->SetElement(i, j, cmplx(Ztemp.re, *PDouble)); + k++; + PDouble++; + } + } + } + *mySize = k; + break; + case 4: // LineCodes.Cmatrix Read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Factor = (TwoPi * with0->BaseFrequency * 1.0e-9); + myDblArray.resize(with0->get_Fnphases() * with0->get_Fnphases()); + k = 0; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + myDblArray[k] = (with0->YC->GetElement(i, j).im) / Factor; + k++; + } + + } + + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 5: // LineCodes.Cmatrix Write + *myType = 2; ///Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pLineCode = (TLineCodeObj*)LineCodeClass->GetActiveObj(); + auto with0 = pLineCode; + Factor = TwoPi * with0->BaseFrequency * 1.0e-9; + PDouble = *(double**)myPtr; + for (i = 1; i <= with0->get_Fnphases(); i++) + { + for (j = 1; j <= with0->get_Fnphases(); j++) + { + with0->YC->SetElement(i, j, cmplx(0.0, (*PDouble)*Factor)); + k++; + PDouble++; + } + } + } + *mySize = k; + break; + case 6: // LineCodes.AllNames + *myType = 4; //String + myStrArray.resize(0); + *mySize = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (LineCodeClass->ElementList.get_myNumList() > 0) + { + k = 0; + pLineCode = (TLineCodeObj*)LineCodeClass->ElementList.Get_First(); + while (pLineCode != nullptr) + { + WriteStr2Array(pLineCode->get_Name()); + WriteStr2Array(Char0()); + pLineCode = (TLineCodeObj*)LineCodeClass->ElementList.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + + +//-------------------------------------------------------------------------------- +// Implements the LoadShape interface for the DLL +//-------------------------------------------------------------------------------- + +TLoadShapeObj* ActiveLSObject = nullptr; + +int __stdcall LoadShapeI(int mode, int arg) +{ + int iElem; + int result = 0; + switch (mode) + { + case 0: // LoadShapes.Count + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = LoadShapeClass[ActiveActor]->ElementList.get_myNumList(); + } + break; + case 1: // LoadShapes.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + iElem = LoadShapeClass[ActiveActor]->Get_First(); + if (iElem != 0) + { + ActiveLSObject = (TLoadShapeObj*)ActiveDSSObject[ActiveActor]; + result = 1; + } + } + break; + case 2: // LoadShapes.Next + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + iElem = LoadShapeClass[ActiveActor]->Get_Next(); + if (iElem != 0) + { + ActiveLSObject = (TLoadShapeObj*)ActiveDSSObject[ActiveActor]; + result = iElem; + } + } + break; + case 3: // LoadShapes.Npts read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->get_FNumPoints(); + } + } + break; + case 4: + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->Set_NumPoints(arg); + } + } + break; + case 5: // LoadShapes.Normalize + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->Normalize(); + } + } + break; + case 6: // LoadShapes.UseActual read + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + if (ActiveLSObject->UseActual) + { + result = 1; + } + } + } + break; + case 7: // LoadShapes.UseActual write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + if (arg == 1) + { + ActiveLSObject->UseActual = true; + } + else + { + ActiveLSObject->UseActual = false; + } + } + } + break; + default: + result = -1; // The parameter is not valid + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall LoadShapeF(int mode, double arg) +{ + double result = 0.0; + switch (mode) + { + case 0: // LoadShapes.HrInterval read + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->Interval; + } + } + break; + case 1: // LoadShapes.HrInterval write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->Interval = arg; + } + } + break; + case 2: // LoadShapes.MinInterval read + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->Interval * 60.0; + } + } + break; + case 3: // LoadShapes.MinInterval write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->Interval = arg / 60.0; + } + } + break; + case 4: // LoadShapes.PBase read + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->BaseP; + } + } + break; + case 5: // LoadShapes.PBase write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->BaseP = arg; + } + } + break; + case 6: // LoadShapes.QBase read + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->BaseQ; + } + } + break; + case 7: // LoadShapes.QBase write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->BaseQ = arg; + } + } + break; + case 8: // LoadShapes.Sinterval read + result = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + result = ActiveLSObject->Interval * 3600.0; + } + } + break; + case 9: // LoadShapes.Sinterval write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + ActiveLSObject->Interval = arg / 3600.0; + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall LoadShapeS(int mode, char* arg) +{ + TLoadShapeObj* elem; + string result = ""; // Default return value + switch (mode) + { + case 0: // LoadShapes.Name read + result = ""; + elem = (TLoadShapeObj*)LoadShapeClass[ActiveActor]->GetActiveObj(); + if (elem != nullptr) + { + result = elem->get_Name(); + } + break; + case 1: // LoadShapes.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (LoadShapeClass[ActiveActor]->SetActive(std::string(arg))) + { + ActiveLSObject = (TLoadShapeObj*)LoadShapeClass[ActiveActor]->ElementList.Get_Active(); + ActiveDSSObject[ActiveActor] = ActiveLSObject; + } + else + { + DoSimpleMsg("Relay '" + std::string(arg) + "' Not Found in Active Circuit.", 77003); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall LoadShapeV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TLoadShapeObj* elem = nullptr; + int i = 0, + k = 0, + LoopLimit = 0; + TPointerList* pList = nullptr; + complex Sample = cmplx(0,0); + bool UseHour = false; + double* PDouble = nullptr; + + switch (mode) + { + case 0: // LoadShapes.AllNames + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (LoadShapeClass[ActiveActor]->ElementList.get_myNumList() > 0) + { + pList = &(LoadShapeClass[ActiveActor]->ElementList); + elem = (TLoadShapeObj*)pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->get_Name()); + WriteStr2Array(Char0()); + + // Need to sync this, otherwise we get name for one object, and data for another + ActiveLSObject = elem; + + elem = (TLoadShapeObj*)pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: // LoadShapes.PMult read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + myDblArray.resize(ActiveLSObject->get_FNumPoints()); + UseHour = (ActiveLSObject->Interval == 0); + for (k = 1; k <= ActiveLSObject->get_FNumPoints(); k++) + { + if (UseHour) + { + Sample = ActiveLSObject->GetMult(ActiveLSObject->Hours[k - 1]); + } + else + { + Sample = ActiveLSObject->GetMult(k * ActiveLSObject->Interval); + } + myDblArray[k - 1] = Sample.re; + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61001); + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 2: // LoadShapes.PMult write + *myType = 2; + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + auto with0 = ActiveLSObject; + if (*mySize > with0->get_FNumPoints()) + { + LoopLimit = with0->get_FNumPoints() - 1; + } + else + { + LoopLimit = *mySize - 1; + } + with0->PMultipliers.resize(with0->get_FNumPoints()); + PDouble = *(double**)myPtr; + for (i = 0; i <= LoopLimit; i++) + { + ActiveLSObject->PMultipliers[k] = *PDouble; + k++; + PDouble++; + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61002); + } + } + *mySize = k; + break; + case 3: // LoadShapes.QMult read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + if (!(ActiveLSObject->QMultipliers.empty())) + { + myDblArray.resize(ActiveLSObject->get_FNumPoints()); + UseHour = (ActiveLSObject->Interval == 0); + for (k = 1; k <= ActiveLSObject->get_FNumPoints(); k++) + { + if (UseHour) + { + Sample = ActiveLSObject->GetMult(ActiveLSObject->Hours[k - 1]); + } + else + { + Sample = ActiveLSObject->GetMult(k * ActiveLSObject->Interval); + } + myDblArray[k - 1] = Sample.im; + } + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61001); + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 4: // LoadShapes.QMult write + *myType = 2; //Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + auto with0 = ActiveLSObject; + if (*mySize > with0->get_FNumPoints()) + { + LoopLimit = with0->get_FNumPoints() - 1; + } + else + { + LoopLimit = *mySize - 1; + } + with0->QMultipliers.resize(with0->get_FNumPoints()); + PDouble = *(double**)myPtr; + for (i = 0; i <= LoopLimit; i++) + { + ActiveLSObject->QMultipliers[k] = *PDouble; + k++; + PDouble++; + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61002); + } + } + *mySize = k; + break; + case 5: // LoadShapes.Timearray read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + if (!(ActiveLSObject->Hours.empty())) + { + myDblArray.resize(ActiveLSObject->get_FNumPoints()); + for (k = 0; k < ActiveLSObject->get_FNumPoints(); k++) + { + myDblArray[k] = ActiveLSObject->Hours[k]; + } + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61001); + } + } + + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 6: // LoadShapes.Timearray write + *myType = 2; //Double + k = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveLSObject != nullptr) + { + auto with0 = ActiveLSObject; + if (*mySize > with0->get_FNumPoints()) + { + LoopLimit = with0->get_FNumPoints() - 1; + } + else + { + LoopLimit = *mySize - 1; + } + with0->Hours.resize(with0->get_FNumPoints()); + k = 0; + PDouble = *(double**)myPtr; + for (i = 0; i <= LoopLimit; i++) + { + ActiveLSObject->Hours[k] = *PDouble; + k++; + PDouble++; + } + } + else + { + DoSimpleMsg("No active Loadshape Object found.", 61002); + } + } + *mySize = k; + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Meters interface for the DLL +//-------------------------------------------------------------------------------- +int __stdcall MetersI(int mode, int arg) +{ + TEnergyMeterObj* pMeter = {}; + bool AssumeRestoration = false; + TPDElement* PD_Element = {}; + int result = 0; + + switch (mode) + { + case 0: // Meters.Rmatrix Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_First(); + if (pMeter != nullptr) + { + do + { + if (pMeter->FEnabled) + { + with0->Set_ActiveCktElement(pMeter); + result = 1; + } + else + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + } while (!(result > 0 || pMeter == nullptr)); + } + else + result = 0; // signify no more + } + break; + case 1: // Meters.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + if (pMeter != nullptr) + { + do + { + if (pMeter->FEnabled) + { + with0->Set_ActiveCktElement(pMeter); + result = 1; + } + else + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + } while (!(result > 0 || pMeter == nullptr)); + } + else + result = 0; // signify no more + } + break; + case 2: // Meters.Reset + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + pMeter->ResetRegisters(); + } + } + break; + case 3: // Meters.ResetAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + EnergyMeterClass[ActiveActor]->ResetAll(ActiveActor); + } + break; + case 4: // Meters.Sample + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + pMeter->TakeSample(ActiveActor); + } + } + break; + case 5: // Meters.Save + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + pMeter->SaveRegisters(ActiveActor); + } + } + break; + case 6: // Meters.MeteredTerminal read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + result = pMeter->MeteredTerminal; + } + else + result = 0; + } + break; + case 7: // Meters.MeterdTerminal Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + pMeter->MeteredTerminal = arg; + pMeter->MeteredElementChanged = true; + pMeter->RecalcElementData(ActiveActor); + } + } + break; + case 8: // Meters.DIFilesAreopen + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = 0; + if (DIFilesAreOpen[ActiveActor]) + { + result = 1; // Global variable + } + } + break; + case 9: // Meters.SampleAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + EnergyMeterClass[ActiveActor]->SampleAll(ActiveActor); + } + break; + case 10: // Meters.SaveAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + EnergyMeterClass[ActiveActor]->SaveAll(ActiveActor); + } + break; + case 11: // Meters.OpenAllDIFiles + if (ActiveCircuit[ActiveActor] != nullptr) + { + EnergyMeterClass[ActiveActor]->OpenAllDIFiles(ActiveActor); + } + break; + case 12: // Meters.CloseAllDIFiles + if (ActiveCircuit[ActiveActor] != nullptr) + { + EnergyMeterClass[ActiveActor]->CloseAllDIFiles(ActiveActor); + } + break; + case 13: // Meters.CountEndElements + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + result = pMeter->BranchList->ZoneEndsList->NumEnds; + } + } + break; + case 14: // Meters.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->EnergyMeters.NumInList; + } + break; + case 15: // Meters.CountBranches + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + result = pMeter->SequenceList->NumInList; + } + } + break; + case 16: // Meters.SequenceIndex read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + result = pMeter->SequenceList->ActiveItem; + } + } + break; + case 17: // Meters.SequenceIndex Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + if (arg > 0 && arg <= pMeter->SequenceList->NumInList) + { + with0->Set_ActiveCktElement((TEnergyMeterObj*)with1->SequenceList->Get(arg)); + } + else + DoSimpleMsg(Format("Invalid index for SequenceList: %d. List size is %d.", arg, with1->SequenceList->get_myNumList()), 500501); + } + } + break; + case 18: // Meters.DoReliabilityCalc + AssumeRestoration = false; + if (arg == 1) + { + AssumeRestoration = true; + } + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter) + { + pMeter->CalcReliabilityIndices(AssumeRestoration, ActiveActor); + } + } + break; + case 19: // Meters.SeqListSize + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + result = pMeter->SequenceList->NumInList; + } + } + break; + case 20: // Meters.TotalCustomers + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + PD_Element = (TPDElement*)pMeter->SequenceList->Get(1); + if (ASSIGNED(PD_Element)) + { + auto with1 = PD_Element; + + result = with0->Buses[with1->Terminals[with1->FromTerminal - 1].BusRef - 1]->BusTotalNumCustomers; + } + } + } + break; + case 21: // Meters.NumSections + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + result = pMeter->SectionCount; + } + break; + case 22: // Meters.SetActiveSection + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + if ((arg > 0) && (arg <= pMeter->SectionCount)) + pMeter->ActiveSection = arg; + else + pMeter->ActiveSection = 0; + } + } + break; + case 23: // Meters.OCPDeviceType + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + + if (with1->ActiveSection > 0) + result = with1->FeederSections[with1->ActiveSection].OCPDeviceType; + } + } + break; + case 24: // Meters.NumSectionCustomers + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + if (with1->ActiveSection > 0) + result = with1->FeederSections[with1->ActiveSection].NCustomers; + } + } + break; + case 25: // Meters.NumSectionBranches + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + if (with1->ActiveSection > 0) + result = with1->FeederSections[with1->ActiveSection].NBranches; + } + } + break; + case 26: // Meters.SectSeqidx + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + if (with1->ActiveSection > 0) + result = with1->FeederSections[with1->ActiveSection].SeqIndex; + } + } + break; + case 27: // Meters.SectTotalCust + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + auto with1 = pMeter; + if (with1->ActiveSection > 0) + result = with1->FeederSections[with1->ActiveSection].TotalCustomers; + } + } + break; + default: + result = -1; // The parameter is not valid + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall MetersF(int mode, double arg) +{ + TEnergyMeterObj* pMeterObj = nullptr; + double result = 0.0; // Default return value + + switch (mode) + { + case 0: // Meters.SAIFI + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->SAIFI; + } + } + break; + case 1: // Meters.SAIFIkW + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->SAIFIkW; + } + } + break; + case 2: // Meters.SAIDI + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->SAIDI; + } + } + break; + case 3: // Meters.CustInterrupts + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->CustInterrupts; + } + } + break; + case 4: // Meters.AvgRepairTime + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + auto with1 = pMeterObj; + if (with1->ActiveSection > 0) + { + result = with1->FeederSections[with1->ActiveSection].AverageRepairTime; + } + + } + } + break; + case 5: // Meters.FaultRateXRepairHrs + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + auto with1 = pMeterObj; + if (with1->ActiveSection > 0) + { + result = with1->FeederSections[with1->ActiveSection].SumFltRatesXRepairHrs; + } + } + } + break; + case 6: // Meters.SumBranchFltRates + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + auto with1 = pMeterObj; + if (with1->ActiveSection > 0) + { + result = with1->FeederSections[with1->ActiveSection].SumBranchFltRates; + } + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall MetersS(int mode, char* arg) +{ + TEnergyMeterObj* pMeterObj = {}; + int ActiveSave = 0; + string TestStr = ""; + bool Found = false; + string result = "0"; // Default return value + + switch (mode) + { + case 0: // Meters.Name Read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->LName; + } + } + break; + case 1: // Meters.Name Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->EnergyMeters; + TestStr = arg; + Found = false; + ActiveSave = with0.ActiveItem; + pMeterObj = (TEnergyMeterObj*)with0.Get_First(); + while (pMeterObj != nullptr) + { + if (CompareText(pMeterObj->LName, TestStr) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMeterObj); + Found = true; + break; + } + pMeterObj = (TEnergyMeterObj*)with0.Get_Next(); + } + if (not(Found)) + { + DoSimpleMsg("EnergyMeter \"" + TestStr + "\" Not Found in Active Circuit.", 5005); + pMeterObj = (TEnergyMeterObj*)with0.Get(ActiveSave); // Restore active Meter + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMeterObj); + } + } + break; + case 2: // Meters.MeteredElement read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + result = pMeterObj->ElementName; + } + else + result = ""; + } + break; + case 3: // Meters.MeteredElement Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + pMeterObj->ElementName = arg; + pMeterObj->MeteredElementChanged = true; + pMeterObj->RecalcElementData(ActiveActor); + } + } + break; + default: + result = "Error, Parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall MetersV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TEnergyMeterObj* pMeter = nullptr; + TEnergyMeterObj* pMeterObj = nullptr; + TEnergyMeterObj* MeterElem = nullptr; + int BranchCount = 0, + last = 0, + k = 0, + i = 0; + TDSSCktElement* cktElem = nullptr; + TDSSCktElement* shuntElement = nullptr; + TDSSCktElement* pElem = nullptr; + TDSSCktElement* elem = nullptr; + TCktTreeNode* node = nullptr; + StringArray* MyPCEList; + double* pDouble = nullptr; + + + switch (mode) + { + case 0: // Meters.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->EnergyMeters.NumInList > 0) + { + MeterElem = (TEnergyMeterObj*)with0->EnergyMeters.Get_First(); + while (MeterElem != nullptr) + { + WriteStr2Array(MeterElem->LName); + WriteStr2Array(Char0()); + MeterElem = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Meters.RegisterNames + *myType = 4; //string + myStrArray.resize(0); + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (ASSIGNED(pMeter)) + { + for (k = 0; k <= NumEMRegisters - 1; k++) + { + WriteStr2Array(pMeter->RegisterNames[k]); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 2: // Meters.RegisterValues + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor]) + { + pMeter = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (ASSIGNED(pMeter)) + { + myDblArray.resize(NumEMRegisters); + for (k = 0; k <= NumEMRegisters - 1; k++) + { + myDblArray[k] = pMeter->Registers[k]; + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 3: // Meters.Totals + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor]) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->TotalizeMeters(); + myDblArray.resize(NumEMRegisters); + for (i = 1; i <= NumEMRegisters; i++) + { + myDblArray[i - 1] = with0->RegisterTotals[i - 1]; + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 4: // Meters.PeakCurrent read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor]) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + myDblArray.resize(pMeterObj->Fnphases); + for (k = 0; k < pMeterObj->Fnphases; k++) + { + myDblArray[k] = pMeterObj->SensorCurrent[k]; + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 5: // Meters.PeakCurrent write + *myType = 2; //double + k = 1; + if (ActiveCircuit[ActiveActor]) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + pDouble = *(double**)myPtr; + for (i = 0; i < pMeterObj->Fnphases; i++) + { + pMeterObj->SensorCurrent[i] = *pDouble; + k++; + pDouble++; + } + } + } + *mySize = k - 1; + break; + case 6: // Meters.CalCurrent read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor]) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + myDblArray.resize(pMeterObj->Fnphases); + for (k = 0; k < pMeterObj->Fnphases; k++) + { + myDblArray[k] = cabs(pMeterObj->CalculatedCurrent[k]); + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 7: // Meters.CalcCurrent Write + *myType = 2; //double + k = 1; + if (ActiveCircuit[ActiveActor]) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + pDouble = *(double**)myPtr; + for (i = 0; i < pMeterObj->Fnphases; i++) + { + pMeterObj->CalculatedCurrent[i] = cmplx(*pDouble, 0.0); + k++; + pDouble++; + } + } + } + *mySize = k - 1; + break; + case 8: // Meters.AllocFactors read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + myDblArray.resize(pMeterObj->Fnphases); + for (i = 0; i < pMeterObj->Fnphases; i++) + { + myDblArray[k] = pMeterObj->PhsAllocationFactor[k]; + } + } + } + *mySize =myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 9: // Meters.AllocFactors Write + *myType = 2; //Double + k = 1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMeterObj = (TEnergyMeterObj*)ActiveCircuit[ActiveActor]->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + pDouble = *(double**)myPtr; + for (i = 0; i < pMeterObj->Fnphases; i++) + { + pMeterObj->PhsAllocationFactor[i] = *pDouble; // Just set the real part + k++; + pDouble++; + } + } + *mySize = k - 1; + } + break; + case 10: // Meters.AllEndElements + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + last = pMeterObj->BranchList->ZoneEndsList->NumEnds - 1; + for (k = 0; k <= last; k++) + { + pMeterObj->BranchList->ZoneEndsList->Get(k + 1, node); + elem = (TDSSCktElement*)node->CktObject; + WriteStr2Array(Format("%s.%s", elem->ParentClass->Class_Name.c_str(), elem->LName.c_str())); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 11: // Meters.AllBranchesInZone + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeterObj = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeterObj != nullptr) + { + BranchCount = MetersI(15, 0); + + if (BranchCount > 0) + { + pElem = (TDSSCktElement*)pMeterObj->BranchList->Get_First(); + while (pElem != nullptr) + { + WriteStr2Array(Format("%s.%s", pElem->ParentClass->Class_Name.c_str(), pElem->LName.c_str())); + WriteStr2Array(Char0()); + pElem = (TDSSCktElement*)pMeterObj->BranchList->Get_Forward(); + } + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 12: // Meters.AllPCEinZone + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Active(); + if (pMeter != nullptr) + { + pMeter->GetPCEatZone(); + if ((pMeter->ZonePCE.size() > 0) && !(pMeter->ZonePCE[0].empty())) + { + for (k = 0; k < pMeter->ZonePCE.size(); k++) + { + WriteStr2Array(pMeter->ZonePCE[k]); + WriteStr2Array(Char0()); + + } + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + default: + *myType = 4; // string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Monitors interface for the DLL +//-------------------------------------------------------------------------------- + +struct THeaderRec { + int Signature; + int Version; + int RecordSize; + int Mode; + TMonitorStrBuffer dummyRec; +}; + +void ReadMonitorHeader(THeaderRec* HeaderRec, bool Opt) +{ + TMonitorObj* mypMon = {}; + mypMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + // This is different since the memory streams are not native to C, it was implemented exernally to mimic its behavior + auto &with0 = mypMon->MonitorStream; + auto with1 = HeaderRec; + + with0.begin(); + with0.Read(&(with1->Signature), sizeof(with1->Signature)); + with0.Read(&(with1->Version), sizeof(with1->Version)); + with0.Read(&(with1->RecordSize), sizeof(with1->RecordSize)); + with0.Read(&(with1->Mode), sizeof(with1->Mode)); + with0.Read((uint8_t*)&with1->dummyRec[0], sizeof(with1->dummyRec)); + if (Opt) + { + // If opt is false leave monitorstream at end of header record + mypMon->MonitorStream.end(); // put monitor stream pointer back where it was + } + +} +// ******************************int type properties************************* +int __stdcall MonitorsI(int mode, int arg) +{ + TMonitorObj* pMon = {}; + THeaderRec Header; + int result = 0; + switch (mode) + { + case 0: // Monitors.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_First(); + if (pMon != nullptr) + { + do + { + if (pMon->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMon); + result = 1; + } + else + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Next(); + } while (!((result == 1) || (pMon == nullptr))); + } + } + break; + case 1: // Monitors.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Next(); + if (pMon != nullptr) + { + do + { + if (pMon->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMon); + result = 1; + } + else + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Next(); + } while (!((result == 1) || (pMon == nullptr))); + } + } + break; + case 2: // Monitors.Reset + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->ResetIt(ActiveActor); + } + } + break; + case 3: // Monitors.ResetAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + MonitorClass[ActiveActor]->ResetAll(ActiveActor); + } + break; + case 4: // Monitors.Sample + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->TakeSample(ActiveActor); + } + } + break; + case 5: // Monitors.Save + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->Save(); + } + } + break; + case 6: // Monitors.Show + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->TranslateToCSV(true, ActiveActor); + } + } + break; + case 7: // Monitors.Mode read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + result = pMon->Mode; + } + } + break; + case 8: // Monitors.Mode write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->Mode = arg; + pMon->ResetIt(ActiveActor); // Always reset the monitor after a Mode change + } + } + break; + case 9: // Monitors.SampleCount + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + result = pMon->SampleCount; + } + break; + case 10: // Monitors.SampleAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + MonitorClass[ActiveActor]->SampleAll(ActiveActor); + } + break; + case 11: // Monitors.SaveAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + MonitorClass[ActiveActor]->SaveAll(ActiveActor); + } + break; + case 12: // Monitors.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->Monitors.NumInList; + } + break; + case 13: // Monitors.Process + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + pMon->PostProcess(ActiveActor); + } + break; + case 14: // Monitors.ProcessAll + if (ActiveCircuit[ActiveActor] != nullptr) + { + MonitorClass[ActiveActor]->PostProcessAll(ActiveActor); + } + break; + case 15: // Monitors.FileVersion + if (ActiveCircuit[ActiveActor] != nullptr) + { + ReadMonitorHeader(&Header, false);// leave at beginning of data; + result = Header.Version; + } + break; + case 16: // Monitors.RecordSize + if (ActiveCircuit[ActiveActor] != nullptr) + { + ReadMonitorHeader(&Header, true); + result = Header.RecordSize; + } + break; + case 17: // Monitors.NumChannels + if (ActiveCircuit[ActiveActor] != nullptr) + { + ReadMonitorHeader(&Header, true); + result = Header.RecordSize; + } + break; + case 18: // Monitors.Terminal read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + result = pMon->MeteredTerminal; + } + } + break; + case 19: // Monitors.Terminal write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + pMon->MeteredTerminal = arg; + pMon->RecalcElementData(ActiveActor); + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall MonitorsS(int mode, char* arg) +{ + TMonitorObj* pMon = nullptr; + THeaderRec Header; + int activesave = 0; + bool Found = false; + string S = "", + result = "0"; // Default return value + + switch (mode) + { + case 0: // Monitors.FileName + result = ""; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + result = pMon->Get_FileName(ActiveActor); // Default return value + } + } + break; + case 1: // Monitors.Name read + result = ""; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + result = pMon->LName; // Default return value + } + } + break; + case 2: // Monitors.Name Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->Monitors; + S = arg; + Found = false; + pMon = (TMonitorObj*)with0.Get_First(); + while (pMon != nullptr) + { + if (CompareText(pMon->LName, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMon); + Found = true; + break; + } + pMon = (TMonitorObj*)with0.Get_Next(); + } + if (not(Found)) + { + DoSimpleMsg("Monitor \"" + S + "\" Not Found in Active Circuit.", 5004); + pMon = (TMonitorObj*)with0.Get(activesave); // Restore active Monerator + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pMon); + } + } + result = ""; + break; + case 3: // Monitors.Element read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + result = pMon->ElementName; // Default return value + } + } + break; + case 4: // Monitors.Element write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + S = arg; + pMon->ElementName = S; + pMon->FPropertyValue[1] = S; + pMon->RecalcElementData(ActiveActor); + } + } + result = "Error, parameter not valid"; + break; + default: + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall MonitorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TMonitorObj* MonitorElem = nullptr; + TMonitorObj* pMon = nullptr; + int AllocSize = 0, + i = 0, + k = 0, + index = 0, + ListSize = 0; + THeaderRec Header; + string TempStr = "", + SaveDelims = "", + SaveWhiteSpace = "", + FirstCol = ""; + float hr = 0.0, s = 0.0; + float sngFreq = 0.0, sngHarm= 0.0; + vector SngBuffer; + int* PInt = nullptr; + + + switch (mode) + { + case 0: // Monitors.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Monitors.NumInList > 0) + { + MonitorElem = (TMonitorObj*)with0->Monitors.Get_First(); + while (MonitorElem != nullptr) + { + WriteStr2Array(MonitorElem->LName); + WriteStr2Array(Char0()); + MonitorElem = (TMonitorObj*)with0->Monitors.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Monitors.ByteStream + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon != nullptr) + { + myStrArray.resize(pMon->MonitorStream.Size()); + pMon->MonitorStream.begin(); + pMon->MonitorStream.Read(&(myStrArray[0]), pMon->MonitorStream.Size()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 2: // Monitors.Header + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon->StrBuffer.size() > 0) + { + ReadMonitorHeader(&Header, false);// leave at beginning of data; + ListSize = Header.RecordSize; + SaveDelims = AuxParser[ActiveActor]->DelimChars; + AuxParser[ActiveActor]->DelimChars = ","; + SaveWhiteSpace = AuxParser[ActiveActor]->WhiteSpaceChars; + AuxParser[ActiveActor]->WhiteSpaceChars = ""; + AuxParser[ActiveActor]->SetCmdString(pMon->StrBuffer.data()); + AuxParser[ActiveActor]->FAutoIncrement = true; + AuxParser[ActiveActor]->MakeString_(); + AuxParser[ActiveActor]->MakeString_(); + k = 0; + while (k < ListSize) + { + WriteStr2Array(AuxParser[ActiveActor]->MakeString_()); + WriteStr2Array(Char0()); + k++; + } + AuxParser[ActiveActor]->FAutoIncrement = false; + AuxParser[ActiveActor]->DelimChars = SaveDelims; + AuxParser[ActiveActor]->WhiteSpaceChars = SaveWhiteSpace; + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 3: // Monitors.dblHour + *myType = 2; // double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon->SampleCount > 0) + { + myDblArray.resize(pMon->SampleCount); + ReadMonitorHeader(&Header, false);// leave at beginning of data + AuxParser[ActiveActor]->SetCmdString(pMon->StrBuffer.data()); + AuxParser[ActiveActor]->FAutoIncrement = true; + FirstCol = AuxParser[ActiveActor]->MakeString_(); + AuxParser[ActiveActor]->FAutoIncrement = false; + // check first col to see if it is "Hour" + if (CompareText(FirstCol, "hour") == 0) + { + AllocSize = sizeof(float) * Header.RecordSize; + SngBuffer.resize(Header.RecordSize); + k = 0; + auto& monStream = pMon->MonitorStream; + for (i = 1; i <= pMon->SampleCount; i++) + { + monStream.Read(&hr, sizeof(hr));// Hour + monStream.Read(&s, sizeof(s));// Seconds past the hour + monStream.Read(&(SngBuffer[0]), AllocSize); + myDblArray[k] = hr + s / 3600.0; + k++; + } + SngBuffer.clear(); // Dispose of buffer + } + else // Not time solution, so return nil array + pMon->MonitorStream.end(); + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 4: // Monitors.dblFreq + *myType = 2; // double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon->SampleCount > 0) + { + myDblArray.resize(pMon->SampleCount); + ReadMonitorHeader(&Header, false);// leave at beginning of data + AuxParser[ActiveActor]->SetCmdString(pMon->StrBuffer.data()); + AuxParser[ActiveActor]->FAutoIncrement = true; + FirstCol = AuxParser[ActiveActor]->MakeString_(); + AuxParser[ActiveActor]->FAutoIncrement = false; + // check first col to see if it is "freq" + if (CompareText(FirstCol, "freq") == 0) + { + AllocSize = sizeof(float) * Header.RecordSize; + SngBuffer.resize(AllocSize); + k = 0; + auto& monStream = pMon->MonitorStream; + for (i = 1; i <= pMon->SampleCount; i++) + { + monStream.Read(&sngFreq, sizeof(sngFreq));// frequency + monStream.Read(&sngHarm, sizeof(sngHarm));// harmonic + monStream.Read(&(SngBuffer[0]), AllocSize); + myDblArray[k] = sngFreq; + k++; + } + SngBuffer.clear(); // Dispose of buffer + } + else // Not time solution, so return nil array + pMon->MonitorStream.end(); + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 5: // Monitors.Channel + *myType = 2; // double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pMon = (TMonitorObj*)ActiveCircuit[ActiveActor]->Monitors.Get_Active(); + if (pMon->SampleCount > 0) + { + PInt = *(int**)myPtr; + index = *PInt; + myDblArray.resize(pMon->SampleCount); + ReadMonitorHeader(&Header, false);// leave at beginning of data + AuxParser[ActiveActor]->SetCmdString(pMon->StrBuffer.data()); + AuxParser[ActiveActor]->FAutoIncrement = true; + FirstCol = AuxParser[ActiveActor]->MakeString_(); + AuxParser[ActiveActor]->FAutoIncrement = false; + AuxParser[ActiveActor]->FAutoIncrement = false; + AllocSize = sizeof(float) * Header.RecordSize; + SngBuffer.resize(AllocSize); + + k = 0; + auto& monStream = pMon->MonitorStream; + for (i = 1; i <= pMon->SampleCount; i++) + { + monStream.Read(&hr, sizeof(hr)); + monStream.Read(&s, sizeof(s)); + monStream.Read((&(SngBuffer[0])), AllocSize); + + myDblArray[k] = (double)SngBuffer[index]; + k++; + } + SngBuffer.clear(); // Dispose of buffer + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + default: + *myType = 4; // String + myStrArray.clear(); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Parallel interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall ParallelI(int mode, int arg) +{ + int result = 0; //Default Return Value + switch (mode) + { + case 0: // Parallel.NumCPUs + result = CPU_Cores; + break; + case 1: // Parallel.NumCores + result = round(CPU_Cores / 2); + break; + case 2: // Parallel.ActiveActor read + result = ActiveActor; + break; + case 3: // Parallel.ActiveActor write + if (arg <= NumOfActors) + { + ActiveActor = arg; + } + else + DoSimpleMsg("The actor does not exist", 7002); + break; + case 4: // Parallel.CreateActor + New_Actor_Slot(); + break; + case 5: // Parallel.ActorCPU read + result = ActorCPU[ActiveActor]; + break; + case 6: // Parallel.ActorCPU write + if (arg < CPU_Cores) + { + ActorCPU[ActiveActor] = arg; + if (ActorHandle[ActiveActor] != nullptr) + { + // in this version we don't provide hread affinity support given the cross platform compatibility + ActorHandle[ActiveActor]->Doterminate(); + } + } + break; + case 7: // Parallel.NumActors + result = NumOfActors; + break; + case 8: // Parallel.Wait + if (Parallel_enabled) + { + Wait4Actors(0); + } + break; + case 9: // Parallel.ActiveParallel read + if (Parallel_enabled) + { + result = 1; + } + else result = 0; + break; + case 10: // Parallel.ActiveParallel write + if (arg != 0) + { + Parallel_enabled = true; + } + else + Parallel_enabled = false; + break; + case 11: // Parallel.ConcatenateReports Read + if (ConcatenateReports) + { + result = 1; + } + else result = 0; + break; + case 12: // Parallel.ConcatenateReports Write + if (ConcatenateReports) + { + ConcatenateReports = true; + } + else ConcatenateReports = false; + break; + default: + result = -1; + break; + } + return result; +} +//************************Structure type properties******************************* +void __stdcall ParallelV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int i = 0; + + switch (mode) + { + case 0: // Parallel.ActorProgress + *myType = 1; //integer + myIntArray.resize(NumOfActors); + for (i = 1; i <= NumOfActors; i++) + { + myIntArray[i - 1] = ActorPctProgress[i]; + } + *mySize =myIntArray.size() * sizeof(myIntArray[0]); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 1: // Parallel.ActorStatus + *myType = 1; //integer + myIntArray.resize(NumOfActors); + for (i = 1; i <= NumOfActors; i++) + { + myIntArray[i - 1] = ActorStatus[i]; + } + *mySize = myIntArray.size() * sizeof(int); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +TParser* ComParser = new TParser; + +//-------------------------------------------------------------------------------- +// Implements the Parser interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall ParserI(int mode, int arg) +{ + + int result = 0; + switch (mode) + { + case 0: // Parser.IntValue + result = ComParser->MakeInteger_(); + break; + case 1: // Parser.ResetDelimeters + ComParser->ResetDelims(); + break; + case 2: // Parser.AutoIncrement read + if (ComParser->FAutoIncrement) + { + result = 1; + } + break; + case 3: // Parser.AutoIncrement write + if (arg == 1) + { + ComParser->FAutoIncrement = true; + } + else + ComParser->FAutoIncrement = false; + break; + default: + int result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall ParserF(int mode, double arg) +{ + double result = 0.0; + switch (mode) + { + case 0: // Parser.DblValue + result = ComParser->MakeDouble_(); + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall ParserS(int mode, char* arg) +{ + string result = 0; + switch (mode) + { + case 0: // Parser.CmdString read - CHECK + result = ComParser->CmdBuffer; + break; + case 1: // Parser.CmdString write + ComParser->SetCmdString(arg); + break; + case 2: // Parser.NextParam + result = ComParser->GetNextParam(); + break; + case 3: // Parser.StrValue + result = ComParser->MakeString_(); + break; + case 4: // Parser.WhiteSpace read + result = ComParser->WhiteSpaceChars; + break; + case 5: // Parser.WhiteSpace write + ComParser->set_WhiteSpaceChars(arg); + break; + case 6: // Parser.BeginQuote read + result = ComParser->FBeginQuoteChars; + break; + case 7: // Parser.BeginQuote write + ComParser->set_FBeginQuoteChars(arg); + break; + case 8: // Parser.EndQuote read + result = ComParser->FEndQuoteChars; + break; + case 9: // Parser.EndQuote write + ComParser->FEndQuoteChars =arg; + break; + case 10: // Parser.Delimiters read + result = ComParser->DelimChars; + break; + case 11: // Parser.Delimiters write + ComParser->set_delimchars(arg); + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall ParserV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int i = 0, + ActualSize = 0, + ExpectedSize = 0, + ExpectedOrder = 0, + MatrixSize = 0; + vector VectorBuffer, + MatrixBuffer; + + switch (mode) + { + case 0: // Parser.Vector + *myType = 2; //double + myDblArray.resize(1); + ExpectedSize = int(*mySize); + VectorBuffer.resize(ExpectedSize + 1); + ActualSize = ComParser->ParseAsVector(ExpectedSize, &(VectorBuffer[1])); + myDblArray.resize(ActualSize); + for (i = 0; i <= ActualSize - 1; i++) + { + myDblArray[i] = VectorBuffer [i + 1]; + } + VectorBuffer.clear(); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 1: // Parser.Matrix + *myType = 2; //double + myDblArray.resize(1); + ExpectedOrder = int(*mySize); + MatrixSize = ExpectedOrder * ExpectedOrder; + MatrixBuffer.resize(MatrixSize + 1); + ComParser->ParseAsMatrix(ExpectedOrder, &(MatrixBuffer[1])); + myDblArray.resize(MatrixSize); + for (i = 0; i <= MatrixSize - 1; i++) + { + myDblArray[i] = MatrixBuffer[i + 1]; + } + MatrixBuffer.clear(); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 2: // Parser.SymMatrix + *myType = 2; //double + myDblArray.resize(1); + ExpectedOrder = int(*mySize); + MatrixSize = ExpectedOrder * ExpectedOrder; + MatrixBuffer.resize(MatrixSize + 1); + ComParser->ParseAsSymMatrix(ExpectedOrder, &(MatrixBuffer[1])); + myDblArray.resize(MatrixSize); + for (i = 0; i <= MatrixSize - 1; i++) + { + myDblArray[i] = MatrixBuffer[i + 1]; + } + MatrixBuffer.clear(); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size() ; + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the PDElements interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall PDElementsI(int mode, int arg) +{ + TPDElement* ActivePDElement = nullptr; + int result = 0; + switch (mode) + { + case 0: // PDElementsI.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + result = with0->PDElements.NumInList; + } + break; + case 1: // PDElementsI.First + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + ActivePDElement = (TPDElement*)with0->PDElements.Get_First(); + if (ActivePDElement != nullptr) + { + do + { + if (ActivePDElement->FEnabled) + { + result = 1; + with0->Set_ActiveCktElement(ActivePDElement); + } + else + ActivePDElement = (TPDElement*)with0->PDElements.Get_Next(); + } while (!((result == 1) || (ActivePDElement == nullptr))); + } + } + break; + case 2: // PDElementsI.Next + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + ActivePDElement = (TPDElement*)with0->PDElements.Get_Next(); + if (ActivePDElement != nullptr) + { + do + { + if (ActivePDElement->FEnabled) + { + result = 1; + with0->Set_ActiveCktElement(ActivePDElement); + } + else + ActivePDElement = (TPDElement*)with0->PDElements.Get_Next(); + } while (!((result > 0) || (ActivePDElement == nullptr))); + } + } + break; + case 3: // PDElementsI.IsShunt + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + if (ActivePDElement->IsShunt) + { + result = 1; + } + } + } + break; + case 4: // PDElementsI.NumCustomers + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->BranchNumCustomers; + + } + } + break; + case 5: // PDElementsI.TotalCustomers + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->BranchTotalCustomers; + + } + } + break; + case 6: // PDElementsI.ParentPDElement + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + if (ActivePDElement->ParentPDElement != nullptr) + { + with0->Set_ActiveCktElement(ActivePDElement->ParentPDElement); + result = with0->FActiveCktElement->ClassIndex; + } + } + } + break; + case 7: // PDElementsI.FromTerminal + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->FromTerminal; + } + } + break; + case 8: // PDElementsI.SectionID + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->BranchSectionID; + } + } + break; + default: + result = -1; + break; + } + return result; +} +// ******************************floating point type properties************************* +double __stdcall PDElementsF(int mode, double arg) +{ + TPDElement* ActivePDElement = {}; + double result = 0.0; + switch (mode) + { + case 0: // PDElementsI.FaultRate read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->FaultRate; + } + } + break; + case 1: // PDElementsI.FaultRate write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + ActivePDElement->FaultRate = arg; + } + } + break; + case 2: // PDElementsI.PctPermanent read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->PctPerm; + } + } + break; + case 3: // PDElementsI.PctPermanent write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + ActivePDElement->PctPerm = arg; + } + } + break; + case 4: // PDElementsI.Lambda + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->BranchFltRate; + } + } + break; + case 5: // PDElementsI.AccumulatedL + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->AccumulatedBrFltRate; + } + } + break; + case 6: // PDElementsI.RepairTime + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->HrsToRepair; + } + } + break; + case 7: // PDElementsI.TotalMiles + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + result = ActivePDElement->AccumulatedMilesDownStream; + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall PDElementsS(int mode, char* arg) +{ + TPDElement* ActivePDElement = nullptr; + string result = "", // Default return value + TestString = ""; + + switch (mode) + { + case 0: // PDElementsI.Name read + result = ""; // return null if not a PD element + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (dynamic_cast(with0->FActiveCktElement) != nullptr) + { + ActivePDElement = (TPDElement*)with0->FActiveCktElement; + auto with1 = ActivePDElement; + result = Format("%s.%s", with1->ParentClass->Class_Name.c_str(), with1->LName.c_str()); // full name + } + } + break; + case 1: // PDElementsI.Name write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + TestString = arg; + // Search through list of PD Elements until we find this one + ActivePDElement = (TPDElement*)with0->PDElements.Get_First(); + while (ASSIGNED(ActivePDElement)) + { + auto with1 = ActivePDElement; + if (CompareText(TestString, Format("%s.%s", with1->ParentClass->Class_Name.c_str(), with1->LName.c_str()))) + { + with0->Set_ActiveCktElement(ActivePDElement); + break; + } + ActivePDElement = (TPDElement*)with0->PDElements.Get_Next(); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + +//-------------------------------------------------------------------------------- +// Implements the PVsystems interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall PVsystemsI(int mode, int arg) +{ + TPVsystemObj* pPVSystem = nullptr; + int result = 0; + + switch (mode) + { + case 0: // PVsystems.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->PVSystems.NumInList; + } + break; + case 1: // PVsystems.First + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + if (pPVSystem != nullptr) + { + do + { + if (pPVSystem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pPVSystem); + result = 1; + } + else + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } while (!((result == 1) || (pPVSystem == nullptr))); + } + } + else + result = 0; + break; + case 2: // PVsystems.Next + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + if (pPVSystem != nullptr) + { + do + { + if (pPVSystem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pPVSystem); + result = ActiveCircuit[ActiveActor]->PVSystems.ActiveItem; + } + else + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } while (!((result > 0) || pPVSystem == nullptr)); + } + } + else + result = 0; + break; + case 3: // PVsystems.Idx read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->PVSystems.ActiveItem; + } + else + result = 0; + break; + case 4: // PVsystems.Idx write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get(arg); + if (pPVSystem != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pPVSystem); + } + } + break; + default: + result = -1; + break; + } + return result; +}// ******************************floating point type properties************************* +//******************************Float point type properties**************************** +double __stdcall PVsystemsF(int mode, double arg) +{ + double result = 0.0; // Default return value + switch (mode) + { + case 0: // PVsystems.Irradiance readif (ActiveCircuit[ActiveActor] != nullptr) + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->PVSystemVars.FIrradiance; + } + } + break; + case 1: // PVsystems.Irradiance write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + ((TPVsystemObj*)with0.Get_Active())->PVSystemVars.FIrradiance = arg; + } + } + break; + case 2: // PVsystems.kW + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->Get_PresentkW(); + } + } + break; + case 3: // PVsystems.kvar read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->Get_Presentkvar(); + } + } + break; + case 4: // PVsystems.kvar write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + ((TPVsystemObj*)with0.Get_Active())->Set_Presentkvar(arg); + } + } + break; + case 5: // PVsystems.pf read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->PFNominal; + } + } + break; + case 6: // PVsystems.pf write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + ((TPVsystemObj*)with0.Get_Active())->PFNominal = arg; + } + } + break; + case 7: // PVsystems.KVARated read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->Get_FkVArating(); + } + } + break; + case 8: // PVsystems.KVARated write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + ((TPVsystemObj*)with0.Get_Active())->Set_kVARating(arg); + } + } + break; + case 9: // PVsystems.pmpp read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->Get_FPmpp(); + } + } + break; + case 10: // PVsystems.pmpp write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + ((TPVsystemObj*)with0.Get_Active())->Set_Pmpp(arg); + } + } + break; + case 11: // PVsystems.IrradianceNow + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + if (with0.ActiveItem != 0) + { + result = ((TPVsystemObj*)with0.Get_Active())->Get_PresentIrradiance(); + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall PVsystemsS(int mode, char* arg) +{ + TPVsystemObj* pPVSystem = nullptr; + TPVsystemObj* PVSystem = nullptr; + int ActiveSave = 0; + bool Found = false; + string S = "", + result = ""; + + switch (mode) + { + case 0: // PVsystems.Name read + if (ActiveCircuit[ActiveActor] != nullptr) + { + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_Active(); + if (pPVSystem != nullptr) + { + result = pPVSystem->LName; + } + else + result = ""; // signify no name + } + break; + case 1: // PVsystems.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->PVSystems; + S = arg; + Found = false; + ActiveSave = with0.ActiveItem; + PVSystem = (TPVsystemObj*)with0.Get_First(); + while (PVSystem != nullptr) + { + if (CompareText(PVSystem->LName, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(PVSystem); + Found = true; + break; + } + PVSystem = (TPVsystemObj*)with0.Get_Next(); + } + if (not(Found)) + { + DoSimpleMsg("PVSystem \"" + S + "\" Not Found in Active Circuit.", 5003); + PVSystem = (TPVsystemObj*)with0.Get(ActiveSave);// Restore active PVSystem + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(PVSystem); + } + } + break; + case 2: // PVsystems.Sensor + if (ActiveCircuit[ActiveActor] != nullptr) + { + pPVSystem = (TPVsystemObj*)ActiveCircuit[ActiveActor]->PVSystems.Get_Active(); + if (pPVSystem != nullptr && pPVSystem->SensorObj != nullptr) + { + result = pPVSystem->SensorObj->get_Name(); + } + else + result = ""; // signify no name + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall PVsystemsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TPVsystemObj* PVSystemElem=nullptr; + + switch (mode) + { + case 0: // PVsystems.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->PVSystems.NumInList) + { + PVSystemElem = (TPVsystemObj*) with0->PVSystems.Get_First(); + while (PVSystemElem != nullptr) + { + WriteStr2Array(PVSystemElem->LName); + WriteStr2Array(Char0()); + PVSystemElem = (TPVsystemObj*) with0->PVSystems.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Reclosers interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Help Functions************************* +void Set_ParameterReC(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("recloser.%s.%s=%s", ((TRecloserObj*)RecloserClass->GetActiveObj())->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} + +// ******************************int type properties************************* +int __stdcall ReclosersI(int mode, int arg) +{ + int result = 0; + TRecloserObj* pElem = nullptr; + TRecloserObj* elem = nullptr; + TRecloserObj* pRecloser = nullptr; + + + switch(mode) + { + case 0: // Reclosers.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = RecloserClass->ElementList.NumInList; + } + break; + case 1: // Reclosers.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TRecloserObj*)RecloserClass->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + pElem = (TRecloserObj*)RecloserClass->ElementList.Get_Next(); + } while (!(result == 1 || pElem == nullptr)); + } + } + break; + case 2: // Reclosers.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TRecloserObj*)RecloserClass->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = RecloserClass->ElementList.ActiveItem; + } + else + pElem = (TRecloserObj*)RecloserClass->ElementList.Get_Next(); + } while (!(result > 0 || pElem == nullptr)); + } + } + break; + case 3: // Reclosers.MonitoredTerm read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementTerminal; + } + break; + case 4: // Reclosers.MonitoredTerm write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("monitoredterm", IntToStr(arg)); + } + break; + case 5: // Reclosers.SwitchedTerm read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->ElementTerminal; + } + break; + case 6: // Reclosers.SwitchedTerm write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("SwitchedTerm", IntToStr(arg)); + } + break; + case 7: // Reclosers.NumFast read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->NumFast; + } + break; + case 8: // Reclosers.NumFast write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("numfast", IntToStr(arg)); + } + break; + case 9: // Reclosers.Shots read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->NumReclose + 1; + } + break; + case 10: // Reclosers.Shots write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("shots", IntToStr(arg)); + } + break; + case 11: // Reclosers.Open -CHECK + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + elem->set_State(CTRL_OPEN); + } + break; + case 12: // Reclosers.Close + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + elem->set_State(CTRL_CLOSE); + } + break; + case 13: // Reclosers.Idx read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = RecloserClass->ElementList.ActiveItem; + } + else + result = 0; + break; + case 14: // Reclosers.Idx write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pRecloser = (TRecloserObj*)RecloserClass->ElementList.Get(arg); + if (pRecloser != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pRecloser); + } + } + else + result = 0; + break; + case 15: // Reclosers.Reset + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + elem->Reset(ActiveActor); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall ReclosersF(int mode, double arg) +{ + double result = 0.0; // Default return value + TRecloserObj* elem = nullptr; + + switch (mode) + { + case 0: // Reclosers.PhaseTrip read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->PhaseTrip; + } + break; + case 1: // Reclosers.PhaseTrip write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("PhaseTrip", Format("%.g", arg)); + } + break; + case 2: // Reclosers.PhaseInst read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->PhaseInst; + } + break; + case 3: // Reclosers.PhaseInst write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("Phaseinst", Format("%.g", arg)); + } + break; + case 4: // Reclosers.GroundTrip read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->GroundTrip; + } + break; + case 5: // Reclosers.GroundTrip write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("GroundTrip", Format("%.g", arg)); + } + break; + case 6: // Reclosers.GroundInst read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->GroundInst; + } + break; + case 7: // Reclosers.GroundInst write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("GroundInst", Format("%.g", arg)); + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall ReclosersS(int mode, char* arg) +{ + TRecloserObj* elem = nullptr; + string result = "", // Default return value + S = ""; + + switch (mode) + { + case 0: // Reclosers.Name read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->LName; + } + break; + case 1: // Reclosers.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (RecloserClass->SetActive(arg)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TRecloserObj*)RecloserClass->ElementList.Get_Active()); + } + else + DoSimpleMsg("Recloser " + (string)arg + " Not Found in Active Circuit.", 77003); + + } + break; + case 2: // Reclosers.MonitoredObj read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementName; + } + break; + case 3: // Reclosers.MonitoredObj write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("monitoredObj", (string)arg); + } + break; + case 4: // Reclosers.SwitchedObj read + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->ElementName; + } + break; + case 5: // Reclosers.SwitchedObj write + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterReC("SwitchedObj", arg); + } + break; + case 6: // Reclosers.State readTBD + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + if (elem->get_State() == CTRL_CLOSE) + result = "closed"; + else + result = "open"; + } + break; + case 7: // Reclosers.State write TBD + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + S = arg; + if (LowerCase(S)[0] == 'c') + elem->set_State(CTRL_CLOSE); + else + elem->set_State(CTRL_OPEN); + } + break; + case 8: // Reclosers.NormalState read TBD + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + if (elem->FNormalState == CTRL_CLOSE) + result = "closed"; + else + result = "open"; + } + break; + case 9: // Reclosers.NormalState write TBD + elem = (TRecloserObj*)RecloserClass->GetActiveObj(); + if (elem != nullptr) + { + S = arg; + if (LowerCase(S)[0] == 'c') + elem->set_NormalState(CTRL_CLOSE); + else + elem->set_NormalState(CTRL_OPEN); + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall ReclosersV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TRecloserObj* elem = nullptr; + TPointerList* pList = nullptr; + int k = 0, + i = 0; + switch (mode) + { + case 0: // Reclosers.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (RecloserClass->ElementList.NumInList > 0) + { + pList = &(RecloserClass->ElementList); + elem = (TRecloserObj*)pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TRecloserObj*)pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Reclosers.RecloseIntervals + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TRecloserObj*)RecloserClass->ElementList.Get_Active(); + if (elem != nullptr) + { + myDblArray.resize(elem->NumReclose); + k = 0; + for (i = 1; i <= elem->NumReclose; i++) + { + myDblArray[k] = elem->RecloseIntervals[i - 1]; + k++; + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the ReduceCkt interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* + +int __stdcall ReactorsI(int mode, int arg) +{ + int Result = 0; + TReactorObj* Elem = nullptr; + TPointerList pList = {}; + + switch (mode) + { + case 0: // Reactors.First + if (ReactorClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = ReactorClass[ActiveActor]->ElementList; + Elem = (TReactorObj*)pList.Get_First(); + do + { + if (Elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Elem); + Result = 1; + } + else + Elem = (TReactorObj*)pList.Get_Next(); + } while ((Result == 0) && (ASSIGNED(Elem))); + } + else + Result = 0; // signify no more + break; + case 1: // Reactors.Next + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + + if (ReactorClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = ReactorClass[ActiveActor]->ElementList; + Elem = (TReactorObj*)pList.Get_First(); + do + { + if (Elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Elem); + Result = pList.ActiveItem; + } + else + Elem = (TReactorObj*)pList.Get_Next(); + } + while( (Result == 0) && (ASSIGNED(Elem))); + } + else + Result = 0; // signify no more + } + break; + case 2: // Reactors.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + Result = ReactorClass[ActiveActor]->ElementList.NumInList; + break; + case 3: // Parallel.read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + if (Elem->IsParallel) + Result = 1; + } + break; + case 4: // Parallel.write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Elem->IsParallel = (arg > 0); + } + break; + default: + Result = -1; // The user is asking for the wrong command + break; + } + return Result; +} + +//******************************Float point type properties**************************** +double __stdcall ReactorsF(int mode, double arg) +{ + double Result = 0.0; + TReactorObj* Elem = nullptr; + TPointerList pList = {}; + + switch (mode) + { + case 0: // Reactor.kV Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->kvrating; + break; + case 1: // Reactor.kV Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->kvrating = arg; + break; + case 2: // Reactor.kvar Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->kvarrating; + break; + case 3: // Reactor.kvar Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->kvarrating = arg; + break; + case 4: // Reactor.lmH Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->l; + break; + case 5: // Reactor.lmH Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->l = arg; + break; + case 6: // Reactor.R Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->R; + break; + case 7: // Reactor.R Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->R = arg; + break; + case 8: // Reactor.Rp Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->Rp; + break; + case 9: // Reactor.Rp Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->Rp = arg; + break; + case 10: // Reactor.X Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Result = Elem->X; + break; + case 11: // Reactor.X Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + Elem->X = arg; + break; + default: + Result = -1.0; // We got the wrong command + break; + } + return Result; +} + +//******************************String type properties********************************* +char* __stdcall ReactorsS(int mode, char* arg) +{ + string Result = "", // Default return value + S = ""; + bool found = false; + TReactorObj* Elem = nullptr; + TPointerList pList = {}; + int activesave = 0, + k = 0; + + switch (mode) + { + case 0: // Reactor.Name Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Result = Elem->get_Name(); + } + break; + case 1: // Reactor.Name Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { // Search list of Storages in active circuit for name + if (ReactorClass[ActiveActor]->ElementList.NumInList > 0) + { + S = arg; // Convert to Pascal String + found = false; + pList = ReactorClass[ActiveActor]->ElementList; + activesave = pList.get_myActiveItem(); + Elem = (TReactorObj*)pList.Get_First(); + while (ASSIGNED(Elem)) + { + if (CompareText(Elem->Get_myLName(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Elem); + found = true; + break; + } + Elem = (TReactorObj*)pList.Get_Next(); + + } + if (!found) + { + DoSimpleMsg("Reactor " + S + " Not Found in Active Circuit.", 20003); + Elem = (TReactorObj*)pList.Get(activesave); // Restore active Storage + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(Elem); + } + + } + } + break; + case 2: // Reactor.LCurve Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Result = Elem->LCurve; + } + break; + case 3: // Reactor.LCurve Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Elem->LCurve = arg; + } + break; + case 4: // Reactor.RCurve Read + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Result = Elem->RCurve; + } + break; + case 5: // Reactor.RCurve Write + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + Elem->RCurve = arg; + } + break; + } + + char* presult = new char[Result.size() + 1]; + strcpy(presult, Result.c_str()); + return presult; +} + +//************************Structure type properties******************************* +void __stdcall ReactorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TReactorObj* Elem = nullptr; + TPointerList pList = {}; + int idx = 0, + i = 0, + k = 0; + double* PDouble = nullptr; + + switch (mode) + { + case 0: // Reactors.AllNames + *myType = 4; // String + myStrArray.clear(); + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (ReactorClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = ReactorClass[ActiveActor]->ElementList; + + k = 0; + Elem = (TReactorObj*)pList.Get_First(); + while (ASSIGNED(Elem)) + { + WriteStr2Array(Elem->LName); + WriteStr2Array(Char0()); + k++; + Elem = (TReactorObj*)pList.Get_Next(); + } + } + } + + if (myStrArray.empty()) + WriteStr2Array("None"); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Reactors.RMatrix read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + + if (with0->Rmatrix != nullptr) + { + myDblArray.resize(Sqr(with0->Get_NPhases())); + for (i = 0; i < Sqr(with0->Get_NPhases()); i++) + { + myDblArray[i] = with0->Rmatrix[i]; + } + } + + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 2: // Reactors.RMatrix write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + + realloc(with0->Rmatrix,sizeof(double) * Sqr(with0->Get_NPhases())); + for( i = 0; i < Sqr(with0->Get_NPhases()); i++) + { + PDouble = *(double**)myPtr; + with0->Rmatrix[i] = *PDouble; + k++; + PDouble++; + } + with0->Set_YprimInvalid(ActiveActor,true); + } + } + *mySize = k; + break; + case 3: // Reactors.XMatrix read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + + if (with0->Rmatrix != nullptr) + { + myDblArray.resize(Sqr(with0->Get_NPhases())); + for (i = 0; i < Sqr(with0->Get_NPhases()); i++) + { + myDblArray[i] = with0->XMatrix[i]; + } + } + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 4: // Reactors.XMatrix write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + + realloc(with0->XMatrix, sizeof(double) * Sqr(with0->Get_NPhases())); + for (i = 0; i < Sqr(with0->Get_NPhases()); i++) + { + PDouble = *(double**)myPtr; + with0->XMatrix[i] = *PDouble; + k++; + PDouble++; + } + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 5: // Reactors.Z read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + myDblArray.resize(2); + myDblArray[0] = with0->Z.re; + myDblArray[1] = with0->Z.im; + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 6: // Reactors.Z write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + PDouble = *(double**)myPtr; + with0->Z.re = *PDouble; + PDouble++; + with0->Z.im = *PDouble; + k = 2; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 7: // Reactors.Z0 read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + myDblArray.resize(2); + myDblArray[0] = with0->Z0.re; + myDblArray[1] = with0->Z0.im; + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 8: // Reactors.Z0 write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + PDouble = *(double**)myPtr; + with0->Z0.re = *PDouble; + PDouble++; + with0->Z0.im = *PDouble; + k = 2; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 9: // Reactors.Z1 read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + myDblArray.resize(2); + myDblArray[0] = with0->Z1.re; + myDblArray[1] = with0->Z1.im; + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 10: // Reactors.Z1 write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + PDouble = *(double**)myPtr; + with0->Z1.re = *PDouble; + PDouble++; + with0->Z1.im = *PDouble; + k = 2; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + case 11: // Reactors.Z2 read + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + myDblArray.resize(2); + myDblArray[0] = with0->Z2.re; + myDblArray[1] = with0->Z2.im; + } + } + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 12: // Reactors.Z2 write + *myType = 2; // Double + k = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Elem = (TReactorObj*)ReactorClass[ActiveActor]->GetActiveObj(); + if (ASSIGNED(Elem)) + { + auto with0 = Elem; + PDouble = *(double**)myPtr; + with0->Z2.re = *PDouble; + PDouble++; + with0->Z2.im = *PDouble; + k = 2; + with0->Set_YprimInvalid(ActiveActor, true); + } + } + *mySize = k; + break; + default: + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + + +string ReduceEditString = ""; +string EnergyMeterName = ""; +string FirstPDelement = ""; + +//-------------------------------------------------------------------------------- +// Implements the ReduceCkt interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall ReduceCktI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // ReduceCkt.Do1phLaterals + + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoRemoveAll_1ph_Laterals(with0->BranchList); + } + } + } + break; + case 1: // ReduceCkt.DoBranchRemove + if(ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + auto with1 = ActiveCircuit[ActiveActor]; + if (with1->SetElementActive(FirstPDelement) >= 0) + { + DoRemoveBranches(with1->Branch_List, (TPDElement*)with1->FActiveCktElement, with1->ReduceLateralsKeepLoad, ReduceEditString); + } + + } + } + } + } + + break; + case 2: // ReduceCkt.DoDangling + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoReduceDangling(with0->BranchList); + } + } + } + break; + case 3: // ReduceCkt.DoDefault + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoReduceDefault(with0->BranchList); + } + } + } + break; + case 4: // ReduceCkt.DoLoopBreak + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoBreakLoops(with0->BranchList); + } + } + } + break; + case 5: // ReduceCkt.DoParallelLines + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoMergeParallelLines(with0->BranchList); + } + } + } + break; + case 6: // ReduceCkt.DoShortLines + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoReduceShortLines(with0->BranchList); + } + } + } + break; + case 7: // ReduceCkt.DoSwitches + if (EnergyMeterClass[ActiveActor]->SetActive(EnergyMeterName)) + { + ActiveEnergyMeterObj = (TEnergyMeterObj*)EnergyMeterClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(ActiveEnergyMeterObj)) + { + auto with0 = ActiveEnergyMeterObj; + if (not(ASSIGNED(with0->BranchList))) + { + with0->MakeMeterZoneLists(ActiveActor); + DoReduceShortLines(with0->BranchList); + } + } + } + break; + case 8: // ReduceCkt.KeepLoad - read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad) + { + result = 1; + } + } + break; + case 9: // ReduceCkt.KeepLoad - write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (arg != 0) + { + ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad = true; + } + else + ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad = false; + } + break; + default: + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall ReduceCktF(int mode, double arg) +{ + double result = 0.0; + + switch (mode) + { + case 0: // ReduceCkt.Zmag - read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->ReductionZmag; + } + break; + case 1: // ReduceCkt.Zmag - write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->ReductionZmag = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall ReduceCktS(int mode, char* arg) +{ + string result = ""; + switch (mode) + { + case 0: // ReduceCkt.EditString - Read + result = ReduceEditString; + break; + case 1: // ReduceCkt.EditString - Write + ReduceEditString = arg; + break; + case 2: // ReduceCkt.EnergyMeter - Read + result = EnergyMeterName; + break; + case 3: // ReduceCkt.EnergyMeter - Write + EnergyMeterName = arg; + break; + case 4: // ReduceCkt.SaveCircuit + DSSExecutive[ActiveActor]->Set_Command("Save Circuit Dir = " + (string)arg); + // Master file name is returned in DSSText.Result + break; + case 5: // ReduceCkt.StartPDElement - Read + result = FirstPDelement; + break; + case 6: // ReduceCkt.StartPDElement - Write + FirstPDelement = arg; + break; + default: + result = "Error, not element found"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} + +//-------------------------------------------------------------------------------- +// Implements the RegControls interface for the DLL +//-------------------------------------------------------------------------------- +// // ******************************Help Functions************************* +TRegControlObj* __stdcall ActiveRegControl() +{ + TRegControlObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TRegControlObj*)ActiveCircuit[ActiveActor]->RegControls.Get_Active(); + } + return result; +} +void Set_ParameterRegC(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("regcontrol.%s.%s=%s", ((TRegControlObj*)ActiveCircuit[ActiveActor]->RegControls.Get_Active())->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ******************************int type properties************************* +int __stdcall RegControlsI(int mode, int arg) +{ + TRegControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int result = 0; + + switch (mode) + { + case 0: // RegControls.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->RegControls); + elem = (TRegControlObj*)lst->Get_First(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + } + else + elem = (TRegControlObj*)lst->Get_Next(); + } while (!(result == 1 || elem == nullptr)); + } + } + break; + case 1: // RegControls.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->RegControls); + elem = (TRegControlObj*)lst->Get_Next(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->ActiveItem; + } + else + elem = (TRegControlObj*)lst->Get_Next(); + } while (!(result > 0 || elem == nullptr)); + } + } + break; + case 2: // RegControls.TapWinding read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->TapWinding;// has the taps + } + break; + case 3: // RegControls.TapWinding write + Set_ParameterRegC("TapWinding", IntToStr(arg)); + break; + case 4: // RegControls.Winding read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->ElementTerminal;// monitored winding + } + break; + case 5: // RegControls.Winding write + Set_ParameterRegC("Winding", IntToStr(arg)); + break; + case 6: // RegControls.IsReversible read + elem = ActiveRegControl(); + if (elem != nullptr) + { + if (elem->IsReversible == true) + result = 1; + } + else result = 0; + break; + case 7: // RegControls.IsReversible read + elem = ActiveRegControl(); + if (arg == 1) + { + Set_ParameterRegC("Reversible", "y"); + } + else + Set_ParameterRegC("Reversible", "n"); + break; + case 8: // RegControls.IsInverseTime read + elem = ActiveRegControl(); + if (elem != nullptr) + { + if (elem->FInversetime == true) + result = 1; + } + else result = 0; + break; + case 9: // RegControls.IsInverseTime write + elem = ActiveRegControl(); + if (arg == 1) + { + Set_ParameterRegC("InverseTime", "y"); + } + else + Set_ParameterRegC("InverseTime", "n"); + break; + case 10: // RegControls.MaxTapChange read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->TapLimitPerChange; + } + break; + case 11: // RegControls.MaxTapChange write + Set_ParameterRegC("MaxTapChange", IntToStr(arg)); + break; + case 12: // RegControls.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->RegControls.NumInList; + } + break; + case 13: // RegControls.TapNumber read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->Get_TapNum();// tap number on the controlled-winding of the transformer controlled by this regcontrol + } + break; + case 14: // RegControls.TapNumber write + Set_ParameterRegC("TapNum", IntToStr(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall RegControlsF(int mode, double arg) +{ + TRegControlObj* elem = nullptr; + double result = 0.0; + switch (mode) + { + case 0: // RegControls.CTPrimary read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->CTRating;// has the taps + } + break; + case 1: // RegControls.CTPrimary write + Set_ParameterRegC("CTprim", FloatToStr(arg)); + break; + case 2: // RegControls.PTRatio read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->PTRatio;// has the taps + } + break; + case 3: // RegControls.PTRatio write + Set_ParameterRegC("PTratio", FloatToStr(arg)); + break; + case 4: // RegControls.ForwardR read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->R; // has the taps + } + break; + case 5: // RegControls.ForwardR write + Set_ParameterRegC("R", FloatToStr(arg)); + break; + case 6: // RegControls.ForwardX read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->X; // has the taps + } + break; + case 7: // RegControls.ForwardX write + Set_ParameterRegC("X", FloatToStr(arg)); + break; + case 8: // RegControls.ReverseR read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->revR ; + } + break; + case 9: // RegControls.ReverseR write + Set_ParameterRegC("RevR", FloatToStr(arg)); + break; + case 10: // RegControls.ReverseX read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->revX; + } + break; + case 11: // RegControls.ReverseX write + Set_ParameterRegC("RevX", FloatToStr(arg)); + break; + case 12: // RegControls.Delay read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->TimeDelay; + } + break; + case 13: // RegControls.Delay write + Set_ParameterRegC("Delay", FloatToStr(arg)); + break; + case 14: // RegControls.TapDelay read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->TapDelay; + } + break; + case 15: // RegControls.TapDelay write + Set_ParameterRegC("TapDelay", FloatToStr(arg)); + break; + case 16: // RegControls.VoltageLimit read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->Vlimit; + } + break; + case 17: // RegControls.VoltageLimit write + Set_ParameterRegC("Vlimit", FloatToStr(arg)); + break; + case 18: // RegControls.ForwardBand read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->Bandwidth; + } + break; + case 19: // RegControls.ForwardBand write + Set_ParameterRegC("Band", FloatToStr(arg)); + break; + case 20: // RegControls.ForwardVreg read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->Vreg; + } + break; + case 21: // RegControls.ForwardVreg write + Set_ParameterRegC("Vreg", FloatToStr(arg)); + break; + case 22: // RegControls.ReverseBand read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->revBandwidth; + } + break; + case 23: // RegControls.ReverseBand write + Set_ParameterRegC("RevBand", FloatToStr(arg)); + break; + case 24: // RegControls.ReverseVreg read + elem = ActiveRegControl(); + if (elem != nullptr) + { + + result = elem->revVreg; + } + break; + case 25: // RegControls.ReverseVreg write + Set_ParameterRegC("RevVreg", FloatToStr(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall RegControlsS(int mode, char* arg) +{ + TRegControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int ActiveSave = 0; + bool Found = false; + string S = "", + result = ""; // Default return value + + switch (mode) + { + case 0: // RegControls.Name read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->LName; + } + break; + case 1: // RegControls.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->RegControls); + S = arg; + Found = false; + ActiveSave = lst->ActiveItem; + elem = (TRegControlObj*)lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->LName, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TRegControlObj*)lst->Get_Next(); + } + if (not(Found)) + { + DoSimpleMsg("RegControl " + S + " Not Found in Active Circuit.", 5003); + elem = (TRegControlObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 2: // RegControls.MonitoredBus read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->RegulatedBus; + } + break; + case 3: // RegControls.MonitoredBus write + Set_ParameterRegC("Bus", (string)arg); + break; + case 4: // RegControls.Transformer read + elem = ActiveRegControl(); + if (elem != nullptr) + { + result = elem->Get_Transformer()->LName; + } + break; + case 5: // RegControls.Transformer write + Set_ParameterRegC("Transformer",(string)arg); + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall RegControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TRegControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int k = 0; + + switch (mode) + { + case 0: // RegControls.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + lst = &(with0->RegControls); + if (lst->NumInList > 0) + { + elem = (TRegControlObj*)lst->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TRegControlObj*)lst->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Relays interface for the DLL +//-------------------------------------------------------------------------------- + // ******************************Help Functions************************* +void Set_ParameterRelay(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("Relay.%s.%s=%s", ((TRecloserObj*)RelayClass->GetActiveObj())->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ******************************int type properties************************* +int __stdcall RelaysI(int mode, int arg) +{ + TRelayObj* pElem = nullptr; + TRelayObj* elem = nullptr; + TRelayObj* pRelay = nullptr; + int result = 0; + + switch (mode) + { + case 0: // Relays.Count + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = RelayClass->ElementList.NumInList; + } + break; + case 1: // Relays.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + + pElem = (TRelayObj*)RelayClass->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + pElem = (TRelayObj*)RelayClass->ElementList.Get_Next(); + } while (!(result == 1 || elem == nullptr)); + } + } + break; + case 2: // Relays.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + + pElem = (TRelayObj*)RelayClass->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = RelayClass->ElementList.ActiveItem; + } + else + pElem = (TRelayObj*)RelayClass->ElementList.Get_Next(); + } while (!(result > 0 || elem == nullptr)); + } + } + break; + case 3: // Relays.MonitoredTerm read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementTerminal; + } + break; + case 4: // Relays.MonitoredTerm write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterRelay("monitoredterm", IntToStr(arg)); + } + break; + case 5: // Relays.SwitchedTerm read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->ElementTerminal; + } + break; + case 6: // Relays.SwitchedTerm write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterRelay("SwitchedTerm", IntToStr(arg)); + } + break; + case 7: // Relays.Idx read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = RelayClass->ElementList.ActiveItem; + } + break; + case 8: // Relays.Idx write + if (ActiveCircuit[ActiveActor] != nullptr) + { + pRelay = (TRelayObj*)RelayClass->ElementList.Get(arg); + if (pRelay != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pRelay); + } + } + break; + case 9: // Relays.Open + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + elem->set_State(CTRL_OPEN); + } + break; + case 10: // Relays.Close + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + elem->set_State(CTRL_CLOSE); + } + break; + case 11: // Relays.Reset + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + elem->Reset(ActiveActor); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall RelaysS(int mode, char* arg) +{ + TRelayObj* elem = nullptr; + string result = ""; // Default return value + switch (mode) + { + case 0: // Relays.Name read + elem = (TRelayObj*) RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->LName; + } + break; + case 1: // Relays.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (RelayClass->SetActive((string)arg)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TRelayObj*)RelayClass->ElementList.Get_Active()); + } + else + DoSimpleMsg("Relay " + (string)arg + " Not Found in Active Circuit.", 77003); + } + break; + case 2: // Relays.MonitoredObj read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->MonitoredElementName; + } + break; + case 3: // Relays.MonitoredObj write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterRelay("monitoredObj", (string)arg); + } + break; + case 4: // Relays.SwitchedObj read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + result = elem->ElementName; + } + break; + case 5: // Relays.SwitchedObj write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + Set_ParameterRelay("SwitchedObj", (string)arg); + } + break; + case 6: // Relays.State read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem->get_State() == CTRL_CLOSE) + { + result = "closed"; + } + else + { + result = "open"; + } + break; + case 7: // Relays.State write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + if (LowerCase((string)arg)[0] == 'c') + { + elem->set_State(CTRL_CLOSE); + } + else + { + elem->set_State(CTRL_OPEN); + } + } + else + result = "open"; + break; + case 8: // Relays.NormalState read + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem->get_NormalState() == CTRL_CLOSE) + { + result = "closed"; + } + else + { + result = "open"; + } + break; + case 9: // Relays.NormalState write + elem = (TRelayObj*)RelayClass->GetActiveObj(); + if (elem != nullptr) + { + if (LowerCase((string)arg)[0] == 'c') + { + elem->set_NormalState(CTRL_CLOSE); + } + else + { + elem->set_NormalState(CTRL_OPEN); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//******************************String type properties**************************** +void __stdcall RelaysV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TRelayObj* elem = nullptr; + TPointerList* pList = nullptr; + int k = 0; + switch (mode) + { + case 0: // Relays.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (RelayClass->ElementList.NumInList > 0) + { + pList = &(RelayClass->ElementList); + elem = (TRelayObj*)pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TRelayObj*)pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Sensors interface for the DLL +//-------------------------------------------------------------------------------- +// // ******************************Help Functions************************* +TSensorObj* __stdcall ActiveSensor() +{ + TSensorObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TSensorObj*)ActiveCircuit[ActiveActor]->Sensors.Get_Active(); + } + return result; +} + +void Set_ParameterSensor(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("sensor.%s.%s=%s", ActiveSensor()->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ******************************int type properties************************* +int __stdcall SensorsI(int mode, int arg) +{ + TSensorObj* elem = nullptr; + TPointerList* lst = nullptr; + int result = 0; + switch (mode) + { + case 0: // Sensors.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Sensors.NumInList; + } + break; + case 1: // Sensors.First + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Sensors); + elem = (TSensorObj*)lst->Get_First(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + } + else + elem = (TSensorObj*)lst->Get_Next(); + } while (!(result == 1 || elem == nullptr)); + } + } + break; + case 2: // Sensors.Next + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Sensors); + elem = (TSensorObj*)lst->Get_Next(); + if (elem != nullptr) + { + do + { + if (elem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->ActiveItem; + } + else + elem = (TSensorObj*)lst->Get_Next(); + } while (!(result > 0 || elem == nullptr)); + } + } + break; + case 3: // Sensors.IsDelta read + elem = ActiveSensor(); + if (elem != nullptr) + { + if (elem->FConn > 0) + result = 1; + } + break; + case 4: // Sensors.IsDelta write + elem = ActiveSensor(); + if (elem != nullptr) + { + elem->FConn = int(arg); + } + break; + case 5: // Sensors.ReverseDelta read + elem = ActiveSensor(); + if (elem != nullptr) + { + if (elem->FDeltaDirection < 0) + result = 1; + } + break; + case 6: // Sensors.ReverseDelta write + if (arg == 1) + Set_ParameterSensor("DeltaDirection", "-1"); + else + Set_ParameterSensor("DeltaDirection", "1"); + break; + case 7: // Sensors.MeteredTerminal read + elem = ActiveSensor(); + if (elem != nullptr) + { + result = elem->MeteredTerminal; + } + break; + case 8: // Sensors.MeteredTerminal write + Set_ParameterSensor("terminal", IntToStr(arg)); + break; + case 9: // Sensors.Reset + elem = ActiveSensor(); + if (elem != nullptr) + { + elem->ResetIt(); + } + break; + case 10: // Sensors.ResetAll + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + SensorClass[ActiveActor]->ResetAll(ActiveActor); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall SensorsF(int mode, double arg) +{ + TSensorObj* elem = nullptr; + double result = 0.0; + switch (mode) + { + case 0: // Sensors.PctError read + elem = ActiveSensor(); + if (elem != nullptr) + { + return elem->pctError; + } + break; + case 1: // Sensors.PctError write + Set_ParameterSensor("%error", FloatToStr(arg)); + break; + case 2: // Sensors.Weight read + elem = ActiveSensor(); + if (elem != nullptr) + { + return elem->Weight; + } + break; + case 3: // Sensors.Weight write + Set_ParameterSensor("weight", FloatToStr(arg)); + break; + case 4: // Sensors.kVbase read + elem = ActiveSensor(); + if (elem != nullptr) + { + return elem->kVBase; + } + break; + case 5: // Sensors.kVbase write + Set_ParameterSensor("kvbase", FloatToStr(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall SensorsS(int mode, char* arg) +{ + TSensorObj* elem = nullptr; + int ActiveSave = 0; + bool Found = false; + TPointerList* lst = nullptr; + string S = "", + result = "";// Default return value + + switch (mode) + { + case 0: // Sensors.Name read + elem = ActiveSensor(); + if (elem != nullptr) + { + result = elem->LName; + } + break; + case 1: // Sensors.Name write + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Sensors); + S = arg; + Found = false; + ActiveSave = lst->ActiveItem; + elem = (TSensorObj*)lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->LName, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TSensorObj*)lst->Get_Next(); + } + if (not(Found)) + { + DoSimpleMsg("Sensor " + S + " Not Found in Active Circuit.", 5003); + elem = (TSensorObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 2: // Sensors.MeteredElement read + elem = ActiveSensor(); + if (elem != nullptr) + { + result = elem->ElementName; + } + break; + case 3: // Sensors.MeteredElement write + Set_ParameterSensor("element", (string)arg); + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall SensorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TSensorObj* elem = nullptr; + int k = 0, + i = 0; + double* PDouble = nullptr; + + switch (mode) + { + case 0: // Sensors.AllNames + *myType = 4; //string + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Sensors.NumInList > 0) + { + elem = (TSensorObj*)with0->Sensors.Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->LName); + WriteStr2Array(Char0()); + elem = (TSensorObj*)with0->Sensors.Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + case 1: // Sensors.Currents read + *myType = 2; //double + myDblArray.resize(0); + myDblArray[0] = 0; + elem = ActiveSensor(); + if (elem != nullptr) + { + myDblArray.resize(elem->Fnphases); + for (k = 0; k < elem->Fnphases; k++) + { + myDblArray[k] = elem->SensorCurrent[k]; + } + } + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 2: // Sensors.Currents write + *myType = 2; //double + elem = ActiveSensor(); + k = 1; + if (elem != nullptr) + { + PDouble = *(double**)myPtr; + for (i = 0; i < elem->Fnphases; i++) + { + elem->SensorCurrent[i] = *PDouble; + PDouble++; + k++; + } + } + *mySize = k - 1; + break; + case 3: // Sensors.KVARS read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + elem = ActiveSensor(); + if (elem != nullptr) + { + myDblArray.resize(elem->Fnphases); + for (k = 0; k < elem->Fnphases; k++) + { + myDblArray[k] = elem->Sensorkvar[k]; + } + } + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 4: // Sensors.KVARS write + *myType = 2; //double + elem = ActiveSensor(); + k = 1; + if (elem != nullptr) + { + PDouble = *(double**)myPtr; + for (i = 1; i <= elem->Fnphases; i++) + { + elem->Sensorkvar[i - 1] = *PDouble; + PDouble ++; + k++; + } + } + break; + case 5: // Sensors.KWS read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + elem = ActiveSensor(); + if (elem != nullptr) + { + myDblArray.resize(elem->Fnphases); + for (k = 0; k <= elem->Fnphases - 1; k++) + { + myDblArray[k] = elem->SensorkW[k]; + } + } + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 6: // Sensors.KWS write + *myType = 2; //double + elem = ActiveSensor(); + k = 1; + if (elem != nullptr) + { + PDouble = *(double**)myPtr; + for (i = 1; i <= elem->Fnphases; i++) + { + elem->SensorkW[i - 1] = *PDouble; + PDouble++; + k++; + } + } + break; + case 7: // Sensors.AllocationFactor + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + elem = ActiveSensor(); + if (elem != nullptr) + { + myDblArray.resize(elem->Fnphases); + for (k = 0; k < elem->Fnphases; k++) + { + myDblArray[k] = elem->PhsAllocationFactor[k]; + } + } + *mySize = sizeof(myDblArray) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Settings interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall SettingsI(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: // Settings.AllowDuplicates read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveCircuit[ActiveActor]->DuplicatesAllowed) + { + result = 1; + } + } + break; + case 1: // Settings.AllowDuplicates Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (arg == 1) + { + ActiveCircuit[ActiveActor]->DuplicatesAllowed = true; + } + else + ActiveCircuit[ActiveActor]->DuplicatesAllowed = false; + } + break; + case 2: // Settings.ZoneLock read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveCircuit[ActiveActor]->ZonesLocked) + { + result = 1; + } + } + break; + case 3: // Settings.ZoneLock Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (arg == 1) + { + ActiveCircuit[ActiveActor]->ZonesLocked = true; + } + else + ActiveCircuit[ActiveActor]->ZonesLocked = false; + } + break; + case 4: // Settings.CktModel read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveCircuit[ActiveActor]->PositiveSequence) + { + result = 1; + } + else + { + result = 0; + } + } + break; + case 5: // Settings.CktModel Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + switch (arg) + { + case 2: + ActiveCircuit[ActiveActor]->PositiveSequence = true; + break; + default: + ActiveCircuit[ActiveActor]->PositiveSequence = false; + } + } + break; + case 6: // Settings.Trapezoidal read + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (ActiveCircuit[ActiveActor]->TrapezoidalIntegration) + { + result = 1; + } + } + break; + case 7: // Settings.Trapezoidal Write + if (ActiveCircuit[ActiveActor] != nullptr) + { + switch (arg) + { + case 2: + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = true; + break; + default: + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = false; + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall SettingsF(int mode, double arg) +{ + double result = 0.0; + switch (mode) + { + case 0: // Settings.AllocationFactors + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSetAllocationFactors(arg); + } + break; + case 1: // Settings.NormVminpu read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->NormalMinVolts; + } + break; + case 2: // Settings.NormVminpu write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->NormalMinVolts = arg; + } + break; + case 3: // Settings.NormVmaxpu read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->NormalMaxVolts; + } + break; + case 4: // Settings.NormVmaxpu write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->NormalMaxVolts = arg; + } + break; + case 5: // Settings.EmergVminpu read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->EmergMinVolts; + } + break; + case 6: // Settings.EmergVminpu write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->EmergMinVolts = arg; + } + break; + case 7: // Settings.EmergVmaxpu read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->EmergMaxVolts; + } + break; + case 8: // Settings.EmergVmaxpu write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->EmergMaxVolts = arg; + } + break; + case 9: // Settings.UEWeight read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->UEWeight; + } + break; + case 10: // Settings.UEWeight write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->UEWeight = arg; + } + break; + case 11: // Settings.LossWeight read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->LossWeight; + } + break; + case 12: // Settings.LossWeight write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->LossWeight = arg; + } + break; + case 13: // Settings.PriceSignal read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->PriceSignal; + } + break; + case 14: // Settings.PriceSignal write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->PriceSignal = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall SettingsS(int mode, char* arg) +{ + string result = ""; // Deafult return value + int i = 0; + + switch (mode) + { + case 0: // Settings.AutoBusList read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto& with0 = ActiveCircuit[ActiveActor]->AutoAddBusList; + for (i = 1; i <= with0.ListPtr.size(); i++) + { + AppendGlobalResult(with0.Get(i)); + result = GlobalResult; + } + } + break; + case 1: // Settings.AutoBusList write + if (ActiveCircuit[ActiveActor] != nullptr) + { + DoAutoAddBusList((string)arg); + } + break; + case 2: // Settings.PriceCurve read + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = ActiveCircuit[ActiveActor]->PriceCurve; + } + break; + case 3: // Settings.PriceCurve read + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->PriceCurve = (string)arg; + with0->PriceCurveObj = (TPriceShapeObj*)LoadShapeClass[ActiveActor]->Find(with0->PriceCurve); + if (with0->PriceCurveObj) + { + DoSimpleMsg("Price Curve: " + with0->PriceCurve + " not found.", 5006); + } + } + break; + default: + result = "Error, parameter not recognized"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall SettingsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int i = 0, + j = 0, + Count = 0, + Num = 0; + int* pInt = nullptr; + double* pDouble = nullptr; + + auto with0 = ActiveCircuit[ActiveActor]; + switch (mode) + { + case 0: // Settings.UERegs read + *myType = 1; //integer + myIntArray.resize(1); + myIntArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + myIntArray.resize(ActiveCircuit[ActiveActor]->NumUEregs); + for (i = 0; i <= ActiveCircuit[ActiveActor]->NumUEregs - 1; i++) + { + myIntArray[i] = ActiveCircuit[ActiveActor]->UEregs[i]; + } + } + *mySize = sizeof(myIntArray[0]) * myIntArray.size(); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 1: // Settings.UERegs write + j = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + ReallocMem(ActiveCircuit[ActiveActor]->UEregs, sizeof(ActiveCircuit[ActiveActor]->UEregs[1]) * (*mySize)); + pInt = *(int**)myPtr; + for (i = 1; i <= *mySize; i++) + { + ActiveCircuit[ActiveActor]->UEregs[j] = *pInt; + pInt++; + j++; + } + } + *mySize = j - 1; + break; + case 2: // Settings.LossRegs read + *myType = 1; //integer + myIntArray.resize(1); + myIntArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + myIntArray.resize(ActiveCircuit[ActiveActor]->NumLossRegs); + for (i = 0; i <= ActiveCircuit[ActiveActor]->NumLossRegs - 1; i++) + { + myIntArray[i] = ActiveCircuit[ActiveActor]->LossRegs[i]; + } + } + *mySize = sizeof(myIntArray[0]) * myIntArray.size(); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 3: // Settings.LossRegs write + j = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + ReallocMem(ActiveCircuit[ActiveActor]->UEregs, sizeof(ActiveCircuit[ActiveActor]->LossRegs[0]) * (*mySize)); + pInt = *(int**)myPtr; + for (i = 1; i <= (*mySize); i++) + { + ActiveCircuit[ActiveActor]->LossRegs[j] = *pInt; + pInt++; + j++; + } + } + *mySize = j - 1; + break; + case 4: // Settings.VoltageBases read + *myType = 2; //double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + //{Count the number of voltagebases specified} + i = 0; + do + { + i++; + } while (with0->LegalVoltageBases[i - 1] != 0.0); + Count = i - 1; + myDblArray.resize(Count); + for (i = 0; i <= Count - 1; i++) + { + myDblArray[i] = with0->LegalVoltageBases[i]; + } + } + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + break; + case 5: // Settings.VoltageBases write + *myType = 2; //double + j = 0; + Num = *mySize; + + with0->LegalVoltageBases.resize(Num + 1); + pDouble = *(double**)myPtr; + for (i = 1; i <= (*mySize); i++) + { + with0->LegalVoltageBases[j] = *pDouble; + pDouble++; + j++; + } + with0->LegalVoltageBases[Num] = 0.0; + *mySize = j; + break; + default: + *myType = 4; //string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *mySize = myStrArray.size(); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Solution interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall SolutionI(int mode, int arg) +{ + int i = 0, + result = 0; + + switch (mode) + { + case 0: // Solution.Solve + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Solve(ActiveActor); + } + break; + case 1: // Solution.Mode - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Get_SolMode(); + } + break; + case 2: // Solution.Mode - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Set_Mode(arg); + } + break; + case 3: // Solution.hour - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour; + } + break; + case 4: // Solution.hour - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour = arg; + } + break; + case 5: // Solution.Year - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Fyear; + } + break; + case 6: // Solution.Year - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Set_Year(arg); + } + break; + case 7: // Solution.Iterations + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Iteration; + } + break; + case 8: // Solution.MaxIterations - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->MaxIterations; + } + break; + case 9: // Solution.MaxIterations - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->MaxIterations = arg; + } + break; + case 10: // Solution.Number - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->NumberOfTimes; + } + break; + case 11: // Solution.Number - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->NumberOfTimes = arg; + } + break; + case 12: // Solution.Random - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->RandomType; + } + break; + case 13: // Solution.Random - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->RandomType = arg; + } + break; + case 14: // Solution.LoadModel - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->LoadModel; + } + break; + case 15: // Solution.LoadModel - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + with0->LoadModel = arg; + with0->DefaultLoadModel = with0->LoadModel; + } + break; + case 16: // Solution.AddType - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->AutoAddObj.AddType; + } + break; + case 17: // Solution.AddType - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->AutoAddObj.AddType = arg; + } + break; + case 18: // Solution.Algorithm - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Algorithm; + } + break; + case 19: // Solution.Algorithm - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Algorithm = arg; + } + break; + case 20: // Solution.ControlMode - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->ControlMode; + } + break; + case 21: // Solution.ControlMode - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + with0->ControlMode = arg; + with0->DefaultControlMode = with0->ControlMode; + } + break; + case 22: // Solution.ControlIterations - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->ControlIteration; + } + break; + case 23: // Solution.ControlIterations - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->ControlIteration = arg; + } + break; + case 24: // Solution.MaxControlIterations - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->MaxControlIterations; + } + break; + case 25: // Solution.MaxControlIterations - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->MaxControlIterations = arg; + } + break; + case 26: // Solution.Sample_DoControlActions + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Sample_DoControlActions(ActiveActor); + } + break; + case 27: // Solution.CheckFaultStatus + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Check_Fault_Status(ActiveActor); + } + break; + case 28: // Solution.SolveDirect + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->SolveDirect(ActiveActor); + } + break; + case 29: // Solution.SolvePflow + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DoPFLOWsolution(ActiveActor); + } + break; + case 30: // Solution.SolveNoControl + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->SolveCircuit(ActiveActor); + } + break; + case 31: // Solution.SolvePlusControl + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->SolveCircuit(ActiveActor); + ActiveCircuit[ActiveActor]->Solution->CheckControls(ActiveActor); + } + break; + case 32: // Solution.InitSnap + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->SnapShotInit(ActiveActor); + } + break; + case 33: // Solution.CheckControls + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->CheckControls(ActiveActor); + } + break; + case 34: // Solution.SampleControlDevices + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->SampleControlDevices(ActiveActor); + } + break; + case 35: // Solution.DoControlActions + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DoControlActions(ActiveActor); + } + break; + case 36: // Solution.BuildYMatrix + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + YMatrix::BuildYMatrix(arg, false, ActiveActor); + } + break; + case 37: // Solution.SystemYChanged + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (ActiveCircuit[ActiveActor]->Solution->SystemYChanged) + { + result = 1; + } + } + break; + case 38: // Solution.Converged - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (ActiveCircuit[ActiveActor]->Solution->ConvergedFlag) + { + result = 1; + } + } + break; + case 39: // Solution.Converged - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (arg == 1) + { + ActiveCircuit[ActiveActor]->Solution->ConvergedFlag = true; + ActiveCircuit[ActiveActor]->Issolved = true; + } + else + { + ActiveCircuit[ActiveActor]->Solution->ConvergedFlag = false; + ActiveCircuit[ActiveActor]->Issolved = false; + } + } + break; + case 40: // Solution.TotalIterations + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Iteration; + } + break; + case 41: // Solution.MostIterationsDone + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->MostIterationsDone; + } + break; + case 42: // Solution.ControlActionsDone - Read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (ActiveCircuit[ActiveActor]->Solution->ControlActionsDone) + { + result = 1; + } + } + break; + case 43: // Solution.ControlActionsDone - Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (arg == 1) + { + ActiveCircuit[ActiveActor]->Solution->ControlActionsDone = true; + } + else + { + ActiveCircuit[ActiveActor]->Solution->ControlActionsDone = false; + } + } + break; + case 44: // Solution.FinishTimeStep + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = with0->Solution; + MonitorClass[ActiveActor]->SampleAll(ActiveActor); // Make all monitors take a sample + EndOfTimeStepCleanup(ActiveActor); + with1->Increment_time(); + } + break; + case 45: // Solution.Cleanup + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + EndOfTimeStepCleanup(ActiveActor); + } + break; + case 46: // Solution.SolveAll + for (i = 1; i <= NumOfActors; i++) + { + ActiveActor = i; + CmdResult = DoSetCmd(1); + } + break; + case 47: // Solution.CalcIncMatrix + ActiveCircuit[ActiveActor]->Solution->Calc_Inc_Matrix(ActiveActor); + break; + case 48: // Solution.CalcIncMatrix_O + ActiveCircuit[ActiveActor]->Solution->Calc_Inc_Matrix_Org(ActiveActor); + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall SolutionF(int mode, double arg) +{ + double result = 0.0; + + switch (mode) + { + case 0: // Solution.Frequency read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->FFrequency; + } + break; + case 1: // Solution.Frequency Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->FFrequency = arg; + } + break; + case 2: // Solution.Seconds read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.T; + } + break; + case 3: // Solution.Seconds Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DynaVars.T = arg; + } + break; + case 4: // Solution.StepSize read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.h; + } + break; + case 5: // Solution.StepSize Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DynaVars.h = arg; + ActiveCircuit[ActiveActor]->Solution->IntervalHrs = arg / 3600.0; + } + break; + case 6: // Solution.LoadMult read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->FLoadMultiplier; + } + break; + case 7: // Solution.LoadMult Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->FLoadMultiplier = arg; + } + break; + case 8: // Solution.Tolerance read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->ConvergenceTolerance; + } + break; + case 9: // Solution.Tolerance Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->ConvergenceTolerance = arg; + } + break; + case 10: // Solution.pctgrowth read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + result = (with0->DefaultGrowthRate - 1.0) * 100.0; + } + break; + case 11: // Solution.pctgrowth Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->DefaultGrowthRate = 1.0 + arg/100.0; + with0->DefaultGrowthFactor = pow(with0->DefaultGrowthRate, with0->Solution->Fyear - 1); + } + break; + case 12: // Solution.GenkW read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->AutoAddObj.GenkW; + } + break; + case 13: // Solution.GenkW Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->AutoAddObj.GenkW = arg; + } + break; + case 14: // Solution.GenPF read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->AutoAddObj.GenPF; + } + break; + case 15: // Solution.GenPF Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->AutoAddObj.GenPF = arg; + } + break; + case 16: // Solution.Capkvar read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->AutoAddObj.Capkvar; + } + break; + case 17: // Solution.Capkvar Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->AutoAddObj.Capkvar = arg; + } + break; + case 18: // Solution.GenMult read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->GenMultiplier; + } + break; + case 19: // Solution.GenMult Writeif (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->GenMultiplier = arg; + } + break; + case 20: // Solution.dblHour read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->DynaVars.dblHour; + } + break; + case 21: // Solution.dblHour Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + with0->DynaVars.intHour = Trunc(arg); + with0->DynaVars.dblHour = arg; + with0->DynaVars.T = (arg - with0->DynaVars.intHour) * 3600.0; + } + break; + case 22: // Solution.StepSizeMin + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DynaVars.h = arg * 60.0; + } + break; + case 23: // Solution.StepSizeHr + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->DynaVars.h = arg * 3600.0; + } + break; + case 24: // Solution.Process_Time + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Solve_Time_Elapsed; + } + break; + case 25: // Solution.Total_Time read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Total_Time_Elapsed; + } + break; + case 26: // Solution.Total_Time Write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + ActiveCircuit[ActiveActor]->Solution->Total_Time_Elapsed = arg; + } + break; + case 27: // Solution.Time_TimeStep + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Solution->Step_Time_Elapsed; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall SolutionS(int mode, char* arg) +{ + TLoadShapeObj* TestLoadShapeOb = nullptr; + string result = ""; // Deafult return value + switch (mode) + { + case 0: // Solution.ModeID + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = GetSolutionModeID(); + } + else + { + result = ""; + } + break; + case 1: // Solution.LDCurve read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->LoadDurCurve; + } + else + { + result = ""; + } + break; + case 2: // Solution.LDCurve write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->LoadDurCurve = std::string(arg); + with0->LoadDurCurveObj = (TLoadShapeObj*)LoadShapeClass[ActiveActor]->Find(with0->LoadDurCurve); + if (with0->LoadDurCurveObj != nullptr) + { + DoSimpleMsg("Load - Duration Curve not found.", 5001); + } + } + break; + case 3: // Solution.DefaultDaily read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->get_Name(); + } + else + { + result = ""; + } + break; + case 4: // Solution.DefaultDaily write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + TestLoadShapeOb = (TLoadShapeObj*)LoadShapeClass[ActiveActor]->Find(std::string(arg)); + if (TestLoadShapeOb != nullptr) + { + ActiveCircuit[ActiveActor]->DefaultDailyShapeObj = TestLoadShapeOb; + } + } + break; + case 5: // Solution.DefaultYearly read + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->DefaultYearlyShapeObj->get_Name(); + } + else + { + result = ""; + } + break; + case 6: // Solution.DefaultYearly write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + TestLoadShapeOb = (TLoadShapeObj*)LoadShapeClass[ActiveActor]->Find(std::string(arg)); + if (TestLoadShapeOb != nullptr) + { + ActiveCircuit[ActiveActor]->DefaultYearlyShapeObj = TestLoadShapeOb; + } + } + break; + default: + result = "Error, paratemer not recognized"; + break; + + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall SolutionV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + int Counter = 0, + i = 0, + IMIdx = 0, + Idx = 0, + ArrSize = 0; + + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = ActiveCircuit[ActiveActor]->Solution; + switch (mode) + { + case 0: // Solution.EventLog + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + for (i = 0; i < EventStrings[ActiveActor].size(); i++) + { + WriteStr2Array(EventStrings[ActiveActor][i]); + WriteStr2Array(Char0()); + } + } + //if (myStrArray.size() == 0) + //{ + // WriteStr2Array("None"); + //} + *myPtr = (uintptr_t)(void*)(myStrArray.data()); + *mySize = myStrArray.size(); + break; + case 1: // Solution.IncMatrix + *myType = 1; //Integer + myIntArray.resize(1); + myIntArray[0] = 0; + if ((ActiveCircuit[ActiveActor] != nullptr) && (with1->IncMat.len != 0)) + { + + ArrSize = with1->IncMat.NZero() * 3; + myIntArray.resize(ArrSize); + Counter = 0; + IMIdx = 0; + while (IMIdx < ArrSize) + { + for (i = 0; i <= 2; i++) + { + myIntArray[IMIdx] = with1->IncMat.data[Counter][i]; + IMIdx++; + } + Counter++; + } + } + *mySize = sizeof(myIntArray[0]) * myIntArray.size(); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 2: // Solution.BusLevels + *myType = 1; //Integer + myIntArray.resize(1); + myIntArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + + ArrSize = with1->Inc_Mat_levels.size() - 1; + myIntArray.resize(ArrSize); + for (IMIdx = 0; IMIdx < ArrSize; IMIdx++) + { + myIntArray[IMIdx] = with1->Inc_Mat_levels[IMIdx]; + } + } + *mySize = sizeof(myIntArray[0]) * myIntArray.size(); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + break; + case 3: // Solution.IncMatrixRows + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + ArrSize = with0->Inc_Mat_Rows.size() - 1; + for (IMIdx = 0; IMIdx <= ArrSize; IMIdx++) + { + WriteStr2Array(with0->Inc_Mat_Rows[IMIdx]); + WriteStr2Array(Char0()); + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 4: // Solution.IncMatrixCols + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (IncMat_Ordered) + { + ArrSize = with1->Inc_Mat_Cols.size(); + for (IMIdx = 0; IMIdx < ArrSize; IMIdx++) + { + WriteStr2Array(with1->Inc_Mat_Rows[IMIdx]); + WriteStr2Array(Char0()); + } + } + else + { + for (i = 1; i <= ActiveCircuit[ActiveActor]->NumBuses; i++) + { + WriteStr2Array(ActiveCircuit[ActiveActor]->BusList.Get(i)); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 5: // Solution.Laplacian + *myType = 1; //Integer + myIntArray.resize(1); + myIntArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr && (with1->Laplacian.len != 0)) + { + ArrSize = with1->Laplacian.NZero() * 3; + myIntArray.resize(ArrSize); + Counter = 0; + IMIdx = 0; + while (IMIdx < ArrSize) + { + for (i = 0; i <= 2; i++) + { + myIntArray[IMIdx] = with1->Laplacian.data[Counter][i]; + IMIdx++; + } + Counter++; + } + } + *mySize = sizeof(myIntArray[0]) * myIntArray.size(); + *myPtr = (uintptr_t)(void*)&(myIntArray[0]); + + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Storages interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall StoragesI(int mode, int arg) +{ + TStorageObj* pStorageElem = nullptr; + int Result = 0; // Default return value + + switch (mode) + { + case 0: // Storages.First + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + if (ASSIGNED(pStorageElem)) + { + do + { + if (pStorageElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pStorageElem); + Result = 1; + } + else + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } while (!((Result == 1) || (!ASSIGNED(pStorageElem)))); + } + } + } + break; + case 1: // Storages.Next + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + if (ASSIGNED(pStorageElem)) + { + do + { + if (pStorageElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pStorageElem); + Result = ActiveCircuit[ActiveActor]->StorageElements.ActiveItem; + } + else + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } while (!((Result > 0) || (!ASSIGNED(pStorageElem)))); + } + } + } + break; + case 2: // Storages.Count + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + Result = ActiveCircuit[ActiveActor]->StorageElements.NumInList; + } + break; + case 3: // Storages.Idx read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + Result = ActiveCircuit[ActiveActor]->StorageElements.ActiveItem; + } + break; + case 4: // Storages.Idx write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get(arg); + if (ASSIGNED(pStorageElem)) + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pStorageElem); + } + } + break; + case 5: // Storages.State Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + Result = pStorageElem->fState; + } + } + break; + case 6: // Storages.State Write + { + /* Legal States + STORE_CHARGING = -1; + STORE_IDLING = 0; + STORE_DISCHARGING = 1; + */ + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + pStorageElem->Set_StorageState(arg); + } + } + break; + case 7: // Storages.ControlMode Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + if (pStorageElem->GFM_Mode) + Result = 1; + } + } + } + break; + case 8: // Storages.ControlMode Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->GFM_Mode = (arg != 0); + } + } + } + break; + case 9: // Storages.SafeMode + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + if (pStorageElem->myDynVars.SafeMode) + Result = 1; + } + } + } + break; + case 10: // Storages.VarFollowInverter Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + if (pStorageElem->FVarFollowInverter) + Result = 1; + } + } + } + break; + case 11: // Storages.VarFollowInverter Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->FVarFollowInverter = (arg != 1); + } + } + } + break; + default: + Result = -1; // Just sent the wrong command + break; + } + + return Result; +} +//******************************Float point type properties**************************** +double __stdcall StoragesF(int mode, double arg) +{ + TStorageObj* pStorageElem = nullptr; + double Result = 0; // Default return value + + switch(mode) + { + case 0: // Storages.puSOC Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->StorageVars.kWhStored / pStorageElem->StorageVars.kWhRating; + } + } + } + break; + case 1: // Storages.puSOC Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->StorageVars.kWhStored = pStorageElem->StorageVars.kWhRating * arg; + } + } + } + break; + case 2: // Storages.AmpLimit Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.ILimit; + } + } + } + break; + case 3: // Storages.AmpLimit Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.ILimit = arg; + } + } + } + break; + case 4: // Storages.AmpLimitGain Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.VError; + } + } + } + break; + case 5: // Storages.AmpLimitGain Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.VError = arg; + } + } + } + break; + case 6: // Storages.ChargeTrigger Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->ChargeTrigger; + } + } + } + break; + case 7: // Storages.ChargeTrigger Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->ChargeTrigger = arg; + } + } + } + break; + case 8: // Storages.DisChargeTrigger Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->DischargeTrigger; + } + } + } + break; + case 9: // Storages.DisChargeTrigger Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->DischargeTrigger = arg; + } + } + } + break; + case 10: // Storages.EffCharge Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->pctChargeEff; + } + } + } + break; + case 11: // Storages.EffCharge Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->pctChargeEff = arg; + } + } + } + break; + case 12: // Storages.EffDisCharge Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->pctDischargeEff; + } + } + } + break; + case 13: // Storages.EffDisCharge Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->pctDischargeEff = arg; + } + } + } + break; + case 14: // Storages.kP Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.Kp * 1e3; + } + } + } + break; + case 15: // Storages.kP Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.Kp = arg / 1e3; + } + } + } + break; + case 16: // Storages.kV Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->Get_PresentkV(); + } + } + } + break; + case 17: // Storages.kV Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->Set_PresentkV(arg); + } + } + } + break; + case 18: // Storages.kVA Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->StorageVars.FkVArating; + } + } + } + break; + case 19: // Storages.kVA Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->StorageVars.FkVArating = arg; + } + } + } + break; + case 20: // Storages.kvar Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->Get_kvarRequested(); + } + } + } + break; + case 21: // Storages.kvar Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->Set_kvarRequested(arg); + } + } + } + break; + case 22: // Storages.kVDC Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.RatedVDC / 1e3; + } + } + } + break; + case 23: // Storages.kVDC Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.RatedVDC = arg * 1e3; + } + } + } + break; + case 24: // Storages.kW Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->Get_PresentkW(); + } + } + } + break; + case 25: // Storages.kW Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->Set_kW(arg); + } + } + } + break; + case 26: // Storages.kWhRated Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->StorageVars.kWhRating; + } + } + } + break; + case 27: // Storages.kWhRated Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->StorageVars.kWhRating = arg; + } + } + } + break; + case 28: // Storages.kWRated Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->StorageVars.kWrating; + } + } + } + break; + case 29: // Storages.kWRated Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->StorageVars.kWrating = arg; + } + } + } + break; + case 30: // Storages.LimitCurrent Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + if (pStorageElem->CurrentLimited) + Result = 1; + } + } + } + break; + case 31: // Storages.LimitCurrent Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->CurrentLimited = (arg != 0); + } + } + } + break; + case 32: // Storages.PF Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->PFNominal; + } + } + } + break; + case 33: // Storages.PF Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->PFNominal = arg; + } + } + } + break; + case 34: // Storages.PITol Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.CtrlTol * 100; + } + } + } + break; + case 35: // Storages.PITol Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.CtrlTol = arg / 100; + } + } + } + break; + case 36: // Storages.SafeVoltage Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->myDynVars.SMThreshold; + } + } + } + break; + case 37: // Storages.SafeVoltage Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->myDynVars.SMThreshold = arg; + } + } + } + break; + case 38: // Storages.TimeChargeTrig Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->ChargeTime; + } + } + } + break; + case 39: // Storages.TimeChargeTrig Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + pStorageElem->ChargeTime = arg; + } + } + } + break; + default: + Result = -1.0; + break; + } + return Result; +} +//******************************String type properties**************************** +char* __stdcall StoragesS(int mode, char* arg) +{ + TStorageObj* pStorageElem = nullptr; + string S = "", + Result = ""; // Default return value + bool Found = false; + TPointerList* lst = nullptr; + int ActiveSave = 0; + + + switch (mode) + { + case 0: // Storages.Name Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pStorageElem = (TStorageObj*)ActiveCircuit[ActiveActor]->StorageElements.Get_Active(); + if (ASSIGNED(pStorageElem)) + { + Result = pStorageElem->get_Name(); + } + } + } + break; + case 1: // Storages.Name Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + lst = &(ActiveCircuit[ActiveActor]->StorageElements); + S = arg; + Found = false; + ActiveSave = lst->get_myActiveItem(); + pStorageElem = (TStorageObj*)lst->Get_First(); + while (pStorageElem != nullptr) + { + if (CompareText(pStorageElem->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pStorageElem); + Found = true; + break; + } + pStorageElem = (TStorageObj*)lst->Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Storage '" + S + "' Not Found in Active Circuit.", 5003); + pStorageElem = (TStorageObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pStorageElem); + } + } + } + break; + default: + Result = "Error, parameter not valid"; + } + char* presult = new char[Result.size() + 1]; + strcpy(presult, Result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall StoragesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TStorageObj* pStorageElem = nullptr; + int k = 0; + + switch (mode) + { + case 0: // Storages.AllNames + { + *myType = 4; //String + myStrArray.resize(0); + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->StorageElements.NumInList > 0) + { + k = 0; + pStorageElem = (TStorageObj*)with0->StorageElements.Get_First(); + while (ASSIGNED(pStorageElem)) + { + WriteStr2Array(pStorageElem->get_Name()); + WriteStr2Array(Char0()); + k++; + pStorageElem = (TStorageObj*)with0->StorageElements.Get_Next(); + } + } + } + if (myStrArray.empty()) + WriteStr2Array("None"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + case 1: // Storages.RegisterNames + { + *myType = 4; // String + myStrArray.resize(0); + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + for (k = 0; k < NumStorageRegisters; k++) + { + WriteStr2Array(StorageClass[ActiveActor]->RegisterNames[k]); + WriteStr2Array(Char0()); + } + } + if (myStrArray.empty()) + WriteStr2Array("None"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + case 2: // Storages.RegisterValues + { + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + auto with0 = ActiveCircuit[ActiveActor]; + pStorageElem = (TStorageObj*)with0->FActiveCktElement; + if (ASSIGNED(pStorageElem)) + { + myDblArray.resize(NumStorageRegisters); + for (k = 0; k < NumStorageRegisters; k++) + { + myDblArray[k] = pStorageElem->Registers[k]; + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + } + break; + default: + { + *myType = 4; // String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + + } + + +} + +//-------------------------------------------------------------------------------- +// Implements the SwtControls interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Help Functions************************* + +TSwtControlObj* __stdcall ActiveSwtControl() +{ + TSwtControlObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TSwtControlObj*)ActiveCircuit[ActiveActor]->SwtControls.Get_Active(); + } + return result; +} + +void Set_ParameterSwtControl(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("swtcontrol.%s.%s=%s", ActiveSwtControl()->LName.c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ******************************int type properties************************* +int __stdcall SwtControlsI(int mode, int arg) +{ + TSwtControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int result = 0; + + switch (mode) + { + case 0: // SwtControls. + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->SwtControls); + elem = (TSwtControlObj*)lst->Get_First(); + if (elem != nullptr) + { + do + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + } + else + { + elem = (TSwtControlObj*)lst->Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(elem)))); + } + } + break; + case 1: // SwtControls. + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->SwtControls); + elem = (TSwtControlObj*)lst->Get_Next(); + if (elem != nullptr) + { + do + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->get_myActiveItem(); + } + else + { + elem = (TSwtControlObj*)lst->Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(elem)))); + } + } + break; + case 2: // SwtControls. + result = 0; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + switch (elem->get_ActionCommand()) + { + case CTRL_CLOSE: + result = 2; + break; + case CTRL_OPEN: + result = 1; + break; + } + } + break; + case 3: // SwtControls. + elem = ActiveSwtControl(); + if (elem != nullptr) + { + switch (arg) + { + case 1: + Set_ParameterSwtControl("Action", "0"); + break; + case 2: + Set_ParameterSwtControl("Action", "c"); + break; + case 3: + Set_ParameterSwtControl("Lock", "n"); + Set_ParameterSwtControl("Action", "c"); + break; + case 4: + Set_ParameterSwtControl("Lock", "y"); + break; + case 5: + Set_ParameterSwtControl("Lock", "n"); + break; + } + } + break; + case 4: // SwtControls. + result = 0; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + if (elem->FLocked) + { + result = 1; + } + } + break; + case 5: // SwtControls. + if (arg == 1) + { + Set_ParameterSwtControl("Lock", "y"); + } + else + { + Set_ParameterSwtControl("Lock", "n"); + } + break; + case 6: // SwtControls. + result = 0; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + result = elem->ElementTerminal; + } + break; + case 7: // SwtControls. + Set_ParameterSwtControl("SwitchedTerm", IntToStr(arg)); + break; + case 8: // SwtControls. + if(ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->SwtControls.get_myNumList(); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall SwtControlsF(int mode, double arg) +{ + TSwtControlObj* elem = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: // SwtControls. + result = 0.0; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + result = elem->TimeDelay; + } + break; + case 1: // SwtControls. + Set_ParameterSwtControl("Delay", std::to_string(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall SwtControlsS(int mode, char* arg) +{ + TSwtControlObj* elem = nullptr; + int ActiveSave = 0; + bool Found = true; + TPointerList* lst = nullptr; + string S = "", + result = ""; + + switch (mode) + { + case 0: // SwtControls. + result = ""; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + result = elem->get_Name(); + } + break; + case 1: // SwtControls. + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->SwtControls); + S = arg; + Found = false; + ActiveSave = lst->get_myActiveItem(); + elem = (TSwtControlObj*)lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->get_Name(),S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TSwtControlObj*)lst->Get_Next(); + } + if (!Found) + { + DoSimpleMsg("SwtControl " + S + " Not Found in Active Circuit.", 5003); + elem = (TSwtControlObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 2: // SwtControls. + result = ""; + elem = ActiveSwtControl(); + if (elem != nullptr) + { + result = elem->ElementName; + } + break; + case 3: // SwtControls. + Set_ParameterSwtControl("SwitchedObj",arg); + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall SwtControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TSwtControlObj* elem = nullptr; + TPointerList* lst = nullptr; + int k = 0; + + switch (mode) + { + case 0: // SwtControls. + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->SwtControls.get_myNumList() > 0) + { + lst = &(with0->SwtControls); + elem = (TSwtControlObj*)lst->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->get_Name()); + WriteStr2Array(Char0()); + elem = (TSwtControlObj*)lst->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Topology interface for the DLL +//-------------------------------------------------------------------------------- +//******************************Help Functions************************* +TCktTree* ActiveTree() +{ + TCktTree* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result =&(ActiveCircuit[ActiveActor]->GetTopology()); + } + return result; +} +TCktTreeNode* ActiveTreeNode() +{ + TCktTree* topo = nullptr; + TCktTreeNode* result = nullptr; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + result = topo->PresentBranch; + } + return result; +} +int ForwardBranch() +{ + TCktTree* topo = nullptr; + int result = 0; + topo = ActiveTree(); + if (ASSIGNED(topo) && topo->Get_Forward() != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)topo->PresentBranch->CktObject); + result = 1; + } + return result; +} +int ActiveBranch() +{ + TCktTree* topo = nullptr; + TCktTreeNode* node = nullptr; + int result = 0; + topo = ActiveTree(); + node = ActiveTreeNode(); + if (ASSIGNED(topo)) + { + result = topo->Get_Level(); + if (node != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)node->CktObject); + } + } + return result; +} + +// ******************************int type properties************************* +int __stdcall TopologyI(int mode, int arg) +{ + TCktTree* topo = nullptr; + TPDElement* pdElem = nullptr; + TPDElement* elm = nullptr; + TCktTreeNode* node = nullptr; + int result = 0; + + switch (mode) + { + case 0: // Topology.NumLoops + result = 0; + topo = ActiveTree(); + if (topo != nullptr) + { + result = 0; + pdElem = (TPDElement*)topo->Get_First(); + while (ASSIGNED(pdElem)) + { + if (topo->PresentBranch->IsLoopedHere) + { + result++; + } + pdElem = (TPDElement*)topo->Get_Forward(); + } + } + result = result / 2; + break; + case 1: // Topology.NumIsolatedBranches + result = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while (ASSIGNED(elm)) + { + if (elm->IsIsolated) + { + result++; + } + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + } + break; + case 2: // Topology.NumIsolatedLoads + result = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while (ASSIGNED(elm)) + { + if (elm->IsIsolated) + { + result++; + } + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + break; + case 3: // Topology.First + result = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + if (ASSIGNED(topo->Get_First())) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)topo->PresentBranch->CktObject); + result = 1; + } + } + break; + case 4: // Topology.Next + result = ForwardBranch(); + break; + case 5: // Topology.ActiveBranch + result = ActiveBranch(); + break; + case 6: // Topology.ForwardBranch + result = ForwardBranch(); + break; + case 7: // Topology.BackwardBranch + result = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + if (ASSIGNED(topo->Get_Backward())) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)topo->PresentBranch->CktObject); + result = 1; + } + } + break; + case 8: // Topology.LoopedBranch + result = 0; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + if (node->IsLoopedHere) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)node->LoopLineObj); + result = 1; + } + } + break; + case 9: // Topology.ParallelBranch + result = 0; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + if (node->IsParallel) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)node->LoopLineObj); + result = 1; + } + } + break; + case 10: // Topology.FirstLoad + result = 0; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + elm = (TPDElement*)node->FShuntObjects->Get_First(); + if (ASSIGNED(elm)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elm); + result = 1; + } + } + break; + case 11: // Topology.NextLoad + result = 0; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + elm = (TPDElement*)node->FShuntObjects->Get_Next(); + if (ASSIGNED(elm)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elm); + result = 1; + } + } + break; + case 12: // Topology.ActiveLevel + result = ActiveBranch(); + break; + default: + result = -1; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall TopologyS(int mode, char* arg) +{ + TCktTreeNode* node = nullptr; + TDSSCktElement* elm = nullptr; + TCktTree* topo = nullptr; + bool Found = false; + TDSSCktElement* elem = nullptr; + TPDElement* pdElem = nullptr; + string S = "", + B = "", + result = ""; + + switch (mode) + { + case 0: // Topology.BranchName read + result = ""; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + elm = (TDSSCktElement*)node->CktObject; + if (ASSIGNED(elm)) + { + result = elm->Get_QualifiedName(); + } + } + break; + case 1: // Topology.BranchName write + Found = false; + elem = nullptr; + S = std::string(arg); + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + pdElem = (TPDElement*)topo->Get_First(); + while (ASSIGNED(pdElem)) + { + if (CompareText(pdElem->Get_QualifiedName(),S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pdElem); + Found = true; + break; + } + pdElem = (TPDElement*)topo->Get_Forward(); + } + } + if (!Found) + { + DoSimpleMsg("Branch '" + S + "' Not Found in Active Circuit Topology.", 5003); + if (ASSIGNED(elem)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 2: // Topology.BusName read + result = ""; + node = ActiveTreeNode(); + if (ASSIGNED(node)) + { + elm = (TPDElement*)node->CktObject; + if (ASSIGNED(elm)) + { + result = elm->Get_FirstBus(); + } + } + break; + case 3: // Topology.BusName write + Found = false; + elem = nullptr; + S = std::string(arg); + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + pdElem =(TPDElement*)topo->Get_First(); + while (ASSIGNED(pdElem) && !Found) + { + B = pdElem->Get_FirstBus(); + while (B.size() > 0) + { + if (CompareText(B, S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pdElem); + Found = true; + break; + } + B = pdElem->Get_NextBus(); + } + pdElem = (TPDElement*)topo->Get_Forward(); + } + } + if (!Found) + { + DoSimpleMsg("Bus " + S + " Not Found in Active Circuit Topology.", 5003); + if (ASSIGNED(elem)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall TopologyV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TCktTree* topo = nullptr; + TPDElement* pdElem = nullptr; + TPDElement* pdLoop = nullptr; + int k = 0, + i = 0; + bool Found = false; + TPDElement* elm = nullptr; + std::vector TStr; + + switch (mode) + { + case 0: // Topology.AllLoopedPairs + *myType = 4; + myStrArray.resize(0); + TStr.resize(1); + TStr[0] = "NONE"; + k = -1; + topo = ActiveTree(); + if (topo != nullptr) + { + pdElem = (TPDElement*)topo->Get_First(); + while (ASSIGNED(pdElem)) + { + if (topo->PresentBranch->IsLoopedHere) + { + pdLoop = (TPDElement*)topo->PresentBranch->LoopLineObj; + Found = false; + i = 1; + while (i <= k && !Found) + { + if (TStr[i-1] == pdElem->Get_QualifiedName() && TStr[i] == pdLoop->Get_QualifiedName()) + { + Found = true; + } + if (TStr[i - 1] == pdLoop->Get_QualifiedName() && TStr[i] == pdElem->Get_QualifiedName()) + { + Found = true; + } + i++; + } + if (!Found) + { + k = k + 2; + TStr.resize(k + 1); + TStr[k - 1] = pdElem->Get_QualifiedName(); + TStr[k] = pdLoop->Get_QualifiedName(); + } + } + pdElem = (TPDElement*)topo->Get_Forward(); + } + } + if (TStr.size() > 0) + { + for (i = 0; i < TStr.size(); i++) + { + if (TStr[i] != "") + { + WriteStr2Array(TStr[i]); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: // Topology.AllIsolatedBranches + *myType = 4; + myStrArray.resize(0); + TStr.resize(1); + TStr[0] = "NONE"; + k = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PDElements.Get_First(); + while (ASSIGNED(elm)) + { + if (elm->IsIsolated) + { + TStr[k] = elm->Get_QualifiedName(); + k++; + if (k > 0) + { + TStr.resize(k + 1); + } + } + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PDElements.Get_Next(); + } + } + if (TStr.size() > 0) + { + for (i = 0; i < TStr.size(); i++) + { + if (TStr[i] != "") + { + WriteStr2Array(TStr[i]); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 2: // Topology.AllIsolatedLoads + *myType = 4; + myStrArray.resize(0); + TStr.resize(1); + TStr[0] = "NONE"; + k = 0; + topo = ActiveTree(); + if (ASSIGNED(topo)) + { + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PCElements.Get_First(); + while (ASSIGNED(elm)) + { + if (elm->IsIsolated) + { + TStr[k] = elm->Get_QualifiedName(); + k++; + if (k > 0) + { + TStr.resize(k + 1); + } + } + elm = (TPDElement*)ActiveCircuit[ActiveActor]->PCElements.Get_Next(); + } + } + if (TStr.size() > 0) + { + for (i = 0; i < TStr.size(); i++) + { + if (TStr[i] != "") + { + WriteStr2Array(TStr[i]); + WriteStr2Array(Char0()); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the Transformers interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************Help Functions************************* +TTransfObj* __stdcall ActiveTransformer() +{ + TTransfObj* result = nullptr; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = (TTransfObj*)ActiveCircuit[ActiveActor]->Transformers.Get_Active(); + } + return result; +} + +void Set_ParameterTransformer(string parm, string val) +{ + string mycmd = ""; + if ((ASSIGNED(ActiveCircuit[ActiveActor]))) + { + SolutionAbort = false;// Reset for commands entered from outside + mycmd = Format("transformer.%s.%s=%s", ActiveTransformer()->get_Name().c_str(), parm.c_str(), val.c_str()); + DSSExecutive[ActiveActor]->Set_Command(mycmd); + } +} +// ******************************int type properties************************* +int __stdcall TransformersI(int mode, int arg) +{ + TTransfObj* elem = nullptr; + TPointerList* lst = nullptr; + int result = 0; + + switch (mode) + { + case 0: //Transformers.NumWindings read + result = 0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->get_NumWindings(); + } + break; + case 1: //Transformers.NumWindings write + elem = ActiveTransformer(); + if (elem != nullptr) + { + elem->SetNumWindings(arg); + } + break; + case 2: //Transformers.Wdg read + result = 0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->ActiveWinding; + } + break; + case 3: //Transformers.Wdg write + elem = ActiveTransformer(); + if (elem != nullptr) + { + if ((arg > 0) && (arg <= elem->get_NumWindings())) + { + elem->ActiveWinding = arg; + } + } + break; + case 4: //Transformers.NumTaps read + result = 0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_NumTaps(elem->ActiveWinding); + } + break; + case 5: //Transformers.NumTaps write + Set_ParameterTransformer("NumTaps", IntToStr(arg)); + break; + case 6: //Transformers.IsDelta read + result = 0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + if (elem->Get_WdgConnection(elem->ActiveWinding) > 0) + { + result = 1; + } + } + break; + case 7: //Transformers.IsDelta write + if (arg == 1) + { + Set_ParameterTransformer("Conn", "Delta"); + } + else + { + Set_ParameterTransformer("Conn", "Wye"); + } + break; + case 8: //Transformers.First + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Transformers); + elem = (TTransfObj*)lst->Get_First(); + if (elem != nullptr) + { + do + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = 1; + } + else + { + elem = (TTransfObj*)lst->Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(elem)))); + } + } + break; + case 9: //Transformers.Next + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Transformers); + elem = (TTransfObj*)lst->Get_Next(); + if (elem != nullptr) + { + do + { + if (elem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + result = lst->get_myActiveItem(); + } + else + { + elem = (TTransfObj*)lst->Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(elem)))); + } + } + break; + case 10: //Transformers.Count + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = ActiveCircuit[ActiveActor]->Transformers.get_myNumList(); + } + break; + case 11: //Transformers.CoreType read + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->CoreType; + } + break; + case 12: //Transformers.CoreType write + elem = ActiveTransformer(); + if (elem !=nullptr) + { + elem->CoreType = arg; + switch (arg) + { + case 1: + elem->strCoreType = "1-phase"; + break; + case 3: + elem->strCoreType = "3-leg"; + break; + case 5: + elem->strCoreType = "4-leg"; + break; + case 7: + elem->strCoreType = "5-leg"; + break; + case 9: + elem->strCoreType = "core-1-phase"; + break; + default: + elem->strCoreType = "shell"; + break; + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall TransformersF(int mode, double arg) +{ + TTransfObj* elem = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_WdgResistance(elem->ActiveWinding) * 100.0; + } + break; + case 1: //Transformers. + Set_ParameterTransformer("%R", std::to_string(arg)); + break; + case 2: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_PresentTap(elem->ActiveWinding,ActiveActor); + } + break; + case 3: //Transformers. + Set_ParameterTransformer("Tap", std::to_string(arg)); + break; + case 4: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_MinTap(elem->ActiveWinding); + } + break; + case 5: //Transformers. + Set_ParameterTransformer("MinTap", std::to_string(arg)); + break; + case 6: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_MaxTap(elem->ActiveWinding); + } + break; + case 7: //Transformers. + Set_ParameterTransformer("MaxTap", std::to_string(arg)); + break; + case 8: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->WINDING_[elem->ActiveWinding - 1].kVLL; + } + break; + case 9: //Transformers. + Set_ParameterTransformer("kv", std::to_string(arg)); + break; + case 10: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_WdgkVA(elem->ActiveWinding); + } + break; + case 11: //Transformers. + Set_ParameterTransformer("kva", std::to_string(arg)); + break; + case 12: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_WdgXneutral(elem->ActiveWinding); + } + break; + case 13: //Transformers. + Set_ParameterTransformer("Xneut", std::to_string(arg)); + break; + case 14: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_WdgRneutral(elem->ActiveWinding); + } + break; + case 15: //Transformers. + Set_ParameterTransformer("Rneut", std::to_string(arg)); + break; + case 16: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->get_XHL() * 100.0; + } + break; + case 17: //Transformers. + Set_ParameterTransformer("Xhl", std::to_string(arg)); + break; + case 18: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->get_XHT() * 100.0; + } + break; + case 19: //Transformers. + Set_ParameterTransformer("Xht", std::to_string(arg)); + break; + case 20: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->get_XLT() * 100.0; + } + break; + case 21: //Transformers. + Set_ParameterTransformer("Xlt", std::to_string(arg)); + break; + case 22: //Transformers. + result = 0.0; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->Get_WdgRdc(elem->ActiveWinding); + } + break; + case 23: //Transformers. + Set_ParameterTransformer("RdcOhms", std::to_string(arg)); + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall TransformersS(int mode, char* arg) +{ + TTransfObj* elem = nullptr; + int ActiveSave = 0; + bool Found = false; + TPointerList* lst = nullptr; + string S = "", + result = ""; + + switch (mode) + { + case 0: //Transformers. + result = ""; + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->XfmrCode; + } + break; + case 1: //Transformers. + Set_ParameterTransformer("XfmrCode", arg); + break; + case 2: //Transformers. + result = ""; + if (ActiveCircuit[ActiveActor] != nullptr) + { + elem = (TTransfObj*)ActiveCircuit[ActiveActor]->Transformers.Get_Active(); + if (elem != nullptr) + { + result = elem->get_Name(); + } + } + break; + case 3: //Transformers. + if (ActiveCircuit[ActiveActor] != nullptr) + { + lst = &(ActiveCircuit[ActiveActor]->Transformers); + S = arg; + Found = false; + ActiveSave = lst->get_myActiveItem(); + elem = (TTransfObj*)lst->Get_First(); + while (elem != nullptr) + { + if (CompareText(elem->get_Name(),S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + Found = true; + break; + } + elem = (TTransfObj*)lst->Get_Next(); + } + if (!Found) + { + DoSimpleMsg("Transformer '" + S + "' Not Found in Active Circuit.", 5003); + elem = (TTransfObj*)lst->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(elem); + } + } + break; + case 4: //Transformers. + elem = ActiveTransformer(); + if (elem != nullptr) + { + result = elem->GetWindingCurrentsResult(ActiveActor); + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall TransformersV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TTransfObj* elem = nullptr; + TPointerList* lst = nullptr; + int i = 0, + iV = 0, + NumCurrents = 0, + k = 0; + vector TempCurrentBuffer, + TempVoltageBuffer; + switch (mode) + { + case 0: //Transformers. + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Transformers.get_myNumList() > 0) + { + lst = &(with0->Transformers); + k = 0; + elem = (TTransfObj*)lst->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->get_Name()); + WriteStr2Array(Char0()); + k++; + elem = (TTransfObj*)lst->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + case 1: //Transformers. + *myType = 3; //Complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + elem = ActiveTransformer(); + if (elem != nullptr && !ActiveCircuit[ActiveActor]->Solution->NodeV.empty()) + { + if (elem->ActiveWinding > 0 && (elem->ActiveWinding <= elem->get_NumWindings())) + { + myCmplxArray.resize(elem->Get_NPhases()); + TempVoltageBuffer.resize(elem->Get_NPhases()); + elem->GetWindingVoltages(elem->ActiveWinding, &(TempVoltageBuffer[0]), ActiveActor); + for (i = 0; i < elem->Get_NPhases(); i++) + { + myCmplxArray[i] = TempVoltageBuffer[i]; + } + TempVoltageBuffer.clear(); + } + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = sizeof(myCmplxArray[0]) * myCmplxArray.size(); + break; + case 2: //Transformers. + *myType = 3; //Complex + myCmplxArray.resize(1); + myCmplxArray[0] = CZero; + elem = ActiveTransformer(); + if (elem != nullptr) + { + NumCurrents = 2 * elem->Get_NPhases() * elem->get_NumWindings(); + myCmplxArray.resize(NumCurrents); + TempCurrentBuffer.resize(NumCurrents); + elem->GetAllWindingCurrents(&(TempCurrentBuffer[0]), ActiveActor); + for (i = 0; i < NumCurrents; i++) + { + myCmplxArray[i] = TempCurrentBuffer[i]; + } + TempCurrentBuffer.clear(); + } + *myPtr = (uintptr_t)(void*)(myCmplxArray.data()); + *mySize = sizeof(myCmplxArray[0]) * myCmplxArray.size(); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + + +//-------------------------------------------------------------------------------- +// Implements the VSources interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall VsourcesI(int mode, int arg) +{ + TVsourceObj* pElem = nullptr; + TVsourceObj* elem = nullptr; + int result = 0; + + switch (mode) + { + case 0: //VSources. + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + result = VSourceClass[ActiveActor]->ElementList.get_myNumList(); + } + break; + case 1: //VSources. + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_First(); + if (pElem != nullptr) + { + do + { + if (pElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = 1; + } + else + { + pElem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Next(); + } + } while (!((result == 1) || (!ASSIGNED(elem)))); + } + } + break; + case 2: //VSources. + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pElem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Next(); + if (pElem != nullptr) + { + do + { + if (pElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pElem); + result = VSourceClass[ActiveActor]->ElementList.get_myActiveItem(); + } + else + { + pElem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Next(); + } + } while (!((result > 0) || (!ASSIGNED(elem)))); + } + } + break; + case 3: //VSources. + result = 0; + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Get_NPhases(); + } + break; + case 4: //VSources. + elem = (TVsourceObj*)VSourceClass[ActiveActor]->GetActiveObj(); + if (elem != nullptr) + { + elem->Set_NPhases(arg); + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall VsourcesF(int mode, double arg) +{ + TVsourceObj* elem = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: //VSources. + result = 0.0; + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->kVBase; + } + break; + case 1: //VSources. + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->kVBase = arg; + } + break; + case 2: //VSources. + result = 0.0; + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->PerUnit; + } + break; + case 3: //VSources. + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->PerUnit = arg; + } + break; + case 4: //VSources. + result = 0.0; + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->Angle; + } + break; + case 5: //VSources. + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->Angle = arg; + } + break; + case 6: //VSources. + result = 0.0; + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + result = elem->SrcFrequency; + } + break; + case 7: //VSources. + elem = (TVsourceObj*)VSourceClass[ActiveActor]->ElementList.Get_Active(); + if (elem != nullptr) + { + elem->SrcFrequency = arg; + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall VsourcesS(int mode, char* arg) +{ + TDSSCktElement* elem = nullptr; + string result = ""; // Default return value + + switch (mode) + { + case 0: //VSources. + result = ""; + elem = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + if (elem != nullptr) + { + result = elem->get_Name(); + } + break; + case 1: //VSources. + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (VSourceClass[ActiveActor]->SetActive(std::string(arg))) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*)VSourceClass[ActiveActor]->ElementList.Get_Active()); + } + else + { + DoSimpleMsg("Vsource '" + (string)arg + "' Not Found in Active Circuit.", 77003); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall VsourcesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TVsourceObj* elem = nullptr; + TPointerList* pList = nullptr; + int k = 0; + + switch (mode) + { + case 0: //VSources. + *myType = 4; //String + myStrArray.resize(0); + if (ActiveCircuit[ActiveActor] != nullptr) + { + if (VSourceClass[ActiveActor]->ElementList.get_myNumList() > 0) + { + pList = &(VSourceClass[ActiveActor]->ElementList); + elem = (TVsourceObj*)pList->Get_First(); + while (elem != nullptr) + { + WriteStr2Array(elem->get_Name()); + WriteStr2Array(Char0()); + elem = (TVsourceObj*) pList->Get_Next(); + } + } + } + if (myStrArray.size() == 0) + { + WriteStr2Array("None"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the WindGens interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall WindGensI(int mode, int arg) +{ + TWindGenObj* WindGenElem = nullptr; + TPointerList* pList = nullptr; + int Result = 0; // Default return value + + switch (mode) + { + case 0: // WindGens.First + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (WindGenClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = &WindGenClass[ActiveActor]->ElementList; + WindGenElem = (TWindGenObj*)pList->Get_First(); + if (WindGenElem != nullptr) + { + do + { + if (WindGenElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(WindGenElem); + Result = 1; + } + else + WindGenElem = (TWindGenObj*)pList->Get_Next(); + } while (!((Result == 1) || (!ASSIGNED(WindGenElem)))); + } + } + else + Result = 0; // signify no more + } + } + break; + case 1: // WindGens.Next + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (WindGenClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = &WindGenClass[ActiveActor]->ElementList; + WindGenElem = (TWindGenObj*)pList->Get_Next(); + if (WindGenElem != nullptr) + { + do + { + if (WindGenElem->FEnabled) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(WindGenElem); + Result = pList->ActiveItem; + } + else + WindGenElem = (TWindGenObj*)pList->Get_Next(); + } while (!((Result > 0) || (!ASSIGNED(WindGenElem)))); + } + } + else + Result = 0; // signify no more + } + } + break; + case 2: // WindGens.Count + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Result = WindGenClass[ActiveActor]->ElementList.NumInList; + } + } + break; + case 3: // WindGens.Idx read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + Result = WindGenClass[ActiveActor]->ElementList.ActiveItem; + } + } + break; + case 4: // WindGens.Idx Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get(arg); + if (ASSIGNED(WindGenElem)) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(WindGenElem); + } + } + } + break; + case 5: // WindGens.N_WTG Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->N_WTG; + } + } + } + break; + case 6: // WindGens.N_WTG Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->N_WTG = arg; + } + } + } + break; + case 7: // WindGens.NPoles Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = (int)round(WindGenElem->WindGenVars.Poles); + } + } + } + break; + case 8: // WindGens.NPoles Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.Poles = (double)arg; + } + } + } + break; + case 9: // WindGens.QFlag Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->QFlg; + } + } + } + break; + case 10: // WindGens.QFlag Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->QFlg = arg; + } + } + } + break; + case 11: // WindGens.QMode Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->QMode; + } + } + } + break; + case 12: // WindGens.QMode Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->QMode = arg; + } + } + } + break; + default: + Result = -1; // The user is asking for the wrong command + break; + } + + return Result; + + +} +//******************************Float point type properties**************************** +double __stdcall WindGensF(int mode, double arg) +{ + TWindGenObj* WindGenElem = nullptr; + double Result = 0.0; // Default return value + + switch (mode) + { + case 0: // WindGens.Ag Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.ag; + } + } + } + break; + case 1: // WindGens.Ag Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.ag = arg; + } + } + } + break; + case 2: // WindGens.Cp Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.Cp; + } + } + } + break; + case 3: // WindGens.Cp Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.Cp = arg; + } + } + } + break; + case 4: // WindGens.kV Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->Get_PresentkV(); + } + } + } + break; + case 5: // WindGens.kV Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->Set_PresentkV(arg); + } + } + } + break; + case 6: // WindGens.kVA Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.kVArating; + } + } + } + break; + case 7: // WindGens.kVA Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.kVArating = arg; + WindGenElem->WindModelDyn->EditProp(13, to_string(arg)); + } + } + } + break; + case 8: // WindGens.kvar Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->Get_Presentkvar(); + } + } + } + break; + case 9: // WindGens.kvar Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->Set_Presentkvar(arg); + } + } + } + break; + case 10: // WindGens.kW Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->Get_PresentkW(); + } + } + } + break; + case 11: // WindGens.kW Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->Set_PresentkW(arg); + } + } + } + break; + case 12: // WindGens.Lamda Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.Lamda; + } + } + } + break; + case 13: // WindGens.Lamda Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.Lamda = arg; + } + } + } + break; + case 14: // WindGens.pd Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.pd; + } + } + } + break; + case 15: // WindGens.pd Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.pd = arg; + } + } + } + break; + case 16: // WindGens.PF Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->PFNominal; + } + } + } + break; + case 17: // WindGens.PF Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->PFNominal = arg; + } + } + } + break; + case 18: // WindGens.Pss Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->Pss; + } + } + } + break; + case 19: // WindGens.Pss Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->Pss = arg; + } + } + } + break; + case 20: // WindGens.Qss Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->Qss; + } + } + } + break; + case 21: // WindGens.Qss Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->Qss = arg; + } + } + } + break; + case 22: // WindGens.Rad Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.Rad; + } + } + } + break; + case 23: // WindGens.Rad Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.Rad = arg; + } + } + } + break; + case 24: // WindGens.RThev Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->Rthev; + } + } + } + break; + case 25: // WindGens.RThev Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->Rthev = arg; + } + } + } + break; + case 26: // WindGens.VCutOut Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.VCutout; + } + } + } + break; + case 27: // WindGens.VCutOut Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.VCutout = arg; + } + } + } + break; + case 28: // WindGens.VCutIn Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindGenVars.VCutin; + } + } + } + break; + case 29: // WindGens.VCutIn Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindGenVars.VCutin = arg; + } + } + } + break; + case 30: // WindGens.Vss Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->Vss; + } + } + } + break; + case 31: // WindGens.Vss Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->Vss = arg; + } + } + } + break; + case 32: // WindGens.WindSpeed Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->vwind; + } + } + } + break; + case 33: // WindGens.WindSpeed Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->vwind = arg; + } + } + } + break; + case 34: // WindGens.XThev Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->WindModelDyn->Xthev; + } + } + } + break; + case 35: // WindGens.XThev Write + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + WindGenElem->WindModelDyn->Xthev = arg; + } + } + } + break; + default: + Result = -1.0; // we got the wrong command + break; + } + return Result; +} +//******************************String type properties**************************** +char* __stdcall WindGensS(int mode, char* arg) +{ + TWindGenObj* WindGenElem = nullptr; + int k = 0, + ActiveSave = 0; + TPointerList* pList = nullptr; + string Result = "", // Default return value + S = ""; + bool Found = false; + + switch (mode) + { + case 0: // WindGen.Name Read + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + Result = WindGenElem->get_Name(); + } + } + } + break; + case 1: + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pList = &(ActiveCircuit[ActiveActor]->WindGens); + S = arg; + Found = false; + ActiveSave = pList->get_myActiveItem(); + WindGenElem = (TWindGenObj*)pList->Get_First(); + while (WindGenElem != nullptr) + { + if (CompareText(WindGenElem->get_Name(), S) == 0) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(WindGenElem); + Found = true; + break; + } + WindGenElem = (TWindGenObj*)pList->Get_Next(); + } + if (!Found) + { + DoSimpleMsg("WindGen '" + S + "' Not Found in Active Circuit.", 5003); + WindGenElem = (TWindGenObj*)pList->Get(ActiveSave); + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(WindGenElem); + } + } + } + break; + default: + Result = "Error, parameter not valid"; + } + + char* presult = new char[Result.size() + 1]; + strcpy(presult, Result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall WindGensV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TWindGenObj* WindGenElem = nullptr; + int k = 0; + TPointerList* pList = nullptr; + + switch (mode) + { + case 0: // WindGen.AllNames + { + *myType = 4; //string + myStrArray.resize(0); + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (WindGenClass[ActiveActor]->ElementList.NumInList > 0) + { + pList = &(WindGenClass[ActiveActor]->ElementList); + k = 0; + WindGenElem = (TWindGenObj*)pList->Get_First(); + while (ASSIGNED(WindGenElem)) + { + WriteStr2Array(WindGenElem->get_Name()); + WriteStr2Array(Char0()); + k++; + WindGenElem = (TWindGenObj*)pList->Get_Next(); + } + } + } + if (myStrArray.empty()) + WriteStr2Array("None"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + case 1: // WindGen.RegisterNames + { + *myType = 4; // string + myStrArray.resize(0); + + for (k = 0; k < NumWGenRegisters; k++) + { + WriteStr2Array(WindGenClass[ActiveActor]->RegisterNames[k]); + WriteStr2Array(Char0()); + } + + if (myStrArray.empty()) + WriteStr2Array("None"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + case 2: // WindGen.RegisterValues + { + *myType = 2; // Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + WindGenElem = (TWindGenObj*)WindGenClass[ActiveActor]->ElementList.Get_Active(); + if (ASSIGNED(WindGenElem)) + { + myDblArray.resize(NumWGenRegisters); + for (k = 0; k < NumWGenRegisters; k++) + { + myDblArray[k] = WindGenElem->Registers[k]; + } + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = myDblArray.size() * sizeof(myDblArray[0]); + } + break; + default: // Something else + *myType = 4; // string + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//-------------------------------------------------------------------------------- +// Implements the XYCurves interface for the DLL +//-------------------------------------------------------------------------------- +// ******************************int type properties************************* +int __stdcall XYCurvesI(int mode, int arg) +{ + TXYcurveObj* pXYCurve = nullptr; + int result = 0; + + switch (mode) + { + case 0: //XYCurves.Count + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = XYCurveClass[ActiveActor]->Get_ElementCount(); + } + break; + case 1: //XYCurves.First + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = XYCurveClass[ActiveActor]->Get_First(); + } + break; + case 2: //XYCurves.Next + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + result = XYCurveClass[ActiveActor]->Get_Next(); + } + break; + case 3: //XYCurves.Npts read + result = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->get_FNumPoints(); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51009); + } + } + break; + case 4: //XYCurves.Npts write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->Set_NumPoints(arg); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51014); + } + } + break; + default: + result = -1; + break; + } + return result; +} +//******************************Float point type properties**************************** +double __stdcall XYCurvesF(int mode, double arg) +{ + TXYcurveObj* pXYCurve = nullptr; + double result = 0.0; + + switch (mode) + { + case 0: //XYCurves.X read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->Get_X(); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 1: //XYCurves.X write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->Set_X(arg); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 2: //XYCurves.Y read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->Get_Y(); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51011); + } + } + break; + case 3: //XYCurves.Y write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->Set_Y(arg); + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 4: //XYCurves.Xshift read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->FXshift; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51011); + } + } + break; + case 5: //XYCurves.Xshift write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->FXshift = arg; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 6: //XYCurves.YShift read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->FYshift; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51011); + } + } + break; + case 7: //XYCurves.YShift write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->FYshift = arg; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 8: //XYCurves.XScale read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->FXscale; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51011); + } + } + break; + case 9: //XYCurves.XScale write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->FXscale = arg; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + case 10: //XYCurves.YScale read + result = 0.0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->FYscale; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51011); + } + } + break; + case 11: //XYCurves.YScale write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + pXYCurve->FYscale = arg; + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51010); + } + } + break; + default: + result = -1.0; + break; + } + return result; +} +//******************************String type properties**************************** +char* __stdcall XYCurvesS(int mode, char* arg) +{ + TXYcurveObj* pXYCurve = nullptr; + string result =""; + + switch (mode) + { + case 0: //XYCurves.Name read + result = ""; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + result = pXYCurve->get_Name(); + } + } + break; + case 1: //XYCurves.Name write + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + if (! XYCurveClass[ActiveActor]->SetActive(string(arg))) + { + DoSimpleMsg("XYCurve '" + string(arg) + "' Not Found in Active Circuit.", 51008); + } + } + break; + default: + result = "Error, parameter not valid"; + break; + } + char* presult = new char[result.size() + 1]; + strcpy(presult, result.c_str()); + return presult; +} +//************************Structure type properties******************************* +void __stdcall XYCurvesV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + TXYcurveObj* pXYCurve = nullptr; + int k = 0, + i = 0, + LoopLimit = 0; + double* pDouble = nullptr; + + switch (mode) + { + case 0: //XYCurves.x read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + myDblArray.resize(pXYCurve->get_FNumPoints()); + for (k = 0; k < pXYCurve->get_FNumPoints(); k++) + { + myDblArray[k] = pXYCurve->Get_XValue(k + 1); + } + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51013); + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 1: //XYCurves.x write + *myType = 2; + k = 1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + LoopLimit = pXYCurve->get_FNumPoints(); + pDouble = *(double**)myPtr; + for (i = 1; i <= LoopLimit; i++) + { + pXYCurve->Set_XValue(k, *pDouble); + pDouble++; + k++; + } + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51015); + } + } + *mySize = k - 1; + break; + case 2: //XYCurves.Y read + *myType = 2; //Double + myDblArray.resize(1); + myDblArray[0] = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + myDblArray.resize(pXYCurve->get_FNumPoints()); + for (k = 0; k < pXYCurve->get_FNumPoints(); k++) + { + myDblArray[k] = pXYCurve->Get_YValue(k + 1); + } + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51013); + } + } + *myPtr = (uintptr_t)(void*)&(myDblArray[0]); + *mySize = sizeof(myDblArray[0]) * myDblArray.size(); + break; + case 3: //XYCurves.Y write + *myType = 2; + k = 1; + if (ActiveCircuit[ActiveActor] != nullptr) + { + pXYCurve = (TXYcurveObj*)XYCurveClass[ActiveActor]->GetActiveObj(); + if (pXYCurve != nullptr) + { + LoopLimit = pXYCurve->get_FNumPoints(); + pDouble = *(double**)myPtr; + for (i = 1; i <= LoopLimit; i++) + { + pXYCurve->Set_YValue(k, *pDouble); + pDouble++; + k++; + } + } + else + { + DoSimpleMsg("No active XYCurve Object found.", 51015); + } + } + *mySize = k - 1; + break; + default: + *myType = 4; //String + myStrArray.resize(0); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + break; + } +} + +//************************Structure type properties******************************* + +int __stdcall CtrlQueueI(int mode, int arg) +{ + int Result = 0; + + switch (mode) + { + case 0: // CtrlQueue.ClearQueue + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + ActiveCircuit[ActiveActor]->ControlQueue.Clear(); + } + break; + case 1: // CtrlQueue.Delete + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + ActiveCircuit[ActiveActor]->ControlQueue.Delete(arg, ActiveActor); + } + break; + case 2: // CtrlQueue.NumActions + { + Result = COMControlProxyObj->ActionList.size(); + } + break; + case 3: // CtrlQueue.Action + { + auto with0 = COMControlProxyObj; + if (arg < with0->ActionList.size()) + ActiveAction = (pAction) with0->ActionList[arg - 1]; + } + break; + case 4: // CtrlQueue.ActionCode + { + if (ASSIGNED(ActiveAction)) + Result = ActiveAction->ActionCode; + } + break; + case 5: // CtrlQueue.DeviceHandle + { + if (ASSIGNED(ActiveAction)) + Result = ActiveAction->DeviceHandle; + } + break; + case 6: // CtrlQueue.Show + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + ActiveCircuit[ActiveActor]->ControlQueue.ShowQueue(DSSDirectory + "COMProxy_ControlQueue.CSV"); + } + break; + case 7: // CtrlQueue.ClearActions + { + COMControlProxyObj->ClearActionList(); + } + break; + case 8: // CtrlQueue.PopAction + { + Result = COMControlProxyObj->ActionList.size(); + COMControlProxyObj->PopAction(); + } + break; + case 9: // CtrlQueue.Get_QueueSize + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + Result = ActiveCircuit[ActiveActor]->ControlQueue.Get_QueueSize(); + } + break; + case 10: // CtrlQueue.DoAllQueue + { + if (ASSIGNED(ActiveCircuit[ActiveActor])) + ActiveCircuit[ActiveActor]->ControlQueue.DoAllActions(ActiveActor); + } + break; + default: + Result = -1; + } + return Result; +} + +void __stdcall CtrlQueueV(int mode, uintptr_t* myPtr, int* myType, int* mySize) +{ + double ActionCode = 0.0, + Hour = 0.0, + DeviceHandle = 0.0, + Seconds = 0.0; + double* pDbl = nullptr; + int i = 0, + Qsize = 0; + + switch (mode) + { + case 0: // CtrlQueue.ClearQueue + { + *myType = 4; // String + myStrArray.clear(); + Qsize = ActiveCircuit[ActiveActor]->ControlQueue.Get_QueueSize(); + + if (Qsize > 0) + { + WriteStr2Array("Handle, Hour, Sec, ActionCode, ProxyDevRef, Device"); + WriteStr2Array(Char0()); + for (i = 0; i < Qsize; i++) + { + WriteStr2Array(ActiveCircuit[ActiveActor]->ControlQueue.QueueItem(i)); + WriteStr2Array(Char0()); + } + } + else + { + WriteStr2Array("No events"); + WriteStr2Array(Char0()); + } + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + break; + case 1: // CtrlQueue.Push + { + *myType = 2; // Double + myStrArray.clear(); + pDbl = (double*)myPtr; + Qsize = 0; + if (ASSIGNED(ActiveCircuit[ActiveActor])) + { + try + { + Hour = *pDbl; + pDbl++; + Seconds = *pDbl; + pDbl++; + ActionCode = *pDbl; + pDbl++; + DeviceHandle = *pDbl; + Qsize = ActiveCircuit[ActiveActor]->ControlQueue.Push(trunc(Hour), Seconds, trunc(ActionCode), trunc(DeviceHandle), COMControlProxyObj, ActiveActor); + } + catch (...) + { + Qsize = -10001; // something went wrong + } + } + *mySize = Qsize; + } + break; + default: + { + *myType = 4; // String + myStrArray.clear(); + WriteStr2Array("Error, parameter not recognized"); + WriteStr2Array(Char0()); + *myPtr = (uintptr_t)(void*)&(myStrArray[0]); + *mySize = myStrArray.size(); + } + } +} + +char* __stdcall DSSProperties(int mode, char* arg) +{ + string Result = ""; + + switch (mode) + { + case 0: // DSSproperties.Name + { + FPropIndex = StrToInt(arg) - 1; + if (ASSIGNED(ActiveCircuit[ActiveActor]) && (FPropIndex >= 0)) + { + auto with0 = ((TDSSObject*)ActiveDSSObject[ActiveActor])->ParentClass; + if (FPropIndex < with0->NumProperties) + Result = with0->PropertyName[FPropIndex]; + } + } + break; + case 1: // DSSproperties.Description + { + FPropIndex = StrToInt(arg) - 1; + if (ASSIGNED(ActiveCircuit[ActiveActor]) && (FPropIndex >= 0)) + { + auto with0 = ((TDSSObject*)ActiveDSSObject[ActiveActor])->ParentClass; + if (FPropIndex < with0->NumProperties) + Result = with0->PropertyHelp[FPropIndex]; + } + } + break; + case 2: // DSSproperties.Value - read + { + FPropIndex = StrToInt(arg) - 1; + if (ASSIGNED(ActiveCircuit[ActiveActor]) && (FPropIndex >= 0)) + { + auto with0 = (TDSSObject*)ActiveDSSObject[ActiveActor]; + auto with1 = with0->ParentClass; + + if (FPropIndex < with1->NumProperties) + Result = with0->GetPropertyValue(with1->PropertyIdxMap[FPropIndex]); + } + } + break; + case 3: // DSSproperties.Value - write + { + if (ASSIGNED(ActiveCircuit[ActiveActor]) && (FPropIndex >= 0)) + { + auto with0 = (TDSSObject*)ActiveDSSObject[ActiveActor]; + auto with1 = with0->ParentClass; + + if (FPropIndex < with1->NumProperties) + { + DSSExecutive[ActiveActor]->Set_Command("Edit " + with1->Class_Name + "." + with0->get_Name() + " " + + with1->PropertyName[FPropIndex] + "=" + string(arg)); + Result = with0->GetPropertyValue(with1->PropertyIdxMap[FPropIndex]); + } + } + } + break; + default: + Result = ""; + break; + } + + char* presult = new char[Result.size() + 1]; + strcpy(presult, Result.c_str()); + return presult; +} + +// Call this first +// Save a copy of these in permanent heap memory here before returning +int InitAndGetYparams(uintptr_t* hY, unsignedint* nBus, unsignedint* nNZ) +{ + int result = 0; // indicates error + if (ActiveCircuit[ActiveActor] == nullptr) return result; + + Yhandle = ActiveCircuit[ActiveActor]->Solution->hY; + if (Yhandle == nullptr) + { + DoSimpleMsg("Y Matrix not Built.", 222); + return result; + } + + *hY = (uintptr_t) Yhandle; + + FactorSparseMatrix(Yhandle); + GetNNZ(Yhandle, &NumNZ); + GetSize(Yhandle, &NumBuses); + + *nBus = NumBuses; + *nNZ = NumNZ; + + result = 1; + return result; +} + +/* Returns Pointers to column and row and matrix values */ +/* Call InitAndGetYparams first to factor the sparse matrix ... */ +void GetCompressedYMatrix(uintptr_t hY, unsignedint nBus, unsignedint nNz, int** ColPtr, int** RowIdx, complex** cVals) +{ + // Allocate space on the heap and put the values there + ReallocMem(YColumns, sizeof(int) * (nBus + 1)); + ReallocMem(YRows, sizeof(int) * nNz); + ReallocMem(YValues, sizeof(YValues[0]) * nNz); + // Fill in the memory + GetCompressedMatrix((klusparseset_t) hY, nBus + 1, nNz, (unsignedint *) YColumns, (unsignedint*) YRows, YValues); + + // Set the pointers in the calling program to the heap variables + *ColPtr = YColumns; + *RowIdx = YRows; + *cVals = YValues; +} + +int SystemYChanged(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: if (ActiveCircuit[ActiveActor]->Solution->SystemYChanged) result = 1; // Read + break; + case 1: { // Write + if (arg == 1) ActiveCircuit[ActiveActor]->Solution->SystemYChanged = true; + else ActiveCircuit[ActiveActor]->Solution->SystemYChanged = false; + } + break; + } + return result; +} + +int SolveSystem(complex** NodeV) +{ + return ActiveCircuit[ActiveActor]->Solution->SolveSystem(*NodeV, ActiveActor); +} + +int UseAuxCurrents(int mode, int arg) +{ + int result = 0; + switch (mode) + { + case 0: if (ActiveCircuit[ActiveActor]->Solution->UseAuxCurrents) result = 1; // Read + break; + case 1: { // Write + if (arg == 1) ActiveCircuit[ActiveActor]->Solution->UseAuxCurrents = true; + else ActiveCircuit[ActiveActor]->Solution->UseAuxCurrents = false; + } + break; + } + return result; +} + +void AddInAuxCurrents(int SType) +{ + ActiveCircuit[ActiveActor]->Solution->AddInAuxCurrents(SType, ActiveActor); +} + +void BuildYMatrixD(int BuildOps, int AllocateVI) +{ + bool AllocateV = false; + if (AllocateVI == 1) AllocateV = true; + BuildYMatrix(BuildOps, AllocateV, ActiveActor); +} + +void GetPCInjCurr(void) +{ + if (ActiveCircuit[ActiveActor] != nullptr) + ActiveCircuit[ActiveActor]->Solution->GetPCInjCurr(ActiveActor); +} + +void GetSourceInjCurrents(void) +{ + if (ActiveCircuit[ActiveActor] != nullptr) + ActiveCircuit[ActiveActor]->Solution->GetSourceInjCurrents(ActiveActor); +} + +void ZeroInjCurr(void) +{ + if (ActiveCircuit[ActiveActor] != nullptr) + ActiveCircuit[ActiveActor]->Solution->ZeroInjCurr(ActiveActor); +} + +void getVpointer(complex** VvectorPtr) +{ + *VvectorPtr = ActiveCircuit[ActiveActor]->Solution->NodeV.data(); +} + +void getIpointer(complex** IvectorPtr) +{ + *IvectorPtr = ActiveCircuit[ActiveActor]->Solution->Currents.data(); +} diff --git a/OpenDSSC/DLL/OpenDSSCDLL.h b/OpenDSSC/DLL/OpenDSSCDLL.h new file mode 100644 index 0000000..2330358 --- /dev/null +++ b/OpenDSSC/DLL/OpenDSSCDLL.h @@ -0,0 +1,336 @@ +// OpenDSSX.h : Include file for standard system include files, +// or project specific include files. + + +#include +#include +#include "ControlElem.h" + +// TODO: Reference additional headers your program requires here. +using namespace std; +#ifdef WIN32 +#define DSS_DLL __declspec(dllexport) +#else +#define DSS_DLL +#endif + +struct TAction +{ + int ActionCode, + DeviceHandle; +}; + +typedef TAction* pAction; + + +class TCOMControlProxyObj : public TControlElem +{ +public: + TList ActionList; + void ClearActionList(); + bool PopAction(); + + TCOMControlProxyObj(DSSClass::TDSSClass* ParClass, const String COMProxyName); + void DopendingAction(const int Code, int ProxyHdl, int ActorID); + void Reset(int ActorID); +}; + +#ifdef __cplusplus +extern "C" { +#endif + // DSS interface + DSS_DLL int __stdcall DSSI(int mode, int arg); + DSS_DLL char* __stdcall DSSS(int mode, char* arg); + DSS_DLL void __stdcall DSSV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall LinesI(int mode, int arg); + DSS_DLL double __stdcall LinesF(int mode, double arg); + DSS_DLL char* __stdcall LinesS(int mode, char* arg); + DSS_DLL void __stdcall LinesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL char* __stdcall DSSPut_Command(char* myCmd); + DSS_DLL int __stdcall DSSLoads(int mode, int arg); + DSS_DLL double __stdcall DSSLoadsF(int mode, double arg); + DSS_DLL char* __stdcall DSSLoadsS(int mode, char* arg); + DSS_DLL void __stdcall DSSLoadsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall CapacitorsI(int mode, int arg); + DSS_DLL double __stdcall CapacitorsF(int mode, double arg); + DSS_DLL const char* __stdcall CapacitorsS(int mode, const char* arg); + DSS_DLL void __stdcall CapacitorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ActiveClassI(int mode, int arg); + DSS_DLL char* __stdcall ActiveClassS(int mode, char* arg); + DSS_DLL void __stdcall ActiveClassV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall BUSI(int mode, int arg); + DSS_DLL double __stdcall BUSF(int mode, double arg); + DSS_DLL char* __stdcall BUSS(int mode, char* arg); + DSS_DLL void __stdcall BUSV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall CapControlsI(int mode, int arg); + DSS_DLL double __stdcall CapControlsF(int mode, double arg); + DSS_DLL char* __stdcall CapControlsS(int mode, char* arg); + DSS_DLL void __stdcall CapControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall CircuitI(int mode, int arg); + DSS_DLL double __stdcall CircuitF(int mode, double arg1, double arg2); + DSS_DLL char* __stdcall CircuitS(int mode, char* arg); + DSS_DLL void __stdcall CircuitV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall CktElementI(int mode, int arg); + DSS_DLL double __stdcall CktElementF(int mode, double arg); + DSS_DLL char* __stdcall CktElementS(int mode, char* arg); + DSS_DLL void __stdcall CktElementV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL double __stdcall CmathLibF(int mode, double arg1, double arg2); + DSS_DLL void __stdcall CmathLibV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall GeneratorsI(int mode, int arg); + DSS_DLL double __stdcall GeneratorsF(int mode, double arg); + DSS_DLL char* __stdcall GeneratorsS(int mode, char* arg); + DSS_DLL void __stdcall GeneratorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall DSSElementI(int mode, int arg); + DSS_DLL char* __stdcall DSSElementS(int mode, char* arg); + DSS_DLL void __stdcall DSSElementV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall DSSProgressI(int mode, int arg); + DSS_DLL char* __stdcall DSSProgressS(int mode, char* arg); + + //************************************************************************************************** + + DSS_DLL int __stdcall DSSExecutiveI(int mode, int arg); + DSS_DLL char* __stdcall DSSExecutiveS(int mode, char* arg); + + //************************************************************************************************** + + DSS_DLL int __cdecl ErrorCode(); + DSS_DLL char* __cdecl ErrorDesc(); + + //************************************************************************************************** + + DSS_DLL int __stdcall FusesI(int mode, int arg); + DSS_DLL double __stdcall FusesF(int mode, double arg); + DSS_DLL char* __stdcall FusesS(int mode, char* arg); + DSS_DLL void __stdcall FusesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall GICSourcesI(int mode, int arg); + DSS_DLL double __stdcall GICSourcesF(int mode, double arg); + DSS_DLL char* __stdcall GICSourcesS(int mode, char* arg); + DSS_DLL void __stdcall GICSourcesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall IsourceI(int mode, int arg); + DSS_DLL double __stdcall IsourceF(int mode, double arg); + DSS_DLL char* __stdcall IsourceS(int mode, char* arg); + DSS_DLL void __stdcall IsourceV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall LineCodesI(int mode, int arg); + DSS_DLL double __stdcall LineCodesF(int mode, double arg); + DSS_DLL char* __stdcall LineCodesS(int mode, char* arg); + DSS_DLL void __stdcall LineCodesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall LoadShapeI(int mode, int arg); + DSS_DLL double __stdcall LoadShapeF(int mode, double arg); + DSS_DLL char* __stdcall LoadShapeS(int mode, char* arg); + DSS_DLL void __stdcall LoadShapeV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall MetersI(int mode, int arg); + DSS_DLL double __stdcall MetersF(int mode, double arg); + DSS_DLL char* __stdcall MetersS(int mode, char* arg); + DSS_DLL void __stdcall MetersV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall MonitorsI(int mode, int arg); + DSS_DLL char* __stdcall MonitorsS(int mode, char* arg); + DSS_DLL void __stdcall MonitorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ParallelI(int mode, int arg); + DSS_DLL void __stdcall ParallelV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ParserI(int mode, int arg); + DSS_DLL double __stdcall ParserF(int mode, double arg); + DSS_DLL char* __stdcall ParserS(int mode, char* arg); + DSS_DLL void __stdcall ParserV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall PDElementsI(int mode, int arg); + DSS_DLL double __stdcall PDElementsF(int mode, double arg); + DSS_DLL char* __stdcall PDElementsS(int mode, char* arg); + + //************************************************************************************************** + + DSS_DLL int __stdcall PVsystemsI(int mode, int arg); + DSS_DLL double __stdcall PVsystemsF(int mode, double arg); + DSS_DLL char* __stdcall PVsystemsS(int mode, char* arg); + DSS_DLL void __stdcall PVsystemsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ReactorsI(int mode, int arg); + DSS_DLL double __stdcall ReactorsF(int mode, double arg); + DSS_DLL char* __stdcall ReactorsS(int mode, char* arg); + DSS_DLL void __stdcall ReactorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ReclosersI(int mode, int arg); + DSS_DLL double __stdcall ReclosersF(int mode, double arg); + DSS_DLL char* __stdcall ReclosersS(int mode, char* arg); + DSS_DLL void __stdcall ReclosersV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall ReduceCktI(int mode, int arg); + DSS_DLL double __stdcall ReduceCktF(int mode, double arg); + DSS_DLL char* __stdcall ReduceCktS(int mode, char* arg); + + //************************************************************************************************** + + DSS_DLL int __stdcall RegControlsI(int mode, int arg); + DSS_DLL double __stdcall RegControlsF(int mode, double arg); + DSS_DLL char* __stdcall RegControlsS(int mode, char* arg); + DSS_DLL void __stdcall RegControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall RelaysI(int mode, int arg); + DSS_DLL char* __stdcall RelaysS(int mode, char* arg); + DSS_DLL void __stdcall RelaysV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall SensorsI(int mode, int arg); + DSS_DLL double __stdcall SensorsF(int mode, double arg); + DSS_DLL char* __stdcall SensorsS(int mode, char* arg); + DSS_DLL void __stdcall SensorsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall SettingsI(int mode, int arg); + DSS_DLL double __stdcall SettingsF(int mode, double arg); + DSS_DLL char* __stdcall SettingsS(int mode, char* arg); + DSS_DLL void __stdcall SettingsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall SolutionI(int mode, int arg); + DSS_DLL double __stdcall SolutionF(int mode, double arg); + DSS_DLL char* __stdcall SolutionS(int mode, char* arg); + DSS_DLL void __stdcall SolutionV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall StoragesI(int mode, int arg); + DSS_DLL double __stdcall StoragesF(int mode, double arg); + DSS_DLL char* __stdcall StoragesS(int mode, char* arg); + DSS_DLL void __stdcall StoragesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall SwtControlsI(int mode, int arg); + DSS_DLL double __stdcall SwtControlsF(int mode, double arg); + DSS_DLL char* __stdcall SwtControlsS(int mode, char* arg); + DSS_DLL void __stdcall SwtControlsV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall TopologyI(int mode, int arg); + DSS_DLL char* __stdcall TopologyS(int mode, char* arg); + DSS_DLL void __stdcall TopologyV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall TransformersI(int mode, int arg); + DSS_DLL double __stdcall TransformersF(int mode, double arg); + DSS_DLL char* __stdcall TransformersS(int mode, char* arg); + DSS_DLL void __stdcall TransformersV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall VsourcesI(int mode, int arg); + DSS_DLL double __stdcall VsourcesF(int mode, double arg); + DSS_DLL char* __stdcall VsourcesS(int mode, char* arg); + DSS_DLL void __stdcall VsourcesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall WindGensI(int mode, int arg); + DSS_DLL double __stdcall WindGensF(int mode, double arg); + DSS_DLL char* __stdcall WindGensS(int mode, char* arg); + DSS_DLL void __stdcall WindGensV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall XYCurvesI(int mode, int arg); + DSS_DLL double __stdcall XYCurvesF(int mode, double arg); + DSS_DLL char* __stdcall XYCurvesS(int mode, char* arg); + DSS_DLL void __stdcall XYCurvesV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL int __stdcall CtrlQueueI(int mode, int arg); + DSS_DLL void __stdcall CtrlQueueV(int mode, uintptr_t* myPtr, int* myType, int* mySize); + + //************************************************************************************************** + + DSS_DLL char* __stdcall DSSProperties(int mode, char* arg); + + //************************************************************************************************** + + DSS_DLL int InitAndGetYparams(uintptr_t* hY, unsignedint* nBus, unsignedint* nNZ); + DSS_DLL void GetCompressedYMatrix(uintptr_t hY, unsignedint nBus, unsignedint nNz, int** ColPtr, int** RowIdx, complex** cVals); + DSS_DLL int SystemYChanged(int mode, int arg); + DSS_DLL int UseAuxCurrents(int mode, int arg); + DSS_DLL void AddInAuxCurrents(int SType); + DSS_DLL void BuildYMatrixD(int BuildOps, int AllocateVI); + DSS_DLL void GetPCInjCurr(void); + DSS_DLL void GetSourceInjCurrents(void); + DSS_DLL void ZeroInjCurr(void); + DSS_DLL int SolveSystem(complex** NodeV); + DSS_DLL void getIpointer(complex** IvectorPtr); + DSS_DLL void getVpointer(complex** VvectorPtr); + +#ifdef __cplusplus +} +#endif diff --git a/OpenDSSC/Docs/OpenDSS-X_Build_Guide_v13.pdf b/OpenDSSC/Docs/OpenDSS-X_Build_Guide_v13.pdf new file mode 100644 index 0000000..437bb8b Binary files /dev/null and b/OpenDSSC/Docs/OpenDSS-X_Build_Guide_v13.pdf differ diff --git a/OpenDSSC/Executive/ConnectOptions.cpp b/OpenDSSC/Executive/ConnectOptions.cpp new file mode 100644 index 0000000..d2c7d93 --- /dev/null +++ b/OpenDSSC/Executive/ConnectOptions.cpp @@ -0,0 +1,118 @@ + + +#pragma hdrstop + +#include "ConnectOptions.h" +//#include "TCP_IP.h" +#include "DSSGlobals.h" +#include "ParserDel.h" +#include "Utilities.h" + +using namespace std; +using namespace Command; +using namespace DSSGlobals; +using namespace ParserDel; +using namespace System; +using namespace Utilities; + +namespace ConnectOptions +{ + + +String* ConnectOption; +String* ConnectHelp; +TCommandList* ConnectCommands = nullptr; + +void DefineOptions() +{ + ConnectOption = new String[2]; + ConnectHelp = new String[2]; + ConnectOption[1 - 1] = "address"; + ConnectOption[2 - 1] = "port"; + ConnectHelp[1 - 1] = "Address is a string containing the IP address of a particular system with which OpenDSS should form a connection"; + ConnectHelp[2 - 1] = String("Port is the ID of the desired server connection:") + CRLF + + "47625 = OpenDSS Viewer"; +} + +int DoConnectCmd() +{ + int result = 0; + result = 0; + +// If NoFormsAllowed Then Begin Result :=1; Exit; End; + /* + if (!ASSIGNED(DSSConnectObj)) + DSSConnectObj = TDSSConnect.Create; + DSSConnectObj.SetDefaults; + with DSSConnectObj do + { + auto& with0 = DSSConnectObj; + Connect; + } + */ + return result; +} +//Var +// ParamName, Param:String; +// ParamPointer, i:Integer; + +int DoDisConnectCmd() +{ + int result = 0; + result = 0; + +// If NoFormsAllowed Then Begin Result :=1; Exit; End; + /* + if (ASSIGNED(DSSConnectObj)) + { + # with DSSConnectObj do + { + auto& with0 = DSSConnectObj; + Disconnect; + } + } + */ + return result; +} +//Var +// ParamName, Param:String; +// ParamPointer, i:Integer; + +void DisposeStrings() +{ + delete[] ConnectOption; + delete[] ConnectHelp; +} + + +void ConnectOptions_initialization() +{ + DefineOptions(); + ConnectCommands = new TCommandList(ConnectHelp, 2); + ConnectCommands->set_AbbrevAllowed(true); +} + +void ConnectOptions_finalization() +{ + DoDisConnectCmd(); + DisposeStrings(); + delete ConnectCommands; +} + + class ConnectOptions_unit + { + public: + ConnectOptions_unit() + { + //AssertSystemInitialization(); + ConnectOptions_initialization(); + } + ~ ConnectOptions_unit(){ConnectOptions_finalization(); } + }; + ConnectOptions_unit _ConnectOptions_unit; + +} // namespace ConnectOptions + + + + diff --git a/OpenDSSC/Executive/ConnectOptions.h b/OpenDSSC/Executive/ConnectOptions.h new file mode 100644 index 0000000..cdf04db --- /dev/null +++ b/OpenDSSC/Executive/ConnectOptions.h @@ -0,0 +1,38 @@ +#ifndef ConnectOptionsH +#define ConnectOptionsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +namespace ConnectOptions +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2017, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +const int NumConnectOptions = 2; +int DoConnectCmd(); +int DoDisConnectCmd(); +extern String* ConnectOption; +extern String* ConnectHelp; +extern Command::TCommandList* ConnectCommands; + + +} // namespace ConnectOptions + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ConnectOptions; +#endif + +#endif // ConnectOptionsH + + + + diff --git a/OpenDSSC/Executive/ExecCommands.cpp b/OpenDSSC/Executive/ExecCommands.cpp new file mode 100644 index 0000000..eefb3f9 --- /dev/null +++ b/OpenDSSC/Executive/ExecCommands.cpp @@ -0,0 +1,1350 @@ + + +#pragma hdrstop + +#include "ExecCommands.h" +#include "dirsep.h" + +int ReadEfieldHDF(int a); +int ReadEfieldHDF(int a) { + return a; +}; + +using namespace std; + +namespace ExecCommands +{ + TCommandList CommandList; + String dummy; + String LastCmdLine; + String RedirFile; + string* ExecCommand; + string* CommandHelp; + + void DefineCommands() + { + ExecCommand = new std::string[NumExecCommands]; + CommandHelp = new std::string[NumExecCommands]; + /*Main executive commands*/ + ExecCommand[1 - 1] = "New"; + ExecCommand[2 - 1] = "Edit"; + ExecCommand[3 - 1] = "More"; + ExecCommand[4 - 1] = "M"; + ExecCommand[5 - 1] = "~"; + ExecCommand[6 - 1] = "Select"; + ExecCommand[7 - 1] = "Save"; + ExecCommand[8 - 1] = "Show"; + ExecCommand[9 - 1] = "Solve"; + ExecCommand[10 - 1] = "Enable"; + ExecCommand[11 - 1] = "Disable"; + ExecCommand[12 - 1] = "Plot"; + ExecCommand[13 - 1] = "Reset"; + ExecCommand[14 - 1] = "Compile"; + ExecCommand[15 - 1] = "Set"; // Set DSS Options + ExecCommand[16 - 1] = "Dump"; // Debug dump + ExecCommand[17 - 1] = "Open"; // Open a device terminal conductor + ExecCommand[18 - 1] = "Close"; // Close a device terminal conductor + ExecCommand[19 - 1] = "//"; // Comment + ExecCommand[20 - 1] = "Redirect"; + ExecCommand[21 - 1] = "Help"; + ExecCommand[22 - 1] = "Quit"; + ExecCommand[23 - 1] = "?"; // Property Value inquiry + ExecCommand[24 - 1] = "Next"; + ExecCommand[25 - 1] = "Panel"; + ExecCommand[26 - 1] = "Sample"; + ExecCommand[27 - 1] = "Clear"; + ExecCommand[28 - 1] = "About"; + ExecCommand[29 - 1] = "Calcvoltagebases"; // Computes voltage bases + ExecCommand[30 - 1] = "SetkVBase"; // Set kV Base at a Bus + ExecCommand[31 - 1] = "BuildY"; // forces Rebuild of Y matrix right now + ExecCommand[32 - 1] = "Get"; // returns values set WITH Set command + ExecCommand[33 - 1] = "Init"; + ExecCommand[34 - 1] = "Export"; + ExecCommand[35 - 1] = "Fileedit"; + ExecCommand[36 - 1] = "Voltages"; + ExecCommand[37 - 1] = "Currents"; + ExecCommand[38 - 1] = "Powers"; + ExecCommand[39 - 1] = "Seqvoltages"; + ExecCommand[40 - 1] = "Seqcurrents"; + ExecCommand[41 - 1] = "Seqpowers"; + ExecCommand[42 - 1] = "Losses"; + ExecCommand[43 - 1] = "Phaselosses"; + ExecCommand[44 - 1] = "Cktlosses"; + ExecCommand[45 - 1] = "Allocateloads"; + ExecCommand[46 - 1] = "Formedit"; + ExecCommand[47 - 1] = "Totals"; // Total all energymeters + ExecCommand[48 - 1] = "Capacity"; // Find upper kW limit of system for present year + ExecCommand[49 - 1] = "Classes"; // List of intrinsic classes + ExecCommand[50 - 1] = "Userclasses"; // List of user-defined classes + ExecCommand[51 - 1] = "Zsc"; + ExecCommand[52 - 1] = "Zsc10"; + ExecCommand[53 - 1] = "ZscRefresh"; + ExecCommand[54 - 1] = "Ysc"; + ExecCommand[55 - 1] = "puvoltages"; + ExecCommand[56 - 1] = "VarValues"; + ExecCommand[57 - 1] = "Varnames"; + ExecCommand[58 - 1] = "Buscoords"; + ExecCommand[59 - 1] = "MakeBusList"; + ExecCommand[60 - 1] = "MakePosSeq"; + ExecCommand[61 - 1] = "Reduce"; + ExecCommand[62 - 1] = "Interpolate"; + ExecCommand[63 - 1] = "AlignFile"; + ExecCommand[64 - 1] = "TOP"; + ExecCommand[65 - 1] = "Rotate"; + ExecCommand[66 - 1] = "Vdiff"; + ExecCommand[67 - 1] = "Summary"; + ExecCommand[68 - 1] = "Distribute"; + ExecCommand[69 - 1] = "DI_plot"; + ExecCommand[70 - 1] = "Comparecases"; + ExecCommand[71 - 1] = "YearlyCurves"; + ExecCommand[72 - 1] = "CD"; + ExecCommand[73 - 1] = "Visualize"; + ExecCommand[74 - 1] = "CloseDI"; + ExecCommand[75 - 1] = "DOScmd"; + ExecCommand[76 - 1] = "Estimate"; + ExecCommand[77 - 1] = "Reconductor"; + ExecCommand[78 - 1] = "_InitSnap"; + ExecCommand[79 - 1] = "_SolveNoControl"; + ExecCommand[80 - 1] = "_SampleControls"; + ExecCommand[81 - 1] = "_DoControlActions"; + ExecCommand[82 - 1] = "_ShowControlQueue"; + ExecCommand[83 - 1] = "_SolveDirect"; + ExecCommand[84 - 1] = "_SolvePFlow"; + ExecCommand[85 - 1] = "AddBusMarker"; + ExecCommand[86 - 1] = "Uuids"; + ExecCommand[87 - 1] = "SetLoadAndGenKV"; + ExecCommand[88 - 1] = "CvrtLoadshapes"; + ExecCommand[89 - 1] = "NodeDiff"; + ExecCommand[90 - 1] = "Rephase"; + ExecCommand[91 - 1] = "SetBusXY"; + ExecCommand[92 - 1] = "UpdateStorage"; + ExecCommand[93 - 1] = "Obfuscate"; + ExecCommand[94 - 1] = "LatLongCoords"; + ExecCommand[95 - 1] = "BatchEdit"; + ExecCommand[96 - 1] = "Pstcalc"; + ExecCommand[97 - 1] = "Variable"; + ExecCommand[98 - 1] = "ReprocessBuses"; + ExecCommand[99 - 1] = "ClearBusMarkers"; + ExecCommand[100 - 1] = "RelCalc"; + ExecCommand[101 - 1] = "var"; + ExecCommand[102 - 1] = "Cleanup"; + ExecCommand[103 - 1] = "FinishTimeStep"; + ExecCommand[104 - 1] = "NodeList"; + ExecCommand[105 - 1] = "NewActor"; + ExecCommand[106 - 1] = "ClearAll"; + ExecCommand[107 - 1] = "Wait"; + ExecCommand[108 - 1] = "SolveAll"; + ExecCommand[109 - 1] = "CalcIncMatrix"; + ExecCommand[110 - 1] = "CalcIncMatrix_O"; + ExecCommand[111 - 1] = "Tear_Circuit"; + ExecCommand[112 - 1] = "Connect"; + ExecCommand[113 - 1] = "Disconnect"; + ExecCommand[114 - 1] = "Refine_BusLevels"; + ExecCommand[115 - 1] = "Remove"; + ExecCommand[116 - 1] = "Abort"; + ExecCommand[117 - 1] = "CalcLaplacian"; + ExecCommand[118 - 1] = "Clone"; + ExecCommand[119 - 1] = "FNCSPublish"; + // ExecCommand[119] := 'UpdateStorage2'; + ExecCommand[120 - 1] = "ExportOverloads"; + ExecCommand[121 - 1] = "ExportVViolations"; + ExecCommand[122 - 1] = "Zsc012"; + ExecCommand[123 - 1] = "AggregateProfiles"; + ExecCommand[124 - 1] = "AllPCEatBus"; + ExecCommand[125 - 1] = "AllPDEatBus"; + ExecCommand[126 - 1] = "TotalPowers"; + ExecCommand[127 - 1] = "COMHelp"; + ExecCommand[128 - 1] = "GIS"; + ExecCommand[129 - 1] = "GISCoords"; + // Start list of INDUCES commands + ExecCommand[130 - 1] = "ReadEfieldHDF"; + + // Ends list of INDUCES commands + + + + // Command help descriptions + CommandHelp[1 - 1] = String("Create a new object within the DSS. Object becomes the " "active object") + CRLF + + "Example: New Line.line1 ..."; + CommandHelp[2 - 1] = String("Edit an object. The object is selected and it then becomes the active object.") + CRLF + + CRLF + + "Note that Edit is the default command. You many change a property value simply by " + + "giving the full property name and the new value, for example:" + + CRLF + + CRLF + + "line.line1.r1=.04" + + CRLF + + "vsource.source.kvll=230"; + CommandHelp[3 - 1] = "Continuation of editing on the active object."; + CommandHelp[4 - 1] = "Continuation of editing on the active object. An abbreviation for More"; + CommandHelp[5 - 1] = String("Continuation of editing on the active object. An abbreviation.") + CRLF + + CRLF + + "Example:" + + CRLF + + "New Line.Line1 Bus1=aaa bus2=bbb" + + CRLF + + "~ R1=.058" + + CRLF + + "~ X1=.1121"; + CommandHelp[6 - 1] = String("Selects an element and makes it the active element. You can also specify the " "active terminal (default = 1).") + CRLF + + CRLF + + "Syntax:" + + CRLF + + "Select [-1]elementname [terminal= - 1]terminalnumber " + + CRLF + + CRLF + + "Example:" + + CRLF + + "Select Line.Line1 " + + CRLF + + "~ R1=.1" + + CRLF + + "(continue editing)" + + CRLF + + CRLF + + "Select Line.Line1 2 " + + CRLF + + "Voltages (returns voltages at terminal 2 in Result)"; + CommandHelp[7 - 1] = String("{Save [class= - 1]{Meters | Circuit | Voltages | (classname)} [file= - 1]filename [dir= - 1]directory ") + CRLF + + CRLF + + "Default class = Meters, which saves the present values in both monitors and energy meters in the active circuit. " + + CRLF + + CRLF + + "\"Save Circuit\" saves the present enabled circuit elements to the specified subdirectory in standard DSS form " + + "with a Master.txt file and separate files for each class of data. " + + CRLF + + CRLF + + "If Dir= not specified a unique name based on the circuit name is created automatically. " + + CRLF + + CRLF + + "If Dir= is specified, any existing files are overwritten. " + + CRLF + + CRLF + + "\"Save Voltages\" saves the present solution in a simple CSV format in a file called DSS_SavedVoltages. " + + "Used for VDIFF command." + + CRLF + + CRLF + + "Any class can be saved to a file. If no filename specified, the classname is used."; + CommandHelp[8 - 1] = String("Writes selected results to a text file and brings " "up the default text editor (see Set Editor=....) with the file for you to browse.") + CRLF + + CRLF + + "See separate help on Show command. " + + CRLF + + CRLF + + "Default is \"show voltages LN Seq\". "; + CommandHelp[9 - 1] = "Perform the solution of the present solution mode. You can set any option " + "that you can set with the Set command (see Set). " + "The Solve command is virtually synonymous with the Set command except that " + "a solution is performed after the options are processed."; + CommandHelp[10 - 1] = String("Enables a circuit element or entire class. Example:") + CRLF + + "Enable load.loadxxx" + + CRLF + + "Enable generator.* (enables all generators)"; + CommandHelp[11 - 1] = String("Disables a circuit element or entire class. Example:") + CRLF + + "Disable load.loadxxx" + + CRLF + + "Disable generator.* (Disables all generators)" + + CRLF + + CRLF + + "The item remains defined, but is not included in the solution."; + CommandHelp[12 - 1] = "Plots circuits and results in a variety of manners. See separate Plot command help."; + CommandHelp[13 - 1] = "{MOnitors | MEters | Faults | Controls | Eventlog | Keeplist |(no argument) } Resets all Monitors, Energymeters, etc. " + "If no argument specified, resets all options listed."; + CommandHelp[14 - 1] = String("Reads the designated file name containing DSS commands " "and processes them as if they were entered directly into the command line. " "The file is said to be \"compiled.\" " "Similar to \"redirect\" except changes the default directory to the path of the specified file.") + CRLF + + CRLF + + "Syntax:" + + CRLF + + "Compile filename"; + CommandHelp[15 - 1] = "Used to set various DSS solution modes and options. You may also set the options with the Solve command. " + "See \"Options\" for help."; + CommandHelp[16 - 1] = String("Display the properties of either a specific DSS object or a complete dump " "on all variables in the problem (Warning! Could be very large!)." " Brings up the default text editor with the text file written by this command.") + CRLF + + " Syntax: dump [-1] [debug - 1]" + + CRLF + + " Examples:" + + CRLF + + CRLF + + " Dump line.line1 " + + CRLF + + " Dump solution (dumps all solution vars) " + + CRLF + + " Dump commands (dumps all commands to a text file) " + + CRLF + + " Dump transformer.* (dumps all transformers)" + + CRLF + + " Dump ALLOCationfactors (load allocation factors)" + + CRLF + + " Dump Buslist (bus name hash list)" + + CRLF + + " Dump Devicelist (Device name hash list)" + + CRLF + + " Dump (dumps all objects in circuit) "; + //' Dump debug'; // Debug dump + CommandHelp[17 - 1] = String("Opens the specified terminal and conductor of the specified circuit element. " "If the conductor is not specified, all phase conductors of the terminal are opened.") + CRLF + + CRLF + + "Examples:" + + CRLF + + "Open line.line1 2 " + + CRLF + + "(opens all phases of terminal 2)" + + CRLF + + CRLF + + "Open line.line1 2 3" + + CRLF + + "(opens the 3rd conductor of terminal 2)"; + CommandHelp[18 - 1] = "Opposite of the Open command."; // Close a device terminal conductor + CommandHelp[19 - 1] = "Comment. Command line is ignored."; // Comment + CommandHelp[20 - 1] = String("Reads the designated file name containing DSS commands " "and processes them as if they were entered directly into the command line. " "Similar to \"Compile\", but leaves current directory where it was when Redirect command is invoked." "Can temporarily change to subdirectories if nested Redirect commands require.") + CRLF + + CRLF + + "ex: redirect filename"; + CommandHelp[21 - 1] = "Gives this display."; + CommandHelp[22 - 1] = "Shuts down DSS unless this is the DLL version. Then it does nothing; DLL parent is responsible for shutting down the DLL."; + CommandHelp[23 - 1] = String("Inquiry for property value. Result is put into GlobalReault and can be seen in the Result Window. " "Specify the full property name.") + CRLF + + CRLF + + "Example: ? Line.Line1.R1" + + CRLF + + CRLF + + "Note you can set this property merely by saying:" + + CRLF + + "Line.line1.r1=.058"; // Property Value inquiry + CommandHelp[24 - 1] = "{Year | Hour | t} Increments year, hour, or time as specified. If \"t\" is " + "specified, then increments time by current step size."; + CommandHelp[25 - 1] = "Displays main control panel window."; + CommandHelp[26 - 1] = "Force all monitors and meters to take a sample for the most recent solution. Keep in mind that meters will perform integration."; + CommandHelp[27 - 1] = "Clear all circuits currently in memory."; + CommandHelp[28 - 1] = "Display \"About Box\". (Result string set to Version string.)"; + CommandHelp[29 - 1] = "Calculates voltagebase for buses based on voltage bases defined " + "with Set voltagebases=... command."; + CommandHelp[30 - 1] = String("Command to explicitly set the base voltage for a bus. " "Bus must be previously defined. Parameters in order are:") + CRLF + + "Bus = {bus name}" + + CRLF + + "kVLL = (line-to-line base kV)" + + CRLF + + "kVLN = (line-to-neutral base kV)" + + CRLF + + CRLF + + "kV base is normally given in line-to-line kV (phase-phase). " + + "However, it may also be specified by line-to-neutral kV." + + CRLF + + "The following exampes are equivalent:" + + CRLF + + CRLF + + "setkvbase Bus=B9654 kVLL=13.2" + + CRLF + + "setkvbase B9654 13.2" + + CRLF + + "setkvbase B9654 kvln=7.62"; + CommandHelp[31 - 1] = "Forces rebuild of Y matrix upon next Solve command regardless of need. " + "The usual reason for doing this would be to reset the matrix for another " + "load level when using LoadModel=PowerFlow (the default) when the system is difficult to " + "solve when the load is far from its base value. Works by invalidating the Y primitive " + "matrices for all the Power Conversion elements."; + CommandHelp[32 - 1] = String("Returns DSS property values set using the Set command. " "Result is returne in Result property of the Text interface. ") + CRLF + + CRLF + + "VBA Example:" + + CRLF + + CRLF + + "DSSText.Command = \"Get mode\"" + + CRLF + + "Answer = DSSText.Result" + + CRLF + + CRLF + + "Multiple properties may be requested on one get. The results are appended " + + "and the individual values separated by commas." + + CRLF + + CRLF + + "See help on Set command for property names."; + CommandHelp[33 - 1] = "This command forces reinitialization of the solution for the next Solve command. " + "To minimize iterations, most solutions start with the previous solution unless there " + "has been a circuit change. However, if the previous solution is bad, it may be necessary " + "to re-initialize. In most cases, a re-initiallization results in a zero-load power flow " + "solution with only the series power delivery elements considered."; + CommandHelp[34 - 1] = String("Export various solution values to CSV (or XML) files for import into other programs. " "Creates a new file except for Energymeter and Generator objects, for which " "the results for each device of this class are APPENDED to the CSV File. You may export to " "a specific file by specifying the file name as the LAST parameter on the line. For example:") + CRLF + + CRLF + + " Export Voltage Myvoltagefile.CSV" + + CRLF + + CRLF + + "Otherwise, the default file names shown in the Export help are used. " + + "For Energymeter and Generator, specifying the switch \"/multiple\" (or /m) for the file name will cause " + + "a separate file to be written for each meter or generator. " + + "The default is for a single file containing all elements." + + CRLF + + CRLF + + "May be abreviated Export V, Export C, etc. Default is \"V\" for voltages." + + " If Set ShowExport=Yes, the output file will be automatically displayed in the default editor. " + + "Otherwise, you must open the file separately. The name appears in the Result window."; + CommandHelp[35 - 1] = String("Edit specified file in default text file editor (see Set Editor= option).") + CRLF + + CRLF + + "Fileedit EXP_METERS.CSV (brings up the meters export file)" + + CRLF + + CRLF + + "\"FileEdit\" may be abbreviated to a unique character string."; + CommandHelp[36 - 1] = "Returns the voltages for the ACTIVE BUS in the Result string. " + "For setting the active Bus, use the Select command or the Set Bus= option. " + "Returned as magnitude and angle quantities, comma separated, one set per conductor of the terminal."; + CommandHelp[37 - 1] = "Returns the currents for each conductor of ALL terminals of the active circuit element in the Result string. " + "(See Select command.)" + "Returned as comma-separated magnitude and angle."; + CommandHelp[38 - 1] = "Returns the powers (complex) going into each conductors of ALL terminals of the active circuit element in the Result string. " + "(See Select command.)" + "Returned as comma-separated kW and kvar."; + CommandHelp[39 - 1] = "Returns the sequence voltages at all terminals of the active circuit element (see Select command) in Result string. Returned as comma-separated magnitude only values." + "Order of returned values: 0, 1, 2 (for each terminal)."; + CommandHelp[40 - 1] = "Returns the sequence currents into all terminals of the active circuit element (see Select command) in Result string. Returned as comma-separated magnitude only values." + "Order of returned values: 0, 1, 2 (for each terminal)."; + CommandHelp[41 - 1] = "Returns the sequence powers into all terminals of the active circuit element (see Select command) in Result string. Returned as comma-separated kw, kvar pairs." + "Order of returned values: 0, 1, 2 (for each terminal)."; + CommandHelp[42 - 1] = "Returns the total losses for the active circuit element (see Select command) " + "in the Result string in kW, kvar."; + CommandHelp[43 - 1] = "Returns the losses for the active circuit element (see Select command) " + "for each PHASE in the Result string in comma-separated kW, kvar pairs."; + CommandHelp[44 - 1] = "Returns the total losses for the active circuit in the Result string in kW, kvar."; + CommandHelp[45 - 1] = "Estimates the allocation factors for loads that are defined using the XFKVA property. " + "Requires that energymeter objects be defined with the PEAKCURRENT property set. " + "Loads that are not in the zone of an energymeter cannot be allocated."; + CommandHelp[46 - 1] = "FormEdit [class.object - 1]. Brings up form editor on active DSS object."; + CommandHelp[47 - 1] = "Totals all EnergyMeter objects in the circuit and reports register totals in the result string."; + CommandHelp[48 - 1] = String("Find the maximum load the active circuit can serve in the PRESENT YEAR. Uses the EnergyMeter objects with the registers " "set with the SET UEREGS= (..) command for the AutoAdd functions. Syntax (defaults shown):") + CRLF + + CRLF + + "capacity [-1]0.9 [increment= - 1]0.005" + + CRLF + + CRLF + + "Returns the metered kW (load + losses - generation) and per unit load multiplier for the loading level at which something in the system reports an overload or undervoltage. " + + "If no violations, then it returns the metered kW for peak load for the year (1.0 multiplier). " + + "Aborts and returns 0 if no energymeters."; + CommandHelp[49 - 1] = "List of intrinsic DSS Classes. Returns comma-separated list in Result variable."; + CommandHelp[50 - 1] = "List of user-defined DSS Classes. Returns comma-separated list in Result variable."; + CommandHelp[51 - 1] = "Returns full Zsc matrix for the ACTIVE BUS in comma-separated complex number form."; + CommandHelp[52 - 1] = "Returns symmetrical component impedances, Z1, Z0 for the ACTIVE BUS in comma-separated R+jX form."; + CommandHelp[53 - 1] = "Refreshes Zsc matrix for the ACTIVE BUS."; + CommandHelp[54 - 1] = "Returns full Ysc matrix for the ACTIVE BUS in comma-separated complex number form G + jB."; + CommandHelp[55 - 1] = "Just like the Voltages command, except the voltages are in per unit if the kVbase at the bus is defined."; + CommandHelp[56 - 1] = "Returns variable values for active element if PC element. Otherwise, returns null."; + CommandHelp[57 - 1] = "Returns variable names for active element if PC element. Otherwise, returns null."; + CommandHelp[58 - 1] = String("Define x,y coordinates for buses. Execute after Solve or MakeBusList command is executed so that bus lists are defined." "Reads coordinates from a CSV file with records of the form: busname, x, y.") + CRLF + + CRLF + + "Example: BusCoords [-1]xxxx.csv"; + CommandHelp[59 - 1] = "Updates the buslist, if needed, using the currently enabled circuit elements. (This happens automatically for Solve command.)" + " See ReprocessBuses"; + CommandHelp[60 - 1] = "Attempts to convert present circuit model to a positive sequence equivalent. " + "It is recommended to Save the circuit after this and edit the saved version to correct possible misinterpretations."; + CommandHelp[61 - 1] = "{All | MeterName} Default is \"All\". Reduce the circuit according to reduction options. " + "See \"Set ReduceOptions\" and \"Set Keeplist\" options." + "Energymeter objects actually perform the reduction. \"All\" causes all meters to reduce their zones."; + CommandHelp[62 - 1] = "{All | MeterName} Default is \"All\". Interpolates coordinates for missing bus coordinates in meter zone"; + CommandHelp[63 - 1] = "Alignfile [file= - 1]filename. Aligns DSS script files in columns for easier reading."; + CommandHelp[64 - 1] = "[class= - 1]{Loadshape | Tshape | Monitor } [object= - 1]{ALL (Loadshapes only) | objectname}. " + "Send specified object to TOP. Loadshapes and TShapes must be hourly fixed interval. "; + CommandHelp[65 - 1] = "Usage: Rotate [angle= - 1]nnn. Rotate circuit plotting coordinates by specified angle (degrees). "; + CommandHelp[66 - 1] = "Displays the difference between the present solution and the last on saved using the SAVE VOLTAGES command."; + CommandHelp[67 - 1] = "Returns a power flow summary of the most recent solution in the global result string."; + CommandHelp[68 - 1] = String("kw=nn how={Proportional* | Uniform |Random | Skip} skip=nn PF=nn file=filename MW=nn What=[Generator*|Load - 1]") + CRLF + + CRLF + + "Creates a DSS script file to distribute Generator or Load objects on the system in the manner specified by \"how\"." + + CRLF + + "kW = total generation to be distributed (default=1000) " + + CRLF + + "how= process name as indicated (default=proportional to load)" + + CRLF + + "skip = no. of buses to skip for \"How=Skip\" (default=1)" + + CRLF + + "PF = power factor for new generators (default=1.0)" + + CRLF + + "file = name of file to save (default=distgenerators.dss or distloads.dss)" + + CRLF + + "MW = alternate way to specify kW (default = 1)" + + CRLF + + "What = what type of device to add, Generator (default) or Load"; + CommandHelp[69 - 1] = String("[case= - 1]casename [year= - 1]yr [registers= - 1](reg1, reg2,...) [peak= - 1]y/n [meter= - 1]metername") + CRLF + + "Plots demand interval (DI) results from yearly simulation cases. " + + "Plots selected registers from selected meter file (default = DI_Totals.CSV). " + + "Peak defaults to NO. If YES, only daily peak of specified registers " + + "is plotted. Example:" + + CRLF + + CRLF + + " DI_Plot basecase year=5 registers=(9,11) no"; + CommandHelp[70 - 1] = String("[Case1= - 1]casename [case2= - 1]casename [register= - 1](register number) [meter= - 1]{Totals* | SystemMeter | metername}. ") + CRLF + + "Compares yearly simulations of two specified cases with respect to the quantity in the designated register " + + "from the designated meter file. " + + "Defaults: Register=9 meter=Totals. Example:" + + CRLF + + CRLF + + "Comparecases base pvgens 10"; + CommandHelp[71 - 1] = String("[cases= - 1](case1, case2, ...) [registers= - 1](reg1, reg2, ...) [meter= - 1]{Totals* | SystemMeter | metername}" "Plots yearly curves for specified cases and registers. ") + CRLF + + "Default: meter=Totals. Example: " + + CRLF + + CRLF + + "yearlycurves cases=(basecase, pvgens) registers=9"; + CommandHelp[72 - 1] = String("Change default directory to specified directory") + CRLF + + CRLF + + "CD dirname"; + CommandHelp[73 - 1] = "[What= - 1] one of {Currents* | Voltages | Powers} [element= - 1]full_element_name (class.name). " + "Shows the selected quantity for selected element on a multiphase line drawing in phasor values."; + CommandHelp[74 - 1] = "Close all DI files ... useful at end of yearly solution where DI files are left open. " + "(Reset and Set Year=nnn will also close the DI files)"; +#ifdef windows + CommandHelp[75 - 1] = String("Do a DOS command. Sends the command \"cmd ... \" to Windows. Execute the \"cmd /?\" command " "in a DOS window to see the options. To do a DOS command and automatically exit, do ") + CRLF + + CRLF + + "DOScmd /c ...command string ..." + + CRLF + + CRLF + + "To keep the DOS window open, use /k switch."; +#else + CommandHelp[74] = String("Execute a shell command. Sends the command \"cmd ... \" to /bin/sh"); +#endif + CommandHelp[76 - 1] = "Execute state estimator on present circuit given present sensor values."; + CommandHelp[77 - 1] = String("Reconductor a line section. Must be in an EnergyMeter zone. ") + CRLF + + "Syntax: Reconductor Line1=... Line2=... {LineCode= | Geometry = } EditString=\"...\" NPhases=#" + + CRLF + + "Line1 and Line2 may be given in any order. All lines in the path between the two are redefined " + + "with either the LineCode or Geometry (not both). You may also add an optional string the alter any other line properties. " + + "The edit string should be enclosed in quotes or parens or brackets." + + CRLF + + "Nphases is an optional filter on the number of phases in line segments to change."; + CommandHelp[78 - 1] = "For step control of solution process: Intialize iteration counters, etc. that normally occurs at the " + "start of a snapshot solution process."; + CommandHelp[79 - 1] = "For step control of solution process: Solves the circuit in present state but does not check for control actions."; + CommandHelp[80 - 1] = "For step control of solution process: Sample the control elements, which push control action requests onto the control queue."; + CommandHelp[81 - 1] = "For step control of solution process: Pops control actions off the control queue according to the present control mode rules. " + "Dispatches contol actions to proper control element \"DoPendingAction\" handlers."; + CommandHelp[82 - 1] = "For step control of solution process: Show the present control queue contents."; + CommandHelp[83 - 1] = "For step control of solution process: Invoke direct solution function in DSS. Non-iterative solution of Y matrix and active sources only."; + CommandHelp[84 - 1] = "For step control of solution process: Invoke iterative power flow solution function of DSS directly."; + CommandHelp[85 - 1] = String("Add a marker to a bus in a circuit plot. Markers must be added before issuing the Plot command. Effect is persistent until circuit is cleared. " "See also ClearBusMarkers command. Example: ") + CRLF + + CRLF + + "ClearBusMarkers !...Clears any previous bus markers" + + CRLF + + "AddBusMarker Bus=Mybusname code=5 color=Red size=3" + + CRLF + + CRLF + + "You can use any of the standard color names or RGB numbers. See Help on C1 property in Plot command."; + CommandHelp[86 - 1] = "Read UUIDs (v4) for class names and other CIM objects. Tab or comma-delimited file with full object name (or key) and UUID. Side effect is to start a new UUID list for the Export CIM100 command; the UUID list is freed after the Export UUIDs command."; + CommandHelp[87 - 1] = "Set load and generator object kv to agree with the bus they are connected to using the bus voltage base and connection type."; + CommandHelp[88 - 1] = String("Convert all Loadshapes presently loaded into either files of single or files of double. " "Usually files of singles are adequate precision for loadshapes. Syntax:") + CRLF + + CRLF + + "cvrtloadshapes type=sng (this is the default)" + + CRLF + + "cvrtloadshapes type=dbl" + + CRLF + + CRLF + + "A DSS script for loading the loadshapes from the created files is produced and displayed in the default editor. "; + CommandHelp[89 - 1] = String("Global result is set to voltage difference, volts and degrees, (Node1 - Node2) between any two nodes. Syntax:") + CRLF + + CRLF + + " NodeDiff Node1=MyBus.1 Node2=MyOtherBus.1"; + CommandHelp[90 - 1] = String("Generates a script to change the phase designation of all lines downstream from a start in line. Useful for such things as moving a single-phase " "lateral from one phase to another and keep the phase designation consistent for reporting functions that need it to be " "(not required for simply solving). ") + CRLF + + CRLF + + "StartLine=... PhaseDesignation=\"...\" EditString=\"...\" ScriptFileName=... StopAtTransformers=Y/N/T/F" + + CRLF + + CRLF + + "Enclose the PhaseDesignation in quotes since it contains periods (dots)." + + CRLF + + "You may add and optional EditString to edit any other line properties." + + CRLF + + CRLF + + "Rephase StartLine=Line.L100 PhaseDesignation=\".2\" EditString=\"phases=1\" ScriptFile=Myphasechangefile.DSS Stop=No"; + CommandHelp[91 - 1] = "Bus=... X=... Y=... Set the X, Y coordinates for a single bus. Prerequisite: Bus must exist as a result of a Solve, CalcVoltageBases, or MakeBusList command."; + CommandHelp[92 - 1] = "Update Storage elements based on present solution and time interval. "; + CommandHelp[93 - 1] = "Change Bus and circuit element names to generic values to remove identifying names. Generally, " + "you will follow this command immediately by a \"Save Circuit Dir=MyDirName\" command."; + CommandHelp[94 - 1] = String("Define x,y coordinates for buses using Latitude and Longitude values (decimal numbers). Similar to BusCoords command. " "Execute after Solve command or MakeBusList command is executed so that bus lists are defined." "Reads coordinates from a CSV file with records of the form: busname, Latitude, Longitude.") + CRLF + + CRLF + + "Example: LatLongCoords [-1]xxxx.csv" + + CRLF + + CRLF + + "Note: Longitude is mapped to x coordinate and Latitude is mapped to y coordinate."; + CommandHelp[95 - 1] = String("Batch edit objects in the same class. Example: BatchEdit Load..* duty=duty_shape") + CRLF + + "In place of the object name, supply a PERL regular expression. .* matches all names." + + CRLF + + "The subsequent parameter string is applied to each object selected."; + CommandHelp[96 - 1] = String("Pst calculation. PstCalc Npts=nnn Voltages=[array - 1] dt=nnn freq=nn lamp=120 or 230.") + CRLF + + "Set Npts to a big enough value to hold the incoming voltage array. " + + CRLF + + "dt = time increment in seconds. default is 1" + + CRLF + + "freq = base frequency in Hz 50 or 60. Default is default base frequency" + + CRLF + + "Lamp= 120 for North America; 230 for Europe. Default is 120" + + CRLF + + CRLF + + "PSTCalc Npts=1900 V=[-1] dt=1 freq=60 lamp=120"; + CommandHelp[97 - 1] = String("[name= - 1] MyVariableName [Index= - 1] IndexofMyVariable ") + CRLF + + CRLF + + "Returns the value of the specified state variable of the active circuit element, if a PCelement. " + + "Returns the value as a string in the Result window or the Text.Result interface if using the COM server. " + + CRLF + + CRLF + + "You may specify the variable by name or by its index. You can determine the index using the VarNames command. " + + "If any part of the request is invalid, the Result is null."; + CommandHelp[98 - 1] = "Forces reprocessing of bus definitions whether there has been a change or not. Use for rebuilding meter zone lists " + "when a line length changes, for example or some other event that would not normally trigger an update to the bus list."; + CommandHelp[99 - 1] = "Clear all bus markers created with the AddBusMarker command."; + CommandHelp[100 - 1] = String("[restore=Y/N - 1]Perform reliability calcs: Failure rates and number of interruptions. ") + CRLF + + CRLF + + "Optional parameter:" + + CRLF + + CRLF + + "If restore=y automatic restoration of unfaulted section is assumed."; + CommandHelp[101 - 1] = String("Define and view script variables. Variable names begin with \"@\"") + CRLF + + CRLF + + "Usage:" + + CRLF + + CRLF + + "var @varname1=values @varname2=value2 ..." + + CRLF + + "var @varname1 (shows the value of @varname1)" + + CRLF + + "var (displays all variabiles and values)" + + CRLF + + CRLF + + "Example of using a variable:" + + CRLF + + CRLF + + "FileEdit @LastFile"; + CommandHelp[102 - 1] = "Force execution of the end-of-time-step cleanup functions that samples/saves meters and updates selected state variables such as storage level"; + CommandHelp[103 - 1] = "Do Cleanup, sample monitors, and increment time."; + CommandHelp[104 - 1] = String("[Circuit element name - 1] (Optional) Returns a list of node numbers for all conductors of all terminals of the active circuit element in the Result window or interface." "If the optional circuit element name is supplied, the program makes it the active element. Usage:") + CRLF + + CRLF + + "NodeList" + + CRLF + + "NodeList Line.Myline"; + CommandHelp[105 - 1] = "This command creates a new actor (OpenDSS Instance) and sets the new actor as the active actor. " + "There can be only 1 circuit per actor. The NewActor command will increment the variable NumOfActors;" + " however, if the number of actors is the same as the number of available CPUs the new actor will not be created " + "generating an error message. This instruction will deliver the ID of the active actor. This command does not requires a precedent command."; + CommandHelp[106 - 1] = "Clears all the circuits and all the actors, after this instruction there will be only 1 actor (actor 1) and will be the active actor"; + CommandHelp[107 - 1] = "Pauses the scripting thread until all the active actors are Ready to receive new commands (have finished all their tasks and are ready to receive new simulation orders)."; + CommandHelp[108 - 1] = "Solves all the circuits (Actors) loaded into memory by the user"; + CommandHelp[109 - 1] = "Calculates the incidence matrix of the Active Circuit"; + CommandHelp[110 - 1] = "Calculates the incidence matrix of the Active Circuit. However, in this case the matrix will be calculated considering its hierarchical order," + "listing the buses starting from the substation to the farthest load in the mode"; + CommandHelp[111 - 1] = "Estimates the buses for tearing the system in many parts as CPUs - 1 are in the local computer, is used for tearing the interconnected circuit into a" + " balanced (same number of nodes) collection of subsystems for the A-Diakoptics algorithm"; + CommandHelp[112 - 1] = "Request to create a TCP/IP socket to communicate data with external modules. This function requires the host address and TCP port to connect."; + CommandHelp[113 - 1] = "Request to terminate a TCP/IP socket. This function requires the host address and TCP port to disconnect."; + CommandHelp[114 - 1] = "This function takes the bus levels array and traces all the possible paths considering the longest paths from the substation to the farthest branches" + " within the circuit. Then, the new paths are filled with 0 to complement the oroginal levels proposed by the calcincmatrix_o command."; + CommandHelp[115 - 1] = String("{ElementName=} [KeepLoad=Y*/N - 1] [EditString=\"...\" - 1] " "Remove (disable) all branches downline from the PDelement named by \"ElementName\" property. Circuit must have an Energymeter on this branch. " "If KeepLoad=Y (default) a new Load element is defined and kW, kvar set to " "present power flow solution for the first element eliminated. " "The EditString is applied to each new Load element defined. ") + CRLF + + "If KeepLoad=N, all downline elements are disabled. Examples: " + + CRLF + + CRLF + + "Remove Line.Lin3021" + + CRLF + + "Remove Line.L22 Editstring=\"Daily=Dailycurve Duty=SolarShape" + + CRLF + + "Remove Line.L333 KeepLoad=No"; + CommandHelp[116 - 1] = "Aborts all the simulations running"; + CommandHelp[117 - 1] = "Calculate the laplacian matrix using the incidence matrix " + "previously calculated. Before calling this command " + "the incidence matrix needs to be calculated using calcincmatrix/calcincmatrix_o."; + CommandHelp[118 - 1] = "Clones the active circuit. This command creates as many copies of the active cirucit as indicated in the argument " + "if the number of requested clones does not overpasses the number of local CPUs. The form of this command is clone X where" + "X is the number of clones to be created"; + CommandHelp[119 - 1] = "Read FNCS publication topics from a JSON file"; + //CommandHelp[119] := 'Update Storage2 elements based on present solution and time interval. '; + CommandHelp[120 - 1] = "Exports the overloads report with the content avaiable at the moment of the call. It only affects the overloads report for the active actor."; + CommandHelp[121 - 1] = "Exports the voltage violations1 report with the content avaiable at the moment of the call. It only affects the voltage violations report for the active actor."; + CommandHelp[122 - 1] = "Returns symmetrical component short circuit impedances Z0, Z1, and Z2 for the ACTIVE 3-PHASE BUS. Determined from Zsc matrix."; + CommandHelp[123 - 1] = String("Aggregates the load shapes in the model using the number of zones given in the argument.") + CRLF + + "Use this command when the number of load shapes is considerably big, this algorithm will simplify" + + CRLF + + "the amount of load shapes in order to make the memory consumption lower for the model." + + CRLF + + "The output of this algorithm is a script describing the new load shapes and their application into loads across the model." + + CRLF + + "The argument on this command can be: Actual/pu to define the units in which the load profiles are." + + CRLF + + "Check the OpenDSS user manual for details"; + CommandHelp[124 - 1] = String("Brings back the names of all PCE connected to the bus specified in the argument.") + CRLF + + "The command goes as follows:" + + CRLF + + CRLF + + "AllPCEatBus myBus" + + CRLF + + CRLF + + "Where \"myBus\" is the name of the bus of interest"; + CommandHelp[125 - 1] = String("Brings back the names of all PDE connected to the bus specified in the argument.") + CRLF + + "The command goes as follows:" + + CRLF + + CRLF + + "AllPDEatBus myBus" + + CRLF + + CRLF + + "Where \"myBus\" is the name of the bus of interest"; + CommandHelp[126 - 1] = "Returns the total powers (complex) at ALL terminals of the active circuit element in the Result string. " + "(See Select command.)" + "Returned as comma-separated kW and kvar."; +#ifdef windows + CommandHelp[127 - 1] = "Shows the documentation file for the COM interface." +#else + CommandHelp[126] = "This command is not supported on this platform, but on MS Windows, this command would show the documentation file for the COM interface." +#endif + "This file provides guidance on the properties and methods included in the COM interface as well as examples and tips. Use this file to learn more about the COM interface and its different interfaces or just as a reference guide."; + CommandHelp[128 - 1] = "Executes GIS options working with OpenDSS-GIS. See GIS command help."; + CommandHelp[129 - 1] = String("Define x,y coordinates for buses using real GIS Latitude and Longitude values (decimal numbers). Similar to BusCoords command. " "Execute after Solve command or MakeBusList command is executed so that bus lists are defined." "Reads coordinates from a CSV file with records of the form: busname, Latitude, Longitude.") + CRLF + + CRLF + + "Example: GISCoords [-1]xxxx.csv" + + CRLF + + CRLF + + "Note: For using only if OpenDSS-GIS is locally installed."; + // Start list of INDUCES commands + CommandHelp[130 - 1] = "Reads an HDF file with non uniform, time varying geoelectric fields used in EMP simulations"; + // Ends list of INDUCES commands + } + + //---------------------------------------------------------------------------- + + void ProcessCommand(const string CmdLine) + { + int ParamPointer = 0; + int Temp_Int = 0; + int Iter = 0; + int i = 0; + String ParamName; + String Param; + String ObjName; + String PropName; + TEnergyMeterObj* MeterElem = nullptr; + try + { + CmdResult = 0; + ErrorNumber = 0; // Reset Error number + LastErrorMessage = ""; + GlobalResult = ""; + + /*Load up the parser and process the first parameter only*/ + LastCmdLine = CmdLine; + Parser[ActiveActor]->SetCmdString(LastCmdLine); // Load up command parser + LastCommandWasCompile = false; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() == 0) + return; // Skip blank line + + // Check for Command verb or Property Value + // Commands do not have equal signs so ParamName must be zero + if(ParamName.size() == 0) + ParamPointer = CommandList.Getcommand(Param); + + // Check first for Compile or Redirect and get outta here + switch(ParamPointer) + { + case 14: + { + /*# with DSSExecutive[ActiveActor] do */ + { + + if(DSSExecutive[ActiveActor]->get_FRecorderOn()) + DSSExecutive[ActiveActor]->Write_to_RecorderFile(CRLF + "!*********" + CmdLine); + } + CmdResult = DoRedirect(true); + return; + }//'Compile'; + case 20: + { + /*# with DSSExecutive[ActiveActor] do */ + { + + if(DSSExecutive[ActiveActor]->get_FRecorderOn()) + DSSExecutive[ActiveActor]->Write_to_RecorderFile(CRLF + "!*********" + CmdLine); + } + CmdResult = DoRedirect(false); + return; + } //'Redirect'; + // Write everything direct to recorder, if ON + default: + /*# with DSSExecutive[ActiveActor] do */ + { + + if(DSSExecutive[ActiveActor]->get_FRecorderOn()) + DSSExecutive[ActiveActor]->Write_to_RecorderFile(CmdLine); + } + break; + } + + // Things that are OK to do before a circuit is defined + switch(ParamPointer) + { + case 1: + CmdResult = DoNewCmd(); + break; // new + case 15: + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSetCmd_NoCircuit(); // can only call this if no circuit active + return; + } + break; /*Do Nothing - comment*/ + case 19: + ; + break; + case 21: + CmdResult = DoHelpCmd(); + break; + case 22: + if(!IsDLL) + ExitControlPanel(); + break; // Quit in Stand alone version + case 25: + ShowControlPanel(); + break; // DSSForms + case 27: + DoClearCmd(); + break; + case 28: + DoAboutBox(); + break; + case 32: + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoGetCmd_NoCircuit(); // can only call this if no circuit active + return; + } + break; + case 35: + CmdResult = DoFileEditCmd(); + break; + case 49: + CmdResult = DoClassesCmd(); + break; + case 50: + CmdResult = DoUserClassesCmd(); + break; + case 63: + CmdResult = DoAlignFileCmd(); + break; + case 69: + CmdResult = DoDI_PlotCmd(); + break; + case 70: + CmdResult = DoCompareCasesCmd(); + break; + case 71: + CmdResult = DoYearlyCurvesCmd(); + break; + case 72: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(SetCurrentDir(Param)) + { + CmdResult = 0; + SetDataPath(Param); // change datadirectory + } + else + DoSimpleMsg(String("Directory \"") + Param + "\" not found.", 282); + } + break; + case 75: + DoADOScmd(); + break; + case 88: + DoCvrtLoadshapesCmd(); + break; + case 101: + DoVarCmd(); + break; + case 105: + { + New_Actor_Slot(); + } + break; + case 106: + DoClearAllCmd(); + break; + case 107: + { + if(Parallel_enabled) + Wait4Actors(0); + } + break; + // Added to avoid crashes when in A-Diakoptics mode but the user + // uses the SolveAll command + case 108: + { + int stop = 0; + if(ADiakoptics) + Iter = 1; + else + Iter = NumOfActors; + // Execution area + for(stop = Iter, i = 1; i <= stop; i++) + { + ActiveActor = i; + CmdResult = DoSetCmd(1); + } + } + break; + case 109: + { + ActiveCircuit[ActiveActor]->Solution->Calc_Inc_Matrix(ActiveActor); + } + break; + case 110: + { + ActiveCircuit[ActiveActor]->Solution->Calc_Inc_Matrix_Org(ActiveActor); + } + break; + case 111: + { + ADiakoptics_Tearing(false); + } + break; + case 114: + { + ActiveCircuit[ActiveActor]->Get_paths_4_Coverage(); + Temp_Int =(ActiveCircuit[ActiveActor]->Path_Idx.size()) - 1; + GlobalResult = IntToStr(Temp_Int) + " new paths detected"; + } + break; + case 117: + { + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with3 = ActiveCircuit[ActiveActor]->Solution; + with3->Laplacian = with3->IncMat.Transpose(); // Transposes the Incidence Matrix + with3->Laplacian = with3->Laplacian.multiply( &(with3->IncMat) ); // IncMatT*IncMat + } + } + break; + case 127: + { +#ifdef windows + Show_COM_Help(); +#endif + } + break; +//#ifndef windows // By making these calls dependent on the OS, we should be able to compile OpenDSS-X by itself + case 130: + { + int a = 0; + int ret = ReadEfieldHDF(a); // Read Efield HDF file and populate internal data structures with file contents + if (!NoFormsAllowed) + cout << CmdLine; + } + break; +//#endif + default: + if(ActiveCircuit[ActiveActor] == nullptr) + { + DoSimpleMsg("You must create a new circuit object first: \"new circuit.mycktname\" to execute this command.", 301); + return; + } + break; + } + + // Now check to see if this is a command or a property reference + if(ParamPointer == 0) + /*If not a command or the command is unknown, THEN it could be a property of a circuit element*/ + + /*If a command or no text beFORe the = sign, THEN error*/ + { + if((ParamName.size() == 0) || (CompareText(ParamName, "command") == 0)) + { + DoSimpleMsg(String("Unknown Command: \"") + Param + + "\" " + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 302); + CmdResult = 1; + } + else + { + ParseObjName(ParamName, ObjName, PropName); + if(ObjName.size() > 0) + SetObject(ObjName); // Set active element + if(ActiveDSSObject[ActiveActor] != nullptr) + // rebuild command line and pass to editor + // use quotes to ensure first parameter is interpreted OK after rebuild + { + Parser[ActiveActor]->SetCmdString(PropName + "=\"" + Param + "\" " + Parser[ActiveActor]->Get_Remainder()); + ActiveDSSClass[ActiveActor]->Edit(ActiveActor); + } + } + return; + } + + // Process the rest of the commands + switch(ParamPointer) + { + case 2: + CmdResult = DoEditCmd(); + break; // edit + case 3: case 4: case 5: + CmdResult = DoMoreCmd(); + break; // more , m, ~ + case 6: + CmdResult = DoSelectCmd(); + break; + case 7: + CmdResult = DoSaveCmd(); + break; //'save'; + case 8: + CmdResult = DoShowCmd(); + break; //'show'; + case 9: + { + if(ADiakoptics) + ActiveActor = 1; // Just in case + CmdResult = DoSetCmd(1); // changed from DoSolveCmd; //'solve'; + } + break; + case 10: + CmdResult = DoEnableCmd(); + break; + case 11: + CmdResult = DoDisableCmd(); + break; + case 12: + CmdResult = DoPlotCmd(); + break; //'plot'; + case 13: + CmdResult = DoResetCmd(ActiveActor); + break; //'resetmonitors'; + case 15: + CmdResult = DoSetCmd(0); + break; //'set WITH no solve' + case 16: + CmdResult = DoPropertyDump(); + break; + case 17: + CmdResult = DoOpenCmd(); + break; + case 18: + CmdResult = DoCloseCmd(); + break; + case 23: + CmdResult = DoQueryCmd(); + break; + case 24: + CmdResult = DoNextCmd(); + break; // Advances time + /*25: ControlPanel.Show -- see above */ + case 26: + CmdResult = DoSampleCmd(ActiveActor); + break; + /*27: Begin ClearAllCircuits; DisposeDSSClasses; CreateDSSClasses; End;*/ + /*28: DoAboutBox; */ + case 29: + CmdResult = DoSetVoltageBases(ActiveActor); + break; + case 30: + CmdResult = DoSetkVBase(); + break; + case 31: + ActiveCircuit[ActiveActor]->InvalidateAllPCElements(); + break; // FORce rebuilding of Y + case 32: + CmdResult = DoGetCmd(); + break; + case 33: + ActiveCircuit[ActiveActor]->Solution->SolutionInitialized = false; + break; + case 34: + CmdResult = DoExportCmd(); + break; + /*35: CmdResult := DoFileEditCmd;*/ + case 36: + CmdResult = DovoltagesCmd(false); + break; + case 37: + CmdResult = DocurrentsCmd(); + break; + case 38: + CmdResult = DopowersCmd(0); + break; + case 39: + CmdResult = DoseqvoltagesCmd(); + break; + case 40: + CmdResult = DoseqcurrentsCmd(); + break; + case 41: + CmdResult = DoseqpowersCmd(); + break; + case 42: + CmdResult = DolossesCmd(); + break; + case 43: + CmdResult = DophaselossesCmd(); + break; + case 44: + CmdResult = DocktlossesCmd(); + break; + case 45: + CmdResult = DoAllocateLoadsCmd(ActiveActor); + break; + case 46: + CmdResult = DoFormEditCmd(); + break; + case 47: + CmdResult = DoMeterTotals(); + break; + case 48: + CmdResult = DoCapacityCmd(); + break; + // 49: CmdResult := DoClassesCmd; + // 50: CmdResult := DoUserClassesCmd; + case 51: + CmdResult = DoZscCmd(true); + break; + case 52: + CmdResult = DoZsc10Cmd(); + break; + case 53: + CmdResult = DoZscRefresh(ActiveActor); + break; + case 54: + CmdResult = DoZscCmd(false); + break; + case 55: + CmdResult = DovoltagesCmd(true); + break; + case 56: + CmdResult = DoVarValuesCmd(); + break; + case 57: + CmdResult = DoVarNamesCmd(); + break; + case 58: + CmdResult = DoBusCoordsCmd(false, 0); + break; + case 59: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with40 = ActiveCircuit[ActiveActor]; + if(with40->get_FBusNameRedefined()) + with40->ReProcessBusDefs(ActiveActor); + } + break; + case 60: + CmdResult = DoMakePosSeq(); + break; + case 61: + CmdResult = DoReduceCmd(); + break; + case 62: + CmdResult = DoInterpolateCmd(); + break; + case 64: + CmdResult = DoTOPCmd(); + break; + case 65: + CmdResult = DoRotateCmd(); + break; + case 66: + CmdResult = DoVDiffCmd(); + break; + case 67: + CmdResult = DoSummaryCmd(); + break; + case 68: + CmdResult = DoDistributeCmd(); + break; + // 69; + // 70; + // 71; + // 72; + case 73: + CmdResult = DoVisualizeCmd(); + break; + case 74: + CmdResult = DoCloseDICmd(); + break; + case 76: + CmdResult = DoEstimateCmd(); + break; + case 77: + CmdResult = DoReconductorCmd(); + break; + /*Step solution commands*/ + case 78: + ActiveCircuit[ActiveActor]->Solution->SnapShotInit(ActiveActor); + break; + case 79: + { + ActiveCircuit[ActiveActor]->Solution->SolveCircuit(ActiveActor); + } + break; + case 80: + ActiveCircuit[ActiveActor]->Solution->SampleControlDevices(ActiveActor); + break; + case 81: + ActiveCircuit[ActiveActor]->Solution->DoControlActions(ActiveActor); + break; + case 82: + ActiveCircuit[ActiveActor]->ControlQueue.ShowQueue(DSSDirectory + CircuitName_[ActiveActor] + "ControlQueue.csv"); + break; + case 83: + { + ActiveCircuit[ActiveActor]->Solution->SolveDirect(ActiveActor); + } + break; + case 84: + { + ActiveCircuit[ActiveActor]->Solution->DoPFLOWsolution(ActiveActor); + } + break; + case 85: + CmdResult = DoAddMarkerCmd(); + break; + case 86: + CmdResult = DoUuidsCmd(); + break; + case 87: + CmdResult = DoSetLoadAndGenKVCmd(); + break; + // 88:; + case 89: + CmdResult = DoNodeDiffCmd(); + break; + case 90: + CmdResult = DoRephaseCmd(); + break; + case 91: + CmdResult = DoSetBusXYCmd(); + break; + case 92: + CmdResult = DoUpdateStorageCmd(); + break; + case 93: + Obfuscate(); + break; + case 94: + CmdResult = DoBusCoordsCmd(true, 0); + break; // swaps X and Y + case 95: + CmdResult = DoBatchEditCmd(); + break; + case 96: + CmdResult = DoPstCalc(); + break; + case 97: + CmdResult = DoValVarCmd(); + break; + case 98: + ActiveCircuit[ActiveActor]->ReProcessBusDefs(ActiveActor); + break; + case 99: + ActiveCircuit[ActiveActor]->ClearBusMarkers(); + break; + case 100: + CmdResult = DoLambdaCalcs(); + break; // Option: Assume Restoration + case 102: + EndOfTimeStepCleanup(ActiveActor); + break; + case 103: + FinishTimeStep(ActiveActor); + break; + case 104: + CmdResult = DoNodeListCmd(); + break; + case 112: + CmdResult = DoConnectCmd(); + break; //'TCP/IP connect'; + case 113: + CmdResult = DoDisConnectCmd(); + break; //'TCP/IP disconnect';'; + case 115: + DoRemoveCmd(); + break; + case 116: + SolutionAbort = true; + break; + case 118: + DoClone(); + break; + case 119: + DoFNCSPubCmd(); + break; + // 120: CmdResult := DoUpDateStorage2Cmd; + case 120: + { + if(OV_MHandle[ActiveActor] != nullptr) + CloseMHandler(OV_MHandle[ActiveActor], EnergyMeterClass[ActiveActor]->DI_Dir + DIRSEP_STR "DI_Overloads_" + IntToStr(ActiveActor) + ".CSV", OV_Append[ActiveActor]); + } + break; + case 121: + { + if(VR_MHandle[ActiveActor] != nullptr) + CloseMHandler(VR_MHandle[ActiveActor], EnergyMeterClass[ActiveActor]->DI_Dir + DIRSEP_STR "DI_VoltExceptions_" + IntToStr(ActiveActor) + ".CSV", VR_Append[ActiveActor]); + } + break; + case 122: + CmdResult = DoZsc012Cmd(); + break; // Get full symmetrical component transformation of Zsc + case 123: + { + dummy = Parser[ActiveActor]->GetNextParam(); + ActiveCircuit[ActiveActor]->AggregateProfiles(Parser[ActiveActor]->MakeString_()); + } + break; + case 124: + { + dummy = Parser[ActiveActor]->GetNextParam(); + GlobalResult = ActiveCircuit[ActiveActor]->ReportPCEatBus(Parser[ActiveActor]->MakeString_()); + } + break; + case 125: + { + dummy = Parser[ActiveActor]->GetNextParam(); + GlobalResult = ActiveCircuit[ActiveActor]->ReportPDEatBus(Parser[ActiveActor]->MakeString_()); + } + break; + case 126: + CmdResult = DopowersCmd(1); + break; + case 128: + GlobalResult = DoGISCmd(); + break; + case 129: + CmdResult = DoBusCoordsCmd(false, 1); + break; // GIS coordinates + + // Ignore excess parameters + default: + ; + break; + } + } + catch (std::exception &e) + { + DoErrorMsg((String(String("ProcessCommand") + CRLF + "Exception Raised While Processing DSS Command:") + CRLF + Parser[ActiveActor]->get_CmdBuffer()), (std::string) e.what(), "Error in command string or circuit data.", 303); + } + + // if ActorStatus[ActiveActor] = 1 then + // ParserVars.Add('@result', GlobalResult) + } + + void DisposeStrings() + { + delete[] ExecCommand; + delete[] CommandHelp; + } + + + void ExecCommands_initialization() + { + DefineCommands(); + } + + void ExecCommands_finalization() + { + DisposeStrings(); + } + + class ExecCommands_unit + { + public: + ExecCommands_unit() + { + //AssertSystemInitialization(); + ExecCommands_initialization(); + } + ~ ExecCommands_unit(){ExecCommands_finalization(); } + }; + ExecCommands_unit _ExecCommands_unit; + +} // namespace ExecCommands + + + + diff --git a/OpenDSSC/Executive/ExecCommands.h b/OpenDSSC/Executive/ExecCommands.h new file mode 100644 index 0000000..227e981 --- /dev/null +++ b/OpenDSSC/Executive/ExecCommands.h @@ -0,0 +1,60 @@ +#ifndef ExecCommandsH +#define ExecCommandsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +#include "DSSGlobals.h" +#include "ExecHelper.h" +#include "Executive.h" +#include "ExecOptions.h" +#include "ShowOptions.h" +#include "ExportOptions.h" +#include "ParserDel.h" +#include "LoadShape.h" +#include "Utilities.h" +#include "SolutionAlgs.h" +#include "DSSClassDefs.h" +#include "Arraydef.h" +#include "CmdForms.h" +#include "ConnectOptions.h" +#include "Diakoptics.h" +#include "Sparse_Math.h" +#include "MemoryMap_lib.h" +#include "EnergyMeter.h" +#include "GISCommands.h" +#include "PlotOptions.h" + +namespace ExecCommands +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + const int NumExecCommands = 130; // This number has to change if we add more commands to OpenDSS...this will need to change for induces + extern string* ExecCommand; + extern string* CommandHelp; + extern TCommandList CommandList; + extern string LastCmdLine; // always has last command processed + extern string RedirFile; + void ProcessCommand(const string CmdLine); + + +} // namespace ExecCommands + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExecCommands; +#endif + +#endif // ExecCommandsH + + + + diff --git a/OpenDSSC/Executive/ExecHelper.cpp b/OpenDSSC/Executive/ExecHelper.cpp new file mode 100644 index 0000000..0e68edc --- /dev/null +++ b/OpenDSSC/Executive/ExecHelper.cpp @@ -0,0 +1,4807 @@ +#pragma hdrstop + +#include "ExecHelper.h" +#include "dirsep.h" +#include +#include +#include +#include + + + +using namespace std; +using namespace Arraydef; +using namespace Bus; +using namespace Capacitor; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace EnergyMeter; +using namespace ExecCommands; +using namespace Executive; +using namespace Generator; +using namespace Line; +using namespace LineUnits; +using namespace Load; +using namespace LoadShape; +using namespace Monitor; +using namespace NamedObject; +using namespace PCElement; +using namespace PDELement; +using namespace ParserDel; +using namespace Pstcalc; +using namespace Reactor; +using namespace ReduceAlgs; +using namespace Sensor; +using namespace Solution; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace ExecHelper +{ +#define ExecHelper__0 (TPerlRegExOptions() << preCaseLess) + + /*ShowResults, ExportResults,*/ +TCommandList* SaveCommands = nullptr; +TCommandList* DistributeCommands = nullptr; +TCommandList* DI_PlotCommands = nullptr; +TCommandList* ReconductorCommands = nullptr; +TCommandList* RephaseCommands = nullptr; +TCommandList* AddMarkerCommands = nullptr; +TCommandList* SetBusXYCommands = nullptr; +TCommandList* PstCalcCommands = nullptr; +TCommandList* RemoveCommands = nullptr; +TCommandList* FNCSPubCommands = nullptr; + + +//---------------------------------------------------------------------------- + +void GetObjClassAndName(String& ObjClass, String& ObjName) +{ + String ParamName; + String Param; + +/* + We're looking for Object Definition: + + ParamName = 'object' IF given + and the name of the object + + Object=Capacitor.C1 + or just Capacitor.C1 + + If no dot, last class is assumed +*/ + ObjClass = ""; + ObjName = ""; + ParamName = LowerCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + if(ParamName.size() > 0) // IF specified, must be object or an abbreviation + { + if(CompareTextShortest(ParamName, "object") != 0) + { + DoSimpleMsg(String("object=Class.Name expected as first parameter in command.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 240); + return; + } + } + ParseObjectClassandName(Param, ObjClass, ObjName); // see DSSGlobals +} + + +//---------------------------------------------------------------------------- + +int DoNewCmd() +{ + int result = 0; + String ObjClass; + String ObjName; + int Handle = 0; + result = 0; + Handle = 0; + GetObjClassAndName(ObjClass, ObjName); + if(CompareText(ObjClass, "solution") == 0) + { + DoSimpleMsg("You cannot create new Solution objects through the command interface.", 241); + return result; + } + if(CompareText(ObjClass, "circuit") == 0) + { + MakeNewCircuit(ObjName); // Make a new circuit + ClearEventLog(); // Start the event log in the current directory + ClearErrorLog(); + } + else + // Everything else must be a circuit element or DSS Object + { + Handle = AddObject(ObjClass, ObjName); + } + if(Handle == 0) + result = 1; + return result; +} + +// Process the New Command +// new type=xxxx name=xxxx editstring + +// IF the device being added already exists, the default behavior is to +// treat the New command as an Edit command. This may be overridden +// by setting the DuplicatesAllowed VARiable to true, in which CASE, +// the New command always results in a new device being added. + + +//---------------------------------------------------------------------------- + +int DoEditCmd() +{ + int result = 0; + String ObjType = "", + ObjName = ""; + + GetObjClassAndName(ObjType, ObjName); + if(CompareText(ObjType, "circuit") == 0) + ; + else + + // Do nothing + + + // Everything ELSE must be a circuit element + { + result = EditObject(ObjType, ObjName); + } + return result; +} + +// edit type=xxxx name=xxxx editstring + + +//---------------------------------------------------------------------------- + +int DoBatchEditCmd() +{ + int result = 0; + String ObjType; + String Pattern; + TPerlRegEx* RegEx1 = nullptr; + TDSSObject* pObj = nullptr; + int Params = 0; + int iElement = 0; + result = 0; + GetObjClassAndName(ObjType, Pattern); + if(CompareText(ObjType, "circuit") == 0) + ; + else + + // Do nothing + { + LastClassReferenced[ActiveActor] = ClassNames[ActiveActor].Find(ObjType); + switch(LastClassReferenced[ActiveActor]) + { + case 0: + { + DoSimpleMsg(String("BatchEdit Command: Object Type \"") + ObjType + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 267); + return result; + }/*Error*/ + default: + Params = Parser[ActiveActor]->get_position(); + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + RegEx1 = new TPerlRegEx(); +// RegEx1->Options = ExecHelper__0; + RegEx1->set_FRegEx(Pattern); // AnsiString(Pattern); + if(ActiveDSSClass[ActiveActor]->Get_First() > 0) + pObj = (TDSSObject*) ActiveDSSObject[ActiveActor]; + else + pObj = nullptr; + while(pObj != nullptr) + { + RegEx1->set_mySubject(pObj->get_Name()); //(pObj.Name); + if(RegEx1->Match()) + { + Parser[ActiveActor]->set_position(Params); + ActiveDSSClass[ActiveActor]->Edit(ActiveActor); + } + if(ActiveDSSClass[ActiveActor]->Get_Next() > 0) + pObj = (TDSSObject*) ActiveDSSObject[ActiveActor]; + else + pObj = nullptr; + } + break; + } + } + return result; +} +// batchedit type=xxxx name=pattern editstring + + +//---------------------------------------------------------------------------- + +int DoRedirect(bool IsCompile) +{ + int result = 0; + TTextRec Fin = {}; + String ParamName; + String InputLine; + String CurrDir; + String SaveDir; + String LocalCompFileName; + bool InBlockComment = false; + result = 0; + InBlockComment = false; // Discareded off stack upon return + // Therefore extent of block comment does not extend beyond a file + // Going back up the redirect stack + + // Get next parm and try to interpret as a file name + ParamName = Parser[ActiveActor]->GetNextParam(); + RedirFile = ExpandFileName(Parser[ActiveActor]->MakeString_()); + if(RedirFile.length()) + { + SaveDir = GetCurrentDir(); + try + { + AssignFile(Fin, RedirFile); + Reset(Fin); + IOResultToException(); + if(IsCompile) + { + LastFileCompiled = RedirFile; + LocalCompFileName = RedirFile; + } + + // Couldn't find file Try appending a '.dss' to the file name + // If it doesn't already have an extension + } + catch(...) + { + if(Pos(".", RedirFile) == 0) + { + RedirFile = RedirFile + ".dss"; + try + { + AssignFile(Fin, RedirFile); + Reset(Fin); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg("Redirect File: \"" + RedirFile + "\" Not Found.", 242); + SolutionAbort = true; + return result; + } + } + else + { + DoSimpleMsg("Redirect File: \"" + RedirFile + "\" Not Found.", 243); + SolutionAbort = true; + return result; + } + } + + // OK, we finally got one open, so we're going to continue + try + { + try + + // Change Directory to path specified by file in CASE that + // loads in more files + { + CurrDir = ExtractFileDir(RedirFile); + SetCurrentDir(CurrDir); + if(IsCompile) + SetDataPath(CurrDir); // change datadirectory + Redirect_Abort = false; + In_Redirect = true; + while(!((Eof(Fin)) || (Redirect_Abort))) + { + ReadLn(Fin, InputLine); + if(InputLine.size() > 0) + { + if(!InBlockComment) + switch(InputLine[0]) + { // look for '/*' at baginning of line + case L'/': + if((InputLine.size() > 1) && (InputLine[1] == L'*')) + InBlockComment = true; + break; + default: {} + } + if(!InBlockComment) + { + if (!SolutionAbort) // process the command line + { + int NumOfTimes = 1; + if (AllActors) + NumOfTimes = NumOfActors; + for (int idx = 1; idx <= NumOfTimes; idx++) + { + if (AllActors) ActiveActor = idx; + ProcessCommand(InputLine); + } + + } + else + Redirect_Abort = true; // Abort file if solution was aborted + + // in block comment ... look for */ and cancel block comment (whole line) + } + if(InBlockComment) + { + if(Pos("*/", InputLine) > 0) + InBlockComment = false; + } + } + } + if(ActiveCircuit[ActiveActor] != nullptr) + ActiveCircuit[ActiveActor]->CurrentDirectory = CurrDir + DIRSEP_STR; + } + catch (std::exception &e) + { + DoErrorMsg(String("DoRedirect") + CRLF + "Error Processing Input Stream in Compile/Redirect.", (std::string) e.what(), String("Error in File: \"") + RedirFile + "\" or Filename itself.", 244); + } +/* } + __finally + {*/ + CloseFile(Fin); + In_Redirect = false; + ParserVars->Add("@lastfile", RedirFile); + if(IsCompile) + { + SetDataPath(CurrDir); // change datadirectory + LastCommandWasCompile = true; + ParserVars->Add("@lastcompilefile", LocalCompFileName); // will be last one off the stack - had to remove the '@', it was killing the process + } + else + { + SetCurrentDir(SaveDir); // set back to where we were for redirect, but not compile + ParserVars->Add("@lastredirectfile", RedirFile); + } + } + catch (...) + { + // + } + } // ELSE ignore altogether IF null filename + return result; +} + +// This routine should be recursive +// So you can redirect input an arbitrary number of times + +// If Compile, makes directory of the file the new home directory +// If not Compile (is simple redirect), return to where we started + + +//---------------------------------------------------------------------------- + +int DoSelectCmd() +{ + int result = 0; + String ObjClass; + String ObjName; + String ParamName; + String Param; + result = 1; + GetObjClassAndName(ObjClass, ObjName); // Parse Object class and name + if((ObjClass.size() == 0) && (ObjName.size() == 0)) + return result; // select active obj if any + if(CompareText(ObjClass, "circuit") == 0) + { + SetActiveCircuit(ObjName); + } + else + + + // Everything else must be a circuit element + { + if(ObjClass.size() > 0) + SetObjectClass(ObjClass); + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if(ActiveDSSClass[ActiveActor] != nullptr) + { + if(!ActiveDSSClass[ActiveActor]->SetActive(ObjName)) // scroll through list of objects untill a match + { + DoSimpleMsg(String("Error! Object \"") + ObjName + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 245); + result = 0; + } + else + /*# with ActiveCircuit[ActiveActor] do */ + { + + switch( ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->DSSObjType ) + { + case DSS_OBJECT: + ; + break; // do nothing for general DSS object + default: + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(((TDSSCktElement*) ActiveDSSClass[ActiveActor]->GetActiveObj())); + // Now check for active terminal designation + ParamName = LowerCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ActiveTerminal(Parser[ActiveActor]->MakeInteger_()); + else + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ActiveTerminal(1); /*default to 1*/ + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + SetActiveBus(StripExtension(with1->GetBus(with1->get_FActiveTerminal()))); + } + break; + } + } + } + else + { + DoSimpleMsg("Error! Active object type/class is not set.", 246); + result = 0; + } + } + return result; +} + +// select active object +// select element=elementname terminal=terminalnumber + + +//---------------------------------------------------------------------------- + +int DoMoreCmd() +{ + int result = 0; + if(ActiveDSSClass[ActiveActor] != nullptr) + result = ActiveDSSClass[ActiveActor]->Edit(ActiveActor); + else + result = 0; + return result; +} + +// more editstring (assumes active circuit element) + + + +//---------------------------------------------------------------------------- + +int DoSaveCmd() +{ + int result = 0; + TMonitorObj* pMon = nullptr; + TEnergyMeterObj* pMtr = nullptr; + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + String ObjClass; + String SaveDir; + String saveFile; + TDSSClass* DSSClass = nullptr; + result = 0; + ObjClass = ""; + SaveDir = ""; + saveFile = ""; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = SaveCommands->Getcommand(ParamName); + switch (ParamPointer) + { + case 1: + ObjClass = Parser[ActiveActor]->MakeString_(); + break; + case 2: + saveFile = Parser[ActiveActor]->MakeString_(); + break; // File name for saving a class + case 3: + SaveDir = Parser[ActiveActor]->MakeString_(); + break; + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + InShowResults = true; + if ((ObjClass.size() == 0) || (CompareTextShortest(ObjClass, "meters") == 0)) + // Save monitors and Meters + { + /*# with ActiveCircuit[ActiveActor].Monitors do */ + { + auto& with0 = ActiveCircuit[ActiveActor]->Monitors; + int stop = 0; + for (stop = with0.get_myNumList(), i = 1; i <= stop; i++) + { + pMon = (TMonitorObj*)with0.Get(i); + pMon->Save(); + } + } + /*# with ActiveCircuit[ActiveActor].EnergyMeters do */ + { + auto& with1 = ActiveCircuit[ActiveActor]->EnergyMeters; + int stop = 0; + for (stop = with1.get_myNumList(), i = 1; i <= stop; i++) + { + pMtr = (TEnergyMeterObj*)with1.Get(i); + pMtr->SaveRegisters(ActiveActor); + } + } + return result; + } + if (CompareTextShortest(ObjClass, "circuit") == 0) + { + if (!ActiveCircuit[ActiveActor]->Save(SaveDir)) + result = 1; + return result; + } + if (CompareTextShortest(ObjClass, "voltages") == 0) + { + ActiveCircuit[ActiveActor]->Solution->SaveVoltages(); + return result; + } + else + return 0; + + /*Assume that we have a class name for a DSS Class*/ + DSSClass = (TDSSClass*)GetDSSClassPtr(ObjClass); + if (DSSClass != nullptr) + { + if (saveFile.size() == 0) + saveFile = ObjClass; + if (SaveDir.size() > 0) + { + if (!DirectoryExists(SaveDir)) + try + { + MkDir(SaveDir); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error making Directory: \"") + SaveDir + "\". " + (std::string)e.what(), 247); + } + saveFile = SaveDir + DIRSEP_STR + saveFile; + } + WriteClassFile((*DSSClass), saveFile, false); // just write the class with no checks + } + SetLastResultFile(saveFile); + GlobalResult = saveFile; + return result; +} + +// Save current values in both monitors and Meters + + + +//---------------------------------------------------------------------------- + +int DoClearCmd() +{ + int result = 0; + DSSExecutive[ActiveActor]->Clear(); + result = 0; + return result; +} +//---------------------------------------------------------------------------- + +int DoClearAllCmd() +{ + int result = 0; + DSSExecutive[ActiveActor]->ClearAll(); + result = 0; + return result; +} +//---------------------------------------------------------------------------- + +int DoHelpCmd() +{ + int result = 0; +// ShowHelpForm(); // DSSForms Unit + result = 0; + return result; +} + + +//---------------------------------------------------------------------------- + +int DoSampleCmd(int ActorID) +{ + int result = 0; + MonitorClass[ActorID]->SampleAll(ActorID); + EnergyMeterClass[ActorID]->SampleAll(ActorID); // gets generators too + result = 0; + return result; +} + +// FORce all monitors and meters in active circuit to take a sample + + + +//---------------------------------------------------------------------------- + +int DoSolveCmd() +{ + int result = 0; + // just invoke solution obj's editor to pick up parsing and execute rest of command + ActiveSolutionObj = ActiveCircuit[ActiveActor]->Solution; + result = SolutionClass[ActiveActor]->Edit(ActiveActor); + return result; +} + + +//---------------------------------------------------------------------------- + +int SetActiveCktElement() +{ + int result = 0; + String ObjType; + String ObjName; + result = 0; + GetObjClassAndName(ObjType, ObjName); + if(CompareText(ObjType, "circuit") == 0) + ; + else + + // Do nothing + { + if(CompareText(ObjType, ActiveDSSClass[ActiveActor]->get_myClass_name()) != 0) + LastClassReferenced[ActiveActor] = ClassNames[ActiveActor].Find(ObjType); + switch(LastClassReferenced[ActiveActor]) + { + case 0: + { + DoSimpleMsg(String("Object Type \"") + ObjType + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 253); + result = 0; + return result; + }/*Error*/ + + // intrinsic and user Defined models + default: + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if(ActiveDSSClass[ActiveActor]->SetActive(ObjName)) + /*# with ActiveCircuit[ActiveActor] do */ + { + // scroll through list of objects until a match + switch( ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->DSSObjType) + { + case DSS_OBJECT: + DoSimpleMsg(String("Error in SetActiveCktElement: Object not a circuit Element.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 254); + break; + default: + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(((TDSSCktElement*) ActiveDSSClass[ActiveActor]->GetActiveObj())); + result = 1; + break; + } + } + break; + } + } + return result; +} + +// Parses the object off the line and sets it active as a circuitelement. + + + +//---------------------------------------------------------------------------- + +int DoEnableCmd() +{ + int result = 0; + String ObjType; + String ObjName; + TDSSClass* ClassPtr = nullptr; + TDSSCktElement* CktElem = nullptr; + int i = 0; + + // Result := SetActiveCktElement; + // IF Result>0 THEN ActiveCircuit[ActiveActor].ActiveCktElement.Enabled := True; + result = 0; + GetObjClassAndName(ObjType, ObjName); + if(CompareText(ObjType, "circuit") == 0) + ; + else + { + if(ObjType.size() > 0) + // Do nothing + + // only applies to CktElementClass objects + { + ClassPtr = (TDSSClass*) GetDSSClassPtr(ObjType); + if(ClassPtr != nullptr) + { + if((ClassPtr->DSSClassType & BaseClassMask) > 0) + // Everything else must be a circuit element + { + if(CompareText(ObjName, "*") == 0) + // Enable all elements of this class + { + int stop = 0; + for(stop = ClassPtr->Get_ElementCount(), i = 1; i <= stop; i++) + { + CktElem = (TDSSCktElement*) ClassPtr->ElementList.Get(i); + CktElem->Set_Enabled(true); + } + } + else + + + // just load up the parser and call the edit routine for the object in question + { + Parser[ActiveActor]->SetCmdString("Enabled=true"); // Will only work for CktElements + result = EditObject(ObjType, ObjName); + } + } + } + } + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoDisableCmd() +{ + int result = 0; + String ObjType; + String ObjName; + TDSSClass* ClassPtr = nullptr; + TDSSCktElement* CktElem = nullptr; + int i = 0; + result = 0; + GetObjClassAndName(ObjType, ObjName); + if(CompareText(ObjType, "circuit") == 0) + ; + else + { + if(ObjType.size() > 0) + // Do nothing + + // only applies to CktElementClass objects + { + ClassPtr = (TDSSClass*) GetDSSClassPtr(ObjType); + if(ClassPtr != nullptr) + { + if((ClassPtr->DSSClassType & BaseClassMask) > 0) + // Everything else must be a circuit element + { + if(CompareText(ObjName, "*") == 0) + // Disable all elements of this class + { + int stop = 0; + for(stop = ClassPtr->Get_ElementCount(), i = 1; i <= stop; i++) + { + CktElem = (TDSSCktElement*) ClassPtr->ElementList.Get(i); + CktElem->Set_Enabled(false); + } + } + else + + + // just load up the parser and call the edit routine for the object in question + { + Parser[ActiveActor]->SetCmdString("Enabled=false"); // Will only work for CktElements + result = EditObject(ObjType, ObjName); + } + } + } + } + +// Result := SetActiveCktElement; +// IF Result>0 THEN ActiveCircuit[ActiveActor].ActiveCktElement.Enabled := False; + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoPropertyDump() +{ + int result = 0; + TDSSObject* PObject = nullptr; + TTextRec f = {}; + bool SingleObject = false; + bool DebugDump = false; + bool IsSolution = false; + int i = 0; + String FileName; + String ParamName; + String Param; + String Param2; + String ObjClass; + String ObjName; + result = 0; + SingleObject = false; + IsSolution = false; + DebugDump = false; + ObjClass = " "; // make sure these have at least one character + ObjName = " "; + + // Continue parsing command line - check for object name + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + { + if(CompareText(Param, "commands") == 0) + { + if(!NoFormsAllowed) + { + DumpAllDSSCommands(FileName); + FireOffEditor(FileName); + return result; + } + + /*dump bus names hash list*/ + } + if(CompareText(Param, "buslist") == 0) + { + if(!NoFormsAllowed) + { + FileName = GetOutputDirectory() + "Bus_Hash_List.Txt"; + ActiveCircuit[ActiveActor]->BusList.DumpToFile(FileName); + FireOffEditor(FileName); + return result; + } + + /*dump device names hash list*/ + } + if(CompareText(Param, "devicelist") == 0) + { + if(!NoFormsAllowed) + { + FileName = GetOutputDirectory() + "Device_Hash_List.Txt"; + ActiveCircuit[ActiveActor]->DeviceList.DumpToFile(FileName); + FireOffEditor(FileName); + return result; + } + } + if(CompareText(LowerCase(Param).substr(0, 5), "alloc") == 0) + { + FileName = GetOutputDirectory() + "AllocationFactors.Txt"; + DumpAllocationFactors(FileName); + FireOffEditor(FileName); + return result; + } + if(CompareText(Param, "debug") == 0) + DebugDump = true; + else + { + if(CompareText(Param, "solution") == 0) + // Assume active circuit solution IF not qualified + { + ActiveDSSClass[ActiveActor] = SolutionClass[ActiveActor]; + ActiveDSSObject[ActiveActor] = ActiveCircuit[ActiveActor]->Solution; + IsSolution = true; + } + else + { + SingleObject = true; + // Check to see IF we want a debugdump on this object + ParamName = Parser[ActiveActor]->GetNextParam(); + Param2 = Parser[ActiveActor]->MakeString_(); + if(CompareText(Param2, "debug") == 0) + DebugDump = true; + // Set active Element to be value in Param + Parser[ActiveActor]->SetCmdString(String("\"") + Param + "\""); // put param back into parser + GetObjClassAndName(ObjClass, ObjName); + // IF DoSelectCmd=0 THEN Exit; 8-17-00 + if(SetObjectClass(ObjClass)) + { + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if(ActiveDSSClass[ActiveActor] == nullptr) + return result; + } + else + return result; + } + } + } + try + { + AssignFile(f, GetOutputDirectory() + CircuitName_[ActiveActor] + "PropertyDump.Txt"); + Rewrite(f); + IOResultToException(); + } + catch (std::exception &e) + { + { + DoErrorMsg(String("DoPropertyDump - opening ") + GetOutputDirectory() + + " DSS_PropertyDump.txt for writing in " + + GetCurrentDir(), (std::string) e.what(), "Disk protected or other file error", 255); + return result; + } + } + try + { + if(SingleObject) + + /*IF ObjName='*' then we dump all objects of this class*/ + { + switch(ObjName[0]) + { + case L'*': + { + int stop = 0; + for(stop = ActiveDSSClass[ActiveActor]->Get_ElementCount(), i = 1; i <= stop; i++) + { + ActiveDSSClass[ActiveActor]->Set_Active(i); + ( (TDSSCktElement*) ActiveDSSObject[ActiveActor])->DumpProperties(f, DebugDump); + } + } + break; + default: + if(!ActiveDSSClass[ActiveActor]->SetActive(ObjName)) + { + DoSimpleMsg(String("Error! Object \"") + ObjName + "\" not found.", 256); + return result; + } + else + ( (TDSSCktElement*) ActiveDSSObject[ActiveActor] )->DumpProperties(f, DebugDump); // Dump only properties of active circuit element + break; + } + } + else + { + if(IsSolution) + { + ((TDSSCktElement*)ActiveDSSObject[ActiveActor])->DumpProperties(f, DebugDump); + } + else + + + // Dump general Circuit stuff + { + if(DebugDump) + ActiveCircuit[ActiveActor]->DebugDump(f); + // Dump circuit objects + try + { + PObject = (TDSSObject*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while(PObject != nullptr) + { + PObject->DumpProperties(f, DebugDump); + PObject = (TDSSObject*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + PObject = (TDSSObject*) DSSObjs[ActiveActor].Get_First(); + while(PObject != nullptr) + { + PObject->DumpProperties(f, DebugDump); + PObject = (TDSSObject*) DSSObjs[ActiveActor].Get_Next(); + } + } + catch (std::exception &e) + { + DoErrorMsg("DoPropertyDump - Problem writing file.", (std::string) e.what(), "File may be read only, in use, or disk full?", 257); + } + ActiveCircuit[ActiveActor]->Solution->DumpProperties(f, DebugDump); + } + } +/* } + __finally + {*/ + CloseFile(f); + } /*TRY*/ + catch (...) + { + // + } + FireOffEditor(GetOutputDirectory() + CircuitName_[ActiveActor] + "PropertyDump.Txt"); + return result; +} + + +//---------------------------------------------------------------------------- + +void Set_Time() +{ + double TimeArray[2/*# range 1..2*/]{}; + Parser[ActiveActor]->ParseAsVector(2, (pDoubleArray) TimeArray); + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + with0->DynaVars.intHour = (int) Round(TimeArray[1 - 1]); + with0->DynaVars.T = TimeArray[2 - 1]; + with0->Update_dblHour(); + } +} + +// for interpreting time specified as an array "hour, sec" + + +//---------------------------------------------------------------------------- + +void SetActiveCircuit(const String cktname) +{ + TDSSCircuit* pCkt = nullptr; + pCkt = (TDSSCircuit*) Circuits.Get_First(); + while(pCkt != nullptr) + { + if(CompareText(pCkt->Get_Name(), cktname) == 0) + { + ActiveCircuit[ActiveActor] = pCkt; + return; + } + pCkt = (TDSSCircuit*) Circuits.Get_Next(); + } + + // IF none is found, just leave as is after giving error + DoSimpleMsg(String("Error! No circuit named \"") + cktname + + "\" found." + + CRLF + + "Active circuit not changed.", 258); +} + +/*-------------------------------------------*/ + +void DoLegalVoltageBases() +{ + pDoubleArray Dummy; + int i = 0; + int Num = 0; + Dummy = (pDoubleArray)malloc(sizeof(double) * 200); // Big Buffer + Num = Parser[ActiveActor]->ParseAsVector(200, Dummy); + /*Parsing zero-fills the array*/ + + /*LegalVoltageBases is a zero-terminated array, so we have to allocate + one more than the number of actual values*/ + /*# with ActiveCircuit[ActiveActor] do */ + { + + int stop = 0; + ActiveCircuit[ActiveActor]->LegalVoltageBases.resize(static_cast>::size_type>(Num) + 1); + for (stop = Num + 1, i = 1; i <= stop; i++) + { + ActiveCircuit[ActiveActor]->LegalVoltageBases[static_cast>::size_type>(i) - 1] = Dummy[i - 1]; + } + } + free(Dummy); +} + + + +//---------------------------------------------------------------------------- + +int DoOpenCmd() +{ + int result = 0; + int RetVal = 0; + int Terminal = 0; + int Conductor = 0; + String ParamName; + +// syntax: "Open class.name term=xx cond=xx" +// IF cond is omitted, all conductors are opened. + RetVal = SetActiveCktElement(); + if(RetVal > 0) + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Terminal = Parser[ActiveActor]->MakeInteger_(); + ParamName = Parser[ActiveActor]->GetNextParam(); + Conductor = Parser[ActiveActor]->MakeInteger_(); + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ActiveTerminal(Terminal); + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ConductorClosed(Conductor, ActiveActor, false); + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + SetActiveBus(StripExtension(with1->GetBus(with1->get_FActiveTerminal()))); + } + } + } + else + { + DoSimpleMsg(String("Error in Open Command: Circuit Element Not Found.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 259); + } + result = 0; + return result; +} +// Opens a terminal and conductor of a ckt Element + + + + +//---------------------------------------------------------------------------- + +int DoCloseCmd() +{ + int result = 0; + int RetVal = 0; + int Terminal = 0; + int Conductor = 0; + String ParamName; + +// syntax: "Close class.name term=xx cond=xx" +// IF cond is omitted, all conductors are opened + RetVal = SetActiveCktElement(); + if(RetVal > 0) + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Terminal = Parser[ActiveActor]->MakeInteger_(); + ParamName = Parser[ActiveActor]->GetNextParam(); + Conductor = Parser[ActiveActor]->MakeInteger_(); + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ActiveTerminal(Terminal); + ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Set_ConductorClosed(Conductor, ActiveActor, true); + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + SetActiveBus(StripExtension(with1->GetBus(with1->get_FActiveTerminal()))); + } + } + } + else + { + DoSimpleMsg(String("Error in Close Command: Circuit Element Not Found.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 260); + } + result = 0; + return result; +} +// Closes a terminal and conductor of a ckt Element + + +//---------------------------------------------------------------------------- + +int DoResetCmd(int ActorID) +{ + int result = 0; + String ParamName; + String Param; + result = 0; + + // Obtener el siguiente parámetro e intentar interpretarlo como un nombre de archivo + ParamName = Parser[ActorID]->GetNextParam(); + Param = UpperCase(Parser[ActorID]->MakeString_()); + if (Param.size() == 0) + { + DoResetMonitors(ActorID); + DoResetMeters(ActorID); + DoResetFaults(); + DoResetControls(); + ClearEventLog(); + ClearErrorLog(); + DoResetKeepList(); + } + else + { + switch (Param[0]) + { + case L'M': + switch (Param[1]) + { + case L'O': /* Monitor */ + DoResetMonitors(ActorID); + break; + case L'E': /* Meter */ + DoResetMeters(ActorID); + break; + default: + // Código de caso desconocido + break; + } + break; + case L'F': /* Faults */ + DoResetFaults(); + break; + case L'C': /* Controls */ + DoResetControls(); + break; + case L'E': /* EventLog and ErrorLog */ + ClearEventLog(); + ClearErrorLog(); + break; + case L'K': + DoResetKeepList(); + break; + default: + DoSimpleMsg(String("Unknown argument to Reset Command: \"") + Param + "\"", 261); + break; + } + } + + return result; +} + + +void MarkCapandReactorBuses() +{ + TDSSClass* pClass = nullptr; + TCapacitorObj* pCapElement = nullptr; + TReactorObj* pReacElement = nullptr; + int ObjRef = 0; +/*Mark all buses as keepers if there are capacitors or reactors on them*/ + pClass = (TDSSClass*) GetDSSClassPtr("capacitor"); + if(pClass != nullptr) + { + ObjRef = pClass->Get_First(); + while(ObjRef > 0) + { + pCapElement = ((TCapacitorObj*) ActiveDSSObject[ActiveActor]); + if(pCapElement->IsShunt) + { + if(pCapElement->Get_Enabled()) + ActiveCircuit[ActiveActor]->Buses[static_cast(pCapElement->Terminals[0].BusRef) - 1]->Keep = true; + } + ObjRef = pClass->Get_Next(); + } + } + + /*Now Get the Reactors*/ + pClass = (TDSSClass*)GetDSSClassPtr("reactor"); + if(pClass != nullptr) + { + ObjRef = pClass->Get_First(); + while(ObjRef > 0) + { + pReacElement = ((TReactorObj*) ActiveDSSObject[ActiveActor]); + if(pReacElement->IsShunt) + try + { + if(pReacElement->Get_Enabled()) + ActiveCircuit[ActiveActor]->Buses[static_cast>::size_type>(pReacElement->Terminals[0].BusRef) - 1]->Keep = true; + } + catch (std::exception &e) + { + { + DoSimpleMsg(Format("%s %s Reactor=%s Bus No.=%d ", + e.what(), CRLF.c_str(), pReacElement->get_Name().c_str(), (int)(pReacElement->NodeRef)[0]), 9999); + break; + } + } + ObjRef = pClass->Get_Next(); + } + } +} + +//---------------------------------------------------------------------------- + +int DoReduceCmd() +{ + int result = 0; + TEnergyMeterObj* MetObj = nullptr; + TEnergyMeter* MeterClass = nullptr; + String ParamName = "", + Param = ""; + int DevClassIndex = 0; + + // Get next parm and try to interpret as a file name + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + + /*Mark Capacitor and Reactor buses as Keep so we don't lose them*/ + MarkCapandReactorBuses(); + if(Param.size() == 0) + Param = "A"; + switch(Param[0]) + { + case L'A': + { + MetObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + while(MetObj != nullptr) + { + MetObj->ReduceZone(ActiveActor); + MetObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + } + break; + /*Reduce a specific meter*/ + default: + DevClassIndex = ClassNames[ActiveActor].Find("energymeter"); + if(DevClassIndex > 0) + { + MeterClass = (TEnergyMeter*) DSSClassList[ActiveActor].Get(DevClassIndex); + if( ( (TDSSClass*) MeterClass )->SetActive(Param)) // Try to set it active + { + MetObj = ((TEnergyMeterObj*) ((TDSSClass*)MeterClass)->GetActiveObj()); + MetObj->ReduceZone(ActiveActor); + } + else + DoSimpleMsg(String("EnergyMeter \"") + Param + "\" not found.", 262); + } + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoResetMonitors(int ActorID) +{ + int result = 0; + TMonitorObj* pMon = nullptr; + /*# with ActiveCircuit[ActorID] do */ + { + + pMon = (TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First(); + while(pMon != nullptr) + { + pMon->ResetIt(ActorID); + pMon = (TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next(); + } + result = 0; + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoFileEditCmd() +{ + int result = 0; + String ParamName; + String Param; + result = 0; + + // Get next parm and try to interpret as a file name + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(FileExists(Param)) + FireOffEditor(Param); + else + { + GlobalResult = String("File \"") + Param + "\" does not exist."; + result = 1; + } + return result; +} + +//---------------------------------------------------------------------------- + +void ParseObjName(const String FullName, String& ObjName, String& PropName) +{ + int DotPos1 = 0; + int DotPos2 = 0; + DotPos1 = Pos(".", FullName); + switch(DotPos1) + { + case 0: + { + ObjName = ""; + PropName = FullName; + } + break; + default: + PropName = FullName.substr(DotPos1, (FullName.size() - DotPos1)); + DotPos2 = Pos(".", PropName); + switch(DotPos2) + { + case 0: + { + ObjName = FullName.substr(0, static_cast(DotPos1) - 1); + } + break; + default: + ObjName = FullName.substr(0, static_cast(DotPos1) + DotPos2 - 1); + PropName = PropName.substr(DotPos2, (PropName.size() - DotPos2)); + break; + } + break; + } +} + +/* Parse strings such as + + 1. Classname.Objectname,Property (full name) + 2. Objectname.Property (classname omitted) + 3. Property (classname and objectname omitted +*/ + +int DoQueryCmd() +{ + int result = 0, + propIndex = 0; + String ParamName = "", + Param = "", + ObjName = "", + PropName = ""; + + + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + ParseObjName(Param, ObjName, PropName); + if(CompareText(ObjName, "solution") == 0) // special for solution + { + ActiveDSSClass[ActiveActor] = SolutionClass[ActiveActor]; + ActiveDSSObject[ActiveActor] = ActiveCircuit[ActiveActor]->Solution; + } + else + + // Set Object Active + { + Parser[ActiveActor]->SetCmdString(String("\"") + ObjName + "\""); + DoSelectCmd(); + } + + // Put property value in global VARiable + propIndex = ActiveDSSClass[ActiveActor]->PropertyIndex(PropName); + if(propIndex > 0) + GlobalPropertyValue = ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->GetPropertyValue(propIndex); + else + GlobalPropertyValue = "Property Unknown"; + GlobalResult = GlobalPropertyValue; + if(LogQueries) + WriteQueryLogFile(Param, GlobalResult); // write time-stamped query + return result; +} +/* ? Command */ +/* Syntax: ? Line.Line1.R1*/ + +//---------------------------------------------------------------------------- + +int DoResetMeters(int ActorID) +{ + int result = 0; + result = 0; + EnergyMeterClass[ActorID]->ResetAll(ActorID); + return result; +} + + +//---------------------------------------------------------------------------- + +int DoNextCmd() +{ + int result = 0; + String ParamName; + String Param; + result = 0; + + // Get next parm and try to interpret as a file name + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + switch(UpCase(Param[1])) + { + case L'Y':/*Year*/ + with0->Set_Year(with0->get_Fyear() + 1); + break;/*Hour*/ + case L'H': + ++with0->DynaVars.intHour; + break;/*Time*/ + case L'T': + with0->Increment_time(); + break; + default: + ; + break; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +void DoAboutBox() +{ + if(NoFormsAllowed) + return; + ShowAboutBox(); +} + +//---------------------------------------------------------------------------- + +int DoSetVoltageBases(int ActorID) +{ + int result = 0; + result = 0; + ActiveCircuit[ActiveActor]->Solution->SetVoltageBases(ActorID); + return result; +} + + + +//---------------------------------------------------------------------------- + +int AddObject(const String ObjType, const String Name) +{ + int result = 0; + result = 0; + + // Search for class IF not already active + // IF nothing specified, LastClassReferenced remains + if(CompareText(ObjType, ActiveDSSClass[ActiveActor]->get_myClass_name()) != 0) + LastClassReferenced[ActiveActor] = ClassNames[ActiveActor].Find(ObjType); + switch(LastClassReferenced[ActiveActor]) + { + case 0: + { + DoSimpleMsg(String("New Command: Object Type \"") + ObjType + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 263); + result = 0; + return result; + }/*Error*/ + + // intrinsic and user Defined models + // Make a new circuit element + default: + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + + // Name must be supplied + if(Name.size() == 0) + { + DoSimpleMsg(String("Object Name Missing") + CRLF + Parser[ActiveActor]->get_CmdBuffer(), 264); + return result; + } + + + // now let's make a new object or set an existing one active, whatever the case + switch(ActiveDSSClass[ActiveActor]->DSSClassType) + { + case DSS_OBJECT: + if(!ActiveDSSClass[ActiveActor]->SetActive(Name)) + // These can be added WITHout having an active circuit + // Duplicates not allowed in general DSS objects; + // If the name is the same, Edit is executed instead of New + { + result = ActiveDSSClass[ActiveActor]->NewObject(Name); + DSSObjs[ActiveActor].Add(ActiveDSSObject[ActiveActor]); // Stick in pointer list to keep track of it + } + break; + // These are circuit elements + default: + if(ActiveActor == 0) + { + DoSimpleMsg("You Must Create a circuit first: \"new circuit.yourcktname\"", 265); + return result; + } + + // IF Object already exists. Treat as an Edit IF dulicates not allowed + if(ActiveCircuit[ActiveActor]->DuplicatesAllowed) + { + result = ActiveDSSClass[ActiveActor]->NewObject(Name); // Returns index into this class + ActiveCircuit[ActiveActor]->AddCktElement(result); // Adds active object to active circuit + } + else + // Check to see if we can set it active first + { + if(!ActiveDSSClass[ActiveActor]->SetActive(Name)) + { + result = ActiveDSSClass[ActiveActor]->NewObject(Name); // Returns index into this class + ActiveCircuit[ActiveActor]->AddCktElement(result); // Adds active object to active circuit + } + else + { + DoSimpleMsg(String("Warning: Duplicate new element definition: \"") + ActiveDSSClass[ActiveActor]->get_myClass_name() + + "." + + Name + + "\"" + + CRLF + + "Element being redefined.", 266); + } + } + break; + } + + // ActiveDSSObject now points to the object just added + // IF a circuit element, ActiveCktElement in ActiveCircuit[ActiveActor] is also set + if(result > 0) + ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->ClassIndex = result; + ActiveDSSClass[ActiveActor]->Edit(ActiveActor); // Process remaining instructions on the command line + break; + } + return result; +} + + +//---------------------------------------------------------------------------- + +int EditObject(const String ObjType, const String Name) +{ + int result = 0; + result = 0; + LastClassReferenced[ActiveActor] = ClassNames[ActiveActor].Find(ObjType); + switch(LastClassReferenced[ActiveActor]) + { + case 0: + { + DoSimpleMsg(String("Edit Command: Object Type \"") + ObjType + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 267); + result = 0; + return result; + }/*Error*/ + + // intrinsic and user Defined models + // Edit the DSS object + default: + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if(ActiveDSSClass[ActiveActor]->SetActive(Name)) + { + result = ActiveDSSClass[ActiveActor]->Edit(ActiveActor); // Edit the active object + } + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoSetkVBase() +{ + int result = 0; + String ParamName; + String Busname; + double kVValue = 0.0; + +// Parse off next two items on line + ParamName = Parser[ActiveActor]->GetNextParam(); + Busname = LowerCase(Parser[ActiveActor]->MakeString_()); + ParamName = Parser[ActiveActor]->GetNextParam(); + kVValue = Parser[ActiveActor]->MakeDouble_(); + + // Now find the bus and set the value + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->ActiveBusIndex = ActiveCircuit[ActiveActor]->BusList.Find(Busname); + if(ActiveCircuit[ActiveActor]->ActiveBusIndex > 0) + { + if(CompareText(ParamName, "kvln") == 0) + ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]->kVBase = kVValue; + else + ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]->kVBase = kVValue / SQRT3; + result = 0; + ActiveCircuit[ActiveActor]->Solution->VoltageBaseChanged = true; + // Solution.SolutionInitialized := FALSE; // Force reinitialization + } + else + { + result = 1; + AppendGlobalResult(String("Bus ") + Busname + " Not Found."); + } + } + return result; +} + + + +//---------------------------------------------------------------------------- + +void DoAutoAddBusList(const String s) +{ + String dummy; + String Parmname; + String Param; + String S2; + TTextRec f = {}; + ActiveCircuit[ActiveActor]->AutoAddBusList.Clear(); + + // Load up auxiliary parser to reparse the array list or file name + AuxParser[ActiveActor]->SetCmdString(s); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + + /*Syntax can be either a list of bus names or a file specification: File= ...*/ + if(CompareText(Parmname, "file") == 0) + // load the list from a file + { + try + { + AssignFile(f, Param); + Reset(f); + IOResultToException(); + while(!Eof(f)) + // Fixed 7/8/01 to handle all sorts of bus names + { + ReadLn(f, S2); + AuxParser[ActiveActor]->SetCmdString(S2); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + ActiveCircuit[ActiveActor]->AutoAddBusList.Add(Param); + } + CloseFile(f); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error trying to read bus list file. Error is: ") + (std::string) e.what(), 268); + } + } + else + + + // Parse bus names off of array list + { + while(Param.size() > 0) + { + ActiveCircuit[ActiveActor]->AutoAddBusList.Add(Param); + dummy = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } +} + +//---------------------------------------------------------------------------- + +void DoKeeperBusList(const String s) +{ + String Parmname; + String Param; + String S2; + TTextRec f = {}; + int iBus = 0; + + // Load up auxiliary parser to reparse the array list or file name + AuxParser[ActiveActor]->SetCmdString(s); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + + /*Syntax can be either a list of bus names or a file specification: File= ...*/ + if(CompareText(Parmname, "file") == 0) + // load the list from a file + { + try + { + AssignFile(f, Param); + Reset(f); + IOResultToException(); + while(!Eof(f)) + // Fixed 7/8/01 to handle all sorts of bus names + { + ReadLn(f, S2); + AuxParser[ActiveActor]->SetCmdString(S2); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + + iBus = ActiveCircuit[ActiveActor]->BusList.Find(Param); + if(iBus > 0) + ActiveCircuit[ActiveActor]->Buses[static_cast(iBus) - 1]->Keep = true; + } + } + CloseFile(f); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error trying to read bus list file \"+param+\". Error is: ") + (std::string) e.what(), 269); + } + } + else + + + // Parse bus names off of array list + { + while(Param.size() > 0) + { + /*# with ActiveCircuit[ActiveActor] do */ + { + + iBus = ActiveCircuit[ActiveActor]->BusList.Find(Param); + if(iBus > 0) + ActiveCircuit[ActiveActor]->Buses[static_cast(iBus) - 1]->Keep = true; + } + String dummy = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } +} + + +// Created 4/25/03 + +/*Set Keep flag on buses found in list so they aren't eliminated by some reduction + algorithm. This command is cumulative. To clear flag, use Reset Keeplist*/ + +//---------------------------------------------------------------------------- + +int DocktlossesCmd() +{ + int result = 0; + complex LossValue = {}; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + { + GlobalResult = ""; + LossValue = ActiveCircuit[ActiveActor]->Get_Losses(ActiveActor); + GlobalResult = Format("%10.5g, %10.5g", LossValue.re * 0.001, LossValue.im * 0.001); + } + else + GlobalResult = "No Active Circuit."; + return result; +} + +int DocurrentsCmd() +{ + int result = 0; + pComplexArray cBuffer = nullptr; // Inicializar a nullptr para evitar basura en el puntero + int NValues = 0; + int i = 0; + result = 0; + if (ActiveCircuit[ActiveActor] != nullptr) + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + int stop = 0; + NValues = with0->Get_NConds() * with0->Get_NTerms(); + GlobalResult = ""; + cBuffer = (pComplexArray)malloc(sizeof(complex) * NValues); + if (cBuffer != nullptr) // Verificar si malloc pudo asignar memoria + { + with0->GetCurrents(cBuffer, ActiveActor); + for (stop = NValues, i = 1; i <= stop; i++) + { + GlobalResult = GlobalResult + Format("%10.5g, %6.1f,", cabs(cBuffer[i - 1]), cdang(cBuffer[i - 1])); + } + free(cBuffer); // Liberar la memoria asignada por malloc + } + else + { + GlobalResult = "Memory allocation failed."; // Si malloc no pudo asignar memoria + } + } + else + { + GlobalResult = "No Active Circuit."; + } + return result; +} + + +int DoNodeListCmd() +{ + int result = 0; + int NValues = 0; + int i = 0; + String CktElementName; + String s; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + { + s = Parser[ActiveActor]->GetNextParam(); + CktElementName = Parser[ActiveActor]->MakeString_(); + if(CktElementName.size() > 0) + SetObject(CktElementName); + if(ASSIGNED(ActiveCircuit[ActiveActor]->get_FActiveCktElement())) + /*# with ActiveCircuit[ActiveActor].ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + int stop = 0; + NValues = with0->Get_NConds() * with0->Get_NTerms(); + GlobalResult = ""; + for(stop = NValues, i = 1; i <= stop; i++) + { + GlobalResult = GlobalResult + Format("%d, ", GetNodeNum(with0->NodeRef[static_cast(i) - 1])); + } + } + else + GlobalResult = "No Active Circuit."; + } + return result; +} + +int DolossesCmd() +{ + int result = 0; + complex LossValue = {}; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->get_FActiveCktElement() != nullptr) + { + GlobalResult = ""; + LossValue = ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Get_Losses(ActiveActor); + GlobalResult = Format("%10.5g, %10.5g", LossValue.re * 0.001, LossValue.im * 0.001); + } + } + else + GlobalResult = "No Active Circuit."; + return result; +} + +int DophaselossesCmd() +{ + int result = 0; + pComplexArray cBuffer = nullptr; + int NValues = 0; + int i = 0; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor].ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + int stop = 0; + NValues = with0->Get_NPhases(); + cBuffer = (pComplexArray) malloc(sizeof(complex) * NValues); + GlobalResult = ""; + with0->GetPhaseLosses(NValues, cBuffer, ActiveActor); + for(stop = NValues, i = 1; i <= stop; i++) + { + GlobalResult = GlobalResult + + Format("%10.5g, %10.5g,", cBuffer[i - 1].re * 0.001, cBuffer[i - 1].im * 0.001); + } + } + else + GlobalResult = "No Active Circuit."; + + free(cBuffer); + + return result; +} + +// Returns Phase losses in kW, kVar + +int DopowersCmd(int Total) +{ + int result = 0; + pComplexArray cBuffer; + int NValues = 0; + int myInit = 0; + int myEnd = 0; + int j = 0; + int i = 0; + std::vector myBuffer; + // If Total = 0, returns the powers per phase + // If Total = 1, returns the power sum at each terminal + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor].ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + NValues = with0->Get_NConds() * with0->Get_NTerms(); + GlobalResult = ""; + cBuffer = (pComplexArray) malloc(sizeof(complex) * NValues); + with0->GetPhasePower(cBuffer, ActiveActor); + if(Total == 0) + { + int stop = 0; + for(stop = NValues, i = 1; i <= stop; i++) + { + GlobalResult = GlobalResult + + Format("%10.5g, %10.5g,", cBuffer[i - 1].re * 0.001, cBuffer[i - 1].im * 0.001); + } + } + else + { + int stop = 0; + myBuffer.resize( with0->Get_NTerms() ); + for(stop = with0->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + myBuffer[static_cast(j) - 1] = cmplx(0.0, 0.0); + myInit = (j - 1) * with0->Get_NConds() + 1; + myEnd = with0->Get_NConds() * j; + for(stop1 = myEnd, i = myInit; i <= stop1; i++) + { + myBuffer[static_cast(j) - 1] = cadd(myBuffer[static_cast(j) - 1], cBuffer[i - 1]); + } + GlobalResult = GlobalResult + + Format("%10.5g, %10.5g,", myBuffer[static_cast(j) - 1].re * 0.001, myBuffer[static_cast(j) - 1].im * 0.001); + } + } + free(cBuffer); + } + else + GlobalResult = "No Active Circuit"; + return result; +} + +int DoseqcurrentsCmd() +{ + int result = 0; + int NValues = 0; + int i = 0; + int j = 0; + int k = 0; + complex IPh[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + complex I012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + pComplexArray cBuffer; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->get_FActiveCktElement() != nullptr) + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + GlobalResult = ""; + if(with1->Get_NPhases() < 3) + { + int stop = 0; + for(stop = 3 * with1->Get_NTerms() - 1, i = 0; i <= stop; i++) + { // Signify n/A + GlobalResult = GlobalResult + " -1.0,"; + } + } + else + { + int stop = 0; + NValues = with1->Get_NConds() * with1->Get_NTerms(); + cBuffer = (pComplexArray)malloc(sizeof(complex) * NValues); + with1->GetCurrents(cBuffer, ActiveActor); + for(stop = with1->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + k = (j - 1) * with1->Get_NConds(); + for(stop1 = 3, i = 1; i <= stop1; i++) + { + IPh[i - 1] = cBuffer[k + i - 1]; + } + Phase2SymComp(&IPh[0], &I012[0]); + for(stop1 = 3, i = 1; i <= stop1; i++) + { + GlobalResult = GlobalResult + Format("%10.5g, ", cabs(I012[i - 1])); + } + } + free(cBuffer); + } /*ELSE*/ + } /*WITH ActiveCktElement*/ + } /*IF/WITH ActiveCircuit[ActiveActor]*/ + else + GlobalResult = "No Active Circuit"; + return result; +} +// All sequence currents of active ciruit element +// returns magnitude only. + +int DoseqpowersCmd() +{ + int result = 0; + int NValues = 0; + int i = 0; + int j = 0; + int k = 0; + complex s = cmplx(0,0); + complex Vph[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + V012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + IPh[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }, + I012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + vector cBuffer; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->get_FActiveCktElement() != nullptr) + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + GlobalResult = ""; + if(with1->Get_NPhases() < 3) + { + int stop = 0; + for(stop = 2 * 3 * with1->Get_NTerms() - 1, i = 0; i <= stop; i++) + { // Signify n/A + GlobalResult = GlobalResult + "-1.0, "; + } + } + else + { + int stop = 0; + NValues = with1->Get_NConds() * with1->Get_NTerms(); + cBuffer.resize(NValues + 1); + with1->GetCurrents(&cBuffer[0], ActiveActor); + for(stop = with1->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + k = (j - 1) * with1->Get_NConds(); + for(stop1 = 3, i = 1; i <= stop1; i++) + { + Vph[i - 1] = ActiveCircuit[ActiveActor]->Solution->NodeV[(with1->Terminals[static_cast(j) - 1].TermNodeRef)[i - 1]]; + } + for(stop1 = 3, i = 1; i <= stop1; i++) + { + IPh[i - 1] = cBuffer[(k + i) - 1]; + } + Phase2SymComp(&IPh[0], &I012[0]); + Phase2SymComp(&Vph[0], &V012[0]); + for(stop1 = 3, i = 1; i <= stop1; i++) + { + s = cmul(V012[i - 1], conjg(I012[i - 1])); + GlobalResult = GlobalResult + + Format("%10.5g, %10.5g,", s.re * 0.003, s.im * 0.003); // 3-phase kW conversion + } + } + } + cBuffer.resize(0); + } + } + else + GlobalResult = "No Active Circuit"; + return result; +} +// All seq Powers of active 3-phase ciruit element +// returns kW + j kvar + +int DoseqvoltagesCmd() +{ + int result = 0; + int NValues = 0; + int i = 0; + int j = 0; + int k = 0; + int n = 0; + complex Vph[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + complex V012[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + String s; + result = 0; + NValues = -1; // unassigned, for exception message + n = -1; // unassigned, for exception message + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->get_FActiveCktElement() != nullptr) + /*# with ActiveCktElement do */ + { + auto with1 = ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + if(with1->Get_Enabled()) + { + try + { + NValues = with1->Get_NPhases(); + GlobalResult = ""; + if(NValues < 3) + { + int stop = 0; + for(stop = 3 * with1->Get_NTerms(), i = 1; i <= stop; i++) + { // Signify n/A + GlobalResult = GlobalResult + "-1.0, "; + } + } + else + { + int stop = 0; + for(stop = with1->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + k = (j - 1) * with1->Get_NConds(); + for(stop1 = 3, i = 1; i <= stop1; i++) + { + Vph[i - 1] = (ActiveCircuit[ActiveActor]->Solution->NodeV)[(with1->NodeRef)[static_cast(i) + k - 1]]; + } + Phase2SymComp(&Vph[0], &V012[0]); // Compute Symmetrical components + for(stop1 = 3, i = 1; i <= stop1; i++) + { // Stuff it in the result + GlobalResult = GlobalResult + Format("%10.5g, ", cabs(V012[i - 1])); + } + } + } + } + catch (std::exception &e) + { + { + s = (std::string) e.what() + + CRLF + + "Element=" + + ( (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement() )->get_Name() + + CRLF + + "Nvalues=" + + IntToStr(NValues) + + CRLF + + "Nterms=" + + IntToStr(with1->Get_NTerms()) + + CRLF + + "NConds =" + + IntToStr(with1->Get_NConds()) + + CRLF + + "noderef=" + + IntToStr(n); + DoSimpleMsg(s, 270); + } + } + } + else + GlobalResult = "Element Disabled"; + } // Disabled + } + else + GlobalResult = "No Active Circuit"; + return result; +} + +// All voltages of active ciruit element +// magnitude only +// returns a set of seq voltages (3) for each terminal + + +//---------------------------------------------------------------------------- + +int DovoltagesCmd(bool PerUnit) +{ + int result = 0; + int i = 0; + complex Volts = {}; + TDSSBus* ActiveBus = nullptr; + double Vmag = 0.0; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->ActiveBusIndex != 0) + { + int stop = 0; + ActiveBus = ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]; + GlobalResult = ""; + for(stop = ActiveBus->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + Volts = (ActiveCircuit[ActiveActor]->Solution->NodeV)[ActiveBus->GetRef(i)]; + Vmag = cabs(Volts); + if(PerUnit && (ActiveBus->kVBase > 0.0)) + { + Vmag = Vmag * 0.001 / ActiveBus->kVBase; + GlobalResult = GlobalResult + + Format("%10.5g, %6.1f, ", Vmag, cdang(Volts)); + } + else + GlobalResult = GlobalResult + + Format("%10.5g, %6.1f, ", Vmag, cdang(Volts)); + } + } + else + GlobalResult = "No Active Bus."; + } + else + GlobalResult = "No Active Circuit."; + return result; +} +// Bus Voltages at active terminal + + +//---------------------------------------------------------------------------- + +int DoZscCmd(bool Zmatrix) +{ + int result = 0; + int i = 0; + int j = 0; + TDSSBus* ActiveBus = nullptr; + complex Z = {}; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->ActiveBusIndex != 0) + { + ActiveBus = ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]; + GlobalResult = ""; + if(ActiveBus->Zsc.Norder == 0) + return result; + /*# with ActiveBus do */ + { + auto with1 = ActiveBus; + int stop = 0; + for(stop = with1->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = with1->get_FNumNodesThisBus(), j = 1; j <= stop1; j++) + { + if(Zmatrix) + Z = with1->Zsc.GetElement(i, j); + else + Z = with1->Ysc.GetElement(i, j); + GlobalResult = GlobalResult + Format("%-.5g, %-.5g, ", Z.re, Z.im); + } + } + } + } + else + GlobalResult = "No Active Bus."; + } + else + GlobalResult = "No Active Circuit."; + return result; +} +// Bus Short Circuit matrix + + + +//---------------------------------------------------------------------------- + +int DoZsc012Cmd() +{ + int result = 0; + int i = 0; + TDSSBus* ActiveBus = nullptr; + complex Z0 = {}; + complex Z1 = {}; + complex Z2 = {}; + pComplexArray Temp1 = nullptr; + pComplexArray temp2 = nullptr; + TcMatrix* Zsc012Temp = nullptr; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->ActiveBusIndex != 0) + { + ActiveBus = ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]; + GlobalResult = ""; + if (ActiveBus->Zsc.Norder == 0) + return result; + /*# with ActiveBus do */ + { + auto with1 = ActiveBus; + if(with1->get_FNumNodesThisBus() == 3) + + // Compute ZSC012 for 3-phase buses else leave it zeros + // ZSC012 = Ap2s Zsc As2p + { + Zsc012Temp = with1->Zsc.MtrxMult(As2p); // temp for intermediate result + with1->Zsc012 = *(Ap2s->MtrxMult(Zsc012Temp)); + // Cleanup + delete Zsc012Temp; + + + /*Just return diagonal elements only*/ + Z0 = with1->Zsc012.GetElement(1, 1); + Z1 = with1->Zsc012.GetElement(2, 2); + Z2 = with1->Zsc012.GetElement(3, 3); + GlobalResult = GlobalResult + + Format("Z0, (%-.5g, +j %-.5g), ", Z0.re, Z0.im) + + CRLF; + GlobalResult = GlobalResult + + Format("Z1, (%-.5g, +j %-.5g), ", Z1.re, Z1.im) + + CRLF; + GlobalResult = GlobalResult + + Format("Z2, (%-.5g, +j %-.5g), ", Z2.re, Z2.im); + } + else + GlobalResult = "Not a 3-phase bus. Cannot compute Symmetrical Component matrix."; + } + } + else + GlobalResult = "No Active Bus."; + } + else + GlobalResult = "No Active Circuit."; + return result; +} +// Bus Short Circuit matrix + + +//---------------------------------------------------------------------------- + +int DoZsc10Cmd() +{ + int result = 0; + TDSSBus* ActiveBus = nullptr; + complex Z = {}; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->ActiveBusIndex != 0) + { + ActiveBus = ActiveCircuit[ActiveActor]->Buses[static_cast(ActiveCircuit[ActiveActor]->ActiveBusIndex) - 1]; + GlobalResult = ""; + if (ActiveBus->Zsc.Norder == 0) + return result; + /*# with ActiveBus do */ + { + auto with1 = ActiveBus; + Z = with1->Get_Zsc1(); + GlobalResult = GlobalResult + + Format("Z1, %-.5g, %-.5g, ", Z.re, Z.im) + + CRLF; + Z = with1->Get_Zsc0(); + GlobalResult = GlobalResult + Format("Z0, %-.5g, %-.5g, ", Z.re, Z.im); + } + } + else + GlobalResult = "No Active Bus."; + } + else + GlobalResult = "No Active Circuit."; + return result; +} +// Bus Short Circuit matrix + + + +//---------------------------------------------------------------------------- + +int DoAllocateLoadsCmd(int ActorID) +{ + int result = 0, + iterCount = 0; + TEnergyMeterObj* pMeter = nullptr; + TSensorObj* pSensor = nullptr; + + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + auto with0 = ActiveCircuit[ActorID]; + with0->Set_LoadMultiplier(1.0); // Property .. has side effects + /*# with Solution do */ + { + auto with1 = with0->Solution; + if(with1->Get_SolMode() != SNAPSHOT) + with1->Set_Mode(SNAPSHOT); // Resets meters, etc. if not in snapshot mode + with1->Solve(ActorID); /*Make guess based on present allocationfactors*/ + } + + /*Allocation loop -- make MaxAllocationIterations iterations*/ + for(stop = MaxAllocationIterations, iterCount = 1; iterCount <= stop; iterCount++) + { + + /*Do EnergyMeters*/ + pMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_First(); + while(pMeter != nullptr) + { + pMeter->CalcAllocationFactors(ActorID); + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + } + + /*Now do other Sensors*/ + pSensor = (TSensorObj*)with0->Sensors.Get_First(); + while(pSensor != nullptr) + { + pSensor->CalcAllocationFactors(ActorID); + pSensor = (TSensorObj*)with0->Sensors.Get_Next(); + } + + /*Now let the EnergyMeters run down the circuit setting the loads*/ + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_First(); + while(pMeter != nullptr) + { + pMeter->AllocateLoad(ActorID); + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_Next(); + } + with0->Solution->Solve(ActorID); /*Update the solution*/ + } + } + return result; +} + +/* Requires an EnergyMeter Object at the head of the feeder + Adjusts loads defined by connected kVA or kWh billing +*/ + +//---------------------------------------------------------------------------- + +void DoSetAllocationFactors(double X) +{ + TLoadObj* pLoad = nullptr; + if(X <= 0.0) + DoSimpleMsg("Allocation Factor must be greater than zero.", 271); + else + /*# with ActiveCircuit[ActiveActor] do */ + { + + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while(pLoad != nullptr) + { + pLoad->Set_kVAAllocationFactor(X); + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + } +} + +void DoSetCFactors(double X) +{ + TLoadObj* pLoad = nullptr; + if(X <= 0.0) + DoSimpleMsg("CFactor must be greater than zero.", 271); + else + /*# with ActiveCircuit[ActiveActor] do */ + { + + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while(pLoad != nullptr) + { + pLoad->Set_CFactor(X); + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + } +} + +//---------------------------------------------------------------------------- + +int DoHarmonicsList(const String s) +{ + int result = 0; + pDoubleArray Dummy; + int i = 0; + int Num = 0; + result = 0; + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + if(CompareText(s, "ALL") == 0) + with0->DoAllHarmonics = true; + else + { + int stop = 0; + with0->DoAllHarmonics = false; + Dummy = (pDoubleArray)malloc(sizeof(complex) * 100); + Num = Parser[ActiveActor]->ParseAsVector(100, Dummy); + /*Parsing zero-fills the array*/ + with0->HarmonicListSize = Num; + with0->HarmonicList = new double[ with0->HarmonicListSize ]; + for(stop = with0->HarmonicListSize, i = 1; i <= stop; i++) + { + (with0->HarmonicList)[i - 1] = (Dummy)[i - 1]; + } + free(Dummy); + } + } + return result; +} + + +//---------------------------------------------------------------------------- + +int DoFormEditCmd() +{ + int result = 0; + result = 0; + if(NoFormsAllowed) + return result; + DoSelectCmd(); // Select ActiveObject + if(ActiveDSSObject[ActiveActor] != nullptr) + { + ShowPropEditForm(); + } + else + { + DoSimpleMsg("Element Not Found.", 272); + result = 1; + } + return result; +} + + +//---------------------------------------------------------------------------- + +int DoMeterTotals() +{ + int result = 0; + int i = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + { + ActiveCircuit[ActiveActor]->TotalizeMeters(); + // Now export to global result + for (i = 0; i < NumEMRegisters; i++) + { + AppendGlobalResult(Format("%-.6g", ActiveCircuit[ActiveActor]->RegisterTotals[i])); + } + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoCapacityCmd() +{ + int result = 0; + int ParamPointer = 0; + String Param; + String ParamName; + result = 0; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + switch(ParamName[1]) + { + case L's': + ParamPointer = 1; + break; + case L'i': + ParamPointer = 2; + break; + default: + ParamPointer = 0; + break; + } + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Capacity Command", 273); + break; + case 1: + ActiveCircuit[ActiveActor]->CapacityStart = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + ActiveCircuit[ActiveActor]->CapacityIncrement = Parser[ActiveActor]->MakeDouble_(); + break; + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(ActiveCircuit[ActiveActor]->ComputeCapacity(ActiveActor)) // Totalizes EnergyMeters at End + { + GlobalResult = Format("%-.6g", (ActiveCircuit[ActiveActor]->RegisterTotals[3 - 1] + ActiveCircuit[ActiveActor]->RegisterTotals[19 - 1])); // Peak KW in Meters + AppendGlobalResult(Format("%-.6g", ActiveCircuit[ActiveActor]->get_FLoadMultiplier())); + } + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoClassesCmd() +{ + int result = 0; + int i = 0; + int stop = 0; + for(stop = NumIntrinsicClasses, i = 1; i <= stop; i++) + { + AppendGlobalResult(((TDSSClass*) DSSClassList[ActiveActor].Get(i))->get_myClass_name()); + } + result = 0; + return result; +} + +//---------------------------------------------------------------------------- + +int DoUserClassesCmd() +{ + int result = 0; + int i = 0; + result = 0; + if(NumUserClasses == 0) + { + AppendGlobalResult("No User Classes Defined."); + } + else + { + int stop = 0; + for(stop = DSSClassList[ActiveActor].get_myNumList(), i = NumIntrinsicClasses + 1; i <= stop; i++) + { + AppendGlobalResult(((TDSSClass*) DSSClassList[ActiveActor].Get(i))->get_myClass_name()); + } + } + return result; +} + +//---------------------------------------------------------------------------- + +int DoZscRefresh(int ActorID) +{ + int result = 0; + int j = 0; + result = 1; + try + { + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor].Solution do */ + { + + auto with1 = ActiveCircuit[ActiveActor]->Solution; + int stop = 0; + for(stop = ActiveCircuit[ActiveActor]->NumNodes, j = 1; j <= stop; j++) + { + (with1->Currents)[j - 1] = CZero; + } // Clear Currents array + if((ActiveCircuit[ActiveActor]->ActiveBusIndex >= 0) && (ActiveCircuit[ActiveActor]->ActiveBusIndex < ActiveCircuit[ActiveActor]->NumBuses)) + { + if(ActiveCircuit[ActiveActor]->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex]->Zsc.Norder == 0) + ActiveCircuit[ActiveActor]->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex]->AllocateBusQuantities(); + ComputeYsc(ActiveCircuit[ActiveActor]->ActiveBusIndex, ActorID); // Compute YSC for active Bus + result = 0; + } + } + } + catch (std::exception &e) + { + DoSimpleMsg(String("ZscRefresh Error: ") + (std::string) e.what() + CRLF, 274); + } + return result; +} + +int DoVarValuesCmd() +{ + int result = 0; + int i = 0; + // PcElem:TPCElement; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + /*Check if PCElement*/ + switch(( ( (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement() )->DSSObjType & BaseClassMask)) + { + case PC_ELEMENT: + /*# with ActiveCktElement as TPCElement do */ + { + auto with1 = (TPCElement*) ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + int stop = 0; + for(stop = with1->NumVariables(), i = 1; i <= stop; i++) + { + AppendGlobalResult(Format("%-.6g", with1->Get_Variable(i))); + } + } + break; + default: + AppendGlobalResult("Null"); + break; + } + } + return result; +} + +int DoValVarCmd() +{ + int result = 0; + String ParamName; + String Param; + int VarIndex = 0; + int propIndex = 0; + TPCElement* pcElem = nullptr; + result = 0; + + /*Check to make sure this is a PC Element. If not, return null string in global result*/ + if( ( ( (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement() )->DSSObjType & BaseClassMask) != PC_ELEMENT ) + GlobalResult = ""; + else + { + pcElem = (TPCElement*) ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + + /*Get next parameter on command line*/ + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + propIndex = 1; + if(ParamName.size() > 0) + switch(ParamName[1]) + { + case L'N': + propIndex = 1; + break; + case L'I': + propIndex = 2; + break; + default: + ; + break; + } + VarIndex = 0; + switch(propIndex) + { + case 1: + VarIndex = pcElem->LookupVariable(Param); + break; // Look up property index + case 2: + VarIndex = Parser[ActiveActor]->MakeInteger_(); + break; + default: + ; + break; + } + if((VarIndex > 0) && (VarIndex <= pcElem->NumVariables())) + GlobalResult = Format("%.8g", pcElem->Get_Variable(VarIndex)); + else + GlobalResult = ""; /*Invalid var name or index*/ + } + return result; +} + +/*Geg value of specified variable by name of index,*/ + +int DoVarNamesCmd() +{ + int result = 0; + int i = 0; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + /*Check if PCElement*/ + switch( ( ( (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement() )->DSSObjType & BaseClassMask)) + { + case PC_ELEMENT: + /*# with (ActiveCktElement as TPCElement) do */ + { + auto with1 = ((TPCElement*) ActiveCircuit[ActiveActor]->get_FActiveCktElement()); + int stop = 0; + for(stop = with1->NumVariables(), i = 1; i <= stop; i++) + { + AppendGlobalResult(with1->VariableName(i)); + } + } + break; + default: + AppendGlobalResult("Null"); + break; + } + } + return result; +} + +int DoBusCoordsCmd(bool SwapXY, int CoordType) +{ + int result = 0; + TTextRec f = {}; + String dummy; + String ParamName; + String Param; + String s; + String Busname; + int iB = 0; + int iLine = 0; + result = 0; + + /*Get next parameter on command line*/ + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + try + { + iLine = -1; + try + { + AssignFile(f, Param); + Reset(f); + IOResultToException(); + iLine = 0; + while(!Eof(f)) + { + ++iLine; + ReadLn(f, s); // Read line in from file + /*# with AuxParser[ActiveActor] do */ + { + // User Auxparser to parse line + auto with35 = AuxParser[ActiveActor]; + with35->SetCmdString(s); + dummy = with35->GetNextParam(); + Busname = with35->MakeString_(); + iB = ActiveCircuit[ActiveActor]->BusList.Find(Busname); + if(iB > 0) + { + /*# with ActiveCircuit[ActiveActor]->Buses^[iB] do */ + { + // Returns TBus object + if(CoordType == 0) // Standard buscoords + { + dummy = with35->GetNextParam(); + if(SwapXY) + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->y = with35->MakeDouble_(); + else + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->x = with35->MakeDouble_(); + dummy = with35->GetNextParam(); + if(SwapXY) + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->x = with35->MakeDouble_(); + else + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->y = with35->MakeDouble_(); + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->CoordDefined = true; + } + else + // GIS coords + { + dummy = with35->GetNextParam(); + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->lat = with35->MakeDouble_(); + dummy = with35->GetNextParam(); + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->longitude = with35->MakeDouble_(); + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->GISCoordDefined = true; + } + } + } + } + /*Else just ignore a bus that's not in the circuit*/ + } + /***CHANGE THIS ERROR MESSAGE***/ + } + catch (std::exception &e) + { + { + if(iLine == - 1) + DoSimpleMsg(String("Bus Coordinate file: \"") + Param + + "\" not found; " + + (std::string) e.what(), 275); + else + DoSimpleMsg(String("Bus Coordinate file: Error Reading Line ") + IntToStr(iLine) + + "; " + + (std::string) e.what(), 275); + } + } +/* } + __finally + {*/ + CloseFile(f); + } + catch (...) + { + // + } + return result; +} + +/* + Format of File should be + + Busname, x, y + + (x, y are real values) + + If SwapXY is true, x and y values are swapped + +*/ + +int DoMakePosSeq() +{ + int result = 0; + TDSSCktElement* CktElem = nullptr; + result = 0; + ActiveCircuit[ActiveActor]->PositiveSequence = true; + CktElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while(CktElem != nullptr) + { + CktElem->MakePosSequence(ActiveActor); + CktElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + return result; +} + +void DoSetReduceStrategy(const String s) +{ + + auto AtLeast = [&](int i, int j) -> int + { + int result = 0; + if(j < i) + result = i; + else + result = j; + return result; + }; + ActiveCircuit[ActiveActor]->ReductionStrategyString = s; + ActiveCircuit[ActiveActor]->ReductionStrategy = rsDefault; + if(s.size() == 0) + return; /*No option given*/ + switch(UpperCase(s)[0]) + { + case L'B': + ActiveCircuit[ActiveActor]->ReductionStrategy = rsBreakLoop; + break; + case L'D': + ActiveCircuit[ActiveActor]->ReductionStrategy = rsDefault; + break; /*Default*/ + case L'E': + ActiveCircuit[ActiveActor]->ReductionStrategy = rsDangling; + break; /*Ends*/ /*Laterals*/ + case L'L': + { + ActiveCircuit[ActiveActor]->ReductionStrategy = rsLaterals; + } + break; + case L'M': + ActiveCircuit[ActiveActor]->ReductionStrategy = rsMergeParallel; + break; + /** + 'T': Begin + ActiveCircuit[ActiveActor].ReductionStrategy := rsTapEnds; + ActiveCircuit[ActiveActor].ReductionMaxAngle := 15.0; + If Length(param2) > 0 Then ActiveCircuit[ActiveActor].ReductionMaxAngle := Auxparser.MakeDouble_(); + End; + **/ /*Shortlines or Switch*/ + case L'S': + { + if(CompareTextShortest(s, "SWITCH") == 0) + { + ActiveCircuit[ActiveActor]->ReductionStrategy = rsSwitches; + } + else + + /* ActiveCircuit.ReductionZmag is now set in main ExecOptions */ + { + ActiveCircuit[ActiveActor]->ReductionStrategy = rsShortlines; + } + } + break; + default: + DoSimpleMsg(String("Unknown Reduction Strategy: \"") + s + "\".", 276); + break; + } +} + +int DoInterpolateCmd() +{ + int result = 0; + TEnergyMeterObj* MetObj = nullptr; + TEnergyMeter* MeterClass = nullptr; + String ParamName; + String Param; + int DevClassIndex = 0; + TDSSCktElement* CktElem = nullptr; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + + // initialize the Checked Flag FOR all circuit Elements + /*# with ActiveCircuit[ActiveActor] do */ + { + + CktElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_First(); + while((CktElem != nullptr)) + { + CktElem->Checked = false; + CktElem = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get_Next(); + } + } + if(Param.size() == 0) + Param = "A"; + switch(Param[0]) + { + case 'A': + { + MetObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + while(MetObj != nullptr) + { + MetObj->InterpolateCoordinates(); + MetObj = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + } + break; + /*Interpolate a specific meter*/ + default: + DevClassIndex = ClassNames[ActiveActor].Find("energymeter"); + if(DevClassIndex > 0) + { + MeterClass = (TEnergyMeter*)DSSClassList[ActiveActor].Get(DevClassIndex); + if( ( (TDSSClass*) MeterClass )->SetActive(Param)) // Try to set it active + { + MetObj = ((TEnergyMeterObj*) ( (TDSSClass*) MeterClass )->GetActiveObj()); + MetObj->InterpolateCoordinates(); + } + else + DoSimpleMsg(String("EnergyMeter \"") + Param + "\" not found.", 277); + } + break; + } + return result; +} + +/*Interpolate bus coordinates in meter zones*/ + +int DoAlignFileCmd() +{ + int result = 0; + String ParamName; + String Param; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(FileExists(Param)) + { + if(!RewriteAlignedFile(Param)) + result = 1; + } + else + { + DoSimpleMsg(String("File \"") + Param + "\" does not exist.", 278); + result = 1; + } + if(result == 0) + FireOffEditor(GlobalResult); + return result; +} +/*Rewrites designated file, aligning the fields into columns*/ /*DoAlignfileCmd*/ + +int DoTOPCmd() +{ + int result = 0; + String ParamName; + String Param; + String ObjName; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + ParamName = Parser[ActiveActor]->GetNextParam(); + ObjName = UpperCase(Parser[ActiveActor]->MakeString_()); + if(ObjName.size() == 0) + ObjName = "ALL"; + switch(Param[1]) + { + case L'L': + LoadShapeClass[ActiveActor]->TOPExport(ObjName); + break; + case L'T': + TShapeClass[ActiveActor]->TOPExport(ObjName); + break; + /* + 'G': GrowthShapeClass.TOPExportAll; + 'T': TCC_CurveClass.TOPExportAll; + */ + default: + MonitorClass[ActiveActor]->TOPExport(ObjName); + break; + } + return result; +} +/* Sends Monitors, Loadshapes, GrowthShapes, or TCC Curves to TOP as an STO file*/ + +void DoSetNormal(double pctNormal) +{ + int i = 0; + TLineObj* pLine = nullptr; + if(ActiveCircuit[ActiveActor] != nullptr) + { + int stop = 0; + pctNormal = pctNormal * 0.01; // local copy only + for(stop = ActiveCircuit[ActiveActor]->Lines.get_myNumList(), i = 1; i <= stop; i++) + { + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get(i); + pLine->NormAmps = pctNormal * pLine->EmergAmps; + } + } +} + +int DoRotateCmd() +{ + int result = 0; + int i = 0; + double Angle = 0.0; + double xmin = 0.0; + double xmax = 0.0; + double ymin = 0.0; + double ymax = 0.0; + double xc = 0.0; + double YC = 0.0; + String ParamName; + complex A = {}; + complex Vector = {}; + result = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Angle = Parser[ActiveActor]->MakeDouble_() * DSSGlobals::PI / 180.0; // Deg to rad + A = cmplx(cos(Angle), sin(Angle)); + /*# with ActiveCircuit[ActiveActor] do */ + { + + int stop = 0; + xmin = 1.0e50; + xmax = -1.0e50; + ymin = 1.0e50; + ymax = -1.0e50; + for(stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + if( ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->CoordDefined) + { + /*# with ActiveCircuit[ActiveActor]->Buses^[i] do */ + { + + xmax = max(xmax, ActiveCircuit[ActiveActor]->Buses[i - 1]->x); + xmin = min(xmin, ActiveCircuit[ActiveActor]->Buses[i - 1]->x); + ymax = max(ymax, ActiveCircuit[ActiveActor]->Buses[i - 1]->y); + ymin = min(ymin, ActiveCircuit[ActiveActor]->Buses[i - 1]->y); + } + } + } + xc = (xmax + xmin) / 2.0; + YC = (ymax + ymin) / 2.0; + for(stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + if(ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->CoordDefined) + { + /*# with ActiveCircuit[ActiveActor]->Buses^[i] do */ + { + + Vector = cmplx(ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->x - xc, ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->y - YC); + Vector = cmul(Vector, A); + ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->x = xc + Vector.re; + ActiveCircuit[ActiveActor]->Buses[static_cast(i) - 1]->y = YC + Vector.im; + } + } + } + } + } + return result; +} + +/*rotate about the center of the coordinates*/ + +int DoVDiffCmd() +{ + int result = 0; + TTextRec Fin = {}; + TTextRec Fout = {}; + String Busname; + String dummy; + String Line; + int i = 0; + int Node = 0; + int BusIndex = 0; + double Vmag = 0.0; + double Diff = 0.0; + result = 0; + if(FileExists(CircuitName_[ActiveActor] + "SavedVoltages.Txt")) + { + try + { + try + { + AssignFile(Fin, CircuitName_[ActiveActor] + "SavedVoltages.Txt"); + Reset(Fin); + IOResultToException(); + AssignFile(Fout, CircuitName_[ActiveActor] + "VDIFF.txt"); + Rewrite(Fout); + IOResultToException(); + while(!Eof(Fin)) + { + ReadLn(Fin, Line); + AuxParser[ActiveActor]->SetCmdString(Line); + dummy = AuxParser[ActiveActor]->GetNextParam(); + Busname = AuxParser[ActiveActor]->MakeString_(); + if(Busname.size() > 0) + { + BusIndex = ActiveCircuit[ActiveActor]->BusList.Find(Busname); + if(BusIndex > 0) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); + Node = AuxParser[ActiveActor]->MakeInteger_(); + /*# with ActiveCircuit[ActiveActor]->Buses^[BusIndex] do */ + { + + int stop = 0; + for(stop = ActiveCircuit[ActiveActor]->Buses[static_cast(BusIndex) - 1]->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + if( ActiveCircuit[ActiveActor]->Buses[static_cast(BusIndex) - 1]->GetNum(i) == Node ) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); + Vmag = AuxParser[ActiveActor]->MakeDouble_(); + Diff = cabs((ActiveCircuit[ActiveActor]->Solution->NodeV)[ ActiveCircuit[ActiveActor]->Buses[static_cast(BusIndex) - 1]->GetRef(i)] ) - Vmag; + if(Vmag != 0.0) + { + { Write(Fout, Busname); Write(Fout, L'.'); Write(Fout, Node); Write(Fout, ", "); Write(Fout, (Diff / Vmag * 100.0), 7, 2); WriteLn(Fout, ", %"); } + } + else + { Write(Fout, Busname); Write(Fout, L'.'); Write(Fout, Node); Write(Fout, ", "); Write(Fout, Format("%-.5g", Diff)); WriteLn(Fout, ", Volts"); } + } + } + } + } + } + } + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error opening Saved Voltages or VDIFF File: ") + (std::string) e.what(), 280); + return result; + } + } +/* } + __finally + {*/ + CloseFile(Fin); + CloseFile(Fout); + FireOffEditor(CircuitName_[ActiveActor] + "VDIFF.txt"); + } + catch (...) + { + // + } + } + else + DoSimpleMsg("Error: No Saved Voltages.", 281); + return result; +} + +int DoSummaryCmd() +{ + int result = 0; + String s; + complex cLosses = {}; + complex cPower = {}; + result = 0; + s = ""; + if(ActiveCircuit[ActiveActor]->Issolved) + s = s + "Status = SOLVED" + CRLF; + else + { + s = s + "Status = NOT Solved" + CRLF; + } + s = s + "Solution Mode = " + GetSolutionModeID() + CRLF; + s = s + "Number = " + IntToStr(ActiveCircuit[ActiveActor]->Solution->NumberOfTimes) + CRLF; + s = s + + "Load Mult = " + + Format("%5.3f", ActiveCircuit[ActiveActor]->get_FLoadMultiplier()) + + CRLF; + s = s + "Devices = " + Format("%d", ActiveCircuit[ActiveActor]->NumDevices) + CRLF; + s = s + "Buses = " + Format("%d", ActiveCircuit[ActiveActor]->NumBuses) + CRLF; + s = s + "Nodes = " + Format("%d", ActiveCircuit[ActiveActor]->NumNodes) + CRLF; + s = s + "Control Mode =" + GetControlModeID() + CRLF; + s = s + "Total Iterations = " + IntToStr(ActiveCircuit[ActiveActor]->Solution->Iteration) + CRLF; + s = s + + "Control Iterations = " + + IntToStr(ActiveCircuit[ActiveActor]->Solution->ControlIteration) + + CRLF; + s = s + "Max Sol Iter = " + IntToStr(ActiveCircuit[ActiveActor]->Solution->MostIterationsDone) + CRLF; + s = s + " " + CRLF; + s = s + " - Circuit Summary -" + CRLF; + s = s + " " + CRLF; + if(ActiveCircuit[ActiveActor] != nullptr) + { + s = s + Format("Year = %d ", ActiveCircuit[ActiveActor]->Solution->get_Fyear()) + CRLF; + s = s + + Format("Hour = %d ", ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour) + + CRLF; + s = s + + "Max pu. voltage = " + + Format("%-.5g ", GetMaxPUVoltage()) + + CRLF; + s = s + + "Min pu. voltage = " + + Format("%-.5g ", GetMinPUVoltage(true)) + + CRLF; + cPower = cmulreal(GetTotalPowerFromSources(ActiveActor), 0.000001); // MVA + s = s + Format("Total Active Power: %-.6g MW", cPower.re) + CRLF; + s = s + Format("Total Reactive Power: %-.6g Mvar", cPower.im) + CRLF; + cLosses = cmulreal(ActiveCircuit[ActiveActor]->Get_Losses(ActiveActor), 0.000001); + if(cPower.re != 0.0) + s = s + + Format("Total Active Losses: %-.6g MW, (%-.4g %%)", cLosses.re, (cLosses.re / cPower.re * 100.0)) + + CRLF; + else + s = s + "Total Active Losses: ****** MW, (**** %%)" + CRLF; + s = s + Format("Total Reactive Losses: %-.6g Mvar", cLosses.im) + CRLF; + s = s + + Format("Frequency = %-g Hz", ActiveCircuit[ActiveActor]->Solution->get_FFrequency()) + + CRLF; + s = s + "Mode = " + GetSolutionModeID() + CRLF; + s = s + "Control Mode = " + GetControlModeID() + CRLF; + s = s + "Load Model = " + GetLoadModel() + CRLF; + } + GlobalResult = s; + CoutLn(s); // publishes the info + return result; +} + +// Returns summary in global result String + +int DoDistributeCmd() +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + bool DoGenerators = false; + double kW = 0.0; + double PF = 0.0; + int Skip = 0; + String how; + String FilName; + result = 0; + ParamPointer = 0; + /*Defaults*/ + kW = 1000.0; + how = "Proportional"; + Skip = 1; + PF = 1.0; + FilName = "DistGenerators.dss"; + DoGenerators = true; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = DistributeCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + kW = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + how = Parser[ActiveActor]->MakeString_(); + break; + case 3: + Skip = Parser[ActiveActor]->MakeInteger_(); + break; + case 4: + PF = Parser[ActiveActor]->MakeDouble_(); + break; + case 5: + FilName = Parser[ActiveActor]->MakeString_(); + break; + case 6: + kW = Parser[ActiveActor]->MakeDouble_() * 1000.0; + break; + case 7: + if(UpperCase(Param)[1] == L'L') + DoGenerators = false; + else + DoGenerators = true; + break; // Load or Generator + + // ignore unnamed and extra parms + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + if(!DoGenerators) + FilName = "DistLoads.dss"; + MakeDistributedGenerators(kW, PF, how, Skip, FilName, DoGenerators); // in Utilities + return result; +} + +int DoDI_PlotCmd() +{ + int result = 0; + String ParamName; + String Param; + int ParamPointer = 0; + int i = 0; + String CaseName; + String MeterName; + int CaseYear = 0; + double dRegisters[231/*# range 1..NumEMRegisters*/]{}; + std::vector iRegisters; + int NumRegs = 0; + bool PEAKDAY = false; + if(DIFilesAreOpen[ActiveActor]) + EnergyMeterClass[ActiveActor]->CloseAllDIFiles(ActiveActor); +// if(!ASSIGNED(DSSPlotObj)) +// DSSPlotObj = new TDSSPlot(); + /*Defaults*/ + NumRegs = 1; + iRegisters.resize( NumRegs ); + iRegisters[0] = 9; + PEAKDAY = false; + CaseYear = 1; + CaseName = ""; + MeterName = "DI_Totals"; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = DI_PlotCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + CaseName = Param; + break; + case 2: + CaseYear = Parser[ActiveActor]->MakeInteger_(); + break; + case 3: + { + int stop = 0; + NumRegs = Parser[ActiveActor]->ParseAsVector(NumEMRegisters, (pDoubleArray) dRegisters); + iRegisters.resize( NumRegs ); + for(stop = NumRegs, i = 1; i <= stop; i++) + { + iRegisters[static_cast(i) - 1] = (int) Round(dRegisters[i - 1]); + } + } + break; + case 4: + PEAKDAY = InterpretYesNo(Param); + break; + case 5: + MeterName = Param; + break; + // ignore unnamed and extra parms + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } +// DSSPlotObj->DoDI_Plot(CaseName, CaseYear, &iRegisters[0], iRegisters.High, PEAKDAY, MeterName); + iRegisters.clear(); + result = 0; + return result; +} + +int DoCompareCasesCmd() +{ + int result = 0; + String ParamName; + String Param; + int ParamPointer = 0; + bool unknown = false; + int reg = 0; + String CaseName1; + String CaseName2; + String WhichFile; + if(DIFilesAreOpen[ActiveActor]) + EnergyMeterClass[ActiveActor]->CloseAllDIFiles(ActiveActor); +// if(!ASSIGNED(DSSPlotObj)) +// DSSPlotObj = new TDSSPlot(); + CaseName1 = "base"; + CaseName2 = ""; + reg = 9; // Overload EEN + WhichFile = "Totals"; + ParamPointer = 0; + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + unknown = false; + if(Param.size() == 0) + ++ParamPointer; + else + { + if(CompareTextShortest(ParamName, "CASE1") == 0){ + ParamPointer = 1; + ++ParamPointer; + } + else + { + if(CompareTextShortest(ParamName, "CASE2") == 0){ + ParamPointer = 2; + ++ParamPointer; + } + else + { + if(CompareTextShortest(ParamName, "REGISTER") == 0) { + ParamPointer = 3; + ++ParamPointer; + } + else + { + if(CompareTextShortest(ParamName, "METER") == 0) { + ParamPointer = 4; + ++ParamPointer; + } + else + unknown = true; + } + } + } + } + if(!unknown) + switch(ParamPointer) + { + case 1: + CaseName1 = Param; + break; + case 2: + CaseName2 = Param; + break; + case 3: + reg = Parser[ActiveActor]->MakeInteger_(); + break; + case 4: + WhichFile = Param; + break; + // ignore unnamed and extra parms + default: + ; + break; + } + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + } +// DSSPlotObj->DoCompareCases(CaseName1, CaseName2, WhichFile, reg); + result = 0; + return result; +} + +int DoYearlyCurvesCmd() +{ + int result = 0; + String dummy; + String ParamName; + String Param; + int ParamPointer = 0; + int i = 0; + bool unknown = false; + TStringList* CaseNames = nullptr; + double dRegisters[231/*# range 1..NumEMRegisters*/]{}; + std::vector iRegisters; + int Nregs = 0; + String WhichFile; + if(DIFilesAreOpen[ActiveActor]) + EnergyMeterClass[ActiveActor]->CloseAllDIFiles(ActiveActor); +// if(!ASSIGNED(DSSPlotObj)) +// DSSPlotObj = new TDSSPlot(); + Nregs = 1; + iRegisters.resize( Nregs ); + WhichFile = "Totals"; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + unknown = false; + if(ParamName.size() == 0) + ++ParamPointer; + else + switch(UpperCase(ParamName)[1]) + { + case L'C': + ParamPointer = 1; + break; + case L'R': + ParamPointer = 2; + break; + case L'M': + ParamPointer = 3; + break; /*meter=*/ + default: + unknown = true; + break; + } + if(!unknown) + switch(ParamPointer) + { + case 1: // List of case names + { + AuxParser[ActiveActor]->SetCmdString(Param); + dummy = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + CaseNames->push_back(Param); + dummy = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } + break; + case 2: + { + int stop = 0; + Nregs = Parser[ActiveActor]->ParseAsVector(NumEMRegisters, (pDoubleArray) dRegisters); + iRegisters.resize( Nregs ); + for(stop = Nregs, i = 1; i <= stop; i++) + { + iRegisters[static_cast(i) - 1] = (int) Round(dRegisters[i - 1]); + } + } + break; + case 3: + WhichFile = Param; + break; + // ignore unnamed and extra parms + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } +// DSSPlotObj->DoYearlyCurvePlot(&CaseNames, WhichFile, &iRegisters[0], iRegisters.High); + iRegisters.clear(); + result = 0; + return result; +} + +int DoVisualizeCmd() +{ + int result = 0; + int DevIndex = 0; + String Param; + String ParamName; + int ParamPointer = 0; + bool unknown = false; + int Quantity = 0; + String ElemName; + TDSSObject* PElem = nullptr; + result = 0; + // Abort if no circuit or solution + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSimpleMsg("No circuit created.", 24721); + return result; + } + if(!ASSIGNED(ActiveCircuit[ActiveActor]->Solution) || (ActiveCircuit[ActiveActor]->Solution->NodeV.empty())) + { + DoSimpleMsg("The circuit must be solved before you can do this.", 24722); + return result; + } +// Quantity = vizCURRENT; + Quantity = 1; + ElemName = ""; + //Parse rest of command line + /* + ParamPointer = 0; + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + unknown = false; + if(ParamName.size() == 0) + ++ParamPointer; + else + { + if(CompareTextShortest(ParamName, "WHAT") == 0) + ParamPointer = 1; + else + { + if(CompareTextShortest(ParamName, "ELEMENT") == 0) + ParamPointer = 2; + else + unknown = true; + } + } + if(!unknown) + switch(ParamPointer) + { + case 1: + switch(LowerCase(Param)[0]) + { + case L'c': + Quantity = vizCURRENT; + break; + case L'v': + Quantity = vizVOLTAGE; + break; + case L'p': + Quantity = vizPOWER; + break; + default: + ; + break; + } + break; + case 2: + ElemName = Param; + break; + // ignore unnamed and extra parms + default: + ; + break; + } + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + Param = Parser[ActiveActor]->MakeString_(); + } //WHILE + + //-------------------------------------------------------------- + DevIndex = GetCktElementIndex(ElemName); // Global function + if(DevIndex > 0) // element must already exist + { + PElem = ActiveCircuit[ActiveActor]->CktElements.Get(DevIndex); + if(ObjectIs(PElem, TDSSCktElement*)) + { + DSSPlotObj->DoVisualizationPlot(((TDSSCktElement*) PElem), Quantity); + } + else + { + DoSimpleMsg(PElem->get_Name() + " must be a circuit element type!", 282); // Wrong type + } + } + else + { + DoSimpleMsg(String("Requested Circuit Element: \"") + ElemName + + "\" Not Found.", 282); // Did not find it .. + } + */ + return result; +} + +int DoCloseDICmd() +{ + int result = 0; + result = 0; + EnergyMeterClass[ActiveActor]->CloseAllDIFiles(ActiveActor); + return result; +} + +int DoADOScmd() +{ + int result = 0; + result = 0; + DoDOSCmd(Parser[ActiveActor]->Get_Remainder()); + return result; +} + +int DoEstimateCmd() +{ + int result = 0; + result = 0; + + /*Load current Estimation is driven by Energy Meters at head of feeders.*/ + DoAllocateLoadsCmd(ActiveActor); + + /*Let's look to see how well we did*/ + if(!AutoShowExport) + DSSExecutive[ActiveActor]->Set_Command("Set showexport=yes"); + DSSExecutive[ActiveActor]->Set_Command("Export Estimation"); + return result; +} + +int DoReconductorCmd() +{ + int result = 0; + String Param; + String ParamName; + int ParamPointer = 0; + String Line1; + String Line2; + String LineCode; + String Geometry; + String EditString; + String MyEditString; + bool LineCodeSpecified = false; + bool GeometrySpecified = false; + TLineObj* pLine1 = nullptr; + TLineObj* pLine2 = nullptr; + TLine* LineClass = nullptr; + int TraceDirection = 0; + int NPhases = 0; + result = 0; + ParamPointer = 0; + LineCodeSpecified = false; + GeometrySpecified = false; + Line1 = ""; + Line2 = ""; + MyEditString = ""; + NPhases = 0; // no filtering by number of phases + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = ReconductorCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + Line1 = Param; + break; + case 2: + Line2 = Param; + break; + case 3: + { + LineCode = Param; + LineCodeSpecified = true; + GeometrySpecified = false; + } + break; + case 4: + { + Geometry = Param; + LineCodeSpecified = false; + GeometrySpecified = true; + } + break; + case 5: + MyEditString = Param; + break; + case 6: + NPhases = Parser[ActiveActor]->MakeInteger_(); + break; + default: + DoSimpleMsg(String("Error: Unknown Parameter on command line: ") + Param, 28701); + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + + /*Check for Errors*/ + + /*If user specified full line name, get rid of "line."*/ + Line1 = StripClassName(Line1); + Line2 = StripClassName(Line2); + if((Line1.size() == 0) || (Line2.size() == 0)) + { + DoSimpleMsg("Both Line1 and Line2 must be specified!", 28702); + return result; + } + if((!LineCodeSpecified) && (!GeometrySpecified)) + { + DoSimpleMsg("Either a new LineCode or a Geometry must be specified!", 28703); + return result; + } + LineClass = (TLine*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("Line")); + pLine1 = ((TLineObj*) ( (TDSSClass*) LineClass )->Find(Line1)); + pLine2 = ((TLineObj*) ( (TDSSClass*) LineClass )->Find(Line2)); + if((pLine1 == nullptr) || (pLine2 == nullptr)) + { + if(pLine1 == nullptr) + DoSimpleMsg(String("Line.") + Line1 + " not found.", 28704); + else + { + if(pLine2 == nullptr) + DoSimpleMsg(String("Line.") + Line2 + " not found.", 28704); + } + return result; + } + + /*Now check to make sure they are in the same meter's zone*/ + if((pLine1->MeterObj == nullptr) || (pLine2->MeterObj == nullptr)) + { + DoSimpleMsg("Error: Both Lines must be in the same EnergyMeter zone. One or both are not in any meter zone.", 28705); + return result; + } + if(pLine1->MeterObj != pLine2->MeterObj) + { + DoSimpleMsg(String("Error: Line1 is in EnergyMeter.") + ( (TDSSObject*) pLine1->MeterObj )->get_Name() + + " zone while Line2 is in EnergyMeter." + + ( (TDSSObject*) pLine2->MeterObj )->get_Name() + + " zone. Both must be in the same Zone.", 28706); + return result; + } + + /*Since the lines can be given in either order, Have to check to see which direction they are specified and find the path between them*/ + TraceDirection = 0; + if(IsPathBetween(pLine1, pLine2)) + TraceDirection = 1; + if(IsPathBetween(pLine2, pLine1)) + TraceDirection = 2; + if(LineCodeSpecified) + EditString = String("Linecode=") + LineCode; + else + EditString = String("Geometry=") + Geometry; + + // Append MyEditString onto the end of the edit string to change the linecode or geometry + EditString = EditString + " " + MyEditString; + switch(TraceDirection) + { + case 1: + TraceAndEdit(pLine1, pLine2, NPhases, EditString); + break; + case 2: + TraceAndEdit(pLine2, pLine1, NPhases, EditString); + break; + default: + DoSimpleMsg("Traceback path not found between Line1 and Line2.", 28707); + return result; + break; + } + return result; +} + +int DoAddMarkerCmd() +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + TBusMarker* BusMarker = nullptr; + result = 0; + ParamPointer = 0; + BusMarker = new TBusMarker(); + ActiveCircuit[ActiveActor]->BusMarkerList.push_back(BusMarker); + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = AddMarkerCommands->Getcommand(ParamName); + /*# with BusMarker do */ + { + auto with0 = BusMarker; + switch(ParamPointer) + { + case 1: + with0->BusName = Param; + break; + case 2: + with0->AddMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 3: + with0->AddMarkerColor = InterpretColorName(Param); + break; + case 4: + with0->AddMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + // ignore unnamed and extra parms + default: + ; + break; + } + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + return result; +} + +int DoSetLoadAndGenKVCmd() +{ + int result = 0; + TLoadObj* pLoad = nullptr; + TGeneratorObj* pGen = nullptr; + TDSSBus* pBus = nullptr; + String sBus; + int iBus = 0; + int i = 0; + double kvln = 0.0; + int stop = 0; + result = 0; + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_First(); + while(pLoad != nullptr) + { + ActiveLoadObj = pLoad; // for UpdateVoltageBases to work + sBus = StripExtension( ( (TDSSCktElement*) pLoad )->GetBus(1)); + iBus = ActiveCircuit[ActiveActor]->BusList.Find(sBus); + pBus = ActiveCircuit[ActiveActor]->Buses[static_cast(iBus) - 1]; + kvln = pBus->kVBase; + if((pLoad->Connection == 1) || ( ( (TDSSCktElement*) pLoad )->Get_NPhases() == 3)) + pLoad->kVLoadBase = kvln * sqrt(3.0L); + else + pLoad->kVLoadBase = kvln; + pLoad->UpdateVoltageBases(); + pLoad->RecalcElementData(ActiveActor); + pLoad = (TLoadObj*) ActiveCircuit[ActiveActor]->Loads.Get_Next(); + } + for(stop = ActiveCircuit[ActiveActor]->Generators.get_myNumList(), i = 1; i <= stop; i++) + { + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get(i); + sBus = StripExtension(pGen->GetBus(1)); + iBus = ActiveCircuit[ActiveActor]->BusList.Find(sBus); + pBus = ActiveCircuit[ActiveActor]->Buses[static_cast(iBus) - 1]; + kvln = pBus->kVBase; + if((pGen->Connection == 1) || (pGen->Get_NPhases() > 1)) + pGen->Set_PresentkV(kvln * sqrt(3.0L)); + else + pGen->Set_PresentkV(kvln); + pGen->RecalcElementData(ActiveActor); + } + return result; +} + +int DoUuidsCmd() +{ + int result = 0; + TTextRec f = {}; + String dummy; + String ParamName; + String Param; + String s; + String NameVal; + String UuidVal; + String DevClass; + String devName; + TNamedObject* PName = nullptr; + int Idx = 0; + StartUuidList(ActiveCircuit[ActiveActor]->NumBuses + 2 * ActiveCircuit[ActiveActor]->NumDevices); + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + try + { + AssignFile(f, Param); + Reset(f); + IOResultToException(); + AuxParser[ActiveActor]->set_delimchars(","); + while(!Eof(f)) + { + ReadLn(f, s); + /*# with AuxParser[ActiveActor] do */ + { + auto with36 = AuxParser[ActiveActor]; + PName = nullptr; + with36->SetCmdString(s); + dummy = with36->GetNextParam(); + NameVal = with36->MakeString_(); + dummy= with36->GetNextParam(); + UuidVal = with36->MakeString_(); + // format the UUID properly + if(Pos("{", UuidVal) < 1) + UuidVal = String("{") + UuidVal + "}"; + if(Pos("=", NameVal) > 0) // it's a non-identified object in OpenDSS + { + AddHashedUUID(NameVal, UuidVal); + } + else + // find this as a descendant of TNamedObject + { + PName = nullptr; + ParseObjectClassandName(NameVal, DevClass, devName); + if(CompareText(DevClass, "circuit") == 0) + { + PName = ActiveCircuit[ActiveActor]; + } + else + { + if(CompareText(DevClass, "Bus") == 0) + { + Idx = ActiveCircuit[ActiveActor]->BusList.Find(devName); + PName = ActiveCircuit[ActiveActor]->Buses[static_cast(Idx) - 1]; + } + else + { + LastClassReferenced[ActiveActor] = ClassNames[ActiveActor].Find(DevClass); + ActiveDSSClass[ActiveActor] = (TDSSClass*) DSSClassList[ActiveActor].Get(LastClassReferenced[ActiveActor]); + if(ActiveDSSClass[ActiveActor] != nullptr) + { + if(ActiveDSSClass[ActiveActor]->SetActive(devName)) + PName = ((TNamedObject*) ActiveDSSClass[ActiveActor]->GetActiveObj()); + } + } + // re-assign its UUID + } + if(PName != nullptr) + PName->Set_UUID(StringToUUID(UuidVal)); + } + } + } +/* } + __finally + {*/ + AuxParser[ActiveActor]->ResetDelims(); + CloseFile(f); + } + catch (...) + { + // + } + return result; +} + +int DoCvrtLoadshapesCmd() +{ + int result = 0; + TLoadShapeObj* pLoadshape = nullptr; + int iLoadshape = 0; + TLoadShape* LoadShapeClass = nullptr; + String ParamName; + String Param; + String Action; + TTextRec f = {}; + String FName; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() == 0) + Param = "s"; + + /*Double file or Single file?*/ + switch(LowerCase(Param)[0]) + { + case L'd': + Action = "action=dblsave"; + break; + default: + Action = "action=sngsave"; // default + break; + } + LoadShapeClass = (TLoadShape*) GetDSSClassPtr("loadshape"); + FName = "ReloadLoadshapes.DSS"; + AssignFile(f, FName); + Rewrite(f); + IOResultToException(); + iLoadshape = LoadShapeClass->Get_First(); + while(iLoadshape > 0) + { + pLoadshape = ((TLoadShapeObj*) LoadShapeClass->GetActiveObj()); + Parser[ActiveActor]->SetCmdString(Action); + pLoadshape->Edit(ActiveActor); + WriteLn(f, "New Loadshape." + pLoadshape->get_Name() + Format("Npts = % d Interval = % .8g ", pLoadshape->get_FNumPoints(), pLoadshape->Interval) + GlobalResult); + iLoadshape = LoadShapeClass->Get_Next(); + } + CloseFile(f); + FireOffEditor(FName); + result = 0; + return result; +} + +int DoNodeDiffCmd() +{ + int result = 0; + String ParamName; + String Param; + String sNode1; + String sNode2; + String sBusName; + complex V1 = {}; + complex V2 = {}; + complex VNodeDiff = {}; + int iBusidx = 0; + int B1ref = 0; + int B2ref = 0; + int NumNodes = 0; + int NodeBuffer[50/*# range 1..50*/]{}; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + sNode1 = Param; + if(Pos("2", ParamName) > 0) + sNode2 = Param; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + sNode2 = Param; + if(Pos("1", ParamName) > 0) + sNode1 = Param; + + // Get first node voltage + AuxParser[ActiveActor]->set_Token(sNode1); + NodeBuffer[1 - 1] = 1; + sBusName = AuxParser[ActiveActor]->ParseAsBusName(NumNodes, (pIntegerArray) NodeBuffer, ActiveActor); + iBusidx = ActiveCircuit[ActiveActor]->BusList.Find(sBusName); + if(iBusidx > 0) + { + B1ref = ActiveCircuit[ActiveActor]->Buses[static_cast(iBusidx) - 1]->Find(NodeBuffer[1 - 1]); + } + else + { + DoSimpleMsg("Bus %s not found." + sBusName, 28709); + return result; + } + V1 = (ActiveCircuit[ActiveActor]->Solution->NodeV)[B1ref]; + + // Get 2nd node voltage + AuxParser[ActiveActor]->set_Token(sNode2); + NodeBuffer[1 - 1] = 1; + sBusName = AuxParser[ActiveActor]->ParseAsBusName(NumNodes, (pIntegerArray) NodeBuffer, ActiveActor); + iBusidx = ActiveCircuit[ActiveActor]->BusList.Find(sBusName); + if(iBusidx > 0) + { + B2ref = ActiveCircuit[ActiveActor]->Buses[static_cast(iBusidx) - 1]->Find(NodeBuffer[1 - 1]); + } + else + { + DoSimpleMsg("Bus %s not found." + sBusName, 28710); + return result; + } + V2 = (ActiveCircuit[ActiveActor]->Solution->NodeV)[B2ref]; + VNodeDiff = csub(V1, V2); + GlobalResult = Format("%.7g, V, %.7g, deg ", cabs(VNodeDiff), cdang(VNodeDiff)); + return result; +} + +int DoRephaseCmd() +{ + int result = 0; + String Param; + String ParamName; + int ParamPointer = 0; + String StartLine; + String NewPhases; + String MyEditString; + String ScriptFileName; + TLineObj* pStartLine = nullptr; + TLine* LineClass = nullptr; + bool TransfStop = false; + result = 0; + ParamPointer = 0; + MyEditString = ""; + ScriptFileName = "RephaseEditScript.DSS"; + TransfStop = true; // Stop at Transformers + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = RephaseCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + StartLine = Param; + break; + case 2: + NewPhases = Param; + break; + case 3: + MyEditString = Param; + break; + case 4: + ScriptFileName = Param; + break; + case 5: + TransfStop = InterpretYesNo(Param); + break; + default: + DoSimpleMsg(String("Error: Unknown Parameter on command line: ") + Param, 28711); + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + LineClass = (TLine*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("Line")); + pStartLine = ((TLineObj*) ( (TDSSClass*) LineClass )->Find(StripClassName(StartLine))); + if(pStartLine == nullptr) + { + DoSimpleMsg(String("Starting Line (") + StartLine + ") not found.", 28712); + return result; + } + /*Check for some error conditions and abort if necessary*/ + if(pStartLine->MeterObj == nullptr) + { + DoSimpleMsg("Starting Line must be in an EnergyMeter zone.", 28713); + return result; + } + if(!(dynamic_cast(pStartLine->MeterObj))) + { + DoSimpleMsg("Starting Line must be in an EnergyMeter zone.", 28714); + return result; + } + GoForwardAndRephase(pStartLine, NewPhases, MyEditString, ScriptFileName, TransfStop); + return result; +} + +int DoSetBusXYCmd() +{ + int result = 0; + String Param; + String ParamName; + int ParamPointer = 0; + String Busname; + double Xval = 0.0; + double Yval = 0.0; + int iB = 0; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + ParamPointer = 0; + Xval = 0.0; + Yval = 0.0; + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = SetBusXYCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + Busname = Param; + break; + case 2: + Xval = Parser[ActiveActor]->MakeDouble_(); + break; + case 3: + Yval = Parser[ActiveActor]->MakeDouble_(); + break; + default: + DoSimpleMsg(String("Error: Unknown Parameter on command line: ") + Param, 28721); + break; + } + iB = ActiveCircuit[ActiveActor]->BusList.Find(Busname); + if(iB > 0) + { + /*# with ActiveCircuit[ActiveActor]->Buses^[iB] do */ + { + // Returns TBus object + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->x = Xval; + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->y = Yval; + ActiveCircuit[ActiveActor]->Buses[static_cast(iB) - 1]->CoordDefined = true; + } + } + else + { + DoSimpleMsg(String("Error: Bus \"") + Busname + "\" Not Found.", 28722); + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + return result; +} + +int DoFNCSPubCmd() +{ + int result = 0; + DoSimpleMsg("Error: FNCS only supported in the Free Pascal version", 28728); + return result; +} + +int DoUpdateStorageCmd() +{ + int result = 0; + StorageClass[ActiveActor]->UpdateAll(ActiveActor); + result = 0; + return result; +} + +/* +FUNCTION DoUpdateStorage2Cmd:Integer; + +Begin + StorageClass[ActiveActor].UpdateAll(ActiveActor); + Result := 0; +End; +*/ + +int DoPstCalc() +{ + int result = 0; + String Param; + String ParamName; + int ParamPointer = 0; + int npts = 0; + pDoubleArray VArray; + int CyclesPerSample = 0; + int Lamp = 0; + pDoubleArray PstArray; + int nPst = 0; + int i = 0; + String s; + double Freq = 0.0; + result = 0; + VArray = NULL; + PstArray = NULL; + npts = 0; + Lamp = 120; // 120 or 230 + CyclesPerSample = 60; + Freq = DefaultBaseFreq; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + ParamPointer = 0; + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = PstCalcCommands->Getcommand(ParamName); + // 'Npts', 'Voltages', 'cycles', 'lamp' + switch(ParamPointer) + { + case 1: + { + npts = Parser[ActiveActor]->MakeInteger_(); + VArray = (pDoubleArray) malloc(sizeof(double) * npts); + } + break; + case 2: + npts = InterpretDblArray(Param, npts, VArray); + break; + case 3: + CyclesPerSample = (int) Round(ActiveCircuit[ActiveActor]->Solution->get_FFrequency() * Parser[ActiveActor]->MakeDouble_()); + break; + case 4: + Freq = Parser[ActiveActor]->MakeDouble_(); + break; + case 5: + Lamp = Parser[ActiveActor]->MakeInteger_(); + break; + default: + DoSimpleMsg(String("Error: Unknown Parameter on command line: ") + Param, 28722); + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + if(npts > 10) + { + int stop = 0; + nPst = PstRMS(PstArray, VArray, Freq, CyclesPerSample, npts, Lamp); + // put resulting pst array in the result string + s = ""; + for(stop = nPst, i = 1; i <= stop; i++) + { + s = s + Format("%.8g, ", PstArray[i - 1]); + } + GlobalResult = s; + } + else + DoSimpleMsg("Insuffient number of points for Pst Calculation.", 28723); + free(VArray); // discard temp arrays + free(PstArray); + return result; +} +int DoLambdaCalcs() +{ + int result = 0, + i = 0; + TEnergyMeterObj* pMeter = nullptr; + + String ParamName = "", + Param = ""; + bool AssumeRestoration = false; + + auto with0 = ActiveCircuit[ActiveActor]; + // Do for each Energymeter object in active circuit + pMeter = (TEnergyMeterObj*)with0->EnergyMeters.Get_First(); + if (pMeter == nullptr) + { + DoSimpleMsg("No EnergyMeter Objects Defined. EnergyMeter objects required for this function.", 28724); + return result; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if (Param.size() > 0) + AssumeRestoration = InterpretYesNo(Param); + else + AssumeRestoration = false; + + // initialize bus quantities + + /*# with ActiveCircuit[ActiveActor] do */ + { + int stop = 0; + for (stop = with0->NumBuses, i = 1; i <= stop; i++) + { + /*# with ActiveCircuit[ActiveActor]->Buses^[i] do */ + { + + with0->Buses[i - 1]->BusFltRate = 0.0; + with0->Buses[i - 1]->Bus_Num_Interrupt = 0.0; + } + } + } + while (pMeter != nullptr) + { + pMeter->CalcReliabilityIndices(AssumeRestoration, ActiveActor); + pMeter = (TEnergyMeterObj*) with0->EnergyMeters.Get_Next(); + } + return result; +} +/*Execute fault rate and bus number of interruptions calc*/ + +int DoVarCmd() +{ + int result = 0; + String ParamName; + String Param; + String Str; + int iVar = 0; + TStringList* MsgStrings = nullptr; + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() == 0) // show all vars + { + int stop = 0; + if(NoFormsAllowed) + return result; + /* + MsgStrings := TStringList.Create; + MsgStrings.Add('Variable, Value'); + for iVar := 1 to ParserVars.NumVariables do + MsgStrings.Add(ParserVars.VarString[iVar] ); + ShowMessageForm(MsgStrings); + MsgStrings.Free;*/ + Str = String("Variable, Value") + CRLF; + for(stop = ParserVars->NumVariables, iVar = 1; iVar <= stop; iVar++) + { + Str = Str + String(ParserVars->Get_VarString((unsigned int) iVar)) + CRLF; + } + DoSimpleMsg(Str, 999345); + } + else + { + if(ParamName.size() == 0) // show value of this var + { + GlobalResult = Param; // Parser substitutes @var with value + } + else + { + while(ParamName.size() > 0) + { + switch(ParamName[0]) + { + case L'@': + ParserVars->Add(ParamName, Param); + break; + default: + DoSimpleMsg(String("Illegal Variable Name: ") + ParamName + + "; Must begin with \"@\"", 28725); + return result; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + } + } + return result; +} +/*Process Script variables*/ + +int DoRemoveCmd() +{ + int result = 0; + String ParamName; + String Param; + String Str; + int i = 0; + int ParamPointer = 0; + int DeviceIndex = 0; + String FElementName; + bool ElmFound = false; + bool FKeepLoad = false; + String FEditString; + TPDElement* pPDElem = nullptr; + TEnergyMeterObj* pMeter = nullptr; + String FMeterName; + result = 0; + FKeepLoad = true; + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = RemoveCommands->Getcommand(ParamName); + switch(ParamPointer) + { + case 1: + FElementName = Param; + break; /*ElementName*/ + case 2: + FKeepLoad = InterpretYesNo(Param); + break; /*KeepLoad*/ + case 3: + FEditString = Param; + break; /*EditString*/ + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } + + // Check for existence of FelementName + DeviceIndex = GetCktElementIndex(FElementName); + if(DeviceIndex == 0) + { + DoSimpleMsg(String("Error: Element ") + FElementName + " does not exist in this circuit.", 28726); + } + else + // Element exists GO! + // first, checks if the element is not linked to an energy meter, if it does, abort (added 01/06/2020 -DM) + { + ElmFound = false; + if(ActiveCircuit[ActiveActor] != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + + int stop = 0; + pMeter = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_First(); + for(stop = ActiveCircuit[ActiveActor]->EnergyMeters.get_myNumList(), i = 1; i <= stop; i++) + { + if(AnsiLowerCase(pMeter->ElementName) == AnsiLowerCase(FElementName)) + { + ElmFound = true; + break; + } + else + pMeter = (TEnergyMeterObj*) ActiveCircuit[ActiveActor]->EnergyMeters.Get_Next(); + } + } + if(!ElmFound) + // Set CktElement active + { + SetObject(FElementName); + + // Get Energymeter associated with this element. + if(dynamic_cast(ActiveCircuit[ActiveActor]->get_FActiveCktElement())) + { + pPDElem = (TPDElement*) ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + if(pPDElem->SensorObj == nullptr) + DoSimpleMsg("Element " + ((TDSSObject*)pPDElem)->ParentClass->get_myClass_name() + + "." + ((TDSSObject*)pPDElem)->get_Name() + " is not in a meter zone!Add an Energymeter. ", 287261); + else + { + FMeterName = ((TDSSObject*)pPDElem->SensorObj)->ParentClass->get_myClass_name() + "." +( (TDSSObject*) pPDElem->SensorObj )->get_Name(); + SetObject(FMeterName); + if(dynamic_cast(ActiveCircuit[ActiveActor]->get_FActiveCktElement())) + { + pMeter = (TEnergyMeterObj*) (void*) ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + // in ReduceAlgs + DoRemoveBranches(pMeter->BranchList, pPDElem, FKeepLoad, FEditString); + } + else + DoSimpleMsg(String("Error: The Sensor Object for ") + FElementName + + " is not an EnergyMeter object", 28727); + } + } + else + DoSimpleMsg(String("Error: Element ") + FElementName + + " is not a power delivery element (PDElement)", 28728); + } + else + DoSimpleMsg(String("Error: Element ") + FElementName + " is tied to an Energy Meter.", 28800); + } + return result; +} + +/*Initialize Command lists*/ + + +void ExecHelper_initialization() +{ + std::string temp[4] = { "class", "file", "dir", "keepdisabled" }; + SaveCommands = new TCommandList(temp, 4); + SaveCommands->set_AbbrevAllowed(true); + + std::string temp1[5] = { "case", "year", "registers", "peak", "meter" }; + DI_PlotCommands = new TCommandList(temp1, 5); + + std::string temp2[7] = { "kW", "how", "skip", "pf", "file", "MW", "what" }; + DistributeCommands = new TCommandList(temp2, 7); + DistributeCommands->set_AbbrevAllowed(true); + + std::string temp3[6] = { "Line1", "Line2", "LineCode", "Geometry", "EditString", "Nphases" }; + ReconductorCommands = new TCommandList(temp3, 6); + ReconductorCommands->set_AbbrevAllowed(true); + + std::string temp4[5] = { "StartLine", "PhaseDesignation", "EditString", "ScriptFileName", "StopAtTransformers" }; + RephaseCommands = new TCommandList(temp4, 5); + RephaseCommands->set_AbbrevAllowed(true); + + std::string temp5[4] = { "Bus", "code", "color", "size" }; + AddMarkerCommands = new TCommandList(temp5, 4); + AddMarkerCommands->set_AbbrevAllowed(true); + + std::string temp6[3] = { "Bus", "x", "y" }; + SetBusXYCommands = new TCommandList(temp6, 3); + SetBusXYCommands->set_AbbrevAllowed(true); + + std::string temp7[5] = { "Npts", "Voltages", "dt", "Frequency", "lamp" }; + PstCalcCommands = new TCommandList(temp7, 5); + PstCalcCommands->set_AbbrevAllowed(true); + + std::string temp8[1] = { "Fname" }; + FNCSPubCommands = new TCommandList(temp8, 1); + FNCSPubCommands->set_AbbrevAllowed(true); + + std::string temp9[3] = { "ElementName", "KeepLoad", "Editstring" }; + RemoveCommands = new TCommandList(temp9, 3); + RemoveCommands->set_AbbrevAllowed(true); +} + +void ExecHelper_finalization() +{ + delete DistributeCommands; + delete DI_PlotCommands; + delete SaveCommands; + delete AddMarkerCommands; + delete ReconductorCommands; + delete RephaseCommands; + delete SetBusXYCommands; + delete PstCalcCommands; + delete FNCSPubCommands; + delete RemoveCommands; +} + + class ExecHelper_unit + { + public: + ExecHelper_unit() + { + //AssertSystemInitialization(); + ExecHelper_initialization(); + } + ~ ExecHelper_unit(){ExecHelper_finalization(); } + }; + ExecHelper_unit _ExecHelper_unit; + +} // namespace ExecHelper + + + + diff --git a/OpenDSSC/Executive/ExecHelper.h b/OpenDSSC/Executive/ExecHelper.h new file mode 100644 index 0000000..14233af --- /dev/null +++ b/OpenDSSC/Executive/ExecHelper.h @@ -0,0 +1,203 @@ +#ifndef ExecHelperH +#define ExecHelperH + +#include "System.h" +#include "Sysutils.h" + +#include "d2c_structures.h" + +#include "Command.h" +#include "Arraydef.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Monitor.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Utilities.h" +#include "Solution.h" +#include "EnergyMeter.h" +#include "generator.h" +#include "LoadShape.h" +#include "Load.h" +#include "PCElement.h" +#include "CktElement.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "Bus.h" +#include "SolutionAlgs.h" +#include "CmdForms.h" +#include "ExecCommands.h" +#include "Executive.h" +#include "Dynamics.h" +#include "Capacitor.h" +#include "Reactor.h" +#include "Line.h" +#include "LineUnits.h" +#include +#include "CktElementClass.h" +#include "Sensor.h" +#include "ExportCIMXML.h" +#include "NamedObject.h" +#include "Pstcalc.h" +#include "PDElement.h" +#include "ReduceAlgs.h" +#include "Ucmatrix.h" +#include "XfmrCode.h" +#include "vccs.h" +#include "RegControl.h" +#include "CapControl.h" +#include "WindGen.h" +#include "GenDispatcher.h" +#include "StorageController.h" +#include "Relay.h" +#include "Recloser.h" +#include "fuse.h" +#include "SwtControl.h" +#include "UPFC.h" +#include "UPFCControl.h" +#include "ESPVLControl.h" +#include "IndMach012.h" +#include "GICsource.h" +#include "AutoTrans.h" +#include "GICLine.h" +#include "GICTransformer.h" +#include "VSConverter.h" +#include "Generic5OrderMach.h" + + + +namespace ExecHelper +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Functions for performing DSS Exec Commands and Options*/ +/* + 8-17-00 Updated Property Dump to handle wildcards + 10-23-00 Fixed EnergyMeters iteration error in DoAllocateLoadsCmd + 7/6/01 Fixed autobuslist command parsing of file + 7/19/01 Added DoMeterTotals + 8/1/01 Revised the Capacity Command return values + 9/12/02 Added Classes and UserClasses + 3/29/03 Implemented DoPlotCmd and Buscoords + 4/24/03 Implemented Keep list and other stuff related to circuit reduction +*/ + +/*$WARN UNIT_PLATFORM OFF*/ +int DoNewCmd(); +int DoEditCmd(); +int DoBatchEditCmd(); +int DoSelectCmd(); +int DoMoreCmd(); +int DoRedirect(bool IsCompile); +int DoSaveCmd(); +int DoSampleCmd(int ActorID); +int DoSolveCmd(); +int DoEnableCmd(); +int DoDisableCmd(); +int DoOpenCmd(); +int DoResetCmd(int ActorID); +int DoNextCmd(); +int DoFormEditCmd(); +int DoClassesCmd(); +int DoUserClassesCmd(); +int DoHelpCmd(); +int DoClearCmd(); +int DoClearAllCmd(); +int DoReduceCmd(); +int DoInterpolateCmd(); +int DoCloseCmd(); +int DoResetMonitors(int ActorID); +int DoFileEditCmd(); +int DoQueryCmd(); +int DoResetMeters(int ActorID); +void DoAboutBox(); +int DoSetVoltageBases(int ActorID); +int DoSetkVBase(); +void DoLegalVoltageBases(); +void DoAutoAddBusList(const String s); +void DoKeeperBusList(const String s); +void DoSetReduceStrategy(const String s); +void DoSetAllocationFactors(double X); +void DoSetCFactors(double X); +int DovoltagesCmd(bool PerUnit); +int DocurrentsCmd(); +int DopowersCmd(int Total); +int DoseqvoltagesCmd(); +int DoseqcurrentsCmd(); +int DoseqpowersCmd(); +int DolossesCmd(); +int DophaselossesCmd(); +int DocktlossesCmd(); +int DoAllocateLoadsCmd(int ActorID); +int DoHarmonicsList(const String s); +int DoMeterTotals(); +int DoCapacityCmd(); +int DoZscCmd(bool Zmatrix); +int DoZsc10Cmd(); +int DoZscRefresh(int ActorID); +int DoZsc012Cmd(); +int DoBusCoordsCmd(bool SwapXY, int CoordType); +int DoUuidsCmd(); +int DoSetLoadAndGenKVCmd(); +int DoVarValuesCmd(); +int DoVarNamesCmd(); +int DoMakePosSeq(); +int DoAlignFileCmd(); +int DoTOPCmd(); +int DoRotateCmd(); +int DoVDiffCmd(); +int DoSummaryCmd(); +int DoDistributeCmd(); +int DoDI_PlotCmd(); +int DoCompareCasesCmd(); +int DoYearlyCurvesCmd(); +int DoVisualizeCmd(); +int DoCloseDICmd(); +int DoADOScmd(); +int DoEstimateCmd(); +int DoReconductorCmd(); +int DoAddMarkerCmd(); +int DoCvrtLoadshapesCmd(); +int DoNodeDiffCmd(); +int DoRephaseCmd(); +int DoSetBusXYCmd(); +int DoUpdateStorageCmd(); + // FUNCTION DoUpdateStorage2Cmd:Integer; +int DoPstCalc(); +int DoValVarCmd(); +int DoLambdaCalcs(); +int DoVarCmd(); +int DoNodeListCmd(); +int DoRemoveCmd(); +int DoFNCSPubCmd(); +void DoSetNormal(double pctNormal); +void Set_Time(); +void ParseObjName(const String FullName, String& ObjName, String& PropName); +void GetObjClassAndName(String& ObjClass, String& ObjName); +int AddObject(const String ObjType, const String Name); +int EditObject(const String ObjType, const String Name); +void SetActiveCircuit(const String cktname); +int SetActiveCktElement(); +int DoPropertyDump(); + + +} // namespace ExecHelper + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExecHelper; +#endif + +#endif // ExecHelperH + + + + diff --git a/OpenDSSC/Executive/ExecOptions.cpp b/OpenDSSC/Executive/ExecOptions.cpp new file mode 100644 index 0000000..4975c01 --- /dev/null +++ b/OpenDSSC/Executive/ExecOptions.cpp @@ -0,0 +1,2150 @@ + + +#pragma hdrstop + +#include "ExecOptions.h" +#include "Utilities.h" + + + +using namespace std; +using namespace Command; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace EnergyMeter; +using namespace ExecHelper; +using namespace Executive; +using namespace LoadShape; +using namespace ParserDel; +using namespace Solution; +using namespace System; +using namespace Utilities; + +namespace ExecOptions +{ + + TCommandList* OptionList = nullptr; + std::string* ExecOption; + std::string* OptionHelp; + + void DefineOptions() + { + ExecOption = new string[NumExecOptions]; + OptionHelp = new string [NumExecOptions]; + + ExecOption[1 - 1] = "type"; + ExecOption[2 - 1] = "element"; + ExecOption[3 - 1] = "hour"; + ExecOption[4 - 1] = "sec"; + ExecOption[5 - 1] = "year"; + ExecOption[6 - 1] = "frequency"; + ExecOption[7 - 1] = "stepsize"; + ExecOption[8 - 1] = "mode"; + ExecOption[9 - 1] = "random"; + ExecOption[10 - 1] = "number"; + ExecOption[11 - 1] = "time"; + ExecOption[12 - 1] = "class"; + ExecOption[13 - 1] = "object"; + ExecOption[14 - 1] = "circuit"; + ExecOption[15 - 1] = "editor"; + ExecOption[16 - 1] = "tolerance"; + ExecOption[17 - 1] = "maxiterations"; + ExecOption[18 - 1] = "h"; + ExecOption[19 - 1] = "Loadmodel"; + ExecOption[20 - 1] = "Loadmult"; + ExecOption[21 - 1] = "normvminpu"; + ExecOption[22 - 1] = "normvmaxpu"; + ExecOption[23 - 1] = "emergvminpu"; + ExecOption[24 - 1] = "emergvmaxpu"; + ExecOption[25 - 1] = "%mean"; + ExecOption[26 - 1] = "%stddev"; + ExecOption[27 - 1] = "LDCurve"; // Load Duration Curve + ExecOption[28 - 1] = "%growth"; // default growth rate + ExecOption[29 - 1] = "Genkw"; + ExecOption[30 - 1] = "Genpf"; + ExecOption[31 - 1] = "CapkVAR"; + ExecOption[32 - 1] = "Addtype"; + ExecOption[33 - 1] = "Allowduplicates"; + ExecOption[34 - 1] = "Zonelock"; + ExecOption[35 - 1] = "UEweight"; + ExecOption[36 - 1] = "Lossweight"; + ExecOption[37 - 1] = "UEregs"; + ExecOption[38 - 1] = "Lossregs"; + ExecOption[39 - 1] = "Voltagebases"; // changes the default voltage base rules + ExecOption[40 - 1] = "Algorithm"; // changes the default voltage base rules + ExecOption[41 - 1] = "Trapezoidal"; + ExecOption[42 - 1] = "Autobuslist"; // array of bus names to include in auto& add solutions + ExecOption[43 - 1] = "Controlmode"; + ExecOption[44 - 1] = "Tracecontrol"; + ExecOption[45 - 1] = "Genmult"; + ExecOption[46 - 1] = "Defaultdaily"; + ExecOption[47 - 1] = "Defaultyearly"; + ExecOption[48 - 1] = "Allocationfactors"; + ExecOption[49 - 1] = "Cktmodel"; + ExecOption[50 - 1] = "Pricesignal"; + ExecOption[51 - 1] = "Pricecurve"; + ExecOption[52 - 1] = "Terminal"; + ExecOption[53 - 1] = "Basefrequency"; + ExecOption[54 - 1] = "Harmonics"; + ExecOption[55 - 1] = "Maxcontroliter"; + ExecOption[56 - 1] = "Bus"; + ExecOption[57 - 1] = "Datapath"; + ExecOption[58 - 1] = "KeepList"; + ExecOption[59 - 1] = "ReduceOption"; + ExecOption[60 - 1] = "DemandInterval"; + ExecOption[61 - 1] = "%Normal"; + ExecOption[62 - 1] = "DIVerbose"; + ExecOption[63 - 1] = "Casename"; + ExecOption[64 - 1] = "Markercode"; + ExecOption[65 - 1] = "Nodewidth"; + ExecOption[66 - 1] = "Log"; + ExecOption[67 - 1] = "Recorder"; + ExecOption[68 - 1] = "Overloadreport"; + ExecOption[69 - 1] = "Voltexceptionreport"; + ExecOption[70 - 1] = "Cfactors"; + ExecOption[71 - 1] = "Showexport"; + ExecOption[72 - 1] = "Numallociterations"; + ExecOption[73 - 1] = "DefaultBaseFrequency"; + ExecOption[74 - 1] = "Markswitches"; + ExecOption[75 - 1] = "Switchmarkercode"; + ExecOption[76 - 1] = "Daisysize"; + ExecOption[77 - 1] = "Marktransformers"; + ExecOption[78 - 1] = "TransMarkerCode"; + ExecOption[79 - 1] = "TransMarkerSize"; + ExecOption[80 - 1] = "LoadShapeClass"; + ExecOption[81 - 1] = "EarthModel"; + ExecOption[82 - 1] = "QueryLog"; + ExecOption[83 - 1] = "MarkCapacitors"; + ExecOption[84 - 1] = "MarkRegulators"; + ExecOption[85 - 1] = "MarkPVSystems"; + ExecOption[86 - 1] = "MarkStorage"; + ExecOption[87 - 1] = "CapMarkerCode"; + ExecOption[88 - 1] = "RegMarkerCode"; + ExecOption[89 - 1] = "PVMarkerCode"; + ExecOption[90 - 1] = "StoreMarkerCode"; + ExecOption[91 - 1] = "CapMarkerSize"; + ExecOption[92 - 1] = "RegMarkerSize"; + ExecOption[93 - 1] = "PVMarkerSize"; + ExecOption[94 - 1] = "StoreMarkerSize"; + ExecOption[95 - 1] = "NeglectLoadY"; + ExecOption[96 - 1] = "MarkFuses"; + ExecOption[97 - 1] = "FuseMarkerCode"; + ExecOption[98 - 1] = "FuseMarkerSize"; + ExecOption[99 - 1] = "MarkReclosers"; + ExecOption[100 - 1] = "RecloserMarkerCode"; + ExecOption[101 - 1] = "RecloserMarkerSize"; + ExecOption[102 - 1] = "RegistryUpdate"; + ExecOption[103 - 1] = "MarkRelays"; + ExecOption[104 - 1] = "RelayMarkerCode"; + ExecOption[105 - 1] = "RelayMarkerSize"; + ExecOption[106 - 1] = "ProcessTime"; + ExecOption[107 - 1] = "TotalTime"; + ExecOption[108 - 1] = "StepTime"; + ExecOption[109 - 1] = "NumCPUs"; + ExecOption[110 - 1] = "NumCores"; + ExecOption[111 - 1] = "NumActors"; + ExecOption[112 - 1] = "ActiveActor"; + ExecOption[113 - 1] = "CPU"; + ExecOption[114 - 1] = "ActorProgress"; + ExecOption[115 - 1] = "Parallel"; + ExecOption[116 - 1] = "ConcatenateReports"; + ExecOption[117 - 1] = "OpenDSSViewer"; + ExecOption[118 - 1] = "DSSVInstalled"; + ExecOption[119 - 1] = "Coverage"; + ExecOption[120 - 1] = "Num_SubCircuits"; + ExecOption[121 - 1] = "SampleEnergyMeters"; + ExecOption[122 - 1] = "ADiakoptics"; + ExecOption[123 - 1] = "MinIterations"; // default is 2 + ExecOption[124 - 1] = "LinkBranches"; + ExecOption[125 - 1] = "KeepLoad"; + ExecOption[126 - 1] = "Zmag"; + ExecOption[127 - 1] = "SeasonRating"; + ExecOption[128 - 1] = "SeasonSignal"; + ExecOption[129 - 1] = "NUMANodes"; + ExecOption[130 - 1] = "GISInstalled"; + ExecOption[131 - 1] = "GISCoords"; + ExecOption[132 - 1] = "GISColor"; + ExecOption[133 - 1] = "GISThickness"; + ExecOption[134 - 1] = "UseMyLinkBranches"; + ExecOption[135 - 1] = "LineTypes"; + ExecOption[136 - 1] = "EventLogDefault"; + ExecOption[137 - 1] = "LongLineCorrection"; + ExecOption[138 - 1] = "ShowReports"; + ExecOption[139 - 1] = "IgnoreGenQLimits"; + ExecOption[140 - 1] = "NCIMQGain"; + ExecOption[141 - 1] = "StateVar"; + + /*Deprecated + ExecOption[130 - 1] := 'MarkPVSystems2'; + ExecOption[132 - 1] := 'MarkStorage2'; + */ + OptionHelp[1 - 1] = "Sets the active DSS class type. Same as Class=..."; + OptionHelp[2 - 1] = "Sets the active DSS element by name. You can use " + "the complete object spec (class.name) or just the " + "name. if full name is specifed, class becomes the active " + "class, also."; + OptionHelp[3 - 1] = "Sets the hour used for the start time of the solution."; + OptionHelp[4 - 1] = "Sets the seconds from the hour for the start time of the solution."; + OptionHelp[5 - 1] = "Sets the Year (integer number) to be used for the solution. " + "for certain solution types, this determines the growth multiplier."; + OptionHelp[6 - 1] = "Sets the frequency for the solution of the active circuit."; + OptionHelp[7 - 1] = String("Sets the time step size for the active circuit. Default units are s. " "May also be specified in minutes or hours by appending \"m\" or \"h\" to the value. For example:") + CRLF + + CRLF + + " stepsize=.25h " + + CRLF + + " stepsize=15m" + + CRLF + + " stepsize=900s"; + OptionHelp[8 - 1] = String("Set the solution Mode: One of") + CRLF + + " Snapshot," + + CRLF + + " Daily," + + CRLF + + " Yearly (follow Yearly curve)," + + CRLF + + " DIrect," + + CRLF + + " DUtycycle," + + CRLF + + " Time, ( see LoadShapeClass option)" + + CRLF + + " DYnamic, ( see LoadShapeClass option)" + + CRLF + + " Harmonic," + + CRLF + + " HarmonicT, (sequential Harmonic Mode)" + + CRLF + + " M1 (Monte Carlo 1)," + + CRLF + + " M2 (Monte Carlo 2)," + + CRLF + + " M3 (Monte Carlo 3)," + + CRLF + + " Faultstudy," + + CRLF + + " MF (monte carlo fault study)" + + CRLF + + " Peakday," + + CRLF + + " LD1 (load-duration 1)" + + CRLF + + " LD2 (load-duration 2)" + + CRLF + + " AutoAdd (see AddType)" + + CRLF + + " YearlyVQ (Yearly Vector Quantiaztion)" + + CRLF + + " DutyVQ (Duty Vector Quantiaztion)" + + CRLF + + CRLF + + "Side effect: setting the Mode propergy resets all monitors and energy meters. It also " + + "resets the time step, etc. to defaults for each mode. After the initial reset, the user " + + "must explicitly reset the monitors and/or meters until another Set Mode= command."; + OptionHelp[9 - 1] = "One of [Uniform | Gaussian | Lognormal | None - 1] for Monte Carlo Variables."; + OptionHelp[10 - 1] = String("Number of solutions or time steps to perform for each Solve command. Defaults for selected modes: ") + CRLF + + CRLF + + "Daily = 24" + + CRLF + + "Yearly = 8760" + + CRLF + + "Duty = 100"; + OptionHelp[11 - 1] = String("Specify the solution start time as an array:") + CRLF + + "time=(hour, secs)"; + OptionHelp[12 - 1] = "Synonym for Type=. (See above)"; + OptionHelp[13 - 1] = "Synonym for Element=. (See above)"; + OptionHelp[14 - 1] = "Set the active circuit by name."; + OptionHelp[15 - 1] = "Set the command string required to start up the editor preferred by the user. Does not require a circuit defined."; + OptionHelp[16 - 1] = "Sets the solution tolerance. Default is 0.0001."; + OptionHelp[17 - 1] = "Sets the maximum allowable iterations for power flow solutions. Default is 15."; + OptionHelp[18 - 1] = "Alternate name for time step size."; + OptionHelp[19 - 1] = "{Powerflow | Admittance} depending on the type of solution you wish to perform. " + "If admittance, a non-iterative, direct solution is done with all loads and generators modeled by their " + "equivalent admittance."; + OptionHelp[20 - 1] = "Global load multiplier for this circuit. Does not affect loads " + "designated to be \"fixed\". All other base kW values are multiplied by this number. " + "Defaults to 1.0 when the circuit is created. As with other values, it always stays " + "at the last value to which it was set until changed again."; + OptionHelp[21 - 1] = "Minimum permissible per unit voltage for normal conditions. Default is 0.95."; + OptionHelp[22 - 1] = "Maximum permissible per unit voltage for normal conditions. Default is 1.05."; + OptionHelp[23 - 1] = "Minimum permissible per unit voltage for emergency (contingency) conditions. Default is 0.90."; + OptionHelp[24 - 1] = "Maximum permissible per unit voltage for emergency (contingency) conditions. Default is 1.08."; + OptionHelp[25 - 1] = "Percent mean to use for global load multiplier. Default is 65%."; + OptionHelp[26 - 1] = "Percent Standard deviation to use for global load multiplier. Default is 9%."; + OptionHelp[27 - 16] = "Set Load-Duration Curve. Global load multiplier is defined by this curve for LD1 and LD2 solution modes. Default is Nil."; + OptionHelp[28 - 1] = "Set default annual growth rate, percent, for loads with no growth curve specified. Default is 2.5."; + OptionHelp[29 - 1] = "Size of generator, kW, to automatically add to system. Default is 1000.0"; + OptionHelp[30] = "Power factor of generator to assume for automatic addition. Default is 1.0."; + OptionHelp[31 - 1] = "Size of capacitor, kVAR, to automatically add to system. Default is 600.0."; + OptionHelp[32 - 1] = "{Generator | Capacitor} Default is Generator. Type of device for AutoAdd Mode."; + OptionHelp[33 - 1] = "{YES/TRUE | NO/FALSE} Default is No. Flag to indicate if it is OK to have devices of same name in the same class. " + "If No, then a New command is treated as an Edit command. " + "If Yes, then a New command will always result in a device being added."; + OptionHelp[34 - 1] = "{YES/TRUE | NO/FALSE} Default is No. if No, then meter zones are recomputed each time there is a change in the circuit. " + "If Yes, then meter zones are not recomputed unless they have not yet been computed. " + "Meter zones are normally recomputed on Solve command following a circuit change."; + OptionHelp[35 - 1] = String("Weighting factor for UE/EEN in AutoAdd functions. Defaults to 1.0.") + CRLF + + CRLF + + "Autoadd mode minimizes" + + CRLF + + CRLF + + "(Lossweight * Losses + UEweight * UE). " + + CRLF + + CRLF + + "If you wish to ignore UE, set to 0. " + + "This applies only when there are EnergyMeter objects. " + + "Otherwise, AutoAdd mode minimizes total system losses."; + OptionHelp[36 - 1] = String("Weighting factor for Losses in AutoAdd functions. Defaults to 1.0.") + CRLF + + CRLF + + "Autoadd mode minimizes" + + CRLF + + CRLF + + "(Lossweight * Losses + UEweight * UE). " + + CRLF + + CRLF + + "If you wish to ignore Losses, set to 0. " + + "This applies only when there are EnergyMeter objects. " + + "Otherwise, AutoAdd mode minimizes total system losses."; + OptionHelp[37 - 1] = String("Which EnergyMeter register(s) to use for UE in AutoAdd Mode. " "May be one or more registers. if more than one, register values are summed together. " "Array of integer values > 0. Defaults to 11 (for Load EEN). ") + CRLF + + CRLF + + "for a list of EnergyMeter register numbers, do the \"Show Meters\" command after defining a circuit."; + OptionHelp[38 - 1] = String("Which EnergyMeter register(s) to use for Losses in AutoAdd Mode. " "May be one or more registers. if more than one, register values are summed together. " "Array of integer values > 0. Defaults to 13 (for Zone kWh Losses). ") + CRLF + + CRLF + + "for a list of EnergyMeter register numbers, do the \"Show Meters\" command after defining a circuit."; + OptionHelp[39 - 1] = String("Define legal bus voltage bases for this circuit. Enter an array " "of the legal voltage bases, in phase-to-phase voltages, for example:") + CRLF + + CRLF + + "set voltagebases=\".208, .480, 12.47, 24.9, 34.5, 115.0, 230.0\" " + + CRLF + + CRLF + + "When the CalcVoltageBases command is issued, a snapshot solution is performed " + + "with no load injections and the bus base voltage is set to the nearest legal voltage base. " + + "The defaults are as shown in the example above."; + OptionHelp[40 - 1] = "{Normal* | Newton | TCIM} Solution algorithm type. " + + CRLF + CRLF + + "Normal (default) is a fixed point iteration solution method " + "that is a little quicker than the Newton iteration. Normal is adequate for most radial " + "distribution circuits. " + + CRLF + CRLF + + "Newton is more robust for circuits that are difficult to solve." + + CRLF + CRLF + + "NCIM or the N Conductor Current Injection Method is a Newton-Raphson based method to be used for Transmission like cases."; + OptionHelp[41 - 1] = String("{YES/TRUE | NO/FALSE} Default is \"No/False\". Specifies whether to use trapezoidal integration for accumulating energy meter registers. " "Applies to EnergyMeter and Generator objects. Default method simply multiplies the " "present value of the registers times the width of the interval (Euler). " "Trapezoidal is more accurate when there are sharp changes in a load shape or unequal intervals. " "Trapezoidal is automatically used for " "some load-duration curve simulations where the interval size varies considerably. " "Keep in mind that for Trapezoidal, you have to solve one more point than the number of intervals. " "That is, to do a Daily simulation on a 24-hr load shape, you would set Number=25 to force a solution " "at the first point again to establish the last (24th) interval.") + CRLF + + CRLF + + "Note: Set Mode= resets Trapezoidal to No/False. Set this to Yes/True AFTER setting the Mode option."; + OptionHelp[42 - 1] = String("Array of bus names to include in AutoAdd searches. Or, you can specify a text file holding the names, one to a line, " "by using the syntax (file=filename) instead of the actual array elements. " "Default is null, which results in the program " "using either the buses in the EnergyMeter object zones or, if no EnergyMeters, all the buses, which can " "make for lengthy solution times. ") + CRLF + + CRLF + + "Examples:" + + CRLF + + CRLF + + "Set autobuslist=(bus1, bus2, bus3, ... )" + + CRLF + + "Set autobuslist=(file=buslist.txt)"; + OptionHelp[43 - 1] = String("{OFF | STATIC |EVENT | TIME} Default is \"STATIC\". Control mode for the solution. " "Set to OFF to prevent controls from changing.") + CRLF + + "STATIC = Time does not advance. Control actions are executed in order of shortest time to act " + + "until all actions are cleared from the control queue. Use this mode for power flow solutions which may require several " + + "regulator tap changes per solution." + + CRLF + + CRLF + + "EVENT = solution is event driven. Only the control actions nearest in time " + + "are executed and the time is advanced automatically to the time of the event. " + + CRLF + + CRLF + + "TIME = solution is time driven. Control actions are executed when the time for the pending " + + "action is reached or surpassed." + + CRLF + + CRLF + + "Controls may reset and may choose not to act when it comes their time. " + + CRLF + + "Use TIME mode when modeling a control externally to the DSS and a solution mode such as " + + "DAILY or DUTYCYCLE that advances time, or set the time (hour and sec) explicitly from the external program. "; + OptionHelp[44 - 1] = "{YES/TRUE | NO/FALSE} Set to YES to trace the actions taken in the control queue. " + "Creates a file named TRACE_CONTROLQUEUE.CSV in the default directory. " + "The names of all circuit elements taking an action are logged."; + OptionHelp[45 - 1] = "Global multiplier for the kW output of every generator in the circuit. Default is 1.0. " + "Applies to all but Autoadd solution modes. " + "Ignored for generators designated as Status=Fixed."; + OptionHelp[46 - 1] = "Default daily load shape name. Default value is \"default\", which is a 24-hour curve defined when the DSS is started."; + OptionHelp[47 - 1] = "Default yearly load shape name. Default value is \"default\", which is a 24-hour curve defined when the DSS is started."; + OptionHelp[48 - 1] = "Sets the connected kVA allocation factors for all loads in the active circuit to the value given."; + OptionHelp[49 - 1] = "{Multiphase | Positive} Default = Multiphase. Designates whether circuit model is to interpreted as a normal multi-phase " + "model or a positive-sequence only mode"; + OptionHelp[50 - 1] = "Sets the present price signal ($/MWh) for the circuit. Default value is 25."; + OptionHelp[51 - 1] = "Sets the PRICESHAPE object to use to obtain for price signal. Default is none (null string). If none, " + "price signal either remains constant or is set by an external process using Set Price= option. " + "Curve is defined as a PRICESHAPE in actual values (not normalized) and should be defined to correspond to " + "the type of analysis being performed (daily, yearly, etc.)."; + OptionHelp[52 - 1] = "Set the active terminal of the active circuit element. May also be done with Select command."; + OptionHelp[53 - 12] = "Default = 60. Set the fundamental frequency for harmonic solution and the default base frequency for all impedance quantities. " + "Side effect: also changes the value of the solution frequency. Saved as default for next circuit."; + OptionHelp[54 - 1] = String("{ALL | (list of harmonics) } Default = ALL. Array of harmonics for which to perform a solution in Harmonics mode. " "If ALL, then solution is performed for all harmonics defined in spectra currently being used. " "Otherwise, specify a more limited list such as: ") + CRLF + + CRLF + + " Set Harmonics=(1 5 7 11 13)"; + OptionHelp[55 - 1] = "Max control iterations per solution. Default is 10."; + OptionHelp[56 - 1] = "Set Active Bus by name. Can also be done with Select and SetkVBase commands and the \"Set Terminal=\" option. " + "The bus connected to the active terminal becomes the active bus. See Zsc and Zsc012 commands."; + OptionHelp[57 - 1] = String("Set the data path for files written or read by the DSS.") + CRLF + + "Defaults to the user documents folder." + + CRLF + + "If the DataPath is not writable, output files will be written to the user application data folder." + + CRLF + + "May be Null. Executes a CHDIR to this path if non-null." + + CRLF + + "Does not require a circuit defined."; + OptionHelp[58 - 1] = String("Array of bus names to keep when performing circuit reductions. You can specify a text file holding the names, one to a line, " "by using the syntax (file=filename) instead of the actual array elements. " "Command is cumulative (reset keeplist first). " "Reduction algorithm may keep other buses automatically. ") + CRLF + + CRLF + + "Examples:" + + CRLF + + CRLF + + "Reset Keeplist (sets all buses to FALSE (no keep))" + + CRLF + + "Set KeepList=(bus1, bus2, bus3, ... )" + + CRLF + + "Set KeepList=(file=buslist.txt)"; + OptionHelp[59 - 1] = String("{ Default or [null - 1] | Shortlines [Zmag=nnn - 1] | MergeParallel | BreakLoops | Switches | Ends | Laterals} Strategy for reducing feeders. " "Default is to eliminate all dangling end buses and buses without load, caps, or taps. ") + CRLF + + "\"Shortlines [-1]\" merges short branches with impedance less than Zmag (default = 0.02 ohms) " + + CRLF + + "\"MergeParallel\" merges lines that have been found to be in parallel " + + CRLF + + "\"Breakloops\" disables one of the lines at the head of a loop. " + + CRLF + + "\"Ends\" eliminates dangling ends only." + + CRLF + + "\"Switches\" merges switches with downline lines and eliminates dangling switches." + + CRLF + + "\"Laterals [-1]\" uses the Remove command to eliminate 1-phase laterals and optionally lump the load back to the 2- or 3-phase feeder (default behavior). " + + CRLF + + CRLF + + "Marking buses with \"Keeplist\" will prevent their elimination."; + OptionHelp[60 - 1] = "{YES/TRUE | NO/FALSE} Default = no. Set for keeping demand interval data for daily, yearly, etc, simulations. " + "Side Effect: Resets all meters!!!"; + OptionHelp[61 - 1] = "Sets the Normal rating of all lines to a specified percent of the emergency rating. Note: This action takes place immediately. " + "Only the in-memory value is changed for the duration of the run."; + OptionHelp[62 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. Set to Yes/True if you wish a separate demand interval (DI) file written " + "for each meter. Otherwise, only the totalizing meters are written."; + OptionHelp[63 - 1] = String("Name of case for yearly simulations with demand interval data. " "Becomes the name of the subdirectory under which all the year data are stored. " "Default = circuit name ") + CRLF + + CRLF + + "Side Effect: Sets the prefix for output files"; + OptionHelp[64 - 1] = "Number code for node marker on circuit plots. Number from 0 to 47. Default is 16 (open circle). 24 is solid circle. Try other values for other symbols. See also Nodewidth"; + OptionHelp[65 - 1] = "Width of node marker. Default=1. See MarkerCode"; + OptionHelp[66 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. Significant solution events are added to the Event Log, primarily for debugging."; + OptionHelp[67 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. Opens DSSRecorder.DSS in DSS install folder and enables recording of all commands that come through " + "the text command interface. Closed by either setting to NO/FALSE or exiting the program. " + "When closed by this command, the file name can be found in the Result. Does not require a circuit defined."; + OptionHelp[68 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. For yearly solution mode, sets overload reporting on/off. DemandInterval must be set to true for this to have effect."; + OptionHelp[69 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. For yearly solution mode, sets voltage exception reporting on/off. DemandInterval must be set to true for this to have effect."; + OptionHelp[70 - 1] = "Sets the CFactors for for all loads in the active circuit to the value given."; + OptionHelp[71 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. If YES/TRUE will automatically show the results of an Export Command after it is written."; + OptionHelp[72 - 1] = "Default is 2. Maximum number of iterations for load allocations for each time the AllocateLoads or Estimate command is given."; + OptionHelp[73 - 1] = "Set Default Base Frequency, Hz. Side effect: Sets solution Frequency and default Circuit Base Frequency. This value is saved when the DSS closes down."; + OptionHelp[74 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark lines that are switches or are isolated with a symbol. See SwitchMarkerCode."; + OptionHelp[75 - 1] = "Numeric marker code for lines with switches or are isolated from the circuit. Default is 4. See markswitches option."; + OptionHelp[76 - 1] = "Default is 1.0. Relative size (a multiplier applied to default size) of daisy circles on daisy plot."; + OptionHelp[77 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark transformer locations with a symbol. See TransMarkerCode. " + "The coordinate of one of the buses for winding 1 or 2 must be defined for the symbol to show"; + OptionHelp[78 - 1] = "Numeric marker code (0..47 see Users Manual) for transformers. Default is 35. See markstransformers option."; + OptionHelp[79 - 1] = "Size of transformer marker. Default is 1."; + OptionHelp[80 - 1] = "={Daily | Yearly | Duty | None*} Default loadshape class to use for mode=time and mode=dynamic simulations. Loads and generators, etc., will follow " + "this shape as time is advanced. Default value is None. That is, Load will not vary with time."; + OptionHelp[81 - 1] = "One of {Carson | FullCarson | Deri*}. Default is Deri, which is" + "a fit to the Full Carson that works well into high frequencies. " + "\"Carson\" is the simplified Carson method that is typically used for 50/60 Hz power flow programs. " + "Applies only to Line objects that use LineGeometry objects to compute impedances."; + OptionHelp[82 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. When set to TRUE/YES, clears the query log file and thereafter appends " + "the time-stamped Result string contents to the log file after a query command, ?. "; + OptionHelp[83 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Capacitor locations with a symbol. See CapMarkerCode. "; + OptionHelp[84 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Regulator locations with a symbol. See RegMarkerCode. "; + OptionHelp[85 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark PVSystem locations with a symbol. See PVMarkerCode and PVMarkerSize. "; + OptionHelp[86 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Storage locations with a symbol. See StoreMarkerCode and StoreMarkerSize. "; + OptionHelp[87 - 1] = "Numeric marker code (0..47 -- see Users Manual) for Capacitors. Default is 38."; + OptionHelp[88 - 1] = "Numeric marker code (0..47 see Users Manual) for Regulators. Default is 17. (red)"; + OptionHelp[89 - 1] = "Numeric marker code (0..47 see Users Manual) for PVSystems and PVSystem. Default is 15."; + OptionHelp[90 - 1] = "Numeric marker code (0..47 see Users Manual) for Storage elements. Default is 9."; + OptionHelp[91 - 1] = "Size of Capacitor marker. Default is 3."; + OptionHelp[92 - 1] = "Size of Regulator marker. Default is 5."; + OptionHelp[93 - 1] = "Size of PVsystem and PVSystem markers. Default is 1."; + OptionHelp[94 - 1] = "Size of Storage marker. Default is 1."; + OptionHelp[95 - 1] = String("{YES/TRUE | NO/FALSE} Default is NO. For Harmonic solution, neglect the Load shunt admittance branch that can siphon off some of the Load injection current. ") + CRLF + + CRLF + + "If YES, the current injected from the LOAD at harmonic frequencies will be nearly ideal."; + OptionHelp[96 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Fuse locations with a symbol. See FuseMarkerCode and FuseMarkerSize. "; + OptionHelp[97 - 1] = "Numeric marker code (0..47 see Users Manual) for Fuse elements. Default is 25."; + OptionHelp[98 - 1] = "Size of Fuse marker. Default is 1."; + OptionHelp[99 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Recloser locations with a symbol. See RecloserMarkerCode and RecloserMarkerSize. "; + OptionHelp[100 - 1] = "Numeric marker code (0..47 see Users Manual) for Recloser elements. Default is 17. (color=Lime)"; + OptionHelp[101 - 1] = "Size of Recloser marker. Default is 5."; + OptionHelp[102 - 1] = "{YES/TRUE | NO/FALSE} Default is Yes. Update Windows Registry values upon exiting. You might want to turn this off if you temporarily " + "change fonts or DefaultBaseFrequency, for example. "; + OptionHelp[103 - 1] = "{YES/TRUE | NO/FALSE} Default is NO. Mark Relay locations with a symbol. See RelayMarkerCode and RelayMarkerSize. "; + OptionHelp[104 - 1] = "Numeric marker code (0..47 see Users Manual) for Relay elements. Default is 17. (Color=Lime)"; + OptionHelp[105 - 1] = "Size of Relay marker. Default is 5."; + OptionHelp[106 - 1] = "The time in microseconds to execute the solve process in the most recent time step or solution (read only)"; + OptionHelp[107 - 1] = "The accumulated time in microseconds to solve the circuit since the last reset. Set this value to reset the accumulator."; + OptionHelp[108 - 1] = "Process time + meter sampling time in microseconds for most recent time step - (read only)"; + OptionHelp[109 - 1] = "Delivers the number of threads (CPUs) available on the machine (read Only)"; + OptionHelp[110 - 1] = "Delivers the number of physical processors (Cores) available on the computer. If your computers processor has less than 64 cores, this number should be equal to the half of the available CPUs, otherise the number should be the same (Read Only)"; + OptionHelp[111 - 1] = "Delivers the number of Actors created by the user, 1 is the default"; + OptionHelp[112 - 1] = "Gets/Sets the number of the active actor, if the value is * (set active actor=*), the commands send after this instruction will be aplied to all the actors."; + OptionHelp[113 - 1] = String("(default -1)Gets/Sets the CPU to be used by the active actor. If negative (-1) means that the actor affinity is to all the CPUs and will be executed in the") + CRLF + + "first available CPU and will be realocated into another CPU dynamically if the operating system requires it. By setting a CPU number for an actor will force" + + CRLF + + "the actor to be executed only on the specific CPU."; + OptionHelp[114 - 1] = "Gets progress (%) for all the actors when performing a task"; + OptionHelp[115 - 1] = "Activates/Deactivates the parallel machine in OpenDSS, if deactivated OpenDSS will behave sequentially"; + OptionHelp[116 - 1] = "Activates/Deactivates the option for concatenate the reports generated by the existing actors, if Yes, everytime the user" + "a show/export monitor command the report will include the data generated by all the actors, otherwise the report will contain" + "The data generated by the active actor"; + OptionHelp[117 - 1] = "Activates/Deactivates the extended version of the plot command for figures with the OpenDSS Viewer."; + OptionHelp[118 - 1] = "Returns Yes/No if the OpenDSS Viewer installation is detected in the local machine (Read Only)"; + OptionHelp[119 - 1] = String("Percentage of coverage expected when estimating the longest paths on the circuit for tearing, the default coverage") + CRLF + + "is the 90% (0.9), this value cannot exceed 1.0. When used with the \"Set\" command is used for the algorithm for estimating the paths within the circuit" + + CRLF + + "but when the \"get\" command is used after executing the tear_circuit command it will deliver the actual coverage after running the algorithm"; + OptionHelp[120 - 1] = "This is the number of subcircuits in which the circuit will be torn when executing the tear_circuit command, by default is the number of local CPUs - 1"; + OptionHelp[121 - 1] = "{YES/TRUE | NO/FALSE} Overrides default value for sampling EnergyMeter objects at the end of the solution loop. " + "Normally Time and Duty modes do not automatically sample EnergyMeters whereas Daily, Yearly, M1, M2, M3, LD1 and LD2 modes do. " + "Use this Option to turn sampling on or off"; + OptionHelp[122 - 1] = String("{YES/TRUE | NO/FALSE} Activates the A-Diakoptics solution algorithm for using spatial parallelization on the feeder.") + CRLF + + "This parameter only affects Actor 1, no matter from which actor is called. When activated (True), OpenDSS will start the " + + CRLF + + "initialization routine for the A-Diakoptics solution mode"; + OptionHelp[123 - 1] = "Minimum number of iterations required for a solution. Default is 2."; + OptionHelp[124 - 1] = String("Get/set the names of the link branches used for tearing the circuit after initializing using set ADiakoptics = True. Using this instruction will set the Active Actor = 1") + CRLF + + "If ADiakoptics is not initialized, this instruction will return an error message"; + OptionHelp[125 - 1] = "Keeploads = Y/N option for ReduceOption Laterals option"; + OptionHelp[126 - 1] = "Sets the Zmag option (in Ohms) for ReduceOption Shortlines option. Lines have less line mode impedance are reduced."; + OptionHelp[127 - 1] = "{YES/TRUE | NO/FALSE} Default = FALSE. Enables/disables the seasonal selection of the rating for determining if an element is overloaded. When enabled, the energy meter wil" + "look for the rating (NormAmps) using the SeasonSignal to evaluate if the PDElement is overloaded"; + OptionHelp[128 - 1] = "It is the name of the XY curve defining the ratings seasonal change for the PDElements in the model when performing QSTS simulations. The seasonal ratings need to be defined" + "at the PDElement or at the general object definition such as linecodes, lineGeometry, etc."; + OptionHelp[129 - 1] = "Delivers the number of Non-uniform memory access nodes (NUMA Nodes) available on the machine (read Only). This information is vital when working" + "with processor clusters (HPC). It will help you know the number of processors in the cluster"; + OptionHelp[130 - 1] = "Returns Yes/No if the OpenDSS GIS installation is detected in the local machine (Read Only)"; + OptionHelp[131 - 1] = "[Coords - 1] : An array of doubles defining the longitud and latitude for an area to be used as refrence for the OpenDSS-GIS related commands, long1, lat1, long2, lat2"; + OptionHelp[132 - 1] = "Color : A Hex string defining 24 bit color in RGB format, e.g. , red = FF0000"; + OptionHelp[133 - 1] = "Thickness: An integer defining the thickness (default = 3)"; + OptionHelp[134 - 1] = "{YES/TRUE | NO/FALSE*} Set/get the boolean flag for indicating to the tearing algorithm the source of the link branches for tearing the model into sub-circuits." + " If FALSE, OpenDSS will use METIS for estimating the link branches to be used based on the number of sub-circuits given by the user through the command \"set Num_SubCircuits\"." + "Otherwise, OpenDSS will use the list of link branches given by the user with the command \"set LinkBranches\"."; + OptionHelp[135 - 1] = "(Read only) Returns the list of line types available in the code for reference.These line types apply to lines, line codes, and line geometry objects."; + OptionHelp[136 - 1] = "{YES / TRUE | NO / FALSE*} Sets / gets the default for the eventlog.After changing this flags the model needs to be recompiled to take effect."; + OptionHelp[137 - 1] = "{YES / TRUE | NO / FALSE*} Defines whether the long - line correctlion is applied or not.Long - line correction only affects lines modelled with sequence components."; + OptionHelp[138 - 1] = "{YES / TRUE | NO / FALSE} Default = TRUE.If YES / TRUE will automatically show the results of a Show Command after it is written."; + OptionHelp[139 - 1] = "{YES/TRUE | NO/FALSE*} Use this flag to indicate if you want to ignore the Q limits for generators during an NCIM solution. The default is NO/FALSE, signaling that generators will always respect their Q generation/absorbtion limits."; + OptionHelp[140 - 1] = "{1.0*} Use this option to set a gain for the reactive power compensation provided by PV buses (generator model 3) when using the NCIM solution algorithm. The default value is 1.0."; + OptionHelp[141 - 1] = "Reads or Writes the value of the given state variable for the given PCE. Depending on the access mode (read/write) the syntax may vary. For writing the variable use the following syntax:" + CRLF + + CRLF + + "set StateVar = myObjName myVarName myValue" + CRLF + + CRLF + + "Where myObjName corresponds to the class and object name, for example, if you want to refer to generator Gen1, then myObjName will be Generator.Gen1. myVarName is the name of the state variable and myValue is the value to assign." + CRLF + + CRLF + " For reading the state variable use the following syntax : " + CRLF + + CRLF + " get StateVar myObjName myVarName " + CRLF + + CRLF + " The reading structure will return the value in the results tab."; + + + } + //---------------------------------------------------------------------------- + + bool DoSetCmd_NoCircuit() + { + bool result = false; + int ParamPointer = 0; + String ParamName; + String Param; + result = true; + // Continue parsing command line + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = OptionList->Getcommand(ParamName); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Set Command ", 130); + break; + case 15: + DefaultEditor = Param; + break; // 'Editor=' + case 57: + SetDataPath(Param); + break; // Set a legal data path + case 67: + DSSExecutive[ActiveActor]->Set_RecorderOn(InterpretYesNo(Param)); + break; + case 73: + DefaultBaseFreq = Parser[ActiveActor]->MakeDouble_(); + break; + case 102: + UpdateRegistry = InterpretYesNo(Param); + break; + case 112: + { + if(Parser[ActiveActor]->MakeString_() == "*") + { + AllActors = true; + ActiveActor = 1; + } + else + { + if(Parser[ActiveActor]->MakeInteger_() <= NumOfActors) + { + ActiveActor = Parser[ActiveActor]->MakeInteger_(); + AllActors = false; + } + else + { + DoSimpleMsg("The actor does not exists", 7002); + } + } + } + break; + case 113: + { + if(Parser[ActiveActor]->MakeInteger_() < CPU_Cores) + { + ActorCPU[ActiveActor] = Parser[ActiveActor]->MakeInteger_(); + if(ActorHandle[ActiveActor] != nullptr) + { + //ActorHandle[ActiveActor]->CPU = ActorCPU[ActiveActor]; + //ActorHandle[ActiveActor]->Priority = tpTimeCritical; + } + } + else + { + DoSimpleMsg("The CPU does not exists", 7003); + } + } + break; + case 115: + { + Parallel_enabled = InterpretYesNo(Param); + } + break; + case 116: + { + ConcatenateReports = InterpretYesNo(Param); + } + break; + case 117: + { + DSS_Viz_enable = InterpretYesNo(Param); + } + break; + case 136: + { + EventLogDefault = InterpretYesNo(Param); + } + break; + default: + DoSimpleMsg("You must create a new circuit object first: \"new circuit.mycktname\" to execute this Set command.", 301); + result = false; // Indicate that we could not process all set command + return result; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } /*WHILE*/ + return result; + } // Set Commands that do not require a circuit + //---------------------------------------------------------------------------- + + // This is for setting global options that do not require an active circuit + + + //---------------------------------------------------------------------------- + + int DoSetCmd(int SolveOption) + { + int result = 0; + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + TLoadShapeObj* TestLoadShapeObj = nullptr; + TStringList* myList; + result = 0; + // Continue parsing command line + ParamPointer = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = OptionList->Getcommand(ParamName); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Set Command ", 130); + break; + case 1: + case 12: + SetObjectClass(Param); + break; + case 2: + case 13: + SetObject(Param); + break; + case 3: + ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour = Parser[ActiveActor]->MakeInteger_(); + break; + case 4: + ActiveCircuit[ActiveActor]->Solution->DynaVars.T = Parser[ActiveActor]->MakeDouble_(); + break; + case 5: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->Solution->Set_Year(Parser[ActiveActor]->MakeInteger_()); + with0->DefaultGrowthFactor = pow(with0->DefaultGrowthRate, (with0->Solution->get_Fyear() - 1)); + } + break; + case 6: + ActiveCircuit[ActiveActor]->Solution->Set_Frequency(Parser[ActiveActor]->MakeDouble_()); + break; + case 7: + case 18: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->Solution->DynaVars.h = InterpretTimeStepSize(Param); + with0->Solution->IntervalHrs = double(with0->Solution->DynaVars.h) / 3600.0; + } + break; + case 8: + { + ActiveCircuit[ActiveActor]->Solution->Set_Mode(InterpretSolveMode(Param)); // see DSSGlobals + if(ADiakoptics) + { + int stop = 0; + for(stop = NumOfActors, i = 2; i <= stop; i++) + { + ActiveCircuit[i]->Solution->Set_Mode(ActiveCircuit[1]->Solution->Get_SolMode()); + } + } + } + break; + case 9: + ActiveCircuit[ActiveActor]->Solution->RandomType = InterpretRandom(Param); + break; + case 10: + ActiveCircuit[ActiveActor]->Solution->NumberOfTimes = Parser[ActiveActor]->MakeInteger_(); + break; + case 11: + Set_Time(); + break; + case 14: + SetActiveCircuit(Param); + break; + case 15: + DefaultEditor = Param; + break; // 'Editor=' + case 16: + ActiveCircuit[ActiveActor]->Solution->ConvergenceTolerance = Parser[ActiveActor]->MakeDouble_(); + break; + case 17: + ActiveCircuit[ActiveActor]->Solution->MaxIterations = Parser[ActiveActor]->MakeInteger_(); + break; + case 19: + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with2 = ActiveCircuit[ActiveActor]->Solution; + with2->DefaultLoadModel = InterpretLoadModel(Param); // for reverting to last on specified + with2->LoadModel = with2->DefaultLoadModel; + } + break; + case 20: + ActiveCircuit[ActiveActor]->Set_LoadMultiplier(Parser[ActiveActor]->MakeDouble_()); + break; // Set using LoadMultiplier property + case 21: + ActiveCircuit[ActiveActor]->NormalMinVolts = Parser[ActiveActor]->MakeDouble_(); + break; + case 22: + ActiveCircuit[ActiveActor]->NormalMaxVolts = Parser[ActiveActor]->MakeDouble_(); + break; + case 23: + ActiveCircuit[ActiveActor]->EmergMinVolts = Parser[ActiveActor]->MakeDouble_(); + break; + case 24: + ActiveCircuit[ActiveActor]->EmergMaxVolts = Parser[ActiveActor]->MakeDouble_(); + break; + case 25: + ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Set_Mean( (Parser[ActiveActor]->MakeDouble_()) / 100.0); + break; + case 26: + ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Set_StdDev( (Parser[ActiveActor]->MakeDouble_()) / 100.0); + break; + case 27: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with30 = ActiveCircuit[ActiveActor]; + with30->LoadDurCurve = Param; + with30->LoadDurCurveObj = (TLoadShapeObj*) LoadShapeClass[ActiveActor]->Find(Param); + if(with30->LoadDurCurveObj == nullptr) + DoSimpleMsg("Load-Duration Curve not found.", 131); + } + break; + case 28: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with30 = ActiveCircuit[ActiveActor]; + with30->DefaultGrowthRate = 1.0 + Parser[ActiveActor]->MakeDouble_() / 100.0; + with30->DefaultGrowthFactor = pow(with30->DefaultGrowthRate, (with30->Solution->get_Fyear() - 1)); + } + break; + case 29: + ActiveCircuit[ActiveActor]->AutoAddObj.GenkW = Parser[ActiveActor]->MakeDouble_(); + break; + case 30: + ActiveCircuit[ActiveActor]->AutoAddObj.GenPF = Parser[ActiveActor]->MakeDouble_(); + break; + case 31: + ActiveCircuit[ActiveActor]->AutoAddObj.Capkvar = Parser[ActiveActor]->MakeDouble_(); + break; + case 32: + ActiveCircuit[ActiveActor]->AutoAddObj.AddType = InterpretAddType(Param); + break; + case 33: + ActiveCircuit[ActiveActor]->DuplicatesAllowed = InterpretYesNo(Param); + break; + case 34: + ActiveCircuit[ActiveActor]->ZonesLocked = InterpretYesNo(Param); + break; + case 35: + ActiveCircuit[ActiveActor]->UEWeight = Parser[ActiveActor]->MakeDouble_(); + break; + case 36: + ActiveCircuit[ActiveActor]->LossWeight = Parser[ActiveActor]->MakeDouble_(); + break; + case 37: + ParseIntArray(ActiveCircuit[ActiveActor]->UEregs, ActiveCircuit[ActiveActor]->NumUEregs, Param); + break; + case 38: + ParseIntArray(ActiveCircuit[ActiveActor]->LossRegs, ActiveCircuit[ActiveActor]->NumLossRegs, Param); + break; + case 39: + DoLegalVoltageBases(); + break; + case 40: + ActiveCircuit[ActiveActor]->Solution->Algorithm = InterpretSolveAlg(Param); + if (ActiveCircuit[ActiveActor]->Solution->Algorithm == NCIMSOLVE) + ActiveCircuit[ActiveActor]->Solution->NCIMRdy = false; + break; + case 41: + ActiveCircuit[ActiveActor]->TrapezoidalIntegration = InterpretYesNo(Param); + break; + case 42: + DoAutoAddBusList(Param); + break; + case 43: + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with5 = ActiveCircuit[ActiveActor]->Solution; + with5->ControlMode = InterpretControlMode(Param); + with5->DefaultControlMode = with5->ControlMode; // always revert to last one specified in a script + // if(ADiakoptics && (ActiveActor == 1)) + // with5->SendCmd2Actors(with5->GETCTRLMODE); + } + break; + case 44: + ActiveCircuit[ActiveActor]->ControlQueue.Set_Trace(InterpretYesNo(Param)); + break; + case 45: + ActiveCircuit[ActiveActor]->GenMultiplier = Parser[ActiveActor]->MakeDouble_(); + break; + case 46: + { + TestLoadShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActiveActor]->Find(Param)); + if(TestLoadShapeObj != nullptr) + ActiveCircuit[ActiveActor]->DefaultDailyShapeObj = TestLoadShapeObj; + } + break; + case 47: + { + TestLoadShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActiveActor]->Find(Param)); + if(TestLoadShapeObj != nullptr) + ActiveCircuit[ActiveActor]->DefaultYearlyShapeObj = TestLoadShapeObj; + } + break; + case 48: + DoSetAllocationFactors(Parser[ActiveActor]->MakeDouble_()); + break; + case 49: + ActiveCircuit[ActiveActor]->PositiveSequence = InterpretCktModel(Param); + break; + case 50: + ActiveCircuit[ActiveActor]->PriceSignal = Parser[ActiveActor]->MakeDouble_(); + break; + case 51: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with31 = ActiveCircuit[ActiveActor]; + with31->PriceCurve = Param; + with31->PriceCurveObj = (TPriceShapeObj*) PriceShapeClass[ActiveActor]->Find(Param); + if(with31->PriceCurveObj == nullptr) + DoSimpleMsg(String("Priceshape.") + Param + " not found.", 132); + } + break; + case 52: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with31 = ActiveCircuit[ActiveActor]; + if(with31->get_FActiveCktElement() != nullptr) + /*# with ActiveCktElement do */ + { + auto with8 = with31->get_FActiveCktElement(); + with8->Set_ActiveTerminal(Parser[ActiveActor]->MakeInteger_()); + SetActiveBus(StripExtension(with8->GetBus(with8->get_FActiveTerminal()))); // bus connected to terminal + } + } + break; + case 53: + { + ActiveCircuit[ActiveActor]->Fundamental = Parser[ActiveActor]->MakeDouble_(); // Set Base Frequency for system (used henceforth) + ActiveCircuit[ActiveActor]->Solution->Set_Frequency(Parser[ActiveActor]->MakeDouble_()); + } + break; + case 54: + DoHarmonicsList(Param); + break; + case 55: + { + ActiveCircuit[ActiveActor]->Solution->MaxControlIterations = Parser[ActiveActor]->MakeInteger_(); + if(ADiakoptics && (ActiveActor == 1)) + ActiveCircuit[ActiveActor]->Solution->SendCmd2Actors(GETCTRLMODE); + } + break; + case 56: + result = SetActiveBus(Param); + break; // See DSSGlobals + case 57: + SetDataPath(Param); + break; // Set a legal data path + case 58: + DoKeeperBusList(Param); + break; + case 59: + DoSetReduceStrategy(Param); + break; + case 60: + EnergyMeterClass[ActiveActor]->Set_SaveDemandInterval(ActiveActor, InterpretYesNo(Param)); + break; + case 61: + { + ActiveCircuit[ActiveActor]->PctNormalFactor = Parser[ActiveActor]->MakeDouble_(); + DoSetNormal(ActiveCircuit[ActiveActor]->PctNormalFactor); + } + break; + case 62: + EnergyMeterClass[ActiveActor]->Set_DI_Verbose(ActiveActor, InterpretYesNo(Param)); + break; + case 63: + ActiveCircuit[ActiveActor]->Set_CaseName(Parser[ActiveActor]->MakeString_()); + break; + case 64: + ActiveCircuit[ActiveActor]->NodeMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 65: + ActiveCircuit[ActiveActor]->NodeMarkerWidth = Parser[ActiveActor]->MakeInteger_(); + break; + case 66: + ActiveCircuit[ActiveActor]->LogEvents = InterpretYesNo(Param); + break; + case 67: + DSSExecutive[ActiveActor]->Set_RecorderOn(InterpretYesNo(Param)); + break; + case 68: + EnergyMeterClass[ActiveActor]->Do_OverloadReport = InterpretYesNo(Param); + break; + case 69: + EnergyMeterClass[ActiveActor]->Do_VoltageExceptionReport = InterpretYesNo(Param); + break; + case 70: + DoSetCFactors(Parser[ActiveActor]->MakeDouble_()); + break; + case 71: + AutoShowExport = InterpretYesNo(Param); + break; + case 72: + MaxAllocationIterations = Parser[ActiveActor]->MakeInteger_(); + break; + case 73: + { + DefaultBaseFreq = Parser[ActiveActor]->MakeDouble_(); + ActiveCircuit[ActiveActor]->Fundamental = Parser[ActiveActor]->MakeDouble_(); // Set Base Frequency for system (used henceforth) + ActiveCircuit[ActiveActor]->Solution->Set_Frequency(Parser[ActiveActor]->MakeDouble_()); + } + break; + case 74: + ActiveCircuit[ActiveActor]->MarkSwitches = InterpretYesNo(Param); + break; + case 75: + ActiveCircuit[ActiveActor]->SwitchMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 76: + DaisySize = Parser[ActiveActor]->MakeDouble_(); + break; + case 77: + ActiveCircuit[ActiveActor]->MarkTransformers = InterpretYesNo(Param); + break; + case 78: + ActiveCircuit[ActiveActor]->TransMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 79: + ActiveCircuit[ActiveActor]->TransMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 80: + ActiveCircuit[ActiveActor]->ActiveLoadShapeClass = InterpretLoadShapeClass(Param); + break; + case 81: + DefaultEarthModel = InterpretEarthModel(Param); + break; + case 82: + { + LogQueries = InterpretYesNo(Param); + if(LogQueries) + ResetQueryLogFile(); + } + break; + case 83: + ActiveCircuit[ActiveActor]->MarkCapacitors = InterpretYesNo(Param); + break; + case 84: + ActiveCircuit[ActiveActor]->MarkRegulators = InterpretYesNo(Param); + break; + case 85: + ActiveCircuit[ActiveActor]->MarkPVSystems = InterpretYesNo(Param); + break; + case 86: + ActiveCircuit[ActiveActor]->MarkStorage = InterpretYesNo(Param); + break; + case 87: + ActiveCircuit[ActiveActor]->CapMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 88: + ActiveCircuit[ActiveActor]->RegMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 89: + ActiveCircuit[ActiveActor]->PVMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 90: + ActiveCircuit[ActiveActor]->StoreMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 91: + ActiveCircuit[ActiveActor]->CapMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 92: + ActiveCircuit[ActiveActor]->RegMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 93: + ActiveCircuit[ActiveActor]->PVMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 94: + ActiveCircuit[ActiveActor]->StoreMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 95: + ActiveCircuit[ActiveActor]->NeglectLoadY = InterpretYesNo(Param); + break; + case 96: + ActiveCircuit[ActiveActor]->MarkFuses = InterpretYesNo(Param); + break; + case 97: + ActiveCircuit[ActiveActor]->FuseMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 98: + ActiveCircuit[ActiveActor]->FuseMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 99: + ActiveCircuit[ActiveActor]->MarkReclosers = InterpretYesNo(Param); + break; + case 100: + ActiveCircuit[ActiveActor]->RecloserMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 101: + ActiveCircuit[ActiveActor]->RecloserMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 102: + UpdateRegistry = InterpretYesNo(Param); + break; + case 103: + ActiveCircuit[ActiveActor]->MarkRelays = InterpretYesNo(Param); + break; + case 104: + ActiveCircuit[ActiveActor]->RelayMarkerCode = Parser[ActiveActor]->MakeInteger_(); + break; + case 105: + ActiveCircuit[ActiveActor]->RelayMarkerSize = Parser[ActiveActor]->MakeInteger_(); + break; + case 107: + ActiveCircuit[ActiveActor]->Solution->Set_Total_Time(Parser[ActiveActor]->MakeDouble_()); + break; + case 112: + { + if(Parser[ActiveActor]->MakeString_() == "*") + { + AllActors = true; + ActiveActor = 1; + } + else + { + if(Parser[ActiveActor]->MakeInteger_() <= NumOfActors) + { + ActiveActor = Parser[ActiveActor]->MakeInteger_(); + AllActors = false; + } + else + { + DoSimpleMsg("The actor does not exists", 7002); + } + } + } + break; + case 113: + { + if(Parser[ActiveActor]->MakeInteger_() < CPU_Cores) + { + ActorCPU[ActiveActor] = Parser[ActiveActor]->MakeInteger_(); + if(ActorHandle[ActiveActor] != nullptr) + { + //ActorHandle[ActiveActor]->CPU = ActorCPU[ActiveActor]; + //ActorHandle[ActiveActor]->Priority = tpTimeCritical; + } + } + else + { + DoSimpleMsg("The CPU does not exists", 7003); + } + } + break; + case 115: + { + Parallel_enabled = InterpretYesNo(Param); + } + break; + case 116: + { + ConcatenateReports = InterpretYesNo(Param); + } + break; + case 117: + { + DSS_Viz_enable = InterpretYesNo(Param); + } + break; + case 119: + { + ActiveCircuit[ActiveActor]->Coverage = Parser[ActiveActor]->MakeDouble_(); + } + break; + case 120: + { + ActiveCircuit[ActiveActor]->Num_SubCkts = Parser[ActiveActor]->MakeInteger_(); + } + break; + case 121: + ActiveCircuit[ActiveActor]->Solution->SampleTheMeters = InterpretYesNo(Param); + break; + case 122: + { + if(InterpretYesNo(Param)) + { + if(!ADiakoptics) // Initalizes the parallel environment if enabled + ADiakopticsInit(); + else + DoSimpleMsg("A-Diakoptics is already active, please use ClearAll and recompile the source mode" + " before activating A-Diakoptics again.", 7010); + } + else + ADiakoptics = false; + } + break; + case 123: + ActiveCircuit[ActiveActor]->Solution->MinIterations = Parser[ActiveActor]->MakeInteger_(); + break; + case 124: + { + myList = new TStringList(); + InterpretTStringListArray(Param, *myList); + if(myList->size() <= (CPU_Cores - 3)) + { + int stop = 0; + ActiveCircuit[ActiveActor]->Link_Branches.resize(myList->size() + 1); + for(stop = myList->size(), i = 1; i <= stop; i++) + { + ActiveCircuit[ActiveActor]->Link_Branches[i] = (*myList)[i]; + } + } + else + { + DoSimpleMsg("The number of link branches exceeds the number of available CPUs for circuit tearing", 7009); + ActiveCircuit[ActiveActor]->Link_Branches.clear(); + } + delete myList; + } + break; + case 125: + ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad = InterpretYesNo(Param); + break; + case 126: + ActiveCircuit[ActiveActor]->ReductionZmag = Parser[ActiveActor]->MakeDouble_(); + break; + case 127: + SeasonalRating = InterpretYesNo(Param); + break; + case 128: + SeasonSignal = Param; + break; + // deprecated 130: ActiveCircuit[ActiveActor]->MarkPVSystems2 := InterpretYesNo(Param); + // deprecated 132: ActiveCircuit[ActiveActor]->MarkStorage2 := InterpretYesNo(Param); + case 131: + { + Parser[ActiveActor]->ParseAsVector(4, GISCoords); + } + break; + case 132: + { + GISColor = Parser[ActiveActor]->MakeString_(); + } + break; + case 133: + { + GISThickness = Parser[ActiveActor]->MakeString_(); + } + break; + case 134: + { + UseUserLinks = InterpretYesNo(Param); + } + break; + case 136: + { + EventLogDefault = InterpretYesNo(Param); + } + break; + case 137: + { + ActiveCircuit[ActiveActor]->LongLineCorrection = InterpretYesNo(Param); + } + break; + case 138: + { + AutoDisplayShowReport = InterpretYesNo(Param); + } + break; + case 139: + { + ActiveCircuit[ActiveActor]->Solution->IgnoreQLimit = InterpretYesNo(Param); + } + break; + case 140: + ActiveCircuit[ActiveActor]->Solution->GenGainNCIM = Parser[ActiveActor]->MakeDouble_(); + break; + case 141: + { + auto with3 = ActiveCircuit[ActiveActor]; + string TmpStr = Parser[ActiveActor]->MakeString_(); + string VarPCE[3] = { "generator", "windgen", "storage" }; + int i = with3->SetElementActive(TmpStr); + if (i == 0) + DoSimpleMsg("Object " + TmpStr + " not found", 7100); + else + { + TmpStr = LowerCase(StripExtension(TmpStr)); + bool ValidObj = false; + for (i = 0; i < 3; i++) + { + ValidObj = ValidObj || (VarPCE[i] == TmpStr); + } + + if (ValidObj) + { + Parser[ActiveActor]->GetNextParam(); + TmpStr = LowerCase(Parser[ActiveActor]->MakeString_()); + // Search for the variable within the object + ValidObj = false; + for (i = 1; i <= ((TPCElement*)with3->FActiveCktElement)->NumStateVars; i++) + { + if (LowerCase(((TPCElement*)with3->FActiveCktElement)->VariableName(i)) == TmpStr) + { + ValidObj = true; + break; + } + } + + if (ValidObj) + { + // Once found, modifies the value + Parser[ActiveActor]->GetNextParam(); + ((TPCElement*)with3->FActiveCktElement)->Set_Variable(i, Parser[ActiveActor]->MakeDouble_()); + } + else + DoSimpleMsg("State variable " + TmpStr + " not found", 7102); + } + else + DoSimpleMsg("Object " + TmpStr + " is not a valid element for this command. Only generators, storage and WindGen.", 7101); + } + } + break; + // Ignore excess parameters + default: + ; + break; + } + switch(ParamPointer) + { + case 3: + case 4: + ActiveCircuit[ActiveActor]->Solution->Update_dblHour(); + break; + case 137: + { + TLineObj* LineObj = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (LineObj != nullptr) + { + if (LineObj->FEnabled && LineObj->SymComponentsModel) + LineObj->Set_YprimInvalid(ActiveActor, true); + } + } + break; + + case 135: + { + // Do nothing + } + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } /*WHILE*/ + if(SolveOption == 1) + DoSolveCmd(); + return result; + } + //---------------------------------------------------------------------------- + + // Set DSS Options + // Solve Command is re-routed here first to set options beFORe solving + + + + //---------------------------------------------------------------------------- + + int DoGetCmd() + { + int result = 0; + int ParamPointer = 0; + int i = 0; + String TempString; + String ParamName; + String Param; + // TScriptEdit* ScriptEd = nullptr; + result = 0; + try + { + GlobalResult = ""; //initialize for appending + + // Continue parsing command line + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + // there will be no named paramters in this command and the params + // themselves will be the parameter name to return + while (Param.size() > 0) + { + ParamPointer = OptionList->Getcommand(Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Get Command ", 133); + break; + case 1: case 12: + AppendGlobalResult(ActiveCircuit[ActiveActor]->get_FActiveCktElement()->Get_myPName()); + break; + case 2: case 13: + AppendGlobalResult(ActiveCircuit[ActiveActor]->get_FActiveCktElement()->get_Name()); + break; + case 3: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour)); + break; + case 4: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->DynaVars.T)); + break; + case 5: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->get_Fyear())); + break; + case 6: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->get_FFrequency())); + break; + case 7: case 18: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->DynaVars.h)); + break; + case 8: + AppendGlobalResult(GetSolutionModeID()); + break; + case 9: + AppendGlobalResult(GetRandomModeID()); + break; + case 10: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->NumberOfTimes)); + break; + case 11: + AppendGlobalResult(Format("[ %d, %-g ] !... %-g (hours)", ActiveCircuit[ActiveActor]->Solution->DynaVars.intHour, ActiveCircuit[ActiveActor]->Solution->DynaVars.T, ActiveCircuit[ActiveActor]->Solution->DynaVars.dblHour)); + break; + case 14: + AppendGlobalResult(ActiveCircuit[ActiveActor]->Get_Name()); + break; + case 15: + AppendGlobalResult(DefaultEditor); + break; + case 16: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->ConvergenceTolerance)); + break; + case 17: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->MaxIterations)); + break; + case 19: + AppendGlobalResult(GetLoadModel()); + break; + case 20: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->get_FLoadMultiplier())); + break; + case 21: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->NormalMinVolts)); + break; + case 22: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->NormalMaxVolts)); + break; + case 23: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->EmergMinVolts)); + break; + case 24: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->EmergMaxVolts)); + break; + case 25: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Get_Mean() * 100.0)); + break; + case 26: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->Get_StdDev() * 100.0)); + break; + case 27: + AppendGlobalResult(ActiveCircuit[ActiveActor]->LoadDurCurve); + break; + case 28: + AppendGlobalResult(Format("%-g", (ActiveCircuit[ActiveActor]->DefaultGrowthRate - 1.0) * 100.0)); + break; + case 29: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->AutoAddObj.GenkW)); + break; + case 30: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->AutoAddObj.GenPF)); + break; + case 31: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->AutoAddObj.Capkvar)); + break; + case 32: + switch (ActiveCircuit[ActiveActor]->AutoAddObj.AddType) + { + case GENADD: + AppendGlobalResult("generator"); + break; + case CAPADD: + AppendGlobalResult("capacitor"); + break; + default: + ; + break; + } + break; + case 33: + if (ActiveCircuit[ActiveActor]->DuplicatesAllowed) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 34: + if (ActiveCircuit[ActiveActor]->ZonesLocked) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 35: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->UEWeight)); + break; + case 36: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->LossWeight)); + break; + case 37: + AppendGlobalResult(IntArrayToString(ActiveCircuit[ActiveActor]->UEregs, ActiveCircuit[ActiveActor]->NumUEregs)); + break; + case 38: + AppendGlobalResult(IntArrayToString(ActiveCircuit[ActiveActor]->LossRegs, ActiveCircuit[ActiveActor]->NumLossRegs)); + break; + case 39: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with32 = ActiveCircuit[ActiveActor]; + i = 0; + GlobalResult = "("; + while ((with32->LegalVoltageBases)[i] > 0.0) + { + GlobalResult = GlobalResult + Format("%-g, ", (with32->LegalVoltageBases)[i]); + ++i; + } + GlobalResult = GlobalResult + ")"; + } + break; + case 40: + switch (ActiveCircuit[ActiveActor]->Solution->Algorithm) + { + case NORMALSOLVE: + AppendGlobalResult("normal"); + break; + case NEWTONSOLVE: + AppendGlobalResult("newton"); + break; + case NCIMSOLVE: + AppendGlobalResult("ncim"); + break; + default: + ; + break; + } + break; + case 41: + if (ActiveCircuit[ActiveActor]->TrapezoidalIntegration) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 42: + /*# with ActiveCircuit[ActiveActor]->AutoAddBusList do */ + { + auto& with1 = ActiveCircuit[ActiveActor]->AutoAddBusList; + int stop = 0; + for (stop = with1.Get_NumElements(), i = 1; i <= stop; i++) + { + AppendGlobalResult(with1.Get(i)); + } + } + break; + case 43: + AppendGlobalResult(GetControlModeID()); + break; + case 44: + if (ActiveCircuit[ActiveActor]->ControlQueue.get_DebugTrace()) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 45: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->GenMultiplier)); + break; + case 46: + AppendGlobalResult(ActiveCircuit[ActiveActor]->DefaultDailyShapeObj->get_Name()); + break; + case 47: + AppendGlobalResult(ActiveCircuit[ActiveActor]->DefaultYearlyShapeObj->get_Name()); + break; + case 48: + AppendGlobalResult("Get function not applicable."); + break; + case 49: + if (ActiveCircuit[ActiveActor]->PositiveSequence) + AppendGlobalResult("positive"); + else + AppendGlobalResult("multiphase"); + break; + case 50: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->PriceSignal)); + break; + case 51: + AppendGlobalResult(ActiveCircuit[ActiveActor]->PriceCurve); + break; + case 52: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->get_FActiveCktElement()->get_FActiveTerminal())); + break; + case 53: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Fundamental)); + break; + case 54: + /*# with ActiveCircuit[ActiveActor]->Solution do */ + { + auto with2 = ActiveCircuit[ActiveActor]->Solution; + if (with2->DoAllHarmonics) + AppendGlobalResult("ALL"); + else + { + int stop = 0; + for (stop = with2->HarmonicListSize, i = 1; i <= stop; i++) + { + AppendGlobalResult(Format("%-g", with2->HarmonicList[i])); + } + } + } + break; + case 55: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->MaxControlIterations)); + break; + case 56: + AppendGlobalResult(ActiveCircuit[ActiveActor]->BusList.Get(ActiveCircuit[ActiveActor]->ActiveBusIndex + 1)); + break; + case 57: + AppendGlobalResult(DataDirectory[ActiveActor]); + break; // NOTE - not necessarily output directory + case 58: + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with33 = ActiveCircuit[ActiveActor]; + int stop = 0; + for (stop = with33->NumBuses, i = 1; i <= stop; i++) + { + if (with33->Buses[i - 1]->Keep) + AppendGlobalResult(with33->BusList.Get(i)); + } + } + break; + case 59: + AppendGlobalResult(ActiveCircuit[ActiveActor]->ReductionStrategyString); + break; + case 60: + if (EnergyMeterClass[ActiveActor]->Get_SaveDemandInterval(ActiveActor)) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 61: + AppendGlobalResult(Format("%-.g", ActiveCircuit[ActiveActor]->PctNormalFactor)); + break; + case 62: + if (EnergyMeterClass[ActiveActor]->Get_DI_Verbose(ActiveActor)) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 63: + AppendGlobalResult(ActiveCircuit[ActiveActor]->get_FCaseName()); + break; + case 64: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->NodeMarkerCode)); + break; + case 65: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->NodeMarkerWidth)); + break; + case 66: + if (ActiveCircuit[ActiveActor]->LogEvents) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 67: + if (DSSExecutive[ActiveActor]->get_FRecorderOn()) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 68: + if (EnergyMeterClass[ActiveActor]->Do_OverloadReport) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 69: + if (EnergyMeterClass[ActiveActor]->Do_VoltageExceptionReport) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 70: + AppendGlobalResult("Get function not applicable."); + break; + case 71: + if (AutoShowExport) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 72: + AppendGlobalResult(Format("%d", MaxAllocationIterations)); + break; + case 73: + AppendGlobalResult(Format("%d", Round(DefaultBaseFreq))); + break; + case 74: + if (ActiveCircuit[ActiveActor]->MarkSwitches) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 75: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->SwitchMarkerCode)); + break; + case 76: + AppendGlobalResult(Format("%-.6g", DaisySize)); + break; + case 77: + if (ActiveCircuit[ActiveActor]->MarkTransformers) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 78: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->TransMarkerCode)); + break; + case 79: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->TransMarkerSize)); + break; + case 80: + AppendGlobalResult(GetActiveLoadShapeClass()); + break; + case 81: + AppendGlobalResult(GetEarthModel(DefaultEarthModel)); + break; + case 82: + if (LogQueries) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 83: + if (ActiveCircuit[ActiveActor]->MarkCapacitors) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 84: + if (ActiveCircuit[ActiveActor]->MarkRegulators) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 85: + if (ActiveCircuit[ActiveActor]->MarkPVSystems) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 86: + if (ActiveCircuit[ActiveActor]->MarkStorage) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 87: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->CapMarkerCode)); + break; + case 88: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RegMarkerCode)); + break; + case 89: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->PVMarkerCode)); + break; + case 90: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->StoreMarkerCode)); + break; + case 91: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->CapMarkerSize)); + break; + case 92: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RegMarkerSize)); + break; + case 93: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->PVMarkerSize)); + break; + case 94: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->StoreMarkerSize)); + break; + case 95: + if (ActiveCircuit[ActiveActor]->NeglectLoadY) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 96: + if (ActiveCircuit[ActiveActor]->MarkFuses) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 97: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->FuseMarkerCode)); + break; + case 98: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->FuseMarkerSize)); + break; + case 99: + if (ActiveCircuit[ActiveActor]->MarkReclosers) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 100: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RecloserMarkerCode)); + break; + case 101: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RecloserMarkerSize)); + break; + case 102: + UpdateRegistry = InterpretYesNo(Param); + break; + case 103: + if (ActiveCircuit[ActiveActor]->MarkRelays) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 104: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RelayMarkerCode)); + break; + case 105: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->RelayMarkerSize)); + break; + case 106: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->get_Solve_Time_Elapsed())); + break; + case 107: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->get_Total_Time_Elapsed())); + break; + case 108: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->get_Step_Time_Elapsed())); + break; + case 109: + AppendGlobalResult(Format("%d", CPU_Cores)); + break; + case 110: + AppendGlobalResult(Format("%d", CPU_Physical)); + break; + case 111: + AppendGlobalResult(Format("%d", NumOfActors)); + break; + case 112: + { + if (AllActors) + AppendGlobalResult("All"); + else + AppendGlobalResult(Format("%d", ActiveActor)); + } + break; + case 113: + AppendGlobalResult(Format("%d", ActorCPU[ActiveActor])); + break; + case 114: + { + std::string myProgress = ""; + for (int idx = 1; idx <= NumOfActors; idx++) + myProgress = myProgress + to_string(ActorPctProgress[idx]) + ", "; + CoutLn(myProgress); + } + //ScriptEd->UpdateProgressSummary(); + break; + case 115: + if (Parallel_enabled) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 116: + if (ConcatenateReports) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 117: + if (DSS_Viz_enable) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 118: + if (DSS_Viz_installed) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 119: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Actual_Coverage)); + break; + case 120: + AppendGlobalResult(Format("%d", ActiveCircuit[ActiveActor]->Num_SubCkts)); + break; + case 121: + if (ActiveCircuit[ActiveActor]->Solution->SampleTheMeters) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 122: + if (ADiakoptics) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 123: + AppendGlobalResult(IntToStr(ActiveCircuit[ActiveActor]->Solution->MinIterations)); + break; + case 124: + { + int stop = 0; + ActiveActor = 1; + for (stop = (ActiveCircuit[ActiveActor]->Link_Branches.size() - 1), i = 0; i <= stop; i++) + { + AppendGlobalResult(ActiveCircuit[ActiveActor]->Link_Branches[i]); + } + } + break; + case 125: + if (ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 126: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->ReductionZmag)); + break; + case 127: + if (SeasonalRating) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 128: + AppendGlobalResult(SeasonSignal); + break; + case 129: + //AppendGlobalResult(Format("%d", NumNUMA)))); + break; + case 130: + if (DSS_GIS_installed) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 134: + if (UseUserLinks) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 135: + GlobalResult = GetLineTypes(); + break; + case 136: + { + if (EventLogDefault) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + } + break; + case 137: + { + if (ActiveCircuit[ActiveActor]->LongLineCorrection) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + } + break; + case 138: + { + if (AutoDisplayShowReport) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + } + break; + case 139: + if (ActiveCircuit[ActiveActor]->Solution->IgnoreQLimit) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 140: + AppendGlobalResult(Format("%-g", ActiveCircuit[ActiveActor]->Solution->GenGainNCIM)); + break; + case 141: + { + auto with4 = ActiveCircuit[ActiveActor]; + Parser[ActiveActor]->GetNextParam(); + string TmpStr = Parser[ActiveActor]->MakeString_(); + string VarPCE[3] = { "generator", "storage", "windgen" }; + bool ValidObj = false; + int i = 0; + + TmpStr = LowerCase(StripExtension(TmpStr)); + for (i = 0; i < 3; i++) + ValidObj = ValidObj || (VarPCE[i] == TmpStr); + + if (ValidObj) + { + Parser[ActiveActor]->GetNextParam(); + TmpStr = LowerCase(Parser[ActiveActor]->MakeString_()); + // Search for the variable within the object + ValidObj = false; + for (i = 1; i <= ((TPCElement*)with4->FActiveCktElement)->NumStateVars; i++) + { + if (LowerCase(((TPCElement*)with4->FActiveCktElement)->VariableName(i)) == TmpStr) + { + ValidObj = true; + break; + } + } + if (ValidObj) + AppendGlobalResult(Format("%-g", ((TPCElement*)with4->FActiveCktElement)->VariableName(i))); + else + DoSimpleMsg("State variable " + TmpStr + " not found", 7102); + } + else + DoSimpleMsg("Object " + TmpStr + " is not a valid element for this command. Only generators, storage and WindGen.", 7101); + } + break; + // Ignore excess parameters + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } /*WHILE*/ + } + catch (...) + { + AppendGlobalResult("***Error***"); + } + return result; + } + + // Get DSS Options Reguest and put it in Global Result string + // may be retrieved by Result property of the DSSText interface + + + //---------------------------------------------------------------------------- + + bool DoGetCmd_NoCircuit() + { + bool result = false; + int ParamPointer = 0; + int i = 0; + String ParamName; + String Param; + result = false; + try + { + GlobalResult = ""; //initialize for appending + + // Continue parsing command line + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + // there will be no named paramters in this command and the params + // themselves will be the parameter name to return + while(Param.size() > 0) + { + ParamPointer = OptionList->Getcommand(Param); + switch(ParamPointer) + { + case 109: + AppendGlobalResult(to_string(CPU_Cores)); + break; + case 110: + { + if(CPU_Cores < 64) + AppendGlobalResult(to_string(CPU_Cores / 2)); + else + AppendGlobalResult(to_string(CPU_Cores)); + } + break; + case 111: + AppendGlobalResult(to_string(NumOfActors)); + break; + case 112: + { + if(AllActors) + AppendGlobalResult("All"); + else + AppendGlobalResult(to_string(ActiveActor)); + } + break; + case 113: + AppendGlobalResult(to_string(ActorCPU[ActiveActor])); + break; + case 115: + if(Parallel_enabled) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 116: + if(ConcatenateReports) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 117: + if(DSS_Viz_enable) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + case 118: + if(DSS_Viz_installed) + AppendGlobalResult("Yes"); + else + AppendGlobalResult("No"); + break; + default: + DoSimpleMsg("You must create a new circuit object first: \"new circuit.mycktname\" to execute this Set command.", 301); + result = false; // Indicate that we could not process all set command + return result; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + } /*WHILE*/ + } + catch(...) + { + AppendGlobalResult("***Error***"); + } + return result; + } + + // Get DSS Options Reguest and put it in Global Result string + // may be retrieved by Result property of the DSSText interface + + void DisposeStrings() + { + delete[] ExecOption; + delete[] OptionHelp; + } + + + void ExecOptions_initialization() + { + DefineOptions(); + } + + void ExecOptions_finalization() + { + DisposeStrings(); + } + + class ExecOptions_unit + { + public: + ExecOptions_unit() + { + //AssertSystemInitialization(); + ExecOptions_initialization(); + } + ~ ExecOptions_unit(){ExecOptions_finalization(); } + }; + ExecOptions_unit _ExecOptions_unit; + +} // namespace ExecOptions + + + + diff --git a/OpenDSSC/Executive/ExecOptions.h b/OpenDSSC/Executive/ExecOptions.h new file mode 100644 index 0000000..dc92f39 --- /dev/null +++ b/OpenDSSC/Executive/ExecOptions.h @@ -0,0 +1,51 @@ +#ifndef ExecOptionsH +#define ExecOptionsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "ParserDel.h" +#include +#include "Executive.h" +#include "ExecHelper.h" +#include "LoadShape.h" +#include "Utilities.h" +#include "Solution.h" +#include "EnergyMeter.h" +#include "Diakoptics.h" + +namespace ExecOptions +{ + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2024, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + const int NumExecOptions = 141; + extern std::string* ExecOption; + extern std::string* OptionHelp; + extern Command::TCommandList* OptionList; + int DoGetCmd(); + int DoSetCmd(int SolveOption); + bool DoSetCmd_NoCircuit(); // Set Commands that do not require a circuit + bool DoGetCmd_NoCircuit(); // Get Commands that do not require a circuit + + +} // namespace ExecOptions + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExecOptions; +#endif + +#endif // ExecOptionsH + + + + diff --git a/OpenDSSC/Executive/Executive.cpp b/OpenDSSC/Executive/Executive.cpp new file mode 100644 index 0000000..ea1e8bd --- /dev/null +++ b/OpenDSSC/Executive/Executive.cpp @@ -0,0 +1,255 @@ + +#pragma hdrstop + +#include "Executive.h" + +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Solution.h" +#include "CmdForms.h" +#include "klusolve.h" +#include "ExecCommands.h" +#include "ExecOptions.h" + +using namespace std; + + +namespace Executive +{ + + + /*ExecHelper,*/ + + +//---------------------------------------------------------------------------- + +TExecutive::TExecutive() + : FRecorderOn(false), + FRecorderFile("") +{ + ; + + + // Exec Commands + CommandList = TCommandList(ExecCommand, NumExecCommands); + + // Exec options + OptionList = new TCommandList(ExecOption, NumExecOptions); + /*Instantiate All DSS Classe Definitions, Intrinsic and User-defined*/ + CreateDSSClasses(); // in DSSGlobals + Circuits = TPointerList(2); // default buffer for 2 active circuits +// ActiveCircuit[ActiveActor] := nil; +// Parser := TParser.Create; // Create global parser object (in DSS globals) + LastCmdLine = ""; + RedirFile = ""; + ReadDSS_Registry(); + + /*Override Locale defaults so that CSV files get written properly*/ +// FormatSettings.DecimalSeparator = L'.'; +// FormatSettings.ThousandSeparator = L','; +} + + +//---------------------------------------------------------------------------- + + TExecutive::~TExecutive() +{ + int i = 0; + + /*Write some global Variables to Registry*/ + WriteDSS_Registry(); + ClearAllCircuits(); + delete OptionList; + DisposeDSSClasses(true); + delete Parser[ActiveActor]; + Parser[ActiveActor] = nullptr; + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + +String TExecutive::Get_LastError() +{ + String result; + result = LastErrorMessage; + return result; +} + +//---------------------------------------------------------------------------- + +int TExecutive::Get_ErrorResult() +{ + int result = 0; + result = ErrorNumber; + return result; +} + + +//---------------------------------------------------------------------------- + + +/*Create default loadshapes, growthshapes, and other general DSS objects + used by all circuits. +*/ + +void TExecutive::CreateDefaultDSSItems() +{ + + +/* this load shape used for generator dispatching, etc. Loads may refer to it, also.*/ + Set_Command( "new loadshape.default npts=24 1.0 mult=(.677 .6256 .6087 .5833 .58028 .6025 .657 .7477 .832 .88 .94 .989 .985 .98 .9898 .999 1 .958 .936 .913 .876 .876 .828 .756)"); + if(CmdResult == 0) + { + Set_Command( "new growthshape.default 2 year=\"1 20\" mult=(1.025 1.025)"); // 20 years at 2.5% + Set_Command( "new spectrum.default 7 Harmonic=(1 3 5 7 9 11 13) %mag=(100 33 20 14 11 9 7) Angle=(0 0 0 0 0 0 0)"); + Set_Command( "new spectrum.defaultload 7 Harmonic=(1 3 5 7 9 11 13) %mag=(100 1.5 20 14 1 9 7) Angle=(0 180 180 180 180 180 180)"); + Set_Command( "new spectrum.defaultgen 7 Harmonic=(1 3 5 7 9 11 13) %mag=(100 5 3 1.5 1 .7 .5) Angle=(0 0 0 0 0 0 0)"); + Set_Command( "new spectrum.defaultvsource 1 Harmonic=(1 ) %mag=(100 ) Angle=(0 ) "); + Set_Command( "new spectrum.linear 1 Harmonic=(1 ) %mag=(100 ) Angle=(0 ) "); + Set_Command( "new spectrum.pwm6 13 Harmonic=(1 3 5 7 9 11 13 15 17 19 21 23 25) %mag=(100 4.4 76.5 62.7 2.9 24.8 12.7 0.5 7.1 8.4 0.9 4.4 3.3) Angle=(-103 -5 28 -180 -33 -59 79 36 -253 -124 3 -30 86)"); + Set_Command( "new spectrum.dc6 10 Harmonic=(1 3 5 7 9 11 13 15 17 19) %mag=(100 1.2 33.6 1.6 0.4 8.7 1.2 0.3 4.5 1.3) Angle=(-75 28 156 29 -91 49 54 148 -57 -46)"); + Set_Command( "New TCC_Curve.A 5 c_array=(1, 2.5, 4.5, 8.0, 14.) t_array=(0.15 0.07 .05 .045 .045) "); + Set_Command( "New TCC_Curve.D 5 c_array=(1, 2.5, 4.5, 8.0, 14.) t_array=(6 0.7 .2 .06 .02)"); + Set_Command( "New TCC_Curve.TLink 7 c_array=(2 2.1 3 4 6 22 50) t_array=(300 100 10.1 4.0 1.4 0.1 0.02)"); + Set_Command( "New TCC_Curve.KLink 6 c_array=(2 2.2 3 4 6 30) t_array=(300 20 4 1.3 0.41 0.02)"); + Set_Command( "New \"TCC_Curve.uv1547\" npts=2 C_array=(0.5, 0.9, ) T_array=(0.166, 2, )"); + Set_Command( "New \"TCC_Curve.ov1547\" npts=2 C_array=(1.1, 1.2, ) T_array=(2, 0.166, )"); + Set_Command( "New \"TCC_Curve.mod_inv\" npts=15 C_array=(1.1, 1.3, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 50, 100, ) T_array=(27.1053, 9.9029, 6.439, 3.8032, 2.4322, 1.9458, 1.6883, 1.5255, 1.4117, 1.3267, 1.2604, 1.2068, 0.9481, 0.7468, 0.6478, )"); + Set_Command( "New \"TCC_Curve.very_inv\" npts=15 C_array=(1.1, 1.3, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 50, 100, ) T_array=(93.872, 28.9113, 16.179, 7.0277, 2.9423, 1.7983, 1.3081, 1.0513, 0.8995, 0.8023, 0.7361, 0.6891, 0.5401, 0.4988, 0.493, )"); + Set_Command( "New \"TCC_Curve.ext_inv\" npts=15 C_array=(1.1, 1.3, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 50, 100, ) T_array=(134.4074, 40.9913, 22.6817, 9.5217, 3.6467, 2.0017, 1.2967, 0.9274, 0.7092, 0.5693, 0.4742, 0.4065, 0.1924, 0.133, 0.1245, )"); + Set_Command( "New \"TCC_Curve.definite\" npts=3 C_array=(1, 1.001, 100, ) T_array=(300, 1, 1, )"); + } +} + +String TExecutive::Get_Command() +{ + String result; + result = LastCmdLine; + return result; +} + +void TExecutive::Set_Command(String Value) +{ + int Idx = 0; + if(AllActors) // Applies the same command to all the actors + { + int stop = 0; + for(stop = NumOfActors, Idx = 1; Idx <= stop; Idx++) + { + if(AllActors) + ActiveActor = Idx; + ProcessCommand(Value); + } + } + else + { + ProcessCommand(Value); // Applies the command to the active actor + } +} + +void TExecutive::Clear() +{ + int i = 0; + if(ActiveCircuit[ActiveActor] != nullptr) + /*First get rid of all existing stuff*/ + { + Circuits = TPointerList(2); // Make a new list of circuits + DisposeDSSClasses(false); + ActiveCircuit[ActiveActor]->NumCircuits = 0; // <<<< added + delete ActiveCircuit[ActiveActor]; // ActiveCircuit[ActiveActor]->~TDSSCircuit(); // <<<< added + ActiveCircuit[ActiveActor] = nullptr; // <<<< added + // In case the actor hasn't been destroyed + if(ActorHandle[ActiveActor] != nullptr) + { + ActorHandle[ActiveActor]->Send_Message(EXIT_ACTOR); + //ActorHandle[ActiveActor]->WaitFor(); + delete ActorHandle[ActiveActor]; // ActorHandle[ActiveActor]->~TSolver(); + ActorHandle[ActiveActor] = nullptr; + } + + /*Now, Start over*/ + CreateDSSClasses(); + CreateDefaultDSSItems(); + RebuildHelpForm = true; // because class strings have changed + } +// if(!IsDLL) +// ControlPanel.UpdateElementBox; + DefaultEarthModel = DERI; + LogQueries = false; + MaxAllocationIterations = 2; + + /*Prepare for new variables*/ + delete ParserVars; + ParserVars = new TParserVar(100); // start with space for 100 variables +} + +void TExecutive::ClearAll() +{ + int i = 0; + /*First get rid of all existing stuff*/ + ClearAllCircuits(); + DisposeDSSClasses(true); + /*Now, Start over*/ + ActiveActor = 1; + CreateDSSClasses(); + if (Parser[ActiveActor] != NULL) + delete Parser[ActiveActor]; + Parser[ActiveActor] = new ParserDel::TParser(); + if (AuxParser[ActiveActor] != NULL) + delete AuxParser[ActiveActor]; + AuxParser[ActiveActor] = new ParserDel::TParser(); + CreateDefaultDSSItems(); + RebuildHelpForm = true; // because class strings have changed +// if(!isDLL) +// ControlPanel.UpdateElementBox; + /*Prepare for new variables*/ + delete ParserVars; + ParserVars = new TParserVar(100); // start with space for 100 variables + ActiveActor = 1; + NumOfActors = 1; +} + +void TExecutive::Set_RecorderOn(bool Value) +{ + if(Value) + { + if(!FRecorderOn) + { + FRecorderFile = GetOutputDirectory() + "DSSRecorder.DSS"; + AssignFile(RecorderFile, FRecorderFile); + } + Rewrite(RecorderFile); + IOResultToException(); + } + else + { + if(FRecorderOn) + { + CloseFile(RecorderFile); + } + } + GlobalResult = FRecorderFile; + FRecorderOn = Value; +} + +bool TExecutive::get_FRecorderOn() +{ + return FRecorderOn; +} + +void TExecutive::Write_to_RecorderFile(const String s) +{ + WriteLn(RecorderFile, s); +} + +//WriteDLLDebugFile('Executive'); + + + + +} // namespace Executive + + + + diff --git a/OpenDSSC/Executive/Executive.h b/OpenDSSC/Executive/Executive.h new file mode 100644 index 0000000..99bf2f7 --- /dev/null +++ b/OpenDSSC/Executive/Executive.h @@ -0,0 +1,97 @@ +#ifndef ExecutiveH +#define ExecutiveH + +#include "System.h" +#include "Sysutils.h" + +#include "PointerList.h" +#include "Command.h" +#include "d2c_structures.h" + +#include "DSSClassDefs.h" +#include "ParserDel.h" +#include "DSSClass.h" +#include "IniRegSave.h" + +#include + + +namespace Executive +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + /* Change Log + + 8/12/99 Added Show Zone Help string + + 10/11/99 Added Dump Commands option. Moved ExecCommand into Public area. + 10/12/99 ADded new AutoAdd options and revised behavior of New Command. + 10/14/99 Added UE weighting option + Fixed Redirect/Compile to change default directory. + 11/2/99 Added message in Open and Close cmd for ckt element not found. + 12/3/99 Fixed bug in command parser - needed quotes when rebuilding command line + 12/6/99 Merged Set and Solve commands + 1-14-00 Added Get Command + Added LossWeight, UEreg, lossreg properties + 2-20-00 Revised Helpform so that help strings won't go away after Clear + 3-2-00 Repaired some places where re-parsing would mess up on names with blanks + 3-10-00 Added FileEdit and Export commands + 3-20-00 Added DefaultDaily and DefaultYearly Options + 4-17-00 Moved bulk of functions to ExecHelper + Added AllocateLoads Command and AllocationFactors option + 8-23-00 Added Price Signal Option + 9-18-00 Fixed Dump Command Help + 9-20-00 Added Dynamic Mode + 10-3-00 Removed test for comment since '//' is now done in the Parser + 5/22/01 Changed behavior of Compile and Redirect with respect to directory changes. + 5/30/01 Add Set maxControlIterations + 7/19/01 Added Totals command, Capacity Command + 8/1/01 Revise the way the Capacity Command works + 9/12/02 Added Classes and UserClasses + 2/4/03 Added Set Bus= + Added Zsc, Zsc012. + Changed way Voltages command works + + */ + + class TExecutive : public TObject + { + public: + typedef TObject inherited; + //private: + bool FRecorderOn; + string FRecorderFile; + string Get_LastError(); + int Get_ErrorResult(); + string Get_Command(); + void Set_Command(String Value); + void Set_RecorderOn(bool Value); + bool get_FRecorderOn(); + public: + System::TTextRec RecorderFile; + TExecutive(); + virtual ~TExecutive(); + void CreateDefaultDSSItems(); + void Write_to_RecorderFile(const String s); + void Clear(); + void ClearAll(); + }; + +} // namespace Executive + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Executive; +#endif + +#endif // ExecutiveH + + + + diff --git a/OpenDSSC/Executive/ExportOptions.cpp b/OpenDSSC/Executive/ExportOptions.cpp new file mode 100644 index 0000000..b1bb40c --- /dev/null +++ b/OpenDSSC/Executive/ExportOptions.cpp @@ -0,0 +1,913 @@ + + +#pragma hdrstop + +#include "ExportOptions.h" + + + +using namespace std; +using namespace Command; +using namespace DSSGlobals; +using namespace EnergyMeter; +using namespace Monitor; +using namespace NamedObject; +using namespace ParserDel; +using namespace System; +using namespace Utilities; + +namespace ExportOptions +{ + + TCommandList* ExportCommands = nullptr; + std::string* ExportOption; + std::string* ExportHelp; + + TUuid AssignNewUUID(String Val) + { + TUuid result = {}; + if(Pos("{", Val) < 1) + Val = String("{") + Val + "}"; + result = StringToUUID(Val); + return result; + } + + void DefineOptions() + { + ExportOption = new std::string[NumExportOptions]; + ExportHelp = new std::string[NumExportOptions]; + + ExportOption[1 - 1] = "Voltages"; + ExportOption[2 - 1] = "SeqVoltages"; + ExportOption[3 - 1] = "Currents"; + ExportOption[4 - 1] = "SeqCurrents"; + ExportOption[5 - 1] = "Estimation"; + ExportOption[6 - 1] = "Capacity"; + ExportOption[7 - 1] = "Overloads"; + ExportOption[8 - 1] = "Unserved"; + ExportOption[9 - 1] = "Powers"; + ExportOption[10 - 1] = "SeqPowers"; + ExportOption[11 - 1] = "Faultstudy"; + ExportOption[12 - 1] = "Generators"; + ExportOption[13 - 1] = "Loads"; + ExportOption[14 - 1] = "Meters"; + ExportOption[15 - 1] = "Monitors"; + ExportOption[16 - 1] = "Yprims"; + ExportOption[17 - 1] = "Y"; + ExportOption[18 - 1] = "seqz"; + ExportOption[19 - 1] = "P_byphase"; + ExportOption[20 - 1] = "CIM100Fragments"; + ExportOption[21 - 1] = "CIM100"; + ExportOption[22 - 1] = "CDPSMAsset"; + ExportOption[23 - 1] = "Buscoords"; + ExportOption[24 - 1] = "Losses"; + ExportOption[25 - 1] = "Uuids"; + ExportOption[26 - 1] = "Counts"; + ExportOption[27 - 1] = "Summary"; + ExportOption[28 - 1] = "CDPSMElec"; + ExportOption[29 - 1] = "CDPSMGeo"; + ExportOption[30 - 1] = "CDPSMTopo"; + ExportOption[31 - 1] = "CDPSMStateVar"; + ExportOption[32 - 1] = "Profile"; + ExportOption[33 - 1] = "EventLog"; + ExportOption[34 - 1] = "AllocationFactors"; + ExportOption[35 - 1] = "VoltagesElements"; + ExportOption[36 - 1] = "GICMvars"; + ExportOption[37 - 1] = "BusReliability"; + ExportOption[38 - 1] = "BranchReliability"; + ExportOption[39 - 1] = "NodeNames"; + ExportOption[40 - 1] = "Taps"; + ExportOption[41 - 1] = "NodeOrder"; + ExportOption[42 - 1] = "ElemCurrents"; + ExportOption[43 - 1] = "ElemVoltages"; + ExportOption[44 - 1] = "ElemPowers"; + ExportOption[45 - 1] = "Result"; + ExportOption[46 - 1] = "YNodeList"; + ExportOption[47 - 1] = "YVoltages"; + ExportOption[48 - 1] = "YCurrents"; + ExportOption[49 - 1] = "PVSystem_Meters"; + ExportOption[50 - 1] = "Storage_Meters"; + ExportOption[51 - 1] = "Sections"; + ExportOption[52 - 1] = "ErrorLog"; + ExportOption[53 - 1] = "IncMatrix"; + ExportOption[54 - 1] = "IncMatrixRows"; + ExportOption[55 - 1] = "IncMatrixCols"; + ExportOption[56 - 1] = "BusLevels"; + ExportOption[57 - 1] = "Laplacian"; + ExportOption[58 - 1] = "ZLL"; + ExportOption[59 - 1] = "ZCC"; + ExportOption[60 - 1] = "Contours"; + ExportOption[61 - 1] = "Y4"; + ExportOption[62 - 1] = "Jacobian"; + ExportOption[63 - 1] = "deltaF"; + ExportOption[64 - 1] = "deltaZ"; + + ExportHelp[1 - 1] = "(Default file = EXP_VOLTAGES.CSV) Voltages to ground by bus/node."; + ExportHelp[2 - 1] = "(Default file = EXP_SEQVOLTAGES.CSV) Sequence voltages."; + ExportHelp[3 - 1] = "(Default file = EXP_CURRENTS.CSV) Currents in each conductor of each element."; + ExportHelp[4 - 1] = "(Default file = EXP_SEQCURRENTS.CSV) Sequence currents in each terminal of 3-phase elements."; + ExportHelp[5 - 1] = "(Default file = EXP_ESTIMATION.CSV) Results of last estimation."; + ExportHelp[6 - 1] = "(Default file = EXP_CAPACITY.CSV) Capacity report."; + ExportHelp[7 - 1] = "(Default file = EXP_OVERLOADS.CSV) Overloaded elements report."; + ExportHelp[8 - 1] = "(Default file = EXP_UNSERVED.CSV) [UEonly - 1] [Filename - 1] Report on elements that are unserved due to violation of ratings."; + ExportHelp[9 - 1] = "(Default file = EXP_POWERS.CSV) [MVA - 1] [Filename - 1] Powers (kVA by default) into each terminal of each element."; + ExportHelp[10 - 1] = "(Default file = EXP_SEQPOWERS.CSV) Sequence powers into each terminal of 3-phase elements."; + ExportHelp[11 - 1] = "(Default file = EXP_FAULTS.CSV) results of a fault study."; + ExportHelp[12 - 1] = "(Default file = EXP_GENMETERS.CSV) Present values of generator meters. Adding the switch \"/multiple\" or \"/m\" will " + " cause a separate file to be written for each generator."; + ExportHelp[13 - 1] = "(Default file = EXP_LOADS.CSV) Report on loads from most recent solution."; + ExportHelp[14 - 1] = "(Default file = EXP_METERS.CSV) Energy meter exports. Adding the switch \"/multiple\" or \"/m\" will " + " cause a separate file to be written for each meter."; + ExportHelp[15 - 1] = String("(file name is assigned by Monitor export) Monitor values. The argument is the name of the monitor (e.g. Export Monitor XYZ, XYZ is the name of the monitor).") + CRLF + + "The argument can be ALL, which means that all the monitors will be exported"; + ExportHelp[16 - 1] = "(Default file = EXP_YPRIMS.CSV) All primitive Y matrices."; + ExportHelp[17 - 1] = "(Default file = EXP_Y.CSV) [triplets - 1] [Filename - 1] System Y matrix, defaults to non-sparse format."; + ExportHelp[18 - 1] = "(Default file = EXP_SEQZ.CSV) Equivalent sequence Z1, Z0 to each bus."; + ExportHelp[19 - 1] = "(Default file = EXP_P_BYPHASE.CSV) [MVA - 1] [Filename - 1] Power by phase. Default is kVA."; + ExportHelp[20 - 1] = String("(Default file ROOT = CIM100) (IEC 61968-13, CIM100 for unbalanced load flow profile)") + CRLF + + " produces 6 separate files ROOT_FUN.XML for Functional profile,' + CRLF + ' ROOT_EP.XML for Electrical Properties profile," + CRLF + + " ROOT_TOPO.XML for Topology profile," + CRLF + + " ROOT_CAT.XML for Asset Catalog profile," + CRLF + + " ROOT_GEO.XML for Geographical profile and" + CRLF + + " ROOT_SSH.XML for Steady State Hypothesis profile" + CRLF + + " [File=fileroot fid=_uuidstring Substation=subname sid=_uuidstring" + CRLF + + " SubGeographicRegion=subgeoname sgrid=_uuidstring GeographicRegion=geoname rgnid=_uuidstring]"; + ExportHelp[21 - 1] = String("(Default file = CIM100x.XML) (IEC 61968-13, combined CIM100 for unbalanced load flow profile)") + CRLF + + " [File=filename fid=_uuidstring Substation=subname sid=_uuidstring" + CRLF + + " SubGeographicRegion=subgeoname sgrid=_uuidstring GeographicRegion=geoname rgnid=_uuidstring]"; + ExportHelp[22 - 1] = "** Deprecated ** (IEC 61968-13, CDPSM Asset profile)"; + ExportHelp[23 - 1] = "[Default file = EXP_BUSCOORDS.CSV - 1] Bus coordinates in csv form."; + ExportHelp[24 - 1] = "[Default file = EXP_LOSSES.CSV - 1] Losses for each element."; + ExportHelp[25 - 1] = "[Default file = EXP_UUIDS.CSV - 1] Uuids for each element. This frees the UUID list after export."; + ExportHelp[26 - 1] = "[Default file = EXP_Counts.CSV - 1] (instance counts for each class)"; + ExportHelp[27 - 1] = "[Default file = EXP_Summary.CSV - 1] Solution summary."; + ExportHelp[28 - 1] = "** Deprecated ** (IEC 61968-13, CDPSM Electrical Properties profile)"; + ExportHelp[29 - 1] = "** Deprecated ** (IEC 61968-13, CDPSM Geographical profile)"; + ExportHelp[30 - 1] = "** Deprecated ** (IEC 61968-13, CDPSM Topology profile)"; + ExportHelp[31 - 1] = "** Deprecated ** (IEC 61968-13, CDPSM State Variables profile)"; + ExportHelp[32 - 1] = String("[Default file = EXP_Profile.CSV - 1] Coordinates, color of each line section in Profile plot. Same options as Plot Profile Phases property.") + CRLF + + CRLF + + "Example: Export Profile Phases=All [optional file name - 1]"; + ExportHelp[33 - 1] = "(Default file = EXP_EventLog.CSV) All entries in the present event log."; + ExportHelp[34 - 1] = "Exports load allocation factors. File name is assigned."; + ExportHelp[35 - 1] = "(Default file = EXP_VOLTAGES_ELEM.CSV) Voltages to ground by circuit element."; + ExportHelp[36 - 1] = "(Default file = EXP_GIC_Mvar.CSV) Mvar for each GICtransformer object by bus for export to power flow programs "; + ExportHelp[37 - 1] = "(Default file = EXP_BusReliability.CSV) Failure rate, number of interruptions and other reliability data at each bus."; + ExportHelp[38 - 1] = "(Default file = EXP_BranchReliability.CSV) Failure rate, number of interruptions and other reliability data for each PD element."; + ExportHelp[39 - 1] = "(Default file = EXP_NodeNames.CSV) Exports Single-column file of all node names in the active circuit. Useful for making scripts."; + ExportHelp[40 - 1] = "(Default file = EXP_Taps.CSV) Exports the regulator tap report similar to Show Taps."; + ExportHelp[41 - 1] = "(Default file = EXP_NodeOrder.CSV) Exports the present node order for all conductors of all circuit elements"; + ExportHelp[42 - 1] = "(Default file = EXP_ElemCurrents.CSV) Exports the current into all conductors of all circuit elements"; + ExportHelp[43 - 1] = "(Default file = EXP_ElemVoltages.CSV) Exports the voltages to ground at all conductors of all circuit elements"; + ExportHelp[44 - 1] = "(Default file = EXP_elemPowers.CSV) Exports the powers into all conductors of all circuit elements"; + ExportHelp[45 - 1] = "(Default file = EXP_Result.CSV) Exports the result of the most recent command."; + ExportHelp[46 - 1] = "(Default file = EXP_YNodeList.CSV) Exports a list of nodes in the same order as the System Y matrix."; + ExportHelp[47 - 1] = "(Default file = EXP_YVoltages.CSV) Exports the present solution complex Voltage array in same order as YNodeList."; + ExportHelp[48 - 1] = "(Default file = EXP_YCurrents.CSV) Exports the present solution complex Current array in same order as YNodeList. This is generally the injection current array"; + ExportHelp[49 - 1] = "(Default file = EXP_PVMETERS.CSV) Present values of PVSystem meters. Adding the switch \"/multiple\" or \"/m\" will " + " cause a separate file to be written for each PVSystem."; + ExportHelp[50 - 1] = "(Default file = EXP_STORAGEMETERS.CSV) Present values of Storage meters. Adding the switch \"/multiple\" or \"/m\" will " + " cause a separate file to be written for each Storage device."; + ExportHelp[51 - 1] = String("(Default file = EXP_SECTIONS.CSV) Data for each section between overcurrent protection devices. ") + CRLF + + CRLF + + "Examples: " + + CRLF + + " Export Sections [optional filename - 1]" + + CRLF + + "Export Sections meter=M1 [optional filename - 1]"; + ExportHelp[52 - 1] = "(Default file = EXP_ErrorLog.TXT) All entries in the present Error log."; + ExportHelp[53 - 1] = "Exports the Branch-to-Node Incidence matrix calculated for the circuit in compressed coordianted format (Row,Col,Value)"; + ExportHelp[54 - 1] = "Exports the names of the rows (PDElements) used for calculating the Branch-to-Node Incidence matrix for the active circuit"; + ExportHelp[55 - 1] = "Exports the names of the Cols (Buses) used for calculating the Branch-to-Node Incidence matrix for the active circuit"; + ExportHelp[56 - 1] = "Exports the names and the level of each Bus inside the Circuit based on its topology information. The level value defines" + "how far or close is the bus from the circuits backbone (0 means that the bus is at the backbone)"; + ExportHelp[57 - 1] = "Exports the Laplacian matrix calculated using the branch-to-node Incidence matrix in compressed coordinated format (Row,Col,Value)"; + ExportHelp[58 - 1] = "Exports the Link branches matrix (ZLL) calculated after initilizing A-Diakoptics. The output format is compressed coordianted and the values are complex conjugates. If A-Diakoptics is not initialized this command does nothing"; + ExportHelp[59 - 1] = "Exports the connectivity matrix (ZCC) calculated after initilizing A-Diakoptics. The output format is compressed coordianted and the values are complex conjugates. If A-Diakoptics is not initialized this command does nothing"; + ExportHelp[60 - 1] = "Exports the Contours matrix (C) calculated after initilizing A-Diakoptics. The output format is compressed coordianted and the values are integers. If A-Diakoptics is not initialized this command does nothing"; + ExportHelp[61 - 1] = "Exports the inverse of Z4 (ZCC) calculated after initilizing A-Diakoptics. The output format is compressed coordianted and the values are complex conjugates. If A-Diakoptics is not initialized this command does nothing"; + ExportHelp[62 - 1] = "Exports the Jacobian matrix, this matrix is calculated when using the NCIM solution algorithm. The matrix is exported as triplets."; + ExportHelp[63 - 1] = "Exports the coeficients of the vector deltaF, which is used for storing the injection current estimation when using the NCIM solution algorithm."; + ExportHelp[64 - 1] = "Exports the coeficients of the vector deltaZ, which is used for storing the voltage delta estimation when using the NCIM solution algorithm."; + } + + //---------------------------------------------------------------------------- + + int DoExportCmd() + { + int result = 0; + String ParamName; + String Parm1; + String Parm2; + String FileName; + int i = 0; + int MVAopt = 0; + bool UEonlyOpt = false; + bool TripletOpt = false; + TMonitorObj* pMon = nullptr; + TEnergyMeterObj* pMeter = nullptr; + int ParamPointer = 0; + int PhasesToPlot = 0; + bool AbortExport = false; + String SUBSTATION; + String GeographicRegion; + String SubGeographicRegion; // for CIM export + TUuid FdrUUID = {}; + TUuid SubUUID = {}; + TUuid SubGeoUUID = {}; + TUuid RgnUUID = {}; // for CIM export + int InitP = 0; + int FinalP = 0; + int idxP = 0; // Variables created for concatenating options + result = 0; + AbortExport = false; + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm1 = LowerCase(Parser[ActiveActor]->MakeString_()); + ParamPointer = ExportCommands->Getcommand(Parm1); + + /*Check commands requiring a solution and abort if no solution or circuit*/ + switch(ParamPointer) + { + case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: + case 11: case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: + case 21: case 22: case 23: case 24: + case 28: case 29: case 30: case 31: case 32: + case 35: + case 46: case 47: case 48: case 49: case 50: case 51: + { + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSimpleMsg("No circuit created.", 24711); + return result; + } + if(!ASSIGNED(ActiveCircuit[ActiveActor]->Solution) || (ActiveCircuit[ActiveActor]->Solution->NodeV.empty())) + { + DoSimpleMsg("The circuit must be solved before you can do this.", 24712); + return result; + } + } + break; + default: + ; + break; + } + MVAopt = 0; + UEonlyOpt = false; + TripletOpt = false; + PhasesToPlot = PROFILE3PH; // init this to get rid of compiler warning + pMeter = nullptr; + SUBSTATION = String(ActiveCircuit[ActiveActor]->Get_Name()) + "_Substation"; + SubGeographicRegion = String(ActiveCircuit[ActiveActor]->Get_Name()) + "_SubRegion"; + GeographicRegion = String(ActiveCircuit[ActiveActor]->Get_Name()) + "_Region"; + DefaultCircuitUUIDs(FdrUUID, SubUUID, RgnUUID, SubGeoUUID); + switch(ParamPointer) + { + case 9: + case 19: /* Trap export powers command and look for MVA/kVA option */ + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = LowerCase(Parser[ActiveActor]->MakeString_()); + MVAopt = 0; + if(Parm2.size() > 0) + { + if(Parm2[0] == L'm') + MVAopt = 1; + } + } + break; /* Trap UE only flag */ + case 8: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = LowerCase(Parser[ActiveActor]->MakeString_()); + UEonlyOpt = false; + if(Parm2.size() > 0) + { + if(Parm2[0] == L'u') + UEonlyOpt = true; + } + } + break; /*Get monitor name for export monitors command*/ + case 15: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = Parser[ActiveActor]->MakeString_(); + } + break; /* Trap Sparse Triplet flag */ + case 17: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = LowerCase(Parser[ActiveActor]->MakeString_()); + TripletOpt = false; + if(Parm2.size() > 0) + { + if(Parm2[0] == L't') + TripletOpt = true; + } + } + break; /*user-supplied substation and regions*/ + case 20: + case 21: + { + ParamName = LowerCase(Parser[ActiveActor]->GetNextParam()); + Parm2 = Parser[ActiveActor]->MakeString_(); + while(ParamName.size() > 0) + { + if(CompareTextShortest(ParamName, "subs") == 0) + SUBSTATION = Parm2; + else + { + if(CompareTextShortest(ParamName, "subg") == 0) + SubGeographicRegion = Parm2; + else + { + if(CompareTextShortest(ParamName, "g") == 0) + GeographicRegion = Parm2; + else + { + if(CompareTextShortest(ParamName, "fil") == 0) + FileName = Parm2; + else + { + if(CompareTextShortest(ParamName, "fid") == 0) + FdrUUID = AssignNewUUID(Parm2); + else + { + if(CompareTextShortest(ParamName, "sid") == 0) + SubUUID = AssignNewUUID(Parm2); + else + { + if(CompareTextShortest(ParamName, "sg") == 0) + SubGeoUUID = AssignNewUUID(Parm2); + else + { + if(CompareTextShortest(ParamName, "rg") == 0) + RgnUUID = AssignNewUUID(Parm2); + } + } + } + } + } + } + } + ParamName = LowerCase(Parser[ActiveActor]->GetNextParam()); + Parm2 = Parser[ActiveActor]->MakeString_(); + } + } + break; /*Get phases to plot*/ + case 32: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = Parser[ActiveActor]->MakeString_(); + PhasesToPlot = PROFILE3PH; // the default + if(CompareTextShortest(Parm2, "default") == 0) + PhasesToPlot = PROFILE3PH; + else + { + if(CompareTextShortest(Parm2, "all") == 0) + PhasesToPlot = PROFILEALL; + else + { + if(CompareTextShortest(Parm2, "primary") == 0) + PhasesToPlot = PROFILEALLPRI; + else + { + if(CompareTextShortest(Parm2, "ll3ph") == 0) + PhasesToPlot = PROFILELL; + else + { + if(CompareTextShortest(Parm2, "llall") == 0) + PhasesToPlot = PROFILELLALL; + else + { + if(CompareTextShortest(Parm2, "llprimary") == 0) + PhasesToPlot = PROFILELLPRI; + else + { + if(Parm2.size() == 1) + PhasesToPlot = Parser[ActiveActor]->MakeInteger_(); + } + } + } + } + } + } + } + break; /*Sections*/ + case 51: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Parm2 = Parser[ActiveActor]->MakeString_(); + if(CompareTextShortest(ParamName, "meter") == 0) + pMeter = ((TEnergyMeterObj*) EnergyMeterClass[ActiveActor]->Find(Parm2)); + } + break; + default: + ; + break; + } + + /*Pick up next parameter on line, alternate file name, if any*/ + if(FileName.size() == 0) + { + ParamName = Parser[ActiveActor]->GetNextParam(); + FileName = LowerCase(Parser[ActiveActor]->MakeString_()); // should be full path name to work universally + } + InShowResults = true; + + /*Assign default file name if alternate not specified*/ + if(FileName.size() == 0) + { + switch(ParamPointer) + { + case 1: + FileName = "EXP_VOLTAGES" + RepTermination; + break; + case 2: + FileName = "EXP_SEQVOLTAGES" + RepTermination; + break; + case 3: + FileName = "EXP_CURRENTS" + RepTermination; + break; + case 4: + FileName = "EXP_SEQCURRENTS" + RepTermination; + break; + case 5: + FileName = "EXP_ESTIMATION" + RepTermination; + break; // Estimation error + case 6: + FileName = "EXP_CAPACITY" + RepTermination; + break; + case 7: + FileName = "EXP_OVERLOADS" + RepTermination; + break; + case 8: + FileName = "EXP_UNSERVED" + RepTermination; + break; + case 9: + FileName = "EXP_POWERS" + RepTermination; + break; + case 10: + FileName = "EXP_SEQPOWERS" + RepTermination; + break; + case 11: + FileName = "EXP_FAULTS" + RepTermination; + break; + case 12: + FileName = "EXP_GENMETERS" + RepTermination; + break; + case 13: + FileName = "EXP_LOADS" + RepTermination; + break; + case 14: + FileName = "EXP_METERS" + RepTermination; + break; + /*15: Filename is assigned*/ + case 16: + FileName = "EXP_YPRIM" + RepTermination; + break; + case 17: + FileName = "EXP_Y" + RepTermination; + break; + case 18: + FileName = "EXP_SEQZ" + RepTermination; + break; + case 19: + FileName = "EXP_P_BYPHASE" + RepTermination; + break; + case 20: + FileName = "CIM100"; + break; + case 21: + FileName = "CIM100x.XML"; + break; + case 22: + FileName = ""; + break; + case 23: + FileName = "EXP_BUSCOORDS" + RepTermination; + break; + case 24: + FileName = "EXP_LOSSES" + RepTermination; + break; + case 25: + FileName = "EXP_UUIDS" + RepTermination; + break; + case 26: + FileName = "EXP_Counts" + RepTermination; + break; + case 27: + FileName = "EXP_Summary" + RepTermination; + break; + case 28: + FileName = ""; + break; + case 29: + FileName = ""; + break; + case 30: + FileName = ""; + break; + case 31: + FileName = ""; + break; + case 32: + FileName = "EXP_Profile" + RepTermination; + break; + case 33: + FileName = "EXP_EventLog" + RepTermination; + break; + case 34: + FileName = "AllocationFactors.Txt"; + break; + case 35: + FileName = "EXP_VOLTAGES_ELEM" + RepTermination; + break; + case 36: + FileName = "EXP_GIC_Mvar" + RepTermination; + break; + case 37: + FileName = "EXP_BusReliability" + RepTermination; + break; + case 38: + FileName = "EXP_BranchReliability" + RepTermination; + break; + case 39: + FileName = "EXP_NodeNames" + RepTermination; + break; + case 40: + FileName = "EXP_Taps" + RepTermination; + break; + case 41: + FileName = "EXP_NodeOrder" + RepTermination; + break; + case 42: + FileName = "EXP_ElemCurrents" + RepTermination; + break; + case 43: + FileName = "EXP_ElemVoltages" + RepTermination; + break; + case 44: + FileName = "EXP_ElemPowers" + RepTermination; + break; + case 45: + FileName = "EXP_Result" + RepTermination; + break; + case 46: + FileName = "EXP_YNodeList" + RepTermination; + break; + case 47: + FileName = "EXP_YVoltages" + RepTermination; + break; + case 48: + FileName = "EXP_YCurrents" + RepTermination; + break; + case 49: + FileName = "EXP_PVMeters" + RepTermination; + break; + case 50: + FileName = "EXP_STORAGEMeters" + RepTermination; + break; + case 51: + FileName = "EXP_SECTIONS" + RepTermination; + break; + case 52: + FileName = "EXP_ErrorLog.txt"; + break; + case 53: + FileName = "Inc_Matrix" + RepTermination; + break; + case 54: + FileName = "Inc_Matrix_Rows" + RepTermination; + break; + case 55: + FileName = "Inc_Matrix_Cols" + RepTermination; + break; + case 56: + FileName = "Bus_Levels" + RepTermination; + break; + case 57: + FileName = "Laplacian" + RepTermination; + break; + case 58: + FileName = "ZLL" + RepTermination; + break; + case 59: + FileName = "ZCC" + RepTermination; + break; + case 60: + FileName = "C" + RepTermination; + break; + case 61: + FileName = "Y4" + RepTermination; + break; + case 62: + FileName = "Jacobian" + RepTermination; + break; + case 63: + FileName = "deltaF" + RepTermination; + break; + case 64: + FileName = "deltaZ" + RepTermination; + break; + default: + FileName = "EXP_VOLTAGES" + RepTermination; // default + break; + } + FileName = GetOutputDirectory() + CircuitName_[ActiveActor] + FileName; // Explicitly define directory + } + switch(ParamPointer) + { + case 1: + ExportVoltages(FileName); + break; + case 2: + ExportSeqVoltages(FileName); + break; + case 3: + ExportCurrents(FileName); + break; + case 4: + ExportSeqCurrents(FileName); + break; + case 5: + ExportEstimation(FileName); + break; // Estimation error + case 6: + ExportCapacity(FileName); + break; + case 7: + ExportOverloads(FileName); + break; + case 8: + ExportUnserved(FileName, UEonlyOpt); + break; + case 9: + ExportPowers(FileName, MVAopt); + break; + case 10: + ExportSeqPowers(FileName, MVAopt); + break; + case 11: + ExportFaultStudy(FileName); + break; + case 12: + ExportGenMeters(FileName); + break; + case 13: + ExportLoads(FileName); + break; + case 14: + ExportMeters(FileName); + break; + case 15: + if(Parm2.size() > 0) + { + int stop = 0; + if(ConcatenateReports) // In case of being activated, the export will be made for all actors + { + InitP = 1; + FinalP = NumOfActors; + } + else + // Otherwise just for the active actor monitor + { + InitP = ActiveActor; + FinalP = ActiveActor; + } + for(stop = FinalP, idxP = InitP; idxP <= stop; idxP++) + { + if(Parm2 == "all") + { + pMon = (TMonitorObj*) ActiveCircuit[idxP]->Monitors.Get_First(); + while(pMon != nullptr) + { + if(pMon != nullptr) + { + pMon->TranslateToCSV(false, idxP); + FileName = GlobalResult; + } + pMon = (TMonitorObj*) ActiveCircuit[idxP]->Monitors.Get_Next(); + } + } + else + { + pMon = (TMonitorObj*) MonitorClass[idxP]->Find(Parm2); + if(pMon != nullptr) + { + pMon->TranslateToCSV(false, idxP); + FileName = GlobalResult; + } + else + DoSimpleMsg(String("Monitor \"") + Parm2 + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 250); + } + } + } + else + DoSimpleMsg(String("Monitor Name Not Specified.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 251); + break; + case 16: + ExportYprim(FileName); + break; + case 17: + ExportY(FileName, TripletOpt); + break; + case 18: + ExportSeqZ(FileName); + break; + case 19: + ExportPbyphase(FileName, MVAopt); + break; + case 20: + ExportCDPSM(FileName, SUBSTATION, SubGeographicRegion, GeographicRegion, FdrUUID, SubUUID, SubGeoUUID, RgnUUID, false); + break; + case 21: + ExportCDPSM(FileName, SUBSTATION, SubGeographicRegion, GeographicRegion, FdrUUID, SubUUID, SubGeoUUID, RgnUUID, true); + break; + case 22: + DoSimpleMsg("Asset export no longer supported; use Export CIM100", 252); + break; + case 23: + ExportBusCoords(FileName); + break; + case 24: + ExportLosses(FileName); + break; + case 25: + ExportUuids(FileName); + break; + case 26: + ExportCounts(FileName); + break; + case 27: + ExportSummary(FileName); + break; + case 28: + DoSimpleMsg("ElectricalProperties export no longer supported; use Export CIM100", 252); + break; + case 29: + DoSimpleMsg("Geographical export no longer supported; use Export CIM100", 252); + break; + case 30: + DoSimpleMsg("Topology export no longer supported; use Export CIM100", 252); + break; + case 31: + DoSimpleMsg("StateVariables export no longer supported; use Export CIM100", 252); + break; + case 32: + ExportProfile(FileName, PhasesToPlot); + break; + case 33: + ExportEventLog(FileName); + break; + case 34: + DumpAllocationFactors(FileName); + break; + case 35: + ExportVoltagesElements(FileName); + break; + case 36: + ExportGICMvar(FileName); + break; + case 37: + ExportBusReliability(FileName); + break; + case 38: + ExportBranchReliability(FileName); + break; + case 39: + ExportNodeNames(FileName); + break; + case 40: + ExportTaps(FileName); + break; + case 41: + ExportNodeOrder(FileName); + break; + case 42: + ExportElemCurrents(FileName); + break; + case 43: + ExportElemVoltages(FileName); + break; + case 44: + ExportElemPowers(FileName); + break; + case 45: + ExportResult(FileName); + break; + case 46: + ExportYNodeList(FileName); + break; + case 47: + ExportYVoltages(FileName); + break; + case 48: + ExportYCurrents(FileName); + break; + case 49: + ExportPVSystemMeters(FileName); + break; + case 50: + ExportStorageMeters(FileName); + break; + case 51: + ExportSections(FileName, *pMeter); + break; + case 52: + ExportErrorLog(FileName); + break; + case 53: + ExportIncMatrix(FileName); + break; + case 54: + ExportIncMatrixRows(FileName); + break; + case 55: + ExportIncMatrixCols(FileName); + break; + case 56: + ExportBusLevels(FileName); + break; + case 57: + ExportLaplacian(FileName); + break; + case 58: + ExportZLL(FileName); + break; + case 59: + ExportZCC(FileName); + break; + case 60: + ExportC(FileName); + break; + case 61: + ExportY4(FileName); + break; + case 62: + ExportJacobian(FileName); + break; + case 63: + ExportdeltaF(FileName); + break; + case 64: + ExportdeltaZ(FileName); + break; + // ExportVoltages(FileName); // default + default: + DoSimpleMsg(String("Error: Unknown Export command: \"") + Parm1 + "\"", 24713); + AbortExport = true; + break; + } + result = 0; + InShowResults = false; + if(!AbortExport) + { + SetLastResultFile(FileName); + ParserVars->Add("@lastexportfile", FileName); + if(AutoShowExport) + FireOffEditor(FileName); + } + return result; + } + + void DisposeStrings() + { + delete[] ExportOption; + delete[] ExportHelp; + } + + + void ExportOptions_initialization() + { + DefineOptions(); + ExportCommands = new TCommandList(ExportOption, NumExportOptions); + ExportCommands->set_AbbrevAllowed(true); + } + + void ExportOptions_finalization() + { + DisposeStrings(); + delete ExportCommands; + } + + class ExportOptions_unit + { + public: + ExportOptions_unit() + { + //AssertSystemInitialization(); + ExportOptions_initialization(); + } + ~ ExportOptions_unit(){ExportOptions_finalization(); } + }; + ExportOptions_unit _ExportOptions_unit; + +} // namespace ExportOptions + + + + diff --git a/OpenDSSC/Executive/ExportOptions.h b/OpenDSSC/Executive/ExportOptions.h new file mode 100644 index 0000000..06525aa --- /dev/null +++ b/OpenDSSC/Executive/ExportOptions.h @@ -0,0 +1,46 @@ +#ifndef ExportOptionsH +#define ExportOptionsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +#include "ExportResults.h" +#include "Monitor.h" +#include "EnergyMeter.h" +#include "ParserDel.h" +#include "DSSGlobals.h" +#include "ExportCIMXML.h" +#include "Utilities.h" +#include "NamedObject.h" + +namespace ExportOptions +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + const int NumExportOptions = 64; + int DoExportCmd(); + extern std::string* ExportOption; + extern std::string* ExportHelp; + extern Command::TCommandList* ExportCommands; + + +} // namespace ExportOptions + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExportOptions; +#endif + +#endif // ExportOptionsH + + + + diff --git a/OpenDSSC/Executive/PlotOptions.cpp b/OpenDSSC/Executive/PlotOptions.cpp new file mode 100644 index 0000000..d0c54a1 --- /dev/null +++ b/OpenDSSC/Executive/PlotOptions.cpp @@ -0,0 +1,627 @@ + +#pragma hdrstop + +#include "PlotOptions.h" + +using namespace std; +using namespace Command; +using namespace DSSGlobals; +using namespace DSSPlot; +using namespace ParserDel; +using namespace System; + +namespace PlotOptions +{ + + +String* PlotOption; +String* PlotHelp; +TCommandList* PlotCommands = nullptr; + +void DefineOptions() +{ + PlotOption = new string[NumPlotOptions + 1]; + PlotHelp = new string[NumPlotOptions + 1]; + + PlotOption[1 - 1] = "type"; + PlotOption[2 - 1] = "quantity"; + PlotOption[3 - 1] = "max"; + PlotOption[4 - 1] = "dots"; + PlotOption[5 - 1] = "labels"; + PlotOption[6 - 1] = "object"; + PlotOption[7 - 1] = "showloops"; + PlotOption[8 - 1] = "r3"; + PlotOption[9 - 1] = "r2"; + PlotOption[10 - 1] = "c1"; + PlotOption[11 - 1] = "c2"; + PlotOption[12 - 1] = "c3"; + PlotOption[13 - 1] = "channels"; + PlotOption[14 - 1] = "bases"; + PlotOption[15 - 1] = "subs"; + PlotOption[16 - 1] = "thickness"; + PlotOption[17 - 1] = "buslist"; + PlotOption[18 - 1] = "min"; + PlotOption[19 - 1] = "3phLinestyle"; + PlotOption[20 - 1] = "1phLinestyle"; + PlotOption[21 - 1] = "phases"; + PlotOption[22 - 1] = "profilescale"; + PlotOption[23 - 1] = "PlotID"; + PlotHelp[1 - 1] = "One of {Circuit | Monitor | Daisy | Zones | AutoAdd | General (bus data) | Loadshape | Tshape | Priceshape |Profile} " + CRLF + + "A \"Daisy\" plot is a special circuit plot that places a marker at each Generator location " + + "or at buses in the BusList property, if defined. " + + "A Zones plot shows the meter zones (see help on Object). " + + "Autoadd shows the autoadded generators. General plot shows quantities associated with buses " + + "using gradient colors between C1 and C2. Values are read from a file (see Object). " + + "Loadshape plots the specified loadshape. Examples:" + + CRLF + + CRLF + + "Plot type=circuit quantity=power" + + CRLF + + "Plot Circuit Losses 1phlinestyle=3" + + CRLF + + "Plot Circuit quantity=3 object=mybranchdata.csv" + + CRLF + + "Plot daisy power max=5000 dots=N Buslist=[file=MyBusList.txt]" + + CRLF + + "Plot General quantity=1 object=mybusdata.csv" + + CRLF + + "Plot Loadshape object=myloadshape" + + CRLF + + "Plot Tshape object=mytemperatureshape" + + CRLF + + "Plot Priceshape object=mypriceshape" + + CRLF + + "Plot Profile" + + CRLF + + "Plot Profile Phases=Primary" + + CRLF + + CRLF + + "Additional plots with the OpenDSS Viewer (These plots are enabled with the \"OpenDSSViewer\" option):" + + CRLF + + "- Plot evolution ! Probabilistic density evolution plot with the line-to-ground magnitude of all load voltages in per unit base." + + CRLF + + "- Plot energymeter object=system ! System energy meter plot. The \"DemandInterval\" option is required." + + CRLF + + "- Plot energymeter object=Totals ! Totals energy meter plot. The \"DemandInterval\" option is required." + + CRLF + + "- Plot energymeter object=voltexception ! Voltage exception plot. The \"DemandInterval\" and \"VoltExceptionReport\" options are required." + + CRLF + + "- Plot energymeter object=overloads ! Overload report plot. The \"DemandInterval\" and \"OverloadReport\" options are required." + + CRLF + + "- Plot energymeter object=myMeter ! Energy meter plot. The \"DemandInterval\" and \"DIVerbose\" options are required." + + CRLF + + "- Plot loadshape object=myLoadshape ! Loadshapes with the OpenDSS Viewer functionalities." + + CRLF + + "- Plot matrix incidence ! Incidence matrix plot (Requires: CalcIncMatrix or CalcIncMatrix_O)." + + CRLF + + "- Plot matrix laplacian ! Laplacian matrix plot (Requires: CalcLaplacian)." + + CRLF + + "- Plot monitor object=myMonitor ! Monitors with the OpenDSS Viewer functionalities. All channels are included in this plot." + + CRLF + + "- Plot phasevoltage object=myMeter ! Phase voltage plot associated to an energy meter. The \"DemandInterval\", \"DIVerbose\" options and the \"PhaseVoltageReport\" parameter are required." + + CRLF + + "- Plot profile ! 3D and 2D versions of the voltage profile." + + CRLF + + "- Plot scatter ! Scatter plot with geovisualization of line-to-ground bus voltage magnitudes in per unit."; + PlotHelp[2 - 1] = "One of {Voltage | Current | Power | Losses | Capacity | (Value Index for General, AutoAdd, or Circuit[w/ file]) }"; + PlotHelp[3 - 1] = "Enter 0 (the default value) or the value corresponding to max scale or line thickness in the circuit plots. " + "Power and Losses in kW. Also, use this to specify the max value corresponding to color C2 in General plots."; + PlotHelp[4 - 1] = "Yes or No*. Places a marker on the circuit plot at the bus location. See Set Markercode under options."; + PlotHelp[5 - 1] = "Yes or No*. If yes, bus labels (abbreviated) are printed on the circuit plot."; + PlotHelp[6 - 1] = "Object to be plotted. One of [Meter Name (zones plot) | Monitor Name | LoadShape Name | File Name for General bus data | File Name Circuit branch data]"; + PlotHelp[7 - 1] = "{Yes | No*} Shows loops on Circuit plot. Requires an EnergyMeter to be defined."; + PlotHelp[8 - 1] = "pu value for tri-color plot max range [default=.85 of max scale]. Corresponds to color C3."; + PlotHelp[9 - 1] = "pu value for tri-color plot mid range [default=.50 of max scale]. Corresponds to color C2."; + PlotHelp[10 - 1] = String("RGB color number or standard color name for color C1. This is the default color for circuit plots. Default is blue. See options in the Plot menu.") + CRLF + + CRLF + + "Standard color names are: " + + CRLF + + CRLF + + " Black " + + CRLF + + " Maroon " + + CRLF + + " Green " + + CRLF + + " Olive " + + CRLF + + " Navy " + + CRLF + + " Purple " + + CRLF + + " Teal " + + CRLF + + " Gray " + + CRLF + + " Silver " + + CRLF + + " Red " + + CRLF + + " Lime " + + CRLF + + " Yellow " + + CRLF + + " Blue " + + CRLF + + " Fuchsia" + + CRLF + + " Aqua " + + CRLF + + " LtGray " + + CRLF + + " DkGray " + + CRLF + + " White "; + PlotHelp[11 - 1] = String("RGB color number or standard color name for color C2. Used for gradients and tricolor plots such as circuit voltage.") + CRLF + + CRLF + + "See Help on C1 for list of standard color names."; + PlotHelp[12 - 1] = String("RGB color number or standard color name for color C3. Used for gradients and tricolor plots such a circuit voltage.") + CRLF + + CRLF + + "See Help on C1 for list of standard color names."; + PlotHelp[13 - 1] = String("Array of channel numbers for monitor plot. Example") + CRLF + + CRLF + + "Plot Type=Monitor Object=MyMonitor Channels=[1, 3, 5]" + + CRLF + + CRLF + + "Do \"Show Monitor MyMonitor\" to see channel definitions."; + PlotHelp[14 - 1] = String("Array of base values for each channel for monitor plot. Useful for creating per unit plots. Default is 1.0 for each channel. Set Base= property after defining channels.") + CRLF + + CRLF + + "Plot Type=Monitor Object=MyMonitor Channels=[1, 3, 5] Bases=[2400 2400 2400]" + + CRLF + + CRLF + + "Do \"Show Monitor MyMonitor\" to see channel range and definitions."; + PlotHelp[15 - 1] = "{Yes | No*} Displays a marker at each transformer declared to be a substation. " + "At least one bus coordinate must be defined for the transformer. " + "See MarkTransformer and TransMarkerCode options."; + PlotHelp[16 - 1] = "Max thickness allowed for lines in circuit plots (default=7)."; + PlotHelp[17 - 1] = String("{Array of Bus Names | File=filename } This is for the Daisy plot. ") + CRLF + + CRLF + + "Plot daisy power max=5000 dots=N Buslist=[file=MyBusList.txt]" + + CRLF + + CRLF + + "A \"daisy\" marker is plotted for " + + "each bus in the list. Bus name may be repeated, which results in multiple markers distributed around the bus location. " + + "This gives the appearance of a daisy if there are several symbols at a bus. Not needed for plotting active generators."; + PlotHelp[18 - 1] = "Enter 0 (the default value) or the value corresponding to min value corresponding to color C1 in General bus data plots."; + PlotHelp[19 - 1] = "Line style for drawing 3-phase lines. A number in the range of [1..7].Default is 1 (solid). Use 3 for dotted; 2 for dashed."; + PlotHelp[20 - 1] = "Line style for drawing 1-phase lines. A number in the range of [1..7].Default is 1 (solid). Use 3 for dotted; 2 for dashed."; + PlotHelp[21 - 1] = String("{default* | ALL | PRIMARY | LL3ph | LLALL | LLPRIMARY | (phase number)} For Profile plot. Specify which phases you want plotted.") + CRLF + + CRLF + + "default = plot only nodes 1-3 at 3-phase buses (default)" + + CRLF + + "ALL = plot all nodes" + + CRLF + + "PRIMARY = plot all nodes -- primary only (voltage > 1kV)" + + CRLF + + "LL3ph = 3-ph buses only -- L-L voltages)" + + CRLF + + "LLALL = plot all nodes -- L-L voltages)" + + CRLF + + "LLPRIMARY = plot all nodes -- L-L voltages primary only)" + + CRLF + + "(phase number) = plot all nodes on selected phase" + + CRLF + + CRLF + + "Note: Only nodes downline from an energy meter are plotted."; + PlotHelp[22 - 1] = String("PUKM | 120KFT, default is PUKM") + CRLF + + "PUKM = per-unit voltage vs. distance in km" + + CRLF + + "120KFT = voltage on 120-V base vs. distance in kft."; + PlotHelp[23 - 1] = String("Plot identifier for dynamic updates of \"profile\" and \"scatter\" plots in the OpenDSS Viewer (See \"plot type\" for more details)." "When multiple \"plot\" commands are executed with the same PlotID, the same figure will be updated with the most recent simulation results.") + CRLF + + CRLF + + "This identifier could be declared as an integer number or a string without spaces." + + CRLF + + CRLF + + "Example:" + + CRLF + + CRLF + + "set OpenDSSViewer=true ! OpenDSS Viewer enabled" + + CRLF + + "solve" + + CRLF + + "plot scatter PlotID=plotA !Generates a new scatter plot" + + CRLF + + "solve" + + CRLF + + "plot scatter PlotID=plotB !Generates a new scatter plot" + + CRLF + + "solve" + + CRLF + + "plot scatter PlotID=plotA !Updates the data in plotA" + + CRLF + + "solve" + + CRLF + + "plot scatter PlotID=plotA !Updates the data in plotA" + + CRLF; +} + + +//---------------------------------------------------------------------------- + +int DoPlotCmd() +{ + int result = 0, + ParamPointer = 0, + i = 0, + NumChannels = 0; + String ParamName = "", + Param = "", + OrgParam; + + double DblBuffer[51]; + + if(NoFormsAllowed) + { + result = 1; + return result; + } + if(!ASSIGNED(DSSPlotObj)) + DSSPlotObj = new TDSSPlot(); + DSSPlotObj->SetDefaults(); + + /*Get next parameter on command line*/ + ParamPointer = 0; + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + OrgParam = Parser[ActiveActor]->MakeString_(); + Param = UpperCase(OrgParam); + while(Param.size() > 0) + + /*Interpret Parameter*/ + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = PlotCommands->Getcommand(ParamName); + + /*Check options requiring a solution and abort if no solution or circuit*/ + switch(ParamPointer) + { + case 1: + switch(Param[0]) + { + case L'A': + case L'C': + case L'D': + case L'G': + case L'M': + case L'P': + case L'Z': + if(!(CompareTextShortest("pri", Param) == 0)) // allow Price shape + { + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSimpleMsg("No circuit created.", 24731); + return result; + } + if(!ASSIGNED(ActiveCircuit[ActiveActor]->Solution) || (ActiveCircuit[ActiveActor]->Solution->NodeV.empty())) + { + DoSimpleMsg("The circuit must be solved before you can do this.", 24732); + return result; + } + } + break; + default: + ; + break; + } + break; + default: + break; + } + /*# with DSSPlotObj do */ + { + auto with0 = DSSPlotObj; + switch(ParamPointer) + { + case 1: + switch(Param[0]) + { + case L'A': + { + with0->PlotType = ptAutoAddLogPlot; + with0->ObjectName = CircuitName_[ActiveActor] + "AutoAddLog.CSV"; + with0->ValueIndex = 2; + } + break; + case L'C': + with0->PlotType = ptCircuitplot; + break; + case L'E': + if(CompareTextShortest("ener", Param) == 0) + with0->PlotType = ptEnergyPlot; + else + with0->PlotType = ptEvolutionPlot; + break; + case L'G': + with0->PlotType = ptGeneralDataPlot; + break; + case L'L': + with0->PlotType = ptLoadShape; + break; + case L'M': + if(CompareTextShortest("mon", Param) == 0) + with0->PlotType = ptmonitorplot; + else + with0->PlotType = ptMatrixplot; + break; + case L'P': + if(CompareTextShortest("pro", Param) == 0) + with0->PlotType = ptProfile; + else + { + if(CompareTextShortest("phas", Param) == 0) + with0->PlotType = ptPhaseVoltage; + else + with0->PlotType = ptPriceShape; + } + break; + case L'S': + with0->PlotType = ptScatterPlot; + break; + case L'T': + with0->PlotType = ptTShape; + break; + case L'D': + { + with0->PlotType = ptdaisyplot; + with0->DaisyBusList.clear(); + } + break; + case L'Z': + with0->PlotType = ptMeterZones; + break; + default: + ; + break; + } + break; + case 2: + switch(Param[0]) + { + case L'V': + with0->Quantity = pqVoltage; + break; + case L'C': + switch(Param[1]) + { + case L'A': + with0->Quantity = pqCapacity; + break; + case L'U': + with0->Quantity = pqCurrent; + break; + default: + ; + break; + } + break; + case L'P': + with0->Quantity = pqPower; + break; + case L'L': + if(CompareTextShortest("los", Param) == 0) + with0->Quantity = pqLosses; + else + with0->MatrixType = pLaplacian; + break; + case L'I': + with0->MatrixType = pIncMatrix; + break; + default: + with0->Quantity = pqNone; + with0->ValueIndex = Parser[ActiveActor]->MakeInteger_(); + break; + } + break; + case 3: + { + with0->MaxScale = Parser[ActiveActor]->MakeDouble_(); + if(with0->MaxScale > 0.0) // Indicate the user wants a particular value + with0->MaxScaleIsSpecified = true; + else + with0->MaxScaleIsSpecified = false; + } + break; + case 4: + with0->Dots = InterpretYesNo(Param); + break; + case 5: + with0->Labels = InterpretYesNo(Param); + break; + case 6: + with0->ObjectName = Parser[ActiveActor]->MakeString_(); + break; + case 7: + { + with0->ShowLoops = InterpretYesNo(Param); + if(with0->ShowLoops) + with0->PlotType = ptMeterZones; + } + break; + case 8: + with0->TriColorMax = Parser[ActiveActor]->MakeDouble_(); + break; + case 9: + with0->TriColorMid = Parser[ActiveActor]->MakeDouble_(); + break; + case 10: + with0->Color1 = InterpretColorName(Param); + break; + case 11: + with0->Color2 = InterpretColorName(Param); + break; + case 12: + with0->Color3 = InterpretColorName(Param); + break; /*Channel definitions for Plot Monitor*/ + case 13: + { + NumChannels = Parser[ActiveActor]->ParseAsVector(51, DblBuffer); // allow up to 50 channels + if(NumChannels > 0) // Else take the defaults + { + int stop = 0; + with0->Channels.resize(NumChannels); + for(stop = NumChannels - 1, i = 0; i <= stop; i++) + { + with0->Channels[i] = (unsigned int) Round(DblBuffer[i]); + } + with0->Bases.resize(NumChannels); + for(stop = NumChannels - 1, i = 0; i <= stop; i++) + { + with0->Bases[i] = 1.0; + } + } + } + break; + case 14: + { + NumChannels = Parser[ActiveActor]->ParseAsVector(51, DblBuffer); // allow up to 50 channels + if(NumChannels > 0) + { + int stop = 0; + with0->Bases.resize(NumChannels); + for(stop = NumChannels - 1, i = 0; i <= stop; i++) + { + with0->Bases[i] = DblBuffer[i]; + } + } + } + break; + case 15: + with0->ShowSubs = InterpretYesNo(Param); + break; + case 16: + with0->FMaxLineThickness = Parser[ActiveActor]->MakeInteger_(); + break; + case 17: + InterpretTStringListArray(OrgParam, with0->DaisyBusList); + break; /*read in Bus list*/ + case 18: + { + with0->MinScale = Parser[ActiveActor]->MakeDouble_(); + with0->MinScaleIsSpecified = true; // Indicate the user wants a particular value + } + break; + case 19: + ThreePhLineStyle = Parser[ActiveActor]->MakeInteger_(); + break; + case 20: + SinglePhLineStyle = Parser[ActiveActor]->MakeInteger_(); + break; // Parse off phase(s) to plot + case 21: + { + with0->PhasesToPlot = PROFILE3PH; // the default + if(CompareTextShortest(Param, "default") == 0) + with0->PhasesToPlot = PROFILE3PH; + else + { + if(CompareTextShortest(Param, "all") == 0) + with0->PhasesToPlot = PROFILEALL; + else + { + if(CompareTextShortest(Param, "primary") == 0) + with0->PhasesToPlot = PROFILEALLPRI; + else + { + if(CompareTextShortest(Param, "ll3ph") == 0) + with0->PhasesToPlot = PROFILELL; + else + { + if(CompareTextShortest(Param, "llall") == 0) + with0->PhasesToPlot = PROFILELLALL; + else + { + if(CompareTextShortest(Param, "llprimary") == 0) + with0->PhasesToPlot = PROFILELLPRI; + else + { + if(Param.size() == 1) + with0->PhasesToPlot = Parser[ActiveActor]->MakeInteger_(); + } + } + } + } + } + } + } + break; + case 22: + { + with0->ProfileScale = PROFILEPUKM; + if(CompareTextShortest(Param, "120KFT") == 0) + with0->ProfileScale = PROFILE120KFT; + } + break; + case 23: + with0->PlotID = Parser[ActiveActor]->MakeString_(); + break; + default: + ; + break; + } + } + ParamName = UpperCase(Parser[ActiveActor]->GetNextParam()); + OrgParam = Parser[ActiveActor]->MakeString_(); + Param = UpperCase(OrgParam); + } + if(!ActiveCircuit[ActiveActor]->Issolved) + DSSPlotObj->Quantity = pqNone; + /*# with DSSPlotObj do */ + { + auto with1 = DSSPlotObj; + if(DSS_Viz_enable) + { + if(DSS_Viz_installed && ((with1->PlotType == ptmonitorplot) || (with1->PlotType == ptLoadShape) || (with1->PlotType == ptProfile) || (with1->PlotType == ptScatterPlot) || (with1->PlotType == ptEvolutionPlot) || (with1->PlotType == ptEnergyPlot) || (with1->PlotType == ptPhaseVoltage) || (with1->PlotType == ptMatrixplot))) + with1->DSSVizPlot(); // OpenDSS Viewer + } + else + { + if((with1->PlotType == ptScatterPlot) || (with1->PlotType == ptEvolutionPlot) || (with1->PlotType == ptMatrixplot)) + DoSimpleMsg("The OpenDSS Viewer is disabled (Check the OpenDSSViewer option in the help).", 0); + else + with1->Execute(); // makes a new plot based on these options + } + } + return result; +} + +/* + Produce a plot with the DSSGraphX object +*/ + +void DisposeStrings() +{ + delete[] PlotOption; + delete[] PlotHelp; +} + + +void PlotOptions_initialization() +{ + DefineOptions(); + PlotCommands = new TCommandList(PlotOption, NumPlotOptions); + PlotCommands->set_AbbrevAllowed(true); +} + +void PlotOptions_finalization() +{ + DisposeStrings(); + delete PlotCommands; +} + + class PlotOptions_unit + { + public: + PlotOptions_unit() + { + //AssertSystemInitialization(); + PlotOptions_initialization(); + } + ~ PlotOptions_unit(){PlotOptions_finalization(); } + }; + PlotOptions_unit _PlotOptions_unit; + +} // namespace PlotOptions + + + + diff --git a/OpenDSSC/Executive/PlotOptions.h b/OpenDSSC/Executive/PlotOptions.h new file mode 100644 index 0000000..d6270ba --- /dev/null +++ b/OpenDSSC/Executive/PlotOptions.h @@ -0,0 +1,46 @@ +#ifndef PlotOptionsH +#define PlotOptionsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +#include "ShowResults.h" +#include "ParserDel.h" +#include "Monitor.h" +#include "Utilities.h" +#include "DSSGlobals.h" +#include "CmdForms.h" +#include "LineUnits.h" +#include "DSSPlot.h" + +namespace PlotOptions +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + const int NumPlotOptions = 23; + int DoPlotCmd(); + extern String* PlotOption; + extern String* PlotHelp; + extern Command::TCommandList* PlotCommands; + + +} // namespace PlotOptions + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PlotOptions; +#endif + +#endif // PlotOptionsH + + + + diff --git a/OpenDSSC/Executive/ShowOptions.cpp b/OpenDSSC/Executive/ShowOptions.cpp new file mode 100644 index 0000000..e165177 --- /dev/null +++ b/OpenDSSC/Executive/ShowOptions.cpp @@ -0,0 +1,614 @@ + + +#pragma hdrstop + +#include "ShowOptions.h" + + + +using namespace std; +using namespace Command; +using namespace DSSGlobals; +using namespace LineUnits; +using namespace Monitor; +using namespace ParserDel; +using namespace System; +using namespace Utilities; + +namespace ShowOptions +{ + + TCommandList* ShowCommands = nullptr; + std::string* ShowOption; + std::string* ShowHelp; + + void DefineOptions() + { + ShowOption = new string[NumShowOptions]; + ShowHelp = new string[NumShowOptions]; + + ShowOption[1 - 1] = "autoadded"; + ShowOption[2 - 1] = "buses"; + ShowOption[3 - 1] = "currents"; + ShowOption[4 - 1] = "convergence"; + ShowOption[5 - 1] = "elements"; + ShowOption[6 - 1] = "faults"; + ShowOption[7 - 1] = "isolated"; + ShowOption[8 - 1] = "generators"; + ShowOption[9 - 1] = "meters"; + ShowOption[10 - 1] = "monitor"; + ShowOption[11 - 1] = "pane"; + ShowOption[12 - 1] = "powers"; + ShowOption[13 - 1] = "voltages"; + ShowOption[14 - 1] = "zone"; + ShowOption[15 - 1] = "taps"; + ShowOption[16 - 1] = "overloads"; + ShowOption[17 - 1] = "unserved"; + ShowOption[18 - 1] = "eventlog"; + ShowOption[19 - 1] = "variables"; + ShowOption[20 - 1] = "ratings"; + ShowOption[21 - 1] = "loops"; + ShowOption[22 - 1] = "losses"; + ShowOption[23 - 1] = "busflow"; + ShowOption[24 - 1] = "lineconstants"; + ShowOption[25 - 1] = "yprim"; + ShowOption[26 - 1] = "y"; + ShowOption[27 - 1] = "controlqueue"; + ShowOption[28 - 1] = "topology"; + ShowOption[29 - 1] = "mismatch"; + ShowOption[30 - 1] = "kvbasemismatch"; + ShowOption[31 - 1] = "deltaV"; + ShowOption[32 - 1] = "QueryLog"; + ShowOption[33 - 1] = "Controlled"; + ShowOption[34 - 1] = "Result"; + ShowOption[35 - 1] = "PV2PQ_Conversions"; + + ShowHelp[1 - 1] = "Shows auto added capacitors or generators. See AutoAdd solution mode."; + ShowHelp[2 - 1] = "Report showing all buses and nodes currently defined."; + ShowHelp[3 - 1] = String("Report showing currents from most recent solution. syntax: ") + CRLF + + CRLF + + "Show Currents [[residual= - 1]yes|no* - 1] [Seq* | Elements - 1]" + + CRLF + + CRLF + + "If \"residual\" flag is yes, the sum of currents in all conductors is reported. " + + "Default is to report Sequence currents; otherwise currents in all conductors are reported."; + ShowHelp[4 - 1] = "Report on the convergence of each node voltage."; + ShowHelp[5 - 1] = String("Shows names of all elements in circuit or all elements of a specified class. Syntax: ") + CRLF + + CRLF + + "Show ELements [Classname - 1] " + + CRLF + + CRLF + + "Useful for creating scripts that act on selected classes of elements. "; + ShowHelp[6 - 1] = "After fault study solution, shows fault currents."; + ShowHelp[7 - 1] = "Report showing buses and elements that are isolated from the main source."; + ShowHelp[8 - 1] = String("Report showing generator elements currently defined and the values of the energy meters ") + CRLF + + "associated with each generator."; + ShowHelp[9 - 1] = "Shows the present values of the registers in the EnergyMeter elements."; + ShowHelp[10 - 1] = String("Shows the contents of a selected monitor. Syntax: ") + CRLF + + CRLF + + " Show Monitor monitorname"; + ShowHelp[11 - 1] = "Shows control panel. (not necessary for standalone version)"; + ShowHelp[12 - 1] = String("Report on powers flowing in circuit from most recent solution. ") + CRLF + + "Powers may be reported in kVA or MVA and in sequence quantities or in every " + + "conductor of each element. Syntax:" + + CRLF + + CRLF + + "Show Powers [MVA|kVA* - 1] [Seq* | Elements - 1]" + + CRLF + + CRLF + + "Sequence powers in kVA is the default. Examples:" + + CRLF + + CRLF + + "Show powers" + + CRLF + + "Show power kva element" + + CRLF + + "Show power mva elem"; + ShowHelp[13 - 1] = String("Reports voltages from most recent solution. Voltages are reported with respect to ") + CRLF + + "system reference (Node 0) by default (LN option), but may also be reported Line-Line (LL option)." + + CRLF + + "The voltages are normally reported by bus/node, but may also be reported by circuit element. Syntax:" + + CRLF + + CRLF + + "Show Voltages [LL |LN* - 1] [Seq* | Nodes | Elements - 1]" + + CRLF + + CRLF + + "Show Voltages" + + CRLF + + "Show Voltage LN Nodes" + + CRLF + + "Show Voltages LL Nodes" + + CRLF + + "Show Voltage LN Elem"; + ShowHelp[14 - 1] = String("Shows the zone for a selected EnergyMeter element. Shows zone either in " "a text file or in a graphical tree view.") + CRLF + + CRLF + + "Show Zone energymetername [Treeview - 1]"; + ShowHelp[15 - 1] = "Shows the regulator/LTC taps from the most recent solution."; + ShowHelp[16 - 1] = "Shows overloaded power delivery elements."; + ShowHelp[17 - 1] = String("Shows loads that are \"unserved\". That is, loads for which the voltage is too low, " "or a branch on the source side is overloaded. If UEonly is specified, shows only those loads " "in which the emergency rating has been exceeded. Syntax:") + CRLF + + CRLF + + "Show Unserved [UEonly - 1] (unserved loads)"; + ShowHelp[18 - 1] = "Shows the present event log. (Regulator tap changes, capacitor switching, etc.)"; + ShowHelp[19 - 1] = "Shows internal state variables of devices (Power conversion elements) that report them."; + ShowHelp[20 - 1] = "Shows ratings of power delivery elements."; + ShowHelp[21 - 1] = "Shows closed loops detected by EnergyMeter elements that are possibly unwanted. Otherwise, loops are OK."; + ShowHelp[22 - 1] = "Reports losses in each element and in the entire circuit."; + ShowHelp[23 - 1] = String("Creates a report showing power and current flows as well as voltages around a selected bus. Syntax:") + CRLF + + CRLF + + "Show BUSFlow busname [MVA|kVA* - 1] [Seq* | Elements - 1]" + + CRLF + + CRLF + + "Show busflow busxxx kVA elem" + + CRLF + + "Show busflow busxxx MVA seq" + + CRLF + + CRLF + + "NOTE: The Show menu will prompt you for these values."; + ShowHelp[24 - 1] = String("Creates two report files for the line constants (impedances) of every LINEGEOMETRY element currently defined. " "One file shows the main report with the matrices. The other file contains corresponding LINECODE " "definitions that you may use in subsequent simulations. Syntax:") + CRLF + + CRLF + + "Show LIneConstants [frequency - 1] [none|mi|km|kft|m|me|ft|in|cm - 1] [rho - 1]" + + CRLF + + CRLF + + "Specify the frequency, length units and earth resistivity (meter-ohms). Examples:" + + CRLF + + CRLF + + "Show Lineconstants 60 kft 100" + + CRLF + + "Show Linecon 50 km 1000"; + ShowHelp[25 - 1] = "Show the primitive admittance (y) matrix for the active element."; + ShowHelp[26 - 1] = "Show the system Y matrix. Could be a large file!"; + ShowHelp[27 - 1] = "Shows the present contents of the control queue."; + ShowHelp[28 - 1] = "Shows the topology as seen by the SwtControl elements."; + ShowHelp[29 - 1] = "Shows the current mismatches at each node in amperes and percent of max currents at node."; + ShowHelp[30 - 1] = "Creates a report of Load and Generator elements for which the base voltage does not match the Bus base voltage. " + "Scripts for correcting the voltage base are suggested."; + ShowHelp[31 - 1] = "Show voltages ACROSS each 2-terminal element, phase-by-phase. "; + ShowHelp[32 - 1] = "Show Query Log file. "; + ShowHelp[33 - 1] = "Show Controlled elements and the names of the controls connected to them in CSV format."; + ShowHelp[34 - 1] = "Show last result (in @result variable)."; + ShowHelp[35 - 1] = "Show the list of generators converted from PV bus to PQ during the last soltuion step (NCIM)."; + } + + + //---------------------------------------------------------------------------- + + int DoShowCmd() + { + int result = 0; + String ParamName; + String Param; + String FilName; + int ParamPointer = 0; + TMonitorObj* pMon = nullptr; + int MVAopt = 0; + bool LLopt = false; + bool ShowResid = false; + int ShowOptionCode = 0; + String Busname; + double Freq = 0.0; + int Units = 0; + double Rho_line = 0.0; + int InitP = 0; + int FinalP = 0; + int idxP = 0; // Variables added to concatenate the results in OpenDSS-PM + result = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + ParamPointer = ShowCommands->Getcommand(Param); + if(ParamPointer == 0) + { + DoSimpleMsg(String("Error: Unknown Show Command:\"") + Param + "\"", 24700); + return result; + } + + /*Check commands requiring a solution and abort if no solution or circuit*/ + switch(ParamPointer) + { + case 4: + case 6: + case 8: case 9: case 10: + case 12: + case 13: case 14: case 15: case 16: case 17: + case 19: case 20: case 21: case 22: case 23: + case 29: case 30: case 31: + { + if(!ASSIGNED(ActiveCircuit[ActiveActor])) + { + DoSimpleMsg("No circuit created.", 24701); + return result; + } + if(!ASSIGNED(ActiveCircuit[ActiveActor]->Solution) || (ActiveCircuit[ActiveActor]->Solution->NodeV.empty())) + { + DoSimpleMsg("The circuit must be solved before you can do this.", 24702); + return result; + } + } + break; + default: + ; + break; + } + InShowResults = true; + switch(ParamPointer) + { + case 1: /*Autoadded*/ + { + FireOffEditor(GetOutputDirectory() + CircuitName_[ActiveActor] + "AutoAddedGenerators.Txt"); + FireOffEditor(GetOutputDirectory() + CircuitName_[ActiveActor] + "AutoAddedCapacitors.Txt"); + } + break; + case 2: + ShowBuses(GetOutputDirectory() + CircuitName_[ActiveActor] + "Buses.Txt"); + break; + case 3: + { + ShowOptionCode = 0; + ShowResid = false; + ParamName = Parser[ActiveActor]->GetNextParam(); // Look for residual + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + // logic handles show curr y|n|T elements or show curr elements + if(Param.size() > 0) + switch(Param[0]) + { + case L'Y': + case L'T': + ShowResid = true; + break; + case L'N': + ShowResid = false; + break; + case L'E': + ShowOptionCode = 1; + break; + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); // Look for another param + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + switch(Param[0]) + { + case L'E': + ShowOptionCode = 1; + break; + default: + ; + break; + } + switch(ShowOptionCode) + { + case 0: + FilName = "Curr_Seq"; + break; + case 1: + FilName = "Curr_Elem"; + break; + default: + ; + break; + } + ShowCurrents(GetOutputDirectory() + CircuitName_[ActiveActor] + FilName + ".Txt", ShowResid, ShowOptionCode); + } + break; + case 4: + ActiveCircuit[ActiveActor]->Solution->WriteConvergenceReport(GetOutputDirectory() + CircuitName_[ActiveActor] + "Convergence.TXT"); + break; + case 5: + { + ParamName = Parser[ActiveActor]->GetNextParam(); // Look for another param + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + ShowElements(GetOutputDirectory() + CircuitName_[ActiveActor] + "Elements.Txt", Param); + } + break; + case 6: + ShowFaultStudy(GetOutputDirectory() + CircuitName_[ActiveActor] + "FaultStudy.Txt"); + break; + case 7: + ShowIsolated(GetOutputDirectory() + CircuitName_[ActiveActor] + "Isolated.Txt"); + break; + case 8: + ShowGenMeters(GetOutputDirectory() + CircuitName_[ActiveActor] + "GenMeterOut.Txt"); + break; + case 9: + ShowMeters(GetOutputDirectory() + CircuitName_[ActiveActor] + "EMout.Txt"); + break; // Show Monitor + case 10: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + { + int stop = 0; + if(ConcatenateReports) // In case of being activated, the export will be made for all actors + { + InitP = 1; + FinalP = NumOfActors; + } + else + // Otherwise just for the active actor monitor + { + InitP = ActiveActor; + FinalP = ActiveActor; + } + for(stop = FinalP, idxP = InitP; idxP <= stop; idxP++) + { + pMon = (TMonitorObj*) MonitorClass[idxP]->Find(Param); + if(pMon != nullptr) + pMon->TranslateToCSV((idxP == FinalP), idxP); + else + DoSimpleMsg(String("Monitor \"") + Param + + "\" not found." + + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 248); + } + } + else + DoSimpleMsg(String("Monitor Name Not Specified.") + CRLF + + Parser[ActiveActor]->get_CmdBuffer(), 249); + } + break; + case 11: + ShowControlPanel(); + break; + case 12: + { + ShowOptionCode = 0; + MVAopt = 0; + FilName = "Power"; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + switch(Param[0]) + { + case L'm': + MVAopt = 1; + break; + case L'e': + ShowOptionCode = 1; + break; + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + { + if(Param[0] == L'e') + ShowOptionCode = 1; + } + if(ShowOptionCode == 1) + FilName = FilName + "_elem"; + else + FilName = FilName + "_seq"; + if(MVAopt == 1) + FilName = FilName + "_MVA"; + else + FilName = FilName + "_kVA"; + ShowPowers(GetOutputDirectory() + CircuitName_[ActiveActor] + FilName + ".txt", MVAopt, ShowOptionCode); + } + break; + case 13: + { + LLopt = false; // Line-Line voltage option + ShowOptionCode = 0; + /*Check for LL or LN option*/ + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + FilName = "VLN"; + if(Param.size() > 0) + { + if(CompareText(Param, "ll") == 0) + { + LLopt = true; + FilName = "VLL"; + } + /*Check for Seq | nodes | elements*/ + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = UpperCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + switch(Param[0]) + { + case L'N': + { + ShowOptionCode = 1; + FilName = FilName + "_Node"; + } + break; + case L'E': + { + ShowOptionCode = 2; + FilName = FilName + "_elem"; + } + break; + default: + FilName = FilName + "_seq"; + break; + } + ShowVoltages(GetOutputDirectory() + CircuitName_[ActiveActor] + FilName + ".Txt", LLopt, ShowOptionCode); + } + break; + case 14: + ShowMeterZone(GetOutputDirectory() + CircuitName_[ActiveActor] + "ZoneOut.Txt"); + break; + case 15: + ShowRegulatorTaps(GetOutputDirectory() + CircuitName_[ActiveActor] + "RegTaps.Txt"); + break; + case 16: + ShowOverloads(GetOutputDirectory() + CircuitName_[ActiveActor] + "Overload.Txt"); + break; + case 17: + { + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = Parser[ActiveActor]->MakeString_(); + if(Param.size() > 0) + ShowUnserved(GetOutputDirectory() + CircuitName_[ActiveActor] + "Unserved.Txt", true); + else + ShowUnserved(GetOutputDirectory() + CircuitName_[ActiveActor] + "Unserved.Txt", false); + } + break; + case 18: + ShowEventLog(GetOutputDirectory() + CircuitName_[ActiveActor] + "EventLog.Txt"); + break;// ShowMessageForm(EventStrings); + case 19: + ShowVariables(GetOutputDirectory() + CircuitName_[ActiveActor] + "Variables.Txt"); + break; + case 20: + ShowRatings(GetOutputDirectory() + CircuitName_[ActiveActor] + "RatingsOut.Txt"); + break; + case 21: + ShowLoops(GetOutputDirectory() + CircuitName_[ActiveActor] + "Loops.Txt"); + break; + case 22: + ShowLosses(GetOutputDirectory() + CircuitName_[ActiveActor] + "Losses.Txt"); + break; // Show Bus Power Report + case 23: + { + ShowOptionCode = 0; + MVAopt = 0; + ParamName = Parser[ActiveActor]->GetNextParam(); // Get busname + Busname = Parser[ActiveActor]->MakeString_(); + if(Busname.size() > 0) + FilName = Busname; + else + FilName = "BusPower"; + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + switch(Param[0]) + { + case L'm': + MVAopt = 1; + break; + case L'e': + ShowOptionCode = 1; + break; + default: + ; + break; + } + ParamName = Parser[ActiveActor]->GetNextParam(); + Param = LowerCase(Parser[ActiveActor]->MakeString_()); + if(Param.size() > 0) + { + if(Param[0] == L'e') + ShowOptionCode = 1; + } + if(ShowOptionCode == 1) + FilName = FilName + "_elem"; + else + FilName = FilName + "_seq"; + if(MVAopt == 1) + FilName = FilName + "_MVA"; + else + FilName = FilName + "_kVA"; + ShowBusPowers(GetOutputDirectory() + CircuitName_[ActiveActor] + FilName + ".txt", Busname, MVAopt, ShowOptionCode); + } + break; /*ShowLineConstants Show Lineconstants 60 mi*/ + case 24: + { + Freq = DefaultBaseFreq; // Default + Units = UNITS_KFT; // 'kft'; // default + Rho_line = 100.0; + ParamName = Parser[ActiveActor]->GetNextParam(); + if(Parser[ActiveActor]->MakeString_().size() > 0) + Freq = Parser[ActiveActor]->MakeDouble_(); + ParamName = Parser[ActiveActor]->GetNextParam(); + if(Parser[ActiveActor]->MakeString_().size() > 0) + Units = GetUnitsCode(Parser[ActiveActor]->MakeString_()); + ParamName = Parser[ActiveActor]->GetNextParam(); + if(Parser[ActiveActor]->MakeString_().size() > 0) + Rho_line = Parser[ActiveActor]->MakeDouble_(); + ShowLineConstants(GetOutputDirectory() + CircuitName_[ActiveActor] + "LineConstants.txt", Freq, Units, Rho_line); + } + break; + case 25: + if(ActiveCircuit[ActiveActor] != nullptr) /*Yprim*/ + { + /*# with ActiveCircuit[ActiveActor].ActiveCktElement do */ + { + auto with0 = (TDSSObject*) ActiveCircuit[ActiveActor]->get_FActiveCktElement(); + ShowYPrim(GetOutputDirectory() + with0->ParentClass->get_myClass_name() + "_" + with0->get_Name() + "_Yprim.txt"); + } + } + break; /*Y*/ + case 26: + { + ShowY(GetOutputDirectory() + CircuitName_[ActiveActor] + "SystemY.txt"); + } + break; + case 27: + if(ActiveCircuit[ActiveActor] != nullptr) + ActiveCircuit[ActiveActor]->ControlQueue.ShowQueue(GetOutputDirectory() + CircuitName_[ActiveActor] + "ControlQueue" + RepTermination); + break; + case 28: + ShowTopology(GetOutputDirectory() + CircuitName_[ActiveActor]); + break; + case 29: + ShowNodeCurrentSum(GetOutputDirectory() + CircuitName_[ActiveActor] + "NodeMismatch.Txt"); + break; + case 30: + ShowkVBaseMismatch(GetOutputDirectory() + CircuitName_[ActiveActor] + "kVBaseMismatch.Txt"); + break; + case 31: + ShowDeltaV(GetOutputDirectory() + CircuitName_[ActiveActor] + "DeltaV.Txt"); + break; + case 32: + FireOffEditor(QueryLogFileName); + break; + case 33: + ShowControlledElements(GetOutputDirectory() + CircuitName_[ActiveActor] + "ControlledElements" + RepTermination); + break; + case 34: + ShowResult(GetOutputDirectory() + CircuitName_[ActiveActor] + "Result" + RepTermination); + break; + case 35: + ShowPV2PQGen(GetOutputDirectory() + CircuitName_[ActiveActor] + "PV2PQ_Generators.Txt"); + break; + default: + ; + break; + } + InShowResults = false; + return result; + } + + void DisposeStrings() + { + delete[] ShowOption; + delete[] ShowHelp; + } + + + void ShowOptions_initialization() + { + DefineOptions(); + ShowCommands = new TCommandList(ShowOption, NumShowOptions); + ShowCommands->set_AbbrevAllowed(true); + } + + void ShowOptions_finalization() + { + DisposeStrings(); + delete ShowCommands; + } + + class ShowOptions_unit + { + public: + ShowOptions_unit() + { + //AssertSystemInitialization(); + ShowOptions_initialization(); + } + ~ ShowOptions_unit(){ShowOptions_finalization(); } + }; + ShowOptions_unit _ShowOptions_unit; + +} // namespace ShowOptions + + + + diff --git a/OpenDSSC/Executive/ShowOptions.h b/OpenDSSC/Executive/ShowOptions.h new file mode 100644 index 0000000..a56ae08 --- /dev/null +++ b/OpenDSSC/Executive/ShowOptions.h @@ -0,0 +1,44 @@ +#ifndef ShowOptionsH +#define ShowOptionsH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "d2c_structures.h" + +#include "ShowResults.h" +#include "ParserDel.h" +#include "Monitor.h" +#include "Utilities.h" +#include "DSSGlobals.h" +#include "CmdForms.h" +#include "LineUnits.h" + +namespace ShowOptions +{ + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + const int NumShowOptions = 35; + int DoShowCmd(); + extern std::string* ShowOption; + extern std::string* ShowHelp; + extern Command::TCommandList* ShowCommands; + + +} // namespace ShowOptions + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ShowOptions; +#endif + +#endif // ShowOptionsH + + + + diff --git a/OpenDSSC/Forms/CmdForms.cpp b/OpenDSSC/Forms/CmdForms.cpp new file mode 100644 index 0000000..70904f7 --- /dev/null +++ b/OpenDSSC/Forms/CmdForms.cpp @@ -0,0 +1,324 @@ + + +#pragma hdrstop + +#include "CmdForms.h" + +#ifndef linux + #define NOMINMAX + #include +#else + #include +#endif + +bool ControlPanelCreated = false; +bool RebuildHelpForm = false; + +const int colwidth = 25; +const int numcols = 4; // for listing commands to the console + +void ShowHeapUsage( ) +{ +} + + +void InitProgressForm( ) +{ +} + + +void ShowPctProgress( int Count ) +{ +} + + +void ProgressCaption( const String S ) +{ + CoutLn( "Progress: " ); CoutLn( S ); +} + + +void ProgressFormCaption( const String S ) +{ + CoutLn( "Progress: " ); CoutLn( S ); +} + + +void ProgressHide( ) +{ +} + + +void ShowAboutBox( ) +{ + CoutLn( "Console OpenDSS (Electric Power Distribution System Simulator)" ); + CoutLn( "Version: " + VersionString ); + CoutLn( "Copyright (c) 2008-2021, Electric Power Research Institute, Inc." ); + CoutLn( "Copyright (c) 2016-2021, Battelle Memorial Institute" ); + CoutLn( "All rights reserved." ); +} + +void ShowTreeView( const String Fname ) +{ +} + + +String GetDSSExeFile( ) +{ + String result; + Char TheFileName[ MAX_PATH ]; + FillChar( TheFileName, sizeof( TheFileName ), '\x00' ); // Fill it with nulls + #ifndef linux + GetModuleFileName( NULL, TheFileName, sizeof( TheFileName ) ); + #else + ssize_t len = readlink("/proc/self/exe", TheFileName, sizeof(TheFileName)-1); + if(len != -1){ + TheFileName[len] = '\0'; + return std::string(TheFileName); + } + #endif + + result = TheFileName; + if ( IsLibrary ) + IsDLL = true; + return result; +} + + +int DSSMessageDlg( const String Msg, bool err ) +{ + int result = 0; + result = 0; + if ( err ) + CoutLn( "** Error: " ); + CoutLn( Msg ); + return result; +} + + +void DSSInfoMessageDlg( const String Msg ) +{ + CoutLn( Msg ); +} + + +void CreateControlPanel( ) +{ +} + + +void ExitControlPanel( ) +{ +} + + +void ShowControlPanel( ) +{ +} + + +int CompareClassNames( void* Item1, void* Item2 ) +{ + int result = 0; + result = CompareText( ((TDSSClass*) Item1 )->get_myClass_name(), ((TDSSClass*) Item2 )->get_myClass_name() ); + return result; +} + + +void AddHelpForClasses( WORD BaseClass, bool bProperties ) +{ + TList HelpList; + TDSSClass* pDSSClass; + int i = 0, j = 0, idx = 0; + HelpList = TList( ); + + idx = ActiveDSSClass[ActiveActor]->Get_First(); + pDSSClass = (TDSSClass*) ActiveDSSObject[ActiveActor]; + + pDSSClass = (TDSSClass*) DSSClassList[ActiveActor].Get_First(); + while ( pDSSClass != NULL ) + { + if ( ( ( pDSSClass->DSSClassType & BaseClassMask ) ) == BaseClass ) + HelpList.push_back( pDSSClass ); + + idx = ActiveDSSClass[ActiveActor]->Get_Next(); + pDSSClass = (TDSSClass*) ActiveDSSObject[ActiveActor]; + pDSSClass = (TDSSClass*) DSSClassList[ActiveActor].Get_Next(); + } + //HelpList.Sort( &CompareClassNames ); + for ( int stop = HelpList.size(), i = 1; i <= stop; i++) + { + pDSSClass = (TDSSClass*) HelpList[i - 1]; + CoutLn( pDSSClass->get_myClass_name() ); + if ( bProperties == true ) + for ( int stop = pDSSClass->NumProperties, j = 1; j <= stop; j++) + { + CoutLn( " " ); CoutLn( pDSSClass->PropertyName[j] ); CoutLn( ": " ); CoutLn( pDSSClass->PropertyHelp[j] ); + } + } + HelpList.clear(); +} + + +void ShowGeneralHelp( ) +{ + CoutLn( "This is a console-mode version of OpenDSS, available for Windows, Linux and Mac OS X" ); + CoutLn( "Enter a command at the >> prompt, followed by any required command parameters" ); + CoutLn( "Enter either a carriage return, \"exit\" or \"q(uit)\" to exit the program" ); + CoutLn( "For specific help, enter:" ); + CoutLn( " \"help command [cmd]\" lists all executive commands, or" ); + CoutLn( " if [cmd] provided, details on that command" ); + CoutLn( " \"help option [opt]\" lists all simulator options, or" ); + CoutLn( " if [opt] provided, details on that option" ); + CoutLn( " \"help show [opt]\" lists the options to \"show\" various outputs, or" ); + CoutLn( " if [opt] provided, details on that output" ); + CoutLn( " \"help export [fmt]\" lists the options to \"export\" in various formats, or" ); + CoutLn( " if [fmt] provided, details on that format" ); + CoutLn( " \"help class [cls]\" lists the names of all available circuit model classes, or" ); + CoutLn( " if [cls] provided, details on that class" ); + CoutLn( "You may truncate any help topic name, which returns all matching entries" ); + CoutLn( "// begins a comment, which is ignored by the parser (including help)" ); +} + +void ShowAnyHelp( const int num, pStringArray cmd, pStringArray hlp, const String opt ) +{ + int i = 0; + TStringList lst; + if ( opt.size( ) < 1 ) + { + lst = TStringList(); + for ( int stop = num, i = 1; i <= stop; i++) + lst.push_back( (cmd)[i] + PadRight((colwidth - (cmd)[i].size()), " ") ); +// lst.Sort; + for ( int stop = num, i = 1; i <= stop; i++) + if ( ( i % numcols ) == 0 ) + CoutLn( lst[i - 1] ); + else + CoutLn( lst[i - 1] + " " ); + lst.clear(); + } + else + { + for ( int stop = num, i = 1; i <= stop; i++) + { + if ( (LowerCase((cmd)[i]).find( opt ) ) != String::npos ) + { + CoutLn( UpperCase( (cmd)[i])); + CoutLn( "======================" ); + CoutLn( (hlp)[i] ); + } + } + } +} + + +void ShowClassHelp( const String opt ) +{ + TDSSClass* pDSSClass; + int i = 0, idx = 0; + if ( opt.size( ) > 0 ) + { + idx = ActiveDSSClass[ActiveActor]->Get_First(); + pDSSClass = (TDSSClass*) ActiveDSSObject[ActiveActor]; + pDSSClass = (TDSSClass*) DSSClassList[ActiveActor].Get_First(); + while ( pDSSClass != NULL ) + { + if (LowerCase(pDSSClass->get_myClass_name()).find( opt ) != String::npos ) + { + CoutLn( UpperCase( pDSSClass->get_myClass_name() ) ); + CoutLn( "======================" ); + for ( int stop = pDSSClass->NumProperties, i = 1; i <= stop; i++) + { + CoutLn( " " ); CoutLn( pDSSClass->PropertyName[i] ); CoutLn( ": " ); CoutLn( pDSSClass->PropertyHelp[i] ); + } + } + idx = ActiveDSSClass[ActiveActor]->Get_Next(); + pDSSClass = (TDSSClass*) ActiveDSSObject[ActiveActor]; + pDSSClass = (TDSSClass*) DSSClassList[ActiveActor].Get_Next(); + } + } + else + { + CoutLn( "== Power Delivery Elements ==" ); + AddHelpForClasses( PD_ELEMENT, false ); + CoutLn( "== Power Conversion Elements ==" ); + AddHelpForClasses( PC_ELEMENT, false ); + CoutLn( "== Control Elements ==" ); + AddHelpForClasses( CTRL_ELEMENT, false ); + CoutLn( "== Metering Elements ==" ); + AddHelpForClasses( METER_ELEMENT, false ); + CoutLn( "== Supporting Elements ==" ); + AddHelpForClasses( 0, false ); + CoutLn( "== Other Elements ==" ); + AddHelpForClasses( NON_PCPD_ELEM, false ); + } +} + + +void ShowHelpForm( ) +{ + String Param = "", + OptName = ""; + String dummy = Parser[ActiveActor]->GetNextParam(); + + Param = LowerCase( Parser[ActiveActor]->MakeString_() ); + dummy = Parser[ActiveActor]->GetNextParam(); + OptName = LowerCase( Parser[ActiveActor]->MakeString_() ); + if ( Param.find("com") != String::npos) + ShowAnyHelp( NumExecCommands, *(pStringArray*) ExecCommand, *(pStringArray*) CommandHelp, OptName ); + else + if (Param.find( "op" ) != String::npos) + ShowAnyHelp( NumExecOptions, *(pStringArray*) ExecOption, *(pStringArray*) OptionHelp, OptName ); + else + if (Param.find( "sh" ) != String::npos) + ShowAnyHelp( NumShowOptions, *(pStringArray*) ShowOption, *(pStringArray*) ShowHelp, OptName ); + else + if (Param.find( 'e' ) != String::npos) + ShowAnyHelp( NumExportOptions, *(pStringArray*) ExportOption, *(pStringArray*) ExportHelp, OptName ); + else + if (Param.find( "cl" ) != String::npos) + ShowClassHelp( OptName ); + else + ShowGeneralHelp(); +} + + +void ShowMessageForm( TStringList S ) +{ + CoutLn( S[0]); +} + + +void ShowPropEditForm( ) +{ +} + + +void CloseDownForms( ) +{ +} + + +bool MakeChannelSelection( int NumFieldsToSkip, const String FileName ) +{ + bool result = false; + result = false; + return result; +} + +void CmdForms_initialization() +{ + RebuildHelpForm = true; +} + +class CmdForms_unit +{ +public: +CmdForms_unit() +{ + CmdForms_initialization(); +} +}; +CmdForms_unit _CmdForms_unit; + + diff --git a/OpenDSSC/Forms/CmdForms.h b/OpenDSSC/Forms/CmdForms.h new file mode 100644 index 0000000..0369ad6 --- /dev/null +++ b/OpenDSSC/Forms/CmdForms.h @@ -0,0 +1,60 @@ +#ifndef CmdFormsH +#define CmdFormsH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 08/17/2016 Created from OpenDSS + ---------------------------------------------------------- + Copyright (c) 2016-2020 Battelle Memorial Institute + ---------------------------------------------------------- +*/ + + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "ExecCommands.h" +#include "ExecOptions.h" +#include "ShowOptions.h" +#include "ExportOptions.h" +#include "DSSGlobals.h" +#include "DSSClass.h" +#include "DSSClassDefs.h" +#include "ParserDel.h" +#include "Arraydef.h" +#include "myCmdUtils.h" + +//#include + +extern bool ControlPanelCreated; // signify whether this is the DLL or EXE + +extern bool RebuildHelpForm; +void CreateControlPanel( ); +void ExitControlPanel( ); +void InitProgressForm( ); +void ProgressCaption( const String S ); +void ProgressFormCaption( const String S ); +void ProgressHide( ); +void ShowControlPanel( ); +void ShowHelpForm( ); +void ShowAboutBox( ); +void ShowPropEditForm( ); +void ShowPctProgress( int Count ); +void ShowMessageForm( TStringList S ); +int DSSMessageDlg( const String Msg, bool err ); +void DSSInfoMessageDlg( const String Msg ); +String GetDSSExeFile( ); +void CloseDownForms( ); +void ShowTreeView( const String Fname ); +bool MakeChannelSelection( int NumFieldsToSkip, const String FileName ); +void ShowHeapUsage( ); // copied from Lazarus form; not used in command line yet + +#endif // CmdFormsH + diff --git a/OpenDSSC/Forms/myCmdUtils.cpp b/OpenDSSC/Forms/myCmdUtils.cpp new file mode 100644 index 0000000..cfa6fe9 --- /dev/null +++ b/OpenDSSC/Forms/myCmdUtils.cpp @@ -0,0 +1,38 @@ +#include "System.h" +#include +#include +/* +#ifdef windows-default +#include +#define GetMyDir _getcwd +#else +#include +#define GetCurrentDir getcwd +#endif +*/ +using namespace std; + +/*void WriteLn(string mytext) +{ + cout << mytext; +}*/ +/* +string GetCurrentDir() +{ + char buff[FILENAME_MAX]; //create string buffer to hold path + GetMyDir(buff, FILENAME_MAX); + string current_working_dir(buff); + return current_working_dir; +}*/ +/* +void SetCurrentDir(string myDir) +{ + //current_path(myDir); +}*/ + + + + + + + diff --git a/OpenDSSC/Forms/myCmdUtils.h b/OpenDSSC/Forms/myCmdUtils.h new file mode 100644 index 0000000..4b20460 --- /dev/null +++ b/OpenDSSC/Forms/myCmdUtils.h @@ -0,0 +1,17 @@ +#ifndef myCmdUtilsH +#define myCmdUtilsH + +#include +#include +#include + + //void WriteLn(const string mytext); + +//string GetCurrentDir(); +//void SetCurrentDir(string myDir); + + + +#endif // CmdFormsH + + diff --git a/OpenDSSC/GISCommands/GISCommands.cpp b/OpenDSSC/GISCommands/GISCommands.cpp new file mode 100644 index 0000000..fe81275 --- /dev/null +++ b/OpenDSSC/GISCommands/GISCommands.cpp @@ -0,0 +1,1853 @@ + + +#pragma hdrstop + +#include "GISCommands.h" +#include "dirsep.h" + + +namespace GISCommands +{ + +/* +TIdTCPClient GISTCPClient; +TIdThreadComponent GISThreadComponent; +*/ + std::vector< double > myCoords; + TCommandList* GISCommandList; + String* GISOption; + String* GISHelp; + + + void DefineOptions( ) + { + + GISOption = new String[NumGISOptions]; + GISHelp = new String[NumGISOptions]; + + GISOption[1 - 1] = "Start"; + GISOption[2 - 1] = "ShowBus"; + GISOption[3 - 1] = "FindRoute"; + GISOption[4 - 1] = "GetRoute"; + GISOption[5 - 1] = "RouteDistance"; + GISOption[6 - 1] = "ShowRoute"; + GISOption[7 - 1] = "JSONRoute"; + GISOption[8 - 1] = "WindowDistribLR"; + GISOption[9 - 1] = "WindowDistribRL"; + GISOption[10 - 1] = "WindowSize"; + GISOption[11 - 1] = "PlotCircuit"; + GISOption[12 - 1] = "showLine"; + GISOption[13 - 1] = "ExportMap"; + GISOption[14 - 1] = "RouteSegDistances"; + GISOption[15 - 1] = "MapView"; + GISOption[16 - 1] = "ClearMap"; + GISOption[17 - 1] = "DrawLine"; + GISOption[18 - 1] = "ZoomMap"; + GISOption[19 - 1] = "PlotFile"; + GISOption[20 - 1] = "GoTo"; + GISOption[21 - 1] = "PlotPoints"; + GISOption[22 - 1] = "PlotPoint"; + GISOption[23 - 1] = "LoadBus"; + GISOption[24 - 1] = "ShowCoords"; + GISOption[25 - 1] = "Format"; + GISOption[26 - 1] = "BatchFormat"; + GISOption[27 - 1] = "Close"; + GISOption[28 - 1] = "Distance"; + GISOption[29 - 1] = "Select"; + GISOption[30 - 1] = "StopSelect"; + GISOption[31 - 1] = "GetSelect"; + GISOption[32 - 1] = "DrawLines"; + GISOption[33 - 1] = "StopDraw"; + GISOption[34 - 1] = "GetPolyline"; + GISOption[35 - 1] = "GetAddress"; + GISOption[36 - 1] = "Text"; + GISOption[37 - 1] = "TextFromFile"; + GISHelp[1 - 1] = "Starts OpenDSS-GIS only if it is installed in the local machine"; + GISHelp[2 - 1] = "Shows the bus specified on the map, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[3 - 1] = String( "Finds a route between the given buses using roads and geographical information. The buses are described as an array" ) + " as follows: GISFindRoute [b1 b2 - 1], do not include phases. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[4 - 1] = "Returns the GIS coords of the route between 2 buses step by step, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. GISFindRoute has been executed at some point before this command (at least once)" + CRLF + "4. The model needs to have the correct GISCoords file"; + GISHelp[5 - 1] = "Returns the distance (value units) of the last route calculated between 2 buses, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. GISFindRoute has been executed at some point before this command (at least once)" + CRLF + "4. The model needs to have the correct GISCoords file"; + GISHelp[6 - 1] = "Shows the last route calculated between 2 buses in OpenDSS-GIS, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. GISFindRoute has been executed at some point before this command (at least once)" + CRLF + "4. The model needs to have the correct GISCoords file"; + GISHelp[7 - 1] = "Returns the JSON script describing the last route calculated between 2 buses, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. GISFindRoute has been executed at some point before this command (at least once)" + CRLF + "4. The model needs to have the correct GISCoords file"; + GISHelp[8 - 1] = "Redistributes the windows horizontally leaving OpenDSS to the left of the screen and OpenDSS-GIS to the right, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)"; + GISHelp[9 - 1] = "Redistributes the windows horizontally leaving OpenDSS to the right of the screen and OpenDSS-GIS to the left, however, the following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)"; + GISHelp[10 - 1] = "Resizes the OpenDSS-GIS window, the coordiantes need to be given as: Left, Top, Right, Bottom. For example:" + CRLF + CRLF + "GISWindowSize 0 0 800 800" + CRLF + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + + "2. OpenDSS-GIS must be initialized (use GIS Start command)"; + GISHelp[11 - 1] = "Draws the circuit on top of the map displayed in OpenDSS-GIS. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[12 - 1] = "Shows the line specified int he argument using OpenDSS-GIS. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[13 - 1] = "Exports the current map view into the models folder as a PNG file. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[14 - 1] = "Returns Tree/No tree if a tree intersects with the line given in the argument. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[15 - 1] = "Chenges the map view in OpenDSS-GIS using one of the following arguments:" + CRLF + CRLF + "- Streets" + CRLF + "- StreetsVector" + CRLF + "- StreetsNight" + CRLF + "- Satellite" + CRLF + + "- SatelliteLabels" + CRLF + "- SatelliteLabelsVector" + CRLF + "- DarkGrayCanvas" + CRLF + "- LightGrayCanvas" + CRLF + "- LightGrayCanvasVector" + CRLF + + "- Navigation" + CRLF + "- OpenStreetMap" + CRLF + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[16 - 1] = "Clears the Map by removing all the previous draws. The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[17 - 1] = "Draws a line at the given coordinates using the color and thickness (pix) specified." + CRLF + "The line features can be defined using GISCoords, GISColor and GISThickness from the exective options." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + + "3. The model needs to have the correct GISCoords file"; + GISHelp[18 - 1] = "Zooms the map at the area specified at GISCoords." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[19 - 1] = "Plots the content of the file specified in the argument on top of the current map." + CRLF + "With this function it is expected that the content of the file describes lines, their color and thickness." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + + "3. The model needs to have the correct GISCoords file"; + GISHelp[20 - 1] = String( "Shows the location in the map at given the coordinates." ) + "The coordiantes must be defined using GISCoords." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)"; + GISHelp[21 - 1] = "Plots the content of the file specified in the argument on top of the current map." + CRLF + "This function plots the content as points, the point shape, color and size must be specified in the file." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + + "3. The model needs to have the correct GISCoords file"; + GISHelp[22 - 1] = String( "plots the shape specified in the argument in the map at given the coordinates." ) + "The coordiantes must be defined using GISCoords, the size and color can be specified through the options GISColor and GISThickness." + CRLF + "The shape can be one fo the following:" + CRLF + CRLF + " Circle" + CRLF + " + " + CRLF + " Diamond" + + CRLF + " Square" + CRLF + " Triangle" + CRLF + " x" + CRLF + CRLF + "The following conditions need to be fulfilled:" + CRLF + + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)"; + GISHelp[23 - 1] = String( "Uploads the coordinates of the bus specified in the argument to the coordinates buffer by pushing the previous down." ) + " The coordinates buffer has 4 positions, the coordinates of the bus specified will be at the first 2 positions." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file" + ; + GISHelp[24 - 1] = "Returns the content of the coordinates buffer." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[25 - 1] = String( "Formats the coordinates located at the first 2 places of the coordiantes buffer. The first argument indicates " ) + "the original format and the second argument the destination format. The format can be one of the following:" + CRLF + CRLF + "- LatLong (latitude, Longitude - WGS84))" + CRLF + "- DMS (Degrees, minutes, seconds) " + CRLF + "- UTM (Universal Transverse Mercator)" + CRLF + "- USNG" + + CRLF + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file" + ; + GISHelp[26 - 1] = String( "Formats the coordinates within the file specified. The first argument indicates " ) + "the original format and the second argument the destination format. The third argument is the path to the source file" + " containing the coordinates, which should be organized in 2 columns comma separated. The format can be one of the following:" + CRLF + CRLF + "- LatLong (latitude, Longitude - WGS84))" + CRLF + "- DMS (Degrees, minutes, seconds) " + CRLF + "- UTM (Universal Transverse Mercator)" + CRLF + + "- USNG" + CRLF + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + + "3. The model needs to have the correct GISCoords file"; + GISHelp[27 - 1] = "Closses all the instances of OpenDSS-GIS"; + GISHelp[28 - 1] = "Returns the distance in meters between the coordinates in the buffer." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[29 - 1] = "Commands OpenDSS-GIS to start the selection mode for allowing users to draw an area on the map." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[30 - 1] = "Stops the latest select command sent to OpenDSS-GIS. Clears the map from selections and stores the selection coords in OpenDSS-GIS." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[31 - 1] = "Requests the boundaries of the latest selection. The boundaties are returned as XMin, YMin, XMax and YMax in WGS84 coords format." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[32 - 1] = "Commands OpenDSS-GIS to start line drawing mode for allowing the user to draw a polyline over the map." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[33 - 1] = "Stops the latest line drawing mode in OpenDSS-GIS. Clears the map and stores the coordinates of the polyline drawn by the user (if any)." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[34 - 1] = "Requests the coordinates of the latest polyline drawn by the user to OpenDSS-GIS. The are returned in coordiante pairs (Longitude, latitude) in WGS84 coords format." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[35 - 1] = "Returns the address calculated at the coordinates given in GISCoords. The address is returned in a JSON string." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[36 - 1] = "Plots the text given at the argument at the coordinates given in GISCoords with the color given at GISCOlor and size given at GISThickness." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + GISHelp[37 - 1] = "Plots the text within the file given at the path in the argument." + CRLF + "The following conditions need to be fulfilled:" + CRLF + CRLF + "1. OpenDSS-GIS must be installed" + CRLF + "2. OpenDSS-GIS must be initialized (use GIS Start command)" + CRLF + "3. The model needs to have the correct GISCoords file"; + } + + String DoGISCmd( ) + { + String dummy, result; + String FormatFrom, FormatTo, ParamName, Param; + int ParamPointer = 0, i = 0; + // double DblBuffer[ 51/*# range 0..50*/ ]; + + /* Get next parameter on command line */ + result = "Unknown GIS command;"; + ParamPointer = 0; + ParamName = UpperCase( Parser[ActiveActor]->GetNextParam() ); + Param = UpperCase( Parser[ActiveActor]->MakeString_() ); + /* Interpret Parameter */ + if ( Param.size() != 0 ) + { + ParamPointer = GISCommandList->Getcommand( Param ); + + /* Check options requiring a solution and abort if no solution or circuit */ + switch ( ParamPointer ) + { + case 1: + if ( start_openDSSGIS( ) ) + result = "GIS Started succesfully"; + else + result = "Error, check if OpenDSS-GIS is running and your firewall setup"; + break; + case 2: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = show_busGIS( Parser[ActiveActor]->MakeString_() ); + } + break; + case 3: + result = Get_routeGIS( ); + break; + case 4: + result = Get_edgesGIS( ); + break; + case 5: + result = Get_distanceGIS( ); + break; + case 6: + result = Show_routeGIS( ); + break; + case 7: + result = Get_JSONrouteGIS( ); + break; + case 8: + { + if ( ! IsDLL ) + { + result = WindowLR( ); + // ControlPanel.ReSizeWindow( 0 ); + } + else + result = "Available only for the EXE interface"; + } + break; + case 9: + { + if ( ! IsDLL ) + { + result = WindowRL( ); + // ControlPanel.ReSizeWindow( 1 ); + } + else + result = "Available only for the EXE interface"; + } + break; + case 10: + { + result = ReSizeWindow( ); + } + break; + case 11: + result = GISDrawCircuit(); + break; + // Draws the circuit on top of the map in DSS-GIS + + case 12: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = show_lineGIS( Parser[ActiveActor]->MakeString_() ); + } + break; + case 13: + result = export_mapGIS( ); + break; + // exports the current map view into the model's folder + + case 14: + { + result = GetRouteSegDistances( ); + // returns the distances of all the segments of the last route estimated + } + break; + case 15: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = set_map_View( LowerCase( Parser[ActiveActor]->MakeString_() ) ); + } + break; + case 16: + result = clear_map( ); + break; + case 17: + result = Draw_line_GIS( ); + break; + case 18: + result = Zoom_area_GIS( ); + break; + case 19: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISPlotfile( LowerCase( Parser[ActiveActor]->MakeString_() ) ); + } + break; + case 20: + { + result = show_LatLong( ); + } + break; + case 21: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISPlotPoints( LowerCase( Parser[ActiveActor]->MakeString_() ) ); + } + break; + case 22: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISPlotPoint( LowerCase( Parser[ActiveActor]->MakeString_() ) ); + } + break; + case 23: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISLoadBus( LowerCase( Parser[ActiveActor]->MakeString_() ) ); + } + break; + case 24: + { + result = GISShowBuffer( ); + } + break; + case 25: + { + dummy = Parser[ActiveActor]->GetNextParam(); + FormatFrom = LowerCase( Parser[ActiveActor]->MakeString_() ); + dummy = Parser[ActiveActor]->GetNextParam(); + FormatTo = LowerCase( Parser[ActiveActor]->MakeString_() ); + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISFormat( FormatFrom, FormatTo, Parser[ActiveActor]->MakeString_() ); + } + break; + case 26: + { + dummy = Parser[ActiveActor]->GetNextParam(); + FormatFrom = LowerCase( Parser[ActiveActor]->MakeString_() ); + dummy = Parser[ActiveActor]->GetNextParam(); + FormatTo = LowerCase( Parser[ActiveActor]->MakeString_() ); + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISBatchFormat( FormatFrom, FormatTo, Parser[ActiveActor]->MakeString_() ); + } + break; + case 27: + result = GISClose( ); + break; + case 28: + result = Get_distance( ); + break; + case 29: + result = GISStartSelect( ); + break; + case 30: + result = GISStopSelect( ); + break; + case 31: + result = GISGetSelect( ); + break; + case 32: + result = GISStartDrawLine( ); + break; + case 33: + result = GISStopDrawLine( ); + break; + case 34: + result = GISGetPolyline( ); + break; + case 35: + result = GISGetAddress( ); + break; + case 36: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISText( Parser[ActiveActor]->MakeString_() ); + } + break; + case 37: + { + dummy = Parser[ActiveActor]->GetNextParam(); + result = GISTextFromFile( Parser[ActiveActor]->MakeString_() ); + } + break; + default: {} + } + } + return result; + } + + bool start_openDSSGIS( ) + { + bool result = false; + String myPath, myFolder; + result = false; + /* + if ( DSS_GIS_Installed ) + { + myPath = StringReplace( DSS_GIS_path, DIRSEP_STR DIRSEP_STR, DIRSEP_CHAR, VECTOROFCONST(( rfReplaceAll, rfIgnoreCase )) ); + myPath = StringReplace( myPath, '\"', "", VECTOROFCONST(( rfReplaceAll, rfIgnoreCase )) ); + myFolder = ExtractFilePath( myPath ); + if ( ! processExists( "OpenDSSGIS.exe" ) ) + { + // Starts OpenDSS-GIS if is not running + ShellExecute( 0, "open", myPath.c_str(), NULL, myFolder.c_str(), SW_SHOWNORMAL ); + sleep( 5000 ); + IsGISON = false; + } + if ( ! IsGISON ) + { + // ... create TIdTCPClient + GISTCPClient = TIdTCPClient.Create( ); + // ... set properties + GISTCPClient.Host = "localhost"; + GISTCPClient.Port = DSSGISPort; + GISTCPClient.ReadTimeout = 1000; + GISThreadComponent = TIdThreadComponent.Create( ); + try + { + GISTCPClient.Connect; + IsGISON = true; + } + catch( Exception & E ) + { + { + IsGISON = false; + } + } + result = IsGISON; + } + else + result = IsGISON; + } + */ + return result; + } + + /* ******************************************************************************* + * Closes OpenDSS-GIS * + ******************************************************************************* */ + + + String GISClose( ) + { + String result = "nos available"; + /* + int myError = 0; + myError = ShellExecute( 0, NULL, "taskkill.exe", "/IM \"OpenDSSGIS.exe\" /F", "C:\\Windows\\System32", SW_HIDE ); + if ( myError > 32 ) + result = "OpenDSS-GIS closed successfuly"; + else + result = "An error has occurred while closing OpenDSS-GIS"; + */ + IsGISON = false; + return result; + } + + /* ******************************************************************************* + * Shows the given bus on the map * + ******************************************************************************* */ + + + String show_busGIS( String BusName ) + { + String result; + /* + TdJSON TCPJSON; + int i = 0; + double lat = 0.0, long = 0.0; + String InMsg; + if ( IsGISON ) + { + SetActiveBus( BusName ); + if ( ActiveCircuit[ActiveActor] != NULL ) + { + # with ActiveCircuit[ActiveActor] do + { + const ActiveCircuit& with0 = ActiveCircuit[ActiveActor]; + { + if ( ( ActiveBusIndex > 0 ) && ( ActiveBusIndex <= Numbuses ) ) + if ( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].GISCoorddefined ) + { + lat = Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].lat; + long = Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].long; + InMsg = "{\"command\":\"showlocation\",\"coords\":{\"longitude\":" + floattostr( long ) + ",\"latitude\":" + floattostr( lat ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["showlocation"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else + result = "One or both of the GIS coordinates are incorrect or not defined"; + } + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Shows the given location using LatLong * + ******************************************************************************* */ + + + + + String show_LatLong( ) + { + String result; + /* + TdJSON TCPJSON; + int i = 0; + double lat = 0.0, long = 0.0; + String InMsg; + if ( IsGISON ) + { + lat = GISCoords[1]; + long = GISCoords[2]; + InMsg = "{\"command\":\"showlocation\",\"coords\":{\"longitude\":" + floattostr( long ) + ",\"latitude\":" + floattostr( lat ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["showlocation"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Request to calculate a route between 2 buses * + ******************************************************************************* */ + + + String Get_routeGIS( ) + { + String result; + /* + TdJSON TCPJSON; + String JSONCmd, InMsg, BusName; + bool TryCom = false, error = false; + int i = 0; + double lat = 0.0, long = 0.0; + if ( IsGISON ) + { + InMsg = "{\"command\":\"route\",\"coords\":{\"long1\":" + floattostr( GISCoords[1] ) + ",\"lat1\":" + floattostr( GISCoords[2] ) + ",\"long2\":" + floattostr( GISCoords[3] ) + ",\"lat2\":" + floattostr( GISCoords[4] ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["route"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Request to coordiantes of the edges that define the last route calculated * + ******************************************************************************* */ + + + String Get_edgesGIS( ) + { + String result; + /* + TdJSON Coords, TCPJSON; + String JSONCmd, TempStr, InMsg; + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"jsonroute\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["coords"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Gets the distance of the last route calculated * + ******************************************************************************* */ + + + String Get_distanceGIS( ) + { + String result; + /* + TdJSON TCPJSON; + String JSONCmd, TempStr, InMsg; + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"routedistance\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["routedistance"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Shows on the map the last route calculated * + ******************************************************************************* */ + + + String Show_routeGIS( ) + { + String result; + /* + TdJSON TCPJSON; + String JSONCmd, TempStr, InMsg; + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"showroute\"},\"color\":\"" + GISColor + "\",\"thickness\":" + GISThickness + "}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["showroute"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Exports to a file the last route calculated in JSON format * + ******************************************************************************* */ + + + String Get_JSONrouteGIS( ) + { + String result; +// TTextRec F; + String JSONCmd, FileName, InMsg; + /* + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"jsonscript\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 20000 ); + FileName = GetOutputDirectory + CircuitName_[ActiveActor] + "JSONScript_route.txt"; // Explicitly define directory + Assignfile( F, FileName ); + Rewrite( F ); + IOResultToException(); + Write( F, InMsg ); + CloseFile( F ); + result = FileName; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Distributes the windows leaving OpenDSS on the left * + ******************************************************************************* */ + + + String WindowLR( ) + { + String result; + /* + TdJSON TCPJSON; + int ScrSize = 0; + String InMsg, TempStr, JSONCmd; + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"resizewindow\",\"coords\":{\"left\":" + inttostr( Screen.Width / 2 ) + ",\"top\":0,\"right\":" + inttostr( Screen.Width ) + ",\"bottom\":" + inttostr( Screen.Height - 40 ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["resizewindow"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Distributes the windows leaving OpenDSS to the right * + ******************************************************************************* */ + + + String WindowRL( ) + { + String result; + /* + TdJSON TCPJSON; + int ScrSize = 0; + String InMsg, TempStr, JSONCmd; + if ( IsGISON ) + { + JSONCmd = "{\"command\":\"resizewindow\",\"coords\":{\"left\":0,\"top\":0,\"right\":" + inttostr( Screen.Width / 2 ) + ",\"bottom\":" + inttostr( Screen.Height - 40 ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["resizewindow"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Resizes the OpenDSS-GIS window using the coordinates given by the user * + ******************************************************************************* */ + + + String ReSizeWindow( ) + { + String result; + /* + TdJSON TCPJSON; + int j = 0, ScrSize = 0; + String InMsg, TempStr, JSONCmd; + DynamicArray< String > TStrArr; + if ( IsGISON ) + { + TStrArr.Length = 4; + TStrArr[0] = ",\"top\":"; + TStrArr[1] = ",\"right\":"; + TStrArr[2] = ",\"bottom\":"; + TStrArr[3] = "}}"; + JSONCmd = "{\"command\":\"resizewindow\",\"coords\":{\"left\":"; + for ( int stop = TStrArr.High, j = 0; j <= stop; j++) + { + Parser[ActiveActor]->GetNextParam(); + JSONCmd = JSONCmd + Parser[ActiveActor]->MakeString_() + TStrArr[j]; + } + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 2000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["resizewindow"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Generates the file required by DSS-GIS to draw the model on the map * + ******************************************************************************* */ + + + String GISDrawCircuit( ) + { + String result = "not available"; + TLineObj LineElem; + String TxtRow, myBus; + int k = 0; +// TTextRec F; + String InMsg, TempStr, JSONCmd; + /* + TdJSON TCPJSON; + bool Add2file = false; + if ( ActiveCircuit[ActiveActor] != NULL ) + { + if ( IsGISON ) + { + # with ActiveCircuit[ActiveActor] do + { + const ActiveCircuit& with0 = ActiveCircuit[ActiveActor]; + { + if ( Lines.get_myNumList() > 0 ) + { + Assignfile( F, "GIS_desc.csv" ); + Rewrite( F ); + IOResultToException(); + LineElem = Lines.Get_First(); + while ( LineElem != NULL ) + { + TxtRow = ""; + Add2file = true; + for ( int stop = 2, k = 1; k <= stop; k++) + { + myBus = StripExtension( LineElem.GetBus( k ) ); + DSSGlobals.SetActiveBus( myBus ); + if ( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].GISCoorddefined ) + { + TxtRow = TxtRow + floattostr( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].long ) + "," + floattostr( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].lat ) + ","; + } + Add2file = Add2file && ( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].long != 0 ) && ( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].lat != 0 ); + } + if ( Add2file ) + WriteLn( F, TxtRow ); + LineElem = Lines.Get_Next(); + } + CloseFile( F ); + JSONCmd = "{\"command\":\"plotcircuit\",\"path\":\"" + OutputDirectory[ActiveActor] + "GIS_desc.csv\",\"color\":\"" + GISColor + "\",\"thickness\":" + GISThickness + "}"; + // Sends the command to OpenDSS-GIS + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 5000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["plotcircuit"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + } + } + } + else + result = "OpenDSS-GIS is not installed or initialized"; + }*/ + return result; + } + + /* ******************************************************************************* + * Shows the given line on the map * + ******************************************************************************* */ + + + String show_lineGIS( String LineName ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + TLineObj pLine; + if ( IsGISON ) + { + // First have to find the line + if ( ActiveCircuit[ActiveActor] != NULL ) + { + get_line_Coords( LineName ); + InMsg = "{\"command\":\"showline\",\"coords\":{\"long1\":" + floattostr( myCoords[0] ) + ",\"lat1\":" + floattostr( myCoords[1] ) + ",\"long2\":" + floattostr( myCoords[2] ) + ",\"lat2\":" + floattostr( myCoords[3] ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["showline"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Exports the current map view into the models folder * + ******************************************************************************* */ + + + String export_mapGIS( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"exportmap\", \"path\":\"" + OutputDirectory[ActiveActor] + "\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["exportmap"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to return the distances for every * + * step of the last route estimated * + ******************************************************************************* */ + + + String GetRouteSegDistances( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + // to be implemented + if ( ActiveCircuit[ActiveActor] != NULL ) + { + InMsg = "{\"command\":\"getdistances\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["getdistances"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to update the map view to the * + * one given by the user * + ******************************************************************************* */ + + String set_map_View( String myView ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = String( "{\"command\":\"mapview\",\"mymap\":\"" ) + myView + "\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["mapview"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to remove all previous lines/draws from the map * + ******************************************************************************* */ + + + String clear_map( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"clearmap\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["clearmap"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Draws a line in the map at the given coordinates * + ******************************************************************************* */ + + + String Draw_line_GIS( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"drawline\",\"coords\":{\"long1\":" + floattostr( GISCoords[2] ) + ",\"lat1\":" + floattostr( GISCoords[1] ) + ",\"long2\":" + floattostr( GISCoords[4] ) + ",\"lat2\":" + floattostr( GISCoords[3] ) + "},\"color\":\"" + GISColor + "\",\"thickness\":" + + GISThickness + "}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["drawline"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Zooms the map at the area described by the given coordinates * + ******************************************************************************* */ + + + String Zoom_area_GIS( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"zoommap\",\"coords\":{\"long1\":" + floattostr( GISCoords[2] ) + ",\"lat1\":" + floattostr( GISCoords[1] ) + ",\"long2\":" + floattostr( GISCoords[4] ) + ",\"lat2\":" + floattostr( GISCoords[3] ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["zoommap"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * request the calculation of the distance between 2 points * + ******************************************************************************* */ + + + String Get_distance( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"distance\",\"coords\":{\"long1\":" + floattostr( GISCoords[1] ) + ",\"lat1\":" + floattostr( GISCoords[2] ) + ",\"long2\":" + floattostr( GISCoords[3] ) + ",\"lat2\":" + floattostr( GISCoords[4] ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["distance"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to start select mode * + ******************************************************************************* */ + + String GISStartSelect( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"select\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["select"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to start line drawing mode * + ******************************************************************************* */ + + + String GISStartDrawLine( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"drawlines\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["drawlines"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to stop the line drawing mode * + ******************************************************************************* */ + + + String GISStopDrawLine( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"stopdrawlines\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["stopdrawlines"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to stop select mode * + ******************************************************************************* */ + + + String GISStopSelect( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"stopselect\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["stopselect"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * gets the boundaries for the latest selection made in OpenDSS-GIS * + ******************************************************************************* */ + + + String GISGetSelect( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"getselect\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["getselect"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * gets the address at the given coords * + ******************************************************************************* */ + + String GISGetAddress( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"address\",\"coords\":{\"long\":" + floattostr( GISCoords[1] ) + ",\"lat\":" + floattostr( GISCoords[2] ) + "}}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + result = InMsg; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * gets the coords for the latest polyline drawn in OpenDSS-GIS * + ******************************************************************************* */ + + + String GISGetPolyline( ) + { + String result; + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"getpolyline\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 200 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["getpolyline"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to draw the content of a file over the map * + ******************************************************************************* */ + + + String GISPlotfile( String myPath ) + { + String result = "not available"; + String TxtRow, myBus; + int k = 0; +// TTextRec F; + String InMsg, TempStr, JSONCmd; + /* + TdJSON TCPJSON; + if ( ActiveCircuit[ActiveActor] != NULL ) + { + if ( IsGISON ) + { + JSONCmd = String( "{\"command\":\"plotfromfile\",\"path\":\"" ) + myPath + "\"}"; + // Sends the command to OpenDSS-GIS + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 5000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["plotfromfile"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else + result = "OpenDSS-GIS is not installed or initialized"; + }*/ + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to draw the points within a file over the map * + ******************************************************************************* */ + + + String GISPlotPoints( String myPath ) + { + String result = "not available"; + String TxtRow, myBus; + int k = 0; +// TTextRec F; + String InMsg, TempStr, JSONCmd; + /* + TdJSON TCPJSON; + if ( ActiveCircuit[ActiveActor] != NULL ) + { + if ( IsGISON ) + { + JSONCmd = String( "{\"command\":\"plotpoints\",\"path\":\"" ) + myPath + "\"}"; + // Sends the command to OpenDSS-GIS + try + { + GISTCPClient.IOHandler.WriteLn( JSONCmd ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 5000 ); + TCPJSON = TdJSON.Parse( InMsg ); + TempStr = TCPJSON["plotpoints"].AsString; + result = TempStr; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else + result = "OpenDSS-GIS is not installed or initialized"; + }*/ + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to draw a text at specific coordinates * + ******************************************************************************* */ + + + String GISText( String myText ) + { + String result; + /* + TdJSON TCPJSON; + int myShpCode = 0, activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = "{\"command\":\"text\",\"coords\":{\"long\":" + floattostr( GISCoords[1] ) + ",\"lat\":" + floattostr( GISCoords[2] ) + "},\"content\":\"" + myText + "\",\"color\":\"" + GISColor + "\",\"size\":" + GISThickness + "}" + ; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["text"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to draw a text from a file * + ******************************************************************************* */ + + + String GISTextFromFile( String myPath ) + { + String result; + /* + TdJSON TCPJSON; + int myShpCode = 0, activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + InMsg = String( "{\"command\":\"textfromfile\",\"path\":\"" ) + myPath + "\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["textfromfile"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands OpenDSS-GIS to draw a marker at specific coordinates * + ******************************************************************************* */ + + String GISPlotPoint( const String myShape ) + { + String result; + /* + TdJSON TCPJSON; + int myShpCode = 0, activesave = 0, i = 0; + String InMsg; + bool Found = false; + TLineObj pLine; + if ( IsGISON ) + { + switch ( myShape[1] ) + { + case // Parse the shape specified + 'c': + myShpCode = 0; + break; + case '+': + myShpCode = 1; + break; + case 'd': + myShpCode = 2; + break; + case 's': + myShpCode = 3; + break; + case 't': + myShpCode = 4; + break; + case 'x': + myShpCode = 5; + break; + } + InMsg = "{\"command\":\"plotpoint\",\"coords\":{\"long\":" + floattostr( GISCoords[2] ) + ",\"lat\":" + floattostr( GISCoords[1] ) + "},\"color\":\"" + GISColor + "\",\"thickness\":" + GISThickness + ",\"shape\":" + inttostr( myShpCode ) + "}" + ; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["plotpoint"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + } + else*/ + result = "OpenDSS-GIS is not installed or initialized"; + return result; + } + + /* ******************************************************************************* + * Commands openDSS-GIS to convert the coords given in a file into a new format * + ******************************************************************************* */ + + + String GISBatchFormat( const String FormatFrom, const String FormatTo, const String myPath ) + { + String result = "not available"; + /* + int myEnd = 0, myStart = 0; + TdJSON TCPJSON; + String InMsg; + InMsg = String( "{\"command\":\"batchformat\",\"from\":\"" ) + FormatFrom + "\",\"to\":\"" + FormatTo + "\"," + "\"path\":\"" + myPath + "\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + myStart = ansipos( "path\":\"", InMsg ) + 6; + myEnd = ansipos( "\"}", InMsg ) - 1; + result = InMsg.Substring( myStart, myEnd - myStart ); + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + */ + return result; + } + + /* ******************************************************************************* + * Commands openDSS-GIS to convert the coords given into a new format * + ******************************************************************************* */ + + + String GISFormat( const String FormatFrom, const String FormatTo, const String Coords ) + { + String result= "not available"; + /* + TdJSON TCPJSON; + String InMsg; + InMsg = String( "{\"command\":\"format\",\"from\":\"" ) + FormatFrom + "\",\"to\":\"" + FormatTo + "\"," + "\"coords\":\"" + Coords + "\"}"; + try + { + GISTCPClient.IOHandler.WriteLn( InMsg ); + InMsg = GISTCPClient.IOHandler.ReadLn( '\x0a', 1000 ); + TCPJSON = TdJSON.Parse( InMsg ); + result = TCPJSON["coords"].AsString; + } + catch( Exception & E ) + { + { + IsGISON = false; + result = "Error while communicating to OpenDSS-GIS"; + } + } + */ + return result; + } + + /* ******************************************************************************* + * Returns a string with the content of the coordiantes buffer * + ******************************************************************************* */ + + + String GISShowBuffer( ) + { + String result; + int idx = 0; + result = ""; + + for ( int stop = 4, idx = 1; idx <= stop; idx++) + result = result + std::to_string( (GISCoords)[idx] ) + ","; + return result; + } + + /* ******************************************************************************* + * Loads the bus coordiantes into the first 2 places fo the coordiantes buffer * + * shifting it down * + ******************************************************************************* */ + + + String GISLoadBus( const String myBus ) + { + String result; + double myLat = 0.0, myLong = 0.0; + if ( ActiveCircuit[ActiveActor] != NULL ) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + SetActiveBus( StripExtension( myBus ) ); + if ( ( with0->ActiveBusIndex > 0 ) && (with0->ActiveBusIndex <= with0->NumBuses ) ) + { + if (with0->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex - 1]->CoordDefined) + { + myLong = with0->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex - 1]->longitude; + myLat = with0->Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex - 1]->lat; + } + (GISCoords)[3] = (GISCoords)[1]; + (GISCoords)[4] = (GISCoords)[2]; + (GISCoords)[1] = myLat; + (GISCoords)[2] = myLong; + result = "done"; + } + else + result = "Invalid bus name"; + } + } + else + result = "There is no active circuit"; + return result; + } + + /* ******************************************************************************* + * Loads the line Long-lat into the global array "myCoords" * + ******************************************************************************* */ + + + void get_line_Coords( String LineName ) + { + /* + TdJSON TCPJSON; + int activesave = 0, i = 0; + std::vector < String > myBuses; + String S, InMsg; + bool Found = false; + TLineObj pLine; + myCoords.size() = 4; + myBuses.size() = 2; + S = LineName; // Convert to Pascal String + Found = false; + # with ActiveCircuit[ActiveActor]->Lines do + { + activesave = ActiveIndex; + pLine = Get_First(); + while ( pLine != NULL ) + { + if ( CompareText( pLine.Name, S ) == 0 ) + { + ActiveCircuit[ActiveActor]->ActiveCktElement = pLine; + Found = true; + Break; + } + pLine = Get_Next(); + } + } + // Get the names of the buses for the line + # with ActiveCircuit[ActiveActor] do + { + const ActiveCircuit& with0 = ActiveCircuit[ActiveActor]; + { + for ( int stop = 2, i = 1; i <= stop; i++) + { + myBuses[i] = StripExtension( pLine.GetBus( i ) ); + } + + // Get the coords of the buses + for ( int stop = 1, i = 0; i <= stop; i++) + { + SetActiveBus( myBuses[i] ); + if ( ( ActiveBusIndex > 0 ) && ( ActiveBusIndex <= Numbuses ) ) + { + if ( Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].GISCoorddefined ) + { + myCoords[i * 2] = Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].long; + myCoords[i * 2 + 1] = Buses[ActiveCircuit[ActiveActor]->ActiveBusIndex].lat; + } + } + } + } + } + + */ + } + + void DisposeStrings( ) + { + delete[] GISOption; + delete[] GISHelp; + } + + void GISCommands_initialization() + { + DefineOptions(); + GISCommandList = new TCommandList( GISOption, NumGISOptions); + GISCommandList->set_AbbrevAllowed(true); + } + + void GISCommands_finalization() + { + DisposeStrings(); + delete GISCommandList; // GISCommandList->~TCommandList(); + } + + class GISCommands_unit + { + public: + GISCommands_unit() + { + GISCommands_initialization(); + } + ~GISCommands_unit(){ GISCommands_finalization(); } + }; + GISCommands_unit _GISCommands_unit; + +} // namespace GISCommands diff --git a/OpenDSSC/GISCommands/GISCommands.h b/OpenDSSC/GISCommands/GISCommands.h new file mode 100644 index 0000000..e3b9c7d --- /dev/null +++ b/OpenDSSC/GISCommands/GISCommands.h @@ -0,0 +1,91 @@ +#ifndef GISCommandsH +#define GISCommandsH + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSGlobals.h" +#include "djson.h" +#include "Line.h" +#include "Utilities.h" +#include "Arraydef.h" +#include "CmdForms.h" + // TCP Indy libraries +#include "ExecHelper.h" +//#include +//#include +//#include +//#include +//#include "IdThreadComponent.h" +//#include "TCP_IP.h" + +namespace GISCommands +{ + + + + const int NumGISOptions = 37; + String DoGISCmd(); + bool start_openDSSGIS(); + String show_busGIS(String BusName); + String Get_routeGIS(); + String Get_edgesGIS(); + String Get_distanceGIS(); + String Show_routeGIS(); + String Get_JSONrouteGIS(); + String WindowLR(); + String WindowRL(); + String ReSizeWindow(); + String GISDrawCircuit(); + String show_lineGIS(String LineName); + String export_mapGIS(); + String GetRouteSegDistances(); + void get_line_Coords(String LineName); + String set_map_View(String myView); + String clear_map(); + String Draw_line_GIS(); + String Zoom_area_GIS(); + String GISPlotfile(String myPath); + String show_LatLong(); + String GISPlotPoints(String myPath); + String GISPlotPoint(const String myShape); + String GISLoadBus(const String myBus); + String GISShowBuffer(); + String GISFormat(const String FormatFrom, const String FormatTo, const String Coords); + String GISBatchFormat(const String FormatFrom, const String FormatTo, const String myPath); + String GISClose(); + String Get_distance(); + String GISStartSelect(); + String GISStopSelect(); + String GISGetSelect(); + String GISStartDrawLine(); + String GISStopDrawLine(); + String GISGetPolyline(); + String GISGetAddress(); + String GISText(String myText); + String GISTextFromFile(String myPath); + //extern TIdTCPClient GISTCPClient; // ... TIdThreadComponent + + //extern TIdThreadComponent GISThreadComponent; + extern vector< double > myCoords; + extern String* GISOption; + extern String* GISHelp; + extern Command::TCommandList* GISCommandList; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GISCommands; +#endif + +#endif // GISCommandsH + diff --git a/OpenDSSC/GenControls/Exciter/ExcSexs.cpp b/OpenDSSC/GenControls/Exciter/ExcSexs.cpp new file mode 100644 index 0000000..73521bf --- /dev/null +++ b/OpenDSSC/GenControls/Exciter/ExcSexs.cpp @@ -0,0 +1,610 @@ + +#include "System.h" +#include "Sysutils.h" +#include "fstream" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "DSSGlobals.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" +#include "ExcSexs.h" +#include +#include "IntegrationMethods.h" + + +using namespace std; +//using namespace std; // declared twice +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + + +namespace ExcSexs +{ + + TExcSexsObj* ActiveExcSexsObj = nullptr; + const int NumPropsThisClass = 8; // Number of properties in this class + + + void TExcSexs::DefineProperties() + { + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[0] = "bus_name"; + PropertyName[1] = "gen_name"; + PropertyName[2] = "TaOverTb"; + PropertyName[3] = "Tb"; + PropertyName[4] = "K"; + PropertyName[5] = "Te"; + PropertyName[6] = "Emin"; + PropertyName[7] = "Emax"; + + PropertyHelp[0] = "Bus name where the model is connected to"; + PropertyHelp[1] = "Generator name where model is connected to"; + PropertyHelp[2] = "Ratio between time constants Ta and Tb"; + PropertyHelp[3] = "Time constant Tb in seconds"; + PropertyHelp[4] = "Scaler value"; + PropertyHelp[5] = "Time constant Te in seconds"; + PropertyHelp[6] = "Per unit on EFD base"; + PropertyHelp[7] = "Per unit on EFD base"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + int TExcSexs::MakeLike(const String ExcSexsName) + { + int result = 0; + TExcSexsObj* OtherExcSexs = nullptr; + int i = 0; + result = 0; + + /*See if we can find this ExcSexsName in the present collection*/ + OtherExcSexs = ((TExcSexsObj*)Find(ExcSexsName)); + if (OtherExcSexs != nullptr) + { + auto thisobj = ActiveExcSexsObj; + int stop = 0; + thisobj->bus_name = OtherExcSexs->bus_name; + + for (i = 1; i <= thisobj->ParentClass->NumProperties; i++) + { + thisobj->Set_PropertyValue(i, OtherExcSexs->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in ExcSexs MakeLike: \"") + ExcSexsName + + "\" Not Found.", 9001); + return result; + } + + // Constructor and Destructor + TExcSexs::TExcSexs() { + + Class_Name = "ExcSexs"; + DSSClassType = DSSClassType + EXCSEXS_ELEMENT; + DefineProperties(); + CommandList = TCommandList(Slice((PropertyName), NumProperties), NumProperties); + CommandList.set_AbbrevAllowed(true); + + } + + TExcSexs::~TExcSexs() { + + } + + + int TExcSexs::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + int ret = -1; + + // continue parsing WITH contents of Parser + ActiveExcSexsObj = (TExcSexsObj*)ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveExcSexsObj); + result = 0; + + { + auto thisobj = ActiveExcSexsObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + thisobj->Set_PropertyValue(ParamPointer, Param); + switch (ParamPointer) // Ability to make this a search versus hardcoded order? + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + thisobj->get_Name() + + "\"", 9000); + break; + case 1: + thisobj->bus_name = Parser[ActorID]->MakeString_(); + break; + case 2: + thisobj->gen_name = Parser[ActorID]->MakeString_(); + // Try to find generator in generator list + ret = FindGenerator(); + break; + case 3: + thisobj->TaOverTb = Parser[ActorID]->MakeDouble_(); + break; + case 4: + thisobj->Tb = Parser[ActorID]->MakeDouble_(); + break; + case 5: + thisobj->K = Parser[ActorID]->MakeDouble_(); + break; + case 6: + thisobj->Te = Parser[ActorID]->MakeDouble_(); + break; + case 7: + thisobj->Emin = Parser[ActorID]->MakeDouble_(); + break; + case 8: + thisobj->Emax = Parser[ActorID]->MakeDouble_(); + break; + default: + ClassEdit(ActiveExcSexsObj, ParamPointer - NumPropsThisClass); + break; + } + + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + //thisobj->RecalcElementData(ActorID); + + } + + return result; + } + + int TExcSexs::NewObject(const String ObjName) { + + // Make a new ExcSexs model and add it to ExcSexs class list + + int result = 0; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TExcSexsObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + /*if(result) + result = FindGenerator(); + */ + return result; + } + + + // Find the generator then find generator model (as an extra step)???? + + int TExcSexs::FindGenerator() + { + auto thisobj = ActiveExcSexsObj; // For the active ExcSexs model, set a pointer to its generator model + TDSSClass* GenClass = nullptr; + TGeneratorObj* Gen = nullptr; + GenClass = (TDSSClass*)GetDSSClassPtr("generator"); + Gen = (TGeneratorObj*)GenClass->Find(thisobj->gen_name); + if (ASSIGNED(Gen) && ((TDSSCktElement*)Gen)->Get_Enabled()) { // If generator is found and is enabled, then set pointer + Gen->exc_model = thisobj; // C++ will allow this just fine since thisobj is a derived class from T + thisobj->pGen = Gen; // Set this object generator pointer for easy access + if (Gen->exc_model != nullptr) + return 0; + } + else { + // If it gets to this point, generator was either not found, or casting was incorrect, or was not online/enabled + DoSimpleMsg(String("ExcSexs model \"") + thisobj->get_Name() + + "\" could not find generator \"" + thisobj->gen_name + + "\". Generator could be missing or not enabled \"", 9002); + return -1; + } + return -1; + } + + + //--------------------------------------------------------------// + // // + // TExcSexsObj Functions // + // // + //--------------------------------------------------------------// + + + // Default contstuctor for the ExcSexs object + TExcSexsObj::TExcSexsObj() + { + nstates = 2; // number of states contained in the model + nchannels = 5; // TBD by model developer + + // States + ps.reserve(nstates); + s = new double(nstates); + ss = new double(nstates); + ds = new double(nstates); + dss = new double(nstates); + + // Parameters + TaOverTb = 0.0; + Tb = 0.0; + K = 0.0; + Te = 0.0; + Emin = 0.0; + Emax = 0.0; + + // Variables + efd=1.0; + Y=1.0; + U=1.0; + Vs=1.0; + Vref=1.0; + Ec=1.0; + + // Others t + pGen = nullptr; // Pointer to generator associated with instance of the exicter + FListSize = 0; // ???????? + + ibase = 0; + vbase = 0; + mbase = 0; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Constructor + TExcSexsObj::TExcSexsObj(DSSClass::TDSSClass* ParClass, const String ExcSexsName) : + inherited(ParClass) + { + Set_Name(LowerCase(ExcSexsName)); + DSSObjType = ParClass->DSSClassType; + cBuffer.clear(); + + InitPropertyValues(0); + + + // Initialize members + nstates = 2; // number of states contained in the model + nchannels = 5; // Is this used? Value is selected based on? + + // States + s = new double[nstates]; + ss = new double[nstates]; + ds = new double[nstates]; + dss = new double[nstates]; + + // Parameters + TaOverTb = 0.0; + Tb = 0.0; + K = 0.0; + Te = 0.0; + Emin = 0.0; + Emax = 0.0; + + // Variables + efd=1.0; + Y=1.0; + U=1.0; + Vs=1.0; + Vref=1.0; + Ec=1.0; + + // Others + pGen = nullptr; + FListSize = 0; // Needed ? + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Deconstructor, removes state information from the heap + TExcSexsObj::~TExcSexsObj() { + delete[] s; + delete[] ss; + delete[] ds; + delete[] dss; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Specification of deafult parameters. Values here based on typical values listed + // in PSSE PAG + // The function is not called anywhere.....remove from code + //void TExcSexsObj::LoadDefaultParameters() { + // TaOverTb = 0.1; + // Tb = 10.0; + // K = 100.0; + // Te = 0.1; + // Emin = 0.0; + // Emax = 3.0; + //} + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Initialization of the model states + int TExcSexsObj::InitializeStates(int ActorID) + { + + complex vterm; + complex vtermpu; + double vbase = (pGen->GenVars.kVGeneratorBase * 1000 / SQRT3); // Voltage base LL in Volts + + // Check whether the "this->"is needed and where throughout this method + + // For validation + stepCount = 0; + + + if (pGen->GenON) + { + + //Get field voltage (EDF) from the generator model + this->efd = this->pGen->gen_model->get_efield(); + + // Initialize first order lag block + this->s[1] = this->efd; + this->ss[1] = this->s[1]; + this->ds[1] = 0.0; + + //Check for initialization of values beyond control limits + if (this->efd > Emax) { + DoSimpleMsg(String("Initialization error of SEXS at generator \"") + this->gen_name + + "\". EFD > Emax \"", 9005); // meaning behind the error number?? + return -1; // return negative value to main function call to stop initialization process? + }else if (this->efd < Emin){ + DoSimpleMsg(String("Initialization error of SEXS at generator \"") + this->gen_name + + "\". EFD < Emin \"", 9005); // meaning behind the error number?? + return -1; + }else{} + + Y = this->s[1] / K; + + // Initialize Lead-lag block + this->s[0] = (1 - TaOverTb) * Y; + this->ss[0] = this->s[0]; + this->ds[0] = 0.0; + + // U = Y, no need to compute in the initialization + + //Compute the terminal voltage in per-unit + vterm = pGen->GetVterminal(ActorID); // Positive sequence voltage - LN + vtermpu = cdivreal(vterm, vbase); + + + // Assume no regulator or stabilizer + Ec = cabs(vtermpu); //Per-unit terminal voltage magnitude + Vs = 0; // assume no stabilizers initial + this->Vref = Y + Ec - Vs; + + + } + else { + DoSimpleMsg(Format(("Generator " + pGen->get_Name() + " is offline.").c_str()), 9004); + return -1; + } + + return 0; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Update state derivatives at each timestep + // ---- Intentionally did not use the explicit this-> in the specifications to determine whether required. + int TExcSexsObj::CalculateRate(int ActorID) + { + complex vterm; + complex vtermpu; + double vbase = (pGen->GenVars.kVGeneratorBase * 1000 / SQRT3); // Voltage base LL in Volts + + // Hard Coding for Validation // + int trigger = 1000; + int trigger2 = 11000; + double Vref_inc = 0.1; + stepCount = stepCount + 1; + if (stepCount == trigger) { + //this->Vref = 1.06;// Case 6 + //this->Vref = 2.00;// Case 7 + //this->Vref = 0.98;// Case 8 + //this->Vref = -2.0;// Case 9 and 10 + } + if (stepCount == trigger2) { + //this->Vref = 2.00;// Case 10 + } + + //Compute the terminal voltage in per-unit + vterm = pGen->GetVterminal(ActorID); // Positive sequence voltage - LN + vtermpu = cdivreal(vterm, vbase); + Ec = cabs(vtermpu); + U = this->Vref - Ec + Vs; // confirm Vs remains at zero + + Y = s[0] + TaOverTb * U; + ds[0] = (U - Y) / Tb; + + + if (s[1] > Emax) { + s[1] = Emax; + ds[1] = (Y * K - s[1]) / Te; + if (ds[1] > 0) { + ds[1] = 0; + } + } + else if (s[1] < Emin) { + s[1] = Emin; + ds[1] = (Y * K - s[1]) / Te; + if (ds[1] < 0) { + ds[1] = 0; + } + } + else { + ds[1] = (Y * K - s[1]) / Te; + } + + this->efd = s[1]; + return 0; + } + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + int TExcSexsObj::StateIntegration(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // Here we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::ab2order(this, &h); + + return 0; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + int TExcSexsObj::StateIntegration_correction(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // HEre we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::euler(this, &h); + // IntegrationMethods::ab2order(this, &h); + + //this->nstates; + return 0; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //Provide variables to monitor + double TExcSexsObj::get_channel(int i) + + { + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if (i < 1) + return result; // Someone goofed + switch (i) { + case 1: + result = this->efd; // Efd + break; + case 2: + result = this->s[0]; // lead-lag transfer function state + break; + case 3: + result = this->Vref; // Vref + break; + case 4: + result = this->Ec; // Ec + break; + case 5: + result = this->Vs; // Vs + break; + default: + break; + } + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //Provides headers for the monitor output file + String TExcSexsObj::get_channel_header(int i) + { + String result; + switch (i) { + case 1: + result = " Efd(pu)"; + break; + case 2: + result = " lead-lag-state"; + break; + case 3: + result = " Vref(pu)"; + break; + case 4: + result = " Ec(pu)"; + break; + case 5: + result = " Vs(pu)"; + break; + default: + break; + } + return result; + } + + int64_t TExcSexsObj::get_number_channels() + { + return nchannels; + } + + + + void TExcSexsObj::sample(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TExcSexsObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TExcSexsObj::Reset(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TExcSexsObj::InitPropertyValues(int ArrayOffset) { + Set_PropertyValue(1,""); // bus_name; + Set_PropertyValue(2,""); // gen_name; + Set_PropertyValue(3,"0.1"); // TaOverTb; + Set_PropertyValue(4,"10.0"); // Tb + Set_PropertyValue(5,"100.0"); // K; + Set_PropertyValue(6,"0.1"); // Te; + Set_PropertyValue(7,"0.0"); // Emin; + Set_PropertyValue(8,"3.0"); // Emax; + inherited::InitPropertyValues(NumPropsThisClass); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + //Provides calculated efield, primarily when requested from gen_model + //during the dynamic simulation + double TExcSexsObj::get_efield() + { + return this->efd; + } + + + /* + void TExcSexsObj::DumpProperties(System::TTextRec& f, bool Complete) { + + } + */ +} \ No newline at end of file diff --git a/OpenDSSC/GenControls/Exciter/ExcSexs.h b/OpenDSSC/GenControls/Exciter/ExcSexs.h new file mode 100644 index 0000000..003c653 --- /dev/null +++ b/OpenDSSC/GenControls/Exciter/ExcSexs.h @@ -0,0 +1,150 @@ +#ifndef EXCSEXS_H +#define EXCSEXS_H + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "Bus.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" + + + +using namespace std; + +namespace ExcSexs +{ + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + /* + Change Log + 11/15/2022 - J. Taylor + + */ + + /* + The SEXS model represents a simplified excitation system. + + It can be invoked as follows in the input file: + + New ExcSexs.Name=myname generator=Generator.name terminal=[ 1|2|...] Parameter_List + // need to revise the call in order to ensure the connection to the generator is correct + // need to define the exciter, than the type of exciter --- precidence in opendSS??? + + The generator model must already exist in the case. + */ + + + + + + + class TExcSexs : public ControlClass::TControlClass { + friend class TExcSexsObj; + public: + typedef ControlClass::TControlClass inherited; + private: + + protected: + void DefineProperties(); + int MakeLike(const String ExcSexsName); + public: + TExcSexs(); + virtual ~TExcSexs(); + int Edit(int ActorID); // uses global parser + int NewObject(const String ObjName); + int FindGenerator(); + + }; + + class TExcSexsObj : public ControlElem::TControlElem { + public: + typedef ControlElem::TControlElem inherited; + + + public: //---Why are these variables not declared as private?? + int64_t nstates; + int64_t nchannels; + + // Pointers to states, stored states and state derivatives + double* s, * ss, * ds, * dss; + vector ps; + + // Parameters + double TaOverTb; // Ratio of Ta and Tb, this parameter definition follows formulation in PSSE + double Tb; // must be greater than zero, units in seconds + double K; // + double Te; // units in seconds + double Emin; // + double Emax; // + + // Variables + double efd; + double Y; + double U; + double Vs; + double Vref; + double Ec; + + //Miscellaneous - Remove after validation + int stepCount; + + // Bases + double vbase, mbase, ibase; + + int FListSize; + String gen_name; // Name of generator the model is connected to + String bus_name; // Name of bus where the model is connected to + Generator::TGeneratorObj* pGen; // Pointer to controlled generator + std::vector cBuffer; // Complexarray buffer + + + public: + TExcSexsObj(DSSClass::TDSSClass* ParClass, const String ExcSexsName); + TExcSexsObj(); + virtual ~TExcSexsObj(); + + void sample(int ActorID); // Sample control quantities and set action times in Control Queue + void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + void Reset(int ActorID); // Reset to initial defined state + + void InitPropertyValues(int ArrayOffset); + + void LoadDefaultParameters(); + + virtual int InitializeStates(int ActorID); + virtual int CalculateRate(int ActorID); + virtual int StateIntegration(int ActorID); + virtual int StateIntegration_correction(int ActorID); +// virtual complex* CalculateIsorce(int ActorID, complex* I012); + //virtual complex GetIsorce1(int ActorID); + //virtual complex GetIsorce2(int ActorID); + virtual double get_channel(int channel_num); + virtual String get_channel_header(int channel_num); + virtual int64_t get_number_channels(); + virtual double get_efield(); // Returns calculated efield + + + }; + + extern TExcSexsObj* ActiveExcSexsObj; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ExcSexs; +#endif + +#endif // !ExcSexs_H diff --git a/OpenDSSC/GenControls/Governor/tgov.cpp b/OpenDSSC/GenControls/Governor/tgov.cpp new file mode 100644 index 0000000..6025416 --- /dev/null +++ b/OpenDSSC/GenControls/Governor/tgov.cpp @@ -0,0 +1,598 @@ + +#include "System.h" +#include "Sysutils.h" +#include "fstream" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "DSSGlobals.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" +//#include "gencls.h" // May not need this +//#include "genrou.h" +#include "tgov.h" +#include +#include "IntegrationMethods.h" + +using namespace std; +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + + +namespace Tgov +{ + + TTgovObj* ActiveTgovObj = nullptr; + const int NumPropsThisClass = 9; // Number of properties in this class + + void TTgov::DefineProperties() + { + NumProperties = NumPropsThisClass; // Parameter comes from DSSClass:TDSSClass + CountProperties(); // Adds one to the NumProperties variable within DSSClass.cpp + AllocatePropertyArrays(); // Adds one more column to property arrays (PropertyName, PropertyHelp, PropertyIdxMap) From DSSClass.cpp + + + // Define Property names + //PropertyName[0] = "bus_name"; + PropertyName[0] = "bus_name"; + PropertyName[1] = "gen_name"; + PropertyName[2] = "R"; + PropertyName[3] = "Dt"; + PropertyName[4] = "T1"; + PropertyName[5] = "T2"; + PropertyName[6] = "T3"; + PropertyName[7] = "Vmax"; + PropertyName[8] = "Vmin"; + + PropertyHelp[0] = "Bus name where the generator model is connected to"; + PropertyHelp[1] = "Generator name where the model is connected to"; + PropertyHelp[2] = "Turbine governor droop (pu)"; + PropertyHelp[3] = "Turbine damping coefficient (pu)"; + PropertyHelp[4] = "Time constant for steam control valve (T1>0) (sec)"; + PropertyHelp[5] = "Lead/Lag Time Constant (sec)"; + PropertyHelp[6] = "Time constant for reheat (T3>0) (sec)"; + PropertyHelp[7] = "Maximum valve position (pu)"; + PropertyHelp[8] = "Minimum valve position (pu)"; + + + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + int TTgov::MakeLike(const String TgovName) + { + int result = 0; + TTgovObj* OtherTgov = nullptr; + int i = 0; + result = 0; + + /*See if we can find this TgovName in the present collection*/ + OtherTgov = ((TTgovObj*)Find(TgovName)); + if (OtherTgov != nullptr) + { + auto thisobj = ActiveTgovObj; + int stop = 0; + thisobj->bus_name = OtherTgov->bus_name; + + for (i = 1; i <= thisobj->ParentClass->NumProperties; i++) + { + thisobj->Set_PropertyValue(i,OtherTgov->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Tgov MakeLike: \"") + TgovName + + "\" Not Found.", 9001); + return result; + } + + // Constructor // + TTgov::TTgov() + { + Class_Name = "Tgov"; + DSSClassType = DSSClassType + TGOV_ELEMENT; //Linked to DSSClassDefs.h (using 47) + DefineProperties(); + CommandList = TCommandList(Slice((PropertyName), NumProperties), NumProperties); + CommandList.set_AbbrevAllowed(true); + } + + // Destructor // + TTgov::~TTgov() + { + // ENTER CODE HERE // + } + + // Parser // + int TTgov::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + int ret = -1; + + // Continue parsing WITH contents of Parser + ActiveTgovObj = (TTgovObj*)ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveTgovObj); + result = 0; + + { + auto thisobj = ActiveTgovObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + thisobj->Set_PropertyValue(ParamPointer,Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + thisobj->get_Name() + + "\"", 9000); + break; + case 1: + thisobj->bus_name = Parser[ActorID]->MakeString_(); + break; + case 2: + thisobj->gen_name = Parser[ActorID]->MakeString_(); + // Try to find generator in generator list + ret = FindGenerator(); + break; + case 3: + thisobj->R = Parser[ActorID]->MakeDouble_(); + break; + case 4: + thisobj->Dt = Parser[ActorID]->MakeDouble_(); + break; + case 5: + thisobj->T1 = Parser[ActorID]->MakeDouble_(); + break; + case 6: + thisobj->T2 = Parser[ActorID]->MakeDouble_(); + break; + case 7: + thisobj->T3 = Parser[ActorID]->MakeDouble_(); + break; + case 8: + thisobj->Vmax = Parser[ActorID]->MakeDouble_(); + break; + case 9: + thisobj->Vmin = Parser[ActorID]->MakeDouble_(); + break; + default: + ClassEdit(ActiveTgovObj, ParamPointer - NumPropsThisClass); + break; + } + + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + //thisobj->RecalcElementData(ActorID); + } + return result; + } + + // Make New Tgov model and add to Tgov class list // + int TTgov::NewObject(const String ObjName) + { + int result = 0; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TTgovObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + /*if(result) + result = FindGenerator(); + */ + return result; + } + + int TTgov::FindGenerator() + { + auto thisobj = ActiveTgovObj; // For the active Tgov model, set a pointer to its generator model + TDSSClass* GenClass = nullptr; // Create a Class called GenClass + TGeneratorObj* Gen = nullptr; // Create a Generator Object called Gen + GenClass = (TDSSClass*)GetDSSClassPtr("generator"); + Gen = (TGeneratorObj*)GenClass->Find(thisobj->gen_name); + if (ASSIGNED(Gen) && ((TDSSCktElement*)Gen)->Get_Enabled()) { // If generator is found and is enabled, then set pointer + Gen->turb_model = thisobj; // C++ will allow this just fine since thisobj is a derived class from T + thisobj->pGen = Gen; // Set this object generator pointer for easy access + if (Gen->turb_model != nullptr) + return 0; + } + else { + // If it gets to this point, generator was either not found, or casting was incorrect, or was not online/enabled + DoSimpleMsg(String("Tgov model \"") + thisobj->get_Name() + + "\" could not find generator \"" + thisobj->gen_name + + "\". Generator could be missing or not enabled \"", 9002); + return -1; + } + return -1; + } + + // Determine if we need to determine that a generator model with the input PMech exists. + + + //--------------------------------------------------------------// + // // + // TTgovObj Functions // + // // + //--------------------------------------------------------------// + + + // THIS CONSTRUCTOR IS USED ONLY DURING TESTING + //TTgovObj::TTgovObj() : + // ibase(1.0), + // mbase(1.0), + // vbase(1.0) //, + + //{ + // nstates = 2; // X1 and X2 + // nchannels = 6; // WHAT IS THIS + // // States + // ps.reserve(nstates); // Is this for allocating memory + // s = new double(nstates); + // ss = new double(nstates); + // ds = new double(nstates); + // dss = new double(nstates); + // // Parameters + // Pmref = 0.0; + // R = 0.0; + // Dt = 0.0; + // T1 = 0.0; + // T2 = 0.0; + // T3 = 0.0; + // Vmin = 0.0; + // Vmax = 0.0; + // // Variables + // pmech = 0.; + // dspd = 0.0; + // // Others + // pGen = nullptr; + // FListSize = 0; + //} + + TTgovObj::TTgovObj(DSSClass::TDSSClass* ParClass, const String TgovName) : + inherited(ParClass) + { + Set_Name(LowerCase(TgovName)); + DSSObjType = ParClass->DSSClassType; + cBuffer.clear(); + + InitPropertyValues(0); + + // Initialize members + nstates = 2; + nchannels = 5; // This is the number of channels which will be monitored for Tgov + + // States + s = new double[nstates]; + ss = new double[nstates]; + ds = new double[nstates]; + dss = new double[nstates]; + + // Parameters + R = 0.0; + Dt = 0.0; + T1 = 0.0; + T2 = 0.0; + T3 = 0.0; + Vmin = 0.0; + Vmax = 0.0; + + // Variables + pmech = 0.; + dspd = 0.0; + Y = 1.0; + U = 1.0; + + // Others + pGen = nullptr; + //FListSize = 0; + } + + //------------------------------------------------------------ + // Deconstructor // + TTgovObj::~TTgovObj() + { + delete[] s; + delete[] ss; + delete[] ds; + delete[] dss; + } + + //------------------------------------------------------------ + // Default Parameters // + void TTgovObj::LoadDefaultParameters() + { + // These are the default parameters for this model + R = 0.05; + Dt = 0.0; + T1 = 0.5; + T2 = 3.0; + T3 = 10.0; + Vmin = 0.0; + Vmax = 1.0; + } + + //------------------------------------------------------------ + // Initialization of the model states // + int TTgovObj::InitializeStates(int ActorID) + { + // Get generator terminal current and terminal voltage + + /*VNeut,*/ + int i = 0; + + // Get voltage and MVA bases for generator. All generator variables and parameters will be in pu and these are the bases used to + double mbase = pGen->GenVars.kVArating * 1000; // MVA base of generator, in VA + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if (pGen->GenON) + { + // Get pmech and dspd from generator model + this->pmech = this->pGen->gen_model->get_pmech(); + this->dspd = this->pGen->gen_model->get_dspd(); + + + + //calculate staste 1 before anti-windup + Y = this->pmech + this->dspd * Dt; + + // Make sure the Y value is within limits + if (Y > Vmax) + { + Y = Vmax; + DoSimpleMsg(string("Vmax exceeded during intitialization of generator") + gen_name, 9005); + } + else if (Y < Vmin) + { + Y = Vmin; + DoSimpleMsg(string("Vmin exceeded during intitialization of generator") + gen_name, 9005); + } + + // Initialize first order lead/lag block + this->s[1] = Y * (1 - T2 / T3); + this->ss[1] = s[1]; + ds[1] = 0; + + + // Initialize first order low-pass filter + this->s[0] = Y; + this->ss[0] = s[0]; + this->ds[0] = 0.0; + + // Caluculate pmref + this->pmref = R * this->pmech + this->dspd * (1 + R * Dt); + this->pmref = this->pmref; + } + else { + DoSimpleMsg(Format(("Generator " + pGen->get_Name() + " is offline.").c_str()), 9004); + return -1; + } + + //int ret = call_iterative_solver(); + + return 0; + } + + //------------------------------------------------------------ + // Calculate of the model states // + int TTgovObj::CalculateRate(int ActorID) + { + // Hard Coding for Validation // + int trigger = 1000; + int trigger2 = 11000; + stepCount = stepCount + 1; + if (stepCount == trigger) { + //this->pmref = 0.05;// Case 6 + //this->pmref = 0.10;// Case 7 + //this->pmref = 0.04;// Case 8 + //this->pmref = -0.1;// Case 9 and 10 + } + if (stepCount == trigger2) { + //this->pmref = 0.10;// Case 10 + } + + + + // Get the speed deviation of the generator model + this->dspd = this->pGen->gen_model->get_dspd(); + + U = (this -> pmref - this->dspd) / R; + // Anti-Windup + if (s[0] > Vmax) + { + s[0] = Vmax; + ds[0] = (U - s[0]) / T1; + if (ds[0] > 0) + { + ds[0] = 0; + } + } + else if (s[0] < Vmin) + { + s[0] = Vmin; + ds[0] = (U - s[0]) / T1; + if (ds[0] < 0) + { + ds[0] = 0; + } + } + else + { + ds[0] = (U - s[0]) / T1; + } + + Y = s[1] + s[0]*(T2 / T3); + ds[1] = (s[0] -Y ) / T3; + this->pmech = Y + this->dspd * Dt; + + return 0; + } + + //------------------------------------------------------------ + // Integration Method // + int TTgovObj::StateIntegration(int ActorID) + { + //// Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + //// HEre we are calling Adams-Bashforth second order. + //// Other methods can be implemented and each model can call a specific method. + //// That is the beauty of this modular implementation + //// IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::ab2order(this, &h); + //// IntegrationMethods::euler(this, &h); + + ////this->nstates; + return 0; + } + + //------------------------------------------------------------ + // Integration Correction // + int TTgovObj::StateIntegration_correction(int ActorID) + { + //// Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + //// HEre we are calling Adams-Bashforth second order. + //// Other methods can be implemented and each model can call a specific method. + //// That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::euler(this, &h); + //// IntegrationMethods::ab2order(this, &h); + + ////this->nstates; + return 0; + } + + + //------------------------------------------------------------ + // Send channels to monitor // + double TTgovObj::get_channel(int i) + { + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if (i < 1) + return result; // Someone goofed + switch (i) { + case 1: + result = this->pmech; // Mechanical Power (pu) + break; + case 2: + result = this->s[1]; // first order lead-lag state + break; + case 3: + result = this->s[0]; // first order low pass filter state + break; + case 4: + result = this->dspd; // Speed Deviation + break; + case 5: + result = this->pmref; + break; + default: + break; + } + return result; + } + + //------------------------------------------------------------ + // Provide headers for channels to monitor // + String TTgovObj::get_channel_header(int i) + { + String result; + switch (i) { + case 1: + result = " GOV_Pmech(pu)"; + break; + case 2: + result = " GOV_lead-lag-state"; + break; + case 3: + result = " GOV_lowpass-state"; + break; + case 4: + result = " GOV_speed_deviation"; + break; + case 5: + result = " Reference Variable"; + break; + default: + break; + } + return result; + } + + int64_t TTgovObj::get_number_channels() + { + return nchannels; + } + + void TTgovObj::sample(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TTgovObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TTgovObj::Reset(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TTgovObj::InitPropertyValues(int ArrayOffset) { + Set_PropertyValue(1,""); // bus_name + Set_PropertyValue(2,""); // gen_name + Set_PropertyValue(3,"0.05"); // R + Set_PropertyValue(4,"0.0"); // Dt + Set_PropertyValue(5,"0.5"); // T1 + Set_PropertyValue(6,"3.0"); // T2 + Set_PropertyValue(7,"10.0"); // T3 + Set_PropertyValue(8,"1.0"); // Vmax + Set_PropertyValue(9,"0.0"); // Vmin + inherited::InitPropertyValues(NumPropsThisClass); + } + + // Provides calculated pmech when requested from gen_model + double TTgovObj::get_pmech() + { + return this->pmech; + } + + + /* void TTgovObj::DumpProperties(System::TTextRec& f, bool Complete) { + + }*/ +} \ No newline at end of file diff --git a/OpenDSSC/GenControls/Governor/tgov.h b/OpenDSSC/GenControls/Governor/tgov.h new file mode 100644 index 0000000..bb5a196 --- /dev/null +++ b/OpenDSSC/GenControls/Governor/tgov.h @@ -0,0 +1,138 @@ +#ifndef TGOV_H +#define TGOV_H + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" // May not need this +#include "Bus.h" // May not need this +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" + +using namespace std; + +namespace Tgov // Create a namespace so similar functions from others namespaces will not be crosswired +{ + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + /* + Change Log + 11/17/2022 - B. Schenkman - created class + + */ + + /* + A Tgov is a class that represents a simple steam turbine governor. + + It can be invoked as follows in the input file: + + New Tgov.Name=myname generator=Generator.name terminal=[ 1|2|...] Parameter_List + + Controlled generator must already exist in the case. + */ + + // TTgov Class + class TTgov : public ControlClass::TControlClass // Create class TTgov and pull in the TControlClass from ControlClass namespace + { // + friend class TTgovObj; + public: + typedef ControlClass::TControlClass inherited; // inherited becomes the ControlClass::TControlClass (Why is this here?) + private: + + protected: + void DefineProperties(); // Define the properties of the model in tgov.cpp + int MakeLike(const String TgovName); // Creates a new Tgov object if none other exists + public: + TTgov(); // Constructor to be performed when the TTGov class is called (initialization) + virtual ~TTgov(); // Destructor to be performed when TTGov class is called (initialization) + int Edit(int ActorID); // uses global parser + int NewObject(const String ObjName); // Create Tgov model in Tgov class + int FindGenerator(); // Find the generator where Tgov model is tied to + + }; + + // TTgovObj Class + class TTgovObj : public ControlElem::TControlElem + { + public: + typedef ControlElem::TControlElem inherited; // Sets inherited as ControlElem::TControlElem + public: + int64_t nstates; + int64_t nchannels; + // States, stored states and state derivatives + double *s, *ss, *ds, *dss; + vector ps; + // Parameters + double R; + double Dt; + double T1; + double T2; + double T3; + double Vmax; + double Vmin; + // Variables + double pmech; // mechanical power output in pu + double pmref; // mechanical power reference + double dspd; // speed deviation from generator + double Y; + double U; + + //Miscellaneous - Remove after validation + int stepCount=0; + + // Bases + double vbase, mbase, ibase; + + int FListSize; + String gen_name; // Name of generator model is connected to + String bus_name; // Name of bus where model is connected to + Generator::TGeneratorObj* pGen; // Pointer to controlled generator + std::vector cBuffer; // Complexarray buffer + + + public: + TTgovObj(DSSClass::TDSSClass* ParClass, const String TgovName); + //TTgovObj(); + virtual ~TTgovObj(); + void sample(int ActorID); // Sample control quantities and set action times in Control Queue + void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + void Reset(int ActorID); // Reset to initial defined state + void InitPropertyValues(int ArrayOffset); // Initialize property values + void LoadDefaultParameters(); // Loads default model parameters + virtual int InitializeStates(int ActorID); // Initializes values of states based on steady state power flow solution + virtual int CalculateRate(int ActorID); // Calculate state derivatives prior to integration + virtual int StateIntegration(int ActorID); // Calls method to integrate states + virtual int StateIntegration_correction(int ActorID); // Calls method to integrate states when predictor corrector method is used + //virtual complex* CalculateIsorce(int ActorID, complex* I012); // Calculates current injections from model for network solution + //virtual complex GetIsorce1(int ActorID); // Get positive sequence current + //virtual complex GetIsorce2(int ActorID); // Get negative sequence current + virtual double get_channel(int channel_num); // Gets channel values from model + virtual String get_channel_header(int channel_num); // Gets channel header names in model + virtual int64_t get_number_channels(); // Gets number of channels in model + virtual double get_pmech(); + //virtual double get_dspd(); + // Implements Newton-Raphson to initialize model + + + + }; + + extern TTgovObj* ActiveTgovObj; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Tgov; +#endif + +#endif // !TGOV_H diff --git a/OpenDSSC/GenModels/gencls.cpp b/OpenDSSC/GenModels/gencls.cpp new file mode 100644 index 0000000..aaf8e8a --- /dev/null +++ b/OpenDSSC/GenModels/gencls.cpp @@ -0,0 +1,710 @@ + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "DSSGlobals.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" +#include "gencls.h" +#include +#include "IntegrationMethods.h" + + +using namespace std; +using namespace std; +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + + +namespace Gencls +{ + + TGenclsObj* ActiveGenclsObj = nullptr; + const int NumPropsThisClass = 4; // Number of properties in this class + + void TGencls::DefineProperties() + { + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[0] = "bus_name"; + PropertyName[1] = "gen_name"; + PropertyName[2] = "h"; + PropertyName[3] = "d"; + PropertyHelp[0] = "Bus name where the model is connected to"; + PropertyHelp[1] = "Generator name where model is connected to"; + PropertyHelp[2] = "Inertia constant"; + PropertyHelp[3] = "Damping constant"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + int TGencls::MakeLike(const String GenclsName) + { + int result = 0; + TGenclsObj* OtherGencls = nullptr; + int i = 0; + result = 0; + /*See if we can find this GenclsName in the present collection*/ + OtherGencls = ((TGenclsObj*)Find(GenclsName)); + if (OtherGencls != nullptr) + { + auto thisobj = ActiveGenclsObj; + int stop = 0; + thisobj->bus_name = OtherGencls->bus_name; + + for (i = 1; i <= thisobj->ParentClass->NumProperties; i++) + { + thisobj->Set_PropertyValue(i,OtherGencls->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Gencls MakeLike: \"") + GenclsName + + "\" Not Found.", 9001); + return result; + } + // Constructor and Destructor + TGencls::TGencls() { + + Class_Name = "Gencls"; + DSSClassType = DSSClassType + GENCLS_ELEMENT; + DefineProperties(); + CommandList = TCommandList(Slice((PropertyName), NumProperties), NumProperties); + CommandList.set_AbbrevAllowed(true); + + } + + TGencls::~TGencls() { + + } + + + int TGencls::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + int ret = -1; + + // continue parsing WITH contents of Parser + ActiveGenclsObj = (TGenclsObj*)ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGenclsObj); + result = 0; + + { + auto thisobj = ActiveGenclsObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + thisobj->Set_PropertyValue(ParamPointer,Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + thisobj->get_Name() + + "\"", 9000); + break; + case 1: + thisobj->bus_name = Parser[ActorID]->MakeString_(); + break; + case 2: + thisobj->gen_name = Parser[ActorID]->MakeString_(); + // Try to find generator in generator list + ret = FindGenerator(); + break; + case 3: + thisobj->h = Parser[ActorID]->MakeDouble_(); + break; + case 4: + thisobj->d = Parser[ActorID]->MakeDouble_(); + break; + default: + ClassEdit(ActiveGenclsObj, ParamPointer - NumPropsThisClass); + break; + } + + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + //thisobj->RecalcElementData(ActorID); + + } + + return result; + } + + int TGencls::NewObject(const String ObjName) { + + // Make a new Gencls model and add it to Gencls class list + + int result = 0; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGenclsObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + /*if(result) + result = FindGenerator(); + */ + return result; + } + + int TGencls::FindGenerator() + { + auto thisobj = ActiveGenclsObj; // For the active gencls model, set a pointer to its generator model + TDSSClass* GenClass = nullptr; + TGeneratorObj* Gen = nullptr; + GenClass = (TDSSClass*)GetDSSClassPtr("generator"); + Gen = (TGeneratorObj*)GenClass->Find(thisobj->gen_name); + if (ASSIGNED(Gen) && ((TDSSCktElement*)Gen)->Get_Enabled()) { // If generator is found and is enabled, then set pointer + Gen->gen_model = thisobj; // C++ will allow this just fine since thisobj is a derived class from T + thisobj->pGen = Gen; // Set this object generator pointer for easy access + if (Gen->gen_model != nullptr) + return 0; + } + else { + // If it gets to this point, generator was either not found, or casting was incorrect, or was not online/enabled + DoSimpleMsg(String("Gencls model \"") + thisobj->get_Name() + + "\" could not find generator \"" + thisobj->gen_name + + "\". Generator could be missing or not enabled \"", 9002); + return -1; + } + return -1; + } + + + //--------------------------------------------------------------// + // // + // TGenclsObj Functions // + // // + //--------------------------------------------------------------// + + + + TGenclsObj::TGenclsObj() : + ibase(1.0), + mbase(1.0), + vbase(1.0), + isorce{ 1.0, 1.0 }, + isorcepu{ 1.0,1.0 }, + isorce2{ 1.0,1.0 }, + isorce2pu{ 1.0,1.0 }, + iterminit{ 1.0,1.0 }, + vsorce{ 1.0,1.0 }, + vsorcepu{ 1.0,1.0 }, + zsorce{ 1.0,1.0 }, + zsorcepu{ 1.0,1.0 } + { + nstates = 2; + nchannels = 6; + // States + ps.reserve(nstates); + s = new double(nstates); + ss = new double(nstates); + ds = new double(nstates); + dss = new double(nstates); + // Parameters + h = 0.0; + d = 0.0; + // Variables + pmech = 0.; + pgen = 0.; + qgen = 0.; + tm = 0.; + te = 0.; + dspd = 0.0; + ang = 0.0; + spd = 0.0; + w0 = 0.0; + ed = 0.0; + eq = 0.0; + id = 0.0; + iq = 0.0; + // Others + pGen = nullptr; + FListSize = 0; + } + + TGenclsObj::TGenclsObj(DSSClass::TDSSClass* ParClass, const String GenclsName) : + inherited(ParClass), + ibase(1.0), + mbase(1.0), + vbase(1.0), + isorce{ 1.0, 1.0 }, + isorcepu{ 1.0,1.0 }, + isorce2{ 1.0,1.0 }, + isorce2pu{ 1.0,1.0 }, + iterminit{ 1.0,1.0 }, + vsorce{ 1.0,1.0 }, + vsorcepu{ 1.0,1.0 }, + zsorce{ 1.0,1.0 }, + zsorcepu{ 1.0,1.0 } + { + Set_Name(LowerCase(GenclsName)); + DSSObjType = ParClass->DSSClassType; + cBuffer.clear(); + //{ + // auto thisobj = ActiveGenclsObj; + // thisobj->bus_name = "none"; + // thisobj->gen_name = "none"; + // thisobj->h = 2.0; + // thisobj->d = 1.0; + //} + InitPropertyValues(0); + + // RecalcElementData; + + // Initialize members + nstates = 2; + nchannels = 6; + // States + s = new double[nstates]; + ss = new double[nstates]; + ds = new double[nstates]; + dss = new double[nstates]; + // Parameters + h = 0.0; + d = 0.0; + // Variables + pmech = 0.; + pgen = 0.; + qgen = 0.; + tm = 0.; + te = 0.; + dspd = 0.0; + ang = 0.0; + spd = 0.0; + w0 = 0.0; + ed = 0.0; + eq = 0.0; + id = 0.0; + iq = 0.0; + // Others + pGen = nullptr; + FListSize = 0; + } + + + + + TGenclsObj::~TGenclsObj() { + delete[] s; + delete[] ss; + delete[] ds; + delete[] dss; + } + + void TGenclsObj::LoadDefaultParameters() { + // These are the deafault parameters for this model + h = 3.0; + d = 0.0; + } + + int TGenclsObj::InitializeStates(int ActorID) + { + // Get generator terminal current and terminal voltage + + /*VNeut,*/ + int i = 0; + complex V012[3/*# range 0..2*/]{ 0.0,0.0,0.0,0.0,0.0,0.0 }; + complex I012[3/*# range 0..2*/]{ 0.0,0.0,0.0,0.0,0.0,0.0 }; + complex Vabc[4/*# range 1..3*/]{ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 }; + complex vterm; // Terminal voltage in V and abc ref frame + complex iterm{ 0.0,0.0 }, itermpu{ 0.0,0.0 }; // Terminal current in A and abc ref frame + complex sgen; + complex Edq; + complex Idq; // Terminal current in dq reference frame + //double ed, eq; // Source voltages in dq reference frame + + + + // Get voltage and MVA bases for generator. All generator variables and parameters will be in pu and these are the bases used to + double vbase = pGen->GenVars.kVGeneratorBase * 1000; // Voltage base LL in Volts + double mbase = pGen->GenVars.kVArating * 1000; // MVA base of generator, in VA + double ibase = mbase / (sqrt(3) * vbase); // Ibase in A for current pu-nitization + double zbase = vbase * vbase / mbase; // Impedance base in Ohms + pGen->Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims on the generator + + // This stuff will have to come from the new generator models, so should come from gencls, genrou, etc + auto& thisgen = pGen->GenVars; + thisgen.Zthev = cmplx(thisgen.Xdp / thisgen.XRdp, thisgen.Xdp); // Set Zthevenin based on Xdp and XRdp, where XRdp = Xdp/Rdp + + pGen->Yeq = cinv(thisgen.Zthev); // Rebuilds Yeq or Ythevenin + zsorce = thisgen.Zthev; // In ohms + zsorcepu = cdivreal(zsorce, zbase); // In ohms + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if (pGen->GenON) + { + + // Get terminal current and put it in 012 reference frame + vterm = pGen->GetVterminal(ActorID); // Positive sequence voltage - LN + + // Calculate terminal current and convert from abc to 012 + pGen->ComputeIterminal(ActorID); + Phase2SymComp(&(pGen->Iterminal[0]), & (I012[0])); + iterm = cmulreal(I012[1], -1.0); // Making iterm convention positive when leaving the generator terminals + iterminit[0] = I012[0]; + iterminit[1] = I012[1]; + iterminit[2] = I012[2]; + + // Calculate vsource - in Volts + vsorce = cadd(vterm, cmul(iterm, zsorce)); + + // Convert put it in DQ reference frame with network angle as the reference - q axis leading d axis + // The angle theta is used to convert from positive sequence to dq reference frame + // theta is the angle of the terminal bus voltage + + double theta = cang(vsorce); + + // Put vsorce in pu and calculate isorce in pu; + vsorcepu = cdivreal(vsorce, (vbase / SQRT3)); + Edq = seq2dq(vsorcepu, theta); // LN + ed = Edq.re; // ed in pu + eq = Edq.im; // eq in pu + + // Calculate isorce in Amps and pu + isorce = cdiv(vsorce, zsorce); + isorcepu = cdiv(vsorcepu, zsorcepu); + Idq = seq2dq(isorcepu, theta); + id = Idq.re; + iq = Idq.im; + + // Get total apparent power at the terminal (sgen) and put in pu + sgen = pGen->Get_Power(1, ActorID); // Total power in Watts and VAr + sgen.re = -1 * sgen.re / (mbase); // mbase is in VA + sgen.im = -1 * sgen.im / (mbase); + + pgen = sgen.re; + qgen = sgen.im; + pmech = pgen; + + // Initialize state 0 - rotor angle + ang = cang(vsorce); + this->s[0] = ang; + this->ss[0] = ang; + this->ds[0] = 0.0; + + + // Initialize state 1 - rotor speed + spd = 1.0; + dspd = 0.; + this->s[1] = 1.0; + this->ss[1] = 1.0; + this->ds[1] = 0.0; + + // Sanity check - Let's calculate sgen just for the sake of validation + //double sout; + //sout = 3 * cabs(vterm) * cabs(iterm); + //double angdiff, pout, qout; + //angdiff = cang(vterm) - cang(iterm); + //pout = sout * cos(angdiff); + //qout = sout * sin(angdiff); + + } + else { + return -1; + DoSimpleMsg(Format(("Generator " + pGen->get_Name() + " is offline.").c_str()), 9004); + } + + return 0; + } + + int TGenclsObj::CalculateRate(int ActorID) + { + complex vterm; + double err; + double te; + double w0 = 2 * PI * DefaultBaseFreq; + vterm = pGen->GetVterminal(ActorID); + + double mbase = pGen->GenVars.kVArating * 1000.; // MVA base of generator, converted from kVA + complex sgen; + + // Get total apparent power at the terminal (sgen) and put in pu + sgen = pGen->Get_Power(1, ActorID); + sgen.re = -1 * sgen.re / mbase; + sgen.im = -1 * sgen.im / mbase; + + pgen = sgen.re; + qgen = sgen.im; + // pmech = pgen; ---> this should come from the turbine governor model + // te = pgen * this->s[1]; + te = pgen; + + dspd = this->s[1] - 1.0; + spd = this->s[1]; + ang = this->s[0]; + + + //err = ((pmech - dspd * d) / spd) - te; + err = ((pmech - dspd * d)) - te; + + // Calculate ds[1] + if (h > 0) + this->ds[1] = err / (2 * h); + else + this->ds[1] = 0.; + + // Calculate ds[0] + this->ds[0] = (spd - 1.0) * w0; + + return 0; + } + + int TGenclsObj::StateIntegration(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // HEre we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::ab2order(this, &h); + // IntegrationMethods::euler(this, &h); + + //this->nstates; + return 0; + } + + int TGenclsObj::StateIntegration_correction(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // HEre we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + IntegrationMethods::trapezoidal(this, &h); + // IntegrationMethods::euler(this, &h); + // IntegrationMethods::ab2order(this, &h); + + //this->nstates; + return 0; + } + + complex* TGenclsObj::CalculateIsorce(int ActorID, complex *I012) + { + // Calculate Isorce + complex V012[3]; // sequence terminal voltage + //complex I012[3]; // sequence terminal voltage + complex isorce2, isorce2pu; // neagtive sequence source currents + complex ithev; // Current down zthev impedance + complex iterm; // Current injected into the terminal + double vbase, ibase, zbase, mbase; + complex vterm; // This is the positive sequence terminal voltage in Volts, abc reference frame + complex vtdq; // This is the positive sequence terminal voltage in Volts, dq reference frame + double theta; // This is the angular reference used to convert from/from abc/dq reference frames + polar vtermll; + complex Edq; + complex iterm2, iterm0; + + //complex vsorce, isorce, vsorcepu, isorcepu, zsorce, zsorcepu; + + // Define bases + vbase = pGen->GenVars.kVGeneratorBase * 1000; // vbase LN in Volts + mbase = pGen->GenVars.kVArating * 1000.; // mbase in VA + ibase = mbase / (SQRT3 * vbase); // ibase in A + zbase = vbase * vbase / mbase; // zbase in Ohms + + // Update the rotation angle + theta = s[0]; + + zsorce = { pGen->GenVars.Zthev.re, pGen->GenVars.Zthev.im }; + zsorcepu = cdivreal(zsorce, zbase); + + // Calculate internal voltage source + Edq = { ed, eq }; // Retrieve values in pu + vsorcepu = dq2seq(Edq, theta); + vsorce = cmulreal(vsorcepu, (vbase / SQRT3)); + + // Calculate isorcepu - this is the positive sequence current injection in pu + isorce = cdiv(vsorce, zsorce); // In amps + + // Get positive sequence terminal voltage in Volts + vterm = pGen->GetVterminal(ActorID); // LN + ithev = cdiv(vterm, zsorce); + + //Iterminal = Isource - Ithevenin (current on Zthev); + iterm = csub(isorce, ithev); + I012[1] = cmulreal(iterm, -1.0); + + // Sanity check on total power out of generator + complex sgen = cmulreal(cmul(vterm, conjg(iterm)), 3); + + // iterm is the positive sequence current in Amps. + // Now need to calculate zero and negative sequence current at the terminals, then update Iterminal + + //************** fix this tomorrow **************************** + + Phase2SymComp(&(pGen->Vterminal[0]), &V012[0]); + I012[2] = cdiv(V012[2], cmplx(0.0, pGen->GenVars.Xdpp)); // machine use Xd" + I012[0] = { 0.0,0.0 }; // Setting zero seq current here to zero but this will be recalculated as soon as we stop out of this function + //complex *pI012; + //pI012 = I012; + + return I012; + } + + complex TGenclsObj::GetIsorce1(int ActorID) + { + complex I1; + I1 = cmulreal(this->isorcepu, ibase); + + return I1; + } + + complex TGenclsObj::GetIsorce2(int ActorID) + { + return complex(); + } + + double TGenclsObj::get_channel(int i) + { + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if (i < 1) + return result; // Someone goofed + switch (i) { + case 1: + result = this->spd; // speed in pu + break; + case 2: + result = this->ang; // ang in radians + break; + case 3: + result = this->ed; // ed in pu + break; + case 4: + result = this->pgen; // pgen in pu + break; + case 5: + result = this->qgen; // qgen in pu + break; + case 6: + result = this->pmech; // pmech in pu + break; + default: + break; + } + return result; + } + + String TGenclsObj::get_channel_header(int i) + { + String result; + switch (i) { + case 1: + result = "spd(pu)"; + break; + case 2: + result = " ang(rad)"; + break; + case 3: + result = " Ed(pu)"; + break; + case 4: + result = " pgen(pu)"; + break; + case 5: + result = " qgen(pu)"; + break; + case 6: + result = " pmech(pu)"; + break; + default: + break; + } + return result; + } + + int64_t TGenclsObj::get_number_channels() + { + return nchannels; + } + + + /*void TGenclsObj::MakePosSequence(int ActorID) { + + }*/ + + /*void TGenclsObj::CalcYPrim(int ActorID){ + + }*/ + + void TGenclsObj::sample(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TGenclsObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TGenclsObj::Reset(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + /*void TGenclsObj::RecalcElementData(int ActorID){ + + }*/ + + /*void TGenclsObj::GetCurrents(Ucomplex::pComplexArray Curr, int ActorID) { + + } + + void TGenclsObj::GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID) { + + }*/ + void TGenclsObj::InitPropertyValues(int ArrayOffset) { + Set_PropertyValue(1,""); // bus_name; + Set_PropertyValue(2,""); // gen_name; + Set_PropertyValue(3,"3.0"); // h; + Set_PropertyValue(4,"1.0"); // d; + inherited::InitPropertyValues(NumPropsThisClass); + } + + /* + void TGenclsObj::DumpProperties(System::TTextRec& f, bool Complete) { + + } + */ +} diff --git a/OpenDSSC/GenModels/gencls.h b/OpenDSSC/GenModels/gencls.h new file mode 100644 index 0000000..cad19aa --- /dev/null +++ b/OpenDSSC/GenModels/gencls.h @@ -0,0 +1,149 @@ +#ifndef GENCLS_H +#define GENCLS_H + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "Bus.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" +#include "gencls.h" + + +using namespace std; + +namespace Gencls +{ + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + /* + Change Log + 6/6/2022 - B. Leonardi - created class + + */ + + /* + A Gencls is a class that represents a classical model of a synchronous generator. + + It can be invoked as follows in the input file: + + New Gencls.Name=myname generator=Generator.name terminal=[ 1|2|...] Parameter_List + + Controlled generator must already exist in the case. + */ + + + + + + + class TGencls : public ControlClass::TControlClass { + friend class TGenclsObj; + public: + typedef ControlClass::TControlClass inherited; + private: + + protected: + void DefineProperties(); + int MakeLike(const String GenclsName); + public: + TGencls(); + virtual ~TGencls(); + int Edit(int ActorID); // uses global parser + int NewObject(const String ObjName); + int FindGenerator(); + + }; + + class TGenclsObj : public ControlElem::TControlElem { + public: + typedef ControlElem::TControlElem inherited; + + + public: + int64_t nstates; + int64_t nchannels; + // States, stored tates and state derivatives + double *s, *ss, *ds, *dss; + vector ps; + // Parameters + double h; + double d; + // Variables + double pmech, tm; + double pgen, qgen, te; + double dspd; + double ang; + double spd; + double w0; + double ed; // internal voltage source direct axis voltage in pu + double eq; // internal voltage source quadrature axis voltage in pu + double id; // internal current source direct axis current in pu + double iq; // internal current source direct axis current in pu + complex zsorce, zsorcepu; + complex vsorce, vsorcepu; + complex isorce, isorcepu; + complex isorce2, isorce2pu; + complex iterminit[3]; + // Bases + double vbase, mbase, ibase; + + int FListSize; + String gen_name; // Name of generator model is connected to + String bus_name; // Name of bus where model is connected to + Generator::TGeneratorObj* pGen; // Pointer to controlled generator + std::vector cBuffer; // Complexarray buffer + + + public: + TGenclsObj(DSSClass::TDSSClass* ParClass, const String GenclsName); + TGenclsObj(); + virtual ~TGenclsObj(); + // void MakePosSequence(int ActorID); // Make a positive Sequence Model + //virtual void RecalcElementData(int ActorID); + //virtual void CalcYPrim(int ActorID); // Always Zero for a GenDispatcher + void sample(int ActorID); // Sample control quantities and set action times in Control Queue + void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + void Reset(int ActorID); // Reset to initial defined state + //void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + //void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + void InitPropertyValues(int ArrayOffset); + // void DumpProperties(System::TTextRec& f, bool Complete); + void LoadDefaultParameters(); + // bool MakeGenList(); + // void SetMachineModel(); + virtual int InitializeStates(int ActorID); + virtual int CalculateRate(int ActorID); + virtual int StateIntegration(int ActorID); + virtual int StateIntegration_correction(int ActorID); + virtual complex* CalculateIsorce(int ActorID, complex *I012); + virtual complex GetIsorce1(int ActorID); + virtual complex GetIsorce2(int ActorID); + virtual double get_channel(int channel_num); + virtual String get_channel_header(int channel_num); + virtual int64_t get_number_channels(); + + + }; + + extern TGenclsObj* ActiveGenclsObj; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Gencls; +#endif + +#endif // !GENCLS_H diff --git a/OpenDSSC/GenModels/genrou.cpp b/OpenDSSC/GenModels/genrou.cpp new file mode 100644 index 0000000..88005bc --- /dev/null +++ b/OpenDSSC/GenModels/genrou.cpp @@ -0,0 +1,1219 @@ + +#include "System.h" +#include "Sysutils.h" +#include "fstream" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "DSSGlobals.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "d2c_structures.h" +#include "genrou.h" +#include +#include "IntegrationMethods.h" +#include "klusolve.h" + + + +using namespace std; +using namespace std; +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + + +namespace Genrou +{ + + TGenrouObj* ActiveGenrouObj = nullptr; + const int NumPropsThisClass = 19; // Number of properties in this class + + void TGenrou::DefineProperties() + { + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[0] = "bus_name"; + PropertyName[1] = "gen_name"; + PropertyName[2] = "tpdo"; + PropertyName[3] = "tppdo"; + PropertyName[4] = "tpqo"; + PropertyName[5] = "tppqo"; + PropertyName[6] = "h"; + PropertyName[7] = "d"; + PropertyName[8] = "xd"; + PropertyName[9] = "xq"; + PropertyName[10] = "xpd"; + PropertyName[11] = "xpq"; + PropertyName[12] = "xppd"; + PropertyName[13] = "xl"; + PropertyName[14] = "s1"; + PropertyName[15] = "s12"; + PropertyName[16] = "ra"; + PropertyName[17] = "rcomp"; + PropertyName[18] = "xcomp"; + PropertyHelp[0] = "Bus name where the model is connected to"; + PropertyHelp[1] = "Generator name where model is connected to"; + PropertyHelp[2] = "d-axis transient rotor time constant"; + PropertyHelp[3] = "d-axis subtransient rotor time constant"; + PropertyHelp[4] = "q-axis transient time constant"; + PropertyHelp[5] = "q-axis subtransient time constant"; + PropertyHelp[6] = "inertia constant"; + PropertyHelp[7] = "damping factor"; + PropertyHelp[8] = "d-axis synchornous reactance"; + PropertyHelp[9] = "q-axis synchronous reactance"; + PropertyHelp[10] = "d-axis transient reactance"; + PropertyHelp[11] = "q-axis transient reactance"; + PropertyHelp[12] = "d-axis subtransient reactance"; + PropertyHelp[13] = "stator leakage reactance"; + PropertyHelp[14] = "saturation factor at 1pu flux"; + PropertyHelp[15] = "saturation factor at 1.2pu flux"; + PropertyHelp[16] = "stator resistance"; + PropertyHelp[17] = "compounding resistance for voltage control"; + PropertyHelp[18] = "compounding reactance for voltage control"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + int TGenrou::MakeLike(const String GenrouName) + { + int result = 0; + TGenrouObj* OtherGenrou = nullptr; + int i = 0; + result = 0; + /*See if we can find this GenrouName in the present collection*/ + OtherGenrou = ((TGenrouObj*)Find(GenrouName)); + if (OtherGenrou != nullptr) + { + auto thisobj = ActiveGenrouObj; + int stop = 0; + thisobj->bus_name = OtherGenrou->bus_name; + + for (i = 1; i <= thisobj->ParentClass->NumProperties; i++) + { + thisobj->Set_PropertyValue(i,OtherGenrou->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Genrou MakeLike: \"") + GenrouName + + "\" Not Found.", 9001); + return result; + } + // Constructor and Destructor + TGenrou::TGenrou() { + + Class_Name = "Genrou"; + DSSClassType = DSSClassType + GENROU_ELEMENT; + DefineProperties(); + CommandList = TCommandList(Slice((PropertyName), NumProperties), NumProperties); + CommandList.set_AbbrevAllowed(true); + + } + + TGenrou::~TGenrou() { + + } + + + int TGenrou::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + int ret = -1; + + // continue parsing WITH contents of Parser + ActiveGenrouObj = (TGenrouObj*)ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGenrouObj); + result = 0; + + { + auto thisobj = ActiveGenrouObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + thisobj->Set_PropertyValue(ParamPointer,Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + thisobj->get_Name() + + "\"", 9000); + break; + case 1: + thisobj->bus_name = Parser[ActorID]->MakeString_(); + break; + case 2: + thisobj->gen_name = Parser[ActorID]->MakeString_(); + // Try to find generator in generator list + ret = FindGenerator(); + break; + case 3: + thisobj->tpdo = Parser[ActorID]->MakeDouble_(); + break; + case 4: + thisobj->tppdo = Parser[ActorID]->MakeDouble_(); + break; + case 5: + thisobj->tpqo = Parser[ActorID]->MakeDouble_(); + break; + case 6: + thisobj->tppqo = Parser[ActorID]->MakeDouble_(); + break; + case 7: + thisobj->h = Parser[ActorID]->MakeDouble_(); + break; + case 8: + thisobj->d = Parser[ActorID]->MakeDouble_(); + break; + case 9: + thisobj->xd = Parser[ActorID]->MakeDouble_(); + break; + case 10: + thisobj->xq = Parser[ActorID]->MakeDouble_(); + break; + case 11: + thisobj->xpd = Parser[ActorID]->MakeDouble_(); + break; + case 12: + thisobj->xpq = Parser[ActorID]->MakeDouble_(); + break; + case 13: + thisobj->xppd = Parser[ActorID]->MakeDouble_(); + break; + case 14: + thisobj->xl = Parser[ActorID]->MakeDouble_(); + break; + case 15: + thisobj->s1 = Parser[ActorID]->MakeDouble_(); + break; + case 16: + thisobj->s12 = Parser[ActorID]->MakeDouble_(); + break; + case 17: + thisobj->ra = Parser[ActorID]->MakeDouble_(); + break; + case 18: + thisobj->rcomp= Parser[ActorID]->MakeDouble_(); + break; + case 19: + thisobj->xcomp = Parser[ActorID]->MakeDouble_(); + break; + default: + ClassEdit(ActiveGenrouObj, ParamPointer - NumPropsThisClass); + break; + } + + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + //thisobj->RecalcElementData(ActorID); + + } + + return result; + } + + int TGenrou::NewObject(const String ObjName) { + + // Make a new Genrou model and add it to Genrou class list + + int result = 0; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGenrouObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + /*if(result) + result = FindGenerator(); + */ + return result; + } + + int TGenrou::FindGenerator() + { + auto thisobj = ActiveGenrouObj; // For the active genrou model, set a pointer to its generator model + TDSSClass* GenClass = nullptr; + TGeneratorObj* Gen = nullptr; + GenClass = (TDSSClass*)GetDSSClassPtr("generator"); + Gen = (TGeneratorObj*)GenClass->Find(thisobj->gen_name); + if (ASSIGNED(Gen) && ((TDSSCktElement*)Gen)->Get_Enabled()) { // If generator is found and is enabled, then set pointer + Gen->gen_model = thisobj; // C++ will allow this just fine since thisobj is a derived class from T + thisobj->pGen = Gen; // Set this object generator pointer for easy access + if (Gen->gen_model != nullptr) + return 0; + } + else { + // If it gets to this point, generator was either not found, or casting was incorrect, or was not online/enabled + DoSimpleMsg(String("Genrou model \"") + thisobj->get_Name() + + "\" could not find generator \"" + thisobj->gen_name + + "\". Generator could be missing or not enabled \"", 9002); + return -1; + } + return -1; + } + + + //--------------------------------------------------------------// + // // + // TGenrouObj Functions // + // // + //--------------------------------------------------------------// + + + + TGenrouObj::TGenrouObj() : + ibase(1.0), + mbase(1.0), + vbase(1.0), + isorce{ 1.0, 1.0 }, + isorcepu{ 1.0,1.0 }, + isorce2{ 1.0,1.0 }, + isorce2pu{ 1.0,1.0 }, + iterminit{ 1.0,1.0 }, + vsorce{ 1.0,1.0 }, + vsorcepu{ 1.0,1.0 }, + zsorce{ 1.0,1.0 }, + zsorcepu{ 1.0,1.0 } + { + nstates = 2; + nchannels = 6; + // States + ps.reserve(nstates); + s = new double(nstates); + ss = new double(nstates); + ds = new double(nstates); + dss = new double(nstates); + // Parameters + tpdo = 0.0; + tppdo = 0.0; + tpqo = 0.0; + tppqo = 0.0; + h = 0.0; + d = 0.0; + xd = 0.0; + xq = 0.0; + xpd = 0.0; + xpq = 0.0; + xppd = 0.0; + xl = 0.0; + s1 = 0.0; + s12 = 0.0; + ra = 0.0; + rcomp = 0.0; + xcomp = 0.0; + // Variables + pmech = 0.; + pgen = 0.; + qgen = 0.; + tm = 0.; + te = 0.; + dspd = 0.0; + ang = 0.0; + spd = 0.0; + w0 = 0.0; + ed = 0.0; + eq = 0.0; + id = 0.0; + iq = 0.0; + efd = 0.0; + ladifd = 0.0; + fd = 0.0; + fpd = 0.0; + fppd = 0.0; + fq = 0.0; + fpq = 0.0; + fppq = 0.0; + // Others + pGen = nullptr; + FListSize = 0; + } + + TGenrouObj::TGenrouObj(DSSClass::TDSSClass* ParClass, const String GenrouName) : + inherited(ParClass), + ibase(1.0), + mbase(1.0), + vbase(1.0), + isorce{ 1.0, 1.0 }, + isorcepu{ 1.0,1.0 }, + isorce2{ 1.0,1.0 }, + isorce2pu{ 1.0,1.0 }, + iterminit{ 1.0,1.0 }, + vsorce{ 1.0,1.0 }, + vsorcepu{ 1.0,1.0 }, + zsorce{ 1.0,1.0 }, + zsorcepu{ 1.0,1.0 } + { + Set_Name(LowerCase(GenrouName)); + DSSObjType = ParClass->DSSClassType; + cBuffer.clear(); + + InitPropertyValues(0); + + // RecalcElementData; + + // Initialize members + nstates = 6; + nchannels = 6; + // States + s = new double[nstates]; + ss = new double[nstates]; + ds = new double[nstates]; + dss = new double[nstates]; + // Parameters + tpdo = 0.0; + tppdo = 0.0; + tpqo = 0.0; + tppqo = 0.0; + h = 0.0; + d = 0.0; + xd = 0.0; + xq = 0.0; + xpd = 0.0; + xpq = 0.0; + xppd = 0.0; + xl = 0.0; + s1 = 0.0; + s12 = 0.0; + ra = 0.0; + rcomp = 0.0; + xcomp = 0.0; + // Variables + pmech = 0.; + pgen = 0.; + qgen = 0.; + tm = 0.; + te = 0.; + dspd = 0.0; + ang = 0.0; + spd = 0.0; + w0 = 0.0; + ed = 0.0; + eq = 0.0; + id = 0.0; + iq = 0.0; + efd = 0.0; + ladifd = 0.0; + fd = 0.0; + fpd = 0.0; + fppd = 0.0; + fq = 0.0; + fpq = 0.0; + fppq = 0.0; + // Others + pGen = nullptr; + FListSize = 0; + } + + + + + TGenrouObj::~TGenrouObj() { + delete[] s; + delete[] ss; + delete[] ds; + delete[] dss; + } + + void TGenrouObj::LoadDefaultParameters() { + // These are the deafault parameters for this model + tpdo = 7.0; + tppdo = 0.030; + tpqo = 0.75; + tppqo = 0.05; + h = 3.0; + d = 0.0; + xd = 2.1; + xq = 2.0; + xpd = 0.2; + xpq = 0.5; + xppd = 0.18; + xl = 0.15; + s1 = 0.05; + s12 = 0.3; + ra = 0.0; + rcomp = 0.0; + xcomp = 0.0; + } + + int TGenrouObj::InitializeStates(int ActorID) + { + // Get generator terminal current and terminal voltage + + /*VNeut,*/ + int i = 0; + complex V012[3/*# range 0..2*/]{ 0.0,0.0,0.0,0.0,0.0,0.0 }; + complex I012[3/*# range 0..2*/]{ 0.0,0.0,0.0,0.0,0.0,0.0 }; + complex Vabc[4/*# range 1..3*/]{ 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 }; + complex vterm; // Terminal voltage in V and abc ref frame + complex iterm{ 0.0,0.0 }, itermpu{ 0.0,0.0 }; // Terminal current in A and abc ref frame + complex sgen; // Complex power + complex Idq; // Terminal current in dq reference frame + complex vtdq, vtermpu; // Terminal dq voltage and terminal in pu + + + // Get voltage and MVA bases for generator. All generator variables and parameters will be in pu and these are the bases used to + this->vbase = (pGen->GenVars.kVGeneratorBase * 1000/SQRT3); // Voltage base LL in Volts + this->mbase = pGen->GenVars.kVArating * 1000; // MVA base of generator, in VA + this->ibase = mbase / (vbase * 3); // Ibase in A for current pu-nitization + double zbase = (vbase) / ibase; // Impedance base in Ohms + double sx; // Saturation adjustment to flux + double aux1, aux2; // Local auxiliary variables + double vmag, imag, delta; // Local variables for voltage magnitude, current magnitude and rotor angle + + pGen->Set_YprimInvalid(ActorID, true); // Force rebuild of YPrims on the generator + + // This stuff will have to come from the new generator models, so should come from genrou, genrou, etc + auto& thisgen = pGen->GenVars; + if (this->xppd <= 0.0001) { + DoSimpleMsg(Format(("Xppd value for Generator " + pGen->get_Name() + " is less or equal than zero.").c_str()), 90001); + return -1; + } + else { + thisgen.Zthev = cmulreal(cmplx(this->ra, this->xppd),zbase); // Set Zthev based on ra and x"d - zthev is is Ohms + //thisgen.Zthev = cmplx(thisgen.Xdp / thisgen.XRdp, thisgen.Xdpp); + } + + pGen->Yeq = cinv(thisgen.Zthev); // Rebuilds Yeq or Ythevenin + zsorce = thisgen.Zthev; // In ohms + zsorcepu = cdivreal(thisgen.Zthev,zbase); // In ohms + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if (pGen->GenON) + { + + // Get terminal current and put it in 012 reference frame + vterm = pGen->GetVterminal(ActorID); // Positive sequence voltage - LN + vtermpu = cdivreal(vterm, vbase); + vmag = cabs(vtermpu); + + // Calculate terminal current and convert from abc to 012 + pGen->ComputeIterminal(ActorID); + Phase2SymComp(&(pGen->Iterminal[0]), & (I012[0])); + iterm = cmulreal(I012[1], -1.0); // Extracting the positive sequence Making iterm convention positive when leaving the generator terminals + itermpu = cdivreal(iterm, ibase); + iterminit[0] = I012[0]; + iterminit[1] = I012[1]; + iterminit[2] = I012[2]; + imag = cabs(itermpu); + + sgen = cmulreal(cmul(vterm,conjg(iterm)), 3); + complex sgenpu = cmul(vtermpu, conjg(itermpu)); + + // Calculate vsource - in Volts + vsorce = cadd(vterm, cmul(iterm, zsorce)); // LN + vsorcepu = cdivreal(vsorce, vbase); + aux1 = cang(vsorcepu); + complex vsp = cadd(vtermpu, cmul(itermpu, zsorcepu)); + + // Initialize rotor angle - delta + // Step 1 - calculate er, ei + double er = vtermpu.re + this->ra * itermpu.re - this->xppd * itermpu.im; + double ei = vtermpu.im + this->ra * itermpu.im + this->xppd * itermpu.re; + + // Step 2 - calculate saturation magnitude + // Calculate the saturation parameters asat and bsat + if (s12 > 0.0) { + this->asat = (1.0 - sqrt((this->s1*1.0) / (this->s12*1.2)) * 1.2) / (1.0 - sqrt((this->s1*1.0) / (this->s12*1.2))); + this->bsat = this->s1 / (pow(1.0 - this->asat, 2)); + } + else { + this->asat = 0.0; + this->bsat = 0.0; + DoSimpleMsg(Format(("Saturation factor s12 for Generator " + pGen->get_Name() + " is less or equal than zero. s12 = " + to_string(this->s12)).c_str()), 90002); + } + double fppmag = sqrt(pow(er, 2) + pow(ei, 2)); + sx = QuadraticSaturation(fppmag); + + // Step 3 - calculate intermediate variables + double A = (sx * (this->xq - this->xl) / (this->xd - this->xl)) + 1; + double B = (this->xq - this->xppd); + + // Step 4 - Calculate rotor angle + delta = atan((A * ei + B * itermpu.re) / (A * er - B * itermpu.im)); + + // Step 5 - calcualte ed, eq + + this->ed = er * sin(delta) - ei * cos(delta); // ed in pu + this->eq = er * cos(delta) + ei * sin(delta); // eq in pu + + vtdq = seq2dq(vtermpu, delta); // terminal voltage in dq ref frame + this->vtd = vtdq.re; + this->vtq = vtdq.im; + + + // Calculate isorce in Amps and pu + isorce = cdiv(vsorce, zsorce); + isorcepu = cdiv(vsorcepu, zsorcepu); + + Idq = seq2dq(itermpu, delta); // This is the iterm current in pu -> iterm = isorce - ithev + this->id = Idq.re; + this->iq = Idq.im; + + // Get total apparent power at the terminal (sgen) and put in pu + sgen = pGen->Get_Power(1, ActorID); // Total power in Watts and VAr + sgen.re = -1 * sgen.re / (mbase); // mbase is in VA + sgen.im = -1 * sgen.im / (mbase); + + this->pgen = sgen.re; + this->qgen = sgen.im; + this->pmech = this->pgen; + + // Calculate machine flux + this->fppq = -this->ed; + this->fppd = this->eq; + + // Calculate pq and pd to calculate electrical torque + this->fq = this->fppq - this->iq * this->xppd; + this->fd = this->fppd - this->id * this->xppd; + this->te = this->fd * this->iq - this->fq * this->id; + + // Initialize state 0 - rotor angle + ang = delta; + this->s[0] = ang; + this->ss[0] = ang; + this->ds[0] = 0.0; + + // Initialize state 1 - rotor speed + spd = 1.0; + dspd = 0.0; + this->s[1] = 1.0; + this->ss[1] = 1.0; + this->ds[1] = 0.0; + + // Initialize state 2 - transient q-axis voltage (E'q) + this->s[2] = this->fppd + this->id * (this->xpd - this->xppd); + this->ss[2] = this->s[2]; + this->ds[2] = 0.; + + // Initialize state 3 - transient d-axis flux (fpd) + this->s[3] = this->s[2] - this->id * (this->xpd - this->xl); + this->ss[3] = this->s[3]; + this->ds[3] = 0.; + + //// Initialize state 5 + this->s[5] = -this->fppq - this->iq * (this->xpq - this->xppd); + this->ss[5] = this->s[5]; + this->ds[5] = 0.; + + // Initialize state 4 + this->s[4] = this->s[5] + this->iq * (this->xpq - this->xl); + this->ss[4] = this->s[4]; + this->ds[4] = 0.; + + // Set field current and voltage + aux1 = this->s[2] - this->s[3] - this->id * (this->xpd - this->xl); + aux2 = aux1 * ((this->xpd - this->xppd) / (pow((this->xpd - this->xl), 2.0))) + this->id * (this->xd - this->xpd); + this->ladifd = this->s[2] + aux2 + sx * fppd; + this->efd = this->ladifd; + + } + else { + DoSimpleMsg(Format(("Generator " + pGen->get_Name() + " is offline.").c_str()), 9004); + return -1; + } + + return 0; + } + + int TGenrouObj::CalculateRate(int ActorID) + { + // Declaring variables + complex I012[3/*# range 0..2*/]{ 0.0,0.0,0.0,0.0,0.0,0.0 }; + complex vterm, vtermpu; // Terminal voltage in V and abc ref frame + complex iterm{ 0.0,0.0 }, itermpu{ 0.0,0.0 }; // Terminal current in A and abc ref frame + complex sgen; + complex Edq; + complex Idq; // Terminal current in dq reference frame + + double err; + double aux1, aux2, aux3, aux4 = 0.0, aux5; + double w0 = 2 * PI * DefaultBaseFreq; + double vbase = pGen->GenVars.kVGeneratorBase * 1000/SQRT3; // Voltage base LL in Volts + double mbase = pGen->GenVars.kVArating * 1000.; // MVA base of generator, converted from kVA + double ibase = mbase / (vbase*3); // Ibase in A for current pu-nitization + double zbase = vbase / ibase; // Impedance base in Ohms + double sx; + + vterm = pGen->GetVterminal(ActorID); + + // Get total apparent power at the terminal (sgen) and put in pu + sgen = pGen->Get_Power(1, ActorID); + sgen.re = -1 * sgen.re / mbase; + sgen.im = -1 * sgen.im / mbase; + + pgen = sgen.re; + qgen = sgen.im; + + // Save last value of pgen and qgen on plast, qlast + // These values will be used to initialize the Time series power flow generation profile + this->plast = this->pgen; + this->qlast = this->qgen; + + // If governor model exists, use pmech from governor model + if (pGen->turb_model != nullptr) + { + this->pmech = pGen->turb_model->get_pmech(); + } + else + { + this->pmech = this->pmech; + } + + // Get terminal current and put it in 012 reference frame + vterm = pGen->GetVterminal(ActorID); // Positive sequence voltage - LN + vtermpu = cdivreal(vterm, vbase); + + // Calculate terminal current and convert from abc to 012 + pGen->ComputeIterminal(ActorID); + Phase2SymComp(&(pGen->Iterminal[0]), & (I012[0])); + iterm = cmulreal(I012[1], -1.0); // Making iterm convention positive when leaving the generator terminals + iterminit[0] = I012[0]; + iterminit[1] = I012[1]; + iterminit[2] = I012[2]; + + // Calculate vsource - in Volts + vsorce = cadd(vterm, cmul(iterm, zsorce)); + + // Convert put it in DQ reference frame with network angle as the reference - q axis leading d axis + // The angle theta is used to convert from positive sequence to dq reference frame + // theta is the angle of the terminal bus voltage + + double delta = this->s[0]; + + // Put vsorce in pu and calculate isorce in pu; + vsorcepu = cdivreal(vsorce, vbase); + Edq = seq2dq(vsorcepu, delta); // LN + this->ed = Edq.re; // ed in pu + this->eq = Edq.im; // eq in pu + + // Calculate isorce in Amps and pu + isorce = cdiv(vsorce, zsorce); + isorcepu = cdiv(vsorcepu, zsorcepu); + + // Calculate angle between terminal current and terminal voltage + //sigma = atan(isorce.im / isorce.re); // Terminal current angle + //alpha = atan(vterm.im / vterm.re); // Terminal voltage angle + //phi = alpha - sigma; // Angle between voltage and current + + itermpu = cdivreal(iterm, ibase); + + Idq = seq2dq(itermpu, delta); // This is the terminal current - includes isorce + ithev + this->id = Idq.re; + this->iq = Idq.im; + + + // Must update fppd and fppq from states + this->fppd = this->s[3] * ((this->xpd - this->xppd) / (this->xpd - this->xl)) + + this->s[2] * ((this->xppd-this->xl) / (this->xpd-this->xl)); + + this->fppq = -1.*((this->s[4] * ((this->xpq - this->xppd) / (this->xpq - this->xl))) + + (this->s[5] * (this->xppd - this->xl) / (this->xpq - this->xl))); + + // Update fpd, fpq + this->fpd = this->s[3]; + this->fpq = this->s[4]; + + + // Calculate electrical torque - something doesn't add up here + this->fq = this->fppq - this->iq * this->xppd; + this->fd = this->fppd - this->id * this->xppd; + this->te = this->fd*this->iq - this->fq*this->id; + + // Assign delta speed and speed + this->dspd = this->s[1] - 1.0; + this->spd = this->s[1]; + this->ang = this->s[0]; + + //err = ((pmech - dspd * d) / spd) - pe; + err = ((this->pmech - this->dspd * this->d)/this->s[1]) - (this->fppd*iq - this->fppq*id); + + // Calculate ds[0] + this->ds[0] = (spd - 1.0) * w0; + + // Calculate ds[1] + if (h > 0) + this->ds[1] = err / (2 * h); + else + this->ds[1] = 0.; + + // Calculate ds[2] + aux1 = this->s[2] - this->s[3] - this->id * (this->xpd - this->xl); + aux2 = (aux1 * ((this->xpd - this->xppd) / (pow((this->xpd - this->xl), 2.0))) + this->id) * (this->xd - this->xpd); + + // Saturation + double er = vtermpu.re + this->ra * itermpu.re - this->xppd * itermpu.im; + double ei = vtermpu.im + this->ra * itermpu.im + this->xppd * itermpu.re; + double fppmag = sqrt(pow(this->fppd, 2) + pow(this->fppq, 2)); + + sx = QuadraticSaturation(fppmag); + + //this->ladifd = sx * this->fppd + this->s[2] + aux2; + + // If excitation system model exits, use efd from exciter model + if (pGen->exc_model != nullptr) { + this->efd = pGen->exc_model->get_efield(); + } + else { // If the generator doesn't have an excitation system model, leave the value of efd unchanged + this->efd = this->efd; + } + + // Calculate ds[3] + double err1 = this->s[2] - this->s[3] - this->id * (this->xpd - this->xl); + this->ds[3] = err1/this->tppdo; + + // Calculate ds[2] + this->ladifd = sx*this->fppd + this->s[2] + (this->xd - this->xpd) * (this->id + err1 * (this->xpd - this->xppd) / pow(this->xpd - this->xl, 2.0)); + this->ds[2] = (this->efd - this->ladifd) / this->tpdo; + + // Calculate ds[4] + double err2 = this->s[5] - this->s[4] + this->iq * (this->xpq - this->xl); + this->ds[4] = err2 / this->tppqo; + + // Calculate ds[5] + aux5 = (this->iq - (err2 * ((this->xpq - this->xppd) / pow(this->xpq - this->xl ,2))) ) * (this->xq - this->xpq); + aux3 = sx * this->fppq * (this->xq - this->xl) / (this->xd - this->xl); + this->ds[5] = (aux3 - this->s[5] + aux5)/this->tpqo; + + + return 0; + } + + int TGenrouObj::StateIntegration(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // HEre we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::ab2order(this, &h); + // IntegrationMethods::euler(this, &h); + + //this->nstates; + return 0; + } + + int TGenrouObj::StateIntegration_correction(int ActorID) + { + // Call global integration method of choice + + double h = ActiveCircuit[ActorID]->Solution->DynaVars.h; + + // HEre we are calling Adams-Bashforth second order. + // Other methods can be implemented and each model can call a specific method. + // That is the beauty of this modular implementation + // IntegrationMethods::trapezoidal(this, &h); + IntegrationMethods::euler(this, &h); + // IntegrationMethods::ab2order(this, &h); + + //this->nstates; + return 0; + } + + complex* TGenrouObj::CalculateIsorce(int ActorID, complex* I012) + { + // Calculate Isorce + complex V012[3] = {CZero, CZero, CZero}; // sequence terminal voltage + complex isorce2 = CZero, + isorce2pu = CZero, // neagtive sequence source currents + ithev = CZero, // Current down zthev impedance + iterm = CZero, // Current injected into the terminal + vterm = CZero, // This is the positive sequence terminal voltage in Volts, abc reference frame + vtdq = CZero, // This is the positive sequence terminal voltage in Volts, dq reference frame + Edq = CZero, + iterm2 = CZero, + iterm0 = CZero; + double vbase = 0.0, + ibase = 0.0, + zbase = 0.0, + mbase = 0.0, + theta = 0.0; // This is the angular reference used to convert from/from abc/dq reference frames + polar vtermll = ctopolar(CZero); + + + //complex vsorce, isorce, vsorcepu, isorcepu, zsorce, zsorcepu; + + // Define bases + vbase = pGen->GenVars.kVGeneratorBase * 1000; // vbase LN in Volts + mbase = pGen->GenVars.kVArating * 1000.; // mbase in VA + ibase = mbase / (SQRT3 * vbase); // ibase in A + zbase = vbase * vbase / mbase; // zbase in Ohms + + // Update the rotation angle + theta = s[0]; + + zsorce = { pGen->GenVars.Zthev.re, pGen->GenVars.Zthev.im }; + zsorcepu = cdivreal(zsorce, zbase); + + // Calculate internal voltage source + this->ed = -this->fppq; + this->eq = this->fppd; + Edq = { this->ed, this->eq }; // Retrieve values in pu + vsorcepu = dq2seq(Edq, theta); + vsorce = cmulreal(vsorcepu, (vbase / SQRT3)); + + // Calculate isorcepu - this is the positive sequence current injection + isorce = cdiv(vsorce, zsorce); // In amps + + // Get positive sequence terminal voltage in Volts + vterm = pGen->GetVterminal(ActorID); // LN + ithev = cdiv(vterm, zsorce); + + //Iterminal = Isource - Ithevenin (current on Zthev); + iterm = csub(isorce, ithev); + I012[1] = cmulreal(iterm, -1.0); + + // Sanity check on total power out of generator + complex sgen = cmulreal(cmul(vterm, conjg(iterm)), 3); + + // iterm is the positive sequence current in Amps. + // Now need to calculate zero and negative sequence current at the terminals, then update Iterminal + + Phase2SymComp(&(pGen->Vterminal[0]), &V012[0]); + I012[2] = cdiv(V012[2], cmplx(0.0, pGen->GenVars.Xdpp)); // machine use Xd" + I012[0] = { 0.0,0.0 }; // Setting zero seq current here to zero but this will be recalculated as soon as we stop out of this function + + return I012; + } + + complex TGenrouObj::GetIsorce1(int ActorID) + { + complex I1; + I1 = cmulreal(this->isorcepu, ibase); + + return I1; + } + + complex TGenrouObj::GetIsorce2(int ActorID) + { + // nothing here yet + return complex(); + } + + double TGenrouObj::get_channel(int i) + { + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if (i < 1) + return result; // Someone goofed + switch (i) { + case 1: + result = this->spd; // speed in pu + break; + case 2: + result = this->s[0]; // ang in radians + break; + case 3: + result = this->ed; // ed in pu + break; + case 4: + result = this->pgen; // pgen in pu + break; + case 5: + result = this->qgen; // qgen in pu + break; + case 6: + result = this->pmech; // pmech in pu + break; + default: + break; + } + return result; + } + + String TGenrouObj::get_channel_header(int i) + { + String result; + switch (i) { + case 1: + result = "spd(pu)"; + break; + case 2: + result = " ang(rad)"; + break; + case 3: + result = " Ed(pu)"; + break; + case 4: + result = " pgen(pu)"; + break; + case 5: + result = " qgen(pu)"; + break; + case 6: + result = " pmech(pu)"; + break; + default: + break; + } + return result; + } + + int64_t TGenrouObj::get_number_channels() + { + return nchannels; + } + + double TGenrouObj::QuadraticSaturation(double &fppmag) + { + double satx = 0.0; // Incremental saturated voltage to be added to d and q axis + double avgflux = 0.0; + + avgflux = fppmag; // Average flux + + satx = this->bsat * pow((avgflux - this->asat), 2.0); + satx = satx / avgflux; + + return satx; + } + + //int64_t TGenrouObj::call_iterative_solver(void) + //{ + // /* + // * Build the Newton-Raphson solution to properly initialize model + // */ + // //KLUSystem* pSys; + + // // + // //cs *T{}; + // int *pTi, *pTj; + // double *pTx, *pb; + // int m, n, nzmax, values=0, triplet=0; + // int i; + // double se, efd=0; + + + + // //// Calculate saturation factor se + // double fppmag = 1.0; + // /**** fix this later ****/ + // /**** fix this later ****/ + // /**** fix this later ****/ + // /**** fix this later ****/ + // se = QuadraticSaturation(fppmag); + + // // Calculate Efd + + + // //m = number of rows, n=number of columns, nz=number of no zero entries + // m = 8; + // n = 8; + // nzmax = 24; + // + // // This is the jacobian in triplet format + // int Ti[] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7}; + // int Tj[] = { 0, 2, 5, 2, 5, 6, 0, 2, 6, 1, 3, 4, 3, 4, 7, 1, 4, 7, 1, 6, 7, 0, 6, 7 }; + // + // // 8x8 matrix -> A + // double Tx[] = { -1.0, (this->xpd - this->xppd) / (this->xpd - this->xl), (this->xppd - this->xl) / (this->xpd - this->xl), + // -1.0, 1.0, -1.0 * (this->xpd - this->xl), + // se, 1.0, (this->xd - this->xpd), + // 1.0, (this->xpq-this->xppd) / (this->xpq-this->xl), (this->xppd-this->xl) / (this->xpq-this->xl), + // -1.0, 1.0, (this->xpq-this->xl), + // se*(this->xq-this->xl)/(this->xd-this->xl), -1.0, (this->xq-this->xpq), + // 1.0, this->ra, -this->xppd, + // -1.0, this->xppd, this->ra}; + + // // Initialize unkowns basaed on preliminary initializion - this may not be needed + // this->fppd = this->fppd; + // this->fppq = this->fppq; + // this->fpd = this->s[3]; + // this->fpq = this->s[4]; + // this->epd = this->s[5]; + // this->epq = this->s[2]; + // this->id = this->id; + // this->iq = this->iq; + // + // // Calculate f(x) at the current operating point + // double num1, num2, den; + // num1 = this->xpd - this->xppd; + // num2 = this->xppd - this->xl; + // den = this->xpd - this->xl; + // double f1 = -this->fppd + this->fpd * (num1/den) + this->epq * (num2 / den); + // double f2 = this->epq - this->fpd - this->id * (this->xpd - this->xl); + // double f3 = -this->efd + this->fpd + (this->xd - this->xpd) * this->id + se * this->fppd; + + // num1 = this->xpq - this->xppd; + // num2 = this->xppd - this->xl; + // den = this->xpq - this->xl; + // double f4 = this->fppq + this->fpq * (num1 / den) +this->epd*(num2/den); + // double f5 = this->epd - this->fpq + this->iq * (den); + // double f6 = -this->epd + this->iq * (this->xq - this->xpq) + se * this->fppq * (this->xq - this->xl) / (this->xd - this->xl); + // double f7 = this->vtd + this->ra * this->id - this->xppd * this->iq; + // double f8 = this->vtq + this->ra * this->iq + this->xppd * this->id; + // + // double b[] = { -f1, -f2, -f3, -f4, -f5, -f6, -f7, -f8}; // Negative sign is needed per formulation + + // // Example + // //int Ti[] = { 0, 0, 1, 1 }; + // //int Tj[] = { 0, 1, 0, 1 }; + // //double Tx[] = { 5.0, -3.0, 2.0, -1.0 }; + // //double b[] = { 1.0, 1.0 }; + // //m = 2; + // //n = 2; + // //nzmax = 4; + // + // //// Load arrays into cs triplet matrix + // + // // Send all data in for the solve and return the solution on array b + // pTi = Ti; + // pTj = Tj; + // pTx = Tx; + // pb = b; + + // // Dump matrices to file for debuggin in matlab or python + // ofstream myfile; + // myfile.open("D:\\Projects-D\\INDUCES\\Examples\\Matrix\\matrix.csv"); + // // Dump row indices + // for (i = 0; i < nzmax; i++) { + // myfile << Ti[i] << " "; + // } + // myfile << endl; + // // Dump column indices + // for (i = 0; i < nzmax; i++) { + // myfile << Tj[i] << " "; + // } + // myfile << endl; + // // Dump entries + // for (i = 0; i < nzmax; i++) { + // myfile << Tx[i] << " "; + // } + // myfile << endl; + // // Dump b array + // for (i = 0; i < n; i++) { + // myfile << b[i] << " "; + // } + // myfile << endl; + // myfile.close(); + + + + + // //i = CSparse_solve(m, n, nzmax, pTi, pTj, pTx, pb); + + // return 0; + //} + + void TGenrouObj::sample(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TGenrouObj::DoPendingAction(int Code, int ProxyHdl, int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TGenrouObj::Reset(int ActorID) { + // Empty for now, but need to see if anything needs to be added here + } + + void TGenrouObj::InitPropertyValues(int ArrayOffset) { + Set_PropertyValue(1,""); // bus_name; + Set_PropertyValue(2,""); // gen_name; + Set_PropertyValue(3,"7.0"); // tpdo; + Set_PropertyValue(4,"0.030"); // tppdo; + Set_PropertyValue(5,"0.75"); // tpqo; + Set_PropertyValue(6,"0.05"); // tppqo; + Set_PropertyValue(7,"3.0"); // h; + Set_PropertyValue(8,"0.0"); // d; + Set_PropertyValue(9,"2.1"); // xd; + Set_PropertyValue(10,"2.0"); // xq; + Set_PropertyValue(11,"0.2"); // xpd; + Set_PropertyValue(12,"0.5"); // xpq; + Set_PropertyValue(13,"0.18"); // xppd; + Set_PropertyValue(14,"0.15"); // xl; + Set_PropertyValue(15,"0.05"); // s1; + Set_PropertyValue(16,"0.3"); // s12; + Set_PropertyValue(17,"0.0"); // ra; + Set_PropertyValue(18,"0.0"); // rcomp; + Set_PropertyValue(19,"0.0"); // xcomp; + inherited::InitPropertyValues(NumPropsThisClass); + } + + + double TGenrouObj::get_efield() + { + return this->efd; + } + + + double TGenrouObj::get_pmech() + { + return this->pmech; + } + + double TGenrouObj::get_dspd() + { + return this->dspd; + } + + double TGenrouObj::get_plast() + { + return this->plast*this->mbase/1000.0; + } + + double TGenrouObj::get_qlast() + { + return this->qlast*this->mbase/1000.0; + } + + /*void TGenrouObj::MakePosSequence(int ActorID) { + + }*/ + + /*void TGenrouObj::CalcYPrim(int ActorID){ + + }*/ + + /*void TGenrouObj::RecalcElementData(int ActorID){ + + }*/ + + /*void TGenrouObj::GetCurrents(Ucomplex::pComplexArray Curr, int ActorID) { + + }*/ + + /*void TGenrouObj::GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID) { + + }*/ + + + /* void TGenrouObj::DumpProperties(System::TTextRec& f, bool Complete) { + + }*/ +} diff --git a/OpenDSSC/GenModels/genrou.h b/OpenDSSC/GenModels/genrou.h new file mode 100644 index 0000000..2556ef5 --- /dev/null +++ b/OpenDSSC/GenModels/genrou.h @@ -0,0 +1,187 @@ +#ifndef GENROU_H +#define GENROU_H + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "CktElement.h" +#include "Bus.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" +//#include "genrou.h" + + +using namespace std; + +namespace Genrou +{ + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + /* + Change Log + 8/22/2022 - B. Leonardi - created genrou model + + */ + + /* + A genrou is a class that represents a round rotor model of a synchronous generator. + + It can be invoked as follows in the input file: + + New Genrou.Name=myname generator=Generator.name terminal=[ 1|2|...] Parameter_List + + The controlled generator must already be declared and exist in the case. + */ + + + + class TGenrou : public ControlClass::TControlClass { + public: + typedef ControlClass::TControlClass inherited; + private: + + protected: + void DefineProperties(); + int MakeLike(const String GenrouName); + public: + TGenrou(); + virtual ~TGenrou(); + int Edit(int ActorID); // uses global DSS parser + int NewObject(const String ObjName); + int FindGenerator(); + + }; + + class TGenrouObj : public ControlElem::TControlElem { + + public: + typedef ControlElem::TControlElem inherited; + + + public: + int64_t nstates; + int64_t nchannels; + // States, stored states and state derivatives + double* s, * ss, * ds, * dss; + vector ps; + // Parameters + double tpdo; // d-axis transient rotor time constant, s + double tppdo; // d-axis subtransient rotor time constant, s + double tpqo; // q-axis transient time constant, s + double tppqo; // q-axis subtransient time constant, s + double h; // inertia constant, sec + double d; // damping factor, pu + double xd; // d-axis synchornous reactance, pu + double xq; // q-axis synchronous reactance, pu + double xpd; // d-axis transient reactance, pu + double xpq; // q-axis transient reactance, pu + double xppd; // d-axis transient reactance, pu + double xl; // leakage reactance, pu + double s1; // saturation factor at 1pu flux + double s12; // saturation factor at 1.2 pu flux + double ra; // armature or stator resistance, pu + double rcomp; // compounding resitance for voltage control, pu (currently not implemented) + double xcomp; // compounding reactance for voltage control, pu (currently not implemented) + // Variables + double pmech, tm; + double pgen, qgen, te; + double dspd; + double ang; + double spd; + double w0; + double ed; // internal voltage source direct axis voltage in pu + double eq; // internal voltage source quadrature axis voltage in pu + double id; // internal current source direct axis current in pu + double iq; // internal current source direct axis current in pu + double asat, bsat; // saturation parameters + double efd; // Field voltage in pu + double ladifd; // Field current in pu + double fq, fpq, fppq; // Steady state, transient and subtransient flux on q axis + double fd, fpd, fppd; // Steady state, transient and subtransient flux on d axis + double epd, epq; // Transient direct and quadrature axis voltages + double vtd, vtq; // Terminal voltage in dq axis and pu + double plast, qlast; // Last pgen and qgen from time domain simulation + + complex zsorce, zsorcepu; + complex vsorce, vsorcepu; + complex isorce, isorcepu; + complex isorce2, isorce2pu; + complex iterminit[3]; + // Bases + double vbase, mbase, ibase; + + int FListSize; + String gen_name; // Name of generator model is connected to + String bus_name; // Name of bus where model is connected to + Generator::TGeneratorObj* pGen; // Pointer to controlled generator + std::vector cBuffer; // Complexarray buffer + + + public: + TGenrouObj(DSSClass::TDSSClass* ParClass, const String GenrouName); + TGenrouObj(); + virtual ~TGenrouObj(); + void sample(int ActorID); // Sample control quantities and set action times in Control Queue + void DoPendingAction(int Code, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + void Reset(int ActorID); // Reset to initial defined state + void InitPropertyValues(int ArrayOffset); // Initialize property values + void LoadDefaultParameters(); // Loads default model parameters + virtual int InitializeStates(int ActorID); // Initializes values of states based on steady state power flow solution + virtual int CalculateRate(int ActorID); // Claculate state derivatives prior to integration + virtual int StateIntegration(int ActorID); // Calls method to integrate states + virtual int StateIntegration_correction(int ActorID); // Calls method to integrate states when predictor corrector method is used + virtual complex* CalculateIsorce(int ActorID, complex* I012); // Calculates current injections from model for network solution + virtual complex GetIsorce1(int ActorID); // Get positive sequence current + virtual complex GetIsorce2(int ActorID); // Get negative sequence current + virtual double get_channel(int channel_num); // Gets channel values from model + virtual String get_channel_header(int channel_num); // Gets channel header names in model + virtual int64_t get_number_channels(); // Gets number of channels in model + double QuadraticSaturation(double &fppmag); // Implements quadratic saturation in genrou + //int64_t call_iterative_solver(void); // Implements Newton-Raphson to initialize model + virtual double get_efield(); // Returns calculated efield, primarily for initialization + virtual double get_pmech(); + virtual double get_dspd(); + + // + virtual double get_plast(); + virtual double get_qlast(); + + + /* + * + * These functions may not be needed so they have been commented out for the time being + * + */ + + // void MakePosSequence(int ActorID); // Make a positive Sequence Model + // virtual void RecalcElementData(int ActorID); + // virtual void CalcYPrim(int ActorID); // Always Zero for a GenDispatcher + // void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + // void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + // void DumpProperties(System::TTextRec& f, bool Complete); + // bool MakeGenList(); + // void SetMachineModel(); + + }; + + extern TGenrouObj* ActiveGenrouObj; + +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Genrou; +#endif + +#endif // !GENROU_H + diff --git a/OpenDSSC/General/CNData.cpp b/OpenDSSC/General/CNData.cpp new file mode 100644 index 0000000..232ce62 --- /dev/null +++ b/OpenDSSC/General/CNData.cpp @@ -0,0 +1,367 @@ + +#pragma hdrstop + +#include "CNData.h" +#include "ParserDel.h" +#include "DSSGlobals.h" +#include "DSSClassDefs.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LineUnits.h" + +using namespace std; +using namespace Arraydef; +using namespace CableData; +using namespace Command; +using namespace ConductorData; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineUnits; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; + +namespace CNData +{ + +TCNDataObj::TCNDataObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TCNDataObj::TCNDataObj(String ClassName) : inherited(ClassName) {} +TCNDataObj::TCNDataObj() {} + + +const int NumPropsThisClass = 4; // Creates superstructure for all Line objects + +TCNData::TCNData() +{ + ; + Class_Name = "CNData"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +TCNData::~TCNData() +{ + // inherited::Destroy(); +} + + +void TCNData::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + (PropertyName)[1 - 1] = "k"; + (PropertyName)[2 - 1] = "DiaStrand"; + (PropertyName)[3 - 1] = "GmrStrand"; + (PropertyName)[4 - 1] = "Rstrand"; + (PropertyHelp)[1 - 1] = "Number of concentric neutral strands; default is 2"; + (PropertyHelp)[2 - 1] = "Diameter of a concentric neutral strand; same units as core conductor radius; no default."; + (PropertyHelp)[3 - 1] = "Geometric mean radius of a concentric neutral strand; same units as core conductor GMR; defaults to 0.7788 * CN strand radius."; + (PropertyHelp)[4 - 1] = "AC resistance of a concentric neutral strand; same units as core conductor resistance; no default."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +int TCNData::NewObject(const String ObjName) +{ + int result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TCNDataObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +int TCNData::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveConductorDataObj = (TConductorDataObj*) ElementList.Get_Active(); + ActiveDSSObject[ActiveActor] = ActiveConductorDataObj; + /*# with TCNDataObj(ActiveConductorDataObj) do */ + { + auto with0 = ((TCNDataObj*) ActiveConductorDataObj); + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 101); + break; + case 1: + with0->FkStrand = Parser[ActorID]->MakeInteger_(); + break; + case 2: + with0->FDiaStrand = Parser[ActorID]->MakeDouble_(); + break; + case 3: + with0->FGmrStrand = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->FRStrand = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + ClassEdit(ActiveConductorDataObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Set defaults*/ + switch(ParamPointer) + { + case 2: + if(with0->FGmrStrand <= 0.0) + with0->FGmrStrand = 0.7788 * 0.5 * with0->FDiaStrand; + break; + default: + ; + break; + } + + /*Check for critical errors*/ + switch(ParamPointer) + { + case 1: + if(with0->FkStrand < 2) + DoSimpleMsg(String("Error: Must have at least 2 concentric neutral strands for CNData ") + with0->get_Name(), 999); + break; + case 2: + if(with0->FDiaStrand <= 0.0) + DoSimpleMsg(String("Error: Neutral strand diameter must be positive for CNData ") + with0->get_Name(), 999); + break; + case 3: + if(with0->FGmrStrand <= 0.0) + DoSimpleMsg(String("Error: Neutral strand GMR must be positive for CNData ") + with0->get_Name(), 999); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; +} + +int TCNData::MakeLike(const String CNName) +{ + int result = 0; + TCNDataObj* OtherData = nullptr; + int i = 0; + result = 0; + OtherData = ((TCNDataObj*) Find(CNName)); + if(OtherData != nullptr) + /*# with TCNDataObj(ActiveConductorDataObj) do */ + { + auto with0 = ((TCNDataObj*) ActiveConductorDataObj); + int stop = 0; + with0->FkStrand = OtherData->FkStrand; + with0->FDiaStrand = OtherData->FDiaStrand; + with0->FGmrStrand = OtherData->FGmrStrand; + with0->FRStrand = OtherData->FRStrand; + ClassMakeLike(OtherData); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherData->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Concentric Neutral MakeLike: \"") + CNName + + "\" Not Found.", 102); + return result; +} + +int TCNData::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TCNData.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TCNData::Get_Code() +{ + String result; + result = ((TCNDataObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active CNData + +void TCNData::Set_Code(const String Value) +{ + TCNDataObj* CNDataObj = nullptr; + ActiveConductorDataObj = nullptr; + CNDataObj = (TCNDataObj*) ElementList.Get_First(); + while(CNDataObj != nullptr) + { + if(CompareText(CNDataObj->get_Name(), Value) == 0) + { + ActiveConductorDataObj = CNDataObj; + return; + } + CNDataObj = (TCNDataObj*) ElementList.Get_Next(); + } + DoSimpleMsg(String("CNData: \"") + Value + "\" not Found.", 103); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TCNData Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TCNDataObj::TCNDataObj(TDSSClass* ParClass, const String CNDataName) + : inherited(ParClass, CNDataName), + FkStrand(2), + FDiaStrand(-1.0), + FGmrStrand(-1.0), + FRStrand(-1.0) +{ + Set_Name(LowerCase(CNDataName)); + DSSObjType = ParClass->DSSClassType; + InitPropertyValues(0); +} + +TCNDataObj::~TCNDataObj() +{ + // inherited::Destroy(); +} + +//------------------------------------------------------------------------------------------- + +int TCNDataObj::get_FkStrand() +{ + return FkStrand; +} + +//------------------------------------------------------------------------------------------- + +double TCNDataObj::get_FDiaStrand() +{ + return FDiaStrand; +} + +//------------------------------------------------------------------------------------------- + +double TCNDataObj::get_FGmrStrand() +{ + return FGmrStrand; +} + +//------------------------------------------------------------------------------------------- + +double TCNDataObj::get_FRStrand() +{ + return FRStrand; +} + +//------------------------------------------------------------------------------------------- + + +void TCNDataObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = NumPropsThisClass, i = 1; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, L'='); } + switch(i) + { + case 1: + System::WriteLn(f, Format("%d", FkStrand)); + break; + case 2: + System::WriteLn(f, Format("%.6g", FDiaStrand)); + break; + case 3: + System::WriteLn(f, Format("%.6g", FGmrStrand)); + break; + case 4: + System::WriteLn(f, Format("%.6g", FRStrand)); + break; + default: + ; + break; + } + } + } +} + +String TCNDataObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = Format("%d", FkStrand); + break; + case 2: + result = Format("%.6g", FDiaStrand); + break; + case 3: + result = Format("%.6g", FGmrStrand); + break; + case 4: + result = Format("%.6g", FRStrand); + break; + default: + result = inherited::GetPropertyValue(Index - NumPropsThisClass); + break; + } + return result; +} + +int TCNDataObj::GetNumProperties(int ArrayOffset) +{ + return inherited::GetNumProperties(NumPropsThisClass + ArrayOffset); +} + +void TCNDataObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"2"); + Set_PropertyValue(2,"-1"); + Set_PropertyValue(3,"-1"); + Set_PropertyValue(4,"-1"); + inherited::InitPropertyValues(ArrayOffset + NumPropsThisClass); +} + + + + +} // namespace CNData + + + + + diff --git a/OpenDSSC/General/CNData.h b/OpenDSSC/General/CNData.h new file mode 100644 index 0000000..0f5dd61 --- /dev/null +++ b/OpenDSSC/General/CNData.h @@ -0,0 +1,84 @@ +#ifndef CNDataH +#define CNDataH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "ConductorData.h" +#include "CableData.h" + + +namespace CNData +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TCNData : public CableData::TCableData +{ + friend class TCNDataObj; +public: + typedef CableData::TCableData inherited; +//private: + String Get_Code(); // Returns active line code String + void Set_Code(const String Value); // sets the active CNData +//protected: + void DefineProperties(); + virtual int MakeLike(const String CNName); +public: + TCNData(); + virtual ~TCNData(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TCNDataObj : public CableData::TCableDataObj +{ + friend class TCNData; +public: + typedef CableData::TCableDataObj inherited; +//private: + int FkStrand; + double FDiaStrand; + double FGmrStrand; + double FRStrand; +public: + + int get_FkStrand(); + double get_FDiaStrand(); + double get_FGmrStrand(); + double get_FRStrand(); + + TCNDataObj(DSSClass::TDSSClass* ParClass, const String CNDataName); + virtual ~TCNDataObj(); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int GetNumProperties(int ArrayOffset); + TCNDataObj(DSSClass::TDSSClass* ParClass); + TCNDataObj(String ClassName); + TCNDataObj(); +}; + + +} // namespace CNData + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CNData; +#endif + +#endif // CNDataH + + + + + diff --git a/OpenDSSC/General/CNLineConstants.cpp b/OpenDSSC/General/CNLineConstants.cpp new file mode 100644 index 0000000..ad36bfe --- /dev/null +++ b/OpenDSSC/General/CNLineConstants.cpp @@ -0,0 +1,249 @@ + +#pragma hdrstop + +#include "CNLineConstants.h" +#include +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace CableConstants; +using namespace LineConstants; +using namespace LineUnits; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace CNLineConstants +{ + +TCNLineConstants::TCNLineConstants() {} + + + +int TCNLineConstants::Get_kStrand(int i) +{ + int result = 0; + result = FkStrand[i - 1]; + return result; +} + +double TCNLineConstants::Get_DiaStrand(int i, int Units) +{ + double result = 0.0; + result = FDiaStrand[i - 1] * From_Meters(Units); + return result; +} + +double TCNLineConstants::Get_GmrStrand(int i, int Units) +{ + double result = 0.0; + result = FGmrStrand[i - 1] * From_Meters(Units); + return result; +} + +double TCNLineConstants::Get_RStrand(int i, int Units) +{ + double result = 0.0; + result = FRStrand[i - 1] * From_per_Meter(Units); + return result; +} + +void TCNLineConstants::Set_kStrand(int i, int Value) +{ + if((i > 0) && (i <= FNumConds)) + FkStrand[i - 1] = Value; +} + +void TCNLineConstants::Set_DiaStrand(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FDiaStrand[i - 1] = Value * To_Meters(Units); +} + +void TCNLineConstants::Set_GmrStrand(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FGmrStrand[i - 1] = Value * To_Meters(Units); +} + +void TCNLineConstants::Set_RStrand(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FRStrand[i - 1] = Value * To_per_Meter(Units); +} +/*Compute base Z and YC matrices in ohms/m for this frequency and earth impedance*/ + +void TCNLineConstants::Calc(double f) +{ + complex Zi = {}; + complex Zspacing = {}; + bool PowerFreq = false; + complex LFactor = {}; + int i = 0; + int j = 0; + double Dij = 0.0; + double Yfactor = 0.0; + int ReducedSize = 0; + int n = 0; + int idxi = 0; + int idxj = 0; + TcMatrix* Zmat = nullptr; + TcMatrix* Ztemp = nullptr; + double ResCN = 0.0; + double RadCN = 0.0; + double GmrCN = 0.0; + double Denom = 0.0; + double RadIn = 0.0; + double RadOut = 0.0; + int stop = 0; + Set_Frequency(f); // this has side effects + if(ASSIGNED(FZreduced)) + { + ReducedSize = FZreduced->get_Norder(); + delete FZreduced; + } + else + ReducedSize = 0; + if(ASSIGNED(FYCreduced)) + delete FYCreduced; + FZreduced = nullptr; + FYCreduced = nullptr; + FZmatrix->Clear(); + FYCmatrix->Clear(); + + // add concentric neutrals to the end of conductor list; they are always reduced + n = FNumConds + FNumPhases; + Zmat = new TcMatrix(n); + + /*For less than 1 kHz use GMR to better match published data*/ + LFactor = cmplx(0.0, Fw * mu0 / DSSGlobals::TwoPi); + if((f < 1000.0) && (f > 40.0)) + PowerFreq = true; + else + PowerFreq = false; + + // Self Impedances - CN cores and bare neutrals + for(stop = FNumConds, i = 1; i <= stop; i++) + { + Zi = Get_Zint(i); + if(PowerFreq) // for less than 1 kHz, use published GMR + { + Zi.im = 0.0; + Zspacing = cmulreal(LFactor, log(1.0 / FGMR[i - 1])); // use GMR + } + else + { + Zspacing = cmulreal(LFactor, log(1.0 / Fradius[i - 1])); + } + Zmat->SetElement(i, i, cadd(Zi, cadd(Zspacing, Get_Ze(i, i)))); + } + + // CN self impedances + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + ResCN = FRStrand[i - 1] / FkStrand[i - 1]; + RadCN = 0.5 * (FDiaCable[i - 1] - FDiaStrand[i - 1]); + GmrCN = pow(FGmrStrand[i - 1] * FkStrand[i - 1] * pow(RadCN, FkStrand[i - 1] - 1.0), 1.0 / FkStrand[i - 1]); + Zspacing = cmulreal(LFactor, log(1.0 / GmrCN)); + Zi = cmplx(ResCN, 0.0); + idxi = i + FNumConds; + Zmat->SetElement(idxi, idxi, cadd(Zi, cadd(Zspacing, Get_Ze(i, i)))); + } + + // Mutual Impedances - between CN cores and bare neutrals + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + Zmat->SetElemsym(i, j, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + } + + // Mutual Impedances - CN to other CN, cores, and bare neutrals + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + int stop1 = 0; + idxi = i + FNumConds; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { // CN to other CN + idxj = j + FNumConds; + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + Zmat->SetElemsym(idxi, idxj, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + for(stop1 = FNumConds, j = 1; j <= stop1; j++) + { // CN to cores and bare neutrals + idxj = j; + RadCN = 0.5 * (FDiaCable[i - 1] - FDiaStrand[i - 1]); + if(i == j) // CN to its own phase core + { + Dij = RadCN; + } + else + // CN to another phase or bare neutral + { + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + Dij = pow(pow(Dij, (double) FkStrand[i - 1]) - pow(RadCN, (double) FkStrand[i - 1]), 1.0 / FkStrand[i - 1]); + } + Zmat->SetElemsym(idxi, idxj, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + } + + // reduce out the CN + while(Zmat->get_Norder() > FNumConds) + { + Ztemp = Zmat->Kron(Zmat->get_Norder()); + delete Zmat; + Zmat = Ztemp; + } + FZmatrix->CopyFrom(Zmat); + delete Zmat; + + // for shielded cables, build the capacitance matrix directly + // assumes the insulation may lie between semicon layers + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + Yfactor = DSSGlobals::TwoPi * E0 * FEpsR[i - 1] * Fw; // includes frequency so C==>Y + RadOut = 0.5 * FDiaIns[i - 1]; + RadIn = RadOut - FInsLayer[i - 1]; + Denom = log(RadOut / RadIn); + FYCmatrix->SetElement(i, i, cmplx(0.0, Yfactor / Denom)); + } + if(ReducedSize > 0) + Kron(ReducedSize); // Was reduced so reduce again to same size + + /*Else the Zmatrix is OK as last computed*/ + FRhoChanged = false; +} + +TCNLineConstants::TCNLineConstants(int NumConductors) + : inherited(NumConductors) +{ + FkStrand = new longInt[FNumConds]; + FDiaStrand = new double[FNumConds]; + FGmrStrand = new double[FNumConds]; + FRStrand = new double[FNumConds]; +} + +TCNLineConstants::~TCNLineConstants() +{ + free(FkStrand); + free(FDiaStrand); + free(FGmrStrand); + free(FRStrand); + // inherited; +} + + + + + +} // namespace CNLineConstants + + + + + diff --git a/OpenDSSC/General/CNLineConstants.h b/OpenDSSC/General/CNLineConstants.h new file mode 100644 index 0000000..292b358 --- /dev/null +++ b/OpenDSSC/General/CNLineConstants.h @@ -0,0 +1,62 @@ +#ifndef CNLineConstantsH +#define CNLineConstantsH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LineUnits.h" +#include "LineConstants.h" +#include "CableConstants.h" + +namespace CNLineConstants +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TCNLineConstants : public CableConstants::TCableConstants +{ +public: + typedef CableConstants::TCableConstants inherited; +//private: + Arraydef::pIntegerArray FkStrand; + Arraydef::pDoubleArray FDiaStrand; + Arraydef::pDoubleArray FGmrStrand; + Arraydef::pDoubleArray FRStrand; + int Get_kStrand(int i); + double Get_DiaStrand(int i, int Units); + double Get_GmrStrand(int i, int Units); + double Get_RStrand(int i, int Units); + void Set_kStrand(int i, int Value); + void Set_DiaStrand(int i, int Units, double Value); + void Set_GmrStrand(int i, int Units, double Value); + void Set_RStrand(int i, int Units, double Value); +protected: +public: + virtual void Calc(double f); + TCNLineConstants(int NumConductors); + virtual ~TCNLineConstants(); + TCNLineConstants(); +}; + + +} // namespace CNLineConstants + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CNLineConstants; +#endif + +#endif // CNLineConstantsH + + + + + diff --git a/OpenDSSC/General/CableConstants.cpp b/OpenDSSC/General/CableConstants.cpp new file mode 100644 index 0000000..a8a60f3 --- /dev/null +++ b/OpenDSSC/General/CableConstants.cpp @@ -0,0 +1,192 @@ + +#pragma hdrstop + +#include +#include "CableConstants.h" + + +using namespace std; +using namespace Arraydef; +using namespace LineConstants; +using namespace LineUnits; +using namespace System; +using namespace Ucmatrix; + +namespace CableConstants +{ + +TCableConstants::TCableConstants() {} + + + +void TCableConstants::Kron(int Norder) +{ + TcMatrix* Ztemp = nullptr; + bool FirstTime = false; + int i = 0; + int j = 0; + Ztemp = FZmatrix; + FirstTime = true; + if((FFrequency >= 0.0) && (Norder > 0) && (Norder < FNumConds)) + { + int stop = 0; + if(ASSIGNED(FZreduced)) + delete FZreduced; + if(ASSIGNED(FYCreduced)) + delete FYCreduced; + while(Ztemp->get_Norder() > Norder) + { + FZreduced = Ztemp->Kron(Ztemp->get_Norder()); // Eliminate last row + if(!FirstTime) + delete Ztemp; // Ztemp points to intermediate matrix + Ztemp = FZreduced; + FirstTime = false; + } + // now copy part of FYCmatrix to FYCreduced + FYCreduced = new TcMatrix(Norder); + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + FYCreduced->SetElement(i, j, FYCmatrix->GetElement(i, j)); + } + } + } +} + +bool TCableConstants::ConductorsInSameSpace(String& ErrorMessage) +{ + bool result = false; + int i = 0; + int j = 0; + double Dij = 0.0; + double Ri = 0.0; + double Rj = 0.0; + int stop = 0; + result = false; + +/* Height of cable doesn't matter + Removed 5-25-2016 RcD + For i := 1 to FNumConds do Begin + if (FY^[i] >= 0.0) then Begin + Result := TRUE; + ErrorMessage := + Format('Cable %d height must be < 0. ', [ i ]); + Exit + End; + End; +*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + if(i <= FNumPhases) + Ri = Fradius[i - 1]; + else + Ri = 0.5 * FDiaCable[i - 1]; + for(stop1 = FNumConds, j = i + 1; j <= stop1; j++) + { + if(j <= FNumPhases) + Rj = Fradius[j - 1]; + else + Rj = 0.5 * FDiaCable[j - 1]; + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + if(Dij < (Ri + Rj)) + { + result = true; + ErrorMessage = Format("Cable conductors %d and %d occupy the same space.", i, j); + return result; + } + } + } + return result; +} + +double TCableConstants::Get_EpsR(int i) +{ + double result = 0.0; + result = FEpsR[i - 1]; + return result; +} + +double TCableConstants::Get_InsLayer(int i, int Units) +{ + double result = 0.0; + result = FInsLayer[i - 1] * From_Meters(Units); + return result; +} + +double TCableConstants::Get_DiaIns(int i, int Units) +{ + double result = 0.0; + result = FDiaIns[i - 1] * From_Meters(Units); + return result; +} + +double TCableConstants::Get_DiaCable(int i, int Units) +{ + double result = 0.0; + result = FDiaCable[i - 1] * From_Meters(Units); + return result; +} + +void TCableConstants::Set_EpsR(int i, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FEpsR[i - 1] = Value; +} + +void TCableConstants::Set_InsLayer(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FInsLayer[i - 1] = Value * To_Meters(Units); +} + +void TCableConstants::Set_DiaIns(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FDiaIns[i - 1] = Value * To_Meters(Units); +} + +void TCableConstants::Set_DiaCable(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FDiaCable[i - 1] = Value * To_Meters(Units); +} + +TCableConstants::TCableConstants(int NumConductors) + : inherited(NumConductors) +{ + FEpsR = new double[FNumConds]; + FInsLayer = new double[FNumConds]; + FDiaIns = new double[FNumConds]; + FDiaCable = new double[FNumConds]; + + for (int i = 0; i < FNumConds; ++i) + { + FEpsR[i] = 0; + FInsLayer[i] = 0; + FDiaIns[i] = 0; + FDiaCable[i] = 0; + } +} + +TCableConstants::~TCableConstants() +{ + delete[] FEpsR; + delete[] FInsLayer; + delete[] FDiaIns; + delete[] FDiaCable; + // inherited; +} + + + + + +} // namespace CableConstants + + + + + diff --git a/OpenDSSC/General/CableConstants.h b/OpenDSSC/General/CableConstants.h new file mode 100644 index 0000000..1bae715 --- /dev/null +++ b/OpenDSSC/General/CableConstants.h @@ -0,0 +1,63 @@ +#ifndef CableConstantsH +#define CableConstantsH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LineUnits.h" +#include "LineConstants.h" +#include "d2c_structures.h" + +namespace CableConstants +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TCableConstants : public LineConstants::TLineConstants +{ +public: + typedef LineConstants::TLineConstants inherited; +//private: + double Get_EpsR(int i); + double Get_InsLayer(int i, int Units); + double Get_DiaIns(int i, int Units); + double Get_DiaCable(int i, int Units); + void Set_EpsR(int i, double Value); + void Set_InsLayer(int i, int Units, double Value); + void Set_DiaIns(int i, int Units, double Value); + void Set_DiaCable(int i, int Units, double Value); +//protected: + Arraydef::pDoubleArray FEpsR; + Arraydef::pDoubleArray FInsLayer; + Arraydef::pDoubleArray FDiaIns; + Arraydef::pDoubleArray FDiaCable; +public: + virtual bool ConductorsInSameSpace(String& ErrorMessage); + virtual void Kron(int Norder); // don't reduce Y, it has zero neutral capacitance + TCableConstants(int NumConductors); + virtual ~TCableConstants(); + TCableConstants(); +}; + + +} // namespace CableConstants + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CableConstants; +#endif + +#endif // CableConstantsH + + + + + diff --git a/OpenDSSC/General/CableData.cpp b/OpenDSSC/General/CableData.cpp new file mode 100644 index 0000000..88850a9 --- /dev/null +++ b/OpenDSSC/General/CableData.cpp @@ -0,0 +1,274 @@ + +#pragma hdrstop + +#include "CableData.h" +#include "ParserDel.h" +#include "DSSGlobals.h" +#include "DSSClassDefs.h" + +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LineUnits.h" + +using namespace std; +using namespace Arraydef; +using namespace ConductorData; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineUnits; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; + +namespace CableData +{ + +TCableDataObj::TCableDataObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TCableDataObj::TCableDataObj(String ClassName) : inherited(ClassName) {} +TCableDataObj::TCableDataObj() {} + + // Creates superstructure for all Line objects + +TCableData::TCableData() +{ + ; + DSSClassType = DSS_OBJECT; +} + +TCableData::~TCableData() +{ + // inherited::Destroy(); +} + + +void TCableData::CountProperties() +{ + NumProperties = NumProperties + NumCableClassProps; + inherited::CountProperties(); +} + +void TCableData::DefineProperties() +{ + (PropertyName)[ActiveProperty + 1] = "EpsR"; + (PropertyName)[ActiveProperty + 2] = "InsLayer"; + (PropertyName)[ActiveProperty + 3] = "DiaIns"; + (PropertyName)[ActiveProperty + 4] = "DiaCable"; + (PropertyHelp)[ActiveProperty + 1] = "Insulation layer relative permittivity; default is 2.3."; + (PropertyHelp)[ActiveProperty + 2] = "Insulation layer thickness; same units as radius; no default. " + "With DiaIns, establishes inner radius for capacitance calculation."; + (PropertyHelp)[ActiveProperty + 3] = "Diameter over insulation layer; same units as radius; no default. " + "Establishes outer radius for capacitance calculation."; + (PropertyHelp)[ActiveProperty + 4] = "Diameter over cable; same units as radius; no default."; + ActiveProperty = ActiveProperty + NumCableClassProps; + inherited::DefineProperties(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TCableData::ClassEdit(const void* activeObj, int ParamPointer) +{ + int result = 0; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TCableDataObj(activeObj) do */ + { + auto with0 = ((TCableDataObj*) activeObj); + switch(ParamPointer) + { + case 1: + with0->FEpsR = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + with0->FInsLayer = Parser[ActiveActor]->MakeDouble_(); + break; + case 3: + with0->FDiaIns = Parser[ActiveActor]->MakeDouble_(); + break; + case 4: + with0->FDiaCable = Parser[ActiveActor]->MakeDouble_(); + break; + default: + inherited::ClassEdit(activeObj, ParamPointer - NumCableClassProps); + break; + } + /*Check for critical errors*/ + switch(ParamPointer) + { + case 1: + if(with0->FEpsR < 1.0) + DoSimpleMsg(String("Error: Insulation permittivity must be greater than one for CableData ") + with0->get_Name(), 999); + break; + case 2: + if(with0->FInsLayer <= 0.0) + DoSimpleMsg(String("Error: Insulation layer thickness must be positive for CableData ") + with0->get_Name(), 999); + break; + case 3: + if(with0->FDiaIns <= 0.0) + DoSimpleMsg(String("Error: Diameter over insulation layer must be positive for CableData ") + with0->get_Name(), 999); + break; + case 4: + if(with0->FDiaCable <= 0.0) + DoSimpleMsg(String("Error: Diameter over cable must be positive for CableData ") + with0->get_Name(), 999); + break; + default: + ; + break; + } + } + return result; +} + +void TCableData::ClassMakeLike(const void* OtherObj) +{ + TCableDataObj* OtherCableData = nullptr; + OtherCableData = ((TCableDataObj*) OtherObj); + /*# with TCableDataObj(ActiveDSSObject[ActiveActor]) do */ + { + auto with0 = ((TCableDataObj*) ActiveDSSObject[ActiveActor]); + with0->FEpsR = OtherCableData->FEpsR; + with0->FInsLayer = OtherCableData->FInsLayer; + with0->FDiaIns = OtherCableData->FDiaIns; + with0->FDiaCable = OtherCableData->FDiaCable; + } + inherited::ClassMakeLike(OtherObj); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TConductorData Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TCableDataObj::TCableDataObj(TDSSClass* ParClass, const String CableDataName) + : inherited(ParClass, CableDataName), + FEpsR(2.3), + FInsLayer(-1.0), + FDiaIns(-1.0), + FDiaCable(-1.0) +{ + Set_Name(LowerCase(CableDataName)); + DSSObjType = ParClass->DSSClassType; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +TCableDataObj::~TCableDataObj() +{ + // inherited::Destroy(); +} + + +void TCableDataObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = NumCableClassProps, i = 1; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[GetNumProperties(0) - NumCableClassProps + i - 1]); System::Write(f, L'='); } + switch(i) + { + case 1: + System::WriteLn(f, Format("%.3g",FEpsR)); + break; + case 2: + System::WriteLn(f, Format("%.6g",FInsLayer)); + break; + case 3: + System::WriteLn(f, Format("%.6g",FDiaIns)); + break; + case 4: + System::WriteLn(f, Format("%.6g",FDiaCable)); + break; + default: + ; + break; + } + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TCableDataObj::get_FEpsR() +{ + return FEpsR; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TCableDataObj::get_FDiaIns() +{ + return FDiaIns; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TCableDataObj::get_FDiaCable() +{ + return FDiaCable; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TCableDataObj::get_FInsLayer() +{ + return FInsLayer; +} + + +String TCableDataObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = Format("%.3g", FEpsR); + break; + case 2: + result = Format("%.6g", FInsLayer); + break; + case 3: + result = Format("%.6g", FDiaIns); + break; + case 4: + result = Format("%.6g", FDiaCable); + break; + default: + result = inherited::GetPropertyValue(Index - NumCableClassProps); + break; + } + return result; +} + +int TCableDataObj::GetNumProperties(int ArrayOffset) +{ + return NumCableClassProps + ArrayOffset; +} + +void TCableDataObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(ArrayOffset + 1,"2.3"); + Set_PropertyValue(ArrayOffset + 2,"-1"); + Set_PropertyValue(ArrayOffset + 3,"-1"); + Set_PropertyValue(ArrayOffset + 4,"-1"); + inherited::InitPropertyValues(ArrayOffset + 4); +} + + + + +} // namespace CableData + + + + + diff --git a/OpenDSSC/General/CableData.h b/OpenDSSC/General/CableData.h new file mode 100644 index 0000000..bca2f43 --- /dev/null +++ b/OpenDSSC/General/CableData.h @@ -0,0 +1,82 @@ +#ifndef CableDataH +#define CableDataH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "ConductorData.h" + + +namespace CableData +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +const int NumCableClassProps = 4; + +class TCableData : public TConductorData +{ + friend class TCableDataObj; +public: + typedef ConductorData::TConductorData inherited; +private: +protected: + void CountProperties(); + void DefineProperties(); + int ClassEdit(const void* activeObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); +public: + TCableData(); + virtual ~TCableData(); +}; + +class TCableDataObj : public ConductorData::TConductorDataObj +{ + friend class TCableData; +public: + typedef ConductorData::TConductorDataObj inherited; +//private: + double FEpsR; + // next 3 use parent RadiusUnits + double FInsLayer; + double FDiaIns; + double FDiaCable; +public: + double get_FEpsR(); + double get_FDiaIns(); + double get_FDiaCable(); + double get_FInsLayer(); + + TCableDataObj(DSSClass::TDSSClass* ParClass, const String CableDataName); + virtual ~TCableDataObj(); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int GetNumProperties(int ArrayOffset); + TCableDataObj(DSSClass::TDSSClass* ParClass); + TCableDataObj(String ClassName); + TCableDataObj(); +}; + + +} // namespace CableData + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CableData; +#endif + +#endif // CableDataH + + + + + diff --git a/OpenDSSC/General/ConductorData.cpp b/OpenDSSC/General/ConductorData.cpp new file mode 100644 index 0000000..dc6e5ce --- /dev/null +++ b/OpenDSSC/General/ConductorData.cpp @@ -0,0 +1,528 @@ + +#pragma hdrstop + +#include "ConductorData.h" + +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; + + +namespace ConductorData +{ + +TConductorDataObj::TConductorDataObj(TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TConductorDataObj::TConductorDataObj(String ClassName) : inherited(ClassName) {} +TConductorDataObj::TConductorDataObj() {} + + +TConductorDataObj* ActiveConductorDataObj; +const string LineUnitsHelp = "{mi|kft|km|m|Ft|in|cm|mm} Default=none."; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TConductorData::TConductorData() +{ + ; + DSSClassType = DSS_OBJECT; +} + +TConductorData::~TConductorData() +{ + // inherited::Destroy(); +} + + +void TConductorData::CountProperties() +{ + NumProperties = NumProperties + NumConductorClassProps; + inherited::CountProperties(); +} + +void TConductorData::DefineProperties() +{ + (PropertyName)[ActiveProperty + 1 + 0] = "Rdc"; + (PropertyName)[ActiveProperty + 1 + 1] = "Rac"; + (PropertyName)[ActiveProperty + 1 + 2] = "Runits"; + (PropertyName)[ActiveProperty + 1 + 3] = "GMRac"; + (PropertyName)[ActiveProperty + 1 + 4] = "GMRunits"; + (PropertyName)[ActiveProperty + 1 + 5] = "radius"; + (PropertyName)[ActiveProperty + 1 + 6] = "radunits"; + (PropertyName)[ActiveProperty + 1 + 7] = "normamps"; + (PropertyName)[ActiveProperty + 1 + 8] = "emergamps"; + (PropertyName)[ActiveProperty + 1 + 9] = "diam"; + (PropertyName)[ActiveProperty + 1 + 10] = "Seasons"; + (PropertyName)[ActiveProperty + 1 + 11] = "Ratings"; + (PropertyName)[ActiveProperty + 1 + 12] = "Capradius"; + (PropertyHelp)[ActiveProperty + 1 + 0] = "dc Resistance, ohms per unit length (see Runits). Defaults to Rac/1.02 if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 1] = "Resistance at 60 Hz per unit length. Defaults to 1.02*Rdc if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 2] = "Length units for resistance: ohms per " "{mi|kft|km|m|Ft|in|cm|mm} Default=none."; + (PropertyHelp)[ActiveProperty + 1 + 3] = "GMR at 60 Hz. Defaults to .7788*radius if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 4] = "Units for GMR: " "{mi|kft|km|m|Ft|in|cm|mm} Default=none."; + (PropertyHelp)[ActiveProperty + 1 + 5] = "Outside radius of conductor. Defaults to GMR/0.7788 if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 6] = "Units for outside radius: " "{mi|kft|km|m|Ft|in|cm|mm} Default=none."; + (PropertyHelp)[ActiveProperty + 1 + 7] = "Normal ampacity, amperes. Defaults to Emergency amps/1.5 if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 8] = "Emergency ampacity, amperes. Defaults to 1.5 * Normal Amps if not specified."; + (PropertyHelp)[ActiveProperty + 1 + 9] = "Diameter; Alternative method for entering radius."; + (PropertyHelp)[ActiveProperty + 1 + 10] = "Defines the number of ratings to be defined for the wire, to be used only when defining seasonal ratings using the \"Ratings\" property."; + (PropertyHelp)[ActiveProperty + 1 + 11] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in lines."; + (PropertyHelp)[ActiveProperty + 12] = "Equivalent conductor radius for capacitance calcs. Specify this for bundled conductors. Defaults to same value as radius. Define Diam or Radius property first."; + ActiveProperty = ActiveProperty + NumConductorClassProps; + inherited::DefineProperties(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TConductorData::ClassEdit(const void* activeObj, int ParamPointer) +{ + int result = 0; + String Param; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TConductorDataObj(activeObj) do */ + { + auto with0 = ((TConductorDataObj*) activeObj); + switch(ParamPointer) + { + case 1: + with0->FRDC = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + with0->FR60 = Parser[ActiveActor]->MakeDouble_(); + break; + case 3: + with0->FResistanceUnits = GetUnitsCode(Parser[ActiveActor]->MakeString_()); + break; + case 4: + with0->FGMR60 = Parser[ActiveActor]->MakeDouble_(); + break; + case 5: + with0->FGMRUnits = GetUnitsCode(Parser[ActiveActor]->MakeString_()); + break; + case 6: + with0->Fradius = Parser[ActiveActor]->MakeDouble_(); + break; + case 7: + with0->FRadiusUnits = GetUnitsCode(Parser[ActiveActor]->MakeString_()); + break; + case 8: + with0->NormAmps = Parser[ActiveActor]->MakeDouble_(); + break; + case 9: + with0->EmergAmps = Parser[ActiveActor]->MakeDouble_(); + break; + case 10: + with0->Fradius = Parser[ActiveActor]->MakeDouble_() / 2.0; + break; + case 11: + { + with0->NumAmpRatings = Parser[ActiveActor]->MakeInteger_(); + with0->AmpRatings.resize(with0->NumAmpRatings); + } + break; + case 12: + { + with0->AmpRatings.resize(with0->NumAmpRatings); + Param = Parser[ActiveActor]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, ((pDoubleArray) &(with0->AmpRatings[0]))); + } + break; + case 13: + with0->Fcapradius60 = Parser[ActiveActor]->MakeDouble_(); + break; + default: + inherited::ClassEdit(activeObj, ParamPointer - NumConductorClassProps); + break; + } + /*Set defaults*/ + switch(ParamPointer) + { + case 1: + if(with0->FR60 < 0.0) + with0->FR60 = 1.02 * with0->FRDC; + break; + case 2: + if(with0->FRDC < 0.0) + with0->FRDC = with0->FR60 / 1.02; + break; + case 4: + { + if(with0->Fradius < 0.0) + with0->Fradius = with0->FGMR60 / 0.7788; // Default to cylindrical conductor + } + break; + case 5: + if(with0->FRadiusUnits == 0) + with0->FRadiusUnits = with0->FGMRUnits; + break; + case 6: case 10: + { + if(with0->FGMR60 < 0.0) + with0->FGMR60 = 0.7788 * with0->Fradius; + if(with0->Fcapradius60 < 0.0) + with0->Fcapradius60 = with0->Fradius; // default to radius + } + break; + case 7: + if(with0->FGMRUnits == 0) + with0->FGMRUnits = with0->FRadiusUnits; + break; + case 8: + if(with0->EmergAmps < 0.0) + with0->EmergAmps = 1.5 * with0->NormAmps; + break; + case 9: + if(with0->NormAmps < 0.0) + with0->NormAmps = with0->EmergAmps / 1.5; + break; + default: + ; + break; + } + /*Check for critical errors*/ + switch(ParamPointer) + { + case 4: + if(with0->Fradius == 0.0) + DoSimpleMsg(String("Error: Radius is specified as zero for ConductorData.") + with0->get_Name(), 999); + break; + case 6: + if(with0->FGMR60 == 0.0) + DoSimpleMsg(String("Error: GMR is specified as zero for ConductorData.") + with0->get_Name(), 999); + break; + default: + ; + break; + } + } + return result; +} + +//------------------------------------------------------------------------------------------------------ + +double TConductorDataObj::get_FRDC() +{ + return FRDC; +} + +//------------------------------------------------------------------------------------------------------ + +double TConductorDataObj::get_FR60() +{ + return FR60; +} + +//------------------------------------------------------------------------------------------------------ + +double TConductorDataObj::get_FGMR60() +{ + return FGMR60; +} + +//------------------------------------------------------------------------------------------------------ + +double TConductorDataObj::get_Fcapradius60() +{ + return Fcapradius60; +} + +//------------------------------------------------------------------------------------------------------ +double TConductorDataObj::get_Fradius() +{ + return Fradius; +} + +//------------------------------------------------------------------------------------------------------ + +int TConductorDataObj::get_FResistanceUnits() +{ + return FResistanceUnits; +} + +//------------------------------------------------------------------------------------------------------ + +int TConductorDataObj::get_FRadiusUnits() +{ + return FRadiusUnits; +} + +//------------------------------------------------------------------------------------------------------ + +int TConductorDataObj::get_FGMRUnits() +{ + return FGMRUnits; +} + +//------------------------------------------------------------------------------------------------------ + +void TConductorData::ClassMakeLike(const void* OtherObj) +{ + TConductorDataObj* OtherConductorData = nullptr; + OtherConductorData = ((TConductorDataObj*) OtherObj); + /*# with TConductorDataObj(ActiveDSSObject[ActiveActor]) do */ + { + auto with0 = ((TConductorDataObj*) ActiveDSSObject[ActiveActor]); + with0->FRDC = OtherConductorData->FRDC; + with0->FR60 = OtherConductorData->FR60; + with0->FResistanceUnits = OtherConductorData->FResistanceUnits; + with0->FGMR60 = OtherConductorData->FGMR60; + with0->Fcapradius60 = OtherConductorData->Fcapradius60; + with0->FGMRUnits = OtherConductorData->FGMRUnits; + with0->Fradius = OtherConductorData->Fradius; + with0->FRadiusUnits = OtherConductorData->FRadiusUnits; + with0->NormAmps = OtherConductorData->NormAmps; + with0->EmergAmps = OtherConductorData->EmergAmps; + } + // Inherited ClassMakeLike(OtherObj); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TConductorData Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TConductorDataObj::TConductorDataObj(TDSSClass* ParClass, const String ConductorDataName) + : inherited(ParClass), + FRDC(-1.0), + FR60(-1.0), + FGMR60(-1.0), + Fcapradius60(-1.0), + Fradius(0.0), + FGMRUnits(0), + FResistanceUnits(0), + FRadiusUnits(0), + NormAmps(0.0), + EmergAmps(0.0), + NumAmpRatings(0) +{ + Set_Name(LowerCase(ConductorDataName)); + DSSObjType = ParClass->DSSClassType; + Fradius = -1.0; + FGMRUnits = 0; + FResistanceUnits = 0; + FRadiusUnits = 0; + NormAmps = -1.0; + EmergAmps = -1.0; + /*Initialize dynamic array for ratings*/ + NumAmpRatings = 1; + AmpRatings.resize(NumAmpRatings); + AmpRatings[0] = NormAmps; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TConductorDataObj::~TConductorDataObj() +{ + // inherited::Destroy(); +} + + +void TConductorDataObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int j = 0; + int i = 0; + String TempStr; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = NumConductorClassProps, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[GetNumProperties(0) + i - 1]); Write(f, L'='); } + switch(i) + { + case 1: + WriteLn(f, Format("%.6g", FRDC)); + break; + case 2: + WriteLn(f, Format("%.6g", FR60)); + break; + case 3: + WriteLn(f, LineUnitsStr(FResistanceUnits)); + break; + case 4: + WriteLn(f, Format("%.6g", FGMR60)); + break; + case 5: + WriteLn(f, LineUnitsStr(FGMRUnits)); + break; + case 6: + WriteLn(f, Format("%.6g", Fradius)); + break; + case 7: + WriteLn(f, LineUnitsStr(FRadiusUnits)); + break; + case 8: + WriteLn(f, Format("%.6g", NormAmps)); + break; + case 9: + WriteLn(f, Format("%.6g", EmergAmps)); + break; + case 10: + WriteLn(f, Format("%.6g", get_Fradius() * 2.0)); + break; + case 11: + WriteLn(f, Format("%d", NumAmpRatings)); + break; + case 12: + { + int stop1 = 0; + TempStr = "["; + for(stop1 = NumAmpRatings, j = 1; j <= stop1; j++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + WriteLn(f, TempStr); + } + break; + case 13: + WriteLn(f, Format("%.6g", Fcapradius60)); + break; + default: + ; + break; + } + } + } +} + +String TConductorDataObj::GetPropertyValue(int Index) +{ + int j = 0; + String TempStr; + String result; + result = ""; + switch(Index) + { + case 1: + result = Format("%.6g", FRDC); + break; + case 2: + result = Format("%.6g", FR60); + break; + case 3: + result = LineUnitsStr(FResistanceUnits); + break; + case 4: + result = Format("%.6g", FGMR60); + break; + case 5: + result = LineUnitsStr(FGMRUnits); + break; + case 6: + result = Format("%.6g", Fradius); + break; + case 7: + result = LineUnitsStr(FRadiusUnits); + break; + case 8: + result = Format("%.6g", NormAmps); + break; + case 9: + result = Format("%.6g", EmergAmps); + break; + case 10: + result = Format("%.6g", Fradius * 2.0); + break; + case 11: + result = Format("%d", NumAmpRatings); + break; + case 12: + { + int stop1 = 0; + TempStr = "["; + for(stop1 = NumAmpRatings, j = 1; j <= stop1; j++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + result = TempStr; + } + break; + case 13: + result = Format("%.6g", Fcapradius60); + break; + default: + result = inherited::GetPropertyValue(GetNumProperties(0) + Index); + break; + } + return result; +} + +int TConductorDataObj::GetNumProperties(int ArrayOffset) +{ + DoErrorMsg(String("Something is Wrong. Got to base Conductor GetNumProperties for Object:") + CRLF + + PName + "." + LName, + "N/A", + "Should not be able to get here. Probable Programming Error.", 400); + + return 0; +} + +/* +function TConductorDataObj.GetPropertyValue(Index: Integer): String; +Var + i, j:Integer; + Tempstr : String; +begin + + Result := ''; + CASE Index of // Special cases + 1 : Result := Format('%.6g',[FRDC]); + 2 : Result := Format('%.6g',[FR60]); + 3 : Result := Format('%s',[LineUnitsStr(FresistanceUnits)]); + 4 : Result := Format('%.6g',[FGMR60]); + 5 : Result := Format('%s',[LineUnitsStr(FGMRUnits)]); + 6 : Result := Format('%.6g',[Fradius]); + 7 : Result := Format('%s',[LineUnitsStr(FRadiusUnits)]); + 8 : Result := Format('%.6g',[NormAmps]); + 9 : Result := Format('%.6g',[EmergAmps]); + 10 : Result := Format('%.6g',[radius*2.0]); + 11 : Result := Format('%d',[NumAmpRatings]); + 12 : Begin + TempStr := '['; + for j:= 1 to NumAmpRatings do + TempStr := TempStr + floattoStrf(AmpRatings[j-1],ffgeneral,8,4) + ','; + TempStr := TempStr + ']'; + Result := TempStr; + End; + 13: Result := Format('%.6g',[Fcapradius60]); + ELSE + Result := Inherited GetPropertyValue(index); + END; + +end; +*/ + +void TConductorDataObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(ArrayOffset + 1,"-1"); + Set_PropertyValue(ArrayOffset + 2,"-1"); + Set_PropertyValue(ArrayOffset + 3,"none"); + Set_PropertyValue(ArrayOffset + 4,"-1"); + Set_PropertyValue(ArrayOffset + 5,"none"); + Set_PropertyValue(ArrayOffset + 6,"-1"); + Set_PropertyValue(ArrayOffset + 7,"none"); + Set_PropertyValue(ArrayOffset + 8,"-1"); + Set_PropertyValue(ArrayOffset + 9,"-1"); + Set_PropertyValue(ArrayOffset + 10,"-1"); + Set_PropertyValue(ArrayOffset + 11,"1"); + Set_PropertyValue(ArrayOffset + 12,"[-1]"); + Set_PropertyValue(ArrayOffset + 13,"-1"); + inherited::InitPropertyValues(ArrayOffset + 13); +} + + + + +} // namespace ConductorData + + + + + diff --git a/OpenDSSC/General/ConductorData.h b/OpenDSSC/General/ConductorData.h new file mode 100644 index 0000000..4ad1d64 --- /dev/null +++ b/OpenDSSC/General/ConductorData.h @@ -0,0 +1,118 @@ +#ifndef ConductorDataH +#define ConductorDataH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Arraydef.h" +#include "ParserDel.h" + +#include "DSSClassDefs.h" +#include "Ucomplex.h" +#include "LineUnits.h" + + +namespace ConductorData +{ + +const int NumConductorClassProps = 13; + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*The ConductorData object is a general DSS object used by all circuits + as a reference for obtaining line impedances. + + The values are set by the normal New and Edit procedures for any DSS object. + + The values are retrieved by setting the Code Property in the ConductorData Class. + This sets the active ConductorData object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. + */ +enum ConductorChoice {Overhead, + ConcentricNeutral, + TapeShield, + unknown }; +typedef ConductorChoice* ConductorChoiceArray; +typedef ConductorChoiceArray pConductorChoiceArray; + +class TConductorData : public TDSSClass +{ + friend class TConductorDataObj; +public: + typedef TDSSClass inherited; +//private: +//protected: + void CountProperties(); + void DefineProperties(); + int ClassEdit(const void* activeObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); +public: + TConductorData(); + virtual ~TConductorData(); +}; + +class TConductorDataObj : public TDSSObject +{ + friend class TConductorData; +public: + typedef TDSSObject inherited; +//private: + double FRDC; + double FR60; + double FGMR60; + double Fcapradius60; // in case it is different than radius for cap calcs + double Fradius; + int FGMRUnits; + int FResistanceUnits; + int FRadiusUnits; +public: + double NormAmps; + double EmergAmps; + int NumAmpRatings; + Arraydef::TRatingsArray AmpRatings; + TConductorDataObj(TDSSClass* ParClass, const String ConductorDataName); + virtual ~TConductorDataObj(); + + double get_FRDC(); + double get_FR60(); + double get_FGMR60(); + double get_Fcapradius60(); + double get_Fradius(); + int get_FResistanceUnits(); + int get_FRadiusUnits(); + int get_FGMRUnits(); + + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int GetNumProperties(int ArrayOffset); + TConductorDataObj(TDSSClass* ParClass); + TConductorDataObj(String ClassName); + TConductorDataObj(); +}; +typedef TConductorDataObj* TConductorDataArray; +typedef std::vector pConductorDataArray; +extern TConductorDataObj* ActiveConductorDataObj; + + +} // namespace ConductorData + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ConductorData; +#endif + +#endif // ConductorDataH + + + + + diff --git a/OpenDSSC/General/DSSObject.cpp b/OpenDSSC/General/DSSObject.cpp new file mode 100644 index 0000000..dda41d5 --- /dev/null +++ b/OpenDSSC/General/DSSObject.cpp @@ -0,0 +1,206 @@ + +#pragma hdrstop + + +#include "DSSObject.h" + +#include "Utilities.h" + + +using namespace std; + +namespace DSSObject +{ + + TDSSObject::TDSSObject(TDSSClass* ParClass, string ClassName) : inherited(ParClass->get_myClass_name()) {} + TDSSObject::TDSSObject(string ClassName) : inherited(ClassName) {} + TDSSObject::TDSSObject() {} + + + void TDSSObject::ClearPropSeqArray() + { + int i = 0; + int stop = 0; + PropSeqCount = 0; + for (stop = ParentClass->NumProperties, i = 1; i <= stop; i++) + { + PrpSequence[i - 1] = 0; + } + } + + TDSSObject::TDSSObject(DSSClass::TDSSClass* ParClass) + : inherited(ParClass->get_myClass_name()), + PropSeqCount(0), + DSSObjType(0), + ParentClass(nullptr), + ClassIndex(0), + HasBeenSaved(false), + Flag(false) + { + ParentClass = ParClass; + FPropertyValue.resize(ParentClass->NumProperties); + PrpSequence.resize(ParentClass->NumProperties); + DSSObjType = 0; + HasBeenSaved = false; + } + + TDSSObject::~TDSSObject() + { + int i = 0; + int stop = 0; + /*for (stop = ParentClass->NumProperties, i = 1; i <= stop; i++) + { + FPropertyValue[i - 1] = ""; + }*/ + FPropertyValue.clear(); + PrpSequence.clear(); + //inherited::Destroy(); + } + + + void TDSSObject::DumpProperties(TTextRec& f, bool Complete) + { + System::WriteLn(f); + { System::Write(f, "New "); System::Write(f, Get_myPName()); System::Write(f, "."); System::WriteLn(f, get_Name()); } + } + + int TDSSObject::Edit(int ActorID) + { + int result = 0; + ParentClass->Set_Active(ClassIndex); + result = ParentClass->Edit(ActorID); + return result; + } + + string DSSObject::TDSSObject::GetPropertyValue(int Index) + { + string result; + result = FPropertyValue[Index - 1]; // Default Behavior for all DSS Objects + return result; + } + + String TDSSObject::Get_PropertyValue(int Index) + { + String result; + result = GetPropertyValue(Index); // This is virtual function that may call routine + return result; + } + + void TDSSObject::InitPropertyValues(int ArrayOffset) + { + Set_PropertyValue(ArrayOffset + 1,""); //Like Property + + // Clear propertySequence Array after initialization + ClearPropSeqArray(); + } + + void TDSSObject::SaveWrite(System::TTextRec& f) + { + int iProp = 0; + String Str; + bool LShpFlag = false; + bool NptsRdy = false; // Created to know the that object is loadshape + + /*Write only properties that were explicitly set in the + final order they were actually set*/ + LShpFlag = false; + NptsRdy = false; + /*# with ParentClass do */ + { + auto with0 = ParentClass; + if (ParentClass->get_myClass_name() == "LoadShape") + { + iProp = 1; + LShpFlag = true; + } + else + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + } + // The part above was created to guarantee that the npts property will be the + // first to be declared when saving LoadShapes + while (iProp > 0) + { + Str = Trim(String(Get_PropertyValue(iProp))); + if (CompareText(Str, "----") == 0) + Str = ""; // set to ignore this property + if (Str.length() > 0) + { + /*# with ParentClass do */ + { + auto with1 = ParentClass; + { Write(f, " "); Write(f, (with1->PropertyName)[(with1->RevPropertyIdxMap)[iProp - 1] - 1]); } + } + { Write(f, "="); Write(f, CheckForBlanks(Str)); } + } + if (LShpFlag) + { + iProp = GetNextPropertySet(0); // starts over + LShpFlag = false; // The npts is already processed + // Flag to not repeat it again + NptsRdy = true; + } + else + { + iProp = GetNextPropertySet(iProp); + if (NptsRdy) + { + if (iProp == 1) + iProp = GetNextPropertySet(iProp); + } + } + } + } + // Find next larger property sequence number + // return 0 if none found + + int TDSSObject::GetNextPropertySet(int Idx) + { + int result = 0; + int i = 0; + int smallest = 0; + int stop = 0; + smallest = 9999999; // some big number + result = 0; + if (Idx > 0) + Idx = PrpSequence[Idx - 1]; + for (stop = ParentClass->NumProperties, i = 1; i <= stop; i++) + { + if (PrpSequence[i - 1] > Idx) + { + if (PrpSequence[i - 1] < smallest) + { + smallest = PrpSequence[i - 1]; + result = i; + } + } + } + return result; + } + + void TDSSObject::Set_Name(const String Value) + { + + // If renamed, then let someone know so hash list can be updated; + if (Get_myLName().length() > 0) + ParentClass->ElementNamesOutOfSynch = true; + Set_myLName(Value); + } + + string TDSSObject::get_Name() + { + String result; + result = Get_myLName(); + return result; + } + + void TDSSObject::Set_PropertyValue(int Index, const String Value) + { + FPropertyValue[Index - 1] = Value; + + // Keep track of the order in which this property was accessed for Save Command + ++PropSeqCount; + PrpSequence[Index - 1] = PropSeqCount; + } + +} + diff --git a/OpenDSSC/General/DSSObject.h b/OpenDSSC/General/DSSObject.h new file mode 100644 index 0000000..43a32a7 --- /dev/null +++ b/OpenDSSC/General/DSSObject.h @@ -0,0 +1,70 @@ +#ifndef DSSObjectH +#define DSSObjectH + +#include "System.h" + +#include "Arraydef.h" +#include "NamedObject.h" +#include "DSSClass.h" +#include "Sysutils.h" + + +namespace DSSObject +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TDSSObject : public TNamedObject +{ +public: + typedef TNamedObject inherited; +//private: + std::string Get_PropertyValue(int Index); + void Set_PropertyValue(int Index, const String Value); + std::string get_Name(); + void Set_Name(const String Value); +//protected: + int PropSeqCount; + std::vector FPropertyValue; + std::vector PrpSequence; + int GetNextPropertySet(int Idx); +public: + int DSSObjType; // PD, PC, Monitor, CondCode, etc. + DSSClass::TDSSClass* ParentClass; + int ClassIndex; // Index into the class collection list + bool HasBeenSaved; + bool Flag; // General purpose Flag for each object don't assume inited + TDSSObject(DSSClass::TDSSClass* ParClass); + virtual ~TDSSObject(); + int Edit(int ActorID); // Allow Calls to edit from object itself + + /*Get actual values of properties*/ + virtual std::string GetPropertyValue(int Index); // Use dssclass.propertyindex to get index by name + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + void ClearPropSeqArray(); + TDSSObject(DSSClass::TDSSClass* ParClass, std::string ClassName); + TDSSObject(std::string ClassName); + TDSSObject(); +}; + + +} // namespace DSSObject + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSObject; +#endif + +#endif // DSSObjectH + + + + + diff --git a/OpenDSSC/General/DynamicExp.cpp b/OpenDSSC/General/DynamicExp.cpp new file mode 100644 index 0000000..4927e88 --- /dev/null +++ b/OpenDSSC/General/DynamicExp.cpp @@ -0,0 +1,805 @@ + +#pragma hdrstop + +#include "DynamicExp.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include +#include "Ucomplex.h" +#include "Utilities.h" +#include "LineUnits.h" +#include +#include "RPN.h" + +#include + +using namespace std; +using namespace Bus; +using namespace CapControlVars; +using namespace CapUserControl; +using namespace Capacitor; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace DynamicExp +{ + +TDynamicExpObj::TDynamicExpObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TDynamicExpObj::TDynamicExpObj(String ClassName) : inherited(ClassName) {} +TDynamicExpObj::TDynamicExpObj() {} + +TDynamicExp* DynamicExpClass = NULL; +TDynamicExpObj* ActiveDynamicExpObj = NULL; + + + +const int NumPropsThisClass = 6; +const string myOps[29] = { "dt", "=", "+", "-", "*", "/", "(", ")", ";", "[", "]", "sqr", "sqrt", "inv", "ln", "exp", "log10", "sin", + "cos", "tan", "asin", "acos", "atan", "atan2", "rollup", "rolldn", "swap", "pi", "^"}; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +TDynamicExp::TDynamicExp() // Creates superstructure for all DynamicExp objects +{ + Class_Name = "DynamicExp"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + DynamicExpClass = this; + SymComponentsChanged = false; + MatrixChanged = false; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +TDynamicExp::~TDynamicExp() +{ + // ElementList and CommandList freed in inherited destroy +// todo check: inherited::Destroy; +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +void TDynamicExp::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + PropertyName[0] = "nvariables"; + PropertyName[1] = "varnames"; + PropertyName[2] = "var"; + PropertyName[3] = "varidx"; + PropertyName[4] = "expression"; + PropertyName[5] = "Domain"; + PropertyHelp[0] = "(Int) Number of state variables to be considered in the differential equation."; + PropertyHelp[1] = "([String]) Array of strings with the names of the state variables."; + PropertyHelp[2] = "(String) Activates the state variable using the given name."; + PropertyHelp[3] = "(Int) read-only, returns the index of the active state variable."; + PropertyHelp[4] = "It is the differential expression using OpenDSS RPN syntax. The expression must be contained within brackets in case of having multiple equations, for example:" + CRLF + CRLF + "expression = \"[w dt = 1 M / (P_m D*w - P_e -) *]\""; + PropertyHelp[5] = "It is the domain for which the equation is defined, it can be one of [time*, dq]. By deafult, dynamic epxressions are defined in the time domain."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExp::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + //auto with0 = ActiveCircuit[ActiveActor]; + { + ActiveDSSObject[ActiveActor] = new TDynamicExpObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +void* TDynamicExp::Find(const String ObjName) +{ + void* result = NULL; + if ((ObjName.size() == 0) || (CompareText(ObjName, "none") == 0)) + result = NULL; + else + result = inherited::Find(ObjName); + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExp::Edit(int ActorID) +{ + int result = 0; + int idx = 0, ParamPointer = 0; + String ParamName, Param; + result = 0; + // continue parsing with contents of Parser + ActiveDynamicExpObj = (TDynamicExpObj*) ElementList.Get_Active(); + ActiveDSSObject[ActorID] = ActiveDynamicExpObj; + SymComponentsChanged = false; + MatrixChanged = false; + /*# with ActiveDynamicExpObj do */ + auto with0 = ActiveDynamicExpObj; + { + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ParamPointer++; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Object \"" + Class_Name + "." + with0->get_Name() + "\"", 50001); + break; + case 1: + { + ActiveDynamicExpObj->FNumvars = Parser[ActorID]->MakeInteger_(); // Use property value to force reallocations + } + break; + case 2: + { + InterpretTStringListArray(Param, ActiveDynamicExpObj->FvarNames); + // ensuring they are lower case + for (int stop = (ActiveDynamicExpObj->FvarNames.size() - 1), idx = 0; idx <= stop; idx++) + ActiveDynamicExpObj->FvarNames[idx] = LowerCase(ActiveDynamicExpObj->FvarNames[idx]); + } + break; + case 3: + { + with0->FActiveVar = LowerCase(Parser[ActorID]->MakeString_()); + with0->FVarIdx = FindInStrVector((&with0->FvarNames), with0->FActiveVar); + if (ActiveDynamicExpObj->FVarIdx < 0) + { + // Being here means that the given name doesn't exist + DoSimpleMsg(String("DynamicExp \"") + ActiveDynamicExpObj->FActiveVar + "\" not found.", 50001); + ActiveDynamicExpObj->FActiveVar = ""; + } + } + break; + case 5: + { + if (ActiveDynamicExpObj->InterpretDiffEq(Parser[ActorID]->MakeString_())) + DoSimpleMsg("There are errors in the differential equation.", 50003); + } + break; + case 6: + { + if (Parser[ActorID]->MakeString_() == "time") + ActiveDynamicExpObj->myDomain = 0; + else + ActiveDynamicExpObj->myDomain = 1; + } + break; + default: + ClassEdit(ActiveDynamicExpObj, ParamPointer - NumPropsThisClass); + } + /* + CASE ParamPointer OF + 1 : ; + END; + + */ + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExp::MakeLike(const String LineName) +{ + int result = 0; + TDynamicExpObj* OtherDynExpCode = NULL; + int i = 0; + result = 0; + /*See if we can find this DynamicExp code in the present collection*/ + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExp::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TDynamicExp.Init", -1); + result = 0; + return result; +} + + +String TDynamicExp::Get_Code() // Returns active line code string + +{ + String result; + result = ""; + return result; +} + + +void TDynamicExp::Set_Code(const String Value) // sets the active linecode + +{ + TDynamicExpObj* DynExpCodeObj = NULL; + ActiveDynamicExpObj = NULL; + DynExpCodeObj = (TDynamicExpObj*) ElementList.Get_First(); + while (DynExpCodeObj != NULL) + { + if (CompareText(DynExpCodeObj->get_Name(), Value) == 0) + { + ActiveDynamicExpObj = DynExpCodeObj; + return; + } + DynExpCodeObj = (TDynamicExpObj*) ElementList.Get_Next(); + } + DoSimpleMsg(String("DynamicExp: \"") + Value + "\" not Found.", 50004); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TDynamicExp Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +TDynamicExpObj::TDynamicExpObj(TDSSClass* ParClass, const String LineCodeName) + : inherited(ParClass), + FVarIdx(0), + FNumvars(0), + BaseFrequency(0.0), + myDomain(0) +{ + Set_Name(LowerCase(LineCodeName)); + DSSObjType = ParClass->DSSClassType; + FvarNames.resize( 0 ); + FNumvars = 20; + FActiveVar = ""; + FVarIdx = -1; + FvarNames.clear(); + FCmd.resize( 0 ); + FVarConst.resize( 0 ); + myDomain = 0; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/*Checks if the given string is a value calculated by the element using the eq model*/ + +bool TDynamicExpObj::Check_If_CalcValue(String myVal, int& myOp) +{ + bool result = false; + bool found = false; + String Val; + int idx = 0; + String ValNames[12/*# range 0..11*/]; + ValNames[0] = "p"; + ValNames[1] = "q"; + ValNames[2] = "vmag"; + ValNames[3] = "vang"; + ValNames[4] = "imag"; + ValNames[5] = "iang"; + ValNames[6] = "s"; + ValNames[7] = "p0"; + ValNames[8] = "q0"; + ValNames[9] = "edp"; + ValNames[10] = "kvdc"; + ValNames[11] = "mod"; + myOp = -1; + found = false; + Val = LowerCase(myVal); + for (int stop = /*# High( ValNames ) */ 11, idx = 0; idx <= stop; idx++) + { + if (Val == ValNames[idx]) + { + myOp = idx; + found = true; + break; + } + } + result = found; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +TDynamicExpObj::~TDynamicExpObj() +{ + FvarNames.clear(); + FVarConst.resize( 0 ); + // todo check: inherited::Destroy; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExpObj::Get_Closer_Op(String myExp, String& myOp, int& OpCode) +{ + int result = 0; + bool SetMark = false; // For validating special chars + + size_t myPos = 0; + int idx = 0; + result = 10000; + for (int stop = /*# High( myOps ) */ 28, idx = 0; idx <= stop; idx++) + { + myPos = myExp.find(myOps[idx]); + if ((((int) myPos) < result) && (myPos != String::npos)) + { + SetMark = true; + if (myOps[idx] == "-") // Verify in case it is a negative number + if (myExp[myPos + 1] != ' ') + SetMark = false; + if (SetMark) + { + result = (int) myPos; + myOp = myOps[idx]; + OpCode = idx; + } + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/*returns the index of the variable if it exists in the state variable list, +otherwise, it returns 50001 if the string entered is a numeric constant (dbl) +or -1 if the string entered is neither a numeric constant or state varaible*/ + + +int TDynamicExpObj::Get_Var_Idx(String myVar) +{ + int result = 0; + double dblval = 0.0; + int idx = 0; + dblval = 0.0; + result = -1; // error + for (int stop = (FvarNames.size() - 1), idx = 0; idx <= stop; idx++) + if (LowerCase(Trim(myVar)) == FvarNames[idx]) + { + result = idx; + break; + } + if (result < 0) + { + // so, it's not a state variable, maybe a constant + try + { + dblval = stod(myVar); + result = 50001; // returns this code to indicate that it is a constant + } + catch (...) + { + result = -1; // it's not a number + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +int TDynamicExpObj::Get_Out_Idx(String myVar) +/*returns the index of the variable if it exists in the state variable list, +and if it is an output (-50 in the next cell ot the FCmd automation array)*/ +{ + int result = 0; + double dblval = 0.0; + int CmdIdx = 0, idx = 0; + dblval = 0.0; + result = -1; // error + for (int stop = (FvarNames.size() - 1), idx = 0; idx <= stop; idx++) + if (LowerCase(myVar) == FvarNames[idx]) + { + // now, check if the index corresponds to an output + for (int stop = ( FCmd.size() - 1 ), CmdIdx = 0; CmdIdx <= stop; CmdIdx++) + { + if ((idx == FCmd[CmdIdx]) && (CmdIdx < (FCmd.size() - 1) ) ) + if (FCmd[CmdIdx + 1] == -50) + { + // Means that the variable found is an output, we can leave + result = idx; + break; + } + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +String TDynamicExpObj::Get_VarName(int myIdx) +{ + String result; + String diffstr; + DynSlot myProt; + + int mylen = 0, myCol = 0, myRow = 0; + myProt.resize(2); + mylen = myProt.size(); + myRow = floor(((double)myIdx) / ((double)mylen)); + myCol = myIdx - (myRow * mylen); + diffstr = ""; + if (myCol > 0) + { + diffstr = "d"; + if (myCol > 1) + diffstr = diffstr + to_string(myCol); + } + result = diffstr + FvarNames[myRow]; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +double TDynamicExpObj::Get_DynamicEqVal(int myIdx, std::vector * MemSpace) +{ + double result = 0.0; + int mylen = 0, myCol = 0, myRow = 0; + mylen = (*MemSpace)[0].size(); + myRow = floor(((double)myIdx) / ((double)mylen)); + myCol = myIdx - (myRow * mylen); + result = (*MemSpace)[myRow][myCol]; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +bool TDynamicExpObj::IsInitVal(int myCode) +{ + bool result = false; + result = false; + switch (myCode) + { + case 7: case 8: case 9: + result = true; + break; + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +void TDynamicExpObj::SolveEq(vector * MemSpace) +{ + int OutIdx = 0, idx = 0, NxtIdx = 0; + TRPNCalc RPN; + + OutIdx = -1; + for (int stop = ( FCmd.size() - 1 ), idx = 0; idx <= stop; idx++) + { + if ((idx + 1) < FCmd.size()) NxtIdx = idx + 1; + else NxtIdx = idx; + if ((FCmd[NxtIdx] == -50) || (FCmd[idx] == -50)) // it's the begining of an equation + { + if (FCmd[idx] != -50) // The index + { + if (OutIdx >= 0) // It's not the first equation + (*MemSpace)[OutIdx][1] = RPN.Get_X(); // Uploads value into memory space + OutIdx = FCmd[idx]; + } + } + else + { + switch (FCmd[idx]) + { + case -2: + RPN.Add(); + break; //Add + + case -3: + RPN.Subtract(); + break; //Sub + + case -4: + RPN.Multiply(); + break; //Mult + + case -5: + RPN.Divide(); + break; //Div + + case -11: + RPN.Square(); + break; //Sqr + + case -12: + RPN.Sqrt(); + break; //Sqrt + + case -13: + RPN.Inv(); + break; //Inv + + case -14: + RPN.NatLog(); + break; //ln + + case -15: + RPN.etothex(); + break; //exp + + case -16: + RPN.TenLog(); + break; //log10 + + case -17: + RPN.Sindeg(); + break; //Sin + + case -18: + RPN.Cosdeg(); + break; //Cos + + case -19: + RPN.Tandeg(); + break; //Tan + + case -20: + RPN.aSindeg(); + break; //ASin + + case -21: + RPN.aCosdeg(); + break; //ACos + + case -22: + RPN.aTandeg(); + break; //ATan + + case -23: + RPN.aTan2deg(); + break; //ATan2 + + case -24: + RPN.RollUp(); + break; //RollUp + + case -25: + RPN.RollDn(); + break; //RollDn + + case -26: + RPN.SwapXY(); + break; //Swap + + case -27: + RPN.EnterPi(); + break; //Pi + + case -28: + RPN.YToTheXPower(); + break; //^ + default: + { + if (FCmd[idx] >= 50000) + RPN.Set_X(FVarConst[FCmd[idx] - 50000]); + else + RPN.Set_X((*MemSpace)[FCmd[idx]][0]); // It's a variable + } + } + } + } + (*MemSpace)[OutIdx][1] = RPN.Get_X(); // Uploads value into memory space +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +bool TDynamicExpObj::InterpretDiffEq(String Exp) +/*Builds the list of commands required for operating the equation declared, this +automation is intended to acelerate the calculation in run time. +Notation: + Positive integers represent the index to a variable slot (dbl) + If the integer is a value >= 50000, it means that it is the index to a + numeric constant that can be located at FVarConst + If is a negative integer, represents one of the following operations: + -2 = Add + -3 = Subtraction + -4 = Mult + -5 = Div .... etc. For details, check myOps array defined above + If the negative integer is -50, it means the begining of a new equation*/ +{ + bool result = false; + int idx = 0, OpCode = 0, OpIdx = 0; + String ErrorSrc, SubXp, Op; + TStringList myVars; + + result = false; + ErrorSrc = ""; + myVars.clear(); + FCmd.resize( 0 ); + FXpression = "[" + LowerCase(Exp) + "]"; + while (FXpression.size() > 0) + { + OpIdx = Get_Closer_Op(FXpression, Op, OpCode); + if (OpIdx == 10000) + { + FXpression = ""; // we're done + } + else + { + SubXp = FXpression.substr(0, OpIdx); + if (Op.size() >= 1) + OpIdx = OpIdx + Op.size(); + FXpression = FXpression.substr(OpIdx, FXpression.size()); + InterpretTStringListArray(SubXp, myVars); + switch (OpCode) + { + case 0: + { + OpIdx = Get_Var_Idx(myVars[0]); // the result is always placed at the begin + if (OpIdx == 50001) + { + DoSimpleMsg("DynamicExp: the expression preceeding the \"dt\" operand has to be a state variable.", 50006); + ErrorSrc = "preceeding differential output"; + } + else + { + if (OpIdx < 0) + ErrorSrc = myVars[0]; + else + { + FCmd.push_back(OpIdx); + FCmd.push_back(-50); // denotes the begining of an equation + } + } + } + break; + case 1: case 6: case 7: case 8: case 9: + { + // Do nothing, it's just for notation reference at the user side + } + break; + default: // it is one of the basic operations or end of the diff eq + { + for (int stop = (myVars.size() - 1), idx = 0; idx <= stop; idx++) + { + OpIdx = Get_Var_Idx(myVars[idx]); + if (OpIdx == 50001) + { + FVarConst.push_back( stod( myVars[idx] ) ); + FCmd.push_back( 50000 + ( FVarConst.size() - 1 ) ); + } + else + { + if (OpIdx < 0) + ErrorSrc = "\"" + myVars[0] + "\""; + else + FCmd.push_back( Get_Var_Idx( myVars[idx] ) ); + } + } + if (OpCode != 10) + { + FCmd.push_back( - 1 * OpCode ); // assings the operator -> + - * / + } + } + } + } + if (!ErrorSrc.empty()) + { + DoSimpleMsg(String("DynamicExp: Variable ") + ErrorSrc + " not Found.", 50005); + FXpression = ""; + result = true; + } + } + if (!result) + FXpression = Exp; // assings the expression again to keep a local copy + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + +void TDynamicExpObj::DumpProperties(TTextRec& F, bool Complete) +{ + int i = 0; + inherited::DumpProperties(F, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + for (int stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Write(F, "~ "); Write(F, (with0->PropertyName)[i - 1]); Write(F, '='); WriteLn(F, Get_PropertyValue(i)); + } + } +} + + +String TDynamicExpObj::GetPropertyValue(int Index) +{ + String result; + switch (Index) + { + case 1: + result = Format("%d", FNumvars); + break; + case 4: + result = Format("%d", FVarIdx); + break; + default: + result = inherited::GetPropertyValue(Index); + } + return result; +} + +int TDynamicExpObj::get_FNumVars() +{ + return FNumvars; +} +void TDynamicExpObj::set_FNumvars(int value) +{ + FNumvars = value; +} + +void TDynamicExpObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); // 'nvariables'; + Set_PropertyValue(2,"[]"); // 'varnames'; + Set_PropertyValue(3,"[0.0]"); // 'varinit'; + Set_PropertyValue(4,""); // 'var'; + Set_PropertyValue(5,"0.0"); // 'varvalue'; + Set_PropertyValue(6,""); // 'expression'; + inherited::InitPropertyValues(NumPropsThisClass); +} + + +} // namespace DynamicExp \ No newline at end of file diff --git a/OpenDSSC/General/DynamicExp.h b/OpenDSSC/General/DynamicExp.h new file mode 100644 index 0000000..8ba3740 --- /dev/null +++ b/OpenDSSC/General/DynamicExp.h @@ -0,0 +1,108 @@ +#ifndef DynamicExpH +#define DynamicExpH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + + +#include "System.h" + +/*The dynamics experssion object implements differential equations +and state variables that can be called by other objects to represent +their dynamic behavior when operating in dynamics simulation mode. + +Last update by Davis Montenegro 04/13/2022 +*/ +#include "Sysutils.h" +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Arraydef.h" +#include "d2c_structures.h" + +namespace DynamicExp +{ + +class TDynamicExp; +class TDynamicExpObj; + + + + +class TDynamicExp : public TDSSClass { + typedef TDSSClass inherited; + friend class TDynamicExpObj; +private: + bool SymComponentsChanged; + bool MatrixChanged; + String Get_Code(); // Returns active line code string + void Set_Code(const String Value); // sets the active linecode +protected: + void DefineProperties(); + virtual int MakeLike(const String LineName); +public: + TDynamicExp(); + virtual ~TDynamicExp(); + virtual void* Find(const String ObjName); + virtual int Edit(int ActorID) // uses global parser + ; + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName) + + // Set this property to point ActiveLineCodeObj to the right value + ; + //__declspec ( property ( get = Get_Code, put = Set_Code ) ) String Code; +}; + + +class TDynamicExpObj : public TDSSObject { + typedef TDSSObject inherited; + friend class TDynamicExp; +private: + int FVarIdx, FNumvars; // Number of state variables + TStringList FvarNames; // List containing the state variable names + vector < double > FVarConst; // Array containing the numeric constants of the expression + vector < int > FCmd; // Sequence of commands that implement the expression + // Name of the active variable + String FActiveVar, FXpression; // Differential equiation in RPN format +public: + double BaseFrequency; + int myDomain; + TDynamicExpObj(DSSClass::TDSSClass* ParClass, const String LineCodeName); + virtual ~TDynamicExpObj(); + bool InterpretDiffEq(String Exp); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(TTextRec& F, bool Complete); + int Get_Closer_Op(String myExp, String& myOp, int& OpCode); + int Get_Var_Idx(String myVar); + bool Check_If_CalcValue(String myVal, int& myOp); + int Get_Out_Idx(String myVar); // gets the index for the given variable if it is an output + void SolveEq(vector * MemSpace); // Equation solver + bool IsInitVal(int myCode); // returns true if the given code is for an initialization value + double Get_DynamicEqVal(int myIdx, std::vector * MemSpace); + String Get_VarName(int myIdx); + int get_FNumVars(); + void set_FNumvars(int value); + //__declspec ( property ( get = get_FNumVars, put = set_FNumvars) ) int NumVars; + + TDynamicExpObj(DSSClass::TDSSClass* ParClass); + TDynamicExpObj(String ClassName); + TDynamicExpObj(); +}; + + +extern TDynamicExp* DynamicExpClass; +extern TDynamicExpObj* ActiveDynamicExpObj; + +} // namespace DynamicExp + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DynamicExp; +#endif + +#endif // DynamicExpH \ No newline at end of file diff --git a/OpenDSSC/General/GrowthShape.cpp b/OpenDSSC/General/GrowthShape.cpp new file mode 100644 index 0000000..2fb4809 --- /dev/null +++ b/OpenDSSC/General/GrowthShape.cpp @@ -0,0 +1,604 @@ + +#pragma hdrstop + +#include "GrowthShape.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace GrowthShape +{ + +TGrowthShapeObj::TGrowthShapeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TGrowthShapeObj::TGrowthShapeObj(String ClassName) : inherited(ClassName) {} +TGrowthShapeObj::TGrowthShapeObj() {} + + +TGrowthShapeObj* ActiveGrowthShapeObj = nullptr; +const int NumPropsThisClass = 6; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TGrowthShape::TGrowthShape() +{ + ; + Class_Name = "GrowthShape"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(false); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGrowthShape::~TGrowthShape() +{ + + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGrowthShape::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "npts"; // Number of points to expect + PropertyName[2 - 1] = "year"; // vextor of year values + PropertyName[3 - 1] = "mult"; // vector of multiplier values corresponding to years + PropertyName[4 - 1] = "csvfile"; // Switch input to a csvfile (year, mult) + PropertyName[5 - 1] = "sngfile"; // switch input to a binary file of singles (year, mult) + PropertyName[6 - 1] = "dblfile"; // switch input to a binary file of doubles (year, mult) + PropertyHelp[1 - 1] = "Number of points to expect in subsequent vector."; + PropertyHelp[2 - 1] = "Array of year values, or a text file spec, corresponding to the multipliers. " + "Enter only those years where the growth changes. " + "May be any integer sequence -- just so it is consistent. See help on Mult."; + PropertyHelp[3 - 1] = String("Array of growth multiplier values, or a text file spec, corresponding to the year values. " "Enter the multiplier by which you would multiply the previous year's load to get the present year's.") + CRLF + + CRLF + + "Examples:" + + CRLF + + CRLF + + " Year = [1, 2, 5] Mult=[1.05, 1.025, 1.02]." + + CRLF + + " Year= (File=years.txt) Mult= (file=mults.txt)." + + CRLF + + CRLF + + "Text files contain one value per line."; + PropertyHelp[4 - 1] = "Switch input of growth curve data to a csv file containing (year, mult) points, one per line."; + PropertyHelp[5 - 1] = "Switch input of growth curve data to a binary file of singles " + "containing (year, mult) points, packed one after another."; + PropertyHelp[6 - 1] = "Switch input of growth curve data to a binary file of doubles " + "containing (year, mult) points, packed one after another."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGrowthShape::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TGrowthShapeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGrowthShape::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + pDoubleArray YrBuffer = nullptr; + int i = 0; + result = 0; + // continue parsing with contents of Parser + ActiveGrowthShapeObj = ((TGrowthShapeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveGrowthShapeObj; + /*# with ActiveGrowthShapeObj do */ + { + auto with0 = ActiveGrowthShapeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 600); + break; + case 1: + with0->npts = Parser[ActorID]->MakeInteger_(); + break; + case 2: + { + int stop = 0; + with0->Year = (pIntegerArray) realloc(with0->Year, sizeof(long) * with0->npts); + YrBuffer = (pDoubleArray) realloc(YrBuffer, sizeof(double) * with0->npts); + with0->npts = InterpretDblArray(Param, with0->npts, YrBuffer); // Parser.ParseAsVector(Npts, Yrbuffer); + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->Year)[i - 1] = (int) Round((YrBuffer)[i - 1]); + } + with0->BaseYear = (with0->Year)[1 - 1]; + free(YrBuffer); //# FreeMemory accepts one parameter only; + } + break; + case 3: + { + with0->Multiplier = (pDoubleArray) realloc(with0->Multiplier, sizeof(double) * with0->npts); + with0->npts = InterpretDblArray(Param, with0->npts, with0->Multiplier); //Parser.ParseAsVector(Npts, Multiplier); + } + break; + case 4: + DoCSVFile(Param); + break; + case 5: + DoSngFile(Param); + break; + case 6: + DoDblFile(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveGrowthShapeObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*WHILE*/ + with0->ReCalcYearMult(); + } /*WITH*/ + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGrowthShape::MakeLike(const String ShapeName) +{ + int result = 0; + TGrowthShapeObj* OtherGrowthShape = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherGrowthShape = ((TGrowthShapeObj*) Find(ShapeName)); + if(OtherGrowthShape != nullptr) + /*# with ActiveGrowthShapeObj do */ + { + auto with0 = ActiveGrowthShapeObj; + int stop = 0; + with0->npts = OtherGrowthShape->npts; + with0->Multiplier = (pDoubleArray) realloc(with0->Multiplier, sizeof(double) * with0->npts); + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->Multiplier)[i - 1] = (OtherGrowthShape->Multiplier)[i - 1]; + } + with0->Year = (pIntegerArray) realloc(with0->Year, sizeof(long) * with0->npts); + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->Year)[i - 1] = (OtherGrowthShape->Year)[i - 1]; + } + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherGrowthShape->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in GrowthShape MakeLike: \"") + ShapeName + + "\" Not Found.", 601); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGrowthShape::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TGrowthShape.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + +String TGrowthShape::Get_Code() +{ + String result; + TGrowthShapeObj* GrowthShapeObj = nullptr; + GrowthShapeObj = ((TGrowthShapeObj*) ElementList.Get_Active()); + result = GrowthShapeObj->get_Name(); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active GrowthShape + +void TGrowthShape::Set_Code(const String Value) +{ + TGrowthShapeObj* GrowthShapeObj = nullptr; + ActiveGrowthShapeObj = nullptr; + GrowthShapeObj = ((TGrowthShapeObj*) ElementList.Get_First()); + while(GrowthShapeObj != nullptr) + { + if(CompareText(GrowthShapeObj->get_Name(), Value) == 0) + { + ActiveGrowthShapeObj = GrowthShapeObj; + return; + } + GrowthShapeObj = ((TGrowthShapeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("GrowthShape: \"") + Value + "\" not Found.", 602); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGrowthShape::DoCSVFile(const String FileName) +{ + String dummy; + System::TTextRec f = {}; + int i = 0; + String s; + try + { + AssignFile(f, FileName); + Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 603); + CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveGrowthShapeObj do */ + { + auto with0 = ActiveGrowthShapeObj; + i = 0; + while((!Eof(f)) && (i < with0->npts)) + { + ++i; + ReadLn(f, s); /*Use AuxParser to allow flexible formats*/ + /*# with AuxParser[ActiveActor] do */ + { + + // Readln(F,Year^[i], Multiplier^[i]); + AuxParser[ActiveActor]->SetCmdString(s); + dummy = AuxParser[ActiveActor]->GetNextParam(); + with0->Year[i - 1] = AuxParser[ActiveActor]->MakeInteger_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); + (with0->Multiplier)[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + } + } + CloseFile(f); + } + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 604); + CloseFile(f); + return; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGrowthShape::DoSngFile(const String FileName) +{ + System::TTypedFile f; + float Y = 0.0F; + float m = 0.0F; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 605); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveGrowthShapeObj do */ + { + auto with0 = ActiveGrowthShapeObj; + i = 0; + while((!Eof(f)) && (i < with0->npts)) + { + ++i; + { System::Read(f, &Y); System::Read(f, &m); } + with0->Year[i - 1] = (int) Round(Y); + with0->Multiplier[i - 1] = m; + } + System::CloseFile(f); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing GrowthShape File: \"") + FileName, 606); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGrowthShape::DoDblFile(const String FileName) +{ + System::TTypedFile f; + int i = 0; + double Yr = 0.0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 607); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveGrowthShapeObj do */ + { + auto with0 = ActiveGrowthShapeObj; + i = 0; + while((!Eof(f)) && (i < with0->npts)) + { + ++i; + { System::Read(f, &Yr); System::Read(f, &(with0->Multiplier)[i - 1]); } + with0->Year[i - 1] = (int) Round(Yr); + } + System::CloseFile(f); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing GrowthShape File: \"") + FileName, 608); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TGrowthShape Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGrowthShapeObj::TGrowthShapeObj(TDSSClass* ParClass, const String GrowthShapeName) + : inherited(ParClass), + npts(0), + NYears(30), + BaseYear(0), + Year(nullptr), + YearMult(nullptr), + Multiplier(nullptr) +{ + Set_Name(LowerCase(GrowthShapeName)); + DSSObjType = ParClass->DSSClassType; + Year = nullptr; + Multiplier = nullptr; + YearMult = new double[NYears]; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGrowthShapeObj::~TGrowthShapeObj() +{ + free(Year); + free(Multiplier); + delete[] YearMult; + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function returns the multiplier to use for a load in the given year. +// The first year specified in the curve is the base year. The Base value +// is the beginning of the first year. + +double TGrowthShapeObj::GetMult(int Yr) +{ + double result = 0.0; + int Index = 0; + result = 1.0; // default return value if no points in curve + if(npts > 0) // Handle Exceptional cases + { + Index = Yr - BaseYear; + if(Index > 0) // Returns 1.0 for base year or any year previous + { + if(Index > NYears) // Make some more space + { + NYears = Index + 10; + YearMult = (pDoubleArray) realloc(YearMult, sizeof(double) * NYears); + ReCalcYearMult(); + } + result = (YearMult)[Index - 1]; + } + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGrowthShapeObj::ReCalcYearMult() +{ + int i = 0; + int DataPtr = 0; + int Yr = 0; + double Mult = 0.0; + double MultInc = 0.0; + // Fill up the YearMult array with total yearly multiplier from base year + int stop = 0; + Mult = (Multiplier)[1 - 1]; + MultInc = Mult; + YearMult[1 - 1] = Mult; + DataPtr = 1; + Yr = BaseYear; + for(stop = NYears, i = 2; i <= stop; i++) + { + ++Yr; + if(DataPtr < npts) + { + if((Year)[DataPtr + 1 - 1] == Yr) + { + ++DataPtr; + MultInc = (Multiplier)[DataPtr - 1]; + } + } + Mult = Mult * MultInc; + YearMult[i - 1] = Mult; + } +} + +void TGrowthShapeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + case 2: case 3: + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, "=("); System::Write(f, Get_PropertyValue(i)); System::WriteLn(f, L')'); } + break; + default: + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, L'='); System::WriteLn(f, Get_PropertyValue(i)); } + break; + } + } + } +} + +String TGrowthShapeObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + switch(Index) + { + case 2: + case 3: + result = "("; + break; + default: + result = ""; + break; + } + switch(Index) + { + int stop; + case 2: + for(stop = npts, i = 1; i <= stop; i++) + { + result = result + Format("%-d, ", (int)Year[i - 1]); + } + break; + case 3: + for(stop = npts, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", Multiplier[i - 1]); + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 2: + case 3: + result = result + ")"; + break; + default: + ; + break; + } + return result; +} + +void TGrowthShapeObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); // Number of points to expect + Set_PropertyValue(2,""); // vextor of year values + Set_PropertyValue(3,""); // vector of multiplier values corresponding to years + Set_PropertyValue(4,""); // Switch input to a csvfile (year, mult) + Set_PropertyValue(5,""); // switch input to a binary file of singles (year, mult) + Set_PropertyValue(6,""); // switch input to a binary file of doubles (year, mult) + inherited::InitPropertyValues(NumPropsThisClass); +} + + + + +} // namespace GrowthShape + + + + + diff --git a/OpenDSSC/General/GrowthShape.h b/OpenDSSC/General/GrowthShape.h new file mode 100644 index 0000000..c6e25ed --- /dev/null +++ b/OpenDSSC/General/GrowthShape.h @@ -0,0 +1,120 @@ +#ifndef GrowthShapeH +#define GrowthShapeH + +#include "System.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Arraydef.h" + + +namespace GrowthShape +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 8-18-00 Added call to InterpretDblArrayto allow File=Syntax */ +/*The GrowthShape object is a general DSS object used by all circuits + as a reference for obtaining yearly growth curves. + + The values are set by the normal New and Edit procedures as for any DSS object. + + The values are retrieved by setting the Code Property in the GrowthShape Class. + This sets the active GrowthShapeObj object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. Or you + can pick up the ActiveGrowthShapeObj object and save the direct reference to the object. + + Growth shapes are entered as multipliers for the previous year's load. If the + load grows by 2.5% in a year, the multiplier is entered as 1.025. You do not need + to enter subsequent years if the multiplier remains the same. You need only enter + the years in which the growth rate is assumed to have changed. + + The user may place the data in CSV or binary files as well as passing through the + command interface. The rules are the same as for LoadShapes except that the year + is always entered. CSV files are text separated by commas, one interval to a line. + There are two binary formats permitted: 1) a file of Singles; 2) a file of Doubles. + + (Year, multiplier) pairs are expected in all formats. Through the COM interface, + supply separate arrays of Year and Mult. + + Edit growthshape.allisonsub npts=5 + ~ year="1999 2000 2001 2005 2010" + ~ mult="1.10 1.07 1.05 1.025 1.01" + + This example describes a growth curve that start off relatively fast (10%) and after + 10 years tapers off to 1% + + */ + +class TGrowthShape : public DSSClass::TDSSClass +{ + friend class TGrowthShapeObj; +public: + typedef DSSClass::TDSSClass inherited; +//private: + String Get_Code(); // Returns active GrowthShape String + void Set_Code(const String Value); // sets the active GrowthShape + void DoCSVFile(const String FileName); + void DoSngFile(const String FileName); + void DoDblFile(const String FileName); +protected: + void DefineProperties(); + virtual int MakeLike(const String ShapeName); +public: + TGrowthShape(); + virtual ~TGrowthShape(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + + // Set this property to point ActiveGrowthShapeObj to the right value +}; + +class TGrowthShapeObj : public DSSObject::TDSSObject +{ + friend class TGrowthShape; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int npts; // Number of points in curve + int NYears; // Number of years presently allocated in look up table + int BaseYear; + Arraydef::pIntegerArray Year; // Year values + Arraydef::pDoubleArray YearMult; + Arraydef::pDoubleArray Multiplier; // Multipliers + void ReCalcYearMult(); +public: + TGrowthShapeObj(DSSClass::TDSSClass* ParClass, const String GrowthShapeName); + virtual ~TGrowthShapeObj(); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + double GetMult(int Yr); // Get multiplier for Specified Year + TGrowthShapeObj(DSSClass::TDSSClass* ParClass); + TGrowthShapeObj(String ClassName); + TGrowthShapeObj(); +}; +extern TGrowthShapeObj* ActiveGrowthShapeObj; + + +} // namespace GrowthShape + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GrowthShape; +#endif + +#endif // GrowthShapeH + + + + + diff --git a/OpenDSSC/General/LineCode.cpp b/OpenDSSC/General/LineCode.cpp new file mode 100644 index 0000000..1cc73a0 --- /dev/null +++ b/OpenDSSC/General/LineCode.cpp @@ -0,0 +1,1080 @@ + +#pragma hdrstop + +#include "LineCode.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucomplex.h" +#include "Utilities.h" +#include "LineUnits.h" + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineUnits; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace LineCode +{ + +TLineCodeObj::TLineCodeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TLineCodeObj::TLineCodeObj(String ClassName) : inherited(ClassName) {} +TLineCodeObj::TLineCodeObj() {} + + +TLineCode* LineCodeClass = nullptr; +TLineCodeObj* ActiveLineCodeObj = nullptr; + +const int NumPropsThisClass = 27; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TLineCode::TLineCode() + : SymComponentsChanged(false), + MatrixChanged(false) +{ + ; + Class_Name = "LineCode"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + LineCodeClass = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineCode::~TLineCode() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineCode::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + (PropertyName)[1 - 1] = "nphases"; + (PropertyName)[2 - 1] = "r1"; + (PropertyName)[3 - 1] = "x1"; + (PropertyName)[4 - 1] = "r0"; + (PropertyName)[5 - 1] = "x0"; + (PropertyName)[6 - 1] = "C1"; + (PropertyName)[7 - 1] = "C0"; + (PropertyName)[8 - 1] = "units"; + (PropertyName)[9 - 1] = "rmatrix"; + (PropertyName)[10 - 1] = "xmatrix"; + (PropertyName)[11 - 1] = "cmatrix"; + (PropertyName)[12 - 1] = "baseFreq"; + (PropertyName)[13 - 1] = "normamps"; + (PropertyName)[14 - 1] = "emergamps"; + (PropertyName)[15 - 1] = "faultrate"; + (PropertyName)[16 - 1] = "pctperm"; + (PropertyName)[17 - 1] = "repair"; + (PropertyName)[18 - 1] = "Kron"; + (PropertyName)[19 - 1] = "Rg"; + (PropertyName)[20 - 1] = "Xg"; + (PropertyName)[21 - 1] = "rho"; + (PropertyName)[22 - 1] = "neutral"; + (PropertyName)[23 - 1] = "B1"; + (PropertyName)[24 - 1] = "B0"; + (PropertyName)[25 - 1] = "Seasons"; + (PropertyName)[26 - 1] = "Ratings"; + (PropertyName)[27 - 1] = "LineType"; + (PropertyHelp)[1 - 1] = "Number of phases in the line this line code data represents. Setting this property reinitializes the line code. Impedance matrix is reset for default symmetrical component."; + (PropertyHelp)[2 - 1] = "Positive-sequence Resistance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Rmatrix."; + (PropertyHelp)[3 - 1] = "Positive-sequence Reactance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Xmatrix"; + (PropertyHelp)[4 - 1] = "Zero-sequence Resistance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition."; + (PropertyHelp)[5 - 1] = "Zero-sequence Reactance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition."; + (PropertyHelp)[6 - 1] = "Positive-sequence capacitance, nf per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Cmatrix and B1."; + (PropertyHelp)[7 - 1] = "Zero-sequence capacitance, nf per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also B0."; + (PropertyHelp)[8 - 1] = "One of (ohms per ...) {none|mi|km|kft|m|me|ft|in|cm}. Default is none; assumes units agree with length units" + "given in Line object"; + (PropertyHelp)[9 - 1] = "Resistance matrix, lower triangle, ohms per unit length. Order of the matrix is the number of phases. " + "May be used to specify the impedance of any line configuration. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + (PropertyHelp)[10 - 1] = "Reactance matrix, lower triangle, ohms per unit length. Order of the matrix is the number of phases. " + "May be used to specify the impedance of any line configuration. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + (PropertyHelp)[11 - 1] = "Nodal Capacitance matrix, lower triangle, nf per unit length.Order of the matrix is the number of phases. " + "May be used to specify the shunt capacitance of any line configuration. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + (PropertyHelp)[12 - 1] = "Frequency at which impedances are specified."; + (PropertyHelp)[13 - 1] = "Normal ampere limit on line. This is the so-called Planning Limit. It may also be " + "the value above which load will have to be dropped in a contingency. Usually about " + "75% - 80% of the emergency (one-hour) rating."; + (PropertyHelp)[14 - 1] = "Emergency ampere limit on line (usually one-hour rating)."; + (PropertyHelp)[15 - 1] = "Number of faults per unit length per year."; + (PropertyHelp)[16 - 1] = "Percentage of the faults that become permanent."; + (PropertyHelp)[17 - 1] = "Hours to repair."; + (PropertyHelp)[18 - 1] = "Kron = Y/N. Default=N. Perform Kron reduction on the impedance matrix after it is formed, reducing order by 1. " + "Eliminates the conductor designated by the \"Neutral=\" property. " + "Do this after the R, X, and C matrices are defined. Ignored for symmetrical components. " + "May be issued more than once to eliminate more than one conductor by resetting the Neutral property after the previous " + "invoking of this property. Generally, you do not want to do a Kron reduction on the matrix if you intend to solve at a " + "frequency other than the base frequency and exploit the Rg and Xg values."; + (PropertyHelp)[19 - 1] = "Carson earth return resistance per unit length used to compute impedance values at base frequency. For making better frequency adjustments. " + "Default is 0.01805 = 60 Hz value in ohms per kft (matches default line impedances). " + "This value is required for harmonic solutions if you wish to adjust the earth return impedances for frequency. " + "If not, set both Rg and Xg = 0."; + (PropertyHelp)[20 - 1] = "Carson earth return reactance per unit length used to compute impedance values at base frequency. For making better frequency adjustments. " + "Default value is 0.155081 = 60 Hz value in ohms per kft (matches default line impedances). " + "This value is required for harmonic solutions if you wish to adjust the earth return impedances for frequency. " + "If not, set both Rg and Xg = 0."; + (PropertyHelp)[21 - 1] = "Default=100 meter ohms. Earth resitivity used to compute earth correction factor."; + (PropertyHelp)[22 - 1] = "Designates which conductor is the \"neutral\" conductor that will be eliminated by Kron reduction. " + "Default is the last conductor (nphases value). After Kron reduction is set to 0. Subsequent issuing of Kron=Yes " + "will not do anything until this property is set to a legal value. Applies only to LineCodes defined by R, X, and C matrix."; + (PropertyHelp)[23 - 1] = "Alternate way to specify C1. MicroS per unit length"; + (PropertyHelp)[24 - 1] = "Alternate way to specify C0. MicroS per unit length"; + (PropertyHelp)[25 - 1] = "Defines the number of ratings to be defined for the wire, to be used only when defining seasonal ratings using the \"Ratings\" property."; + (PropertyHelp)[26 - 1] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in lines."; + (PropertyHelp)[27 - 1] = String("Code designating the type of line. ") + CRLF + + "One of: OH, UG, UG_TS, UG_CN, SWT_LDBRK, SWT_FUSE, SWT_SECT, SWT_REC, SWT_DISC, SWT_BRK, SWT_ELBOW" + + CRLF + + CRLF + + "OpenDSS currently does not use this internally. For whatever purpose the user defines. Default is OH."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineCode::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TLineCodeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +String TLineCodeObj::get_Rmatrix() +{ + String result; + int j = 0; + int i = 0; + int stop = 0; + result = "["; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + result = result + Format("%12.8f ", Z->GetElement(i, j).re); + } + if(i < Fnphases) + result = result + "|"; + } + result = result + "]"; + return result; +} + +String TLineCodeObj::get_Xmatrix() +{ + String result; + int j = 0; + int i = 0; + int stop = 0; + result = "["; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + result = result + Format("%12.8f ", Z->GetElement(i, j).im); + } + if(i < Fnphases) + result = result + "|"; + } + result = result + "]"; + return result; +} + +String TLineCodeObj::get_CMatrix() +{ + String result; + int i = 0; + int j = 0; + int stop = 0; + result = "["; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + result = result + + Format("%12.8f ", double(YC->GetElement(i, j).im) / DSSGlobals::TwoPi / BaseFrequency * 1.0E9); + } + if(i < Fnphases) + result = result + "|"; + } + result = result + "]"; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// decodes the units string and sets the Units variable + +void TLineCode::SetUnits(const String s) +{ + ActiveLineCodeObj->Units = GetUnitsCode(s); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// set symmetrical component impedances and a flag to indicate they were changed + +void TLineCode::SetZ1Z0(int i, double Value) +{ + SymComponentsChanged = true; + /*# with ActiveLineCodeObj do */ + { + auto with0 = ActiveLineCodeObj; + with0->SymComponentsModel = true; + switch(i) + { + case 1: + with0->R1 = Value; + break; + case 2: + with0->X1 = Value; + break; + case 3: + with0->R0 = Value; + break; + case 4: + with0->X0 = Value; + break; + case 5: + with0->C1 = Value; + break; + case 6: + with0->C0 = Value; + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineCode::DoMatrix(int i, int ActorID) +{ + int OrderFound = 0; + int Norder = 0; + int j = 0; + pDoubleArray MatBuffer; + pComplexArray Zvalues; + double Factor = 0.0; + /*# with ActiveLineCodeObj do */ + { + auto with0 = ActiveLineCodeObj; + MatrixChanged = true; + MatBuffer = new double[with0->Fnphases * with0->Fnphases]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix(with0->Fnphases, MatBuffer); + if(OrderFound > 0) + switch(i) + { // Parse was successful + case 1: /*R*/ + { + Zvalues = with0->Z->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Zvalues)[j - 1].re = (MatBuffer)[j - 1]; + } + } + } + break; /*X*/ + case 2: + { + Zvalues = with0->Z->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Zvalues)[j - 1].im = (MatBuffer)[j - 1]; + } + } + } + break; /*YC Matrix*/ + case 3: + { + Factor = DSSGlobals::TwoPi * with0->BaseFrequency * 1.0e-9; + Zvalues = with0->YC->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Zvalues)[j - 1].im = Factor * (MatBuffer)[j - 1]; + } + } + } + break; + default: + ; + break; + } + delete[] MatBuffer; //# free accepts one parameter only; + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineCode::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveLineCodeObj = ((TLineCodeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveLineCodeObj; + SymComponentsChanged = false; + MatrixChanged = false; + ActiveLineCodeObj->ReduceByKron = false; // Allow all matrices to be computed it raw form + /*# with ActiveLineCodeObj do */ + { + auto with0 = ActiveLineCodeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 101); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // Use property value to force reallocations + case 2: + SetZ1Z0(1, Parser[ActorID]->MakeDouble_()); + break; /*R1*/ + case 3: + SetZ1Z0(2, Parser[ActorID]->MakeDouble_()); + break; /*X0*/ + case 4: + SetZ1Z0(3, Parser[ActorID]->MakeDouble_()); + break; /*R1*/ + case 5: + SetZ1Z0(4, Parser[ActorID]->MakeDouble_()); + break; /*X0*/ + case 6: + SetZ1Z0(5, Parser[ActorID]->MakeDouble_() * 1.0e-9); + break; /*C1*/ // Convert from nano to farads + case 7: + SetZ1Z0(6, Parser[ActorID]->MakeDouble_() * 1.0e-9); + break; /*C0*/ + case 8: + SetUnits(Param); + break; /*Rmatrix*/ + case 9: + DoMatrix(1, ActorID); + break; /*Xmatrix*/ + case 10: + DoMatrix(2, ActorID); + break; /*Cmatrix*/ + case 11: + DoMatrix(3, ActorID); + break; + case 12: + with0->BaseFrequency = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->NormAmps = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->EmergAmps = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->FaultRate = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->PctPerm = Parser[ActorID]->MakeDouble_(); + break; + case 17: + with0->HrsToRepair = Parser[ActorID]->MakeDouble_(); + break; + case 18: + with0->ReduceByKron = InterpretYesNo(Param); + break; + case 19: + with0->Rg = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->Xg = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->rho = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->FNeutralConductor = Parser[ActorID]->MakeInteger_(); + break; + case 23: + SetZ1Z0(5, Parser[ActorID]->MakeDouble_() / (DSSGlobals::TwoPi * with0->BaseFrequency) * 1.0e-6); + break; /*B1 -> C1*/ + case 24: + SetZ1Z0(6, Parser[ActorID]->MakeDouble_() / (DSSGlobals::TwoPi * with0->BaseFrequency) * 1.0e-6); + break; /*B0 -> C0*/ + case 25: + { + with0->NumAmpRatings = Parser[ActorID]->MakeInteger_(); + with0->AmpRatings.resize(with0->NumAmpRatings); + } + break; + case 26: + { + with0->AmpRatings.resize(with0->NumAmpRatings); + Param = Parser[ActiveActor]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, ((pDoubleArray) &(with0->AmpRatings[0]))); + } + break; + case 27: + with0->FLineType = LineTypeList.Getcommand(Param); + break; + default: + ClassEdit(ActiveLineCodeObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 9: case 10: case 11: + with0->SymComponentsModel = false; + break; + case 18: + if(with0->ReduceByKron && !with0->SymComponentsModel) + with0->DoKronReduction(); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(with0->SymComponentsModel) + with0->CalcMatricesFromZ1Z0(); + if(MatrixChanged) + { + with0->Zinv->CopyFrom(with0->Z); + with0->Zinv->Invert(); + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineCode::MakeLike(const String LineName) +{ + int result = 0; + TLineCodeObj* OtherLineCode = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherLineCode = ((TLineCodeObj*) Find(LineName)); + if(OtherLineCode != nullptr) + /*# with ActiveLineCodeObj do */ + { + auto with0 = ActiveLineCodeObj; + int stop = 0; + if(with0->Fnphases != OtherLineCode->Fnphases) + { + with0->Fnphases = OtherLineCode->Fnphases; + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + if(with0->YC != nullptr) + delete with0->YC; + with0->Z = new TcMatrix(with0->Fnphases); + with0->Zinv = new TcMatrix(with0->Fnphases); + with0->YC = new TcMatrix(with0->Fnphases); + } + with0->Z->CopyFrom(OtherLineCode->Z); + with0->Zinv->CopyFrom(OtherLineCode->Zinv); + with0->YC->CopyFrom(OtherLineCode->YC); + with0->BaseFrequency = OtherLineCode->BaseFrequency; + with0->R1 = OtherLineCode->R1; + with0->X1 = OtherLineCode->X1; + with0->R0 = OtherLineCode->R0; + with0->X0 = OtherLineCode->X0; + with0->C1 = OtherLineCode->C1; + with0->C0 = OtherLineCode->C0; + with0->Rg = OtherLineCode->Rg; + with0->Xg = OtherLineCode->Xg; + with0->rho = OtherLineCode->rho; + with0->FNeutralConductor = OtherLineCode->FNeutralConductor; + with0->NormAmps = OtherLineCode->NormAmps; + with0->EmergAmps = OtherLineCode->EmergAmps; + with0->FaultRate = OtherLineCode->FaultRate; + with0->PctPerm = OtherLineCode->PctPerm; + with0->HrsToRepair = OtherLineCode->HrsToRepair; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherLineCode->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Line MakeLike: \"") + LineName + "\" Not Found.", 102); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineCode::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TLineCode.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TLineCode::Get_Code() +{ + String result; + result = ((TLineCodeObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active linecode + +void TLineCode::Set_Code(const String Value) +{ + TLineCodeObj* LineCodeObj = nullptr; + ActiveLineCodeObj = nullptr; + LineCodeObj = ((TLineCodeObj*) ElementList.Get_First()); + while(LineCodeObj != nullptr) + { + if(CompareText(LineCodeObj->get_Name(), Value) == 0) + { + ActiveLineCodeObj = LineCodeObj; + return; + } + LineCodeObj = ((TLineCodeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("Linecode: \"") + Value + "\" not Found.", 103); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TLineCode Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineCodeObj::TLineCodeObj(TDSSClass* ParClass, const String LineCodeName) + : inherited(ParClass), + SymComponentsModel(false), + ReduceByKron(false), + Z(nullptr), + Zinv(nullptr), + YC(nullptr), + BaseFrequency(0.0), + R1(0.0), + X1(0.0), + R0(0.0), + X0(0.0), + C1(0.0), + C0(0.0), + FaultRate(0.0), + PctPerm(0.0), + HrsToRepair(0.0), + Rg(0.0), + Xg(0.0), + rho(0.0), + FLineType(0), + Units(0) +{ + Set_Name(LowerCase(LineCodeName)); + DSSObjType = ParClass->DSSClassType; + Fnphases = 3; // Directly set conds and phases + FNeutralConductor = Fnphases; // initialize to last conductor + R1 = 0.0580; //ohms per 1000 ft + X1 = 0.1206; + R0 = 0.1784; + X0 = 0.4047; + C1 = 3.4E-9; // nf per 1000ft + C0 = 1.6E-9; + Z = nullptr; + Zinv = nullptr; + YC = nullptr; + BaseFrequency = ActiveCircuit[ActiveActor]->Fundamental; + Units = UNITS_NONE; // default to none (no conversion) + NormAmps = 400.0; + EmergAmps = 600.0; + PctPerm = 20.0; + FaultRate = 0.1; + FLineType = 1; // Default to OH Line + Rg = 0.01805; // ohms per 1000' + Xg = 0.155081; + rho = 100.0; + SymComponentsModel = true; + ReduceByKron = false; + CalcMatricesFromZ1Z0(); // put some reasonable values in + + /*Initialize dynamic array for ratings*/ + NumAmpRatings = 1; + AmpRatings.resize(NumAmpRatings); + AmpRatings[0] = NormAmps; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineCodeObj::~TLineCodeObj() +{ + delete Z; + delete Zinv; + delete YC; + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Set the number of phases and reallocate phase-sensitive arrays +// Need to preserve values in Z matrices + +void TLineCodeObj::Set_NPhases(int Value) +{ + if(Value > 0) + { + if(Fnphases != Value) // If size is no different, we don't need to do anything + { + Fnphases = Value; + FNeutralConductor = Fnphases; // Init to last conductor + // Put some reasonable values in these matrices + CalcMatricesFromZ1Z0(); // reallocs matrices + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineCodeObj::CalcMatricesFromZ1Z0() +{ + complex Zs = {}; + complex ZM = {}; + complex Ys = {}; + complex YM = {}; + complex Ztemp = {}; + int i = 0; + int j = 0; + double Yc1 = 0.0; + double Yc0 = 0.0; + double OneThird = 0.0; + int stop = 0; + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + if(YC != nullptr) + delete YC; + + // For a line, nphases = ncond, for now + Z = new TcMatrix(Fnphases); + Zinv = new TcMatrix(Fnphases); + YC = new TcMatrix(Fnphases); + OneThird = 1.0 / 3.0; // Do this to get more precision in next few statements + Ztemp = cmulreal(cmplx(R1, X1), 2.0); + Zs = cmulreal(cadd(Ztemp, cmplx(R0, X0)), OneThird); + ZM = cmulreal(csub(cmplx(R0, X0), cmplx(R1, X1)), OneThird); + Yc1 = DSSGlobals::TwoPi * BaseFrequency * C1; + Yc0 = DSSGlobals::TwoPi * BaseFrequency * C0; + Ys = cmulreal(cadd(cmulreal(cmplx(0.0, Yc1), 2.0), cmplx(0.0, Yc0)), OneThird); + YM = cmulreal(csub(cmplx(0.0, Yc0), cmplx(0.0, Yc1)), OneThird); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + Z->SetElement(i, i, Zs); + YC->SetElement(i, i, Ys); + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Z->SetElemsym(i, j, ZM); + YC->SetElemsym(i, j, YM); + } + } + Zinv->CopyFrom(Z); + Zinv->Invert(); +} + +void TLineCodeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int k = 0; + int i = 0; + int j = 0; + char Buff[1000]; + String TempStr; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[1 - 1]); System::Write(f, "="); System::WriteLn(f, Fnphases, 0); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[2 - 1]); System::Write(f, "="); System::WriteLn(f, R1, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[3 - 1]); System::Write(f, "="); System::WriteLn(f, X1, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[4 - 1]); System::Write(f, "="); System::WriteLn(f, R0, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[5 - 1]); System::Write(f, "="); System::WriteLn(f, X0, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[6 - 1]); System::Write(f, "="); System::WriteLn(f, C1 * 1.0E9, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[7 - 1]); System::Write(f, "="); System::WriteLn(f, C0 * 1.0E9, 0, 5); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[8 - 1]); System::Write(f, "="); System::WriteLn(f, Get_PropertyValue(8)); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[9 - 1]); System::Write(f, "="); System::Write(f, L'\"'); } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { System::Write(f, Z->GetElement(i, j).re, 0, 8); System::Write(f, ""); } + } + System::Write(f, L'|'); + } + System::WriteLn(f, L'\"'); + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[10 - 1]); System::Write(f, "="); Write(f, L'\"'); } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { System::Write(f, Z->GetElement(i, j).im, 0, 8); System::Write(f, ""); } + } + Write(f, L'|'); + } + System::WriteLn(f, L'\"'); + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[11 - 1]); System::Write(f, "="); Write(f, L'\"'); } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { System::Write(f, (double(YC->GetElement(i, j).im) / DSSGlobals::TwoPi / BaseFrequency * 1.0E9), 0, 8); Write(f, ""); } + } + System::Write(f, L'|'); + } + System::WriteLn(f, L'\"'); + for(stop = 21, i = 12; i <= stop; i++) + { + { System::Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); System::Write(f, "="); System::WriteLn(f, Get_PropertyValue(i)); } + } + sprintf(Buff, "~ %s=%d", with0->PropertyName[22 - 1].c_str(), FNeutralConductor); + System::WriteLn(f, Buff); + sprintf(Buff, "~ %s=%d", with0->PropertyName[25 - 1].c_str(), NumAmpRatings); + System::WriteLn(f, Buff); + TempStr = "["; + for(stop = NumAmpRatings, k = 1; k <= stop; k++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[k - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + sprintf(Buff, "~ %s=%s", with0->PropertyName[26 - 1].c_str(), TempStr.c_str()); + System::WriteLn(f, Buff); + } +} + +String TLineCodeObj::GetPropertyValue(int Index) +{ + String result; + int j = 0; + char Buff[1000]; + switch(Index) + { + case 1: + { + sprintf(Buff, "%d", Fnphases); + result = Buff; + } + break; + case 2: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", R1); + result = Buff; + } + else + result = "----"; + break; + case 3: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", X1); + result = Buff; + } + else + result = "----"; + break; + case 4: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", R0); + result = Buff; + } + else + result = "----"; + break; + case 5: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", X0); + result = Buff; + } + else + result = "----"; + break; + case 6: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", C1 * 1.0E9); + result = Buff; + } + else + result = "----"; + break; + case 7: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", C0 * 1.0E9); + result = Buff; + } + else + result = "----"; + break; + case 8: + result = LineUnitsStr(Units); + break; + case 9: + result = get_Rmatrix(); + break; + case 10: + result = get_Xmatrix(); + break; + case 11: + result = get_CMatrix(); + break; + case 12: + { + sprintf(Buff, "%.g", BaseFrequency); + result = Buff; + } + break; // was defaultbasefrequency ??? 'baseFreq'; + case 18: + if(ReduceByKron) + result = "Y"; + else + result = "N"; + break; + case 19: + { + sprintf(Buff, "%.5g", Rg); + result = Buff; + } + break; + case 20: + { + sprintf(Buff, "%.5g", Xg); + result = Buff; + } + break; + case 21: + { + sprintf(Buff, "%.5g", rho); + result = Buff; + } + break; + case 22: + result = IntToStr(FNeutralConductor); + break; + case 23: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", DSSGlobals::TwoPi * BaseFrequency * C1 * 1.0e6); + result = Buff; + } + else + result = "----"; + break; + case 24: + if (SymComponentsModel) + { + sprintf(Buff, "%.5g", DSSGlobals::TwoPi * BaseFrequency * C0 * 1.0e6); + result = Buff; + } + else + result = "----"; + break; + case 25: + result = IntToStr(NumAmpRatings); + break; + case 26: + { + int stop = 0; + result = "["; + for(stop = NumAmpRatings, j = 1; j <= stop; j++) + { + result = result + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + result = result + "]"; + } + break; + case 27: + result = LineTypeList.Get(FLineType); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TLineCodeObj::InitPropertyValues(int ArrayOffset) +{ + char Buff[300]; + + Set_PropertyValue(1,"3"); // 'nphases'; + Set_PropertyValue(2,".058"); // 'r1'; + Set_PropertyValue(3,".1206"); // 'x1'; + Set_PropertyValue(4,"0.1784"); // 'r0'; + Set_PropertyValue(5,"0.4047"); // 'x0'; + Set_PropertyValue(6,"3.4"); // 'c1'; + Set_PropertyValue(7,"1.6"); // 'c0'; + Set_PropertyValue(8,"none"); // 'units'; + Set_PropertyValue(9,""); // 'rmatrix'; + Set_PropertyValue(10,""); // 'xmatrix'; + Set_PropertyValue(11,""); // 'cmatrix'; + sprintf(Buff, "%6.1f", DefaultBaseFreq); + Set_PropertyValue(12,Buff); // 'baseFreq'; + Set_PropertyValue(13,"400"); // 'normamps'; + Set_PropertyValue(14,"600"); // 'emergamps'; + Set_PropertyValue(15,"0.1"); // 'faultrate'; + Set_PropertyValue(16,"20"); // 'pctperm'; + Set_PropertyValue(17,"3"); // 'Hrs to repair'; + Set_PropertyValue(18,"N"); // 'Kron'; + Set_PropertyValue(19,".01805"); // 'Rg'; + Set_PropertyValue(20,".155081"); // 'Xg'; + Set_PropertyValue(21,"100"); // 'rho'; + Set_PropertyValue(22,"3"); // 'Neutral'; + Set_PropertyValue(23,"1.2818"); // B1 microS + Set_PropertyValue(24,"0.60319"); // B0 microS + Set_PropertyValue(25,"1"); // 1 season + Set_PropertyValue(26,"[400]"); // 1 rating + Set_PropertyValue(27,"OH"); // 1 rating + inherited::InitPropertyValues(NumPropsThisClass); +} + +//---------------------------------------------------------------------------------------------------------------- + +int TLineCodeObj::get_Fnphases() +{ + return Fnphases; +} + +//---------------------------------------------------------------------------------------------------------------- + +void TLineCodeObj::DoKronReduction() +{ + TcMatrix* NewZ = nullptr; + TcMatrix* NewYC = nullptr; + if(FNeutralConductor == 0) + return; // Do Nothing + NewZ = nullptr; + NewYC = nullptr; + if(Fnphases > 1) + { + try + { + NewZ = Z->Kron(FNeutralConductor); // Perform Kron Reductions into temp space + /* Have to invert the Y matrix to eliminate properly*/ + YC->Invert(); // Vn = 0 not In + NewYC = YC->Kron(FNeutralConductor); + } + catch (...) + { + DoSimpleMsg(Format("Kron Reduction failed: LineCode.%s. Attempting to eliminate Neutral Conductor %d.", get_Name().c_str(), FNeutralConductor), 103); + } + + // Reallocate into smaller space if Kron was successful + if((NewZ != nullptr) && (NewYC != nullptr)) + { + NewYC->Invert(); // Back to Y + Set_NPhases(NewZ->get_Norder()); + + // Get rid of Z and YC and replace + delete Z; + delete YC; + Z = NewZ; + YC = NewYC; + FNeutralConductor = 0; + ReduceByKron = false; + + /*Change Property values to reflect Kron reduction for save circuit function*/ + Set_PropertyValue(1,Format("%d", Fnphases)); + Set_PropertyValue(9,get_Rmatrix()); + Set_PropertyValue(10,get_Xmatrix()); + Set_PropertyValue(11,get_CMatrix()); + } + else + { + DoSimpleMsg(Format("Kron Reduction failed: LineCode.%s. Attempting to eliminate Neutral Conductor %d.", get_Name().c_str(), FNeutralConductor), 103); + } + } + else + { + DoSimpleMsg(String("Cannot perform Kron Reduction on a 1-phase LineCode: LineCode.") + get_Name(), 103); + } +} + + + + +} // namespace LineCode + + + + + diff --git a/OpenDSSC/General/LineCode.h b/OpenDSSC/General/LineCode.h new file mode 100644 index 0000000..8114881 --- /dev/null +++ b/OpenDSSC/General/LineCode.h @@ -0,0 +1,127 @@ +#ifndef LineCodeH +#define LineCodeH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Arraydef.h" + + +namespace LineCode +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*The Linecode object is a general DSS object used by all circuits + as a reference for obtaining line impedances. + + The values are set by the normal New and Edit procedures for any DSS object. + + The values are retrieved by setting the Code Property in the LineCode Class. + This sets the active Linecode object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. + + */ + +class TLineCode : public DSSClass::TDSSClass +{ + friend class TLineCodeObj; +public: + typedef DSSClass::TDSSClass inherited; +private: + bool SymComponentsChanged; + bool MatrixChanged; + string Get_Code(); // Returns active line code string + void Set_Code(const String Value); // sets the active linecode + void SetZ1Z0(int i, double Value); + void SetUnits(const String s); // decode units specification + void DoMatrix(int i, int ActorID); // set impedances as matrices +protected: + void DefineProperties(); + virtual int MakeLike(const String LineName); +public: + TLineCode(); + virtual ~TLineCode(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TLineCodeObj : public DSSObject::TDSSObject +{ + friend class TLineCode; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int FNeutralConductor; + void Set_NPhases(int Value); + void DoKronReduction(); + string get_Rmatrix(); + string get_Xmatrix(); + string get_CMatrix(); +public: + int NumAmpRatings; + int Fnphases; + bool SymComponentsModel; + bool ReduceByKron; // Base Frequency Series Z matrix + Ucmatrix::TcMatrix* Z; + Ucmatrix::TcMatrix* Zinv; + Ucmatrix::TcMatrix* YC; // Shunt capacitance matrix at Base frequency. + double BaseFrequency; + double R1; + double X1; + double R0; + double X0; + double C1; + double C0; + double NormAmps; + double EmergAmps; + double FaultRate; + double PctPerm; + double HrsToRepair; + double Rg; + double Xg; + double rho; + Arraydef::TRatingsArray AmpRatings; + int FLineType; // Pointer to code for type of line + int Units; /*See LineUnits*/ + + int get_Fnphases(); + + TLineCodeObj(DSSClass::TDSSClass* ParClass, const String LineCodeName); + virtual ~TLineCodeObj(); + void CalcMatricesFromZ1Z0(); + virtual string GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TLineCodeObj(DSSClass::TDSSClass* ParClass); + TLineCodeObj(String ClassName); + TLineCodeObj(); +}; +extern TLineCode* LineCodeClass; +extern TLineCodeObj* ActiveLineCodeObj; + + +} // namespace LineCode + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LineCode; +#endif + +#endif // LineCodeH + + + + + diff --git a/OpenDSSC/General/LineConstants.cpp b/OpenDSSC/General/LineConstants.cpp new file mode 100644 index 0000000..4096833 --- /dev/null +++ b/OpenDSSC/General/LineConstants.cpp @@ -0,0 +1,652 @@ + + +#pragma hdrstop + +#include "LineConstants.h" +#include "DSSGlobals.h" +#include "mathutil.h" +#include + +using namespace std; +using namespace Arraydef; +using namespace DSSGlobals; +using namespace LineUnits; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; + +namespace LineConstants +{ + +TLineConstants::TLineConstants() {} + + +complex C1_j1 = {}; +double B1 = 0.0; +double B2 = 0.0; +double B3 = 0.0; +double B4 = 0.0; +double D2 = 0.0; +double D4 = 0.0; +double C2 = 0.0; +double c4 = 0.0; + + + +/* TLineConstants */ +/*Compute base Z and YC matrices in ohms/m for this frequency and earth impedance*/ + +void TLineConstants::Calc(double f) +{ + bool PowerFreq = false; + complex Temp = {}; + complex Zi = {}; + complex Zspacing = {}; + complex LFactor = {}; + int ReducedSize = 0; + int i = 0; + int j = 0; + double Dij = 0.0; + double Dijp = 0.0; + double Pfactor = 0.0; + + // RhoEarth := rho; + int stop = 0; + Set_Frequency(f); // this has side effects + if(ASSIGNED(FZreduced)) + { + ReducedSize = FZreduced->get_Norder(); + delete FZreduced; + } + else + ReducedSize = 0; + if(ASSIGNED(FYCreduced)) + delete FYCreduced; + FZreduced = nullptr; + FYCreduced = nullptr; + FZmatrix->Clear(); + FYCmatrix->Clear(); + + /*For less than 1 kHz use GMR to better match published data*/ + LFactor = cmplx(0.0, Fw * mu0 / TwoPi); + if((f < 1000.0) && (f > 40.0)) + PowerFreq = true; + else + PowerFreq = false; + + /*Self Impedances*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + Zi = Get_Zint(i); + if(PowerFreq) // for less than 1 kHz, use published GMR + { + Zi.im = 0.0; + Zspacing = cmulreal(LFactor, log(1.0 / FGMR[i - 1])); // use GMR + } + else + { + Zspacing = cmulreal(LFactor, log(1.0 / Fradius[i - 1])); + } + Temp = Get_Ze(i, i); + FZmatrix->SetElement(i, i, cadd(Zi, cadd(Zspacing, Get_Ze(i, i)))); + } + + /*Mutual IMpedances*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + FZmatrix->SetElemsym(i, j, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + } + + /*Capacitance Matrix*/ + Pfactor = -1.0 / TwoPi / E0 / Fw; // include frequency + + /*Construct P matrix and then invert*/ + + /*Self uses capradius, which defaults to actual conductor radius. But + in case of bundled conductors can be specified different in Wiredata.*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + FYCmatrix->SetElement(i, i, cmplx(0.0, Pfactor * log(2.0 * FY[i - 1] / Fcapradius[i - 1]))); + } + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + Dijp = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] + FY[j - 1])); // distance to image j + FYCmatrix->SetElemsym(i, j, cmplx(0.0, Pfactor * log(Dijp / Dij))); + } + } + FYCmatrix->Invert(); // now should be nodal C matrix + if(ReducedSize > 0) + Kron(ReducedSize); // Was reduced so reduce again to same size + + /*Else the Zmatrix is OK as last computed*/ + FRhoChanged = false; +} + +bool TLineConstants::ConductorsInSameSpace(string& ErrorMessage) +{ + bool result = false; + int i = 0; + int j = 0; + double Dij = 0.0; +/*Check all conductors to make sure none occupy the same space or are defined at 0,0*/ + int stop = 0; + result = false; + + /*Check for 0 Y coordinate*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + if(FY[i - 1] <= 0.0) + { + result = true; + ErrorMessage = Format("Conductor %d height must be > 0. ",i); + return result; + } + } + + /*Check for overlapping conductors*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = FNumConds, j = i + 1; j <= stop1; j++) + { + Dij = sqrt(sqr(FX[i - 1] - FX[j - 1]) + sqr(FY[i - 1] - FY[j - 1])); + if(Dij < (Fradius[i - 1] + Fradius[j - 1])) + { + result = true; + ErrorMessage = Format("Conductors %d and %d occupy the same space.",i, j); + return result; + } + } + } + return result; +} + +TLineConstants::TLineConstants(int NumConductors) + : FNumConds(NumConductors), + FNumPhases(0), + FZmatrix(nullptr), + FYCmatrix(nullptr), + FZreduced(nullptr), + FYCreduced(nullptr), + FFrequency(0.0), + Fw(0.0), + FrhoEarth(0.0), + FRhoChanged(false) +{ + int i = 0; + int stop = 0; + Set_NPhases(FNumConds); + FX.resize(FNumConds, 0); + FY.resize(FNumConds, 0); + FGMR.resize(FNumConds, 0); + Fradius.resize(FNumConds, 0); + Fcapradius.resize(FNumConds, 0); + FRDC.resize(FNumConds, 0); + Frac.resize(FNumConds, 0); + + + /*Initialize to not set*/ + for(stop = FNumConds, i = 1; i <= stop; i++) + { + FGMR[i - 1] = -1.0; + } + for(stop = FNumConds, i = 1; i <= stop; i++) + { + Fradius[i - 1] = -1.0; + } + for(stop = FNumConds, i = 1; i <= stop; i++) + { + Fcapradius[i - 1] = -1.0; + } + for(stop = FNumConds, i = 1; i <= stop; i++) + { + FRDC[i - 1] = -1.0; + } + FZmatrix = new TcMatrix(FNumConds); + FYCmatrix = new TcMatrix(FNumConds); + FFrequency = -1.0; // not computed + FrhoEarth = 100.0; // default value + FRhoChanged = true; + FZreduced = nullptr; + FYCreduced = nullptr; +} + +TLineConstants::~TLineConstants() +{ + if(ASSIGNED(FZmatrix)) + delete FZmatrix; + if(ASSIGNED(FYCmatrix)) + delete FYCmatrix; + if(ASSIGNED(FZreduced)) + delete FZreduced; + if(ASSIGNED(FYCreduced)) + delete FYCreduced; + FX.clear(); + FY.clear(); + FGMR.clear(); + Fradius.clear(); + Fcapradius.clear(); + FRDC.clear(); + Frac.clear(); + // inherited; +} + + +double TLineConstants::Get_Capradius(int i, int Units) +{ + double result = 0.0; + result = Fcapradius[i - 1] * From_Meters(Units); + return result; +} + +double TLineConstants::Get_GMR(int i, int Units) +{ + double result = 0.0; + result = FGMR[i - 1] * From_Meters(Units); + return result; +} + +double TLineConstants::Get_Rac(int i, int Units) +{ + double result = 0.0; + result = Frac[i - 1] * From_per_Meter(Units); + return result; +} + +double TLineConstants::Get_radius(int i, int Units) +{ + double result = 0.0; + result = Fradius[i - 1] * From_Meters(Units); + return result; +} + +double TLineConstants::Get_Rdc(int i, int Units) +{ + double result = 0.0; + result = FRDC[i - 1] * From_per_Meter(Units); + return result; +} + +double TLineConstants::Get_X(int i, int Units) +{ + double result = 0.0; + result = FX[i - 1] * From_Meters(Units); + return result; +} + +double TLineConstants::Get_Y(int i, int Units) +{ + double result = 0.0; + result = FY[i - 1] * From_Meters(Units); + return result; +} +/*Makes a new YCmatrix and correct for lengths and units as it copies*/ +/*Uses the reduced Zmatrix by default if it exists*/ + +TcMatrix* TLineConstants::Get_YCmatrix(double f, double loggth, int Units) +{ + TcMatrix* result = nullptr; + int NewSize = 0; + int i = 0; + double UnitLengthConversion = 0.0; + TcMatrix* YC = nullptr; + pComplexArray YCValues = nullptr; + int stop = 0; + if(ASSIGNED(FYCreduced)) + { + YC = FYCreduced; + } + else + { + YC = FYCmatrix; + } + NewSize = YC->get_Norder(); + result = new TcMatrix(NewSize); + result->CopyFrom(YC); + YCValues = result->GetValuesArrayPtr(NewSize); + UnitLengthConversion = From_per_Meter(Units) * loggth; + for(stop = NewSize * NewSize, i = 1; i <= stop; i++) + { + cmulrealaccum(YCValues[i - 1], UnitLengthConversion); + } + return result; +} + +complex TLineConstants::Get_Ze(int i, int j) +{ + complex result = {}; + complex logArg = {}; + complex hterm = {}; + complex xterm = {}; + double mij = 0.0; + double thetaij = 0.0; + double Dij = 0.0; + double Fyi = 0.0; + double Fyj = 0.0; + double term1 = 0.0; + double term2 = 0.0; + double term3 = 0.0; + double term4 = 0.0; + double term5 = 0.0; + Fyi = Abs(FY[i - 1]); + Fyj = Abs(FY[j - 1]); + switch(ActiveEarthModel[ActiveActor]) + { + case SIMPLECARSON: + { + result = cmplx(Fw * mu0 / 8.0, (Fw * mu0 / TwoPi) * log(658.5L * sqrt(FrhoEarth / FFrequency))); + // {****} WriteDLLDebugFile(Format('Simple: Z(%d,%d) = %.8g +j %.8g',[i,j, Result.re, result.im])); + } + break; + /*notation from Tleis book Power System Modelling and Fault Analysis*/ + case FULLCARSON: + { + if(i == j) + { + thetaij = 0.0; + Dij = 2.0 * Fyi; + } + else + { + Dij = sqrt(sqr(Fyi + Fyj) + sqr(FX[i - 1] - FX[j - 1])); + thetaij = acos((Fyi + Fyj) / Dij); + } + mij = 2.8099e-3 * Dij * sqrt(FFrequency / FrhoEarth); + result.re = double(DSSGlobals::PI) / 8.0 - B1 * mij * cos(thetaij) + B2 * sqr(mij) * (log(exp(C2) / mij) * cos(2.0 * thetaij) + thetaij * sin(2.0 * thetaij)) + B3 * mij * mij * mij * cos(3.0 * thetaij) - D4 * mij * mij * mij * mij * cos(4.0 * thetaij); + term1 = 0.5L * log(1.85138 / mij); + term2 = B1 * mij * cos(thetaij); + term3 = -D2 * sqr(mij) * cos(2.0 * thetaij); + term4 = B3 * mij * mij * mij * cos(3.0 * thetaij); + term5 = -B4 * mij * mij * mij * mij * (log(exp(c4) / mij) * cos(4.0 * thetaij) + thetaij * sin(4.0 * thetaij)); + result.im = term1 + term2 + term3 + term4 + term5; + result.im = result.im + 0.5 * log(Dij); // correction term to work with DSS structure + result = cmulreal(result, Fw * mu0 / DSSGlobals::PI); + + // {****} WriteDLLDebugFile(Format('Full: Z(%d,%d) = %.8g +j %.8g; Dij=%.8g, thetaij=%.8g, mij=%.8g, Terms= %.8g, %.8g, %.8g, %.8g, %.8g',[i,j, Result.re, result.im, Dij, thetaij*180.0/pi, mij, term1, term2, term3, term4, term5])); + } + break; + case DERI: + { + if(i != j) + { + hterm = cadd(cmplx(Fyi + Fyj, 0.0), cmulreal(cinv(Fme), 2.0)); + xterm = cmplx(FX[i - 1] - FX[j - 1], 0.0); + logArg = csqrt(cadd(cmul(hterm, hterm), cmul(xterm, xterm))); + result = cmul(cmplx(0.0, Fw * mu0 / TwoPi), CLn(logArg)); + } + else + { + hterm = cadd(cmplx(Fyi, 0.0), cinv(Fme)); + result = cmul(cmplx(0.0, Fw * mu0 / TwoPi), CLn(cmulreal(hterm, 2.0))); + } + // {****} WriteDLLDebugFile(Format('Deri: Z(%d,%d) = %.8g +j %.8g; hterm= %.8g + j %.8g',[i,j, Result.re, result.im, hterm.re, hterm.im])); + } + break; + default: + ; + break; + } + return result; +} + +//--------------------------------------------------------------------------------------------------------------- + +int TLineConstants::get_FNumConds() +{ + return FNumConds; +} + +//--------------------------------------------------------------------------------------------------------------- + +int TLineConstants::get_FNumPhases() +{ + return FNumPhases; +} + +//--------------------------------------------------------------------------------------------------------------- + +complex TLineConstants::Get_Zint(int i) +{ + complex result = {}; + complex Alpha = {}; + complex I0I1 = {}; + switch(ActiveEarthModel[ActiveActor]) + { + case SIMPLECARSON: + { + result = cmplx(Frac[i - 1], Fw * mu0 / (8 * DSSGlobals::PI)); + } + break; // no skin effect + case FULLCARSON: + { + result = cmplx(Frac[i - 1], Fw * mu0 / (8 * DSSGlobals::PI)); + } + break; // with skin effect model + + /*Assume round conductor*/ + case DERI: + { + Alpha = cmulreal(C1_j1, sqrt(FFrequency * mu0 / FRDC[i - 1])); + if(cabs(Alpha) > 35.0) + I0I1 = cONE; + else + I0I1 = cdiv(Bessel_I0(Alpha), Bessel_I1(Alpha)); + result = cmulreal(cmul(C1_j1, I0I1), sqrt(FRDC[i - 1] * FFrequency * mu0) / 2.0); + } + break; + default: + ; + break; + } + return result; +} + +//-------------------------------------------------------------------------------------------------- + +double TLineConstants::get_FrhoEarth() +{ + return FrhoEarth; +} + +//-------------------------------------------------------------------------------------------------- + +/*Makes a new Zmatrix and correct for lengths and units as it copies*/ +/*Uses the reduced Zmatrix by default if it exists*/ + +TcMatrix* TLineConstants::Get_Zmatrix(double f, double loggth, int Units) +{ + TcMatrix* result = nullptr; + int NewSize = 0; + int i = 0; + double UnitLengthConversion = 0.0; + TcMatrix* Z = nullptr; + pComplexArray Zvalues = nullptr; + int stop = 0; + if((f != FFrequency) || FRhoChanged) + Calc(f); // only recalcs if f changed or rho earth changed + if(ASSIGNED(FZreduced)) + { + Z = FZreduced; + } + else + { + Z = FZmatrix; + } + NewSize = Z->get_Norder(); + result = new TcMatrix(NewSize); + result->CopyFrom(Z); // gets ohms/meter + Zvalues = result->GetValuesArrayPtr(NewSize); // ptr to the values in the new copy + /*Convert the values by units and length*/ + UnitLengthConversion = From_per_Meter(Units) * loggth; + for(stop = NewSize * NewSize, i = 1; i <= stop; i++) + { + cmulrealaccum(Zvalues[i - 1], UnitLengthConversion); + } + + return result; +} + +void TLineConstants::Kron(int Norder) +{ + TcMatrix* Ztemp = nullptr; + bool FirstTime = false; + int i = 0; + int j = 0; + Ztemp = FZmatrix; + FirstTime = true; + if((FFrequency >= 0.0) && (Norder > 0) && (Norder < FNumConds)) + { + int stop = 0; + if(ASSIGNED(FZreduced)) + free( FZreduced ); + if(ASSIGNED(FYCreduced)) + free( FYCreduced ); + + /*Reduce computed matrix one row/col at a time until it is norder*/ + while(Ztemp->get_Norder() > Norder) + { + FZreduced = Ztemp->Kron(Ztemp->get_Norder()); // Eliminate last row + if(!FirstTime) // don't throw away original matrix + { + free( Ztemp ); // Ztemp now points to intermediate matrix + } + Ztemp = FZreduced; + FirstTime = false; + } + + /*Extract norder x norder portion of Yc matrx*/ + FYCreduced = new TcMatrix(Norder); + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + FYCreduced->SetElement(i, j, FYCmatrix->GetElement(i, j)); + } + } + + /*Left with reduced matrix*/ + } +} + +/*Performs a Kron reduction to get rid of neutral conductors*/ + +void TLineConstants::Reduce() +{ + Kron(FNumPhases); +} + +void TLineConstants::Set_Capradius(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + { + Fcapradius[i - 1] = Value * To_Meters(Units); + } +} + +void TLineConstants::Set_Frequency(double Value) +{ + FFrequency = Value; + Fw = TwoPi * FFrequency; + Fme = csqrt(cmplx(0.0, Fw * mu0 / FrhoEarth)); +} + +void TLineConstants::Set_Frhoearth(double Value) +{ + if(Value != FrhoEarth) + FRhoChanged = true; + FrhoEarth = Value; + if(FFrequency >= 0.0) + Fme = csqrt(cmplx(0.0, Fw * mu0 / FrhoEarth)); +} + +void TLineConstants::Set_GMR(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + { + FGMR[i - 1] = Value * To_Meters(Units); + if(Fradius[i - 1] < 0.0) + Fradius[i - 1] = FGMR[i - 1] / 0.7788; // equivalent round conductor + } +} + +void TLineConstants::Set_NPhases(int Value) +{ + FNumPhases = Value; +} + +void TLineConstants::Set_Rac(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + Frac[i - 1] = Value * To_per_Meter(Units); +} + +void TLineConstants::Set_radius(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + { + Fradius[i - 1] = Value * To_Meters(Units); + if(FGMR[i - 1] < 0.0) + FGMR[i - 1] = Fradius[i - 1] * 0.7788; // Default to round conductor + } +} + +void TLineConstants::Set_Rdc(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FRDC[i - 1] = Value * To_per_Meter(Units); +} + +void TLineConstants::Set_X(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FX[i - 1] = Value * To_Meters(Units); +} + +void TLineConstants::Set_Y(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FY[i - 1] = Value * To_Meters(Units); +} + + +void LineConstants_initialization() +{ + C1_j1 = cmplx(1.0, 1.0); + B1 = 1.0 / (3.0L * sqrt(2.0L)); + B2 = 1.0 / 16.0; + B3 = B1 / 3.0 / 5.0; + B4 = B2 / 4.0 / 6.0; + D2 = B2 * DSSGlobals::PI / 4.0; + D4 = B4 * DSSGlobals::PI / 4.0; + C2 = 1.3659315; + c4 = C2 + 1.0 / 4.0 + 1.0 / 6.0; +} + + class LineConstants_unit + { + public: + LineConstants_unit() + { + //AssertSystemInitialization(); + LineConstants_initialization(); + } + }; + LineConstants_unit _LineConstants_unit; + +} // namespace LineConstants + + + + + diff --git a/OpenDSSC/General/LineConstants.h b/OpenDSSC/General/LineConstants.h new file mode 100644 index 0000000..b66cf63 --- /dev/null +++ b/OpenDSSC/General/LineConstants.h @@ -0,0 +1,122 @@ +#ifndef LineConstantsH +#define LineConstantsH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LineUnits.h" + +namespace LineConstants +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Manages the geometry data and calculates the impedance matrices for an overhead line*/ + +/*Usage: Create with Number of conductors you want + Specify the number of phases. The first conductors you define with + be the phases. Other conductors may be considered neutral. + + Uses GMR for power frequency calcs so that answers match published + data. + + You only have to set R or GMR. The other will default. However, you should set + both for better accuracy. + + When you ask for Zmatrix or YCmatrix you get the full matrix unless you have executed + a Kron reduction or Reduce function. Reduce eleminates all non phases. If you + want the full detailed model, DO NOT REDUCE! + +*/ + +/*This class returns a matrix ordered by phases first then remaining conductors + Assumes phases are defined first*/ + +class TLineConstants : public System::TObject +{ +public: + typedef TObject inherited; +//private: +//protected: + int FNumConds; + int FNumPhases; + std::vector FX; + std::vector FY; + std::vector FRDC; // ohms/m + std::vector Frac; // ohms/m + std::vector FGMR; // m + std::vector Fradius; + std::vector Fcapradius; // if different than radius; defaults to radius + // Primarily for bundled conductors + Ucmatrix::TcMatrix* FZmatrix; // in ohms/m + Ucmatrix::TcMatrix* FYCmatrix; // siemens/m --- jwC + Ucmatrix::TcMatrix* FZreduced; // These two do not exist until Kron Reduction + Ucmatrix::TcMatrix* FYCreduced; // is executed + double FFrequency; // Frequency for which impedances are computed + double Fw; // 2piF + double FrhoEarth; // ohm-m + Ucomplex::complex Fme; // factor for earth impedance + bool FRhoChanged; + double Get_GMR(int i, int Units); + double Get_radius(int i, int Units); + double Get_Rdc(int i, int Units); + double Get_Rac(int i, int Units); + double Get_X(int i, int Units); + double Get_Y(int i, int Units); + Ucmatrix::TcMatrix* Get_YCmatrix(double f, double Lngth, int Units); + Ucomplex::complex Get_Ze(int i, int j); + Ucomplex::complex Get_Zint(int i); + Ucmatrix::TcMatrix* Get_Zmatrix(double f, double Lngth, int Units); + void Set_GMR(int i, int Units, double Value); + void Set_radius(int i, int Units, double Value); + void Set_Rdc(int i, int Units, double Value); + void Set_Rac(int i, int Units, double Value); + void Set_X(int i, int Units, double Value); + void Set_Y(int i, int Units, double Value); + void Set_Frequency(double Value); + void Set_Frhoearth(double Value); // m + // This allows you to compute capacitance using a different radius -- for bundled conductors + double Get_Capradius(int i, int Units); + void Set_Capradius(int i, int Units, double Value); + + /*These can only be called privately*/ + void Set_NPhases(int Value); +public: + virtual bool ConductorsInSameSpace(std::string& ErrorMessage); + virtual void Calc(double f); // force a calc of impedances + virtual void Kron(int Norder); // Performs a Kron reduction leaving first Norder rows + void Reduce(); // Kron reduce to Numphases only + double get_FrhoEarth(); + int get_FNumConds(); + int get_FNumPhases(); + + TLineConstants(int NumConductors); + virtual ~TLineConstants(); + TLineConstants(); +}; +const double E0 = 8.854e-12; // dielectric constant F/m +const double mu0 = 12.56637e-7; // hy/m +//const double TwoPi = 6.283185307; + + +} // namespace LineConstants + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LineConstants; +#endif + +#endif // LineConstantsH + + + + + diff --git a/OpenDSSC/General/LineGeometry.cpp b/OpenDSSC/General/LineGeometry.cpp new file mode 100644 index 0000000..74c9a5d --- /dev/null +++ b/OpenDSSC/General/LineGeometry.cpp @@ -0,0 +1,1184 @@ + +#pragma hdrstop + +#include "LineGeometry.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucomplex.h" +#include "Utilities.h" +#include "LineUnits.h" +#include "OHLineConstants.h" +#include "CNLineConstants.h" +#include "TSLineConstants.h" + + +using namespace std; +using namespace Arraydef; +using namespace CNData; +using namespace CNLineConstants; +using namespace Command; +using namespace ConductorData; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineConstants; +using namespace LineSpacing; +using namespace LineUnits; +using namespace OHLineConstants; +using namespace ParserDel; +using namespace System; +using namespace TSData; +using namespace TSLineConstants; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace LineGeometry +{ + +ELineGeometryProblem::ELineGeometryProblem(const String &Msg) : inherited(Msg) {} + +TLineGeometryObj::TLineGeometryObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TLineGeometryObj::TLineGeometryObj(String ClassName) : inherited(ClassName) {} +TLineGeometryObj::TLineGeometryObj() {} + + +TLineGeometryObj* ActiveLineGeometryObj = nullptr; + +const int NumPropsThisClass = 19; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TLineGeometry::TLineGeometry() +{ + ; + Class_Name = "LineGeometry"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineGeometry::~TLineGeometry() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineGeometry::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + PropertyName[1 - 1] = "nconds"; + PropertyName[2 - 1] = "nphases"; + PropertyName[3 - 1] = "cond"; + PropertyName[4 - 1] = "wire"; + PropertyName[5 - 1] = "x"; + PropertyName[6 - 1] = "h"; + PropertyName[7 - 1] = "units"; + PropertyName[8 - 1] = "normamps"; + PropertyName[9 - 1] = "emergamps"; + PropertyName[10 - 1] = "reduce"; + PropertyName[11 - 1] = "spacing"; + PropertyName[12 - 1] = "wires"; + PropertyName[13 - 1] = "cncable"; + PropertyName[14 - 1] = "tscable"; + PropertyName[15 - 1] = "cncables"; + PropertyName[16 - 1] = "tscables"; + PropertyName[17 - 1] = "Seasons"; + PropertyName[18 - 1] = "Ratings"; + PropertyName[19 - 1] = "LineType"; + PropertyHelp[1 - 1] = "Number of conductors in this geometry. Default is 3. Triggers memory allocations. Define first!"; + PropertyHelp[2 - 1] = "Number of phases. Default =3; All other conductors are considered neutrals and might be reduced out."; + PropertyHelp[3 - 1] = "Set this = number of the conductor you wish to define. Default is 1."; + PropertyHelp[4 - 1] = String("Code from WireData. MUST BE PREVIOUSLY DEFINED. no default.") + CRLF + + "Specifies use of Overhead Line parameter calculation," + + CRLF + + "Unless Tape Shield cable previously assigned to phases, and this wire is a neutral."; + PropertyHelp[5 - 1] = "x coordinate."; + PropertyHelp[6 - 1] = "Height of conductor."; + PropertyHelp[7 - 1] = "Units for x and h: {mi|kft|km|m|Ft|in|cm } Initial default is \"ft\", but defaults to last unit defined"; + PropertyHelp[8 - 1] = "Normal ampacity, amperes for the line. Defaults to first conductor if not specified."; + PropertyHelp[9 - 1] = "Emergency ampacity, amperes. Defaults to first conductor if not specified."; + PropertyHelp[10 - 1] = "{Yes | No} Default = no. Reduce to Nphases (Kron Reduction). Reduce out neutrals."; + PropertyHelp[11 - 1] = String("Reference to a LineSpacing for use in a line constants calculation.") + CRLF + + "Alternative to x, h, and units. MUST BE PREVIOUSLY DEFINED." + + CRLF + + "Must match \"nconds\" as previously defined for this geometry." + + CRLF + + "Must be used in conjunction with the Wires property."; + PropertyHelp[12 - 1] = String("Array of WireData names for use in a line constants calculation.") + CRLF + + "Alternative to individual wire inputs. ALL MUST BE PREVIOUSLY DEFINED." + + CRLF + + "Must match \"nconds\" as previously defined for this geometry," + + CRLF + + "unless TSData or CNData were previously assigned to phases, and these wires are neutrals." + + CRLF + + "Must be used in conjunction with the Spacing property."; + PropertyHelp[13 - 1] = String("Code from CNData. MUST BE PREVIOUSLY DEFINED. no default.") + CRLF + + "Specifies use of Concentric Neutral cable parameter calculation."; + PropertyHelp[14 - 1] = String("Code from TSData. MUST BE PREVIOUSLY DEFINED. no default.") + CRLF + + "Specifies use of Tape Shield cable parameter calculation."; + PropertyHelp[15 - 1] = String("Array of CNData names for cable parameter calculation.") + CRLF + + "All must be previously defined, and match \"nphases\" for this geometry." + + CRLF + + "You can later define \"nconds-nphases\" wires for bare neutral conductors."; + PropertyHelp[16 - 1] = String("Array of TSData names for cable parameter calculation.") + CRLF + + "All must be previously defined, and match \"nphases\" for this geometry." + + CRLF + + "You can later define \"nconds-nphases\" wires for bare neutral conductors."; + PropertyHelp[17 - 1] = "Defines the number of ratings to be defined for the wire, to be used only when defining seasonal ratings using the " + "\"Ratings\" property. Defaults to first conductor if not specified."; + PropertyHelp[18 - 1] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in lines." + + "Defaults to first conductor if not specified."; + PropertyHelp[19 - 1] = String("Code designating the type of line. ") + CRLF + + "One of: OH, UG, UG_TS, UG_CN, SWT_LDBRK, SWT_FUSE, SWT_SECT, SWT_REC, SWT_DISC, SWT_BRK, SWT_ELBOW" + + CRLF + + CRLF + + "OpenDSS currently does not use this internally. For whatever purpose the user defines. Default is OH."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineGeometry::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TLineGeometryObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineGeometry::Edit(int ActorID) +{ + int result = 0; + int i = 0; + int iStart = 0; + int istop = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveLineGeometryObj = ((TLineGeometryObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveLineGeometryObj; + /*# with ActiveLineGeometryObj do */ + { + auto with0 = ActiveLineGeometryObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 10101); + break; + case 1: + with0->Set_Nconds(Parser[ActorID]->MakeInteger_()); + break; // Use property value to force reallocations + case 2: + with0->Fnphases = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->set_ActiveCond(Parser[ActorID]->MakeInteger_()); + break; + case 4: + { + with0->FCondName[with0->get_FActiveCond() - 1] = Param; + if((with0->FPhaseChoice[with0->get_FActiveCond() - 1] == unknown) || (with0->FPhaseChoice[with0->get_FActiveCond() - 1] == Overhead)) + with0->ChangeLineConstantsType(Overhead); + } + break; + case 5: + with0->FX[with0->get_FActiveCond() - 1] = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->FY[with0->get_FActiveCond() - 1] = Parser[ActorID]->MakeDouble_(); + break; + case 7: + { + with0->FUnits[with0->get_FActiveCond() - 1] = GetUnitsCode(Param); + with0->FLastUnit = (with0->FUnits)[with0->get_FActiveCond() - 1]; + } + break; + case 8: + with0->NormAmps = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->EmergAmps = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->FReduce = InterpretYesNo(Param); + break; + case 11: + { + with0->FSpacingType = Parser[ActorID]->MakeString_(); + if(LineSpacingClass[ActorID]->SetActive(with0->FSpacingType)) + { + ActiveLineSpacingObj = ((TLineSpacingObj*) LineSpacingClass[ActorID]->GetActiveObj()); + if(with0->Fnconds == ActiveLineSpacingObj->get_Fnconds()) + { + int stop = 0; + with0->FLastUnit = ActiveLineSpacingObj->get_FUnits(); + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + with0->FX[i - 1] = ActiveLineSpacingObj->Get_FX(i); + with0->FY[i - 1] = ActiveLineSpacingObj->Get_FY(i); + with0->FUnits[i - 1] = with0->FLastUnit; + } + } + else + DoSimpleMsg(String("LineSpacing object ") + with0->FSpacingType + + " has the wrong number of wires.", 10103); + } + else + DoSimpleMsg(String("LineSpacing object ") + with0->FSpacingType + + " has not been defined.", 10103); + } + break; + case 13: + { + (with0->FCondName)[with0->get_FActiveCond() - 1] = Param; + with0->ChangeLineConstantsType(ConcentricNeutral); + } + break; + case 14: + { + (with0->FCondName)[with0->get_FActiveCond() - 1] = Param; + with0->ChangeLineConstantsType(TapeShield); + } + break; + case 12: case 15: case 16: + { + int stop = 0; + iStart = 1; + istop = with0->Fnconds; + if(ParamPointer == 15) + { + with0->ChangeLineConstantsType(ConcentricNeutral); + istop = with0->Fnphases; + } + else + { + if(ParamPointer == 16) + { + with0->ChangeLineConstantsType(TapeShield); + istop = with0->Fnphases; + } + else + { + if(ParamPointer == 12) + { + if(with0->FPhaseChoice[with0->get_FActiveCond() - 1] == unknown) + with0->ChangeLineConstantsType(Overhead); + else + { + if(with0->FPhaseChoice[with0->get_FActiveCond() - 1] != Overhead) // these are buried neutral wires + iStart = with0->Fnphases + 1; // to fix the bug introduced with ActiveCond + } + } + } + } + AuxParser[ActorID]->SetCmdString(Parser[ActorID]->MakeString_()); + for(stop = istop, i = iStart; i <= stop; i++) + { + String dummy = AuxParser[ActorID]->GetNextParam(); // ignore any parameter name not expecting any + (with0->FCondName)[i - 1] = AuxParser[ActorID]->MakeString_(); + if(ParamPointer == 15) + CNDataClass[ActorID]->Set_Code((with0->FCondName)[i - 1]); + else + { + if(ParamPointer == 16) + TSDataClass[ActorID]->Set_Code((with0->FCondName)[i - 1]); + else + WireDataClass[ActorID]->Set_Code((with0->FCondName)[i - 1]); + } + if(ASSIGNED(ActiveConductorDataObj)) + { + with0->FWireData[i - 1] = ActiveConductorDataObj; + if(i == 1) + { + if((ActiveConductorDataObj->NormAmps > 0.0) && (with0->NormAmps == 0.0)) + with0->NormAmps = ActiveConductorDataObj->NormAmps; + if((ActiveConductorDataObj->EmergAmps > 0.0) && (with0->EmergAmps == 0.0)) + with0->EmergAmps = ActiveConductorDataObj->EmergAmps; + if((ActiveConductorDataObj->NumAmpRatings > 1) && (with0->NumAmpRatings == 1)) + with0->NumAmpRatings = ActiveConductorDataObj->NumAmpRatings; + if((!ActiveConductorDataObj->AmpRatings.empty()) && (!with0->AmpRatings.empty())) + { + with0->AmpRatings.resize(with0->NumAmpRatings); + with0->AmpRatings = ActiveConductorDataObj->AmpRatings; + } + } + } + else + { + if(ParamPointer == 15) + DoSimpleMsg(String("CNData Object \"") + (with0->FCondName)[i] + + "\" not defined. Must be previously defined.", 10103); + else + { + if(ParamPointer == 16) + DoSimpleMsg(String("TSData Object \"") + (with0->FCondName)[i] + + "\" not defined. Must be previously defined.", 10103); + else + DoSimpleMsg(String("WireData Object \"") + (with0->FCondName)[i] + + "\" not defined. Must be previously defined.", 10103); + } + } + } + } + break; + case 17: + { + with0->NumAmpRatings = Parser[ActorID]->MakeInteger_(); + with0->AmpRatings.resize(with0->NumAmpRatings); + } + break; + case 18: + { + with0->AmpRatings.resize(with0->NumAmpRatings); + Param = Parser[ActorID]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, (pDoubleArray) &(with0->AmpRatings[0])); + } + break; + case 19: + with0->FLineType = LineTypeList.Getcommand(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveLineGeometryObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Set defaults*/ + switch(ParamPointer) + { + case 2: + if(with0->Fnphases > with0->Fnconds) + with0->Fnphases = with0->Fnconds; + break; + case 3: + if((with0->get_FActiveCond() < 1) || (with0->get_FActiveCond() > with0->Fnconds)) + DoSimpleMsg(String("Illegal cond= specification in Line Geometry:") + CRLF + + Parser[ActorID]->get_CmdBuffer(), 10102); + break; + case 4: case 13: case 14: + { + if(ParamPointer == 4) + WireDataClass[ActorID]->Set_Code(Param); + else + { + if(ParamPointer == 13) + CNDataClass[ActorID]->Set_Code(Param); + else + TSDataClass[ActorID]->Set_Code(Param); + } + if(ASSIGNED(ActiveConductorDataObj)) + { + with0->FWireData[with0->get_FActiveCond() - 1] = ActiveConductorDataObj; + /*Default the current ratings for this geometry to the rating of the first conductor*/ + if(with0->get_FActiveCond() == 1) + { + if((ActiveConductorDataObj->NormAmps > 0.0) && (with0->NormAmps == 0.0)) + with0->NormAmps = ActiveConductorDataObj->NormAmps; + if((ActiveConductorDataObj->EmergAmps > 0.0) && (with0->EmergAmps == 0.0)) + with0->EmergAmps = ActiveConductorDataObj->EmergAmps; + if((ActiveConductorDataObj->NumAmpRatings > 1) && (with0->NumAmpRatings == 1)) + with0->NumAmpRatings = ActiveConductorDataObj->NumAmpRatings; + if((!ActiveConductorDataObj->AmpRatings.empty()) && (!with0->AmpRatings.empty())) + { + with0->AmpRatings.resize(with0->NumAmpRatings); + with0->AmpRatings = ActiveConductorDataObj->AmpRatings; + } + } + } + else + { + if(ParamPointer == 4) + DoSimpleMsg(String("WireData Object \"") + Param + + "\" not defined. Must be previously defined.", 10103); + else + { + if(ParamPointer == 13) + DoSimpleMsg(String("CNData Object \"") + Param + + "\" not defined. Must be previously defined.", 10103); + else + DoSimpleMsg(String("TSData Object \"") + Param + + "\" not defined. Must be previously defined.", 10103); + } + } + } + break; + default: + ; + break; + } + switch(ParamPointer) + { + case 1: case 4: case 5: case 6: case 7: case 11: case 12: case 13: case 14: case 15: case 16: + with0->DataChanged = true; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineGeometry::MakeLike(const String LineName) +{ + int result = 0; + TLineGeometryObj* OtherLineGeometry = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherLineGeometry = ((TLineGeometryObj*) Find(LineName)); + if(OtherLineGeometry != nullptr) + /*# with ActiveLineGeometryObj do */ + { + auto with0 = ActiveLineGeometryObj; + int stop = 0; + with0->Set_Nconds(OtherLineGeometry->get_Fnconds()); // allocates + with0->Fnphases = OtherLineGeometry->Fnphases; + with0->FSpacingType = OtherLineGeometry->FSpacingType; + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + with0->FPhaseChoice[i - 1] = OtherLineGeometry->FPhaseChoice[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FCondName)[i - 1] = (OtherLineGeometry->FCondName)[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FWireData)[i - 1] = (OtherLineGeometry->FWireData)[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FX)[i - 1] = (OtherLineGeometry->FX)[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FY)[i - 1] = (OtherLineGeometry->FY)[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FUnits)[i - 1] = (OtherLineGeometry->FUnits)[i - 1]; + } + with0->FReduce = OtherLineGeometry->FReduce; + with0->DataChanged = true; + with0->NormAmps = OtherLineGeometry->NormAmps; + with0->EmergAmps = OtherLineGeometry->EmergAmps; + with0->UpdateLineGeometryData(ActiveCircuit[ActiveActor]->Solution->get_FFrequency()); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherLineGeometry->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in LineGeometry MakeLike: \"") + LineName + + "\" Not Found.", 102); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineGeometry::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TLineGeometry.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TLineGeometry::Get_Code() +{ + String result; + result = ((TLineGeometryObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active LineGeometry + +void TLineGeometry::Set_Code(const String Value) +{ + TLineGeometryObj* LineGeometryObj = nullptr; + ActiveLineGeometryObj = nullptr; + LineGeometryObj = ((TLineGeometryObj*) ElementList.Get_First()); + while(LineGeometryObj != nullptr) + { + if(CompareText(LineGeometryObj->get_Name(), Value) == 0) + { + ActiveLineGeometryObj = LineGeometryObj; + return; + } + LineGeometryObj = ((TLineGeometryObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("LineGeometry: \"") + Value + "\" not Found.", 103); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TLineGeometry Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineGeometryObj::TLineGeometryObj(TDSSClass* ParClass, const String LineGeometryName) + : inherited(ParClass), + Fnconds(0), + Fnphases(0), + FLastUnit(0), + DataChanged(false), + FReduce(false), + FActiveCond(0), + NormAmps(0.0), + EmergAmps(0.0), + NumAmpRatings(0), + FLineType(0) +{ + Set_Name(LowerCase(LineGeometryName)); + + FPhaseChoice = nullptr; + DSSObjType = ParClass->DSSClassType; + DataChanged = true; + FCondName = nullptr; + FWireData.clear(); + FX.clear(); + FY.clear(); + FUnits.clear(); + FLineData = nullptr; + FSpacingType = ""; + +/* was causing unnecessary allocations (was leaving dangling memory) + Nconds := 3; // Allocates terminals + FNphases := 3; +*/ + FActiveCond = 1; + FLastUnit = UNITS_FT; + NormAmps = 0.0; + EmergAmps = 0.0; + FLineType = 1; // Default to OH Line + FReduce = false; + /*Initialize dynamic array for ratings*/ + NumAmpRatings = 1; + AmpRatings.resize(NumAmpRatings); + AmpRatings[0] = NormAmps; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineGeometryObj::~TLineGeometryObj() +{ + FLineData = nullptr; + FreeStringArray(FCondName, Fnconds); + FWireData.clear(); + FY.clear(); + FX.clear(); + FUnits.clear(); + // inherited::Destroy(); +} + + +void TLineGeometryObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = 2, i = 1; i <= stop; i++) + { + { System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "="); + System::WriteLn(f, GetPropertyValue(i)); } + } + for(stop = Fnconds, j = 1; j <= stop; j++) + { + set_ActiveCond(j); + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[3 - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(3)); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[4 - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(4)); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[5 - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(5)); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[6 - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(6)); } + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[7 - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(7)); } + } + for(stop = with0->NumProperties, i = 8; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, "="); System::WriteLn(f, GetPropertyValue(i)); } + } + } +} + +String TLineGeometryObj::GetPropertyValue(int Index) +{ + String result; + int j = 0; + int i = 0; +/*Return Property Value for Active index*/ + switch(Index) + { + case 3: + result = Format("%d", FActiveCond); + break; + case 4: + case 13: + case 14: + result = FCondName[FActiveCond - 1]; + break; + case 5: + result = Format("%-g", FX[FActiveCond - 1]); + break; + case 6: + result = Format("%-g", FY[FActiveCond - 1]); + break; + case 7: + result = LineUnitsStr((FUnits)[FActiveCond - 1]); + break; + case 8: + result = Format("%-g", NormAmps); + break; + case 9: + result = Format("%-g", EmergAmps); + break; + case 12: + case 15: + case 16: + { + int stop = 0; + result = "["; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + result = result + FCondName[i - 1] + " "; + } + result = result + "]"; + } + break; + case 17: + result = IntToStr(NumAmpRatings); + break; + case 18: + { + int stop = 0; + result = "["; + for(stop = NumAmpRatings, j = 1; j <= stop; j++) + { + result = result + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + result = result + "]"; + } + break; + case 19: + result = LineTypeList.Get(FLineType); + break; + // Inherited parameters + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +double TLineGeometryObj::Get_FX(int i) +{ + double result = 0.0; + if(i <= Fnconds) + result = FX[i - 1]; + else + result = 0.0; + return result; +} + +double TLineGeometryObj::Get_FY(int i) +{ + double result = 0.0; + if(i <= Fnconds) + result = FY[i - 1]; + else + result = 0.0; + return result; +} + +int TLineGeometryObj::Get_FUnits(int i) +{ + int result = 0; + if(i <= Fnconds) + result = FUnits[i - 1]; + else + result = 0; + return result; +} + +String TLineGeometryObj::Get_ConductorName(int i) +{ + String result; + if(i <= Fnconds) + result = FCondName[i - 1]; + else + result = ""; + return result; +} + +TConductorDataObj* TLineGeometryObj::Get_ConductorData(int i) +{ + TConductorDataObj* result = nullptr; + if(i <= Fnconds) + result = FWireData[i - 1]; + else + result = nullptr; + return result; +} + +int TLineGeometryObj::get_Nconds() +{ + int result = 0; + if(FReduce) + result = Fnphases; + else + result = Fnconds; + return result; +} + +ConductorChoice TLineGeometryObj::Get_PhaseChoice(int i) +{ + ConductorChoice result = Overhead; + result = FPhaseChoice[i - 1]; + return result; +} + +double TLineGeometryObj::Get_RhoEarth() +{ + double result = 0.0; + result = FLineData->get_FrhoEarth(); + return result; +} + +TcMatrix* TLineGeometryObj::Get_YCmatrix(double f, double Lngth, int Units) +{ + TcMatrix* result = nullptr; + result = nullptr; + if(DataChanged) + UpdateLineGeometryData(f); + if(!SolutionAbort) + result = FLineData->Get_YCmatrix(f,Lngth,Units); + return result; +} + +TcMatrix* TLineGeometryObj::Get_Zmatrix(double f, double Lngth, int Units) +{ + TcMatrix* result = nullptr; + result = nullptr; + if(DataChanged) + UpdateLineGeometryData(f); + if(!SolutionAbort) + result = FLineData->Get_Zmatrix(f,Lngth,Units); + return result; +} + +void TLineGeometryObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); + Set_PropertyValue(2,"3"); + Set_PropertyValue(3,"1"); + Set_PropertyValue(4,""); + Set_PropertyValue(5,"0"); + Set_PropertyValue(6,"32"); + Set_PropertyValue(7,"ft"); + Set_PropertyValue(8,"0"); + Set_PropertyValue(9,"0"); + Set_PropertyValue(17,"1"); // 1 season + Set_PropertyValue(18,"[400]"); // 1 rating + Set_PropertyValue(19,"OH"); // 1 rating + inherited::InitPropertyValues(NumPropsThisClass); +} +/* Override standard SaveWrite*/ +/*Linegeometry structure not conducive to standard means of saving*/ +void TLineGeometryObj::SaveWrite(System::TTextRec& f) +{ + String TempStr; + String strPhaseChoice; + int j = 0; + int iProp = 0; + int i = 0; + /*Write only properties that were explicitly set in the + final order they were actually set*/ + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + if (iProp > 0) + WriteLn(f); + while (iProp > 0) + { + /*# with ParentClass do */ + { + auto with0 = ParentClass; + switch ((with0->RevPropertyIdxMap)[iProp - 1]) + { + case 3: + case 11: + case 12: // if cond=, spacing, or wires were ever used write out arrays ... + { + int stop = 0; + for (stop = Fnconds, i = 1; i <= stop; i++) + { + switch (Get_PhaseChoice(i)) + { + case Overhead: + strPhaseChoice = "wire"; + break; + case ConcentricNeutral: + strPhaseChoice = "cncable"; + break; + case TapeShield: + strPhaseChoice = "tscable"; + break; + default: + strPhaseChoice = "wire"; + break; + } + WriteLn(f, Format(("~ Cond=%d " + strPhaseChoice + "= " + FCondName[i - 1] + " X=%.7g h=%.7g units=" + LineUnitsStr((FUnits)[i - 1])).c_str(), i, FX[i - 1], FY[i - 1])); + } + } + break; /*do Nothing*/ + case 4: case 5: case 6: case 7: + ; + break; // Ignore these properties; + case 8: + WriteLn(f, Format("~ normamps=%.4g", NormAmps)); + break; + case 9: + WriteLn(f, Format("~ emergamps=%.4g", EmergAmps)); + break; + case 10: + if (FReduce) + WriteLn(f, "~ Reduce=Yes"); + break; + case 13: case 14: + ; + break; /*do Nothing*/ // Ignore these properties; + case 18: + { + int stop = 0; + TempStr = "["; + for (stop = NumAmpRatings, j = 1; j <= stop; j++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + WriteLn(f, String("ratings=") + TempStr); + } + break; + case 19: + WriteLn(f, String("~ LineType=%.4g") + LineTypeList.Get(FLineType)); + break; + default: + String PropValue = "=" + CheckForBlanks(String(Get_PropertyValue(iProp))); + WriteLn(f, "~ " + with0->PropertyName[(with0->RevPropertyIdxMap)[iProp - 1] - 1] + PropValue); + break; + } + } + iProp = GetNextPropertySet(iProp); + } +} + + +void TLineGeometryObj::set_ActiveCond(int Value) +{ + if(Value > 0) + { + if(Value <= Fnconds) + { + FActiveCond = Value; + if(FUnits[FActiveCond - 1] == - 1) + FUnits[FActiveCond - 1] = FLastUnit; // makes this a sticky value so you don't have to repeat it + } + } +} + +void TLineGeometryObj::ChangeLineConstantsType(ConductorChoice newPhaseChoice) +{ + TLineConstants* newLineData = nullptr; + bool needNew = false; + newLineData = nullptr; + needNew = false; + if(newPhaseChoice != FPhaseChoice[get_FActiveCond() - 1]) + needNew = true; + if(!ASSIGNED(FLineData)) + needNew = true; + else + { + if(Fnconds != FLineData->get_FNumConds()) + needNew = true; + } + if(needNew) + switch(newPhaseChoice) + { + case Overhead: + newLineData = new TOHLineConstants(Fnconds); + break; + case ConcentricNeutral: + newLineData = new TCNLineConstants(Fnconds); + break; + case TapeShield: + newLineData = new TTSLineConstants(Fnconds); + break; + default: + ; + break; + } + if(ASSIGNED(newLineData)) + { + if (ASSIGNED(FLineData)) + { + newLineData->Set_NPhases(FLineData->get_FNumPhases()); + newLineData->Set_Frhoearth(FLineData->get_FrhoEarth()); + } + else + delete FLineData; + FLineData = newLineData; + } + FPhaseChoice[get_FActiveCond() - 1] = newPhaseChoice; +} + +//------------------------------------------------------------------------------------------------------- + +int TLineGeometryObj::get_Fnphases() +{ + return Fnphases; +} + +//------------------------------------------------------------------------------------------------------- + +int TLineGeometryObj::get_FActiveCond() +{ + return FActiveCond; +} + +//------------------------------------------------------------------------------------------------------- + +int TLineGeometryObj::get_Fnconds() +{ + return Fnconds; +} + +//------------------------------------------------------------------------------------------------------- + +void TLineGeometryObj::Set_Nconds(int Value) +{ + int i = 0; + int stop = 0; + if(ASSIGNED(FCondName)) + FreeStringArray(FCondName, Fnconds); // dispose of old allocation + Fnconds = Value; + if(ASSIGNED(FLineData)) + free( FLineData ); + + + /*Allocations*/ + FWireData.resize(Fnconds); + FX.resize(Fnconds); + FY.resize(Fnconds); + FUnits.resize(Fnconds); + FPhaseChoice = (pConductorChoiceArray) realloc(FPhaseChoice, sizeof(FPhaseChoice[0]) * Fnconds); + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FPhaseChoice[i - 1] = unknown; + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + set_ActiveCond(i); + ChangeLineConstantsType(Overhead); // works on activecond + } + FCondName = new string[Fnconds]; + +/*Initialize Allocations*/ + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FWireData[i - 1] = nullptr; + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FX[i - 1] = 0.0; + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FY[i - 1] = 0.0; + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FUnits[i - 1] = -1; + } // default to ft + FLastUnit = UNITS_FT; +} + +void TLineGeometryObj::Set_NPhases(int Value) +{ + Fnphases = Value; + FLineData->Set_NPhases(Value); +} + +void TLineGeometryObj::Set_RhoEarth(double Value) +{ + FLineData->Set_Frhoearth(Value); +} + +void TLineGeometryObj::UpdateLineGeometryData(double f) +{ + int i = 0; + String LineGeomErrMsg; + TCNDataObj* cnd = nullptr; + TTSDataObj* tsd = nullptr; + int stop = 0; + + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FLineData->Set_X(i, FUnits[i - 1], FX[i - 1]); + FLineData->Set_Y(i, FUnits[i - 1], FY[i - 1]); + FLineData->Set_radius(i, FWireData[i - 1]->get_FRadiusUnits(), FWireData[i - 1]->get_Fcapradius60()); + FLineData->Set_Capradius(i, FWireData[i - 1]->get_FRadiusUnits(), FWireData[i - 1]->get_Fcapradius60()); + FLineData->Set_GMR(i, FWireData[i - 1]->get_FGMRUnits(), FWireData[i - 1]->get_FGMR60()); + FLineData->Set_Rdc(i, FWireData[i - 1]->get_FResistanceUnits(), FWireData[i - 1]->get_FRDC()); + FLineData->Set_Rac(i, FWireData[i - 1]->get_FResistanceUnits(), FWireData[i - 1]->get_FR60()); + if( dynamic_cast< TCNDataObj* > ( FWireData[i - 1] ) != nullptr ) + { + /*# with (FLineData as TCNLineConstants) do */ + { + auto with0 = ((TCNLineConstants*) FLineData); + cnd = (TCNDataObj*) FWireData[i - 1]; + with0->Set_EpsR(i, cnd->get_FEpsR()); + with0->Set_InsLayer(i, cnd->get_FRadiusUnits(), cnd->get_FInsLayer()); + with0->Set_DiaIns(i, cnd->get_FRadiusUnits(), cnd->get_FDiaIns()); + with0->Set_DiaCable(i, cnd->get_FRadiusUnits(), cnd->get_FDiaCable()); + with0->Set_kStrand(i, cnd->get_FkStrand()); + with0->Set_DiaStrand(i, cnd->get_FRadiusUnits(), cnd->get_FDiaStrand()); + with0->Set_GmrStrand(i, cnd->get_FGMRUnits(), cnd->get_FGmrStrand()); + with0->Set_RStrand(i, cnd->get_FResistanceUnits(), cnd->get_FRStrand()); + + } + } + else + { + if( ( dynamic_cast ( FWireData[i - 1] ) ) != nullptr) + { + /*# with (FLineData as TTSLineConstants) do */ + { + auto with1 = ((TTSLineConstants*) FLineData); + tsd = ((TTSDataObj*) FWireData[i - 1]); + with1->Set_EpsR(i, tsd->get_FEpsR()); + with1->Set_InsLayer(i, tsd->get_FRadiusUnits(), tsd->get_FInsLayer()); + with1->Set_DiaIns(i, tsd->get_FRadiusUnits(), tsd->get_FDiaIns()); + with1->Set_DiaCable(i, tsd->get_FRadiusUnits(), tsd->get_FDiaCable()); + with1->Set_DiaShield(i, tsd->get_FRadiusUnits(), tsd->get_FDiaShield()); + with1->Set_TapeLayer(i, tsd->get_FRadiusUnits(), tsd->get_FTapeLayer()); + with1->Set_TapeLap(i, tsd->get_FTapeLap()); + } + } + } + } + FLineData->Set_NPhases(Fnphases); + DataChanged = false; + + /*Before we calc, check for bad conductor definitions*/ + if(FLineData->ConductorsInSameSpace(LineGeomErrMsg)) + { + SolutionAbort = true; + throw ELineGeometryProblem(String("Error in LineGeometry.") + get_Name() + ": " + LineGeomErrMsg); + } + else + { + FLineData->Calc(f); + if(FReduce) + FLineData->Reduce(); // reduce out neutrals + } +} + +void TLineGeometryObj::LoadSpacingAndWires(TLineSpacingObj* Spc, pConductorDataArray Wires) +{ + int i = 0; + ConductorChoice newPhaseChoice = Overhead; + int stop = 0; + Set_Nconds(Spc->get_Fnconds()); // allocates + Fnphases = Spc->get_Fnphases(); + FSpacingType = Spc->get_Name(); + if(Fnconds > Fnphases) + FReduce = true; + newPhaseChoice = Overhead; + for(i = 1; i < Fnconds; i++) + { + if(dynamic_cast (Wires[i - 1]) != nullptr ) + newPhaseChoice = ConcentricNeutral; + if(dynamic_cast(Wires[i - 1]) != nullptr ) + newPhaseChoice = TapeShield; + } + ChangeLineConstantsType(newPhaseChoice); + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FCondName[i - 1] = Wires[i - 1]->get_Name(); + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FWireData[i - 1] = Wires[i - 1]; + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FX[i - 1] = Spc->Get_FX(i); + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FY[i - 1] = Spc->Get_FY(i); + } + for(stop = Fnconds, i = 1; i <= stop; i++) + { + FUnits[i - 1] = Spc->get_FUnits(); + } + DataChanged = true; + NormAmps = (Wires)[1 - 1]->NormAmps; + EmergAmps = (Wires)[1 - 1]->EmergAmps; + UpdateLineGeometryData(ActiveCircuit[ActiveActor]->Solution->get_FFrequency()); +} + + + + +} // namespace LineGeometry + diff --git a/OpenDSSC/General/LineGeometry.h b/OpenDSSC/General/LineGeometry.h new file mode 100644 index 0000000..b45aca5 --- /dev/null +++ b/OpenDSSC/General/LineGeometry.h @@ -0,0 +1,144 @@ +#ifndef LineGeometryH +#define LineGeometryH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "LineConstants.h" +#include "ConductorData.h" +#include "CNData.h" +#include "TSData.h" +#include "LineSpacing.h" +#include "Ucmatrix.h" +#include "d2c_structures.h" + +namespace LineGeometry +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*The LineGeometry object is a general DSS object used by all circuits + as a reference for obtaining line impedances. + + The values are set by the normal New and Edit procedures for any DSS object. + + The values are retrieved by setting the Code Property in the LineGeometry Class. + This sets the active LineGeometry object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. + + */ + +class ELineGeometryProblem : public std::runtime_error +{ +public: + typedef std::runtime_error inherited; + ELineGeometryProblem(const String &Msg); +}; + +class TLineGeometry : public DSSClass::TDSSClass +{ + friend class TLineGeometryObj; +public: + typedef DSSClass::TDSSClass inherited; +private: + String Get_Code(); // Returns active line code String + void Set_Code(const String Value); // sets the active LineGeometry +protected: + void DefineProperties(); + virtual int MakeLike(const String LineName); +public: + TLineGeometry(); + virtual ~TLineGeometry(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TLineGeometryObj : public DSSObject::TDSSObject +{ + friend class TLineGeometry; +public: + typedef DSSObject::TDSSObject inherited; +//private: + ConductorData::pConductorChoiceArray FPhaseChoice; + int Fnconds; + int Fnphases; + Arraydef::pStringArray FCondName; + ConductorData::pConductorDataArray FWireData; + std::vector FX; + std::vector FY; + std::vector FUnits; + int FLastUnit; + bool DataChanged; + bool FReduce; + int FActiveCond; + String FSpacingType; + LineConstants::TLineConstants* FLineData; + void ChangeLineConstantsType(ConductorData::ConductorChoice newPhaseChoice); + void Set_Nconds(int Value); + void Set_NPhases(int Value); + void set_ActiveCond(int Value); + Ucmatrix::TcMatrix* Get_YCmatrix(double f, double Lngth, int Units); + Ucmatrix::TcMatrix* Get_Zmatrix(double f, double Lngth, int Units); + double Get_RhoEarth(); + void Set_RhoEarth(double Value); + int get_Nconds(); + void UpdateLineGeometryData(double f); // call this before using the line data + + // CIM Accessors + double Get_FX(int i); + double Get_FY(int i); + int Get_FUnits(int i); + String Get_ConductorName(int i); + ConductorData::TConductorDataObj* Get_ConductorData(int i); + ConductorData::ConductorChoice Get_PhaseChoice(int i); +public: + double NormAmps; + double EmergAmps; + int NumAmpRatings; + Arraydef::TRatingsArray AmpRatings; + int FLineType; // Pointer to code for type of line + TLineGeometryObj(DSSClass::TDSSClass* ParClass, const String LineGeometryName); + virtual ~TLineGeometryObj(); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + //------------------------functions for passing variables as properties------------------------------------ + int get_Fnphases(); + int get_FActiveCond(); + int get_Fnconds(); + + // called from a Line object that has its own Spacing and Wires input + // automatically sets reduce=y if the spacing has more wires than phases + void LoadSpacingAndWires(LineSpacing::TLineSpacingObj* Spc, ConductorData::pConductorDataArray Wires); + // CIM XML accessors + TLineGeometryObj(DSSClass::TDSSClass* ParClass); + TLineGeometryObj(String ClassName); + TLineGeometryObj(); +}; +extern TLineGeometryObj* ActiveLineGeometryObj; + +} // namespace LineGeometry + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LineGeometry; +#endif + +#endif // LineGeometryH + + + + + diff --git a/OpenDSSC/General/LineSpacing.cpp b/OpenDSSC/General/LineSpacing.cpp new file mode 100644 index 0000000..e400176 --- /dev/null +++ b/OpenDSSC/General/LineSpacing.cpp @@ -0,0 +1,434 @@ + +#pragma hdrstop + +#include "LineSpacing.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucomplex.h" +#include "Utilities.h" +#include "LineUnits.h" + +using namespace std; + +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineUnits; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; +using namespace Utilities; + +namespace LineSpacing +{ + +TLineSpacingObj::TLineSpacingObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TLineSpacingObj::TLineSpacingObj(String ClassName) : inherited(ClassName) {} +TLineSpacingObj::TLineSpacingObj() {} + + +TLineSpacingObj* ActiveLineSpacingObj = nullptr; +const int NumPropsThisClass = 5; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TLineSpacing::TLineSpacing() +{ + ; + Class_Name = "LineSpacing"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineSpacing::~TLineSpacing() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineSpacing::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + (PropertyName)[1 - 1] = "nconds"; + (PropertyName)[2 - 1] = "nphases"; + (PropertyName)[3 - 1] = "x"; + (PropertyName)[4 - 1] = "h"; + (PropertyName)[5 - 1] = "units"; + (PropertyHelp)[1 - 1] = "Number of wires in this geometry. Default is 3. Triggers memory allocations. Define first!"; + (PropertyHelp)[2 - 1] = "Number of retained phase conductors. If less than the number of wires, list the retained phase coordinates first."; + (PropertyHelp)[3 - 1] = "Array of wire X coordinates."; + (PropertyHelp)[4 - 1] = "Array of wire Heights."; + (PropertyHelp)[5 - 1] = "Units for x and h: {mi|kft|km|m|Ft|in|cm } Initial default is \"ft\", but defaults to last unit defined"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineSpacing::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TLineSpacingObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +void TLineSpacing::InterpretArray(const String s, SpcParmChoice Which) +{ + String Str; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); + /*# with ActiveLineSpacingObj do */ + { + auto with0 = ActiveLineSpacingObj; + int stop = 0; + for(stop = with0->get_Fnconds(), i = 1; i <= stop; i++) + { + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + Str = AuxParser[ActiveActor]->MakeString_(); + if(Str.length() > 0) + switch(Which) + { + case X: + (with0->FX)[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + break; + case h: + (with0->FY)[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + break; + default: + ; + break; + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineSpacing::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveLineSpacingObj = ((TLineSpacingObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveLineSpacingObj; + /*# with ActiveLineSpacingObj do */ + { + auto with0 = ActiveLineSpacingObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 10101); + break; + case 1: + with0->set_Nwires(Parser[ActorID]->MakeInteger_()); + break; // Use property value to force reallocations + case 2: + with0->Fnphases = Parser[ActorID]->MakeInteger_(); + break; + case 3: + InterpretArray(Param, X); + break; + case 4: + InterpretArray(Param, h); + break; + case 5: + with0->FUnits = GetUnitsCode(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveLineSpacingObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 2: case 3: case 4: case 5: + with0->DataChanged = true; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineSpacing::MakeLike(const String LineName) +{ + int result = 0; + TLineSpacingObj* OtherLineSpacing = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherLineSpacing = ((TLineSpacingObj*) Find(LineName)); + if(OtherLineSpacing != nullptr) + /*# with ActiveLineSpacingObj do */ + { + auto with0 = ActiveLineSpacingObj; + int stop = 0; + with0->set_Nwires(OtherLineSpacing->get_Fnconds()); // allocates + with0->Fnphases = OtherLineSpacing->get_Fnphases(); + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FX)[i - 1] = (OtherLineSpacing->FX)[i - 1]; + } + for(stop = with0->Fnconds, i = 1; i <= stop; i++) + { + (with0->FY)[i - 1] = (OtherLineSpacing->FY)[i - 1]; + } + with0->FUnits = OtherLineSpacing->FUnits; + with0->DataChanged = true; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherLineSpacing->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in LineSpacing MakeLike: \"") + LineName + + "\" Not Found.", 102); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLineSpacing::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TLineSpacing.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TLineSpacing::Get_Code() +{ + String result; + result = ((TLineSpacingObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active LineSpacing + +void TLineSpacing::Set_Code(const String Value) +{ + TLineSpacingObj* LineSpacingObj = nullptr; + ActiveLineSpacingObj = nullptr; + LineSpacingObj = ((TLineSpacingObj*) ElementList.Get_First()); + while(LineSpacingObj != nullptr) + { + if(CompareText(LineSpacingObj->get_Name(), Value) == 0) + { + ActiveLineSpacingObj = LineSpacingObj; + return; + } + LineSpacingObj = ((TLineSpacingObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("LineSpacing: \"") + Value + "\" not Found.", 103); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TLineSpacing Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineSpacingObj::TLineSpacingObj(TDSSClass* ParClass, const String LineSpacingName) + : inherited(ParClass), + Fnconds(0), + Fnphases(0) +{ + Set_Name(LowerCase(LineSpacingName)); + DSSObjType = ParClass->DSSClassType; + DataChanged = true; + FX = nullptr; + FY = nullptr; + FUnits = UNITS_FT; + set_Nwires(3); // Allocates terminals + Fnphases = 3; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineSpacingObj::~TLineSpacingObj() +{ + free(FY); + free(FX); + // inherited::Destroy(); +} + + +void TLineSpacingObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = 5, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(i)); } + } + } +} + +String ArrayString(pDoubleArray PF, int n) +{ + String result; + int i = 0; + String R; + int stop = 0; + R = "["; + if(n > 0) + R = R + Format("%-g", PF[1 - 1]); + for(stop = n, i = 2; i <= stop; i++) + { + R = R + Format(",%-g", PF[i - 1]); + } + result = R + "]"; + return result; +} + +/*Return Property Value for Active index*/ + +String TLineSpacingObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 3: + result = ArrayString(FX, Fnconds); + break; + case 4: + result = ArrayString(FY, Fnconds); + break; + case 5: + result = LineUnitsStr(FUnits); + break; + // Inherited parameters + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +double TLineSpacingObj::Get_FX(int i) +{ + double result = 0.0; + if(i <= Fnconds) + result = FX[i - 1]; + else + result = 0.0; + return result; +} + +double TLineSpacingObj::Get_FY(int i) +{ + double result = 0.0; + if(i <= Fnconds) + result = FY[i - 1]; + else + result = 0.0; + return result; +} + +//------------------------------------------------------------------------------------ + +int TLineSpacingObj::get_Fnconds() +{ + return Fnconds; +} + +//------------------------------------------------------------------------------------ + +int TLineSpacingObj::get_Fnphases() +{ + return Fnphases; +} + +//------------------------------------------------------------------------------------ + +int TLineSpacingObj::get_FUnits() +{ + return FUnits; +} + +//------------------------------------------------------------------------------------ + +void TLineSpacingObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); + Set_PropertyValue(2,"3"); + Set_PropertyValue(3,"0"); + Set_PropertyValue(4,"32"); + Set_PropertyValue(5,"ft"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TLineSpacingObj::set_Nwires(int Value) +{ + int ncondsPrev = Fnconds; + Fnconds = Value; + FX = (pDoubleArray) realloc(FX, sizeof(double) * Fnconds); + FY = (pDoubleArray) realloc(FY, sizeof(double) * Fnconds); + FUnits = UNITS_FT; + for (int i = ncondsPrev; i < Fnconds; ++i) + { + FX[i] = 0.0; + FY[i] = 0.0; + } +} + + + + +} // namespace LineSpacing + + + + + diff --git a/OpenDSSC/General/LineSpacing.h b/OpenDSSC/General/LineSpacing.h new file mode 100644 index 0000000..6f01cd3 --- /dev/null +++ b/OpenDSSC/General/LineSpacing.h @@ -0,0 +1,93 @@ +#ifndef LineSpacingH +#define LineSpacingH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "d2c_structures.h" + +namespace LineSpacing +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +enum SpcParmChoice {X, + h }; + +class TLineSpacing : public TDSSClass +{ + friend class TLineSpacingObj; +public: + typedef TDSSClass inherited; +//private: + String Get_Code(); // Returns active line code String + void Set_Code(const String Value); // sets the active LineSpacing + void InterpretArray(const String s, SpcParmChoice Which); +protected: + void DefineProperties(); + virtual int MakeLike(const String LineName); +public: + TLineSpacing(); + virtual ~TLineSpacing(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TLineSpacingObj : public DSSObject::TDSSObject +{ + friend class TLineSpacing; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int Fnconds; + int Fnphases; + Arraydef::pDoubleArray FX; + Arraydef::pDoubleArray FY; + int FUnits; + bool DataChanged; + void set_Nwires(int Value); + + // CIM Accessors + double Get_FX(int i); + double Get_FY(int i); +public: + TLineSpacingObj(DSSClass::TDSSClass* ParClass, const String LineSpacingName); + virtual ~TLineSpacingObj(); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + int get_Fnconds(); + int get_Fnphases(); + int get_FUnits(); + + // CIM XML accessors + TLineSpacingObj(DSSClass::TDSSClass* ParClass); + TLineSpacingObj(String ClassName); + TLineSpacingObj(); +}; +extern TLineSpacingObj* ActiveLineSpacingObj; + + +} // namespace LineSpacing + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LineSpacing; +#endif + +#endif // LineSpacingH + + + + + diff --git a/OpenDSSC/General/LoadShape.cpp b/OpenDSSC/General/LoadShape.cpp new file mode 100644 index 0000000..84a07c8 --- /dev/null +++ b/OpenDSSC/General/LoadShape.cpp @@ -0,0 +1,1890 @@ + +#pragma hdrstop + +#ifndef _WIN32 +//#include +//#include +//#include +#include +#endif + +#include "LoadShape.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "mathutil.h" +#include "Utilities.h" +//#include "../Common/TOPExport.h" +#include +#include "PointerList.h" + + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace PointerList; +using namespace System; +//using namespace TOPExport; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace LoadShape +{ + +TLoadShapeObj::TLoadShapeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TLoadShapeObj::TLoadShapeObj(string ClassName) : inherited(ClassName) {} +TLoadShapeObj::TLoadShapeObj() {} + + +TLoadShapeObj* ActiveLoadShapeObj = nullptr; +const int NumPropsThisClass = 22; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TLoadShape::TLoadShape() +{ + ; + Class_Name = "LoadShape"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLoadShape::~TLoadShape() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoadShape::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "npts"; // Number of points to expect + PropertyName[2 - 1] = "interval"; // default = 1.0; + PropertyName[3 - 1] = "mult"; // vector of power multiplier values + PropertyName[4 - 1] = "hour"; // vextor of hour values + PropertyName[5 - 1] = "mean"; // set the mean (otherwise computed) + PropertyName[6 - 1] = "stddev"; // set the std dev (otherwise computed) + PropertyName[7 - 1] = "csvfile"; // Switch input to a csvfile + PropertyName[8 - 1] = "sngfile"; // switch input to a binary file of singles + PropertyName[9 - 1] = "dblfile"; // switch input to a binary file of singles + PropertyName[10 - 1] = "action"; // actions Normalize + PropertyName[11 - 1] = "qmult"; // Q multiplier + PropertyName[12 - 1] = "UseActual"; // Flag to signify to use actual value + PropertyName[13 - 1] = "Pmax"; // MaxP value + PropertyName[14 - 1] = "Qmax"; // MaxQ + PropertyName[15 - 1] = "sinterval"; // Interval in seconds + PropertyName[16 - 1] = "minterval"; // Interval in minutes + PropertyName[17 - 1] = "Pbase"; // for normalization, use peak if 0 + PropertyName[18 - 1] = "Qbase"; // for normalization, use peak if 0 + PropertyName[19 - 1] = "Pmult"; // synonym for Mult + PropertyName[20 - 1] = "PQCSVFile"; // Redirect to a file with p, q pairs + PropertyName[21 - 1] = "MemoryMapping"; // Enable/disable using Memory mapping for this shape + PropertyName[22 - 1] = "mode"; + // define Property help values + PropertyHelp[1 - 1] = "Max number of points to expect in load shape vectors. This gets reset to the number of multiplier values found (in files only) if less than specified."; // Number of points to expect + PropertyHelp[2 - 1] = String("Time interval for fixed interval data, hrs. Default = 1. " "If Interval = 0 then time data (in hours) may be at either regular or irregular intervals and time value must be specified using either the Hour property or input files. " "Then values are interpolated when Interval=0, but not for fixed interval data. ") + CRLF + + CRLF + + "See also \"sinterval\" and \"minterval\"."; // default = 1.0; + PropertyHelp[3 - 1] = String("Array of multiplier values for active power (P) or other key value (such as pu V for Vsource). ") + CRLF + + CRLF + + "You can also use the syntax: " + + CRLF + + CRLF + + "mult = (file=filename) !for text file one value per line" + + CRLF + + "mult = (dblfile=filename) !for packed file of doubles" + + CRLF + + "mult = (sngfile=filename) !for packed file of singles " + + CRLF + + "mult = (file=MyCSVFile.CSV, col=3, header=yes) !for multicolumn CSV files " + + CRLF + + CRLF + + "Note: this property will reset Npts if the number of values in the files are fewer." + + CRLF + + CRLF + + "Same as Pmult"; // vector of power multiplier values + PropertyHelp[4 - 1] = String("Array of hour values. Only necessary to define for variable interval data (Interval=0)." " If you set Interval>0 to denote fixed interval data, DO NOT USE THIS PROPERTY. " "You can also use the syntax: ") + CRLF + + "hour = (file=filename) !for text file one value per line" + + CRLF + + "hour = (dblfile=filename) !for packed file of doubles" + + CRLF + + "hour = (sngfile=filename) !for packed file of singles "; // vextor of hour values + PropertyHelp[5 - 1] = "Mean of the active power multipliers. This is computed on demand the first time a " + "value is needed. However, you may set it to another value independently. " + "Used for Monte Carlo load simulations."; // set the mean (otherwise computed) + PropertyHelp[6 - 1] = String("Standard deviation of active power multipliers. This is computed on demand the first time a " "value is needed. However, you may set it to another value independently." "Is overwritten if you subsequently read in a curve") + CRLF + + CRLF + + "Used for Monte Carlo load simulations."; // set the std dev (otherwise computed) + PropertyHelp[7 - 1] = "Switch input of active power load curve data to a CSV text file " + "containing (hour, mult) points, or simply (mult) values for fixed time interval data, one per line. " + "NOTE: This action may reset the number of points to a lower value."; // Switch input to a csvfile + PropertyHelp[8 - 1] = "Switch input of active power load curve data to a binary file of singles " + "containing (hour, mult) points, or simply (mult) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + PropertyHelp[9 - 1] = "Switch input of active power load curve data to a binary file of doubles " + "containing (hour, mult) points, or simply (mult) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + PropertyHelp[10 - 1] = String("{NORMALIZE | DblSave | SngSave} After defining load curve data, setting action=normalize " "will modify the multipliers so that the peak is 1.0. " "The mean and std deviation are recomputed.") + CRLF + + CRLF + + "Setting action=DblSave or SngSave will cause the present mult and qmult values to be written to " + + "either a packed file of double or single. The filename is the loadshape name. The mult array will have a " + + "\"_P\" appended on the file name and the qmult array, if it exists, will have \"_Q\" appended."; // Action + // vector of qmultiplier values + PropertyHelp[11 - 1] = String("Array of multiplier values for reactive power (Q). You can also use the syntax: ") + CRLF + + "qmult = (file=filename) !for text file one value per line" + + CRLF + + "qmult = (dblfile=filename) !for packed file of doubles" + + CRLF + + "qmult = (sngfile=filename) !for packed file of singles " + + CRLF + + "qmult = (file=MyCSVFile.CSV, col=4, header=yes) !for multicolumn CSV files "; + PropertyHelp[12 - 1] = "{Yes | No* | True | False*} If true, signifies to Load, Generator, Vsource, or other objects to " + "use the return value as the actual kW, kvar, kV, or other value rather than a multiplier. " + "Nominally for AMI Load data but may be used for other functions."; + PropertyHelp[13 - 1] = "kW value at the time of max power. Is automatically set upon reading in a loadshape. " + "Use this property to override the value automatically computed or to retrieve the value computed."; + PropertyHelp[14 - 1] = "kvar value at the time of max kW power. Is automatically set upon reading in a loadshape. " + "Use this property to override the value automatically computed or to retrieve the value computed."; + PropertyHelp[15 - 1] = "Specify fixed interval in SECONDS. Alternate way to specify Interval property."; + PropertyHelp[16 - 1] = "Specify fixed interval in MINUTES. Alternate way to specify Interval property."; + PropertyHelp[17 - 1] = "Base P value for normalization. Default is zero, meaning the peak will be used."; + PropertyHelp[18 - 1] = "Base Q value for normalization. Default is zero, meaning the peak will be used."; + PropertyHelp[19 - 1] = "Synonym for \"mult\"."; + PropertyHelp[20 - 1] = String("Switch input to a CSV text file containing (active, reactive) power (P, Q) multiplier pairs, one per row. ") + CRLF + + "If the interval=0, there should be 3 items on each line: (hour, Pmult, Qmult)"; + PropertyHelp[21 - 1] = String("{Yes | No* | True | False*} Enables the memory mapping functionality for dealing with large amounts of load shapes. ") + CRLF + + "By defaul is False. Use it to accelerate the model loading when the containing a large number of load shapes."; + PropertyHelp[22 - 1] = String("{carryover | default} carryover will initialize generator dispatch from latest Pgen/Qgen in memory. default will use kWbase ") + CRLF + + "and kvarbase to initialize generator dispatch."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoadShape::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TLoadShapeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +/******************************************************************************** +* Loads the mapped file features into local variables for further use * +*********************************************************************************/ +void TLoadShapeObj::LoadFileFeatures(int ShapeType) +{ + int LocalCol = 0; + int myType = 0; + String Parmname; + String Param; + AuxParser[ActiveActor]->SetCmdString(myFileCmd); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + LocalCol = 1; + if(CompareText(Parmname, "file") == 0) + /*Default values*/ + { + myType = 0; + // Default options + + // Look for other options (may be in either order) + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + while(Param.length() > 0) + { + if(CompareTextShortest(Parmname, "column") == 0) + LocalCol = AuxParser[ActiveActor]->MakeInteger_(); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } + else + { + if(CompareText(Parmname, "dblfile") == 0) + myType = 1; + else + { + if(CompareText(Parmname, "sngfile") == 0) + myType = 2; + } + } + if(ShapeType == 0) // P + { + myFileType = myType; + myColumn = LocalCol; + } + else + { + myFileTypeQ = myType; + myColumnQ = LocalCol; + } +} + +/******************************************************************************** +* Uploads the active MMF view into memory for further use * +*********************************************************************************/ +// Destination +// 0 : P +// 1 : Q + +void TLoadShapeObj::LoadMMFView(const String Parmname, int Destination) +{ + int FirstPos = 0; + unsigned char myLastCh = 0; + // processes the view depending on the file type + FirstPos = 1; + if(Destination == 0) + { + if(CompareText(Parmname, "file") == 0) // starndard csv file + { + myLastCh = myView[FirstPos]; + while(myLastCh != 0x0A) + { + ++FirstPos; + myLastCh = myView[FirstPos]; + } + myLineLen = FirstPos + 1; + // DBL file + } + else + { + if((Parmname.length() > 0) && (CompareTextShortest(Parmname, "dblfile") == 0)) + // SGL file + myLineLen = sizeof(double); + else + { + if((Parmname.length() > 0) && (CompareTextShortest(Parmname, "sngfile") == 0)) + myLineLen = sizeof(float); + } + } + } + else + { + if(CompareText(Parmname, "file") == 0) // starndard csv file + { + myLastCh = myViewQ[FirstPos]; + while(myLastCh != 0x0A) + { + ++FirstPos; + myLastCh = myViewQ[FirstPos]; + } + myLineLenQ = FirstPos + 1; + // DBL file + } + else + { + if((Parmname.length() > 0) && (CompareTextShortest(Parmname, "dblfile") == 0)) + // SGL file + myLineLenQ = sizeof(double); + else + { + if((Parmname.length() > 0) && (CompareTextShortest(Parmname, "sngfile") == 0)) + myLineLenQ = sizeof(float); + } + } + } +} + +/******************************************************************************** +* Creates the Memory mapping for the file specified, Destination is used to * +* Indicate the destinaton (0 = P, 1 = Q) * +*********************************************************************************/ + +int TLoadShape::CreateMMF(const String s, int Destination) +{ + int result = 0; + String Parmname; + String Param; + unsigned char myLastCh = 0; + int i = 0; + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + try + { + AuxParser[ActiveActor]->SetCmdString(s); + Parmname = AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + if(FileExists(Param)) + { + if(Destination == 0) + // Creating mapping for P + // Opens the file for this instance + { +#ifdef _WIN32 + with0->myFile = CreateFile(Param.c_str(), GENERIC_READ, (DWORD) FILE_SHARE_READ, nullptr, (DWORD) OPEN_EXISTING, (DWORD) FILE_ATTRIBUTE_NORMAL, 0); + // Creates the memory map for the file + with0->myMMF = CreateFileMapping(with0->myFile, nullptr, (DWORD) PAGE_READONLY, 0, 0, nullptr); + with0->myFileSize = GetFileSize(with0->myFile, nullptr); + with0->MyViewLen = (int) with0->myFileSize; + with0->myView = ((PByte) MapViewOfFile(with0->myMMF, (DWORD) FILE_MAP_READ, 0, 0, (SIZE_T) with0->MyViewLen)); +#else + with0->myFile = open(Param.c_str(), O_RDONLY, 0); + with0->myFileSize = lseek(with0->myFile, 0, SEEK_END); + (void) lseek(with0->myFile, 0, SEEK_SET); + with0->MyViewLen = (int) with0->myFileSize; + with0->myView = (PByte) mmap(nullptr, with0->myFileSize, PROT_READ, MAP_SHARED, with0->myFile, 0); +#endif + with0->myFileCmd = s; + } + else + + // Creating mapping for Q + // Opens the file for this instance + { +#ifdef _WIN32 + with0->myQFile = CreateFile(Param.c_str(), GENERIC_READ, (DWORD) FILE_SHARE_READ, nullptr, (DWORD) OPEN_EXISTING, (DWORD) FILE_ATTRIBUTE_NORMAL, 0); + // Creates the memory map for the file + with0->myQMMF = CreateFileMapping(with0->myQFile, nullptr, (DWORD) PAGE_READONLY, 0, 0, nullptr); + with0->myFileSizeQ = GetFileSize(with0->myFile, nullptr); + with0->MyViewLenQ = (int) with0->myFileSizeQ; + with0->myViewQ = ((PByte) MapViewOfFile(with0->myQMMF, (DWORD) FILE_MAP_READ, 0, 0, (SIZE_T) with0->MyViewLenQ)); +#else + with0->myQFile = open(Param.c_str(), O_RDONLY, 0); + with0->myFileSizeQ = lseek(with0->myQFile, 0, SEEK_END); + (void) lseek(with0->myQFile, 0, SEEK_SET); + with0->MyViewLenQ = (int) with0->myFileSizeQ; + with0->myViewQ = (PByte) mmap(nullptr, with0->myFileSizeQ, PROT_READ, MAP_SHARED, with0->myQFile, 0); +#endif + with0->myFileCmdQ = s; + } + with0->LoadMMFView(Parmname, Destination); + result = 0; + } + else + { + DoSimpleMsg("The file "+ Param + " does not exist. Process cancelled.", 800002); + result = -1; + } + } + catch(...) + { + DoSimpleMsg("There was a proble mapping file " + Param + ". Process cancelled.", 800001); + result = -1; + } + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoadShape::Edit(int ActorID) +{ + int result = 0; + int MMFError = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveLoadShapeObj = ((TLoadShapeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveLoadShapeObj; + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 610); + break; + case 1: + with0->Set_NumPoints( Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->Interval = Parser[ActorID]->MakeDouble_(); + break; + case 3: + { + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + MMFError = CreateMMF(Param, 0); // Creates MMF for P + if(MMFError == 0) + { + with0->LoadFileFeatures(0); + with0->myDataSize = with0->get_FNumPoints(); + with0->PMultipliers.resize(2); + } + } + else + // Otherwise, follow the traditional technique for loading up load shapes + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + // Allow possible Resetting (to a lower value) of num points when specifying multipliers not Hours + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->PMultipliers[0]))); // Parser.ParseAsVector(Npts, Multipliers); + } + } + break; + case 4: + { + with0->Hours.resize(with0->get_FNumPoints()); + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->Hours[0]))); // Parser.ParseAsVector(Npts, Hours); + with0->Interval = 0.0; + } + break; + case 5: + with0->Set_Mean(Parser[ActorID]->MakeDouble_()); + break; + case 6: + with0->Set_StdDev(Parser[ActorID]->MakeDouble_()); + break; + case 7: + DoCSVFile(Param); + break; + case 8: + DoSngFile(Param); + break; + case 9: + DoDblFile(Param); + break; + case 10: + switch(LowerCase(Param)[0]) + { + case L'n': + with0->Normalize(); + break; + case L'd': + with0->SaveToDblFile(); + break; + case L's': + with0->SaveToSngFile(); + break; + default: + ; + break; + } + break; + case 11: + { + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + MMFError = CreateMMF(Param, 1); // Creates MMF for Q + if(MMFError == 0) + { + with0->LoadFileFeatures(1); + if(!with0->PMultipliers.empty()) + with0->myDataSizeQ = with0->myDataSize; + else + with0->myDataSizeQ = with0->get_FNumPoints(); + with0->QMultipliers.resize(2); + } + } + else + // Otherwise, follow the traditional technique for loading up load shapes + { + with0->QMultipliers.resize(with0->get_FNumPoints()); + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->QMultipliers[0]))); // Parser.ParseAsVector(Npts, Multipliers); + } + } + break; + case 12: + with0->UseActual = InterpretYesNo(Param); + break; + case 13: + with0->MaxP = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->MaxQ = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->Interval = Parser[ActorID]->MakeDouble_() / 3600.0; + break; // Convert seconds to hr + case 16: + with0->Interval = Parser[ActorID]->MakeDouble_() / 60.0; + break; // Convert minutes to hr + case 17: + with0->BaseP = Parser[ActorID]->MakeDouble_(); + break; + case 18: + with0->BaseQ = Parser[ActorID]->MakeDouble_(); + break; // same as mult + case 19: + { + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + MMFError = CreateMMF(Param, 0); // Creates MMF for P + if(MMFError == 0) + { + with0->LoadFileFeatures(0); + with0->myDataSize = with0->get_FNumPoints(); + with0->PMultipliers.resize(2); + } + } + else + // Otherwise, follow the traditional technique for loading up load shapes + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + // Allow possible Resetting (to a lower value) of num points when specifying multipliers not Hours + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->PMultipliers[0]))); // Parser.ParseAsVector(Npts, Multipliers); + } + } + break; + case 20: + Do2ColCSVFile(Param); + break; + case 21: + with0->UseMMF = InterpretYesNo(Param); + break; + case 22: + with0->mode = Parser[ActorID]->MakeString_(); + break; + + + // Inherited parameters + default: + ClassEdit(ActiveLoadShapeObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 3: case 7: case 8: case 9: case 11: + { + with0->FStdDevCalculated = false; // now calculated on demand + with0->ArrayPropertyIndex = ParamPointer; + with0->Set_NumPoints(with0->FNumPoints); // Keep Properties in order for save command + } + break; + case 14: + with0->MaxQSpecified = true; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*WHILE*/ + if(!with0->PMultipliers.empty()) + with0->SetMaxPandQ(); + } /*WITH*/ + return result; +} + +void* TLoadShape::Find(const String ObjName) +{ + void* result = nullptr; + if((ObjName.length() == 0) || (CompareText(ObjName, "none") == 0)) + result = nullptr; + else + result = inherited::Find(ObjName); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoadShape::MakeLike(const String ShapeName) +{ + int result = 0; + TLoadShapeObj* OtherLoadShape = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherLoadShape = ((TLoadShapeObj*) Find(ShapeName)); + if(OtherLoadShape != nullptr) + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + int stop = 0; + with0->Set_NumPoints(OtherLoadShape->get_FNumPoints()); + with0->Interval = OtherLoadShape->Interval; + with0->PMultipliers.resize(with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->PMultipliers)[i - 1] = (OtherLoadShape->PMultipliers)[i - 1]; + } + if(!OtherLoadShape->QMultipliers.empty()) + { + int stop = 0; + with0->QMultipliers.resize(with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->QMultipliers)[i - 1] = (OtherLoadShape->QMultipliers)[i - 1]; + } + } + if(with0->Interval > 0.0) + with0->Hours.clear(); + else + { + int stop = 0; + with0->Hours.resize(with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->Hours)[i - 1] = (OtherLoadShape->Hours)[i - 1]; + } + } + with0->SetMaxPandQ(); + with0->UseActual = OtherLoadShape->UseActual; + with0->UseMMF = OtherLoadShape->UseMMF; + with0->BaseP = OtherLoadShape->BaseP; + with0->BaseQ = OtherLoadShape->BaseQ; + + + /* MaxP := OtherLoadShape.MaxP; + MaxQ := OtherLoadShape.MaxQ; + Mean := OtherLoadShape.Mean; + StdDev := OtherLoadShape.StdDev; + */ + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherLoadShape->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in LoadShape MakeLike: \"") + ShapeName + + "\" Not Found.", 611); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoadShape::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TLoadShape.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + +String TLoadShape::Get_Code() +{ + String result; + TLoadShapeObj* LoadShapeObj = nullptr; + LoadShapeObj = ((TLoadShapeObj*) ElementList.Get_Active()); + result = LoadShapeObj->get_Name(); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active LoadShape + +void TLoadShape::Set_Code(const String Value) +{ + TLoadShapeObj* LoadShapeObj = nullptr; + ActiveLoadShapeObj = nullptr; + LoadShapeObj = ((TLoadShapeObj*) ElementList.Get_First()); + while(LoadShapeObj != nullptr) + { + if(CompareText(LoadShapeObj->get_Name(), Value) == 0) + { + ActiveLoadShapeObj = LoadShapeObj; + return; + } + LoadShapeObj = ((TLoadShapeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("LoadShape: \"") + Value + "\" not Found.", 612); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/* + Process 2-column CSV file (3-col if time expected) +*/ + +void TLoadShape::Do2ColCSVFile(const String FileName) +{ + System::TTextRec f = {}; + int MMFError = 0; + int i = 0; + String dummy, s; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 613); + System::CloseFile(f); System::InOutRes = 0; + return; + } + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + System::CloseFile(f); + with0->myDataSize = with0->get_FNumPoints(); + with0->myFileCmd = String("file=") + FileName + " column=1"; // Command for P + MMFError = CreateMMF(with0->myFileCmd, 0); // Creates MMF for the whole file + with0->myViewQ = with0->myView; + if(MMFError == 0) + { + with0->LoadFileFeatures(0); // Features for P + with0->myFileCmd = String("file=") + FileName + " column=2"; // Command for Q + with0->LoadFileFeatures(1); // Features for Q + with0->myDataSize = with0->get_FNumPoints(); + with0->myLineLenQ = with0->myLineLen; + with0->PMultipliers.resize(2); + with0->QMultipliers.resize(2); + } + } + else + { + try + + // Allocate both P and Q multipliers + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + with0->QMultipliers.resize(with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + System::ReadLn(f, s); // read entire line and parse with AuxParser + /*AuxParser allows commas or white space*/ + /*# with AuxParser[ActiveActor] do */ + { + auto with1 = AuxParser[ActiveActor]; + with1->SetCmdString(s); + if(with0->Interval == 0.0) + { + dummy = with1->GetNextParam(); + (with0->Hours)[i - 1] = with1->MakeDouble_(); + } + dummy = with1->GetNextParam(); + (with0->PMultipliers)[i - 1] = with1->MakeDouble_(); // first parm + dummy = with1->GetNextParam(); + (with0->QMultipliers)[i - 1] = with1->MakeDouble_(); // second parm + } + } + System::CloseFile(f); + if(i != with0->get_FNumPoints()) + with0->Set_NumPoints(i); + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 614); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + } + } +} + +void TLoadShape::DoCSVFile(const String FileName) +{ + int MMFError = 0; + int i = 0; + String dummy, s; + System::TTextRec f = {}; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 613); + System::CloseFile(f); System::InOutRes = 0; + return; + } + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + CloseFile(f); + s = String("file=") + FileName; + MMFError = CreateMMF(s, 0); // Creates MMF for P + if(MMFError == 0) + { + with0->LoadFileFeatures(0); + with0->myDataSize = with0->get_FNumPoints(); + with0->PMultipliers.resize(2); + } + } + else + { + try + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + System::ReadLn(f, s); // read entire line and parse with AuxParser + /*AuxParser allows commas or white space*/ + /*# with AuxParser[ActiveActor] do */ + { + auto with1 = AuxParser[ActiveActor]; + with1->SetCmdString(s); + if(with0->Interval == 0.0) + { + dummy = with1->GetNextParam(); + (with0->Hours)[i - 1] = with1->MakeDouble_(); + } + dummy = with1->GetNextParam(); + (with0->PMultipliers)[i - 1] = with1->MakeDouble_(); + } + } + System::CloseFile(f); + if(i != with0->get_FNumPoints()) + with0->Set_NumPoints(i); + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 614); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoadShape::DoSngFile(const String FileName) +{ + String s; + System::TTypedFile f; + float hr = 0.0F; + float m = 0.0F; + int MMFError = 0; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 615); + System::CloseFile(f); System::InOutRes = 0; + return; + } + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + System::CloseFile(f); + s = String("sngfile=") + FileName; + MMFError = CreateMMF(s, 0); // Creates MMF for P + if(MMFError == 0) + { + with0->LoadFileFeatures(0); + with0->myDataSize = with0->get_FNumPoints(); + with0->PMultipliers.resize(2); + } + } + else + { + try + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + { + System::Read(f, &hr); + (with0->Hours)[i - 1] = hr; + } + System::Read(f, &m); + (with0->PMultipliers)[i - 1] = m; + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + catch(...) + { + DoSimpleMsg(String("Error Processing LoadShape File: \"") + FileName, 616); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoadShape::DoDblFile(const String FileName) +{ + String s; + System::TTypedFile f; + int MMFError = 0; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 617); + System::CloseFile(f); System::InOutRes = 0; + return; + } + /*# with ActiveLoadShapeObj do */ + { + auto with0 = ActiveLoadShapeObj; + if(with0->UseMMF) // A different procedure if the user is working with MMF + { + System::CloseFile(f); + s = String("dblfile=") + FileName; + MMFError = CreateMMF(s, 0); // Creates MMF for P + if(MMFError == 0) + { + with0->LoadFileFeatures(0); + with0->myDataSize = with0->get_FNumPoints(); + with0->PMultipliers.resize(2); + } + } + else + { + try + { + with0->PMultipliers.resize(with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + System::Read(f, &(with0->Hours)[i - 1]); + System::Read(f, &(with0->PMultipliers)[i - 1]); + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + catch(...) + { + DoSimpleMsg(String("Error Processing LoadShape File: \"") + FileName, 618); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TLoadShape Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLoadShapeObj::TLoadShapeObj(TDSSClass* ParClass, const String LoadShapeName) + : inherited(ParClass), + LastValueAccessed(1), + FNumPoints(0), + ArrayPropertyIndex(0), + iMaxP(0), + FStdDevCalculated(false), + MaxQSpecified(false), + FMean(0.0), + FStdDev(0.0), + Interval(0.0), + MaxP(0.0), + MaxQ(0.0), + BaseP(0.0), + BaseQ(0.0), + Enabled(false), + UseActual(false), + UseMMF(false), +#ifdef _WIN32 + myMMF(0), + myQMMF(0), +#endif + myFile(0), + myQFile(0), + myFileSizeQ(0), + myFileSize(0), + myViewQ(nullptr), + myView(nullptr), + myFileType(0), + myFileTypeQ(0), + myColumn(0), + myColumnQ(0), + myLineLen(0), + myLineLenQ(0), + myDataSize(0), + myDataSizeQ(0), + MyViewLenQ(0), + MyViewLen(0) +{ + Set_Name(LowerCase(LoadShapeName)); + DSSObjType = ParClass->DSSClassType; + Interval = 1.0; // hr + Hours.clear(); + PMultipliers.clear(); + QMultipliers.clear(); + MaxP = 1.0; + MaxQ = 0.0; + BaseP = 0.0; + BaseQ = 0.0; + UseActual = false; + UseMMF = false; // No memory mapping by default + MaxQSpecified = false; + FStdDevCalculated = false; // calculate on demand + Enabled = true; + MyViewLen = 1000; // 1kB by default, it may change for not missing a row + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLoadShapeObj::~TLoadShapeObj() +{ + if( !Hours.empty() ) + Hours.clear(); + if( !PMultipliers.empty() ) + PMultipliers.clear(); + if( !QMultipliers.empty() ) + QMultipliers.clear(); + + if(UseMMF) + { +#ifdef _WIN32 + UnmapViewOfFile(myView); + CloseHandle(myMMF); + CloseHandle(myFile); + UnmapViewOfFile(myViewQ); + CloseHandle(myQMMF); + CloseHandle(myQFile); +#else + if ((myViewQ != nullptr) && (myViewQ != myView)) + munmap(myViewQ, myFileSizeQ); + if (myView != nullptr) + munmap(myView, myFileSize); + + if ((myQFile != 0) && (myQFile != myFile)) + close(myQFile); + if (myFile != 0) + close(myQFile); +#endif + } + + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function returns a multiplier for the given hour. +// If no points exist in the curve, the result is 1.0 +// If there are fewer points than requested, the curve is simply assumed to repeat +// Thus a daily load curve can suffice for a yearly load curve: You just get the +// same day over and over again. +// The value returned is the nearest to the interval requested. Thus if you request +// hour=12.25 and the interval is 1.0, you will get interval 12. + +complex TLoadShapeObj::GetMult(double hr) +{ + complex result = CZero; + String FileType = ""; + bool MMFound = false; + int LocalPage = 0, + UpLimit = 0, + LowLimit = 0, + Index = 0, + j = 0, + i = 0; + + auto Set_Result_im = [&](double RealPart) -> double + { + double result = 0.0; + if(UseActual) // if actual, assume zero + result = 0.0; + else + result = RealPart; // same as real otherwise + return result; + }; + /*Set imaginary part of Result when Qmultipliers not defined*/ + result.re = 1.0; + result.im = 1.0; // default return value if no points in curve + if(FNumPoints > 0) + { + if(FNumPoints == 1) // Handle Exceptional cases + { + result.re = PMultipliers[1 - 1]; + if( !QMultipliers.empty()) + result.im = QMultipliers[1 - 1]; + else + result.im = Set_Result_im(result.re); + } + else + { + if(Interval > 0.0) // Using Interval + { + Index = Round(hr / Interval); + if(UseMMF) + { + if(Index > myDataSize) + Index = Index % myDataSize; // Wrap around using remainder + if(Index == 0) + Index = myDataSize; + result.re = InterpretDblArrayMMF(myView, myFileType, myColumn, Index, myLineLen); + if( !QMultipliers.empty() ) + result.im = InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, Index, myLineLenQ); + else + result.im = Set_Result_im(result.re); + } + else + { + if(Index > FNumPoints) + Index = Index % FNumPoints; // Wrap around using remainder + if(Index == 0) + Index = FNumPoints; + result.re = PMultipliers[Index - 1]; + if(!QMultipliers.empty()) + result.im = QMultipliers[Index - 1]; + else + result.im = Set_Result_im(result.re); + } + } + else + + // For random interval + /* Start with previous value accessed under the assumption that most + of the time, this function will be called sequentially*/ + /*Normalize Hr to max hour in curve to get wraparound*/ + { + int stop = 0; + if(hr > (Hours)[FNumPoints - 1]) + hr = hr - Trunc(hr / (Hours)[FNumPoints - 1]) * (Hours)[FNumPoints - 1]; + if((Hours)[LastValueAccessed - 1] > hr) + LastValueAccessed = 1; // Start over from beginning + for(stop = FNumPoints, i = LastValueAccessed + 1; i <= stop; i++) + { + if(Abs(((Hours)[i - 1] - hr)) < 0.00001) // If close to an actual point, just use it. + { + if(UseMMF) + { + result.re = InterpretDblArrayMMF(myView, myFileType, myColumn, Index, myLineLen); + if(!QMultipliers.empty()) + result.im = InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, Index, myLineLenQ); + else + result.im = Set_Result_im(result.re); + } + else + { + result.re = PMultipliers[i - 1]; + if(!QMultipliers.empty()) + result.im = QMultipliers[i - 1]; + else + result.im = Set_Result_im(result.re); + } + LastValueAccessed = i; + return result; + } + else + { + if((Hours)[i - 1] > hr) // Interpolate for multiplier + { + LastValueAccessed = i - 1; + if(UseMMF) + { + result.re = InterpretDblArrayMMF(myView, myFileType, myColumn, LastValueAccessed, myLineLen) + (hr - (Hours)[LastValueAccessed - 1]) / ((Hours)[i - 1] - (Hours)[LastValueAccessed - 1]) * (InterpretDblArrayMMF(myView, myFileType, myColumn, i, myLineLen) - InterpretDblArrayMMF(myView, myFileType, myColumn, LastValueAccessed, myLineLen)); + if(!QMultipliers.empty()) + result.im = InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, LastValueAccessed, myLineLenQ) + (hr - (Hours)[LastValueAccessed - 1]) / ((Hours)[i - 1] - (Hours)[LastValueAccessed - 1]) * (InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, i, myLineLenQ) - InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, LastValueAccessed, myLineLenQ)); + else + result.im = Set_Result_im(result.re); + } + else + { + result.re = PMultipliers[LastValueAccessed - 1] + (hr - (Hours)[LastValueAccessed - 1]) / ((Hours)[i - 1] - (Hours)[LastValueAccessed - 1]) * (PMultipliers[i - 1] - PMultipliers[LastValueAccessed - 1]); + if(!QMultipliers.empty()) + result.im = QMultipliers[LastValueAccessed - 1] + (hr - (Hours)[LastValueAccessed - 1]) / ((Hours)[i - 1] - (Hours)[LastValueAccessed - 1]) * (QMultipliers[i - 1] - QMultipliers[LastValueAccessed - 1]); + else + result.im = Set_Result_im(result.re); + } + return result; + } + } + } + // If we fall through the loop, just use last value + LastValueAccessed = FNumPoints - 1; + result.re = PMultipliers[FNumPoints - 1]; + if(!QMultipliers.empty()) + result.im = QMultipliers[FNumPoints - 1]; + else + result.im = Set_Result_im(result.re); + } + } + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// normalize this load shape + +void TLoadShapeObj::Normalize() +{ + double MaxMult = 0.0; + + auto DoNormalize = [&](pDoubleArray Multipliers) -> void + { + int i = 0; + if(FNumPoints > 0) + { + int stop = 0; + if(MaxMult <= 0.0) + { + int stop = 0; + MaxMult = Abs((Multipliers)[1 - 1]); + for(stop = FNumPoints, i = 2; i <= stop; i++) + { + MaxMult = max(MaxMult, Abs((Multipliers)[i - 1])); + } + } + if(MaxMult == 0.0) + MaxMult = 1.0; // Avoid divide by zero + for(stop = FNumPoints, i = 1; i <= stop; i++) + { + (Multipliers)[i - 1] = (Multipliers)[i - 1] / MaxMult; + } + } + }; + if(UseMMF) + DoSimpleMsg("Normalize is not possible when working in memory mapping mode\"", 2000001); + else + { + MaxMult = BaseP; + DoNormalize(&(PMultipliers[0])); + if(!QMultipliers.empty()) + { + MaxMult = BaseQ; + DoNormalize(&(QMultipliers[0])); + } + UseActual = false; // not likely that you would want to use the actual if you normalized it. + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoadShapeObj::CalcMeanandStdDev() +{ + if(FNumPoints > 0) + { + if(Interval > 0.0) + RCDMeanAndStdDev(&(PMultipliers[0]), FNumPoints, FMean, FStdDev); + else + CurveMeanAndStdDev(&(PMultipliers[0]), &(Hours[0]), FNumPoints, FMean, FStdDev); + } + Set_PropertyValue(5,Format("%.8g", FMean)); + Set_PropertyValue(6,Format("%.8g", FStdDev)); + FStdDevCalculated = true; + /* No Action is taken on Q multipliers*/ +} + +/* +Function TLoadShapeObj.Get_FirstMult:Double; +Begin + + If Npts>0 Then Begin + Result := Multipliers^[1]; + LastValueAccessed := 1; + End + Else + Result := 0.0; + +End; + +Function TLoadShapeObj.Get_NextMult :Double; +Begin + + If Npts>0 Then Begin + Inc(LastValueAccessed); + If LastValueAccessed>Npts Then Begin + Result := 0.0; + Dec(LastValueAccessed); + End + Else Begin + Result := Multipliers^[LastValueAccessed]; + End; + End Else + Result := 0.0; + +End; +*/ + +double TLoadShapeObj::Get_Interval() +{ + double result = 0.0; + if(Interval > 0.0) + result = Interval; + else + { + if(LastValueAccessed > 1) + result = (Hours)[LastValueAccessed - 1] - (Hours)[LastValueAccessed - 1 - 1]; + else + result = 0.0; + } + return result; +} + +double TLoadShapeObj::Get_Mean() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FMean; + return result; +} + +double TLoadShapeObj::Get_StdDev() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FStdDev; + return result; +} + +double TLoadShapeObj::Mult(int i) +{ + double result = 0.0; + if((i <= FNumPoints) && (i > 0)) + { + if(UseMMF) + result = InterpretDblArrayMMF(myView, myFileType, myColumn, i, myLineLen); + else + result = PMultipliers[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; +} + +double TLoadShapeObj::Hour(int i) +{ + double result = 0.0; + if(Interval == 0) + { + if((i <= FNumPoints) && (i > 0)) + { + result = (Hours)[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + } + else + { + result = (Hours)[i - 1] * Interval; + LastValueAccessed = i; + } + return result; +} + +void TLoadShapeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "="); + System::WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +String TLoadShapeObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 2: + result = Format("%.8g", Interval); + break; + case 3: + { + if(UseMMF) + result = String("(") + myFileCmd + ")"; + else + result = GetDSSArray_Real(FNumPoints, &(PMultipliers[0])); + } + break; + case 4: + if(!Hours.empty()) + result = GetDSSArray_Real(FNumPoints, &(Hours[0])); + break; + case 5: + result = Format("%.8g", Get_Mean()); + break; + case 6: + result = Format("%.8g", Get_StdDev()); + break; + case 11: + { + if(!QMultipliers.empty()) + { + if(UseMMF) + result = String("(") + myFileCmdQ + ")"; + else + result = GetDSSArray_Real(FNumPoints, &(QMultipliers[0])); + } + } + break; + case 12: + if(UseActual) + result = "Yes"; + else + result = "No"; + break; + case 13: + result = Format("%.8g", MaxP); + break; + case 14: + result = Format("%.8g", MaxQ); + break; + case 15: + result = Format("%.8g", Interval * 3600.0); + break; + case 16: + result = Format("%.8g", Interval * 60.0); + break; + case 17: + result = Format("%.8g", BaseP); + break; + case 18: + result = Format("%.8g", BaseQ); + break; + case 19: + { + if(UseMMF) + result = String("(") + myFileCmd + ")"; + else + result = GetDSSArray_Real(FNumPoints, &(PMultipliers[0])); + } + break; + case 21: + if(UseMMF) + result = "Yes"; + else + result = "No"; + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TLoadShapeObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, "0"); // Number of points to expect + Set_PropertyValue(2, "1"); // default = 1.0 hr; + Set_PropertyValue(3, ""); // vector of multiplier values + Set_PropertyValue(4, ""); // vextor of hour values + Set_PropertyValue(5, "0"); // set the mean (otherwise computed) + Set_PropertyValue(6, "0"); // set the std dev (otherwise computed) + Set_PropertyValue(7, ""); // Switch input to a csvfile + Set_PropertyValue(8, ""); // switch input to a binary file of singles + Set_PropertyValue(9, ""); // switch input to a binary file of singles + Set_PropertyValue(10, ""); // action option . + Set_PropertyValue(11, ""); // Qmult. + Set_PropertyValue(12, "No"); + Set_PropertyValue(13, "0"); + Set_PropertyValue(14, "0"); + Set_PropertyValue(15, "3600"); // seconds + Set_PropertyValue(16, "60"); // minutes + Set_PropertyValue(17, "0"); + Set_PropertyValue(18, "0"); + Set_PropertyValue(19, ""); // same as 3 + Set_PropertyValue(20, ""); // switch input to csv file of P, Q pairs + Set_PropertyValue(21, "No"); // memory mapped load shape + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TLoadShape::TOPExport(String ObjName) +{ + TStringList* NameList = nullptr; + TStringList* cNames = nullptr; + pDoubleArray Vbuf = nullptr; + pDoubleArray CBuf = nullptr; + TLoadShapeObj* Obj = nullptr; + int MaxPts = 0; + int i = 0; + int j = 0; + double MaxTime = 0.0; + double MinInterval = 0.0; + double Hr_Time = 0.0; + PointerList::TPointerList* ObjList = nullptr; + /* + TOPTransferFile->FileName = GetOutputDirectory() + "TOP_LoadShape.STO"; + try + { + TOPTransferFile->Open(); + } + catch(Exception* e) + { + { + DoSimpleMsg(String("TOP Transfer File Error: ") + e->Message, 619); + try + { + TOPTransferFile->Close(); + //OK if Error + } + catch(...) + { + ; + } + return; + } + } + + //Send only fixed interval data + ObjList = new PointerList::TPointerList(10); + NameList = new TStringList(); + cNames = new TStringList(); + + //Make a List of fixed interval data where the interval is greater than 1 minute + if(CompareText(ObjName, "ALL") == 0) + { + Obj = ((TLoadShapeObj*) ElementList.Get_First()); + while(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + Obj = ((TLoadShapeObj*) ElementList.Get_Next()); + } + } + else + { + Obj = ((TLoadShapeObj*) Find(ObjName)); + if(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + else + DoSimpleMsg(String("Loadshape.") + ObjName + " is not hourly fixed interval.", 620); + } + else + { + DoSimpleMsg(String("Loadshape.") + ObjName + " not found.", 621); + } + } + + //If none found, exit + if(ObjList->get_myNumList() > 0) + + //Find Max number of points + { + int stop = 0; + MaxTime = 0.0; + MinInterval = 1.0; + Obj = ((TLoadShapeObj*) ObjList->Get_First()); + while(Obj != nullptr) + { + MaxTime = Max(MaxTime, Obj->get_FNumPoints() * Obj->Interval); + MinInterval = Min(MinInterval, Obj->Interval); + NameList->Add(Obj->get_Name()); + Obj = ((TLoadShapeObj*) ObjList->Get_Next()); + } + // SetLength(Xarray, maxPts); + MaxPts = (int) Round(MaxTime / MinInterval); + TOPTransferFile->WriteHeader(0.0, MaxTime, MinInterval, ObjList->get_myNumList(), 0, 16, "OpenDSS(TM), EPRI (R)"); + TOPTransferFile->WriteNames(NameList, cNames); + Hr_Time = 0.0; + Vbuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1 - 1]) * ObjList->get_myNumList())); + CBuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1 - 1]) * 1)); // just a dummy -- Cbuf is ignored here + for(stop = MaxPts, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = ObjList->get_myNumList(), j = 1; j <= stop1; j++) + { + Obj = ((TLoadShapeObj*) ObjList->Get(j)); + (*Vbuf)[j - 1] = Obj->GetMult(Hr_Time).re; + } + TOPTransferFile->WriteData(Hr_Time, Vbuf, CBuf); + Hr_Time = Hr_Time + MinInterval; + } + TOPTransferFile->Close(); + TOPTransferFile->SendToTop(); + Vbuf = (pDoubleArray) realloc(Vbuf, 0); + CBuf = (pDoubleArray) realloc(CBuf, 0); + } + delete ObjList; + delete NameList; + delete cNames; + */ +} + +void TLoadShapeObj::SaveToDblFile() +{ + double myDBL = 0.0; + System::TTypedFile f; + int i = 0; + String FName; + if (!PMultipliers.empty()) + { + try + { + FName = get_Name() + "_P.dbl"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + if (UseMMF) + { + int stop = 0; + for (stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + myDBL = InterpretDblArrayMMF(myView, myFileType, myColumn, i, myLineLen); + System::Write(f, &myDBL); + } + } + else + { + int stop = 0; + for (stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + System::Write(f, &PMultipliers[i - 1]); + } + } + GlobalResult = String("mult=[dblfile=") + FName + "]"; + // } + // __finally + // { + System::CloseFile(f); + } + catch (...) + { + // Added to match Delphi (try) + } + if(!QMultipliers.empty()) + { + try + { + FName = get_Name() + "_Q.dbl"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + if(UseMMF) + { + int stop = 0; + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + myDBL = InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, i, myLineLenQ); + System::Write(f, &myDBL); + } + } + else + { + int stop = 0; + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + System::Write(f, &QMultipliers[i - 1]); + } + } + AppendGlobalResult(String(" Qmult=[dblfile=") + FName + "]"); +// } +// __finally +// { + System::CloseFile(f); + } + catch (...) + { + // added to match Delphi (try) + } + } + } + else + DoSimpleMsg(String("Loadshape.") + get_Name() + " P multipliers not defined.", 622); +} + +//-------------------------------------------------------------------------------------------- + +int TLoadShapeObj::get_FNumPoints() +{ + return FNumPoints; +} + +//-------------------------------------------------------------------------------------------- + +void TLoadShapeObj::SaveToSngFile() +{ + System::TTypedFile f; + int i = 0; + String FName; + float Temp = 0.0F; + if(!PMultipliers.empty()) + { + try + { + int stop = 0; + FName = get_Name() + "_P.sng"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + if(UseMMF) + Temp = (float) InterpretDblArrayMMF(myView, myFileType, myColumn, i, myLineLen); + else + Temp = (float) PMultipliers[i - 1]; + System::Write(f, &Temp); + } + GlobalResult = String("mult=[sngfile=") + FName + "]"; +// } +// __finally +// { + CloseFile(f); + } + catch (...) + { + // added to match with Delphi (try) + } + if(!QMultipliers.empty()) + { + try + { + int stop = 0; + FName = get_Name() + "_Q.sng"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + if(UseMMF) + Temp = (float) InterpretDblArrayMMF(myViewQ, myFileTypeQ, myColumnQ, i, myLineLenQ); + else + Temp = (float) QMultipliers[i - 1]; + System::Write(f, &Temp); + } + AppendGlobalResult(String(" Qmult=[sngfile=") + FName + "]"); +// } +// __finally +// { + CloseFile(f); + } + catch (...) + { + // Added to match Delphi (try) + } + } + } + else + DoSimpleMsg(String("Loadshape.") + get_Name() + " P multipliers not defined.", 623); +} + +void TLoadShapeObj::SetMaxPandQ() +{ + if(!UseMMF) + { + iMaxP = iMaxAbsdblArrayValue(get_FNumPoints(), &(PMultipliers[0])); + if(iMaxP > 0) + { + MaxP = PMultipliers[iMaxP - 1]; + if(!MaxQSpecified) + { + if(!QMultipliers.empty()) + MaxQ = QMultipliers[iMaxP - 1]; + else + MaxQ = 0.0; + } + } + } +} + +void TLoadShapeObj::Set_Mean(double Value) +{ + FStdDevCalculated = true; + FMean = Value; +} + +void TLoadShapeObj::Set_NumPoints(int Value) +{ + Set_PropertyValue(1,IntToStr(Value)); // Update property list variable + + // Reset array property values to keep them in proper order in Save + if(ArrayPropertyIndex > 0) + Set_PropertyValue(ArrayPropertyIndex,Get_PropertyValue(ArrayPropertyIndex)); + if(!QMultipliers.empty()) + Set_PropertyValue(11,Get_PropertyValue(11)); + FNumPoints = Value; // Now assign the value +} + +void TLoadShapeObj::Set_StdDev(double Value) +{ + FStdDevCalculated = true; + FStdDev = Value; +} + +} // namespace LoadShape + + + + + diff --git a/OpenDSSC/General/LoadShape.h b/OpenDSSC/General/LoadShape.h new file mode 100644 index 0000000..aa7a546 --- /dev/null +++ b/OpenDSSC/General/LoadShape.h @@ -0,0 +1,204 @@ +#ifndef LoadShapeH +#define LoadShapeH + +#include // uint8_t +#include "System.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "d2c_structures.h" + +namespace LoadShape +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 8-18-00 Added call to InterpretDblArrayto allow File=Syntax */ + +/*The LoadShape object is a general DSS object used by all circuits + as a reference for obtaining yearly, daily, and other load shapes. + + The values are set by the normal New and Edit procedures for any DSS object. + + The values are retrieved by setting the Code Property in the LoadShape Class. + This sets the active LoadShape object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. Or you + can pick up the ActiveLoadShapeObj object and save the direct reference to the object. + + Loadshapes default to fixed interval data. If the Interval is specified to be 0.0, + then both time and multiplier data are expected. If the Interval is greater than 0.0, + the user specifies only the multipliers. The Hour command is ignored and the files are + assumed to contain only the multiplier data. + + The user may place the data in CSV or binary files as well as passing through the + command interface. Obviously, for large amounts of data such as 8760 load curves, the + command interface is cumbersome. CSV files are text separated by commas, one interval to a line. + There are two binary formats permitted: 1) a file of Singles; 2) a file of Doubles. + + For fixed interval data, only the multiplier is expected. Therefore, the CSV format would + contain only one number per line. The two binary formats are packed. + + For variable interval data, (hour, multiplier) pairs are expected in both formats. + + The Mean and Std Deviation are automatically computed upon demand when new series of points is entered. + + The data may also be entered in unnormalized form. The normalize=Yes command will force normalization. That + is, the multipliers are scaled so that the maximum value is 1.0. + + */ + +class TLoadShape : public TDSSClass +{ + friend class TLoadShapeObj; +public: + typedef TDSSClass inherited; +private: + string Get_Code(); // Returns active LoadShape string + void Set_Code(const String Value); // sets the active LoadShape + void DoCSVFile(const String FileName); + void Do2ColCSVFile(const String FileName); // for P and Q pairs + void DoSngFile(const String FileName); + void DoDblFile(const String FileName); +protected: + void DefineProperties(); + virtual int MakeLike(const String ShapeName); +public: + TLoadShape(); + virtual ~TLoadShape(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void* Find(const String ObjName); // Find an obj of this class by name + void TOPExport(String ObjName); + int CreateMMF(const String s, int Destination); +}; + +class TLoadShapeObj : public DSSObject::TDSSObject +{ + friend class TLoadShape; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int LastValueAccessed; + int FNumPoints; // Number of points in curve + int ArrayPropertyIndex; + int iMaxP; + bool FStdDevCalculated; + bool MaxQSpecified; + double FMean; + double FStdDev; + + // Function Get_FirstMult:Double; + // Function Get_NextMult :Double; + double Get_Interval(); + void Set_NumPoints(int Value); + void SaveToDblFile(); + void SaveToSngFile(); + void CalcMeanandStdDev(); + double Get_Mean(); + double Get_StdDev(); + void Set_Mean(double Value); + void Set_StdDev(double Value); // Normalize the curve presently in memory + void SetMaxPandQ(); +public: + double Interval; //=0.0 then random interval (hr) + // Time values (hr) if Interval > 0.0 Else nil + std::vector Hours; + std::vector PMultipliers; + std::vector QMultipliers; // Multipliers + double MaxP; + double MaxQ; + double BaseP; + double BaseQ; + bool Enabled; + bool UseActual; + + /************************************************************************ + * Memory mapping variables * + *************************************************************************/ + bool UseMMF; // Flag to indicated that the user wants to use MMF +#ifdef _WIN32 + HANDLE myMMF; // Handle for the memory map (P) + HANDLE myFile; // Handle for the file to be mapped (P) + HANDLE myQMMF; // Handle for the memory map (Q) + HANDLE myQFile; // Handle for the file to be mapped (Q) +#else + int myFile; // Handle for the file to be mapped (P) + int myQFile; // Handle for the file to be mapped (Q) +#endif + + unsigned int myFileSizeQ; // File size of the file opened (Q) + unsigned int myFileSize; // File size of the file opened (P) + string myFileCmdQ; + string myFileCmd; // The file definition added by the user (for moving the data window) + // Current view of the file mapped (Bytes - Q) + uint8_t* myViewQ; + uint8_t* myView; // Current view of the file mapped (Bytes - P) + // The file type (P) + // The file type (Q) + // The column to read (P) + // The column to read (Q) + // The size of the char line (P) + // The size of the char line (Q) + // The total data size expected (P) + // The total data size expected (Q) + // Memory View size in bytes (Q) + int myFileType; + int myFileTypeQ; + int myColumn; + int myColumnQ; + int myLineLen; + int myLineLenQ; + int myDataSize; + int myDataSizeQ; + int MyViewLenQ; + int MyViewLen; // Memory View size in bytes (P) + + //********************************************************************** + TLoadShapeObj(DSSClass::TDSSClass* ParClass, const string LoadShapeName); + virtual ~TLoadShapeObj(); + Ucomplex::complex GetMult(double hr); // Get multiplier at specified time + double Mult(int i); // get multiplier by index + double Hour(int i); // get hour corresponding to point index + void Normalize(); + // Loads the current view of the MMF into memory for further use + void LoadMMFView(const string Parmname, int Destination); + void LoadFileFeatures(int ShapeType); + virtual string GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + int get_FNumPoints(); + + /*Property FirstMult :Double Read Get_FirstMult;*/ + /*Property NextMult :Double Read Get_NextMult;*/ + TLoadShapeObj(DSSClass::TDSSClass* ParClass); + TLoadShapeObj(string ClassName); + TLoadShapeObj(); + string mode; +}; +extern TLoadShapeObj* ActiveLoadShapeObj; + + +} // namespace LoadShape + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LoadShape; +#endif + +#endif // LoadShapeH + + + + + diff --git a/OpenDSSC/General/NamedObject.cpp b/OpenDSSC/General/NamedObject.cpp new file mode 100644 index 0000000..2c0f4d8 --- /dev/null +++ b/OpenDSSC/General/NamedObject.cpp @@ -0,0 +1,170 @@ +#pragma hdrstop + +#include "NamedObject.h" + +#ifndef windows +#include // uuid_generate +#include // std::memcpy +#endif + + + + +using namespace std; +using namespace System; + +namespace NamedObject +{ + + TNamedObject::TNamedObject() {} + + string TNamedObject::Get_myPName() + { + return PName; + } + + + void TNamedObject::Set_myPName(string Value) + { + PName = Value; + } + + string TNamedObject::Get_myLName() + { + return LName; + } + + void TNamedObject::Set_myLName(std::string Value) + { + LName = Value; + } + + + + int CreateUUID4(TUuid& UUID) + { +#ifdef windows + int result = 0; + result = CoCreateGuid(&UUID); +#else + // Note: This code looks peculiar because uuid_t is not a + // struct. It is instead a typedef to unsigned char [16]. + uuid_t _UUID; + uuid_generate(_UUID); // This function returns void. + static_assert(sizeof(_UUID) == sizeof(UUID),"Wrong _UUID!"); + std::memcpy(&UUID, &_UUID[0], sizeof(_UUID)); + + // CoCreateGuid returns S_OK to indicate success, which on MS + // Windows, appears to be 0. Too bad no one checks our return + // value... + int result = 0; // emulate S_OK +#endif + UUID.Data3 = (WORD)((UUID.Data3 & 0x0FFF) | 0x4000); // place a 4 at character 13 + UUID.Data4[0] = (unsigned char)((UUID.Data4[0] & 0x3F) | 0x80); // character 17 to be 8, 9, A or B + return result; + } + + TUuid StringToUUID(string s) + { + TUuid result = {}; + result = StringToGuid(s); + return result; + } + + String UUIDToString(const TUuid& UUID) + { + String result; + result = GuidToString(UUID); + return result; + } + + String UUIDToCIMString(const TUuid& cUUID) + { + TUuid UUID = cUUID; + String result; + String s; + s = GuidToString(UUID); + result = s.substr(1, s.length() - 2); + return result; + } + + TNamedObject::TNamedObject(string ClassName) + : PName(ClassName), + LName(""), + DName(""), + puuid(nullptr) + { + ; + } + + TNamedObject::~TNamedObject() + { + // if (ASSIGNED(puuid)) + // delete puuid; + // inherited::Destroy(); + } + + + void TNamedObject::Set_DisplayName(const string Value) + { + DName = Value; + } + + String TNamedObject::Get_DisplayName() + { + String result; + if (DName == "") + result = PName + "_" + LName; + else + result = DName; + return result; + } + + String TNamedObject::Get_QualifiedName() + { + String result; + result = PName + "." + LName; + return result; + } + + void TNamedObject::Set_UUID(const TUuid& Value) + { + if (puuid == nullptr) + puuid = new GUID; + (*puuid) = Value; + } + + const TUuid& TNamedObject::Get_UUID() + { + if (puuid == nullptr) + { + puuid = new TUuid; + CreateUUID4(*puuid); + } + return *puuid; + } + + String TNamedObject::Get_ID() + { + String result; + result = GuidToString(Get_UUID()); + return result; + } + + String TNamedObject::Get_CIM_ID() + { + String result; + result = UUIDToCIMString(Get_UUID()); + return result; + } +} + + + + + + + + + + diff --git a/OpenDSSC/General/NamedObject.h b/OpenDSSC/General/NamedObject.h new file mode 100644 index 0000000..ecda826 --- /dev/null +++ b/OpenDSSC/General/NamedObject.h @@ -0,0 +1,64 @@ +#ifndef NamedObjectH +#define NamedObjectH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + + +namespace NamedObject +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +typedef GUID TUuid; // this is a GUID compliant to RFC 4122, v4 + +class TNamedObject : public System::TObject +{ +public: + typedef TObject inherited; +//private: +public: + std::string PName; // path name, or class name for DSS + std::string LName; // localName is unique within a class, like the old FName + std::string DName; // for optional display, does not have to be unique + TUuid* puuid; // compliant to RFC 4122, v4 + std::string Get_QualifiedName(); + std::string Get_DisplayName(); + void Set_DisplayName(const std::string Value); + const TUuid& Get_UUID(); + std::string Get_ID(); + std::string Get_CIM_ID(); + void Set_UUID(const TUuid& Value); + std::string Get_myPName(); + void Set_myPName(std::string Value); + std::string Get_myLName(); + void Set_myLName(std::string Value); +public: + TNamedObject(std::string ClassName); + virtual ~TNamedObject(); + TNamedObject(); +}; +int CreateUUID4(TUuid& UUID); +TUuid StringToUUID(std::string s); +std::string UUIDToString(const TUuid& UUID); +String UUIDToCIMString(const TUuid& cUUID); + + +} // namespace NamedObject + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace NamedObject; +#endif + +#endif // NamedObjectH + + + + + diff --git a/OpenDSSC/General/OHLineConstants.cpp b/OpenDSSC/General/OHLineConstants.cpp new file mode 100644 index 0000000..5c56dc6 --- /dev/null +++ b/OpenDSSC/General/OHLineConstants.cpp @@ -0,0 +1,36 @@ + +#pragma hdrstop + +#include "OHLineConstants.h" + +using namespace std; +using namespace LineConstants; +using namespace System; + +namespace OHLineConstants +{ + +TOHLineConstants::TOHLineConstants() {} + + + +TOHLineConstants::TOHLineConstants(int NumConductors) + : inherited(NumConductors) +{ +} + +TOHLineConstants::~TOHLineConstants() +{ + // inherited; +} + + + + + +} // namespace OHLineConstants + + + + + diff --git a/OpenDSSC/General/OHLineConstants.h b/OpenDSSC/General/OHLineConstants.h new file mode 100644 index 0000000..97c0181 --- /dev/null +++ b/OpenDSSC/General/OHLineConstants.h @@ -0,0 +1,49 @@ +#ifndef OHLineConstantsH +#define OHLineConstantsH + +#include "System.h" + +#include "Arraydef.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LineUnits.h" +#include "LineConstants.h" + +namespace OHLineConstants +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Manages the geometry data and calculates the impedance matrices for an overhead line*/ + +class TOHLineConstants : public LineConstants::TLineConstants +{ +public: + typedef LineConstants::TLineConstants inherited; +private: +protected: +public: + TOHLineConstants(int NumConductors); + virtual ~TOHLineConstants(); + TOHLineConstants(); +}; + + +} // namespace OHLineConstants + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace OHLineConstants; +#endif + +#endif // OHLineConstantsH + + + + + diff --git a/OpenDSSC/General/PriceShape.cpp b/OpenDSSC/General/PriceShape.cpp new file mode 100644 index 0000000..702c356 --- /dev/null +++ b/OpenDSSC/General/PriceShape.cpp @@ -0,0 +1,1011 @@ + +#pragma hdrstop + +#include "PriceShape.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "mathutil.h" +#include "Utilities.h" +//#include "TOPExport.h" +#include +#include "PointerList.h" + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace PointerList; +using namespace System; +using namespace mathutil; +using namespace Utilities; + +namespace PriceShape +{ + +TPriceShapeObj::TPriceShapeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TPriceShapeObj::TPriceShapeObj(String ClassName) : inherited(ClassName) {} +TPriceShapeObj::TPriceShapeObj() {} + + +TPriceShapeObj* ActivePriceShapeObj = nullptr; +const int NumPropsThisClass = 12; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TPriceShape::TPriceShape() +{ + ; + Class_Name = "PriceShape"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TPriceShape::~TPriceShape() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TPriceShape::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + (PropertyName)[1 - 1] = "npts"; // Number of points to expect + (PropertyName)[2 - 1] = "interval"; // default = 1.0; + (PropertyName)[3 - 1] = "price"; // vector of price values + (PropertyName)[4 - 1] = "hour"; // vector of hour values + (PropertyName)[5 - 1] = "mean"; // set the mean Price (otherwise computed) + (PropertyName)[6 - 1] = "stddev"; // set the std dev of the Price (otherwise computed) + (PropertyName)[7 - 1] = "csvfile"; // Switch input to a csvfile + (PropertyName)[8 - 1] = "sngfile"; // switch input to a binary file of singles + (PropertyName)[9 - 1] = "dblfile"; // switch input to a binary file of singles + (PropertyName)[10 - 1] = "sinterval"; // Interval in seconds + (PropertyName)[11 - 1] = "minterval"; // Interval in minutes + (PropertyName)[12 - 1] = "action"; // + + // define Property help values + (PropertyHelp)[1 - 1] = "Max number of points to expect in price shape vectors. This gets reset to the number of Price values " + "found if less than specified."; // Number of points to expect + (PropertyHelp)[2 - 1] = String("Time interval for fixed interval data, hrs. Default = 1. " "If Interval = 0 then time data (in hours) may be at irregular intervals and time value must be specified using either the Hour property or input files. " "Then values are interpolated when Interval=0, but not for fixed interval data. ") + CRLF + + CRLF + + "See also \"sinterval\" and \"minterval\"."; // default = 1.0; + (PropertyHelp)[3 - 1] = String("Array of Price values. Units should be compatible with the object using the data. " "You can also use the syntax: ") + CRLF + + "Price = (file=filename) !for text file one value per line" + + CRLF + + "Price = (dblfile=filename) !for packed file of doubles" + + CRLF + + "Price = (sngfile=filename) !for packed file of singles " + + CRLF + + CRLF + + "Note: this property will reset Npts if the number of values in the files are fewer."; // vextor of hour values + (PropertyHelp)[4 - 1] = String("Array of hour values. Only necessary to define this property for variable interval data." " If the data are fixed interval, do not use this property. " "You can also use the syntax: ") + CRLF + + "hour = (file=filename) !for text file one value per line" + + CRLF + + "hour = (dblfile=filename) !for packed file of doubles" + + CRLF + + "hour = (sngfile=filename) !for packed file of singles "; // vextor of hour values + (PropertyHelp)[5 - 1] = "Mean of the Price curve values. This is computed on demand the first time a " + "value is needed. However, you may set it to another value independently. " + "Used for Monte Carlo load simulations."; // set the mean (otherwise computed) + (PropertyHelp)[6 - 1] = String("Standard deviation of the Prices. This is computed on demand the first time a " "value is needed. However, you may set it to another value independently." "Is overwritten if you subsequently read in a curve") + CRLF + + CRLF + + "Used for Monte Carlo load simulations."; // set the std dev (otherwise computed) + (PropertyHelp)[7 - 1] = "Switch input of Price curve data to a csv file " + "containing (hour, Price) points, or simply (Price) values for fixed time interval data, one per line. " + "NOTE: This action may reset the number of points to a lower value."; // Switch input to a csvfile + (PropertyHelp)[8 - 1] = "Switch input of Price curve data to a binary file of singles " + "containing (hour, Price) points, or simply (Price) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + (PropertyHelp)[9 - 1] = "Switch input of Price curve data to a binary file of doubles " + "containing (hour, Price) points, or simply (Price) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + (PropertyHelp)[10 - 1] = "Specify fixed interval in SECONDS. Alternate way to specify Interval property."; + (PropertyHelp)[11 - 1] = "Specify fixed interval in MINUTES. Alternate way to specify Interval property."; + (PropertyHelp)[12 - 1] = "{DblSave | SngSave} After defining Price curve data... " + "Setting action=DblSave or SngSave will cause the present \"Price\" values to be written to " + "either a packed file of double or single. The filename is the PriceShape name. "; // Action + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPriceShape::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TPriceShapeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPriceShape::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActivePriceShapeObj = ((TPriceShapeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActivePriceShapeObj; + /*# with ActivePriceShapeObj do */ + { + auto with0 = ActivePriceShapeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 58610); + break; + case 1: + with0->Set_NumPoints( Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->Interval = Parser[ActorID]->MakeDouble_(); + break; + case 3: + { + with0->PriceValues = (pDoubleArray) realloc(with0->PriceValues, sizeof(double) * with0->get_FNumPoints()); + // Allow possible Resetting (to a lower value) of num points when specifying Prices not Hours + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), with0->PriceValues)); // Parser.ParseAsVector(Npts, Prices); + } + break; + case 4: + { + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), with0->Hours)); // Parser.ParseAsVector(Npts, Hours); + } + break; + case 5: + with0->Set_Mean(Parser[ActorID]->MakeDouble_()); + break; + case 6: + with0->Set_StdDev(Parser[ActorID]->MakeDouble_()); + break; + case 7: + DoCSVFile(Param); + break; + case 8: + DoSngFile(Param); + break; + case 9: + DoDblFile(Param); + break; + case 10: + with0->Interval = double(Parser[ActorID]->MakeDouble_()) / 3600.0; + break; // Convert seconds to hr + case 11: + with0->Interval = double(Parser[ActorID]->MakeDouble_()) / 60.0; + break; // Convert minutes to hr + case 12: + switch(LowerCase(Param)[1]) + { + case L'd': + with0->SaveToDblFile(); + break; + case L's': + with0->SaveToSngFile(); + break; + default: + ; + break; + } + break; + // Inherited parameters + default: + ClassEdit(ActivePriceShapeObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 3: case 7: case 8: case 9: + { + with0->FStdDevCalculated = false; // now calculated on demand + with0->ArrayPropertyIndex = ParamPointer; + with0->Set_NumPoints(with0->FNumPoints); // Keep Properties in order for save command + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*While*/ + } /*WITH*/ + return result; +} + +void* TPriceShape::Find(const String ObjName) +{ + void* result = nullptr; + if((ObjName.length() == 0) || (CompareText(ObjName, "none") == 0)) + result = nullptr; + else + result = inherited::Find(ObjName); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPriceShape::MakeLike(const String ShapeName) +{ + int result = 0; + TPriceShapeObj* OtherPriceShape = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherPriceShape = ((TPriceShapeObj*) Find(ShapeName)); + if(OtherPriceShape != nullptr) + /*# with ActivePriceShapeObj do */ + { + auto with0 = ActivePriceShapeObj; + int stop = 0; + with0->Set_NumPoints(OtherPriceShape->get_FNumPoints()); + with0->Interval = OtherPriceShape->Interval; + with0->PriceValues = (pDoubleArray) realloc(with0->PriceValues, sizeof(double) * with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->PriceValues)[i - 1] = (OtherPriceShape->PriceValues)[i - 1]; + } + if(with0->Interval > 0.0) + free(with0->Hours); + else + { + int stop = 0; + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->Hours)[i - 1] = (OtherPriceShape->Hours)[i - 1]; + } + } + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherPriceShape->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in PriceShape MakeLike: \"") + ShapeName + + "\" Not Found.", 58611); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPriceShape::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TPriceShape.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + +String TPriceShape::Get_Code() +{ + String result; + TPriceShapeObj* PriceShapeObj = nullptr; + PriceShapeObj = ((TPriceShapeObj*) ElementList.Get_Active()); + result = PriceShapeObj->get_Name(); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active PriceShape + +void TPriceShape::Set_Code(const String Value) +{ + TPriceShapeObj* PriceShapeObj = nullptr; + ActivePriceShapeObj = nullptr; + PriceShapeObj = ((TPriceShapeObj*) ElementList.Get_First()); + while(PriceShapeObj != nullptr) + { + if(CompareText(PriceShapeObj->get_Name(), Value) == 0) + { + ActivePriceShapeObj = PriceShapeObj; + return; + } + PriceShapeObj = ((TPriceShapeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("PriceShape: \"") + Value + "\" not Found.", 58612); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TPriceShape::DoCSVFile(const String FileName) +{ + String dummy; + System::TTextRec f = {}; + int i = 0; + String s; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 58613); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActivePriceShapeObj do */ + { + auto with0 = ActivePriceShapeObj; + with0->PriceValues = (pDoubleArray) realloc(with0->PriceValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + ReadLn(f, s); // read entire line and parse with AuxParser + /*AuxParser allows commas or white space*/ + /*# with AuxParser[ActiveActor] do */ + { + auto with1 = AuxParser[ActiveActor]; + + with1->SetCmdString(s); + if(with0->Interval == 0.0) + { + dummy = with1->GetNextParam(); + (with0->Hours)[i - 1] = with1->MakeDouble_(); + } + dummy = with1->GetNextParam(); + (with0->PriceValues)[i - 1] = with1->MakeDouble_(); + } + } + CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 58614); + CloseFile(f); System::InOutRes = 0; + return; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TPriceShape::DoSngFile(const String FileName) +{ + System::TTypedFile f; + float hr = 0.0F; + float m = 0.0F; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 58615); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActivePriceShapeObj do */ + { + auto with0 = ActivePriceShapeObj; + with0->PriceValues = (pDoubleArray) realloc(with0->PriceValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + { + System::Read(f, &hr); + (with0->Hours)[i - 1] = hr; + } + System::Read(f, &m); + (with0->PriceValues)[i - 1] = m; + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing PriceShape File: \"") + FileName, 58616); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TPriceShape::DoDblFile(const String FileName) +{ + System::TTypedFile f; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 58617); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActivePriceShapeObj do */ + { + auto with0 = ActivePriceShapeObj; + with0->PriceValues = (pDoubleArray) realloc(with0->PriceValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + System::Read(f, &(with0->Hours)[i - 1]); + System::Read(f, &(with0->PriceValues)[i - 1]); + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing PriceShape File: \"") + FileName, 58618); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TPriceShape Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TPriceShapeObj::TPriceShapeObj(TDSSClass* ParClass, const String PriceShapeName) + : inherited(ParClass), + LastValueAccessed(1), + FNumPoints(0), + ArrayPropertyIndex(0), + FStdDevCalculated(false), + FMean(0.0), + FStdDev(0.0), + Interval(0.0), + Hours(nullptr), + PriceValues(nullptr) +{ + Set_Name(LowerCase(PriceShapeName)); + DSSObjType = ParClass->DSSClassType; + Interval = 1.0; // hr + Hours = nullptr; + PriceValues = nullptr; + FStdDevCalculated = false; // calculate on demand + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TPriceShapeObj::~TPriceShapeObj() +{ + free(Hours); + if(PriceValues != NULL) + free(PriceValues); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This FUNCTION returns the Price for the given hour. +// If no points exist in the curve, the result is 0.0 +// If there are fewer points than requested, the curve is simply assumed to repeat +// Thus a daily load curve can suffice for a yearly load curve: You just get the +// same day over and over again. +// The value returned is the nearest to the interval requested. Thus if you request +// hour=12.25 and the interval is 1.0, you will get interval 12. + +double TPriceShapeObj::GetPrice(double hr) +{ + double result = 0.0; + int Index = 0; + int i = 0; + result = 0.0; // default return value if no points in curve + if(FNumPoints > 0) + { + if(FNumPoints == 1) // Handle Exceptional cases + { + result = PriceValues[1 - 1]; + } + else + { + if(Interval > 0.0) + { + Index = (int) Round(hr / Interval); + if(Index > FNumPoints) + Index = Index % FNumPoints; // Wrap around using remainder + if(Index == 0) + Index = FNumPoints; + result = PriceValues[Index - 1]; + } + else + + // For random interval + + /* Start with previous value accessed under the assumption that most + of the time, this FUNCTION will be called sequentially*/ + + /*Normalize Hr to max hour in curve to get wraparound*/ + { + int stop = 0; + if(hr > Hours[FNumPoints - 1]) + { + hr = hr - Trunc(hr / Hours[FNumPoints - 1]) * Hours[FNumPoints - 1]; + } + if(Hours[LastValueAccessed - 1] > hr) + LastValueAccessed = 1; // Start over from Beginning + for(stop = FNumPoints, i = LastValueAccessed + 1; i <= stop; i++) + { + if(Abs((int) (Hours[i - 1] - hr)) < 0.00001) // If close to an actual point, just use it. + { + result = PriceValues[i - 1]; + LastValueAccessed = i; + return result; + } + else + { + if(Hours[i - 1] > hr) // Interpolate for Price + { + LastValueAccessed = i - 1; + result = PriceValues[LastValueAccessed - 1] + (hr - Hours[LastValueAccessed - 1]) / (Hours[i - 1] - Hours[LastValueAccessed - 1]) * (PriceValues[i - 1] - PriceValues[LastValueAccessed - 1]); + return result; + } + } + } + + // If we fall through the loop, just use last value + LastValueAccessed = FNumPoints - 1; + result = PriceValues[FNumPoints - 1]; + } + } + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TPriceShapeObj::CalcMeanandStdDev() +{ + if(FNumPoints > 0) + { + if(Interval > 0.0) + RCDMeanAndStdDev(PriceValues, FNumPoints, FMean, FStdDev); + else + CurveMeanAndStdDev(PriceValues, Hours, FNumPoints, FMean, FStdDev); + } + Set_PropertyValue(5,Format("%.8g", FMean)); + Set_PropertyValue(6,Format("%.8g", FStdDev)); + FStdDevCalculated = true; +} + +double TPriceShapeObj::Get_Interval() +{ + double result = 0.0; + if(Interval > 0.0) + result = Interval; + else + { + if(LastValueAccessed > 1) + result = Hours[LastValueAccessed - 1] - Hours[LastValueAccessed - 1 - 1]; + else + result = 0.0; + } + return result; +} + +double TPriceShapeObj::Get_Mean() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FMean; + return result; +} + +//------------------------------------------------------------------ + +int TPriceShapeObj::get_FNumPoints() +{ + return FNumPoints; +} + +//------------------------------------------------------------------ + +double TPriceShapeObj::Get_StdDev() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FStdDev; + return result; +} + +double TPriceShapeObj::Price(int i) +{ + double result = 0.0; + if((i <= FNumPoints) && (i > 0)) + { + result = PriceValues[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; +} + +double TPriceShapeObj::Hour(int i) +{ + double result = 0.0; + if(Interval == 0) + { + if((i <= FNumPoints) && (i > 0)) + { + result = Hours[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + } + else + { + result = Hours[i - 1] * Interval; + LastValueAccessed = i; + } + return result; +} + +void TPriceShapeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, L'='); + System::WriteLn(f, Get_PropertyValue(i)); + } + } + } +} + +String TPriceShapeObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 2: + result = Format("%.8g", Interval); + break; + case 3: + result = GetDSSArray_Real(FNumPoints, PriceValues); + break; + case 4: + if(Hours != nullptr) + result = GetDSSArray_Real(FNumPoints, Hours); + break; + case 5: + result = Format("%.8g", Get_Mean()); + break; + case 6: + result = Format("%.8g", Get_StdDev()); + break; + case 10: + result = Format("%.8g", Interval * 3600.0); + break; + case 11: + result = Format("%.8g", Interval * 60.0); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TPriceShapeObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); // Number of points to expect + Set_PropertyValue(2,"1"); // default = 1.0 hr; + Set_PropertyValue(3,""); // vector of multiplier values + Set_PropertyValue(4,""); // vextor of hour values + Set_PropertyValue(5,"0"); // set the mean (otherwise computed) + Set_PropertyValue(6,"0"); // set the std dev (otherwise computed) + Set_PropertyValue(7,""); // Switch input to a csvfile + Set_PropertyValue(8,""); // switch input to a binary file of singles + Set_PropertyValue(9,""); // switch input to a binary file of singles + Set_PropertyValue(10,"3600"); // seconds + Set_PropertyValue(11,"60"); // minutes + Set_PropertyValue(12,""); // action option . + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TPriceShape::TOPExport(String ObjName) +{ + TStringList* NameList = nullptr; + TStringList* cNames = nullptr; + pDoubleArray Vbuf = nullptr; + pDoubleArray CBuf = nullptr; + TPriceShapeObj* Obj = nullptr; + int MaxPts = 0; + int i = 0; + int j = 0; + double MaxTime = 0.0; + double MinInterval = 0.0; + double Hr_Time = 0.0; + PointerList::TPointerList* ObjList = nullptr; + /* + TOPTransferFile->FileName = GetOutputDirectory() + "TOP_PriceShape.STO"; + try + { + TOPTransferFile->Open(); + } + catch(Exception* e) + { + { + DoSimpleMsg(String("TOP Transfer File Error: ") + e->Message, 58619); + try + { + TOPTransferFile->Close(); + //OK if Error + } + catch(...) + { + ; + } + return; + } + } + + //Send only fixed interval data + ObjList = new PointerList::TPointerList(10); + NameList = new TStringList(); + cNames = new TStringList(); + + //Make a List of fixed interval data where the interval is greater than 1 minute + if(CompareText(ObjName, "ALL") == 0) + { + Obj = ((TPriceShapeObj*) ElementList.Get_First()); + while(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + Obj = ((TPriceShapeObj*) ElementList.Get_Next()); + } + } + else + { + Obj = ((TPriceShapeObj*) Find(ObjName)); + if(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + else + DoSimpleMsg(String("PriceShape.") + ObjName + " is not hourly fixed interval.", 58620); + } + else + { + DoSimpleMsg(String("PriceShape.") + ObjName + " not found.", 58621); + } + } + + //If none found, exit + if(ObjList->get_myNumList() > 0) + + //Find Max number of points + { + int stop = 0; + MaxTime = 0.0; + MinInterval = 1.0; + Obj = ((TPriceShapeObj*) ObjList->Get_First()); + while(Obj != nullptr) + { + MaxTime = Max(MaxTime, Obj->get_FNumPoints() * Obj->Interval); + MinInterval = Min(MinInterval, Obj->Interval); + NameList->Add(Obj->get_Name()); + Obj = ((TPriceShapeObj*) ObjList->Get_Next()); + } + // SetLength(Xarray, maxPts); + MaxPts = (int) Round(MaxTime / MinInterval); + TOPTransferFile->WriteHeader(0.0, MaxTime, MinInterval, ObjList->get_myNumList(), 0, 16, "DSS (TM), Electrotek Concepts (R)"); + TOPTransferFile->WriteNames(NameList, cNames); + Hr_Time = 0.0; + Vbuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1 - 1]) * ObjList->get_myNumList())); + CBuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1 - 1]) * 1)); // just a dummy -- Cbuf is ignored here + for(stop = MaxPts, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = ObjList->get_myNumList(), j = 1; j <= stop1; j++) + { + Obj = ((TPriceShapeObj*) ObjList->Get(j)); + (*Vbuf)[j - 1] = Obj->GetPrice(Hr_Time); + } + TOPTransferFile->WriteData(Hr_Time, Vbuf, CBuf); + Hr_Time = Hr_Time + MinInterval; + } + TOPTransferFile->Close(); + TOPTransferFile->SendToTop(); + Vbuf = (pDoubleArray) realloc(Vbuf, 0); + CBuf = (pDoubleArray) realloc(CBuf, 0); + } + delete ObjList; + delete NameList; + delete cNames; + */ +} + +void TPriceShapeObj::SaveToDblFile() +{ + System::TTypedFile f; + int i = 0; + String FName; + if(PriceValues != NULL) + { + try + { + int stop = 0; + FName = get_Name() + ".dbl"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + System::Write(f, &PriceValues[i - 1]); + } + GlobalResult = String("Price=[dblfile=") + FName + "]"; +// } +// __finally +// { + CloseFile(f); + } + catch (...) + { + //Does nothing, inserted to match with delphi + } + } + else + DoSimpleMsg(String("PriceShape.") + get_Name() + " Prices not defined.", 58622); +} + +void TPriceShapeObj::SaveToSngFile() +{ + System::TTypedFile f; + int i = 0; + String FName; + float sngPrice = 0.0F; + if (PriceValues != NULL) + { + try + { + int stop = 0; + FName = get_Name() + ".sng"; + AssignFile(f, FName); + Rewrite(f); + IOResultToException(); + for (stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + sngPrice = (float)PriceValues[i - 1]; + System::Write(f, &sngPrice); + } + GlobalResult = String("Price=[sngfile=") + FName + "]"; + // } + // __finally + // { + System::CloseFile(f); + } + catch (...) + { + // Inserted to match with Delphi (try) + } + } + else + DoSimpleMsg(String("PriceShape.") + get_Name() + " Prices not defined.", 58623); +} + +void TPriceShapeObj::Set_Mean(double Value) +{ + FStdDevCalculated = true; + FMean = Value; +} + +void TPriceShapeObj::Set_NumPoints(int Value) +{ + Set_PropertyValue(1,IntToStr(Value)); // Update property list variable + + // Reset array property values to keep them in propoer order in Save + if(ArrayPropertyIndex > 0) + Set_PropertyValue(ArrayPropertyIndex,Get_PropertyValue(ArrayPropertyIndex)); + FNumPoints = Value; // Now assign the value +} + +void TPriceShapeObj::Set_StdDev(double Value) +{ + FStdDevCalculated = true; + FStdDev = Value; +} + +} // namespace PriceShape + + + + + diff --git a/OpenDSSC/General/PriceShape.h b/OpenDSSC/General/PriceShape.h new file mode 100644 index 0000000..26029c6 --- /dev/null +++ b/OpenDSSC/General/PriceShape.h @@ -0,0 +1,144 @@ +#ifndef PriceShapeH +#define PriceShapeH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Arraydef.h" + + +namespace PriceShape +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 2-16-2011 Converted from TempShape. + Price shapes would generally be defined to correspond to loadshapes + +*/ + +/*The PriceShape object is a general DSS object used by all circuits + as a reference for obtaining yearly, daily, and other Price shapes. + + The values are set by the normal New and Edit procedures for any DSS object. + + The values may be retrieved by setting the Code Property in the PriceShape Class. + This sets the active PriceShape object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. Or you + can pick up the ActivePriceShapeObj object and save the direct reference to the object. + + PriceShapes default to fixed interval data (like Loadshapes). If the Interval is specified to be 0.0, + then both time and price data are expected. If the Interval is greater than 0.0, + the user specifies only the prices. The Hour command is ignored and the files are + assumed to contain only the price data. + + The Interval may also be specified in seconds (sinterval) or minutes (minterval). + + The user may place the data in CSV or binary files as well as passing through the + command interface. Obviously, for large amounts of data such as 8760 load curves, the + command interface is cumbersome. CSV files are text separated by commas, one interval to a line. + There are two binary formats permitted: 1) a file of Singles; 2) a file of Doubles. + + For fixed interval data, only the price values are expected. Therefore, the CSV format would + contain only one number per line. The two binary formats are packed. + + For variable interval data, (hour, price) pairs are expected in both formats. + + The Mean and Std Deviation are automatically computed upon demand when new series of points is entered. + + + + */ + +class TPriceShape : public DSSClass::TDSSClass +{ + friend class TPriceShapeObj; +public: + typedef DSSClass::TDSSClass inherited; +private: + String Get_Code(); // Returns active PriceShape String + void Set_Code(const String Value); // sets the active PriceShape + void DoCSVFile(const String FileName); + void DoSngFile(const String FileName); + void DoDblFile(const String FileName); +protected: + void DefineProperties(); + virtual int MakeLike(const String ShapeName); +public: + TPriceShape(); + virtual ~TPriceShape(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void* Find(const String ObjName); // Find an obj of this class by name + void TOPExport(String ObjName); // can export this to top for plotting + + // Set this property to point ActivePriceShapeObj to the right value +}; + +class TPriceShapeObj : public DSSObject::TDSSObject +{ + friend class TPriceShape; +public: + typedef DSSObject::TDSSObject inherited; +private: + int LastValueAccessed; + int FNumPoints; // Number of points in curve + int ArrayPropertyIndex; + bool FStdDevCalculated; + double FMean; + double FStdDev; + double Get_Interval(); + void Set_NumPoints(int Value); + void SaveToDblFile(); + void SaveToSngFile(); + void CalcMeanandStdDev(); + double Get_Mean(); + double Get_StdDev(); + void Set_Mean(double Value); + void Set_StdDev(double Value); // Normalize the curve presently in memory +public: + double Interval; //=0.0 then random interval (hr) + // Time values (hr) if Interval > 0.0 Else nil + Arraydef::pDoubleArray Hours; + Arraydef::pDoubleArray PriceValues; // Prices + TPriceShapeObj(DSSClass::TDSSClass* ParClass, const String PriceShapeName); + virtual ~TPriceShapeObj(); + double GetPrice(double hr); // Get Prices at specified time, hr + double Price(int i); // get Prices by index + double Hour(int i); // get hour corresponding to point index + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + int get_FNumPoints(); + + TPriceShapeObj(DSSClass::TDSSClass* ParClass); + TPriceShapeObj(String ClassName); + TPriceShapeObj(); +}; +extern TPriceShapeObj* ActivePriceShapeObj; + + +} // namespace PriceShape + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PriceShape; +#endif + +#endif // PriceShapeH + + + + + diff --git a/OpenDSSC/General/Spectrum.cpp b/OpenDSSC/General/Spectrum.cpp new file mode 100644 index 0000000..ce0d5d9 --- /dev/null +++ b/OpenDSSC/General/Spectrum.cpp @@ -0,0 +1,591 @@ + +#pragma hdrstop + +#include "Spectrum.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; + +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; +using namespace Utilities; + +namespace Spectrum +{ + +TSpectrumObj::TSpectrumObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TSpectrumObj::TSpectrumObj(String ClassName) : inherited(ClassName) {} +TSpectrumObj::TSpectrumObj() {} + + +TSpectrumObj* ActiveSpectrumObj = nullptr; +const int NumPropsThisClass = 5; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TSpectrum::TSpectrum() +{ + ; + Class_Name = "Spectrum"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TSpectrum::~TSpectrum() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TSpectrum::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + PropertyName[0] = "NumHarm"; + PropertyName[1] = "harmonic"; + PropertyName[2] = "%mag"; + PropertyName[3] = "angle"; + PropertyName[4] = "CSVFile"; + PropertyHelp[0] = "Number of frequencies in this spectrum. (See CSVFile)"; + PropertyHelp[1] = String("Array of harmonic values. You can also use the syntax") + CRLF + + "harmonic = (file=filename) !for text file one value per line" + + CRLF + + "harmonic = (dblfile=filename) !for packed file of doubles" + + CRLF + + "harmonic = (sngfile=filename) !for packed file of singles "; + PropertyHelp[2] = String("Array of magnitude values, assumed to be in PERCENT. You can also use the syntax") + CRLF + + "%mag = (file=filename) !for text file one value per line" + + CRLF + + "%mag = (dblfile=filename) !for packed file of doubles" + + CRLF + + "%mag = (sngfile=filename) !for packed file of singles "; + PropertyHelp[3] = String("Array of phase angle values, degrees.You can also use the syntax") + CRLF + + "angle = (file=filename) !for text file one value per line" + + CRLF + + "angle = (dblfile=filename) !for packed file of doubles" + + CRLF + + "angle = (sngfile=filename) !for packed file of singles "; + PropertyHelp[4] = "File of spectrum points with (harmonic, magnitude-percent, angle-degrees) values, one set of 3 per line, in CSV format. " + "If fewer than NUMHARM frequencies found in the file, NUMHARM is set to the smaller value."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TSpectrum::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TSpectrumObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TSpectrum::Edit(int ActorID) +{ + int result = 0; + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int iZeroPoint = 0; // for error trapping + result = 0; + // continue parsing with contents of Parser + ActiveSpectrumObj = ((TSpectrumObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveSpectrumObj; + /*# with ActiveSpectrumObj do */ + { + auto with0 = ActiveSpectrumObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + with0->get_Name() + + "\"", 650); + break; + case 1: + { + int stop = 0; + with0->NumHarm = Parser[ActorID]->MakeInteger_(); + with0->AngleArray.resize(with0->NumHarm); // Make a dummy Angle array + for(stop = with0->NumHarm, i = 1; i <= stop; i++) + { + with0->AngleArray[i - 1] = 0.0; + } + } + break; + case 2: + { + with0->HarmArray.resize(with0->NumHarm); + with0->NumHarm = InterpretDblArray(Param, with0->NumHarm, &(with0->HarmArray[0])); + } + break; + case 3: + { + int stop = 0; + with0->puMagArray.resize(with0->NumHarm); + with0->NumHarm = InterpretDblArray(Param, with0->NumHarm, &(with0->puMagArray[0])); + for(stop = with0->NumHarm, i = 1; i <= stop; i++) + { + with0->puMagArray[i - 1] = with0->puMagArray[i - 1] * 0.01; + } // convert to per unit + } + break; + case 4: + { + with0->AngleArray.resize(with0->NumHarm); + with0->NumHarm = InterpretDblArray(Param, with0->NumHarm, &(with0->AngleArray[0])); + } + break; + case 5: + DoCSVFile(Param); + break; + // Inherited parameters + default: + ClassEdit(ActiveSpectrumObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*WHILE*/ + if(!with0->HarmArray.empty()) // Check this after HarmArray is allocated 2/20/2018 + { + if(with0->HarmArrayHasaZero(iZeroPoint)) + DoSimpleMsg(Format("Error: Zero frequency detected in Spectrum.%s, point %d. Not allowed",with0->get_Name().c_str(), iZeroPoint), 65001); + else + { + if((!with0->HarmArray.empty()) && (!with0->puMagArray.empty()) && (!with0->AngleArray.empty())) + with0->SetMultArray(); + } + } + } /*WITH*/ + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TSpectrum::MakeLike(const String LineName) +{ + int result = 0; + TSpectrumObj* OtherSpectrum = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherSpectrum = ((TSpectrumObj*) Find(LineName)); + if(OtherSpectrum != nullptr) + /*# with ActiveSpectrumObj do */ + { + auto with0 = ActiveSpectrumObj; + int stop = 0; + with0->NumHarm = OtherSpectrum->NumHarm; + with0->HarmArray.resize(with0->NumHarm); + with0->puMagArray.resize(with0->NumHarm); + with0->AngleArray.resize(with0->NumHarm); + for(stop = with0->NumHarm, i = 1; i <= stop; i++) + { + (with0->HarmArray)[i - 1] = (OtherSpectrum->HarmArray)[i - 1]; + (with0->puMagArray)[i - 1] = (OtherSpectrum->puMagArray)[i - 1]; + (with0->AngleArray)[i - 1] = (OtherSpectrum->AngleArray)[i - 1]; + } + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherSpectrum->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Spectrum MakeLike: \"") + LineName + + "\" Not Found.", 651); + return result; +} // Returns active line code string + +String TSpectrum::Get_Code() +{ + String result; + TSpectrumObj* SpectrumObj = nullptr; + SpectrumObj = ((TSpectrumObj*) ElementList.Get_Active()); + result = SpectrumObj->get_Name(); + return result; +} // sets the active Spectrum + +void TSpectrum::Set_Code(const String Value) +{ + TSpectrumObj* SpectrumObj = nullptr; + ActiveSpectrumObj = nullptr; + SpectrumObj = ((TSpectrumObj*) ElementList.Get_First()); + while(SpectrumObj != nullptr) + { + if(CompareText(SpectrumObj->get_Name(), Value) == 0) + { + ActiveSpectrumObj = SpectrumObj; + return; + } + SpectrumObj = ((TSpectrumObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("Spectrum: \"") + Value + "\" not Found.", 652); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TSpectrum Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TSpectrumObj::TSpectrumObj(TDSSClass* ParClass, const String SpectrumName) + : inherited(ParClass), + NumHarm(0) +{ + Set_Name(LowerCase(SpectrumName)); + DSSObjType = ParClass->DSSClassType; + NumHarm = 0; + puMagArray.clear(); + AngleArray.clear(); + MultArray.clear(); + HarmArray.clear(); + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TSpectrumObj::~TSpectrumObj() +{ + puMagArray.clear(); + AngleArray.clear(); + MultArray.clear(); + HarmArray.clear(); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TSpectrum::DoCSVFile(const String FileName) +{ + String dummy; + System::TTextRec f = {}; + int i = 0; + String s; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening CSV File: \"") + FileName, 653); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveSpectrumObj do */ + { + auto with0 = ActiveSpectrumObj; + with0->HarmArray.resize(with0->NumHarm); + with0->puMagArray.resize(with0->NumHarm); + with0->AngleArray.resize(with0->NumHarm); + i = 0; + while((!Eof(f)) && (i < with0->NumHarm)) + { + ++i; + System::ReadLn(f, s); // Use Auxparser, which allows for formats + /*# with AuxParser[ActiveActor] do */ + { + + AuxParser[ActiveActor]->SetCmdString(s); + dummy = AuxParser[ActiveActor]->GetNextParam(); + (with0->HarmArray)[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); + (with0->puMagArray)[i - 1] = AuxParser[ActiveActor]->MakeDouble_() * 0.01; + dummy = AuxParser[ActiveActor]->GetNextParam(); + (with0->AngleArray)[i - 1] = AuxParser[ActiveActor]->MakeDouble_(); + } + } + System::CloseFile(f); + if(i != with0->NumHarm) + with0->NumHarm = i; // reset number of points + } + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 654); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } +} + +void TSpectrumObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + case 2: + { + int stop1 = 0; + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "=("); + } + for(stop1 = NumHarm, j = 1; j <= stop1; j++) + { + System::Write(f, Format("%-g, ",HarmArray[j - 1])); + } + System::WriteLn(f, ")"); + } + break; + case 3: + { + int stop1 = 0; + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "=("); + } + for(stop1 = NumHarm, j = 1; j <= stop1; j++) + { + System::Write(f, Format("%-g, ",puMagArray[j - 1] * 100.0)); + } + System::WriteLn(f, ")"); + } + break; + case 4: + { + int stop1 = 0; + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "=("); + } + for(stop1 = NumHarm, j = 1; j <= stop1; j++) + { + System::Write(f, Format("%-g, ",AngleArray[j - 1])); + } + System::WriteLn(f, ")"); + } + break; + default: + { + System::Write(f, "~ "); + System::Write(f, with0->PropertyName[i - 1]); + System::Write(f, "="); + System::WriteLn(f, Get_PropertyValue(i)); + } + break; + } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f, "Multiplier Array:"); + WriteLn(f, "Harmonic, Mult.re, Mult.im, Mag, Angle"); + for(stop = NumHarm, i = 1; i <= stop; i++) + { + { Write(f, Format("%-g",HarmArray[i - 1])); Write(f, ", "); } + Write(f, Format("%-g, %-g, ",MultArray[i - 1].re, MultArray[i - 1].im)); + Write(f, Format("%-g, %-g",cabs(MultArray[i - 1]), cdang(MultArray[i - 1]))); + WriteLn(f); + } + } +} + +complex TSpectrumObj::GetMult(double h) +{ + complex result = {}; + int i = 0; + + /*Search List for harmonic (nearest 0.01 harmonic) and return multiplier*/ + int stop = 0; + for(stop = NumHarm, i = 1; i <= stop; i++) + { + if(Abs((h - HarmArray[i - 1])) < 0.01) + { + result = MultArray[i - 1]; + return result; + } /*IF*/ + } /*For*/ + + /*None Found, return zero*/ + result = CZero; + return result; +} + +String TSpectrumObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + switch(Index) + { + case 2: case 3: case 4: + result = "("; + break; + default: + result = ""; + break; + } + switch(Index) + { + int stop; + + case 1: + result = IntToStr(NumHarm); + break; + case 2: + for(stop = NumHarm, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ",HarmArray[i - 1]); + } + break; + case 3: + for(stop = NumHarm, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ",puMagArray[i - 1] * 100.0); + } + break; + case 4: + for(stop = NumHarm, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ",AngleArray[i - 1]); + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 2: case 3: case 4: + result = result + ")"; + break; + default: + ; + break; + } + return result; +} + +bool TSpectrumObj::HarmArrayHasaZero(int& zeropoint) +{ + bool result = false; + int i = 0; + int stop = 0; + result = false; + zeropoint = 0; + for(stop = NumHarm, i = 1; i <= stop; i++) + { + if(HarmArray[i - 1] == 0.0) + { + result = true; + zeropoint = i; + break; + } + } + return result; +} + +void TSpectrumObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); + Set_PropertyValue(2,""); + Set_PropertyValue(3,""); + Set_PropertyValue(4,""); + Set_PropertyValue(5,""); + inherited::InitPropertyValues(NumPropsThisClass); +} + +/*Rotate all phase angles so that the fundamental is at zero*/ + +void TSpectrumObj::SetMultArray() +{ + int i = 0; + double FundAngle = 0.0; + try + { + int stop = 0; + FundAngle = 0.0; + for(stop = NumHarm, i = 1; i <= stop; i++) + { + if(Round(HarmArray[i - 1]) == 1) + { + FundAngle = AngleArray[i - 1]; + break; + } + } + MultArray.resize(NumHarm); + for(stop = NumHarm, i = 1; i <= stop; i++) + { + MultArray[i - 1] = pdegtocomplex(puMagArray[i - 1], (AngleArray[i - 1] - HarmArray[i - 1] * FundAngle)); + } + } + catch(...) + { + DoSimpleMsg(String("Exception while computing Spectrum.") + get_Name() + + ". Check Definition. Aborting", 655); + if(In_Redirect) + Redirect_Abort = true; + } +} + + + + +} // namespace Spectrum + + + + + diff --git a/OpenDSSC/General/Spectrum.h b/OpenDSSC/General/Spectrum.h new file mode 100644 index 0000000..071972b --- /dev/null +++ b/OpenDSSC/General/Spectrum.h @@ -0,0 +1,93 @@ +#ifndef SpectrumH +#define SpectrumH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" + +namespace Spectrum +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Created 10/25/00 + + Harmonic Spectrum specified as Harmonic, pct magnitude and angle + + Spectrum is shifted by the fundamental angle and stored in MultArray + so that the fundamental is at zero degrees phase shift + +*/ + +class TSpectrum : public DSSClass::TDSSClass +{ + friend class TSpectrumObj; +public: + typedef DSSClass::TDSSClass inherited; +private: + String Get_Code(); // Returns active spectrum code String + void Set_Code(const String Value); // sets the active Spectrum + void DoCSVFile(const String FileName); +protected: + void DefineProperties(); + virtual int MakeLike(const String LineName); +public: + TSpectrum(); + virtual ~TSpectrum(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); + + // Set this property to point ActiveSpectrumObj to the right value +}; + +class TSpectrumObj : public DSSObject::TDSSObject +{ + friend class TSpectrum; +public: + typedef DSSObject::TDSSObject inherited; +private: + std::vector puMagArray; + std::vector AngleArray; + std::vector MultArray; + void SetMultArray(); + bool HarmArrayHasaZero(int& zeropoint); +public: + int NumHarm; // Public so solution can get to it. + std::vector HarmArray; + TSpectrumObj(DSSClass::TDSSClass* ParClass, const String SpectrumName); + virtual ~TSpectrumObj(); + Ucomplex::complex GetMult(double h); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TSpectrumObj(DSSClass::TDSSClass* ParClass); + TSpectrumObj(String ClassName); + TSpectrumObj(); +}; +extern TSpectrumObj* ActiveSpectrumObj; + + +} // namespace Spectrum + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Spectrum; +#endif + +#endif // SpectrumH + + + + + diff --git a/OpenDSSC/General/TCC_Curve.cpp b/OpenDSSC/General/TCC_Curve.cpp new file mode 100644 index 0000000..0704e0e --- /dev/null +++ b/OpenDSSC/General/TCC_Curve.cpp @@ -0,0 +1,511 @@ + +#pragma hdrstop + +#include "TCC_Curve.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace TCC_Curve +{ + +TTCC_CurveObj::TTCC_CurveObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TTCC_CurveObj::TTCC_CurveObj(String ClassName) : inherited(ClassName) {} +TTCC_CurveObj::TTCC_CurveObj() {} + + +TTCC_CurveObj* ActiveTCC_CurveObj = nullptr; +const int NumPropsThisClass = 3; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TTCC_Curve::TTCC_Curve() +{ + ; + Class_Name = "TCC_Curve"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTCC_Curve::~TTCC_Curve() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTCC_Curve::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + (PropertyName)[0] = "npts"; // Number of points to expect + (PropertyName)[1] = "C_array"; // vector of multiplier values + (PropertyName)[2] = "T_array"; // vextor of time values , Sec + + // define Property help values + (PropertyHelp)[0] = "Number of points to expect in time-current arrays."; // Number of points to expect + (PropertyHelp)[1] = "Array of current (or voltage) values corresponding to time values (see help on T_Array)."; // vector of multiplier values + (PropertyHelp)[2] = String("Array of time values in sec. Typical array syntax: ") + CRLF + + "t_array = (1, 2, 3, 4, ...)" + + CRLF + + CRLF + + "Can also substitute a file designation: " + + CRLF + + "t_array = (file=filename)" + + CRLF + + CRLF + + "The specified file has one value per line."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTCC_Curve::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TTCC_CurveObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void CalcLogPoints(const pDoubleArray X, pDoubleArray LogX, int n) +{ + int i = 0; + int stop = 0; + for(stop = n, i = 1; i <= stop; i++) + { + if((X)[i - 1] > 0.0) + (LogX)[i - 1] = log((X)[i - 1]); + else + (LogX)[i - 1] = log(0.001L); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTCC_Curve::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveTCC_CurveObj = ((TTCC_CurveObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveTCC_CurveObj; + /*# with ActiveTCC_CurveObj do */ + { + auto with0 = ActiveTCC_CurveObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 420); + break; + case 1: + with0->npts = Parser[ActorID]->MakeInteger_(); + break; + case 2: + with0->npts = InterpretDblArray(Param, with0->npts, with0->c_values); + break; // Parser.ParseAsVector(Npts, Multipliers); + case 3: + with0->npts = InterpretDblArray(Param, with0->npts, with0->t_values); + break; // Parser.ParseAsVector(Npts, Hours); + + // Inherited parameters + default: + ClassEdit(ActiveTCC_CurveObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: // Reallocate arrays to corresponde to Npts + { + with0->c_values = (pDoubleArray) realloc(with0->c_values, sizeof(double) * with0->npts); + with0->LogC = (pDoubleArray) realloc(with0->LogC, sizeof(double) * with0->npts); + with0->t_values = (pDoubleArray) realloc(with0->t_values, sizeof(double) * with0->npts); + with0->Logt = (pDoubleArray) realloc(with0->Logt, sizeof(double) * with0->npts); + } + break; + case 2: + CalcLogPoints(with0->c_values, with0->LogC, with0->npts); + break; + case 3: + CalcLogPoints(with0->t_values, with0->Logt, with0->npts); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*WHILE*/ + } /*WITH*/ + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTCC_Curve::MakeLike(const String ShapeName) +{ + int result = 0; + TTCC_CurveObj* OtherTCC_Curve = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherTCC_Curve = ((TTCC_CurveObj*) Find(ShapeName)); + if(OtherTCC_Curve != nullptr) + /*# with ActiveTCC_CurveObj do */ + { + auto with0 = ActiveTCC_CurveObj; + int stop = 0; + with0->npts = OtherTCC_Curve->npts; + with0->c_values = new double[with0->npts]; + with0->LogC = new double[with0->npts]; + with0->t_values = new double[with0->npts]; + with0->Logt = new double[with0->npts]; + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->c_values)[i - 1] = (OtherTCC_Curve->c_values)[i - 1]; + } + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->t_values)[i - 1] = (OtherTCC_Curve->t_values)[i - 1]; + } + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->LogC)[i - 1] = (OtherTCC_Curve->LogC)[i - 1]; + } + for(stop = with0->npts, i = 1; i <= stop; i++) + { + (with0->Logt)[i - 1] = (OtherTCC_Curve->Logt)[i - 1]; + } + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherTCC_Curve->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in TCC_Curve MakeLike: \"") + ShapeName + + "\" Not Found.", 421); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTCC_Curve::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TTCC_Curve.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + +String TTCC_Curve::Get_Code() +{ + String result; + TTCC_CurveObj* TCC_CurveObj = nullptr; + TCC_CurveObj = ((TTCC_CurveObj*) ElementList.Get_Active()); + result = TCC_CurveObj->get_Name(); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active TCC_Curve + +void TTCC_Curve::Set_Code(const String Value) +{ + TTCC_CurveObj* TCC_CurveObj = nullptr; + ActiveTCC_CurveObj = nullptr; + TCC_CurveObj = ((TTCC_CurveObj*) ElementList.Get_First()); + while(TCC_CurveObj != nullptr) + { + if(CompareText(TCC_CurveObj->get_Name(), Value) == 0) + { + ActiveTCC_CurveObj = TCC_CurveObj; + return; + } + TCC_CurveObj = ((TTCC_CurveObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("TCC_Curve: \"") + Value + "\" not Found.", 422); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TTCC_Curve Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTCC_CurveObj::TTCC_CurveObj(TDSSClass* ParClass, const String TCC_CurveName) + : inherited(ParClass), + LastValueAccessed(1), + npts(0), + Logt(nullptr), + LogC(nullptr), + t_values(nullptr), + c_values(nullptr) +{ + Set_Name(LowerCase(TCC_CurveName)); + DSSObjType = ParClass->DSSClassType; + c_values = nullptr; + t_values = nullptr; + LogC = nullptr; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTCC_CurveObj::~TTCC_CurveObj() +{ + free(t_values); + free(c_values); + free(LogC); + free(Logt); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function returns the operation time for the value given. +// If the value is less than the first entry, return = -1 for No operation. +// Log-Log interpolation is used. + +double TTCC_CurveObj::GetTCCTime(double C_Value) +{ + double result = 0.0; + int i = 0; + double Logtest = 0.0; + result = -1.0; // default return value + + /*If current is less than first point, just leave*/ + if(C_Value < c_values[1 - 1]) + return result; + if(npts > 0) + { + if(npts == 1) // Handle Exceptional cases + result = t_values[1 - 1]; + else + + + /* Start with previous value accessed under the assumption that most + of the time, this function will be called sequentially*/ + { + int stop = 0; + if(c_values[LastValueAccessed - 1] > C_Value) + LastValueAccessed = 1; // Start over from beginning + for(stop = npts, i = LastValueAccessed + 1; i <= stop; i++) + { + if(c_values[i - 1] == C_Value) + { + result = t_values[i - 1]; // direct hit! + LastValueAccessed = i; + return result; + } + else + { + if(c_values[i - 1] > C_Value) // Log-Log interpolation + { + LastValueAccessed = i - 1; + if(C_Value > 0.0) + Logtest = log(C_Value); + else + Logtest = log(0.001L); + result = exp(Logt[LastValueAccessed - 1] + (Logtest - LogC[LastValueAccessed - 1]) / (LogC[i - 1] - LogC[LastValueAccessed - 1]) * (Logt[i - 1] - Logt[LastValueAccessed - 1])); + return result; + } + } + } + + // If we fall through the loop, just use last value + LastValueAccessed = npts - 1; + result = t_values[npts - 1]; + } + } + return result; +} +// Over-voltage, definite time relay + +double TTCC_CurveObj::GetOVTime(double V_Value) +{ + double result = 0.0; + int i = 0; + result = -1.0; // No op return + if(V_Value > c_values[1 - 1]) + { + if(npts == 1) + result = t_values[1 - 1]; + else + { + i = 1; + while(c_values[i - 1] < V_Value) + { + ++i; + if(i > npts) + break; + } + result = t_values[i - 1 - 1]; + } + } + return result; +} + +// Under-voltage, definite time relay + +double TTCC_CurveObj::GetUVTime(double V_Value) +{ + double result = 0.0; + int i = 0; + result = -1.0; // No op return + if(V_Value < c_values[npts - 1]) + { + if(npts == 1) + result = t_values[1 - 1]; + else + { + i = npts; + while(c_values[i - 1] > V_Value) + { + --i; + if(i == 0) + break; + } + result = t_values[i + 1 - 1]; + } + } + return result; +} + +double TTCC_CurveObj::Value(int i) +{ + double result = 0.0; + if((i <= npts) && (i > 0)) + { + result = c_values[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; +} + +double TTCC_CurveObj::Time(int i) +{ + double result = 0.0; + if((i <= npts) && (i > 0)) + { + result = t_values[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; +} + +void TTCC_CurveObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, L'='); System::WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +String TTCC_CurveObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 2: + result = GetDSSArray_Real(npts, c_values); + break; + case 3: + result = GetDSSArray_Real(npts, t_values); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TTCC_CurveObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); // Number of points to expect + Set_PropertyValue(2,""); // vector of multiplier values + Set_PropertyValue(3,""); // vextor of sec values + inherited::InitPropertyValues(NumPropsThisClass); +} + + + + +} // namespace TCC_Curve + + + + + diff --git a/OpenDSSC/General/TCC_Curve.h b/OpenDSSC/General/TCC_Curve.h new file mode 100644 index 0000000..5d71002 --- /dev/null +++ b/OpenDSSC/General/TCC_Curve.h @@ -0,0 +1,95 @@ +#ifndef TCC_CurveH +#define TCC_CurveH + +#include "System.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Arraydef.h" + + +namespace TCC_Curve +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Created 8-25-00 */ + +/* + Nominally, a time-current curve, but also used for volt-time curves. + + Collections of time points. Return values can be interpolated either + Log-Log as traditional TCC or as over- or under-voltage definite time. +*/ + +class TTCC_Curve : public DSSClass::TDSSClass +{ + friend class TTCC_CurveObj; +public: + typedef DSSClass::TDSSClass inherited; +//private: + String Get_Code(); // Returns active TCC_Curve String + void Set_Code(const String Value); // sets the active TCC_Curve +protected: + void DefineProperties(); + virtual int MakeLike(const String ShapeName); +public: + TTCC_Curve(); + virtual ~TTCC_Curve(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TTCC_CurveObj : public DSSObject::TDSSObject +{ + friend class TTCC_Curve; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int LastValueAccessed; + int npts; // Number of points in curve + // Logarithms of t_values and c_values + // Time values (hr) if Interval > 0.0 Else nil + Arraydef::pDoubleArray Logt; + Arraydef::pDoubleArray LogC; + Arraydef::pDoubleArray t_values; + Arraydef::pDoubleArray c_values; +public: + TTCC_CurveObj(DSSClass::TDSSClass* ParClass, const String TCC_CurveName); + virtual ~TTCC_CurveObj(); + double GetTCCTime(double C_Value); // Return operating time for a particular time value + double GetUVTime(double V_Value); // Return operating time for undervoltage relay + double GetOVTime(double V_Value); // Return operating time for overvoltage relay + double Value(int i); // get C_Value by index + double Time(int i); // get time value (sec) corresponding to point index + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TTCC_CurveObj(DSSClass::TDSSClass* ParClass); + TTCC_CurveObj(String ClassName); + TTCC_CurveObj(); +}; +extern TTCC_CurveObj* ActiveTCC_CurveObj; + + +} // namespace TCC_Curve + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace TCC_Curve; +#endif + +#endif // TCC_CurveH + + + + + diff --git a/OpenDSSC/General/TSData.cpp b/OpenDSSC/General/TSData.cpp new file mode 100644 index 0000000..5cf2fd6 --- /dev/null +++ b/OpenDSSC/General/TSData.cpp @@ -0,0 +1,320 @@ + +#pragma hdrstop + +#include "TSData.h" +#include "DSSGlobals.h" + +using namespace std; + + +namespace TSData +{ + +TTSDataObj::TTSDataObj(TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TTSDataObj::TTSDataObj(String ClassName) : inherited(ClassName) {} +TTSDataObj::TTSDataObj() {} + + +const int NumPropsThisClass = 3; // Creates superstructure for all Line objects + +TTSData::TTSData() +{ + ; + Class_Name = "TSData"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + + + +TTSData::~TTSData() +{ + // inherited::Destroy(); +} + + +void TTSData::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + (PropertyName)[1 - 1] = "DiaShield"; + (PropertyName)[2 - 1] = "TapeLayer"; + (PropertyName)[3 - 1] = "TapeLap"; + (PropertyHelp)[1 - 1] = "Diameter over tape shield; same units as radius; no default."; + (PropertyHelp)[2 - 1] = "Tape shield thickness; same units as radius; no default."; + (PropertyHelp)[3 - 1] = "Tape Lap in percent; default 20.0"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +int TTSData::NewObject(const String ObjName) +{ + int result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TTSDataObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +int TTSData::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveConductorDataObj = (TConductorDataObj*) ElementList.Get_Active(); + ActiveDSSObject[ActorID] = ActiveConductorDataObj; + /*# with TTSDataObj(ActiveConductorDataObj) do */ + { + auto with0 = ((TTSDataObj*) ActiveConductorDataObj); + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 101); + break; + case 1: + with0->FDiaShield = Parser[ActorID]->MakeDouble_(); + break; + case 2: + with0->FTapeLayer = Parser[ActorID]->MakeDouble_(); + break; + case 3: + with0->FTapeLap = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + ClassEdit(ActiveConductorDataObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Check for critical errors*/ + switch(ParamPointer) + { + case 1: + if(with0->FDiaShield <= 0.0) + DoSimpleMsg(String("Error: Diameter over shield must be positive for TapeShieldData ") + with0->get_Name(), 999); + break; + case 2: + if(with0->FTapeLayer <= 0.0) + DoSimpleMsg(String("Error: Tape shield thickness must be positive for TapeShieldData ") + with0->get_Name(), 999); + break; + case 3: + if((with0->FTapeLap < 0.0) || (with0->FTapeLap > 100.0)) + DoSimpleMsg(String("Error: Tap lap must range from 0 to 100 for TapeShieldData ") + with0->get_Name(), 999); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; +} + +int TTSData::MakeLike(const String TSName) +{ + int result = 0; + TTSDataObj* OtherData = nullptr; + int i = 0; + result = 0; + OtherData = ((TTSDataObj*) Find(TSName)); + if(OtherData != nullptr) + /*# with TTSDataObj(ActiveConductorDataObj) do */ + { + auto with0 = ((TTSDataObj*) ActiveConductorDataObj); + int stop = 0; + with0->FDiaShield = OtherData->FDiaShield; + with0->FTapeLayer = OtherData->FTapeLayer; + with0->FTapeLap = OtherData->FTapeLap; + ClassMakeLike(OtherData); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherData->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in TapeShield MakeLike: \"") + TSName + + "\" Not Found.", 102); + return result; +} + +int TTSData::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TTSData.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TTSData::Get_Code() +{ + String result; + result = ((TTSDataObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active TSData + +void TTSData::Set_Code(const String Value) +{ + TTSDataObj* TSDataObj = nullptr; + ActiveConductorDataObj = nullptr; + TSDataObj = (TTSDataObj*) ElementList.Get_First(); + while(TSDataObj != nullptr) + { + if(CompareText(TSDataObj->get_Name(), Value) == 0) + { + ActiveConductorDataObj = TSDataObj; + return; + } + TSDataObj = (TTSDataObj*) ElementList.Get_Next(); + } + DoSimpleMsg(String("TSData: \"") + Value + "\" not Found.", 103); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TTSData Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTSDataObj::TTSDataObj(TDSSClass* ParClass, const String TSDataName) + : inherited(ParClass, TSDataName), + FDiaShield(-1.0), + FTapeLayer(-1.0), + FTapeLap(20.0) +{ + Set_Name(LowerCase(TSDataName)); + DSSObjType = ParClass->DSSClassType; + InitPropertyValues(0); +} + +TTSDataObj::~TTSDataObj() +{ + // inherited::Destroy(); +} + +//--------------------------------------------------------------------------------- + +double TTSDataObj::get_FDiaShield() +{ + return FDiaShield; +} + +//--------------------------------------------------------------------------------- + +double TTSDataObj::get_FTapeLayer() +{ + return FTapeLayer; +} + +//--------------------------------------------------------------------------------- + +double TTSDataObj::get_FTapeLap() +{ + return FTapeLap; +} + +//--------------------------------------------------------------------------------- + + +void TTSDataObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = NumPropsThisClass, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); } + switch(i) + { + case 1: + WriteLn(f, Format("%.6g",FDiaShield)); + break; + case 2: + WriteLn(f, Format("%.6g",FTapeLayer)); + break; + case 3: + WriteLn(f, Format("%.2g",FTapeLap)); + break; + default: + ; + break; + } + } + } +} + +String TTSDataObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 1: + result = Format("%.6g", FDiaShield); + break; + case 2: + result = Format("%.6g", FTapeLayer); + break; + case 3: + result = Format("%.2g", FTapeLap); + break; + default: + result = inherited::GetPropertyValue(Index - NumPropsThisClass); + break; + } + return result; +} + +int TTSDataObj::GetNumProperties(int ArrayOffset) +{ + return inherited::GetNumProperties(NumPropsThisClass + ArrayOffset); +} + +void TTSDataObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"-1"); + Set_PropertyValue(2,"-1"); + Set_PropertyValue(3,"20.0"); + inherited::InitPropertyValues(ArrayOffset + NumPropsThisClass); +} + + + + +} // namespace TSData + + + + + diff --git a/OpenDSSC/General/TSData.h b/OpenDSSC/General/TSData.h new file mode 100644 index 0000000..ef10057 --- /dev/null +++ b/OpenDSSC/General/TSData.h @@ -0,0 +1,91 @@ +#ifndef TSDataH +#define TSDataH + +#include "System.h" +//#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "CableData.h" +#include "ConductorData.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LineUnits.h" +#include "d2c_structures.h" + + +namespace TSData +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TTSData : public TCableData +{ + friend class TTSDataObj; +public: + typedef CableData::TCableData inherited; +//private: + String Get_Code(); + void Set_Code(const String Value); +protected: + void DefineProperties(); + virtual int MakeLike(const String TSName); +public: + TTSData(); + virtual ~TTSData(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + + // Set this property to point ActiveTSDataObj to the right value +}; + +class TTSDataObj : public CableData::TCableDataObj +{ + friend class TTSData; +public: + typedef CableData::TCableDataObj inherited; +//private: + double FDiaShield; + double FTapeLayer; + double FTapeLap; +public: + + double get_FDiaShield(); + double get_FTapeLayer(); + double get_FTapeLap(); + + TTSDataObj(DSSClass::TDSSClass* ParClass, const String TSDataName); + virtual ~TTSDataObj(); + + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int GetNumProperties(int ArrayOffset); + TTSDataObj(DSSClass::TDSSClass* ParClass); + TTSDataObj(String ClassName); + TTSDataObj(); +}; + + +} // namespace TSData + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace TSData; +#endif + +#endif // TSDataH + + + + + diff --git a/OpenDSSC/General/TSLineConstants.cpp b/OpenDSSC/General/TSLineConstants.cpp new file mode 100644 index 0000000..21516c2 --- /dev/null +++ b/OpenDSSC/General/TSLineConstants.cpp @@ -0,0 +1,226 @@ + +#pragma hdrstop + +#include "TSLineConstants.h" + +#include "DSSGlobals.h" + + +using namespace std; + + +namespace TSLineConstants +{ + +TTSLineConstants::TTSLineConstants() {} + + +const double RhoTS = 2.3718e-8; // for copper tape shield + +double TTSLineConstants::Get_DiaShield(int i, int Units) +{ + double result = 0.0; + result = FDiaShield[i - 1] * From_Meters(Units); + return result; +} + +double TTSLineConstants::Get_TapeLayer(int i, int Units) +{ + double result = 0.0; + result = FTapeLayer[i - 1] * From_Meters(Units); + return result; +} + +double TTSLineConstants::Get_TapeLap(int i) +{ + double result = 0.0; + result = FTapeLap[i - 1]; + return result; +} + +void TTSLineConstants::Set_DiaShield(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FDiaShield[i - 1] = Value * To_Meters(Units); +} + +void TTSLineConstants::Set_TapeLayer(int i, int Units, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FTapeLayer[i - 1] = Value * To_Meters(Units); +} + +void TTSLineConstants::Set_TapeLap(int i, double Value) +{ + if((i > 0) && (i <= FNumConds)) + FTapeLap[i - 1] = Value; +} +/*Compute base Z and YC matrices in ohms/m for this frequency and earth impedance*/ + +void TTSLineConstants::Calc(double f) +{ + complex Zi = {}; + complex Zspacing = {}; + bool PowerFreq = false; + complex LFactor = {}; + int i = 0; + int j = 0; + double Dij = 0.0; + double Yfactor = 0.0; + int ReducedSize = 0; + int n = 0; + int idxi = 0; + int idxj = 0; + TcMatrix* Zmat = nullptr; + TcMatrix* Ztemp = nullptr; + double ResTS = 0.0; + double GmrTS = 0.0; + double Denom = 0.0; + double RadIn = 0.0; + double RadOut = 0.0; + int stop = 0; + Set_Frequency(f); // this has side effects + if(FZreduced != NULL) + { + ReducedSize = FZreduced->get_Norder(); + delete FZreduced; + } + else + ReducedSize = 0; + if(FYCreduced != NULL) + delete FYCreduced; + FZreduced = nullptr; + FYCreduced = nullptr; + FZmatrix->Clear(); + FYCmatrix->Clear(); + + // add concentric neutrals to the end of conductor list; they are always reduced + n = FNumConds + FNumPhases; + Zmat = new TcMatrix(n); + + /*For less than 1 kHz use GMR to better match published data*/ + LFactor = cmplx(0.0, Fw * mu0 / TwoPi); + if((f < 1000.0) && (f > 40.0)) + PowerFreq = true; + else + PowerFreq = false; + + // Self Impedances - TS cores and bare neutrals + for(stop = FNumConds, i = 1; i <= stop; i++) + { + Zi = Get_Zint(i); + if(PowerFreq) // for less than 1 kHz, use published GMR + { + Zi.im = 0.0; + Zspacing = cmulreal(LFactor, log(1.0 / FGMR[i - 1])); // use GMR + } + else + { + Zspacing = cmulreal(LFactor, log(1.0 / Fradius[i - 1])); + } + Zmat->SetElement(i, i, cadd(Zi, cadd(Zspacing, Get_Ze(i, i)))); + } + + // TS self impedances + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + ResTS = 0.3183 * RhoTS / (FDiaShield[i - 1] * FTapeLayer[i - 1] * sqrt(50.0 / (100.0 - FTapeLap[i - 1]))); + GmrTS = 0.5 * (FDiaShield[i - 1] - FTapeLayer[i - 1]); // per Kersting, to center of TS + Zspacing = cmulreal(LFactor, log(1.0 / GmrTS)); + Zi = cmplx(ResTS, 0.0); + idxi = i + FNumConds; + Zmat->SetElement(idxi, idxi, cadd(Zi, cadd(Zspacing, Get_Ze(i, i)))); + } + + // Mutual Impedances - between TS cores and bare neutrals + for(stop = FNumConds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Dij = sqrt(pow(FX[i - 1] - FX[j - 1], 2) + pow(FY[i - 1] - FY[j - 1], 2)); + Zmat->SetElemsym(i, j, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + } + + // Mutual Impedances - TS to other TS, cores, and bare neutrals + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + int stop1 = 0; + idxi = i + FNumConds; + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { // TS to other TS + idxj = j + FNumConds; + Dij = sqrt(pow(FX[i - 1] - FX[j - 1], 2) + pow(FY[i - 1] - FY[j - 1], 2)); + Zmat->SetElemsym(idxi, idxj, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + for(stop1 = FNumConds, j = 1; j <= stop1; j++) + { // CN to cores and bare neutrals + idxj = j; + GmrTS = 0.5 * (FDiaShield[i - 1] - FTapeLayer[i - 1]); // per Kersting, to center of TS + if(i == j) // TS to its own phase core + { + Dij = GmrTS; + } + else + // TS to another phase or bare neutral + { + Dij = sqrt(pow(FX[i - 1] - FX[j - 1], 2) + pow(FY[i - 1] - FY[j - 1], 2)); + } + Zmat->SetElemsym(idxi, idxj, cadd(cmulreal(LFactor, log(1.0 / Dij)), Get_Ze(i, j))); + } + } + + // reduce out the tape shields + while(Zmat->get_Norder() > FNumConds) + { + Ztemp = Zmat->Kron(Zmat->get_Norder()); + delete Zmat; + Zmat = Ztemp; + } + FZmatrix->CopyFrom(Zmat); + delete Zmat; + + // for shielded cables, build the capacitance matrix directly + // assumes the insulation may lie between semicon layers + for(stop = FNumPhases, i = 1; i <= stop; i++) + { + Yfactor = TwoPi * E0 * FEpsR[i - 1] * Fw; // includes frequency so C==>Y + RadOut = 0.5 * FDiaIns[i - 1]; + RadIn = RadOut - FInsLayer[i - 1]; + Denom = log(RadOut / RadIn); + FYCmatrix->SetElement(i, i, cmplx(0.0, Yfactor / Denom)); + } + if(ReducedSize > 0) + Kron(ReducedSize); // Was reduced so reduce again to same size + + /*Else the Zmatrix is OK as last computed*/ + FRhoChanged = false; +} + +TTSLineConstants::TTSLineConstants(int NumConductors) + : inherited(NumConductors) +{ + FDiaShield = new double[FNumConds]; + FTapeLayer = new double[FNumConds]; + FTapeLap = new double[FNumConds]; +} + +TTSLineConstants::~TTSLineConstants() +{ + free(FDiaShield); + free(FTapeLayer); + free(FTapeLap); + // inherited; +} + + + + + +} // namespace TSLineConstants + + + + + diff --git a/OpenDSSC/General/TSLineConstants.h b/OpenDSSC/General/TSLineConstants.h new file mode 100644 index 0000000..43ccb41 --- /dev/null +++ b/OpenDSSC/General/TSLineConstants.h @@ -0,0 +1,60 @@ +#ifndef TSLineConstantsH +#define TSLineConstantsH + +#include "System.h" +#include "Sysutils.h" +#include + +#include "Arraydef.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LineUnits.h" +#include "LineConstants.h" +#include "CableConstants.h" + +namespace TSLineConstants +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TTSLineConstants : public CableConstants::TCableConstants +{ +public: + typedef CableConstants::TCableConstants inherited; +//private: + Arraydef::pDoubleArray FDiaShield; + Arraydef::pDoubleArray FTapeLayer; + Arraydef::pDoubleArray FTapeLap; + double Get_DiaShield(int i, int Units); + double Get_TapeLayer(int i, int Units); + double Get_TapeLap(int i); + void Set_DiaShield(int i, int Units, double Value); + void Set_TapeLayer(int i, int Units, double Value); + void Set_TapeLap(int i, double Value); +protected: +public: + virtual void Calc(double f); + TTSLineConstants(int NumConductors); + virtual ~TTSLineConstants(); + TTSLineConstants(); +}; + + +} // namespace TSLineConstants + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace TSLineConstants; +#endif + +#endif // TSLineConstantsH + + + + + diff --git a/OpenDSSC/General/TempShape.cpp b/OpenDSSC/General/TempShape.cpp new file mode 100644 index 0000000..9cf53f5 --- /dev/null +++ b/OpenDSSC/General/TempShape.cpp @@ -0,0 +1,1006 @@ + +#pragma hdrstop + +#include "TempShape.h" + +#include "DSSGlobals.h" +#include "Utilities.h" +#include "TOPExport.h" + +using namespace std; +using namespace Arraydef; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace PointerList; +using namespace System; +using namespace mathutil; +using namespace Utilities; + +namespace TempShape +{ + +TTShapeObj::TTShapeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TTShapeObj::TTShapeObj(string ClassName) : inherited(ClassName) {} +TTShapeObj::TTShapeObj() {} + + +TTShapeObj* ActiveTShapeObj = nullptr; +const int NumPropsThisClass = 12; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TTShape::TTShape() +{ + ; + Class_Name = "TShape"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTShape::~TTShape() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTShape::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + (PropertyName)[1 - 1] = "npts"; // Number of points to expect + (PropertyName)[2 - 1] = "interval"; // default = 1.0; + (PropertyName)[3 - 1] = "temp"; // vector of temperature values + (PropertyName)[4 - 1] = "hour"; // vector of hour values + (PropertyName)[5 - 1] = "mean"; // set the mean temp (otherwise computed) + (PropertyName)[6 - 1] = "stddev"; // set the std dev of the temp (otherwise computed) + (PropertyName)[7 - 1] = "csvfile"; // Switch input to a csvfile + (PropertyName)[8 - 1] = "sngfile"; // switch input to a binary file of singles + (PropertyName)[9 - 1] = "dblfile"; // switch input to a binary file of singles + (PropertyName)[10 - 1] = "sinterval"; // Interval in seconds + (PropertyName)[11 - 1] = "minterval"; // Interval in minutes + (PropertyName)[12 - 1] = "action"; // Interval in minutes + + // define Property help values + (PropertyHelp)[1 - 1] = "Max number of points to expect in temperature shape vectors. This gets reset to the number of Temperature values " + "found if less than specified."; // Number of points to expect + (PropertyHelp)[2 - 1] = String("Time interval for fixed interval data, hrs. Default = 1. " "If Interval = 0 then time data (in hours) may be at irregular intervals and time value must be specified using either the Hour property or input files. " "Then values are interpolated when Interval=0, but not for fixed interval data. ") + CRLF + + CRLF + + "See also \"sinterval\" and \"minterval\"."; // default = 1.0; + (PropertyHelp)[3 - 1] = String("Array of temperature values. Units should be compatible with the object using the data. " "You can also use the syntax: ") + CRLF + + "Temp = (file=filename) !for text file one value per line" + + CRLF + + "Temp = (dblfile=filename) !for packed file of doubles" + + CRLF + + "Temp = (sngfile=filename) !for packed file of singles " + + CRLF + + CRLF + + "Note: this property will reset Npts if the number of values in the files are fewer."; // vextor of hour values + (PropertyHelp)[4 - 1] = String("Array of hour values. Only necessary to define this property for variable interval data." " If the data are fixed interval, do not use this property. " "You can also use the syntax: ") + CRLF + + "hour = (file=filename) !for text file one value per line" + + CRLF + + "hour = (dblfile=filename) !for packed file of doubles" + + CRLF + + "hour = (sngfile=filename) !for packed file of singles "; // vextor of hour values + (PropertyHelp)[5 - 1] = "Mean of the temperature curve values. This is computed on demand the first time a " + "value is needed. However, you may set it to another value independently. " + "Used for Monte Carlo load simulations."; // set the mean (otherwise computed) + (PropertyHelp)[6 - 1] = String("Standard deviation of the temperatures. This is computed on demand the first time a " "value is needed. However, you may set it to another value independently." "Is overwritten if you subsequently read in a curve") + CRLF + + CRLF + + "Used for Monte Carlo load simulations."; // set the std dev (otherwise computed) + (PropertyHelp)[7 - 1] = "Switch input of temperature curve data to a csv file " + "containing (hour, Temp) points, or simply (Temp) values for fixed time interval data, one per line. " + "NOTE: This action may reset the number of points to a lower value."; // Switch input to a csvfile + (PropertyHelp)[8 - 1] = "Switch input of temperature curve data to a binary file of singles " + "containing (hour, Temp) points, or simply (Temp) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + (PropertyHelp)[9 - 1] = "Switch input of temperature curve data to a binary file of doubles " + "containing (hour, Temp) points, or simply (Temp) values for fixed time interval data, packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + (PropertyHelp)[10 - 1] = "Specify fixed interval in SECONDS. Alternate way to specify Interval property."; + (PropertyHelp)[11 - 1] = "Specify fixed interval in MINUTES. Alternate way to specify Interval property."; + (PropertyHelp)[12 - 1] = "{DblSave | SngSave} After defining temperature curve data... " + "Setting action=DblSave or SngSave will cause the present \"Temp\" values to be written to " + "either a packed file of double or single. The filename is the Tshape name. "; // Action + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTShape::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TTShapeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTShape::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveTShapeObj = ((TTShapeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveTShapeObj; + /*# with ActiveTShapeObj do */ + { + auto with0 = ActiveTShapeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 57610); + break; + case 1: + with0->Set_NumPoints(Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->Interval = Parser[ActorID]->MakeDouble_(); + break; + case 3: + { + with0->TValues = (pDoubleArray) realloc(with0->TValues, sizeof(double) * with0->get_FNumPoints()); + // Allow possible Resetting (to a lower value) of num points when specifying temperatures not Hours + with0->Set_NumPoints(InterpretDblArray(Param, with0->get_FNumPoints(), with0->TValues)); // Parser.ParseAsVector(Npts, Temperatures); + } + break; + case 4: + { + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), with0->Hours)); // Parser.ParseAsVector(Npts, Hours); + } + break; + case 5: + with0->Set_Mean(Parser[ActorID]->MakeDouble_()); + break; + case 6: + with0->Set_StdDev(Parser[ActorID]->MakeDouble_()); + break; + case 7: + DoCSVFile(Param); + break; + case 8: + DoSngFile(Param); + break; + case 9: + DoDblFile(Param); + break; + case 10: + with0->Interval = double(Parser[ActorID]->MakeDouble_()) / 3600.0; + break; // Convert seconds to hr + case 11: + with0->Interval = double(Parser[ActorID]->MakeDouble_()) / 60.0; + break; // Convert minutes to hr + case 12: + switch(LowerCase(Param)[0]) + { + case L'd': + with0->SaveToDblFile(); + break; + case L's': + with0->SaveToSngFile(); + break; + default: + ; + break; + } + break; + // Inherited parameters + default: + ClassEdit(ActiveTShapeObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 3: case 7: case 8: case 9: + { + with0->FStdDevCalculated = false; // now calculated on demand + with0->ArrayPropertyIndex = ParamPointer; + with0->Set_NumPoints(with0->FNumPoints); // Keep Properties in order for save command + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*While*/ + } /*WITH*/ + return result; +} + +void* TTShape::Find(const String ObjName) +{ + void* result = nullptr; + if((ObjName.length() == 0) || (CompareText(ObjName, "none") == 0)) + result = nullptr; + else + result = inherited::Find(ObjName); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTShape::MakeLike(const String ShapeName) +{ + int result = 0; + TTShapeObj* OtherTShape = nullptr; + int i = 0; + result = 0; + /*See if we can find this line code in the present collection*/ + OtherTShape = ((TTShapeObj*) Find(ShapeName)); + if(OtherTShape != nullptr) + /*# with ActiveTShapeObj do */ + { + auto with0 = ActiveTShapeObj; + int stop = 0; + with0->Set_NumPoints(OtherTShape->get_FNumPoints()); + with0->Interval = OtherTShape->Interval; + with0->TValues = (pDoubleArray) realloc(with0->TValues, sizeof(double) * with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->TValues)[i] = (OtherTShape->TValues)[i]; + } + if(with0->Interval > 0.0) + free(with0->Hours); + else + { + int stop = 0; + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + (with0->Hours)[i] = (OtherTShape->Hours)[i]; + } + } + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherTShape->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in TShape MakeLike: \"") + ShapeName + + "\" Not Found.", 57611); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTShape::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TTShape.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + +String TTShape::Get_Code() +{ + String result; + TTShapeObj* TShapeObj = nullptr; + TShapeObj = ((TTShapeObj*) ElementList.Get_Active()); + result = TShapeObj->get_Name(); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active TShape + +void TTShape::Set_Code(const string Value) +{ + TTShapeObj* TShapeObj = nullptr; + ActiveTShapeObj = nullptr; + TShapeObj = ((TTShapeObj*) ElementList.Get_First()); + while(TShapeObj != nullptr) + { + if(CompareText(TShapeObj->get_Name(), Value) == 0) + { + ActiveTShapeObj = TShapeObj; + return; + } + TShapeObj = ((TTShapeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("TShape: \"") + Value + "\" not Found.", 57612); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTShape::DoCSVFile(const string FileName) +{ + String dummy; + System::TTextRec f = {}; + int i = 0; + String s; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 57613); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveTShapeObj do */ + { + auto with0 = ActiveTShapeObj; + with0->TValues = (pDoubleArray) realloc(with0->TValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray)realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + System::ReadLn(f, s); // read entire line and parse with AuxParser + /*AuxParser allows commas or white space*/ + /*# with AuxParser[ActiveActor] do */ + auto with1 = AuxParser[ActiveActor]; + { + + with1->SetCmdString(s); + if(with0->Interval == 0.0) + { + dummy = with1->GetNextParam(); + (with0->Hours)[i] = with1->MakeDouble_(); + } + dummy = with1->GetNextParam(); + (with0->TValues)[i] = with1->MakeDouble_(); + } + } + CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(exception& e) + { + { + DoSimpleMsg(String("Error Processing CSV File: \"") + FileName + + ". " + + (string) e.what(), 57614); + CloseFile(f); System::InOutRes = 0; + return; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTShape::DoSngFile(const string FileName) +{ + System::TTypedFile f; + float hr = 0.0F; + float m = 0.0F; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 57615); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveTShapeObj do */ + { + auto with0 = ActiveTShapeObj; + with0->TValues = (pDoubleArray)realloc(with0->TValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray)realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + { + System::Read(f, &hr); + (with0->Hours)[i] = hr; + } + System::Read(f, &m); + (with0->TValues)[i] = m; + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing TShape File: \"") + FileName, 57616); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTShape::DoDblFile(const string FileName) +{ + System::TTypedFile f; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 57617); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveTShapeObj do */ + { + auto with0 = ActiveTShapeObj; + with0->TValues = (pDoubleArray) realloc(with0->TValues, sizeof(double) * with0->get_FNumPoints()); + if(with0->Interval == 0.0) + with0->Hours = (pDoubleArray) realloc(with0->Hours, sizeof(double) * with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + if(with0->Interval == 0.0) + System::Read(f, &(with0->Hours)[i]); + System::Read(f, &(with0->TValues)[i]); + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing Tshape File: \"") + FileName, 57618); + System::CloseFile(f); System::InOutRes = 0; + return; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TTShape Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTShapeObj::TTShapeObj(TDSSClass* ParClass, const string TShapeName) + : inherited(ParClass), + LastValueAccessed(1), + FNumPoints(0), + ArrayPropertyIndex(0), + FStdDevCalculated(false), + FMean(0.0), + FStdDev(0.0), + Interval(0.0), + Hours(nullptr), + TValues(nullptr) +{ + Set_Name(LowerCase(TShapeName)); + DSSObjType = ParClass->DSSClassType; + Interval = 1.0; // hr + Hours = nullptr; + TValues = nullptr; + FStdDevCalculated = false; // calculate on demand + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTShapeObj::~TTShapeObj() +{ + free(Hours); + if(TValues != NULL) + free(TValues); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This FUNCTION returns the Temperature for the given hour. +// If no points exist in the curve, the result is 0.0 +// If there are fewer points than requested, the curve is simply assumed to repeat +// Thus a daily load curve can suffice for a yearly load curve: You just get the +// same day over and over again. +// The value returned is the nearest to the interval requested. Thus if you request +// hour=12.25 and the interval is 1.0, you will get interval 12. + +double TTShapeObj::GetTemperature(double hr) +{ + double result = 0.0; + int Index = 0; + int i = 0; + result = 0.0; // default return value if no points in curve + if(FNumPoints > 0) + { + if(FNumPoints == 1) // Handle Exceptional cases + { + result = TValues[1 - 1]; + } + else + { + if(Interval > 0.0) + { + Index = (int) Round(hr / Interval); + if(Index > FNumPoints) + Index = Index % FNumPoints; // Wrap around using remainder + if(Index == 0) + Index = FNumPoints; + result = TValues[Index - 1]; + } + else + + // For random interval + + /* Start with previous value accessed under the assumption that most + of the time, this FUNCTION will be called sequentially*/ + + /*Normalize Hr to max hour in curve to get wraparound*/ + { + int stop = 0; + if(hr > Hours[FNumPoints]) + { + hr = hr - Trunc(hr / Hours[FNumPoints]) * Hours[FNumPoints]; + } + if(Hours[LastValueAccessed] > hr) + LastValueAccessed = 1; // Start over from Beginning + for(stop = FNumPoints, i = LastValueAccessed + 1; i <= stop; i++) + { + if(Abs((int) (Hours[i] - hr)) < 0.00001) // If close to an actual point, just use it. + { + result = TValues[i - 1]; + LastValueAccessed = i; + return result; + } + else + { + if(Hours[i] > hr) // Interpolate for temperature + { + LastValueAccessed = i - 1; + result = TValues[LastValueAccessed] + (hr - Hours[LastValueAccessed]) / (Hours[i - 1] - Hours[LastValueAccessed]) * (TValues[i - 1] - TValues[LastValueAccessed]); + return result; + } + } + } + + // If we fall through the loop, just use last value + LastValueAccessed = FNumPoints - 1; + result = TValues[FNumPoints]; + } + } + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTShapeObj::CalcMeanandStdDev() +{ + if(FNumPoints > 0) + { + if(Interval > 0.0) + RCDMeanAndStdDev(TValues, FNumPoints, FMean, FStdDev); + else + CurveMeanAndStdDev(TValues, Hours, FNumPoints, FMean, FStdDev); + } + Set_PropertyValue(5,Format("%.8g", FMean)); + Set_PropertyValue(6,Format("%.8g", FStdDev)); + FStdDevCalculated = true; +} + +double TTShapeObj::Get_Interval() +{ + double result = 0.0; + if(Interval > 0.0) + result = Interval; + else + { + if(LastValueAccessed > 1) + result = Hours[LastValueAccessed] - Hours[LastValueAccessed - 1]; + else + result = 0.0; + } + return result; +} + +double TTShapeObj::Get_Mean() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FMean; + return result; +} + +double TTShapeObj::Get_StdDev() +{ + double result = 0.0; + if(!FStdDevCalculated) + CalcMeanandStdDev(); + result = FStdDev; + return result; +} + +double TTShapeObj::Temperature(int i) +{ + double result = 0.0; + if((i <= FNumPoints) && (i > 0)) + { + result = TValues[i]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; +} + +double TTShapeObj::Hour(int i) +{ + double result = 0.0; + if(Interval == 0) + { + if((i <= FNumPoints) && (i > 0)) + { + result = Hours[i]; + LastValueAccessed = i; + } + else + result = 0.0; + } + else + { + result = Hours[i] * Interval; + LastValueAccessed = i; + } + return result; +} + +void TTShapeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, with0->PropertyName[i - 1]); System::Write(f, "="); System::WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +String TTShapeObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 2: + result = Format("%.8g", Interval); + break; + case 3: + result = GetDSSArray_Real(FNumPoints, TValues); + break; + case 4: + if(Hours != nullptr) + result = GetDSSArray_Real(FNumPoints, Hours); + break; + case 5: + result = Format("%.8g", Get_Mean()); + break; + case 6: + result = Format("%.8g", Get_StdDev()); + break; + case 10: + result = Format("%.8g", Interval * 3600.0); + break; + case 11: + result = Format("%.8g", Interval * 60.0); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TTShapeObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); // Number of points to expect + Set_PropertyValue(2,"1"); // default = 1.0 hr; + Set_PropertyValue(3,""); // vector of multiplier values + Set_PropertyValue(4,""); // vextor of hour values + Set_PropertyValue(5,"0"); // set the mean (otherwise computed) + Set_PropertyValue(6,"0"); // set the std dev (otherwise computed) + Set_PropertyValue(7,""); // Switch input to a csvfile + Set_PropertyValue(8,""); // switch input to a binary file of singles + Set_PropertyValue(9,""); // switch input to a binary file of singles + Set_PropertyValue(10,"3600"); // seconds + Set_PropertyValue(11,"60"); // minutes + Set_PropertyValue(12,""); // action option . + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TTShape::TOPExport(String ObjName) +{ + TStringList* NameList = nullptr; + TStringList* cNames = nullptr; + pDoubleArray Vbuf = nullptr; + pDoubleArray CBuf = nullptr; + TTShapeObj* Obj = nullptr; + int MaxPts = 0; + int i = 0; + int j = 0; + double MaxTime = 0.0; + double MinInterval = 0.0; + double Hr_Time = 0.0; + PointerList::TPointerList* ObjList = nullptr; + /* + // removed for now, no under use currently + TOPTransferFile->FileName = GetOutputDirectory() + "TOP_TShape.STO"; + try + { + TOPTransferFile->Open(); + } + catch(Exception* e) + { + { + DoSimpleMsg(String("TOP Transfer File Error: ") + e->Message, 57619); + try + { + TOPTransferFile->Close(); + //OK if Error + } + catch(...) + { + ; + } + return; + } + } + + //Send only fixed interval data + ObjList = new PointerList::TPointerList(10); + NameList = new TStringList(); + cNames = new TStringList(); + + //Make a List of fixed interval data where the interval is greater than 1 minute + if(CompareText(ObjName, "ALL") == 0) + { + Obj = ((TTShapeObj*) ElementList->Get_First()); + while(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + Obj = ((TTShapeObj*) ElementList->Get_Next()); + } + } + else + { + Obj = ((TTShapeObj*) Find(ObjName)); + if(Obj != nullptr) + { + if(Obj->Interval > (1.0 / 60.0)) + ObjList->Add(Obj); + else + DoSimpleMsg(String("Tshape.") + ObjName + " is not hourly fixed interval.", 57620); + } + else + { + DoSimpleMsg(String("Tshape.") + ObjName + " not found.", 57621); + } + } + + //If none found, exit + if(ObjList->get_myNumList() > 0) + + //Find Max number of points + { + int stop = 0; + MaxTime = 0.0; + MinInterval = 1.0; + Obj = ((TTShapeObj*) ObjList->Get_First()); + while(Obj != nullptr) + { + MaxTime = Max(MaxTime, Obj->Get_FNumPoints() * Obj->Interval); + MinInterval = Min(MinInterval, Obj->Interval); + NameList->Add(Obj->get_Name()); + Obj = ((TTShapeObj*) ObjList->Get_Next()); + } + // SetLength(Xarray, maxPts); + MaxPts = (int) Round(MaxTime / MinInterval); + TOPTransferFile->WriteHeader(0.0, MaxTime, MinInterval, ObjList->get_myNumList(), 0, 16, "DSS (TM), Electrotek Concepts (R)"); + TOPTransferFile->WriteNames(NameList, cNames); + Hr_Time = 0.0; + Vbuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1]) * ObjList->get_myNumList())); + CBuf = ((pDoubleArray) AllocMem(sizeof((*Vbuf)[1]) * 1)); // just a dummy -- Cbuf is ignored here + for(stop = MaxPts, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = ObjList->get_myNumList(), j = 1; j <= stop1; j++) + { + Obj = ((TTShapeObj*) ObjList->Get(j)); + (*Vbuf)[j] = Obj->GetTemperature(Hr_Time); + } + TOPTransferFile->WriteData(Hr_Time, Vbuf, CBuf); + Hr_Time = Hr_Time + MinInterval; + } + TOPTransferFile->Close(); + TOPTransferFile->SendToTop(); + Vbuf = (pDoubleArray) realloc(Vbuf, 0); + CBuf = (pDoubleArray) realloc(CBuf, 0); + } + delete ObjList; + delete NameList; + delete cNames; + */ +} + +//----------------------------------------------------------- + +int TTShapeObj::get_FNumPoints() +{ + return FNumPoints; +} + +//----------------------------------------------------------- + +void TTShapeObj::SaveToDblFile() +{ + System::TTypedFile f; + int i = 0; + String FName; + if(TValues != NULL) + { + try + { + int stop = 0; + FName = get_Name() + ".dbl"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + System::Write(f, &(TValues)[i]); + } + GlobalResult = String("Temp=[dblfile=") + FName + "]"; +// } +// __finally +// { + System::CloseFile(f); + } + catch (exception& E) + { + // added to match with the try declaration in Delhpi + } + } + else + DoSimpleMsg(String("Tshape.") + get_Name() + " Temperatures not defined.", 57622); +} + +void TTShapeObj::SaveToSngFile() +{ + System::TTypedFile f; + int i = 0; + String FName; + float Temp = 0.0F; + if(TValues != NULL) + { + try + { + int stop = 0; + FName = get_Name() + ".sng"; + System::AssignFile(f, FName); + System::Rewrite(f); + IOResultToException(); + for(stop = get_FNumPoints(), i = 1; i <= stop; i++) + { + Temp = (float) TValues[i]; + System::Write(f, &Temp); + } + GlobalResult = String("Temp=[sngfile=") + FName + "]"; +// } +// __finally +// { + System::CloseFile(f); + } + catch (exception& E) + { + // Added to match the Delphi declaration + } + } + else + DoSimpleMsg(String("Tshape.") + get_Name() + " Temperatures not defined.", 57623); +} + +void TTShapeObj::Set_Mean(double Value) +{ + FStdDevCalculated = true; + FMean = Value; +} + +void TTShapeObj::Set_NumPoints(int Value) +{ + Set_PropertyValue(1,IntToStr(Value)); // Update property list variable + + // Reset array property values to keep them in propoer order in Save + if(ArrayPropertyIndex > 0) + Set_PropertyValue(ArrayPropertyIndex,Get_PropertyValue(ArrayPropertyIndex)); + FNumPoints = Value; // Now assign the value +} + +void TTShapeObj::Set_StdDev(double Value) +{ + FStdDevCalculated = true; + FStdDev = Value; +} + + + + +} // namespace TempShape + + + + + diff --git a/OpenDSSC/General/TempShape.h b/OpenDSSC/General/TempShape.h new file mode 100644 index 0000000..2037e4e --- /dev/null +++ b/OpenDSSC/General/TempShape.h @@ -0,0 +1,147 @@ +#ifndef TempShapeH +#define TempShapeH + +#include "System.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Arraydef.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "mathutil.h" +#include +#include "PointerList.h" + + +namespace TempShape +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 2-13-2011 Converted from Loadshape. + Temperature shapes (Tshapes) would generally be defined to correspond to loadshapes + +*/ + +/*The Tshape object is a general DSS object used by all circuits + as a reference for obtaining yearly, daily, and other Temperature shapes. + + The values are set by the normal New and Edit PROCEDUREs for any DSS object. + + The values may be retrieved by setting the Code Property in the Tshape Class. + This sets the active Tshape object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. Or you + can pick up the ActiveTShapeObj object and save the direct reference to the object. + + Tshapes default to fixed interval data (like Loadshapes). If the Interval is specified to be 0.0, + then both time and temperature data are expected. If the Interval is greater than 0.0, + the user specifies only the Temperatures. The Hour command is ignored and the files are + assumed to contain only the temperature data. + + The Interval may also be specified in seconds (sinterval) or minutes (minterval). + + The user may place the data in CSV or binary files as well as passing through the + command interface. Obviously, for large amounts of data such as 8760 load curves, the + command interface is cumbersome. CSV files are text separated by commas, one interval to a line. + There are two binary formats permitted: 1) a file of Singles; 2) a file of Doubles. + + For fixed interval data, only the Temperature values are expected. Therefore, the CSV format would + contain only one number per line. The two binary formats are packed. + + For variable interval data, (hour, Temperature) pairs are expected in both formats. + + The Mean and Std Deviation are automatically computed upon demand when new series of points is entered. + + + + */ + +class TTShape : public DSSClass::TDSSClass +{ + friend class TTShapeObj; +public: + typedef DSSClass::TDSSClass inherited; +//private: + string Get_Code(); // Returns active TShape string + void Set_Code(const string Value); // sets the active TShape + void DoCSVFile(const string FileName); + void DoSngFile(const string FileName); + void DoDblFile(const string FileName); +//protected: + void DefineProperties(); + virtual int MakeLike(const String ShapeName); +public: + TTShape(); + virtual ~TTShape(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void* Find(const String ObjName); // Find an obj of this class by name + void TOPExport(String ObjName); // can export this to top for plotting + + // Set this property to point ActiveTShapeObj to the right value +}; + +class TTShapeObj : public DSSObject::TDSSObject +{ + friend class TTShape; +public: + typedef DSSObject::TDSSObject inherited; +//private: + int LastValueAccessed; + int FNumPoints; // Number of points in curve + int ArrayPropertyIndex; + bool FStdDevCalculated; + double FMean; + double FStdDev; + double Get_Interval(); + void Set_NumPoints(int Value); + void SaveToDblFile(); + void SaveToSngFile(); + void CalcMeanandStdDev(); + double Get_Mean(); + double Get_StdDev(); + void Set_Mean(double Value); + void Set_StdDev(double Value); // Normalize the curve presently in memory +public: + double Interval; //=0.0 then random interval (hr) + // Time values (hr) if Interval > 0.0 Else nil + Arraydef::pDoubleArray Hours; + Arraydef::pDoubleArray TValues; // Temperatures + TTShapeObj(DSSClass::TDSSClass* ParClass, const string TShapeName); + virtual ~TTShapeObj(); + double GetTemperature(double hr); // Get Temperatures at specified time, hr + double Temperature(int i); // get Temperatures by index + double Hour(int i); // get hour corresponding to point index + virtual string GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + int get_FNumPoints(); + + TTShapeObj(DSSClass::TDSSClass* ParClass); + TTShapeObj(string ClassName); + TTShapeObj(); +}; +extern TTShapeObj* ActiveTShapeObj; + + +} // namespace TempShape + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace TempShape; +#endif + +#endif // TempShapeH + + + + + diff --git a/OpenDSSC/General/WireData.cpp b/OpenDSSC/General/WireData.cpp new file mode 100644 index 0000000..3a8514d --- /dev/null +++ b/OpenDSSC/General/WireData.cpp @@ -0,0 +1,214 @@ + +#pragma hdrstop + +#include "WireData.h" + +#include "DSSGlobals.h" +#include + +using namespace std; + + +namespace WireData +{ + + TWireDataObj::TWireDataObj(TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} + TWireDataObj::TWireDataObj(String ClassName) : inherited(ClassName) {} + TWireDataObj::TWireDataObj() {} + + + const int NumPropsThisClass = 0; // because they were all moved to ConductorData + // Creates superstructure for all Line objects + + TWireData::TWireData() + { + ; + Class_Name = "WireData"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + } + + TWireData::~TWireData() + { + // inherited::Destroy(); + } + + + void TWireData::DefineProperties() + { + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + int TWireData::NewObject(const String ObjName) + { + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TWireDataObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; + } + + int TWireData::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveConductorDataObj = (TConductorDataObj*)ElementList.Get_Active(); + ActiveDSSObject[ActorID] = ActiveConductorDataObj; + /*# with ActiveConductorDataObj do */ + { + auto with0 = ActiveConductorDataObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.length() > 0) + { + if (ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch (ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 101); + break; + // Inherited parameters + default: + inherited::ClassEdit(ActiveConductorDataObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + } + return result; + } + + int TWireData::MakeLike(const String WireName) + { + int result = 0; + TWireDataObj* OtherWireData = nullptr; + int i = 0; + result = 0; + OtherWireData = ((TWireDataObj*)Find(WireName)); + if (OtherWireData != nullptr) + /*# with ActiveConductorDataObj do */ + { + auto with0 = ActiveConductorDataObj; + int stop = 0; + ClassMakeLike(OtherWireData); + for (stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherWireData->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Wire MakeLike: \"") + WireName + "\" Not Found.", 102); + return result; + } + + int TWireData::Init(int Handle, int ActorID) + { + int result = 0; + DoSimpleMsg("Need to implement TWireData.Init", -1); + result = 0; + return result; + } // Returns active line code string + + String TWireData::Get_Code() + { + String result; + result = ((TWireDataObj*)ElementList.Get_Active())->get_Name(); + return result; + } // sets the active WireData + + void TWireData::Set_Code(const String Value) + { + TWireDataObj* WireDataObj = nullptr; + ActiveConductorDataObj = nullptr; + WireDataObj = (TWireDataObj*) ElementList.Get_First(); + while (WireDataObj != nullptr) + { + if (CompareText(WireDataObj->get_Name(), Value) == 0) + { + ActiveConductorDataObj = WireDataObj; + return; + } + WireDataObj = (TWireDataObj*) ElementList.Get_Next(); + } + DoSimpleMsg(String("WireData: \"") + Value + "\" not Found.", 103); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // TWireData Obj + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + TWireDataObj::TWireDataObj(TDSSClass* ParClass, const String WireDataName) + : inherited(ParClass, WireDataName) + { + Set_Name(LowerCase(WireDataName)); + DSSObjType = ParClass->DSSClassType; + InitPropertyValues(0); + /*ratings := Nil;*/ + } + + TWireDataObj::~TWireDataObj() + { + // inherited::Destroy(); + } + + + void TWireDataObj::DumpProperties(System::TTextRec& f, bool Complete) + { + inherited::DumpProperties(f, Complete); + } + + String TWireDataObj::GetPropertyValue(int Index) + { + String result; + result = inherited::GetPropertyValue(Index); + return result; + } + + int TWireDataObj::GetNumProperties(int ArrayOffset) + { + return NumPropsThisClass; + } + + void TWireDataObj::InitPropertyValues(int ArrayOffset) + { + inherited::InitPropertyValues(ArrayOffset + NumPropsThisClass); + } + + +} + + + + + + diff --git a/OpenDSSC/General/WireData.h b/OpenDSSC/General/WireData.h new file mode 100644 index 0000000..af69399 --- /dev/null +++ b/OpenDSSC/General/WireData.h @@ -0,0 +1,78 @@ +#ifndef WireDataH +#define WireDataH + +#include "System.h" +#include "Sysutils.h" +#include "Command.h" +#include "ConductorData.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LineUnits.h" + + +namespace WireData +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Used for overhead line impedances. +*/ + +class TWireData : public TConductorData +{ + friend class TWireDataObj; +public: + typedef TConductorData inherited; +//private: + String Get_Code(); // Returns active line code String + void Set_Code(const String Value); // sets the active WireData +protected: + void DefineProperties(); + virtual int MakeLike(const String WireName); +public: + TWireData(); + virtual ~TWireData(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + + // Set this property to point ActiveWireDataObj to the right value +}; + +class TWireDataObj : public ConductorData::TConductorDataObj +{ + friend class TWireData; +public: + typedef ConductorData::TConductorDataObj inherited; + TWireDataObj(DSSClass::TDSSClass* ParClass, const String WireDataName); + virtual ~TWireDataObj(); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int GetNumProperties(int ArrayOffset); + TWireDataObj(DSSClass::TDSSClass* ParClass); + TWireDataObj(String ClassName); + TWireDataObj(); +}; + + +} // namespace WireData + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace WireData; +#endif + +#endif // WireDataH + + + + + diff --git a/OpenDSSC/General/XYcurve.cpp b/OpenDSSC/General/XYcurve.cpp new file mode 100644 index 0000000..4ce0d85 --- /dev/null +++ b/OpenDSSC/General/XYcurve.cpp @@ -0,0 +1,1108 @@ + +#pragma hdrstop + +#include "XYcurve.h" + +#include "DSSClassDefs.h" +#include "DSSGlobals.h" + +using namespace std; + +namespace XYCurve +{ + + //TXYcurveObj::TXYcurveObj(TDSSClass* ParClass, const string XYCurveName) : inherited(ParClass->get_Name()) {} + TXYcurveObj::TXYcurveObj(string ClassName) : inherited(ClassName) {} + TXYcurveObj::TXYcurveObj() {} + + + TXYcurveObj* ActiveXYcurveObj = nullptr; + const int NumPropsThisClass = 13; + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + + TXYcurve::TXYcurve() + { + TempPointsBuffer.clear(); + Class_Name = "XYcurve"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + TXYcurve::~TXYcurve() + { + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void TXYcurve::DefineProperties() + { + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "npts"; // Number of points to expect + PropertyName[2 - 1] = "Points"; + PropertyName[3 - 1] = "Yarray"; // vector of Y values + PropertyName[4 - 1] = "Xarray"; // vector of X values corresponding to Y values + PropertyName[5 - 1] = "csvfile"; // Switch input to a csvfile + PropertyName[6 - 1] = "sngfile"; // switch input to a binary file of singles + PropertyName[7 - 1] = "dblfile"; // switch input to a binary file of singles + PropertyName[8 - 1] = "x"; + PropertyName[9 - 1] = "y"; + PropertyName[10 - 1] = "Xshift"; + PropertyName[11 - 1] = "Yshift"; + PropertyName[12 - 1] = "Xscale"; + PropertyName[13 - 1] = "Yscale"; + + // define Property help values + PropertyHelp[1 - 1] = "Max number of points to expect in curve. This could get reset to the actual number of points defined " + "if less than specified."; // Number of points to expect + PropertyHelp[2 - 1] = String("One way to enter the points in a curve. Enter x and y values as one array " "in the order [x1, y1, x2, y2, ...]. For example:") + CRLF + + CRLF + + "Points=[1,100 2,200 3, 300] " + + CRLF + + CRLF + + "Values separated by commas or white space. Zero fills arrays if insufficient number of values."; + PropertyHelp[3 - 1] = String("Alternate way to enter Y values. Enter an array of Y values corresponding to the X values. " "You can also use the syntax: ") + CRLF + + "Yarray = (file=filename) !for text file one value per line" + + CRLF + + "Yarray = (dblfile=filename) !for packed file of doubles" + + CRLF + + "Yarray = (sngfile=filename) !for packed file of singles " + + CRLF + + CRLF + + "Note: this property will reset Npts to a smaller value if the number of values in the files are fewer."; // vextor of hour values + PropertyHelp[4 - 1] = String("Alternate way to enter X values. Enter an array of X values corresponding to the Y values. " "You can also use the syntax: ") + CRLF + + "Xarray = (file=filename) !for text file one value per line" + + CRLF + + "Xarray = (dblfile=filename) !for packed file of doubles" + + CRLF + + "Xarray = (sngfile=filename) !for packed file of singles " + + CRLF + + CRLF + + "Note: this property will reset Npts to a smaller value if the number of values in the files are fewer."; // vextor of hour values + PropertyHelp[5 - 1] = "Switch input of X-Y curve data to a CSV file " + "containing X, Y points one per line. " + "NOTE: This action may reset the number of points to a lower value."; // Switch input to a csvfile + PropertyHelp[6 - 1] = "Switch input of X-Y curve data to a binary file of SINGLES " + "containing X, Y points packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + PropertyHelp[7 - 1] = "Switch input of X-Y curve data to a binary file of DOUBLES " + "containing X, Y points packed one after another. " + "NOTE: This action may reset the number of points to a lower value."; // switch input to a binary file of singles + PropertyHelp[8 - 1] = "Enter a value and then retrieve the interpolated Y value from the Y property. On input shifted then scaled to original curve. Scaled then shifted on output."; + PropertyHelp[9 - 1] = "Enter a value and then retrieve the interpolated X value from the X property. On input shifted then scaled to original curve. Scaled then shifted on output."; + PropertyHelp[10 - 1] = "Shift X property values (in/out) by this amount of offset. Default = 0. Does not change original definition of arrays."; + PropertyHelp[11 - 1] = "Shift Y property values (in/out) by this amount of offset. Default = 0. Does not change original definition of arrays."; + PropertyHelp[12 - 1] = "Scale X property values (in/out) by this factor. Default = 1.0. Does not change original definition of arrays."; + PropertyHelp[13 - 1] = "Scale Y property values (in/out) by this factor. Default = 1.0. Does not change original definition of arrays."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TXYcurve::NewObject(const String ObjName) + { + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TXYcurveObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; + } + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TXYcurve::Edit(int ActorID) + { + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + result = 0; + // continue parsing with contents of Parser + ActiveXYcurveObj = ((TXYcurveObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveXYcurveObj; + /*# with ActiveXYcurveObj do */ + { + auto with0 = ActiveXYcurveObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 610); + break; + case 1: + with0->Set_NumPoints(Parser[ActorID]->MakeInteger_()); + break; + case 2: + { + int stop = 0; + TempPointsBuffer.resize(with0->FNumPoints * 2); + // Allow possible Resetting (to a lower value) of num points when specifying temperatures not Hours + with0->Set_NumPoints( (int)(InterpretDblArray(Param, (with0->FNumPoints * 2), &(TempPointsBuffer[0])) / 2)); // Parser.ParseAsVector(Npts, Temperatures); + with0->YValues.resize(with0->FNumPoints); + with0->XValues.resize(with0->FNumPoints); + for(stop = with0->FNumPoints, i = 1; i <= stop; i++) + { + with0->XValues[i - 1] = TempPointsBuffer[2 * i - 0]; + with0->YValues[i - 1] = TempPointsBuffer[2 * i]; + } + with0->Set_X(with0->XValues[1]); + with0->Set_Y(with0->YValues[1]); + TempPointsBuffer.clear(); // Throw away temp array + } + break; + case 3: + { + with0->YValues.resize(with0->get_FNumPoints()); + with0->Set_NumPoints( InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->YValues[0]))); + with0->Set_Y(with0->YValues[0]); + } + break; + case 4: + { + with0->XValues.resize(with0->get_FNumPoints()); + with0->Set_NumPoints(InterpretDblArray(Param, with0->get_FNumPoints(), &(with0->XValues[0]))); + with0->Set_X(with0->XValues[0]); + } + break; + case 5: + DoCSVFile(Param); + break; // file of x,y points, one to a line + case 6: + DoSngFile(Param); + break; + case 7: + DoDblFile(Param); + break; + case 8: + with0->Set_X(Parser[ActorID]->MakeDouble_()); + break; + case 9: + with0->Set_Y(Parser[ActorID]->MakeDouble_()); + break; + case 10: + with0->FXshift = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->FYshift = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FXscale = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->FYscale = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + ClassEdit(ActiveXYcurveObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 5: case 6: case 7: + { + if ((!with0->XValues.empty()) && (!with0->YValues.empty())) + { + with0->Set_X(with0->XValues[1 - 1]); + with0->Set_Y(with0->YValues[1 - 1]); + } + } + break; + default: + ; + break; + } + switch(ParamPointer) + { + case 2: case 3: case 4: case 5: case 6: case 7: + { + with0->ArrayPropertyIndex = ParamPointer; + with0->Set_NumPoints(with0->get_FNumPoints()); // Keep Properties in order for save command + with0->LastValueAccessed = 1; + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } /*While*/ + } /*WITH*/ + return result; + } + + void* TXYcurve::Find(const String ObjName) + { + void* result = nullptr; + if((ObjName.length() == 0) || (CompareText(ObjName, "none") == 0)) + result = nullptr; + else + result = inherited::Find(ObjName); + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TXYcurve::MakeLike(const String CurveName) + { + int result = 0; + TXYcurveObj* OtherXYCurve = nullptr; + int i = 0; + result = 0; + /*See if we can find this curve in the present collection*/ + OtherXYCurve = ((TXYcurveObj*) Find(CurveName)); + if(OtherXYCurve != nullptr) + /*# with ActiveXYcurveObj do */ + { + auto with0 = ActiveXYcurveObj; + int stop = 0; + with0->Set_NumPoints(OtherXYCurve->get_FNumPoints()); + with0->XValues.resize(with0->get_FNumPoints()); + with0->YValues.resize(with0->get_FNumPoints()); + for(stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + with0->XValues[i - 1] = OtherXYCurve->XValues[i - 1]; + with0->YValues[i - 1] = OtherXYCurve->YValues[i]; + } + with0->FXshift = OtherXYCurve->FXshift; + with0->FYshift = OtherXYCurve->FYshift; + with0->FXscale = OtherXYCurve->FXscale; + with0->FYscale = OtherXYCurve->FYscale; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherXYCurve->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in XYCurve MakeLike: \"") + CurveName + + "\" Not Found.", 611); + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TXYcurve::Init(int Handle, int ActorID) + { + int result = 0; + DoSimpleMsg("Need to implement TXYcurve.Init", -1); + result = 0; + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Returns active line code string + + String TXYcurve::Get_Code() + { + String result; + TXYcurveObj* XYCurveObj = nullptr; + XYCurveObj = ((TXYcurveObj*) ElementList.Get_Active()); + result = XYCurveObj->get_Name(); + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // sets the active TShape + + void TXYcurve::Set_Code(const String Value) + { + TXYcurveObj* XYCurveObj = nullptr; + ActiveXYcurveObj = nullptr; + XYCurveObj = ((TXYcurveObj*) ElementList.Get_First()); + while(XYCurveObj != nullptr) + { + if(CompareText(XYCurveObj->get_Name(), Value) == 0) + { + ActiveXYcurveObj = XYCurveObj; + return; + } + XYCurveObj = ((TXYcurveObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("XYCurve: \"") + Value + "\" not Found.", 612); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void TXYcurve::DoCSVFile(const String FileName) + { + System::TTextRec f = {}; + int i = 0; + String dummy, s; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg("Error Opening File: " + FileName, 613); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveXYcurveObj do */ + { + auto with0 = ActiveXYcurveObj; + with0->XValues.resize(with0->get_FNumPoints()); + with0->YValues.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->FNumPoints)) + { + ++i; + System::ReadLn(f, s); // read entire line and parse with AuxParser + /*AuxParser allows commas or white space*/ + /*# with AuxParser[ActiveActor] do */ + auto with1 = AuxParser[ActiveActor]; + { + with1->SetCmdString(s); + dummy = with1->GetNextParam(); + with0->XValues[i] = with1->MakeDouble_(); + dummy = with1->GetNextParam(); + with0->YValues[i] = with1->MakeDouble_(); + } + } + System::CloseFile(f); + if(i != with0->FNumPoints) + with0->Set_NumPoints(i); + } + } + catch(exception & e) + { + { + DoSimpleMsg(String("Error Processing XYCurve CSV File: \"") + FileName + + ". " + + ( string ) e.what(), 614); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void TXYcurve::DoSngFile(const String FileName) + { + System::TTypedFile f; + float sX = 0.0F; + float sY = 0.0F; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 615); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveXYcurveObj do */ + { + auto with0 = ActiveXYcurveObj; + with0->XValues.resize(with0->get_FNumPoints()); + with0->YValues.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->get_FNumPoints())) + { + ++i; + System::Read(f, &sX); + with0->XValues[i - 1] = sX; + System::Read(f, &sY); + with0->YValues[i - 1] = sY; + } + System::CloseFile(f); + if(i != with0->get_FNumPoints()) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing binary (single) XYCurve File: \"") + FileName, 616); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + void TXYcurve::DoDblFile(const String FileName) + { + System::TTypedFile f; + int i = 0; + try + { + System::AssignFile(f, FileName); + System::Reset(f); + IOResultToException(); + } + catch(...) + { + DoSimpleMsg(String("Error Opening File: \"") + FileName, 617); + System::CloseFile(f); System::InOutRes = 0; + return; + } + try + { + /*# with ActiveXYcurveObj do */ + { + auto with0 = ActiveXYcurveObj; + with0->XValues.resize(with0->get_FNumPoints()); + with0->YValues.resize(with0->get_FNumPoints()); + i = 0; + while((!Eof(f)) && (i < with0->get_FNumPoints())) + { + ++i; + System::Read(f, &with0->XValues[i - 1]); + System::Read(f, &with0->YValues[i - 1]); + } + System::CloseFile(f); + if(i != with0->get_FNumPoints()) + with0->Set_NumPoints(i); + } + } + catch(...) + { + DoSimpleMsg(String("Error Processing binary (double) XYCurve File: \"") + FileName, 618); + System::CloseFile(f); System::InOutRes = 0; + return; + } + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // TTShape Obj + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + TXYcurveObj::TXYcurveObj(TDSSClass* ParClass, const String XYCurveName) + : inherited(ParClass), + LastValueAccessed(1), + FNumPoints(0), + ArrayPropertyIndex(0), + FX(0.0), + FY(0.0), + FXshift(0.0), + FYshift(0.0), + FXscale(0.0), + FYscale(0.0) + { + Set_Name(LowerCase(XYCurveName)); + DSSObjType = ParClass->DSSClassType; + XValues.clear(); + YValues.clear(); + FX = 0.0; + FY = 0.0; + FXshift = 0.0; + FYshift = 0.0; + FXscale = 1.0; + FYscale = 1.0; + InitPropertyValues(0); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + TXYcurveObj::~TXYcurveObj() + { + if(!XValues.empty()) + XValues.clear(); + if(!YValues.empty()) + YValues.clear(); + // inherited::Destroy(); + } + + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + // This function returns the interpolated Y value for the given X. + // If no points exist in the curve, the result is 0.0 + // If Xvalue is outside the range of defined X values, + // the curve is extrapolated from the Ends. + + double TXYcurveObj::GetYValue_(double X) + { + double result = 0.0; + int i = 0; + result = 0.0; // default return value if no points in curve + if(FNumPoints > 0) + { + if(FNumPoints == 1) // Handle Exceptional cases + result = YValues[1 - 1]; + else + + + /* Start with previous value accessed under the assumption that most + of the time, the values won't change much*/ + { + int stop = 0; + if(XValues[LastValueAccessed - 1] > X) + LastValueAccessed = 1; // Start over from Beginning + + // if off the curve for the first point, extrapolate from the first two points + if((LastValueAccessed == 1) && (XValues[1 - 1] > X)) + { + result = InterpolatePoints(1, 2, X, &(XValues[0]), &(YValues[0])); + return result; + } + + // In the middle of the arrays + for(stop = FNumPoints, i = LastValueAccessed + 1; i <= stop; i++) + { + if(Abs((XValues[i - 1] - X)) < 0.00001) // If close to an actual point, just use it. + { + result = YValues[i - 1]; + LastValueAccessed = i; + return result; + } + else + { + if(XValues[i - 1] > X) + // INTERPOLATE between two values + { + LastValueAccessed = i - 1; + result = InterpolatePoints(i, LastValueAccessed, X, &(XValues[0]), &(YValues[0])); + return result; + } + } + } + + // If we fall through the loop, Extrapolate from last two points + LastValueAccessed = FNumPoints - 1; + result = InterpolatePoints(FNumPoints, LastValueAccessed, X, &(XValues[0]), &(YValues[0])); + } + } + return result; + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + // This function returns the coefficients of the line interpolated line for the given X (a*X + b). + // If no points exist in the curve (or just a single point), the result is (a = 0, b = 0) + // If Xvalue is outside the range of defined X values, + // the curve is extrapolated from the Ends (a = 0, b = extrapolated value) + + TCoeff TXYcurveObj::GetCoefficients(double X) + { + int i = 0; + // coef: pDoubleArray; + TCoeff coef; + TCoeff result; + + // default return value if no points in curve + coef[0] = 0.0; + coef[1] = 0.0; + result = coef; + if(FNumPoints > 0) + { + if (FNumPoints == 1) // Handle Exceptional cases + { + result = coef; + } + + else + + + /* Start with previous value accessed under the assumption that most + of the time, the values won't change much*/ + { + int stop = 0; + if(XValues[LastValueAccessed - 1] > X) + LastValueAccessed = 1; // Start over from Beginning + + // if off the curve for the first point, extrapolate from the first two points + if((LastValueAccessed == 1) && (XValues[0] > X)) + + // Assume the same coefficients determined by the first two points. Necessary to keep + // consistency with TXYcurveObj.GetYValue function. + { + coef[0] = (YValues[1] - YValues[0]) / (XValues[1] - XValues[0]); + coef[1] = YValues[1] - coef[0] * XValues[1]; + result = coef; + return result; + } + + // In the middle of the arrays + for(stop = FNumPoints, i = LastValueAccessed; i <= stop; i++) + { + if(XValues[i - 1] > X) + // INTERPOLATE between two values + { + LastValueAccessed = i - 1; + coef[0] = (YValues[i - 1] - YValues[i - 2]) / (XValues[i - 1] - XValues[i - 2]); + coef[1] = YValues[i - 1] - coef[0] * XValues[i - 1]; + result = coef; + return result; + } + } + + + // Assume the same coefficients determined by the last two points. Necessary to keep + // consistency with TXYcurveObj.GetYValue function. + coef[0] = (YValues[FNumPoints - 1] - YValues[FNumPoints - 2]) / (XValues[FNumPoints - 1] - XValues[FNumPoints - 2]); + coef[1] = YValues[FNumPoints - 1] - coef[0] * XValues[FNumPoints - 1]; + result = coef; + } + } + return result; + } + + double TXYcurveObj::Get_Y() + { + double result = 0.0; + result = FY * FYscale + FYshift; + return result; + } + + double TXYcurveObj::Get_YValue(int i) + { + double result = 0.0; + if((i <= FNumPoints) && (i > 0)) + { + result = YValues[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; + } + + double TXYcurveObj::Get_X() + { + double result = 0.0; + result = FX * FXscale + FXshift; + return result; + } + + double TXYcurveObj::Get_XValue(int i) + { + double result = 0.0; + if((i <= FNumPoints) && (i > 0)) + { + result = XValues[i - 1]; + LastValueAccessed = i; + } + else + result = 0.0; + return result; + } + + void TXYcurveObj::DumpProperties(System::TTextRec& f, bool Complete) + { + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + case 3: case 4: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(i)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + break; + } + } + } + } + + String TXYcurveObj::GetPropertyValue(int Index) + { + String result; + int i = 0; + switch(Index) + { + case 2: case 3: case 4: + result = "["; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 2: + if((!XValues.empty()) && (!YValues.empty())) + { + int stop = 0; + for(stop = FNumPoints, i = 1; i <= stop; i++) + { + result = result + Format("%.8g, %.8g ", XValues[i - 1], YValues[i - 1]); + } + } + else + result = "0, 0"; + break; + case 3: + if(!YValues.empty()) + { + int stop = 0; + for(stop = FNumPoints, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", YValues[i - 1]); + } + } + else + result = "0"; + break; + case 4: + if(!XValues.empty()) + { + int stop = 0; + for(stop = FNumPoints, i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", XValues[i - 1]); + } + } + else + result = "0"; + break; + case 8: + result = Format("%.8g", Get_X()); + break; + case 9: + result = Format("%.8g", Get_Y()); + break; + case 10: + result = Format("%.8g", FXshift); + break; + case 11: + result = Format("%.8g", FYshift); + break; + case 12: + result = Format("%.8g", FXscale); + break; + case 13: + result = Format("%.8g", FYscale); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 2: case 3: case 4: + result = result + "]"; + break; + default: + ; + break; + } + return result; + } + + int TXYcurveObj::get_FNumPoints() + { + return FNumPoints; + } + + + // This FUNCTION returns the interpolated X value for the given Y. + // If no points exist in the curve, the result is 0.0 + // If Xvalue is outside the range of defined X values, + // the curve is extrapolated from the Ends. + // TEMc: change to relax assumption that Y values are increasing monotonically + // if Y is not monotonic (increasing or decreasing) then X is not unique + + double TXYcurveObj::GetXValue(double Y) + { + double result = 0.0; + int i = 0; + result = 0.0; // default return value if no points in curve + if(FNumPoints > 0) + { + if(FNumPoints == 1) + result = XValues[1]; + else + { + int stop = 0; + for(stop = FNumPoints, i = 2; i <= stop; i++) + { + if((Y >= YValues[i - 2]) && (Y <= YValues[i - 1])) + { + result = InterpolatePoints(i - 1, i, Y, &(YValues[0]), &(XValues[0])); + return result; + } + if((Y <= YValues[i - 2]) && (Y >= YValues[i - 1])) + { + result = InterpolatePoints(i - 1, i, Y, &(YValues[0]), &(XValues[0])); + return result; + } + } + // Y is out of range, need to determine which end to extrapolate from + if(YValues[1 - 1] <= YValues[FNumPoints]) // increasing Y values + { + if(Y <= YValues[1]) + { + result = InterpolatePoints(1, 2, Y, &(YValues[0]), &(XValues[0])); + } + else + { + result = InterpolatePoints(FNumPoints - 1, FNumPoints, Y, &(YValues[0]), &(XValues[0])); + } + } + else + // decreasing Y values + { + if(Y >= YValues[1 - 1]) + { + result = InterpolatePoints(1, 2, Y, &(YValues[0]), &(XValues[0])); + } + else + { + result = InterpolatePoints(FNumPoints - 1, FNumPoints, Y, &(YValues[0]), &(XValues[0])); + } + } + } + /* + IF FNumPoints>0 Then // Handle Exceptional cases + IF FNumPoints=1 Then Result := XValues^[1] + ELSE + Begin + + IF (YValues^[LastValueAccessed] > Y) Then LastValueAccessed := 1; // Start over from Beginning + + // if off the curve for the first point, extrapolate from the first two points + IF (LastValueAccessed = 1) AND (YValues[1] > Y) Then Begin + Result := InterpolatePoints(1, 2, Y, YValues, XValues); + Exit; + End; + + FOR i := LastValueAccessed+1 TO FNumPoints do + Begin + IF (Abs(YValues^[i]-Y) < 0.00001) Then // If close to an actual point, just use it. + Begin + Result := XValues^[i]; + LastValueAccessed := i; + Exit; + End + ELSE IF (YValues^[i] > Y) Then + // INTERPOLATE + Begin + LastValueAccessed := i-1; + Result := InterpolatePoints(i, LastValueAccessed, Y, YValues, XValues); + Exit ; + End; + End; + + // If we fall through the loop, Extrapolate from last two points + LastValueAccessed := FNumPoints-1; + Result := InterpolatePoints(FNumPoints, LastValueAccessed, Y, YValues, XValues); + End; + */ + } + return result; + } + + void TXYcurveObj::InitPropertyValues(int ArrayOffset) + { + Set_PropertyValue(1,"0"); // Number of points to expect + Set_PropertyValue(2,""); + Set_PropertyValue(3,""); + Set_PropertyValue(4,""); + Set_PropertyValue(5,""); + Set_PropertyValue(6,""); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,""); + Set_PropertyValue(10,"0"); + Set_PropertyValue(11,"0"); + Set_PropertyValue(12,"1"); + Set_PropertyValue(13,"1"); + inherited::InitPropertyValues(NumPropsThisClass); + } + + double TXYcurveObj::InterpolatePoints(int i, int j, double X, pDoubleArray Xarray, pDoubleArray Yarray) + { + double result = 0.0; + double Den = 0.0; + Den = (Xarray[i - 1] - Xarray[j - 1]); + if(Den != 0.0) + result = Yarray[j - 1] + (X - Xarray[j - 1]) / Den * (Yarray[i - 1] - Yarray[j - 1]); + else + result = Yarray[i - 1]; // Y is undefined, return ith value + return result; + } + + /************************************************* + + PROCEDURE TXYcurveObj.SaveToDblFile; + + Var + F:File of Double; + i:Integer; + Fname :String; + Begin + If Assigned(TValues) then Begin + TRY + FName := Format('%s.dbl',[Name]); + AssignFile(F, Fname); + Rewrite(F); + IOResultToException(); + FOR i := 1 to NumPoints Do Write(F, TValues^[i]); + GlobalResult := 'Temp=[dblfile='+FName+']'; + FINALLY + CloseFile(F); + End; + + End + ELSE DoSimpleMsg('Tshape.'+Name + ' Temperatures not defined.', 622); + End; + + PROCEDURE TXYcurveObj.SaveToSngFile; + + Var + F:File of Single; + i:Integer; + Fname :String; + Temp :Single; + + Begin + If Assigned(TValues) then Begin + TRY + FName := Format('%s.sng',[Name]); + AssignFile(F, Fname); + Rewrite(F); + IOResultToException(); + FOR i := 1 to NumPoints Do Begin + Temp := TValues^[i] ; + Write(F, Temp); + End; + GlobalResult := 'Temp=[sngfile='+FName+']'; + FINALLY + CloseFile(F); + End; + + + End + ELSE DoSimpleMsg('Tshape.'+Name + ' Temperatures not defined.', 623); + + + End; + + ****************************************************/ + + void TXYcurveObj::Set_X(double Value) + { + FX = (Value - FXshift) / FXscale; + FY = GetYValue_(FX); //Keep In synch + } + + void TXYcurveObj::Set_XValue(int Index, double Value) + { + if(Index <= FNumPoints) + XValues[Index - 1] = Value; + } + + void TXYcurveObj::Set_Y(double Value) + { + FY = (Value - FYshift) / FYscale; + FX = GetXValue(FY); //Keep In synch + } + + void TXYcurveObj::Set_YValue(int Index, double Value) + { + if(Index <= FNumPoints) + YValues[Index - 1] = Value; + } + + /*Override standard SaveWrite*/ + /*Transformer structure not conducive to standard means of saving*/ + + void TXYcurveObj::SaveWrite(System::TTextRec& f) + { + int iProp = 0; + /*Write only properties that were explicitly set in the final order they were actually set*/ + + /*Write Npts out first so that arrays get allocated properly*/ + System::Write(f, Format(" Npts=%d", FNumPoints)); + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + while(iProp > 0) + { + /*# with ParentClass do */ + { + auto with0 = ParentClass; + switch((with0->RevPropertyIdxMap)[iProp - 1]) + { + /*Trap npts= and write out array properties instead*/ + case 1: /*Ignore Npts*/ + ; + break; + default: + System::Write(f, ( " " + with0->PropertyName[with0->RevPropertyIdxMap[iProp - 1] - 1] + "=" + CheckForBlanks( String(Get_PropertyValue(iProp) ) ) ) ); + break; + } + } + iProp = GetNextPropertySet(iProp); + } + } + + void TXYcurveObj::Set_NumPoints(int Value) + { + Set_PropertyValue(1,IntToStr(Value)); // Update property list variable + + // Reset array property values to keep them in propoer order in Save + if(ArrayPropertyIndex > 0) + Set_PropertyValue(ArrayPropertyIndex,Get_PropertyValue(ArrayPropertyIndex)); + FNumPoints = Value; // Now assign the value + + // reallocate the curve memory + YValues.resize(FNumPoints); + XValues.resize(FNumPoints); + } + +}// namespace XYCurve + + + + + + + + diff --git a/OpenDSSC/General/XYcurve.h b/OpenDSSC/General/XYcurve.h new file mode 100644 index 0000000..1a76fbb --- /dev/null +++ b/OpenDSSC/General/XYcurve.h @@ -0,0 +1,149 @@ +#ifndef XYCurveH +#define XYCurveH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Arraydef.h" +#include "d2c_structures.h" +#include + + +namespace XYCurve +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 2-15-2011 Converted from TempShape. + + General X-Y Curve Data Support Class + +*/ + +/* + + The XYcurve object is a general DSS object used by all circuit elements + as a reference for obtaining yearly, daily, and other Temperature shapes. + + The values are set by the normal New and Edit PROCEDUREs for any DSS object. + + The values may be retrieved by setting the Code Property in the XYCurve Class. + This sets the active XYCurve object to be the one referenced by the Code Property; + + Then the values of that code can be retrieved via the public variables. Or you + can pick up the ActiveTXYcurveObj object and save the direct reference to the object. + + The user may place the curve data in CSV or binary files as well as passing through the + command interface. Obviously, for large amounts of data such as 8760 load curves, the + command interface is cumbersome. CSV files are text separated by commas, or white space + one point to a line. + + There are two binary formats permitted: 1) a file of Singles; 2) a file of Doubles. + + + + */ + +// We're not allowed to return arrays such as if we used "typedef double TCoeff[2];", +// so instead, use C++ std::array: +typedef std::array TCoeff; + +class TXYcurve : public DSSClass::TDSSClass +{ + friend class TXYcurveObj; +public: + typedef DSSClass::TDSSClass inherited; +//private: + std::vector TempPointsBuffer; + string Get_Code(); // Returns active TShape string + void Set_Code(const String Value); // sets the active TShape + void DoCSVFile(const String FileName); + void DoSngFile(const String FileName); + void DoDblFile(const String FileName); +protected: + void DefineProperties(); + virtual int MakeLike(const String CurveName); +public: + TXYcurve(); + virtual ~TXYcurve(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void* Find(const String ObjName); // Find an obj of this class by name + + + // Set this property to point ActiveTShapeObj to the right value +}; + +class TXYcurveObj : public TDSSObject +{ + friend class TXYcurve; +public: + typedef TDSSObject inherited; +//private: + int LastValueAccessed; + int FNumPoints; // Number of points in curve + int ArrayPropertyIndex; + double FX; + double FY; + std::vector XValues; + std::vector YValues; + void Set_NumPoints(int Value); + double InterpolatePoints(int i, int j, double X, Arraydef::pDoubleArray Xarray, Arraydef::pDoubleArray Yarray); + // PROCEDURE SaveToDblFile; + // PROCEDURE SaveToSngFile; + double Get_YValue(int i); // get Y Value by index + double Get_XValue(int i); // get X Value corresponding to point index + void Set_XValue(int Index, double Value); + void Set_YValue(int Index, double Value); + double Get_X(); + double Get_Y(); + void Set_X(double Value); + void Set_Y(double Value); +public: + + // Make these vars available to COM interface + double FXshift; + double FYshift; + double FXscale; + double FYscale; + TXYcurveObj(DSSClass::TDSSClass* ParClass, const String XYCurveName); + virtual ~TXYcurveObj(); + double GetYValue_(double X); // Get Y value at specified X Value + double GetXValue(double Y); // Get X value at specified Y Value + TCoeff GetCoefficients(double X); + virtual string GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + int get_FNumPoints(); + + //TXYcurveObj(DSSClass::TDSSClass* ParClass, const string XYCurveName); + TXYcurveObj(string ClassName); + TXYcurveObj(); +}; +extern TXYcurveObj* ActiveXYcurveObj; + + +} // namespace XYCurve + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace XYCurve; +#endif + +#endif // XYCurveH + + + + + diff --git a/OpenDSSC/General/XfmrCode.cpp b/OpenDSSC/General/XfmrCode.cpp new file mode 100644 index 0000000..7903dad --- /dev/null +++ b/OpenDSSC/General/XfmrCode.cpp @@ -0,0 +1,1053 @@ + +#pragma hdrstop + +#include "XfmrCode.h" + +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; + +namespace XfmrCode +{ + +TXfmrCodeObj::TXfmrCodeObj(TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TXfmrCodeObj::TXfmrCodeObj(String ClassName) : inherited(ClassName) {} +TXfmrCodeObj::TXfmrCodeObj() {} + + +TXfmrCodeObj* ActiveXfmrCodeObj = nullptr; +const int NumPropsThisClass = 39; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TXfmrCode::TXfmrCode() +{ + ; + Class_Name = "XfmrCode"; + DSSClassType = DSS_OBJECT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TXfmrCode::~TXfmrCode() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TXfmrCode::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + (PropertyName)[1 - 1] = "phases"; + (PropertyName)[2 - 1] = "windings"; + + // Winding Definition + (PropertyName)[3 - 1] = "wdg"; + (PropertyName)[4 - 1] = "conn"; + (PropertyName)[5 - 1] = "kV"; // FOR 2-and 3- always kVLL ELSE actual winding KV + (PropertyName)[6 - 1] = "kVA"; + (PropertyName)[7 - 1] = "tap"; + (PropertyName)[8 - 1] = "%R"; + (PropertyName)[9 - 1] = "Rneut"; + (PropertyName)[10 - 1] = "Xneut"; + + // General Data + (PropertyName)[11 - 1] = "conns"; + (PropertyName)[12 - 1] = "kVs"; + (PropertyName)[13 - 1] = "kVAs"; + (PropertyName)[14 - 1] = "taps"; + (PropertyName)[15 - 1] = "Xhl"; + (PropertyName)[16 - 1] = "Xht"; + (PropertyName)[17 - 1] = "Xlt"; + (PropertyName)[18 - 1] = "Xscarray"; // x12 13 14... 23 24.. 34 .. + (PropertyName)[19 - 1] = "thermal"; + (PropertyName)[20 - 1] = "n"; + (PropertyName)[21 - 1] = "m"; + (PropertyName)[22 - 1] = "flrise"; + (PropertyName)[23 - 1] = "hsrise"; + (PropertyName)[24 - 1] = "%loadloss"; + (PropertyName)[25 - 1] = "%noloadloss"; + (PropertyName)[26 - 1] = "normhkVA"; + (PropertyName)[27 - 1] = "emerghkVA"; + (PropertyName)[28 - 1] = "MaxTap"; + (PropertyName)[29 - 1] = "MinTap"; + (PropertyName)[30 - 1] = "NumTaps"; + (PropertyName)[31 - 1] = "%imag"; + (PropertyName)[32 - 1] = "ppm_antifloat"; + (PropertyName)[33 - 1] = "%Rs"; + (PropertyName)[34 - 1] = "X12"; + (PropertyName)[35 - 1] = "X13"; + (PropertyName)[36 - 1] = "X23"; + (PropertyName)[37 - 1] = "RdcOhms"; + (PropertyName)[38 - 1] = "Seasons"; + (PropertyName)[39 - 1] = "Ratings"; + + // define Property help values + (PropertyHelp)[1 - 1] = "Number of phases this transformer. Default is 3."; + (PropertyHelp)[2 - 1] = "Number of windings, this transformers. (Also is the number of terminals) " + "Default is 2. This property triggers memory allocation for the Transformer and will cause other properties to revert to default values."; + // Winding Definition + (PropertyHelp)[3 - 1] = "Set this = to the number of the winding you wish to define. Then set " + "the values for this winding. Repeat for each winding. Alternatively, use " + "the array collections (buses, kvas, etc.) to define the windings. Note: " + "reactances are BETWEEN pairs of windings; they are not the property of a single winding."; + (PropertyHelp)[4 - 1] = "Connection of this winding. Default is \"wye\" with the neutral solidly grounded."; + (PropertyHelp)[5 - 1] = "For 2-or 3-phase, enter phase-phase kV rating. Otherwise, kV rating of the actual winding"; + (PropertyHelp)[6 - 1] = "Base kVA rating of the winding. Side effect: forces change of max normal and emerg kva ratings." + "If 2-winding transformer, forces other winding to same value. " + "When winding 1 is defined, all other windings are defaulted to the same rating " + "and the first two winding resistances are defaulted to the %loadloss value."; + (PropertyHelp)[7 - 1] = "Per unit tap that this winding is normally on."; + (PropertyHelp)[8 - 1] = "Percent resistance this winding. (half of total for a 2-winding)."; + (PropertyHelp)[9 - 1] = "Default = -1. Neutral resistance of wye (star)-connected winding in actual ohms." + "If entered as a negative value, the neutral is assumed to be open, or floating."; + (PropertyHelp)[10 - 1] = "Neutral reactance of wye(star)-connected winding in actual ohms. May be + or -."; + + // General Data + (PropertyHelp)[11 - 1] = String("Use this to specify all the Winding connections at once using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + "~ conns=(delta, wye)"; + (PropertyHelp)[12 - 1] = String("Use this to specify the kV ratings of all windings at once using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + CRLF + + "~ conns=(delta, wye)" + + CRLF + + "~ kvs=(115, 12.47)" + + CRLF + + CRLF + + "See kV= property for voltage rules."; + (PropertyHelp)[13 - 1] = "Use this to specify the kVA ratings of all windings at once using an array."; + (PropertyHelp)[14 - 1] = "Use this to specify the normal p.u. tap of all windings at once using an array."; + (PropertyHelp)[15 - 1] = "Use this to specify the percent reactance, H-L (winding 1 to winding 2). Use " + "for 2- or 3-winding transformers. On the kva base of winding 1."; + (PropertyHelp)[16 - 1] = "Use this to specify the percent reactance, H-T (winding 1 to winding 3). Use " + "for 3-winding transformers only. On the kVA base of winding 1."; + (PropertyHelp)[17 - 1] = "Use this to specify the percent reactance, L-T (winding 2 to winding 3). Use " + "for 3-winding transformers only. On the kVA base of winding 1."; + (PropertyHelp)[18 - 1] = String("Use this to specify the percent reactance between all pairs of windings as an array. " "All values are on the kVA base of winding 1. The order of the values is as follows:") + CRLF + + CRLF + + "(x12 13 14... 23 24.. 34 ..) " + + CRLF + + CRLF + + "There will be n(n-1)/2 values, where n=number of windings."; + (PropertyHelp)[19 - 1] = "Thermal time constant of the transformer in hours. Typically about 2."; + (PropertyHelp)[20 - 1] = "n Exponent for thermal properties in IEEE C57. Typically 0.8."; + (PropertyHelp)[21 - 1] = "m Exponent for thermal properties in IEEE C57. Typically 0.9 - 1.0"; + (PropertyHelp)[22 - 1] = "Temperature rise, deg C, for full load. Default is 65."; + (PropertyHelp)[23 - 1] = "Hot spot temperature rise, deg C. Default is 15."; + (PropertyHelp)[24 - 1] = "Percent load loss at full load. The %R of the High and Low windings (1 and 2) are adjusted to agree at rated kVA loading."; + (PropertyHelp)[25 - 1] = "Percent no load losses at rated excitatation voltage. Default is 0. Converts to a resistance in parallel with the magnetizing impedance in each winding."; + (PropertyHelp)[26 - 1] = "Normal maximum kVA rating of H winding (winding 1). Usually 100% - 110% of" + "maximum nameplate rating, depending on load shape. Defaults to 110% of kVA rating of Winding 1."; + (PropertyHelp)[27 - 1] = "Emergency (contingency) kVA rating of H winding (winding 1). Usually 140% - 150% of" + "maximum nameplate rating, depending on load shape. Defaults to 150% of kVA rating of Winding 1."; + (PropertyHelp)[28 - 1] = "Max per unit tap for the active winding. Default is 1.10"; + (PropertyHelp)[29 - 1] = "Min per unit tap for the active winding. Default is 0.90"; + (PropertyHelp)[30 - 1] = "Total number of taps between min and max tap. Default is 32."; + (PropertyHelp)[31 - 1] = "Percent magnetizing current. Default=0.0. Magnetizing branch is in parallel with windings in each phase. Also, see \"ppm_antifloat\"."; + (PropertyHelp)[32 - 1] = "Default=1 ppm. Parts per million of transformer winding VA rating connected to ground to protect against accidentally floating a winding without a reference. " + "If positive then the effect is adding a very large reactance to ground. If negative, then a capacitor."; + (PropertyHelp)[33 - 1] = String("Use this property to specify all the winding %resistances using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + "~ %Rs=(0.2 0.3)"; + (PropertyHelp)[34 - 1] = "Alternative to XHL for specifying the percent reactance from winding 1 to winding 2. Use " + "for 2- or 3-winding transformers. Percent on the kVA base of winding 1. "; + (PropertyHelp)[35 - 1] = "Alternative to XHT for specifying the percent reactance from winding 1 to winding 3. Use " + "for 3-winding transformers only. Percent on the kVA base of winding 1. "; + (PropertyHelp)[36 - 1] = "Alternative to XLT for specifying the percent reactance from winding 2 to winding 3.Use " + "for 3-winding transformers only. Percent on the kVA base of winding 1. "; + (PropertyHelp)[37 - 1] = "Winding dc resistance in OHMS. Useful for GIC analysis. From transformer test report. " + "Defaults to 85% of %R property"; + (PropertyHelp)[38 - 1] = "Defines the number of ratings to be defined for the transfomer, to be used only when defining seasonal ratings using the \"Ratings\" property."; + (PropertyHelp)[39 - 1] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in transformers."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TXfmrCode::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveDSSObject[ActiveActor] = new TXfmrCodeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +void TXfmrCodeObj::SetNumWindings(int n) +{ + int i = 0; + int OldWdgSize = 0; + int NewWdgSize = 0; + if(n > 1) + { + int stop = 0; + WINDING_.clear(); // Free old WINDING_ objects + OldWdgSize = ((NumWindings - 1) * ((double) NumWindings / 2)); // this is needed to emulate the beavior in delphi, do not remove the (double)! + NumWindings = n; + MaxWindings = n; + NewWdgSize = ((NumWindings - 1) * ((double) NumWindings / 2)); + WINDING_.resize(MaxWindings); // Reallocate collector array + for(stop = MaxWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1] = TWinding(); + } + XSC.resize(NewWdgSize); + for(stop = NewWdgSize, i = OldWdgSize + 1; i <= stop; i++) + { + XSC[i - 1] = 0.30; // default to something + } + } + else + DoSimpleMsg(String("Invalid number of windings: (") + IntToStr(n) + + ") for Transformer " + + ActiveTransfObj->get_Name(), 111); +} + +void TXfmrCode::SetActiveWinding(int W) +{ + /*# with ActiveXfmrCodeObj do */ + { + auto with0 = ActiveXfmrCodeObj; + if((W > 0) && (W <= with0->NumWindings)) + with0->ActiveWinding = W; + else + DoSimpleMsg(String("Wdg parameter invalid for \"") + ActiveXfmrCodeObj->get_Name() + + "\"", 112); + } +} + +void TXfmrCode::InterpretWindings(const String s, WdgParmChoice Which) +{ + String Str; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); + /*# with ActiveXfmrCodeObj do */ + { + auto with0 = ActiveXfmrCodeObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + Str = AuxParser[ActiveActor]->MakeString_(); + if(Str.length() > 0) + switch(Which) + { + case Conn: + with0->WINDING_[with0->ActiveWinding - 1].Connection = InterpretConnection(Str); + break; + case kV: + with0->WINDING_[with0->ActiveWinding - 1].kVLL = AuxParser[ActiveActor]->MakeDouble_(); + break; + case kVA: + with0->WINDING_[with0->ActiveWinding - 1].kVA = AuxParser[ActiveActor]->MakeDouble_(); + break; + case R: + with0->WINDING_[with0->ActiveWinding - 1].Rpu = 0.01 * AuxParser[ActiveActor]->MakeDouble_(); + break; + case Tap: + with0->WINDING_[with0->ActiveWinding - 1].puTap = AuxParser[ActiveActor]->MakeDouble_(); + break; + default: + ; + break; + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TXfmrCode::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + int i = 0; + String ParamName; /*For parsing property names*/ + String Param; + bool UpdateXsc = false; + ActiveXfmrCodeObj = ((TXfmrCodeObj*) ElementList.Get_Active()); + ActiveDSSObject[ActorID] = ActiveXfmrCodeObj; + UpdateXsc = false; + /*# with ActiveXfmrCodeObj do */ + { + auto with0 = ActiveXfmrCodeObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.length() > 0) + { + if(ParamName.length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"XfmrCode." + + with0->get_Name() + + "\"", 110); + break; + case 1: + with0->Fnphases = Parser[ActorID]->MakeInteger_(); + break; + case 2: + with0->SetNumWindings(Parser[ActorID]->MakeInteger_()); + break; // Reallocate stuff if bigger + case 3: + SetActiveWinding(Parser[ActorID]->MakeInteger_()); + break; + case 4: + with0->WINDING_[with0->ActiveWinding - 1].Connection = InterpretConnection(Param); + break; + case 5: + with0->WINDING_[with0->ActiveWinding - 1].kVLL = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->WINDING_[with0->ActiveWinding - 1].kVA = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->WINDING_[with0->ActiveWinding - 1].puTap = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->WINDING_[with0->ActiveWinding - 1].Rpu = Parser[ActorID]->MakeDouble_() * 0.01; + break; // %R + case 9: + with0->WINDING_[with0->ActiveWinding - 1].Rneut = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->WINDING_[with0->ActiveWinding - 1].Xneut = Parser[ActorID]->MakeDouble_(); + break; + case 11: + InterpretWindings(Param, Conn); + break; + case 12: + InterpretWindings(Param, kV); + break; + case 13: + InterpretWindings(Param, kVA); + break; + case 14: + InterpretWindings(Param, Tap); + break; + case 15: + with0->XHL = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 16: + with0->XHT = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 17: + with0->XLT = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 18: + Parser[ActorID]->ParseAsVector(((with0->NumWindings - 1) * (with0->NumWindings / 2)), (pDoubleArray) & (with0->XSC)); + break; + case 19: + with0->ThermalTimeConst = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->n_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->m_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->FLrise = Parser[ActorID]->MakeDouble_(); + break; + case 23: + with0->HSrise = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->pctLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->pctNoLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 26: + with0->NormMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->EmergMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->WINDING_[with0->ActiveWinding - 1].MaxTap = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->WINDING_[with0->ActiveWinding - 1].MinTap = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->WINDING_[with0->ActiveWinding - 1].NumTaps = Parser[ActorID]->MakeInteger_(); + break; + case 31: + with0->pctImag = Parser[ActorID]->MakeDouble_(); + break; + case 32: + with0->ppm_FloatFactor = Parser[ActorID]->MakeDouble_() * 1.0e-6; + break; + case 33: + InterpretWindings(Param, R); + break; + case 34: + with0->XHL = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 35: + with0->XHT = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 36: + with0->XLT = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 37: + with0->WINDING_[with0->ActiveWinding - 1].RdcOhms = Parser[ActorID]->MakeDouble_(); + break; + case 38: + { + with0->NumAmpRatings = Parser[ActorID]->MakeInteger_(); + with0->AmpRatings.resize(with0->NumAmpRatings); + } + break; + case 39: + { + with0->AmpRatings.resize(with0->NumAmpRatings); + Param = Parser[ActiveActor]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, ((pDoubleArray) &(with0->AmpRatings[0]))); + } + break; + default: + ClassEdit(ActiveXfmrCodeObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Take care of properties that require some additional work,*/ + switch(ParamPointer) + { + case 6: + if(with0->ActiveWinding == 1) + // default all winding kvas to first winding so latter Donot have to be specified + { + int stop = 0; + for(stop = with0->NumWindings, i = 2; i <= stop; i++) + { + with0->WINDING_[i - 1].kVA = with0->WINDING_[1 - 1].kVA; + } + with0->NormMaxHkVA = 1.1 * with0->WINDING_[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * with0->WINDING_[1 - 1].kVA; + } + else + { + if(with0->NumWindings == 2) + { + with0->WINDING_[1 - 1].kVA = with0->WINDING_[2 - 1].kVA; // For 2-winding, force both kVAs to be same + } + } + break; + // Update LoadLosskW if winding %r changed. Using only windings 1 and 2 + case 8: + with0->pctLoadLoss = (with0->WINDING_[1 - 1].Rpu + with0->WINDING_[2 - 1].Rpu) * 100.0; + break; + case 13: + { + with0->NormMaxHkVA = 1.1 * with0->WINDING_[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * with0->WINDING_[1 - 1].kVA; + } + break; + case 15: case 16: case 17: + { + UpdateXsc = true; + } + break; + case 18: + for(int stop = ((with0->NumWindings - 1) * (with0->NumWindings / 2)), i = 1; i <= stop; i++) + { + (with0->XSC)[i - 1] = (with0->XSC)[i - 1] * 0.01; + } + break; // Convert to per unit + // Assume load loss is split evenly between windings 1 and 2 + case 24: + { + with0->WINDING_[1 - 1].Rpu = with0->pctLoadLoss / 2.0 / 100.0; + with0->WINDING_[2 - 1].Rpu = with0->WINDING_[1 - 1].Rpu; + } + break; + case 33: + with0->pctLoadLoss = (with0->WINDING_[1 - 1].Rpu + with0->WINDING_[2 - 1].Rpu) * 100.0; + break; // Keep this up to date + case 34: case 35: case 36: + UpdateXsc = true; + break; + case 37: + with0->WINDING_[with0->ActiveWinding].RdcSpecified = true; + break; + default: + ; + break; + } + + /*Advance to next property on input line*/ + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(UpdateXsc) + { + if(with0->NumWindings <= 3) + { + int stop = 0; + for(stop = (with0->NumWindings * (with0->NumWindings - 1) / 2), i = 1; i <= stop; i++) + { + switch(i) + { + case 1: + (with0->XSC)[1 - 1] = with0->XHL; + break; + case 2: + (with0->XSC)[2 - 1] = with0->XHT; + break; + case 3: + (with0->XSC)[3 - 1] = with0->XLT; + break; + default: + ; + break; + } + } + } + } + } + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TXfmrCode::MakeLike(const String Name) +{ + int result = 0; + TXfmrCodeObj* Other = nullptr; + int i = 0; + result = 0; + /*See if we can find this ode in the present collection*/ + Other = ((TXfmrCodeObj*) Find(Name)); + if(Other != nullptr) + /*# with ActiveXfmrCodeObj do */ + { + auto with0 = ActiveXfmrCodeObj; + int stop = 0; + with0->Fnphases = Other->Fnphases; + with0->SetNumWindings(Other->NumWindings); + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + /*# with with0->WINDING^[i] do */ + { + + with0->WINDING_[i - 1].Connection = Other->WINDING_[i - 1].Connection; + with0->WINDING_[i - 1].kVLL = Other->WINDING_[i - 1].kVLL; + with0->WINDING_[i - 1].VBase = Other->WINDING_[i - 1].VBase; + with0->WINDING_[i - 1].kVA = Other->WINDING_[i - 1].kVA; + with0->WINDING_[i - 1].puTap = Other->WINDING_[i - 1].puTap; + with0->WINDING_[i - 1].Rpu = Other->WINDING_[i - 1].Rpu; + with0->WINDING_[i - 1].RdcOhms = Other->WINDING_[i - 1].RdcOhms; + with0->WINDING_[i - 1].RdcSpecified = Other->WINDING_[i - 1].RdcSpecified; + with0->WINDING_[i - 1].Rneut = Other->WINDING_[i - 1].Rneut; + with0->WINDING_[i - 1].Xneut = Other->WINDING_[i - 1].Xneut; + with0->WINDING_[i - 1].TapIncrement = Other->WINDING_[i - 1].TapIncrement; + with0->WINDING_[i - 1].MinTap = Other->WINDING_[i - 1].MinTap; + with0->WINDING_[i - 1].MaxTap = Other->WINDING_[i - 1].MaxTap; + with0->WINDING_[i - 1].NumTaps = Other->WINDING_[i - 1].NumTaps; + } + } + with0->XHL = Other->XHL; + with0->XHT = Other->XHT; + with0->XLT = Other->XLT; + for(stop = (with0->NumWindings * (with0->NumWindings - 1) / 2), i = 1; i <= stop; i++) + { + (with0->XSC)[i - 1] = (Other->XSC)[i - 1]; + } + with0->ThermalTimeConst = Other->ThermalTimeConst; + with0->n_thermal = Other->n_thermal; + with0->m_thermal = Other->m_thermal; + with0->FLrise = Other->FLrise; + with0->HSrise = Other->HSrise; + with0->pctLoadLoss = Other->pctLoadLoss; + with0->pctNoLoadLoss = Other->pctNoLoadLoss; + with0->NormMaxHkVA = Other->NormMaxHkVA; + with0->EmergMaxHkVA = Other->EmergMaxHkVA; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,Other->Get_PropertyValue(i)); + } + with0->NumAmpRatings = Other->NumAmpRatings; + with0->AmpRatings.resize(with0->NumAmpRatings); + for(stop = (sizeof(with0->AmpRatings) - 1), i = 0; i <= stop; i++) + { + with0->AmpRatings[i] = Other->AmpRatings[i]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in XfmrCode MakeLike: \"") + Name + + "\" Not Found.", 102); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TXfmrCode::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TXfmrCode.Init", -1); + result = 0; + return result; +} // Returns active line code string + +String TXfmrCode::Get_Code() +{ + String result; + result = ((TXfmrCodeObj*) ElementList.Get_Active())->get_Name(); + return result; +} // sets the active XfmrCode + +void TXfmrCode::Set_Code(const String Value) +{ + TXfmrCodeObj* XfmrCodeObj = nullptr; + ActiveXfmrCodeObj = nullptr; + XfmrCodeObj = ((TXfmrCodeObj*) ElementList.Get_First()); + while(XfmrCodeObj != nullptr) + { + if(CompareText(XfmrCodeObj->get_Name(), Value) == 0) + { + ActiveXfmrCodeObj = XfmrCodeObj; + return; + } + XfmrCodeObj = ((TXfmrCodeObj*) ElementList.Get_Next()); + } + DoSimpleMsg(String("XfmrCode: \"") + Value + "\" not Found.", 103); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TXfmrCode Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TXfmrCodeObj::TXfmrCodeObj(TDSSClass* ParClass, const String XfmrCodeName) + : inherited(ParClass), + Fnphases(3), + ActiveWinding(1), + NumWindings(0), + MaxWindings(0), + XHL(0.0), + XHT(0.0), + XLT(0.0), + VABase(0.0), + NormMaxHkVA(0.0), + EmergMaxHkVA(0.0), + ThermalTimeConst(0.0), + n_thermal(0.0), + m_thermal(0.0), + FLrise(0.0), + HSrise(0.0), + pctLoadLoss(0.0), + pctNoLoadLoss(0.0), + ppm_FloatFactor(0.0), + pctImag(0.0), + NumAmpRatings(0) +{ + int i = 0; + int stop = 0; + XSC.clear(); + Set_Name(LowerCase(XfmrCodeName)); + DSSObjType = ParClass->DSSClassType; + + // default values and sizes + NumWindings = 2; + MaxWindings = 2; + WINDING_.resize(MaxWindings); + for(stop = MaxWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1] = TWinding(); + } + XHL = 0.07; + XHT = 0.35; + XLT = 0.30; + XSC.resize((NumWindings - 1) * (NumWindings / 2)); + VABase = WINDING_[1 - 1].kVA * 1000.0; + ThermalTimeConst = 2.0; + n_thermal = 0.8; + m_thermal = 0.8; + FLrise = 65.0; + HSrise = 15.0; // Hot spot rise + NormMaxHkVA = 1.1 * WINDING_[1 - 1].kVA; + EmergMaxHkVA = 1.5 * WINDING_[1 - 1].kVA; + pctLoadLoss = 2.0 * WINDING_[1 - 1].Rpu * 100.0; // assume two windings + ppm_FloatFactor = 0.000001; + /*Compute antifloat added for each winding */ + for(stop = NumWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1].ComputeAntiFloatAdder(ppm_FloatFactor, VABase / Fnphases); + } + pctNoLoadLoss = 0.0; + pctImag = 0.0; + NumAmpRatings = 1; + AmpRatings.resize(NumAmpRatings); + AmpRatings[0] = 600; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +TXfmrCodeObj::~TXfmrCodeObj() +{ + XSC.clear(); + // inherited::Destroy(); +} + + +void TXfmrCodeObj::PullFromTransformer(TTransfObj* Obj) +{ + int i = 0; + int stop = 0; + SetNumWindings(Obj->get_NumWindings()); + Fnphases = Obj->Get_NPhases(); + XHL = Obj->get_XHL(); + XHT = Obj->get_XHT(); + XLT = Obj->get_XLT(); + VABase = Obj->get_VABase(); + NormMaxHkVA = Obj->get_NormMaxHkVA(); + EmergMaxHkVA = Obj->get_EmergMaxHkVA(); + ThermalTimeConst = Obj->get_ThermalTimeConst(); + n_thermal = Obj->get_n_thermal(); + m_thermal = Obj->get_m_thermal(); + FLrise = Obj->get_FLrise(); + HSrise = Obj->get_HSrise(); + pctLoadLoss = Obj->get_pctLoadLoss(); + pctNoLoadLoss = Obj->get_pctNoLoadLoss(); + ppm_FloatFactor = Obj->get_ppm_FloatFactor(); + pctImag = Obj->get_pctImag(); + for(stop = (NumWindings - 1) * (NumWindings / 2), i = 1; i <= stop; i++) + { + XSC[i - 1] = Obj->Get_Xsc(i); + } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1].Connection = Obj->Get_WdgConnection(i - 1); + WINDING_[i - 1].kVLL = Obj->Get_BasekVLL(i - 1); + WINDING_[i - 1].VBase = Obj->Get_BaseVoltage(i - 1); + WINDING_[i - 1].kVA = Obj->Get_WdgkVA(i - 1); + WINDING_[i - 1].puTap = Obj->Get_PresentTap(i - 1, ActiveActor - 1); + WINDING_[i - 1].Rpu = Obj->Get_WdgResistance(i - 1); + WINDING_[i - 1].Rneut = Obj->Get_WdgRneutral(i - 1); + WINDING_[i - 1].Xneut = Obj->Get_WdgXneutral(i - 1); + WINDING_[i - 1].Y_PPM = Obj->Get_WdgYPPM(i - 1); + WINDING_[i - 1].TapIncrement = Obj->Get_TapIncrement(i - 1); + WINDING_[i - 1].MinTap = Obj->Get_MinTap(i - 1); + WINDING_[i - 1].MaxTap = Obj->Get_MaxTap(i - 1); + WINDING_[i - 1].NumTaps = Obj->Get_NumTaps(i - 1); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TXfmrCodeObj::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + int stop = 0; + inherited::DumpProperties(f, Complete); + + /*Basic Property Dump*/ + { System::Write(f, "~ "); Write(f, "NumWindings="); WriteLn(f, NumWindings, 0); } + { System::Write(f, "~ "); Write(f, "phases="); WriteLn(f, Fnphases, 0); } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(i == 1) + { + System::Write(f, "~ "); System::Write(f, "Wdg="); WriteLn(f, i, 0); } + else + { + System::Write(f, "~ "); System::Write(f, "Wdg="); WriteLn(f, i, 0); } + switch(WINDING_[i - 1].Connection) + { + case 0: + System::WriteLn(f, "~ conn=wye"); + break; + case 1: + System::WriteLn(f, "~ conn=delta"); + break; + default: + ; + break; + } + { System::Write(f, "~ kV="); System::WriteLn(f, WINDING_[i - 1].kVLL, 0, 2); } + { System::Write(f, "~ kVA="); System::WriteLn(f, WINDING_[i - 1].kVA, 0, 1); } + { System::Write(f, "~ tap="); System::WriteLn(f, WINDING_[i - 1].puTap, 0, 3); } + { System::Write(f, "~ %R="); System::WriteLn(f, (WINDING_[i - 1].Rpu * 100.0), 0, 2); } + System::WriteLn(f, Format("~ RdcOhms=%.7g", WINDING_[i - 1].RdcOhms) ); + { System::Write(f, "~ rneut="); System::WriteLn(f, WINDING_[i - 1].Rneut, 0, 3); } + { System::Write(f, "~ xneut="); System::WriteLn(f, WINDING_[i - 1].Xneut, 0, 3); } + } + } + { System::Write(f, "~ "); System::Write(f, "XHL="); System::WriteLn(f, XHL * 100.0, 0, 3); } + { System::Write(f, "~ "); System::Write(f, "XHT="); System::WriteLn(f, XHT * 100.0, 0, 3); } + { System::Write(f, "~ "); System::Write(f, "XLT="); System::WriteLn(f, XLT * 100.0, 0, 3); } + { System::Write(f, "~ "); System::Write(f, "X12="); System::WriteLn(f, XHL * 100.0, 0, 3); } + { System::Write(f, "~ "); System::Write(f, "X13="); System::WriteLn(f, XHT * 100.0, 0, 3); } + { System::Write(f, "~ "); System::Write(f, "X23="); System::WriteLn(f, XLT * 100.0, 0, 3); } + System::Write(f, "~ Xscmatrix= \""); + for(stop = (NumWindings - 1) * (NumWindings / 2), i = 1; i <= stop; i++) + { + { System::Write(f, XSC[i - 1] * 100.0, 0, 2); System::Write(f, L' '); } + } + System::WriteLn(f, L'\"'); + { System::Write(f, "~ "); System::Write(f, "NormMAxHkVA="); System::WriteLn(f, NormMaxHkVA, 0, 0); } + { System::Write(f, "~ "); System::Write(f, "EmergMAxHkVA="); System::WriteLn(f, EmergMaxHkVA, 0, 0); } + { System::Write(f, "~ "); System::Write(f, "thermal="); System::WriteLn(f, ThermalTimeConst, 0, 1); } + { System::Write(f, "~ "); System::Write(f, "n="); System::WriteLn(f, n_thermal, 0, 1); } + { System::Write(f, "~ "); System::Write(f, "m="); System::WriteLn(f, m_thermal, 0, 1); } + { System::Write(f, "~ "); System::Write(f, "flrise="); System::WriteLn(f, FLrise, 0, 0); } + { System::Write(f, "~ "); System::Write(f, "hsrise="); System::WriteLn(f, HSrise, 0, 0); } + { System::Write(f, "~ "); System::Write(f, "%loadloss="); System::WriteLn(f, pctLoadLoss, 0, 0); } + { System::Write(f, "~ "); System::Write(f, "%noloadloss="); System::WriteLn(f, pctNoLoadLoss, 0, 0); } + for(stop = NumPropsThisClass, i = 28; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, (*ParentClass->PropertyName)[i]); System::Write(f, L'='); System::WriteLn(f, Get_PropertyValue(i)); } + } + /*# with ParentClass do */ + { + auto with1 = ParentClass; + int stop = 0; + for(stop = with1->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { System::Write(f, "~ "); System::Write(f, (*with1->PropertyName)[i]); System::Write(f, L'='); System::WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +/* gets the property for the active winding ; Set the active winding before calling*/ + +String TXfmrCodeObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + int k = 0; + String TempStr; + switch(Index) + { + case 11: case 12: case 13: case 14: + case 18: + case 33: + result = "["; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 3: + result = IntToStr(ActiveWinding); + break; // return active winding + case 4: + switch(WINDING_[ActiveWinding - 1].Connection) + { + case 0: + result = "wye "; + break; + case 1: + result = "delta "; + break; + default: + ; + break; + } + break; + case 5: + result = Format("%.7g", WINDING_[ActiveWinding- 1].kVLL); + break; + case 6: + result = Format("%.7g", WINDING_[ActiveWinding- 1].kVA); + break; + case 7: + result = Format("%.7g", WINDING_[ActiveWinding- 1].puTap); + break; + case 8: + result = Format("%.7g", WINDING_[ActiveWinding- 1].Rpu * 100.0); + break; // %R + case 9: + result = Format("%.7g", WINDING_[ActiveWinding- 1].Rneut); + break; + case 10: + result = Format("%.7g", WINDING_[ActiveWinding- 1].Xneut); + break; + case 11: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + switch(WINDING_[i - 1].Connection) + { + case 0: + result = result + "wye, "; + break; + case 1: + result = result + "delta, "; + break; + default: + ; + break; + } + } + break; + case 12: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i- 1].kVLL); + } + break; + case 13: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i- 1].kVA); + } + break; + case 14: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i- 1].puTap); + } + break; + case 18: + for(int stop = (NumWindings - 1) * (NumWindings / 2), i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", XSC[i- 1] * 100.0); + } + break; + case 24: + result = Format("%.7g", pctLoadLoss); + break; + case 25: + result = Format("%.7g", pctNoLoadLoss); + break; + case 28: + result = Format("%.7g", WINDING_[ActiveWinding - 1].MaxTap); + break; + case 29: + result = Format("%.7g", WINDING_[ActiveWinding - 1].MinTap); + break; + case 30: + result = Format("%-d", WINDING_[ActiveWinding - 1].NumTaps); + break; + case 33: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i - 1].Rpu * 100.0); + } + break; + case 37: + result = Format("%.7g", WINDING_[ActiveWinding - 1].RdcOhms); + break; + case 38: + result = IntToStr(NumAmpRatings); + break; + case 39: + { + int stop = 0; + TempStr = "["; + for(stop = NumAmpRatings, k = 1; k <= stop; k++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[k - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + result = TempStr; + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 11: case 12: case 13: case 14: + case 18: + case 33: + result = result + "]"; + break; + default: + ; + break; + } + return result; +} + +void TXfmrCodeObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,"2"); //'windings'; + Set_PropertyValue(3,"1"); //'wdg'; + Set_PropertyValue(4,"wye"); // 'conn'; + Set_PropertyValue(5,"12.47"); // IF 2or 3-phase: phase-phase ELSE actual winding + Set_PropertyValue(6,"1000"); + Set_PropertyValue(7,"1.0"); + Set_PropertyValue(8,"0.2"); + Set_PropertyValue(9,"-1"); + Set_PropertyValue(10,"0"); + Set_PropertyValue(11,""); + Set_PropertyValue(12,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(13,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(14,""); + Set_PropertyValue(15,"7"); + Set_PropertyValue(16,"35"); + Set_PropertyValue(17,"30"); + Set_PropertyValue(18,""); // x12 13 14... 23 24.. 34 .. + Set_PropertyValue(19,"2"); + Set_PropertyValue(20,".8"); + Set_PropertyValue(21,".8"); + Set_PropertyValue(22,"65"); + Set_PropertyValue(23,"15"); + Set_PropertyValue(24,"0"); + Set_PropertyValue(25,"0"); + Set_PropertyValue(26,""); + Set_PropertyValue(27,""); + Set_PropertyValue(28,"1.10"); + Set_PropertyValue(29,"0.90"); + Set_PropertyValue(30,"32"); + Set_PropertyValue(31,"0"); + Set_PropertyValue(32,"1"); + Set_PropertyValue(33,""); + Set_PropertyValue(34,"7"); + Set_PropertyValue(35,"35"); + Set_PropertyValue(36,"30"); + Set_PropertyValue(37,"0.1"); + Set_PropertyValue(38,"1"); + Set_PropertyValue(39,"[600]"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +} // namespace XfmrCode + + + + + diff --git a/OpenDSSC/General/XfmrCode.h b/OpenDSSC/General/XfmrCode.h new file mode 100644 index 0000000..416debd --- /dev/null +++ b/OpenDSSC/General/XfmrCode.h @@ -0,0 +1,112 @@ +#ifndef XfmrCodeH +#define XfmrCodeH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "DSSObject.h" +#include "Ucmatrix.h" +#include "Arraydef.h" +#include "Transformer.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" + +#include "Ucomplex.h" + + + +namespace XfmrCode +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +enum WdgParmChoice {Conn, + kV, + kVA, + R, + Tap }; + +class TXfmrCode : public TDSSClass +{ + friend class TXfmrCodeObj; +public: + typedef TDSSClass inherited; +private: + String Get_Code(); + void SetActiveWinding(int W); + void InterpretWindings(const String s, WdgParmChoice Which); +protected: + void DefineProperties(); + virtual int MakeLike(const String Name); +public: + TXfmrCode(); + virtual ~TXfmrCode(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void Set_Code(const String Value); + + // Set this property to point ActiveXfmrCodeObj to the right value +}; + +class TXfmrCodeObj : public DSSObject::TDSSObject +{ + friend class TXfmrCode; +public: + typedef DSSObject::TDSSObject inherited; + int Fnphases; + int ActiveWinding; + int NumWindings; + int MaxWindings; + double XHL; + double XHT; + double XLT; // per unit + std::vector XSC; // per unit SC measurements + double VABase; // FOR impedances + double NormMaxHkVA; + double EmergMaxHkVA; + double ThermalTimeConst; /*hr*/ + double n_thermal; + double m_thermal; /*Exponents*/ + double FLrise; + double HSrise; + double pctLoadLoss; + double pctNoLoadLoss; + double ppm_FloatFactor; // parts per million winding float factor + double pctImag; + std::vector WINDING_; + int NumAmpRatings; + Arraydef::TRatingsArray AmpRatings; + void SetNumWindings(int n); + void PullFromTransformer(Transformer::TTransfObj* Obj); + TXfmrCodeObj(DSSClass::TDSSClass* ParClass, const String XfmrCodeName); + virtual ~TXfmrCodeObj(); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TXfmrCodeObj(DSSClass::TDSSClass* ParClass); + TXfmrCodeObj(String ClassName); + TXfmrCodeObj(); +}; +extern TXfmrCodeObj* ActiveXfmrCodeObj; + + +} // namespace XfmrCode + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace XfmrCode; +#endif + +#endif // XfmrCodeH + + + + + diff --git a/OpenDSSC/Meters/EnergyMeter.cpp b/OpenDSSC/Meters/EnergyMeter.cpp new file mode 100644 index 0000000..25370c8 --- /dev/null +++ b/OpenDSSC/Meters/EnergyMeter.cpp @@ -0,0 +1,4242 @@ + +#pragma hdrstop + +#include "EnergyMeter.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Bus.h" +#include "mathutil.h" +#include "Ucmatrix.h" +#include "Utilities.h" +#include "PCElement.h" +#include "StackDef.h" +#include "Circuit.h" +#include "Line.h" +#include "LineUnits.h" +#include "ReduceAlgs.h" +#include +#include "MemoryMap_lib.h" +#include "dirsep.h" + +using namespace std; +using namespace Arraydef; +using namespace Bus; +using namespace Circuit; +using namespace CktElement; +using namespace CktTree; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Feeder; +using namespace Generator; +using namespace Line; +using namespace LineUnits; +using namespace Load; +using namespace MemoryMap_lib; +using namespace MeterClass; +using namespace MeterElement; +using namespace PCElement; +using namespace PDELement; +using namespace ParserDel; +using namespace PointerList; +using namespace ReduceAlgs; +using namespace StackDef; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace EnergyMeter +{ + +TEnergyMeterObj::TEnergyMeterObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TEnergyMeterObj::TEnergyMeterObj(String ClassName) : inherited(ClassName) {} +TEnergyMeterObj::TEnergyMeterObj() {} + + +TEnergyMeterObj* ActiveEnergyMeterObj = nullptr; + +//{$UNDEF DEBUG} +const int NumPropsThisClass = 24; +double Delta_Hrs = 0.0; + // adjacency lists for PC and PD elements at each bus, built for faster searches +TAdjArray BusAdjPC; // also includes shunt PD elements +TAdjArray BusAdjPD; + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/*#inline*/ +int jiIndex(int i, int j) +{ + int result = 0; + result = (j - 1) * 3 + i; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure FOR all EnergyMeter objects + +TEnergyMeter::TEnergyMeter() + : FSaveDemandInterval(false), + FDI_Verbose(false), + SystemMeter(nullptr), + Do_OverloadReport(false), + Do_VoltageExceptionReport(false), + OverLoadFileIsOpen(false), + VoltageFileIsOpen(false) +{ + int Idx = 0; + Class_Name = "EnergyMeter"; + DSSClassType = DSSClassType + ENERGY_METER; + ActiveElement = 0; + + /*Initialice demand interval options to off*/ + OverLoadFileIsOpen = false; + VoltageFileIsOpen = false; + Do_OverloadReport = false; + Do_VoltageExceptionReport = false; + DI_Dir = ""; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + +//{$IFDEF MSWINDOWS} + //**** GeneratorClass := DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find('generator')); +//{$ENDIF} + SystemMeter = new TSystemMeter(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TEnergyMeter::~TEnergyMeter() +{ + delete SystemMeter; + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeter::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "element"; + PropertyName[2 - 1] = "terminal"; + PropertyName[3 - 1] = "action"; + PropertyName[4 - 1] = "option"; + PropertyName[5 - 1] = "kVAnormal"; + PropertyName[6 - 1] = "kVAemerg"; + PropertyName[7 - 1] = "peakcurrent"; + PropertyName[8 - 1] = "Zonelist"; + PropertyName[9 - 1] = "LocalOnly"; + PropertyName[10 - 1] = "Mask"; + PropertyName[11 - 1] = "Losses"; + PropertyName[12 - 1] = "LineLosses"; + PropertyName[13 - 1] = "XfmrLosses"; + PropertyName[14 - 1] = "SeqLosses"; + PropertyName[15 - 1] = "3phaseLosses"; + PropertyName[16 - 1] = "VbaseLosses"; // segregate losses by voltage base + PropertyName[17 - 1] = "PhaseVoltageReport"; // Compute Avg phase voltages in zone + PropertyName[18 - 1] = "Int_Rate"; + PropertyName[19 - 1] = "Int_Duration"; + PropertyName[20 - 1] = "SAIFI"; // Read only + PropertyName[21 - 1] = "SAIFIkW"; // Read only + PropertyName[22 - 1] = "SAIDI"; // Read only + PropertyName[23 - 1] = "CAIDI"; // Read only + PropertyName[24 - 1] = "CustInterrupts"; // Read only + +/* PropertyName^[11 - 1] := 'Feeder'; **** removed - not used*/ + PropertyHelp[1 - 1] = "Name (Full Object name) of element to which the monitor is connected."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the monitor is connected. " + "1 or 2, typically."; + PropertyHelp[3 - 1] = String("{Clear (reset) | Save | Take | Zonedump | Allocate | Reduce} ") + CRLF + + CRLF + + "(A)llocate = Allocate loads on the meter zone to match PeakCurrent." + + CRLF + + "(C)lear = reset all registers to zero" + + CRLF + + "(R)educe = reduces zone by merging lines (see Set Keeplist & ReduceOption)" + + CRLF + + "(S)ave = saves the current register values to a file." + + CRLF + + " File name is \"MTR_metername.CSV\"." + + CRLF + + "(T)ake = Takes a sample at present solution" + + CRLF + + "(Z)onedump = Dump names of elements in meter zone to a file" + + CRLF + + " File name is \"Zone_metername.CSV\"."; + PropertyHelp[4 - 1] = String("Enter a string ARRAY of any combination of the following. Options processed left-to-right:") + CRLF + + CRLF + + "(E)xcess : (default) UE/EEN is estimate of energy over capacity " + + CRLF + + "(T)otal : UE/EEN is total energy after capacity exceeded" + + CRLF + + "(R)adial : (default) Treats zone as a radial circuit" + + CRLF + + "(M)esh : Treats zone as meshed network (not radial)." + + CRLF + + "(C)ombined : (default) Load UE/EEN computed from combination of overload and undervoltage." + + CRLF + + "(V)oltage : Load UE/EEN computed based on voltage only." + + CRLF + + CRLF + + "Example: option=(E, R)"; + PropertyHelp[5 - 1] = "Upper limit on kVA load in the zone, Normal configuration. Default is 0.0 (ignored). " + "Overrides limits on individual lines for overload EEN. " + "With \"LocalOnly=Yes\" option, uses only load in metered branch."; + PropertyHelp[6 - 1] = "Upper limit on kVA load in the zone, Emergency configuration. Default is 0.0 (ignored). " + "Overrides limits on individual lines for overload UE. " + "With \"LocalOnly=Yes\" option, uses only load in metered branch."; + PropertyHelp[7 - 1] = "ARRAY of current magnitudes representing the peak currents measured at this location " + "for the load allocation function. Default is (400, 400, 400). Enter one current for each phase"; + PropertyHelp[8 - 1] = String("ARRAY of full element names for this meter's zone. Default is for meter to find it's own zone. " "If specified, DSS uses this list instead. Can access the names in a single-column text file. Examples: ") + CRLF + + CRLF + + "zonelist=[line.L1, transformer.T1, Line.L3 - 1] " + + CRLF + + "zonelist=(file=branchlist.txt)"; + PropertyHelp[9 - 1] = "{Yes | No} Default is NO. If Yes, meter considers only the monitored element " + "for EEN and UE calcs. Uses whole zone for losses."; + PropertyHelp[10 - 1] = "Mask for adding registers whenever all meters are totalized. Array of floating point numbers " + "representing the multiplier to be used for summing each register from this meter. " + "Default = (1, 1, 1, 1, ... ). You only have to enter as many as are changed (positional). " + "Useful when two meters monitor same energy, etc."; + PropertyHelp[11 - 1] = "{Yes | No} Default is YES. Compute Zone losses. If NO, then no losses at all are computed."; + PropertyHelp[12 - 1] = "{Yes | No} Default is YES. Compute Line losses. If NO, then none of the losses are computed."; + PropertyHelp[13 - 1] = "{Yes | No} Default is YES. Compute Transformer losses. If NO, transformers are ignored in loss calculations."; + PropertyHelp[14 - 1] = "{Yes | No} Default is YES. Compute Sequence losses in lines and segregate by line mode losses and zero mode losses."; + PropertyHelp[15 - 1] = "{Yes | No} Default is YES. Compute Line losses and segregate by 3-phase and other (1- and 2-phase) line losses. "; + PropertyHelp[16 - 1] = "{Yes | No} Default is YES. Compute losses and segregate by voltage base. If NO, then voltage-based tabulation is not reported."; + PropertyHelp[17 - 1] = "{Yes | No} Default is NO. Report min, max, and average phase voltages for the zone and tabulate by voltage base. " + "Demand Intervals must be turned on (Set Demand=true) and voltage bases must be defined for this property to take effect. " + "Result is in a separate report file."; + PropertyHelp[18 - 1] = "Average number of annual interruptions for head of the meter zone (source side of zone or feeder)."; + PropertyHelp[19 - 1] = "Average annual duration, in hr, of interruptions for head of the meter zone (source side of zone or feeder)."; + PropertyHelp[20 - 1] = "(Read only) Makes SAIFI result available via return on query (? energymeter.myMeter.SAIFI."; + PropertyHelp[21 - 1] = "(Read only) Makes SAIFIkW result available via return on query (? energymeter.myMeter.SAIFIkW."; + PropertyHelp[22 - 1] = "(Read only) Makes SAIDI result available via return on query (? energymeter.myMeter.SAIDI."; + PropertyHelp[23 - 1] = "(Read only) Makes CAIDI result available via return on query (? energymeter.myMeter.CAIDI."; + PropertyHelp[24 - 1] = "(Read only) Makes Total Customer Interrupts value result available via return on query (? energymeter.myMeter.CustInterrupts."; +/**** Not used in present version + PropertyHelp[11]:= '{Yes/True | No/False} Default is NO. If set to Yes, a Feeder object is created corresponding to ' + + 'the energymeter. Feeder is enabled if Radial=Yes; diabled if Radial=No. Feeder is ' + + 'synched automatically with the meter zone. Do not create feeders for zones in meshed transmission systems.'; +*****/ + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEnergyMeter::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TEnergyMeterObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEnergyMeter::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + bool DoRecalc = false; + + // continue parsing WITH contents of Parser + // continue parsing WITH contents of Parser + ActiveEnergyMeterObj = (TEnergyMeterObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveEnergyMeterObj); + result = 0; + DoRecalc = false; + /*# with ActiveEnergyMeterObj do */ + { + auto with0 = ActiveEnergyMeterObj; + with0->MeteredElementChanged = false; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 520); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->MeteredTerminal = Parser[ActorID]->MakeInteger_(); + break; /*Actions*/ + case 3: + { + Param = LowerCase(Param); + switch(Param[0]) + { + case L'a': + with0->AllocateLoad(ActorID); + break; + case L'c': + with0->ResetRegisters(); + break; + case L'r': + with0->ReduceZone(ActorID); + break; + case L's': + with0->SaveRegisters(ActorID); + break; + case L't': + with0->TakeSample(ActorID); + break; + case L'z': + with0->ZoneDump(ActorID); + break; + default: + ; + break; + } + } + break; + case 4: + ProcessOptions(Param); + break; + case 5: + with0->MaxZonekVA_Norm = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->MaxZonekVA_Emerg = Parser[ActorID]->MakeDouble_(); + break; + case 7: + Parser[ActorID]->ParseAsVector(with0->Fnphases, &(with0->SensorCurrent[0])); + break; // Inits to zero + case 8: + InterpretAndAllocStrArray(Param, with0->DefinedZoneListSize, with0->DefinedZoneList); + break; + case 9: + with0->LocalOnly = InterpretYesNo(Param); + break; + case 10: + InterpretRegisterMaskArray(with0->TotalsMask, ActorID); + break; + case 11: + with0->FLosses = InterpretYesNo(Param); + break; + case 12: + with0->FLineLosses = InterpretYesNo(Param); + break; + case 13: + with0->FXfmrLosses = InterpretYesNo(Param); + break; + case 14: + with0->FSeqLosses = InterpretYesNo(Param); + break; + case 15: + with0->F3PhaseLosses = InterpretYesNo(Param); + break; + case 16: + with0->FVBaseLosses = InterpretYesNo(Param); + break; + case 17: + with0->FPhaseVoltageReport = InterpretYesNo(Param); + break; + case 18: + with0->Source_NumInterruptions = Parser[ActorID]->MakeDouble_(); + break; // Annual interruptions for upline circuit + case 19: + with0->Source_IntDuration = Parser[ActorID]->MakeDouble_(); + break; // hours + case 20: + with0->Set_PropertyValue(20,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + case 21: + with0->Set_PropertyValue(21,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + case 22: + with0->Set_PropertyValue(22,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + case 23: + with0->Set_PropertyValue(23,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + case 24: + with0->Set_PropertyValue(24,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + /****11: HasFeeder := InterpretYesNo(Param); ***/ + default: + inherited::ClassEdit(ActiveEnergyMeterObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 2: + { + with0->MeteredElementChanged = true; + DoRecalc = true; + } + break; + /****11: If HasFeeder Then DoRecalc := True Else RemoveFeederObj; */ + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(DoRecalc) + with0->RecalcElementData(ActorID); // When some basic data have changed + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEnergyMeter::MakeLike(const String EnergyMeterName) +{ + int result = 0; + TEnergyMeterObj* OtherEnergyMeter = nullptr; + int i = 0; + result = 0; + /*See IF we can find this EnergyMeter name in the present collection*/ + OtherEnergyMeter = ((TEnergyMeterObj*) Find(EnergyMeterName)); + if(OtherEnergyMeter != nullptr) + /*# with ActiveEnergyMeterObj do */ + { + auto with0 = ActiveEnergyMeterObj; + int stop = 0; + with0->Set_NPhases(OtherEnergyMeter->Fnphases); + with0->Set_Nconds(OtherEnergyMeter->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherEnergyMeter->ElementName; + with0->MeteredElement = OtherEnergyMeter->MeteredElement; // Pointer to target circuit element + with0->MeteredTerminal = OtherEnergyMeter->MeteredTerminal; + with0->ExcessFlag = OtherEnergyMeter->ExcessFlag; + with0->MaxZonekVA_Norm = OtherEnergyMeter->MaxZonekVA_Norm; + with0->MaxZonekVA_Emerg = OtherEnergyMeter->MaxZonekVA_Emerg; + + // Reliability + with0->Source_NumInterruptions = OtherEnergyMeter->Source_NumInterruptions; + with0->Source_IntDuration = OtherEnergyMeter->Source_IntDuration; + FreeStringArray(with0->DefinedZoneList, with0->DefinedZoneListSize); + with0->DefinedZoneListSize = OtherEnergyMeter->DefinedZoneListSize; + with0->DefinedZoneList = AllocStringArray(with0->DefinedZoneListSize); + // Copy Strings over (actually incr ref count on string) + for(stop = with0->DefinedZoneListSize, i = 1; i <= stop; i++) + { + with0->DefinedZoneList[i] = OtherEnergyMeter->DefinedZoneList[i]; + } + with0->LocalOnly = OtherEnergyMeter->LocalOnly; + with0->VoltageUEOnly = OtherEnergyMeter->VoltageUEOnly; + + /*Boolean Flags*/ + with0->FLosses = OtherEnergyMeter->FLosses; + with0->FLineLosses = OtherEnergyMeter->FLineLosses; + with0->FXfmrLosses = OtherEnergyMeter->FXfmrLosses; + with0->FSeqLosses = OtherEnergyMeter->FSeqLosses; + with0->F3PhaseLosses = OtherEnergyMeter->F3PhaseLosses; + with0->FVBaseLosses = OtherEnergyMeter->FVBaseLosses; + with0->FPhaseVoltageReport = OtherEnergyMeter->FPhaseVoltageReport; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + if(i < 20) + // Skip Read Only properties + with0->Set_PropertyValue(i,OtherEnergyMeter->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in EnergyMeter MakeLike: \"") + EnergyMeterName + + "\" Not Found.", 521); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEnergyMeter::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TEnergyMeter.Init", -1); + result = 0; + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to reset their meter zones + +void TEnergyMeter::ResetMeterZonesAll(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + TDSSCktElement* pCktElement = nullptr; + TPDElement* PDElem = nullptr; + TPCElement* pcElem = nullptr; + int i = 0; + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + if(ActiveCircuit[ActorID]->EnergyMeters.get_myNumList() == 0) + return; // Do not do anything + + // initialize the Checked Flag FOR all circuit Elements + pCktElement = (TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get_First(); + while((pCktElement != nullptr)) + { + /*# with pCktElement do */ + { + auto with1 = pCktElement; + int stop = 0; + with1->Checked = false; + with1->IsIsolated = true; + for(stop = with1->Get_NTerms(), i = 1; i <= stop; i++) + { + with1->Terminals[i - 1].Checked = false; + } + } + pCktElement = (TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get_Next(); + } + + /*Clear some things that will be set by the Meter Zone*/ + PDElem = (TPDElement*) ActiveCircuit[ActorID]->PDElements.Get_First(); + while(PDElem != nullptr) + { + PDElem->MeterObj = nullptr; + PDElem->SensorObj = nullptr; + PDElem->ParentPDElement = nullptr; + PDElem = (TPDElement*) ActiveCircuit[ActorID]->PDElements.Get_Next(); + } + pcElem = (TPCElement*) ActiveCircuit[ActorID]->PCElements.Get_First(); + while(pcElem != nullptr) + { + pcElem->MeterObj = nullptr; + pcElem->SensorObj = nullptr; + pcElem = (TPCElement*) ActiveCircuit[ActorID]->PCElements.Get_Next(); + } + + // Set up the bus adjacency lists for faster searches to build meter zone lists. + BuildActiveBusAdjacencyLists(BusAdjPD, BusAdjPC, ActorID); + + //Set Hasmeter flag for all cktelements + SetHasMeterFlag(ActorID); + SensorClass[ActorID]->SetHasSensorFlag(); // Set all Sensor branch flags, too. + + // initialize the Checked Flag for all Buses + for(stop = ActiveCircuit[ActorID]->NumBuses, i = 1; i <= stop; i++) + { + ActiveCircuit[ActorID]->Buses[i - 1]->BusChecked = false; + } + for(stop = ActiveCircuit[ActorID]->EnergyMeters.get_myNumList(), i = 1; i <= stop; i++) + { + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get(i); + mtr->MakeMeterZoneLists(ActorID); + } + FreeAndNilBusAdjacencyLists(BusAdjPD, BusAdjPC); + } +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to reset + +void TEnergyMeter::ResetAll(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + String CasePath; + if(DIFilesAreOpen[ActorID]) + CloseAllDIFiles(ActorID); + if(FSaveDemandInterval) + { + CasePath = OutputDirectory[ActorID] + ActiveCircuit[ActorID]->get_FCaseName(); + /*Make directories to save data*/ + if(!DirectoryExists(CasePath)) + { + try + { + MkDir(CasePath); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error making Directory: \"") + CasePath + + "\". " + + (std::string) e.what(), 522); + } + } + DI_Dir = CasePath + DIRSEP_STR "DI_yr_" + Trim(IntToStr(ActiveCircuit[ActorID]->Solution->get_Fyear())); + if(!DirectoryExists(DI_Dir)) + { + try + { + MkDir(DI_Dir); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error making Demand Interval Directory: \"") + DI_Dir + + "\". " + + (std::string) e.what(), 523); + } + } + CreateFDI_Totals(ActorID); + } + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + mtr->ResetRegisters(); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + SystemMeter->Reset(); + + + // Reset Generator Objects, too + GeneratorClass->ResetRegistersAll(ActorID); + StorageClass[ActorID]->ResetRegistersAll(); +// Storage2Class[ActorID]->ResetRegistersAll(); + PVSystemClass[ActorID]->ResetRegistersAll(); +// PVSystem2Class[ActorID]->ResetRegistersAll(); +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to take a sample + +void TEnergyMeter::SampleAll(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + int i = 0; + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + mtr->TakeSample(ActorID); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + SystemMeter->TakeSample(ActorID); + if(FSaveDemandInterval) /*Write Totals Demand interval file*/ + { + int stop = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(TDI_MHandle[ActorID], with0->DynaVars.dblHour); + } + for (i = 0; i < NumEMRegisters; i++) + { + WriteintoMem(TDI_MHandle[ActorID], DI_RegisterTotals[i]); + } + std::string s(1, (Char)10); + WriteintoMemStr(TDI_MHandle[ActorID], s) ; + ClearDI_Totals(); + if(OverLoadFileIsOpen) + WriteOverloadReport(ActorID); + if(VoltageFileIsOpen) + WriteVoltageReport(ActorID); + } + + // Sample Generator ans Storage Objects, too + GeneratorClass->SampleAll(ActorID); + StorageClass[ActorID]->SampleAll(ActorID); // samples energymeter part of storage elements (not update) +// Storage2Class[ActorID]->SampleAll(ActorID); + PVSystemClass[ActorID]->SampleAll(ActorID); +// PVSystem2Class[ActorID]->SampleAll(ActorID); +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to take a sample + +void TEnergyMeter::SaveAll(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + mtr->SaveRegisters(ActorID); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + SystemMeter->Save(ActorID); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TEnergyMeter Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TEnergyMeterObj::TEnergyMeterObj(TDSSClass* ParClass, const String EnergyMeterName) + : inherited(ParClass), + FirstSampleAfterReset(false), + ExcessFlag(false), + ZoneIsRadial(false), + VoltageUEOnly(false), + LocalOnly(false), + HasFeeder(false), + FLosses(false), + FLineLosses(false), + FXfmrLosses(false), + FSeqLosses(false), + F3PhaseLosses(false), + FVBaseLosses(false), + FeederObj(nullptr), + DefinedZoneListSize(0), + MaxZonekVA_Norm(0.0), + MaxZonekVA_Emerg(0.0), + VPhaseReportFileIsOpen(false), + This_Meter_DIFileIsOpen(false), + DI_MHandle(nullptr), + PHV_MHandle(nullptr), + FPhaseVoltageReport(false), + BranchList(nullptr), + SequenceList(nullptr), + LoadList(nullptr), + SAIFI(0.0), + SAIFIkW(0.0), + SAIDI(0.0), + CAIDI(0.0), + CustInterrupts(0.0), + Source_NumInterruptions(0.0), + Source_IntDuration(0.0), + SectionCount(0), + ActiveSection(0) +{ + int i = 0; + int stop = 0; + VPhaseAccumCount.clear(); + RegisterNames.resize(NumEMRegisters); + Set_Name(LowerCase(EnergyMeterName)); + DSSObjType = ParClass->DSSClassType; //ENERGY_METER; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors in base class + ExcessFlag = true; // Default to Excess energy FOR UE + ElementName = String("Vsource.") + ((TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get(1))->get_Name(); // Default to first circuit element (source) + MeteredElement = nullptr; + BranchList = nullptr; // initialize to NIL, set later when inited + SequenceList = NULL; + LoadList = NULL; + This_Meter_DIFileIsOpen = false; + VPhaseReportFileIsOpen = false; + InitPropertyValues(0); + DefinedZoneList = NULL; + VBaseTotalLosses.clear(); + VBaseLineLosses.clear(); + VBaseLoadLosses.clear(); + VBaseNoLoadLosses.clear(); + VBaseLoad.clear(); + VBaseList.clear(); + VBaseCount = 0; + MaxVBaseCount = 0; + VphaseMax.clear(); + VPhaseMin.clear(); + VPhaseAccum.clear(); + AssumeRestoration = false; + + // Max zone kW limits ignored unless the user provides a rating + MaxZonekVA_Norm = 0.0; + MaxZonekVA_Emerg = 0.0; + + // Zone reliability variables + SAIFI = 0.0; // For this Zone + SAIFIkW = 0.0; + SAIDI = 0.0; + CAIDI = 0.0; + CustInterrupts = 0.0; + Source_NumInterruptions = 0.0; // Annual interruptions for upline circuit + Source_IntDuration = 0.0; // Aver interruption duration of upline circuit + ZoneIsRadial = true; + HasFeeder = false; // Not used; leave as False + FeederObj = nullptr; // initialize to not assigned + DefinedZoneList = NULL; + DefinedZoneListSize = 0; + FLosses = true; /*Loss Reporting switches*/ + FLineLosses = true; + FXfmrLosses = true; + FSeqLosses = true; + F3PhaseLosses = true; + FVBaseLosses = true; + FPhaseVoltageReport = false; + VBaseList.clear(); + VBaseTotalLosses.clear(); + VBaseLineLosses.clear(); + VBaseLoadLosses.clear(); + VBaseNoLoadLosses.clear(); + VBaseLoad.clear(); + VBaseCount = 0; + MaxVBaseCount = ((NumEMRegisters - Reg_VBaseStart) / 5); + VBaseList.resize( MaxVBaseCount + 1 ); + VBaseTotalLosses.resize(MaxVBaseCount + 1); + VBaseLineLosses.resize(MaxVBaseCount + 1); + VBaseLoadLosses.resize(MaxVBaseCount + 1); + VBaseNoLoadLosses.resize(MaxVBaseCount + 1); + VBaseLoad.resize(MaxVBaseCount + 1); + +// Init pointers to Nil before allocating + VphaseMax.clear(); + VPhaseMin.clear(); + VPhaseAccum.clear(); + VPhaseAccumCount.clear(); + + // Arrays for phase voltage report + VphaseMax.resize(3 * MaxVBaseCount + 1); + VPhaseMin.resize(3 * MaxVBaseCount + 1); + VPhaseAccum.resize(3 * MaxVBaseCount + 1); + VPhaseAccumCount.resize(3 * MaxVBaseCount + 1); + LocalOnly = false; + VoltageUEOnly = false; + +//*************No append files by default*************************************** + OV_Append[ActiveActor] = false; + VR_Append[ActiveActor] = false; + DI_Append[ActiveActor] = false; + SDI_Append[ActiveActor] = false; + TDI_Append[ActiveActor] = false; + SM_Append[ActiveActor] = false; + EMT_Append[ActiveActor] = false; + PHV_Append[ActiveActor] = false; + FM_Append[ActiveActor] = false; + + // Set Register names that correspond to the register quantities + RegisterNames[1 - 1] = "kWh"; + RegisterNames[2 - 1] = "kvarh"; + RegisterNames[3 - 1] = "Max kW"; + RegisterNames[4 - 1] = "Max kVA"; + RegisterNames[5 - 1] = "Zone kWh"; + RegisterNames[6 - 1] = "Zone kvarh"; + RegisterNames[7 - 1] = "Zone Max kW"; + RegisterNames[8 - 1] = "Zone Max kVA"; + RegisterNames[9 - 1] = "Overload kWh Normal"; + RegisterNames[10 - 1] = "Overload kWh Emerg"; + RegisterNames[11 - 1] = "Load EEN"; + RegisterNames[12 - 1] = "Load UE"; + RegisterNames[13 - 1] = "Zone Losses kWh"; + RegisterNames[14 - 1] = "Zone Losses kvarh"; + RegisterNames[15 - 1] = "Zone Max kW Losses"; + RegisterNames[16 - 1] = "Zone Max kvar Losses"; + RegisterNames[17 - 1] = "Load Losses kWh"; + RegisterNames[18 - 1] = "Load Losses kvarh"; + RegisterNames[19 - 1] = "No Load Losses kWh"; + RegisterNames[20 - 1] = "No Load Losses kvarh"; + RegisterNames[21 - 1] = "Max kW Load Losses"; + RegisterNames[22 - 1] = "Max kW No Load Losses"; + RegisterNames[23 - 1] = "Line Losses"; + RegisterNames[24 - 1] = "Transformer Losses"; + RegisterNames[25 - 1] = "Line Mode Line Losses"; + RegisterNames[26 - 1] = "Zero Mode Line Losses"; + RegisterNames[27 - 1] = "3-phase Line Losses"; + RegisterNames[28 - 1] = "1- and 2-phase Line Losses"; + RegisterNames[29 - 1] = "Gen kWh"; + RegisterNames[30 - 1] = "Gen kvarh"; + RegisterNames[31 - 1] = "Gen Max kW"; + RegisterNames[32 - 1] = "Gen Max kVA"; + /*Registers for capturing losses by base voltage, names assigned later*/ + for(stop = NumEMRegisters, i = Reg_VBaseStart + 1; i < stop; i++) + { + RegisterNames[i] = ""; + } + ResetRegisters(); + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + TotalsMask[i - 1] = 1.0; + } + AllocateSensorArrays(); + for(i = 0; i < Fnphases; i++) + { + SensorCurrent[i] = 400.0; + } + FeederSections.clear(); + ActiveSection = 0; + DI_MHandle = nullptr; + TDI_MHandle[ActiveActor] = nullptr; + SM_MHandle[ActiveActor] = nullptr; + EMT_MHandle[ActiveActor] = nullptr; + PHV_MHandle = nullptr; + FM_MHandle[ActiveActor] = nullptr; + ZonePCE.resize( 1 ); + ZonePCE[0] = ""; + + // RecalcElementData; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TEnergyMeterObj::~TEnergyMeterObj() +{ + int i = 0; + int stop = 0; + VBaseList.clear(); + VBaseTotalLosses.clear(); + VBaseLineLosses.clear();; + VBaseLoadLosses.clear();; + VBaseNoLoadLosses.clear();; + VBaseLoad.clear();; + // Arrays for phase voltage report + VphaseMax.clear();; + VPhaseMin.clear();; + VPhaseAccum.clear();; + VPhaseAccumCount.clear();; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + RegisterNames[i - 1] = ""; + } + if(ASSIGNED(BranchList)) + delete BranchList; + if(ASSIGNED(SequenceList)) + delete SequenceList; + if(ASSIGNED(LoadList)) + delete LoadList; + FreeStringArray(DefinedZoneList, DefinedZoneListSize); + if(!(FeederSections.empty())) + FeederSections.clear(); + if(DI_MHandle != nullptr) + delete DI_MHandle; + if (SM_MHandle[ActiveActor] != nullptr) + { + delete SM_MHandle[ActiveActor]; + SM_MHandle[ActiveActor] = nullptr; // This vector is managed by DSSGlobals and not our object, so be sure to indicate we've freed this memory. + } + if(EMT_MHandle[ActiveActor] != nullptr) + { + delete EMT_MHandle[ActiveActor]; + EMT_MHandle[ActiveActor] = nullptr; // This vector is managed by DSSGlobals and not our object, so be sure to indicate we've freed this memory. + } + if(PHV_MHandle != nullptr) + delete PHV_MHandle; + if(FM_MHandle[ActiveActor] != nullptr) + { + delete FM_MHandle[ActiveActor]; + FM_MHandle[ActiveActor] = nullptr; // This vector is managed by DSSGlobals and not our object, so be sure to indicate we've freed this memory. + } + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Monitored element must already exist + { + MeteredElement = (TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex); // Get pointer to metered element + /*MeteredElement must be a PDElement*/ + if(!(dynamic_cast(MeteredElement))) + { + MeteredElement = nullptr; // element not found + DoErrorMsg(String("EnergyMeter: \"") + this->get_Name() + "\"", String("Circuit Element \"") + ElementName + + "\" is not a Power Delivery (PD) element.", " Element must be a PD element.", 525); + return; + } + if(MeteredTerminal > MeteredElement->Get_NTerms()) + { + DoErrorMsg(String("EnergyMeter: \"") + get_Name() + "\"", String("Terminal no. \"") + IntToStr(MeteredTerminal) + "\" does not exist.", "Respecify terminal no.", 524); + } + else + { + if(MeteredElementChanged) + // Sets name of i-th terminal's connected bus in monitor's buslist + // This value will be used to set the NodeRef array (see TakeSample) + { + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + AllocateSensorArrays(); + + // If we come through here, throw branchlist away + if(BranchList != nullptr) + delete BranchList; + BranchList = nullptr; + } + + /****If HasFeeder Then MakeFeederObj; // OK to call multiple times */ + } + } + else + { + MeteredElement = nullptr; // element not found + DoErrorMsg(String("EnergyMeter: \"") + this->get_Name() + "\"", String("Circuit Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 525); + } +} + +void TEnergyMeterObj::MakePosSequence(int ActorID) +{ + if(MeteredElement != nullptr) + { + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + AllocateSensorArrays(); + if(BranchList != nullptr) + delete BranchList; + BranchList = nullptr; + } + /***If HasFeeder Then MakeFeederObj;*/ + TDSSCktElement::MakePosSequence(ActorID); +} + +String TEnergyMeterObj::MakeVPhaseReportFileName(int ActorID) +{ + String result; + result = EnergyMeterClass[ActorID]->DI_Dir + + DIRSEP_STR + + get_Name() + + "_PhaseVoltageReport_" + + IntToStr(ActorID) + + ".CSV"; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::ResetRegisters() +{ + int i = 0; + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Registers[i - 1] = 0.0; + } + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Derivatives[i - 1] = 0.0; + } + /*Initialize DragHand registers to some big negative number*/ + Registers[Reg_MaxkW] = -1.0e50; + Registers[Reg_MaxkVA] = -1.0e50; + Registers[Reg_ZoneMaxkW] = -1.0e50; + Registers[Reg_ZoneMaxkVA] = -1.0e50; + Registers[Reg_MaxLoadLosses] = -1.0e50; + Registers[Reg_MaxNoLoadLosses] = -1.0e50; + Registers[Reg_LossesMaxkW] = -1.0e50; + Registers[Reg_LossesMaxkvar] = -1.0e50; + Registers[Reg_GenMaxkW] = -1.0e50; + Registers[Reg_GenMaxkVA] = -1.0e50; + FirstSampleAfterReset = true; // initialize for trapezoidal integration + // Removed .. open in solution loop See Solve Yearly If EnergyMeterClass.SaveDemandInterval Then OpenDemandIntervalFile; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::CalcYPrim(int ActorID) +{ + + + // YPrim is all zeros. Just leave as NIL so it is ignored. +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::SaveRegisters(int ActorID) +{ + String CSVName; + TTextRec f = {}; + int i = 0; + try + { + CSVName = String("MTR_") + get_Name() + ".CSV"; + AssignFile(f, GetOutputDirectory() + CSVName); + Rewrite(f); + IOResultToException(); + GlobalResult = CSVName; + SetLastResultFile(CSVName); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error opening Meter File \"") + CRLF + + CSVName + + "\": " + + (std::string) e.what(), 526); + return; + } + } + try + +// Writeln(F,'**** NEW RECORD ****'); + { + int stop = 0; + { Write(f, "Year, "); Write(f, ActiveCircuit[ActorID]->Solution->get_Fyear(), 0); WriteLn(f, L','); } + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + { Write(f, L'\"'); Write(f, RegisterNames[i - 1]); Write(f, "\","); WriteLn(f, Registers[i - 1], 0, 0); } + } +/* } + __finally + {*/ + CloseFile(f); + } + catch (...) + { + // + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::Integrate(int reg, double Deriv, double Interval, int ActorID) +{ + if(ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + Registers[reg] = Registers[reg] + 0.5 * Interval * (Deriv + Derivatives[reg]); + } + else + /*Plain Euler integration*/ + { + Registers[reg] = Registers[reg] + Interval * Deriv; + } + +/* Set the derivatives so that the proper value shows up in Demand Interval Files + and prepare for next time step in Trapezoidal integration */ + Derivatives[reg] = Deriv; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Update registers from metered zone +// Assumes one time period has taken place since last sample. + +void TEnergyMeterObj::TakeSample(int ActorID) +{ + int i = 0; + int j = 0; + int l = 0; + int Idx = 0; // Lines only for now + complex S_Local = CZero; + complex S_Totallosses = CZero; + complex S_LoadLosses = CZero; + complex S_NoLoadLosses = CZero; + complex TotalLoadLosses = CZero; + complex TotalNoLoadLosses = CZero; + complex TotalLineLosses = CZero; + complex TotalTransformerLosses = CZero; + complex TotalLineModeLosses = CZero; + complex TotalZeroModeLosses = CZero; + complex Total3phaseLosses = CZero; + complex Total1phaseLosses = CZero; + complex TotalLosses = CZero; + TPDElement* CktElem = nullptr; + TPDElement* ParenElem = nullptr; + TPCElement* pcElem = nullptr; + TLoadObj* pLoad = nullptr; + TGeneratorObj* pGen = nullptr; + // doubles + double MaxExcesskWNorm = 0.0; + double MaxExcesskWEmerg = 0.0; + double EEN = 0.0; + double UE = 0.0; + double ZonekW = 0.0; + double TotalZonekW = 0.0; + double TotalZonekvar = 0.0; + double TotalLoad_EEN = 0.0; + double TotalLoad_UE = 0.0; + double TotalGenkw = 0.0; + double TotalGenkvar = 0.0; + double LoadkVA = 0.0; + double GenkVA = 0.0; + double S_Local_kVA = 0.0; + double load_kw = 0.0; + complex S_PosSeqLosses = CZero; + complex S_ZeroSeqLosses = CZero; + complex S_NegSeqLosses = CZero; + double puV = 0.0; + +// Compute energy in branch to which meter is connected + + //----MeteredElement.ActiveTerminalIdx := MeteredTerminal; // needed for Excess kVA calcs + int stop = 0; + S_Local = cmulreal(MeteredElement->Get_Power(MeteredTerminal, ActorID), 0.001); + S_Local_kVA = cabs(S_Local); + Delta_Hrs = ActiveCircuit[ActorID]->Solution->IntervalHrs; + Integrate(Reg_kWh, S_Local.re, Delta_Hrs, ActorID); // Accumulate the power + Integrate(Reg_kvarh, S_Local.im, Delta_Hrs, ActorID); + SetDragHandRegister(Reg_MaxkW, S_Local.re); // 3-10-04 removed abs() + SetDragHandRegister(Reg_MaxkVA, S_Local_kVA); + +// Compute Maximum overload energy in all branches in zone +// and mark all load downline from an overloaded branch as unserved +// If localonly, check only metered element + TotalLosses = CZero; // Initialize loss accumulators + TotalLoadLosses = CZero; + TotalNoLoadLosses = CZero; + TotalLineLosses = CZero; + TotalLineModeLosses = CZero; + TotalZeroModeLosses = CZero; + Total3phaseLosses = CZero; + Total1phaseLosses = CZero; + TotalTransformerLosses = CZero; + + // Init all voltage base loss accumulators + for(i = 1; i <= MaxVBaseCount; i++) + { + VBaseTotalLosses[i] = 0.0; + VBaseLineLosses[i] = 0.0; + VBaseLoadLosses[i] = 0.0; + VBaseNoLoadLosses[i] = 0.0; + VBaseLoad[i] = 0.0; + } + + // Phase Voltage arrays + if(FPhaseVoltageReport) + { + for(i = 1; i <= MaxVBaseCount; i++) + { + if((VBaseList)[i] > 0.0) + { + int stop1 = 0; + for(stop1 = 3, j = 1; j <= stop1; j++) + { + VphaseMax[jiIndex(j, i)] = 0.0; + VPhaseMin[jiIndex(j, i)] = 9999.0; + VPhaseAccum[jiIndex(j, i)] = 0.0; + VPhaseAccumCount[jiIndex(j, i)] = 0; // Keep track of counts for average + } + } + } + } + CktElem = (TPDElement*) BranchList->Get_First(); + MaxExcesskWNorm = 0.0; + MaxExcesskWEmerg = 0.0; + + /*--------------------------------------------------------------------------*/ + /*------------------------ Local Zone Only --------------------------------*/ + /*--------------------------------------------------------------------------*/ + if(LocalOnly) + { + CktElem = (TPDElement*) MeteredElement; + MaxExcesskWNorm = Abs( CktElem->Get_ExcessKVANorm(MeteredTerminal,ActorID).re); + MaxExcesskWEmerg = Abs( CktElem->Get_ExcessKVAEmerg(MeteredTerminal, ActorID).re); + } + else + { + while(CktElem != nullptr) + + /*--------------------------------------------------------------------------*/ + /*--------Cyle Through Entire Zone Setting EEN/UE --------------------------*/ + /*--------------------------------------------------------------------------*/ // loop thru all ckt elements on zone + { + /*# with CktElem do */ + { + auto with0 = CktElem; + with0->Set_ActiveTerminal(BranchList->PresentBranch->FromTerminal); + // Invoking this property sets the Overload_UE flag in the PD Element + EEN = Abs( with0->Get_ExcessKVANorm(with0->get_FActiveTerminal(),ActorID).re); + UE = Abs( with0->Get_ExcessKVAEmerg(with0->get_FActiveTerminal(),ActorID).re); + } + + /*For radial circuits just keep the maximum overload; for mesh, add 'em up*/ + if(ZoneIsRadial) + { + if(UE > MaxExcesskWEmerg) + MaxExcesskWEmerg = UE; + if(EEN > MaxExcesskWNorm) + MaxExcesskWNorm = EEN; + } + else + { + MaxExcesskWEmerg = MaxExcesskWEmerg + UE; + MaxExcesskWNorm = MaxExcesskWNorm + EEN; + } + + // Even if this branch is not overloaded, if the parent element is overloaded + // mark load on this branch as unserved also + // Use the larger of the two factors + ParenElem = ((TPDElement*) BranchList->Get_Parent()); + if(ParenElem != nullptr) + { + vector myVec0 = { CktElem->OverLoad_EEN, ParenElem->OverLoad_EEN }; + CktElem->OverLoad_EEN = MaxValue(&myVec0); + vector myVec1 = { CktElem->Overload_UE, ParenElem->Overload_UE }; + CktElem->Overload_UE = MaxValue(&myVec1); + } + + // Mark loads (not generators) by the degree of overload if the meter's zone is to be considered radial + // This overrides and supercedes the load's own determination of unserved based on voltage + // If voltage only is to be used for Load UE/EEN, don't mark (set to 0.0 and load will calc UE based on voltage) + pcElem = (TPCElement*) BranchList->Get_FirstObject(); + while((pcElem != nullptr)) + { + if( ( ( (TDSSCktElement*) pcElem )->DSSObjType & CLASSMASK) == LOAD_ELEMENT) + { + pLoad = (TLoadObj*) pcElem; + if((CktElem->OverLoad_EEN > 0.0) && (ZoneIsRadial) && !(VoltageUEOnly)) + pLoad->EEN_Factor = CktElem->OverLoad_EEN; + else + pLoad->EEN_Factor = 0.0; + if((CktElem->Overload_UE > 0.0) && (ZoneIsRadial) && !(VoltageUEOnly)) + pLoad->UE_Factor = CktElem->Overload_UE; + else + pLoad->UE_Factor = 0.0; + } + pcElem = ((TPCElement*) BranchList->Get_NextObject()); + } + CktElem = ((TPDElement*) BranchList->Get_Forward()); + } + + + // Get the Losses, and unserved bus energies + } + + TotalZonekW = 0.0; + TotalZonekvar = 0.0; + TotalLoad_EEN = 0.0; + TotalLoad_UE = 0.0; + TotalGenkw = 0.0; + TotalGenkvar = 0.0; + + + /*--------------------------------------------------------------------------*/ + /*-------- Cycle Through Zone Accumulating Load and Losses --------*/ + /*--------------------------------------------------------------------------*/ + CktElem = (TPDElement*) BranchList->Get_First(); + while ((CktElem != nullptr)) + { + TLoadObj* pLoad = nullptr; + TGeneratorObj* pGen = nullptr; + pcElem = (TPCElement*)BranchList->Get_FirstObject(); + while (pcElem != nullptr) + { + int myElem = pcElem->DSSObjType & CLASSMASK; + switch (myElem) + { + case LOAD_ELEMENT: + if (!LocalOnly) + { + pLoad = (TLoadObj*)pcElem; + load_kw = Accumulate_Load(pLoad, TotalZonekW, TotalZonekvar, TotalLoad_EEN, TotalLoad_UE, ActorID); + if (FVBaseLosses) + { + auto with1 = BranchList->PresentBranch; + if (with1->VoltBaseIndex > 0) + VBaseLoad[with1->VoltBaseIndex] = VBaseLoad[with1->VoltBaseIndex] + load_kw; + } + } + break; + case GEN_ELEMENT: + pGen = (TGeneratorObj*)pcElem; + Accumulate_Gen(pGen, TotalGenkw, TotalGenkvar, ActorID); + break; + default: + { + /* {Ignore other types of PC Elements}*/ + } + break; + } + pcElem = (TPCElement*)BranchList->Get_NextObject(); + } + if(FLosses) // Compute and Report Losses + + /*Get losses from the present circuit element*/ + { + CktElem->GetLosses(S_Totallosses, S_LoadLosses, S_NoLoadLosses, ActorID); // returns watts, vars + /*Convert to kW*/ + cmulrealaccum(S_Totallosses, 0.001); + cmulrealaccum(S_LoadLosses, 0.001); + cmulrealaccum(S_NoLoadLosses, 0.001); + /*Update accumulators*/ + caccum(TotalLosses, S_Totallosses); // Accumulate total losses in meter zone + caccum(TotalLoadLosses, S_LoadLosses); // Accumulate total load losses in meter zone + caccum(TotalNoLoadLosses, S_NoLoadLosses); // Accumulate total no load losses in meter zone + + /*Line and Transformer Elements*/ + if(IslineElement((TDSSCktElement*) CktElem) && FLineLosses) + { + caccum(TotalLineLosses, S_Totallosses); // Accumulate total losses in meter zone + if(FSeqLosses) + { + CktElem->GetSeqLosses(S_PosSeqLosses, S_NegSeqLosses, S_ZeroSeqLosses, ActorID); + caccum(S_PosSeqLosses, S_NegSeqLosses); // add line modes together + cmulrealaccum(S_PosSeqLosses, 0.001); // convert to kW + cmulrealaccum(S_ZeroSeqLosses, 0.001); + caccum(TotalLineModeLosses, S_PosSeqLosses); + caccum(TotalZeroModeLosses, S_ZeroSeqLosses); + } + /*Separate Line losses into 3- and "1-phase" losses*/ + if(F3PhaseLosses) + { + if(CktElem->Get_NPhases() == 3) + caccum(Total3phaseLosses, S_Totallosses); + else + caccum(Total1phaseLosses, S_Totallosses); + } + } + else + { + if(IsTransformerElement(CktElem) && FXfmrLosses) + { + caccum(TotalTransformerLosses, S_Totallosses); // Accumulate total losses in meter zone + } + } + if(FVBaseLosses) + /*# with BranchList.PresentBranch do */ + { + auto with2 = BranchList->PresentBranch; + if(with2->VoltBaseIndex > 0) + { + VBaseTotalLosses[with2->VoltBaseIndex] = VBaseTotalLosses[with2->VoltBaseIndex] + S_Totallosses.re; + if(IslineElement(CktElem)) + VBaseLineLosses[with2->VoltBaseIndex] = VBaseLineLosses[with2->VoltBaseIndex] + S_Totallosses.re; + else + { + if(IsTransformerElement(CktElem)) + { + VBaseLoadLosses[with2->VoltBaseIndex] = VBaseLoadLosses[with2->VoltBaseIndex] + S_LoadLosses.re; + VBaseNoLoadLosses[with2->VoltBaseIndex] = VBaseNoLoadLosses[with2->VoltBaseIndex] + S_NoLoadLosses.re; + } + } + } + } + + // Compute min, max, and average pu voltages for 1st 3 phases (nodes designated 1, 2, or 3) + if(FPhaseVoltageReport) + /*# with BranchList.PresentBranch do */ + { + auto with3 = BranchList->PresentBranch; + if(with3->VoltBaseIndex > 0) + /*# with ActiveCircuit[ActorID] do */ + { + + if(ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->kVBase > 0.0) + { + int stop = 0; + for(stop = ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->get_FNumNodesThisBus(), i = 1; i <= stop; i++) + { + j = ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->GetNum(i); + if((j > 0) && (j < 4)) + { + if(!ADiakoptics || (ActorID == 1)) + puV = cabs(ActiveCircuit[ActorID]->Solution->NodeV[ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->GetRef(i)]) / ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->kVBase; + else + puV = cabs(ActiveCircuit[ActorID]->Solution->VoltInActor1(ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->GetRef(i))) / ActiveCircuit[ActorID]->Buses[with3->FromBusReference - 1]->kVBase; + Idx = jiIndex(j, with3->VoltBaseIndex); + if(puV > (VphaseMax)[Idx]) + { + (VphaseMax)[jiIndex(j, with3->VoltBaseIndex)] = puV; + // VmaxBus := FromBusReference; + } + if(puV < (VPhaseMin)[Idx]) + { + (VPhaseMin)[jiIndex(j, with3->VoltBaseIndex)] = puV; + // VminBus := FromBusReference; + } + DblInc((VPhaseAccum)[jiIndex(j, with3->VoltBaseIndex)], puV); + ++(VPhaseAccumCount)[jiIndex(j, with3->VoltBaseIndex)]; // Keep track of counts for average + } + } + } + } + } + } /*If FLosses*/ + CktElem = ((TPDElement*) BranchList->Get_Forward()); + } + + /*NOTE: Integrate proc automatically sets derivatives array*/ + Integrate(Reg_LoadEEN, TotalLoad_EEN, Delta_Hrs, ActorID); + Integrate(Reg_LoadUE, TotalLoad_UE, Delta_Hrs, ActorID); + + /*Accumulate losses in appropriate registers*/ + Integrate(Reg_ZoneLosseskWh, TotalLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_ZoneLosseskvarh, TotalLosses.im, Delta_Hrs, ActorID); + Integrate(Reg_LoadLosseskWh, TotalLoadLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_LoadLosseskvarh, TotalLoadLosses.im, Delta_Hrs, ActorID); + Integrate(Reg_NoLoadLosseskWh, TotalNoLoadLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_NoLoadLosseskvarh, TotalNoLoadLosses.im, Delta_Hrs, ActorID); + Integrate(Reg_LineLosseskWh, TotalLineLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_LineModeLineLoss, TotalLineModeLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_ZeroModeLineLoss, TotalZeroModeLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_3_phaseLineLoss, Total3phaseLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_1_phaseLineLoss, Total1phaseLosses.re, Delta_Hrs, ActorID); + Integrate(Reg_TransformerLosseskWh, TotalTransformerLosses.re, Delta_Hrs, ActorID); + for(i = 1; i <= MaxVBaseCount; i++) + { + Integrate(Reg_VBaseStart + i, VBaseTotalLosses[i], Delta_Hrs, ActorID); + Integrate(Reg_VBaseStart + (1 * MaxVBaseCount) + i, VBaseLineLosses[i], Delta_Hrs, ActorID); + Integrate(Reg_VBaseStart + (2 * MaxVBaseCount) + i, VBaseLoadLosses[i], Delta_Hrs, ActorID); + Integrate(Reg_VBaseStart + (3 * MaxVBaseCount) + i, VBaseNoLoadLosses[i], Delta_Hrs, ActorID); + Integrate(Reg_VBaseStart + (4 * MaxVBaseCount) + i, VBaseLoad[i], Delta_Hrs, ActorID); + } + + + /*--------------------------------------------------------------------------*/ + /*--------------- Total Zone Load and Generation -------------------------*/ + /*--------------------------------------------------------------------------*/ + Integrate(Reg_ZonekWh, TotalZonekW, Delta_Hrs, ActorID); + Integrate(Reg_Zonekvarh, TotalZonekvar, Delta_Hrs, ActorID); + Integrate(Reg_GenkWh, TotalGenkw, Delta_Hrs, ActorID); + Integrate(Reg_Genkvarh, TotalGenkvar, Delta_Hrs, ActorID); + GenkVA = sqrt(Sqr(TotalGenkvar) + Sqr(TotalGenkw)); + LoadkVA = sqrt(Sqr(TotalZonekvar) + Sqr(TotalZonekW)); + + /*--------------------------------------------------------------------------*/ + /*--------------- Set Drag Hand Registers ------------------------------*/ + /*--------------------------------------------------------------------------*/ + SetDragHandRegister(Reg_LossesMaxkW, Abs(TotalLosses.re)); + SetDragHandRegister(Reg_LossesMaxkvar, Abs(TotalLosses.im)); + SetDragHandRegister(Reg_MaxLoadLosses, Abs(TotalLoadLosses.re)); + SetDragHandRegister(Reg_MaxNoLoadLosses, Abs(TotalNoLoadLosses.re)); + SetDragHandRegister(Reg_ZoneMaxkW, TotalZonekW); // Removed abs() 3-10-04 + SetDragHandRegister(Reg_ZoneMaxkVA, LoadkVA); + /*Max total generator registers*/ + SetDragHandRegister(Reg_GenMaxkW, TotalGenkw); // Removed abs() 3-10-04 + SetDragHandRegister(Reg_GenMaxkVA, GenkVA); + + /*--------------------------------------------------------------------------*/ + /*--------------------- Overload Energy ---------------------------------*/ + /*--------------------------------------------------------------------------*/ + /*Overload energy for the entire zone*/ + if(LocalOnly) + ZonekW = S_Local.re; + else + ZonekW = TotalZonekW; + + /*Either the max excess kW of any PD element or the excess over zone limits*/ + + /*regs 9 and 10*/ + /*Fixed these formulas 2-7-07 per discussions with Daniel Brooks */ + if(MaxZonekVA_Norm > 0.0) + { + if(S_Local_kVA == 0.0) + S_Local_kVA = MaxZonekVA_Norm; + std::vector myVec3 = { 0.0, (ZonekW * (1.0 - MaxZonekVA_Norm / S_Local_kVA) ) }; + Integrate(Reg_OverloadkWhNorm, MaxValue(&myVec3), Delta_Hrs, ActorID); + } + else + { + Integrate(Reg_OverloadkWhNorm, MaxExcesskWNorm, Delta_Hrs, ActorID); + } + if(MaxZonekVA_Emerg > 0.0) + { + if(S_Local_kVA == 0.0) + S_Local_kVA = MaxZonekVA_Emerg; + std::vector myVec4 = { 0.0, ( ZonekW * ( 1.0 - MaxZonekVA_Emerg / S_Local_kVA ) ) }; + Integrate(Reg_OverloadkWhEmerg, MaxValue(&myVec4), Delta_Hrs, ActorID); + } + else + { + Integrate(Reg_OverloadkWhEmerg, MaxExcesskWEmerg, Delta_Hrs, ActorID); + } + FirstSampleAfterReset = false; + if(EnergyMeterClass[ActorID]->Get_SaveDemandInterval(ActorID)) + WriteDemandIntervalData(ActorID); +} + +/*---------------------------------------------------------------------------------*/ + +void TEnergyMeterObj::TotalupDownstreamCustomers() +{ + int i = 0; + /*, Accumulator*/ + // PresentNode: TCktTreeNode; + TPDElement* CktElem = nullptr; + int stop = 0; + if(!ASSIGNED(BranchList)) + { + DoSimpleMsg("Meter Zone Lists need to be built. Do Solve or Makebuslist first!", 529); + return; + } + + /*Init totsls and checked flag*/ + CktElem = (TPDElement*) SequenceList->Get_First(); + while(CktElem != nullptr) + { + ( (TDSSCktElement*) CktElem )->Checked = false; + CktElem->BranchTotalCustomers = 0; + CktElem = (TPDElement*) SequenceList->Get_Next(); + } + + /*This algorithm could be made more efficient with a Sequence list*/ + /********* + For i := 1 to Branchlist.ZoneEndsList.NumEnds Do + Begin + {Busref := } Branchlist.ZoneEndsList.Get(i, PresentNode); + If PresentNode <> Nil Then + Begin + CktElem := PresentNode.CktObject; + if Not CktElem.Checked then // don't do a zone end element more than once + Begin + CktElem.Checked := TRUE; + Accumulator := CktElem.NumCustomers; + Repeat {Trace back to the source} + + Inc(CktElem.TotalCustomers, Accumulator); + PresentNode := PresentNode.Get_Parent(); + If PresentNode=Nil Then Break; + CktElem := PresentNode.CktObject; + If not CktElem.Checked Then Begin // avoid double counting + Inc(Accumulator, CktElem.NumCustomers); + CktElem.Checked := TRUE; + End; + + Until FALSE; + End; + End; + End; {For} + *******/ + + // Backward Sweep - Order is guaranteed to process end branches first + // sum numcustomers branch by branch + for(stop = 1, i = SequenceList->get_myNumList(); i >= stop; i--) + { + CktElem = (TPDElement*) SequenceList->Get(i); + if(!( (TDSSCktElement*) CktElem )->Checked) + /*# with CktElem do */ + { + auto with0 = CktElem; // Avoid double counting + ( (TDSSCktElement*) CktElem )->Checked = true; + with0->BranchTotalCustomers += with0->BranchNumCustomers; + if (with0->ParentPDElement != nullptr) + { + if (!(with0->HasOCPDevice && AssumeRestoration && with0->HasAutoOCPDevice)) + with0->ParentPDElement->BranchTotalCustomers += with0->BranchTotalCustomers; + } + } + } /*For i*/ +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Set the HasMeter Flag for all cktElement; + +void TEnergyMeter::SetHasMeterFlag(int ActorID) +{ + int i = 0; + TEnergyMeterObj* ThisMeter = nullptr; + TDSSCktElement* CktElem = nullptr; + /*Initialize all to FALSE*/ + int stop = 0; + /*# with ActiveCircuit[ActorID] do */ + { + + CktElem = (TDSSCktElement*) ActiveCircuit[ActorID]->PDElements.Get_First(); + while(CktElem != nullptr) + { + CktElem->HasEnergyMeter = false; + CktElem = (TDSSCktElement*) ActiveCircuit[ActorID]->PDElements.Get_Next(); + } /*WHILE*/ + } /*WITH*/ + for(stop = ActiveCircuit[ActorID]->EnergyMeters.get_myNumList(), i = 1; i <= stop; i++) + { + ThisMeter = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get(i); + /*# with ThisMeter do */ + { + auto with1 = ThisMeter; + if(with1->Get_Enabled() && (with1->MeteredElement != nullptr)) + with1->MeteredElement->HasEnergyMeter = true; + } + } /*FOR*/ +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This gets fired off whenever the buslists are rebuilt +// Must be updated whenever there is a change in the circuit + +void TEnergyMeterObj::MakeMeterZoneLists(int ActorID) +{ + int TestBusNum = 0; + int ZoneListCounter = 0; + int j = 0; + int iTerm = 0; + int iPC = 0; + int iPD = 0; + TDSSCktElement* ActiveBranch = nullptr; + TPDElement* TestElement = nullptr; + TPCElement* pPCelem = nullptr; + TLoadObj* pLoad = nullptr; + bool IsFeederEnd = false; + TList* adjLst; + unsigned int PCElementType = 0; + int stop = 0; + ZoneListCounter = 0; + VBaseCount = 0; /*Build the voltage base list over in case a base added or deleted*/ + for(j = 1; j <= MaxVBaseCount; j++) + { + VBaseList[j - 1] = 0.0; + } + if(BranchList != nullptr) + delete BranchList; + if(Get_Enabled()) + // Make a new branch list + { + BranchList = new TCktTree(); /*Instantiates ZoneEndsList, too*/ + } + else + { + BranchList = nullptr; + return; + } + + // Get Started + if(ASSIGNED(MeteredElement)) + BranchList->Set_New(MeteredElement); + else + // oops + { + DoSimpleMsg(String("Metered Element for EnergyMeter ") + get_Name() + + " not defined.", 527); + return; + } + + /*Initialize SensorObj property of the first branch to this TMeterElement Object. + Before starting, all sensorObj definitions are cleared in PCElements and PDElements. The + SensorObj property is passed down to the Load objects for LoadAllocation and State Estimation + */ + if(dynamic_cast(MeteredElement)) + /*# with TPDElement(MeteredElement) do */ + { + auto with0 = ((TPDElement*) MeteredElement); + with0->SensorObj = this; + with0->MeterObj = this; + } + else + { + if(dynamic_cast(MeteredElement)) + /*# with TPCElement(MeteredElement) do */ + { + auto with1 = ((TPCElement*) MeteredElement); + with1->SensorObj = this; + with1->MeterObj = this; + } + } + MeteredElement->Terminals[MeteredTerminal - 1].Checked = true; + /*# with BranchList.PresentBranch do */ + { + auto with2 = BranchList->PresentBranch; + // This bus is the head of the feeder or zone; do not mark as radial bus + with2->FromBusReference = MeteredElement->Terminals[MeteredTerminal - 1].BusRef; + ActiveCircuit[ActorID]->Buses[with2->FromBusReference - 1]->DistFromMeter = 0.0; + with2->VoltBaseIndex = AddToVoltBaseList(with2->FromBusReference, ActorID); + with2->FromTerminal = MeteredTerminal; + if(dynamic_cast(MeteredElement)) + ((TPDElement*) MeteredElement)->FromTerminal = MeteredTerminal; + } + + // Check off this element so we don't use it again + /*# with MeteredElement do */ + { + auto with3 = MeteredElement; + with3->Checked = true; + with3->IsIsolated = false; + } + + // Make SequenceList for use in reliability calcs or anything that + // needs to run through the tree quickly in a radial sequence + if(ASSIGNED(SequenceList)) + delete SequenceList; + SequenceList = new PointerList::TPointerList(1024); //make it a big initial allocation + if(ASSIGNED(LoadList)) + delete LoadList; + LoadList = new PointerList::TPointerList(1024); //make it a big initial allocation + + // Now start looking for other branches + // Finds any branch connected to the TestBranch and adds it to the list + // Goes until end of circuit, another energy meter, an open terminal, or disabled device. + ActiveBranch = MeteredElement; + + /* **************** MAIN LOOP ******************************/ + while(ActiveBranch != nullptr) + { + int stop = 0; + SequenceList->Add(ActiveBranch); // When done, this should be the correct order. + /*# with BranchList.PresentBranch do */ + { + auto with4 = BranchList->PresentBranch; + with4->IsLoopedHere = false; + with4->IsParallel = false; + with4->IsDangling = true; // Unless we find something connected to it + with4->VoltBaseIndex = AddToVoltBaseList(with4->FromBusReference, ActorID); + } + ((TPDElement*) ActiveBranch)->BranchNumCustomers = 0; // Init counter + for(stop = ActiveBranch->Get_NTerms(), iTerm = 1; iTerm <= stop; iTerm++) + { + if(!(ActiveBranch->Terminals[iTerm - 1].Checked)) + /*# with ActiveCircuit[ActorID] do */ + { + + // Now find all loads and generators connected to the bus on this end of branch + // attach them as generic objects to cktTree node. + int stop1 = 0; + TestBusNum = ActiveBranch->Terminals[iTerm - 1].BusRef; + /*# with BranchList.PresentBranch do */ + { + auto with6 = BranchList->PresentBranch; + with6->Set_ToBusReference(TestBusNum); // Add this as a "to" bus reference + if(IslineElement(ActiveBranch)) // Convert to consistent units (km) + ActiveCircuit[ActorID]->Buses[TestBusNum - 1]->DistFromMeter = ActiveCircuit[ActorID]->Buses[with6->FromBusReference - 1]->DistFromMeter + ((TLineObj*) ActiveBranch)->Len * ConvertLineUnits(((TLineObj*) ActiveBranch)->LengthUnits, UNITS_KM); + else + ActiveCircuit[ActorID]->Buses[TestBusNum - 1]->DistFromMeter = ActiveCircuit[ActorID]->Buses[with6->FromBusReference - 1]->DistFromMeter; + } + adjLst = &(BusAdjPC[TestBusNum]); + for(stop1 = adjLst->size() - 1, iPC = 0; iPC <= stop1; iPC++) + { + TDSSCktElement* elem = (TDSSCktElement*) (*adjLst)[iPC]; + + // Note: we cannot use these directly with a plain C cast, casting + // a pointer can corrupt the memory with delayed issues, hard to locate. + pPCelem = dynamic_cast(elem); + TPDElement* pPDelem = dynamic_cast(elem); + + // IF pPCelem.Enabled Then Begin only enabled elements in the search list + if(!elem->Checked) + { + BranchList->PresentBranch->IsDangling = false; // Something is connected here + // Is this a load or a generator or a Capacitor or reactor?? + PCElementType = (unsigned int) (elem->DSSObjType & CLASSMASK); + if((PCElementType == LOAD_ELEMENT) || (PCElementType == GEN_ELEMENT) || (PCElementType == PVSYSTEM_ELEMENT) || (PCElementType == STORAGE_ELEMENT) || (PCElementType == CAP_ELEMENT) || (PCElementType == REACTOR_ELEMENT)) +// OR (PCElementType = PVSYSTEM2_ELEMENT) + +// OR (PCElementType = STORAGE2_ELEMENT) + // Capacitor and Reactor put on the PC list if IsShunt=TRUE + { + BranchList->Set_NewObject(elem); // This adds element to the Shunt list in CktTree + elem->Checked = true; // So we don't pick this element up again + elem->IsIsolated = false; + elem->Set_ActiveTerminal(1); + /*Totalize Number of Customers if Load Type*/ + if((pLoad = dynamic_cast(elem))) + { + ((TPDElement*) ActiveBranch)->BranchNumCustomers += pLoad->NumCustomers; + LoadList->Add(pLoad); // Add to list of loads in this zone.) + } + /*If object does not have a sensor attached, it acquires the sensor of its parent branch*/ + if(!elem->HasSensorObj) + { + if (pPCelem) pPCelem->SensorObj = ((TPDElement*)ActiveBranch)->SensorObj; + if (pPDelem) pPDelem->SensorObj = ((TPDElement*)ActiveBranch)->SensorObj; + } + if (pPCelem) pPCelem->MeterObj = this; + if (pPDelem) pPDelem->MeterObj = this; + } /*IF*/ + } + } + + // Now find all branches connected to this bus that we haven't found already + // Do not include in this zone if branch has open terminals or has another meter + if(DefinedZoneListSize == 0) // Search tree for connected branches (default) + { + int stop1 = 0; + IsFeederEnd = true; + adjLst = &(BusAdjPD[TestBusNum]); + for(stop1 = adjLst->size() - 1, iPD = 0; iPD <= stop1; iPD++) + { + TestElement = ((TPDElement*) (*adjLst)[iPD]); // Only enabled objects are in this list + // **** See ResetMeterZonesAll + if(!(((TDSSCktElement*) TestElement) == ActiveBranch)) + { + if(!( (TDSSCktElement*) TestElement )->HasEnergyMeter) // Skip self + // Stop at other meters so zones don't interfere + { + int stop2 = 0; + for(stop2 = ((TDSSCktElement*)TestElement)->Get_NTerms(), j = 1; j <= stop2; j++) + { // Check each terminal + if(TestBusNum == (((TDSSCktElement*)TestElement)->Terminals)[j - 1].BusRef) + { + BranchList->PresentBranch->IsDangling = false; // We found something it was connected to + /*Check for loops and parallel branches and mark them*/ + if(((TDSSCktElement*)TestElement)->Checked) + /*# with BranchList.PresentBranch do */ + { + auto with7 = BranchList->PresentBranch; /*This branch is on some meter's list already */ + with7->IsLoopedHere = true; /*It's a loop*/ + with7->LoopLineObj = TestElement; + if(IslineElement(ActiveBranch) && IslineElement(((TDSSCktElement*)TestElement))) + { + if(CheckParallel(ActiveBranch, ((TDSSCktElement*)TestElement))) + with7->IsParallel = true; /*It's paralleled with another line*/ + } + } + else + // push TestElement onto stack and set properties + { + IsFeederEnd = false; // for interpolation + BranchList->AddNewChild(TestElement, TestBusNum, j); // Add new child to the branchlist + /*# with TestElement do */ + { + auto with8 = TestElement; + (((TDSSCktElement*) with8)->Terminals)[j - 1].Checked = true; + with8->FromTerminal = j; + ((TDSSCktElement*)with8)->Checked = true; + ((TDSSCktElement*)with8)->IsIsolated = false; + /*Branch inherits sensor of upline branch if it doesn't have its own*/ + if(!((TDSSCktElement*)with8)->HasSensorObj) + with8->SensorObj = ((TPDElement*) ActiveBranch)->SensorObj; + with8->MeterObj = this; // Set meterobj to this meter + with8->ParentPDElement = ((TPDElement*) ActiveBranch); // record the parent so we can easily back up for reconductoring, etc. + } + break; + } /*Else*/ + } /*IF TestBusNum*/ + } /*FOR terminals*/ + } /*ELSE*/ + } + } /*FOR iPD*/ + if(IsFeederEnd) + BranchList->ZoneEndsList->Add(BranchList->PresentBranch, TestBusNum); + /*This is an end of the feeder and testbusnum is the end bus*/ + } + else + // Zone is manually specified; Just add next element in list as a child + { + ++ZoneListCounter; + while(ZoneListCounter <= DefinedZoneListSize) + { + if(ActiveCircuit[ActorID]->SetElementActive((DefinedZoneList)[ZoneListCounter - 1]) == 0) // Not Found. Let's search for another + ++ZoneListCounter; + else + { + TestElement = (TPDElement*) ActiveCircuit[ActorID]->get_FActiveCktElement(); + if(!((TDSSCktElement*)TestElement)->Get_Enabled()) // Lets ignore disabled devices + ++ZoneListCounter; + else + { + if((((TDSSCktElement*)TestElement)->DSSObjType & BaseClassMask) != PD_ELEMENT) // Lets ignore non-PD elements + ++ZoneListCounter; + else + BranchList->AddNewChild(TestElement, 0, 0); // add it as a child to the previous element + break; + } + } + } // while + } + } /*WITH Active Circuit*/ + } /*FOR iTerm*/ + ActiveBranch = ((TDSSCktElement*) BranchList->Get_Forward()); // Sets PresentBranch + /* **************** END MAIN LOOP ******************************/ + } + TotalupDownstreamCustomers(); + + /****If HasFeeder Then FeederObj.InitializeFeeder(BranchList); // Synchronize the feeder definition */ + AssignVoltBaseRegisterNames(); +} + +/*--------------------------------------------------------------------------*/ //Get present value of terminal Curr FOR reports + +void TEnergyMeterObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + Curr[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TEnergyMeterObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + Curr[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TEnergyMeterObj::ZoneDump(int ActorID) +{ + String CSVName; + TTextRec f = {}; + TPDElement* PDElem = nullptr; + TDSSCktElement* LoadElem = nullptr; + try + { + CSVName = String("Zone_") + get_Name() + ".CSV"; + AssignFile(f, GetOutputDirectory() + CSVName); + Rewrite(f); + IOResultToException(); + GlobalResult = CSVName; + SetLastResultFile(CSVName); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error opening File \"") + CSVName + "\": " + (std::string) e.what(), 528); + return; + } + } + try + { + WriteLn(f, "Level, Branch, Bus1, Bus2, Distance"); + if(BranchList != nullptr) + { + PDElem = ((TPDElement*) BranchList->Get_First()); + while(PDElem != nullptr) + /*# with ActiveCircuit[ActorID] do */ + { + + /*BusList.Get(BranchList.PresentBranch.ToBusReference),*/ + WriteLn(f, Format("%d, %s.%s, %s, %s, %10.4f", + BranchList->Get_Level(), + PDElem->ParentClass->get_myClass_name().c_str(), + PDElem->get_Name().c_str(), + PDElem->Get_FirstBus().c_str(), + PDElem->Get_NextBus().c_str(), + ActiveCircuit[ActorID]->Buses[BranchList->PresentBranch->Get_ToBusReference() - 1]->DistFromMeter)); + BranchList->PresentBranch->ResetToBusList(); + LoadElem = ((TDSSCktElement*) BranchList->Get_FirstObject()); + while(LoadElem != nullptr) + { + { Write(f, "-1, "); + WriteLn(f, LoadElem->ParentClass->get_myClass_name() + + "." + + LoadElem->get_Name() + + ", " + + LoadElem->Get_FirstBus()); + } + LoadElem = ((TDSSCktElement*) BranchList->Get_NextObject()); + } + PDElem = ((TPDElement*) BranchList->Get_Forward()); + } + } +/* } + __finally + {*/ + CloseFile(f); + } + catch (...) + { + // + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEnergyMeterObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + TPDElement* PDElem = nullptr; + TDSSCktElement* LoadElem = nullptr; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + case 4: // option + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, "=("); } + if(ExcessFlag) + Write(f, "E,"); + else + Write(f, "T,"); + if(ZoneIsRadial) + Write(f, " R,"); + else + Write(f, " M,"); + if(VoltageUEOnly) + Write(f, " V"); + else + Write(f, " C"); + WriteLn(f, L')'); + } + break; + case 7: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(i)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + break; + } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f, "Registers"); + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + { Write(f, L'\"'); Write(f, RegisterNames[i - 1]); Write(f, "\" = "); WriteLn(f, Registers[i - 1], 0, 0); } + } + WriteLn(f); + WriteLn(f, "Branch List:"); + if(BranchList != nullptr) + { + PDElem = ((TPDElement*) BranchList->Get_First()); + while(PDElem != nullptr) + { + { Write(f, "Circuit Element = "); WriteLn(f, ( (TDSSCktElement*) PDElem )->get_Name()); } + LoadElem = ((TDSSCktElement*) BranchList->Get_FirstObject()); + while(LoadElem != nullptr) + { + { Write(f, " Shunt Element = "); Write(f, LoadElem->ParentClass->get_myClass_name()); Write(f, L'.'); WriteLn(f, LoadElem->get_Name()); } + LoadElem = ((TDSSCktElement*) BranchList->Get_NextObject()); + } + PDElem = ((TPDElement*) BranchList->Get_Forward()); + } + } + } +} + +void TEnergyMeter::ProcessOptions(const String Opts) +{ + String S1; + String S2; + AuxParser[ActiveActor]->SetCmdString(Opts); // Load up aux Parser + + /*Loop until no more options found*/ + /*# with ActiveEnergyMeterObj do */ + { + auto with0 = ActiveEnergyMeterObj; + do + { + S1 = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + S2 = LowerCase(AuxParser[ActiveActor]->MakeString_()); + if(S2.size() > 0) + switch(S2[1]) + { + case L'e': + with0->ExcessFlag = true; + break; + case L't': + with0->ExcessFlag = false; + break; + case L'r': + with0->ZoneIsRadial = true; + break; + case L'm': + with0->ZoneIsRadial = false; + break; + case L'c': + with0->VoltageUEOnly = false; + break; + case L'v': + with0->VoltageUEOnly = true; + break; + default: + ; + break; + } + } + while(!(S2.size() == 0)); + } +} +/*Add to VoltBase list if not already there and return index*/ + +int TEnergyMeterObj::AddToVoltBaseList(int BusRef, int ActorID) +{ + int result = 0; + int i = 0; + /*# with ActiveCircuit[ActorID]->Buses^[BusRef] do */ + { + + int stop = 0; + for(stop = VBaseCount, i = 1; i <= stop; i++) + { + if(Abs((1.0 - ActiveCircuit[ActorID]->Buses[BusRef - 1]->kVBase / (VBaseList)[i])) < 0.01) // < 1% difference + { + result = i; + return result; + } + } + if((ActiveCircuit[ActorID]->Buses[BusRef - 1]->kVBase > 0.0) && (VBaseCount < MaxVBaseCount)) + { + ++VBaseCount; /*ActiveCircuit[ActorID].Buses^[BusRef].*/ + (VBaseList)[VBaseCount] = ActiveCircuit[ActorID]->Buses[BusRef - 1]->kVBase; + result = VBaseCount; + } + else + result = 0; + } + return result; +} + +void TEnergyMeterObj::AllocateLoad(int ActorID) +{ + int ConnectedPhase = 0; + TPDElement* CktElem = nullptr; + TLoadObj* LoadElem = nullptr; + + +/*PREREQUISITE: EXECUTE CALCALLOCATIONFACTORS FOR ALL ENERGYMETERS AND SENSORS*/ +/*****Done in calling procedure now *** CalcAllocationFactors;*/ /*for this meter. Inherited from Meterelement*/ +/*See ExecHelper*/ + + /* Now go through the meter's zone and adjust the loads. + + While the AllocationFactor property is adjusted for all loads, it will only + have an effect on loads defined with either the XFKVA property or the + kWh property. + + Loads have a SensorObj property that points to its upstream sensor that has the adjustments for + the allocation factors. This is established in the MakeMeterZoneLists proc in this Unit. + + Sensors consist of EnergyMeters, which drive the load allocation process and Sensor objects that + are simply voltage and current measuring points. A Sensor may be attached to a line or transformer + or it may be connected directly to a load. + */ + CktElem = ((TPDElement*) BranchList->Get_First()); + while(CktElem != nullptr) + { + LoadElem = ((TLoadObj*) BranchList->Get_FirstObject()); + while((LoadElem != nullptr)) + { + if( ( ( LoadElem )->DSSObjType & CLASSMASK) == LOAD_ELEMENT) + switch(((TDSSCktElement*)LoadElem)->Get_NPhases()) + { // only for loads not other shunts + case 1: + /*# with LoadElem do */ + { + auto with0 = LoadElem; + /*For Single phase loads, allocate based on phase factor, else average factor*/ + ConnectedPhase = (ActiveCircuit[ActorID]->MapNodeToBus)[ (with0->NodeRef)[1 - 1] - 1 ].NodeNum; + if((ConnectedPhase > 0) && (ConnectedPhase < 4)) + { + if ( ( ( with0->SensorObj ) )->Get_NPhases() == 1) // Restrict to phases 1..3 + with0->Set_AllocationFactor(with0->get_FAllocationFactor() * (with0->SensorObj->PhsAllocationFactor)[0]); + else + with0->Set_AllocationFactor(with0->get_FAllocationFactor() * (with0->SensorObj->PhsAllocationFactor)[ConnectedPhase - 1]); + } + } + break; + default: + /*# with LoadElem do */ + { + auto with1 = LoadElem; + with1->Set_AllocationFactor(with1->get_FAllocationFactor() * with1->SensorObj->AvgAllocFactor); + } + break; + } /*CASE*/ + LoadElem = ((TLoadObj*) BranchList->Get_NextObject()); + } /*While Loadelem*/ + CktElem = ((TPDElement*) BranchList->Get_Forward()); /*Go on down the tree*/ + } /*While CktElem*/ +} + +void TEnergyMeterObj::InitPropertyValues(int ArrayOffset) +{ + int i = 0; + String s; + int stop = 0; + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,"clear"); //'action'; + Set_PropertyValue(4,"(E, R, C)"); //'Option'; + Set_PropertyValue(5,"0.0"); //'kWnormal'; + Set_PropertyValue(6,"0.0"); //'kwEmerg'; + Set_PropertyValue(7,"(400, 400, 400)"); //'PeakCurrent'; + Set_PropertyValue(8,""); // ZoneList + Set_PropertyValue(9,"No"); + /*Define mask as 1 for all registers*/ + s = "["; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + s = s + "1 "; + } + Set_PropertyValue(10,s + "]"); + Set_PropertyValue(11,"Yes"); + Set_PropertyValue(12,"Yes"); + Set_PropertyValue(13,"Yes"); + Set_PropertyValue(14,"Yes"); + Set_PropertyValue(15,"Yes"); // segregate losses by voltage base + Set_PropertyValue(16,"Yes"); + Set_PropertyValue(17,"No"); + Set_PropertyValue(18,"0"); + Set_PropertyValue(19,"0"); + Set_PropertyValue(20,"0"); + Set_PropertyValue(21,"0"); + Set_PropertyValue(22,"0"); + Set_PropertyValue(23,"0"); + Set_PropertyValue(24,"0"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TEnergyMeterObj::Accumulate_Gen(TGeneratorObj* pGen, double& TotalZonekW, double& TotalZonekvar, int ActorID) +{ + complex s = {}; + //----pGen.ActiveTerminalIdx := 1; + s = cnegate(cmulreal( ( (TDSSCktElement*) pGen )->Get_Power(1, ActorID), 0.001)); + TotalZonekW = TotalZonekW + s.re; + TotalZonekvar = TotalZonekvar + s.im; +} + +double TEnergyMeterObj::Accumulate_Load(TLoadObj* pLoad, double& TotalZonekW, double& TotalZonekvar, double& TotalLoad_EEN, double& TotalLoad_UE, int ActorID) +{ + double result = 0.0; + complex S_Load = cmplx(0,0); + double kW_Load = 0.0; + double Load_EEN = 0.0; + double Load_UE = 0.0; + /*# with pLoad do */ + { + auto with0 = pLoad; + //----ActiveTerminalIdx := 1; + S_Load = cmulreal( ((TDSSCktElement*) pLoad )->Get_Power(1, ActorID), 0.001); // Get Power in Terminal 1 + kW_Load = S_Load.re; + result = kW_Load; + + /*Accumulate load in zone*/ + TotalZonekW = TotalZonekW + kW_Load; + TotalZonekvar = TotalZonekvar + S_Load.im; + + /*always integrate even if the value is 0.0 + otherwise the Integrate function is not correct*/ + /*Invoking the ExceedsNormal and Unserved Properties causes the factors to be computed*/ + if(ExcessFlag) // Return Excess load as EEN/UE + { + if (with0->Get_ExceedsNormal(ActorID)) + Load_EEN = kW_Load * with0->EEN_Factor;// *0.3194; + else + Load_EEN = 0.0; + if (with0->Get_Unserved(ActorID)) + Load_UE = kW_Load * with0->UE_Factor;// *0.1536; + else + Load_UE = 0.0; + } + else + // Return TOTAL load as EEN/UE + { + if(with0->Get_ExceedsNormal(ActorID)) + Load_EEN = kW_Load; + else + Load_EEN = 0.0; + if(with0->Get_Unserved(ActorID)) + Load_UE = kW_Load; + else + Load_UE = 0.0; + } + TotalLoad_EEN = TotalLoad_EEN + Load_EEN; + TotalLoad_UE = TotalLoad_UE + Load_UE; + } /*WITH*/ + return result; +} + +/*Reduce the zone by merging lines*/ + +void TEnergyMeterObj::ReduceZone(int ActorID) +{ + + // Make sure zone list is built + if(!ASSIGNED(BranchList)) + MakeMeterZoneLists(ActorID); + switch(ActiveCircuit[ActorID]->ReductionStrategy) + { + case rsShortlines: + DoReduceShortLines(BranchList); + break; /*See ReduceAlgs.Pas*/ + /*rsTapEnds: DoReduceTapEnds (BranchList);*/ + case rsMergeParallel: + DoMergeParallelLines(BranchList); + break; + case rsDangling: + DoReduceDangling(BranchList); + break; + case rsBreakLoop: + DoBreakLoops(BranchList); + break; + case rsSwitches: + DoReduceSwitches(BranchList); + break; + case rsLaterals: + DoRemoveAll_1ph_Laterals(BranchList); + break; + /*Default*/ + default: + DoReduceDefault(BranchList); + break; + } +/* Feeder Code removed + // Resynchronize with Feeders + If HasFeeder Then FeederObj.InitializeFeeder (Branchlist); +*/ +} +/*Start at the ends of the zone and work toward the start + interpolating between known coordinates*/ + +void TEnergyMeterObj::InterpolateCoordinates() +{ + int i = 0; + int BusRef = 0; + int FirstCoordRef = 0; + int SecondCoordRef = 0; + int LineCount = 0; + TCktTreeNode* PresentNode = nullptr; + TCktTreeNode* StartNode = nullptr; + TDSSCktElement* CktElem = nullptr; + if(!ASSIGNED(BranchList)) + { + DoSimpleMsg("Meter Zone Lists need to be built. Do Solve or Makebuslist first!", 529); + return; + } + /*# with ActiveCircuit[ActiveActor] do */ + { + + int stop = 0; + for(stop = BranchList->ZoneEndsList->NumEnds, i = 1; i <= stop; i++) + { + BusRef = BranchList->ZoneEndsList->Get(i, PresentNode); + FirstCoordRef = BusRef; + SecondCoordRef = FirstCoordRef; /*so compiler won't issue stupid warning*/ + /*Find a bus with a coordinate*/ + if(!ActiveCircuit[ActiveActor]->Buses[BusRef - 1]->CoordDefined) + { + while(!ActiveCircuit[ActiveActor]->Buses[PresentNode->FromBusReference - 1]->CoordDefined) + { + PresentNode = PresentNode->Get_Parent(); + if(PresentNode == nullptr) + break; + } + if(PresentNode != nullptr) + FirstCoordRef = PresentNode->FromBusReference; + } + while(PresentNode != nullptr) + + /*Back up until we find another Coord defined*/ + { + LineCount = 0; /*number of line segments in this segment*/ + StartNode = PresentNode; + CktElem = ((TDSSCktElement*) PresentNode->CktObject); + if(FirstCoordRef != PresentNode->FromBusReference) /*Handle special case for end branch*/ + { + if(ActiveCircuit[ActiveActor]->Buses[PresentNode->FromBusReference - 1]->CoordDefined) + FirstCoordRef = PresentNode->FromBusReference; + else + ++LineCount; + } + do + { + CktElem->Checked = true; + PresentNode = PresentNode->Get_Parent(); + if(PresentNode == nullptr) + break; + CktElem = ((TDSSCktElement*) PresentNode->CktObject); + SecondCoordRef = PresentNode->FromBusReference; + ++LineCount; + } + while(!(ActiveCircuit[ActiveActor]->Buses[SecondCoordRef - 1]->CoordDefined || CktElem->Checked)); + if((PresentNode != nullptr) && (LineCount > 1)) + { + if(ActiveCircuit[ActiveActor]->Buses[SecondCoordRef - 1]->CoordDefined) + { + CalcBusCoordinates(StartNode, FirstCoordRef, SecondCoordRef, LineCount); + } + else + break; /*While - went as far as we could go this way*/ + } + FirstCoordRef = SecondCoordRef; + } + } /*For*/ + } /*With*/ +} + +void TEnergyMeterObj::CalcBusCoordinates(TCktTreeNode* StartBranch, int FirstCoordRef, int SecondCoordRef, int LineCount) +{ + double X = 0.0; + double Y = 0.0; + double Xinc = 0.0; + double Yinc = 0.0; + if(LineCount == 1) + return; /*Nothing to do!*/ + /*# with ActiveCircuit[ActiveActor] do */ + { + + Xinc = (ActiveCircuit[ActiveActor]->Buses[FirstCoordRef - 1]->x - ActiveCircuit[ActiveActor]->Buses[SecondCoordRef - 1]->x) / LineCount; + Yinc = (ActiveCircuit[ActiveActor]->Buses[FirstCoordRef - 1]->y - ActiveCircuit[ActiveActor]->Buses[SecondCoordRef - 1]->y) / LineCount; + X = ActiveCircuit[ActiveActor]->Buses[FirstCoordRef - 1]->x; + Y = ActiveCircuit[ActiveActor]->Buses[FirstCoordRef - 1]->y; + + /****Debug*/ + /* If ((X<10.0) and (y<10.0)) or + ((Buses^[SecondCoordRef].X<10.0) and (Buses^[SecondCoordRef].Y<10.0)) Then + Begin + X := y; // Stopping point + End; + */ + + /*Either start with the "to" end of StartNode or the "from" end;*/ + if(FirstCoordRef != StartBranch->FromBusReference) // Start with "to" end + { + X = X - Xinc; + Y = Y - Yinc; + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->x = X; + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->y = Y; + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->CoordDefined = true; + --LineCount; + } + while(LineCount > 1) + { + X = X - Xinc; + Y = Y - Yinc; + StartBranch = StartBranch->Get_Parent(); // back up the tree + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->x = X; + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->y = Y; + ActiveCircuit[ActiveActor]->Buses[StartBranch->FromBusReference - 1]->CoordDefined = true; + --LineCount; + } + } +} + + + + +/*--------------------------- CalcReliabilityIndices ----------------------------*/ + +void TEnergyMeterObj::CalcReliabilityIndices(bool AssumeRestoration_in, int ActorID) +{ + TPDElement* PD_Elem = nullptr; + TFeederSection pSection = {}; + int Idx = 0, + stop = 0; + TDSSBus* pBus = nullptr; + double dblNcusts = 0.0, + dblkW = 0.0; + + if(!ASSIGNED(SequenceList)) + { + DoSimpleMsg("Energymeter." + get_Name() + " Zone not defined properly.", 52901); + return; + } + + // Update the number of customers + AssumeRestoration = AssumeRestoration_in; + TotalupDownstreamCustomers(); + // Zero reliability accumulators + for(stop = 1, Idx = SequenceList->get_myNumList(); Idx >= stop; Idx--) + { + ((TPDElement*) SequenceList->Get(Idx))->ZeroReliabilityAccums(); + } + + // Backward sweep calculating failure rates + for(stop = 1, Idx = SequenceList->get_myNumList(); Idx >= stop; Idx--) + { + /*# with TPDElement(SequenceList->Get(Idx)) do */ + { + auto with0 = ((TPDElement*) SequenceList->Get(Idx)); + with0->CalcFltRate(); // Calc failure rate for this element + with0->AccumFltRate(); + } + } + + // Forward sweep to get number of interruptions + // Initialize number of interruptions and Duration + PD_Elem = ((TPDElement*) SequenceList->Get(1)); + pBus = ActiveCircuit[ActorID]->Buses[ PD_Elem->Terminals[PD_Elem->FromTerminal - 1].BusRef - 1]; + pBus->Bus_Num_Interrupt = Source_NumInterruptions; + pBus->BusCustInterrupts = Source_NumInterruptions * pBus->BusTotalNumCustomers; + pBus->Bus_Int_Duration = Source_IntDuration; + + // init for defining sections + SectionCount = 0; + pBus->BusSectionID = SectionCount; // section before 1st OCP device is zero + for(stop = SequenceList->get_myNumList(), Idx = 1; Idx <= stop; Idx++) + { + ((TPDElement*) SequenceList->Get(Idx))->CalcNum_Int(SectionCount, AssumeRestoration_in); + } + if(SectionCount == 0) // Error - no OCP devices + { + DoSimpleMsg("Error: No Overcurrent Protection device (Relay, Recloser, or Fuse) defined. Aborting Reliability calc.", 52902); + return; + } + + // Now have number of sections so allocate FeederSections array + FeederSections.resize(SectionCount + 1); + for(stop = SectionCount, Idx = 0; Idx <= stop; Idx++) + { + /*# with FeederSections^[Idx] do */ + { + // Should be only place idx=0 + FeederSections[Idx].OCPDeviceType = 0; // 1=Fuse; 2=Recloser; 3=Relay + FeederSections[Idx].AverageRepairTime = 0.0; + FeederSections[Idx].SumFltRatesXRepairHrs = 0.0; + FeederSections[Idx].SumBranchFltRates = 0.0; + FeederSections[Idx].NCustomers = 0; + FeederSections[Idx].TotalCustomers = 0; + FeederSections[Idx].SectFaultRate = 0.0; + FeederSections[Idx].NBranches = 0; + FeederSections[Idx].SeqIndex = 0; + } + } + + + // Now do Backward sweep calculating N*Fault rates + for(stop = 1, Idx = SequenceList->get_myNumList(); Idx >= stop; Idx--) + { + PD_Elem = (TPDElement*) SequenceList->Get(Idx); + PD_Elem->CalcCustInterrupts(); + // Populate the Section properties + pSection = FeederSections[PD_Elem->BranchSectionID]; + pSection.NCustomers += PD_Elem->BranchNumCustomers; // Sum up num Customers on this Section + pSection.NBranches += 1; // Sum up num branches on this Section + pBus = ActiveCircuit[ActorID]->Buses[PD_Elem->Terminals[PD_Elem->ToTerminal - 1].BusRef - 1] ; + DblInc(pSection.SumBranchFltRates, pBus->Bus_Num_Interrupt * PD_Elem->BranchFltRate); + DblInc(pSection.SumFltRatesXRepairHrs, (pBus->Bus_Num_Interrupt * PD_Elem->BranchFltRate * PD_Elem->HrsToRepair)); + if( PD_Elem->HasOCPDevice) // set Section properties + { + pSection.OCPDeviceType = GetOCPDeviceType(PD_Elem); + pSection.SeqIndex = Idx; // index of pdelement with OCP device at head of section + pSection.TotalCustomers = PD_Elem->BranchTotalCustomers; + pSection.SectFaultRate = PD_Elem->AccumulatedBrFltRate; + } + FeederSections[PD_Elem->BranchSectionID] = pSection; // put it back + } + + /* Compute Avg Interruption duration of each Section except 0 Section*/ + for(stop = SectionCount, Idx = 1; Idx <= stop; Idx++) + { + /*# with FeederSections^[Idx] do */ + { + + FeederSections[Idx].AverageRepairTime = FeederSections[Idx].SumFltRatesXRepairHrs / FeederSections[Idx].SumBranchFltRates; + } + } + + /* Set Bus_int_Duration */ + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + for(stop = ActiveCircuit[ActorID]->NumBuses, Idx = 1; Idx <= stop; Idx++) + { + pBus = ActiveCircuit[ActorID]->Buses[Idx - 1]; + if(pBus->BusSectionID > 0) + pBus->Bus_Int_Duration = Source_IntDuration + FeederSections[pBus->BusSectionID].AverageRepairTime; + } + } + + /* Compute SAIFI based on numcustomers and load kW */ + /* SAIFI is weighted by specified load weights */ + /* SAIFI is for the EnergyMeter Zone */ + SAIFI = 0.0; + CAIDI = 0.0; + SAIFIkW = 0.0; + dblNcusts = 0.0; + dblkW = 0.0; + CustInterrupts = 0.0; + + // Use LoadList for SAIFI calculation + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + for(stop = LoadList->get_myNumList(), Idx = 1; Idx <= stop; Idx++) + { // all loads in meter zone + + // Compute CustInterrupts based on interrupts at each load + /*# with TLoadObj(LoadList.Get(Idx)) do */ + { + auto with5 = ((TLoadObj*) LoadList->Get(Idx)); + pBus = ActiveCircuit[ActorID]->Buses[ with5->Terminals[1 - 1].BusRef - 1]; // pointer to Load's bus + CustInterrupts = CustInterrupts + with5->NumCustomers * with5->RelWeighting * pBus->Bus_Num_Interrupt; + SAIFIkW = SAIFIkW + with5->kWBase * with5->RelWeighting * pBus->Bus_Num_Interrupt; + DblInc(dblNcusts, with5->NumCustomers * with5->RelWeighting); + // total up weighted numcustomers + DblInc(dblkW, with5->kWBase * with5->RelWeighting); // total up weighted kW + // Set BusCustDurations for Branch reliability export + pBus->BusCustDurations = (pBus->BusTotalNumCustomers + with5->NumCustomers) * with5->RelWeighting * pBus->Bus_Int_Duration * pBus->Bus_Num_Interrupt; + } + } + } + + // Compute SAIDI from Sections list + SAIDI = 0.0; + for(stop = SectionCount, Idx = 1; Idx <= stop; Idx++) + { + /*# with FeederSections^[Idx] do */ + { + // ignore idx=0 + SAIDI = SAIDI + FeederSections[Idx].SectFaultRate * FeederSections[Idx].AverageRepairTime * FeederSections[Idx].TotalCustomers; + } + } + if(dblNcusts > 0.0) + { + SAIFI = CustInterrupts / dblNcusts; // Normalize to total number of customers + SAIDI = SAIDI / dblNcusts; // Normalize to total number of customers + } + if(SAIFI > 0.0) + CAIDI = SAIDI / SAIFI; + if(dblkW > 0.0) + SAIFIkW = SAIFIkW / dblkW; // Normalize to total kW +} + +/*-------------------------------------------------------------------------------*/ + +String TEnergyMeterObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 4: + case 7: + result = "("; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 4: // option + { + if(ExcessFlag) + result = result + "E,"; + else + result = result + "T,"; + if(ZoneIsRadial) + result = result + " R,"; + else + result = result + " M,"; + if(VoltageUEOnly) + result = result + " V"; + else + result = result + " C"; + } + break; + case 20: + result = Format("%.11g", SAIFI); + break; + case 21: + result = Format("%.11g", SAIFIkW); + break; + case 22: + result = Format("%.11g", SAIDI); + break; + case 23: + result = Format("%.11g", CAIDI); + break; + case 24: + result = Format("%.11g", CustInterrupts); + break; + default: + result = result + inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 4: + case 7: + result = result + ")"; + break; + default: + ; + break; + } + return result; +} + +void TEnergyMeterObj::SaveZone(const String DirName) +{ + TDSSCktElement* CktElem = nullptr; + TDSSCktElement* shuntElement = nullptr; + TLoadObj* LoadElement = nullptr; + TDSSCktElement* pControlElem = nullptr; + TTextRec FBranches = {}; + TTextRec FShunts = {}; + TTextRec FLoads = {}; + TTextRec FGens = {}; + TTextRec FCaps = {}; + TTextRec FXfmrs = {}; + int NBranches = 0; + int NShunts = 0; + int Nloads = 0; + int NGens = 0; + int NCaps = 0; + int NXfmrs = 0; + /*We are in the directory indicated by dirname*/ + +/*Run down the zone and write each element into a file*/ + if(BranchList != nullptr) + /*Open some files:*/ + { + try + { + AssignFile(FBranches, "Branches.dss"); // Both lines and transformers + Rewrite(FBranches); + IOResultToException(); + NBranches = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Branches.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 530); + CloseFile(FBranches); System::InOutRes = 0; + return; + } + } + try + { + AssignFile(FXfmrs, "Transformers.dss"); // Both lines and transformers + Rewrite(FXfmrs); + IOResultToException(); + NXfmrs = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Transformers.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 53001); + CloseFile(FXfmrs); System::InOutRes = 0; + return; + } + } + try + { + AssignFile(FShunts, "Shunts.dss"); + Rewrite(FShunts); + IOResultToException(); + NShunts = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Shunts.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 531); + CloseFile(FShunts); System::InOutRes = 0; + return; + } + } + try + { + AssignFile(FLoads, "Loads.dss"); + Rewrite(FLoads); + IOResultToException(); + Nloads = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Loads.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 532); + CloseFile(FLoads); System::InOutRes = 0; + return; + } + } + try + { + AssignFile(FGens, "Generators.dss"); + Rewrite(FGens); + IOResultToException(); + NGens = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Generators.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 533); + CloseFile(FGens); System::InOutRes = 0; + return; + } + } + try + { + AssignFile(FCaps, "Capacitors.dss"); + Rewrite(FCaps); + IOResultToException(); + NCaps = 0; + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error creating Capacitors.dss for Energymeter: ") + this->get_Name() + + ". " + + (std::string) e.what(), 534); + CloseFile(FCaps); System::InOutRes = 0; + return; + } + } + CktElem = ((TDSSCktElement*) BranchList->Get_First()); + /*# with ActiveCircuit[ActiveActor] do */ + { + + while(CktElem != nullptr) + { + if(CktElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(CktElem); + if((CktElem->DSSObjType & CLASSMASK) == XFMR_ELEMENT) + { + ++NXfmrs; + WriteActiveDSSObject(FXfmrs, "New"); // sets HasBeenSaved := TRUE + if(CktElem->HasControl) + { + pControlElem = (TDSSCktElement*) CktElem->ControlElementList.Get_First(); + while(pControlElem != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pControlElem); + WriteActiveDSSObject(FXfmrs, "New"); // regulator control ...Also, relays, switch controls + pControlElem = (TDSSCktElement*) CktElem->ControlElementList.Get_Next(); + } + } + } + else + /*Mostly LINE elements*/ + { + ++NBranches; + WriteActiveDSSObject(FBranches, "New"); // sets HasBeenSaved := TRUE + if(CktElem->HasControl) + { + pControlElem = (TDSSCktElement*) CktElem->ControlElementList.Get_First(); + while(pControlElem != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pControlElem); + WriteActiveDSSObject(FBranches, "New"); // regulator control ...Also, relays, switch controls + pControlElem = (TDSSCktElement*) CktElem->ControlElementList.Get_Next(); + } + } + } + shuntElement = ((TDSSCktElement*) BranchList->Get_FirstObject()); + while(shuntElement != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(shuntElement); + if((shuntElement->DSSObjType & CLASSMASK) == LOAD_ELEMENT) + { + LoadElement = ((TLoadObj*) shuntElement); + if(LoadElement->HasBeenAllocated) + /*Manually set the allocation factor so it shows up*/ + { + Parser[ActiveActor]->SetCmdString(String("allocationfactor=") + Format("%-.4g", LoadElement->get_FAllocationFactor())); + ( (TDSSObject*) LoadElement )->Edit(ActiveActor); + } + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(shuntElement); // reset in case Edit mangles it + ++Nloads; + WriteActiveDSSObject(FLoads, "New"); + } + else + { + if((shuntElement->DSSObjType & CLASSMASK) == GEN_ELEMENT) + { + ++NGens; + WriteActiveDSSObject(FGens, "New"); + if(shuntElement->HasControl) + { + pControlElem = (TDSSCktElement*) shuntElement->ControlElementList.Get_First(); + while(pControlElem != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pControlElem); + WriteActiveDSSObject(FGens, "New"); + pControlElem = (TDSSCktElement*) shuntElement->ControlElementList.Get_Next(); + } + } + } + else + { + if((shuntElement->DSSObjType & CLASSMASK) == CAP_ELEMENT) + { + ++NCaps; + WriteActiveDSSObject(FCaps, "New"); + if(shuntElement->HasControl) + { + pControlElem = (TDSSCktElement*) shuntElement->ControlElementList.Get_First(); + while(pControlElem != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pControlElem); + WriteActiveDSSObject(FCaps, "New"); + pControlElem = (TDSSCktElement*) shuntElement->ControlElementList.Get_Next(); + } + } + } + else + { + ++NShunts; + WriteActiveDSSObject(FShunts, "New"); + } + } + } + shuntElement = ((TDSSCktElement*) BranchList->Get_NextObject()); + } + } /*if enabled*/ + CktElem = ((TDSSCktElement*) BranchList->Get_Forward()); + } + }/*WHILE*/ + CloseFile(FBranches); + CloseFile(FXfmrs); + CloseFile(FShunts); + CloseFile(FLoads); + CloseFile(FGens); + CloseFile(FCaps); + + /*If any records were written to the file, record their relative names*/ + if(NBranches > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Branches.dss"); + else + DeleteFile("Branches.dss"); + if(NXfmrs > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Transformers.dss"); + else + DeleteFile("Transformers.dss"); + if(NShunts > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Shunts.dss"); + else + DeleteFile("Shunts.dss"); + if(Nloads > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Loads.dss"); + else + DeleteFile("Loads.dss"); + if(NGens > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Generators.dss"); + else + DeleteFile("Generators.dss"); + if(NCaps > 0) + SavedFileList[ActiveActor].push_back(DirName + DIRSEP_STR "Capacitors.dss"); + else + DeleteFile("Capacitors.dss"); + } /*IF*/ +} + +void TEnergyMeterObj::GetPCEatZone() +{ + TDSSCktElement* CktElem = nullptr; + TDSSCktElement* shuntElement = nullptr; + std::vector myPCEList; + TEnergyMeterObj* pMeter = nullptr; + if(ActiveCircuit[ActiveActor] != nullptr) + { + ZonePCE.resize( 0 ); + /*# with ActiveCircuit[ActiveActor] do */ + { + + if(BranchList != nullptr) + { + CktElem = ((TDSSCktElement*) BranchList->Get_First()); + while(CktElem != nullptr) + { + if(CktElem->Get_Enabled()) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(CktElem); + shuntElement = ((TDSSCktElement*) BranchList->Get_FirstObject()); + while(shuntElement != nullptr) + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(shuntElement); + ZonePCE.resize( ZonePCE.size() + 1); + ZonePCE[ZonePCE.size() - 1] = shuntElement->Get_myPName() + "." + shuntElement->get_Name(); + shuntElement = ((TDSSCktElement*) BranchList->Get_NextObject()); + } + } + CktElem = ((TDSSCktElement*) BranchList->Get_Forward()); + } + } + } + } + if (ZonePCE.size() == 0) + { + ZonePCE.resize( 1 ); + ZonePCE[0] = ""; + } +} + +void TEnergyMeterObj::SetDragHandRegister(int reg, double Value) +{ + if(Value > Registers[reg]) + { + Registers[reg] = Value; + Derivatives[reg] = Value; // Use this for demand interval data; + } +} + +void TEnergyMeterObj::CloseDemandIntervalFile(int ActorID) +{ + int i = 0; + try + { + if(This_Meter_DIFileIsOpen) + { + if(DI_MHandle != nullptr) + CloseMHandler(DI_MHandle, MakeDIFileName(ActorID), DI_Append[ActorID]); + This_Meter_DIFileIsOpen = false; + if(PHV_MHandle != nullptr) + { + if(VPhaseReportFileIsOpen) + CloseMHandler(PHV_MHandle, MakeVPhaseReportFileName(ActorID), PHV_Append[ActorID]); + } + VPhaseReportFileIsOpen = false; + } + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error Closing Demand Interval file for Meter \"") + get_Name() + + "\"", 534); + } + + + /*Write Registers to Totals File*/ + /*# with EnergyMeterClass[ActorID] do */ + { + + int stop = 0; + WriteintoMemStr(EMT_MHandle[ActorID], String("\"") + this->get_Name() + "\""); + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMem(EMT_MHandle[ActorID], Registers[i - 1]); + } + WriteintoMemStr(EMT_MHandle[ActorID], CHAR10); + } +} + +void TEnergyMeterObj::OpenDemandIntervalFile(int ActorID) +{ + int i = 0; + int j = 0; + double VBase = 0.0; + try + { + if(This_Meter_DIFileIsOpen) + CloseDemandIntervalFile(ActorID); + if(EnergyMeterClass[ActorID]->Get_DI_Verbose(ActorID)) + { + int stop = 0; + This_Meter_DIFileIsOpen = true; + if(DI_MHandle != nullptr) + delete DI_MHandle; + DI_MHandle = Create_Meter_Space("\"Hour\""); + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMemStr(DI_MHandle, String(", \"") + RegisterNames[i - 1] + "\""); + } + WriteintoMemStr(DI_MHandle, CHAR10); + + /*Phase Voltage Report, if requested*/ + if(FPhaseVoltageReport) + { + int stop = 0; + if(PHV_MHandle != nullptr) + delete PHV_MHandle; + PHV_MHandle = Create_Meter_Space("\"Hour\""); + VPhaseReportFileIsOpen = true; + for(stop = MaxVBaseCount, i = 1; i <= stop; i++) + { + VBase = (VBaseList)[i] * SQRT3; + if(VBase > 0.0) + { + int stop1 = 0; + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMemStr(PHV_MHandle, Format(", %.3gkV_Phs_%d_Max", VBase, j)); + } + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMemStr(PHV_MHandle, Format(", %.3gkV_Phs_%d_Min", VBase, j)); + } + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMemStr(PHV_MHandle, Format(", %.3gkV_Phs_%d_Avg", VBase, j)); + } + } + } + // WriteintoMemStr(PHV_MHandle, ', Min Bus, MaxBus' + Char(10)); // This has not been recorded + WriteintoMemStr(PHV_MHandle, CHAR10); // This has not been recorded + } + } + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error opening demand interval file \"") + get_Name() + + ".CSV" + + " for writing." + + CRLF + + (std::string) e.what(), 535); + } +} + +void TEnergyMeterObj::WriteDemandIntervalData(int ActorID) +{ + int i = 0; + int j = 0; + + auto MyCount_Avg = [&](double Value, int Count) -> double + { + double result = 0.0; + if(Count == 0) + result = 0.0; + else + result = Value / Count; + return result; + }; + if(EnergyMeterClass[ActorID]->Get_DI_Verbose(ActorID) && This_Meter_DIFileIsOpen) + { + int stop = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(DI_MHandle, with0->DynaVars.dblHour); + } + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMem(DI_MHandle, Derivatives[i - 1]); + } + WriteintoMemStr(DI_MHandle, CHAR10); + } + + /*Add to Class demand interval registers*/ + /*# with EnergyMeterClass[ActorID] do */ + { + for (i = 0; i < NumEMRegisters; i++) + { + EnergyMeterClass[ActorID]->DI_RegisterTotals[i] = EnergyMeterClass[ActorID]->DI_RegisterTotals[i] + Derivatives[i] * TotalsMask[i]; + } + } + + + /*Phase Voltage Report, if requested*/ + if(VPhaseReportFileIsOpen) + { + int stop = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(PHV_MHandle, with2->DynaVars.dblHour); + } + for(stop = MaxVBaseCount, i = 1; i <= stop; i++) + { + if((VBaseList)[i] > 0.0) + { + int stop1 = 0; + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMem(PHV_MHandle, 0.001 * (VphaseMax)[jiIndex(j, i)]); + } + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMem(PHV_MHandle, 0.001 * (VPhaseMin)[jiIndex(j, i)]); + } + for(stop1 = 3, j = 1; j <= stop1; j++) + { + WriteintoMem(PHV_MHandle, 0.001 * MyCount_Avg((VPhaseAccum)[jiIndex(j, i)], (VPhaseAccumCount)[jiIndex(j, i)])); + } + } + } + WriteintoMemStr(PHV_MHandle, CHAR10); + } +} + +void TEnergyMeter::CloseAllDIFiles(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + if(FSaveDemandInterval) + /*While closing DI files, write all meter registers to one file*/ + { + try + { + CreateMeterTotals(ActorID); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error on Rewrite of totals file: ") + (std::string) e.what(), 536); + } + + /*Close all the DI file for each meter*/ + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + mtr->CloseDemandIntervalFile(ActorID); + mtr =(TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + WriteTotalsFile(ActorID); // Sum all energymeter registers to "Totals.CSV" + SystemMeter->CloseDemandIntervalFile(ActorID); + SystemMeter->Save(ActorID); + if(EMT_MHandle[ActorID] != nullptr) + CloseMHandler(EMT_MHandle[ActorID], DI_Dir + DIRSEP_STR "EnergyMeterTotals_" + IntToStr(ActorID) + ".CSV", EMT_Append[ActorID]); + EMT_MHandle[ActorID] = nullptr; + if(TDI_MHandle[ActorID] != nullptr) + CloseMHandler(TDI_MHandle[ActorID], DI_Dir + DIRSEP_STR "DI_Totals_" + IntToStr(ActorID) + ".CSV", TDI_Append[ActorID]); + DIFilesAreOpen[ActorID] = false; + if(OverLoadFileIsOpen) + { + if(OV_MHandle[ActorID] != nullptr) + CloseMHandler(OV_MHandle[ActorID], EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR "DI_Overloads_" + IntToStr(ActorID) + ".CSV", OV_Append[ActorID]); + OverLoadFileIsOpen = false; + } + if(VoltageFileIsOpen) + { + if(VR_MHandle[ActorID] != nullptr) + CloseMHandler(VR_MHandle[ActorID], EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR "DI_VoltExceptions_" + IntToStr(ActorID) + ".CSV", VR_Append[ActorID]); + VoltageFileIsOpen = false; + } + } +} + +void TEnergyMeterObj::AppendDemandIntervalFile(int ActorID) +{ + String FileNm; + + /*Only called if "SaveDemandInterval"*/ + if(This_Meter_DIFileIsOpen) + return; + try + { + if(EnergyMeterClass[ActorID]->FDI_Verbose) + { + FileNm = MakeDIFileName(ActorID); // Creates directory if it doesn't exist + if(FileExists(FileNm)) + DI_Append[ActorID] = true; + else + DI_Append[ActorID] = false; + if(DI_MHandle != nullptr) + delete DI_MHandle; + DI_MHandle = Create_Meter_Space(" "); + This_Meter_DIFileIsOpen = true; + } + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error opening demand interval file \"") + get_Name() + + ".CSV" + + " for appending." + + CRLF + + (std::string) e.what(), 537); + } +} + +void TEnergyMeterObj::AssignVoltBaseRegisterNames() +{ + int i = 0; + int ireg = 0; + double VBase = 0.0; + int stop = 0; + ireg = 1; + for(stop = MaxVBaseCount, i = 1; i <= stop; i++) + { + if((VBaseList)[i] > 0.0) + { + VBase = (VBaseList)[i] * SQRT3; + RegisterNames[i + Reg_VBaseStart] = Format("%.3g kV Losses", VBase); + RegisterNames[i + 1 * MaxVBaseCount + Reg_VBaseStart] = Format("%.3g kV Line Loss", VBase); + RegisterNames[i + 2 * MaxVBaseCount + Reg_VBaseStart] = Format("%.3g kV Load Loss", VBase); + RegisterNames[i + 3 * MaxVBaseCount + Reg_VBaseStart] = Format("%.3g kV No Load Loss", VBase); + RegisterNames[i + 4 * MaxVBaseCount + Reg_VBaseStart] = Format("%.3g kV Load Energy", VBase); + } + else + { + RegisterNames[i + Reg_VBaseStart] = Format("Aux%d", ireg); + ++ireg; + RegisterNames[i + 1 * MaxVBaseCount + Reg_VBaseStart] = Format("Aux%d", ireg); + ++ireg; + RegisterNames[i + 2 * MaxVBaseCount + Reg_VBaseStart] = Format("Aux%d", ireg); + ++ireg; + RegisterNames[i + 3 * MaxVBaseCount + Reg_VBaseStart] = Format("Aux%d", ireg); + ++ireg; + RegisterNames[i + 4 * MaxVBaseCount + Reg_VBaseStart] = Format("Aux%d", ireg); + ++ireg; + } + } + for(stop = NumEMRegisters, i = 1 + Reg_VBaseStart + 5 * MaxVBaseCount; i < stop; i++) + { + RegisterNames[i - 1] = Format("Aux%d", ireg); + ++ireg; + } +} + +void TEnergyMeter::AppendAllDIFiles(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + String FileNm; + if(FSaveDemandInterval) + { + ClearDI_Totals(); // clears accumulator arrays + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + mtr->AppendDemandIntervalFile(ActorID); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + SystemMeter->AppendDemandIntervalFile(ActorID); + + /*Open FDI_Totals*/ + try + { + FileNm = DI_Dir + DIRSEP_STR "DI_Totals_" + IntToStr(ActorID) + ".CSV"; + /*File Must Exist*/ + if(FileExists(FileNm)) + TDI_Append[ActorID] = true; + CreateFDI_Totals(ActorID); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error opening demand interval file \"") + get_myClass_name() + + ".CSV" + + " for appending." + + CRLF + + (std::string) e.what(), 538); + } + DIFilesAreOpen[ActorID] = true; + }/*IF*/ +} + +String TEnergyMeterObj::MakeDIFileName(int ActorID) +{ + String result; + result = EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR + this->get_Name() + "_" + IntToStr(ActorID) + ".CSV"; + return result; +} + +void TEnergyMeter::Set_SaveDemandInterval(int ActorID, bool Value) +{ + FSaveDemandInterval = Value; + ResetAll(ActorID); +} + +bool TEnergyMeter::Get_SaveDemandInterval(int ActorID) +{ + bool result = false; + result = FSaveDemandInterval; + return result; +} + +void TEnergyMeter::WriteOverloadReport(int ActorID) +{ + TPDElement* PDElem = nullptr; + double EmergAmps = 0.0; + double NormAmps = 0.0; + double cMax = 0.0; + TEnergyMeterObj* mtr = nullptr; + String ClassName; + TXYcurveObj* RSignal = nullptr; + int i = 0; + int j = 0; + int k = 0; + int RatingIdx = 0; + std::vector cVector; + std::vector cBuffer; +/* + Scans the active circuit for overloaded PD elements and writes each to a file + This is called only if in Demand Interval (DI) mode and the file is open. +*/ +/* Prepares everything for using seasonal ratings if required*/ + if(SeasonalRating) + { + if(SeasonSignal != "") + { + RSignal = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(SeasonSignal)); + if(RSignal != nullptr) + RatingIdx = Trunc(RSignal->GetYValue_(ActiveCircuit[ActorID]->Solution->DynaVars.intHour)); + else + SeasonalRating = false; // The XYCurve defined doesn't exist + } + else + SeasonalRating = false; // The user didn't define the seasonal signal + } + + /* CHECK PDELEMENTS ONLY*/ + PDElem = (TPDElement*) ActiveCircuit[ActorID]->PDElements.Get_First(); + while(PDElem != nullptr) + { + if( (PDElem->Get_Enabled()) && !(PDElem->IsShunt) ) // Ignore shunts + { + if((PDElem->NormAmps > 0.0) || (PDElem->EmergAmps > 0.0)) + { + PDElem->ComputeIterminal(ActorID); + cMax = PDElem->MaxTerminalOneIMag(ActorID); // For now, check only terminal 1 for overloads + + // Section introduced in 02/20/2019 for allowing the automatic change of ratings + // when the seasonal ratings option is active + ClassName = LowerCase(PDElem->Get_myPName()); + //if SeasonalRating and (ClassName = 'line') and (PDElem.NumAmpRatings > 1) then + if(SeasonalRating && (PDElem->NumAmpRatings > 1)) // Includes all PDE + { + if(RatingIdx > PDElem->NumAmpRatings) + { + NormAmps = PDElem->NormAmps; + EmergAmps = PDElem->EmergAmps; + } + else + { + NormAmps = PDElem->AmpRatings[RatingIdx]; + EmergAmps = PDElem->AmpRatings[RatingIdx]; + } + } + else + { + NormAmps = PDElem->NormAmps; + EmergAmps = PDElem->EmergAmps; + } + if((cMax > NormAmps) || (cMax > EmergAmps)) + + // Gets the currents for the active Element + { + int stop = 0; + cBuffer.resize( PDElem->Get_NPhases() * PDElem->Get_NTerms() + 1 ); + PDElem->Get_Current_Mags(&(cBuffer[0]), ActorID); + cVector.resize( 3 + 1 ); // for storing + for(stop = 3, i = 1; i <= stop; i++) + { + cVector[i] = 0.0; + } + if(PDElem->Get_NPhases() < 3) + { + int stop = 0; + ClassName = PDElem->Get_FirstBus(); + j = AnsiPos(".", ClassName); // Removes the name of the bus + ClassName = ClassName.substr(j, ClassName.size()); + for(stop = 3, i = 1; i <= stop; i++) + { + j = AnsiPos(".", ClassName); // goes for the phase Number + if(j == 0) + { + k = StrToInt(ClassName); + cVector[k] = cBuffer[i - 1]; + break; + } + else + { + k = StrToInt(ClassName.substr(0, j - 1)); + cVector[k] = cBuffer[i - 1]; + ClassName = ClassName.substr(j, ClassName.size()); + } + } + } + else + { + int stop = 0; + for(stop = 3, i = 1; i <= stop; i++) + { + cVector[i] = cBuffer[i - 1]; + } + } + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(OV_MHandle[ActorID], with0->DynaVars.dblHour); + } + WriteintoMemStr(OV_MHandle[ActorID], String(", ") + FullName( PDElem ) ); + WriteintoMem(OV_MHandle[ActorID], NormAmps); + WriteintoMem(OV_MHandle[ActorID], EmergAmps); + if(PDElem->NormAmps > 0.0) + WriteintoMem(OV_MHandle[ActorID], cMax / NormAmps * 100.0); + else + WriteintoMem(OV_MHandle[ActorID], 0.0); + if(PDElem->EmergAmps > 0.0) + WriteintoMem(OV_MHandle[ActorID], cMax / EmergAmps * 100.0); + else + WriteintoMem(OV_MHandle[ActorID], 0.0); + /*# with ActiveCircuit[ActorID] do */ + { + // Find bus of first terminal + WriteintoMem(OV_MHandle[ActorID], ActiveCircuit[ActorID]->Buses[ ActiveCircuit[ActorID]->MapNodeToBus[ ( PDElem->NodeRef)[1 - 1] - 1 ].BusRef - 1]->kVBase); + } + // Adds the currents in Amps per phase at the end of the report + for(stop = 3, i = 1; i <= stop; i++) + { + WriteintoMem(OV_MHandle[ActorID], cVector[i]); + } + WriteintoMemStr(OV_MHandle[ActorID], " " + CHAR10); + } + } /* */ + } + PDElem = (TPDElement*) ActiveCircuit[ActorID]->PDElements.Get_Next(); + } +} + +void TEnergyMeter::ClearDI_Totals() +{ + int i; + for (i = 0; i < NumEMRegisters; i++) + { + DI_RegisterTotals[i] = 0.0; + } +} + +void TEnergyMeter::CreateFDI_Totals(int ActorID) +{ + int i = 0; + TEnergyMeterObj* mtr = nullptr; + try + { + if(TDI_MHandle[ActorID] != nullptr) + delete TDI_MHandle[ActorID]; + TDI_MHandle[ActorID] = Create_Meter_Space("Time"); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); // just get the first one + if(ASSIGNED(mtr)) + { + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMemStr(TDI_MHandle[ActorID], String(", \"") + mtr->RegisterNames[i - 1] + "\""); + } + } + WriteintoMemStr(TDI_MHandle[ActorID], CHAR10); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error creating: \"") + DI_Dir + + DIRSEP_STR "DI_Totals_" + + IntToStr(ActorID) + + ".CSV\": " + + (std::string) e.what(), 539); + } +} + +/* TSystemMeter */ + +void TSystemMeter::AppendDemandIntervalFile(int ActorID) +{ + String FileNm; + + /*Only called if "SaveDemandInterval"*/ + if(This_Meter_DIFileIsOpen) + return; + try + { + FileNm = EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR "DI_SystemMeter_" + IntToStr(ActorID) + ".CSV"; + AssignFile(SystemDIFile, FileNm); + /*File Must Exist*/ + if(FileExists(FileNm)) + ; + else + +// DI_MMFView:= MapFile2Memory(EnergyMeterClass.DI_Dir+'\DI_SystemMeter.CSV', DI_MMFHandle); +// DI_Cursor := GetMMFCursor(DI_MMFView); + OpenDemandIntervalFile(ActorID); + + IOResultToException(); + This_Meter_DIFileIsOpen = true; + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error opening demand interval file \"") + FileNm + + " for appending." + + CRLF + + (std::string) e.what(), 540); + } +} + +void TSystemMeter::Clear() +{ + kWh = 0.0; + kvarh = 0.0; + peakkW = 0.0; + peakkVA = 0.0; + Losseskwh = 0.0; + Losseskvarh = 0.0; + PeakLosseskW = 0.0; + dkWh = 0.0; + dkvarh = 0.0; + dLosseskWh = 0.0; + dlosseskvarh = 0.0; + FirstSampleAfterReset = true; +} + +void TSystemMeter::CloseDemandIntervalFile(int ActorID) +{ + String File_Path; + TEnergyMeterObj* mtr = nullptr; + if(This_Meter_DIFileIsOpen) + { + File_Path = EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR "DI_SystemMeter_" + IntToStr(ActorID) + ".CSV"; + CloseMHandler(SDI_MHandle[ActorID], File_Path, SDI_Append[ActorID]); + This_Meter_DIFileIsOpen = false; + } +} + +TSystemMeter::TSystemMeter() + : kWh(0.0), + dkWh(0.0), + kvarh(0.0), + dkvarh(0.0), + peakkW(0.0), + peakkVA(0.0), + Losseskwh(0.0), + dLosseskWh(0.0), + Losseskvarh(0.0), + dlosseskvarh(0.0), + PeakLosseskW(0.0), + FirstSampleAfterReset(false), + This_Meter_DIFileIsOpen(false) +{ + Clear(); + This_Meter_DIFileIsOpen = false; + SDI_MHandle[ActiveActor] = nullptr; + TDI_MHandle[ActiveActor] = nullptr; + VR_MHandle[ActiveActor] = nullptr; + OV_MHandle[ActiveActor] = nullptr; +} + +TSystemMeter::~TSystemMeter() +{ + if(SDI_MHandle[ActiveActor] != nullptr) + delete SDI_MHandle[ActiveActor]; + if(TDI_MHandle[ActiveActor] != nullptr) + delete TDI_MHandle[ActiveActor]; + if(VR_MHandle[ActiveActor] != nullptr) + delete VR_MHandle[ActiveActor]; + if(OV_MHandle[ActiveActor] != nullptr) + delete OV_MHandle[ActiveActor]; + // inherited; +} + + +void TSystemMeter::Integrate(double& reg, double Value, double& Deriv, int ActorID) +{ + if(ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + reg = reg + 0.5 * ActiveCircuit[ActorID]->Solution->IntervalHrs * (Value + Deriv); + } + else + /*Plain Euler integration*/ + reg = reg + ActiveCircuit[ActorID]->Solution->IntervalHrs * Value; + Deriv = Value; +} + +void TSystemMeter::OpenDemandIntervalFile(int ActorID) +{ + String F_header; + TEnergyMeterObj* mtr = nullptr; + try + { + if(This_Meter_DIFileIsOpen) + delete SDI_MHandle[ActorID]; + This_Meter_DIFileIsOpen = true; + if(SDI_MHandle[ActorID] != nullptr) + delete SDI_MHandle[ActorID]; + SDI_MHandle[ActorID] = Create_Meter_Space("\"Hour\", "); + WriteintoMemStr(SDI_MHandle[ActorID], "kWh, kvarh, \"Peak kW\", \"peak kVA\", \"Losses kWh\", \"Losses kvarh\", \"Peak Losses kW\"" + + CHAR10); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error opening demand interval file \"DI_SystemMeter.CSV\" for writing.") + CRLF + + (std::string) e.what(), 541); + } +} + +void TSystemMeter::Reset() +{ + Clear(); + // removed - open in solution If EnergyMeterClass.SaveDemandInterval Then OpenDemandIntervalFile; +} + +void TSystemMeter::Save(int ActorID) +{ + TTextRec f = {}; + String CSVName; + String Folder; + TEnergyMeterObj* mtr = nullptr; + try + { + CSVName = String("SystemMeter_") + IntToStr(ActorID) + ".CSV"; + /*If we are doing a simulation and saving interval data, create this in the + same directory as the demand interval data*/ + if(EnergyMeterClass[ActorID]->Get_SaveDemandInterval(ActorID)) + Folder = EnergyMeterClass[ActorID]->DI_Dir + DIRSEP_STR; + else + Folder = GetOutputDirectory(); + GlobalResult = CSVName; + SetLastResultFile(CSVName); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error opening System Meter File \"") + CRLF + + CSVName + + "\": " + + (std::string) e.what(), 542); + return; + } + } + try + { + if(SM_MHandle[ActorID] != nullptr) + delete SM_MHandle[ActorID]; + SM_MHandle[ActorID] = Create_Meter_Space("Year, "); + WriteintoMemStr(SM_MHandle[ActorID], "kWh, kvarh, \"Peak kW\", \"peak kVA\", \"Losses kWh\", \"Losses kvarh\", \"Peak Losses kW\"" + + CHAR10); + WriteintoMemStr(SM_MHandle[ActorID], IntToStr(ActiveCircuit[ActorID]->Solution->get_Fyear())); + WriteRegisters(f, ActorID); + WriteintoMemStr(SM_MHandle[ActorID], CHAR10); +/* } + __finally + {*/ + CloseMHandler(SM_MHandle[ActorID], Folder + CSVName, SM_Append[ActorID]); + SM_MHandle[ActorID] = nullptr; + } + catch (...) + { + // + } +} + +void TSystemMeter::TakeSample(int ActorID) +{ + + + /*Get total system energy out of the sources*/ + cPower = cmulreal(GetTotalPowerFromSources(ActorID), 0.001); // convert to kW + Integrate(kWh, cPower.re, dkWh, ActorID); + Integrate(kvarh, cPower.im, dkvarh, ActorID); // TODO TEMc + peakkW = max(cPower.re, peakkW); + peakkVA = max(cabs(cPower), peakkVA); + + /*Get total circuit losses*/ + cLosses = ActiveCircuit[ActorID]->Get_Losses(ActorID); // PD Elements except shunts + cLosses = cmulreal(cLosses, 0.001); // convert to kW + Integrate(Losseskwh, cLosses.re, dLosseskWh, ActorID); + Integrate(Losseskvarh, cLosses.im, dlosseskvarh, ActorID); // TODO TEMc + PeakLosseskW = max(cLosses.re, PeakLosseskW); + FirstSampleAfterReset = false; + if(This_Meter_DIFileIsOpen) + WriteDemandIntervalData(ActorID); +} + +void TEnergyMeter::CreateMeterTotals(int ActorID) +{ + int i = 0; + TEnergyMeterObj* mtr = nullptr; + if(EMT_MHandle[ActorID] != nullptr) + delete EMT_MHandle[ActorID]; + EMT_MHandle[ActorID] = Create_Meter_Space("Name"); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + if(ASSIGNED(mtr)) + { + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMemStr(EMT_MHandle[ActorID], String(", \"") + mtr->RegisterNames[i - 1] + "\""); + } + } + WriteintoMemStr(EMT_MHandle[ActorID], CHAR10); +} + +void TSystemMeter::WriteDemandIntervalData(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(SDI_MHandle[ActorID], with0->DynaVars.dblHour); + } + WriteintoMem(SDI_MHandle[ActorID], cPower.re); + WriteintoMem(SDI_MHandle[ActorID], cPower.im); + WriteintoMem(SDI_MHandle[ActorID], peakkW); + WriteintoMem(SDI_MHandle[ActorID], peakkVA); + WriteintoMem(SDI_MHandle[ActorID], cLosses.re); + WriteintoMem(SDI_MHandle[ActorID], cLosses.im); + WriteintoMem(SDI_MHandle[ActorID], PeakLosseskW); + WriteintoMemStr(SDI_MHandle[ActorID], CHAR10); +} + +void TSystemMeter::WriteRegisterNames(TTextRec& f) +{ + +// Does nothing +} + +void TSystemMeter::WriteRegisters(TTextRec& f, int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + WriteintoMem(SM_MHandle[ActorID], kWh); + WriteintoMem(SM_MHandle[ActorID], kvarh); + WriteintoMem(SM_MHandle[ActorID], peakkW); + WriteintoMem(SM_MHandle[ActorID], peakkVA); + WriteintoMem(SM_MHandle[ActorID], Losseskwh); + WriteintoMem(SM_MHandle[ActorID], Losseskvarh); + WriteintoMem(SM_MHandle[ActorID], PeakLosseskW); +} + +void TEnergyMeter::Set_DI_Verbose(int ActorID, bool Value) +{ + FDI_Verbose = Value; + ResetAll(ActorID); +} + +bool TEnergyMeter::Get_DI_Verbose(int ActorID) +{ + bool result = false; + result = FDI_Verbose; + return result; +} + +void TEnergyMeter::WriteTotalsFile(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + TRegisterArray Regsum; + int i = 0; + TTextRec f = {}; + /*Sum up all registers of all meters and write to Totals.CSV*/ + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Regsum[i - 1] = 0.0; + } + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + /*# with mtr do */ + { + auto with0 = mtr; + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + Regsum[i - 1] = Regsum[i - 1] + with0->Registers[i - 1] * with0->TotalsMask[i - 1]; + } + } + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + try + // Writes the file + { + int stop = 0; + if(FM_MHandle[ActorID] != nullptr) + delete FM_MHandle[ActorID]; + FM_MHandle[ActorID] = Create_Meter_Space("Year"); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + if(ASSIGNED(mtr)) + { + int stop = 0; + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMemStr(FM_MHandle[ActorID], String(", \"") + mtr->RegisterNames[i - 1] + "\""); + } //Write(F,', "', mtr.RegisterNames[i - 1],'"'); + } + WriteintoMemStr(FM_MHandle[ActorID], CHAR10); + WriteintoMemStr(FM_MHandle[ActorID], IntToStr(ActiveCircuit[ActorID]->Solution->get_Fyear())); + for(stop = NumEMRegisters, i = 1; i <= stop; i++) + { + WriteintoMem(FM_MHandle[ActorID], Regsum[i - 1]); + } + WriteintoMemStr(FM_MHandle[ActorID], CHAR10); + CloseMHandler(FM_MHandle[ActorID], DI_Dir + DIRSEP_STR "Totals_" + IntToStr(ActorID) + ".CSV", FM_Append[ActorID]); + FM_MHandle[ActorID] = nullptr; + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error writing demand interval file Totals_") + IntToStr(ActorID) + + ".CSV." + + CRLF + + (std::string) e.what(), 543); + } +} + +void TEnergyMeter::WriteVoltageReport(int ActorID) +{ + int i = 0; + int j = 0; + int l = 0; + double Vmagpu = 0.0; + int UnderCount = 0; + int OverCount = 0; + double OverVmax = 0.0; + double UnderVmin = 0.0; + int MinBus = 0; + int MaxBus = 0; + bool BusCounted = false; + TEnergyMeterObj* mtr = nullptr; + /*For any bus with a defined voltage base, test for > Vmax or < Vmin*/ + OverCount = 0; + UnderCount = 0; + MinBus = 0; + MaxBus = 0; + /*# with ActiveCircuit[ActorID] do */ + { + + int stop = 0; + OverVmax = ActiveCircuit[ActorID]->NormalMinVolts; + UnderVmin = ActiveCircuit[ActorID]->NormalMaxVolts; + for(stop = ActiveCircuit[ActorID]->NumBuses, i = 1; i <= stop; i++) + { + /*# with ActiveCircuit[ActorID]->Buses^[i] do */ + { + + BusCounted = false; + if(ActiveCircuit[ActorID]->Buses[i - 1]->kVBase > 1.0) // Primary Nodes first + { + int stop1 = 0; + for(stop1 = ActiveCircuit[ActorID]->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop1; j++) + { + if(!ADiakoptics || (ActorID == 1)) + Vmagpu = cabs(ActiveCircuit[ActorID]->Solution->NodeV[ActiveCircuit[ActorID]->Buses[i - 1]->GetRef(j)]) / ActiveCircuit[ActorID]->Buses[i - 1]->kVBase * 0.001; + else + Vmagpu = cabs(ActiveCircuit[ActorID]->Solution->VoltInActor1(ActiveCircuit[ActorID]->Buses[i - 1]->GetRef(j))) / ActiveCircuit[ActorID]->Buses[i - 1]->kVBase * 0.001; + if(Vmagpu > 0.1) // ignore neutral buses + { + if(Vmagpu < UnderVmin) + { + UnderVmin = Vmagpu; + MinBus = i; + } + if(Vmagpu > OverVmax) + { + OverVmax = Vmagpu; + MaxBus = i; + } + if(Vmagpu < ActiveCircuit[ActorID]->NormalMinVolts) + { + if(!BusCounted) // Don't count more than once + { + ++UnderCount; + BusCounted = true; + } + } + else + { + if(Vmagpu > ActiveCircuit[ActorID]->NormalMaxVolts) + { + if(!BusCounted) + { + ++OverCount; + BusCounted = true; + } + } + } + } + } + } + } + } /*For i*/ + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + WriteintoMem(VR_MHandle[ActorID], with2->DynaVars.dblHour); + } + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + IntToStr(UnderCount)); + WriteintoMem(VR_MHandle[ActorID], UnderVmin); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + IntToStr(OverCount)); + WriteintoMem(VR_MHandle[ActorID], OverVmax); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + ActiveCircuit[ActorID]->BusList.Get((unsigned int) MinBus)); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + ActiveCircuit[ActorID]->BusList.Get((unsigned int) MaxBus)); + + // Klugy but it works + // now repeat for buses under 1 kV + OverCount = 0; + UnderCount = 0; + MinBus = 0; + MaxBus = 0; + OverVmax = ActiveCircuit[ActorID]->NormalMinVolts; + UnderVmin = ActiveCircuit[ActorID]->NormalMaxVolts; + for(stop = ActiveCircuit[ActorID]->NumBuses, i = 1; i <= stop; i++) + { + /*# with ActiveCircuit[ActorID]->Buses^[i] do */ + { + + BusCounted = false; + if((ActiveCircuit[ActorID]->Buses[i - 1]->kVBase > 0.0) && (ActiveCircuit[ActorID]->Buses[i - 1]->kVBase <= 1.0)) + { + int stop1 = 0; + for(stop1 = ActiveCircuit[ActorID]->Buses[i - 1]->get_FNumNodesThisBus(), j = 1; j <= stop1; j++) + { + if(!ADiakoptics || (ActorID == 1)) + Vmagpu = cabs(ActiveCircuit[ActorID]->Solution->NodeV[ActiveCircuit[ActorID]->Buses[i - 1]->GetRef(j)]) / ActiveCircuit[ActorID]->Buses[i - 1]->kVBase * 0.001; + else + Vmagpu = cabs(ActiveCircuit[ActorID]->Solution->VoltInActor1(ActiveCircuit[ActorID]->Buses[i - 1]->GetRef(j))) / ActiveCircuit[ActorID]->Buses[i - 1]->kVBase * 0.001; + if(Vmagpu > 0.1) // ignore neutral buses + { + if(Vmagpu < UnderVmin) + { + UnderVmin = Vmagpu; + MinBus = i; + } + if(Vmagpu > OverVmax) + { + OverVmax = Vmagpu; + MaxBus = i; + } + if(Vmagpu < ActiveCircuit[ActorID]->NormalMinVolts) + { + if(!BusCounted) // Don't count more than once + { + ++UnderCount; + BusCounted = true; + } + } + else + { + if(Vmagpu > ActiveCircuit[ActorID]->NormalMaxVolts) + { + if(!BusCounted) + { + ++OverCount; + BusCounted = true; + } + } + } + } + } + } + } + } /*For i*/ + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + IntToStr(UnderCount)); + WriteintoMem(VR_MHandle[ActorID], UnderVmin); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + IntToStr(OverCount)); + WriteintoMem(VR_MHandle[ActorID], OverVmax); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + ActiveCircuit[ActorID]->BusList.Get((unsigned int) MinBus)); + WriteintoMemStr(VR_MHandle[ActorID], String(", ") + ActiveCircuit[ActorID]->BusList.Get((unsigned int) MaxBus)); + WriteintoMemStr(VR_MHandle[ActorID], CHAR10); + } +} + +void TEnergyMeter::InterpretRegisterMaskArray(TRegisterArray Mask, int ActorID) +{ + int i = 0; + int n = 0; + int stop = 0; + n = Parser[ActorID]->ParseAsVector(NumEMRegisters, *(pDoubleArray*) & Mask); + for(stop = NumEMRegisters, i = n + 1; i <= stop; i++) + { + Mask[i - 1] = 1.0; + } // Set the rest to 1 +} + +/* Feeder object code commented out +procedure TEnergyMeterObj.MakeFeederObj; +begin + If Assigned(MeteredElement) Then Begin + + FeederClass.NewObject(Name); // NewObject creates only if not existent. Else Inits and desynchs + FeederObj := ActiveCircuit[ActiveActor].ActiveCktElement as TFeederObj; + FeederObj.SetBus (1, MeteredElement.GetBus(MeteredTerminal)); + FeederObj.Nphases := MeteredElement.NPhases; + FeederObj.Nconds := MeteredElement.Nconds; + FeederObj.Enabled := ActiveCircuit[ActiveActor].RadialSolution; + + End + Else DoSimpleMsg('Error: Attempted to make Feeder Obj without instantiating Metered Element in Energymeter.'+name,544); +end; +*/ +/* Feeder object code commented out +procedure TEnergyMeterObj.RemoveFeederObj; +begin + + If Assigned(FeederObj) Then Begin + FeederObj.Enabled := FALSE; + FeederObj.SetCktElementFeederFlags (FALSE); + End; + +end; +*/ +// HasFeeder has to be true before feederObj will be re-enabled. + +void TEnergyMeterObj::EnableFeeder() +{ + +/* Feeder object code commented out HasFeeder can never be true + If HasFeeder Then Begin + If Not Assigned(FeederObj) Then MakeFeederObj + Else FeederObj.Enabled := TRUE; + FeederObj.SetCktElementFeederFlags (TRUE); + End; +*/ +} +/*Similar to Append, by creates the files.*/ + +void TEnergyMeter::OpenAllDIFiles(int ActorID) +{ + TEnergyMeterObj* mtr = nullptr; + // Filenm:String; + if(FSaveDemandInterval) + { + ClearDI_Totals(); // clears accumulator arrays + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_First(); + while(mtr != nullptr) + { + if(mtr->Get_Enabled()) + mtr->OpenDemandIntervalFile(ActorID); + mtr = (TEnergyMeterObj*) ActiveCircuit[ActorID]->EnergyMeters.Get_Next(); + } + SystemMeter->OpenDemandIntervalFile(ActorID); + + /*Optional Exception Reporting*/ + if(Do_OverloadReport) + OpenOverloadReportFile(ActorID); + if(Do_VoltageExceptionReport) + OpenVoltageReportFile(ActorID); + + /*Open FDI_Totals*/ + try + { + CreateFDI_Totals(ActorID); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error creating the memory space for demand interval \"") + get_myClass_name() + + ".CSV" + + " for appending." + + CRLF + + (std::string) e.what(), 538); + } + DIFilesAreOpen[ActorID] = true; + }/*IF*/ +} + +void TEnergyMeter::OpenOverloadReportFile(int ActorID) +{ + try + { + if(OverLoadFileIsOpen) + delete OV_MHandle[ActorID]; + OverLoadFileIsOpen = true; + if(OV_MHandle[ActorID] != nullptr) + delete OV_MHandle[ActorID]; + OV_MHandle[ActorID] = Create_Meter_Space("\"Hour\", \"Element\", \"Normal Amps\", \"Emerg Amps\", \"% Normal\", \"% Emerg\", \"kVBase\", \"I1(A)\", \"I2(A)\", \"I3(A)\"" + + CHAR10); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error creating memory space (Overload report) for writing.") + CRLF + + (std::string) e.what(), 541); + } +} + +void TEnergyMeter::OpenVoltageReportFile(int ActorID) +{ + try + { + if(VoltageFileIsOpen) + delete VR_MHandle[ActorID]; + VoltageFileIsOpen = true; + if(VR_MHandle[ActorID] != nullptr) + delete VR_MHandle[ActorID]; + VR_MHandle[ActorID] = Create_Meter_Space("\"Hour\", \"Undervoltages\", \"Min Voltage\", \"Overvoltage\", \"Max Voltage\", \"Min Bus\", \"Max Bus\""); + WriteintoMemStr(VR_MHandle[ActorID], ", \"LV Undervoltages\", \"Min LV Voltage\", \"LV Overvoltage\", \"Max LV Voltage\", \"Min LV Bus\", \"Max LV Bus\"" + + CHAR10); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error creating memory space (Voltage report) for writing.") + CRLF + + (std::string) e.what(), 541); + } +} + + /*RegisterNameList := TCommandList.Create(['kWh', 'kvarh', 'Max kW', 'Max kVA', 'Zone kWh', + 'Zone kvarh', 'Zone Max kW','Zone Max kVA','Overload kWh Normal','Overload kWh Emerg','Load EEN', + 'Load UE', 'Zone Losses kWh', 'Zone Losses kvarh', 'Zone Max kW Losses', 'Zone Max kvar Losses', + 'Gen kWh', 'Gen kvarh', 'Gen Max kW', 'Gen Max kVA']); */ + + + + +} // namespace EnergyMeter + + + + + diff --git a/OpenDSSC/Meters/EnergyMeter.h b/OpenDSSC/Meters/EnergyMeter.h new file mode 100644 index 0000000..c87ddc9 --- /dev/null +++ b/OpenDSSC/Meters/EnergyMeter.h @@ -0,0 +1,390 @@ +#ifndef EnergyMeterH +#define EnergyMeterH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "CktElement.h" +#include "PDElement.h" +#include "Arraydef.h" +#include "PointerList.h" +#include "CktTree.h" +#include "Ucomplex.h" +#include "Feeder.h" +#include "Load.h" +#include "generator.h" +#include "XYcurve.h" +#include "Command.h" +#include "d2c_structures.h" + + + + + +namespace EnergyMeter +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + This class of device accumulates the energy of the voltage and current in the + terminal of the device to which it is connected. + + It is an intelligent energy meter capable of measuring losses of all + devices within its "zone". + + The Zone is determined automatically after a circuit change. The Zone starts on the + opposite side of the branch on which the meter is located and continues in the same + direction through the network until + a) an open point is encountered + b) an open terminal or switch is encountered + c) another energy meter is encountered + d) a branch that is already included in a zone is encountered + + It keeps track of kwh, kvarh, UE, EEN, Losses, etc., having registers FOR each + of these quantities. + + In EEN/UE calculations, line overload takes precedence. + + If the Max Zone kW limits are specified, then these replace the line overload UE/EEN numbers. + These limits were added so that the user can override line limits in cases + such as networks where it is difficult to judge the UE from the individual + line limits. + + Only the maximum |kVA| overload is accumulated, not all. Loads downline from + an overload are marked WITH a factor representing the degree of overload. This + is used to compute EEN/UE FOR loads. + + FOR low voltages, the full kW FOR loads below the emergency min voltage are counted. + The EEN is proportioned based on how low the voltage is. + + Emergency min voltage must be less than normal min voltage. + +*/ + +/* CHANGE LOG + +8-3-99 Added Option property + Revised EEN/UE computation to do either total or excess +8-4-99 Save always rewrites file now and returns file name. + +11-11-99 Fixed bug in Take sample to use the maxvalue of the overload_EEN + +1-4-99 Modified tree checking to avoid picking up the same load more than once + Fixed bugs in sampling load EEN/UE + Modified Overload UE; added kwnormal, kwemerg properties for whole zone + +1-28-00 Changed to derived from Meter Element +2-2-00 Trapezoidal Integration option +4-14-00 Added load allocation algorithm +4-17-00 Removed shunt capacitors from meter zones +5-3-00 Corrected Zone kW, kvar accumulation to be actual power not target power +5-29-00 Fixed problem with Nphases not being set right for 1-phase devices. +6-15-01 Added Zonelist and LocalOnly options +7/6/01 Added Voltage Only option for Load UE calcs. +7/19/01 Added Totalizer Function for meterclass +7/24/01 Added Generator registers and code for adding generators to zone lists. + Changed to use zone loads and gens even if local only. If you only want the local + measurements, specify a null zone manually. +8/2/01 Fixed hole in Local only options. +4/29/03 Added ReduceZone Function +2/7/07 Fixed overload formulas +9/18/08 Added load loss and no load loss registers and aux registers +11/8/08 Revamped TakeSample to fix bugs with Demand Interval reporting +8/8/13 Added initial reliability calcs +3/27/2018 Corrected SAIDI calcs +*/ + +/*$WARN UNIT_PLATFORM OFF*/ +const int NumEMVbase = 7; +const int NumEMRegisters = 32 + 5 * NumEMVbase; // Total Number of energy meter registers + /*Fixed Registers*/ +const int Reg_kWh = 1 - 1; +const int Reg_kvarh = 2 - 1; +const int Reg_MaxkW = 3 - 1; +const int Reg_MaxkVA = 4 - 1; +const int Reg_ZonekWh = 5 - 1; +const int Reg_Zonekvarh = 6 - 1; +const int Reg_ZoneMaxkW = 7 - 1; +const int Reg_ZoneMaxkVA = 8 - 1; +const int Reg_OverloadkWhNorm = 9 - 1; // Max overload +const int Reg_OverloadkWhEmerg = 10 - 1; +const int Reg_LoadEEN = 11 - 1; +const int Reg_LoadUE = 12 - 1; // Energy served below normal voltage +const int Reg_ZoneLosseskWh = 13 - 1; +const int Reg_ZoneLosseskvarh = 14 - 1; +const int Reg_LossesMaxkW = 15 - 1; +const int Reg_LossesMaxkvar = 16 - 1; +const int Reg_LoadLosseskWh = 17 - 1; +const int Reg_LoadLosseskvarh = 18 - 1; +const int Reg_NoLoadLosseskWh = 19 - 1; +const int Reg_NoLoadLosseskvarh = 20 - 1; +const int Reg_MaxLoadLosses = 21 - 1; +const int Reg_MaxNoLoadLosses = 22 - 1; +const int Reg_LineLosseskWh = 23 - 1; +const int Reg_TransformerLosseskWh = 24 - 1; +const int Reg_LineModeLineLoss = 25 - 1; // for 3-phase feeder lines +const int Reg_ZeroModeLineLoss = 26 - 1; +const int Reg_3_phaseLineLoss = 27 - 1; +const int Reg_1_phaseLineLoss = 28 - 1; +const int Reg_GenkWh = 29 - 1; +const int Reg_Genkvarh = 30 - 1; +const int Reg_GenMaxkW = 31 - 1; +const int Reg_GenMaxkVA = 32 - 1; +const int Reg_VBaseStart = 32 - 1; // anchor for the voltage base loss registers +typedef double TRegisterArray[231/*# range 1..NumEMRegisters*/]; + + // --------- Feeder Section Definition ----------- + +struct TFeederSection +{ + int OCPDeviceType; // 1=Fuse; 2=Recloser; 3=Relay + int NCustomers; + int NBranches; + int TotalCustomers; + int SeqIndex; // index of pdelement with OCP device at head of section + double AverageRepairTime; + double SectFaultRate; + double SumFltRatesXRepairHrs; + double SumBranchFltRates; +}; +typedef TFeederSection FeederSectionArray; +typedef FeederSectionArray* pFeederSections; // Dummy dimension + // 0 is an OK index RCD 5/14/2021 + // --------- Feeder Section Definition ----------- + +class TSystemMeter : public System::TObject +{ + friend class TEnergyMeter; +public: + typedef TObject inherited; +private: + double kWh; + double dkWh; + double kvarh; + double dkvarh; + double peakkW; + double peakkVA; + double Losseskwh; + double dLosseskWh; + double Losseskvarh; + double dlosseskvarh; + double PeakLosseskW; + bool FirstSampleAfterReset; + bool This_Meter_DIFileIsOpen; + System::TTextRec SystemDIFile; + Ucomplex::complex cPower; + Ucomplex::complex cLosses; + void Clear(); + void Integrate(double& reg, double Value, double& Deriv, int ActorID); + void WriteRegisters(System::TTextRec& f, int ActorID); + void WriteRegisterNames(System::TTextRec& f); +protected: + void OpenDemandIntervalFile(int ActorID); + void WriteDemandIntervalData(int ActorID); + void CloseDemandIntervalFile(int ActorID); + void AppendDemandIntervalFile(int ActorID); +public: + void TakeSample(int ActorID); + void Reset(); + void Save(int ActorID); + TSystemMeter(); + virtual ~TSystemMeter(); +}; // derive strait from base class + +class TEnergyMeter : public MeterClass::TMeterClass +{ + friend class TEnergyMeterObj; +public: + typedef MeterClass::TMeterClass inherited; +//private: + //**** GeneratorClass : TGenerator; + bool FSaveDemandInterval; + bool FDI_Verbose; + System::TTextRec FOverLoadFile; + System::TTextRec FVoltageFile; + void ProcessOptions(const String Opts); + void Set_SaveDemandInterval(int ActorID, bool Value); + bool Get_SaveDemandInterval(int ActorID); + void CreateMeterTotals(int ActorID); + void CreateFDI_Totals(int ActorID); + void ClearDI_Totals(); + void WriteTotalsFile(int ActorID); + void OpenOverloadReportFile(int ActorID); + void OpenVoltageReportFile(int ActorID); + void WriteOverloadReport(int ActorID); + void WriteVoltageReport(int ActorID); + void InterpretRegisterMaskArray(TRegisterArray Mask, int ActorID); + void Set_DI_Verbose(int ActorID, bool Value); + bool Get_DI_Verbose(int ActorID); +protected: + void DefineProperties(); + virtual int MakeLike(const String EnergyMeterName); + void SetHasMeterFlag(int ActorID); +public: + TRegisterArray DI_RegisterTotals; + String DI_Dir; + System::TTextRec FDI_Totals; + System::TTextRec FMeterTotals; + TSystemMeter* SystemMeter; + bool Do_OverloadReport; + bool Do_VoltageExceptionReport; + bool OverLoadFileIsOpen; + bool VoltageFileIsOpen; + TEnergyMeter(); + virtual ~TEnergyMeter(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void ResetMeterZonesAll(int ActorID); + virtual void ResetAll(int ActorID); // Reset all meters in active circuit to zero + virtual void SampleAll(int ActorID); // Force all meters in active circuit to sample + virtual void SaveAll(int ActorID); + void AppendAllDIFiles(int ActorID); + void OpenAllDIFiles(int ActorID); + void CloseAllDIFiles(int ActorID); +}; + +class TEnergyMeterObj : public MeterElement::TMeterElement +{ + friend class TEnergyMeter; +public: + typedef MeterElement::TMeterElement inherited; +//private: + bool FirstSampleAfterReset; + bool ExcessFlag; + bool ZoneIsRadial; + bool VoltageUEOnly; + bool LocalOnly; + bool HasFeeder; + bool FLosses; + bool FLineLosses; + bool FXfmrLosses; + bool FSeqLosses; + bool F3PhaseLosses; + bool FVBaseLosses; + TFeederObj* FeederObj; // not used at present + pStringArray DefinedZoneList; + int DefinedZoneListSize; + + /*Limits on the entire load in the zone for networks where UE cannot be determined + by the individual branches*/ + double MaxZonekVA_Norm; + double MaxZonekVA_Emerg; + + /*Voltage bases in the Meter Zone*/ + vector VBaseTotalLosses; // allocated array + vector VBaseLineLosses; + vector VBaseLoadLosses; + vector VBaseNoLoadLosses; + vector VBaseLoad; + vector VBaseList; + int VBaseCount; + int MaxVBaseCount; + + /* Arrays for phase voltage report */ + vector VphaseMax; + vector VPhaseMin; + vector VPhaseAccum; + vector VPhaseAccumCount; + System::TTextRec VPhase_File; + bool VPhaseReportFileIsOpen; + + /*Demand Interval File variables*/ + System::TTextRec DI_File; + bool This_Meter_DIFileIsOpen; + void Integrate(int reg, double Deriv, double Interval, int ActorID); + void SetDragHandRegister(int reg, double Value); + double Accumulate_Load(Load::TLoadObj* pLoad, double& TotalZonekW, double& TotalZonekvar, double& TotalLoad_EEN, double& TotalLoad_UE, int ActorID); + void Accumulate_Gen(Generator::TGeneratorObj* pGen, double& TotalZonekW, double& TotalZonekvar, int ActorID); + void CalcBusCoordinates(CktTree::TCktTreeNode* StartBranch, int FirstCoordRef, int SecondCoordRef, int LineCount); + int AddToVoltBaseList(int BusRef, int ActorID); + String MakeDIFileName(int ActorID); + String MakeVPhaseReportFileName(int ActorID); + void AssignVoltBaseRegisterNames(); + + // Not used Procedure MakeFeederObj; + // Not used Procedure RemoveFeederObj; + void TotalupDownstreamCustomers(); +protected: + void OpenDemandIntervalFile(int ActorID); + void WriteDemandIntervalData(int ActorID); + void CloseDemandIntervalFile(int ActorID); + void AppendDemandIntervalFile(int ActorID); +public: + TBytesStream* DI_MHandle; + TBytesStream* PHV_MHandle; + std::vector< std::string> RegisterNames; + bool FPhaseVoltageReport; + CktTree::TCktTree* BranchList; // Pointers to all circuit elements in meter's zone + PointerList::TPointerList* SequenceList; // Pointers to branches in sequence from meter to ends + PointerList::TPointerList* LoadList; // Pointers to Loads in the Meter zone to aid reliability calcs + TRegisterArray Registers; + TRegisterArray Derivatives; + TRegisterArray TotalsMask; + + // Reliability data for Head of Zone + double SAIFI; // For this Zone - based on number of customers + double SAIFIkW; // For this Zone - based on kW load + double SAIDI; + double CAIDI; + double CustInterrupts; + bool AssumeRestoration; + + // Source reliability + double Source_NumInterruptions; // Annual interruptions for upline circuit + double Source_IntDuration; // Aver interruption duration of upline circuit + int SectionCount; + int ActiveSection; // For COM interface to index into FeederSections array + vector FeederSections; + vector ZonePCE; + TEnergyMeterObj(DSSClass::TDSSClass* ParClass, const String EnergyMeterName); + virtual ~TEnergyMeterObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, reset nphases + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); //Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + void ResetRegisters(); + virtual void TakeSample(int ActorID); + void SaveRegisters(int ActorID); + void MakeMeterZoneLists(int ActorID); + void ZoneDump(int ActorID); + void InterpolateCoordinates(); + void EnableFeeder(); + void AllocateLoad(int ActorID); + void ReduceZone(int ActorID); // Reduce Zone by eliminating buses and merging lines + void SaveZone(const String DirName); + void GetPCEatZone(); + void CalcReliabilityIndices(bool AssumeRestoration_in, int ActorID); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TEnergyMeterObj(DSSClass::TDSSClass* ParClass); + TEnergyMeterObj(String ClassName); + TEnergyMeterObj(); +}; +extern TEnergyMeterObj* ActiveEnergyMeterObj; + /* RegisterNameList :TCommandList; */ + + +} // namespace EnergyMeter + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace EnergyMeter; +#endif + +#endif // EnergyMeterH + + + + + diff --git a/OpenDSSC/Meters/LD_fm_infos.h b/OpenDSSC/Meters/LD_fm_infos.h new file mode 100644 index 0000000..3a1e6fb --- /dev/null +++ b/OpenDSSC/Meters/LD_fm_infos.h @@ -0,0 +1,66 @@ +#ifndef LD_fm_infosH +#define LD_fm_infosH + +#include "System.h" + +#include "Ucomplex.h" + +namespace LD_fm_infos +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2017, Electric Power Research Institute, Inc. + Added by Ying. + ---------------------------------------------------------- + + Definition of Fmonitor (virtue leader) Public Data Record +*/ + //PointerList; + + + /*Fmonitor public data/state variable structure*/ +#pragma pack (push, 1) + + //properties for Nodes + // highest voltage node + +struct TLD_fm_infos +{ + int ndnum_hghst; + bool b_ctrl_hghst; //can contribute more to the high volt problem + double volt_hghst; //low volt in pu + double volt_hgh_lmt; //low limit in pu + double Pinjec_hghst; //net P injection on this node + + // lowest voltage node + int ndnum_lwst; + bool b_ctrl_lwst; //can contribute more to the high volt problem + double volt_lwst; //low volt in pu + double volt_lw_lmt; //low limit in pu + double Pinjec_lwst; // net P injection on this node + + // overview information + double volt_avg; + double total_pg; //total generation of this cluster + double total_pl; //total load of this cluster + bool b_Curt_Ctrl; +}; +#pragma pack (pop) + + + +} // namespace LD_fm_infos + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LD_fm_infos; +#endif + +#endif // LD_fm_infosH + + + + + diff --git a/OpenDSSC/Meters/MemoryMap_lib.cpp b/OpenDSSC/Meters/MemoryMap_lib.cpp new file mode 100644 index 0000000..95a61fa --- /dev/null +++ b/OpenDSSC/Meters/MemoryMap_lib.cpp @@ -0,0 +1,353 @@ + +#pragma hdrstop + +#include "MemoryMap_lib.h" + +#include "DSSGlobals.h" + +using namespace std; +using namespace DSSGlobals; +using namespace System; + + +namespace MemoryMap_lib +{ + + +typedef vector TByteArr; + +WORD wordBuf = 0; +// $01A0 is Header for identifying String type data +// $02A0 is Header for identifying Double type data +//****************************************************************************** +// Creates a new BytesStream for the caller +// Returns the handler to handle the new memory space +//****************************************************************************** + +TBytesStream* Create_Meter_Space(String Init_Str) +{ + TBytesStream* result = nullptr; + TBytesStream* Mem_Space = nullptr; + Mem_Space = new TBytesStream(); + Mem_Space->WriteData((int16_t) 0x01A0); // Header for identifying String type data + Write_String(Mem_Space, Init_Str); + result = Mem_Space; + return result; +} +//****************************************************************************** +// Writes a string into the specified BytesStream +//****************************************************************************** + +void WriteintoMemStr(TBytesStream* Mem_Space, String Content) +{ + Mem_Space->WriteData((int16_t) 0x01A0); // Header for identifying String type data + Write_String(Mem_Space, Content); +} +//****************************************************************************** +// Writes a DBL into the specified BytesStream +//****************************************************************************** + +void WriteintoMem(TBytesStream* Mem_Space, double Content) +{ + Mem_Space->WriteData((int16_t) 0x02A0); // Header for identifying a double type data + Mem_Space->WriteData((float) Content); +} +//****************************************************************************** +// Saves the content of the BytesStream into the specified file path +// and destroys the ByteStream +//****************************************************************************** + +void CloseMHandler(TBytesStream* Mem_Space, const String Dest_Path, bool AppendFile) +{ + TTextRec f = {}; + unsigned char Buffer = 0; + int Idx = 0; + bool MWrite = false; + bool FHead = false; + int MType = 0; + int MSize = 0; + double TVariableDbl = 0.0; + +/* Open Output file; check for errors*/ + try + { + AssignFile(f, Dest_Path); + if(AppendFile) + Append(f); + else + Rewrite(f); + IOResultToException(); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error Attempting to open file: \"") + Dest_Path + + ". " + + (std::string) e.what(), 159000); + CloseFile(f); System::InOutRes = 0; + return; + } + } + try + { + Idx = 0; + MType = 0; // initialize to eliminate compiler warning + MWrite = false; + FHead = true; + MSize = (int) Mem_Space->Size(); + while(Idx < MSize) + { + Mem_Space->myPos = Idx; + if(MWrite == false) // Checks if we are writing + { + Mem_Space->Read(&Buffer, 1); + if(Buffer == 0xA0) // If not, checks the header of the next content + { + Mem_Space->myPos = Idx + 1; + Mem_Space->Read(&Buffer, 1); + if(Buffer < 0x03) + { + MWrite = true; + MType = (int) Buffer; + ++Idx; + } + } + } + else + { + switch(MType) + { + case 1: // Is a string + { + Mem_Space->Read(&Buffer, 1); + if(Buffer != 0xA0) + { + if(FHead) + FHead = false; + if(Buffer == 10) + { + WriteLn(f); + FHead = true; + //++Idx; + } + else + { + if(Buffer > 0) + Write(f, ((Char&) Buffer)); + } + } + else + { + Idx = Idx - 1; + MWrite = false; + } + } + break; // Is a Double + case 2: + { + Mem_Space->ReadData(&TVariableDbl, 4); + Idx = Idx + 3; + if(FHead) + FHead = false; + else + Write(f, ", "); + Write(f, Format("%.11f", TVariableDbl)); // Changed from "%-g", since %g can discard all decimal places + MWrite = false; + } + break; // Not recognized + default: + Idx = Idx; + break; + } + } + ++Idx; + } // make sure we close the file + /* } + __finally + {*/ + CloseFile(f); + } + catch (...) + { + // + } +} +//****************************************************************************** +// Returns the content of the BytesStream to be plotted with the OpenDSS Viewer +//****************************************************************************** + +void ReadMHandler(TBytesStream* Mem_Space, pDoubleArray2d X_axis, pStringArray1d Ylabels, pDoubleArray2d Y_axis) +{ + unsigned char Buffer = 0; + int Idx = 0; + bool MWrite = false; + bool FHead = false; + int MType = 0; + int MSize = 0; + double TVariableDbl = 0.0; + int strCounter = 0; + int colYCounter = 0; + int rowYCounter = 0; + int dblXCounter = 0; + X_axis->resize(1); + Y_axis->resize(1); + Ylabels->resize(1); + try + { + Idx = 0; + MType = 0; // initialize to eliminate compiler warning + strCounter = -1; + colYCounter = -1; + rowYCounter = 0; + dblXCounter = 0; + MWrite = false; + FHead = true; + MSize = (int) Mem_Space->Size(); + while(Idx < MSize) + { + Mem_Space->myPos = Idx; + if(MWrite == false) // Checks if we are writing + { + Mem_Space->Read(&Buffer, 1); + if(Buffer == 0xA0) // If not, checks the header of the next content + { + Mem_Space->myPos = Idx + 1; + Mem_Space->Read(&Buffer, 1); + if(Buffer < 0x03) + { + MWrite = true; + MType = (int) Buffer; + ++Idx; + } + } + } + else + { + switch(MType) + { + case 1: // Is a string + { + Mem_Space->Read(&Buffer, 1); + if(Buffer != 0xA0) + { + if(FHead) + FHead = false; + if(Buffer == 10) + { + ++colYCounter; + rowYCounter = 0; + FHead = true; + ++Idx; + } + else + { + if(Buffer > 0) + { + if((Buffer == 44) && (colYCounter < 0)) // If comma in header + { + ++strCounter; + Ylabels->resize( strCounter + 1 ); + } + else + { + if((strCounter >= 0) && (Buffer != 34) && (colYCounter < 0)) // If char diff than " in header (second and beyond) + (*Ylabels)[strCounter] = (*Ylabels)[strCounter] + ( (Char) Buffer ); + else + { + if((Buffer == 44) && (colYCounter >= 0)) // If comma in content (not header) + + // This section removes str from the data content. It stores 0.0 instead of the str. + { + ++rowYCounter; + if(colYCounter > 0) + { + Y_axis->resize(Y_axis->size(), vector (colYCounter + 1)); + } + else + Y_axis->resize( rowYCounter, vector (colYCounter + 1) ); + (*Y_axis)[rowYCounter - 1][colYCounter] = 0.0; + } + } + } + } + } + } + else + { + Idx = Idx - 1; + MWrite = false; + } + } + break; // Is a Double + case 2: + { + Mem_Space->ReadData(&TVariableDbl, 8); + Idx = Idx + 7; + if(FHead) + FHead = false; + else + { + ++rowYCounter; + } + if(colYCounter > 0) + { + Y_axis->resize( Y_axis->size(), vector ( colYCounter + 1 )); + } + else + Y_axis->resize( rowYCounter, vector (colYCounter + 1)); + if(rowYCounter == 0) + { + X_axis->resize( 1, vector (dblXCounter + 1)); + (*X_axis)[0][dblXCounter] = TVariableDbl * 3600; + ++dblXCounter; + } + else + (*Y_axis)[rowYCounter - 1][colYCounter] = TVariableDbl; + MWrite = false; + } + break; // Not recognized + default: + Idx = Idx; + break; + } + } + ++Idx; + } +/* } + __finally + {*/ + ; + } + catch (...) + { + // + } +} +//****************************************************************************** +// Writes the incomming String into the specified BytesStream +//****************************************************************************** + +void Write_String(TBytesStream* Mem_Space, const String Content) +{ + + // Str_Sz : Integer; + int Idx = 0; + +/* Str_Sz := length(Content)-1; + For idx := 0 to Str_Sz do Mem_Space.WriteData(Content[idx+1]);*/ + int stop = 0; + for(stop = (int) Content.size(), Idx = 1; Idx <= stop; Idx++) + { + Mem_Space->WriteData(Content[Idx - 1]); + } +} + + + + +} // namespace MemoryMap_lib + + + + + diff --git a/OpenDSSC/Meters/MemoryMap_lib.h b/OpenDSSC/Meters/MemoryMap_lib.h new file mode 100644 index 0000000..fd7dab6 --- /dev/null +++ b/OpenDSSC/Meters/MemoryMap_lib.h @@ -0,0 +1,46 @@ +#ifndef MemoryMap_libH +#define MemoryMap_libH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include + + +namespace MemoryMap_lib +{ + +/***************************Memory mapped files Library************************** +* This library was added to OpenDSS to handle the different functions related * +* with mapping files into memory to accelerate the data manipulation process * +* when including this device to the simulation * +* * +* last modification: 09-12-2022 * +******************************************************************************** +*/ +typedef double* DoubleArray1d; +typedef std::vector * pDoubleArray1d; +typedef std::vector < vector >* pDoubleArray2d; +typedef std::vector * pStringArray1d; + +TBytesStream* Create_Meter_Space(String Init_Str); +void WriteintoMemStr(TBytesStream* Mem_Space, String Content); +void WriteintoMem(TBytesStream* Mem_Space, double Content); +void CloseMHandler(TBytesStream* Mem_Space, const String Dest_Path, bool AppendFile); +void ReadMHandler(TBytesStream* Mem_Space, pDoubleArray2d X_axis, pStringArray1d Ylabels, pDoubleArray2d Y_axis); +void Write_String(TBytesStream* Mem_Space, const String Content); + + +} // namespace MemoryMap_lib + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace MemoryMap_lib; +#endif + +#endif // MemoryMap_libH + + + + + diff --git a/OpenDSSC/Meters/MeterClass.cpp b/OpenDSSC/Meters/MeterClass.cpp new file mode 100644 index 0000000..3280bda --- /dev/null +++ b/OpenDSSC/Meters/MeterClass.cpp @@ -0,0 +1,115 @@ + +#pragma hdrstop + +#include "MeterClass.h" +#include "MeterElement.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace CktElementClass; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace MeterElement; +using namespace ParserDel; +using namespace System; + +namespace MeterClass +{ + + + + TMeterClass::TMeterClass() + : NumMeterClassProps(0) + { + ; + DSSClassType = METER_ELEMENT; + } + + TMeterClass::~TMeterClass() + { + // inherited::Destroy(); + } + + + void TMeterClass::CountProperties() + { + NumProperties = NumProperties + NumMeterClassProps; + inherited::CountProperties(); + } + + // Define the properties for the base power delivery element class + + void TMeterClass::DefineProperties() + { + + // no properties + // PropertyName^[ActiveProperty + 1] := 'propname'; + // PropertyHelp^[ActiveProperty + 1] := 'prop help'; + ActiveProperty = ActiveProperty + NumMeterClassProps; + inherited::DefineProperties(); + } + + //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + int TMeterClass::ClassEdit(const void* ActiveMeterObj, int ParamPointer) + { + int result = 0; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TMeterElement(ActiveMeterObj) do */ + { + auto with0 = ((TMeterElement*) ActiveMeterObj); + + //CASE ParamPointer OF + //1: BaseFrequency := Parser.Dblvalue; + //ELSE + + //END; + inherited::ClassEdit(ActiveMeterObj, ParamPointer - NumMeterClassProps); + } + return result; + } + + //Var + // OtherMeterObj : TMeterElement; + + void TMeterClass::ClassMakeLike(const void* OtherObj) + { + + + // OtherMeterObj := TMeterElement(OtherObj); + TMeterElement((TDSSClass*) OtherObj); + //With TPCElement(ActiveDSSObject) Do + //Begin + // value:= OtherMeterObj.value; + //End; + } + + void TMeterClass::ResetAll(int ActorID) + { + DoSimpleMsg(String("Programming Error: Base MeterClass.ResetAll Reached for Class: ") + get_myClass_name(), 760); + } + + void TMeterClass::SampleAll(int ActorID) + { + DoSimpleMsg(String("Programming Error: Base MeterClass.SampleAll Reached for Class: ") + get_myClass_name(), 761); + } + + void TMeterClass::SaveAll(int ActorID) + { + DoSimpleMsg(String("Programming Error: Base MeterClass.SaveAll Reached for Class: ") + get_myClass_name(), 762); + } + + + + +} // namespace MeterClass + + + + + diff --git a/OpenDSSC/Meters/MeterClass.h b/OpenDSSC/Meters/MeterClass.h new file mode 100644 index 0000000..8b47d40 --- /dev/null +++ b/OpenDSSC/Meters/MeterClass.h @@ -0,0 +1,58 @@ +#ifndef MeterClassH +#define MeterClassH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElementClass.h" + +namespace MeterClass +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + /* + Base for Meter classes + */ + + + /*$M+*/ + + class TMeterClass : public TCktElementClass + { + public: + typedef TCktElementClass inherited; + private: + protected: + int ClassEdit(const void* ActiveMeterObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); + void CountProperties(); // Add no. of intrinsic properties + void DefineProperties(); // Add Properties of this class to propName + public: + int NumMeterClassProps; + TMeterClass(); + virtual ~TMeterClass(); + void ResetAll(int ActorID); + void SampleAll(int ActorID); // Force all monitors to take a sample + void SaveAll(int ActorID); // Force all monitors to save their buffers to disk + //__published: + }; + + +} // namespace MeterClass + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace MeterClass; +#endif + +#endif // MeterClassH + + + + + diff --git a/OpenDSSC/Meters/MeterElement.cpp b/OpenDSSC/Meters/MeterElement.cpp new file mode 100644 index 0000000..8833de3 --- /dev/null +++ b/OpenDSSC/Meters/MeterElement.cpp @@ -0,0 +1,104 @@ + +#pragma hdrstop + +#include "MeterElement.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" + + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace System; +using namespace Ucomplex; + +namespace MeterElement +{ + +TMeterElement::TMeterElement(String ClassName) : inherited(ClassName) {} +TMeterElement::TMeterElement() {} + + + +void TMeterElement::AllocateSensorArrays() +{ + if(ASSIGNED(MeteredElement)) + CalculatedCurrent.resize(MeteredElement->Yorder); + if(ASSIGNED(MeteredElement)) + CalculatedVoltage.resize(MeteredElement->Yorder); + SensorCurrent.resize(Fnphases); + SensorVoltage.resize(Fnphases); + PhsAllocationFactor.resize(Fnphases); +} + +void TMeterElement::CalcAllocationFactors(int ActorID) +{ + int IOffset = 0, + i = 0, + stop = 0; + double mag = 0.0; + + MeteredElement->GetCurrents(&CalculatedCurrent[0], ActorID); + + // The Phase Allocation Factor is the amount that the load must change to match the measured peak + IOffset = (MeteredTerminal - 1) * MeteredElement->Get_NConds(); + AvgAllocFactor = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + mag = cabs(CalculatedCurrent[i + IOffset - 1]); + if(mag > 0.0) + PhsAllocationFactor[i - 1] = SensorCurrent[i - 1] / mag; + else + PhsAllocationFactor[i - 1] = 1.0; // No change + AvgAllocFactor = AvgAllocFactor + PhsAllocationFactor[i - 1]; + } + AvgAllocFactor = AvgAllocFactor / Fnphases; // Factor for 2- and 3-phase loads +} + +TMeterElement::TMeterElement(TDSSClass* ParClass) + : inherited(ParClass), + ElementName(""), + MeteredElement(nullptr), + MeteredTerminal(1), + MeteredElementChanged(false), + AvgAllocFactor(0.0) +{ + DSSObjType = METER_ELEMENT; + SensorCurrent.clear(); + SensorVoltage.clear(); + PhsAllocationFactor.clear(); + CalculatedCurrent.clear(); + CalculatedVoltage.clear(); +} + +TMeterElement::~TMeterElement() +{ + if(!SensorCurrent.empty()) + SensorCurrent.clear(); + if(!SensorVoltage.empty()) + SensorVoltage.clear(); + if(!CalculatedCurrent.empty()) + CalculatedCurrent.clear(); + if(!CalculatedVoltage.empty()) + CalculatedVoltage.clear(); + if(!PhsAllocationFactor.empty()) + PhsAllocationFactor.clear(); + // inherited::Destroy(); +} + + +void TMeterElement::TakeSample(int ActorID) +{ + + // virtual function - should be overridden + DoSimpleMsg(String("Programming Error: Reached base Meterelement class for TakeSample.") + CRLF + + "Device: " + + get_Name(), 723); +} + +} // namespace MeterElement + diff --git a/OpenDSSC/Meters/MeterElement.h b/OpenDSSC/Meters/MeterElement.h new file mode 100644 index 0000000..f11f9ed --- /dev/null +++ b/OpenDSSC/Meters/MeterElement.h @@ -0,0 +1,59 @@ +#ifndef MeterElementH +#define MeterElementH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElement.h" +#include "Bus.h" +#include "Ucomplex.h" +#include "DSSClass.h" +#include "Arraydef.h" + +namespace MeterElement +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TMeterElement : public TDSSCktElement +{ +public: + typedef TDSSCktElement inherited; + String ElementName; + CktElement::TDSSCktElement* MeteredElement; // Pointer to target circuit element + int MeteredTerminal; + bool MeteredElementChanged; + std::vector SensorCurrent; + std::vector SensorVoltage; + std::vector PhsAllocationFactor; + std::vector CalculatedCurrent; + std::vector CalculatedVoltage; + double AvgAllocFactor; /*Average Allocation Factor*/ + TMeterElement(DSSClass::TDSSClass* ParClass); + virtual ~TMeterElement(); + virtual void TakeSample(int ActorID); // Sample control quantities and set action times in Control Queue + void AllocateSensorArrays(); + void CalcAllocationFactors(int ActorID); + TMeterElement(String ClassName); + TMeterElement(); +}; + + +} // namespace MeterElement + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace MeterElement; +#endif + +#endif // MeterElementH + + + + + diff --git a/OpenDSSC/Meters/Monitor.cpp b/OpenDSSC/Meters/Monitor.cpp new file mode 100644 index 0000000..58e8317 --- /dev/null +++ b/OpenDSSC/Meters/Monitor.cpp @@ -0,0 +1,2520 @@ + +#pragma hdrstop + +#include "Monitor.h" + +#include "Utilities.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "CktElement.h" +#include "Transformer.h" +#include "AutoTrans.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "ShowResults.h" +#include "mathutil.h" +#include "PointerList.h" +#include "TOPExport.h" +#include "Dynamics.h" +#include "Pstcalc.h" +#include "Capacitor.h" +#include "Storage.h" +#include +#include + +using namespace std; +using namespace Arraydef; +using namespace AutoTrans; +using namespace Capacitor; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace MeterClass; +using namespace MeterElement; +using namespace PCElement; +using namespace ParserDel; +using namespace PointerList; +using namespace Pstcalc; +using namespace Storage; +using namespace System; +using namespace TOPExport; +using namespace Transformer; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Monitor +{ + +TMonitorObj::TMonitorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TMonitorObj::TMonitorObj(String ClassName) : inherited(ClassName) {} +TMonitorObj::TMonitorObj() {} + + + + +TMonitorObj* ActiveMonitorObj = nullptr; +const int SEQUENCEMASK = 16; +const int MAGNITUDEMASK = 32; +const int POSSEQONLYMASK = 64; +const int ModeMask = 15; +const int NumPropsThisClass = 8; // Updated to 8 classes to include time constant for frequency calc +const int NumSolutionVars = 12; +char dummyRec[256]; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all Monitor objects + +TDSSMonitor::TDSSMonitor() +{ + ; + Class_Name = "Monitor"; + DSSClassType = DSSClassType + MON_ELEMENT; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TDSSMonitor::~TDSSMonitor() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TDSSMonitor::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[0] = "element"; + PropertyName[1] = "terminal"; + PropertyName[2] = "mode"; + PropertyName[3] = "action"; // buffer=clear|save + PropertyName[4] = "residual"; // buffer=clear|save + PropertyName[5] = "VIPolar"; // V I in mag and angle rather then re and im + PropertyName[6] = "PPolar"; // Power in power PF rather then power and vars + PropertyName[7] = "Tf"; // Time constant for low pass fitler (frequency Calculation) + + PropertyHelp[0] = "Name (Full Object name) of element to which the monitor is connected."; + PropertyHelp[1] = "Number of the terminal of the circuit element to which the monitor is connected. " + "1 or 2, typically. For monitoring states, attach monitor to terminal 1."; + PropertyHelp[2] = String("Bitmask integer designating the values the monitor is to capture: ") + CRLF + + "0 = Voltages, currents and frequency at designated terminal" + + CRLF + + "1 = Powers at designated terminal" + + CRLF + + "2 = Tap Position (Transformer Device only)" + + CRLF + + "3 = State Variables (PCElements only)" + + CRLF + + "4 = Flicker level and severity index (Pst) for voltages. No adders apply." + + CRLF + + " Flicker level at simulation time step, Pst at 10-minute time step." + + CRLF + + "5 = Solution variables (Iterations, etc)." + + CRLF + + "Normally, these would be actual phasor quantities from solution." + + CRLF + + "6 = Capacitor Switching (Capacitors only)" + + CRLF + + "7 = Storage state vars (Storage device only)" + + CRLF + + "8 = All winding currents (Transformer device only)" + + CRLF + + "9 = Losses, watts and var (of monitored device)" + + CRLF + + "10 = All Winding voltages (Transformer device only)" + + CRLF + + "Normally, these would be actual phasor quantities from solution." + + CRLF + + "11 = All terminal node voltages and line currents of monitored device" + + CRLF + + "12 = All terminal node voltages LL and line currents of monitored device" + + CRLF + + "Combine mode with adders below to achieve other results for terminal quantities:" + + CRLF + + "+16 = Sequence quantities" + + CRLF + + "+32 = Magnitude only" + + CRLF + + "+64 = Positive sequence only or avg of all phases" + + CRLF + + CRLF + + "Mix adder to obtain desired results. For example:" + + CRLF + + "Mode=112 will save positive sequence voltage and current magnitudes only" + + CRLF + + "Mode=48 will save all sequence voltages and currents, but magnitude only."; + PropertyHelp[3] = String("{Clear | Save | Take | Process}") + CRLF + + "(C)lears or (S)aves current buffer." + + CRLF + + "(T)ake action takes a sample." + + CRLF + + "(P)rocesses the data taken so far (e.g. Pst for mode 4)." + + CRLF + + CRLF + + "Note that monitors are automatically reset (cleared) when the Set Mode= command is issued. " + + "Otherwise, the user must explicitly reset all monitors (reset monitors command) or individual " + + "monitors with the Clear action."; + PropertyHelp[4] = "{Yes/True | No/False} Default = No. Include Residual cbannel (sum of all phases) for voltage and current. " + "Does not apply to sequence quantity modes or power modes."; + PropertyHelp[5] = "{Yes/True | No/False} Default = YES. Report voltage and current in polar form (Mag/Angle). (default) Otherwise, it will be real and imaginary."; + PropertyHelp[6] = "{Yes/True | No/False} Default = YES. Report power in Apparent power, S, in polar form (Mag/Angle).(default) Otherwise, is P and Q"; + PropertyHelp[7] = "Time constant for low pass filter during frequency calculations (sec). Default is Tf = 0.05 sec"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TDSSMonitor::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Monitor and add it to Monitor class list + /*# with ActiveCircuit[ActiveActor] do */ + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TMonitorObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TDSSMonitor::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int recalc = 0; + + // continue parsing with contents of Parser + // continue parsing with contents of Parser + ActiveMonitorObj = ((TMonitorObj*) ElementList.Get_Active()); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveMonitorObj); + result = 0; + recalc = 0; + /*# with ActiveMonitorObj do */ + { + auto with0 = ActiveMonitorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + ++recalc; + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 661); + break; + case 1: + { + with0->ElementName = ConstructElemName(LowerCase(Param)); // subtitute @var values if any + with0->Set_PropertyValue(1,with0->ElementName); + } + break; + case 2: + with0->MeteredTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->Mode = Parser[ActorID]->MakeInteger_(); + break; + case 4: + { + Param = LowerCase(Param); + switch(Param[0]) + { + case L's': + with0->Save(); + break; + case L'c': case L'r': + with0->ResetIt(ActorID); + break; + case L't': + with0->TakeSample(ActorID); + break; + case L'p': + { + with0->PostProcess(ActorID); + --recalc; + } + break; + default: + ; + break; + } + } + break; // buffer + case 5: + with0->IncludeResidual = InterpretYesNo(Param); + break; + case 6: + with0->VIpolar = InterpretYesNo(Param); + break; + case 7: + with0->Ppolar = InterpretYesNo(Param); + break; + case 8: // BLS + with0->Tf = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + ClassEdit(ActiveMonitorObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(recalc > 0) + with0->RecalcElementData(ActorID); + } + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to reset + +void TDSSMonitor::ResetAll(int ActorID) +{ + TMonitorObj* Mon = nullptr; + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First()); + while(Mon != nullptr) + { + if( ( (TDSSCktElement*) Mon )->Get_Enabled()) + Mon->ResetIt(ActorID); + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to take a sample + +void TDSSMonitor::SampleAll(int ActorID) +{ + TMonitorObj* Mon = nullptr; +// sample all monitors except mode 5 monitors + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + { + if(Mon->Mode != 5) + Mon->TakeSample(ActorID); + } + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all mode=5 monitors in the circuit to take a sample + +void TDSSMonitor::SampleAllMode5(int ActorID) +{ + TMonitorObj* Mon = nullptr; +// sample all Mode 5 monitors except monitors + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + { + if(Mon->Mode == 5) + Mon->TakeSample(ActorID); + } + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ + +void TDSSMonitor::PostProcessAll(int ActorID) +{ + TMonitorObj* Mon = nullptr; + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + Mon->PostProcess(ActorID); + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to save their buffers to disk + +void TDSSMonitor::SaveAll(int ActorID) +{ + TMonitorObj* Mon = nullptr; + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + Mon->Save(); + Mon = ((TMonitorObj*) ActiveCircuit[ActorID]->Monitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ + +int TDSSMonitor::MakeLike(const String MonitorName) +{ + int result = 0; + TMonitorObj* OtherMonitor = nullptr; + int i = 0; + result = 0; + /*See if we can find this Monitor name in the present collection*/ + OtherMonitor = ((TMonitorObj*) Find(MonitorName)); + if(OtherMonitor != nullptr) + /*# with ActiveMonitorObj do */ + { + auto with0 = ActiveMonitorObj; + int stop = 0; + (with0)->Set_NPhases((OtherMonitor)->Fnphases); + (with0)->Set_Nconds((OtherMonitor)->Fnconds); // Force Reallocation of terminal stuff + with0->BufferSize = OtherMonitor->BufferSize; + with0->ElementName = OtherMonitor->ElementName; + with0->MeteredElement = OtherMonitor->MeteredElement; // Pointer to target circuit element + with0->MeteredTerminal = OtherMonitor->MeteredTerminal; + with0->Mode = OtherMonitor->Mode; + with0->IncludeResidual = OtherMonitor->IncludeResidual; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherMonitor->Get_PropertyValue(i)); + } + with0->BaseFrequency = OtherMonitor->BaseFrequency; + } + else + DoSimpleMsg(String("Error in Monitor MakeLike: \"") + MonitorName + + "\" Not Found.", 662); + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TDSSMonitor::Init(int Handle, int ActorID) +{ + int result = 0; + TMonitorObj* Mon = nullptr; + result = 0; + if(Handle > 0) + { + Mon = ((TMonitorObj*) ElementList.Get(Handle)); + Mon->ResetIt(ActorID); + } + else + // Do 'em all + { + Mon = ((TMonitorObj*) ElementList.Get_First()); + while(Mon != nullptr) + { + Mon->ResetIt(ActorID); + Mon = ((TMonitorObj*) ElementList.Get_Next()); + } + } + return result; +} + + +/*==========================================================================*/ +/* TMonitorObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TMonitorObj::TMonitorObj(TDSSClass* ParClass, const String MonitorName) + : inherited(ParClass), + BufferSize(1024), + Hour(0), + Sec(0.0), + BufPtr(0), + NumTransformerCurrents(0), + NumWindingVoltages(0), + NumStateVars(0), + IncludeResidual(false), + VIpolar(false), + Ppolar(false), + FileSignature(0), + FileVersion(0), + BaseFrequency(0.0), + IsFileOpen(false), + ValidMonitor(false), + IsProcessed(false), + Mode(0), + SampleCount(0), + myHeaderSize(0), + stepCount(0), + Tf(0.05), + s(0) +{ + Set_Name(LowerCase(MonitorName)); + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + MonitorStream.clear(), + MonBuffer.clear(); + /*Current Buffer has to be big enough to hold all terminals*/ + CurrentBuffer.clear(); + VoltageBuffer.clear(); + StateBuffer.clear(); + FlickerBuffer.clear(); + SolutionBuffer.clear(); + WdgCurrentsBuffer.clear(); + WdgVoltagesBuffer.clear(); + PhsVoltagesBuffer.clear(); + NumTransformerCurrents = 0; + BaseFrequency = 60.0; + Hour = 0; + Sec = 0.0; + Mode = 0; // Standard Mode: V & I, complex values + MonBuffer.resize( BufferSize ); + BufPtr = 0; + ElementName = ((TDSSObject*) ActiveCircuit[ActiveActor]->CktElements.Get(1))->get_Name(); // Default to first circuit element (source) + MeteredElement = nullptr; + BufferFile = ""; + MonitorStream.clear(); // Create memory stream + IsFileOpen = false; + MeteredTerminal = 1; + IncludeResidual = false; + VIpolar = true; + Ppolar = true; + FileSignature = 43756; + FileVersion = 1; + SampleCount = 0; + IsProcessed = false; + DSSObjType = ParClass->DSSClassType; //MON_ELEMENT; + stepCount = 0; + Tf = 0.05; + s = 0; + InitPropertyValues(0); +} + +TMonitorObj::~TMonitorObj() +{ + MonitorStream.clear(); + ElementName = ""; + BufferFile = ""; + MonBuffer.clear(); + StateBuffer.clear(); + CurrentBuffer.clear(); + VoltageBuffer.clear(); + FlickerBuffer.clear(); + SolutionBuffer.clear(); + WdgVoltagesBuffer.clear(); + WdgCurrentsBuffer.clear(); + PhsVoltagesBuffer.clear(); + // inherited::Destroy(); +} + + + +/*--------------------------------------------------------------------------*/ + +void ConvertBlanks(String& s) +{ + int BlankPos = 0; + /* Convert spaces to Underscores */ + BlankPos = Pos(" ", s); + while(BlankPos > 0) + { + s[BlankPos] = L'_'; + BlankPos = Pos(" ", s); + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + int i = 0; + ValidMonitor = false; + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Monitored element must already exist + { + MeteredElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + switch((Mode & ModeMask)) + { + case 2: + case 8: + case 10: // Must be transformer + { + if((MeteredElement->DSSObjType & CLASSMASK) != XFMR_ELEMENT) + { + if((MeteredElement->DSSObjType & CLASSMASK) != AUTOTRANS_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " is not a transformer!", 663); + return; + } + } + } + break; // Must be PCElement + case 3: + { + if((MeteredElement->DSSObjType & BaseClassMask) != PC_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " must be a power conversion element (Load or Generator)!", 664); + return; + } + } + break; // Checking Caps Tap + case 6: + { + if((MeteredElement->DSSObjType & CLASSMASK) != CAP_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " is not a capacitor!", 2016001); + return; + } + } + break; // Checking if the element is a storage device + case 7: + { + if((MeteredElement->DSSObjType & CLASSMASK) != STORAGE_ELEMENT) /*and ((MeteredElement.DSSObjType And CLASSMASK) <> STORAGE2_ELEMENT)*/ + { + DoSimpleMsg(MeteredElement->get_Name() + " is not a storage device!", 2016002); + return; + } + } + break; + default: + ; + break; + } + if(MeteredTerminal > MeteredElement->Get_NTerms()) + { + DoErrorMsg(String("Monitor: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Respecify terminal no.", 665); + } + else + { + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + // Sets name of i-th terminal's connected bus in monitor's buslist + // This value will be used to set the NodeRef array (see TakeSample) + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + // Make a name for the Buffer File + /*ActiveCircuit[ActiveActor].CurrentDirectory + */ + BufferFile = CircuitName_[ActorID] + "Mon_" + get_Name() + ".mon"; + // removed 10/19/99 ConvertBlanks(BufferFile); // turn blanks into '_' + + /*Allocate Buffers*/ + switch((Mode & ModeMask)) + { + case 3: + { + if ( !ASSIGNED( ( (TPCElement*)MeteredElement )->DynamicEqObj ) ) + NumStateVars = ((TPCElement*) MeteredElement)->NumVariables(); + else + NumStateVars = ((TPCElement*)MeteredElement)->DynamicEqObj->get_FNumVars() * ((TPCElement*)MeteredElement)->DynamicEqVals[0].size(); + StateBuffer.resize(NumStateVars); + } + break; + case 4: + { + FlickerBuffer.resize(Get_NPhases()); + } + break; + case 5: + { + SolutionBuffer.resize(NumSolutionVars); + } + break; + case 8: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with0 = ((TAutoTransObj*) MeteredElement); + NumTransformerCurrents = 2 * with0->get_NumWindings() * ( with0 )->Get_NPhases(); + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with1 = ((TTransfObj*) MeteredElement); + NumTransformerCurrents = 2 * with1->get_NumWindings() * with1->Get_NPhases(); + } + WdgCurrentsBuffer.resize(NumTransformerCurrents); + } + break; + case 10: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with2 = ((TAutoTransObj*) MeteredElement); + NumWindingVoltages = with2->get_NumWindings() * ( with2 )->Get_NPhases(); + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with3 = ((TTransfObj*) MeteredElement); + NumWindingVoltages = with3->get_NumWindings() * with3->Get_NPhases(); + } + WdgVoltagesBuffer.resize(NumWindingVoltages); // total all phases, all windings + PhsVoltagesBuffer.resize(Get_NPhases()); + } + break; + case 11: + { + CurrentBuffer.resize(MeteredElement->Yorder + 1); + VoltageBuffer.resize(MeteredElement->Yorder + 1); + } + break; + case 12: + { + CurrentBuffer.resize(MeteredElement->Yorder + 1); + VoltageBuffer.resize(MeteredElement->Yorder + 1); + } + break; + default: + CurrentBuffer.resize(MeteredElement->Yorder + 1); + VoltageBuffer.resize(MeteredElement->Get_NConds() + 1); + break; + } + ClearMonitorStream(ActorID); + ValidMonitor = true; + } + } + else + { + MeteredElement = nullptr; // element not found + DoErrorMsg(String("Monitor: \"") + this->get_Name() + "\"", String("Circuit Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 666); + } +} + +void TMonitorObj::MakePosSequence(int ActorID) +{ + if(MeteredElement != nullptr) + { + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + switch((Mode & ModeMask)) + { + case 3: + { + NumStateVars = ((TPCElement*) MeteredElement)->NumVariables(); + StateBuffer.resize(NumStateVars); + } + break; + case 4: + { + FlickerBuffer.resize(Get_NPhases()); + } + break; + case 5: + { + SolutionBuffer.resize(NumSolutionVars); + } + break; + default: + CurrentBuffer.resize(MeteredElement->Yorder); + VoltageBuffer.resize(MeteredElement->Get_NConds()); + break; + } + ClearMonitorStream(ActorID); + ValidMonitor = true; + } + inherited::MakePosSequence(ActorID); +} + + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::CalcYPrim(int ActorID) +{ + + + /*A Monitor is a zero current source; Yprim is always zero.*/ + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. +} + +/*-------------------------------------------------------------------------- + Concatenates the given string into the header buffer +--------------------------------------------------------------------------*/ + +void TMonitorObj::Add2Header(AnsiString myText) +{ + int i = 0; + int j = 0; + int myLen = 0; + int stop = 0; + myLen = (int) StrBuffer.size(); + for(stop = (myText.size() - 1), i = 0; i <= stop; i++) + { + if(myText[i] != ((AnsiChar) 0)) + StrBuffer.push_back( myText[i] ); + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::ClearMonitorStream(int ActorID) +{ + std::vector PhaseLoc; + int i = 0; + int j = 0; + int IMax = 0; + int NumVI = 0; + int RecordSize = 0; + int IMin = 0; + bool IsPosSeq = false; + bool IsPower = false; + AnsiString NameOfState; + AnsiString Str_Temp; + try + { + MonitorStream.clear(); + IsProcessed = false; + SampleCount = 0; + IsPosSeq = false; + StrBuffer.clear(); + if(ActiveCircuit[ActorID]->Solution->IsHarmonicModel) + Add2Header("Freq, Harmonic, "); + else + Add2Header("hour, t(sec), "); + switch((Mode & ModeMask)) + { + case 2: + { + RecordSize = 1; // Transformer Taps + Add2Header("Tap (pu)"); + } + break; + case 3: + { + int stop = 0; + RecordSize = NumStateVars; // Statevariabes + for(stop = NumStateVars, i = 1; i <= stop; i++) + { + if ( !ASSIGNED( ( ( TPCElement* )MeteredElement )->DynamicEqObj ) ) + NameOfState = AnsiString(((TPCElement*) MeteredElement)->VariableName(i) + ","); + else + NameOfState = AnsiString(((TPCElement*)MeteredElement)->DynamicEqObj->Get_VarName(i - 1) + ","); + Add2Header(NameOfState.c_str()); + } + } + break; + case 4: + { + int stop = 0; + RecordSize = 2 * Fnphases; + for(stop = Fnphases, i = 1; i <= stop; i++) + { //AnsString and pAnsiChar replaced with AnsiString and pAnsiChar to make it compatible with Linux + Add2Header((AnsiString(String("Flk") + IntToStr(i) + ", Pst" + IntToStr(i))).c_str()); + if(i < Fnphases) + Add2Header(", "); + } + } + break; + case 5: + { + RecordSize = NumSolutionVars; + Add2Header("TotalIterations, "); + Add2Header("ControlIteration, "); + Add2Header("MaxIterations, "); + Add2Header("MaxControlIterations, "); + Add2Header("Converged, "); + Add2Header("IntervalHrs, "); + Add2Header("SolutionCount, "); + Add2Header("Mode, "); + Add2Header("Frequency, "); + Add2Header("Year, "); + Add2Header("SolveSnap_uSecs, "); + Add2Header("TimeStep_uSecs, "); + } + break; + case 6: + { + int stop = 0; + RecordSize = ((TCapacitorObj*) MeteredElement)->Get_FNumSteps(); // Capacitor Taps + for(stop = RecordSize, i = 1; i <= stop; i++) + { + Str_Temp = AnsiString(String("Step_") + IntToStr(i) + ","); + Add2Header(Str_Temp.c_str()); + } + } + break; + case 7: + { + RecordSize = 5; // Storage state vars + Add2Header(("kW output, ")); + Add2Header(("kvar output, ")); + Add2Header(("kW Stored, ")); + Add2Header(("%kW Stored, ")); + Add2Header(("State, ")); + } + break; // All winding Currents + case 8: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with0 = ((TAutoTransObj*) MeteredElement); + int stop = 0; + RecordSize = NumTransformerCurrents; // Transformer Winding Currents + for(stop = ( (TDSSCktElement*) with0 )->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = with0->get_NumWindings(), j = 1; j <= stop1; j++) + { + Str_Temp = AnsiString(Format("P%dW%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with1 = ((TTransfObj*) MeteredElement); + int stop = 0; + RecordSize = NumTransformerCurrents; // Transformer Winding Currents + for(stop = with1->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = with1->get_NumWindings(), j = 1; j <= stop1; j++) + { + Str_Temp = AnsiString(Format("P%dW%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + } + break; // watts vars of meteredElement + case 9: + { + RecordSize = 2; + Add2Header("watts, vars"); + } + break; // All Winding Voltages + case 10: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with2 = ((TAutoTransObj*) MeteredElement); + int stop = 0; + RecordSize = 2 * with2->get_NumWindings() * with2->Get_NPhases(); // Transformer Winding woltages + for(stop = with2->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = with2->get_NumWindings(), j = 1; j <= stop1; j++) + { + Str_Temp = AnsiString(Format("P%dW%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with3 = ((TTransfObj*) MeteredElement); + int stop = 0; + RecordSize = 2 * with3->get_NumWindings() * with3->Get_NPhases(); // Transformer Winding woltages + for(stop = with3->Get_NPhases(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = with3->get_NumWindings(), j = 1; j <= stop1; j++) + { + Str_Temp = AnsiString(Format("P%dW%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + } + break; /*All terminal voltages and currents ******/ + case 11: + { + int stop = 0; + RecordSize = 2 * 2 * MeteredElement->Yorder; // V and I + + /*Voltages*/ + for(stop = MeteredElement->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = MeteredElement->Get_NConds(), i = 1; i <= stop1; i++) + { + Str_Temp = AnsiString(Format("V%dT%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + + /*Currents*/ + for(stop = MeteredElement->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = MeteredElement->Get_NConds(), i = 1; i <= stop1; i++) + { + Str_Temp = AnsiString(Format("I%dT%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + break; /*All terminal voltages LL and currents ******/ + case 12: + { + int stop = 0; + /*# with MeteredElement do */ + { + auto with4 = MeteredElement; + RecordSize = 2 * ((with4->Get_NPhases() * with4->Get_NTerms()) + with4->Yorder); // V and I + PhaseLoc.resize( with4->Get_NPhases() + 1 ); + } + // Creates the map of phase combinations (LL) + for(stop = MeteredElement->Get_NPhases(), j = 1; j <= stop; j++) + { + PhaseLoc[j - 1] = j; + } + PhaseLoc[PhaseLoc.size() - 1] = 1; + + /*Voltages*/ + for(stop = MeteredElement->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = MeteredElement->Get_NPhases(), i = 1; i <= stop1; i++) + { + Str_Temp = AnsiString(Format("V%d-%dT%d,Deg, ", PhaseLoc[i - 1], PhaseLoc[i], j)); + Add2Header(Str_Temp.c_str()); + } + } + + /*Currents*/ + for(stop = MeteredElement->Get_NTerms(), j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = MeteredElement->Get_NConds(), i = 1; i <= stop1; i++) + { + Str_Temp = AnsiString(Format("I%dT%d,Deg, ", i, j)); + Add2Header(Str_Temp.c_str()); + } + } + } + break; + default: + if(((Mode & SEQUENCEMASK) > 0) && (Fnphases == 3)) // Convert to Symmetrical components + { + IsPosSeq = true; + NumVI = 3; + } + else + { + NumVI = Fnconds; + } + // Convert Voltage Buffer to power kW, kvar + if((Mode & ModeMask) == 1) + IsPower = true; + else + IsPower = false; + switch((Mode & (MAGNITUDEMASK + POSSEQONLYMASK))) + { + case 32: // Save Magnitudes only + { + int stop = 0; + RecordSize = 0; + for(stop = NumVI, i = 1; i <= stop; i++) + { + RecordSize += 1; + } + if(!IsPower) + { + int stop = 0; + for(stop = NumVI, i = 1; i <= stop; i++) + { + RecordSize += 1; + } + if(IncludeResidual) + RecordSize += 2; + for(stop = NumVI, i = 1; i <= stop; i++) + { + Add2Header(AnsiString(Format("|V|%d (volts)", i))); + Add2Header(", "); + } + if(IncludeResidual) + { + Add2Header("|VN| (volts)"); + Add2Header(", "); + } + for(stop = NumVI, i = 1; i <= stop; i++) + { + Add2Header((AnsiString(String("|I|") + IntToStr(i) + " (amps)"))); + if(i < NumVI) + Add2Header(", "); + } + if(IncludeResidual) + { + Add2Header(",|IN| (amps)"); + } + RecordSize += 1; + Add2Header(", Freq (Hz)"); // BLS + } + else + // Power + { + int stop = 0; + for(stop = NumVI, i = 1; i <= stop; i++) + { + if(Ppolar) + Add2Header((AnsiString(String("S") + IntToStr(i) + " (kVA)"))); + else + Add2Header((AnsiString(String("P") + IntToStr(i) + " (kW)"))); + if(i < NumVI) + Add2Header(", "); + } + } + } + break; // Save Pos Seq or Total of all Phases or Total power (Complex) + case 64: + { + RecordSize = 2; + if(!IsPower) + { + RecordSize = RecordSize + 3; + if(VIpolar) + Add2Header("V1, V1ang, I1, I1ang, Freq (Hz)"); // BLS + else + Add2Header("V1.re, V1.im, I1.re, I1.im, Freq (Hz)"); // BLS + } + else + { + if(Ppolar) + Add2Header("S1 (kVA), Ang "); + else + Add2Header("P1 (kW), Q1 (kvar)"); + } + } + break; // Save Pos Seq or Aver magnitude of all Phases of total kVA (Magnitude) + case 96: + { + RecordSize = 1; + if(!IsPower) + { + RecordSize = RecordSize + 2; + Add2Header("V, I, Freq (Hz) "); //BLS + } + else + // Power + { + if(Ppolar) + Add2Header("S1 (kVA)"); + else + Add2Header("P1 (kW)"); + } + } + break; // save V and I in mag and angle or complex kW, kvar + default: + RecordSize = NumVI * 2; + if(!IsPower) + { + int stop = 0; + if(IsPosSeq) + { + IMin = 0; + IMax = NumVI - 1; + } + else + { + IMin = 1; + IMax = NumVI; + } + RecordSize = RecordSize + NumVI * 2; + if(IncludeResidual) + RecordSize += 4; + for(stop = IMax, i = IMin; i <= stop; i++) + { + if(VIpolar) + Add2Header((AnsiString(String("V") + IntToStr(i) + ", VAngle" + IntToStr(i)))); + else + Add2Header((AnsiString(String("V") + IntToStr(i) + ".re, V" + IntToStr(i) + ".im"))); + Add2Header(", "); + } + if(IncludeResidual) + { + if(VIpolar) + Add2Header("VN, VNAngle"); + else + Add2Header("VN.re, VN.im"); + Add2Header(", "); + } + for(stop = IMax, i = IMin; i <= stop; i++) + { + if(VIpolar) + Add2Header((AnsiString(String("I") + IntToStr(i) + ", IAngle" + IntToStr(i)))); + else + Add2Header((AnsiString(String("I") + IntToStr(i) + ".re, I" + IntToStr(i) + ".im"))); + if(i < NumVI) + Add2Header(", "); + } + if(IncludeResidual) + { + if(VIpolar) + Add2Header(", IN, INAngle"); + else + Add2Header(", IN.re, IN.im"); + } + RecordSize = RecordSize + 1; + Add2Header(", Freq (Hz)"); // BLS + } + else + { + int stop = 0; + if(IsPosSeq) + { + IMin = 0; + IMax = NumVI - 1; + } + else + { + IMin = 1; + IMax = NumVI; + } + for(stop = IMax, i = IMin; i <= stop; i++) + { + if(Ppolar) + Add2Header((AnsiString(String("S") + IntToStr(i) + " (kVA), Ang" + IntToStr(i)))); + else + Add2Header((AnsiString(String("P") + IntToStr(i) + " (kW), Q" + IntToStr(i) + " (kvar)"))); + if(i < NumVI) + Add2Header(", "); + } + } + break; + } + break; + } /*CASE*/ + + + // RecordSize is the number of singles in the sample (after the hour and sec) + + // Write Header to Monitor Stream + // Write ID so we know it is a DSS Monitor file and which version in case we + // change it down the road + // Adds NULL character at the end of the header to note the end of the string + StrBuffer.push_back((AnsiChar) 0); + myHeaderSize = (int) StrBuffer.size(); // stores the size of the header for further use + /*# with MonitorStream do */ + { + auto& with5 = MonitorStream; + with5.Write(&FileSignature); + with5.Write(&FileVersion); + with5.Write(&RecordSize); + with5.Write(&Mode); + with5.Write(dummyRec); // adds the empty dummy record to avoid + // killing apps relying on this space + } + +/* So the file now looks like: (update 05-18-2021) + FileSignature (4 bytes) 32-bit Integers + FileVersion (4) + RecordSize (4) + Mode (4) + String (256) - > this is empty now + + hr (4) all singles + Sec (4) + Sample (4*RecordSize) + ... + + */ + } + catch (std::exception &e) + { + DoErrorMsg("Cannot open Monitor file.", (std::string) e.what(), String("Monitor: \"") + get_Name() + "\"", 670); + } +} + + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::OpenMonitorStream() +{ + if(!IsFileOpen) + { + MonitorStream.end(); // Positioned at End of Stream + IsFileOpen = true; + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::CloseMonitorStream(int ActorID) +{ + try + { + if(IsFileOpen) // only close open files + { + PostProcess(ActorID); + MonitorStream.begin(); // just move stream position to the beginning + IsFileOpen = false; + } + } + catch (std::exception &e) + { + DoErrorMsg("Cannot close Monitor stream.", (std::string) e.what(), String("Monitor: \"") + get_Name() + "\"", 671); + } +} + +/*--------------------------------------------------------------------------*/ + +// Saves present buffer to monitor file, resets bufferptrs and continues + +void TMonitorObj::Save() +{ + if(!IsFileOpen) + OpenMonitorStream(); // Position to end of stream + + /*Write present monitor buffer to monitorstream*/ + + MonitorStream.Write(&MonBuffer, BufPtr); + BufPtr = 0; // reset Buffer for next +} + + + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::ResetIt(int ActorID) +{ + BufPtr = 0; + ClearMonitorStream(ActorID); +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::PostProcess(int ActorID) +{ + if(IsProcessed == false) + { + if((Mode == 4) && ( ( MonitorStream.Position() ) > 0)) + DoFlickerCalculations(ActorID); + } + IsProcessed = true; +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::TakeSample(int ActorID) +{ + double dHour = 0.0, + dSum = 0.0; + bool IsPower = false, + IsSequence = false; + int BuffInit = 0, + BuffEnd = 0, + i = 0, + j = 0, + k = 0, + myRefIdx = 0, + CalcEnd = 0, + NumVI = 0, + Offset = 0; + double Freq = DefaultBaseFreq; // BLS + complex VangOld = CZero, // BLS + VangNew = CZero, // BLS + ResidualCurr = CZero, + ResidualVolt = CZero, + Sum = CZero, + CplxLosses = CZero; + complex V012[4/*# range 1..3*/] = { CZero, CZero, CZero, CZero }; + complex I012[4/*# range 1..3*/] = { CZero, CZero, CZero, CZero }; + + stepCount = stepCount + 1; // BLS - used for the frequency meter + + if(!(ValidMonitor && Get_Enabled())) + return; + ++SampleCount; + Hour = ActiveCircuit[ActorID]->Solution->DynaVars.intHour; + Sec = ActiveCircuit[ActorID]->Solution->DynaVars.T; + simdt = ActiveCircuit[ActorID]->Solution->DynaVars.h; + Offset = (MeteredTerminal - 1) * MeteredElement->Get_NConds(); // Used to index the CurrentBuffer array + + //Save time unless Harmonics mode and then save Frequency and Harmonic + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsHarmonicModel) + { + double myFreq = with0->get_FFrequency(); + AddDblsToBuffer((pDoubleArray) &myFreq, 1); // put freq in hour slot as a double + double myHarm = with0->Harmonic; + AddDblsToBuffer((pDoubleArray) &myHarm, 1); // stick harmonic in time slot in buffer + } + else + { + dHour = (double) Hour; // convert to double + AddDblsToBuffer((pDoubleArray)&dHour, 1); // put hours in buffer as a double + AddDblsToBuffer((pDoubleArray)&Sec, 1); // stick time in sec in buffer + } + } + switch((Mode & ModeMask)) + { + case 0: + case 1: // Voltage, current. Powers + + + // MeteredElement.GetCurrents(CurrentBuffer); + // To save some time, call ComputeITerminal + { + int stop = 0; + MeteredElement->ComputeIterminal(ActorID); // only does calc if needed (This calculates all + for(stop = MeteredElement->Yorder, i = 1; i <= stop; i++) + { + (CurrentBuffer)[i - 1] = (MeteredElement->Iterminal)[i - 1]; + } + try + { + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + // NodeRef is set by the main Circuit object + // It is the index of the terminal into the system node list + (VoltageBuffer)[i - 1] = ActiveCircuit[ActorID]->Solution->NodeV[NodeRef[i - 1]]; + } + } + catch (std::exception &e) + { + DoSimpleMsg( (std::string) e.what() + + CRLF + + "NodeRef is invalid. Try solving a snapshot or direct before solving in a mode that takes a monitor sample.", 672); + } + } + break; // Monitor Transformer Tap Position + case 2: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with1 = ((TAutoTransObj*) MeteredElement); + AddDblToBuffer(with1->Get_PresentTap(MeteredTerminal, ActorID)); + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with2 = ((TTransfObj*) MeteredElement); + AddDblToBuffer(with2->Get_PresentTap(MeteredTerminal,ActorID)); + } + return; + } // Pick up device state variables + case 3: + { + ((TPCElement*) MeteredElement)->GetAllVariables(&(StateBuffer[0])); + AddDblsToBuffer(&(StateBuffer[0]), NumStateVars); + return; + } // RMS phase voltages for flicker evaluation + case 4: + { + try + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (FlickerBuffer)[i - 1] = ActiveCircuit[ActorID]->Solution->NodeV[(NodeRef)[i - 1]]; + } + } + catch (std::exception &e) + { + DoSimpleMsg((std::string) e.what() + + CRLF + + "NodeRef is invalid. Try solving a snapshot or direct before solving in a mode that takes a monitor sample.", 672); + } + } + break; + /* Capture Solution Variables */ + case 5: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with3 = ActiveCircuit[ActorID]->Solution; + SolutionBuffer.push_back(static_cast(with3->Iteration)); + SolutionBuffer.push_back(static_cast(with3->ControlIteration)); + SolutionBuffer.push_back(static_cast(with3->MaxIterations)); + SolutionBuffer.push_back(static_cast(with3->MaxControlIterations)); + if(with3->ConvergedFlag) + SolutionBuffer.push_back(1); + else + SolutionBuffer.push_back(0); + SolutionBuffer.push_back(static_cast(with3->IntervalHrs)); + SolutionBuffer.push_back(static_cast(with3->SolutionCount)); + SolutionBuffer.push_back(static_cast(with3->Get_SolMode())); + SolutionBuffer.push_back(with3->get_FFrequency()); + SolutionBuffer.push_back(static_cast(with3->get_Fyear())); + SolutionBuffer.push_back(with3->get_Solve_Time_Elapsed()); + SolutionBuffer.push_back(with3->get_Step_Time_Elapsed()); + } + } + break; // Monitor Capacitor State + case 6: + { + /*# with TCapacitorObj(MeteredElement) do */ + { + auto with4 = ((TCapacitorObj*) MeteredElement); + int stop = 0; + for(stop = with4->Get_FNumSteps(), i = 1; i <= stop; i++) + { + AddDblToBuffer((double) with4->get_States(i,ActorID)); + } + } + return; + } // Monitor Storage Device state variables + case 7: + { + if((MeteredElement->DSSObjType & CLASSMASK) == STORAGE_ELEMENT) // Storage Element + { + /*# with TStorageObj(MeteredElement) do */ + { + auto with5 = ((TStorageObj*) MeteredElement); + AddDblToBuffer(with5->Get_PresentkW()); + AddDblToBuffer(with5->Get_Presentkvar()); + AddDblToBuffer(with5->StorageVars.kWhStored); + AddDblToBuffer((double((with5->StorageVars.kWhStored)) / (with5->StorageVars.kWhRating)) * 100.0L); + AddDblToBuffer((double) with5->get_fState()); + } + /*End + Else if (MeteredElement.DSSObjType And CLASSMASK) = STORAGE2_ELEMENT Then Begin // Storage2 Element + With TStorageObj(MeteredElement) Do Begin + AddDblToBuffer(Get_PresentkW()); + AddDblToBuffer(Get_Presentkvar()); + AddDblToBuffer(StorageVars.kWhStored); + AddDblToBuffer(((StorageVars.kWhStored)/(StorageVars.kWhRating))*100); + AddDblToBuffer(get_fState()); + End; */ + } + return; + } // Winding Currents + // Get all currents in each end of each winding + case 8: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with6 = ((TAutoTransObj*) MeteredElement); + int stop = 0; + with6->GetAllWindingCurrents(&(WdgCurrentsBuffer[0]), ActorID); + ConvertComplexArrayToPolar(&(WdgCurrentsBuffer[0]), NumTransformerCurrents); + // Put every other Current into buffer + // Current magnitude is same in each end + k = 1; + for(stop = ( (TDSSCktElement*) with6 )->Get_NPhases() * with6->get_NumWindings(), i = 1; i <= stop; i++) + { + AddDblsToBuffer((pDoubleArray)&(WdgCurrentsBuffer)[k - 1].re, 2); // Add Mag, Angle + k = k + 2; + } + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with7 = ((TTransfObj*) MeteredElement); + int stop = 0; + with7->GetAllWindingCurrents(&(WdgCurrentsBuffer[0]), ActorID); + ConvertComplexArrayToPolar(&(WdgCurrentsBuffer[0]), NumTransformerCurrents); + // Put every other Current into buffer + // Current magnitude is same in each end + k = 1; + for(stop = with7->Get_NPhases() * with7->get_NumWindings(), i = 1; i <= stop; i++) + { + AddDblsToBuffer((pDoubleArray)&(WdgCurrentsBuffer)[k - 1].re, 2); // Add Mag, Angle + k = k + 2; + } + // AddDblsToBuffer(@WdgCurrentsBuffer^[1].re, NumTransformerCurrents); + } + return; + } // losses + case 9: + { + CplxLosses = MeteredElement->Get_Losses(ActorID); + AddDblToBuffer(CplxLosses.re); + AddDblToBuffer(CplxLosses.im); + return; + } // Winding Voltages + // Get all Voltages across each winding and put into buffer + case 10: + { + if((MeteredElement->DSSObjType & CLASSMASK) == AUTOTRANS_ELEMENT) + /*# with TAutoTransObj(MeteredElement) do */ + { + auto with8 = ((TAutoTransObj*) MeteredElement); + int stop = 0; + for(stop = with8->get_NumWindings(), i = 1; i <= stop; i++) + { + int stop1 = 0; + with8->GetAutoWindingVoltages(i, &(PhsVoltagesBuffer[0]), ActorID); + for(stop1 = ( (TDSSCktElement*) with8 )->Get_NPhases(), j = 1; j <= stop1; j++) + { + (WdgVoltagesBuffer)[i + (j - 1) * with8->get_NumWindings() - 1] = (PhsVoltagesBuffer)[j - 1]; + } + } + ConvertComplexArrayToPolar(&(WdgVoltagesBuffer[0]), NumWindingVoltages); + /*Put winding Voltages into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(WdgVoltagesBuffer)[1 - 1].re, 2 * NumWindingVoltages); // Add Mag, Angle each winding + } + else + /*# with TTransfObj(MeteredElement) do */ + { + auto with9 = ((TTransfObj*) MeteredElement); + int stop = 0; + for(stop = with9->get_NumWindings(), i = 1; i <= stop; i++) + { + int stop1 = 0; + with9->GetWindingVoltages(i, &(PhsVoltagesBuffer[0]), ActorID); + for(stop1 = with9->Get_NPhases(), j = 1; j <= stop1; j++) + { + (WdgVoltagesBuffer)[i + (j - 1) * with9->get_NumWindings() - 1] = (PhsVoltagesBuffer)[j - 1]; + } + } + ConvertComplexArrayToPolar(&(WdgVoltagesBuffer[0]), NumWindingVoltages); + /*Put winding Voltages into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(WdgVoltagesBuffer)[1 - 1].re, 2 * NumWindingVoltages); // Add Mag, Angle each winding + } + return; + } /*Get all terminal voltages and currents of this device*/ + + /*Get All node voltages at all terminals*/ + case 11: + { + int stop = 0; + MeteredElement->ComputeVterminal(ActorID); + for(stop = MeteredElement->Yorder, i = 1; i <= stop; i++) + { + (VoltageBuffer)[i - 1] = (MeteredElement->Vterminal)[i - 1]; + } + ConvertComplexArrayToPolar(&(VoltageBuffer[0]), MeteredElement->Yorder); + /*Put Terminal Voltages into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(VoltageBuffer)[1 - 1].re, 2 * MeteredElement->Yorder); + + /*Get all terminsl currents*/ + MeteredElement->ComputeIterminal(ActorID); // only does calc if needed + for(stop = MeteredElement->Yorder, i = 1; i <= stop; i++) + { + (CurrentBuffer)[i - 1] = (MeteredElement->Iterminal)[i - 1]; + } + ConvertComplexArrayToPolar(&(CurrentBuffer[0]), MeteredElement->Yorder); + /*Put Terminal currents into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(CurrentBuffer)[1 - 1].re, 2 * MeteredElement->Yorder); + return; + } /*Get all terminal voltages LL and currents of this device - 05192021*/ + case 12: + { + /*# with MeteredElement do */ + { + auto with10 = MeteredElement; + /*Get All node voltages at all terminals*/ + int stop = 0; + with10->ComputeVterminal(ActorID); + for(stop = with10->Get_NTerms(), k = 1; k <= stop; k++) + { // Adds each term separately + int stop1 = 0; + BuffInit = 1 + with10->Get_NPhases() * (k - 1); + BuffEnd = with10->Get_NPhases() * k; + for(stop1 = BuffEnd, i = BuffInit; i <= stop1; i++) + { + (VoltageBuffer)[i - (BuffInit - 1) - 1] = (with10->Vterminal)[i - 1]; + } + if(with10->Get_NPhases() == with10->Get_NConds()) + myRefIdx = with10->Get_NPhases() + 1; + else + myRefIdx = with10->Get_NConds(); + + //Brings the first phase to the last place for calculations + (VoltageBuffer)[myRefIdx - 1] = (VoltageBuffer)[1 - 1]; + // Calculates the LL voltages + for(stop1 = with10->Get_NPhases(), i = 1; i <= stop1; i++) + { + (VoltageBuffer)[i - 1] = csub((VoltageBuffer)[i - 1], (VoltageBuffer)[i + 1 - 1]); + } + ConvertComplexArrayToPolar(&(VoltageBuffer[0]), with10->Yorder); + /*Put Terminal Voltages into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(VoltageBuffer)[1 - 1].re, 2 * with10->Get_NPhases()); + } + + /*Get all terminsl currents*/ + with10->ComputeIterminal(ActorID); // only does calc if needed + for(stop = with10->Yorder, i = 1; i <= stop; i++) + { + (CurrentBuffer)[i - 1] = (with10->Iterminal)[i - 1]; + } + ConvertComplexArrayToPolar(&(CurrentBuffer[0]), with10->Yorder); + /*Put Terminal currents into Monitor*/ + AddDblsToBuffer((pDoubleArray)&(CurrentBuffer)[1 - 1].re, 2 * with10->Yorder); + return; + } + } + break; + default: // Ignore invalid mask + return; + break; + } + if(((Mode & SEQUENCEMASK) > 0) && (Fnphases == 3)) // Convert to Symmetrical components + { + int stop = 0; + Phase2SymComp(&(VoltageBuffer[0]), &V012[0]); + Phase2SymComp(&(CurrentBuffer)[Offset + 1 - 1], &I012[0]); + NumVI = 3; + IsSequence = true; + // Replace voltage and current buffer with sequence quantities + for(stop = 3, i = 1; i <= stop; i++) + { + (VoltageBuffer)[i - 1] = V012[i - 1]; + } + for(stop = 3, i = 1; i <= stop; i++) + { + (CurrentBuffer)[Offset + i - 1] = I012[i - 1]; + } + } + else + { + NumVI = Fnconds; + IsSequence = false; + } + IsPower = false; // Init so compiler won't complain + switch((Mode & ModeMask)) + { + case 0: // Convert to Mag, Angle and compute residual if required + { + IsPower = false; + if (IncludeResidual) + { + if (VIpolar) + { + ResidualVolt = ResidualPolar(&VoltageBuffer[1], Fnphases); + ResidualCurr = ResidualPolar(&CurrentBuffer[Offset + 1], Fnphases); + } + else + { + ResidualVolt = Residual(&VoltageBuffer[1], Fnphases); + ResidualCurr = Residual(&CurrentBuffer[Offset + 1], Fnphases); + } + } + if (VIpolar) + { + ConvertComplexArrayToPolar(&(VoltageBuffer[0]), NumVI); + ConvertComplexArrayToPolar((pComplexArray) & (CurrentBuffer)[Offset + 1 - 1], NumVI); // Corrected 3-11-13 + } + // commented out for now + this->Freq = DefaultBaseFreq; //FreqCalc(stepCount, &VoltageBuffer[0], this->Vold, Sec); // BLS - Calculate frequency + } + break; // Convert Voltage Buffer to power kW, kvar or Mag/Angle + case 1: + { + CalcKPowers(&(VoltageBuffer[0]), &(VoltageBuffer[0]), (pComplexArray) &(CurrentBuffer)[Offset + 1 - 1], NumVI); + if(IsSequence || ActiveCircuit[ActorID]->PositiveSequence) + CmulArray(&(VoltageBuffer[0]), 3.0, NumVI); // convert to total power + if(Ppolar) + ConvertComplexArrayToPolar(&(VoltageBuffer[0]), NumVI); + IsPower = true; + } + break; + case 4: + { + IsPower = false; + ConvertComplexArrayToPolar(&(FlickerBuffer[0]), Fnphases); + } + break; + default: + ; + break; + } + + // Now check to see what to write to disk + switch((Mode & (MAGNITUDEMASK + POSSEQONLYMASK))) + { + case 32: // Save Magnitudes only + { + int stop = 0; + for(stop = NumVI, i = 1; i <= stop; i++) + { + AddDblToBuffer((VoltageBuffer)[i - 1].re); + } + if(IncludeResidual) + AddDblToBuffer(ResidualVolt.re); + if(!IsPower) + { + int stop = 0; + for(stop = NumVI, i = 1; i <= stop; i++) + { + AddDblToBuffer((CurrentBuffer)[Offset + i - 1].re); + } + if(IncludeResidual) + AddDblToBuffer(ResidualCurr.re); + AddDblToBuffer(this->Freq); // BLS + } + } + break; // Save Pos Seq or Avg of all Phases or Total power (Complex) + case 64: + { + if(IsSequence) + { + AddDblsToBuffer((pDoubleArray)&(VoltageBuffer)[2 - 1].re, 2); + if(!IsPower) + AddDblsToBuffer((pDoubleArray)&(CurrentBuffer)[Offset + 2 - 1].re, 2); + } + else + { + if(IsPower) + { + int stop = 0; + Sum = CZero; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + caccum(Sum, (VoltageBuffer)[i - 1]); + } + AddDblsToBuffer((pDoubleArray)&Sum.re, 2); + } + else + // Average the phase magnitudes and sum angles + { + int stop = 0; + Sum = CZero; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + caccum(Sum, (VoltageBuffer)[i - 1]); + } + Sum.re = Sum.re / Fnphases; + AddDblsToBuffer((pDoubleArray)&Sum.re, 2); + Sum = CZero; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + caccum(Sum, (CurrentBuffer)[Offset + i - 1]); + } // Corrected 3-11-13 + Sum.re = Sum.re / Fnphases; + AddDblsToBuffer((pDoubleArray)&Sum.re, 2); + AddDblToBuffer(this->Freq); // BLS + } + } + + } + break; // Save Pos Seq or Aver magnitude of all Phases of total kVA (Magnitude) + case 96: + { + if(IsSequence) + { + AddDblToBuffer((VoltageBuffer)[2 - 1].re); // Get_First() double is magnitude + if(!IsPower) + AddDblToBuffer((CurrentBuffer)[Offset + 2 - 1].re); + } + else + { + int stop = 0; + dSum = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + dSum = dSum + (VoltageBuffer)[i - 1].re; + } //Cabs(VoltageBuffer^[i]); + if(!IsPower) + dSum = dSum / Fnphases; + AddDblToBuffer(dSum); + if(!IsPower) + { + int stop = 0; + dSum = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + dSum = dSum + (CurrentBuffer)[Offset + i - 1].re; + } //Cabs(CurrentBuffer^[Offset+i]); + dSum = dSum / Fnphases; + AddDblToBuffer(dSum); + AddDblToBuffer(this->Freq); // BLS + } + } + } + break; + default: + switch(Mode) + { + case 4: + AddDblsToBuffer((pDoubleArray)&(FlickerBuffer)[1 - 1].re, Fnphases * 2); + break; + case 5: + AddDblsToBuffer((pDoubleArray)&(SolutionBuffer)[1 - 1], NumSolutionVars); + break; + default: + AddDblsToBuffer((pDoubleArray)&(VoltageBuffer)[1 - 1].re, NumVI * 2); + if(!IsPower) + { + if(IncludeResidual) + AddDblsToBuffer((pDoubleArray) &ResidualVolt, 2); + AddDblsToBuffer((pDoubleArray)&(CurrentBuffer)[Offset + 1 - 1].re, NumVI * 2); + if(IncludeResidual) + AddDblsToBuffer((pDoubleArray) &ResidualCurr, 2); + AddDblToBuffer(this->Freq); // BLS + } + break; + } + break; + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::AddDblsToBuffer(pDoubleArray Dbl, int Ndoubles) +{ + int i = 0; + int stop = 0; + for(stop = Ndoubles, i = 1; i <= stop; i++) + { + AddDblToBuffer((Dbl)[i - 1]); + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::AddDblToBuffer(double Dbl) +{ + + // first check to see if there's enough room + // if not, save to monitorstream first. + if(BufPtr == BufferSize) + Save(); + ++BufPtr; + MonBuffer[BufPtr - 1] = (float) Dbl; +} + +void TMonitorObj::DoFlickerCalculations(int ActorID) +{ + int FSignature = 0; + int FVersion = 0; + unsigned int RecordSize = 0; + unsigned int RecordBytes = 0; + float SngBuffer[100/*# range 1..100*/]; + float hr = 0.0F; + float s = 0.0F; + int n = 0; + int nPst = 0; + int i = 0; + int P = 0; + int bStart = 0; + std::vector < std::vector > Data; // indexed from zero (time) to FnPhases + std::vector < std::vector > pst; // indexed from zero to FnPhases - 1 + int ipst = 0; + float tpst = 0.0F; + float defaultpst = 0.0F; + float VBase = 0.0F; + int BusRef = 0; + n = SampleCount; + /*# with MonitorStream do */ + { + auto &with0 = MonitorStream; + with0.begin(); // Start at the beginning of the Stream + with0.Read(&FSignature); + with0.Read(&FVersion); + with0.Read(&RecordSize); + with0.Read(&Mode); + + with0.Read(dummyRec); + bStart = (int) with0.Position(); + } + RecordBytes = (unsigned int) (sizeof(SngBuffer[1 - 1]) * RecordSize); + try + + // read rms voltages out of the monitor stream into arrays + { + int stop = 0; + Data.resize( Fnphases + 1 ); + pst.resize( Fnphases ); + for(stop = Fnphases, P = 0; P <= stop; P++) + { + Data[P].resize(n); + } + i = 1; + while(!(MonitorStream.Position() >= MonitorStream.Size())) + { + /*# with MonitorStream do */ + { + auto &with1 = MonitorStream; + int stop = 0; + with1.Read(&hr); + with1.Read(&s); + with1.Read(SngBuffer); + (Data[0])[i - 1] = (float) (s + 3600.0F * hr); + for(stop = Fnphases, P = 1; P <= stop; P++) + { + (Data[P])[i - 1] = SngBuffer[2 * P - 1 - 1]; + } + i = i + 1; + } + } + + // calculate the flicker level and pst + nPst = 1 + Trunc((Data[0])[n - 1] / 600.0F); // pst updates every 10 minutes or 600 seconds + for(stop = Fnphases - 1, P = 0; P <= stop; P++) + { + pst[P].resize(nPst); + BusRef = (MeteredElement->Terminals)[MeteredTerminal - 1].BusRef; + VBase = (float) (1000.0 * ActiveCircuit[ActorID]->Buses[BusRef - 1]->kVBase); + FlickerMeter(n, BaseFrequency, VBase, &Data[0][0], &Data[P + 1][0], &pst[P][0]); + } + + // stuff the flicker level and pst back into the monitor stream + /*# with MonitorStream do */ + { + auto &with2 = MonitorStream; + int stop = 0; + with2.myPos = bStart; + tpst = 0.0F; + ipst = 0; + defaultpst = 0.0F; + for(stop = n, i = 1; i <= stop; i++) + { + int stop1 = 0; + if(((Data[0])[i - 1] - tpst) >= 600.0) + { + ++ipst; + tpst = (Data[0])[i - 1]; + } + with2.myPos = with2.Position() + 2 * sizeof(hr); // don't alter the time + for(stop1 = Fnphases, P = 1; P <= stop1; P++) + { + with2.Write( &(Data[P - 1][i - 1]), (int) sizeof(Data[P][i - 1]) ); + if((ipst > 0) && (ipst <= nPst)) + with2.Write(&pst[P - 2][ipst - 1], sizeof(pst[P - 2][ipst - 1])); + else + with2.Write(&defaultpst); + } + } + } +/* } + __finally + {*/ + + for(int stop = Fnphases, P = 0; P <= stop; P++) + { + Data[P].clear(); + } + for(stop = Fnphases - 1, P = 0; P <= stop; P++) + { + pst[P].clear(); + } + } + catch (...) + { + // + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::TranslateToCSV(bool Show, int ActorID) +{ + String CSVName; + TTextRec f = {}; + int FSignature = 0; + int FVersion = 0; + float hr = 0.0F; + unsigned int i = 0; + int Mode = 0; + unsigned int Nread = 0; + PAnsiChar PStr = nullptr; + unsigned int RecordBytes = 0; + unsigned int RecordSize = 0; + float s = 0.0F; + float SngBuffer[100/*# range 1..100*/] = {0.0}; + Save(); // Save present buffer + CloseMonitorStream(ActorID); // Position at beginning + CSVName = Get_FileName(ActorID); + try + { + AssignFile(f, CSVName); // Make CSV file + if(ConcatenateReports && (ActorID != 1)) + Append(f); + else + Rewrite(f); + IOResultToException(); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error opening CSVFile \"") + CSVName + + "\" for writing" + + CRLF + + (std::string) e.what(), 672); + return; + } + } + /*# with MonitorStream do */ + { + auto &with0 = MonitorStream; + with0.begin(); // Start at the beginning of the Stream + with0.Read(&FSignature); + with0.Read(&FVersion); + with0.Read(&RecordSize); + with0.Read(&Mode); + with0.Read(dummyRec); + } + PStr = &StrBuffer[0]; + if(!ConcatenateReports || (ActorID == 1)) + WriteLn(f, PStr); + RecordBytes = (unsigned int) (sizeof(SngBuffer[1 - 1]) * RecordSize); + try + { + try + { + while(!(MonitorStream.Position() >= MonitorStream.Size())) + { + int stop = 0; + /*# with MonitorStream do */ + { + auto& with1 = MonitorStream; + with1.Read(&hr); + with1.Read(&s); + Nread = with1.Read(&SngBuffer[0], RecordBytes); + } + if(Nread < RecordBytes) + break; + + Write(f, Format("%d", (int)hr)); // hours + Write(f, ", "); Write(f, Format("%.5f", s)); // sec + for (int i = 0; i <= RecordSize-1; i++) + { + Write(f, ", "); Write(f, Format("%-.6g", SngBuffer[i])); + } + WriteLn(f); + } + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("Error Writing CSVFile \"") + CSVName + + "\" " + + CRLF + + (std::string) e.what(), 673); + } + } +/* } + __finally + {*/ + CloseMonitorStream(ActorID); + CloseFile(f); + } + catch (...) + { + // + } + if (Show && AutoDisplayShowReport) + FireOffEditor(CSVName); + + GlobalResult = CSVName; +} + +/*--------------------------------------------------------------------------*/ //Get present value of terminal Curr for reports + +void TMonitorObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + +/* + Revised 12-7-99 to return Zero current instead of Monitored element current because + it was messing up Newton iteration. +*/ + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TMonitorObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TMonitorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int k = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "// BufferSize="); WriteLn(f, BufferSize, 0); } + { Write(f, "// Hour="); WriteLn(f, Hour, 0); } + { Write(f, "// Sec="); WriteLn(f, Sec, 0); } + { Write(f, "// BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + { Write(f, "// Bufptr="); WriteLn(f, BufPtr, 0); } + WriteLn(f, "// Buffer="); + k = 0; + for(stop = BufPtr, i = 1; i <= stop; i++) + { + { Write(f, (MonBuffer)[i - 1], 0, 1); Write(f, ", "); } + ++k; + if(k == (2 + Fnconds * 4)) + { + WriteLn(f); + k = 0; + } + } + WriteLn(f); + } +} + +void TMonitorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, ""); //'element'; + Set_PropertyValue(2, "1"); //'terminal'; + Set_PropertyValue(3, "0"); //'mode'; + Set_PropertyValue(4, ""); // 'action'; // buffer=clear|save|take|process + Set_PropertyValue(5, "NO"); + Set_PropertyValue(6, "YES"); + Set_PropertyValue(7, "YES"); + inherited::InitPropertyValues(NumPropsThisClass); +} + + +/*--------------------------------------------------------------------------*/ + +void TDSSMonitor::TOPExport(String ObjName) +{ +/* + TStringList* NameList; + TStringList* cNames; + pDoubleArray Vbuf; + pDoubleArray CBuf; + TMonitorObj* Obj = nullptr; + int i = 0; + double MaxTime = 0.0; + PointerList::TPointerList* ObjList = nullptr; + bool Hours = false; + TMonitorStrBuffer StrBuffer; + PAnsiChar pStrBuffer = nullptr; + int FVersion = 0; + int FSignature = 0; + int iMode = 0; + unsigned int Nread = 0; + unsigned int RecordSize = 0; + unsigned int RecordBytes = 0; + unsigned int PositionSave = 0; + float SngBuffer[100]; //# range 1..100 + double Time = 0.0; + float hr = 0.0F; + float s = 0.0F; + String TrialFileName; + String FileNumber; + // Create a unique file name + TrialFileName = GetOutputDirectory() + "TOP_Mon_" + ObjName; + FileNumber = ""; + i = 0; + while(FileExists(TrialFileName + FileNumber + ".STO")) + { + ++i; + FileNumber = IntToStr(i); + } + TOPTransferFile->Filename = TrialFileName + FileNumber + ".STO"; + try + { + //TOPTransferFile->Open(); + } + catch (std::exception &e) + { + { + DoSimpleMsg(String("TOP Transfer File Error: ") + (std::string) e.what(), 674); + try + { + //TOPTransferFile->Close(); + //OK if Error + } + catch(...) + { + ; + } + return; + } + } + + //Send only fixed interval data + ObjList = new PointerList::TPointerList(10); + NameList = new TStringList(); + cNames = new TStringList(); + + //Make a List of fixed interval data where the interval is greater than 1 minute + if(CompareText(ObjName, "ALL") == 0) + { + DoSimpleMsg("ALL option not yet implemented.", 675); + // Obj := ElementList.Get_First(); + // While Obj <> Nil Do Begin + // If Obj.Interval>(1.0/60.0) Then ObjList.Add(Obj); + // Obj := ElementList.Get_Next(); + // End; + } + else + { + Obj = ((TMonitorObj*) Find(ObjName)); + if(Obj != nullptr) + ObjList->Add(Obj); + else + DoSimpleMsg(String("Monitor.") + ObjName + " not found.", 676); + } + + //If none found, exit + if(ObjList->get_myNumList() > 0) + { + Obj = ((TMonitorObj*) ObjList->Get_First()); //And only + //with Obj do + { + auto with0 = Obj; + int stop = 0; + with0->Save(); // Save present buffer + with0->CloseMonitorStream(ActiveActor); + pStrBuffer = (PAnsiChar) &(with0->StrBuffer); + //with MonitorStream do + { + auto &with1 = with0->MonitorStream; + with1.begin(); // Start at the beginning of the Stream + with1.Read(&FSignature); + with1.Read(&FVersion); + with1.Read(&RecordSize); + with1.Read(&iMode); + with1.Read(dummyRec); + } + + //Parse off Channel Names + AuxParser[ActiveActor]->WhiteSpace = ""; + AuxParser[ActiveActor]->CmdString = pStrBuffer; + AuxParser[ActiveActor]->GetNextParam(); // pop off two + AuxParser[ActiveActor]->GetNextParam(); + for(stop = RecordSize, i = 1; i <= stop; i++) + { + AuxParser[ActiveActor]->GetNextParam(); + NameList->push_back(AuxParser[ActiveActor]->MakeString_()); + } + AuxParser[ActiveActor]->ResetDelims(); + + //Write TOP Header + + //Find Max number of points + RecordBytes = (unsigned int) (sizeof(SngBuffer[1 - 1]) * RecordSize); + Vbuf->resize( RecordSize ); // Put Everything in here for now + CBuf->resize( 1 ); // just a dummy -- Cbuf is ignored here + + //Get first time value and set the interval to this value + hr = 0.0F; + s = 0.0F; + if(!(with0->MonitorStream.Position() >= with0->MonitorStream.Size())) + //with MonitorStream do + { + auto &with2 = with0->MonitorStream; + with2.Read(&hr); // singles + with2.Read(&s); + with2.Read(SngBuffer); + } + //Set Hours or Seconds for Interval + Hours = true; + if((s > 0.0F) && (s < 100.0F)) + Hours = false; + switch(ActiveCircuit[ActiveActor]->Solution->DynaVars.SolutionMode) + { + case HARMONICMODE: + Time = hr; + break; + default: + if(Hours) // in hrs + Time = hr + s / 3600.0F; + else + Time = hr * 3600.0F + s; // in sec + break; + } + + //Now find Maxtime in Monitor + PositionSave = (unsigned int) with0->MonitorStream.Position(); + with0->MonitorStream.end(); + if(!(with0->MonitorStream.Position() >= with0->MonitorStream.Size())) + //# with MonitorStream do + { + auto &with3 = with0->MonitorStream; + with3.Read(&hr); // singles + with3.Read(&s); + with3.Read(SngBuffer); + } + switch(ActiveCircuit[ActiveActor]->Solution->DynaVars.SolutionMode) + { + case HARMONICMODE: + MaxTime = hr; + break; + default: + if(Hours) // in hrs + MaxTime = hr + s / 3600.0F; + else + MaxTime = hr * 3600.0F + s; // in sec + break; + } + + //Go Back to where we were + with0->MonitorStream.begin(); + TOPTransferFile->WriteHeader(Time, MaxTime, Time, (int) RecordSize, 0, 16, "DSS (TM), EPRI (R)"); + TOPTransferFile->WriteNames(*NameList, *cNames); + + //Now Process rest of monitor file + if(!(with0->MonitorStream.Position() >= with0->MonitorStream.Size())) + { + do + { + int stop = 0; + for(stop = RecordSize, i = 1; i <= stop; i++) + { + (*Vbuf)[i - 1] = SngBuffer[i - 1]; + } + TOPTransferFile->WriteData(Time, Vbuf, CBuf); + //# with MonitorStream do + { + auto &with4 = with0->MonitorStream; + with4.Read(&hr); + with4.Read(&s); + Nread = with4.Read(SngBuffer); + } + if(Nread < RecordBytes) + break; + switch(ActiveCircuit[ActiveActor]->Solution->DynaVars.SolutionMode) + { + case HARMONICMODE: + Time = hr; + break; + default: + if(Hours) // in hrs + Time = hr + s / 3600.0F; + else + Time = hr * 3600.0F + s; // in sec + break; + } + } + while(!(with0->MonitorStream.Position() >= with0->MonitorStream.Size())); + } + with0->CloseMonitorStream(ActiveActor); + TOPTransferFile->Close(); + TOPTransferFile->SendToTop(); + Vbuf->clear(); + CBuf->clear(); + } + } + delete ObjList; // ObjList->~TPointerList(); + NameList->clear(); + cNames->clear(); + */ +} + +String TMonitorObj::Get_FileName(int ActorID) +{ + String result; + if(ConcatenateReports) + result = GetOutputDirectory() + CircuitName_[ActorID] + "Mon_" + get_Name() + ".csv"; + else + result = GetOutputDirectory() + CircuitName_[ActorID] + "Mon_" + get_Name() + "_" + IntToStr(ActorID) + ".csv"; + return result; +} + +double TMonitorObj::FreqCalc(int stepCount, complex* V, complex Vo, double time) +{ + double w = (2 * PI * DefaultBaseFreq); // calculate wo + if (stepCount == 1) + { + U1 = 0.0; + U2 = 0.0; + U3 = 0.0; + if (VIpolar) + { + this->Vold = *V; + } + else + { + polar x; + x = ctopolardeg(*V); + this->Vold.re = x.mag; + this->Vold.im = x.ang; + } + this->Told = time; + return DefaultBaseFreq; + } + else + { + complex Vnew; + if (VIpolar) + { + Vnew = *V; + } + else + { + polar x; + x = ctopolardeg(*V); + Vnew.re = x.mag; + Vnew.im = x.ang; + } + if (Vnew.im < 0) + { + Vnew.im = Vnew.im + 90; // If the angle is negative, it has to be pushed back into the range of 0 to 360 + } + double angle = (Vnew.im - Vo.im) * (PI / 180); // Find the delta between the voltage angles and convert to radians + double dt = (time - Told); // Find the delta of the time between angles + double in; + U3 = angle * 1 / (dt * w); // Compute input into filter. Use median value if and only if there are 3 or more stepCounts + if (stepCount > 2) + { + std::vector UU; + UU = { U1,U2,U3 }; + std::sort(UU.begin(), UU.end()); + in = UU[1]; + } + else + { + in = U3; + } + + // Use PI controller to update the state variable s + Filter_F.Kp = 1 / (Tf); // Determine proportional gain + Filter_F.kDen = exp(-1 * abs(dt / Tf)); // Determine the denominator for the Integral of the PI controller + Filter_F.kNum = (1 - Filter_F.kDen) * Tf; // Determine the numerator for the Integral of the PI controller + this->s = Filter_F.SolvePI(in); // Solve for the PI controller + double ff = (1 + this->s) * (w / (2 * PI)); // Calculate the new frequency + + this->Vold = Vnew; // Set the old voltage angle to the new voltage angle for next iteration of calculations + this->Told = time; // Set the old time to the new time for next iteration of calculations + + this->U1 = U2; + this->U2 = U3; + + return ff; // return the calculated frequency + } +} + //WriteDLLDebugFile('Monitor'); + + + + +} // namespace Monitor + diff --git a/OpenDSSC/Meters/Monitor.h b/OpenDSSC/Meters/Monitor.h new file mode 100644 index 0000000..0cff569 --- /dev/null +++ b/OpenDSSC/Meters/Monitor.h @@ -0,0 +1,248 @@ +#ifndef MonitorH +#define MonitorH + +#include "System.h" + +#include "Command.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" +#include "mathutil.h" + + + + +namespace Monitor +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 12-7-99 Modified Getcurrents override + 1-22-00 Derived from MeterElement Class + 5-30-00 Added test for positive sequence ckt model + Fixed resetting of Nphases to match metered element + 10-27-00 Changed default to magnitude and angle instead of real and imag + 12-18-01 Added Transformer Tap Monitor Code + 12-18-02 Added Monitor Stream + 2-19-08 Added SampleCount + 01-19-13 Added flicker meter mode + 08-18-15 Added Solution monitor mode + 08-10-16 Added mode 6 for storing capacitor switching + 06-04-18 Added modes 7-9 + 11-29-18 Added mode 10; revised mode 8 + 12-4-18 Added link to AutoTransformer + 08-21-20 Added mode 11 + +*/ + +/* + A monitor is a circuit element that is connected to a terminal of another + circuit element. It records the voltages and currents at that terminal as + a function of time and can report those values upon demand. + + A Monitor is defined by a New commands: + + New Type=Monitor Name=myname Element=elemname Terminal=[1,2,...] Buffer=clear|save + + Upon creation, the monitor buffer is established. There is a file associated + with the buffer. It is named "Mon_elemnameN.mon" where N is the terminal no. + The file is truncated to zero at creation or buffer clearing. + + The Monitor keeps results in the in-memory buffer until it is filled. Then it + appends the buffer to the associated file and resets the in-memory buffer. + + For buffer=save, the present in-memory buffer is appended to the disk file so + that it is saved for later reference. + + The Monitor is a passive device that takes a sample whenever its "TakeSample" + method is invoked. The SampleAll method of the Monitor ckt element class will + force all monitors elements to take a sample. If the present time (for the most + recent solution is greater than the last time entered in to the monitor buffer, + the sample is appended to the buffer. Otherwise, it replaces the last entry. + + Monitor Files are simple binary files of Singles. The first record + contains the number of conductors per terminal (NCond). (always use 'round' function + when converting this to an integer). Then subsequent records consist of time and + voltage and current samples for each terminal (all complex doubles) in the order + shown below: + + + <--- All voltages first ---------------->|<--- All currents ----->| + .... ... + .... ... + .... ... + + The time values will not necessarily be in a uniform time step; they will + be at times samples or solutions were taken. This could vary from several + hours down to a few milliseconds. + + The monitor ID can be determined from the file name. Thus, these values can + be post-processed at any later time, provided that the monitors are not reset. + + Modes are: + 0: Standard mode - V and I,each phase, Mag and Angle and Freq // Frequency added by BLS 2/1/23 + 1: Power each phase, complex (kw and kvars) + 2: Transformer Tap + 3: State Variables + 4: Flicker level and severity index by phase (no modifiers apply) + 5: Solution Variables (Iteration count, etc.) + 6: Capacitor Switching (Capacitors only) + 7: Storage Variables + 8: Transformer Winding Currents + 9: Losses (watts and vars) + 10: Transformer Winding Voltages (across winding) + 11: All terminal V and I, all conductors, mag and angle + + +16: Sequence components: V012, I012 + +32: Magnitude Only + +64: Pos Seq only or Average of phases + +*/ +typedef AnsiChar TMonitorStrBuffer[256/*# range 1..256*/]; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + /*This has to be named TDSSMonitor because Delphi has a TMonitor Class and the compiler will get confused*/ + +class TDSSMonitor : public MeterClass::TMeterClass +{ + friend class TMonitorObj; +public: + typedef MeterClass::TMeterClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String MonitorName); +public: + TDSSMonitor(); + virtual ~TDSSMonitor(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void ResetAll(int ActorID); + virtual void SampleAll(int ActorID); // Force all monitors to take a sample + void SampleAllMode5(int ActorID); // Sample just Mode 5 monitors + virtual void SaveAll(int ActorID); // Force all monitors to save their buffers to disk + void PostProcessAll(int ActorID); + void TOPExport(String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TMonitorObj : public MeterElement::TMeterElement +{ + friend class TDSSMonitor; +public: + typedef MeterElement::TMeterElement inherited; +//private: + int BufferSize; + int Hour; + double Sec; // last time entered in the buffer + std::vector MonBuffer; + int BufPtr; // point to present (last) element in buffer must be incremented to add + std::vector CurrentBuffer; + std::vector VoltageBuffer; + std::vector WdgCurrentsBuffer; + std::vector WdgVoltagesBuffer; + std::vector PhsVoltagesBuffer; + int NumTransformerCurrents; + int NumWindingVoltages; + int NumStateVars; + + std::vector StateBuffer; + std::vector FlickerBuffer; // store phase voltages in polar form + // then convert to re=flicker level, update every time step + // and im=Pst, update every 10 minutes + std::vector SolutionBuffer; + bool IncludeResidual; + bool VIpolar; + bool Ppolar; + int FileSignature; + int FileVersion; + double BaseFrequency; + String BufferFile; // Name of file for catching buffer overflow + bool IsFileOpen; + bool ValidMonitor; + bool IsProcessed; + void AddDblsToBuffer(Arraydef::pDoubleArray Dbl, int Ndoubles); + void AddDblToBuffer(double Dbl); + void DoFlickerCalculations(int ActorID); // call from CloseMonitorStream + // function Get_FileName: String; +public: + int Mode; + + int stepCount = 0; // BLS - used for frequency meter modeled after PSLF FMETER + complex Vold; // + double Told; // + double simdt; // + double U1; // + double U2; // + double U3; // + double Tf = 0.05; // Low pass filter time constant (sec). Default value is 0.05 sec + double ds = 0; // Initialize low pass filter - ds is derivative state variable + double s = 0; // Initialize low pass filter - s is state variable + double Freq; // Output of frequency calcualtion + TPICtrl Filter_F; // Object for PI Control to update state variable s + + TMemoryStream MonitorStream; + int SampleCount; // This is the number of samples taken + int myHeaderSize; // size of the header of this monitor + vector StrBuffer; // Header + TMonitorObj(DSSClass::TDSSClass* ParClass, const String MonitorName); + virtual ~TMonitorObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, reset nphases + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a monitor + virtual void TakeSample(int ActorID); // Go add a sample to the buffer + void ResetIt(int ActorID); + void Save(); // Saves present buffer to file + void PostProcess(int ActorID); // calculates Pst or other post-processing + void Add2Header(AnsiString myText); + void OpenMonitorStream(); + void ClearMonitorStream(int ActorID); + void CloseMonitorStream(int ActorID); + void TranslateToCSV(bool Show, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + String Get_FileName(int ActorID); + //Property MonitorFileName:String read BufferFile; + +// Property CSVFileName:String Read Get_FileName; + TMonitorObj(DSSClass::TDSSClass* ParClass); + TMonitorObj(String ClassName); + TMonitorObj(); + +// Freq Calc + double FreqCalc(int stepCount, complex* V, complex Vo, double time); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +extern TMonitorObj* ActiveMonitorObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace Monitor + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Monitor; +#endif + +#endif // MonitorH + + + + + diff --git a/OpenDSSC/Meters/ReduceAlgs.cpp b/OpenDSSC/Meters/ReduceAlgs.cpp new file mode 100644 index 0000000..f3f3592 --- /dev/null +++ b/OpenDSSC/Meters/ReduceAlgs.cpp @@ -0,0 +1,650 @@ + +#pragma hdrstop + +#include "ReduceAlgs.h" + +#include "Line.h" +#include "Utilities.h" +#include "DSSGlobals.h" +#include "DSSClassDefs.h" +#include "Load.h" +#include "Ucomplex.h" +#include "ParserDel.h" +#include "CktElement.h" +#include "ExecHelper.h" +#include "Bus.h" + +using namespace std; +using namespace Bus; +using namespace CktElement; +using namespace CktTree; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace ExecHelper; +using namespace Line; +using namespace Load; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucomplex; +using namespace Utilities; + +namespace ReduceAlgs +{ + + +const bool SERIESMERGE = true; +const bool PARALLELMERGE = false; + +void DoMergeParallelLines(TCktTree*& BranchList) +{ + void* dummy; + TLineObj* LineElement = nullptr; + if(BranchList != nullptr) + { + dummy = BranchList->Get_First(); + LineElement = ((TLineObj*) BranchList->Get_Forward()); // Always keep the first element + while(LineElement != nullptr) + { + if(BranchList->PresentBranch->IsParallel) + /*There will always be two lines in parallel. The first operation will disable the second*/ + { + if( ( (TDSSCktElement*) LineElement )->Get_Enabled()) + LineElement->MergeWith(((TLineObj*&) BranchList->PresentBranch->LoopLineObj), PARALLELMERGE); // Guaranteed to be a line + } + LineElement = ((TLineObj*) BranchList->Get_Forward()); + } + } +} +/*Merge all lines in this zone that are marked in parallel*/ + +void DoBreakLoops(TCktTree*& BranchList) +{ + void* dummy; + TLineObj* LineElement = nullptr; + if(BranchList != nullptr) + { + dummy = BranchList->Get_First(); + LineElement = ((TLineObj*) BranchList->Get_Forward()); // Always keep the first element + while(LineElement != nullptr) + { + if(BranchList->PresentBranch->IsLoopedHere) + /*There will always be two lines in the loop. The first operation will disable the second*/ + { + if(((TDSSCktElement*)LineElement)->Get_Enabled()) + ((TDSSCktElement*) BranchList->PresentBranch->LoopLineObj)->Set_Enabled(false); // Disable the other + } + LineElement = ((TLineObj*) BranchList->Get_Forward()); + } + } +} + +/*Break loops*/ + + +/* + +procedure DoReduceTapEnds(var BranchList:TCktTree); +(*Var + pLineElem1, pLineElem2:TLineObj; + ToBusRef:Integer; + AngleTest:Double; + ParentNode:TCktTreeNode; +*) +begin + +end; +*/ + +void DoReduceDangling(TCktTree*& BranchList) +{ + void* dummy; + TDSSCktElement* pLineElem1 = nullptr; + int ToBusRef = 0; + if(BranchList != nullptr) + /*Let's throw away all dangling end branches*/ + { + dummy = BranchList->Get_First(); + pLineElem1 = ((TDSSCktElement*) BranchList->Get_Forward()); // Always keep the first element + while(pLineElem1 != nullptr) + { + if(IslineElement(pLineElem1)) + /*# with BranchList.PresentBranch do */ + { + auto with0 = BranchList->PresentBranch; + + /*If it is at the end of a section and has no load,cap, reactor, + or coordinate, just throw it away*/ + if(with0->IsDangling) + { + ToBusRef = with0->Get_ToBusReference(); // only access this property once! + if(ToBusRef > 0) + /*# with ActiveCircuit[ActiveActor]->Buses^[ToBusRef] do */ + { + + if(!(ActiveCircuit[ActiveActor]->Buses[ToBusRef - 1]->Keep)) + pLineElem1->Set_Enabled(false); + } + } /*IF*/ + } /*If-With*/ + pLineElem1 = ((TDSSCktElement*) BranchList->Get_Forward()); + } + } +} + +bool IsShortLine(TDSSCktElement* const Elem) +{ + bool result = false; + double Ztest = 0.0; + TLineObj* LineElement = nullptr; + LineElement = ((TLineObj*) Elem); + /*Get Positive Sequence or equivalent from matrix*/ + if(LineElement->SymComponentsModel) + /*# with LineElement do */ + { + auto with0 = LineElement; + Ztest = cabs(cmplx(with0->R1, with0->X1)) * with0->Len; + } + else + /*# with LineElement do */ + { + auto with1 = LineElement; /*Get impedance from Z matrix*/ /*Zs - Zm ... approximates Z1*/ + if( ( (TDSSCktElement*) with1 )->Get_NPhases() > 1) + Ztest = cabs(csub(with1->Z->GetElement(1, 1), with1->Z->GetElement(1, 2))) * with1->Len; + else + Ztest = cabs(with1->Z->GetElement(1, 1)) * with1->Len; + } + if(Ztest <= ActiveCircuit[ActiveActor]->ReductionZmag) + result = true; + else + result = false; + return result; +} + +void DoReduceShortLines(TCktTree*& BranchList) +{ + TLineObj* LineElement1 = nullptr; + TLineObj* LineElement2 = nullptr; + TDSSCktElement* shuntElement = nullptr; + TCktTreeNode* ParentNode = nullptr; + bool MergeOK = false; + if(BranchList != nullptr) /*eliminate really short lines*/ + /*Get_First(), flag all elements that need to be merged*/ + { + LineElement1 = (TLineObj*) BranchList->Get_First(); + LineElement1 = (TLineObj*) BranchList->Get_Forward(); // Always keep the first element + while(LineElement1 != nullptr) + { + if(IslineElement(LineElement1)) + { + ( (TDSSObject*) LineElement1 )->Flag = IsShortLine( (TDSSCktElement*) LineElement1 ); /*Too small: Mark for merge with something*/ + } /*IF*/ + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); // traverse the whole meter zone (circuit tree) + } /*WHILE*/ + LineElement1 = (TLineObj*) BranchList->Get_First(); + LineElement1 = (TLineObj*) BranchList->Get_Forward(); // Always keep the first element in the Tree + while(LineElement1 != nullptr) + { + if(LineElement1->Get_Enabled()) + { + if(!LineElement1->HasControl) + { + if(!LineElement1->IsMonitored) + { + if(LineElement1->Flag) // else skip + // Skip if controlled element or control is monitoring ,,, + // too short; Try to merge this element out + { + /*# with BranchList do */ + { + auto with0 = BranchList; + // {****} WriteDLLDebugFile(Format('Processing Line.%s Bus1=%s Bus2=%s',[Uppercase(LineElement1.Name), LineElement1.GetBus(1), LineElement1.GetBus(2)])); + if((with0->PresentBranch->Get_NumChildren() == 0) && (with0->PresentBranch->Get_NumObjects() == 0)) // just discard it + LineElement1->Set_Enabled(false); + else + { + if(with0->PresentBranch->Get_NumChildren() == 0) /*****OR (PresentBranch.Get_NumChildren()>1)***/ /*Merge with Parent and move shunt elements to TO node on parent branch*/ + { + ParentNode = with0->PresentBranch->Get_Parent(); + if(ParentNode != nullptr) + { + if(ParentNode->Get_NumChildren() == 1) + { + if(!ActiveCircuit[ActiveActor]->Buses[with0->PresentBranch->Get_ToBusReference() - 1]->Keep) // only works for in-line + // Check Keeplist + /*Let's consider merging*/ + /*Get_First() Check for any Capacitors. Skip if any*/ + { + MergeOK = true; + if(ParentNode->Get_NumObjects() > 0) + { + shuntElement = ((TDSSCktElement*) ParentNode->Get_FirstObject()); + while(shuntElement != nullptr) + { + if(((shuntElement->DSSObjType & CLASSMASK) == CAP_ELEMENT) || ((shuntElement->DSSObjType & CLASSMASK) == REACTOR_ELEMENT)) + { + MergeOK = false; + break; + } + shuntElement = ((TDSSCktElement*) with0->PresentBranch->Get_NextObject()); + } /*While*/ + } + if(MergeOK) + { + LineElement2 = ((TLineObj*) ParentNode->CktObject); + if(((TDSSCktElement*)LineElement2)->Get_Enabled()) + { + if(IslineElement(LineElement2)) + { + if(LineElement2->MergeWith(LineElement1, SERIESMERGE)) // Check to make sure it hasn't been merged out + /*Move any loads to ToBus Reference of parent branch*/ + // {****} WriteDLLDebugFile(Format('TOP Loop: Eliminating Line %s and merging into Line %s ',[Uppercase(LineElement1.Name), Uppercase(LineElement2.Name) ])); + { + if(ParentNode->Get_NumObjects() > 0) + /*Redefine bus connection for PC elements hanging on the bus that is eliminated*/ + { + shuntElement = ((TDSSCktElement*) ParentNode->Get_FirstObject()); + while(shuntElement != nullptr) + { + Parser[ActiveActor]->SetCmdString(String("bus1=\"") + ActiveCircuit[ActiveActor]->BusList.Get(with0->PresentBranch->Get_ToBusReference()) + + GetNodeString(shuntElement->GetBus(1)) + + "\""); + // {****} WriteDLLDebugFile(Format('Moving Shunt.%s from %s to %s ',[ShuntElement.Name, ShuntElement.GetBus(1), Parser.get_CmdBuffer() ])); + shuntElement->Edit(ActiveActor); + shuntElement = ((TDSSCktElement*) ParentNode->Get_NextObject()); + } /*While*/ + } /*IF*/ + //+++ LineElement1 := BranchList.Get_Forward(); // skip to next branch since we eliminated a bus + } + } + } + } + } /*IF*/ + } + } /*IF ParentNode*/ + } + else + { + if(with0->PresentBranch->Get_NumChildren() == 1) /*Merge with child*/ + { + if(!ActiveCircuit[ActiveActor]->Buses[with0->PresentBranch->Get_ToBusReference() - 1]->Keep) // check keeplist + + /*Let's consider merging*/ + /*Get_First() Check for any Capacitors. Skip if any*/ + { + MergeOK = true; + if(with0->PresentBranch->Get_NumObjects() > 0) + { + shuntElement = ((TDSSCktElement*) with0->PresentBranch->Get_FirstObject()); + while(shuntElement != nullptr) + { + if(((shuntElement->DSSObjType & CLASSMASK) == CAP_ELEMENT) || ((shuntElement->DSSObjType & CLASSMASK) == REACTOR_ELEMENT)) + { + MergeOK = false; + break; + } + shuntElement = ((TDSSCktElement*) with0->PresentBranch->Get_NextObject()); + } /*While*/ + } + if(MergeOK) + { + LineElement2 = ((TLineObj*) with0->PresentBranch->Get_FirstChild()->CktObject); // child of PresentBranch + if(((TDSSCktElement*)LineElement2)->Get_Enabled()) + { + if(IslineElement(LineElement2)) + { + if(LineElement2->MergeWith(LineElement1, SERIESMERGE)) // Check to make sure it hasn't been merged out + + // {****} WriteDLLDebugFile(Format('BOT Loop: Eliminating Line %s and merging into Line %s ',[Uppercase(LineElement1.Name), Uppercase(LineElement2.Name)])); + { + if(with0->PresentBranch->Get_NumObjects() > 0) + /*Redefine bus connection to upline bus*/ + { + shuntElement = ((TDSSCktElement*) with0->PresentBranch->Get_FirstObject()); + while(shuntElement != nullptr) + { + Parser[ActiveActor]->SetCmdString(String("bus1=\"") + ActiveCircuit[ActiveActor]->BusList.Get(with0->PresentBranch->FromBusReference) + + GetNodeString(shuntElement->GetBus(1)) + + "\""); + // {****} WriteDLLDebugFile(Format('Moving Shunt.%s from %s to %s ',[ShuntElement.Name, ShuntElement.GetBus(1), Parser.get_CmdBuffer() ])); + shuntElement->Edit(ActiveActor); + shuntElement = ((TDSSCktElement*) with0->PresentBranch->Get_NextObject()); + } /*While*/ + } /*IF*/ + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); // skip to next branch since we eliminated a bus + } + } + } + } + } /*IF not*/ + } + } /*ELSE*/ + } + } + } + } + } + } + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with3 = ActiveCircuit[ActiveActor]; + with3->ReProcessBusDefs(ActiveActor); // to get new load added and account for disabled devices + with3->DoResetMeterZones(ActiveActor); // without eliminated devices + with3->Solution->SystemYChanged = true; // force rebuild of Y + } + } +} +/*Eliminate short lines with impedance < Zmag and merge with lines on either side*/ + +void DoReduceSwitches(TCktTree*& BranchList) +{ + TLineObj* LineElement1 = nullptr; + TLineObj* LineElement2 = nullptr; + if(BranchList != nullptr) + { + LineElement1 = ((TLineObj*) BranchList->Get_First()); + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); // Always keep the first element + while(LineElement1 != nullptr) + { + if( ( (TDSSCktElement*) LineElement1 )->Get_Enabled()) + { + if(IslineElement(LineElement1)) + { + if(LineElement1->IsSwitch) + /*# with BranchList.PresentBranch do */ + { + auto with0 = BranchList->PresentBranch; + switch(with0->Get_NumChildren()) + { // maybe we threw it away already + + /*see if eligble for merging*/ + case 0: + if(with0->Get_NumObjects() == 0) /*Throw away if dangling*/ + ((TDSSCktElement*)LineElement1)->Set_Enabled(false); + break; + case 1: + if(with0->Get_NumObjects() == 0) + { + if(!ActiveCircuit[ActiveActor]->Buses[with0->Get_ToBusReference() - 1]->Keep) + /*Let's consider merging*/ + { + LineElement2 = ((TLineObj*) with0->Get_FirstChild()->CktObject); + if(IslineElement(LineElement2)) + { + if(!LineElement2->IsSwitch)/*Series Merge*/ + LineElement2->MergeWith(LineElement1, SERIESMERGE); + } + } + } + break; /*Nada*/ + default: + ; + break; + } + } + } + } + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); + } + } +} + +/*Merge switches in with lines or delete if dangling*/ + +void DoReduceDefault(TCktTree*& BranchList) +{ + TLineObj* LineElement1 = nullptr; + TLineObj* LineElement2 = nullptr; + if(BranchList != nullptr) + + /*Now merge remaining lines*/ + { + LineElement1 = ((TLineObj*) BranchList->Get_First()); + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); // Always keep the first element + while(LineElement1 != nullptr) + { + if(IslineElement(LineElement1)) + { + if(!LineElement1->IsSwitch) + { + if(!((TDSSCktElement*)LineElement1)->HasControl) + { + if(!((TDSSCktElement*)LineElement1)->IsMonitored) + { + if(((TDSSCktElement*)LineElement1)->Get_Enabled()) + /*# with BranchList do */ + { + auto with0 = BranchList; // Exceptions + // maybe we threw it away already + + /*see if eligble for merging*/ + if(with0->PresentBranch->Get_NumChildren() == 1) + { + if(with0->PresentBranch->Get_NumObjects() == 0) + { + if(!ActiveCircuit[ActiveActor]->Buses[with0->PresentBranch->Get_ToBusReference() - 1]->Keep) + /*Let's consider merging*/ + { + LineElement2 = ((TLineObj*) with0->PresentBranch->Get_FirstChild()->CktObject); + if(IslineElement(LineElement2)) + { + if(!LineElement2->IsSwitch)/*Series Merge*/ + LineElement2->MergeWith(LineElement1, SERIESMERGE); + } + } + } + } + } + } + } + } + } + LineElement1 = ((TLineObj*) BranchList->Get_Forward()); + } + } +} + +void DoRemoveBranches(TCktTree*& BranchList, TPDElement* FirstPDElement, bool KeepLoad, const String EditStr) +{ + TPDElement* PDElem = nullptr; + String Busname; + complex TotalkVA = {}; + // pLoad : TLoadObj; + String NewLoadName; + TDSSCktElement* pShunt = nullptr; + TDSSBus* LoadBus = nullptr; + double LoadBasekV = 0.0; + int StartLevel = 0; + +// Position BranchList at "FirstPDElement" + PDElem = ((TPDElement*) BranchList->Get_First()); + while((PDElem != FirstPDElement) && (PDElem != nullptr)) + PDElem = ((TPDElement*) BranchList->Get_Forward()); + StartLevel = BranchList->Get_Level(); + if(PDElem == nullptr) + { + DoSimpleMsg(((TDSSObject*)FirstPDElement)->ParentClass->get_myClass_name() + "." + ((TDSSObject*)FirstPDElement)->get_Name() + " Not Found(Remove Command).", 5432100); + } + else + + + /* If KeepLoad, create a new Load object at upstream bus (from bus).*/ + { + if(KeepLoad) + /*# with BranchList.PresentBranch do */ + { + auto with0 = BranchList->PresentBranch; + Busname = ( (TDSSCktElement*) FirstPDElement )->GetBus(with0->FromTerminal); + TotalkVA = cdivreal( ( (TDSSCktElement*) PDElem )->Get_Power(with0->FromTerminal, ActiveActor), 1000.0); + NewLoadName = "Eq_"+ ( (TDSSCktElement*) FirstPDElement )->get_Name() + "_" + StripExtension(Busname) ; + /*Pick up the kV Base for the From bus*/ + LoadBus = ActiveCircuit[ActiveActor]->Buses[with0->FromBusReference - 1]; + if(LoadBus->kVBase > 0.0) + LoadBasekV = LoadBus->kVBase; + else + // Try to guess from the present voltage at the first node on the bus + { + ActiveCircuit[ActiveActor]->Solution->UpdateVBus(ActiveActor); + LoadBasekV = cabs((LoadBus->VBus)[1 - 1]) * 0.001; + } + if(((TDSSCktElement*)FirstPDElement)->Get_NPhases() > 1) + LoadBasekV = LoadBasekV * SQRT3; + /*Load up parser with definition of equivalent load*/ + Parser[ActiveActor]->SetCmdString(Format(" phases=%d Bus1=", (FirstPDElement)->Get_NPhases() ) + + Busname + Format(" kW=%g kvar=%g kV=%g ", TotalkVA.re, TotalkVA.im, LoadBasekV ) + EditStr); + AddObject("load", NewLoadName); // Add new load to circuit + } + + /*Disable all elements in the tree downline from the start element*/ + + // {****} WriteDLLDebugFile(Format('StartLevel = %d ',[ StartLevel])); + while(PDElem != nullptr) + + // {****} WriteDLLDebugFile(Format('Disabling cktelement %d %s.%s',[ BranchList.Level, PDelem.ParentClass.Name, PDElem.Name ])); + { + /*# with BranchList do */ + { + auto with1 = BranchList; + pShunt = ((TDSSCktElement*) with1->PresentBranch->Get_FirstObject()); + while(pShunt != nullptr) + { + pShunt->Set_Enabled(false); + // {****} WriteDLLDebugFile(Format('Disabling shunt element %s.%s',[ pShunt.ParentClass.Name, pShunt.Name ])); + pShunt = ((TDSSCktElement*) with1->PresentBranch->Get_NextObject()); + } + } + ( (TDSSCktElement*) PDElem )->Set_Enabled(false); + PDElem = ((TPDElement*) BranchList->Get_Forward()); + + // Check to see if we are back where we started. If so, stop. + if(BranchList->Get_Level() <= StartLevel) + PDElem = nullptr; + } + } + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with3 = ActiveCircuit[ActiveActor]; + with3->ReProcessBusDefs(ActiveActor); // to get new load added and account for disabled devices + with3->DoResetMeterZones(ActiveActor); // without eliminated devices + with3->Solution->SystemYChanged = true; // force rebuild of Y + } +} + +void DoRemoveAll_1ph_Laterals(TCktTree*& BranchList) +{ + TPDElement* PDElem = nullptr; + String Busname; + TDSSCktElement* pShunt = nullptr; + TDSSBus* HeadBus = nullptr; + double HeadBasekV = 0.0; + int StartLevel = 0; + TDSSBus* pBus = nullptr; + String strNodes; + /* + Just march down the feeder until we encounter a 1-phase PD element + */ + // Position BranchList at "beginning" + PDElem = ((TPDElement*) BranchList->Get_First()); + while(PDElem != nullptr) + { + if( ( (TDSSCktElement*) PDElem )->Get_NPhases() == 1) // ELIMINATE THIS LATERAL + + /*Check to see if this is a 1-phase switch or other branch in the middle of a 3-phase branch and go on*/ + /*If the To bus has more than 1 phase, keep this branch else lump the load at the From node*/ + { + pBus = ActiveCircuit[ActiveActor]->Buses[BranchList->PresentBranch->Get_ToBusReference() - 1]; //To Bus + if(pBus->get_FNumNodesThisBus() == 1) // Eliminate the lateral starting with this branch + + + /* If KeepLoad (ReduceLateralsKeepLoad), create a new Load object at upstream bus (from bus).*/ + { + if(ActiveCircuit[ActiveActor]->ReduceLateralsKeepLoad) + /*# with BranchList do */ + { + auto with0 = BranchList; + Busname = ((TDSSCktElement*)PDElem)->GetBus(with0->PresentBranch->FromTerminal); + // Make sure there is a node reference .. default to 1 + if(Pos(".", Busname) == 0) + Busname = Busname + ".1"; + + /*Pick up the kV Base for the From bus*/ + HeadBus = ActiveCircuit[ActiveActor]->Buses[with0->PresentBranch->FromBusReference - 1]; + if(HeadBus->kVBase > 0.0) + HeadBasekV = HeadBus->kVBase; + else + // Try to guess voltage base from the present voltage at the first node on the bus + { + ActiveCircuit[ActiveActor]->Solution->UpdateVBus(ActiveActor); + HeadBasekV = cabs((HeadBus->VBus)[1 - 1]) * 0.001; + } + } + + /* + + Disable all PDelements in the tree downline from the beginning of the 1-phase lateral + Move 1-phase shunts to Headbus + + */ + StartLevel = BranchList->Get_Level(); // record level of first 1-phase branch in this lateral + while(PDElem != nullptr) + + // {****} WriteDLLDebugFile(Format('Disabling cktelement %d %s.%s',[ BranchList.Level, PDelem.ParentClass.Name, PDElem.Name ])); + /* Get rid of loads and other shunt elements connected to this branch */ + { + /*# with BranchList do */ + { + auto with1 = BranchList; + pShunt = ((TDSSCktElement*) with1->PresentBranch->Get_FirstObject()); + while(pShunt != nullptr) + { + Parser[ActiveActor]->SetCmdString(Format("Bus1=%s kV=%.6g ",Busname.c_str(), HeadBasekV)); + pShunt->Edit(ActiveActor); + pShunt = ((TDSSCktElement*) with1->PresentBranch->Get_NextObject()); + } + } + ((TDSSCktElement*)PDElem)->Set_Enabled(false); + PDElem = ((TPDElement*) BranchList->Get_Forward()); + + // Check to see if we are back where we started. If so, stop with this lateral and get on to the next. + if(PDElem != nullptr) + { + if(BranchList->Get_Level() <= StartLevel) + break; + } + } + } + else + PDElem = ((TPDElement*) BranchList->Get_Forward()); + } + else + PDElem = ((TPDElement*) BranchList->Get_Forward()); + + + // {****} If PDElem<>Nil then WriteDLLDebugFile(Format('Going on.. cktelement %d %s.%s phases=%d',[ BranchList.Level, PDelem.ParentClass.Name, PDElem.Name, PDelem.NPhases ])); + } + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with3 = ActiveCircuit[ActiveActor]; + + with3->ReProcessBusDefs(ActiveActor); // to get new load added and account for disabled devices + with3->DoResetMeterZones(ActiveActor); // without eliminated devices + with3->Solution->SystemYChanged = true; // force rebuild of Y + } +} +/*Remove all 1-phase laterals in Branchlist and lump total load back to main feeder*/ +/* + This removes all elements on all 1ph laterals and moves the net load back to the main feeder tap point + Does not +*/ + + + + +} // namespace ReduceAlgs + + + + + diff --git a/OpenDSSC/Meters/ReduceAlgs.h b/OpenDSSC/Meters/ReduceAlgs.h new file mode 100644 index 0000000..e0cb93f --- /dev/null +++ b/OpenDSSC/Meters/ReduceAlgs.h @@ -0,0 +1,50 @@ +#ifndef ReduceAlgsH +#define ReduceAlgsH + +#include "System.h" +#include "Sysutils.h" + +#include "CktTree.h" +#include "PDElement.h" +#include "d2c_structures.h" + + + + +namespace ReduceAlgs +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Reduction Algorithms*/ + +/*Primarily called from EnergyMeter*/ +void DoReduceDefault(CktTree::TCktTree*& BranchList); +void DoReduceShortLines(CktTree::TCktTree*& BranchList); +void DoReduceDangling(CktTree::TCktTree*& BranchList); + /*{procedure DoReduceTapEnds(var BranchList:TCktTree);*/ +void DoBreakLoops(CktTree::TCktTree*& BranchList); +void DoMergeParallelLines(CktTree::TCktTree*& BranchList); +void DoReduceSwitches(CktTree::TCktTree*& BranchList); +void DoRemoveAll_1ph_Laterals(CktTree::TCktTree*& BranchList); +void DoRemoveBranches(CktTree::TCktTree*& BranchList, PDELement::TPDElement* FirstPDElement, bool KeepLoad, const String EditStr); + + +} // namespace ReduceAlgs + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ReduceAlgs; +#endif + +#endif // ReduceAlgsH + + + + + diff --git a/OpenDSSC/Meters/Sensor.cpp b/OpenDSSC/Meters/Sensor.cpp new file mode 100644 index 0000000..7c1507a --- /dev/null +++ b/OpenDSSC/Meters/Sensor.cpp @@ -0,0 +1,934 @@ + +#pragma hdrstop + +#include "Sensor.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "CktElement.h" +#include "Transformer.h" +#include "PCElement.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "ShowResults.h" +#include "mathutil.h" +#include "PointerList.h" +#include "Dynamics.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace MeterClass; +using namespace MeterElement; +using namespace PCElement; +using namespace PDELement; +using namespace ParserDel; +using namespace PointerList; +using namespace System; +using namespace Transformer; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Sensor +{ + +TSensorObj::TSensorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TSensorObj::TSensorObj(String ClassName) : inherited(ClassName) {} +TSensorObj::TSensorObj() {} + + +TSensorObj* ActiveSensorObj = nullptr; /*TOPExport,*/ +const int NumPropsThisClass = 13; + +/*==============================================================================*/ // Creates superstructure for all Sensor objects + +TSensor::TSensor() +{ + ; + Class_Name = "Sensor"; + DSSClassType = DSSClassType + SENSOR_ELEMENT; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*==============================================================================*/ + +TSensor::~TSensor() +{ + // inherited::Destroy(); +} + + +/*==============================================================================*/ + +void TSensor::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "element"; + PropertyName[2 - 1] = "terminal"; + PropertyName[3 - 1] = "kvbase"; + PropertyName[4 - 1] = "clear"; + PropertyName[5 - 1] = "kVs"; + PropertyName[6 - 1] = "currents"; + PropertyName[7 - 1] = "kWs"; + PropertyName[8 - 1] = "kvars"; + PropertyName[9 - 1] = "conn"; // Sensor connection + PropertyName[10 - 1] = "Deltadirection"; // +/- 1 + PropertyName[11 - 1] = "%Error"; // %Error of sensor + PropertyName[12 - 1] = "Weight"; // for WLS calc + PropertyName[13 - 1] = "action"; + PropertyHelp[1 - 1] = "Name (Full Object name) of element to which the Sensor is connected."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the Sensor is connected. " + "1 or 2, typically. Default is 1."; + PropertyHelp[3 - 1] = String("Voltage base for the sensor, in kV. If connected to a 2- or 3-phase terminal, ") + CRLF + + "specify L-L voltage. For 1-phase devices specify L-N or actual 1-phase voltage. " + + "Like many other DSS devices, default is 12.47kV."; + PropertyHelp[4 - 1] = "{ Yes | No }. Clear=Yes clears sensor values. Should be issued before putting in a new set of measurements."; + PropertyHelp[5 - 1] = "Array of Voltages (kV) measured by the voltage sensor. For Delta-connected " + "sensors, Line-Line voltages are expected. For Wye, Line-Neutral are expected."; + PropertyHelp[6 - 1] = "Array of Currents (amps) measured by the current sensor. Specify this or power quantities; not both."; + PropertyHelp[7 - 1] = String("Array of Active power (kW) measurements at the sensor. Is converted into Currents along with q=[...]") + CRLF + + "Will override any currents=[...] specification."; + PropertyHelp[8 - 1] = "Array of Reactive power (kvar) measurements at the sensor. Is converted into Currents along with p=[...]"; + PropertyHelp[9 - 1] = String("Voltage sensor Connection: { wye | delta | LN | LL }. Default is wye. Applies to voltage measurement only. ") + CRLF + + "Currents are always assumed to be line currents." + + CRLF + + "If wye or LN, voltage is assumed measured line-neutral; otherwise, line-line."; + PropertyHelp[10 - 1] = "{1 or -1} Default is 1: 1-2, 2-3, 3-1. For reverse rotation, enter -1. Any positive or negative entry will suffice."; + PropertyHelp[11 - 1] = "Assumed percent error in the measurement. Default is 1."; + PropertyHelp[12 - 1] = "Weighting factor: Default is 1."; + PropertyHelp[13 - 1] = String("NOT IMPLEMENTED.Action options: ") + CRLF + + "SQERROR: Show square error of the present value of the monitored terminal " + + CRLF + + "quantity vs the sensor value. Actual values - convert to per unit in calling program. " + + CRLF + + "Value reported in result window/result variable."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*==============================================================================*/ + +int TSensor::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Sensor and add it to Sensor class list + /*# with ActiveCircuit[ActiveActor] do */ + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TSensorObj(this, ObjName)); + + + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +/*==============================================================================*/ + +int TSensor::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + bool DoRecalcElementData = false; + + // continue parsing with contents of Parser + ActiveSensorObj = ((TSensorObj*) ElementList.Get_Active()); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveSensorObj); + result = 0; + DoRecalcElementData = false; + /*# with ActiveSensorObj do */ + { + auto with0 = ActiveSensorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 661); + break; + case 1: + with0->ElementName = LowerCase(Param); + break; + case 2: + with0->MeteredTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->kVBase = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->ClearSpecified = InterpretYesNo(Param); + break; + case 5: + Parser[ActorID]->ParseAsVector( ( (TDSSCktElement*) with0 )->Fnphases, &(with0->SensorVoltage[0])); + break; // Inits to zero + case 6: + Parser[ActorID]->ParseAsVector(((TDSSCktElement*)with0)->Fnphases, &(with0->SensorCurrent[0])); + break; // Inits to zero + case 7: + { + Parser[ActorID]->ParseAsVector(((TDSSCktElement*)with0)->Fnphases, with0->SensorkW); + with0->Pspecified = true; + with0->UpdateCurrentVector(); + } + break; + case 8: + { + Parser[ActorID]->ParseAsVector(((TDSSCktElement*)with0)->Fnphases, with0->Sensorkvar); + with0->Qspecified = true; + with0->UpdateCurrentVector(); + } + break; + case 9: + with0->Set_Conn(InterpretConnection(Param)); + break; + case 10: + with0->FDeltaDirection = with0->LimitToPlusMinusOne(Parser[ActorID]->MakeInteger_()); + break; + case 11: + with0->pctError = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->Weight = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->Set_Action(Param); + break; // Put sq error in Global Result + + // Inherited parameters + default: + inherited::ClassEdit(ActiveSensorObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 2: + { + DoRecalcElementData = true; + with0->MeteredElementChanged = true; + } + break; + case 3: + DoRecalcElementData = true; + break; + + /*Do not recalc element data for setting of sensor quantities*/ + case 4: + if(with0->ClearSpecified) + with0->ClearSensor(); + break; + case 5: + with0->Vspecified = true; + break; + case 6: + with0->Ispecified = true; + break; + case 7: + with0->Pspecified = true; + break; + case 8: + with0->Qspecified = true; + break; + case 9: + DoRecalcElementData = true; + break; + case 10: + DoRecalcElementData = true; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(DoRecalcElementData) + with0->RecalcElementData(ActorID); + } + return result; +} + +/*==============================================================================*/ // Force all Sensors in the circuit to reset + +void TSensor::ResetAll(int ActorID) +{ + TSensorObj* pSensor = nullptr; + pSensor = ((TSensorObj*) ActiveCircuit[ActorID]->Sensors.Get_First()); + while(pSensor != nullptr) + { + if( ( (TDSSCktElement*) pSensor )->Get_Enabled()) + pSensor->ResetIt(); + pSensor = ((TSensorObj*) ActiveCircuit[ActiveActor]->Sensors.Get_Next()); + } +} + +/*==============================================================================*/ // Force all Sensors in the circuit to take a sample + +void TSensor::SampleAll(int ActorID) +{ + TSensorObj* pSensor = nullptr; + pSensor = ((TSensorObj*) ActiveCircuit[ActorID]->Sensors.Get_First()); + while(pSensor != nullptr) + { + if(((TDSSCktElement*)pSensor)->Get_Enabled()) + pSensor->TakeSample(ActorID); + pSensor = ((TSensorObj*) ActiveCircuit[ActorID]->Sensors.Get_Next()); + } +} + +/*==============================================================================*/ // Force all Sensors in the circuit to save their buffers to disk + +//VAR +// Mon:TSensorObj; + +void TSensor::SaveAll(int ActorID) +{ + +/* + Mon := ActiveCircuit[ActiveActor].Sensors.Get_First(); + WHILE Mon<>Nil DO + Begin + If Mon.Enabled Then Mon.Save; + Mon := ActiveCircuit[ActiveActor].Sensors.Get_Next(); + End; +*/ +} + +/*==============================================================================*/ +// Set the HasSensorObj Flag for all cktElement; + +void TSensor::SetHasSensorFlag() +{ + int i = 0; + TSensorObj* ThisSensor = nullptr; + TDSSCktElement* CktElem = nullptr; + /*Initialize all to FALSE*/ + int stop = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + + CktElem = ((TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_First()); + while(CktElem != nullptr) + { + CktElem->HasSensorObj = false; + CktElem = ((TDSSCktElement*) ActiveCircuit[ActiveActor]->PDElements.Get_Next()); + } /*WHILE*/ + CktElem = ((TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_First()); + while(CktElem != nullptr) + { + CktElem->HasSensorObj = false; + CktElem = ((TDSSCktElement*) ActiveCircuit[ActiveActor]->PCElements.Get_Next()); + } /*WHILE*/ + } /*WITH*/ + for(stop = ActiveCircuit[ActiveActor]->Sensors.get_myNumList(), i = 1; i <= stop; i++) + { + ThisSensor = ((TSensorObj*) ActiveCircuit[ActiveActor]->Sensors.Get(i)); + /*# with ThisSensor do */ + { + auto with1 = ThisSensor; + if(with1->MeteredElement != nullptr) + { + with1->MeteredElement->HasSensorObj = true; + if(dynamic_cast (with1->MeteredElement)) + ((TPCElement*) with1->MeteredElement)->SensorObj = ThisSensor; + else + ((TPDElement*) with1->MeteredElement)->SensorObj = ThisSensor; + } + } + } /*FOR*/ +} + +/*==============================================================================*/ + +int TSensor::MakeLike(const String SensorName) +{ + int result = 0; + TSensorObj* OtherSensor = nullptr; + int i = 0; + result = 0; + /*See if we can find this Sensor name in the present collection*/ + OtherSensor = ((TSensorObj*) Find(SensorName)); + if(OtherSensor != nullptr) + /*# with ActiveSensorObj do */ + { + auto with0 = ActiveSensorObj; + int stop = 0; + ((TDSSCktElement*)with0)->Set_NPhases(((TDSSCktElement*)OtherSensor)->Fnphases); + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)OtherSensor)->Fnconds); // Force Reallocation of terminal stuff + with0->ElementName = OtherSensor->ElementName; + with0->MeteredElement = OtherSensor->MeteredElement; // Pointer to target circuit element + with0->MeteredTerminal = OtherSensor->MeteredTerminal; +/*==========================================================================*/ + + + + + + + +/*==========================================================================*/ + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherSensor->Get_PropertyValue(i)); + } + ((TDSSCktElement*)with0)->BaseFrequency = ((TDSSCktElement*)OtherSensor)->BaseFrequency; + } + else + DoSimpleMsg(String("Error in Sensor MakeLike: \"") + SensorName + + "\" Not Found.", 662); + return result; +} + +/*==============================================================================*/ + +int TSensor::Init(int Handle, int ActorID) +{ + int result = 0; + TSensorObj* pSensor = nullptr; + result = 0; + if(Handle > 0) + { + pSensor = ((TSensorObj*) ElementList.Get(Handle)); + pSensor->ResetIt(); + } + else + // Do 'em all + { + pSensor = ((TSensorObj*) ElementList.Get_First()); + while(pSensor != nullptr) + { + pSensor->ResetIt(); + pSensor = ((TSensorObj*) ElementList.Get_Next()); + } + } + return result; +} + + +/*==========================================================================*/ +/* TSensorObj */ +/*==========================================================================*/ + + + +/*==============================================================================*/ + +TSensorObj::TSensorObj(TDSSClass* ParClass, const String SensorName) + : inherited(ParClass->get_myClass_name()), + ValidSensor(false), + SensorkW(nullptr), + Sensorkvar(nullptr), + kVBase(0.0), + VBase(0.0), + FConn(0), + Vspecified(false), + Ispecified(false), + Pspecified(false), + Qspecified(false), + ClearSpecified(false), + FDeltaDirection(0), + pctError(0.0), + Weight(0.0) +{ + Set_Name(LowerCase(SensorName)); + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + SensorkW = nullptr; + Sensorkvar = nullptr; + kVBase = 12.47; // default 3-phase voltage + Weight = 1.0; + pctError = 1.0; + Set_Conn(0); // Wye + ClearSensor(); + DSSObjType = ParClass->DSSClassType; //SENSOR_ELEMENT; + InitPropertyValues(0); + + // RecalcElementData; +} + +/*==============================================================================*/ + +TSensorObj::~TSensorObj() +{ + ElementName = ""; + free(SensorkW); + free(Sensorkvar); + // inherited::Destroy(); +} + + +/*==============================================================================*/ + +void TSensorObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + ValidSensor = false; + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Sensored element must already exist + { + MeteredElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + if(MeteredTerminal > MeteredElement->Get_NTerms()) + { + DoErrorMsg(String("Sensor: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Respecify terminal no.", 665); + } + else + { + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + + // Sets name of i-th terminal's connected bus in Sensor's buslist + // This value will be used to set the NodeRef array (see TakeSample) + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + ClearSensor(); + ValidSensor = true; + AllocateSensorObjArrays(); + ZeroSensorArrays(); + RecalcVbase(); + } + } + else + { + MeteredElement = nullptr; // element not found + DoErrorMsg(String("Sensor: \"") + this->get_Name() + "\"", String("Circuit Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 666); + } +} + +void TSensorObj::MakePosSequence(int ActorID) +{ + if(MeteredElement != nullptr) + { + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + ClearSensor(); + ValidSensor = true; + AllocateSensorObjArrays(); + ZeroSensorArrays(); + RecalcVbase(); + } + TDSSCktElement::MakePosSequence(ActorID); +} + +/*==============================================================================*/ + +void TSensorObj::RecalcVbase() +{ + switch(FConn) + { + case 0: + if(Fnphases == 1) + VBase = kVBase * 1000.0; + else + VBase = kVBase * 1000.0 / SQRT3; + break; + case 1: + VBase = kVBase * 1000.0; + break; + default: + ; + break; + } +} + +/*==============================================================================*/ + +void TSensorObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*==============================================================================*/ + +/*What does it mean to reset a sensor?*/ + +void TSensorObj::ResetIt() +{ + ClearSensor(); +} + +/*==============================================================================*/ +// For Delta connections or Line-Line voltages + +int TSensorObj::RotatePhases(int j) +{ + int result = 0; + result = j + FDeltaDirection; + + // make sure result is within limits + if(Fnphases > 2) + // Assumes 2 phase delta is open delta + { + if(result > Fnphases) + result = 1; + if(result < 1) + result = Fnphases; + } + else + { + if(result < 1) + result = 3; // For 2-phase delta, next phase will be 3rd phase + } + return result; +} + +/*==============================================================================*/ + +void TSensorObj::TakeSample(int ActorID) +{ + int i = 0; + if(!(ValidSensor && Get_Enabled())) + return; + MeteredElement->GetCurrents(&(CalculatedCurrent[0]), ActorID); + ComputeVterminal(ActorID); + switch(FConn) + { + case 1: + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + (CalculatedVoltage)[i - 1] = csub((Vterminal)[i - 1], (Vterminal)[RotatePhases(i) - 1]); + } + break; + default: + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (CalculatedVoltage)[i - 1] = (Vterminal)[i - 1]; + } + break; + } + + /*NOTE: CalculatedVoltage is complex*/ +} + +/*==============================================================================*/ //Get present value of terminal Curr for reports + +void TSensorObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; +/* + Return array of zero +*/ + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*==============================================================================*/ + +int TSensorObj::get_FConn() +{ + return FConn; +} + +/*==============================================================================*/ + +int TSensorObj::get_FDeltaDirection() +{ + return FDeltaDirection; +} + +/*==============================================================================*/ + +double TSensorObj::get_kVBase() +{ + return kVBase; +} + +/*==============================================================================*/ + +pDoubleArray TSensorObj::get_SensorkW() +{ + return SensorkW; +} + +/*==============================================================================*/ + +pDoubleArray TSensorObj::get_Sensorkvar() +{ + return Sensorkvar; +} + +/*==============================================================================*/ + +void TSensorObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} +/*Updates the currentvector when P and Q are defined + as the input vectors for the sensor*/ + +void TSensorObj::UpdateCurrentVector() +{ + double kVA = 0.0; + int i = 0; +/*Convert P and Q specification to Currents*/ + if(Pspecified) // compute currents assuming vbase + { + if(Qspecified) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + kVA = cabs(cmplx((SensorkW)[i - 1], (Sensorkvar)[i - 1])); + (SensorCurrent)[i - 1] = kVA * 1000.0 / VBase; + } + } + else + // No Q just use P + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (SensorCurrent)[i - 1] = (SensorkW)[i - 1] * 1000.0 / VBase; + } + } + Ispecified = true; // Overrides current specification + } +} +/* + Return the WLS Error for Currents + Get Square error and weight it + +*/ + +double TSensorObj::Get_WLSCurrentError() +{ + double result = 0.0; + double kVA = 0.0; + int i = 0; + result = 0.0; +/*Convert P and Q specification to Currents*/ + if(Pspecified) // compute currents assuming vbase + { + if(Qspecified) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + kVA = cabs(cmplx((SensorkW)[i - 1], (Sensorkvar)[i - 1])); + (SensorCurrent)[i - 1] = kVA * 1000.0 / VBase; + } + } + else + // No Q just use P + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (SensorCurrent)[i - 1] = (SensorkW)[i - 1] * 1000.0 / VBase; + } + } + Ispecified = true; // Overrides current specification + } + if(Ispecified) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + result = result + Sqr((CalculatedCurrent)[i - 1].re) + Sqr((CalculatedCurrent)[i - 1].im) - Sqr((SensorCurrent)[i - 1]); + } + } + result = result * Weight; + return result; +} + +/*==============================================================================*/ +// Get Square error and weight it + +double TSensorObj::Get_WLSVoltageError() +{ + double result = 0.0; + int i = 0; + result = 0.0; + if(Vspecified) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + result = result + Sqr((CalculatedVoltage)[i - 1].re) + Sqr((CalculatedVoltage)[i - 1].im) - Sqr((SensorVoltage)[i - 1]); + } + } + result = result * Weight; + return result; +} + +/*==============================================================================*/ + +void TSensorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + } +} + +/*==============================================================================*/ + +void TSensorObj::ClearSensor() +{ + Vspecified = false; + Ispecified = false; + Pspecified = false; + Qspecified = false; + ClearSpecified = false; +} + +/*==============================================================================*/ + +void TSensorObj::AllocateSensorObjArrays() +{ + SensorkW = new double[Fnphases]; + Sensorkvar = new double[Fnphases]; + AllocateSensorArrays(); +} + +/*==============================================================================*/ + +void TSensorObj::ZeroSensorArrays() +{ + int i = 0; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (SensorCurrent)[i - 1] = 0.0; + (SensorVoltage)[i - 1] = 0.0; + (SensorkW)[i - 1] = 0.0; + (Sensorkvar)[i - 1] = 0.0; + } +} + +/*==============================================================================*/ + +void TSensorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element' + Set_PropertyValue(2,"1"); //'terminal' + Set_PropertyValue(3,"12.47"); //'kVBase' + Set_PropertyValue(4,"No"); // Must be set to yes to clear before setting quantities + Set_PropertyValue(5,"[7.2, 7.2, 7.2]"); + Set_PropertyValue(6,"[0.0, 0.0, 0.0]"); // currents + Set_PropertyValue(7,"[0.0, 0.0, 0.0]"); // P kW + Set_PropertyValue(8,"[0.0, 0.0, 0.0]"); // Q kvar + Set_PropertyValue(9,"wye"); + Set_PropertyValue(10,"1"); + Set_PropertyValue(11,"1"); // %Error + Set_PropertyValue(12,"1"); // %Error + Set_PropertyValue(13,""); // Action + TDSSCktElement::InitPropertyValues(NumPropsThisClass); +} + + +/*==============================================================================*/ + +int TSensorObj::LimitToPlusMinusOne(int i) +{ + int result = 0; + if(i >= 0) + result = 1; + else + result = -1; + return result; +} + +/*--------------------------------------------------------------------------*/ + +/* - function is not actually used +function TSensorObj.Get_FileName: String; +begin + Result := GetOutputDirectory + CircuitName_ + 'Sensor_' + Name + '.csv' +end; +*/ + +/*==============================================================================*/ + +void TSensorObj::Save() +{ +} + + +/*==============================================================================*/ +/*Interpret the Connection*/ + +void TSensorObj::Set_Conn(int Value) +{ + FConn = Value; + RecalcVbase(); +} + +/*==============================================================================*/ +/*Interpret Action Property*/ + +void TSensorObj::Set_Action(const String Value) +{ +} + +/*==============================================================================*/ + //WriteDLLDebugFile('Sensor'); + + + + +} // namespace Sensor + + + + + diff --git a/OpenDSSC/Meters/Sensor.h b/OpenDSSC/Meters/Sensor.h new file mode 100644 index 0000000..0fcb0e5 --- /dev/null +++ b/OpenDSSC/Meters/Sensor.h @@ -0,0 +1,136 @@ +#ifndef SensorH +#define SensorH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "d2c_structures.h" + +namespace Sensor +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 8-24-2007 Created from Monitor Object + Sept-Oct 2008 Modified for new load allocation and state estimator algorithms +*/ + +/* + Sensor compares voltages and currents. Power quantities are converted to current quantities + based on rated kVBase, or actual voltage if voltage measurement specified. +*/ + +/*==============================================================================*/ + +class TSensor : public MeterClass::TMeterClass +{ + friend class TSensorObj; +public: + typedef MeterClass::TMeterClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String SensorName); +public: + TSensor(); + virtual ~TSensor(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void ResetAll(int ActorID); + virtual void SampleAll(int ActorID); // Force all Sensors to take a sample + virtual void SaveAll(int ActorID); // Force all Sensors to save their buffers to disk + void SetHasSensorFlag(); +}; + +/*==============================================================================*/ + +class TSensorObj : public MeterElement::TMeterElement +{ + friend class TSensor; +public: + typedef MeterElement::TMeterElement inherited; +//private: + bool ValidSensor; + Arraydef::pDoubleArray SensorkW; + Arraydef::pDoubleArray Sensorkvar; + double kVBase; // value specified + double VBase; // in volts + int FConn; + bool Vspecified; + bool Ispecified; + bool Pspecified; + bool Qspecified; + bool ClearSpecified; + int FDeltaDirection; + void Set_Conn(int Value); + void Set_Action(const String Value); + void ZeroSensorArrays(); + void AllocateSensorObjArrays(); + void RecalcVbase(); + int RotatePhases(int j); + int LimitToPlusMinusOne(int i); + void ClearSensor(); + void UpdateCurrentVector(); + double Get_WLSCurrentError(); + double Get_WLSVoltageError(); +public: + double pctError; + double Weight; + TSensorObj(DSSClass::TDSSClass* ParClass, const String SensorName); + virtual ~TSensorObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, reset nphases + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a Sensor + virtual void TakeSample(int ActorID); // Go add a sample to the buffer + void ResetIt(); + void Save(); // Saves present buffer to file + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + int get_FConn(); + int get_FDeltaDirection(); + double get_kVBase(); + pDoubleArray get_SensorkW(); + pDoubleArray get_Sensorkvar(); + + TSensorObj(DSSClass::TDSSClass* ParClass); + TSensorObj(String ClassName); + TSensorObj(); +}; + +/*==============================================================================*/ +extern TSensorObj* ActiveSensorObj; + +/*==============================================================================*/ + + +} // namespace Sensor + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Sensor; +#endif + +#endif // SensorH + + + + + diff --git a/OpenDSSC/Meters/VLNodeVars.cpp b/OpenDSSC/Meters/VLNodeVars.cpp new file mode 100644 index 0000000..a693ef7 --- /dev/null +++ b/OpenDSSC/Meters/VLNodeVars.cpp @@ -0,0 +1,23 @@ + +#pragma hdrstop + +#include "VLNodeVars.h" + +using namespace std; +using namespace System; +using namespace Ucomplex; + +namespace VLNodeVars +{ + + + + + + +} // namespace VLNodeVars + + + + + diff --git a/OpenDSSC/Meters/VLNodeVars.h b/OpenDSSC/Meters/VLNodeVars.h new file mode 100644 index 0000000..0fffe83 --- /dev/null +++ b/OpenDSSC/Meters/VLNodeVars.h @@ -0,0 +1,154 @@ +#ifndef VLNodeVarsH +#define VLNodeVarsH + +#include "System.h" +#include "Sysutils.h" + +#include "Ucomplex.h" + +namespace VLNodeVars +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2017 - 2022, Electric Power Research Institute, Inc. + Added by Ying. + ---------------------------------------------------------- + + Definition of Fmonitor (virtue leader) Public Data Record +*/ + //PointerList; + + /*Fmonitor public data/state variable structure*/ + + //value ot save communication delay + //TDelays = packed record +typedef double Tdlys[100/*# range 0..99*/]; //max 99 + + //end; +#pragma pack (push, 1) + + //properties for Node +struct TVLNodeVars; +typedef TVLNodeVars* pNodeVar; + +struct TVLNodeVars +{ + String vl_strBusName; + String vl_strMeasuredName; + int vl_terminalNum; + int vl_ndphases; + double vl_basevolt; + short int vl_nodeType_phase[3]; // range 1..3, set by TFMonitorObj.Init_nodeFM : + //for each phase + //1, dg under it; 2, no dg there + //if a dg is connected, it is 1; + double vl_V; + double vl_V1; + double vl_V2; + double vl_V3; + int Bus_Idx; // has to be updated before being used + // it is related to YMatrix + Ucomplex::complex Yii[4/*# range 0..3*/]; //each phase 123 - ABC, 0 - pos seq + Ucomplex::complex Yij[4/*# range 0..3*/]; //each phase 123 - ABC, 0 - pos seq + + // complex voltage + Ucomplex::complex vl_V_c; + Ucomplex::complex vl_V_1c; + Ucomplex::complex vl_V_2c; + Ucomplex::complex vl_V_3c; + //Properties for DG + String vl_strName_dg; + //vl_terminalNum : integer; + int vl_ndphases_dg; // set by TFMonitorObj.Init_nodeFM: 1,3 + int vl_phase_num_dg; // set by TFMonitorObj.Init_nodeFM, 123--abc 0- this node has 3-phase + //if vl_nodeType=1, and vl_ndphases=1,phase_num =1,2,3 + //SmallIntArray = Array[1..100] of SmallInt; + //vl_strBusName : string; + bool vl_CC_switch_dg;// cooperate control switch. true, cooperate control is on + int vl_PF_flag_dg;//1, real power control is on + int vl_QV_flag_dg;//1, volt/var control is on + double vl_volt_thrd_dg; + //vl_phase_select + double vl_Alpha_dg; + double vl_Alpha1_dg; + double vl_Alpha2_dg; + double vl_Alpha3_dg; + double vl_Alpha_dgn; + double vl_Gradient_dg; + double vl_Gradient1_dg; + double vl_Gradient2_dg; + double vl_Gradient3_dg; + + // communication array for alpha and others can be improved + Tdlys vl_smpl_dg[6/*# range 1..6*/]; //1: alpha; 2: alphaP; 3, bus voltage 0 seq. ; 4,5,6: bus voltage ABC + + // + int vl_SmplCnt; //sample count for this agent + double vl_crnt_smp_time; //time for current sample at this agent + double vl_AlphaP_dg; + double vl_AlphaP1_dg; + double vl_AlphaP2_dg; + double vl_AlphaP3_dg; + double vl_GradientP_dg; + double vl_GradientP1_dg; + double vl_GradientP2_dg; + double vl_GradientP3_dg; + double vl_Pmax_dg; + double vl_Qmax_dg; + double vl_Pmax_phase_dg; + double vl_Qmax_phase_dg; + double vl_V_base_dg; + double vl_V_ref_dg; + double vl_V_ref1_dg; + double vl_V_ref2_dg; + double vl_V_ref3_dg;// nominal value with respect to p.u. 1 //must be set by initialization + double vl_kcq_dg; // the step size gain of agent i //has to be defined befor used + double vl_p_DG; + double vl_p_DG1; + double vl_p_DG2; + double vl_p_DG3; + double vl_kcd_dg; // the step size gain of agent i //has to be defined befor used + double vl_kc_ul_dg; // the cooperative gain for agent i + double vl_q_DG; + double vl_q_DG1; + double vl_q_DG2; + double vl_q_DG3; + //Properties for Loads + int ldType; //-1: noload; 0: one 3phase or 2phase load; 1, 2, 3: 1,2 or 3 single loads; + int ldIdx; + int ldIdx1; + int ldIdx2; + int ldIdx3; + double vl_Q_Di; //all load reactive power except DG + double vl_Q_Di1; // + double vl_Q_Di2; // + double vl_Q_Di3; // + double vl_P_Di; //all load reactive power except DG + double vl_P_Di1; // + double vl_P_Di2; // + double vl_P_Di3; // + // vl_NodeRef : integer;// for global use + + // attack and defense + double d_atk; + double z_dfs; + double z_dfsn; + double d_atk0; +}; +#pragma pack (pop) + +} // namespace VLNodeVars + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace VLNodeVars; +#endif + +#endif // VLNodeVarsH + + + + + diff --git a/OpenDSSC/Meters/fMonitor.cpp b/OpenDSSC/Meters/fMonitor.cpp new file mode 100644 index 0000000..723c60c --- /dev/null +++ b/OpenDSSC/Meters/fMonitor.cpp @@ -0,0 +1,4889 @@ + +#pragma hdrstop + +#include "fMonitor.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "CktTree.h" +#include "CktElement.h" +#include "Transformer.h" +#include "PCElement.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "ShowResults.h" +#include "mathutil.h" +#include "TOPExport.h" +#include "Dynamics.h" +#include "Pstcalc.h" +#include "Terminal.h" +#include "Generic5OrderMach.h" +#include "Capacitor.h" +#include "Load.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Capacitor; +using namespace Circuit; +using namespace CktElement; +using namespace CktTree; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace Generic5OrderMach; +using namespace LD_fm_infos; +using namespace Load; +using namespace MeterClass; +using namespace MeterElement; +using namespace PCElement; +using namespace PDELement; +using namespace ParserDel; +using namespace Pstcalc; +using namespace System; +using namespace TOPExport; +using namespace Transformer; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace VLNodeVars; +using namespace mathutil; +using namespace Utilities; + +namespace Fmonitor +{ + +TFMonitorObj::TFMonitorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TFMonitorObj::TFMonitorObj(String ClassName) : inherited(ClassName) {} +TFMonitorObj::TFMonitorObj() {} + + +TFMonitorObj* ActiveFMonitorObj = nullptr; + /**/ +const int SEQUENCEMASK = 17; +const int MAGNITUDEMASK = 32; +const int POSSEQONLYMASK = 64; +const int ModeMask = 15; +const int NumPropsThisClass = 28;//22;//21;//20;//17; //12;// 9; //8;//7;//add P_ref_one +const int NumSolutionVars = 12; +TFMonitorStrBuffer StrBuffer; + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all Monitor objects + +TDSSFMonitor::TDSSFMonitor() +{ + ; + Class_Name = "FMonitor"; + DSSClassType = DSSClassType + FMON_ELEMENT; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +/*--------------------------------------------------------------------------*/ + +TDSSFMonitor::~TDSSFMonitor() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TDSSFMonitor::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "element"; + PropertyName[2 - 1] = "terminal"; + PropertyName[3 - 1] = "mode"; + PropertyName[4 - 1] = "action"; // buffer=clear|save + PropertyName[5 - 1] = "residual"; // buffer=clear|save + PropertyName[6 - 1] = "VIPolar"; // V I in mag and angle rather then re and im + PropertyName[7 - 1] = "PPolar"; // Power in power PF rather then power and vars + PropertyName[8 - 1] = "P_trans_ref"; + PropertyName[9 - 1] = "V_Sensor"; + PropertyName[10 - 1] = "P_Sensor"; + PropertyName[11 - 1] = "Node_num"; + PropertyName[12 - 1] = "Cluster_num"; + PropertyName[13 - 1] = "Total_Clusters"; + PropertyName[14 - 1] = "Nodes"; + PropertyName[15 - 1] = "CommVector"; + PropertyName[16 - 1] = "ElemTableLine"; + PropertyName[17 - 1] = "P_Mode"; //real power control mode + PropertyName[18 - 1] = "CommDelayVector"; + PropertyName[19 - 1] = "T_intvl_smpl"; //real power control mode + PropertyName[20 - 1] = "MaxLocalMem"; + PropertyName[21 - 1] = "Volt_limits_pu";// set limits for this cluster {0,1.05, 0.95} + PropertyName[22 - 1] = "b_Curt_Ctrl";// set P curtailment on/off + PropertyName[23 - 1] = "up_dly";// delay time to communicate to upper level + PropertyName[24 - 1] = "virtual_ld_node";// delay time to communicate to upper level + PropertyName[25 - 1] = "EGen";//equivalent generator: Egen = {kVA, M, D, Tau, K_i} + PropertyName[26 - 1] = "attack_defense"; // define attack and defense: attack_defense = {atk = true , dfs = false , atk_time = 0.5 , atk_node_num = 1 , d_atk0 = 0.1 , beta_dfs = 30, D_beta = 1} + PropertyName[27 - 1] = "Comm_hide"; // define attack and defense: attack_defense = {atk = true , dfs = false , atk_time = 0.5 , atk_node_num = 1 , d_atk0 = 0.1 , beta_dfs = 30, D_beta = 1} + PropertyName[28 - 1] = "Comm_node_hide"; // define attack and defense: attack_defense = {atk = true , dfs = false , atk_time = 0.5 , atk_node_num = 1 , d_atk0 = 0.1 , beta_dfs = 30, D_beta = 1} + PropertyHelp[1 - 1] = "Name (Full Object name) of element to which the monitor is connected."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the monitor is connected. " + "1 or 2, typically. For monitoring states, attach monitor to terminal 1."; + PropertyHelp[3 - 1] = String("Bitmask integer designating the values the monitor is to capture: ") + CRLF + + "0 = Voltages and currents" + + CRLF + + "1 = Powers" + + CRLF + + "2 = Tap Position (Transformers only)" + + CRLF + + "3 = State Variables (PCElements only)" + + CRLF + + "4 = Flicker level and severity index (Pst) for voltages. No adders apply." + + CRLF + + " Flicker level at simulation time step, Pst at 10-minute time step." + + CRLF + + "5 = Solution variables (Iterations, etc)." + + CRLF + + CRLF + + "Normally, these would be actual phasor quantities from solution." + + CRLF + + "6 = Capacitor Switching (Capacitors only)" + + CRLF + + "Combine with adders below to achieve other results for terminal quantities:" + + CRLF + + "+16 = Sequence quantities" + + CRLF + + "+32 = Magnitude only" + + CRLF + + "+64 = Positive sequence only or avg of all phases" + + CRLF + + CRLF + + "Mix adder to obtain desired results. For example:" + + CRLF + + "Mode=112 will save positive sequence voltage and current magnitudes only" + + CRLF + + "Mode=48 will save all sequence voltages and currents, but magnitude only."; + PropertyHelp[4 - 1] = String("{Clear | Save | Take | Process}") + CRLF + + "(C)lears or (S)aves current buffer." + + CRLF + + "(T)ake action takes a sample." + + CRLF + + "(P)rocesses the data taken so far (e.g. Pst for mode 4)." + + CRLF + + CRLF + + "Note that monitors are automatically reset (cleared) when the Set Mode= command is issued. " + + "Otherwise, the user must explicitly reset all monitors (reset monitors command) or individual " + + "monitors with the Clear action."; + PropertyHelp[5 - 1] = "{Yes/True | No/False} Default = No. Include Residual cbannel (sum of all phases) for voltage and current. " + "Does not apply to sequence quantity modes or power modes."; + PropertyHelp[6 - 1] = "{Yes/True | No/False} Default = YES. Report voltage and current in polar form (Mag/Angle). (default) Otherwise, it will be real and imaginary."; + PropertyHelp[7 - 1] = "{Yes/True | No/False} Default = YES. Report power in Apparent power, S, in polar form (Mag/Angle).(default) Otherwise, is P and Q"; + PropertyHelp[8 - 1] = "P_trans_ref: P ref value for metered element(unit kW)"; + PropertyHelp[9 - 1] = String("V_Sensor") + CRLF + "Enable voltage sensor"; + PropertyHelp[10 - 1] = String("P_Sensor") + CRLF + "Enable power sensor"; + PropertyHelp[11 - 1] = String("Node_num") + CRLF + "Assign a node number within a cluster"; + PropertyHelp[12 - 1] = "Cluster_num"; + PropertyHelp[13 - 1] = String("Total_Clusters.") + CRLF + + "Define the total number of groups in a circuit" + + CRLF + + "Just use for the first defined FMonitor"; + PropertyHelp[14 - 1] = "Nodes connected to this FMonitor. Example:(Nodes=33)"; + PropertyHelp[15 - 1] = String("CommVector of this FMonitor. ") + CRLF + + "The first entry of this vector is the number of " + + CRLF + + "Example:(CommVector={2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})" + + CRLF + + "The example show node #2 can communicate to node #1,#2,#3"; + PropertyHelp[16 - 1] = String("ElemTableLine of the each node within this cluster. ") + CRLF + + "The first entry of this vector is the number of node within cluster " + + CRLF + + "The second entry of this vector is element name " + + CRLF + + "The third entry of this vector is terminal number " + + CRLF + + "The fourth entry of this vector is voltage sensor " + + CRLF + + "Example:(ElemTable={2,Line.1,1,1})" + + CRLF + + "The example show node #2 Element"; + PropertyHelp[17 - 1] = String("0 = real Power controlled by each p_ref on each DG") + CRLF + + "1 = real Power on MeteredElem controlled by DGs according to P_trans_ref" + + CRLF + + "2 = Not defined" + + CRLF + + "3 = Not defined"; + PropertyHelp[18 - 1] = String("CommDelayVector of this FMonitor. ") + CRLF + + "The first entry of this vector is the number of the node." + + CRLF + + "Example:(CommVector={2,t1,0,t2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})" + + CRLF + + "The example show node #2 can communicate to node #1 and #3 with time delay t1 and t2 seperately"; + PropertyHelp[19 - 1] = String("T_intvl_smpl: ") + CRLF + + "The imformation of each agent will be sampled at each T_comm time. Unit is second." + + CRLF + + "T_intvl_smpl is also the minimal communication time between neighbor nodes." + + CRLF + + "If T_intvl_smpl=0.0, no delay for the communication is enabled in the simulation."; + PropertyHelp[20 - 1] = "MaxLocalMem: the max number of local memory siza. No larger than 99"; + PropertyHelp[21 - 1] = String("Volt_limits_pu: exmaple \"Volt_limits_pu={a0,a1, a2}\"") + CRLF + + "a0: the phase number, 0 means pos. seq; a1: upper voltage limit of this cluster, usually 1.05;" + + CRLF + + "a2: upper voltage limit of this cluster, usually 0.95";// set limits for this cluster {0,1.05, 0.95} +// set P curtailment on/off + PropertyHelp[22 - 1] = String("b_Curt_Ctrl:set P curtailment on/off;") + CRLF + + "b_Curt_Ctrl=True: P curtailment will be implemented according to the system voltage (default);" + + CRLF + + "b_Curt_Ctrl=False: P curtailment will not be implemented."; + PropertyHelp[23 - 1] = String("up_dly: delay time to upper level. For example: \"up_dly := 0.05\"") + CRLF + + "It can be used to simulate the time delay between clusters"; + PropertyName[24 - 1] = "virtual_ld_node: which node talks to upper level. virtual_ld_node=1"; + PropertyHelp[25 - 1] = String(" EGen = {kVA_fm, M_fm, D_fm, Tau_fm, Ki_fm,init_time}") + CRLF + + "where equations are:" + + CRLF + + "(1):delta''=omega" + + CRLF + + "(1):M_fm * omega''=puPm - puPe - D_fm*omega" + + CRLF + + "(1):Tau_fm*Pm ''=Ki_fm * omega " + + CRLF + + "puPm = Pm / kVA_fm, puPe = Pe/ kVAM_fm;" + + CRLF + + "everything is zero within init_time(default value is 0.5s);" + + CRLF + + "k_dltP is the coordinator for PV control input: u_i = k_dltP * pu_DltP + omg_fm."; + PropertyHelp[26 - 1] = String("Define attack and defense: attack_defense = {atk , dfs , atk_time , atk_node_num , d_atk0 , beta_dfs, D_beta, D_p }.") + CRLF + + "attack_defense has to be defined after ''nodes'." + + CRLF + + "Example: attack_defense = { true , false , 0.5 , 1 , 0.1 , 5, 1 , 1}." + + CRLF + + "Example: (1) under attack); (2) defense is off; (3) attack starts at 0.5s; (4) attack is on node 1;" + + CRLF + + "(5) initial value of attack: d_0 = 0.1; (6) beta = 5;" + + CRLF + + "(7) D_bata is used as a multiplier on \\phi;" + + CRLF + + "(8) D_p is used as the attack on gradient contol: D_p = 1, which is normal; D_p=-1, gradient control work on the oppesite."; + PropertyHelp[27 - 1] = "Comm_hide={...}. It is defined like CommVector."; // define attack and defense: attack_defense = {atk = true , dfs = false , atk_time = 0.5 , atk_node_num = 1 , d_atk0 = 0.1 , beta_dfs = 30, D_beta = 1} + PropertyHelp[28 - 1] = "Comm_node_hide={...}. It is defined like CommVector."; // define attack and defense: attack_defense = {atk = true , dfs = false , atk_time = 0.5 , atk_node_num = 1 , d_atk0 = 0.1 , beta_dfs = 30, D_beta = 1} + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TDSSFMonitor::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Monitor and add it to Monitor class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement((TDSSCktElement*) new TFMonitorObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} +/*--------------------------------------------------------------------------*/ + +int TDSSFMonitor::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int recalc = 0; + int i = 0; + + // continue parsing with contents of Parser + // continue parsing with contents of Parser + ActiveFMonitorObj = ((TFMonitorObj*) ElementList.Get_Active()); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveFMonitorObj); + result = 0; + recalc = 0; + /*# with ActiveFMonitorObj do */ + { + auto with0 = ActiveFMonitorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + ++recalc; + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 661); + break; + case 1: + { + with0->ElementName = ConstructElemName(LowerCase(Param)); // subtitute @var values if any + with0->Set_PropertyValue(1,with0->ElementName); + } + break; + case 2: + with0->MeteredTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->Mode = Parser[ActorID]->MakeInteger_(); + break; + case 4: + { + Param = LowerCase(Param); + switch(Param[1]) + { + case L's': + with0->Save(); + break; + case L'c': case L'r': + with0->ResetIt(ActorID); + break; + case L't': + with0->TakeSample(ActorID); + break; + //'p': begin PostProcess(ActorID); dec(recalc) end + default: + ; + break; + } + } + break; // buffer + case 5: + with0->IncludeResidual = InterpretYesNo(Param); + break; + case 6: + with0->VIpolar = InterpretYesNo(Param); + break; + case 7: + with0->Ppolar = InterpretYesNo(Param); + break; + case 8: + with0->P_trans_ref = 1000 * Parser[ActorID]->MakeDouble_(); + break;//kW for ref, unit of p_trans_ref is 'W' + case 9: + with0->V_Sensor = Parser[ActorID]->MakeInteger_(); + break;//Voltage Sensor: Binary + case 10: + with0->P_Sensor = Parser[ActorID]->MakeInteger_(); + break;//Power sensor : Binary + //11: Node_num := Parser[ActorID].MakeInteger_();//Node number : integer + case 12: + with0->Cluster_num = Parser[ActorID]->MakeInteger_(); + break;//group number: integer + case 13: + with0->Total_Clusters = Parser[ActorID]->MakeInteger_(); + break;//Total number of the groups: integer + case 14: + with0->Set_nodes_for_fm(Parser[ActorID]->MakeInteger_()); + break;//Nodes. Innitiate the structure + case 15: + with0->Set_CommVector(Param); + break;// + case 16: + with0->Set_ElemTable_line(Param); + break;// + case 17: + with0->p_mode = Parser[ActorID]->MakeInteger_(); + break; + case 18: + with0->Set_CommDelayVector(Param); + break;// + case 19: + { + int stop = 0; + with0->T_intvl_smpl = Parser[ActorID]->MakeDouble_(); // + for(stop = with0->Nodes, i = 0; i < stop; i++) + { + with0->ResetDelaySteps(i); + } + } + break; + case 20: + with0->MaxLocalMem = Parser[ActorID]->MakeInteger_(); + break; + case 21: + with0->Set_volt_lmt_clstr(Param); + break; + case 22: + with0->ld_fm_info[0].b_Curt_Ctrl = InterpretYesNo(Param); + break; //curtailment + case 23: + { + with0->up_dly = Parser[ActorID]->MakeDouble_(); + if(with0->T_intvl_smpl != 0.0) + { + if(Frac(with0->up_dly / with0->T_intvl_smpl) != 0.0L) + with0->nup_dlys = Trunc(with0->up_dly / with0->T_intvl_smpl); + else + with0->nup_dlys = Trunc(with0->up_dly / with0->T_intvl_smpl) + 1; + } + else + with0->nup_dlys = 0; + } + break; + case 24: + with0->virtual_Ld_Nd = Parser[ActorID]->MakeInteger_() - 1; + break; + case 25: + with0->Set_EquivalentGenerator(Param); + break; + case 26: + with0->Set_atk_dfs(Param); + break; + case 27: + with0->Set_CommVector_Hide(Param); + break;// + case 28: + with0->Set_CommVector_NodeHide(Param); + break;// + + // Inherited parameters + default: + ClassEdit(ActiveFMonitorObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + if(recalc > 0) + with0->RecalcElementData(ActorID); + } + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to reset + +void TDSSFMonitor::ResetAll(int ActorID) +{ + TFMonitorObj* Mon = nullptr; + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(Mon != nullptr) + { + if( ( (TDSSCktElement*) Mon )->Get_Enabled()) + Mon->ResetIt(ActorID); + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to take a sample + +void TDSSFMonitor::SampleAll(int ActorID) +{ + TFMonitorObj* Mon = nullptr; +// sample all monitors except mode 5 monitors + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + { + if(Mon->Mode != 5) + Mon->TakeSample(ActorID); + } + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + } + //ProcessFvalue; +} +//This function is used to measure total net power of a cluster + //all FMs + +void TDSSFMonitor::update_sys_ld_info(int ActorID) +{ + TFMonitorObj* FMon = nullptr; + double vtemp = 0.0; + double dv_lwst = 0.0; + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_hghst = -999999; + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst = 9999999; + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(FMon != nullptr) + + //update all agents information: + //synchronous: voltage to agents + //asynchronous: aphga, ahphaP, highest/lowest voltage + { + if( ( (TDSSCktElement*) FMon )->Get_Enabled()) + { + FMon->update_node_info_each_time_step(ActorID); //update old z_dfs, vl_alpha_dgn + FMon->update_ld_dly(ActorID); //with delay + } + // + /*Update cluster info to center*/ + if(ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_hghst < FMon->ld_fm_info[0].volt_hghst) + { + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_hghst = FMon->ld_fm_info[0].volt_hghst; + ActiveCircuit[ActorID]->Solution->LD_FM[0].ndnum_hghst = FMon->ld_fm_info[0].ndnum_hghst; + ActiveCircuit[ActorID]->Solution->LD_FM[0].clstr_num_hghst = FMon->Cluster_num; + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_hgh_lmt = FMon->ld_fm_info[0].volt_hgh_lmt; + ActiveCircuit[ActorID]->Solution->LD_FM[0].b_ctrl_hghst = FMon->ld_fm_info[0].b_ctrl_hghst; + } + if(ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst > FMon->ld_fm_info[0].volt_lwst) + { + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst = FMon->ld_fm_info[0].volt_lwst; + ActiveCircuit[ActorID]->Solution->LD_FM[0].ndnum_lwst = FMon->ld_fm_info[0].ndnum_lwst; + ActiveCircuit[ActorID]->Solution->LD_FM[0].clstr_num_lwst = FMon->Cluster_num; + ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lw_lmt = FMon->ld_fm_info[0].volt_lw_lmt; + ActiveCircuit[ActorID]->Solution->LD_FM[0].b_ctrl_lwst = FMon->ld_fm_info[0].b_ctrl_lwst; + } + + /*---- curtailment ----- bCurtl := t/f for overall system ------*/ + //curtailment is needed or not + if(FMon->ld_fm_info[0].volt_hghst > 1.0) //need curtailment + FMon->ld_fm_info[0].b_ctrl_hghst = true; + else + FMon->ld_fm_info[0].b_ctrl_hghst = false; + /*---- each cluster may have their own ---*/ + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + } + //curtailment is needed or not + vtemp = (ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_hghst - ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst);//p.u. + dv_lwst = ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst - ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lw_lmt;//0.95; // must greater than 0.0 + if(dv_lwst < 0.0) + { + ActiveCircuit[ActorID]->Solution->bCurtl = true; //curtailment + } + else + { + ActiveCircuit[ActorID]->Solution->bCurtl = false;//dont need curtailment + } +}// calculte frequency for each cluster + +void TDSSFMonitor::Calc_P_freq(int ActorID) +{ + TFMonitorObj* FMon = nullptr; + //ActiveCircuit[ActorID].Solution.LD_FM[0].freq := 0; //saved for system frequency + //ActiveCircuit[ActorID].Solution.LD_FM[0].delta := 0; //saved for angle of the inertia center of a cluster + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(FMon != nullptr) + { + if(((TDSSCktElement*)FMon)->Get_Enabled()) + { + if(FMon->eg_defed == true) + FMon->Calc_P_freq_fm(ActorID); //w + } + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + // + } +} + +void TDSSFMonitor::update_atks(int ActorID) +{ + TFMonitorObj* FMon = nullptr; + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(FMon != nullptr) + { + if(((TDSSCktElement*)FMon)->Get_Enabled() && (FMon->atk == true)) + FMon->update_attack(ActorID); //w + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + // + } +} + +void TDSSFMonitor::update_defense_layer(int ActorID) +{ + TFMonitorObj* FMon = nullptr; + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(FMon != nullptr) + { + if(((TDSSCktElement*)FMon)->Get_Enabled() && (FMon->dfs == true)) + FMon->update_defense(ActorID); //w + FMon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + // + } +} + +/*--------------------------------------------------------------------------*/ +/* +Procedure TDSSFMonitor.PostProcessAll(ActorID : Integer); +VAR + Mon:TFMonitorObj; +Begin + Mon := ActiveCircuit[ActorID].FMonitors.Get_First(); + WHILE Mon<>Nil DO Begin + If Mon.Enabled Then Mon.PostProcess; + Mon := ActiveCircuit[ActorID].FMonitors.Get_Next(); + End; +End; +*/ +/*--------------------------------------------------------------------------*/ // Force all monitors in the circuit to save their buffers to disk + +void TDSSFMonitor::SaveAll(int ActorID) +{ + TFMonitorObj* Mon = nullptr; + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_First()); + while(Mon != nullptr) + { + if(((TDSSCktElement*)Mon)->Get_Enabled()) + Mon->Save(); + Mon = ((TFMonitorObj*) ActiveCircuit[ActorID]->FMonitors.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ + +int TDSSFMonitor::MakeLike(const String MonitorName) +{ + int result = 0; + TFMonitorObj* OtherMonitor = nullptr; + int i = 0; + result = 0; + /*See if we can find this Monitor name in the present collection*/ + OtherMonitor = ((TFMonitorObj*) Find(MonitorName)); + if(OtherMonitor != nullptr) + /*# with ActiveFMonitorObj do */ + { + auto with0 = ActiveFMonitorObj; + int stop = 0; + ((TDSSCktElement*)with0)->Set_NPhases(((TDSSCktElement*)OtherMonitor)->Fnphases); + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)OtherMonitor)->Fnconds); // Force Reallocation of terminal stuff + with0->BufferSize = OtherMonitor->BufferSize; + with0->ElementName = OtherMonitor->ElementName; + with0->MeteredElement = OtherMonitor->MeteredElement; // Pointer to target circuit element + with0->MeteredTerminal = OtherMonitor->MeteredTerminal; + with0->Mode = OtherMonitor->Mode; + with0->IncludeResidual = OtherMonitor->IncludeResidual; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherMonitor->Get_PropertyValue(i)); + } + with0->BaseFrequency = OtherMonitor->BaseFrequency; + } + else + DoSimpleMsg(String("Error in Monitor MakeLike: \"") + MonitorName + + "\" Not Found.", 662); + return result; +} + +/*--------------------------------------------------------------------------*/ + +int TDSSFMonitor::Init(int Handle, int ActorID) +{ + int result = 0; + TFMonitorObj* Mon = nullptr; + result = 0; + if(Handle > 0) + { + Mon = ((TFMonitorObj*) ElementList.Get(Handle)); + Mon->ResetIt(ActorID); + } + else + // Do 'em all + { + Mon = ((TFMonitorObj*) ElementList.Get_First()); + while(Mon != nullptr) + { + Mon->ResetIt(ActorID); + Mon = ((TFMonitorObj*) ElementList.Get_Next()); + } + } + return result; +} + + +/*==========================================================================*/ +/* TFMonitorObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TFMonitorObj::TFMonitorObj(TDSSClass* ParClass, const String MonitorName) + : inherited(ParClass), + Nodes(33), + pCommMatrix(nullptr), + P_trans_ref(0.0), + p_mode(0), + BufferSize(0), + Hour(0), + Sec(0.0), + MonBuffer(nullptr), + BufPtr(0), + CurrentBuffer(nullptr), + VoltageBuffer(nullptr), + NumStateVars(0), + StateBuffer(nullptr), + FlickerBuffer(nullptr), + SolutionBuffer(nullptr), + IncludeResidual(false), + VIpolar(false), + Ppolar(false), + FileSignature(0), + FileVersion(0), + BaseFrequency(0.0), + F_Value_one(0.0), + F_Value_one_V(nullptr), + F_Value_one_S(nullptr), + Fvalue_P(0.0), + Fvalue_Q(0.0), + F_P_one(0.0), + F_Q_one(0.0), + P_ref_one(0.0), + Node_num(0), + V_Sensor(0), + P_Sensor(0), + Cluster_num(0), + Total_Clusters(0), + T_intvl_smpl(0.0), + MaxLocalMem(0), + Smpl_stps(0), + pCommDelayMatrix(nullptr), + pCommDelaySteps(nullptr), + kVA_fm(0.0), + M_fm(0.0), + D_fm(0.0), + Tau_fm(0.0), + Ki_fm(0.0), + Pm_fm(0.0), + init_time(0.0), + k_dltP(0.0), + up_dly(0.0), + nup_dlys(0), + virtual_Ld_Nd(0), + d_atk_inited(false), + z_dfs_inited(false), + atk_node_num(0), + atk_time(0.0), + beta_dfs(0.0), + D_beta(0.0), + D_p(0.0), + dlt_z0(0.0), + pCommHide(nullptr), + pCommNode_Hide(nullptr), + Bus_code(0), + NodeNum(0), + Node_Ref(0), + IsFileOpen(false), + ValidMonitor(false), + IsProcessed(false), + pNodeFMs(nullptr), + Mode(0), + SampleCount(0), + eg_defed(false), + dlt_fm(0.0), + omg_fm(0.0), + comp_omg(0.0), + atk(false), + dfs(false) +{ + int i = 0; + int stop = 0; + Set_Name(LowerCase(MonitorName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + pNodeFMs = nullptr; + //pNodeFMs := AllocMem(Sizeof(pNodeFMs^[1] )* 1); + + /*Current Buffer has to be big enough to hold all terminals*/ + CurrentBuffer = nullptr; + VoltageBuffer = nullptr; + StateBuffer = nullptr; + FlickerBuffer = nullptr; + SolutionBuffer = nullptr; + BaseFrequency = 60.0; + Hour = 0; + Sec = 0.0; + Mode = 0; // Standard Mode: V & I, complex values + BufferSize = 1024; // Makes a 4K buffer + MonBuffer = (pSingleArray) malloc( sizeof(float) * BufferSize ); + BufPtr = 0; + ElementName = ((TDSSObject*) ActiveCircuit[ActiveActor]->CktElements.Get(1))->get_Name(); // Default to first circuit element (source) + MeteredElement = nullptr; + BufferFile = ""; + + //MonitorStream := TMemoryStream.Create; // Create memory stream + IsFileOpen = false; + MeteredTerminal = 1; + IncludeResidual = false; + VIpolar = true; + Ppolar = true; + FileSignature = 43756; + FileVersion = 1; + SampleCount = 0; + IsProcessed = false; + DSSObjType = ParClass->DSSClassType; //MON_ELEMENT; + InitPropertyValues(0); + pCommMatrix = (pSmallIntArray) malloc( sizeof(pCommMatrix[0]) * Nodes * Nodes); + /**/ + F_Value_one_V = (pDoubleArray)malloc(sizeof(double) * 999); + F_Value_one_S = (pComplexArray)malloc(sizeof(complex) * 999); + /**/ + T_intvl_smpl = 0; + MaxLocalMem = 10; + pCommDelayMatrix = (pDoubleArray)malloc(sizeof(double) * Nodes * Nodes); + pCommDelaySteps = (pSmallIntArray)malloc(sizeof(pCommMatrix[0]) * Nodes * Nodes); + pCommHide = (pSmallIntArray)malloc(sizeof(pCommMatrix[0]) * Nodes * Nodes); + pCommNode_Hide = (pSmallIntArray)malloc(sizeof(pCommMatrix[0]) * Nodes * Nodes); + + /*leader information*/ + for(stop = 3, i = 0; i <= stop; i++) + { + ld_fm_info[i].ndnum_hghst = 0; + ld_fm_info[i].b_ctrl_hghst = false; //small number that can never be true + ld_fm_info[i].volt_hghst = -1.0; + ld_fm_info[i].volt_hgh_lmt = 1.05; + ld_fm_info[i].Pinjec_hghst = 0.0; + ld_fm_info[i].ndnum_lwst = 0; + ld_fm_info[i].b_ctrl_lwst = false; + ld_fm_info[i].volt_lw_lmt = 0.95; + ld_fm_info[i].volt_lwst = 9999999999.0; //large nunber can never be true + ld_fm_info[i].Pinjec_lwst = 0.0; + ld_fm_info[i].volt_avg = 0.0; + ld_fm_info[i].total_pg = 0.0; + ld_fm_info[i].total_pl = 0.0; + ld_fm_info[i].b_Curt_Ctrl = false; + } + virtual_Ld_Nd = 0; + nup_dlys = 0; + //bCurtl_Clstr := false; + /*end of leader initialization*/ + //virtual generator for frequency + eg_defed = false; + kVA_fm = 0.0; + M_fm = 0.0; + D_fm = 0.0; + Tau_fm = 0.0; + Ki_fm = 0.0; + dlt_fm = 0.0; + omg_fm = 0.0; + Pm_fm = 0.0; + init_time = 0.5; + comp_omg = 0.0; + // when the attack time starts + atk = false; + atk_time = 0.5; + atk_node_num = 1; + d_atk_inited = false; + z_dfs_inited = false; + D_beta = 1; + D_p = 1; + dlt_z0 = 0.0; +} + +TFMonitorObj::~TFMonitorObj() +{ + + //MonitorStream.Free; + ElementName = ""; + BufferFile = ""; + free(MonBuffer); + free(StateBuffer); + free(CurrentBuffer); + free(VoltageBuffer); + free(FlickerBuffer); + free(SolutionBuffer); + /**/ + if(ASSIGNED(F_Value_one_V)) + free(F_Value_one_V); + if(ASSIGNED(F_Value_one_S)) + free(F_Value_one_S); + /**/ + delete[] pNodeFMs; + free(pCommMatrix); + free(pCommDelayMatrix); + free(pCommDelaySteps); + // + free(pCommHide); + free(pCommNode_Hide); + // inherited::Destroy(); +} + + + +/*--------------------------------------------------------------------------*/ + +void ConvertBlanks(String& s) +{ + int BlankPos = 0; + /* Convert spaces to Underscores */ + BlankPos = Pos(" ", s); + while(BlankPos > 0) + { + s[BlankPos] = L'_'; + BlankPos = Pos(" ", s); + } +} + +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + int i = 0; + ValidMonitor = false; + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Monitored element must already exist + { + MeteredElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + switch((Mode & ModeMask)) + { + case 2: // Must be transformer + { + if((MeteredElement->DSSObjType & CLASSMASK) != XFMR_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " is not a transformer!", 663); + return; + } + } + break; // Must be PCElement + case 3: + { + if((MeteredElement->DSSObjType & BaseClassMask) != PC_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " must be a power conversion element (Load or Generator)!", 664); + return; + } + } + break; // Checking Caps Tap + case 6: + { + if((MeteredElement->DSSObjType & CLASSMASK) != CAP_ELEMENT) + { + DoSimpleMsg(MeteredElement->get_Name() + " is not a capacitor!", 2016001); + return; + } + } + break; + default: + ; + break; + } + if(MeteredTerminal > MeteredElement->Get_NTerms()) + { + DoErrorMsg(String("FMonitor: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Respecify terminal no.", 665); + } + else + { + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + + // Sets name of i-th terminal's connected bus in monitor's buslist + // This value will be used to set the NodeRef array (see TakeSample) + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + switch((Mode & ModeMask)) + { + case 3: + { + NumStateVars = ((TPCElement*) MeteredElement)->NumVariables(); + StateBuffer = (pDoubleArray)realloc(StateBuffer, sizeof(double) * NumStateVars); + } + break; + case 4: + { + FlickerBuffer = (pComplexArray)realloc(FlickerBuffer, sizeof(complex) * Get_NPhases()); + } + break; + case 5: + { + SolutionBuffer = (pDoubleArray)realloc(SolutionBuffer, sizeof(double) * NumSolutionVars); + } + break; + default: + CurrentBuffer = (pComplexArray)realloc(CurrentBuffer, sizeof(complex) * MeteredElement->Yorder); + VoltageBuffer = (pComplexArray)realloc(VoltageBuffer, sizeof(complex) * MeteredElement->Get_NConds()); + break; + } + + //ClearMonitorStream; + ValidMonitor = true; + } + } + else + { + MeteredElement = nullptr; // element not found + DoErrorMsg(String("Monitor: \"") + this->get_Name() + "\"", String("Circuit Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 666); + } + /**/ + /**/ +} + +void TFMonitorObj::MakePosSequence(int ActorID) +{ + if(MeteredElement != nullptr) + { + SetBus(1, MeteredElement->GetBus(MeteredTerminal)); + Set_NPhases(MeteredElement->Get_NPhases()); + Set_Nconds(MeteredElement->Get_NConds()); + switch((Mode & ModeMask)) + { + case 3: + { + NumStateVars = ((TPCElement*) MeteredElement)->NumVariables(); + StateBuffer = (pDoubleArray)realloc(StateBuffer, sizeof(double) * NumStateVars); + } + break; + case 4: + { + FlickerBuffer = (pComplexArray)realloc(FlickerBuffer, sizeof(complex) * Get_NPhases()); + } + break; + case 5: + { + SolutionBuffer = (pDoubleArray)realloc(SolutionBuffer, sizeof(double) * NumSolutionVars); + } + break; + default: + CurrentBuffer = (pComplexArray)realloc(CurrentBuffer, sizeof(complex) * MeteredElement->Yorder); + VoltageBuffer = (pComplexArray)realloc(VoltageBuffer, sizeof(complex) * MeteredElement->Get_NConds()); + break; + } + //ClearMonitorStream; + ValidMonitor = true; + } + TDSSCktElement::MakePosSequence(ActorID); +} + + +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::CalcYPrim(int ActorID) +{ + + + /*A Monitor is a zero current source; Yprim is always zero.*/ + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. +} + +/*--------------------------------------------------------------------------*/ + +// Saves present buffer to monitor file, resets bufferptrs and continues + +void TFMonitorObj::Save() +{ + + + //If NOT IsFileOpen THEN OpenMonitorStream; // Position to end of stream + + /*Write present monitor buffer to monitorstream*/ + //MonitorStream.Write(MonBuffer^, SizeOF(MonBuffer^[1]) * BufPtr); + BufPtr = 0; // reset Buffer for next +} +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::Set_nodes_for_fm(int intNodes) +{ + int i = 0; + int j = 0; + // + int stop = 0; + Nodes = intNodes;//initalize the size according to nodes + if(pNodeFMs != nullptr) + { + delete[] pNodeFMs; + pNodeFMs = nullptr; + } + if(pCommMatrix != nullptr) + free(pCommMatrix); + if(pCommDelayMatrix != nullptr) + free(pCommDelayMatrix); + if(pCommDelaySteps != nullptr) + free(pCommDelaySteps); + if(pCommHide != nullptr) + free(pCommHide); + if(pCommNode_Hide != nullptr) + free(pCommNode_Hide); + + pNodeFMs = new TVLNodeVars[intNodes]; + pCommMatrix = (pSmallIntArray)malloc(sizeof(pCommMatrix[0]) * intNodes * intNodes); + pCommHide = (pSmallIntArray)malloc(sizeof(pCommHide[0]) * intNodes * intNodes); + pCommNode_Hide = (pSmallIntArray)malloc(sizeof(pCommNode_Hide[0]) * intNodes * intNodes); + pCommDelayMatrix = (pDoubleArray)malloc(sizeof(pCommDelayMatrix[0]) * intNodes * intNodes); + pCommDelaySteps = (pSmallIntArray)malloc(sizeof(pCommDelaySteps[0]) * intNodes * intNodes); + for(stop = Nodes, i = 0; i < stop; i++) + { + int stop1 = 0; + for(stop1 = Nodes, j = 0; j < stop1; j++) + { + (pCommDelayMatrix)[Nodes * i + j] = 0.0; + pCommMatrix[Nodes * i + j] = 0; + pCommHide[Nodes * i + j] = 0; + pCommNode_Hide[Nodes * i + j] = 0; + pCommDelaySteps[Nodes * i + j] = 0; + } + } +} +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::Set_volt_lmt_clstr(String strParam) +{ + String dummy; + int i = 0; + double Datahgh = 0.0; + double datalw = 0.0; + int iPhasenum = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the No. of iNode + iPhasenum = AuxParser[ActiveActor]->MakeInteger_(); //node number defined in cluster + dummy = AuxParser[ActiveActor]->GetNextParam(); // high limit + Datahgh = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // low limit + datalw = AuxParser[ActiveActor]->MakeDouble_(); + switch(iPhasenum) + { + case 0: + { + ld_fm_info[0].volt_hgh_lmt = Datahgh; + ld_fm_info[0].volt_lw_lmt = datalw; + } + break; + case 1: + ; + break; + case 2: + ; + break; + case 3: + ; + break; + default: + ; + break; + } +} + +void TFMonitorObj::Set_CommVector(String strParam) +{ + String dummy; + String TempStr; + String DataStr; // the min if Nodes or the length of the vector + int i = 0; + int j = 0; + int IMin = 0; + int iNodeNum = 0; + int stop = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + //iMin := min(Nodes, ) + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the No. of iNode + iNodeNum = AuxParser[ActiveActor]->MakeInteger_() - 1; //node number defined in cluster + for(stop = Nodes, i = 0; i < stop; i++) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + { + (pCommMatrix)[iNodeNum * Nodes + i] = (short int) AuxParser[ActiveActor]->MakeInteger_(); + (pCommHide)[iNodeNum * Nodes + i] = (short int) AuxParser[ActiveActor]->MakeInteger_(); //default + (pCommNode_Hide)[iNodeNum * Nodes + i] = (short int) AuxParser[ActiveActor]->MakeInteger_(); //default + } + } + +// Updates the value of the property for future queries +// Added y Davis 02072019 + TempStr = ""; + for(stop = Nodes, j = 0; j < stop; j++) + { + int stop1 = 0; + iNodeNum = j; + TempStr = TempStr + IntToStr(iNodeNum + 1) + ","; + for(stop1 = Nodes, i = 0; i < stop1; i++) + { + TempStr = TempStr + IntToStr(pCommMatrix[iNodeNum * Nodes + i]) + ","; + } + TempStr = TempStr + "|"; + } + ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->Set_PropertyValue(15,TempStr); +} + +void TFMonitorObj::Set_CommVector_Hide(String strParam) +{ + String dummy; + String DataStr; + int i = 0; + int IMin = 0; // the min if Nodes or the length of the vector + int iNodeNum = 0; + int stop = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + //iMin := min(Nodes, ) + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the No. of iNode + iNodeNum = AuxParser[ActiveActor]->MakeInteger_() - 1; //node number defined in cluster + for(stop = Nodes, i = 0; i < stop; i++) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + pCommHide[iNodeNum * Nodes + i] = (short int) AuxParser[ActiveActor]->MakeInteger_(); + } +} + +void TFMonitorObj::Set_CommVector_NodeHide(String strParam) +{ + String dummy; + String DataStr; + int i = 0; + int IMin = 0; // the min if Nodes or the length of the vector + int iNodeNum = 0; + int stop = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + //iMin := min(Nodes, ) + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the No. of iNode + iNodeNum = AuxParser[ActiveActor]->MakeInteger_() - 1; //node number defined in cluster + for(stop = Nodes, i = 0; i < stop; i++) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + pCommNode_Hide[iNodeNum * Nodes + i] = (short int) AuxParser[ActiveActor]->MakeInteger_(); + } +} + +void TFMonitorObj::Set_CommDelayVector(String strParam) +{ + String dummy; + String TempStr; + String DataStr; + int i = 0; + int j = 0; + int iNodeNum = 0; + int stop = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + //iMin := min(Nodes, ) + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the No. of iNode + iNodeNum = AuxParser[ActiveActor]->MakeInteger_() - 1; //node number defined in cluster + for(stop = Nodes, i = 0; i < stop; i++) + { + dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + pCommDelayMatrix[iNodeNum * Nodes + i] = AuxParser[ActiveActor]->MakeDouble_(); + } + ResetDelaySteps(iNodeNum); //Use pCommDelayMatrix^ to calculate pCommDelaySteps^ + +// Updates the value of the property for future queries +// Added y Davis 02072019 + TempStr = ""; + for(stop = Nodes, j = 0; j < stop; j++) + { + int stop1 = 0; + iNodeNum = j; + TempStr = TempStr + IntToStr(iNodeNum + 1) + ","; + for(stop1 = Nodes, i = 0; i < stop1; i++) + { + TempStr = TempStr + FloatToStr(pCommDelayMatrix[iNodeNum * Nodes + i]) + ","; + } + TempStr = TempStr + "|"; + } + ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->Set_PropertyValue(18,TempStr); +} + +void TFMonitorObj::Set_EquivalentGenerator(String strParam) +{ + String dummy; + String DataStr; + int i = 0; + int iNodeNum = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is kVA + kVA_fm = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // + M_fm = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // + D_fm = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // + Tau_fm = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // + Ki_fm = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // init_time + init_time = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // k_dltP is the coordinator + k_dltP = AuxParser[ActiveActor]->MakeDouble_(); + if(kVA_fm * M_fm * D_fm * Tau_fm * Ki_fm != 0.0) + eg_defed = true; //eg_defed := false by default +} + +void TFMonitorObj::Set_atk_dfs(String strParam) +{ + String dummy; + String DataStr; + int i = 0; + int iNodeNum = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + dummy = AuxParser[ActiveActor]->GetNextParam(); // atk + DataStr = AuxParser[ActiveActor]->MakeString_(); + atk = InterpretYesNo(DataStr); + dummy = AuxParser[ActiveActor]->GetNextParam(); // dfs + DataStr = AuxParser[ActiveActor]->MakeString_(); + dfs = InterpretYesNo(DataStr); + dummy = AuxParser[ActiveActor]->GetNextParam(); // atk_time + atk_time = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // atk_node_num + atk_node_num = AuxParser[ActiveActor]->MakeInteger_() - 1; + dummy = AuxParser[ActiveActor]->GetNextParam(); // d_atk0 + (pNodeFMs)[atk_node_num].d_atk0 = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // beta_dfs + beta_dfs = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // D_beta + D_beta = AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); // direction of gradient control + D_p = AuxParser[ActiveActor]->MakeDouble_(); +} +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::Set_ElemTable_line(String strParam) +{ + String dummy; + String TempStr; + String DataStr; + int i = 0; + int iNodeNum = 0; + int stop = 0; + AuxParser[ActiveActor]->SetCmdString(strParam); // Load up Parser + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the number of the iNode + iNodeNum = AuxParser[ActiveActor]->MakeInteger_() - 1; //node number defined in the cluster + dummy = AuxParser[ActiveActor]->GetNextParam(); // the first entry is the number of the iNode + (pNodeFMs)[iNodeNum].vl_strBusName = AuxParser[ActiveActor]->MakeString_(); //node number defined in the cluster + dummy = AuxParser[ActiveActor]->GetNextParam(); + (pNodeFMs)[iNodeNum].vl_strMeasuredName = AuxParser[ActiveActor]->MakeString_(); //Element name load into data str + // + //pNodeFMs^[iNodeNum].vl_strName_dg := pNodeFMs^[iNodeNum].vl_strMeasuredName; + // + dummy = AuxParser[ActiveActor]->GetNextParam(); + (pNodeFMs)[iNodeNum].vl_terminalNum = AuxParser[ActiveActor]->MakeInteger_(); //Terminal number load into data str + dummy = AuxParser[ActiveActor]->GetNextParam(); + (pNodeFMs)[iNodeNum].vl_V_ref_dg = 1000 * AuxParser[ActiveActor]->MakeDouble_(); + dummy = AuxParser[ActiveActor]->GetNextParam(); + (pNodeFMs)[iNodeNum].vl_kc_ul_dg = AuxParser[ActiveActor]->MakeDouble_(); + //2.402 + Init_nodeFM(iNodeNum, ActiveActor); +// Updates the value of the property for future queries +// Added y Davis 02072019 + TempStr = ""; + for(stop = iNodeNum, i = 0; i <= stop; i++) + { + TempStr = TempStr + + IntToStr(i + 1) + + "," + + (pNodeFMs)[i].vl_strBusName + + "," + + (pNodeFMs)[i].vl_strMeasuredName + + "," + + IntToStr((pNodeFMs)[i].vl_terminalNum) + + "," + + FloatToStr((pNodeFMs)[i].vl_V_ref_dg) + + "," + + FloatToStr((pNodeFMs)[iNodeNum].vl_kc_ul_dg) + + "|"; + } + ( (TDSSObject*) ActiveDSSObject[ActiveActor] )->Set_PropertyValue(16,TempStr); +} + +void TFMonitorObj::Get_PQ_DI(int i_NodeNum, int ActorID) +{ + int DevIndex = 0; + int i = 0; + int j = 0; + int Num = 0; + TDSSCktElement* PElement = nullptr; + TLoadObj* pLoad = nullptr; + pComplexArray cBuffer = nullptr; + /*# with pNodeFMs^[i_NodeNum] do */ + { + + switch((pNodeFMs)[i_NodeNum].ldType) + { + case 0:// one 3 phase or 2 phase load + { + int stop = 0; + PElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get((pNodeFMs)[i_NodeNum].ldIdx)); + Num = PElement->Get_NPhases(); + cBuffer = (pComplexArray) malloc(sizeof(complex) * Num); + PElement->GetPhasePower(cBuffer, ActorID);// power + for(stop = Num, j = 1; j <= stop; j++) + { + i = (PElement->Terminals[0].TermNodeRef)[j - 1]; + switch((ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum) + { + case 1: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[1].im; + } + break; + case 2: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[2].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[2].im; + } + break; + case 3: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[3].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[3].im; + } + break; + default: + ; + break; + } + } + } + break; + case 1: + case 2: + case 3: + { + PElement = nullptr; + if((pNodeFMs)[i_NodeNum].ldIdx1 > 0) + { + int stop = 0; + PElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get((pNodeFMs)[i_NodeNum].ldIdx1)); + Num = PElement->Get_NPhases(); + cBuffer = (pComplexArray)realloc(cBuffer, sizeof(complex) * Num); + PElement->GetPhasePower(cBuffer, ActorID);// power + for(stop = Num, j = 1; j <= stop; j++) + { + i = (PElement->Terminals[0].TermNodeRef)[j - 1]; + switch((ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum) + { + case 1: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[1].im; + } + break; + case 2: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[1].im; + } + break; + case 3: + { + (pNodeFMs)[i_NodeNum].vl_P_Di1 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di1 = (cBuffer)[1].im; + } + break; + default: + ; + break; + } + } + } + if((pNodeFMs)[i_NodeNum].ldIdx2 > 0) + { + int stop = 0; + PElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get((pNodeFMs)[i_NodeNum].ldIdx2)); + Num = PElement->Get_NPhases(); + cBuffer = (pComplexArray)realloc(cBuffer, sizeof(complex) * Num); + PElement->GetPhasePower(cBuffer, ActorID);// power + for(stop = Num, j = 1; j <= stop; j++) + { + i = PElement->Terminals[0].TermNodeRef[j - 1]; + switch((ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum) + { + case 1: + { + (pNodeFMs)[i_NodeNum].vl_P_Di2 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di2 = (cBuffer)[1].im; + } + break; + case 2: + { + (pNodeFMs)[i_NodeNum].vl_P_Di2 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di2 = (cBuffer)[1].im; + } + break; + case 3: + { + (pNodeFMs)[i_NodeNum].vl_P_Di2 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di2 = (cBuffer)[1].im; + } + break; + default: + ; + break; + } + } + } + if((pNodeFMs)[i_NodeNum].ldIdx3 > 0) + { + int stop = 0; + PElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get((pNodeFMs)[i_NodeNum].ldIdx3)); + Num = PElement->Get_NPhases(); + cBuffer = (pComplexArray)realloc(cBuffer, sizeof(complex) * Num); + PElement->GetPhasePower(cBuffer, ActorID);// power + for(stop = Num, j = 1; j <= stop; j++) + { + i = (PElement->Terminals[0].TermNodeRef)[j - 1]; + switch((ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum) + { + case 1: + { + (pNodeFMs)[i_NodeNum].vl_P_Di3 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di3 = (cBuffer)[1].im; + } + break; + case 2: + { + (pNodeFMs)[i_NodeNum].vl_P_Di3 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di3 = (cBuffer)[2].im; + } + break; + case 3: + { + (pNodeFMs)[i_NodeNum].vl_P_Di3 = (cBuffer)[1].re; + (pNodeFMs)[i_NodeNum].vl_Q_Di3 = (cBuffer)[3].im; + } + break; + default: + ; + break; + } + } + } + } + break; +// 2: +// begin +// +// end; +// 3: +// begin +// +// end + default: + ; + break; + } + } +} + +void TFMonitorObj::Init_nodeFM(int iNodeNum, int ActorID) +{ + String StrTemp; + int DevIndex = 0; + int i = 0; + int j = 0; + int PCindex_ld = 0; + TDSSCktElement* PElem = nullptr; + TGeneric5Obj* pDG = nullptr; + TLoadObj* pLd = nullptr; + //pPDElem : TPDElement; + TAdjArray lstPC; + int Num = 0; + complex ctmp = {}; + pComplexArray cBuffer = nullptr; + + //init all info of this node + /*# with pNodeFMs^[iNodeNum] do */ + { + + //1 + int stop = 0; + StrTemp = LowerCase((pNodeFMs)[iNodeNum].vl_strBusName); + (pNodeFMs)[iNodeNum].Bus_Idx = ActiveCircuit[ActorID]->BusList.Find(StrTemp); + DevIndex = GetCktElementIndex((pNodeFMs)[iNodeNum].vl_strMeasuredName); // Global function + if(DevIndex > 0) // Monitored element must already exist + { + PElem = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + } + else + { + return; + } + (pNodeFMs)[iNodeNum].vl_ndphases = PElem->Get_NPhases(); + (pNodeFMs)[iNodeNum].vl_basevolt = ActiveCircuit[ActorID]->Buses[(pNodeFMs)[iNodeNum].Bus_Idx - 1]->kVBase * 1000; + (pNodeFMs)[iNodeNum].vl_phase_num_dg = -1; //-1 -- no dg under this nodes;0 --3 phases by default + for(stop = 3, j = 1; j <= stop; j++) + { + (pNodeFMs)[iNodeNum].vl_nodeType_phase[j - 1] = 2; + }// by default not dg + /*# with ActiveCircuit[ActorID] do */ + { + + PElem = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get_First()); + PCindex_ld = ActiveCircuit[ActorID]->PCElements.get_myActiveItem(); + while(PElem != nullptr) + { + if(PElem->Get_Enabled()) + { + if(PElem->ActiveTerminal->BusRef == (pNodeFMs)[iNodeNum].Bus_Idx) + { + if(LowerCase(((TDSSObject*)PElem)->Get_myPName()).find("generic5") != String::npos) + + //vl_nodeType should be define per phase + { + (pNodeFMs)[iNodeNum].vl_ndphases_dg = PElem->Get_NPhases(); //1 or 3 + // under 1 bus, there can be either 3 phase DG or 1 phase dg + //set Cluster defination for DG + // one 3phase dg + // 1,2 or 3 1-phase dgs under each phase + pDG = ((TGeneric5Obj*) PElem); + Num = Trunc(pDG->Get_Variable(30)); //ctrl_mode + switch(Num) + { + case 1: + (pNodeFMs)[iNodeNum].vl_nodeType_phase[0] = 1; + break; + case 2: + (pNodeFMs)[iNodeNum].vl_nodeType_phase[1] = 1; + break; + case 3: + (pNodeFMs)[iNodeNum].vl_nodeType_phase[2] = 1; + break; + default: + int stop = 0; + for(stop = 3, j = 0; j < stop; j++) + { + (pNodeFMs)[iNodeNum].vl_nodeType_phase[j] = 1; + } // //ctrl_mode = 4 or 0 + break; + } + //pDG + if(pDG->FMonObj == nullptr) // first cluster + { + pDG->Set_Variable(28, (double) Cluster_num); //28: TPCElement(self).cluster_num := trunc(Value); + //if cluster_num >= 1 then // assign the virtue leader to this DG + pDG->FMonObj = this; //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); cluster_num can not be used for 'Get' + pDG->Set_Variable(29, (double) (iNodeNum + 1)); //29: TPCElement(self).NdNumInCluster := trunc(Value) ; + pDG->Set_Variable(30, 1); //TPCElement(self).nVLeaders := trunc(Value) ; + } + else + // the second virtual leader // which means if the 2nd one will always be the one being overwritten + { + // + if(Cluster_num != Round(pDG->Get_Variable(28))) + { + pDG->Set_Variable(31, (double) Cluster_num); //28: TPCElement(self).cluster_num2 := trunc(Value); + //if cluster_num >= 1 then // assign the virtue leader to this DG + pDG->FMonObj2 = this; //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); cluster_num can not be used for 'Get' + pDG->Set_Variable(32, (double) (iNodeNum + 1)); //29: TPCElement(self).NdNumInCluster2 := trunc(Value) ; + pDG->Set_Variable(30, 2); // TPCElement(self).nVLeaders := trunc(Value) ; + } + } + (pNodeFMs)[iNodeNum].vl_phase_num_dg = 0; //3 phases by default + if((pNodeFMs)[iNodeNum].vl_ndphases_dg == 1) + (pNodeFMs)[iNodeNum].vl_phase_num_dg = Trunc(pDG->Get_Variable(30)); //if vl_nodeType=1, and vl_ndphases=1,phase_num =1,2,3 0- this node has 3 phases + // 30, ctrl_mode, is the phase number of this Generic5 + } + (pNodeFMs)[iNodeNum].ldType = -1; + (pNodeFMs)[iNodeNum].ldIdx = -1; + (pNodeFMs)[iNodeNum].ldIdx1 = -1; + (pNodeFMs)[iNodeNum].ldIdx2 = -1; + (pNodeFMs)[iNodeNum].ldIdx3 = -1; + if(LowerCase(((TDSSObject*)PElem)->Get_myPName()).find("load") != String::npos) + { + Num = PElem->Get_NPhases(); + pLd = ((TLoadObj*) PElem); + //Devindex := + if(Num == 3) + { + (pNodeFMs)[iNodeNum].ldIdx = PCindex_ld; + (pNodeFMs)[iNodeNum].ldType = 0; + } + else + { + if(Num == 2) + { + (pNodeFMs)[iNodeNum].ldIdx = PCindex_ld; + (pNodeFMs)[iNodeNum].ldType = 0; + } + else + { + if(Num == 1) + { + i = (PElem->Terminals[0].TermNodeRef)[0]; + switch((ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum) + { + case 1: + (pNodeFMs)[iNodeNum].ldIdx1 = PCindex_ld; + break; + case 2: + (pNodeFMs)[iNodeNum].ldIdx2 = PCindex_ld; + break; + case 3: + (pNodeFMs)[iNodeNum].ldIdx3 = PCindex_ld; + break; + default: + ; + break; + } + if((pNodeFMs)[iNodeNum].ldType < 1) + (pNodeFMs)[iNodeNum].ldType = 1; + else + { + if((pNodeFMs)[iNodeNum].ldType >= 1) + (pNodeFMs)[iNodeNum].ldType = (pNodeFMs)[iNodeNum].ldType + 1; + } + if((pNodeFMs)[iNodeNum].ldType >= 3) + (pNodeFMs)[iNodeNum].ldType = 3; + } + } + // + +// cBuffer := Allocmem(sizeof(cBuffer^[1])*num); +// pElem.GetPhasePower(cBuffer);// power +// for j := 1 to num do +// begin +// i := pElem.Terminals^[1].TermNodeRef^[j]; +// case activecircuit.MapNodeToBus^[i].NodeNum of +// 1: begin vl_P_Di1 := cBuffer^[1].re; vl_Q_Di1 := cBuffer^[1].im; end; +// 2: begin vl_P_Di1 := cBuffer^[2].re; vl_Q_Di1 := cBuffer^[2].im; end; +// 3: begin vl_P_Di1 := cBuffer^[3].re; vl_Q_Di1 := cBuffer^[3].im; end; +// end; +// end; +// +// Reallocmem(cBuffer,0); + } + } + } + } + PElem = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get_Next()); + PCindex_ld = ActiveCircuit[ActorID]->PCElements.get_myActiveItem(); + } + } + //lstPC := ActiveCircuit.GetBusAdjacentPCLists; + //activecircuit.MapNodeToBus + //num := lstPC.NumShuntObjects; + + //2 + + + // will be overwritten if this nodeFM is a 1-phase Generic5 + ////// update cluster_num and node number of this DG in this cluster + /*if vl_nodeType=1 then // this only work for DG + begin + //set + pDG := TGeneric5Obj(pElement); + //pDG + if pDG.FMonObj = nil then // first cluster + begin + + pDG.Set_Variable(28,cluster_num); //28: TPCElement(self).cluster_num := trunc(Value); + //if cluster_num >= 1 then // assign the virtue leader to this DG + pDG.FMonObj := self; //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); cluster_num can not be used for 'Get' + pDG.Set_Variable(29,iNodeNum); //29: TPCElement(self).NdNumInCluster := trunc(Value) ; + pDG.Set_Variable(30,1); //TPCElement(self).nVLeaders := trunc(Value) ; + end else + begin // the second virtual leader // which means if the 2nd one will always be the one being overwritten + + pDG.Set_Variable(31,cluster_num); //28: TPCElement(self).cluster_num2 := trunc(Value); + //if cluster_num >= 1 then // assign the virtue leader to this DG + pDG.FMonObj2 := self; //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); cluster_num can not be used for 'Get' + pDG.Set_Variable(32,iNodeNum); //29: TPCElement(self).NdNumInCluster2 := trunc(Value) ; + pDG.Set_Variable(30,2); // TPCElement(self).nVLeaders := trunc(Value) ; + end; + if vl_ndphases_dg=1 then + vl_phase_num_dg := trunc(pDG.Get_Variable(30)); //if vl_nodeType=1, and vl_ndphases=1,phase_num =1,2,3 0- this node has 3 phases + // 30, ctrl_mode, is the phase number of this Generic5 + end; */ + /*if vl_nodeType=2 then // line and tranformer + begin + //set + //pPDelem := TPDElement(pElement); + //pDG + end; + */ + /// + (pNodeFMs)[iNodeNum].vl_V_ref1_dg = (pNodeFMs)[iNodeNum].vl_V_ref_dg;//:=1000*2.4; 1000*2.4; V_ref2:=1000*2.4; V_ref3 :=1000*2.4;// norminal value with respect to p.u. 1 //must be set by initialization + (pNodeFMs)[iNodeNum].vl_V_ref2_dg = (pNodeFMs)[iNodeNum].vl_V_ref_dg; + (pNodeFMs)[iNodeNum].vl_V_ref3_dg = (pNodeFMs)[iNodeNum].vl_V_ref_dg; + //kcq := 1.0; // the step size gain of agent i //has to be defined befor used + + /// other properties if needed + //ndphases : integer; //how many phases of this device on this node; not those of node + (pNodeFMs)[iNodeNum].vl_CC_switch_dg = false; // cooperate control switch. true, cooperate control is on + (pNodeFMs)[iNodeNum].vl_PF_flag_dg = 0;//1, real power control is on + (pNodeFMs)[iNodeNum].vl_QV_flag_dg = 0;//1, volt/var control is on + (pNodeFMs)[iNodeNum].vl_volt_thrd_dg = 0.03; + (pNodeFMs)[iNodeNum].vl_Alpha_dg = 0; + (pNodeFMs)[iNodeNum].vl_Alpha1_dg = 0; + (pNodeFMs)[iNodeNum].vl_Alpha2_dg = 0; + (pNodeFMs)[iNodeNum].vl_Alpha3_dg = 0; + (pNodeFMs)[iNodeNum].vl_Gradient_dg = 0; + (pNodeFMs)[iNodeNum].vl_Gradient1_dg = 0; + (pNodeFMs)[iNodeNum].vl_Gradient2_dg = 0; + (pNodeFMs)[iNodeNum].vl_Gradient3_dg = 0; + (pNodeFMs)[iNodeNum].vl_AlphaP_dg = 0; + (pNodeFMs)[iNodeNum].vl_Alpha_dgn = 0; + (pNodeFMs)[iNodeNum].vl_AlphaP1_dg = 0; + (pNodeFMs)[iNodeNum].vl_AlphaP2_dg = 0; + (pNodeFMs)[iNodeNum].vl_AlphaP3_dg = 0; + (pNodeFMs)[iNodeNum].vl_GradientP_dg = 0; + (pNodeFMs)[iNodeNum].vl_GradientP1_dg = 0; + (pNodeFMs)[iNodeNum].vl_GradientP2_dg = 0; + (pNodeFMs)[iNodeNum].vl_GradientP3_dg = 0; + (pNodeFMs)[iNodeNum].vl_Pmax_dg = 0; + (pNodeFMs)[iNodeNum].vl_Qmax_dg = 0; + (pNodeFMs)[iNodeNum].vl_Pmax_phase_dg = 0; + (pNodeFMs)[iNodeNum].vl_Qmax_phase_dg = 0; + (pNodeFMs)[iNodeNum].vl_V_base_dg = 1000 * 2.4; + (pNodeFMs)[iNodeNum].vl_V = 1000 * 2.4; + (pNodeFMs)[iNodeNum].vl_V1 = 1000 * 2.4; + (pNodeFMs)[iNodeNum].vl_V2 = 1000 * 2.4; + (pNodeFMs)[iNodeNum].vl_V3 = 1000 * 2.4; + (pNodeFMs)[iNodeNum].vl_Q_Di = 0.0; + (pNodeFMs)[iNodeNum].vl_Q_Di1 = 0.0; + (pNodeFMs)[iNodeNum].vl_Q_Di2 = 0.0; + (pNodeFMs)[iNodeNum].vl_Q_Di3 = 0.0; + (pNodeFMs)[iNodeNum].vl_P_Di = 0.0; + (pNodeFMs)[iNodeNum].vl_P_Di1 = 0.0; + (pNodeFMs)[iNodeNum].vl_P_Di2 = 0.0; + (pNodeFMs)[iNodeNum].vl_P_Di3 = 0.0; + (pNodeFMs)[iNodeNum].vl_SmplCnt = 0; + (pNodeFMs)[iNodeNum].vl_crnt_smp_time = 0.0; + // attack and defense + (pNodeFMs)[iNodeNum].d_atk = 0.0; + (pNodeFMs)[iNodeNum].z_dfs = 0.0; + (pNodeFMs)[iNodeNum].z_dfsn = 0.0; + (pNodeFMs)[iNodeNum].d_atk0 = 0.0; + + // init the remaining to zero + (pNodeFMs)[iNodeNum].vl_V_c = CZero; + (pNodeFMs)[iNodeNum].vl_V_1c = CZero; + (pNodeFMs)[iNodeNum].vl_V_2c = CZero; + (pNodeFMs)[iNodeNum].vl_V_3c = CZero; + (pNodeFMs)[iNodeNum].vl_q_DG = 0; + } +} + +void TFMonitorObj::Get_PDElem_terminal_voltage(int nd_num_in_cluster, String devName, int Tern_num, int ActorID) +{ + TPowerTerminal* tempTerminal = nullptr; + int i = 0; + int DevIndex = 0; + int j = 0; + TDSSCktElement* tempElement = nullptr; + //VAR + //pElem:TDSSCktElement; + int phase_num = 0; + double vabs = 0.0; + //V012 :TSymCompArray5; + complex V012[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + complex VaVbVc[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) , cmplx(0,0) }; + int stop = 0; + DevIndex = GetCktElementIndex(devName); // Global function + if(DevIndex > 0) // Monitored element must already exist + { + tempElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + } + // + tempTerminal = &(tempElement->Terminals)[Tern_num - 1]; + for(stop = tempElement->Get_NPhases(), j = 1; j <= stop; j++) + {// how many phases of this element + i = (tempTerminal->TermNodeRef)[j - 1]; // global node number + phase_num = (ActiveCircuit[ActorID]->MapNodeToBus)[i - 1].NodeNum; + if(!ADiakoptics || (ActorID == 1)) + vabs = cabs(ActiveCircuit[ActorID]->Solution->NodeV[i]); + else + vabs = cabs(ActiveCircuit[ActorID]->Solution->VoltInActor1(i)); + if(phase_num == 1) // phase A + { + (pNodeFMs)[nd_num_in_cluster].vl_V1 = vabs; + if(!ADiakoptics || (ActorID == 1)) + (pNodeFMs)[nd_num_in_cluster].vl_V_1c = ActiveCircuit[ActorID]->Solution->NodeV[i]; + else + (pNodeFMs)[nd_num_in_cluster].vl_V_1c = ActiveCircuit[ActorID]->Solution->VoltInActor1(i); + } + else + { + if(phase_num == 2) //phase B + { + (pNodeFMs)[nd_num_in_cluster].vl_V2 = vabs; + if(!ADiakoptics || (ActorID == 1)) + (pNodeFMs)[nd_num_in_cluster].vl_V_2c = ActiveCircuit[ActorID]->Solution->NodeV[i]; + else + (pNodeFMs)[nd_num_in_cluster].vl_V_2c = ActiveCircuit[ActorID]->Solution->VoltInActor1(i); + } + else + { + if(phase_num == 3) //phase c + { + (pNodeFMs)[nd_num_in_cluster].vl_V3 = vabs; + if(!ADiakoptics || (ActorID == 1)) + (pNodeFMs)[nd_num_in_cluster].vl_V_3c = ActiveCircuit[ActorID]->Solution->NodeV[i]; + else + (pNodeFMs)[nd_num_in_cluster].vl_V_3c = ActiveCircuit[ActorID]->Solution->VoltInActor1(i); + } + } + } + } + if(tempElement->Get_NPhases() == 3) + { + VaVbVc[1] = (pNodeFMs)[nd_num_in_cluster].vl_V_1c;//phase A + VaVbVc[2] = (pNodeFMs)[nd_num_in_cluster].vl_V_2c; + VaVbVc[3] = (pNodeFMs)[nd_num_in_cluster].vl_V_3c; + Phase2SymComp(&VaVbVc[1],&V012[0]); // Convert abc voltages to 012 + (pNodeFMs)[nd_num_in_cluster].vl_V = cabs(V012[1]); //pos. seq. Voltage + } +} //PD nodes + +void TFMonitorObj::update_all_nodes_info(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Nodes, i = 0; i < stop; i++) + { + /*# with pNodeFMs^[i] do */ + { + + //if vl_nodeType = 1 then // generic dg + //begin + // do nothing; because the info is updated from the other end (sent by DGs) + //end + //else if vl_nodeType = 2 then // PD elements: lines, xformers, etc.. + //begin + //Update_PD_Node_Info(i,vl_strMeasuredName,vl_terminalNum); + Get_PDElem_terminal_voltage(i, (pNodeFMs)[i].vl_strMeasuredName, (pNodeFMs)[i].vl_terminalNum, ActorID); + //Calc_Alpha_for_PDNode(i ); // calc all alpha, alpha1, alpha2, alph3 of all pdelement nodes + //end; + } + } +} +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::ResetDelaySteps(int iNodeNum) +{ + int j = 0; + int Tmp = 0; + //calc delay array + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if((T_intvl_smpl == 0.0) || ((pCommDelayMatrix)[iNodeNum * Nodes + j] == 0.0)) + (pCommDelaySteps)[iNodeNum * Nodes + j] = 0; + else + { + Tmp = Trunc((pCommDelayMatrix)[iNodeNum * Nodes + j] / T_intvl_smpl); + if(Frac((pCommDelayMatrix)[iNodeNum * Nodes + j] / T_intvl_smpl) == 0.0L) + (pCommDelaySteps)[iNodeNum * Nodes + j] = (short int) Tmp; + else + (pCommDelaySteps)[iNodeNum * Nodes + j] = (short int) (Tmp + 1); + //How many delays for communication + } + } +} + +void TFMonitorObj::ResetIt(int ActorID) +{ + int iTmp = 0; + BufPtr = 0; + //ClearMonitorStream; + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + //calc Delay_stps for sampling + { + int stop = 0; + if(T_intvl_smpl == 0.0) //No delay. + Smpl_stps = 0; + else + { + iTmp = Trunc(T_intvl_smpl / ActiveCircuit[ActorID]->Solution->DynaVars.h); + if(Frac(T_intvl_smpl / ActiveCircuit[ActorID]->Solution->DynaVars.h) == 0.0L) + Smpl_stps = iTmp; + else + Smpl_stps = iTmp + 1;// uper + } + for(stop = Nodes, iTmp = 0; iTmp < stop; iTmp++) + { + (pNodeFMs)[iTmp].vl_SmplCnt = 0; + (pNodeFMs)[iTmp].vl_crnt_smp_time = ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600 + ActiveCircuit[ActorID]->Solution->DynaVars.T; + Init_delay_array(iTmp, ActorID); // in DYNAMICMODE, init alpha array + } + } +} + +/*--------------------------------------------------------------------------*/ +/* +Procedure TFMonitorObj.PostProcess; +Begin + if IsProcessed = FALSE then begin + if (mode = 4) and (MonitorStream.Position > 0) then DoFlickerCalculations; + end; + IsProcessed := TRUE; +End; + +{--------------------------------------------------------------------------*/ +/* +Procedure TFMonitorObj.GetFvalue; +VAR + dHour :Double; + dSum :Double; + i,j :Integer; + IsPower :Boolean; + IsSequence :Boolean; + NumVI :Integer; + Offset :Integer; + ResidualCurr :Complex; + ResidualVolt :Complex; + Sum :Complex; + V012,I012 :Array[1..3] of Complex; + + Monitor : TFMonitorObj; + + +Begin + + If Not (ValidMonitor and Enabled) Then Exit; + + //inc(SampleCount); + + Hour := ActiveCircuit.Solution.DynaVars.intHour; + Sec := ActiveCircuit.Solution.Dynavars.t; + + Offset := (MeteredTerminal-1) * MeteredElement.NConds; + + //Save time unless Harmonics mode and then save Frequency and Harmonic + WITH ActiveCircuit.Solution Do + IF IsHarmonicModel Then Begin + AddDblsToBuffer(@Frequency, 1); // put freq in hour slot as a double + AddDblsToBuffer(@Harmonic ,1); // stick harmonic in time slot in buffer + End + ELSE Begin + dHour := Hour; // convert to double + AddDblsToBuffer(@dHour, 1); // put hours in buffer as a double + AddDblsToBuffer(@Sec, 1); // stick time in sec in buffer + End; + + CASE (Mode AND MODEMASK) of + + 0,1: // Voltage, current. Powers + Begin + + // MeteredElement.GetCurrents(CurrentBuffer); + // To save some time, call ComputeITerminal + MeteredElement.ComputeIterminal; // only does calc if needed + For i := 1 to MeteredElement.Yorder Do CurrentBuffer^[i] := MeteredElement.Iterminal^[i]; + + TRY + + Bus_code := Activeterminal.BusRef; + Monitor := ActiveCircuit.FMonitors.Active; + //Detect non-existed phase====================================================== + for j := 1 to 3 do + begin + NodeNum := ActiveCircuit.Buses^[Bus_code].Find(j); + if NodeNum=0 then + begin + F_Value_one_V^[j] := 9999; + end + else + begin + + for i := 1 to Fnphases do + begin + Node_Ref := Monitor.ActiveTerminal.TermNodeRef^[i]; + if Node_Ref=NodeNum then F_Value_one_V^[j] := cabs(ActiveCircuit.Solution.NodeV^[NodeRef^[i]])/ActiveCircuit.Solution.NodeVbase^[NodeRef^[i]]; + end; + + end; + end; + + FOR i := 1 to Fnconds DO + Begin + // It is the index of the terminal into the system node list + //Meteredelement. + f_value_one := cabs(ActiveCircuit.Solution.NodeV^[NodeRef^[1]]); //A value of voltage on first phase + f_value_one := f_value_one/ActiveCircuit.Solution.NodeVbase^[NodeRef^[i]] ; + VoltageBuffer^[i] := ActiveCircuit.Solution.NodeV^[NodeRef^[i]]; + End; + EXCEPT + On E:Exception Do DoSimpleMsg(E.Message + CRLF + 'NodeRef is invalid. Try solving a snapshot or direct before solving in a mode that takes a monitor sample.', 672); + END; + End; + + 2: Begin // Monitor Transformer Tap Position + + With TTransfObj(MeteredElement) Do Begin + //AddDblToBuffer(PresentTap[MeteredTerminal]); + End; + Exit; // Done with this mode now. + End; + + 3: Begin // Pick up device state variables + TPCElement(MeteredElement).GetAllVariables(StateBuffer); + AddDblsToBuffer(StateBuffer, NumStateVars); + Exit; // Done with this mode now + End; + + 4: Begin // RMS phase voltages for flicker evaluation + TRY + FOR i := 1 to Fnphases DO Begin + FlickerBuffer^[i] := ActiveCircuit.Solution.NodeV^[NodeRef^[i]]; + End; + EXCEPT + On E:Exception Do DoSimpleMsg(E.Message + CRLF + 'NodeRef is invalid. Try solving a snapshot or direct before solving in a mode that takes a monitor sample.', 672); + END; + End; + + 5: Begin + (* Capture Solution Variables *) + With ActiveCircuit.Solution Do Begin + SolutionBuffer^[1] := Iteration; + SolutionBuffer^[2] := ControlIteration; + SolutionBuffer^[3] := MaxIterations; + SolutionBuffer^[4] := MaxControlIterations; + If ConvergedFlag then SolutionBuffer^[5] := 1 else SolutionBuffer^[5] := 0; + SolutionBuffer^[6] := IntervalHrs; + SolutionBuffer^[7] := SolutionCount; + SolutionBuffer^[8] := Mode; + SolutionBuffer^[9] := Frequency; + SolutionBuffer^[10] := Year; + SolutionBuffer^[11] := Time_Solve; + SolutionBuffer^[12] := Time_Step; + End; + + End; + + 6: Begin // Monitor Transformer Tap Position + + With TCapacitorObj(MeteredElement) Do Begin + for i := 1 to NumSteps do + begin + //AddDblToBuffer(States[i]); + end; + End; + Exit; // Done with this mode now. + End; + // + Else Exit // Ignore invalid mask + + End; + + + IF ((Mode AND SEQUENCEMASK)>0) And (Fnphases=3) + THEN Begin // Convert to Symmetrical components + Phase2SymComp(VoltageBuffer, @V012); + Phase2SymComp(@CurrentBuffer^[Offset + 1], @I012); + NumVI := 3; + IsSequence := TRUE; + // Replace voltage and current buffer with sequence quantities + FOR i := 1 to 3 DO VoltageBuffer^[i] := V012[i]; + FOR i := 1 to 3 DO CurrentBuffer[Offset + i] := I012[i]; + End + ELSE Begin + NumVI :=Fnconds; + IsSequence := FALSE; + End; + + IsPower := False; // Init so compiler won't complain + CASE (Mode AND MODEMASK) of + 0: Begin // Convert to Mag, Angle // and compute residual if required + IsPower := FALSE; + IF IncludeResidual THEN Begin + If VIPolar Then Begin + ResidualVolt := ResidualPolar(@VoltageBuffer^[1], Fnphases); + ResidualCurr := ResidualPolar(@CurrentBuffer^[Offset+1], Fnphases); + End Else Begin + ResidualVolt := Residual(@VoltageBuffer^[1], Fnphases); + ResidualCurr := Residual(@CurrentBuffer^[Offset+1], Fnphases); + End; + End; + If VIPolar Then Begin + ConvertComplexArrayToPolar(VoltageBuffer, NumVI); + ConvertComplexArrayToPolar(@CurrentBuffer^[Offset+1], NumVI ); // Corrected 3-11-13 + + ConvertComplexArrayToPolar(F_Value_one_S, NumVI); + + End; + + + //Calulate power in mode 0 + CalckPowers(F_Value_one_S, VoltageBuffer, @CurrentBuffer^[Offset+1], NumVI); + IF (IsSequence OR ActiveCircuit.PositiveSequence) THEN CmulArray(F_Value_one_S, 3.0, NumVI); // convert to total power + Fvalue_P :=0 ; + Fvalue_Q :=0 ; + FOR i := 1 to NumVI DO + begin + Fvalue_P := Fvalue_P + F_Value_one_S^[i].re; + Fvalue_Q := Fvalue_Q + F_Value_one_S^[i].im; + end; + + + End; + 1: Begin // Convert Voltage Buffer to power kW, kvar or Mag/Angle + CalckPowers(VoltageBuffer, VoltageBuffer, @CurrentBuffer^[Offset+1], NumVI); + IF (IsSequence OR ActiveCircuit.PositiveSequence) THEN CmulArray(VoltageBuffer, 3.0, NumVI); // convert to total power + f_p_one :=0 ; + f_q_one :=0 ; + FOR i := 1 to NumVI DO + begin + f_p_one := f_p_one + VoltageBuffer^[i].re; + f_q_one := f_q_one + VoltageBuffer^[i].im; + end; + + If Ppolar Then ConvertComplexArrayToPolar(VoltageBuffer, NumVI); + IsPower := TRUE; + End; + 4: Begin + IsPower := FALSE; + ConvertComplexArrayToPolar(FlickerBuffer, Fnphases); + End + Else + End; + + +End; + */ +/**/ +/*--------------------------------------------------------------------------*/ + +/*--------------------------------------------------------------------------*/ +/* +Procedure TFMonitorObj.AddDblsToBuffer( Dbl:pDoubleArray; Ndoubles:Integer); + +VAR + i:Integer; + +Begin + //FOR i := 1 to Ndoubles DO AddDblToBuffer(Dbl^[i]); +End; +*/ + +/*--------------------------------------------------------------------------*/ +/* +Procedure TFMonitorObj.AddDblToBuffer(const Dbl:Double); + +Begin + // first check to see if there's enough room + // if not, save to monitorstream first. + IF BufPtr=BufferSize THEN Save; + Inc(BufPtr); + MonBuffer^[BufPtr]:=Dbl; +End; +*/ +/* +Procedure TFMonitorObj.DoFlickerCalculations; +var + FSignature :Integer; + Fversion :Integer; + RecordSize :Cardinal; + RecordBytes :Cardinal; + SngBuffer :Array[1..100] of Single; + hr :single; + s :single; + N :Integer; + Npst :Integer; + i, p :Integer; + bStart :Integer; + data :Array of pSingleArray; // indexed from zero (time) to FnPhases + pst :Array of pSingleArray; // indexed from zero to FnPhases - 1 + ipst :integer; + tpst :single; + defaultpst :single; + Vbase :single; + busref :integer; +begin + N := SampleCount; + With MonitorStream Do Begin + Seek(0, soFromBeginning); // Start at the beginning of the Stream + Read( Fsignature, Sizeof(Fsignature)); + Read( Fversion, Sizeof(Fversion)); + Read( RecordSize, Sizeof(RecordSize)); + Read( Mode, Sizeof(Mode)); + Read( StrBuffer, Sizeof(StrBuffer)); + bStart := Position; + End; + RecordBytes := Sizeof(SngBuffer[1]) * RecordSize; + Try + // read rms voltages out of the monitor stream into arrays + SetLength (data, Fnphases + 1); + SetLength (pst, Fnphases); + for p := 0 to FnPhases do data[p] := AllocMem (Sizeof(SngBuffer[1]) * N); + i := 1; + while Not (MonitorStream.Position>=MonitorStream.Size) do Begin + With MonitorStream Do Begin + Read( hr, SizeOf(hr)); + Read( s, SizeOf(s)); + Read(SngBuffer, RecordBytes); + data[0][i] := s + 3600.0 * hr; + for p := 1 to FnPhases do data[p][i] := SngBuffer[2*p]; + i := i + 1; + End; + End; + + // calculate the flicker level and pst + Npst := 1 + Trunc (data[0][N] / 600.0); // pst updates every 10 minutes or 600 seconds + for p := 0 to FnPhases-1 do begin + pst[p] := AllocMem (Sizeof(SngBuffer[1]) * Npst); + busref := MeteredElement.Terminals[MeteredTerminal].BusRef; + Vbase := 1000.0 * ActiveCircuit.Buses^[busref].kVBase; + FlickerMeter (N, BaseFrequency, Vbase, data[0], data[p+1], pst[p]); + end; + + // stuff the flicker level and pst back into the monitor stream + with MonitorStream do begin + Position := bStart; + tpst:=0.0; + ipst:=0; + defaultpst:=0; + for i := 1 to N do begin + if (data[0][i] - tpst) >= 600.0 then begin + inc(ipst); + tpst:=data[0][i]; + end; + Position:=Position + 2 * SizeOf(hr); // don't alter the time + for p := 1 to FnPhases do begin + Write (data[p][i], sizeof(data[p][i])); + if (ipst > 0) and (ipst <= Npst) then + Write (pst[p-1][ipst], sizeof(pst[p-1][ipst])) + else + Write (defaultpst, sizeof(defaultpst)) + end; + end; + end; + Finally + for p := 0 to FnPhases do ReAllocMem (data[p], 0); + for p := 0 to FnPhases-1 do ReAllocMem (pst[p], 0); + end; +end; +*/ +/*--------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ //Get present value of terminal Curr for reports + +void TFMonitorObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + +/* + Revised 12-7-99 to return Zero current instead of Monitored element current because + it was messing up Newton iteration. +*/ + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +void TFMonitorObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ + +void TFMonitorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int k = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "// BufferSize="); WriteLn(f, BufferSize, 0); } + { Write(f, "// Hour="); WriteLn(f, Hour, 0); } + { Write(f, "// Sec="); WriteLn(f, Sec, 0); } + { Write(f, "// BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + { Write(f, "// Bufptr="); WriteLn(f, BufPtr, 0); } + WriteLn(f, "// Buffer="); + k = 0; + for(stop = BufPtr, i = 1; i <= stop; i++) + { + { Write(f, (MonBuffer)[i], 0, 1); Write(f, ", "); } + ++k; + if(k == (2 + Fnconds * 4)) + { + WriteLn(f); + k = 0; + } + } + WriteLn(f); + } +} + +void TFMonitorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,"0"); //'mode'; + Set_PropertyValue(4,""); // 'action'; // buffer=clear|save|take|process + Set_PropertyValue(5,"NO"); + Set_PropertyValue(6,"YES"); + Set_PropertyValue(7,"YES"); + /**/ + Set_PropertyValue(8,"0");//ref power + Set_PropertyValue(9,"0");// default voltage sensor value + Set_PropertyValue(10,"0");// default power sensor value + Set_PropertyValue(11,"1");// default node number value + Set_PropertyValue(12,"1");// default by group 1 + Set_PropertyValue(13,"1");// default number of groups + /**/ + TDSSCktElement::InitPropertyValues(NumPropsThisClass); +} + + +/*--------------------------------------------------------------------------*/ + + +/*----------------------------------------------------------------------*/ + +// + +//must be called after self gradient calc +// self gradient calc is in 'Update _pd_node_info' + +void TFMonitorObj::Calc_Alpha_for_PDNode(int NodeNum) +{ + int j = 0; + int phase_num = 0; + double sum_Sij_j = 0.0; + double TempAlpha = 0.0; + //if phase_num=0 then + // result := 0.0 //alpha + //else if phase_num=1 then + // result:= 0.0 //alpha1 + // else if phase_num=2 then + // result := 0.0 //alpha2 + // else if phase_num=3 then + // result := 0.0; //alpha3 + //update nodes information before calculating alpha_i + //update_all_nodes_info; + + // calclate alpha + /*# with pNodeFMs^[NodeNum] do */ + { + + int stop = 0; + for(stop = (pNodeFMs)[NodeNum].vl_ndphases_dg, phase_num = 1; phase_num <= stop; phase_num++) + { + switch(phase_num) + { + case 1: //phase A + { + int stop1 = 0; + TempAlpha = 0.0;//init as zero + sum_Sij_j = 0.0; + for(stop1 = Nodes, j = 0; j < stop1; j++) + { + //for j := 1 to NodeNumofDG-1 do + + //if pnodeFMs^[j].vl_phase_num=phase_num then + //begin + TempAlpha = TempAlpha + (pCommMatrix)[NodeNum * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNum * Nodes + j]; + //end; + } + //for j := NodeNumofDG + 1 to Nodes do + //begin + // Alpha1 := Alpha1 + pcommmatrix^[(NodeNumofDG-1)*nodes +j]*pnodeFMs^[j].Alpha1 ; + // sum_Sij_j := sum_Sij_j + pcommmatrix^[(NodeNumofDG-1)*nodes +j]; + //end; + (pNodeFMs)[NodeNum].vl_Alpha1_dg = TempAlpha / sum_Sij_j; + (pNodeFMs)[NodeNum].vl_Alpha1_dg = (pNodeFMs)[NodeNum].vl_Alpha1_dg - (pNodeFMs)[NodeNum].vl_kcq_dg * (pNodeFMs)[NodeNum].vl_Gradient1_dg; + //result := Alpha1; + } + break; //phase B + case 2: + { + int stop1 = 0; + TempAlpha = 0.0;//init as zero + sum_Sij_j = 0.0; + for(stop1 = Nodes, j = 0; j < stop1; j++) + { + //for j := 1 to NodeNumofDG-1 do + TempAlpha = TempAlpha + (pCommMatrix)[NodeNum * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNum * Nodes + j]; + } + //for j := NodeNumofDG + 1 to Nodes do + //begin + // Alpha2 := Alpha2 + pcommmatrix^[(NodeNumofDG-1)*nodes +j]*pnodeFMs^[j].Alpha2 ; + // sum_Sij_j := sum_Sij_j + pcommmatrix^[(NodeNumofDG-1)*nodes +j]; + //end; + (pNodeFMs)[NodeNum].vl_Alpha2_dg = TempAlpha / sum_Sij_j; + (pNodeFMs)[NodeNum].vl_Alpha2_dg = (pNodeFMs)[NodeNum].vl_Alpha2_dg - (pNodeFMs)[NodeNum].vl_kcq_dg * (pNodeFMs)[NodeNum].vl_Gradient2_dg; + //result := Alpha2; + } + break; //phase C + case 3: + { + int stop1 = 0; + TempAlpha = 0.0;//init as zero + sum_Sij_j = 0.0; + for(stop1 = Nodes, j = 0; j < stop1; j++) + { + //for j := 1 to NodeNumofDG-1 do + TempAlpha = TempAlpha + (pCommMatrix)[NodeNum * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNum * Nodes + j]; + } + //for j := NodeNumofDG + 1 to Nodes do + //begin + // Alpha3 := Alpha3 + pcommmatrix^[(NodeNumofDG-1)*nodes +j]*pnodeFMs^[j].Alpha3 ; + // sum_Sij_j := sum_Sij_j + pcommmatrix^[(NodeNumofDG-1)*nodes +j]; + //end; + (pNodeFMs)[NodeNum].vl_Alpha3_dg = TempAlpha / sum_Sij_j; + (pNodeFMs)[NodeNum].vl_Alpha3_dg = (pNodeFMs)[NodeNum].vl_Alpha3_dg - (pNodeFMs)[NodeNum].vl_kcq_dg * (pNodeFMs)[NodeNum].vl_Gradient3_dg; + //result := Alpha3; + } + break; //pos seq value + case 0: + { + int stop1 = 0; + TempAlpha = 0.0;//init as zero + sum_Sij_j = 0.0; + for(stop1 = Nodes, j = 0; j < stop1; j++) + { + //for j := 1 to NodeNumofDG-1 do + TempAlpha = TempAlpha + (pCommMatrix)[NodeNum * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNum * Nodes + j]; + } + //for j := NodeNumofDG + 1 to Nodes do + //begin + // Alpha := Alpha + pcommmatrix^[(NodeNumofDG-1)*nodes +j]*pnodeFMs^[j].Alpha ; + // sum_Sij_j := sum_Sij_j + pcommmatrix^[(NodeNumofDG-1)*nodes +j]; + //end; + (pNodeFMs)[NodeNum].vl_Alpha_dg = TempAlpha / sum_Sij_j; + (pNodeFMs)[NodeNum].vl_Alpha_dg = (pNodeFMs)[NodeNum].vl_Alpha_dg - (pNodeFMs)[NodeNum].vl_kcq_dg * (pNodeFMs)[NodeNum].vl_Gradient_dg; + //result := Alpha; + } + break; + default: + ; + break; + } + } + } +} +/*------------------------*/ +////////////////////////// + +int TFMonitorObj::Get_P_mode(int ActorID) +{ + int result = 0; + result = p_mode; + return result; +} +// AlphaP Gradient or Pref + // NodeNuminClstr: node number in cluster + +double TFMonitorObj::Get_power_trans(int ActorID) +{ + double result = 0.0; + int i = 0; + int j = 0; + int k = 0; + TPowerTerminal* pTerminal = nullptr; + pComplexArray Curr = nullptr; + //tempCplx := MeteredElement.power[MeteredTerminal]; + int stop = 0; + ((TPDElement*) MeteredElement)->GetCurrents(&(MeteredElement->Iterminal[0]), ActorID); //Curr + pTerminal = &((MeteredElement->Terminals)[MeteredTerminal - 1]); + tempCplx = CZero; + k = (MeteredTerminal - 1) * MeteredElement->Get_NConds(); + for(stop = MeteredElement->Get_NConds(), j = 1; j <= stop; j++) + {// how many conds of this element + i = (pTerminal->TermNodeRef)[j - 1]; // global node number + if(!ADiakoptics || (ActorID == 1))//power + caccum(tempCplx, cmul(ActiveCircuit[ActorID]->Solution->NodeV[i], conjg((MeteredElement->Iterminal)[k + j - 1]))); + else + caccum(tempCplx, cmul(ActiveCircuit[ActorID]->Solution->VoltInActor1(i), conjg((MeteredElement->Iterminal)[k + j - 1]))); + } + result = tempCplx.re; + return result; +} +//calculate the gradient for alpha i + +double TFMonitorObj::Calc_Grdt_for_Alpha(int NodeNuminClstr, int phase_num, int ActorID) +{ + double result = 0.0; + complex vtemp = {}; + complex ctmp = {}; + double Tmp = 0.0; + double Gij = 0.0; + double Bij = 0.0; + double Gii = 0.0; + double Bii = 0.0; + int DevIndex = 0; + int i = 0; + int j = 0; + int k = 0; + int jTempTerminal = 0; + TDSSCktElement* PElem = nullptr; + int nodeRefi = 0;// ref number of this node + int nodeRefj = 0;// ref number of the upper node + double Den = 0.0; + //pNodeFMs^[NodeNuminClstr].vl_strMeasuredName;//element followed by this bus + int stop = 0; + DevIndex = GetCktElementIndex((pNodeFMs)[NodeNuminClstr].vl_strMeasuredName); + if(DevIndex > 0) // Monitored element must already exist + { + PElem = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + } + if(PElem != nullptr) //want to get voltages from the other side of the device + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = PElem->Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (PElem->Vterminal)[i - 1] = with0->NodeV[(PElem->NodeRef)[i - 1]]; + else + (PElem->Vterminal)[i - 1] = with0->VoltInActor1((PElem->NodeRef)[i - 1]); + } + } + } + else + result = 0.0; + //k is the terminal number of this end + k = (pNodeFMs)[NodeNuminClstr].vl_terminalNum; + //this is the other end jTempTerminal + if(k == 1) + jTempTerminal = 2; + else + jTempTerminal = 1; + //k := (iTempTerminal -1)*MeteredElement.NConds; + // + //find the voltage of this phase on this terminal + for(stop = PElem->Get_NPhases(), i = 1; i <= stop; i++) + {// how many conds of this element + j = ((PElem->Terminals)[jTempTerminal - 1].TermNodeRef)[i - 1]; + if((ActiveCircuit[ActorID]->MapNodeToBus)[j - 1].NodeNum == phase_num) + { + nodeRefj = j; // node ref of the other end of this element and this phase + if(!ADiakoptics || (ActorID == 1)) + vtemp = ActiveCircuit[ActorID]->Solution->NodeV[nodeRefj]; + else + vtemp = ActiveCircuit[ActorID]->Solution->VoltInActor1(nodeRefj); + nodeRefi = ((PElem->Terminals)[k - 1].TermNodeRef)[i - 1]; // node ref of this node + } + } // cannot deal with pos seq + if(phase_num == 0) + ; + ctmp = ActiveCircuit[ActorID]->Solution->Get_Yij(nodeRefi, nodeRefj); + Gij = ctmp.re; + Bij = ctmp.im; + ctmp = ActiveCircuit[ActorID]->Solution->Get_Yij(nodeRefi, nodeRefi); + //ctmp := activecircuit.Solution.NodeYii^[nodeRefi]; + Gii = ctmp.re; + Bii = ctmp.im; + /*# with pNodeFMs^[NodeNuminClstr] do */ + { + + switch(phase_num) + { + case 0: //pos seq + { + result = (pNodeFMs)[NodeNuminClstr].vl_Gradient_dg; // can not deal with that + } + break; + /*den := vl_Q_DG1 - vl_Q_Di1- vl_V1*vl_V1* Bii; // pos ctrl: Bii use the first one + tmp := vl_V1-cabs(vTemp); + + vl_gradient1_dg := vl_V1 * tmp; + + if abs(den) 0) // Monitored element must already exist + { + PElem = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + } + if(PElem != nullptr) //want to get voltages from the other side of the device + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = PElem->Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (PElem->Vterminal)[i - 1] = with0->NodeV[(PElem->NodeRef)[i - 1]]; + else + (PElem->Vterminal)[i - 1] = with0->VoltInActor1((PElem->NodeRef)[i - 1]); + } + } + } + else + result = 0.0; + //k is the terminal number of this end + k = (pNodeFMs)[NodeNuminClstr].vl_terminalNum; + //this is the other end jTempTerminal + if(k == 1) + jTempTerminal = 2; + else + jTempTerminal = 1; + //k := (iTempTerminal -1)*MeteredElement.NConds; + // + //find the voltage of this phase on this terminal + for(stop = PElem->Get_NPhases(), i = 1; i <= stop; i++) + {// how many conds of this element + j = ((PElem->Terminals)[jTempTerminal - 1].TermNodeRef)[i - 1]; + if((ActiveCircuit[ActorID]->MapNodeToBus)[j - 1].NodeNum == phase_num) + { + nodeRefj = j; // node ref of the other end of this element and this phase + if(!ADiakoptics || (ActorID == 1)) + vtemp = ActiveCircuit[ActorID]->Solution->NodeV[nodeRefj]; + else + vtemp = ActiveCircuit[ActorID]->Solution->VoltInActor1(nodeRefj); + nodeRefi = ((PElem->Terminals)[k - 1].TermNodeRef)[i - 1]; // node ref of this node + } + } // cannot deal with pos seq + if(phase_num == 0) + ; + ctmp = ActiveCircuit[ActorID]->Solution->Get_Yij(nodeRefi, nodeRefj); + Gij = ctmp.re; + Bij = ctmp.im; + ctmp = ActiveCircuit[ActorID]->Solution->Get_Yij(nodeRefi, nodeRefi); + //ctmp := activecircuit.Solution.NodeYii^[nodeRefi]; + Gii = ctmp.re; + Bii = ctmp.im; + /*# with pNodeFMs^[NodeNuminClstr] do */ + { + + switch(phase_num) + { + case 0: //pos seq + { + result = (pNodeFMs)[NodeNuminClstr].vl_Gradient_dg; // can not deal with that + } + break; + case 1: + { + Den = (pNodeFMs)[NodeNuminClstr].vl_q_DG1 - (pNodeFMs)[NodeNuminClstr].vl_Q_Di1 - (pNodeFMs)[NodeNuminClstr].vl_V1 * (pNodeFMs)[NodeNuminClstr].vl_V1 * Bii; // pos ctrl: Bii use the first one + Tmp = (pNodeFMs)[NodeNuminClstr].vl_V1 - cabs(vtemp); + (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg = (pNodeFMs)[NodeNuminClstr].vl_V1 * Tmp; + if(Abs((int) Den) < EPSILON) + (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg = 0.0; + else + (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg / (Den); + Tmp = (pNodeFMs)[NodeNuminClstr].vl_Qmax_phase_dg * Gij; + (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg * Tmp; + (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg / ((pNodeFMs)[NodeNuminClstr].vl_V_ref1_dg * (pNodeFMs)[NodeNuminClstr].vl_V_ref1_dg);//PU value?? + ////////////////////////////////////////////////////////// + //vl_gradient_dg := (vl_V_ref_dg-vl_v)*vl_V/(den)/(vl_V_ref_dg*vl_V_ref_dg); //*vl_Qmax, 0311-by dahei + // vl_gradient_dg := (beta*vl_V_ref_dg*vl_V_ref_dg* abs(Bii)*100/j)*vl_gradient_dg; + //////////////////////////////////////////////////////////////////////////////////// + result = (pNodeFMs)[NodeNuminClstr].vl_Gradient1_dg; // + } + break; + case 2: + { + Den = (pNodeFMs)[NodeNuminClstr].vl_q_DG2 - (pNodeFMs)[NodeNuminClstr].vl_Q_Di2 - (pNodeFMs)[NodeNuminClstr].vl_V2 * (pNodeFMs)[NodeNuminClstr].vl_V2 * Bii; // pos ctrl: Bii use the first one + Tmp = (pNodeFMs)[NodeNuminClstr].vl_V2 - cabs(vtemp); + (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg = (pNodeFMs)[NodeNuminClstr].vl_V2 * Tmp; + if(Abs((int) Den) < EPSILON) + (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg = 0.0; + else + (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg / (Den); + Tmp = (pNodeFMs)[NodeNuminClstr].vl_Qmax_phase_dg * Gij; + (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg * Tmp; + (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient2_dg / ((pNodeFMs)[NodeNuminClstr].vl_V_ref2_dg * (pNodeFMs)[NodeNuminClstr].vl_V_ref2_dg);//PU value?? + } + break; + case 3: + { + Den = (pNodeFMs)[NodeNuminClstr].vl_q_DG3 - (pNodeFMs)[NodeNuminClstr].vl_Q_Di3 - (pNodeFMs)[NodeNuminClstr].vl_V3 * (pNodeFMs)[NodeNuminClstr].vl_V3 * Bii; // pos ctrl: Bii use the first one + Tmp = (pNodeFMs)[NodeNuminClstr].vl_V3 - cabs(vtemp); + (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg = (pNodeFMs)[NodeNuminClstr].vl_V3 * Tmp; + if(Abs((int) Den) < EPSILON) + (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg = 0.0; + else + (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg / (Den); + Tmp = (pNodeFMs)[NodeNuminClstr].vl_Qmax_phase_dg * Gij; + (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg * Tmp; + (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg = (pNodeFMs)[NodeNuminClstr].vl_Gradient3_dg / ((pNodeFMs)[NodeNuminClstr].vl_V_ref3_dg * (pNodeFMs)[NodeNuminClstr].vl_V_ref3_dg);//PU value?? + } + break; + default: + ; + break; + } + } + //result := tempCplx.re ; + return result; +} // NodeNuminClstr: node number in cluster + +double TFMonitorObj::Calc_GP_AlphaP(int phase_num, int ActorID) +{ + double result = 0.0; + double PGtemp = 0.0; + double PTemp = 0.0; + //tempCplx + PTemp = Get_power_trans(ActorID); // get power on trans point + //tempCplx := cnegate(tempCplx);// + //if pNodeFMs^[NodeNuminClstr].vl_V_ref_dg<>0 then + // PGtemp := -(p_trans_ref - ptemp )/Activecircuit.solution.t;//pNodeFMs^[NodeNuminClstr].vl_V_ref_dg // pu value? + //else + //if pNodeFMs^[NodeNuminClstr].vl_Pmax_dg<>0.0 then + //PGtemp := -(p_trans_ref - ptemp )//-(p_trans_ref - ptemp )/pNodeFMs^[NodeNuminClstr].vl_Pmax_dg // should use the total load + //else PGtemp := 0.0 ; + if(eg_defed == true) // D_fm is damping plus droop + PGtemp = -(P_trans_ref - PTemp) / (kVA_fm * 1000) * k_dltP; + else + PGtemp = -(P_trans_ref - PTemp) / 1000 * k_dltP; // kVA_fm = 1 kVA + switch(phase_num) + { + case 0: //pos seq + { + result = PGtemp; // + } + break; + case 1: + { + result = PGtemp; // + } + break; + case 2: + { + result = PGtemp; // + } + break; + case 3: + { + result = PGtemp; // + } + break; + default: + ; + break; + } + return result; +} +////////////////////////// +/*-------------------------*/ // NodeNuminClstr: node number in cluster + +double TFMonitorObj::Calc_AlphaP(int NodeNuminClstr, int phase_num, int ActorID) +{ + double result = 0.0; + int nn = 0; + int j = 0; + double den_dij = 0.0; + double TempAlpha = 0.0; + //alphaP = avg (alphaP) + Beta * Gp + nn = NodeNuminClstr; + switch(phase_num) + { + case 0: //pos seq + + //1.calculate d_ij*alpha_j summation + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if((pNodeFMs)[j].vl_ndphases_dg == 3) //only 3 phase nodes + { + den_dij = den_dij + (pCommMatrix)[nn * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[nn * Nodes + j] * (pNodeFMs)[j].vl_AlphaP_dg; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + } + (pNodeFMs)[nn].vl_Gradient_dg = this->Calc_GP_AlphaP(phase_num, ActorID); + (pNodeFMs)[nn].vl_AlphaP_dg = TempAlpha + (pNodeFMs)[nn].vl_kcd_dg * (pNodeFMs)[nn].vl_Gradient_dg / ActiveCircuit[ActorID]->Solution->Iteration; + + //disturbance + (pNodeFMs)[nn].vl_AlphaP_dg = (pNodeFMs)[nn].vl_AlphaP_dg; + if((pNodeFMs)[nn].vl_AlphaP_dg > 1) + (pNodeFMs)[nn].vl_AlphaP_dg = 1; + if((pNodeFMs)[nn].vl_AlphaP_dg < 0) + (pNodeFMs)[nn].vl_AlphaP_dg = 0; + result = (pNodeFMs)[NodeNuminClstr].vl_AlphaP_dg; + } + break; + default: + ; + break; + } + /*# with pNodeFMs^[nn] do */ + { + + switch(phase_num) + { + case 1: //pos seq + + //1.calculate d_ij*alpha_j summation + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_phase_num_dg == phase_num)) //only count dgs with 3 phases or 1 phase that is same number + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP1_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + } + (pNodeFMs)[nn].vl_GradientP1_dg = Calc_GP_AlphaP(phase_num, ActorID); + (pNodeFMs)[nn].vl_AlphaP1_dg = TempAlpha + (pNodeFMs)[nn].vl_kcd_dg * (pNodeFMs)[nn].vl_GradientP1_dg / ActiveCircuit[ActorID]->Solution->Iteration; + if((pNodeFMs)[nn].vl_AlphaP1_dg > 1) + (pNodeFMs)[nn].vl_AlphaP1_dg = 1; + if((pNodeFMs)[nn].vl_AlphaP1_dg < - 1) + (pNodeFMs)[nn].vl_AlphaP1_dg = (double) -1; + result = (pNodeFMs)[nn].vl_AlphaP1_dg; + } + break; + //1.calculate d_ij*alpha_j summation + case 2: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_phase_num_dg == phase_num)) //only count dgs with 3 phases or 1 phase that is same number + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP2_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + } + (pNodeFMs)[nn].vl_GradientP2_dg = Calc_GP_AlphaP(phase_num, ActorID); + (pNodeFMs)[nn].vl_AlphaP2_dg = TempAlpha + (pNodeFMs)[nn].vl_kcd_dg * (pNodeFMs)[nn].vl_GradientP2_dg / ActiveCircuit[ActorID]->Solution->Iteration; + if((pNodeFMs)[nn].vl_AlphaP2_dg > 1) + (pNodeFMs)[nn].vl_AlphaP2_dg = 1; + if((pNodeFMs)[nn].vl_AlphaP2_dg < - 1) + (pNodeFMs)[nn].vl_AlphaP2_dg = (double) -1; + result = (pNodeFMs)[nn].vl_AlphaP2_dg; + } + break; + //1.calculate d_ij*alpha_j summation + case 3: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_phase_num_dg == phase_num)) //only count dgs with 3 phases or 1 phase that is same number + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP3_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + } + (pNodeFMs)[nn].vl_GradientP3_dg = Calc_GP_AlphaP(phase_num, ActorID); + (pNodeFMs)[nn].vl_AlphaP3_dg = TempAlpha + (pNodeFMs)[nn].vl_kcd_dg * (pNodeFMs)[nn].vl_GradientP3_dg / ActiveCircuit[ActorID]->Solution->Iteration; + if((pNodeFMs)[nn].vl_AlphaP3_dg > 1) + (pNodeFMs)[nn].vl_AlphaP3_dg = 1; + if((pNodeFMs)[nn].vl_AlphaP3_dg < - 1) + (pNodeFMs)[nn].vl_AlphaP3_dg = (double) -1; + result = (pNodeFMs)[nn].vl_AlphaP3_dg; + } + break; + default: + ; + break; + } + } + return result; +} +/*----------------------------------------------------------------------------------*/ +//only work for Generic5 nodefm + +//NodeNumofDG = NodeNuminClstr + +double TFMonitorObj::Calc_Alpha_M2(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + int i = 0; + int j = 0; + double sum_Sij_j = 0.0; + double Den = 0.0; + double Alpha = 0.0; + double den_dij = 0.0; + double dii = 0.0; + double TempAlpha = 0.0; + double tmp1 = 0.0; + double tmp2 = 0.0; + double tmp3 = 0.0; + double tmp4 = 0.0; + double tmp5 = 0.0; + double tmp6 = 0.0; + double tmp7 = 0.0; + update_all_nodes_info(ActorID); // update voltages on all buses + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + switch(phase_num) + { + case 0: //pos seq + + //1.calculate d_ij*alpha_j summation + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if((pNodeFMs)[j].vl_ndphases_dg == 3) //only 3 phase nodes + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + + //2.calculate gradient---------------- + //Bii := ActiveCircuit.Solution.NodeYii^[dbNodeRef].im; + //Load.ActiveLoadObj.kvarBase; + Den = (pNodeFMs)[NodeNumofDG].vl_q_DG - (pNodeFMs)[NodeNumofDG].vl_Q_Di - (pNodeFMs)[NodeNumofDG].vl_V * (pNodeFMs)[NodeNumofDG].vl_V * Bii; // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = ((pNodeFMs)[NodeNumofDG].vl_V_ref_dg - (pNodeFMs)[NodeNumofDG].vl_V) * (pNodeFMs)[NodeNumofDG].vl_V / (Den) / ((pNodeFMs)[NodeNumofDG].vl_V_ref_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref_dg); //*vl_Qmax, 0311-by dahei + j = ActiveCircuit[ActorID]->Solution->Iteration; + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = (beta * (pNodeFMs)[NodeNumofDG].vl_V_ref_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref_dg * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_Gradient_dg; + if(Abs((int) ((pNodeFMs)[NodeNumofDG].vl_V_ref_dg - (pNodeFMs)[NodeNumofDG].vl_V)) <= Volt_Trhd * (pNodeFMs)[NodeNumofDG].vl_V_ref_dg) + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = 0.0; + + //calculate final alpha---------------- + } + Alpha = (pNodeFMs)[NodeNumofDG].vl_kc_ul_dg * TempAlpha + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg; + if(Alpha > 1) + Alpha = 1; + if(Alpha < - 1) + Alpha = (double) -1; + (pNodeFMs)[NodeNumofDG].vl_Alpha_dg = Alpha; + result = Alpha; + } + break; + //1.calculate d_ij*alpha_j summation + case 1: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[1] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //Bii := ActiveCircuit.Solution.NodeYii^[dbNodeRef].im; + Den = (pNodeFMs)[NodeNumofDG].vl_q_DG1 - (pNodeFMs)[NodeNumofDG].vl_Q_Di1 - (pNodeFMs)[NodeNumofDG].vl_V1 * (pNodeFMs)[NodeNumofDG].vl_V1 * Bii; // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + tmp1 = (pNodeFMs)[NodeNumofDG].vl_q_DG1; + tmp2 = (pNodeFMs)[NodeNumofDG].vl_Q_Di1; + tmp3 = (pNodeFMs)[NodeNumofDG].vl_V1; + tmp4 = (pNodeFMs)[NodeNumofDG].vl_Qmax_dg; + tmp5 = (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg; + j = ActiveCircuit[ActorID]->Solution->Iteration; + (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg = ((pNodeFMs)[NodeNumofDG].vl_V_ref1_dg - (pNodeFMs)[NodeNumofDG].vl_V1) * (pNodeFMs)[NodeNumofDG].vl_V1 / (Den) / ((pNodeFMs)[NodeNumofDG].vl_V_ref1_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg = (beta * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg; + //vl_gradient1 := (beta)*vl_gradient1; + if(Abs((int) ((pNodeFMs)[NodeNumofDG].vl_V_ref1_dg - (pNodeFMs)[NodeNumofDG].vl_V1)) <= Volt_Trhd * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg) + (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg = 0.0; + //calculate final alpha---------------- + } + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = TempAlpha + (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg; + tmp6 = (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg; + tmp7 = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (double) -1; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg; + } + break; + //1.calculate d_ij*alpha_j summation + case 2: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + + //2.calculate gradient---------------- + //Bii := ActiveCircuit.Solution.NodeYii^[dbNodeRef].im; + Den = (pNodeFMs)[NodeNumofDG].vl_q_DG2 - (pNodeFMs)[NodeNumofDG].vl_Q_Di2 - (pNodeFMs)[NodeNumofDG].vl_V2 * (pNodeFMs)[NodeNumofDG].vl_V2 * Bii; // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + j = ActiveCircuit[ActorID]->Solution->Iteration; + (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg = ((pNodeFMs)[NodeNumofDG].vl_V_ref2_dg - (pNodeFMs)[NodeNumofDG].vl_V2) * (pNodeFMs)[NodeNumofDG].vl_V2 / (Den) / ((pNodeFMs)[NodeNumofDG].vl_V_ref2_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg); //*vl_Qmax + (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg = (beta * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg; + //vl_gradient2 := (beta)*vl_gradient2; + if(Abs((int) ((pNodeFMs)[NodeNumofDG].vl_V_ref2_dg - (pNodeFMs)[NodeNumofDG].vl_V2)) <= Volt_Trhd * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg) + (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg = 0.0; + //calculate final alpha---------------- + } + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = TempAlpha + (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (double) -1; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg; + } + break; + //1.calculate d_ij*alpha_j summation + case 3: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + + //2.calculate gradient---------------- + //Bii := ActiveCircuit.Solution.NodeYii^[dbNodeRef].im; + Den = (pNodeFMs)[NodeNumofDG].vl_q_DG3 - (pNodeFMs)[NodeNumofDG].vl_Q_Di3 - (pNodeFMs)[NodeNumofDG].vl_V3 * (pNodeFMs)[NodeNumofDG].vl_V3 * Bii; // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + j = ActiveCircuit[ActorID]->Solution->Iteration; + (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg = ((pNodeFMs)[NodeNumofDG].vl_V_ref3_dg - (pNodeFMs)[NodeNumofDG].vl_V3) * (pNodeFMs)[NodeNumofDG].vl_V3 / (Den) / ((pNodeFMs)[NodeNumofDG].vl_V_ref3_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg); //*vl_Qmax + (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg = (beta * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg; + //vl_gradient3 := (beta)*vl_gradient3; + if(Abs((int) ((pNodeFMs)[NodeNumofDG].vl_V_ref3_dg - (pNodeFMs)[NodeNumofDG].vl_V3)) <= Volt_Trhd * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg) + (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg = 0.0; + //calculate final alpha---------------- + } + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = TempAlpha + (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (double) -1; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg; + } + break; + default: + ; + break; + } + } + //result := 0; + return result; +} +//will be call in Generic5 +//calculate subgradient for DG 'NodeNumofDG' phase 'phase_num' + +double TFMonitorObj::Calc_Alpha_LnM2(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + double Lambda0 = 0.0; + double Lambda = 0.0; + double Tmp = 0.0; + double tmp1 = 0.0; + Lambda0 = 0.1; + Lambda = 1.0; + Tmp = 0.0; + //tmp := Calc_Alpha_L(NodeNumofDG, phase_num, dbNodeRef, Bii,beta,Volt_Trhd) ; + tmp1 = Calc_Alpha_M2(NodeNumofDG, phase_num, dbNodeRef, Bii, beta, Volt_Trhd, ActorID); + result = (1 - Lambda) * Tmp + Lambda * tmp1; + //result := Calc_Alpha_L_vivj(NodeNumofDG, phase_num, dbNodeRef, Bii,beta,Volt_Trhd) ; + return result; +} + +double TFMonitorObj::Calc_Alpha_L_vivj(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + int i = 0; + int j = 0; + double sum_Sij_j = 0.0; + double Den = 0.0; + double Alpha = 0.0; + double den_dij = 0.0; + double dii = 0.0; + double TempAlpha = 0.0; + double Tmp = 0.0; + double dynBeta = 0.0; + //tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7: double; + update_all_nodes_info(ActorID); // update voltages on all buses + Get_PQ_DI(NodeNumofDG, ActorID); // load measure + // calclate alpha + //with pnodeFMs^[NodeNumofDG] do + switch(phase_num) + { + case 1: //phase A + //1.calculate d_ij*alpha_j summation + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[1] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha_vivj(NodeNumofDG, phase_num, ActorID);// vl_gradient1_dg updated inside + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg; + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg; + } + break; //phase B + //1.calculate d_ij*alpha_j summation + case 2: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha_vivj(NodeNumofDG, phase_num, ActorID); + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg; // + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg; + } + break; //phase C + //1.calculate d_ij*alpha_j summation + case 3: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha_vivj(NodeNumofDG, phase_num, ActorID); + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg; // + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg; + } + break; //pos seq value + case 0: + break; + default: + ; + break; + } + return result; +} + +double TFMonitorObj::Calc_Alpha_L(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + int i = 0; + int j = 0; + double sum_Sij_j = 0.0; + double Den = 0.0; + double Alpha = 0.0; + double den_dij = 0.0; + double dii = 0.0; + double TempAlpha = 0.0; + double Tmp = 0.0; + double dynBeta = 0.0; + //tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7: double; + update_all_nodes_info(ActorID); // update voltages on all buses + Get_PQ_DI(NodeNumofDG, ActorID); // load measure + // calclate alpha + //with pnodeFMs^[NodeNumofDG] do + switch(phase_num) + { + case 1: //phase A + //1.calculate d_ij*alpha_j summation + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[1] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha(NodeNumofDG, phase_num, ActorID);// vl_gradient1_dg updated inside + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref1_dg / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg; + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient1_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha1_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg; + } + break; //phase B + //1.calculate d_ij*alpha_j summation + case 2: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha(NodeNumofDG, phase_num, ActorID); + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref2_dg; // + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient2_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha2_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg; + } + break; //phase C + //1.calculate d_ij*alpha_j summation + case 3: + { + int stop = 0; + den_dij = 0; + TempAlpha = 0; + //for i := 1 to nodes do den_dij := den_dij+pCommMatrix^[(NodeNumofDG-1)*Nodes+ i]; //4.is this correct + //tmp1 := Nodes; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) || ((pNodeFMs)[j].vl_nodeType_phase[2] == 1)) //only count dgs with 3 phases or 1 phase that is same number + //or (pnodeFMs^[j].vl_phase_num_dg = phase_num) then + //this phase has DG + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + //end; + } + } + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + //2.calculate gradient---------------- + //vl_gradient1_dg := (vl_V_ref1_dg-vl_v1)*vl_V1/(den)/(vl_V_ref1_dg*vl_V_ref1_dg); //*vl_Qmax, 0311-by dahei + //vl_gradient1_dg := (beta*vl_V_ref1_dg*vl_V_ref1_dg* abs(Bii)*100/j)*vl_gradient1_dg; + } + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + Tmp = Calc_Grdt_for_Alpha(NodeNumofDG, phase_num, ActorID); + if((pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg != 0) + dynBeta = (beta * Abs((int) Bii) * 100 / j) / (pNodeFMs)[NodeNumofDG].vl_Qmax_phase_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg * (pNodeFMs)[NodeNumofDG].vl_V_ref3_dg; // + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = TempAlpha + dynBeta * (pNodeFMs)[NodeNumofDG].vl_Gradient3_dg; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Alpha3_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (double) -1; + } + result = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg; + } + break; //pos seq value + case 0: + break; + default: + ; + break; + } + return result; +} + +/*----------------------------------------------------------------------------------*/ + +double TFMonitorObj::Calc_sum_dij_Alphaj(int NodeNumofDG, int phase_num, int ActorID) +{ + double result = 0.0; + int j = 0; + double sum_Sij_j = 0.0; + update_all_nodes_info(ActorID); + + // calclate alpha + /*# with pNodeFMs^[NodeNumofDG] do */ + { + + switch(phase_num) + { + case 1: //phase A + { + int stop = 0; + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = 0.0;//init as zero + sum_Sij_j = 0.0; + //for j := 1 to Nodes do + for(stop = NodeNumofDG, j = 0; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + for(stop = Nodes, j = NodeNumofDG + 1; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha1_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg / sum_Sij_j; + //Alpha1 := Alpha1 - kcq* gradient1; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha1_dg; + } + break; //phase B + case 2: + { + int stop = 0; + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = 0.0;//init as zero + sum_Sij_j = 0.0; + //for j := 1 to Nodes do + for(stop = NodeNumofDG, j = 0; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + for(stop = Nodes, j = NodeNumofDG + 1; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha2_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg / sum_Sij_j; + //Alpha2 := Alpha2 - kcq* gradient2; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha2_dg; + } + break; //phase C + case 3: + { + int stop = 0; + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = 0.0;//init as zero + sum_Sij_j = 0.0; + //for j := 1 to Nodes do + for(stop = NodeNumofDG, j = 0; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + for(stop = Nodes, j = NodeNumofDG + 1; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha3_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg / sum_Sij_j; + //Alpha3 := Alpha3 - kcq* gradient3; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha3_dg; + } + break; //pos seq value + case 0: + { + int stop = 0; + (pNodeFMs)[NodeNumofDG].vl_Alpha_dg = 0.0;//init as zero + sum_Sij_j = 0.0; + //for j := 1 to Nodes do + for(stop = NodeNumofDG, j = 0; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + for(stop = Nodes, j = NodeNumofDG + 1; j < stop; j++) + { + (pNodeFMs)[NodeNumofDG].vl_Alpha_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + sum_Sij_j = sum_Sij_j + (pCommMatrix)[NodeNumofDG * Nodes + j]; + } + (pNodeFMs)[NodeNumofDG].vl_Alpha_dg = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg / sum_Sij_j; + //Alpha := Alpha - kcq* gradient; + result = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg; + } + break; + default: + ; + break; + } + } + return result; +} + +double TFMonitorObj::AvgPmax() +{ + double result = 0.0; + int i = 0; + int k = 0; + int stop = 0; + result = 0.0; + k = 1; + //nodes;//all nodes included; + for(stop = Nodes, i = 0; i < stop; i++) + { + /*# with pNodeFMs^[i] do */ + { + + if(((pNodeFMs)[i].vl_PF_flag_dg == 1) && ((pNodeFMs)[i].vl_CC_switch_dg == true)) // + { + result = result + (pNodeFMs)[i].vl_Pmax_dg; + result = result / k; + k = k + 1; + } + } + } + return result; +} + +double TFMonitorObj::AvgQmax() +{ + double result = 0.0; + int i = 0; + int k = 0; + int stop = 0; + result = 0.0; + k = 1; + //nodes;//all nodes included; + for(stop = Nodes, i = 0; i < stop; i++) + { + /*# with pNodeFMs^[i] do */ + { + + if(((pNodeFMs)[i].vl_QV_flag_dg == 1) && ((pNodeFMs)[i].vl_CC_switch_dg == true)) //volt/var control is on + { + result = result + (pNodeFMs)[i].vl_Qmax_dg; + result = result / k; + k = k + 1; + } + } + } + return result; +} +/*----------------------------------------------------------------------*/ +/**/ + +String TFMonitorObj::Get_FileName(int ActorID) +{ + String result; + result = GetOutputDirectory() + CircuitName_[ActorID] + "Mon_" + get_Name() + ".csv"; + return result; +} + +double TFMonitorObj::Calc_fm_ul_0(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + int dly = 0; + int i = 0; + int j = 0; + double Den = 0.0; + double den_dij = 0.0; + double TempAlpha = 0.0; + double Tmp = 0.0; + double dfs_hide = 0.0; + + //update_all_nodes_info; // update voltages on all buses + //with pNodeFMs^[NodeNumofDG] do + // begin + switch(phase_num) + { + case 0: //pos seq + + //1.calculate d_ij*alpha_j summation + { + den_dij = 0; + TempAlpha = 0.0; + /*-----------------------------------*/ + //no delay + if(T_intvl_smpl == 0.0) + // communication + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + if(j != atk_node_num) // regular nodes + + //Sumation of all alpha s + { + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dgn; + } + else + + // attack and defense ------------------------------------- + // node under attack + //Sumation of all alpha s + { + if((atk == true) && (ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time)) + TempAlpha = TempAlpha + D_p * (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dgn; + else + // attack starts from here + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dgn; + } /*--attack and defense ends---------------------------------*/ + // attack and defense + /*-----------------------------------*/ + if((atk == true) && (ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time)) + //and (ActiveCircuit[ActorID].Solution.DynaVars.IterationFlag = 1) + + // if being attacked + { + TempAlpha = TempAlpha + (pNodeFMs)[j].d_atk; // attack is added on + } + /*--attack and defense ends---------------------------------*/ + } + } + //with delay + } + else + { + int stop = 0; + for(stop = NodeNumofDG, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + //how many steps of delay from node j to node 'NodeNumofDG' + dly = (pCommDelaySteps)[NodeNumofDG * Nodes + j]; + if(dly == 0) + { + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + } + else + { + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_smpl_dg[1][dly]; + } + } + } + j = NodeNumofDG; + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + } + for(stop = Nodes, j = NodeNumofDG + 1; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + { + den_dij = den_dij + (pCommMatrix)[NodeNumofDG * Nodes + j]; + dly = (pCommDelaySteps)[NodeNumofDG * Nodes + j]; + if(dly == 0) + { + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_Alpha_dg; + } + else + { + TempAlpha = TempAlpha + (pCommMatrix)[NodeNumofDG * Nodes + j] * (pNodeFMs)[j].vl_smpl_dg[1][dly]; + } + } + } + } + + /*-----------------------------------*/ + // from sumation to ul + if(den_dij == 0) + TempAlpha = 0.0; + else + { + TempAlpha = TempAlpha / den_dij; + } + // if this node is the node under attack, change the sign of that + if((NodeNumofDG == atk_node_num) && (atk == true) && (ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time)) + { + Tmp = (TempAlpha - D_p * (pNodeFMs)[NodeNumofDG].vl_Alpha_dgn); + } + else + Tmp = (TempAlpha - (pNodeFMs)[NodeNumofDG].vl_Alpha_dgn); + + // attack and defense + /*-----------------------------------*/ + if((atk == true) && (ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time)) + { + dfs_hide = organise_dfs_node(NodeNumofDG); // x_i' = A_i x + {{ \beta K_i z }}+ \beta B_i x_0 + d_i + //TempAlpha := TempAlpha + beta_dfs * tmp; // defense is added on + /*--attack and defense ends---------------------------------*/ + Tmp = Tmp + beta_dfs * dfs_hide; + } + //Tolerance of alpha_i alpha_j + if(Abs((int) Tmp) <= Volt_Trhd * 0.01) + //Result := 0.0 + ; + else + result = Tmp * (pNodeFMs)[NodeNumofDG].vl_kc_ul_dg; + // if there is attck + } + break; + default: + ; + break; + } + //end; + //result := 0; + return result; +} + +double TFMonitorObj::Calc_fm_us_0(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID) +{ + double result = 0.0; + int i = 0; + int j = 0; + double Den = 0.0; + double Tmp = 0.0; + double V = 0.0; + double VRef = 0.0; + double den_dij = 0.0; + double tempUl = 0.0; + double pHi = 0.0; + //update voltage + j = NodeNumofDG; + Get_PDElem_terminal_voltage(NodeNumofDG, (pNodeFMs)[NodeNumofDG].vl_strMeasuredName, (pNodeFMs)[NodeNumofDG].vl_terminalNum, ActorID); + //calc gradient + //with pNodeFMs^[NodeNumofDG] do + //begin + V = (pNodeFMs)[NodeNumofDG].vl_V; + VRef = (pNodeFMs)[NodeNumofDG].vl_V_ref_dg; + switch(phase_num) + { + case 0: //pos seq + { + Den = Abs((int) ((pNodeFMs)[NodeNumofDG].vl_q_DG - (pNodeFMs)[NodeNumofDG].vl_Q_Di - V * V * Bii)); // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = (VRef - V) * V / (Den) / (VRef * VRef);//*vl_Qmax_dg;// + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = (beta * VRef * VRef) * Abs((int) Bii) * 100 * (pNodeFMs)[NodeNumofDG].vl_Gradient_dg; + + //(beta* abs(Bii)*100/j)/vl_Qmax_phase_dg* + if(Abs((int) (VRef - V)) <= Volt_Trhd * VRef) + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = 0.0; + Tmp = Abs((int) (VRef - V)); + if((pNodeFMs)[NodeNumofDG].vl_Gradient_dg > 1) + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = 1; + if((pNodeFMs)[NodeNumofDG].vl_Gradient_dg < - 1) + (pNodeFMs)[NodeNumofDG].vl_Gradient_dg = (double) -1; + result = (pNodeFMs)[NodeNumofDG].vl_Gradient_dg; + + + // the following only works for the node under attack + if(j == atk_node_num) + // in dynamic simulation + { + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + // attack and defense has been set + { + if((atk == true) && (dfs == true)) + //if current time is over attack time + { + if(ActiveCircuit[ActorID]->Solution->DynaVars.T > atk_time) + // if the attack is of the second type, then phi =0 + { + if((pNodeFMs)[atk_node_num].d_atk0 == 0) + pHi = 0.0; + else + + // if the attack is of the first type, then phi =0 + { + if(beta_dfs != 0) + //Set a coeffient for beta_dfs + //if NodeNumofDG<>atk_node_num then // only for those nodes not attacked + { + int stop = 0; + den_dij = 0; + tempUl = 0.0; + for(stop = Nodes, i = 0; i < stop; i++) + { + if(((pNodeFMs)[i].vl_ndphases_dg == 3) && (((pNodeFMs)[i].vl_nodeType_phase[0] + (pNodeFMs)[i].vl_nodeType_phase[1] + (pNodeFMs)[i].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + + //Sumation of all Z and alpha s + { + den_dij = den_dij + (pCommMatrix)[j * Nodes + i]; + tempUl = tempUl + (pCommMatrix)[j * Nodes + i] * (pNodeFMs)[i].vl_Alpha_dgn; + } + /// + } + // average + if(den_dij == 0) + { + tempUl = 0.0; + } + else + { + tempUl = tempUl / den_dij; + } + tempUl = (tempUl - (pNodeFMs)[j].vl_Alpha_dgn); + // calculate phi + pHi = Coef_Phi(Abs((int) tempUl)); + } + } + // + result = D_p * (1 + pHi * beta_dfs) * (pNodeFMs)[NodeNumofDG].vl_Gradient_dg; + } + } + } + } + + //if result >1 then result := 1 ; + //if result <-1 then result := -1 ; + } + break; + default: + ; + break; + } + //end; + return result; +} + +double TFMonitorObj::Coef_Phi(double X) +{ + double result = 0.0; + double X1 = 0.0; + double X2 = 0.0; + double X3 = 0.0; + double Y1 = 0.0; + double Y2 = 0.0; + double Y3 = 0.0; + double y0 = 0.0; + double overall = 0.0; + overall = D_beta; + X1 = 0.005; + X2 = 0.01; + X3 = 0.05; + Y1 = 1.0; + Y2 = 0.5; + Y3 = 0.0; + y0 = 1.0; + if(X <= X1) + result = X * (Y1 - y0) / X1 + y0; + else + { + if(X <= X2) + result = Y1 + (X - X1) * (Y2 - Y1) / (X2 - X1); + else + { + if(X <= X3) + result = Y2 + (X - X2) * (Y3 - Y2) / (X3 - X2); + else + result = Y1; + } + + + //result := 1.0 ; + } + result = overall * result; + return result; +} + +double TFMonitorObj::Getgradient(int j, int phase_num, double Bii, double Volt_Trhd) +{ + double result = 0.0; + double V = 0.0; + double VRef = 0.0; + double Den = 0.0; + double Tmp = 0.0; + V = (pNodeFMs)[j].vl_V; + VRef = (pNodeFMs)[j].vl_V_ref_dg; + switch(phase_num) + { + case 0: //pos seq + { + Den = Abs((int) ((pNodeFMs)[j].vl_q_DG - (pNodeFMs)[j].vl_Q_Di - V * V * Bii)); // pos ctrl: Bii use the first one + if(Abs((int) Den) < EPSILON) + Den = EPSILON; + Tmp = (VRef - V) * V / (Den) / (VRef * VRef);//*vl_Qmax_dg;// + + + //(beta* abs(Bii)*100/j)/vl_Qmax_phase_dg* + + //if abs(vref - v)<= Volt_Trhd*vref then tmp := 0.0; + if(Tmp > 1) + Tmp = 1; + if(Tmp < - 1) + Tmp = (double) -1; + result = Tmp; + } + break; + default: + ; + break; + } + return result; +} //abandoned + +void TFMonitorObj::Agnt_smpl(int NodeNumofDG, int phase_num, int ActorID) +{ + double crnt_time = 0.0; + int i = 0; + //if True then + if(ActiveCircuit[ActorID]->Solution->DynaVars.IterationFlag == 1) /*1= Same Time Step as last iteration*/ + // + { + if((pNodeFMs)[NodeNumofDG].vl_SmplCnt == 0)//the first step + { + int stop = 0; + for(stop = MaxLocalMem, i = 1; i <= stop; i++) + { + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[1][i] = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg; + } + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[2][i] = (pNodeFMs)[NodeNumofDG].vl_AlphaP_dg; + } + // + crnt_time = ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600 + ActiveCircuit[ActorID]->Solution->DynaVars.T; + //Move the array only at the first time-step + + //if t_k greater or equal to current sample time plus smp interval, do another sample + if(crnt_time >= (T_intvl_smpl + (pNodeFMs)[NodeNumofDG].vl_crnt_smp_time)) + //if Trunc(crnt_time/T_intvl_smpl) >= pNodeFMs^[NodeNumofDG].vl_SmplCnt +1 then + //begin + //save alf into the first entry of smpl_ary for communication + //alpha + { + int stop = 0; + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[1][0] = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg;// [0] is the newest value + // [0] and [1] are always the same + //alphaP + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[2][0] = (pNodeFMs)[NodeNumofDG].vl_AlphaP_dg;// + //0 seq voltage + //pNoddeFMs^[NodeNumofDG].vl_smpl_dg[3][0] := pNodeFMs^[NodeNumofDG].vl_V;// + for(stop = MaxLocalMem - 1, i = 0; i <= stop; i++) + { // [0]->[1],[MaxLocalMem-1]->[MaxLocalMem] + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[1][MaxLocalMem - i] = (pNodeFMs)[NodeNumofDG].vl_smpl_dg[1][MaxLocalMem - i]; + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[2][MaxLocalMem - i] = (pNodeFMs)[NodeNumofDG].vl_smpl_dg[2][MaxLocalMem - i]; + } + + //vl_SmplCnt increase + ++(pNodeFMs)[NodeNumofDG].vl_SmplCnt; + //update vl_crnt_time + (pNodeFMs)[NodeNumofDG].vl_crnt_smp_time = crnt_time; + //end; + } + } +} + +void TFMonitorObj::Init_delay_array(int NodeNumofDG, int ActorID) +{ + int i = 0; + //measure all voltages + int stop = 0; + for(stop = Nodes, i = 0; i < stop; i++) + { + Get_PDElem_terminal_voltage(i, (pNodeFMs)[i].vl_strMeasuredName, (pNodeFMs)[i].vl_terminalNum, ActorID); + } + // inti delay array + for(stop = MaxLocalMem, i = 0; i <= stop; i++) + { + //alpha + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[1][i] = (pNodeFMs)[NodeNumofDG].vl_Alpha_dg; + //alphaP + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[2][i] = (pNodeFMs)[NodeNumofDG].vl_AlphaP_dg; + // vl_v, which is the 0 seq. voltage + (pNodeFMs)[NodeNumofDG].vl_smpl_dg[3][i] = (pNodeFMs)[NodeNumofDG].vl_V; + } +} // NodeNuminClstr: node number in cluster + +double TFMonitorObj::Calc_Gradient_ct_P(int NodeNuminClstr, int phase_num, int ActorID) +{ + double result = 0.0; + double dvDGtemp = 0.0; + double Grdnt_P = 0.0; + //tempCplx + dvDGtemp = ((pNodeFMs)[NodeNuminClstr].vl_V - (pNodeFMs)[NodeNuminClstr].vl_V_ref_dg) / (pNodeFMs)[NodeNuminClstr].vl_V_ref_dg; // + // if this DG is above 1.05, then it should have P curtail gradient + //if ( ActiveCircuit.Solution.bCurtl=true ) and (dvDGtemp>0.0) then //overall system need control + if(ActiveCircuit[ActorID]->Solution->bCurtl == true) + { + if(ld_fm_info[0].b_Curt_Ctrl == true) // if false, the curtailment will be zero for any node in this cluster + + //- activecircuit.Solution.LD_FM[0].volt_lw_lmt); + Grdnt_P = (ActiveCircuit[ActorID]->Solution->LD_FM[0].volt_lwst - 1.0); + } + else + Grdnt_P = 0.0; + //!!!!!!!!!!!!! + switch(phase_num) + { + case 0: //pos seq + { + result = Grdnt_P; // + } + break; + case 1: + { + result = Grdnt_P; // + } + break; + case 2: + { + result = Grdnt_P; // + } + break; + case 3: + { + result = Grdnt_P; // + } + break; + default: + ; + break; + } + return result; +} +////////////////////////// +/*-------------------------*/ // NodeNuminClstr: node number in cluster //with delay + +double TFMonitorObj::Calc_ul_P(int NodeNuminClstr, int phase_num) +{ + double result = 0.0; + int j = 0; + double den_dij = 0.0; + double TempAlphaP = 0.0; + int dly = 0; + //alphaP = sum (alphaP) + Beta * Gp + + //with pNodeFMs^[NodeNuminClstr] do + // begin + switch(phase_num) + { + case 0: //pos seq + + //1.calculate d_ij*alpha_j summation + { + den_dij = 0; + TempAlphaP = 0; + /*-----------------------------------*/ + //no delay + if(T_intvl_smpl == 0.0) + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + // has 3-phase DG + // if (pnodeFMs^[j].vl_ndphases_dg = 3) then //only 3 phase nodes + + //if pnodeFMs^[j].vl_nodeType = 1 then // only DG nodes + //begin + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP_dg; + //end; + } + } + } + else + + // with delay + { + int stop = 0; + + for(stop = NodeNuminClstr, j = 0; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //has 3-phase DG + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + //how many steps of delay from node j to node 'NodeNumofDG' + dly = (pCommDelaySteps)[NodeNuminClstr * Nodes + j]; + if(dly == 0) + { + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP_dg; + } + else + { + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_smpl_dg[2][dly]; + } + } + } + j = NodeNuminClstr; + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //has 3-phase DG + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP_dg; + } + for(stop = Nodes, j = NodeNuminClstr + 1; j < stop; j++) + { + if(((pNodeFMs)[j].vl_ndphases_dg == 3) && (((pNodeFMs)[j].vl_nodeType_phase[0] + (pNodeFMs)[j].vl_nodeType_phase[1] + (pNodeFMs)[j].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //has 3-phase DG + { + den_dij = den_dij + (pCommMatrix)[NodeNuminClstr * Nodes + j]; + dly = (pCommDelaySteps)[NodeNuminClstr * Nodes + j]; + if(dly == 0) + { + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_AlphaP_dg; + } + else + { + TempAlphaP = TempAlphaP + (pCommMatrix)[NodeNuminClstr * Nodes + j] * (pNodeFMs)[j].vl_smpl_dg[2][dly]; + } + } + } + } + if(den_dij == 0) + TempAlphaP = 0.0; + else + { + TempAlphaP = TempAlphaP / den_dij; //the average + } + //Tolerance of alphap_i alphap_j + TempAlphaP = TempAlphaP - (pNodeFMs)[NodeNuminClstr].vl_AlphaP_dg; //uL for cooperative control of active power + if(Abs((int) TempAlphaP) < 0.002) + result = 0.0; + else + result = TempAlphaP; + } + break; + default: + ; + break; + } + // end; + return result; +} //all nodes , p.u. value + +void TFMonitorObj::update_node_info_each_time_step(int ActorID) +{ + int Den = 0; + int i = 0; + double v0_tmp = 0.0; + int stop = 0; + dlt_z0 = 0.0; + Den = 0; + for(stop = Nodes, i = 0; i < stop; i++) + { + if(((pNodeFMs)[i].vl_ndphases_dg == 3) && (((pNodeFMs)[i].vl_nodeType_phase[0] + (pNodeFMs)[i].vl_nodeType_phase[1] + (pNodeFMs)[i].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + { + (pNodeFMs)[i].vl_Alpha_dgn = (pNodeFMs)[i].vl_Alpha_dg; + (pNodeFMs)[i].z_dfsn = (pNodeFMs)[i].z_dfs; + dlt_z0 = dlt_z0 + (pNodeFMs)[i].vl_Gradient_dg; + } + Den = Den + 1; + } + + //sumation or average + if(Den != 0) + dlt_z0 = -dlt_z0 / Den; // gredient (v-vref) +} +//Calculate equivalent omega and delta + +void TFMonitorObj::Calc_P_freq_fm(int ActorID) +{ + double domg = 0.0; + double ddlt = 0.0; + double dPm = 0.0; + double DeltaP = 0.0; + double Tmp = 0.0; + //first time initialization + if(ActiveCircuit[ActorID]->Solution->DynaVars.T < init_time) + Pm_fm = this->Get_power_trans(ActorID); + + //preparation : calculate Delta P + Tmp = this->Get_power_trans(ActorID); + DeltaP = Pm_fm - Tmp; + //derivatives + //ddlt := omg_fm; + domg = (DeltaP / (kVA_fm * 1000) - D_fm * omg_fm) / M_fm; + dPm = -Ki_fm * omg_fm * (kVA_fm * 1000) / Tau_fm; + //integral + if(ActiveCircuit[ActorID]->Solution->Get_SolMode() == DYNAMICMODE) + //dlt_fm := dlt_fm + ddlt * ActiveCircuit[ActorID].Solution.DynaVars.h; + { + Pm_fm = Pm_fm + dPm * ActiveCircuit[ActorID]->Solution->DynaVars.h; + omg_fm = omg_fm + domg * ActiveCircuit[ActorID]->Solution->DynaVars.h; + } + comp_omg = omg_fm + DeltaP / (kVA_fm * 1000) / D_fm; //comp_omg is (\Delta f + \Delta P / B) +} //all nodes , p.u. value + +void TFMonitorObj::update_ld_dly(int ActorID) +{ + int i = 0; + int j = 0; + int ndlys = 0; + double v0_tmp = 0.0; + double crnt_time = 0.0; + int stop = 0; + ld_fm_info[0].volt_avg = 0.0; //recalculate voltage average + ld_fm_info[0].volt_lwst = 999999; //search new value at each round + ld_fm_info[0].volt_hghst = (double) -99999; + for(stop = Nodes, i = 0; i < stop; i++) + { + //update vl_v1/v2/v3, vl_v_1c/v_2c/v_3c, update vl_v for node i + Get_PDElem_terminal_voltage(i, (pNodeFMs)[i].vl_strMeasuredName, (pNodeFMs)[i].vl_terminalNum, ActorID); + //synchronous sampling + if(T_intvl_smpl == 0.0) + // pNodeFMs^[i].vl_smpl_dg[i][j] is not used + { + v0_tmp = (pNodeFMs)[i].vl_V / ((pNodeFMs)[i].vl_basevolt); + } + else + + //asynchronous sampling + //update pNodeFMs^[i].vl_smpl_dg[i][j] first + { + if((pNodeFMs)[i].vl_SmplCnt == 0)//the first step + { + int stop1 = 0; + for(stop1 = MaxLocalMem, j = 0; j <= stop1; j++) + { + //alphas + (pNodeFMs)[i].vl_smpl_dg[1][j] = (pNodeFMs)[i].vl_Alpha_dg; + } + (pNodeFMs)[i].vl_smpl_dg[2][j] = (pNodeFMs)[i].vl_AlphaP_dg; + //voltage + (pNodeFMs)[i].vl_smpl_dg[3][j] = (pNodeFMs)[i].vl_V; // 0 seq. + } + // + crnt_time = ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600 + ActiveCircuit[ActorID]->Solution->DynaVars.T; + //Move the array only at the first time-step + + //if t_k greater or equal to current sample time plus smp interval, do another sample + if(crnt_time >= (T_intvl_smpl + (pNodeFMs)[i].vl_crnt_smp_time)) + + //if Trunc(crnt_time/T_intvl_smpl) >= pNodeFMs^[NodeNumofDG].vl_SmplCnt +1 then + //begin + //save alf into the first entry of smpl_ary for communication + //alpha + { + int stop1 = 0; + (pNodeFMs)[i].vl_smpl_dg[1][0] = (pNodeFMs)[i].vl_Alpha_dg;// [0] is the newest value + //alphaP + (pNodeFMs)[i].vl_smpl_dg[2][0] = (pNodeFMs)[i].vl_AlphaP_dg;// + // VL_V //0 seq voltage + (pNodeFMs)[i].vl_smpl_dg[3][0] = (pNodeFMs)[i].vl_V;// + + + //pNoddeFMs^[NodeNumofDG].vl_smpl_dg[3][0] := pNodeFMs^[NodeNumofDG].vl_V;// + for(stop1 = MaxLocalMem - 1, j = 0; j <= stop1; j++) + { // [0]->[1],[MaxLocalMem-1]->[MaxLocalMem] + (pNodeFMs)[i].vl_smpl_dg[1][MaxLocalMem - j] = (pNodeFMs)[i].vl_smpl_dg[1][MaxLocalMem - j]; + (pNodeFMs)[i].vl_smpl_dg[2][MaxLocalMem - j] = (pNodeFMs)[i].vl_smpl_dg[2][MaxLocalMem - j]; + (pNodeFMs)[i].vl_smpl_dg[3][MaxLocalMem - j] = (pNodeFMs)[i].vl_smpl_dg[3][MaxLocalMem - j]; + } + + //vl_SmplCnt increase + ++(pNodeFMs)[i].vl_SmplCnt; + //update vl_crnt_time + (pNodeFMs)[i].vl_crnt_smp_time = crnt_time; + //end; + } + // delay steps from agent to virtual leader + ndlys = (pCommDelaySteps)[virtual_Ld_Nd * Nodes + i]; + // total delay steps: ndlys+nup_dlys + //if pnodefms^[i].vl_basevolt <> 0.0 then + v0_tmp = (pNodeFMs)[i].vl_smpl_dg[3][ndlys + nup_dlys] / ((pNodeFMs)[i].vl_basevolt); + } + //update highest voltage + if(ld_fm_info[0].volt_hghst < v0_tmp) + { + ld_fm_info[0].volt_hghst = v0_tmp; + ld_fm_info[0].ndnum_hghst = i; + } + //update lowest voltage + if(ld_fm_info[0].volt_lwst > v0_tmp) + { + ld_fm_info[0].volt_lwst = v0_tmp; + ld_fm_info[0].ndnum_lwst = i; + } + + //other information should be updated? + // + ld_fm_info[0].volt_avg = ld_fm_info[0].volt_avg + v0_tmp; //p.u. + } + //avg of valtage + ld_fm_info[0].volt_avg = ld_fm_info[0].volt_avg / Nodes; +} + +//attack and defense + // update d_i + +void TFMonitorObj::update_attack(int ActorID) +{ + double dlt_d = 0.0; + int j = 0; + //attack and defense at this step + /*-----------------------------------*/ + if(atk == false) + return; + dlt_d = 0.0; // no dynamic for now + if((atk == true) && (ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) && (ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time)) + // initialization first, only once + { + int stop = 0; + if(d_atk_inited == false) + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + if(j == atk_node_num) // only the node being attacked is affected + { + (pNodeFMs)[j].d_atk = (pNodeFMs)[atk_node_num].d_atk0; //the + } + } + d_atk_inited = true; + } + // attack + for(stop = Nodes, j = 0; j < stop; j++) + { + if(j == atk_node_num) // only the node being attacked is affected + { + (pNodeFMs)[j].d_atk = (pNodeFMs)[j].d_atk + ActiveCircuit[ActorID]->Solution->DynaVars.h * dlt_d; + } + } + } + else + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + // no attack + (pNodeFMs)[j].d_atk = 0.0; + } + } +}// update z_i + +void TFMonitorObj::update_defense(int ActorID) +{ + double dlt_z = 0.0; + int j = 0; + double Bii = 0.0; + int den_dij = 0; + int den_dij_z = 0; + double tempZ = 0.0; + double TempAlpha = 0.0; + int DevIndex = 0; + int ndref = 0; + TDSSCktElement* tempElement = nullptr; + TPowerTerminal* tempTerminal = nullptr; + int i = 0; + if(dfs == false) // if no defense + //or (ActiveCircuit[ActorID].Solution.DynaVars.t < atk_time) // if no attack + return; + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + { + if(ActiveCircuit[ActorID]->Solution->DynaVars.T <= atk_time) + // IF THERE IS NO ATTACK YET, Z FOLLOWS ALPHA + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + (pNodeFMs)[j].z_dfs = (pNodeFMs)[j].vl_Alpha_dg; //the let z : alpha + (pNodeFMs)[j].z_dfsn = (pNodeFMs)[j].z_dfs; + } + } + if(ActiveCircuit[ActorID]->Solution->DynaVars.T >= atk_time) + //calculate the initial value for z_dfs + { + int stop = 0; + if(z_dfs_inited == false) + { + int stop = 0; + for(stop = Nodes, j = 0; j < stop; j++) + { + (pNodeFMs)[j].z_dfs = (pNodeFMs)[j].vl_Alpha_dgn; //the let z : alpha + (pNodeFMs)[j].z_dfsn = (pNodeFMs)[j].z_dfs; + } + // has been initiated + z_dfs_inited = true; + } + + + //update for each node + for(stop = Nodes, j = 0; j < stop; j++) + { + // x_i' = A_i x + \beta K_i z + \beta B_i x_0 + d_i + // z_i' = H_i Z + \beta G_i x + \beta D_i x_0 + // calculate z_i + ////////////////////// + // derivative calculation + int stop1 = 0; + dlt_z = dlt_z0; //dlt_z0 will be update at each time step by average of gradient actually this is -us_i + /* + dlt_z := 0.0; + //(1)/\beta D_i x_0 + ndref := 1; + + Bii := 1.0; + Devindex := GetCktElementIndex(pNodeFMs[j].vl_strMeasuredName) ; // Global function + IF DevIndex>0 THEN Begin // Monitored element must already exist + tempElement := ActiveCircuit[ActorID].CktElements.Get(DevIndex) ; + tempTerminal := tempElement.Terminals^[pNodeFMs[j].vl_terminalNum] ; + ndref := tempTerminal.TermNodeRef^[1] ; + Bii := ActiveCircuit[ActorID].Solution.NodeYii[tempTerminal.TermNodeRef^[1] ].im ; + end; + + //D_beta := 0.05; + + dlt_z := Getgradient(j,0,Bii,pNodeFMs[j].vl_volt_thrd_dg) ; + */ + + //(2,3)/////(2)/ / calculate H_i Z ; H_i = A_i; //(3)/ calculate \beta G_i x ; G_i = A_i + // j is the outer loop + // pCommMatrix is used as the matrix for H_i , G_i, K_i + den_dij = 0; + tempZ = 0.0; + TempAlpha = 0.0; + for(stop1 = Nodes, i = 0; i < stop1; i++) + { + if(((pNodeFMs)[i].vl_ndphases_dg == 3) && (((pNodeFMs)[i].vl_nodeType_phase[0] + (pNodeFMs)[i].vl_nodeType_phase[1] + (pNodeFMs)[i].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + + //Sumation of all Z and alpha s + { + den_dij_z = den_dij + (pCommHide)[j * Nodes + i]; + tempZ = tempZ + (pCommHide)[j * Nodes + i] * (pNodeFMs)[i].z_dfsn; + den_dij = den_dij + (pCommMatrix)[j * Nodes + i]; + TempAlpha = TempAlpha + (pCommMatrix)[j * Nodes + i] * (pNodeFMs)[i].vl_Alpha_dgn; + } + /// + } + // average + if(den_dij == 0) + { + tempZ = 0.0; + TempAlpha = 0.0; + } + else + { + tempZ = tempZ / den_dij_z; + TempAlpha = TempAlpha / den_dij; + } + tempZ = (tempZ - (pNodeFMs)[j].z_dfsn); + TempAlpha = (TempAlpha - (pNodeFMs)[j].vl_Alpha_dgn); + + // z_i' = H_i Z + \beta G_i x + \beta D_i x_0 + dlt_z = tempZ + beta_dfs * TempAlpha;//- beta_dfs *dlt_z0;// - pNodeFMs^[j].z_dfsn/den_dij;// - 0.1* pNodeFMs[j].z_dfs ; //+ pNodeFMs[j].vl_kcq_dg*dlt_z0 ; + // integration + //if abs(dlt_z) < 0.003 then dlt_z := 0.0 ; + (pNodeFMs)[j].z_dfs = (pNodeFMs)[j].z_dfsn + dlt_z * ActiveCircuit[ActorID]->Solution->DynaVars.h; + } + } + } +} // calculate K_i z // x_i' = A_i x + \beta K_i z + \beta B_i x_0 + d_i + +double TFMonitorObj::organise_dfs_node(int j) +{ + double result = 0.0; + int i = 0; + int den_dij = 0; + double tempZ = 0.0; + // x_i' = A_i x - \beta K_i z + \beta B_i x_0 + d_i + // z_i' = H_i Z + \beta G_i x + \beta D_i x_0 + + // this function is to calculate + // K_i z + int stop = 0; + den_dij = 0; + tempZ = 0.0; + for(stop = Nodes, i = 0; i < stop; i++) + { + if(((pNodeFMs)[i].vl_ndphases_dg == 3) && (((pNodeFMs)[i].vl_nodeType_phase[0] + (pNodeFMs)[i].vl_nodeType_phase[1] + (pNodeFMs)[i].vl_nodeType_phase[2]) == 3)) //only 3 phase nodes + //this phase has DG + { + den_dij = den_dij + (pCommMatrix)[j * Nodes + i]; + tempZ = tempZ + (pCommMatrix)[j * Nodes + i] * (pNodeFMs)[i].z_dfsn; + } + } + + //average + if(den_dij == 0) + tempZ = 0.0; + else + { + tempZ = tempZ / den_dij; + } + result = -(tempZ - (pNodeFMs)[j].z_dfsn);// - pNodeFMs^[j].z_dfsn/den_dij; // should be ZERO at last + //result := TempZ; + //what if defens is zdfs + //result := pNodeFMs^[j].z_dfs; + return result; +} + //WriteDLLDebugFile('Monitor'); + + + + +} // namespace Fmonitor + diff --git a/OpenDSSC/Meters/fMonitor.h b/OpenDSSC/Meters/fMonitor.h new file mode 100644 index 0000000..b4ab596 --- /dev/null +++ b/OpenDSSC/Meters/fMonitor.h @@ -0,0 +1,289 @@ +#ifndef FmonitorH +#define FmonitorH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "MeterClass.h" +#include "MeterElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "PointerList.h" +#include "VLNodeVars.h" +#include "LD_fm_infos.h" +#include "d2c_structures.h" + +namespace Fmonitor +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + By Ying @UCF 10/27/2017 + +*/ +typedef AnsiChar TFMonitorStrBuffer[256/*# range 1..256*/]; +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + /*This has to be named TDSSMonitor because Delphi has a TMonitor Class and the compiler will get confused*/ + +class TDSSFMonitor : public MeterClass::TMeterClass +{ + friend class TFMonitorObj; +public: + typedef MeterClass::TMeterClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String MonitorName); +public: + TDSSFMonitor(); + virtual ~TDSSFMonitor(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + virtual void ResetAll(int ActorID); + virtual void SampleAll(int ActorID); // Force all monitors to take a sample + //Procedure SampleAllMode5; // Sample just Mode 5 monitors + virtual void SaveAll(int ActorID); // Force all monitors to save their buffers to disk + /*update FM leader information*/ + void update_sys_ld_info(int ActorID); //all FMs + void Calc_P_freq(int ActorID);// calculte frequency for each cluster + //attack and defense + void update_atks(int ActorID); + void update_defense_layer(int ActorID); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TFMonitorObj : public MeterElement::TMeterElement +{ + friend class TDSSFMonitor; +public: + typedef MeterElement::TMeterElement inherited; +private: + //pTVLeaderVars : TPointerList; //save all nodes information + //VL_node : TVLnodeVars;// leader node of this cluster + int Nodes; //nodes of this cluster \\default nodes := 33; + Arraydef::pSmallIntArray pCommMatrix;// communication matrix of this cluster + double P_trans_ref; // Power Ref on metered elemet, if mode =1 real power of this cluster will be used + int p_mode; + Ucomplex::complex tempCplx; + int BufferSize; + int Hour; + double Sec; // last time entered in the buffer + Arraydef::pSingleArray MonBuffer; + int BufPtr; // point to present (last) element in buffer must be incremented to add + Ucomplex::pComplexArray CurrentBuffer; + Ucomplex::pComplexArray VoltageBuffer; + int NumStateVars; + Arraydef::pDoubleArray StateBuffer; + Ucomplex::pComplexArray FlickerBuffer; // store phase voltages in polar form + // then convert to re=flicker level, update every time step + // and im=Pst, update every 10 minutes + Arraydef::pDoubleArray SolutionBuffer; + bool IncludeResidual; + bool VIpolar; + bool Ppolar; + int FileSignature; + int FileVersion; + double BaseFrequency; + /*-------------*/ + double F_Value_one;//test; + //Voltages + Arraydef::pDoubleArray F_Value_one_V; //Measured voltage by each FMonitor(p.u.) + Ucomplex::pComplexArray F_Value_one_S; //Measured apparent power for each phase by each Fmonitor + double Fvalue_P; //This variable is used to store total measure three-phase active power of any Fmonitor + double Fvalue_Q; //This variable is used to store total measure three-phase reactive power of any Fmonitor + double F_P_one; + double F_Q_one;//measured power + double P_ref_one; //the ref Power for this point + int Node_num; // Node number within the cluster + int V_Sensor; // Voltage sensor enable variable + int P_Sensor; // Power sensor enable variable + int Cluster_num; // the group number for this + int Total_Clusters; //Total Number of the Groups in a circuit + + //communication time + double T_intvl_smpl; //Sampling interval. + int MaxLocalMem; //Max number of local memory, no large than 99 + int Smpl_stps; // T_Comm/ ActiveCircuit.Solution.Dynavars.h. + Arraydef::pDoubleArray pCommDelayMatrix; // + Arraydef::pSmallIntArray pCommDelaySteps;// Communication delay step matrix of this cluster + + // define properties for equivalent generator for simulate frequency + //eg_defed : boolean; //moved to public + //default 0.5s to flat the initial condition + // determine the input of PV: u_i = k_dltP * \Delta P + omg_fm + //delay to uppper level + double kVA_fm; + double M_fm; + double D_fm; + double Tau_fm; + double Ki_fm; + double Pm_fm; + double init_time; + double k_dltP; + double up_dly; //in seconds + //nup_dlys := up_dly / t_intvl_smpl; + int nup_dlys; + int virtual_Ld_Nd; // denotes which node talks to upper level + // default by 1; + + // attack and defense + bool d_atk_inited; + bool z_dfs_inited; // for attack initialization if attack is dynamic + int atk_node_num; //default no. 1; + //when the attack starts to work, default by 0.5s. + //defense index + //parameter for Kc (gradient control) + //attack on gradient control: 1: no attack; -1: make the gradient control work to the oppesite + double atk_time; + double beta_dfs; + double D_beta; + double D_p; + double dlt_z0; + Arraydef::pSmallIntArray pCommHide; // communication matrix of this cluster + Arraydef::pSmallIntArray pCommNode_Hide; // communication matrix of this cluster + + // + int Bus_code; + int NodeNum; + int Node_Ref; + /*------------*/ + String BufferFile; // Name of file for catching buffer overflow + bool IsFileOpen; + bool ValidMonitor; + bool IsProcessed; + + //Procedure AddDblsToBuffer(Dbl:pDoubleArray; Ndoubles:Integer); + //Procedure AddDblToBuffer(const Dbl:Double); + + //Procedure DoFlickerCalculations; // call from CloseMonitorStream + void Set_nodes_for_fm(int intNodes);//initiate the structure of this FMon + void Set_CommVector(String strParam); + void Set_CommVector_Hide(String strParam); + void Set_CommVector_NodeHide(String strParam); + // + void Set_volt_lmt_clstr(String strParam); + void Set_CommDelayVector(String strParam); + void ResetDelaySteps(int iNodeNum); + + //attack and defense + void update_attack(int ActorID); // update d_i + void update_defense(int ActorID);// update z_i + double organise_dfs_node(int j);// update z_i + + //Function fm_defense(i : integer): double; // calculate K_i z + void Set_atk_dfs(String strParam); + void Set_EquivalentGenerator(String strParam); + // + void Set_ElemTable_line(String strParam); + void Init_nodeFM(int iNodeNum, int ActorID); + //Procedure push_voltage; + void Get_PDElem_terminal_voltage(int nd_num_in_cluster, String devName, int Tern_num, int ActorID); // + void Calc_Alpha_for_PDNode(int NodeNum); + void update_all_nodes_info(int ActorID); + double AvgPmax(); + double AvgQmax(); + void Get_PQ_DI(int i_NodeNum, int ActorID); + double Calc_Grdt_for_Alpha(int NodeNuminClstr, int phase_num, int ActorID); + double Calc_Grdt_for_Alpha_vivj(int NodeNuminClstr, int phase_num, int ActorID); + double Getgradient(int j, int phase_num, double Bii, double Volt_Trhd); + double Calc_GP_AlphaP(int phase_num, int ActorID); + double Get_power_trans(int ActorID); + double Coef_Phi(double X); // a coeffient +public: + VLNodeVars::TVLNodeVars* pNodeFMs; + int Mode; + //MonitorStream :TMemoryStream; + int SampleCount; // This is the number of samples taken + /*-- overview information about this cluster--*/ + LD_fm_infos::TLD_fm_infos ld_fm_info[4/*# range 0..3*/]; + // define properties for equivalent generator for simulate frequency + bool eg_defed; //moved to public + double dlt_fm; + double omg_fm; + double comp_omg; // + + // define properties for attack and defense + bool atk; //default = false + bool dfs; //default = false + TFMonitorObj(DSSClass::TDSSClass* ParClass, const String MonitorName); + virtual ~TFMonitorObj(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, reset nphases + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a monitor + //Procedure TakeSample(ActorID : Integer); Override; // Go add a sample to the buffer + /**/ + //Procedure GetFvalue; + //Function PhaseDetect(Bus_name:string):Integer; + /**/ + void ResetIt(int ActorID); + void Save(); // Saves present buffer to file + //Procedure PostProcess(ActorID : Integer); // calculates Pst or other post-processing + // + double Calc_sum_dij_Alphaj(int NodeNumofDG, int phase_num, int ActorID); + //unified voltage (1-V_dg)^2 + double Calc_Alpha_M2(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + //minimize loss + double Calc_Alpha_L(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + double Calc_Alpha_L_vivj(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + double Calc_Alpha_LnM2(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + double Calc_AlphaP(int NodeNuminClstr, int phase_num, int ActorID); + int Get_P_mode(int ActorID); + + //Zero seq. + double Calc_fm_ul_0(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + double Calc_fm_us_0(int NodeNumofDG, int phase_num, int dbNodeRef, double Bii, double beta, double Volt_Trhd, int ActorID); + + // + void Agnt_smpl(int NodeNumofDG, int phase_num, int ActorID); // sample data of this node at each t_intvl_smpl + void Init_delay_array(int NodeNumofDG, int ActorID); + /*For real power control-dynamic simu*/ + double Calc_ul_P(int NodeNuminClstr, int phase_num); + double Calc_Gradient_ct_P(int NodeNuminClstr, int phase_num, int ActorID); // curtailment + /*--*/ + void update_node_info_each_time_step(int ActorID); //all nodes in the cluster + //Procedure update_ld_info( ActorID: integer); //all nodes in the cluster + void update_ld_dly(int ActorID); // all nodes in this cluster with delay + void Calc_P_freq_fm(int ActorID);// calculte frequency for each cluster + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + String Get_FileName(int ActorID); + + // Property CSVFileName:String Read Get_FileName; + TFMonitorObj(DSSClass::TDSSClass* ParClass); + TFMonitorObj(String ClassName); + TFMonitorObj(); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +extern TFMonitorObj* ActiveFMonitorObj; + +/*--------------------------------------------------------------------------*/ + + +} // namespace Fmonitor + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Fmonitor; +#endif + +#endif // FmonitorH + + + + + diff --git a/OpenDSSC/MyOpenDSS/MyDSSClassDefs.cpp b/OpenDSSC/MyOpenDSS/MyDSSClassDefs.cpp new file mode 100644 index 0000000..d1b56a4 --- /dev/null +++ b/OpenDSSC/MyOpenDSS/MyDSSClassDefs.cpp @@ -0,0 +1,35 @@ + +#pragma hdrstop + +#include "MyDSSClassDefs.h" +#include "DSSClass.h" + +using namespace std; + + +namespace MyDSSClassDefs +{ + + + /*Add Special Uses clauses here: */ + /*,MyDSSClass*/ + +void CreateMyDSSClasses() +{ + + /*Put your custom class instantiations here*/ + + /* Example: + DSSClasses.New := TMyDSSClass.Create; + + */ +} + + + + +} // namespace MyDSSClassDefs + + + + diff --git a/OpenDSSC/MyOpenDSS/MyDSSClassDefs.h b/OpenDSSC/MyOpenDSS/MyDSSClassDefs.h new file mode 100644 index 0000000..3402be2 --- /dev/null +++ b/OpenDSSC/MyOpenDSS/MyDSSClassDefs.h @@ -0,0 +1,33 @@ +#ifndef MyDSSClassDefsH +#define MyDSSClassDefsH + +#include "System.h" + + +namespace MyDSSClassDefs +{ + + + +/* + Prototype unit for creating custom version of DSS + +*/ +const int MYCLASS_ELEMENT_CONST = 99 * 8; // make unique constants for your classes + // SEE DSSClassDefs.pas + /*Assign (typically by adding) this constant to DSSClassType when objects of + your custom class are instantiated. See Tline.Create in Line.Pas, for example*/ +void CreateMyDSSClasses(); // Called in DSSClassDefs + + +} // namespace MyDSSClassDefs + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace MyDSSClassDefs; +#endif + +#endif // MyDSSClassDefsH + + + + diff --git a/OpenDSSC/PCElements/Equivalent.cpp b/OpenDSSC/PCElements/Equivalent.cpp new file mode 100644 index 0000000..2e2aa3c --- /dev/null +++ b/OpenDSSC/PCElements/Equivalent.cpp @@ -0,0 +1,762 @@ + +#pragma hdrstop + +#include "Equivalent.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Command.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace Equivalent +{ + +TEquivalentObj::TEquivalentObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TEquivalentObj::TEquivalentObj(String ClassName) : inherited(ClassName) {} +TEquivalentObj::TEquivalentObj() {} + + +TEquivalentObj* ActiveEquivalentObj = nullptr; +const int NumPropsThisClass = 16; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TEquivalent::TEquivalent() +{ + ; + Class_Name = "Equivalent"; + DSSClassType = SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TEquivalent::~TEquivalent() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TEquivalent::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "terminals"; + PropertyName[2 - 1] = "buses"; + PropertyName[3 - 1] = "basekv"; + PropertyName[4 - 1] = "pu"; + PropertyName[5 - 1] = "angle"; + PropertyName[6 - 1] = "frequency"; + PropertyName[7 - 1] = "phases"; + PropertyName[8 - 1] = "R1"; + PropertyName[9 - 1] = "X1"; + PropertyName[10 - 1] = "R0"; + PropertyName[11 - 1] = "X0"; + + // define Property help values + PropertyHelp[1 - 1] = "Number of terminals. Default =1. Set this BEFORE defining matrices."; + PropertyHelp[2 - 1] = String("Array of Bus Names to which equivalent source is connected.") + CRLF + + "buses=(b1 b2 b3)"; + PropertyHelp[3 - 1] = "Base Source kV, usually L-L unless you are making a positive-sequence model" + "in which case, it will be L-N."; + PropertyHelp[4 - 1] = String("Per unit of the base voltage that the source is actually operating at.") + CRLF + + "\"pu=1.05\""; + PropertyHelp[5 - 1] = "Phase angle in degrees of first phase: e.g.,Angle=10.3"; + PropertyHelp[6 - 1] = "Source frequency. Defaults to 60 Hz."; + PropertyHelp[7 - 1] = "Number of phases. Defaults to 3."; + PropertyHelp[8 - 1] = "Positive-sequence resistance matrix, lower triangle."; + PropertyHelp[9 - 1] = "Positive-sequence reactance matrix, lower triangle."; + PropertyHelp[10 - 1] = "Zero-sequence resistance matrix, lower triangle."; + PropertyHelp[11 - 1] = "Zero-sequence reactance matrix, lower triangle."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1 - 1] = "Name of harmonic spectrum for this source. Default is \"defaultvsource\", which is defined when the DSS starts."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEquivalent::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to Equivalent class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TEquivalentObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TEquivalent::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveEquivalentObj = (TEquivalentObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveEquivalentObj); + result = 0; + /*# with ActiveEquivalentObj do */ + { + auto with0 = ActiveEquivalentObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"Equivalent." + + with0->get_Name() + + "\"", 800); + break; + case 1: + ( (TDSSCktElement*) with0 )->Set_NTerms(with0->DoTerminalsDef(Parser[ActorID]->MakeInteger_())); + break; // This will allocate a bunch of stuff + case 2: + InterpretAllBuses(Param); + break; + case 3: + with0->kVBase = Parser[ActorID]->MakeDouble_(); + break; // basekv + case 4: + with0->PerUnit = Parser[ActorID]->MakeDouble_(); + break; // pu + case 5: + with0->Angle = Parser[ActorID]->MakeDouble_(); + break; // Ang + case 6: + with0->EquivFrequency = Parser[ActorID]->MakeDouble_(); + break; // freq + case 7: + { + ((TDSSCktElement*)with0)->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)with0)->Fnphases); // Force Reallocation of terminal info + } + break; + case 8: + with0->ParseDblMatrix(with0->R1); + break; + case 9: + with0->ParseDblMatrix(with0->X1); + break; + case 10: + with0->ParseDblMatrix(with0->R0); + break; + case 11: + with0->ParseDblMatrix(with0->X0); + break; + default: + inherited::ClassEdit(ActiveEquivalentObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 8: case 9: case 10: case 11: + with0->NeedToDoRecalc = true; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + + // RecalcElementData; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TEquivalent::MakeLike(const String OtherSource) +{ + int result = 0; + TEquivalentObj* OtherEquivalent = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherEquivalent = ((TEquivalentObj*) Find(OtherSource)); + if(OtherEquivalent != nullptr) + /*# with ActiveEquivalentObj do */ + { + auto with0 = ActiveEquivalentObj; + int stop = 0; + if(((with0)->Fnphases != (OtherEquivalent)->Fnphases) || ((with0)->Fnterms != (OtherEquivalent)->Fnterms)) + { + int stop = 0; + (with0)->Set_NTerms(with0->DoTerminalsDef((OtherEquivalent)->Fnterms)); + (with0)->Set_NPhases((OtherEquivalent)->Fnphases); + (with0)->Set_Nconds((with0)->Fnphases); // Forces reallocation of terminal stuff + (with0)->Yorder = (with0)->Fnconds * (with0)->Fnterms; + (with0)->Set_YprimInvalid(ActiveActor,true); + for(stop = (with0)->Fnterms, i = 1; i <= stop; i++) + { + (with0->R1)[i - 1] = (OtherEquivalent->R1)[i - 1]; + } + for(stop = (with0)->Fnterms, i = 1; i <= stop; i++) + { + (with0->R0)[i - 1] = (OtherEquivalent->R0)[i - 1]; + } + for(stop = (with0)->Fnterms, i = 1; i <= stop; i++) + { + (with0->X1)[i - 1] = (OtherEquivalent->X1)[i - 1]; + } + for(stop = (with0)->Fnterms, i = 1; i <= stop; i++) + { + (with0->X0)[i - 1] = (OtherEquivalent->X0)[i - 1]; + } + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + with0->Z = new TcMatrix(((TDSSCktElement*)with0)->Fnphases); + with0->Zinv = new TcMatrix(((TDSSCktElement*)with0)->Fnphases); + } + with0->Z->CopyFrom(OtherEquivalent->Z); + // Zinv.CopyFrom(OtherLine.Zinv); + with0->Vmag = OtherEquivalent->Vmag; + with0->kVBase = OtherEquivalent->kVBase; + with0->PerUnit = OtherEquivalent->PerUnit; + with0->Angle = OtherEquivalent->Angle; + with0->EquivFrequency = OtherEquivalent->EquivFrequency; + ClassMakeLike(OtherEquivalent); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->FPropertyValue[i - 1] = OtherEquivalent->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Equivalent MakeLike: \"") + OtherSource + + "\" Not Found.", 801); + return result; +} + +//---------------------------------------------------------------------------- + +int TEquivalent::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TEquivalent.Init", -1); + result = 0; + return result; +} + +//---------------------------------------------------------------------------- + +TEquivalentObj::TEquivalentObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + kVBase(115.0), + Vmag(0.0), + PerUnit(0.0), + Angle(0.0), + EquivFrequency(0.0), + R1(nullptr), + X1(nullptr), + R0(nullptr), + X0(nullptr), + NeedToDoRecalc(false), + Z(nullptr), + Zinv(nullptr) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; //SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + Set_NPhases(3); + Fnconds = 3; + Set_NTerms(1); + Z = nullptr; + Zinv = nullptr; + /*Basefrequency := 60.0;*/ // set in base class + R1 = nullptr; + X1 = nullptr; + R0 = nullptr; + X0 = nullptr; + ReallocRX(); + (R1)[1 - 1] = 1.65; + (X1)[1 - 1] = 6.6; + (R0)[1 - 1] = 1.9; + (X0)[1 - 1] = 5.7; + PerUnit = 1.0; + EquivFrequency = BaseFrequency; + Angle = 0.0; + Spectrum = "defaultvsource"; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + + +//---------------------------------------------------------------------------- + +TEquivalentObj::~TEquivalentObj() +{ + free(Z); + free(Zinv); + free(R1); + free(R0); + free(X1); + free(X0); + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + +void TEquivalentObj::RecalcElementData(int ActorID) +{ + complex Zs = {}; + complex ZM = {}; + int i = 0; + int j = 0; + int II = 0; + int jj = 0; + int IOffset = 0; + int joffset = 0; + int indx = 0; + + auto Idx = [&](int A, int B) -> int + { + int result = 0; + result = (B - 1) * Fnterms + A; + return result; + }; + int stop = 0; + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + + // For a Source, nphases = ncond, for now + Z = new TcMatrix(Fnphases * Fnterms); + Zinv = new TcMatrix(Fnphases * Fnterms); + + // Build Z matrix for all phases + for(stop = Fnterms, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnterms, j = 1; j <= stop1; j++) + { + int stop2 = 0; + indx = Idx(i, j); + Zs = cdivreal(cmplx(2.0 * (R1)[indx - 1] + (R0)[indx - 1], 2.0 * (X1)[indx - 1] + (X0)[indx - 1]), 3.0); + ZM = cdivreal(cmplx((R0)[indx - 1] - (R1)[indx - 1], (X0)[indx - 1] - (X1)[indx - 1]), 3.0); + IOffset = (i - 1) * Fnphases; + joffset = (j - 1) * Fnphases; + for(stop2 = Fnphases, II = 1; II <= stop2; II++) + { + int stop3 = 0; + for(stop3 = II, jj = 1; jj <= stop3; jj++) + { + if(II == jj) + Z->SetElement(II + IOffset, jj + joffset, Zs); + else + { + Z->SetElement(II + IOffset, jj + joffset, ZM); + Z->SetElement(jj + IOffset, II + joffset, ZM); // set other offdiagonal in this submatrix + } + } + } + } + } + + // Voltage source properties + switch(Fnphases) + { + case 1: + Vmag = kVBase * PerUnit * 1000.0; + break; + default: + Vmag = kVBase * PerUnit * 1000.0 / 2.0 / sin((180.0 / Fnphases) * DSSGlobals::PI / 180.0L); + break; + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + { + DoSimpleMsg(String("Spectrum Object \"") + Spectrum + + "\" for Device Equivalent." + + get_Name() + + " Not Found.", 802); + } + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder);; + NeedToDoRecalc = false; +} + +//---------------------------------------------------------------------------- + +void TEquivalentObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + + // Build only YPrim Series + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + if(NeedToDoRecalc) + RecalcElementData(ActorID); + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /* Put in Series RL matrix Adjusted for frequency */ + for(stop = Yorder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Yorder, j = 1; j <= stop1; j++) + { + Value = Z->GetElement(i, j); + Value.im = Value.im * FreqMultiplier; /*Modify from base freq*/ + Zinv->SetElement(i, j, Value); + } + } + Zinv->Invert(); /*Invert in place*/ + if(Zinv->InvertError > 0) /*If error, put in Large series conductance*/ + { + int stop = 0; + DoErrorMsg("TEquivalentObj.CalcYPrim", String("Matrix Inversion Error for Equivalent \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with small resistance.", 803); + Zinv->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, cmplx(1.0 / EPSILON, 0.0)); + } + } + YPrim_Series->CopyFrom(Zinv); + YPrim->CopyFrom(YPrim_Series); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +//==================================== + +void TEquivalentObj::GetVterminalForSource() +{ + int i = 0; + complex Vharm = {}; + double EquivHarm = 0.0; + try + + + /*This formulation will theoretically handle voltage sources of any number of phases assuming they are + equally displaced in time.*/ + { + switch(Fnphases) + { + case 1: + Vmag = kVBase * PerUnit * 1000.0; + break; + default: + Vmag = kVBase * PerUnit * 1000.0 / 2.0 / sin((180.0 / Fnphases) * DSSGlobals::PI / 180.0L); + break; + } + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + if(with0->IsHarmonicModel) + { + int stop = 0; + EquivHarm = with0->get_FFrequency() / EquivFrequency; + Vharm = cmulreal(SpectrumObj->GetMult(EquivHarm), Vmag); // Base voltage for this harmonic + RotatePhasorDeg(Vharm, EquivHarm, Angle); // Rotate for phase 1 shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = Vharm; + if(i < Fnphases) + RotatePhasorDeg(Vharm, EquivHarm, -360.0 / Fnphases); + } + } + else + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle - (i - 1) * 360.0 / Fnphases)); + } + } + } + } + catch(...) + { + DoSimpleMsg(String("Error computing Voltages for Equivalent.") + get_Name() + + ". Check specification. Aborting.", 804); + if(In_Redirect) + Redirect_Abort = true; + } +} + +//==================================== + +int TEquivalentObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + +/*This is source injection*/ + result = inherited::InjCurrents(ActorID); // Add into system array + return result; +} + +//==================================== + +void TEquivalentObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + //FOR i := 1 TO (Nterms * NConds) DO Vtemp^[i] := V^[NodeRef^[i]]; + // This is safer 12/7/99 + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = with0->NodeV[(NodeRef)[i - 1]]; + } + YPrim->MVmult(Curr, &(Vterminal[0])); + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = csub((Curr)[i - 1], (ComplexBuffer)[i - 1]); + } + } /*With*/ + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element.", 805); + } +} + + +//==================================== + +void TEquivalentObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + GetVterminalForSource(); + YPrim->MVmult(Curr, &(Vterminal[0])); /*I = Y V*/ + set_ITerminalUpdated(false, ActorID); +} + +void TEquivalentObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + complex C = {}; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + { Write(f, "VMag="); WriteLn(f, Vmag, 0, 2); } + WriteLn(f, "Z Matrix="); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + C = Z->GetElement(i, j); + { Write(f, C.re, 0, 3); Write(f, " + j"); Write(f, C.im, 0, 3); } + } + WriteLn(f); + } + } +} + +void TEquivalentObj::InitPropertyValues(int ArrayOffset) +{ + +/* + + PropertyName[1] := 'terminals'; + PropertyName[2] := 'buses'; + PropertyName[3] := 'basekv'; + PropertyName[4] := 'pu'; + PropertyName[5] := 'angle'; + PropertyName[6] := 'frequency'; + PropertyName[7] := 'phases'; + PropertyName[8] := 'R1'; + PropertyName[9] := 'X1'; + PropertyName[10] := 'R0'; + PropertyName[11] := 'X0'; +*/ + /*PropertyValue Allocated in DSSObject.Create*/ + Set_PropertyValue(1,"1"); + Set_PropertyValue(2,GetBus(1)); + Set_PropertyValue(3,"115"); + Set_PropertyValue(4,"1"); + Set_PropertyValue(5,"0"); + Set_PropertyValue(6,"60"); + Set_PropertyValue(7,"3"); + Set_PropertyValue(8,"1.65"); + Set_PropertyValue(9,"6.6"); + Set_PropertyValue(10,"1.9"); + Set_PropertyValue(11,"5.7"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +String TEquivalentObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +void TEquivalentObj::MakePosSequence(int ActorID) +{ + String s; + + +/// ???? + s = "Phases=1 "; + s = s + Format("BasekV=%-.5g ",kVBase / SQRT3); + s = s + Format("R1=%-.5g ",(R1)[0]); + s = s + Format("X1=%-.5g ",(X1)[0]); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + TDSSCktElement::MakePosSequence(ActorID); +} + +int TEquivalentObj::DoTerminalsDef(int n) +{ + int result = 0; + result = Fnterms; + if(n != Fnterms) + { + if(n > 0) + ReallocRX(); + } + return result; +} + +// Parse input string as an array + +void TEquivalentObj::ParseDblMatrix(pDoubleArray Mat) +{ + Parser[ActiveActor]->ParseAsSymMatrix(Fnterms, Mat); +} + +void TEquivalentObj::ReallocRX() +{ + R1 = (pDoubleArray)realloc(R1, sizeof(double) * Sqr(Fnterms)); + X1 = (pDoubleArray)realloc(X1, sizeof(double) * Sqr(Fnterms)); + R0 = (pDoubleArray)realloc(R0, sizeof(double) * Sqr(Fnterms)); + X0 = (pDoubleArray)realloc(X0, sizeof(double) * Sqr(Fnterms)); +} +// routine expecting all winding connections expressed in one array of strings + +void TEquivalent::InterpretAllBuses(const String s) +{ + String S1; + String BusNam; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveEquivalentObj do */ + { + auto with0 = ActiveEquivalentObj; + int stop = 0; + for(stop = with0->Fnterms, i = 1; i <= stop; i++) + { + S1 = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + BusNam = AuxParser[ActiveActor]->MakeString_(); + if(BusNam.size() > 0) + with0->SetBus(i, BusNam); + } + } +} + + + + +} // namespace Equivalent + + + + diff --git a/OpenDSSC/PCElements/Equivalent.h b/OpenDSSC/PCElements/Equivalent.h new file mode 100644 index 0000000..2b6e738 --- /dev/null +++ b/OpenDSSC/PCElements/Equivalent.h @@ -0,0 +1,107 @@ +#ifndef EquivalentH +#define EquivalentH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "d2c_structures.h" + +namespace Equivalent +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Multi terminal, multi-phase Short Circuit (Thevinen) Equivalent + + Enter positive and zero short circuit impedance matrices + And Voltage behind the equivalent +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TEquivalent : public PCClass::TPCClass +{ + friend class TEquivalentObj; +public: + typedef PCClass::TPCClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); + void InterpretAllBuses(const String s); +public: + TEquivalent(); + virtual ~TEquivalent(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TEquivalentObj : public PCElement::TPCElement +{ + friend class TEquivalent; +public: + typedef PCElement::TPCElement inherited; +//private: + double kVBase; + double Vmag; + double PerUnit; + double Angle; + double EquivFrequency; + Arraydef::pDoubleArray R1; + Arraydef::pDoubleArray X1; + Arraydef::pDoubleArray R0; + Arraydef::pDoubleArray X0; + bool NeedToDoRecalc; + void GetVterminalForSource(); + void ReallocRX(); + void ParseDblMatrix(Arraydef::pDoubleArray Mat); + int DoTerminalsDef(int n); +public: + Ucmatrix::TcMatrix* Z; // Base Frequency Series Z matrix + Ucmatrix::TcMatrix* Zinv; + TEquivalentObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TEquivalentObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + TEquivalentObj(DSSClass::TDSSClass* ParClass); + TEquivalentObj(String ClassName); + TEquivalentObj(); +}; +extern TEquivalentObj* ActiveEquivalentObj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace Equivalent + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Equivalent; +#endif + +#endif // EquivalentH + + + + diff --git a/OpenDSSC/PCElements/GICLine.cpp b/OpenDSSC/PCElements/GICLine.cpp new file mode 100644 index 0000000..2765a55 --- /dev/null +++ b/OpenDSSC/PCElements/GICLine.cpp @@ -0,0 +1,838 @@ + +#pragma hdrstop + +#include "GICLine.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "MyDSSClassDefs.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Command.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace MyDSSClassDefs; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace GICLine +{ + +TGICLineObj::TGICLineObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGICLineObj::TGICLineObj(String ClassName) : inherited(ClassName) {} +TGICLineObj::TGICLineObj() {} + + +TGICLineObj* ActiveGICLineObj = nullptr; +const int NumPropsThisClass = 15; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TGICLine::TGICLine() +{ + ; + Class_Name = "GICLine"; + DSSClassType = GIC_Line + PC_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGICLine::~TGICLine() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICLine::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1- 1 ] = "bus1"; + PropertyName[2- 1 ] = "bus2"; + PropertyName[3- 1 ] = "Volts"; + PropertyName[4- 1 ] = "Angle"; + PropertyName[5- 1 ] = "frequency"; + PropertyName[6- 1 ] = "phases"; + PropertyName[7- 1 ] = L'R'; + PropertyName[8- 1 ] = L'X'; + PropertyName[9- 1 ] = L'C'; + // PropertyName[10] := 'ScanType'; + // PropertyName[11] := 'Sequence'; + PropertyName[10- 1 ] = "EN"; + PropertyName[11- 1 ] = "EE"; + PropertyName[12- 1 ] = "Lat1"; + PropertyName[13- 1 ] = "Lon1"; + PropertyName[14- 1 ] = "Lat2"; + PropertyName[15- 1 ] = "Lon2"; + + // define Property help values + PropertyHelp[1- 1 ] = String("Name of bus to which the main terminal (1) is connected.") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3"; + PropertyHelp[2- 1 ] = String("Name of bus to which 2nd terminal is connected.") + CRLF + + "bus2=busname" + + CRLF + + "bus2=busname.1.2.3" + + CRLF + + CRLF + + "No Default; must be specified."; + PropertyHelp[3- 1 ] = String("Voltage magnitude, in volts, of the GIC voltage induced across this line. " "When spedified, voltage source is assumed defined by Voltage and Angle properties. ") + CRLF + + CRLF + + "Specify this value" + + CRLF + + CRLF + + "OR" + + CRLF + + CRLF + + "EN, EE, lat1, lon1, lat2, lon2. " + + CRLF + + CRLF + + "Not both!! Last one entered will take precedence. " + + "Assumed identical in each phase of the Line object."; + PropertyHelp[4- 1 ] = "Phase angle in degrees of first phase. Default=0.0. See Voltage property"; + PropertyHelp[5- 1 ] = "Source frequency. Defaults to 0.1 Hz."; + PropertyHelp[6- 1 ] = "Number of phases. Defaults to 3."; + PropertyHelp[7- 1 ] = "Resistance of line, ohms of impedance in series with GIC voltage source. "; + PropertyHelp[8- 1 ] = "Reactance at base frequency, ohms. Default = 0.0. This value is generally not important for GIC studies but may be used if desired."; + PropertyHelp[9- 1 ] = "Value of line blocking capacitance in microfarads. Default = 0.0, implying that there is no line blocking capacitor."; + // PropertyHelp[10] := '{pos | zero* | none} Maintain specified sequence for harmonic solution. Default is ZERO sequence. '+ + // 'Otherwise, angle between phases rotates with harmonic.'; + // PropertyHelp[11] := '{pos | neg | zero*} Set the phase angles for the specified symmetrical component sequence for non-harmonic solution modes. '+ + // 'Default is ZERO sequence. '; + PropertyHelp[10- 1 ] = "Northward Electric field (V/km). If specified, Voltage and Angle are computed from EN, EE, lat and lon values."; + PropertyHelp[11- 1 ] = "Eastward Electric field (V/km). If specified, Voltage and Angle are computed from EN, EE, lat and lon values."; + PropertyHelp[12- 1 ] = "Latitude of Bus1 (degrees)"; + PropertyHelp[13- 1 ] = "Longitude of Bus1 (degrees)"; + PropertyHelp[14- 1 ] = "Latitude of Bus2 (degrees)"; + PropertyHelp[15- 1 ] = "Longitude of Bus2 (degrees)"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1] = "Inherited Property for all PCElements. Name of harmonic spectrum for this source. Default is \"defaultvsource\", which is defined when the DSS starts."; + PropertyHelp[NumPropsThisClass + 2] = "Inherited Property for all PCElements. Base frequency for specification of reactance value."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICLine::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to GICLine class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGICLineObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICLine::GICLineSetBus1(const String s) +{ + String S2; + int dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveGICLineObj do */ + { + auto with0 = ActiveGICLineObj; + with0->SetBus(1, s); + + // Strip node designations from S + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); // copy up to Dot + with0->SetBus(2, S2); // default setting for Bus2 is same as Bus1 + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICLine::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveGICLineObj = (TGICLineObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGICLineObj); + result = 0; + /*# with ActiveGICLineObj do */ + { + auto with0 = ActiveGICLineObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"VSource." + + with0->get_Name() + + "\"", 320); + break; + case 1: + GICLineSetBus1(Param); + break; // special handling of Bus 1 + case 2: + with0->SetBus(2, Param); + break; + case 3: + with0->Volts = Parser[ActorID]->MakeDouble_(); + break; // basekv + case 4: + with0->Angle = Parser[ActorID]->MakeDouble_(); + break; // Ang + case 5: + with0->SrcFrequency = Parser[ActorID]->MakeDouble_(); + break; // freq + case 6: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + } + break; + case 7: + with0->R = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->X = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->C = Parser[ActorID]->MakeDouble_(); + break; + + /* 10: Case Uppercase(Param)[1] of + 'P': ScanType := 1; + 'Z': ScanType := 0; + 'N': ScanType := -1; + ELSE + DoSimpleMsg('Unknown Scan Type for "' + Class_Name +'.'+ Name + '": '+Param, 321); + END; + 11: Case Uppercase(Param)[1] of + 'P': Sequencetype := 1; + 'Z': Sequencetype := 0; + 'N': Sequencetype := -1; + ELSE + DoSimpleMsg('Unknown Sequence Type for "' + Class_Name +'.'+ Name + '": '+Param, 321); + END; + */ + case 10: + with0->ENorth = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->EEast = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->Lat1 = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->Lon1 = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->Lat2 = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->Lon2 = Parser[ActorID]->MakeDouble_(); + break; + default: + inherited::ClassEdit(ActiveGICLineObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 3: case 4: + with0->VoltsSpecified = true; + break; + case 10: case 11: case 12: case 13: case 14: case 15: + with0->VoltsSpecified = false; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TGICLine::MakeLike(const String OtherLine) +{ + int result = 0; + TGICLineObj* OtherGICLine = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherGICLine = ((TGICLineObj*) Find(OtherLine)); + if(OtherGICLine != nullptr) + /*# with ActiveGICLineObj do */ + { + auto with0 = ActiveGICLineObj; + int stop = 0; + if(with0->Fnphases != OtherGICLine->Fnphases) + { + with0->Set_NPhases(OtherGICLine->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + with0->Z = new TcMatrix(with0->Fnphases); + with0->Zinv = new TcMatrix(with0->Fnphases); + } + with0->Z->CopyFrom(OtherGICLine->Z); + // Zinv.CopyFrom(OtherLine.Zinv); + with0->R = OtherGICLine->R; + with0->X = OtherGICLine->X; + with0->C = OtherGICLine->C; + with0->Volts = OtherGICLine->Volts; + with0->Angle = OtherGICLine->Angle; + with0->SrcFrequency = OtherGICLine->SrcFrequency; + with0->ScanType = OtherGICLine->ScanType; + with0->SequenceType = OtherGICLine->SequenceType; + ClassMakeLike(OtherGICLine); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->FPropertyValue[i - 1] = OtherGICLine->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in GICLine MakeLike: \"") + OtherLine + + "\" Not Found.", 322); + return result; +} + +//---------------------------------------------------------------------------- + +int TGICLine::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TGICLine.Init", -1); + result = 0; + return result; +} + +//============================================================================= + +double TGICLineObj::Compute_VLine() +{ + double result = 0.0; + double pHi = 0.0; + double DeltaLat = 0.0; + double DeltaLon = 0.0; + pHi = (Lat2 + Lat1) / 2.0 * (double(DSSGlobals::PI) / 180.0); // deg to radians + DeltaLat = Lat2 - Lat1; + DeltaLon = Lon2 - Lon1; + VE = (111.133 - 0.56 * cos(2.0 * pHi)) * DeltaLat * ENorth; + Vn = (111.5065L - 0.1872L * cos(2.0 * pHi)) * cos(pHi) * DeltaLon * EEast; + result = Vn + VE; + return result; +} + +TGICLineObj::TGICLineObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + Angle(0.0), + Volts(0.0), + Vmag(0.0), + SrcFrequency(0.0), + R(0.0), + X(0.0), + C(0.0), + ENorth(0.0), + EEast(0.0), + Lat1(0.0), + Lon1(0.0), + Lat2(0.0), + Lon2(0.0), + Vn(0.0), + VE(0.0), + ScanType(0), + SequenceType(0), + VoltsSpecified(false), + Z(nullptr), + Zinv(nullptr) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; //SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + Set_NPhases(3); + Fnconds = 3; + Set_NTerms(2); // Now a 2-terminal device + Z = nullptr; + Zinv = nullptr; + /*Basefrequency := 60.0;*/ // set in base class + R = 1.0; + X = 0.0; + C = 0.0; + ENorth = 1.0; + EEast = 1.0; + Lat1 = 33.613499; + Lon1 = -87.373673; + Lat2 = 33.547885; + Lon2 = -86.074605; + VoltsSpecified = false; + SrcFrequency = 0.1; // Typical GIC study frequency + ScanType = 0; + SequenceType = 0; // default to zero sequence (same voltage induced in all phases) + Spectrum = ""; // no default + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + + +//============================================================================= + +TGICLineObj::~TGICLineObj() +{ + delete Z; + delete Zinv; + // inherited::Destroy(); +} + + +//============================================================================= + +void TGICLineObj::RecalcElementData(int ActorID) +{ + complex Zs = {}; + complex ZM = {}; + int i = 0; + int j = 0; + int stop = 0; + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + + // For a Source, nphases = ncond, for now + Z = new TcMatrix(Fnphases); + Zinv = new TcMatrix(Fnphases); + + /*Update property Value array*/ + /* Don't change a specified value; only computed ones*/ + Zs = cmplx(R, X); + ZM = CZero; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + Z->SetElement(i, i, Zs); + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Z->SetElemsym(i, j, ZM); + } + } + if(!VoltsSpecified) + Volts = Compute_VLine(); + Vmag = Volts; + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if((SpectrumObj == nullptr) && (Spectrum.size() > 0)) + { + DoSimpleMsg(String("Spectrum Object \"") + Spectrum + + "\" for Device GICLine." + + get_Name() + + " Not Found.", 324); + } + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder); +} + +//============================================================================= + +void TGICLineObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + double xc = 0.0; + + // Build only YPrim Series + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /* Put in Series RL Adjusted for frequency */ + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Z->GetElement(i, j); + Value.im = Value.im * FreqMultiplier; /*Modify from base freq*/ + Zinv->SetElement(i, j, Value); + } + } + if(C > 0.0) // Add 1/wC into diagonals of Zinv + { + int stop = 0; + xc = -1.0 / (TwoPi * FYprimFreq * C * 1.0e-6); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->AddElement(i, i, cmplx(0.0, xc)); + } + } + Zinv->Invert(); /*Invert in place*/ + if(Zinv->InvertError > 0) /*If error, put in Large series conductance*/ + { + int stop = 0; + DoErrorMsg("TGICLineObj.CalcYPrim", String("Matrix Inversion Error for GICLine \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with small resistance.", 325); + Zinv->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, cmplx(1.0 / EPSILON, 0.0)); + } + } + + // YPrim_Series.CopyFrom(Zinv); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zinv->GetElement(i, j); + YPrim_Series->SetElement(i, j, Value); + YPrim_Series->SetElement(i + Fnphases, j + Fnphases, Value); + YPrim_Series->SetElemsym(i + Fnphases, j, cnegate(Value)); + } + } + YPrim->CopyFrom(YPrim_Series); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +//============================================================================= + +void TGICLineObj::GetVterminalForSource() +{ + int i = 0; + complex Vharm = {}; + double SrcHarmonic = 0.0; + try + + + /*This formulation will theoretically handle voltage sources of any number of phases assuming they are + equally displaced in time.*/ + { + Vmag = Volts; + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + if(with0->IsHarmonicModel && (SpectrumObj != nullptr)) + { + int stop = 0; + SrcHarmonic = with0->get_FFrequency() / SrcFrequency; + Vharm = cmulreal(SpectrumObj->GetMult(SrcHarmonic), Vmag); // Base voltage for this harmonic + RotatePhasorDeg(Vharm, SrcHarmonic, Angle); // Rotate for phase 1 shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = Vharm; + (Vterminal)[i + Fnphases - 1] = CZero; + if(i < Fnphases) + { + switch(ScanType) + { + case 1: + RotatePhasorDeg(Vharm, 1.0, -360.0 / Fnphases); + break; // maintain pos seq + case 0: + ; + break; // Do nothing for Zero Sequence; All the same + default: + RotatePhasorDeg(Vharm, SrcHarmonic, -360.0 / Fnphases); // normal rotation + break; + } + } + } + } + else + // non-harmonic modes or no spectrum + { + int stop = 0; + if(Abs((int) (with0->get_FFrequency() - SrcFrequency)) > EPSILON2) + Vmag = 0.0; // Solution Frequency and Source Frequency don't match! + /*NOTE: RE-uses VTerminal space*/ + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(SequenceType) + { + case -1: // Always 0 for GIC + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle + (i - 1) * 360.0 / Fnphases)); + break; // neg seq + case 0: + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle)); + break; // all the same for zero sequence + default: + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle - (i - 1) * 360.0 / Fnphases)); + break; + } + // bottom part of the vector is zero + (Vterminal)[i + Fnphases - 1] = CZero; // See comments in GetInjCurrents + } + } + } + } + catch(...) + { + DoSimpleMsg(String("Error computing Voltages for GICLine.") + get_Name() + + ". Check specification. Aborting.", 326); + if(In_Redirect) + Redirect_Abort = true; + } +} + +//=========================================================================== + +int TGICLineObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + +/*This is source injection*/ + result = inherited::InjCurrents(ActorID); // Add into system array + return result; +} + +//=========================================================================== + +void TGICLineObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (Vterminal)[i - 1] = with0->NodeV[(NodeRef)[i - 1]]; + else + (Vterminal)[i - 1] = with0->VoltInActor1((NodeRef)[i - 1]); + } + YPrim->MVmult(Curr, &(Vterminal[0])); // Current from Elements in System Y + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = csub((Curr)[i - 1], (ComplexBuffer)[i - 1]); + } + } /*With*/ + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element.", 327); + } +} + + +//============================================================================= + +void TGICLineObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + + + /* source injection currents given by this formula: + _ _ _ _ + |Iinj1| |GICLine | + | | = [Yprim] | | + |Iinj2| | 0 | + _ _ _ _ + */ + GetVterminalForSource(); // gets voltage vector above + YPrim->MVmult(Curr, &(Vterminal[0])); + set_ITerminalUpdated(false, ActorID); +} + +//============================================================================= + +void TGICLineObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + complex C = {}; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + { Write(f, "Volts="); WriteLn(f, Volts, 0, 2); } + { Write(f, "VMag="); WriteLn(f, Vmag, 0, 2); } + { Write(f, "VE="); WriteLn(f, VE, 0, 4); } + { Write(f, "VN="); WriteLn(f, Vn, 0, 4); } + WriteLn(f, "Z Matrix="); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + C = Z->GetElement(i, j); + Write(f, Format("%.8g +j %.8g ", C.re, C.im)); + } + WriteLn(f); + } + } +} + + +//============================================================================= + +void TGICLineObj::InitPropertyValues(int ArrayOffset) +{ + + + /*PropertyValue Allocated in DSSObject.Create*/ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,"0.0"); + Set_PropertyValue(4,"0"); + Set_PropertyValue(5,"0.1"); + Set_PropertyValue(6,"3"); + Set_PropertyValue(7,"1.0"); + Set_PropertyValue(8,"0"); + Set_PropertyValue(9,"0"); + + // Set_PropertyValue(10] := 'zero'); + // Set_PropertyValue(11] := 'zero'); + Set_PropertyValue(10,"1.0"); + Set_PropertyValue(11,"1.0"); + Set_PropertyValue(12,"33.613499"); + Set_PropertyValue(13,"-87.373673"); + Set_PropertyValue(14,"33.547885"); + Set_PropertyValue(15,"-86.074605"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +//============================================================================= + +String TGICLineObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = GetBus(1); + break; + case 2: + result = GetBus(2); + break; + case 3: + result = Format("%.8g", Volts); + break; + case 4: + result = Format("%.8g", Angle); + break; + case 5: + result = Format("%.8g", SrcFrequency); + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +//============================================================================= + +void TGICLineObj::MakePosSequence(int ActorID) +{ + String s; + s = "Phases=1 "; + s = s + Format("Voltage=%-.8g Angle=%=.5g", Volts, Angle); + s = s + Format("R=%-.8g ", R); + s = s + Format("X=%-.8g ", X); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + TDSSCktElement::MakePosSequence(ActorID); +} + + + + +} // namespace GICLine + + + + diff --git a/OpenDSSC/PCElements/GICLine.h b/OpenDSSC/PCElements/GICLine.h new file mode 100644 index 0000000..3481928 --- /dev/null +++ b/OpenDSSC/PCElements/GICLine.h @@ -0,0 +1,134 @@ +#ifndef GICLineH +#define GICLineH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Spectrum.h" +#include "d2c_structures.h" + + + +namespace GICLine +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 6-23-2011 Created from VSource object + + Simplified 2-terminal VSource with series impedance for GIC studies. + For representing induced voltages in lines + + Contains blocking capacitor inherent in model. Set C > 0.0 to activate. + + Blocking capacitors may also be added as separate items or the branch may be + disconnected. + + Example: + New GICline.Myline Bus1=MyBus1 Bus2=MyBus2 Volts=1234 R=0.5 + + This takes the following defaults: + Angle=0 + X=0 + C=0 + Frequency=0.1 Hz + Sequence = ZERO sequence + ScanType = ZERO sequence + + +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGICLine : public PCClass::TPCClass +{ + friend class TGICLineObj; +public: + typedef PCClass::TPCClass inherited; +private: + void GICLineSetBus1(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherLine); +public: + TGICLine(); + virtual ~TGICLine(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGICLineObj : public PCElement::TPCElement +{ + friend class TGICLine; +public: + typedef PCElement::TPCElement inherited; +private: + double Angle; + double Volts; + double Vmag; // Present voltage magnitude + double SrcFrequency; + double R; + double X; + double C; + double ENorth; + double EEast; + double Lat1; + double Lon1; + double Lat2; + double Lon2; + double Vn; + double VE; // components of vmag + int ScanType; + int SequenceType; + bool VoltsSpecified; + void GetVterminalForSource(); + double Compute_VLine(); +public: + Ucmatrix::TcMatrix* Z; // Base Frequency Series Z matrix + Ucmatrix::TcMatrix* Zinv; + TGICLineObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TGICLineObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + TGICLineObj(DSSClass::TDSSClass* ParClass); + TGICLineObj(String ClassName); + TGICLineObj(); +}; +extern TGICLineObj* ActiveGICLineObj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace GICLine + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GICLine; +#endif + +#endif // GICLineH + + + + diff --git a/OpenDSSC/PCElements/GICsource.cpp b/OpenDSSC/PCElements/GICsource.cpp new file mode 100644 index 0000000..453065f --- /dev/null +++ b/OpenDSSC/PCElements/GICsource.cpp @@ -0,0 +1,649 @@ + +#pragma hdrstop + +#include "GICsource.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Command.h" +#include "Dynamics.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace Line; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace GICsource +{ + +TGICSourceObj::TGICSourceObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGICSourceObj::TGICSourceObj(String ClassName) : inherited(ClassName) {} +TGICSourceObj::TGICSourceObj() {} + + +TGICSourceObj* ActiveGICsourceObj = nullptr; +TGICsource* GICsourceClass = nullptr; +int NumPropsThisClass = 0; + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TGICsource::TGICsource() +{ + ; + Class_Name = "GICsource"; + DSSClassType = SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + GICsourceClass = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGICsource::~TGICsource() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICsource::DefineProperties() +{ + NumPropsThisClass = 10; + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "Volts"; + PropertyName[2 - 1] = "angle"; + PropertyName[3 - 1] = "frequency"; + PropertyName[4 - 1] = "phases"; + PropertyName[5 - 1] = "EN"; + PropertyName[6 - 1] = "EE"; + PropertyName[7 - 1] = "Lat1"; + PropertyName[8 - 1] = "Lon1"; + PropertyName[9 - 1] = "Lat2"; + PropertyName[10 - 1] = "Lon2"; + + // define Property help values + PropertyHelp[1 - 1] = String("Voltage magnitude, in volts, of the GIC voltage induced across the associated line. " "When specified, induced voltage is assumed defined by Voltage and Angle properties. ") + CRLF + + CRLF + + "Specify this value" + + CRLF + + CRLF + + "OR" + + CRLF + + CRLF + + "EN, EE, lat1, lon1, lat2, lon2. " + + CRLF + + CRLF + + "Not both!! Last one entered will take precedence. " + + "Assumed identical in each phase of the Line object."; + PropertyHelp[2 - 1] = "Phase angle in degrees of first phase. Default=0.0. See Voltage property"; + PropertyHelp[3 - 1] = "Source frequency. Defaults to 0.1 Hz. So GICSource=0 at power frequency."; + PropertyHelp[4 - 1] = "Number of phases. Defaults to 3. All three phases are assumed in phase (zero sequence)"; + PropertyHelp[5 - 1] = "Northward Electric field (V/km). If specified, Voltage and Angle are computed from EN, EE, lat and lon values."; + PropertyHelp[6 - 1] = "Eastward Electric field (V/km). If specified, Voltage and Angle are computed from EN, EE, lat and lon values."; + PropertyHelp[7 - 1] = "Latitude of Bus1 of the line(degrees)"; + PropertyHelp[8 - 1] = "Longitude of Bus1 of the line (degrees)"; + PropertyHelp[9 - 1] = "Latitude of Bus2 of the line (degrees)"; + PropertyHelp[10 - 1] = "Longitude of Bus2 of the line (degrees)"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1] = "Not used."; + PropertyHelp[NumPropsThisClass + 2] = "Not used."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICsource::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to GICsource class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGICSourceObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICsource::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveGICsourceObj = (TGICSourceObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGICsourceObj); + result = 0; + /*# with ActiveGICsourceObj do */ + { + auto with0 = ActiveGICsourceObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 330); + break; + case 1: + with0->Volts = Parser[ActorID]->MakeDouble_(); + break; + case 2: + with0->Angle = Parser[ActorID]->MakeDouble_(); + break; // Ang + case 3: + with0->SrcFrequency = Parser[ActorID]->MakeDouble_(); + break; // freq Usually 0.1 Hz + case 4: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + with0->FphaseShift = 0.0; // Zero Sequence + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + } + break; + case 5: + with0->ENorth = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->EEast = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->Lat1 = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->Lon1 = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->Lat2 = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->Lon2 = Parser[ActorID]->MakeDouble_(); + break; + default: + inherited::ClassEdit(ActiveGICsourceObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 2: + with0->VoltsSpecified = true; + break; + case 5: case 6: case 7: case 8: case 9: case 10: + with0->VoltsSpecified = false; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TGICsource::MakeLike(const String OtherSource) +{ + int result = 0; + TGICSourceObj* OtherGICsource = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherGICsource = ((TGICSourceObj*) Find(OtherSource)); + if(OtherGICsource != nullptr) + /*# with ActiveGICsourceObj do */ + { + auto with0 = ActiveGICsourceObj; + int stop = 0; + if(with0->Fnphases != OtherGICsource->Fnphases) + { + with0->Set_NPhases(OtherGICsource->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->Volts = OtherGICsource->Volts; + with0->Angle = OtherGICsource->Angle; + with0->SrcFrequency = OtherGICsource->SrcFrequency; + with0->LineName = OtherGICsource->LineName; + with0->ENorth = OtherGICsource->ENorth; + with0->EEast = OtherGICsource->EEast; + with0->Lat1 = OtherGICsource->Lat1; + with0->Lon1 = OtherGICsource->Lon1; + with0->Lat2 = OtherGICsource->Lat2; + with0->Lon2 = OtherGICsource->Lon2; + with0->Bus2Defined = OtherGICsource->Bus2Defined; + ClassMakeLike(OtherGICsource); // set spectrum, base frequency + with0->Spectrum = ""; // Spectrum not allowed + with0->SpectrumObj = nullptr; + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherGICsource->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in GICsource MakeLike: \"") + OtherSource + + "\" Not Found.", 332); + return result; +} + +//---------------------------------------------------------------------------- + +int TGICsource::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TGICsource.Init", -1); + result = 0; + return result; +} + + +//---------------------------------------------------------------------------- + +TGICSourceObj::TGICSourceObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + FphaseShift(0.0), + Bus2Defined(false), + Vmag(0.0), + Angle(0.0), + SrcFrequency(0.0), + pLineElem(nullptr), + Vn(0.0), + VE(0.0), + LineClass(nullptr), + ENorth(0.0), + EEast(0.0), + Lat1(0.0), + Lon1(0.0), + Lat2(0.0), + Lon2(0.0), + Volts(0.0), + VoltsSpecified(false) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + LineName = get_Name(); // GICsource name must be same as associated Line + LineClass = (TLine*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("Line")); + Set_NPhases(3); + Fnconds = 3; + Set_NTerms(2); // 4/27/2018 made a 2-terminal I source + Volts = 0.0; + Angle = 0.0; + ENorth = 1.0; + EEast = 1.0; + Lat1 = 33.613499; + Lon1 = -87.373673; + Lat2 = 33.547885; + Lon2 = -86.074605; + VoltsSpecified = false; + SrcFrequency = 0.1; // this is the GIC source + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + // Don't do This here RecalcElementData; + Spectrum = ""; // Spectrum not allowed + SpectrumObj = nullptr; +} + + +//---------------------------------------------------------------------------- + +TGICSourceObj::~TGICSourceObj() +{ + LineName = ""; + // inherited::Destroy(); +} + + +//============================================================================= + +double TGICSourceObj::Compute_VLine() +{ + double result = 0.0; + double pHi = 0.0; + double DeltaLat = 0.0; + double DeltaLon = 0.0; + pHi = (Lat2 + Lat1) / 2.0 * (double(DSSGlobals::PI) / 180.0); // deg to radians + DeltaLat = Lat1 - Lat2; // switched 11-20 to get pos GIC for pos ENorth + DeltaLon = Lon1 - Lon2; + VE = (111.133 - 0.56 * cos(2.0 * pHi)) * DeltaLat * ENorth; + Vn = (111.5065L - 0.1872L * cos(2.0 * pHi)) * cos(pHi) * DeltaLon * EEast; + result = Vn + VE; + return result; +} + +//---------------------------------------------------------------------------- + +void TGICSourceObj::RecalcElementData(int ActorID) +{ + String GICBus; + String LineBus2; + pLineElem = ((TLineObj*) ( (TDSSClass*) LineClass )->Find(LineName)); + if(pLineElem == nullptr) + { + DoSimpleMsg(String("Line Object \"") + LineName + + "\" associated with GICsource." + + get_Name() + + " Not Found. Make sure you define it first.", 333); + } + else + { + LineBus2 = ( (TDSSCktElement*) pLineElem )->GetBus(2); + + // If LineBus2 already begins with GIC, Don't insert the GIC Bis + if(CompareTextShortest("GIC_", LineBus2) != 0) + // Define buses -- inserting a new bus GIC_{LineName} + { + GICBus = String("GIC_") + LineName; + SetBus(1, GICBus); + SetBus(2, LineBus2); + // Redefine the bus2 spec for LineElem + Parser[ActorID]->SetCmdString(String("Bus2=") + GICBus); + ( (TDSSObject*) pLineElem )->Edit(ActorID); // invoke the Line's editor to process Parser + } + Bus2Defined = true; + if(!VoltsSpecified) + Volts = Compute_VLine(); + } + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder); +} + +//---------------------------------------------------------------------------- + +void TGICSourceObj::CalcYPrim(int ActorID) +{ + double Rs = 0.0; + double Rm = 0.0; + double Rzero = 0.0; + int i = 0; + complex Value = {}; + complex NegValue = {}; + + // Build only YPrim Series + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + + + /* + Assume 0.0001 ohms resistance for GIC Source + */ + Value = cmplx(10000.0, 0.0); + NegValue = cnegate(Value); + /*# with YPrim_Series do */ + { + auto with0 = YPrim_Series; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, NegValue); + } + } + YPrim->CopyFrom(YPrim_Series); // Initialize YPrim for series impedances +/* **************************************************************************** + { + Compute R0 of associated line + Average diagonals of Z matrix and off-diagonals + Z0=Zs + 2 Zm + } + + IF abs(ActiveCircuit.Solution.Frequency - SrcFrequency) < EPSILON2 THEN Begin + Rs := 0.0; { zero the accumulators} + Rm := 0.0; + With pLineElem Do + Begin + for i := 1 to NPhases do Begin + Rs := Rs + Z.GetElement(i,i).re; + for j := i+1 to NPhases do + Rm := Rm + Z.GetElement(i,j).re; + End; + Rs := Rs / NPhases; + Rm := Rm / (NPhases * (NPhases-1)/2); + Rzero := (Rs + 2.0*Rm) * Len / UnitsConvert; // Total for entire line + Gzero := 1.0/Rzero; // zero-sequence conductance of line + + End; + End; + *********************************************************************************** + */ + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TGICSourceObj::GetVterminalForSource(int ActorID) +{ + double Vmag = 0.0; + int i = 0; + try + + // If the solution frequency not 0.1 Hz, source is shorted. + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + if(Abs((int) (with0->get_FFrequency() - SrcFrequency)) < EPSILON2) + Vmag = Volts; + else + Vmag = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (Angle)); // all the same for zero sequence + // bottom part of the vector is zero + (Vterminal)[i + Fnphases - 1] = CZero; // See comments in GetInjCurrents + } + } + } + catch(...) + { + DoSimpleMsg(String("Error computing current for GICsource.") + get_Name() + + ". Check specification. Aborting.", 334); + if(In_Redirect) + Redirect_Abort = true; + } +} + +/*Sum Currents directly into solution array*/ + +int TGICSourceObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + result = inherited::InjCurrents(ActorID); // Adds into system array + return result; +} + +/*Total currents into a device*/ + +void TGICSourceObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (Vterminal)[i - 1] = with0->NodeV[(NodeRef)[i - 1]]; + else + (Vterminal)[i - 1] = with0->VoltInActor1((NodeRef)[i - 1]); + } + YPrim->MVmult(Curr, &(Vterminal[0])); // Current from Elements in System Y + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = csub((Curr)[i - 1], (ComplexBuffer)[i - 1]); + } + } /*With*/ + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for GICsource Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element?", 335); + } +} + + /* source injection currents given by this formula: + _ _ _ _ + |Iinj1| |GICLineVolts | + | | = [Yprim] | | + |Iinj2| | 0 | + _ _ _ _ + */ + +void TGICSourceObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + GetVterminalForSource(ActorID); // only at 0.1 Hz + YPrim->MVmult(Curr, &(Vterminal[0])); + set_ITerminalUpdated(false, ActorID); +} + +String TGICSourceObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = Format("%.8g", Volts); + break; + case 2: + result = Format("%.8g", Angle); + break; + case 3: + result = Format("%.8g", SrcFrequency); + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +void TGICSourceObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + WriteLn(f); + } +} + +void TGICSourceObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"0"); + Set_PropertyValue(2,"0"); + Set_PropertyValue(3,Format("%-.6g", SrcFrequency)); + Set_PropertyValue(4,"3"); + Set_PropertyValue(5,"1.0"); + Set_PropertyValue(6,"1.0"); + Set_PropertyValue(7,"33.613499"); + Set_PropertyValue(8,"-87.373673"); + Set_PropertyValue(9,"33.547885"); + Set_PropertyValue(10,"-86.074605"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TGICSourceObj::MakePosSequence(int ActorID) +{ + if(Fnphases > 1) + { + Parser[ActorID]->SetCmdString("phases=1"); + Edit(ActorID); + } + TDSSCktElement::MakePosSequence(ActorID); +} + + + + +} // namespace GICsource + + + + diff --git a/OpenDSSC/PCElements/GICsource.h b/OpenDSSC/PCElements/GICsource.h new file mode 100644 index 0000000..1c615f2 --- /dev/null +++ b/OpenDSSC/PCElements/GICsource.h @@ -0,0 +1,110 @@ +#ifndef GICsourceH +#define GICsourceH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Line.h" +#include "d2c_structures.h" + + + +namespace GICsource +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Develpoed from Isource and GICLine May 2018 +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGICsource : public PCClass::TPCClass +{ + friend class TGICSourceObj; +public: + typedef PCClass::TPCClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); +public: + TGICsource(); + virtual ~TGICsource(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGICSourceObj : public PCElement::TPCElement +{ + friend class TGICsource; +public: + typedef PCElement::TPCElement inherited; +private: + double FphaseShift; + bool Bus2Defined; + double Vmag; + double Angle; + double SrcFrequency; + String LineName; + Line::TLineObj* pLineElem; // Pointer to associated Line + double Vn; + double VE; // components of vmag + Line::TLine* LineClass; + void GetVterminalForSource(int ActorID); + double Compute_VLine(); +public: + double ENorth; + double EEast; + double Lat1; + double Lon1; + double Lat2; + double Lon2; + double Volts; + bool VoltsSpecified; + TGICSourceObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TGICSourceObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + TGICSourceObj(DSSClass::TDSSClass* ParClass); + TGICSourceObj(String ClassName); + TGICSourceObj(); +}; +extern TGICSourceObj* ActiveGICsourceObj; +extern TGICsource* GICsourceClass; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace GICsource + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GICsource; +#endif + +#endif // GICsourceH + + + + diff --git a/OpenDSSC/PCElements/GenUserModel.cpp b/OpenDSSC/PCElements/GenUserModel.cpp new file mode 100644 index 0000000..f9d8308 --- /dev/null +++ b/OpenDSSC/PCElements/GenUserModel.cpp @@ -0,0 +1,186 @@ + +#pragma hdrstop + +#include "GenUserModel.h" + +#include "generator.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace Arraydef; +using namespace DSSGlobals; +using namespace Dynamics; +using namespace Generator; +using namespace GeneratorVars; +using namespace System; +using namespace Ucomplex; + +namespace GenUserModel +{ + +TGenUserModel::TGenUserModel() {} + + + +/* TGenUserModel */ + +void* TGenUserModel::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("Generator User Model Does Not Have Required Function: ") + FuncName, 569); + FuncError = true; + } + result = Addr; + return result; +} + +TGenUserModel::TGenUserModel(pTGeneratorVars ActiveGeneratorVars) + : FHandle(0), + FID(0), + FuncError(false), + FActiveGeneratorVars(nullptr) +{ + FID = 0; + FName = ""; + FActiveGeneratorVars = ActiveGeneratorVars; +} + +TGenUserModel::~TGenUserModel() +{ + if(FID != 0) + { + FDelete(FID); // Clean up all memory associated with this instance + FreeLibrary((HMODULE) FHandle); + } + // inherited; +} + +//--------------------------------------------------------------- + +String TGenUserModel::get_FName() +{ + return FName; +} + +//--------------------------------------------------------------- + +bool TGenUserModel::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} + +void TGenUserModel::Integrate() +{ + FSelect(FID); + FIntegrate(); +} + +void TGenUserModel::select() +{ + FSelect(FID); +} + +void TGenUserModel::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit((PAnsiChar) Value.c_str(), Value.size()); + // Else Ignore +} + +void TGenUserModel::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if((HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + FreeLibrary((HMODULE) FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if((HMODULE) FHandle == 0) // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary((DSSDirectory + Value).c_str()); + } + if((HMODULE) FHandle == 0) + DoSimpleMsg(String("Generator User Model ") + Value + + " Not Loaded. DSS Directory = " + + DSSDirectory, 570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (GenUserModelProc__0) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("New")), "New"); + if(!FuncError) + FSelect = (GenUserModelProc__2) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Select")), "Select"); + if(!FuncError) + FInit = (GenUserModelProc__4) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Init")), "Init"); + if(!FuncError) + FCalc = (GenUserModelProc__5) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Calc")), "Calc"); + if(!FuncError) + FIntegrate = (GenUserModelProc__6) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Integrate")), "Integrate"); + if(!FuncError) + FSave = (GenUserModelProc__8) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Save")), "Save"); + if(!FuncError) + fRestore = (GenUserModelProc__9) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Restore")), "Restore"); + if(!FuncError) + FEdit = (GenUserModelProc__3) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (GenUserModelProc__7) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (GenUserModelProc__1) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Delete")), "Delete"); + if(!FuncError) + FNumVars = (GenUserModelProc__10) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("NumVars")), "NumVars"); + if(!FuncError) + FGetAllVars = (GenUserModelProc__11) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetAllVars")), "GetAllVars"); + if(!FuncError) + FGetVariable = (GenUserModelProc__12) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVariable")), "GetVariable"); + if(!FuncError) + FSetVariable = (GenUserModelProc__13) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("SetVariable")), "SetVariable"); + if(!FuncError) + FGetVarName = (GenUserModelProc__14) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVarName")), "GetVarName"); + if(FuncError) + { + FreeLibrary((HMODULE) FHandle); + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew((*FActiveGeneratorVars), ActiveCircuit[ActiveActor]->Solution->DynaVars, CallBackRoutines); // Create new instance of user model + } + } +} + + + + +} // namespace GenUserModel + + + + diff --git a/OpenDSSC/PCElements/GenUserModel.h b/OpenDSSC/PCElements/GenUserModel.h new file mode 100644 index 0000000..256ee08 --- /dev/null +++ b/OpenDSSC/PCElements/GenUserModel.h @@ -0,0 +1,113 @@ +#ifndef GenUserModelH +#define GenUserModelH + +#include "System.h" +#include "Sysutils.h" + +#include "GeneratorVars.h" +#include "Dynamics.h" +#include "DSSCallBackRoutines.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "d2c_structures.h" + +namespace GenUserModel +{ + + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + 7-7-10 + Modified to allow DLLS to retain ANSI string type in Edit function and Var names + Nominally all strings passed to DLLS are ASCII to make it easier to write code in other languages + and legacy defaults + +*/ + +class TGenUserModel : public System::TObject +{ +public: + typedef TObject inherited; +//private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + // OK for this to be Wide String, since not passed to DLLs + String FName; // Name of the DLL file containing user model + bool FuncError; + + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *GenUserModelProc__0)(GeneratorVars::TGeneratorVars&, Dynamics::TDynamicsRec&, TDSSCallBacks&); + GenUserModelProc__0 FNew; // deletes specified instance + typedef void (__stdcall *GenUserModelProc__1)(int&); + GenUserModelProc__1 FDelete; // Select active instance + typedef int (__stdcall *GenUserModelProc__2)(int&); + GenUserModelProc__2 FSelect; + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); + String get_FName(); + +protected: +public: // send string to user model to handle + typedef void (__stdcall *GenUserModelProc__3)(System::PAnsiChar, unsigned int); + GenUserModelProc__3 FEdit; // For dynamics + typedef void (__stdcall *GenUserModelProc__4)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + GenUserModelProc__4 FInit; // returns Currents or sets Pshaft + typedef void (__stdcall *GenUserModelProc__5)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + GenUserModelProc__5 FCalc; // Integrates any state vars + typedef void (__stdcall *GenUserModelProc__6)(); + GenUserModelProc__6 FIntegrate; // Called when props of generator updated + typedef void (__stdcall *GenUserModelProc__7)(); + GenUserModelProc__7 FUpdateModel; + GeneratorVars::pTGeneratorVars FActiveGeneratorVars; + + /*Save and restore data*/ + typedef void (__stdcall *GenUserModelProc__8)(); + GenUserModelProc__8 FSave; + + /*Monitoring functions*/ + typedef void (__stdcall *GenUserModelProc__9)(); + GenUserModelProc__9 fRestore; + typedef int (__stdcall *GenUserModelProc__10)(); + GenUserModelProc__10 FNumVars; // Get all vars + typedef void (__stdcall *GenUserModelProc__11)(Arraydef::pDoubleArray); + GenUserModelProc__11 FGetAllVars;// Get a particular var + typedef double (__stdcall *GenUserModelProc__12)(int&); + GenUserModelProc__12 FGetVariable; + typedef void (__stdcall *GenUserModelProc__13)(int&, double&); + GenUserModelProc__13 FSetVariable; + + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + // Wide string OK here + typedef void (__stdcall *GenUserModelProc__14)(int&, System::PAnsiChar, unsigned int); + GenUserModelProc__14 FGetVarName; + void select(); + void Integrate(); + TGenUserModel(GeneratorVars::pTGeneratorVars ActiveGeneratorVars); + virtual ~TGenUserModel(); +//__published: +public: + TGenUserModel(); +}; + + +} // namespace GenUserModel + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GenUserModel; +#endif + +#endif // GenUserModelH + + + + diff --git a/OpenDSSC/PCElements/GeneratorVars.cpp b/OpenDSSC/PCElements/GeneratorVars.cpp new file mode 100644 index 0000000..18e94fb --- /dev/null +++ b/OpenDSSC/PCElements/GeneratorVars.cpp @@ -0,0 +1,22 @@ + +#pragma hdrstop + +#include "GeneratorVars.h" + +using namespace std; +using namespace System; +using namespace Ucomplex; + +namespace GeneratorVars +{ + + + + + + +} // namespace GeneratorVars + + + + diff --git a/OpenDSSC/PCElements/GeneratorVars.h b/OpenDSSC/PCElements/GeneratorVars.h new file mode 100644 index 0000000..6c2e538 --- /dev/null +++ b/OpenDSSC/PCElements/GeneratorVars.h @@ -0,0 +1,89 @@ +#ifndef GeneratorVarsH +#define GeneratorVarsH + +#include "System.h" +#include "Sysutils.h" + +#include "Ucomplex.h" + +namespace GeneratorVars +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2024, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + Definition of Generator Public Data Record for passing to DLLs and other object +*/ + + /*Generator public data/state variable structure*/ +#pragma pack (push, 1) + +struct TGeneratorVars; +typedef TGeneratorVars* pTGeneratorVars; + +struct TGeneratorVars +{ + /*Direct-Axis voltage magnitude & angle*/ /*present Shaft Power and relative Speed, rad/sec, difference from Synchronous speed, w0*/ + /*actual speed = Speed + w0*/ /*Per unit mass constant*/ /*Mass constant actual values (Joule-sec/rad*/ /*Actual and per unit damping factors*/ /*machine Reactances, ohms*/ /*machine Reactances, per unit*/ /*Derivatives of Theta and Speed*/ /*history variables for integration*/ /*Target P and Q for power flow solution, watts, vars*/ + double Theta; + double Pshaft; + double Speed; + double w0; + double Hmass; + double Mmass; + double D; + double Dpu; + double kVArating; + double kVGeneratorBase; + double XD; + double Xdp; + double Xdpp; + double puXd; + double puXdp; + double puXdpp; + double dTheta; + double dSpeed; + double ThetaHistory; + double SpeedHistory; + double Pnominalperphase; + double Qnominalperphase; /* All Doubles */ + double *deltaQNomPtr; // Pointer to deltaQNom's data, for plain C compat + + /*32-bit integers*/ /*Number of phases*/ /*Total Number of conductors (wye-connected will have 4)*/ + int NumPhases; + int NumConductors; + int Conn; // 0 = wye; 1 = Delta + + /* Revisons (additions) to structure ... + Later additions are appended to end of the structure so that + previously compiled DLLs do not break + */ + double VthevMag; /*Thevinen equivalent voltage for dynamic model*/ + double VThevHarm; /*Thevinen equivalent voltage mag reference for Harmonic model*/ + double ThetaHarm; /*Thevinen equivalent voltage angle reference for Harmonic model*/ + double VTarget; // Target voltage for generator with voltage control + Ucomplex::complex Zthev; + double XRdp; // Assumed X/R for Xd' + + std::vector deltaQNom; +}; +#pragma pack (pop) + + + +} // namespace GeneratorVars + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GeneratorVars; +#endif + +#endif // GeneratorVarsH + + + + diff --git a/OpenDSSC/PCElements/Generic5OrderMach.cpp b/OpenDSSC/PCElements/Generic5OrderMach.cpp new file mode 100644 index 0000000..8059b7b --- /dev/null +++ b/OpenDSSC/PCElements/Generic5OrderMach.cpp @@ -0,0 +1,4642 @@ + + +#pragma hdrstop + +#include "Generic5OrderMach.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Command.h" +#include +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace GeneratorVars; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Generic5OrderMach +{ + +TGeneric5Obj::TGeneric5Obj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGeneric5Obj::TGeneric5Obj(String ClassName) : inherited(ClassName) {} +TGeneric5Obj::TGeneric5Obj() {} + + +TGeneric5* Generic5Class = nullptr; +TGeneric5Obj* ActiveGeneric5Obj = nullptr; +/*Typical Uses Clause -- not all may not be needed*/ // DSS parser + // Where class is instantiated + // Global DSS variables + // If access to circuit variables is needed + // DSS command and property support module + // Delphi misc utility functions + // Delphi Math functions + // DSS Math utilities + // DSS misc utility functions +const int NumPropsThisClass = 48;//44;//24;//23; // Set this constant to the actual number of properties you define add grpnum +const int NumGeneric5Variables = 36;//33;//25;//24; +const int Norder = 6; // Define any useful module vars here, for example: +complex cBuffer[24/*# range 1..24*/]; // Temp buffer for complex math calcs; allows up to 24-phase models. +complex CDoubleOne = {}; // 1 + j1 (see Initialization section below) + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates main collection handler for all IndMach012 objects + +TGeneric5::TGeneric5() +{ + ; // make the base class and init DSSClassType + + // Specify class name and bit mask ID for this class type + // IndMach012_ELEMENT must be defined in DSSClassDefs as nn*8 + // First 3 bits are used for base class type (DSSClassType) + Class_Name = "Generic5"; + DSSClassType = DSSClassType + Generic5OrderMach_ELEMENT; + ActiveElement = 0; // no active elements yet; init to 0 + + /*Initialize any other special variables here*/ + DefineProperties(); // This is where the properties for this class are defined + + // Use the Command processor to manage property names + // PropertyName is an array of String defined in DefineProperties + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + Generic5Class = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGeneric5::~TGeneric5() +{ + + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is where the properties are defined, assigned names, indexes, and help strings +// The Help strings will automatically show up when the Help is invoked + +void TGeneric5::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Refer to other classes for alternative methods of assigning properties + // This example uses the AddProperty function to assign Name, Index, and Help string + // in one statement. + + // First argument is string name of the property + // Second argument is the index for the CASE statement + // Third argument is help string + + // DSS properties are accessed in sequence if the property name is not explicitly specified. + // The advantage of using the AddProperty function is that you may change the sequence simply + // by shuffling the order of the definitions and you do not have to change the index in the CASE + // statement in the EDIT function + PropertyName[1 - 1] = "phases"; + PropertyName[2 - 1] = "bus1"; + PropertyName[3 - 1] = "kv"; + PropertyName[4 - 1] = "kW"; + PropertyName[5 - 1] = "pf"; + PropertyName[6 - 1] = "conn"; + PropertyName[7 - 1] = "kVA"; + PropertyName[8 - 1] = "H"; + PropertyName[9 - 1] = "D"; + PropertyName[10 - 1] = "P_ref1kW"; + PropertyName[11 - 1] = "P_ref2kW"; + PropertyName[12 - 1] = "P_ref3kW"; + PropertyName[13 - 1] = "V_ref1kVLN"; + PropertyName[14 - 1] = "V_ref2kVLN"; + PropertyName[15 - 1] = "V_ref3kVLN"; + PropertyName[16 - 1] = "MaxSlip"; + PropertyName[17 - 1] = "SlipOption"; + PropertyName[18 - 1] = "Yearly"; + PropertyName[19 - 1] = "Daily"; + PropertyName[20 - 1] = "Duty"; + PropertyName[21 - 1] = "Debugtrace"; + PropertyName[22 - 1] = "P_refkW"; + PropertyName[25 - 1] = "V_refkVLN"; + PropertyName[23 - 1] = "Q_refkVAr"; + PropertyName[24 - 1] = "Cluster_num"; + PropertyName[26 - 1] = "ctrl_mode"; + /////////////////////////////////////////// + /// contrl mode + /// ctrl_mode =0; phases = 3; // pos avg control---p_ref, V_ref, Q_ref + /// ctrl_mode =1; phases = 1; bus1 = 452.1; ---p_ref1, V_ref1, Q_ref1 + /// ctrl_mode =2; phases = 1; bus1 = 452.2; ---p_ref2, V_ref2, Q_ref2 + /// ctrl_mode =3; phases = 1; bus1 = 452.3; ---p_ref3, V_ref3, Q_ref3 + /// ctrl_mode =4; phases = 3; bus1 = 452.2; ---p_ref1,2,3, V_ref1,2,3, Q_ref1,2,3 + PropertyName[27 - 1] = "QV_flag"; + PropertyName[28 - 1] = "kcd";//Idi control gain + PropertyName[29 - 1] = "kcq";//Iqi control gain to delta V + PropertyName[30 - 1] = "kqi";//Iqi control gain to delta Q + PropertyName[31 - 1] = "Q_ref1kVAr"; + PropertyName[32 - 1] = "Q_ref2kVAr"; + PropertyName[33 - 1] = "Q_ref3kVAr"; + PropertyName[34 - 1] = "PmaxkW"; // + PropertyName[35 - 1] = "PminkW"; + PropertyName[36 - 1] = "PQpriority"; + PropertyName[37 - 1] = "PmppkW"; + PropertyName[38 - 1] = "Pfctr1"; + PropertyName[39 - 1] = "Pfctr2"; + PropertyName[40 - 1] = "Pfctr3"; + PropertyName[41 - 1] = "Pfctr4"; + PropertyName[42 - 1] = "Pfctr5"; + PropertyName[43 - 1] = "Pfctr6"; + PropertyName[44 - 1] = "PbiaskW"; + PropertyName[45 - 1] = "CC_Switch"; + PropertyName[46 - 1] = "kcq_drp2"; + PropertyName[47 - 1] = "Volt_Trhd"; + PropertyName[48 - 1] = "droop"; + + //PropertyName[46] := 'Num_in_Cluster. Num_in_Cluster = 1~33'; + PropertyHelp[1 - 1] = "Number of Phases, this Induction Machine. "; + PropertyHelp[2 - 1] = "Bus to which the Induction Machine is connected. May include specific node specification."; + PropertyHelp[3 - 1] = "Nominal rated (1.0 per unit) voltage, kV. For 2- and 3-phase machines, specify phase-phase kV. " + "Otherwise, specify actual kV across each branch of the machine. " + "If wye (star), specify phase-neutral kV. " + "If delta or phase-phase connected, specify phase-phase kV."; // line-neutral voltage// base voltage + PropertyHelp[4 - 1] = "Shaft Power, kW, for the Induction Machine. Output limit of a DG";//A positive value denotes power for a //load. ';//+CRLF+ + //'Negative value denotes an induction generator. '; + PropertyHelp[5 - 1] = "[Read Only] Present power factor for the machine. "; + PropertyHelp[6 - 1] = "Connection of stator: Delta or Wye. Default is Delta."; + PropertyHelp[7 - 1] = "Rated kVA for the machine."; + PropertyHelp[8 - 1] = "Per unit mass constant of the machine. MW-sec/MVA. Default is 1.0."; + PropertyHelp[9 - 1] = "Damping constant. Usual range is 0 to 4. Default is 1.0. Adjust to get damping in Dynamics mode,"; + PropertyHelp[10 - 1] = "P_ref1kW = 10, goes to P_ref1, unit kW, 1st phase set power"; + PropertyHelp[11 - 1] = "P_ref2kW = 10, goes to P_ref2, unit kW, 2nd phase set power"; + PropertyHelp[12 - 1] = "P_ref3kW = 10, goes to P_ref3, unit kW, 3rd phase set power"; + PropertyHelp[13 - 1] = "V_ref1kVLN = 2.16, 1st phase set V, (Unit kV, L-N value): V mode will work if QV_flag =1(by default) V_ref is set which is prior to Q_ref "; + PropertyHelp[14 - 1] = "V_ref2kVLN = 2.16, 2nd phase set V, (Unit kV, L-N value): V mode will work if QV_flag =1(by default) V_ref is set which is prior to Q_ref "; + PropertyHelp[15 - 1] = "V_ref3kVLN = 2.16, 3rd phase set V, (Unit kV, L-N value): V mode will work if QV_flag =1(by default) V_ref is set which is prior to Q_ref "; + PropertyHelp[16 - 1] = "Max slip value to allow. Default is 0.1. Set this before setting slip."; + PropertyHelp[17 - 1] = "Option for slip model. One of {fixedslip | variableslip* }"; + PropertyHelp[18 - 1] = "LOADSHAPE object to use for yearly simulations. Must be previously defined " + "as a Loadshape object. Is set to the Daily load shape " + " when Daily is defined. The daily load shape is repeated in this case. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "The default is no variation."; + PropertyHelp[19 - 1] = "LOADSHAPE object to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "Default is no variation (constant) if not defined. " + "Side effect: Sets Yearly load shape if not already defined."; + PropertyHelp[20 - 1] = "LOADSHAPE object to use for duty cycle simulations. Must be previously defined " + "as a Loadshape object. Typically would have time intervals less than 1 hr. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat." + "Set to NONE to reset to no loadahape. " + "Set Status=Fixed to ignore Loadshape designation. " + " Defaults to Daily curve If not specified."; + PropertyHelp[21 - 1] = "[Yes | No*] Write DebugTrace file."; + PropertyHelp[22 - 1] = "P_refkW = 10, goes to P_ref. Ref P Value (kW). P_ref has prority to kW which is nomimal value. (Incide variable P_ref is W)"; + PropertyHelp[25 - 1] = "V_refkVLN = 2.16, pos sequence set V. V_ref (Unit kV, L-N value): V mode will work if QV_flag =1(by default) V_ref is set which is prior to Q_ref"; + PropertyHelp[23 - 1] = "Q_refkVAr=10. Unit Qvar. Ref Q kVAr Value: work only when V_ref is not set"; + PropertyHelp[24 - 1] = "Cluster_num: has to be coincident with Fmonitor attached. Default value is 0"; + /* add properties here */ + PropertyHelp[26 - 1] = String("ctrl mode: /// contrl mode " " /// ctrl_mode =0; phases = 3; // pos avg control---p_ref, V_ref, Q_ref \\n ") + CRLF + + " /// ctrl_mode =1; phases = 1; bus1 = 452.1; ---p_ref1, V_ref1, Q_ref1 \\n" + + CRLF + + "/// ctrl_mode =2; phases = 1; bus1 = 452.2; ---p_ref2, V_ref2, Q_ref2 \\n" + + CRLF + + "/// ctrl_mode =3; phases = 1; bus1 = 452.3; ---p_ref3, V_ref3, Q_ref3 \\n" + + CRLF + + "/// ctrl_mode =4; phases = 3; bus1 = 452.2; ---p_ref1,2,3, V_ref1,2,3, Q_ref1,2,3"; + PropertyHelp[27 - 1] = "QV_flag : 0-Q_ref mode; 1- V_ref mode"; + PropertyHelp[28 - 1] = "kcd: Idi control gain"; + PropertyHelp[29 - 1] = "kcq: Iqi control gain to delta V"; + PropertyHelp[30 - 1] = "kqi: Iqi control gain to delta Q"; + PropertyHelp[31 - 1] = "Q_ref1kVAr=10. Unit Qvar. Ref Q kVAr Value: work only when V_ref is not set"; + PropertyHelp[32 - 1] = "Q_ref2kVAr=10. Unit Qvar. Ref Q kVAr Value: work only when V_ref is not set"; + PropertyHelp[33 - 1] = "Q_ref3kVAr=10. Unit Qvar. Ref Q kVAr Value: work only when V_ref is not set"; + PropertyHelp[34 - 1] = String("PmaxkW = 100, goes to Pmax, unit kW, set max active power output; Operation limit of active power for DG") + CRLF + + " Pmax should be less than or equal to kW"; + PropertyHelp[35 - 1] = "PminkW = 10, goes to Pmin, unit kW; Operation limit of active power for DG"; + PropertyHelp[36 - 1] = "PQpriority, goes to PQpriority, define how to set Qmax. 0: Q,1: P "; + PropertyHelp[37 - 1] = String("Set_PmppkW(100, goes to Pmpp, unit kW, input Get_FPmpp() to calculate kW);") + CRLF + + " kW := (Pmpp + Pbias)*Pfctr1*Pfctr2*Pfctr3*Pfctr4*Pfctr5*Pfctr6;" + + CRLF + + "Pbias = 0 by default, Pfctr*=1 by default; These properties will overwrite kW."; + PropertyHelp[38 - 1] = "Pfctr1 = 0.16, see PmppkW"; + PropertyHelp[39 - 1] = "Pfctr2 = 1, 1 by default, see PmppkW"; + PropertyHelp[40 - 1] = "Pfctr3 = 1, 1 by default, see PmppkW"; + PropertyHelp[41 - 1] = "Pfctr4= 1, 1 by default, see PmppkW"; + PropertyHelp[42 - 1] = "Pfctr5 =1, 1 by default, see PmppkW"; + PropertyHelp[43 - 1] = "Pfctr6 = 1, 1 by default, see PmppkW"; + PropertyHelp[44 - 1] = "Pbias = -0.1, 0 by default, see PmppkW"; + PropertyHelp[45 - 1] = String("CC_Switch: default value is false.") + CRLF + + "CC_Switch = true --cooperate control on" + + CRLF + + "CC_Switch = false -- cooperate control off"; + PropertyHelp[46 - 1] = "kcq_drp2. the droop gain: 0.0~0.1"; + PropertyHelp[47 - 1] = "Volt_Trhd. 0.~0.05. 0 means v has to follow v_ref"; + PropertyHelp[48 - 1] = "droop type: integer: 2- Q = kcq_drp2 * (1-v_dg). others: integral droop with kcq."; + // Finally, we have to pick up any properties that were inherited + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // You can optionally override default help string of an inherited property, for example + PropertyHelp[NumPropsThisClass + 1 - 1] = "Name of harmonic voltage or current spectrum for this IndMach012. " + "Voltage behind Xd\" for machine - default. Current injection for inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function is called by the DSS whenever a New IndMach012... command is encountered + +int TGeneric5::NewObject(const String ObjName) +{ + int result = 0; + // Make a new IndMach012 and add it to IndMach012 class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGeneric5Obj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is a typical helper function found in many DSS circuit element class +// for defining the number of conductors per terminal (Nconds) based on Y or delta connection + +void TGeneric5::SetNcondsForConnection() +{ + /*# with ActiveGeneric5Obj do */ + { + auto with0 = ActiveGeneric5Obj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases); + break; // Neutral is not connected for induction machine + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: // Delta connection + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); // no neutral for this connection + break; + } + break; + default: + ; + break; + } + } +} + + +//- - - - - - - - - - - - - MAIN EDIT FUNCTION - - - - - - - - - - - - - - - +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// This function is the heart of the property managment for this class + +int TGeneric5::Edit(int ActorID) +{ + int result = 0; // Define some local vars for handling parser results + int ParamPointer = 0; + String ParamName; + String Param; + +// The Edit function starts where the Parser is presently pointing and +// manages the parsing of the rest of the command line in the parser. + +// The DSS executive processes the command verb on the front of the line and +// then passes control to the appropriate Edit function + + + // set the present element active + // and continue parsing with contents of Parser + ActiveGeneric5Obj = (TGeneric5Obj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGeneric5Obj); + result = 0; + /*# with ActiveGeneric5Obj do */ + { + auto with0 = ActiveGeneric5Obj; + // peel off the next token on the edit line + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + + // Find the index for the CASE statement + // If property is not named, just increment the index to the next property + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + + // Update the PropertyValy for this property + // Actual index is mapped via PropertyIdxMap array for this class + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1],Param); + else + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Generic5 \"" + + with0->get_Name() + + "\"", 560); + + // --------------- MAIN CASE STATEMENT ---------------------- + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + // since we used AddProperty function to define properties, have to + // use PropertyIdxMap to map to the correct Case index + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // num phases + case 2: + { + with0->SetBus(1, Param); //'bus1 = 8.1.2.3' + //if True then + } + break; + case 3: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_()); + break; + case 4: + { + with0->kWBase = Parser[ActorID]->MakeDouble_(); + if((with0->PMax < 0) || (with0->PMax > with0->kWBase * 1000)) + with0->PMax = with0->kWBase * 1000; + if(with0->PQpriority == 1) + with0->PMax = with0->kWBase * 1000; + } + break; + case 5: + ; + break; // Do nothing; read only power factor := Parser.MakeDouble_(); + case 6: + InterpretConnection(Parser[ActorID]->MakeString_()); + break; + case 7: + with0->MachineData.kVArating = Parser[ActorID]->MakeDouble_(); + break; + //8: MachineData.Hmass := Parser.MakeDouble_(); + //9: MachineData.D := Parser.MakeDouble_(); + case 10: + with0->P_ref1 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl unit kW to W + case 11: + with0->P_ref2 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 12: + with0->P_ref3 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 13: + with0->V_ref1 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl unit kV to V + case 14: + with0->V_ref2 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 15: + with0->V_ref3 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 16: + with0->MaxSlip = Parser[ActorID]->MakeDouble_(); + break; + case 17: + ; + break;//InterpretOption(Parser.MakeString_()); + case 18: + with0->YearlyShape = Param; + break; + case 19: + with0->DailyDispShape = Param; + break; + case 20: + with0->DutyShape = Param; + break; + case 21: + with0->DebugTrace = InterpretYesNo(Param); + break; + /**/ + case 22: + with0->Set_P_Ref(Parser[ActorID]->MakeDouble_(), ActorID); + break;//to norm value W from kW(in script)//for avg ctrl 1000*PrefKw/3; + case 23: + with0->Set_Q_Ref(Parser[ActorID]->MakeDouble_()); + break;//to VA from kVA(in script) //for avg ctrl 1000*QrefKVAr/3; + case 24: + with0->Cluster_num = Parser[ActorID]->MakeInteger_(); + break; + case 25: + with0->Set_V_Ref(Parser[ActorID]->MakeDouble_()); + break;//kV to V //for avg ctrl 1000*VrefkV; + case 26: + with0->ctrl_mode = Parser[ActorID]->MakeInteger_(); + break; + /////////////////////////////////////////// + /// + /////////////////////////////////////////// + case 27: + { + with0->QV_flag = Parser[ActorID]->MakeInteger_(); + } + break; // QV_flag_0 :=QV_flag + case 28: + with0->kcd = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->kcq = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->kqi = Parser[ActorID]->MakeDouble_(); + break; + case 31: + with0->Q_ref1 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl unit kVar to Var + case 32: + with0->Q_ref2 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 33: + with0->Q_ref3 = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for phase ctrl + case 34: + { + with0->PMax = 1000 * Parser[ActorID]->MakeDouble_(); //Pmax has to be less then kW in script + with0->PMax_phase = with0->PMax / with0->Fnphases; + } + break; + case 35: + { + with0->PMin = 1000 * Parser[ActorID]->MakeDouble_(); //for phase ctrl + with0->Pmin_phase = with0->PMax / with0->Fnphases; + } + break; + case 36: + with0->PQpriority = Parser[ActorID]->MakeInteger_(); + break; // + case 37: + with0->Pmpp = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for pmpp kW + case 38: + with0->Pfctr1 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 39: + with0->Pfctr2 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 40: + with0->Pfctr3 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 41: + with0->Pfctr4 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 42: + with0->Pfctr5 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 43: + with0->Pfctr6 = Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 44: + with0->Pbias = 1000 * Parser[ActorID]->MakeDouble_(); + break; //for pmpp + case 45: + with0->CC_Switch = InterpretYesNo(Parser[ActorID]->MakeString_()); + break; // yes, true, y ,t; or no, false, n, f + case 46: + with0->kcq_drp2 = Parser[ActorID]->MakeDouble_(); + break; //cluster num + case 47: + with0->Volt_Trhd = Parser[ActorID]->MakeDouble_(); + break; + case 48: + with0->droop = Parser[ActorID]->MakeInteger_(); + break; + // Handle Inherited properties + default: + inherited::ClassEdit(ActiveGeneric5Obj, ParamPointer - NumPropsThisClass); + break; + } + + // ---------------- SIDE EFFECTS CASE STATEMENT --------------------- + // This case statment handles any side effects from setting a property + // (for example, from Generator) + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + case 18: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(ASSIGNED(with0->YearlyShapeObj)) + /*# with YearlyShapeObj do */ + { + auto with1 = with0->YearlyShapeObj; + if(with1->UseActual) + with0->SetPowerkW(with1->MaxP); + } + } + break; + case 19: + { + with0->DailyDispShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyDispShape)); + if(ASSIGNED(with0->DailyDispShapeObj)) + /*# with DailyDispShapeObj do */ + { + auto with2 = with0->DailyDispShapeObj; + if(with2->UseActual) + with0->SetPowerkW(with2->MaxP); + } + } + break; + case 20: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(ASSIGNED(with0->DutyShapeObj)) + /*# with DutyShapeObj do */ + { + auto with3 = with0->DutyShapeObj; + if(with3->UseActual) + with0->SetPowerkW(with3->MaxP); + } + } + break; + default: + ; + break; + } + + //if Get_FPmpp() and fctrs are defined + if((ParamPointer >= 37) && (ParamPointer <= 44)) + { + with0->Update_kWbase_by_Fctrs();// Update Pmax + //will cover direct Pmax input by these + } + + // Get next token off Parser and continue editing properties + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + + // After editing is complete, the typical next step is to call the RecalcElementData function + /*---------------*/ + //if QV_switch = 1 then // + //begin + //QV_flag := QV_flag_0; + //QV_switch := 0;// wait next limit break + //end; + with0->Update_PQlimits(); + /*----------------*/ + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); // Setting this flag notifies the DSS that something has changed + // and the Yprim will have to be rebuilt + } + return result; +} + +//---------------------------------------------------------------------------- +// dont use this 0114-2018 by Ying +//---------------------------------------------------------------------------- + + +// This function should be defined to handle the Like property inherited from +// the base class. + +// The function copies the essential properties of another object of this class + +int TGeneric5::MakeLike(const String OtherIndMach012Name) +{ + int result = 0; + TGeneric5Obj* OtherIndMach012 = nullptr; + int i = 0; + result = 0; + /*See if we can find this IndMach012 name in the present collection*/ + OtherIndMach012 = ((TGeneric5Obj*) Find(OtherIndMach012Name)); + if(OtherIndMach012 != nullptr) + /*# with ActiveGeneric5Obj do */ + { + auto with0 = ActiveGeneric5Obj; // skip if not found + + // You should first set the basic circuit element properties, for example + int stop = 0; + if(with0->Fnphases != OtherIndMach012->Fnphases) + { + with0->Set_NPhases(OtherIndMach012->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->Set_PresentkV(OtherIndMach012->Get_PresentkV()); + with0->kWBase = OtherIndMach012->kWBase; + with0->puRs = OtherIndMach012->puRs; + with0->puRr = OtherIndMach012->puRr; + with0->puXr = OtherIndMach012->puXr; + with0->puXm = OtherIndMach012->puXm; + with0->puXs = OtherIndMach012->puXs; + with0->MaxSlip = OtherIndMach012->MaxSlip; + with0->MachineData.kVArating = OtherIndMach012->MachineData.kVArating; + with0->MachineData.Hmass = OtherIndMach012->MachineData.Hmass; + with0->MachineData.D = OtherIndMach012->MachineData.D; + + // Do inherited properties + ClassMakeLike(OtherIndMach012); + + // Finally initialize all the property value strings to be the same as + // the copied element + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0->FPropertyValue)[i - 1] = (OtherIndMach012->FPropertyValue)[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Load MakeLike: \"") + OtherIndMach012Name + + "\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Optional function if you want to do anything to initialize objects of this class + +int TGeneric5::Init(int Handle, int ActorID) +{ + int result = 0; + TGeneric5Obj* P = nullptr; + if(Handle == 0) // init all + { + P = (TGeneric5Obj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TGeneric5Obj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TGeneric5Obj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TGeneric5.Init", -1); + result = 0; + return result; +} + +//------------------------- MAIN OBJECT CONSTRUCTOR --------------------- + +TGeneric5Obj::TGeneric5Obj(TDSSClass* ParClass, const String Generic5ObjName) + : inherited(ParClass), + Connection(1), + puRs(0.0), + puXs(0.0), + puRr(0.0), + puXr(0.0), + puXm(0.0), + MaxSlip(0.0), + Xopen(0.0), + Xp(0.0), + T0p(0.0), + NumOrderX(0), + NumOrderY(0), + X_var(nullptr), + dX_vardt(nullptr), + X_varn(nullptr), + dX_vardtn(nullptr), + Y_out_var(nullptr), + V_in_var(nullptr), + pV_f_CC(nullptr), + CC_Switch(false), + Amm(nullptr), + Bmn(nullptr), + Cnm(nullptr), + Dnn(nullptr), + InDynamics(false), + id(0.0), + Iq(0.0), + flag_dyna_Id_chg(false), + dIddt(0.0), + dIqdt(0.0), + Idn(0.0), + Iqn(0.0), + dIddtn(0.0), + dIqdtn(0.0), + kcd(0.0), + kcq(0.0), + kcq_drp2(0.0), + Volt_Trhd(0.0), + droop(0), + kqi(0.0), + vi1(0.0), + vi2(0.0), + vi1n(0.0), + vi2n(0.0), + dvi1dt(0.0), + dvi2dt(0.0), + dvi1dtn(0.0), + dvi2dtn(0.0), + Id_ref(0.0), + Iq_ref(0.0), + P_ref(0.0), + Q_ref(0.0), + V_ref(0.0), + DPX(0.0), + ctrl_mode(0), + P_DG(0.0), + Q_DG(0.0), + V_DG(0.0), + Theta_DG(0.0), + QV_flag(0), + P_DG1(0.0), + P_DG2(0.0), + P_dg3(0.0), + Q_DG1(0.0), + Q_dg2(0.0), + Q_dg3(0.0), + V_DG1(0.0), + V_DG2(0.0), + V_DG3(0.0), + V_theta1(0.0), + V_theta2(0.0), + V_theta3(0.0), + ID1(0.0), + Iq1(0.0), + ID2(0.0), + Iq2(0.0), + Id3(0.0), + Iq3(0.0), + P_ref1(0.0), + P_ref2(0.0), + P_ref3(0.0), + Q_ref1(0.0), + Q_ref2(0.0), + Q_ref3(0.0), + V_ref1(0.0), + V_ref2(0.0), + V_ref3(0.0), + PMax(0.0), + PMax_phase(0.0), + PMin(0.0), + Pmin_phase(0.0), + Qmax(0.0), + Qmax_phase(0.0), + Qmin(0.0), + Qmin_phase(0.0), + IdMax_phase(0.0), + IqMax_phase(0.0), + PQpriority(0), + Freq(0.0), + z_dfs_plot(0.0), + FirstIteration(false), + FixedSlip(false), + DQDV(0.0), + RandomMult(0.0), + Generic5SwitchOpen(false), + DebugTrace(false), + MachineON(false), + ShapeIsActual(false), + VBase(0.0), + kWBase(0.0), + Pmpp(0.0), + Pbias(0.0), + Pfctr1(0.0), + Pfctr2(0.0), + Pfctr3(0.0), + Pfctr4(0.0), + Pfctr5(0.0), + Pfctr6(0.0), + Alpha(0.0), + dAlpha(0.0), + Gradient(0.0), + Alpha1(0.0), + Alpha2(0.0), + Alpha3(0.0), + dAlpha1(0.0), + dAlpha2(0.0), + dAlpha3(0.0), + Gradient1(0.0), + Gradient2(0.0), + Gradient3(0.0), + AlphaP(0.0), + AlphaP1(0.0), + AlphaP2(0.0), + AlphaP3(0.0), + GradientP(0.0), + GradientP1(0.0), + GradientP2(0.0), + GradientP3(0.0), + DailyDispShapeObj(nullptr), + DutyShapeObj(nullptr), + YearlyShapeObj(nullptr) +{ + int i = 0; + int j = 0; +//---------------------------------------------------------------------------- + int stop = 0; + Set_Name(LowerCase(Generic5ObjName)); + DSSObjType = ParClass->DSSClassType; // Same as Parent Class + + // Set some basic circuit element properties + Set_NPhases(3); // typical DSS default for a circuit element + Fnconds = 3; // defaults to delta + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations of terminal quantities + kWBase = (double) -1;//00; // has to be set in DSS scripts + YearlyShape = ""; + YearlyShapeObj = nullptr; // if YearlyShapeobj = nil then the load alway stays nominal * global multipliers + DailyDispShape = ""; + DailyDispShapeObj = nullptr; // if DaillyShapeobj = nil then the load alway stays nominal * global multipliers + DutyShape = ""; + DutyShapeObj = nullptr; // if DutyShapeobj = nil then the load alway stays nominal * global multipliers + DebugTrace = false; + FMonObj = nullptr; + Yorder = Fnterms * Fnconds; + ShapeIsActual = false; + Generic5SwitchOpen = false; + MachineData.kVGeneratorBase = 12.47; + MachineData.kVArating = kWBase * 1.2; + /*# with MachineData do */ + { + auto& with0 = MachineData; + with0.Hmass = 1.0; // W-sec/VA rating + with0.Theta = 0.0; + with0.w0 = TwoPi * BaseFrequency; + with0.Speed = 0.0; // relative speed + with0.dSpeed = 0.0; + with0.D = 1.0; + with0.XRdp = 20.0; // not used for indmach + + // newly added + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + } + + /*---- end note Andres: from dll model ----*/ + + /*Typical machine impedance data*/ + puRs = 0.0053; + puXs = 0.106; + puRr = 0.007; + puXr = 0.12; + puXm = 4.0; + + // Set slip local and make generator model agree + MaxSlip = 0.1; // 10% slip limit - set this before setting slip + //Slip := -0.007; // About 1 pu power + FixedSlip = false; // Allow Slip to float to match specified power + InDynamics = false; + + // call the procedure to set the initial property string values + InitPropertyValues(0); + //NumOrder := 2; + NumOrderX = Norder;//2;// // system order + NumOrderY = Norder; //2;//// system output Y order + /*A,B,C,D, X_var, Y_out_var, V_in_var matrix*/ + Amm = new double[Norder * Norder];// dot X = Ax +Bu + Bmn = new double[Norder * Norder];// suppose Y and U have the same dimesion. Square + Cnm = new double[Norder * Norder]; + Dnn = new double[Norder * Norder]; + X_var = new double[Norder]; + dX_vardt = new double[Norder]; + X_varn = new double[Norder]; // for trapezoid integration + dX_vardtn = new double[Norder]; // for trapezoid integration + Y_out_var = new double[Norder]; + V_in_var = new double[Norder]; + pV_f_CC = new double[Norder]; + //Allocate ABCDXYV + /*A,B matrix, X_var*/ //5 order system + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + (Amm)[(i - 1) * Norder + j - 1] = 0.0;//CMPLX(0.0, 0.0); + //if j=i then + // Amm^[(i-1)*nOrder +j] := 1;//Amm := 0; + } + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + (Bmn)[(i - 1) * Norder + j - 1] = 0.0;//CMPLX(0.0, 0.0); + if(j == i) + (Bmn)[(i - 1) * Norder + j - 1] = 1; + } + (X_var)[i - 1] = 0.0;//CMPLX(0.0, 0.0); + (dX_vardt)[i - 1] = 0.0;// derivatives + (X_varn)[i - 1] = 0.0;// for trapezoid + (dX_vardtn)[i - 1] = 0.0;// derivatives + } + /*C,D Matrix, Y, V*/ + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + (Dnn)[(i - 1) * Norder + j - 1] = 0.0;//CMPLX(0.0, 0.0); + } + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + (Cnm)[(i - 1) * Norder + j - 1] = 0.0;//CMPLX(0.0, 0.0); + if(i == j) + (Cnm)[(i - 1) * Norder + j - 1] = 1; + } + (Y_out_var)[i - 1] = 0.0;//CMPLX(0.0, 0.0); + (V_in_var)[i - 1] = 0.0;//CMPLX(0.0, 0.0); + (pV_f_CC)[i - 1] = 0.0; + } + P_ref = 0; + V_ref = 1; + id = 0; + Iq = 0;//default current + ID1 = 0; + Iq1 = 0; + ID2 = 0; + Iq2 = 0; + Id3 = 0; + Iq3 = 0;// + /**/ + kcd = 0.1; + kcq = 0.1; + kqi = 0.1; //for local control gain in vi1, vi2 + Volt_Trhd = 0.0; + //Id_ref := 1; + //Iq_ref := 0; + Cluster_num = 0;//by default. + // Update anything that has to be calculated from property values + DQDV = 1;// + ctrl_mode = 0;// avg contrl by default + QV_flag = 0; + //QV_flag_0 := QV_flag; + /*------------------*/ + //PQ max + PMax = (double) -1; // Activity power output limit MachineData.kVArating := 1.2*kWbase; Pmax, Smax + PMax_phase = PMax / Fnphases; //limit per phase + PMin = 0; //(0, default) + Pmin_phase = PMin / Fnphases; // + Qmax = 1000 * MachineData.kVArating; //Reactive power output limit + Qmax_phase = Qmax / Fnphases; + Qmin = -Qmax; //(-Qmax, default) + Qmin_phase = Qmin / Fnphases; // + PQpriority = 1;//P priority + Pmpp = 1;//Pmpp, default value is 1.0); + Pbias = 0; //Pbias, default value is 0.0; + Pfctr1 = 1;//factors, default value all are 1.0; + Pfctr2 = 1; + Pfctr3 = 1; + Pfctr4 = 1; + Pfctr5 = 1; + Pfctr6 = 1; + /*------------------*/ + kcq_drp2 = 0; + CC_Switch = false; + flag_dyna_Id_chg = false; + z_dfs_plot = 0.0; + RecalcElementData(ActiveActor); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Free everything here that needs to be freed +// If you allocated anything, dispose of it here + +TGeneric5Obj::~TGeneric5Obj() +{ + + + //A, B matrix + if(ASSIGNED(Amm)) + delete[] Amm; + if(ASSIGNED(Bmn)) + delete[] Bmn; + if(ASSIGNED(Cnm)) + delete[] Cnm; + if(ASSIGNED(Dnn)) + delete[] Dnn; + if(ASSIGNED(X_var)) + delete[] X_var; + if(ASSIGNED(dX_vardt)) + delete[] dX_vardt; + if(ASSIGNED(X_varn)) + delete[] X_varn; + if(ASSIGNED(dX_vardtn)) + delete[] dX_vardtn; + if(ASSIGNED(Y_out_var)) + delete[] Y_out_var; + if(ASSIGNED(V_in_var)) + delete[] V_in_var; + delete[] pV_f_CC; + // inherited::Destroy(); // This will take care of most common circuit element arrays, etc. +} + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::RecalcElementData(int ActorID) +{ + double Rs = 0.0; + double Xs = 0.0; + double rr = 0.0; + double Xr = 0.0; + double XM = 0.0; + double ZBase = 0.0; + bool modetest = false; + int numPhase = 0; + int dotpos = 0; + String StrTemp; + /*# with MachineData do */ + { + auto& with0 = MachineData; + ZBase = Sqr(with0.kVGeneratorBase) / with0.kVArating * 1000.0; + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + } + Rs = puRs * ZBase; + Xs = puXs * ZBase; + rr = puRr * ZBase; + Xr = puXr * ZBase; + XM = puXm * ZBase; + Zs = cmplx(Rs, Xs); + ZM = cmplx(0.0, XM); + Zr = cmplx(rr, Xr); + Xopen = Xs + XM; + Xp = Xs + (Xr * XM) / (Xr + XM); + Zsp = cmplx(Rs, Xp); + //Yeq := Cinv(Zsp); // for Yprim for dynamics + //Yeq := Cmplx(1.0/ZBase, -0.5/Zbase); // vars are half the watts + Yeq = cmplx(0.0, -1.0 / ZBase); // vars only for power flow + T0p = (Xr + XM) / (MachineData.w0 * rr); + + // dSdP := Compute_dSdP; + Is1 = CZero; + V1 = CZero; + Is2 = CZero; + V2 = CZero; + FirstIteration = true; + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + SetNominalPower(ActorID); + /////////////////////////////////////////// + /// contrl mode + /// ctrl_mode =0; phases = 3; // pos avg control---p_ref, V_ref, Q_ref + /// ctrl_mode =1; phases = 1; bus1 = 452.1; ---p_ref1, V_ref1, Q_ref1 + /// ctrl_mode =2; phases = 1; bus1 = 452.2; ---p_ref2, V_ref2, Q_ref2 + /// ctrl_mode =3; phases = 1; bus1 = 452.3; ---p_ref3, V_ref3, Q_ref3 + /// ctrl_mode =4; phases = 3; bus1 = 452.2; ---p_ref1,2,3, V_ref1,2,3, Q_ref1,2,3 + /// + /////////////////////////////////////////// + modetest = false; + if(((ctrl_mode == 0) || (ctrl_mode == 4)) && (Fnphases == 3)) + modetest = true; + else + { + if(Fnphases == 1) + { + if((ctrl_mode == 1) || (ctrl_mode == 2) || (ctrl_mode == 3)) + { + StrTemp = Get_FirstBus(); //only one + dotpos = Pos(".", StrTemp); + if(dotpos != 0) + { + numPhase = Sysutils::StrToInt(Trim(StrTemp.substr(dotpos, 1))); // Bus Name . node Num + if(numPhase == ctrl_mode) + modetest = true; + } + } + } + } + if(modetest == false) + DoSimpleMsg("ctrl_mode and bus node connection dont match, see help for generic5.ctrl_mode", 561); + ////////////////////////////////////////////// + //if cluster_num >= 1 then // assign the virtue leader to this DG + //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); + //if function 'get' fails , return nil + ////////////////////////////////////////////// + if(CompareText(YearlyShape, "none") == 0) + YearlyShape = ""; + if(CompareText(DailyDispShape, "none") == 0) + DailyDispShape = ""; + if(CompareText(DutyShape, "none") == 0) + DutyShape = ""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 563); + } + if(DailyDispShapeObj == nullptr) + { + if(DailyDispShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyDispShape + + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 565); + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 566); + if(DebugTrace) + InitTraceFile(); +} + /* +Procedure TGeneric5Obj.CalcABMatrix ; +//var +// i,j :Integer; +begin + //this is useless. All things is to be done in updateabcd +end; + + +procedure TGeneric5Obj.InterpretOption(s: String); +begin + Case Uppercase(s)[1] of + 'F': Fixedslip := TRUE; + 'V': Fixedslip := FALSE; + Else + + End; +end; + +//---------------------------------------------------------------------------- */ + +void TGeneric5Obj::SetPowerkW(double PkW) +{ + kWBase = PkW; +} + +void TGeneric5Obj::Set_PresentkV(double Value) +{ + /*# with MachineData do */ + { + auto& with0 = MachineData; + with0.kVGeneratorBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = with0.kVGeneratorBase * InvSQRT3x1000; + break; + default: + VBase = with0.kVGeneratorBase * 1000.0; + break; + } + } +} + +double TGeneric5Obj::Get_PresentkV() +{ + double result = 0.0; + result = MachineData.kVGeneratorBase; + return result; +} + +//---------------------------------------------------------------------------- +//--------------------- MAIN CALC ROUTINES ----------------------------------- + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::Integrate(int ActorID) +{ + double H2 = 0.0; + if(ctrl_mode == 0) + { + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + if(with0.IterationFlag == 0) // on predictor step + { + Idn = id; + Iqn = Iq; + dIddtn = dIddt; + dIqdtn = dIqdt; + vi1n = vi1; + vi2n = vi2; + dvi1dtn = dvi1dt; + dvi2dtn = dvi2dt; + } + update_system_abcd(); //vi1, vi2 calculation + H2 = with0.h * 0.5; + Id_ref = kcd * P_ref / V_DG;//active + Iq_ref = Q_DG / V_DG; //V_ref ~= 1; reactive + //vi1 := kcq* (Iq_ref - Iq); + DPX = P_ref - P_DG; + vi1 = 1 * kcd * DPX / V_DG;//+ kcq* (Iq_ref - Iq);//+ //active + additional control + //vi2 := kcd* (Id_ref - Id); //reactive + dvi1dt = kcd * (DPX); + //dvi2dt := -kcd* (V_ref-V_DG) ; //voltage droop control + if(QV_flag == 1) //voltage droop control + vi2 = kcq * (V_ref - V_DG); + else + vi2 = kqi * (Q_ref - Q_DG); + /*--------------------------------------------*/ + dIddt = vi1;//1; //active P + dIqdt = vi2;//2; //reactive Q + id = Idn + H2 * (dIddt + dIddtn); + Iq = Iqn + H2 * (dIqdt + dIqdtn); + } + } +} +/*-------------------------------------------------------------------------------*/ +/*integrate with ABCD*/ +//---------------------------------------------------------------------------- + +void TGeneric5Obj::IntegrateABCD(int ActorID) +{ + double H2 = 0.0; + int i = 0; + int j = 0; + int stop = 0; + if(ActiveCircuit[ActorID]->Solution->DynaVars.IterationFlag == 0) + { + int stop = 0; + for(stop = NumOrderX, i = 1; i <= stop; i++) + { + (X_varn)[i - 1] = (X_var)[i - 1]; + (dX_vardtn)[i - 1] = (dX_vardt)[i - 1]; + } + } + update_system_abcd(); //Matrix ABCD calculation if they are state-dependant + update_controlinput(ActorID); //vi1, vi2 calculation, + // co control strategies from network vfi can be done here + //dX_vardt calculation + for(stop = NumOrderX, i = 1; i <= stop; i++) + { // numOrderX, numOrderY should be less than norder 5 + int stop1 = 0; + (dX_vardt)[i - 1] = 0.0; + for(stop1 = NumOrderY, j = 1; j <= stop1; j++) + { + (dX_vardt)[i - 1] = (dX_vardt)[i - 1] + (Amm)[Norder * (i - 1) + j - 1] * (X_var)[j - 1] + (Bmn)[Norder * (i - 1) + j - 1] * (V_in_var)[j - 1]; + //cooperate control if exist is involved in + } + } + + // Trapezoidal Integration + H2 = ActiveCircuit[ActorID]->Solution->DynaVars.h * 0.5; + for(stop = NumOrderX, i = 1; i <= stop; i++) + { + (X_var)[i - 1] = (X_varn)[i - 1] + H2 * ((dX_vardtn)[i - 1] + (dX_vardt)[i - 1]); + } + /*----------------*/ + //Y=CX to be added + /*----------------*/ + /// + /// the following is to connect with calcDynamic or CalcDynamicVIabc + /// because Id, Iq; Id1, Iq1, Id2, Iq2, Id3, Iq3 will be used there + if(ctrl_mode == 0) //pos seq control + { + id = (X_var)[1 - 1];//can be put in calcdyna, so the integrate is just for X_var + Iq = (X_var)[2 - 1]; + } + else + // all other ctrl_mode's are phase control modes + { + ID1 = (X_var)[1 - 1];//1st phase, or the only phase if fnphases=1 + Iq1 = (X_var)[2 - 1];//can be put in calcdyna in futher, so the integrate is just for X_var + ID2 = (X_var)[3 - 1];//2nd phase; zero if single phase + Iq2 = (X_var)[4 - 1]; + Id3 = (X_var)[5 - 1];//3rd phase; zero if single phase + Iq3 = (X_var)[6 - 1]; + } +} +/*-------------------------------------------------------------------------------*/ +//This part deals with the control input, is based on the voltage measurement + +void TGeneric5Obj::update_controlinput(int ActorID) +{ + int j = 0; + double temp_pref = 0.0; + double temp_qref = 0.0; + double temp_vref = 0.0; + double Pref3 = 0.0; + //Update_PQlimits; + /////////////////////////////////// + //local control input and alpha gradient calculation + /////////////////////////////////// + //gradient, gradient1, gradient2, gradient3 + // gradient will be calculated in FMonitor because of Bii, Q_Di etc + //calculate_gradient; //alpha, and gradients, + //V_DG, Q_DG have been updated either in 'init' or in 'calcdynamic' + int stop = 0; + if(ctrl_mode == 0) //pos seq control mode + + //Id + // P and Q control + /* + //Iq + if QV_flag=1 then + vi2 := kcq* (V_ref - V_DG) //reactive V_ref control + else + vi2 := kqi* (Q_ref - Q_DG); //reactive Q_ref control + */ + // vi1, vi2 local gradient + // vi1, vi2 =0, local gradient calculated outside + { + vi1 = 0; + vi2 = 0; // local gradient calculated IN fMONITOR Node + /*---if in curtailment P_ref has to be changed here-----*/ + if((ActiveCircuit[ActorID]->Solution->bCurtl == true) && (FMonObj->ld_fm_info[0].b_ctrl_hghst == true)) + //if (ActiveCircuit.Solution.bCurtl=true) then // this will cause oscillation + { + Pref3 = V_DG * id; //Here, P_ref will never go out of limits. + //if cuitailment is needed, update P_ref here; then vi1 will be 0 + //check limits + if(Pref3 > PMax) + { + Pref3 = PMax; //set real power change during the simulation + } + else + { + if(Pref3 < PMin) + { + Pref3 = PMin; + } + } + P_ref = Pref3 / 3.0; + } + /*--use vi1 to follow p_ref--*/ + DPX = Fnphases * P_ref - P_DG; + vi1 = 100 * kcd * DPX / V_DG; //pref control is 100 times faster than Curtailment + //update V_in_var + (V_in_var)[1 - 1] = vi1; + (V_in_var)[2 - 1] = vi2; + } + else + //phases control mode + { + if(Fnphases == 3) + //12 + { + DPX = P_ref1 - P_DG1; + vi1 = kcd * DPX / V_DG1; + //Iq + if(QV_flag == 1) + { + if(CC_Switch == false) //droop + //reactive V_ref control + //gradient + vi2 = kcq * (V_ref1 - V_DG1); + else + vi2 = Qmax_phase / V_DG1 * (-kcq * Gradient1); + if((Q_DG1 >= Qmax_phase) || (Q_DG1 <= Qmin_phase)) // switch control mode to Q_ref control + + //QV_flag := 0; + { + if(Q_DG1 >= Qmax_phase) + { + Q_ref1 = Qmax_phase; // set Q_ref + Q_ref2 = Qmax_phase; // set Q_ref + Q_ref3 = Qmax_phase; // set Q_ref + } + else + { + Q_ref1 = Qmin_phase; + Q_ref2 = Qmin_phase; + Q_ref3 = Qmin_phase; + } + vi2 = kqi * (Q_ref1 - Q_DG1); //reactive Q_ref control + } + } + else + vi2 = kqi * (Q_ref1 - Q_DG1); //reactive Q_ref control + //update V_in_var + (V_in_var)[1 - 1] = vi1; + (V_in_var)[2 - 1] = vi2; + //34 + DPX = P_ref2 - P_DG2; + vi1 = kcd * DPX / V_DG2; + //Iq + if(QV_flag == 1) + { + if(CC_Switch == false) //droop + //reactive V_ref control + //gradient + vi2 = kcq * (V_ref2 - V_DG2); + else + vi2 = Qmax_phase / V_DG2 * (-kcq * Gradient2); + if((Q_dg2 >= Qmax_phase) || (Q_dg2 <= Qmin_phase)) // switch control mode to Q_ref control + + //QV_flag:=0; + { + if(Q_dg2 >= Qmax_phase) + { + Q_ref1 = Qmax_phase; // set Q_ref + Q_ref2 = Qmax_phase; // set Q_ref + Q_ref3 = Qmax_phase; // set Q_ref + } + else + { + Q_ref1 = Qmin_phase; + Q_ref2 = Qmin_phase; + Q_ref3 = Qmin_phase; + } + vi2 = kqi * (Q_ref2 - Q_dg2); //reactive Q_ref control + } + } + else + vi2 = kqi * (Q_ref2 - Q_dg2); //reactive Q_ref control + //update V_in_var + (V_in_var)[3 - 1] = vi1; + (V_in_var)[4 - 1] = vi2; + //56 + DPX = P_ref3 - P_dg3; + vi1 = kcd * DPX / V_DG3; + //Iq + if(QV_flag == 1) + { + if(CC_Switch == false) //droop + //reactive V_ref control + //gradient + vi2 = kcq * (V_ref3 - V_DG3); + else + vi2 = Qmax_phase / V_DG3 * (-kcq * Gradient3); + if((Q_dg3 >= Qmax_phase) || (Q_dg3 <= Qmin_phase)) // switch control mode to Q_ref control + + //QV_flag := 0; + { + if(Q_dg3 >= Qmax_phase) + { + Q_ref1 = Qmax_phase; // set Q_ref + Q_ref2 = Qmax_phase; // set Q_ref + Q_ref3 = Qmax_phase; // set Q_ref + } + else + { + Q_ref1 = Qmin_phase; + Q_ref2 = Qmin_phase; + Q_ref3 = Qmin_phase; + } + vi2 = kqi * (Q_ref3 - Q_dg3); //reactive Q_ref control + } + } + else + vi2 = kqi * (Q_ref3 - Q_dg3); //reactive Q_ref control + //update V_in_var + (V_in_var)[5 - 1] = vi1; + (V_in_var)[6 - 1] = vi2; + } + else + { + if(Fnphases == 1) + //choose ref + { + switch(ctrl_mode) + { + case 1: + { + temp_pref = P_ref1; + temp_qref = Q_ref1; + temp_vref = V_ref1; + } + break; + case 2: + { + temp_pref = P_ref2; + temp_qref = Q_ref2; + temp_vref = V_ref2; + } + break; + case 3: + { + temp_pref = P_ref3; + temp_qref = Q_ref3; + temp_vref = V_ref3; + } + break; + default: + ; + break; + } + DPX = temp_pref - P_DG1; + vi1 = kcd * DPX / V_DG1; + //Iq + if(QV_flag == 1) + { + if(CC_Switch == false) //droop + //reactive V_ref control + vi2 = kcq * (temp_vref - V_DG); + else + vi2 = Qmax_phase / V_DG1 * (-kcq * Gradient1); + if((Q_DG1 >= Qmax_phase) || (Q_DG1 <= Qmin_phase)) // switch control mode to Q_ref control + + //QV_flag := 0; + { + if(Q_DG1 >= Qmax_phase) // set Q_ref + temp_qref = Qmax_phase; + else + temp_qref = Qmin_phase; + // + vi2 = kqi * (temp_qref - Q_DG); //reactive Q_ref control + //send Qref back + //q_ref1 := temp_qref; + //q_ref2 := temp_qref; + //q_ref3 := temp_qref; + } + } + else + vi2 = kqi * (temp_qref - Q_DG); //reactive Q_ref control + //update V_in_var + (V_in_var)[1 - 1] = vi1; + (V_in_var)[2 - 1] = vi2; + } + } + } + /*--------------------------------*/ + // cooperate part is done here + //pVinput^[j]; + update_pV_f_CC(ActorID); //update pV_f_CC which is cooperate control + /*--------------------------------*/ +//implement cooperate control + for(stop = NumOrderX, j = 1; j <= stop; j++) + { + (V_in_var)[j - 1] = (V_in_var)[j - 1] + (pV_f_CC)[j - 1]; + } +} //for power flow + +void TGeneric5Obj::update_pV_f_CC_M2(int ActorID) +{ + int j = 0; + int num_vleader = 0; + double Bii = 0.0; + if(CC_Switch == false) + { + int stop = 0; + for(stop = NumOrderX, j = 1; j <= stop; j++) + { + (pV_f_CC)[j - 1] = 0.0; + } + return; + } + + //avg ctrl, under V120, I120 + ////////////////////////////////// + if(FMonObj != nullptr) + //try + { + num_vleader = 1; + ///////////////////////////////// + if(ctrl_mode == 0) + //u = gradient + pV_f_CC; pV_f_CC = -alpha + sum(alpha_j) + { + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[1 - 1]].im; + // Q ctrl with v_ref + // pV_f_CC^[2] := FmonObj.Calc_Alpha_M2(ndNumincluster,0,NodeRef^[1],Bii,kcq,Volt_Trhd); // for dIddt, diqdt + // Q ctrl with loss + //pV_f_CC^[2] := FmonObj.Calc_Alpha_L(ndNumincluster,0,NodeRef^[1],Bii,kcq,Volt_Trhd); + (pV_f_CC)[2 - 1] = FMonObj->Calc_Alpha_LnM2(NdNumInCluster, 0, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); + // pV_f_CC^[2] := alpha * Qmax / v ; + //P ctrl + //pV_f_CC^[1] := FmonObj.Calc_AlphaP(ndNumincluster,0); // for dIddt, diqdt + (pV_f_CC)[1 - 1] = 0; + // phases control + } + else + { + if(Fnphases == 3) + { + (pV_f_CC)[6 - 1] = 0.0; + //u = gradient + pV_f_CC; pV_f_CC = -alpha + sum(alpha_j) + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[1 - 1]].im; + (pV_f_CC)[2 - 1] = FMonObj->Calc_Alpha_M2(NdNumInCluster, 1, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); + //pV_f_CC^[2] := FmonObj.Calc_Alpha_L(ndNumincluster,1,NodeRef^[1],Bii,kcq,Volt_Trhd); + //pV_f_CC^[2] := FmonObj.Calc_Alpha_LnM2(ndNumincluster,1,NodeRef^[1],Bii,kcq,Volt_Trhd); + (pV_f_CC)[1 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, 1, ActorID); + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[2 - 1]].im; + (pV_f_CC)[4 - 1] = FMonObj->Calc_Alpha_M2(NdNumInCluster, 2, (NodeRef)[2 - 1], Bii, kcq, Volt_Trhd, ActorID); + //pV_f_CC^[4] := FmonObj.Calc_Alpha_L(ndNumincluster,2,NodeRef^[2],Bii,kcq,Volt_Trhd); + //pV_f_CC^[4] := FmonObj.Calc_Alpha_LnM2(ndNumincluster,2,NodeRef^[2],Bii,kcq,Volt_Trhd); + (pV_f_CC)[3 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, 2, ActorID); + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[3 - 1]].im; + (pV_f_CC)[6 - 1] = FMonObj->Calc_Alpha_M2(NdNumInCluster, 3, (NodeRef)[3 - 1], Bii, kcq, Volt_Trhd, ActorID); + //pV_f_CC^[6] := FmonObj.Calc_Alpha_L(ndNumincluster,3,NodeRef^[3],Bii,kcq,Volt_Trhd); + //pV_f_CC^[6] := FmonObj.Calc_Alpha_LnM2(ndNumincluster,3,NodeRef^[3],Bii,kcq,Volt_Trhd); + (pV_f_CC)[5 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, 3, ActorID); + //pV_f_CC[1-6]; // for dIddt1, diqdt1,dIddt2, diqdt2,dIddt3, diqdt3 + } + else + { + if(Fnphases == 1) + //if ctrl_mode=1 then + { + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[1 - 1]].im; + (pV_f_CC)[2 - 1] = FMonObj->Calc_Alpha_M2(NdNumInCluster, ctrl_mode, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); // for dIddt1, diqdt1 + //pV_f_CC^[2] := FmonObj.Calc_Alpha_L(ndNumincluster,ctrl_mode,NodeRef^[1],Bii,kcq,Volt_Trhd); // for dIddt1, diqdt1 + //pV_f_CC^[2] := FmonObj.Calc_Alpha_LnM2(ndNumincluster,ctrl_mode,NodeRef^[1],Bii,kcq,Volt_Trhd); + (pV_f_CC)[1 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, ctrl_mode, ActorID); + } + } + } + } +} //used in dynamic mode to update alpha + +void TGeneric5Obj::update_pV_f_CC(int ActorID) +{ + int p_mode = 0; + int j = 0; + int num_vleader = 0; + double Bii = 0.0; + double us_i = 0.0; + double ul_i = 0.0; + if(CC_Switch == false) //no control at all //local gradient control will be set by communication matrix + { + int stop = 0; + for(stop = NumOrderX, j = 1; j <= stop; j++) + { + (pV_f_CC)[j - 1] = 0.0; + } + return; + } + + //avg ctrl, under V120, I120 + ////////////////////////////////// + if(FMonObj != nullptr) + //try + { + num_vleader = 1; + ///////////////////////////////// + if(ctrl_mode == 0) + { + p_mode = 0; + if(FMonObj != nullptr) + p_mode = FMonObj->Get_P_mode(ActorID); + //u = gradient + pV_f_CC; pV_f_CC = -alpha + sum(alpha_j) + Bii = ActiveCircuit[ActorID]->Solution->NodeYii[(NodeRef)[1 - 1]].im; + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + //Ip control + { + if(FMonObj->ld_fm_info[0].b_Curt_Ctrl == true) // curtailment algorithm + { + ul_i = FMonObj->Calc_ul_P(NdNumInCluster, 0); + us_i = kcd * FMonObj->Calc_Gradient_ct_P(NdNumInCluster, 0, ActorID); + GradientP = us_i; + if(CC_Switch == false) //local + (pV_f_CC)[1 - 1] = 0.0; + else + { + (pV_f_CC)[1 - 1] = ul_i + us_i; + (pV_f_CC)[1 - 1] = (pV_f_CC)[1 - 1] * PMax / V_DG; + } + } + + //if pMode then + if((p_mode == 1) && (CC_Switch == true)) //if delta P = p_trans_ref - p_trans + //balance p_trans + { + (pV_f_CC)[1 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, 0, ActorID);//new alfa_p + (pV_f_CC)[1 - 1] = (pV_f_CC)[1 - 1] - AlphaP; //derivative of alfa_p + //use us_i to calculate the frequncy + us_i = -FMonObj->omg_fm; //frequency droop + (pV_f_CC)[1 - 1] = ((pV_f_CC)[1 - 1] + us_i) * PMax / V_DG; // derivative of Ip in dynamic mode, + //use us_i to + } + + //Iq control + ul_i = FMonObj->Calc_fm_ul_0(NdNumInCluster, 0, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); + us_i = FMonObj->Calc_fm_us_0(NdNumInCluster, 0, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); + Gradient = us_i; + if(FMonObj->ld_fm_info[0].b_Curt_Ctrl == false) + ; + else + // if curtailment for this cluster is off + // if curtailment for this cluster is on + //Q will try to boost the voltage while P is decreasing + { + if((ActiveCircuit[ActorID]->Solution->bCurtl == true) && (Gradient == 0.0)) + us_i = -GradientP * PMax / Qmax; + } + if(CC_Switch == false) //local + { + (pV_f_CC)[2 - 1] = us_i; + } + else + // cc_switch is on + { + (pV_f_CC)[2 - 1] = ul_i + us_i; //cc //attack comes in ul_i (FmonObj.Calc_fm_ul_0) + } + (pV_f_CC)[2 - 1] = (pV_f_CC)[2 - 1] * Qmax / V_DG; + } + else + //power flow + + //alphaP: p ratio + + //if pMode then + { + if((p_mode == 1) || (FMonObj->ld_fm_info[0].b_Curt_Ctrl == true)) + (pV_f_CC)[1 - 1] = FMonObj->Calc_AlphaP(NdNumInCluster, 0, ActorID); + else + (pV_f_CC)[1 - 1] = 0.0; + //alpha : q ratio + (pV_f_CC)[2 - 1] = FMonObj->Calc_Alpha_M2(NdNumInCluster, 0, (NodeRef)[1 - 1], Bii, kcq, Volt_Trhd, ActorID); // for dIddt, diqdt + } + } + } +} +//var +// j : integer; + +void TGeneric5Obj::InfoPublish(int ActorID) +{ + Update_PQlimits(); + if(FMonObj != nullptr) + { + /*# with FMonObj->pNodeFMs^[NdNumInCluster] do */ + { + auto& with0 = (FMonObj->pNodeFMs)[NdNumInCluster]; + switch(ctrl_mode) + { + case 1: + { + with0.vl_V1 = V_DG1;//Phase A or the first phase if there are less than 3 phases + with0.vl_p_DG1 = P_DG1; + with0.vl_q_DG1 = Q_DG1; + //vl_Alpha1_dg := Alpha1; + //vl_AlphaP1_dg := AlphaP1; + with0.vl_V_ref1_dg = V_ref1; + } + break; + case 2: + { + with0.vl_V2 = V_DG2;//Phase B if exists + with0.vl_p_DG2 = P_DG2; + with0.vl_q_DG2 = Q_dg2; + //vl_Alpha2_dg := Alpha2; + //vl_AlphaP2_dg := AlphaP2; + with0.vl_V_ref2_dg = V_ref2; + } + break; + case 3: + { + with0.vl_V3 = V_DG3;//Phase c if exists + with0.vl_p_DG3 = P_dg3; + with0.vl_q_DG3 = Q_dg3; + //vl_Alpha3_dg := Alpha3; + //vl_AlphaP3_dg := AlphaP3; + with0.vl_V_ref3_dg = V_ref3; + } + break; + case 0: + { + with0.vl_V = V_DG; //0 seq , will be used in FmonObj.Agnt_smpl + with0.vl_p_DG = P_DG; + with0.vl_q_DG = Q_DG; + // + Alpha = Q_DG / Qmax; + with0.vl_Alpha_dg = Alpha; // update first, will be used in FmonObj.Agnt_smpl + //P control + AlphaP = P_DG / PMax; + with0.vl_AlphaP_dg = AlphaP; + // + with0.vl_V_ref_dg = V_ref; + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + { + z_dfs_plot = with0.z_dfs; // defense value + } + } + break; + case 4: + { + with0.vl_V1 = V_DG1;//Phase A or the first phase if there are less than 3 phases + with0.vl_p_DG1 = P_DG1; + with0.vl_q_DG1 = Q_DG1; + with0.vl_V2 = V_DG2;//Phase B if exists + with0.vl_p_DG2 = P_DG2; + with0.vl_q_DG2 = Q_dg2; + with0.vl_V3 = V_DG3;//Phase c if exists + with0.vl_p_DG3 = P_dg3; + with0.vl_q_DG3 = Q_dg3; + with0.vl_V_ref1_dg = V_ref1; + with0.vl_V_ref2_dg = V_ref2; + with0.vl_V_ref3_dg = V_ref3; + + //vl_Alpha1_dg := Alpha1; + //vl_AlphaP1_dg := AlphaP1; + //vl_V_ref1_dg := V_ref1; + //vl_Alpha2_dg := Alpha2; + //vl_AlphaP2_dg := AlphaP2; + //vl_V_ref2_dg := V_ref2; + //vl_Alpha3_dg := Alpha3; + //vl_AlphaP3_dg := AlphaP3; + //vl_V_ref3_dg := V_ref3; + } + break; + default: + ; + break; + } + with0.vl_Qmax_dg = Qmax; + with0.vl_Qmax_phase_dg = Qmax_phase; + with0.vl_Pmax_dg = PMax; + with0.vl_Pmax_phase_dg = PMax_phase; + with0.vl_CC_switch_dg = CC_Switch; + with0.vl_QV_flag_dg = QV_flag; + with0.vl_kcd_dg = kcd; + with0.vl_kcq_dg = kcq; + with0.vl_volt_thrd_dg = Volt_Trhd; + } + } + /*with FmonObj2.pNodeFMs^[NdNuminCluster2] do + begin + + vl_V := V_DG; + vl_P_DG := P_DG; + vl_Q_DG := Q_DG; + vl_V1 := V_DG1;//Phase A or the first phase if there are less than 3 phases + vl_P_DG1 := P_DG1; + vl_Q_DG1 := Q_DG1; + vl_V2 := V_DG2;//Phase B if exists + vl_P_DG2 := P_DG2; + vl_Q_DG2 := Q_DG2; + vl_V3 := V_DG3;//Phase c if exists + vl_P_DG3 := P_DG3; + vl_Q_DG3 := Q_DG3; + vl_Qmax_dg := Qmax; + vl_Qmax_phase_dg := Qmax_Phase; + vl_Pmax_dg := Pmax; + vl_Pmax_phase_dg := Pmax_Phase; + vl_Alpha_dg := alpha; + vl_Alpha1_dg := Alpha1; + vl_Alpha2_dg := Alpha2; + vl_Alpha3_dg := Alpha3; + vl_AlphaP_dg := alphaP; + vl_AlphaP1_dg := AlphaP1; + vl_AlphaP2_dg := AlphaP2; + vl_AlphaP3_dg := AlphaP3; + vl_V_ref_dg := V_ref; + vl_V_ref1_dg := V_ref1; + vl_V_ref2_dg := V_ref2; + vl_V_ref3_dg := V_ref3; + vl_CC_switch_dg := CC_switch; + vl_QV_flag_dg := QV_flag; + + end; */ + if(FMonObj2 != nullptr) + ; +} + +void TGeneric5Obj::Set_P_Ref(double PrefkW, int ActorID) +{ + P_ref = (double) (1000 * PrefkW / Fnphases); //nphases + P_ref1 = P_ref; + P_ref2 = P_ref; + P_ref3 = P_ref; + if(PrefkW > kWBase) + DoSimpleMsg("P ref should be leq than kW", 562); + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) //if P_ref changed in the dynamic simulation + //The sudden change of Id has to be applied + { + flag_dyna_Id_chg = true; + } + // +} + +void TGeneric5Obj::Set_Q_Ref(double QrefkVAr) +{ + + // + Q_ref = (double) (1000 * QrefkVAr / Fnphases); //nphases + Q_ref1 = Q_ref; + Q_ref2 = Q_ref; + Q_ref3 = Q_ref; +} + +void TGeneric5Obj::Set_V_Ref(double VrefkV) +{ + + // + V_ref = 1000 * VrefkV; + V_ref1 = V_ref; + V_ref2 = V_ref; + V_ref3 = V_ref; +} + +void TGeneric5Obj::Update_kWbase_by_Fctrs() +{ + kWBase = (Pmpp + Pbias) * Pfctr1 * Pfctr2 * Pfctr3 * Pfctr4 * Pfctr5 * Pfctr6; + kWBase = kWBase / 1000; + Update_PQlimits(); +} + +void TGeneric5Obj::update_system_abcd() +{ + + //2 order system example + //Amn := Zeros; + //Bmn := I; + //Cnm := I; + /*-Done in the initial part-*/ +} + +void TGeneric5Obj::UpdateAlpha_qi() +{ + + //Update_PQlimits; + if(Qmax > EPSILON) + //pos control + { + Alpha = Q_DG / Qmax; + // phase control + Alpha1 = Q_DG1 / Qmax_phase; + if(Fnphases == 3) + { + Alpha2 = Q_dg2 / Qmax_phase; + Alpha3 = Q_dg3 / Qmax_phase; + } + } +} + +void TGeneric5Obj::Update_PQlimits() +{ + if(PQpriority == 1) //P prior by default + { + if((PMax <= 0) || (PMax > kWBase)) + PMax = kWBase * 1000;// first value is set to be kWbase; when kWbase is set, Pmax will be update in edit; + PMax = kWBase * 1000;//if PQpriority=1 then + //if (Pmax <0 )or (Pmax > kWBase*1000) then Pmax := kWBase*1000; + //Pmax + //Pmax; should be what it is + //P_DG + if(1000 * MachineData.kVArating >= P_DG) // Pmax P_DG + // PMax*PMax)// + Qmax = sqrt(MachineData.kVArating * 1000 * MachineData.kVArating * 1000 - P_DG * P_DG); + else + Qmax = EPSILON; //error when used as demoninator + Qmin = -Qmax; + } + else + { + if(PQpriority == 0) //Q prior + { + Qmax = MachineData.kVArating; + Qmin = -MachineData.kVArating; + PMax = min(sqrt(MachineData.kVArating * 1000 * MachineData.kVArating * 1000 - Q_DG * Q_DG), kWBase * 1000); //which one is smaller + PMin = 0; + //Pmax_phase := Pmax / fnphases; + //Pmin_phase := Pmin / fnphases; + } + //if machinedata.kVArating <= 0 then + //begin + // if fmonobj <> nil then + // Qmax := fmonobj.CalcAvgQmax; //if the node is without control, Qmax := cluster avg + //end; + } + PMax_phase = PMax / Fnphases; + Pmin_phase = PMin / Fnphases; + Qmax_phase = Qmax / Fnphases; + Qmin_phase = Qmin / Fnphases; + //used for limit currents derivative + IdMax_phase = PMax_phase / (VBase);// vBase := kVGeneratorBase*InvSQRT31000 + IqMax_phase = Qmax_phase / (VBase); +} +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcDynamic(TSymCompArray5 V012, TSymCompArray5 I012, int ActorID) +{ + double Pref3 = 0.0; + //Update_Pqlimits;// confirm P, Q limits + if(ctrl_mode == 0) + { + InDynamics = true; + V1 = V012[1]; // Save for variable calcs + V2 = V012[2]; + V_DG = cabs(V1); + Theta_DG = cang(V1); + + + /*P*/ //P_DG follows ref, and allows sudden change + P_DG = V_DG * id; //update P_DG + // if P_DG, Q_DG exceed the limits + if(P_DG > PMax) + { + P_DG = PMax; //set real power change during the simulation + id = P_DG / V_DG; //set Id + Idn = id; + (X_var)[1 - 1] = id; + (X_varn)[1 - 1] = Idn; + (dX_vardtn)[1 - 1] = 0.0; + } + else + { + if(P_DG < PMin) + { + P_DG = PMin; + id = P_DG / V_DG; //set Id + Idn = id; + (X_var)[1 - 1] = id; + (X_varn)[1 - 1] = Idn; + (dX_vardtn)[1 - 1] = 0.0; + } + + /*Q*/ + } + Q_DG = V_DG * Iq; + if(Q_DG >= Qmax) + { + Q_DG = Qmax; + Iq = Q_DG / V_DG; + Iqn = Iq; + (X_var)[2 - 1] = Iq; + (X_varn)[2 - 1] = Iqn; + (dX_vardtn)[1 - 1] = 0.0; + } + else + { + if(Q_DG <= Qmin) + { + Q_DG = Qmin; + Iq = Q_DG / V_DG; + Iqn = Iq; + (X_var)[2 - 1] = Iq; + (X_varn)[2 - 1] = Iqn; + (dX_vardtn)[1 - 1] = 0.0; + } + } + Get_DynamicModelCurrent(); //Iq Iq does not change, Is1 := cmplx(Id, Iq)*1Get_P_mode(ActorID); + if((p_mode == 1) && (CC_Switch == true)) //if delta P = p_trans_ref - p_trans + //balance p_trans + { + AlphaP = (pV_f_CC)[1 - 1]; //alpha_p + P_DG = PMax * AlphaP; + } + else + { + P_DG = Fnphases * P_ref; // local + } + if(P_DG > PMax) + { + P_DG = PMax; + } + else + { + if(P_DG < PMin) + { + P_DG = PMin; + } + } + AlphaP = P_DG / PMax; + /*--- real power is controled above --*/ + if(QV_flag == 0) //P_ref, Q_ref + Curr = conjg(cdiv(cmplx(P_DG / 3.0, Q_ref), V1)); + else + //P_ref, V_ref + { + if(ActiveCircuit[ActorID]->Solution->Iteration == 1) + { + Iq = 0; //In power flow, start value of Iq for each power flow + } + + //update_pV_f_CC(ActorID); //Alpha + Alpha = (pV_f_CC)[2 - 1]; // only when not dynamode + Q_DG = Qmax * Alpha; + Curr = conjg(cdiv(cmplx(P_DG / 3.0, Q_DG / 3.0), V1)); + /*----------------*/ + } + I012[1] = Curr; // Save for variable calcs + I012[2] = cmplx(0.0, 0.0);//force to be balanced output DG + I012[0] = cmplx(0.0, 0.0); + /*change direction*///added by dahei + I012[1] = cnegate(I012[1]); + I012[2] = cnegate(I012[2]); + I012[0] = cnegate(I012[0]); // avg ctrl + } + else + //direct phase ctrl + { + if(Fnphases == 3) + ; + else + { + //3-phase ctrl + + //1-phase ctrl + + //no consideration for 2-phase DG + if(Fnphases == 1) + ; + } + } +} +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcPFlowVIabc(pComplexArray Vabc, pComplexArray Iabc, int ActorID) +{ + complex tempV1 = {}; + complex tempV2 = {}; + complex tempV3 = {}; + complex Curr1 = {}; + complex Curr2 = {}; + complex Curr3 = {}; + double temp_pref = 0.0; + double temp_qref = 0.0; + double temp_vref = 0.0; + double temp_alpha = 0.0; + double flmt = 0.0; + int p_mode = 0; + flmt = 0.9; + Update_PQlimits(); // Pmax_phase, Qmax_phase will be used in the following steps + update_pV_f_CC_M2(ActorID); // pV_f_CC, updated from virtual leader + // Q ctrl: 3-phase, pV_f_CC^[2], [4], [6] + // 1-phase, pV_f_CC^[2] + // P ctrl: 3-phase, pV_f_CC^[1], [3], [5] + // 1-phase, pV_f_CC^[1] + if(Fnphases == 3) + { + tempV1 = (Vabc)[1 - 1]; // Save for variable calcs //assume Vabc[1][2][3] is ABC! + tempV2 = (Vabc)[2 - 1]; + tempV3 = (Vabc)[3 - 1]; + if(cabs(tempV1) == 0) + tempV1 = cmplx(1, 0); + if(cabs(tempV2) == 0) + tempV2 = cmplx(1, 0); + if(cabs(tempV3) == 0) + tempV3 = cmplx(1, 0); + } + else + { + if(Fnphases == 1) + { + tempV1 = (Vabc)[1 - 1]; // Save for variable calcs //assume Vabc[1][2][3] is ABC! + tempV2 = cmplx(1, 0); + tempV3 = cmplx(1, 0); + } + } + V_DG1 = cabs(tempV1); // Save for variable calcs + V_DG2 = cabs(tempV2); + V_DG3 = cabs(tempV3); + /*----real power is control by Pref in DG----*/ + P_DG1 = P_ref1; + P_DG2 = P_ref2; + P_dg3 = P_ref3; + + /**/ + //calculate_gradient; //alpha, dalpha, and gradients + //alpha is implemented in M2 + p_mode = 0; + if(FMonObj != nullptr) + p_mode = FMonObj->Get_P_mode(ActorID); + if((p_mode == 1) && (CC_Switch == true)) //if delta P = p_trans_ref - p_trans + { + switch(ctrl_mode) + { + case 1: + { + AlphaP1 = (pV_f_CC)[1 - 1]; + P_DG1 = P_DG1 + PMax_phase * AlphaP1; + //p_DG1 := Pmax_phase * AlphaP1; + } + break; + case 2: + { + AlphaP2 = (pV_f_CC)[1 - 1];//if single phase only pV_f_CC^[1] and pV_f_CC^[2] + P_DG2 = P_DG2 + PMax_phase * AlphaP2; + //p_DG2 := Pmax_phase * AlphaP2; + } + break; + case 3: + { + AlphaP3 = (pV_f_CC)[1 - 1]; //if single phase only pV_f_CC^[1] and pV_f_CC^[2] + P_dg3 = P_dg3 + PMax_phase * AlphaP3; + //p_DG3 := Pmax_phase * AlphaP3; + } + break; + case 4: + { + AlphaP1 = (pV_f_CC)[1 - 1]; + P_DG1 = P_DG1 + PMax_phase * AlphaP1; + //p_DG1 := Pmax_phase * AlphaP1; + AlphaP2 = (pV_f_CC)[3 - 1]; + P_DG2 = P_DG2 + PMax_phase * AlphaP2; + //p_DG2 := Pmax_phase * AlphaP2; + AlphaP3 = (pV_f_CC)[5 - 1]; + P_dg3 = P_dg3 + PMax_phase * AlphaP3; + //p_DG3 := Pmax_phase * AlphaP3; + } + break; + default: + ; + break; + } + if(P_DG1 > PMax_phase) + { + P_DG1 = PMax_phase; + } + else + { + if(P_DG1 < Pmin_phase) + { + P_DG1 = Pmin_phase; + } + } + if(P_DG2 > PMax_phase) + { + P_DG2 = PMax_phase; + } + else + { + if(P_DG2 < Pmin_phase) + { + P_DG2 = Pmin_phase; + } + } + if(P_dg3 > PMax_phase) + { + P_dg3 = PMax_phase; + } + else + { + if(P_dg3 < Pmin_phase) + { + P_dg3 = Pmin_phase; + } + } + Update_PQlimits(); // Qmax_phase will be updated accordingly + } + // calc P_DG + switch(ctrl_mode) + { + case 1: + { + P_DG = P_DG1; + } + break; + case 2: + { + P_DG = P_DG2; + } + break; + case 3: + { + P_DG = P_dg3; + } + break; + case 4: + { + P_DG = P_DG1 + P_DG2 + P_dg3; + } + break; + default: + ; + break; + } + /*Q Control*/ + if(ctrl_mode == 0) + ; + else + + //will never be used + //will be in CalcPFlow + // avg ctrl + //direct phase ctrl + { + if(Fnphases == 3) + //3-phase ctrl + // V_Theta1 := cang(V1); + // V_Theta2 := cang(V2); + // V_Theta3 := cang(V3); + { + InDynamics = false; + + //if (P_Mode = 1) and then + //real power control + + // Guess at a new var output value + if(QV_flag == 0) //P_ref, Q_ref + { + Curr1 = conjg(cdiv(cmplx(P_DG1, Q_ref1), tempV1)); //currents A,B,C + Curr2 = conjg(cdiv(cmplx(P_DG2, Q_ref2), tempV2)); + Curr3 = conjg(cdiv(cmplx(P_dg3, Q_ref3), tempV3)); + } + else + //P_ref, V_ref + + //phase A + //1 st ireration Iq := 0; + { + if(ActiveCircuit[ActorID]->Solution->Iteration == 1) + { + Iq1 = 0; //In power flow, start value of Iq for each power flow + Iq2 = 0; + Iq3 = 0; + } //should be taken care of here + if(CC_Switch == false) //droop //Q_DG starts from 0 + + ///////////integral droop + { + dIqdt = kcq * (V_ref1 - V_DG1) / ActiveCircuit[ActorID]->Solution->Iteration; + if(Abs((int) (V_ref1 - V_DG1)) <= Volt_Trhd * V_ref1) + dIqdt = 0.0; + + //if abs(dIqdt)> flmt*Iqmax_phase then dIqdt := sign(dIqdt)*flmt*Iqmax_phase; + Iq1 = Iq1 + dIqdt; + Q_DG1 = V_DG1 * Iq1; + if(droop == 2) + /////////////////} + Q_DG1 = kcq_drp2 * (V_ref1 - V_DG1) * 1000 * MachineData.kVArating / 0.05 / V_ref1; + /*gradient control*/ + } + else + // cooperative control + //dIqdt := Qmax_phase/ V_DG1 * ( - kcq*Gradient1); + //dIqdt := dIqdt / ActiveCircuit.Solution.Iteration; + //dIqdt := dIqdt + Qmax_phase/ V_DG1 * (pV_f_CC[2]);//dIqdt1 + //second method + //calc alpha + //calc Q + //Iq1 := Iq1 + dIqdt; + //Q_DG1 := V_DG1 * Iq1; + { + Alpha1 = (pV_f_CC)[2 - 1]; + Q_DG1 = Qmax_phase * Alpha1; + } + /*----------------*/ + //if abs(dIqdt)> flmt*Iqmax_phase then dIqdt := sign(dIqdt)*flmt*Iqmax_phase; + + //If (Q_DG1 >= Qmax_phase) then Q_DG1 := Qmax_phase; //limit check only one phase + //If Q_DG1 <= Qmin_phase then Q_DG1:= Qmin_phase; + + //phase B + if(CC_Switch == false) //droop + + ///////////integral droop + { + dIqdt = kcq * (V_ref2 - V_DG2) / ActiveCircuit[ActorID]->Solution->Iteration; // ref control + if(Abs((int) (V_ref2 - V_DG2)) <= Volt_Trhd * V_ref2) + dIqdt = 0.0; + Iq2 = Iq2 + dIqdt; //In power flow, Iq starts from 0; + Q_dg2 = V_DG2 * Iq2; + if(droop == 2) + /////////////////} + Q_dg2 = kcq_drp2 * (V_ref2 - V_DG2) * 1000 * MachineData.kVArating / 0.05 / V_ref1; + /*gradient control*/ + } + else + + //dIqdt := Qmax_phase/ V_DG2 * ( - kcq*gradient2); //self gradient + //dIqdt := dIqdt / ActiveCircuit.Solution.Iteration; + //dIqdt := dIqdt + Qmax_phase/ V_DG2 * (pV_f_CC[4]);//dIqdt2 + //Iq2 := Iq2 + dIqdt; //In power flow, Iq starts from 0; + //Q_DG2 := V_DG2 * Iq2; + { + Alpha2 = (pV_f_CC)[4 - 1]; + Q_dg2 = Qmax_phase * Alpha2; + } + //if abs(dIqdt)> flmt*Iqmax_phase then dIqdt := sign(dIqdt)*flmt*Iqmax_phase; + /*----------------*/ + + //If Q_DG2 >= Qmax_phase then Q_DG2:= Qmax_phase; //limit check only one phase + //If Q_DG2 <= Qmin_phase then Q_DG2:= Qmin_phase; + + //phase C + if(CC_Switch == false) //droop + + ///////////integral droop + { + dIqdt = kcq * (V_ref3 - V_DG3) / ActiveCircuit[ActorID]->Solution->Iteration; + if(Abs((int) (V_ref3 - V_DG3)) <= Volt_Trhd * V_ref3) + dIqdt = 0.0; + Iq3 = Iq3 + dIqdt; //In power flow, Iq starts from 0; + Q_dg3 = V_DG3 * Iq3; + if(droop == 2) /////////////////} + Q_dg3 = kcq_drp2 * (V_ref3 - V_DG3) * 1000 * MachineData.kVArating / 0.05 / V_ref1; + } + else + + /*gradient control*/ + //dIqdt := Qmax_phase/ V_DG3 * ( - kcq*gradient3); + //dIqdt := dIqdt / ActiveCircuit.Solution.Iteration; + //dIqdt := dIqdt + Qmax_phase/ V_DG3 * (pV_f_CC[6]);//dIqdt3 + //Iq3 := Iq3 + dIqdt; //In power flow, Iq starts from 0; + //Q_DG3 := V_DG3 * Iq3; + { + Alpha3 = (pV_f_CC)[6 - 1]; + Q_dg3 = Qmax_phase * Alpha3; + } + + /// code bellow is for each phase working seperately + if(Q_DG1 > Qmax_phase) + { + Q_DG1 = Qmax_phase; + } + else + { + if(Q_DG1 < Qmin_phase) + { + Q_DG1 = Qmin_phase; + } + } + Curr1 = conjg(cdiv(cmplx(P_DG1, Q_DG1), tempV1)); + if(Q_dg2 > Qmax_phase) + { + Q_dg2 = Qmax_phase; + } + else + { + if(Q_dg2 < Qmin_phase) + { + Q_dg2 = Qmin_phase; + } + } + Curr2 = conjg(cdiv(cmplx(P_DG2, Q_dg2), tempV2)); + if(Q_dg3 > Qmax_phase) + { + Q_dg3 = Qmax_phase; + } + else + { + if(Q_dg3 < Qmin_phase) + { + Q_dg3 = Qmin_phase; + } + } + Curr3 = conjg(cdiv(cmplx(P_dg3, Q_dg3), tempV3)); + ///////////////////////////////////////////////////// + } + Q_DG = Q_DG1 + Q_dg2 + Q_dg3;// + (Iabc)[1 - 1] = Curr1; // Save for variable calcs + (Iabc)[2 - 1] = Curr2; + (Iabc)[3 - 1] = Curr3; + /*change direction*///added by dahei + (Iabc)[1 - 1] = cnegate((Iabc)[1 - 1]); + (Iabc)[2 - 1] = cnegate((Iabc)[2 - 1]); + (Iabc)[3 - 1] = cnegate((Iabc)[3 - 1]); + } + else + { + if(Fnphases == 1) + //1-phase ctrl + + //tempV1 := Vabc[1]; // Save for variable calcs //assume Vabc[1][2][3] is ABC! + { + V_DG2 = V_DG1; // Save for variable calcs, just in case of other use + V_DG3 = V_DG1; + // V_Theta1 := cang(V1); + InDynamics = false; + // Guess at a new var output value + switch(ctrl_mode) + { + case 1: + { + temp_pref = P_DG1;// + temp_qref = Q_ref1; + temp_vref = V_ref1; + Alpha1 = (pV_f_CC)[2 - 1]; //1 phase, only first one. coincident with dynamic calc + temp_alpha = Alpha1; + } + break; + case 2: + { + temp_pref = P_DG2; + temp_qref = Q_ref2; + temp_vref = V_ref2; + Alpha2 = (pV_f_CC)[2 - 1]; + temp_alpha = Alpha2; + } + break; + case 3: + { + temp_pref = P_dg3; + temp_qref = Q_ref3; + temp_vref = V_ref3; + Alpha3 = (pV_f_CC)[2 - 1]; + temp_alpha = Alpha3; + } + break; + default: + ; + break; + } + if(QV_flag == 0) //P_ref, Q_ref + { + Curr1 = conjg(cdiv(cmplx(temp_pref, temp_qref), tempV1)); //currents A,B,C + } + else + //P_ref, V_ref + // QV_flag=1 + + //phase 1 + //1 st ireration Iq := 0; + { + if(ActiveCircuit[ActorID]->Solution->Iteration == 1) + { + Iq1 = 0; //In power flow, start value of Iq for each power flow + } + if(CC_Switch == false) //droop + + ///////////integral droop + { + dIqdt = kcq * (temp_vref - V_DG1) / ActiveCircuit[ActorID]->Solution->Iteration; + if(Abs((int) (V_ref1 - V_DG1)) <= Volt_Trhd * V_ref1) + dIqdt = 0.0; + Iq1 = Iq1 + dIqdt; //In power flow, Iq starts from 0; + temp_qref = V_DG1 * Iq1; + if(droop == 2) + /////////////////} + temp_qref = kcq_drp2 * (temp_vref - V_DG1) * 1000 * MachineData.kVArating / 0.05 / V_ref1; + } + else + + /*gradient control*/ + { + temp_qref = Qmax_phase * temp_alpha; + } + /*----------------*/ + if(temp_qref > Qmax_phase) // switch control mode to Q_ref control + temp_qref = Qmax_phase; + else + { + if(temp_qref < Qmin_phase) + temp_qref = Qmin_phase; + } + Curr1 = conjg(cdiv(cmplx(temp_pref, temp_qref), tempV1)); + switch(ctrl_mode) + { + case 1: + //P_ref1 := temp_pref ; + { + Q_DG1 = temp_qref; + //v_ref1 := temp_vref; + Alpha1 = temp_alpha; + } + break; + //P_ref2 := temp_pref; + case 2: + { + Q_dg2 = temp_qref; + //v_ref2 := temp_vref ; + Alpha2 = temp_alpha; + } + break; + //P_ref3 := temp_pref ; + case 3: + { + Q_dg3 = temp_qref; + //v_ref3 := temp_vref ; + Alpha3 = temp_alpha; + } + break; + default: + ; + break; + } + + // else + // begin + //no consideration for 2-phase DG + } + (Iabc)[1 - 1] = Curr1; // Save for variable calcs + /*change direction*///added by dahei + (Iabc)[1 - 1] = cnegate((Iabc)[1 - 1]); + } //phase =1 + } + } //direct phase ctrl + //InfoPublish; // publish data into fmonitor +} +//*()//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// typical proc for handling randomization in DSS fashion + +void TGeneric5Obj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + // GAUSSIAN: RandomMult := Gauss(YearlyShapeObj.Mean, YearlyShapeObj.StdDev); + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + // LOGNORMAL: RandomMult := QuasiLognormal(YearlyShapeObj.Mean); + default: + ; + break; + } +} + + +/*-------------------------------------------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------------------------------------------*/ + +// Init for Dynamics mode + +void TGeneric5Obj::InitModel(const TSymCompArray5& V012, const TSymCompArray5& I012) +{ + if(ctrl_mode == 0) //duplicate all codes as avg ctrl + { + id = P_DG / V_DG; //make sure V_DG has been calc beforehand + Iq = Q_DG / V_DG; //change P_ref/Q_ref to P_DG/Q_DG dahei 1-16-18 + Idn = id; + Iqn = Iq; + Id_ref = id;// local; may need to be changed in futher + Iq_ref = Iq;// + // P_ref := Id_ref *v_DG;//local + // V_ref := v_DG;//local + /*-initiate ABCD XY-*/ + (X_var)[1 - 1] = id; + (X_var)[2 - 1] = Iq; + dIddt = 0; + dIqdt = 0; + dIddtn = 0; + dIqdtn = 0; + dvi1dt = 0; + dvi1dtn = 0; + dvi2dt = 0; + dvi2dtn = 0; + // the global part + } +} +/*-------------------------------------------------------------------------------------------------------------*/ + +void TGeneric5Obj::InitModelVIabc(int ActorID) +{ + pComplexArray cBuffer = nullptr; + cBuffer = (pComplexArray) realloc(cBuffer, sizeof(complex) * Fnphases);//define cBuffer + GetPhasePower(cBuffer, ActorID); + P_DG1 = (cBuffer)[1 - 1].re; //first phase or the only one + Q_DG1 = (cBuffer)[1 - 1].im; + /// + //InitModelVIabc(@Vabc, @Iabc); // + ID1 = P_DG1 / V_DG1; + Iq1 = Q_DG1 / V_DG1; + /*-initiate ABCD XY-*/ + (X_var)[1 - 1] = ID1; + (X_var)[2 - 1] = Iq1; + if(Fnphases == 3) //for 3 phase control the bellow is needed + { + P_DG2 = (cBuffer)[2 - 1].re; + Q_dg2 = (cBuffer)[2 - 1].im; + P_dg3 = (cBuffer)[3 - 1].re; + Q_dg3 = (cBuffer)[3 - 1].im; + ID2 = P_DG2 / V_DG2; // + Iq2 = Q_dg2 / V_DG2; + Id3 = P_dg3 / V_DG3; // + Iq3 = Q_dg3 / V_DG3; + (X_var)[3 - 1] = ID2; + (X_var)[4 - 1] = Iq2; + (X_var)[5 - 1] = Id3; + (X_var)[6 - 1] = Iq3; + } + free(cBuffer);//free cBuffer +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::InitStateVars(int ActorID) +{ + int i = 0; + TSymCompArray5 V012 = {}; + TSymCompArray5 I012 = {}; + complex Vabc[4] = { CZero,CZero ,CZero ,CZero }, + Iabc[4] = { CZero,CZero ,CZero ,CZero }; + pComplexArray cBuffer = nullptr; + + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + /*# with MachineData do */ + { + auto& with0 = MachineData; + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if(MachineON) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + Yeq = cinv(Zsp); + TDSSCktElement::ComputeIterminal(ActorID); + switch(Fnphases) + { + case 1: + //E1 := Csub( CSub(NodeV^[NodeRef^[1]], NodeV^[NodeRef^[2]]) , Cmul(ITerminal^[1], Zsp)); + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vabc[i - 1] = with1->NodeV[(NodeRef)[i - 1]]; + else + Vabc[i - 1] = with1->VoltInActor1((NodeRef)[i - 1]); + } // Wye Voltage + } + break; + // Calculate E1 based on Pos Seq only + case 3: + { + int stop = 0; + Phase2SymComp(&(Iterminal[0]), &I012[1]); // terminal currents + + // Voltage behind Zsp (transient reactance), volts + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vabc[i - 1] = with1->NodeV[(NodeRef)[i - 1]]; + else + Vabc[i - 1] = with1->VoltInActor1((NodeRef)[i - 1]); + } + Phase2SymComp(&Vabc[0], &V012[1]); + //E1 := Csub( V012[1] , Cmul(I012[1], Zsp)); // Pos sequence + } + break; + default: + DoSimpleMsg(Format(("Dynamics mode is implemented only for 1- or 3-phase Motors. IndMach012." + with1->get_Name() + + " has %d phases.").c_str(), Fnphases), 5672); + SolutionAbort = true; + break; + } + with0.dTheta = 0.0; + with0.w0 = TwoPi * ActiveCircuit[ActorID]->Solution->get_FFrequency(); + // recalc Mmass and D in case the frequency has changed + /*# with MachineData do */ + { + auto& with2 = MachineData; + with2.Mmass = 2.0 * with2.Hmass * with2.kVArating * 1000.0 / (with2.w0); // M = W-sec + with2.D = with2.Dpu * with2.kVArating * 1000.0 / (with2.w0); + } + with0.Pshaft = 0 - Get_Power(1, ActorID).re;//P_DG;//Power[1].re; // Initialize Pshaft to present power consumption of motor + + //Speed := -LocalSlip * w0; // relative to synch speed + with0.dSpeed = 0.0; + /**/ + if(DebugTrace) // Put in a separator record + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile); + WriteLn(Tracefile, "*************** Entering Dynamics Mode ***********************"); + WriteLn(Tracefile); + Close(Tracefile); + } + } + else + { + with0.Theta = 0.0; + with0.dTheta = 0.0; + with0.w0 = 0; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + /**/ + //Id + } + } /*With*/ + /// + /// from here, let us deal with ctrl_mode and everything related to control + if(ctrl_mode == 0) //Pos seq contrl + + /**/ + { + V_DG = cabs(V012[1]);// Pos Seq Control + Theta_DG = cang(V012[1]); + //P_DG := 0-Power[1].re/3.0; //1-terminal, for gen has only one terminal + // div 3.0 ---% 1-11-2018. each phase + P_DG = 0 - Get_Power(1, ActorID).re; + //Q_DG := 0-Power[1].im/3.0; + Q_DG = 0 - Get_Power(1, ActorID).im; + //V_ref := V_DG ; //1;// + P_ref = P_DG / 3; + Q_ref = Q_DG / 3; + InitModel(V012, I012); // E2, etc , Id Iq etc + //init alpha array +// if fmonobj <> nil then +// fmonobj.Init_delay_array(ndNumincluster); + // Shaft variables + //Theta := Cang(E1) ; + } + else + //ctrl_mode <> 0 =1,2,3,4 + //Vabc + { + V_DG1 = cabs(Vabc[1 - 1]); // Save for variable calcs + V_DG2 = cabs(Vabc[2 - 1]); + V_DG3 = cabs(Vabc[3 - 1]); + cBuffer = (pComplexArray) realloc(cBuffer, sizeof(complex) * Fnphases);//define cBuffer + GetPhasePower(cBuffer, ActorID); + P_DG1 = 0.0 - (cBuffer)[1 - 1].re; //first phase or the only one + Q_DG1 = 0.0 - (cBuffer)[1 - 1].im; + /// + //InitModelVIabc(@Vabc, @Iabc); // + ID1 = P_DG1 / V_DG1; + Iq1 = Q_DG1 / V_DG1; + /*-initiate ABCD XY-*/ + (X_var)[1 - 1] = ID1; + (X_var)[2 - 1] = Iq1; + if(Fnphases == 3) //for 3 phase control the bellow is needed + { + P_DG2 = 0.0 - (cBuffer)[2 - 1].re; + Q_dg2 = 0.0 - (cBuffer)[2 - 1].im; + P_dg3 = 0.0 - (cBuffer)[3 - 1].re; + Q_dg3 = 0.0 - (cBuffer)[3 - 1].im; + ID2 = P_DG2 / V_DG2; // + Iq2 = Q_dg2 / V_DG2; + Id3 = P_dg3 / V_DG3; // + Iq3 = Q_dg3 / V_DG3; + (X_var)[3 - 1] = ID2; + (X_var)[4 - 1] = Iq2; + (X_var)[5 - 1] = Id3; + (X_var)[6 - 1] = Iq3; + } + free(cBuffer);//free cBuffer + } + //if QV_switch = 1 then // + // begin + //QV_flag := QV_flag_0; + //QV_switch := 0;// wait next limit break + // end; + Update_PQlimits(); +} + +//---------------------------------------------------------------------------- + + +/*A typical helper function for PC elements to assist in the computation + of Yprim +*/ + +void TGeneric5Obj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + complex Yadder = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; // ratio to adjust reactances for present solution frequency + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsDynamicModel || with0->IsHarmonicModel) + // for Dynamics and Harmonics modes use constant equivalent Y + { + int stop = 0; + if(MachineON) // L-N value computed in initialization routines + Y = Yeq; + else + Y = cmplx(EPSILON, 0.0); + if(Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; // adjust for frequency + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); // sets the element + /* + Ymatrix.AddElement(Fnconds, Fnconds, Y); // sums the element + Ymatrix.SetElemsym(i, Fnconds, Yij); + */ + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Yadder = cmulreal(Y, 1.000001); // to prevent floating delta + Ymatrix->SetElement(i, i, cadd(Y, Yadder)); // add a little bit to diagonal + Ymatrix->AddElement(i, i, Y); // put it in again + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + else + + + // Typical code for a regular power flow model + // Borrowed from Generator object + + /*Yeq is typically expected as the equivalent line-neutral admittance*/ + { + Y = Yeq; // Yeq is L-N quantity + + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + switch(Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + /* + AddElement(Fnconds, Fnconds, Y); + SetElemsym(i, Fnconds, Yij); + */ + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } /*ELSE IF Solution.mode*/ +} + + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcYPrim(int ActorID) +{ + int i = 0; + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + + + // call helper routine to compute YPrim_Shunt + CalcYPrimMatrix(YPrim_Shunt, ActorID); + + // Set YPrim_Series based on a small fraction of the diagonals of YPrim_shunt + // so that CalcVoltages doesn't fail + // This is just one of a number of possible strategies but seems to work most of the time + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + + // copy YPrim_shunt into YPrim; That's all that is needed for most PC Elements + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors -- done in base class + TDSSCktElement::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/*Compute total terminal Current */ + +void TGeneric5Obj::DoGeneric5Model(int ActorID) +{ + int i = 0; + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcModel(&(Vterminal[0]), &(Iterminal[0]), ActorID); + + //IterminalUpdated := TRUE; + set_ITerminalUpdated(true, ActorID); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + if(DebugTrace) + WriteTraceRecord(ActorID); +} // given voltages returns currents + +void TGeneric5Obj::CalcModel(pComplexArray V, pComplexArray i, int ActorID) +{ + TSymCompArray5 V012 = {}; + TSymCompArray5 I012 = {}; + if(ctrl_mode == 0) + // Convert abc voltages to 012 + { + Phase2SymComp(V, &V012[0]); + + // compute I012 + switch(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode) + { + case DYNAMICMODE: + { + CalcDynamic(V012, I012, ActorID); + } + break; /*All other modes are power flow modes*/ + default: + CalcPFlow(V012, I012, ActorID); + break; + } + SymComp2Phase(i, (pComplexArray) &I012); // convert back to I abc + // avg ctrl + } + else + //direct phase ctrl + { + if(Fnphases == 3) + //3-phase ctrl + // use Vterminal Iterminal directly instead of computing 120 + { + switch(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode) + { + case DYNAMICMODE: + { + CalcDynamicVIabc(V, i, ActorID); //if ((ctrl_mode=4)and (fnphases=3)) + } + break; /*All other modes are power flow modes*/ + default: + CalcPFlowVIabc(V, i, ActorID); // //if ((ctrl_mode=4)and (fnphases=3)) + break; + } + } + else + { + //no consideration for 2-phase DG + if(Fnphases == 1) + //1-phase ctrl + // use Vterminal Iterminal directly instead of computing 120 + // actually there is no 120 for single phase + { + switch(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode) + { + case DYNAMICMODE: + { + CalcDynamicVIabc(V, i, ActorID); //if (fnphases=1) + } + break; /*All other modes are power flow modes*/ + default: + CalcPFlowVIabc(V, i, ActorID); // //if (fnphases=1) + break; + } + } + } + } + /*--------pullish info--------*/ + if(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode == DYNAMICMODE) + //dynamode + //if ActiveCircuit.Issolved = true then + { + if(FMonObj != nullptr) + InfoPublish(ActorID); + } + else + //power flow + { + if(FMonObj != nullptr) + InfoPublish(ActorID); + } + + /*----------------------------*/ +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* This is an example taken from Generator illustrating how a PC element might + handle Dynamics mode with a Thevenin equivalent + + Also illustrates the computation of symmetrical component values +*/ + +/*Compute Total Current and add into InjTemp*/ + +void TGeneric5Obj::DoDynamicMode(int ActorID) +{ + int i = 0; + + // Start off by getting the current in the admittance branch of the model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + + /*Inj = -Itotal (in) - Yprim*Vtemp*/ + CalcModel(&(Vterminal[0]), &(Iterminal[0]), ActorID); + + //IterminalUpdated := TRUE; + set_ITerminalUpdated(true, ActorID); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +/*Do not support Harmonic for now*/ + +/* + Example taken from Generator illustrating how a PC element might handle + current calcs for Harmonics mode + + Note: Generator objects assume a Thevenin model (voltage behind and impedance) + while Load objects assume the Spectrum applies to a Norton model injection current +*/ + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TGeneric5Obj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double GenHarmonic = 0.0; + + // Set the VTerminal array + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + GenHarmonic = with0->get_FFrequency() / BaseFrequency; // harmonic based on the fundamental for this object + // get the spectrum multiplier and multiply by the V thev (or Norton current for load objects) + // ??? E := CmulReal(SpectrumObj.GetMult(GenHarmonic), VThevHarm); // Get base harmonic magnitude + // ??? RotatePhasorRad(E, GenHarmonic, ThetaHarm); // Time shift by fundamental frequency phase shift + + // Put the values in a temp complex buffer + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, GenHarmonic, -120.0); // Assume 3-phase IndMach012 + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + // In this case the injection currents are simply Yprim(frequency) times the voltage buffer + // Refer to Load.Pas for load-type objects + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Main dispatcher for computing PC Element currnts + +// Calculates IndMach012 current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TGeneric5Obj::CalcGeneric5ModelContribution(int ActorID) +{ + + //IterminalUpdated := FALSE; + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + DoGeneric5Model(ActorID); + } + } /*WITH*/ + + /*When this is done, ITerminal is up to date*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Main procedure for controlling computation of InjCurrent array + +// InjCurrent is difference between currents in YPrim and total terminal current + +void TGeneric5Obj::CalcInjCurrentArray(int ActorID) +{ + + +// You usually will want some logic like this + + // If the element is open, just zero the array and return + if(Generic5SwitchOpen) + + // otherwise, go to a routine that manages the calculation + ZeroInjCurrent(); + else + CalcGeneric5ModelContribution(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// This function controls the calculation of the total terminal currents + +// Note that it only does something if the solution count has changed. +// Otherwise, Iterminal array already contains the currents + +void TGeneric5Obj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + // You will likely want some logic like this + { + if(!Generic5SwitchOpen) + CalcGeneric5ModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); // add in inherited contribution + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Required function for managing computing of InjCurrents + +int TGeneric5Obj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + + // Generators and Loads use logic like this: + if(with0->LoadsNeedUpdating) + SetNominalPower(ActorID); // Set the nominal kW, etc for the type of solution being done + + // call the main function for doing calculation + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + + // If (DebugTrace) Then WriteTraceRecord; + + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Set shaft power + +void TGeneric5Obj::SetNominalPower(int ActorID) +{ + double Factor = 0.0; + bool MachineOn_Saved = false; + MachineOn_Saved = MachineON; + ShapeFactor = CDoubleOne; + // Check to make sure the generation is ON + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) // Leave machine in whatever state it was prior to entering Dynamic mode + { + MachineON = true; // Init to on then check if it should be off + } + if(!MachineON) + // If Machine is OFF enter as tiny resistive load (.0001 pu) so we don't get divide by zero in matrix + { + MachineData.Pnominalperphase = -0.1 * kWBase / Fnphases; + // Pnominalperphase := 0.0; + MachineData.Qnominalperphase = 0.0; // This really doesn't matter + } + else + // Generator is on, compute it's nominal watts and vars + { + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + switch(with2->Get_SolMode()) + { + case SNAPSHOT: + Factor = 1.0; + break; + case DAILYMODE: + { + Factor = 1.0; // Daily dispatch curve + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + Factor = 1.0; + CalcYearlyMult(with2->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + Factor = 1.0; + CalcDutyMult(with2->DynaVars.dblHour); + } + break; // General sequential time simulation + case GENERALTIME: case DYNAMICMODE: + { + Factor = 1.0; + // This mode allows use of one class of load shape + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with2->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with2->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with2->DynaVars.dblHour); + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + case MONTECARLO1: case MONTEFAULT: case FAULTSTUDY: + Factor = 1.0; + break; + case MONTECARLO2: case MONTECARLO3: case LOADDURATION1: case LOADDURATION2: + { + Factor = 1.0; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case PEAKDAY: + { + Factor = 1.0; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case AUTOADDFLAG: + Factor = 1.0; + break; + default: + Factor = 1.0; + break; + } + } + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + if(ShapeIsActual) + MachineData.Pnominalperphase = 1000.0 * ShapeFactor.re / Fnphases; + else + MachineData.Pnominalperphase = 1000.0 * kWBase * Factor * ShapeFactor.re / Fnphases; + + // cannot dispatch vars in induction machine + // you get what you get + } + } /*ELSE GenON*/ + } /*With ActiveCircuit*/ + + // If machine state changes, force re-calc of Y matrix + if(MachineON != MachineOn_Saved) + Set_YprimInvalid(ActorID,true); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcDailyMult(double hr) +{ + if(DailyDispShapeObj != nullptr) + { + ShapeFactor = DailyDispShapeObj->GetMult(hr); + ShapeIsActual = DailyDispShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Default to no daily variation +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult if no duty curve specified +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Defaults to no variation +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Gets the currents for the last solution performed + +// Do not call anything that may change the basic element values from the last solution + +void TGeneric5Obj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + // an exception here generally means an array boundary overrun + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("IndMach012 Object: \"") + get_Name() + "\" in GetInjCurrents function.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- +/* + This procedure is require to respond to various commands such as Dump that + write all the device's property values to a file. +*/ + +void TGeneric5Obj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + + /*Write out any specials here, usually preceded by a "!"*/ + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; // Map to get proper index into property value array + switch(Idx) + { + case 34: case 36: + /*Trap any specials here, such as values that are array properties, for example*/ + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/*Procedure to initialize for Harmonics solution*/ + +/*This example is extracted from Generator and constructs a Thevinen equivalent. + Refer to Load for how to do a Norton equivalent + */ + +//Var +// E, Va:complex; + +void TGeneric5Obj::InitHarmonics(int ActorID) +{ + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + +/**** + GenFundamental := ActiveCircuit.Solution.Frequency ; // Whatever the frequency is when we enter here. + + With GenVars Do Begin + + // Xd" is used for harmonics analysis for generators + Yeq := Cinv(Cmplx(0.0, Xdpp)); // used for current calcs Always L-N + + {Compute reference Thevinen voltage from phase 1 current} + + IF GenON Then + Begin + + ComputeIterminal; // Get present value of current + + With ActiveCircuit.solution Do + Case Connection of + 0: Begin {wye - neutral is explicit} + Va := Csub(NodeV^[NodeRef^[1]], NodeV^[NodeRef^[Fnconds]]); + End; + 1: Begin {delta -- assume neutral is at zero} + Va := NodeV^[NodeRef^[1]]; + End; + End; + + E := Csub(Va, Cmul(Iterminal^[1], cmplx(0.0, Xdpp))); + Vthevharm := Cabs(E); // establish base mag and angle + ThetaHarm := Cang(E); + End + ELSE Begin + // If Generator is off, just set to zero + Vthevharm := 0.0; + ThetaHarm := 0.0; + End; + End; + ***/ +} + +// ******************* PROPERTY VALUES ******************* + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// required procedure to initialize the string value of the properties + +void TGeneric5Obj::InitPropertyValues(int ArrayOffset) +{ + + // Some examples + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(3,"12.47"); + Set_PropertyValue(4,"100"); + Set_PropertyValue(5,".80"); + Set_PropertyValue(6,"Delta"); + Set_PropertyValue(7,Format("%-g", MachineData.kVArating)); + Set_PropertyValue(8,Format("%-g", MachineData.Hmass)); + Set_PropertyValue(9,Format("%-g", MachineData.D)); + Set_PropertyValue(10,"0.0053"); + Set_PropertyValue(11,"0.106"); + Set_PropertyValue(12,"0.007"); + Set_PropertyValue(13,"0.12"); + Set_PropertyValue(14,"4.0"); + Set_PropertyValue(15,"0.007"); + Set_PropertyValue(16,"0.1"); + Set_PropertyValue(17,"variable"); + Set_PropertyValue(18,""); + Set_PropertyValue(19,""); + Set_PropertyValue(20,""); /*...*/ + Set_PropertyValue(21,"NO"); + Set_PropertyValue(24,"1");//GrpNum + Set_PropertyValue(25,"1");//V_ref + Set_PropertyValue(26,"0");//control mode + +/*Call inherited function to init inherited property values*/ + inherited::InitPropertyValues(NumPropsThisClass); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Return i-th property value as a string + +String TGeneric5Obj::GetPropertyValue(int Index) +{ + String result; + result = ""; // Init the string + switch(Index) + { + case 4: + // Put special cases here + // often a good idea to convert numeric values to strings, for example + result = Format("%.6g", kWBase); + break; + case 5: + result = Format("%.6g", PowerFactor(Get_Power(1, ActiveActor))); + break; + case 7: + result = Format("%.6g", MachineData.kVArating); + break; + case 8: + result = Format("%.6g", MachineData.Hmass); + break; + case 9: + result = Format("%.6g", MachineData.D); + break; + //15: Result := Format('%.6g', [localslip]); + case 18: + result = YearlyShape; + break; + case 19: + result = DailyDispShape; + break; + case 20: + result = DutyShape; + break; + /**/ + case 24: + result = Format("%d", Cluster_num); + break; + /*...*/ + + // The default is to just return the current string value of the property + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +// ******************* END PROPERTY VALUES ******************* + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + This is a virtual function. You do not need to write this routine + if you are not integrating state variables in dynamics mode. +*/ + +// Integrate state variables for Dynamics analysis +// Example from Generator + +// Illustrates use of debug tracing + +// Present technique is a predictor-corrector trapezoidal rule + +void TGeneric5Obj::IntegrateStates(int ActorID) +{ + complex TracePower = {}; + // Compute Derivatives and then integrate + TDSSCktElement::ComputeIterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution, MachineData do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = MachineData; + /*# with DynaVars do */ + { + auto& with2 = with0->DynaVars; /*First iteration of new time step*/ + //ThetaHistory := Theta + 0.5*h*dTheta; + //SpeedHistory := Speed + 0.5*h*dSpeed; + if(with2.IterationFlag == 0) + ; + } + + // Compute shaft dynamics + TracePower = TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases); // in watts + //dSpeed := (TracePower.re - Pshaft - abs(D*Speed)) / Mmass; + //dTheta := Speed ; + with1.Pshaft = P_DG; // P_DG is calculated in CalcDynamic or CalcDynamicVIabc + // + // Trapezoidal method + + //Speed := SpeedHistory + 0.5*h*dSpeed; + //Theta := ThetaHistory + 0.5*h*dTheta; + if(DebugTrace) + WriteTraceRecord(ActorID); + IntegrateABCD(ActorID); + //Integrate; + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::Get_DynamicModelCurrent() +{ + double Temp = 0.0; + if(id == 0.0) + Temp = double(DSSGlobals::PI) / 2; + else + Temp = atan(Iq / id); + Is1 = pclx(sqrt(Iq * Iq + id * id), Theta_DG - Temp);//with respect to Q_axis + //Is1 := cmul(Is1,cmplex());// Put this into XY domine + Is1 = cdivreal(Is1, 3.0); //here we need to divide all values back to Network + //Is1 := Cdiv(Csub(V1, E1),Zsp); // I = (V-E')/Z' + //Is2 := Cdiv(Csub(V2, E2),Zsp); // I = (V-E')/Z' + Is2 = cmplx(0, 0); //force balance + // rotor current Ir1= Is1-Vm/jXm + Ir1 = Is1; + //Ir1 := Csub(Is1 ,Cdiv( Csub(V1, cmul(Is1, Zsp)), Zm )); + //Ir2 := Csub(Is2 ,Cdiv( Csub(V2, cmul(Is2, Zsp)), Zm )); + Ir2 = cmplx(0, 0); +} + + +//---------------------------------------------------------------------------- +// ********************** VARIABLES *************************************** +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/* + Return the number of state variables + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. + Note: it is not necessary to define any state variables +*/ + +int TGeneric5Obj::NumVariables() +{ + int result = 0; + result = NumGeneric5Variables; + return result; +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + Returns the i-th state variable in a string + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +String TGeneric5Obj::VariableName(int i) +{ + String result; + if(i < 1) + return result; // This means Someone goofed + switch(i) + { + case 1: + result = "V_DG"; + break;//pos seq value + case 2: + result = "P_DG"; + break; + case 3: + result = "Q_DG"; + break; + case 4: + result = "V_DG1"; + break;//Phase A or the first phase if there are less than 3 + case 5: + result = "P_DG1"; + break; + case 6: + result = "Q_DG1"; + break; + case 7: + result = "V_DG2"; + break;//Phase B if exists + case 8: + result = "P_DG2"; + break; + case 9: + result = "Q_DG2"; + break; + case 10: + result = "V_DG3"; + break;//phase C if exists + case 11: + result = "P_DG3"; + break; + case 12: + result = "Q_DG3"; + break; + case 13: + result = "Qmax"; + break; + case 14: + result = "Qmax_Phase"; + break; + case 15: + result = "Pmax"; + break; + case 16: + result = "Pmax_Phase"; + break; + case 17: + result = "Alpha"; + break; + case 18: + result = "Alpha1"; + break; + case 19: + result = "Alpha2"; + break; + case 20: + result = "Alpha3"; + break; + case 21: + result = "AlphaP"; + break; + case 22: + result = "AlphaP1"; + break; + case 23: + result = "AlphaP2"; + break; + case 24: + result = "AlphaP3"; + break; + case 25: + result = "V_ref"; + break; //Voltage object + case 26: + result = "kVA"; + break; //kVArating + case 27: + result = "kW"; + break; //kVArating + case 28: + result = "cluster_num"; + break; + case 29: + result = "NdNumInCluster"; + break; + case 30: + result = "ctrl_mode"; + break; + case 31: + result = "Gradient"; + break; + case 32: + result = "Id"; + break; + case 33: + result = "Iq"; + break; + case 34: + result = "P_set"; + break; + case 35: + result = "Frequency"; + break; + case 36: + result = "Defense"; + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TGeneric5Obj::Get_Variable(int i) +{ + double result = 0.0; + result = -9999.99; // Error Value + + //With MachineData Do + switch(i) + { + case 1: + result = V_DG; + break; + case 2: + result = P_DG / 1000; + break;//kW + case 3: + result = Q_DG / 1000; + break; + case 4: + result = V_DG1; + break;//Phase A or the first phase if there are less than 3 phases + case 5: + result = P_DG1 / 1000; + break; + case 6: + result = Q_DG1 / 1000; + break; + case 7: + result = V_DG2; + break;//Phase B if exists + case 8: + result = P_DG2 / 1000; + break; + case 9: + result = Q_dg2 / 1000; + break; + case 10: + result = V_DG3; + break;//Phase c if exists + case 11: + result = P_dg3 / 1000; + break; + case 12: + result = Q_dg3 / 1000; + break; + case 13: + result = Qmax / 1000; + break; + case 14: + result = Qmax_phase / 1000; + break; + case 15: + result = PMax / 1000; + break; + case 16: + result = PMax_phase / 1000; + break; + case 17: + result = Alpha; + break; + case 18: + result = Alpha1; + break; + case 19: + result = Alpha2; + break; + case 20: + result = Alpha3; + break; + case 21: + result = AlphaP; + break; + case 22: + result = AlphaP1; + break; + case 23: + result = AlphaP2; + break; + case 24: + result = AlphaP3; + break; + case 25: + result = V_ref; + break; + case 26: + result = MachineData.kVArating / 1000; + break; + case 27: + result = kWBase / 1000; + break; + case 28: + result = (double) Cluster_num; + break; + case 29: + result = (double) NdNumInCluster + 1; + break; + case 30: + result = (double) ctrl_mode; + break; + case 31: + result = Gradient; + break; + case 32: + result = id; + break; + case 33: + result = Iq; + break; + case 34: + result = P_ref * 3.0; + break; + case 35: + { + Freq = ActiveCircuit[ActiveActor]->Solution->get_FFrequency(); + if(FMonObj != nullptr) + Freq = Freq + FMonObj->omg_fm;//fmonobj.comp_omg;//fmonobj.omg_fm; // + result = Freq; + } + break; + case 36: + { + result = 0.0; + if(FMonObj != nullptr) + result = z_dfs_plot; + } + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::Set_Variable(int i, double Value) +{ + switch(i) + { + case 1: + V_DG = Value; + break; + case 2: + P_DG = Value; + break; + case 3: + Q_DG = Value; + break; + case 4: + V_DG1 = Value; + break;//Phase A or the first phase if there are less than 3 phases + case 5: + P_DG1 = Value; + break; + case 6: + Q_DG1 = Value; + break; + case 7: + V_DG2 = Value; + break;//Phase B if exists + case 8: + P_DG2 = Value; + break; + case 9: + Q_dg2 = Value; + break; + case 10: + V_DG3 = Value; + break;//Phase c if exists + case 11: + P_dg3 = Value; + break; + case 12: + Q_dg3 = Value; + break; + case 13: + Qmax = Value; + break; + case 14: + Qmax_phase = Value; + break; + case 15: + PMax = Value; + break; + case 16: + PMax_phase = Value; + break; + case 17: + Alpha = Value; + break; + case 18: + Alpha1 = Value; + break; + case 19: + Alpha2 = Value; + break; + case 20: + Alpha3 = Value; + break; + case 21: + AlphaP = Value; + break; + case 22: + AlphaP1 = Value; + break; + case 23: + AlphaP2 = Value; + break; + case 24: + AlphaP3 = Value; + break; + case 25: + V_ref = Value; + break; + case 26: + MachineData.kVArating = Value; + break; + case 27: + kWBase = Value; + break; + case 28: + { + ((TPCElement*) this)->Cluster_num = Trunc(Value); + + + //if cluster_num >= 1 then // assign the virtue leader to this DG + //begin + //FMonObj := ActiveCircuit.Fmonitors.Get(cluster_num); // it works only if cluster_num starts from 1 and being consecutively + + // move this piece of codes to Fmonitor, InitFM + //ActiveCircuit.Fmonitors.First; + //FMonObj := ActiveCircuit.Fmonitors.Active; + //if FMonObj. then + + + //end; + + //if function 'get' fails , return nil + } + break; + case 29: + ((TPCElement*) this)->NdNumInCluster = Trunc(Value) - 1; + break; + case 30: + ((TPCElement*) this)->nVLeaders = Trunc(Value); + break; + case 31: + ((TPCElement*) this)->cluster_num2 = Trunc(Value); + break; + case 32: + ((TPCElement*) this)->NdNumInCluster2 = Trunc(Value) - 1; + break; + /*Do Nothing for other variables: they are read only*/ + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/* + Return all state variables in double array (allocated by calling function) + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +void TGeneric5Obj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + //N:Integer; + +// N := 0; + int stop = 0; + for(stop = NumGeneric5Variables, i = 1; i <= stop; i++) + { + (States)[i - 1] = Get_Variable(i); + } +} + +// ********************** END VARIABLES *************************************** + + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TGeneric5Obj::GetRotorLosses() +{ + double result = 0.0; + result = 3.0 * (Sqr(Ir1.re) + Sqr(Ir1.im) + Sqr(Ir2.re) + Sqr(Ir2.im)) * Zr.re; + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TGeneric5Obj::GetStatorLosses() +{ + double result = 0.0; + result = 3.0 * (Sqr(Is1.re) + Sqr(Is1.im) + Sqr(Is2.re) + Sqr(Is2.im)) * Zs.re; + return result; +} + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + This is a virtual function. You do not need to write this routine + if the base class function will suffice. +*/ + +// Routine to convert existing three-phase models to a single-phase positive- +// sequence model + +void TGeneric5Obj::MakePosSequence(int ActorID) +{ + String s; +// V :Double; + + +/* + The usual technique is to create a new property editing string + based on the present values of properties. Once the string is + created, it is pushed into the Parser and the Edit routine for this + class is invoked. + + Thus, the positive sequence model is created in memory. Do a + "Save Circuit" command to save the model that is created. Some + editing of the resulting scripts will likely be required. Not all + elements have an obvious positive sequence equivalent. +*/ + + + // example from Generator class + // Modify as necessary + s = "Phases=1 conn=wye"; // Positive sequence model is 1-phase wye + + /**** + + // Make sure voltage is line-neutral + If (Fnphases>1) or (connection<>0) Then V := GenVars.kVGeneratorBase/SQRT3 + Else V := GenVars.kVGeneratorBase; + + S := S + Format(' kV=%-.5g',[V]); + + // Divide the load by no. phases + If Fnphases>1 Then + Begin + S := S + Format(' kW=%-.5g PF=%-.5g',[kWbase/Fnphases, PFNominal]); + If (PrpSequence^[19]<>0) or (PrpSequence^[20]<>0) Then S := S + Format(' maxkvar=%-.5g minkvar=%-.5g',[kvarmax/Fnphases, kvarmin/Fnphases]); + If PrpSequence^[26]>0 Then S := S + Format(' kva=%-.5g ',[genvars.kvarating/Fnphases]); + If PrpSequence^[27]>0 Then S := S + Format(' MVA=%-.5g ',[genvars.kvarating/1000.0/Fnphases]); + End; + + Parser.CmdString := S; // Push the string into the Parser object + Edit; // Invoke the Edit method for this class + + inherited; // sets the terminal bus references, must do after editing number of phases + + ***/ +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Routine for handling Open/Close procedures + +void TGeneric5Obj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + TDSSCktElement::Set_ConductorClosed(Index, ActorID, Value); + if(Value) + Generic5SwitchOpen = false; + else + Generic5SwitchOpen = true; +} + + +//---------------------------------------------------------------------------- +/*procedure TGeneric5Obj.set_Localslip(const Value: Double); +//---------------------------------------------------------------------------- + + Function Sign(const x:Double):Double; + Begin If x<0.0 then Result := -1.0 Else Result := 1.0; End; + +begin + S1 := Value; + If Not InDynamics Then If Abs(S1)>MaxSlip Then S1 := Sign(S1)*MaxSlip; // Put limits on the slip unless dynamics + S2 := 2.0 - S1; +end; + */ +//---------------------------------------------------------------------------- +/*procedure TGeneric5Obj.Set_Slip(const Value: Double); +//---------------------------------------------------------------------------- +begin + LocalSlip := Value; + MachineData.Speed := MachineData.w0 * (-S1); // make motor speed agree +end; +*/ +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::InitTraceFile() +{ + AssignFile(Tracefile, get_Name() + "_IndMach012_Trace.CSV"); + Rewrite(Tracefile); + IOResultToException(); + Write(Tracefile, "Time, Iteration, S1, |IS1|, |IS2|, |E1|, |dE1dt|, |E2|, |dE2dt|, |V1|, |V2|, Pshaft, Pin, Speed, dSpeed"); + WriteLn(Tracefile); + CloseFile(Tracefile); +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TGeneric5Obj::WriteTraceRecord(int ActorID) +{ + Append(Tracefile); + IOResultToException(); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + //Write(TraceFile, Format('%-.6g, %d, %-.6g, ',[Dynavars.dblHour*3600.0, Iteration, S1])); + Write(Tracefile, Format("%-.6g, %-.6g, ", cabs(Is1), cabs(Is2))); + } + //Write(TraceFile, Format('%-.6g, %-.6g, %-.6g, %-.6g, ', [Cabs(E1), Cabs(dE1dt), Cabs(E2), Cabs(dE2dt)])); + Write(Tracefile, Format("%-.6g, %-.6g, ", cabs(V1), cabs(V2))); + Write(Tracefile, Format("%-.6g, %-.6g, ", MachineData.Pshaft, Get_Power(1, ActorID).re)); + Write(Tracefile, Format("%-.6g, %-.6g, ", MachineData.Speed, MachineData.dSpeed)); + WriteLn(Tracefile); + CloseFile(Tracefile); +} + +// Initialize any variables here + + + // For Example: 1 + j 1 + + +void Generic5OrderMach_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class Generic5OrderMach_unit + { + public: + Generic5OrderMach_unit() + { + //AssertSystemInitialization(); + Generic5OrderMach_initialization(); + } + }; + Generic5OrderMach_unit _Generic5OrderMach_unit; + +} // namespace Generic5OrderMach + + + + diff --git a/OpenDSSC/PCElements/Generic5OrderMach.h b/OpenDSSC/PCElements/Generic5OrderMach.h new file mode 100644 index 0000000..d0af452 --- /dev/null +++ b/OpenDSSC/PCElements/Generic5OrderMach.h @@ -0,0 +1,436 @@ +#ifndef Generic5OrderMachH +#define Generic5OrderMachH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Dynamics.h" +#include "GeneratorVars.h" +#include "d2c_structures.h" + + +namespace Generic5OrderMach +{ + + + +/* Change Log + + November 3, 2017 + + Created by + Darhey Xu + +*/ // Base class for most DSS objects + // Base class for collection manager for PC elements + // Base class for PC Elements + // Unit for managing complex matrice (for Yprim, etc) + // Complex math functions, type definitions + // definitions of basic DSS arrays + + // common modules used in PC elements + // class for supporting/representing loadshapes + // Class for holding growth shapes + // Definitions for harmonic spectra + // for elements that interact with dynamics variables + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* Collection manager for this class of element */ /* Notes Andres: -- definition of the class -- */ + +class TGeneric5 : public PCClass::TPCClass +{ + friend class TGeneric5Obj; +public: + typedef PCClass::TPCClass inherited; +private: + + /*These private functions are generally helper functions for Edit procedure*/ + + /* A typical function */ + void SetNcondsForConnection(); +protected: + void DefineProperties(); // Define the property names and help strings + virtual int MakeLike(const String OtherIndMach012Name); // copy properties of another similar object +public: + TGeneric5(); + virtual ~TGeneric5(); + virtual int Edit(int ActorID); // Definition of the main property editing function + virtual int Init(int Handle, int ActorID); // Initialize by handle (index), if necessary + virtual int NewObject(const String ObjName); // This function is called by the DSS New command + + /*any public functions that might be called from other elements*/ +}; + +/* Class definition for this class of element*/ +typedef Ucomplex::complex TSymCompArray5[3/*# range 0..2*/]; + //pTDynamicsRec = ^TDynamicsRec; + //pTGeneratorVars = ^TGeneratorVars; + +class TGeneric5Obj : public PCElement::TPCElement +{ + friend class TGeneric5; +public: + typedef PCElement::TPCElement inherited; +private: + + /*Private variables of this class*/ + int Connection; /*0 = line-neutral; 1=Delta*/ + Ucomplex::complex Yeq; // Y at nominal voltage + + //S1, // Pos seq slip + //S2, + // limit for slip to prevent solution blowing up + //dSdP, // for power flow + + /*Dynamics variables*/ // Rotor time constant + double puRs; + double puXs; + double puRr; + double puXr; + double puXm; + double MaxSlip; + double Xopen; + double Xp; + double T0p; + //NOrder, //NOrder = 5 is defined as constant + // system order + int NumOrderX; + int NumOrderY; // system output Y order + /*X,V*/ + /* X_var:pComplexArray; + Y_out_var :pComplexArray; + V_in_var :pComplexArray; + {A, B Matrix */ + /* Amm:pComplexArray; + Bmn:pComplexArray; + Cnm:pComplexArray; + Dnn:pComplexArray; + {*/ + Arraydef::pDoubleArray X_var; + Arraydef::pDoubleArray dX_vardt; + Arraydef::pDoubleArray X_varn;//for tropdize integrate + Arraydef::pDoubleArray dX_vardtn; + Arraydef::pDoubleArray Y_out_var; + Arraydef::pDoubleArray V_in_var; + Arraydef::pDoubleArray pV_f_CC; + bool CC_Switch; + //Cluster_num : integer; + /*A, B Matrix */ + Arraydef::pDoubleArray Amm; + Arraydef::pDoubleArray Bmn; + Arraydef::pDoubleArray Cnm; + Arraydef::pDoubleArray Dnn; + /**/ + bool InDynamics; + Ucomplex::complex Zs; + Ucomplex::complex ZM; + Ucomplex::complex Zr; // Keep the last computed voltages and currents + Ucomplex::complex Is1; + Ucomplex::complex Ir1; + Ucomplex::complex V1; + Ucomplex::complex Is2; + Ucomplex::complex Ir2; + Ucomplex::complex V2; + + /*Complex variables for dynamics*/ + //E1, E1n, dE1dt, dE1dtn, + //E2, E2n, dE2dt, dE2dtn, + Ucomplex::complex Zsp; + + /**/ + double id; + double Iq; //Id related to P ; Iq related to Q + bool flag_dyna_Id_chg; + double dIddt; + double dIqdt; + double Idn; + double Iqn; + double dIddtn; + double dIqdtn; //save last time step for integration. + /*the input for control purpose*/ + double kcd; + double kcq; + double kcq_drp2; //the control gain in vi1, vi2 + double Volt_Trhd; + int droop;//droop type: 2, Q = kcq_drp2 * (1-v_dg). others: integral droop with kcq + //flag_drp2 : integer; //if it is 1, drp2 + double kqi; //control gain for Q_ref + double vi1; + double vi2; //the input of the control + double vi1n; + double vi2n; //the input of the control + double dvi1dt; + double dvi2dt; + double dvi1dtn; + double dvi2dtn; + double Id_ref; + double Iq_ref; // The pursued value of Id related to P ; Iq related to Q + /**/ + double P_ref; + double Q_ref; + double V_ref;//Power and voltage goal of the machine + double DPX; + int ctrl_mode; //ctrl_mode 0-local droop V_ref = V_DG_0, P_ref = P_DG_0 + /**/ + double P_DG; + double Q_DG; //power of all phases totally in one + double V_DG;// the voltage magetitude of current bus + double Theta_DG; //the voltage angel of DG bus to slack + //Cluster_Num : integer; //the cluster define --move to PCElement + //Num_in_Cluster : integer; // node num in cluster; --move to PCElement + int QV_flag; // 0 Q_ref; 1 V_ref + //QV_flag_0 : integer; + //QV_switch: integer; //if Q hits limits, PV to PQ, the QV_switch:= 1; each time Edit function runs, check this and set QV_flag back to user set. + /*--for 3 phases--*/ + //power, voltage, angle, + double P_DG1; + double P_DG2; + double P_dg3; + double Q_DG1; + double Q_dg2; + double Q_dg3; + double V_DG1; + double V_DG2; + double V_DG3; + double V_theta1; + double V_theta2; + double V_theta3;//operation values + double ID1; + double Iq1; + double ID2; + double Iq2; + double Id3; + double Iq3; //currents + //set values + double P_ref1; + double P_ref2; + double P_ref3; + double Q_ref1; + double Q_ref2; + double Q_ref3; + double V_ref1; + double V_ref2; + double V_ref3;// set values from outside + /*------Max Check-------*/ + //SMax; // MachineData.kVArating; // 'g1.kva=100' + // Activity power output limit + //limit per phase + //(0, default) // 'g1.pmax=100' + // + //Reactive power output limit + //(-Qmax, default) + double PMax; + double PMax_phase; + double PMin; + double Pmin_phase; + double Qmax; + double Qmax_phase; + double Qmin; + double Qmin_phase; // + double IdMax_phase; + double IqMax_phase;//phase current limit + int PQpriority; //Active and reactive power control mode, control s + //'g1.pqvflag=0 Q, 1 P; + /////////////////// + //Gradient ; move to public + //Alpha, // Alpha := Q_DG/Qmax; + //dAlpha, + //Gradient: double; + /*----------------------*/ + //equivalent frequency + double Freq; + double z_dfs_plot; + /*----------------------*/ + bool FirstIteration; + bool FixedSlip; + + //var_Remembered :Double; //Q remembered of last calc + double DQDV; //for P_ref V_ref model + double RandomMult; + //Generic5SolutionCount : Integer; + bool Generic5SwitchOpen; + + // Debugging + System::TTextRec Tracefile; + bool DebugTrace; + GeneratorVars::TGeneratorVars MachineData; // Use generator variable structure + + // Andres: NEW variables from generator + bool MachineON; + Ucomplex::complex ShapeFactor; + bool ShapeIsActual; + // Andres: end NEW variables from generator + double VBase; + double kWBase; + /*---deal with -Update_Pmax_by_Ftrs-*///Pmpp, default value is 1.0; + //Pbias, default value is 0.0; +//factors, default value all are 1.0; + double Pmpp; + double Pbias; + double Pfctr1; + double Pfctr2; + double Pfctr3; + double Pfctr4; + double Pfctr5; + double Pfctr6; + + /*----------------*/ + //Gradient ; public + // Alpha := Q_DG/Qmax; //pos ctrl + double Alpha; + double dAlpha; + double Gradient; // Alpha := Q_DG/Qmax; //pos ctrl + double Alpha1; + double Alpha2; + double Alpha3; + double dAlpha1; + double dAlpha2; + double dAlpha3; + double Gradient1; + double Gradient2; + double Gradient3; + double AlphaP; + double AlphaP1; + double AlphaP2; + double AlphaP3;// for active P control + double GradientP; + double GradientP1; + double GradientP2; + double GradientP3; +// Procedure InterpretOption(s:String); + + //procedure set_Localslip(const Value: Double); + + //Procedure Get_PFlowModelCurrent(Const V:Complex; Const S:Double; var Istator, Irotor:Complex); + void Get_DynamicModelCurrent(); + //procedure Set_Slip(const Value: Double); + double GetRotorLosses(); + double GetStatorLosses(); + //Function Compute_dSdP:Double; + void Randomize(int Opt); + void InitModel(const TSymCompArray5& V012, const TSymCompArray5& I012); + void InitModelVIabc(int ActorID); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void CalcGeneric5ModelContribution(int ActorID); + void CalcInjCurrentArray(int ActorID); + void DoGeneric5Model(int ActorID); + void CalcModel(Ucomplex::pComplexArray V, Ucomplex::pComplexArray i, int ActorID); + + + // Andres: NEW procedures from generator + void CalcDailyMult(double hr); + void CalcYearlyMult(double hr); + void CalcDutyMult(double hr); + // Andres: NEW procedures from generator + void InitTraceFile(); + void WriteTraceRecord(int ActorID); + double Get_PresentkV(); + void Set_PresentkV(double Value); + void SetPowerkW(double PkW); + /**/ + void update_controlinput(int ActorID); + void update_pV_f_CC(int ActorID);// update cooperate control part, pV_f_CC + void update_pV_f_CC_M2(int ActorID);// update cooperate control part, pV_f_CC + void update_system_abcd(); + void Set_P_Ref(double PrefkW, int ActorID); + void Set_Q_Ref(double QrefkVAr); + void Set_V_Ref(double VrefkV); + void Update_kWbase_by_Fctrs(); + void Update_PQlimits(); //real time limits check + // can also be used in power flow and simulation + void InfoPublish(int ActorID); + //Procedure Get_Bii; + void CalGradient(); +// Procedure CalcDQDV; +protected: + + /*A couple of virtual procedures you can override*/ + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); + void DoDynamicMode(int ActorID); + void DoHarmonicMode(int ActorID); +public: + + /*Variables and functions accessed by DSS and other objects*/ + + // Andres: new variables from generator + String DailyDispShape; // Daily (24 HR) Generator shape + LoadShape::TLoadShapeObj* DailyDispShapeObj; // Daily Generator Shape for this load + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this generator + String DutyShape; // + String YearlyShape; // ='fixed' means no variation on all the time + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this Generator + // Andres: New variables from generator + TGeneric5Obj(DSSClass::TDSSClass* ParClass, const String Generic5ObjName); + virtual ~TGeneric5Obj(); + virtual void RecalcElementData(int ActorID); // Generally called after Edit is complete to recompute variables + virtual void CalcYPrim(int ActorID); // Calculate Primitive Y matrix + /*-----------*/ +// Procedure CalcABMatrix; + /*-----------*/ + void Integrate(int ActorID); + void IntegrateABCD(int ActorID); + void CalcDynamic(TSymCompArray5 V012, TSymCompArray5 I012, int ActorID); + void CalcPFlow(TSymCompArray5 V012, TSymCompArray5 I012, int ActorID); + // for abc phases: the below 2 + void CalcDynamicVIabc(Ucomplex::pComplexArray Vabc, Ucomplex::pComplexArray Iabc, int ActorID); + void CalcPFlowVIabc(Ucomplex::pComplexArray Vabc, Ucomplex::pComplexArray Iabc, int ActorID); + void SetNominalPower(int ActorID); + void UpdateAlpha_qi(); // \alpha_qi := Q_DG/Qmax; + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + + // State variable management functions, if any + // You can omit these if your PC element model is not using these + // Default behavior is to basically do nothing + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, if possible + + // Functions required for managing values of properties + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + + // Property LocalSlip:Double read S1 write set_Localslip; + //Property Slip:Double Write Set_Slip; + TGeneric5Obj(DSSClass::TDSSClass* ParClass); + TGeneric5Obj(String ClassName); + TGeneric5Obj(); +}; +extern TGeneric5* Generic5Class; +extern TGeneric5Obj* ActiveGeneric5Obj; + + +} // namespace Generic5OrderMach + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Generic5OrderMach; +#endif + +#endif // Generic5OrderMachH + + + + diff --git a/OpenDSSC/PCElements/IndMach012.cpp b/OpenDSSC/PCElements/IndMach012.cpp new file mode 100644 index 0000000..58312b1 --- /dev/null +++ b/OpenDSSC/PCElements/IndMach012.cpp @@ -0,0 +1,2400 @@ +#pragma hdrstop + +#include "IndMach012.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Command.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace GeneratorVars; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace IndMach012 +{ + +TIndMach012Obj::TIndMach012Obj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TIndMach012Obj::TIndMach012Obj(String ClassName) : inherited(ClassName) {} +TIndMach012Obj::TIndMach012Obj() {} + + +TIndMach012* IndMach012Class = nullptr; +TIndMach012Obj* ActiveIndMach012Obj = nullptr; + +/*Typical Uses Clause -- not all may not be needed*/ // DSS parser + // Where class is instantiated + // Global DSS variables + // If access to circuit variables is needed + // DSS command and property support module + // Delphi misc utility functions + // Delphi Math functions + // DSS Math utilities + // DSS misc utility functions +const int NumPropsThisClass = 21; // Set this constant to the actual number of properties you define +const int NumIndMach012Variables = 22; // Define any useful module vars here, for example: +complex cBuffer[24/*# range 1..24*/]; // Temp buffer for complex math calcs; allows up to 24-phase models. +complex CDoubleOne = {}; // 1 + j1 (see Initialization section below) + +String CmplxArrayToString(pComplexArray cpxarray, int Count) +{ + String result; + int i = 0; + + auto AppendMagAngle = [&]() -> void + { + result = result + + Format(" (%.6g, %.5g)", cabs((cpxarray)[i - 1]), cdang((cpxarray)[i - 1] )); + }; + result = "[NULL]"; + if(Count > 0) + { + int stop = 0; + result = Format("[%.6g +j %.6g", (cpxarray)[1 - 1].re, (cpxarray)[1 - 1].im); + i = 1; + AppendMagAngle(); + for(stop = Count, i = 2; i <= stop; i++) + { + result = result + + Format(", %.6g +j %.6g", (cpxarray)[i - 1].re, (cpxarray)[i - 1].im); + AppendMagAngle(); + } + result = result + "]"; + } + return result; +} +// Put array values in brackets separated by commas. +// Special version that appends magnitude and angle. + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates main collection handler for all IndMach012 objects + +TIndMach012::TIndMach012() +{ + ; // make the base class and init DSSClassType + + // Specify class name and bit mask ID for this class type + // IndMach012_ELEMENT must be defined in DSSClassDefs as nn*8 + // First 3 bits are used for base class type (DSSClassType) + Class_Name = "IndMach012"; + DSSClassType = DSSClassType + INDMACH012_ELEMENT; + ActiveElement = 0; // no active elements yet; init to 0 + + /*Initialize any other special variables here*/ + DefineProperties(); // This is where the properties for this class are defined + + // Use the Command processor to manage property names + // PropertyName is an array of String defined in DefineProperties + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + IndMach012Class = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TIndMach012::~TIndMach012() +{ + + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is where the properties are defined, assigned names, indexes, and help strings +// The Help strings will automatically show up when the Help is invoked + +void TIndMach012::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Refer to other classes for alternative methods of assigning properties + // This example uses the AddProperty function to assign Name, Index, and Help string + // in one statement. + + // First argument is string name of the property + // Second argument is the index for the CASE statement + // Third argument is help string + + // DSS properties are accessed in sequence if the property name is not explicitly specified. + // The advantage of using the AddProperty function is that you may change the sequence simply + // by shuffling the order of the definitions and you do not have to change the index in the CASE + // statement in the EDIT function + PropertyName[1 - 1] = "phases"; + PropertyName[2 - 1] = "bus1"; + PropertyName[3 - 1] = "kv"; + PropertyName[4 - 1] = "kW"; + PropertyName[5 - 1] = "pf"; + PropertyName[6 - 1] = "conn"; + PropertyName[7 - 1] = "kVA"; + PropertyName[8 - 1] = "H"; + PropertyName[9 - 1] = "D"; + PropertyName[10 - 1] = "puRs"; + PropertyName[11 - 1] = "puXs"; + PropertyName[12 - 1] = "puRr"; + PropertyName[13 - 1] = "puXr"; + PropertyName[14 - 1] = "puXm"; + PropertyName[15 - 1] = "Slip"; + PropertyName[16 - 1] = "MaxSlip"; + PropertyName[17 - 1] = "SlipOption"; + PropertyName[18 - 1] = "Yearly"; + PropertyName[19 - 1] = "Daily"; + PropertyName[20 - 1] = "Duty"; + PropertyName[21 - 1] = "Debugtrace"; + PropertyHelp[1 - 1] = "Number of Phases, this Induction Machine. "; + PropertyHelp[2 - 1] = "Bus to which the Induction Machine is connected. May include specific node specification."; + PropertyHelp[3 - 1] = "Nominal rated (1.0 per unit) voltage, kV. For 2- and 3-phase machines, specify phase-phase kV. " + "Otherwise, specify actual kV across each branch of the machine. " + "If wye (star), specify phase-neutral kV. " + "If delta or phase-phase connected, specify phase-phase kV."; // line-neutral voltage// base voltage + PropertyHelp[4 - 1] = String("Shaft Power, kW, for the Induction Machine. A positive value denotes power for a load. ") + CRLF + + "Negative value denotes an induction generator. "; + PropertyHelp[5 - 1] = "[Read Only] Present power factor for the machine. "; + PropertyHelp[6 - 1] = "Connection of stator: Delta or Wye. Default is Delta."; + PropertyHelp[7 - 1] = "Rated kVA for the machine."; + PropertyHelp[8 - 1] = "Per unit mass constant of the machine. MW-sec/MVA. Default is 1.0."; + PropertyHelp[9 - 1] = "Damping constant. Usual range is 0 to 4. Default is 1.0. Adjust to get damping in Dynamics mode,"; + PropertyHelp[10 - 1] = "Per unit stator resistance. Default is 0.0053."; + PropertyHelp[11 - 1] = "Per unit stator leakage reactance. Default is 0.106."; + PropertyHelp[12 - 1] = "Per unit rotor resistance. Default is 0.007."; + PropertyHelp[13 - 1] = "Per unit rotor leakage reactance. Default is 0.12."; + PropertyHelp[14 - 1] = "Per unit magnetizing reactance.Default is 4.0."; + PropertyHelp[15 - 1] = "Initial slip value. Default is 0.007"; + PropertyHelp[16 - 1] = "Max slip value to allow. Default is 0.1. Set this before setting slip."; + PropertyHelp[17 - 1] = "Option for slip model. One of {fixedslip | variableslip* }"; + PropertyHelp[18 - 1] = "LOADSHAPE object to use for yearly simulations. Must be previously defined " + "as a Loadshape object. Is set to the Daily load shape " + " when Daily is defined. The daily load shape is repeated in this case. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "The default is no variation."; + PropertyHelp[19 - 1] = "LOADSHAPE object to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "Default is no variation (constant) if not defined. " + "Side effect: Sets Yearly load shape if not already defined."; + PropertyHelp[20 - 1] = "LOADSHAPE object to use for duty cycle simulations. Must be previously defined " + "as a Loadshape object. Typically would have time intervals less than 1 hr. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat." + "Set to NONE to reset to no loadahape. " + "Set Status=Fixed to ignore Loadshape designation. " + " Defaults to Daily curve If not specified."; + PropertyHelp[21 - 1] = "[Yes | No*] Write DebugTrace file."; + + + /* add properties here */ + + // Finally, we have to pick up any properties that were inherited + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // You can optionally override default help string of an inherited property, for example + PropertyHelp[NumPropsThisClass + 1 - 1] = "Name of harmonic voltage or current spectrum for this IndMach012. " + "Voltage behind Xd\" for machine - default. Current injection for inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function is called by the DSS whenever a New IndMach012... command is encountered + +int TIndMach012::NewObject(const String ObjName) +{ + int result = 0; + // Make a new IndMach012 and add it to IndMach012 class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TIndMach012Obj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is a typical helper function found in many DSS circuit element class +// for defining the number of conductors per terminal (Nconds) based on Y or delta connection + +void TIndMach012::SetNcondsForConnection() +{ + /*# with ActiveIndMach012Obj do */ + { + auto with0 = ActiveIndMach012Obj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases); + break; // Neutral is not connected for induction machine + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: // Delta connection + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); // no neutral for this connection + break; + } + break; + default: + ; + break; + } + } +} + + +//- - - - - - - - - - - - - MAIN EDIT FUNCTION - - - - - - - - - - - - - - - +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// This function is the heart of the property managment for this class + +int TIndMach012::Edit(int ActorID) +{ + int result = 0; // Define some local vars for handling parser results + int ParamPointer = 0; + String ParamName; + String Param; + +// The Edit function starts where the Parser is presently pointing and +// manages the parsing of the rest of the command line in the parser. + +// The DSS executive processes the command verb on the front of the line and +// then passes control to the appropriate Edit function + + + // set the present element active + // and continue parsing with contents of Parser + ActiveIndMach012Obj = (TIndMach012Obj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveIndMach012Obj); + result = 0; + /*# with ActiveIndMach012Obj do */ + { + auto with0 = ActiveIndMach012Obj; + // peel off the next token on the edit line + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + + // Find the index for the CASE statement + // If property is not named, just increment the index to the next property + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + + // Update the PropertyValy for this property + // Actual index is mapped via PropertyIdxMap array for this class + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1],Param); + else + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for IndMach012 \"" + + with0->get_Name() + + "\"", 560); + + // --------------- MAIN CASE STATEMENT ---------------------- + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + // since we used AddProperty function to define properties, have to + // use PropertyIdxMap to map to the correct Case index + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case 3: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_()); + break; + case 4: + with0->kWBase = Parser[ActorID]->MakeDouble_(); + break; + case 5: + ; + break; // Do nothing; read only power factor := Parser.MakeDouble_(); + case 6: + InterpretConnection(Parser[ActorID]->MakeString_()); + break; + case 7: + with0->MachineData.kVArating = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->MachineData.Hmass = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->MachineData.D = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->puRs = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->puXs = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->puRr = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->puXr = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->puXm = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->Set_Slip(Parser[ActorID]->MakeDouble_()); + break; + case 16: + with0->MaxSlip = Parser[ActorID]->MakeDouble_(); + break; + case 17: + with0->InterpretOption(Parser[ActorID]->MakeString_()); + break; + case 18: + with0->YearlyShape = Param; + break; + case 19: + with0->DailyDispShape = Param; + break; + case 20: + with0->DutyShape = Param; + break; + case 21: + with0->DebugTrace = InterpretYesNo(Param); + break; + // Handle Inherited properties + default: + inherited::ClassEdit(ActiveIndMach012Obj, ParamPointer - NumPropsThisClass); + break; + } + + // ---------------- SIDE EFFECTS CASE STATEMENT --------------------- + // This case statment handles any side effects from setting a property + // (for example, from Generator) + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + case 18: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(ASSIGNED(with0->YearlyShapeObj)) + /*# with YearlyShapeObj do */ + { + auto with1 = with0->YearlyShapeObj; + if(with1->UseActual) + with0->SetPowerkW(with1->MaxP); + } + } + break; + case 19: + { + with0->DailyDispShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyDispShape)); + if(ASSIGNED(with0->DailyDispShapeObj)) + /*# with DailyDispShapeObj do */ + { + auto with2 = with0->DailyDispShapeObj; + if(with2->UseActual) + with0->SetPowerkW(with2->MaxP); + } + } + break; + case 20: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(ASSIGNED(with0->DutyShapeObj)) + /*# with DutyShapeObj do */ + { + auto with3 = with0->DutyShapeObj; + if(with3->UseActual) + with0->SetPowerkW(with3->MaxP); + } + } + break; + default: + ; + break; + } + + // Get next token off Parser and continue editing properties + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + + // After editing is complete, the typical next step is to call the RecalcElementData function + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); // Setting this flag notifies the DSS that something has changed + // and the Yprim will have to be rebuilt + } + return result; +} + +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- + + +// This function should be defined to handle the Like property inherited from +// the base class. + +// The function copies the essential properties of another object of this class + +int TIndMach012::MakeLike(const String OtherIndMach012Name) +{ + int result = 0; + TIndMach012Obj* OtherIndMach012 = nullptr; + int i = 0; + result = 0; + /*See if we can find this IndMach012 name in the present collection*/ + OtherIndMach012 = ((TIndMach012Obj*) Find(OtherIndMach012Name)); + if(OtherIndMach012 != nullptr) + /*# with ActiveIndMach012Obj do */ + { + auto with0 = ActiveIndMach012Obj; // skip if not found + + // You should first set the basic circuit element properties, for example + int stop = 0; + if(with0->Fnphases != OtherIndMach012->Fnphases) + { + with0->Set_NPhases(OtherIndMach012->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->Set_PresentkV(OtherIndMach012->Get_PresentkV()); + with0->kWBase = OtherIndMach012->kWBase; + with0->puRs = OtherIndMach012->puRs; + with0->puRr = OtherIndMach012->puRr; + with0->puXr = OtherIndMach012->puXr; + with0->puXm = OtherIndMach012->puXm; + with0->puXs = OtherIndMach012->puXs; + with0->MaxSlip = OtherIndMach012->MaxSlip; + with0->MachineData.kVArating = OtherIndMach012->MachineData.kVArating; + with0->MachineData.Hmass = OtherIndMach012->MachineData.Hmass; + with0->MachineData.D = OtherIndMach012->MachineData.D; + + // Do inherited properties + ClassMakeLike(OtherIndMach012); + + // Finally initialize all the property value strings to be the same as + // the copied element + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + if(i != 5) + // Skip read only properties + with0->FPropertyValue[i - 1] = OtherIndMach012->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Load MakeLike: \"") + OtherIndMach012Name + + "\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Optional function if you want to do anything to initialize objects of this class + +int TIndMach012::Init(int Handle, int ActorID) +{ + int result = 0; + TIndMach012Obj* P = nullptr; + if(Handle == 0) // init all + { + P = (TIndMach012Obj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TIndMach012Obj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TIndMach012Obj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TIndMach012.Init", -1); + result = 0; + return result; +} + + +//------------------------- MAIN OBJECT CONSTRUCTOR --------------------- + +//---------------------------------------------------------------------------- + +TIndMach012Obj::TIndMach012Obj(TDSSClass* ParClass, const String IndMach012ObjName) + : inherited(ParClass), + Connection(1), + puRs(0.0), + puXs(0.0), + puRr(0.0), + puXr(0.0), + puXm(0.0), + S1(0.0), + S2(0.0), + MaxSlip(0.0), + dSdP(0.0), + Xopen(0.0), + Xp(0.0), + T0p(0.0), + InDynamics(false), + FirstIteration(false), + FixedSlip(false), + RandomMult(0.0), + IndMach012SolutionCount(0), + IndMach012SwitchOpen(false), + DebugTrace(false), + MachineON(false), + ShapeIsActual(false), + VBase(0.0), + kWBase(0.0), + DailyDispShapeObj(nullptr), + DutyShapeObj(nullptr), + YearlyShapeObj(nullptr) +{ + Set_Name(LowerCase(IndMach012ObjName)); + DSSObjType = ParClass->DSSClassType; // Same as Parent Class + + // Set some basic circuit element properties + Set_NPhases(3); // typical DSS default for a circuit element + Fnconds = 3; // defaults to delta + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations of terminal quantities + kWBase = 1000.0; + YearlyShape = ""; + YearlyShapeObj = nullptr; // if YearlyShapeobj = nil then the load alway stays nominal * global multipliers + DailyDispShape = ""; + DailyDispShapeObj = nullptr; // if DaillyShapeobj = nil then the load alway stays nominal * global multipliers + DutyShape = ""; + DutyShapeObj = nullptr; // if DutyShapeobj = nil then the load alway stays nominal * global multipliers + DebugTrace = false; + Yorder = Fnterms * Fnconds; + ShapeIsActual = false; + IndMach012SwitchOpen = false; + MachineData.kVGeneratorBase = 12.47; + MachineData.kVArating = kWBase * 1.2; + /*# with MachineData do */ + { + auto& with0 = MachineData; + with0.Hmass = 1.0; // W-sec/VA rating + with0.Theta = 0.0; + with0.w0 = TwoPi * BaseFrequency; + with0.Speed = 0.0; // relative speed + with0.dSpeed = 0.0; + with0.D = 1.0; + with0.XRdp = 20.0; // not used for indmach + + // newly added + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + } + + /*---- end note Andres: from dll model ----*/ + + /*Typical machine impedance data*/ + puRs = 0.0053; + puXs = 0.106; + puRr = 0.007; + puXr = 0.12; + puXm = 4.0; + + // Set slip local and make generator model agree + MaxSlip = 0.1; // 10% slip limit - set this before setting slip + Set_Slip(0.007); // About 1 pu power + FixedSlip = false; // Allow Slip to float to match specified power + InDynamics = false; + + // call the procedure to set the initial property string values + InitPropertyValues(0); + + // Update anything that has to be calculated from property values + RecalcElementData(ActiveActor); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Free everything here that needs to be freed +// If you allocated anything, dispose of it here + +TIndMach012Obj::~TIndMach012Obj() +{ + // inherited::Destroy(); // This will take care of most common circuit element arrays, etc. +} + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::RecalcElementData(int ActorID) +{ + double Rs = 0.0; + double Xs = 0.0; + double rr = 0.0; + double Xr = 0.0; + double XM = 0.0; + double ZBase = 0.0; + /*# with MachineData do */ + { + auto& with0 = MachineData; + ZBase = Sqr(with0.kVGeneratorBase) / with0.kVArating * 1000.0; + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + } + Rs = puRs * ZBase; + Xs = puXs * ZBase; + rr = puRr * ZBase; + Xr = puXr * ZBase; + XM = puXm * ZBase; + Zs = cmplx(Rs, Xs); + ZM = cmplx(0.0, XM); + Zr = cmplx(rr, Xr); + Xopen = Xs + XM; + Xp = Xs + (Xr * XM) / (Xr + XM); + Zsp = cmplx(Rs, Xp); + //Yeq := Cinv(Zsp); // for Yprim for dynamics + //Yeq := Cmplx(1.0/ZBase, -0.5/Zbase); // vars are half the watts + Yeq = cmplx(0.0, -1.0 / ZBase); // vars only for power flow + T0p = (Xr + XM) / (MachineData.w0 * rr); + dSdP = Compute_dSdP(); + Is1 = CZero; + V1 = CZero; + Is2 = CZero; + V2 = CZero; + FirstIteration = true; + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + SetNominalPower(ActorID); + if(CompareText(YearlyShape, "none") == 0) + YearlyShape = ""; + if(CompareText(DailyDispShape, "none") == 0) + DailyDispShape = ""; + if(CompareText(DutyShape, "none") == 0) + DutyShape = ""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 563); + } + if(DailyDispShapeObj == nullptr) + { + if(DailyDispShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyDispShape + + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 565); + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 566); + if(DebugTrace) + InitTraceFile(); +} + +double TIndMach012Obj::Get_PresentkV() +{ + double result = 0.0; + result = MachineData.kVGeneratorBase; + return result; +} + +void TIndMach012Obj::Set_PresentkV(double Value) +{ + /*# with MachineData do */ + { + auto& with0 = MachineData; + with0.kVGeneratorBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = with0.kVGeneratorBase * InvSQRT3x1000; + break; + default: + VBase = with0.kVGeneratorBase * 1000.0; + break; + } + } +} + +void TIndMach012Obj::InterpretOption(String s) +{ + switch(UpperCase(s)[1]) + { + case L'F': + FixedSlip = true; + break; + case L'V': + FixedSlip = false; + break; + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::SetPowerkW(double PkW) +{ + kWBase = PkW; +} + +//---------------------------------------------------------------------------- +//--------------------- MAIN CALC ROUTINES ----------------------------------- + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::Integrate(int ActorID) +{ + double H2 = 0.0; + /*# with ActiveCircuit[ActorID].Solution.DynaVars do */ + { + auto& with0 = ActiveCircuit[ActorID]->Solution->DynaVars; + if(with0.IterationFlag == 0) // on predictor step + { + E1n = E1; // update old values + dE1dtn = dE1dt; + E2n = E2; + dE2dtn = dE2dt; + } + + // Derivative of E + // dEdt = -jw0SE' - (E' - j(X-X')I')/T0' + dE1dt = csub(cmul(cmplx(0.0, -MachineData.w0 * S1), E1), cdivreal(csub(E1, cmul(cmplx(0.0, (Xopen - Xp)), Is1)), T0p)); + dE2dt = csub(cmul(cmplx(0.0, -MachineData.w0 * S2), E2), cdivreal(csub(E2, cmul(cmplx(0.0, (Xopen - Xp)), Is2)), T0p)); + + // Trapezoidal Integration + H2 = with0.h * 0.5; + E1 = cadd(E1n, cmulreal(cadd(dE1dt, dE1dtn), H2)); + E2 = cadd(E2n, cmulreal(cadd(dE2dt, dE2dtn), H2)); + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::CalcDynamic(TSymCompArray V012, TSymCompArray I012) +{ + + /*In dynamics mode, slip is allowed to vary*/ + InDynamics = true; + V1 = V012[1]; // Save for variable calcs + V2 = V012[2]; + /*Gets slip from shaft speed*/ + /*# with MachineData do */ + { + auto& with0 = MachineData; + set_Localslip((-with0.Speed) / with0.w0); + } + Get_DynamicModelCurrent(); + + // Get_ModelCurrent(V2, S2, Is2, Ir2); + I012[1] = Is1; // Save for variable calcs + I012[2] = Is2; + I012[0] = cmplx(0.0, 0.0); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::CalcPFlow(TSymCompArray V012, TSymCompArray I012) +{ + double P_Error = 0.0; + V1 = V012[1]; // Save for variable calcs + V2 = V012[2]; + InDynamics = false; + if(FirstIteration) + { + Get_PFlowModelCurrent(V1, S1, Is1, Ir1); // initialize Is1 + FirstIteration = false; + } + + /*If Fixed slip option set, then use the value set by the user*/ + if(!FixedSlip) + { + P_Error = MachineData.Pnominalperphase - cmul(V1, conjg(Is1)).re; + set_Localslip(S1 + dSdP * P_Error); // make new guess at slip + } + Get_PFlowModelCurrent(V1, S1, Is1, Ir1); + Get_PFlowModelCurrent(V2, S2, Is2, Ir2); + I012[1] = Is1; // Save for variable calcs + I012[2] = Is2; + I012[0] = cmplx(0.0, 0.0); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// typical proc for handling randomization in DSS fashion + +void TIndMach012Obj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + // GAUSSIAN: RandomMult := Gauss(YearlyShapeObj.Mean, YearlyShapeObj.StdDev); + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + // LOGNORMAL: RandomMult := QuasiLognormal(YearlyShapeObj.Mean); + default: + ; + break; + } +} + + +/*-------------------------------------------------------------------------------------------------------------*/ +/*-------------------------------------------------------------------------------------------------------------*/ + +// Init for Dynamics mode + +void TIndMach012Obj::InitModel(const TSymCompArray& V012, const TSymCompArray& I012) +{ + + + // Compute Voltage behind transient reactance and set derivatives to zero + // *** already done *** E1 := csub(V012[1], cmul(I012[1], Zsp)); + dE1dt = CZero; + E1n = E1; + dE1dtn = dE1dt; + E2 = csub(V012[2], cmul(I012[2], Zsp)); + dE2dt = CZero; + E2n = E2; + dE2dtn = dE2dt; +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::InitStateVars(int ActorID) +{ + int i = 0; + TSymCompArray V012 = {}; + TSymCompArray I012 = {}; + complex Vabc[4] = { CZero, CZero ,CZero ,CZero }; + + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + /*# with MachineData do */ + { + auto& with0 = MachineData; + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if(MachineON) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + Yeq = cinv(Zsp); + TPCElement::ComputeIterminal(ActorID); + switch(Fnphases) + { + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + E1 = csub(csub(with1->NodeV[(NodeRef)[1 - 1]], with1->NodeV[(NodeRef)[2 - 1]]), cmul((Iterminal)[1 - 1], Zsp)); + else + E1 = csub(csub(with1->VoltInActor1((NodeRef)[1 - 1]), with1->VoltInActor1((NodeRef)[2 - 1])), cmul((Iterminal)[1 - 1], Zsp)); + } + break; + // Calculate E1 based on Pos Seq only + case 3: + { + int stop = 0; + Phase2SymComp(&(Iterminal[0]), &I012[0]); // terminal currents + + // Voltage behind Zsp (transient reactance), volts + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vabc[i - 1] = with1->NodeV[(NodeRef)[i - 1]]; + else + Vabc[i - 1] = with1->VoltInActor1((NodeRef)[i - 1]); // Wye Voltage + } + Phase2SymComp(&Vabc[0], &V012[0]); + E1 = csub(V012[1], cmul(I012[1], Zsp)); // Pos sequence + } + break; + default: + DoSimpleMsg(Format(("Dynamics mode is implemented only for 1- or 3-phase Motors. IndMach012." + with1->get_Name() + + " has %d phases.").c_str(), Fnphases), 5672); + SolutionAbort = true; + break; + } + InitModel(V012, I012); // E2, etc + + // Shaft variables + with0.Theta = cang(E1); + with0.dTheta = 0.0; + with0.w0 = TwoPi * ActiveCircuit[ActorID]->Solution->get_FFrequency(); + // recalc Mmass and D in case the frequency has changed + /*# with MachineData do */ + { + auto& with2 = MachineData; + with2.Mmass = 2.0 * with2.Hmass * with2.kVArating * 1000.0 / (with2.w0); // M = W-sec + with2.D = with2.Dpu * with2.kVArating * 1000.0 / (with2.w0); + } + with0.Pshaft = Get_Power(1, ActorID).re; // Initialize Pshaft to present power consumption of motor + with0.Speed = -get_S1() * with0.w0; // relative to synch speed + with0.dSpeed = 0.0; + if(DebugTrace) // Put in a separator record + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile); + WriteLn(Tracefile, "*************** Entering Dynamics Mode ***********************"); + WriteLn(Tracefile); + Close(Tracefile); + } + } + else + { + with0.Theta = 0.0; + with0.dTheta = 0.0; + with0.w0 = 0; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + } + } /*With*/ +} + +//---------------------------------------------------------------------------- + +double TIndMach012Obj::get_S1() +{ + return S1; +} + +//---------------------------------------------------------------------------- + + +/*A typical helper function for PC elements to assist in the computation + of Yprim +*/ + +void TIndMach012Obj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + complex Yadder = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; // ratio to adjust reactances for present solution frequency + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsDynamicModel || with0->IsHarmonicModel) + // for Dynamics and Harmonics modes use constant equivalent Y + { + int stop = 0; + if(MachineON) // L-N value computed in initialization routines + Y = Yeq; + else + Y = cmplx(EPSILON, 0.0); + if(Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; // adjust for frequency + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); // sets the element + /* + Ymatrix.AddElement(Fnconds, Fnconds, Y); // sums the element + Ymatrix.SetElemsym(i, Fnconds, Yij); + */ + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Yadder = cmulreal(Y, 1.000001); // to prevent floating delta + Ymatrix->SetElement(i, i, cadd(Y, Yadder)); // add a little bit to diagonal + Ymatrix->AddElement(i, i, Y); // put it in again + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + else + + + // Typical code for a regular power flow model + // Borrowed from Generator object + + /*Yeq is typically expected as the equivalent line-neutral admittance*/ + { + Y = Yeq; // Yeq is L-N quantity + + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + switch(Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + /* + AddElement(Fnconds, Fnconds, Y); + SetElemsym(i, Fnconds, Yij); + */ + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } /*ELSE IF Solution.mode*/ +} + +/*--- Notes Andres: Added according to IndMach012.dll model */ + +double TIndMach012Obj::Compute_dSdP() +{ + double result = 0.0; +// dSdP based on rated slip and rated voltage + V1 = cmplx(MachineData.kVGeneratorBase * 1000.0 / 1.732, 0.0); + if(S1 != 0.0) + Get_PFlowModelCurrent(V1, S1, Is1, Ir1); + result = S1 / cmul(V1, conjg(Is1)).re; + return result; +} + +//---------------------------------------------------------------------------- + + +// Required routine to calculate the primitive Y matrix for this element + +// This example uses a helper function (CalcYPrimMatrix) to keep the code +// here clean + +void TIndMach012Obj::CalcYPrim(int ActorID) +{ + int i = 0; + +/* + There are three Yprim matrices that could be computed: + + YPrim_Series: Used for zero-load solutions to initialize the first guess + YPrim_Shunt: Equivalent Y in shunt with power system + For PC elements, this is typically the main YPrim + YPrim: Generally the sum of the other two; the total YPrim +*/ + + // Typical PC Elements build only shunt Yprim + // Also, build a dummy Yprim Series so that CalcVoltagebases does not fail + + // First clear present value; redefine if necessary + // Note: Complex matrix (TcMatrix -- see uCmatrix.pas) is used for this + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + + + // call helper routine to compute YPrim_Shunt + CalcYPrimMatrix(YPrim_Shunt, ActorID); + + // Set YPrim_Series based on a small fraction of the diagonals of YPrim_shunt + // so that CalcVoltages doesn't fail + // This is just one of a number of possible strategies but seems to work most of the time + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + + // copy YPrim_shunt into YPrim; That's all that is needed for most PC Elements + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors -- done in base class + TDSSCktElement::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/*Compute total terminal Current */ + +void TIndMach012Obj::DoIndMach012Model(int ActorID) +{ + int i = 0; + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcModel(&(Vterminal[0]), &(Iterminal[0]), ActorID); + set_ITerminalUpdated(true, ActorID); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + if(DebugTrace) + WriteTraceRecord(ActorID); +} // given voltages returns currents + +void TIndMach012Obj::CalcModel(pComplexArray V, pComplexArray i, int ActorID) +{ + TSymCompArray V012 = {}; + TSymCompArray I012 = {}; + + // Convert abc voltages to 012 + Phase2SymComp(V, &V012[0]); + + // compute I012 + switch(ActiveCircuit[ActorID]->Solution->DynaVars.SolutionMode) + { + case DYNAMICMODE: + { + CalcDynamic(V012, I012); + } + break; /*All other modes are power flow modes*/ + default: + CalcPFlow(V012, I012); + break; + } + SymComp2Phase(i, &I012[0]); // convert back to I abc +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* This is an example taken from Generator illustrating how a PC element might + handle Dynamics mode with a Thevenin equivalent + + Also illustrates the computation of symmetrical component values +*/ + +/*Compute Total Current and add into InjTemp*/ + +void TIndMach012Obj::DoDynamicMode(int ActorID) +{ + int i = 0; + + // Start off by getting the current in the admittance branch of the model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + + /*Inj = -Itotal (in) - Yprim*Vtemp*/ + CalcModel(&(Vterminal[0]), &(Iterminal[0]), ActorID); + set_ITerminalUpdated(true, ActorID); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* + Example taken from Generator illustrating how a PC element might handle + current calcs for Harmonics mode + + Note: Generator objects assume a Thevenin model (voltage behind and impedance) + while Load objects assume the Spectrum applies to a Norton model injection current +*/ + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TIndMach012Obj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double GenHarmonic = 0.0; + + // Set the VTerminal array + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + GenHarmonic = with0->get_FFrequency() / BaseFrequency; // harmonic based on the fundamental for this object + // get the spectrum multiplier and multiply by the V thev (or Norton current for load objects) + // ??? E := CmulReal(SpectrumObj.GetMult(GenHarmonic), VThevHarm); // Get base harmonic magnitude + // ??? RotatePhasorRad(E, GenHarmonic, ThetaHarm); // Time shift by fundamental frequency phase shift + + // Put the values in a temp complex buffer + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, GenHarmonic, -120.0); // Assume 3-phase IndMach012 + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + // In this case the injection currents are simply Yprim(frequency) times the voltage buffer + // Refer to Load.Pas for load-type objects + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Main dispatcher for computing PC Element currnts + +// Calculates IndMach012 current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TIndMach012Obj::CalcIndMach012ModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + DoIndMach012Model(ActorID); + } + } /*WITH*/ + + /*When this is done, ITerminal is up to date*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Main procedure for controlling computation of InjCurrent array + +// InjCurrent is difference between currents in YPrim and total terminal current + +void TIndMach012Obj::CalcInjCurrentArray(int ActorID) +{ + + +// You usually will want some logic like this + + // If the element is open, just zero the array and return + if(IndMach012SwitchOpen) + + // otherwise, go to a routine that manages the calculation + ZeroInjCurrent(); + else + CalcIndMach012ModelContribution(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// This function controls the calculation of the total terminal currents + +// Note that it only does something if the solution count has changed. +// Otherwise, Iterminal array already contains the currents + +void TIndMach012Obj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + // You will likely want some logic like this + { + if(!IndMach012SwitchOpen) + CalcIndMach012ModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); // add in inherited contribution + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Required function for managing computing of InjCurrents + +int TIndMach012Obj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + + // Generators and Loads use logic like this: + if(with0->LoadsNeedUpdating) + SetNominalPower(ActorID); // Set the nominal kW, etc for the type of solution being done + + // call the main function for doing calculation + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + + // If (DebugTrace) Then WriteTraceRecord; + + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +// Set shaft power + +void TIndMach012Obj::SetNominalPower(int ActorID) +{ + double Factor = 0.0; + bool MachineOn_Saved = false; + MachineOn_Saved = MachineON; + ShapeFactor = CDoubleOne; + // Check to make sure the generation is ON + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) // Leave machine in whatever state it was prior to entering Dynamic mode + { + MachineON = true; // Init to on then check if it should be off + } + if(!MachineON) + // If Machine is OFF enter as tiny resistive load (.0001 pu) so we don't get divide by zero in matrix + { + MachineData.Pnominalperphase = -0.1 * kWBase / Fnphases; + // Pnominalperphase := 0.0; + MachineData.Qnominalperphase = 0.0; // This really doesn't matter + } + else + // Generator is on, compute it's nominal watts and vars + { + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + switch(with2->Get_SolMode()) + { + case SNAPSHOT: + Factor = 1.0; + break; + case DAILYMODE: + { + Factor = 1.0; // Daily dispatch curve + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + Factor = 1.0; + CalcYearlyMult(with2->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + Factor = 1.0; + CalcDutyMult(with2->DynaVars.dblHour); + } + break; // General sequential time simulation + case GENERALTIME: case DYNAMICMODE: + { + Factor = 1.0; + // This mode allows use of one class of load shape + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with2->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with2->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with2->DynaVars.dblHour); + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + case MONTECARLO1: case MONTEFAULT: case FAULTSTUDY: + Factor = 1.0; + break; + case MONTECARLO2: case MONTECARLO3: case LOADDURATION1: case LOADDURATION2: + { + Factor = 1.0; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case PEAKDAY: + { + Factor = 1.0; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case AUTOADDFLAG: + Factor = 1.0; + break; + default: + Factor = 1.0; + break; + } + } + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + if(ShapeIsActual) + MachineData.Pnominalperphase = 1000.0 * ShapeFactor.re / Fnphases; + else + MachineData.Pnominalperphase = 1000.0 * kWBase * Factor * ShapeFactor.re / Fnphases; + + // cannot dispatch vars in induction machine + // you get what you get + } + } /*ELSE GenON*/ + } /*With ActiveCircuit*/ + + // If machine state changes, force re-calc of Y matrix + if(MachineON != MachineOn_Saved) + Set_YprimInvalid(ActorID,true); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::CalcDailyMult(double hr) +{ + if(DailyDispShapeObj != nullptr) + { + ShapeFactor = DailyDispShapeObj->GetMult(hr); + ShapeIsActual = DailyDispShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Default to no daily variation +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult if no duty curve specified +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Defaults to no variation +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- + +// Gets the currents for the last solution performed + +// Do not call anything that may change the basic element values from the last solution + +void TIndMach012Obj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + // an exception here generally means an array boundary overrun + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("IndMach012 Object: \"") + get_Name() + "\" in GetInjCurrents function.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +//---------------------------------------------------------------------------- +/* + This procedure is require to respond to various commands such as Dump that + write all the device's property values to a file. +*/ + +void TIndMach012Obj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + + /*Write out any specials here, usually preceded by a "!"*/ + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; // Map to get proper index into property value array + switch(Idx) + { + case 34: case 36: + /*Trap any specials here, such as values that are array properties, for example*/ + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/*Procedure to initialize for Harmonics solution*/ + +/*This example is extracted from Generator and constructs a Thevinen equivalent. + Refer to Load for how to do a Norton equivalent + */ + +void TIndMach012Obj::InitHarmonics(int ActorID) +{ + complex e = {}; + complex Va = {}; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + +/**** + GenFundamental := ActiveCircuit.Solution.Frequency ; // Whatever the frequency is when we enter here. + + With GenVars Do Begin + + // Xd" is used for harmonics analysis for generators + Yeq := Cinv(Cmplx(0.0, Xdpp)); // used for current calcs Always L-N + + {Compute reference Thevinen voltage from phase 1 current} + + IF GenON Then + Begin + + ComputeIterminal; // Get present value of current + + With ActiveCircuit.solution Do + Case Connection of + 0: Begin {wye - neutral is explicit} + Va := Csub(NodeV^[NodeRef^[1]], NodeV^[NodeRef^[Fnconds]]); + End; + 1: Begin {delta -- assume neutral is at zero} + Va := NodeV^[NodeRef^[1]]; + End; + End; + + E := Csub(Va, Cmul(Iterminal^[1], cmplx(0.0, Xdpp))); + Vthevharm := Cabs(E); // establish base mag and angle + ThetaHarm := Cang(E); + End + ELSE Begin + // If Generator is off, just set to zero + Vthevharm := 0.0; + ThetaHarm := 0.0; + End; + End; + ***/ +} + +// ******************* PROPERTY VALUES ******************* + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// required procedure to initialize the string value of the properties + +void TIndMach012Obj::InitPropertyValues(int ArrayOffset) +{ + + // Some examples + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(3,"12.47"); + Set_PropertyValue(4,"100"); + Set_PropertyValue(5,".80"); + Set_PropertyValue(6,"Delta"); + Set_PropertyValue(7,Format("%-g", MachineData.kVArating)); + Set_PropertyValue(8,Format("%-g", MachineData.Hmass)); + Set_PropertyValue(9,Format("%-g", MachineData.D)); + Set_PropertyValue(10,"0.0053"); + Set_PropertyValue(11,"0.106"); + Set_PropertyValue(12,"0.007"); + Set_PropertyValue(13,"0.12"); + Set_PropertyValue(14,"4.0"); + Set_PropertyValue(15,"0.007"); + Set_PropertyValue(16,"0.1"); + Set_PropertyValue(17,"variable"); + Set_PropertyValue(18,""); + Set_PropertyValue(19,""); + Set_PropertyValue(20,""); /*...*/ + Set_PropertyValue(21,"NO"); + +/*Call inherited function to init inherited property values*/ + inherited::InitPropertyValues(NumPropsThisClass); +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Return i-th property value as a string + +String TIndMach012Obj::GetPropertyValue(int Index) +{ + String result; + result = ""; // Init the string + switch(Index) + { + case 4: + // Put special cases here + // often a good idea to convert numeric values to strings, for example + result = Format("%.6g", kWBase); + break; + case 5: + result = Format("%.6g", PowerFactor(Get_Power(1, ActiveActor))); + break; + case 7: + result = Format("%.6g", MachineData.kVArating); + break; + case 8: + result = Format("%.6g", MachineData.Hmass); + break; + case 9: + result = Format("%.6g", MachineData.D); + break; + case 15: + result = Format("%.6g", get_S1()); + break; + case 18: + result = YearlyShape; + break; + case 19: + result = DailyDispShape; + break; + case 20: + result = DutyShape; + break; + /*...*/ + + // The default is to just return the current string value of the property + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +// ******************* END PROPERTY VALUES ******************* + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + This is a virtual function. You do not need to write this routine + if you are not integrating state variables in dynamics mode. +*/ + +// Integrate state variables for Dynamics analysis +// Example from Generator + +// Illustrates use of debug tracing + +// Present technique is a predictor-corrector trapezoidal rule + +void TIndMach012Obj::IntegrateStates(int ActorID) +{ + complex TracePower = {}; + // Compute Derivatives and then integrate + TDSSCktElement::ComputeIterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution, MachineData do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = MachineData; + /*# with DynaVars do */ + { + auto& with2 = with0->DynaVars; + if(with2.IterationFlag == 0) /*First iteration of new time step*/ + { + with1.ThetaHistory = with1.Theta + 0.5 * with2.h * with1.dTheta; + with1.SpeedHistory = with1.Speed + 0.5 * with2.h * with1.dSpeed; + } + } + + // Compute shaft dynamics + TracePower = TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases); // in watts + with1.dSpeed = (TracePower.re - with1.Pshaft - Abs((int) (with1.D * with1.Speed))) / with1.Mmass; + with1.dTheta = with1.Speed; + + // Trapezoidal method + /*# with DynaVars do */ + { + auto& with3 = with0->DynaVars; + with1.Speed = with1.SpeedHistory + 0.5 * with3.h * with1.dSpeed; + with1.Theta = with1.ThetaHistory + 0.5 * with3.h * with1.dTheta; + } + if(DebugTrace) + WriteTraceRecord(ActorID); + Integrate(ActorID); + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::Get_DynamicModelCurrent() +{ + Is1 = cdiv(csub(V1, E1), Zsp); // I = (V-E')/Z' + Is2 = cdiv(csub(V2, E2), Zsp); // I = (V-E')/Z' + + // rotor current Ir1= Is1-Vm/jXm + Ir1 = csub(Is1, cdiv(csub(V1, cmul(Is1, Zsp)), ZM)); + Ir2 = csub(Is2, cdiv(csub(V2, cmul(Is2, Zsp)), ZM)); +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::Get_PFlowModelCurrent(const complex& V, double s, complex& Istator, complex& Irotor) +{ + double RL = 0.0; + complex ZRotor = {}; + complex numerator = {}; + complex Zmotor = {}; + if(s != 0.0) + RL = Zr.re * (1.0 - s) / s; + else + RL = Zr.re * 1.0e6; + ZRotor = cadd(cmplx(RL, 0.0), Zr); + numerator = cmul(ZM, ZRotor); + Zmotor = cadd(Zs, cdiv(numerator, cadd(ZRotor, ZM))); + Istator = cdiv(V, Zmotor); + /*Ir = Is -(V-ZsIs)/Zm*/ + Irotor = csub(Istator, cdiv(csub(V, cmul(Zs, Istator)), ZM)); +} + +//---------------------------------------------------------------------------- +// ********************** VARIABLES *************************************** +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/* + Return the number of state variables + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. + Note: it is not necessary to define any state variables +*/ + +int TIndMach012Obj::NumVariables() +{ + int result = 0; + result = NumIndMach012Variables; + return result; +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + Returns the i-th state variable in a string + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +String TIndMach012Obj::VariableName(int i) +{ + String result; + if(i < 1) + return result; // This means Someone goofed + switch(i) + { + case 1: + result = "Frequency"; + break; + case 2: + result = "Theta (deg)"; + break; + case 3: + result = "E1"; + break; + case 4: + result = "Pshaft"; + break; + case 5: + result = "dSpeed (deg/sec)"; + break; + case 6: + result = "dTheta (deg)"; + break; + case 7: + result = "Slip"; + break; + case 8: + result = "puRs"; + break; + case 9: + result = "puXs"; + break; + case 10: + result = "puRr"; + break; + case 11: + result = "puXr"; + break; + case 12: + result = "puXm"; + break; + case 13: + result = "Maxslip"; + break; + case 14: + result = "Is1"; + break; + case 15: + result = "Is2"; + break; + case 16: + result = "Ir1"; + break; + case 17: + result = "Ir2"; + break; + case 18: + result = "Stator Losses"; + break; + case 19: + result = "Rotor Losses"; + break; + case 20: + result = "Shaft Power (hp)"; + break; + case 21: + result = "Power Factor"; + break; + case 22: + result = "Efficiency (%)"; + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TIndMach012Obj::Get_Variable(int i) +{ + double result = 0.0; + result = -9999.99; // Error Value + /*# with MachineData do */ + { + auto& with0 = MachineData; + switch(i) + { + case 1: + result = (with0.w0 + with0.Speed) / TwoPi; + break; // Frequency, Hz + case 2: + result = (with0.Theta) * RadiansToDegrees; + break; // Report in Deg + case 3: + result = cabs(E1) / VBase; + break; // Report in pu + case 4: + result = with0.Pshaft; + break; + case 5: + result = with0.dSpeed * RadiansToDegrees; + break; // Report in Deg 57.29577951 + case 6: + result = with0.dTheta; + break; + case 7: + result = get_S1(); + break; + case 8: + result = puRs; + break; + case 9: + result = puXs; + break; + case 10: + result = puRr; + break; + case 11: + result = puXr; + break; + case 12: + result = puXm; + break; + case 13: + result = MaxSlip; + break; + case 14: + result = cabs(Is1); + break; + case 15: + result = cabs(Is2); + break; + case 16: + result = cabs(Ir1); + break; + case 17: + result = cabs(Ir2); + break; + case 18: + result = GetStatorLosses(); + break; + case 19: + result = GetRotorLosses(); + break; // Shaft Power (hp) + case 20: + { + result = 3.0 / 746.0 * (Sqr(cabs(Ir1)) * (1.0 - S1) / S1 + Sqr(cabs(Ir2)) * (1.0 - S2) / S2) * Zr.re; + } + break; + case 21: + result = PowerFactor(Get_Power(1, ActiveActor)); + break; + case 22: + result = (1.0 - (GetStatorLosses() + GetRotorLosses()) / Get_Power(1, ActiveActor).re) * 100.0; + break; // Efficiency + default: + ; + break; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::Set_Variable(int i, double Value) +{ + switch(i) + { + case 7: + Set_Slip(Value); + break; + case 8: + puRs = Value; + break; + case 9: + puXs = Value; + break; + case 10: + puRr = Value; + break; + case 11: + puXr = Value; + break; + case 12: + puXm = Value; + break; + /*Do Nothing for other variables: they are read only*/ + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- +/* + Return all state variables in double array (allocated by calling function) + + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +void TIndMach012Obj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int n = 0; + int stop = 0; + n = 0; + for(stop = NumIndMach012Variables, i = 1; i <= stop; i++) + { + (States)[i - 1] = Get_Variable(i); + } +} + +// ********************** END VARIABLES *************************************** + + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TIndMach012Obj::GetRotorLosses() +{ + double result = 0.0; + result = 3.0 * (Sqr(Ir1.re) + Sqr(Ir1.im) + Sqr(Ir2.re) + Sqr(Ir2.im)) * Zr.re; + return result; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +double TIndMach012Obj::GetStatorLosses() +{ + double result = 0.0; + result = 3.0 * (Sqr(Is1.re) + Sqr(Is1.im) + Sqr(Is2.re) + Sqr(Is2.im)) * Zs.re; + return result; +} + + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +/* + This is a virtual function. You do not need to write this routine + if the base class function will suffice. +*/ + +// Routine to convert existing three-phase models to a single-phase positive- +// sequence model + +void TIndMach012Obj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + +/* + The usual technique is to create a new property editing string + based on the present values of properties. Once the string is + created, it is pushed into the Parser and the Edit routine for this + class is invoked. + + Thus, the positive sequence model is created in memory. Do a + "Save Circuit" command to save the model that is created. Some + editing of the resulting scripts will likely be required. Not all + elements have an obvious positive sequence equivalent. +*/ + + + // example from Generator class + // Modify as necessary + s = "Phases=1 conn=wye"; // Positive sequence model is 1-phase wye + + /**** + + // Make sure voltage is line-neutral + If (Fnphases>1) or (connection<>0) Then V := GenVars.kVGeneratorBase/SQRT3 + Else V := GenVars.kVGeneratorBase; + + S := S + Format(' kV=%-.5g',[V]); + + // Divide the load by no. phases + If Fnphases>1 Then + Begin + S := S + Format(' kW=%-.5g PF=%-.5g',[kWbase/Fnphases, PFNominal]); + If (PrpSequence^[19]<>0) or (PrpSequence^[20]<>0) Then S := S + Format(' maxkvar=%-.5g minkvar=%-.5g',[kvarmax/Fnphases, kvarmin/Fnphases]); + If PrpSequence^[26]>0 Then S := S + Format(' kva=%-.5g ',[genvars.kvarating/Fnphases]); + If PrpSequence^[27]>0 Then S := S + Format(' MVA=%-.5g ',[genvars.kvarating/1000.0/Fnphases]); + End; + + Parser.CmdString := S; // Push the string into the Parser object + Edit; // Invoke the Edit method for this class + + inherited; // sets the terminal bus references, must do after editing number of phases + + ***/ +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +// Routine for handling Open/Close procedures + +void TIndMach012Obj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + TDSSCktElement::Set_ConductorClosed(Index, ActorID, Value); + if(Value) + IndMach012SwitchOpen = false; + else + IndMach012SwitchOpen = true; +} + + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::set_Localslip(double Value) +{ + + auto Sign = [&](double X) -> double + { + double result = 0.0; + if(X < 0.0) + result = -1.0; + else + result = 1.0; + return result; + }; + S1 = Value; + if(!InDynamics) + { + if(Abs((int) S1) > MaxSlip) + S1 = Sign(S1) * MaxSlip; // Put limits on the slip unless dynamics + } + S2 = 2.0 - S1; +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::Set_Slip(double Value) +{ + set_Localslip(Value); + MachineData.Speed = MachineData.w0 * (-S1); // make motor speed agree +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::InitTraceFile() +{ + AssignFile(Tracefile, get_Name() + "_IndMach012_Trace.CSV"); + Rewrite(Tracefile); + IOResultToException(); + Write(Tracefile, "Time, Iteration, S1, |IS1|, |IS2|, |E1|, |dE1dt|, |E2|, |dE2dt|, |V1|, |V2|, Pshaft, Pin, Speed, dSpeed"); + WriteLn(Tracefile); + CloseFile(Tracefile); +} + +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +void TIndMach012Obj::WriteTraceRecord(int ActorID) +{ + Append(Tracefile); + IOResultToException(); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + Write(Tracefile, Format("%-.6g, %d, %-.6g, ", with0->DynaVars.dblHour * 3600.0, with0->Iteration, S1)); + } + Write(Tracefile, Format("%-.6g, %-.6g, ", cabs(Is1), cabs(Is2))); + Write(Tracefile, Format("%-.6g, %-.6g, %-.6g, %-.6g, ", cabs(E1), cabs(dE1dt), cabs(E2), cabs(dE2dt))); + Write(Tracefile, Format("%-.6g, %-.6g, ", cabs(V1), cabs(V2))); + Write(Tracefile, Format("%-.6g, %-.6g, ", MachineData.Pshaft, Get_Power(1, ActorID).re)); + Write(Tracefile, Format("%-.6g, %-.6g, ", MachineData.Speed, MachineData.dSpeed)); + WriteLn(Tracefile); + CloseFile(Tracefile); +} + +// Initialize any variables here + + + // For Example: 1 + j 1 + + +void IndMach012_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class IndMach012_unit + { + public: + IndMach012_unit() + { + //AssertSystemInitialization(); + IndMach012_initialization(); + } + }; + IndMach012_unit _IndMach012_unit; + +} // namespace IndMach012 + + + + diff --git a/OpenDSSC/PCElements/IndMach012.h b/OpenDSSC/PCElements/IndMach012.h new file mode 100644 index 0000000..4102894 --- /dev/null +++ b/OpenDSSC/PCElements/IndMach012.h @@ -0,0 +1,293 @@ +#ifndef IndMach012H +#define IndMach012H + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Dynamics.h" +#include "GeneratorVars.h" +#include "d2c_structures.h" + + + +namespace IndMach012 +{ + + + +// Symmetrical component Induction Machine model + +// ************ DRAFT Version 2 ****************************** + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + + November 10, 2016 + + Created by + Andres Ovalle + Celso Rocha + +*/ + +/* + Description + + This is a Power Converstion (PC) element. + + PC elements are Load, Generator, Vsource, Isource, etc. PC elements are + used to model devices that convert the power delivered by the Power Delivery (PD) + elements into some other form. PC elements are generally considered to be + in shunt with the power system and are the terminations of the power flow + while PD elements are considered to be in series with the power flow path. + + Both PC and PD elements are represpented by their primitive Y matrices. PC elements + are also used to model the nonlinear devices in the system (see the Load model). They + differ from PD elements in that they have a current injection source in parallel with + the primitive Y matrix. + +*/ + +/*Add other modules accessed by this class*/ // Base class for most DSS objects + // Base class for collection manager for PC elements + // Base class for PC Elements + // Unit for managing complex matrice (for Yprim, etc) + // Complex math functions, type definitions + // definitions of basic DSS arrays + + // common modules used in PC elements + // class for supporting/representing loadshapes + // Class for holding growth shapes + // Definitions for harmonic spectra + // for elements that interact with dynamics variables + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* Collection manager for this class of element */ /* Notes Andres: -- definition of the class -- */ + +class TIndMach012 : public PCClass::TPCClass +{ + friend class TIndMach012Obj; +public: + typedef PCClass::TPCClass inherited; +private: + + /*These private functions are generally helper functions for Edit procedure*/ + + /* A typical function */ + void SetNcondsForConnection(); +protected: + void DefineProperties(); // Define the property names and help strings + virtual int MakeLike(const String OtherIndMach012Name); // copy properties of another similar object +public: + TIndMach012(); + virtual ~TIndMach012(); + virtual int Edit(int ActorID); // Definition of the main property editing function + virtual int Init(int Handle, int ActorID); // Initialize by handle (index), if necessary + virtual int NewObject(const String ObjName); // This function is called by the DSS New command + + /*any public functions that might be called from other elements*/ +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* Class definition for this class of element*/ +typedef Ucomplex::complex TSymCompArray[3]; + //pTDynamicsRec = ^TDynamicsRec; + //pTGeneratorVars = ^TGeneratorVars; + +class TIndMach012Obj : public PCElement::TPCElement +{ + friend class TIndMach012; +public: + typedef PCElement::TPCElement inherited; +private: + + /*Private variables of this class*/ + int Connection; /*0 = line-neutral; 1=Delta*/ + Ucomplex::complex Yeq; // Y at nominal voltage + // Pos seq slip + // limit for slip to prevent solution blowing up + // for power flow + + /*Dynamics variables*/ // Rotor time constant + double puRs; + double puXs; + double puRr; + double puXr; + double puXm; + double S1; + double S2; + double MaxSlip; + double dSdP; + double Xopen; + double Xp; + double T0p; + bool InDynamics; // Keep the last computed voltages and currents + Ucomplex::complex Zs; + Ucomplex::complex ZM; + Ucomplex::complex Zr; + Ucomplex::complex Is1; + Ucomplex::complex Ir1; + Ucomplex::complex V1; + Ucomplex::complex Is2; + Ucomplex::complex Ir2; + Ucomplex::complex V2; + + /*Complex variables for dynamics*/ + Ucomplex::complex E1; + Ucomplex::complex E1n; + Ucomplex::complex dE1dt; + Ucomplex::complex dE1dtn; + Ucomplex::complex E2; + Ucomplex::complex E2n; + Ucomplex::complex dE2dt; + Ucomplex::complex dE2dtn; + Ucomplex::complex Zsp; + bool FirstIteration; + bool FixedSlip; + double RandomMult; + int IndMach012SolutionCount; + bool IndMach012SwitchOpen; + + // Debugging + System::TTextRec Tracefile; + bool DebugTrace; + GeneratorVars::TGeneratorVars MachineData; // Use generator variable structure + + // Andres: NEW variables from generator + bool MachineON; + Ucomplex::complex ShapeFactor; + bool ShapeIsActual; + // Andres: end NEW variables from generator + double VBase; + double kWBase; + void InterpretOption(String s); + void set_Localslip(double Value); + void Get_PFlowModelCurrent(const Ucomplex::complex& V, double s, Ucomplex::complex& Istator, Ucomplex::complex& Irotor); + void Get_DynamicModelCurrent(); + void Set_Slip(double Value); + double GetRotorLosses(); + double GetStatorLosses(); + double Compute_dSdP(); + void Randomize(int Opt); + void InitModel(const TSymCompArray& V012, const TSymCompArray& I012); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void CalcIndMach012ModelContribution(int ActorID); + void CalcInjCurrentArray(int ActorID); + void DoIndMach012Model(int ActorID); + void CalcModel(Ucomplex::pComplexArray V, Ucomplex::pComplexArray i, int ActorID); + + // Andres: NEW procedures from generator + void CalcDailyMult(double hr); + void CalcYearlyMult(double hr); + void CalcDutyMult(double hr); + // Andres: NEW procedures from generator + void InitTraceFile(); + void WriteTraceRecord(int ActorID); + double Get_PresentkV(); + void Set_PresentkV(double Value); + void SetPowerkW(double PkW); +protected: + + /*A couple of virtual procedures you can override*/ + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); + void DoDynamicMode(int ActorID); + void DoHarmonicMode(int ActorID); +public: + + /*Variables and functions accessed by DSS and other objects*/ + + // Andres: new variables from generator + String DailyDispShape; // Daily (24 HR) Generator shape + LoadShape::TLoadShapeObj* DailyDispShapeObj; // Daily Generator Shape for this load + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this generator + String DutyShape; // + String YearlyShape; // ='fixed' means no variation on all the time + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this Generator + // Andres: New variables from generator + TIndMach012Obj(DSSClass::TDSSClass* ParClass, const String IndMach012ObjName); + virtual ~TIndMach012Obj(); + virtual void RecalcElementData(int ActorID); // Generally called after Edit is complete to recompute variables + virtual void CalcYPrim(int ActorID); // Calculate Primitive Y matrix + void Integrate(int ActorID); + void CalcDynamic(TSymCompArray V012, TSymCompArray I012); + void CalcPFlow(TSymCompArray V012, TSymCompArray I012); + void SetNominalPower(int ActorID); + + // Injection current management functions (unique to PC Elements) + // This is how the DSS represents elements with nonlinear characteristics + // Inj currents are the difference between the desired total terminal currents and the + // currents that result from the linear admittance matrix of the element + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + + // State variable management functions, if any + // You can omit these if your PC element model is not using these + // Default behavior is to basically do nothing + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model, if possible + + // Functions required for managing values of properties + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + double get_S1(); + + //Property Variable[i:Integer]:Double Read Get_Variable Write Set_Variable; + + /*Put any class properties here*/ + /*Use properties when some method must be executed when a value is set or retrieved*/ + + /* Example (from Load) + Property ConnectedkVA :Double Read FConnectedkVA Write Set_ConnectedkVA; + */ + TIndMach012Obj(DSSClass::TDSSClass* ParClass); + TIndMach012Obj(String ClassName); + TIndMach012Obj(); +}; +extern TIndMach012* IndMach012Class; +extern TIndMach012Obj* ActiveIndMach012Obj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace IndMach012 + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace IndMach012; +#endif + +#endif // IndMach012H + + + + diff --git a/OpenDSSC/PCElements/Isource.cpp b/OpenDSSC/PCElements/Isource.cpp new file mode 100644 index 0000000..20bd06d --- /dev/null +++ b/OpenDSSC/PCElements/Isource.cpp @@ -0,0 +1,759 @@ + +#pragma hdrstop + +#include "Isource.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Command.h" +#include "Dynamics.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace ISource +{ + +TIsourceObj::TIsourceObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TIsourceObj::TIsourceObj(String ClassName) : inherited(ClassName) {} +TIsourceObj::TIsourceObj() {} + + +TIsourceObj* ActiveIsourceObj = nullptr; +int NumPropsThisClass = 0; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TIsource::TIsource() +{ + ; + Class_Name = "Isource"; + DSSClassType = SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + IsourceClass[ActiveActor] = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TIsource::~TIsource() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TIsource::DefineProperties() +{ + NumPropsThisClass = 11; + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "amps"; + PropertyName[3 - 1] = "angle"; + PropertyName[4 - 1] = "frequency"; + PropertyName[5 - 1] = "phases"; + PropertyName[6 - 1] = "scantype"; + PropertyName[7 - 1] = "sequence"; + PropertyName[8 - 1] = "Yearly"; + PropertyName[9 - 1] = "Daily"; + PropertyName[10 - 1] = "Duty"; + PropertyName[11 - 1] = "Bus2"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of bus to which source is connected.") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3"; + PropertyHelp[2 - 1] = "Magnitude of current source, each phase, in Amps."; + PropertyHelp[3 - 1] = String("Phase angle in degrees of first phase: e.g.,Angle=10.3.") + CRLF + + "Phase shift between phases is assumed 120 degrees when " + + "number of phases <= 3"; + PropertyHelp[4 - 1] = "Source frequency. Defaults to circuit fundamental frequency."; + PropertyHelp[5 - 1] = "Number of phases. Defaults to 3. For 3 or less, phase shift is 120 degrees."; + PropertyHelp[6 - 1] = "{pos*| zero | none} Maintain specified sequence for harmonic solution. Default is positive sequence. " + "Otherwise, angle between phases rotates with harmonic."; + PropertyHelp[7 - 1] = "{pos*| neg | zero} Set the phase angles for the specified symmetrical component sequence for non-harmonic solution modes. " + "Default is positive sequence. "; + PropertyHelp[8 - 1] = String("LOADSHAPE object to use for the per-unit current for YEARLY-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual Amp.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Is set to the Daily load shape when Daily is defined. The daily load shape is repeated in this case. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[9 - 1] = String("LOADSHAPE object to use for the per-unit current for DAILY-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual A.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Sets Yearly curve if it is not already defined. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[10 - 1] = String("LOADSHAPE object to use for the per-unit current for DUTYCYCLE-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual A.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Defaults to Daily load shape when Daily is defined. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[11 - 1] = String("Name of bus to which 2nd terminal is connected.") + CRLF + + "bus2=busname" + + CRLF + + "bus2=busname.1.2.3" + + CRLF + + CRLF + + "Default is Bus1.0.0.0 (grounded-wye connection)"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1] = "Harmonic spectrum assumed for this source. Default is \"default\"."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TIsource::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to Isource class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TIsourceObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TIsource::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveIsourceObj = (TIsourceObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveIsourceObj); + result = 0; + /*# with ActiveIsourceObj do */ + { + auto with0 = ActiveIsourceObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 330); + break; + case 1: + IsourceSetBus1(Param); + break; + case 2: + with0->Amps = Parser[ActorID]->MakeDouble_(); + break; + case 3: + with0->Angle = Parser[ActorID]->MakeDouble_(); + break; // Ang + case 4: + with0->SrcFrequency = Parser[ActorID]->MakeDouble_(); + break; // freq + case 5: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + switch(with0->Fnphases) + { + case 1: + with0->FphaseShift = 0.0; + break; + case 2: case 3: + with0->FphaseShift = 120.0; + break; // higher order systems + default: + with0->FphaseShift = 360.0 / with0->Fnphases; + break; + } + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + } + break; + case 6: + switch(UpperCase(Param)[0]) + { + case L'P': + with0->ScanType = 1; + break; + case L'Z': + with0->ScanType = 0; + break; + case L'N': + with0->ScanType = -1; + break; + default: + DoSimpleMsg(String("Unknown Scan Type for \"") + Class_Name + + "." + + with0->get_Name() + + "\": " + + Param, 331); + break; + } + break; + case 7: + switch(UpperCase(Param)[0]) + { + case L'P': + with0->SequenceType = 1; + break; + case L'Z': + with0->SequenceType = 0; + break; + case L'N': + with0->SequenceType = -1; + break; + default: + DoSimpleMsg(String("Unknown Sequence Type for \"") + Class_Name + + "." + + with0->get_Name() + + "\": " + + Param, 331); + break; + } + break; + case 8: + with0->YearlyShape = Param; + break; + case 9: + with0->DailyShape = Param; + break; + case 10: + with0->DutyShape = Param; + break; + case 11: + with0->SetBus(2, Param); + break; + default: + inherited::ClassEdit(ActiveIsourceObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 8: + /*Set shape objects; returns nil if not valid*/ + /*Sets the kW and kvar properties to match the peak kW demand from the Loadshape*/ + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + break; + case 9: + { + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + /*If Yearly load shape is not yet defined, make it the same as Daily*/ + if(with0->YearlyShapeObj == nullptr) + with0->YearlyShapeObj = with0->DailyShapeObj; + } + break; + case 10: + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TIsource::MakeLike(const String OtherSource) +{ + int result = 0; + TIsourceObj* OtherIsource = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherIsource = ((TIsourceObj*) Find(OtherSource)); + if(OtherIsource != nullptr) + /*# with ActiveIsourceObj do */ + { + auto with0 = ActiveIsourceObj; + int stop = 0; + if(with0->Fnphases != OtherIsource->Fnphases) + { + with0->Set_NPhases(OtherIsource->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->Amps = OtherIsource->Amps; + with0->Angle = OtherIsource->Angle; + with0->SrcFrequency = OtherIsource->SrcFrequency; + with0->ScanType = OtherIsource->ScanType; + with0->SequenceType = OtherIsource->SequenceType; + with0->ShapeIsActual = OtherIsource->ShapeIsActual; + with0->DailyShape = OtherIsource->DailyShape; + with0->DailyShapeObj = OtherIsource->DailyShapeObj; + with0->DutyShape = OtherIsource->DutyShape; + with0->DutyShapeObj = OtherIsource->DutyShapeObj; + with0->YearlyShape = OtherIsource->YearlyShape; + with0->YearlyShapeObj = OtherIsource->YearlyShapeObj; + with0->Bus2Defined = OtherIsource->Bus2Defined; + ClassMakeLike(OtherIsource); // set spectrum, base frequency + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherIsource->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Isource MakeLike: \"") + OtherSource + + "\" Not Found.", 332); + return result; +} + +//---------------------------------------------------------------------------- + +int TIsource::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TIsource.Init", -1); + result = 0; + return result; +} + +void TIsource::IsourceSetBus1(const String s) +{ + String S2 = ""; + int i = 0, + dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveIsourceObj do */ + { + auto with0 = ActiveIsourceObj; + with0->SetBus(1, s); + if(!with0->Bus2Defined) // Default Bus2 to zero node of Bus1. (Grounded-Y connection) + + // Strip node designations from S + { + int stop = 0; + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); // copy up to Dot + for(stop = with0->Fnphases, i = 1; i <= stop; i++) + { + S2 = S2 + ".0"; + } // append series of ".0"'s + with0->SetBus(2, S2); // default setting for Bus2 + } + } +} + +//---------------------------------------------------------------------------- + +TIsourceObj::TIsourceObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + FphaseShift(120.0), + ShapeIsActual(false), + Bus2Defined(false), + Amps(0.0), + Angle(0.0), + SrcFrequency(0.0), + ScanType(0), + SequenceType(0), + PerUnit(0.0), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr), + YearlyShapeObj(nullptr) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + Set_NPhases(3); + Fnconds = 3; + Set_NTerms(2); + Amps = 0.0; + Angle = 0.0; + PerUnit = 1.0; // for future use if pu property added, + SrcFrequency = BaseFrequency; + ScanType = 1; // Pos Sequence + SequenceType = 1; + Bus2Defined = false; + InitPropertyValues(0); + YearlyShape = ""; + YearlyShapeObj = nullptr; // IF YearlyShapeobj = nil THEN the Vsource alway stays nominal + DailyShape = ""; + DailyShapeObj = nullptr; // IF DaillyShapeobj = nil THEN the Vsource alway stays nominal + DutyShape = ""; + DutyShapeObj = nullptr; // IF DutyShapeobj = nil THEN the Vsource alway stays nominal + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + + +//---------------------------------------------------------------------------- + +TIsourceObj::~TIsourceObj() +{ + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + +void TIsourceObj::RecalcElementData(int ActorID) +{ + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + { + DoSimpleMsg(String("Spectrum Object \"") + Spectrum + + "\" for Device Isource." + + get_Name() + + " Not Found.", 333); + } + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); +} + +//---------------------------------------------------------------------------- + +void TIsourceObj::CalcYPrim(int ActorID) +{ + + + // Build only YPrim Series + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + + + /*Yprim = 0 for Ideal Current Source; just leave it zeroed*/ + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +complex TIsourceObj::GetBaseCurr(int ActorID) +{ + complex result = {}; + double SrcHarmonic = 0.0; + double NAmps = 0.0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsHarmonicModel) + /*Get first Phase Current*/ + { + SrcHarmonic = with0->get_FFrequency() / SrcFrequency; + result = cmulreal(SpectrumObj->GetMult(SrcHarmonic), Amps); // Base current for this harmonic + RotatePhasorDeg(result, SrcHarmonic, Angle); + } + else + { + switch(with0->Get_SolMode()) + { + case DAILYMODE: + /*Uses same logic as LOAD*/ + { + CalcDailyMult(with0->DynaVars.dblHour); + } + break; + case EMPDAILYMODE: + { + CalcDailyMult(with0->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + CalcYearlyMult(with0->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + CalcDutyMult(with0->DynaVars.dblHour); + } + break; + // This mode allows use of one class of load shape in DYNAMIC mode + case DYNAMICMODE: + { + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with0->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with0->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with0->DynaVars.dblHour); + break; + default: + ShapeFactor = cmplx(1.0, 0.0); // default to 1 + j0 if not known + break; + } + } + break; + default: + ; + break; + } + NAmps = Amps; + if((with0->Get_SolMode() == DAILYMODE) || (with0->Get_SolMode() == YEARLYMODE) || (with0->Get_SolMode() == DUTYCYCLE) || (with0->Get_SolMode() == DYNAMICMODE)) /*If a loadshape mode simulation*/ + NAmps = Amps * ShapeFactor.re; + if(Abs((int) (with0->get_FFrequency() - SrcFrequency)) < EPSILON2) + result = pdegtocomplex(NAmps, Angle); + else + result = CZero; + } + } + } + catch(...) + { + DoSimpleMsg(String("Error computing current for Isource.") + get_Name() + + ". Check specification. Aborting.", 334); + if(In_Redirect) + Redirect_Abort = true; + } + return result; +} + +/*Sum Currents directly into solution array*/ + +int TIsourceObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + result = inherited::InjCurrents(ActorID); // Adds into system array + return result; +} + +/*Total currents into a device*/ + +void TIsourceObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + int stop = 0; + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = cnegate((ComplexBuffer)[i - 1]); + } + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Isource Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element?", 335); + } +} + +/*Fill Up an array of injection currents*/ + +void TIsourceObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + complex BaseCurr = {}; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + BaseCurr = GetBaseCurr(ActorID); // this func applies spectrum if needed + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = BaseCurr; + (Curr)[i + Fnphases - 1] = cnegate(BaseCurr); // 2nd Terminal + if(i < Fnphases) + { + if(with0->IsHarmonicModel) + switch(ScanType) + { + case 1: + RotatePhasorDeg(BaseCurr, 1.0, -FphaseShift); + break; // maintain positive sequence for isource + case 0: + ; + break; // Do not rotate for zero sequence + default: // rotate by frequency + /*Harmonic 1 will be pos; 2 is neg; 3 is zero, and so on.*/ + RotatePhasorDeg(BaseCurr, with0->Harmonic, -FphaseShift); + break; + } + else + switch(SequenceType) + { + case -1: + RotatePhasorDeg(BaseCurr, 1.0, FphaseShift); + break; // Neg seq + case 0: + ; + break; // Do not rotate for zero sequence + default: + RotatePhasorDeg(BaseCurr, 1.0, -FphaseShift); // Maintain pos seq + break; + } + } + } + } +} + +void TIsourceObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + WriteLn(f); + } +} + +void TIsourceObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,"0"); + Set_PropertyValue(3,"0"); + Set_PropertyValue(4,Format("%-.6g", SrcFrequency)); + Set_PropertyValue(5,"3"); + Set_PropertyValue(6,"pos"); + Set_PropertyValue(7,"pos"); + Set_PropertyValue(8,""); + Set_PropertyValue(9,""); + Set_PropertyValue(10,""); + Set_PropertyValue(11,""); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TIsourceObj::MakePosSequence(int ActorID) +{ + if(Fnphases > 1) + { + Parser[ActorID]->SetCmdString("phases=1"); + Edit(ActorID); + } + TDSSCktElement::MakePosSequence(ActorID); +} + +void TIsourceObj::CalcDailyMult(double hr) +{ + if(DailyShapeObj != nullptr) + { + ShapeFactor = DailyShapeObj->GetMult(hr); + ShapeIsActual = DailyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(PerUnit, 0.0); // CDOUBLEONE; // Default to no daily variation +} + +void TIsourceObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult IF no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TIsourceObj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(PerUnit, 0.0); // CDOUBLEONE; // Defaults to no variation +} + + + + +} // namespace ISource + + + + diff --git a/OpenDSSC/PCElements/Isource.h b/OpenDSSC/PCElements/Isource.h new file mode 100644 index 0000000..9784733 --- /dev/null +++ b/OpenDSSC/PCElements/Isource.h @@ -0,0 +1,121 @@ +#ifndef ISourceH +#define ISourceH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Spectrum.h" +#include "LoadShape.h" +#include "d2c_structures.h" + + + +namespace ISource +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Ideal current source + + Stick'em on wherever you want as many as you want + + ISource maintains a positive sequence for harmonic scans. If you want zero sequence, + use three single-phase ISource. + + + 10-25-00 Created from Vsource + 5-17-02 Moved spectrum to base class + 2-19-03 Added Phaseshift variable for n-phase elements + +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TIsource : public PCClass::TPCClass +{ + friend class TIsourceObj; +public: + typedef PCClass::TPCClass inherited; +private: + void IsourceSetBus1(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); +public: + TIsource(); + virtual ~TIsource(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TIsourceObj : public PCElement::TPCElement +{ + friend class TIsource; +public: + typedef PCElement::TPCElement inherited; +private: + double FphaseShift; + bool ShapeIsActual; + Ucomplex::complex ShapeFactor; + bool Bus2Defined; + Ucomplex::complex GetBaseCurr(int ActorID); + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); + void CalcYearlyMult(double hr); +public: + double Amps; + double Angle; + double SrcFrequency; + int ScanType; + int SequenceType; + double PerUnit; + String DailyShape; // Daily (24 HR) load shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily load Shape FOR this load + String DutyShape; // Duty cycle load shape FOR changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this load + String YearlyShape; // ='fixed' means no variation exempt from variation + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this load + TIsourceObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TIsourceObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TIsourceObj(DSSClass::TDSSClass* ParClass); + TIsourceObj(String ClassName); + TIsourceObj(); +}; +extern TIsourceObj* ActiveIsourceObj; + /*IsourceClass:TISource;*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace ISource + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ISource; +#endif + +#endif // ISourceH + + + + diff --git a/OpenDSSC/PCElements/Load.cpp b/OpenDSSC/PCElements/Load.cpp new file mode 100644 index 0000000..0b255ac --- /dev/null +++ b/OpenDSSC/PCElements/Load.cpp @@ -0,0 +1,2886 @@ + + +#pragma hdrstop + +#include "Load.h" + +#include "DSSGlobals.h" +#include // malloc + + +using namespace std; + + +namespace Load +{ + +TLoadObj::TLoadObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TLoadObj::TLoadObj(String ClassName) : inherited(ClassName) {} +TLoadObj::TLoadObj() {} + + +TLoadObj* ActiveLoadObj = nullptr; +const int NumPropsThisClass = 38; +complex CDoubleOne = {}; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure FOR all Line objects + +TLoad::TLoad() +{ + ; + Class_Name = "Load"; + DSSClassType = DSSClassType + LOAD_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLoad::~TLoad() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoad::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "phases"; + PropertyName[2 - 1] = "bus1"; + PropertyName[3 - 1] = "kV"; // + PropertyName[4 - 1] = "kW"; + PropertyName[5 - 1] = "pf"; + PropertyName[6 - 1] = "model"; + PropertyName[7 - 1] = "yearly"; + PropertyName[8 - 1] = "daily"; + PropertyName[9 - 1] = "duty"; + PropertyName[10 - 1] = "growth"; + PropertyName[11 - 1] = "conn"; + PropertyName[12 - 1] = "kvar"; + PropertyName[13 - 1] = "Rneut"; // IF entered -, assume open + PropertyName[14 - 1] = "Xneut"; + PropertyName[15 - 1] = "status"; // fixed or variable + PropertyName[16 - 1] = "class"; // integer + PropertyName[17 - 1] = "Vminpu"; // Min pu voltage for which model applies + PropertyName[18 - 1] = "Vmaxpu"; // Max pu voltage for which model applies + PropertyName[19 - 1] = "Vminnorm"; // Min pu voltage normal load + PropertyName[20 - 1] = "Vminemerg"; // Min pu voltage emergency rating + PropertyName[21 - 1] = "xfkVA"; // Service transformer rated kVA + PropertyName[22 - 1] = "allocationfactor"; // allocation factor for xfkVA + PropertyName[23 - 1] = "kVA"; // specify load in kVA and PF + PropertyName[24 - 1] = "%mean"; // per cent default mean + PropertyName[25 - 1] = "%stddev"; // per cent default standard deviation + PropertyName[26 - 1] = "CVRwatts"; // Percent watts reduction per 1% reduction in voltage from nominal + PropertyName[27 - 1] = "CVRvars"; // Percent vars reduction per 1% reduction in voltage from nominal + PropertyName[28 - 1] = "kwh"; // kwh billing + PropertyName[29 - 1] = "kwhdays"; // kwh billing period (24-hr days) + PropertyName[30 - 1] = "Cfactor"; // multiplier from kWh avg to peak kW + PropertyName[31 - 1] = "CVRcurve"; // name of curve to use for yearly CVR simulations + PropertyName[32 - 1] = "NumCust"; // Number of customers, this load + PropertyName[33 - 1] = "ZIPV"; // array of 7 coefficients + PropertyName[34 - 1] = "%SeriesRL"; // pct of Load that is series R-L + PropertyName[35 - 1] = "RelWeight"; // Weighting factor for reliability + PropertyName[36 - 1] = "Vlowpu"; // Below this value resort to constant Z model = Yeq + PropertyName[37 - 1] = "puXharm"; // pu Reactance for Harmonics, if specifies + PropertyName[38 - 1] = "XRharm"; // X/R at fundamental for series R-L model for hamonics +/* + Typical Motor Parameters for motor + Xpu = 0.20 + X/r typically 3-6 for normal motors; higher for high-eff motors +*/ + + // define Property help values + PropertyHelp[1 - 1] = "Number of Phases, this load. Load is evenly divided among phases."; + PropertyHelp[2 - 1] = "Bus to which the load is connected. May include specific node specification."; + PropertyHelp[3 - 1] = "Nominal rated (1.0 per unit) voltage, kV, for load. For 2- and 3-phase loads, specify phase-phase kV. " + "Otherwise, specify actual kV across each branch of the load. " + "If wye (star), specify phase-neutral kV. " + "If delta or phase-phase connected, specify phase-phase kV."; // line-neutral voltage + PropertyHelp[4 - 1] = String("Total base kW for the load. Normally, you would enter the maximum kW for the load for the first year " "and allow it to be adjusted by the load shapes, growth shapes, and global load multiplier.") + CRLF + + CRLF + + "Legal ways to define base load:" + + CRLF + + "kW, PF" + + CRLF + + "kW, kvar" + + CRLF + + "kVA, PF" + + CRLF + + "XFKVA * Allocationfactor, PF" + + CRLF + + "kWh/(kWhdays*24) * Cfactor, PF"; + PropertyHelp[5 - 1] = "Load power factor. Enter negative for leading powerfactor (when kW and kvar have opposite signs.)"; + PropertyHelp[6 - 1] = String("Integer code for the model to use for load variation with voltage. " "Valid values are:") + CRLF + + CRLF + + "1:Standard constant P+jQ load. (Default)" + + CRLF + + "2:Constant impedance load. " + + CRLF + + "3:Const P, Quadratic Q (like a motor)." + + CRLF + + "4:Nominal Linear P, Quadratic Q (feeder mix). Use this with CVRfactor." + + CRLF + + "5:Constant Current Magnitude" + + CRLF + + "6:Const P, Fixed Q" + + CRLF + + "7:Const P, Fixed Impedance Q" + + CRLF + + "8:ZIPV (7 values)" + + CRLF + + CRLF + + "For Types 6 and 7, only the P is modified by load multipliers."; + PropertyHelp[7 - 1] = "LOADSHAPE object to use for yearly simulations. Must be previously defined " + "as a Loadshape object. Is set to the Daily load shape " + " when Daily is defined. The daily load shape is repeated in this case. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "The default is no variation."; + PropertyHelp[8 - 1] = "LOADSHAPE object to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "Default is no variation (constant) if not defined. " + "Side effect: Sets Yearly load shape if not already defined."; + PropertyHelp[9 - 1] = "LOADSHAPE object to use for duty cycle simulations. Must be previously defined " + "as a Loadshape object. Typically would have time intervals less than 1 hr. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat." + "Set to NONE to reset to no loadahape. " + "Set Status=Fixed to ignore Loadshape designation. " + " Defaults to Daily curve If not specified."; + PropertyHelp[10 - 1] = "Characteristic to use for growth factors by years. Must be previously defined " + "as a Growthshape object. Defaults to circuit default growth factor (see Set Growth command)."; + PropertyHelp[11 - 1] = "={wye or LN | delta or LL}. Default is wye."; + PropertyHelp[12 - 1] = "Specify the base kvar for specifying load as kW & kvar. Assumes kW has been already defined. Alternative to specifying the power factor. Side effect: " + " the power factor and kVA is altered to agree."; + PropertyHelp[13 - 1] = "Default is -1. Neutral resistance of wye (star)-connected load in actual ohms. " + "If entered as a negative value, the neutral can be open, or floating, or it can be connected to " + "node 0 (ground), which is the usual default. " + "If >=0 be sure to explicitly specify the node connection for the neutral, or last, conductor. " + "Otherwise, the neutral impedance will be shorted to ground."; + PropertyHelp[14 - 1] = "Neutral reactance of wye(star)-connected load in actual ohms. May be + or -."; + PropertyHelp[15 - 1] = "={Variable | Fixed | Exempt}. Default is variable. If Fixed, no load multipliers apply; however, growth " + "multipliers do apply. All multipliers apply to Variable loads. Exempt loads are not " + "modified by the global load multiplier, such as in load duration curves, etc. Daily multipliers " + "do apply, so setting this property to Exempt is a good way to represent industrial load that stays the same" + " day-after-day for the period study."; // fixed or variable + PropertyHelp[16 - 1] = "An arbitrary integer number representing the class of load so that load values may " + "be segregated by load value. Default is 1; not used internally."; + PropertyHelp[17 - 1] = "Default = 0.95. Minimum per unit voltage for which the MODEL is assumed to apply. Lower end of normal voltage range." + "Below this value, the load model reverts to a constant impedance model that matches the model at the transition voltage. " + "See also \"Vlowpu\" which causes the model to match Model=2 below the transition voltage."; + PropertyHelp[18 - 1] = "Default = 1.05. Maximum per unit voltage for which the MODEL is assumed to apply. " + "Above this value, the load model reverts to a constant impedance model."; + PropertyHelp[19 - 1] = "Minimum per unit voltage for load EEN evaluations, Normal limit. Default = 0, which defaults to system \"vminnorm\" " + "property (see Set Command under Executive). If this property is specified, it ALWAYS " + "overrides the system specification. This allows you to have different criteria for different loads. " + "Set to zero to revert to the default system value."; + PropertyHelp[20 - 1] = "Minimum per unit voltage for load UE evaluations, Emergency limit. Default = 0, which defaults to system \"vminemerg\" " + "property (see Set Command under Executive). If this property is specified, it ALWAYS " + "overrides the system specification. This allows you to have different criteria for different loads. " + "Set to zero to revert to the default system value."; + PropertyHelp[21 - 1] = "Default = 0.0. Rated kVA of service transformer for allocating loads based on connected kVA " + "at a bus. Side effect: kW, PF, and kvar are modified. See help on kVA."; + PropertyHelp[22 - 1] = "Default = 0.5. Allocation factor for allocating loads based on connected kVA " + "at a bus. Side effect: kW, PF, and kvar are modified by multiplying this factor times the XFKVA (if > 0)."; + PropertyHelp[23 - 1] = String("Specify base Load in kVA (and power factor)") + CRLF + + CRLF + + "Legal ways to define base load:" + + CRLF + + "kW, PF" + + CRLF + + "kW, kvar" + + CRLF + + "kVA, PF" + + CRLF + + "XFKVA * Allocationfactor, PF" + + CRLF + + "kWh/(kWhdays*24) * Cfactor, PF"; + PropertyHelp[24 - 1] = "Percent mean value for load to use for monte carlo studies if no loadshape is assigned to this load. Default is 50."; + PropertyHelp[25 - 1] = "Percent Std deviation value for load to use for monte carlo studies if no loadshape is assigned to this load. Default is 10."; + PropertyHelp[26 - 1] = String("Percent reduction in active power (watts) per 1% reduction in voltage from 100% rated. Default=1. ") + CRLF + + " Typical values range from 0.4 to 0.8. Applies to Model=4 only." + + CRLF + + " Intended to represent conservation voltage reduction or voltage optimization measures."; + PropertyHelp[27 - 1] = String("Percent reduction in reactive power (vars) per 1% reduction in voltage from 100% rated. Default=2. ") + CRLF + + " Typical values range from 2 to 3. Applies to Model=4 only." + + CRLF + + " Intended to represent conservation voltage reduction or voltage optimization measures."; + PropertyHelp[28 - 1] = "kWh billed for this period. Default is 0. See help on kVA and Cfactor and kWhDays."; + PropertyHelp[29 - 1] = "Length of kWh billing period in days (24 hr days). Default is 30. Average demand is computed using this value."; // kwh billing period (24-hr days) + PropertyHelp[30 - 1] = "Factor relating average kW to peak kW. Default is 4.0. See kWh and kWhdays. See kVA."; // multiplier from kWh avg to peak kW + PropertyHelp[31 - 1] = "Default is NONE. Curve describing both watt and var factors as a function of time. " + "Refers to a LoadShape object with both Mult and Qmult defined. " + "Define a Loadshape to agree with yearly or daily curve according to the type of analysis being done. " + "If NONE, the CVRwatts and CVRvars factors are used and assumed constant."; + PropertyHelp[32 - 1] = "Number of customers, this load. Default is 1."; + PropertyHelp[33 - 1] = String("Array of 7 coefficients:") + CRLF + + CRLF + + " Get_First() 3 are ZIP weighting factors for real power (should sum to 1)" + + CRLF + + " Next 3 are ZIP weighting factors for reactive power (should sum to 1)" + + CRLF + + " Last 1 is cut-off voltage in p.u. of base kV; load is 0 below this cut-off" + + CRLF + + " No defaults; all coefficients must be specified if using model=8."; + PropertyHelp[34 - 1] = "Percent of load that is series R-L for Harmonic studies. Default is 50. Remainder is assumed to be parallel R and L. " + "This can have a significant impact on the amount of damping observed in Harmonics solutions."; + PropertyHelp[35 - 1] = String("Relative weighting factor for reliability calcs. Default = 1. Used to designate high priority loads such as hospitals, etc. ") + CRLF + + CRLF + + "Is multiplied by number of customers and load kW during reliability calcs."; + PropertyHelp[36 - 1] = "Default = 0.50. Per unit voltage at which the model switches to same as constant Z model (model=2). " + "This allows more consistent convergence at very low voltaes due to opening switches or solving for fault situations."; + PropertyHelp[37 - 1] = String("Special reactance, pu (based on kVA, kV properties), for the series impedance branch in the load model for HARMONICS analysis. " "Generally used to represent motor load blocked rotor reactance. " "If not specified (that is, set =0, the default value), the series branch is computed from the percentage of the " "nominal load at fundamental frequency specified by the %SERIESRL property. ") + CRLF + + CRLF + + "Applies to load model in HARMONICS mode only." + + CRLF + + CRLF + + "A typical value would be approximately 0.20 pu based on kVA * %SeriesRL / 100.0."; + PropertyHelp[38 - 1] = "X/R ratio of the special harmonics mode reactance specified by the puXHARM property at fundamental frequency. Default is 6. "; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + PropertyHelp[NumPropsThisClass + 1] = "Name of harmonic current spectrum for this load. Default is \"defaultload\", which is defined when the DSS starts."; +} +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoad::NewObject(const String ObjName) +{ + int result = 0; + // Make a new load object and add it to Load class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TLoadObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLoad::SetNcondsForConnection() +{ + /*# with ActiveLoadObj do */ + { + auto with0 = ActiveLoadObj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases + 1); + break; + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); + break; + } + break; /*nada*/ + default: + ; + break; + } + } +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FAllocationFactor() +{ + return FAllocationFactor; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FCFactor() +{ + return FCFactor; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FkWhDays() +{ + return FkWhDays; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FkWh() +{ + return FkWh; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FConnectedkVA() +{ + return FConnectedkVA; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FkVAAllocationFactor() +{ + return FkVAAllocationFactor; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FpuMean() +{ + return FpuMean; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FpuStdDev() +{ + return FpuStdDev; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FCVRwattFactor() +{ + return FCVRwattFactor; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_FCVRvarFactor() +{ + return FCVRvarFactor; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_Vmaxpu() +{ + return Vmaxpu; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_VminEmerg() +{ + return VminEmerg; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_VminNormal() +{ + return VminNormal; +} + +//--------------------------------------------------------------------------- + +double TLoadObj::get_Vminpu() +{ + return Vminpu; +} + +//--------------------------------------------------------------------------- + +bool TLoadObj::get_ExemptFromLDCurve() +{ + return ExemptFromLDCurve; +} + +//--------------------------------------------------------------------------- + +bool TLoadObj::get_FIXED() +{ + return FIXED; +} + +//--------------------------------------------------------------------------- + +int TLoadObj::get_FnZIPV() +{ + return FnZIPV; +} + +//--------------------------------------------------------------------------- + +bool TLoadObj::get_PFSpecified() +{ + return PFSpecified; +} + +//--------------------------------------------------------------------------- + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts (checks only min number of chars required} +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TLoad::InterpretConnection(const String s) +{ + String TestS; + /*# with ActiveLoadObj do */ + { + auto with0 = ActiveLoadObj; + TestS = LowerCase(s); + switch(TestS[0]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[2]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + SetNcondsForConnection(); + switch(with0->Connection) + { + case 1: + with0->VBase = with0->kVLoadBase * 1000.0; + break; + default: + switch(with0->Fnphases) + { + case 2: case 3: + with0->VBase = with0->kVLoadBase * InvSQRT3x1000; + break; + default: + with0->VBase = with0->kVLoadBase * 1000.0; + break; + } + break; + } + with0->VBase95 = with0->Vminpu * with0->VBase; + with0->VBase105 = with0->Vmaxpu * with0->VBase; + with0->VBaseLow = with0->VLowpu * with0->VBase; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLoad::Edit(int ActorID) +{ + int result = 0, + ParamPointer = 0; + String ParamName = "", + Param = ""; + // continue parsing WITH contents of Parser + ActiveLoadObj = (TLoadObj *) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveLoadObj); + result = 0; + /*# with ActiveLoadObj do */ + { + auto with0 = ActiveLoadObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while((Param.size() > 0)) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 580); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case 3: + with0->kVLoadBase = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->kWBase = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->PFNominal = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->FLoadModel = Parser[ActorID]->MakeInteger_(); + break; + case 7: + with0->YearlyShape = Param; + break; + case 8: + with0->DailyShape = Param; + break; + case 9: + with0->DutyShape = Param; + break; + case 10: + with0->GrowthShape = Param; + break; + case 11: + InterpretConnection(Param); + break; + case 12: + with0->kvarBase = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->Rneut = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->Xneut = Parser[ActorID]->MakeDouble_(); + break; + case 15: + switch(LowerCase(Param)[0]) + { + case L'f': + { + with0->FIXED = true; + with0->ExemptFromLDCurve = false; + } + break; + case L'e': + { + with0->FIXED = false; + with0->ExemptFromLDCurve = true; + } + break; + default: + with0->FIXED = false; + with0->ExemptFromLDCurve = false; + break; + } + break; + case 16: + with0->LoadClass = Parser[ActorID]->MakeInteger_(); + break; + case 17: + with0->Vminpu = Parser[ActorID]->MakeDouble_(); + break; + case 18: + with0->Vmaxpu = Parser[ActorID]->MakeDouble_(); + break; + case 19: + with0->VminNormal = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->VminEmerg = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->Set_ConnectedkVA(Parser[ActorID]->MakeDouble_()); + break; + case 22: + with0->Set_kVAAllocationFactor(Parser[ActorID]->MakeDouble_()); + break; + case 23: + with0->kVABase = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->FpuMean = Parser[ActorID]->MakeDouble_() / 100.0; + break; + case 25: + with0->FpuStdDev = Parser[ActorID]->MakeDouble_() / 100.0; + break; + case 26: + with0->FCVRwattFactor = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->FCVRvarFactor = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->Set_kWh(Parser[ActorID]->MakeDouble_()); + break; + case 29: + with0->Set_kWhDays(Parser[ActorID]->MakeDouble_()); + break; + case 30: + with0->Set_CFactor(Parser[ActorID]->MakeDouble_()); + break; + case 31: + with0->CVRshape = Param; + break; + case 32: + with0->NumCustomers = Parser[ActorID]->MakeInteger_(); + break; + case 33: + { + with0->SetZIPVSize(7); + Parser[ActorID]->ParseAsVector(7, with0->ZIPV); + } + break; + case 34: + with0->puSeriesRL = Parser[ActorID]->MakeDouble_() / 100.0; + break; + case 35: + with0->RelWeighting = Parser[ActorID]->MakeDouble_(); + break; + case 36: + with0->VLowpu = Parser[ActorID]->MakeDouble_(); + break; + case 37: + with0->FpuXHarm = Parser[ActorID]->MakeDouble_(); + break; // 0 means not set + case 38: + with0->FXRHarmRatio = Parser[ActorID]->MakeDouble_(); + break; + // Inherited edits + default: + inherited::ClassEdit(ActiveLoadObj, ParamPointer - NumPropsThisClass); + break; + } + + // << SIDE EFFECTS >> + // keep kvar nominal up to date WITH kW and PF + switch(ParamPointer) + { + case 1: + { + SetNcondsForConnection(); // Force Reallocation of terminal info + with0->UpdateVoltageBases(); + } + break; + case 3: + with0->UpdateVoltageBases(); + break; + case 4: + { + with0->LoadSpecType = 0; + with0->kWref = with0->kWBase; + } + break; + case 5: + { + with0->PFChanged = true; + with0->PFSpecified = true; + } + break; + /*Set shape objects; returns nil if not valid*/ + /*Sets the kW and kvar properties to match the peak kW demand from the Loadshape*/ + case 7: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(ASSIGNED(with0->YearlyShapeObj)) + /*# with YearlyShapeObj do */ + { + auto with1 = with0->YearlyShapeObj; + if(with1->UseActual) + { + with0->kWref = with0->kWBase; + with0->kVARref = with0->kvarBase; + with0->SetkWkvar(with1->MaxP, with1->MaxQ); + } + } + } + break; + case 8: + { + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + if(ASSIGNED(with0->DailyShapeObj)) + /*# with DailyShapeObj do */ + { + auto with2 = with0->DailyShapeObj; + if(with2->UseActual) + with0->SetkWkvar(with2->MaxP, with2->MaxQ); + } + /*If Yearly load shape is not yet defined, make it the same as Daily*/ + if(with0->YearlyShapeObj == nullptr) + with0->YearlyShapeObj = with0->DailyShapeObj; + } + break; + case 9: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(ASSIGNED(with0->DutyShapeObj)) + /*# with DutyShapeObj do */ + { + auto with3 = with0->DutyShapeObj; + if(with3->UseActual) + with0->SetkWkvar(with3->MaxP, with3->MaxQ); + } + } + break; + case 10: + with0->GrowthShapeObj = ((TGrowthShapeObj*) GrowthShapeClass[ActorID]->Find(with0->GrowthShape)); + break; + case 12: + { + with0->LoadSpecType = 1; + with0->PFSpecified = false; + with0->kVARref = with0->kvarBase; + } + break;// kW, kvar + /**** see set_xfkva, etc 21, 22: LoadSpectype := 3; // XFKVA*AllocationFactor, PF */ + case 23: + with0->LoadSpecType = 2; + break; // kVA, PF + /**** see set_kwh, etc 28..30: LoadSpecType := 4; // kWh, days, cfactor, PF */ + case 31: + with0->CVRShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->CVRshape)); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TLoad::MakeLike(const String OtherLoadName) +{ + int result = 0; + TLoadObj* OtherLoad = nullptr; + int i = 0; + result = 0; + /*See IF we can find this line name in the present collection*/ + OtherLoad = ((TLoadObj*) Find(OtherLoadName)); + if(OtherLoad != nullptr) + /*# with ActiveLoadObj do */ + { + auto with0 = ActiveLoadObj; + int stop = 0; + with0->Connection = OtherLoad->Connection; + if(with0->Fnphases != OtherLoad->Fnphases) + { + with0->Set_NPhases(OtherLoad->Fnphases); + SetNcondsForConnection(); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->kVLoadBase = OtherLoad->kVLoadBase; + with0->VBase = OtherLoad->VBase; + with0->VLowpu = OtherLoad->VLowpu; + with0->Vminpu = OtherLoad->Vminpu; + with0->Vmaxpu = OtherLoad->Vmaxpu; + with0->VBaseLow = OtherLoad->VBaseLow; + with0->VBase95 = OtherLoad->VBase95; + with0->VBase105 = OtherLoad->VBase105; + with0->kWBase = OtherLoad->kWBase; + with0->kVABase = OtherLoad->kVABase; + with0->kvarBase = OtherLoad->kvarBase; + with0->LoadSpecType = OtherLoad->LoadSpecType; + with0->WNominal = OtherLoad->WNominal; + with0->PFNominal = OtherLoad->PFNominal; + with0->varNominal = OtherLoad->varNominal; + with0->Rneut = OtherLoad->Rneut; + with0->Xneut = OtherLoad->Xneut; + with0->CVRshape = OtherLoad->CVRshape; + with0->CVRShapeObj = OtherLoad->CVRShapeObj; + with0->DailyShape = OtherLoad->DailyShape; + with0->DailyShapeObj = OtherLoad->DailyShapeObj; + with0->DutyShape = OtherLoad->DutyShape; + with0->DutyShapeObj = OtherLoad->DutyShapeObj; + with0->YearlyShape = OtherLoad->YearlyShape; + with0->YearlyShapeObj = OtherLoad->YearlyShapeObj; + with0->GrowthShape = OtherLoad->GrowthShape; + with0->GrowthShapeObj = OtherLoad->GrowthShapeObj; +// Spectrum := OtherLoad.Spectrum; in base class now +// SpectrumObj := OtherLoad.SpectrumObj; + with0->LoadClass = OtherLoad->LoadClass; + with0->NumCustomers = OtherLoad->NumCustomers; + with0->FLoadModel = OtherLoad->FLoadModel; + with0->FIXED = OtherLoad->FIXED; + with0->ExemptFromLDCurve = OtherLoad->ExemptFromLDCurve; + with0->FkVAAllocationFactor = OtherLoad->FkVAAllocationFactor; + with0->FConnectedkVA = OtherLoad->FConnectedkVA; + with0->FCVRwattFactor = OtherLoad->FCVRwattFactor; + with0->FCVRvarFactor = OtherLoad->FCVRvarFactor; + with0->ShapeIsActual = OtherLoad->ShapeIsActual; + with0->puSeriesRL = OtherLoad->puSeriesRL; + with0->RelWeighting = OtherLoad->RelWeighting; + with0->SetZIPVSize(OtherLoad->get_FnZIPV()); + for(stop = with0->FnZIPV, i = 1; i <= stop; i++) + { + (with0->ZIPV)[i] = (OtherLoad->ZIPV)[i]; + } + ClassMakeLike(OtherLoad); // Take care of inherited class properties + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherLoad->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Load MakeLike: \"") + OtherLoadName + + "\" Not Found.", 581); + return result; +} + +//---------------------------------------------------------------------------- + +int TLoad::Init(int Handle, int ActorID) +{ + int result = 0; + TLoadObj* P = nullptr; + if(Handle == 0) // init all load objects + { + P = (TLoadObj*) ElementList.Get_First(); + while(P != nullptr) + { + P->Randomize(0); + P = (TLoadObj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TLoadObj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to finish implementation TLoad.Init", -1); + result = 0; + return result; +} + +//---------------------------------------------------------------------------- + +TLoadObj::TLoadObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + PFChanged(false), + FAllocationFactor(0.0), + FkVAAllocationFactor(0.0), + FConnectedkVA(0.0), + FkWh(0.0), + FkWhDays(0.0), + FCFactor(0.0), + FAvgkW(0.0), + LastGrowthFactor(0.0), + LastYear(0), + LoadFundamental(0.0), + LoadSolutionCount(0), + OpenLoadSolutionCount(0), + RandomMult(0.0), + varBase(0.0), + varNominal(0.0), + VBase(0.0), + VBase105(0.0), + VBase95(0.0), + VBaseLow(0.0), + WNominal(0.0), + YPrimOpenCond(nullptr), + YQFixed(0.0), + FpuXHarm(0.0), + FXRHarmRatio(0.0), + FpuMean(0.0), + FpuStdDev(0.0), + FCVRwattFactor(0.0), + FCVRvarFactor(0.0), + Vmaxpu(0.0), + VminEmerg(0.0), + VminNormal(0.0), + Vminpu(0.0), + VLowpu(0.0), + ExemptFromLDCurve(false), + FIXED(false), + ShapeIsActual(false), + PFSpecified(false), + FnZIPV(0), + Connection(0), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr), + EEN_Factor(0.0), + GrowthShapeObj(nullptr), + HasBeenAllocated(false), + kWBase(0.0), + kVABase(0.0), + kWref(0.0), + kVARref(0.0), + kvarBase(0.0), + kVLoadBase(0.0), + LoadClass(0), + NumCustomers(0), + LoadSpecType(0), + PFNominal(0.0), + Rneut(0.0), + UE_Factor(0.0), + Xneut(0.0), + YearlyShapeObj(nullptr), + CVRShapeObj(nullptr), + ZIPV(nullptr), + puSeriesRL(0.0), + RelWeighting(0.0), + FLoadModel(0) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; + Fnphases = 3; + Fnconds = 4; // defaults to wye so it has a 4th conductor + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations + kWBase = 10.0; + kvarBase = 5.0; + PFNominal = 0.88; + kVABase = kWBase / PFNominal; + LoadSpecType = 0; + Rneut = -1.0; // signify neutral is open + Xneut = 0.0; + YearlyShape = ""; + YearlyShapeObj = nullptr; // IF YearlyShapeobj = nil THEN the load alway stays nominal * global multipliers + DailyShape = ""; + DailyShapeObj = nullptr; // IF DaillyShapeobj = nil THEN the load alway stays nominal * global multipliers + DutyShape = ""; + DutyShapeObj = nullptr; // IF DutyShapeobj = nil THEN the load alway stays nominal * global multipliers + GrowthShape = ""; + GrowthShapeObj = nullptr; // IF grwothshapeobj = nil THEN the load alway stays nominal * global multipliers + CVRshape = ""; + CVRShapeObj = nullptr; + Connection = 0; // Wye (star) + FLoadModel = 1; // changed from 2 RCD {easiest to solve} + LoadClass = 1; + NumCustomers = 1; + LastYear = 0; + FCVRwattFactor = 1.0; + FCVRvarFactor = 2.0; + RelWeighting = 1.0; + LastGrowthFactor = 1.0; + FkVAAllocationFactor = 0.5; + FAllocationFactor = FkVAAllocationFactor; + HasBeenAllocated = false; + ShapeIsActual = false; + PFSpecified = false; // default to not specified by PF property + LoadSolutionCount = -1; // for keeping track of the present solution in Injcurrent calcs + OpenLoadSolutionCount = -1; + YPrimOpenCond = nullptr; + FConnectedkVA = 0.0; // Loadspectype=3 + FkWh = 0.0; // Loadspectype=4 + FCFactor = 4.0; + FkWhDays = 30.0; + VminNormal = 0.0; // indicates for program to use Circuit quantities + VminEmerg = 0.0; + kVLoadBase = 12.47; + VBase = 7200.0; + VLowpu = 0.50; + Vminpu = 0.95; + Vmaxpu = 1.05; + VBaseLow = VLowpu * VBase; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + RandomMult = 1.0; + FIXED = false; + ExemptFromLDCurve = false; + FpuXHarm = 0.0; // zero signifies not specified. + FXRHarmRatio = 6.0; + FpuMean = 0.5; + FpuStdDev = 0.1; + UE_Factor = 0.0; + EEN_Factor = 0.0; + Spectrum = "defaultload"; // override base class definition + HarmMag.clear(); + HarmAng.clear(); + puSeriesRL = 0.50; + ZIPV = nullptr; + SetZIPVSize(0); + FPhaseCurr.clear(); // storage for intermediate current computation + // allocated in Recalcelementdata + InitPropertyValues(0); + RecalcElementData(ActiveActor); +} + + +//---------------------------------------------------------------------------- + +TLoadObj::~TLoadObj() +{ + delete YPrimOpenCond; + HarmMag.clear(); + HarmAng.clear(); + free(ZIPV); + FPhaseCurr.clear(); + // inherited::Destroy(); +} + + +void TLoadObj::SetZIPVSize(int n) +{ + FnZIPV = n; + ZIPV = (pDoubleArray) realloc(ZIPV, sizeof(double) * FnZIPV); +} + +//---------------------------------------------------------------------------- + +void TLoadObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + if(ASSIGNED(YearlyShapeObj)) + RandomMult = Gauss(YearlyShapeObj->Get_Mean(), YearlyShapeObj->Get_StdDev()); + else + RandomMult = Gauss(FpuMean, FpuStdDev); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + if(ASSIGNED(YearlyShapeObj)) + RandomMult = QuasiLogNormal(YearlyShapeObj->Get_Mean()); + else + RandomMult = QuasiLogNormal(FpuMean); + break; + /*nada*/ + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +void TLoadObj::CalcDailyMult(double hr) +{ + if(DailyShapeObj != nullptr) + { + ShapeFactor = DailyShapeObj->GetMult(hr); + ShapeIsActual = DailyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(1.0, 1.0); // Default to no daily variation +} + + +//---------------------------------------------------------------------------- + +void TLoadObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult IF no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TLoadObj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(1.0, 1.0); + // Defaults to no variation +} + +//---------------------------------------------------------------------------- + +void TLoadObj::CalcCVRMult(double hr) +{ + complex CVRFactor = {}; + /*CVR curve is assumed to be used in a yearly simulation*/ + if(CVRShapeObj != nullptr) + { + CVRFactor = CVRShapeObj->GetMult(hr); /*Complex*/ + FCVRwattFactor = CVRFactor.re; + FCVRvarFactor = CVRFactor.im; + } + /*Else FCVRWattFactor, etc. remain unchanged*/ +} + +//---------------------------------------------------------------------------- + +double TLoadObj::GrowthFactor(int Year, int ActorID) +{ + double result = 0.0; + if(Year == 0) // default all to 1 in year 0 ; use base values + LastGrowthFactor = 1.0; + else + { + if(GrowthShapeObj == nullptr) + LastGrowthFactor = ActiveCircuit[ActorID]->DefaultGrowthFactor; + else + { + if(Year != LastYear) // Search growthcurve + LastGrowthFactor = GrowthShapeObj->GetMult(Year); + } + } + result = LastGrowthFactor; // for Now + return result; +} + + +//---------------------------------------------------------------------------- + +void TLoadObj::SetkWkvar(double PkW, double Qkvar) +{ + kWBase = PkW; + kvarBase = Qkvar; + if(PFSpecified) + LoadSpecType = 0; + else + LoadSpecType = 1; +} + +void TLoadObj::SetNominalLoad(int ActorID) +{ + double Factor = 0.0; + ShapeFactor = CDoubleOne; + ShapeIsActual = false; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(FIXED) + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); // For fixed loads, consider only growth factor + } + else + switch(with0->Get_SolMode()) + { + case SNAPSHOT: + case HARMONICMODE: + if(ExemptFromLDCurve) + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + else + Factor = ActiveCircuit[ActorID]->get_FLoadMultiplier() * GrowthFactor(with0->get_Fyear(), ActorID); + break; + case DAILYMODE: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + CalcDailyMult(with0->DynaVars.dblHour); + } + break; + case EMPDAILYMODE: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + CalcDailyMult(with0->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + Factor = ActiveCircuit[ActorID]->get_FLoadMultiplier() * GrowthFactor(with0->get_Fyear(), ActorID); + CalcYearlyMult(with0->DynaVars.dblHour); + if(FLoadModel == 4) + CalcCVRMult(with0->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + CalcDutyMult(with0->DynaVars.dblHour); + } + break; + case GENERALTIME: + case DYNAMICMODE: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + // This mode allows use of one class of load shape + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with0->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with0->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with0->DynaVars.dblHour); + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + case MONTECARLO1: + { + Randomize(with0->RandomType); + Factor = RandomMult * GrowthFactor(with0->get_Fyear(), ActorID); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + } + break; + case MONTECARLO2: + case MONTECARLO3: + case LOADDURATION1: + case LOADDURATION2: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + CalcDailyMult(with0->DynaVars.dblHour); + if(!ExemptFromLDCurve) + Factor = Factor * ActiveCircuit[ActorID]->get_FLoadMultiplier(); + } + break; + case PEAKDAY: + { + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + CalcDailyMult(with0->DynaVars.dblHour); + } + break; + case AUTOADDFLAG: + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + break; // Loadmult = 1.0 by default + default: // defaults to Base kW * growth + Factor = GrowthFactor(with0->get_Fyear(), ActorID); + break; + } + } + if(ShapeIsActual) + { + WNominal = 1000.0 * ShapeFactor.re / Fnphases; + varNominal = 0.0; // initialize for unity PF and check for change + if(ShapeFactor.im != 0.0) // Qmult was specified + varNominal = 1000.0 * ShapeFactor.im / Fnphases; + else + { + if(PFSpecified && (PFNominal != 1.0)) // Qmult not specified but PF was + // user specified the PF for this load + { + varNominal = WNominal * sqrt((1.0L / Sqr(PFNominal) - 1.0L)); + if(PFNominal < 0.0) // watts and vare are in opposite directions + varNominal = -varNominal; + } + } + } + else + { + WNominal = 1000.0 * kWBase * Factor * ShapeFactor.re / Fnphases; + varNominal = 1000.0 * kvarBase * Factor * ShapeFactor.im / Fnphases; + } + Yeq = cdivreal(cmplx(WNominal, -varNominal), Sqr(VBase)); + if(Vminpu != 0.0) // at 95% voltage + Yeq95 = cdivreal(Yeq, Sqr(Vminpu)); + else + Yeq95 = CZero; + if(Vmaxpu != 0.0) // at 105% voltage + Yeq105 = cdivreal(Yeq, Sqr(Vmaxpu)); + else + Yeq105 = Yeq; + if(Vmaxpu != 0.0) // at 105% voltage for Constant I ***Added by Celso & Paulo + Yeq105I = cdivreal(Yeq, Vmaxpu); + else + Yeq105I = Yeq; // **Added by Celso & Paulo + + /*New code to help with convergence at low voltages*/ + ILow = (cmulreal(Yeq, VBaseLow)); + I95 = (cmulreal(Yeq95, VBase95)); + M95 = cdivreal(csub(I95, ILow), (VBase95 - VBaseLow)); // (I95 - ILow)/(Vbase95 - VbaseLow); + M95 = cdivreal(csub(I95, ILow), (VBase95 - VBaseLow)); // (I95 - ILow)/(Vbase95 - VbaseLow); ***Added by Celso & Paulo + IBase = (cmulreal(Yeq, VBase)); // ***Added by Celso & Paulo + M95I = cdivreal(csub(IBase, ILow), (VBase95 - VBaseLow)); // (IBase - ILow)/(Vbase95 - VbaseLow); ***Added by Celso & Paulo +} + +//---------------------------------------------------------------------------- + +void TLoadObj::RecalcElementData(int ActorID) +{ + VBaseLow = VLowpu * VBase; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + + + + /*Set kW and kvar from root values of kVA and PF*/ + switch(LoadSpecType) + { + case 0: /*kW, PF*/ + { + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + if(PFNominal < 0.0) + kvarBase = -kvarBase; + kVABase = sqrt(Sqr(kWBase) + Sqr(kvarBase)); + } + break; /*kW, kvar -- need to set PFNominal*/ + case 1: + { + kVABase = sqrt(Sqr(kWBase) + Sqr(kvarBase)); + if(kVABase > 0.0) + { + PFNominal = kWBase / kVABase; + /*If kW and kvar are different signs, PF is negative*/ + if(kvarBase != 0.0) + PFNominal = PFNominal * Sign(kWBase * kvarBase); + } + /*Else leave it as it is*/ + } + break; /*kVA, PF*/ + case 2: + { + kWBase = kVABase * Abs(PFNominal); + kWref = kWBase; + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + kVARref = kvarBase; + if(PFNominal < 0.0) + kvarBase = -kvarBase; + } + break; + case 3: + case 4: + if(PFChanged) // Recompute kvarBase + { + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + if(PFNominal < 0.0) + kvarBase = -kvarBase; + kVABase = sqrt(Sqr(kWref) + Sqr(kVARref)); + } + break; + + +/* done automagically in Property set... 3, 4: ComputeAllocatedLoad; */ + default: + ; + break; + } + SetNominalLoad(ActorID); + + /*Now check for errors. IF any of these came out nil and the string was not nil, give warning*/ + if(CompareText(YearlyShape, "none") == 0) + YearlyShape = ""; + if(CompareText(DailyShape, "none") == 0) + DailyShape = ""; + if(CompareText(DutyShape, "none") == 0) + DutyShape = ""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 583); + } + if(DailyShapeObj == nullptr) + { + if(DailyShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyShape + + "\" Not Found.", 584); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 585); + } + if(GrowthShapeObj == nullptr) + { + if(GrowthShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly Growth shape: \"") + GrowthShape + + "\" Not Found.", 586); + } + if(CVRShapeObj == nullptr) + { + if(CVRshape.size() > 0) + DoSimpleMsg(String("WARNING! CVR Shape shape: \"") + CVRshape + + "\" Not Found.", 586); + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 587); + if(Rneut < 0.0) // flag FOR open neutral + Yneut = cmplx(0.0, 0.0); + else + { + if((Rneut == 0.0) && (Xneut == 0.0)) // Solidly Grounded + // 1 microohm resistor + Yneut = cmplx(1.0e6, 0.0); + else + Yneut = cinv(cmplx(Rneut, Xneut)); + } + varBase = 1000.0 * kvarBase / Fnphases; + YQFixed = -varBase / Sqr(VBase); + InjCurrent = static_cast(realloc(InjCurrent, sizeof(complex) * Yorder)); + FPhaseCurr.resize( Fnphases + 1); + PFChanged = false; +} + +//---------------------------------------------------------------------------- + +void TLoadObj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + complex ZSeries = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + double XseriesOhms = 0.0; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsHarmonicModel && (with0->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) // Harmonic Mode and other than fundamental frequency + { + if(ActiveCircuit[ActorID]->NeglectLoadY) + /*Just a small value so things don't die and we get the actual injection current out the terminal*/ + { + Y = cmplx(EPSILON, 0.0); + } + else + + // compute equivalent Y assuming some of the load is series R-L and the rest is parallel R-L + + // Parallel R-L part of the Load model for harmonics mode + // Based in equivalent Y at 100% voltage + { + Y = cmulreal(Yeq, (1.0 - puSeriesRL)); + Y.im = Y.im / FreqMultiplier; /*Correct reactive part for frequency*/ + + // Series-connected R-L part + if(puSeriesRL != 0.0) + { + if(FpuXHarm > 0.0) // compute Zseries from special harmonic reactance for representing motors. + // the series branch is assumed to represent the motor + { + XseriesOhms = Sqr(kVLoadBase) * 1000.0L / (kVABase * puSeriesRL) * FpuXHarm; + ZSeries = cmplx(XseriesOhms / FXRHarmRatio, XseriesOhms); + } + else + // Compute Zseries from nominal load value + ZSeries = cinv(cmulreal(Yeq, puSeriesRL)); + ZSeries.im = ZSeries.im * FreqMultiplier; /*Correct reactive part for frequency*/ + Y = cadd(cinv(ZSeries), Y); // convert to admittance and add into Y + } + } + } + else + // not Harmonic mode + { + Y = Yeq; + Y.im = Y.im / FreqMultiplier; /*Correct reactive part for frequency*/ + } + } + Yij = cnegate(Y); + switch(Connection) + { + case 0: // WYE + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(Fnconds, Fnconds, Y); + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + Ymatrix->AddElement(Fnconds, Fnconds, Yneut); // Neutral + + /* If neutral is floating, make sure there is some small + connection to ground by increasing the last diagonal slightly */ + if(Rneut < 0.0) + Ymatrix->SetElement(Fnconds, Fnconds, cmulreal(Ymatrix->GetElement(Fnconds, Fnconds), 1.000001)); + } + break; // Delta or L-L + case 1: + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; // wrap around for closed connections + Ymatrix->AddElement(i, i, Y); + Ymatrix->AddElement(j, j, Y); + Ymatrix->AddElemsym(i, j, Yij); // get both off-diagonal elements + } + } + break; + default: + ; + break; + } +} + + +//---------------------------------------------------------------------------- + + + +// If doing an analysis that requires the load to be modeled as an impedance +// then put all in. + +void TLoadObj::CalcYPrim(int ActorID) +{ + int i = 0; + +// Build only YPrim Shunt for a Load then Copy to YPrim +// Build a dummy Yprim Series so that CalcV does not fail + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; // YPrim_Shunt->~TcMatrix(); + if(YPrim_Series != nullptr) + delete YPrim_Series; // YPrim_Series->~TcMatrix(); + if(YPrim != nullptr) + delete YPrim; // YPrim->~TcMatrix(); + YPrim_Series = new TcMatrix(Yorder); + YPrim_Shunt = new TcMatrix(Yorder); + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + if(ActiveCircuit[ActorID]->Solution->LoadModel == POWERFLOW) + { + SetNominalLoad(ActorID); // same as admittance model + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + else + // ADMITTANCE model wanted + { + SetNominalLoad(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages doesn't fail + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors + inherited::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + /*Put the current into the proper location according to connection*/ + +void TLoadObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum(TermArray[i - 1], cnegate(Curr)); + caccum(TermArray[Fnconds - 1], Curr); // Neutral + } + break; //DELTA + case 1: + { + caccum(TermArray[i - 1], cnegate(Curr)); + j = i + 1; + if(j > Fnconds) + j = 1; // rotate the phases + caccum(TermArray[j - 1], Curr); + } + break; + default: + ; + break; + } +} + +void TLoadObj::UpdateVoltageBases() +{ + /*# with ActiveLoadObj do */ + { + auto with0 = ActiveLoadObj; + switch(with0->Connection) + { + case 1: + with0->VBase = with0->kVLoadBase * 1000.0; + break; /*wye*/ + default: + switch(with0->Fnphases) + { + case 2: case 3: + with0->VBase = with0->kVLoadBase * InvSQRT3x1000; + break; + default: + with0->VBase = with0->kVLoadBase * 1000.0; /*1-phase or unknown*/ + break; + } + break; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TLoadObj::DoConstantPQLoad(int ActorID) +{ + int i = 0; + complex Curr = CZero, + V = CZero; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if (Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + { + Curr = cmul(Yeq, V); + } + else + { + if (Vmag <= VBase95) // Voltage between Vminpu and Vlow + { + Curr = cmul(InterpolateY95_YLow(Vmag), V); + } + else + { + if (Vmag > VBase105) // above 105% use an impedance model + { + Curr = cmul(Yeq105, V); + } + else + Curr = conjg(cdiv(cmplx(WNominal, varNominal), V)); + } // Above 95%, constant PQ + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TLoadObj::DoConstantZLoad(int ActorID) +{ + int i = 0; + complex Curr = {}; + +// Assume Yeq is kept up to date + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmul(Yeq, Vterminal[i - 1]); + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Constant P, quadratic Q + +void TLoadObj::DoMotorTypeLoad(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) // Voltage between Vminpu and Vlow + Curr = cmul(InterpolateY95_YLow(Vmag), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, V); + else + { + Curr = conjg(cdiv(cmplx(WNominal, 0.0), V)); // Above 95%, constant P + caccum(Curr, cmul(cmplx(0.0, Yeq.im), V)); // add in Q component of current + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// Constant Current Load + +void TLoadObj::DoConstantILoad(int ActorID) +{ + int i = 0; + complex V = {}; + double Vmag = 0.0; + complex Curr = {}; + +// Computes the current assuming the voltage mag is Vbase +// Just uses the phase angle off the voltage + +/* + Injection = [s/v]* = [ (P+jQ)/(Vbase * V/|V|)]* +*/ + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) // Voltage between Vminpu and Vlow ***Added by Celso & Paulo + Curr = cmul(InterpolateY95I_YLow(Vmag), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105I, V); + else + { + Curr = conjg(cdiv(cmplx(WNominal, varNominal), cmulreal(cdivreal(V, Vmag), VBase))); + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + + } +} + +void TLoadObj::DoZIPVModel(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex CurrZ = {}; + complex CurrI = {}; + complex CurrP = {}; + complex V = {}; + double Vmag = 0.0; + double vx = 0.0; + double evx = 0.0; + double yv = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + + /* May 31, 2016 changed to linear model below VbaseLow -- converges better for low voltage*/ + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) + { + CurrZ = cmul(cmplx(Yeq.re * ZIPV[1 - 1], Yeq.im * ZIPV[4 - 1]), V); // ***Changed by Celso & Paulow + CurrP = cmul(cmplx(InterpolateY95_YLow(Vmag).re * ZIPV[3 - 1], InterpolateY95_YLow(Vmag).im * ZIPV[6 - 1]), V); // ***Changed by Celso & Paulo + CurrI = cmul(cmplx(InterpolateY95I_YLow(Vmag).re * ZIPV[2 - 1], InterpolateY95I_YLow(Vmag).im * ZIPV[5 - 1]), V); // ***Changed by Celso & Paulo + Curr = cadd(CurrZ, cadd(CurrI, CurrP)); // ***Changed by Celso & Paulo + } + else + { + if(Vmag > VBase105) + { + CurrZ = cmul(cmplx(Yeq.re * ZIPV[1 - 1], Yeq.im * ZIPV[4 - 1]), V); // ***Changed by Celso & Paulo + CurrP = cmul(cmplx(Yeq105.re * ZIPV[3 - 1], Yeq105.im * ZIPV[6 - 1]), V); // ***Changed by Celso & Paulo + CurrI = cmul(cmplx(Yeq105I.re * ZIPV[2 - 1], Yeq105I.im * ZIPV[5 - 1]), V); // ***Changed by Celso & Paulo + Curr = cadd(CurrZ, cadd(CurrI, CurrP)); + } + else + { + CurrZ = cmul(cmplx(Yeq.re * ZIPV[1 - 1], Yeq.im * ZIPV[4 - 1]), V); + CurrI = conjg(cdiv(cmplx(WNominal * ZIPV[2 - 1], varNominal * ZIPV[5 - 1]), cmulreal(cdivreal(V, cabs(V)), VBase))); + CurrP = conjg(cdiv(cmplx(WNominal * ZIPV[3 - 1], varNominal * ZIPV[6 - 1]), V)); + Curr = cadd(CurrZ, cadd(CurrI, CurrP)); + } + + // low-voltage drop-out + } + if(ZIPV[6] > 0.0) + { + vx = 500.0 * (Vmag / VBase - ZIPV[6]); + evx = exp(2 * vx); + yv = 0.5 * (1 + (evx - 1) / (evx + 1)); + Curr = cmulreal(Curr, yv); + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Linear P, quadratic Q + +void TLoadObj::DoCVRModel(int ActorID) +{ + int i = 0; + complex V = {}; + complex Curr = {}; + complex Cvar = {}; // var current + double WattFactor = 0.0; + double VarFactor = 0.0; + double Vmag = 0.0; + double VRatio = 0.0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + try + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) // Voltage between Vminpu and Vlow + Curr = cmul(InterpolateY95_YLow(Vmag), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, V); + else + { + VRatio = Vmag / VBase; // vbase is l-n FOR wye and l-l FOR delta + + + // Linear factor adjustment does not converge for some reason while power adjust does easily + // WattFactor := (1.0 + FCVRwattFactor*(Vmag/VBase - 1.0)); + if(FCVRwattFactor != 1.0) + WattFactor = pow(VRatio, FCVRwattFactor); + else + WattFactor = VRatio; // old value (in error): 1.0; + if(WattFactor > 0.0) + Curr = conjg(cdiv(cmplx(WNominal * WattFactor, 0.0), V)); + else + Curr = CZero; // P component of current + if(Vmag == 0.0) // Trap divide by zero error + /*Compute Q component of current*/ + Cvar = CZero; + else + { + if(FCVRvarFactor == 2.0) /*Check for easy, quick ones first*/ + { + Cvar = cmul(cmplx(0.0, Yeq.im), V); // 2 is same as Constant impedance + } + else + { + if(FCVRvarFactor == 3.0) + { + VarFactor = pow(VRatio, 3); + Cvar = conjg(cdiv(cmplx(0.0, varNominal * VarFactor), V)); + } + else + + /*Other Var factor code here if not squared or cubed*/ + { + VarFactor = pow(VRatio, FCVRvarFactor); + Cvar = conjg(cdiv(cmplx(0.0, varNominal * VarFactor), V)); + } + } + } + caccum(Curr, Cvar); // add in Q component of current + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } + } + catch (std::exception &e) + { + { + DoSimpleMsg("Error in Load." + get_Name() + ": " + (std::string)e.what(), 5871); + throw ; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Constant P, Fixed Q Q is always kvarBase + +void TLoadObj::DoFixedQ(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + { + Curr = conjg(cdiv(cmplx(WNominal, varBase), V)); + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Constant P, Fixed Q Q is always a fixed Z derived from kvarBase + +void TLoadObj::DoFixedQZ(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID, true); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = Vterminal[i - 1]; + Vmag = cabs(V); + if(Vmag <= VBaseLow) // Below VbaseZ resort to linear equal to Yprim contribution + Curr = cmul(Yeq, V); + else + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + { + Curr = conjg(cdiv(cmplx(WNominal, 0.0), V)); // P component of current + caccum(Curr, cmul(cmplx(0.0, YQFixed), V)); // add in Q component of current + } + } + + // Save this value in case the Load value is different than the terminal value (see InitHarmonics) + } + FPhaseCurr[i - 1] = Curr; + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute Injection Current Only when in harmonics mode*/ +/*Assumes spectrum is an ideal current source based on the fundamental current and spectrum*/ + +void TLoadObj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex Mult = {}; + double LoadHarmonic = 0.0; + + /*Don't calc Vterminal here because it could be undefined!*/ + ZeroInjCurrent(); + ZeroITerminal(); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + LoadHarmonic = with0->get_FFrequency() / LoadFundamental; // Loadfundamental = frequency of solution when Harmonic mode entered + Mult = SpectrumObj->GetMult(LoadHarmonic); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmulreal(Mult, HarmMag[i]); // Get base harmonic magnitude + RotatePhasorDeg(Curr, LoadHarmonic, HarmAng[i]); // Time shift by fundamental + // don't need to save Curr here like we do in Power Flow modes + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into InjCurrent array taking into account connection + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + // NOTE: This is the value of ITerminal a Monitor will capture in Harmonics mode .. it captures the harmonic injection + set_ITerminalUpdated(true, ActorID); + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +bool TLoadObj::AllTerminalsClosed() +{ + bool result = false; + int i = 0; + int j = 0; + int stop = 0; + result = true; + for(stop = Get_NTerms(), i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Get_NConds(), j = 1; j <= stop1; j++) + { + if(! ( Terminals[i - 1].Conductors[j - 1].Closed )) + { + result = false; + return result; + } + } + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TLoadObj::CalcVTerminalPhase(int ActorID, bool CheckAlg) +{ + int i = 0; + int j = 0; + +/* Establish phase voltages and stick in Vtemp*/ + auto with0 = ActiveCircuit[ActorID]->Solution; + if ( (with0->Algorithm == NCIMSOLVE) && CheckAlg) + { + for (i = 1; i <= Fnphases; i++) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + } + else + { + switch (Connection) + { + case 0: + { + { + for (i = 1; i <= Fnphases; i++) + Vterminal[i - 1] = with0->VDiff(NodeRef[i - 1], NodeRef[Fnconds - 1], ActorID); + } + } + break; + case 1: + { + { + for (i = 1; i <= Fnphases; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; + Vterminal[i - 1] = with0->VDiff(NodeRef[i - 1], NodeRef[j - 1], ActorID); + } + } + } + break; + default: + ; + break; + } + } + LoadSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Calculates total load current and adds it properly into the InjCurrent array + +// Need to implement DynamicMode sometime ... + +void TLoadObj::CalcLoadModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + /*IF IsDynamicModel THEN DoDynamicMode + ELSE*/ + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + switch(FLoadModel) + { + // compute total Load currents and Add into InjCurrent array; + case 1: + DoConstantPQLoad(ActorID); + break; // normal load-flow type load + case 2: + DoConstantZLoad(ActorID); + break; + case 3: + DoMotorTypeLoad(ActorID); + break; // Constant P, Quadratic Q; + case 4: + DoCVRModel(ActorID); + break; // mixed motor/resistive load with CVR factors + case 5: + DoConstantILoad(ActorID); + break; + case 6: + DoFixedQ(ActorID); + break; // Fixed Q + case 7: + DoFixedQZ(ActorID); + break; // Fixed, constant Z Q + case 8: + DoZIPVModel(ActorID); + break; + default: + DoConstantZLoad(ActorID); // FOR now, until we implement the other models. + break; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Fill InjCurrent array with the current values to use for injections. + +void TLoadObj::CalcInjCurrentArray(int ActorID) +{ + int i = 0; + int j = 0; + int k = 0; + +// IF a terminal is open, THEN standard load models don't apply, so check it out first + if(AllTerminalsClosed()) + +// Now Get Injection Currents + { + CalcLoadModelContribution(ActorID); + } + else + + + /// THIS MAY NOT WORK !!! WATCH FOR BAD RESULTS + + // some terminals not closed use admittance model FOR injection + { + int stop = 0; + if(OpenLoadSolutionCount != ActiveCircuit[ActorID]->Solution->SolutionCount) + + // Rebuild the Yprimopencond IF a new solution because values may have changed. + + // only reallocate when necessary + { + if(YPrimOpenCond == nullptr) + YPrimOpenCond = new TcMatrix(Yorder); + else + YPrimOpenCond->Clear(); + if(YPrimOpenCond->get_Norder() != Yorder) + { + delete YPrimOpenCond; + YPrimOpenCond = new TcMatrix(Yorder); + } + CalcYPrimMatrix(YPrimOpenCond, ActorID); + + /*Now Account FOR the Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + /*# with YPrimOpenCond do */ + { + auto with0 = YPrimOpenCond; + int stop = 0; + k = 0; + for(stop = Fnterms, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnconds, j = 1; j <= stop1; j++) + { + if(! ( Terminals[i - 1].Conductors[j - 1].Closed ) ) + { + with0->ZeroRow(j + k); + with0->ZeroCol(j + k); + with0->SetElement(j + k, j + k, cmplx(1.0e-12, 0.0)); // In case node gets isolated + } + } + k = k + Fnconds; + } + } + OpenLoadSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; + } + ComputeVterminal(ActorID); + YPrimOpenCond->MVmult(&(ComplexBuffer[0]), &(Vterminal[0])); + for(stop = Yorder, i = 1; i <= stop; i++) + { + (ComplexBuffer)[i] = cnegate((ComplexBuffer)[i]); + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Always return total terminal currents in the Curr array + +void TLoadObj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + { + CalcLoadModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Get the injection currents and add them directly into the Currents array + +int TLoadObj::InjCurrents(int ActorID) +{ + int result = 0; + result = 0; + if(Get_Enabled()) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if (with0->LoadsNeedUpdating) + SetNominalLoad(ActorID); // Set the nominal kW, etc. for the type of solution being done + CalcInjCurrentArray(ActorID); + result = inherited::InjCurrents(ActorID); // Add into Global Currents Array + + } + return result; +} +/* + For Vmag between V95 and Vlow, interpolate for equivalent Y +*/ + +complex TLoadObj::InterpolateY95_YLow(double Vmag) +{ + complex result = {}; + result = cdivreal(cadd(ILow, cmulreal(M95, Vmag - VBaseLow)), Vmag); //(Ilow + M95 * (Vmag - VBaseLow))/Vmag) + +/***** + WriteDLLDebugFile(Format('Iter=%d, Name="%s", Vmag=%.6g, Yeq=%.6g +j %.6g', + [ActiveCircuit.Solution.iteration, Name, Vmag, Result.re, Result.im])); + */ + return result; +} // ***Added by Celso & Paulo +/* + For Vmag between V95 and Vlow, interpolate for equivalent Y +*/ + +complex TLoadObj::InterpolateY95I_YLow(double Vmag) +{ + complex result = {}; + result = cdivreal(cadd(ILow, cmulreal(M95I, Vmag - VBaseLow)), Vmag); //(Ilow + M95I * (Vmag - VBaseLow))/Vmag) // ***Changed by Celso & Paulo + +/***** + WriteDLLDebugFile(Format('Iter=%d, Name="%s", Vmag=%.6g, Yeq=%.6g +j %.6g', + [ActiveCircuit[ActiveActor].Solution.iteration, Name, Vmag, Result.re, Result.im])); + */ + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Gets the injection currents for the last solution performed +// Do not call SetNominalLoad, as that may change the load values + +void TLoadObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + if(Get_Enabled()) + { + int stop = 0; + CalcInjCurrentArray(ActorID); + // Copy into buffer array + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i] = (InjCurrent)[i]; + } + } + else + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i] = CZero; + } + } + } + catch (std::exception &e) + { + DoErrorMsg(String("Load Object: \"") + get_Name() + "\" in GetInjCurrents FUNCTION.", (std::string) e.what(), "Current buffer may not big enough.", 588); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +bool TLoadObj::Get_Unserved(int ActorID) +{ + bool result = false; + int i = 0; + double Vpu = 0.0; + double Vmag = 0.0; + double NormMinCriteria = 0.0; + double EmergMinCriteria = 0.0; + /* Line overload takes precedence. + Assumes that low voltage is due to overloaded line. + IF voltage is below Emergency minumum, it is counted as unserved. + */ + int stop = 0; + result = false; + if(UE_Factor > 0.0) + { + result = true; + return result; + } + + /*ELSE Check Voltages*/ + if(LoadSolutionCount != ActiveCircuit[ActorID]->Solution->SolutionCount) + CalcVTerminalPhase(ActorID); + + // Get the lowest of the Phase voltages + Vpu = VBase; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Vmag = cabs(Vterminal[i - 1]); + if(Vmag < Vpu) + Vpu = Vmag; + } + Vpu = Vpu / VBase; + if(VminNormal != 0.0) + NormMinCriteria = VminNormal; + else + NormMinCriteria = ActiveCircuit[ActorID]->NormalMinVolts; + if(VminEmerg != 0.0) + EmergMinCriteria = VminEmerg; + else + EmergMinCriteria = ActiveCircuit[ActorID]->EmergMinVolts; + if(Vpu < EmergMinCriteria) + { + result = true; + //UE_Factor := 1.0; + // 9-19-00 RCD let UE_Factor start small and grow linearly at same slope + // as EEN_Factor + UE_Factor = (EmergMinCriteria - Vpu) / (NormMinCriteria - EmergMinCriteria); + return result; + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +bool TLoadObj::Get_ExceedsNormal(int ActorID) +{ + bool result = false; + int i = 0; + double Vpu = 0.0; + double Vmag = 0.0; + + /* Line overload takes precedence. + Assumes that low voltage is due to overloaded line. + IF voltage is below Normal minumum, it is counted as unserved in proportion + to the difference between the normal and emergency voltage limits. + */ + double NormMinCriteria = 0.0; + double EmergMinCriteria = 0.0; + +/* 1-4-00 Added Vpu*/ + int stop = 0; + result = false; + if(EEN_Factor > 0.0) + { + result = true; + return result; + } // Check line overload + if(LoadSolutionCount != ActiveCircuit[ActorID]->Solution->SolutionCount) + CalcVTerminalPhase(ActorID); + + // Get the lowest of the Phase voltages + Vpu = VBase; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Vmag = cabs(Vterminal[i-1]); + if(Vmag < Vpu) + Vpu = Vmag; + } + Vpu = Vpu / VBase; + if(VminNormal != 0.0) + NormMinCriteria = VminNormal; + else + NormMinCriteria = ActiveCircuit[ActorID]->NormalMinVolts; + if(VminEmerg != 0.0) + EmergMinCriteria = VminEmerg; + else + EmergMinCriteria = ActiveCircuit[ActorID]->EmergMinVolts; + if(Vpu < NormMinCriteria) + { + EEN_Factor = (NormMinCriteria - Vpu) / (NormMinCriteria - EmergMinCriteria); + // 9-19-00 RCD Let EEN factor grow linearly at same slope + // IF EEN_Factor > 1.0 THEN EEN_Factor := 1.0; + result = true; + return result; + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TLoadObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + switch(i) + { + case 4: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, kWBase, 8, 1); } + break; + case 5: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, PFNominal, 5, 3); } + break; + case 12: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, kvarBase, 8, 1); } + break; + case 22: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, FkVAAllocationFactor, 5, 3); } + break; + case 23: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, kVABase, 8, 1); } + break; + case 33: + { + int stop1 = 0; + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); } + for(stop1 = get_FnZIPV(), j = 1; j <= stop1; j++) + { + { Write(f, (ZIPV)[j], 0, 2); Write(f, L' '); } + } + WriteLn(f, L'\"'); + } + break; + case 34: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, (puSeriesRL * 100.0), 8, 1); } + break; + default: + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + break; + } + } + } +} + +void TLoadObj::Set_kVAAllocationFactor(double Value) +{ + FkVAAllocationFactor = Value; + FAllocationFactor = Value; + LoadSpecType = 3; + ComputeAllocatedLoad(); + HasBeenAllocated = true; +} +/*This procedure is used by the energymeter allocateload function to adjust load allocation factors*/ + +void TLoadObj::Set_AllocationFactor(double Value) +{ + FAllocationFactor = Value; + switch(LoadSpecType) + { + case 3: + FkVAAllocationFactor = Value; + break; + case 4: + FCFactor = Value; + break; + default: + ; + break; + } + ComputeAllocatedLoad(); // update kWbase + HasBeenAllocated = true; +} + +void TLoadObj::Set_CFactor(double Value) +{ + FCFactor = Value; + FAllocationFactor = Value; + LoadSpecType = 4; + ComputeAllocatedLoad(); + HasBeenAllocated = true; +} + +void TLoadObj::Set_ConnectedkVA(double Value) +{ + FConnectedkVA = Value; + LoadSpecType = 3; + FAllocationFactor = FkVAAllocationFactor; + ComputeAllocatedLoad(); +} + +void TLoadObj::Set_kWh(double Value) +{ + FkWh = Value; + LoadSpecType = 4; + FAllocationFactor = FCFactor; + ComputeAllocatedLoad(); +} + +void TLoadObj::Set_kWhDays(double Value) +{ + FkWhDays = Value; + LoadSpecType = 4; + ComputeAllocatedLoad(); +} + +void TLoadObj::set_nZIPV(int Value) +{ + SetZIPVSize(Value); +} + +void TLoadObj::ComputeAllocatedLoad() +{ + +/*Fixed loads defined by kW, kvar or kW, pf are ignored*/ + switch(LoadSpecType) + { + case 3: + if(FConnectedkVA > 0.0) + { + kWBase = FConnectedkVA * FkVAAllocationFactor * Abs(PFNominal); + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + if(PFNominal < 0.0) + kvarBase = -kvarBase; + } + break; + case 4: + { + FAvgkW = FkWh / (FkWhDays * 24); + kWBase = FAvgkW * FCFactor; + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + if(PFNominal < 0.0) + kvarBase = -kvarBase; + } + break; + default: + ; + break; + } +} +/* + Get the present terminal currents and store for harmonics base reference; +*/ + +void TLoadObj::InitHarmonics(int ActorID) +{ + + /*Currents:pComplexArray;*/ + int i = 0; + /*Make Sure there's enuff memory*/ + int stop = 0; + HarmMag.resize(Fnphases + 1); + HarmAng.resize(Fnphases + 1); + + // Currents := AllocMem(Sizeof(Currents^[1])*Yorder); // to hold currents + LoadFundamental = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + + // GetCurrents(Currents); // Use FPhaseCurr from most recent pflow solution + /*Store the currents at fundamental frequency. + The spectrum is applied to these. + */ + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (HarmMag)[i] = cabs(FPhaseCurr[i - 1]); + (HarmAng)[i] = cdang(FPhaseCurr[i - 1]); + } + + // ReallocMem(Currents, 0); // get rid of temp space +} + +void TLoadObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(3,"12.47"); + Set_PropertyValue(4,"10"); + Set_PropertyValue(5,".88"); + Set_PropertyValue(6,"1"); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,""); + Set_PropertyValue(10,""); + Set_PropertyValue(11,"wye"); + Set_PropertyValue(12,"5"); + Set_PropertyValue(13,"-1"); // 'rneut'; // IF entered -, assume open or user defined + Set_PropertyValue(14,"0"); //'xneut'; + Set_PropertyValue(15,"variable"); //'status'; // fixed or variable + Set_PropertyValue(16,"1"); //class + Set_PropertyValue(17,"0.95"); + Set_PropertyValue(18,"1.05"); + Set_PropertyValue(19,"0.0"); + Set_PropertyValue(20,"0.0"); + Set_PropertyValue(21,"0.0"); + Set_PropertyValue(22,"0.5"); // Allocation Factor + Set_PropertyValue(23,"11.3636"); + Set_PropertyValue(24,"50"); + Set_PropertyValue(25,"10"); + Set_PropertyValue(26,"1"); // CVR watt factor + Set_PropertyValue(27,"2"); // CVR var factor + Set_PropertyValue(28,"0"); // kwh bulling + Set_PropertyValue(29,"30"); // kwhdays + Set_PropertyValue(30,"4"); // Cfactor + Set_PropertyValue(31,""); // CVRCurve + Set_PropertyValue(32,"1"); // NumCust + Set_PropertyValue(33,""); // ZIPV coefficient array + Set_PropertyValue(34,"50"); // %SeriesRL + Set_PropertyValue(35,"1"); // RelWeighting + Set_PropertyValue(36,"0.5"); // VZpu + Set_PropertyValue(37,"0.0"); // puXharm + Set_PropertyValue(38,"6.0"); // XRHarm + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TLoadObj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + char Buff[1000]; + s = "Phases=1 conn=wye"; + + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = kVLoadBase / SQRT3; + else + V = kVLoadBase; + s = s + Format(" kV=%-.5g", V); + +/* OLD Method + // Divide the load by no. phases + If Fnphases>1 Then + Begin + S := S + Format(' kW=%-.5g kvar=%-.5g',[kWbase/Fnphases, kvarbase/Fnphases]); + If FConnectedKVA>0.0 Then + S := S + Format(' xfkVA=%-.5g ',[FConnectedkVA/Fnphases]); + End; +*/ + +// New Method: Assume load is distributed equally among the 3 phases -- works better +//1-5-2016 RCD + s = s + Format(" kW=%-.5g kvar=%-.5g", kWBase / 3.0, kvarBase / 3.0); + if(FConnectedkVA > 0.0) + s = s + Format(" xfkVA=%-.5g ", FConnectedkVA / 3.0); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + TDSSCktElement::MakePosSequence(ActorID); +} + +String TLoadObj::GetPropertyValue(int Index) +{ + String result = ""; + int i = 0; + switch(Index) + { + case 2: + result = GetBus(1); + break; + case 3: + result = Format("%-.14f", kVLoadBase); + break; + case 4: + result = Format("%-.14f", kWBase); + break; + case 5: + result = Format("%-.4g", PFNominal); + break; + case 7: + result = YearlyShape; + break; + case 8: + result = DailyShape; + break; + case 9: + result = DutyShape; + break; + case 12: + result = Format("%-.14f", kvarBase); + break; + case 22: + result = Format("%-.14f", FkVAAllocationFactor); + break; + case 23: + result = Format("%-.14f", kVABase); + break; + case 30: + result = Format("%-.4g", FCFactor); + break; + case 33: + { + int stop = 0; + result = ""; + for(stop = get_FnZIPV(), i = 1; i <= stop; i++) + { + result = result + Format(" %-g", (ZIPV)[i]); + } + } + break; + case 34: + result = Format("%-.14f", puSeriesRL * 100.0); + break; + case 35: + result = Format("%-.14f", RelWeighting); + break; + case 36: + result = Format("%-.14f", VLowpu); + break; + case 37: + result = Format("%-.14f", FpuXHarm); + break; + case 38: + result = Format("%-.14f", FXRHarmRatio); + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + + +void Load_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class Load_unit + { + public: + Load_unit() + { + //AssertSystemInitialization(); + Load_initialization(); + } + }; + Load_unit _Load_unit; + +} // namespace Load + + + + diff --git a/OpenDSSC/PCElements/Load.h b/OpenDSSC/PCElements/Load.h new file mode 100644 index 0000000..f9de810 --- /dev/null +++ b/OpenDSSC/PCElements/Load.h @@ -0,0 +1,281 @@ +#ifndef LoadH +#define LoadH + +#include "System.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Arraydef.h" + +namespace Load +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +// The load is assumed balanced over the no. of phases defined +// To model unbalanced loads, define separate single-phase loads + +// IF you do not specify load shapes defaults are: +// Yearly: Defaults to No variation or Daily when Daily is defined +// Daily: Defaults to No variation (i.e. multiplier = 1.0 always) +// Dutycycle: Defaults to Daily shape +// Growth: Circuit default growth factor + +/* Change Log + 10/7/99 RCD Tightened up default load shape code and corrected comments + 11-22-99 Fixed bug in CalcYPrimMatrix + 12-5-99 Changed PQ load limits to 95% to 105% + 1-8-99 Made PQ load limits a variable (added vminpu, vmaxpu properties) + 2-1-00 Added normal and emergency voltage ratings to override system settings when <> 0 + 4-17-00 Added XFKVA and AllocationFactor properties and associated code. + 8-26-00 Added exemption from LoadMult code (exemptfromLDcurve) + 9-19-00 Changed the way UE and EEN computed for low voltage + 10-25-00 Added Spectrum + 10-27-00 Implemented Harmonic current and Harmonic Mode stuff + 3-27-01 Added check to prevent divide by zero on calculation of PFNominal + 5-17-01 Moved Spectrum definition back to PCElement + 2-18-03 Changed Rneut default to -1 + Created a Y_Series with small conductances on the diagonal so that calcV doesn't fail + 9-23-08 Added CVR Factors + 10-14-08 Added kWh and Cfactor. Modified behavior of AllocationFactor to simplify State Estimation + 4/1/14 Added Vlowpu property to make solution converge better at very low voltages + 1/7/15 Added puXHarm and XRHarm properties to help model motor load for harmonic studies + 3/16/16 Added PFSpecified to account for problems when UseActual is specified and no Qmult specified + 1/10/18 Celso/Paulo mods for low-voltage transition for Model 5 +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TLoad : public PCClass::TPCClass +{ + friend class TLoadObj; +public: + typedef PCClass::TPCClass inherited; +private: + void InterpretConnection(const String s); + void SetNcondsForConnection(); +protected: + virtual int MakeLike(const String OtherLoadName); + void DefineProperties(); // Add Properties of this class to propName +public: + TLoad(); + virtual ~TLoad(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TLoadObj : public PCElement::TPCElement +{ + friend class TLoad; +public: + typedef PCElement::TPCElement inherited; +//private: + bool PFChanged; + double FAllocationFactor; // For all types of allocation + double FkVAAllocationFactor; // for connected kVA specification + double FConnectedkVA; + double FkWh; + double FkWhDays; + double FCFactor; // For kWh billed spec + double FAvgkW; + std::vector FPhaseCurr; // this is the intermediate current computed in each power flow mode. + std::vector HarmAng; // References for Harmonics mode + std::vector HarmMag; + double LastGrowthFactor; + int LastYear; // added FOR speedup so we don't have to search FOR growth factor a lot + double LoadFundamental; + int LoadSolutionCount; + int OpenLoadSolutionCount; + double RandomMult; + Ucomplex::complex ShapeFactor; + double varBase; // Base vars per phase + double varNominal; + double VBase; // Base volts suitable for computing currents + double VBase105; + double VBase95; + double VBaseLow; + double WNominal; // Nominal Watts per phase + Ucomplex::complex Yeq; // at nominal + Ucomplex::complex Yeq105; + Ucomplex::complex Yeq105I; // ***Added by Celso & Paulo + Ucomplex::complex Yeq95; + Ucomplex::complex Yneut; + Ucmatrix::TcMatrix* YPrimOpenCond; // To handle cases where one conductor of load is open + double YQFixed; // Fixed value of y FOR type 7 load + double FpuXHarm; // puX for harmonics solution. + double FXRHarmRatio; // X/R at fundamental + + // formerly private, now read-only properties for COM access + double FpuMean; + double FpuStdDev; + double FCVRwattFactor; + double FCVRvarFactor; + double Vmaxpu; + double VminEmerg; // overrides system settings IF <> 0.0 + double VminNormal; + double Vminpu; + double VLowpu; // below this voltage, resorts to linear @ Yeq + + // For interpolating currents between VbaseLow and Vbase95 + Ucomplex::complex ILow; + Ucomplex::complex I95; + Ucomplex::complex IBase; // at nominal ***Added by Celso & Paulo + Ucomplex::complex M95; // complex slope of line between Low and 95 + Ucomplex::complex M95I; // complex slope of line between Low and 95 for Constant I **Added by Celso & Paulo + bool ExemptFromLDCurve; + bool FIXED; // IF Fixed, always at base value + bool ShapeIsActual; + bool PFSpecified; // Added 3-16-16 to fix problem with UseActual + int FnZIPV; + bool AllTerminalsClosed(); + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); + void CalcInjCurrentArray(int ActorID); + void CalcLoadModelContribution(int ActorID); + void CalcVTerminalPhase(int ActorID, bool CheckAlg = false); + void CalcYearlyMult(double hr); + void CalcCVRMult(double hr); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void DoConstantILoad(int ActorID); + void DoConstantPQLoad(int ActorID); + void DoConstantZLoad(int ActorID); + void DoFixedQ(int ActorID); + void DoFixedQZ(int ActorID); + void DoHarmonicMode(int ActorID); + void DoCVRModel(int ActorID); + void DoZIPVModel(int ActorID); + void SetZIPVSize(int n); + void DoMotorTypeLoad(int ActorID); + double GrowthFactor(int Year, int ActorID); + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); + Ucomplex::complex InterpolateY95_YLow(double Vmag); + Ucomplex::complex InterpolateY95I_YLow(double Vmag); // ***Added by Celso & Paulo + bool Get_Unserved(int ActorID); + void Set_kVAAllocationFactor(double Value); + void Set_ConnectedkVA(double Value); + void ComputeAllocatedLoad(); + /*Set kWh properties ...*/ + void Set_CFactor(double Value); + void Set_kWh(double Value); + void Set_kWhDays(double Value); + void Set_AllocationFactor(double Value); + void SetkWkvar(double PkW, double Qkvar); + void set_nZIPV(int Value); +protected: + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); +public: + int Connection; /* 0 = line-neutral; 1=Delta*/ + String DailyShape; // Daily (24 HR) load shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily load Shape FOR this load + String DutyShape; // Duty cycle load shape FOR changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this load + double EEN_Factor; // is overloaded Factor is the amount of overload + String GrowthShape; // (year, Multiplier from previous year) + GrowthShape::TGrowthShapeObj* GrowthShapeObj; // Shape for this Growth Curve + bool HasBeenAllocated; + double kWBase; + double kVABase; + double kWref; + double kVARref; + double kvarBase; + double kVLoadBase; + int LoadClass; + int NumCustomers; + int LoadSpecType; // 0=kW, PF; 1= kw, kvar; 2=kva, PF + double PFNominal; + double Rneut; + double UE_Factor; // These are set to > 0 IF a line in the critical path + double Xneut; // Neutral impedance + String YearlyShape; // ='fixed' means no variation exempt from variation + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this load + String CVRshape; + LoadShape::TLoadShapeObj* CVRShapeObj; + Arraydef::pDoubleArray ZIPV; // Made public 5-20-2013 + double puSeriesRL; + double RelWeighting; + int FLoadModel; // Variation with voltage + /* 1 = Constant kVA (P,Q always in same ratio) + 2 = Constant impedance + 3 = Constant P, Quadratic Q (Mostly motor) + 4 = Linear P, Quadratic Q (Mixed motor/resistive Use this for CVR studies + 5 = Constant |I| + 6 = Constant P (Variable); Q is fixed value (not variable) + 7 = Constant P (Variable); Q is fixed Z (not variable) + 8 = ZIPV (3 real power coefficients, 3 reactive, Vcutoff) + */ + TLoadObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TLoadObj(); + bool Get_ExceedsNormal(int ActorID); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + void SetNominalLoad(int ActorID); + void Randomize(int Opt); + // 0 = reset to 1.0 + // 1 = Gaussian around mean and std Dev + // 2 = uniform + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + void UpdateVoltageBases(); + //************************************* returns to properties*************************************************** + double get_FAllocationFactor(); + double get_FCFactor(); + double get_FkWhDays(); + double get_FkWh(); + double get_FConnectedkVA(); + double get_FkVAAllocationFactor(); + double get_FpuMean(); + double get_FpuStdDev(); + double get_FCVRwattFactor(); + double get_FCVRvarFactor(); + double get_Vmaxpu(); + double get_VminEmerg(); + double get_VminNormal(); + double get_Vminpu(); + bool get_ExemptFromLDCurve(); + bool get_FIXED(); + int get_FnZIPV(); + bool get_PFSpecified(); + +// Property ExceedsNormal[ActorID:Integer] :Boolean Read Get_ExceedsNormal(ActorID:Integer); + + /*Allocate load from connected kva or kWh billing*/ + TLoadObj(DSSClass::TDSSClass* ParClass); + TLoadObj(String ClassName); + TLoadObj(); +}; +extern TLoadObj* ActiveLoadObj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace Load + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Load; +#endif + +#endif // LoadH + + + + diff --git a/OpenDSSC/PCElements/PCClass.cpp b/OpenDSSC/PCElements/PCClass.cpp new file mode 100644 index 0000000..e9fb093 --- /dev/null +++ b/OpenDSSC/PCElements/PCClass.cpp @@ -0,0 +1,98 @@ + +#pragma hdrstop + +#include "PCClass.h" + +#include "DSSGlobals.h" +#include "Utilities.h" +#include "PCElement.h" + +using namespace std; +using namespace CktElementClass; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Utilities; + +namespace PCClass +{ + + + +TPCClass::TPCClass() + : NumPCClassProps(1) +{ + ; + DSSClassType = PC_ELEMENT; +} + +TPCClass::~TPCClass() +{ + // inherited::Destroy(); +} + + +void TPCClass::CountProperties() +{ + NumProperties = NumProperties + NumPCClassProps; + inherited::CountProperties(); +} + +// Define the properties for the base power delivery element class + +void TPCClass::DefineProperties() +{ + PropertyName[ActiveProperty + 1] = "spectrum"; + PropertyHelp[ActiveProperty + 1] = "Name of harmonic spectrum for this device."; + ActiveProperty = ActiveProperty + NumPCClassProps; + inherited::DefineProperties(); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPCClass::ClassEdit(const void* ActivePCObj, int ParamPointer) +{ + int result = 0; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TPCElement(ActivePCObj) do */ + { + auto with0 = ((TPCElement*) ActivePCObj); + switch(ParamPointer) + { + case 1: + with0->Spectrum = Parser[ActiveActor]->MakeString_(); + break; + default: + inherited::ClassEdit(ActivePCObj, ParamPointer - NumPCClassProps); + break; + } + } + return result; +} + +void TPCClass::ClassMakeLike(const void* OtherObj) +{ + TPCElement* OtherPCObj = nullptr; + OtherPCObj = ((TPCElement*) OtherObj); + /*# with TPCElement(ActiveDSSObject[ActiveActor]) do */ + { + auto with0 = ((TPCElement*) ActiveDSSObject[ActiveActor]); + with0->Spectrum = OtherPCObj->Spectrum; + with0->SpectrumObj = OtherPCObj->SpectrumObj; + } + inherited::ClassMakeLike(OtherObj); +} + + + + +} // namespace PCClass + + + + diff --git a/OpenDSSC/PCElements/PCClass.h b/OpenDSSC/PCElements/PCClass.h new file mode 100644 index 0000000..2c88dbd --- /dev/null +++ b/OpenDSSC/PCElements/PCClass.h @@ -0,0 +1,53 @@ +#ifndef PCClassH +#define PCClassH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElementClass.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" + + +namespace PCClass +{ + + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TPCClass : public CktElementClass::TCktElementClass +{ +public: + typedef CktElementClass::TCktElementClass inherited; +private: +protected: + int ClassEdit(const void* ActivePCObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); + void CountProperties(); // Add no. of intrinsic properties + void DefineProperties(); // Add Properties of this class to propName +public: + int NumPCClassProps; + TPCClass(); + virtual ~TPCClass(); +//__published: +}; + + +} // namespace PCClass + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PCClass; +#endif + +#endif // PCClassH + + + + diff --git a/OpenDSSC/PCElements/PCElement.cpp b/OpenDSSC/PCElements/PCElement.cpp new file mode 100644 index 0000000..d43a911 --- /dev/null +++ b/OpenDSSC/PCElements/PCElement.cpp @@ -0,0 +1,434 @@ + +#pragma hdrstop + +#include "PCElement.h" +#include "DSSGlobals.h" +#include "MeterElement.h" + +using namespace DynamicExp; +using namespace std; + + +namespace PCElement +{ + +//TPCElement::TPCElement(TDSSClass* ParClass) : inherited(ParClass) {} +TPCElement::TPCElement(String ClassName) : inherited(ClassName) {} +TPCElement::TPCElement() {} + + + +TPCElement::TPCElement(TDSSClass* ParClass) + : inherited(ParClass), + FIterminalUpdated(false), + SpectrumObj(nullptr), + MeterObj(nullptr), + SensorObj(nullptr), + FMonObj(nullptr), + Cluster_num(0), + NdNumInCluster(0), + nVLeaders(0), + FMonObj2(nullptr), + cluster_num2(0), + NdNumInCluster2(0), + InjCurrent(nullptr) +{ + Spectrum = "default"; + SpectrumObj = nullptr; // have to allocate later because not guaranteed there will be one now. + SensorObj = nullptr; + MeterObj = nullptr; + InjCurrent = nullptr; + DSSObjType = PC_ELEMENT; + DynamicEq = ""; + DynamicEqObj = NULL; + NumStateVars = 0; + DynamicEqPair.resize(0); + DynamicEqVals.resize(0); + DynOut.resize(0); +} + +TPCElement::~TPCElement() +{ + if(InjCurrent != NULL) + free(InjCurrent); + // inherited::Destroy(); +} + + +// Add injection currents into System currents array + +int TPCElement::InjCurrents(int ActorID) +{ + int result = 0; + int i = 0; + result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + + for(stop = Yorder, i = 1; i <= stop; i++) + { + caccum(with0->Currents[NodeRef[i - 1]], InjCurrent[i - 1]); + } + + } + return result; +} + +void TPCElement::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + DoErrorMsg("PCElement.InjCurrents", (String("Improper call to GetInjCurrents for Element: ") + get_Name() + "."), "Called PCELEMENT class virtual function instead of actual.", 640); +} + +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +// This is called only if we need to compute the terminal currents from the inj currents +// Such as for Harmonic model + +void TPCElement::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + if(FIterminalUpdated) // Just copy iTerminal unless iTerminal=Curr + { + if(Curr != &(Iterminal[0])) + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (Iterminal)[i - 1]; + } + } + } + else + { + int stop = 0; + YPrim->MVmult(Curr, &(Vterminal[0])); + for(stop = Yorder, i = 1; i <= stop; i++) + { + caccum((Curr)[i - 1], cnegate((InjCurrent)[i - 1])); + } + set_ITerminalUpdated(true, ActorID); + } + IterminalSolutionCount[ActorID] = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +/*Gets total Currents going INTO a devices terminals*/ + +void TPCElement::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(Get_Enabled()) + { + if((with0->LastSolutionWasDirect) && (!(with0->IsDynamicModel || with0->IsHarmonicModel))) + + // Take a short cut and get Currents from YPrim only + // For case where model is entirely in Y matrix + { + CalcYPrimContribution(Curr, ActorID); + } + else + { + GetTerminalCurrents(Curr, ActorID); + } /*IF*/ + } + else + // not enabled + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } + } + } /*With*/ + } + catch(exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (string)e.what(), "Inadequate storage allotted for circuit element.", 641); + } +} +//---------------------------------------------------------------------------- +// Evaluates if the value provided corresponds to a constant value or to an operand +// for calculating the value using the simulation results +int TPCElement::CheckIfDynVar(string myVar, int ActorID) +{ + int myOp, Result = 0; + string myValue = ""; + + Result = -1; + if ( ASSIGNED( DynamicEqObj ) ) + { + Result = DynamicEqObj->Get_Var_Idx(myVar); + if ((Result >= 0) && (Result < 50000)) + { + myValue = Parser[ActorID]->MakeString_(); + if (DynamicEqObj->Check_If_CalcValue(myValue, myOp)) + { + // Adss the pair (var index + operand index) + DynamicEqPair.push_back(Result); + DynamicEqPair.push_back(myOp); + } + else + { + // Otherwise, move the value to the values array + DynamicEqVals[Result][0] = Parser[ActorID]->MakeDouble_(); + } + } + else + Result = -1; + } + + return Result; +} + +//---------------------------------------------------------------------------- +//{Returns the names of the variables to be used as outputs for the dynamic expression} +std::string TPCElement::GetDynOutputStr() +{ + int idx = 0; + std::string Result = "["; + + if (ASSIGNED(DynamicEqObj)) + { + for (idx = 0; idx < DynOut.size(); idx++) + { + Result = Result + DynamicEqObj->Get_VarName(DynOut[idx]) + ","; + } + } + + Result = Result + "]"; + + return Result; +} + +//---------------------------------------------------------------------------- +//{Obtains the indexes of the given variables to use them as reference for setting +//the dynamic output for the generator} +void TPCElement::SetDynOutput(string myVar) +{ + int idx = 0; + int VarIdx = 0; + TStringList myStrArray; + + if (ASSIGNED(DynamicEqObj)) + { + DynOut.resize(2); + myStrArray.resize(0); + InterpretTStringListArray(myVar, myStrArray); + for (idx = 0; idx < myStrArray.size(); idx++) + { + myStrArray[idx] = LowerCase(myStrArray[idx]); + VarIdx = DynamicEqObj->Get_Out_Idx(myStrArray[idx]); + if (VarIdx < 0) + // Being here means that the given name doesn't exist or is a constant + DoSimpleMsg("DynamicExp variable " + myStrArray[idx] + " not found or not defined as an output.", 50008); + else + DynOut[idx] = VarIdx; + } + myStrArray.resize(0); + } + else + DoSimpleMsg("A DynamicExp object needs to be assigned to this element before this declaration: DynOut = [" + myVar + "]", 50007); +} + +void TPCElement::CalcYPrimContribution(pComplexArray Curr, int ActorID) +{ + ComputeVterminal(ActorID); + // Apply these voltages to Yprim + YPrim->MVmult(Curr, &(Vterminal[0])); +} + +void TPCElement::InitHarmonics(int ActorID) +{ + + // By default do nothing in the base class +} + +void TPCElement::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(ArrayOffset + 1,Spectrum); + inherited::InitPropertyValues(ArrayOffset + 1); +} + +void TPCElement::InitStateVars(int ActorID) +{ + + // By default do nothing +} + +void TPCElement::IntegrateStates(int ActorID) +{ + + // inherited; + // By default do nothing +} + +int TPCElement::InitializeStates(int ActorID) +{ + + // inherited; + // By default do nothing + return 0; +} + +void TPCElement::CalculateRate(int ActorID) +{ + + // inherited; + // By default do nothing +} + +void TPCElement::StateIntegration(int ActorID) +{ + // inherited; + // By default do nothing + +} + +void TPCElement::StateIntegration_correction(int ActorID) +{ + // inherited; + // By default do nothing + +} + +void TPCElement::GetAllVariables(pDoubleArray States) +{ + + /*Do Nothing*/ +} + +bool TPCElement::get_FITerminalUpdated(int ActorID, int value) +{ + return FIterminalUpdated; +} + +int TPCElement::NumVariables() +{ + int result = 0; + result = 0; + return result; +} + +String TPCElement::VariableName(int i) +{ + String result; + /*Do Nothing*/ + result = ""; + return result; +} + +/*Search through variable name list and return index if found*/ +/*Compare up to length of S*/ + +int TPCElement::LookupVariable(const String s) +{ + int result = 0; + int i = 0; + int TestLength = 0; + int stop = 0; + result = -1; // Returns -1 for error not found + TestLength = (int) s.size(); + for(stop = NumVariables(), i = 1; i <= stop; i++) + { + if(CompareText(VariableName(i).substr(0, TestLength), s) == 0) + { + result = i; + break; + } + } + return result; +} + +bool TPCElement::CheckForGeneratorModel(void) +{ + // + return false; +} + +bool TPCElement::IsGenerator() +{ + // Will get here only for PCelemets that are not generators + return false; +} + +void TPCElement::DumpProperties(System::TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + if(Complete) + { + int stop = 0; + WriteLn(f, L"! VARIABLES"); + for(stop = NumVariables(), i = 1; i <= stop; i++) + { + { Write(f, "! "); Write(f, i, 2); Write(f, ": "); Write(f, VariableName(i)); Write(f, " = "); WriteLn(f, Format("%-.5g", Get_Variable(i))); } + } + } +} + +double TPCElement::Get_Variable(int i) +{ + double result = 0.0; + /*do Nothing here -- up to override function*/ + result = -9999.99; + return result; +} + +void TPCElement::Set_Variable(int i, double Value) +{ + if (i < 0) + { + //Do Nothing + } + else + { + //return Value; + } + /*Do Nothing*/ +} + +void TPCElement::ComputeIterminal(int ActorID) +{ + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) + { + GetCurrents(&(Iterminal[0]), ActorID); + IterminalSolutionCount[ActorID] = ActiveCircuit[ActorID]->Solution->SolutionCount; + } +} + +void TPCElement::ZeroInjCurrent() +{ + int i = 0; + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (InjCurrent)[i - 1] = CZero; + } +} + +void TPCElement::set_ITerminalUpdated(bool Value, int ActorID) +{ + FIterminalUpdated = Value; + if(Value) + IterminalSolutionCount[ActorID] = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + + + + +} // namespace PCElement + + + + diff --git a/OpenDSSC/PCElements/PCElement.h b/OpenDSSC/PCElements/PCElement.h new file mode 100644 index 0000000..1c01a14 --- /dev/null +++ b/OpenDSSC/PCElements/PCElement.h @@ -0,0 +1,114 @@ +#ifndef PCElementH +#define PCElementH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElement.h" +#include "Ucomplex.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "DSSClassDefs.h" +#include "fMonitor.h" +#include "Spectrum.h" +#include "DynamicExp.h" + + +namespace PCElement +{ + + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TPCElement : public TDSSCktElement +{ +public: + typedef TDSSCktElement inherited; +//private: + bool FIterminalUpdated; +//protected: + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); +public: + String Spectrum; + Spectrum::TSpectrumObj* SpectrumObj; /*Upline Energymeter*/ + MeterElement::TMeterElement* MeterObj; + MeterElement::TMeterElement* SensorObj; // Upline Sensor for this element + /*by Dahei*/ + Fmonitor::TFMonitorObj* FMonObj; + int Cluster_num; + int NdNumInCluster; + int nVLeaders; // How many virtual leaders for this pcelement + Fmonitor::TFMonitorObj* FMonObj2; + int cluster_num2; + int NdNumInCluster2; + int NumStateVars; + Ucomplex::pComplexArray InjCurrent; + std::string DynamicEq; + TDynamicExpObj* DynamicEqObj; + std::vector DynamicEqVals; + std::vector DynOut, DynamicEqPair; + + TPCElement(TDSSClass* ParClass); + virtual ~TPCElement(); + void ZeroInjCurrent(); + virtual void InitPropertyValues(int ArrayOffset); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present values of terminal + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present values of terminal + virtual void ComputeIterminal(int ActorID); + virtual int InjCurrents(int ActorID); + void CalcYPrimContribution(Ucomplex::pComplexArray Curr, int ActorID); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + // Sweep solution removed PROCEDURE BackwardSweep;Override; + + // For Harmonics Mode + virtual void InitHarmonics(int ActorID); + void set_ITerminalUpdated(bool Value, int ActorID); + bool get_FITerminalUpdated(int ActorID, int value); + // For Dynamics Mode and Control Devices + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + virtual int InitializeStates(int ActorID); + virtual void CalculateRate(int ActorID); + virtual void StateIntegration(int ActorID); + virtual void StateIntegration_correction(int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual String VariableName(int i); + int LookupVariable(const String s); + virtual bool IsGenerator(); + virtual bool CheckForGeneratorModel(); + + int CheckIfDynVar(string myVar, int ActorID); + void SetDynOutput(string myVar); + string GetDynOutputStr(); + + //__declspec ( property ( get = Get_Variable, put = Set_Variable ) ) double Variable[]; + //// Property ITerminalUpdated:Boolean read FITerminalUpdated write set_ITerminalUpdated; + //__declspec ( property(get = get_FITerminalUpdated, put = set_ITerminalUpdated)) bool ITerminalUpdated[]DECLSPEC_2D; +// TPCElement(TDSSClass* ParClass); + TPCElement(String ClassName); + TPCElement(); +}; + + +} // namespace PCElement + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PCElement; +#endif + +#endif // PCElementH + + + + diff --git a/OpenDSSC/PCElements/PCPrototype.cpp b/OpenDSSC/PCElements/PCPrototype.cpp new file mode 100644 index 0000000..64436a7 --- /dev/null +++ b/OpenDSSC/PCElements/PCPrototype.cpp @@ -0,0 +1,1780 @@ + +#include +#pragma hdrstop + +#include "PCPrototype.h" +#include "../Parser/ParserDel.h" +#include "../Common/DSSClassDefs.h" +#include "../Common/DSSGlobals.h" +#include "../Common/Circuit.h" +#include "../Shared/Command.h" +#include +#include +#include "../Shared/mathutil.h" +#include "../Common/Utilities.h" + +using namespace std; +using namespace d2c_system; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace System::Math; +using namespace System::Sysutils; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace utilities; + +namespace PCPrototype +{ + +TPCPrototypeObj::TPCPrototypeObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TPCPrototypeObj::TPCPrototypeObj(String ClassName) : inherited(ClassName) {} +TPCPrototypeObj::TPCPrototypeObj() {} + + +TPCPrototypeObj* ActivePCPrototypeObj = nullptr; + +/*Typical Uses Clause -- not all may not be needed*/ // DSS parser + // Where class is instantiated + // Global DSS variables + // If access to circuit variables is needed + // DSS command and property support module + // Delphi misc utility functions + // Delphi Math functions + // DSS Math utilities + // DSS misc utility functions +const int NumPropsThisClass = 36; // Set this constant to the actual number of properties you define + // Define any useful module vars here, for example: +complex cBuffer[24/*# range 1..24*/]; // Temp buffer for complex math calcs; allows up to 24-phase models. +complex CDoubleOne = {}; // 1 + j1 (see Initialization section below) + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates main collection handler for all PCPrototype objects + +TPCPrototype::TPCPrototype() +{ + ; // make the base class and init DSSClassType + + // Specify class name and bit mask ID for this class type + // PCPROTOTYPE_ELEMENT must be defined in DSSClassDefs as nn*8 + // First 3 bits are used for base class type (DSSClassType) + Class_Name = L"PCPrototype"; + DSSClassType = DSSClassType + PCPROTOTYPE_ELEMENT; + ActiveElement = 0; // no active elements yet; init to 0 + + /*Initialize any other special variables here*/ + DefineProperties(); // This is where the properties for this class are defined + + // Use the Command processor to manage property names + // PropertyName is an array of String defined in DefineProperties + CommandList = new TCommandList(SLICE((*PropertyName), NumProperties)); + CommandList->set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TPCPrototype::~TPCPrototype() +{ + + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is where the properties are defined, assigned names, indexes, and help strings +// The Help strings will automatically show up when the Help is invoked + +void TPCPrototype::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Refer to other classes for alternative methods of assigning properties + // This example uses the AddProperty function to assign Name, Index, and Help string + // in one statement. + + // First argument is string name of the property + // Second argument is the index for the CASE statement + // Third argument is help string + + // DSS properties are accessed in sequence if the property name is not explicitly specified. + // The advantage of using the AddProperty function is that you may change the sequence simply + // by shuffling the order of the definitions and you do not have to change the index in the CASE + // statement in the EDIT function + + // Define Property names, for example (from Generator class) + AddProperty(L"phases", 1, L"Number of Phases, this PCPrototype. Power is evenly divided among phases."); + AddProperty(L"bus1", 2, L"Bus to which the PCPrototype is connected. May include specific node specification."); + AddProperty(L"kv", 3, L"Nominal rated (1.0 per unit) voltage, kV, for PCPrototype. For 2- and 3-phase PCPrototypes, specify phase-phase kV. " + L"Otherwise, specify actual kV across each branch of the PCPrototype. " + L"If wye (star), specify phase-neutral kV. " + L"If delta or phase-phase connected, specify phase-phase kV."); // line-neutral voltage// base voltage + AddProperty(L"kW", 4, String(L"Total base kW for the PCPrototype. A positive value denotes power coming OUT of the element, ") + CRLF + + L"which is the opposite of a load. This value is modified depending on the dispatch mode. " + + L"Unaffected by the global load multiplier and growth curves. " + + L"If you want there to be more generation, you must add more PCPrototypes or change this value."); + + + + + /*...*/ + /*etc.*/ + + + + + // Finally, we have to pick up any properties that were inherited + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // You can optionally override default help string of an inherited property, for example + (*PropertyHelp)[NumPropsThisClass + 1 - 1] = L"Name of harmonic voltage or current spectrum for this PCPrototype. " + L"Voltage behind Xd\" for machine - default. Current injection for inverter. " + L"Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This function is called by the DSS whenever a New PCPrototype... command is encountered + +int TPCPrototype::NewObject(const String ObjName) +{ + int result = 0; + // Make a new PCPrototype and add it to PCPrototype class list + /*# with ActiveCircuit do */ + { + auto& with0 = ActiveCircuit; + ActiveCktElement = new TPCPrototypeObj(this, ObjName); + result = AddObjectToList(ActiveDSSObject[0]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// This is a typical helper function found in many DSS circuit element class +// for defining the number of conductors per terminal (Nconds) based on Y or delta connection + +void TPCPrototype::SetNcondsForConnection() +{ + /*# with ActivePCPrototypeObj do */ + { + auto with0 = ActivePCPrototypeObj; + switch(Connection) + { + case 0: + with0->Set_Nconds(Fnphases + 1); + break; // Wye connection (has a neutral terminal) + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: // Delta connection + with0->Set_Nconds(Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); // no neutral for this connection + break; + } + break; + default: + ; + break; + } + } +} + + + +//- - - - - - - - - - - - -MAIN EDIT FUNCTION - - - - - - - - - - - - - - - + + +// This function is the heart of the property managment for this class + +int TPCPrototype::Edit() +{ + int result = 0; // Define some local vars for handling parser results + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + +// The Edit function starts where the Parser is presently pointing and +// manages the parsing of the rest of the command line in the parser. + +// The DSS executive processes the command verb on the front of the line and +// then passes control to the appropriate Edit function + + // set the present element active + // and continue parsing with contents of Parser + ActivePCPrototypeObj = &ElementList.Get_Active(); + ActiveCircuit.ActiveCktElement = ActivePCPrototypeObj; + result = 0; + /*# with ActivePCPrototypeObj do */ + { + auto with0 = ActivePCPrototypeObj; + // peel off the next token on the edit line + ParamPointer = 0; + ParamName = Parser.NextParam; + Param = Parser.StrValue; + while(Param.Length() > 0) + + // Find the index for the CASE statement + // If property is not named, just increment the index to the next property + { + if(ParamName.Length() == 0) + ++ParamPointer; + else + ParamPointer = CommandList->Getcommand(ParamName); + + // Update the PropertyValy for this property + // Actual index is mapped via PropertyIdxMap array for this class + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->PropertyValue[(*PropertyIdxMap)[ParamPointer - 1]] = Param; + else + DoSimpleMsg(String(L"Unknown parameter \"") + ParamName + + L"\" for PCPrototype \"" + + with0->Name + + L"\"", 560); + + // --------------- MAIN CASE STATEMENT ---------------------- + if(ParamPointer > 0) + switch((*PropertyIdxMap)[ParamPointer - 1]) + { + // since we used AddProperty function to define properties, have to + // use PropertyIdxMap to map to the correct Case index + case 0: + DoSimpleMsg(String(L"Unknown parameter \"") + ParamName + + L"\" for Object \"" + + Class_Name + + L"." + + with0->Name + + L"\"", 561); + break; + case 1: + with0->NPhases = Parser.IntValue; + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case 3: + Set_PresentkV(Parser.DblValue); + break; + + /*...*/ + /*etc.*/ + + /*One case for each property*/ + // Handle Inherited properties + default: + ClassEdit(ActivePCPrototypeObj, ParamPointer - NumPropsThisClass); + break; + } + + // ---------------- SIDE EFFECTS CASE STATEMENT --------------------- + // This case statment handles any side effects from setting a property + // (for example, from Generator) + if(ParamPointer > 0) + switch((*PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + + // keep kvar nominal up to date with kW and PF + case 4: case 5: + SyncUpPowerQuantities; + break; + + /*etc.*/ + default: + ; + break; + } + + // Get next token off Parser and continue editing properties + ParamName = Parser.NextParam; + Param = Parser.StrValue; + } + + // After editing is complete, the typical next step is to call the RecalcElementData function + with0->RecalcElementData(); + with0->YPrimInvalid[ActorID] = true; // Setting this flag notifies the DSS that something has changed + // and the Yprim will have to be rebuilt + } + return result; +} + +//---------------------------------------------------------------------------- + + +// This function should be defined to handle the Like property inherited from +// the base class. + +// The function copies the essential properties of another object of this class + +int TPCPrototype::MakeLike(const String OtherPCPrototypeName) +{ + int result = 0; + TPCPrototypeObj* OtherPCPrototype = nullptr; + int i = 0; + result = 0; + /*See if we can find this PCPrototype name in the present collection*/ + OtherPCPrototype = ((TPCPrototypeObj*) Find(OtherPCPrototypeName)); + if(OtherPCPrototype != nullptr) + /*# with ActivePCPrototypeObj do */ + { + auto with0 = ActivePCPrototypeObj; // skip if not found + + // You should first set the basic circuit element properties, for example + int stop = 0; + if(with0->Fnphases != OtherPCPrototype->Fnphases) + { + with0->NPhases = OtherPCPrototype->Fnphases; + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->YPrimInvalid[ActorID] = true; + } + + // Then set other property values, for example from Generator + GenVars.kVGeneratorBase = OtherPCPrototype->GenVars.kVGeneratorBase; + VBase = OtherPCPrototype->VBase; + kWBase = OtherPCPrototype->kWBase; + kvarBase = OtherPCPrototype->kvarBase; + UserModel.Name = OtherPCPrototype->UserModel.Name; // Connect to user written models + + /*...*/ + /*etc.*/ + + + + + // Do inherited properties + ClassMakeLike(OtherPCPrototype); + + // Finally initialize all the property value strings to be the same as + // the copied element + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (*with0->FPropertyValue)[i - 1] = (*OtherPCPrototype->FPropertyValue)[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String(L"Error in Load MakeLike: \"") + OtherPCPrototypeName + + L"\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + + +// Optional function if you want to do anything to initialize objects of this class + +int TPCPrototype::Init(int Handle) +{ + int result = 0; + TPCPrototypeObj* P = nullptr; + + /* For example: set up for randomization*/ + if(Handle == 0) // init all + { + P = &ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = &ElementList.Get_Next(); + } + } + else + { + Active = Handle; + P = ((TPCPrototypeObj*) GetActiveObj()); + P->Randomize(0); + } + result = 0; + return result; +} + + +//------------------------- MAIN OBJECT CONSTRUCTOR --------------------- + +TPCPrototypeObj::TPCPrototypeObj(TDSSClass* ParClass, const String PCPrototypeObjName) + : inherited(ParClass) +{ + Name = LowerCase(PCPrototypeObjName); + DSSObjType = ParClass->DSSClassType; // Same as Parent Class + + // Set some basic circuit element properties + NPhases = 3; // typical DSS default for a circuit element + Fnconds = 4; // defaults to wye + Yorder = 0; // To trigger an initial allocation + NTerms = 1; // forces allocations of terminal quantities + + /*Initialize variables for this object, for example*/ + kvarMax = kvarBase * 2.0; + kvarMin = -kvarMax; + PFNominal = 0.88; + YearlyShape = L""; + YearlyShapeObj = nullptr; // if YearlyShapeobj = nil then the load alway stays nominal * global multipliers + Vpu = 1.0; + VBase = 7200.0; + Vminpu = 0.90; + Vmaxpu = 1.10; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + + + /*etc.*/ + + + + + // If you support a user-written DLL, Initialize here + // For example, from Generator + UserModel = new TGenUserModel(GenVars); + + + + // call the procedure to set the initial property string values + InitPropertyValues(0); + + // Update anything that has to be calculated from property values + RecalcElementData(); +} + + +//---------------------------------------------------------------------------- + + +// Free everything here that needs to be freed +// If you allocated anything, dispose of it here + +TPCPrototypeObj::~TPCPrototypeObj() +{ + delete UserModel; // If you have a user-written DLL + // inherited::Destroy(); // This will take care of most common circuit element arrays, etc. +} + + +//---------------------------------------------------------------------------- + + +// typical proc for handling randomization in DSS fashion + +void TPCPrototypeObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + RandomMult = Gauss(YearlyShapeObj.Mean(), YearlyShapeObj.StdDev()); + break; + case UNIFORM: + RandomMult = Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + RandomMult = QuasiLogNormal(YearlyShapeObj.Mean()); + break; + default: + ; + break; + } +} + + +//---------------------------------------------------------------------------- + + +// Anything that needs to re-calculated after an Edit + +void TPCPrototypeObj::RecalcElementData() +{ + + + + /*For example:*/ + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + + /*...*/ + /*etc.*/ + + // For example, find specified Spectrum object and report error if not found + SpectrumObj = SpectrumClass.Find(Spectrum); + if(SpectrumObj == nullptr) + DoSimpleMsg(String(L"ERROR! Spectrum \"") + Spectrum + L"\" Not Found.", 566); + + // For PC elements, a good idea to reallocate InjCurrent in case Yorder has changed + InjCurrent = (pComplexArray) ReallocMemory(InjCurrent, sizeof((*InjCurrent)[1 - 1]) * Yorder); + + /*Update any user-written models, for example*/ + if(UserModel.Get_Exists()) + UserModel.FUpdateModel; +} + +//---------------------------------------------------------------------------- + + +/*A typical helper function for PC elements to assist in the computation + of Yprim +*/ + +void TPCPrototypeObj::CalcYPrimMatrix(TcMatrix* Ymatrix) +{ + complex Y = {}; + complex Yij = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit.Solution.Frequency; + FreqMultiplier = FYprimFreq / BaseFrequency; // ratio to adjust reactances for present solution frequency + /*# with ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit.Solution; + if(IsDynamicModel | IsHarmonicModel) + // for Dynamics and Harmonics modes use constant equivalent Y + + // Example from Generator + // If the generator is on, use equivalent Y else some very small value + { + int stop = 0; + if(GenON) // L-N value computed in initialization routines + Y = Yeq; + else + Y = cmplx(Epsilon, 0.0); + if(Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; // adjust for frequency + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); // sets the element + Ymatrix->AddElement(Fnconds, Fnconds, Y); // sums the element + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(i, i, Y); // put it in again + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + else + + + // Typical code for a regular power flow model + // Example from Generator object + + /*Yeq is typically expected as the equivalent line-neutral admittance*/ + { + Y = cnegate(Yeq); // negate for generation Yeq is L-N quantity + + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + switch(Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + with1->AddElement(Fnconds, Fnconds, Y); + with1->SetElemsym(i, Fnconds, Yij); + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } /*ELSE IF Solution.mode*/ +} + + +//---------------------------------------------------------------------------- + + +// Required routine to calculate the primitive Y matrix for this element + +// This example uses a helper function (CalcYPrimMatrix) to keep the code +// here clean + +void TPCPrototypeObj::CalcYPrim() +{ + int i = 0; + +/* + There are three Yprim matrices that could be computed: + + YPrim_Series: Used for zero-load solutions to initialize the first guess + YPrim_Shunt: Equivalent Y in shunt with power system + For PC elements, this is typically the main YPrim + YPrim: Generally the sum of the other two; the total YPrim +*/ + + // Typical PC Elements build only shunt Yprim + // Also, build a dummy Yprim Series so that CalcVoltagebases does not fail + + // First clear present value; redefine if necessary + // Note: Complex matrix (TcMatrix -- see uCmatrix.pas) is used for this + int stop = 0; + if(YPrimInvalid[ActorID]) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + + /*do whatever you have to do to determine Yeq here*/ + + // call helper routine to compute YPrim_Shunt + CalcYPrimMatrix(YPrim_Shunt); + + // Set YPrim_Series based on a small fraction of the diagonals of YPrim_shunt + // so that CalcVoltages doesn't fail + // This is just one of a number of possible strategies but seems to work most of the time + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + + // copy YPrim_shunt into YPrim; That's all that is needed for most PC Elements + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors -- done in base class + inherited::CalcYPrim(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Most PC Elements should have a routine like this to make the current injections into the proper place + + /*Add the current into the proper array position according to connection*/ + + /* + This example is from GENERATOR + Reverse of similar routine in LOAD (Cnegates are switched) + */ + +void TPCPrototypeObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum((*TermArray)[i - 1], Curr); + caccum((*TermArray)[Fnconds - 1], cnegate(Curr)); // Neutral + } + break; //DELTA + case 1: + { + caccum((*TermArray)[i - 1], Curr); + j = i + 1; + if(j > Fnconds) + j = 1; + caccum((*TermArray)[j - 1], cnegate(Curr)); + } + break; + default: + ; + break; + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* + This routine is an example from Generator to illustrate how to compute currents + for PC elements. This is a common constant P + jQ model. +*/ + +/*Compute the total terminal current for Constant PQ*/ + +void TPCPrototypeObj::DoConstantPQGen() +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + + // First compute the contribution due to Yprim matrix + int stop = 0; + CalcYPrimContribution(InjCurrent); + + // Zero out the Iterminal array to hold the results of this calculation + ZeroITerminal(); + // get actual voltage across each phase of the load and put into VTerminal array + CalcVTerminalPhase; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (*Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: /*Wye*/ + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(Yeq95, V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, V); + else + /*# with GenVars do */ + { + auto& with0 = GenVars; + Curr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; /*Delta*/ + case 1: + { + Vmag = Vmag / SQRT3; // L-N magnitude + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cdivreal(Yeq95, 3.0), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cdivreal(Yeq105, 3.0), V); + else + /*# with GenVars do */ + { + auto& with1 = GenVars; + Curr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; + default: + ; + break; + } + + // Add into ITerminal (initialized above) + StickCurrInTerminalArray(Iterminal, cnegate(Curr), i); // Put into Terminal array taking into account connection + IterminalUpdated = true; + // Now, add into InjCurrent array. This is used in the Normal solution algorithm + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* This is an example taken from Generator illustrating how a PC element might + handle Dynamics mode with a Thevenin equivalent + + Also illustrates the computation of symmetrical component values +*/ + +/*Compute Total Current and add into InjTemp*/ + +void TPCPrototypeObj::DoDynamicMode() +{ + int i = 0; + complex V012[4] = { CZero, CZero, CZero, CZero, }; + complex I012[4] = { CZero, CZero, CZero, CZero, }; + + // Start off by getting the current in the admittance branch of the model + int stop = 0; + CalcYPrimContribution(InjCurrent); // Init InjCurrent Array + + /*Inj = -Itotal (in) - Yprim*Vtemp*/ + /*# with GenVars do */ + { + auto& with0 = GenVars; + + // Convert Terminal voltages to symmetrical component + Phase2SymComp(Vterminal, &V012[0]); + + // Positive Sequence Contribution to Iterminal + + // Compute present value of VThev + CalcVthev_Dyn; // Update for latest phase angle + + // Positive Sequence Contribution to Iterminal + // Use Xd' for pos seq; Xd" for neg seq + I012[1] = cdiv(csub(V012[1], Vthev), cmplx(0.0, Xdp)); + I012[2] = cdiv(V012[2], cmplx(0.0, Xdpp)); + if(Connection == 1) + I012[0] = CZero; + else + I012[0] = cdiv(V012[0], cmplx(0.0, Xdpp)); + + // Convert back to phase components + SymComp2Phase(Iterminal, &I012[0]); + + // Neutral current, if any + if(Connection == 0) + (*Iterminal)[Fnconds - 1] = cnegate(cmulreal(I012[0], 3.0)); + } + IterminalUpdated = true; + + /*Add it into inj current array*/ + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((*InjCurrent)[i - 1], cnegate((*Iterminal)[i - 1])); + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* + Example taken from Generator illustrating how a PC element might handle + current calcs for Harmonics mode + + Note: Generator objects assume a Thevenin model (voltage behind and impedance) + while Load objects assume the Spectrum applies to a Norton model injection current +*/ + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TPCPrototypeObj::DoHarmonicMode() +{ + int i = 0; + complex e = {}; + double GenHarmonic = 0.0; + + // Set the VTerminal array + ComputeVterminal(); + /*# with ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit.Solution; + int stop = 0; + GenHarmonic = double(Frequency) / GenFundamental; // harmonic based on the fundamental for this object + // get the spectrum multiplier and multiply by the V thev (or Norton current for load objects) + e = cmulreal(SpectrumObj->GetMult(GenHarmonic), VThevHarm); // Get base harmonic magnitude + RotatePhasorRad(e, GenHarmonic, ThetaHarm); // Time shift by fundamental frequency phase shift + + // Put the values in a temp complex buffer + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, GenHarmonic, -120.0); // Assume 3-phase PCPrototype + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (*Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + // In this case the injection currents are simply Yprim(frequency) times the voltage buffer + // Refer to Load.Pas for load-type objects + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* + Many PC Element models will contain a Proc like this to compute terminal voltages + differently for Y or Delta connections +*/ + +void TPCPrototypeObj::CalcVTerminalPhase() +{ + int i = 0; + int j = 0; + +/* Establish phase voltages and stick in Vterminal*/ + switch(Connection) + { + case 0: + { + /*# with ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit.Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (*Vterminal)[i - 1] = VDiff((*NodeRef)[i - 1], (*NodeRef)[Fnconds - 1]); + } + } + } + break; + case 1: + { + /*# with ActiveCircuit.Solution do */ + { + auto& with1 = ActiveCircuit.Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; + (*Vterminal)[i - 1] = VDiff((*NodeRef)[i - 1], (*NodeRef)[j - 1]); + } + } + } + break; + default: + ; + break; + } + + + // It is often advantageous to keep track of which solution VTerminal applies to + // You can use this to avoid unnecessary recalcs of Vterminal if the solution hasn't changed + PCPrototypeSolutionCount = ActiveCircuit.Solution.SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* this is just the standard routine to put terminal voltages in an array + But it also keeps track of the solution count for computational efficiency +*/ + +void TPCPrototypeObj::CalcVterminal() +{ + ComputeVterminal(); + PCPrototypeSolutionCount = ActiveCircuit.Solution.SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Main dispatcher for computing PC Element currnts + +// Calculates PCPrototype current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TPCPrototypeObj::CalcPCPrototypeModelContribution() +{ + IterminalUpdated = false; + /*# with ActiveCircuit, ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit; + auto& with1 = ActiveCircuit.Solution; + if(IsDynamicModel) + DoDynamicMode; + else + { + if(IsHarmonicModel && (Frequency != Fundamental)) + DoHarmonicMode; + else + + // compute currents and put into InjTemp array; + { + switch(PCPrototypeModel) + { + case 1: + DoConstantPQGen; + break; // for example, from Generator + /*etc.*/ + case 2: + ; + break; // Different models + + // Put a default model proc call here + default: + ; + break; + } + } /*ELSE*/ + } + } /*WITH*/ + + /*When this is done, ITerminal is up to date*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Main procedure for controlling computation of InjCurrent array + +// InjCurrent is difference between currents in YPrim and total terminal current + +void TPCPrototypeObj::CalcInjCurrentArray() +{ + + +// You usually will want some logic like this + + // If the element is open, just zero the array and return + if(PCPrototypeSwitchOpen) + // otherwise, go to a routine that manages the calculation + ZeroInjCurrent(); + else + CalcPCPrototypeModelContribution; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// This function controls the calculation of the total terminal currents + +// Note that it only does something if the solution count has changed. +// Otherwise, Iterminal array already contains the currents + +void TPCPrototypeObj::GetTerminalCurrents(pComplexArray Curr) +{ + /*# with ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit.Solution; + if(IterminalSolutionCount != ActiveCircuit.Solution.SolutionCount) // recalc the contribution + // You will likely want some logic like this + { + if(!PCPrototypeSwitchOpen) + CalcPCPrototypeModelContribution; // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr); // add in inherited contribution + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Required function for managing computing of InjCurrents + +int TPCPrototypeObj::InjCurrents() +{ + int result = 0; + /*# with ActiveCircuit.Solution do */ + { + auto& with0 = ActiveCircuit.Solution; + + // Generators and Loads use logic like this: + // If LoadsNeedUpdating Then SetNominalGeneration; // Set the nominal kW, etc for the type of solution being done + + // call the main function for doing calculation + CalcInjCurrentArray; // Difference between currents in YPrim and total terminal current + + + // Add into System Injection Current Array + result = inherited::InjCurrents(); + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Gets the currents for the last solution performed + +// Do not call anything that may change the basic element values from the last solution + +void TPCPrototypeObj::GetInjCurrents(pComplexArray Curr) +{ + int i = 0; + CalcInjCurrentArray; // Difference between currents in YPrim and total current + try + // an exception here generally means an array boundary overrun + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (*Curr)[i - 1] = (*InjCurrent)[i - 1]; + } + } + catch(Exception* e) + { + DoErrorMsg(String(L"PCPrototype Object: \"") + Name + + L"\" in GetInjCurrents function.", e->Message, L"Current buffer not big enough.", 568); + } +} +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/* + This procedure is require to respond to various commands such as Dump that + write all the device's property values to a file. +*/ + +void TPCPrototypeObj::DumpProperties(d2c_system::TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + + /*Write out any specials here, usually preceded by a "!"*/ + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; // Map to get proper index into property value array + switch(Idx) + { + case 34: case 36: + + /*Trap any specials here, such as values that are array properties, for example*/ + { Write(f, L"~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L"=("); Write(f, PropertyValue[Idx]); WriteLn(f, L')'); } + break; + default: + { Write(f, L"~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, PropertyValue[Idx]); } + break; + } + } + } + WriteLn(f); +} + +/*Procedure to initialize for Harmonics solution*/ + +/*This example is extracted from Generator and constructs a Thevinen equivalent. + Refer to Load for how to do a Norton equivalent + */ + +void TPCPrototypeObj::InitHarmonics() +{ + complex e = {}; + complex Va = {}; + YPrimInvalid[ActorID] = true; // Force rebuild of YPrims + GenFundamental = ActiveCircuit.Solution.Frequency; // Whatever the frequency is when we enter here. + /*# with GenVars do */ + { + auto& with0 = GenVars; + + // Xd" is used for harmonics analysis for generators + Yeq = cinv(cmplx(0.0, Xdpp)); // used for current calcs Always L-N + + /*Compute reference Thevinen voltage from phase 1 current*/ + if(GenON) + { + ComputeIterminal(); // Get present value of current + /*# with ActiveCircuit.Solution do */ + { + auto& with1 = ActiveCircuit.Solution; + switch(Connection) + { + case 0: /*wye - neutral is explicit*/ + { + Va = csub(NodeV[(*NodeRef)[1 - 1]], NodeV[(*NodeRef)[Fnconds - 1]]); + } + break; /*delta -- assume neutral is at zero*/ + case 1: + { + Va = NodeV[(*NodeRef)[1 - 1]]; + } + break; + default: + ; + break; + } + } + e = csub(Va, cmul((*Iterminal)[1 - 1], cmplx(0.0, Xdpp))); + VThevHarm = cabs(e); // establish base mag and angle + ThetaHarm = cang(e); + } + else + + // If Generator is off, just set to zero + { + VThevHarm = 0.0; + ThetaHarm = 0.0; + } + } +} + +// required procedure to initialize the string value of the properties + +void TPCPrototypeObj::InitPropertyValues(int ArrayOffset) +{ + + // Some examples + PropertyValue[1] = L'3'; //'phases'; + PropertyValue[2] = GetBus(1); //'bus1'; + PropertyValue[3] = L"12.47"; + /*...*/ + PropertyValue[26] = Format(L"%-g", ARRAYOFCONST((GenVars.kVArating))); + /*...*/ + PropertyValue[33] = L""; // null string + + +/*Call inherited function to init inherited property values*/ + inherited::InitPropertyValues(NumPropsThisClass); +} + +// Initialize state variables, principally for Dynamics analysis + +// Example here is standard Generator model; Refer to other modules for other approaches. +// This model uses symmetrical components + +void TPCPrototypeObj::InitStateVars() +{ + complex VNeut = {}; + complex Edp = {}; + int i = 0; + complex V012[3/*# range 0..2*/]; + complex I012[3/*# range 0..2*/]; + complex Vabc[3/*# range 1..3*/]; + YPrimInvalid[ActorID] = true; // Force rebuild of YPrims + /*# with GenVars do */ + { + auto& with0 = GenVars; + Yeq = cinv(cmplx(0.0, Xdp)); + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if(GenON) + /*# with ActiveCircuit.Solution do */ + { + auto& with1 = ActiveCircuit.Solution; + int stop = 0; + ComputeIterminal(); + Phase2SymComp(Iterminal, (pComplexArray) &I012); + // Voltage behind Xdp (transient reactance), volts + switch(Connection) + { + case 0: + VNeut = NodeV[(*NodeRef)[Fnconds - 1]]; + break; + default: + VNeut = CZero; + break; + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Vabc[i - 1] = NodeV[(*NodeRef)[i - 1]]; + } // Wye Voltage + Phase2SymComp((pComplexArray) &Vabc, (pComplexArray) &V012); + Edp = csub(V012[1], cmul(I012[1], cmplx(0.0, Xdp))); // Pos sequence + VthevMag = cabs(Edp); + Theta = cang(Edp); + dTheta = 0.0; + w0 = TwoPi * ActiveCircuit.Solution.Frequency; + // recalc Mmass and D in case the frequency has changed + /*# with GenVars do */ + { + auto& with2 = GenVars; + GenVars.Mmass = 2.0 * GenVars.Hmass * GenVars.kVArating * 1000.0 / (w0); // M = W-sec + D = Dpu * kVArating * 1000.0 / (w0); + } + Pshaft = -Get_Power(1, ActiveActor).re; // Initialize Pshaft to present power Output + Speed = 0.0; // relative to synch speed + dSpeed = 0.0; + + // Init User-written models + //Ncond:Integer; V, I:pComplexArray; const X,Pshaft,Theta,Speed,dt,time:Double + /*# with ActiveCircuit.Solution do */ + { + auto& with3 = ActiveCircuit.Solution; + if(GenModel == 6) + { + if(UserModel.Get_Exists()) + UserModel.FInit(Vterminal, Iterminal); + } + } + } + else + { + Vthev = CZero; + Theta = 0.0; + dTheta = 0.0; + w0 = 0; + Speed = 0.0; + dSpeed = 0.0; + } + } /*With*/ +} + +/* + This is a virtual function. You do not need to write this routine + if you are not integrating state variables in dynamics mode. +*/ + +// Integrate state variables for Dynamics analysis +// Example from Generator + +// Illustrates use of debug tracing + +// Present technique is a predictor-corrector trapezoidal rule + +void TPCPrototypeObj::IntegrateStates() +{ + complex TracePower = {}; + // Compute Derivatives and then integrate + ComputeIterminal(); + +// Check for user-written exciter model. + //Function(V, I:pComplexArray; const Pshaft,Theta,Speed,dt,time:Double) + /*# with ActiveCircuit.Solution, GenVars do */ + { + auto& with0 = ActiveCircuit.Solution; + auto& with1 = GenVars; + + + // handling of iteration flag + /*# with DynaVars do */ + { + auto& with2 = DynaVars; + if(IterationFlag == 0) /*First iteration of new time step*/ + { + ThetaHistory = Theta + 0.5 * h * dTheta; + SpeedHistory = Speed + 0.5 * h * dSpeed; + } + } + + // Compute shaft dynamics + TracePower = TerminalPowerIn(Vterminal, Iterminal, Fnphases); + dSpeed = (Pshaft + TracePower.re - D * Speed) / Mmass; + dTheta = Speed; + + // Trapezoidal method + /*# with DynaVars do */ + { + auto& with3 = DynaVars; + Speed = SpeedHistory + 0.5 * h * dSpeed; + Theta = ThetaHistory + 0.5 * h * dTheta; + } + + // Write Dynamics Trace Record + if(DebugTrace) + { + Append(Tracefile); + IOResultToException(); + { Write(Tracefile); Write(Format(L"t=%-.5g ", ARRAYOFCONST((DynaVars.T)))); } + { Write(Tracefile); Write(Format(L" Flag=%d ", ARRAYOFCONST((DynaVars.IterationFlag)))); } + { Write(Tracefile); Write(Format(L" Speed=%-.5g ", ARRAYOFCONST((Speed)))); } + { Write(Tracefile); Write(Format(L" dSpeed=%-.5g ", ARRAYOFCONST((dSpeed)))); } + { Write(Tracefile); Write(Format(L" Pshaft=%-.5g ", ARRAYOFCONST((Pshaft)))); } + { Write(Tracefile); Write(Format(L" P=%-.5g Q= %-.5g", ARRAYOFCONST((TracePower.re, TracePower.im)))); } + { Write(Tracefile); Write(Format(L" M=%-.5g ", ARRAYOFCONST((Mmass)))); } + WriteLn(Tracefile); + CloseFile(Tracefile); + } + + // Handline of user models, if any + if(GenModel == 6) + { + if(UserModel.Get_Exists()) + UserModel.Integrate; + } + } +} + +/* + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +/* + Return i-th state variable one at a time + Mainly for reports +*/ + +double TPCPrototypeObj::Get_Variable(int i) +{ + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if(i < 1) + return result; // Someone goofed + /*# with GenVars do */ + { + auto& with0 = GenVars; + switch(i) + { + case 1: + // for example, the intrinsic state variables of a Generator + // change to whatever is appropriate to report in desired units + result = double((w0 + Speed)) / TwoPi; + break; // Frequency, Hz + case 2: + result = (Theta) * RadiansToDegrees; + break; // Report in Deg + case 3: + result = cabs(Vthev) / VBase; + break; // Report in pu + case 4: + result = Pshaft; + break; + case 5: + result = dSpeed * RadiansToDegrees; + break; // Report in Deg 57.29577951 + case 6: + result = dTheta; + break; + default: + if(UserModel.Get_Exists()) + { + n = UserModel.FNumVars; + k = (i - NumPCPrototypeVariables); + if(k <= n) + { + result = UserModel.FGetVariable(k); + return result; + } + } + break; + } + } + return result; +} + +/* + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +// Sets i-th state variable to specified Value + +void TPCPrototypeObj::Set_Variable(int i, double Value) +{ + int n = 0; + int k = 0; + n = 0; + if(i < 1) + return; // Someone goofed + /*# with GenVars do */ + { + auto& with0 = GenVars; + switch(i) + { + case 1: + // for example, the intrinsic state vars of a generator + // change to appropriate values + Speed = (Value - w0) * TwoPi; + break; + case 2: + Theta = Value / RadiansToDegrees; + break; // deg to rad + case 3: + ; + break;// meaningless to set Vd := Value * vbase; // pu to volts + case 4: + Pshaft = Value; + break; + case 5: + dSpeed = Value / RadiansToDegrees; + break; + case 6: + dTheta = Value; + break; + default: + if(UserModel.Get_Exists()) + { + n = UserModel.FNumVars; + k = (i - NumPCPrototypeVariables); + if(k <= n) + { + UserModel.FSetVariable(k, Value); + return; + } + } + break; + } + } +} + +/* + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +// Return all state variables in double array (allocated by calling function) + +void TPCPrototypeObj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int n = 0; + int stop = 0; + n = 0; + for(stop = NumPCPrototypeVariables, i = 1; i <= stop; i++) + { + (*States)[i - 1] = Variable[i]; + } + if(UserModel.Get_Exists()) + { + n = UserModel.FNumVars; + UserModel.FGetAllVars(&(*States)[NumPCPrototypeVariables + 1 - 1]); + } +} + +/* + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +// Return the number of state variables + +// Note: it is not necessary to define any state variables + +int TPCPrototypeObj::NumVariables() +{ + int result = 0; + result = NumPCPrototypeVariables; + if(UserModel.Get_Exists()) + result = result + UserModel.FNumVars; + return result; +} + +/* + This is a virtual function. You do not need to write this routine + if you are not defining state variables. +*/ + +// Returns the i-th state variable in a string + +String TPCPrototypeObj::VariableName(int i) +{ + String result; + const int BuffSize = 255; + int n = 0; + int I2 = 0; + Char Buff[256/*# range 0..BuffSize*/]; + PChar PName = nullptr; + n = 0; + if(i < 1) + return result; // Someone goofed + switch(i) + { + case 1: + // For example, these are the 6 intrinsic state variables of a generator + // Change to appropriate names + result = L"Frequency"; + break; + case 2: + result = L"Theta (Deg)"; + break; + case 3: + result = L"Vd"; + break; + case 4: + result = L"PShaft"; + break; + case 5: + result = L"dSpeed (Deg/sec)"; + break; + case 6: + result = L"dTheta (Deg)"; + break; + default: + if(UserModel.Get_Exists()) + { + PName = (PChar) &Buff; + n = UserModel.FNumVars; + I2 = i - NumPCPrototypeVariables; + if(I2 <= n) + { + UserModel.FGetVarName(I2, PName, BuffSize); + result = PName; + return result; + } + } + break; + } + return result; +} + +// Return i-th property value as a string + +String TPCPrototypeObj::GetPropertyValue(int Index) +{ + String result; + result = L""; // Init the string + switch(Index) + { + case 4: + // Put special cases here + // often a good idea to convert numeric values to strings, for example + result = Format(L"%.6g", ARRAYOFCONST((kWBase))); + break; + case 5: + result = Format(L"%.6g", ARRAYOFCONST((PFNominal))); + break; + + /*...*/ + // Some values must be enclosed in parens or brackets + case 34: + result = String(L"(") + inherited::GetPropertyValue(Index) + L")"; + break; + + // The default is to just return the current string value of the property + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +/* + This is a virtual function. You do not need to write this routine + if the base class function will suffice. +*/ + +// Routine to convert existing three-phase models to a single-phase positive- +// sequence model + +void TPCPrototypeObj::MakePosSequence() +{ + String s; + double V = 0.0; + +/* + The usual technique is to create a new property editing string + based on the present values of properties. Once the string is + created, it is pushed into the Parser and the Edit routine for this + class is invoked. + + Thus, the positive sequence model is created in memory. Do a + "Save Circuit" command to save the model that is created. Some + editing of the resulting scripts will likely be required. Not all + elements have an obvious positive sequence equivalent. +*/ + + + // example from Generator class + // Modify as necessary + s = L"Phases=1 conn=wye"; // Positive sequence model is 1-phase wye + + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = double(GenVars.kVGeneratorBase) / SQRT3; + else + V = GenVars.kVGeneratorBase; + s = s + Format(L" kV=%-.5g", ARRAYOFCONST((V))); + + // Divide the load by no. phases + if(Fnphases > 1) + { + s = s + Format(L" kW=%-.5g PF=%-.5g", ARRAYOFCONST((double(kWBase) / Fnphases, PFNominal))); + if(((*PrpSequence)[19 - 1] != 0) || ((*PrpSequence)[20 - 1] != 0)) + s = s + + Format(L" maxkvar=%-.5g minkvar=%-.5g", ARRAYOFCONST((double(kvarMax) / Fnphases, double(kvarMin) / Fnphases))); + if((*PrpSequence)[26 - 1] > 0) + s = s + Format(L" kva=%-.5g ", ARRAYOFCONST((double(GenVars.kVArating) / Fnphases))); + if((*PrpSequence)[27 - 1] > 0) + s = s + Format(L" MVA=%-.5g ", ARRAYOFCONST((double(GenVars.kVArating) / 1000.0 / Fnphases))); + } + Parser.CmdString = s; // Push the string into the Parser object + Edit(); // Invoke the Edit method for this class + inherited::MakePosSequence(); // sets the terminal bus references, must do after editing number of phases +} + +// Routine for handling Open/Close procedures + +void TPCPrototypeObj::Set_ConductorClosed(int Index, bool Value) +{ + inherited::Set_ConductorClosed(Index, Value); + + // In this example from Generator, just turn the object on or off; + if(Value) + PCPrototypeSwitchOpen = false; + else + PCPrototypeSwitchOpen = true; +} + +// Initialize any variables here + + + // For Example: 1 + j 1 + + +void PCPrototype_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class PCPrototype_unit + { + public: + PCPrototype_unit() + { + //AssertSystemInitialization(); + PCPrototype_initialization(); + } + }; + PCPrototype_unit _PCPrototype_unit; + +} // namespace PCPrototype + + + + diff --git a/OpenDSSC/PCElements/PCPrototype.h b/OpenDSSC/PCElements/PCPrototype.h new file mode 100644 index 0000000..5b47ce0 --- /dev/null +++ b/OpenDSSC/PCElements/PCPrototype.h @@ -0,0 +1,186 @@ +#ifndef PCPrototypeH +#define PCPrototypeH + +#include +#include "../Support/d2c_system.h" + +#include "../Common/DSSClass.h" +#include "../PCElements/PCClass.h" +#include "../PCElements/PCElement.h" +#include "../Shared/Ucmatrix.h" +#include "../Shared/Ucomplex.h" +#include "../shared/Arraydef.h" +#include "../General/LoadShape.h" +#include "../General/GrowthShape.h" +#include "../General/Spectrum.h" +#include "../Shared/Dynamics.h" +#include "../Support/d2c_sysfile.h" + +namespace PCPrototype +{ + + + +// Prototype for PC Element class + +// Do a global Replace on "PCPrototype" to the name of your class to start + +/* + ---------------------------------------------------------- + Copyright (c) 2008, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + +*/ + +/* + Description + + This is a prototype of a Power Converstion (PC) element. + + PC elements are Load, Generator, Vsource, Isource, etc. PC elements are + used to model devices that convert the power delivered by the Power Delivery (PD) + elements into some other form. PC elements are generally considered to be + in shunt with the power system and are the terminations of the power flow + while PD elements are considered to be in series with the power flow path. + + Both PC and PD elements are represpented by their primitive Y matrices. PC elements + are also used to model the nonlinear devices in the system (see the Load model). They + differ from PD elements in that they have a current injection source in parallel with + the primitive Y matrix. + +*/ + +/*Add other modules accessed by this class*/ // Base class for most DSS objects + // Base class for collection manager for PC elements + // Base class for PC Elements + // Unit for managing complex matrice (for Yprim, etc) + // Complex math functions, type definitions + // definitions of basic DSS arrays + + // common modules used in PC elements + // class for supporting/representing loadshapes + // Class for holding growth shapes + // Definitions for harmonic spectra + // for elements that interact with dynamics variables + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* Collection manager for this class of element */ + +class TPCPrototype : public PCClass::TPCClass +{ + friend class TPCPrototypeObj; +public: + typedef PCClass::TPCClass inherited; +private: + + /*These private functions are generally helper functions for Edit procedure*/ + + /* A typical function */ + void SetNcondsForConnection(); +protected: + void DefineProperties(); // Define the property names and help strings + virtual int MakeLike(const String OtherPCPrototypeName); // copy properties of another similar object +public: + TPCPrototype(); + virtual ~TPCPrototype(); + virtual int Edit(); // Definition of the main property editing function + virtual int Init(int Handle); // Initialize by handle (index), if necessary + virtual int NewObject(const String ObjName); // This function is called by the DSS New command + + /*any public functions that might be called from other elements*/ +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +/* Class definition for this class of element*/ + +class TPCPrototypeObj : public PCElement::TPCElement +{ + friend class TPCPrototype; +public: + typedef PCElement::TPCElement inherited; +private: + + /*Private variables of this class*/ + // a typical private variable: + Ucomplex::complex Yeq; // Y at nominal voltage + + // a typical procedure if user models are supported + void DoUserModel(); + + // many PC elements have a proc like this to map computed currents into appropriate array + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); +protected: + + /*A couple of virtual procedures you can override*/ + virtual void Set_ConductorClosed(int Index, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr); +public: + + /*Variables and functions accessed by DSS and other objects*/ + TPCPrototypeObj(DSSClass::TDSSClass* ParClass, const String PCPrototypeObjName); + virtual ~TPCPrototypeObj(); + virtual void RecalcElementData(); // Generally called after Edit is complete to recompute variables + virtual void CalcYPrim(); // Calculate Primitive Y matrix + + // Injection current management functions (unique to PC Elements) + // This is how the DSS represents elements with nonlinear characteristics + // Inj currents are the difference between the desired total terminal currents and the + // currents that result from the linear admittance matrix of the element + virtual int InjCurrents(); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr); + + // State variable management functions, if any + // You can omit these if your PC element model is not using these + // Default behavior is to basically do nothing + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + + // Support for Dynamics Mode + virtual void InitStateVars(); + virtual void IntegrateStates(); + + // Support for Harmonics Mode + virtual void InitHarmonics(); + virtual void MakePosSequence(); // Make a positive Sequence Model, if possible + + // Functions required for managing values of properties + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(d2c_system::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + + /*Put any class properties here*/ + /*Use properties when some method must be executed when a value is set or retrieved*/ + + /* Example (from Load) + Property ConnectedkVA :Double Read FConnectedkVA Write Set_ConnectedkVA; + */ + TPCPrototypeObj(DSSClass::TDSSClass* ParClass); + TPCPrototypeObj(String ClassName); + TPCPrototypeObj(); +}; +extern TPCPrototypeObj* ActivePCPrototypeObj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace PCPrototype + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PCPrototype; +#endif + +#endif // PCPrototypeH + + + + diff --git a/OpenDSSC/PCElements/PVSystemUserModel.cpp b/OpenDSSC/PCElements/PVSystemUserModel.cpp new file mode 100644 index 0000000..defe92b --- /dev/null +++ b/OpenDSSC/PCElements/PVSystemUserModel.cpp @@ -0,0 +1,185 @@ + +#pragma hdrstop + +#include "PVSystemUserModel.h" + +#include "Ucomplex.h" +#include "Arraydef.h" +#include "PVsystem.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace Arraydef; +using namespace DSSGlobals; +using namespace Dynamics; +using namespace PVSystem; +using namespace System; +using namespace Ucomplex; + +namespace PVsystemUserModel +{ + + + +/* TPVsystemUserModel */ + +void* TPVsystemUserModel::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("PVSystem User Model Does Not Have Required Function: ") + FuncName, 1569); + FuncError = true; + } + result = Addr; + return result; +} + +TPVsystemUserModel::TPVsystemUserModel() + : FHandle(0), + FID(0), + FuncError(false) +{ + FID = 0; + FName = ""; +} + +//------------------------------------------------------------------------------------ + +String TPVsystemUserModel::get_FName() +{ + return FName; +} + +//------------------------------------------------------------------------------------ + +TPVsystemUserModel::~TPVsystemUserModel() +{ + if(FID != 0) + { + FDelete(FID); // Clean up all memory associated with this instance + FreeLibrary((HMODULE) FHandle); + } + // inherited; +} + + +bool TPVsystemUserModel::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} + +void TPVsystemUserModel::Integrate() +{ + FSelect(FID); + FIntegrate(); +} + +void TPVsystemUserModel::select() +{ + FSelect(FID); +} + +void TPVsystemUserModel::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit((PAnsiChar) Value.c_str(), Value.size()); + // Else Ignore +} + +void TPVsystemUserModel::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if((HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + FreeLibrary((HMODULE) FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if((HMODULE) FHandle == 0) + // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary( (DSSDirectory + Value).c_str() ); + } + if((HMODULE) FHandle == 0) + DoSimpleMsg(String("PVSystem User Model ") + Value + + " Not Loaded. DSS Directory = " + + DSSDirectory, 1570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (PVsystemUserModelProc__0) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("New")), "New"); + if(!FuncError) + FSelect = (PVsystemUserModelProc__2) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Select")), "Select"); + if(!FuncError) + FInit = (PVsystemUserModelProc__4) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Init")), "Init"); + if(!FuncError) + FCalc = (PVsystemUserModelProc__5) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Calc")), "Calc"); + if(!FuncError) + FIntegrate = (PVsystemUserModelProc__6) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Integrate")), "Integrate"); + if(!FuncError) + FSave = (PVsystemUserModelProc__8) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Save")), "Save"); + if(!FuncError) + fRestore = (PVsystemUserModelProc__9) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Restore")), "Restore"); + if(!FuncError) + FEdit = (PVsystemUserModelProc__3) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (PVsystemUserModelProc__7) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (PVsystemUserModelProc__1) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Delete")), "Delete"); + if(!FuncError) + FNumVars = (PVsystemUserModelProc__10) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("NumVars")), "NumVars"); + if(!FuncError) + FGetAllVars = (PVsystemUserModelProc__11) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetAllVars")), "GetAllVars"); + if(!FuncError) + FGetVariable = (PVsystemUserModelProc__12) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVariable")), "GetVariable"); + if(!FuncError) + FSetVariable = (PVsystemUserModelProc__13) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("SetVariable")), "SetVariable"); + if(!FuncError) + FGetVarName = (PVsystemUserModelProc__14) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVarName")), "GetVarName"); + if(FuncError) + { + FreeLibrary((HMODULE) FHandle); + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew(ActiveCircuit[ActiveActor]->Solution->DynaVars, CallBackRoutines); // Create new instance of user model + } + } +} + + + + +} // namespace PVsystemUserModel + + + + diff --git a/OpenDSSC/PCElements/PVSystemUserModel.h b/OpenDSSC/PCElements/PVSystemUserModel.h new file mode 100644 index 0000000..f607071 --- /dev/null +++ b/OpenDSSC/PCElements/PVSystemUserModel.h @@ -0,0 +1,102 @@ +#ifndef PVsystemUserModelH +#define PVsystemUserModelH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" +#include "Dynamics.h" +#include "DSSCallBackRoutines.h" + + + +namespace PVsystemUserModel +{ + + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TPVsystemUserModel : public System::TObject +{ +public: + typedef TObject inherited; +//private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + String FName; // Name of the DLL file containing user model + bool FuncError; + + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *PVsystemUserModelProc__0)(TDynamicsRec&, TDSSCallBacks&); + PVsystemUserModelProc__0 FNew; // deletes specified instance + typedef void (__stdcall *PVsystemUserModelProc__1)(int&); + PVsystemUserModelProc__1 FDelete; // Select active instance + typedef int (__stdcall *PVsystemUserModelProc__2)(int&); + PVsystemUserModelProc__2 FSelect; + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); + + String get_FName(); + +protected: +public: // send string to user model to handle + typedef void (__stdcall *PVsystemUserModelProc__3)(System::PAnsiChar, unsigned int); + PVsystemUserModelProc__3 FEdit; // For dynamics + typedef void (__stdcall *PVsystemUserModelProc__4)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + PVsystemUserModelProc__4 FInit; // returns Currents or sets Pshaft + typedef void (__stdcall *PVsystemUserModelProc__5)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + PVsystemUserModelProc__5 FCalc; // Integrates any state vars + typedef void (__stdcall *PVsystemUserModelProc__6)(); + PVsystemUserModelProc__6 FIntegrate; // Called when props of generator updated + + + /*Save and restore data*/ + typedef void (__stdcall *PVsystemUserModelProc__7)(); + PVsystemUserModelProc__7 FUpdateModel; + typedef void (__stdcall *PVsystemUserModelProc__8)(); + PVsystemUserModelProc__8 FSave; + + /*Monitoring functions*/ + typedef void (__stdcall *PVsystemUserModelProc__9)(); + PVsystemUserModelProc__9 fRestore; + typedef int (__stdcall *PVsystemUserModelProc__10)(); + PVsystemUserModelProc__10 FNumVars; // Get all vars + typedef void (__stdcall *PVsystemUserModelProc__11)(Arraydef::pDoubleArray); + PVsystemUserModelProc__11 FGetAllVars;// Get a particular var + typedef double (__stdcall *PVsystemUserModelProc__12)(int&); + PVsystemUserModelProc__12 FGetVariable; + typedef void (__stdcall *PVsystemUserModelProc__13)(int&, double&); + PVsystemUserModelProc__13 FSetVariable; + + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + typedef void (__stdcall *PVsystemUserModelProc__14)(int&, System::PAnsiChar, unsigned int); + PVsystemUserModelProc__14 FGetVarName; + void select(); + void Integrate(); + TPVsystemUserModel(); + virtual ~TPVsystemUserModel(); +//__published: +}; + + +} // namespace PVsystemUserModel + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PVsystemUserModel; +#endif + +#endif // PVsystemUserModelH + + + + diff --git a/OpenDSSC/PCElements/PVsystem.cpp b/OpenDSSC/PCElements/PVsystem.cpp new file mode 100644 index 0000000..8d28e2d --- /dev/null +++ b/OpenDSSC/PCElements/PVsystem.cpp @@ -0,0 +1,3755 @@ + + +#pragma hdrstop + +#include "PVsystem.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "Command.h" +#include +#include "mathutil.h" +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace PVsystemUserModel; +using namespace ParserDel; +using namespace System; +using namespace TempShape; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace PVSystem +{ + +TPVsystemObj::TPVsystemObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TPVsystemObj::TPVsystemObj(String ClassName) : inherited(ClassName) {} +TPVsystemObj::TPVsystemObj() {} + + +TPVsystemObj* ActivePVsystemObj = nullptr; +// =========================================================================================== +/* + To add a property, + 1) add a property constant to this list + 2) add a handler to the CASE statement in the Edit FUNCTION + 3) add a statement(s) to InitPropertyValues FUNCTION to initialize the string value + 4) add any special handlers to DumpProperties and GetPropertyValue, If needed +*/ +// =========================================================================================== +const int propKV = 3; +const int propIrradiance = 4; +const int propPF = 5; +const int propMODEL = 6; +const int propYEARLY = 7; +const int propDAILY = 8; +const int propDUTY = 9; +const int propTYEARLY = 10; +const int propTDAILY = 11; +const int propTDUTY = 12; +const int PropConnection = 13; +const int propKVAR = 14; +const int propPCTR = 15; +const int propPCTX = 16; +const int propCLASS = 17; +const int propInvEffCurve = 18; +const int propTemp = 19; +const int propPmpp = 20; +const int propP_T_Curve = 21; +const int propCutin = 22; +const int propCutout = 23; +const int propVMINPU = 24; +const int propVMAXPU = 25; +const int propKVA = 26; +const int propUSERMODEL = 27; +const int propUSERDATA = 28; +const int propDEBUGTRACE = 29; +const int proppctPmpp = 30; +const int propBalanced = 31; +const int propLimited = 32; +const int propVarFollowInverter = 33; +const int propkvarLimit = 34; +const int propDutyStart = 35; +const int propPpriority = 36; +const int propPFpriority = 37; +const int propPminNoVars = 38; +const int propPminkvarLimit = 39; +const int propkvarLimitneg = 40; +const int propkVDC = 41; +const int propkp = 42; +const int propCtrlTol = 43; +const int propSMT = 44; +const int propSM = 45; +const int propDynEq = 46; +const int propDynOut = 47; +const int propGFM = 48; +const int propAmpsLimit = 49; +const int propAmpsError = 50; +const int NumPropsThisClass = 50; // Make this agree with the last property constant +complex cBuffer[25/*# range 1..24*/]; // Temp buffer for calcs 24-phase PVSystem element? +complex CDoubleOne = {}; // Creates superstructure for all PVSystem elements + +TPVSystem::TPVSystem() +{ + ; + Class_Name = "PVSystem"; + DSSClassType = DSSClassType + PVSYSTEM_ELEMENT; // In both PCelement and PVSystem element list + ActiveElement = 0; + // Set Register names + RegisterNames[0] = "kWh"; + RegisterNames[1] = "kvarh"; + RegisterNames[2] = "Max kW"; + RegisterNames[3] = "Max kVA"; + RegisterNames[4] = "Hours"; + RegisterNames[5] = "Price($)"; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +TPVSystem::~TPVSystem() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +void TPVSystem::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + // Define Property names + /* + Using the AddProperty FUNCTION, you can list the properties here in the order you want + them to appear when properties are accessed sequentially without tags. Syntax: + AddProperty( , , ); + */ + AddProperty("phases", 1, "Number of Phases, this PVSystem element. Power is evenly divided among phases."); + AddProperty("bus1", 2, "Bus to which the PVSystem element is connected. May include specific node specification."); + AddProperty("kv", propKV, "Nominal rated (1.0 per unit) voltage, kV, for PVSystem element. For 2- and 3-phase PVSystem elements, specify phase-phase kV. " + "Otherwise, specify actual kV across each branch of the PVSystem element. " + "If 1-phase wye (star or LN), specify phase-neutral kV. " + "If 1-phase delta or phase-phase connected, specify phase-phase kV."); // line-neutral voltage// base voltage + AddProperty("irradiance", propIrradiance, "Get/set the present irradiance value in kW/sq-m. Used as base value for shape multipliers. " + "Generally entered as peak value for the time period of interest and the yearly, daily, and duty load shape " + "objects are defined as per unit multipliers (just like Loads/Generators)."); + AddProperty("Pmpp", propPmpp, "Get/set the rated max power of the PV array for 1.0 kW/sq-m irradiance and a user-selected array temperature. " + "The P-TCurve should be defined relative to the selected array temperature."); + AddProperty("%Pmpp", proppctPmpp, "Upper limit on active power as a percentage of Pmpp."); + AddProperty("Temperature", propTemp, "Get/set the present Temperature. Used as fixed value corresponding to PTCurve property. " + "A multiplier is obtained from the Pmpp-Temp curve and applied to the nominal Get_FPmpp() from the irradiance " + "to determine the net array output."); + AddProperty("pf", propPF, String("Nominally, the power factor for the output power. Default is 1.0. " "Setting this property will cause the inverter to operate in constant power factor mode." "Enter negative when kW and kvar have opposite signs.") + CRLF + + "A positive power factor signifies that the PVSystem element produces vars " + + CRLF + + "as is typical for a generator. "); + AddProperty("conn", PropConnection, "={wye|LN|delta|LL}. Default is wye."); + AddProperty("kvar", propKVAR, "Get/set the present kvar value. Setting this property forces the inverter to operate in constant kvar mode."); + AddProperty("kVA", propKVA, "kVA rating of inverter. Used as the base for Dynamics mode and Harmonics mode values."); + AddProperty("%Cutin", propCutin, "% cut-in power -- % of kVA rating of inverter. " + "When the inverter is OFF, the power from the array must be greater than this for the inverter to turn on."); + AddProperty("%Cutout", propCutout, "% cut-out power -- % of kVA rating of inverter. " + "When the inverter is ON, the inverter turns OFF when the power from the array drops below this value."); + AddProperty("EffCurve", propInvEffCurve, "An XYCurve object, previously defined, that describes the PER UNIT efficiency vs PER UNIT of rated kVA for the inverter. " + "Inverter output power is discounted by the multiplier obtained from this curve."); + AddProperty("P-TCurve", propP_T_Curve, "An XYCurve object, previously defined, that describes the PV array PER UNIT Get_FPmpp() vs Temperature curve. " + "Temperature units must agree with the Temperature property and the Temperature shapes used for simulations. " + "The Pmpp values are specified in per unit of the Get_FPmpp() value for 1 kW/sq-m irradiance. " + "The value for the temperature at which Get_FPmpp() is defined should be 1.0. " + "The net array power is determined by the irradiance * Get_FPmpp() * f(Temperature)"); + AddProperty("%R", propPCTR, "Equivalent percent internal resistance, ohms. Default is 50%. Placed in series with internal voltage source" + " for harmonics and dynamics modes. (Limits fault current to about 2 pu if not current limited -- see LimitCurrent) "); + AddProperty("%X", propPCTX, "Equivalent percent internal reactance, ohms. Default is 0%. Placed in series with internal voltage source" + " for harmonics and dynamics modes. "); + AddProperty("model", propMODEL, String("Integer code (default=1) for the model to use for power output variation with voltage. " "Valid values are:") + CRLF + + CRLF + + "1:PVSystem element injects a CONSTANT kW at specified power factor." + + CRLF + + "2:PVSystem element is modeled as a CONSTANT ADMITTANCE." + + CRLF + + "3:Compute load injection from User-written Model."); + AddProperty("Vminpu", propVMINPU, "Default = 0.90. Minimum per unit voltage for which the Model is assumed to apply. " + "Below this value, the load model reverts to a constant impedance model except for Dynamics model. " + "In Dynamics mode, the current magnitude is limited to the value the power flow would compute for this voltage."); + AddProperty("Vmaxpu", propVMAXPU, "Default = 1.10. Maximum per unit voltage for which the Model is assumed to apply. " + "Above this value, the load model reverts to a constant impedance model."); + AddProperty("Balanced", propBalanced, "{Yes | No*} Default is No. Force balanced current only for 3-phase PVSystems. Forces zero- and negative-sequence to zero. "); + AddProperty("LimitCurrent", propLimited, "Limits current magnitude to Vminpu value for both 1-phase and 3-phase PVSystems similar to Generator Model 7. For 3-phase, " + "limits the positive-sequence current but not the negative-sequence."); + AddProperty("yearly", propYEARLY, "Dispatch shape to use for yearly simulations. Must be previously defined " + "as a Loadshape object. If this is not specified, the Daily dispatch shape, if any, is repeated " + "during Yearly solution modes. In the default dispatch mode, " + "the PVSystem element uses this loadshape to trigger State changes."); + AddProperty("daily", propDAILY, "Dispatch shape to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. In the default dispatch mode, " + "the PVSystem element uses this loadshape to trigger State changes."); // daily dispatch (hourly) + AddProperty("duty", propDUTY, "Load shape to use for duty cycle dispatch simulations such as for solar ramp rate studies. " + "Must be previously defined as a Loadshape object. " + "Typically would have time intervals of 1-5 seconds. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat."); // as for wind generation + AddProperty("Tyearly", propTYEARLY, "Temperature shape to use for yearly simulations. Must be previously defined " + "as a TShape object. If this is not specified, the Daily dispatch shape, if any, is repeated " + "during Yearly solution modes. " + "The PVSystem element uses this TShape to determine the Pmpp from the Get_FPmpp() vs T curve. " + "Units must agree with the Get_FPmpp() vs T curve."); + AddProperty("Tdaily", propTDAILY, "Temperature shape to use for daily simulations. Must be previously defined " + "as a TShape object of 24 hrs, typically. " + "The PVSystem element uses this TShape to determine the Pmpp from the Get_FPmpp() vs T curve. " + "Units must agree with the Get_FPmpp() vs T curve."); // daily dispatch (hourly) + AddProperty("Tduty", propTDUTY, "Temperature shape to use for duty cycle dispatch simulations such as for solar ramp rate studies. " + "Must be previously defined as a TShape object. " + "Typically would have time intervals of 1-5 seconds. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat. " + "The PVSystem model uses this TShape to determine the Pmpp from the Get_FPmpp() vs T curve. " + "Units must agree with the Get_FPmpp() vs T curve."); // Cloud transient simulation + AddProperty("class", propCLASS, "An arbitrary integer number representing the class of PVSystem element so that PVSystem values may " + "be segregated by class."); // integer + AddProperty("UserModel", propUSERMODEL, "Name of DLL containing user-written model, which computes the terminal currents for Dynamics studies, " + "overriding the default model. Set to \"none\" to negate previous setting."); + AddProperty("UserData", propUSERDATA, "String (in quotes or parentheses) that gets passed to user-written model for defining the data required for that model."); + AddProperty("debugtrace", propDEBUGTRACE, "{Yes | No } Default is no. Turn this on to capture the progress of the PVSystem model " + "for each iteration. Creates a separate file for each PVSystem element named \"PVSystem_name.CSV\"."); + AddProperty("VarFollowInverter", propVarFollowInverter, "Boolean variable (Yes|No) or (True|False). Defaults to False which indicates that the reactive power generation/absorption does not respect the inverter status." + "When set to True, the PVSystem reactive power generation/absorption will cease when the inverter status is off, due to panel kW dropping below %Cutout. The reactive power " + "generation/absorption will begin again when the panel kW is above %Cutin. When set to False, the PVSystem will generate/absorb reactive power regardless of the status of the inverter."); + AddProperty("DutyStart", propDutyStart, "Starting time offset [hours] into the duty cycle shape for this PVSystem, defaults to 0"); + AddProperty("WattPriority", propPpriority, "{Yes/No*/True/False} Set inverter to watt priority instead of the default var priority"); + AddProperty("PFPriority", propPFpriority, "{Yes/No*/True/False} Set inverter to operate with PF priority when in constant PF mode. If \"Yes\", value assigned to \"WattPriority\"" + " is neglected. If controlled by an InvControl with either Volt-Var or DRC or both functions activated, PF priority is neglected and \"WattPriority\" is considered. Default = No."); + AddProperty("%PminNoVars", propPminNoVars, "Minimum active power as percentage of Pmpp under which there is no vars production/absorption."); + AddProperty("%PminkvarMax", propPminkvarLimit, "Minimum active power as percentage of Pmpp that allows the inverter to produce/absorb reactive power up to its kvarMax or kvarMaxAbs."); + AddProperty("kvarMax", propkvarLimit, "Indicates the maximum reactive power GENERATION (un-signed numerical variable in kvar) for the inverter (as an un-signed value). Defaults to kVA rating of the inverter."); + AddProperty("kvarMaxAbs", propkvarLimitneg, "Indicates the maximum reactive power ABSORPTION (un-signed numerical variable in kvar) for the inverter (as an un-signed value). Defaults to kVA rating of the inverter."); + AddProperty("kVDC", propkVDC, + "Indicates the rated voltage (kV) at the input of the inverter at the peak of PV energy production. The value is normally greater or equal to the kV base of the PV system. It is used for dynamics simulation ONLY."); + + AddProperty("Kp", propkp, + "It is the proportional gain for the PI controller within the inverter. Use it to modify the controller response in dynamics simulation mode."); + + AddProperty("PITol", propCtrlTol, + "It is the tolerance (%) for the closed loop controller of the inverter. For dynamics simulation mode."); + + AddProperty("SafeVoltage", propSMT, + "Indicates the voltage level (%) respect to the base voltage level for which the Inverter will operate. If this threshold is violated, the Inverter will enter safe mode (OFF). For dynamic simulation. By default is 80%"); + + AddProperty("SafeMode", propSM, + "(Read only) Indicates whether the inverter entered (Yes) or not (No) into Safe Mode."); + AddProperty("DynamicEq", propDynEq, + string("The name of the dynamic equation (DinamicExp) that will be used for defining the dynamic behavior of the generator. ") + + "if not defined, the generator dynamics will follow the built-in dynamic equation."); + AddProperty("DynOut", propDynOut, + string("The name of the variables within the Dynamic equation that will be used to govern the PVSystem dynamics.") + + "This PVsystem model requires 1 output from the dynamic equation: " + CRLF + CRLF + + "1. Current." + CRLF + + "The output variables need to be defined in the same order."); + AddProperty("ControlMode", propGFM, + string("Defines the control mode for the inverter. It can be one of {GFM | GFL*}. By default it is GFL (Grid Following Inverter).") + + " Use GFM (Grid Forming Inverter) for energizing islanded microgrids, but, if the device is conencted to the grid, it is highly recommended to use GFL." + CRLF + CRLF + + "GFM control mode disables any control action set by the InvControl device."); + AddProperty("AmpLimit", propAmpsLimit, + "Is the current limiter per phase for the IBR when operating in GFM mode. This limit is imposed to prevent the IBR to enter into Safe Mode when reaching the IBR power ratings." + CRLF + + "Once the IBR reaches this value, it remains there without moving into Safe Mode. This value needs to be set lower than the IBR Amps rating."); + AddProperty("AmpLimitGain", propAmpsError, + "Use it for fine tunning the current limiter when active, by default is 0.8, it has to be a value between 0.1 and 1. This value allows users to fine tune the IBRs current limiter to match with the user requirements."); + + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + // Override default help string + PropertyHelp[NumPropsThisClass + 1 - 1] = "Name of harmonic voltage or current spectrum for this PVSystem element. " + "A harmonic voltage source is assumed for the inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +int TPVSystem::NewObject(const String ObjName) +{ + int result = 0; + // Make a new PVSystem element and add it to PVSystem class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TPVsystemObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +void TPVSystem::SetNcondsForConnection() +{ + /*# with ActivePVsystemObj do */ + { + auto with0 = ActivePVsystemObj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases + 1); + break; + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); + break; + } + break; + default: + ; + break; + } + } +} + +void TPVSystem::UpdateAll() +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TPVsystemObj(ElementList.Get(i)) do */ + { + auto with0 = ((TPVsystemObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->UpdatePVSystem(); + } + } +} + // Accepts + // delta or LL (Case insensitive) + // Y, wye, or LN + +void TPVSystem::InterpretConnection(const String s) +{ + String TestS; + /*# with ActivePVsystemObj do */ + { + auto with0 = ActivePVsystemObj; + TestS = LowerCase(s); + switch(TestS[0]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[1]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + SetNcondsForConnection(); + /*VBase is always L-N voltage unless 1-phase device or more than 3 phases*/ + /*# with PVSystemVars do */ + { + auto& with1 = with0->PVSystemVars; + switch(with0->Fnphases) + { + case 2: case 3: + with0->VBase = with1.kVPVSystemBase * InvSQRT3x1000; + break; // L-N Volts + default: + with0->VBase = with1.kVPVSystemBase * 1000.0; // Just use what is supplied + break; + } + } + with0->VBaseMin = with0->Vminpu * with0->VBase; + with0->VBaseMax = with0->Vmaxpu * with0->VBase; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + +//- - - - - - - - - - - - - - -MAIN EDIT FUNCTION - - - - - - - - - - - - - - - + +int TPVSystem::Edit(int ActorID) +{ + int result = 0, + i = 0, + iCase = 0, + VarIdx = 0, + ParamPointer = 0; + String ParamName = "", + Param = ""; + // continue parsing with contents of Parser + ActivePVsystemObj = (TPVsystemObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActivePVsystemObj); + result = 0; + /*# with ActivePVsystemObj do */ + { + auto with0 = ActivePVsystemObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); // Parse next property off the command line + Param = Parser[ActorID]->MakeString_(); // Put the string value of the property value in local memory for faster access + while(Param.size() > 0) + { + if(ParamName.size() == 0) // If it is not a named property, assume the next property + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); // Look up the name in the list for this class + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) // Update the string value of the property + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1],Param); + else + { + VarIdx = with0->CheckIfDynVar(ParamName, ActorID); + if (VarIdx < 0) + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for PVSystem \"" + with0->get_Name() + "\"", 560); + } + if(ParamPointer > 0) + { + iCase = (PropertyIdxMap)[ParamPointer - 1]; + switch(iCase) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + with0->Set_PresentkV(with0->PVSystemVars.kVPVSystemBase); // In case phases have been defined after + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case propKV: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_()); + break; + case propIrradiance: + with0->PVSystemVars.FIrradiance = Parser[ActorID]->MakeDouble_(); + break; + case propPF: + { + with0->Set_Varmode(VARMODEPF); + with0->PFNominal = Parser[ActorID]->MakeDouble_(); + } + break; + case propMODEL: + with0->VoltageModel = Parser[ActorID]->MakeInteger_(); + break; + case propYEARLY: + with0->YearlyShape = Param; + break; + case propDAILY: + with0->DailyShape = Param; + break; + case propDUTY: + with0->DutyShape = Param; + break; + case propTYEARLY: + with0->YearlyTShape = Param; + break; + case propTDAILY: + with0->DailyTShape = Param; + break; + case propTDUTY: + with0->DutyTShape = Param; + break; + case PropConnection: + InterpretConnection(Param); + break; + case propKVAR: + { + with0->Set_Varmode(VARMODEKVAR); + with0->Set_Presentkvar(Parser[ActorID]->MakeDouble_()); + } + break; + case propPCTR: + with0->pctR = Parser[ActorID]->MakeDouble_(); + break; + case propPCTX: + with0->pctX = Parser[ActorID]->MakeDouble_(); + break; + case propCLASS: + with0->FClass = Parser[ActorID]->MakeInteger_(); + break; + case propInvEffCurve: + with0->InverterCurve = Param; + break; + case propTemp: + with0->PVSystemVars.FTemperature = Parser[ActorID]->MakeDouble_(); + break; + case propPmpp: + with0->PVSystemVars.FPmpp = Parser[ActorID]->MakeDouble_(); + break; + case propP_T_Curve: + with0->Power_TempCurve = Param; + break; + case propCutin: + with0->FpctCutIn = Parser[ActorID]->MakeDouble_(); + break; + case propCutout: + with0->FpctCutOut = Parser[ActorID]->MakeDouble_(); + break; + case propVMINPU: + with0->Vminpu = Parser[ActorID]->MakeDouble_(); + break; + case propVMAXPU: + with0->Vmaxpu = Parser[ActorID]->MakeDouble_(); + break; + case propKVA: + /*# with PVSystemVars do */ + { + auto& with1 = with0->PVSystemVars; + with1.FkVArating = Parser[ActorID]->MakeDouble_(); + if(!with0->kvarLimitSet) + with0->PVSystemVars.Fkvarlimit = with1.FkVArating; + if(!(with0->kvarLimitSet) && !(with0->kvarLimitNegSet)) + with0->PVSystemVars.Fkvarlimitneg = with1.FkVArating; + } + break; + case propUSERMODEL: + with0->UserModel->Set_Name(Parser[ActorID]->MakeString_()); + break; // Connect to user written models + case propUSERDATA: + with0->UserModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; // Send edit string to user model + case propDEBUGTRACE: + with0->DebugTrace = InterpretYesNo(Param); + break; + case proppctPmpp: + with0->PVSystemVars.FpuPmpp = Parser[ActorID]->MakeDouble_() / 100.0; + break; // convert to pu + case propBalanced: + with0->ForceBalanced = InterpretYesNo(Param); + break; + case propLimited: + with0->CurrentLimited = InterpretYesNo(Param); + break; + case propVarFollowInverter: + with0->FVarFollowInverter = InterpretYesNo(Param); + break; + case propkvarLimit: + { + with0->PVSystemVars.Fkvarlimit = Abs( Parser[ActorID]->MakeDouble_()); + with0->kvarLimitSet = true; + if(!with0->kvarLimitNegSet) + with0->PVSystemVars.Fkvarlimitneg = Abs( with0->PVSystemVars.Fkvarlimit); + } + break; + case propDutyStart: + with0->DutyStart = Parser[ActorID]->MakeDouble_(); + break; + case propPpriority: + with0->PVSystemVars.P_priority = InterpretYesNo(Param); + break; // set watt priority flag + case propPFpriority: + with0->PVSystemVars.PF_Priority = InterpretYesNo(Param); + break; + case propPminNoVars: + with0->FpctPminNoVars = Abs( Parser[ActorID]->MakeDouble_()); + break; + case propPminkvarLimit: + with0->FpctPminkvarLimit = Abs( Parser[ActorID]->MakeDouble_()); + break; + case propkvarLimitneg: + { + with0->PVSystemVars.Fkvarlimitneg = Abs( Parser[ActorID]->MakeDouble_()); + with0->kvarLimitNegSet = true; + } + break; + case propkVDC: + with0->myDynVars.RatedVDC = Parser[ActorID]->MakeDouble_() * 1000; + break; + case propkp: + with0->myDynVars.Kp = Parser[ActorID]->MakeDouble_() / 1000; + break; + case propCtrlTol: + with0->myDynVars.CtrlTol = Parser[ActorID]->MakeDouble_() / 100; + break; + case propSMT: + with0->myDynVars.SMThreshold = Parser[ActorID]->MakeDouble_(); + break; + case propDynEq: + with0->DynamicEq = Param; + break; + case propDynOut: + with0->SetDynOutput(Param); + break; + case propGFM: + { + if (LowerCase(Parser[ActorID]->MakeString_()) == "gfm") + { + with0->GFM_Mode = true; + with0->myDynVars.ResetIBR = false; + if (with0->myDynVars.Vgrid.size() < with0->Get_NPhases()) + with0->myDynVars.Vgrid.resize(with0->Get_NPhases()); + } + else + with0->GFM_Mode = false; + + with0->Set_YprimInvalid(ActorID, true); + } + break; + case propAmpsLimit: + with0->myDynVars.ILimit = Parser[ActorID]->MakeDouble_(); + break; + case propAmpsError: + with0->myDynVars.VError = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + inherited::ClassEdit(ActivePVsystemObj, ParamPointer - NumPropsThisClass); + break; + } + switch(iCase) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + /*Set loadshape objects; returns nil If not valid*/ + case propYEARLY: + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + break; + case propDAILY: + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + break; + case propDUTY: + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + break; + case propTYEARLY: + with0->YearlyTShapeObj = ((TTShapeObj*) TShapeClass[ActorID]->Find(with0->YearlyTShape)); + break; + case propTDAILY: + with0->DailyTShapeObj = ((TTShapeObj*) TShapeClass[ActorID]->Find(with0->DailyTShape)); + break; + case propTDUTY: + with0->DutyTShapeObj = ((TTShapeObj*) TShapeClass[ActorID]->Find(with0->DutyTShape)); + break; + case propInvEffCurve: + with0->InverterCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->InverterCurve)); + break; + case propP_T_Curve: + with0->Power_TempCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->Power_TempCurve)); + break; + case propDEBUGTRACE: + if(with0->DebugTrace) // Init trace file + { + int stop = 0; + AssignFile(with0->Tracefile, GetOutputDirectory() + "STOR_" + with0->get_Name() + ".CSV"); + Rewrite(with0->Tracefile); + IOResultToException(); + Write(with0->Tracefile, "t, Iteration, LoadMultiplier, Mode, LoadModel, PVSystemModel, Qnominalperphase, Pnominalperphase, CurrentType"); + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iinj") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iterm") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Vterm") + IntToStr(i) + "|"); + } + Write(with0->Tracefile, ",Vthev, Theta"); + WriteLn(with0->Tracefile); + CloseFile(with0->Tracefile); + } + break; + case propDynEq: + { + with0->DynamicEqObj = (TDynamicExpObj*)TDynamicExpClass[ActorID]->Find(with0->DynamicEq); + if (ASSIGNED(with0->DynamicEqObj)) + { + with0->DynamicEqVals.resize(with0->DynamicEqObj->get_FNumVars()); + for (int idx = 0; idx < with0->DynamicEqVals.size(); idx++) + with0->DynamicEqVals[idx].resize(2); + } + } + break; + default: + ; + break; + } + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} +// Copy over essential properties from other object + +int TPVSystem::MakeLike(const String OtherPVsystemObjName) +{ + int result = 0; + TPVsystemObj* OtherPVSystemObj = nullptr; + int i = 0; + result = 0; + /*See If we can find this line name in the present collection*/ + OtherPVSystemObj = ((TPVsystemObj*) Find(OtherPVsystemObjName)); + if(OtherPVSystemObj != nullptr) + { + /*# with ActivePVsystemObj do */ + { + auto with0 = ActivePVsystemObj; + int stop = 0; + if(with0->Fnphases != OtherPVSystemObj->Fnphases) + { + with0->Set_NPhases(OtherPVSystemObj->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->PVSystemVars.kVPVSystemBase = OtherPVSystemObj->PVSystemVars.kVPVSystemBase; + with0->VBase = OtherPVSystemObj->VBase; + with0->Vminpu = OtherPVSystemObj->Vminpu; + with0->Vmaxpu = OtherPVSystemObj->Vmaxpu; + with0->VBaseMin = OtherPVSystemObj->VBaseMin; + with0->VBaseMax = OtherPVSystemObj->VBaseMax; + with0->kW_out = OtherPVSystemObj->kW_out; + with0->kvar_out = OtherPVSystemObj->kvar_out; + with0->Pnominalperphase = OtherPVSystemObj->Pnominalperphase; + with0->PFNominal = OtherPVSystemObj->PFNominal; + with0->Qnominalperphase = OtherPVSystemObj->Qnominalperphase; + with0->Connection = OtherPVSystemObj->Connection; + with0->YearlyShape = OtherPVSystemObj->YearlyShape; + with0->YearlyShapeObj = OtherPVSystemObj->YearlyShapeObj; + with0->DailyShape = OtherPVSystemObj->DailyShape; + with0->DailyShapeObj = OtherPVSystemObj->DailyShapeObj; + with0->DutyShape = OtherPVSystemObj->DutyShape; + with0->DutyShapeObj = OtherPVSystemObj->DutyShapeObj; + with0->DutyStart = OtherPVSystemObj->DutyStart; + with0->YearlyTShape = OtherPVSystemObj->YearlyTShape; + with0->YearlyTShapeObj = OtherPVSystemObj->YearlyTShapeObj; + with0->DailyTShape = OtherPVSystemObj->DailyTShape; + with0->DailyTShapeObj = OtherPVSystemObj->DailyTShapeObj; + with0->DutyTShape = OtherPVSystemObj->DutyTShape; + with0->DutyTShapeObj = OtherPVSystemObj->DutyTShapeObj; + with0->InverterCurve = OtherPVSystemObj->InverterCurve; + with0->InverterCurveObj = OtherPVSystemObj->InverterCurveObj; + with0->Power_TempCurve = OtherPVSystemObj->Power_TempCurve; + with0->Power_TempCurveObj = OtherPVSystemObj->Power_TempCurveObj; + with0->FClass = OtherPVSystemObj->FClass; + with0->VoltageModel = OtherPVSystemObj->VoltageModel; + with0->PVSystemVars.FTemperature = OtherPVSystemObj->PVSystemVars.FTemperature; + with0->PVSystemVars.FPmpp = OtherPVSystemObj->PVSystemVars.FPmpp; + with0->FpctCutIn = OtherPVSystemObj->FpctCutIn; + with0->FpctCutOut = OtherPVSystemObj->FpctCutOut; + with0->FVarFollowInverter = OtherPVSystemObj->FVarFollowInverter; + with0->PVSystemVars.Fkvarlimit = OtherPVSystemObj->PVSystemVars.Fkvarlimit; + with0->PVSystemVars.Fkvarlimitneg = OtherPVSystemObj->PVSystemVars.Fkvarlimitneg; + with0->FpctPminNoVars = OtherPVSystemObj->FpctPminNoVars; + with0->FpctPminkvarLimit = OtherPVSystemObj->FpctPminkvarLimit; + with0->kvarLimitSet = OtherPVSystemObj->kvarLimitSet; + with0->kvarLimitNegSet = OtherPVSystemObj->kvarLimitNegSet; + with0->PVSystemVars.FIrradiance = OtherPVSystemObj->PVSystemVars.FIrradiance; + with0->PVSystemVars.FkVArating = OtherPVSystemObj->PVSystemVars.FkVArating; + with0->pctR = OtherPVSystemObj->pctR; + with0->pctX = OtherPVSystemObj->pctX; + with0->RandomMult = OtherPVSystemObj->RandomMult; + with0->FVWMode = OtherPVSystemObj->FVWMode; + with0->FVVMode = OtherPVSystemObj->FVVMode; + with0->FWPMode = OtherPVSystemObj->FWPMode; + with0->FWVMode = OtherPVSystemObj->FWPMode; + with0->FDRCMode = OtherPVSystemObj->FDRCMode; + with0->FAVRMode = OtherPVSystemObj->FAVRMode; + with0->UserModel->FName = OtherPVSystemObj->UserModel->FName; // Connect to user written models + with0->ForceBalanced = OtherPVSystemObj->ForceBalanced; + with0->CurrentLimited = OtherPVSystemObj->CurrentLimited; + ClassMakeLike(OtherPVSystemObj); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0->FPropertyValue)[i - 1] = (OtherPVSystemObj->FPropertyValue)[i - 1]; + } + result = 1; + } + } + else + DoSimpleMsg(String("Error in PVSystem MakeLike: \"") + OtherPVsystemObjName + + "\" Not Found.", 562); + return result; +} + +int TPVSystem::Init(int Handle, int ActorID) +{ + int result = 0; + TPVsystemObj* P = nullptr; + if(Handle == 0) // init all + { + P = (TPVsystemObj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TPVsystemObj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TPVsystemObj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TPVSystem.Init", -1); + result = 0; + return result; +} // Force all EnergyMeters in the circuit to reset + +void TPVSystem::ResetRegistersAll() +{ + int Idx = 0; + Idx = Get_First(); + while((Idx > 0)) + { + ((TPVsystemObj*) GetActiveObj())->ResetRegisters(); + Idx = Get_Next(); + } +} // Force all active PV System energy meters to take a sample + +void TPVSystem::SampleAll(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TPVsystemObj(ElementList.Get(i)) do */ + { + auto with0 = ((TPVsystemObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->TakeSample(ActorID); + } + } +} + +TPVsystemObj::TPVsystemObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + LastThevAngle(0.0), + DebugTrace(false), + PVSystemSolutionCount(0), + PVSystemFundamental(0.0), + PVsystemObjSwitchOpen(false), + FirstSampleAfterReset(false), + PFSpecified(false), + kvarSpecified(false), + ForceBalanced(false), + CurrentLimited(false), + kvar_out(0.0), + kW_out(0.0), + kvarRequested(0.0), + kWRequested(0.0), + FpctCutIn(0.0), + FpctCutOut(0.0), + FVarFollowInverter(false), + CutInkW(0.0), + CutOutkW(0.0), + FInverterON(false), + pctR(0.0), + pctX(0.0), + OpenPVSystemSolutionCount(0), + Pnominalperphase(0.0), + Qnominalperphase(0.0), + RandomMult(0.0), + Reg_Hours(0), + Reg_kvarh(0), + Reg_kWh(0), + Reg_MaxkVA(0), + Reg_MaxkW(0), + Reg_Price(0), + TShapeValue(0.0), + UserModel(nullptr), + varBase(0.0), + VBase(0.0), + VBaseMax(0.0), + VBaseMin(0.0), + Vmaxpu(0.0), + Vminpu(0.0), + YPrimOpenCond(nullptr), + FVWMode(false), + FVWYAxis(0), + Connection(0), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr), + DutyStart(0.0), + YearlyShapeObj(nullptr), + DailyTShapeObj(nullptr), + DutyTShapeObj(nullptr), + YearlyTShapeObj(nullptr), + InverterCurveObj(nullptr), + Power_TempCurveObj(nullptr), + FClass(0), + VoltageModel(0), + PFNominal(0.0) +{ + int i; + + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // + PVSystem_ELEMENT; // In both PCelement and PVSystemelement list + Set_NPhases(3); + Fnconds = 4; // defaults to wye + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations + YearlyShape = ""; + YearlyShapeObj = nullptr; // If YearlyShapeobj = nil Then the Irradiance alway stays nominal + DailyShape = ""; + DailyShapeObj = nullptr; // If DaillyShapeobj = nil Then the Irradiance alway stays nominal + DutyShape = ""; + DutyShapeObj = nullptr; // If DutyShapeobj = nil Then the Irradiance alway stays nominal + DutyStart = 0.0; + YearlyTShape = ""; + YearlyTShapeObj = nullptr; // If YearlyShapeobj = nil Then the Temperature always stays nominal + DailyTShape = ""; + DailyTShapeObj = nullptr; // If DaillyShapeobj = nil Then the Temperature always stays nominal + DutyTShape = ""; + DutyTShapeObj = nullptr; // If DutyShapeobj = nil Then the Temperature always stays nominal + InverterCurveObj = nullptr; + Power_TempCurveObj = nullptr; + InverterCurve = ""; + Power_TempCurve = ""; + Connection = 0; // Wye (star, L-N) + VoltageModel = 1; /*Typical fixed kW negative load*/ + FClass = 1; + PVSystemSolutionCount = -1; // For keep track of the present solution in Injcurrent calcs + OpenPVSystemSolutionCount = -1; + YPrimOpenCond = nullptr; + PVSystemVars.kVPVSystemBase = 12.47; + VBase = 7200.0; + Vminpu = 0.90; + Vmaxpu = 1.10; + VBaseMin = Vminpu * VBase; + VBaseMax = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + RandomMult = 1.0; + Set_Varmode(VARMODEPF); + FInverterON = true; // start with inverterON + FVarFollowInverter = false; + ForceBalanced = false; + CurrentLimited = false; + NumStateVars = NumPVSystemVariables; + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + auto& with1 = myDynVars; + with0.FTemperature = 25.0; + with0.FIrradiance = 1.0; // kW/sq-m + with0.FkVArating = 500.0; + with0.FPmpp = 500.0; + with0.FpuPmpp = 1.0; // full on + with0.Vreg = 9999; + with0.Vavg = 9999; + with0.VVOperation = 9999; + with0.VWOperation = 9999; + with0.DRCOperation = 9999; + with0.VVDRCOperation = 9999; + with0.WPOperation = 9999; + with0.WVOperation = 9999; + // kW_out_desired :=9999; + with0.Fkvarlimit = with0.FkVArating; + with0.Fkvarlimitneg = with0.FkVArating; + with0.P_priority = false; // This is a change from older versions + with0.PF_Priority = false; + with1.RatedVDC = 8000; + with1.SMThreshold = 80; + with1.SafeMode = false; + with1.Kp = 0.00001; + with1.ILimit = -1; // No Amps limit + with1.IComp = 0; + with1.VError = 0.8; + } + FpctCutIn = 20.0; + FpctCutOut = 20.0; + FpctPminNoVars = -1.0; + FpctPminkvarLimit = -1.0; + Fpf_wp_nominal = 1.0; + /*Output rating stuff*/ + kW_out = 500.0; + kvar_out = 0.0; + PFNominal = 1.0; + pctR = 50.0; + pctX = 0.0; + PublicDataStruct = &PVSystemVars; + PublicDataSize = sizeof(TPVSystemVars); + kvarLimitSet = false; + kvarLimitNegSet = false; + UserModel = new TPVsystemUserModel(); + Reg_kWh = 1 - 1; + Reg_kvarh = 2 - 1; + Reg_MaxkW = 3 - 1; + Reg_MaxkVA = 4 - 1; + Reg_Hours = 5 - 1; + Reg_Price = 6 - 1; + DebugTrace = false; + PVsystemObjSwitchOpen = false; + Spectrum = ""; // override base class + SpectrumObj = nullptr; + FVWMode = false; + FVVMode = false; + FWVMode = false; + FWPMode = false; + FDRCMode = false; + FAVRMode = false; + InitPropertyValues(0); + RecalcElementData(ActiveActor); + + for (i = 0; i < NumPVSystemRegisters; i++) + { + Registers[i] = 0.0; + Derivatives[i] = 0.0; + } +} +// Define default values for the properties + +void TPVsystemObj::InitPropertyValues(int ArrayOffset) +{ + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(propKV,Format("%-g", with0.kVPVSystemBase)); + Set_PropertyValue(propIrradiance,Format("%-g", with0.FIrradiance)); + Set_PropertyValue(propPF,Format("%-g", PFNominal)); + Set_PropertyValue(propMODEL,"1"); + Set_PropertyValue(propYEARLY,""); + Set_PropertyValue(propDAILY,""); + Set_PropertyValue(propDUTY,""); + Set_PropertyValue(propTYEARLY,""); + Set_PropertyValue(propTDAILY,""); + Set_PropertyValue(propTDUTY,""); + Set_PropertyValue(PropConnection,"wye"); + Set_PropertyValue(propKVAR,Format("%-g", Get_Presentkvar())); + Set_PropertyValue(propPCTR,Format("%-g", pctR)); + Set_PropertyValue(propPCTX,Format("%-g", pctX)); + Set_PropertyValue(propCLASS,"1"); //'class' + Set_PropertyValue(propInvEffCurve,""); + Set_PropertyValue(propTemp,Format("%-g", with0.FTemperature)); + Set_PropertyValue(propPmpp,Format("%-g", with0.FPmpp)); + Set_PropertyValue(propP_T_Curve,""); + Set_PropertyValue(propCutin,"20"); + Set_PropertyValue(propCutout,"20"); + Set_PropertyValue(propVarFollowInverter,"NO"); + Set_PropertyValue(propVMINPU,"0.90"); + Set_PropertyValue(propVMAXPU,"1.10"); + Set_PropertyValue(propKVA,Format("%-g", with0.FkVArating)); + Set_PropertyValue(propUSERMODEL,""); // Usermodel + Set_PropertyValue(propUSERDATA,""); // Userdata + Set_PropertyValue(propDEBUGTRACE,"NO"); + Set_PropertyValue(proppctPmpp,"100"); + Set_PropertyValue(propBalanced,"NO"); + Set_PropertyValue(propLimited,"NO"); + Set_PropertyValue(propkvarLimit,Format("%-g", with0.Fkvarlimit)); + Set_PropertyValue(propkvarLimitneg,Format("%-g", PVSystemVars.Fkvarlimitneg)); + Set_PropertyValue(propPpriority,"NO"); + Set_PropertyValue(propPFpriority,"NO"); + Set_PropertyValue(propkVDC,"8000"); + Set_PropertyValue(propkp,"0.00001"); + Set_PropertyValue(propCtrlTol,"5"); + Set_PropertyValue(propSMT,"80"); + Set_PropertyValue(propSM,"NO"); + Set_PropertyValue(propGFM,"GFL"); + + } + inherited::InitPropertyValues(NumPropsThisClass); +} + +String TPVsystemObj::GetPropertyValue(int Index) +{ + String result = ""; + + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + switch(Index) + { + case propKV: + result = Format("%.6g", with0.kVPVSystemBase); + break; + case propIrradiance: + result = Format("%.6g", with0.FIrradiance); + break; + case propPF: + result = Format("%.6g", PFNominal); + break; + case propMODEL: + result = Format("%d", VoltageModel); + break; + case propYEARLY: + result = YearlyShape; + break; + case propDAILY: + result = DailyShape; + break; + case propDUTY: + result = DutyShape; + break; + case propTYEARLY: + result = YearlyTShape; + break; + case propTDAILY: + result = DailyTShape; + break; + case propTDUTY: + result = DutyTShape; + break; + case PropConnection: + if (Connection == 0) + result = "wye"; + else + result = "delta"; + break; + case propKVAR: + result = Format("%.6g", kvar_out); + break; + case propPCTR: + result = Format("%.6g", pctR); + break; + case propPCTX: + result = Format("%.6g", pctX); + break; + /*propCLASS = 17;*/ + case propInvEffCurve: + result = InverterCurve; + break; + case propTemp: + result = Format("%.6g", with0.FTemperature); + break; + case propPmpp: + result = Format("%.6g", with0.FPmpp); + break; + case propP_T_Curve: + result = Power_TempCurve; + break; + case propCutin: + result = Format("%.6g", FpctCutIn); + break; + case propCutout: + result = Format("%.6g", FpctCutOut); + break; + case propVarFollowInverter: + if(FVarFollowInverter) + result = "Yes"; + else + result = "No"; + break; + case propPminNoVars: + result = Format("%.6g", FpctPminNoVars); + break; + case propPminkvarLimit: + result = Format("%.6g", FpctPminkvarLimit); + break; + case propVMINPU: + result = Format("%.6g", Vminpu); + break; + case propVMAXPU: + result = Format("%.6g", Vmaxpu); + break; + case propKVA: + result = Format("%.6g", with0.FkVArating); + break; + case propUSERMODEL: + result = UserModel->FName; + break; + case propUSERDATA: + result = String("(") + inherited::GetPropertyValue(Index) + ")"; + break; + case proppctPmpp: + result = Format("%.6g", with0.FpuPmpp * 100.0); + break; + case propBalanced: + if(ForceBalanced) + result = "Yes"; + else + result = "No"; + break; + case propLimited: + if(CurrentLimited) + result = "Yes"; + else + result = "No"; + break; + case propkvarLimit: + result = Format("%.6g", with0.Fkvarlimit); + break; + case propkvarLimitneg: + result = Format("%.6g", PVSystemVars.Fkvarlimitneg); + break; + case propDutyStart: + result = Format("%.6g", DutyStart); + break; + case propkVDC: + result = Format("%.6g", myDynVars.RatedVDC / 1000); + break; + case propkp: + result = Format("%.10g", myDynVars.Kp * 1000); + break; + case propCtrlTol: + result = Format("%.6g", myDynVars.CtrlTol * 100); + break; + case propSMT: + result = Format("%.6g", myDynVars.SMThreshold); + break; + case propSM: + result = (myDynVars.SafeMode) ? "Yes" : "No"; + break; + case propDynEq: + result = DynamicEq; + break; + case propDynOut: + result = GetDynOutputStr(); + break; + case propGFM: + result = (GFM_Mode) ? "GFM" : "GFL"; + break; + /*propDEBUGTRACE = 33;*/ // take the generic handler + default: + result = inherited::GetPropertyValue(Index); + break; + } + } + return result; +} + +TPVsystemObj::~TPVsystemObj() +{ + delete YPrimOpenCond; + delete UserModel; + // inherited::Destroy(); +} + + +void TPVsystemObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + RandomMult = Gauss(YearlyShapeObj->Get_Mean(), YearlyShapeObj->Get_StdDev()); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + RandomMult = QuasiLogNormal(YearlyShapeObj->Get_Mean()); + break; + default: + ; + break; + } +} + +void TPVsystemObj::CalcDailyMult(double hr) +{ + if(DailyShapeObj != nullptr) + { + ShapeFactor = DailyShapeObj->GetMult(hr); + } + else + ShapeFactor = CDoubleOne; // Default to no variation +} + +void TPVsystemObj::CalcDailyTemperature(double hr) +{ + if(DailyTShapeObj != nullptr) + { + TShapeValue = DailyTShapeObj->GetTemperature(hr); + } + else + TShapeValue = PVSystemVars.FTemperature; // Default to no variation +} + +void TPVsystemObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr + DutyStart); + } + else + CalcDailyMult(hr); // Default to Daily Mult If no duty curve specified +} + +void TPVsystemObj::CalcDutyTemperature(double hr) +{ + if(DutyTShapeObj != nullptr) + { + TShapeValue = DutyTShapeObj->GetTemperature(hr); + } + else + CalcDailyTemperature(hr); // Default to Daily Mult If no duty curve specified +} + +void TPVsystemObj::CalcYearlyMult(double hr) +{ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr + DutyStart); + } + else + CalcDailyMult(hr); // Defaults to Daily curve +} + +void TPVsystemObj::CalcYearlyTemperature(double hr) +{ + if(YearlyTShapeObj != nullptr) + { + TShapeValue = YearlyTShapeObj->GetTemperature(hr); + } + else + CalcDailyTemperature(hr); // Defaults to Daily curve +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Required for operation in GFM mode +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +void TPVsystemObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + if (GFM_Mode) + { + try + { + auto& with0 = ActiveCircuit[ActorID]->Solution; + for (i = 1; i <= Yorder; i++) + { + if (!ADiakoptics || (ActorID == 1)) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + YPrim->MVmult(Curr, &Vterminal[0]); // Current from Elements in System Y + + // Add Together with yprim currents + for (i = 1; i <= Yorder; i++) + Curr[i - 1] = csub(Curr[i - 1], InjCurrent[i - 1]); + } + catch (const std::exception &e) + { + DoErrorMsg(String("GetCurrents for Element: \"") + get_Name(), (std::string)e.what(), "Inadequate storage allotted for circuit element.", 327); + } + } + else + inherited::GetCurrents(Curr, ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Returns True if any of the inverter phases is overloaded +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +bool TPVsystemObj::CheckOLInverter(int ActorID) +{ + complex myCurr = cmplx(0, 0); + double MaxAmps = 0, + PhaseAmps = 0; + int i = 0; + bool result = false; + // Check if reaching saturation point in GFM + if (GFM_Mode) + { + ComputePanelPower(); + MaxAmps = ((PVSystemVars.FkVArating * 1000) / Get_NPhases()) / VBase; + ComputeIterminal(ActorID); + for (i = 1; i <= Get_NPhases(); i++) + { + myCurr = Iterminal[i - 1]; + PhaseAmps = cabs(myCurr); + if (PhaseAmps > MaxAmps) + { + result = true; + break; + } + } + } + + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Returns True if any of the inverter phases has reached the current limit +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +bool TPVsystemObj::CheckAmpsLimit(int ActorID) +{ + complex myCurr; + double myVolts; + double NomP; + double PhaseP; + double PhaseAmps; + int i; + // Check if reaching saturation point in GFM + bool result = false; + NomP = myDynVars.ILimit * VBase; + if (GFM_Mode) + { + GetCurrents(&Iterminal[0], ActorID); + myDynVars.IComp = 0.0; + for (i = 1; i <= Fnphases; i++) + { + myCurr = Iterminal[i - 1]; + PhaseAmps = cabs(myCurr); + myVolts = ctopolar(ActiveCircuit[ActorID]->Solution->NodeV[NodeRef[i - 1]]).mag; + PhaseP = PhaseAmps * myVolts; + if (PhaseP > NomP) + { + if (PhaseP > myDynVars.IComp) + myDynVars.IComp = PhaseP; + result = true; + } + } + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Implements the grid forming inverter control routine for the storage device +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +void TPVsystemObj::DoGFM_Mode(int ActorID) +{ + int j = 0, + i = 0; + double myW = 0, + ZSys = 0; + + myDynVars.BaseV = VBase; + myDynVars.Discharging = true; + + auto& with0 = ActiveCircuit[ActorID]->Solution; + + /*Initial conditions just in case*/ + if (myDynVars.Vgrid.size() < Fnphases) myDynVars.Vgrid.resize(Fnphases); + + for (i = 1; i <= Fnphases; i++) + myDynVars.Vgrid[i - 1] = ctopolar(with0->NodeV[NodeRef[i - 1]]); + if (myDynVars.IComp > 0) + { + ZSys = (2 * (VBase * myDynVars.ILimit)) - myDynVars.IComp; + myDynVars.BaseV = (ZSys / myDynVars.ILimit) * myDynVars.VError; + } + myDynVars.CalcGFMVoltage(ActorID, Get_NPhases(), &(Vterminal[0])); // needs to be referenced as 0 + YPrim->MVmult(InjCurrent, &(Vterminal[0])); // needs to be referenced as 1 + + set_ITerminalUpdated(false, ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TPVsystemObj::RecalcElementData(int ActorID) +{ + VBaseMin = Vminpu * VBase; + VBaseMax = Vmaxpu * VBase; + varBase = 1000.0 * kvar_out / Fnphases; + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + // values in ohms for thevenin equivalents + with0.RThev = pctR * 0.01 * Sqr(Get_PresentkV()) / with0.FkVArating * 1000.0; + with0.XThev = pctX * 0.01 * Sqr(Get_PresentkV()) / with0.FkVArating * 1000.0; + CutInkW = FpctCutIn * with0.FkVArating / 100.0; + CutOutkW = FpctCutOut * with0.FkVArating / 100.0; + if(FpctPminNoVars <= 0) + PminNoVars = -1; + else + PminNoVars = FpctPminNoVars * with0.FPmpp / 100.0; + if(FpctPminkvarLimit <= 0) + PminkvarLimit = -1; + else + PminkvarLimit = FpctPminkvarLimit * with0.FPmpp / 100.0; + } + SetNominalPVSystemOuput(ActorID); + /*Now check for errors. If any of these came out nil and the string was not nil, give warning*/ + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 563); + } + if(DailyShapeObj == nullptr) + { + if(DailyShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyShape + + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 565); + } + if(YearlyTShapeObj == nullptr) + { + if(YearlyTShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly temperature shape: \"") + YearlyTShape + + "\" Not Found.", 5631); + } + if(DailyTShapeObj == nullptr) + { + if(DailyTShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily temperature shape: \"") + DailyTShape + + "\" Not Found.", 5641); + } + if(DutyTShapeObj == nullptr) + { + if(DutyTShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty temperature shape: \"") + DutyTShape + + "\" Not Found.", 5651); + } + if(Spectrum.size() > 0) + { + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 566); + } + else + SpectrumObj = nullptr; + // Initialize to Zero - defaults to PQ PVSystem element + // Solution object will reset after circuit modifications + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + /*Update any user-written models*/ + if(UserModel->Get_Exists()) + UserModel->FUpdateModel(); +} + +void TPVsystemObj::SetNominalPVSystemOuput(int ActorID) +{ + ShapeFactor = CDoubleOne; // init here; changed by curve routine + TShapeValue = PVSystemVars.FTemperature; // init here; changed by curve routine + // Check to make sure the PVSystem element is ON + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) // Leave PVSystem element in whatever state it was prior to entering Dynamic mode + + // Check dispatch to see what state the PVSystem element should be in + { + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + switch(with2->Get_SolMode()) + { + case SNAPSHOT: + ; + break; /*Just solve for the present kW, kvar*/ // Don't check for state change + case DAILYMODE: + { + CalcDailyMult(with2->DynaVars.dblHour); + CalcDailyTemperature(with2->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + CalcYearlyMult(with2->DynaVars.dblHour); + CalcYearlyTemperature(with2->DynaVars.dblHour); + } + break; + /* + MONTECARLO1, + MONTEFAULT, + FAULTSTUDY, + DYNAMICMODE: ; // {do nothing yet} + */ + // This mode allows use of one class of load shape + case GENERALTIME: + { + switch(ActiveCircuit[ActiveActor]->ActiveLoadShapeClass) + { + case USEDAILY: + { + CalcDailyMult(with2->DynaVars.dblHour); + CalcDailyTemperature(with2->DynaVars.dblHour); + } + break; + case USEYEARLY: + { + CalcYearlyMult(with2->DynaVars.dblHour); + CalcYearlyTemperature(with2->DynaVars.dblHour); + } + break; + case USEDUTY: + { + CalcDutyMult(with2->DynaVars.dblHour); + CalcDutyTemperature(with2->DynaVars.dblHour); + } + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + // Assume Daily curve, If any, for the following + case MONTECARLO2: case MONTECARLO3: case LOADDURATION1: case LOADDURATION2: + { + CalcDailyMult(with2->DynaVars.dblHour); + CalcDailyTemperature(with2->DynaVars.dblHour); + } + break; + case PEAKDAY: + { + CalcDailyMult(with2->DynaVars.dblHour); + CalcDailyTemperature(with2->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + CalcDutyMult(with2->DynaVars.dblHour); + CalcDutyTemperature(with2->DynaVars.dblHour); + } + break; + /*AUTOADDFLAG: ; */ + default: + ; + break; + } + } + ComputekWkvar(); + Pnominalperphase = 1000.0 * kW_out / Fnphases; + Qnominalperphase = 1000.0 * kvar_out / Fnphases; + switch(VoltageModel) + { + case 3: + //**** Fix this when user model gets connected in + // YEQ := Cinv(cmplx(0.0, -StoreVARs.Xd)) ; // Gets negated in CalcYPrim + ; + break; + default: + Yeq = cdivreal(cmplx(Pnominalperphase, -Qnominalperphase), Sqr(VBase)); // Vbase must be L-N for 3-phase + if(Vminpu != 0.0) // at 95% voltage + YEQ_Min = cdivreal(Yeq, Sqr(Vminpu)); + else + YEQ_Min = Yeq; // Always a constant Z model + if(Vmaxpu != 0.0) // at 105% voltage + YEQ_Max = cdivreal(Yeq, Sqr(Vmaxpu)); + else + YEQ_Max = Yeq; + /* Like Model 7 generator, max current is based on amount of current to get out requested power at min voltage + */ + /*# with PVSystemVars do */ + { + auto& with3 = PVSystemVars; + PhaseCurrentLimit = cdivreal(cmplx(Pnominalperphase, Qnominalperphase), VBaseMin); + with3.MaxDynPhaseCurrent = cabs(PhaseCurrentLimit); + } + break; + } + /* When we leave here, all the YEQ's are in L-N values*/ + } /*If NOT (IsDynamicModel or IsHarmonicModel)*/ + } /*With ActiveCircuit[ActiveActor]*/ +} + +// =========================================================================================== + +void TPVsystemObj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit[ActiveActor]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + /*# with ActiveCircuit[ActiveActor].Solution do */ + { + auto with0 = ActiveCircuit[ActiveActor]->Solution; + if(with0->IsHarmonicModel) + /*YEQ is computed from %R and %X -- inverse of Rthev + j Xthev*/ + { + int stop = 0; + Y = Yeq; // L-N value computed in initial condition routines + if(Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(Fnconds, Fnconds, Y); + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(i, i, Y); // put it in again + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + else + // Regular power flow PVSystem element model + /*YEQ is always expected as the equivalent line-neutral admittance*/ + { + if (!GFM_Mode) + { + Y = cnegate(Yeq); // negate for generation YEQ is L-N quantity + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + switch (Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + with1->AddElement(Fnconds, Fnconds, Y); + with1->SetElemsym(i, Fnconds, Yij); + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + else + { + // Otherwise, the inverter is in GFM control modem calculation changes + myDynVars.RatedkVLL = Get_PresentkV(); + myDynVars.mKVARating = PVSystemVars.FkVArating; + myDynVars.CalcGFMYprim(ActorID, Get_NPhases(), Ymatrix); + } + } + } /*ELSE IF Solution.mode*/ +} + +void TPVsystemObj::ComputeInverterPower() +{ + double kVA_Gen = 0.0; + double Qramp_limit = 0.0; + double TempPF = 0.0; + double CutOutkWAC = 0.0; + double CutInkWAC = 0.0; + // Reset CurrentkvarLimit to kvarLimit + CurrentkvarLimit = PVSystemVars.Fkvarlimit; + CurrentkvarLimitNeg = PVSystemVars.Fkvarlimitneg; + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + with0.EffFactor = 1.0; + kW_out = 0.0; + if(ASSIGNED(InverterCurveObj)) + { + CutOutkWAC = CutOutkW * InverterCurveObj->GetYValue_(Abs(CutOutkW) / with0.FkVArating); + CutInkWAC = CutInkW * InverterCurveObj->GetYValue_(Abs(CutInkW) / with0.FkVArating); + } + else + // Assume Ideal Inverter + { + CutOutkWAC = CutOutkW; + CutInkWAC = CutInkW; + } + + // Determine state of the inverter + if(FInverterON) + { + if(with0.PanelkW < CutOutkW) + { + FInverterON = false; + } + } + else + { + if(with0.PanelkW >= CutInkW) + { + FInverterON = true; + } + } + // set inverter output. Defaults to 100% of the panelkW if no efficiency curve spec'd + if(FInverterON) + { + if(ASSIGNED(InverterCurveObj)) + with0.EffFactor = InverterCurveObj->GetYValue_(with0.PanelkW / with0.FkVArating); // pu eff vs pu power + kWOut_Calc(); + } + else + { + kW_out = 0.0; + } + if(Abs(kW_out) < PminNoVars) + { + kvar_out = 0.0; // Check minimum P for Q gen/absorption. if PminNoVars is disabled (-1), this will always be false + CurrentkvarLimit = 0; + CurrentkvarLimitNeg = 0.0; // Set current limit to be used by InvControl's Check_Qlimits procedure. + } + else + { + if(Get_Varmode() == VARMODEPF) + { + if(PFNominal == 1.0) + kvar_out = 0.0; + else + { + kvar_out = kW_out * sqrt(1.0L / Sqr(PFNominal) - 1.0L) * Sign(PFNominal); + // Check limits + if(Abs(kW_out) < PminkvarLimit) // straight line limit check. if PminkvarLimit is disabled (-1), this will always be false. + + // straight line starts at max(PminNoVars, CutOutkWAC) + // if CutOut differs from CutIn, take cutout since it is assumed that CutOut <= CutIn always. + { + if(Abs(kW_out) >= max(PminNoVars, CutOutkWAC)) + { + if(kvar_out > 0.0) + { + Qramp_limit = with0.Fkvarlimit / PminkvarLimit * Abs(kW_out); // generation limit + CurrentkvarLimit = Qramp_limit; // For use in InvControl + } + else + { + if(kvar_out < 0.0) + { + Qramp_limit = double(PVSystemVars.Fkvarlimitneg) / PminkvarLimit * Abs( kW_out); // absorption limit + CurrentkvarLimitNeg = Qramp_limit; // For use in InvControl + } + } + if(Abs( kvar_out) > Qramp_limit) + kvar_out = Qramp_limit * Sign(kW_out) * Sign(PFNominal); + } + } + else + { + if((Abs( kvar_out) > with0.Fkvarlimit) || (Abs( kvar_out) > PVSystemVars.Fkvarlimitneg)) // Other cases, check normal kvarLimit and kvarLimitNeg + { + if(kvar_out > 0.0) + kvar_out = with0.Fkvarlimit * Sign(kW_out) * Sign(PFNominal); + else + kvar_out = PVSystemVars.Fkvarlimitneg * Sign(kW_out) * Sign(PFNominal); + if(with0.PF_Priority) // Forces constant power factor when kvar limit is exceeded and PF Priority is true. + { + kW_out = kvar_out * sqrt(1.0 / (1.0L - Sqr(PFNominal)) - 1.0) * Sign(PFNominal); + } + } + } + } + } + else + // kvar is specified + + // Check limits + { + if(Abs( kW_out) < PminkvarLimit) // straight line limit check. if PminkvarLimit is disabled (-1), this will always be false. + + // straight line starts at max(PminNoVars, CutOutkWAC) + // if CutOut differs from CutIn, take cutout since it is assumed that CutOut <= CutIn always. + { + if(Abs( kW_out) >= max(PminNoVars, CutOutkWAC)) + { + if(kvarRequested > 0.0) + { + Qramp_limit = with0.Fkvarlimit / PminkvarLimit * Abs( kW_out); // generation limit + CurrentkvarLimit = Qramp_limit; // For use in InvControl + } + else + { + if(kvarRequested < 0.0) + { + Qramp_limit = double(PVSystemVars.Fkvarlimitneg) / PminkvarLimit * Abs( kW_out); // absorption limit + CurrentkvarLimitNeg = Qramp_limit; // For use in InvControl + } + } + if(Abs( kvarRequested) > Qramp_limit) + kvar_out = Qramp_limit * Sign(kvarRequested); + else + kvar_out = kvarRequested; + } + } + else + { + if(((kvarRequested > 0.0) && (Abs( kvarRequested) >= with0.Fkvarlimit)) || ((kvarRequested < 0.0) && (Abs( kvarRequested) >= PVSystemVars.Fkvarlimitneg))) + { + if(kvarRequested > 0.0) + kvar_out = with0.Fkvarlimit * Sign(kvarRequested); + else + kvar_out = PVSystemVars.Fkvarlimitneg * Sign(kvarRequested); + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && FWPMode) + { + kW_out = Abs( kvar_out) * sqrt(1.0 / (1.0L - Sqr(Fpf_wp_nominal)) - 1.0) * Sign(kW_out); + // Forces constant power factor when kvar limit is exceeded and PF Priority is true. Temp PF is calculated based on kvarRequested + } + else + { + if(with0.PF_Priority && (!FVVMode || !FDRCMode || !FWVMode || !FAVRMode)) + { + if(Abs( kvarRequested) > 0.0) + { + TempPF = cos(atan(Abs( (kvarRequested / kW_out)))); + kW_out = Abs( kvar_out) * sqrt(1.0 / (1.0L - Sqr(TempPF)) - 1.0) * Sign(kW_out); + } + } + } + } + else + kvar_out = kvarRequested; + } + } + } + if((FInverterON == false) && (FVarFollowInverter == true)) + kvar_out = 0.0; + // Limit kvar and kW so that kVA of inverter is not exceeded + kVA_Gen = sqrt(Sqr(kW_out) + Sqr(kvar_out)); + if(kVA_Gen > with0.FkVArating) + { + if((Get_Varmode() == VARMODEPF) && with0.PF_Priority) + // Operates under constant power factor when kVA rating is exceeded. PF must be specified and PFPriority must be TRUE + { + kW_out = with0.FkVArating * Abs( PFNominal); + kvar_out = with0.FkVArating * sqrt(1.0L - Sqr(PFNominal)) * Sign(PFNominal); + } + else + { + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && FWPMode) + { + kW_out = with0.FkVArating * Abs(Fpf_wp_nominal) * Sign(kW_out); + kvar_out = with0.FkVArating * Abs( sin(acos(Fpf_wp_nominal))) * Sign(kvarRequested); + } + else + { + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && (!FVVMode || !FDRCMode || !FWVMode || !FAVRMode)) + // Operates under constant power factor (PF implicitly calculated based on kw and kvar) + { + if(Abs( kvar_out) == with0.Fkvarlimit) // for handling cases when kvar limit and inverter's kVA limit are exceeded + { + kW_out = with0.FkVArating * Abs( TempPF) * Sign(kW_out); + } + else + { + kW_out = with0.FkVArating * Abs( cos(atan(kvarRequested / kW_out))) * Sign(kW_out); + } + kvar_out = with0.FkVArating * Abs( sin(acos(kW_out / with0.FkVArating))) * Sign(kvarRequested); + } + else + { + if(with0.P_priority) // back off the kvar + { + if(kW_out > with0.FkVArating) + { + kW_out = with0.FkVArating; + kvar_out = 0.0; + } + else + kvar_out = sqrt(Sqr(with0.FkVArating) - Sqr(kW_out)) * Sign(kvar_out); + } + else + kW_out = sqrt(Sqr(with0.FkVArating) - Sqr(kvar_out)) * Sign(kW_out); + } + } + } + } + if((FInverterON == false) && (FVarFollowInverter == true)) + kvar_out = 0.0; + } /*With PVSystemVars*/ +} + +void TPVsystemObj::ComputekWkvar() +{ + ComputePanelPower(); // apply irradiance + ComputeInverterPower(); // apply inverter eff after checking for cutin/cutout +} +// =========================================================================================== + +void TPVsystemObj::ComputePanelPower() +{ + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + with0.TempFactor = 1.0; + if(ASSIGNED(Power_TempCurveObj)) + { + with0.TempFactor = Power_TempCurveObj->GetYValue_(TShapeValue); // pu Set_Pmpp vs T (actual) + } + with0.PanelkW = with0.FIrradiance * ShapeFactor.re * with0.FPmpp * with0.TempFactor; + } +} + +void TPVsystemObj::CalcYPrim(int ActorID) +{ + int i = 0; + // Build only shunt Yprim + // Build a dummy Yprim Series so that CalcV Does not fail + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + SetNominalPVSystemOuput(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages Doesn't fail + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + YPrim->CopyFrom(YPrim_Shunt); + // Account for Open Conductors + inherited::CalcYPrim(ActorID); +} +// =========================================================================================== + + /*Add the current into the proper location according to connection*/ + /*Reverse of similar routine in load (Cnegates are switched)*/ + +void TPVsystemObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum((TermArray)[i - 1], Curr); + caccum((TermArray)[Fnconds - 1], cnegate(Curr)); // Neutral + } + break; //DELTA + case 1: + { + caccum((TermArray)[i - 1], Curr); + j = i + 1; + if(j > Fnconds) + j = 1; + caccum((TermArray)[j - 1], cnegate(Curr)); + } + break; + default: + ; + break; + } +} +// =========================================================================================== + +void TPVsystemObj::WriteTraceRecord(const String s) +{ + int i = 0; + try + { + if(!InShowResults) + { + int stop = 0; + Append(Tracefile); + IOResultToException(); + { Write(Tracefile, Format("%-.g, %d, %-.g, ", + ActiveCircuit[ActiveActor]->Solution->DynaVars.T, ActiveCircuit[ActiveActor]->Solution->Iteration, ActiveCircuit[ActiveActor]->get_FLoadMultiplier())); + Write(Tracefile, GetSolutionModeID()); Write(Tracefile, ", "); Write(Tracefile, GetLoadModel()); Write(Tracefile, ", "); + Write(Tracefile, VoltageModel, 0); Write(Tracefile, ", "); Write(Tracefile, (Qnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile, ", "); Write(Tracefile, (Pnominalperphase * 3.0 / 1.0e6), 8, 2); Write(Tracefile, ", "); + Write(Tracefile, s); Write(Tracefile, ", "); } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((InjCurrent)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Iterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Vterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + catch (...) + { + } +} + +// =========================================================================================== + +/*Compute total terminal current for Constant PQ*/ + +void TPVsystemObj::DoConstantPQPVsystemObj(int ActorID) +{ + int i = 0; + complex PhaseCurr = {}; + complex DeltaCurr = {}; + complex VLN = {}; + complex VLL = {}; + double VmagLN = 0.0; + double VmagLL = 0.0; + complex V012[4] = { CZero, CZero, CZero, CZero, }; // Sequence voltages + + auto with0 = ActiveCircuit[ActorID]->Solution; + + //Treat this just like the Load model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + ZeroITerminal(); + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: /*Wye*/ + { + VLN = (Vterminal)[i - 1]; + VmagLN = cabs(VLN); + if(CurrentLimited) + /*Current-Limited Model*/ + { + PhaseCurr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLN)); + if(cabs(PhaseCurr) > PVSystemVars.MaxDynPhaseCurrent) + PhaseCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLN, VmagLN))); + } + else + + /*The usual model*/ + { + if(VmagLN <= VBaseMin) // Below Vminpu use an impedance model + PhaseCurr = cmul(YEQ_Min, VLN); + else + { + if(VmagLN > VBaseMax) // above Vmaxpu use an impedance model + PhaseCurr = cmul(YEQ_Max, VLN); + else + PhaseCurr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLN)); // Between Vminpu and Vmaxpu, constant PQ + } + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(PhaseCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, PhaseCurr, i); // Put into Terminal array taking into account connection + } + break; /*Delta*/ + case 1: + { + VLL = (Vterminal)[i - 1]; + VmagLL = cabs(VLL); + if(CurrentLimited) + /*Current-Limited Model*/ + { + DeltaCurr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLL)); + if(cabs(DeltaCurr) * SQRT3 > PVSystemVars.MaxDynPhaseCurrent) + DeltaCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLL / SQRT3))); + } + else + + /*The usual model*/ + { + switch(Fnphases) + { + case 2: + case 3: + VmagLN = VmagLL / SQRT3; + break; + default: + VmagLN = VmagLL; + break; + } + if(VmagLN <= VBaseMin) // Below 95% use an impedance model + DeltaCurr = cmul(cdivreal(YEQ_Min, 3.0), VLL); + else + { + if(VmagLN > VBaseMax) // above 105% use an impedance model + DeltaCurr = cmul(cdivreal(YEQ_Max, 3.0), VLL); + else + DeltaCurr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLL)); // Between 95% -105%, constant PQ + } + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(DeltaCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, DeltaCurr, i); // Put into Terminal array taking into account connection + } + break; + default: + ; + break; + } + if (with0->Algorithm == NCIMSOLVE) // NCIM solution algorithms + DoPQBusNCIM(ActorID, i, Vterminal[i - 1], DeltaCurr); + } +} +// =========================================================================================== + +/*constant Z model*/ + +void TPVsystemObj::DoConstantZPVsystemObj(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex YEQ2 = {}; + complex V012[4] = { CZero, CZero, CZero, CZero, }; // Sequence voltages + auto with0 = ActiveCircuit[ActorID]->Solution; + + // Assume YEQ is kept up to date + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + ZeroITerminal(); + if(Connection == 0) // YEQ is always line to neutral + YEQ2 = Yeq; + else + YEQ2 = cdivreal(Yeq, 3.0); // YEQ for delta connection + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmul(YEQ2, (Vterminal)[i - 1]); + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + + if (with0->Algorithm == NCIMSOLVE) // NCIM solution algorithms + DoPQBusNCIM(ActorID, i, Vterminal[i - 1], Curr); + } +} + +// =================================================================DOUSERMODEL========================== + +/*Compute total terminal Current from User-written model*/ + +void TPVsystemObj::DoUserModel(int ActorID) +{ + int i = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + if(UserModel->Get_Exists()) // Check automatically selects the usermodel If true + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); + set_ITerminalUpdated(true, ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; // Negate currents from user model for power flow PVSystem element model + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + } + } + else + DoSimpleMsg(String("PVSystem.") + get_Name() + + " model designated to use user-written model, but user-written model is not defined.", 567); +} +// ===============================================================DoDynamicMode============================ + +/*Compute Total Current and add into InjTemp*/ + +void TPVsystemObj::DoDynamicMode(int ActorID) +{ + int i = 0; + complex V012[3/*# range 0..2*/] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + complex I012[3/*# range 0..2*/] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + + double Theta = 0.0, // phase angle of thevinen source + iActual = 0.0; + complex NeutAmps = cmplx(0,0), + Vthev = cmplx(0,0); + polar PolarN = ctopolar(cmplx(0,0)); + + /*-------------- Internal Proc -----------------------*/ + + auto CalcVthev_Dyn = [&](const complex& V) -> void + { + + /*Try to keep in phase with terminal voltage*/ + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + if(cabs(V) > 0.20 * VBase) + Theta = with0.ThetaDyn + (cang(V) - with0.InitialVAngle); + else + Theta = LastThevAngle; + Vthev = pclx(with0.VthevmagDyn, Theta); + LastThevAngle = Theta; // remember this for angle persistence + } + }; + + if (!GFM_Mode) + { + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array and computes VTerminal + //{Inj = -Itotal(in) - Yprim * Vtemp} + if (VoltageModel == 3) + { + if (UserModel->Get_Exists()) + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); // returns terminal currents in Iterminal + else + { + DoSimpleMsg(Format("Dynamics model missing for PVSystem.% s ", get_Name().c_str()), 5671); + SolutionAbort = true; + } + } + else + { + ZeroITerminal(); + //{This model has no limitation in the nmber of phasesand is ideally unbalanced(no dq - dv, but is implementable as well)} + // First, get the phase angles for the currents + NeutAmps = cmplx(0, 0); + for (i = 1; i <= Fnphases; i++) + { + auto& with0 = myDynVars; + + if (with0.it[i - 1] <= with0.iMaxPPhase || GFM_Mode) + iActual = with0.it[i - 1]; + else + iActual = with0.iMaxPPhase; + //----------------------------------------------------------- + + PolarN = topolar(iActual, with0.Vgrid[i - 1].ang); // Output Current estimated for active power + Iterminal[i - 1] = cnegate(ptocomplex(PolarN)); + NeutAmps = csub(NeutAmps, Iterminal[i - 1]); + } + if (Fnconds > Fnphases) + Iterminal[Fnconds - 1] = NeutAmps; + //{Add it into inj current array} + for (i = 1; i <= Fnconds; i++) + caccum(InjCurrent[i - 1], cnegate(Iterminal[i - 1])); + set_ITerminalUpdated(true, ActorID); + } + } + else + { + myDynVars.BaseV = myDynVars.BasekV * 1000 * (myDynVars.it[0] / myDynVars.iMaxPPhase); + myDynVars.CalcGFMVoltage(ActorID, Get_NPhases(), &(Vterminal[0])); // needs to be referenced as 0 + YPrim->MVmult(InjCurrent, &(Vterminal[0])); // needs to be referenced as 1 + } +} +// ====================================================================DoHarmonicMode======================= + +/*Compute Injection Current Only when in harmonics mode*/ +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TPVsystemObj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double PVSystemHarmonic = 0.0; + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution, PVSystemVars do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = PVSystemVars; + int stop = 0; + PVSystemHarmonic = with0->get_FFrequency() / PVSystemFundamental; + if(SpectrumObj != nullptr) // Get base harmonic magnitude + e = cmulreal(SpectrumObj->GetMult(PVSystemHarmonic), with1.VThevHarm); + else + e = CZero; + RotatePhasorRad(e, PVSystemHarmonic, with1.ThetaHarm); // Time shift by fundamental frequency phase shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, PVSystemHarmonic, -120.0); // Assume 3-phase PVSystem element + } + } + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} +// =========================================================================================== + +void TPVsystemObj::CalcVTerminalPhase(int ActorID) +{ + int i = 0; + int j = 0; + /* Establish phase voltages and stick in Vterminal*/ + switch(Connection) + { + case 0: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Vterminal[i - 1] = with0->VDiff(NodeRef[i - 1], NodeRef[Fnconds - 1], ActorID); + } + } + } + break; + case 1: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; + Vterminal[i - 1] = with1->VDiff(NodeRef[i - 1], NodeRef[j - 1], ActorID); + } + } + } + break; + default: + ; + break; + } + PVSystemSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} +// =========================================================================================== +/* +PROCEDURE TPVsystemObj.CalcVTerminal; +{Put terminal voltages in an array} +Begin + ComputeVTerminal; + PVSystemSolutionCount := ActiveCircuit[ActiveActor].Solution.SolutionCount; +End; +*/ + +// ============================================CalcPVSystemModelContribution=============================================== + +// Calculates PVSystem element current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TPVsystemObj::CalcPVSystemModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + // compute currents and put into InjTemp array; + if (GFM_Mode) + DoGFM_Mode(ActorID); + else + { + switch(VoltageModel) + { + case 1: + DoConstantPQPVsystemObj(ActorID); + break; + case 2: + DoConstantZPVsystemObj(ActorID); + break; + case 3: + DoUserModel(ActorID); + break; + default: + DoConstantPQPVsystemObj(ActorID); // for now, until we implement the other models. + break; + } + } /*ELSE*/ + } + } /*WITH*/ + /*When this is Done, ITerminal is up to date*/ +} +// ==========================================CalcInjCurrentArray================================================= + + // Difference between currents in YPrim and total current + +void TPVsystemObj::CalcInjCurrentArray(int ActorID) +{ + + // Now Get Injection Currents + if(PVsystemObjSwitchOpen) + ZeroInjCurrent(); + else + CalcPVSystemModelContribution(ActorID); +} + +// ----------------------------------------------------------------------------------- +// Updates the Jacobian matrix diagonal and calculates the Amps delta using deltaF +void TPVsystemObj::DoPQBusNCIM(int ActorID, int i, complex V, complex Curr) +{ + complex Pow = {}, + FaVr = {}, + FaVm = {}, + Temp = {}, + Vc2 = {}; + + int LCoords[4][2] = { {0,0}, {1,1}, {0,1}, {1,0} }; + int GCoord = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + Pow = conjg(cmplx(-Pnominalperphase, -Qnominalperphase)); + Vc2 = cmul(conjg(V), conjg(V)); + FaVr = cdiv(cmplx(-1, 0), Vc2); + FaVm = cdiv(cmplx(0, 1), Vc2); + GCoord = (NodeRef[i - 1] * 2) - 1; + // Updates the Jacobian + for (int j = 0; j < 4; j++) + { + // Add the derivatives + switch (j) + { + case 0: // dImdVr + Temp.re = cmul(FaVr, Pow).im; + break; + case 1: // dIrdVm + Temp.re = cmul(FaVm, Pow).re; + break; + case 2: // dImdVm + Temp.re = cmul(FaVm, Pow).im; + break; + case 3: // dIrdVr + Temp.re = cmul(FaVr, Pow).re; + break; + default: + break; + } + SetMatrixElement(with0->Jacobian, GCoord + LCoords[j][0], GCoord + LCoords[j][1], &Temp); + } + + // Add current injection contributions to deltaF + GCoord--; // Removes the additional index added by DSS + Iterminal[i - 1] = Curr; + with0->deltaF[GCoord].re = Curr.im + with0->deltaF[GCoord].re; // Respecting the decoupled distribution + with0->deltaF[GCoord + 1].re = Curr.re + with0->deltaF[GCoord + 1].re; // Prioritizing reactive power over the diagonal +} + +// =========================================GetTerminalCurrents================================================== + +// Compute total Currents + +void TPVsystemObj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + { + if(!PVsystemObjSwitchOpen) + CalcPVSystemModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); + } + if(DebugTrace) + WriteTraceRecord("TotalCurrent"); +} +// ===========================================INJCURRENTS================================================ + +int TPVsystemObj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->LoadsNeedUpdating) + SetNominalPVSystemOuput(ActorID); // Set the nominal kW, etc for the type of solution being Done + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + if(DebugTrace) + WriteTraceRecord("Injection"); + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} +// =========================================================================================== + +// Gives the currents for the last solution performed +// Do not call SetNominal, as that may change the load values + +void TPVsystemObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("PVSystem Object: \"") + get_Name() + "\" in GetInjCurrents FUNCTION.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} + +//-------------------------------------------------------------------------------------------- + +double TPVsystemObj::get_PFNominal() +{ + return PFNominal; +} + +//-------------------------------------------------------------------------------------------- + +double TPVsystemObj::get_Vminpu() +{ + return Vminpu; +} + +//-------------------------------------------------------------------------------------------- + +double TPVsystemObj::get_Fkvarlimitneg() +{ + return PVSystemVars.Fkvarlimitneg; +} + +// =========================================================================================== + +void TPVsystemObj::ResetRegisters() +{ + int i = 0; + int stop = 0; + for(stop = NumPVSystemRegisters, i = 1; i <= stop; i++) + { + Registers[i - 1] = 0.0; + } + for(stop = NumPVSystemRegisters, i = 1; i <= stop; i++) + { + Derivatives[i - 1] = 0.0; + } + FirstSampleAfterReset = true; // initialize for trapezoidal integration +} +// =========================================================================================== + +void TPVsystemObj::Integrate(int reg, double Deriv, double Interval) +{ + if(ActiveCircuit[ActiveActor]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + Registers[reg] = Registers[reg] + 0.5 * Interval * (Deriv + Derivatives[reg]); + } + else + /*Plain Euler integration*/ + Registers[reg] = Registers[reg] + Interval * Deriv; + Derivatives[reg] = Deriv; +} +// =========================================================================================== + +// Update Energy from metered zone + +void TPVsystemObj::TakeSample(int ActorID) +{ + complex s = {}; + double Smag = 0.0; + double HourValue = 0.0; + // Compute energy in PVSystem element branch + if(Get_Enabled()) + { + s = cmplx(Get_PresentkW(), Get_Presentkvar()); + Smag = cabs(s); + HourValue = 1.0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(ActiveCircuit[ActorID]->PositiveSequence) + { + s = cmulreal(s, 3.0); + Smag = 3.0 * Smag; + } + Integrate(Reg_kWh, s.re, with0->IntervalHrs); // Accumulate the power + Integrate(Reg_kvarh, s.im, with0->IntervalHrs); + SetDragHandRegister(Reg_MaxkW, Abs( s.re)); + SetDragHandRegister(Reg_MaxkVA, Smag); + Integrate(Reg_Hours, HourValue, with0->IntervalHrs); // Accumulate Hours in operation + Integrate(Reg_Price, s.re * ActiveCircuit[ActorID]->PriceSignal * 0.001, with0->IntervalHrs); // + FirstSampleAfterReset = false; + } + } +} +/*Update PVSystem levels*/ + +void TPVsystemObj::UpdatePVSystem() +{ + + /* Do Nothing*/ +} + +double TPVsystemObj::Get_PresentkW() +{ + double result = 0.0; + result = Pnominalperphase * 0.001 * Fnphases; + return result; +} + +double TPVsystemObj::Get_PresentIrradiance() +{ + double result = 0.0; + result = PVSystemVars.FIrradiance * ShapeFactor.re; + return result; +} + +double TPVsystemObj::Get_PresentkV() +{ + double result = 0.0; + result = PVSystemVars.kVPVSystemBase; + return result; +} + +double TPVsystemObj::Get_Presentkvar() +{ + double result = 0.0; + result = Qnominalperphase * 0.001 * Fnphases; + return result; +} + +bool TPVsystemObj::Get_VarFollowInverter() +{ + bool result = false; + if(FVarFollowInverter) + result = true; + else + result = false; + return result; +} + +void TPVsystemObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; // HERE + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; + switch(Idx) + { + case propUSERDATA: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + +// ============================================================InitHarmonics=============================== + +// This routine makes a thevenin equivalent behis the reactance spec'd in %R and %X + +void TPVsystemObj::InitHarmonics(int ActorID) +{ + int i = 0; + int j = 0; + complex e = {}; + complex Va = {}; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + PVSystemFundamental = ActiveCircuit[ActorID]->Solution->get_FFrequency(); // Whatever the frequency is when we enter here. + /*Compute reference Thevinen voltage from phase 1 current*/ + ComputeIterminal(ActorID); // Get present value of current + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + switch(Connection) + { + case 0: /*wye - neutral is explicit*/ + { + if(!ADiakoptics || (ActorID == 1)) + Va = csub(with0->NodeV[(NodeRef)[1 - 1]], with0->NodeV[(NodeRef)[Fnconds - 1]]); + else + Va = csub(with0->VoltInActor1((NodeRef)[1 - 1]), with0->VoltInActor1((NodeRef)[Fnconds - 1])); + } + break; /*delta -- assume neutral is at zero*/ + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + Va = with0->NodeV[(NodeRef)[1 - 1]]; + else + Va = with0->VoltInActor1((NodeRef)[1 - 1]); + } + break; + default: + ; + break; + } + } + /*# with PVSystemVars do */ + { + auto& with1 = PVSystemVars; + Yeq = cinv(cmplx(with1.RThev, with1.XThev)); // used for current calcs Always L-N + e = csub(Va, cmul((Iterminal)[1 - 1], cmplx(with1.RThev, with1.XThev))); + with1.VThevHarm = cabs(e); // establish base mag and angle + with1.ThetaHarm = cang(e); + } +} + +// ===============================================================InitStateVars============================ + +// for going into dynamics mode + +void TPVsystemObj::InitStateVars(int ActorID) +{ + +// VNeut, + complex Edp = {}; + complex V12 = {}; + double BaseZt = 0.0; + int i = 0, + j = 0; + + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + if (PICtrl.empty() || (PICtrl.size() < Fnphases)) + { + PICtrl.resize(Fnphases); + for (i = 0; i < Fnphases; i++) + { + PICtrl[i] = TPICtrl(); + PICtrl[i].Kp = myDynVars.Kp; + PICtrl[i].kNum = 0.9502; + PICtrl[i].kDen = 0.04979; + } + } + myDynVars.SafeMode = false; + auto with2 = ActiveCircuit[ActorID]->Solution; + auto& with3 = PVSystemVars; + auto& with4 = myDynVars; + + switch (ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with2->DynaVars.dblHour); + CalcDailyTemperature(with2->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with2->DynaVars.dblHour); + CalcYearlyTemperature(with2->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with2->DynaVars.dblHour); + CalcDutyTemperature(with2->DynaVars.dblHour); + break; + default: + ShapeFactor = CDoubleOne; // default to 1 + j1 if not known + break; + } + + ComputePanelPower(); + + with3.NumPhases = Fnphases; + with3.NumConductors = Fnconds; + with3.Conn = Connection; + + with4.InitDynArrays(with3.NumPhases); + if (with3.NumPhases > 1) + with4.BasekV = Get_PresentkV() / sqrt(3); + else + with4.BasekV = Get_PresentkV(); + + BaseZt = 0.01 * (sqr(Get_PresentkV()) / with3.FkVArating) * 1000; + with4.MaxVS = (2 - (with4.SMThreshold / 100)) * with4.BasekV * 1000; + with4.MinVS = (with4.SMThreshold / 100) * with4.BasekV * 1000; + with4.MinAmps = (FpctCutOut / 100) * ((with3.FkVArating / with4.BasekV) / with3.NumPhases); + with4.ResetIBR = false; + with4.iMaxPPhase = (with3.FkVArating / with4.BasekV) / with3.NumPhases; + + if (pctX == 0) + pctX = 50; + with3.XThev = pctX * BaseZt; + with4.RS = pctR * BaseZt; + Zthev = cmplx(with4.RS, with3.XThev); + Yeq = cinv(Zthev); + ComputeIterminal(ActorID); + with4.LS = Zthev.im / (2 * PI * DefaultBaseFreq); + for (i = 0; i < Get_NPhases(); i++) + { + with4.Vgrid[i] = ctopolar(with2->NodeV[NodeRef[i]]); + with4.dit[i] = 0; + if (GFM_Mode) + with4.it[i] = 0; + else + with4.it[i] = ((with3.PanelkW * 1000) / with4.Vgrid[i].mag) / Fnphases; + with4.m[i] = ((with4.RS * with4.it[i]) + with4.Vgrid[i].mag) / with4.RatedVDC; // Duty factor in terms of actual voltage + if (with4.m[i] > 1) + with4.m[i] = 1; + with4.ISPDelta[i] = 0; + with4.AngDelta[i] = 0; + } + if (ASSIGNED(DynamicEqObj)) + for (i = 0; i < DynamicEqVals.size(); i++) + DynamicEqVals[i][1] = 0; // Initializes the memory values for the dynamic equation + +} +// =========================================================================================== + +// dynamics mode integration routine +// VAR +// TracePower:Complex; + +void TPVsystemObj::IntegrateStates(int ActorID) +{ + int NumData = 0, + j = 0, + k = 0, + i = 0; + bool GFMUpdate = false; // To avoid updating the IBR if current limit reached + double IPresent; + std::vector myCurr; + + // Compute Derivatives and Then integrate + ComputeIterminal(ActorID); + if (UserModel->Get_Exists()) // Checks for existence and Selects + UserModel->Integrate(); + else + { + auto wSol = ActiveCircuit[ActorID]->Solution; + auto& wSV = PVSystemVars; + auto& wDynV = myDynVars; + + // Compute actual power output for the PVPanel + + switch (ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(wSol->DynaVars.dblHour); + CalcDailyTemperature(wSol->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(wSol->DynaVars.dblHour); + CalcYearlyTemperature(wSol->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(wSol->DynaVars.dblHour); + CalcDutyTemperature(wSol->DynaVars.dblHour); + break; + default: + ShapeFactor = CDoubleOne; // default to 1 + j1 if not known + break; + } + ComputePanelPower(); + wDynV.iMaxPPhase = (wSV.PanelkW / wDynV.BasekV) / wSV.NumPhases; + for (i = 0; i < wSV.NumPhases; i++) + { + auto& DynaVars = wSol->DynaVars; + if (DynaVars.IterationFlag == 0) //{ First iteration of new time step } + wDynV.itHistory[i] = wDynV.it[i] + 0.5 * DynaVars.h * wDynV.dit[i]; + + wDynV.Vgrid[i] = ctopolar(wSol->NodeV[NodeRef[i]]);// Voltage at the Inv terminals + // Compute the actual target (Amps) + if (!GFM_Mode) + { + wDynV.ISP = ((wSV.PanelkW * 1000) / wDynV.Vgrid[i].mag) / wSV.NumPhases; + if (wDynV.ISP > wDynV.iMaxPPhase) + wDynV.ISP = wDynV.iMaxPPhase; + if ((wDynV.Vgrid[i].mag < wDynV.MinVS) || (wDynV.Vgrid[i].mag > wDynV.MaxVS)) + wDynV.ISP = 0.01; + } + else + { + if (wDynV.ResetIBR) wDynV.VDelta[i] = ((0.001 - (wDynV.Vgrid[i].mag / 1000)) / wDynV.BasekV); + else wDynV.VDelta[i] = (wDynV.BasekV - (wDynV.Vgrid[i].mag / 1000)) / wDynV.BasekV; + + GFMUpdate = true; + if (myDynVars.ILimit > 0) + { + myCurr.resize(Fnphases + 1); + GetCurrents(&myCurr[0], ActorID); + for (j = 0; j < (Fnphases - 1); j++) + { + IPresent = ctopolar(myCurr[j]).mag; + GFMUpdate = GFMUpdate && (IPresent < (myDynVars.ILimit * myDynVars.VError)); + } + } + if (abs(wDynV.VDelta[i]) > wDynV.CtrlTol && GFMUpdate) + { + wDynV.ISPDelta[i] = wDynV.ISPDelta[i] + (wDynV.iMaxPPhase * wDynV.VDelta[i]) * wDynV.Kp * 100; + if (wDynV.ISPDelta[i] > wDynV.iMaxPPhase) wDynV.ISPDelta[i] = wDynV.iMaxPPhase; + else if (wDynV.ISPDelta[i] < 0) wDynV.ISPDelta[i] = 0.01; + } + wDynV.ISP = wDynV.ISPDelta[i]; + wDynV.FixPhaseAngle(ActorID, i); + } + if (ASSIGNED(DynamicEqObj)) // Loads values into dynamic expression if any + { + NumData = (int)(round((DynamicEqPair.size() / 2)) - 1); + DynamicEqVals[DynOut[0]][0] = wDynV.it[i]; // brings back the current values/phase + DynamicEqVals[DynOut[0]][1] = wDynV.dit[i]; + + for (j = 0; j <= NumData; j++) + { + if (!DynamicEqObj->IsInitVal(DynamicEqPair[(j * 2) + 1])) + { + switch (DynamicEqPair[(j * 2) + 1]) + { + case 2: + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.Vgrid[i].mag; // volt per phase + break; + case 4: // Nothing for this object (current) + break; + case 10: + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.RatedVDC; + break; + case 11: + wDynV.SolveModulation(i, ActorID, &PICtrl[i]); + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.m[i]; + break; + default: + DynamicEqVals[DynamicEqPair[j * 2]][0] = Get_PCEValue(1, DynamicEqPair[(j * 2) + 1],ActorID); + break; + } + } + } + DynamicEqObj->SolveEq(&DynamicEqVals); // solves the differential equation using the given dynamic expression + } + else + wDynV.SolveDynamicStep(i, ActorID, &PICtrl[i]); // Solves dynamic step for inverter + + // Trapezoidal method + if (ASSIGNED(DynamicEqObj)) wDynV.dit[i] = DynamicEqVals[DynOut[0]][1]; + wDynV.it[i] = wDynV.itHistory[i] + 0.5 * DynaVars.h * wDynV.dit[i]; + + // Write Dynamics Trace Record + if (DebugTrace) + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile, Format("t=%-.5g", wSol->DynaVars.T)); + WriteLn(Tracefile, Format("Flag=%d", wSol->DynaVars.IterationFlag)); + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + } + + + +} + +// ===========================================================Get_Variable================================ + +/*Return variables one at a time*/ + +double TPVsystemObj::Get_Variable(int i) +{ + double result = 0.0; + int n = 0; + int k = 0; + result = -9999.99; // error return value; no state fars + if(i < 1) + return result; + // for now, report kWhstored and mode + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + switch(i) + { + case 1: + result = Get_PresentIrradiance(); + break; + case 2: + result = with0.PanelkW; + break; + case 3: + result = with0.TempFactor; + break; + case 4: + result = with0.EffFactor; + break; + case 5: + result = with0.Vreg; + break; + case 6: + result = with0.Vavg; + break; + case 7: + result = with0.VVOperation; + break; + case 8: + result = with0.VWOperation; + break; + case 9: + result = with0.DRCOperation; + break; + case 10: + result = with0.VVDRCOperation; + break; + case 11: + result = with0.WPOperation; + break; + case 12: + result = with0.WVOperation; + break; + case 13: + result = with0.PanelkW * with0.EffFactor; + break; + default: + result = myDynVars.Get_InvDynValue(i - 14, Get_NPhases()); + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + k = (i - NumPVSystemVariables); + if(k <= n) + { + result = UserModel->FGetVariable(k); + return result; + } + } + break; + } + } + return result; +} + +bool TPVsystemObj::Get_InverterON() +{ + bool result = false; + if(FInverterON) + result = true; + else + result = false; + return result; +} +// ============================================================Get_Varmode=============================== + +int TPVsystemObj::Get_Varmode() +{ + int result = 0; + result = FvarMode; + return result; +} +// ============================================================Get_VWmode=============================== + +bool TPVsystemObj::Get_VWmode() +{ + bool result = false; + if(FVWMode) + result = true; + else + result = false; // TRUE if volt-watt mode // engaged from InvControl (not ExpControl) + return result; +} +// ============================================================Get_VVmode=============================== + +bool TPVsystemObj::Get_VVmode() +{ + bool result = false; + if(FVVMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} +// ============================================================Get_WPmode=============================== + +bool TPVsystemObj::Get_WPmode() +{ + bool result = false; + if(FWPMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} +// ============================================================Get_WVmode=============================== + +bool TPVsystemObj::Get_WVmode() +{ + bool result = false; + if(FWVMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} +// ============================================================Get_DRCmode=============================== + +bool TPVsystemObj::Get_DRCmode() +{ + bool result = false; + if(FDRCMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} + +// ============================================================Get_AVRmode=============================== + +bool TPVsystemObj::Get_AVRmode() +{ + bool result = false; + if(FAVRMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} +// ============================================================kWOut_Calc=============================== + +void TPVsystemObj::kWOut_Calc() +{ + double Pac = 0.0; + double PpctLimit = 0.0; + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + Pac = with0.PanelkW * with0.EffFactor; + if(Get_VWmode() || Get_WVmode()) + { + if(Pac > kWRequested) + kW_out = kWRequested; + else + kW_out = Pac; + } + else + { + PpctLimit = with0.FPmpp * with0.FpuPmpp; + if(Pac > PpctLimit) + kW_out = PpctLimit; + else + kW_out = Pac; + } + } +} +// ============================================================Set_Variable=============================== + +void TPVsystemObj::Set_Variable(int i, double Value) +{ + int n = 0; + int k = 0; + if(i < 1) + return; // No variables to set + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + switch(i) + { + case 1: + with0.FIrradiance = Value; + break; + case 2: + ; + break; // Setting this has no effect Read only + case 3: + ; + break; // Setting this has no effect Read only + case 4: + ; + break; // Setting this has no effect Read only + case 5: + with0.Vreg = Value; + break; // the InvControl or ExpControl will do this + case 6: + with0.Vavg = Value; + break; + case 7: + with0.VVOperation = Value; + break; + case 8: + with0.VWOperation = Value; + break; + case 9: + with0.DRCOperation = Value; + break; + case 10: + with0.VVDRCOperation = Value; + break; + case 11: + with0.WPOperation = Value; + break; + case 12: + with0.WVOperation = Value; + break; + case 13: + ; + break; //ReadOnly //kW_out_desired := Value; + default: + myDynVars.Set_InvDynValue(i - 14, Value); + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + k = (i - NumPVSystemVariables); + if(k <= n) + { + UserModel->FSetVariable(k, Value); + return; + } + } + break; + } + } +} + +void TPVsystemObj::Set_Varmode(int Value) +{ + FvarMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::Set_VWmode(bool Value) +{ + FVWMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::Set_VVmode(bool Value) +{ + FVVMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::Set_WVmode(bool Value) +{ + FWVMode = Value; +} + +// =========================================================================================== + +void TPVsystemObj::Set_WPmode(bool Value) +{ + FWPMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::Set_DRCmode(bool Value) +{ + FDRCMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::Set_AVRmode(bool Value) +{ + FAVRMode = Value; +} +// =========================================================================================== + +void TPVsystemObj::GetAllVariables(pDoubleArray States) +{ +/*, N*/ + int i = 0, + stop = 0; + + if (!ASSIGNED(DynamicEqObj)) + { + for (stop = NumPVSystemVariables, i = 1; i <= stop; i++) + (States)[i - 1] = Get_Variable(i); + } + else + { + for (i = 1; i <= (DynamicEqObj->get_FNumVars() * DynamicEqVals[0].size()); i++) + States[i - 1] = DynamicEqObj->Get_DynamicEqVal(i - 1, &DynamicEqVals); + } + + if(UserModel->Get_Exists()) + UserModel->FGetAllVars((pDoubleArray)&(States)[NumPVSystemVariables + 1 - 1]); +} +// =========================================================================================== + +int TPVsystemObj::NumVariables() +{ + int result = 0; + result = NumPVSystemVariables; + if(UserModel->Get_Exists()) + result = result + UserModel->FNumVars(); + return result; +} +// =========================================================================================== + +String TPVsystemObj::VariableName(int i) +{ + String result; + const int BuffSize = 255; + int n = 0; + int I2 = 0; + AnsiChar Buff[256/*# range 0..BuffSize*/]; + PAnsiChar PName = nullptr; + if(i < 1) + return result; // Someone goofed + switch(i) + { + case 1: + result = "Irradiance"; + break; + case 2: + result = "PanelkW"; + break; + case 3: + result = "P_TFactor"; + break; + case 4: + result = "Efficiency"; + break; + case 5: + result = "Vreg"; + break; + case 6: + result = "Vavg (DRC)"; + break; + case 7: + result = "volt-var"; + break; + case 8: + result = "volt-watt"; + break; + case 9: + result = "DRC"; + break; + case 10: + result = "VV_DRC"; + break; + case 11: + result = "watt-pf"; + break; + case 12: + result = "watt-var"; + break; + case 13: + result = "kW_out_desired"; + break; + default: + result = myDynVars.Get_InvDynName(i - 14); + if(UserModel->Get_Exists()) + { + PName = (PAnsiChar) &Buff; + n = UserModel->FNumVars(); + I2 = i - NumPVSystemVariables; + if(I2 <= n) + { + UserModel->FGetVarName(I2, PName, (unsigned int) BuffSize); + result = PName; + return result; + } + } + break; + } + return result; +} +// =========================================================================================== + +void TPVsystemObj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + s = "Phases=1 conn=wye"; + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = with0.kVPVSystemBase / SQRT3; + else + V = with0.kVPVSystemBase; + s = s + Format(" kV=%-.5g", V); + if(Fnphases > 1) + s = s + + Format(" kva=%-.5g PF=%-.5g", with0.FkVArating / Fnphases, PFNominal); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + } + inherited::MakePosSequence(ActorID); // write out other properties +} +// =========================================================================================== + +void TPVsystemObj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + inherited::Set_ConductorClosed(Index, ActorID, Value); + // Just turn PVSystem element on or off; + if(Value) + PVsystemObjSwitchOpen = false; + else + PVsystemObjSwitchOpen = true; +} + +void TPVsystemObj::Set_Maxkvar(double Value) +{ + PVSystemVars.Fkvarlimit = Value; + Set_PropertyValue(propkvarLimit,Format("%-g", PVSystemVars.Fkvarlimit)); +} + +void TPVsystemObj::Set_Maxkvarneg(double Value) +{ + PVSystemVars.Fkvarlimitneg = Value; + Set_PropertyValue(propkvarLimitneg,Format("%-g", PVSystemVars.Fkvarlimitneg)); +} + +void TPVsystemObj::Set_kVARating(double Value) +{ + PVSystemVars.FkVArating = Value; + Set_PropertyValue(propKVA,Format("%-g", PVSystemVars.FkVArating)); +} +// =========================================================================================== + +void TPVsystemObj::Set_Pmpp(double Value) +{ + PVSystemVars.FPmpp = Value; + Set_PropertyValue(propPmpp,Format("%-g", PVSystemVars.FkVArating)); +} + +void TPVsystemObj::Set_PowerFactor(double Value) +{ + PFNominal = Value; + Set_Varmode(VARMODEPF); +} + +void TPVsystemObj::Set_PresentIrradiance(double Value) +{ + PVSystemVars.FIrradiance = Value; +} + +void TPVsystemObj::Set_PresentkV(double Value) +{ + /*# with PVSystemVars do */ + { + auto& with0 = PVSystemVars; + with0.kVPVSystemBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = with0.kVPVSystemBase * InvSQRT3x1000; + break; + default: + VBase = with0.kVPVSystemBase * 1000.0; + break; + } + } +} + +void TPVsystemObj::Set_VarFollowInverter(bool Value) +{ + FVarFollowInverter = Value; +} + +void TPVsystemObj::Set_InverterON(bool Value) +{ + FInverterON = Value; +} + +void TPVsystemObj::Set_PresentkW(double Value) +{ + kWRequested = Value; +} + +void TPVsystemObj::Set_Presentkvar(double Value) +{ + kvarRequested = Value; +} + +void TPVsystemObj::Set_pf_wp_nominal(double Value) +{ + Fpf_wp_nominal = Value; +} + +void TPVsystemObj::Set_puPmpp(double Value) +{ + PVSystemVars.FpuPmpp = Value; +} + +void TPVsystemObj::SetDragHandRegister(int reg, double Value) +{ + if(Value > Registers[reg]) + Registers[reg] = Value; +} + + +void PVSystem_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + +// functions for returning struct data to properties + +double TPVsystemObj::Get_FkVArating() +{ + return PVSystemVars.FkVArating; +} + +double TPVsystemObj::Get_FPmpp() +{ + return PVSystemVars.FPmpp; +} + +double TPVsystemObj::Get_FpuPmpp() +{ + return PVSystemVars.FpuPmpp; +} + +double TPVsystemObj::Get_Fkvarlimit() +{ + return PVSystemVars.Fkvarlimit; +} + +double TPVsystemObj::Get_FShapefactorRe() +{ + return ShapeFactor.re; +} + +// for CIM export + +double TPVsystemObj::Get_Pmin() +{ + return std::min(FpctCutIn, FpctCutOut) * Get_FkVArating() / 100.0; +} + +double TPVsystemObj::Get_Pmax() +{ + return Get_FPmpp(); +} + +double TPVsystemObj::Get_qMaxInj() +{ + double result = PVSystemVars.Fkvarlimit; + if (!kvarLimitSet) + result = 0.25 * Get_FkVArating(); // unlike storage, defaults to category A + + return result; +} + +double TPVsystemObj::Get_qMaxAbs() +{ + double result = PVSystemVars.Fkvarlimitneg; + if (!kvarLimitNegSet) + result = 0.25 * Get_FkVArating(); // unlike storage, defaults to category A + + return result; +} + +double TPVsystemObj::Get_acVmin() +{ + return Get_PresentkV() * Vminpu; +} + +double TPVsystemObj::Get_acVmax() +{ + return Get_PresentkV() * Vmaxpu; +} + +double TPVsystemObj::Get_acVnom() +{ + return Get_PresentkV(); +} + +double TPVsystemObj::Get_pMaxUnderPF() +{ + double q = Get_qMaxAbs(); + auto& with0 = PVSystemVars; + return sqrt( Sqr(with0.FkVArating) - q * q); +} + +double TPVsystemObj::Get_pMaxOverPF() +{ + double q = Get_qMaxInj(); + auto& with0 = PVSystemVars; + return sqrt(Sqr(with0.FkVArating) - q * q); +} + +double TPVsystemObj::Get_pMaxCharge() +{ + return 0.0; +} + +double TPVsystemObj::Get_sMaxCharge() +{ + return 0.0; +} + +bool TPVsystemObj::Get_CIMDynamicMode() +{ + bool result = false; + + result = FVWMode || FVVMode || FWVMode || FAVRMode || FDRCMode; // FWPMode not in CIM Dynamics + + return result; +} + + + class PVSystem_unit + { + public: + PVSystem_unit() + { + //AssertSystemInitialization(); + PVSystem_initialization(); + } + }; + PVSystem_unit _PVSystem_unit; + + +} // namespace PVSystem + + + + diff --git a/OpenDSSC/PCElements/PVsystem.h b/OpenDSSC/PCElements/PVsystem.h new file mode 100644 index 0000000..ba4b52f --- /dev/null +++ b/OpenDSSC/PCElements/PVsystem.h @@ -0,0 +1,386 @@ +#ifndef PVSystemH +#define PVSystemH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "PVSystemUserModel.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "TempShape.h" +#include "XYcurve.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "Dynamics.h" +#include "DSSClassDefs.h" +#include "InvDynamics.h" +#include "mathutil.h" + + +namespace PVSystem +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + + 1/28/2011 Created from Storage Model + + + To Do: + Make connection to User model + Yprim for various modes + Define state vars and dynamics mode behavior + Complete Harmonics mode algorithm (generator mode is implemented) +*/ +/* + The PVsystem element is essentially a generator that consists of a PV panel and an inverter. + + The PVsystem element can also produce or absorb vars within the kVA rating of the inverter. + // WGS: Updated 9/24/2015 to allow for simultaneous modes and additional functionality in the InvControl. + + 09/11/2022 Compatibility with dynamics simulation added + 10/28/2022 Grid forming inverter capabilities added +*/ + +// The PVsystem element is assumed balanced over the no. of phases defined +const int NumPVSystemRegisters = 6; // Number of energy meter registers +const int NumPVSystemVariables = 22; // Includes dynamics state variables - added on 09/15/2022. +const int VARMODEPF = 0; +const int VARMODEKVAR = 1; + +/*Struct to pass basic data to user-written DLLs*/ +#pragma pack (push, 1) + + +struct TPVSystemVars +{ + double FkVArating; + double kVPVSystemBase; + double RThev; + double XThev; + double VThevHarm; /*Thevinen equivalent voltage mag for Harmonic model*/ + double VthevmagDyn; /*Thevinen equivalent voltage mag reference for Dynamics model*/ + double ThetaHarm; /*Thevinen equivalent angle reference for Harmonic model*/ + double ThetaDyn; /*Thevinen equivalent angle reference for Dynamics model*/ + double InitialVAngle; /*initial terminal voltage angle when entering dynamics mode*/ + double EffFactor; + double TempFactor; + double PanelkW; //computed + double FTemperature; + double FPmpp; + double FpuPmpp; + double FIrradiance; + double MaxDynPhaseCurrent; + double Fkvarlimit; //maximum kvar output of the PVSystem (unsigned) + double Fkvarlimitneg; + // Variables set from InvControl. They are results of monitor in mode 3 + double Vreg; // will be set from InvControl or ExpControl + double Vavg; + double VVOperation; + double VWOperation; + double DRCOperation; + double VVDRCOperation; + double WPOperation; + double WVOperation; + // kW_out_desired :Double; + + /*32-bit integers*/ + int NumPhases; /*Number of phases*/ + int NumConductors;/*Total Number of conductors (wye-connected will have 4)*/ + int Conn; // 0 = wye; 1 = Delta + bool P_priority; // default False // added 10/30/2018 + bool PF_Priority; // default False // added 1/29/2019 +}; +#pragma pack (pop) + + +// =========================================================================================== + +class TPVSystem : public PCClass::TPCClass +{ + friend class TPVsystemObj; +public: + typedef PCClass::TPCClass inherited; +private: + void InterpretConnection(const String s); + void SetNcondsForConnection(); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherPVsystemObjName); +public: + String RegisterNames[6/*# range 1..NumPVSystemRegisters*/]; + TPVSystem(); + virtual ~TPVSystem(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void ResetRegistersAll(); + void SampleAll(int ActorID); + void UpdateAll(); +}; + +// =========================================================================================== + +class TPVsystemObj : public PCElement::TPCElement +{ + friend class TPVsystem; +public: + typedef PCElement::TPCElement inherited; +//private: + Ucomplex::complex Yeq; // at nominal + Ucomplex::complex YEQ_Min; // at Vmin + Ucomplex::complex YEQ_Max; // at VMax + Ucomplex::complex PhaseCurrentLimit; + Ucomplex::complex Zthev; + double LastThevAngle; + bool DebugTrace; + int PVSystemSolutionCount; + double PVSystemFundamental; /*Thevinen equivalent voltage mag and angle reference for Harmonic model*/ + bool PVsystemObjSwitchOpen; + bool FirstSampleAfterReset; + bool PFSpecified; + bool kvarSpecified; + bool ForceBalanced; + bool CurrentLimited; + double kvar_out; + double kW_out; + double kvarRequested; + double Fpf_wp_nominal; + double kWRequested; + int FvarMode; + double FpctCutIn; + double FpctCutOut; + bool FVarFollowInverter; + double CutInkW; + double CutOutkW; + bool FInverterON; + double FpctPminNoVars; + double FpctPminkvarLimit; + double PminNoVars; + double PminkvarLimit; + double pctR; + double pctX; + int OpenPVSystemSolutionCount; + double Pnominalperphase; + double Qnominalperphase; + double RandomMult; + int Reg_Hours; + int Reg_kvarh; + int Reg_kWh; + int Reg_MaxkVA; + int Reg_MaxkW; + int Reg_Price; + Ucomplex::complex ShapeFactor; + double TShapeValue; + System::TTextRec Tracefile; + PVsystemUserModel::TPVsystemUserModel* UserModel; /*User-Written Models*/ + double varBase; // Base vars per phase + double VBase; // Base volts suitable for computing currents + double VBaseMax; + double VBaseMin; + double Vmaxpu; + double Vminpu; + Ucmatrix::TcMatrix* YPrimOpenCond; + bool FVWMode; //boolean indicating if under volt-watt control mode from InvControl (not ExpControl) + bool FVVMode; //boolean indicating if under volt-var mode from InvControl + bool FWVMode; //boolean indicating if under watt-var mode from InvControl + bool FWPMode; //boolean indicating if under watt-pf mode from InvControl + bool FDRCMode; //boolean indicating if under DRC mode from InvControl + bool FAVRMode; + + int FVWYAxis; // integer value indicating that whether y-axis of watts is in %Pmpp or %PAvailable + // 1 = %Pmpp, 0=%PAvailable. Default is 1 such that pctPmpp user-settable + // property will correctly operate on Pmpp (NOT PAvailable) + void CalcDailyMult(double hr); // now incorporates DutyStart offset + void CalcDutyMult(double hr); + void CalcYearlyMult(double hr); // now incorporates DutyStart offset + void CalcDailyTemperature(double hr); + void CalcDutyTemperature(double hr); + void CalcYearlyTemperature(double hr); + void ComputePanelPower(); + void ComputeInverterPower(); + void ComputekWkvar(); + void CalcPVSystemModelContribution(int ActorID); // This is where the power gets computed + void CalcInjCurrentArray(int ActorID); + /*PROCEDURE CalcVterminal;*/ + void CalcVTerminalPhase(int ActorID); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void DoConstantPQPVsystemObj(int ActorID); + void DoConstantZPVsystemObj(int ActorID); + void DoDynamicMode(int ActorID); + void DoHarmonicMode(int ActorID); + void DoUserModel(int ActorID); + void Integrate(int reg, double Deriv, double Interval); + void SetDragHandRegister(int reg, double Value); + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); + void WriteTraceRecord(const String s); + + // PROCEDURE SetKWandKvarOut; + void UpdatePVSystem(); // Update PVSystem elements based on present kW and IntervalHrs variable + double Get_PresentkW(); + double Get_Presentkvar(); + double Get_PresentkV(); + double Get_PresentIrradiance(); + void Set_PresentkV(double Value); + void Set_Presentkvar(double Value); + void Set_PresentkW(double Value); + void Set_PowerFactor(double Value); + void Set_PresentIrradiance(double Value); + void Set_pf_wp_nominal(double Value); + void Set_kVARating(double Value); + void Set_Pmpp(double Value); + void Set_puPmpp(double Value); + int Get_Varmode(); + void Set_Varmode(int Value); + bool Get_VWmode(); + void Set_VWmode(bool Value); + bool Get_VVmode(); + void Set_VVmode(bool Value); + bool Get_WPmode(); + void Set_WPmode(bool Value); + bool Get_WVmode(); + void Set_WVmode(bool Value); + bool Get_DRCmode(); + void Set_DRCmode(bool Value); + bool Get_AVRmode(); + void Set_AVRmode(bool Value); + + //int Get_VWYAxis(); + //void Set_VWYAxis(int Value); + void kWOut_Calc(); + + // get implementation for properties + double Get_FkVArating(); + double Get_FPmpp(); + double Get_FpuPmpp(); + double Get_Fkvarlimit(); + double Get_FShapefactorRe(); + +protected: + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); +public: + TPVSystemVars PVSystemVars; + InvDynamics::TInvDynamicVars myDynVars; + double CurrentkvarLimit; + double CurrentkvarLimitNeg; + int Connection; /*0 = line-neutral; 1=Delta*/ + String DailyShape; // Daily (24 HR) PVSystem element irradiance shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily PVSystem element irradianceShape for this load + String DutyShape; // Duty cycle irradiance shape for changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // irradiance Shape for this PVSystem element + double DutyStart; // starting time offset into the DutyShape [hrs] for this PVsystem + String YearlyShape; // + LoadShape::TLoadShapeObj* YearlyShapeObj; // Yearly irradiance Shape for this PVSystem element + String DailyTShape; + TempShape::TTShapeObj* DailyTShapeObj; + String DutyTShape; + TempShape::TTShapeObj* DutyTShapeObj; + String YearlyTShape; + TempShape::TTShapeObj* YearlyTShapeObj; + String InverterCurve; + XYCurve::TXYcurveObj* InverterCurveObj; + String Power_TempCurve; + XYCurve::TXYcurveObj* Power_TempCurveObj; + bool kvarLimitSet; + bool kvarLimitNegSet; + std::vector PICtrl; + + int FClass; + int VoltageModel; // Variation with voltage + double PFNominal; + double Registers[6/*# range 1..NumPVSystemRegisters*/]; + double Derivatives[6/*# range 1..NumPVSystemRegisters*/]; + TPVsystemObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TPVsystemObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + bool Get_InverterON(); + void Set_InverterON(bool Value); + bool Get_VarFollowInverter(); + void Set_VarFollowInverter(bool Value); + void Set_Maxkvar(double Value); + void Set_Maxkvarneg(double Value); + void SetNominalPVSystemOuput(int ActorID); + void Randomize(int Opt); // 0 = reset to 1.0; 1 = Gaussian around mean and std Dev ; // 2 = uniform + void ResetRegisters(); + void TakeSample(int ActorID); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + void DoGFM_Mode(int ActorID); + void GetCurrents(pComplexArray Curr, int ActorID); + bool CheckAmpsLimit(int ActorID); + bool CheckOLInverter(int ActorID); + + //-------------------------------------------------------------------------------------------------------- + + double get_PFNominal(); + double get_Vminpu(); + double get_Fkvarlimitneg(); + + double Get_Pmin(); + double Get_Pmax(); + double Get_qMaxInj(); + double Get_qMaxAbs(); + double Get_acVmin(); + double Get_acVmax(); + double Get_acVnom(); + double Get_pMaxUnderPF(); + double Get_pMaxOverPF(); + double Get_pMaxCharge(); + double Get_sMaxCharge(); + bool Get_CIMDynamicMode(); + + //-------------------------------------------------------------------------------------------------------- + // Functions for NCIM solution algorithm + void DoPQBusNCIM(int ActorID, int i, complex V, complex Curr); + + TPVsystemObj(DSSClass::TDSSClass* ParClass); + TPVsystemObj(String ClassName); + TPVsystemObj(); +}; +extern TPVsystemObj* ActivePVsystemObj; + +// =========================================================================================== + + +} // namespace PVSystem + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PVSystem; +#endif + +#endif // PVSystemH + + + + diff --git a/OpenDSSC/PCElements/Storage.cpp b/OpenDSSC/PCElements/Storage.cpp new file mode 100644 index 0000000..50566a3 --- /dev/null +++ b/OpenDSSC/PCElements/Storage.cpp @@ -0,0 +1,5193 @@ + + +#pragma hdrstop + +#include "Storage.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "Command.h" +#include +#include "mathutil.h" +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace StorageVars; +using namespace StoreUserModel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace Storage +{ + +TStorageObj::TStorageObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TStorageObj::TStorageObj(String ClassName) : inherited(ClassName) {} +TStorageObj::TStorageObj() {} + + +TStorageObj* ActiveStorageObj = nullptr; + +/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + To add a property, + 1) add a property constant to this list + 2) add a handler to the CASE statement in the Edit FUNCTION + 3) add a statement(s) to InitPropertyValues FUNCTION to initialize the string value + 4) add any special handlers to DumpProperties and GetPropertyValue, If needed + = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/ +const int propKV = 3; +const int propKW = 4; +const int propPF = 5; +const int propMODEL = 6; +const int propYEARLY = 7; +const int propDAILY = 8; +const int propDUTY = 9; +const int propDISPMODE = 10; +const int PropConnection = 11; +const int propKVAR = 12; +const int propPCTR = 13; +const int propPCTX = 14; +const int propIDLEKW = 15; +const int propCLASS = 16; +const int propDISPOUTTRIG = 17; +const int propDISPINTRIG = 18; +const int propCHARGEEFF = 19; +const int propDISCHARGEEFF = 20; +const int propPCTKWOUT = 21; +const int propVMINPU = 22; +const int propVMAXPU = 23; +const int propSTATE = 24; +const int propKVA = 25; +const int propKWRATED = 26; +const int propKWHRATED = 27; +const int propKWHSTORED = 28; +const int propPCTRESERVE = 29; +const int propUSERMODEL = 30; +const int propUSERDATA = 31; +const int propDEBUGTRACE = 32; +const int propPCTKWIN = 33; +const int propPCTSTORED = 34; +const int propCHARGETIME = 35; +const int propDynaDLL = 36; +const int propDynaData = 37; +const int propBalanced = 38; +const int propLimited = 39; +const int propInvEffCurve = 40; +const int propCutin = 41; +const int propCutout = 42; +const int proppctkWrated = 43; +const int propVarFollowInverter = 44; +const int propkvarLimit = 45; +const int propPpriority = 46; +const int propPFpriority = 47; +const int propPminNoVars = 48; +const int propPminkvarLimit = 49; +const int propkvarLimitneg = 50; +const int propIDLEKVAR = 51; +const int propkVDC = 52; +const int propkp = 53; +const int propCtrlTol = 54; +const int propSMT = 55; +const int propSM = 56; +const int propDynEq = 57; +const int propDynOut = 58; +const int propGFM = 59; +const int propAmpsLimit = 60; +const int propAmpsError = 61; +const int NumPropsThisClass = 61; // Make this agree with the last property constant +complex cBuffer[25/*# range 1..24*/]; // Temp buffer for calcs 24-phase Storage element? +complex CDoubleOne = {}; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Storage elements + +TStorage::TStorage() +{ + ; + Class_Name = "Storage"; + DSSClassType = DSSClassType + STORAGE_ELEMENT; // In both PCelement and Storage element list + ActiveElement = 0; + + // Set Register names + RegisterNames[0] = "kWh"; + RegisterNames[1] = "kvarh"; + RegisterNames[2] = "Max kW"; + RegisterNames[3] = "Max kVA"; + RegisterNames[4] = "Hours"; + RegisterNames[5] = "Price($)"; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TStorage::~TStorage() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorage::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Define Property names + /* + Using the AddProperty FUNCTION, you can list the properties here in the order you want + them to appear when properties are accessed sequentially without tags. Syntax: + + AddProperty( , , ); + + */ + AddProperty("phases", 1, "Number of Phases, this Storage element. Power is evenly divided among phases."); + AddProperty("bus1", 2, "Bus to which the Storage element is connected. May include specific node specification."); + AddProperty("kv", propKV, String("Nominal rated (1.0 per unit) voltage, kV, for Storage element. For 2- and 3-phase Storage elements, specify phase-phase kV. " "Otherwise, specify actual kV across each branch of the Storage element. ") + CRLF + + CRLF + + "If wye (star), specify phase-neutral kV. " + + CRLF + + CRLF + + "If delta or phase-phase connected, specify phase-phase kV."); // line-neutral voltage// base voltage + AddProperty("conn", PropConnection, "={wye|LN|delta|LL}. Default is wye."); + AddProperty("kW", propKW, "Get/set the requested kW value. Final kW is subjected to the inverter ratings. A positive value denotes power coming OUT of the element, " + "which is the opposite of a Load element. A negative value indicates the Storage element is in Charging state. " + "This value is modified internally depending on the dispatch mode."); + AddProperty("kvar", propKVAR, "Get/set the requested kvar value. Final kvar is subjected to the inverter ratings. Sets inverter to operate in constant kvar mode."); + AddProperty("pf", propPF, String("Get/set the requested PF value. Final PF is subjected to the inverter ratings. Sets inverter to operate in constant PF mode. Nominally, " "the power factor for discharging (acting as a generator). Default is 1.0. ") + CRLF + + CRLF + + "Enter negative for leading power factor " + + "(when kW and kvar have opposite signs.)" + + CRLF + + CRLF + + "A positive power factor signifies kw and kvar at the same direction."); + AddProperty("kVA", propKVA, "Indicates the inverter nameplate capability (in kVA). " + "Used as the base for Dynamics mode and Harmonics mode values."); + AddProperty("%Cutin", propCutin, "Cut-in power as a percentage of inverter kVA rating. It is the minimum DC power necessary to turn the inverter ON when it is OFF. " + "Must be greater than or equal to %CutOut. Defaults to 2 for PVSystems and 0 for Storage elements which means that the inverter state " + "will be always ON for this element."); + AddProperty("%Cutout", propCutout, "Cut-out power as a percentage of inverter kVA rating. It is the minimum DC power necessary to keep the inverter ON. " + "Must be less than or equal to %CutIn. Defaults to 0, which means that, once ON, the inverter state " + "will be always ON for this element."); + AddProperty("EffCurve", propInvEffCurve, "An XYCurve object, previously defined, that describes the PER UNIT efficiency vs PER UNIT of rated kVA for the inverter. " + "Power at the AC side of the inverter is discounted by the multiplier obtained from this curve."); + AddProperty("VarFollowInverter", propVarFollowInverter, "Boolean variable (Yes|No) or (True|False). Defaults to False, which indicates that the reactive power generation/absorption does not respect the inverter status." + "When set to True, the reactive power generation/absorption will cease when the inverter status is off, due to DC kW dropping below %CutOut. The reactive power " + "generation/absorption will begin again when the DC kW is above %CutIn. When set to False, the Storage will generate/absorb reactive power regardless of the status of the inverter."); + AddProperty("kvarMax", propkvarLimit, "Indicates the maximum reactive power GENERATION (un-signed numerical variable in kvar) for the inverter. Defaults to kVA rating of the inverter."); + AddProperty("kvarMaxAbs", propkvarLimitneg, "Indicates the maximum reactive power ABSORPTION (un-signed numerical variable in kvar) for the inverter. Defaults to kvarMax."); + AddProperty("WattPriority", propPpriority, "{Yes/No*/True/False} Set inverter to watt priority instead of the default var priority."); + AddProperty("PFPriority", propPFpriority, "If set to true, priority is given to power factor and WattPriority is neglected. It works only if operating in either constant PF " + "or constant kvar modes. Defaults to False."); + AddProperty("%PminNoVars", propPminNoVars, "Minimum active power as percentage of kWrated under which there is no vars production/absorption. Defaults to 0 (disabled)."); + AddProperty("%PminkvarMax", propPminkvarLimit, "Minimum active power as percentage of kWrated that allows the inverter to produce/absorb reactive power up to its maximum " + "reactive power, which can be either kvarMax or kvarMaxAbs, depending on the current operation quadrant. Defaults to 0 (disabled)."); + AddProperty("kWrated", propKWRATED, "kW rating of power output. Base for Loadshapes when DispMode=Follow. Sets kVA property if it has not been specified yet. " + "Defaults to 25."); + AddProperty("%kWrated", proppctkWrated, "Upper limit on active power as a percentage of kWrated. Defaults to 100 (disabled)."); + AddProperty("kWhrated", propKWHRATED, "Rated Storage capacity in kWh. Default is 50."); + AddProperty("kWhstored", propKWHSTORED, "Present amount of energy stored, kWh. Default is same as kWhrated."); + AddProperty("%stored", propPCTSTORED, "Present amount of energy stored, % of rated kWh. Default is 100."); + AddProperty("%reserve", propPCTRESERVE, String("Percentage of rated kWh Storage capacity to be held in reserve for normal operation. Default = 20. ") + CRLF + + "This is treated as the minimum energy discharge level unless there is an emergency. For emergency operation " + + "set this property lower. Cannot be less than zero."); + AddProperty("State", propSTATE, "{IDLING | CHARGING | DISCHARGING} Get/Set present operational state. In DISCHARGING mode, the Storage element " + "acts as a generator and the kW property is positive. The element continues discharging at the scheduled output power level " + "until the Storage reaches the reserve value. Then the state reverts to IDLING. " + "In the CHARGING state, the Storage element behaves like a Load and the kW property is negative. " + "The element continues to charge until the max Storage kWh is reached and then switches to IDLING state. " + "In IDLING state, the element draws the idling losses plus the associated inverter losses."); + AddProperty("%Discharge", propPCTKWOUT, "Discharge rate (output power) in percentage of rated kW. Default = 100."); + AddProperty("%Charge", propPCTKWIN, "Charging rate (input power) in percentage of rated kW. Default = 100."); + AddProperty("%EffCharge", propCHARGEEFF, "Percentage efficiency for CHARGING the Storage element. Default = 90."); + AddProperty("%EffDischarge", propDISCHARGEEFF, "Percentage efficiency for DISCHARGING the Storage element. Default = 90."); + AddProperty("%IdlingkW", propIDLEKW, "Percentage of rated kW consumed by idling losses. Default = 1."); + AddProperty("%Idlingkvar", propIDLEKVAR, "Deprecated."); + AddProperty("%R", propPCTR, "Equivalent percentage internal resistance, ohms. Default is 0. Placed in series with internal voltage source" + " for harmonics and dynamics modes. Use a combination of %IdlingkW, %EffCharge and %EffDischarge to account for " + "losses in power flow modes."); + AddProperty("%X", propPCTX, "Equivalent percentage internal reactance, ohms. Default is 50%. Placed in series with internal voltage source" + " for harmonics and dynamics modes. (Limits fault current to 2 pu."); + AddProperty("model", propMODEL, String("Integer code (default=1) for the model to be used for power output variation with voltage. " "Valid values are:") + CRLF + + CRLF + + "1:Storage element injects/absorbs a CONSTANT power." + + CRLF + + "2:Storage element is modeled as a CONSTANT IMPEDANCE." + + CRLF + + "3:Compute load injection from User-written Model."); + AddProperty("Vminpu", propVMINPU, "Default = 0.90. Minimum per unit voltage for which the Model is assumed to apply. " + "Below this value, the load model reverts to a constant impedance model."); + AddProperty("Vmaxpu", propVMAXPU, "Default = 1.10. Maximum per unit voltage for which the Model is assumed to apply. " + "Above this value, the load model reverts to a constant impedance model."); + AddProperty("Balanced", propBalanced, "{Yes | No*} Default is No. Force balanced current only for 3-phase Storage. Forces zero- and negative-sequence to zero. "); + AddProperty("LimitCurrent", propLimited, "Limits current magnitude to Vminpu value for both 1-phase and 3-phase Storage similar to Generator Model 7. For 3-phase, " + "limits the positive-sequence current but not the negative-sequence."); + AddProperty("yearly", propYEARLY, "Dispatch shape to use for yearly simulations. Must be previously defined " + "as a Loadshape object. If this is not specified, the Daily dispatch shape, if any, is repeated " + "during Yearly solution modes. In the default dispatch mode, " + "the Storage element uses this loadshape to trigger State changes."); + AddProperty("daily", propDAILY, "Dispatch shape to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. In the default dispatch mode, " + "the Storage element uses this loadshape to trigger State changes."); // daily dispatch (hourly) + AddProperty("duty", propDUTY, String("Load shape to use for duty cycle dispatch simulations such as for solar ramp rate studies. " "Must be previously defined as a Loadshape object. ") + CRLF + + CRLF + + "Typically would have time intervals of 1-5 seconds. " + + CRLF + + CRLF + + "Designate the number of points to solve using the Set Number=xxxx command. " + + "If there are fewer points in the actual shape, the shape is assumed to repeat."); // as for wind generation + AddProperty("DispMode", propDISPMODE, String("{DEFAULT | FOLLOW | EXTERNAL | LOADLEVEL | PRICE } Default = \"DEFAULT\". Dispatch mode. ") + CRLF + + CRLF + + "In DEFAULT mode, Storage element state is triggered to discharge or charge at the specified rate by the " + + "loadshape curve corresponding to the solution mode. " + + CRLF + + CRLF + + "In FOLLOW mode the kW output of the Storage element follows the active loadshape multiplier " + + "until Storage is either exhausted or full. " + + "The element discharges for positive values and charges for negative values. The loadshape is based on rated kW. " + + CRLF + + CRLF + + "In EXTERNAL mode, Storage element state is controlled by an external Storagecontroller2. " + + "This mode is automatically set if this Storage element is included in the element list of a StorageController element. " + + CRLF + + CRLF + + "For the other two dispatch modes, the Storage element state is controlled by either the global default Loadlevel value or the price level. "); + AddProperty("DischargeTrigger", propDISPOUTTRIG, String("Dispatch trigger value for discharging the Storage. ") + CRLF + + "If = 0.0 the Storage element state is changed by the State command or by a StorageController2 object. " + + CRLF + + "If <> 0 the Storage element state is set to DISCHARGING when this trigger level is EXCEEDED by either the specified " + + "Loadshape curve value or the price signal or global Loadlevel value, depending on dispatch mode. See State property."); + AddProperty("ChargeTrigger", propDISPINTRIG, String("Dispatch trigger value for charging the Storage. ") + CRLF + + CRLF + + "If = 0.0 the Storage element state is changed by the State command or StorageController2 object. " + + CRLF + + CRLF + + "If <> 0 the Storage element state is set to CHARGING when this trigger level is GREATER than either the specified " + + "Loadshape curve value or the price signal or global Loadlevel value, depending on dispatch mode. See State property."); + AddProperty("TimeChargeTrig", propCHARGETIME, "Time of day in fractional hours (0230 = 2.5) at which Storage element will automatically go into charge state. " + "Default is 2.0. Enter a negative time value to disable this feature."); + AddProperty("class", propCLASS, "An arbitrary integer number representing the class of Storage element so that Storage values may " + "be segregated by class."); // integer + AddProperty("DynaDLL", propDynaDLL, "Name of DLL containing user-written dynamics model, which computes the terminal currents for Dynamics-mode simulations, " + "overriding the default model. Set to \"none\" to negate previous setting. " + "This DLL has a simpler interface than the UserModel DLL and is only used for Dynamics mode."); + AddProperty("DynaData", propDynaData, "String (in quotes or parentheses if necessary) that gets passed to the user-written dynamics model Edit function for defining the data required for that model."); + AddProperty("UserModel", propUSERMODEL, "Name of DLL containing user-written model, which computes the terminal currents for both power flow and dynamics, " + "overriding the default model. Set to \"none\" to negate previous setting."); + AddProperty("UserData", propUSERDATA, "String (in quotes or parentheses) that gets passed to user-written model for defining the data required for that model."); + AddProperty("debugtrace", propDEBUGTRACE, "{Yes | No } Default is no. Turn this on to capture the progress of the Storage model " + "for each iteration. Creates a separate file for each Storage element named \"Storage_name.CSV\"."); + AddProperty("kVDC", propkVDC, + "Indicates the rated voltage (kV) at the input of the inverter while the storage is discharging. The value is normally greater or equal to the kV base of the Storage device. It is used for dynamics simulation ONLY."); + + AddProperty("Kp", propkp, + "It is the proportional gain for the PI controller within the inverter. Use it to modify the controller response in dynamics simulation mode."); + + AddProperty("PITol", propCtrlTol, + "It is the tolerance (%) for the closed loop controller of the inverter. For dynamics simulation mode."); + + AddProperty("SafeVoltage", propSMT, + "Indicates the voltage level (%) respect to the base voltage level for which the Inverter will operate. If this threshold is violated, the Inverter will enter safe mode (OFF). For dynamic simulation. By default is 80%"); + + AddProperty("SafeMode", propSM, + "(Read only) Indicates whether the inverter entered (Yes) or not (No) into Safe Mode."); + AddProperty("DynamicEq", propDynEq, + string("The name of the dynamic equation (DinamicExp) that will be used for defining the dynamic behavior of the generator. ") + + "if not defined, the generator dynamics will follow the built-in dynamic equation."); + AddProperty("DynOut", propDynOut, + string("The name of the variables within the Dynamic equation that will be used to govern the PVSystem dynamics.") + + "This PVsystem model requires 1 output from the dynamic equation: " + CRLF + CRLF + + "1. Current." + CRLF + + "The output variables need to be defined in the same order."); + AddProperty("ControlMode", propGFM, + string("Defines the control mode for the inverter. It can be one of {GFM | GFL*}. By default it is GFL (Grid Following Inverter).") + + " Use GFM (Grid Forming Inverter) for energizing islanded microgrids, but, if the device is conencted to the grid, it is highly recommended to use GFL." + CRLF + CRLF + + "GFM control mode disables any control action set by the InvControl device."); + AddProperty("AmpLimit", propAmpsLimit, + "Is the current limiter per phase for the IBR when operating in GFM mode. This limit is imposed to prevent the IBR to enter into Safe Mode when reaching the IBR power ratings." + CRLF + + "Once the IBR reaches this value, it remains there without moving into Safe Mode. This value needs to be set lower than the IBR Amps rating."); + AddProperty("AmpLimitGain", propAmpsError, + "Use it for fine tunning the current limiter when active, by default is 0.8, it has to be a value between 0.1 and 1. This value allows users to fine tune the IBRs current limiter to match with the user requirements."); + + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override default help string + PropertyHelp[NumPropsThisClass] = "Name of harmonic voltage or current spectrum for this Storage element. " + "Current injection is assumed for inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TStorage::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Storage element and add it to Storage class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TStorageObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorage::SetNcondsForConnection() +{ + /*# with ActiveStorageObj do */ + { + auto with0 = ActiveStorageObj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases + 1); + break; + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); + break; + } + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorage::UpdateAll(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TStorageObj(ElementList.Get(i)) do */ + { + auto with0 = ((TStorageObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->UpdateStorage(ActorID); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TStorage::InterpretConnection(const String s) +{ + String TestS; + /*# with ActiveStorageObj do */ + { + auto with0 = ActiveStorageObj; + TestS = LowerCase(s); + switch(TestS[0]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[1]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + SetNcondsForConnection(); + + /*VBase is always L-N voltage unless 1-phase device or more than 3 phases*/ + switch(with0->Fnphases) + { + case 2: + case 3: + with0->VBase = with0->StorageVars.kVStorageBase * InvSQRT3x1000; + break; // L-N Volts + default: + with0->VBase = with0->StorageVars.kVStorageBase * 1000.0; // Just use what is supplied + break; + } + with0->VBase95 = with0->Vminpu * with0->VBase; + with0->VBase105 = with0->Vmaxpu * with0->VBase; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int InterpretDispMode(const String s) +{ + int result = 0; + switch(LowerCase(s)[0]) + { + case L'e': + result = STORE_EXTERNALMODE; + break; + case L'f': + result = STORE_FOLLOW; + break; + case L'l': + result = STORE_LOADMODE; + break; + case L'p': + result = STORE_PRICEMODE; + break; + default: + result = STORE_DEFAULT; + break; + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +String ReturnDispMode(int iMode) +{ + String result; + switch(iMode) + { + case STORE_EXTERNALMODE: + result = "External"; + break; + case STORE_FOLLOW: + result = "Follow"; + break; + case STORE_LOADMODE: + result = "Loadshape"; + break; + case STORE_PRICEMODE: + result = "Price"; + break; + default: + result = "default"; + break; + } + return result; +} + + + +//- - - - - - - - - - - - - - -MAIN EDIT FUNCTION - - - - - - - - - - - - - - - + +int TStorage::Edit(int ActorID) +{ + int result = 0, + i = 0, + iCase = 0, + ParamPointer = 0, + VarIdx; + String ParamName = "", + Param = ""; + + // continue parsing with contents of Parser + ActiveStorageObj = (TStorageObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveStorageObj); + result = 0; + /*# with ActiveStorageObj do */ + { + auto with0 = ActiveStorageObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); // Parse next property off the command line + Param = Parser[ActorID]->MakeString_(); // Put the string value of the property value in local memory for faster access + while(Param.size() > 0) + { + if(ParamName.size() == 0) // If it is not a named property, assume the next property + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); // Look up the name in the list for this class + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) // Update the string value of the property + ( (TDSSObject*) with0 )->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1], Param); + else + { + VarIdx = with0->CheckIfDynVar(ParamName, ActorID); + if (VarIdx < 0) + DoSimpleMsg(String("Unknown parameter \"") + ParamName + "\" for Storage \"" + with0->get_Name() + "\"", 560); + } + if(ParamPointer > 0) + { + iCase = (PropertyIdxMap)[ParamPointer - 1]; + switch(iCase) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->SetBus(1, Param); + break; + case propKV: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_()); + break; + case propKW: + with0->Set_kW( Parser[ActorID]->MakeDouble_()); + break; + case propPF: + { + with0->Set_Varmode(VARMODEPF); + with0->PFNominal = Parser[ActorID]->MakeDouble_(); + } + break; + case propMODEL: + with0->VoltageModel = Parser[ActorID]->MakeInteger_(); + break; + case propYEARLY: + with0->YearlyShape = Param; + break; + case propDAILY: + with0->DailyShape = Param; + break; + case propDUTY: + with0->DutyShape = Param; + break; + case propDISPMODE: + with0->DispatchMode = InterpretDispMode(Param); + break; + case PropConnection: + InterpretConnection(Param); + break; + case propKVAR: + { + with0->Set_Varmode(VARMODEKVAR); + with0->Set_kvarRequested(Parser[ActorID]->MakeDouble_()); + } + break; + case propPCTR: + with0->pctR = Parser[ActorID]->MakeDouble_(); + break; + case propPCTX: + with0->pctX = Parser[ActorID]->MakeDouble_(); + break; + case propIDLEKW: + with0->pctIdlekW = Parser[ActorID]->MakeDouble_(); + break; + case propIDLEKVAR: + ; + break; // Do nothing. Deprecated property. + case propCLASS: + with0->StorageClass = Parser[ActorID]->MakeInteger_(); + break; + case propInvEffCurve: + with0->InverterCurve = Param; + break; + case propDISPOUTTRIG: + with0->DischargeTrigger = Parser[ActorID]->MakeDouble_(); + break; + case propDISPINTRIG: + with0->ChargeTrigger = Parser[ActorID]->MakeDouble_(); + break; + case propCHARGEEFF: + with0->pctChargeEff = Parser[ActorID]->MakeDouble_(); + break; + case propDISCHARGEEFF: + with0->pctDischargeEff = Parser[ActorID]->MakeDouble_(); + break; + case propPCTKWOUT: + with0->Set_pctkWOut(Parser[ActorID]->MakeDouble_()); + break; + case propCutin: + with0->FpctCutIn = Parser[ActorID]->MakeDouble_(); + break; + case propCutout: + with0->FpctCutOut = Parser[ActorID]->MakeDouble_(); + break; + case propVMINPU: + with0->Vminpu = Parser[ActorID]->MakeDouble_(); + break; + case propVMAXPU: + with0->Vmaxpu = Parser[ActorID]->MakeDouble_(); + break; + case propSTATE: + with0->fState = with0->InterpretState(Param); + break; //**** + case propKVA: + /*# with StorageVars do */ + { + auto& with1 = with0->StorageVars; + with1.FkVArating = Parser[ActorID]->MakeDouble_(); + with0->kVASet = true; + if(!with0->kvarLimitSet) + with0->StorageVars.Fkvarlimit = with1.FkVArating; + if(!with0->kvarLimitSet && !with0->kvarLimitNegSet) + with0->StorageVars.Fkvarlimitneg = with1.FkVArating; + } + break; + case propKWRATED: + with0->StorageVars.kWrating = Parser[ActorID]->MakeDouble_(); + break; + case propKWHRATED: + with0->StorageVars.kWhRating = Parser[ActorID]->MakeDouble_(); + break; + case propKWHSTORED: + with0->StorageVars.kWhStored = Parser[ActorID]->MakeDouble_(); + break; + case propPCTRESERVE: + with0->pctReserve = Parser[ActorID]->MakeDouble_(); + break; + case propUSERMODEL: + with0->UserModel->Set_Name(Parser[ActorID]->MakeString_()); + break; // Connect to user written models + case propUSERDATA: + with0->UserModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; // Send edit string to user model + case propDEBUGTRACE: + with0->DebugTrace = InterpretYesNo(Param); + break; + case propPCTKWIN: + with0->Set_pctkWIn(Parser[ActorID]->MakeDouble_()); + break; + case propPCTSTORED: + with0->StorageVars.kWhStored = Parser[ActorID]->MakeDouble_() * 0.01 * with0->StorageVars.kWhRating; + break; + case propCHARGETIME: + with0->ChargeTime = Parser[ActorID]->MakeDouble_(); + break; + case propDynaDLL: + with0->DynaModel->FName = Parser[ActorID]->MakeString_(); + break; + case propDynaData: + with0->DynaModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; + case proppctkWrated: + with0->StorageVars.FpctkWrated = Parser[ActorID]->MakeDouble_() / 100.0; + break; // convert to pu + case propBalanced: + with0->ForceBalanced = InterpretYesNo(Param); + break; + case propLimited: + with0->CurrentLimited = InterpretYesNo(Param); + break; + case propVarFollowInverter: + with0->FVarFollowInverter = InterpretYesNo(Param); + break; + case propkvarLimit: + { + with0->StorageVars.Fkvarlimit = Abs( Parser[ActorID]->MakeDouble_()); + with0->kvarLimitSet = true; + if(!with0->kvarLimitNegSet) + with0->StorageVars.Fkvarlimitneg = Abs(with0->StorageVars.Fkvarlimit); + } + break; + case propPpriority: + with0->StorageVars.P_Priority = InterpretYesNo(Param); + break; // watt priority flag + case propPFpriority: + with0->StorageVars.PF_Priority = InterpretYesNo(Param); + break; + case propPminNoVars: + with0->FpctPminNoVars = Parser[ActorID]->MakeDouble_(); + break; + case propPminkvarLimit: + with0->FpctPminkvarLimit = Parser[ActorID]->MakeDouble_(); + break; + case propkvarLimitneg: + { + with0->StorageVars.Fkvarlimitneg = Abs( Parser[ActorID]->MakeDouble_()); + with0->kvarLimitNegSet = true; + } + break; + case propkVDC: + with0->myDynVars.RatedVDC = Parser[ActorID]->MakeDouble_() * 1000; + break; + case propkp: + with0->myDynVars.Kp = Parser[ActorID]->MakeDouble_() / 1000; + break; + case propCtrlTol: + with0->myDynVars.CtrlTol = Parser[ActorID]->MakeDouble_() / 100; + break; + case propSMT: + with0->myDynVars.SMThreshold = Parser[ActorID]->MakeDouble_(); + break; + case propDynEq: + with0->DynamicEq = Param; + break; + case propDynOut: + with0->SetDynOutput(Param); + break; + case propGFM: + { + if (LowerCase(Parser[ActorID]->MakeString_()) == "gfm") + { + with0->GFM_Mode = true; + with0->myDynVars.ResetIBR = false; + if (with0->myDynVars.Vgrid.size() < with0->Get_NPhases()) + with0->myDynVars.Vgrid.resize(with0->Get_NPhases()); + } + else + with0->GFM_Mode = false; + + with0->Set_YprimInvalid(ActorID, true); + } + break; + case propAmpsLimit: + with0->myDynVars.ILimit = Parser[ActorID]->MakeDouble_(); + break; + case propAmpsError: + with0->myDynVars.VError = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + inherited::ClassEdit(ActiveStorageObj, ParamPointer - NumPropsThisClass); + break; + } + switch(iCase) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + // (PR) Make sure if we will need it + /* removed + propKW,propPF: Begin + SyncUpPowerQuantities; // keep kvar nominal up to date with kW and PF + + End; */ + + /*Set loadshape objects; returns nil If not valid*/ + case propYEARLY: + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + break; + case propDAILY: + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + break; + case propDUTY: + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + break; + case propKWRATED: + if(!with0->kVASet) + with0->StorageVars.FkVArating = with0->StorageVars.kWrating; + break; + case propKWHRATED: + { + with0->StorageVars.kWhStored = with0->StorageVars.kWhRating; // Assume fully charged + with0->kWhBeforeUpdate = with0->StorageVars.kWhStored; + with0->StorageVars.kWhReserve = with0->StorageVars.kWhRating * with0->pctReserve * 0.01; + } + break; + case propPCTRESERVE: + with0->StorageVars.kWhReserve = with0->StorageVars.kWhRating * with0->pctReserve * 0.01; + break; + case propInvEffCurve: + with0->InverterCurveObj = ( (TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->InverterCurve) ); + break; + case propDEBUGTRACE: + if(with0->DebugTrace) // Init trace file + { + int stop = 0; + AssignFile(with0->Tracefile, GetOutputDirectory() + "STOR_" + with0->get_Name() + ".CSV"); + Rewrite(with0->Tracefile); + IOResultToException(); + Write(with0->Tracefile, "t, Iteration, LoadMultiplier, Mode, LoadModel, StorageModel, Qnominalperphase, Pnominalperphase, CurrentType"); + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iinj") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iterm") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Vterm") + IntToStr(i) + "|"); + } + for(stop = with0->NumVariables(), i = 1; i <= stop; i++) + { + { Write(with0->Tracefile, ", "); Write(with0->Tracefile, with0->VariableName(i)); } + } + Write(with0->Tracefile, ",Vthev, Theta"); + WriteLn(with0->Tracefile); + CloseFile(with0->Tracefile); + } + break; + case propUSERMODEL: + with0->IsUserModel = with0->UserModel->Get_Exists(); + break; + case propDynaDLL: + with0->IsUserModel = with0->DynaModel->Get_Exists(); + break; + case propDynEq: + { + with0->DynamicEqObj = (TDynamicExpObj*) TDynamicExpClass[ActorID]->Find(with0->DynamicEq); + if (ASSIGNED(with0->DynamicEqObj)) + { + with0->DynamicEqVals.resize(with0->DynamicEqObj->get_FNumVars()); + for (int idx = 0; idx < with0->DynamicEqVals.size(); idx++) + with0->DynamicEqVals[idx].resize(2); + } + } + break; + +// propPFPriority: For i := 1 to ControlElementList.ListSize Do +// Begin +// +// if TControlElem(ControlElementList.Get(i)).ClassName = 'InvControl' Then +// // Except for VW mode, all other modes (including combined ones) can operate with PF priority +// if (TInvControlObj(ControlElementList.Get(i)).Mode <> 'VOLTWATT') Then +// StorageVars.PF_Priority := FALSE; // For all other modes +// +// End; + default: + ; + break; + } + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + + +// Copy over essential properties from other object + +int TStorage::MakeLike(const String OtherStorageObjName) +{ + int result = 0; + TStorageObj* OtherStorageObj = nullptr; + int i = 0; + result = 0; + /*See If we can find this line name in the present collection*/ + OtherStorageObj = ((TStorageObj*) Find(OtherStorageObjName)); + if(OtherStorageObj != nullptr) + /*# with ActiveStorageObj do */ + { + auto with0 = ActiveStorageObj; + int stop = 0; + if(with0->Fnphases != OtherStorageObj->Fnphases) + { + with0->Set_NPhases(OtherStorageObj->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->StorageVars.kVStorageBase = OtherStorageObj->StorageVars.kVStorageBase; + with0->VBase = OtherStorageObj->VBase; + with0->Vminpu = OtherStorageObj->Vminpu; + with0->Vmaxpu = OtherStorageObj->Vmaxpu; + with0->VBase95 = OtherStorageObj->VBase95; + with0->VBase105 = OtherStorageObj->VBase105; + with0->kW_out = OtherStorageObj->kW_out; + with0->kvar_out = OtherStorageObj->kvar_out; + with0->Pnominalperphase = OtherStorageObj->Pnominalperphase; + with0->PFNominal = OtherStorageObj->PFNominal; + with0->Qnominalperphase = OtherStorageObj->Qnominalperphase; + with0->Connection = OtherStorageObj->Connection; + with0->YearlyShape = OtherStorageObj->YearlyShape; + with0->YearlyShapeObj = OtherStorageObj->YearlyShapeObj; + with0->DailyShape = OtherStorageObj->DailyShape; + with0->DailyShapeObj = OtherStorageObj->DailyShapeObj; + with0->DutyShape = OtherStorageObj->DutyShape; + with0->DutyShapeObj = OtherStorageObj->DutyShapeObj; + with0->DispatchMode = OtherStorageObj->DispatchMode; + with0->InverterCurve = OtherStorageObj->InverterCurve; + with0->InverterCurveObj = OtherStorageObj->InverterCurveObj; + with0->StorageClass = OtherStorageObj->StorageClass; + with0->VoltageModel = OtherStorageObj->VoltageModel; + with0->fState = OtherStorageObj->fState; + with0->FStateChanged = OtherStorageObj->FStateChanged; + with0->kvarLimitSet = OtherStorageObj->kvarLimitSet; + with0->kvarLimitNegSet = OtherStorageObj->kvarLimitNegSet; + with0->FpctCutIn = OtherStorageObj->FpctCutIn; + with0->FpctCutOut = OtherStorageObj->FpctCutOut; + with0->FVarFollowInverter = OtherStorageObj->FVarFollowInverter; + with0->StorageVars.Fkvarlimit = OtherStorageObj->StorageVars.Fkvarlimit; + with0->StorageVars.Fkvarlimitneg = OtherStorageObj->StorageVars.Fkvarlimitneg; + with0->StorageVars.FkVArating = OtherStorageObj->StorageVars.FkVArating; + with0->FpctPminNoVars = OtherStorageObj->FpctPminNoVars; + with0->FpctPminkvarLimit = OtherStorageObj->FpctPminkvarLimit; + with0->kWOutIdling = OtherStorageObj->kWOutIdling; + with0->StorageVars.kWrating = OtherStorageObj->StorageVars.kWrating; + with0->StorageVars.kWhRating = OtherStorageObj->StorageVars.kWhRating; + with0->StorageVars.kWhStored = OtherStorageObj->StorageVars.kWhStored; + with0->StorageVars.kWhReserve = OtherStorageObj->StorageVars.kWhReserve; + with0->kWhBeforeUpdate = OtherStorageObj->kWhBeforeUpdate; + with0->pctReserve = OtherStorageObj->pctReserve; + with0->DischargeTrigger = OtherStorageObj->DischargeTrigger; + with0->ChargeTrigger = OtherStorageObj->ChargeTrigger; + with0->pctChargeEff = OtherStorageObj->pctChargeEff; + with0->pctDischargeEff = OtherStorageObj->pctDischargeEff; + with0->Set_pctkWOut(OtherStorageObj->get_FpctkWout()); + with0->Set_pctkWIn(OtherStorageObj->Get_FpctkWIn()); + with0->pctIdlekW = OtherStorageObj->pctIdlekW; + with0->pctIdlekvar = OtherStorageObj->pctIdlekvar; + with0->ChargeTime = OtherStorageObj->ChargeTime; + with0->pctR = OtherStorageObj->pctR; + with0->pctX = OtherStorageObj->pctX; + with0->RandomMult = OtherStorageObj->RandomMult; + with0->FVWMode = OtherStorageObj->FVWMode; + with0->FVVMode = OtherStorageObj->FVVMode; + with0->FDRCMode = OtherStorageObj->FDRCMode; + with0->FWPMode = OtherStorageObj->FWPMode; + with0->FWVMode = OtherStorageObj->FWVMode; + with0->FAVRMode = OtherStorageObj->FAVRMode; + with0->UserModel->FName = OtherStorageObj->UserModel->FName; // Connect to user written models + with0->DynaModel->FName = OtherStorageObj->DynaModel->FName; + with0->IsUserModel = OtherStorageObj->IsUserModel; + with0->ForceBalanced = OtherStorageObj->ForceBalanced; + with0->CurrentLimited = OtherStorageObj->CurrentLimited; + ClassMakeLike(OtherStorageObj); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0->FPropertyValue)[i - 1] = (OtherStorageObj->FPropertyValue)[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Storage MakeLike: \"") + OtherStorageObjName + + "\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + +int TStorage::Init(int Handle, int ActorID) +{ + int result = 0; + TStorageObj* P = nullptr; + if(Handle == 0) // init all + { + P = (TStorageObj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TStorageObj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TStorageObj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TStorage.Init", -1); + result = 0; + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to reset + +void TStorage::ResetRegistersAll() +{ + int Idx = 0; + Idx = Get_First(); + while(Idx > 0) + { + ((TStorageObj*) GetActiveObj())->ResetRegisters(); + Idx = Get_Next(); + } +} + +/*--------------------------------------------------------------------------*/ // Force all Storage elements in the circuit to take a sample + +void TStorage::SampleAll(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = ElementList.get_myNumList(), i = 1; i <= stop; i++) + { + /*# with TStorageObj(ElementList.Get(i)) do */ + { + auto with0 = ((TStorageObj*) ElementList.Get(i)); + if(with0->Get_Enabled()) + with0->TakeSample(ActorID); + } + } +} + +//---------------------------------------------------------------------------- + +TStorageObj::TStorageObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + MaxDynPhaseCurrent(0.0), + DebugTrace(false), + fState(0), + FStateChanged(false), + FirstSampleAfterReset(false), + StorageSolutionCount(0), + StorageFundamental(0.0), + StorageObjSwitchOpen(false), + ForceBalanced(false), + CurrentLimited(false), + pctR(0.0), + pctX(0.0), + OpenStorageSolutionCount(0), + Pnominalperphase(0.0), + Qnominalperphase(0.0), + RandomMult(0.0), + Reg_Hours(0), + Reg_kvarh(0), + Reg_kWh(0), + Reg_MaxkVA(0), + Reg_MaxkW(0), + Reg_Price(0), + IsUserModel(false), + UserModel(nullptr), + DynaModel(nullptr), + kvarBase(0.0), + VBase(0.0), + VBase105(0.0), + VBase95(0.0), + Vmaxpu(0.0), + Vminpu(0.0), + YPrimOpenCond(nullptr), + Connection(0), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr), + StorageClass(0), + VoltageModel(0), + PFNominal(0.0), + YearlyShapeObj(nullptr), + FpctkWout(0.0), + Fpctkvarout(0.0), + pctReserve(0.0), + DispatchMode(0), + kVANotSet(false), + kvar_out(0.0), + kW_out(0.0), + pctIdlekW(0.0), + pctIdlekvar(0.0), + pctChargeEff(0.0), + pctDischargeEff(0.0), + DischargeTrigger(0.0), + ChargeTrigger(0.0), + ChargeTime(0.0), + kWhBeforeUpdate(0.0) +{ + int i; + + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // + Storage_ELEMENT; // In both PCelement and Storageelement list + Set_NPhases(3); + Fnconds = 4; // defaults to wye + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations + YearlyShape = ""; + YearlyShapeObj = nullptr; // If YearlyShapeobj = nil Then the load alway stays nominal * global multipliers + DailyShape = ""; + DailyShapeObj = nullptr; // If DaillyShapeobj = nil Then the load alway stays nominal * global multipliers + DutyShape = ""; + DutyShapeObj = nullptr; // If DutyShapeobj = nil Then the load alway stays nominal * global multipliers + InverterCurveObj = nullptr; + InverterCurve = ""; + Connection = 0; // Wye (star) + VoltageModel = 1; /*Typical fixed kW negative load*/ + StorageClass = 1; + StorageSolutionCount = -1; // For keep track of the present solution in Injcurrent calcs + OpenStorageSolutionCount = -1; + YPrimOpenCond = nullptr; + StorageVars.kVStorageBase = 12.47; + VBase = 7200.0; + Vminpu = 0.90; + Vmaxpu = 1.10; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + RandomMult = 1.0; + Set_Varmode(VARMODEPF); + FInverterON = true; // start with inverterON + kVA_exceeded = false; + FVarFollowInverter = false; + ForceBalanced = false; + CurrentLimited = false; + NumStateVars = NumStorageVariables; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + auto& with01 = myDynVars; + with0.kWrating = 25.0; + with0.FkVArating = with0.kWrating; + with0.kWhRating = 50; + with0.kWhStored = with0.kWhRating; + kWhBeforeUpdate = with0.kWhRating; + with0.kWhReserve = with0.kWhRating * pctReserve / 100.0; + with0.Fkvarlimit = with0.FkVArating; + with0.Fkvarlimitneg = with0.FkVArating; + with0.FpctkWrated = 1.0; + with0.P_Priority = false; + with0.PF_Priority = false; + with0.EffFactor = 1.0; + with0.Vreg = 9999; + with0.Vavg = 9999; + with0.VVOperation = 9999; + with0.VWOperation = 9999; + with0.DRCOperation = 9999; + with0.VVDRCOperation = 9999; + with0.WPOperation = 9999; + with0.WVOperation = 9999; + with01.RatedVDC = 8000; + with01.SMThreshold = 80; + with01.SafeMode = false; + with01.Kp = 0.00001; + with01.ILimit = -1; // No Amps limit + with01.IComp = 0; + with01.VError = 0.8; + PICtrl.resize(0); + } + FDCkW = 25.0; + FpctCutIn = 0.0; + FpctCutOut = 0.0; + FpctPminNoVars = -1.0; // Deactivated by default + FpctPminkvarLimit = -1.0; // Deactivated by default + Fpf_wp_nominal = 1.0; + + /*Output rating stuff*/ + kvar_out = 0.0; + // removed kvarBase := kvar_out; // initialize + PFNominal = 1.0; + pctR = 0.0; + pctX = 50.0; + + /*Make the StorageVars struct as public*/ + PublicDataStruct = &StorageVars; + PublicDataSize = sizeof(TStorageVars); + IsUserModel = false; + UserModel = new TStoreUserModel(); + DynaModel = new TStoreDynaModel(); + fState = STORE_IDLING; // Idling and fully charged + FStateChanged = true; // Force building of YPrim + pctReserve = 20.0; // per cent of kWhRating + pctIdlekW = 1.0; + pctIdlekvar = 0.0; + DischargeTrigger = 0.0; + ChargeTrigger = 0.0; + pctChargeEff = 90.0; + pctDischargeEff = 90.0; + FpctkWout = 100.0; + FpctkWin = 100.0; + ChargeTime = 2.0; // 2 AM + kVASet = false; + kvarLimitSet = false; + kvarLimitNegSet = false; + Reg_kWh = 1 - 1; + Reg_kvarh = 2 - 1; + Reg_MaxkW = 3 - 1; + Reg_MaxkVA = 4 - 1; + Reg_Hours = 5 - 1; + Reg_Price = 6 - 1; + DebugTrace = false; + StorageObjSwitchOpen = false; + Spectrum = ""; // override base class + SpectrumObj = nullptr; + FVWMode = false; + FVVMode = false; + FDRCMode = false; + FWPMode = false; + FWVMode = false; + FAVRMode = false; + InitPropertyValues(0); + RecalcElementData(ActiveActor); + + for (i = 0; i < NumStorageRegisters; i++) + { + Registers[i] = 0.0; + Derivatives[i] = 0.0; + } +} + + +//---------------------------------------------------------------------------- + +String TStorageObj::DecodeState() +{ + String result; + switch(fState) + { + case STORE_CHARGING: + result = "CHARGING"; + break; + case STORE_DISCHARGING: + result = "DISCHARGING"; + break; + default: + result = "IDLING"; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_FkVARating() +{ + return StorageVars.FkVArating; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_FpctkWrated() +{ + return StorageVars.FpctkWrated; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_Fkvarlimit() +{ + return StorageVars.Fkvarlimit; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_Fkvarlimitneg() +{ + return StorageVars.Fkvarlimitneg; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_FpctkWIn() +{ + return FpctkWin; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_InverterLosses() +{ + double Result; + + switch (get_fState()) + { + case STORE_IDLING: + Result = abs(Get_Power(1, ActiveActor).re * 0.001) - abs(Get_DCkW()); + break; + case STORE_CHARGING: + Result = abs(Get_Power(1, ActiveActor).re * 0.001) - abs(Get_DCkW()); + break; + case STORE_DISCHARGING: + Result = Get_DCkW() - abs(Get_Power(1, ActiveActor).re * 0.001); + break; + default: + Result = 0.0; + } + + return Result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kWChDchLosses() +{ + double Result; + + auto& with0 = StorageVars; + + switch (get_fState()) + { + case STORE_IDLING: + Result = 0.0; + break; + case STORE_CHARGING: + if (abs(Get_DCkW()) - PIdling > 0) + Result = (abs(Get_DCkW()) - PIdling) * (1.0 - 0.01 * pctChargeEff); // most cases will fall here + else + Result = -1 * (abs(Get_DCkW()) - PIdling) * (1.0 / (0.01 * pctDischargeEff) - 1.0); // exceptional cases when Pidling is higher than Get_DCkW() (net effect is that the ideal Storage will be discharged) + break; + case STORE_DISCHARGING: + Result = (Get_DCkW() + PIdling) * (1.0 / (0.01 * pctDischargeEff) - 1.0); + break; + default : + Result = 0.0; + } + return Result; +} + +//---------------------------------------------------------------------------- +/* +void TStorageObj::ComputeDCkW() +{ + TCoeff* coefGuess; + TCoeff* coef; + (coefGuess)[1] = 0.0; + (coefGuess)[2] = 0.0; + + (coef)[1] = 1.0; + (coef)[2] = 1.0; // just a guess + + FDCkW = Power[1][ActiveActor].re * 0.001; // Assume ideal inverter + + if (!ASSIGNED(InverterCurveObj)) + { + // make sure sign is correct + if (fState = STORE_IDLING) + FDCkW = abs(FDCkW) * -1; + else + FDCkW = abs(FDCkW) * fState; + } + else + { + int N_tentatives = 0; + while (((coef)[1] != (coefGuess)[1]) && ((coef)[2] != (coefGuess)[2]) || (N_tentatives > 9)) + { + N_tentatives = N_tentatives + 1; + coefGuess = &( InverterCurveObj.GetCoefficients(abs(FDCkW) / StorageVars.FkVArating) ); + + + switch (fState) + { + case STORE_DISCHARGING: + FDCkW = QuadSolver((coefGuess)[1] / StorageVars.FkVArating, (coefGuess)[2], -1.0 * abs(Power[1][ActiveActor].re * 0.001)); + break; + case STORE_CHARGING: STORE_IDLING: + FDCkW = abs(FDCkW) * (coefGuess)[2] / (1.0 - ((coefGuess)[1] * abs(FDCkW) / StorageVars.FkVArating)); + } + // Final coefficients + coef = &( InverterCurveObj.GetCoefficients(abs(FDCkW) / StorageVars.FkVArating) ); + } + + // make sure sign is correct + if (fState = STORE_IDLING) + FDCkW = abs(FDCkW) * -1; + else + FDCkW = abs(FDCkW) * fState; + } + free(coefGuess); + free(coef); +}*/ + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_DCkW() +{ + ComputeDCkW(); + return FDCkW; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_VminPu() +{ + return Vminpu; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_pf_wp_nominal(double myPFNom) +{ + Fpf_wp_nominal = myPFNom; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_Pmin() +{ + return -StorageVars.kWrating * Get_FpctkWIn() / 100.0; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_Pmax() +{ + return StorageVars.kWrating * get_FpctkWout() / 100.0; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_qMaxInj() +{ + return StorageVars.Fkvarlimit; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_qMaxAbs() +{ + return StorageVars.Fkvarlimitneg; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_acVmin() +{ + return ( Get_PresentkV() * Vminpu ); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_acVmax() +{ + return ( Get_PresentkV() * Vmaxpu ); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_acVnom() +{ + return Get_PresentkV(); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_pMaxUnderPF() +{ + auto& with0 = StorageVars; + return sqrt( Sqr(with0.FkVArating) - Sqr(with0.Fkvarlimitneg)); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_pMaxOverPF() +{ + auto& with0 = StorageVars; + return sqrt(Sqr(with0.FkVArating) - Sqr(with0.Fkvarlimit)); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_pMaxCharge() +{ + return abs(Get_Pmin()); +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_sMaxCharge() +{ + return StorageVars.FkVArating; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_CIMDynamicMode() +{ + bool result = false; + + result = (FVWMode || FVVMode || FWVMode || FAVRMode || FDRCMode); + + return result; +} + +//---------------------------------------------------------------------------- + + +// Define default values for the properties + +void TStorageObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1, "3"); //'phases'; + Set_PropertyValue(2, GetBus(1)); //'bus1'; + Set_PropertyValue(propKV, Format("%-g", StorageVars.kVStorageBase)); + Set_PropertyValue(propKW, Format("%-g", kW_out)); + Set_PropertyValue(propPF, Format("%-g", PFNominal)); + Set_PropertyValue(propMODEL, "1"); + Set_PropertyValue(propYEARLY, ""); + Set_PropertyValue(propDAILY, ""); + Set_PropertyValue(propDUTY, ""); + Set_PropertyValue(propDISPMODE, "Default"); + Set_PropertyValue(PropConnection, "wye"); + Set_PropertyValue(propKVAR, Format("%-g", Get_Presentkvar())); + Set_PropertyValue(propPCTR, Format("%-g", pctR)); + Set_PropertyValue(propPCTX, Format("%-g", pctX)); + Set_PropertyValue(propIDLEKW, "1"); // PERCENT + Set_PropertyValue(propIDLEKVAR, ""); // deprecated + Set_PropertyValue(propCLASS, "1"); //'class' + Set_PropertyValue(propDISPOUTTRIG, "0"); // 0 MEANS NO TRIGGER LEVEL + Set_PropertyValue(propDISPINTRIG, "0"); + Set_PropertyValue(propCHARGEEFF, "90"); + Set_PropertyValue(propDISCHARGEEFF, "90"); + Set_PropertyValue(propPCTKWOUT, "100"); + Set_PropertyValue(propPCTKWIN, "100"); + Set_PropertyValue(propInvEffCurve, ""); + Set_PropertyValue(propCutin, "0"); + Set_PropertyValue(propCutout, "0"); + Set_PropertyValue(propVarFollowInverter, "NO"); + Set_PropertyValue(propVMINPU, "0.90"); + Set_PropertyValue(propVMAXPU, "1.10"); + Set_PropertyValue(propSTATE, "IDLING"); + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + Set_PropertyValue(propKVA, Format("%-g", StorageVars.FkVArating)); + Set_PropertyValue(propkvarLimit, Format("%-g", with0.Fkvarlimit)); + Set_PropertyValue(propkvarLimitneg, Format("%-g", with0.Fkvarlimitneg)); + Set_PropertyValue(propKWRATED, Format("%-g", with0.kWrating)); + Set_PropertyValue(propKWHRATED, Format("%-g", with0.kWhRating)); + Set_PropertyValue(propKWHSTORED, Format("%-g", with0.kWhStored)); + Set_PropertyValue(propPCTSTORED, Format("%-g", with0.kWhStored / with0.kWhRating * 100.0)); + } + Set_PropertyValue(propPCTRESERVE, Format("%-g", pctReserve)); + Set_PropertyValue(propCHARGETIME, Format("%-g", ChargeTime)); + Set_PropertyValue(propUSERMODEL, ""); // Usermodel + Set_PropertyValue(propUSERDATA, ""); // Userdata + Set_PropertyValue(propDynaDLL, ""); // + Set_PropertyValue(propDynaData, ""); // + Set_PropertyValue(propDEBUGTRACE, "NO"); + Set_PropertyValue(propBalanced, "NO"); + Set_PropertyValue(propLimited, "NO"); + Set_PropertyValue(proppctkWrated, "100"); // Included + Set_PropertyValue(propPpriority, "NO"); // Included + Set_PropertyValue(propPFpriority, "NO"); + Set_PropertyValue(propkVDC, "8000"); + Set_PropertyValue(propkp,"0.00001"); + Set_PropertyValue(propCtrlTol,"5"); + Set_PropertyValue(propSMT,"80"); + Set_PropertyValue(propSM,"NO"); + Set_PropertyValue(propGFM,"GFL"); + + inherited::InitPropertyValues(NumPropsThisClass); +} + + +//---------------------------------------------------------------------------- + +String TStorageObj::GetPropertyValue(int Index) +{ + String result = ""; + + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + switch(Index) + { + case propKV: result = Format("%.6g", StorageVars.kVStorageBase); + break; + case propKW: result = Format("%.6g", kW_out); + break; + case propPF: result = Format("%.6g", PFNominal); + break; + case propMODEL: result = Format("%d", VoltageModel); + break; + case propYEARLY: result = YearlyShape; + break; + case propDAILY: result = DailyShape; + break; + case propDUTY: result = DutyShape; + break; + case propDISPMODE: result = ReturnDispMode(DispatchMode); + break; + + /*propCONNECTION :;*/ + case propKVAR: result = Format("%.6g", kvar_out); + break; + case propPCTR: result = Format("%.6g", pctR); + break; + case propPCTX: result = Format("%.6g", pctX); + break; + case propIDLEKW: result = Format("%.6g", pctIdlekW); + break; + case propIDLEKVAR: result = ""; + break; // deprecated + /*propCLASS = 17;*/ + case propInvEffCurve: result = InverterCurve; + break; + case propCutin: result = Format("%.6g", FpctCutIn); + break; + case propCutout: result = Format("%.6g", FpctCutOut); + break; + case propVarFollowInverter: + if(FVarFollowInverter) + result = "Yes"; + else + result = "No"; + break; + case propPminNoVars: result = Format("%.6g", FpctPminNoVars); + break; + case propPminkvarLimit: result = Format("%.6g", FpctPminkvarLimit); + break; + case propDISPOUTTRIG: result = Format("%.6g", DischargeTrigger); + break; + case propDISPINTRIG: result = Format("%.6g", ChargeTrigger); + break; + case propCHARGEEFF: result = Format("%.6g", pctChargeEff); + break; + case propDISCHARGEEFF: result = Format("%.6g", pctDischargeEff); + break; + case propPCTKWOUT: result = Format("%.6g", get_FpctkWout()); + break; + case propVMINPU: result = Format("%.6g", Vminpu); + break; + case propVMAXPU: result = Format("%.6g", Vmaxpu); + break; + case propSTATE: result = DecodeState(); + break; + + /*StorageVars*/ + case propKVA: result = Format("%.6g", with0.FkVArating); + break; + case propKWRATED: result = Format("%.6g", with0.kWrating); + break; + case propKWHRATED: result = Format("%.6g", with0.kWhRating); + break; + case propKWHSTORED: result = Format("%.6g", with0.kWhStored); + break; + case propPCTRESERVE: result = Format("%.6g", pctReserve); + break; + case propUSERMODEL: result = UserModel->get_FName(); + break; + case propUSERDATA: result = String("(") + inherited::GetPropertyValue(Index) + ")"; + break; + case proppctkWrated: result = Format("%.6g", with0.FpctkWrated * 100.0); + break; + case propDynaDLL: result = DynaModel->get_FName(); + break; + case propDynaData: result = String("(") + inherited::GetPropertyValue(Index) + ")"; + break; + /*propDEBUGTRACE = 33;*/ + case propPCTKWIN: result = Format("%.6g", Get_FpctkWIn()); + break; + case propPCTSTORED: result = Format("%.6g", with0.kWhStored / with0.kWhRating * 100.0); + break; + case propCHARGETIME: result = Format("%.6g", ChargeTime); + break; + case propBalanced: + if(ForceBalanced) + result = "Yes"; + else + result = "No"; + break; + case propLimited: + if(CurrentLimited) + result = "Yes"; + else + result = "No"; + break; + case propkvarLimit: result = Format("%.6g", with0.Fkvarlimit); + break; + case propkvarLimitneg: result = Format("%.6g", with0.Fkvarlimitneg); + break; // take the generic handler + case propkVDC: result = Format("%.6g", myDynVars.RatedVDC / 1000); + break; + case propkp: result = Format("%.10g", myDynVars.Kp * 1000); + break; + case propCtrlTol: result = Format("%.6g", myDynVars.CtrlTol * 100); + break; + case propSMT: result = Format("%.6g", myDynVars.SMThreshold); + break; + case propSM: if (myDynVars.SafeMode) result = "Yes"; else result = "NO"; + break; + case propDynEq: result = DynamicEq; + break; + case propDynOut: result = GetDynOutputStr(); + break; + case propGFM: if (GFM_Mode) result = "GFM"; else result = "GFL"; + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + } + return result; +} + + +//---------------------------------------------------------------------------- + +void TStorageObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + RandomMult = Gauss(YearlyShapeObj->Get_Mean(), YearlyShapeObj->Get_StdDev()); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + RandomMult = QuasiLogNormal(YearlyShapeObj->Get_Mean()); + break; + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +TStorageObj::~TStorageObj() +{ + delete YPrimOpenCond; + delete UserModel; + delete DynaModel; + // inherited::Destroy(); +} + + + +//---------------------------------------------------------------------------- + +void TStorageObj::CalcDailyMult(double hr, int ActorID) +{ + if(DailyShapeObj != nullptr) + { + ShapeFactor = DailyShapeObj->GetMult(hr); + } + else + ShapeFactor = CDoubleOne; // Default to no variation + CheckStateTriggerLevel(ShapeFactor.re, ActorID); // last recourse +} + + +//---------------------------------------------------------------------------- + +void TStorageObj::CalcDutyMult(double hr, int ActorID) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + CheckStateTriggerLevel(ShapeFactor.re, ActorID); + } + else + CalcDailyMult(hr, ActorID); // Default to Daily Mult If no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TStorageObj::CalcYearlyMult(double hr, int ActorID) +{ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + CheckStateTriggerLevel(ShapeFactor.re, ActorID); + } + else + CalcDailyMult(hr, ActorID); // Defaults to Daily curve +} + +//---------------------------------------------------------------------------- + +void TStorageObj::RecalcElementData(int ActorID) +{ + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + + // removed 5/8/17 kvarBase := kvar_out ; // remember this for Follow Mode + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + YeqDischarge = cmplx((with0.kWrating * 1000.0 / Sqr(VBase) / Fnphases), 0.0); + + // values in ohms for thevenin equivalents + with0.RThev = pctR * 0.01 * Sqr(Get_PresentkV()) / with0.FkVArating * 1000.0L; // Changed + with0.XThev = pctX * 0.01 * Sqr(Get_PresentkV()) / with0.FkVArating * 1000.0L; // Changed + CutInkW = FpctCutIn * with0.FkVArating / 100.0; + CutOutkW = FpctCutOut * with0.FkVArating / 100.0; + if(FpctPminNoVars <= 0) + PminNoVars = -1.0; + else + PminNoVars = FpctPminNoVars * with0.kWrating / 100.0; + if(FpctPminkvarLimit <= 0) + PminkvarLimit = -1.0; + else + PminkvarLimit = FpctPminkvarLimit * with0.kWrating / 100.0; + + // efficiencies + with0.ChargeEff = pctChargeEff * 0.01; + with0.DisChargeEff = pctDischargeEff * 0.01; + PIdling = pctIdlekW * with0.kWrating / 100.0; + if(InverterCurveObj != nullptr) + { + kWOutIdling = double(PIdling) / (InverterCurveObj->GetYValue_(double(PIdling) / (with0.FkVArating))); + } + else + kWOutIdling = PIdling; + } + SetNominalStorageOutput(ActorID); + + /*Now check for errors. If any of these came out nil and the string was not nil, give warning*/ + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 563); + } + if(DailyShapeObj == nullptr) + { + if(DailyShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyShape + + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 565); + } + if(Spectrum.size() > 0) + { + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 566); + } + else + SpectrumObj = nullptr; + + // Initialize to Zero - defaults to PQ Storage element + // Solution object will reset after circuit modifications + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + + /*Update any user-written models*/ + if(UserModel->Get_Exists()) + UserModel->FUpdateModel(); // Checks for existence and Selects + if(DynaModel->Get_Exists()) + DynaModel->FUpdateModel(); // Checks for existence and Selects +} +//---------------------------------------------------------------------------- + +void TStorageObj::SetNominalStorageOutput(int ActorID) +{ + ShapeFactor = CDoubleOne; // init here; changed by curve routine + // Check to make sure the Storage element is ON + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) // Leave Storage element in whatever state it was prior to entering Dynamic mode + + // Check dispatch to see what state the Storage element should be in + { + switch(DispatchMode) + { + case STORE_EXTERNALMODE: + ; + break; // Do nothing + case STORE_LOADMODE: + CheckStateTriggerLevel(ActiveCircuit[ActorID]->GeneratorDispatchReference, ActorID); + break; + case STORE_PRICEMODE: + CheckStateTriggerLevel(ActiveCircuit[ActorID]->PriceSignal, ActorID); + break; // dispatch off element's loadshapes, If any + default: + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + switch(with2->Get_SolMode()) + { + case SNAPSHOT: + ; + break; /*Just solve for the present kW, kvar*/ // Don't check for state change + case DAILYMODE: + CalcDailyMult(with2->DynaVars.dblHour, ActorID); + break; // Daily dispatch curve + case YEARLYMODE: + CalcYearlyMult(with2->DynaVars.dblHour, ActorID); + break; + /* + MONTECARLO1, + MONTEFAULT, + FAULTSTUDY, + DYNAMICMODE: ; // {do nothing for these modes} + */ + // This mode allows use of one class of load shape + case GENERALTIME: + { + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with2->DynaVars.dblHour, ActorID); + break; + case USEYEARLY: + CalcYearlyMult(with2->DynaVars.dblHour, ActorID); + break; + case USEDUTY: + CalcDutyMult(with2->DynaVars.dblHour, ActorID); + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + // Assume Daily curve, If any, for the following + case MONTECARLO2: case MONTECARLO3: case LOADDURATION1: case LOADDURATION2: + CalcDailyMult(with2->DynaVars.dblHour, ActorID); + break; + case PEAKDAY: + CalcDailyMult(with2->DynaVars.dblHour, ActorID); + break; + case DUTYCYCLE: + CalcDutyMult(with2->DynaVars.dblHour, ActorID); + break; + /*AUTOADDFLAG: ; */ + default: + ; + break; + } + } + break; + } + ComputekWkvar(); + + /* + Pnominalperphase is net at the terminal. If supplying idling losses, when discharging, + the Storage supplies the idling losses. When charging, the idling losses are subtracting from the amount + entering the Storage element. + */ + /*# with StorageVars do */ + { + auto& with3 = StorageVars; + Pnominalperphase = 1000.0 * kW_out / Fnphases; + Qnominalperphase = 1000.0 * kvar_out / Fnphases; + } + switch(VoltageModel) + { + case 3: + //**** Fix this when user model gets connected in + // Yeq := Cinv(cmplx(0.0, -StoreVARs.Xd)) ; // Gets negated in CalcYPrim + ; + break; + /* + Yeq no longer used for anything other than this calculation of Yeq95, Yeq105 and + constant Z power flow model + */ + default: + Yeq = cdivreal(cmplx(Pnominalperphase, -Qnominalperphase), Sqr(VBase)); // Vbase must be L-N for 3-phase + if(Vminpu != 0.0) // at 95% voltage + Yeq95 = cdivreal(Yeq, Sqr(Vminpu)); + else + Yeq95 = Yeq; // Always a constant Z model + if(Vmaxpu != 0.0) // at 105% voltage + Yeq105 = cdivreal(Yeq, Sqr(Vmaxpu)); + else + Yeq105 = Yeq; + break; + } + /* Like Model 7 generator, max current is based on amount of current to get out requested power at min voltage + */ + /*# with StorageVars do */ + { + auto& with4 = StorageVars; + PhaseCurrentLimit = cdivreal(cmplx(Pnominalperphase, Qnominalperphase), VBase95); + MaxDynPhaseCurrent = cabs(PhaseCurrentLimit); + } + + /* When we leave here, all the Yeq's are in L-N values*/ + } /*If NOT (IsDynamicModel or IsHarmonicModel)*/ + } /*With ActiveCircuit[ActiveActor]*/ + + // If Storage element state changes, force re-calc of Y matrix + if(FStateChanged) + { + Set_YprimInvalid(ActorID,true); + FStateChanged = false; // reset the flag + } +} +// =========================================================================================== + +void TStorageObj::ComputekWkvar() +{ + ComputePresentkW(); + ComputeInverterPower(); // apply inverter eff after checking for cutin/cutout +} +//---------------------------------------------------------------------------- + +void TStorageObj::ComputePresentkW() +{ + int OldState = 0; + OldState = fState; + FStateDesired = OldState; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + switch(fState) + { + case STORE_CHARGING: + { + if(with0.kWhStored < with0.kWhRating) + switch(DispatchMode) + { + case STORE_FOLLOW: + { + kW_out = with0.kWrating * ShapeFactor.re; + FpctkWin = Abs( ShapeFactor.re) * 100.0; // keep %charge updated + } + break; + default: + kW_out = -with0.kWrating * Get_FpctkWIn() / 100.0; + break; + } + else + fState = STORE_IDLING; // all charged up + } + break; + case STORE_DISCHARGING: + { + if(with0.kWhStored > with0.kWhReserve) + switch(DispatchMode) + { + case STORE_FOLLOW: + { + kW_out = with0.kWrating * ShapeFactor.re; + FpctkWout = Abs( ShapeFactor.re) * 100.0; // keep %discharge updated + } + break; + default: + kW_out = with0.kWrating * get_FpctkWout() / 100.0; + break; + } + else + fState = STORE_IDLING; // not enough Storage to discharge + } + break; + default: + ; + break; + } + } + + /*If idling output is only losses*/ + if(fState == STORE_IDLING) + { + kW_out = -kWOutIdling; + } + if(OldState != fState) + FStateChanged = true; +} + +// =========================================================================================== + +void TStorageObj::ComputeInverterPower() +{ + double kVA_Gen = 0.0; + int OldState = 0; + double TempPF = 0.0; // temporary power factor + double Qramp_limit = 0.0; + + // Reset CurrentkvarLimit to kvarLimit + CurrentkvarLimit = StorageVars.Fkvarlimit; + CurrentkvarLimitNeg = StorageVars.Fkvarlimitneg; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + if(InverterCurveObj != nullptr) + { + if(fState == STORE_DISCHARGING) + { + FCutOutkWAC = CutOutkW * InverterCurveObj->GetYValue_(double(Abs(CutOutkW)) / with0.FkVArating); + FCutInkWAC = CutInkW * InverterCurveObj->GetYValue_(double(Abs(CutInkW)) / with0.FkVArating); + } + else + // Charging or Idling + { + FCutOutkWAC = double(CutOutkW) / InverterCurveObj->GetYValue_(double(Abs(CutOutkW)) / with0.FkVArating); + FCutInkWAC = double(CutInkW) / InverterCurveObj->GetYValue_(double(Abs(CutInkW)) / with0.FkVArating); + } + } + else + // Assume Ideal Inverter + { + FCutOutkWAC = CutOutkW; + FCutInkWAC = CutInkW; + } + OldState = fState; + + // CutIn/CutOut checking performed on the AC side. + if(FInverterON) + { + if(Abs(kW_out) < FCutOutkWAC) + { + FInverterON = false; + fState = STORE_IDLING; + } + } + else + { + if(Abs(kW_out) >= FCutInkWAC) + { + FInverterON = true; + } + else + { + fState = STORE_IDLING; + } + } + if(OldState != fState) + FStateChanged = true; + + // Set inverter output + if(FInverterON) + { + kWOut_Calc(); + } + else + + // Idling + { + kW_out = -kWOutIdling; // In case it has just turned off due to %CutIn/%CutOut. Necessary to make sure SOC will be kept constant (higher priority than the %CutIn/%CutOut operation) + } + + + // Calculate kvar value based on operation mode (PF or kvar) + if(fState == STORE_IDLING) // Should watt-pf with watt=0 be applied here? + // If in Idling state, check for kvarlimit only + { + if(Get_Varmode() == VARMODEPF) +// kvar_out := 0.0; //kW = 0 leads to kvar = 0 in constant PF Mode + { + kvar_out = kW_out * sqrt(1.0L / Sqr(PFNominal) - 1.0L) * Sign(PFNominal); + if((kvar_out > 0.0) && (Abs( kvar_out) > with0.Fkvarlimit)) + kvar_out = with0.Fkvarlimit; + else + { + if((kvar_out < 0.0) && (Abs( kvar_out) > with0.Fkvarlimitneg)) + kvar_out = with0.Fkvarlimitneg * Sign(Get_kvarRequested()); + } + } + else + // kvarRequested might have been set either internally or by an InvControl + { + double kvarReq = Get_kvarRequested(); + if((kvarReq > 0.0) && (Abs(kvarReq) > with0.Fkvarlimit)) + kvar_out = with0.Fkvarlimit; + else + { + if((kvarReq < 0.0) && (Abs( kvarReq) > with0.Fkvarlimitneg)) + kvar_out = with0.Fkvarlimitneg * Sign(kvarReq); + else + kvar_out = kvarReq; + } + } + } + else + + // If in either Charging or Discharging states + { + if(Abs( kW_out) < PminNoVars) + { + kvar_out = 0.0; // Check minimum P for Q gen/absorption. if PminNoVars is disabled (-1), this will always be false + CurrentkvarLimit = 0; + CurrentkvarLimitNeg = 0.0; // InvControl uses this. + } + else + { + if(Get_Varmode() == VARMODEPF) + { + if(PFNominal == 1.0) + kvar_out = 0.0; + else + { + kvar_out = kW_out * sqrt(1.0L / Sqr(PFNominal) - 1.0L) * Sign(PFNominal); //kvar_out desired by constant PF + + // Check Limits + if(Abs( kW_out) < PminkvarLimit) // straight line limit check. if PminkvarLimit is disabled (-1), this will always be false. + + // straight line starts at max(PminNoVars, FCutOutkWAC) + // if CutOut differs from CutIn, take cutout since it is assumed that CutOut <= CutIn always. + { + if(Abs( kW_out) >= max(PminNoVars, FCutOutkWAC)) + { + if(kvar_out > 0.0) + { + Qramp_limit = double(with0.Fkvarlimit) / PminkvarLimit * Abs( kW_out); // generation limit + } + else + { + if(kvar_out < 0.0) + { + Qramp_limit = double(with0.Fkvarlimitneg) / PminkvarLimit * Abs( kW_out); // absorption limit + } + } + if(Abs( kvar_out) > Qramp_limit) + { + kvar_out = Qramp_limit * Sign(kW_out) * Sign(PFNominal); + if(kvar_out > 0) + CurrentkvarLimit = Qramp_limit; // For use in InvControl + if(kvar_out < 0) + CurrentkvarLimitNeg = Qramp_limit; // For use in InvControl + } + } + } + else + { + if((Abs( kvar_out) > with0.Fkvarlimit) || (Abs( kvar_out) > with0.Fkvarlimitneg)) // Other cases, check normal kvarLimit and kvarLimitNeg + { + if(kvar_out > 0.0) + kvar_out = with0.Fkvarlimit * Sign(kW_out) * Sign(PFNominal); + else + kvar_out = with0.Fkvarlimitneg * Sign(kW_out) * Sign(PFNominal); + if(with0.PF_Priority) // Forces constant power factor when kvar limit is exceeded and PF Priority is true. + { + kW_out = kvar_out * sqrt(1.0 / (1.0L - Sqr(PFNominal)) - 1.0) * Sign(PFNominal); + } + } + } + } + } + else + // VARMODE kvar + + // Check limits + { + if(Abs( kW_out) < PminkvarLimit) // straight line limit check. if PminkvarLimit is disabled (-1), this will always be false. + + // straight line starts at max(PminNoVars, FCutOutkWAC) + // if CutOut differs from CutIn, take cutout since it is assumed that CutOut <= CutIn always. + { + if(Abs( kW_out) >= max(PminNoVars, FCutOutkWAC)) + { + if(with0.kvarRequested > 0.0) + { + Qramp_limit = double(with0.Fkvarlimit) / PminkvarLimit * Abs( kW_out); // generation limit + CurrentkvarLimit = Qramp_limit; // For use in InvControl + } + else + { + if(with0.kvarRequested < 0.0) + { + Qramp_limit = double(with0.Fkvarlimitneg) / PminkvarLimit * Abs( kW_out); // absorption limit + CurrentkvarLimitNeg = Qramp_limit; // For use in InvControl + } + } + if(Abs( with0.kvarRequested) > Qramp_limit) + kvar_out = Qramp_limit * Sign(with0.kvarRequested); + else + kvar_out = with0.kvarRequested; + } + } + else + { + double kvarReq = Get_kvarRequested(); + if(((kvarReq > 0.0) && (Abs( kvarReq) > with0.Fkvarlimit)) || ((kvarReq < 0.0) && (Abs( kvarReq) > with0.Fkvarlimitneg))) + { + if(kvarReq > 0.0) + kvar_out = with0.Fkvarlimit * Sign(kvarReq); + else + kvar_out = with0.Fkvarlimitneg * Sign(kvarReq); + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && FWPMode) + { + kW_out = Abs( kvar_out) * sqrt(1.0 / (1.0L - Sqr(Fpf_wp_nominal)) - 1.0) * Sign(kW_out); + + // Forces constant power factor when kvar limit is exceeded and PF Priority is true. Temp PF is calculated based on kvarRequested + // PF Priority is not valid if controlled by an InvControl operating in at least one amongst VV and DRC modes + } + else + { + if(with0.PF_Priority && (!FVVMode || !FDRCMode || !FWVMode)) + { + if(Abs( with0.kvarRequested) > 0.0) + { + TempPF = cos(atan(Abs( (Get_kvarRequested() / kW_out)))); + kW_out = Abs( kvar_out) * sqrt(1.0 / (1.0L - Sqr(TempPF)) - 1.0) * Sign(kW_out); + } + } + } + } + else + kvar_out = Get_kvarRequested(); + } + } + } + } + if((FInverterON == false) && (FVarFollowInverter == true)) + kvar_out = 0.0; + + // Limit kvar and kW so that kVA of inverter is not exceeded + kVA_Gen = sqrt(Sqr(kW_out) + Sqr(kvar_out)); + if(kVA_Gen > with0.FkVArating) + { + kVA_exceeded = true; + + // Expectional case: When kVA is exceeded and in idling state, we force P priority always + if(fState == STORE_IDLING) + { + kvar_out = sqrt(Sqr(with0.FkVArating) - Sqr(kW_out)) * Sign(kvar_out); + + // Regular Cases + } + else + { + if((Get_Varmode() == VARMODEPF) && with0.PF_Priority) + // Operates under constant power factor when kVA rating is exceeded. PF must be specified and PFPriority must be TRUE + { + kW_out = with0.FkVArating * Abs( PFNominal) * Sign(kW_out); + kvar_out = with0.FkVArating * sqrt(1.0L - Sqr(PFNominal)) * Sign(kW_out) * Sign(PFNominal); + } + else + { + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && FWPMode) + { + kW_out = with0.FkVArating * Abs(Fpf_wp_nominal) * Sign(kW_out); + kvar_out = with0.FkVArating * Abs( sin(acos(Fpf_wp_nominal))) * Sign(Get_kvarRequested()); + } + else + { + if((Get_Varmode() == VARMODEKVAR) && with0.PF_Priority && (!FVVMode || !FDRCMode || !FWVMode)) + // Operates under constant power factor (PF implicitly calculated based on kw and kvar) + { + if(Abs( kvar_out) == with0.Fkvarlimit) // for handling cases when kvar limit and inverter's kVA limit are exceeded + { + kW_out = with0.FkVArating * Abs( TempPF) * Sign(kW_out); // Temp PF has already been calculated at this point + } + else + { + kW_out = with0.FkVArating * Abs( cos(atan(with0.kvarRequested / kW_out))) * Sign(kW_out); + } + kvar_out = with0.FkVArating * Abs( sin(acos(kW_out / with0.FkVArating))) * Sign(Get_kvarRequested()); + } + else + { + if(with0.P_Priority) // back off the kvar + { + if(kW_out > with0.FkVArating) + { + kW_out = with0.FkVArating; + kvar_out = 0.0; + } + else + kvar_out = sqrt(Sqr(with0.FkVArating) - Sqr(kW_out)) * Sign(kvar_out); + } + else + kW_out = sqrt(Sqr(with0.FkVArating) - Sqr(kvar_out)) * Sign(kW_out); // Q Priority (Default) back off the kW + } + } + } /*With StorageVars*/ + } + } + else + { + if(double(Abs( (kVA_Gen - with0.FkVArating))) / with0.FkVArating < 0.0005) + kVA_exceeded = true; + else + kVA_exceeded = false; + } + } +} +//---------------------------------------------------------------------------- + +void TStorageObj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->IsHarmonicModel) /*IsDynamicModel or*/ + /*Yeq is computed from %R and %X -- inverse of Rthev + j Xthev*/ + { + int stop = 0; + Y = Yeq; // L-N value computed in initial condition routines + if(Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; + Yij = cnegate(Y); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(Fnconds, Fnconds, Y); + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(i, i, Y); // put it in again + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + else + // Regular power flow Storage element model + + /*Yeq is always expected as the equivalent line-neutral admittance*/ + { + switch(fState) + { + case STORE_CHARGING: Y = YeqDischarge; + break; + case STORE_IDLING: Y = cmplx(0.0, 0.0); + break; + case STORE_DISCHARGING: + { + if (!GFM_Mode) + Y = cnegate(YeqDischarge); + else + { + myDynVars.RatedkVLL = Get_PresentkV(); + myDynVars.Discharging = ( get_fState() == 1); + myDynVars.mKVARating = StorageVars.FkVArating; + myDynVars.CalcGFMYprim(ActorID, Get_NPhases(), Ymatrix); + } + } + break; + default: + ; + break; + } + + //---DEBUG--- WriteDLLDebugFile(Format('t=%.8g, Change To State=%s, Y=%.8g +j %.8g',[ActiveCircuit[ActiveActor].Solution.dblHour, StateToStr, Y.re, Y.im])); + + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + if (!GFM_Mode) + { + switch (Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + with1->AddElement(Fnconds, Fnconds, Y); + with1->SetElemsym(i, Fnconds, Yij); + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } + } /*ELSE IF Solution.mode*/ +} + +//---------------------------------------------------------------------------- + +// Normalize time to a floating point number representing time of day If Hour > 24 +// time should be 0 to 24. + +double TStorageObj::NormalizeToTOD(int h, double Sec) +{ + double result = 0.0; + int HourOfDay = 0; + if(h > 23) + HourOfDay = (h - ((int)(h / 24)) * 24); + else + HourOfDay = h; + result = HourOfDay + Sec / 3600.0; + if(result > 24.0) + result = result - 24.0; // Wrap around + return result; +} + +//---------------------------------------------------------------------------- + +/*This is where we set the state of the Storage element*/ + +void TStorageObj::CheckStateTriggerLevel(double Level, int ActorID) +{ + int OldState = 0; + FStateChanged = false; + OldState = fState; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + if(DispatchMode == STORE_FOLLOW) + + // set charge and discharge modes based on sign of loadshape + { + if(Level > 0.0 && (with0.kWhStored - with0.kWhReserve) > EPSILON) + Set_StorageState(STORE_DISCHARGING); + else if(Level < 0.0 && (with0.kWhStored - with0.kWhRating) < -EPSILON) + Set_StorageState(STORE_CHARGING); + else + Set_StorageState(STORE_IDLING); + } + else + // All other dispatch modes Just compare to trigger value + { + if((ChargeTrigger == 0.0) && (DischargeTrigger == 0.0)) + return; + + // First see If we want to turn off Charging or Discharging State + switch(fState) + { + case STORE_CHARGING: + if(ChargeTrigger != 0.0) + { + if((ChargeTrigger < Level) || (with0.kWhStored >= with0.kWhRating)) + fState = STORE_IDLING; + } + break; + case STORE_DISCHARGING: + if(DischargeTrigger != 0.0) + { + if((DischargeTrigger > Level) || (with0.kWhStored <= with0.kWhReserve)) + fState = STORE_IDLING; + } + break; + default: + ; + break; + } + + // Now check to see If we want to turn on the opposite state + switch(fState) + { + case STORE_IDLING: + { + if((DischargeTrigger != 0.0) && (DischargeTrigger < Level) && (with0.kWhStored > with0.kWhReserve)) + fState = STORE_DISCHARGING; + else + { + if((ChargeTrigger != 0.0) && (ChargeTrigger > Level) && (with0.kWhStored < with0.kWhRating)) + fState = STORE_CHARGING; + + // Check to see If it is time to turn the charge cycle on If it is not already on. + } + if(!(fState == STORE_CHARGING)) + { + if(ChargeTime > 0.0) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + if(Abs( (NormalizeToTOD(with1->DynaVars.intHour, with1->DynaVars.T) - ChargeTime)) < with1->DynaVars.h / 3600.0) + fState = STORE_CHARGING; + } + } + } + break; + default: + ; + break; + } + } + } + if(OldState != fState) + { + FStateChanged = true; + Set_YprimInvalid(ActorID,true); + } +} + +//---------------------------------------------------------------------------- + +void TStorageObj::CalcYPrim(int ActorID) +{ + int i = 0; + + // Build only shunt Yprim + // Build a dummy Yprim Series so that CalcV Does not fail + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + SetNominalStorageOutput(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages Doesn't fail + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors + inherited::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + /*Add the current into the proper location according to connection*/ + + /*Reverse of similar routine in load (Cnegates are switched)*/ + +void TStorageObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum(TermArray[i - 1], Curr); + caccum(TermArray[Fnconds - 1], cnegate(Curr)); // Neutral + } + break; //DELTA + case 1: + { + caccum(TermArray[i - 1], Curr); + j = i + 1; + if(j > Fnconds) + j = 1; + caccum(TermArray[j - 1], cnegate(Curr)); + } + break; + default: + ; + break; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TStorageObj::WriteTraceRecord(const String s, int ActorID) +{ + int i = 0; + try + { + if(!InShowResults) + { + int stop = 0; + Append(Tracefile); + IOResultToException(); + { Write(Tracefile, Format("%-.g, %d, %-.g, ", + ActiveCircuit[ActorID]->Solution->DynaVars.dblHour, + ActiveCircuit[ActorID]->Solution->Iteration, + ActiveCircuit[ActorID]->get_FLoadMultiplier())); + Write(Tracefile, GetSolutionModeID()); + Write(Tracefile, ", "); + Write(Tracefile, GetLoadModel()); + Write(Tracefile, ", "); + Write(Tracefile, VoltageModel, 0); + Write(Tracefile, ", "); + Write(Tracefile, (Qnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile, ", "); + Write(Tracefile, (Pnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile, ", "); + Write(Tracefile, s); + Write(Tracefile, ", "); + } + + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((InjCurrent)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Iterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Vterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = NumVariables(), i = 1; i <= stop; i++) + { + Write(Tracefile, Format("%-.g, ", Get_Variable(i))); + } + + + //**** Write(TraceFile,VThevMag:8:1 ,', ', StoreVARs.Theta*180.0/PI); + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + catch (...) + { + } +} +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for Constant PQ*/ + +void TStorageObj::DoConstantPQStorageObj(int ActorID) +{ + int i = 0; +// CurrIdlingZ, + complex Curr = CZero; + complex VLN = CZero; + complex VLL = CZero; + //---DEBUG--- S:Complex; + double VmagLN = 0.0; + double VmagLL = 0.0; + complex V012[4] = { CZero, CZero, CZero, CZero, }; // Sequence voltages + + + auto with0 = ActiveCircuit[ActorID]->Solution; + //Treat this just like the Load model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + ZeroITerminal(); + + //---DEBUG--- WriteDLLDebugFile(Format('t=%.8g, State=%s, Iyprim= %s', [ActiveCircuit[ActiveActor].Solution.dblHour, StateToStr, CmplxArrayToString(InjCurrent, Yprim.Order) ])); + +// CASE FState of +// STORE_IDLING: // YPrim current is only current +// Begin +// For i := 1 to FNPhases Do +// Begin +// Curr := InjCurrent^[i]; +// StickCurrInTerminalArray(ITerminal, Curr, i); // Put YPrim contribution into Terminal array taking into account connection +// set_ITerminalUpdated(True, ActorID); +// StickCurrInTerminalArray(InjCurrent, Cnegate(Curr), i); // Compensation current is zero since terminal current is same as Yprim contribution +// //---DEBUG--- S := Cmul(Vterminal^[i] , Conjg(Iterminal^[i])); // for debugging below +// //---DEBUG--- WriteDLLDebugFile(Format(' Phase=%d, Pnom=%.8g +j %.8g',[i, S.re, S.im ])); +// End; +// //---DEBUG--- WriteDLLDebugFile(Format(' Icomp=%s ', [CmplxArrayToString(InjCurrent, Yprim.Order) ])); +// End; +// ELSE // For Charging and Discharging + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: /*Wye*/ + { + VLN = (Vterminal)[i - 1]; + VmagLN = cabs(VLN); + if(VmagLN <= VBase95) // Below 95% use an impedance model + Curr = cmul(Yeq95, VLN); + else + { + if(VmagLN > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, VLN); + else + Curr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLN)); // Between 95% -105%, constant PQ + } + if(CurrentLimited) + { + if(cabs(Curr) > MaxDynPhaseCurrent) + Curr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLN, VmagLN))); + } + } + break; /*Delta*/ + case 1: + { + VLL = (Vterminal)[i - 1]; + VmagLL = cabs(VLL); + if(Fnphases > 1) + VmagLN = VmagLL / SQRT3; + else + VmagLN = VmagLL; // L-N magnitude + if(VmagLN <= VBase95) // Below 95% use an impedance model + Curr = cmul(cdivreal(Yeq95, 3.0), VLL); + else + { + if(VmagLN > VBase105) // above 105% use an impedance model + Curr = cmul(cdivreal(Yeq105, 3.0), VLL); + else + Curr = conjg(cdiv(cmplx(Pnominalperphase, Qnominalperphase), VLL)); // Between 95% -105%, constant PQ + } + if(CurrentLimited) + { + if(cabs(Curr) * SQRT3 > MaxDynPhaseCurrent) + Curr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLN))); // Note VmagLN has sqrt3 factor in it + } + } + break; + default: + ; + break; + } + + //---DEBUG--- WriteDLLDebugFile(Format(' Phase=%d, Pnom=%.8g +j %.8g', [i, Pnominalperphase, Qnominalperphase ])); + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + + if (with0->Algorithm == NCIMSOLVE) // NCIM solution algorithms + DoPQBusNCIM(ActorID, i, Vterminal[i - 1], Curr); + + } + //---DEBUG--- WriteDLLDebugFile(Format(' Icomp=%s ', [CmplxArrayToString(InjCurrent, Yprim.Order) ])); +// END; +} + +// ----------------------------------------------------------------------------------- +// Updates the Jacobian matrix diagonal and calculates the Amps delta using deltaF +void TStorageObj::DoPQBusNCIM(int ActorID, int i, complex V, complex Curr) +{ + complex Pow = {}, + FaVr = {}, + FaVm = {}, + Temp = {}, + Vc2 = {}; + + int LCoords[4][2] = { {0,0}, {1,1}, {0,1}, {1,0} }; + int GCoord = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + Pow = conjg(cmplx(-Pnominalperphase, -Qnominalperphase)); + Vc2 = cmul(conjg(V), conjg(V)); + FaVr = cdiv(cmplx(-1, 0), Vc2); + FaVm = cdiv(cmplx(0, 1), Vc2); + GCoord = (NodeRef[i - 1] * 2) - 1; + // Updates the Jacobian + for (int j = 0; j < 4; j++) + { + // Add the derivatives + switch (j) + { + case 0: // dImdVr + Temp.re = cmul(FaVr, Pow).im; + break; + case 1: // dIrdVm + Temp.re = cmul(FaVm, Pow).re; + break; + case 2: // dImdVm + Temp.re = cmul(FaVm, Pow).im; + break; + case 3: // dIrdVr + Temp.re = cmul(FaVr, Pow).re; + break; + default: + break; + } + SetMatrixElement(with0->Jacobian, GCoord + LCoords[j][0], GCoord + LCoords[j][1], &Temp); + } + + // Add current injection contributions to deltaF + GCoord--; // Removes the additional index added by DSS + Iterminal[i - 1] = Curr; + with0->deltaF[GCoord].re = Curr.im + with0->deltaF[GCoord].re; // Respecting the decoupled distribution + with0->deltaF[GCoord + 1].re = Curr.re + with0->deltaF[GCoord + 1].re; // Prioritizing reactive power over the diagonal +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*constant Z model*/ + +void TStorageObj::DoConstantZStorageObj(int ActorID) +{ + int i = 0; + complex Curr = CZero, + YEQ2 = CZero; + complex V012[4] = { CZero, CZero, CZero, CZero, }; // Sequence voltages + + auto with0 = ActiveCircuit[ActorID]->Solution; + +// Assume Yeq is kept up to date + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + if(Connection == 0) + YEQ2 = Yeq; + else + YEQ2 = cdivreal(Yeq, 3.0); + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmul(YEQ2, (Vterminal)[i - 1]); // Yeq is always line to neutral + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + + if (with0->Algorithm == NCIMSOLVE) // NCIM solution algorithms + DoPQBusNCIM(ActorID, i, Vterminal[i - 1], Curr); + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal Current from User-written model*/ + +void TStorageObj::DoUserModel(int ActorID) +{ + int i = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + if(UserModel->Get_Exists()) // Check automatically selects the usermodel If true + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); + set_ITerminalUpdated(true, ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; // Negate currents from user model for power flow Storage element model + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum(InjCurrent[i - 1], cnegate(Iterminal[i - 1])); + } + } + } + else + { + DoSimpleMsg(String("Storage.") + get_Name() + + " model designated to use user-written model, but user-written model is not defined.", 567); + } +} + + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Total Current and add into InjTemp*/ +/* + For now, just assume the Storage element Thevenin voltage is constant + for the duration of the dynamic simulation. +*/ +/******/ + +void TStorageObj::DoDynamicMode(int ActorID) +{ + int i = 0; + polar PolarN = topolar(0,0); + complex Curr = cmplx(0,0), + NeutAmps = cmplx(0,0); + complex V012[3/*# range 0..2*/] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + complex I012[3/*# range 0..2*/] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + double AngCmp = 0, + iActual = 0; + + auto CalcVthev_Dyn = [&]() -> void + { + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + with0.Vthev = pclx(with0.VthevMag, with0.Theta); + } // keeps theta constant + }; + +/******/ // Test using DESS model + // Compute Vterminal + if(DynaModel->Get_Exists()) // do user-written model + DoDynaModel(ActorID); + else + { + if (!GFM_Mode) + { + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + ZeroITerminal(); + //{This model has no limitation in the nmber of phasesand is ideally unbalanced(no dq - dv, but is implementable as well)} + // First, get the phase angles for the currents + NeutAmps = cmplx(0, 0); + for (i = 1; i <= Fnphases; i++) + { + auto& with0 = myDynVars; + AngCmp = 0; + if (with0.it[i - 1] <= with0.iMaxPPhase) + iActual = with0.it[i - 1]; + else + iActual = with0.iMaxPPhase; + //----------------------------------------------------------- + if (iActual < with0.MinAmps) + iActual = 0; + if (fState != 1) + iActual = (PIdling / with0.Vgrid[i - 1].mag) / Get_NPhases(); + PolarN = topolar(iActual, with0.Vgrid[i - 1].ang + AngCmp); // Output Current estimated for active power + Curr = cnegate(ptocomplex(PolarN)); + NeutAmps = csub(NeutAmps, Curr); + Iterminal[i - 1] = Curr; + } + if (Fnconds > Fnphases) + Iterminal[Fnconds - 1] = NeutAmps; + //{Add it into inj current array} + for (i = 1; i <= Fnconds; i++) + caccum(InjCurrent[i - 1], cnegate(Iterminal[i - 1])); + set_ITerminalUpdated(true, ActorID); + } + else + { + myDynVars.BaseV = myDynVars.BasekV * 1000 * (myDynVars.it[0] / myDynVars.iMaxPPhase); + myDynVars.CalcGFMVoltage( ActorID, Get_NPhases(), &(Vterminal[0])); // needs to be referenced as 0 + YPrim->MVmult(InjCurrent, &(Vterminal[0])); // needs to be referenced as 1 + } + } +} +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Returns True if any of the inverter phases has reached the current limit +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +bool TStorageObj::CheckAmpsLimit(int ActorID) +{ + complex myCurr; + double myVolts; + double NomP; + double PhaseP; + double PhaseAmps; + int i; + // Check if reaching saturation point in GFM + bool result = false; + NomP = myDynVars.ILimit * VBase; + if (GFM_Mode) + { + GetCurrents(&Iterminal[0], ActorID); + myDynVars.IComp = 0.0; + for (i = 1; i <= Fnphases; i++) + { + myCurr = Iterminal[i - 1]; + PhaseAmps = cabs(myCurr); + myVolts = ctopolar(ActiveCircuit[ActorID]->Solution->NodeV[NodeRef[i - 1]]).mag; + PhaseP = PhaseAmps * myVolts; + if (PhaseP > NomP) + { + if (PhaseP > myDynVars.IComp) + myDynVars.IComp = PhaseP; + result = true; + } + } + } + return result; +} +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Implements the grid forming inverter control routine for the storage device +void TStorageObj::DoGFM_Mode(int ActorID) +{ + int j = 0, + i = 0; + double myW = 0, + ZSys = 0; + + auto& with0 = ActiveCircuit[ActorID]->Solution; + + myDynVars.BaseV = VBase; + myDynVars.Discharging = (get_fState() == STORE_DISCHARGING); + if (myDynVars.IComp > 0) + { + ZSys = (2 * (VBase * myDynVars.ILimit)) - myDynVars.IComp; + myDynVars.BaseV = (ZSys / myDynVars.ILimit) * myDynVars.VError; + } + myDynVars.CalcGFMVoltage(ActorID, Get_NPhases(), &(Vterminal[0])); + YPrim->MVmult(InjCurrent, &(Vterminal[0])); + + set_ITerminalUpdated(false, ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TStorageObj::DoDynaModel(int ActorID) +{ + complex DESSCurr[6/*# range 1..6*/]; // Temporary buffer + int i = 0; + int j = 0; +// do user written dynamics model + int stop = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; // Just pass node voltages to ground and let dynamic model take care of it + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (Vterminal)[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + (Vterminal)[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + StorageVars.w_grid = TwoPi * with0->get_FFrequency(); + } + DynaModel->FCalc(&(Vterminal[0]), (pComplexArray)&DESSCurr); + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(DESSCurr[i - 1]), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, DESSCurr[i - 1], i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TStorageObj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double StorageHarmonic = 0.0; + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + StorageHarmonic = with0->get_FFrequency() / StorageFundamental; + if(SpectrumObj != nullptr) // Get base harmonic magnitude + e = cmulreal(SpectrumObj->GetMult(StorageHarmonic), StorageVars.VThevHarm); + else + e = CZero; + RotatePhasorRad(e, StorageHarmonic, StorageVars.ThetaHarm); // Time shift by fundamental frequency phase shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, StorageHarmonic, -120.0); // Assume 3-phase Storage element + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TStorageObj::CalcVTerminalPhase(int ActorID) +{ + int i = 0; + int j = 0; + +/* Establish phase voltages and stick in Vterminal*/ + switch(Connection) + { + case 0: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Vterminal[i - 1] = with0->VDiff(NodeRef[i - 1], NodeRef[Fnconds - 1], ActorID); + } + } + } + break; + case 1: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; + (Vterminal)[i - 1] = with1->VDiff(NodeRef[i - 1], NodeRef[j - 1], ActorID); + } + } + } + break; + default: + ; + break; + } + StorageSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +/* +PROCEDURE TStorageObj.CalcVTerminal; +{Put terminal voltages in an array} +Begin + ComputeVTerminal; + StorageSolutionCount := ActiveCircuit[ActiveActor].Solution.SolutionCount; +End; +*/ + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Calculates Storage element current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TStorageObj::CalcStorageModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + // compute currents and put into InjTemp array; + { + if (GFM_Mode) DoGFM_Mode(ActorID); + else + switch(VoltageModel) + { + case 1: DoConstantPQStorageObj(ActorID); + break; + case 2: DoConstantZStorageObj(ActorID); + break; + case 3: DoUserModel(ActorID); + break; + default: DoConstantPQStorageObj(ActorID); // for now, until we implement the other models. + break; + } + } /*ELSE*/ + } + } /*WITH*/ + + /*When this is Done, ITerminal is up to date*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Difference between currents in YPrim and total current + +void TStorageObj::CalcInjCurrentArray(int ActorID) +{ + + // Now Get Injection Currents + if(StorageObjSwitchOpen) + ZeroInjCurrent(); + else + CalcStorageModelContribution(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Compute total Currents + +void TStorageObj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + { + if(!StorageObjSwitchOpen) + CalcStorageModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); + } + if(DebugTrace) + WriteTraceRecord("TotalCurrent", ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +int TStorageObj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->LoadsNeedUpdating) + SetNominalStorageOutput(ActorID); // Set the nominal kW, etc for the type of solution being Done + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + if(DebugTrace) + WriteTraceRecord("Injection", ActorID); + + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Required for operation in GFM mode +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +void TStorageObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + if (GFM_Mode) + { + try + { + auto& with0 = ActiveCircuit[ActorID]->Solution; + for (i = 1; i <= Yorder; i++) + { + if (!ADiakoptics || (ActorID == 1)) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + YPrim->MVmult(Curr, &Vterminal[0]); // Current from Elements in System Y + // Add Together with yprim currents + for (i = 1; i <= Yorder; i++) + Curr[i - 1] = csub(Curr[i - 1], InjCurrent[i - 1]); + } + catch (const std::exception &e) + { + DoErrorMsg(String("GetCurrents for Element: \"") + get_Name(), (std::string)e.what(), "Inadequate storage allotted for circuit element.", 327); + } + } + else + inherited::GetCurrents(Curr, ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Returns True if any of the inverter phases is overloaded +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +bool TStorageObj::CheckOLInverter(int ActorID) +{ + complex myCurr = cmplx(0,0); + double MaxAmps = 0, + PhaseAmps = 0; + int i = 0; + bool result = false; + + if (GFM_Mode) + { + MaxAmps = ( ( StorageVars.FkVArating * 1000 ) / Get_NPhases() ) / VBase; + GetCurrents( &( Iterminal[0] ), ActorID ); + for (i = 1; i <= Get_NPhases(); i++) + { + myCurr = Iterminal[i - 1]; + PhaseAmps = cabs( myCurr ); + if (PhaseAmps > MaxAmps) + { + result = true; + break; + } + } + } + + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Gives the currents for the last solution performed + +// Do not call SetNominalLoad, as that may change the load values + +void TStorageObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("Storage Object: \"") + get_Name() + "\" in GetInjCurrents FUNCTION.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorageObj::ResetRegisters() +{ + int i = 0; + int stop = 0; + for(stop = NumStorageRegisters, i = 1; i <= stop; i++) + { + Registers[i - 1] = 0.0; + } + for(stop = NumStorageRegisters, i = 1; i <= stop; i++) + { + Derivatives[i - 1] = 0.0; + } + FirstSampleAfterReset = true; // initialize for trapezoidal integration +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TStorageObj::Integrate(int reg, double Deriv, double Interval, int ActorID) +{ + if(ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + Registers[reg] = Registers[reg] + 0.5 * Interval * (Deriv + Derivatives[reg]); + } + else + /*Plain Euler integration*/ + Registers[reg] = Registers[reg] + Interval * Deriv; + Derivatives[reg] = Deriv; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Update Energy from metered zone + +void TStorageObj::TakeSample(int ActorID) +{ + complex s = {}; + double Smag = 0.0; + double HourValue = 0.0; + +// Compute energy in Storage element branch + if(Get_Enabled()) + + // Only tabulate discharge hours + { + if(fState == STORE_DISCHARGING) + { + s = cmplx(Get_PresentkW(), Get_Presentkvar()); + Smag = cabs(s); + HourValue = 1.0; + } + else + { + s = CZero; + Smag = 0.0; + HourValue = 0.0; + } + if((fState == STORE_DISCHARGING) || ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + /*Make sure we always integrate for Trapezoidal case + Don't need to for Gen Off and normal integration*/ + if(ActiveCircuit[ActorID]->PositiveSequence) + { + s = cmulreal(s, 3.0); + Smag = 3.0 * Smag; + } + Integrate(Reg_kWh, s.re, with0->IntervalHrs, ActorID); // Accumulate the power + Integrate(Reg_kvarh, s.im, with0->IntervalHrs, ActorID); + SetDragHandRegister(Reg_MaxkW, Abs( s.re)); + SetDragHandRegister(Reg_MaxkVA, Smag); + Integrate(Reg_Hours, HourValue, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + Integrate(Reg_Price, s.re * ActiveCircuit[ActorID]->PriceSignal * 0.001, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + FirstSampleAfterReset = false; + } + } +} + +//--------------------------------------------------------------------------- +// Checks if delivering or abosrbing power in GFM control mode +//--------------------------------------------------------------------------- +bool TStorageObj::CheckIfDelivering(int ActorID) +{ + int i = 0; + bool result = false; + std::vector myVolt, myCurr; + + // If in GFM mode, check if we are actually delivering power + ComputeIterminal(ActorID); + myVolt.resize(Get_NPhases() + 1); + myCurr.resize(Get_NPhases() + 1); + for (i = 1; i <= Get_NPhases(); i++) + { + myCurr[i] = Iterminal[i - 1]; + myVolt[i] = ActiveCircuit[ActorID]->Solution->NodeV[NodeRef[i - 1]]; + CalcKPowers(&(myVolt[i]), &(myVolt[i]), &(myCurr[i]), 1); + result = ( myVolt[i].re < 0 ) || result; + } + + return result; +} + +//---------------------------------------------------------------------------- + +/*Update Storage levels*/ + +void TStorageObj::UpdateStorage(int ActorID) +{ + bool UpdateSt = false; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + kWhBeforeUpdate = with0.kWhStored; // keep this for reporting change in Storage as a variable + + /*Assume User model will take care of updating Storage in dynamics mode*/ + if(ActiveCircuit[ActorID]->Solution->IsDynamicModel && IsUserModel) + return; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + switch(fState) + { + case STORE_DISCHARGING: + { + UpdateSt = true; + if (GFM_Mode) UpdateSt = CheckIfDelivering(ActorID); + + if (UpdateSt) + with0.kWhStored = with0.kWhStored - (Get_DCkW() + Get_kWIdlingLosses()) / with0.DisChargeEff * with1->IntervalHrs; + else + { // We are obsrobing power, let's recharge if needed + with0.kWhStored = with0.kWhStored + (Get_DCkW() + Get_kWIdlingLosses()) / with0.DisChargeEff * with1->IntervalHrs; + if (with0.kWhStored > with0.kWhRating) with0.kWhStored = with0.kWhRating; + } + if(with0.kWhStored < with0.kWhReserve) + { + with0.kWhStored = with0.kWhReserve; + fState = STORE_IDLING; // It's empty Turn it off + FStateChanged = true; + GFM_Mode = false; + } + } + break; + case STORE_CHARGING: + { + if((Abs(Get_DCkW()) - Get_kWIdlingLosses()) >= 0) // 99.9 % of the cases will fall here + { + with0.kWhStored = with0.kWhStored + (Abs(Get_DCkW()) - Get_kWIdlingLosses()) * with0.ChargeEff * with1->IntervalHrs; + if(with0.kWhStored > with0.kWhRating) + { + with0.kWhStored = with0.kWhRating; + fState = STORE_IDLING; // It's full Turn it off + FStateChanged = true; + GFM_Mode = 0; + } + } + else + // Exceptional cases when the idling losses are higher than the Get_DCkW() such that the net effect is that the + // the ideal Storage will discharge + { + with0.kWhStored = with0.kWhStored + (Abs(Get_DCkW()) - Get_kWIdlingLosses()) / with0.DisChargeEff * with1->IntervalHrs; + if(with0.kWhStored < with0.kWhReserve) + { + with0.kWhStored = with0.kWhReserve; + fState = STORE_IDLING; // It's empty Turn it off + FStateChanged = true; + } + } + } + break; + case STORE_IDLING: + ; + break; + default: + ; + break; + } + } + } + + // the update is done at the end of a time step so have to force + // a recalc of the Yprim for the next time step. Else it will stay the same. + if(FStateChanged) + Set_YprimInvalid(ActorID,true); +} + +//---------------------------------------------------------------------------- + +// Computes actual DCkW to Update Storage SOC + +void TStorageObj::ComputeDCkW() +{ + TCoeff coefGuess = {0,0}; + TCoeff coef = { 0,0 }; + int N_tentatives = 0; + coefGuess[0] = 0.0; + coefGuess[1] = 0.0; + coef[0] = 1.0; + coef[1] = 1.0; // just a guess + FDCkW = Get_Power(1, ActiveActor).re * 0.001; // Assume ideal inverter + if(InverterCurveObj == nullptr) + // make sure sign is correct + { + if(fState == STORE_IDLING) + FDCkW = Abs(FDCkW) * - 1; + else + FDCkW = Abs(FDCkW) * fState; + return; + } + N_tentatives = 0; + while((coef[0] != coefGuess[0]) && (coef[1] != coefGuess[1]) || (N_tentatives > 9)) + { + N_tentatives = N_tentatives + 1; + coefGuess = InverterCurveObj->GetCoefficients(Abs(FDCkW) / StorageVars.FkVArating); + switch(fState) + { + case STORE_DISCHARGING: + FDCkW = QuadSolver(coefGuess[0] / StorageVars.FkVArating, coefGuess[1], -1.0 * Abs( (Get_Power(1, ActiveActor).re * 0.001))); + break; + case STORE_CHARGING: + case STORE_IDLING: + FDCkW = Abs(FDCkW) * coefGuess[1] / (1.0L - (coefGuess[0] * Abs(FDCkW) / StorageVars.FkVArating)); + break; + default: + ; + break; + } + + // Final coefficients + coef = InverterCurveObj->GetCoefficients(Abs(FDCkW) / StorageVars.FkVArating); + } + + // make sure sign is correct + if(fState == STORE_IDLING) + FDCkW = Abs(FDCkW) * - 1; + else + FDCkW = Abs(FDCkW) * fState; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_PresentkW() +{ + double result = 0.0; + result = Pnominalperphase * 0.001 * Fnphases; + return result; +} + +//---------------------------------------------------------------------------- +/* +double TStorageObj::Get_DCkW() +{ + double result = 0.0; + ComputeDCkW; + result = FDCkW; + return result; +}*/ + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kWDesired() +{ + double result = 0.0; + switch(FStateDesired) + { + case STORE_CHARGING: + result = -Get_FpctkWIn() * StorageVars.kWrating / 100.0; + break; + case STORE_DISCHARGING: + result = get_FpctkWout() * StorageVars.kWrating / 100.0; + break; + case STORE_IDLING: + result = 0.0; + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_StateDesired(int i) +{ + FStateDesired = i; +} + +//----------------------------------------------------------------------------- + +double TStorageObj::Get_kWTotalLosses() +{ + double result = 0.0; + result = Get_kWIdlingLosses() + Get_InverterLosses() + Get_kWChDchLosses(); + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::get_PFNominal() +{ + return PFNominal; +} + +//---------------------------------------------------------------------------- + +int TStorageObj::get_fState() +{ + return fState; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::get_FpctkWout() +{ + return FpctkWout; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::get_Fpctkvarout() +{ + return Fpctkvarout; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::get_Vminpu() +{ + return Vminpu; +} + +//---------------------------------------------------------------------------- +/* +double TStorageObj::Get_InverterLosses() +{ + double result = 0.0; + result = 0.0; + //# with StorageVars do + { + auto with0 = StorageVars; + switch(get_fState()) + { + case STORE_IDLING: + result = Abs( (Power[1][ActiveActor].re * 0.001)) - Abs(Get_DCkW()); + break; + case STORE_CHARGING: + result = Abs( (Power[1][ActiveActor].re * 0.001)) - Abs(Get_DCkW()); + break; + case STORE_DISCHARGING: + result = Get_DCkW() - Abs( (Power[1][ActiveActor].re * 0.001)); + break; + default: + ; + break; + } + } + return result; +}*/ + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kWIdlingLosses() +{ + double result = 0.0; + if(fState == STORE_IDLING) + { + result = Abs(Get_DCkW()); // For consistency keeping with voltage variations + } + else + result = PIdling; + return result; +} + +//---------------------------------------------------------------------------- +/* +double TStorageObj::Get_kWChDchLosses() +{ + double result = 0.0; + result = 0.0; + //# with StorageVars do + { + auto with0 = StorageVars; + switch(get_fState()) + { + case STORE_IDLING: + result = 0.0; + break; + case STORE_CHARGING: + if(Abs(Get_DCkW()) - PIdling > 0) // most cases will fall here + result = (Abs(Get_DCkW()) - PIdling) * (1.0 - 0.01 * pctChargeEff); + else + result = -1 * (Abs(Get_DCkW()) - PIdling) * (1.0 / (0.01 * pctDischargeEff) - 1.0); + break; // exceptional cases when Pidling is higher than DCkW (net effect is that the ideal Storage will be discharged) + case STORE_DISCHARGING: + result = (Get_DCkW() + PIdling) * (1.0 / (0.01 * pctDischargeEff) - 1.0); + break; + default: + ; + break; + } + } + return result; +}*/ + +//---------------------------------------------------------------------------- + +void TStorageObj::Update_EfficiencyFactor() +{ + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + if(InverterCurveObj == nullptr) + with0.EffFactor = 1.0; + else + with0.EffFactor = InverterCurveObj->GetYValue_(double(Abs(Get_DCkW())) / with0.FkVArating); + } +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_PresentkV() +{ + double result = 0.0; + result = StorageVars.kVStorageBase; + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_Presentkvar() +{ + double result = 0.0; + result = Qnominalperphase * 0.001 * Fnphases; + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; + switch(Idx) + { + case propUSERDATA: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + case propDynaData: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + default: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + + +//---------------------------------------------------------------------------- + + +// This routine makes a thevenin equivalent behis the reactance spec'd in %R and %X + +void TStorageObj::InitHarmonics(int ActorID) +{ + int i = 0; + int j = 0; + complex e = {}; + complex Va = {}; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + StorageFundamental = ActiveCircuit[ActorID]->Solution->get_FFrequency(); // Whatever the frequency is when we enter here. + Yeq = cinv(cmplx(StorageVars.RThev, StorageVars.XThev)); // used for current calcs Always L-N + + /*Compute reference Thevenin voltage from phase 1 current*/ + ComputeIterminal(ActorID); // Get present value of current + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + switch(Connection) + { + case 0: /*wye - neutral is explicit*/ + { + if(!ADiakoptics || (ActorID == 1)) + Va = csub(with0->NodeV[NodeRef[0]], with0->NodeV[NodeRef[Fnconds - 1]]); + else + Va = csub(with0->VoltInActor1(NodeRef[0]), with0->VoltInActor1(NodeRef[Fnconds - 1])); + } + break; /*delta -- assume neutral is at zero*/ + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + Va = with0->NodeV[NodeRef[0]]; + else + Va = with0->VoltInActor1(NodeRef[0]); + } + break; + default: + ; + break; + } + } + e = csub(Va, cmul((Iterminal)[1 - 1], cmplx(StorageVars.RThev, StorageVars.XThev))); + StorageVars.VThevHarm = cabs(e); // establish base mag and angle + StorageVars.ThetaHarm = cang(e); +} + + +//---------------------------------------------------------------------------- + + +// for going into dynamics mode + +void TStorageObj::InitStateVars(int ActorID) +{ + //complex VNeut = cmplx(0,0); + //polar VThevPolar = topolar(0,0); + int i = 0; + int j = 0; + //complex V012[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + //complex I012[3] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0) }; + //complex Vabc[4] = { cmplx(0,0), cmplx(0,0) , cmplx(0,0), cmplx(0,0) }; + double BaseZt = 0; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + + if (PICtrl.empty() || (PICtrl.size() < Fnphases)) + { + PICtrl.resize(Fnphases); + for (i = 0; i < Fnphases; i++) + { + PICtrl[i] = TPICtrl(); + PICtrl[i].Kp = myDynVars.Kp; + PICtrl[i].kNum = 0.9502; + PICtrl[i].kDen = 0.04979; + } + } + + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + with0.Zthev = cmplx(with0.RThev, with0.XThev); + Yeq = cinv(with0.Zthev); // used to init state vars + } + if(DynaModel->Get_Exists()) // Checks existence and selects + { + ComputeIterminal(ActorID); + ComputeVterminal(ActorID); + /*# with StorageVars do */ + { + auto& with1 = StorageVars; + with1.NumPhases = Fnphases; + with1.NumConductors = Fnconds; + with1.w_grid = TwoPi * ActiveCircuit[ActorID]->Solution->get_FFrequency(); + } + DynaModel->FInit(&(Vterminal[0]), &(Iterminal[0])); + } + else if(fState == STORE_DISCHARGING) + { + auto with2 = ActiveCircuit[ActorID]->Solution; + auto& with3 = StorageVars; + auto& with4 = myDynVars; + + with3.NumPhases = Fnphases; + with3.NumConductors = Fnconds; + with3.Conn = Connection; + + with4.InitDynArrays(with3.NumPhases); + if (with3.NumPhases > 1) + with4.BasekV = Get_PresentkV() / sqrt(3); + else + with4.BasekV = Get_PresentkV(); + + with4.ResetIBR = false; + BaseZt = 0.01 * (sqr(Get_PresentkV()) / Get_FkVARating()) * 1000; + with4.MaxVS = (2 - (with4.SMThreshold / 100)) * with4.BasekV * 1000; + with4.MinVS = (with4.SMThreshold / 100) * with4.BasekV * 1000; + with4.MinAmps = (FpctCutOut / 100) * ((Get_FkVARating() / with4.BasekV) / with3.NumPhases); + with4.iMaxPPhase= (Get_FkVARating() / with4.BasekV) / with3.NumPhases; + + if (pctX == 0) + pctX = 50; + with3.XThev = pctX * BaseZt; + with4.RS = pctR * BaseZt; + with3.Zthev = cmplx(with4.RS, with3.XThev); + Yeq = cinv(with3.Zthev); + ComputePresentkW(); + with4.LS = with3.Zthev.im / (2 * PI * DefaultBaseFreq); + for (i = 0; i < Get_NPhases(); i++) + { + with4.Vgrid[i] = ctopolar(with2->NodeV[NodeRef[i]]); + with4.dit[i] = 0; + with4.it[i] = 0; + with4.m[i] = ((with4.RS * with4.it[i]) + with4.Vgrid[i].mag) / with4.RatedVDC; + if (with4.m[i] > 1) + with4.m[i] = 1; + with4.ISPDelta[i] = 0; + with4.AngDelta[i] = 0; + } + if (ASSIGNED(DynamicEqObj)) + for (i = 0; i < DynamicEqVals.size(); i++) + DynamicEqVals[i][1] = 0; + } +} + +//---------------------------------------------------------------------------- + + +// dynamics mode integration routine + +void TStorageObj::IntegrateStates(int ActorID) +{ + //complex TracePower = {}; + vector myCurr = {}; + int NumData = 0, + IPresent = 0, // Present amps per phase + j = 0, + i = 0; + double IMaxPhase = 0, + OFFVal = 0; + bool GFMUpdate = 0; + + // Compute Derivatives and Then integrate + ComputeIterminal(ActorID); + if(DynaModel->Get_Exists()) // Checks for existence and Selects + DynaModel->Integrate(); + else + { + auto wSol = ActiveCircuit[ActorID]->Solution; + auto& wSV = StorageVars; + auto& wDynV = myDynVars; + + ComputePresentkW(); + IMaxPhase = (kW_out / wDynV.BasekV) / wSV.NumPhases; + for (i = 0; i < wSV.NumPhases; i++) + { + if (fState == STORE_DISCHARGING) + { + auto& DynaVars = wSol->DynaVars; + if (DynaVars.IterationFlag == 0) //{ First iteration of new time step } + wDynV.itHistory[i] = wDynV.it[i] + 0.5 * DynaVars.h * wDynV.dit[i]; + + wDynV.Vgrid[i] = ctopolar(wSol->NodeV[NodeRef[i]]);// Voltage at the Inv terminals + if (!GFM_Mode) + { + if ((wDynV.Vgrid[i].mag < wDynV.MinVS) || (wDynV.Vgrid[i].mag > wDynV.MaxVS)) + { + wDynV.ISP = 0.01; // turn OFF the inverter + fState = STORE_IDLING; + if (wDynV.Vgrid[i].mag > wDynV.MaxVS) + wDynV.Vgrid[i].mag = wDynV.MaxVS; + } + else + wDynV.ISP = ((kW_out * 1000) / wDynV.Vgrid[i].mag) / wSV.NumPhases; + if (wDynV.ISP > wDynV.iMaxPPhase) + wDynV.ISP = wDynV.iMaxPPhase; + } + else + { + if (wDynV.ResetIBR) wDynV.VDelta[i] = ((0.001 - (wDynV.Vgrid[i].mag / 1000)) / wDynV.BasekV); + else wDynV.VDelta[i] = (wDynV.BasekV - (wDynV.Vgrid[i].mag / 1000)) / wDynV.BasekV; + + // Set true to update the IBR + GFMUpdate = 1; + + // Checks if there is current limit set + if (wDynV.ILimit > 0) + { + myCurr.resize(Fnphases); + GetCurrents(&(myCurr[0]), ActorID); + + for (int stop = Fnphases, j = 1; j <= stop; j++) + { + IPresent = ctopolar(myCurr[j - 1]).mag; + GFMUpdate = GFMUpdate && (IPresent < wDynV.ILimit * wDynV.VError); + } + } + + if (abs(wDynV.VDelta[i]) > wDynV.CtrlTol && GFMUpdate) + { + wDynV.ISPDelta[i] = wDynV.ISPDelta[i] + (IMaxPhase * wDynV.VDelta[i]) * wDynV.Kp * 100; + if (wDynV.ISPDelta[i] > wDynV.iMaxPPhase) wDynV.ISPDelta[i] = wDynV.iMaxPPhase; + else if (wDynV.ISPDelta[i] < 0) wDynV.ISPDelta[i] = 0.01; + } + wDynV.ISP = wDynV.ISPDelta[i]; + wDynV.FixPhaseAngle(ActorID, i); + } + if (ASSIGNED(DynamicEqObj)) // Loads values into dynamic expression if any + { + NumData = (int)(round((DynamicEqPair.size() / 2)) - 1); + DynamicEqVals[DynOut[0]][0] = wDynV.it[i]; // brings back the current values/phase + DynamicEqVals[DynOut[0]][1] = wDynV.dit[i]; + + for (j = 0; j <= NumData; j++) + { + if (!DynamicEqObj->IsInitVal(DynamicEqPair[(j * 2) + 1])) + { + switch (DynamicEqPair[ ( j * 2 ) + 1 ]) + { + case 2: + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.Vgrid[i].mag; // volt per phase + break; + case 4: // Nothing for this object (current) + break; + case 10: + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.RatedVDC; + break; + case 11: + wDynV.SolveModulation(i, ActorID, &PICtrl[i]); + DynamicEqVals[DynamicEqPair[j * 2]][0] = wDynV.m[i]; + break; + default: + DynamicEqVals[DynamicEqPair[j * 2]][0] = Get_PCEValue(1, DynamicEqPair[(j * 2) + 1], ActorID); + break; + } + } + } + DynamicEqObj->SolveEq(&DynamicEqVals); // solves the differential equation using the given dynamic expression + } + else + wDynV.SolveDynamicStep(i, ActorID, &PICtrl[i]); // Solves dynamic step for inverter + + // Trapezoidal method + if (ASSIGNED(DynamicEqObj)) wDynV.dit[i] = DynamicEqVals[DynOut[0]][1]; + wDynV.it[i] = wDynV.itHistory[i] + 0.5 * DynaVars.h * wDynV.dit[i]; + } + else + { + if(wDynV.Vgrid[i].mag >= wDynV.MinVS || wDynV.ResetIBR) + OFFVal = PIdling / wDynV.Vgrid[i].mag; // To match with idling losses + else + OFFVal = 0; + + wDynV.it[i] = OFFVal; + } + + // Write Dynamics Trace Record + if (DebugTrace) + { + Append(Tracefile); + IOResultToException(); + WriteLn(Tracefile, Format("t=%-.5g", wSol->DynaVars.T)); + WriteLn(Tracefile, Format("Flag=%d", wSol->DynaVars.IterationFlag)); + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + + + } +} + +//---------------------------------------------------------------------------- + +int TStorageObj::InterpretState(const String s) +{ + int result = 0; + switch(LowerCase(s)[0]) + { + case L'c': + result = STORE_CHARGING; + break; + case L'd': + result = STORE_DISCHARGING; + break; + default: + result = STORE_IDLING; + break; + } + return result; +} + +/* apparently for debugging only +//---------------------------------------------------------------------------- +Function TStorageObj.StateToStr:String; +Begin + CASE FState of + STORE_CHARGING: Result := 'Charging'; + STORE_IDLING: Result := 'Idling'; + STORE_DISCHARGING: Result := 'Discharging'; + END; +End; +*/ + +//---------------------------------------------------------------------------- + +/*Return variables one at a time*/ + +double TStorageObj::Get_Variable(int i) +{ + double result = 0.0; + int n = 0; + int k = 0; + result = -9999.99; // error return value; no state vars + if(i < 1) + return result; + // for now, report kWhstored and mode + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + switch(i) + { + case 1: + result = with0.kWhStored; + break; + case 2: + if(not GFM_Mode) + result = (double) fState; + else + { + if (CheckIfDelivering(ActiveActor)) + result = STORE_DISCHARGING; + else if (with0.kWhStored == with0.kWhRating) + result = STORE_IDLING; + else + result = STORE_CHARGING; + } + break; + case 3: + case 4: + { + bool A = GFM_Mode && CheckIfDelivering(ActiveActor); + bool B = (fState == STORE_DISCHARGING) && !(GFM_Mode); + A = A || B; + if (i == 4) A = !A; + if (A) + result = abs(Get_Power(1, ActiveActor).re * 0.001); + else + result = 0; + } + break; + case 5: + result = -1 * Get_Power(1,ActiveActor).im * 0.001; + break; + case 6: + result = Get_DCkW(); + break; + case 7: + result = Get_kWTotalLosses(); + break; /*Present kW charge or discharge loss incl idle losses*/ + case 8: + result = Get_InverterLosses(); + break; /*Inverter Losses*/ + case 9: + result = Get_kWIdlingLosses(); + break; /*Present kW Idling Loss*/ + case 10: + result = Get_kWChDchLosses(); + break; // Charge/Discharge Losses + case 11: + result = with0.kWhStored - kWhBeforeUpdate; + break; + case 12: + { + Update_EfficiencyFactor(); + result = with0.EffFactor; //Old: Result := Get_EfficiencyFactor; + } + break; + case 13: + if(FInverterON) + result = 1.0; + else + result = 0.0; + break; + case 14: + result = with0.Vreg; + break; + case 15: + result = with0.Vavg; + break; + case 16: + result = with0.VVOperation; + break; + case 17: + result = with0.VWOperation; + break; + case 18: + result = with0.DRCOperation; + break; + case 19: + result = with0.VVDRCOperation; + break; + case 20: + result = with0.WPOperation; + break; + case 21: + result = with0.WVOperation; + break; + case 22: + result = Get_kWDesired(); + break; + case 23: + if(!(Get_VWmode())) + result = 9999; + else + result = Get_kWRequested(); + break; + case 24: + result = Get_FpctkWrated() * with0.kWrating; + break; + case 25: + if(kVA_exceeded) + result = 1.0; + else + result = 0.0; + break; + default: + result = myDynVars.Get_InvDynValue(i - 26, Get_NPhases()); + + if(UserModel->Get_Exists()) // Checks for existence and Selects + { + n = UserModel->FNumVars(); + k = (i - NumStorageVariables); + if(k <= n) + { + result = UserModel->FGetVariable(k); + return result; + } + } + if(DynaModel->Get_Exists()) // Checks for existence and Selects + { + n = DynaModel->FNumVars(); + k = (i - NumStorageVariables); + if(k <= n) + { + result = DynaModel->FGetVariable(k); + return result; + } + } + break; + } + } + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_Variable(int i, double Value) +{ + int n = 0; + int k = 0; + if(i < 1) + return; // No variables to set + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + switch(i) + { + case 1: + with0.kWhStored = Value; + break; + case 2: + fState = Trunc(Value); + break; + case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: + case 13: + ; + break; /*Do Nothing; read only*/ + case 14: + with0.Vreg = Value; + break; + case 15: + with0.Vavg = Value; + break; + case 16: + with0.VVOperation = Value; + break; + case 17: + with0.VWOperation = Value; + break; + case 18: + with0.DRCOperation = Value; + break; + case 19: + with0.VVDRCOperation = Value; + break; + case 20: + with0.WPOperation = Value; + break; + case 21: + with0.WVOperation = Value; + break; + case 22: case 23: case 24: case 25: + ; + break; /*Do Nothing; read only*/ + default: + auto& with1 = myDynVars; // Dynamic state variable write + + with1.Set_InvDynValue(i - 26, Value); + + if(UserModel->Get_Exists()) // Checks for existence and Selects + { + n = UserModel->FNumVars(); + k = (i - NumStorageVariables); + if(k <= n) + { + UserModel->FSetVariable(k, Value); + return; + } + } + if(DynaModel->Get_Exists()) // Checks for existence and Selects + { + n = DynaModel->FNumVars(); + k = (i - NumStorageVariables); + if(k <= n) + { + DynaModel->FSetVariable(k, Value); + return; + } + } + break; + } + } +} + +//---------------------------------------------------------------------------- + +void TStorageObj::GetAllVariables(pDoubleArray States) +{ +/*, N*/ + int i = 0; + int stop = 0; + if (!ASSIGNED(DynamicEqObj)) + { + for (stop = NumStorageVariables, i = 1; i <= stop; i++) + States[i - 1] = Get_Variable(i); + } + else + { + for (i = 1; i <= (DynamicEqObj->get_FNumVars() * DynamicEqVals[0].size()); i++) + States[i - 1] = DynamicEqObj->Get_DynamicEqVal(i - 1, &DynamicEqVals); + } + + if (UserModel->Get_Exists()) // Checks for existence and Selects + /*N := UserModel.FNumVars;*/ + { + UserModel->FGetAllVars((pDoubleArray)&(States)[NumStorageVariables + 1 - 1]); + } + if(DynaModel->Get_Exists()) // Checks for existence and Selects + /*N := UserModel.FNumVars;*/ + { + DynaModel->FGetAllVars((pDoubleArray)&(States)[NumStorageVariables + 1 - 1]); + } +} + +//---------------------------------------------------------------------------- + +int TStorageObj::NumVariables() +{ + int result = 0; + result = NumStorageVariables; + + // Get_Exists() does a check and then does a Select + if(UserModel->Get_Exists()) + result = result + UserModel->FNumVars(); + if(DynaModel->Get_Exists()) + result = result + DynaModel->FNumVars(); + return result; +} + +//---------------------------------------------------------------------------- + +String TStorageObj::VariableName(int i) +{ + String result; + const int BuffSize = 255; + int n = 0; + int I2 = 0; + AnsiChar Buff[256/*# range 0..BuffSize*/]; + PAnsiChar PName = nullptr; + if(i < 1) + return result; // Someone goofed + switch(i) + { + case 1: + result = "kWh"; + break; + case 2: + result = "State"; + break; +// 3:Result := 'Pnom'; +// 4:Result := 'Qnom'; + case 3: + result = "kWOut"; + break; + case 4: + result = "kWIn"; + break; + case 5: + result = "kvarOut"; + break; + case 6: + result = "DCkW"; + break; + case 7: + result = "kWTotalLosses"; + break; + case 8: + result = "kWInvLosses"; + break; + case 9: + result = "kWIdlingLosses"; + break; + case 10: + result = "kWChDchLosses"; + break; + case 11: + result = "kWh Chng"; + break; + case 12: + result = "InvEff"; + break; + case 13: + result = "InverterON"; + break; + case 14: + result = "Vref"; + break; + case 15: + result = "Vavg (DRC)"; + break; + case 16: + result = "VV Oper"; + break; + case 17: + result = "VW Oper"; + break; + case 18: + result = "DRC Oper"; + break; + case 19: + result = "VV_DRC Oper"; + break; + case 20: + result = "WP Oper"; + break; + case 21: + result = "WV Oper"; + break; + case 22: + result = "kWDesired"; + break; + case 23: + result = "kW VW Limit"; + break; + case 24: + result = "Limit kWOut Function"; + break; + case 25: + result = "kVA Exceeded"; + break; + default: + result = myDynVars.Get_InvDynName(i - 26); + + if(UserModel->Get_Exists()) // Checks for existence and Selects + { + PName = (PAnsiChar) &Buff; + n = UserModel->FNumVars(); + I2 = i - NumStorageVariables; + if(I2 <= n) + { + UserModel->FGetVarName(I2, PName, (unsigned int) BuffSize); + result = PName; + return result; + } + } + if(DynaModel->Get_Exists()) // Checks for existence and Selects + { + PName = (PAnsiChar) &Buff; + n = DynaModel->FNumVars(); + I2 = i - NumStorageVariables; // Relative index + if(I2 <= n) + { + DynaModel->FGetVarName(I2, PName, (unsigned int) BuffSize); + result = PName; + return result; + } + } + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + s = "Phases=1 conn=wye"; + + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = StorageVars.kVStorageBase / SQRT3; + else + V = StorageVars.kVStorageBase; + s = s + Format(" kV=%-.5g", V); + if(Fnphases > 1) + { + s = s + + Format(" kWrating=%-.5g PF=%-.5g", StorageVars.kWrating / Fnphases, PFNominal); + } + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); // write out other properties +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + inherited::Set_ConductorClosed(Index, ActorID, Value); + + // Just turn Storage element on or off; + if(Value) + StorageObjSwitchOpen = false; + else + StorageObjSwitchOpen = true; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_InverterON() +{ + bool result = false; + if(FInverterON) + result = true; + else + result = false; + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::kWOut_Calc() +{ + double limitkWpct = 0.0; + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + FVWStateRequested = false; + if(fState == STORE_DISCHARGING) + limitkWpct = with0.kWrating * with0.FpctkWrated; + else + limitkWpct = with0.kWrating * with0.FpctkWrated * - 1; + +// if VWmode and (FState = STORE_DISCHARGING) then if (abs(kwRequested) < abs(limitkWpct)) then limitkWpct := kwRequested * sign(kW_Out); + // VW works only if element is not in idling state. + // When the VW is working in the 'limiting' region, kWRequested will be positive. + // When in 'requesting' region, it will be negative. + if(Get_VWmode() && !(fState == STORE_IDLING)) + { + if((Get_kWRequested() >= 0.0) && (Abs(Get_kWRequested()) < Abs( limitkWpct))) // Apply VW limit + { + if(fState == STORE_DISCHARGING) + limitkWpct = Get_kWRequested(); + else + limitkWpct = (double) (-1 * Get_kWRequested()); + } + else + { + if(Get_kWRequested() < 0.0) // IEEE 1547 Requesting Region (not fully implemented) + { + if(fState == STORE_DISCHARGING) + { + if(with0.kWhStored < with0.kWhRating) // let it charge only if enough not fully charged + { + fState = STORE_CHARGING; + kW_out = Get_kWRequested(); + } + else + { + fState = STORE_IDLING; + kW_out = -kWOutIdling; + } + } + else + // Charging + { + if(with0.kWhStored > with0.kWhReserve) // let it charge only if enough not fully charged + { + fState = STORE_DISCHARGING; + kW_out = (double) (-1 * Get_kWRequested()); + } + else + { + fState = STORE_IDLING; + kW_out = -kWOutIdling; + } + } + FStateChanged = true; + FVWStateRequested = true; + + // Update limitkWpct because state might have been changed + if(fState == STORE_DISCHARGING) + limitkWpct = with0.kWrating * with0.FpctkWrated; + else + limitkWpct = with0.kWrating * with0.FpctkWrated * - 1; + } + } + } + if((limitkWpct > 0) && (kW_out > limitkWpct)) + kW_out = limitkWpct; + else + { + if((limitkWpct < 0) && (kW_out < limitkWpct)) + kW_out = limitkWpct; + } + } +} + +//---------------------------------------------------------------------------- + +int TStorageObj::Get_Varmode() +{ + int result = 0; + result = FvarMode; + return result; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_VWmode() +{ + bool result = false; + if(FVWMode) + result = true; + else + result = false; // TRUE if volt-watt mode + // engaged from InvControl (not ExpControl) + return result; +} + +// ============================================================Get_WPmode=============================== + +bool TStorageObj::Get_WPmode() +{ + bool result = false; + if(FWPMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} + +// ============================================================Get_WVmode=============================== + +bool TStorageObj::Get_WVmode() +{ + bool result = false; + if(FWVMode) + result = true; + else + result = false; // engaged from InvControl (not ExpControl) + return result; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_VVmode() +{ + bool result = false; + if(FVVMode) + result = true; + else + result = false; + return result; +} + + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_DRCmode() +{ + bool result = false; + if(FDRCMode) + result = true; + else + result = false; + return result; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_AVRmode() +{ + bool result = false; + + if (FAVRMode) + result = true; + + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_CutOutkWAC() +{ + double result = 0.0; + result = FCutOutkWAC; + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_CutInkWAC() +{ + double result = 0.0; + result = FCutInkWAC; + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_pctkWOut(double Value) +{ + FpctkWout = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_pctkWIn(double Value) +{ + FpctkWin = Value; +} + +//---------------------------------------------------------------------------- + +// =========================================================================================== + +void TStorageObj::Set_WVmode(bool Value) +{ + FWVMode = Value; +} + + +// =========================================================================================== + +void TStorageObj::Set_WPmode(bool Value) +{ + FWPMode = Value; +} + +void TStorageObj::Set_kW(double Value) +{ + if(Value > 0) + { + fState = STORE_DISCHARGING; + FpctkWout = Value / StorageVars.kWrating * 100.0; + } + else + { + if(Value < 0) + { + fState = STORE_CHARGING; + FpctkWin = double(Abs( Value)) / StorageVars.kWrating * 100.0; + } + else + { + fState = STORE_IDLING; + } + } +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_Maxkvar(double Value) +{ + StorageVars.Fkvarlimit = Value; + Set_PropertyValue(propkvarLimit,Format("%-g", StorageVars.Fkvarlimit)); +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_Maxkvarneg(double Value) +{ + StorageVars.Fkvarlimitneg = Value; + Set_PropertyValue(propkvarLimitneg,Format("%-g", StorageVars.Fkvarlimitneg)); +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_kVARating(double Value) +{ + StorageVars.FkVArating = Value; + Set_PropertyValue(propKVA,Format("%-g", StorageVars.FkVArating)); +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_PowerFactor(double Value) +{ + PFNominal = Value; + Set_Varmode(VARMODEPF); +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_Varmode(int Value) +{ + FvarMode = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_VWmode(bool Value) +{ + FVWMode = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_VVmode(bool Value) +{ + FVVMode = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_DRCmode(bool Value) +{ + FDRCMode = Value; +} +//---------------------------------------------------------------------------- + +void TStorageObj::Set_AVRmode(bool Value) +{ + FAVRMode = Value; +} +//---------------------------------------------------------------------------- + +void TStorageObj::Set_PresentkV(double Value) +{ + StorageVars.kVStorageBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = StorageVars.kVStorageBase * InvSQRT3x1000; + break; + default: + VBase = StorageVars.kVStorageBase * 1000.0; + break; + } +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_kvarRequested(double Value) +{ + FkvarRequested = Value; +} + +//---------------------------------------------------------------------------- +/* +void TStorageObj::Set_pf_wp_nominal(double Value) +{ + Fpf_wp_nominal = Value; +} +*/ +void TStorageObj::Set_kWRequested(double Value) +{ + FkWRequested = Value; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kW() +{ + double result = 0.0; + switch(fState) + { + case STORE_CHARGING: + result = -Get_FpctkWIn() * StorageVars.kWrating / 100.0; + break; + case STORE_DISCHARGING: + result = get_FpctkWout() * StorageVars.kWrating / 100.0; + break; + case STORE_IDLING: + result = -kWOutIdling; + break; + default: + ; + break; + } + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kWRequested() +{ + double result = 0.0; + result = FkWRequested; + return result; +} + +//---------------------------------------------------------------------------- + +double TStorageObj::Get_kvarRequested() +{ + double result = 0.0; + result = FkvarRequested; + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_VarFollowInverter(bool Value) +{ + FVarFollowInverter = Value; +} + +//---------------------------------------------------------------------------- + +bool TStorageObj::Get_VarFollowInverter() +{ + bool result = false; + if(FVarFollowInverter) + result = true; + else + result = false; + return result; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_pctkWrated(double Value) +{ + StorageVars.FpctkWrated = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_InverterON(bool Value) +{ + FInverterON = Value; +} + +//---------------------------------------------------------------------------- + +void TStorageObj::Set_StorageState(int Value) +{ + int SavedState = 0; + SavedState = fState; + + // Decline if Storage is at its limits ; set to idling instead + /*# with StorageVars do */ + { + auto& with0 = StorageVars; + switch(Value) + { + case STORE_CHARGING: + { + if(with0.kWhStored < with0.kWhRating) + fState = Value; + else + fState = STORE_IDLING; // all charged up + } + break; + case STORE_DISCHARGING: + { + if(with0.kWhStored > with0.kWhReserve) + fState = Value; + else + fState = STORE_IDLING; // not enough Storage to discharge + } + break; + default: + fState = STORE_IDLING; + break; + } + } + if(SavedState != fState) + FStateChanged = true; + + //---DEBUG--- WriteDLLDebugFile(Format('t=%.8g, ---State Set To %s', [ActiveCircuit[ActiveActor].Solution.dblHour, StateToStr ])); +} +//---------------------------------------------------------------------------- + +void TStorageObj::SetDragHandRegister(int reg, double Value) +{ + if(Value > Registers[reg]) + Registers[reg] = Value; +} + +//---------------------------------------------------------------------------- + + +void Storage_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class Storage_unit + { + public: + Storage_unit() + { + //AssertSystemInitialization(); + Storage_initialization(); + } + }; + Storage_unit _Storage_unit; + +} // namespace Storage + + + + diff --git a/OpenDSSC/PCElements/Storage.h b/OpenDSSC/PCElements/Storage.h new file mode 100644 index 0000000..ecda745 --- /dev/null +++ b/OpenDSSC/PCElements/Storage.h @@ -0,0 +1,460 @@ +#ifndef StorageH +#define StorageH + +#include "System.h" +#include "Sysutils.h" + +#include "StorageVars.h" +#include "StoreUserModel.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "Dynamics.h" +#include "d2c_structures.h" +#include "DSSClassDefs.h" +#include "XYcurve.h" +#include "InvDynamics.h" +#include "mathutil.h" + + +namespace Storage +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2009-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + + 10/04/2009 Created from Generator Model + + + To Do: + Make connection to User model + Yprim for various modes + Define state vars and dynamics mode behavior + Complete Harmonics mode algorithm (generator mode is implemented) +*/ +/* + The storage element is essentially a generator that can be dispatched + to either produce power or consume power commensurate with rating and + amount of stored energy. + + The storage element can also produce or absorb vars within the kVA rating of the inverter. + That is, a StorageController object requests kvar and the storage element provides them if + it has any capacity left. The storage element can produce/absorb kvar while idling. +*/ + +// The Storage element is assumed balanced over the no. of phases defined +const int NumStorageRegisters = 6; // Number of energy meter registers +const int NumStorageVariables = 25 + 9; // No state variables + + +//= = = = = = = = = = = = = = DEFINE STATES = = = = = = = = = = = = = = = = = = = = = = = = = +const int STORE_CHARGING = -1; +const int STORE_IDLING = 0; +const int STORE_DISCHARGING = 1; +//= = = = = = = = = = = = = = DEFINE DISPATCH MODES = = = = = = = = = = = = = = = = = = = = = = = = = +const int STORE_DEFAULT = 0; +const int STORE_LOADMODE = 1; +const int STORE_PRICEMODE = 2; +const int STORE_EXTERNALMODE = 3; +const int STORE_FOLLOW = 4; + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TStorage : public PCClass::TPCClass +{ + friend class TStorageObj; +public: + typedef PCClass::TPCClass inherited; +//private: + void InterpretConnection(const String s); + void SetNcondsForConnection(); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherStorageObjName); +public: + String RegisterNames[6/*# range 1..NumStorageRegisters*/]; + TStorage(); + virtual ~TStorage(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void ResetRegistersAll(); + void SampleAll(int ActorID); + void UpdateAll(int ActorID); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TStorageObj : public PCElement::TPCElement +{ + friend class TStorage; +public: + typedef PCElement::TPCElement inherited; +//private: + Ucomplex::complex Yeq; // at nominal + Ucomplex::complex Yeq95; // at 95% + Ucomplex::complex Yeq105; // at 105% + Ucomplex::complex YeqIdling; // in shunt representing idle impedance + double PIdling; + Ucomplex::complex YeqDischarge; // equiv at rated power of storage element only + Ucomplex::complex PhaseCurrentLimit; + double MaxDynPhaseCurrent; + bool DebugTrace; + int fState; + bool FStateChanged; + bool FirstSampleAfterReset; + int StorageSolutionCount; + double StorageFundamental; /*Thevinen equivalent voltage mag and angle reference for Harmonic model*/ + bool StorageObjSwitchOpen; + bool ForceBalanced; + bool CurrentLimited; + double pctR; + double pctX; + int OpenStorageSolutionCount; + double Pnominalperphase; + double Qnominalperphase; + double RandomMult; + int Reg_Hours; + int Reg_kvarh; + int Reg_kWh; + int Reg_MaxkVA; + int Reg_MaxkW; + int Reg_Price; + Ucomplex::complex ShapeFactor; + System::TTextRec Tracefile; + bool IsUserModel; + + TStoreUserModel *UserModel; /*User-Written Models*/ + TStoreDynaModel *DynaModel; + + double kvarBase; // Base vars per phase + double VBase; // Base volts suitable for computing currents + double VBase105; + double VBase95; + double Vmaxpu; + double Vminpu; + Ucmatrix::TcMatrix* YPrimOpenCond; + void CalcDailyMult(double hr, int ActorID); + void CalcDutyMult(double hr, int ActorID); + void CalcStorageModelContribution(int ActorID); + void CalcInjCurrentArray(int ActorID); + + void ComputePresentkW(); + void ComputeInverterPower(); + + void ComputekWkvar(); + void ComputeDCkW(); + + /*PROCEDURE CalcVterminal;*/ + void CalcVTerminalPhase(int ActorID); + void CalcYearlyMult(double hr, int ActorID); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void DoConstantPQStorageObj(int ActorID); + void DoConstantZStorageObj(int ActorID); + void DoDynamicMode(int ActorID); + void DoHarmonicMode(int ActorID); + void DoUserModel(int ActorID); + void DoDynaModel(int ActorID); + void Integrate(int reg, double Deriv, double Interval, int ActorID); + void SetDragHandRegister(int reg, double Value); + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); + void WriteTraceRecord(const String s, int ActorID); + void SyncUpPowerQuantities(); + void SetKWandKvarOut(); + void CheckStateTriggerLevel(double Level, int ActorID); + void UpdateStorage(int ActorID); // Update Storage elements based on present kW and IntervalHrs variable + double NormalizeToTOD(int h, double Sec); + int InterpretState(const String s); +// FUNCTION StateToStr:String; + String DecodeState(); + double Get_PresentkW(); + double Get_Presentkvar(); + double Get_PresentkV(); + void Set_PresentkV(double Value); + void Set_Presentkvar(double Value); + void Set_PresentkW(double Value); + void Set_PowerFactor(double Value); + void Set_StorageState(int Value); + void Set_pctkvarOut(double Value); + void Set_pctkWOut(double Value); + double Get_kWTotalLosses(); + double Get_kWIdlingLosses(); + + void kWOut_Calc(); + +protected: + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); +public: + int Connection; /*0 = line-neutral; 1=Delta*/ + String DailyShape; // Daily (24 HR) Storage element shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily Storage element Shape for this load + String DutyShape; // Duty cycle load shape for changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this Storage element + int StorageClass; + int VoltageModel; // Variation with voltage + double PFNominal; + String YearlyShape; // ='fixed' means no variation on all the time + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this Storage element + StorageVars::TStorageVars StorageVars; + InvDynamics::TInvDynamicVars myDynVars; + double FpctkWout; // percent of kW rated output currently dispatched + double Fpctkvarout; + double pctReserve; + int DispatchMode; + bool kVANotSet; + double kvar_out; + double kW_out; + double pctIdlekW; + + double kWOutIdling; + + double pctIdlekvar; + double pctChargeEff; + double pctDischargeEff; + double DischargeTrigger; + double ChargeTrigger; + double ChargeTime; + double kWhBeforeUpdate; + double Registers[6]; + double Derivatives[6]; + //-----------------Inverter type vars----------------------------------------------- + std::string InverterCurve; + TXYcurveObj* InverterCurveObj; + + bool FVWStateRequested; + + double CurrentkvarLimit; + double CurrentkvarLimitNeg; + double FpctkWin; + + // Variables for InvControl's Volt-Watt function + bool FVWMode; //boolean indicating if under volt-watt control mode from InvControl (not ExpControl) + bool FVVMode; //boolean indicating if under volt-var mode from InvControl + bool FDRCMode; //boolean indicating if under DRC mode from InvControl + bool FWPMode; //boolean indicating if under watt-pf mode from InvControl + bool FWVMode; //boolean indicating if under watt-var mode from InvControl + bool FAVRMode; //boolean indicating whether under AVR mode from ExpControl (or InvControl, but that does not seem to be implemented yet) + + double FkvarRequested; + double FkWRequested; + int FvarMode; + double FDCkW; + double Fpf_wp_nominal; + + // Variables for Inverter functionalities + double FpctCutIn; + double FpctCutOut; + bool FVarFollowInverter; + double CutInkW; + double CutOutkW; + + double FCutOutkWAC; // CutInkW reflected to the AC side of the inverter + double FCutInkWAC; // CutOutkW reflected to the AC side of the inverter + + Integer FStateDesired; // Stores desired state (before any change due to kWh limits or %CutIn/%CutOut + + bool FInverterON; + double FpctPminNoVars; + double FpctPminkvarLimit; + double PminNoVars; + double PminkvarLimit; + double kVA_exceeded; + + std::vector PICtrl; + + bool kvarLimitSet; + bool kvarLimitNegSet; + bool kVASet; + + + + TStorageObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TStorageObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + void Randomize(int Opt); // 0 = reset to 1.0; 1 = Gaussian around mean and std Dev ; // 2 = uniform + void ResetRegisters(); + void TakeSample(int ActorID); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + + double get_PFNominal(); + int get_fState(); + double get_FpctkWout(); + double get_Fpctkvarout(); + double get_Vminpu(); + +//--------------------------------------------------------------------------------------------------- + + double Get_kW(); + void Set_kW(double Value); + double Get_kWDesired(); + void Set_StateDesired(int Value); + double Get_kWRequested(); + void Set_kWRequested(double Value); + double Get_kvarRequested(); + void Set_kvarRequested(double Value); + double Get_FkVARating(); + void Set_kVARating(double Value); + double Get_FpctkWrated(); + void Set_pctkWrated(double Value); + int Get_Varmode(); + void Set_Varmode(int Value); + bool Get_VWmode(); + void Set_VWmode(bool Value); + bool Get_VVmode(); + void Set_VVmode(bool Value); + bool Get_WPmode(); + void Set_WPmode(bool Value); + bool Get_WVmode(); + void Set_WVmode(bool Value); + bool Get_DRCmode(); + void Set_DRCmode(bool Value); + bool Get_AVRmode(); + void Set_AVRmode(bool Value); + bool Get_InverterON(); + bool Get_CIMDynamicMode(); + void Set_InverterON(bool Value); + double Get_CutOutkWAC(); + double Get_CutInkWAC(); + bool Get_VarFollowInverter(); + void Set_VarFollowInverter(bool Value); + double Get_Fkvarlimit(); + void Set_Maxkvar(double Value); + double Get_Fkvarlimitneg(); + void Set_Maxkvarneg(double Value); + + void SetNominalStorageOutput(int ActorID); + + double Get_FpctkWIn(); + void Set_pctkWIn(double myMaxkvar); + double Get_InverterLosses(); + double Get_kWChDchLosses(); + void Update_EfficiencyFactor(); + + double Get_DCkW(); + double Get_VminPu(); + void Set_pf_wp_nominal(double myPFNom); + double Get_Pmin(); + double Get_Pmax(); + double Get_qMaxInj(); + double Get_qMaxAbs(); + double Get_acVmin(); + double Get_acVmax(); + double Get_acVnom(); + double Get_pMaxUnderPF(); + double Get_pMaxOverPF(); + double Get_pMaxCharge(); + double Get_sMaxCharge(); + void DoGFM_Mode(int ActorID); + void GetCurrents(pComplexArray Curr, int ActorID); + bool CheckAmpsLimit(int ActorID); + bool CheckOLInverter(int ActorID); + bool CheckIfDelivering(int ActorID); + + // Functions for NCIM solution algorithm + void DoPQBusNCIM(int ActorID, int i, complex V, complex Curr); + +//--------------------------------------------------------------------------------------------------- + + //__declspec (property (get = Get_kW, put = Set_kW)) double kW; + //__declspec (property (get = Get_kWDesired)) double kWDesired; + //__declspec (property (put = Set_StateDesired)) int StateDesired; + //__declspec (property (get = Get_kWRequested, put = Set_kWRequested)) double kWRequested; + //__declspec (property (get = Get_kvarRequested, put = Set_kvarRequested)) double kvarRequested; + //__declspec (property (get = Get_FkVARating, put = Set_kVARating)) double kVARating; + //__declspec (property (get = Get_FpctkWrated, put = Set_pctkWrated)) double pctkWrated; + //__declspec (property (get = Get_Varmode, put = Set_Varmode)) int Varmode; + //__declspec (property (get = Get_VWmode, put = Set_VWmode)) bool VWmode; + //__declspec (property (get = Get_VVmode, put = Set_VVmode)) bool VVmode; + //__declspec (property (get = Get_WPmode, put = Set_WPmode)) bool WPmode; + //__declspec (property (get = Get_WVmode, put = Set_WVmode)) bool WVmode; + //__declspec (property (get = Get_DRCmode, put = Set_DRCmode)) bool DRCmode; + //__declspec (property (get = Get_InverterON, put = Set_InverterON)) bool InverterON; + //__declspec (property (get = Get_CutOutkWAC)) double CutOutkWAC; + //__declspec (property (get = Get_CutInkWAC)) double CutInkWAC; + //__declspec (property (get = Get_VarFollowInverter, put = Set_VarFollowInverter)) bool VarFollowInverter; + //__declspec (property (get = Get_Fkvarlimit, put = Set_Maxkvar)) double kvarLimit; + //__declspec (property (get = Get_Fkvarlimitneg, put = Set_Maxkvarneg)) double kvarLimitneg; + //__declspec (property (get = Get_FpctkWIn, put = Set_pctkWIn)) double PctkWIn; + //__declspec (property (get = Get_InverterLosses)) double kWInverterLosses; + //__declspec (property (get = Get_kWChDchLosses)) double kWChDchLosses; + //__declspec (property (get = Get_DCkW)) double DCkW; + //__declspec (property (get = Get_VminPu)) double MinModelVoltagePU; + //__declspec (property (put = Set_pf_wp_nominal)) double pf_wp_nominal; + //__declspec (property (get = Get_Pmin)) double Pmin; + //__declspec (property (get = Get_Pmax)) double Pmax; + //__declspec (property (get = Get_qMaxInj)) double qMaxInj; + //__declspec (property (get = Get_qMaxAbs)) double qMaxAbs; + //__declspec (property (get = Get_acVmin)) double acVmin; + //__declspec (property (get = Get_acVmax)) double acVmax; + //__declspec (property (get = Get_acVnom)) double acVnom; + //__declspec (property (get = Get_pMaxUnderPF)) double pMaxUnderPF; + //__declspec (property (get = Get_pMaxOverPF)) double pMaxOverPF; + //__declspec (property (get = Get_pMaxCharge)) double pMaxCharge; + //__declspec (property (get = Get_sMaxCharge)) double apparentPowerChargeMax; + + //__declspec (property (get = Get_PresentkW, put = Set_PresentkW ) ) double PresentkW; + //__declspec (property (get = Get_Presentkvar, put = Set_Presentkvar ) ) double Presentkvar; + //__declspec (property (get = Get_PresentkV, put = Set_PresentkV ) ) double PresentkV; + + //__declspec (property (get = get_PFNominal, put = Set_PowerFactor ) ) double Powerfactor; + //__declspec (property (get = get_fState, put = Set_StorageState ) ) int StorageState; + //__declspec (property (get = get_FpctkWout, put = Set_pctkWOut ) ) double PctkWOut; + //__declspec (property (get = get_Fpctkvarout, put = Set_pctkvarOut ) ) double PctkVarOut; + + //__declspec (property (get = Get_kWTotalLosses ) ) double kWTotalLosses; + //__declspec (property (get = Get_kWIdlingLosses ) ) double kWIdlingLosses; + + //__declspec (property (get = get_Vminpu ) ) double MinModelVoltagePU; + TStorageObj(TDSSClass* ParClass); + TStorageObj(String ClassName); + TStorageObj(); +}; +extern TStorageObj* ActiveStorageObj; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace Storage + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Storage; +#endif + +#endif // StorageH + + + + diff --git a/OpenDSSC/PCElements/StorageVars.cpp b/OpenDSSC/PCElements/StorageVars.cpp new file mode 100644 index 0000000..caa4c82 --- /dev/null +++ b/OpenDSSC/PCElements/StorageVars.cpp @@ -0,0 +1,22 @@ + +#pragma hdrstop + +#include "StorageVars.h" + +using namespace std; +using namespace System; +using namespace Ucomplex; + +namespace StorageVars +{ + + + + + + +} // namespace StorageVars + + + + diff --git a/OpenDSSC/PCElements/StorageVars.h b/OpenDSSC/PCElements/StorageVars.h new file mode 100644 index 0000000..b80eb4b --- /dev/null +++ b/OpenDSSC/PCElements/StorageVars.h @@ -0,0 +1,88 @@ +#ifndef StorageVarsH +#define StorageVarsH + +#include "System.h" + +#include "Ucomplex.h" + +namespace StorageVars +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + Definition of Storage Public Data Record for passing to DLLs and other object +*/ + +/*Struct to pass basic data to user-written DLLs*/ +#pragma pack (push, 1) + + +struct TStorageVars +{ + double kWrating; + double kWhRating; + double kWhStored; + double kWhReserve; + double ChargeEff; + double DisChargeEff; + double kVArating; + double kVStorageBase; + double kvarRequested; + double RThev; + double XThev; + // Inverter Related Properties + double FkVArating; + double Fkvarlimit; + double Fkvarlimitneg; + bool P_Priority; + bool PF_Priority; + double FpctkWrated; + double EffFactor; + + + // Interaction with InvControl + double Vreg; + double Vavg; + double VVOperation; + double VWOperation; + double DRCOperation; + double VVDRCOperation; + double WPOperation; + double WVOperation; + // Dynamics variables + Ucomplex::complex Vthev; /*Thevenin equivalent voltage (complex) for dynamic model*/ + Ucomplex::complex Zthev; + double VThevHarm; /*Thevenin equivalent voltage mag and angle reference for Harmonic model*/ + double ThetaHarm; /*Thevenin equivalent voltage mag and angle reference for Harmonic model*/ + double VthevMag; /*Thevenin equivalent voltage for dynamic model*/ + double Theta; /*Power angle between voltage and current*/ + double w_grid; /*Grid frequency*/ + double TotalLosses; + double IdlingLosses; + + /*32-bit integers*/ /*Number of phases*/ /*Total Number of conductors (wye-connected will have 4)*/ + int NumPhases; + int NumConductors; + int Conn; // 0 = wye; 1 = Delta +}; +#pragma pack (pop) + + + +} // namespace StorageVars + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace StorageVars; +#endif + +#endif // StorageVarsH + + + + diff --git a/OpenDSSC/PCElements/StoreUserModel.cpp b/OpenDSSC/PCElements/StoreUserModel.cpp new file mode 100644 index 0000000..427c20e --- /dev/null +++ b/OpenDSSC/PCElements/StoreUserModel.cpp @@ -0,0 +1,331 @@ + +#pragma hdrstop + +#include "StoreUserModel.h" + +#include "DSSGlobals.h" + +using namespace std; +using namespace Arraydef; +using namespace DSSGlobals; +using namespace Dynamics; +using namespace Storage; +using namespace System; +using namespace Ucomplex; + +namespace StoreUserModel +{ + + + +/* TStoreUserModel */ + +void* TStoreUserModel::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("Storage User Model DLL Does Not Have Required Function: ") + FuncName, 1569); + FuncError = true; + } + result = Addr; + return result; +} + +TStoreUserModel::TStoreUserModel() + : FHandle(0), + FID(0), + FuncError(false) +{ + FID = 0; + FName = ""; +} + +TStoreUserModel::~TStoreUserModel() +{ + // inherited; + if(FID != 0) + { + FDelete(FID); // Clean up all memory associated with this instance + FreeLibrary( (HMODULE) FHandle); + } +} + +//------------------------------------------------------------------------------ + +std::string TStoreUserModel::get_FName() +{ + return FName; +} + +//------------------------------------------------------------------------------ + +std::string TStoreDynaModel::get_FName() +{ + return FName; +} + +//------------------------------------------------------------------------------ + + +bool TStoreUserModel::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} + +void TStoreUserModel::Integrate() +{ + FSelect(FID); + FIntegrate(); +} + +void TStoreUserModel::select() +{ + FSelect(FID); +} + +void TStoreUserModel::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit((PAnsiChar) Value.c_str(), Value.size()); + // Else Ignore +} + +void TStoreUserModel::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if((HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + FreeLibrary((HMODULE) FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if((HMODULE) FHandle == 0) + // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary((DSSDirectory + Value).c_str()); + } + if((HMODULE) FHandle == 0) + DoSimpleMsg(String("Storage User Model ") + Value + + " Not Loaded. DSS Directory = " + + DSSDirectory, 1570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (StoreUserModelProc__13) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("New")), "New"); + if(!FuncError) + FSelect = (StoreUserModelProc__15) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Select")), "Select"); + if(!FuncError) + FInit = (StoreUserModelProc__17) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Init")), "Init"); + if(!FuncError) + FCalc = (StoreUserModelProc__18) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Calc")), "Calc"); + if(!FuncError) + FIntegrate = (StoreUserModelProc__19) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Integrate")), "Integrate"); + if(!FuncError) + FSave = (StoreUserModelProc__21) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Save")), "Save"); + if(!FuncError) + fRestore = (StoreUserModelProc__22) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Restore")), "Restore"); + if(!FuncError) + FEdit = (StoreUserModelProc__16) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (StoreUserModelProc__20) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (StoreUserModelProc__14) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Delete")), "Delete"); + if(!FuncError) + FNumVars = (StoreUserModelProc__23) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("NumVars")), "NumVars"); + if(!FuncError) + FGetAllVars = (StoreUserModelProc__24) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetAllVars")), "GetAllVars"); + if(!FuncError) + FGetVariable = (StoreUserModelProc__25) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVariable")), "GetVariable"); + if(!FuncError) + FSetVariable = (StoreUserModelProc__26) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("SetVariable")), "SetVariable"); + if(!FuncError) + FGetVarName = (StoreUserModelProc__27) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVarName")), "GetVarName"); + if(FuncError) + { + FreeLibrary((HMODULE) FHandle); + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew(ActiveCircuit[ActiveActor]->Solution->DynaVars, CallBackRoutines); // Create new instance of user model + } + } +} + +/*============================= TSTOREDYNAMODEL ================================================================*/ + +/* TStoreDynaModel */ + +void* TStoreDynaModel::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("Storage User Dynamic DLL Does Not Have Required Function: ") + FuncName, 1569); + FuncError = true; + } + result = Addr; + return result; +} + +TStoreDynaModel::TStoreDynaModel() + : FHandle(0), + FID(0), + FuncError(false) +{ + FID = 0; + FName = ""; +} + +TStoreDynaModel::~TStoreDynaModel() +{ + if(FID != 0) + { + FDelete(FID); // Clean up all memory associated with this instance + FreeLibrary((HMODULE) FHandle); + } + // inherited; +} + + +bool TStoreDynaModel::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} + +void TStoreDynaModel::Integrate() +{ + FSelect(FID); + FIntegrate(); +} + +void TStoreDynaModel::select() +{ + FSelect(FID); +} + +void TStoreDynaModel::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit((PAnsiChar) Value.c_str(), Value.size()); +} + +void TStoreDynaModel::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if((HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + FreeLibrary((HMODULE) FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if((HMODULE) FHandle == 0) + // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary((DSSDirectory + Value).c_str()); + } + if((HMODULE) FHandle == 0) + DoSimpleMsg(String("Storage User-written Dynamics Model ") + Value + + " Not Loaded. DSS Directory = " + + DSSDirectory, 1570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (StoreUserModelProc__0) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("New")), "New"); + if(!FuncError) + FSelect = (StoreUserModelProc__2) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Select")), "Select"); + if(!FuncError) + FInit = (StoreUserModelProc__4) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Init")), "Init"); + if(!FuncError) + FCalc = (StoreUserModelProc__5) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Calc")), "Calc"); + if(!FuncError) + FIntegrate = (StoreUserModelProc__6) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Integrate")), "Integrate"); + if(!FuncError) + FEdit = (StoreUserModelProc__3) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (StoreUserModelProc__7) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (StoreUserModelProc__1) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Delete")), "Delete"); + if(!FuncError) + FNumVars = (StoreUserModelProc__8) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("NumVars")), "NumVars"); + if(!FuncError) + FGetAllVars = (StoreUserModelProc__9) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetAllVars")), "GetAllVars"); + if(!FuncError) + FGetVariable = (StoreUserModelProc__10) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVariable")), "GetVariable"); + if(!FuncError) + FSetVariable = (StoreUserModelProc__11) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("SetVariable")), "SetVariable"); + if(!FuncError) + FGetVarName = (StoreUserModelProc__12) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVarName")), "GetVarName"); + if(FuncError) + { + FreeLibrary((HMODULE) FHandle); + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew(ActiveCircuit[ActiveActor]->Solution->DynaVars, CallBackRoutines); // Create new instance of user model + } + } +} + + + + +} // namespace StoreUserModel + + + + diff --git a/OpenDSSC/PCElements/StoreUserModel.h b/OpenDSSC/PCElements/StoreUserModel.h new file mode 100644 index 0000000..2853e93 --- /dev/null +++ b/OpenDSSC/PCElements/StoreUserModel.h @@ -0,0 +1,175 @@ +#ifndef StoreUserModelH +#define StoreUserModelH + +#include "System.h" +#include "Sysutils.h" + +#include "StorageVars.h" +#include "Dynamics.h" +#include "DSSCallBackRoutines.h" +#include "DSSCallBackStructDef.h" +#include "Ucomplex.h" +#include "Arraydef.h" + +//#include "Storage.h" + + +namespace StoreUserModel +{ + + + + /*$M+*/ + /* + ---------------------------------------------------------- + Copyright (c) 2009-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + This module contains two interfaces: + 1) Standard user written model and + 2) dynamics only DLL + + */ + + // Interface for Dynamics-only user-written model + + class TStoreDynaModel + { + public: + typedef TObject inherited; + //private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + String FName; // Name of the DLL file containing user model + bool FuncError; + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *StoreUserModelProc__0)(Dynamics::TDynamicsRec&, TDSSCallBacks&); + StoreUserModelProc__0 FNew; // deletes specified instance + typedef void (__stdcall *StoreUserModelProc__1)(int&); + StoreUserModelProc__1 FDelete; // Select active instance + typedef int (__stdcall *StoreUserModelProc__2)(int&); + StoreUserModelProc__2 FSelect; + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); + + String get_FName(); + + public: // send string to user model to handle + typedef void (__stdcall *StoreUserModelProc__3)(System::PAnsiChar, unsigned int); + StoreUserModelProc__3 FEdit; // For dynamics + typedef void (__stdcall *StoreUserModelProc__4)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + StoreUserModelProc__4 FInit; // returns Currents or sets Pshaft + typedef void (__stdcall *StoreUserModelProc__5)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + StoreUserModelProc__5 FCalc; // Integrates any state vars + typedef void (__stdcall *StoreUserModelProc__6)(); + StoreUserModelProc__6 FIntegrate; // Called when props of generator updated + + /*Monitoring functions*/ + typedef void (__stdcall *StoreUserModelProc__7)(); + StoreUserModelProc__7 FUpdateModel; + typedef int (__stdcall *StoreUserModelProc__8)(); + StoreUserModelProc__8 FNumVars; // Get all vars + typedef void (__stdcall *StoreUserModelProc__9)(Arraydef::pDoubleArray); + StoreUserModelProc__9 FGetAllVars;// Get a particular var + typedef double (__stdcall *StoreUserModelProc__10)(int&); + StoreUserModelProc__10 FGetVariable; + typedef void (__stdcall *StoreUserModelProc__11)(int&, double&); + StoreUserModelProc__11 FSetVariable; + + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + typedef void (__stdcall *StoreUserModelProc__12)(int&, System::PAnsiChar, unsigned int); + StoreUserModelProc__12 FGetVarName; + void select(); + void Integrate(); + TStoreDynaModel(); + virtual ~TStoreDynaModel(); + //__published: + }; + + + + + // Interface for general user-written model that includes power flow calcs as well as dynamics + + class TStoreUserModel + { + public: + typedef TObject inherited; + //private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + String FName; // Name of the DLL file containing user model + bool FuncError; + + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *StoreUserModelProc__13)(Dynamics::TDynamicsRec&, TDSSCallBacks&); + StoreUserModelProc__13 FNew; // deletes specified instance + typedef void (__stdcall *StoreUserModelProc__14)(int&); + StoreUserModelProc__14 FDelete; // Select active instance + typedef int (__stdcall *StoreUserModelProc__15)(int&); + StoreUserModelProc__15 FSelect; + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); + + std::string get_FName(); + + protected: + public: // send string to user model to handle + typedef void (__stdcall *StoreUserModelProc__16)(System::PAnsiChar, unsigned int); + StoreUserModelProc__16 FEdit; // For dynamics + typedef void (__stdcall *StoreUserModelProc__17)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + StoreUserModelProc__17 FInit; // returns Currents or sets Pshaft + typedef void (__stdcall *StoreUserModelProc__18)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + StoreUserModelProc__18 FCalc; // Integrates any state vars + typedef void (__stdcall *StoreUserModelProc__19)(); + StoreUserModelProc__19 FIntegrate; // Called when props of generator updated + + /*Save and restore data*/ + typedef void (__stdcall *StoreUserModelProc__20)(); + StoreUserModelProc__20 FUpdateModel; + typedef void (__stdcall *StoreUserModelProc__21)(); + StoreUserModelProc__21 FSave; + + /*Monitoring functions*/ + typedef void (__stdcall *StoreUserModelProc__22)(); + StoreUserModelProc__22 fRestore; + typedef int (__stdcall *StoreUserModelProc__23)(); + StoreUserModelProc__23 FNumVars; // Get all vars + typedef void (__stdcall *StoreUserModelProc__24)(Arraydef::pDoubleArray); + StoreUserModelProc__24 FGetAllVars;// Get a particular var + typedef double (__stdcall *StoreUserModelProc__25)(int&); + StoreUserModelProc__25 FGetVariable; + typedef void (__stdcall *StoreUserModelProc__26)(int&, double&); + StoreUserModelProc__26 FSetVariable; + + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + typedef void (__stdcall *StoreUserModelProc__27)(int&, System::PAnsiChar, unsigned int); + StoreUserModelProc__27 FGetVarName; + void select(); + void Integrate(); + TStoreUserModel(); + virtual ~TStoreUserModel(); + //__published: + }; + + +} // namespace StoreUserModel + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace StoreUserModel; +#endif + +#endif // StoreUserModelH + + + + diff --git a/OpenDSSC/PCElements/UPFC.cpp b/OpenDSSC/PCElements/UPFC.cpp new file mode 100644 index 0000000..733c8c4 --- /dev/null +++ b/OpenDSSC/PCElements/UPFC.cpp @@ -0,0 +1,1559 @@ + + +#pragma hdrstop + +#include "UPFC.h" + +#include "Circuit.h" +#include "Utilities.h" +#include "DSSGlobals.h" +#include "Solution.h" +#include "UPFCControl.h" + + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace Solution; +using namespace System; +using namespace UPFCControl; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace YMatrix; +using namespace Utilities; + +namespace UPFC +{ + +TUPFCObj::TUPFCObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TUPFCObj::TUPFCObj(String ClassName) : inherited(ClassName) {} +TUPFCObj::TUPFCObj() {} + + +TUPFCObj* ActiveUPFCObj = nullptr; +TUPFC* UPFC_class = nullptr; +const int propLossCurve = 11; +const int NumPropsThisClass = 17; +const int NumUPFCVariables = 14; +complex CDoubleOne = {}; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TUPFC::TUPFC() +{ + ; + Class_Name = "UPFC"; + DSSClassType = PC_ELEMENT + UPFC_ELEMENT; // UPFC is PC Element + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + UPFC_class = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TUPFC::~TUPFC() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TUPFC::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "bus2"; + PropertyName[3 - 1] = "refkv"; + PropertyName[4 - 1] = "pf"; + PropertyName[5 - 1] = "frequency"; + PropertyName[6 - 1] = "phases"; + PropertyName[7 - 1] = "Xs"; + PropertyName[8 - 1] = "Tol1"; + PropertyName[9 - 1] = "Mode"; + PropertyName[10 - 1] = "VpqMax"; + PropertyName[11 - 1] = "LossCurve"; + PropertyName[12 - 1] = "VHLimit"; + PropertyName[13 - 1] = "VLLimit"; + PropertyName[14 - 1] = "CLimit"; + PropertyName[15 - 1] = "refkv2"; + PropertyName[16 - 1] = "kvarLimit"; + PropertyName[17 - 1] = "Element"; + + + // define Property help values + PropertyHelp[1 - 1] = String("Name of bus to which the input terminal (1) is connected.") + CRLF + + "bus1=busname.1.3" + + CRLF + + "bus1=busname.1.2.3"; + PropertyHelp[2 - 1] = String("Name of bus to which the output terminal (2) is connected.") + CRLF + + "bus2=busname.1.2" + + CRLF + + "bus2=busname.1.2.3"; + PropertyHelp[3 - 1] = String("Base Voltage expected at the output of the UPFC") + CRLF + + CRLF + + "\"refkv=0.24\""; + PropertyHelp[4 - 1] = "Power factor target at the input terminal."; + PropertyHelp[5 - 1] = "UPFC working frequency. Defaults to system default base frequency."; + PropertyHelp[6 - 1] = "Number of phases. Defaults to 1 phase (2 terminals, 1 conductor per terminal)."; + PropertyHelp[7 - 1] = "Reactance of the series transformer of the UPFC, ohms (default=0.7540 ... 2 mH)"; + PropertyHelp[8 - 1] = String("Tolerance in pu for the series PI controller") + CRLF + + "Tol1=0.02 is the format used to define 2% tolerance (Default=2%)"; + PropertyHelp[9 - 1] = String("Integer used to define the control mode of the UPFC: ") + CRLF + + CRLF + + "0 = Off, " + + CRLF + + "1 = Voltage regulator, " + + CRLF + + "2 = Phase angle regulator, " + + CRLF + + "3 = Dual mode" + + CRLF + + "4 = It is a control mode where the user can set two different set points to create a secure GAP," + + " these references must be defined in the parameters RefkV and RefkV2. The only restriction when " + + "setting these values is that RefkV must be higher than RefkV2. " + + CRLF + + "5 = In this mode the user can define the same GAP using two set points as in control mode 4. The " + + "only difference between mode 5 and mode 4 is that in mode 5, the UPFC controller performs dual control" + + " actions just as in control mode 3"; + PropertyHelp[10 - 1] = "Maximum voltage (in volts) delivered by the series voltage source (Default = 24 V)"; + PropertyHelp[11 - 1] = "Name of the XYCurve for describing the losses behavior as a function of the voltage at the input of the UPFC"; + PropertyHelp[12 - 1] = "High limit for the voltage at the input of the UPFC, if the voltage is above this value the UPFC turns off. This value is specified in Volts (default 300 V)"; + PropertyHelp[13 - 1] = "low limit for the voltage at the input of the UPFC, if voltage is below this value the UPFC turns off. This value is specified in Volts (default 125 V)"; + PropertyHelp[14 - 1] = "Current Limit for the UPFC, if the current passing through the UPFC is higher than this value the UPFC turns off. This value is specified in Amps (Default 265 A)"; + PropertyHelp[15 - 1] = String("Base Voltage expected at the output of the UPFC for control modes 4 and 5.") + CRLF + + CRLF + + "This reference must be lower than refkv, see control modes 4 and 5 for details"; + PropertyHelp[16 - 1] = "Maximum amount of reactive power (kvar) that can be absorved by the UPFC (Default = 5)"; + PropertyHelp[17 - 1] = String("The name of the PD element monitored when operating with reactive power compensation. Normally, it should be the ") + + "PD element immediately upstream the UPFC. The element must be defined including the class, e.g. Line.myline."; + + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1 - 1] = "Name of harmonic spectrum for this source. Default is \"defaultUPFC\", which is defined when the DSS starts."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TUPFC::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to UPFC class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TUPFCObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TUPFC::Edit(int ActorID) +{ + int Devindex; + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; +//>>> ZTemp : Complex; + + // continue parsing with contents of Parser + ActiveUPFCObj = (TUPFCObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveUPFCObj); + result = 0; + /*# with ActiveUPFCObj do */ + { + auto with0 = ActiveUPFCObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"UPFC." + + with0->get_Name() + + "\"", 320); + break; + case 1: + with0->SetBus(1, Param); + break; // special handling of Bus 1 + case 2: + with0->SetBus(2, Param); + break; // special handling of Bus 2 + case 3: + with0->VRef = Parser[ActorID]->MakeDouble_(); + break; // kv Output reference + case 4: + with0->PF = Parser[ActorID]->MakeDouble_(); + break; // power factor + case 5: + with0->Freq = Parser[ActorID]->MakeDouble_(); + break; // Freq + case 6: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + with0->OutCurr.resize( with0->Get_NPhases() ); + with0->InCurr.resize( with0->Get_NPhases() ); + } + break; + case 7: + with0->Xs = Parser[ActorID]->MakeDouble_(); + break; // Xs + case 8: + with0->Tol1 = Parser[ActorID]->MakeDouble_(); + break; // Tolerance Ctrl 2 + case 9: + with0->ModeUPFC = Parser[ActorID]->MakeInteger_(); + break; + case 10: + with0->Vpqmax = Parser[ActorID]->MakeDouble_(); + break; + case propLossCurve: + with0->LossCurve = Param; + break; + case 12: + with0->VHLimit = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->VLLimit = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->CLimit = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->VRef2 = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->KVARLim = Parser[ActorID]->MakeDouble_(); + break; + case 17: + { + with0->MonElm = LowerCase(Param); + Devindex = GetCktElementIndex(with0->MonElm); + if (Devindex > 0) + with0->myElm = (TDSSCktElement*) ActiveCircuit[ActiveActor]->CktElements.Get(Devindex); + else + DoSimpleMsg("Monitored Element for UPFC operation does not exist:\"" + with0->MonElm + "\"", 9002); + } + break; + default: + inherited::ClassEdit(ActiveUPFCObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case propLossCurve: + with0->UPFCLossCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->LossCurve)); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TUPFC::MakeLike(const String OtherSource) +{ + int result = 0; + TUPFCObj* OtherUPFC = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherUPFC = ((TUPFCObj*) Find(OtherSource)); + if(OtherUPFC != nullptr) + /*# with ActiveUPFCObj do */ + { + auto with0 = ActiveUPFCObj; + int stop = 0; + if(with0->Fnphases != OtherUPFC->Fnphases) + { + with0->Set_NPhases(OtherUPFC->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + with0->Z = new TcMatrix(with0->Fnphases); + with0->Zinv = new TcMatrix(with0->Fnphases); + } + with0->Z->CopyFrom(OtherUPFC->Z); + with0->VRef = OtherUPFC->VRef; + with0->PF = OtherUPFC->PF; + with0->Xs = OtherUPFC->Xs; + with0->Tol1 = OtherUPFC->Tol1; + with0->ZBase = OtherUPFC->ZBase; + with0->Freq = OtherUPFC->Freq; + with0->ModeUPFC = OtherUPFC->ModeUPFC; + with0->Vpqmax = OtherUPFC->Vpqmax; + with0->LossCurve = OtherUPFC->LossCurve; + with0->UPFCLossCurveObj = with0->UPFCLossCurveObj; + with0->VHLimit = OtherUPFC->VHLimit; + with0->VLLimit = OtherUPFC->VLLimit; + with0->CLimit = OtherUPFC->CLimit; + with0->VRef2 = OtherUPFC->VRef2; + with0->KVARLim = OtherUPFC->KVARLim; + ClassMakeLike(OtherUPFC); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->FPropertyValue[i - 1] = OtherUPFC->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in UPFC MakeLike: \"") + OtherSource + "\" Not Found.", 322); + return result; +} + +//---------------------------------------------------------------------------- + +int TUPFC::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TUPFC.Init", -1); + result = 0; + return result; +} + +//============================================================================= + +TUPFCObj::TUPFCObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + VRef(0.24), + PF(1.0), + Xs(0.7540), + Tol1(0.0), + ZBase(0.0), + Freq(0.0), + VHLimit(0.0), + VLLimit(0.0), + CLimit(0.0), + UPFCON(false), + VRef2(0.0), + VRefD(0.0), + KVARLim(0.0), + Losses(0.0), + QIdeal(0.0), + ModeUPFC(0), + Vpqmax(0.0), + SyncFlag(false), + SF2(false), + UPFCLossCurveObj(nullptr), + Z(nullptr), + Zinv(nullptr), + Vmag(0.0) +{ + int i = 0; + Sr0 = NULL; + Sr1 = NULL; + TDSSClass* MyClass = nullptr; + TUPFCControlObj* myCtrl = nullptr; + int stop = 0; + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; //SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + Set_NPhases(1); + Fnconds = 1; // number conductors per terminal + Set_NTerms(2); // A 2-terminal device + Z = nullptr; + Zinv = nullptr; + Tol1 = 0.02; + Freq = 60.0; + Set_Enabled(true); + ModeUPFC = 1; + Vpqmax = 24.0; // From the data provided + LossCurve = ""; + UPFCLossCurveObj = nullptr; + VHLimit = 300.0; + VLLimit = 125.0; + CLimit = 265.0; + UPFCON = true; + VRef2 = 0.0; + KVARLim = 5; + myElm = nullptr; + + QIdeal = 0.0; + + // Initialize shift registers + Sr0 = (pComplexArray) realloc(Sr0, sizeof(complex) * Fnphases); + Sr1 = (pComplexArray) realloc(Sr1, sizeof(complex) * Fnphases); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + (Sr0)[i - 1] = CZero; + } //For multiphase model + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + (Sr1)[i - 1] = CZero; + } //For multiphase model + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + ERR0[i - 1] = 0; + } //For multiphase model + InitPropertyValues(0); + OutCurr.resize( Get_NPhases()); + InCurr.resize( Get_NPhases()); + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + OutCurr[i - 1] = CZero; //For multiphase model + InCurr[i - 1] = CZero; //For multiphase model + } + + // If there is a controller, sets the flag for it to consider de new UPFC + MyClass = (TDSSClass*) GetDSSClassPtr("upfccontrol"); + if(MyClass->Get_ElementCount() > 0) + { + myCtrl = ((TUPFCControlObj*) MyClass->ElementList.Get(1)); + myCtrl->get_FUPFCList()->Clear(); + myCtrl->set_FListSize(0); + } + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + + +//============================================================================= + +TUPFCObj::~TUPFCObj() +{ + delete Z; // Z->~TcMatrix(); + delete Zinv; // Zinv->~TcMatrix(); + free(Sr0); + free(Sr1); + // inherited::Destroy(); +} + + +//============================================================================= + +void TUPFCObj::RecalcElementData(int ActorID) +{ + complex Z1 = {}; + complex Value = {}; + int i = 0; + int stop = 0; + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + + // For a Source, nphases = ncond, for now + Z = new TcMatrix(Fnphases); + Zinv = new TcMatrix(Fnphases); + QIdeal = 0.0; + + /*Update property Value array*/ + /* Don't change a specified value; only computed ones*/ + Z1 = cmplx(0, Xs); + // Diagonals (all the same) + Value = Z1; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Z->SetElement(i, i, Value); + } + Sr0 = (pComplexArray)realloc(Sr0, sizeof(complex) * Fnphases); + Sr1 = (pComplexArray)realloc(Sr1, sizeof(complex) * Fnphases); + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder); +} + + + +//============================================================================= + +void TUPFCObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + +// Calc UPFC Losses + // Build only YPrim Series + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /* Put in Series RL Adjusted for frequency */ + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Z->GetElement(i, j); + Value.im = Value.im * FreqMultiplier; /*Modify from base freq*/ + Zinv->SetElement(i, j, Value); + } + } + Zinv->Invert(); /*Invert in place*/ + if(Zinv->InvertError > 0) /*If error, put in Large series conductance*/ + { + int stop = 0; + DoErrorMsg("TUPFCObj.CalcYPrim", String("Matrix Inversion Error for UPFC \"") + get_Name() + "\"", "Invalid impedance specified. Replaced with small resistance.", 325); + Zinv->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, cmplx(1.0 / EPSILON, 0.0)); + } + } + + // YPrim_Series.CopyFrom(Zinv); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zinv->GetElement(i, j); + YPrim_Series->SetElement(i, j, Value); + YPrim_Series->SetElement(i + Fnphases, j + Fnphases, Value); + //YPrim_series.SetElemsym(i + FNPhases, j, CNegate(Value)) + YPrim_Series->SetElement(i, j + Fnphases, cnegate(Value)); + YPrim_Series->SetElement(i + Fnphases, j, cnegate(Value)); + } + } + YPrim->CopyFrom(YPrim_Series); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +//============================================================================= + +double TUPFCObj::CalcUPFCLosses(double Vpu) +{ + double result = 0.0; + +// Calculates the Active power losses at the input of the device +// By using the Load powers, the approach is based in the data provided + result = UPFCLossCurveObj->GetYValue_(Vpu); + return result; +} + + +//=========================================================================== + +int TUPFCObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + +/*This is source injection*/ + result = inherited::InjCurrents(ActorID); // Add into system array + return result; +} + +//=========================================================================== +//Taken from ISources due to the kind of model +//=========================================================================== +//Calculates the output current for the UPFC device +/* + Vbin Xs Vbout + <---*--=======--*---> + | | + I input ^ ^ I output + | | + + 4 modes of operation: + mode 0: UPFC Off + mode 1: UPFC in voltage regulation mode + mode 2: UPFC in reactive power compensation mode + mode 3: Mode 1 and 2 working together +*/ + +complex TUPFCObj::GetOutputCurr(int Cond, int ActorID) +{ + complex result = {}; + double Error = 0.0; + double TError = 0.0; + double VinMag = 0.0; + double RefH = 0.0; + double RefL = 0.0; + polar Vpolar = {}; + complex vtemp = {}; + complex CurrOut = {}; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + UPFCON = true; + } + VinMag = cabs(Vbin); + if((VinMag > VHLimit) || (VinMag < VLLimit)) // Check Limits (Voltage) + { + UPFCON = false; + CurrOut = cmplx(0, 0); + } + else + // Limits OK + { + switch(ModeUPFC) + { + case 0: + { + CurrOut = cmplx(0, 0); //UPFC off + } + break; //UPFC as a voltage regulator + case 1: + { + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRef * 1000))); + if(Error > Tol1) + { + vtemp = csub(Vbout, Vbin); + Vpolar = ctopolar(Vbin); + TError = (VRef * 1000) - Vpolar.mag; + if(TError > Vpqmax) + TError = Vpqmax; + else + { + if(TError < - Vpqmax) + TError = -Vpqmax; + } + Vpolar = topolar(TError, Vpolar.ang); + vtemp = csub(ptocomplex(Vpolar), vtemp); //Calculates Vpq + CurrOut = cadd((Sr0)[Cond - 1], cdiv(vtemp, cmplx(0, Xs))); + (Sr0)[Cond - 1] = CurrOut; + } + else + { + CurrOut = (Sr0)[Cond - 1]; + } + } + break; + case 2: + CurrOut = cmplx(0, 0); + break; //UPFC as a phase angle regulator + //UPFC in Dual mode Voltage and Phase angle regulator + case 3: + { + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRef * 1000))); + if(Error > Tol1) + { + vtemp = csub(Vbout, Vbin); + Vpolar = ctopolar(Vbin); + TError = (VRef * 1000) - Vpolar.mag; + if(TError > Vpqmax) + TError = Vpqmax; + else + { + if(TError < - Vpqmax) + TError = -Vpqmax; + } + Vpolar = topolar(TError, Vpolar.ang); + vtemp = csub(ptocomplex(Vpolar), vtemp); //Calculates Vpq + CurrOut = cadd((Sr0)[Cond - 1], cdiv(vtemp, cmplx(0, Xs))); + (Sr0)[Cond - 1] = CurrOut; + SyncFlag = false; + } + else + { + CurrOut = (Sr0)[Cond - 1]; + SyncFlag = true; + } + } + break; // Double reference control mode (only voltage control) + case 4: + { + Vpolar = ctopolar(Vbin); // Takes the input voltage to verify the operation + // Verifies if the Voltage at the input is out of the gap defined with VRef and VRef2 + RefH = (VRef * 1000) + (VRef * 1000 * Tol1); + RefL = (VRef2 * 1000) - (VRef2 * 1000 * Tol1); + if((Vpolar.mag > RefH) || (Vpolar.mag < RefL)) + // Sets the New reference by considering the value at the input of the device + { + if(Vpolar.mag > RefH) + VRefD = VRef; + else + { + if(Vpolar.mag < RefL) + VRefD = VRef2; + // Starts the control routine for voltage control only + } + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRefD * 1000))); + if(Error > Tol1) + { + vtemp = csub(Vbout, Vbin); + Vpolar = ctopolar(Vbin); + TError = (VRefD * 1000) - Vpolar.mag; + if(TError > Vpqmax) + TError = Vpqmax; + else + { + if(TError < - Vpqmax) + TError = -Vpqmax; + } + Vpolar = topolar(TError, Vpolar.ang); + vtemp = csub(ptocomplex(Vpolar), vtemp); //Calculates Vpq + CurrOut = cadd((Sr0)[Cond - 1], cdiv(vtemp, cmplx(0, Xs))); + (Sr0)[Cond - 1] = CurrOut; + } + else + { + CurrOut = (Sr0)[Cond - 1]; + } + SF2 = true; // Normal control routine + } + else + { + CurrOut = cmplx(0, 0); //UPFC off + (Sr0)[Cond - 1] = CurrOut; + SF2 = false; // Says to the other controller to do nothing + } + } + break; // Double reference control mode (Dual mode) + case 5: + { + Vpolar = ctopolar(Vbin); // Takes the input voltage to verify the operation + // Verifies if the Voltage at the input is out of the gap defined with VRef and VRef2 + RefH = (VRef * 1000) + (VRef * 1000 * Tol1); + RefL = (VRef2 * 1000) - (VRef2 * 1000 * Tol1); + if((Vpolar.mag > RefH) || (Vpolar.mag < RefL)) + // Sets the New reference by considering the value at the input of the device + { + if(Vpolar.mag > RefH) + VRefD = VRef; + else + { + if(Vpolar.mag < RefL) + VRefD = VRef2; + // Starts standard control (the same as Dual control mode) + } + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRefD * 1000))); + if(Error > Tol1) + { + vtemp = csub(Vbout, Vbin); + Vpolar = ctopolar(Vbin); + TError = (VRefD * 1000) - Vpolar.mag; + if(TError > Vpqmax) + TError = Vpqmax; + else + { + if(TError < - Vpqmax) + TError = -Vpqmax; + } + Vpolar = topolar(TError, Vpolar.ang); + vtemp = csub(ptocomplex(Vpolar), vtemp); //Calculates Vpq + CurrOut = cadd((Sr0)[Cond - 1], cdiv(vtemp, cmplx(0, Xs))); + (Sr0)[Cond - 1] = CurrOut; + SyncFlag = false; + } + else + { + CurrOut = (Sr0)[Cond - 1]; + SyncFlag = true; + } + SF2 = true; // Normal control routine + } + else + { + CurrOut = cmplx(0, 0); //UPFC off + (Sr0)[Cond - 1] = CurrOut; + SF2 = false; // Says to the other controller to do nothing + SyncFlag = false; + } + } + break; + default: + DoSimpleMsg("Control mode not regognized for UPFC", 790); + break; + } + } + result = CurrOut; + } + catch(...) + { + DoSimpleMsg(String("Error computing current for Isource.") + get_Name() + + ". Check specification. Aborting.", 334); + if(In_Redirect) + Redirect_Abort = true; + } + return result; +} +//============================================================================ + +complex TUPFCObj::CalcUPFCPowers(int ModeUP, int Cond) +{ + complex result = {}; + switch(ModeUP) + { + case 1: //Dual mode + { + IUPFC = cdiv(csub(Vbout, Vbin), cmplx(0, Xs)); +// SOut=cmul(Vbout,conjg(cadd(IUPFC,SR0[Cond]))) // Just if you want to know the power at the output + result = cnegate(cmul(Vbin, conjg(cadd(IUPFC, (Sr1)[Cond - 1])))); + } + break; //StatCOM + case 2: + { + IUPFC = cdiv(csub(Vbin, Vbout), cmplx(0, Xs)); + result = cmul(Vbin, conjg(IUPFC)); + } + break; + default: + ; + break; + } + return result; +} + + +//============================================================================ +//Calculates the input current to absorb reactive power from UPFC +/* + Vbin Xs Vbout + <---*--=======--*---> + | | + I input ^ ^ I output + | | +*/ + +complex TUPFCObj::GetinputCurr(int Cond, int ActorID) +{ + complex result = {}; + complex CurrIn = {}; + complex Ctemp = {}; + double s = 0.0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(UPFCON) + /*Get first Phase Current*/ + { + switch(ModeUPFC) + { + case 0: + { + CurrIn = cmplx(0, 0); + UPFC_Power = CZero; + } + break; // Voltage regulation mode + case 1: + { + CurrIn = CZero; + Ctemp = conjg(cmul(cdiv(Vbout, Vbin), conjg((Sr0)[Cond - 1]))); //Balancing powers + Losses = CalcUPFCLosses(cabs(Vbin) / (VRef * 1000)); + CurrIn = cnegate(cmplx((Ctemp.re * Losses), Sr0[Cond - 1].im)); +// CurrIn = cnegate(cmplx(Losses * (Sr0)[Cond - 1].re, (Sr0)[Cond - 1].im)); // This change removes power balance, dangerous + (Sr1)[Cond - 1] = CurrIn; + } + break; // Reactive compensation mode + case 2: + { + UPFC_Power = CalcUPFCPowers(2, 0); + s = Abs(UPFC_Power.re) / PF; + QIdeal = UPFC_Power.im - sqrt(1 - PF * PF) * s; //This is the expected compensating reactive power + if(QIdeal > (KVARLim * 1000)) + QIdeal = KVARLim * 1000; + CurrIn = conjg(cdiv(cmplx(0, QIdeal), Vbin)); //Q in terms of current *** conjg + } + break; // Dual mode + case 3: + { + CurrIn = CZero; + Ctemp = conjg(cmul(cdiv(Vbout, Vbin), conjg((Sr0)[Cond - 1]))); //Balancing powers + Losses = CalcUPFCLosses(cabs(Vbin) / (VRef * 1000)); + + + CurrIn = cnegate(cmplx((Ctemp.re * Losses), Sr0[Cond - 1].im)); +// CurrIn = cnegate(cmplx(Losses * (Sr0)[Cond - 1].re, (Sr0)[Cond - 1].im)); // This change removes power balance, dangerous + (Sr1)[Cond - 1] = CurrIn; + if(SyncFlag) + // Starts Power Calculations to copensate the reactive power + { + UPFC_Power = CalcUPFCPowers(1, Cond); + s = Abs(UPFC_Power.re) / PF; + QIdeal = UPFC_Power.im - sqrt(1 - PF * PF) * s; //This is the expected compensating reactive power + if(QIdeal > (KVARLim * 1000)) + QIdeal = KVARLim * 1000; + CurrIn = cadd(conjg(cdiv(cmplx(0, QIdeal), Vbin)), (Sr1)[Cond - 1]); //Q in terms of current *** conjg + // This partial result is added to the one obtained previously to balance the control loop + } + } + break; // Two band reference Mode (Only Voltage control mode) + case 4: + { + if(SF2) // Normal control routine considering the dynamic reference + { + CurrIn = CZero; + Ctemp = conjg(cmul(cdiv(Vbout, Vbin), conjg((Sr0)[Cond - 1]))); //Balancing powers + Losses = CalcUPFCLosses(cabs(Vbin) / (VRefD * 1000)); + CurrIn = cnegate(cmplx((Ctemp.re * Losses), Sr0[Cond - 1].im)); +// CurrIn = cnegate(cmplx(Losses * (Sr0)[Cond - 1].re, (Sr0)[Cond - 1].im)); // This change removes power balance, dangerous + (Sr1)[Cond - 1] = CurrIn; + } + else + // Do nothing, aparently the input voltage is OK + { + CurrIn = cmplx(0, 0); + (Sr0)[Cond - 1] = CurrIn; + UPFC_Power = CZero; + } + } + break; // Two band reference mode (Dual control mode) + case 5: + { + if(SF2) + { + CurrIn = CZero; + Ctemp = conjg(cmul(cdiv(Vbout, Vbin), conjg((Sr0)[Cond - 1]))); //Balancing powers + Losses = CalcUPFCLosses(cabs(Vbin) / (VRefD * 1000)); + CurrIn = cnegate(cmplx((Ctemp.re * Losses), Sr0[Cond - 1].im)); +// CurrIn = cnegate(cmplx(Losses * (Sr0)[Cond - 1].re, (Sr0)[Cond - 1].im)); // This change removes power balance, dangerous + (Sr1)[Cond - 1] = CurrIn; + } + else + // Do nothing, aparently the input voltage is OK + { + CurrIn = CZero; + (Sr1)[Cond - 1] = CurrIn; + UPFC_Power = CZero; + } + //Always corrects PF + if(SyncFlag) + // Starts Power Calculations to compensate the reactive power + { + UPFC_Power = CalcUPFCPowers(1, Cond); + s = Abs(UPFC_Power.re) / PF; + QIdeal = UPFC_Power.im - sqrt(1 - PF * PF) * s; //This is the expected compensating reactive power + if(QIdeal > (KVARLim * 1000)) + QIdeal = KVARLim * 1000; + CurrIn = cadd(conjg(cdiv(cmplx(0, QIdeal), Vbin)), (Sr1)[Cond - 1]); //Q in terms of current *** conjg + // This partial result is added to the one obtained previously to balance the control loop + } + } + break; + default: + ; + break; + } + } + else + CurrIn = cmplx(0, 0); + } + result = CurrIn; + } + catch(...) + { + DoSimpleMsg(String("Error computing current for Isource.") + get_Name() + + ". Check specification. Aborting.", 334); + if(In_Redirect) + Redirect_Abort = true; + } + return result; +} +//=========================================================================== + + +/*Fill Up an array of injection currents*/ + +void TUPFCObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + { + Vbin = (with0->NodeV)[(NodeRef)[i - 1]]; //Gets voltage at the input of UPFC Cond i + Vbout = (with0->NodeV)[(NodeRef)[i + Fnphases - 1]]; //Gets voltage at the output of UPFC Cond i + } + else + { + Vbin = with0->VoltInActor1((NodeRef)[i - 1]); //Gets voltage at the input of UPFC Cond i + Vbout = with0->VoltInActor1((NodeRef)[i + Fnphases - 1]); //Gets voltage at the output of UPFC Cond i + } + +// These functions were modified to follow the UPFC Dynamic +// (Different from VSource) + (Curr)[i + Fnphases - 1] = OutCurr[i - 1]; + (Curr)[i - 1] = InCurr[i - 1]; + } + } +} + +//=========================================================================== +//| Checks if the monitored pf is out of range, returns true if so | +//=========================================================================== + +bool TUPFCObj::CheckPFStatus(int ActorID) +{ + double mypf, S; + complex MonPower; + bool result = false; + if (myElm != nullptr) + { + MonPower = myElm->Get_Power(1, ActorID); + S = sqrt(MonPower.re * MonPower.re + MonPower.im * MonPower.im); + mypf = MonPower.re / S; + mypf = abs(PF - mypf); // calculates the difference to the target + result = (mypf / PF) > Tol1; + } + return result; +} + +//=========================================================================== +//| Checks if the UPFC control needs an update, returns true if so | +//=========================================================================== + +bool TUPFCObj::CheckStatus(int ActorID) +{ + bool result = false; + int i = 0; + double Error = 0.0; + double TError = 0.0; + double VinMag = 0.0; + double RefH = 0.0; + double RefL = 0.0; + polar Vpolar = {}; + complex vtemp = {}; + complex CurrOut = {}; + result = false; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + UPFCON = true; + } + VinMag = cabs(Vbin); + if((VinMag > VHLimit) || (VinMag < VLLimit)) // Check Limits (Voltage) + { + UPFCON = false; + CurrOut = cmplx(0, 0); + } + else + // Limits OK + { + switch(ModeUPFC) + { + case 0: + { + // UPFC off, CurrOut = cmplx(0, 0) was not used + } + break; //UPFC as a voltage regulator + case 1: + { + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRef * 1000))); + if(Error > Tol1) + result = true; + } + break; + case 2: + result = CheckPFStatus(ActorID); + break; //UPFC as a phase angle regulator + //UPFC in Dual mode Voltage and Phase angle regulator + case 3: + { + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRef * 1000))); + if(Error > Tol1) + result = true; + else + result = CheckPFStatus(ActorID); + } + break; // Double reference control mode (only voltage control) + case 4: + { + Vpolar = ctopolar(Vbin); // Takes the input voltage to verify the operation + // Verifies if the Voltage at the input is out of the gap defined with VRef and VRef2 + RefH = (VRef * 1000) + (VRef * 1000 * Tol1); + RefL = (VRef2 * 1000) - (VRef2 * 1000 * Tol1); + if((Vpolar.mag > RefH) || (Vpolar.mag < RefL)) + // Sets the New reference by considering the value at the input of the device + { + if(Vpolar.mag > RefH) + VRefD = VRef; + else + { + if(Vpolar.mag < RefL) + VRefD = VRef2; + // Starts the control routine for voltage control only + } + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRefD * 1000))); + if(Error > Tol1) + result = true; + } + } + break; // Double reference control mode (Dual mode) + case 5: + { + Vpolar = ctopolar(Vbin); // Takes the input voltage to verify the operation + // Verifies if the Voltage at the input is out of the gap defined with VRef and VRef2 + RefH = (VRef * 1000) + (VRef * 1000 * Tol1); + RefL = (VRef2 * 1000) - (VRef2 * 1000 * Tol1); + if((Vpolar.mag > RefH) || (Vpolar.mag < RefL)) + // Sets the New reference by considering the value at the input of the device + { + if(Vpolar.mag > RefH) + VRefD = VRef; + else + { + if(Vpolar.mag < RefL) + VRefD = VRef2; + // Starts standard control (the same as Dual control mode) + } + Vpolar = ctopolar(Vbout); + Error = Abs(1 - Abs(Vpolar.mag / (VRefD * 1000))); + if(Error > Tol1) + result = true; // In case we need a control action + else + result = CheckPFStatus(ActorID); + } + } + break; + default: + ; + break; + } + } + return result; +} + + +//=========================================================================== +//| Uploads the calculated currents into memeory for further use | +//=========================================================================== + +void TUPFCObj::UploadCurrents(int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + OutCurr[i - 1] = GetOutputCurr(i, ActorID); + InCurr[i - 1] = GetinputCurr(i, ActorID); + } +} + +//=========================================================================== + +void TUPFCObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + ComputeVterminal(ActorID); + YPrim->MVmult(Curr, &(Vterminal[0])); // Current from Elements in System Y + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents +// Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = csub((Curr)[i - 1], (ComplexBuffer)[i - 1]); + } + } /*With*/ + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element.", 327); + } +} + + +//============================================================================= + +void TUPFCObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + complex C = {}; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + // Writeln(F,'VMag=',VMag:0:2); + WriteLn(f, "Z Matrix="); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + C = Z->GetElement(i, j); + Write(f, Format("%.8g +j %.8g ", C.re, C.im)); + } + WriteLn(f); + } + } +} + + +//============================================================================= + +void TUPFCObj::InitPropertyValues(int ArrayOffset) +{ + + + /*PropertyValue Allocated in DSSObject.Create*/ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,"0.24"); + Set_PropertyValue(4,"1"); + Set_PropertyValue(5,Format("%d", Round(ActiveCircuit[ActiveActor]->Fundamental))); + Set_PropertyValue(6,"3"); + Set_PropertyValue(7,"0.7540"); // 2mH inductance + Set_PropertyValue(8,"0.02"); + Set_PropertyValue(9,"1"); + Set_PropertyValue(10,"24"); + Set_PropertyValue(11,""); + inherited::InitPropertyValues(NumPropsThisClass); +} + +//============================================================================= + +String TUPFCObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = GetBus(1); + break; + case 2: + result = GetBus(2); + break; + case 3: + result = Format("%-.5g", VRef); + break; + case 4: + result = Format("%-.5g", PF); + break; + case 5: + result = Format("%-.5g", Freq); + break; + case 7: + result = Format("%-.5g", Xs); + break; + case 8: + result = Format("%-.5g", Tol1); + break; + case 9: + result = Format("%d", ModeUPFC); + break; + case 10: + result = Format("%-.5g", Vpqmax); + break; + case propLossCurve: + result = LossCurve; + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +/*Var + S:String; +*/ + +void TUPFCObj::MakePosSequence(int ActorID) +{ + + /* + S :='Phases=1 '; + S := S + Format('BasekV=%-.5g ', [kVbase/SQRT3]); + S := S + Format('R1=%-.5g ', [R1]); + S := S + Format('X1=%-.5g ', [X1]); + + Parser.CmdString := S; + Edit; + + inherited; + */ +} + +// ======================== BEGIN STATE VARIABLES =============================== + +int TUPFCObj::NumVariables() +{ + int result = 0; + result = NumUPFCVariables; + return result; +} + +void TUPFCObj::Set_Variable(int i, double Value) +{ + + // inherited; + switch(i) + { + case 1: + ModeUPFC = (int) Round(Value); + break; + case 2: + ; + break; // can't set this one -readonly + case 3: + ; + break; // can't set this one -readonly + case 4: + ; + break; // can't set this one -readonly + case 5: + ; + break; // can't set this one -readonly + case 6: + ; + break; // can't set this one -readonly + case 7: + ; + break; // can't set this one -readonly + case 8: + ; + break; // can't set this one -readonly + case 9: + ; + break; // can't set this one -readonly + case 10: + ; + break; // can't set this one -readonly + case 11: + (Sr0)[1 - 1].re = Value; + break; + case 12: + (Sr0)[1 - 1].im = Value; + break; + case 13: + (Sr1)[1 - 1].re = Value; + break; + case 14: + (Sr1)[1 - 1].im = Value; + break; + default: + ; + break; + } +} + +double TUPFCObj::Get_Variable(int i) +{ + double result = 0.0; + result = -1.0; + switch(i) + { + case 1: + result = (double) ModeUPFC; + break; + case 2: + result = cabs(IUPFC); + break; + case 3: + result = Vbin.re; + break; + case 4: + result = Vbin.im; + break; + case 5: + result = Vbout.re; + break; + case 6: + result = Vbout.im; + break; + case 7: + result = Losses; + break; + case 8: + result = UPFC_Power.re; + break; + case 9: + result = UPFC_Power.im; + break; + case 10: + result = QIdeal; + break; + case 11: + result = (Sr0)[1 - 1].re; + break; + case 12: + result = (Sr0)[1 - 1].im; + break; + case 13: + result = (Sr1)[1 - 1].re; + break; + case 14: + result = (Sr1)[1 - 1].im; + break; + default: + ; + break; + } + return result; +} + +void TUPFCObj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int stop = 0; + for(stop = NumUPFCVariables, i = 1; i <= stop; i++) + { + (States)[i - 1] = Get_Variable(i); + } +} + +String TUPFCObj::VariableName(int i) +{ + String result; + if(i < 1) + return result; // Someone goofed + switch(i) + { + case 1: + result = "ModeUPFC"; + break; + case 2: + result = "IUPFC"; + break; + case 3: + result = "Re{Vbin}"; + break; + case 4: + result = "Im{Vbin}"; + break; + case 5: + result = "Re{Vbout}"; + break; + case 6: + result = "Im{Vbout}"; + break; + case 7: + result = "Losses"; + break; + case 8: + result = "P_UPFC"; + break; + case 9: + result = "Q_UPFC"; + break; + case 10: + result = "Qideal"; + break; + case 11: + result = "Re{Sr0^[1]}"; + break; + case 12: + result = "Im{Sr0^[1]}"; + break; + case 13: + result = "Re{Sr1^[1]}"; + break; + case 14: + result = "Im{Sr1^[1]}"; + break; + default: + ; + break; + } + return result; +} + +// ======================== END STATE VARIABLES =============================== + + +void UPFC_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class UPFC_unit + { + public: + UPFC_unit() + { + //AssertSystemInitialization(); + UPFC_initialization(); + } + }; + UPFC_unit _UPFC_unit; + +} // namespace UPFC + + + + diff --git a/OpenDSSC/PCElements/UPFC.h b/OpenDSSC/PCElements/UPFC.h new file mode 100644 index 0000000..f4eca07 --- /dev/null +++ b/OpenDSSC/PCElements/UPFC.h @@ -0,0 +1,150 @@ +#ifndef UPFCH +#define UPFCH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "LoadShape.h" +#include "XYcurve.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Dynamics.h" +#include "Command.h" +#include "YMatrix.h" + + +namespace UPFC +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 7-6-2015 Created from VSOURCE + +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TUPFC : public PCClass::TPCClass +{ + friend class TUPFCObj; +public: + typedef PCClass::TPCClass inherited; +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); +public: + TUPFC(); + virtual ~TUPFC(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TUPFCObj : public PCElement::TPCElement +{ + friend class TUPFC; +public: + typedef PCElement::TPCElement inherited; +//private: + double VRef; //Expected vooltage in the output (only magnitude) + double PF; //Expected power factor (under revision) + double Xs; //Impedance of the series Xfmr + Ucomplex::pComplexArray Sr0; //Shift register for controller 1 + Ucomplex::pComplexArray Sr1; //Shift register for controller 2 + Ucomplex::complex Vbin; // Voltage at the input of the device + Ucomplex::complex Vbout; // Voltage at the output of the device + double Tol1; //Tolerance (dead band) specified for the controller 1 + double ERR0[6/*# range 1..6*/]; //Error controller 1 for Dual mode + double ZBase; + double Freq; + double VHLimit; // High limit for the input voltage in volts (default 300V) + double VLLimit; // Low limit for the input voltage in volts (default 125V) + double CLimit; // Limit for the maximum current in amperes + bool UPFCON; // Flag to indicate when the UPFC operation is out of boundaries + double VRef2; // Value for deadband's upper limit, it is calculated if tolerance is specified + double VRefD; // Dynamic reference for control modes 4 and 5 + double KVARLim; // kvar limit, defines the maximum amount of kvars that the UPFC can absorb + String MonElm; // Name of the monitored element to perform PF compensation + TDSSCktElement* myElm; // ref to the monitored element + + // some state vars for reporting + double Losses; + Ucomplex::complex IUPFC; + Ucomplex::complex UPFC_Power; + double QIdeal; + int ModeUPFC; + double Vpqmax; + bool SyncFlag; // Flag used to synchronize controllers in Dual mode + bool SF2; // Flag used to Synch control modes 4 and 5 + String LossCurve; //Losses curve name + XYCurve::TXYcurveObj* UPFCLossCurveObj; //Losses curve reference + Ucomplex::complex GetinputCurr(int Cond, int ActorID); + Ucomplex::complex GetOutputCurr(int Cond, int ActorID); + Ucomplex::complex CalcUPFCPowers(int ModeUP, int Cond); + double CalcUPFCLosses(double Vpu); +protected: + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); +public: + vector InCurr; + vector OutCurr; // for storing the input and output currents + Ucmatrix::TcMatrix* Z; // Base Frequency Series Z matrix + Ucmatrix::TcMatrix* Zinv; + double Vmag; + TUPFCObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TUPFCObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + + // Uploads the input/output currents when commanded by the controller - 09/02/2021 + void UploadCurrents(int ActorID); + bool CheckPFStatus(int ActorID); + bool CheckStatus(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual String VariableName(int i); + TUPFCObj(DSSClass::TDSSClass* ParClass); + TUPFCObj(String ClassName); + TUPFCObj(); +}; +extern TUPFCObj* ActiveUPFCObj; +extern TUPFC* UPFC_class; + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace UPFC + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace UPFC; +#endif + +#endif // UPFCH + + + + diff --git a/OpenDSSC/PCElements/VSConverter.cpp b/OpenDSSC/PCElements/VSConverter.cpp new file mode 100644 index 0000000..93e453b --- /dev/null +++ b/OpenDSSC/PCElements/VSConverter.cpp @@ -0,0 +1,776 @@ + +#pragma hdrstop + +#include "VSConverter.h" + +#include "Circuit.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace MyDSSClassDefs; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace VSConverter +{ + +TVSConverterObj::TVSConverterObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TVSConverterObj::TVSConverterObj(String ClassName) : inherited(ClassName) {} +TVSConverterObj::TVSConverterObj() {} + + +TVSConverterObj* ActiveVSConverterObj = nullptr; +const int NumPropsThisClass = 19; +const int VSC_FIXED = 0; +const int VSC_PACVAC = 1; +const int VSC_PACQAC = 2; +const int VSC_VDCVAC = 3; +const int VSC_VDCQAC = 4; + +// ===================================================== +// Class Methods +// ===================================================== + +TVSConverter::TVSConverter() +{ + ; + Class_Name = "VSConverter"; + DSSClassType = VS_CONVERTER + PC_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +TVSConverter::~TVSConverter() +{ + // inherited::Destroy(); +} + + +void TVSConverter::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); + AllocatePropertyArrays(); + PropertyName[1 - 1] = "phases"; + PropertyName[2 - 1] = "Bus1"; + PropertyName[3 - 1] = "kVac"; + PropertyName[4 - 1] = "kVdc"; + PropertyName[5 - 1] = "kW"; + PropertyName[6 - 1] = "Ndc"; + PropertyName[7 - 1] = "Rac"; + PropertyName[8 - 1] = "Xac"; + PropertyName[9 - 1] = "m0"; + PropertyName[10 - 1] = "d0"; + PropertyName[11 - 1] = "Mmin"; + PropertyName[12 - 1] = "Mmax"; + PropertyName[13 - 1] = "Iacmax"; + PropertyName[14 - 1] = "Idcmax"; + PropertyName[15 - 1] = "Vacref"; + PropertyName[16 - 1] = "Pacref"; + PropertyName[17 - 1] = "Qacref"; + PropertyName[18 - 1] = "Vdcref"; + PropertyName[19 - 1] = "VscMode"; + PropertyHelp[1 - 1] = "Number of AC plus DC conductors. Default is 4. AC phases numbered before DC conductors."; + PropertyHelp[2 - 1] = "Name of converter bus, containing both AC and DC conductors. Bus2 is always ground."; + PropertyHelp[3 - 1] = "Nominal AC line-neutral voltage in kV. Must be specified > 0."; + PropertyHelp[4 - 1] = "Nominal DC voltage in kV. Must be specified > 0."; + PropertyHelp[5 - 1] = "Nominal converter power in kW. Must be specified > 0."; + PropertyHelp[6 - 1] = "Number of DC conductors. Default is 1. DC conductors numbered after AC phases."; + PropertyHelp[7 - 1] = String("AC resistance (ohms) for the converter transformer, plus any series reactors. Default is 0.") + CRLF + + "Must be 0 for Vac control mode."; + PropertyHelp[8 - 1] = String("AC reactance (ohms) for the converter transformer, plus any series reactors. Default is 0.") + CRLF + + "Must be 0 for Vac control mode. Must be >0 for PacVac, PacQac or VacVdc control mode."; + PropertyHelp[9 - 1] = "Fixed or initial value of the modulation index. Default is 0.5."; + PropertyHelp[10 - 1] = "Fixed or initial value of the power angle in degrees. Default is 0."; + PropertyHelp[11 - 1] = "Minimum value of modulation index. Default is 0.1."; + PropertyHelp[12 - 1] = "Maximum value of modulation index. Default is 0.9."; + PropertyHelp[13 - 1] = "Maximum value of AC line current, per-unit of nominal. Default is 2."; + PropertyHelp[14 - 1] = "Maximum value of DC current, per-unit of nominal. Default is 2."; + PropertyHelp[15 - 1] = String("Reference AC line-to-neutral voltage, RMS Volts. Default is 0.") + CRLF + + "Applies to PacVac and VdcVac control modes, influencing m."; + PropertyHelp[16 - 1] = String("Reference total AC real power, Watts. Default is 0.") + CRLF + + "Applies to PacVac and PacQac control modes, influencing d."; + PropertyHelp[17 - 1] = String("Reference total AC reactive power, Vars. Default is 0.") + CRLF + + "Applies to PacQac and VdcQac control modes, influencing m."; + PropertyHelp[18 - 1] = String("Reference DC voltage, Volts. Default is 0.") + CRLF + + "Applies to VdcVac control mode, influencing d."; + PropertyHelp[19 - 1] = "Control Mode (Fixed|PacVac|PacQac|VdcVac|VdcQac). Default is Fixed."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); +} + +int TVSConverter::NewObject(const String ObjName) +{ + int result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TVSConverterObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +void TVSConverter::VscSetBus1(const String s) +{ + String S2; + int i = 0; + int dotpos = 0; + /*# with ActiveVSConverterObj do */ + { + auto with0 = ActiveVSConverterObj; + int stop = 0; + with0->SetBus(1, s); + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); + for(stop = with0->Fnphases, i = 1; i <= stop; i++) + { + S2 = S2 + ".0"; + } + with0->SetBus(2, S2); // default setting for Bus2=Bus1.0.0.0.0 + } +} + +int TVSConverter::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + String tok; + result = 0; + ActiveVSConverterObj = (TVSConverterObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveVSConverterObj); // use property to set this value + /*# with ActiveVSConverterObj do */ + { + auto with0 = ActiveVSConverterObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 350); + break; + case 1: + if(with0->Fnphases != Parser[ActorID]->MakeInteger_()) + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + with0->Set_Nconds(with0->Fnphases); + ActiveCircuit[ActorID]->Set_BusNameRedefined(true); + } + break; + case 2: + VscSetBus1(Param); + break; + case 3: + with0->FkVac = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->FkVdc = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->FkW = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->FNdc = Parser[ActorID]->MakeInteger_(); + break; + case 7: + with0->FRac = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->FXac = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->FM = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->FD = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->FMinM = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FMaxM = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->FMaxIac = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->FMaxIdc = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->FrefVac = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->FrefPac = Parser[ActorID]->MakeDouble_(); + break; + case 17: + with0->FrefQac = Parser[ActorID]->MakeDouble_(); + break; + case 18: + with0->FrefVdc = Parser[ActorID]->MakeDouble_(); + break; + case 19: + { + tok = UpperCase( Param.substr(4) ); + if(CompareStr( tok.substr(1), "F") == 0) + with0->FMode = VSC_FIXED; + else + { + if(CompareStr(tok, "PACV") == 0) + with0->FMode = VSC_PACVAC; + else + { + if(CompareStr(tok, "PACQ") == 0) + with0->FMode = VSC_PACQAC; + else + { + if(CompareStr(tok, "VDCV") == 0) + with0->FMode = VSC_VDCVAC; + else + { + if(CompareStr(tok, "VDCQ") == 0) + with0->FMode = VSC_VDCQAC; + else + with0->FMode = VSC_FIXED; + } + } + } + } + } + break; + default: + inherited::ClassEdit(ActiveVSConverterObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: + case 11: case 12: case 13: case 14: case 15: case 16: + with0->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +int TVSConverter::MakeLike(const String VSCName) +{ + int result = 0; + TVSConverterObj* OtherVSC = nullptr; + int i = 0; + result = 0; + OtherVSC = ((TVSConverterObj*) Find(VSCName)); + if(OtherVSC != nullptr) + /*# with ActiveVSConverterObj do */ + { + auto with0 = ActiveVSConverterObj; + int stop = 0; + if(with0->Fnphases != OtherVSC->Fnphases) + { + with0->Fnphases = OtherVSC->Fnphases; + with0->Fnterms = OtherVSC->Fnterms; + with0->Set_Nconds(with0->Fnphases); + with0->FNdc = OtherVSC->FNdc; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + with0->FkVac = OtherVSC->FkVac; + with0->FkVdc = OtherVSC->FkVdc; + with0->FkW = OtherVSC->FkW; + with0->FRac = OtherVSC->FRac; + with0->FXac = OtherVSC->FXac; + with0->FM = OtherVSC->FM; + with0->FD = OtherVSC->FD; + with0->FMinM = OtherVSC->FMinM; + with0->FMaxM = OtherVSC->FMaxM; + with0->FMaxIac = OtherVSC->FMaxIac; + with0->FMaxIdc = OtherVSC->FMaxIdc; + with0->FrefVac = OtherVSC->FrefVac; + with0->FrefPac = OtherVSC->FrefPac; + with0->FrefQac = OtherVSC->FrefQac; + with0->FrefVdc = OtherVSC->FrefVdc; + with0->FMode = OtherVSC->FMode; + } + with0->BaseFrequency = OtherVSC->BaseFrequency; + ClassMakeLike(OtherVSC); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherVSC->Get_PropertyValue(i)); + } + result = 1; + } // with + else + DoSimpleMsg(String("Error in VSConverter MakeLike: \"") + VSCName + + "\" Not Found.", 351); + return result; +} + +int TVSConverter::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TVSConverter.Init", -1); + result = 0; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// Object Methods +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TVSConverterObj::TVSConverterObj(TDSSClass* ParClass, const String FaultName) + : inherited(ParClass), + FkVac(1.0), + FkVdc(1.0), + FkW(1.0), + FM(0.5), + FD(0.0), + FRac(0.0), + FXac(0.0), + FrefVac(0.0), + FrefVdc(0.0), + FrefPac(0.0), + FrefQac(0.0), + FMinM(0.0), + FMaxM(0.0), + FMaxIac(0.0), + FMaxIdc(0.0), + FMode(0), + FNdc(0), + LastCurrents(nullptr) +{ + DSSObjType = ParClass->DSSClassType; + Set_Name(LowerCase(FaultName)); + LastCurrents = nullptr; + + // typically the first 3 "phases" are AC, and the last one is DC + Set_NPhases(4); + Fnconds = 4; + Set_NTerms(2); // two-terminal device, like the voltage source + FNdc = 1; + FMode = VSC_FIXED; + FRac = EPSILON; + FXac = 0.0; + FrefVac = 0.0; + FrefPac = 0.0; + FrefQac = 0.0; + FrefVdc = 0.0; + FMinM = 0.1; + FMaxM = 0.9; + FMaxIac = 2.0; + FMaxIdc = 2.0; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + +TVSConverterObj::~TVSConverterObj() +{ + free(LastCurrents); + //inherited::~TPCElement(); +} + + +void TVSConverterObj::RecalcElementData(int ActorID) +{ + int i = 0; + int stop = 0; + if((FRac == 0.0) && (FXac == 0.0)) + FRac = EPSILON; + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + LastCurrents = (pComplexArray)realloc(LastCurrents, sizeof(complex) * Yorder); + for(stop = Yorder, i = 1; i <= stop; i++) + { + (LastCurrents)[i - 1] = CZero; + } +} + +void TVSConverterObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + complex Value2 = {}; + double FreqMultiplier = 0.0; + int i = 0; +// build YPrim_Series non-zero for just the AC phases, and it will be diagonal + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + + // calculate the AC voltage source admittance + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + Value.re = FRac; + Value.im = FXac * FreqMultiplier; + Value = cinv(Value); + Value2 = cnegate(Value); + /*# with YPrim_Series do */ + { + auto with0 = YPrim_Series; + int stop = 0; + for(stop = (Fnphases - FNdc), i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } + } + YPrim->CopyFrom(YPrim_Series); + TDSSCktElement::CalcYPrim(ActorID); // may open some conductors + Set_YprimInvalid(ActorID,false); +} + +int TVSConverterObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + result = inherited::InjCurrents(ActorID); // Add into system array + return result; +} + +void TVSConverterObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + ComputeVterminal(ActorID); + // add the injection currents from both AC and DC nodes, to the + // currents from Yprim elements, which should be zero at the DC nodes + YPrim->MVmult(Curr, &(Vterminal[0])); + GetInjCurrents(&(ComplexBuffer[0]), ActorID); + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = csub((Curr)[i - 1], (ComplexBuffer)[i - 1]); + (LastCurrents)[i - 1] = (Curr)[i - 1]; + } + } + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element.", 327); + } +} + +void TVSConverterObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + complex Vmag = {}; + complex Vdc = {}; + complex Sphase = {}; + complex Stotal = {}; + double Pac = 0.0; + double Deg = 0.0; + double Idc = 0.0; + double Idclim = 0.0; + double Iaclim = 0.0; + double Itmag = 0.0; + int i = 0; + int Nac = 0; + + /* AC Voltage source injection currents given by this formula: + _ _ _ _ + |Iinj1| |Vsource | + | | = [Yprim] | | + |Iinj2| | 0 | + _ _ _ _ + */ + int stop = 0; + Nac = Fnphases - FNdc; + Idclim = FMaxIdc * FkW / FkVdc; + Iaclim = FMaxIac * FkW / FkVac / Nac; + + // obtain the terminal control quantities + ComputeVterminal(ActorID); + set_ITerminalUpdated(false, ActorID); + GetTerminalCurrents(&(Iterminal[0]), ActorID); +// for i := 1 to Nac do begin +// Itmag := cabs(Iterminal^[i]); +// if Itmag > Iaclim then begin +// Itmag := Iaclim / Itmag; +// Iterminal^[i].re := Iterminal^[i].re * Itmag; +// Iterminal^[i].im := Iterminal^[i].im * Itmag; +// end; +// end; + + // do the AC voltage source injection - dependent voltage sources kept in ComplexBuffer + Vdc = (Vterminal)[Fnphases - 1]; + if((Vdc.re == 0.0) && (Vdc.im == 0.0)) + Vdc.re = 1000.0 * FkVdc; + Vmag = cmulreal(Vdc, 0.353553 * FM); + RotatePhasorDeg(Vmag, 1.0, FD); + (ComplexBuffer)[1 - 1] = Vmag; + Deg = -360.0 / Nac; + for(stop = Nac, i = 2; i <= stop; i++) + { + RotatePhasorDeg(Vmag, 1.0, Deg); + (ComplexBuffer)[i - 1] = Vmag; + } + (ComplexBuffer)[Fnphases - 1] = CZero; + YPrim->MVmult(Curr, &(ComplexBuffer[0])); + + // calculate the converter AC power, exclusive of the losses, using LastCurrents + Stotal.re = 0.0; + Stotal.im = 0.0; + for(stop = Nac, i = 1; i <= stop; i++) + { +// Sphase := Cmul (ComplexBuffer^[i], Conjg(LastCurrents^[i])); + Sphase = cmul((ComplexBuffer)[i - 1], conjg((Iterminal)[i - 1])); + Stotal = cadd(Stotal, Sphase); + } + Pac = Stotal.re; +// Qac := Stotal.im; + if(Pac == 0.0) + Pac = 1000.0 * FkW; + + // DC current source injection + Idc = Pac / cabs(Vdc); + if(Idc > Idclim) + Idc = Idclim; + if(Idc < - Idclim) + Idc = -Idclim; + (Curr)[Fnphases - 1] = cmplx(Idc, 0.0); + (Curr)[2 * Fnphases - 1] = cmplx(-Idc, 0.0); + set_ITerminalUpdated(false, ActorID); +} + +void TVSConverterObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { Write(f, "~ "); Write(f, with0->PropertyName[1 - 1]); Write(f, L'='); WriteLn(f, Fnphases, 0); } + { Write(f, "~ "); Write(f, with0->PropertyName[2 - 1]); Write(f, L'='); WriteLn(f, Get_FirstBus()); } + { Write(f, "~ "); Write(f, with0->PropertyName[3 - 1]); Write(f, L'='); WriteLn(f, FkVac, 8, 1); } + { Write(f, "~ "); Write(f, with0->PropertyName[4 - 1]); Write(f, L'='); WriteLn(f, FkVdc, 8, 1); } + { Write(f, "~ "); Write(f, with0->PropertyName[5 - 1]); Write(f, L'='); WriteLn(f, FkW, 8, 1); } + { Write(f, "~ "); Write(f, with0->PropertyName[6 - 1]); Write(f, L'='); WriteLn(f, FNdc, 0); } + { Write(f, "~ "); Write(f, with0->PropertyName[7 - 1]); Write(f, L'='); WriteLn(f, FRac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[8 - 1]); Write(f, L'='); WriteLn(f, FXac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[9 - 1]); Write(f, L'='); WriteLn(f, FM, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[10 - 1]); Write(f, L'='); WriteLn(f, FD, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[11 - 1]); Write(f, L'='); WriteLn(f, FMinM, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[12 - 1]); Write(f, L'='); WriteLn(f, FMaxM, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[13 - 1]); Write(f, L'='); WriteLn(f, FMaxIac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[14 - 1]); Write(f, L'='); WriteLn(f, FMaxIdc, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[15 - 1]); Write(f, L'='); WriteLn(f, FrefVac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[16 - 1]); Write(f, L'='); WriteLn(f, FrefPac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[17 - 1]); Write(f, L'='); WriteLn(f, FrefQac, 0, 4); } + { Write(f, "~ "); Write(f, with0->PropertyName[18 - 1]); Write(f, L'='); WriteLn(f, FrefVdc, 0, 4); } + switch(FMode) + { + case VSC_FIXED: + { Write(f, "~ "); Write(f, (with0->PropertyName)[19 - 1]); WriteLn(f, "= Fixed"); } + break; + case VSC_PACVAC: + { Write(f, "~ "); Write(f, (with0->PropertyName)[19 - 1]); WriteLn(f, "= PacVac"); } + break; + case VSC_PACQAC: + { Write(f, "~ "); Write(f, (with0->PropertyName)[19 - 1]); WriteLn(f, "= PacQac"); } + break; + case VSC_VDCVAC: + { Write(f, "~ "); Write(f, (with0->PropertyName)[19 - 1]); WriteLn(f, "= VdcVac"); } + break; + case VSC_VDCQAC: + { Write(f, "~ "); Write(f, (with0->PropertyName)[19 - 1]); WriteLn(f, "= VdcQac"); } + break; + default: + ; + break; + } + for(stop = with0->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +void TVSConverterObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"4"); + Set_PropertyValue(2,GetBus(1)); + Set_PropertyValue(3,"1"); + Set_PropertyValue(4,"1"); + Set_PropertyValue(5,"1"); + Set_PropertyValue(6,"1"); + Set_PropertyValue(7,"0"); + Set_PropertyValue(8,"0"); + Set_PropertyValue(9,"0.5"); + Set_PropertyValue(10,"0"); + Set_PropertyValue(11,"0.1"); + Set_PropertyValue(12,"0.9"); + Set_PropertyValue(13,"0"); + Set_PropertyValue(14,"0"); + Set_PropertyValue(15,"0"); + Set_PropertyValue(16,"0"); + Set_PropertyValue(17,"0"); + Set_PropertyValue(18,"0"); + Set_PropertyValue(19,"FIXED"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +String TVSConverterObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = Format("%d", Get_NPhases()); + break; + case 2: + result = GetBus(1); + break; + case 3: + result = Format("%.8g", FkVac); + break; + case 4: + result = Format("%.8g", FkVdc); + break; + case 5: + result = Format("%.8g", FkW); + break; + case 6: + result = Format("%d", FNdc); + break; + case 7: + result = Format("%.8g", FRac); + break; + case 8: + result = Format("%.8g", FXac); + break; + case 9: + result = Format("%.8g", FM); + break; + case 10: + result = Format("%.8g", FD); + break; + case 11: + result = Format("%.8g", FMinM); + break; + case 12: + result = Format("%.8g", FMaxM); + break; + case 13: + result = Format("%.8g", FMaxIac); + break; + case 14: + result = Format("%.8g", FMaxIdc); + break; + case 15: + result = Format("%.8g", FrefVac); + break; + case 16: + result = Format("%.8g", FrefPac); + break; + case 17: + result = Format("%.8g", FrefQac); + break; + case 18: + result = Format("%.8g", FrefVdc); + break; + case 19: + switch(FMode) + { + case VSC_FIXED: + result = "Fixed"; + break; + case VSC_PACVAC: + result = "PacVac"; + break; + case VSC_PACQAC: + result = "PacQac"; + break; + case VSC_VDCVAC: + result = "VdcVac"; + break; + case VSC_VDCQAC: + result = "VdcQac"; + break; + default: + ; + break; + } + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +void TVSConverterObj::MakePosSequence(int ActorID) +{ + if(Fnphases != 2) + { + Parser[ActorID]->SetCmdString("Phases=2"); + Edit(ActorID); + Parser[ActorID]->SetCmdString("Ndc=1"); + Edit(ActorID); + } + TDSSCktElement::MakePosSequence(ActorID); +} + + + + +} // namespace VSConverter + + + + diff --git a/OpenDSSC/PCElements/VSConverter.h b/OpenDSSC/PCElements/VSConverter.h new file mode 100644 index 0000000..de5601d --- /dev/null +++ b/OpenDSSC/PCElements/VSConverter.h @@ -0,0 +1,111 @@ +#ifndef VSConverterH +#define VSConverterH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Arraydef.h" +#include "XYcurve.h" +#include "ParserDel.h" +#include "MyDSSClassDefs.h" +#include "DSSClassDefs.h" +#include "Dynamics.h" +#include "mathutil.h" +#include + + + + + +namespace VSConverter +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2013-2022, University of Pittsburgh + All rights reserved. + ---------------------------------------------------------- +*/ + +class TVSConverter : public PCClass::TPCClass +{ + friend class TVSConverterObj; +public: + typedef PCClass::TPCClass inherited; +private: + void VscSetBus1(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String VSCName); +public: + TVSConverter(); + virtual ~TVSConverter(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TVSConverterObj : public PCElement::TPCElement +{ + friend class TVSConverter; +public: + typedef PCElement::TPCElement inherited; +//private: + double FkVac; + double FkVdc; + double FkW; + double FM; + double FD; + double FRac; + double FXac; + double FrefVac; + double FrefVdc; + double FrefPac; + double FrefQac; + double FMinM; + double FMaxM; + double FMaxIac; + double FMaxIdc; + int FMode; + int FNdc; + Ucomplex::pComplexArray LastCurrents; // state memory for GetInjCurrents +public: + TVSConverterObj(DSSClass::TDSSClass* ParClass, const String FaultName); + virtual ~TVSConverterObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + + // these three functions make it a PCElement + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void MakePosSequence(int ActorID); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TVSConverterObj(DSSClass::TDSSClass* ParClass); + TVSConverterObj(String ClassName); + TVSConverterObj(); +}; +extern TVSConverterObj* ActiveVSConverterObj; + + +} // namespace VSConverter + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace VSConverter; +#endif + +#endif // VSConverterH + + + + diff --git a/OpenDSSC/PCElements/VSource.cpp b/OpenDSSC/PCElements/VSource.cpp new file mode 100644 index 0000000..8c382c4 --- /dev/null +++ b/OpenDSSC/PCElements/VSource.cpp @@ -0,0 +1,1668 @@ + + +#pragma hdrstop + +#include "VSource.h" + +#include "Circuit.h" +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace VSource +{ + +TVsourceObj::TVsourceObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TVsourceObj::TVsourceObj(String ClassName) : inherited(ClassName) {} +TVsourceObj::TVsourceObj() {} + + +TVsourceObj* ActiveVsourceObj = nullptr; +const int NumPropsThisClass = 31; +complex CDoubleOne = {}; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TVsource::TVsource() +{ + ; + Class_Name = "Vsource"; + DSSClassType = SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + VSourceClass[ActiveActor] = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TVsource::~TVsource() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TVsource::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "basekv"; + PropertyName[3 - 1] = "pu"; + PropertyName[4 - 1] = "angle"; + PropertyName[5 - 1] = "frequency"; + PropertyName[6 - 1] = "phases"; + PropertyName[7 - 1] = "MVAsc3"; + PropertyName[8 - 1] = "MVAsc1"; + PropertyName[9 - 1] = "x1r1"; + PropertyName[10 - 1] = "x0r0"; + PropertyName[11 - 1] = "Isc3"; + PropertyName[12 - 1] = "Isc1"; + PropertyName[13 - 1] = "R1"; + PropertyName[14 - 1] = "X1"; + PropertyName[15 - 1] = "R0"; + PropertyName[16 - 1] = "X0"; + PropertyName[17 - 1] = "ScanType"; + PropertyName[18 - 1] = "Sequence"; + PropertyName[19 - 1] = "bus2"; + PropertyName[20 - 1] = "Z1"; + PropertyName[21 - 1] = "Z0"; + PropertyName[22 - 1] = "Z2"; + PropertyName[23 - 1] = "puZ1"; + PropertyName[24 - 1] = "puZ0"; + PropertyName[25 - 1] = "puZ2"; + PropertyName[26 - 1] = "baseMVA"; + PropertyName[27 - 1] = "Yearly"; + PropertyName[28 - 1] = "Daily"; + PropertyName[29 - 1] = "Duty"; + PropertyName[30 - 1] = "Model"; + PropertyName[31 - 1] = "puZideal"; + + + // define Property help values + PropertyHelp[1 - 1] = String("Name of bus to which the main terminal (1) is connected.") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3" + + CRLF + + CRLF + + "The VSOURCE object is a two-terminal voltage source (thevenin equivalent). " + + "Bus2 defaults to Bus1 with all phases connected to ground (node 0) unless previously specified. This is a Yg connection. " + + "If you want something different, define the Bus2 property ezplicitly."; + PropertyHelp[2 - 1] = "Base Source kV, usually phase-phase (L-L) unless you are making a positive-sequence model or 1-phase model " + "in which case, it will be phase-neutral (L-N) kV."; + PropertyHelp[3 - 1] = String("Per unit of the base voltage that the source is actually operating at.") + CRLF + + "\"pu=1.05\""; + PropertyHelp[4 - 1] = "Phase angle in degrees of first phase: e.g.,Angle=10.3"; + PropertyHelp[5 - 1] = "Source frequency. Defaults to system default base frequency."; + PropertyHelp[6 - 1] = "Number of phases. Defaults to 3."; + PropertyHelp[7 - 1] = "MVA Short circuit, 3-phase fault. Default = 2000. " + "Z1 is determined by squaring the base kv and dividing by this value. " + "For single-phase source, this value is not used."; + PropertyHelp[8 - 1] = "MVA Short Circuit, 1-phase fault. Default = 2100. " + "The \"single-phase impedance\", Zs, is determined by squaring the base kV and dividing by this value. " + "Then Z0 is determined by Z0 = 3Zs - 2Z1. For 1-phase sources, Zs is used directly. " + "Use X0R0 to define X/R ratio for 1-phase source."; + PropertyHelp[9 - 1] = "Positive-sequence X/R ratio. Default = 4."; + PropertyHelp[10 - 1] = "Zero-sequence X/R ratio.Default = 3."; + PropertyHelp[11 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "3-phase short circuit current, amps. Default is 10000."; + PropertyHelp[12 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "single-phase short circuit current, amps. Default is 10500."; + PropertyHelp[13 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "Positive-sequence resistance, ohms. Default is 1.65."; + PropertyHelp[14 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "Positive-sequence reactance, ohms. Default is 6.6."; + PropertyHelp[15 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "Zero-sequence resistance, ohms. Default is 1.9."; + PropertyHelp[16 - 1] = String("Alternate method of defining the source impedance. ") + CRLF + + "Zero-sequence reactance, ohms. Default is 5.7."; + PropertyHelp[17 - 1] = "{pos*| zero | none} Maintain specified sequence for harmonic solution. Default is positive sequence. " + "Otherwise, angle between phases rotates with harmonic."; + PropertyHelp[18 - 1] = "{pos*| neg | zero} Set the phase angles for the specified symmetrical component sequence for non-harmonic solution modes. " + "Default is positive sequence. "; + PropertyHelp[19 - 1] = String("Name of bus to which 2nd terminal is connected.") + CRLF + + "bus2=busname" + + CRLF + + "bus2=busname.1.2.3" + + CRLF + + CRLF + + "Default is Bus1.0.0.0 (grounded wye connection)"; + PropertyHelp[20 - 1] = String("Positive-sequence equivalent source impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z1=[1, 2 - 1] ! represents 1 + j2 " + + CRLF + + CRLF + + "If defined, Z1, Z2, and Z0 are used to define the impedance matrix of the VSOURCE. " + + "Z1 MUST BE DEFINED TO USE THIS OPTION FOR DEFINING THE MATRIX." + + CRLF + + CRLF + + "Side Effect: Sets Z2 and Z0 to same values unless they were previously defined."; + PropertyHelp[21 - 1] = String("Zero-sequence equivalent source impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z0=[3, 4 - 1] ! represents 3 + j4 " + + CRLF + + CRLF + + "Used to define the impedance matrix of the VSOURCE if Z1 is also specified. " + + CRLF + + CRLF + + "Note: Z0 defaults to Z1 if it is not specifically defined. "; + PropertyHelp[22 - 1] = String("Negative-sequence equivalent source impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z2=[1, 2 - 1] ! represents 1 + j2 " + + CRLF + + CRLF + + "Used to define the impedance matrix of the VSOURCE if Z1 is also specified. " + + CRLF + + CRLF + + "Note: Z2 defaults to Z1 if it is not specifically defined. If Z2 is not equal to Z1, the impedance matrix is asymmetrical."; + PropertyHelp[23 - 1] = "2-element array: e.g., [1 2 - 1]. An alternate way to specify Z1. See Z1 property. Per-unit positive-sequence impedance on base of Vsource BasekV and BaseMVA."; + PropertyHelp[24 - 1] = "2-element array: e.g., [1 2 - 1]. An alternate way to specify Z0. See Z0 property. Per-unit zero-sequence impedance on base of Vsource BasekV and BaseMVA."; + PropertyHelp[25 - 1] = "2-element array: e.g., [1 2 - 1]. An alternate way to specify Z2. See Z2 property. Per-unit negative-sequence impedance on base of Vsource BasekV and BaseMVA."; + PropertyHelp[26 - 1] = "Default value is 100. Base used to convert values specifiied with puZ1, puZ0, and puZ2 properties to ohms on kV base specified by BasekV property."; + PropertyHelp[27 - 1] = String("LOADSHAPE object to use for the per-unit voltage for YEARLY-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual L-N kV.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Is set to the Daily load shape when Daily is defined. The daily load shape is repeated in this case. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[28 - 1] = String("LOADSHAPE object to use for the per-unit voltage for DAILY-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual L-N kV.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Sets Yearly curve if it is not already defined. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[29 - 1] = String("LOADSHAPE object to use for the per-unit voltage for DUTYCYCLE-mode simulations. Set the Mult property of the LOADSHAPE " "to the pu curve. Qmult is not used. If UseActual=Yes then the Mult curve should be actual L-N kV.") + CRLF + + CRLF + + "Must be previously defined as a LOADSHAPE object. " + + CRLF + + CRLF + + "Defaults to Daily load shape when Daily is defined. " + + "Set to NONE to reset to no loadahape for Yearly mode. " + + "The default is no variation."; + PropertyHelp[30 - 1] = "{Thevenin* | Ideal} Specifies whether the Vsource is to be considered a Thevenin short circuit model or a quasi-ideal voltage source. If Thevenin, the Vsource uses the impedances defined for all calculations. " + "If \"Ideal\", the model uses a small impedance on the diagonal of the impedance matrix for the fundamental base frequency power flow only. Then switches to actual Thevenin model for other frequencies. "; + PropertyHelp[31 - 1] = "2-element array: e.g., [1 2 - 1]. The pu impedance to use for the quasi-ideal voltage source model. Should be a very small impedances. Default is [1e-6, 0.001 - 1]. Per-unit impedance on base of Vsource BasekV and BaseMVA. " + "If too small, solution may not work. Be sure to check the voltage values and powers."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1] = "Name of harmonic spectrum for this source. Default is \"defaultvsource\", which is defined when the DSS starts."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TVsource::NewObject(const String ObjName) +{ + int result = 0; + // Make a new voltage source and add it to Vsource class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TVsourceObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TVsource::VsourceSetBus1(const String s) +{ + String S2; + int i = 0; + int dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveVsourceObj do */ + { + auto with0 = ActiveVsourceObj; + ( with0 )->SetBus(1, s); + if(!with0->Bus2Defined) // Default Bus2 to zero node of Bus1. (Grounded-Y connection) + + // Strip node designations from S + { + int stop = 0; + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); // copy up to Dot + for(stop = with0->Fnphases, i = 1; i <= stop; i++) + { + S2 = S2 + ".0"; + } // append series of ".0"'s + with0->SetBus(2, S2); // default setting for Bus2 + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TVsource::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + complex Ztemp = {}; + // continue parsing with contents of Parser + ActiveVsourceObj = (TVsourceObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveVsourceObj); + result = 0; + /*# with ActiveVsourceObj do */ + { + auto with0 = ActiveVsourceObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"VSource." + + with0->get_Name() + + "\"", 320); + break; + case 1: + VsourceSetBus1(Param); + break; // special handling of Bus 1 + case 2: + with0->kVBase = Parser[ActorID]->MakeDouble_(); + break; // basekv + case 3: + with0->PerUnit = Parser[ActorID]->MakeDouble_(); + break; // pu + case 4: + with0->Angle = Parser[ActorID]->MakeDouble_(); + break; // Ang + case 5: + with0->SrcFrequency = Parser[ActorID]->MakeDouble_(); + break; // freq + case 6: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + } + break; + case 7: + with0->MVAsc3 = Parser[ActorID]->MakeDouble_(); + break; // MVAsc3 + case 8: + with0->MVAsc1 = Parser[ActorID]->MakeDouble_(); + break; // MVAsc1 + case 9: + with0->X1R1 = Parser[ActorID]->MakeDouble_(); + break; // X1/R1 + case 10: + with0->X0R0 = Parser[ActorID]->MakeDouble_(); + break; // X0/R0 + case 11: + with0->Isc3 = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->Isc1 = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->R1 = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->X1 = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->R0 = Parser[ActorID]->MakeDouble_(); + break; + case 16: + with0->X0 = Parser[ActorID]->MakeDouble_(); + break; + case 17: + switch(UpperCase(Param)[1]) + { + case L'P': + with0->ScanType = 1; + break; + case L'Z': + with0->ScanType = 0; + break; + case L'N': + with0->ScanType = -1; + break; + default: + DoSimpleMsg(String("Unknown Scan Type for \"") + Class_Name + + "." + + with0->get_Name() + + "\": " + + Param, 321); + break; + } + break; + case 18: + switch(UpperCase(Param)[1]) + { + case L'P': + with0->SequenceType = 1; + break; + case L'Z': + with0->SequenceType = 0; + break; + case L'N': + with0->SequenceType = -1; + break; + default: + DoSimpleMsg(String("Unknown Sequence Type for \"") + Class_Name + + "." + + with0->get_Name() + + "\": " + + Param, 321); + break; + } + break; + case 19: + with0->SetBus(2, Param); + break; + case 20: + Ztemp = InterpretComplex(Param); + break; + case 21: + Ztemp = InterpretComplex(Param); + break; + case 22: + Ztemp = InterpretComplex(Param); + break; + case 23: + with0->puZ1 = InterpretComplex(Param); + break; + case 24: + with0->puZ0 = InterpretComplex(Param); + break; + case 25: + with0->puZ2 = InterpretComplex(Param); + break; + case 26: + with0->BaseMVA = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->YearlyShape = Param; + break; + case 28: + with0->DailyShape = Param; + break; + case 29: + with0->DutyShape = Param; + break; + case 30: + with0->IsQuasiIdeal = with0->InterpretSourceModel(Param); + break; + case 31: + with0->puZideal = InterpretComplex(Param); + break; + default: + inherited::ClassEdit(ActiveVsourceObj, ParamPointer - NumPropsThisClass); + break; + } + switch(ParamPointer) + { + case 20: + { + with0->R1 = Ztemp.re; + with0->X1 = Ztemp.im; + with0->Z1Specified = true; + // default values for Z2, Z0 + if(!with0->Z2Specified) + { + with0->R2 = with0->R1; + with0->X2 = with0->X1; + } + if(!with0->Z0Specified) + { + with0->R0 = with0->R1; + with0->X0 = with0->X1; + } + } + break; + case 21: + { + with0->R0 = Ztemp.re; + with0->X0 = Ztemp.im; + with0->Z0Specified = true; + } + break; + case 22: + { + with0->R2 = Ztemp.re; + with0->X2 = Ztemp.im; + with0->Z2Specified = true; + } + break; + case 23: + { + with0->puZ1Specified = true; + // default values for Z2, Z0 + if(!with0->puZ2Specified) + { + with0->puZ2 = with0->puZ1; + } + if(!with0->puZ0Specified) + { + with0->puZ0 = with0->puZ1; + } + } + break; + case 24: + with0->puZ0Specified = true; + break; + case 25: + with0->puZ2Specified = true; + break; + /*Set shape objects; returns nil if not valid*/ + /*Sets the kW and kvar properties to match the peak kW demand from the Loadshape*/ + case 27: + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + break; + case 28: + { + with0->DailyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyShape)); + /*If Yearly load shape is not yet defined, make it the same as Daily*/ + if(with0->YearlyShapeObj == nullptr) + with0->YearlyShapeObj = with0->DailyShapeObj; + } + break; + case 29: + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + break; + default: + ; + break; + } + switch(ParamPointer) + { + case 13: + with0->R2 = with0->R1; + break; + case 14: + with0->X2 = with0->X1; + break; + default: + ; + break; + } + // Set the Z spec type switch depending on which was specified. + switch(ParamPointer) + { + case 7: case 8: + with0->ZSpecType = 1; + break; // MVAsc + case 11: case 12: + with0->ZSpecType = 2; + break; // Isc + case 13: case 14: case 15: case 16: + with0->ZSpecType = 3; + break; // Specified in Ohms + case 19: + with0->Bus2Defined = true; + break; + case 20: case 21: case 22: case 23: case 24: case 25: + with0->ZSpecType = 3; + break; + default: + ; + break; + } + switch(ParamPointer) + { + case 2: + with0->ZBase = Sqr(with0->kVBase) / with0->BaseMVA; + break; + case 23: + { + with0->Z1Specified = true; + with0->puZ1Specified = true; + } + break; + case 24: + with0->puZ0Specified = true; + break; + case 25: + with0->puZ2Specified = true; + break; + case 26: + with0->ZBase = Sqr(with0->kVBase) / with0->BaseMVA; + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TVsource::MakeLike(const String OtherSource) +{ + int result = 0; + TVsourceObj* OtherVSource = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherVSource = ((TVsourceObj*) Find(OtherSource)); + if(OtherVSource != nullptr) + /*# with ActiveVsourceObj do */ + { + auto with0 = ActiveVsourceObj; + int stop = 0; + if(with0->Fnphases != OtherVSource->Fnphases) + { + with0->Set_NPhases(OtherVSource->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + with0->Z = new TcMatrix(with0->Fnphases); + with0->Zinv = new TcMatrix(with0->Fnphases); + } + with0->Z->CopyFrom(OtherVSource->Z); + // Zinv.CopyFrom(OtherLine.Zinv); + with0->Vmag = OtherVSource->Vmag; + with0->kVBase = OtherVSource->kVBase; + with0->BaseMVA = OtherVSource->BaseMVA; + with0->PerUnit = OtherVSource->PerUnit; + with0->Angle = OtherVSource->Angle; + with0->MVAsc3 = OtherVSource->MVAsc3; + with0->MVAsc1 = OtherVSource->MVAsc1; + with0->ScanType = OtherVSource->ScanType; + with0->SequenceType = OtherVSource->SequenceType; + with0->SrcFrequency = OtherVSource->SrcFrequency; + with0->ZSpecType = OtherVSource->ZSpecType; + with0->R1 = OtherVSource->R1; + with0->X1 = OtherVSource->X1; + with0->R2 = OtherVSource->R2; + with0->X2 = OtherVSource->X2; + with0->R0 = OtherVSource->R0; + with0->X0 = OtherVSource->X0; + with0->X1R1 = OtherVSource->X1R1; + with0->X0R0 = OtherVSource->X0R0; + with0->BaseMVA = OtherVSource->BaseMVA; + with0->puZ1 = OtherVSource->puZ1; + with0->puZ0 = OtherVSource->puZ0; + with0->puZ2 = OtherVSource->puZ2; + with0->ZBase = OtherVSource->ZBase; + with0->Bus2Defined = OtherVSource->Bus2Defined; + with0->Z1Specified = OtherVSource->Z1Specified; + with0->Z2Specified = OtherVSource->Z2Specified; + with0->Z0Specified = OtherVSource->Z0Specified; + with0->puZ0Specified = OtherVSource->puZ0Specified; + with0->puZ1Specified = OtherVSource->puZ1Specified; + with0->puZ2Specified = OtherVSource->puZ2Specified; + with0->IsQuasiIdeal = OtherVSource->IsQuasiIdeal; + with0->puZideal = OtherVSource->puZideal; + + /*Loadshape stuff*/ + with0->ShapeIsActual = OtherVSource->ShapeIsActual; + with0->DailyShape = OtherVSource->DailyShape; + with0->DailyShapeObj = OtherVSource->DailyShapeObj; + with0->DutyShape = OtherVSource->DutyShape; + with0->DutyShapeObj = OtherVSource->DutyShapeObj; + with0->YearlyShape = OtherVSource->YearlyShape; + with0->YearlyShapeObj = OtherVSource->YearlyShapeObj; + ClassMakeLike(OtherVSource); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0->FPropertyValue)[i - 1] = (OtherVSource->FPropertyValue)[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Vsource MakeLike: \"") + OtherSource + + "\" Not Found.", 322); + return result; +} + +//---------------------------------------------------------------------------- + +int TVsource::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TVsource.Init", -1); + result = 0; + return result; +} + +//============================================================================= + +TVsourceObj::TVsourceObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + MVAsc3(2000.0), + MVAsc1(2100.0), + Isc3(10000.0), + Isc1(10540.0), + ZSpecType(0), + R1(0.0), + X1(0.0), + R2(0.0), + X2(0.0), + R0(0.0), + X0(0.0), + X1R1(0.0), + X0R0(0.0), + BaseMVA(0.0), + ZBase(0.0), + Bus2Defined(false), + Z1Specified(false), + puZ1Specified(false), + puZ0Specified(false), + puZ2Specified(false), + Z2Specified(false), + Z0Specified(false), + IsQuasiIdeal(false), + ScanType(0), + SequenceType(0), + ShapeIsActual(false), + Z(nullptr), + Zinv(nullptr), + Vmag(0.0), + kVBase(0.0), + PerUnit(0.0), + Angle(0.0), + SrcFrequency(0.0), + DailyShapeObj(nullptr), + DutyShapeObj(nullptr), + YearlyShapeObj(nullptr) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; //SOURCE + NON_PCPD_ELEM; // Don't want this in PC Element List + Set_NPhases(3); + Fnconds = 3; + Set_NTerms(2); // Now a 2-terminal device + Z = nullptr; + Zinv = nullptr; + /*Basefrequency := 60.0;*/ // set in base class + ZSpecType = 1; // default to MVAsc + R1 = 1.65; + X1 = 6.6; + R2 = R1; + X2 = X1; + R0 = 1.9; + X0 = 5.7; + X1R1 = 4.0; + X0R0 = 3.0; + PerUnit = 1.0; // per unit voltage, not impedance + kVBase = 115.0; + BaseMVA = 100.0; + ZBase = Sqr(kVBase) / BaseMVA; + SrcFrequency = BaseFrequency; + Angle = 0.0; + ScanType = 1; + SequenceType = 1; + Bus2Defined = false; + Z1Specified = false; + Z2Specified = false; + Z0Specified = false; + puZ0Specified = false; + puZ2Specified = false; + puZ1Specified = false; + IsQuasiIdeal = false; // you have to turn this flag ON + puZideal = cmplx(1.0e-6, 0.001); // default ideal source pu impedance + Spectrum = "defaultvsource"; + ShapeIsActual = false; + YearlyShape = ""; + YearlyShapeObj = nullptr; // IF YearlyShapeobj = nil THEN the Vsource alway stays nominal + DailyShape = ""; + DailyShapeObj = nullptr; // IF DaillyShapeobj = nil THEN the Vsource alway stays nominal + DutyShape = ""; + DutyShapeObj = nullptr; // IF DutyShapeobj = nil THEN the Vsource alway stays nominal + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + + +//============================================================================= + +TVsourceObj::~TVsourceObj() +{ + delete Z; + delete Zinv; + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + + +// interpret Model type + +bool TVsourceObj::InterpretSourceModel(const String s) +{ + bool result = false; + if(CompareTextShortest(s, "ideal") == 0) + result = true; + else + result = false; + return result; +} + +//============================================================================= + +void TVsourceObj::RecalcElementData(int ActorID) +{ + complex Zs = {}; + complex ZM = {}; + complex Z1 = {}; + complex Z2 = {}; + complex Z0 = {}; + complex Value = {}; + complex Value1 = {}; + complex Value2 = {}; + complex Calpha1 = {}; + complex Calpha2 = {}; + int i = 0; + int j = 0; + double Factor = 0.0; + double Rs = 0.0; + double Xs = 0.0; + double Rm = 0.0; + double XM = 0.0; + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + + // For a Source, nphases = ncond, for now + Z = new TcMatrix(Fnphases); + Zinv = new TcMatrix(Fnphases); + if(Fnphases == 1) + Factor = 1.0; + else + Factor = SQRT3; + Rs = 0.0; + Rm = 0.0; + Xs = 0.1; + XM = 0.0; + + /*Calculate the short circuit impedance and make all other spec types agree*/ + switch(ZSpecType) + { + case 1: // MVAsc + { + X1 = Sqr(kVBase) / MVAsc3 / sqrt(1.0L + 1.0L / Sqr(X1R1)); + // Xs := Sqr(KvBase) / MVAsc1/sqrt(1.0 + 1.0/Sqr(X0R0)); // Approx + R1 = X1 / X1R1; + R2 = R1; // default Z2 = Z1 + X2 = X1; + Isc3 = MVAsc3 * 1000.0 / (SQRT3 * kVBase); + Isc1 = MVAsc1 * 1000.0 / (Factor * kVBase); + + // Compute R0, X0 + R0 = QuadSolver((1.0L + Sqr(X0R0)), (4.0 * (R1 + X1 * X0R0)), (4.0 * (R1 * R1 + X1 * X1) - Sqr(3.0 * kVBase * 1000.0 / Factor / Isc1))); + X0 = R0 * X0R0; + + // for Z matrix + Xs = (2.0 * X1 + X0) / 3.0; + Rs = (2.0 * R1 + R0) / 3.0; + Rm = (R0 - R1) / 3.0; + XM = (X0 - X1) / 3.0; + } + break; // Isc + case 2: + { + MVAsc3 = SQRT3 * kVBase * Isc3 / 1000.0; + MVAsc1 = Factor * kVBase * Isc1 / 1000.0; + X1 = Sqr(kVBase) / MVAsc3 / sqrt(1.0L + 1.0L / Sqr(X1R1)); + R1 = X1 / X1R1; + R2 = R1; // default Z2 = Z1 + X2 = X1; + // Compute R0, X0 + R0 = QuadSolver((1.0L + Sqr(X0R0)), (4.0 * (R1 + X1 * X0R0)), (4.0 * (R1 * R1 + X1 * X1) - Sqr(3.0 * kVBase * 1000.0 / Factor / Isc1))); + X0 = R0 * X0R0; + + // for Z matrix + Xs = (2.0 * X1 + X0) / 3.0; + Rs = (2.0 * R1 + R0) / 3.0; + Rm = (R0 - R1) / 3.0; + XM = (X0 - X1) / 3.0; + } + break; // Z1, Z2, Z0 Specified + + // Compute Z1, Z2, Z0 in ohms if Z1 is specified in pu + case 3: + { + if(puZ1Specified) + { + R1 = puZ1.re * ZBase; + X1 = puZ1.im * ZBase; + R2 = puZ2.re * ZBase; + X2 = puZ2.im * ZBase; + R0 = puZ0.re * ZBase; + X0 = puZ0.im * ZBase; + } + + // Compute equivalent Isc3, Isc1, MVAsc3, MVAsc1 values; + Isc3 = kVBase * 1000.0 / SQRT3 / cabs(cmplx(R1, X1)); + + // compute nominal values for case where Z1=Z2 + // we won't necessarily use it to build Yprim matrix if Z2 <> Z1 + if(Fnphases == 1) // Force Z0 and Z2 to be Z1 so Zs is same as Z1 + { + R0 = R1; + X0 = X1; + R2 = R1; + X2 = X1; + } + Rs = (2.0 * R1 + R0) / 3.0; + Xs = (2.0 * X1 + X0) / 3.0; + Isc1 = kVBase * 1000.0 / Factor / cabs(cmplx(Rs, Xs)); + MVAsc3 = SQRT3 * kVBase * Isc3 / 1000.0; + MVAsc1 = Factor * kVBase * Isc1 / 1000.0; + XM = Xs - X1; + Rs = (2.0 * R1 + R0) / 3.0; + Rm = (R0 - R1) / 3.0; + } + break; + default: + ; + break; + } + + /*Update property Value array*/ + /* Don't change a specified value; only computed ones*/ + if((R1 == R2) && (X1 == X2)) + // Symmetric Matrix Case + { + int stop = 0; + Zs = cmplx(Rs, Xs); + ZM = cmplx(Rm, XM); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + Z->SetElement(i, i, Zs); + for(stop1 = i - 1, j = 1; j <= stop1; j++) + { + Z->SetElemsym(i, j, ZM); + } + } + } + else + + // Asymmetric Matrix case where Z2 <> Z1 + { + int stop = 0; + Z1 = cmplx(R1, X1); + Z2 = cmplx(R2, X2); + Z0 = cmplx(R0, X0); + + // Diagonals (all the same) + Value = cadd(Z2, cadd(Z1, Z0)); // Z1 + Z2 + Z0 + Value = cdivreal(Value, 3.0); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Z->SetElement(i, i, Value); + } + + // Off-Diagonals + if(Fnphases == 3) // otherwise undefined + + + // There are two possible off-diagonal elements if Z1 <> Z2 + // Calpha is defined as 1 /_ -120 instead of 1 /_ 120 + { + Calpha1 = conjg(CALPHA); // Change Calpha to agree with textbooks + Calpha2 = cmul(Calpha1, Calpha1); // Alpha squared = 1 /_ 240 = 1/_-120 + //(Z0 + aZ1 + a2 Z2)/3 + Value2 = cadd(cmul(Calpha2, Z2), cadd(cmul(Calpha1, Z1), Z0)); + //(Z0 + a2 Z1 + aZ2)/3 + Value1 = cadd(cmul(Calpha2, Z1), cadd(cmul(Calpha1, Z2), Z0)); + // Apply 1/3 ... + Value1 = cdivreal(Value1, 3.0); + Value2 = cdivreal(Value2, 3.0); + /*# with Z do */ + { + auto with0 = Z; + //Lower Triangle + with0->SetElement(2, 1, Value1); + with0->SetElement(3, 1, Value2); + with0->SetElement(3, 2, Value1); + //Upper Triangle + with0->SetElement(1, 2, Value2); + with0->SetElement(1, 3, Value1); + with0->SetElement(2, 3, Value2); + } + } + } + + // if not specified, compute a value for for puZ1 for display in formedit + if(!(puZ1Specified || puZ0Specified || puZ2Specified) && (ZBase > 0.0)) + { + puZ1.re = R1 / ZBase; + puZ1.im = X1 / ZBase; + puZ2.re = R2 / ZBase; + puZ2.im = X2 / ZBase; + puZ0.re = R0 / ZBase; + puZ0.im = X0 / ZBase; + } + switch(Fnphases) + { + case 1: + Vmag = kVBase * PerUnit * 1000.0; + break; + default: + Vmag = kVBase * PerUnit * 1000.0 / 2.0 / sin((180.0 / Fnphases) * DSSGlobals::PI / 180.0L); + break; + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + { + DoSimpleMsg(String("Spectrum Object \"") + Spectrum + + "\" for Device Vsource." + + get_Name() + + " Not Found.", 324); + } + + /*Now check for errors. If any of these came out nil and the string was not nil, give warning*/ + if(CompareText(YearlyShape, "none") == 0) + YearlyShape = ""; + if(CompareText(DailyShape, "none") == 0) + DailyShape = ""; + if(CompareText(DutyShape, "none") == 0) + DutyShape = ""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Vsource Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 34583); + } + if(DailyShapeObj == nullptr) + { + if(DailyShape.size() > 0) + DoSimpleMsg(String("WARNING! Vsource Daily load shape: \"") + DailyShape + + "\" Not Found.", 34584); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Vsource Duty load shape: \"") + DutyShape + + "\" Not Found.", 34585); + } + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); +} + +//============================================================================= + +void TVsourceObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + + // Build only YPrim Series + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + FYprimFreq = with0->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /***** Quasi Ideal Source for fundamental power flow*****/ + if(((FreqMultiplier - 1.0) < EPSILON) && IsQuasiIdeal && (!with0->IsHarmonicModel)) + // Ideal Source approximation -- impedance matrix is diagonal matrix only + { + int stop = 0; + Zinv->Clear(); + Value = cmulreal(puZideal, ZBase); // convert to ohms + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, Value); + } + } + else + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + + /***** Normal Thevenin Source *****/ + /* Put in Series RL Adjusted for frequency -- Use actual values */ + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Z->GetElement(i, j); + Value.im = Value.im * FreqMultiplier; /*Modify from base freq*/ + Zinv->SetElement(i, j, Value); + } + } + } + } + Zinv->Invert(); /*Invert in place*/ + if(Zinv->InvertError > 0) /*If error, put in Large series conductance*/ + { + int stop = 0; + DoErrorMsg("TVsourceObj.CalcYPrim", String("Matrix Inversion Error for Vsource \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with small resistance.", 325); + Zinv->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, cmplx(1.0 / EPSILON, 0.0)); + } + } + + // YPrim_Series.CopyFrom(Zinv); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zinv->GetElement(i, j); + YPrim_Series->SetElement(i, j, Value); + YPrim_Series->SetElement(i + Fnphases, j + Fnphases, Value); + //YPrim_series.SetElemsym(i + FNPhases, j, CNegate(Value)) + YPrim_Series->SetElement(i, j + Fnphases, cnegate(Value)); + YPrim_Series->SetElement(i + Fnphases, j, cnegate(Value)); + } + } + YPrim->CopyFrom(YPrim_Series); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +//============================================================================= + +void TVsourceObj::GetVterminalForSource(int ActorID) +{ + int i = 0; + complex Vharm = {}; + double SrcHarmonic = 0.0; + try + + + /* + This formulation will theoretically handle voltage sources of + any number of phases assuming they are + equally displaced in time. + */ + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + ShapeIsActual = false; + + /*Modify magnitude based on a LOADSHAPE if assigned*/ + switch(with0->Get_SolMode()) + { + case DAILYMODE: + /*Uses same logic as LOAD*/ + { + CalcDailyMult(with0->DynaVars.dblHour); // set Shapefactor.re = Pmult(t) or PerUnit + } + break; + case YEARLYMODE: + { + CalcYearlyMult(with0->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + CalcDutyMult(with0->DynaVars.dblHour); + } + break; + // This mode allows use of one class of load shape in DYNAMIC mode + case DYNAMICMODE: + { + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with0->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with0->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with0->DynaVars.dblHour); + break; + default: + ShapeFactor = cmplx(PerUnit, 0.0); // default to 1 + j0 if not known + break; + } + } + break; + default: + ; + break; + } + if((with0->Get_SolMode() == DAILYMODE) || (with0->Get_SolMode() == YEARLYMODE) || (with0->Get_SolMode() == DUTYCYCLE) || (with0->Get_SolMode() == DYNAMICMODE)) /*If a loadshape mode simulation*/ /*Loadshape cases*/ + { + if(ShapeIsActual) + Vmag = 1000.0 * ShapeFactor.re; + else + switch(Fnphases) + { + case 1: + Vmag = kVBase * ShapeFactor.re * 1000.0; + break; + default: + Vmag = kVBase * ShapeFactor.re * 1000.0 / 2.0 / sin((180.0 / Fnphases) * DSSGlobals::PI / 180.0L); + break; + } + } + else + switch(Fnphases) + { // Normal Case + case 1: + Vmag = kVBase * PerUnit * 1000.0; + break; + default: + Vmag = kVBase * PerUnit * 1000.0 / 2.0 / sin((180.0 / Fnphases) * DSSGlobals::PI / 180.0L); + break; + } + if(with0->IsHarmonicModel) + { + int stop = 0; + SrcHarmonic = with0->get_FFrequency() / SrcFrequency; + Vharm = cmulreal(SpectrumObj->GetMult(SrcHarmonic), Vmag); // Base voltage for this harmonic + RotatePhasorDeg(Vharm, SrcHarmonic, Angle); // Rotate for phase 1 shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = Vharm; + (Vterminal)[i + Fnphases - 1] = CZero; + if(i < Fnphases) + { + switch(ScanType) + { + case 1: + RotatePhasorDeg(Vharm, 1.0, -360.0 / Fnphases); + break; // maintain pos seq + case 0: + ; + break; // Do nothing for Zero Sequence; All the same + default: + RotatePhasorDeg(Vharm, SrcHarmonic, -360.0 / Fnphases); // normal rotation + break; + } + } + } + } + else + // non-harmonic modes + { + int stop = 0; + if(Abs((int) (with0->get_FFrequency() - SrcFrequency)) > EPSILON2) + Vmag = 0.0; // Solution Frequency and Source Frequency don't match! + /*NOTE: RE-uses VTerminal space*/ + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(SequenceType) + { + case -1: + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle + (i - 1) * 360.0 / Fnphases)); + break; // neg seq + case 0: + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle)); + break; // all the same for zero sequence + default: + (Vterminal)[i - 1] = pdegtocomplex(Vmag, (360.0 + Angle - (i - 1) * 360.0 / Fnphases)); + break; + } + (Vterminal)[i + Fnphases - 1] = CZero; // See comments in GetInjCurrents + } + } + } + } + catch(...) + { + DoSimpleMsg(String("Error computing Voltages for Vsource.") + get_Name() + + ". Check specification. Aborting.", 326); + if(In_Redirect) + Redirect_Abort = true; + } +} + +//=========================================================================== + +int TVsourceObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + +/*This is source injection*/ + result = inherited::InjCurrents(ActorID); // Add into system array + return result; +} + +//=========================================================================== + +void TVsourceObj::CalcInjCurrAtBus(pComplexArray Curr, int ActorID) +{ + vector ElmCurrents; // For storing the currents of the PDE + string BusName = StripExtension(FBusNames[0]); // Gets the name of the bus we are connected to + auto with1 = ActiveCircuit[ActorID]; + + auto ActiveElem = with1->FActiveCktElement; // saves whatever the active ckt element is + // First, inspect the currents based on PDE + DynStringArray myList = with1->getPDEatBus(BusName); // Obtains the list of PDE connected to the Bus + int myTerm = 0; // The terminal of the PDE connected to the Bus + + for (int idx = 0; idx < Yorder; idx++) + Curr[idx] = CZero; + + auto ActivePDE = ActiveElem; + + for (int idx = 0; idx < myList.size(); idx++) // We go through all the devices + { + myTerm = 0; // Restarts the terminal + with1->SetElementActive(myList[idx]); + ActivePDE = with1->FActiveCktElement; // To prevent super long statements + + ElmCurrents.resize((ActivePDE->Yorder) + 1); + ActivePDE->GetCurrents(&(ElmCurrents[0]), ActorID); + + for (int j = 0; j < ActivePDE->Fnphases; j++) + { + if (BusName == StripExtension(ActivePDE->FBusNames[j])) + break; + myTerm++; + } + + for (int j = 0; j < Fnphases; j++) + { + Curr[j] = csub(Curr[j], ElmCurrents[(myTerm * int(ActivePDE->Yorder / 2)) + j]); + } + + } + + ElmCurrents.clear(); + myList.clear(); + + // Now check the PCE at the same Bus + myList = with1->getPCEatBus(BusName); // Obtains the list of PCE connected to the Bus + myTerm = 0; // The terminal of the PCE connected to the Bus + string myName = LowerCase(ParentClass->Class_Name + "." + get_Name()); + + for (int idx = 0; idx < myList.size(); idx++) // We go through all the devices + { + if (LowerCase(myList[idx]) != myName) + { + with1->SetElementActive(myList[idx]); + auto ActivePCE = with1->FActiveCktElement; // To prevent super long statements + + ElmCurrents.resize((ActivePCE->Yorder) + 1); + ActivePCE->GetCurrents(&(ElmCurrents[0]), ActorID); + + for (int j = 0; j < ActivePCE->Fnphases; j++) + { + if (BusName == StripExtension(ActivePCE->FBusNames[j])) + break; + myTerm++; + } + for (int j = 0; j < Fnphases; j++) + { + Curr[j] = cadd(ElmCurrents[(myTerm * ActivePCE->Fnphases) + j], Curr[j]); + } + } + } + with1->Set_ActiveCktElement(ActiveElem); // returns the active ckt element to the ckt instance +} + +//=========================================================================== + +void TVsourceObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + //complex Vterminal[6]; + try + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + //FOR i := 1 TO (Nterms * NConds) DO Vtemp^[i] := V^[NodeRef^[i]]; + // This is safer 12/7/99 + if ((ActiveCircuit[ActiveActor]->Solution->Algorithm == NCIMSOLVE) && (NodeRef[0] == 1)) + { + CalcInjCurrAtBus(Curr, ActorID); + } + else + { + int stop = 0; + for (stop = Yorder, i = 1; i <= stop; i++) + { + if (!ADiakoptics || (ActorID == 1)) + { + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + } + else + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + YPrim->MVmult(Curr, &(Vterminal[0])); // Current from Elements in System Y + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for (stop = Yorder, i = 1; i <= stop; i++) + { + Curr[i - 1] = csub(Curr[i - 1], ComplexBuffer[i - 1]); + } + } + } /*With*/ + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element.", 327); + } +} + + +//============================================================================= + +void TVsourceObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + + + /* source injection currents given by this formula: + _ _ _ _ + |Iinj1| |Vsource | + | | = [Yprim] | | + |Iinj2| | 0 | + _ _ _ _ + */ + GetVterminalForSource(ActorID); // gets voltage vector above + YPrim->MVmult(Curr, &(Vterminal[0])); + set_ITerminalUpdated(false, ActorID); +} + +//============================================================================= + +void TVsourceObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + complex C = {}; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + { Write(f, "BaseFrequency="); WriteLn(f, BaseFrequency, 0, 1); } + { Write(f, "VMag="); WriteLn(f, Vmag, 0, 2); } + WriteLn(f, "Z Matrix="); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + C = Z->GetElement(i, j); + Write(f, Format("%.8g +j %.8g ", C.re, C.im)); + } + WriteLn(f); + } + } +} + + +//============================================================================= + +void TVsourceObj::InitPropertyValues(int ArrayOffset) +{ + + + /*PropertyValue Allocated in DSSObject.Create*/ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,"115"); + Set_PropertyValue(3,"1"); + Set_PropertyValue(4,"0"); + Set_PropertyValue(5,Format("%d", Round(ActiveCircuit[ActiveActor]->Fundamental))); + Set_PropertyValue(6,"3"); + Set_PropertyValue(7,"2000"); + Set_PropertyValue(8,"2100"); + Set_PropertyValue(9,"4"); + Set_PropertyValue(10,"3"); + Set_PropertyValue(11,"10000"); + Set_PropertyValue(12,"10500"); + Set_PropertyValue(13,"1.65"); + Set_PropertyValue(14,"6.6"); + Set_PropertyValue(15,"1.9"); + Set_PropertyValue(16,"5.7"); + Set_PropertyValue(17,"Pos"); + Set_PropertyValue(18,"Pos"); + Set_PropertyValue(19,GetBus(2)); + Set_PropertyValue(20,"[ 0 0 ]"); + Set_PropertyValue(21,"[ 0 0 ]"); + Set_PropertyValue(22,"[ 0 0 ]"); + Set_PropertyValue(23,"[ 0 0 ]"); + Set_PropertyValue(24,"[ 0 0 ]"); + Set_PropertyValue(25,"[ 0 0 ]"); + Set_PropertyValue(26,"100"); + Set_PropertyValue(27,""); + Set_PropertyValue(28,""); + Set_PropertyValue(29,""); + Set_PropertyValue(30,"Thevenin"); + Set_PropertyValue(31,"[1.0e-6, 0.001]"); + inherited::InitPropertyValues(NumPropsThisClass); + +} + +//============================================================================= + +String TVsourceObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = GetBus(1); + break; + case 4: + result = Format("%-.5g", Angle); + break; + case 7: + result = Format("%-.5g", MVAsc3); + break; + case 8: + result = Format("%-.5g", MVAsc1); + break; + case 11: + result = Format("%-.5g", Isc3); + break; + case 12: + result = Format("%-.5g", Isc1); + break; + case 13: + result = Format("%-.5g", R1); + break; + case 14: + result = Format("%-.5g", X1); + break; + case 15: + result = Format("%-.5g", R0); + break; + case 16: + result = Format("%-.5g", X0); + break; + case 19: + result = GetBus(2); + break; + case 20: + result = Format("[%-.8g, %-.8g]", R1, X1); + break; + case 21: + result = Format("[%-.8g, %-.8g]", R0, X0); + break; + case 22: + result = Format("[%-.8g, %-.8g]", R2, X2); + break; + case 23: + result = Format("[%-.8g, %-.8g]", puZ1.re, puZ1.im); + break; + case 24: + result = Format("[%-.8g, %-.8g]", puZ0.re, puZ0.im); + break; + case 25: + result = Format("[%-.8g, %-.8g]", puZ2.re, puZ2.im); + break; + case 26: + result = Format("%-.5g", BaseMVA); + break; + case 31: + result = Format("[%-.8g, %-.8g]", puZideal.re, puZideal.im); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + + +//---------------------------------------------------------------------------- + +void TVsourceObj::CalcDailyMult(double hr) +{ + if(DailyShapeObj != nullptr) + { + ShapeFactor = DailyShapeObj->GetMult(hr); + ShapeIsActual = DailyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(PerUnit, 0.0); // Default to no daily variation +} + + +//---------------------------------------------------------------------------- + +void TVsourceObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult IF no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TVsourceObj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = cmplx(PerUnit, 0.0); // Defaults to no variation +} + +//============================================================================= + +void TVsourceObj::MakePosSequence(int ActorID) +{ + String s; + s = "Phases=1 "; + s = s + Format("BasekV=%-.5g ", kVBase / SQRT3); + s = s + Format("R1=%-.5g ", R1); + s = s + Format("X1=%-.5g ", X1); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + + +void VSource_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +} + + class VSource_unit + { + public: + VSource_unit() + { + //AssertSystemInitialization(); + VSource_initialization(); + } + }; + VSource_unit _VSource_unit; + +} // namespace VSource + + + + diff --git a/OpenDSSC/PCElements/VSource.h b/OpenDSSC/PCElements/VSource.h new file mode 100644 index 0000000..1b5c161 --- /dev/null +++ b/OpenDSSC/PCElements/VSource.h @@ -0,0 +1,153 @@ +#ifndef VSourceH +#define VSourceH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "Spectrum.h" +#include "LoadShape.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Dynamics.h" +#include "Command.h" + + + + +namespace VSource +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 2-17-00 Change Log + Added Angle to VMag calculation + + 6-18-00 Added ability to do specify impedance in ohms or short circuit current + 5-17-01 Moved Spectrum to Base class + 2-10-09 Converted to 2-terminal voltage source + +*/ +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TVsource : public PCClass::TPCClass +{ + friend class TVsourceObj; +public: + typedef PCClass::TPCClass inherited; +private: + void VsourceSetBus1(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); +public: + TVsource(); + virtual ~TVsource(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TVsourceObj : public TPCElement +{ + friend class TVsource; +public: + typedef PCElement::TPCElement inherited; +//private: + double MVAsc3; + double MVAsc1; + double Isc3; + double Isc1; + int ZSpecType; + double R1; + double X1; // Pos Seq Z + double R2; + double X2; // Neg Seq Z + double R0; + double X0; // Zero Seq Z + double X1R1; + double X0R0; + double BaseMVA; + Ucomplex::complex puZideal; + Ucomplex::complex puZ1; + Ucomplex::complex puZ0; + Ucomplex::complex puZ2; + double ZBase; + bool Bus2Defined; + bool Z1Specified; + bool puZ1Specified; + bool puZ0Specified; + bool puZ2Specified; + bool Z2Specified; + bool Z0Specified; + bool IsQuasiIdeal; // Use puZideal for power flow + int ScanType; + int SequenceType; + Ucomplex::complex ShapeFactor; + bool ShapeIsActual; + void GetVterminalForSource(int ActorID); + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); + void CalcYearlyMult(double hr); + bool InterpretSourceModel(const String s); +public: + Ucmatrix::TcMatrix* Z; // Base Frequency Series Z matrix + Ucmatrix::TcMatrix* Zinv; + double Vmag; + double kVBase; + double PerUnit; + double Angle; + double SrcFrequency; + String DailyShape; // Daily (24 HR) load shape + LoadShape::TLoadShapeObj* DailyShapeObj; // Daily load Shape FOR this load + String DutyShape; // Duty cycle load shape FOR changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this load + String YearlyShape; // ='fixed' means no variation exempt from variation + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this load + TVsourceObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TVsourceObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + void CalcInjCurrAtBus(pComplexArray Curr, int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + TVsourceObj(DSSClass::TDSSClass* ParClass); + TVsourceObj(String ClassName); + TVsourceObj(); +}; +extern TVsourceObj* ActiveVsourceObj; +/* VSourceClass : TVsource;*/ + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace VSource + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace VSource; +#endif + +#endif // VSourceH + + + + diff --git a/OpenDSSC/PCElements/WTG3_Model.cpp b/OpenDSSC/PCElements/WTG3_Model.cpp new file mode 100644 index 0000000..ce62950 --- /dev/null +++ b/OpenDSSC/PCElements/WTG3_Model.cpp @@ -0,0 +1,1833 @@ + + +#pragma hdrstop + +#include "WTG3_Model.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" + +namespace WTG3_Model +{ + + TGE_WTG3_Model* ActiveModel = nullptr; + TParser ModelParser; + + /* ------------------------------------------------------------------------------------------------------------- */ + /* Model Class code */ + /* ------------------------------------------------------------------------------------------------------------- */ + + /* TGE_WTG3_Model */ + /* ------------------------------------------------------------------------------------------------------------- */ + + TGE_WTG3_Model::TGE_WTG3_Model(TWindGenVars& GenVars, TDynamicsRec& DynaVars) + /* ------------------------------------------------------------------------------------------------------------- */ + : + ratedHz(0.0), + ratedKVA(0.0), + ratedOmg(0.0), + ratedKVll(0.0), + ratedVln(0.0), + ratedAmp(0.0), + TfltPQM(0.0), + TfltVfbk(0.0), + VmeasMax(0.0), + ImeasMax(0.0), + KpPLL(0.0), + KiPLL(0.0), + dOmgLim(0.0), + VdPos(0.0), + VqPos(0.0), + VdNeg(0.0), + VqNeg(0.0), + VdFbkPos(0.0), + VqFbkPos(0.0), + VdFbkNeg(0.0), + VqFbkNeg(0.0), + IdPos(0.0), + IqPos(0.0), + IdNeg(0.0), + IqNeg(0.0), + dOmg(0.0), + Vang(0.0), + QordMax(0.0), + QordMin(0.0), + Iphl(0.0), + Iqhl(0.0), + ImaxTD(0.0), + TfltIqmxvUp(0.0), + TfltIqmxvDn(0.0), + Iqmxv(0.0), + Ipmx(0.0), + Iqmx(0.0), + Ipmn(0.0), + Iqmn(0.0), + V1_VoltVar(0.0), + V2_VoltVar(0.0), + V3_VoltVar(0.0), + V4_VoltVar(0.0), + Q1_VoltVar(0.0), + Q2_VoltVar(0.0), + Q3_VoltVar(0.0), + Q4_VoltVar(0.0), + Qref(0.0), + PFref(0.0), + rrlQcmd(0.0), + PordMax(0.0), + PordMin(0.0), + Pcurtail(0.0), + Pord(0.0), + Pcmd(0.0), + KpQreg(0.0), + KiQreg(0.0), + VrefMin(0.0), + VrefMax(0.0), + Qcmd(0.0), + errQgen(0.0), + KpVreg(0.0), + KiVreg(0.0), + Vref(0.0), + errVmag(0.0), + TfltVmagLVPL(0.0), + TfltPplvLim0(0.0), + V0LVPL(0.0), + P0LVPL(0.0), + V1LVPL(0.0), + P1LVPL(0.0), + MaxTrq(0.0), + TfltPplvLimUp(0.0), + TfltPplvLimDn(0.0), + VmagLVPL(0.0), + PplvLim0(0.0), + PplvLim(0.0), + TfltVmagLVQL(0.0), + V0LVQL(0.0), + I0LVQL(0.0), + V1LVQL(0.0), + I1LVQL(0.0), + TfltIqlvLimUp(0.0), + TfltIqlvLimDn(0.0), + IqLimAsymFlt(0.0), + VmagLVQL(0.0), + IqlvLim(0.0), + TfltIcmdPos(0.0), + KpIregPos(0.0), + KiIregPos(0.0), + rrlIqCmd(0.0), + KpIregNeg(0.0), + KiIregNeg(0.0), + AngIregNeg(0.0), + dE2Lim(0.0), + E2magLim(0.0), + IdCmdPos(0.0), + IqCmdPos(0.0), + IdCmdNeg(0.0), + IqCmdNeg(0.0), + Iplv(0.0), + Iqlv(0.0), + errIdPos(0.0), + errIqPos(0.0), + errIdNeg(0.0), + errIqNeg(0.0), + VthrsAsymFlt(0.0), + TthrsAsymFlt(0.0), + AsymFltFlag(0), + TmrAsymFlt(0.0), + underSpeedTrip(0), + wtgTrip(0), + userTrip(0), + KbAero(0.0), + HalfRhoArAero(0.0), + WtOpt(0.0), + PmechMax(0.0), + WtRefMin(0.0), + WtRefMax(0.0), + TfltWtRef(0.0), + KpTrqReg(0.0), + KiTrqReg(0.0), + TrqRefMax(0.0), + TrqRefMin(0.0), + TfltPinp(0.0), + PinpMax(0.0), + PinpMin(0.0), + rrlPinp(0.0), + TfltErrPinp(0.0), + WtRef(0.0), + errWt(0.0), + errWtOld(0.0), + Pinp1(0.0), + Pinp(0.0), + TrqRef(0.0), + errPinp(0.0), + errPinpFlt(0.0), + KpPitchCtrl(0.0), + KiPitchCtrl(0.0), + KpPitchComp(0.0), + KiPitchComp(0.0), + thetaPitchMax(0.0), + thetaPitchMin(0.0), + TfltPitch(0.0), + rrlThetaPitch(0.0), + thetaPitch(0.0), + thetaPitch0(0.0), + errPstl(0.0), + Pmech(0.0), + PmechAvl(0.0), + TfltPavlAPC(0.0), + TfltPsetAPC(0.0), + TdelayAPC(0.0), + PavlAPC(0.0), + PsetAPC(0.0), + PadeAPC(0.0), + Pstl(0.0), + dbWindInertia(0.0), + TfltDFrqWindInertia(0.0), + KWindInertia(0.0), + TfltDPinpWindInertia(0.0), + dPinpMax(0.0), + dPinpMin(0.0), + rruDPinp(0.0), + rrdDPinp(0.0), + dFrqPuTest(0.0), + dFrqWindInertia(0.0), + y3Lpf(0.0), + dPinpWindInertia(0.0), + WtBase(0.0), + Hwtg(0.0), + Dshaft(0.0), + Wt(0.0), + dWt(0.0), + dEmax(0.0), + dEmin(0.0), + EdPos(0.0), + EqPos(0.0), + EdNeg(0.0), + EqNeg(0.0), + DebugTrace(0), + tsim(0.0), + deltSim(0.0), + delt0(0.000050), + delt(0.0), + nRec(0), + nIterLF(0), + QMode(0), + QFlg(0), + APCFLG(0), + SimMechFlg(0), + N_WTG(0), + Xthev(0.0), + Rthev(0.0), + Vmag(0.0), + VmagMin(0.0), + Emag(0.0), + Eang(0.0), + Pele(0.0), + Qele(0.0), + Pgen(0.0), + Qgen(0.0), + Vss(0.0), + Pss(0.0), + Qss(0.0), + vwind(0.0), + DynaData(nullptr), + GenData(nullptr) + { + /* default parameter values */ + ratedHz = 60; + ratedKVA = 3600; + ratedKVll = 0.69; + // + N_WTG = 1; + // + Vss = 1; + Pss = 1; + Qss = 0; + vwind = 14; + // + Xthev = 0.05; + Rthev = 0.0; + // + SimMechFlg = 1; + APCFLG = 0; + QFlg = 1; + // + TfltPQM = 0.02; + TfltVfbk = 0.001; + VmeasMax = 2.0; + ImeasMax = 2.0; + // + KpPLL = 60; + KiPLL = 300; + // + QordMax = 0.436; + QordMin = -0.436; + Iphl = 1.24; + Iqhl = 1.25; + ImaxTD = 1.25; + TfltIqmxvUp = 0.016; + TfltIqmxvDn = 0.160; + // + PordMin = 0.0; + PordMax = 1.12; + Pcurtail = 1.12; + // + QMode = 0; // 0 -> Constant Q, 1 -> Constant PF, 2 -> Volt-Var + // IEEE 1547-2018 CAT-B Volt-Var curve + V1_VoltVar = 0.92; + V2_VoltVar = 0.98; + V3_VoltVar = 1.02; + V4_VoltVar = 1.08; + Q1_VoltVar = 0.44; + Q2_VoltVar = 0.0; + Q3_VoltVar = 0.0; + Q4_VoltVar = -0.44; + // Q regulator + rrlQcmd = 0.2; + KpQreg = 0.0; + KiQreg = 0.2; + VrefMax = 1.1; + VrefMin = 0.9; + // + KpVreg = 0; + KiVreg = 40; + // + TfltVmagLVPL = 0.002; + TfltPplvLim0 = 0.01; + V0LVPL = 0.4875; + P0LVPL = 0.0; + V1LVPL = 0.9; + P1LVPL = 1.13625; + MaxTrq = (ratedKVA * 1000 / 1454 / 2 / PI * 60) * 1.1931; + TfltPplvLimUp = 0.160; + TfltPplvLimDn = 0.016; + // + TfltVmagLVQL = 0.01; + V0LVQL = 0.5; + I0LVQL = 0.9; + V1LVQL = 0.9; + I1LVQL = 0.79; + TfltIqlvLimUp = 0.016; + TfltIqlvLimDn = 0.160; + IqLimAsymFlt = 0.447; + // + TfltIcmdPos = 0.002; + // KpIregPos := 0.9*Xthev; + // KiIregPos := 100*KpIregPos; + rrlIqCmd = 0.5; + // + // KiIregNeg := KiIregPos*0.1; + AngIregNeg = 65 * PI / 180; + dE2Lim = 0.05; + E2magLim = 0.105; + // + dEmax = 0.1; + dEmin = -0.1; + // + VthrsAsymFlt = 30 / 0.69 * 1000 * sqrt(2) / sqrt(3); + TthrsAsymFlt = 0.03; + // + KbAero = 69.5; + HalfRhoArAero = 0.00145; + AlphaAero[0][0] = -0.41909; + AlphaAero[0][1] = 0.21808; + AlphaAero[0][2] = -0.012406; + AlphaAero[0][3] = -0.00013365; + AlphaAero[0][4] = 0.000011524; + AlphaAero[1][0] = -0.067606; + AlphaAero[1][1] = 0.060405; + AlphaAero[1][2] = -0.013934; + AlphaAero[1][3] = 0.0010683; + AlphaAero[1][4] = -0.000023895; + AlphaAero[2][0] = 0.015727; + AlphaAero[2][1] = -0.010996; + AlphaAero[2][2] = 0.0021495; + AlphaAero[2][3] = -0.00014855; + AlphaAero[2][4] = 2.7937E-06; + AlphaAero[3][0] = -0.00086018; + AlphaAero[3][1] = 0.00057051; + AlphaAero[3][2] = -0.00010479; + AlphaAero[3][3] = 5.9924E-06; + AlphaAero[3][4] = -8.9194E-08; + AlphaAero[4][0] = 0.000014787; + AlphaAero[4][1] = -9.4839E-06; + AlphaAero[4][2] = 1.6167E-06; + AlphaAero[4][3] = -7.1535E-08; + AlphaAero[4][4] = 4.9686E-10; + // + WtRefMin = 0; + WtRefMax = 1.2; + TfltWtRef = 60; + KpTrqReg = 3; + KiTrqReg = 0.6; + TrqRefMax = 1.2; + TrqRefMin = 0.08; + TfltPinp = 0.05; + PinpMax = 1.12; + PinpMin = 0.04; + rrlPinp = 0.45; + TfltErrPinp = 1.0; + // + KpPitchCtrl = 150; + KiPitchCtrl = 25; + KpPitchComp = 3; + KiPitchComp = 30; + thetaPitchMax = 27; + thetaPitchMin = 0; + TfltPitch = 0.3; + rrlThetaPitch = 10; + // + TfltPavlAPC = 0.15; + FrqTableAPC[0] = 0.96; + FrqTableAPC[1] = 0.996; + FrqTableAPC[2] = 1.004; + FrqTableAPC[3] = 1.04; + FrqTableAPC[4] = 1.0662; + PwrTableAPC[0] = 1.0; + PwrTableAPC[1] = 0.95; + PwrTableAPC[2] = 0.95; + PwrTableAPC[3] = 0.40; + PwrTableAPC[4] = 0.0; + TfltPsetAPC = 5; + TdelayAPC = 0.15; + // + dbWindInertia = 0.0025; + TfltDFrqWindInertia = 1; + KWindInertia = 10; + TfltDPinpWindInertia = 5.5; + dPinpMax = 0.5; + dPinpMin = 0; + rruDPinp = 0.1; + rrdDPinp = 1; + // + // WtBase := 2*PI*(ratedHz/3); + Hwtg = 5.23; + Dshaft = 0.0; + // + DebugTrace = 0; + // + GenData = &GenVars; // Make pointer to data in main DSS + DynaData = &DynaVars; + ReCalcElementData(); + } + + TGE_WTG3_Model::~TGE_WTG3_Model() + { + // todo check: inherited::Destroy(); + } + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::Edit() + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ParamPointer = 0; + String ParamName = ""; + String Param = ""; + /* This DLL has a version of the DSS Parser compiled into it directly because it + was written on the same platform as the DSS. Otherwise, one should use the Callbacks. */ + ParamPointer = 0; + ParamName = ModelParser.GetNextParam(); + Param = ModelParser.MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + { + if (CompareText(Param, "help") == 0) + ParamPointer = 23; + else + ParamPointer++; + } + else + ParamPointer = CommandList.Getcommand(ParamName); + switch (ParamPointer) + { + case + // 0: DoSimpleMsg('Unknown parameter "'+ParamName+'" for Object "'+Name+'"'); + 1: + Rthev = ModelParser.MakeDouble_(); + break; + case 2: + Xthev = ModelParser.MakeDouble_(); + break; + case 3: + Vss = ModelParser.MakeDouble_(); + break; + case 4: + Pss = ModelParser.MakeDouble_(); + break; + case 5: + Qss = ModelParser.MakeDouble_(); + break; + case 6: + vwind = ModelParser.MakeDouble_(); + break; + case 7: + QMode = ModelParser.MakeInteger_(); + break; + case 8: + SimMechFlg = ModelParser.MakeInteger_(); + break; + case 9: + APCFLG = ModelParser.MakeInteger_(); + break; + case 10: + QFlg = ModelParser.MakeInteger_(); + break; + case 11: + DebugTrace = ModelParser.MakeInteger_(); + break; + case 12: + delt0 = ModelParser.MakeDouble_(); + break; + case 13: + ratedKVA = ModelParser.MakeDouble_(); + break; + case 14: + V1_VoltVar = ModelParser.MakeDouble_(); + break; + case 15: + V2_VoltVar = ModelParser.MakeDouble_(); + break; + case 16: + V3_VoltVar = ModelParser.MakeDouble_(); + break; + case 17: + V4_VoltVar = ModelParser.MakeDouble_(); + break; + case 18: + Q1_VoltVar = ModelParser.MakeDouble_(); + break; + case 19: + Q2_VoltVar = ModelParser.MakeDouble_(); + break; + case 20: + Q3_VoltVar = ModelParser.MakeDouble_(); + break; + case 21: + Q4_VoltVar = ModelParser.MakeDouble_(); + break; + case 22: + N_WTG = ModelParser.MakeInteger_(); + break; + case 23: + DoHelpCmd(); + break; // whatever the option, do help + default: + break; + } + ParamName = ModelParser.GetNextParam(); + Param = ModelParser.MakeString_(); + } + ReCalcElementData(); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::EditProp(int ParamPointer, String StrVal) + /* ------------------------------------------------------------------------------------------------------------- */ + { + String Param; + switch (ParamPointer) + { + case + // 0: DoSimpleMsg('Unknown parameter "'+ParamName+'" for Object "'+Name+'"'); + 1: + Rthev = StrToFloat(StrVal); + break; + case 2: + Xthev = StrToFloat(StrVal); + break; + case 3: + Vss = StrToFloat(StrVal); + break; + case 4: + Pss = StrToFloat(StrVal); + break; + case 5: + Qss = StrToFloat(StrVal); + break; + case 6: + vwind = StrToFloat(StrVal); + break; + case 7: + QMode = StrToInt(StrVal); + break; + case 8: + SimMechFlg = StrToInt(StrVal); + break; + case 9: + APCFLG = StrToInt(StrVal); + break; + case 10: + QFlg = StrToInt(StrVal); + break; + case 11: + DebugTrace = StrToInt(StrVal); + break; + case 12: + delt0 = StrToFloat(StrVal); + break; + case 13: + ratedKVA = StrToFloat(StrVal); + break; + case 14: + V1_VoltVar = StrToFloat(StrVal); + break; + case 15: + V2_VoltVar = StrToFloat(StrVal); + break; + case 16: + V3_VoltVar = StrToFloat(StrVal); + break; + case 17: + V4_VoltVar = StrToFloat(StrVal); + break; + case 18: + Q1_VoltVar = StrToFloat(StrVal); + break; + case 19: + Q2_VoltVar = StrToFloat(StrVal); + break; + case 20: + Q3_VoltVar = StrToFloat(StrVal); + break; + case 21: + Q4_VoltVar = StrToFloat(StrVal); + break; + case 22: + N_WTG = StrToInt(StrVal); + break; + case 23: + DoHelpCmd(); + break; // whatever the option, do help + default: + break; + } + ReCalcElementData(); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::ReCalcElementData() + /* ------------------------------------------------------------------------------------------------------------- */ + { + + // execution order: Create(Recalc) -> CalcPFlow -> Init + ratedOmg = 2 * PI * ratedHz; + ratedVln = ratedKVll / sqrt(3.0) * 1000; + ratedAmp = double(ratedKVA) * 1000 / ratedVln / 3; + MaxTrq = (double(double(double(ratedKVA))) * 1000 / 1454 / 2 / PI * 60) * 1.1931; + Zthev = cmplx(Rthev, Xthev); + dOmgLim = 0.2 * ratedOmg; + + // current regulator parameters + KpIregPos = 0.9 * Xthev; + KiIregPos = 25. * KpIregPos; + // + KpIregNeg = KpIregPos * 1.5; + KiIregNeg = KiIregPos * 1.5; + + // volt-var curve + VCurveVoltVar[0] = max(0.0, V1_VoltVar - 0.2); + VCurveVoltVar[1] = V1_VoltVar; + VCurveVoltVar[2] = V2_VoltVar; + VCurveVoltVar[3] = V3_VoltVar; + VCurveVoltVar[4] = V4_VoltVar; + VCurveVoltVar[5] = min(2.0, V4_VoltVar + 0.2); + QCurveVoltVar[0] = Q1_VoltVar; + QCurveVoltVar[1] = Q1_VoltVar; + QCurveVoltVar[2] = Q2_VoltVar; + QCurveVoltVar[3] = Q3_VoltVar; + QCurveVoltVar[4] = Q4_VoltVar; + QCurveVoltVar[5] = Q4_VoltVar; + + // turbine rotation speed base + WtBase = 2 * PI * (ratedHz / 3); + + // 1.5MW parameters + if (ratedKVA < 2000) + { + Hwtg = 4.94; + KbAero = 56.6; + HalfRhoArAero = 0.00159; + } + + // time steps + deltSim = DynaData->h; + nRec = trunc(int(double(DynaData->h) / delt0 / 2) * 2 + 1); + delt = double(DynaData->h) / nRec; + tsim = DynaData->T; + nIterLF = 100; + + // initialize trace file + if (DebugTrace == 1) + InitTraceFile(); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + complex TGE_WTG3_Model::MagLimiter(complex x, double magmin, double magMax) + /* ------------------------------------------------------------------------------------------------------------- */ + { + complex result = CZero; + result = pclx(max(magmin, min(magMax, cabs(x))), cang(x)); + return result; + } + + +/* ------------------------------------------------------------------------------------------------------------- */ + + double TGE_WTG3_Model::LinearInterp(double* xTable, int xTable_maxidx, double* yTable, int yTable_maxidx, double x) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double result = 0.0; + int iLeft = 0, + iRight = 0, + ii = 0; + + iLeft = 0 /*# Low(xTable) */; + iRight = xTable_maxidx /*# High(xTable) */; + result = yTable[iLeft]; + if (x < xTable[iLeft]) + result = yTable[iLeft]; + else + { + if (x > xTable[iRight]) + result = yTable[iRight]; + else + { + for (int stop = iRight - 1, ii = iLeft; ii <= stop; ii++) + if ((x >= xTable[ii]) && (x <= xTable[ii + 1])) + { + result = ((yTable[ii + 1] - yTable[ii]) / (xTable[ii + 1] - xTable[ii])) * (x - xTable[ii]) + yTable[ii]; + break; + } + } + } + return result; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::abc2seq(complex* abc, complex* seq, double ang) + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + complex temp; + // phase to sequence conversion + Phase2SymComp(abc, seq); + // rotation of the sequence components + temp = cmplx(cos(-ang), sin(-ang)); + for (int stop = 2, ii = 0; ii <= stop; ii++) + { + (seq[ii]) = cmul((seq[ii]), temp); + } + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::seq2abc(complex* abc, complex* seq, double ang) + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + complex temp; + // sequence to phase conversion + SymComp2Phase(abc, seq); + // rotation of the sequence components + temp = cmplx(cos(ang), sin(ang)); + for (int stop = 3, ii = 1; ii <= stop; ii++) + { + abc[ii - 1] = cmul(abc[ii - 1], temp); + } + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::Instrumentation(pComplexArray V, pComplexArray i) + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + double ktemp = 0.0; + // per-unitize abc voltage and current + for (int stop = 3, ii = 1; ii <= stop; ii++) + { + Vabc[ii - 1] = MagLimiter(cdivreal(V[ii - 1], ratedVln), 0, VmeasMax); + // Iabc = -(I/AmpBase+Vabc/Zthev) + Iabc[ii - 1] = MagLimiter(csub(cdivreal(i[ii - 1], -ratedAmp * N_WTG), cdiv(Vabc[ii - 1], Zthev)), 0, ImeasMax); + } + + // phase to sequence conversion + abc2seq(&(Vabc[0]), &(V012[0]), Vang); + abc2seq(&(Iabc[0]), &(I012[0]), Vang); + + // get rid of zero sequence component in voltage + V012[0] = cmplx(0, 0); + seq2abc(&(Vabc[0]), &(V012[0]), Vang); + + // voltage magnitude + Vmag = cabs(V012[1]); + + // minimum voltage for fault ride through + VmagMin = min(min(cabs(Vabc[1 - 1]), cabs(Vabc[2 - 1])), cabs(Vabc[3 - 1])); + + // calculate output power + Sele = cmplx(0, 0); + for (int stop = 3, ii = 1; ii <= stop; ii++) + Sele = cadd(Sele, cdivreal(cmul(Vabc[ii - 1], conjg(Iabc[ii - 1])), 3)); + Pele = Sele.re; + Qele = Sele.im; + ktemp = min(1.0, deltSim / TfltPQM); + Pgen = Pgen + (Pele - Pgen) * ktemp; + Qgen = Qgen + (Qele - Qgen) * ktemp; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::CalcPFlow(pComplexArray V, pComplexArray i) + /* ------------------------------------------------------------------------------------------------------------- */ + { + complex Vtemp = CZero, + Itemp = CZero, + Etemp = CZero; + double kCnvg = 0.0; + // instrumentation + Instrumentation(V, i); + + // solve Emag and Eang + if (nIterLF == 1) + { + Vtemp = cmulreal(cdivreal(V012[1], max(0.000001, cabs(V012[1]))), Vss); + Emag = cabs(Vtemp); + Eang = cang(Vtemp); + } + else + Vtemp = V012[1]; + Itemp = conjg(cdiv(cmplx(Pss, Qss), Vtemp)); + Etemp = cadd(Vtemp, cmul(Zthev, Itemp)); + if (nIterLF < 10) + { + kCnvg = max(0.4, min(1.0, 1 - (nIterLF - 1) * 0.1)); + Emag = max(0.0, min(2.0, Emag + (cabs(Etemp) - Emag) * kCnvg)); + Eang = Eang + (cang(Etemp) - Eang) * kCnvg; + } + nIterLF = nIterLF + 1; + + // update output + E012[0] = cmplx(0, 0); + E012[1] = cmplx(Emag * cos(Eang), Emag * sin(Eang)); + E012[2] = cmplx(0, 0); + CalcCurrent(i); + } + + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::Init(pComplexArray V, pComplexArray i) + /* ------------------------------------------------------------------------------------------------------------- */ + // Init for Dynamics mode + // execution order: Create(Recalc) -> CalcPFlow -> Init + + { + int ii = 0; + double eIter = 0.0; + double kIter = 0.0; + // check for available wind power and update initial power condition + AeroMPPT(); + if (Pss > PmechMax) + // not enough wind power to support Pss, update Pss + { + Pss = PmechMax; + Wt = WtOpt; + } + else + Wt = CalcWtRef(Pss); + // run iteration to solve for thetaPitch + thetaPitch = thetaPitchMax / 2; + eIter = 0.01; + kIter = 10; + for (int stop = 10, ii = 1; ii <= stop; ii++) + { + AeroDynamic(); + if (abs(Pmech - Pss) < eIter) + break; + else + { + thetaPitch = thetaPitch + kIter * (Pmech - Pss); + thetaPitch = min(thetaPitchMax, max(thetaPitchMin, thetaPitch)); + } + } + + // run a load flow + nIterLF = 1; + CalcPFlow(V, i); + + // initialize control variables + VdFbkPos = Vss; + VqFbkPos = 0; + VdFbkNeg = 0; + VqFbkNeg = 0; + dOmg = 0; + Vang = cang(Vabc[1 - 1]); + VqPos = 0; + PplvLim0 = P1LVPL; + PplvLim = PplvLim0; + IqlvLim = I0LVQL; + VmagLVPL = VdFbkPos; + VmagLVQL = VdFbkPos; + Pord = Pss; + Pgen = Pss; + IdCmdPos = Pss / Vss; + Iplv = IdCmdPos; + if ((QMode == 0) || (QMode == 1)) + Qcmd = Qss; + else + Qcmd = LinearInterp(VCurveVoltVar, MAXIDX(VCurveVoltVar), QCurveVoltVar, MAXIDX(QCurveVoltVar), Vss); + PFref = abs(Pss) / max(0.000001, sqrt(Pss * Pss + Qss * Qss)); + if (Qss < 0) + PFref = -PFref; + Qgen = Qcmd; + errQgen = 0; + Vref = Vss; + IqCmdPos = -Qcmd / Vss; + Iqlv = IqCmdPos; + Iqmxv = QordMax / Vss; + errVmag = 0; + errIdPos = 0; + errIqPos = 0; + EdPos = Emag * cos(Eang); + EqPos = Emag * sin(Eang); + // negative sequence current regulator + errIdNeg = 0; + errIqNeg = 0; + EdNeg = 0; + EqNeg = 0; + // fault detection + underSpeedTrip = 0; + wtgTrip = 0; + AsymFltFlag = 0; + TmrAsymFlt = 0; + // torque regulator + WtRef = Wt; + errWt = 0; + Pinp1 = Pss; + Pinp = Pss; + TrqRef = Pss / Wt; + errPinp = 0; + errPinpFlt = 0; + // pitch control + errPstl = 0; + thetaPitch0 = thetaPitch; + // active power control + // Pcurtail := Pss; + PavlAPC = Pss; + PsetAPC = Pss; + PadeAPC = Pss; + Pstl = Pss; + // wind inertia + dFrqPuTest = 0; + dFrqWindInertia = 0; + y3Lpf = 0; + dPinpWindInertia = 0; + // swing model + dWt = Wt - 1; + + // initialize integrator + for (int stop = /*# High( intg_x ) */ 11, ii = /*# Low( intg_x ) */ 0; ii <= stop; ii++) + { + intg_x[ii] = 0; + intg_d[ii] = 0; + intg_d_old[ii] = 0; + } + intg_x[0] = dOmg; + intg_x[1] = Vang; + intg_x[2] = 0; + intg_x[3] = 0; + intg_x[4] = 0; + intg_x[5] = 0; + intg_x[6] = IqCmdPos; + intg_x[7] = Vref; + intg_x[8] = TrqRef; + intg_x[9] = thetaPitch; + intg_x[10] = 0; + intg_x[11] = dWt; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::PllLogic() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double VqPosOld = 0.0; + double kFltTemp = 0.0; + double drvTemp = 0.0; + // PI regulator (Vq to dFrq) + VqPosOld = VqPos; + VdPos = V012[1].re; + VqPos = V012[1].im; + drvTemp = KiPLL * VqPos + KpPLL * (VqPos - VqPosOld) / deltSim; + dOmg = max(-dOmgLim, min(dOmgLim, dOmg + drvTemp * deltSim)); + // integrator (dFrq to Vang) + Vang = Vang + dOmg * deltSim; + // other sequence components + VdNeg = V012[2].re; + VqNeg = -V012[2].im; + IdPos = I012[1].re; + IqPos = I012[1].im; + IdNeg = I012[2].re; + IqNeg = -I012[2].im; + // LPF on voltage feedback + kFltTemp = min(1.0, double(DynaData->h) / TfltVfbk); + VdFbkPos = VdFbkPos + (VdPos - VdFbkPos) * kFltTemp; + VqFbkPos = VqFbkPos + (VqPos - VqFbkPos) * kFltTemp; + VdFbkNeg = VdFbkNeg + (VdNeg - VdFbkNeg) * kFltTemp; + VqFbkNeg = VqFbkNeg + (VqNeg - VqFbkNeg) * kFltTemp; + } + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::PQPriority(int PQFlag) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double y0 = 0.0, + temp = 0.0; + + y0 = min(Iqhl, max(QordMax, (QordMax - 2.15) * Vmag + 2.15)); + if (y0 > Iqmxv) + temp = min(1.0, delt / TfltIqmxvUp); + else + temp = min(1.0, delt / TfltIqmxvDn); + Iqmxv = Iqmxv + (y0 - Iqmxv) * temp; + Iqmxv = min(Iqhl, max(0.0, Iqmxv)); + if (PQFlag == 1) + { + // P priority + Ipmx = min(ImaxTD, Iphl); + Iqmx = min(Iqhl, sqrt(max(0.0, sqr(ImaxTD) - sqr(Iplv)))); + } + else + { + Iqmx = min(ImaxTD, Iqmxv); + Ipmx = min(Iphl, sqrt(max(0.0, sqr(ImaxTD) - sqr(Iqlv)))); + } + Ipmn = -Ipmx; + Iqmn = -Iqmx; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::LVPL() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double temp = 0.0; + double y0 = 0.0, + y0Lim = 0.0, + y1 = 0.0, + y1Sub = 0.0, + y2 = 0.0; + + // low pass filter on Vmag + temp = min(1.0, delt / TfltVmagLVPL); + VmagLVPL = VmagLVPL + (VmagMin - VmagLVPL) * temp; + // LVPL curve interpolation + y0 = (P1LVPL - P0LVPL) / (V1LVPL - V0LVPL) * (VmagLVPL - V0LVPL) + P0LVPL; + y0 = max(P0LVPL, min(P1LVPL, y0)); + y0 = y0 + 0.02; + // upper limit to y0 + if (AsymFltFlag == 1) + y0Lim = 0.75; + else + y0Lim = max(0.5, min(2.0, Pord)); + y1 = min(y0Lim, y0); + // subtraction term to y1 + if ((Vmag < (0.91 - 0.05)) && (Vmag > (0.65 - 0.05))) + y1Sub = 0.2; + else + y1Sub = 0.0; + y1 = max(0.0, y1 - y1Sub); + // limit on torque + y2 = min(MaxTrq * Wt * WtBase / ratedKVA / 1000, y1); + // low pass filter + if (y2 > PplvLim) + temp = min(1.0, delt / TfltPplvLimUp); + else + temp = min(1.0, delt / TfltPplvLimDn); + PplvLim = PplvLim + (y2 - PplvLim) * temp; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::LVQL() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double temp = 0.0; + double y0 = 0.0; + // low pass filter on Vmag + temp = min(1.0, delt / TfltVmagLVQL); + VmagLVQL = VmagLVQL + (VmagMin - VmagLVQL) * temp; + // LVQL curve interpolation + y0 = (I1LVQL - I0LVQL) / (V1LVQL - V0LVQL) * (VmagLVQL - V0LVQL) + I0LVQL; + y0 = min(I0LVQL, max(I1LVQL, y0)); + // low pass filter + if (y0 > IqlvLim) + temp = min(1.0, delt / TfltIqlvLimUp); + else + temp = min(1.0, delt / TfltIqlvLimDn); + IqlvLim = IqlvLim + (y0 - IqlvLim) * temp; + if (AsymFltFlag == 1) + IqlvLim = IqLimAsymFlt; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::RealPowerReg() + /* ------------------------------------------------------------------------------------------------------------- */ + { + // active power regulator + Pcmd = max(PordMin, min(PordMax, min(PplvLim, Pord))); + Pcmd = min(Pcurtail, Pcmd); + IdCmdPos = Pcmd / max(0.000001, Vmag); + IdCmdPos = max(Ipmn, min(Ipmx, IdCmdPos)); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::ReactivePowerReg() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double Qord = 0.0, errQgenOld = 0.0; + double temp = 0.0; + // calculation of desired Q output + if (QMode == 0) + // constant Q mode + Qord = Qref; + else if (QMode == 1) + // constant PF mode (negative means absorption) + { + Qord = sqrt(1 - PFref * PFref) / max(0.000001, abs(PFref)) * Pgen; + if (PFref < 0) + Qord = -Qord; + } + else + // volt-var mode + Qord = LinearInterp(VCurveVoltVar, MAXIDX(VCurveVoltVar), QCurveVoltVar, MAXIDX(QCurveVoltVar), Vmag); + // hard limiter on Qord + Qord = min(QordMax, max(QordMin, Qord)); + // ramp rate limiter on Qcmd + temp = rrlQcmd * delt; + Qcmd = min(Qcmd + temp, max(Qcmd - temp, Qord)); + + if (Qcmd <= -0.0078) + Qcmd = Qcmd; + + // reactive power regulator + errQgenOld = errQgen; + errQgen = Qcmd - Qgen; + intg_d[7] = KiQreg * errQgen + KpQreg * (errQgen - errQgenOld) / delt; + intg_x[7] = max(VrefMin, min(VrefMax, intg_x[7])); + Vref = intg_x[7]; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::VoltageReg() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double errVmagOld = 0.0; + errVmagOld = errVmag; + errVmag = -(Vref - Vmag); + intg_d[6] = KiVreg * errVmag + KpVreg * (errVmag - errVmagOld) / delt; + intg_x[6] = max(Iqmn, min(Iqmx, intg_x[6])); + IqCmdPos = intg_x[6]; + } + + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::CurrentReg() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double ktemp = 0.0, + errIdPosOld = 0.0, + errIqPosOld = 0.0, + errIdNegOld = 0.0, + errIqNegOld = 0.0, + dE2Real = 0.0, + dE2Imag = 0.0; + complex tempE2 = CZero; + + // positive sequence current regulator + ktemp = min(1.0, delt / TfltIcmdPos); + Iplv = Iplv + (IdCmdPos - Iplv) * ktemp; + Iqlv = min(IqlvLim, max(-IqlvLim, Iqlv + (IqCmdPos - Iqlv) * ktemp)); + // anti windup + if (((Iqlv == IqlvLim) && (IqCmdPos > Iqlv)) || ((Iqlv == -IqlvLim) && (IqCmdPos < Iqlv))) + { + intg_d[6] = 0; + intg_d[7] = 0; + } + + // PI regulator for IdPos + errIdPosOld = errIdPos; + errIdPos = Iplv - IdPos; + intg_d[2] = KiIregPos * errIdPos + KpIregPos * (errIdPos - errIdPosOld) / delt; + intg_x[2] = max(dEmin, min(dEmax, intg_x[2])); + EdPos = intg_x[2] + Rthev * Iplv - Xthev * Iqlv + VdFbkPos; + // PI regulator for IqPos + errIqPosOld = errIqPos; + errIqPos = Iqlv - IqPos; + intg_d[3] = KiIregPos * errIqPos + KpIregPos * (errIqPos - errIqPosOld) / delt; + intg_x[3] = max(dEmin, min(dEmax, intg_x[3])); + EqPos = intg_x[3] + Rthev * Iqlv + Xthev * Iplv + VqFbkPos; + + // negative sequence current regulator + // be carefule with signs: E2=Ed-jEq, I2=Id-jIq + IdCmdNeg = 0; + IqCmdNeg = 0; + // PI regulator + errIdNegOld = errIdNeg; + errIdNeg = IdCmdNeg - IdNeg; + intg_d[4] = KiIregNeg * errIdNeg + KpIregNeg * (errIdNeg - errIdNegOld) / delt; + errIqNegOld = errIqNeg; + errIqNeg = IqCmdNeg - IqNeg; + intg_d[5] = KiIregNeg * errIqNeg + KpIregNeg * (errIqNeg - errIqNegOld) / delt; + // limiter on integrator + intg_x[4] = min(dE2Lim, max(-dE2Lim, intg_x[4])); + intg_x[5] = min(dE2Lim, max(-dE2Lim, intg_x[5])); + // angle rotation (for better damping) + dE2Real = intg_x[4] * cos(AngIregNeg) + intg_x[5] * sin(AngIregNeg); + dE2Imag = intg_x[4] * sin(AngIregNeg) - intg_x[5] * cos(AngIregNeg); + // V2 feedforwarding and E2 magnitude limiting + tempE2 = cmplx(VdFbkNeg + dE2Real, -VqFbkNeg + dE2Imag); + tempE2 = MagLimiter(tempE2, 0, E2magLim); + EdNeg = tempE2.re; + EqNeg = -tempE2.im; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::Integrate() + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + for (int stop = 11, ii = 0; ii <= stop; ii++) + { + intg_x[ii] = intg_x[ii] + delt / 2 * (intg_d_old[ii] + intg_d[ii]); + intg_d_old[ii] = intg_d[ii]; + } + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::CurrentLimiting() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double I2Max = 0.0; + E012[0] = cmplx(0, 0); + // current limit on positive sequence + E012[1] = cmplx(EdPos, EqPos); + I012[1] = cdiv(csub(E012[1], V012[1]), Zthev); + if (cabs(I012[1]) > ImaxTD) + { + I012[1] = cmulreal(cdivreal(I012[1], max(0.000001, cabs(I012[1]))), ImaxTD); + E012[1] = cadd(V012[1], cmul(I012[1], Zthev)); + } + // current limit on negative sequence + E012[2] = cmplx(EdNeg, -EqNeg); + I012[2] = cdiv(csub(E012[2], V012[2]), Zthev); + I2Max = max(0.0, 1.1 - cabs(I012[1])); + if (cabs(I012[2]) > I2Max) + { + I012[2] = cmulreal(cdivreal(I012[2], max(0.000001, cabs(I012[2]))), I2Max); + E012[2] = cadd(V012[2], cmul(I012[2], Zthev)); + } + } + + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::FaultDetection() + /* ------------------------------------------------------------------------------------------------------------- */ + { + if (cabs(V012[2]) > VthrsAsymFlt) + TmrAsymFlt = TmrAsymFlt + deltSim; + else + { + TmrAsymFlt = 0; + AsymFltFlag = 0; + } + if (TmrAsymFlt > TthrsAsymFlt) + AsymFltFlag = 1; + + // under speed fault + if (Wt < 0.1) + underSpeedTrip = 1; + + // tripping of WTG (more tripping logics to be added in the future) + if ((userTrip == 1) || (underSpeedTrip == 1)) + wtgTrip = 1; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + double TGE_WTG3_Model::CalcCp(double Theta, double lmbda) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double result = 0.0; + int ii = 0, jj = 0; + result = 0; + for (int stop = 4, ii = 0; ii <= stop; ii++) + for (int stop = 4, jj = 0; jj <= stop; jj++) + result = result + AlphaAero[ii][jj] * pow(Theta, ii) * pow(lmbda, jj); + return result; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + double TGE_WTG3_Model::CalcPmech(double Theta, double wrotor, double spdwind) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double result = 0.0; + double lmbda = 0.0, Cp = 0.0; + lmbda = min(20.0, max(0.0, wrotor / max(0.01, spdwind) * KbAero)); + Cp = CalcCp(Theta, lmbda); + result = min(1.2, HalfRhoArAero * pow(spdwind, 3) * Cp); + return result; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::AeroMPPT() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double WtList[101 /*# range 0..100*/], PmechList[101 /*# range 0..100*/]; + double tempWt = 0.0, stepWt = 0.0; + int ii = 0, max_ii = 0; + stepWt = (WtRefMax - WtRefMin) / 100; + for (int stop = 100, ii = 0; ii <= stop; ii++) + { + tempWt = WtRefMin + ii * stepWt; + WtList[ii] = tempWt; + PmechList[ii] = CalcPmech(0, tempWt, vwind); + } + // find optimal Wt and maximum Pmech + PmechMax = -100000; + max_ii = 0; + for (int stop = 100, ii = 0; ii <= stop; ii++) + if (PmechList[ii] > PmechMax) + { + max_ii = ii; + PmechMax = PmechList[ii]; + } + WtOpt = WtList[max_ii]; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::AeroDynamic() + /* ------------------------------------------------------------------------------------------------------------- */ + { + Pmech = CalcPmech(thetaPitch, Wt, vwind); + PmechAvl = CalcPmech(0.001, Wt, vwind); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + double TGE_WTG3_Model::CalcWtRef(double elePwr) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double result = 0.0; + double temp = 0.0; + temp = min(1.0, elePwr); + result = max(WtRefMin, min(WtRefMax, -0.75 * temp * temp + 1.59 * temp + 0.63)); + return result; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::TorqueReg() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double y1 = 0.0, + y2 = 0.0, + temp = 0.0, + PinpSat = 0.0, + errPinpHpf = 0.0; + + y1 = CalcWtRef(Pele); + // low pass filter + temp = min(1.0, delt / TfltWtRef); + WtRef = WtRef + (y1 - WtRef) * temp; + // PI regulator + errWtOld = errWt; + errWt = Wt - WtRef; + intg_d[8] = KiTrqReg * errWt + KpTrqReg * (errWt - errWtOld) / delt; + intg_x[8] = max(TrqRefMin, min(TrqRefMax, intg_x[8])); + TrqRef = intg_x[8]; + // convert torque to power + y2 = TrqRef * Wt; + // low pass filter on Pinp + temp = min(1.0, delt / TfltPinp); + Pinp1 = min(PinpMax, max(PinpMin, Pinp1 + (y2 - Pinp1) * temp)); + // ramp rate limiter + temp = rrlPinp * delt; + Pinp = min(Pinp + temp, max(Pinp - temp, Pinp1)); + // power response rate limit + PinpSat = min(Pstl, max(0.0, Pinp)); + errPinp = Pinp - PinpSat; + // high pass filter on errPinp + temp = min(1.0, delt / TfltErrPinp); + errPinpFlt = errPinpFlt + (errPinp - errPinpFlt) * temp; + errPinpHpf = errPinp - errPinpFlt; + // get the final Pord + Pord = PinpSat + errPinpHpf + dPinpWindInertia; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::PitchControl() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double x1 = 0.0, y1 = 0.0, y2 = 0.0, errPstlOld = 0.0, temp = 0.0; + // Note: this function should go after torque regulator where errWt and errWtOld are calculated + // PI regulator for pitch control + intg_d[9] = KiPitchCtrl * errWt + KpPitchCtrl * (errWt - errWtOld) / delt; + // PI regulator for pitch compensator + errPstlOld = errPstl; + errPstl = Pinp - Pstl; + intg_d[10] = KiPitchComp * errPstl + KpPitchComp * (errPstl - errPstlOld) / delt; + // anti-windup + x1 = intg_d[9] + intg_d[10]; + y1 = intg_x[9] + intg_x[10]; + if (((y1 >= thetaPitchMax) && (x1 > 0)) || ((y1 <= thetaPitchMin) && (x1 < 0))) + { + intg_d[9] = 0; + intg_d[10] = 0; + } + y2 = max(thetaPitchMin, min(thetaPitchMax, y1)); + // low pass filter + temp = min(1.0, delt / TfltPitch); + thetaPitch0 = thetaPitch0 + (y2 - thetaPitch0) * temp; + // ramp rate limiter + temp = rrlThetaPitch * delt; + thetaPitch = min(thetaPitch + temp, max(thetaPitch - temp, thetaPitch0)); + } + + + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::APCLogic() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double y1 = 0.0, + y2 = 0.0, + y3 = 0.0, + y4 = 0.0, + temp = 0.0, + gridFrq = 0.0, + PmechMax = 0.0, + PmechMin = 0.0; + + y1 = min(1.0, max(0.000001, PmechAvl)); + // low pass filter on available power + temp = min(1.0, delt / TfltPavlAPC); + PavlAPC = PavlAPC + (y1 - PavlAPC) * temp; + // power curtailment + temp = max(0.4, min(1.0, Pcurtail / PavlAPC)); + PwrTableAPC[1] = temp; + PwrTableAPC[2] = temp; + // power frequency curve + gridFrq = 1 + dOmg / ratedOmg; + y2 = LinearInterp(FrqTableAPC, MAXIDX(FrqTableAPC), PwrTableAPC, MAXIDX(PwrTableAPC), gridFrq); + y3 = PavlAPC * y2; + // low pass filter on set power + temp = min(1.0, delt / TfltPsetAPC); + PsetAPC = PsetAPC + (y3 - PsetAPC) * temp; + // APCFLG + if (APCFLG == 0) + y4 = Pcurtail; + else + y4 = PsetAPC; + // enforce user-defined PmechMax in normal condition + if ((gridFrq >= FrqTableAPC[1]) && (gridFrq <= FrqTableAPC[2])) + PmechMax = 1.0; + else + PmechMax = 1.2; + PmechMin = 0.2; + y4 = min(PmechMax, max(PmechMin, y4)); + // Pade delay function + temp = min(1.0, delt / TdelayAPC * 2); + PadeAPC = PadeAPC + (y4 - PadeAPC) * temp; + Pstl = min(PmechMax, max(PmechMin, 2 * PadeAPC - y4)); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::WindInertia() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double y1 = 0.0, + y2 = 0.0, + y3 = 0.0, + y4 = 0.0, + temp = 0.0, + temp1 = 0.0, + temp2 = 0.0; + + y1 = -dOmg / ratedOmg + dFrqPuTest; + // deadband + y2 = max(0.0, y1 - dbWindInertia); + // low pass filter + temp = min(1.0, delt / TfltDFrqWindInertia); + dFrqWindInertia = dFrqWindInertia + (y2 - dFrqWindInertia) * temp; + // multiplier + y3 = dFrqWindInertia * KWindInertia; + // high pass filter + temp = min(1.0, delt / TfltDPinpWindInertia); + y3Lpf = y3Lpf + (y3 - y3Lpf) * temp; + y4 = min(dPinpMax, max(dPinpMin, y3 - y3Lpf)); + // ramp rate limiter + temp1 = rruDPinp * delt; + temp2 = rrdDPinp * delt; + dPinpWindInertia = min(dPinpWindInertia + temp1, max(dPinpWindInertia - temp2, y4)); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::SwingModel() + /* ------------------------------------------------------------------------------------------------------------- */ + { + double Tmech = 0.0, + Tele = 0.0, + Tdamp = 0.0; + + Tmech = Pmech / Wt; + Tele = Pele / Wt; + Tdamp = Dshaft * dWt; + intg_d[11] = double((Tmech - Tele - Tdamp)) / 2 / Hwtg; + dWt = intg_x[11]; + Wt = max(0.01, 1.0 + dWt); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::CalcCurrent(pComplexArray i) + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + // sequence to phase + seq2abc(&(Eabc[0]), &(E012[0]), Vang); + + // Thevenin to Norton (current injection) + for (int stop = 3, ii = 1; ii <= stop; ii++) + i[ii - 1] = cmulreal(cdiv(Eabc[ii - 1], Zthev), -ratedAmp * N_WTG); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::CalcDynamic(pComplexArray V, pComplexArray i) + /* ------------------------------------------------------------------------------------------------------------- */ + { + int ii = 0; + deltSim = DynaData->h; + + // instrumentation + Instrumentation(V, i); + // PLL + PllLogic(); + // fault detection + FaultDetection(); + + // start small time step iteration on when time proceeds + if ((DynaData->T > tsim) && (DynaData->IterationFlag == 1)) + { + nRec = trunc(int(double(DynaData->h) / delt0 / 2) * 2 + 1); + delt = double(DynaData->h) / nRec; + tsim = DynaData->T; + + if (wtgTrip == 0) + { + for (int stop = nRec, ii = 1; ii <= stop; ii++) + { + // PQ Priority + PQPriority(0); + + // real power regulation + RealPowerReg(); + + // reactive power and voltage regulation + if (QFlg == 0) + { + IqCmdPos = Qcmd / max(0.000001, Vmag); + IqCmdPos = max(Iqmn, min(Iqmx, IqCmdPos)); + } + else + { + ReactivePowerReg(); + VoltageReg(); + } + + // Current regulator + LVPL(); + LVQL(); + CurrentReg(); + if (SimMechFlg > 0) + { + AeroDynamic(); + TorqueReg(); + PitchControl(); + APCLogic(); + WindInertia(); + SwingModel(); + } + + // perform integration + Integrate(); + + // current limiting logic + CurrentLimiting(); + } + } + else + { + E012[0] = V012[0]; + E012[1] = V012[1]; + E012[2] = V012[2]; + } + CalcCurrent(i); + if (DebugTrace == 1) + WriteTraceRecord(); + } + } + + +/* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::DoHelpCmd() + /* ------------------------------------------------------------------------------------------------------------- */ + { + String HelpStr; + AnsiString AnsiHelpStr; + String CRLF; + CRLF = "\x0d\x0a"; + HelpStr = String("Rthev= per unit Thevenin equivalent R.") + CRLF; + HelpStr = HelpStr + "Xthev= per unit Thevenin equivalent X." + CRLF; + HelpStr = HelpStr + "Vss= steady state voltage magnitude." + CRLF; + HelpStr = HelpStr + "Pss= steady state output real power." + CRLF; + HelpStr = HelpStr + "Qss= steady state output reactive power." + CRLF; + HelpStr = HelpStr + "vwind= wind speed in m/s" + CRLF; + HelpStr = HelpStr + "QMOde= Q control mode (0:Q, 1:PF, 2:VV)" + CRLF; + HelpStr = HelpStr + "SimMechFlg= 1 to simulate mechanical system" + CRLF; + HelpStr = HelpStr + "APCFlg= 1 to enable active power control" + CRLF; + HelpStr = HelpStr + "QFlg= 1 to enable reactive power and voltage control" + CRLF; + HelpStr = HelpStr + "DebugTrace= 1 to save dynamic simulation result in csv file" + CRLF; + HelpStr = HelpStr + "delt0= user defined internal simulation step" + CRLF; + HelpStr = HelpStr + "ratedKVA= WTG power rating (either 3600 or 1500)" + CRLF; + HelpStr = HelpStr + "V#_VoltVar= V points on Volt-Var curve" + CRLF; + HelpStr = HelpStr + "Q#_VoltVar= Q points on Volt-Var curve" + CRLF; + HelpStr = HelpStr + "N_WTG= number of WTG in aggregation" + CRLF; + HelpStr = HelpStr + "Help: this help message."; + AnsiHelpStr = ((AnsiString)HelpStr); // Implicit typecast + } + + /* ------------------------------------------------------------------------------------------------------------- */ + double TGE_WTG3_Model::Get_Variable(int i) + /* ------------------------------------------------------------------------------------------------------------- */ + { + double result = 0.0; + result = -9999; + switch (i) + { + case 1: + result = userTrip; + break; + case 2: + result = wtgTrip; + break; + case 3: + result = Pcurtail; + break; + case 4: + result = Pcmd; + break; + case 5: + result = Pgen; + break; + case 6: + result = Qcmd; + break; + case 7: + result = Qgen; + break; + case 8: + result = Vref; + break; + case 9: + result = Vmag; + break; + case 10: + result = vwind; + break; + case 11: + result = WtRef; + break; + case 12: + result = Wt; + break; + case 13: + result = dOmg; + break; + case 14: + result = dFrqPuTest; + break; + case 15: + result = QMode; + break; + case 16: + result = Qref; + break; + case 17: + result = PFref; + break; + case 18: + result = thetaPitch; + break; + default: + break; + } + return result; + } + + /* ------------------------------------------------------------------------------------------------------------- */ + void TGE_WTG3_Model::Set_Variable(int i, const double Value) + /* ------------------------------------------------------------------------------------------------------------- */ + { + switch (i) + { + case 1: + userTrip = round(Value); + break; + case 3: + Pcurtail = Value; + break; + case 10: + vwind = Value; + break; + case 14: + dFrqPuTest = Value; + break; + case 15: + QMode = round(Value); + break; + case 16: + Qref = Value; + break; + case 17: + PFref = Value; + break; + default: + break; + /* Do Nothing for other variables: they are read only */ + } + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::InitTraceFile() + /* ------------------------------------------------------------------------------------------------------------- */ + { + String headerStr; + AssignFile(TraceFile, "GE_WTG3_Trace.CSV"); + Rewrite(TraceFile); + headerStr = String("Time,Iteration,delt,nRec,ratedVln,ratedAmp,") + "vwind,thetaPitch,WtRef,Wt,Pmech,Pcmd,Pele,Pgen,Qcmd,Qele,Qgen," + "Vref,Vmag,VdPos,VqPos,VdNeg,VqNeg,IdPos,IqPos,IdNeg,IqNeg,dOmg," + "debug1,debug2,debug3,debug4,debug5,debug6,debug7,debug8,debug9,debut10"; + Write(TraceFile, headerStr); + WriteLn(TraceFile); + CloseFile(TraceFile); + } + + /* ------------------------------------------------------------------------------------------------------------- */ + + void TGE_WTG3_Model::WriteTraceRecord() + /* ------------------------------------------------------------------------------------------------------------- */ + { + // AssignFile(TraceFile, 'GE_WTG3_Trace.CSV'); + Append(TraceFile); + Write(TraceFile, DynaData->T); + Write(TraceFile, ','); + Write(TraceFile, DynaData->IterationFlag); + Write(TraceFile, ','); + Write(TraceFile, delt); + Write(TraceFile, ','); + Write(TraceFile, nRec); + Write(TraceFile, ','); + Write(TraceFile, ratedVln); + Write(TraceFile, ','); + Write(TraceFile, ratedAmp); + Write(TraceFile, ','); + Write(TraceFile, vwind); + Write(TraceFile, ','); + Write(TraceFile, thetaPitch); + Write(TraceFile, ','); + Write(TraceFile, WtRef); + Write(TraceFile, ','); + Write(TraceFile, Wt); + Write(TraceFile, ','); + Write(TraceFile, Pmech); + Write(TraceFile, ','); + Write(TraceFile, Pcmd); + Write(TraceFile, ','); + Write(TraceFile, Pele); + Write(TraceFile, ','); + Write(TraceFile, Pgen); + Write(TraceFile, ','); + Write(TraceFile, Qcmd); + Write(TraceFile, ','); + Write(TraceFile, Qele); + Write(TraceFile, ','); + Write(TraceFile, Qgen); + Write(TraceFile, ','); + Write(TraceFile, Vref); + Write(TraceFile, ','); + Write(TraceFile, Vmag); + Write(TraceFile, ','); + Write(TraceFile, VdPos); + Write(TraceFile, ','); + Write(TraceFile, VqPos); + Write(TraceFile, ','); + Write(TraceFile, VdNeg); + Write(TraceFile, ','); + Write(TraceFile, VqNeg); + Write(TraceFile, ','); + Write(TraceFile, IdPos); + Write(TraceFile, ','); + Write(TraceFile, IqPos); + Write(TraceFile, ','); + Write(TraceFile, IdNeg); + Write(TraceFile, ','); + Write(TraceFile, IqNeg); + Write(TraceFile, ','); + Write(TraceFile, dOmg); + Write(TraceFile, ','); + Write(TraceFile, debugVar[1 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[2 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[3 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[4 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[5 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[6 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[7 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[8 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[9 - 1]); + Write(TraceFile, ','); + Write(TraceFile, debugVar[10 - 1]); + WriteLn(TraceFile); + CloseFile(TraceFile); + } + +} diff --git a/OpenDSSC/PCElements/WTG3_Model.h b/OpenDSSC/PCElements/WTG3_Model.h new file mode 100644 index 0000000..a0bd176 --- /dev/null +++ b/OpenDSSC/PCElements/WTG3_Model.h @@ -0,0 +1,225 @@ +#ifndef WTG3_ModelH +#define WTG3_ModelH + +#include "System.h" + +#include "Ucomplex.h" +#include "Dynamics.h" +#include "math.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "ParserDel.h" +#include "Command.h" +#include "WindGenVars.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "Dynamics.h" +#include "d2c_structures.h" +#include "ControlElem.h" +#include "mathutil.h" + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2024, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + Definition of WindGen Public Data Record for passing to DLLs and other object +*/ + +/*WindGen public data/state variable structure*/ + + +namespace WTG3_Model +{ + struct TWTG3_Model; + typedef TWTG3_Model* pTWTG3_Model; + + typedef complex TSymCompArray[3]; + typedef complex TPhArray[4]; + typedef TDynamicsRec* pTDynamicsRec; + typedef TWindGenVars* pTWindGenVars; + + const int NumProperties = 23; // motor model parameters + + const int NumVariables = 18; // runtime variables + + + class TGE_WTG3_Model : public PCElement::TPCElement + { + typedef TObject inherited; + + public: + //private: + // ratings + double ratedHz, ratedKVA, ratedOmg, ratedKVll, ratedVln, ratedAmp; + + // filter time constant + double TfltPQM; + double TfltVfbk; + double VmeasMax, ImeasMax; + // PLL + double KpPLL, KiPLL, dOmgLim; + double VdPos, VqPos, VdNeg, VqNeg; + double VdFbkPos, VqFbkPos, VdFbkNeg, VqFbkNeg; + double IdPos, IqPos, IdNeg, IqNeg; + double dOmg, Vang; + // PQ priority control + double QordMax, QordMin, Iphl, Iqhl, ImaxTD; + double TfltIqmxvUp, TfltIqmxvDn; + double Iqmxv, Ipmx, Iqmx, Ipmn, Iqmn; + // Active and reactive power regulator + double V1_VoltVar, V2_VoltVar, V3_VoltVar, V4_VoltVar; + double Q1_VoltVar, Q2_VoltVar, Q3_VoltVar, Q4_VoltVar; + double VCurveVoltVar[6 /*# range 0..5*/], QCurveVoltVar[6 /*# range 0..5*/]; + double Qref, PFref, rrlQcmd; + double PordMax, PordMin, Pcurtail, Pord, Pcmd; + double KpQreg, KiQreg, VrefMin, VrefMax; + double Qcmd, errQgen; + // Voltage regulator + double KpVreg, KiVreg; + double Vref, errVmag; + // LVPL logic + double TfltVmagLVPL, TfltPplvLim0; + double V0LVPL, P0LVPL, V1LVPL, P1LVPL, MaxTrq; + double TfltPplvLimUp, TfltPplvLimDn; + double VmagLVPL, PplvLim0, PplvLim; + // LVQL logic + double TfltVmagLVQL; + double V0LVQL, I0LVQL, V1LVQL, I1LVQL; + double TfltIqlvLimUp, TfltIqlvLimDn; + double IqLimAsymFlt; + double VmagLVQL, IqlvLim; + // Ireg + double TfltIcmdPos, KpIregPos, KiIregPos, rrlIqCmd; + double KpIregNeg, KiIregNeg, AngIregNeg, dE2Lim, E2magLim; + double IdCmdPos, IqCmdPos, IdCmdNeg, IqCmdNeg; + double Iplv, Iqlv; + double errIdPos, errIqPos, errIdNeg, errIqNeg; + // fault detection + double VthrsAsymFlt, TthrsAsymFlt; + int AsymFltFlag; + double TmrAsymFlt; + int underSpeedTrip, wtgTrip; + int userTrip; + + // Aerodynamic model + double KbAero, HalfRhoArAero; + double AlphaAero[5 /*# range 0..4*/][5 /*# range 0..4*/]; + double WtOpt, PmechMax; + // torque regulator + double WtRefMin, WtRefMax; + double TfltWtRef, KpTrqReg, KiTrqReg, TrqRefMax, TrqRefMin; + double TfltPinp, PinpMax, PinpMin, rrlPinp, TfltErrPinp; + double WtRef, errWt, errWtOld, Pinp1, Pinp, TrqRef, errPinp, errPinpFlt; + // pitch control + double KpPitchCtrl, KiPitchCtrl, KpPitchComp, KiPitchComp; + double thetaPitchMax, thetaPitchMin, TfltPitch, rrlThetaPitch; + double thetaPitch, thetaPitch0, errPstl, Pmech, PmechAvl; + double TfltPavlAPC; + double FrqTableAPC[5 /*# range 0..4*/], PwrTableAPC[5 /*# range 0..4*/]; + double TfltPsetAPC, TdelayAPC; + double PavlAPC, PsetAPC, PadeAPC, Pstl; + // wind inertia + double dbWindInertia, TfltDFrqWindInertia, KWindInertia, TfltDPinpWindInertia; + double dPinpMax, dPinpMin, rruDPinp, rrdDPinp; + double dFrqPuTest, dFrqWindInertia, y3Lpf, dPinpWindInertia; + // swing model + double WtBase, Hwtg, Dshaft; + double Wt, dWt; + // regulator output + double dEmax, dEmin; + double EdPos, EqPos, EdNeg, EqNeg; + // integrator + double intg_x[12 /*# range 0..11*/], intg_d[12 /*# range 0..11*/], intg_d_old[12 /*# range 0..11*/]; + int DebugTrace; + TTextRec TraceFile; + double debugVar[10 /*# range 1..10*/]; + double Get_Variable(int i); + void Set_Variable(int i, const double Value); + void abc2seq(complex* abc, complex* seq, double ang); + void seq2abc(complex* abc, complex* seq, double ang); + complex MagLimiter(complex x, double magmin, double magMax); + double LinearInterp(double* xTable, int xTable_maxidx, double* yTable, int yTable_maxidx, double x); + double CalcCp(double Theta, double lmbda); + double CalcPmech(double Theta, double wrotor, double spdwind); + double CalcWtRef(double elePwr); + void Instrumentation(pComplexArray V, pComplexArray i); + void PllLogic(); + void PQPriority(int PQFlag); + void LVPL(); + void LVQL(); + void RealPowerReg(); + void ReactivePowerReg(); + void VoltageReg(); + void CurrentReg(); + void CurrentLimiting(); + void FaultDetection(); + void AeroMPPT(); + void AeroDynamic(); + void TorqueReg(); + void PitchControl(); + void APCLogic(); + void WindInertia(); + void SwingModel(); + void CalcCurrent(pComplexArray i); + void DoHelpCmd(); + void InitTraceFile(); + void WriteTraceRecord(); + + //protected: + public: + // simulation time setup + double tsim, deltSim, delt0, delt; + int nRec, nIterLF; + int QMode, QFlg; + // active power control + int APCFLG; + // simulate mechanical system + int SimMechFlg; + // number of WTG + int N_WTG; + // terminal impedance + double Xthev, Rthev; + complex Zthev; + // terminal voltage and current + TPhArray Vabc, Iabc, Eabc; + TSymCompArray V012, I012, E012; + double Vmag, VmagMin; + double Emag, Eang; + complex Sele; + double Pele, Qele; + double Pgen, Qgen; + // steady state conditions for initialization + double Vss, Pss, Qss; + // wind speed + double vwind; + pTDynamicsRec DynaData; + pTWindGenVars GenData; + void Init(pComplexArray V, pComplexArray i); + void Edit(); // Uses ModelParser + void EditProp(int ParamPointer, String StrVal); + void Integrate(); + void CalcDynamic(pComplexArray V, pComplexArray i); + void CalcPFlow(pComplexArray V, pComplexArray i); + void ReCalcElementData(); + TGE_WTG3_Model(TWindGenVars& GenVars, TDynamicsRec& DynaVars); + virtual ~TGE_WTG3_Model(); + }; + + extern TGE_WTG3_Model* ActiveModel; +} + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace WTG3_Model; +#endif + +#endif // WTG3_ModelH \ No newline at end of file diff --git a/OpenDSSC/PCElements/WindGen.cpp b/OpenDSSC/PCElements/WindGen.cpp new file mode 100644 index 0000000..dd6c8df --- /dev/null +++ b/OpenDSSC/PCElements/WindGen.cpp @@ -0,0 +1,3608 @@ + + +#pragma hdrstop + +#include "WindGen.h" + +#include "Circuit.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "d2c_structures.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace WindGenUserModel; +using namespace WindGenVars; +using namespace mathutil; +using namespace Utilities; + +namespace WindGen +{ + +TWindGenObj::TWindGenObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TWindGenObj::TWindGenObj(String ClassName) : inherited(ClassName) {} +TWindGenObj::TWindGenObj() {} + + +TWindGenObj* ActiveWindGenObj = nullptr; + +const int NumPropsThisClass = 44; // removed Fuel variables + // Dispatch modes +const int Default = 0; +const int LOADMODE = 1; +complex cBuffer[25]; // Temp buffer for calcs 24-phase WindGen? +complex CDoubleOne = cmplx(1,1); +// TwoPI3:Double; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TWindGen::TWindGen() +{ + ; + Class_Name ="WindGen"; + DSSClassType = DSSClassType + WINDGEN_ELEMENT; // In both PCelement and Genelement list + ActiveElement = 0; + + // Set Register names + RegisterNames[1 - 1] ="kWh"; + RegisterNames[2 - 1] ="kvarh"; + RegisterNames[3 - 1] ="Max kW"; + RegisterNames[4 - 1] ="Max kVA"; + RegisterNames[5 - 1] ="Hours"; + RegisterNames[6 - 1] ="$"; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + WindGenClass[ActiveActor] = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TWindGen::~TWindGen() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TWindGen::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Define Property names + PropertyName[1 - 1] ="phases"; + PropertyHelp[1 - 1] ="Number of Phases, this WindGen. Power is evenly divided among phases."; + + PropertyName[2 - 1] ="bus1"; + PropertyHelp[2 - 1] ="Bus to which the WindGen is connected. May include specific node specification."; + + PropertyName[3 - 1] ="kv"; + PropertyHelp[3 - 1] ="Nominal rated (1.0 per unit) voltage, kV, for WindGen. For 2- and 3-phase WindGens, specify phase-phase kV. " + "Otherwise, for phases=1 or phases>3, specify actual kV across each branch of the WindGen. " + "If wye (star), specify phase-neutral kV. " + "If delta or phase-phase connected, specify phase-phase kV."; + + PropertyName[4 - 1] ="kW"; + PropertyHelp[4 - 1] = String("Total base kW for the WindGen. A positive value denotes power coming OUT of the element, ") + CRLF + +"which is the opposite of a load. This value is modified depending on the dispatch mode. " + +"Unaffected by the global load multiplier and growth curves. " + +"If you want there to be more generation, you must add more WindGens or change this value."; + + PropertyName[5 - 1] ="PF"; + PropertyHelp[5 - 1] = String("WindGen power factor. Default is 0.80. Enter negative for leading powerfactor ""(when kW and kvar have opposite signs.)") + CRLF + +"A positive power factor for a WindGen signifies that the WindGen produces vars " + + CRLF + +"as is typical for a synchronous WindGen. Induction machines would be " + + CRLF + +"generally specified with a negative power factor."; + + PropertyName[6 - 1] ="model"; + PropertyHelp[6 - 1] = String("Integer code for the model to use for generation variation with voltage. ""Valid values are:") + CRLF + + CRLF + +"1:WindGen injects a constant kW at specified power factor." + + CRLF + +"2:WindGen is modeled as a constant admittance." + + CRLF + +"3:Const kW, constant kV. Voltage-regulated model." + + CRLF + +"4:Const kW, Fixed Q (Q never varies)" + + CRLF + +"5:Const kW, Fixed Q(as a constant reactance)" + + CRLF + +"6:Compute load injection from User-written Model.(see usage of Xd, Xdp)"; + + PropertyName[7 - 1] ="yearly"; + PropertyHelp[7 - 1] ="Dispatch shape to use for yearly-mode simulations. Must be previously defined " + "as a Loadshape object. If this is not specified, a constant value is assumed (no variation). " + "Set to NONE to reset to no loadahape. " + "Nominally for 8760 simulations. If there are fewer points in the designated shape than " + "the number of points in the solution, the curve is repeated."; + + PropertyName[8 - 1] ="daily"; + PropertyHelp[8 - 1] ="Dispatch shape to use for daily-mode simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically." + "Set to NONE to reset to no loadahape. "; // daily dispatch (hourly) + + PropertyName[9 - 1] ="duty"; + PropertyHelp[9 - 1] ="Load shape to use for duty cycle dispatch simulations such as for wind or solar generation. " + "Must be previously defined as a Loadshape object. " + "Typically would have time intervals less than 1 hr -- perhaps, in seconds. " + "Set to NONE to reset to no loadahape. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat."; // as for wind generation + + PropertyName[10 - 1] ="conn"; + PropertyHelp[10 - 1] ="={wye|LN|delta|LL}. Default is wye."; + + PropertyName[11 - 1] ="kvar"; + PropertyHelp[11 - 1] ="Specify the base kvar. Alternative to specifying the power factor. Side effect: " + " the power factor value is altered to agree based on present value of kW."; + + PropertyName[12 - 1] ="class"; + PropertyHelp[12 - 1] ="An arbitrary integer number representing the class of WindGen so that WindGen values may " + "be segregated by class."; // integer + + PropertyName[13 - 1] ="debugtrace"; + PropertyHelp[13 - 1] ="{Yes | No } Default is no. Turn this on to capture the progress of the WindGen model " + "for each iteration. Creates a separate file for each WindGen named \"GEN_name.CSV\""; // per unit set point voltage for power flow model + + PropertyName[14 - 1] ="Vminpu"; + PropertyHelp[14 - 1] ="Default = 0.90. Minimum per unit voltage for which the Model is assumed to apply. " + "Below this value, the Windgen model reverts to a constant impedance model. For model 7, the current is " + "limited to the value computed for constant power at Vminpu."; + + PropertyName[15 - 1] ="Vmaxpu"; + PropertyHelp[15 - 1] ="Default = 1.10. Maximum per unit voltage for which the Model is assumed to apply. " + "Above this value, the Windgen model reverts to a constant impedance model."; + + PropertyName[16 - 1] ="kVA"; + PropertyHelp[16 - 1] ="kVA rating of electrical machine. Defaults to 1.2* kW if not specified. Applied to machine or inverter definition for Dynamics mode solutions. "; + + PropertyName[17 - 1] ="MVA"; + PropertyHelp[17 - 1] ="MVA rating of electrical machine. Alternative to using kVA=."; + + PropertyName[18 - 1] ="UserModel"; + PropertyHelp[18 - 1] ="Name of DLL containing user-written model, which computes the terminal currents for Dynamics studies, " + "overriding the default model. Set to \"none\" to negate previous setting."; + + PropertyName[19 - 1] ="UserData"; + PropertyHelp[19 - 1] ="String (in quotes or parentheses) that gets passed to user-written model for defining the data required for that model."; + + PropertyName[20 - 1] ="DutyStart"; + PropertyHelp[20 - 1] ="Starting time offset [hours] into the duty cycle shape for this WindGen, defaults to 0"; + + PropertyName[21 - 1] ="DynamicEq"; + PropertyHelp[21 - 1] ="The name of the dynamic equation (DinamicExp) that will be used for defining the dynamic behavior of the generator. " + "if not defined, the generator dynamics will follow the built-in dynamic equation."; + + PropertyName[22 - 1] ="DynOut"; + PropertyHelp[22 - 1] ="The name of the variables within the Dynamic equation that will be used to govern the generator dynamics." + "This generator model requires 2 outputs from the dynamic equation: " + + CRLF + CRLF + + "1. Shaft speed (velocity) relative to synchronous speed." + CRLF + + "2. Shaft, or power, angle (relative to synchronous reference frame)." + CRLF + CRLF + + "The output variables need to be defined in the same order."; + + PropertyName[23 - 1] = "Rthev"; + PropertyHelp[23 - 1] = "per unit Thevenin equivalent R."; + + PropertyName[24 - 1] = "Xthev"; + PropertyHelp[24 - 1] = "per unit Thevenin equivalent X."; + + PropertyName[25 - 1] = "Vss"; + PropertyHelp[25 - 1] = "Steady state voltage magnitude."; + + PropertyName[26 - 1] = "Pss"; + PropertyHelp[26 - 1] = "Steady state output real power."; + + PropertyName[27 - 1] = "Qss"; + PropertyHelp[27 - 1] = "Steady state output reactive power."; + + PropertyName[28 - 1] = "vwind"; + PropertyHelp[28 - 1] = "Wind speed in m/s"; + + PropertyName[29 - 1] = "QMode"; + PropertyHelp[29 - 1] = "Q control mode (0:Q, 1:PF, 2:VV)."; + + PropertyName[30 - 1] = "SimMechFlg"; + PropertyHelp[30 - 1] = "1 to simulate mechanical system. Otherwise (0) only uses the electrical system. For dynamics simulation purposes."; + + PropertyName[31 - 1] = "APCFlg"; + PropertyHelp[31 - 1] = "1 to enable active power control."; + + PropertyName[32 - 1] = "QFlg"; + PropertyHelp[32 - 1] = "1 to enable reactive power and voltage control."; + + PropertyName[33 - 1] = "delt0"; + PropertyHelp[33 - 1] = "User defined internal simulation step."; + + PropertyName[34 - 1] = "N_WTG"; + PropertyHelp[34 - 1] = "Number of WTG in aggregation."; + + PropertyName[35 - 1] = "VV_Curve"; + PropertyHelp[35 - 1] = "Name of the XY curve defining the control curve for implementing Vol-var control with this inverter."; + + PropertyName[36 - 1] = "Ag"; + PropertyHelp[36 - 1] = "Gearbox ratio (Default 1/90)."; + + PropertyName[37 - 1] = "Cp"; + PropertyHelp[37 - 1] = "Turbine performance coefficient (deafult 0.41)."; + + PropertyName[38 - 1] = "Lamda"; + PropertyHelp[38 - 1] = "Tip speed ratio (Default 7.95)."; + + PropertyName[39 - 1] = "P"; + PropertyHelp[39 - 1] = "Number of pole pairs of the induction generator (Default 2)."; + + PropertyName[40 - 1] = "pd"; + PropertyHelp[40 - 1] = "Air density in kg/m3 (Default 1.225)."; + + PropertyName[41 - 1] = "PLoss"; + PropertyHelp[41 - 1] = "Name of the XYCurve object describing the active power losses in pct versus the wind speed."; + + PropertyName[42 - 1] = "Rad"; + PropertyHelp[42 - 1] = "Rotor radius in meters (Default 40)."; + + PropertyName[43 - 1] = "VCutIn"; + PropertyHelp[43 - 1] = "Cut-in speed for the wind generator (m/s - default 5)."; + + PropertyName[44 - 1] = "VCutOut"; + PropertyHelp[44 - 1] = "Cut-out speed for the wind generator (m/s - default 23)."; + + /*Removed Fuel-related variables 40-44 from Generator model*/ + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override default help string + PropertyHelp[NumPropsThisClass + 1 - 1] ="Name of harmonic voltage or current spectrum for this WindGen. " + "Voltage behind Xd\" for machine - default. Current injection for inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TWindGen::NewObject(const String ObjName) +{ + int result = 0; + // Make a new WindGen and add it to WindGen class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TWindGenObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TWindGen::SetNcondsForConnection() +{ + /*# with ActiveWindGenObj do */ + { + auto with0 = ActiveWindGenObj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases + 1); + break; + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); + break; + } + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TWindGen::InterpretConnection(const String s) +{ + String TestS; + /*# with ActiveWindGenObj do */ + { + auto with0 = ActiveWindGenObj; + TestS = LowerCase(s); + switch(TestS[1]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[2]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + SetNcondsForConnection(); + + /*VBase is always L-N voltage unless 1-phase device or more than 3 phases*/ + /*# with WindGenVars do */ + { + auto& with1 = with0->WindGenVars; + switch(with0->Fnphases) + { /*CASE Connection OF + 1: VBase := kVWindGenBase * 1000.0 ; + Else*/ + case 2: case 3: + with0->VBase = with1.kVWindGenBase * InvSQRT3x1000; + break; // L-N Volts + default: + with0->VBase = with1.kVWindGenBase * 1000.0; // Just use what is supplied + break; + } + } + /*End;*/ + with0->VBase95 = with0->Vminpu * with0->VBase; + with0->VBase105 = with0->Vmaxpu * with0->VBase; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int InterpretDispMode(const String s) +{ + int result = 0; + switch(LowerCase(s)[0]) + { + case L'l': + result = LOADMODE; + break; + default: + result = Default; + break; + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TWindGen::Edit(int ActorID) +{ + int result = 0; + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveWindGenObj = (TWindGenObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveWindGenObj); + result = 0; + /*# with ActiveWindGenObj do */ + { + auto with0 = ActiveWindGenObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1],Param); + else + DoSimpleMsg("Unknown parameter \"" + ParamName + "\" for WindGen \"" + with0->get_Name() + "\"", 560); + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 0: + DoSimpleMsg("Unknown parameter \"" + ParamName + "\" for Object \"" + Class_Name + "." + with0->get_Name() + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case 3: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_()); + break; + case 4: + with0->kWBase = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->PFNominal = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->GenModel = Parser[ActorID]->MakeInteger_(); + break; + case 7: + with0->YearlyShape = Param; + break; + case 8: + with0->DailyDispShape = Param; + break; + case 9: + with0->DutyShape = Param; + break; + case 10: + InterpretConnection(Param); + break; + case 11: + with0->Set_Presentkvar(Parser[ActorID]->MakeDouble_()); + break; + case 12: + with0->GenClass = Parser[ActorID]->MakeInteger_(); + break; + case 14: + with0->Vminpu = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->Vmaxpu = Parser[ActorID]->MakeDouble_(); + break; + case 16: + { + with0->WindModelDyn->EditProp(13, Param); + with0->WindGenVars.kVArating = Parser[ActorID]->MakeDouble_(); + } + break; + case 17: + { + with0->WindGenVars.kVArating = Parser[ActorID]->MakeDouble_() * 1e3; // 'MVA' + with0->WindModelDyn->EditProp(13, to_string(with0->WindGenVars.kVArating)); + } + break; + case 18: + with0->UserModel->Set_Name(Parser[ActorID]->MakeString_()); + break; // Connect to user written models + case 19: + with0->UserModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; // Send edit string to user model + case 20: + with0->DutyStart = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->DynamicEq = Param; + break; + case 22: + with0->SetDynOutput(Param); + break; + case 23: + with0->WindModelDyn->EditProp(1,Param); + break; + case 24: + with0->WindModelDyn->EditProp(2, Param); + break; + case 25: + with0->WindModelDyn->EditProp(3, Param); + break; + case 26: + with0->WindModelDyn->EditProp(4, Param); + break; + case 27: + with0->WindModelDyn->EditProp(5, Param); + break; + case 28: + with0->WindModelDyn->EditProp(6, Param); + break; + case 29: + with0->WindModelDyn->EditProp(7, Param); + break; + case 30: + with0->WindModelDyn->EditProp(8, Param); + break; + case 31: + with0->WindModelDyn->EditProp(9, Param); + break; + case 32: + with0->WindModelDyn->EditProp(10, Param); + break; + case 33: + with0->WindModelDyn->EditProp(12, Param); + break; + case 34: + with0->WindModelDyn->EditProp(22, Param); + break; + case 35: + with0->VV_Curve = Param; + break; + case 36: + with0->WindGenVars.ag = Parser[ActorID]->MakeDouble_(); + break; + case 37: + with0->WindGenVars.Cp = Parser[ActorID]->MakeDouble_(); + break; + case 38: + with0->WindGenVars.Lamda = Parser[ActorID]->MakeDouble_(); + break; + case 39: + with0->WindGenVars.Poles = Parser[ActorID]->MakeDouble_(); + break; + case 40: + with0->WindGenVars.pd = Parser[ActorID]->MakeDouble_(); + break; + case 41: + with0->WindGenVars.PLoss = Parser[ActorID]->MakeString_(); + break; + case 42: + with0->WindGenVars.Rad = Parser[ActorID]->MakeDouble_(); + break; + case 43: + with0->WindGenVars.VCutin = Parser[ActorID]->MakeDouble_(); + break; + case 44: + with0->WindGenVars.VCutout = Parser[ActorID]->MakeDouble_(); + break; + // Inherited parameters + default: + inherited::ClassEdit(ActiveWindGenObj, ParamPointer - NumPropsThisClass); + break; + } + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + + // keep kvar nominal up to date with kW and PF + case 4: case 5: + with0->SyncUpPowerQuantities(); + break; + + // if a model 3 WindGen added, force calc of dQdV + case 6: + if(with0->GenModel == 3) + ActiveCircuit[ActorID]->Solution->SolutionInitialized = false; + break; + + /*Set shape objects; returns nil if not valid*/ + /*Sets the kW and kvar properties to match the peak kW demand from the Loadshape*/ + case 7: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(ASSIGNED(with0->YearlyShapeObj)) + /*# with YearlyShapeObj do */ + { + auto with1 = with0->YearlyShapeObj; + if(with1->UseActual) + with0->SetkWkvar(with1->MaxP, with1->MaxQ); + } + } + break; + case 8: + { + with0->DailyDispShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyDispShape)); + if(ASSIGNED(with0->DailyDispShapeObj)) + /*# with DailyDispShapeObj do */ + { + auto with2 = with0->DailyDispShapeObj; + if(with2->UseActual) + with0->SetkWkvar(with2->MaxP, with2->MaxQ); + } + } + break; + case 9: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(ASSIGNED(with0->DutyShapeObj)) + /*# with DutyShapeObj do */ + { + auto with3 = with0->DutyShapeObj; + if(with3->UseActual) + with0->SetkWkvar(with3->MaxP, with3->MaxQ); + } + } + break; + case 13: + if(with0->DebugTrace) + { + int stop = 0; + AssignFile(with0->Tracefile, GetOutputDirectory() +"WINDGEN_" + with0->get_Name() +".CSV"); + Rewrite(with0->Tracefile); + IOResultToException(); + Write(with0->Tracefile,"t, Iteration, LoadMultiplier, Mode, LoadModel, GenModel, dQdV, Avg_Vpu, Vdiff, MQnominalperphase, MPnominalperphase, CurrentType"); + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iinj") + IntToStr(i) +"|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iterm") + IntToStr(i) +"|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Vterm") + IntToStr(i) +"|"); + } + Write(with0->Tracefile,",Vthev, Theta"); + WriteLn(with0->Tracefile); + CloseFile(with0->Tracefile); + } + break; + case 16: case 17: + with0->kVANotSet = false; + break; + case 21: + { + with0->DynamicEqObj = (TDynamicExpObj*) TDynamicExpClass[ActorID]->Find(with0->DynamicEq); + if (ASSIGNED(with0->DynamicEqObj)) + { + with0->DynamicEqVals.resize(with0->DynamicEqObj->get_FNumVars()); + for (int idx = 0; idx < with0->DynamicEqVals.size(); idx++) + with0->DynamicEqVals[idx].resize(2); + } + } + break; + case 35: // get the Volt-var control curve + { + with0->VV_CurveObj = (TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->VV_Curve); + if (ASSIGNED(with0->VV_CurveObj)) + { + auto with1 = with0->VV_CurveObj; + for (int idx = 1; idx <= with1->FNumPoints; idx++) + { + with0->WindModelDyn->EditProp(13 + idx, to_string(with1->Get_XValue(idx))); + with0->WindModelDyn->EditProp(17 + idx, to_string(with1->Get_YValue(idx))); + } + } + else + DoSimpleMsg("Volt-var control curve \"" + with0->VV_Curve + "\" not found, make sure that it was not defined before this element", 565); + } + break; + case 41: // get the losses curve + { + with0->Loss_CurveObj = (TXYcurveObj*)XYCurveClass[ActorID]->Find(with0->WindGenVars.PLoss); + if (!(ASSIGNED(with0->Loss_CurveObj))) + DoSimpleMsg("Losses curve \"" + with0->VV_Curve + "\" not found, make sure that it was not defined before this element", 566); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TWindGen::MakeLike(const String OtherWindGenName) +{ + int result = 0; + TWindGenObj* OtherWindGen = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherWindGen = ((TWindGenObj*) Find(OtherWindGenName)); + if(OtherWindGen != nullptr) + /*# with ActiveWindGenObj do */ + { + auto with0 = ActiveWindGenObj; + int stop = 0; + if(with0->Fnphases != OtherWindGen->Fnphases) + { + with0->Set_NPhases(OtherWindGen->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->WindGenVars.kVWindGenBase = OtherWindGen->WindGenVars.kVWindGenBase; + with0->VBase = OtherWindGen->VBase; + with0->Vminpu = OtherWindGen->Vminpu; + with0->Vmaxpu = OtherWindGen->Vmaxpu; + with0->VBase95 = OtherWindGen->VBase95; + with0->VBase105 = OtherWindGen->VBase105; + with0->kWBase = OtherWindGen->kWBase; + with0->kvarBase = OtherWindGen->kvarBase; + with0->WindGenVars.Pnominalperphase = OtherWindGen->WindGenVars.Pnominalperphase; + with0->PFNominal = OtherWindGen->PFNominal; + with0->WindGenVars.Qnominalperphase = OtherWindGen->WindGenVars.Qnominalperphase; + with0->varMin = OtherWindGen->varMin; + with0->varMax = OtherWindGen->varMax; + with0->Connection = OtherWindGen->Connection; + // Rneut := OtherWindGen.Rneut; + // Xneut := OtherWindGen.Xneut; + with0->YearlyShape = OtherWindGen->YearlyShape; + with0->YearlyShapeObj = OtherWindGen->YearlyShapeObj; + with0->DailyDispShape = OtherWindGen->DailyDispShape; + with0->DailyDispShapeObj = OtherWindGen->DailyDispShapeObj; + with0->DutyShape = OtherWindGen->DutyShape; + with0->DutyShapeObj = OtherWindGen->DutyShapeObj; + with0->DutyStart = OtherWindGen->DutyStart; + with0->GenClass = OtherWindGen->GenClass; + with0->GenModel = OtherWindGen->GenModel; + with0->IsFixed = OtherWindGen->IsFixed; + with0->WindGenVars.VTarget = OtherWindGen->WindGenVars.VTarget; + with0->Vpu = OtherWindGen->Vpu; + with0->kvarMax = OtherWindGen->kvarMax; + with0->kvarMin = OtherWindGen->kvarMin; + with0->FForcedON = OtherWindGen->FForcedON; + with0->kVANotSet = OtherWindGen->kVANotSet; + with0->WindGenVars.kVArating = OtherWindGen->WindGenVars.kVArating; + with0->WindGenVars.puXd = OtherWindGen->WindGenVars.puXd; + with0->WindGenVars.puXdp = OtherWindGen->WindGenVars.puXdp; + with0->WindGenVars.puXdpp = OtherWindGen->WindGenVars.puXdpp; + with0->WindGenVars.Hmass = OtherWindGen->WindGenVars.Hmass; + with0->WindGenVars.Theta = OtherWindGen->WindGenVars.Theta; + with0->WindGenVars.Speed = OtherWindGen->WindGenVars.Speed; + with0->WindGenVars.w0 = OtherWindGen->WindGenVars.w0; + with0->WindGenVars.dSpeed = OtherWindGen->WindGenVars.dSpeed; + with0->WindGenVars.D = OtherWindGen->WindGenVars.D; + with0->WindGenVars.Dpu = OtherWindGen->WindGenVars.Dpu; + with0->WindGenVars.XRdp = OtherWindGen->WindGenVars.XRdp; + with0->UserModel->FName = OtherWindGen->UserModel->FName; // Connect to user written models + with0->ShaftModel->FName = OtherWindGen->ShaftModel->FName; + ClassMakeLike(OtherWindGen); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0->FPropertyValue)[i - 1] = (OtherWindGen->FPropertyValue)[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Load MakeLike: \"") + OtherWindGenName + +"\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + +int TWindGen::Init(int Handle, int ActorID) +{ + int result = 0; + TWindGenObj* P = nullptr; + if(Handle == 0) // init all + { + P = (TWindGenObj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TWindGenObj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TWindGenObj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TWindGen.Init", -1); + result = 0; + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to reset + +void TWindGen::ResetRegistersAll(int ActorID) +{ + TWindGenObj* pGen = nullptr; + pGen = ((TWindGenObj*) ActiveCircuit[ActorID]->WindGens.Get_First()); + while((pGen != nullptr)) + { + pGen->ResetRegisters(); + pGen = ((TWindGenObj*) ActiveCircuit[ActorID]->WindGens.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to take a sample + +void TWindGen::SampleAll(int ActorID) +{ + TWindGenObj* pGen = nullptr; + pGen = ((TWindGenObj*) ActiveCircuit[ActorID]->WindGens.Get_First()); + while(pGen != nullptr) + { + if(pGen->Get_Enabled()) + pGen->TakeSample(ActorID); + pGen = ((TWindGenObj*) ActiveCircuit[ActorID]->WindGens.Get_Next()); + } +} + +//---------------------------------------------------------------------------- + +TWindGenObj::TWindGenObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + Model7MaxPhaseCurr(0.0), + Model7LastAngle(0.0), + DebugTrace(false), + DeltaQMax(0.0), + DQDV(0.0), + DQDVSaved(0.0), + FForcedON(false), + FirstSampleAfterReset(false), + IsFixed(false), + WindGenSolutionCount(0), + GenFundamental(0.0), + GenON(false), + GenSwitchOpen(false), + kVANotSet(false), + LastGrowthFactor(0.0), + LastYear(0), + OpenWindGenSolutionCount(0), + PVFactor(0.0), + RandomMult(0.0), + Reg_Hours(0), + Reg_kvarh(0), + Reg_kWh(0), + Reg_MaxkVA(0), + Reg_MaxkW(0), + Reg_Price(0), + UserModel(nullptr), + ShaftModel(nullptr), + V_Avg(0.0), + V_Remembered(0.0), + var_Remembered(0.0), + varBase(0.0), + varMax(0.0), + varMin(0.0), + VBase(0.0), + VBase105(0.0), + VBase95(0.0), + YPrimOpenCond(nullptr), + YQFixed(0.0), + ShapeIsActual(false), + ForceBalanced(false), + Connection(0), + DailyDispShapeObj(nullptr), + DutyShapeObj(nullptr), + DutyStart(0.0), + GenClass(0), + GenModel(0), + kvarBase(0.0), + kvarMax(0.0), + kvarMin(0.0), + kWBase(0.0), + PFNominal(0.0), + Vpu(0.0), + Vmaxpu(0.0), + Vminpu(0.0), + GenActive(false), + YearlyShapeObj(nullptr) +{ + int i; + + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // + WINDGEN_ELEMENT; // In both PCelement and Genelement list + Set_NPhases(3); + Fnconds = 4; // defaults to wye + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations + kWBase = 1000.0; + kvarBase = 60.0; + kvarMax = kvarBase * 2.0; + kvarMin = -kvarMax; + PFNominal = 0.88; + YearlyShape =""; + YearlyShapeObj = nullptr; // if YearlyShapeobj = nil then the load alway stays nominal * global multipliers + DailyDispShape =""; + DailyDispShapeObj = nullptr; // if DaillyShapeobj = nil then the load alway stays nominal * global multipliers + DutyShape =""; + DutyShapeObj = nullptr; // if DutyShapeobj = nil then the load alway stays nominal * global multipliers + DutyStart = 0.0; + Connection = 0; // Wye (star) + GenModel = 1; /*Typical fixed kW negative load*/ + GenClass = 1; + LastYear = 0; + LastGrowthFactor = 1.0; + DQDVSaved = 0.0; // Initialize this here. Allows WindGens to be turned off and on + WindGenSolutionCount = -1; // For keep track of the present solution in Injcurrent calcs + OpenWindGenSolutionCount = -1; + YPrimOpenCond = nullptr; + WindGenVars.kVWindGenBase = 12.47; + Vpu = 1.0; + WindGenVars.VTarget = 1000.0 * Vpu * WindGenVars.kVWindGenBase / SQRT3; /*Line-to-Neutral target*/ + VBase = 7200.0; + Vminpu = 0.90; + Vmaxpu = 1.10; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + RandomMult = 1.0; + IsFixed = false; + + /*Machine rating stuff*/ + WindGenVars.kVArating = kWBase * 1.2; + kVANotSet = true; // Flag for default value for kVA + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + with0.puXd = 1.0; + with0.puXdp = 0.28; + with0.puXdpp = 0.20; + with0.XD = with0.puXd * Sqr(with0.kVWindGenBase) * 1000.0L / with0.kVArating; + with0.Xdp = with0.puXdp * Sqr(with0.kVWindGenBase) * 1000.0L / with0.kVArating; + with0.Xdpp = with0.puXdpp * Sqr(with0.kVWindGenBase) * 1000.0L / with0.kVArating; + with0.Hmass = 1.0; // W-sec/VA rating + with0.Theta = 0.0; + with0.w0 = TwoPi * BaseFrequency; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + with0.D = 1.0; + with0.XRdp = 20.0; + + // Added for the wind generator specifically + with0.PLoss = ""; + with0.ag = 0.0111111111111111111; + with0.Cp = 0.41; + with0.Lamda = 7.95; + with0.Poles = 2; + with0.pd = 1.225; + with0.Rad = 40; + with0.VCutin = 5; + with0.VCutout = 23; + with0.Pm = 0; + with0.Ps = 0; + with0.Pr = 0; + with0.Pg = 0; + with0.s = 0; + } + + /*Advertise Genvars struct as public*/ + PublicDataStruct = ((void*) &WindGenVars); + PublicDataSize = sizeof(TWindGenVars); + UserModel = new TWindGenUserModel(&WindGenVars); + ShaftModel = new TWindGenUserModel(&WindGenVars); + + // Register values inherited from Generator model + Reg_kWh = 1 - 1; + Reg_kvarh = 2 - 1; + Reg_MaxkW = 3 - 1; + Reg_MaxkVA = 4 - 1; + Reg_Hours = 5 - 1; + Reg_Price = 6 - 1; + PVFactor = 0.1; + DebugTrace = false; + FForcedON = false; + GenSwitchOpen = false; + ShapeIsActual = false; + ForceBalanced = false; + + Spectrum ="defaultgen"; // override base class + + GenActive = true; // variable to use if needed + + // Creates the Dynamic model for the Wind Turbine + WindModelDyn = new TGE_WTG3_Model(WindGenVars, ActiveCircuit[ActiveActor]->Solution->DynaVars); + WindModelDyn->EditProp(6, "12"); + WindModelDyn->QMode = 0; + + Loss_CurveObj = nullptr; + VV_CurveObj = nullptr; + + InitPropertyValues(0); + RecalcElementData(ActiveActor); + + for (i = 0; i < NumWGenRegisters; i++) + { + Registers[i] = 0.0; + Derivatives[i] = 0.0; + } +} + + +//---------------------------------------------------------------------------- + +TWindGenObj::~TWindGenObj() +{ + delete YPrimOpenCond; + delete UserModel; + delete ShaftModel; + // inherited::Destroy(); +} + + +//---------------------------------------------------------------------------- + +void TWindGenObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + RandomMult = Gauss(YearlyShapeObj->Get_Mean(), YearlyShapeObj->Get_StdDev()); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + RandomMult = QuasiLogNormal(YearlyShapeObj->Get_Mean()); + break; + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- +/*Evaluates if the value provided corresponds to a constant value or to an operand + for calculating the value using the simulation results*/ + +int TWindGenObj::CheckIfDynVar(String myVar, int ActorID) +{ + int result = 0; + int myOp = 0; // Operator found + + String myValue; // Value entered by the user + result = -1; + if ((DynamicEqObj != NULL)) + { + result = DynamicEqObj->Get_Var_Idx(myVar); + if ((result >= 0) && (result < 50000)) + { + myValue = Parser[ActorID]->MakeString_(); + if (DynamicEqObj->Check_If_CalcValue(myValue, myOp)) + { + // Adss the pair (var index + operand index) + DynamicEqPair.push_back(result); + DynamicEqPair.push_back(myOp); + } + else // Otherwise, move the value to the values array + DynamicEqVals[result][0] = Parser[ActorID]->MakeDouble_(); + } + else + result = -1; // in case is a constant + } + return result; +} + +//---------------------------------------------------------------------------- +/*Obtains the indexes of the given variables to use them as reference for setting +the dynamic output for the generator*/ + +void TWindGenObj::SetDynOutput(String myVar) +{ + int VarIdx = 0, + idx = 0; + TStringList myStrArray; + + if (DynamicEqObj != NULL) // Making sure we have a dynamic eq linked + { + // First, set the length for the index array, 2 variables in this case + DynOut.resize(2); + InterpretTStringListArray(myVar, myStrArray); + // ensuring they are lower case + for (int stop = 1, idx = 0; idx <= stop; idx++) + { + myStrArray[idx] = LowerCase(myStrArray[idx]); + VarIdx = DynamicEqObj->Get_Out_Idx(myStrArray[idx]); + if (VarIdx < 0) + // Being here means that the given name doesn't exist or is a constant + DoSimpleMsg("DynamicExp variable \"" + myStrArray[idx] + "\" not found or not defined as an output.", 50008); + else + DynOut[idx] = VarIdx; + } + myStrArray.clear(); + } + else + DoSimpleMsg(String("A DynamicExp object needs to be assigned to this element before this declaration: DynOut = [") + myVar + "]", 50007); +} + +//---------------------------------------------------------------------------- +/*Returns the names of the variables to be used as outputs for the dynamic expression*/ + +String TWindGenObj::GetDynOutputStr() +{ + String result = "["; + int idx = 0; + + if (DynamicEqObj != nullptr) // Making sure we have a dynamic eq linked + { + for (int stop = DynOut.size() - 1, idx = 0; idx <= stop; idx++) + result = result + DynamicEqObj->Get_VarName(DynOut[idx]) + ","; + } + result = result + "]"; // Close array str + return result; +} + +//---------------------------------------------------------------------------- + +void TWindGenObj::CalcDailyMult(double hr) +{ + if(DailyDispShapeObj != nullptr) + { + ShapeFactor = DailyDispShapeObj->GetMult(hr); + ShapeIsActual = DailyDispShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Default to no daily variation +} + + +//---------------------------------------------------------------------------- + +void TWindGenObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr + DutyStart); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult if no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TWindGenObj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Defaults to no variation +} + + + +//---------------------------------------------------------------------------- + +void TWindGenObj::SetNominalGeneration(int ActorID) +{ + complex myV = CZero; + double VMag = 0.0, + VMagTmp = 0.0, + LeadLag = 0.0, + kVATmp = 0.0, + kvarCalc = 0.0, + myLosses = 0.0, + Factor = 0.0; + bool GenOn_Saved = false; + int i = 0; + + + GenOn_Saved = GenON; + ShapeFactor = cmplx(WindModelDyn->vwind, 0); + // Check to make sure the generation is ON + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + auto with0 = ActiveCircuit[ActorID]; + auto with1 = ActiveCircuit[ActorID]->Solution; + { + { + kvarCalc = 0.0; + GenON = true; // The first assumption is that the generator is ON + + // first, get wind speed (Factor) + if (IsFixed) + { + Factor = 1.0; // for fixed WindGens, set constant + } + else + { + switch (with1->Get_SolMode()) + { + case SNAPSHOT: + Factor = with0->GenMultiplier; + break; + case DAILYMODE: + { + Factor = with0->GenMultiplier; + CalcDailyMult(with1->DynaVars.dblHour); // Daily dispatch curve + } + break; + case YEARLYMODE: + { + Factor = with0->GenMultiplier; + CalcYearlyMult(with1->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + Factor = with0->GenMultiplier; + CalcDutyMult(with1->DynaVars.dblHour); + } + break; + case GENERALTIME: + case // General sequential time simulation + DYNAMICMODE: + { + Factor = with0->GenMultiplier; + // This mode allows use of one class of load shape + switch (with0->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with1->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with1->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with1->DynaVars.dblHour); + break; + default: + ShapeFactor = cmplx(WindModelDyn->vwind, 0); // default to the wind speed set by default + } + } + break; + case MONTECARLO1: + case MONTEFAULT: + case FAULTSTUDY: + Factor = with0->GenMultiplier * 1.0; + break; + case MONTECARLO2: + case MONTECARLO3: + case LOADDURATION1: + case LOADDURATION2: + { + Factor = with0->GenMultiplier; + CalcDailyMult(with1->DynaVars.dblHour); + } + break; + case PEAKDAY: + { + Factor = with0->GenMultiplier; + CalcDailyMult(with1->DynaVars.dblHour); + } + break; + case AUTOADDFLAG: + Factor = 1.0; + break; + default: + Factor = with0->GenMultiplier; + } + } + WindModelDyn->vwind = ShapeFactor.re; + if ((ShapeFactor.re > WindGenVars.VCutout) || (ShapeFactor.re < WindGenVars.VCutin)) + { + WindGenVars.Pnominalperphase = 0.001 * kWBase; + WindGenVars.Qnominalperphase = 0.0; + WindGenVars.Pm = 0.0; + WindGenVars.Pg = 0.0; + WindGenVars.Ps = 0.0; + WindGenVars.Pr = 0.0; + WindGenVars.s = 0.0; + } + else + { + if (!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + // start by getting the losses from the provided curve (if any) + if (ASSIGNED(Loss_CurveObj)) + myLosses = Loss_CurveObj->GetYValue_(WindModelDyn->vwind); + else + myLosses = 0.0; // no losses given that the curve was not provided + LeadLag = 1; + /*# with WindGenVars do */ + { + auto& with2 = WindGenVars; + + with2.Pm = 0.5 * with2.pd * PI * pow(with2.Rad, 2) * pow(ShapeFactor.re, 3) * with2.Cp; + myLosses = with2.Pm * myLosses / 100; + with2.Pg = (with2.Pm - myLosses) / 1e3; // in kW + if (with2.Pg > kWBase) + with2.Pg = kWBase; // Generation limits + with2.s = 1 - ((with2.Poles * ShapeFactor.re * with2.Lamda) / (with2.w0 * with2.ag * with2.Rad)); + with2.Ps = with2.Pg / (1 - with2.s); + with2.Pr = with2.Ps * with2.s; + with2.Pnominalperphase = (1e3 * Factor * with2.Pg) / Fnphases; + // Now check for Q depending on QMode + switch (WindModelDyn->QMode) + { + case 1: // PF + { + kvarCalc = pow((with2.Pg / Abs(PFNominal)), 2) - pow(with2.Pg, 2); + kvarCalc = sqrt(kvarCalc); + kVATmp = sqrt(pow(with2.Pg, 2) + pow(kvarCalc, 2)); + if (kVATmp > with2.kVArating) // Check saturation + kvarCalc = kvarBase; + if (PFNominal < 0) + LeadLag = -1.0; + } + break; + case 2: // Volt-var ctrl + { + if (!(NodeRef.empty())) + { + // get the highest voltage done locally given with whatever is on memory + for (int stop = WindGenVars.NumPhases, i = 1; i <= stop; i++) + { + myV = with1->NodeV[NodeRef[i - 1]]; + VMagTmp = ctopolar(myV).mag; + if (VMagTmp > VMag) + VMag = VMagTmp; + } + VMag = VMag / VBase; // in pu + + // start by getting the losses from the provided curve (if any) + if ((VV_CurveObj != nullptr)) + VMagTmp = VV_CurveObj->GetYValue_(VMag); + else + VMagTmp = 0.0; // no losses given that the curve was not provided + } + else + VMagTmp = 0.0; + + // Calculates Q based on the + kvarCalc = kvarBase * VMagTmp; + if (Abs(kvarCalc) > kvarBase) + { + kvarCalc = kvarBase; + if (VMagTmp < 0) + LeadLag = -1.0; + } + } + break; + default: + kvarCalc = 0; + } + WindGenVars.Qnominalperphase = 1e3 * kvarCalc * LeadLag * Factor / Fnphases; + } + } + } + } + } + if (!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + // build the Y primitive eq + switch (GenModel) + { + case 6: + Yeq = cinv(cmplx(0, -WindGenVars.XD)); // Gets negated in CalcYPrim + break; + default: + auto with4 = WindGenVars; + Yeq = cdivreal(cmplx(with4.Pnominalperphase, -with4.Qnominalperphase), sqr(VBase)); // Vbase must be L-N for 3-phase + if (Vminpu != 0) + Yeq95 = cdivreal(Yeq, sqr(Vminpu)); // at 95% voltage + else + Yeq95 = Yeq; // Always a constant Z model + if (Vmaxpu != 0) + Yeq105 = cdivreal(Yeq, sqr(Vmaxpu)); // at 105% voltage + else + Yeq105 = Yeq; + break; + } + } + +} + +//---------------------------------------------------------------------------- + +void TWindGenObj::RecalcElementData(int ActorID) +{ + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + varBase = 1000.0 * kvarBase / Fnphases; + varMin = 1000.0 * kvarMin / Fnphases; + varMax = 1000.0 * kvarMax / Fnphases; + + /*Populate data structures used for interchange with user-written models.*/ + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + with0.XD = with0.puXd * 1000.0 * Sqr(with0.kVWindGenBase) / with0.kVArating; + with0.Xdp = with0.puXdp * 1000.0 * Sqr(with0.kVWindGenBase) / with0.kVArating; + with0.Xdpp = with0.puXdpp * 1000.0 * Sqr(with0.kVWindGenBase) / with0.kVArating; + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + + if (!kVANotSet) + { + kWBase = (with0.kVArating * Abs(PFNominal)); + kvarBase = sqrt(sqr(with0.kVArating) - sqr(kWBase)); + } + else + { + with0.kVArating = kWBase / Abs(PFNominal); + WindModelDyn->EditProp(13, to_string(with0.kVArating)); + } + } + SetNominalGeneration(ActorID); + + /*Now check for errors. If any of these came out nil and the string was not nil, give warning*/ + if(CompareText(YearlyShape,"none") == 0) + YearlyShape =""; + if(CompareText(DailyDispShape,"none") == 0) + DailyDispShape =""; + if(CompareText(DutyShape,"none") == 0) + DutyShape =""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg("WARNING! Yearly load shape: \"" + YearlyShape + "\" Not Found.", 563); + } + if(DailyDispShapeObj == nullptr) + { + if(DailyDispShape.size() > 0) + DoSimpleMsg("WARNING! Daily load shape: \"" + DailyDispShape + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg("WARNING! Duty load shape: \"" + DutyShape + "\" Not Found.", 565); + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg("ERROR! Spectrum \"" + Spectrum +"\" Not Found.", 566); + YQFixed = -varBase / Sqr(VBase); //10-17-02 Fixed negative sign + WindGenVars.VTarget = Vpu * 1000.0 * WindGenVars.kVWindGenBase; + if(Fnphases > 1) + WindGenVars.VTarget = WindGenVars.VTarget / SQRT3; + + // Initialize to Zero - defaults to PQ WindGen + // Solution object will reset after circuit modifications + DQDV = DQDVSaved; // for Model = 3 + DeltaQMax = (varMax - varMin) * 0.10; // Limit to 10% of range + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder); + + /*Update any user-written models*/ + if(UserModel->Get_Exists()) + UserModel->FUpdateModel(); + if(ShaftModel->Get_Exists()) + ShaftModel->FUpdateModel(); + + if (ASSIGNED(WindModelDyn)) + WindModelDyn->ReCalcElementData(); +} + +void TWindGenObj::CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID) +{ + complex Y = CZero, + Yij = CZero; + int i = 0, + j = 0; + double FreqMultiplier = 0.0; + double WTGZLV = 0.0; + + auto with0 = ActiveCircuit[ActorID]; + auto with1 = with0->Solution; + + FYprimFreq = with1->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + /*# with ActiveCircuit[ActorID].Solution do */ + + if (with1->IsDynamicModel || with1->IsHarmonicModel) + { + if (GenON) + { + /*# with WindModelDyn do */ + auto with2 = WindModelDyn; + { + WTGZLV = sqr(Get_PresentkV()) * 1e3 / WindGenVars.kVArating; + Y = cmplx(EPSILON, (-with2->N_WTG) / (with2->Xthev * WTGZLV)); // Yeq // L-N value computed in initial condition routines + } + } + else + Y = cmplx(EPSILON, 0.0); + if (Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = double(Y.im) / FreqMultiplier; + Yij = cnegate(Y); + for (int stop = Fnphases, i = 1; i <= stop; i++) + { + switch (Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(Fnconds, Fnconds, Y); + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + break; + case 1: + { /*Delta connection*/ + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(i, i, Y); // put it in again + for (int stop = i - 1, j = 1; j <= stop; j++) + Ymatrix->SetElemsym(i, j, Yij); + } + break; + default: + break; + } + } + + /**** Removed Neutral / Neutral may float + + IF Connection = 0 Then With Ymatrix Do // Take care of neutral issues + Begin + AddElement(Fnconds, Fnconds, YNeut); // Add in user specified Neutral Z, if any + // Bump up neutral-ground in case neutral ends up floating + SetElement(Fnconds, Fnconds, CmulReal(GetElement(Fnconds, Fnconds), 1.000001)); + End; + + */ + } + else + { // Regular power flow WindGen model + + /*Yeq is always expected as the equivalent line-neutral admittance*/ + Y = cnegate(Yeq); // negate for generation Yeq is L-N quantity + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = (Y.im) / FreqMultiplier; + auto with3 = Ymatrix; + switch (Connection) + { + case 0: + /*# with Ymatrix do */ + + { // WYE + Yij = cnegate(Y); + for (int stop = Fnphases, i = 1; i <= stop; i++) + { + with3->SetElement(i, i, Y); + with3->AddElement(Fnconds, Fnconds, Y); + with3->SetElemsym(i, Fnconds, Yij); + } + } + break; + case 1: + /*# with Ymatrix do */ + { // Delta or L-L + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for (int stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; // wrap around for closed connections + with3->AddElement(i, i, Y); + with3->AddElement(j, j, Y); + with3->AddElemsym(i, j, Yij); + } + } + break; + default: + break; + } + } /*ELSE IF Solution.mode*/ +} + + +//---------------------------------------------------------------------------- + +void TWindGenObj::CalcYPrim(int ActorID) +{ + int i = 0; + + // Build only shunt Yprim + // Build a dummy Yprim Series so that CalcV does not fail + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + if(ActiveCircuit[ActorID]->Solution->LoadModel == POWERFLOW) + + // 12-7-99 we'll start with Yeq in system matrix + { + SetNominalGeneration(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + else + + + // ADMITTANCE model wanted + { + SetNominalGeneration(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages doesn't fail + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors + inherited::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + /*Add the current into the proper location according to connection*/ + + /*Reverse of similar routine in load (Cnegates are switched)*/ + +void TWindGenObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum((TermArray)[i - 1], Curr); + caccum((TermArray)[Fnconds - 1], cnegate(Curr)); // Neutral + } + break; //DELTA + case 1: + { + caccum((TermArray)[i - 1], Curr); + j = i + 1; + if(j > Fnconds) + j = 1; + caccum((TermArray)[j - 1], cnegate(Curr)); + } + break; + default: + ; + break; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::WriteTraceRecord(const String s, int ActorID) +{ + int i = 0; + try + { + if(!InShowResults) + { + int stop = 0; + Append(Tracefile); + IOResultToException(); + { Write(Tracefile, Format("%-.g, %d, %-.g, ", + ActiveCircuit[ActorID]->Solution->DynaVars.T + ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600.0, + ActiveCircuit[ActorID]->Solution->Iteration, + ActiveCircuit[ActorID]->get_FLoadMultiplier())); + + Write(Tracefile, GetSolutionModeID()); + Write(Tracefile,", "); Write(Tracefile, + GetLoadModel()); Write(Tracefile,", "); + Write(Tracefile, GenModel, 0); + Write(Tracefile,", "); + Write(Tracefile, DQDV, 8, 0); + Write(Tracefile,", "); + Write(Tracefile, (V_Avg * 0.001732 / WindGenVars.kVWindGenBase), 8, 3); + Write(Tracefile,", "); + Write(Tracefile, (WindGenVars.VTarget - V_Avg), 9, 1); + Write(Tracefile,", "); + Write(Tracefile, (WindGenVars.Qnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile,", "); + Write(Tracefile, (WindGenVars.Pnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile,", "); + Write(Tracefile, s); + Write(Tracefile,", "); } + + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((InjCurrent)[i - 1])), 8, 1); Write(Tracefile,", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Iterminal)[i - 1])), 8, 1); Write(Tracefile,", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Vterminal)[i - 1])), 8, 1); Write(Tracefile,", "); } + } + { Write(Tracefile, WindGenVars.VthevMag, 8, 1); Write(Tracefile,", "); Write(Tracefile, WindGenVars.Theta * 180.0 / DSSGlobals::PI); } + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + catch (...) + { + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for Constant PQ*/ + +void TWindGenObj::DoConstantPQGen(int ActorID) +{ + int i = 0; + complex Curr = CZero; + complex V = CZero; + double Vmag = 0.0; +// V012,I012 :Array[0..2] of Complex; +// Iabc :Array[1..3] of Complex; + + //Treat this just like the Load model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + for (i = 0; i < Fnconds; i++) + InjCurrent[i] = CZero; + + ZeroITerminal(); + + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: /*Wye*/ + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(Yeq95, V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, V); + else + /*# with WindGenVars do */ + { + auto with0 = WindGenVars; + Curr = conjg(cdiv(cmplx(with0.Pnominalperphase, with0.Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; /*Delta*/ + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cdivreal(Yeq95, 3.0), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cdivreal(Yeq105, 3.0), V); + else + /*# with WindGenVars do */ + { + auto& with1 = WindGenVars; + Curr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; + default: + ; + break; + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } + /*END;*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::DoConstantZGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex YEQ2 = {}; + +// Assume Yeq is kept up to date + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + if(Connection == 0) + YEQ2 = Yeq; + else + YEQ2 = cdivreal(Yeq, 3.0); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmul(YEQ2, (Vterminal)[i - 1]); // Yeq is always line to neutral + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal current for Constant P,|V|*/ + +// Constant P, constant |V| + +void TWindGenObj::DoPVTypeGen(int ActorID) +{ + int i = 0; + double DQ = 0.0; + complex Curr = {}; + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the WindGen + ZeroITerminal(); + + // Guess at a new var output value + V_Avg = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V_Avg = V_Avg + cabs((Vterminal)[i - 1]); + } + if(Connection == 1) + V_Avg = V_Avg / (SQRT3 * Fnphases); + else + V_Avg = V_Avg / Fnphases; + + // 12-9-99 added empirical 0.7 factor to improve iteration + // 12-17-99 changed to 0.1 because first guess was consistently too high + DQ = PVFactor * DQDV * (WindGenVars.VTarget - V_Avg); // Vtarget is L-N + if(Abs((int) DQ) > DeltaQMax) + { + if(DQ < 0.0) + DQ = -DeltaQMax; + else + DQ = DeltaQMax; + } + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + with0.Qnominalperphase = with0.Qnominalperphase + DQ; + } + + /* Test Limits*/ + /*# with WindGenVars do */ + { + auto& with1 = WindGenVars; + int stop = 0; + if(with1.Qnominalperphase > varMax) + with1.Qnominalperphase = varMax; + else + { + if(with1.Qnominalperphase < varMin) + with1.Qnominalperphase = varMin; + + // Compute injection currents using W and var values + // Do not use comstant Z models outside normal range + // Presumably the var source will take care of the voltage problems + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), (Vterminal)[i - 1])); + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } + } /*With*/ +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for Fixed Q*/ +// Constant P, Fixed Q Q is always kvarBase + +void TWindGenObj::DoFixedQGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + Curr = conjg(cdiv(cmplx(WindGenVars.Pnominalperphase, varBase), V)); + } + } + break; + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re / 3.0, YQFixed / 3.0), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cmplx(Yeq105.re / 3.0, YQFixed / 3.0), V); + else + Curr = conjg(cdiv(cmplx(WindGenVars.Pnominalperphase, varBase), V)); + } + } + break; + default: + ; + break; + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for */ +// Constant P, Fixed Q Q is always a fixed Z derived from kvarBase + +void TWindGenObj::DoFixedQZGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + { + Curr = conjg(cdiv(cmplx(WindGenVars.Pnominalperphase, 0.0), V)); // P component of current + caccum(Curr, cmul(cmplx(0.0, YQFixed), V)); // add in Q component of current + } + } + } + break; + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re / 3.0, YQFixed / 3.0), V); + else + { + if(Vmag > VBase105) + Curr = cmul(cmplx(Yeq105.re / 3.0, YQFixed / 3.0), V); + else + { + Curr = conjg(cdiv(cmplx(WindGenVars.Pnominalperphase, 0.0), V)); // P component of current + caccum(Curr, cmul(cmplx(0.0, YQFixed / 3.0), V)); // add in Q component of current + } + } + } + break; + default: + ; + break; + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } /*FOR*/ +} +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal Current from User-written model*/ + +void TWindGenObj::DoUserModel(int ActorID) +{ + int i = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + if(UserModel->Get_Exists()) // Check automatically selects the usermodel if true + + //AppendToEventLog('Wnominal=', Format('%-.5g',[Pnominalperphase])); + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); + set_ITerminalUpdated(true, ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; // Negate currents from user model for power flow WindGen model + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + } + } + else + { + DoSimpleMsg(String("WindGen.") + get_Name() + +" model designated to use user-written model, but user-written model is not defined.", 567); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal current for Constant PQ, but limit to max current below + Vminpu*/ + +void TWindGenObj::DoCurrentLimitedPQ(int ActorID) +{ + int i = 0; + complex PhaseCurr = CZero; + complex DeltaCurr = CZero; + complex VLN = CZero; + complex VLL = CZero; + double VmagLN = 0.0; + double VmagLL = 0.0; + complex V012[4] = { CZero, CZero, CZero, CZero, }; // Sequence voltages + + //Treat this just like the Load model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + VLN = (Vterminal)[i - 1]; // VTerminal is LN for this connection + VmagLN = cabs(VLN); + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + PhaseCurr = conjg(cdiv(cmplx(with0.Pnominalperphase, with0.Qnominalperphase), VLN)); + } + if(cabs(PhaseCurr) > Model7MaxPhaseCurr) + PhaseCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLN, VmagLN))); + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(PhaseCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, PhaseCurr, i); // Put into Terminal array taking into account connection + } + break; + case 1: + { + VLL = (Vterminal)[i - 1]; // VTerminal is LL for this connection + VmagLL = cabs(VLL); + switch(Fnphases) + { + case 2: + case 3: // 2 or 3 phase WindGen model 7 + { + /*# with WindGenVars do */ + { + auto& with1 = WindGenVars; + DeltaCurr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), VLL)); + } + if(cabs(DeltaCurr) * SQRT3 > Model7MaxPhaseCurr) + DeltaCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLL / SQRT3))); + } + break; // 1-phase WindGen model 7 + default: + /*# with WindGenVars do */ + { + auto& with2 = WindGenVars; + DeltaCurr = conjg(cdiv(cmplx(with2.Pnominalperphase, with2.Qnominalperphase), VLL)); + } + if(cabs(DeltaCurr) > Model7MaxPhaseCurr) + DeltaCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLL))); + break; + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(DeltaCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, DeltaCurr, i); // Put into Terminal array taking into account connection + } + break; + default: + ; + break; + } + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Total Current and add into InjTemp*/ + +void TWindGenObj::DoDynamicMode(int ActorID) +{ + int i = 0; + complex V012[4] = { CZero, CZero, CZero, CZero, }; + complex I012[4] = { CZero, CZero, CZero, CZero, }; + int stop = 0; + //CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array and computes VTerminal L-N + ComputeVterminal(ActorID); + + for (i = 0; i < Get_NConds(); i++) + InjCurrent[i] = CZero; + + /*Inj = -Itotal (in) - Yprim*Vtemp*/ + switch(GenModel) + { + case 6: + if(UserModel->Get_Exists()) // auto selects model + /*We have total currents in Iterminal*/ + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); // returns terminal currents in Iterminal + } + else + { + DoSimpleMsg("Dynamics model missing for WindGen." + get_Name() + " ", 5671); + DSSGlobals::SolutionAbort = true; + } + break; + default: + WindModelDyn->CalcDynamic(&(Vterminal[0]), &(Iterminal[0])); + break; + } + set_ITerminalUpdated(true, ActorID); + + /*Add it into inj current array*/ + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + + /*Take Care of any shaft model calcs*/ + if((GenModel == 6) && ShaftModel->Get_Exists()) // auto selects model + // Compute Mech Power to shaft + { + ShaftModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); // Returns pshaft at least + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TWindGenObj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double GenHarmonic = 0.0; + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + GenHarmonic = with0->get_FFrequency() / GenFundamental; + e = cmulreal(SpectrumObj->GetMult(GenHarmonic), WindGenVars.VThevHarm); // Get base harmonic magnitude + RotatePhasorRad(e, GenHarmonic, WindGenVars.ThetaHarm); // Time shift by fundamental frequency phase shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, GenHarmonic, -120.0); // Assume 3-phase WindGen + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::CalcVTerminalPhase(int ActorID) +{ + int i = 0; + int j = 0; + +/* Establish phase voltages and stick in Vterminal*/ + switch(Connection) + { + case 0: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = with0->VDiff((NodeRef)[i - 1], (NodeRef)[Fnconds - 1], ActorID); + } + } + } + break; + case 1: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if(j > Fnconds) + j = 1; + (Vterminal)[i - 1] = with1->VDiff((NodeRef)[i - 1], (NodeRef)[j - 1], ActorID); + } + } + } + break; + default: + ; + break; + } + WindGenSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Put terminal voltages in an array*/ + +void TWindGenObj::CalcVterminal(int ActorID) +{ + ComputeVterminal(ActorID); + WindGenSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Calculates WindGen current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TWindGenObj::CalcGenModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + + // compute currents and put into InjTemp array; + { + switch(GenModel) + { + case 1: + DoConstantPQGen(ActorID); + break; + case 2: + DoConstantZGen(ActorID); + break; + case 3: + DoPVTypeGen(ActorID); + break; // Constant P, |V| + case 4: + DoFixedQGen(ActorID); + break; + case 5: + DoFixedQZGen(ActorID); + break; + case 6: + DoUserModel(ActorID); + break; + case 7: + DoCurrentLimitedPQ(ActorID); + break; + default: + DoConstantPQGen(ActorID); // for now, until we implement the other models. + break; + } + } /*ELSE*/ + } + } /*WITH*/ + + /*When this is done, ITerminal is up to date*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + + +// Difference between currents in YPrim and total current + +void TWindGenObj::CalcInjCurrentArray(int ActorID) +{ + + + +// Now Get Injection Currents + if(GenSwitchOpen) + ZeroInjCurrent(); + else + CalcGenModelContribution(ActorID); + +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Compute total Currents + +void TWindGenObj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + { + if(!GenSwitchOpen) + CalcGenModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); + } + if(DebugTrace) + WriteTraceRecord("TotalCurrent", ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +int TWindGenObj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->LoadsNeedUpdating) + SetNominalGeneration(ActorID); // Set the nominal kW, etc for the type of solution being done + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + if(DebugTrace) + WriteTraceRecord("Injection", ActorID); + + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Gives the currents for the last solution performed + +// Do not call SetNominalLoad, as that may change the load values + +void TWindGenObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("WindGen Object: \"") + get_Name() +"\" in GetInjCurrents function.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TWindGenObj::ResetRegisters() +{ + int i = 0; + int stop = 0; + for(stop = NumWGenRegisters, i = 1; i <= stop; i++) + { + Registers[i - 1] = 0.0; + } + for(stop = NumWGenRegisters, i = 1; i <= stop; i++) + { + Derivatives[i - 1] = 0.0; + } + FirstSampleAfterReset = true; // initialize for trapezoidal integration +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TWindGenObj::Integrate(int reg, double Deriv, double Interval, int ActorID) +{ + if(ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + Registers[reg] = Registers[reg] + 0.5 * Interval * (Deriv + Derivatives[reg]); + } + else + /*Plain Euler integration*/ + Registers[reg] = Registers[reg] + Interval * Deriv; + Derivatives[reg] = Deriv; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Update Energy from metered zone + +void TWindGenObj::TakeSample(int ActorID) +{ + complex s = {}; + double Smag = 0.0; + double HourValue = 0.0; + +// Compute energy in WindGen branch + if(Get_Enabled()) + { + if(GenON) + { + s = cmplx(Get_PresentkW(), Get_Presentkvar()); + Smag = cabs(s); + HourValue = 1.0; + } + else + { + s = CZero; + Smag = 0.0; + HourValue = 0.0; + } + if(GenON || ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + /*Make sure we always integrate for Trapezoidal case + Don't need to for Gen Off and normal integration*/ + if(ActiveCircuit[ActorID]->PositiveSequence) + { + s = cmulreal(s, 3.0); + Smag = 3.0 * Smag; + } + Integrate(Reg_kWh, s.re, with0->IntervalHrs, ActorID); // Accumulate the power + Integrate(Reg_kvarh, s.im, with0->IntervalHrs, ActorID); + SetDragHandRegister(Reg_MaxkW, Abs((int) s.re)); + SetDragHandRegister(Reg_MaxkVA, Smag); + Integrate(Reg_Hours, HourValue, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + Integrate(Reg_Price, s.re * ActiveCircuit[ActorID]->PriceSignal * 0.001, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + FirstSampleAfterReset = false; + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +double TWindGenObj::Get_PresentkW() +{ + double result = 0.0; + result = WindGenVars.Pnominalperphase * 0.001 * Fnphases; + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +double TWindGenObj::Get_PresentkV() +{ + double result = 0.0; + result = WindGenVars.kVWindGenBase; + return result; +} + +double TWindGenObj::Get_Presentkvar() +{ + double result = 0.0; + result = WindGenVars.Qnominalperphase * 0.001 * Fnphases; + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::InitDQDVCalc() +{ + DQDV = 0.0; + WindGenVars.Qnominalperphase = 0.5 * (varMax + varMin); // avg of the limits +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Bump up vars by 10% of range for next calc*/ + +void TWindGenObj::BumpUpQ() +{ + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + with0.Qnominalperphase = with0.Qnominalperphase + 0.1 * (varMax - varMin); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::RememberQV(int ActorID) +{ + int i = 0; + int stop = 0; + var_Remembered = WindGenVars.Qnominalperphase; + CalcVterminal(ActorID); + V_Avg = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V_Avg = V_Avg + cabs((Vterminal)[i - 1]); + } + V_Avg = V_Avg / Fnphases; + V_Remembered = V_Avg; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::CalcDQDV(int ActorID) +{ + double VDiff = 0.0; + int i = 0; + int stop = 0; + CalcVterminal(ActorID); + V_Avg = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V_Avg = V_Avg + cabs((Vterminal)[i - 1]); + } + V_Avg = V_Avg / Fnphases; + VDiff = V_Avg - V_Remembered; + if(VDiff != 0.0) + DQDV = (WindGenVars.Qnominalperphase - var_Remembered) / VDiff; + else + DQDV = 0.0; // Something strange has occured + // this will force a de facto P,Q model + DQDVSaved = DQDV; //Save for next time Allows WindGen to be enabled/disabled during simulation +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::ResetStartPoint() +{ + WindGenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TWindGenObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + { Write(f,"!DQDV="); WriteLn(f, DQDV, 10, 2); } + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; + switch(Idx) + { + case 34: case 36: + { Write(f,"~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f,"=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + case 44: // This one has no variable associated, not needed + { Write(f,"~ "); Write(f, (with0->PropertyName)[i - 1]); WriteLn(f,"=False"); } + break; + default: + { Write(f,"~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + +void TWindGenObj::InitHarmonics(int ActorID) +{ + complex e = {}; + complex Va = {}; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + GenFundamental = ActiveCircuit[ActorID]->Solution->get_FFrequency(); // Whatever the frequency is when we enter here. + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + Yeq = cinv(cmplx(0.0, with0.Xdpp)); // used for current calcs Always L-N + + /*Compute reference Thevinen voltage from phase 1 current*/ + if(GenON) + { + ComputeIterminal(ActorID); // Get present value of current + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + switch(Connection) + { + case 0: /*wye - neutral is explicit*/ + { + if(!ADiakoptics || (ActorID == 1)) + Va = csub(with1->NodeV[(NodeRef)[1 - 1]], with1->NodeV[(NodeRef)[Fnconds - 1]]); + else + Va = csub(with1->VoltInActor1((NodeRef)[1 - 1]), with1->VoltInActor1((NodeRef)[Fnconds - 1])); + } + break; /*delta -- assume neutral is at zero*/ + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + Va = with1->NodeV[(NodeRef)[1 - 1]]; + else + Va = with1->VoltInActor1((NodeRef)[1 - 1]); + } + break; + default: + ; + break; + } + } + e = csub(Va, cmul((Iterminal)[1 - 1], cmplx(0.0, with0.Xdpp))); + with0.VThevHarm = cabs(e); // establish base mag and angle + with0.ThetaHarm = cang(e); + } + else + { + with0.VThevHarm = 0.0; + with0.ThetaHarm = 0.0; + } + } +} + +void TWindGenObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(3,"12.47"); //kV + Set_PropertyValue(4,"100"); //kW + Set_PropertyValue(5,".80"); //PF + Set_PropertyValue(6,"1"); //model + Set_PropertyValue(7,""); //yearly + Set_PropertyValue(8,""); //daily + Set_PropertyValue(9,""); //duty + Set_PropertyValue(10,"wye"); //conn + Set_PropertyValue(11,"60.0"); //kvar + Set_PropertyValue(12,"100"); //class + Set_PropertyValue(13,"no"); //debugtrace + Set_PropertyValue(14,"0.90"); //VMinPu + Set_PropertyValue(15,"1.1"); //VMaxPu; + Set_PropertyValue(16, Format("%-g", WindGenVars.kVArating)); //kVA + Set_PropertyValue(17, Format("%-g", WindGenVars.kVArating * 1e-3)); //MVA + Set_PropertyValue(18, ""); //UserModel + Set_PropertyValue(19, ""); //UserData + Set_PropertyValue(20, "0.0"); //DutyStart + Set_PropertyValue(21,""); //DynamicEq + Set_PropertyValue(22,""); //DynOut + Set_PropertyValue(23, Format("%-g", WindModelDyn->Rthev)); //RThev + Set_PropertyValue(24, Format("%-g", WindModelDyn->Xthev)); //XThev + Set_PropertyValue(25, Format("%-g", WindModelDyn->Vss)); //Vss + Set_PropertyValue(26, Format("%-g", WindModelDyn->Pss)); //Pss + Set_PropertyValue(27, Format("%-g", WindModelDyn->Qss)); //Qss + Set_PropertyValue(28, Format("%-g", WindModelDyn->vwind)); //VWind + Set_PropertyValue(29, Format("%-g", WindModelDyn->QMode)); //QMode + Set_PropertyValue(30, Format("%-g", WindModelDyn->SimMechFlg)); //SimMechFlg + Set_PropertyValue(31, Format("%-g", WindModelDyn->APCFLG)); //APCFlg + Set_PropertyValue(32, Format("%-g", WindModelDyn->QFlg)); //QFlg + Set_PropertyValue(33, Format("%-g", WindModelDyn->delt0)); //delt0 + Set_PropertyValue(34, Format("%-g", WindModelDyn->N_WTG)); //N_WTG + Set_PropertyValue(35,""); //VV_Curve + Set_PropertyValue(36, Format("%-g", WindGenVars.ag)); //Ag + Set_PropertyValue(37, Format("%-g", WindGenVars.Cp)); //Cp + Set_PropertyValue(38, Format("%-g", WindGenVars.Lamda)); //Lamda + Set_PropertyValue(39, Format("%-g", WindGenVars.Poles)); //Poles + Set_PropertyValue(40, Format("%-g", WindGenVars.pd)); //pd + Set_PropertyValue(41, WindGenVars.PLoss); //PLoss + Set_PropertyValue(42, Format("%-g", WindGenVars.Rad)); //Rad + Set_PropertyValue(43, Format("%-g", WindGenVars.VCutin)); //VCutIn + Set_PropertyValue(44, Format("%-g", WindGenVars.VCutout)); //VCutOut + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TWindGenObj::InitStateVars(int ActorID) +{ + + /*VNeut,*/ + int i = 0; + complex V012[4] = { CZero, CZero, CZero, CZero, }, + I012[4] = { CZero, CZero, CZero, CZero, }, + Vabc[4] = { CZero, CZero, CZero, CZero, }; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + switch(GenModel) + { + case 7: + with0.Zthev = cmplx(with0.Xdp, 0.0); + break; // use Xd' as an equivalent R for the inverter + default: + with0.Zthev = cmplx(with0.Xdp / with0.XRdp, with0.Xdp); + break; + } + Yeq = cinv(with0.Zthev); + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if(GenON) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + ComputeIterminal(ActorID); + switch(Fnphases) + { + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + Edp = csub(csub(with1->NodeV[(NodeRef)[1 - 1]], with1->NodeV[(NodeRef)[2 - 1]]), cmul((Iterminal)[1 - 1], with0.Zthev)); + else + Edp = csub(csub(with1->VoltInActor1((NodeRef)[1 - 1]), with1->VoltInActor1((NodeRef)[2 - 1])), cmul((Iterminal)[1 - 1], with0.Zthev)); + with0.VthevMag = cabs(Edp); + } + break; + // Calculate Edp based on Pos Seq only + case 3: + { + int stop = 0; + Phase2SymComp(&(Iterminal[0]), &I012[0]); + // Voltage behind Xdp (transient reactance), volts + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vabc[i] = with1->NodeV[(NodeRef)[i - 1]]; + else + Vabc[i] = with1->VoltInActor1((NodeRef)[i - 1]); + } // Wye Voltage + Phase2SymComp(&Vabc[1], &V012[0]); + Edp = csub(V012[1], cmul(I012[1], with0.Zthev)); // Pos sequence + with0.VthevMag = cabs(Edp); + } + break; + default: + DoSimpleMsg(Format(("Dynamics mode is implemented only for 1- or 3-phase WindGens. WindGen." + with1->get_Name() + +" has %d phases.").c_str(), Fnphases), 5672); + SolutionAbort = true; + break; + } + + if (!ASSIGNED(DynamicEqObj)) + { + // Shaft variables + // Theta is angle on Vthev[1] relative to system reference + // Theta := Cang(Vthev^[1]); // Assume source at 0 + with0.Theta = cang(Edp); + if (GenModel == 7) + Model7LastAngle = with0.Theta; + + with0.dTheta = 0.0; + with0.w0 = TwoPi * ActiveCircuit[ActorID]->Solution->get_FFrequency(); + // recalc Mmass and D in case the frequency has changed + with0.Mmass = 2.0 * with0.Hmass * with0.kVArating * 1000.0 / (with0.w0); // M = W-sec + with0.D = with0.Dpu * with0.kVArating * 1000.0 / (with0.w0); + + with0.Pshaft = -Get_Power(1, ActorID).re; // Initialize Pshaft to present power Output + + with0.Speed = 0.0; // relative to synch speed + with0.dSpeed = 0.0; + + // Init User-written models + // Ncond:Integer; V, I:pComplexArray; const X,Pshaft,Theta,Speed,dt,time:Double + + auto with4 = ActiveCircuit[ActorID]->Solution; + + if (GenModel == 6) + { + if (UserModel->Get_Exists()) + UserModel->FInit(&(Vterminal[0]), &(Iterminal[0])); + if (ShaftModel->Get_Exists()) + ShaftModel->FInit(&(Vterminal[0]), &(Iterminal[0])); + } + else + WindModelDyn->Init(&(Vterminal[0]), &(Iterminal[0])); + } + else + { + // Initializes the memory values for the dynamic equation + for( i = 0; i < DynamicEqVals.size(); i++) + DynamicEqVals[i][1] = 0.0; + // Check for initial conditions using calculated values (P0, Q0) + int NumData = (DynamicEqPair.size() / 2) - 1; + + for (i = 0; i <= NumData; i++) + { + if (DynamicEqObj->IsInitVal(DynamicEqPair[(i * 2) + 1])) + { + switch (DynamicEqPair[(i * 2) + 1]) + { + case 9: + { + DynamicEqVals[DynamicEqPair[i * 2]][0] = cang(Edp); + + if (GenModel == 7) + Model7LastAngle = DynamicEqVals[DynamicEqPair[i * 2]][0]; + } + break; + default: + DynamicEqVals[DynamicEqPair[i * 2]][0] = Get_PCEValue(1, DynamicEqPair[(i * 2) + 1], ActorID); + } + } + } + } + } + else + { + Vthev = CZero; + with0.Theta = 0.0; + with0.dTheta = 0.0; + with0.w0 = 0; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + } + } /*With*/ +} + +void TWindGenObj::IntegrateStates(int ActorID) +{ + complex TracePower = CZero; + // Compute Derivatives and then integrate + ComputeIterminal(ActorID); + +// Check for user-written exciter model. + //Function(V, I:pComplexArray; const Pshaft,Theta,Speed,dt,time:Double) + /*# with ActiveCircuit[ActorID].Solution, WindGenVars do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = WindGenVars; + + if (!ASSIGNED(DynamicEqObj)) + { + /*# with DynaVars do */ + { + auto& with2 = with0->DynaVars; + if (with2.IterationFlag == 0) /*Get_First() iteration of new time step*/ + { + with1.ThetaHistory = with1.Theta + 0.5 * with2.h * with1.dTheta; + with1.SpeedHistory = with1.Speed + 0.5 * with2.h * with1.dSpeed; + } + } + // Compute shaft dynamics + TracePower = TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases); + with1.dSpeed = (with1.Pshaft + TracePower.re - with1.D * with1.Speed) / with1.Mmass; + // dSpeed := (Torque + TerminalPowerIn(Vtemp,Itemp,FnPhases).re/Speed) / (Mmass); + with1.dTheta = with1.Speed; + // Trapezoidal method + /*# with DynaVars do */ + { + auto& with3 = with0->DynaVars; + with1.Speed = with1.SpeedHistory + 0.5 * with3.h * with1.dSpeed; + with1.Theta = with1.ThetaHistory + 0.5 * with3.h * with1.dTheta; + } + + // Write Dynamics Trace Record + if (DebugTrace) + { + Append(Tracefile); + IOResultToException(); + Write(Tracefile, Format("t=%-.5g ", with0->DynaVars.T)); + Write(Tracefile, Format(" Flag=%d ", with0->DynaVars.IterationFlag)); + Write(Tracefile, Format(" Speed=%-.5g ", with1.Speed)); + Write(Tracefile, Format(" dSpeed=%-.5g ", with1.dSpeed)); + Write(Tracefile, Format(" Pshaft=%-.5g ", with1.Pshaft)); + Write(Tracefile, Format(" P=%-.5g Q= %-.5g", TracePower.re, TracePower.im)); + Write(Tracefile, Format(" M=%-.5g ", with1.Mmass)); + WriteLn(Tracefile); + CloseFile(Tracefile); + } + + if (GenModel == 6) + { + if (UserModel->Get_Exists()) + UserModel->Integrate(); + if (ShaftModel->Get_Exists()) + ShaftModel->Integrate(); + } + else + { + WindModelDyn->Integrate(); + } + } + else + { + // Dynamics using an external equation + auto With5 = with0->DynaVars; + + if (With5.IterationFlag == 0) + { + //{ First iteration of new time step } + with1.SpeedHistory = DynamicEqVals[DynOut[0]][0] + 0.5 * h * DynamicEqVals[DynOut[0]][1]; // first speed + with1.ThetaHistory = DynamicEqVals[DynOut[1]][0] + 0.5 * h * DynamicEqVals[DynOut[1]][1]; // then angle + } + // Check for initial conditions using calculated values (P, Q, VMag, VAng, IMag, IAng) + int NumData = round(DynamicEqPair.size() / 2) - 1; + for (int i = 0; i <= NumData; i++) + { + if (!DynamicEqObj->IsInitVal(DynamicEqPair[(i * 2) + 1])) + { // it's not intialization + switch( DynamicEqPair[(i * 2) + 1]) + { + case 0: + DynamicEqVals[DynamicEqPair[i * 2]][0] = -TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases).re; + break; + case 1: + DynamicEqVals[DynamicEqPair[i * 2]][0] = -TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases).im; + break; + default: + DynamicEqVals[DynamicEqPair[i * 2]][0] = Get_PCEValue(1, DynamicEqPair[(i * 2) + 1], ActorID); + break; + } + } + } + + // solves the differential equation using the given values + DynamicEqObj->SolveEq(&DynamicEqVals); + // Trapezoidal method - Places the calues in the same vars to keep the code consistent + with1.Speed = with1.SpeedHistory + 0.5 * h * DynamicEqVals[DynOut[0]][1]; + with1.Theta = with1.ThetaHistory + 0.5 * h * DynamicEqVals[DynOut[1]][1]; + + // saves the new integration values in memoryspace + DynamicEqVals[DynOut[0]][0] = with1.Speed; + DynamicEqVals[DynOut[1]][0] = with1.Theta; + } + } +} +/*Return variables one at a time*/ + +double TWindGenObj::Get_Variable(int i) +{ + double result = -9999.99; // error return value + int N = 0, + k = 0; + + if (i < 1) + return result; // Someone goofed + if (i < 19) + result = WindModelDyn->Get_Variable(i); + else + { + switch (i) + { + case 19: + result = WindGenVars.Pg; + break; + case 20: + result = WindGenVars.Ps; + break; + case 21: + result = WindGenVars.Pr; + break; + case 22: + result = WindGenVars.s; + break; + default: + result = -9999.99; + } + } + if (UserModel->Get_Exists()) + { + N = UserModel->FNumVars(); + k = (i - NumWGenVariables); + if (k <= N) + { + result = UserModel->FGetVariable(k); + return result; + } + } + + /*If we get here, must be in the Shaft Model if anywhere*/ + if (ShaftModel->Get_Exists()) + { + k = i - (NumWGenVariables + N); + if (k > 0) + result = ShaftModel->FGetVariable(k); + } + return result; + +} + +void TWindGenObj::Set_Variable(int i, double Value) +{ + int n = 0; + int k = 0; + n = 0; + if(i < 1) + return; // Someone goofed + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + switch(i) + { + case 1: + with0.Speed = (Value - with0.w0) * TwoPi; + break; + case 2: + with0.Theta = Value / RadiansToDegrees; + break; // deg to rad + case 3: + ; + break;// meaningless to set Vd := Value * vbase; // pu to volts + case 4: + with0.Pshaft = Value; + break; + case 5: + with0.dSpeed = Value / RadiansToDegrees; + break; + case 6: + with0.dTheta = Value; + break; + default: + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + k = (i - NumWGenVariables); + if(k <= n) + { + UserModel->FSetVariable(k, Value); + return; + } + } + // If we get here, must be in the shaft model + if(ShaftModel->Get_Exists()) + { + k = (i - (NumWGenVariables + n)); + if(k > 0) + ShaftModel->FSetVariable(k, Value); + } + break; + } + } +} + +void TWindGenObj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int n = 0; + int stop = 0; + + if (!ASSIGNED(DynamicEqObj)) + { + for (stop = NumWGenVariables, i = 1; i <= stop; i++) + { + (States)[i - 1] = Get_Variable(i); + } + } + else + { + for (stop = DynamicEqObj->get_FNumVars(), i = 1; i <= stop; i++) + { + (States)[i - 1] = DynamicEqObj->Get_DynamicEqVal(i - 1, &DynamicEqVals); + } + } + + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + UserModel->FGetAllVars((pDoubleArray)&(States)[NumWGenVariables + 1 - 1]); + } + if(ShaftModel->Get_Exists()) + { + ShaftModel->FGetAllVars((pDoubleArray)&(States)[NumWGenVariables + 1 + n - 1]); + } +} + +int TWindGenObj::NumVariables() +{ + int result = 0; + result = NumWGenVariables; + if(UserModel->Get_Exists()) + result = result + UserModel->FNumVars(); + if(ShaftModel->Get_Exists()) + result = result + ShaftModel->FNumVars(); + return result; +} + +//--------------------------------------------------------------------------- + +bool TWindGenObj::get_FForcedON() +{ + return FForcedON; +} + +//--------------------------------------------------------------------------- + +void TWindGenObj::set_FForcedON(bool myState) +{ + FForcedON = myState; +} + +//--------------------------------------------------------------------------- + +double TWindGenObj::get_PFNominal() +{ + return PFNominal; +} + +//--------------------------------------------------------------------------- + +String TWindGenObj::VariableName(int i) +{ + String result; + const int BuffSize = 255; + int n = 0; + int I2 = 0; + AnsiChar Buff[256/*# range 0..BuffSize*/]; + PAnsiChar PName = nullptr; + n = 0; + if(i < 1) + return result; // Someone goofed + switch(i) + { + case 1: + result ="userTrip"; + break; + case 2: + result ="wtgTrip"; + break; + case 3: + result ="Pcurtail"; + break; + case 4: + result ="Pcmd"; + break; + case 5: + result ="Pgen"; + break; + case 6: + result ="Qcmd"; + break; + case 7: + result = "Qgen"; + break; + case 8: + result = "Vref"; + break; + case 9: + result = "Vmag"; + break; + case 10: + result = "vwind"; + break; + case 11: + result = "WtRef"; + break; + case 12: + result = "WtAct"; + break; + case 13: + result = "dOmg"; + break; + case 14: + result = "dFrqPuTest"; + break; + case 15: + result = "QMode"; + break; + case 16: + result = "Qref"; + break; + case 17: + result = "PFref"; + break; + case 18: + result = "thetaPitch"; + break; + case 19: + result = "Pg"; + break; + case 20: + result = "Ps"; + break; + case 21: + result = "Pr"; + break; + case 22: + result = "s"; + break; + default: + if(UserModel->Get_Exists()) // Checks for existence and Selects + { + PName = (PAnsiChar) &Buff; + n = UserModel->FNumVars(); + I2 = i - NumWGenVariables; + if(I2 <= n) + // DLL functions require AnsiString (AnsiString) type + { + UserModel->FGetVarName(I2, PName, (unsigned int) BuffSize); + result = PName; + return result; + } + } + if(ShaftModel->Get_Exists()) + { + PName = (PAnsiChar) &Buff; + I2 = i - NumWGenVariables - n; + if(I2 > 0) + UserModel->FGetVarName(I2, PName, (unsigned int) BuffSize); + result = PName; + } + break; + } + return result; +} + +String TWindGenObj::GetPropertyValue(int Index) +{ + String Result; + Result =""; + switch(Index) + { + case 3: Result = Format("%.6g", Get_PresentkV()); + break; + case 4 : Result = Format("%.6g", kWBase); + break; + case 5 : Result = Format("%.6g", PFNominal); + break; + case 7 : Result = YearlyShape; + break; + case 8 : Result = DailyDispShape; + break; + case 9 : Result = DutyShape; + break; + case 10: + if (Connection == 0) + Result = "wye"; + else + Result = "delta"; + break; + case 11 : Result = Format("%.6g", Get_Presentkvar()); + break; + case 12 : Result = Format("%.d", GenClass); + break; + case 13: + if (DebugTrace) + Result = "Yes"; + else + Result = "No"; + break; + case 14 : Result = Format("%.6g", Vminpu); + break; + case 15 : Result = Format("%.6g", Vmaxpu); + break; + case 16 : Result = Format("%.6g", WindGenVars.kVArating); + break; + case 17 : Result = Format("%.6g", (WindGenVars.kVArating / 1e3)); + break; + case 18: + Result = UserModel->get_FName(); + break; + case 20 : Result = Format("%.6g", DutyStart); + break; + case 21 : Result = DynamicEq; + break; + case 22 : Result = GetDynOutputStr(); + break; + case 23 : Result = Format("%.6g", WindModelDyn->Rthev); + break; + case 24 : Result = Format("%.6g", WindModelDyn->Xthev); + break; + case 25 : Result = Format("%.6g", WindModelDyn->Vss); + break; + case 26 : Result = Format("%.6g", WindModelDyn->Pss); + break; + case 27 : Result = Format("%.6g", WindModelDyn->Qss); + break; + case 28 : Result = Format("%.6g", WindModelDyn->vwind); + break; + case 29 : Result = Format("%.d", WindModelDyn->QMode); + break; + case 30 : Result = Format("%.d", WindModelDyn->SimMechFlg); + break; + case 31 : Result = Format("%.d", WindModelDyn->APCFLG); + break; + case 32: Result = Format("%.d", WindModelDyn->QFlg); + break; + case 33: Result = Format("%.6g", WindModelDyn->delt0); + break; + case 34: Result = Format("%.d", WindModelDyn->N_WTG); + break; + case 35 : Result = VV_Curve; + break; + case 36 : Result = Format("%.6g", WindGenVars.ag); + break; + case 37 : Result = Format("%.6g", WindGenVars.Cp); + break; + case 38 : Result = Format("%.6g", WindGenVars.Lamda); + break; + case 39 : Result = Format("%.6g", WindGenVars.Poles); + break; + case 40 : Result = Format("%.6g", WindGenVars.pd); + break; + case 41 : Result = WindGenVars.PLoss; + break; + case 42 : Result = Format("%.6g", WindGenVars.Rad); + break; + case 43 : Result = Format("%.6g", WindGenVars.VCutin); + break; + case 44 : Result = Format("%.6g", WindGenVars.VCutout); + break; + default: + Result = inherited::GetPropertyValue(Index); + break; + } + return Result; +} + +void TWindGenObj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + s ="Phases=1 conn=wye"; + + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = WindGenVars.kVWindGenBase / SQRT3; + else + V = WindGenVars.kVWindGenBase; + s = s + Format(" kV=%-.5g", V); + + // Divide the load by no. phases + if(Fnphases > 1) + { + s = s + Format(" kW=%-.5g PF=%-.5g", kWBase / Fnphases, PFNominal); + if((PrpSequence[19 - 1] != 0) || (PrpSequence[20 - 1] != 0 )) + s = s + + Format(" maxkvar=%-.5g minkvar=%-.5g", kvarMax / Fnphases, kvarMin / Fnphases); + if((PrpSequence)[26 - 1] > 0) + s = s + Format(" kva=%-.5g ", WindGenVars.kVArating / Fnphases); + if((PrpSequence)[27 - 1] > 0) + s = s + Format(" MVA=%-.5g ", WindGenVars.kVArating / 1000.0 / Fnphases); + } + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + +void TWindGenObj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + inherited::Set_ConductorClosed(Index, ActorID, Value); + + // Just turn WindGen on or off; + if(Value) + GenSwitchOpen = false; + else + GenSwitchOpen = true; +} + +void TWindGenObj::Set_PowerFactor(double Value) +{ + PFNominal = Value; + SyncUpPowerQuantities(); +} + +void TWindGenObj::Set_PresentkV(double Value) +{ + /*# with WindGenVars do */ + { + auto& with0 = WindGenVars; + with0.kVWindGenBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = with0.kVWindGenBase * InvSQRT3x1000; + break; + default: + VBase = with0.kVWindGenBase * 1000.0; + break; + } + } +} + +void TWindGenObj::Set_Presentkvar(double Value) +{ + double kVA_Gen = 0.0; + kvarBase = Value; + WindGenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; // init to something reasonable + kVA_Gen = sqrt(Sqr(kWBase) + Sqr(kvarBase)); + if(kVA_Gen != 0.0) + PFNominal = kWBase / kVA_Gen; + else + PFNominal = 1.0; + if((kWBase * kvarBase) < 0.0) + PFNominal = -PFNominal; + kvarMax = 2.0 * kvarBase; + kvarMin = -kvarMax; +} + +void TWindGenObj::Set_PresentkW(double Value) +{ + kWBase = Value; + SyncUpPowerQuantities(); +} + +void TWindGenObj::SyncUpPowerQuantities() +{ + + + // keep kvar nominal up to date with kW and PF + if(PFNominal != 0.0) + { + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + WindGenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; + kvarMax = 2.0 * kvarBase; + kvarMin = -kvarMax; + if(PFNominal < 0.0) + kvarBase = -kvarBase; + if(kVANotSet) + WindGenVars.kVArating = kWBase * 1.2; + } +} + +void TWindGenObj::SetDragHandRegister(int reg, double Value) +{ + if(Value > Registers[reg]) + Registers[reg] = Value; +} + +void TWindGenObj::SetkWkvar(double PkW, double Qkvar) +{ + kWBase = PkW; + Set_Presentkvar(Qkvar); +} + +void TWindGenObj::CalcVthev_Dyn() +{ + if(GenSwitchOpen) + WindGenVars.VthevMag = 0.0; + Vthev = pclx(WindGenVars.VthevMag, WindGenVars.Theta); +} +/*Adjust VThev to be in phase with V, if possible*/ +/* + If the voltage magnitude drops below 15% or so, the accuracy of determining the + phase angle gets flaky. This algorithm approximates the action of a PLL that will + hold the last phase angle until the voltage recovers. +*/ + +void TWindGenObj::CalcVthev_Dyn_Mod7(const complex& V) +{ + double Model7angle = 0.0; + if(GenSwitchOpen) + WindGenVars.VthevMag = 0.0; + /* + For Phases=1, Vbase is voltage across the terminals. + Else it is LN voltage. + */ + if(cabs(V) > 0.2 * VBase) + Model7angle = cang(V); + else + Model7angle = Model7LastAngle; + Vthev = pclx(WindGenVars.VthevMag, Model7angle); + Model7LastAngle = Model7angle; +} + + +void WindGen_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +// TWOPI3 := twopi/3.0; +} + + class WindGen_unit + { + public: + WindGen_unit() + { + //AssertSystemInitialization(); + WindGen_initialization(); + } + }; + WindGen_unit _WindGen_unit; + +} // namespace WindGen + + + + diff --git a/OpenDSSC/PCElements/WindGen.h b/OpenDSSC/PCElements/WindGen.h new file mode 100644 index 0000000..ff1041b --- /dev/null +++ b/OpenDSSC/PCElements/WindGen.h @@ -0,0 +1,292 @@ +#ifndef WindGenH +#define WindGenH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "WindGenVars.h" +#include "WindGenUserModel.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "Dynamics.h" +#include "ParserDel.h" +#include "Command.h" +#include +#include "mathutil.h" +#include "DSSClassDefs.h" +#include "WTG3_Model.h" +#include "XYcurve.h" + + + + +namespace WindGen +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2024, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + + 2/26/21 Created from Generator.pas + 3/25/21 Removed Generator-related properties (e.g., Fuel variables) + +*/ +/* + In power flow modes, the WindGen element is essentially a negative load that can be dispatched. +*/ + +// The WindGen is assumed balanced over the no. of phases defined + +// If you do not specify load shapes defaults are: +// Yearly: Defaults to No variation (i.e. multiplier = 1.0 always) +// Daily: Defaults to No variation +// Dutycycle: Defaults to Daily shape + +const int NumWGenRegisters = 6; // Number of energy meter registers +const int NumWGenVariables = 22; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TWindGen : public PCClass::TPCClass +{ + friend class TWindGenObj; +public: + typedef PCClass::TPCClass inherited; +private: + void InterpretConnection(const String s); + void SetNcondsForConnection(); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherWindGenName); +public: + String RegisterNames[6/*# range 1..NumGenRegisters*/]; + TWindGen(); + virtual ~TWindGen(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void ResetRegistersAll(int ActorID); + void SampleAll(int ActorID); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TWindGenObj : public PCElement::TPCElement +{ + friend class TWindGen; +public: + typedef PCElement::TPCElement inherited; +//private: +// Moved to WindGenVars Zthev :Complex; + Ucomplex::complex Yeq; // at nominal + Ucomplex::complex Yeq95; // at 95% + Ucomplex::complex Yeq105; // at 105% + Ucomplex::complex Edp; + Ucomplex::complex PhaseCurrentLimit; + double Model7MaxPhaseCurr; + double Model7LastAngle; + bool DebugTrace; + double DeltaQMax; // Max allowable var change on Model=3 per iteration + double DQDV; + double DQDVSaved; + bool FForcedON; + bool FirstSampleAfterReset; + bool IsFixed; // if Fixed, always at base value + int WindGenSolutionCount; + double GenFundamental; /*Thevinen equivalent voltage mag and angle reference for Harmonic model*/ + bool GenON; /*Indicates whether WindGen is currently on*/ + bool GenSwitchOpen; + bool kVANotSet; + double LastGrowthFactor; + int LastYear; // added for speedup so we don't have to search for growth factor a lot + int OpenWindGenSolutionCount; + double PVFactor; // deceleration Factor for computing vars for PV WindGens + double RandomMult; + int Reg_Hours; + int Reg_kvarh; + int Reg_kWh; + int Reg_MaxkVA; + int Reg_MaxkW; + int Reg_Price; + Ucomplex::complex ShapeFactor; +// moved to WindGenVars Thetaharm :Double; {Thevinen equivalent voltage angle reference for Harmonic model} + + System::TTextRec Tracefile; + + TWindGenUserModel *UserModel; + TWindGenUserModel *ShaftModel; /*User-Written Models*/ + + double V_Avg; + double V_Remembered; + double var_Remembered; + double varBase; // Base vars per phase + double varMax; + double varMin; + double VBase; // Base volts suitable for computing currents + double VBase105; + double VBase95; + Ucomplex::complex Vthev; /*Thevinen equivalent voltage (complex) for dynamic model*/ +// moved to WindGenVars Vthevharm :Double; {Thevinen equivalent voltage mag reference for Harmonic model} +// moved to WindGenVars VthevMag :Double; {Thevinen equivalent voltage for dynamic model} + Ucmatrix::TcMatrix* YPrimOpenCond; // To handle cases where one conductor of load is open ; We revert to admittance for inj currents + double YQFixed; // Fixed value of y for type 7 load + bool ShapeIsActual; + bool ForceBalanced; + + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); // now incorporates DutyStart offset + void CalcGenModelContribution(int ActorID); + void CalcInjCurrentArray(int ActorID); + void CalcVterminal(int ActorID); + void CalcVTerminalPhase(int ActorID); + void CalcVthev_Dyn(); // 3-phase Voltage behind transient reactance + void CalcVthev_Dyn_Mod7(const Ucomplex::complex& V); + void CalcYearlyMult(double hr); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + + void DoConstantPQGen(int ActorID); + void DoConstantZGen(int ActorID); + void DoCurrentLimitedPQ(int ActorID); + void DoDynamicMode(int ActorID); + void DoFixedQGen(int ActorID); + void DoFixedQZGen(int ActorID); + void DoHarmonicMode(int ActorID); + void DoPVTypeGen(int ActorID); + void DoUserModel(int ActorID); + void Integrate(int reg, double Deriv, double Interval, int ActorID); + void SetDragHandRegister(int reg, double Value); + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); + + void WriteTraceRecord(const String s, int ActorID); + + void SyncUpPowerQuantities(); + + + double Get_PresentkW(); + double Get_Presentkvar(); + double Get_PresentkV(); + void Set_PresentkV(double Value); + void Set_Presentkvar(double Value); + void Set_PresentkW(double Value); + void Set_PowerFactor(double Value); + + void SetkWkvar(double PkW, double Qkvar); +//protected: + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); +public: + TGE_WTG3_Model* WindModelDyn; + int Connection; /*0 = line-neutral; 1=Delta*/ + String DailyDispShape; // Daily (24 HR) WindGen shape + TLoadShapeObj* DailyDispShapeObj; // Daily WindGen Shape for this load + String DutyShape; // Duty cycle load shape for changes typically less than one hour + TLoadShapeObj* DutyShapeObj; // Shape for this WindGen + double DutyStart; // starting time offset into the DutyShape [hrs] for this WindGen + int GenClass; + int GenModel; // Variation with voltage + TWindGenVars WindGenVars; /*State Variables*/ + double kvarBase, + kvarMax, + kvarMin, + kWBase, + PFNominal, + Vpu, // per unit Target voltage for WindGen with voltage control + Vmaxpu, + Vminpu; + String VV_Curve; + TXYcurveObj* VV_CurveObj; + TXYcurveObj* Loss_CurveObj; + + bool GenActive; +// Fuel variables from Generator model removed + +// moved to WindGenVars VTarget :Double; // Target voltage for WindGen with voltage control + String YearlyShape; // ='fixed' means no variation on all the time + TLoadShapeObj* YearlyShapeObj; // Shape for this WindGen + double Registers[6/*# range 1..NumGenRegisters*/]; + double Derivatives[6/*# range 1..NumGenRegisters*/]; + + TWindGenObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TWindGenObj(); + + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + + + void SetNominalGeneration(int ActorID); + void Randomize(int Opt); // 0 = reset to 1.0; 1 = Gaussian around mean and std Dev ; // 2 = uniform + + void ResetRegisters(); + void TakeSample(int ActorID); + + // Procedures for setting the DQDV used by the Solution Object + void InitDQDVCalc(); + void BumpUpQ(); + void RememberQV(int ActorID); + void CalcDQDV(int ActorID); + void ResetStartPoint(); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + + virtual int CheckIfDynVar(string myVar, int ActorID); + virtual void SetDynOutput(string myVar); + virtual string GetDynOutputStr(); + + bool get_FForcedON(); + void set_FForcedON(bool myState); + double get_PFNominal(); + + TWindGenObj(DSSClass::TDSSClass* ParClass); + TWindGenObj(String ClassName); + TWindGenObj(); +}; +extern TWindGenObj* ActiveWindGenObj; + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace WindGen + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace WindGen; +#endif + +#endif // WindGenH + + + + diff --git a/OpenDSSC/PCElements/WindGenUserModel.cpp b/OpenDSSC/PCElements/WindGenUserModel.cpp new file mode 100644 index 0000000..c729512 --- /dev/null +++ b/OpenDSSC/PCElements/WindGenUserModel.cpp @@ -0,0 +1,186 @@ + +#pragma hdrstop + +#include "WindGenUserModel.h" + +#include "DSSGlobals.h" + +using namespace std; +using namespace Arraydef; +using namespace DSSGlobals; +using namespace Dynamics; +using namespace System; +using namespace Ucomplex; +//using namespace WindGen; +using namespace WindGenVars; + +namespace WindGenUserModel +{ + +TWindGenUserModel::TWindGenUserModel() {} + + + +/* TGenUserModel */ + +void* TWindGenUserModel::CheckFuncError(void* Addr, String FuncName) +{ + void* result = nullptr; + if(Addr == nullptr) + { + DoSimpleMsg(String("WindGen User Model Does Not Have Required Function: ") + FuncName, 569); + FuncError = true; + } + result = Addr; + return result; +} + +TWindGenUserModel::TWindGenUserModel(pTWindGenVars ActiveWindGenVars) + : FHandle(0), + FID(0), + FuncError(false), + FActiveWindGenVars(nullptr) +{ + FID = 0; + FName = ""; + FActiveWindGenVars = ActiveWindGenVars; +} + +TWindGenUserModel::~TWindGenUserModel() +{ + if(FID != 0) + { + FDelete(FID); // Clean up all memory associated with this instance + //free(&FHandle); + } + // inherited; +} + + +bool TWindGenUserModel::Get_Exists() +{ + bool result = false; + if(FID != 0) + { + result = true; + select(); /*Automatically select if true*/ + } + else + result = false; + return result; +} + +void TWindGenUserModel::Integrate() +{ + FSelect(FID); + FIntegrate(); +} + +void TWindGenUserModel::select() +{ + FSelect(FID); +} + +void TWindGenUserModel::Set_Edit(const String Value) +{ + if(FID != 0) + FEdit((System::PAnsiChar) Value.c_str(), Value.size()); + // Else Ignore +} + +//---------------------------------------------------------------- + +String TWindGenUserModel::get_FName() +{ + return FName; +} + +//---------------------------------------------------------------- + +void TWindGenUserModel::Set_Name(const String Value) +{ + + + /*If Model already points to something, then free it*/ + if((HMODULE) FHandle != 0) + { + if(FID != 0) + { + FDelete(FID); + FName = ""; + FID = 0; + } + //free(&FHandle); + } + + /*If Value is blank or zero-length, bail out.*/ + if((Value.size() == 0) || (TrimLeft(Value).size() == 0)) + return; + if(CompareText(Value, "none") == 0) + return; + FHandle = (NativeUInt) LoadLibrary(Value.c_str()); // Default LoadLibrary and PChar must agree in expected type + if((HMODULE) FHandle == 0) // Try again with full path name + { + FHandle = (NativeUInt) LoadLibrary((DSSDirectory + Value).c_str()); + } + if((HMODULE) FHandle == 0) + DoSimpleMsg(String("WindGen User Model ") + Value + + " Not Loaded. DSS Directory = " + + DSSDirectory, 570); + else + { + FName = Value; + + // Now set up all the procedure variables + FuncError = false; + FNew = (WindGenUserModelProc__0) CheckFuncError((void *) GetProcAddress( (HMODULE) FHandle, "New"), "New"); + if(!FuncError) + FSelect = (WindGenUserModelProc__2) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, "Select" ), "Select"); + if(!FuncError) + FInit = (WindGenUserModelProc__4) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, "Init"), "Init"); + if(!FuncError) + FCalc = (WindGenUserModelProc__5) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Calc")), "Calc"); + if(!FuncError) + FIntegrate = (WindGenUserModelProc__6) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Integrate")), "Integrate"); + if(!FuncError) + FSave = (WindGenUserModelProc__8) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Save")), "Save"); + if(!FuncError) + fRestore = (WindGenUserModelProc__9) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Restore")), "Restore"); + if(!FuncError) + FEdit = (WindGenUserModelProc__3) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Edit")), "Edit"); + if(!FuncError) + FUpdateModel = (WindGenUserModelProc__7) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("UpdateModel")), "UpdateModel"); + if(!FuncError) + FDelete = (WindGenUserModelProc__1) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("Delete")), "Delete"); + if(!FuncError) + FNumVars = (WindGenUserModelProc__10) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("NumVars")), "NumVars"); + if(!FuncError) + FGetAllVars = (WindGenUserModelProc__11) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetAllVars")), "GetAllVars"); + if(!FuncError) + FGetVariable = (WindGenUserModelProc__12) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVariable")), "GetVariable"); + if(!FuncError) + FSetVariable = (WindGenUserModelProc__13) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("SetVariable")), "SetVariable"); + if(!FuncError) + FGetVarName = (WindGenUserModelProc__14) CheckFuncError((void *) GetProcAddress((HMODULE) FHandle, ("GetVarName")), "GetVarName"); + if(FuncError) + { + FreeLibrary((HMODULE) FHandle); + FID = 0; + FHandle = 0; + FName = ""; + } + else + { + FID = FNew((*FActiveWindGenVars), ActiveCircuit[ActiveActor]->Solution->DynaVars, CallBackRoutines); // Create new instance of user model + } + } +} + + + + +} // namespace WindGenUserModel + + + + diff --git a/OpenDSSC/PCElements/WindGenUserModel.h b/OpenDSSC/PCElements/WindGenUserModel.h new file mode 100644 index 0000000..2239446 --- /dev/null +++ b/OpenDSSC/PCElements/WindGenUserModel.h @@ -0,0 +1,108 @@ +#ifndef WindGenUserModelH +#define WindGenUserModelH + +#include "System.h" + +#include "WindGenVars.h" +#include "Dynamics.h" +#include "DSSCallBackRoutines.h" +#include "Ucomplex.h" +#include "Arraydef.h" + +//#include "WindGen.h" +#include "Sysutils.h" + +namespace WindGenUserModel +{ + + + + /*$M+*/ + /* + ---------------------------------------------------------- + Copyright (c) 2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + + + */ + + class TWindGenUserModel : public System::TObject + { + public: + typedef TObject inherited; + //private: + System::NativeUInt FHandle; // Handle to DLL containing user model + int FID; // ID of this instance of the user model + // OK for this to be Wide String, since not passed to DLLs + String FName; // Name of the DLL file containing user model + bool FuncError; + + + /*These functions should only be called by the object itself*/// Make a new instance + typedef int (__stdcall *WindGenUserModelProc__0)(WindGenVars::TWindGenVars&, Dynamics::TDynamicsRec&, TDSSCallBacks&); + WindGenUserModelProc__0 FNew; // deletes specified instance + typedef void (__stdcall *WindGenUserModelProc__1)(int&); + WindGenUserModelProc__1 FDelete; // Select active instance + typedef int (__stdcall *WindGenUserModelProc__2)(int&); + WindGenUserModelProc__2 FSelect; + void Set_Name(const String Value); + void* CheckFuncError(void* Addr, String FuncName); + void Set_Edit(const String Value); + bool Get_Exists(); + protected: + public: // send string to user model to handle + typedef void (__stdcall *WindGenUserModelProc__3)(System::PAnsiChar, unsigned int); + WindGenUserModelProc__3 FEdit; // For dynamics + typedef void (__stdcall *WindGenUserModelProc__4)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + WindGenUserModelProc__4 FInit; // returns Currents or sets Pshaft + typedef void (__stdcall *WindGenUserModelProc__5)(Ucomplex::pComplexArray, Ucomplex::pComplexArray); + WindGenUserModelProc__5 FCalc; // Integrates any state vars + typedef void (__stdcall *WindGenUserModelProc__6)(); + WindGenUserModelProc__6 FIntegrate; // Called when props of WindGen updated + typedef void (__stdcall *WindGenUserModelProc__7)(); + WindGenUserModelProc__7 FUpdateModel; + WindGenVars::pTWindGenVars FActiveWindGenVars; + + /*Save and restore data*/ + typedef void (__stdcall *WindGenUserModelProc__8)(); + WindGenUserModelProc__8 FSave; + + /*Monitoring functions*/ + typedef void (__stdcall *WindGenUserModelProc__9)(); + WindGenUserModelProc__9 fRestore; + typedef int (__stdcall *WindGenUserModelProc__10)(); + WindGenUserModelProc__10 FNumVars; // Get all vars + typedef void (__stdcall *WindGenUserModelProc__11)(Arraydef::pDoubleArray); + WindGenUserModelProc__11 FGetAllVars;// Get a particular var + typedef double (__stdcall *WindGenUserModelProc__12)(int&); + WindGenUserModelProc__12 FGetVariable; + typedef void (__stdcall *WindGenUserModelProc__13)(int&, double&); + WindGenUserModelProc__13 FSetVariable; + + String get_FName(); + + // this property loads library (if needed), sets the procedure variables, and makes a new instance + // old reference is freed first + // Wide string OK here + typedef void (__stdcall *WindGenUserModelProc__14)(int&, System::PAnsiChar, unsigned int); + WindGenUserModelProc__14 FGetVarName; + void select(); + void Integrate(); + TWindGenUserModel(WindGenVars::pTWindGenVars ActiveWindGenVars); + virtual ~TWindGenUserModel(); + //__published: + public: + TWindGenUserModel(); + }; + + +} // namespace WindGenUserModel + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace WindGenUserModel; +#endif + +#endif // WindGenUserModelH + diff --git a/OpenDSSC/PCElements/WindGenVars.cpp b/OpenDSSC/PCElements/WindGenVars.cpp new file mode 100644 index 0000000..1a31797 --- /dev/null +++ b/OpenDSSC/PCElements/WindGenVars.cpp @@ -0,0 +1,23 @@ + +#pragma hdrstop + +#include "WindGenVars.h" + +using namespace std; + +using namespace System; +using namespace Ucomplex; + +namespace WindGenVars +{ + + + + + + +} // namespace WindGenVars + + + + diff --git a/OpenDSSC/PCElements/WindGenVars.h b/OpenDSSC/PCElements/WindGenVars.h new file mode 100644 index 0000000..c9691a5 --- /dev/null +++ b/OpenDSSC/PCElements/WindGenVars.h @@ -0,0 +1,99 @@ +#ifndef WindGenVarsH +#define WindGenVarsH + +#include "System.h" + +#include "Ucomplex.h" + +namespace WindGenVars +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2024, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + Definition of WindGen Public Data Record for passing to DLLs and other object +*/ + + /*WindGen public data/state variable structure*/ +#pragma pack (push, 1) + +struct TWindGenVars; +typedef TWindGenVars* pTWindGenVars; + +struct TWindGenVars +{ + /*Direct-Axis voltage magnitude & angle*/ /*present Shaft Power and relative Speed, rad/sec, difference from Synchronous speed, w0*/ + /*actual speed = Speed + w0*/ /*Per unit mass constant*/ /*Mass constant actual values (Joule-sec/rad*/ /*Actual and per unit damping factors*/ /*machine Reactances, ohms*/ /*machine Reactances, per unit*/ /*Derivatives of Theta and Speed*/ /*history variables for integration*/ /*Target P and Q for power flow solution, watts, vars*/ + double Theta, + Pshaft, + Speed, + w0, + Hmass, + Mmass, + D, + Dpu, + kVArating, + kVWindGenBase, + XD, + Xdp, + Xdpp, + puXd, + puXdp, + puXdpp, + dTheta, + dSpeed, + ThetaHistory, + SpeedHistory, + Pnominalperphase, + Qnominalperphase; /* All Doubles */ + + /*32-bit integers*/ /*Number of phases*/ /*Total Number of conductors (wye-connected will have 4)*/ + int NumPhases, + NumConductors, + Conn; // 0 = wye; 1 = Delta + + /* Revisons (additions) to structure ... + Later additions are appended to end of the structure so that + previously compiled DLLs do not break + */ + double VthevMag, /*Thevinen equivalent voltage for dynamic model*/ + VThevHarm, /*Thevinen equivalent voltage mag reference for Harmonic model*/ + ThetaHarm, /*Thevinen equivalent voltage angle reference for Harmonic model*/ + VTarget; // Target voltage for WindGen with voltage control + complex Zthev; + double XRdp; // Assumed X/R for Xd' + String PLoss; // Name of the XY curve describing the active power losses for the turbine + double ag, // Garbox ratio + Cp, // Turbine performance coefficient + Lamda, // Tip speed ratio + Poles, // Number of poles of the induction generator + pd, // Air density + Rad, // Rotor radius + VCutin, // Cut-in speed for the wind generator + VCutout, // Cut-out speed for the wind generator + Pm, // mechanical power (steady-state) + Ps, // Stator active power + Pr, // Rotor active power + Pg, // Total power output + s; // generator pitch +}; +#pragma pack (pop) + + + +} // namespace WindGenVars + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace WindGenVars; +#endif + +#endif // WindGenVarsH + + + + diff --git a/OpenDSSC/PCElements/generator.cpp b/OpenDSSC/PCElements/generator.cpp new file mode 100644 index 0000000..40d87fa --- /dev/null +++ b/OpenDSSC/PCElements/generator.cpp @@ -0,0 +1,4001 @@ + + +#pragma hdrstop + +#include "generator.h" + +#include "ParserDel.h" +#include "Circuit.h" +#include "Command.h" +#include +#include "mathutil.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "ControlElem.h" +#include "Solution.h" + +// list of dynamic models +#include "gencls.h" +#include "genrou.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace GenUserModel; +using namespace GeneratorVars; +using namespace LoadShape; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Generator +{ + + // Should initialize members on these constructors, that is just good practice +TGeneratorObj::TGeneratorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGeneratorObj::TGeneratorObj(String ClassName) : inherited(ClassName) {} +TGeneratorObj::TGeneratorObj() {} + + +TGeneratorObj* ActiveGeneratorObj = nullptr; +TGenerator* GeneratorClass = nullptr; +const int NumPropsThisClass = 46; + // Dispatch modes +const int Default = 0; +const int LOADMODE = 1; +const int PRICEMODE = 2; +complex cBuffer[24/*# range 1..24*/]; // Temp buffer for calcs 24-phase generator? +complex CDoubleOne = {}; +// TwoPI3:Double; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TGenerator::TGenerator() +{ + ; + Class_Name = "Generator"; + DSSClassType = DSSClassType + GEN_ELEMENT; // In both PCelement and Genelement list + ActiveElement = 0; + + // Set Register names + RegisterNames[1 - 1] = "kWh"; + RegisterNames[2 - 1] = "kvarh"; + RegisterNames[3 - 1] = "Max kW"; + RegisterNames[4 - 1] = "Max kVA"; + RegisterNames[5 - 1] = "Hours"; + RegisterNames[6 - 1] = "$"; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + GeneratorClass = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGenerator::~TGenerator() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGenerator::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); /*see DSSClass*/ + + // Define Property names + AddProperty("phases", 1, "Number of Phases, this Generator. Power is evenly divided among phases."); + AddProperty("bus1", 2, "Bus to which the Generator is connected. May include specific node specification."); + AddProperty("kv", 3, "Nominal rated (1.0 per unit) voltage, kV, for Generator. For 2- and 3-phase Generators, specify phase-phase kV. " + "Otherwise, for phases=1 or phases>3, specify actual kV across each branch of the Generator. " + "If wye (star), specify phase-neutral kV. " + "If delta or phase-phase connected, specify phase-phase kV."); // line-neutral voltage// base voltage + AddProperty("kW", 4, String("Total base kW for the Generator. A positive value denotes power coming OUT of the element, ") + CRLF + + "which is the opposite of a load. This value is modified depending on the dispatch mode. " + + "Unaffected by the global load multiplier and growth curves. " + + "If you want there to be more generation, you must add more generators or change this value."); + AddProperty("pf", 5, String("Generator power factor. Default is 0.80. Enter negative for leading powerfactor " "(when kW and kvar have opposite signs.)") + CRLF + + "A positive power factor for a generator signifies that the generator produces vars " + + CRLF + + "as is typical for a synchronous generator. Induction machines would be " + + CRLF + + "specified with a negative power factor."); + AddProperty("kvar", 13, "Specify the base kvar. Alternative to specifying the power factor. Side effect: " + " the power factor value is altered to agree based on present value of kW."); + AddProperty("model", 6, String("Integer code for the model to use for generation variation with voltage. " "Valid values are:") + CRLF + + CRLF + + "1:Generator injects a constant kW at specified power factor." + + CRLF + + "2:Generator is modeled as a constant admittance." + + CRLF + + "3:Const kW, constant kV. Somewhat like a conventional transmission power flow P-V generator." + + CRLF + + "4:Const kW, Fixed Q (Q never varies)" + + CRLF + + "5:Const kW, Fixed Q(as a constant reactance)" + + CRLF + + "6:Compute load injection from User-written Model.(see usage of Xd, Xdp)" + + CRLF + + "7:Constant kW, kvar, but current-limited below Vminpu. Approximates a simple inverter. See also Balanced."); + AddProperty("Vminpu", 23, "Default = 0.90. Minimum per unit voltage for which the Model is assumed to apply. " + "Below this value, the load model reverts to a constant impedance model. For model 7, the current is " + "limited to the value computed for constant power at Vminpu."); + AddProperty("Vmaxpu", 24, "Default = 1.10. Maximum per unit voltage for which the Model is assumed to apply. " + "Above this value, the load model reverts to a constant impedance model."); + AddProperty("yearly", 7, "Dispatch shape to use for yearly simulations. Must be previously defined " + "as a Loadshape object. If this is not specified, a constant value is assumed (no variation). " + "If the generator is assumed to be ON continuously, specify Status=FIXED, or " + "designate a curve that is 1.0 per unit at all times. " + "Set to NONE to reset to no loadahape. " + "Nominally for 8760 simulations. If there are fewer points in the designated shape than " + "the number of points in the solution, the curve is repeated."); + AddProperty("daily", 8, "Dispatch shape to use for daily simulations. Must be previously defined " + "as a Loadshape object of 24 hrs, typically. If generator is assumed to be " + "ON continuously, specify Status=FIXED, or designate a Loadshape object" + "that is 1.0 perunit for all hours. " + "Set to NONE to reset to no loadahape. "); // daily dispatch (hourly) + AddProperty("duty", 9, "Load shape to use for duty cycle dispatch simulations such as for wind generation. " + "Must be previously defined as a Loadshape object. " + "Typically would have time intervals less than 1 hr -- perhaps, in seconds. " + "Set Status=Fixed to ignore Loadshape designation. " + "Set to NONE to reset to no loadahape. " + "Designate the number of points to solve using the Set Number=xxxx command. " + "If there are fewer points in the actual shape, the shape is assumed to repeat."); // as for wind generation + AddProperty("dispmode", 10, "{Default* | Loadlevel | Price } Default = Default. Dispatch mode. " + "In default mode, gen is either always on or follows dispatch curve as specified. " + "Otherwise, the gen comes on when either the global default load level (Loadshape \"default\") or the price level " + "exceeds the dispatch value."); // = 0 | >0 + AddProperty("dispvalue", 11, String("Dispatch value. ") + CRLF + + "If = 0.0 (default) then Generator follow dispatch curves, if any. " + + CRLF + + "If > 0 then Generator is ON only when either the price signal (in Price dispatch mode) " + + "exceeds this value or the active circuit load multiplier * \"default\" loadshape value * the default yearly growth factor " + + "exceeds this value. Then the generator follows dispatch curves (duty, daily, or yearly), if any (see also Status)."); // = 0 | >0 + AddProperty("conn", 12, "={wye|LN|delta|LL}. Default is wye."); + AddProperty("Rneut", 14, "Removed due to causing confusion - Add neutral impedance externally."); + AddProperty("Xneut", 15, "Removed due to causing confusion - Add neutral impedance externally."); + AddProperty("status", 16, "={Fixed | Variable*}. If Fixed, then dispatch multipliers do not apply. " + "The generator is alway at full power when it is ON. " + " Default is Variable (follows curves)."); // fixed or variable + AddProperty("class", 17, "An arbitrary integer number representing the class of Generator so that Generator values may " + "be segregated by class."); // integer + AddProperty("Vpu", 18, "Per Unit voltage set point for Model = 3 (typical power flow model). Default is 1.0. "); // per unit set point voltage for power flow model + AddProperty("maxkvar", 19, "Maximum kvar limit for Model = 3. Defaults to twice the specified load kvar. " + "Always reset this if you change PF or kvar properties."); + AddProperty("minkvar", 20, "Minimum kvar limit for Model = 3. Enter a negative number if generator can absorb vars." + " Defaults to negative of Maxkvar. Always reset this if you change PF or kvar properties."); + AddProperty("pvfactor", 21, "Deceleration factor for P-V generator model (Model=3). Default is 0.1. " + "If the circuit converges easily, you may want to use a higher number such as 1.0. " + "Use a lower number if solution diverges. Use Debugtrace=yes to create a file that will " + "trace the convergence of a generator model."); + AddProperty("forceon", 25, "{Yes | No} Forces generator ON despite requirements of other dispatch modes. " + "Stays ON until this property is set to NO, or an internal algorithm cancels the forced ON state."); + AddProperty("kVA", 26, "kVA rating of electrical machine. Defaults to 1.2* kW if not specified. Applied to machine or inverter definition for Dynamics mode solutions. "); + AddProperty("MVA", 27, "MVA rating of electrical machine. Alternative to using kVA=."); + AddProperty("Xd", 28, "Per unit synchronous reactance of machine. Presently used only for Thevinen impedance for power flow calcs of user models (model=6). " + "Typically use a value 0.4 to 1.0. Default is 1.0"); + AddProperty("Xdp", 29, "Per unit transient reactance of the machine. Used for Dynamics mode and Fault studies. Default is 0.27." + "For user models, this value is used for the Thevinen/Norton impedance for Dynamics Mode."); + AddProperty("Xdpp", 30, "Per unit subtransient reactance of the machine. Used for Harmonics. Default is 0.20."); + AddProperty("H", 31, "Per unit mass constant of the machine. MW-sec/MVA. Default is 1.0."); + AddProperty("D", 32, "Damping constant. Usual range is 0 to 4. Default is 1.0. Adjust to get damping"); + AddProperty("UserModel", 33, "Name of DLL containing user-written model, which computes the terminal currents for Dynamics studies, " + "overriding the default model. Set to \"none\" to negate previous setting."); + AddProperty("UserData", 34, "String (in quotes or parentheses) that gets passed to user-written model for defining the data required for that model."); + AddProperty("ShaftModel", 35, "Name of user-written DLL containing a Shaft model, which models the prime mover and determines the power on the shaft for Dynamics studies. " + "Models additional mass elements other than the single-mass model in the DSS default model. Set to \"none\" to negate previous setting."); + AddProperty("ShaftData", 36, "String (in quotes or parentheses) that gets passed to user-written shaft dynamic model for defining the data for that model."); + AddProperty("DutyStart", 37, "Starting time offset [hours] into the duty cycle shape for this generator, defaults to 0"); + AddProperty("debugtrace", 22, "{Yes | No } Default is no. Turn this on to capture the progress of the generator model " + "for each iteration. Creates a separate file for each generator named \"GEN_name.CSV\"."); + AddProperty("Balanced", 38, "{Yes | No*} Default is No. For Model=7, force balanced current only for 3-phase generators. Force zero- and negative-sequence to zero."); + AddProperty("XRdp", 39, "Default is 20. X/R ratio for Xdp property for FaultStudy and Dynamic modes."); + AddProperty("UseFuel", 40, "{Yes | *No}. Activates the use of fuel for the operation of the generator. When the fuel level" + " reaches the reserve level, the generator stops until it gets refueled. By default, the generator " + "is connected to a continuous fuel supply, Use this mode to mimic dependency on fuel level for different " + "generation technologies."); + AddProperty("FuelkWh", 41, "{*0}Is the nominal level of fuel for the generator (kWh). It only applies if UseFuel = Yes/True"); + AddProperty("%Fuel", 42, "It is a number between 0 and 100 representing the current amount of fuel avaiable in percentage " + "of FuelkWh. It only applies if UseFuel = Yes/True"); + AddProperty("%Reserve", 43, "It is a number between 0 and 100 representing the reserve level in percentage of FuelkWh. " + "It only applies if UseFuel = Yes/True"); + AddProperty("Refuel", 44, "It is a boolean value (Yes/True, No/False) that can be used to manually refuel the generator when needed. " + "It only applies if UseFuel = Yes/True"); + AddProperty("DynamicEq", 45, "The name of the dynamic equation (DinamicExp) that will be used for defining the dynamic behavior of the generator. " + "if not defined, the generator dynamics will follow the built-in dynamic equation."); + AddProperty("DynOut", 46, "The name of the variables within the Dynamic equation that will be used to govern the generator dynamics." + "This generator model requires 2 outputs from the dynamic equation: " + CRLF + CRLF + + "1. Shaft speed (velocity) relative to synchronous speed." + CRLF + + "2. Shaft, or power, angle (relative to synchronous reference frame)." + CRLF + CRLF + + "The output variables need to be defined in the same order."); + AddProperty("spectrum", 47, "Spectrum"); + AddProperty("basefreq", 48, "basefreq"); + AddProperty("enabled", 49, "enabled"); + AddProperty("like", 50, "like"); + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override default help string + (PropertyHelp)[NumPropsThisClass] = "Name of harmonic voltage or current spectrum for this generator. " + "Voltage behind Xd\" for machine - default. Current injection for inverter. " + "Default value is \"default\", which is defined when the DSS starts."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGenerator::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Generator and add it to Generator class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGeneratorObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGenerator::SetNcondsForConnection() +{ + /*# with ActiveGeneratorObj do */ + { + auto with0 = ActiveGeneratorObj; + switch(with0->Connection) + { + case 0: + with0->Set_Nconds(with0->Fnphases + 1); + break; + case 1: + switch(with0->Fnphases) + { + case 1: + case 2: + with0->Set_Nconds(with0->Fnphases + 1); + break; // L-L and Open-delta + default: + with0->Set_Nconds(with0->Fnphases); + break; + } + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TGenerator::InterpretConnection(const String s) +{ + String TestS = ""; + /*# with ActiveGeneratorObj do */ + { + auto with0 = ActiveGeneratorObj; + TestS = LowerCase(s); + switch(TestS[0]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[1]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + SetNcondsForConnection(); + + /*VBase is always L-N voltage unless 1-phase device or more than 3 phases*/ + /*# with GenVars do */ + { + auto& with1 = with0->GenVars; + switch(with0->Fnphases) + { /*CASE Connection OF + 1: VBase := kVGeneratorBase * 1000.0 ; + Else*/ + case 2: case 3: + with0->VBase = with1.kVGeneratorBase * InvSQRT3x1000; + break; // L-N Volts + default: + with0->VBase = with1.kVGeneratorBase * 1000.0; // Just use what is supplied + break; + } + } + /*End;*/ + with0->VBase95 = with0->Vminpu * with0->VBase; + with0->VBase105 = with0->Vmaxpu * with0->VBase; + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int InterpretDispMode(const String s) +{ + int result = 0; + switch(LowerCase(s)[0]) + { + case L'l': + result = LOADMODE; + break; + case L'p': + result = PRICEMODE; + break; + default: + result = Default; + break; + } + return result; +} + + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGenerator::Edit(int ActorID) +{ + int result = 0; + int i = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveGeneratorObj = (TGeneratorObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGeneratorObj); + result = 0; + /*# with ActiveGeneratorObj do */ + { + auto with0 = ActiveGeneratorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while (Param.size() > 0) + { + if (ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if ((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue((PropertyIdxMap)[ParamPointer - 1], Param); + else + { + // first, checks if there is a dynamic eq assigned, then + // checks if the new property edit the state variables within + int VarIdx = with0->CheckIfDynVar(ParamName, ActorID); + if ( VarIdx < 0 ) + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Generator \"" + + with0->get_Name() + + "\"", 560); + } + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 561); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; // num phases + case 2: + with0->SetBus(1, Param); + break; + case 3: + with0->Set_PresentkV(Parser[ActorID]->MakeDouble_() ); + break; + case 4: + with0->kWBase = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->PFNominal = Parser[ActorID]->MakeDouble_(); + break; + case 6: + with0->GenModel = Parser[ActorID]->MakeInteger_(); + break; + case 7: + with0->YearlyShape = Param; + break; + case 8: + with0->DailyDispShape = Param; + break; + case 9: + with0->DutyShape = Param; + break; + case 10: + with0->DispatchMode = InterpretDispMode(Param); + break; + case 11: + with0->DispatchValue = Parser[ActorID]->MakeDouble_(); + break; + case 12: + InterpretConnection(Param); + break; + case 13: + with0->Set_Presentkvar(Parser[ActorID]->MakeDouble_()); + break; + case 14: + DoSimpleMsg("Rneut property has been deleted. Use external impedance.", 5611); + break; + case 15: + DoSimpleMsg("Xneut property has been deleted. Use external impedance.", 5612); + break; + case 16: + if(LowerCase(&(Param[0])) == "f") + with0->IsFixed = true; + else + with0->IsFixed = false; + break; + case 17: + with0->GenClass = Parser[ActorID]->MakeInteger_(); + break; + case 18: + with0->Vpu = Parser[ActorID]->MakeDouble_(); + break; + case 19: + with0->kvarMax = Parser[ActorID]->MakeDouble_(); + break; + case 20: + with0->kvarMin = Parser[ActorID]->MakeDouble_(); + break; + case 21: + with0->PVFactor = Parser[ActorID]->MakeDouble_(); + break; //decelaration factor + case 22: + with0->DebugTrace = InterpretYesNo(Param); + break; + case 23: + with0->Vminpu = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->Vmaxpu = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->FForcedON = InterpretYesNo(Param); + break; + case 26: + with0->GenVars.kVArating = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->GenVars.kVArating = Parser[ActorID]->MakeDouble_() * 1000.0; + break; // 'MVA'; + case 28: + with0->GenVars.puXd = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->GenVars.puXdp = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->GenVars.puXdpp = Parser[ActorID]->MakeDouble_(); + break; + case 31: + with0->GenVars.Hmass = Parser[ActorID]->MakeDouble_(); + break; + case 32: + with0->GenVars.Dpu = Parser[ActorID]->MakeDouble_(); + break; + case 33: + with0->UserModel->Set_Name(Parser[ActorID]->MakeString_()); + break; // Connect to user written models + case 34: + with0->UserModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; // Send edit string to user model + case 35: + with0->ShaftModel->Set_Name(Parser[ActorID]->MakeString_()); + break; + case 36: + with0->ShaftModel->Set_Edit(Parser[ActorID]->MakeString_()); + break; + case 37: + with0->DutyStart = Parser[ActorID]->MakeDouble_(); + break; + case 38: + with0->ForceBalanced = InterpretYesNo(Param); + break; + case 39: + with0->GenVars.XRdp = Parser[ActorID]->MakeDouble_(); + break; // X/R for dynamics model + case 40: + with0->UseFuel = InterpretYesNo(Param); + break; + case 41: + with0->FuelkWh = Parser[ActorID]->MakeDouble_(); + break; + case 42: + with0->pctFuel = Parser[ActorID]->MakeDouble_(); + break; + case 43: + with0->pctReserve = Parser[ActorID]->MakeDouble_(); + break; + case 44: + if(InterpretYesNo(Param)) + { + with0->pctFuel = 100.0; + with0->GenActive = true; + } + break; + case 45: + with0->DynamicEq = Param; + break; + case 46: + with0->SetDynOutput(Param); + break; + // Inherited parameters + default: + inherited::ClassEdit(ActiveGeneratorObj, ParamPointer - NumPropsThisClass); + break; + } + if(ParamPointer > 0) + switch((PropertyIdxMap)[ParamPointer - 1]) + { + case 1: + SetNcondsForConnection(); + break; // Force Reallocation of terminal info + // keep kvar nominal up to date with kW and PF + case 4: case 5: + with0->SyncUpPowerQuantities(); + break; + case 6: + ActiveCircuit[ActorID]->Solution->SolutionInitialized = !(with0->GenModel == 3); // if a model 3 generator added, force calc of dQdV + break; + /*Set shape objects; returns nil if not valid*/ + /*Sets the kW and kvar properties to match the peak kW demand from the Loadshape*/ + case 7: + { + with0->YearlyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->YearlyShape)); + if(ASSIGNED(with0->YearlyShapeObj)) + /*# with YearlyShapeObj do */ + { + auto with1 = with0->YearlyShapeObj; + if(with1->UseActual) + with0->SetkWkvar(with1->MaxP, with1->MaxQ); + } + } + break; + case 8: + { + with0->DailyDispShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DailyDispShape)); + if(ASSIGNED(with0->DailyDispShapeObj)) + /*# with DailyDispShapeObj do */ + { + auto with2 = with0->DailyDispShapeObj; + if(with2->UseActual) + with0->SetkWkvar(with2->MaxP, with2->MaxQ); + } + } + break; + case 9: + { + with0->DutyShapeObj = ((TLoadShapeObj*) LoadShapeClass[ActorID]->Find(with0->DutyShape)); + if(ASSIGNED(with0->DutyShapeObj)) + /*# with DutyShapeObj do */ + { + auto with3 = with0->DutyShapeObj; + if(with3->UseActual) + with0->SetkWkvar(with3->MaxP, with3->MaxQ); + } + } + break; + case 22: + if(with0->DebugTrace) + { + int stop = 0; + AssignFile(with0->Tracefile, GetOutputDirectory() + "GEN_" + with0->get_Name() + ".CSV"); + Rewrite(with0->Tracefile); + IOResultToException(); + Write(with0->Tracefile, "t, Iteration, LoadMultiplier, Mode, LoadModel, GenModel, dQdV, Avg_Vpu, Vdiff, MQnominalperphase, MPnominalperphase, CurrentType"); + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iinj") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Iterm") + IntToStr(i) + "|"); + } + for(stop = with0->Get_NPhases(), i = 1; i <= stop; i++) + { + Write(with0->Tracefile, String(", |Vterm") + IntToStr(i) + "|"); + } + Write(with0->Tracefile, ",Vthev, Theta"); + WriteLn(with0->Tracefile); + CloseFile(with0->Tracefile); + } + break; + case 26: case 27: + with0->kVANotSet = false; + break; + case 45: + with0->DynamicEqObj = (TDynamicExpObj*) TDynamicExpClass[ActorID]->Find(with0->DynamicEq); + if (ASSIGNED(with0->DynamicEqObj)) + { + with0->DynamicEqVals.resize(with0->DynamicEqObj->get_FNumVars()); + for (int idx = 0; idx < with0->DynamicEqVals.size(); idx++) + with0->DynamicEqVals[idx].resize(2); + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TGenerator::MakeLike(const String OtherGeneratorName) +{ + int result = 0; + TGeneratorObj* OtherGenerator = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherGenerator = ((TGeneratorObj*) Find(OtherGeneratorName)); + if(OtherGenerator != nullptr) + /*# with ActiveGeneratorObj do */ + { + auto with0 = ActiveGeneratorObj; + int stop = 0; + if(with0->Fnphases != OtherGenerator->Fnphases) + { + with0->Set_NPhases(OtherGenerator->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->GenVars.kVGeneratorBase = OtherGenerator->GenVars.kVGeneratorBase; + with0->VBase = OtherGenerator->VBase; + with0->Vminpu = OtherGenerator->Vminpu; + with0->Vmaxpu = OtherGenerator->Vmaxpu; + with0->VBase95 = OtherGenerator->VBase95; + with0->VBase105 = OtherGenerator->VBase105; + with0->kWBase = OtherGenerator->kWBase; + with0->kvarBase = OtherGenerator->kvarBase; + with0->GenVars.Pnominalperphase = OtherGenerator->GenVars.Pnominalperphase; + with0->PFNominal = OtherGenerator->PFNominal; + with0->GenVars.Qnominalperphase = OtherGenerator->GenVars.Qnominalperphase; + with0->varMin = OtherGenerator->varMin; + with0->varMax = OtherGenerator->varMax; + with0->Connection = OtherGenerator->Connection; + // Rneut := OtherGenerator.Rneut; + // Xneut := OtherGenerator.Xneut; + with0->YearlyShape = OtherGenerator->YearlyShape; + with0->YearlyShapeObj = OtherGenerator->YearlyShapeObj; + with0->DailyDispShape = OtherGenerator->DailyDispShape; + with0->DailyDispShapeObj = OtherGenerator->DailyDispShapeObj; + with0->DutyShape = OtherGenerator->DutyShape; + with0->DutyShapeObj = OtherGenerator->DutyShapeObj; + with0->DutyStart = OtherGenerator->DutyStart; + with0->DispatchMode = OtherGenerator->DispatchMode; + with0->DispatchValue = OtherGenerator->DispatchValue; + with0->GenClass = OtherGenerator->GenClass; + with0->GenModel = OtherGenerator->GenModel; + with0->IsFixed = OtherGenerator->IsFixed; + with0->GenVars.VTarget = OtherGenerator->GenVars.VTarget; + with0->Vpu = OtherGenerator->Vpu; + with0->kvarMax = OtherGenerator->kvarMax; + with0->kvarMin = OtherGenerator->kvarMin; + with0->FForcedON = OtherGenerator->FForcedON; + with0->kVANotSet = OtherGenerator->kVANotSet; + with0->UseFuel = OtherGenerator->UseFuel; + with0->FuelkWh = OtherGenerator->FuelkWh; + with0->pctFuel = OtherGenerator->pctFuel; + with0->pctReserve = OtherGenerator->pctReserve; + with0->GenVars.kVArating = OtherGenerator->GenVars.kVArating; + with0->GenVars.puXd = OtherGenerator->GenVars.puXd; + with0->GenVars.puXdp = OtherGenerator->GenVars.puXdp; + with0->GenVars.puXdpp = OtherGenerator->GenVars.puXdpp; + with0->GenVars.Hmass = OtherGenerator->GenVars.Hmass; + with0->GenVars.Theta = OtherGenerator->GenVars.Theta; + with0->GenVars.Speed = OtherGenerator->GenVars.Speed; + with0->GenVars.w0 = OtherGenerator->GenVars.w0; + with0->GenVars.dSpeed = OtherGenerator->GenVars.dSpeed; + with0->GenVars.D = OtherGenerator->GenVars.D; + with0->GenVars.Dpu = OtherGenerator->GenVars.Dpu; + with0->GenVars.XRdp = OtherGenerator->GenVars.XRdp; + with0->UserModel->FName = OtherGenerator->UserModel->FName; // Connect to user written models + with0->ShaftModel->FName = OtherGenerator->ShaftModel->FName; + ClassMakeLike(OtherGenerator); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->FPropertyValue[i - 1] = OtherGenerator->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Load MakeLike: \"") + OtherGeneratorName + + "\" Not Found.", 562); + return result; +} + +//---------------------------------------------------------------------------- + +int TGenerator::Init(int Handle, int ActorID) +{ + int result = 0; + TGeneratorObj* P = nullptr; + if(Handle == 0) // init all + { + P = (TGeneratorObj*) ElementList.Get_First(); + while((P != nullptr)) + { + P->Randomize(0); + P = (TGeneratorObj*) ElementList.Get_Next(); + } + } + else + { + Set_Active(Handle); + P = ((TGeneratorObj*) GetActiveObj()); + P->Randomize(0); + } + DoSimpleMsg("Need to implement TGenerator.Init", -1); + result = 0; + return result; +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to reset + +void TGenerator::ResetRegistersAll(int ActorID) +{ + TGeneratorObj* pGen = nullptr; + pGen = ((TGeneratorObj*) ActiveCircuit[ActorID]->Generators.Get_First()); + while((pGen != nullptr)) + { + pGen->ResetRegisters(); + pGen = ((TGeneratorObj*) ActiveCircuit[ActorID]->Generators.Get_Next()); + } +} + +/*--------------------------------------------------------------------------*/ // Force all EnergyMeters in the circuit to take a sample + +void TGenerator::SampleAll(int ActorID) +{ + TGeneratorObj* pGen = nullptr; + pGen = ((TGeneratorObj*) ActiveCircuit[ActorID]->Generators.Get_First()); + while(pGen != nullptr) + { + if(pGen->Get_Enabled()) + pGen->TakeSample(ActorID); + pGen = ((TGeneratorObj*) ActiveCircuit[ActorID]->Generators.Get_Next()); + } +} + +//---------------------------------------------------------------------------- + +TGeneratorObj::TGeneratorObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + Model7MaxPhaseCurr(0.0), + Model7LastAngle(0.0), + DebugTrace(false), + DeltaQMax(0.0), + DispatchMode(0), + DispatchValue(0.0), + DQDV(0.0), + DQDVSaved(0.0), + FForcedON(false), + FirstSampleAfterReset(false), + IsFixed(false), + GeneratorSolutionCount(0), + GenFundamental(0.0), + GenON(false), + GenSwitchOpen(false), + kVANotSet(false), + LastGrowthFactor(0.0), + LastYear(0), + OpenGeneratorSolutionCount(0), + RandomMult(0.0), + Reg_Hours(0), + Reg_kvarh(0), + Reg_kWh(0), + Reg_MaxkVA(0), + Reg_MaxkW(0), + Reg_Price(0), + UserModel(nullptr), + ShaftModel(nullptr), + V_Avg(0.0), + V_Remembered(0.0), + var_Remembered(0.0), + varBase(0.0), + varMax(0.0), + varMin(0.0), + VBase(0.0), + VBase105(0.0), + VBase95(0.0), + YPrimOpenCond(nullptr), + YQFixed(0.0), + ShapeIsActual(false), + ForceBalanced(false), + Connection(0), + DailyDispShapeObj(nullptr), + DutyShapeObj(nullptr), + DutyStart(0.0), + GenClass(0), + GenModel(0), + kvarBase(0.0), + kvarMax(0.0), + kvarMin(0.0), + kWBase(0.0), + PFNominal(0.0), + Vpu(0.0), + Vmaxpu(0.0), + Vminpu(0.0), + GenActive(false), + UseFuel(false), + FuelkWh(0.0), + pctFuel(0.0), + pctReserve(0.0), + YearlyShapeObj(nullptr) +{ + int i; + + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; // + GEN_ELEMENT; // In both PCelement and Genelement list + Set_NPhases(3); + Fnconds = 4; // defaults to wye + Yorder = 0; // To trigger an initial allocation + Set_NTerms(1); // forces allocations + kWBase = 1000.0; + kvarBase = 60.0; + kvarMax = kvarBase * 2.0; + kvarMin = -kvarMax; + PFNominal = 0.88; + // Rneut := 0.0; + // Xneut := 0.0; + YearlyShape = ""; + YearlyShapeObj = nullptr; // if YearlyShapeobj = nil then the load alway stays nominal * global multipliers + DailyDispShape = ""; + DailyDispShapeObj = nullptr; // if DaillyShapeobj = nil then the load alway stays nominal * global multipliers + DutyShape = ""; + DutyShapeObj = nullptr; // if DutyShapeobj = nil then the load alway stays nominal * global multipliers + DutyStart = 0.0; + Connection = 0; // Wye (star) + GenModel = 1; /*Typical fixed kW negative load*/ + GenClass = 1; + LastYear = 0; + LastGrowthFactor = 1.0; + DQDVSaved = 0.0; // Initialize this here. Allows generators to be turned off and on + GeneratorSolutionCount = -1; // For keep track of the present solution in Injcurrent calcs + OpenGeneratorSolutionCount = -1; + YPrimOpenCond = nullptr; + GenVars.kVGeneratorBase = 12.47; + Vpu = 1.0; + GenVars.VTarget = 1000.0 * Vpu * GenVars.kVGeneratorBase / SQRT3; /*Line-to-Neutral target*/ + VBase = 7200.0; + Vminpu = 0.90; + Vmaxpu = 1.10; + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + Yorder = Fnterms * Fnconds; + RandomMult = 1.0; + IsFixed = false; + /*Machine rating stuff*/ + GenVars.kVArating = kWBase * 1.2; + kVANotSet = true; // Flag for default value for kVA + + //GenVars.Vd := 7200.0; + /*# with GenVars do */ + { + auto& with0 = GenVars; + with0.puXd = 1.0; + with0.puXdp = 0.28; + with0.puXdpp = 0.20; + with0.XD = with0.puXd * Sqr(with0.kVGeneratorBase) * 1000.0 / with0.kVArating; + with0.Xdp = with0.puXdp * Sqr(with0.kVGeneratorBase) * 1000.0 / with0.kVArating; + with0.Xdpp = with0.puXdpp * Sqr(with0.kVGeneratorBase) * 1000.0 / with0.kVArating; + with0.Hmass = 1.0; // W-sec/VA rating + with0.Theta = 0.0; + with0.w0 = TwoPi * BaseFrequency; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + with0.D = 1.0; + with0.XRdp = 20.0; + with0.deltaQNomPtr = nullptr; + } + + /*Advertise Genvars struct as public*/ + PublicDataStruct = ((void*) &GenVars); + PublicDataSize = sizeof(TGeneratorVars); + UserModel = new TGenUserModel(&GenVars); + ShaftModel = new TGenUserModel(&GenVars); + DispatchValue = 0.0; // Follow curves + Reg_kWh = 1 - 1; + Reg_kvarh = 2 - 1; + Reg_MaxkW = 3 - 1; + Reg_MaxkVA = 4 - 1; + Reg_Hours = 5 - 1; + Reg_Price = 6 - 1; + PVFactor = 0.1; + DebugTrace = false; + FForcedON = false; + GenSwitchOpen = false; + ShapeIsActual = false; + ForceBalanced = false; + Spectrum = "defaultgen"; // override base class + UseFuel = false; + GenActive = true; + FuelkWh = 0.0; + pctFuel = 100.0; + pctReserve = 20.0; + InitPropertyValues(0); + RecalcElementData(ActiveActor); + // Assume no models are provided upon genrator initialization - this may change if models are provided + gen_model = nullptr; + exc_model = nullptr; + turb_model = nullptr; + NCIMIdx = 0; + + for (i = 0; i < NumGenRegisters; i++) + { + Registers[i] = 0.0; + Derivatives[i] = 0.0; + } +} + +//---------------------------------------------------------------------------- +TGeneratorObj::~TGeneratorObj() +{ + delete YPrimOpenCond; + delete UserModel; + delete ShaftModel; + // inherited::Destroy(); +} + +//---------------------------------------------------------------------------- +void TGeneratorObj::Randomize(int Opt) +{ + switch(Opt) + { + case 0: + RandomMult = 1.0; + break; + case GAUSSIAN: + RandomMult = Gauss(YearlyShapeObj->Get_Mean(), YearlyShapeObj->Get_StdDev()); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; // number between 0 and 1.0 + case LOGNORMAL: + RandomMult = QuasiLogNormal(YearlyShapeObj->Get_Mean()); + break; + default: + ; + break; + } +} + +//---------------------------------------------------------------------------- + +void TGeneratorObj::CalcDailyMult(double hr) +{ + if(DailyDispShapeObj != nullptr) + { + ShapeFactor = DailyDispShapeObj->GetMult(hr); + ShapeIsActual = DailyDispShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Default to no daily variation +} + + +//---------------------------------------------------------------------------- + +void TGeneratorObj::CalcDutyMult(double hr) +{ + if(DutyShapeObj != nullptr) + { + ShapeFactor = DutyShapeObj->GetMult(hr + DutyStart); + ShapeIsActual = DutyShapeObj->UseActual; + } + else + CalcDailyMult(hr); // Default to Daily Mult if no duty curve specified +} + +//---------------------------------------------------------------------------- + +void TGeneratorObj::CalcYearlyMult(double hr) +{ + +/*Yearly curve is assumed to be hourly only*/ + if(YearlyShapeObj != nullptr) + { + ShapeFactor = YearlyShapeObj->GetMult(hr); + ShapeIsActual = YearlyShapeObj->UseActual; + } + else + ShapeFactor = CDoubleOne; // Defaults to no variation +} + + + +//---------------------------------------------------------------------------- + +void TGeneratorObj::SetNominalGeneration(int ActorID) +{ + double Factor = 0.0; + bool GenOn_Saved = false; + GenOn_Saved = GenON; + ShapeFactor = CDoubleOne; + //Gets active loadshape object; if mode is carryover, the generators Pgen/Qgen will be carried over from what's in memory + auto loadshape = ActiveLoadShapeObj; + + auto with1 = ActiveCircuit[ActorID]->Solution; + double pinitial = kWBase; + double qinitial = kvarBase; + + switch (with1->DynaVars.SolutionMode) + { + case EMPDAILYMODE: + // Get plast from dynamic model at the end of dynamic simulation + auto gen = this->gen_model; + pinitial = gen->get_plast(); + qinitial = gen->get_qlast(); + break; + } + + + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) // Leave generator in whatever state it was prior to entering Dynamic mode + { + GenON = true; // Init to on then check if it should be off + if(!FForcedON) + switch(DispatchMode) + { + case LOADMODE: + if((DispatchValue > 0.0) && (ActiveCircuit[ActorID]->GeneratorDispatchReference < DispatchValue)) + GenON = false; + break; + case PRICEMODE: + if((DispatchValue > 0.0) && (ActiveCircuit[ActorID]->PriceSignal < DispatchValue)) + GenON = false; + break; + default: + ; + break; + } + } + if(!GenON) + // If Generator is OFF enter as tiny resistive load (.0001 pu) so we don't get divide by zero in matrix + { + GenVars.Pnominalperphase = -0.1 * kWBase / Fnphases; + // Pnominalperphase := 0.0; + GenVars.Qnominalperphase = 0.0; + } + else + // Generator is on, compute it's nominal watts and vars + { + /*# with Solution do */ + { + auto with2 = ActiveCircuit[ActorID]->Solution; + if(IsFixed) + { + Factor = 1.0; // for fixed generators, set constant + } + else + { + switch(with2->Get_SolMode()) + { + case SNAPSHOT: + Factor = ActiveCircuit[ActorID]->GenMultiplier * 1.0; + break; + case DAILYMODE: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; // Daily dispatch curve + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case EMPDAILYMODE: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; // Daily dispatch curve + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case YEARLYMODE: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; + CalcYearlyMult(with2->DynaVars.dblHour); + } + break; + case DUTYCYCLE: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; + CalcDutyMult(with2->DynaVars.dblHour); + } + break; // General sequential time simulation + case GENERALTIME: case DYNAMICMODE: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; + // This mode allows use of one class of load shape + switch(ActiveCircuit[ActorID]->ActiveLoadShapeClass) + { + case USEDAILY: + CalcDailyMult(with2->DynaVars.dblHour); + break; + case USEYEARLY: + CalcYearlyMult(with2->DynaVars.dblHour); + break; + case USEDUTY: + CalcDutyMult(with2->DynaVars.dblHour); + break; + default: // default to 1 + j1 if not known + ShapeFactor = CDoubleOne; + break; + } + } + break; + case MONTECARLO1: case MONTEFAULT: case FAULTSTUDY: + Factor = ActiveCircuit[ActorID]->GenMultiplier * 1.0; + break; + case MONTECARLO2: case MONTECARLO3: case LOADDURATION1: case LOADDURATION2: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case PEAKDAY: + { + Factor = ActiveCircuit[ActorID]->GenMultiplier; + CalcDailyMult(with2->DynaVars.dblHour); + } + break; + case AUTOADDFLAG: + Factor = 1.0; + break; + default: + Factor = 1.0; + break; + } + } + } + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + if(ShapeIsActual) + GenVars.Pnominalperphase = 1000.0 * ShapeFactor.re / Fnphases; + else + GenVars.Pnominalperphase = 1000.0 * pinitial * Factor * ShapeFactor.re / Fnphases; + + + /*# with GenVars do */ + { + auto& with3 = GenVars; + if(GenModel == 3) /* Just make sure present value is reasonable*/ + { + if(with3.Qnominalperphase > varMax) + with3.Qnominalperphase = varMax; + else + { + if(with3.Qnominalperphase < varMin) + with3.Qnominalperphase = varMin; + } + } + else + + /* for other generator models*/ + { + if(ShapeIsActual) + with3.Qnominalperphase = 1000.0 * ShapeFactor.im / Fnphases; + else + with3.Qnominalperphase = 1000.0 * qinitial * Factor * ShapeFactor.im / Fnphases; + } + } + } + } /*ELSE GenON*/ + if(!(with1->IsDynamicModel || with1->IsHarmonicModel)) //****** + { + switch(GenModel) + { + case 6: + Yeq = cinv(cmplx(0.0, -GenVars.XD)); + break; // Gets negated in CalcYPrim + default: + /*# with GenVars do */ + { + auto& with4 = GenVars; + Yeq = cdivreal(cmplx(with4.Pnominalperphase, -with4.Qnominalperphase), Sqr(VBase)); + } // Vbase must be L-N for 3-phase + if(Vminpu != 0.0) // at 95% voltage + Yeq95 = cdivreal(Yeq, Sqr(Vminpu)); + else + Yeq95 = Yeq; // Always a constant Z model + if(Vmaxpu != 0.0) // at 105% voltage + Yeq105 = cdivreal(Yeq, Sqr(Vmaxpu)); + else + Yeq105 = Yeq; + break; + } + + /* When we leave here, all the Yeq's are in L-N values*/ + if(GenModel == 7) + /*# with GenVars do */ + { + auto& with5 = GenVars; + PhaseCurrentLimit = cdivreal(cmplx(with5.Pnominalperphase, -with5.Qnominalperphase), VBase95); + Model7MaxPhaseCurr = cabs(PhaseCurrentLimit); + } + } + } /*With ActiveCircuit[ActiveActor]*/ + + // If generator state changes, force re-calc of Y matrix + if(GenON != GenOn_Saved) + Set_YprimInvalid(ActorID,true); +} + +//---------------------------------------------------------------------------- + +void TGeneratorObj::RecalcElementData(int ActorID) +{ + VBase95 = Vminpu * VBase; + VBase105 = Vmaxpu * VBase; + varBase = 1000.0 * kvarBase / Fnphases; + varMin = 1000.0 * kvarMin / Fnphases; + varMax = 1000.0 * kvarMax / Fnphases; + + /*Populate data structures used for interchange with user-written models.*/ + /*# with GenVars do */ + { + auto& with0 = GenVars; + with0.XD = with0.puXd * 1000.0 * Sqr(with0.kVGeneratorBase) / with0.kVArating; + with0.Xdp = with0.puXdp * 1000.0 * Sqr(with0.kVGeneratorBase) / with0.kVArating; + with0.Xdpp = with0.puXdpp * 1000.0 * Sqr(with0.kVGeneratorBase) / with0.kVArating; + with0.Conn = Connection; + with0.NumPhases = Fnphases; + with0.NumConductors = Fnconds; + } + SetNominalGeneration(ActorID); + + /*Now check for errors. If any of these came out nil and the string was not nil, give warning*/ + if(CompareText(YearlyShape, "none") == 0) + YearlyShape = ""; + if(CompareText(DailyDispShape, "none") == 0) + DailyDispShape = ""; + if(CompareText(DutyShape, "none") == 0) + DutyShape = ""; + if(YearlyShapeObj == nullptr) + { + if(YearlyShape.size() > 0) + DoSimpleMsg(String("WARNING! Yearly load shape: \"") + YearlyShape + + "\" Not Found.", 563); + } + if(DailyDispShapeObj == nullptr) + { + if(DailyDispShape.size() > 0) + DoSimpleMsg(String("WARNING! Daily load shape: \"") + DailyDispShape + + "\" Not Found.", 564); + } + if(DutyShapeObj == nullptr) + { + if(DutyShape.size() > 0) + DoSimpleMsg(String("WARNING! Duty load shape: \"") + DutyShape + + "\" Not Found.", 565); + } + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + DoSimpleMsg(String("ERROR! Spectrum \"") + Spectrum + "\" Not Found.", 566); + YQFixed = -varBase / Sqr(VBase); //10-17-02 Fixed negative sign + GenVars.VTarget = Vpu * 1000.0 * GenVars.kVGeneratorBase; + if(Fnphases > 1) + GenVars.VTarget = GenVars.VTarget / SQRT3; + + // Initialize to Zero - defaults to PQ generator + // Solution object will reset after circuit modifications + DQDV = DQDVSaved; // for Model = 3 + DeltaQMax = (varMax - varMin) * 0.10; // Limit to 10% of range + InjCurrent = (pComplexArray)realloc(InjCurrent, sizeof(complex) * Yorder); + + /*Update any user-written models*/ + if(UserModel->Get_Exists()) + UserModel->FUpdateModel(); + if(ShaftModel->Get_Exists()) + ShaftModel->FUpdateModel(); +} + +//---------------------------------------------------------------------------- + +void TGeneratorObj::CalcYPrimMatrix(TcMatrix* Ymatrix, int ActorID) +{ + complex Y = {}; + complex Yij = {}; + int i = 0; + int j = 0; + double FreqMultiplier = 0.0; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if (with0->IsDynamicModel || with0->IsHarmonicModel) + { + int stop = 0; + if (GenON) // L-N value computed in initialization routines + Y = Yeq; + else + Y = cmplx(EPSILON, 0.0); + if (Connection == 1) + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Y.im = Y.im / FreqMultiplier; + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + switch (Connection) + { + case 0: + { + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(Fnconds, Fnconds, Y); + Ymatrix->SetElemsym(i, Fnconds, Yij); + } + break; /*Delta connection*/ + case 1: + { + int stop1 = 0; + Ymatrix->SetElement(i, i, Y); + Ymatrix->AddElement(i, i, Y); // put it in again + for (stop1 = i - 1, j = 1; j <= stop1; j++) + { + Ymatrix->SetElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + /**** Removed Neutral / Neutral may float + + IF Connection = 0 Then With Ymatrix Do // Take care of neutral issues + Begin + AddElement(Fnconds, Fnconds, YNeut); // Add in user specified Neutral Z, if any + // Bump up neutral-ground in case neutral ends up floating + SetElement(Fnconds, Fnconds, CmulReal(GetElement(Fnconds, Fnconds), 1.000001)); + End; + + */ + } + else + // Regular power flow generator model + /*Yeq is always expected as the equivalent line-neutral admittance*/ + { + Y = cnegate(Yeq); // negate for generation Yeq is L-N quantity + + // if Type 3 generator, only put a little (1%) in Yprim + if (GenModel == 3) + Y = cdivreal(Y, 100.0); + + // ****** Need to modify the base admittance for real harmonics calcs + Y.im = Y.im / FreqMultiplier; + switch (Connection) + { + case 0: + /*# with Ymatrix do */ + { + auto with1 = Ymatrix; // WYE + int stop = 0; + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + with1->SetElement(i, i, Y); + with1->AddElement(Fnconds, Fnconds, Y); + with1->SetElemsym(i, Fnconds, Yij); + } + } + break; + case 1: + /*# with Ymatrix do */ + { + auto with2 = Ymatrix; // Delta or L-L + int stop = 0; + Y = cdivreal(Y, 3.0); // Convert to delta impedance + Yij = cnegate(Y); + for (stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; // wrap around for closed connections + with2->AddElement(i, i, Y); + with2->AddElement(j, j, Y); + with2->AddElemsym(i, j, Yij); + } + } + break; + default: + ; + break; + } + } + } /*ELSE IF Solution.mode*/ +} + + +//---------------------------------------------------------------------------- + +void TGeneratorObj::CalcYPrim(int ActorID) +{ + int i = 0; + + // Build only shunt Yprim + // Build a dummy Yprim Series so that CalcV does not fail + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Shunt->Clear(); + YPrim_Series->Clear(); + YPrim->Clear(); + } + if(ActiveCircuit[ActorID]->Solution->LoadModel == POWERFLOW) + // 12-7-99 we'll start with Yeq in system matrix + { + SetNominalGeneration(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + else + // ADMITTANCE model wanted + { + SetNominalGeneration(ActorID); + CalcYPrimMatrix(YPrim_Shunt, ActorID); + } + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages doesn't fail + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + YPrim->CopyFrom(YPrim_Shunt); + + // Account for Open Conductors + inherited::CalcYPrim(ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Overrides the standard procedure to match with NCIM solution algorithm +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +void TGeneratorObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = GenVars; + + if (with0->Algorithm == NCIMSOLVE) + { + for (int i = 0; i < Get_NPhases(); i++) + Curr[i] = Iterminal[i]; + } + else + inherited::GetCurrents(Curr, ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + /*Add the current into the proper location according to connection*/ + /*Reverse of similar routine in load (Cnegates are switched)*/ +void TGeneratorObj::StickCurrInTerminalArray(pComplexArray TermArray, const complex& Curr, int i) +{ + int j = 0; + switch(Connection) + { + case 0: //Wye + { + caccum(TermArray[i - 1], Curr); + caccum(TermArray[Fnconds - 1], cnegate(Curr)); // Neutral + } + break; //DELTA + case 1: + { + caccum(TermArray[i - 1], Curr); + j = i + 1; + if(j > Fnconds) + j = 1; + caccum(TermArray[j - 1], cnegate(Curr)); + } + break; + default: + ; + break; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::WriteTraceRecord(const String s, int ActorID) +{ + int i = 0; + try + { + if(!InShowResults) + { + int stop = 0; + Append(Tracefile); + IOResultToException(); + { Write(Tracefile, Format("%-.g, %d, %-.g, ", + ActiveCircuit[ActorID]->Solution->DynaVars.T + ActiveCircuit[ActorID]->Solution->DynaVars.intHour * 3600.0, + ActiveCircuit[ActorID]->Solution->Iteration, + ActiveCircuit[ActorID]->get_FLoadMultiplier())); + Write(Tracefile, GetSolutionModeID()); + Write(Tracefile, ", "); + Write(Tracefile, GetLoadModel()); + Write(Tracefile, ", "); + Write(Tracefile, GenModel, 0); + Write(Tracefile, ", "); + Write(Tracefile, DQDV, 8, 0); + Write(Tracefile, ", "); + Write(Tracefile, (V_Avg * 0.001732 / GenVars.kVGeneratorBase), 8, 3); + Write(Tracefile, ", "); + Write(Tracefile, (GenVars.VTarget - V_Avg), 9, 1); + Write(Tracefile, ", "); + Write(Tracefile, (GenVars.Qnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile, ", "); + Write(Tracefile, (GenVars.Pnominalperphase * 3.0 / 1.0e6), 8, 2); + Write(Tracefile, ", "); + Write(Tracefile, s); + Write(Tracefile, ", "); + } + + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((InjCurrent)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Iterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + for(stop = Get_NPhases(), i = 1; i <= stop; i++) + { + { Write(Tracefile, (cabs((Vterminal)[i - 1])), 8, 1); Write(Tracefile, ", "); } + } + { Write(Tracefile, GenVars.VthevMag, 8, 1); Write(Tracefile, ", "); Write(Tracefile, GenVars.Theta * 180.0 / DSSGlobals::PI); } + WriteLn(Tracefile); + CloseFile(Tracefile); + } + } + catch (...) + { + } +} + +bool TGeneratorObj::CheckOnFuel(double Deriv, double Interval, int ActorID) +{ + bool result = false; + result = true; + pctFuel = ((((pctFuel / 100) * FuelkWh) - Interval * Deriv) / FuelkWh) * 100.0L; + if(pctFuel <= pctReserve) + { + result = false; + pctFuel = pctReserve; +// GenON := False; + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for Constant PQ*/ + +void TGeneratorObj::DoConstantPQGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; +// V012,I012 :Array[0..2] of Complex; +// Iabc :Array[1..3] of Complex; + + //Treat this just like the Load model + int stop = 0; + + auto with0 = ActiveCircuit[ActorID]->Solution; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + ZeroITerminal(); + + /***** Tried this but couldn't get it to work + CASE Fnphases of + + 3:With Genvars Do Begin // Use Symmetrical Components + Phase2SymComp(Vterminal, @V012); // Vterminal is L-N voltages here + // Phase2SymComp(InjCurrent, @I012); // Vterminal is L-G voltages here + V := V012[1]; // Positive sequence L-N voltage + Vmag := Cabs(V012[1]); + + { IF VMag <= VBase95 + THEN Curr := Cnegate(Cmul(Yeq95, V)) // Below 95% (Vminpu) use an impedance model + ELSE If VMag > VBase105 + THEN Curr := Cnegate(Cmul(Yeq105, V)) // above 105% (Vmaxpu) use an impedance model + } + IF (VMag <= VBase95) or (VMag > VBase105) THEN Curr := Conjg( Cdiv( CurrentLimit, CDivReal(V, -Vmag)) ) + ELSE With Genvars Do Curr := Conjg(Cdiv(Cmplx(-Pnominalperphase, -Qnominalperphase), V)); // Current INTO pos seq model + + I012[1] := Curr; // Pos sequence current into the terminal + + If Connection=1 Then I012[0] := CZERO Else I012[0] := Cdiv(V012[0], cmplx(0.0, xdpp)); + I012[2] := Cdiv(V012[2], cmplx(0.0, xdpp)); + + // Negative and Zero Sequence Contributions + SymComp2Phase(@Iabc, @I012); // Iabc now desired terminal current + IF DebugTrace Then Begin + Append(TraceFile); + IOResultToException(); + Write(TraceFile,Format('V1=%-.5g, /_%-.5g, ',[Cabs(V), CDang(V)])); + Write(TraceFile,Format('I1=%-.5g, /_%-.5g, ',[Cabs(Curr), CDang(Curr)])); + Write(TraceFile,'Iabc='); + For i := 1 to 3 Do Write(TraceFile,Format('%-.5g, /_%-.5g, ',[ Cabs(Iabc[i]), CDang(Iabc[i])])); + Writeln(TraceFile); + CloseFile(TraceFile); + End; + + For i := 1 to 3 Do Begin + ITerminal^[i] := Iabc[i]; // Put into Terminal array directly because we have computed line current above + Caccum(InjCurrent^[i], Cnegate(Iabc[i])); // subtract in + If Connection=0 Then Begin + Caccum(Iterminal^[Fnconds], Cnegate(Iabc[i])); // Neutral + Caccum(InjCurrent^[Fnconds], Iabc[i]); // Neutral + End; + End; + IterminalUpdated := TRUE; // so that we con't have to recompute for a report + End + ELSE + ****/ + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: /*Wye*/ + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(Yeq95, V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(Yeq105, V); + else + /*# with GenVars do */ + { + auto& with0 = GenVars; + Curr = conjg(cdiv(cmplx(with0.Pnominalperphase, with0.Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; /*Delta*/ + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cdivreal(Yeq95, 3.0), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cdivreal(Yeq105, 3.0), V); + else + /*# with GenVars do */ + { + auto& with1 = GenVars; + Curr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), V)); + } // Between 95% -105%, constant PQ + } + } + break; + default: + ; + break; + } + // Checks the output in case of using Fuel + if(UseFuel) + { + if(!GenActive) + Curr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } + /*END;*/ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::DoConstantZGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex YEQ2 = {}; + +// Assume Yeq is kept up to date + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + if(Connection == 0) + YEQ2 = Yeq; + else + YEQ2 = cdivreal(Yeq, 3.0); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Curr = cmul(YEQ2, (Vterminal)[i - 1]); // Yeq is always line to neutral + // Checks the output in case of using Fuel + if(UseFuel) + { + if(!GenActive) + Curr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal current for Constant P,|V|*/ + +// Constant P, constant |V| + +void TGeneratorObj::DoPVTypeGen(int ActorID) +{ + int i = 0; + double DQ = 0.0; + complex Curr = {}; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the generator + ZeroITerminal(); + + // Guess at a new var output value + V_Avg = 0.0; + for(i = 0; i < Fnphases; i++) + { + V_Avg = V_Avg + cabs(Vterminal[i]); + } + if(Connection == 1) + V_Avg = V_Avg / (SQRT3 * Fnphases); + else + V_Avg = V_Avg / Fnphases; + + // 12-9-99 added empirical 0.7 factor to improve iteration + // 12-17-99 changed to 0.1 because first guess was consistently too high + DQ = PVFactor * DQDV * (GenVars.VTarget - V_Avg); // Vtarget is L-N + if(Abs(DQ) > DeltaQMax) + { + if(DQ < 0.0) + DQ = -DeltaQMax; + else + DQ = DeltaQMax; + } + /*# with GenVars do */ + { + auto& with0 = GenVars; + with0.Qnominalperphase = with0.Qnominalperphase + DQ; + } + + /* Test Limits*/ + /*# with GenVars do */ + { + auto& with1 = GenVars; + if(with1.Qnominalperphase > varMax) + with1.Qnominalperphase = varMax; + else + { + if(with1.Qnominalperphase < varMin) + with1.Qnominalperphase = varMin; + + // Compute injection currents using W and var values + // Do not use comstant Z models outside normal range + // Presumably the var source will take care of the voltage problems + } + for(i = 1; i <= Fnphases; i++) + { + Curr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), (Vterminal)[i - 1])); + + // Checks the output in case of using Fuel + if (UseFuel) + { + if (!GenActive) + Curr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } + } /*With*/ +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for Fixed Q*/ +// Constant P, Fixed Q Q is always kvarBase + +void TGeneratorObj::DoFixedQGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + Curr = conjg(cdiv(cmplx(GenVars.Pnominalperphase, varBase), V)); + } + } + break; + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re / 3.0, YQFixed / 3.0), V); + else + { + if(Vmag > VBase105) // above 105% use an impedance model + Curr = cmul(cmplx(Yeq105.re / 3.0, YQFixed / 3.0), V); + else + Curr = conjg(cdiv(cmplx(GenVars.Pnominalperphase, varBase), V)); + } + } + break; + default: + ; + break; + } + + // Checks the output in case of using Fuel + if(UseFuel) + { + if(!GenActive) + Curr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute total terminal current for */ +// Constant P, Fixed Q Q is always a fixed Z derived from kvarBase + +void TGeneratorObj::DoFixedQZGen(int ActorID) +{ + int i = 0; + complex Curr = {}; + complex V = {}; + double Vmag = 0.0; + int stop = 0; + auto with0 = ActiveCircuit[ActorID]->Solution; + + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V = (Vterminal)[i - 1]; + Vmag = cabs(V); + switch(Connection) + { + case 0: + { + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re, YQFixed), V); + else + { + if(Vmag > VBase105) + Curr = cmul(cmplx(Yeq105.re, YQFixed), V); + else + { + Curr = conjg(cdiv(cmplx(GenVars.Pnominalperphase, 0.0), V)); // P component of current + caccum(Curr, cmul(cmplx(0.0, YQFixed), V)); // add in Q component of current + } + } + } + break; + case 1: + { + switch(Fnphases) + { + case 2: + case 3: + Vmag = Vmag / SQRT3; + break; // L-N magnitude + + /*leave Vmag as is*/ + default: + ; + break; + } + if(Vmag <= VBase95) // Below 95% use an impedance model + Curr = cmul(cmplx(Yeq95.re / 3.0, YQFixed / 3.0), V); + else + { + if(Vmag > VBase105) + Curr = cmul(cmplx(Yeq105.re / 3.0, YQFixed / 3.0), V); + else + { + Curr = conjg(cdiv(cmplx(GenVars.Pnominalperphase, 0.0), V)); // P component of current + caccum(Curr, cmul(cmplx(0.0, YQFixed / 3.0), V)); // add in Q component of current + } + } + } + break; + default: + ; + break; + } + + // Checks the output in case of using Fuel + if(UseFuel) + { + if(!GenActive) + Curr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(Curr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, Curr, i); // Put into Terminal array taking into account connection + } /*FOR*/ +} +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal Current from User-written model*/ + +void TGeneratorObj::DoUserModel(int ActorID) +{ + int i = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + if(UserModel->Get_Exists()) // Check automatically selects the usermodel if true + + //AppendToEventLog('Wnominal=', Format('%-.5g',[Pnominalperphase])); + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); + set_ITerminalUpdated(true, ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; // Negate currents from user model for power flow generator model + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + } + } + else + { + DoSimpleMsg(String("Generator.") + get_Name() + + " model designated to use user-written model, but user-written model is not defined.", 567); + } +} + +//----------------------------------------------------------------------------------- + +bool TGeneratorObj::get_FForcedON() +{ + return FForcedON; +} + +//----------------------------------------------------------------------------------- + +void TGeneratorObj::set_FForcedON(bool Value) +{ + FForcedON = Value; +} + +//----------------------------------------------------------------------------------- + +double TGeneratorObj::get_PFNominal() +{ + return PFNominal; +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Compute total terminal current for Constant PQ, but limit to max current below + Vminpu*/ + +void TGeneratorObj::DoCurrentLimitedPQ(int ActorID) +{ + int i = 0; + complex PhaseCurr = {}; + complex DeltaCurr = {}; + complex VLN = {}; + complex VLL = {}; + double VmagLN = 0.0; + double VmagLL = 0.0; + complex V012[4] = {CZero, CZero, CZero, CZero}; // Sequence voltages + auto with0 = ActiveCircuit[ActorID]->Solution; + + //Treat this just like the Load model + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array + CalcVTerminalPhase(ActorID); // get actual voltage across each phase of the load + if(ForceBalanced && (Fnphases == 3)) // convert to pos-seq only + { + Phase2SymComp(&(Vterminal[0]), &V012[0]); + V012[0] = CZero; // Force zero-sequence voltage to zero + V012[2] = CZero; // Force negative-sequence voltage to zero + SymComp2Phase(&(Vterminal[0]), &V012[0]); // Reconstitute Vterminal as balanced + } + ZeroITerminal(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(Connection) + { + case 0: + { + VLN = (Vterminal)[i - 1]; // VTerminal is LN for this connection + VmagLN = cabs(VLN); + /*# with GenVars do */ + { + auto& with0 = GenVars; + PhaseCurr = conjg(cdiv(cmplx(with0.Pnominalperphase, with0.Qnominalperphase), VLN)); + } + if(cabs(PhaseCurr) > Model7MaxPhaseCurr) + PhaseCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLN, VmagLN))); + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(PhaseCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, PhaseCurr, i); // Put into Terminal array taking into account connection + } + break; + case 1: + { + VLL = (Vterminal)[i - 1]; // VTerminal is LL for this connection + VmagLL = cabs(VLL); + switch(Fnphases) + { + case 2: + case 3: // 2 or 3 phase generator model 7 + { + /*# with GenVars do */ + { + auto& with1 = GenVars; + DeltaCurr = conjg(cdiv(cmplx(with1.Pnominalperphase, with1.Qnominalperphase), VLL)); + } + if(cabs(DeltaCurr) * SQRT3 > Model7MaxPhaseCurr) + DeltaCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLL / SQRT3))); + } + break; // 1-phase generator model 7 + default: + /*# with GenVars do */ + { + auto& with2 = GenVars; + DeltaCurr = conjg(cdiv(cmplx(with2.Pnominalperphase, with2.Qnominalperphase), VLL)); + } + if(cabs(DeltaCurr) > Model7MaxPhaseCurr) + DeltaCurr = conjg(cdiv(PhaseCurrentLimit, cdivreal(VLL, VmagLL))); + break; + } + + // Checks the output in case of using Fuel + if(UseFuel) + { + if(!GenActive) + DeltaCurr = cmplx(0, 0); + } + StickCurrInTerminalArray(&(Iterminal[0]), cnegate(DeltaCurr), i); // Put into Terminal array taking into account connection + set_ITerminalUpdated(true, ActorID); + StickCurrInTerminalArray(InjCurrent, DeltaCurr, i); // Put into Terminal array taking into account connection + + } + break; + default: + ; + break; + } + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Total Current and add into InjTemp*/ + +void TGeneratorObj::DoDynamicMode(int ActorID) +{ + int i = 0, ret = 0; + complex V012[4] = { CZero, CZero, CZero, CZero }, + I012[4] = { CZero, CZero, CZero, CZero }; + complex isrc1 = CZero, + isrc2 = CZero; + complex *pI012 = &I012[0]; + + int stop = 0; + CalcYPrimContribution(InjCurrent, ActorID); // Init InjCurrent Array and computes VTerminal L-N + + /*Inj = -Itotal (in) - Yprim*Vtemp*/ + switch(GenModel) + { + case 6: + if(UserModel->Get_Exists()) // auto& selects model + /*We have total currents in Iterminal*/ + { + UserModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); // returns terminal currents in Iterminal + } + else + { + DoSimpleMsg("Dynamics model missing for Generator." + get_Name() + " ", 5671); + SolutionAbort = true; + } + break; + default: + switch(Fnphases) + { + case 1: + /*# with GenVars do */ + { + auto& with0 = GenVars; /*No user model, use default Thevinen equivalent for standard Generator model*/ + // 1-phase generators have 2 conductors + switch(GenModel) + { + case 7: // simple inverter model + // Assume inverter stays in phase with terminal voltage + { + CalcVthev_Dyn_Mod7(csub((Vterminal)[1 - 1], (Vterminal)[2 - 1])); + } + break; + default: + CalcVthev_Dyn(); // Update for latest phase angle + break; + } + (Iterminal)[1 - 1] = cdiv(csub(csub((Vterminal)[1 - 1], Vthev), (Vterminal)[2 - 1]), with0.Zthev); // ZThev is based on Xd' + if(GenModel == 7) + { + if(cabs((Iterminal)[1 - 1]) > Model7MaxPhaseCurr) // Limit the current but keep phase angle + (Iterminal)[1 - 1] = ptocomplex(topolar(Model7MaxPhaseCurr, cang((Iterminal)[1 - 1]))); + } + (Iterminal)[2 - 1] = cnegate((Iterminal)[1 - 1]); + } + break; + case 3: + /*# with GenVars do */ + { + auto& with1 = GenVars; + Phase2SymComp(&(Vterminal[0]), &V012[0]); + + auto withSol = ActiveCircuit[ActorID]->Solution; + + // If in EMP mode, then calculate current contributions from gen_model + if (withSol->DynaVars.SolutionMode && this->gen_model != nullptr) + { + // This will call Isorce from whatever generator model is being used with this generator + pI012 = this->gen_model->CalculateIsorce(ActorID, pI012); + I012[1] = pI012[1]; // not needed but left here for redundancy + I012[2] = pI012[2]; + + + } + else { + switch (GenModel) + { + case 7: // simple inverter model + // Positive Sequence Contribution to Iterminal + // Assume inverter stays in phase with pos seq voltage + // and pos seq current is limited + { + CalcVthev_Dyn_Mod7(V012[1]); + + // Positive Sequence Contribution to Iterminal + // Ref Frame here is all L-N + I012[1] = cdiv(csub(V012[1], Vthev), with1.Zthev); // ZThev is based on Xd' + if (cabs(I012[1]) > Model7MaxPhaseCurr) // Limit the current but keep phase angle + I012[1] = ptocomplex(topolar(Model7MaxPhaseCurr, cang(I012[1]))); + if (ForceBalanced) // set the negative sequence current + I012[2] = CZero; + else + I012[2] = cdiv(V012[2], with1.Zthev); // for inverter ZThev is (Xd' + j0) + } + break; + // Positive Sequence Contribution to Iterminal + default: + CalcVthev_Dyn(); // Update for latest phase angle + + // Positive Sequence Contribution to Iterminal + I012[1] = cdiv(csub(V012[1], Vthev), with1.Zthev); // ZThev is based on Xd' + I012[2] = cdiv(V012[2], cmplx(0.0, with1.Xdpp)); // machine use Xd" + break; + } + } + + /* Adjust for generator connection */ + if((Connection == 1) || ForceBalanced) + I012[0] = CZero; + else + I012[0] = cdiv(V012[0], cmplx(0.0, with1.Xdpp)); + SymComp2Phase(&(Iterminal[0]), &I012[0]); // Convert back to phase components and store currents in Iterminal array + + // Neutral current + if(Connection == 0) + (Iterminal)[Fnconds - 1] = cnegate(cmulreal(I012[0], 3.0)); + } + break; + default: + DoSimpleMsg(Format("Dynamics mode is implemented only for 1- or 3-phase Generators. Generator.%s has %d phases.", get_Name().c_str(), Fnphases), 5671); + SolutionAbort = true; + break; + } + break; + } + set_ITerminalUpdated(true, ActorID); + + /*Add it into inj current array*/ + for(stop = Fnconds, i = 1; i <= stop; i++) + { + caccum((InjCurrent)[i - 1], cnegate((Iterminal)[i - 1])); + } + + /*Take Care of any shaft model calcs*/ + if((GenModel == 6) && ShaftModel->Get_Exists()) // auto& selects model + // Compute Mech Power to shaft + { + ShaftModel->FCalc(&(Vterminal[0]), &(Iterminal[0])); // Returns pshaft at least + } +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Compute Injection Current Only when in harmonics mode*/ + +/*Assumes spectrum is a voltage source behind subtransient reactance and YPrim has been built*/ +/*Vd is the fundamental frequency voltage behind Xd" for phase 1*/ + +void TGeneratorObj::DoHarmonicMode(int ActorID) +{ + int i = 0; + complex e = {}; + double GenHarmonic = 0.0; + ComputeVterminal(ActorID); + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + GenHarmonic = with0->get_FFrequency() / GenFundamental; + e = cmulreal(SpectrumObj->GetMult(GenHarmonic), GenVars.VThevHarm); // Get base harmonic magnitude + RotatePhasorRad(e, GenHarmonic, GenVars.ThetaHarm); // Time shift by fundamental frequency phase shift + for(stop = Fnphases, i = 1; i <= stop; i++) + { + cBuffer[i - 1] = e; + if(i < Fnphases) + RotatePhasorDeg(e, GenHarmonic, -120.0); // Assume 3-phase generator + } + } + + /*Handle Wye Connection*/ + if(Connection == 0) + cBuffer[Fnconds - 1] = (Vterminal)[Fnconds - 1]; // assume no neutral injection voltage + + /*Inj currents = Yprim (E) */ + YPrim->MVmult(InjCurrent, (pComplexArray) &cBuffer); +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::CalcVTerminalPhase(int ActorID) +{ + int i = 0; + int j = 0; + +/* Establish phase voltages and stick in Vterminal*/ + + if (ActiveCircuit[ActorID]->Solution->Algorithm == NCIMSOLVE) + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for (stop = Fnphases, i = 1; i <= stop; i++) + { + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + } + } + else + { + switch (Connection) + { + case 0: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for (stop = Fnphases, i = 1; i <= stop; i++) + { + Vterminal[i - 1] = with0->VDiff(NodeRef[i - 1], NodeRef[Fnconds - 1], ActorID); + } + } + } + break; + case 1: + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for (stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; + (Vterminal)[i - 1] = with1->VDiff(NodeRef[i - 1], NodeRef[j - 1], ActorID); + } + } + } + break; + default: + ; + break; + } + } + + GeneratorSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +/*Put terminal voltages in an array*/ + +void TGeneratorObj::CalcVterminal(int ActorID) +{ + ComputeVterminal(ActorID); + GeneratorSolutionCount = ActiveCircuit[ActorID]->Solution->SolutionCount; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +// Calculates generator current and adds it properly into the injcurrent array +// routines may also compute ITerminal (ITerminalUpdated flag) + +void TGeneratorObj::CalcGenModelContribution(int ActorID) +{ + set_ITerminalUpdated(false, ActorID); + /*# with ActiveCircuit[ActorID], ActiveCircuit[ActorID].Solution do */ + { + + auto with1 = ActiveCircuit[ActorID]->Solution; + if(with1->IsDynamicModel) + DoDynamicMode(ActorID); + else + { + if(with1->IsHarmonicModel && (with1->get_FFrequency() != ActiveCircuit[ActorID]->Fundamental)) + DoHarmonicMode(ActorID); + else + + // compute currents and put into InjTemp array; + { + switch(GenModel) + { + case 1: + DoConstantPQGen(ActorID); + break; + case 2: + DoConstantZGen(ActorID); + break; + case 3: // Constant P, |V| + DoPVTypeGen(ActorID); + break; + case 4: + DoFixedQGen(ActorID); + break; + case 5: + DoFixedQZGen(ActorID); + break; + case 6: + DoUserModel(ActorID); + break; + case 7: + DoCurrentLimitedPQ(ActorID); + break; + break; + default: + DoConstantPQGen(ActorID); // for now, until we implement the other models. + break; + } + } /*ELSE*/ + } + } /*WITH*/ + + /*When this is done, ITerminal is up to date*/ +} + +void TGeneratorObj::InitPVBusJac(int ActorID) +{ + int GCoord = 0, + GCoordY = 0; + complex Temp = cmplx(1e-20, 0); + auto with0 = ActiveCircuit[ActorID]->Solution; + + // Adds space for the voltage and power regulation coefficients Z and X + for (int i = 1; i <= Get_NPhases(); i++) + { + GCoord = (ActiveCircuit[ActorID]->NumNodes * 2) + (NCIMIdx + i - 1); + GCoordY = NodeRef[i - 1] * 2 - 1; + for (int j = 0; j < 2; j++) + AddMatrixElement(with0->Jacobian, GCoord, GCoordY + j, &Temp); // Adds space for the voltage regulation coefficients (Z) + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - +// Difference between currents in YPrim and total current + +void TGeneratorObj::CalcInjCurrentArray(int ActorID) +{ + + + +// Now Get Injection Currents + if(GenSwitchOpen) + ZeroInjCurrent(); + else + CalcGenModelContribution(ActorID); + +/* We're not going to mess with this logic here -- too complicated: Use an open line in series + to look at open phase conditions. + + ELSE Begin + + // some terminals not closed use admittance model for injection + If OpenGeneratorSolutionCount <> ActiveCircuit[ActiveActor].Solution.SolutionCount Then Begin + + // Rebuild the Yprimopencond if a new solution because values may have changed. + + // only reallocate when necessary + If YPrimOpenCond=nil Then YPrimOpenCond := TcMatrix.CreateMatrix(Yorder) + ELSE YPrimOpenCond.Clear; + If YPrimOpenCond.Order <> Yorder Then Begin + YPrimOpenCond.Free; + YPrimOpenCond := TcMatrix.CreateMatrix(Yorder); + End; + CalcYPrimMatrix(YPrimOpenCond); + + {Now Account for the Open Conductors} + {For any conductor that is open, zero out row and column} + With YPrimOpenCond Do Begin + k := 0; + FOR i := 1 TO Fnterms Do Begin + FOR j := 1 TO Fnconds Do Begin + If Not Terminals^[i].Conductors^[j].Closed Then Begin + ZeroRow(j+k); + ZeroCol(j+k); + SetElement(j+k, j+k, Cmplx(1.0e-12,0.0)); // In case node gets isolated + End; + End; + k := k+Fnconds; + End; + End; + OpenGeneratorSolutionCount := ActiveCircuit[ActiveActor].Solution.SolutionCount; + + End; + + With ActiveCircuit[ActiveActor].Solution Do + FOR i := 1 TO Yorder Do Begin + Ref := NodeRef^[i]; + If Ref=0 Then Vterminal^[i] := cZero + ELSE Vterminal^[i] := V^[ref]; + End; + YPrimOpenCond.MVmult(InjTemp, Vterminal); + For i := 1 to Yorder Do InjTemp^[i] := Cnegate(InjTemp^[i]); + End; + */ +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Compute total Currents + +void TGeneratorObj::GetTerminalCurrents(pComplexArray Curr, int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(IterminalSolutionCount[ActorID] != ActiveCircuit[ActorID]->Solution->SolutionCount) // recalc the contribution + { + if(!GenSwitchOpen) + CalcGenModelContribution(ActorID); // Adds totals in Iterminal as a side effect + } + inherited::GetTerminalCurrents(Curr, ActorID); + } + if(DebugTrace) + WriteTraceRecord("TotalCurrent", ActorID); +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +int TGeneratorObj::InjCurrents(int ActorID) +{ + int result = 0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(with0->LoadsNeedUpdating) + SetNominalGeneration(ActorID); // Set the nominal kW, etc for the type of solution being done + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total terminal current + if(DebugTrace) + WriteTraceRecord("Injection", ActorID); + + // Add into System Injection Current Array + result = inherited::InjCurrents(ActorID); + } + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + + +// Gives the currents for the last solution performed + +// Do not call SetNominalLoad, as that may change the load values + +void TGeneratorObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + CalcInjCurrentArray(ActorID); // Difference between currents in YPrim and total current + try + + // Copy into buffer array + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = (InjCurrent)[i - 1]; + } + } + catch (std::exception &e) + { + DoErrorMsg(String("Generator Object: \"") + get_Name() + "\" in GetInjCurrents function.", (std::string) e.what(), "Current buffer not big enough.", 568); + } +} +//= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGeneratorObj::ResetRegisters() +{ + int i = 0; + int stop = 0; + for(stop = NumGenRegisters, i = 1; i <= stop; i++) + { + Registers[i - 1] = 0.0; + } + for(stop = NumGenRegisters, i = 1; i <= stop; i++) + { + Derivatives[i - 1] = 0.0; + } + FirstSampleAfterReset = true; // initialize for trapezoidal integration +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGeneratorObj::Integrate(int reg, double Deriv, double Interval, int ActorID) +{ + + if(ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*Trapezoidal Rule Integration*/ + { + if(!FirstSampleAfterReset) + Registers[reg] = Registers[reg] + 0.5 * Interval * (Deriv + Derivatives[reg]); + } + else + /*Plain Euler integration*/ + Registers[reg] = Registers[reg] + Interval * Deriv; + Derivatives[reg] = Deriv; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// Update Energy from metered zone + +void TGeneratorObj::TakeSample(int ActorID) +{ + complex s = {}; + double Smag = 0.0; + double HourValue = 0.0; + + +// Compute energy in Generator branch + if(Get_Enabled()) + { + if(GenON) + { + s = cmplx(Get_PresentkW(), Get_Presentkvar()); + Smag = cabs(s); + HourValue = 1.0; + } + else + { + s = CZero; + Smag = 0.0; + HourValue = 0.0; + } + if(GenON || ActiveCircuit[ActorID]->TrapezoidalIntegration) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + /*Make sure we always integrate for Trapezoidal case + Don't need to for Gen Off and normal integration*/ + if(ActiveCircuit[ActorID]->PositiveSequence) + { + s = cmulreal(s, 3.0); + Smag = 3.0 * Smag; + } + Integrate(Reg_kWh, s.re, with0->IntervalHrs, ActorID); // Accumulate the power + Integrate(Reg_kvarh, s.im, with0->IntervalHrs, ActorID); + SetDragHandRegister(Reg_MaxkW, Abs((int) s.re)); + SetDragHandRegister(Reg_MaxkVA, Smag); + Integrate(Reg_Hours, HourValue, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + Integrate(Reg_Price, s.re * ActiveCircuit[ActorID]->PriceSignal * 0.001, with0->IntervalHrs, ActorID); // Accumulate Hours in operation + FirstSampleAfterReset = false; + // If using fuel + if(UseFuel) + GenActive = CheckOnFuel(s.re, with0->IntervalHrs, ActorID); + } + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +double TGeneratorObj::Get_PresentkW() +{ + double result = 0.0; + result = GenVars.Pnominalperphase * 0.001 * Fnphases; + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +double TGeneratorObj::Get_PresentkV() +{ + double result = 0.0; + result = GenVars.kVGeneratorBase; + return result; +} + +double TGeneratorObj::Get_Presentkvar() +{ + double result = 0.0; + result = GenVars.Qnominalperphase * 0.001 * Fnphases; + return result; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::InitDQDVCalc() +{ + DQDV = 0.0; + GenVars.Qnominalperphase = 0.5 * (varMax + varMin); // avg of the limits +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +/*Bump up vars by 10% of range for next calc*/ + +void TGeneratorObj::BumpUpQ() +{ + /*# with GenVars do */ + { + auto& with0 = GenVars; + with0.Qnominalperphase = with0.Qnominalperphase + 0.1 * (varMax - varMin); + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::RememberQV(int ActorID) +{ + int i = 0; + int stop = 0; + var_Remembered = GenVars.Qnominalperphase; + CalcVterminal(ActorID); + V_Avg = 0.0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + V_Avg = V_Avg + cabs((Vterminal)[i - 1]); + } + V_Avg = V_Avg / Fnphases; + V_Remembered = V_Avg; +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::CalcDQDV(int ActorID) +{ + double VDiff = 0.0; + int i = 0; + int stop = 0; + complex cYii; + //CalcVterminal(ActorID); + //V_Avg = 0.0; + //for(stop = Fnphases, i = 1; i <= stop; i++) + //{ + // V_Avg = V_Avg + cabs((Vterminal)[i - 1]); + //} + //V_Avg = V_Avg / Fnphases; + //VDiff = V_Avg - V_Remembered; + //if(VDiff != 0.0) + // DQDV = (GenVars.Qnominalperphase - var_Remembered) / VDiff; + //else + // DQDV = 0.0; // Something strange has occured + // // this will force a de facto P,Q model + + i = NodeRef[0]; + GetMatrixElement(ActiveSolutionObj->hYsystem, i, i, &cYii); + DQDV = 2.0 * cabs(cYii) * VBase * Vpu; // Save in DQDV for now + DQDVSaved = DQDV; //Save for next time Allows generator to be enabled/disabled during simulation +} + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::ResetStartPoint() +{ + GenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; +} + + +// - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - + +void TGeneratorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int Idx = 0; + inherited::DumpProperties(f, Complete); + { Write(f, "!DQDV="); WriteLn(f, DQDV, 10, 2); } + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + Idx = (with0->PropertyIdxMap)[i - 1]; + switch(Idx) + { + case 34: case 36: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "=("); Write(f, Get_PropertyValue(Idx)); WriteLn(f, L')'); } + break; + case 44: // This one has no variable associated, not needed + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); WriteLn(f, "=False"); } + break; + case 46: // This one has no variable associated, not needed + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); WriteLn(f, "=[]"); } + break; + default: + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(Idx)); } + break; + } + } + } + WriteLn(f); +} + +void TGeneratorObj::InitHarmonics(int ActorID) +{ + complex e = {}; + complex Va = {}; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + GenFundamental = ActiveCircuit[ActorID]->Solution->get_FFrequency(); // Whatever the frequency is when we enter here. + /*# with GenVars do */ + { + auto& with0 = GenVars; + Yeq = cinv(cmplx(0.0, with0.Xdpp)); // used for current calcs Always L-N + + /*Compute reference Thevinen voltage from phase 1 current*/ + if(GenON) + { + ComputeIterminal(ActorID); // Get present value of current + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto& with1 = ActiveCircuit[ActorID]->Solution; + switch(Connection) + { + case 0: /*wye - neutral is explicit*/ + { + if(!ADiakoptics || (ActorID == 1)) + Va = csub(with1->NodeV[NodeRef[1 - 1]], with1->NodeV[NodeRef[Fnconds - 1]]); + else + Va = csub(with1->VoltInActor1(NodeRef[1 - 1]), with1->VoltInActor1(NodeRef[Fnconds - 1])); + } + break; /*delta -- assume neutral is at zero*/ + case 1: + { + if(!ADiakoptics || (ActorID == 1)) + Va = with1->NodeV[NodeRef[1 - 1]]; + else + Va = with1->VoltInActor1(NodeRef[1 - 1]); + } + break; + default: + ; + break; + } + } + e = csub(Va, cmul((Iterminal)[1 - 1], cmplx(0.0, with0.Xdpp))); + with0.VThevHarm = cabs(e); // establish base mag and angle + with0.ThetaHarm = cang(e); + } + else + { + with0.VThevHarm = 0.0; + with0.ThetaHarm = 0.0; + } + } +} + +void TGeneratorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,GetBus(1)); //'bus1'; + Set_PropertyValue(3,"12.47"); + Set_PropertyValue(4,"100"); + Set_PropertyValue(5,".80"); + Set_PropertyValue(6,"1"); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,""); + Set_PropertyValue(10,"Default"); + Set_PropertyValue(11,"0.0"); + Set_PropertyValue(12,"wye"); + Set_PropertyValue(13,"60"); + Set_PropertyValue(14,"0"); // 'rneut'; // if entered -, assume open + Set_PropertyValue(15,"0"); //'xneut'; + Set_PropertyValue(16,"variable"); //'status' fixed or variable + Set_PropertyValue(17,"1"); //'class' + Set_PropertyValue(18,"1.0"); + Set_PropertyValue(19,Str_Real(kvarMax, 3)); + Set_PropertyValue(20,Str_Real(kvarMin, 3)); + Set_PropertyValue(21,"0.1"); + Set_PropertyValue(22,"no"); + Set_PropertyValue(23,"0.90"); + Set_PropertyValue(24,"1.10"); + Set_PropertyValue(25,"No"); + Set_PropertyValue(26,Format("%-g", GenVars.kVArating)); + Set_PropertyValue(27,Format("%-g", GenVars.kVArating * 0.001)); + Set_PropertyValue(28,Format("%-g", GenVars.puXd)); + Set_PropertyValue(29,Format("%-g", GenVars.puXdp)); + Set_PropertyValue(30,Format("%-g", GenVars.puXdpp)); + Set_PropertyValue(31,Format("%-g", GenVars.Hmass)); + Set_PropertyValue(32,Format("%-g", GenVars.Dpu)); + Set_PropertyValue(33,""); + Set_PropertyValue(34,""); + Set_PropertyValue(35,""); + Set_PropertyValue(36,""); + Set_PropertyValue(37,"0"); + Set_PropertyValue(38,"No"); + Set_PropertyValue(39,"20"); + Set_PropertyValue(40,"No"); + Set_PropertyValue(41,"0.0"); + Set_PropertyValue(42,"100.0"); + Set_PropertyValue(43,"20.0"); + Set_PropertyValue(44,"No"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TGeneratorObj::InitStateVars(int ActorID) +{ + + /*VNeut,*/ + int i = 0; + complex V012[3] = { CZero, CZero, CZero }; + complex I012[3] = { CZero, CZero, CZero }; + complex Vabc[4] = { CZero, CZero, CZero, CZero }; + Set_YprimInvalid(ActorID,true); // Force rebuild of YPrims + /*# with GenVars do */ + { + auto& with0 = GenVars; + switch(GenModel) + { + case 7: + with0.Zthev = cmplx(with0.Xdp, 0.0); + break; // use Xd' as an equivalent R for the inverter + default: + with0.Zthev = cmplx(with0.Xdp / with0.XRdp, with0.Xdp); + break; + } + Yeq = cinv(with0.Zthev); + + /*Compute nominal Positive sequence voltage behind transient reactance*/ + if (GenON) + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with1 = ActiveCircuit[ActorID]->Solution; + ComputeIterminal(ActorID); + switch (Fnphases) + { + case 1: + { + if (!ADiakoptics || (ActorID == 1)) + Edp = csub(csub(with1->NodeV[NodeRef[1 - 1]], with1->NodeV[NodeRef[2 - 1]]), cmul((Iterminal)[1 - 1], with0.Zthev)); + else + Edp = csub(csub(with1->VoltInActor1(NodeRef[1 - 1]), with1->VoltInActor1(NodeRef[2 - 1])), cmul((Iterminal)[1 - 1], with0.Zthev)); + with0.VthevMag = cabs(Edp); + } + break; + // Calculate Edp based on Pos Seq only + case 3: + { + int stop = 0; + Phase2SymComp(&(Iterminal[0]), & (I012[0])); + // Voltage behind Xdp (transient reactance), volts + for (stop = Fnphases, i = 1; i <= stop; i++) + { + if (!ADiakoptics || (ActorID == 1)) + Vabc[i] = with1->NodeV[NodeRef[i - 1]]; + else + Vabc[i] = with1->VoltInActor1(NodeRef[i - 1]); + } // Wye Voltage + Phase2SymComp(& (Vabc[1]), & (V012[0])); + complex IXd = cmul(I012[1], with0.Zthev); + Edp = csub(V012[1], IXd); // Pos sequence + with0.VthevMag = cabs(Edp); + } + break; + default: + DoSimpleMsg(Format(("Dynamics mode is implemented only for 1- or 3-phase Generators. Generator." + with1->get_Name() + + " has %d phases.").c_str(), Fnphases), 5672); + SolutionAbort = true; + break; + } + if (!ASSIGNED(DynamicEqObj)) + { + + // Shaft variables + // Theta is angle on Vthev[1] relative to system reference + //Theta := Cang(Vthev^[1]); // Assume source at 0 + with0.Theta = cang(Edp); + if (GenModel == 7) + Model7LastAngle = with0.Theta; + with0.dTheta = 0.0; + with0.w0 = TwoPi * ActiveCircuit[ActorID]->Solution->get_FFrequency(); + // recalc Mmass and D in case the frequency has changed + /*# with GenVars do */ + { + auto& with2 = GenVars; + GenVars.Mmass = 2.0 * GenVars.Hmass * GenVars.kVArating * 1000.0 / (with2.w0); // M = W-sec + with2.D = with2.Dpu * with2.kVArating * 1000.0 / (with2.w0); + } + with0.Pshaft = -Get_Power(1, ActorID).re; // Initialize Pshaft to present power Output + with0.Speed = 0.0; // relative to synch speed + with0.dSpeed = 0.0; + + // Init User-written models + //Ncond:Integer; V, I:pComplexArray; const X,Pshaft,Theta,Speed,dt,time:Double + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with3 = ActiveCircuit[ActorID]->Solution; + if (GenModel == 6) + { + if (UserModel->Get_Exists()) + UserModel->FInit(&(Vterminal[0]), &(Iterminal[0])); + if (ShaftModel->Get_Exists()) + ShaftModel->FInit(&(Vterminal[0]), &(Iterminal[0])); + } + } + } + else + { + // Initializes the memory values for the dynamic equation + for (i = 0; i < DynamicEqVals.size(); i++) + DynamicEqVals[i][1] = 0.0; + int NumData = (DynamicEqPair.size() / 2) - 1; + for (i = 0; i <= NumData; i++) + { + if (DynamicEqObj->IsInitVal(DynamicEqPair[(i * 2) + 1])) + { + switch (DynamicEqPair[(i * 2) + 1]) + { + case 9: + DynamicEqVals[DynamicEqPair[i * 2]][0] = cang(Edp); + if (GenModel == 7) Model7LastAngle = DynamicEqVals[DynamicEqPair[i * 2]][0]; + break; + default: + DynamicEqVals[DynamicEqPair[i * 2]][0] = Get_PCEValue(1, DynamicEqPair[(i * 2) + 1], ActorID); + break; + } + } + } + } + } + else + { + Vthev = CZero; + with0.Theta = 0.0; + with0.dTheta = 0.0; + with0.w0 = 0; + with0.Speed = 0.0; + with0.dSpeed = 0.0; + } + } /*With*/ +} + +int TGeneratorObj::InitializeStates(int ActorID) +{ + // To initialize all states in a generator, we need to check for the existence of specific controls + /* + Each generator could have the following controls: + GENERATOR + --> Machine model + --> Excitation system model + --> Turbine governor model + --> Power system stabilizer (tbd) + --> Over excitation limiter (tbd) + --> Under excitation limiter (tbd) + + */ + generatorInitialized = false; + exciterInitialized = false; + turbineInitialized = false; + + String s = typeid(gen_model).name(); + + // Check for presence of machine model, if it exists, then initialize it + //gen_model = dynamic_cast(gen_model); + + /*void* pA = nullptr; + Gencls::TGenclsObj objB; + pA = dynamic_cast( & objB); + static_cast(pA)->InitializeStates();*/ + + if (!(gen_model == nullptr)) { + int ret = gen_model->InitializeStates(ActorID); + if (ret >= 0) + generatorInitialized = true; + } + + // Check for presence of exciter model and machine model, if they exist, then initialize them + if (!(exc_model == nullptr) && generatorInitialized) { + int ret = exc_model->CalculateRate(ActorID); + if (ret >= 0) + exciterInitialized = true; + } + // Check for presence of turbine/governor model + if (!(turb_model == nullptr) && generatorInitialized) { + int ret = turb_model->CalculateRate(ActorID); + if (ret >= 0) + turbineInitialized = true; + } + + return 0; +} + +void TGeneratorObj::CalculateRate(int ActorID) +{ + // This function will call the calculation of state derivatives in each model associated with this generator + /* + Each generator could have the following controls: + GENERATOR + --> Machine model + --> Excitation system model + --> Turbine governor model + --> Power system stabilizer (tbd) + --> Over excitation limiter (tbd) + --> Under excitation limiter (tbd) + + */ + + + String s = typeid(gen_model).name(); + + // Check for presence of machine model, if it exists, then initialize it + //gen_model = dynamic_cast(gen_model); + + /*void* pA = nullptr; + Gencls::TGenclsObj objB; + pA = dynamic_cast( & objB); + static_cast(pA)->InitializeStates();*/ + + if (!(gen_model == nullptr) && generatorInitialized) { + int ret = gen_model->CalculateRate(ActorID); + if (ret >= 0) + generatorInitialized = true; + } + + // Check for presence of exciter model and machine model, if they exist, then initialize them + if (!(exc_model == nullptr) && generatorInitialized) { + int ret = exc_model->CalculateRate(ActorID); + if (ret >= 0) + exciterInitialized = true; + } + // Check for presence of turbine/governor model + if (!(turb_model == nullptr) && generatorInitialized) { + int ret = turb_model->CalculateRate(ActorID); + if (ret >= 0) + turbineInitialized = true; + } +} + +void TGeneratorObj::StateIntegration(int ActorID) +{ + + // This function will call the calculation of integration of the states in each model associated with this generator + /* + Each generator could have the following controls: + GENERATOR + --> Machine model + --> Excitation system model + --> Turbine governor model + --> Power system stabilizer (tbd) + --> Over excitation limiter (tbd) + --> Under excitation limiter (tbd) + + */ + + // Integrate states associated with the synchronous machine model + if (!(gen_model == nullptr) && generatorInitialized) { + int ret = gen_model->StateIntegration(ActorID); + if (ret >= 0) + generatorInitialized = true; + } + + // Check for presence of exciter model and machine model, if they exist, then initialize them + if (!(exc_model == nullptr) && generatorInitialized) { + int ret = exc_model->StateIntegration(ActorID); + if (ret >= 0) + exciterInitialized = true; + } + // Check for presence of turbine/governor model + if (!(turb_model == nullptr) && generatorInitialized) { + int ret = turb_model->StateIntegration(ActorID); + if (ret >= 0) + turbineInitialized = true; + } + + +} + +void TGeneratorObj::StateIntegration_correction(int ActorID) +{ + + // This function will call the calculation of integration of the states in each model associated with this generator + /* + Each generator could have the following controls: + GENERATOR + --> Machine model + --> Excitation system model + --> Turbine governor model + --> Power system stabilizer (tbd) + --> Over excitation limiter (tbd) + --> Under excitation limiter (tbd) + + */ + + // Integrate states associated with the synchronous machine model + if (!(gen_model == nullptr) && generatorInitialized) { + int ret = gen_model->StateIntegration_correction(ActorID); + if (ret >= 0) + generatorInitialized = true; + } + + // Check for presence of exciter model and machine model, if they exist, then initialize them + if (!(exc_model == nullptr) && generatorInitialized) { + int ret = exc_model->StateIntegration_correction(ActorID); + if (ret >= 0) + exciterInitialized = true; + } + // Check for presence of turbine/governor model + if (!(turb_model == nullptr) && generatorInitialized) { + int ret = turb_model->StateIntegration_correction(ActorID); + if (ret >= 0) + turbineInitialized = true; + } + + +} + +bool TGeneratorObj::IsGenerator() +{ + return true; +} + +bool TGeneratorObj::CheckForGeneratorModel() +{ + if (gen_model == nullptr) { + // If pointer to generator model is null, then generator model was not provided, return false + DoErrorMsg( "CheckForGeneratorModel", + "Generator " + get_Name() + " does not have a dynamic model associated with it.", + "Missing dynamic model for this generator", 999); + return false; + } + else { + // If pointer to generator model is not null, then generator model was provided, return true + return true; + } +} + + + + +void TGeneratorObj::IntegrateStates(int ActorID) +{ + complex TracePower = {}; + // Compute Derivatives and then integrate + ComputeIterminal(ActorID); + +// Check for user-written exciter model. + //Function(V, I:pComplexArray; const Pshaft,Theta,Speed,dt,time:Double) + /*# with ActiveCircuit[ActorID].Solution, GenVars do */ + auto with0 = ActiveCircuit[ActorID]->Solution; + auto& with1 = GenVars; + { + if (!ASSIGNED(DynamicEqObj)) + { + /*# with DynaVars do */ + auto& with2 = with0->DynaVars; + { + if (with2.IterationFlag == 0) /*First iteration of new time step*/ + { + with1.ThetaHistory = with1.Theta + 0.5 * with2.h * with1.dTheta; + with1.SpeedHistory = with1.Speed + 0.5 * with2.h * with1.dSpeed; + } + } + + // Compute shaft dynamics + TracePower = TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases); + with1.dSpeed = (with1.Pshaft + TracePower.re - with1.D * with1.Speed) / with1.Mmass; + // dSpeed := (Torque + TerminalPowerIn(Vtemp,Itemp,FnPhases).re/Speed) / (Mmass); + with1.dTheta = with1.Speed; + + // Trapezoidal method + /*# with DynaVars do */ + { + with1.Speed = with1.SpeedHistory + 0.5 * with2.h * with1.dSpeed; + with1.Theta = with1.ThetaHistory + 0.5 * with2.h * with1.dTheta; + } + + // Write Dynamics Trace Record + if (DebugTrace) + { + Append(Tracefile); + IOResultToException(); + Write(Tracefile, Format("t=%-.5g ", with0->DynaVars.T)); + Write(Tracefile, Format(" Flag=%d ", with0->DynaVars.IterationFlag)); + Write(Tracefile, Format(" Speed=%-.5g ", with1.Speed)); + Write(Tracefile, Format(" dSpeed=%-.5g ", with1.dSpeed)); + Write(Tracefile, Format(" Pshaft=%-.5g ", with1.Pshaft)); + Write(Tracefile, Format(" P=%-.5g Q= %-.5g", TracePower.re, TracePower.im)); + Write(Tracefile, Format(" M=%-.5g ", with1.Mmass)); + WriteLn(Tracefile); + CloseFile(Tracefile); + } + if (GenModel == 6) + { + if (UserModel->Get_Exists()) + UserModel->Integrate(); + if (ShaftModel->Get_Exists()) + ShaftModel->Integrate(); + } + } + else + { + auto& with20 = with0->DynaVars; + if (with20.IterationFlag == 0) + { + with1.SpeedHistory = DynamicEqVals[DynOut[0]][0] + 0.5 * with20.h * DynamicEqVals[DynOut[0]][1]; // first speed + with1.ThetaHistory = DynamicEqVals[DynOut[1]][0] + 0.5 * with20.h * DynamicEqVals[DynOut[1]][1]; // then angle + } + // Check for initializations using calculated values (P, Q, VMag, VAng, IMag, IAng) + int NumData = (DynamicEqPair.size() / 2) - 1; + for (int i = 0; i <= NumData; i++) + { + if (!DynamicEqObj->IsInitVal(DynamicEqPair[(i * 2) + 1])) + { + switch (DynamicEqPair[(i * 2) + 1]) + { + case 0: + DynamicEqVals[DynamicEqPair[i * 2]][0] = -TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases).re; + break; + case 1: + DynamicEqVals[DynamicEqPair[i * 2]][0] = -TerminalPowerIn(&(Vterminal[0]), &(Iterminal[0]), Fnphases).im; + break; + default: + DynamicEqVals[DynamicEqPair[i * 2]][0] = Get_PCEValue(1,DynamicEqPair[(i * 2) + 1],ActorID); + break; + } + } + } + // solves the differential equation using the given values + DynamicEqObj->SolveEq(&DynamicEqVals); // This can be done since we are not resizing the vector + // Trapezoidal method - Places the calues in the same vars to keep the code consistent + with1.Speed = with1.SpeedHistory + 0.5 * with20.h * DynamicEqVals[DynOut[0]][1]; + with1.Theta = with1.ThetaHistory + 0.5 * with20.h * DynamicEqVals[DynOut[1]][1]; + + // saves the new integration values in memoryspace + DynamicEqVals[DynOut[0]][0] = with1.Speed; + DynamicEqVals[DynOut[1]][0] = with1.Theta; + } + } +} +/*Return variables one at a time*/ + +double TGeneratorObj::Get_Variable(int i) +{ + double result = 0.0; + int n = 0; + int k = 0; + n = 0; + result = -9999.99; // error return value + if(i < 1) + return result; // Someone goofed + /*# with GenVars do */ + { + auto& with0 = GenVars; + switch(i) + { + case 1: + result = (with0.w0 + with0.Speed) / TwoPi; + break; // Frequency, Hz + case 2: + result = (with0.Theta) * RadiansToDegrees; + break; // Report in Deg + case 3: + result = cabs(Vthev) / VBase; + break; // Report in pu + case 4: + result = with0.Pshaft; + break; + case 5: + result = with0.dSpeed * RadiansToDegrees; + break; // Report in Deg 57.29577951 + case 6: + result = with0.dTheta; + break; + default: + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + k = (i - NumGenVariables); + if(k <= n) + { + result = UserModel->FGetVariable(k); + return result; + } + } + + /*If we get here, must be in the Shaft Model if anywhere*/ + if(ShaftModel->Get_Exists()) + { + k = i - (NumGenVariables + n); + if(k > 0) + result = ShaftModel->FGetVariable(k); + } + break; + } + } + return result; +} + +void TGeneratorObj::Set_Variable(int i, double Value) +{ + int n = 0; + int k = 0; + n = 0; + if(i < 1) + return; // Someone goofed + /*# with GenVars do */ + { + auto& with0 = GenVars; + switch(i) + { + case 1: + with0.Speed = (Value - with0.w0) * TwoPi; + break; + case 2: + with0.Theta = Value / RadiansToDegrees; + break; // deg to rad + case 3: + ; + break;// meaningless to set Vd := Value * vbase; // pu to volts + case 4: + with0.Pshaft = Value; + break; + case 5: + with0.dSpeed = Value / RadiansToDegrees; + break; + case 6: + with0.dTheta = Value; + break; + default: + if(UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + k = (i - NumGenVariables); + if(k <= n) + { + UserModel->FSetVariable(k, Value); + return; + } + } + // If we get here, must be in the shaft model + if(ShaftModel->Get_Exists()) + { + k = (i - (NumGenVariables + n)); + if(k > 0) + ShaftModel->FSetVariable(k, Value); + } + break; + } + } +} + +void TGeneratorObj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int j = 0; + int k = 0; + int stop = 0; + int n = 0; + int64_t nchan = 0; + if (gen_model != nullptr) // If gen_model exists, then get its channels + { + nchan = gen_model->get_number_channels(); + for (i = 1; i < nchan+1; i++) { + (States)[i - 1] = gen_model->get_channel(i); + } + i = i - 1; + + if (exc_model != nullptr) // Add exciter model values if the model exists + { + + nchan = exc_model->get_number_channels(); + for (j=1; j < nchan + 1; j++) { + (States)[i + j - 1] = exc_model->get_channel(j); + } + j = j - 1; + } + + if (turb_model != nullptr) // Add exciter model values if the model exists + { + nchan = turb_model->get_number_channels(); + for (k = 1; k < nchan + 1; k++) { + (States)[i + j +k - 1] = turb_model->get_channel(k); + } + k = k - 1; + } + } + else + { + if (!ASSIGNED(DynamicEqObj)) + { + for (stop = NumGenVariables, i = 1; i <= stop; i++) + States[i - 1] = Get_Variable(i); + } + else + { + for (stop = ( DynamicEqObj->get_FNumVars() * DynamicEqVals[0].size() ), i = 1; i <= stop; i++) + States[i - 1] = DynamicEqObj->Get_DynamicEqVal(i - 1, &DynamicEqVals); + } + if (UserModel->Get_Exists()) + { + n = UserModel->FNumVars(); + UserModel->FGetAllVars((pDoubleArray) & (States)[NumGenVariables + 1 - 1]); + } + if (ShaftModel->Get_Exists()) + { + ShaftModel->FGetAllVars((pDoubleArray) & (States)[NumGenVariables + 1 + n - 1]); + } + } +} + +int TGeneratorObj::NumVariables() +{ + int result = 0; + result = NumGenVariables; // Number of standard generator variables + + // Check for gen_model, exc + if (gen_model != nullptr) { + result = this->gen_model->get_number_channels(); + if (exc_model != nullptr) { + result = result + exc_model->get_number_channels(); + } + if (turb_model != nullptr) { + result = result + turb_model->get_number_channels(); + } + } + + + // Check for additional values given the inclusion of a user or shaft model + if(UserModel->Get_Exists()) + result = result + UserModel->FNumVars(); + if(ShaftModel->Get_Exists()) + result = result + ShaftModel->FNumVars(); + return result; +} + +String TGeneratorObj::VariableName(int i) +{ + String result; + const int BuffSize = 255; + int n = 0; + int I2 = 0; + int ii = 0; + int jj = 0; + int kk = 0; + + AnsiChar Buff[256/*# range 0..BuffSize*/]; + PAnsiChar PName = nullptr; + n = 0; + int64_t nchan = 0; + if(i < 1) + return result; // Someone goofed + if (gen_model != nullptr) // If gen_model exists, then get its channels + { + ii = gen_model->get_number_channels(); + if (i<=ii){ + result = gen_model->get_channel_header(i); + } + else{ + if (exc_model != nullptr) // If exc_model exists, then get its channels + { + jj = exc_model->get_number_channels(); + } + if (turb_model != nullptr) // If turb_model exists, then get its channels + { + kk = turb_model->get_number_channels(); + } + // + if (i > ii && i <= (ii + jj)) { + result = exc_model->get_channel_header(i-ii); + } + else if (i > (ii + jj) && i <= (ii + jj + kk )) { + result = turb_model->get_channel_header(i - ii-jj); + } + else { + DoSimpleMsg("Error in the dynamic generator channel specification", -1); + } + } + } + else { + switch (i) + { + case 1: + result = "Frequency"; + break; + case 2: + result = "Theta (Deg)"; + break; + case 3: + result = "Vd"; + break; + case 4: + result = "PShaft"; + break; + case 5: + result = "dSpeed (Deg/sec)"; + break; + case 6: + result = "dTheta (Deg)"; + break; + default: + if (UserModel->Get_Exists()) // Checks for existence and Selects + { + PName = (PAnsiChar)&Buff; + n = UserModel->FNumVars(); + I2 = i - NumGenVariables; + if (I2 <= n) + // DLL functions require AnsiString (AnsiString) type + { + UserModel->FGetVarName(I2, PName, (unsigned int)BuffSize); + result = PName; + return result; + } + } + if (ShaftModel->Get_Exists()) + { + PName = (PAnsiChar)&Buff; + I2 = i - NumGenVariables - n; + if (I2 > 0) + UserModel->FGetVarName(I2, PName, (unsigned int)BuffSize); + result = PName; + } + break; + } + } + return result; +} + +String TGeneratorObj::GetPropertyValue(int Index) +{ + String result; + result = ""; + switch(Index) + { + case 3: + result = Format("%.6g", GenVars.kVGeneratorBase); + break; + case 4: + result = Format("%.6g", kWBase); + break; + case 5: + result = Format("%.6g", PFNominal); + break; + case 7: + result = YearlyShape; + break; + case 8: + result = DailyDispShape; + break; + case 9: + result = DutyShape; + break; + case 13: + result = Format("%.6g", kvarBase); + break; + case 19: + result = Format("%.6g", kvarMax); + break; + case 20: + result = Format("%.6g", kvarMin); + break; + case 26: + result = Format("%.6g", GenVars.kVArating); + break; + case 27: + result = Format("%.6g", GenVars.kVArating * 0.001); + break; + case 34: + case 36: + { + result = String("(") + inherited::GetPropertyValue(Index) + ")"; + } + break; + case 37: + result = Format("%.6g", DutyStart); + break; + case 38: + if(ForceBalanced) result = "Yes"; + else result = "No"; + break; + case 40: + if(UseFuel) result = "Yes"; + else result = "No"; + break; + case 41: + result = Format("%.6g", FuelkWh); + break; + case 42: + result = Format("%.6g", pctFuel); + break; + case 43: + result = Format("%.6g", pctReserve); + break; + case 44: + result = "No"; + break; + case 45: + result = DynamicEq; + break; + case 46: + result = GetDynOutputStr(); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TGeneratorObj::MakePosSequence(int ActorID) +{ + String s; + double V = 0.0; + s = "Phases=1 conn=wye"; + + // Make sure voltage is line-neutral + if((Fnphases > 1) || (Connection != 0)) + V = GenVars.kVGeneratorBase / SQRT3; + else + V = GenVars.kVGeneratorBase; + s = s + Format(" kV=%-.5g", V); + + // Divide the load by no. phases + if(Fnphases > 1) + { + s = s + Format(" kW=%-.5g PF=%-.5g", kWBase / Fnphases, PFNominal); + if(((PrpSequence)[19 - 1] != 0) || ((PrpSequence)[20 - 1] != 0)) + s = s + + Format(" maxkvar=%-.5g minkvar=%-.5g", kvarMax / Fnphases, kvarMin / Fnphases); + if((PrpSequence)[26 - 1] > 0) + s = s + Format(" kva=%-.5g ", GenVars.kVArating / Fnphases); + if((PrpSequence)[27 - 1] > 0) + s = s + Format(" MVA=%-.5g ", GenVars.kVArating / 1000.0 / Fnphases); + } + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + +void TGeneratorObj::Set_ConductorClosed(int Index, int ActorID, bool Value) +{ + inherited::Set_ConductorClosed(Index, ActorID, Value); + + // Just turn generator on or off; + if(Value) + GenSwitchOpen = false; + else + GenSwitchOpen = true; +} + +void TGeneratorObj::Set_PowerFactor(double Value) +{ + PFNominal = Value; + SyncUpPowerQuantities(); +} + +void TGeneratorObj::Set_PresentkV(double Value) +{ + /*# with GenVars do */ + { + auto& with0 = GenVars; + with0.kVGeneratorBase = Value; + switch(Fnphases) + { + case 2: + case 3: + VBase = with0.kVGeneratorBase * InvSQRT3x1000; + break; + default: + VBase = with0.kVGeneratorBase * 1000.0; + break; + } + } +} + +void TGeneratorObj::Set_Presentkvar(double Value) +{ + double kVA_Gen = 0.0; + kvarBase = Value; + GenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; // init to something reasonable + kVA_Gen = sqrt(Sqr(kWBase) + Sqr(kvarBase)); + if(kVA_Gen != 0.0) + PFNominal = kWBase / kVA_Gen; + else + PFNominal = 1.0; + if((kWBase * kvarBase) < 0.0) + PFNominal = -PFNominal; + kvarMax = 2.0 * kvarBase; + kvarMin = -kvarMax; +} + +void TGeneratorObj::Set_PresentkW(double Value) +{ + kWBase = Value; + SyncUpPowerQuantities(); +} + +void TGeneratorObj::SyncUpPowerQuantities() +{ + + + // keep kvar nominal up to date with kW and PF + if(PFNominal != 0.0) + { + kvarBase = kWBase * sqrt(1.0L / Sqr(PFNominal) - 1.0L); + GenVars.Pnominalperphase = 1000.0 * kWBase / Fnphases; + GenVars.Qnominalperphase = 1000.0 * kvarBase / Fnphases; + kvarMax = 2.0 * kvarBase; + kvarMin = -kvarMax; + if(PFNominal < 0.0) + kvarBase = -kvarBase; + if(kVANotSet) + GenVars.kVArating = kWBase * 1.2; + } +} + +void TGeneratorObj::SetDragHandRegister(int reg, double Value) +{ + if(Value > Registers[reg]) + Registers[reg] = Value; +} + +void TGeneratorObj::SetkWkvar(double PkW, double Qkvar) +{ + kWBase = PkW; + Set_Presentkvar(Qkvar); +} + +void TGeneratorObj::CalcVthev_Dyn() +{ + if(GenSwitchOpen) + GenVars.VthevMag = 0.0; + Vthev = pclx(GenVars.VthevMag, GenVars.Theta); +} +/*Adjust VThev to be in phase with V, if possible*/ +/* + If the voltage magnitude drops below 15% or so, the accuracy of determining the + phase angle gets flaky. This algorithm approximates the action of a PLL that will + hold the last phase angle until the voltage recovers. +*/ + +void TGeneratorObj::CalcVthev_Dyn_Mod7(const complex& V) +{ + double Model7angle = 0.0; + if(GenSwitchOpen) + GenVars.VthevMag = 0.0; + /* + For Phases=1, Vbase is voltage across the terminals. + Else it is LN voltage. + */ + if(cabs(V) > 0.2 * VBase) + Model7angle = cang(V); + else + Model7angle = Model7LastAngle; + Vthev = pclx(GenVars.VthevMag, Model7angle); + Model7LastAngle = Model7angle; +} + + +void Generator_initialization() +{ + CDoubleOne = cmplx(1.0, 1.0); +// TWOPI3 := twopi/3.0; +} + + +complex TGeneratorObj::GetVterminal(int ActorID) { + + int i = 0; + complex V012[3/*# range 0..2*/]; + complex I012[3/*# range 0..2*/]; + complex Vabc[4/*# range 1..3*/]; + complex vterm {0.0,0.0}; + + auto with1 = ActiveCircuit[ActorID]->Solution; + switch (Fnphases) + { + // This function will only work for 3phase generators + case 3: + { + for (i = 0; i <= Fnphases; i++) + { + if (!ADiakoptics || (ActorID == 1)) + Vabc[i] = with1->NodeV[NodeRef[i - 1]]; + else + Vabc[i] = with1->VoltInActor1(NodeRef[i - 1]); + } // Wye Voltage + // Convert abc to 012 + Phase2SymComp(& (Vabc[1]), & (V012[0])); + vterm.re = V012[1].re; + vterm.im = V012[1].im; + } + break; + + default: + DoSimpleMsg(Format(("Dynamics mode is implemented only for 3-phase Generators. Generator." + with1->get_Name() + + " has %d phases.").c_str(), Fnphases), 9005); + SolutionAbort = true; + break; + } + return vterm; +} + + class Generator_unit + { + public: + Generator_unit() + { + //AssertSystemInitialization(); + Generator_initialization(); + } + }; + Generator_unit _Generator_unit; + +} // namespace Generator + + + + diff --git a/OpenDSSC/PCElements/generator.h b/OpenDSSC/PCElements/generator.h new file mode 100644 index 0000000..76fea2d --- /dev/null +++ b/OpenDSSC/PCElements/generator.h @@ -0,0 +1,360 @@ +#ifndef GeneratorH +#define GeneratorH + +#include "System.h" +#include "Sysutils.h" + +#include "GeneratorVars.h" +#include "GenUserModel.h" +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "LoadShape.h" +#include "GrowthShape.h" +#include "Spectrum.h" +#include "Arraydef.h" +#include "Dynamics.h" +#include "d2c_structures.h" +#include "ControlElem.h" +#include "mathutil.h" + + + + +namespace Generator +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Change Log + + 11/30/99 Added new properties to support conventional load flow + Vset, Qmin, Qmax + 12/1/99 Split out ComputeYsc(ibus) + Added Code to estimate DQDV + 12/2/99 Fixed bug in CalcYPrimMatrix - same bug as was in Load + 12/6/99 revised 95% - 105% limits - same as Load + 1-8-00 made voltage limites variable just like the Load. Added vminpu + and vmaxpu properties and modified YEq95, etc. + 2-2-00 Trapezoidal integration option + 2-28-00 Corrected Errors in Take Sample function + 8-23-00 Added FixedQ models; Added Price register and related dispatchmode + 8-24-00 Fixed Pnominalperphase so that it is never 0.0 to avoid divide by zero error + 9-20-00 Added InitStateVars Function for Dynamics mode + 10-6-00 Fixed error in TakeSample for positive sequence model + 10-25-00 Added Spectrum and code for Harmonic mode analysis + 10-27-00 Deleted GetCurrents Override; + 3-7-01 Fixed bug related to setting kvar= (Index wrong) + 3-27-01 Added check to prevent divide by zero on calculation of PFNominal + 5-17-01 moved spectrum editing back to base class + 7-2-01 Corrected TakeSample to integrate only when GenON instead of S>0 + Also corrected kVA Max for Positive Seq only + 8-14-01 Added price signal integration, which had been omitted + Fixed TakeSample so it would integrate on Trapezoidal when not GenON + 1-17/02 Fixed sign error for Type 5 model. + 7/11/02 Added code to change Yprim when generator changes ON/OFF state + 7/30/02 Fixed problem with propertyvalues and maxkvar + 11/08/02 Added Dynamics model + 11/11/02 Add user-written exciter and Shaft Models + 3/6/03 Revised user-written dll interface. + added control terminal code for PCELement override. + 3-17-03 Revised user-written models and harmonic models + 5-11-09 Added properties to support kW, kvar, PV, and kV through COM + 8-28-13 Forced re-initializing solution if Model 3 generator added. + 7-??-18 Corrected Generator Model 7 1-phase Model +*/ +/* + The generator is essentially a negative load that can be dispatched. + + If the dispatch value (DispValue) is 0, the generator always follows the + appropriate dispatch curve, which are simply load curves. If DispValue>0 then + the generator only comes on when the global circuit load multiplier exceeds + DispValue. When the generator is on, it always follows the dispatch curve + appropriate for the type of solution being performed. + + If you want to model a generator that is fully on whenever it is dispatched on, + simply designate "Status=Fixed". The default is "Status=Variable" (i.e., it follows + a dispatch curve. You could also define a dispatch curve that is always 1.0. + + Generators have their own energy meters that record: + 1. Total kwh + 2. Total kvarh + 3. Max kW + 4. Max kVA + 5. Hours in operation + 6. Price * kwH + + Generator meters reset with the circuit energy meters and take a sample with + the circuit energy meters as well. The Energy meters also used trapezoidal integration + so that they are compatible with Load-Duration simulations. + + Generator models are: + 1. Constant P, Q (* dispatch curve, if appropriate). + 2. Constant Z (For simple solution) + 3. Constant P, |V| like a standard power flow + 4. Constant P, Fixed Q (vars) + 5. Constant P, Fixed Q (reactance) + 6. User model + 7. Approximate Inverter model + + Most of the time you will use #1 for planning studies. + +*/ + +// The Generator is assumed balanced over the no. of phases defined + +// If you do not specify load shapes defaults are: +// Yearly: Defaults to No variation (i.e. multiplier = 1.0 always) +// Daily: Defaults to No variation +// Dutycycle: Defaults to Daily shape +const int NumGenRegisters = 6; // Number of energy meter registers +const int NumGenVariables = 6; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGenerator : public PCClass::TPCClass +{ + friend class TGeneratorObj; +public: + typedef PCClass::TPCClass inherited; +//private: + void InterpretConnection(const String s); + void SetNcondsForConnection(); +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherGeneratorName); +public: + String RegisterNames[6/*# range 1..NumGenRegisters*/]; + TGenerator(); + virtual ~TGenerator(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); + void ResetRegistersAll(int ActorID); + void SampleAll(int ActorID); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TGeneratorObj : public PCElement::TPCElement +{ + friend class TGenerator; +public: + typedef PCElement::TPCElement inherited; +//private: +// Moved to GeneratorVars Zthev :Complex; + Ucomplex::complex Yeq; // at nominal + Ucomplex::complex Yeq95; // at 95% + Ucomplex::complex Yeq105; // at 105% + Ucomplex::complex Edp; + Ucomplex::complex PhaseCurrentLimit; + double Model7MaxPhaseCurr; + double Model7LastAngle; + bool DebugTrace; + double DeltaQMax; // Max allowable var change on Model=3 per iteration + int DispatchMode; + double DispatchValue; + double DQDV; + double DQDVSaved; + bool FForcedON; + bool FirstSampleAfterReset; + bool IsFixed; // if Fixed, always at base value + int GeneratorSolutionCount; + double GenFundamental; /*Thevinen equivalent voltage mag and angle reference for Harmonic model*/ + bool GenON; /*Indicates whether generator is currently on*/ + bool GenSwitchOpen; + bool kVANotSet; + double LastGrowthFactor; + int LastYear; // added for speedup so we don't have to search for growth factor a lot + int OpenGeneratorSolutionCount; + double PVFactor; // deceleration Factor for computing vars for PV generators + double RandomMult; + int Reg_Hours, + Reg_kvarh, + Reg_kWh, + Reg_MaxkVA, + Reg_MaxkW, + Reg_Price; + Ucomplex::complex ShapeFactor; +// moved to GeneratorVars Thetaharm :Double; {Thevinen equivalent voltage angle reference for Harmonic model} + System::TTextRec Tracefile; + GenUserModel::TGenUserModel* UserModel; + GenUserModel::TGenUserModel* ShaftModel; /*User-Written Models*/ + double V_Avg, + V_Remembered, + var_Remembered, + varBase, // Base vars per phase + varMax, + varMin, + VBase, // Base volts suitable for computing currents + VBase105, + VBase95; + Ucomplex::complex Vthev; /*Thevinen equivalent voltage (complex) for dynamic model*/ +// moved to GeneratorVars Vthevharm :Double; {Thevinen equivalent voltage mag reference for Harmonic model} +// moved to GeneratorVars VthevMag :Double; {Thevinen equivalent voltage for dynamic model} + Ucmatrix::TcMatrix* YPrimOpenCond; // To handle cases where one conductor of load is open ; We revert to admittance for inj currents + double YQFixed; // Fixed value of y for type 7 load + bool ShapeIsActual, + ForceBalanced; + void CalcDailyMult(double hr); + void CalcDutyMult(double hr); // now incorporates DutyStart offset + void CalcGenModelContribution(int ActorID); + void CalcInjCurrentArray(int ActorID); + void CalcVterminal(int ActorID); + void CalcVTerminalPhase(int ActorID); + void CalcVthev_Dyn(); // 3-phase Voltage behind transient reactance + void CalcVthev_Dyn_Mod7(const Ucomplex::complex& V); + void CalcYearlyMult(double hr); + void CalcYPrimMatrix(Ucmatrix::TcMatrix* Ymatrix, int ActorID); + void DoConstantPQGen(int ActorID); + void DoConstantZGen(int ActorID); + void DoCurrentLimitedPQ(int ActorID); + void DoPVBus(int ActorID); + void DoDynamicMode(int ActorID); + void DoFixedQGen(int ActorID); + void DoFixedQZGen(int ActorID); + void DoHarmonicMode(int ActorID); + void DoPVTypeGen(int ActorID); + void DoUserModel(int ActorID); + bool CheckOnFuel(double Deriv, double Interval, int ActorID); + void Integrate(int reg, double Deriv, double Interval, int ActorID); + void SetDragHandRegister(int reg, double Value); + void StickCurrInTerminalArray(Ucomplex::pComplexArray TermArray, const Ucomplex::complex& Curr, int i); + void WriteTraceRecord(const String s, int ActorID); + void SyncUpPowerQuantities(); + double Get_PresentkW(); + double Get_Presentkvar(); + double Get_PresentkV(); + void Set_PresentkV(double Value); + void Set_Presentkvar(double Value); + void Set_PresentkW(double Value); + void Set_PowerFactor(double Value); + void SetkWkvar(double PkW, double Qkvar); + // Variables associated with EMP mode + ControlElem::TControlElem* gen_model; + ControlElem::TControlElem* exc_model; + ControlElem::TControlElem* turb_model; +protected: + virtual void Set_ConductorClosed(int Index, int ActorID, bool Value); + virtual void GetTerminalCurrents(Ucomplex::pComplexArray Curr, int ActorID); +public: + int Connection; /*0 = line-neutral; 1=Delta*/ + String DailyDispShape; // Daily (24 HR) Generator shape + LoadShape::TLoadShapeObj* DailyDispShapeObj; // Daily Generator Shape for this load + String DutyShape; // Duty cycle load shape for changes typically less than one hour + LoadShape::TLoadShapeObj* DutyShapeObj; // Shape for this generator + double DutyStart; // starting time offset into the DutyShape [hrs] for this generator + int GenClass, + GenModel, // Variation with voltage + NCIMIdx; // Index for voltage regulation when solving with NCIM algorithm + GeneratorVars::TGeneratorVars GenVars; /*State Variables*/ + double kvarBase; + double kvarMax; + double kvarMin; + double kWBase; + double PFNominal; + double Vpu; // per unit Target voltage for generator with voltage control + double Vmaxpu; + double Vminpu; +// Fuel related variables + bool GenActive; + bool UseFuel; + double FuelkWh; + double pctFuel; + double pctReserve; + bool generatorInitialized; + bool exciterInitialized; + bool turbineInitialized; + + +// moved to GeneratorVars VTarget :Double; // Target voltage for generator with voltage control + String YearlyShape; // ='fixed' means no variation on all the time + LoadShape::TLoadShapeObj* YearlyShapeObj; // Shape for this Generator + double Registers[6/*# range 1..NumGenRegisters*/]; + double Derivatives[6/*# range 1..NumGenRegisters*/]; + TGeneratorObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TGeneratorObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); + virtual String VariableName(int i); + void SetNominalGeneration(int ActorID); + void Randomize(int Opt); // 0 = reset to 1.0; 1 = Gaussian around mean and std Dev ; // 2 = uniform + void ResetRegisters(); + void TakeSample(int ActorID); + + // Procedures for setting the DQDV used by the Solution Object + void InitDQDVCalc(); + void BumpUpQ(); + void RememberQV(int ActorID); + void CalcDQDV(int ActorID); + void ResetStartPoint(); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + virtual int InitializeStates(int ActorID); + virtual void CalculateRate(int ActorID); + virtual void StateIntegration(int ActorID); + virtual void StateIntegration_correction(int ActorID); + virtual bool IsGenerator(); + virtual bool CheckForGeneratorModel(); + + // Support for Harmonics Mode + virtual void InitHarmonics(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + + bool get_FForcedON(); + void set_FForcedON(bool Value); + double get_PFNominal(); + void GetCurrents(pComplexArray Curr, int ActorID); // overrides the standard procedure for model 8 + + //__declspec (property (get = Get_PresentkW, put = Set_PresentkW ) ) double PresentkW; + //__declspec (property (get = Get_Presentkvar, put = Set_Presentkvar ) ) double Presentkvar; + //__declspec (property (get = get_ForcedON, put = set_FForcedON ) ) bool ForcedON; + //__declspec (property (get = Get_PresentkV, put = Set_PresentkV ) ) double PresentkV; + //__declspec (property (get = get_PFNominal, put = Set_PowerFactor ) ) double Powerfactor; + TGeneratorObj(DSSClass::TDSSClass* ParClass); + TGeneratorObj(String ClassName); + TGeneratorObj(); + + // Functions for NCIM solution algorithm + void InitPVBusJac(int ActorID); + + // New auxiliary functions + complex GetVterminal(int ActorID); +}; +extern TGeneratorObj* ActiveGeneratorObj; +extern TGenerator* GeneratorClass; + + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + + +} // namespace Generator + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Generator; +#endif + +#endif // GeneratorH + + + + diff --git a/OpenDSSC/PCElements/vccs.cpp b/OpenDSSC/PCElements/vccs.cpp new file mode 100644 index 0000000..5013174 --- /dev/null +++ b/OpenDSSC/PCElements/vccs.cpp @@ -0,0 +1,1050 @@ + + +#pragma hdrstop + +#include "vccs.h" + +#include "Circuit.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "Solution.h" + +using namespace std; +using namespace Arraydef; +using namespace Circuit; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PCClass; +using namespace PCElement; +using namespace ParserDel; +using namespace Solution; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace Utilities; + +namespace VCCS +{ + +TVCCSObj::TVCCSObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TVCCSObj::TVCCSObj(String ClassName) : inherited(ClassName) {} +TVCCSObj::TVCCSObj() {} + + +TVCCSObj* ActiveVCCSObj = nullptr; +TVCCS* VCCSClass = nullptr; +int NumPropsThisClass = 0; +complex Alpha1 = {}; +complex Alpha2 = {}; + +// helper functions for ring buffer indexing, 1..len + +int MapIdx(int Idx, int Len) +{ + int result = 0; + while(Idx <= 0) + Idx = Idx + Len; + result = Idx % (Len + 1); + if(result == 0) + result = 1; + return result; +} + +int OffsetIdx(int Idx, int Offset, int Len) +{ + int result = 0; + result = MapIdx(Idx + Offset, Len); + return result; +} // Creates superstructure for all Line objects + +TVCCS::TVCCS() + : XY_CurveClass((TDSSClass*) GetDSSClassPtr("XYCurve")) +{ + ; + Class_Name = "VCCS"; + DSSClassType = VCCS_ELEMENT + PC_ELEMENT; // participates in dynamics + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + VCCSClass = this; +} + +TVCCS::~TVCCS() +{ + // inherited::Destroy(); +} + + +void TVCCS::DefineProperties() +{ + NumPropsThisClass = 13; + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "phases"; + PropertyName[3 - 1] = "prated"; + PropertyName[4 - 1] = "vrated"; + PropertyName[5 - 1] = "ppct"; + PropertyName[6 - 1] = "bp1"; + PropertyName[7 - 1] = "bp2"; + PropertyName[8 - 1] = "filter"; + PropertyName[9 - 1] = "fsample"; + PropertyName[10 - 1] = "rmsmode"; + PropertyName[11 - 1] = "imaxpu"; + PropertyName[12 - 1] = "vrmstau"; + PropertyName[13 - 1] = "irmstau"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of bus to which source is connected.") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3"; + PropertyHelp[2 - 1] = "Number of phases. Defaults to 1."; + PropertyHelp[3 - 1] = "Total rated power, in Watts."; + PropertyHelp[4 - 1] = "Rated line-to-line voltage, in Volts"; + PropertyHelp[5 - 1] = "Steady-state operating output, in percent of rated."; + PropertyHelp[6 - 1] = "XYCurve defining the input piece-wise linear block."; + PropertyHelp[7 - 1] = "XYCurve defining the output piece-wise linear block."; + PropertyHelp[8 - 1] = "XYCurve defining the digital filter coefficients (x numerator, y denominator)."; + PropertyHelp[9 - 1] = "Sample frequency [Hz} for the digital filter."; + PropertyHelp[10 - 1] = "True if only Hz is used to represent a phase-locked loop (PLL), ignoring the BP1, BP2 and time-domain transformations. Default is no."; + PropertyHelp[11 - 1] = "Maximum output current in per-unit of rated; defaults to 1.1"; + PropertyHelp[12 - 1] = "Time constant in sensing Vrms for the PLL; defaults to 0.0015"; + PropertyHelp[13 - 1] = "Time constant in producing Irms from the PLL; defaults to 0.0015"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + // Override help string + PropertyHelp[NumPropsThisClass + 1 - 1] = "Harmonic spectrum assumed for this source. Default is \"default\"."; +} + +int TVCCS::NewObject(const String ObjName) +{ + int result = 0; + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TVCCSObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +int TVCCS::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + // continue parsing with contents of Parser + ActiveVCCSObj = (TVCCSObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveVCCSObj); + result = 0; + /*# with ActiveVCCSObj do */ + { + auto with0 = ActiveVCCSObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 330); + break; + case 1: + with0->SetBus(1, Param); + break; + case 2: + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); // num phases + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + } + break; + case 3: + with0->Prated = Parser[ActorID]->MakeDouble_(); + break; + case 4: + with0->Vrated = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->Ppct = Parser[ActorID]->MakeDouble_(); + break; + case 6: + { + with0->Fbp1_name = Parser[ActorID]->MakeString_(); + if(with0->Fbp1_name.size() > 0) + { + with0->Fbp1 = ((TXYcurveObj*) XY_CurveClass->Find(with0->Fbp1_name)); + } + } + break; + case 7: + { + with0->Fbp2_name = Parser[ActorID]->MakeString_(); + if(with0->Fbp2_name.size() > 0) + { + with0->Fbp2 = ((TXYcurveObj*) XY_CurveClass->Find(with0->Fbp2_name)); + } + } + break; + case 8: + { + with0->Ffilter_name = Parser[ActorID]->MakeString_(); + if(with0->Ffilter_name.size() > 0) + { + with0->FFilter = ((TXYcurveObj*) XY_CurveClass->Find(with0->Ffilter_name)); + } + } + break; + case 9: + with0->FsampleFreq = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->FrmsMode = InterpretYesNo(Param); + break; + case 11: + with0->FmaxIpu = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FvrmsTau = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->FirmsTau = Parser[ActorID]->MakeDouble_(); + break; + default: + inherited::ClassEdit(ActiveVCCSObj, ParamPointer - NumPropsThisClass); + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + with0->Set_YprimInvalid(ActorID,true); + } + return result; +} + +//---------------------------------------------------------------------------- + +int TVCCS::MakeLike(const String OtherSource) +{ + int result = 0; + TVCCSObj* OtherVCCS = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherVCCS = ((TVCCSObj*) Find(OtherSource)); + if(OtherVCCS != nullptr) + /*# with ActiveVCCSObj do */ + { + auto with0 = ActiveVCCSObj; + int stop = 0; + if(with0->Fnphases != OtherVCCS->Fnphases) + { + with0->Set_NPhases(OtherVCCS->Fnphases); + with0->Set_Nconds(with0->Fnphases); // Forces reallocation of terminal stuff + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->Prated = OtherVCCS->Prated; + with0->Vrated = OtherVCCS->Vrated; + with0->Ppct = OtherVCCS->Ppct; + with0->Fbp1 = OtherVCCS->Fbp1; + with0->Fbp2 = OtherVCCS->Fbp2; + with0->FFilter = OtherVCCS->FFilter; + with0->Fbp1_name = OtherVCCS->Fbp1_name; + with0->Fbp2_name = OtherVCCS->Fbp2_name; + with0->Ffilter_name = OtherVCCS->Ffilter_name; + with0->FsampleFreq = OtherVCCS->FsampleFreq; + with0->FrmsMode = OtherVCCS->FrmsMode; + with0->FmaxIpu = OtherVCCS->FmaxIpu; + with0->FvrmsTau = OtherVCCS->FvrmsTau; + with0->FirmsTau = OtherVCCS->FirmsTau; + ClassMakeLike(OtherVCCS); // set spectrum, base frequency + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherVCCS->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in VCCS MakeLike: \"") + OtherSource + "\" Not Found.", 332); + return result; +} + +int TVCCS::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TVCCS.Init", -1); + result = 0; + return result; +} + +TVCCSObj::TVCCSObj(TDSSClass* ParClass, const String SourceName) + : inherited(ParClass), + Fbp1(nullptr), + Fbp2(nullptr), + FFilter(nullptr), + BaseCurr(0.0), + BaseVolt(0.0), + FsampleFreq(0.0), + Fwinlen(0), + Ffiltlen(0), + Irated(0.0), + Fkv(0.0), + Fki(0.0), + FrmsMode(false), + FmaxIpu(0.0), + FvrmsTau(0.0), + FirmsTau(0.0), + S1(0.0), + S2(0.0), + S3(0.0), + S4(0.0), + S5(0.0), + S6(0.0), + Y2(nullptr), + Z(nullptr), + whist(nullptr), + zlast(nullptr), + wlast(nullptr), + sIdxU(0), + sIdxY(0), + y2sum(0.0), + Ppct(0.0), + Prated(0.0), + Vrated(0.0) +{ + Set_Name(LowerCase(SourceName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(1); + Fnconds = 1; + Set_NTerms(1); + Prated = 250.0; + Vrated = 208.0; + Ppct = 100.0; + FsampleFreq = 5000.0; + Fkv = 1.0; + Fki = 1.0; + FrmsMode = false; + FmaxIpu = 1.1; + FvrmsTau = 0.0015; + FirmsTau = 0.0015; + Fwinlen = 0; + Ffilter_name = ""; + Fbp1_name = ""; + Fbp2_name = ""; + Y2 = nullptr; + Z = nullptr; + whist = nullptr; + zlast = nullptr; + wlast = nullptr; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + +TVCCSObj::~TVCCSObj() +{ + free(Y2); + free(Z); + free(whist); + free(wlast); + free(zlast); + // inherited::Destroy(); +} + + +void TVCCSObj::RecalcElementData(int ActorID) +{ + SpectrumObj = ((TSpectrumObj*) SpectrumClass[ActorID]->Find(Spectrum)); + if(SpectrumObj == nullptr) + { + DoSimpleMsg(String("Spectrum Object \"") + Spectrum + + "\" for Device VCCS." + + get_Name() + + " Not Found.", 333); + } + InjCurrent = (pComplexArray) realloc(InjCurrent, sizeof(complex) * Yorder); + Irated = Prated / Vrated / Fnphases; + BaseVolt = Vrated; + if(Fnphases == 3) + { + Irated = Irated * sqrt(3.0L); + BaseVolt = BaseVolt / sqrt(3.0L); + } + BaseCurr = 0.01 * Ppct * Irated; + Fkv = 1.0 / BaseVolt / sqrt(2.0L); + Fki = BaseCurr * sqrt(2.0L); + if(Ffilter_name.size() > 0) + { + Ffiltlen = FFilter->get_FNumPoints(); + Fwinlen = Trunc(FsampleFreq / BaseFrequency); + Y2 = (pDoubleArray) realloc(Y2, sizeof(double) * Fwinlen); + Z = (pDoubleArray)realloc(Z, sizeof(double) * Ffiltlen); + whist = (pDoubleArray)realloc(whist, sizeof(double) * Ffiltlen); + wlast = (pDoubleArray)realloc(wlast, sizeof(double) * Ffiltlen); + zlast = (pDoubleArray)realloc(zlast, sizeof(double) * Ffiltlen); + } +} + +void TVCCSObj::CalcYPrim(int ActorID) +{ + + // Build only YPrim Series + if(Get_YprimInvalid(ActorID,0)) + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); + YPrim->Clear(); + } + /*Yprim = 0 for Ideal Current Source; just leave it zeroed*/ + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} +/*Sum Currents directly into solution array*/ + +int TVCCSObj::InjCurrents(int ActorID) +{ + int result = 0; + GetInjCurrents(InjCurrent, ActorID); + result = inherited::InjCurrents(ActorID); // Adds into system array + return result; +} +/*Total currents into a device*/ + +void TVCCSObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + try + { + int stop = 0; + GetInjCurrents(&(ComplexBuffer[0]), ActorID); // Get present value of inj currents + // Add Together with yprim currents + for(stop = Yorder, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = cnegate((ComplexBuffer)[i - 1]); + } + } + catch (std::exception &e) + { + DoErrorMsg((String("GetCurrents for VCCS Element: ") + get_Name() + "."), (std::string) e.what(), "Inadequate storage allotted for circuit element?", 335); + } +} + +void TVCCSObj::UpdateSequenceVoltage() +{ + if(Fnphases == 3) + sV1 = cdivreal(cadd((Vterminal)[1 - 1], cadd(cmul(Alpha1, (Vterminal)[2 - 1]), cmul(Alpha2, (Vterminal)[3 - 1]))), 3.0); + else + sV1 = (Vterminal)[1 - 1]; +} + +void TVCCSObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + complex I1 = {}; + if(!Get_ConductorClosed(1, ActorID)) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } + return; + } + ComputeVterminal(ActorID); + UpdateSequenceVoltage(); +// IterminalUpdated := FALSE; + if(ActiveSolutionObj->IsDynamicModel) + { + if(FrmsMode) + { + I1 = pdegtocomplex(S4 * BaseCurr, cdang(sV1)); + switch(Fnphases) + { + case 1: + (Curr)[1 - 1] = I1; + break; + case 3: + { + (Curr)[1 - 1] = I1; + (Curr)[2 - 1] = cmul(I1, Alpha2); + (Curr)[3 - 1] = cmul(I1, Alpha1); + } + break; + default: + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = pdegtocomplex(S4 * BaseCurr, cdang((Vterminal)[i - 1])); + } + break; + } + } + else + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = pdegtocomplex(S3 * BaseCurr, cdang((Vterminal)[i - 1])); + } + } + } + else + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = pdegtocomplex(BaseCurr, cdang((Vterminal)[i - 1])); + } + } +} + +void TVCCSObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + WriteLn(f); + WriteLn(f); + } +} + +void TVCCSObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,"1"); + Set_PropertyValue(3,"250"); + Set_PropertyValue(4,"208"); + Set_PropertyValue(5,"100"); + Set_PropertyValue(6,"NONE"); + Set_PropertyValue(7,"NONE"); + Set_PropertyValue(8,"NONE"); + Set_PropertyValue(9,"5000"); + Set_PropertyValue(10,"no"); + Set_PropertyValue(11,"1.1"); + Set_PropertyValue(12,"0.0015"); + Set_PropertyValue(13,"0.0015"); + inherited::InitPropertyValues(NumPropsThisClass); +} + +void TVCCSObj::MakePosSequence(int ActorID) +{ + if(Fnphases > 1) + { + Parser[ActorID]->SetCmdString("phases=1"); + Edit(ActorID); + } + TDSSCktElement::MakePosSequence(ActorID); +} + +// support for DYNAMICMODE +// NB: in phasor mode, use load convention for OpenDSS + // stop injecting if the terminal opens + +void TVCCSObj::ShutoffInjections() +{ + int i = 0; + int stop = 0; + for(stop = Ffiltlen, i = 1; i <= stop; i++) + { + (whist)[i - 1] = 0.0; + (wlast)[i - 1] = 0.0; + (Z)[i - 1] = 0.0; + (zlast)[i - 1] = 0.0; + } + for(stop = Fwinlen, i = 1; i <= stop; i++) + { + (Y2)[i - 1] = 0.0; + } + S1 = 0; + S2 = 0; + S3 = 0; + S4 = 0; + S5 = 0; + S6 = 0; +} + +void TVCCSObj::InitPhasorStates(int ActorID) +{ + int i = 0; + int k = 0; + int stop = 0; + inherited::ComputeIterminal(ActorID); + S1 = cabs((Vterminal)[1 - 1]) / BaseVolt; + S4 = cabs((Iterminal)[1 - 1]) / BaseCurr; + S2 = S4; + S3 = S4; + S5 = 0; + S6 = 0; + sV1 = cmplx(1.0, 0.0); + vlast = cdivreal((Vterminal)[1 - 1], BaseVolt); + + // initialize the history terms for HW model source convention + for(stop = Ffiltlen, i = 1; i <= stop; i++) + { + (whist)[i - 1] = S1; + (wlast)[i - 1] = S1; + } + for(stop = Fwinlen, i = 1; i <= stop; i++) + { + k = i - Fwinlen + Ffiltlen; + if(k > 0) + { + (Z)[k - 1] = S4; // HW history with load convention + (zlast)[k - 1] = (Z)[k - 1]; + } + } + // initialize the ring buffer indices; these increment by 1 before actual use + sIdxU = 0; + sIdxY = 0; +} + +// support for DYNAMICMODE +// NB: The test data and HW model used source convention (I and V in phase) +// However, OpenDSS uses the load convention + +void TVCCSObj::InitStateVars(int ActorID) +{ + double D = 0.0; + double wt = 0.0; + double wd = 0.0; + double Val = 0.0; + double iang = 0.0; + double vang = 0.0; + int i = 0; + int k = 0; + // initialize outputs from the terminal conditions + int stop = 0; + if(FrmsMode) + { + InitPhasorStates(ActorID); + return; + } + inherited::ComputeIterminal(ActorID); + iang = cang((Iterminal)[1 - 1]); + vang = cang((Vterminal)[1 - 1]); + S1 = cabs((Vterminal)[1 - 1]) / BaseVolt; + S3 = cabs((Iterminal)[1 - 1]) / BaseCurr; + S2 = S3; + S4 = S3; + S5 = 0; + S6 = 0; + sV1 = cmplx(1.0, 0.0); + vlast = cdivreal((Vterminal)[1 - 1], BaseVolt); + + // initialize the history terms for HW model source convention + D = double(1) / FsampleFreq; + wd = 2 * DSSGlobals::PI * ActiveSolutionObj->get_FFrequency() * D; + for(stop = Ffiltlen, i = 1; i <= stop; i++) + { + wt = vang - wd * (Ffiltlen - i); + (whist)[i - 1] = 0; + (whist)[i - 1] = Fbp1->GetYValue_(S1 * cos(wt)); + (wlast)[i - 1] = (whist)[i - 1]; + } + for(stop = Fwinlen, i = 1; i <= stop; i++) + { + wt = iang - wd * (Fwinlen - i); + Val = S3 * cos(wt); // current by passive sign convention + (Y2)[i - 1] = Val * Val; + k = i - Fwinlen + Ffiltlen; + if(k > 0) + { + (Z)[k - 1] = -Fbp2->GetXValue(Val); // HW history with generator convention + (zlast)[k - 1] = (Z)[k - 1]; + } + } + + // initialize the ring buffer indices; these increment by 1 before actual use + sIdxU = 0; + sIdxY = 0; +} + +void TVCCSObj::IntegratePhasorStates(int ActorID) +{ + double Vpu = 0.0; + double ipwr = 0.0; + double IMax = 0.0; + double h = 0.0; + double D = 0.0; + int iu = 0; + int i = 0; + int k = 0; + int nstep = 0; + int corrector = 0; + inherited::ComputeIterminal(ActorID); + UpdateSequenceVoltage(); + Vpu = cabs(sV1) / BaseVolt; + if(Vpu > 0.0) + { + int stop = 0; + h = ActiveSolutionObj->DynaVars.h; + corrector = ActiveSolutionObj->DynaVars.IterationFlag; + nstep = Trunc(1E-6 + h * FsampleFreq); + // Vrms from LPF + D = Vpu - S1; + S1 = S1 + D * (1.0 - exp(-h / FvrmsTau)); + // rms current to maintain power + ipwr = BaseCurr / S1; + IMax = FmaxIpu * Irated; + if(ipwr > IMax) + ipwr = IMax; + S2 = ipwr / BaseCurr; + // Hout +// s3 := s2; + iu = sIdxU; + for(stop = Ffiltlen, k = 1; k <= stop; k++) + { + (Z)[k - 1] = (zlast)[k - 1]; + (whist)[k - 1] = (wlast)[k - 1]; + } + for(stop = nstep, i = 1; i <= stop; i++) + { + int stop1 = 0; + iu = OffsetIdx(iu, 1, Ffiltlen); + (whist)[iu - 1] = S2; + // apply the filter and second PWL block + (Z)[iu - 1] = 0; + for(stop1 = Ffiltlen, k = 1; k <= stop1; k++) + { + (Z)[iu - 1] = (Z)[iu - 1] + FFilter->Get_YValue(k) * (whist)[MapIdx(iu - k + 1, Ffiltlen) - 1]; + } + for(stop1 = Ffiltlen, k = 2; k <= stop1; k++) + { + (Z)[iu - 1] = (Z)[iu - 1] - FFilter->Get_XValue(k) * (Z)[MapIdx(iu - k + 1, Ffiltlen) - 1]; + } + S3 = (Z)[iu - 1]; + } + // Irms through LPF + D = S3 - S4; + S4 = S4 + D * (1.0 - exp(-h / FirmsTau)); + if(corrector == 1) + { + int stop = 0; + sIdxU = iu; + for(stop = Ffiltlen, k = 1; k <= stop; k++) + { + (zlast)[k - 1] = (Z)[k - 1]; + (wlast)[k - 1] = (whist)[k - 1]; + } + } + } +} + + +// this is called twice per dynamic time step; predictor then corrector + +void TVCCSObj::IntegrateStates(int ActorID) +{ + double T = 0.0; + double h = 0.0; + double D = 0.0; + double f = 0.0; + double W = 0.0; + double wt = 0.0; + double vre = 0.0; + double vim = 0.0; + double vin = 0.0; + double Scale = 0.0; + double Y = 0.0; + int nstep = 0; + int i = 0; + int k = 0; + int corrector = 0; + complex vnow = {}; + int iu = 0; + int IY = 0; // local copies of sIdxU and sIdxY for predictor + int stop = 0; + if(!Get_ConductorClosed(1, ActorID)) + { + ShutoffInjections(); + return; + } + if(FrmsMode) + { + IntegratePhasorStates(ActorID); + return; + } + inherited::ComputeIterminal(ActorID); + T = ActiveSolutionObj->DynaVars.T; + h = ActiveSolutionObj->DynaVars.h; + f = ActiveSolutionObj->get_FFrequency(); + corrector = ActiveSolutionObj->DynaVars.IterationFlag; + D = double(1) / FsampleFreq; + nstep = Trunc(1E-6 + h / D); + W = 2 * DSSGlobals::PI * f; + vnow = cdivreal((Vterminal)[1 - 1], BaseVolt); + vin = 0; + Y = 0; + iu = sIdxU; + IY = sIdxY; + for(stop = Ffiltlen, k = 1; k <= stop; k++) + { + (Z)[k - 1] = (zlast)[k - 1]; + (whist)[k - 1] = (wlast)[k - 1]; + } + for(stop = nstep, i = 1; i <= stop; i++) + { + int stop1 = 0; + iu = OffsetIdx(iu, 1, Ffiltlen); + // push input voltage waveform through the first PWL block + Scale = 1.0 * i / nstep; + vre = vlast.re + (vnow.re - vlast.re) * Scale; + vim = vlast.im + (vnow.im - vlast.im) * Scale; + wt = W * (T - h + i * D); + vin = (vre * cos(wt) + vim * sin(wt)); + (whist)[iu - 1] = Fbp1->GetYValue_(vin); + // apply the filter and second PWL block + (Z)[iu - 1] = 0; + for(stop1 = Ffiltlen, k = 1; k <= stop1; k++) + { + (Z)[iu - 1] = (Z)[iu - 1] + FFilter->Get_YValue(k) * (whist)[MapIdx(iu - k + 1, Ffiltlen) - 1]; + } + for(stop1 = Ffiltlen, k = 2; k <= stop1; k++) + { + (Z)[iu - 1] = (Z)[iu - 1] - FFilter->Get_XValue(k) * (Z)[MapIdx(iu - k + 1, Ffiltlen) - 1]; + } + Y = Fbp2->GetYValue_((Z)[iu - 1]); + // updating outputs + if((corrector == 1) && (Abs((int) Y) > S4)) + S4 = Abs((int) Y); // catching the fastest peaks + // update the RMS + IY = OffsetIdx(IY, 1, Fwinlen); + (Y2)[IY - 1] = Y * Y; // brute-force RMS update + if(i == nstep) + { + int stop1 = 0; + y2sum = 0.0; + for(stop1 = Fwinlen, k = 1; k <= stop1; k++) + { + y2sum = y2sum + (Y2)[k - 1]; + } + S3 = sqrt(2.0 * y2sum / Fwinlen); // TODO - this is the magnitude, what about angle? + } + } + if(corrector == 1) + { + int stop = 0; + sIdxU = iu; + sIdxY = IY; + vlast = vnow; + S1 = vin; + S5 = (whist)[sIdxU - 1]; + S6 = (Z)[sIdxU - 1]; + S2 = Y; + for(stop = Ffiltlen, k = 1; k <= stop; k++) + { + (zlast)[k - 1] = (Z)[k - 1]; + (wlast)[k - 1] = (whist)[k - 1]; + } + } +} + +int TVCCSObj::NumVariables() +{ + int result = 0; + result = 6; + return result; +} + +void TVCCSObj::GetAllVariables(pDoubleArray States) +{ + int i = 0; + int stop = 0; + for(stop = 6, i = 1; i <= stop; i++) + { + (States)[i - 1] = Get_Variable(i); + } // property maps to Get_Variable below +} + +String TVCCSObj::VariableName(int i) +{ + String result; + result = ""; + if(FrmsMode) + { + switch(i) + { + case 1: + result = "Vrms"; + break; + case 2: + result = "Ipwr"; + break; + case 3: + result = "Hout"; + break; + case 4: + result = "Irms"; + break; + case 5: + result = "NA"; + break; + case 6: + result = "NA"; + break; + default: + ; + break; + } + } + else + { + switch(i) + { + case 1: + result = "Vwave"; + break; + case 2: + result = "Iwave"; + break; + case 3: + result = "Irms"; + break; + case 4: + result = "Ipeak"; + break; + case 5: + result = "BP1out"; + break; + case 6: + result = "Hout"; + break; + default: + ; + break; + } + } + return result; +} + +double TVCCSObj::Get_Variable(int i) +{ + double result = 0.0; + result = 0; + switch(i) + { + case 1: + result = S1; + break; + case 2: + result = S2; + break; + case 3: + result = S3; + break; + case 4: + result = S4; + break; + case 5: + result = S5; + break; + case 6: + result = S6; + break; + default: + ; + break; + } + return result; +} + +void TVCCSObj::Set_Variable(int i, double Value) +{ + switch(i) + { + case 1: + S1 = Value; + break; + case 2: + S2 = Value; + break; + case 3: + S3 = Value; + break; + case 4: + S4 = Value; + break; + case 5: + S5 = Value; + break; + case 6: + S6 = Value; + break; + default: + ; + break; + } +} + + +void VCCS_initialization() +{ + Alpha1 = cmplx(-0.5, 0.5L * sqrt(3.0L)); // 1 at 120 degrees + Alpha2 = cmplx(-0.5, -Alpha1.im); // 1 at 240 degrees +} + + class VCCS_unit + { + public: + VCCS_unit() + { + //AssertSystemInitialization(); + VCCS_initialization(); + } + }; + VCCS_unit _VCCS_unit; + +} // namespace VCCS + + + + diff --git a/OpenDSSC/PCElements/vccs.h b/OpenDSSC/PCElements/vccs.h new file mode 100644 index 0000000..5d6b3f2 --- /dev/null +++ b/OpenDSSC/PCElements/vccs.h @@ -0,0 +1,141 @@ +#ifndef VCCSH +#define VCCSH + +#include "System.h" +#include "Sysutils.h" + +#include "DSSClass.h" +#include "PCClass.h" +#include "PCElement.h" +#include "Ucmatrix.h" +#include "Ucomplex.h" +#include "XYcurve.h" +#include "Arraydef.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Command.h" + + + + +namespace VCCS +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2021, University of Pittsburgh + Copyright (c) 2019-2021, Battelle Memorial Institute + All rights reserved. + ---------------------------------------------------------- +*/ + +class TVCCS : public PCClass::TPCClass +{ + friend class TVCCSObj; +public: + typedef PCClass::TPCClass inherited; +private: + DSSClass::TDSSClass* XY_CurveClass; +protected: + void DefineProperties(); + virtual int MakeLike(const String OtherSource); +public: + TVCCS(); + virtual ~TVCCS(); + virtual int Edit(int ActorID); + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TVCCSObj : public PCElement::TPCElement +{ + friend class TVCCS; +public: + typedef PCElement::TPCElement inherited; +private: + XYCurve::TXYcurveObj* Fbp1; + String Fbp1_name; + XYCurve::TXYcurveObj* Fbp2; + String Fbp2_name; + XYCurve::TXYcurveObj* FFilter; + String Ffilter_name; + double BaseCurr; // line current at Ppct + double BaseVolt; // line-to-neutral voltage at Vrated + double FsampleFreq; // discretization frequency for Z filter + int Fwinlen; + int Ffiltlen; + double Irated; // line current at full output + double Fkv; // scale voltage to HW pu input + double Fki; // scale HW pu output to current + bool FrmsMode; // indicates a phasor-domain PLL simulation + double FmaxIpu; // maximum RMS current in per-unit of rated + double FvrmsTau; // LPF time constant sensing Vrms + double FirmsTau; // LPF time constant producing Irms + + // Support for Dynamics Mode - PU of BaseVolt and BaseCurr + // state variables for Dynamics Mode + double S1; // Vwave(t), or Vrms in phasor mode + double S2; // Iwave(t), or Ipwr in phasor mode + double S3; // Irms, or Hout in phasor mode + double S4; // Ipeak, or Irms in phasor mode + double S5; // BP1out, or NA in phasor mode + double S6; // Hout, or NA in phasor mode + Ucomplex::complex sV1; // positive-sequence voltage; use to inject I1 only + Ucomplex::complex vlast; + Arraydef::pDoubleArray Y2; + Arraydef::pDoubleArray Z; // current digital filter history terms + Arraydef::pDoubleArray whist; + Arraydef::pDoubleArray zlast; // update only after the corrector step + Arraydef::pDoubleArray wlast; + int sIdxU; // ring buffer index for z and whist + int sIdxY; // ring buffer index for y2 (rms current) + double y2sum; + void InitPhasorStates(int ActorID); + void IntegratePhasorStates(int ActorID); + void ShutoffInjections(); + void UpdateSequenceVoltage(); +protected: + virtual double Get_Variable(int i); + virtual void Set_Variable(int i, double Value); +public: + double Ppct; + double Prated; + double Vrated; + TVCCSObj(DSSClass::TDSSClass* ParClass, const String SourceName); + virtual ~TVCCSObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual int InjCurrents(int ActorID); + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + // Support for Dynamics Mode + virtual void InitStateVars(int ActorID); + virtual void IntegrateStates(int ActorID); + virtual int NumVariables(); + virtual void GetAllVariables(Arraydef::pDoubleArray States); + virtual String VariableName(int i); + TVCCSObj(DSSClass::TDSSClass* ParClass); + TVCCSObj(String ClassName); + TVCCSObj(); +}; +extern TVCCSObj* ActiveVCCSObj; +extern TVCCS* VCCSClass; + + +} // namespace VCCS + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace VCCS; +#endif + +#endif // VCCSH + + + + diff --git a/OpenDSSC/PDElements/AutoTrans.cpp b/OpenDSSC/PDElements/AutoTrans.cpp new file mode 100644 index 0000000..a4b1f2c --- /dev/null +++ b/OpenDSSC/PDElements/AutoTrans.cpp @@ -0,0 +1,2932 @@ + +#pragma hdrstop + +#include "AutoTrans.h" + +#include "Circuit.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "XfmrCode.h" + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PDClass; +using namespace PDELement; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XfmrCode; +using namespace Utilities; + +namespace AutoTrans +{ + +TAutoWinding::TAutoWinding() {} +TAutoTransObj::TAutoTransObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TAutoTransObj::TAutoTransObj(String ClassName) : inherited(ClassName) {} +TAutoTransObj::TAutoTransObj() {} + + +TAutoTransObj* ActiveAutoTransObj = nullptr; +TAutoTrans* AutoTransClass = nullptr; /*AUTOTRANDEBUG*/ +TXfmrCode* XfmrCodeClass = nullptr; +const int NumPropsThisClass = 42; +const int WYE = 0; +const int delta = 1; +const int SERIES = 2; + + +int XSCSize(int NumWindings) +{ + return ((NumWindings - 1) * NumWindings) / 2; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all AutoTrans objects + +TAutoTrans::TAutoTrans() +{ + ; + Class_Name = "AutoTrans"; + DSSClassType = DSSClassType + AUTOTRANS_ELEMENT; // override PDElement (kept in both actually) + ActiveElement = 0; + XfmrCodeClass = nullptr; + DefineProperties(); + + /*Make space for AutoTrans property list*/ + std::string* slc = Slice( (PropertyName), NumProperties); + CommandList = TCommandList( slc, NumProperties ); + delete[] slc; + CommandList.set_AbbrevAllowed(true); /*Allow property list abbreviations*/ + AutoTransClass = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TAutoTrans::~TAutoTrans() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TAutoTrans::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + +/* Define Property names */ + PropertyName[1 - 1] = "phases"; + PropertyName[2 - 1] = "windings"; + + // Winding Definition + PropertyName[3 - 1] = "wdg"; + PropertyName[4 - 1] = "bus"; + PropertyName[5 - 1] = "conn"; + PropertyName[6 - 1] = "kV"; // FOR 2-and 3- phase always kVLL ELSE actual winding KV + PropertyName[7 - 1] = "kVA"; + PropertyName[8 - 1] = "tap"; + PropertyName[9 - 1] = "%R"; + PropertyName[10 - 1] = "Rdcohms"; + PropertyName[11 - 1] = "Core"; + + // General Data + PropertyName[12 - 1] = "buses"; + PropertyName[13 - 1] = "conns"; + PropertyName[14 - 1] = "kVs"; + PropertyName[15 - 1] = "kVAs"; + PropertyName[16 - 1] = "taps"; + PropertyName[17 - 1] = "XHX"; + PropertyName[18 - 1] = "XHT"; + PropertyName[19 - 1] = "XXT"; + PropertyName[20 - 1] = "XSCarray"; // x12 13 14... 23 24.. 34 .. + PropertyName[21 - 1] = "thermal"; + PropertyName[22 - 1] = "n"; + PropertyName[23 - 1] = "m"; + PropertyName[24 - 1] = "flrise"; + PropertyName[25 - 1] = "hsrise"; + PropertyName[26 - 1] = "%loadloss"; + PropertyName[27 - 1] = "%noloadloss"; + PropertyName[28 - 1] = "normhkVA"; + PropertyName[29 - 1] = "emerghkVA"; + PropertyName[30 - 1] = "sub"; // =y/n + PropertyName[31 - 1] = "MaxTap"; + PropertyName[32 - 1] = "MinTap"; + PropertyName[33 - 1] = "NumTaps"; + PropertyName[34 - 1] = "subname"; + PropertyName[35 - 1] = "%imag"; + PropertyName[36 - 1] = "ppm_antifloat"; + PropertyName[37 - 1] = "%Rs"; + PropertyName[38 - 1] = "bank"; + PropertyName[39 - 1] = "XfmrCode"; + PropertyName[40 - 1] = "XRConst"; + PropertyName[41 - 1] = "LeadLag"; + PropertyName[42 - 1] = "WdgCurrents"; + + + // define Property help values + PropertyHelp[1 - 1] = "Number of phases this AutoTrans. Default is 3."; + PropertyHelp[2 - 1] = "Number of windings, this AutoTranss. (Also is the number of terminals) " + "Default is 2. This property triggers memory allocation for the AutoTrans and will cause other properties to revert to default values."; + // Winding Definition + PropertyHelp[3 - 1] = "Set this = to the number of the winding you wish to define. Then set " + "the values for this winding. Winding 1 is always the Series winding. " + "Winding 2 is always Common winding (wye connected). " + "Repeat for each winding. Alternatively, use " + "the array collections (buses, kVAs, etc.) to define the windings. Note: " + "reactances are BETWEEN pairs of windings; they are not the property of a single winding."; + PropertyHelp[4 - 1] = "Bus connection spec for this winding."; + PropertyHelp[5 - 1] = String("Connection of this winding {Series, wye*, Delta, LN, LL }. Default is \"wye\" with the neutral solidly grounded. ") + CRLF + + "For AutoTrans, Winding 1 is always Series and Winding 2 (the Common winding) is always Wye. " + + CRLF + + "If only 2 windings, no need to specify connections."; + PropertyHelp[6 - 1] = "For 2-or 3-phase, enter phase-phase kV rating. Otherwise, kV rating of the actual winding. " + "Specify H terminal kV rating for Series winding."; + PropertyHelp[7 - 1] = "Base kVA rating of the winding. Side effect: forces change of max normal and emerg kVA ratings." + "If 2-winding AutoTrans, forces other winding to same value. " + "When winding 1 is defined, all other windings are defaulted to the same rating " + "and the first two winding resistances are defaulted to the %loadloss value."; + PropertyHelp[8 - 1] = "Per unit tap that this winding is on."; + PropertyHelp[9 - 1] = "Percent ac resistance this winding. This value is for the power flow model." + "Is derived from the full load losses in the transformer test report."; + PropertyHelp[10 - 1] = "Winding dc resistance in OHMS. Specify this for GIC analysis. From transformer test report (divide by number of phases). " + "Defaults to 85% of %R property (the ac value that includes stray losses)."; + PropertyHelp[11 - 1] = "{Shell*|5-leg|3-Leg|1-phase} Core Type. Used for GIC analysis in auxiliary programs. Not used inside OpenDSS."; + + // General Data + PropertyHelp[12 - 1] = String("Use this to specify all the bus connections at once using an array. Example:") + CRLF + + CRLF + + "New AutoTrans.T1 buses=[Hbus, Xbus]"; + PropertyHelp[13 - 1] = String("Use this to specify all the Winding connections at once using an array. Example:") + CRLF + + CRLF + + "New AutoTrans.T1 buses=[Hbus, Xbus] " + + "~ conns=(series, wye)"; + PropertyHelp[14 - 1] = String("Use this to specify the kV ratings of all windings at once using an array. Example:") + CRLF + + CRLF + + "New AutoTrans.T1 buses=[Hbus, Xbus] " + + CRLF + + "~ conns=(series, wye)" + + CRLF + + "~ kvs=(115, 12.47)" + + CRLF + + CRLF + + "See kV= property for voltage rules."; + PropertyHelp[15 - 1] = "Use this to specify the kVA ratings of all windings at once using an array."; + PropertyHelp[16 - 1] = "Use this to specify the p.u. tap of all windings at once using an array."; + PropertyHelp[17 - 1] = "Use this to specify the percent reactance, H-L (winding 1 to winding 2). Use " + "for 2- or 3-winding AutoTranss. On the kVA base of winding 1(H-X). See also X12."; + PropertyHelp[18 - 1] = "Use this to specify the percent reactance, H-T (winding 1 to winding 3). Use " + "for 3-winding AutoTranss only. On the kVA base of winding 1(H-X). See also X13."; + PropertyHelp[19 - 1] = "Use this to specify the percent reactance, L-T (winding 2 to winding 3). Use " + "for 3-winding AutoTranss only. On the kVA base of winding 1(H-X). See also X23."; + PropertyHelp[20 - 1] = String("Use this to specify the percent reactance between all pairs of windings as an array. " "All values are on the kVA base of winding 1. The order of the values is as follows:") + CRLF + + CRLF + + "(x12 13 14... 23 24.. 34 ..) " + + CRLF + + CRLF + + "There will be n(n-1)/2 values, where n=number of windings."; + PropertyHelp[21 - 1] = "Thermal time constant of the AutoTrans in hours. Typically about 2."; + PropertyHelp[22 - 1] = "n Exponent for thermal properties in IEEE C57. Typically 0.8."; + PropertyHelp[23 - 1] = "m Exponent for thermal properties in IEEE C57. Typically 0.9 - 1.0"; + PropertyHelp[24 - 1] = "Temperature rise, deg C, for full load. Default is 65."; + PropertyHelp[25 - 1] = "Hot spot temperature rise, deg C. Default is 15."; + PropertyHelp[26 - 1] = "Percent load loss at full load. The %R of the High and Low windings (1 and 2) are adjusted to agree at rated kVA loading."; + PropertyHelp[27 - 1] = "Percent no load losses at rated excitatation voltage. Default is 0. Converts to a resistance in parallel with the magnetizing impedance in each winding."; + PropertyHelp[28 - 1] = "Normal maximum kVA rating of H winding (winding 1+2). Usually 100% - 110% of" + "maximum nameplate rating, depending on load shape. Defaults to 110% of kVA rating of Winding 1."; + PropertyHelp[29 - 1] = "Emergency (contingency) kVA rating of H winding (winding 1+2). Usually 140% - 150% of" + "maximum nameplate rating, depending on load shape. Defaults to 150% of kVA rating of Winding 1."; + PropertyHelp[30 - 1] = "={Yes|No} Designates whether this AutoTrans is to be considered a substation." "Default is No."; // =y/n + PropertyHelp[31 - 1] = "Max per unit tap for the active winding. Default is 1.10"; + PropertyHelp[32 - 1] = "Min per unit tap for the active winding. Default is 0.90"; + PropertyHelp[33 - 1] = "Total number of taps between min and max tap. Default is 32 (16 raise and 16 lower taps about the neutral position). The neutral position is not counted."; + PropertyHelp[34 - 1] = "Substation Name. Optional. Default is null. If specified, printed on plots"; + PropertyHelp[35 - 1] = "Percent magnetizing current. Default=0.0. Magnetizing branch is in parallel with windings in each phase. Also, see \"ppm_antifloat\"."; + PropertyHelp[36 - 1] = "Default=1 ppm. Parts per million of AutoTrans winding VA rating connected to ground to protect against accidentally floating a winding without a reference. " + "If positive then the effect is adding a very large reactance to ground. If negative, then a capacitor."; + PropertyHelp[37 - 1] = String("Use this property to specify all the winding ac %resistances using an array. Example:") + CRLF + + CRLF + + "New AutoTrans.T1 buses=[Hibus, lowbus] " + + "~ %Rs=(0.2 0.3)"; + PropertyHelp[38 - 1] = "Name of the bank this transformer is part of, for CIM, MultiSpeak, and other interfaces."; + PropertyHelp[39 - 1] = "Name of a library entry for transformer properties. The named XfmrCode must already be defined."; + PropertyHelp[40 - 1] = "={Yes|No} Default is NO. Signifies whether or not the X/R is assumed contant for harmonic studies."; + PropertyHelp[41 - 1] = "{Lead | Lag (default) | ANSI (default) | Euro } Designation in mixed Delta-wye connections the " + "relationship between HV to LV winding. Default is ANSI 30 deg lag, e.g., Dy1 of Yd1 vector group. " + "To get typical European Dy11 connection, specify either \"lead\" or \"Euro\""; + PropertyHelp[42 - 1] = "(Read only) Makes winding currents available via return on query (? AutoTrans.TX.WdgCurrents). " + "Order: Phase 1, Wdg 1, Wdg 2, ..., Phase 2 ..."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TAutoTrans::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TAutoTransObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); // Return index of AutoTrans in AutoTrans list + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/* + A Transf Defaults to 3-phases, 2-windings (both wye) +*/ + +int TAutoTrans::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + int i = 0; + String ParamName; /*For parsing property names*/ + String Param; + // continue parsing cmdline presently in Parser + + /*Make this object the active circuit element*/ + ActiveAutoTransObj = (TAutoTransObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveAutoTransObj); // use property to set this value + result = 0; + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + with0->XHXChanged = false; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + ( (TDSSCktElement*) with0 )->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"AutoTrans." + + ((TDSSCktElement*)with0)->get_Name() + + "\"", 100110); + break; + case 1: + ((TDSSCktElement*)with0)->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->SetNumWindings(Parser[ActorID]->MakeInteger_()); + break; // Reallocate stuff if bigger + case 3: + SetActiveWinding(Parser[ActorID]->MakeInteger_()); + break; + case 4: + with0->SetBusAuto(with0->ActiveWinding, Param, ActorID); + break; + case 5: + InterpretAutoConnection(Param); + break; + case 6: + (with0->WINDING_)[with0->ActiveWinding - 1].kVLL = Parser[ActorID]->MakeDouble_(); + break; + case 7: + (with0->WINDING_)[with0->ActiveWinding - 1].kVA = Parser[ActorID]->MakeDouble_(); + break; + case 8: + (with0->WINDING_)[with0->ActiveWinding - 1].puTap = Parser[ActorID]->MakeDouble_(); + break; + case 9: + (with0->WINDING_)[with0->ActiveWinding - 1].Rpu = Parser[ActorID]->MakeDouble_() * 0.01; + break; // %R + case 10: + (with0->WINDING_)[with0->ActiveWinding - 1].RdcOhms = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->strCoreType = Param; + break; + case 12: + InterpretAllBuses(Param, ActorID); + break; + case 13: + InterpretAllConns(Param); + break; + case 14: + InterpretAllkVRatings(Param); + break; + case 15: + InterpretAllkVARatings(Param); + break; + case 16: + InterpretAllTaps(Param); + break; + case 17: + with0->puXHX = TrapZero(Parser[ActorID]->MakeDouble_(), 7.0) * 0.01; + break; + case 18: + with0->puXHT = TrapZero(Parser[ActorID]->MakeDouble_(), 35.0) * 0.01; + break; + case 19: + with0->puXXT = TrapZero(Parser[ActorID]->MakeDouble_(), 30.0) * 0.01; + break; + case 20: + Parser[ActorID]->ParseAsVector(XSCSize(with0->NumWindings), (pDoubleArray) (with0->puXSC.data())); + break; + case 21: + with0->ThermalTimeConst = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->n_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 23: + with0->m_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->FLrise = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->HSrise = Parser[ActorID]->MakeDouble_(); + break; + case 26: + with0->pctLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->pctNoLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->NormMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->EmergMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->IsSubstation = InterpretYesNo(Param); + break; + case 31: + (with0->WINDING_)[with0->ActiveWinding - 1].MaxTap = Parser[ActorID]->MakeDouble_(); + break; + case 32: + (with0->WINDING_)[with0->ActiveWinding - 1].MinTap = Parser[ActorID]->MakeDouble_(); + break; + case 33: + (with0->WINDING_)[with0->ActiveWinding - 1].NumTaps = Parser[ActorID]->MakeInteger_(); + break; + case 34: + with0->SubstationName = Param; + break; + case 35: + with0->pctImag = Parser[ActorID]->MakeDouble_(); + break; + case 36: + with0->ppm_FloatFactor = Parser[ActorID]->MakeDouble_() * 1.0e-6; + break; + case 37: + InterpretAllRs(Param); + break; /*XfmrBank := Param*/ + case 38: + ; + break; + case 39: + with0->FetchXfmrCode(Param); + break; // Do nothing until we define auto code + case 40: + with0->XRConst = InterpretYesNo(Param); + break; + case 41: + with0->HVLeadsLV = InterpretLeadLag(Param); + break; + case 42: + ( (TDSSCktElement*) with0 )->Set_PropertyValue(45,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + + // Inherited properties + default: + inherited::ClassEdit(ActiveAutoTransObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Take care of properties that require some additional work,*/ + switch(ParamPointer) + { + case 1: + ((TDSSCktElement*)with0)->Set_Nconds(2 * ((TDSSCktElement*)with0)->Fnphases); + break; // Force redefinition of number of conductors and reallocation of matrices + // YPrim is built with windings not connected. Connected in NodeRef + // default all winding kVAs to first winding so latter Donot have to be specified + case 7: + if(with0->ActiveWinding == 1) + { + int stop = 0; + for(int stop = with0->NumWindings, i = 2; i <= stop; i++) + { + (with0->WINDING_)[i - 1].kVA = (with0->WINDING_)[1 - 1].kVA; + } + with0->NormMaxHkVA = 1.1 * (with0->WINDING_)[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * (with0->WINDING_)[1 - 1].kVA; + } + else + { + if(with0->NumWindings == 2) + { + (with0->WINDING_)[1 - 1].kVA = (with0->WINDING_)[2 - 1].kVA; // For 2-winding, force both kVAs to be same + } + } + break; + // Update LoadLosskW if winding %r changed. Using only windings 1 and 2 + case 9: + with0->pctLoadLoss = ((with0->WINDING_)[1 - 1].Rpu + (with0->WINDING_)[2 - 1].Rpu) * 100.0; + break; + case 10: + (with0->WINDING_)[with0->ActiveWinding - 1].RdcSpecified = true; + break; + case 11: + with0->CoreType = InterpretCoreType(Param); + break; // Assign integer number + case 15: + { + with0->NormMaxHkVA = 1.1 * (with0->WINDING_)[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * (with0->WINDING_)[1 - 1].kVA; + } + break; + case 17: case 18: case 19: + with0->XHXChanged = true; + break; + case 20: + for(int stop = XSCSize(with0->NumWindings), i = 1; i <= stop; i++) + { + (with0->puXSC)[i - 1] = (with0->puXSC)[i - 1] * 0.01; + } + break; // Convert to per unit + // Assume load loss is split evenly between windings 1 and 2 + case 26: + { + (with0->WINDING_)[1 - 1].Rpu = with0->pctLoadLoss / 2.0 / 100.0; + (with0->WINDING_)[2 - 1].Rpu = (with0->WINDING_)[1 - 1].Rpu; + } + break; + case 37: + with0->pctLoadLoss = ((with0->WINDING_)[1 - 1].Rpu + (with0->WINDING_)[2 - 1].Rpu) * 100.0; + break; // Update + case 38: + DoSimpleMsg("Bank Property not used with AutoTrans object.", 100130); + break; + case 39: + DoSimpleMsg("XFmrCode Property not used with AutoTrans object.", 100131); + break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: + case 15: case 16: case 17: case 18: case 19: + ( (TDSSCktElement*) with0 )->Set_YprimInvalid(ActorID,true); + break; + case 26: case 27: + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActorID,true); + break; + case 35: case 36: case 37: + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + + /*Advance to next property on input line*/ + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TAutoTrans::SetActiveWinding(int W) +{ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + if((W > 0) && (W <= with0->NumWindings)) + with0->ActiveWinding = W; + else + DoSimpleMsg(String("Wdg parameter invalid for \"") + ((TDSSCktElement*)with0)->get_Name() + + "\"", 100112); + } +} + +double TAutoTrans::TrapZero(double Value, double DefaultValue) +{ + double result = 0.0; + if(Value == 0.0) + { + DoSimpleMsg(String("Zero Reactance specified for AutoTrans.") + ( (TDSSCktElement*) ActiveAutoTransObj )->get_Name(), 10011201); + result = DefaultValue; + } + else + result = Value; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TAutoTrans::InterpretAutoConnection(const String s) +{ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + /*# with with0->WINDING^[ActiveWinding] do */ + { + + switch(with0->ActiveWinding) + { + case 1: + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = SERIES; + break; // Get_First() Winding always Series + case 2: + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = WYE; + break; // Second Winding is always Common and Wye + default: + switch(LowerCase(s)[0]) + { + case L'y': case L'w': + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = WYE; + break; /*Wye*/ + case L'd': + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = delta; + break; /*Delta or line-Line*/ + case L'l': + switch(LowerCase(s)[1]) + { + case L'n': + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = WYE; + break; + case L'l': + (with0->WINDING_)[with0->ActiveWinding - 1].Connection = delta; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + break; + } + } + ((TDSSCktElement*)with0)->Yorder = ((TDSSCktElement*)with0)->Fnconds * ((TDSSCktElement*)with0)->Fnterms; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActiveActor,true); + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding connections expressed in one array of strings + +void TAutoTrans::InterpretAllConns(const String s) +{ + String S1; + String S2; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + S1 = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + S2 = AuxParser[ActiveActor]->MakeString_(); + if(S2.size() > 0) + InterpretAutoConnection(S2); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding bus connections expressed in one array of strings + +void TAutoTrans::InterpretAllBuses(const String s, int ActorID) +{ + String BusNam; + int i = 0; + AuxParser[ActorID]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActorID]->GetNextParam(); // ignore any parameter name not expecting any + BusNam = AuxParser[ActorID]->MakeString_(); + if(BusNam.size() > 0) + with0->SetBusAuto(with0->ActiveWinding, BusNam, ActorID); + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding bus connections expressed in one array of strings + +bool TAutoTrans::InterpretLeadLag(const String s) +{ + bool result = false; + result = false; // default to ANSI 30 Deg Lag if can't understand S + if(CompareTextShortest(s, "lead") == 0) + result = true; + else + { + if(CompareTextShortest(s, "euro") == 0) + result = true; + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding kV ratings expressed in one array of strings + +void TAutoTrans::InterpretAllkVRatings(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + (with0->WINDING_)[with0->ActiveWinding - 1].kVLL = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding ratings expressed in one array of strings + +void TAutoTrans::InterpretAllkVARatings(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + (with0->WINDING_)[with0->ActiveWinding - 1].kVA = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding ratings expressed in one array of strings + +void TAutoTrans::InterpretAllRs(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + (with0->WINDING_)[with0->ActiveWinding - 1].Rpu = AuxParser[ActiveActor]->MakeDouble_() * 0.01; + } + } +} + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding taps expressed in one array of strings + +void TAutoTrans::InterpretAllTaps(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name, not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + (with0->WINDING_)[with0->ActiveWinding - 1].puTap = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TAutoTrans::MakeLike(const String AutoTransfName) +{ + int result = 0; + TAutoTransObj* OtherTransf = nullptr; + int i = 0; + result = 0; + /*See if we can find this Transf name in the present collection*/ + OtherTransf = ((TAutoTransObj*) Find(AutoTransfName)); + if(OtherTransf != nullptr) + /*# with ActiveAutoTransObj do */ + { + auto with0 = ActiveAutoTransObj; + int stop = 0; + ((TDSSCktElement*)with0)->Set_NPhases(( (TDSSCktElement*) OtherTransf )->Fnphases); + with0->SetNumWindings(OtherTransf->NumWindings); + ((TDSSCktElement*)with0)->Set_Nconds(2 * ((TDSSCktElement*)with0)->Fnphases); // forces reallocation of terminals and conductors + ((TDSSCktElement*)with0)->Yorder = ((TDSSCktElement*)with0)->Fnconds * ((TDSSCktElement*)with0)->Fnterms; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActiveActor,true); + for(int stop = with0->NumWindings, i = 1; i <= stop; i++) + { + /*# with with0->WINDING^[i] do */ + { + + (with0->WINDING_)[i - 1].Connection = (OtherTransf->WINDING_)[i - 1].Connection; + (with0->WINDING_)[i - 1].kVLL = (OtherTransf->WINDING_)[i - 1].kVLL; + with0->kVSeries = OtherTransf->kVSeries; + (with0->WINDING_)[i - 1].VBase = (OtherTransf->WINDING_)[i - 1].VBase; + (with0->WINDING_)[i - 1].kVA = (OtherTransf->WINDING_)[i - 1].kVA; + (with0->WINDING_)[i - 1].puTap = (OtherTransf->WINDING_)[i - 1].puTap; + (with0->WINDING_)[i - 1].Rpu = (OtherTransf->WINDING_)[i - 1].Rpu; + (with0->WINDING_)[i - 1].RdcOhms = (OtherTransf->WINDING_)[i - 1].RdcOhms; + (with0->WINDING_)[i - 1].RdcSpecified = (OtherTransf->WINDING_)[i - 1].RdcSpecified; + // copy the taps + (with0->WINDING_)[i - 1].TapIncrement = (OtherTransf->WINDING_)[i - 1].TapIncrement; + (with0->WINDING_)[i - 1].MinTap = (OtherTransf->WINDING_)[i - 1].MinTap; + (with0->WINDING_)[i - 1].MaxTap = (OtherTransf->WINDING_)[i - 1].MaxTap; + (with0->WINDING_)[i - 1].NumTaps = (OtherTransf->WINDING_)[i - 1].NumTaps; + } + } + with0->SetTermRef(); + with0->puXHX = OtherTransf->puXHX; + with0->puXHT = OtherTransf->puXHT; + with0->puXXT = OtherTransf->puXXT; + for(int stop = XSCSize(with0->NumWindings), i = 1; i <= stop; i++) + { + (with0->puXSC)[i - 1] = (OtherTransf->puXSC)[i - 1]; + } + with0->ZB->CopyFrom(OtherTransf->ZB); + with0->Y_1Volt->CopyFrom(OtherTransf->Y_1Volt); + with0->Y_Term->CopyFrom(OtherTransf->Y_Term); + with0->Y_1Volt_NL->CopyFrom(OtherTransf->Y_1Volt_NL); + with0->Y_Term_NL->CopyFrom(OtherTransf->Y_Term_NL); + with0->ThermalTimeConst = OtherTransf->ThermalTimeConst; + with0->n_thermal = OtherTransf->n_thermal; + with0->m_thermal = OtherTransf->m_thermal; + with0->FLrise = OtherTransf->FLrise; + with0->HSrise = OtherTransf->HSrise; + with0->pctLoadLoss = OtherTransf->pctLoadLoss; + with0->pctNoLoadLoss = OtherTransf->pctNoLoadLoss; + with0->NormMaxHkVA = OtherTransf->NormMaxHkVA; + with0->EmergMaxHkVA = OtherTransf->EmergMaxHkVA; + with0->XRConst = OtherTransf->XRConst; + with0->XfmrBank = OtherTransf->XfmrBank; + with0->XfmrCode = OtherTransf->XfmrCode; + ClassMakeLike(OtherTransf); + for(int stop = ((TDSSCktElement*)with0)->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + if(i != 45) + // skip read only properties + ((TDSSCktElement*)with0)->Set_PropertyValue(i,( (TDSSCktElement*) OtherTransf )->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in AutoTrans MakeLike: \"") + AutoTransfName + + "\" Not Found.", 100113); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TAutoTrans::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TAutoTrans.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TAutoTrans Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TAutoTransObj::TAutoTransObj(TDSSClass* ParClass, const String TransfName) + : inherited(ParClass), + DeltaDirection(1), + ppm_FloatFactor(0.000001), + pctImag(0.0), + XRConst(false), + NumWindings(0), + MaxWindings(0), + puXHX(0.0), + puXHT(0.0), + puXXT(0.0), + ZBase(0.0), + puXSC(3, 0.0), + VABase(0.0), + kVSeries(0.0), + ZB(nullptr), + Y_1Volt(nullptr), + Y_Term(nullptr), + Y_1Volt_NL(nullptr), + Y_Term_NL(nullptr), + Y_Terminal_Freqmult(0.0), + NormMaxHkVA(0.0), + EmergMaxHkVA(0.0), + ThermalTimeConst(0.0), + n_thermal(0.0), + m_thermal(0.0), + FLrise(0.0), + HSrise(0.0), + pctLoadLoss(0.0), + pctNoLoadLoss(0.0), + HVLeadsLV(false), + XHXChanged(false), + ActiveWinding(0), + IsSubstation(false), + CoreType(0) +{ + int i = 0; + int stop = 0; + Set_Name(LowerCase(TransfName)); + DSSObjType = ParClass->DSSClassType; //DSSObjType + XFMR; // override PDElement (kept in both actually) + Set_NPhases(3); // Directly set conds and phases + Fnconds = 2 * Fnphases; // 2 conductors per phase; let NodeRef connect neutral, etc. + SetNumWindings(2); // must do this after setting number of phases + ActiveWinding = 1; + Set_NTerms(NumWindings); // Force allocation of terminals and conductors + puXHX = 0.10; + puXHT = 0.35; + puXXT = 0.30; + XHXChanged = true; // Set flag to for calc of XSC array from XHL, etc. + SubstationName = ""; + XfmrBank = ""; + XfmrCode = ""; + VABase = (WINDING_)[1 - 1].kVA * 1000.0; + ThermalTimeConst = 2.0; + n_thermal = 0.8; + m_thermal = 0.8; + FLrise = 65.0; + HSrise = 15.0; // Hot spot rise + NormMaxHkVA = 1.1 * (WINDING_)[1 - 1].kVA; + EmergMaxHkVA = 1.5 * (WINDING_)[1 - 1].kVA; + pctLoadLoss = 2.0 * (WINDING_)[1 - 1].Rpu * 100.0; // assume two windings for init'ing + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + (WINDING_)[i - 1].ComputeAntiFloatAdder(ppm_FloatFactor, VABase / Fnphases); + } + + /*Default the no load properties to zero*/ + pctNoLoadLoss = 0.0; + FaultRate = 0.007; + IsSubstation = false; + HVLeadsLV = false; // Defaults to ANSI connection + Y_Terminal_Freqmult = 0.0; + Yorder = Fnterms * Fnconds; + InitPropertyValues(0); + RecalcElementData(ActiveActor); +} +// Added Jan 3, 2019 + +void TAutoTransObj::SetBusAuto(int iwdg, const String s, int ActorID) +{ + int NNodes[50/*# range 1..50*/]; // big integer buffer + int NumNodes = 0; + int dotpos = 0; + int FirstNeut = 0; // Get_First() Neutral Node + int II = 0; + String strBusName; + String strNewBusName; +// For winding 2 set all nodes on second end of winding to same as 1st value +// so all neutral ends of common winding get connected to same neutral node + switch(iwdg) + { + case 2: + { + int stop = 0; + for(int stop = Get_NPhases(), II = 1; II <= stop; II++) + { + NNodes[II - 1] = II; + } // set up buffer with defaults + // Default all other conductors to a ground connection + // If user wants them ungrounded, must be specified explicitly! + for(int stop = Get_NConds(), II = Get_NPhases() + 1; II <= stop; II++) + { + NNodes[II - 1] = 0; + } + AuxParser[ActorID]->set_Token(s); // load up AuxParser + strBusName = AuxParser[ActorID]->ParseAsBusName(NumNodes, (pIntegerArray) &NNodes, ActorID); + + // Check for non-zero neutral specification + if(NNodes[Get_NPhases() + 1 - 1] > 0) + // Reconstruct new bus name + { + int stop = 0; + strNewBusName = strBusName; + for(int stop = Get_NPhases(), II = 1; II <= stop; II++) + { + strNewBusName = strNewBusName + Format(".%d", NNodes[II - 1]); + } + for(int stop = Get_NConds(), II = Get_NPhases() + 1; II <= stop; II++) + { + strNewBusName = strNewBusName + Format(".%d", NNodes[Get_NPhases() + 1 - 1]); + } + SetBus(iwdg, strNewBusName); + } + else + SetBus(iwdg, s); + } + break; + default: + SetBus(iwdg, s); // all other windings + break; + } +} +// Overrides standard function + +void TAutoTransObj::SetNodeRef(int iTerm, Arraydef::pIntegerArray NodeRefArray) +{ + int i = 0; + inherited::SetNodeRef(iTerm, NodeRefArray); + + // Now fixup noderefs for series winding of AutoTrans + // Warning **** Magic happens here + // Redefine 2nd node of Series winding to same as first node of 2nd winding (common winding) + if(iTerm == 2) + { + if((WINDING_)[1 - 1].Connection == SERIES) // If series winding + { + int stop = 0; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + (NodeRef)[Fnphases + i - 1] = (NodeRef)[i + Fnconds - 1]; + (Terminals[iTerm - 1].TermNodeRef)[Fnphases + i - 1] = (NodeRef)[i + Fnconds - 1]; + } + } + } +} + +void TAutoTransObj::SetNumWindings(int n) +{ + int i = 0; + int OldWdgSize = 0; + int NewWdgSize = 0; + if(n > 1) + { + int stop = 0; + // Free old winding objects + WINDING_.clear(); + OldWdgSize = XSCSize(NumWindings); + NumWindings = n; + MaxWindings = n; + NewWdgSize = XSCSize(NumWindings); + Fnconds = 2 * Fnphases; + Set_NTerms(NumWindings); + + WINDING_.resize(MaxWindings); // Reallocate collector array + for(int stop = MaxWindings, i = 1; i <= stop; i++) + { + (WINDING_)[i - 1] = TAutoWinding(i); + } + + // array of short circuit measurements between pairs of windings + puXSC.resize(NewWdgSize); + for(int stop = NewWdgSize, i = OldWdgSize + 1; i <= stop; i++) + { + (puXSC)[i - 1] = 0.30; + } + TermRef.resize(2 * NumWindings * Fnphases); + + /*Reallocate impedance matrices*/ + delete ZB; + delete Y_1Volt; + delete Y_1Volt_NL; + delete Y_Term; + delete Y_Term_NL; + ZB = new TcMatrix(NumWindings - 1); + Y_1Volt = new TcMatrix(NumWindings); + Y_1Volt_NL = new TcMatrix(NumWindings); + Y_Term = new TcMatrix(2 * NumWindings); + Y_Term_NL = new TcMatrix(2 * NumWindings); + } + else + DoSimpleMsg(String("Invalid number of windings: (") + IntToStr(n) + + ") for AutoTrans." + + get_Name(), 100111); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TAutoTransObj::~TAutoTransObj() +{ + /*Throw away stuff allocated for this object*/ + + if (ZB != nullptr) delete ZB; // ZB->~TcMatrix(); + if (Y_1Volt != nullptr) delete Y_1Volt; // Y_1Volt->~TcMatrix(); + if (Y_1Volt_NL != nullptr) delete Y_1Volt_NL; // Y_1Volt_NL->~TcMatrix(); + if (Y_Term != nullptr) delete Y_Term; // Y_Term->~TcMatrix(); + if (Y_Term_NL != nullptr) delete Y_Term_NL; // Y_Term_NL->~TcMatrix(); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TAutoTransObj::RecalcElementData(int ActorID) +{ + int i = 0; + int ihvolt = 0; + double VFactor = 0.0; + + // Determine Delta Direction + // If high voltage is delta, delta leads y + // If high voltage is wye, delta lags wye + int stop = 0; + if((WINDING_)[1 - 1].Connection == (WINDING_)[2 - 1].Connection) + DeltaDirection = 1; + else + { + if((WINDING_)[1 - 1].Connection == SERIES) // Auto + DeltaDirection = 1; + else + { + if((WINDING_)[1 - 1].kVLL >= (WINDING_)[2 - 1].kVLL) + ihvolt = 1; + else + ihvolt = 2; + switch((WINDING_)[ihvolt - 1].Connection) + { + case WYE: + if(HVLeadsLV) + DeltaDirection = -1; + else + DeltaDirection = 1; + break; + case delta: + if(HVLeadsLV) + DeltaDirection = 1; + else + DeltaDirection = -1; + break; + // ---old code --- If Winding^[2].Connection = 0 Then DeltaDirection := -1 Else DeltaDirection := 1; + default: + ; + break; + } + } + } + SetTermRef(); // Re-establish TermRef IF num windings or connection changed + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if((WINDING_)[i - 1].NumTaps > 0) + (WINDING_)[i - 1].TapIncrement = ((WINDING_)[i - 1].MaxTap - (WINDING_)[i - 1].MinTap) / (WINDING_)[i - 1].NumTaps; + else + (WINDING_)[i - 1].TapIncrement = 0.0; + } + } + if(XHXChanged) + /*should only happen for 2- and 3-winding AutoTranss*/ + { + if(NumWindings <= 3) + { + int stop = 0; + for(int stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + switch(i) + { + case 1: + puXSC[1 - 1] = puXHX; + break; + case 2: + (puXSC)[2 - 1] = puXHT; + break; + case 3: + (puXSC)[3 - 1] = puXXT; + break; + default: + ; + break; + } + } + } + XHXChanged = false; + } + + // Set winding voltage bases (in volts) + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + switch((WINDING_)[i - 1].Connection) + { // Get the actual turns voltage base for each winding + case WYE: + switch(Fnphases) + { + case 2: + case 3: // Wye + (WINDING_)[i - 1].VBase = (WINDING_)[i - 1].kVLL * InvSQRT3x1000; + break; // assume 3-phase for 2-phase designation + default: + (WINDING_)[i - 1].VBase = (WINDING_)[i - 1].kVLL * 1000.0; + break; + } + break; + case delta: + (WINDING_)[i - 1].VBase = (WINDING_)[i - 1].kVLL * 1000.0; + break; // delta + // Series winding for Auto Should be Winding[1] + case SERIES: + { + switch(Fnphases) + { + case 2: + case 3: + kVSeries = ((WINDING_)[i - 1].kVLL - (WINDING_)[2 - 1].kVLL) / SQRT3; + break; + default: + kVSeries = (WINDING_)[i - 1].kVLL - (WINDING_)[2 - 1].kVLL; + break; + } + if(kVSeries == 0.0) + kVSeries = (WINDING_)[i - 1].kVLL * 0.0001; // In case series has same voltage as common + (WINDING_)[i - 1].VBase = kVSeries * 1000.0; + } + break; + default: + ; + break; + } + } + } + + /*Base rating of Winding 1 */ + VABase = (WINDING_)[1 - 1].kVA * 1000.0; + + // Set Rdc parameters for each winding. + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if((WINDING_)[i - 1].RdcSpecified) + (WINDING_)[i - 1].Rdcpu = (WINDING_)[i - 1].RdcOhms / (Sqr((WINDING_)[i - 1].VBase) / VABase); + else + { + (WINDING_)[i - 1].Rdcpu = 0.85 * (WINDING_)[i - 1].Rpu; // default to 85% of the ac value (does not include stray loss) + (WINDING_)[i - 1].RdcOhms = (WINDING_)[i - 1].Rdcpu * Sqr((WINDING_)[i - 1].VBase) / VABase; + } + } + } + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + (WINDING_)[i - 1].ComputeAntiFloatAdder(ppm_FloatFactor, VABase / Fnphases); + } + + /* Normal and Emergency terminal current Rating for UE check*/ + VFactor = 1.0; // ensure initialization + switch((WINDING_)[1 - 1].Connection) + { + case WYE: + VFactor = (WINDING_)[1 - 1].VBase * 0.001; + break; // wye + case delta: + switch(Fnphases) + { + case 1: + VFactor = (WINDING_)[1 - 1].VBase * 0.001; + break; + case 2: + case 3: + VFactor = (WINDING_)[1 - 1].VBase * 0.001 / SQRT3; + break; + default: + VFactor = (WINDING_)[1 - 1].VBase * 0.001 * 0.5 / sin(double(DSSGlobals::PI) / Fnphases); + break; + } + break; + case 2: + VFactor = (WINDING_)[1 - 1].VBase * 0.001; + break; // Series Winding + default: + ; + break; + } + + /*Divide per phase kVA by voltage to neutral*/ + NormAmps = NormMaxHkVA / Fnphases / VFactor; + EmergAmps = EmergMaxHkVA / Fnphases / VFactor; + CalcY_Terminal(1.0, ActorID); // Calc Y_Terminal at base frequency +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/*Override standard SaveWrite*/ +/*AutoTrans structure not conducive to standard means of saving*/ + +void TAutoTransObj::SaveWrite(TTextRec& f) +{ + int iProp = 0; + int i = 0; + /*Write only properties that were explicitly set in the + final order they were actually set*/ + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + while(iProp > 0) + { + /*# with ParentClass do */ + { + auto with0 = ParentClass; + switch((with0->RevPropertyIdxMap)[iProp - 1]) + { + /*Trap wdg= and write out array properties instead*/ + case 3: // if WDG= was ever used write out arrays ... + { + int stop = 0; + for(int stop = 16, i = 12; i <= stop; i++) + { + String PropValue = "=" + GetPropertyValue(i); + Write( f, " " + with0->PropertyName[i-1] + PropValue ); + } + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + Write(f, Format(" wdg=%d %%R=%.7g", i, WINDING_[i - 1].Rpu * 100.0)); + } + } + break; /*do Nothing*/ + case 4: case 5: case 6: case 7: case 8: case 9: + ; + break; // Ignore these properties; use arrays instead + default: + if(Length(String(Get_PropertyValue(iProp))) > 0) + { + String PropValue = "=" + CheckForBlanks(String(Get_PropertyValue(iProp) ) ); + Write( f, " " + with0->PropertyName[with0->RevPropertyIdxMap[iProp - 1] - 1] + PropValue ); + } + break; + } + } + iProp = GetNextPropertySet(iProp); + } +} + +//---------------------------------------------------------------------------- + +int TAutoTransObj::get_NumWindings() +{ + return NumWindings; +} + +// sets an array which maps the two conductors of each winding to the +// phase and neutral conductors of the AutoTrans according to the winding connection + +void TAutoTransObj::SetTermRef() +{ + int i = 0; + int j = 0; + int k = 0; + int NumCondPerPhase = 0; + k = 0; + switch(Fnphases) + { + case 1: + for(int stop = NumWindings, j = 1; j <= stop; j++) + { + ++k; + (TermRef)[k - 1] = (j - 1) * Fnconds + 1; // fNconds = 2 + ++k; + (TermRef)[k - 1] = j * Fnconds; + } + break; + + +/*** Typical array for 3-phase auto +This builds the YPrim and the NodeRef array maps it into Y + TermRef^[1] := 1; + TermRef^[2] := 4; + TermRef^[3] := 7; + TermRef^[4] := 10; + TermRef^[5] := 2; + TermRef^[6] := 5; + TermRef^[7] := 8; + TermRef^[8] := 11; + TermRef^[9] := 3; + TermRef^[10] := 6; + TermRef^[11] := 9; + TermRef^[12] := 12; + +********/ + default: + int stop = 0; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = NumWindings, j = 1; j <= stop1; j++) + { + ++k; + switch((WINDING_)[j - 1].Connection) + { + case WYE: // Wye + { + TermRef[k - 1] = (j - 1) * Fnconds + i; + ++k; + TermRef[k - 1] = TermRef[k - 1 - 1] + Fnphases; + } + break; + /***** WILL THIS WORK for 2-PHASE OPEN DELTA ???? Need to check this sometime*/ // Delta + case delta: + { + (TermRef)[k - 1] = (j - 1) * Fnconds + i; + ++k; + (TermRef)[k - 1] = (j - 1) * Fnconds + RotatePhases(i); // connect to next phase in sequence + } + break; // Series Winding for Auto Transfomer + case SERIES: + { + (TermRef)[k - 1] = i; + ++k; + (TermRef)[k - 1] = i + Fnphases; + } + break; + default: + ; + break; + } /*CASE connection*/ + } + } + break; + } /*CASE Fnphases*/ +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TAutoTransObj::CalcYPrim(int ActorID) +{ + double FreqMultiplier = 0.0; + if(Get_YprimInvalid(ActorID,0)) + // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + if(YPrim != nullptr) + delete YPrim; + YPrim_Series = new TcMatrix(Yorder); + YPrim_Shunt = new TcMatrix(Yorder); + YPrim = new TcMatrix(Yorder); + } + else + /*Same size as last time; just zero out to start over*/ + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + + // Set frequency multipliers for this calculation + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + // Check for rebuilding Y_Terminal; Only rebuild if freq is different than last time + if(FreqMultiplier != Y_Terminal_Freqmult) + CalcY_Terminal(FreqMultiplier, ActorID); + BuildYPrimComponent(YPrim_Series, Y_Term); + BuildYPrimComponent(YPrim_Shunt, Y_Term_NL); + + + /*Combine the two Yprim components into Yprim*/ + YPrim->CopyFrom(YPrim_Series); + YPrim->AddFrom(YPrim_Shunt); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TAutoTransObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + TcMatrix* ZBtemp = nullptr; + int stop = 0; + inherited::DumpProperties(f, Complete); + + /*Basic Property Dump*/ + { Write(f, "~ "); Write(f, "NumWindings="); WriteLn(f, NumWindings, 0); } + { Write(f, "~ "); Write(f, "phases="); WriteLn(f, Fnphases, 0); } + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(i == 1) + { Write(f, "~ "); Write(f, "Wdg="); Write(f, i, 0); Write(f, " bus="); WriteLn(f, Get_FirstBus()); } + else + { Write(f, "~ "); Write(f, "Wdg="); Write(f, i, 0); Write(f, " bus="); WriteLn(f, Get_NextBus()); } + switch((WINDING_)[i - 1].Connection) + { + case WYE: + WriteLn(f, "~ conn=wye"); + break; + case delta: + WriteLn(f, "~ conn=delta"); + break; + case SERIES: + WriteLn(f, "~ conn=Series"); + break; + default: + ; + break; + } + WriteLn(f, Format("~ kv=%.7g", (WINDING_)[i - 1].kVLL)); + WriteLn(f, Format("~ kVA=%.7g", (WINDING_)[i - 1].kVA)); + WriteLn(f, Format("~ tap=%.7g", (WINDING_)[i - 1].puTap)); + WriteLn(f, Format("~ %%r=%.7g", (WINDING_)[i - 1].Rpu * 100.0)); + WriteLn(f, Format("~ Rdcohms=%.7g", (WINDING_)[i - 1].RdcOhms)); + } + } + { Write(f, "~ "); Write(f, "XHL="); WriteLn(f, puXHX * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "XHT="); WriteLn(f, puXHT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "XLT="); WriteLn(f, puXXT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X12="); WriteLn(f, puXHX * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X13="); WriteLn(f, puXHT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X23="); WriteLn(f, puXXT * 100.0, 0, 3); } + Write(f, "~ Xscmatrix= \""); + for(int stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + { Write(f, (puXSC)[i - 1] * 100.0, 0, 2); Write(f, L' '); } + } + WriteLn(f, L'\"'); + { Write(f, "~ "); Write(f, "NormMAxHkVA="); WriteLn(f, NormMaxHkVA, 0, 0); } + { Write(f, "~ "); Write(f, "EmergMAxHkVA="); WriteLn(f, EmergMaxHkVA, 0, 0); } + { Write(f, "~ "); Write(f, "thermal="); WriteLn(f, ThermalTimeConst, 0, 1); } + { Write(f, "~ "); Write(f, "n="); WriteLn(f, n_thermal, 0, 1); } + { Write(f, "~ "); Write(f, "m="); WriteLn(f, m_thermal, 0, 1); } + { Write(f, "~ "); Write(f, "flrise="); WriteLn(f, FLrise, 0, 0); } + { Write(f, "~ "); Write(f, "hsrise="); WriteLn(f, HSrise, 0, 0); } + { Write(f, "~ "); Write(f, "%loadloss="); WriteLn(f, pctLoadLoss, 0, 0); } + { Write(f, "~ "); Write(f, "%noloadloss="); WriteLn(f, pctNoLoadLoss, 0, 0); } + for(int stop = NumPropsThisClass, i = 28; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (ParentClass->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + /*# with ParentClass do */ + { + auto with1 = ParentClass; + int stop = 0; + for(int stop = with1->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with1->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + ZBtemp = new TcMatrix(NumWindings - 1); + ZBtemp->CopyFrom(ZB); + ZBtemp->Invert(); + WriteLn(f, "ZB:"); + /*# with ZBtemp do */ + { + auto with2 = ZBtemp; + int stop = 0; + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + Write(f, Format("%g ", with2->GetElement(i, j).re)); + } + WriteLn(f); + } + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + Write(f, Format("%g ", with2->GetElement(i, j).im)); + } + WriteLn(f); + } + } /*WITH*/ + delete ZBtemp; + WriteLn(f); + WriteLn(f, "ZB: (inverted)"); + /*# with ZB do */ + { + auto with3 = ZB; + int stop = 0; + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with3->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with3->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } /*WITH*/ + WriteLn(f); + WriteLn(f, "Y_OneVolt"); + /*# with Y_1Volt do */ + { + auto with4 = Y_1Volt; + int stop = 0; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with4->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with4->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } + WriteLn(f); + WriteLn(f, "Y_Terminal"); + /*# with Y_Term do */ + { + auto with5 = Y_Term; + int stop = 0; + for(int stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with5->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(int stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with5->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } + WriteLn(f); + Write(f, "TermRef= "); + for(int stop = 2 * NumWindings * Fnphases, i = 1; i <= stop; i++) + { + { + Write(f, to_string(TermRef[i - 1])); + Write(f, L' '); } + } + WriteLn(f); + } +} + +void TAutoWinding::ComputeAntiFloatAdder(double PPM_Factor, double VABase1ph) +{ + Y_PPM = -PPM_Factor / (Sqr(VBase) / VABase1ph) / 2.0L; //12-11-12 divided by two + // put half on each terminal of the winding. +} +/* + Make a new winding +*/ + +TAutoWinding::TAutoWinding(int iWinding) + : Connection(0), + kVLL(0.0), + VBase(0.0), + kVA(0.0), + puTap(0.0), + Rpu(0.0), + Rdcpu(0.0), + RdcOhms(0.0), + RdcSpecified(false), + Y_PPM(0.0), + TapIncrement(0.0), + MinTap(0.0), + MaxTap(0.0), + NumTaps(0) +{ + ; + switch(iWinding) + { + case 1: + { + Connection = SERIES; // Get_First() Winding is Series Winding + kVLL = 115.0; + } + break; + default: + Connection = WYE; + kVLL = 12.47; + break; + } + VBase = kVLL / SQRT3 * 1000.0; + kVA = 1000.0; + puTap = 1.0; + Rpu = 0.002; + Rdcpu = Rpu * 0.85; // default value + RdcOhms = Sqr(kVLL) / (kVA / 1000.0) * Rdcpu; + RdcSpecified = false; + ComputeAntiFloatAdder(1.0e-6, kVA / 3.0 / 1000.0); // 1 PPM + TapIncrement = 0.00625; + NumTaps = 32; + MaxTap = 1.10; + MinTap = 0.90; +} + +double TAutoTransObj::Get_PresentTap(int i, int ActorID) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].puTap; + else + result = 0.0; + return result; +} + +void TAutoTransObj::Set_PresentTap(int i, int ActorID, double Value) +{ + double TempVal = 0.0; + if((i > 0) && (i <= NumWindings)) + /*# with WINDING^[i] do */ + { + + /*Range Checking*/ + TempVal = Value; + if(TempVal < (WINDING_)[i - 1].MinTap) + TempVal = (WINDING_)[i - 1].MinTap; + else + { + if(TempVal > (WINDING_)[i - 1].MaxTap) + TempVal = (WINDING_)[i - 1].MaxTap; + } + if(TempVal != (WINDING_)[i - 1].puTap) /*Only if there's been a change*/ + { + (WINDING_)[i - 1].puTap = TempVal; + Set_YprimInvalid(ActorID,true); // this property triggers setting SystemYChanged=true + RecalcElementData(ActorID); + } + } +} + +double TAutoTransObj::Get_WdgResistance(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].Rpu; + else + result = 0.0; + return result; +} + +double TAutoTransObj::Get_WdgkVA(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].kVA; + else + result = 0.0; + return result; +} + +double TAutoTransObj::Get_WdgYPPM(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].Y_PPM; + else + result = 0.0; + return result; +} + +double TAutoTransObj::Get_Xsc(int i) +{ + double result = 0.0; + int IMax = 0; + IMax = XSCSize(NumWindings); + if((i > 0) && (i <= IMax)) + result = (puXSC)[i - 1]; + else + result = 0.0; + return result; +} + +int TAutoTransObj::Get_WdgConnection(int i) +{ + int result = 0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].Connection; + else + result = 0; + return result; +} + +double TAutoTransObj::Get_MinTap(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].MinTap; + else + result = 0.0; + return result; +} + +double TAutoTransObj::Get_MaxTap(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].MaxTap; + else + result = 0.0; + return result; +} + +int TAutoTransObj::Get_NumTaps(int i) +{ + int result = 0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].NumTaps; + else + result = 0; + return result; +} + +double TAutoTransObj::Get_TapIncrement(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = (WINDING_)[i - 1].TapIncrement; + else + result = 0.0; + return result; +} + +/* + Return a vector of complex currents for each Winding of all phases + + Iterm = Yterm * Vterm + + Yterm order is 2*NumWindings. Each phase has same Yterm. + Vterm order is 2*NumWindings . + + Calculate Iterm phase-by-phase and concatenate into CurrBuffer. +*/ + +void TAutoTransObj::GetAllWindingCurrents(pComplexArray CurrBuffer, int ActorID) +{ + int jphase = 0; + int k = 0; + int iPhase = 0; + int iWind = 0; + int i = 0; + pComplexArray VTerm = nullptr; + pComplexArray iTerm = nullptr; + pComplexArray ITerm_NL = nullptr; + try + { + int stop = 0; + VTerm = new complex[2 * NumWindings]; + iTerm = new complex[2 * NumWindings]; + ITerm_NL = new complex[2 * NumWindings]; + + /*Load up Vterminal - already allocated for all cktelements*/ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(!(with0->NodeV.empty())) + { + int stop = 0; + for(int stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (Vterminal)[i - 1] = with0->NodeV[(NodeRef)[i - 1]]; + else + (Vterminal)[i - 1] = with0->VoltInActor1((NodeRef)[i - 1]); + } + } + else + { + int stop = 0; + for(int stop = Yorder, i = 1; i <= stop; i++) + { + (Vterminal)[i - 1] = CZero; + } + } + } + k = 0; + for(int stop = Fnphases, iPhase = 1; iPhase <= stop; iPhase++) + { + int stop1 = 0; + for(int stop1 = NumWindings, iWind = 1; iWind <= stop1; iWind++) + { + i = 2 * iWind - 1; + switch((WINDING_)[iWind - 1].Connection) + { + case WYE: // Wye (Common winding usually) + { + (VTerm)[i - 1] = (Vterminal)[iPhase + (iWind - 1) * Fnconds - 1]; + (VTerm)[i + 1 - 1] = (Vterminal)[iPhase + (iWind - 1) * Fnconds + Fnphases - 1]; + } + break; // Delta + case delta: + { + jphase = RotatePhases(iPhase); // Get next phase in sequence + (VTerm)[i - 1] = (Vterminal)[iPhase + (iWind - 1) * Fnconds - 1]; + (VTerm)[i + 1 - 1] = (Vterminal)[jphase + (iWind - 1) * Fnconds - 1]; + } + break; // Series Winding + case SERIES: + { + (VTerm)[i - 1] = (Vterminal)[iPhase + (iWind - 1) * Fnconds - 1]; + (VTerm)[i + 1 - 1] = (Vterminal)[iPhase + Fnphases - 1]; + } + break; + default: + ; + break; + } /*CASE*/ + } + Y_Term->MVmult(iTerm, VTerm); // ITerm = Y_Term Vterm + Y_Term_NL->MVmult(ITerm_NL, VTerm);// no load part + // Add into Currbuffer + for(int stop1 = 2 * NumWindings, i = 1; i <= stop1; i++) + { + k = k + 1; + (CurrBuffer)[k - 1] = cadd((iTerm)[i - 1], (ITerm_NL)[i - 1]); + } + } + VTerm = (pComplexArray) realloc(VTerm, 0); + iTerm = (pComplexArray) realloc(iTerm, 0); + ITerm_NL = (pComplexArray) realloc(ITerm_NL, 0); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error filling voltage buffer in GetAllWindingCurrents for Circuit Element:AutoTrans.") + get_Name() + + CRLF + + "Probable Cause: Invalid definition of element." + + CRLF + + "System Error Message: " + + (std::string) e.what(), 100115); + } +} + +// Returns string mag, angle + +String TAutoTransObj::GeTAutoWindingCurrentsResult(int ActorID) +{ + String result; + pComplexArray WindingCurrents = nullptr; + int i = 0; + int j = 0; + int k = 0; + int stop = 0; + WindingCurrents = new complex[ 2 * Fnphases * NumWindings]; + GetAllWindingCurrents(WindingCurrents, ActorID); + result = ""; + k = 0; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = NumWindings, j = 1; j <= stop1; j++) + { + k = k + 1; + result = result + + Format("%.7g, (%.5g), ", cabs((WindingCurrents)[k - 1]), cdang((WindingCurrents)[k - 1])); + k = k + 1; + // Skip currents from other end of the winding + } + } + free(WindingCurrents); // throw away temp array + return result; +} + +// Voltages across indicated winding +// Fill Vbuffer array which must be adequately allocated by calling routine +// Order is Number of Phases + +void TAutoTransObj::GetAutoWindingVoltages(int iWind, pComplexArray VBuffer, int ActorID) +{ + int i = 0; + int II = 0; + int k = 0; + int NeutTerm = 0; + try + + + /*return Zero if winding number improperly specified*/ + { + int stop = 0; + if((iWind < 1) || (iWind > NumWindings)) + { + int stop = 0; + for(int stop = Fnconds, i = 1; i <= stop; i++) + { + (VBuffer)[i - 1] = CZero; + } + return; + } + + /*Load up VTerminal - already allocated for all cktelements*/ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(int stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + (Vterminal)[i - 1] = with0->NodeV[(NodeRef)[i - 1]]; + else + (Vterminal)[i - 1] = with0->VoltInActor1((NodeRef)[i - 1]); + } + } + k = (iWind - 1) * Fnconds; // Offset for winding + NeutTerm = Fnphases + k + 1; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + switch((WINDING_)[iWind - 1].Connection) + { + case WYE: // Wye + { + (VBuffer)[i - 1] = csub((Vterminal)[i + k - 1], (Vterminal)[NeutTerm - 1]); + } + break; // Delta + case delta: + { + II = RotatePhases(i); // Get next phase in sequence + (VBuffer)[i - 1] = csub((Vterminal)[i + k - 1], (Vterminal)[II + k - 1]); + } + break; // Series (winding 1) + case SERIES: + { + (VBuffer)[i - 1] = csub((Vterminal)[i + k - 1], (Vterminal)[i + Fnconds - 1]); + } + break; + default: + ; + break; + } + } /*CASE*/ + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error filling voltage buffer in GeTAutoWindingVoltages for Circuit Element:AutoTrans.") + get_Name() + + CRLF + + "Probable Cause: Invalid definition of element." + + CRLF + + "System Error Message: " + + (std::string) e.what(), 100114); + } +} + +double TAutoTransObj::Get_BaseVoltage(int i) +{ + double result = 0.0; + if((i < 1) || (i > NumWindings)) + result = (WINDING_)[1 - 1].VBase; + else + result = (WINDING_)[i - 1].VBase; + return result; +} + +/*============================== GetLosses Override ===============================*/ + +void TAutoTransObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int j = 0; + int stop = 0; + inherited::GetCurrents(Curr, ActorID); + + // Combine Series (wdg 1) and Common winding (2) Currents to get X Terminal Currents + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + caccum((Curr)[i + Fnconds - 1], (Curr)[i + Fnphases - 1]); + } +} + +void TAutoTransObj::GetLosses(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID) +{ + pComplexArray cTempIterminal = nullptr; + int i = 0; + /*inherited;*/ + + /*Calculates losses in watts, vars*/ + int stop = 0; + TotalLosses = Get_Losses(ActorID); // Side effect: computes Iterminal + + /*Compute No load losses in Yprim_Shunt*/ + cTempIterminal = new complex[Yorder]; + ComputeVterminal(ActorID); + YPrim_Shunt->MVmult(cTempIterminal, &(Vterminal[0])); + /*No Load Losses are sum of all powers coming into YPrim_Shunt from each terminal*/ + NoLoadLosses = CZero; + for(int stop = Yorder, i = 1; i <= stop; i++) + { + caccum(NoLoadLosses, cmul((Vterminal)[i - 1], conjg((cTempIterminal)[i - 1]))); + } + LoadLosses = csub(TotalLosses, NoLoadLosses); + cTempIterminal = (pComplexArray) realloc(cTempIterminal, 0); +} + +/* gets the property for the active winding ; Set the active winding before calling*/ + +String TAutoTransObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + switch(Index) + { + case 12: case 13: case 14: case 15: case 16: + case 20: + case 37: + result = "["; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 1: + result = IntToStr(Get_NPhases()); + break; + case 2: + result = IntToStr(NumWindings); + break; + case 3: + result = IntToStr(ActiveWinding); + break; // return active winding + case 4: + result = GetBus(ActiveWinding); + break; // return bus spec for active winding + case 5: + switch((WINDING_)[ActiveWinding - 1].Connection) + { + case 0: + result = "wye "; + break; + case 1: + result = "Delta "; + break; + case 2: + result = "Series"; + break; + default: + ; + break; + } + break; + case 6: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].kVLL); + break; + case 7: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].kVA); + break; + case 8: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].puTap); + break; + case 9: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].Rpu * 100.0); + break; // %R + case 10: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].RdcOhms); + break; + case 11: + switch(CoreType) + { + case 0: + result = "shell"; + break; + case 1: + result = "1-phase"; + break; + case 3: + result = "3-leg"; + break; + case 5: + result = "5-Leg"; + break; + default: + ; + break; + } + break; + case 12: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + GetBus(i) + ", "; + } + break; + case 13: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + switch((WINDING_)[i - 1].Connection) + { + case 0: + result = result + "wye, "; + break; + case 1: + result = result + "delta, "; + break; + case 2: + result = result + "Series, "; + break; + default: + ; + break; + } + } + break; + case 14: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", (WINDING_)[i - 1].kVLL); + } + break; + case 15: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", (WINDING_)[i - 1].kVA); + } + break; + case 16: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", (WINDING_)[i - 1].puTap); + } + break;// InterpretAllTaps(Param); + case 17: + result = Format("%.7g", puXHX * 100.0); + break; + case 18: + result = Format("%.7g", puXHT * 100.0); + break; + case 19: + result = Format("%.7g", puXXT * 100.0); + break; + case 20: + for(int stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", (puXSC)[i - 1] * 100.0); + } + break;// Parser.ParseAsVector(((NumWindings - 1)*NumWindings div 2), Xsc); + case 26: + result = Format("%.7g", pctLoadLoss); + break; + case 27: + result = Format("%.7g", pctNoLoadLoss); + break; + case 28: + result = Format("%.7g", NormMaxHkVA); + break; + case 29: + result = Format("%.7g", EmergMaxHkVA); + break; + case 31: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].MaxTap); + break; + case 32: + result = Format("%.7g", (WINDING_)[ActiveWinding - 1].MinTap); + break; + case 33: + result = Format("%-d", (WINDING_)[ActiveWinding - 1].NumTaps); + break; + case 35: + result = Format("%.7g", pctImag); + break; + case 36: + result = Format("%.7g", ppm_FloatFactor / 1.0e-6); + break; + case 37: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", (WINDING_)[i - 1].Rpu * 100.0); + } + break; + case 40: + if(XRConst) + result = "YES"; + else + result = "NO"; + break; + case 42: + result = GeTAutoWindingCurrentsResult(ActiveActor); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + + // Overrides + switch((Index - NumPropsThisClass)) + { + case 1: + result = Format("%-.5g", NormAmps); + break; //Normamps + case 2: + result = Format("%-.5g", EmergAmps); + break; //emergamps + default: + ; + break; + } + switch(Index) + { + case 12: case 13: case 14: case 15: case 16: + case 20: + case 37: + result = result + "]"; + break; + default: + ; + break; + } + return result; +} + +void TAutoTransObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,"2"); //'windings'; + // Winding Definition + Set_PropertyValue(3,"1"); //'wdg'; + Set_PropertyValue(4,GetBus(1)); //'bus'; + Set_PropertyValue(5,"Series"); // 'conn'; + Set_PropertyValue(6,"115"); // IF 2or 3-phase: phase-phase ELSE actual winding + Set_PropertyValue(7,"100000"); + Set_PropertyValue(8,"1.0"); + Set_PropertyValue(9,"0.2"); + Set_PropertyValue(10,"0.2645"); // 0.002 pu @ 115 kV, 100 MVA + Set_PropertyValue(11,"shell"); + + // General Data + Set_PropertyValue(12,""); + Set_PropertyValue(13,""); + Set_PropertyValue(14,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(15,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(16,""); + Set_PropertyValue(17,"7"); + Set_PropertyValue(18,"35"); + Set_PropertyValue(19,"30"); + Set_PropertyValue(20,""); // x12 13 14... 23 24.. 34 .. + Set_PropertyValue(21,"2"); + Set_PropertyValue(22,".8"); + Set_PropertyValue(23,".8"); + Set_PropertyValue(24,"65"); + Set_PropertyValue(25,"15"); + Set_PropertyValue(26,Format("%.7g", pctLoadLoss)); + Set_PropertyValue(27,Format("%.7g", pctNoLoadLoss)); // Defaults to zero + Set_PropertyValue(28,""); + Set_PropertyValue(29,""); + Set_PropertyValue(30,"n"); // =y/n + Set_PropertyValue(31,"1.10"); + Set_PropertyValue(32,"0.90"); + Set_PropertyValue(33,"32"); + Set_PropertyValue(34,""); + Set_PropertyValue(35,"0"); + Set_PropertyValue(36,"1"); + Set_PropertyValue(37,""); + Set_PropertyValue(38,""); + Set_PropertyValue(39,""); + Set_PropertyValue(40,"NO"); + Set_PropertyValue(41,"Lag"); + Set_PropertyValue(42,"0"); + inherited::InitPropertyValues(NumPropsThisClass); + + // Override some Inherited properties + Set_PropertyValue(NumPropsThisClass + 1,"400"); //Normamps + Set_PropertyValue(NumPropsThisClass + 2,"600"); //emergamps + Set_PropertyValue(NumPropsThisClass + 3,"0.007"); //Fault rate + Set_PropertyValue(NumPropsThisClass + 4,"100"); // Pct Perm + Set_PropertyValue(NumPropsThisClass + 5,"36"); // Hrs to repair + ClearPropSeqArray(); // so the overrides don't show up on save +} +// For Delta connections or Line-Line voltages + +int TAutoTransObj::RotatePhases(int iPhs) +{ + int result = 0; + result = iPhs + DeltaDirection; + + // make sure result is within limits + if(Fnphases > 2) + // Assumes 2 phase delta is open delta + { + if(result > Fnphases) + result = 1; + if(result < 1) + result = Fnphases; + } + else + { + if(result < 1) + result = 3; // For 2-phase delta, next phase will be 3rd phase + } + return result; +} +/* + Converts default 3-phase AutoTrans model into equivalent positive-sequence + using scripting +*/ + +void TAutoTransObj::MakePosSequence(int ActorID) +{ + int IW = 0; + int i = 0; + int n = 0; + String s; + int Nodes[50/*# range 1..50*/]; // big integer buffer + bool OnPhase1 = false; + + /*Get_First(), determine if we can convert this one.*/ + int stop = 0; + if((Fnphases == 1) || (Fnphases == 2)) //disable if any terminal not connected to phase one + { + int stop = 0; + for(int stop = NumWindings, IW = 1; IW <= stop; IW++) + { + int stop1 = 0; + OnPhase1 = false; + /*Load up auxiliary parser*/ + AuxParser[ActorID]->SetCmdString(GetBus(IW)); + String dummy = AuxParser[ActorID]->GetNextParam(); + s = AuxParser[ActorID]->ParseAsBusName(n, (pIntegerArray) &Nodes, ActorID); + if(n == 0) + OnPhase1 = true; + for(int stop1 = n, i = 1; i <= stop1; i++) + { + if(Nodes[i - 1] == 1) + OnPhase1 = true; + } + if(!OnPhase1) + { + Set_Enabled(false); // We won't use this one + return; + } + } + } + + /*Construct AutoTrans definition string */ + s = "Phases=1 Conns=("; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + s = s + "Wye "; + } + s = s + ") buses=("; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + s = s + GetBus(i) + " "; + } + s = s + ") kVS=("; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if((Get_NPhases() > 1) || ((WINDING_)[i - 1].Connection != WYE)) + s = s + Format(" %-.5g", (WINDING_)[i - 1].kVLL / SQRT3); + else + s = s + Format(" %-.5g", (WINDING_)[i - 1].kVLL); + } + } + s = s + ") kVAs=("; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + s = s + Format(" %-.5g", (WINDING_)[i - 1].kVA / Fnphases); + } + } + s = s + ")"; + s = s + + " NormHkVA=" + + Format(" %-.5g %-.5g", NormMaxHkVA / Fnphases, EmergMaxHkVA / Fnphases); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + +void TAutoTransObj::BuildYPrimComponent(TcMatrix* YPrim_Component, TcMatrix* Y_Terminal) +{ + int NW2 = 0; + int i = 0; + int k = 0; + complex Value = {}; + int j = 0; + /*# with YPrim_Component do */ + { + auto with0 = YPrim_Component; + /* Now, Put in Yprim matrix */ + /*have to add every element of Y_terminal into Yprim somewhere*/ + int stop = 0; + NW2 = 2 * NumWindings; + for (i = 1; i <= NW2; i++) + { + int stop1 = 0; + for (j = 1; j <= i; j++) + { + int stop2 = 0; + Value = Y_Terminal->GetElement(i, j); + // This value goes in Yprim nphases times + for (k = 0; k < Fnphases; k++) + { + with0->AddElemsym((TermRef)[i + k * NW2 - 1], (TermRef)[j + k * NW2 - 1], Value); + } + } + } + } +} + +double TAutoTransObj::Get_BasekVLL(int i) +{ + double result = 0.0; + result = (WINDING_)[i - 1].kVLL; + return result; +} +// Build YTerminal considering only resistance and no coupling to other winding. + +void TAutoTransObj::GICBuildYTerminal() +{ + int i = 0; + int j = 0; + int Idx = 0; + complex Yr = {}; + TTextRec f = {}; + complex Yadder = {}; + int stop = 0; + Y_Term->Clear(); + Y_Term_NL->Clear(); + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + Yr = cmplx(1.0 / ((WINDING_)[i - 1].RdcOhms), 0.0); // convert to Siemens + /*# with Y_Term do */ + { + auto with0 = Y_Term; + Idx = 2 * i - 1; + with0->SetElement(Idx, Idx, Yr); + with0->SetElement(Idx + 1, Idx + 1, Yr); + with0->SetElemsym(Idx, Idx + 1, cnegate(Yr)); // set off-diagonals + } + } + + /*For GIC add a small *Conductance* to both conductors of each winding so that + the matrix will always invert even if the user neglects to define a voltage + reference on all sides*/ + if(ppm_FloatFactor != 0.0) + /*# with Y_Term do */ + { + auto with1 = Y_Term; + int stop = 0; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + Yadder = cmplx(-(WINDING_)[i - 1].Y_PPM, 0.0); // G + j0 + for(int stop1 = (2 * i), j = (2 * i - 1); j <= stop1; j++) + { + with1->SetElement(j, j, cadd(with1->GetElement(j, j), Yadder)); + } +/* SetElement(j, j, CmulReal_im(GetElement(j, j) , ppm_FloatFactorPlusOne));*/ + } + } +} + +void TAutoTransObj::CalcY_Terminal(double FreqMult, int ActorID) +{ + int i = 0; + int j = 0; + int k = 0; + vector A; + vector ctempArray1; + vector ctempArray2; + complex cMinusOne = CZero; + TcMatrix* At = nullptr; + complex Yadder = CZero; + double Rmult = 0.0; + double ZCorrected = 0.0; + double puXst, Vs, Vc; + /*Function to fix a specification of a pu tap of 0.0*/ + /*Regcontrol can attempt to force zero tap position in some models*/ + + auto ZeroTapFix = [&](double tapvalue) -> double + { + double result = 0.0; + if(tapvalue == 0.0) + result = 0.0001; + else + result = tapvalue; + return result; + }; + + // check for GIC build + if(ActiveCircuit[ActorID]->Solution->get_FFrequency() < 0.51) + /*Build Yterminal for GIC ~dc simulation*/ + GICBuildYTerminal(); + else + /*Normal Y matrix build*/ + { + int stop = 0; + if(XRConst) + Rmult = FreqMult; + else + Rmult = 1.0; + + + // Construct ZBMatrix; + ZB->Clear(); + ZBase = 1.0L / (VABase / Fnphases); // base ohms on 1.0 volt basis + // Adjust specified XSC by SQR(1 + Vcommon/Vseries) + ZCorrected = ZBase * Sqr(1.0 + (WINDING_)[2 - 1].VBase / (WINDING_)[1 - 1].VBase); // Correction factor for Series + // since the losses are correct as they are, mimic Dommel (6.50) for Zst or puXSC[2], without disturbing Zbase or Zcorrected + // Dommel: Xst = Xhl*Vh*Vl/(Vh-Vl)^2 + Xht*Vh/(Vh-Vl) - Xlt*Vl/(Vh-Vl) + // = Xhl*(Vs+Vc)*Vc/Vs^2 + Xht*(Vs+Vc)/Vs - Xlt*Vc/Vs + if (NumWindings > 2) + { + Vc = WINDING_[2 - 1].VBase; + Vs = WINDING_[1 - 1].VBase; + puXst = puXSC[1 - 1] * (Vs + Vc) * Vc / Vs / Vs + puXSC[2 - 1] * (Vs + Vc) / Vs - puXSC[3 - 1] * Vc / Vs; + } + else + { + puXst = 0.0; + } + + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + /* convert pu to ohms on one volt base as we go... */ + if(i == 1) + ZB->SetElement(i, i, cmulreal(cmplx(Rmult * ((WINDING_)[1 - 1].Rpu + (WINDING_)[i + 1 - 1].Rpu), FreqMult * (puXSC)[i - 1]), ZCorrected)); + else if (i == 2) + ZB->SetElement(i, i, cmulreal(cmplx(Rmult * ((WINDING_)[1 - 1].Rpu + (WINDING_)[i + 1 - 1].Rpu), FreqMult * puXst), ZBase)); + else + ZB->SetElement(i, i, cmulreal(cmplx(Rmult * ((WINDING_)[1 - 1].Rpu + (WINDING_)[i + 1 - 1].Rpu), FreqMult * (puXSC)[i - 1]), ZBase)); + } + + // Off diagonals + k = NumWindings; + /*# with ZB do */ + { + auto with0 = ZB; + int stop = 0; + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = NumWindings - 1, j = i + 1; j <= stop1; j++) + { + with0->SetElemsym(i, j, cmulreal(csub(cadd(with0->GetElement(i, i), with0->GetElement(j, j)), cmulreal(cmplx(Rmult * ((WINDING_)[i + 1 - 1].Rpu + (WINDING_)[j + 1 - 1].Rpu), FreqMult * (puXSC)[k - 1]), ZBase)), 0.5)); + ++k; + } + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + ZB->Invert(); // mhos on one volt base + if(ZB->InvertError > 0) + { + int stop = 0; + DoErrorMsg("TAutoTransObj.CalcYPrim", String("Matrix Inversion Error for AutoTrans \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with tiny conductance to ground.", 117); + ZB->Clear(); + for(int stop = ZB->get_Norder(), i = 1; i <= stop; i++) + { + ZB->SetElement(i, i, cmplx(EPSILON, 0.0)); + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + + // Now construct Y_Oneturn = AT * ZB.Invert * A + /* -1 1 0 ... + A = -1 0 1 .. order: N-1 x N N = NumWindings + ... + -1 -1 ... + AT = Transpose of A = 1 0 ... N X N-1 + 0 1 .. + */ + Y_1Volt->Clear(); + Y_1Volt_NL->Clear(); + + /*Allocate temp complex arrays*/ + ctempArray1.resize(NumWindings * 2); + ctempArray2.resize(NumWindings * 2); + A.resize(NumWindings * 2); + cMinusOne = cmplx(-1.0, 0.0); + At = new TcMatrix(NumWindings); + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + At->SetElement(i + 1, i, cONE); + } + for(int stop = NumWindings - 1, i = 1; i <= stop; i++) + { + At->SetElement(1, i, cMinusOne); + } + (ctempArray1)[NumWindings - 1] = CZero; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + if(i == 1) + { + int stop1 = 0; + for(int stop1 = NumWindings - 1, k = 1; k <= stop1; k++) + { + (A)[k - 1] = cMinusOne; + } + } + else + { + int stop1 = 0; + for(int stop1 = NumWindings - 1, k = 1; k <= stop1; k++) + { + if(k == (i - 1)) + (A)[k - 1] = cONE; + else + (A)[k - 1] = CZero; + } + } + ZB->MVmult(&ctempArray1[0], &A[0]); /*Zb.invert * A*/ + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for (j = 1; j <= NumWindings; j++) + { + Y_1Volt->SetElement(j, i, (ctempArray2)[j - 1]); + } + } + + /*Add magnetizing Reactance to 2nd winding, assuming it is closest to the core + Add both resistive element representing core losses and a reactive element representing + magnetizing current + */ + Y_1Volt_NL->AddElement(2, 2, cmplx((pctNoLoadLoss / 100.0 / ZBase), -pctImag / 100.0 / ZBase / FreqMult)); + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + // should have admittance of one phase of the AutoTrans on a one-volt, wye-connected base + + // Now make into terminal admittance matrix and correct for actual voltage ratings + // Y_Terminal = AT * Y_onevolt * A where V_onevolt = A * V_terminal + delete At; + Y_Term->Clear(); + Y_Term_NL->Clear(); + At = new TcMatrix(NumWindings * 2); + + // 8/22/2013 Added ZeroTapFix so that regcontrol can set a tap to zero + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + At->SetElement(2 * i - 1, i, cmplx(1.0 / ((WINDING_)[i - 1].VBase * ZeroTapFix((WINDING_)[i - 1].puTap)), 0.0)); + } + } + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + At->SetElement(2 * i, i, cmplx(-1.0 / ((WINDING_)[i - 1].VBase * ZeroTapFix((WINDING_)[i - 1].puTap)), 0.0)); + } + } + for(int stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + (ctempArray1)[i - 1] = CZero; + } + for(int stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = NumWindings, k = 1; k <= stop1; k++) + { + /*# with WINDING^[k] do */ + { + + if(i == (2 * k - 1)) + (A)[k - 1] = cmplx((1.0 / ((WINDING_)[k - 1].VBase * ZeroTapFix((WINDING_)[k - 1].puTap))), 0.0); + else + { + if(i == 2 * k) + (A)[k - 1] = cmplx((-1.0 / ((WINDING_)[k - 1].VBase * ZeroTapFix((WINDING_)[k - 1].puTap))), 0.0); + else + (A)[k - 1] = CZero; + } + } + } + /*Main AutoTrans part*/ + Y_1Volt->MVmult(&ctempArray1[0], &A[0]); + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for(int stop1 = 2 * NumWindings, j = 1; j <= stop1; j++) + { + Y_Term->SetElement(j, i, (ctempArray2)[j - 1]); + } + /*No Load part*/ + Y_1Volt_NL->MVmult(&ctempArray1[0], &A[0]); + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for(int stop1 = 2 * NumWindings, j = 1; j <= stop1; j++) + { + Y_Term_NL->SetElement(j, i, (ctempArray2)[j - 1]); + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + + /*Add a small Admittance to both conductors of each winding so that + the matrix will always invert even if the user neglects to define a voltage + reference on all sides*/ + if(ppm_FloatFactor != 0.0) + /*# with Y_Term do */ + { + auto with4 = Y_Term; + int stop = 0; + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + Yadder = cmplx(0.0, (WINDING_)[i - 1].Y_PPM); + for(int stop1 = (2 * i), j = (2 * i - 1); j <= stop1; j++) + { + with4->SetElement(j, j, cadd(with4->GetElement(j, j), Yadder)); + } +/* SetElement(j, j, CmulReal_im(GetElement(j, j) , ppm_FloatFactorPlusOne));*/ + } + } + +/*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + delete At; + } + Y_Terminal_Freqmult = FreqMult; +} +// Uses strandard Xfmrcode, but forces connection of first two windings. + +void TAutoTransObj::FetchXfmrCode(const String Code) +{ + TXfmrCodeObj* Obj = nullptr; + int i = 0; + if(XfmrCodeClass == nullptr) + XfmrCodeClass = (TXfmrCode*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("xfmrcode")); + if(XfmrCodeClass->SetActive(Code)) + { + int stop = 0; + Obj = ((TXfmrCodeObj*) XfmrCodeClass->GetActiveObj()); + XfmrCode = LowerCase(Code); + // set sizes and copy parameters + Set_NPhases(Obj->Fnphases); + SetNumWindings(Obj->NumWindings); + Set_Nconds(Fnphases + 1); // forces reallocation of terminals and conductors + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + switch(i) + { + case 1: + (WINDING_)[i - 1].Connection = SERIES; + break; // No Choice for 1st two + case 2: + (WINDING_)[i - 1].Connection = WYE; + break; // Wye + default: + (WINDING_)[i - 1].Connection = Obj->WINDING_[i - 1].Connection; + break; + } + (WINDING_)[i - 1].kVLL = Obj->WINDING_[i - 1].kVLL; + (WINDING_)[i - 1].VBase = Obj->WINDING_[i - 1].VBase; + (WINDING_)[i - 1].kVA = (double) Obj->WINDING_[i - 1].kVA; + (WINDING_)[i - 1].puTap = Obj->WINDING_[i - 1].puTap; + (WINDING_)[i - 1].Rpu = Obj->WINDING_[i - 1].Rpu; + (WINDING_)[i - 1].RdcOhms = Obj->WINDING_[i - 1].RdcOhms; + (WINDING_)[i - 1].RdcSpecified = true; //This will force calc of Rdcpu + (WINDING_)[i - 1].TapIncrement = Obj->WINDING_[i - 1].TapIncrement; + (WINDING_)[i - 1].MinTap = Obj->WINDING_[i - 1].MinTap; + (WINDING_)[i - 1].MaxTap = Obj->WINDING_[i - 1].MaxTap; + (WINDING_)[i - 1].NumTaps = Obj->WINDING_[i - 1].NumTaps; + } + } + SetTermRef(); + puXHX = Obj->XHL; + puXHT = Obj->XHT; + puXXT = Obj->XLT; + for(int stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + (puXSC)[i - 1] = (Obj->XSC)[i - 1]; + } + ThermalTimeConst = Obj->ThermalTimeConst; + n_thermal = Obj->n_thermal; + m_thermal = Obj->m_thermal; + FLrise = Obj->FLrise; + HSrise = Obj->HSrise; + pctLoadLoss = Obj->pctLoadLoss; + pctNoLoadLoss = Obj->pctNoLoadLoss; + pctImag = Obj->pctImag; // Omission corrected 12-14-18 + NormMaxHkVA = Obj->NormMaxHkVA; + EmergMaxHkVA = Obj->EmergMaxHkVA; + ppm_FloatFactor = Obj->ppm_FloatFactor; + Yorder = Fnconds * Fnterms; + Set_YprimInvalid(ActiveActor,true); + Y_Terminal_Freqmult = 0.0; + RecalcElementData(ActiveActor); + } + else + DoSimpleMsg(String("Xfmr Code:") + Code + " not found.", 100180); +} + + + + +} // namespace AutoTrans + diff --git a/OpenDSSC/PDElements/AutoTrans.h b/OpenDSSC/PDElements/AutoTrans.h new file mode 100644 index 0000000..cfd69f3 --- /dev/null +++ b/OpenDSSC/PDElements/AutoTrans.h @@ -0,0 +1,207 @@ +#ifndef AutoTransH +#define AutoTransH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "ParserDel.h" +#include "Arraydef.h" + + + + +namespace AutoTrans +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change log + 7-14-2018 Created from Transformer + 9-19-2018 committed + 12-4-2018 Corrected indices for mapping into Yprim + 1-3-2019 Default last nphase nodes of X terminal (2) to same as first neutral node + 3-6-2021 Added code for readability +*/ + +/* You can designate a AutoTrans to be a substation by setting the sub=yes parameter*/ + +class TAutoTrans : public PDClass::TPDClass +{ + friend class TAutoTransObj; +public: + typedef PDClass::TPDClass inherited; +private: + void SetActiveWinding(int W); + void InterpretAutoConnection(const String s); + void InterpretAllConns(const String s); + void InterpretAllBuses(const String s, int ActorID); + void InterpretAllTaps(const String s); + void InterpretAllkVRatings(const String s); + void InterpretAllkVARatings(const String s); + void InterpretAllRs(const String s); + double TrapZero(double Value, double DefaultValue); + bool InterpretLeadLag(const String s); + + /*PROCEDURE MakeNewBusNameForNeutral(Var NewBusName:String; Nphases:Integer);*/ +protected: + void DefineProperties(); + virtual int MakeLike(const String AutoTransfName); +public: + TAutoTrans(); + virtual ~TAutoTrans(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TAutoWinding +{ +public: + int Connection; + double kVLL; + double VBase; + double kVA; + double puTap; + double Rpu; // on AutoTrans MVABase (H-X Rating) + double Rdcpu; // on AutoTrans MVABase (H-X Rating) + double RdcOhms; // for GIC solutions; default to 85% of Rpu + bool RdcSpecified; + double Y_PPM; // Anti Float reactance adder + + /*Tap Changer Data*/ + double TapIncrement; + double MinTap; + double MaxTap; + int NumTaps; + void ComputeAntiFloatAdder(double PPM_Factor, double VABase1ph); + TAutoWinding(int iWinding); + TAutoWinding(); +}; + +class TAutoTransObj : public PDELement::TPDElement +{ + friend class TAutoTrans; +public: + typedef PDELement::TPDElement inherited; +//private: + int DeltaDirection; + double ppm_FloatFactor; // parts per million winding float factor + double pctImag; + bool XRConst; + double Get_PresentTap(int i, int ActorID); + void Set_PresentTap(int i, int ActorID, double Value); + double Get_MinTap(int i); + double Get_MaxTap(int i); + double Get_TapIncrement(int i); + double Get_BaseVoltage(int i); + double Get_BasekVLL(int i); + // CIM accessors + int Get_NumTaps(int i); + double Get_WdgResistance(int i); + int Get_WdgConnection(int i); + double Get_WdgkVA(int i); + double Get_Xsc(int i); + double Get_WdgYPPM(int i); + void CalcY_Terminal(double FreqMult, int ActorID); + void GICBuildYTerminal(); + void BuildYPrimComponent(Ucmatrix::TcMatrix* YPrim_Component, Ucmatrix::TcMatrix* Y_Terminal); + void FetchXfmrCode(const String Code); + String GeTAutoWindingCurrentsResult(int ActorID); + void SetBusAuto(int iwdg, const String s, int ActorID); +protected: + int NumWindings; + int MaxWindings; + std::vector TermRef; // keeps track of terminal connections + double puXHX; + double puXHT; + double puXXT; // per unit + double ZBase; + std::vector puXSC; // per unit SC measurements + double VABase; // FOR impedances + double kVSeries; // Rating for Series winding + Ucmatrix::TcMatrix* ZB; + Ucmatrix::TcMatrix* Y_1Volt; + Ucmatrix::TcMatrix* Y_Term; + Ucmatrix::TcMatrix* Y_1Volt_NL; // No Load Y's + Ucmatrix::TcMatrix* Y_Term_NL; + double Y_Terminal_Freqmult; + double NormMaxHkVA; + double EmergMaxHkVA; + double ThermalTimeConst; /*hr*/ + double n_thermal; + double m_thermal; /*Exponents*/ + double FLrise; + double HSrise; + bool HVLeadsLV; + bool XHXChanged; + void SetTermRef(); +public: + double pctLoadLoss; + double pctNoLoadLoss; + int ActiveWinding; // public for COM interface + bool IsSubstation; + String SubstationName; + std::vector WINDING_; + String XfmrBank; + String XfmrCode; + int CoreType; /*0=Shell; 1=1ph; 3-3leg; 5=5-leg*/ + String strCoreType; + TAutoTransObj(DSSClass::TDSSClass* ParClass, const String TransfName); + virtual ~TAutoTransObj(); + void SetNumWindings(int n); + virtual void RecalcElementData(int ActorID); + virtual void SetNodeRef(int iTerm, Arraydef::pIntegerArray NodeRefArray); + virtual void CalcYPrim(int ActorID); + + /*GetLosses override for AutoTrans*/ + virtual void GetLosses(Ucomplex::complex& TotalLosses, Ucomplex::complex& LoadLosses, Ucomplex::complex& NoLoadLosses, int ActorID); + /*Getcurrents Override for AutoTrans*/ + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present values of terminal + int RotatePhases(int iPhs); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + void GetAutoWindingVoltages(int iWind, Ucomplex::pComplexArray VBuffer, int ActorID); + void GetAllWindingCurrents(Ucomplex::pComplexArray CurrBuffer, int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + + int get_NumWindings(); + + // CIM accessors + TAutoTransObj(DSSClass::TDSSClass* ParClass); + TAutoTransObj(String ClassName); + TAutoTransObj(); +}; +extern TAutoTransObj* ActiveAutoTransObj; +extern TAutoTrans* AutoTransClass; + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +} // namespace AutoTrans + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace AutoTrans; +#endif + +#endif // AutoTransH + + + + diff --git a/OpenDSSC/PDElements/Capacitor.cpp b/OpenDSSC/PDElements/Capacitor.cpp new file mode 100644 index 0000000..efb0b42 --- /dev/null +++ b/OpenDSSC/PDElements/Capacitor.cpp @@ -0,0 +1,1383 @@ + +#pragma hdrstop + +#include "Capacitor.h" + +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PDClass; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace Utilities; + +namespace Capacitor +{ + +TCapacitorObj::TCapacitorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TCapacitorObj::TCapacitorObj(String ClassName) : inherited(ClassName) {} +TCapacitorObj::TCapacitorObj() {} + + +TCapacitorObj* ActiveCapacitorObj = nullptr; +TCapacitor* CapacitorClass = nullptr; +const int NumPropsThisClass = 13; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Capacitor objects + +TCapacitor::TCapacitor() +{ + ; + Class_Name = "Capacitor"; + DSSClassType = DSSClassType + CAP_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + CapacitorClass = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TCapacitor::~TCapacitor() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapacitor::DefineProperties() +{ + NumProperties = NumPropsThisClass; + inherited::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "bus2"; + PropertyName[3 - 1] = "phases"; + PropertyName[4 - 1] = "kvar"; + PropertyName[5 - 1] = "kv"; + PropertyName[6 - 1] = "conn"; + PropertyName[7 - 1] = "cmatrix"; + PropertyName[8 - 1] = "cuf"; + PropertyName[9 - 1] = "R"; + PropertyName[10 - 1] = "XL"; + PropertyName[11 - 1] = "Harm"; + PropertyName[12 - 1] = "Numsteps"; + PropertyName[13 - 1] = "states"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of first bus of 2-terminal capacitor. Examples:") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3" + + CRLF + + CRLF + + "If only one bus specified, Bus2 will default to this bus, Node 0, " + + "and the capacitor will be a Yg shunt bank."; + PropertyHelp[2 - 1] = String("Name of 2nd bus. Defaults to all phases connected " "to first bus, node 0, (Shunt Wye Connection) " "except when Bus2 explicitly specified. ") + CRLF + + CRLF + + "Not necessary to specify for delta (LL) connection."; + PropertyHelp[3 - 1] = "Number of phases."; + PropertyHelp[4 - 1] = "Total kvar, if one step, or ARRAY of kvar ratings for each step. Evenly divided among phases. See rules for NUMSTEPS."; + PropertyHelp[5 - 1] = "For 2, 3-phase, kV phase-phase. Otherwise specify actual can rating."; + PropertyHelp[6 - 1] = "={wye | delta |LN |LL} Default is wye, which is equivalent to LN"; + PropertyHelp[7 - 1] = String("Nodal cap. matrix, lower triangle, microfarads, of the following form:") + CRLF + + CRLF + + "cmatrix=\"c11 | -c21 c22 | -c31 -c32 c33\"" + + CRLF + + CRLF + + "All steps are assumed the same if this property is used."; + PropertyHelp[8 - 1] = String("ARRAY of Capacitance, each phase, for each step, microfarads.") + CRLF + + "See Rules for NumSteps."; + PropertyHelp[9 - 1] = "ARRAY of series resistance in each phase (line), ohms. Default is 0.0"; + PropertyHelp[10 - 1] = "ARRAY of series inductive reactance(s) in each phase (line) for filter, ohms at base frequency. Use this OR \"h\" property to define filter. Default is 0.0."; + PropertyHelp[11 - 1] = "ARRAY of harmonics to which each step is tuned. Zero is interpreted as meaning zero reactance (no filter). Default is zero."; + PropertyHelp[12 - 1] = "Number of steps in this capacitor bank. Default = 1. Forces reallocation of the capacitance, reactor, and states array. Rules: " + "If this property was previously =1, the value in the kvar property is divided equally among the steps. The kvar property " + "does not need to be reset if that is accurate. If the Cuf or Cmatrix property was used previously, all steps are set to the value of the first step. " + "The states property is set to all steps on. All filter steps are set to the same harmonic. " + "If this property was previously >1, the arrays are reallocated, but no values are altered. You must SUBSEQUENTLY assign all array properties."; + PropertyHelp[13 - 1] = "ARRAY of integers {1|0} states representing the state of each step (on|off). Defaults to 1 when reallocated (on). " + "Capcontrol will modify this array as it turns steps on or off."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + PropertyHelp[NumPropsThisClass] = PropertyHelp[NumPropsThisClass] + " Defaults to 135 % of per - phase rated current."; + PropertyHelp[NumPropsThisClass + 1] = PropertyHelp[NumPropsThisClass + 1] + " Defaults to 180 % of per - phase rated current."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TCapacitor::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + with0->Set_ActiveCktElement(new TCapacitorObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapacitor::DoCmatrix(int ActorID) +{ + int OrderFound = 0; + int j = 0; + pDoubleArray MatBuffer = nullptr; + /*# with ActiveCapacitorObj do */ + { + auto with0 = ActiveCapacitorObj; + MatBuffer = new double[ with0->Fnphases * with0->Fnphases ]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix( ( (TDSSCktElement*) with0 )->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful + /*C*/ + { + int stop = 0; + with0->Cmatrix.resize(with0->Fnphases * with0->Fnphases); + for(stop = ( (TDSSCktElement*) with0 )->Fnphases * ( (TDSSCktElement*) with0 )->Fnphases, j = 1; j <= stop; j++) + { + (with0->Cmatrix)[j - 1] = 1.0e-6 * (MatBuffer)[j - 1]; + } + } + free(MatBuffer); //# FreeMemory accepts one parameter only; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TCapacitor::InterpretConnection(const String s) +{ + String TestS; + /*# with ActiveCapacitorObj do */ + { + auto with0 = ActiveCapacitorObj; + TestS = LowerCase(s); + switch(TestS[1 - 1]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[2 - 1]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + switch(with0->Connection) + { + case 1: + { + int myshift = 0; + with0->Set_NTerms(1); // Force reallocation of terminals + if (with0->Fnphases < 3) + myshift = 1; + + with0->Set_Nconds(with0->Fnphases + myshift); + } + break; + case 0: + if(with0->Fnterms != 2) + { + with0->Set_NTerms(2); + } + with0->Set_Nconds(with0->Fnphases); + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapacitor::CapSetBus1(const String s) +{ + String S2; + int i = 0; + int dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveCapacitorObj do */ + { + auto with0 = ActiveCapacitorObj; + with0->SetBus(1, s); + + // Default Bus2 to zero node of Bus1 unless it is previously defined. (Grounded-Y connection) + if(!with0->Bus2Defined && (with0->Fnterms == 2)) // Fixed Bus 9-21-19 + + // Strip node designations from S + { + int stop = 0; + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); // copy up to Dot + for(stop = with0->Fnphases, i = 1; i <= stop; i++) + { + S2 = S2 + ".0"; + } // append series of ".0"'s + with0->SetBus(2, S2); // default setting for Bus2 + with0->IsShunt = true; + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TCapacitor::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int i = 0; + result = 0; + // continue parsing with contents of Parser + ActiveCapacitorObj = (TCapacitorObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveCapacitorObj); // use property to set this value + /*# with ActiveCapacitorObj do */ + { + auto with0 = ActiveCapacitorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"Capacitor." + + with0->get_Name() + + "\"", 450); + break; + case 1: + CapSetBus1(Param); + break; + case 2: + { + with0->SetBus(2, Param); + with0->NumTerm = 2; // Specifies that the capacitor is not connected to ground + } + break;/* Numphases := Parser.MakeInteger_()*/ + case 3: + ; + break; // see below + case 4: + with0->FNumSteps = InterpretDblArray(Param, with0->FNumSteps, &(with0->Fkvarrating[0])); + break; + case 5: + with0->kvrating = Parser[ActorID]->MakeDouble_(); + break; + case 6: + InterpretConnection(Param); + break; + case 7: + DoCmatrix(ActorID); + break; + case 8: + with0->FNumSteps = InterpretDblArray(Param, with0->FNumSteps, &(with0->FC[0])); + break; + case 9: + with0->FNumSteps = InterpretDblArray(Param, with0->FNumSteps, &(with0->FR[0])); + break; + case 10: + with0->FNumSteps = InterpretDblArray(Param, with0->FNumSteps, &(with0->FXL[0])); + break; + case 11: + with0->ProcessHarmonicSpec(Param); + break; + case 12: + with0->set_NumSteps(Parser[ActorID]->MakeInteger_()); + break; + case 13: + with0->ProcessStatesSpec(Param); + break; + // Inherited Property Edits + default: + inherited::ClassEdit(ActiveCapacitorObj, ParamPointer - NumPropsThisClass); + break; + } + + // Some specials ... + switch(ParamPointer) + { + case 1: + { + with0->Set_PropertyValue(2,with0->GetBus(2)); // this gets modified + with0->PrpSequence[2 - 1] = 0; // Reset this for save function + } + break; + case 2: + if(CompareText(StripExtension(with0->GetBus(1)), StripExtension(with0->GetBus(2))) != 0) + { + with0->IsShunt = false; + with0->Bus2Defined = true; + } + break; + case 3: + if(with0->Fnphases != Parser[ActorID]->MakeInteger_()) + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + if (with0->Connection == 1) + with0->Set_Nconds(with0->Fnphases + 1); + else + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + with0->Yorder = with0->Fnterms * with0->Fnconds; + } + break; + case 4: + with0->SpecType = 1; + break; + case 7: + with0->SpecType = 3; + break; + case 8: + { + int stop = 0; + with0->SpecType = 2; + for(stop = with0->FNumSteps, i = 1; i <= stop; i++) + { + (with0->FC)[i - 1] = (with0->FC)[i - 1] * 1.0e-6; + } + } + break; + case 10: + { + int stop = 0; + for(stop = with0->FNumSteps, i = 1; i <= stop; i++) + { + if((with0->FXL)[i - 1] != 0.0) + { + if((with0->FR)[i - 1] == 0.0) + (with0->FR)[i - 1] = double(Abs((int) (with0->FXL)[i - 1])) / 1000.0; + } + } // put in something so it doesn't fail + with0->DoHarmonicRecalc = false; // XL is specified + } + break; + case (NumPropsThisClass + 1): + with0->FNormAmpsSpecified = true; + break; + case (NumPropsThisClass + 2): + with0->FEmergAmpsSpecified = true; + break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 3: case 4: case 5: case 6: case 7: case 8: + with0->Set_YprimInvalid(ActorID,true); + break; + case 12: case 13: + with0->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TCapacitor::MakeLike(const String CapacitorName) +{ + int result = 0; + TCapacitorObj* OtherCapacitor = nullptr; + int i = 0; + result = 0; + /*See if we can find this Capacitor name in the present collection*/ + OtherCapacitor = ((TCapacitorObj*) Find(CapacitorName)); + if(OtherCapacitor != nullptr) + /*# with ActiveCapacitorObj do */ + { + auto with0 = ActiveCapacitorObj; + int stop = 0; + if((with0)->Fnphases != (OtherCapacitor)->Fnphases) + { + (with0)->Set_NPhases((OtherCapacitor)->Fnphases); + (with0)->Set_Nconds((with0)->Fnphases); // force reallocation of terminals and conductors + (with0)->Yorder = (with0)->Fnconds * (with0)->Fnterms; + (with0)->Set_YprimInvalid(ActiveActor,true); + } + with0->set_NumSteps(OtherCapacitor->Get_FNumSteps()); + for(stop = with0->FNumSteps, i = 1; i <= stop; i++) + { + (with0->FC)[i - 1] = (OtherCapacitor->FC)[i - 1]; + (with0->Fkvarrating)[i - 1] = (OtherCapacitor->Fkvarrating)[i - 1]; + (with0->FR)[i - 1] = (OtherCapacitor->FR)[i - 1]; + (with0->FXL)[i - 1] = (OtherCapacitor->FXL)[i - 1]; + (with0->FXL)[i - 1] = (OtherCapacitor->FXL)[i - 1]; + (with0->FHarm)[i - 1] = (OtherCapacitor->FHarm)[i - 1]; + (with0->FStates)[i - 1] = (OtherCapacitor->FStates)[i - 1]; + } + with0->kvrating = OtherCapacitor->kvrating; + with0->Connection = OtherCapacitor->Connection; + with0->SpecType = OtherCapacitor->SpecType; + if(OtherCapacitor->Cmatrix.empty()) + with0->Cmatrix.clear(); + else + { + int stop = 0; + with0->Cmatrix.resize(with0->Fnphases * with0->Fnphases); + for(stop = (with0)->Fnphases * (with0)->Fnphases, i = 1; i <= stop; i++) + { + (with0->Cmatrix)[i - 1] = (OtherCapacitor->Cmatrix)[i - 1]; + } + } + ClassMakeLike(OtherCapacitor); // Take care of inherited class properties + for(stop = (with0)->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + (with0)->Set_PropertyValue(i,(OtherCapacitor)->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Capacitor MakeLike: \"") + CapacitorName + + "\" Not Found.", 451); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TCapacitor::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TCapacitor.Init", 452); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TCapacitor Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TCapacitorObj::TCapacitorObj(TDSSClass* ParClass, const String CapacitorName) + : inherited(ParClass), + Ftotalkvar(0.0), + kvrating(0.0), + FNumSteps(0), + FLastStepInService(0), + DoHarmonicRecalc(false), + Bus2Defined(false), + SpecType(0), + NumTerm(0), + Connection(0) +{ + Set_Name(LowerCase(CapacitorName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(2); // Force allocation of terminals and conductors + SetBus(2, (GetBus(1) + ".0.0.0")); // Default to grounded wye + IsShunt = true; // defaults to shunt capacitor + Cmatrix.clear(); + FC.clear(); + FXL.clear(); + Fkvarrating.clear(); + FR.clear(); + FHarm.clear(); + FStates.clear(); + + /*Initialize these pointers to Nil so reallocmem will work reliably*/ + set_NumSteps(1); // Initial Allocation for the Arrays, too + set_LastStepInService(FNumSteps); + FC.resize(FNumSteps); + FXL.resize(FNumSteps); + Fkvarrating.resize(FNumSteps); + FR.resize(FNumSteps); + FHarm.resize(FNumSteps); + FStates.resize(FNumSteps); + InitDblArray(FNumSteps, &FR[0], 0.0); + InitDblArray(FNumSteps, &FXL[0], 0.0); + InitDblArray(FNumSteps, &FHarm[0], 0.0); + InitDblArray(FNumSteps, &Fkvarrating[0], 1200.0); + FStates[1 - 1] = 1; + kvrating = 12.47; + InitDblArray(FNumSteps, &FC[0], 1.0L / (TwoPi * BaseFrequency * Sqr(kvrating) * 1000.0L / Fkvarrating[1 - 1])); + Connection = 0; // 0 or 1 for wye (default) or delta, respectively + SpecType = 1; // 1=kvar, 2=Cuf, 3=Cmatrix + NormAmps = Fkvarrating[1 - 1] * SQRT3 / kvrating * 1.35; // 135% + EmergAmps = NormAmps * 1.8 / 1.35; //180% + + FNormAmpsSpecified = false; + FEmergAmpsSpecified = false; + + FaultRate = 0.0005; + PctPerm = 100.0; + HrsToRepair = 3.0; + Yorder = Fnterms * Fnconds; + DoHarmonicRecalc = false; + Bus2Defined = false; + RecalcElementData(ActiveActor); + NumTerm = 1; + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TCapacitorObj::~TCapacitorObj() +{ + Cmatrix.clear(); + FC.clear(); + FXL.clear(); + Fkvarrating.clear(); + FR.clear(); + FHarm.clear(); + FStates.clear(); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapacitorObj::RecalcElementData(int ActorID) +{ + double KvarPerPhase = 0.0; + double PhasekV = 0.0; + double W = 0.0; + int i = 0; + Ftotalkvar = 0.0; + PhasekV = 1.0; + W = TwoPi * BaseFrequency; + switch(SpecType) + { + case 1: // kvar + { + int stop = 0; + switch(Connection) + { + case 1: // Line-to-Line + { + PhasekV = kvrating; + } + break; + default: + switch(Fnphases) + { + case 2: + case 3: + PhasekV = kvrating / SQRT3; + break; // Assume three phase system + default: + PhasekV = kvrating; + break; + } + break; + } + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + FC[i - 1] = 1.0L / (W * Sqr(PhasekV) * 1000.0L / (Fkvarrating[1 - 1] / Fnphases)); + } + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + Ftotalkvar = Ftotalkvar + Fkvarrating[i - 1]; + } + } + break; // Cuf + case 2: + { + int stop = 0; + switch(Connection) + { + case 1: // Line-to-Line + { + PhasekV = kvrating; + } + break; + default: + switch(Fnphases) + { + case 2: + case 3: + PhasekV = kvrating / SQRT3; + break; // Assume three phase system + default: + PhasekV = kvrating; + break; + } + break; + } + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + Ftotalkvar = Ftotalkvar + W * FC[i - 1] * Sqr(PhasekV) / 1000.0L; + } + } + break; // Cmatrix + // Nothing to do + case 3: + break; + default: + ; + break; + } + if(DoHarmonicRecalc) + { + int stop = 0; + for(stop = FNumSteps, i = 1; i <= stop; i++) + { // If harmonic specified, compute filter reactance + if(FHarm[i - 1] != 0.0) + FXL[i - 1] = (1.0 / (W * FC[i - 1])) / Sqr(FHarm[i - 1]); + else + FXL[i - 1] = 0.0; // Assume 0 harmonic means no filter + if(FR[i - 1] == 0.0) + FR[i - 1] = FXL[i - 1] / 1000.0; + } + } + KvarPerPhase = Ftotalkvar / Fnphases; + if (!FNormAmpsSpecified) NormAmps = KvarPerPhase / PhasekV * 1.35; + if (!FEmergAmpsSpecified) EmergAmps = KvarPerPhase / PhasekV * 1.8; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TCapacitorObj::CalcYPrim(int ActorID) +{ + int i = 0; + TcMatrix* YPrimTemp = nullptr; + TcMatrix* YprimWork = nullptr; + +// Normally build only Yprim Shunt, but if there are 2 terminals and +// Bus1 <> Bus 2 + int stop = 0; + if(Get_YprimInvalid(ActorID,0)) // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; //YPrim_Shunt->~TcMatrix(); + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; //YPrim_Series->~TcMatrix(); + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; //YPrim->~TcMatrix(); + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + if(IsShunt) + YPrimTemp = YPrim_Shunt; + else + YPrimTemp = YPrim_Series; + YprimWork = new TcMatrix(Yorder); + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + if(FStates[i - 1] == 1) + { + MakeYprimWork(YprimWork, i, ActorID); + YPrimTemp->AddFrom(YprimWork); + } + } + delete YprimWork; + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages doesn't fail + if(IsShunt) + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + } + YPrim->CopyFrom(YPrimTemp); + + /*Don't Free YPrimTemp - It's just a pointer to an existing complex matrix*/ + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TCapacitorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { Write(f, "~ "); Write(f, with0->PropertyName[1 - 1]); Write(f, L'='); WriteLn(f, Get_FirstBus()); } + { Write(f, "~ "); Write(f, with0->PropertyName[2 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, with0->PropertyName[3 - 1]); Write(f, L'='); WriteLn(f, Fnphases, 0); } + { Write(f, "~ "); Write(f, with0->PropertyName[4 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(4)); } + { Write(f, "~ "); Write(f, with0->PropertyName[5 - 1]); Write(f, L'='); WriteLn(f, kvrating, 0, 3); } + switch(Connection) + { + case 0: + { Write(f, "~ "); Write(f, with0->PropertyName[6 - 1]); WriteLn(f, "=wye"); } + break; + case 1: + { Write(f, "~ "); Write(f, with0->PropertyName[6 - 1]); WriteLn(f, "=delta"); } + break; + default: + ; + break; + } + if(!Cmatrix.empty()) + { + int stop = 0; + { Write(f, with0->PropertyName[7 - 1]); Write(f, "= ("); } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, ((Cmatrix)[(i - 1) * Fnphases + j - 1] * 1.0e6), 0, 3); Write(f, L' '); } + } + if(i != Fnphases) + Write(f, L'|'); + } + WriteLn(f, L')'); + } + { Write(f, "~ "); Write(f, with0->PropertyName[8 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(8)); } + { Write(f, "~ "); Write(f, with0->PropertyName[9 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(9)); } + { Write(f, "~ "); Write(f, with0->PropertyName[10 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(10)); } + { Write(f, "~ "); Write(f, with0->PropertyName[11 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(11)); } + { Write(f, "~ "); Write(f, with0->PropertyName[12 - 1]); Write(f, L'='); WriteLn(f, FNumSteps); } + { Write(f, "~ "); Write(f, with0->PropertyName[13 - 1]); Write(f, L'='); WriteLn(f, GetPropertyValue(13)); } + for(stop = with0->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + if(Complete) + { + { Write(f, "SpecType="); WriteLn(f, SpecType, 0); } + } + } +} + +void TCapacitorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,"3"); + Set_PropertyValue(4,"1200"); + Set_PropertyValue(5,"12.47"); + Set_PropertyValue(6,"wye"); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,"0"); + Set_PropertyValue(10,"0"); + Set_PropertyValue(11,"0"); + Set_PropertyValue(12,"1"); + Set_PropertyValue(13,"1"); // states + inherited::InitPropertyValues(NumPropsThisClass); + + // Override Inherited properties + // Override Inherited properties + Set_PropertyValue(NumPropsThisClass + 1,Format("%g", NormAmps)); + Set_PropertyValue(NumPropsThisClass + 2,Format("%g", EmergAmps)); + Set_PropertyValue(NumPropsThisClass + 3,Str_Real(FaultRate, 0)); + Set_PropertyValue(NumPropsThisClass + 4,Str_Real(PctPerm, 0)); + Set_PropertyValue(NumPropsThisClass + 5,Str_Real(HrsToRepair, 0)); + ClearPropSeqArray(); +} + +void TCapacitorObj::MakePosSequence(int ActorID) +{ + String s; + double KvarPerPhase = 0.0; + double PhasekV = 0.0; + double CS = 0.0; + double CM = 0.0; + int i = 0; + int j = 0; + /*If FnPhases>1 Then -- do same for 1-phase, too*/ + s = " "; + switch(SpecType) + { + case 1: // kvar + { + int stop = 0; + if((Fnphases > 1) || (Connection != 0)) + PhasekV = kvrating / SQRT3; + else + PhasekV = kvrating; + s = String("Phases=1 ") + Format(" kV=%-.5g kvar=(", PhasekV); + + // 1-6-16 do caps Like load ... + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + KvarPerPhase = Fkvarrating[i - 1] / 3.0; // divide the total kvar equally among3 phases.../Fnphases; + s = s + Format(" %-.5g", KvarPerPhase); + } + s = s + ")"; + + /*Leave R as specified*/ + } + break; // + case 2: + { + s = "Phases=1 "; + } + break; + case 3: + if(Fnphases > 1) // C Matrix + { + int stop = 0; + s = "Phases=1 "; + // R1 + CS = 0.0; // Avg Self + for(stop = Fnphases, i = 1; i <= stop; i++) + { + CS = CS + (Cmatrix)[(i - 1) * Fnphases + i - 1]; + } + CS = CS / Fnphases; + CM = 0.0; //Avg mutual + for(stop = Fnphases, i = 2; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = i; j <= stop1; j++) + { + CM = CM + (Cmatrix)[(i - 1) * Fnphases + j - 1]; + } + } + CM = CM / (Fnphases * (Fnphases - 1.0) / 2.0); + + s = s + Format(" Cuf=%-.5g", (CS - CM)); + } + break; + default: + ; + break; + } + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + +int TCapacitorObj::get_States(int Idx, int ActorID) +{ + int result = 0; + result = FStates[Idx - 1]; + return result; +} + +void TCapacitorObj::set_States(int Idx, int ActorID, int Value) +{ + if(FStates[Idx - 1] != Value) + { + FStates[Idx - 1] = Value; + Set_YprimInvalid(ActorID,true); + } +} + +//-------------------------------------------------------------------------------------- + +int TCapacitorObj::Get_NumTerm() +{ + return NumTerm; +} + +//-------------------------------------------------------------------------------------- + +int TCapacitorObj::Get_FLastStepInService() +{ + return FLastStepInService; +} + +//-------------------------------------------------------------------------------------- + +int TCapacitorObj::Get_FNumSteps() +{ + return FNumSteps; +} + +//-------------------------------------------------------------------------------------- + +double TCapacitorObj::Get_kvrating() +{ + return kvrating; +} + +//-------------------------------------------------------------------------------------- + +double TCapacitorObj::Get_Ftotalkvar() +{ + return Ftotalkvar; +} + +/* + Special case for changing from 1 to more .. Automatically make a new bank +*/ + +void TCapacitorObj::set_NumSteps(int Value) +{ + double StepSize = 0.0; + double RStep = 0.0; + double XLstep = 0.0; + int i = 0; + /*reallocate all arrays associated with steps */ + if((FNumSteps != Value) && (Value > 0)) + { + RStep = 0.0; + XLstep = 0.0; + if(FNumSteps == 1) + /*Save total values to be divided up*/ + { + Ftotalkvar = Fkvarrating[1 - 1]; + RStep = FR[1 - 1] * Value; + XLstep = FXL[1 - 1] * Value; + } + + // Reallocate arrays (Must be initialized to nil for first call) + FC.resize(Value + 1); + FXL.resize(Value + 1); + Fkvarrating.resize(Value + 1); + FR.resize(Value + 1); + FHarm.resize(Value + 1); + FStates.resize(Value + 1); + + // Special case for FNumSteps=1 + if(FNumSteps == 1) + { + int stop = 0; + switch(SpecType) + { + case 1: // kvar {We'll make a multi-step bank of same net size as at present} + { + int stop = 0; + StepSize = Ftotalkvar / Value; + for(stop = Value, i = 1; i <= stop; i++) + { + Fkvarrating[i - 1] = StepSize; + } + } + break; // Cuf {We'll make a multi-step bank with all the same as first} + case 2: + { + int stop = 0; + for(stop = Value, i = 2; i <= stop; i++) + { + FC[i - 1] = FC[1 - 1]; + } // Make same as first step + } + break; // Cmatrix {We'll make a multi-step bank with all the same as first} + // Nothing to do since all will be the same + case 3: + break; + default: + ; + break; + } + switch(SpecType) + { + case 1: + { + int stop = 0; + for(stop = Value, i = 1; i <= stop; i++) + { + FR[i - 1] = RStep; + } + for(stop = Value, i = 1; i <= stop; i++) + { + FXL[i - 1] = XLstep; + } + } + break; // Make R and XL same as first step + case 2: case 3: + { + int stop = 0; + for(stop = Value, i = 2; i <= stop; i++) + { + FR[i - 1] = FR[1 - 1]; + } + for(stop = Value, i = 2; i <= stop; i++) + { + FXL[i - 1] = FXL[1 - 1]; + } + } + break; + default: + ; + break; + } + for(stop = Value, i = 1; i <= stop; i++) + { + FStates[i - 1] = 1; + } // turn 'em all ON + set_LastStepInService(Value); + for(stop = Value, i = 2; i <= stop; i++) + { + FHarm[i - 1] = FHarm[1 - 1]; + } // tune 'em all the same as first + } + } + FNumSteps = Value; +} + +void TCapacitorObj::ProcessHarmonicSpec(const String Param) +{ + FNumSteps = InterpretDblArray(Param, FNumSteps, &(FHarm[0])); + DoHarmonicRecalc = true; +} +// Find the last step energized + +void TCapacitorObj::FindLastStepInService() +{ + int i = 0; + int stop = 0; + FLastStepInService = 0; + for(i = FNumSteps - 1; i >= 0; i--) + { + if(FStates[i] == 1) + { + FLastStepInService = i; + break; + } + } +} +// force the last step in service to be a certain value + +void TCapacitorObj::set_LastStepInService(int Value) +{ + int i = 0; + int stop = 0; + for(stop = Value, i = 1; i <= stop; i++) + { + FStates[i - 1] = 1; + } + // set remainder steps, if any, to 0 + for(stop = FNumSteps, i = Value + 1; i <= stop; i++) + { + FStates[i - 1] = 0; + } + + // Force rebuild of YPrims if necessary. + if(Value != FLastStepInService) + Set_YprimInvalid(ActiveActor,true); + FLastStepInService = Value; +} + +void TCapacitorObj::ProcessStatesSpec(const String Param) +{ + vector TArray; + TArray.resize(FStates.size()); + FNumSteps = InterpretIntArray(Param, FNumSteps, &TArray[0]); + for (int i = 0; i < FNumSteps; i++) + FStates[i] = TArray[i]; + FindLastStepInService(); +} + +/* call this routine only if step is energized*/ + +void TCapacitorObj::MakeYprimWork(TcMatrix* YprimWork, int iStep, int ActorID) +{ + complex Value = {}; + complex Value2 = {}; + complex ZL = {}; + int i = 0; + int j = 0; + int IOffset = 0; + double W = 0.0; + double FreqMultiple = 0.0; + bool HasZL = false; + /*# with YprimWork do */ + { + auto with0 = YprimWork; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiple = FYprimFreq / BaseFrequency; + W = TwoPi * FYprimFreq; + if((FR[iStep - 1] + Abs((int) FXL[iStep - 1])) > 0.0) + HasZL = true; + else + HasZL = false; + if(HasZL) + { + ZL = cmplx(FR[iStep - 1], FXL[iStep - 1] * FreqMultiple); + } + + /* Now, Put C into in Yprim matrix */ + switch(SpecType) + { + case 1: + case 2: + { + Value = cmplx(0.0, FC[iStep - 1] * W); + switch(Connection) + { + case 1: // Line-Line + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; // wrap around for closed connections + with0->AddElement(i, i, Value); + with0->AddElement(j, j, Value); + with0->AddElemsym(i, j, cnegate(Value)); + } + // Remainder of the matrix is all zero + } + break; + default: + int stop = 0; + if(HasZL) + Value = cinv(cadd(ZL, cinv(Value))); // add in ZL + Value2 = cnegate(Value); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } + break; + } + } + break; // C matrix specified + case 3: + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + IOffset = (i - 1) * Fnphases; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = cmplx(0.0, (Cmatrix)[(IOffset + j) - 1] * W); + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + Value = cnegate(Value); + with0->SetElemsym(i, j + Fnphases, Value); + } + } + } + break; + default: + ; + break; + } + + /*Add line reactance for filter reactor, if any*/ + if(HasZL) + switch(SpecType) + { + case 1: case 2: + switch(Connection) + { + case 1: /*Line-Line*/ + /*Add a little bit to each phase so it will invert*/ + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, cmulreal(with0->GetElement(i, i), 1.000001)); + } + with0->Invert(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Value = cadd(ZL, with0->GetElement(i, i)); + with0->SetElement(i, i, Value); + } + with0->Invert(); + } + break; /*WYE - just put ZL in series*/ + /*DO Nothing; Already in - see above*/ + default: + ; + break; + } + break; + case 3: + { + int stop = 0; + with0->Invert(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Value = cadd(ZL, with0->GetElement(i, i)); + with0->SetElement(i, i, Value); + } + with0->Invert(); + } + break; + default: + ; + break; + } + } /*With YPRIM*/ +} + +String TCapacitorObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + pDoubleArray FTemp = nullptr; + + result = ""; + switch(Index) + { + case 1: // Special cases + result = GetBus(1); + break; + case 2: + result = GetBus(2); + break; + case 4: + result = GetDSSArray_Real(FNumSteps, &Fkvarrating[0]); + break; + case 5: + { + result = Format("%-g", kvrating); + } + break; + case 8: + { + int stop = 0; + FTemp = (pDoubleArray) realloc(FTemp, sizeof(double) * FNumSteps); + for(stop = FNumSteps, i = 1; i <= stop; i++) + { + FTemp[i - 1] = FC[i - 1] * 1.0e6; + } // To microfarads + result = GetDSSArray_Real(FNumSteps, FTemp); + free(FTemp); // throw away temp storage + } + break; + case 9: + result = GetDSSArray_Real(FNumSteps, &FR[0]); + break; + case 10: + result = GetDSSArray_Real(FNumSteps, &FXL[0]); + break; + case 11: + result = GetDSSArray_Real(FNumSteps, &FHarm[0]); + break; + case 13: + result = GetDSSArray_Integer(FNumSteps, &FStates[0]); + break; + case 14: + { + + result = Format("%g", NormAmps); + } + break; + case 15: + { + result = Format("%g", EmergAmps); + } + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + return result; +} + +bool TCapacitorObj::AddStep(int ActorID) +{ + bool result = false; + // Start with last step in service and see if we can add more. If not return FALSE + if(Get_FLastStepInService() == FNumSteps) + result = false; + else + { + ++FLastStepInService; + set_States(FLastStepInService,ActorID,1); + result = true; + } + return result; +} + +bool TCapacitorObj::SubtractStep(int ActorID) +{ + bool result = false; + if(Get_FLastStepInService() == 0) + result = false; + else + { + set_States(FLastStepInService,ActorID,0); + --FLastStepInService; + if(Get_FLastStepInService() == 0) + result = false; + else + result = true; // signify bank OPEN + } + return result; +} + +int TCapacitorObj::AvailableSteps() +{ + int result = 0; + result = FNumSteps - Get_FLastStepInService(); + return result; +} + + + + +} // namespace Capacitor + + + + diff --git a/OpenDSSC/PDElements/Capacitor.h b/OpenDSSC/PDElements/Capacitor.h new file mode 100644 index 0000000..0a75fbe --- /dev/null +++ b/OpenDSSC/PDElements/Capacitor.h @@ -0,0 +1,158 @@ +#ifndef CapacitorH +#define CapacitorH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "Arraydef.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Ucomplex.h" + + + +namespace Capacitor +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 4-17-00 Made IsShunt Public + 12-7-04 Added Reactance in series with each capacitor + +*/ +/*Basic capacitor + + Implemented as a two-terminal constant impedance (Power Delivery Element) + + Bus2 connection defaults to 0 node of Bus1 (if Bus2 has the default bus connection + at the time Bus1 is defined. Therefore, if only Bus1 is specified, a shunt capacitor results. + If delta connected, Bus2 is set to node zero of Bus1 and nothing is returned in the lower + half of YPrim - all zeroes. + + If an ungrounded wye is desired, explicitly set Bus2= and set all nodes the same, + e.g. Bus1.4.4.4 (uses 4th node of Bus1 as neutral point) + or BusNew.1.1.1 (makes a new bus for the neutral point) + You must specify the nodes or you will get a series capacitor! + + A series capacitor is specified simply by setting bus2 and declaring the connection + to be Wye. If the connection is specified as delta, nothing will be connected to Bus2. + In fact the number of terminals is set to 1. + + Capacitance may be specified as: + + 1. kvar and kv ratings at base frequency. impedance. Specify kvar as total for + all phases (all cans assumed equal). For 1-phase, kV = capacitor can kV rating. + For 2 or 3-phase, kV is line-line three phase. For more than 3 phases, specify + kV as actual can voltage. + 2. Capacitance in uF to be used in each phase. If specified in this manner, + the given value is always used whether wye or delta. + 3. A nodal C matrix (like a nodal admittance matrix). + If conn=wye then 2-terminal through device + If conn=delta then 1-terminal. + Microfarads. + +*/ + +class TCapacitor : public PDClass::TPDClass +{ + friend class TCapacitorObj; +public: + typedef PDClass::TPDClass inherited; +private: + void DoCmatrix(int ActorID); + void InterpretConnection(const String s); + void CapSetBus1(const String s); +protected: + virtual int MakeLike(const String CapacitorName); + void DefineProperties(); // Add Properties of this class to propName +public: + TCapacitor(); + virtual ~TCapacitor(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TCapacitorObj : public PDELement::TPDElement +{ + friend class TCapacitor; +public: + typedef PDELement::TPDElement inherited; +//private: + std::vector FC; + std::vector FXL; + std::vector Fkvarrating; + std::vector FR; + std::vector FHarm; // single C per phase (line rating) if Cmatrix not specified + std::vector FStates; + double Ftotalkvar; + double kvrating; + int FNumSteps; + int FLastStepInService; + std::vector Cmatrix; // If not nil then overrides C + bool DoHarmonicRecalc; + bool Bus2Defined; + bool FNormAmpsSpecified; + bool FEmergAmpsSpecified; + + int SpecType; + int NumTerm; // Flag used to indicate The number of terminals + int get_States(int Idx, int ActorID); + void set_States(int Idx, int ActorID, int Value); + void set_LastStepInService(int Value); + void ProcessHarmonicSpec(const String Param); + void ProcessStatesSpec(const String Param); + void MakeYprimWork(Ucmatrix::TcMatrix* YprimWork, int iStep, int ActorID); + void set_NumSteps(int Value); // 1=kvar, 2=Cuf, 3=Cmatrix +public: + int Connection; // 0 or 1 for wye (default) or delta, respectively + TCapacitorObj(DSSClass::TDSSClass* ParClass, const String CapacitorName); + virtual ~TCapacitorObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual String GetPropertyValue(int Index); + bool AddStep(int ActorID); + bool SubtractStep(int ActorID); + int AvailableSteps(); + void FindLastStepInService(); + // properties for getting/setting variables. + int Get_NumTerm(); + int Get_FLastStepInService(); + int Get_FNumSteps(); + double Get_kvrating(); + double Get_Ftotalkvar(); + + TCapacitorObj(TDSSClass* ParClass); + TCapacitorObj(String ClassName); + TCapacitorObj(); +}; +extern TCapacitorObj* ActiveCapacitorObj; +extern TCapacitor* CapacitorClass; + + +} // namespace Capacitor + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Capacitor; +#endif + +#endif // CapacitorH + + + + diff --git a/OpenDSSC/PDElements/Fault.cpp b/OpenDSSC/PDElements/Fault.cpp new file mode 100644 index 0000000..e20db24 --- /dev/null +++ b/OpenDSSC/PDElements/Fault.cpp @@ -0,0 +1,768 @@ + +#pragma hdrstop + +#include "Fault.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Dynamics.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "Utilities.h" +#include "Circuit.h" + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace PDClass; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Fault +{ + +TFaultObj::TFaultObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TFaultObj::TFaultObj(String ClassName) : inherited(ClassName) {} +TFaultObj::TFaultObj() {} + + +TFaultObj* ActiveFaultObj = nullptr; +const int NumPropsThisClass = 9; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Fault objects + +TFault::TFault() +{ + ; + Class_Name = "Fault"; + DSSClassType = FAULTOBJECT + NON_PCPD_ELEM; // Only in Fault object class + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TFault::~TFault() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFault::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "bus2"; + PropertyName[3 - 1] = "phases"; + PropertyName[4 - 1] = "r"; + PropertyName[5 - 1] = "%stddev"; + PropertyName[6 - 1] = "Gmatrix"; + PropertyName[7 - 1] = "ONtime"; + PropertyName[8 - 1] = "temporary"; + PropertyName[9 - 1] = "MinAmps"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of first bus. Examples:") + CRLF + + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3" + + CRLF + + CRLF + + "Bus2 automatically defaults to busname.0,0,0 unless it was previously defined. "; + PropertyHelp[2 - 1] = String("Name of 2nd bus of the 2-terminal Fault object. Defaults to all phases connected " "to first bus, node 0, if not specified. (Shunt Wye Connection to ground reference)") + CRLF + + CRLF + + "That is, the Fault defaults to a ground fault unless otherwise specified."; + PropertyHelp[3 - 1] = "Number of Phases. Default is 1."; + PropertyHelp[4 - 1] = "Resistance, each phase, ohms. Default is 0.0001. Assumed to be Mean value if gaussian random mode." + "Max value if uniform mode. A Fault is actually a series resistance " + "that defaults to a wye connection to ground on the second terminal. You " + "may reconnect the 2nd terminal to achieve whatever connection. Use " + "the Gmatrix property to specify an arbitrary conductance matrix."; + PropertyHelp[5 - 1] = "Percent standard deviation in resistance to assume for Monte Carlo fault (MF) solution mode for GAUSSIAN distribution. Default is 0 (no variation from mean)."; + PropertyHelp[6 - 1] = "Use this to specify a nodal conductance (G) matrix to represent some arbitrary resistance network. " + "Specify in lower triangle form as usual for DSS matrices."; + PropertyHelp[7 - 1] = "Time (sec) at which the fault is established for time varying simulations. Default is 0.0 " + "(on at the beginning of the simulation)"; + PropertyHelp[8 - 1] = "{Yes | No} Default is No. Designate whether the fault is temporary. For Time-varying simulations, " + "the fault will be removed if the current through the fault drops below the MINAMPS criteria."; + PropertyHelp[9 - 1] = "Minimum amps that can sustain a temporary fault. Default is 5."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TFault::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TFaultObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFault::DoGmatrix(int ActorID) +{ + int OrderFound = 0; + int j = 0; + pDoubleArray MatBuffer = nullptr; + /*# with ActiveFaultObj do */ + { + auto with0 = ActiveFaultObj; + MatBuffer = new double[ with0->Fnphases * with0->Fnphases ]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix( with0->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful + /*X*/ + { + int stop = 0; + with0->Gmatrix = (pDoubleArray) realloc(with0->Gmatrix, sizeof(double) * with0->Fnphases * with0->Fnphases); + for(stop = ( with0 )->Fnphases * ( with0 )->Fnphases, j = 1; j <= stop; j++) + { + (with0->Gmatrix)[j - 1] = (MatBuffer)[j - 1]; + } + } + free(MatBuffer); //# FreeMemory accepts one parameter only; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFault::FltSetBus1(const String s) +{ + String S2; + int dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveFaultObj do */ + { + auto& with0 = ActiveFaultObj; + with0->SetBus(1, s); + + // Default Bus2 to zero node of Bus1 unless previously defined explicitly. (Wye Grounded connection) + if(!with0->Bus2Defined) + // Strip node designations from S + { + dotpos = Pos(".", s); + if(dotpos > 0) // copy up to Dot + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); + S2 = S2 + ".0.0.0"; // Set Default for up to 3 phases + with0->SetBus(2, S2); + with0->IsShunt = true; + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TFault::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int PhasesTemp = 0; + result = 0; + // continue parsing with contents of Parser + ActiveFaultObj = (TFaultObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveFaultObj); // use property to set this value + /*# with ActiveFaultObj do */ + { + auto with0 = ActiveFaultObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + with0->get_Name() + + "\"", 350); + break; + case 1: + FltSetBus1(Param); + break; + case 2: + with0->SetBus(2, Param); + break; + case 3: + ; + break;/*Numphases := Parser.MakeInteger_();*/ // see below + case 4: + { + with0->G = Parser[ActorID]->MakeDouble_(); + if(with0->G != 0.0) + with0->G = 1.0 / with0->G; + else + with0->G = 10000.0; // Default to a low resistance + } + break; + case 5: + with0->StdDev = Parser[ActorID]->MakeDouble_() * 0.01; + break; + case 6: + DoGmatrix(ActorID); + break; + case 7: + with0->On_Time = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->IsTemporary = InterpretYesNo(Param); + break; + case 9: + with0->MinAmps = Parser[ActorID]->MakeDouble_(); + break; + // Inherited + default: + ClassEdit(ActiveFaultObj, ParamPointer - NumPropsThisClass); + break; + } + + // Some specials ... + switch(ParamPointer) + { + case 1: + with0->Set_PropertyValue(2,with0->GetBus(2)); + break; // Bus2 gets modified if bus1 is + case 2: + if(CompareText(StripExtension(with0->GetBus(1) ), StripExtension( with0->GetBus(2))) != 0 ) + { + with0->IsShunt = false; + with0->Bus2Defined = true; + } + break; + case 3: + { + PhasesTemp = Parser[ActorID]->MakeInteger_(); + if( with0->Fnphases != PhasesTemp) + { + with0->Set_NPhases(PhasesTemp); + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + ActiveCircuit[ActorID]->Set_BusNameRedefined(true); // Set Global Flag to signal circuit to rebuild busdefs + } + } + break; + case 4: + with0->SpecType = 1; + break; + case 6: + with0->SpecType = 2; + break; + case 7: + if(with0->On_Time > 0.0) + with0->Is_ON = false; + break; // Assume fault will be on later + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 3: case 4: case 6: + with0->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TFault::MakeLike(const String FaultName) +{ + int result = 0; + TFaultObj* OtherFault = nullptr; + int i = 0; + result = 0; + /*See if we can find this Fault name in the present collection*/ + OtherFault = ((TFaultObj*) Find(FaultName)); + if(OtherFault != nullptr) + /*# with ActiveFaultObj do */ + { + auto with0 = ActiveFaultObj; + int stop = 0; + if(((TDSSCktElement*)with0)->Fnphases != ( (TDSSCktElement*) OtherFault )->Fnphases) + { + with0->Fnphases = OtherFault->Fnphases; + with0->Set_Nconds(with0->Fnphases); // force reallocation of terminals and conductors + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } + with0->BaseFrequency = OtherFault->BaseFrequency; + with0->G = OtherFault->G; + with0->SpecType = OtherFault->SpecType; + with0->MinAmps = OtherFault->MinAmps; + with0->IsTemporary = OtherFault->IsTemporary; + with0->Cleared = OtherFault->Cleared; + with0->Is_ON = OtherFault->Is_ON; + with0->On_Time = OtherFault->On_Time; + if(OtherFault->Gmatrix == nullptr) + with0->Gmatrix = NULL; + else + { + int stop = 0; + with0->Gmatrix = (pDoubleArray) realloc(with0->Gmatrix, sizeof(double) * with0->Fnphases * with0->Fnphases); + for(stop = with0->Fnphases * with0->Fnphases, i = 1; i <= stop; i++) + { + (with0->Gmatrix)[i - 1] = (OtherFault->Gmatrix)[i - 1]; + } + } + ClassMakeLike(OtherFault); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->Set_PropertyValue(i,OtherFault->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Fault MakeLike: \"") + FaultName + "\" Not Found.", 351); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TFault::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TFault.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TFault Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TFaultObj::TFaultObj(TDSSClass* ParClass, const String FaultName) + : inherited(ParClass), + MinAmps(5.0), + IsTemporary(false), + Cleared(false), + Is_ON(true), + Bus2Defined(false), + On_Time(0.0), + RandomMult(0.0), + G(0.0), + Gmatrix(nullptr), + StdDev(0.0), + SpecType(0) +{ + DSSObjType = ParClass->DSSClassType; //FAULTOBJECT + NON_PCPD_ELEM; // Only in Fault object class + Set_Name(LowerCase(FaultName)); + + // Default to SLG fault + Set_NPhases(1); // Directly set conds and phases + Fnconds = 1; + Set_NTerms(2); // Force allocation of terminals and conductors + SetBus(2, (GetBus(1) + ".0")); // Default to grounded + IsShunt = true; + Gmatrix = nullptr; + G = 10000.0; + SpecType = 1; // G 2=Gmatrix + Bus2Defined = false; + On_Time = 0.0; // Always enabled at the start of a solution. + RandomMult = 1; + NormAmps = 0.0; + EmergAmps = 0.0; + FaultRate = 0.0; + PctPerm = 100.0; + HrsToRepair = 0.0; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TFaultObj::~TFaultObj() +{ + free(Gmatrix); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFaultObj::RecalcElementData(int ActorID) +{ + + +// Nothing to do +} + +double Cube(double X) +{ + double result = 0.0; + result = X * X * X; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// called from solveMontefault Procedure + +void TFaultObj::Randomize(int ActorID) +{ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + switch(with0->RandomType) + { + case GAUSSIAN: + RandomMult = Gauss(1.0, StdDev); + break; + case UNIFORM: + RandomMult = (double) Random(); + break; + case LOGNORMAL: + RandomMult = QuasiLogNormal(1.0); + break; + default: + RandomMult = 1.0; + break; + } + } + + // Give the multiplier some skew to approximate more uniform/Gaussian current distributions + // RandomMult := Cube(RandomMult); removed 12/7/04 + Set_YprimInvalid(ActorID,true); // force rebuilding of matrix +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFaultObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + complex Value2 = {}; + int i = 0; + int j = 0; + int IOffset = 0; + TcMatrix* YPrimTemp = nullptr; + if(Get_YprimInvalid(ActorID,0)) // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + if(IsShunt) + YPrimTemp = YPrim_Shunt; + else + YPrimTemp = YPrim_Series; + + // make sure randommult is 1.0 if not solution mode MonteFault + if(ActiveCircuit[ActorID]->Solution->Get_SolMode() != MONTEFAULT) + RandomMult = 1.0; + if(RandomMult == 0.0) + RandomMult = 0.000001; + /*# with YPrimTemp do */ + { + auto with0 = YPrimTemp; + + /* Now, Put in Yprim matrix */ + + /*If the fault is not ON, the set zero conductance*/ + switch(SpecType) + { + case 1: + { + int stop = 0; + if(Is_ON) + Value = cmplx(G / RandomMult, 0.0); + else + Value = CZero; + Value2 = cnegate(Value); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } + } + break; // G matrix specified + case 2: + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + IOffset = (i - 1) * Fnphases; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + if(Is_ON) + Value = cmplx((Gmatrix)[(IOffset + j) - 1] / RandomMult, 0.0); + else + Value = CZero; + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + Value = cnegate(Value); + with0->SetElemsym(i, j + Fnphases, Value); + } + } + } + break; + default: + ; + break; + } + } /*With YPRIM*/ + YPrim->CopyFrom(YPrimTemp); + TDSSCktElement::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TFaultObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { Write(f, "~ "); Write(f, with0->PropertyName[1 - 1]); Write(f, L'='); WriteLn(f, Get_FirstBus()); } + { Write(f, "~ "); Write(f, with0->PropertyName[2 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, with0->PropertyName[3 - 1]); Write(f, L'='); WriteLn(f, Fnphases, 0); } + { Write(f, "~ "); Write(f, with0->PropertyName[4 - 1]); Write(f, L'='); WriteLn(f, (1.0 / G), 0, 2); } + { Write(f, "~ "); Write(f, with0->PropertyName[5 - 1]); Write(f, L'='); WriteLn(f, (StdDev * 100.0), 0, 1); } + if(Gmatrix != nullptr) + { + int stop = 0; + { Write(f, "~ "); Write(f, with0->PropertyName[6 - 1]); Write(f, "= ("); } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, ((Gmatrix)[(i - 1) * Fnphases + j - 1]), 0, 3); Write(f, L' '); } + } + if(i != Fnphases) + Write(f, L'|'); + } + WriteLn(f, L')'); + } + { Write(f, "~ "); Write(f, with0->PropertyName[7 - 1]); Write(f, L'='); WriteLn(f, On_Time, 0, 3); } + if(IsTemporary) + { Write(f, "~ "); Write(f, with0->PropertyName[8 - 1]); WriteLn(f, "= Yes"); } + else + { Write(f, "~ "); Write(f, with0->PropertyName[8 - 1]); WriteLn(f, "= No"); } + { Write(f, "~ "); Write(f, with0->PropertyName[9 - 1]); Write(f, L'='); WriteLn(f, MinAmps, 0, 1); } + for(stop = with0->NumProperties, i = NumPropsThisClass; i <= stop; i++) + { + { Write(f, "~ "); Write(f, with0->PropertyName[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + if(Complete) + { + { Write(f, "// SpecType="); WriteLn(f, SpecType, 0); } + } + } +} + +void TFaultObj::CheckStatus(int ControlMode, int ActorID) +{ + switch(ControlMode) + { /*Leave it however it is defined by other processes*/ + case CTRLSTATIC: + break; + case EVENTDRIVEN: + case MULTIRATE: + case TIMEDRIVEN: + { + if(!Is_ON) /*Turn it on unless it has been previously cleared*/ + { + if((PresentTimeInSec(ActorID) > On_Time) && !Cleared) + { + Is_ON = true; + Set_YprimInvalid(ActorID,true); + AppendToEventLog(String("Fault.") + get_Name(), "**APPLIED**", ActorID); + } + } + else + { + if(IsTemporary) + { + if(!FaultStillGoing(ActorID)) + { + Is_ON = false; + Cleared = true; + Set_YprimInvalid(ActorID,true); + AppendToEventLog(String("Fault.") + get_Name(), "**CLEARED**", ActorID); + } + } + } + } + break; + default: + ; + break; + } +} + +bool TFaultObj::FaultStillGoing(int ActorID) +{ + bool result = false; + int i = 0; + int stop = 0; + ComputeIterminal(ActorID); + result = false; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(cabs((Iterminal)[i - 1]) > MinAmps) + { + result = true; + return result; + } + } + return result; +} + +void TFaultObj::Reset() +{ + Cleared = false; +} + +void TFaultObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,"1"); + Set_PropertyValue(4,"0.0001"); + Set_PropertyValue(5,"0"); + Set_PropertyValue(6,""); + Set_PropertyValue(7,"0.0"); + Set_PropertyValue(8,"no"); + Set_PropertyValue(9,"5.0"); + inherited::InitPropertyValues(NumPropsThisClass); + + // Override Inherited Properties + Set_PropertyValue(NumPropsThisClass + 1,"0"); //Normamps + Set_PropertyValue(NumPropsThisClass + 2,"0"); //emergamps + Set_PropertyValue(NumPropsThisClass + 3,"0"); //Fault rate + Set_PropertyValue(NumPropsThisClass + 4,"0"); // Pct Perm + Set_PropertyValue(NumPropsThisClass + 5,"0"); // Hrs to repair +} + +String TFaultObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + int j = 0; + switch(Index) + { + case 6: + { + result = "("; + if(ASSIGNED(Gmatrix)) + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { // G matrix + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + result = result + Format("%-g", (Gmatrix)[(i - 1) * Fnphases + j - 1]) + " "; + } + if(i < Fnphases) + result = result + "|"; + } + } + result = result + ")"; + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TFaultObj::MakePosSequence(int ActorID) +{ + if(Fnphases != 1) + { + Parser[ActorID]->SetCmdString("Phases=1"); + Edit(ActorID); + } + inherited::MakePosSequence(ActorID); +} + + + + +} // namespace Fault + + + + diff --git a/OpenDSSC/PDElements/Fault.h b/OpenDSSC/PDElements/Fault.h new file mode 100644 index 0000000..f916a51 --- /dev/null +++ b/OpenDSSC/PDElements/Fault.h @@ -0,0 +1,129 @@ +#ifndef FaultH +#define FaultH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "Arraydef.h" + + + + + + +namespace Fault +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 3-1-00 Restored old Dump + Removed 1.e6 multiplier (where did this come from???) + 9-??-00 Added Temporary fault logic + 9-22-00 Revised Is_ON logic + 7-2-01 Corrected default bus2 phase designation + Force rebuilding of bus lists if num phases changed +*/ + +/* + Fault object: + + One or more faults can be placed across any two buses in the circuit. + Like the capacitor, the second bus defaults to the ground node of the + same bus that bus1 is connected to. + + The fault is basically an uncoupled, multiphase resistance branch. however, + you may also specify it as NODAL CONDUCTANCE (G) matrix, which will give you + complete control of a complex fault situation. + + To eliminate a fault from the system after it has been defined, disable it. + + In Monte Carlo Fault mode, the fault resistance is varied by the % std dev specified + If %Stddev is specified as zero (default), the resistance is varied uniformly. + + Fault may have its "ON" time specified (defaults to 0). When Time (t) exceeds this value, the + fault will be enabled. Else it is disabled. + + Fault may be designated as Temporary. That is, after it is enabled, it will disable itself + if the fault current drops below the MinAmps value. +*/ + +class TFault : public PDClass::TPDClass +{ + friend class TFaultObj; +public: + typedef PDClass::TPDClass inherited; +private: + void DoGmatrix(int ActorID); + void FltSetBus1(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String FaultName); +public: + TFault(); + virtual ~TFault(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TFaultObj : public PDELement::TPDElement +{ + friend class TFault; +public: + typedef PDELement::TPDElement inherited; +private: + double MinAmps; + bool IsTemporary; + bool Cleared; + bool Is_ON; + bool Bus2Defined; + double On_Time; + double RandomMult; + bool FaultStillGoing(int ActorID); +protected: + double G; // single G per phase (line rating) if Gmatrix not specified + Arraydef::pDoubleArray Gmatrix; // If not nil then overrides G + double StdDev; // per unit stddev + int SpecType; +public: + TFaultObj(DSSClass::TDSSClass* ParClass, const String FaultName); + virtual ~TFaultObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + void Randomize(int ActorID); + void CheckStatus(int ControlMode, int ActorID); + void Reset(); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TFaultObj(DSSClass::TDSSClass* ParClass); + TFaultObj(String ClassName); + TFaultObj(); +}; +extern TFaultObj* ActiveFaultObj; + + +} // namespace Fault + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Fault; +#endif + +#endif // FaultH + + + + diff --git a/OpenDSSC/PDElements/GICTransformer.cpp b/OpenDSSC/PDElements/GICTransformer.cpp new file mode 100644 index 0000000..0726c95 --- /dev/null +++ b/OpenDSSC/PDElements/GICTransformer.cpp @@ -0,0 +1,840 @@ + +#pragma hdrstop + +#include "GICTransformer.h" + +#include "ParserDel.h" +#include "MyDSSClassDefs.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Dynamics.h" +#include "Ucomplex.h" +#include "mathutil.h" +#include "Utilities.h" +#include "Circuit.h" + +using namespace std; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace Dynamics; +using namespace MyDSSClassDefs; +using namespace PDClass; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace GICTransformer +{ + +TGICTransformerObj::TGICTransformerObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TGICTransformerObj::TGICTransformerObj(String ClassName) : inherited(ClassName) {} +TGICTransformerObj::TGICTransformerObj() {} + + +TGICTransformerObj* ActiveGICTransformerObj = nullptr; +const int NumPropsThisClass = 15; +const int SPEC_GSU = 1; +const int SPEC_AUTO = 2; +const int SPEC_YY = 3; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Fault objects + +TGICTransformer::TGICTransformer() +{ + ; + Class_Name = "GICTransformer"; + DSSClassType = GIC_Transformer + PD_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGICTransformer::~TGICTransformer() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICTransformer::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + // Define Property names + PropertyName[1 - 1] = "BusH"; + PropertyName[2 - 1] = "BusNH"; + PropertyName[3 - 1] = "BusX"; + PropertyName[4 - 1] = "BusNX"; + PropertyName[5 - 1] = "phases"; + PropertyName[6 - 1] = "Type"; + PropertyName[7 - 1] = "R1"; + PropertyName[8 - 1] = "R2"; + PropertyName[9 - 1] = "KVLL1"; + PropertyName[10 - 1] = "KVLL2"; + PropertyName[11 - 1] = "MVA"; + PropertyName[12 - 1] = "VarCurve"; + PropertyName[13 - 1] = "%R1"; + PropertyName[14 - 1] = "%R2"; + PropertyName[15 - 1] = "K"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of High-side(H) bus. Examples:") + CRLF + + "BusH=busname" + + CRLF + + "BusH=busname.1.2.3"; + PropertyHelp[2 - 1] = "Name of Neutral bus for H, or first, winding. Defaults to all phases connected " + "to H-side bus, node 0, if not specified and transformer type is either GSU or YY. " + "(Shunt Wye Connection to ground reference)" + "For Auto, this is automatically set to the X bus."; + PropertyHelp[3 - 1] = "Name of Low-side(X) bus, if type=Auto or YY. "; + PropertyHelp[4 - 1] = "Name of Neutral bus for X, or Second, winding. Defaults to all phases connected " + "to X-side bus, node 0, if not specified. (Shunt Wye Connection to ground reference)"; + PropertyHelp[5 - 1] = "Number of Phases. Default is 3."; + PropertyHelp[6 - 1] = "Type of transformer: {GSU* | Auto | YY}. Default is GSU."; + PropertyHelp[7 - 1] = "Resistance, each phase, ohms for H winding, (Series winding, if Auto). Default is 0.0001. If "; + PropertyHelp[8 - 1] = "Resistance, each phase, ohms for X winding, (Common winding, if Auto). Default is 0.0001. "; + PropertyHelp[9 - 1] = "Optional. kV LL rating for H winding (winding 1). Default is 500. Required if you are going to export vars for power flow analysis " + "or enter winding resistances in percent."; + PropertyHelp[10 - 1] = "Optional. kV LL rating for X winding (winding 2). Default is 138. Required if you are going to export vars for power flow analysis " + "or enter winding resistances in percent.."; + PropertyHelp[11 - 1] = "Optional. MVA Rating assumed Transformer. Default is 100. Used for computing vars due to GIC and " + "winding resistances if kV and MVA ratings are specified."; + PropertyHelp[12 - 1] = "Optional. XYCurve object name. Curve is expected as TOTAL pu vars vs pu GIC amps/phase. Vars are in pu of the MVA property. No Default value. " + "Required only if you are going to export vars for power flow analysis. " + "See K property."; + PropertyHelp[13 - 1] = String("Optional. Percent Resistance, each phase, for H winding (1), (Series winding, if Auto). Default is 0.2. ") + CRLF + + CRLF + + "Alternative way to enter R1 value. It is the actual resistances in ohmns that matter. MVA and kV should be specified."; + PropertyHelp[14 - 1] = String("Optional. Percent Resistance, each phase, for X winding (2), (Common winding, if Auto). Default is 0.2. ") + CRLF + + CRLF + + "Alternative way to enter R2 value. It is the actual resistances in ohms that matter. MVA and kV should be specified."; + PropertyHelp[15 - 1] = String("Mvar K factor. Default way to convert GIC Amps in H winding (winding 1) to Mvar. Default is 2.2. " "Commonly-used simple multiplier for estimating Mvar losses for power flow analysis. ") + CRLF + + CRLF + + "Mvar = K * kvLL * GIC per phase / 1000 " + + CRLF + + CRLF + + "Mutually exclusive with using the VarCurve property and pu curves." + + "If you specify this (default), VarCurve is ignored."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICTransformer::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TGICTransformerObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICTransformer::GICTransSetBusH(const String s) +{ + String S2; + int dotpos = 0; + + // Set Bus2 = BusH1.0.0.0 + /*# with ActiveGICTransformerObj do */ + { + auto with0 = ActiveGICTransformerObj; + ( (TDSSCktElement*) with0 )->SetBus(1, s); + + // Default Bus2 to zero node of Bus1. (Wye Grounded connection) + + // Strip node designations from S + dotpos = Pos(".", s); + if(dotpos > 0) // copy up to Dot + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); + S2 = S2 + ".0.0.0"; // Set Default for up to 3 phases + ( (TDSSCktElement*) with0 )->SetBus(2, S2); + with0->IsShunt = true; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICTransformer::GICTransSetBusX(const String s) +{ + String S2; + int dotpos = 0; + + // Special handling for Bus X + // Make sure we have enough terminals defined + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveGICTransformerObj do */ + { + auto with0 = ActiveGICTransformerObj; + if( ( (TDSSCktElement*) with0 )->Get_NTerms() != 4) // have to have 4 terminals to set this property + { + ( (TDSSCktElement*) with0 )->Set_NTerms(4); + ( (TDSSCktElement*) with0 )->Set_Nconds(( (TDSSCktElement*) with0 )->Fnphases); // force reallocation of terminals and conductors + } + ( (TDSSCktElement*) with0 )->SetBus(3, s); + + // Default Bus4 to zero node of Bus3. (Wye Grounded connection) + + // Strip node designations from S + dotpos = Pos(".", s); + if(dotpos > 0) // copy up to Dot + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); + S2 = S2 + ".0.0.0"; // Set Default for up to 3 phases + ( (TDSSCktElement*) with0 )->SetBus(4, S2); + with0->IsShunt = true; + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICTransformer::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveGICTransformerObj = (TGICTransformerObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveGICTransformerObj); // use property to set this value + /*# with ActiveGICTransformerObj do */ + { + auto with0 = ActiveGICTransformerObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + ( (TDSSCktElement*) with0 )->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + ( (TDSSCktElement*) with0 )->get_Name() + + "\"", 350); + break; + case 1: + GICTransSetBusH(Param); + break; + case 2: + ( (TDSSCktElement*) with0 )->SetBus(2, Param); + break; + case 3: + GICTransSetBusX(Param); + break; + case 4: + ( (TDSSCktElement*) with0 )->SetBus(4, Param); + break; + case 5: + ; + break; // see below + case 6: + switch(UpperCase(Param)[0]) + { + case L'G': + with0->SpecType = SPEC_GSU; + break; + case L'A': + with0->SpecType = SPEC_AUTO; + break; + case L'Y': + with0->SpecType = SPEC_YY; + break; + default: + ; + break; + } + break; + case 7: + { + with0->G1 = Parser[ActorID]->MakeDouble_(); + if(with0->G1 != 0.0) + with0->G1 = 1.0 / with0->G1; + else + with0->G1 = 10000.0; // Default to a low resistance + } + break; + case 8: + { + with0->G2 = Parser[ActorID]->MakeDouble_(); + if(with0->G2 != 0.0) + with0->G2 = 1.0 / with0->G2; + else + with0->G2 = 10000.0; // Default to a low resistance + } + break; + case 9: + with0->FkV1 = Parser[ActorID]->MakeDouble_(); + break; + case 10: + with0->FkV2 = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->FMVARating = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->FVarCurve = Param; + break; + case 13: + with0->FpctR1 = Parser[ActorID]->MakeDouble_(); + break; + case 14: + with0->FpctR2 = Parser[ActorID]->MakeDouble_(); + break; + case 15: + with0->FKFactor = Parser[ActorID]->MakeDouble_(); + break; + // Inherited + default: + inherited::ClassEdit(ActiveGICTransformerObj, ParamPointer - NumPropsThisClass); + break; + } + + // Some specials ... + switch(ParamPointer) + { + case 1: + ( (TDSSCktElement*) with0 )->Set_PropertyValue(2,( (TDSSCktElement*) with0 )->GetBus(2)); + break; // Bus2 gets modified if bus1 is set + case 3: + { + ( (TDSSCktElement*) with0 )->Set_PropertyValue(4,( (TDSSCktElement*) with0 )->GetBus(4)); // Bus4 gets modified if bus3(X) is set + if(with0->SpecType == SPEC_AUTO) // automatically make up series-to-common connection + { + ( (TDSSCktElement*) with0 )->SetBus(2, ( (TDSSCktElement* )with0 )->GetBus(3)); + ( (TDSSCktElement*) with0 )->Set_PropertyValue(2,( (TDSSCktElement*) with0 )->GetBus(2)); + } + } + break; + case 5: + if( ( (TDSSCktElement*) with0 )->Fnphases != Parser[ActorID]->MakeInteger_()) + { + ( (TDSSCktElement*) with0 )->Set_NPhases(Parser[ActorID]->MakeInteger_()); + ( (TDSSCktElement*) with0 )->Set_Nconds(( (TDSSCktElement*) with0 )->Fnphases); // Force Reallocation of terminal info if different size + ActiveCircuit[ActiveActor]->Set_BusNameRedefined(true); // Set Global Flag to signal circuit to rebuild busdefs + } + break; + case 6: + switch(with0->SpecType) + { + case SPEC_AUTO: + { + if( ( (TDSSCktElement*) with0 )->Get_NTerms() == 2) + { + ( (TDSSCktElement*) with0 )->Set_NTerms(4); + ( (TDSSCktElement*) with0 )->Set_Nconds(( (TDSSCktElement*) with0 )->Fnphases); + } + ( (TDSSCktElement*) with0 )->SetBus(2, ( (TDSSCktElement*) with0 )->GetBus(3)); + } + break; + default: + ; + break; + } + break; + case 7: case 8: + with0->FpctRSpecified = false; + break; + case 9: case 10: + with0->FkVSpecified = true; + break; + case 12: + { + with0->FVarCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->FVarCurve)); + with0->KSpecified = false; + } + break; + case 13: case 14: + with0->FpctRSpecified = true; + break; + case 15: + with0->KSpecified = true; + break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values or no. of terminals + switch(ParamPointer) + { + case 3: case 4: case 5: case 6: case 7: case 8: + ( (TDSSCktElement*) with0 )->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICTransformer::MakeLike(const String GICTransName) +{ + int result = 0; + TGICTransformerObj* OtherGICTrans = nullptr; + int i = 0; + result = 0; + /*See if we can find this Fault name in the present collection*/ + OtherGICTrans = ((TGICTransformerObj*) Find(GICTransName)); + if(OtherGICTrans != nullptr) + /*# with ActiveGICTransformerObj do */ + { + auto with0 = ActiveGICTransformerObj; + int stop = 0; + if(((TDSSCktElement*)with0)->Fnphases != ((TDSSCktElement*)OtherGICTrans)->Fnphases) + { + ((TDSSCktElement*)with0)->Fnphases = ((TDSSCktElement*)OtherGICTrans)->Fnphases; + ((TDSSCktElement*)with0)->Fnterms = ((TDSSCktElement*)OtherGICTrans)->Fnterms; + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)with0)->Fnphases); // force reallocation of terminals and conductors + ((TDSSCktElement*)with0)->Yorder = ((TDSSCktElement*)with0)->Fnconds * ((TDSSCktElement*)with0)->Fnterms; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActiveActor,true); + } + ((TDSSCktElement*)with0)->BaseFrequency = ((TDSSCktElement*)OtherGICTrans)->BaseFrequency; + with0->G1 = OtherGICTrans->G1; + with0->G2 = OtherGICTrans->G2; + with0->SpecType = OtherGICTrans->SpecType; + with0->FMVARating = OtherGICTrans->FMVARating; + with0->FVarCurve = OtherGICTrans->FVarCurve; + with0->FVarCurveObj = OtherGICTrans->FVarCurveObj; + with0->FkV1 = OtherGICTrans->FkV1; + with0->FkV2 = OtherGICTrans->FkV2; + with0->FpctR1 = OtherGICTrans->FpctR1; + with0->FpctR2 = OtherGICTrans->FpctR2; + with0->FpctRSpecified = OtherGICTrans->FpctRSpecified; + with0->FkVSpecified = OtherGICTrans->FkVSpecified; + with0->FZbase1 = OtherGICTrans->FZbase1; + with0->FZbase2 = OtherGICTrans->FZbase2; + with0->FKFactor = OtherGICTrans->FKFactor; + with0->KSpecified = OtherGICTrans->KSpecified; + ClassMakeLike(OtherGICTrans); + for(stop = ((TDSSCktElement*)with0)->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + ((TDSSCktElement*)with0)->Set_PropertyValue(i,((TDSSCktElement*)OtherGICTrans)->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in GICTransformer MakeLike: \"") + GICTransName + + "\" Not Found.", 351); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TGICTransformer::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TGICTransformer.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TGICTransformer Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGICTransformerObj::TGICTransformerObj(TDSSClass* ParClass, const String FaultName) + : inherited(ParClass), + G1(10000.0), + G2(10000.0), + SpecType(SPEC_GSU), + FMVARating(100.0), + FVarCurve(""), + FVarCurveObj(nullptr), + FpctR1(0.2), + FpctR2(0.2), + FZbase1(0.0), + FZbase2(0.0), + FkVSpecified(false), + FpctRSpecified(false), + KSpecified(false), + FKFactor(0.0), + FkV1(0.0), + FkV2(0.0) +{ + DSSObjType = ParClass->DSSClassType; + Set_Name(LowerCase(FaultName)); + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(2); // Force allocation of terminals and conductors + SetBus(2, (GetBus(1) + ".0")); // Default to grounded + IsShunt = true; + FkVSpecified = false; + FkV1 = 500.0; + FkV2 = 138.0; + FKFactor = 2.2; + KSpecified = true; + NormAmps = 0.0; + EmergAmps = 0.0; + FaultRate = 0.0; + PctPerm = 100.0; + HrsToRepair = 0.0; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + FpctRSpecified = true; // Force computation of G1, G2 + RecalcElementData(ActiveActor); + FpctRSpecified = false; // Turn flag off +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TGICTransformerObj::~TGICTransformerObj() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICTransformerObj::RecalcElementData(int ActorID) +{ + FZbase1 = Sqr(FkV1) / FMVARating; + FZbase2 = Sqr(FkV2) / FMVARating; + if(FpctRSpecified) + { + G1 = 100.0 / (FZbase1 * FpctR1); + G2 = 100.0 / (FZbase2 * FpctR1); + } + else + { + FpctR1 = 100.0 / (FZbase1 * G1); + FpctR2 = 100.0 / (FZbase2 * G2); + } +} + +//- - - - - - - - VAR EXPORT - - - - - - - - - - - - - - - - - - - - + +void TGICTransformerObj::WriteVarOutputRecord(TTextRec& f, int ActorID) +{ + complex Curr = {}; + double MVarMag = 0.0; + double GICperPhase = 0.0; + double puCurrMag = 0.0; + int i = 0; + int stop = 0; + ComputeIterminal(ActorID); + Curr = CZero; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + caccum(Curr, (Iterminal)[i - 1]); + } + GICperPhase = cabs(Curr) / Fnphases; + if(KSpecified) + { + MVarMag = FKFactor * FkV1 * GICperPhase / 1000.0; + } + else + { + if(ASSIGNED(FVarCurveObj)) + // MVA = sqrt(3) * kVLL * I/1000 + // pu A per phase (Avg) + { + puCurrMag = GICperPhase / (FMVARating * 1000.0 / FkV1 / SQRT3); + MVarMag = FVarCurveObj->GetYValue_(puCurrMag) * FMVARating / SQRT2; + } + else + MVarMag = 0.0; + } + WriteLn(f, Format("%s, %.8g, %.8g", GetBus(1).c_str(), MVarMag, GICperPhase) ); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TGICTransformerObj::CalcYPrim(int ActorID) +{ + complex Value = {}; + complex Value2 = {}; + int i = 0; + TcMatrix* YPrimTemp = nullptr; + if(Get_YprimInvalid(ActorID,0)) // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + if(IsShunt) + YPrimTemp = YPrim_Shunt; + else + YPrimTemp = YPrim_Series; + + // make sure randommult is 1.0 if not solution mode MonteFault + /*# with YPrimTemp do */ + { + auto with0 = YPrimTemp; + + /* Now, Put in Yprim matrix */ + + /*If the fault is not ON, the set zero conductance*/ + switch(SpecType) + { + case SPEC_GSU: + { + int stop = 0; + Value = cmplx(G1, 0.0); + Value2 = cnegate(Value); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } /*For*/ + } + break; + // Terminals 1 and 2 + case SPEC_AUTO: + { + int stop = 0; + Value = cmplx(G1, 0.0); + Value2 = cnegate(Value); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } /*For*/ + // Terminals 3 and 4 + Value = cmplx(G2, 0.0); + Value2 = cnegate(Value); + for(stop = 3 * Fnphases, i = (2 * Fnphases + 1); i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } /*For*/ + } + break; + // Terminals 1 and 2 + case SPEC_YY: + { + int stop = 0; + Value = cmplx(G1, 0.0); + Value2 = cnegate(Value); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } /*For*/ + // Terminals 3 and 4 + Value = cmplx(G2, 0.0); + Value2 = cnegate(Value); + for(stop = 3 * Fnphases, i = (2 * Fnphases + 1); i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, Value2); + } /*For*/ + } + break; + default: + ; + break; + } + } /*With YPRIM*/ + YPrim->CopyFrom(YPrimTemp); + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TGICTransformerObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { Write(f, "~ "); Write(f, (with0->PropertyName)[1 - 1]); Write(f, L'='); WriteLn(f, Get_FirstBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[2 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[3 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[4 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[5 - 1]); Write(f, L'='); WriteLn(f, Fnphases, 0); } + switch(SpecType) + { + case SPEC_GSU: + { Write(f, "~ "); Write(f, (with0->PropertyName)[6 - 1]); WriteLn(f, "= GSU"); } + break; + case SPEC_AUTO: + { Write(f, "~ "); Write(f, (with0->PropertyName)[6 - 1]); WriteLn(f, "= AUTO"); } + break; + case SPEC_YY: + { Write(f, "~ "); Write(f, (with0->PropertyName)[6 - 1]); WriteLn(f, "= YY"); } + break; + default: + ; + break; + } + { Write(f, "~ "); Write(f, (with0->PropertyName)[7 - 1]); Write(f, L'='); WriteLn(f, Format("%.8g", 1.0 / G1)); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[8 - 1]); Write(f, L'='); WriteLn(f, Format("%.8g", 1.0 / G2)); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[9 - 1]); Write(f, L'='); WriteLn(f, FkV1, 0, 2); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[10 - 1]); Write(f, L'='); WriteLn(f, FkV2, 0, 2); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[11 - 1]); Write(f, L'='); WriteLn(f, FMVARating, 0, 2); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[12 - 1]); Write(f, L'='); WriteLn(f, FVarCurve); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[13 - 1]); Write(f, L'='); WriteLn(f, Format("%.8g", FpctR1)); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[14 - 1]); Write(f, L'='); WriteLn(f, Format("%.8g", FpctR2)); } + for(stop = with0->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } +} + +void TGICTransformerObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,GetBus(3)); + Set_PropertyValue(4,GetBus(4)); + Set_PropertyValue(5,"3"); + Set_PropertyValue(6,"GSU"); + Set_PropertyValue(7,"0.0001"); + Set_PropertyValue(8,"0.0001"); + Set_PropertyValue(9,"500"); + Set_PropertyValue(10,"138"); + Set_PropertyValue(11,"100"); + Set_PropertyValue(12,""); + Set_PropertyValue(13,"0.2"); + Set_PropertyValue(14,"0.2"); + Set_PropertyValue(15,"2.2"); + inherited::InitPropertyValues(NumPropsThisClass); + + // Override Inherited Properties + Set_PropertyValue(NumPropsThisClass + 1,"0"); //Normamps + Set_PropertyValue(NumPropsThisClass + 2,"0"); //emergamps + Set_PropertyValue(NumPropsThisClass + 3,"0"); //Fault rate + Set_PropertyValue(NumPropsThisClass + 4,"0"); // Pct Perm + Set_PropertyValue(NumPropsThisClass + 5,"0"); // Hrs to repair +} + +String TGICTransformerObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 1: + result = GetBus(1); + break; + case 2: + result = GetBus(2); + break; + case 3: + result = GetBus(3); + break; + case 4: + result = GetBus(4); + break; + case 5: + result = Format("%d", Get_NPhases()); + break; + case 7: + result = Format("%.8g", 1.0 / G1); + break; + case 8: + result = Format("%.8g", 1.0 / G2); + break; + case 9: + result = Format("%.8g", FkV1); + break; + case 10: + result = Format("%.8g", FkV2); + break; + case 11: + result = Format("%.8g", FMVARating); + break; + case 12: + result = FVarCurve; + break; + case 13: + result = Format("%.8g", FpctR1); + break; + case 14: + result = Format("%.8g", FpctR2); + break; + case 15: + result = Format("%.8g", FKFactor); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TGICTransformerObj::MakePosSequence(int ActorID) +{ + if(Fnphases != 1) + { + Parser[ActorID]->SetCmdString("Phases=1"); + Edit(ActorID); + } + inherited::MakePosSequence(ActorID); +} + + + + +} // namespace GICTransformer + + + + diff --git a/OpenDSSC/PDElements/GICTransformer.h b/OpenDSSC/PDElements/GICTransformer.h new file mode 100644 index 0000000..575d975 --- /dev/null +++ b/OpenDSSC/PDElements/GICTransformer.h @@ -0,0 +1,106 @@ +#ifndef GICTransformerH +#define GICTransformerH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "Arraydef.h" +#include "XYcurve.h" + + + +namespace GICTransformer +{ + + + +/* + ---------------------------------------------------------- + Copyright (c) 2011-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 6-21-2011 Created from Fault Object +*/ + +/* + + Special resistance-only model of transformers for geomagnetically-induced current (GIC) studies +*/ + +class TGICTransformer : public PDClass::TPDClass +{ + friend class TGICTransformerObj; +public: + typedef PDClass::TPDClass inherited; +private: + void GICTransSetBusH(const String s); + void GICTransSetBusX(const String s); +protected: + void DefineProperties(); + virtual int MakeLike(const String GICTransName); +public: + TGICTransformer(); + virtual ~TGICTransformer(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TGICTransformerObj : public PDELement::TPDElement +{ + friend class TGICTransformer; +public: + typedef PDELement::TPDElement inherited; +private: + double G1; + double G2; // single G per phase (line rating) + int SpecType; + double FMVARating; + String FVarCurve; + XYCurve::TXYcurveObj* FVarCurveObj; + double FpctR1; + double FpctR2; + double FZbase1; + double FZbase2; + bool FkVSpecified; + bool FpctRSpecified; + bool KSpecified; + double FKFactor; + double FkV1; + double FkV2; +public: + TGICTransformerObj(DSSClass::TDSSClass* ParClass, const String FaultName); + virtual ~TGICTransformerObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + void WriteVarOutputRecord(System::TTextRec& f, int ActorID); // Add a record to the ouput file based on present GIC + TGICTransformerObj(DSSClass::TDSSClass* ParClass); + TGICTransformerObj(String ClassName); + TGICTransformerObj(); +}; +extern TGICTransformerObj* ActiveGICTransformerObj; + + +} // namespace GICTransformer + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace GICTransformer; +#endif + +#endif // GICTransformerH + + + + diff --git a/OpenDSSC/PDElements/Line.cpp b/OpenDSSC/PDElements/Line.cpp new file mode 100644 index 0000000..e8db04d --- /dev/null +++ b/OpenDSSC/PDElements/Line.cpp @@ -0,0 +1,2470 @@ + + +#pragma hdrstop + +#include "Line.h" + +#include "ControlElem.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "mathutil.h" +#include "Circuit.h" + + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace ConductorData; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace LineCode; +using namespace LineGeometry; +using namespace LineSpacing; +using namespace LineUnits; +using namespace PDClass; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace Line +{ + +TLineObj::TLineObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TLineObj::TLineObj(String ClassName) : inherited(ClassName) {} +TLineObj::TLineObj() {} + + +TLineObj* ActiveLineObj = nullptr; +TLineGeometry* LineGeometryClass = nullptr; +const int NumPropsThisClass = 30; + // MaxPhases = 20; // for fixed buffers +complex CAP_EPSILON = {}; +const double ONE_THIRD = 1.0 / 3.0; // Do this to get more precision in next few statements + +TLineCode* LineCodeClass = nullptr; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Line objects + +TLine::TLine() +{ + ; + Class_Name = "Line"; + DSSClassType = DSSClassType + LINE_ELEMENT; // in both PDElement list and Linesection lists + ActiveElement = 0; + LineCodeClass = nullptr; + LineGeometryClass = nullptr; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLine::~TLine() +{ + + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLine::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "bus2"; + PropertyName[3 - 1] = "linecode"; + PropertyName[4 - 1] = "length"; + PropertyName[5 - 1] = "phases"; + PropertyName[6 - 1] = "r1"; + PropertyName[7 - 1] = "x1"; + PropertyName[8 - 1] = "r0"; + PropertyName[9 - 1] = "x0"; + PropertyName[10 - 1] = "C1"; + PropertyName[11 - 1] = "C0"; + PropertyName[12 - 1] = "rmatrix"; + PropertyName[13 - 1] = "xmatrix"; + PropertyName[14 - 1] = "cmatrix"; + PropertyName[15 - 1] = "Switch"; + PropertyName[16 - 1] = "Rg"; + PropertyName[17 - 1] = "Xg"; + PropertyName[18 - 1] = "rho"; + PropertyName[19 - 1] = "geometry"; + PropertyName[20 - 1] = "units"; + PropertyName[21 - 1] = "spacing"; + PropertyName[22 - 1] = "wires"; + PropertyName[23 - 1] = "EarthModel"; + PropertyName[24 - 1] = "cncables"; + PropertyName[25 - 1] = "tscables"; + PropertyName[26 - 1] = "B1"; + PropertyName[27 - 1] = "B0"; + PropertyName[28 - 1] = "Seasons"; + PropertyName[29 - 1] = "Ratings"; + PropertyName[30 - 1] = "LineType"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of bus to which first terminal is connected.") + CRLF + + "Example:" + + CRLF + + "bus1=busname (assumes all terminals connected in normal phase order)" + + CRLF + + "bus1=busname.3.1.2.0 (specify terminal to node connections explicitly)"; + PropertyHelp[2 - 1] = "Name of bus to which 2nd terminal is connected."; + PropertyHelp[3 - 1] = String("Name of linecode object describing line impedances.") + CRLF + + "If you use a line code, you do not need to specify the impedances here. " + + "The line code must have been PREVIOUSLY defined. " + + "The values specified last will prevail over those specified earlier (left-to-right " + + "sequence of properties). You can subsequently change the number of phases if symmetrical component quantities are specified." + + "If no line code or impedance data are specified, the line object " + + "defaults to 336 MCM ACSR on 4 ft spacing."; + PropertyHelp[4 - 1] = "Length of line. Default is 1.0. If units do not match the impedance data, specify \"units\" property. "; + PropertyHelp[5 - 1] = "Number of phases, this line."; + PropertyHelp[6 - 1] = "Positive-sequence Resistance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Rmatrix."; + PropertyHelp[7 - 1] = "Positive-sequence Reactance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Xmatrix"; + PropertyHelp[8 - 1] = "Zero-sequence Resistance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition."; + PropertyHelp[9 - 1] = "Zero-sequence Reactance, ohms per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition."; + PropertyHelp[10 - 1] = "Positive-sequence capacitance, nf per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition. See also Cmatrix and B1."; + PropertyHelp[11 - 1] = "Zero-sequence capacitance, nf per unit length. Setting any of R1, R0, X1, X0, C1, C0 forces " + "the program to use the symmetrical component line definition.See also B0."; + PropertyHelp[12 - 1] = "Resistance matrix, lower triangle, ohms per unit length. Order of the matrix is the number of phases. " + "May be used to specify the impedance of any line configuration. Using any of Rmatrix, Xmatrix, Cmatrix " + "forces program to use the matrix values for line impedance definition. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + PropertyHelp[13 - 1] = "Reactance matrix, lower triangle, ohms per unit length. Order of the matrix is the number of phases. " + "May be used to specify the impedance of any line configuration. Using any of Rmatrix, Xmatrix, Cmatrix " + "forces program to use the matrix values for line impedance definition. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + PropertyHelp[14 - 1] = "Nodal Capacitance matrix, lower triangle, nf per unit length.Order of the matrix is the number of phases. " + "May be used to specify the shunt capacitance of any line configuration. Using any of Rmatrix, Xmatrix, Cmatrix " + "forces program to use the matrix values for line impedance definition. For balanced line models, you may " + "use the standard symmetrical component data definition instead."; + PropertyHelp[15 - 1] = String("{y/n | T/F} Default= no/false. Designates this line as a switch for graphics and algorithmic purposes. ") + CRLF + + "SIDE EFFECT: Sets r1 = 1.0; x1 = 1.0; r0 = 1.0; x0 = 1.0; c1 = 1.1 ; c0 = 1.0; length = 0.001; You must reset if you want something different."; + PropertyHelp[16 - 1] = "Carson earth return resistance per unit length used to compute impedance values at base frequency. " + "Default is 0.01805 = 60 Hz value in ohms per kft (matches default line impedances). " + "This value is required for harmonic solutions if you wish to adjust the earth return impedances for frequency. " + "If not, set both Rg and Xg = 0."; + PropertyHelp[17 - 1] = "Carson earth return reactance per unit length used to compute impedance values at base frequency. For making better frequency adjustments. " + "Default is 0.155081 = 60 Hz value in ohms per kft (matches default line impedances). " + "This value is required for harmonic solutions if you wish to adjust the earth return impedances for frequency. " + "If not, set both Rg and Xg = 0."; + PropertyHelp[18 - 1] = "Default=100 meter ohms. Earth resitivity used to compute earth correction factor. Overrides Line geometry definition if specified."; + PropertyHelp[19 - 1] = "Geometry code for LineGeometry Object. Supercedes any previous definition of line impedance. " + "Line constants are computed for each frequency change or rho change. CAUTION: may alter number of phases. " + "You cannot subsequently change the number of phases unless you change how the line impedance is defined."; + PropertyHelp[20 - 1] = "Length Units = {none | mi|kft|km|m|Ft|in|cm } Default is None - assumes length units match impedance units."; + PropertyHelp[21 - 1] = String("Reference to a LineSpacing for use in a line constants calculation.") + CRLF + + "Must be used in conjunction with the Wires property." + + CRLF + + "Specify this before the wires property."; + PropertyHelp[22 - 1] = String("Array of WireData names for use in an overhead line constants calculation.") + CRLF + + "Must be used in conjunction with the Spacing property." + + CRLF + + "Specify the Spacing first, and \"ncond\" wires." + + CRLF + + "May also be used to specify bare neutrals with cables, using \"ncond-nphase\" wires."; + PropertyHelp[23 - 1] = "One of {Carson | FullCarson | Deri}. Default is the global value established with the Set EarthModel command. " + "See the Options Help on EarthModel option. This is used to override the global value for this line. This " + "option applies only when the \"geometry\" property is used."; + PropertyHelp[24 - 1] = String("Array of CNData names for use in a cable constants calculation.") + CRLF + + "Must be used in conjunction with the Spacing property." + + CRLF + + "Specify the Spacing first, using \"nphases\" cncables." + + CRLF + + "You may later specify \"nconds-nphases\" wires for separate neutrals"; + PropertyHelp[25 - 1] = String("Array of TSData names for use in a cable constants calculation.") + CRLF + + "Must be used in conjunction with the Spacing property." + + CRLF + + "Specify the Spacing first, using \"nphases\" tscables." + + CRLF + + "You may later specify \"nconds-nphases\" wires for separate neutrals"; + PropertyHelp[26 - 1] = "Alternate way to specify C1. MicroS per unit length"; + PropertyHelp[27 - 1] = "Alternate way to specify C0. MicroS per unit length"; + PropertyHelp[28 - 1] = "Defines the number of ratings to be defined for the wire, to be used only when defining seasonal ratings using the \"Ratings\" property."; + PropertyHelp[29 - 1] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in lines."; + PropertyHelp[30 - 1] = String("Code designating the type of line. ") + CRLF + + "One of: OH, UG, UG_TS, UG_CN, SWT_LDBRK, SWT_FUSE, SWT_SECT, SWT_REC, SWT_DISC, SWT_BRK, SWT_ELBOW, BUSBAR" + + CRLF + + CRLF + + "OpenDSS currently does not use this internally. For whatever purpose the user defines. Default is OH."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + PropertyHelp[NumPropsThisClass + 3 - 1] = "Failure rate PER UNIT LENGTH per year. Length must be same units as LENGTH property. Default is 0.1 fault per unit length per year."; + PropertyHelp[NumPropsThisClass + 4 - 1] = PropertyHelp[NumPropsThisClass + 4 - 1] + " Default is 20."; + PropertyHelp[NumPropsThisClass + 5 - 1] = PropertyHelp[NumPropsThisClass + 5 - 1] + " Default is 3 hr."; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLine::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TLineObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + +void TLineObj::UpdatePDProperties() +{ + String TempStr; + int j = 0; + int stop = 0; + Set_PropertyValue(28,Format("%-d", NumAmpRatings)); + TempStr = "["; + for(int stop = NumAmpRatings, j = 1; j <= stop; j++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[j - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + Set_PropertyValue(29,TempStr); + Set_PropertyValue(NumPropsThisClass + 1,to_string(NormAmps)); + Set_PropertyValue(NumPropsThisClass + 2,to_string(EmergAmps)); + // commented out 8/26/2014 + // PropertyValue[NumPropsThisClass + 3] := Format('%-g', [FaultRate]); + // PropertyValue[NumPropsThisClass + 4] := Format('%-g', [PctPerm]); + // PropertyValue[NumPropsThisClass + 5] := Format('%-g', [HrsToRepair]); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineObj::FetchLineCode(const String Code) +{ + TLineCodeObj* LineCodeObj = nullptr; + int i = 0; + if(LineCodeClass == nullptr) + LineCodeClass = (TLineCode*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("linecode")); + if(LineCodeClass->SetActive(Code)) + { + LineCodeObj = ((TLineCodeObj*) LineCodeClass->GetActiveObj()); + CondCode = LowerCase(Code); + + // Frequency compensation takes place in calcYPrim. + BaseFrequency = LineCodeObj->BaseFrequency; + /*Copy impedances from line code, but do not recalc because symmetrical + component z's may not match what's in matrix*/ + if(LineCodeObj->SymComponentsModel) + { + R1 = LineCodeObj->R1; + X1 = LineCodeObj->X1; + R0 = LineCodeObj->R0; + X0 = LineCodeObj->X0; + C1 = LineCodeObj->C1; + C0 = LineCodeObj->C0; + SymComponentsModel = true; + } + else + SymComponentsModel = false; + + + // Earth return impedances used to compensate for frequency + Rg = LineCodeObj->Rg; + Xg = LineCodeObj->Xg; + rho = LineCodeObj->rho; + KXg = Xg / log(658.5L * sqrt(rho / BaseFrequency)); + FLineCodeUnits = LineCodeObj->Units; + FLineCodeSpecified = true; + FUnitsConvert = ConvertLineUnits(FLineCodeUnits, LengthUnits); + NormAmps = LineCodeObj->NormAmps; + EmergAmps = LineCodeObj->EmergAmps; + NumAmpRatings = LineCodeObj->NumAmpRatings; + AmpRatings = LineCodeObj->AmpRatings; + + // These three properties should not come from the Linecode + // But can vary from line section to line section + // commented out 8/26/2014 + // FaultRate := LineCodeObj.FaultRate; + // PctPerm := LineCodeObj.PctPerm; + // HrsToRepair := LineCodeObj.HrsToRepair; + UpdatePDProperties(); + if(Fnphases != LineCodeObj->Fnphases) + { + Set_NPhases(LineCodeObj->Fnphases); + ReallocZandYcMatrices(); + } + if(!SymComponentsModel) // Copy matrices + { + Z->CopyFrom(LineCodeObj->Z); + /*Zinv.CopyFrom(LineCodeObj.Zinv);*/ // no need to copy Zinv + YC->CopyFrom(LineCodeObj->YC); + } + else + RecalcElementData(ActiveActor); // Compute matrices + Set_Nconds(Fnphases); // Force Reallocation of terminal info + //Fnconds := Fnphases; + Yorder = Fnconds * Fnterms; + // Set_YprimInvalid[ActorID] := True; (set in Edit; this is redundant) + FLineType = LineCodeObj->FLineType; + } + else + DoSimpleMsg("Line Code:" + Code + " not found for Line object Line." + get_Name(), 180); +} + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLine::DoRmatrix(int ActorID) +{ + int OrderFound = 0; + int Norder = 0; + int j = 0; + pDoubleArray MatBuffer; + pComplexArray Zvalues; + /*# with ActiveLineObj do */ + { + auto with0 = ActiveLineObj; + /*Added 3-17-15 in case Z and Yc do not get allocated to the proper value*/ + if(with0->Z->get_Norder() != with0->Fnphases) + with0->ReallocZandYcMatrices(); + MatBuffer = new double[with0->Fnphases * with0->Fnphases]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix(with0->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful + /*R*/ + { + Zvalues = with0->Z->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(int stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Zvalues)[j - 1].re = (MatBuffer)[j - 1]; + } + } + } + delete[] MatBuffer; //# FreeMemory accepts one parameter only; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLine::DoXmatrix(int ActorID) +{ + int OrderFound = 0; + int Norder = 0; + int j = 0; + pDoubleArray MatBuffer; + pComplexArray Zvalues; + /*# with ActiveLineObj do */ + { + auto with0 = ActiveLineObj; + if(with0->Z->get_Norder() != with0->Fnphases) + with0->ReallocZandYcMatrices(); + MatBuffer = new double[with0->Fnphases * with0->Fnphases]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix(with0->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful + /*X*/ + { + Zvalues = with0->Z->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(int stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Zvalues)[j - 1].im = (MatBuffer)[j - 1]; + } + } + } + delete[] MatBuffer; //# FreeMemory accepts one parameter only; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLine::DoCmatrix(int ActorID) +{ + int OrderFound = 0; + int Norder = 0; + int j = 0; + pDoubleArray MatBuffer; + pComplexArray YValues; + double Factor = 0.0; + /*# with ActiveLineObj do */ + { + auto with0 = ActiveLineObj; + if(with0->Z->get_Norder() != with0->Fnphases) + with0->ReallocZandYcMatrices(); + MatBuffer = new double[with0->Fnphases * with0->Fnphases]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix(with0->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful + /*X*/ + { + Factor = TwoPi * with0->BaseFrequency * 1.0e-9; + YValues = with0->YC->GetValuesArrayPtr(Norder); + if(Norder == with0->Fnphases) + { + int stop = 0; + for(int stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (YValues)[j - 1].im = Factor * (MatBuffer)[j - 1]; + } + } + } + delete[] MatBuffer; //# FreeMemory accepts one parameter only; + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// A Line Defaults to 3-phases and some typical symmetrical component data +/* + Line impedances are specified in per unit length and are multiplied by the length + when the primitive Y matrix is computed. + + You may specify the impedances of the line either by symmetrical components or + by R, X, and nodal C matrices (also per unit length). + + All C's is entered in nano farads. + + The ultimate values are in the matrices. If you specify matrices, then the symmetrical + component values are ignored. However, if you change any of the symmetrical component values + the matrices will be recomputed. It is assumed you want to use symmetrical component values. + Don't mix data entry by matrix and by symmetrical components. + + Note that if you change the number of phases, the matrices are reallocated and reinitialized + with whatever is currently in the symmetrical component data. + +*/ + +int TLine::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int NewLengthUnits = 0; + result = 0; + // continue parsing with contents of Parser + ActiveLineObj = (TLineObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveLineObj); // use property to set this value + /*# with ActiveLineObj do */ + { + auto with0 = ActiveLineObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"Line." + + with0->get_Name() + + "\"", 181); + break; + case 1: + with0->SetBus(1, Param); + break; + case 2: + with0->SetBus(2, Param); + break; + case 3: + with0->FetchLineCode(Param); + break; // Define line by conductor code + case 4: + with0->Len = Parser[ActorID]->MakeDouble_(); + break; /*Nphases: See below*/ + case 5: + ; + break; + case 6: + with0->R1 = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->X1 = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->R0 = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->X0 = Parser[ActorID]->MakeDouble_(); + break; + case 10: + { + with0->C1 = Parser[ActorID]->MakeDouble_() * 1.0e-9; + with0->FCapSpecified = true; + } + break; // Convert from nano to farads + case 11: + { + with0->C0 = Parser[ActorID]->MakeDouble_() * 1.0e-9; + with0->FCapSpecified = true; + } + break; + case 12: + DoRmatrix(ActorID); + break; + case 13: + DoXmatrix(ActorID); + break; + case 14: + { + DoCmatrix(ActorID); + with0->FCapSpecified = true; + } + break; + case 15: + with0->IsSwitch = InterpretYesNo(Param); + break; + case 16: + with0->Rg = Parser[ActorID]->MakeDouble_(); + break; + case 17: + with0->Xg = Parser[ActorID]->MakeDouble_(); + break; + case 18: + { + with0->rho = Parser[ActorID]->MakeDouble_(); + with0->FrhoSpecified = true; + } + break; + case 19: + with0->FetchGeometryCode(Param); + break; // Update units conversion factor that might have been changed previously + case 20: + { + NewLengthUnits = GetUnitsCode(Param); + if(with0->FLineCodeSpecified) + with0->FUnitsConvert = ConvertLineUnits(with0->FLineCodeUnits, NewLengthUnits); + else + with0->FUnitsConvert = with0->FUnitsConvert * ConvertLineUnits(with0->LengthUnits, NewLengthUnits); + with0->LengthUnits = NewLengthUnits; + with0->FUserLengthUnits = with0->LengthUnits; + } + break; + case 21: + with0->FetchLineSpacing(Param); + break; + case 22: + with0->FetchWireList(Param); + break; + case 23: + with0->FEarthModel = InterpretEarthModel(Param); + break; + case 24: + with0->FetchCNCableList(Param); + break; + case 25: + with0->FetchTSCableList(Param); + break; + case 26: + { + with0->C1 = Parser[ActorID]->MakeDouble_() / (TwoPi * with0->BaseFrequency) * 1.0e-6 / with0->FUnitsConvert; + with0->FCapSpecified = true; + } + break; + case 27: + { + with0->C0 = Parser[ActorID]->MakeDouble_() / (TwoPi * with0->BaseFrequency) * 1.0e-6 / with0->FUnitsConvert; + with0->FCapSpecified = true; + } + break; + case 28: + { + with0->NumAmpRatings = Parser[ActorID]->MakeInteger_(); + with0->AmpRatings.resize( with0->NumAmpRatings ); + } + break; + case 29: + { + with0->AmpRatings.resize( with0->NumAmpRatings ); + Param = Parser[ActiveActor]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, &( with0->AmpRatings[0])); + } + break; + case 30: + with0->FLineType = LineTypeList.Getcommand(Param); + break; + // Inherited Property Edits + default: + ClassEdit(ActiveLineObj, ParamPointer - NumPropsThisClass); + break; + } + + // Side Effects ... + switch(ParamPointer) + { + case 3: + { + with0->SpacingSpecified = false; + if(with0->GeometrySpecified == true) + with0->KillGeometrySpecified(); + with0->GeometrySpecified = false; + } + break; // for Reliability calcs -- see PDElement.Pas + case 4: case 20: + with0->MilesThisLine = with0->Len * ConvertLineUnits(with0->LengthUnits, UNITS_MILES); + break; /*Change the number of phases ... only valid if SymComponentsModel=TRUE*/ + case 5: + if(with0->Fnphases != Parser[ActorID]->MakeInteger_()) + { + if((!with0->GeometrySpecified) && with0->SymComponentsModel) // ignore change of nphases if geometry used + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + with0->Set_Nconds(with0->Fnphases); // Force Reallocation of terminal info + with0->Yorder = with0->Fnterms * with0->Fnconds; + /*Set_YprimInvalid[ActorID] := True;*/ // now set below + with0->RecalcElementData(ActorID); // Reallocate Z, etc. + } + else + { + DoSimpleMsg(String("Illegal change of number of phases for Line.") + with0->get_Name(), 18101); + } + } + break; + case 6: case 7: case 8: case 9: case 10: case 11: case 26: case 27: + { + with0->FLineCodeSpecified = false; + with0->KillGeometrySpecified(); + with0->KillSpacingSpecified(); + with0->ResetLengthUnits(); + with0->SymComponentsChanged = true; + with0->SymComponentsModel = true; + } + break; + case 12: case 13: case 14: + { + with0->FLineCodeSpecified = false; + with0->SymComponentsModel = false; + with0->ResetLengthUnits(); + with0->KillGeometrySpecified(); + with0->KillSpacingSpecified(); + } + break; + case 15: + if(with0->IsSwitch) + { + with0->SymComponentsChanged = true; + with0->Set_YprimInvalid(ActorID,true); + with0->GeometrySpecified = false; + with0->SpacingSpecified = false; + with0->R1 = 1.0; + with0->X1 = 1.0; + with0->R0 = 1.0; + with0->X0 = 1.0; + with0->C1 = 1.1 * 1.0e-9; + with0->C0 = 1.0 * 1.0e-9; + with0->Len = 0.001; + with0->ResetLengthUnits(); + } + break; + case 17: case 18: + with0->KXg = with0->Xg / log(658.5L * sqrt(with0->rho / with0->BaseFrequency)); + break; + case 19: + { + with0->GeometrySpecified = true; + with0->SymComponentsModel = false; + with0->SymComponentsChanged = false; + } + break; + case 21: case 22: case 24: case 25: + { + if(ASSIGNED(with0->FLineSpacingObj) && (!with0->FLineWireData.empty())) + { + with0->SpacingSpecified = true; + with0->SymComponentsModel = false; + with0->SymComponentsChanged = false; + with0->KillGeometrySpecified(); + with0->FRatingsSpecified = false; + } + with0->Set_YprimInvalid(ActorID,true); + } + break; + case 28: case 29: case 31: case 32: with0->FRatingsSpecified = true; break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: + case 13: case 14: + with0->Set_YprimInvalid(ActorID,true); + break; + case 18: + if(with0->GeometrySpecified && ASSIGNED(with0->FLineGeometryObj)) + with0->FLineGeometryObj->Set_RhoEarth(with0->rho); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + + // If SymComponentsChanged THEN RecalcElementData; + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLine::MakeLike(const String LineName) +{ + int result = 0; + TLineObj* OtherLine = nullptr; + int i = 0; + result = 0; + /*See if we can find this line name in the present collection*/ + OtherLine = ((TLineObj*) Find(LineName)); + if(OtherLine != nullptr) + /*# with ActiveLineObj do */ + { + auto with0 = ActiveLineObj; + int stop = 0; + if(with0->Fnphases != OtherLine->Fnphases) + { + with0->Set_NPhases(OtherLine->Fnphases); + with0->Set_Nconds(with0->Fnphases); // force reallocation of terminals and conductors + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + if(with0->Z != nullptr) + delete with0->Z; + if(with0->Zinv != nullptr) + delete with0->Zinv; + if(with0->YC != nullptr) + delete with0->YC; + + // For a line, nphases = ncond, for now + with0->Z = new TcMatrix(with0->Fnphases); + with0->Zinv = new TcMatrix(with0->Fnphases); + with0->YC = new TcMatrix(with0->Fnphases); + } + with0->Z->CopyFrom(OtherLine->Z); + // Zinv.CopyFrom(OtherLine.Zinv); + with0->YC->CopyFrom(OtherLine->YC); + with0->R1 = OtherLine->R1; + with0->X1 = OtherLine->X1; + with0->R0 = OtherLine->R0; + with0->X0 = OtherLine->X0; + with0->C1 = OtherLine->C1; + with0->C0 = OtherLine->C0; + with0->Len = OtherLine->Len; + with0->SymComponentsModel = OtherLine->SymComponentsModel; + with0->FCapSpecified = OtherLine->FCapSpecified; + ClassMakeLike(OtherLine); // Take care of inherited class properties + for(int stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + with0->FPropertyValue[i - 1] = OtherLine->FPropertyValue[i - 1]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Line MakeLike: \"") + LineName + "\" Not Found.", 182); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TLine::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TLine.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TLine Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineObj::TLineObj(TDSSClass* ParClass, const String LineName) + : inherited(ParClass), + FZFrequency(-1.0), + FLineCodeUnits(0), + FUnitsConvert(0.0), + FLineGeometryObj(nullptr), + FLineSpacingObj(nullptr), + FWireDataSize(0), + FPhaseChoice(Overhead), + FrhoSpecified(false), + FLineCodeSpecified(false), + FEarthModel(0), + FCapSpecified(false), + FLineType(0), + FUserLengthUnits(0), + Zinv(nullptr), + Z(nullptr), + YC(nullptr), + R1(0.0), + X1(0.0), + R0(0.0), + X0(0.0), + C1(0.0), + C0(0.0), + Len(0.0), + Rg(0.0), + Xg(0.0), + KXg(0.0), + rho(0.0), + GeneralPlotQuantity(0.0), + GeometrySpecified(false), + SpacingSpecified(false), + SymComponentsChanged(false), + SymComponentsModel(false), + IsSwitch(false) +{ + Set_Name(LowerCase(LineName)); + DSSObjType = ParClass->DSSClassType; // DSSObjType + LINESECTION; // in both PDElement list and Linesection lists + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(2); // Force allocation of terminals and conductors + IsSwitch = false; + R1 = 0.0580; //ohms per 1000 ft + X1 = 0.1206; + R0 = 0.1784; + X0 = 0.4047; + C1 = 3.4E-9; // nf per 1000ft + C0 = 1.6E-9; + Len = 1.0; // 1 kFt + Z = nullptr; + Zinv = nullptr; + YC = nullptr; + CondCode = ""; + Rg = 0.01805; //ohms per 1000 ft + Xg = 0.155081; + rho = 100.0; + KXg = Xg / log(658.5L * sqrt(rho / BaseFrequency)); + FrhoSpecified = false; + FCapSpecified = false; + FLineWireData.clear(); + /*Basefrequency := 60.0;*/ // set in base class + NormAmps = 400.0; + EmergAmps = 600.0; + PctPerm = 20.0; + FaultRate = 0.1; // per mile per year + HrsToRepair = 3.0; + SymComponentsChanged = false; + SymComponentsModel = true; + GeometrySpecified = false; + GeometryCode = ""; + LengthUnits = UNITS_NONE; // Assume everything matches + FUserLengthUnits = UNITS_NONE; + FUnitsConvert = 1.0; + FLineCodeUnits = UNITS_NONE; + FLineCodeSpecified = false; + FEarthModel = DefaultEarthModel; + FLineType = 1; // Default to OH Line + FRatingsSpecified = false; + SpacingSpecified = false; + FLineSpacingObj = nullptr; + FWireDataSize = 0; + FPhaseChoice = unknown; + SpacingCode = ""; + FLineGeometryObj = nullptr; + InitPropertyValues(0); + Yorder = Fnterms * Fnconds; + RecalcElementData(ActiveActor); + NumAmpRatings = 1; + AmpRatings.resize( NumAmpRatings ); + AmpRatings[0] = NormAmps; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TLineObj::~TLineObj() +{ + if(ASSIGNED(Z)) + delete Z; + if(ASSIGNED(Zinv)) + delete Zinv; + if(ASSIGNED(YC)) + delete YC; + FLineWireData.clear(); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineObj::ReallocZandYcMatrices() +{ + if(Z != nullptr) + delete Z; + if(Zinv != nullptr) + delete Zinv; + if(YC != nullptr) + delete YC; + + // For a line, nphases = ncond, for now + Z = new TcMatrix(Fnphases); + Zinv = new TcMatrix(Fnphases); + YC = new TcMatrix(Fnphases); +} +// do long line correction for len and frequwnen + +void TLineObj::DoLongLine(double Frequency, double R, double X, double C, double& R_h, double& X_h, double& C_h, double& G_h) +// Do long line correction for len and desired frequency +// Updated the procedure to correct for any frequency. Moved usage to CalcYPrim. +{ + complex Zs, Zm, Ys, Ym, Zc; + complex GammaL, ExpP, ExpM, SinhGL, CoshGL; + + G_h = EPSILON; // Adding a tiny conductance to avoid skipping correction on lines with C1=0 + Zs = cmplx(R * Len, X * Len * Frequency / BaseFrequency); // Use X1 for the desired frequency + + Ys = cmplx(G_h, TwoPi * Frequency * C * Len); + // Apply the long-line correction to obtain Zm and Ym + // Rearrange things to express as in Arrillaga's book. no difference to original DoLongLine. + GammaL = csqrt(cmul(Zs, Ys)); + Zc = csqrt(cdiv(Zs, Ys)); + ExpP = cmulreal(cmplx(cos(GammaL.im), sin(GammaL.im)), exp(GammaL.re)); + ExpM = cinv(ExpP); + + SinhGL = cmulreal(csub(ExpP, ExpM), 0.5); + CoshGL = cmulreal(cadd(ExpP, ExpM), 0.5); + Zm = cmul(Zc, SinhGL); + Ym = cmulreal(cmul(cinv(Zc), cdiv(csub(CoshGL, cmplx(1.0, 0.0)), SinhGL)), 2.0); + + // Update values for tested frequency and adjusted for long-line + // do not replace original X1, R1, C1. We use these locally where the procedure is called. + R_h = Zm.re / Len; + X_h = Zm.im / Len; // X1_h output is already accounting for new frequency + C_h = Ym.im / Len / TwoPi / Frequency; + G_h = Ym.re; +} + +/* + This routine is only called when the symmetrical component data have changed + It computes the values for Z and Yc in ohms per unit length + + Can also compute long line correction for 1-phase pos sequence line models +*/ + +void TLineObj::RecalcElementData(int ActorID) +{ + complex Zs = CZero, + ZM = CZero, + Ys = CZero, + YM = CZero, + Ztemp = CZero, + GammaL = CZero, + ExpP = CZero, + ExpM = CZero, + Exp2P = CZero, + Exp2M = CZero, + SinhGL = CZero, + Tanh2GL = CZero; + int i = 0, + j = 0; + double Yc1 = 0.0, + Yc0 = 0.0; + + int stop = 0; + ReallocZandYcMatrices(); + + /*Only time this is called is if symmetrical components are specified*/ + Ztemp = cmulreal(cmplx(R1, X1), 2.0); + /*Handle special case for 1-phase line and/or pos seq model */ + if((Fnphases == 1) || ActiveCircuit[ActorID]->PositiveSequence) + // Long line correction has been moved to CalcYPrim as it must be performed frequency-wise (not only for base freq). + { + // Zero sequence the same as positive sequence + R0 = R1; + X0 = X1; + C0 = C1; + } + Zs = cmulreal(cadd(Ztemp, cmplx(R0, X0)), ONE_THIRD); + ZM = cmulreal(csub(cmplx(R0, X0), cmplx(R1, X1)), ONE_THIRD); + Yc1 = TwoPi * BaseFrequency * C1; + Yc0 = TwoPi * BaseFrequency * C0; + Ys = cmulreal(cadd(cmulreal(cmplx(0.0, Yc1), 2.0), cmplx(0.0, Yc0)), ONE_THIRD); + YM = cmulreal(csub(cmplx(0.0, Yc0), cmplx(0.0, Yc1)), ONE_THIRD); + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + Z->SetElement(i, i, Zs); + YC->SetElement(i, i, Ys); + for(int stop1 = i - 1, j = 1; j <= stop1; j++) + { + Z->SetElemsym(i, j, ZM); + YC->SetElemsym(i, j, YM); + } + } + SymComponentsChanged = false; + + // values in ohms per unit length +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TLineObj::CalcFltRate() +{ + + // inherited; + + // Assume Faultrate specified in same units as length + BranchFltRate = FaultRate * PctPerm * 0.01 * Len; +} + +void TLineObj::CalcYPrim(int ActorID) +{ + // Added a few definitions for long-line correction frequency-wise + complex Zs, Zm, Ys, Ym, Ztemp; + double Yc1, Yc0, R1_h, X1_h, C1_h, G1_h, R0_h, X0_h, C0_h, G0_h; + + complex Value = CZero; + pComplexArray ZinvValues = nullptr; + pComplexArray Zvalues = nullptr; + pComplexArray YValues = nullptr; + double FreqMultiplier = 1.0; + double XgMod = 0.0; + double LengthMultiplier = 1.0; + int i = 0; + int j = 0; + int k = 0; + int Norder = 0; + + if(SymComponentsChanged) + /*Try to catch inadvertent user error when they forget to specify C1 and C0 */ + /*Check to see if user has spec'd C1 and C0. If not, adjust default values for new length units*/ + { + if(!FCapSpecified) + { + C1 = C1 / ConvertLineUnits(UNITS_KFT, LengthUnits); // were defined in kft + C0 = C0 / ConvertLineUnits(UNITS_KFT, LengthUnits); + FCapSpecified = true; // so we don't do it again + } + RecalcElementData(ActorID); + } + ClearYPrim(); + + + // Build Series YPrim + /*# with YPrim_Series do */ + { + auto& with0 = YPrim_Series; + + /*Build Zmatrix*/ + if(GeometrySpecified) + { + FMakeZFromGeometry(ActiveCircuit[ActorID]->Solution->get_FFrequency()); // Includes length in proper units + if(SolutionAbort) + return; + } + else + { + if(SpacingSpecified) + { + FMakeZFromSpacing(ActiveCircuit[ActorID]->Solution->get_FFrequency()); // Includes length in proper units + if(SolutionAbort) + return; + } + else + // Z is from line code or specified in line data + // In this section Z is assumed in ohms per unit length + { + // If positive sequence, long-line correction can be taken into account here + // It needs to be recalculated for every frequency + if (SymComponentsModel && ActiveCircuit[ActorID]->LongLineCorrection) // Should only enter here if sequence components model + { + // These values are specific for the harmonic being tested (adjust for frequency) + R1_h = R1; + X1_h = X1 * FYprimFreq / BaseFrequency; // Adjust for frequency here + C1_h = C1; + G1_h = 0.0; // DoLongLine uses a tiny conductance to avoid skipping case where C1=0 + // Do the same for zero sequence + R0_h = R0; + X0_h = X0 * FYprimFreq / BaseFrequency; // Adjust for frequency here + C0_h = C0; + G0_h = 0.0; // DoLongLine uses a tiny conductance to avoid skipping case where C0=0 + + // long-line equivalent PI + // To avoid errors in higher freqs, we shouldn't skip cases with C1=0. Critical to match IEEE 14bus harmonics benchmark. + // Do long-line correction for tested frequency for +seq mode + // Use R1_h, X1_h, C1_h, G1_h to correct Y prim + DoLongLine(FYprimFreq, R1, X1, C1, R1_h, X1_h, C1_h, G1_h); + + if ((Fnphases > 1) && !ActiveCircuit[ActorID]->PositiveSequence) + { + // apply long line correction to 0seq mode as well + DoLongLine(FYprimFreq, R0, X0, C0, R0_h, X0_h, C0_h, G0_h); + } + else + { + // zero sequence the same as positive sequence + R0_h = R1_h; + X0_h = X1_h; + C0_h = C1_h; + G0_h = G1_h; + } + + Ztemp = cmulreal(cmplx(R1_h, X1_h), 2.0); + Zs = cmulreal(cadd(Ztemp, cmplx(R0_h, X0_h)), ONE_THIRD); + Zm = cmulreal(csub(cmplx(R0_h, X0_h), cmplx(R1_h, X1_h)), ONE_THIRD); + + Yc1 = TwoPi * FYprimFreq * C1_h; + Yc0 = TwoPi * FYprimFreq * C0_h; + + Ys = cmulreal(cadd(cmulreal(cmplx(G1_h, Yc1), 2.0), cmplx(G0_h, Yc0)), ONE_THIRD); + Ym = cmulreal(csub(cmplx(G0_h, Yc0), cmplx(G1_h, Yc1)), ONE_THIRD); + + for (i = 1; i <= Fnphases; i++) + { + Z->SetElement(i, i, Zs); + YC->SetElement(i, i, Ys); + for (j = 1; j <= i - 1; j++) + { + Z->SetElemsym(i, j, Zm); + YC->SetElemsym(i, j, Ym); + } + } + + // Put in Series RL + Zvalues = Z->GetValuesArrayPtr(Norder); + ZinvValues = Zinv->GetValuesArrayPtr(Norder); + // Correct the impedances for length and frequency + // Rg increases with frequency + // Xg modified by ln of sqrt(1/f) + if (Xg != 0.0) + XgMod = 0.5 * KXg * log(FreqMultiplier); + else + XgMod = 0.0; + + for (i = 1; i < Norder * Norder; i++) + { + // Apply freq multiplier only to XgMod as we have already accounted for freq adjustment above + ZinvValues[i - 1] = cmplx((Zvalues[i - 1].re + Rg * (FreqMultiplier - 1.0)) * LengthMultiplier, (Zvalues[i - 1].im - XgMod * FreqMultiplier) * LengthMultiplier); + } + } + else + { + // Original piece of code is kept here + int stop = 0; + LengthMultiplier = Len / FUnitsConvert; // convert to per unit length + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /* Put in Series RL */ + Zvalues = Z->GetValuesArrayPtr(Norder); + ZinvValues = Zinv->GetValuesArrayPtr(Norder); + // Correct the impedances for length and frequency + // Rg increases with frequency + // Xg modified by ln of sqrt(1/f) + if(Xg != 0.0) + XgMod = 0.5 * KXg * log(FreqMultiplier); + else + XgMod = 0.0; + for(int stop = Norder * Norder, i = 1; i <= stop; i++) + { + (ZinvValues)[i - 1] = cmplx(((Zvalues)[i - 1].re + Rg * (FreqMultiplier - 1.0)) * LengthMultiplier, ((Zvalues)[i - 1].im - XgMod) * LengthMultiplier * FreqMultiplier); + } + } + Zinv->Invert(); /*Invert Z in place to get values to put in Yprim*/ + } + + /*At this point have Z and Zinv in proper values including length*/ + /*If GIC simulation, convert Zinv back to sym components, R Only */ + } + if(ActiveCircuit[ActorID]->Solution->get_FFrequency() < 0.51) // 0.5 Hz is cutoff + ConvertZinvToPosSeqR(); + if(Zinv->InvertError > 0) + /*If error, put in tiny series conductance*/ +// TEMc - shut this up for the CDPSM connectivity profile test, or whenever else it gets annoying + { + int stop = 0; + DoErrorMsg("TLineObj.CalcYPrim", String("Matrix Inversion Error for Line \"") + get_Name() + "\"", "Invalid impedance specified. Replaced with tiny conductance.", 183); + Zinv->Clear(); + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, cmplx(EPSILON, 0.0)); + } + } + else + { + int stop = 0; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + /* Now, Put in Yprim_Series matrix */ + int stop1 = 0; + for(int stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zinv->GetElement(i, j); + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + Value = cnegate(Value); + with0->SetElemsym(i, j + Fnphases, Value); + } + } + } + } /*With Yprim_series*/ + YPrim->CopyFrom(YPrim_Series); // Initialize YPrim for series impedances + + // 10/3/2006 moved this to after the copy to Yprim so it doesn't affect normal line model capacitance + // 3-30-04 ----- Rev 2-4-09 to include both sides of line + // Increase diagonal elements of both sides of line so that we will avoid isolated bus problem + // add equivalent of 10 kvar capacitive at 345 kV + /*# with YPrim_Series do */ + { + auto with1 = YPrim_Series; + int stop = 0; + for(int stop = Yorder, i = 1; i <= stop; i++) + { + with1->AddElement(i, i, CAP_EPSILON); + } + } + + // Now Build the Shunt admittances and add into YPrim + if(ActiveCircuit[ActorID]->Solution->get_FFrequency() > 0.51) + /*# with YPrim_Shunt do */ + { + auto with2 = YPrim_Shunt; // Skip Capacitance for GIC + + + /*Put half the Shunt Capacitive Admittance at each end*/ + YValues = YC->GetValuesArrayPtr(Norder); + if(GeometrySpecified || SpacingSpecified) + + /*Values are already compensated for length and frequency*/ + { + int stop = 0; + k = 0; + for(int stop = Fnphases, j = 1; j <= stop; j++) + { + int stop1 = 0; + for(int stop1 = Fnphases, i = 1; i <= stop1; i++) + { + ++k; // Assume matrix in col order (1,1 2,1 3,1 ...) + Value = cdivreal((YValues)[k - 1], 2.0); // half at each end ... + with2->AddElement(i, j, Value); + with2->AddElement(i + Fnphases, j + Fnphases, Value); + } + } + } + else + + /*Regular line model - values computed per unit length at base frequency*/ + { + int stop = 0; + k = 0; + for(int stop = Fnphases, j = 1; j <= stop; j++) + { + int stop1 = 0; + for(int stop1 = Fnphases, i = 1; i <= stop1; i++) + { + ++k; // Assume matrix in col order (1,1 2,1 3,1 ...) + if (SymComponentsModel && ActiveCircuit[ActorID]->LongLineCorrection) // Should only enter here if sequence components model + { + // If we enter here, frequency adjustment has already been applied above during Z and Yc recalculation (and also affected by long-line correction) + Value = cmplx(YValues[k - 1].re / 2.0, YValues[k - 1].im * LengthMultiplier / 2.0); + } + else + { + Value = cmplx(0.0, YValues[k - 1].im * LengthMultiplier * FreqMultiplier / 2.0); + } + + with2->AddElement(i, j, Value); + with2->AddElement(i + Fnphases, j + Fnphases, Value); + } + } + } + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + } /*With YPRIM*/ + YPrim->AddFrom(YPrim_Shunt); + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TLineObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + String Rslt; + double LengthMult = 0.0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + { Write(f, "~ "); Write(f, (with0->PropertyName)[1 - 1]); Write(f, L'='); WriteLn(f, Get_FirstBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[2 - 1]); Write(f, L'='); WriteLn(f, Get_NextBus()); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[3 - 1]); Write(f, L'='); WriteLn(f, CondCode); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[4 - 1]); Write(f, L'='); WriteLn(f, Len, 0, 3); } + { Write(f, "~ "); Write(f, (with0->PropertyName)[5 - 1]); Write(f, L'='); WriteLn(f, Fnphases, 0); } + if(SymComponentsModel) + Rslt = Format("%-.7g", R1 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[6 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + if(SymComponentsModel) + Rslt = Format("%-.7g", X1 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[7 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + if(SymComponentsModel) + Rslt = Format("%-.7g", R0 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[8 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + if(SymComponentsModel) + Rslt = Format("%-.7g", X0 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[9 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + if(SymComponentsModel) + Rslt = Format("%-.7g", C1 * 1.0E9 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[10 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + if(SymComponentsModel) + Rslt = Format("%-.7g", C0 * 1.0E9 / FUnitsConvert); + else + Rslt = "----"; + { Write(f, "~ "); Write(f, (with0->PropertyName)[11 - 1]); Write(f, L'='); WriteLn(f, Rslt); } + + // If GeometrySpecified Or SpacingSpecified then length is embedded in Z and Yc 4-9-2020 + if(GeometrySpecified || SpacingSpecified) + LengthMult = Len; + else + LengthMult = 1.0; + { Write(f, "~ "); Write(f, (with0->PropertyName)[12 - 1]); Write(f, L'='); Write(f, L'\"'); } + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { Write(f, (double(Z->GetElement(i, j).re) / LengthMult / FUnitsConvert), 0, 9); Write(f, L' '); } + } + Write(f, L'|'); + } + WriteLn(f, L'\"'); + { Write(f, "~ "); Write(f, (with0->PropertyName)[13 - 1]); Write(f, L'='); Write(f, L'\"'); } + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { Write(f, (double(Z->GetElement(i, j).im) / LengthMult / FUnitsConvert), 0, 9); Write(f, L' '); } + } + Write(f, L'|'); + } + WriteLn(f, L'\"'); + { Write(f, "~ "); Write(f, (with0->PropertyName)[14 - 1]); Write(f, L'='); Write(f, L'\"'); } + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = Fnphases, j = 1; j <= stop1; j++) + { + { Write(f, (double(YC->GetElement(i, j).im) / TwoPi / BaseFrequency / LengthMult / FUnitsConvert * 1.0E9), 0, 3); Write(f, L' '); } + } + Write(f, L'|'); + } + WriteLn(f, L'\"'); + { Write(f, "~ "); Write(f, (with0->PropertyName)[15 - 1]); Write(f, L'='); } + if(IsSwitch) + WriteLn(f, "true"); + else + WriteLn(f, "false"); + + /*Dump the rest by default*/ + for(int stop = with0->NumProperties, i = 16; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } +} + + +/************ Placeholder for Line module No Load Loss procedure **********/ + +void TLineObj::GetLosses(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID) +{ + + + /*For Now, we'll just do the default behavior until we implement shunt losses*/ + inherited::GetLosses(TotalLosses, LoadLosses, NoLoadLosses, ActorID); +} + +String TLineObj::GetPropertyValue(int Index) +{ + String result; + int k = 0; + int i = 0; + int j = 0; + double Factor = 0.0; + String TempStr; + switch(Index) + { + case 12: case 13: case 14: + result = "["; + break; + default: + result = ""; + break; + } + /*Report Impedance values in ohms per unit length of present length units*/ + switch(Index) + { + case 1: + result = GetBus(1); + break; + case 2: + result = GetBus(2); + break; + case 3: + if (FLineCodeSpecified) result = CondCode; else result = ""; + break; + case 4: + result = Format("%-.7g", Len); + break; + case 5: + result = Format("%d", Fnphases); + break; + case 6: + if(SymComponentsModel) + result = Format("%-.7g", R1 / FUnitsConvert); + else + result = "----"; + break; + case 7: + if(SymComponentsModel) + result = Format("%-.7g", X1 / FUnitsConvert); + else + result = "----"; + break; + case 8: + if(SymComponentsModel) + result = Format("%-.7g", R0 / FUnitsConvert); + else + result = "----"; + break; + case 9: + if(SymComponentsModel) + result = Format("%-.7g", X0 / FUnitsConvert); + else + result = "----"; + break; + case 10: + if(SymComponentsModel) + result = Format("%-.7g", C1 * 1.0E9 / FUnitsConvert); + else + result = "----"; + break; + case 11: + if(SymComponentsModel) + result = Format("%-.7g", C0 * 1.0E9 / FUnitsConvert); + else + result = "----"; + break; + case 12: + for(int stop = Fnconds, i = 1; i <= stop; i++) + { // R matrix + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { // report in per unit Length in length units + if(GeometrySpecified || SpacingSpecified) + result = result + Format("%-.7g", double(Z->GetElement(i, j).re) / Len) + " "; + else + result = result + Format("%-.7g", double(Z->GetElement(i, j).re) / FUnitsConvert) + " "; + } + if(i < Fnconds) + result = result + "|"; + } + break; + case 13: + for(int stop = Fnconds, i = 1; i <= stop; i++) + { // X matrix + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + if(GeometrySpecified || SpacingSpecified) + result = result + Format("%-.7g", double(Z->GetElement(i, j).im) / Len) + " "; + else + result = result + Format("%-.7g", double(Z->GetElement(i, j).im) / FUnitsConvert) + " "; + } + if(i < Fnconds) + result = result + "|"; + } + break; // CMatrix nf + case 14: + { + int stop = 0; + Factor = TwoPi * BaseFrequency * 1.0e-9; + for(int stop = Fnconds, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + if(GeometrySpecified || SpacingSpecified) + result = result + Format("%-.7g", double(YC->GetElement(i, j).im) / Factor / Len) + " "; + else + result = result + + Format("%-.7g", double(YC->GetElement(i, j).im) / Factor / FUnitsConvert) + + " "; + } + if(i < Fnconds) + result = result + "|"; + } + } + break; + case 15: + if(IsSwitch) + result = "True"; + else + result = "False"; + break; + case 16: + result = Format("%-g", Rg); + break; + case 17: + result = Format("%-g", Xg); + break; + case 18: + result = Format("%-g", rho); + break; + case 19: + if (GeometrySpecified) result = GeometryCode; else result = ""; + break; + case 20: + result = LineUnitsStr(LengthUnits); + break; + case 23: + result = GetEarthModel(FEarthModel); + break; + case 26: + if(SymComponentsModel) + result = Format("%.7g", TwoPi * BaseFrequency * C1 * 1.0e6); + else + result = "----"; + break; + case 27: + if(SymComponentsModel) + result = Format("%.7g", TwoPi * BaseFrequency * C0 * 1.0e6); + else + result = "----"; + break; + case 28: + result = IntToStr(NumAmpRatings); + break; + case 29: + { + int stop = 0; + TempStr = "["; + for(int stop = NumAmpRatings, k = 1; k <= stop; k++) + { + TempStr = TempStr + FloatToStrF(AmpRatings[k - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + result = TempStr; + } + break; + case 30: + result = LineTypeList.Get(FLineType); + break; + + // Intercept FaultRate, PctPerm, and HourstoRepair + case 33: + result = Format("%-g", FaultRate); + break; + case 34: + result = Format("%-g", PctPerm); + break; + case 35: + result = Format("%-g", HrsToRepair); + break; + case 36: + result = Format("%-g", BaseFrequency); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 12: case 13: case 14: + result = result + "]"; + break; + default: + ; + break; + } + return result; +} + +/* Only consider 3-phase branches with Pos seq >> Neg seq + Otherwise, we don't know whether it is a 3-phase line or just a line with 3 phases +*/ + +void TLineObj::GetSeqLosses(complex& PosSeqLosses, complex& NegSeqLosses, complex& ZeroSeqLosses, int ActorID) +{ + int i = 0; + int j = 0; + int k = 0; + int l = 0; + complex Vph[3] = { CZero, CZero, CZero }; + complex V012[3] = { CZero, CZero, CZero }; + complex I012[3] = { CZero, CZero, CZero }; + PosSeqLosses = CZero; + NegSeqLosses = CZero; + ZeroSeqLosses = CZero; + + /*Method: sum seq powers going into each terminal + */ + if(Fnphases == 3) /*3-phase lines only*/ + { + int stop = 0; + ComputeIterminal(ActorID); + for(int stop = 2, i = 1; i <= stop; i++) + { + int stop1 = 0; + k = (i - 1) * Fnphases + 1; + for(int stop1 = 2, j = 0; j <= stop1; j++) + { + if(!ADiakoptics || (ActorID == 1)) + Vph[j] = ActiveCircuit[ActorID]->Solution->NodeV[(NodeRef)[k + j - 1]]; + else + Vph[j] = ActiveCircuit[ActorID]->Solution->VoltInActor1((NodeRef)[k + j - 1]); + } + Phase2SymComp(&Vph[0], &V012[0]); + Phase2SymComp((pComplexArray) &(Iterminal)[k - 1], &I012[0]); + caccum(PosSeqLosses, cmul(V012[1], conjg(I012[1]))); + caccum(NegSeqLosses, cmul(V012[2], conjg(I012[2]))); // accumulate both line modes + caccum(ZeroSeqLosses, cmul(V012[0], conjg(I012[0]))); + } + cmulrealaccum(PosSeqLosses, 3.0); + cmulrealaccum(NegSeqLosses, 3.0); + cmulrealaccum(ZeroSeqLosses, 3.0); + } +} + +void TLineObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,""); + Set_PropertyValue(4,"1.0"); // '5.28'; Changed 2/17/00 + Set_PropertyValue(5,"3"); + Set_PropertyValue(6,".058"); + Set_PropertyValue(7,".1206"); + Set_PropertyValue(8,".1784"); + Set_PropertyValue(9,".4047"); + Set_PropertyValue(10,"3.4"); + Set_PropertyValue(11,"1.6"); + Set_PropertyValue(12,""); + Set_PropertyValue(13,""); + Set_PropertyValue(14,""); + Set_PropertyValue(15,"false"); + Set_PropertyValue(16,"0.01805"); + Set_PropertyValue(17,"0.155081"); + Set_PropertyValue(18,"100"); + Set_PropertyValue(19,""); + Set_PropertyValue(20,"NONE"); + Set_PropertyValue(21,""); + Set_PropertyValue(22,""); + Set_PropertyValue(23,GetEarthModel(SIMPLECARSON)); + Set_PropertyValue(24,""); + Set_PropertyValue(25,""); + Set_PropertyValue(26,"1.2818"); // B1 microS + Set_PropertyValue(27,"0.60319"); // B0 microS + Set_PropertyValue(28,"1"); // 1 Season + Set_PropertyValue(29,"[400]"); // 1 Season + Set_PropertyValue(30,"OH"); // Overhead line default + inherited::InitPropertyValues(NumPropsThisClass); + + // Override Inherited properties just in case + Set_PropertyValue(NumPropsThisClass + 1,"400"); //Normamps + Set_PropertyValue(NumPropsThisClass + 2,"600"); //emergamps + Set_PropertyValue(NumPropsThisClass + 3,"0.1"); //Fault rate + Set_PropertyValue(NumPropsThisClass + 4,"20"); // Pct Perm + Set_PropertyValue(NumPropsThisClass + 5,"3"); // Hrs to repair + ClearPropSeqArray(); +} + +void TLineObj::MakePosSequence(int ActorID) +{ + String s; + double C1_new = 0.0; + double CS = 0.0; + double CM = 0.0; + double LengthMult = 0.0; + complex Z1 = {}; + complex Zs = {}; + complex ZM = {}; + int i = 0; + int j = 0; +// set to single phase and make sure R1, X1, C1 set. +// If already single phase, let alone + if(Fnphases > 1) + // Kill certain propertyvalue elements to get a cleaner looking save + { + int stop = 0; + (PrpSequence)[3 - 1] = 0; + for(int stop = 14, i = 6; i <= stop; i++) + { + (PrpSequence)[i - 1] = 0; + } + + // If GeometrySpecified Or SpacingSpecified then length is embedded in Z and Yc 4-9-2020 + if(GeometrySpecified || SpacingSpecified) + LengthMult = Len; + else + LengthMult = 1.0; + if(IsSwitch) + { + s = " R1=1 X1=1 C1=1.1 Phases=1 Len=0.001"; + } + else + { + if(SymComponentsModel) // keep the same Z1 and C1 + { + Z1.re = R1; + Z1.im = X1; + C1_new = C1 * 1.0E9; // convert to nF + } + else + // matrix was input directly, or built from physical data + // average the diagonal and off-dialgonal elements + { + int stop = 0; + Zs = CZero; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + caccum(Zs, Z->GetElement(i, i)); + } + Zs = cdivreal(Zs, (Fnphases * LengthMult)); + ZM = CZero; + for(int stop = Fnphases - 1, i = 1; i <= stop; i++) + { // Corrected 6-21-04 + int stop1 = 0; + for(int stop1 = Fnphases, j = i + 1; j <= stop1; j++) + { + caccum(ZM, Z->GetElement(i, j)); + } + } + ZM = cdivreal(ZM, (LengthMult * Fnphases * (Fnphases - 1.0) / 2.0)); + Z1 = csub(Zs, ZM); + + // Do same for Capacitances + CS = 0.0; + for(int stop = Fnphases, i = 1; i <= stop; i++) + { + CS = CS + YC->GetElement(i, i).im; + } + CM = 0.0; + for(int stop = Fnphases - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = Fnphases, j = i + 1; j <= stop1; j++) + { // corrected 4-9-2020 + CM = CM + YC->GetElement(i, j).im; + } + } + C1_new = (CS - CM) / TwoPi / BaseFrequency / (LengthMult * Fnphases * (Fnphases - 1.0) / 2.0) * 1.0E9; // nanofarads + + // compensate for length units + Z1 = cdivreal(Z1, FUnitsConvert); + C1_new = C1_new / FUnitsConvert; + } + s = Format(" R1=%-.5g %-.5g C1=%-.5g Phases=1", Z1.re, Z1.im, C1_new); + } + // Conductor Current Ratings + s = s + + Format(" Normamps=%-.5g %-.5g", NormAmps, EmergAmps); + // Repeat the Length Units to compensate for unexpected reset + s = s + " Units=" + LineUnitsStr(LengthUnits); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + } + inherited::MakePosSequence(ActorID); +} + +// Cleaned up and corrected 3-17-15 + +// Merge this line with another line and disble the other line. + +bool TLineObj::MergeWith(TLineObj* OtherLine, bool SERIES) +{ + bool result = false; + pComplexArray Values1 = nullptr; + pComplexArray Values2 = nullptr; + int Order1 = 0, + Order2 = 0, + i = 0, + j = 0, + Common1 = 0, + Common2 = 0, + TestBusNum = 0, + LenUnitsSaved = 0; + double TotalLen = 0.0, + wnano = 0.0, + LenSelf = 0.0, + LenOther = 0.0; + String s = "", + NewName = ""; + complex NewZ = CZero; + + + if(OtherLine != nullptr) + { + if(Fnphases != OtherLine->Fnphases) + return result; // Can't merge + LenUnitsSaved = LengthUnits; + Set_YprimInvalid(ActiveActor,true); + + // Redefine property values to make it appear that line was defined this way originally using matrices + if(SERIES) + TotalLen = Len + OtherLine->Len * ConvertLineUnits(OtherLine->LengthUnits, LengthUnits); + else + TotalLen = 1.0; + if(SERIES) + /* redefine the bus connections*/ + + // Find the bus in common between the two lines + { + Common1 = 0; + Common2 = 0; + i = 1; + while((Common1 == 0) && (i <= 2)) + { + int stop = 0; + TestBusNum = (ActiveCircuit[ActiveActor]->MapNodeToBus)[NodeRef[(i - 1) * Fnconds] - 1].BusRef; + for(int stop = 2, j = 1; j <= stop; j++) + { + if((ActiveCircuit[ActiveActor]->MapNodeToBus)[OtherLine->NodeRef[(j - 1) * OtherLine->Get_NConds()] - 1].BusRef == TestBusNum) + { + Common1 = i; + Common2 = j; + break; + } + } + ++i; + } + if(Common1 == 0) + return result; // There's been an error; didn't find anything in common + + /*Redefine the bus connections, eliminating the common bus*/ + switch(Common1) + { + case 1: + switch(Common2) + { + case 1: + s = String("Bus1=\"") + OtherLine->GetBus(2) + "\""; + break; + case 2: + s = String("Bus1=\"") + OtherLine->GetBus(1) + "\""; + break; + default: + ; + break; + } + break; + case 2: + switch(Common2) + { + case 1: + s = String("Bus2=\"") + OtherLine->GetBus(2) + "\""; + break; + case 2: + s = String("Bus2=\"") + OtherLine->GetBus(1) + "\""; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + Parser[ActiveActor]->SetCmdString(s); + Edit(ActiveActor); + } /*If Series*/ + + /*Rename the line*/ + if(SERIES) //StripExtension(GetBus(1)) + '~' + StripExtension(GetBus(2)) + NewName = OtherLine->get_Name() + "~" + get_Name(); + else + NewName = StripExtension(GetBus(1)) + "||" + StripExtension(GetBus(2)); + + /*Update ControlElement Connections to This Line*/ + UpdateControlElements(String("line.") + NewName, String("line.") + get_Name()); + UpdateControlElements(String("line.") + NewName, String("line.") + OtherLine->get_Name()); + Set_Name(NewName); + if(SERIES) + IsSwitch = false; // not allowed on series merge. + + /*Now Do the impedances*/ + LenSelf = Len / FUnitsConvert; // in units of the R X Data + LenOther = OtherLine->Len / OtherLine->FUnitsConvert; + + /* If both lines are Symmmetrical Components, just merge the R1..C0 values*/ + /* This will catch many 3-phase lines since this is a common way to define lines*/ + if(SymComponentsModel && OtherLine->SymComponentsModel && (Get_NPhases() == 3)) /*------------------------- Sym Component Model ----------------------------------*/ + { + if(SERIES) + { + s = String(" R1=") + Format("%-g", (R1 * LenSelf + OtherLine->R1 * LenOther) / TotalLen); // Ohms per unit length of this line length units + s = s + Format(" %-g", (X1 * LenSelf + OtherLine->X1 * LenOther) / TotalLen); + s = s + Format(" %-g", (R0 * LenSelf + OtherLine->R0 * LenOther) / TotalLen); + s = s + Format(" %-g", (X0 * LenSelf + OtherLine->X0 * LenOther) / TotalLen); + s = s + Format(" %-g", (C1 * LenSelf + OtherLine->C1 * LenOther) / TotalLen * 1.0E9); + s = s + Format(" %-g", (C0 * LenSelf + OtherLine->C0 * LenOther) / TotalLen * 1.0E9); + } + else + /*parallel*/ + { + if(IsSwitch) /*Leave as is if switch; just dummy z anyway*/ + s = ""; + else + { + if(OtherLine->IsSwitch) /*This will take care of setting Z's*/ + s = " switch=yes"; + else + +/********** Will This work with Length multiplier? did it ever work? **************************/ + { + NewZ = ParallelZ(cmplx(R1 * Len, X1 * Len), cmplx(OtherLine->R1 * OtherLine->Len, OtherLine->X1 * OtherLine->Len)); + s = String(" R1=") + Format("%-g %-g ", NewZ.re, NewZ.im); + NewZ = ParallelZ(cmplx(R0 * Len, X0 * Len), cmplx(OtherLine->R0 * OtherLine->Len, OtherLine->X0 * OtherLine->Len)); + s = String(" R0=") + Format("%-g %-g ", NewZ.re, NewZ.im); + s = s + Format(" %-g", (C1 * Len + OtherLine->C1 * OtherLine->Len) / TotalLen * 1.0E9); + s = s + Format(" %-g", (C0 * Len + OtherLine->C0 * OtherLine->Len) / TotalLen * 1.0E9); + } + } + } + Parser[ActiveActor]->SetCmdString(s); // This reset the length units + Edit(ActiveActor); + + // update length units + Parser[ActiveActor]->SetCmdString(Format(" Length=%-g Units=", TotalLen) + LineUnitsStr(LenUnitsSaved)); + Edit(ActiveActor); + + // Update symmetrical Components computation + // (Only time this function is called is for sym comp update -- computes Z and Yc) + RecalcElementData(ActiveActor); + } + else + { + if(!SERIES) /*------------- Matrix Model for anything other than Symmetrical Components -------------------------*/ /*We'll assume lines are equal for now*/ + TotalLen = Len / 2.0; + else + /*Matrices were defined*/ + + // Merge Z matrices + { + int stop = 0; + Values1 = Z->GetValuesArrayPtr(Order1); + Values2 = OtherLine->Z->GetValuesArrayPtr(Order2); + if(Order1 != Order2) + return result; // OOps. Lines not same size for some reason + + // If Geometry specified, length is already included; so reset to 1.0 + if(GeometrySpecified || SpacingSpecified) + LenSelf = 1.0; + if(OtherLine->GeometrySpecified || OtherLine->SpacingSpecified) + LenOther = 1.0; + + // Z <= (Z1 + Z2 )/TotalLen to get equiv ohms per unit length + for(int stop = Order1 * Order1, i = 1; i <= stop; i++) + { + (Values1)[i - 1] = cdivreal(cadd(cmulreal((Values1)[i - 1], LenSelf), cmulreal((Values2)[i - 1], LenOther)), TotalLen); + } + + // Merge Yc matrices + Values1 = YC->GetValuesArrayPtr(Order1); + Values2 = OtherLine->YC->GetValuesArrayPtr(Order2); + if(Order1 != Order2) + return result; // OOps. Lines not same size for some reason + for(int stop = Order1 * Order1, i = 1; i <= stop; i++) + { + (Values1)[i - 1] = cdivreal(cadd(cmulreal((Values1)[i - 1], LenSelf), cmulreal((Values2)[i - 1], LenOther)), TotalLen); + } + + /*R Matrix*/ + s = "Rmatrix=["; + for(int stop = Order1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + s = s + Format(" %-g", Z->GetElement(i, j).re); + } + s = s + " | "; + } + s = s + "] Xmatrix=["; + /*X Matrix*/ + for(int stop = Order1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + s = s + Format(" %-g", Z->GetElement(i, j).im); + } + s = s + " | "; + } + s = s + "]"; + Parser[ActiveActor]->SetCmdString(s); + Edit(ActiveActor); + + /*C Matrix*/ + wnano = TwoPi * BaseFrequency / 1.0E9; + s = "Cmatrix=["; + for(int stop = Order1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(int stop1 = i, j = 1; j <= stop1; j++) + { + s = s + Format(" %-g", YC->GetElement(i, j).im / wnano ); + } // convert from mhos to nanofs + s = s + " | "; + } + s = s + "] "; + Parser[ActiveActor]->SetCmdString(s); + Edit(ActiveActor); + + // update length units + Parser[ActiveActor]->SetCmdString(Format(" Length=%-g Units=", TotalLen) + LineUnitsStr(LenUnitsSaved)); + Edit(ActiveActor); + } /*Matrix definition*/ + } + OtherLine->Set_Enabled(false); // Disable the Other Line + result = true; + } + else + DoSimpleMsg("Error in Line Merge: Attempt to merge with invalid (nil) line object found.", 184); + return result; +} + +void TLineObj::UpdateControlElements(const String NewName, const String OldName) +{ + TControlElem* pControlElem = nullptr; + pControlElem = ((TControlElem*) ActiveCircuit[ActiveActor]->DSSControls.Get_First()); + while(pControlElem != nullptr) + { + if(CompareText(OldName, pControlElem->ElementName) == 0) + { + Parser[ActiveActor]->SetCmdString(String(" Element=") + NewName); // Change name of the property + ( (TDSSObject*) pControlElem )->Edit(ActiveActor); + } + pControlElem = ((TControlElem*) ActiveCircuit[ActiveActor]->DSSControls.Get_Next()); + } +} + +void TLineObj::FetchLineSpacing(const String Code) +{ + if( LineSpacingClass[ActiveActor]->SetActive(Code)) + { + FLineSpacingObj = (TLineSpacingObj*)LineSpacingClass[ActiveActor]->GetActiveObj(); + FLineCodeSpecified = false; + KillGeometrySpecified(); + SpacingCode = LowerCase(Code); + + // need to establish Yorder before FMakeZFromSpacing + Set_NPhases(FLineSpacingObj->get_Fnphases()); + Set_Nconds(Fnphases); // Force Reallocation of terminal info + Yorder = Fnconds * Fnterms; + Set_YprimInvalid(ActiveActor,true); // Force Rebuild of Y matrix + } + else + DoSimpleMsg(String("Line Spacing object ") + Code + " not found.(LINE." + get_Name() + ")", 181011); +} + +void TLineObj::FetchWireList(const String Code) +{ + bool RatingsInc = false; + int NewNumRat = 0; + int j = 0; + int i = 0; + int iStart = 0; + TRatingsArray NewRatings; + int stop = 0; + if(!ASSIGNED(FLineSpacingObj)) + DoSimpleMsg(String("You must assign the LineSpacing before the Wires Property (LINE.") + get_Name() + + ").", 18102); + if(FPhaseChoice == unknown) // it's an overhead line + { + FLineCodeSpecified = false; + KillGeometrySpecified(); + FWireDataSize = FLineSpacingObj->get_Fnconds(); + FLineWireData.resize(FWireDataSize); + iStart = 1; + FPhaseChoice = Overhead; + } + else + // adding bare neutrals to an underground line - TODO what about repeat invocation? + { + iStart = FLineSpacingObj->get_Fnphases() + 1; + } + AuxParser[ActiveActor]->SetCmdString(Code); + NewNumRat = 1; + RatingsInc = false; // So far we don't know if there are seasonal ratings + for(int stop = FLineSpacingObj->get_Fnconds(), i = iStart; i <= stop; i++) + { + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + WireDataClass[ActiveActor]->Set_Code(AuxParser[ActiveActor]->MakeString_()); + if(ASSIGNED(ActiveConductorDataObj)) + { + FLineWireData[i - 1] = ActiveConductorDataObj; + if(FLineWireData[i - 1]->NumAmpRatings > NewNumRat) + { + NewRatings = Copy( FLineWireData[i - 1]->AmpRatings ); // Have to be same type to be assignable + NewNumRat = sizeof(NewRatings) + 1; + RatingsInc = true; // Yes, there are seasonal ratings + } + NormAmps = FLineWireData[i - 1]->NormAmps; + EmergAmps = FLineWireData[i - 1]->EmergAmps; + } + else + DoSimpleMsg(String("Wire \"") + AuxParser[ActiveActor]->MakeString_() + + "\" was not defined first (LINE." + + get_Name() + + ").", 18103); + } + if(RatingsInc) + { + AmpRatings = Copy(NewRatings); /***** NewRatings disappears when it goes out of scope*/ + NumAmpRatings = NewNumRat; + } + UpdatePDProperties(); +} + +void TLineObj::FetchCNCableList(const String Code) +{ + int i = 0; + int stop = 0; + FLineCodeSpecified = false; + KillGeometrySpecified(); + if(!ASSIGNED(FLineSpacingObj)) + DoSimpleMsg(String("Must assign the LineSpacing before CN cables.(LINE.") + get_Name() + + ")", 18104); + FPhaseChoice = ConcentricNeutral; + FLineWireData.resize(FLineSpacingObj->get_Fnconds()); + AuxParser[ActiveActor]->SetCmdString(Code); + for(int stop = FLineSpacingObj->get_Fnphases(), i = 1; i <= stop; i++) + { // fill extra neutrals later + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + CNDataClass[ActiveActor]->Set_Code(AuxParser[ActiveActor]->MakeString_()); + if(ASSIGNED(ActiveConductorDataObj)) + FLineWireData[i - 1] = ActiveConductorDataObj; + else + DoSimpleMsg(String("CN cable ") + AuxParser[ActiveActor]->MakeString_() + + " was not defined first.(LINE." + + get_Name() + + ")", 18105); + } +} + +void TLineObj::FetchTSCableList(const String Code) +{ + int i = 0; + int stop = 0; + FLineCodeSpecified = false; + KillGeometrySpecified(); + if(!ASSIGNED(FLineSpacingObj)) + DoSimpleMsg(String("Must assign the LineSpacing before TS cables.(LINE.") + get_Name() + + ")", 18106); + FPhaseChoice = TapeShield; + FLineWireData.resize(FLineSpacingObj->get_Fnconds()); + AuxParser[ActiveActor]->SetCmdString(Code); + for(int stop = FLineSpacingObj->get_Fnphases(), i = 1; i <= stop; i++) + { // fill extra neutrals later + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + TSDataClass[ActiveActor]->Set_Code(AuxParser[ActiveActor]->MakeString_()); + if(ASSIGNED(ActiveConductorDataObj)) + FLineWireData[i - 1] = ActiveConductorDataObj; + else + DoSimpleMsg(String("TS cable ") + AuxParser[ActiveActor]->MakeString_() + + " was not defined first. (LINE." + + get_Name() + + ")", 18107); + } +} + +void TLineObj::FetchGeometryCode(const String Code) +{ + int i = 0; + if(LineGeometryClass == nullptr) + LineGeometryClass = (TLineGeometry*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("LineGeometry")); + if(LineGeometryClass->SetActive(Code)) + { + FLineCodeSpecified = false; // Cancel this flag + SpacingSpecified = false; + FLineGeometryObj = ((TLineGeometryObj*) LineGeometryClass->GetActiveObj()); + FZFrequency = -1.0; // Init to signify not computed + GeometryCode = LowerCase(Code); + if(FrhoSpecified) + FLineGeometryObj->Set_RhoEarth(rho); + if (!FRatingsSpecified) + { + NormAmps = FLineGeometryObj->NormAmps; + EmergAmps = FLineGeometryObj->EmergAmps; + UpdatePDProperties(); + } + Set_NPhases(FLineGeometryObj->get_Nconds()); + Set_Nconds(Fnphases); // Force Reallocation of terminal info + Yorder = Fnconds * Fnterms; + Set_YprimInvalid(ActiveActor,true); // Force Rebuild of Y matrix + NumAmpRatings = FLineGeometryObj->NumAmpRatings; + AmpRatings = Copy( FLineGeometryObj->AmpRatings ); + FLineType = FLineGeometryObj->FLineType; + } + else + DoSimpleMsg(String("Line Geometry Object:") + Code + + " not found. (LINE." + + get_Name() + + ")", 18108); +} // make new Z, Zinv, Yc, etc + +void TLineObj::FMakeZFromGeometry(double f) +{ + if(f == FZFrequency) + return; // Already Done for this frequency, no need to do anything + if(ASSIGNED(FLineGeometryObj)) + /*This will make a New Z; Throw away present allocations*/ + { + if(ASSIGNED(Z)) + { + delete Z; + Z = nullptr; + } + if(ASSIGNED(Zinv)) + { + delete Zinv; + Zinv = nullptr; + } + if(ASSIGNED(YC)) + { + delete YC; + YC = nullptr; + } + ActiveEarthModel[ActiveActor] = FEarthModel; + Z = FLineGeometryObj->Get_Zmatrix(f,Len,LengthUnits); + YC = FLineGeometryObj->Get_YCmatrix(f,Len,LengthUnits); + /*Init Zinv*/ + if(ASSIGNED(Z)) + { + Zinv = new TcMatrix(Z->get_Norder()); // Either no. phases or no. conductors + Zinv->CopyFrom(Z); + Zinv->Invert(); /*Invert Z in place to get values to put in Yprim*/ + } + + // Z and YC are actual total impedance for the line; + FZFrequency = f; + } +} // make new Z, Zinv, Yc, etc + +void TLineObj::FMakeZFromSpacing(double f) +{ + TLineGeometryObj* pGeo = nullptr; + if(f == FZFrequency) + return; // Already Done for this frequency, no need to do anything + if(ASSIGNED(Z)) + { + delete Z; + Z = nullptr; + } + if(ASSIGNED(Zinv)) + { + delete Zinv; + Zinv = nullptr; + } + if(ASSIGNED(YC)) + { + delete YC; + YC = nullptr; + } + + // make a temporary LineGeometry to calculate line constants + if(LineGeometryClass == nullptr) + LineGeometryClass = (TLineGeometry*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("LineGeometry")); + pGeo = new TLineGeometryObj(LineGeometryClass, get_Name()); + pGeo->LoadSpacingAndWires(FLineSpacingObj, FLineWireData); // this sets OH, CN, or TS + if(FrhoSpecified) + pGeo->Set_RhoEarth(rho); + NormAmps = pGeo->NormAmps; + EmergAmps = pGeo->EmergAmps; + UpdatePDProperties(); + + ActiveEarthModel[ActiveActor] = FEarthModel; + + Z = pGeo->Get_Zmatrix(f,Len,LengthUnits); + YC = pGeo->Get_YCmatrix(f,Len,LengthUnits); + if(ASSIGNED(Z)) + { + Zinv = new TcMatrix(Z->get_Norder()); // Either no. phases or no. conductors + Zinv->CopyFrom(Z); + Zinv->Invert(); /*Invert Z in place to get values to put in Yprim*/ + } + delete pGeo; + FZFrequency = f; +} + +void TLineObj::KillGeometrySpecified() +{ + +/*Indicate No Line Geometry specification if this is called*/ + if(GeometrySpecified) + { + FLineGeometryObj = nullptr; + FZFrequency = -1.0; + GeometrySpecified = false; + } +} + +void TLineObj::KillSpacingSpecified() +{ + if(SpacingSpecified) + { + FLineSpacingObj = nullptr; + FLineWireData.clear(); + FPhaseChoice = unknown; + FZFrequency = -1.0; + SpacingSpecified = false; + } +} + +void TLineObj::ClearYPrim() +{ + + // Line Object needs both Series and Shunt YPrims built + if(Get_YprimInvalid(ActiveActor,0)) // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + if(YPrim != nullptr) + delete YPrim; + YPrim_Series = new TcMatrix(Yorder); + YPrim_Shunt = new TcMatrix(Yorder); + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); // zero out YPrim Series + YPrim_Shunt->Clear(); // zero out YPrim Shunt + YPrim->Clear(); // zero out YPrim + } +} + +// For GIC Analysis, use only real part of Z + +void TLineObj::ConvertZinvToPosSeqR() +{ + complex Z1 = {}; + complex Zs = {}; + complex ZM = {}; + int i = 0; + int j = 0; + +// re-invert Zinv + int stop = 0; + Zinv->Invert(); +// Now Zinv is back to Z with length included + + // average the diagonal and off-dialgonal elements + Zs = Zinv->AvgDiagonal(); + ZM = Zinv->AvgOffDiagonal(); + Z1 = csub(Zs, ZM); + Z1.im = 0.0; // ignore X part + Zinv->Clear(); + for(int stop = Zinv->get_Norder(), i = 1; i <= stop; i++) + { + Zinv->SetElement(i, i, Z1); + } // Set Diagonals + Zinv->Invert(); // back to zinv for inserting in Yprim +} +/*If specify the impedances always assume the length units match*/ + +void TLineObj::ResetLengthUnits() +{ + FUnitsConvert = 1.0; + LengthUnits = UNITS_NONE; // but do not erase FUserLengthUnits, in case of CIM export +} + +int TLineObj::NumConductorData() +{ + int result = 0; + result = 0; + if (!FLineWireData.empty()) + result = FLineSpacingObj->get_Fnconds(); + if(ASSIGNED(FLineGeometryObj)) + result = FLineGeometryObj->get_Fnconds(); + return result; +} + +TConductorDataObj* TLineObj::FetchConductorData(int i) +{ + TConductorDataObj* result = nullptr; + result = nullptr; + if (!FLineWireData.empty()) + { + if(i <= FLineSpacingObj->get_Fnconds()) + result = FLineWireData[i - 1]; + } + else + { + if(ASSIGNED(FLineGeometryObj)) + { + if(i <= FLineGeometryObj->get_Fnconds()) + result = FLineGeometryObj->Get_ConductorData(i); + } + } + return result; +} + + +void Line_initialization() +{ + CAP_EPSILON = cmplx(0.0, 4.2E-8); // 5 kvar of capacitive reactance at 345 kV to avoid open line problem +} + + class Line_unit + { + public: + Line_unit() + { + //AssertSystemInitialization(); + Line_initialization(); + } + }; + Line_unit _Line_unit; + +} // namespace Line + diff --git a/OpenDSSC/PDElements/Line.h b/OpenDSSC/PDElements/Line.h new file mode 100644 index 0000000..ed467da --- /dev/null +++ b/OpenDSSC/PDElements/Line.h @@ -0,0 +1,167 @@ +#ifndef LineH +#define LineH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDElement.h" +#include "Ucmatrix.h" +#include "LineCode.h" +#include "Arraydef.h" +#include "ConductorData.h" +#include "PDClass.h" +#include "Ucomplex.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "LineGeometry.h" +#include "LineSpacing.h" +#include "LineUnits.h" +#include "d2c_structures.h" + + +namespace Line +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 3-1-00 Reactivated line dump + 3-13-03 Fixed bug where terminal quantities were not getting reallocated in FetchCondCode + 2018 Added GIC stuff + 2022 Fixed bug on long-line correction to correct for frequencies other than base freq. +*/ + +class TLine : public PDClass::TPDClass +{ + friend class TLineObj; +public: + typedef PDClass::TPDClass inherited; +private: + void DoRmatrix(int ActorID); + void DoXmatrix(int ActorID); + void DoCmatrix(int ActorID); +protected: + void DefineProperties(); // Add Properties of this class to propName + virtual int MakeLike(const String LineName); +public: + TLine(); + virtual ~TLine(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TLineObj : public PDELement::TPDElement +{ + friend class TLine; +public: + typedef PDELement::TPDElement inherited; +public: + double FZFrequency; // keep track of last frequency computed for geometry + int FLineCodeUnits; + double FUnitsConvert; // conversion factor + LineGeometry::TLineGeometryObj* FLineGeometryObj; + LineSpacing::TLineSpacingObj* FLineSpacingObj; + ConductorData::pConductorDataArray FLineWireData; + int FWireDataSize; + ConductorData::ConductorChoice FPhaseChoice; + bool FrhoSpecified; + bool FLineCodeSpecified; + int FEarthModel; + bool FCapSpecified; // To make sure user specifies C in some form + int FLineType; // Pointer to code for type of line + int FUserLengthUnits; // keep track of the user's input length units + bool FRatingsSpecified; // To track if ratings should be overriden from geometry + spacing spec + void FMakeZFromGeometry(double f); // make new Z, Zinv, Yc, etc + void KillGeometrySpecified(); + void FMakeZFromSpacing(double f); // make new Z, Zinv, Yc, etc + void KillSpacingSpecified(); + void ClearYPrim(); + void ResetLengthUnits(); + void UpdatePDProperties(); // update inherited properties + int NumConductorData(); + ConductorData::TConductorDataObj* FetchConductorData(int i); + void ReallocZandYcMatrices(); + void DoLongLine(double Frequency); // Long Line Correction for 1=phase + void DoLongLine(double Frequency, double R, double X, double C, double& R_h, double& X_h, double& C_h, double& G_h); // Long Line Correction for 1=phase + void ConvertZinvToPosSeqR(); // for GIC analysis, primarily +protected: + Ucmatrix::TcMatrix* Zinv; +public: // Moved to make values available to the COM interface + Ucmatrix::TcMatrix* Z; // Base Frequency Series Z matrix per unit length + Ucmatrix::TcMatrix* YC; + double R1; + double X1; + double R0; + double X0; + double C1; + double C0; + double Len; + int LengthUnits; + double Rg; + double Xg; + double KXg; + double rho; + double GeneralPlotQuantity; // For general circuit plotting + String CondCode; + String GeometryCode; + String SpacingCode; + bool GeometrySpecified; + bool SpacingSpecified; + bool SymComponentsChanged; + bool SymComponentsModel; + bool IsSwitch; + +// NRatings : Integer; // See PDElement +// ratings : pDoubleArray; + virtual void GetLosses(Ucomplex::complex& TotalLosses, Ucomplex::complex& LoadLosses, Ucomplex::complex& NoLoadLosses, int ActorID); + virtual void GetSeqLosses(Ucomplex::complex& PosSeqLosses, Ucomplex::complex& NegSeqLosses, Ucomplex::complex& ZeroSeqLosses, int ActorID); + TLineObj(TDSSClass* ParClass, const String LineName); + virtual ~TLineObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + bool MergeWith(TLineObj* OtherLine, bool SERIES); + void UpdateControlElements(const String NewName, const String OldName); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + // Public for the COM Interface + void FetchLineCode(const String Code); + void FetchGeometryCode(const String Code); + void FetchLineSpacing(const String Code); + void FetchWireList(const String Code); + void FetchCNCableList(const String Code); + void FetchTSCableList(const String Code); + + // Reliability calcs + virtual void CalcFltRate(); // Calc failure rates for section and buses + + // CIM XML access + TLineObj(TDSSClass* ParClass); + TLineObj(String ClassName); + TLineObj(); +}; +extern TLineObj* ActiveLineObj; +extern LineGeometry::TLineGeometry* LineGeometryClass; // public to show line constant results + + +} // namespace Line + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Line; +#endif + +#endif // LineH + + + + diff --git a/OpenDSSC/PDElements/PDClass.cpp b/OpenDSSC/PDElements/PDClass.cpp new file mode 100644 index 0000000..e458ba5 --- /dev/null +++ b/OpenDSSC/PDElements/PDClass.cpp @@ -0,0 +1,124 @@ + +#pragma hdrstop + +#include "PDClass.h" + +#include "PDElement.h" +#include "DSSGlobals.h" +#include "Utilities.h" + + +using namespace std; +using namespace CktElementClass; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Utilities; + +namespace PDClass +{ + + + +TPDClass::TPDClass() + : NumPDClassProps(5) +{ + ; + DSSClassType = PD_ELEMENT; +} + + +TPDClass::~TPDClass() +{ + // inherited::Destroy(); +} + + +void TPDClass::CountProperties() +{ + NumProperties = NumProperties + NumPDClassProps; + inherited::CountProperties(); +} + +// Define the properties for the base power delivery element class + +void TPDClass::DefineProperties() +{ + PropertyName[ActiveProperty + 1] = "normamps"; + PropertyName[ActiveProperty + 2] = "emergamps"; + PropertyName[ActiveProperty + 3] = "faultrate"; + PropertyName[ActiveProperty + 4] = "pctperm"; + PropertyName[ActiveProperty + 5] = "repair"; + PropertyHelp[ActiveProperty + 1] = "Normal rated current."; + PropertyHelp[ActiveProperty + 2] = "Maximum or emerg current."; + PropertyHelp[ActiveProperty + 3] = "Failure rate per year."; + PropertyHelp[ActiveProperty + 4] = "Percent of failures that become permanent."; + PropertyHelp[ActiveProperty + 5] = "Hours to repair."; + ActiveProperty = ActiveProperty + NumPDClassProps; + inherited::DefineProperties(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TPDClass::ClassEdit(const void* ActivePDObj, int ParamPointer) +{ + int result = 0; + result = 0; + // continue parsing with contents of Parser + if(ParamPointer > 0) + /*# with TPDElement(ActivePDObj) do */ + { + auto with0 = ((TPDElement*) ActivePDObj); + switch(ParamPointer) + { + case 1: + with0->NormAmps = Parser[ActiveActor]->MakeDouble_(); + break; + case 2: + with0->EmergAmps = Parser[ActiveActor]->MakeDouble_(); + break; + case 3: + with0->FaultRate = Parser[ActiveActor]->MakeDouble_(); + break; + case 4: + with0->PctPerm = Parser[ActiveActor]->MakeDouble_(); + break; + case 5: + with0->HrsToRepair = Parser[ActiveActor]->MakeDouble_(); + break; + default: + inherited::ClassEdit(ActivePDObj, ParamPointer - NumPDClassProps); + break; + } + } + return result; +} + +void TPDClass::ClassMakeLike(const void* OtherObj) +{ + TPDElement* OtherPDObj = nullptr; + OtherPDObj = ((TPDElement*) OtherObj); + /*# with TPDElement(ActiveDSSObject[ActiveActor]) do */ + { + auto with0 = ((TPDElement*) ActiveDSSObject[ActiveActor]); + with0->NormAmps = OtherPDObj->NormAmps; + with0->EmergAmps = OtherPDObj->EmergAmps; + with0->FaultRate = OtherPDObj->FaultRate; + with0->PctPerm = OtherPDObj->PctPerm; + with0->HrsToRepair = OtherPDObj->HrsToRepair; + } + inherited::ClassMakeLike(OtherObj); +} + + + + +} // namespace PDClass + + + + diff --git a/OpenDSSC/PDElements/PDClass.h b/OpenDSSC/PDElements/PDClass.h new file mode 100644 index 0000000..1f8a444 --- /dev/null +++ b/OpenDSSC/PDElements/PDClass.h @@ -0,0 +1,50 @@ +#ifndef PDClassH +#define PDClassH + +#include "System.h" +#include "CktElementClass.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" + +namespace PDClass +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*$M+*/ + +class TPDClass : public CktElementClass::TCktElementClass +{ +public: + typedef CktElementClass::TCktElementClass inherited; +private: +protected: + int ClassEdit(const void* ActivePDObj, int ParamPointer); + void ClassMakeLike(const void* OtherObj); + void CountProperties(); // Add no. of intrinsic properties + void DefineProperties(); // Add Properties of this class to propName +public: + int NumPDClassProps; + TPDClass(); + virtual ~TPDClass(); +//__published: +}; + + +} // namespace PDClass + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PDClass; +#endif + +#endif // PDClassH + + + + diff --git a/OpenDSSC/PDElements/PDElement.cpp b/OpenDSSC/PDElements/PDElement.cpp new file mode 100644 index 0000000..848e735 --- /dev/null +++ b/OpenDSSC/PDElements/PDElement.cpp @@ -0,0 +1,350 @@ + +#pragma hdrstop + +#include "PDElement.h" +#include "DSSGlobals.h" + +using namespace std; +using namespace Arraydef; +using namespace Bus; +using namespace CktElement; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace MeterElement; +using namespace System; +using namespace Ucomplex; + +namespace PDELement +{ + +TPDElement::TPDElement(String ClassName) : inherited(ClassName) {} +TPDElement::TPDElement() {} + + + +/*---------Summing Utility proc-------*/ + +/*#inline*/ +void accumsum(double& A, double B) +{ + A = A + B; +} +/*------------------------------------*/ + +void TPDElement::AccumFltRate() +{ + TDSSBus* FromBus = nullptr; + TDSSBus* ToBus = nullptr; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + if(FromTerminal == 2) + ToTerminal = 1; + else + ToTerminal = 2; + + /*Get fault Rate for TO bus and add it to this section failure rate*/ + ToBus = with0->Buses[Terminals[ToTerminal - 1].BusRef - 1]; + AccumulatedBrFltRate = ToBus->BusFltRate + BranchFltRate; + FromBus = with0->Buses[Terminals[FromTerminal - 1].BusRef - 1]; + FromBus->BusTotalNumCustomers = FromBus->BusTotalNumCustomers + BranchTotalCustomers; + AccumulatedMilesDownStream = ToBus->BusTotalMiles + MilesThisLine; + accumsum(FromBus->BusTotalMiles, AccumulatedMilesDownStream); + + /*Compute accumulated to FROM Bus; if a fault interrupter, assume it isolates all downline faults*/ + if(!HasOCPDevice) + // accumlate it to FROM bus + { + accumsum(FromBus->BusFltRate, AccumulatedBrFltRate); + } + } +} /*Virtual function -- LINE is different, for one*/ + +void TPDElement::CalcFltRate() +{ + + /*Default base algorithm for radial fault rate calculation*/ + /*May be overridden by specific device class behavior*/ + BranchFltRate = FaultRate * PctPerm * 0.01; +} + +void TPDElement::CalcCustInterrupts() +{ + TDSSBus* FromBus = nullptr; + FromBus = ActiveCircuit[ActiveActor]->Buses[Terminals[FromTerminal - 1].BusRef - 1]; + /*# with FromBus do */ + { + auto& with0 = FromBus; + accumsum(with0->BusCustInterrupts, with0->Bus_Num_Interrupt * BranchTotalCustomers); + } +} +/*This is called on the forward sweep to set the number of interruptions at the To bus.*/ + +void TPDElement::CalcNum_Int(int& SectionCount, bool AssumeRestoration) +{ + TDSSBus* FromBus = nullptr; + TDSSBus* ToBus = nullptr; + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + if(FromTerminal == 2) + ToTerminal = 1; + else + ToTerminal = 2; + ToBus = with0->Buses[Terminals[ToTerminal - 1].BusRef - 1]; + FromBus = with0->Buses[Terminals[FromTerminal - 1].BusRef - 1]; + + // If no interrupting device then the downline bus will have the same num of interruptions + ToBus->Bus_Num_Interrupt = FromBus->Bus_Num_Interrupt; + + /* If Interrupting device (on FROM side)then downline bus will have + additional interruptions ---- including for fused lateral + If assuming restoration and the device is an automatic device, the To bus will be + interrupted only for faults on the main section, not including fused sections. + */ + if(HasOCPDevice) + { + if (AssumeRestoration && HasAutoOCPDevice) + { + /*To Bus will be interrupted only for faults on this section. + AccumulatedBrFltRate does not include Branches down from + Branches with OCP devics*/ + ToBus->Bus_Num_Interrupt = AccumulatedBrFltRate; + } + else + accumsum(ToBus->Bus_Num_Interrupt, AccumulatedBrFltRate); + + /*If there is an OCP device on this PDElement, this is the + beginning of a new section.*/ + SectionCount++; + ToBus->BusSectionID = SectionCount; // Assign it to the new section + } + else + { + ToBus->BusSectionID = FromBus->BusSectionID; // else it's in the same section + } + BranchSectionID = ToBus->BusSectionID; + } +} + +TPDElement::TPDElement(TDSSClass* ParClass) + : inherited(ParClass), + NormAmps(0.0), + EmergAmps(0.0), + FaultRate(0.0), + PctPerm(0.0), + BranchFltRate(0.0), + AccumulatedBrFltRate(0.0), + MilesThisLine(0.0), + AccumulatedMilesDownStream(0.0), + HrsToRepair(0.0), + FromTerminal(0), + ToTerminal(0), + IsShunt(false), + BranchNumCustomers(0), + BranchTotalCustomers(0), + BranchCustWeight(0.0), + BranchSectionID(0), + ParentPDElement(nullptr), + MeterObj(nullptr), + SensorObj(nullptr), + Overload_UE(0.0), + OverLoad_EEN(0.0), + NumAmpRatings(0) +{ + IsShunt = false; + FromTerminal = 1; + BranchNumCustomers = 0; + BranchTotalCustomers = 0; + AccumulatedBrFltRate = 0.0; + MilesThisLine = 0.0; + SensorObj = nullptr; + MeterObj = nullptr; + ParentPDElement = nullptr; + DSSObjType = PD_ELEMENT; + NumAmpRatings = 1; + AmpRatings.resize( 1 ); // Initialized here + AmpRatings[0] = 1000; +} + +TPDElement::~TPDElement() +{ + // inherited::Destroy(); +} + + +void TPDElement::CalcNumCustomers(int ActorID, TPDElement* pElem) +{ + + int k = 0, + kk = 0, + j = 0; + + kk = ActiveCircuit[ActorID]->Loads.get_myNumList(); // List of ActiveLoads in Circuit + pElem->BranchNumCustomers = 0; + pElem->BranchTotalCustomers = 0; + + string name = pElem->get_Name(); + int i = 0; + + std::vector BpElem = pElem->FBusNames; // BusNames + int* TotalCust = 0; + + for (i = 1; i <= kk; i++) + { + TPCElement* Loads = (TPCElement*)ActiveCircuit[ActiveActor]->Loads.Get(i); + std::vector LoadsV = Loads->FBusNames; + + for (j = 0; j < BpElem.size(); j++) + { + if (BpElem[j] == LoadsV[0]) //Count the NumCustomers in the Bus + { + if (name.find("line") != std::string::npos) + { + k++; + pElem->BranchNumCustomers = k; + } + pElem->BranchTotalCustomers++; + } + } + + + + } +} + + +void TPDElement::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int j = 0; + try + { + if(Get_Enabled()) + { + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + // In the contenxt of actor 1 voltages + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + } + YPrim->MVmult(Curr, &(Vterminal[0])); + } + else + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + Curr[i - 1] = CZero; + } + } + } + catch (std::exception &e) + { + DoErrorMsg((String("Trying to Get Currents for Element: ") + get_Name() + "."), (std::string) e.what(), "Has the circuit been solved?", 660); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - + +complex TPDElement::Get_ExcessKVANorm(int idxTerm, int ActorID) +{ + complex result = CZero; + double Factor = 0.0; + complex kVA = CZero; + + if((NormAmps == 0.0) || !Get_Enabled()) + { + OverLoad_EEN = 0.0; // bug fixed 1/10/00 + result = CZero; + return result; + } + kVA = cmulreal(Get_Power(idxTerm, ActorID), 0.001); // Also forces computation of Current into Itemp + Factor = (MaxTerminalOneIMag(ActorID) / NormAmps - 1.0); + if(Factor > 0.0) + { + OverLoad_EEN = Factor; + Factor = 1.0 - 1.0 / (Factor + 1.0); // To get factor + result = cmulreal(kVA, Factor); + } + else + { + OverLoad_EEN = 0.0; + result = CZero; + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - + +complex TPDElement::Get_ExcessKVAEmerg(int idxTerm, int ActorID) +{ + complex result = {}; + double Factor = 0.0; + complex kVA = {}; + if((EmergAmps == 0.0) || !Get_Enabled()) + { + Overload_UE = 0.0; // bug fixed 1/10/00 + result = CZero; + return result; + } + kVA = cmulreal(Get_Power(idxTerm, ActorID), 0.001); // Also forces computation of Current into Itemp + Factor = (MaxTerminalOneIMag(ActorID) / EmergAmps - 1.0); + if(Factor > 0.0) + { + Overload_UE = Factor; + Factor = 1.0 - 1.0 / (Factor + 1.0); // To get Excess + result = cmulreal(kVA, Factor); + } + else + { + Overload_UE = 0.0; + result = CZero; + } + return result; +} + +void TPDElement::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(ArrayOffset + 1,"400"); //Normamps + Set_PropertyValue(ArrayOffset + 2,"600"); //emergamps + Set_PropertyValue(ArrayOffset + 3,"0.1"); //Fault rate + Set_PropertyValue(ArrayOffset + 4,"20"); // Pct Perm + Set_PropertyValue(ArrayOffset + 5,"3"); // Hrs to repair + inherited::InitPropertyValues(ArrayOffset + 5); +} + +void TPDElement::ZeroReliabilityAccums() +{ + TDSSBus* FromBus = nullptr; + FromBus = ActiveCircuit[ActiveActor]->Buses[(Terminals)[FromTerminal - 1].BusRef - 1]; + /*# with FromBus do */ + { + auto with0 = FromBus; + with0->BusCustInterrupts = 0.0; + with0->BusFltRate = 0.0; + with0->BusTotalNumCustomers = 0; + with0->BusTotalMiles = 0.0; + with0->BusCustDurations = 0.0; + with0->Bus_Num_Interrupt = 0.0; + with0->BusSectionID = -1; // signify not set + } +} + + + + +} // namespace PDELement + + + + diff --git a/OpenDSSC/PDElements/PDElement.h b/OpenDSSC/PDElements/PDElement.h new file mode 100644 index 0000000..185e4ac --- /dev/null +++ b/OpenDSSC/PDElements/PDElement.h @@ -0,0 +1,96 @@ +#ifndef PDELementH +#define PDELementH + +#include "System.h" +#include "Sysutils.h" + +#include "CktElement.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "DSSClass.h" +#include "MeterElement.h" +#include "Arraydef.h" +#include "DSSClassDefs.h" +#include "PCElement.h" +#include "Bus.h" + +namespace PDELement +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change Log + 1/10/00 Fixed bug where OverLoad_EEN, _UE was not being set for elements + where the rating was not specified. + 4/11/01 Fixed error in computin excess kVAs (factor readjustment) +*/ + + class TPDElement : public CktElement::TDSSCktElement + { + public: + typedef CktElement::TDSSCktElement inherited; + //private: + Ucomplex::complex Get_ExcessKVANorm(int idxTerm, int ActorID); + Ucomplex::complex Get_ExcessKVAEmerg(int idxTerm, int ActorID); + public: // annual faults per year + // percent of faults that are permanent in this element + // net failure rate for this branch + // accumulated failure rate for this branch + // length in miles if line + // total miles downstream + double NormAmps; + double EmergAmps; + double FaultRate; + double PctPerm; + double BranchFltRate; + double AccumulatedBrFltRate; + double MilesThisLine; + double AccumulatedMilesDownStream; + double HrsToRepair; + int FromTerminal; + int ToTerminal; // Set by Meter zone for radial feeder + bool IsShunt; + int BranchNumCustomers; + int BranchTotalCustomers; + double BranchCustWeight; // Weighting factor for customers on this elemebt + int BranchSectionID; // ID of the section that this PD element belongs to + TPDElement* ParentPDElement; /*Upline energymeter*/ + MeterElement::TMeterElement* MeterObj; + MeterElement::TMeterElement* SensorObj; // Upline Sensor for this element for allocation and estimation + double Overload_UE; + double OverLoad_EEN; // Indicate amount of branch overload + int NumAmpRatings; + Arraydef::TRatingsArray AmpRatings; + TPDElement(TDSSClass* ParClass); + virtual ~TPDElement(); + virtual void InitPropertyValues(int ArrayOffset); + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present values of terminal + virtual void CalcFltRate(); // Calc failure rates for section and buses + void AccumFltRate(); + void CalcNum_Int(int& SectionCount, bool AssumeRestoration); // Calc Number of Interruptions in forward sweep + void CalcCustInterrupts(); + void ZeroReliabilityAccums(); // Zero out reliability accumulators + void CalcNumCustomers(int ActorID, TPDElement* pElems); + TPDElement(String ClassName); + TPDElement(); + }; + + +} // namespace PDELement + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PDELement; +#endif + +#endif // PDELementH + + + + diff --git a/OpenDSSC/PDElements/Reactor.cpp b/OpenDSSC/PDElements/Reactor.cpp new file mode 100644 index 0000000..8a24879 --- /dev/null +++ b/OpenDSSC/PDElements/Reactor.cpp @@ -0,0 +1,1416 @@ + +#pragma hdrstop + +#include "Reactor.h" + +#include "DSSGlobals.h" +#include "Utilities.h" + +using namespace std; +using namespace Arraydef; +using namespace CktElement; +using namespace CktElementClass; +using namespace Command; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace PDClass; +using namespace PDELement; +using namespace ParserDel; +using namespace System; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace XYCurve; +using namespace mathutil; +using namespace Utilities; + +namespace Reactor +{ + +TReactorObj::TReactorObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TReactorObj::TReactorObj(String ClassName) : inherited(ClassName) {} +TReactorObj::TReactorObj() {} + + +TReactorObj* ActiveReactorObj = nullptr; +const int NumPropsThisClass = 19; + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Reactor objects + +TReactor::TReactor() +{ + ; + Class_Name = "Reactor"; + DSSClassType = DSSClassType + REACTOR_ELEMENT; + ActiveElement = 0; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + + ReactorClass[ActiveActor] = this; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TReactor::~TReactor() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TReactor::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "bus1"; + PropertyName[2 - 1] = "bus2"; + PropertyName[3 - 1] = "phases"; + PropertyName[4 - 1] = "kvar"; + PropertyName[5 - 1] = "kv"; + PropertyName[6 - 1] = "conn"; + PropertyName[7 - 1] = "Rmatrix"; + PropertyName[8 - 1] = "Xmatrix"; + PropertyName[9 - 1] = "Parallel"; + PropertyName[10 - 1] = "R"; + PropertyName[11 - 1] = "X"; + PropertyName[12 - 1] = "Rp"; + PropertyName[13 - 1] = "Z1"; + PropertyName[14 - 1] = "Z2"; + PropertyName[15 - 1] = "Z0"; + PropertyName[16 - 1] = "Z"; + PropertyName[17 - 1] = "RCurve"; + PropertyName[18 - 1] = "LCurve"; + PropertyName[19 - 1] = "LmH"; + + // define Property help values + PropertyHelp[1 - 1] = String("Name of first bus. Examples:") + CRLF + + "bus1=busname" + + CRLF + + "bus1=busname.1.2.3" + + CRLF + + CRLF + + "Bus2 property will default to this bus, node 0, unless previously specified. " + + "Only Bus1 need be specified for a Yg shunt reactor."; + PropertyHelp[2 - 1] = String("Name of 2nd bus. Defaults to all phases connected " "to first bus, node 0, (Shunt Wye Connection) " "except when Bus2 is specifically defined.") + CRLF + + CRLF + + "Not necessary to specify for delta (LL) connection"; + PropertyHelp[3 - 1] = "Number of phases."; + PropertyHelp[4 - 1] = "Total kvar, all phases. Evenly divided among phases. Only determines X. Specify R separately"; + PropertyHelp[5 - 1] = "For 2, 3-phase, kV phase-phase. Otherwise specify actual coil rating."; + PropertyHelp[6 - 1] = "={wye | delta |LN |LL} Default is wye, which is equivalent to LN. If Delta, then only one terminal."; + PropertyHelp[7 - 1] = "Resistance matrix, lower triangle, ohms at base frequency. Order of the matrix is the number of phases. " + "Mutually exclusive to specifying parameters by kvar or X."; + PropertyHelp[8 - 1] = "Reactance matrix, lower triangle, ohms at base frequency. Order of the matrix is the number of phases. " + "Mutually exclusive to specifying parameters by kvar or X."; + PropertyHelp[9 - 1] = "{Yes | No} Default=No. Indicates whether Rmatrix and Xmatrix are to be considered in parallel. " + "Default is series. For other models, specify R and Rp."; + PropertyHelp[10 - 1] = "Resistance (in series with reactance), each phase, ohms. " + "This property applies to REACTOR specified by either kvar or X. See also help on Z."; + PropertyHelp[11 - 1] = "Reactance, each phase, ohms at base frequency. See also help on Z and LmH properties."; + PropertyHelp[12 - 1] = "Resistance in parallel with R and X (the entire branch). Assumed infinite if not specified."; + PropertyHelp[13 - 1] = String("Positive-sequence impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z1=[1, 2] ! represents 1 + j2 " + + CRLF + + CRLF + + "If defined, Z1, Z2, and Z0 are used to define the impedance matrix of the REACTOR. " + + "Z1 MUST BE DEFINED TO USE THIS OPTION FOR DEFINING THE MATRIX." + + CRLF + + CRLF + + "Side Effect: Sets Z2 and Z0 to same values unless they were previously defined."; + PropertyHelp[14 - 1] = String("Negative-sequence impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z2=[1, 2] ! represents 1 + j2 " + + CRLF + + CRLF + + "Used to define the impedance matrix of the REACTOR if Z1 is also specified. " + + CRLF + + CRLF + + "Note: Z2 defaults to Z1 if it is not specifically defined. If Z2 is not equal to Z1, the impedance matrix is asymmetrical."; + PropertyHelp[15 - 1] = String("Zer0-sequence impedance, ohms, as a 2-element array representing a complex number. Example: ") + CRLF + + CRLF + + "Z0=[3, 4] ! represents 3 + j4 " + + CRLF + + CRLF + + "Used to define the impedance matrix of the REACTOR if Z1 is also specified. " + + CRLF + + CRLF + + "Note: Z0 defaults to Z1 if it is not specifically defined. "; + PropertyHelp[16 - 1] = String("Alternative way of defining R and X properties. Enter a 2-element array representing R +jX in ohms. Example:") + CRLF + + CRLF + + "Z=[5 10] ! equivalent to R=5 X=10 "; + PropertyHelp[17 - 1] = "Name of XYCurve object, previously defined, describing per-unit variation of phase resistance, R, vs. frequency. Applies to resistance specified by R or Z property. " + "If actual values are not known, R often increases by approximately the square root of frequency."; + PropertyHelp[18 - 1] = "Name of XYCurve object, previously defined, describing per-unit variation of phase inductance, L=X/w, vs. frequency. Applies to reactance specified by X, LmH, Z, or kvar property." + "L generally decreases somewhat with frequency above the base frequency, approaching a limit at a few kHz."; + PropertyHelp[19 - 1] = "Inductance, mH. Alternate way to define the reactance, X, property."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list + + PropertyHelp[NumPropsThisClass] = PropertyHelp[NumPropsThisClass] + " Defaults to per - phase rated current when reactor is specified with rated power and voltage."; + PropertyHelp[NumPropsThisClass + 1] = PropertyHelp[NumPropsThisClass + 1] + " Defaults to 135 % of per - phase rated current when reactor is specified with rated power and voltage."; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TReactor::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TReactorObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TReactor::DoMatrix(pDoubleArray Matrix, int ActorID) +{ + int OrderFound = 0; + int j = 0; + pDoubleArray MatBuffer = nullptr; + /*# with ActiveReactorObj do */ + { + auto with0 = ActiveReactorObj; + MatBuffer = new double[ with0->Fnphases * with0->Fnphases]; + OrderFound = Parser[ActorID]->ParseAsSymMatrix( ( (TDSSCktElement*) with0 )->Fnphases, MatBuffer); + if(OrderFound > 0) // Parse was successful Else don't change Matrix + /*X*/ + { + int stop = 0; + Matrix = (pDoubleArray) realloc(Matrix, sizeof(double) * with0->Fnphases * with0->Fnphases); + for(stop = with0->Fnphases * with0->Fnphases, j = 1; j <= stop; j++) + { + (Matrix)[j - 1] = (MatBuffer)[j - 1]; + } + } + free(MatBuffer); + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TReactor::InterpretConnection(const String s) +{ + String TestS; + /*# with ActiveReactorObj do */ + { + auto with0 = ActiveReactorObj; + TestS = LowerCase(s); + switch(TestS[0]) + { + case L'y': + case L'w': + with0->Connection = 0; + break; /*Wye*/ + case L'd': + with0->Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(TestS[1]) + { + case L'n': + with0->Connection = 0; + break; + case L'l': + with0->Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + int myshift = 0; + switch(with0->Connection) + { + case 1: // Force reallocation of terminals + { + with0->Set_NTerms(1); + if (with0->Fnphases < 3) + myshift++; + with0->Set_Nconds(with0->Fnphases + myshift); + } + break; + case 0: + { + if (with0->Fnterms != 2) + with0->Set_NTerms(2); + with0->Set_Nconds(with0->Fnphases); + } + break; + default: + ; + break; + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TReactor::ReactorSetbus1(const String s) +{ + String S2; + int i = 0; + int dotpos = 0; + + // Special handling for Bus 1 + // Set Bus2 = Bus1.0.0.0 + /*# with ActiveReactorObj do */ + { + auto with0 = ActiveReactorObj; + with0->SetBus(1, s); + + // Default Bus2 to zero node of Bus1 if not already defined. (Wye Grounded connection) + if(!with0->Bus2Defined) + // Strip node designations from S + { + int stop = 0; + dotpos = Pos(".", s); + if(dotpos > 0) + S2 = s.substr(0, dotpos - 1); + else + S2 = s.substr(0, s.size()); // copy up to Dot + for(stop = with0->Fnphases, i = 1; i <= stop; i++) + { + S2 = S2 + ".0"; + } + with0->SetBus(2, S2); + with0->IsShunt = true; + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TReactor::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + result = 0; + // continue parsing with contents of Parser + ActiveReactorObj = (TReactorObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement((TDSSCktElement*) ActiveReactorObj); // use property to set this value + /*# with ActiveReactorObj do */ + { + auto with0 = ActiveReactorObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + ( (TDSSCktElement*) with0 )->get_Name() + + "\"", 230); + break; + case 1: + ReactorSetbus1(Param); + break; + case 2: + { + ( (TDSSCktElement*) with0 )->SetBus(2, Param); + } + break;/* Numphases := Parser.MakeInteger_()*/ + case 3: + ; + break; // see below + case 4: + with0->kvarrating = Parser[ActorID]->MakeDouble_(); + break; + case 5: + with0->kvrating = Parser[ActorID]->MakeDouble_(); + break; + case 6: + InterpretConnection(Param); + break; + case 7: + DoMatrix(with0->Rmatrix, ActorID); + break; + case 8: + DoMatrix(with0->XMatrix, ActorID); + break; + case 9: + with0->IsParallel = InterpretYesNo(Param); + break; + case 10: + with0->R = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->X = Parser[ActorID]->MakeDouble_(); + break; + case 12: + with0->Rp = Parser[ActorID]->MakeDouble_(); + break; + case 13: + with0->Z1 = InterpretComplex(Param); + break; + case 14: + with0->Z2 = InterpretComplex(Param); + break; + case 15: + with0->Z0 = InterpretComplex(Param); + break; + case 16: + with0->Z = InterpretComplex(Param); + break; + case 17: + with0->RCurve = Param; + break; + case 18: + with0->LCurve = Param; + break; + case 19: + with0->l = Parser[ActorID]->MakeDouble_() / 1000.0; + break; // convert from mH to H + + // Inherited Property Edits + default: + inherited::ClassEdit(ActiveReactorObj, ParamPointer - NumPropsThisClass); + break; + } + + // Some specials ... + switch(ParamPointer) + { + case 1: + { + with0->Set_PropertyValue(2,with0->GetBus(2)); // this gets modified + with0->PrpSequence[2 - 1] = 0; // Reset this for save function + } + break; + case 2: + if(CompareText(StripExtension( with0->GetBus(1)), StripExtension( with0->GetBus(2))) != 0) + { + with0->IsShunt = false; + with0->Bus2Defined = true; + } + break; + case 3: + if( with0->Fnphases != Parser[ActorID]->MakeInteger_()) + { + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + int lclshift = 0; + if (with0->Connection == 1) + lclshift++; + with0->Set_Nconds(with0->Fnphases + lclshift); // Force Reallocation of terminal info + with0->Yorder = with0->Fnterms * with0->Fnconds; + } + break; + case 4: + with0->SpecType = 1; + break; // X specified by kvar, kV + case 7: case 8: + with0->SpecType = 3; + break; + case 11: + with0->SpecType = 2; + break; // X specified directly rather than computed from kvar + case 12: + with0->RpSpecified = true; + break; + case 13: + { + with0->SpecType = 4; // have to set Z1 to get this mode + if(!with0->Z2Specified) + with0->Z2 = with0->Z1; + if(!with0->Z0Specified) + with0->Z0 = with0->Z1; + } + break; + case 14: + with0->Z2Specified = true; + break; + case 15: + with0->Z0Specified = true; + break; + case 16: + { + with0->R = with0->Z.re; + with0->X = with0->Z.im; + with0->SpecType = 2; + } + break; + case 17: + with0->RCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->RCurve)); + break; + case 18: + with0->LCurveObj = ((TXYcurveObj*) XYCurveClass[ActorID]->Find(with0->LCurve)); + break; + case 19: + { + with0->SpecType = 2; + with0->X = with0->l * TwoPi * with0->BaseFrequency; + } + break; + case (NumPropsThisClass + 1): + with0->FNormAmpsSpecified = true; // Normamps + break; + case (NumPropsThisClass + 2): + with0->FEmergAmpsSpecified = true; // Emergamps + break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: + case 13: case 14: case 15: case 16: + with0->Set_YprimInvalid(ActorID,true); + break; + case 17: + if(with0->RCurveObj == nullptr) + DoSimpleMsg(String("Resistance-frequency curve XYCurve.") + with0->RCurve + + " not Found.", 2301); + break; + case 18: + if(with0->LCurveObj == nullptr) + DoSimpleMsg(String("Inductance-frequency curve XYCurve.") + with0->LCurve + + " not Found.", 2301); + break; + case 19: + ( (TDSSCktElement*) with0 )->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TReactor::MakeLike(const String ReactorName) +{ + int result = 0; + TReactorObj* OtherReactor = nullptr; + int i = 0; + result = 0; + /*See if we can find this Reactor name in the present collection*/ + OtherReactor = ((TReactorObj*) Find(ReactorName)); + if(OtherReactor != nullptr) + /*# with ActiveReactorObj do */ + { + auto with0 = ActiveReactorObj; + int stop = 0; + if( ( (TDSSCktElement*) with0 )->Fnphases != ( (TDSSCktElement*) OtherReactor )->Fnphases) + { + ( (TDSSCktElement*) with0 )->Set_NPhases(( (TDSSCktElement*) OtherReactor )->Fnphases); + ( (TDSSCktElement*) with0 )->Set_Nconds(( (TDSSCktElement*) with0 )->Fnphases); // force reallocation of terminals and conductors + ( (TDSSCktElement*) with0 )->Yorder = ( (TDSSCktElement*) with0 )->Fnconds * ((TDSSCktElement*)with0)->Fnterms; + ( (TDSSCktElement* )with0 )->Set_YprimInvalid(ActiveActor,true); + } + with0->R = OtherReactor->R; + with0->X = OtherReactor->X; + with0->Rp = OtherReactor->Rp; + with0->RpSpecified = OtherReactor->RpSpecified; + with0->IsParallel = OtherReactor->IsParallel; + with0->kvarrating = OtherReactor->kvarrating; + with0->kvrating = OtherReactor->kvrating; + with0->Connection = OtherReactor->Connection; + with0->SpecType = OtherReactor->SpecType; + with0->Z = OtherReactor->Z; + with0->Z1 = OtherReactor->Z1; + with0->Z2 = OtherReactor->Z2; + with0->Z0 = OtherReactor->Z0; + with0->Z2Specified = OtherReactor->Z2Specified; + with0->Z0Specified = OtherReactor->Z0Specified; + with0->RCurve = OtherReactor->RCurve; + with0->RCurveObj = OtherReactor->RCurveObj; + with0->LCurve = OtherReactor->LCurve; + with0->LCurveObj = OtherReactor->LCurveObj; + if(OtherReactor->Rmatrix == nullptr) + with0->Rmatrix = NULL; + else + { + int stop = 0; + with0->Rmatrix = (pDoubleArray) realloc(with0->Rmatrix, sizeof(double) * with0->Fnphases * with0->Fnphases); + for(stop = with0->Fnphases * with0->Fnphases, i = 1; i <= stop; i++) + { + (with0->Rmatrix)[i - 1] = (OtherReactor->Rmatrix)[i - 1]; + } + } + if(OtherReactor->XMatrix == nullptr) + with0->XMatrix = NULL; + else + { + int stop = 0; + with0->XMatrix = (pDoubleArray) realloc(with0->XMatrix, sizeof(double) * with0->Fnphases * with0->Fnphases); + for(stop = ( (TDSSCktElement*) with0 )->Fnphases * ( (TDSSCktElement*) with0 )->Fnphases, i = 1; i <= stop; i++) + { + (with0->XMatrix)[i - 1] = (OtherReactor->XMatrix)[i - 1]; + } + } + ClassMakeLike(OtherReactor); // Take care of inherited class properties + for(stop = ( (TDSSCktElement*) with0 )->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + ( (TDSSCktElement*) with0 )->Set_PropertyValue(i,( (TDSSCktElement*) OtherReactor )->Get_PropertyValue(i)); + } + result = 1; + } + else + DoSimpleMsg(String("Error in Reactor MakeLike: \"") + ReactorName + + "\" Not Found.", 231); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TReactor::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TReactor.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TReactor Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TReactorObj::TReactorObj(TDSSClass* ParClass, const String ReactorName) + : inherited(ParClass), + R(0.0), + Rp(0.0), + Gp(0.0), + X(0.0), + l(0.0), + kvarrating(0.0), + kvrating(0.0), + Rmatrix(nullptr), + Gmatrix(nullptr), + XMatrix(nullptr), + Bmatrix(nullptr), + Connection(0), + SpecType(0), + IsParallel(false), + RpSpecified(false), + Bus2Defined(false), + Z2Specified(false), + Z0Specified(false), + RCurveObj(nullptr), + LCurveObj(nullptr) +{ + Set_Name(LowerCase(ReactorName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(2); // Force allocation of terminals and conductors + SetBus(2, (GetBus(1) + ".0.0.0")); // Default to grounded wye + IsShunt = true; + Rmatrix = nullptr; + XMatrix = nullptr; + Gmatrix = nullptr; + Bmatrix = nullptr; + kvarrating = 100.0; + kvrating = 12.47; + X = Sqr(kvrating) * 1000.0L / kvarrating; + IsParallel = false; + RpSpecified = false; + Bus2Defined = false; + Z2Specified = false; + Z0Specified = false; + Connection = 0; // 0 or 1 for wye (default) or delta, respectively + SpecType = 1; // 1=kvar, 2=Cuf, 3=Cmatrix + NormAmps = kvarrating * SQRT3 / kvrating; + EmergAmps = NormAmps * 1.35; + FNormAmpsSpecified = false; + FEmergAmpsSpecified = false; + FaultRate = 0.0005; + PctPerm = 100.0; + HrsToRepair = 3.0; + Yorder = Fnterms * Fnconds; + RCurve = ""; + RCurveObj = nullptr; + LCurve = ""; + LCurveObj = nullptr; + RecalcElementData(ActiveActor); + InitPropertyValues(0); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TReactorObj::~TReactorObj() +{ + free(Rmatrix); + free(XMatrix); + free(Gmatrix); + free(Bmatrix); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TReactorObj::RecalcElementData(int ActorID) +{ + double KvarPerPhase = 0.0; + double PhasekV = 0.0; + int i = 0; + int CheckError = 0; + switch(SpecType) + { + case 1: // kvar + { + KvarPerPhase = kvarrating / Fnphases; + switch(Connection) + { + case 1: // Line-to-Line + { + PhasekV = kvrating; + } + break; + default: + switch(Fnphases) + { + case 2: + case 3: + PhasekV = kvrating / SQRT3; + break; // Assume three phase system + default: + PhasekV = kvrating; + break; + } + break; + } + X = Sqr(PhasekV) * 1000.0L / KvarPerPhase; + l = X / TwoPi / BaseFrequency; + /*Leave R as specified*/ + if (!FNormAmpsSpecified) NormAmps = KvarPerPhase / PhasekV; + if (!FEmergAmpsSpecified) EmergAmps = KvarPerPhase / PhasekV * 1.35; + } + break; // R + j X + // Nothing much to do + case 2: + { + l = X / TwoPi / BaseFrequency; + } + break; // Matrices + case 3: + break; + default: + ; + break; + } + if(RpSpecified && (Rp != 0.0)) + Gp = 1.0 / Rp; + else + Gp = 0.0; // default to 0,0 if Rp=0; + if(IsParallel && (SpecType == 3)) + { + int stop = 0; + Gmatrix = (pDoubleArray) realloc(Gmatrix, sizeof(double) * Fnphases * Fnphases); + Bmatrix = (pDoubleArray) realloc(Bmatrix, sizeof(double) * Fnphases * Fnphases); + + /*Copy Rmatrix to Gmatrix and Invert*/ + for(stop = Fnphases * Fnphases, i = 1; i <= stop; i++) + { + (Gmatrix)[i - 1] = (Rmatrix)[i - 1]; + } +// should be Gmatrix ETKInvert(Rmatrix, Fnphases, CheckError); + ETKInvert(Gmatrix, Fnphases, CheckError); + if(CheckError > 0) + { + int stop = 0; + DoSimpleMsg(String("Error inverting R Matrix for Reactor.") + get_Name() + + " - G is zeroed.", 232); + for(stop = Fnphases * Fnphases, i = 1; i <= stop; i++) + { + Gmatrix[i - 1] = 0.0; + } + } + + /*Copy Xmatrix to Bmatrix and Invert*/ + for(stop = Fnphases * Fnphases, i = 1; i <= stop; i++) + { + Bmatrix[i - 1] = -XMatrix[i - 1]; + } + ETKInvert(Bmatrix, Fnphases, CheckError); + if(CheckError > 0) + { + int stop = 0; + DoSimpleMsg(String("Error inverting X Matrix for Reactor.") + get_Name() + + " - B is zeroed.", 233); + for(stop = Fnphases * Fnphases, i = 1; i <= stop; i++) + { + Bmatrix[i - 1] = 0.0; + } + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TReactorObj::CalcYPrim(int ActorID) +{ + complex Value = CZero, + Value1 = CZero, + Value2 = CZero, + Calpha1 = CZero, + Calpha2 = CZero; + // Y0, Y1, Y2 : Complex; + int i = 0; + int j = 0; + int Idx = 0; + double FreqMultiplier = 0.0; + pComplexArray Zvalues = nullptr;/*, Ymatrix */ + TcMatrix* YPrimTemp = nullptr; + TcMatrix* Zmatrix = nullptr; + double RValue = 0.0; + double LValue = 0.0; + +// Normally build only Yprim Shunt, but if there are 2 terminals and +// Bus1 <> Bus 2 + if(Get_YprimInvalid(ActorID,0)) // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + YPrim_Shunt = new TcMatrix(Yorder); + if(YPrim_Series != nullptr) + delete YPrim_Series; + YPrim_Series = new TcMatrix(Yorder); + if(YPrim != nullptr) + delete YPrim; + YPrim = new TcMatrix(Yorder); + } + else + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + if(IsShunt) + YPrimTemp = YPrim_Shunt; + else + YPrimTemp = YPrim_Series; + /*# with YPrimTemp do */ + { + auto with0 = YPrimTemp; + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + + /*If GIC simulation, Resistance Only */ + if(ActiveCircuit[ActorID]->Solution->get_FFrequency() < 0.51) // 0.5 Hz is cutoff + { + if(X > 0.0) + { + if(R <= 0.0) + R = X / 50.0; // Assume X/R = 50 + } + FYprimFreq = 0.0; // Set these to 0.0 for GIC model + FreqMultiplier = 0.0; // sets reactance part to zero + } + + /* Now, Put in Yprim matrix */ + switch(SpecType) + { + case 1: + case 2: /*Some form of R and X specified*/ + // Adjust for frequency + { + if(ASSIGNED(RCurveObj)) + RValue = R * RCurveObj->GetYValue_(FYprimFreq); + else + RValue = R; + if(ASSIGNED(LCurveObj)) + LValue = l * LCurveObj->GetYValue_(FYprimFreq); + else + LValue = l; + Value = cinv(cmplx(RValue, LValue * TwoPi * FYprimFreq)); + // Add in Rp Value if specified + if(RpSpecified) + caccum(Value, cmplx(Gp, 0.0)); + switch(Connection) + { + case 1: // Line-Line + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + j = i + 1; + if (j > Fnconds) + j = 1; + with0->AddElement(i, i, Value); + with0->AddElement(j, j, Value); + with0->AddElemsym(i, j, cnegate(Value)); + } + // Remainder of the matrix is all zero + } + break; + default: + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + with0->SetElement(i, i, Value); // Elements are only on the diagonals + with0->SetElement(i + Fnphases, i + Fnphases, Value); + with0->SetElemsym(i, i + Fnphases, cnegate(Value)); + } + break; + } + } + break; // Z matrix specified + /*Compute Z matrix*/ + + /* Put in Parallel R & L */ + case 3: + { + if(IsParallel) /*Build Z as a Y Matrix*/ + { + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Idx = (j - 1) * Fnphases + i; + /*FreqMultiplier = 0 signifies GIC model where we only need R part*/ + if(FreqMultiplier > 0.0) + Value = cmplx(Gmatrix[Idx - 1], Bmatrix[Idx - 1] / FreqMultiplier); + else + Value = cmplx(Gmatrix[Idx - 1], 0.0); + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + with0->SetElemsym(i, j + Fnphases, cnegate(Value)); + } + } + } + else + /*For Series R and X*/ + { + int stop = 0; + Zmatrix = new TcMatrix(Fnphases); + Zvalues = Zmatrix->GetValuesArrayPtr(Fnphases); // So we can stuff array fast + /* Put in Series R & L */ + for(stop = Fnphases * Fnphases, i = 1; i <= stop; i++) + { + // Correct the impedances for frequency + Zvalues[i - 1] = cmplx(Rmatrix[i - 1], XMatrix[i - 1] * FreqMultiplier); + } + Zmatrix->Invert(); /*Invert in place - is now Ymatrix*/ + if(Zmatrix->InvertError > 0) /*If error, put in tiny series conductance*/ + { + int stop = 0; + DoErrorMsg("TReactorObj.CalcYPrim", String("Matrix Inversion Error for Reactor \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with tiny conductance.", 234); + Zmatrix->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zmatrix->SetElement(i, i, cmplx(EPSILON, 0.0)); + } + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zmatrix->GetElement(i, j); + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + with0->SetElemsym(i, j + Fnphases, cnegate(Value)); + } + } + delete Zmatrix; + } + } + break; // Symmetrical component Z's specified + +/*** + + parallel doesn't make sense + If IsParallel Then + Begin + + If Cabs(Z0) > 0.0 Then Y0 := Cinv(Z0) Else Y0 := Cmplx(1.0e12, 0.0); + If Cabs(Z1) > 0.0 Then Y1 := Cinv(Z1) Else Y1 := Cmplx(1.0e12, 0.0); + If Cabs(Z2) > 0.0 Then Y2 := Cinv(Z2) Else Y2 := Cmplx(1.0e12, 0.0); + + {Assumes the sequence networks are in parallel} + Ymatrix := TcMatrix.CreateMatrix(Fnphases); + + // diagonal elements -- all the same + If Fnphases=1 Then // assume positive sequence only model + Value := Y1 + Else + Value := Cadd(Y2, Cadd(Y1, Y0)); + + Value.im := Value.im / FreqMultiplier; // Correct the impedances for frequency + Value := CdivReal(Value, 3.0); + With Ymatrix Do FOR i := 1 to Fnphases Do SetElement(i, i, Value); + + + + If FnPhases = 3 Then // otherwise undefined + Begin + Calpha1 := Conjg(Calpha); // Change it to agree with textbooks + Calpha2 := Cmul(Calpha1, Calpha1); // Alpha squared = 1 /_ 240 = 1/_-120 + Value2 := Cadd(Cmul(Calpha2,Y2),Cadd(Cmul(Calpha1, Y1), Y0)); + Value1 := Cadd(Cmul(Calpha2,Y1),Cadd(Cmul(Calpha1, Y2), Y0)); + + Value1.im := Value1.im / FreqMultiplier; // Correct the impedances for frequency + Value2.im := Value2.im / FreqMultiplier; // Correct the impedances for frequency + + Value1 := CdivReal(Value1, 3.0); + Value2 := CdivReal(Value2, 3.0); + With Ymatrix Do Begin + //Lower Triangle + SetElement(2, 1, Value1); + SetElement(3, 1, Value2); + SetElement(3, 2, Value1); + //Upper Triangle + SetElement(1, 2, Value2); + SetElement(1, 3, Value1); + SetElement(2, 3, Value2); + End; + End; + + FOR i := 1 to Fnphases Do BEGIN // could be asymmetric + FOR j := 1 to Fnphases Do BEGIN + Value := Ymatrix.GetElement(i,j); + SetElement(i, j, Value); + SetElement(i+Fnphases, j+Fnphases, Value); + SetElement(i, j+Fnphases, Cnegate(Value)); + SetElement(i+Fnphases, j, Cnegate(Value)); + END; + END; + + Ymatrix.Free; + + End + Else Begin +***/ + /*Series R+jX */ + case 4: + { + int stop = 0; + Zmatrix = new TcMatrix(Fnphases); + + // diagonal elements -- all the same + if(Fnphases == 1) // assume positive sequence only model + Value = Z1; + else + Value = cadd(Z2, cadd(Z1, Z0)); + Value.im = Value.im * FreqMultiplier; // Correct the impedances for frequency + Value = cdivreal(Value, 3.0); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zmatrix->SetElement(i, i, Value); + } + if(Fnphases == 3) // otherwise undefined + + + // There are two possible off-diagonal elements if Z1 <> Z2 + // Calpha is defined as 1 /_ -120 instead of 1 /_ 120 + { + Calpha1 = conjg(CALPHA); // Change it to agree with textbooks + Calpha2 = cmul(Calpha1, Calpha1); // Alpha squared = 1 /_ 240 = 1/_-120 + Value2 = cadd(cmul(Calpha2, Z2), cadd(cmul(Calpha1, Z1), Z0)); + Value1 = cadd(cmul(Calpha2, Z1), cadd(cmul(Calpha1, Z2), Z0)); + Value1.im = Value1.im * FreqMultiplier; // Correct the impedances for frequency + Value2.im = Value2.im * FreqMultiplier; // Correct the impedances for frequency + Value1 = cdivreal(Value1, 3.0); + Value2 = cdivreal(Value2, 3.0); + /*# with Zmatrix do */ + { + auto with1 = Zmatrix; + //Lower Triangle + with1->SetElement(2, 1, Value1); + with1->SetElement(3, 1, Value2); + with1->SetElement(3, 2, Value1); + //Upper Triangle + with1->SetElement(1, 2, Value2); + with1->SetElement(1, 3, Value1); + with1->SetElement(2, 3, Value2); + } + } + Zmatrix->Invert(); /*Invert in place - is now Ymatrix*/ + if(Zmatrix->InvertError > 0) /*If error, put in tiny series conductance*/ + { + int stop = 0; + DoErrorMsg("TReactorObj.CalcYPrim", String("Matrix Inversion Error for Reactor \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with tiny conductance.", 234); + Zmatrix->Clear(); + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Zmatrix->SetElement(i, i, cmplx(EPSILON, 0.0)); + } + } + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = 1; j <= stop1; j++) + { + Value = Zmatrix->GetElement(i, j); + with0->SetElement(i, j, Value); + with0->SetElement(i + Fnphases, j + Fnphases, Value); + with0->SetElement(i, j + Fnphases, cnegate(Value)); + with0->SetElement(i + Fnphases, j, cnegate(Value)); + } + } + delete Zmatrix; + } + break; + // END; + default: + ; + break; + } + } /*With YPRIM*/ + + // Set YPrim_Series based on diagonals of YPrim_shunt so that CalcVoltages doesn't fail + if(IsShunt) + { + if((Get_NPhases() == 1) && (!ActiveCircuit[ActorID]->PositiveSequence)) + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { // assume a neutral or grounding reactor; Leave diagonal in the circuit + YPrim_Series->SetElement(i, i, YPrim_Shunt->GetElement(i, i)); + } + } + else + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + YPrim_Series->SetElement(i, i, cmulreal(YPrim_Shunt->GetElement(i, i), 1.0e-10)); + } + } + } + YPrim->CopyFrom(YPrimTemp); + /*Don't Free YPrimTemp - It's just a pointer to an existing complex matrix*/ + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TReactorObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + int k = 0; + inherited::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, k = 1; k <= stop; k++) + { + switch(k) + { + case 7: + if(Rmatrix != nullptr) // was 'CASE i of' - good example of reason to remove all warnings + { + int stop1 = 0; + { Write(f, with0->PropertyName[k - 1]); Write(f, "= ("); } + for(stop1 = Fnphases, i = 1; i <= stop1; i++) + { + int stop2 = 0; + for(stop2 = Fnphases, j = 1; j <= stop2; j++) + { + { Write(f, Format("%-.5g",Rmatrix[(i - 1) * Fnphases + j - 1])); Write(f, L' '); } + } + if(i != Fnphases) + Write(f, L'|'); + } + WriteLn(f, L')'); + } + break; + case 8: + if(XMatrix != nullptr) + { + int stop1 = 0; + { Write(f, with0->PropertyName[k - 1]); Write(f, "= ("); } + for(stop1 = Fnphases, i = 1; i <= stop1; i++) + { + int stop2 = 0; + for(stop2 = Fnphases, j = 1; j <= stop2; j++) + { + { Write(f, Format("%-.5g",XMatrix[(i - 1) * Fnphases + j - 1])); Write(f, L' '); } + } + if(i != Fnphases) + Write(f, L'|'); + } + WriteLn(f, L')'); + } + break; + case 13: + WriteLn(f, Format("~ Z1=[%-.8g, %-.8g]",Z1.re, Z1.im)); + break; + case 14: + WriteLn(f, Format("~ Z2=[%-.8g, %-.8g]",Z2.re, Z2.im)); + break; + case 15: + WriteLn(f, Format("~ Z0=[%-.8g, %-.8g]",Z0.re, Z0.im)); + break; + case 16: + WriteLn(f, Format("~ Z =[%-.8g, %-.8g]",R, X)); + break; + case 19: + WriteLn(f, Format("~ LmH=%-.8g",l * 1000.0)); + break; + default: + { Write(f, "~ "); Write(f, with0->PropertyName[k - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(k)); } + break; + } + } + } +} + +void TReactorObj::GetLosses(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID) +{ + int i = 0; + int j = 0; + + /*Only report No Load Losses if Rp defined and Reactor is a shunt device; + Else do default behavior.*/ + if(RpSpecified && IsShunt && (Rp != 0.0)) + { + TotalLosses = Get_Losses(ActorID); // Side effect: computes Iterminal and Vterminal + /*Compute losses in Rp Branch from voltages across shunt element -- node to ground*/ + NoLoadLosses = CZero; + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + { + /*# with NodeV^[NodeRef^[i]] do */ + { + // V^2/Rp + caccum(NoLoadLosses, cmplx((Sqr(with0->NodeV[NodeRef[i - 1]].re) + Sqr(with0->NodeV[NodeRef[i - 1]].im)) / Rp, 0.0)); + } + } + else + { + /*# with VoltInActor1(NodeRef^[i]) do */ + { + auto with2 = with0->VoltInActor1(NodeRef[i - 1]); // V^2/Rp + caccum(NoLoadLosses, cmplx((Sqr(with2.re) + Sqr(with2.im)) / Rp, 0.0)); + } + } + } + } + if(ActiveCircuit[ActorID]->PositiveSequence) + cmulreal(NoLoadLosses, 3.0); + LoadLosses = csub(TotalLosses, NoLoadLosses); // Subtract no load losses from total losses + } + else + inherited::GetLosses(TotalLosses, LoadLosses, NoLoadLosses, ActorID); /*do the default Cktelement behaviors*/ +} + +String TReactorObj::GetPropertyValue(int Index) +{ + String result; + switch(Index) + { + case 10: + result = Format("%-.8g",R); + break; + case 11: + result = Format("%-.8g",X); + break; + /*Special cases for array properties*/ + case 13: + result = Format("[%-.8g, %-.8g]",Z1.re, Z1.im); + break; + case 14: + result = Format("[%-.8g, %-.8g]",Z2.re, Z2.im); + break; + case 15: + result = Format("[%-.8g, %-.8g]",Z0.re, Z0.im); + break; + case 16: + result = Format("[%-.8g, %-.8g]",R, X); + break; + case 19: + result = Format("%-.8g",l * 1000.0); + break; + case (NumPropsThisClass + 1): + result = Format("%g", NormAmps); + break; + case (NumPropsThisClass + 2): + result = Format("%g", EmergAmps); + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + return result; +} + +void TReactorObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,GetBus(1)); + Set_PropertyValue(2,GetBus(2)); + Set_PropertyValue(3,"3"); + Set_PropertyValue(4,"1200"); + Set_PropertyValue(5,"12.47"); + Set_PropertyValue(6,"wye"); + Set_PropertyValue(7,""); + Set_PropertyValue(8,""); + Set_PropertyValue(9,"NO"); // Parallel + Set_PropertyValue(10,"0"); // R series + Set_PropertyValue(11,Format("%-.6g",X)); //X + Set_PropertyValue(12,"0"); //Rp + Set_PropertyValue(13,"[0 0]"); //Z1 + Set_PropertyValue(14,"[0 0]"); //Z2 + Set_PropertyValue(15,"[0 0]"); //Z0 + Set_PropertyValue(16,"[0 0]"); //Z + Set_PropertyValue(17,""); + Set_PropertyValue(18,""); + Set_PropertyValue(19,Format("%-.8g",X / TwoPi / BaseFrequency * 1000.0)); //X + inherited::InitPropertyValues(NumPropsThisClass); + + // Override Inherited properties + Set_PropertyValue(NumPropsThisClass + 1,Str_Real(NormAmps, 0)); + Set_PropertyValue(NumPropsThisClass + 2,Str_Real(EmergAmps, 0)); + Set_PropertyValue(NumPropsThisClass + 3,Str_Real(FaultRate, 0)); + Set_PropertyValue(NumPropsThisClass + 4,Str_Real(PctPerm, 0)); + Set_PropertyValue(NumPropsThisClass + 5,Str_Real(HrsToRepair, 0)); + ClearPropSeqArray(); +} + +void TReactorObj::MakePosSequence(int ActorID) +{ + String s; + double KvarPerPhase = 0.0; + double PhasekV = 0.0; + double Rs = 0.0; + double Rm = 0.0; + int i = 0; + int j = 0; + /*If FnPhases>1 Then */ + s = " "; + switch(SpecType) + { + case 1: // kvar + { + KvarPerPhase = kvarrating / 3.0; // divide among 3 phases Fnphases; + if((Fnphases > 1) || (Connection != 0)) + PhasekV = kvrating / SQRT3; + else + PhasekV = kvrating; + s = String("Phases=1 ") + Format(" kV=%-.5g kvar=%-.5g", PhasekV, KvarPerPhase); + /*Leave R as specified*/ + } + break; // R + j X + case 2: + { + s = "Phases=1 "; + } + break; + case 3: + if(Fnphases > 1) // Matrices + { + int stop = 0; + s = "Phases=1 "; + // R1 + Rs = 0.0; // Avg Self + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Rs = Rs + Rmatrix[(i - 1) * Fnphases + i - 1]; + } + Rs = Rs / Fnphases; + Rm = 0.0; //Avg mutual + for(stop = Fnphases, i = 2; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = i; j <= stop1; j++) + { + Rm = Rm + Rmatrix[(i - 1) * Fnphases + j - 1]; + } + } + Rm = Rm / (Fnphases * (Fnphases - 1.0) / 2.0); + s = s + Format(" R=%-.5g",(Rs - Rm)); + + // X1 + Rs = 0.0; // Avg Self + for(stop = Fnphases, i = 1; i <= stop; i++) + { + Rs = Rs + XMatrix[(i - 1) * Fnphases + i - 1]; + } + Rs = Rs / Fnphases; + Rm = 0.0; //Avg mutual + for(stop = Fnphases, i = 2; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Fnphases, j = i; j <= stop1; j++) + { + Rm = Rm + XMatrix[(i - 1) * Fnphases + j - 1]; + } + } + Rm = Rm / (Fnphases * (Fnphases - 1.0) / 2.0); + s = s + Format(" X=%-.5g",(Rs - Rm)); + } + break; // symmetrical components Z1 specified + case 4: + { + s = "Phases=1 "; + } + break; + default: + ; + break; + } + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + + + + +} // namespace Reactor + + + + diff --git a/OpenDSSC/PDElements/Reactor.h b/OpenDSSC/PDElements/Reactor.h new file mode 100644 index 0000000..dba5b73 --- /dev/null +++ b/OpenDSSC/PDElements/Reactor.h @@ -0,0 +1,166 @@ +#ifndef ReactorH +#define ReactorH + +#include "System.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "Arraydef.h" +#include "d2c_structures.h" +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "Sysutils.h" +#include "XYcurve.h" +#include "mathutil.h" + + + +namespace Reactor +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* 10-26-00 Created from Capacitor object + 3-2-06 Added Parallel Option and corrected frequency adjustments + RMATRIX, Xmatrix untested + 2013 Added Symmetrical component specification and frequency-dependence for simplr + R+jX model + + +Basic Reactor + + Uses same rules as Capacitor and Fault for connections + + Implemented as a two-terminal constant impedance (Power Delivery Element) + Defaults to a Shunt Reactor but can be connected as a two-terminal series reactor + + If Parallel=Yes, then the R and X components are treated as being in parallel + + Bus2 connection defaults to 0 node of Bus1 (if Bus2 has the default bus connection + at the time Bus1 is defined. Therefore, if only Bus1 is specified, a shunt Reactor results. + If delta connected, Bus2 is set to node zero of Bus1 and nothing is returned in the lower + half of YPrim - all zeroes. + + If an ungrounded wye is desired, explicitly set Bus2= and set all nodes the same, + e.g. Bus1.4.4.4 (uses 4th node of Bus1 as neutral point) + or BusNew.1.1.1 (makes a new bus for the neutral point) + You must specify the nodes or you will get a series Reactor! + + A series Reactor is specified simply by setting bus2 and declaring the connection + to be Wye. If the connection is specified as delta, nothing will be connected to Bus2. + In fact the number of terminals is set to 1. + + Reactance may be specified as: + + 1. kvar and kv ratings at base frequency. impedance. Specify kvar as total for + all phases. For 1-phase, kV = Reactor coil kV rating. + For 2 or 3-phase, kV is line-line three phase. For more than 3 phases, specify + kV as actual coil voltage. + 2. Series Resistance, R, and Reactance, X, in ohns at base frequency to be used in each phase. If specified in this manner, + the given value is always used whether wye or delta. X may be specified as Inductance, LmH, in mH. + The Z property may also be used to specify R and X in an array. + 3. A R and X matrices . + If conn=wye then 2-terminal through device + If conn=delta then 1-terminal. + Ohms at base frequency + Note that Rmatix may be in parallel with Xmatric (set parallel = Yes) + 4. As symmetrical component values using Z1, Z2, and Z0 complex array properties. + Z2 defaults to Z1, but can be set to a different value. + +*/ + +class TReactor : public PDClass::TPDClass +{ + friend class TReactorObj; +public: + typedef PDClass::TPDClass inherited; +private: + void DoMatrix(Arraydef::pDoubleArray Matrix, int ActorID); + void InterpretConnection(const String s); + void ReactorSetbus1(const String s); +protected: + virtual int MakeLike(const String ReactorName); + void DefineProperties(); // Add Properties of this class to propName +public: + TReactor(); + virtual ~TReactor(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TReactorObj : public PDELement::TPDElement +{ + friend class TReactor; +public: + typedef PDELement::TPDElement inherited; +//private: + double R; + double Rp; + double Gp; + double X; + double l; + double kvarrating; + double kvrating; + Ucomplex::complex Z; + Ucomplex::complex Z1; + Ucomplex::complex Z2; + Ucomplex::complex Z0; + Arraydef::pDoubleArray Rmatrix; + Arraydef::pDoubleArray Gmatrix; + Arraydef::pDoubleArray XMatrix; + Arraydef::pDoubleArray Bmatrix; // If not nil then overrides C + int Connection; // 0 or 1 for wye (default) or delta, respectively + int SpecType; // 1=kvar, 2=R+jX, 3=R and X matrices, 4=sym components + bool IsParallel; + bool RpSpecified; + bool Bus2Defined; + bool Z2Specified; + bool Z0Specified; + + bool FNormAmpsSpecified; + bool FEmergAmpsSpecified; +public: + String RCurve; + XYCurve::TXYcurveObj* RCurveObj; + String LCurve; + XYCurve::TXYcurveObj* LCurveObj; + TReactorObj(TDSSClass* ParClass, const String ReactorName); + virtual ~TReactorObj(); + virtual void GetLosses(Ucomplex::complex& TotalLosses, Ucomplex::complex& LoadLosses, Ucomplex::complex& NoLoadLosses, int ActorID); + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + + // CIM XML access - this is only tested for the IEEE 8500-node feeder + TReactorObj(DSSClass::TDSSClass* ParClass); + TReactorObj(String ClassName); + TReactorObj(); +}; +extern TReactorObj* ActiveReactorObj; + + +} // namespace Reactor + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Reactor; +#endif + +#endif // ReactorH + + + + diff --git a/OpenDSSC/PDElements/Transformer.cpp b/OpenDSSC/PDElements/Transformer.cpp new file mode 100644 index 0000000..cdba824 --- /dev/null +++ b/OpenDSSC/PDElements/Transformer.cpp @@ -0,0 +1,2981 @@ + +#pragma hdrstop + +#include "Transformer.h" + +#include "Circuit.h" +#include "DSSGlobals.h" +#include "Utilities.h" +#include "XfmrCode.h" + +using namespace std; + + +namespace Transformer +{ + +TTransfObj::TTransfObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass) {} +TTransfObj::TTransfObj(String ClassName) : inherited(ClassName) {} +TTransfObj::TTransfObj() {} + + +TTransfObj* ActiveTransfObj = nullptr; /*TRANSDEBUG*/ +TXfmrCode* XfmrCodeClass = nullptr; +const int NumPropsThisClass = 49; + + +int XSCSize(int NumWindings) +{ + return ((NumWindings - 1) * NumWindings) / 2; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Creates superstructure for all Transformer objects + +TTransf::TTransf() +{ + ; + Class_Name = "Transformer"; + DSSClassType = DSSClassType + XFMR_ELEMENT; // override PDElement (kept in both actually) + ActiveElement = 0; + XfmrCodeClass = nullptr; + DefineProperties(); + + /*Make space for transformer property list*/ + std::string* slc = Slice(PropertyName, NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); /*Allow property list abbreviations*/ +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTransf::~TTransf() +{ + + // ElementList and CommandList freed in inherited destroy + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTransf::DefineProperties() +{ + NumProperties = NumPropsThisClass; + TPDClass::CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + +/* Define Property names */ + (PropertyName)[1 - 1] = "phases"; + (PropertyName)[2 - 1] = "windings"; + + // Winding Definition + (PropertyName)[3 - 1] = "wdg"; + (PropertyName)[4 - 1] = "bus"; + (PropertyName)[5 - 1] = "conn"; + (PropertyName)[6 - 1] = "kV"; // FOR 2-and 3- always kVLL ELSE actual winding KV + (PropertyName)[7 - 1] = "kVA"; + (PropertyName)[8 - 1] = "tap"; + (PropertyName)[9 - 1] = "%R"; + (PropertyName)[10 - 1] = "Rneut"; + (PropertyName)[11 - 1] = "Xneut"; + + // General Data + (PropertyName)[12 - 1] = "buses"; + (PropertyName)[13 - 1] = "conns"; + (PropertyName)[14 - 1] = "kVs"; + (PropertyName)[15 - 1] = "kVAs"; + (PropertyName)[16 - 1] = "taps"; + (PropertyName)[17 - 1] = "XHL"; + (PropertyName)[18 - 1] = "XHT"; + (PropertyName)[19 - 1] = "XLT"; + (PropertyName)[20 - 1] = "Xscarray"; // x12 13 14... 23 24.. 34 .. + (PropertyName)[21 - 1] = "thermal"; + (PropertyName)[22 - 1] = "n"; + (PropertyName)[23 - 1] = "m"; + (PropertyName)[24 - 1] = "flrise"; + (PropertyName)[25 - 1] = "hsrise"; + (PropertyName)[26 - 1] = "%loadloss"; + (PropertyName)[27 - 1] = "%noloadloss"; + (PropertyName)[28 - 1] = "normhkVA"; + (PropertyName)[29 - 1] = "emerghkVA"; + (PropertyName)[30 - 1] = "sub"; // =y/n + (PropertyName)[31 - 1] = "MaxTap"; + (PropertyName)[32 - 1] = "MinTap"; + (PropertyName)[33 - 1] = "NumTaps"; + (PropertyName)[34 - 1] = "subname"; + (PropertyName)[35 - 1] = "%imag"; + (PropertyName)[36 - 1] = "ppm_antifloat"; + (PropertyName)[37 - 1] = "%Rs"; + (PropertyName)[38 - 1] = "bank"; + (PropertyName)[39 - 1] = "XfmrCode"; + (PropertyName)[40 - 1] = "XRConst"; + (PropertyName)[41 - 1] = "X12"; + (PropertyName)[42 - 1] = "X13"; + (PropertyName)[43 - 1] = "X23"; + (PropertyName)[44 - 1] = "LeadLag"; + (PropertyName)[45 - 1] = "WdgCurrents"; + (PropertyName)[46 - 1] = "Core"; + (PropertyName)[47 - 1] = "RdcOhms"; + (PropertyName)[48 - 1] = "Seasons"; + (PropertyName)[49 - 1] = "Ratings"; + + + // define Property help values + (PropertyHelp)[1 - 1] = "Number of phases this transformer. Default is 3."; + (PropertyHelp)[2 - 1] = "Number of windings, this transformers. (Also is the number of terminals) " + "Default is 2. This property triggers memory allocation for the Transformer and will cause other properties to revert to default values."; + // Winding Definition + (PropertyHelp)[3 - 1] = "Set this = to the number of the winding you wish to define. Then set " + "the values for this winding. Repeat for each winding. Alternatively, use " + "the array collections (buses, kVAs, etc.) to define the windings. Note: " + "reactances are BETWEEN pairs of windings; they are not the property of a single winding."; + (PropertyHelp)[4 - 1] = "Bus connection spec for this winding."; + (PropertyHelp)[5 - 1] = "Connection of this winding {wye*, Delta, LN, LL}. Default is \"wye\" with the neutral solidly grounded. "; + (PropertyHelp)[6 - 1] = "For 2-or 3-phase, enter phase-phase kV rating. Otherwise, kV rating of the actual winding"; + (PropertyHelp)[7 - 1] = "Base kVA rating of the winding. Side effect: forces change of max normal and emerg kVA ratings." + "If 2-winding transformer, forces other winding to same value. " + "When winding 1 is defined, all other windings are defaulted to the same rating " + "and the first two winding resistances are defaulted to the %loadloss value."; + (PropertyHelp)[8 - 1] = "Per unit tap that this winding is on."; + (PropertyHelp)[9 - 1] = "Percent resistance this winding. (half of total for a 2-winding)."; + (PropertyHelp)[10 - 1] = "Default = -1. Neutral resistance of wye (star)-connected winding in actual ohms. " + "If entered as a negative value, the neutral is assumed to be open, or floating. " + "To solidly ground the neutral, connect the neutral conductor to Node 0 in the Bus property spec for this winding. " + "For example: Bus=MyBusName.1.2.3.0, which is generally the default connection."; + (PropertyHelp)[11 - 1] = "Neutral reactance of wye(star)-connected winding in actual ohms. May be + or -."; + + // General Data + (PropertyHelp)[12 - 1] = String("Use this to specify all the bus connections at once using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\""; + (PropertyHelp)[13 - 1] = String("Use this to specify all the Winding connections at once using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + "~ conns=(delta, wye)"; + (PropertyHelp)[14 - 1] = String("Use this to specify the kV ratings of all windings at once using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + CRLF + + "~ conns=(delta, wye)" + + CRLF + + "~ kvs=(115, 12.47)" + + CRLF + + CRLF + + "See kV= property for voltage rules."; + (PropertyHelp)[15 - 1] = "Use this to specify the kVA ratings of all windings at once using an array."; + (PropertyHelp)[16 - 1] = "Use this to specify the p.u. tap of all windings at once using an array."; + (PropertyHelp)[17 - 1] = "Use this to specify the percent reactance, H-L (winding 1 to winding 2). Use " + "for 2- or 3-winding transformers. On the kVA base of winding 1. See also X12."; + (PropertyHelp)[18 - 1] = "Use this to specify the percent reactance, H-T (winding 1 to winding 3). Use " + "for 3-winding transformers only. On the kVA base of winding 1. See also X13."; + (PropertyHelp)[19 - 1] = "Use this to specify the percent reactance, L-T (winding 2 to winding 3). Use " + "for 3-winding transformers only. On the kVA base of winding 1. See also X23."; + (PropertyHelp)[20 - 1] = String("Use this to specify the percent reactance between all pairs of windings as an array. " "All values are on the kVA base of winding 1. The order of the values is as follows:") + CRLF + + CRLF + + "(x12 13 14... 23 24.. 34 ..) " + + CRLF + + CRLF + + "There will be n(n-1)/2 values, where n=number of windings."; + (PropertyHelp)[21 - 1] = "Thermal time constant of the transformer in hours. Typically about 2."; + (PropertyHelp)[22 - 1] = "n Exponent for thermal properties in IEEE C57. Typically 0.8."; + (PropertyHelp)[23 - 1] = "m Exponent for thermal properties in IEEE C57. Typically 0.9 - 1.0"; + (PropertyHelp)[24 - 1] = "Temperature rise, deg C, for full load. Default is 65."; + (PropertyHelp)[25 - 1] = "Hot spot temperature rise, deg C. Default is 15."; + (PropertyHelp)[26 - 1] = "Percent load loss at full load. The %R of the High and Low windings (1 and 2) are adjusted to agree at rated kVA loading."; + (PropertyHelp)[27 - 1] = "Percent no load losses at rated excitatation voltage. Default is 0. Converts to a resistance in parallel with the magnetizing impedance in each winding."; + (PropertyHelp)[28 - 1] = "Normal maximum kVA rating of H winding (winding 1). Usually 100% - 110% of" + "maximum nameplate rating, depending on load shape. Defaults to 110% of kVA rating of Winding 1."; + (PropertyHelp)[29 - 1] = "Emergency (contingency) kVA rating of H winding (winding 1). Usually 140% - 150% of" + "maximum nameplate rating, depending on load shape. Defaults to 150% of kVA rating of Winding 1."; + (PropertyHelp)[30 - 1] = "={Yes|No} Designates whether this transformer is to be considered a substation." + "Default is No."; // =y/n + (PropertyHelp)[31 - 1] = "Max per unit tap for the active winding. Default is 1.10"; + (PropertyHelp)[32 - 1] = "Min per unit tap for the active winding. Default is 0.90"; + (PropertyHelp)[33 - 1] = "Total number of taps between min and max tap. Default is 32 (16 raise and 16 lower taps about the neutral position). The neutral position is not counted."; + (PropertyHelp)[34 - 1] = "Substation Name. Optional. Default is null. If specified, printed on plots"; + (PropertyHelp)[35 - 1] = "Percent magnetizing current. Default=0.0. Magnetizing branch is in parallel with windings in each phase. Also, see \"ppm_antifloat\"."; + (PropertyHelp)[36 - 1] = "Default=1 ppm. Parts per million of transformer winding VA rating connected to ground to protect against accidentally floating a winding without a reference. " + "If positive then the effect is adding a very large reactance to ground. If negative, then a capacitor."; + (PropertyHelp)[37 - 1] = String("Use this property to specify all the winding %resistances using an array. Example:") + CRLF + + CRLF + + "New Transformer.T1 buses=\"Hibus, lowbus\" " + + "~ %Rs=(0.2 0.3)"; + (PropertyHelp)[38 - 1] = "Name of the bank this transformer is part of, for CIM, MultiSpeak, and other interfaces."; + (PropertyHelp)[39 - 1] = "Name of a library entry for transformer properties. The named XfmrCode must already be defined."; + (PropertyHelp)[40 - 1] = "={Yes|No} Default is NO. Signifies whether or not the X/R is assumed contant for harmonic studies."; + (PropertyHelp)[41 - 1] = "Alternative to XHL for specifying the percent reactance from winding 1 to winding 2. Use " + "for 2- or 3-winding transformers. Percent on the kVA base of winding 1. "; + (PropertyHelp)[42 - 1] = "Alternative to XHT for specifying the percent reactance from winding 1 to winding 3. Use " + "for 3-winding transformers only. Percent on the kVA base of winding 1. "; + (PropertyHelp)[43 - 1] = "Alternative to XLT for specifying the percent reactance from winding 2 to winding 3.Use " + "for 3-winding transformers only. Percent on the kVA base of winding 1. "; + (PropertyHelp)[44 - 1] = "{Lead | Lag (default) | ANSI (default) | Euro } Designation in mixed Delta-wye connections the " + "relationship between HV to LV winding. Default is ANSI 30 deg lag, e.g., Dy1 of Yd1 vector group. " + "To get typical European Dy11 connection, specify either \"lead\" or \"Euro\""; + (PropertyHelp)[45 - 1] = "(Read only) Makes winding currents available via return on query (? Transformer.TX.WdgCurrents). " + "Order: Phase 1, Wdg 1, Wdg 2, ..., Phase 2 ..."; + (PropertyHelp)[46 - 1] = "{Shell*|5-leg|3-Leg|1-phase} Core Type. Used for GIC analysis"; + (PropertyHelp)[47 - 1] = "Winding dc resistance in OHMS. Useful for GIC analysis. From transformer test report. " + "Defaults to 85% of %R property"; + (PropertyHelp)[48 - 1] = "Defines the number of ratings to be defined for the transfomer, to be used only when defining seasonal ratings using the \"Ratings\" property."; + (PropertyHelp)[49 - 1] = String("An array of ratings to be used when the seasonal ratings flag is True. It can be used to insert") + CRLF + + "multiple ratings to change during a QSTS simulation to evaluate different ratings in transformers. Is given in kVA"; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTransf::NewObject(const String ObjName) +{ + int result = 0; + // create a new object of this class and add to list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TTransfObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); // Return index of transformer in transformer list + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTransfObj::get_NumWindings() +{ + return NumWindings; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_XHL() +{ + return XHL; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_XHT() +{ + return XHT; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_XLT() +{ + return XLT; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_NormMaxHkVA() +{ + return NormMaxHkVA; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_EmergMaxHkVA() +{ + return EmergMaxHkVA; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_ThermalTimeConst() +{ + return ThermalTimeConst; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_n_thermal() +{ + return n_thermal; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_m_thermal() +{ + return m_thermal; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_FLrise() +{ + return FLrise; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_HSrise() +{ + return HSrise; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_pctLoadLoss() +{ + return pctLoadLoss; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_pctNoLoadLoss() +{ + return pctNoLoadLoss; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_pctImag() +{ + return pctImag; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_ppm_FloatFactor() +{ + return ppm_FloatFactor; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +double TTransfObj::get_VABase() +{ + return VABase; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/* + A Transf Defaults to 3-phases, 2-windings (both wye) +*/ + +int TTransf::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + int i = 0; + String ParamName; /*For parsing property names*/ + String Param; + // continue parsing cmdline presently in Parser + + /*Make this object the active circuit element*/ + ActiveTransfObj = (TTransfObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveTransfObj); // use property to set this value + result = 0; + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + with0->XHLChanged = false; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + with0->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"Transformer." + + with0->get_Name() + + "\"", 110); + break; + case 1: + with0->Set_NPhases(Parser[ActorID]->MakeInteger_()); + break; + case 2: + with0->SetNumWindings(Parser[ActorID]->MakeInteger_()); + break; // Reallocate stuff if bigger + case 3: + SetActiveWinding(Parser[ActorID]->MakeInteger_()); + break; + case 4: + with0->SetBus(with0->ActiveWinding, Param); + break; + case 5: + InterpretConnection(Param); + break; + case 6: + with0->WINDING_[with0->ActiveWinding - 1].kVLL = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->WINDING_[with0->ActiveWinding - 1].kVA = Parser[ActorID]->MakeDouble_(); + break; + case 8: + with0->WINDING_[with0->ActiveWinding - 1].puTap = Parser[ActorID]->MakeDouble_(); + break; + case 9: + with0->WINDING_[with0->ActiveWinding - 1].Rpu = Parser[ActorID]->MakeDouble_() * 0.01; + break; // %R + case 10: + with0->WINDING_[with0->ActiveWinding - 1].Rneut = Parser[ActorID]->MakeDouble_(); + break; + case 11: + with0->WINDING_[with0->ActiveWinding - 1].Xneut = Parser[ActorID]->MakeDouble_(); + break; + case 12: + InterpretAllBuses(Param); + break; + case 13: + InterpretAllConns(Param); + break; + case 14: + InterpretAllkVRatings(Param); + break; + case 15: + InterpretAllkVARatings(Param); + break; + case 16: + InterpretAllTaps(Param); + break; + case 17: + with0->XHL = TrapZero(Parser[ActorID]->MakeDouble_(), 7.0) * 0.01; + break; + case 18: + with0->XHT = TrapZero(Parser[ActorID]->MakeDouble_(), 35.0) * 0.01; + break; + case 19: + with0->XLT = TrapZero(Parser[ActorID]->MakeDouble_(), 30.0) * 0.01; + break; + case 20: + Parser[ActorID]->ParseAsVector(XSCSize(with0->NumWindings), (pDoubleArray) (with0->XSC.data())); + break; + case 21: + with0->ThermalTimeConst = Parser[ActorID]->MakeDouble_(); + break; + case 22: + with0->n_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 23: + with0->m_thermal = Parser[ActorID]->MakeDouble_(); + break; + case 24: + with0->FLrise = Parser[ActorID]->MakeDouble_(); + break; + case 25: + with0->HSrise = Parser[ActorID]->MakeDouble_(); + break; + case 26: + with0->pctLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 27: + with0->pctNoLoadLoss = Parser[ActorID]->MakeDouble_(); + break; + case 28: + with0->NormMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 29: + with0->EmergMaxHkVA = Parser[ActorID]->MakeDouble_(); + break; + case 30: + with0->IsSubstation = InterpretYesNo(Param); + break; + case 31: + with0->WINDING_[with0->ActiveWinding - 1].MaxTap = Parser[ActorID]->MakeDouble_(); + break; + case 32: + with0->WINDING_[with0->ActiveWinding - 1].MinTap = Parser[ActorID]->MakeDouble_(); + break; + case 33: + with0->WINDING_[with0->ActiveWinding - 1].NumTaps = Parser[ActorID]->MakeInteger_(); + break; + case 34: + with0->SubstationName = Param; + break; + case 35: + with0->pctImag = Parser[ActorID]->MakeDouble_(); + break; + case 36: + with0->ppm_FloatFactor = Parser[ActorID]->MakeDouble_() * 1.0e-6; + break; + case 37: + InterpretAllRs(Param); + break; + case 38: + with0->XfmrBank = Param; + break; + case 39: + with0->FetchXfmrCode(Param); + break; + case 40: + with0->XRConst = InterpretYesNo(Param); + break; + case 41: + with0->XHL = TrapZero(Parser[ActorID]->MakeDouble_(), 7.0) * 0.01; + break; + case 42: + with0->XHT = TrapZero(Parser[ActorID]->MakeDouble_(), 35.0) * 0.01; + break; + case 43: + with0->XLT = TrapZero(Parser[ActorID]->MakeDouble_(), 30.0) * 0.01; + break; + case 44: + with0->HVLeadsLV = InterpretLeadLag(Param); + break; + case 45: + with0->Set_PropertyValue(45,""); + break; // placeholder, do nothing just throw value away if someone tries to set it. + case 46: + with0->strCoreType = Param; + break; + case 47: + with0->WINDING_[with0->ActiveWinding - 1].RdcOhms = Parser[ActorID]->MakeDouble_(); + break; + case 48: + { + with0->NumAmpRatings = Parser[ActorID]->MakeInteger_(); + with0->kVARatings.resize( with0->NumAmpRatings ); + } + break; + case 49: + { + with0->kVARatings.resize( with0->NumAmpRatings ); + Param = Parser[ActiveActor]->MakeString_(); + with0->NumAmpRatings = InterpretDblArray(Param, with0->NumAmpRatings, &(with0->kVARatings[0])); + } + break; + // Inherited properties + default: + TPDClass::ClassEdit(ActiveTransfObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Take care of properties that require some additional work,*/ + switch(ParamPointer) + { + case 1: + with0->Set_Nconds(with0->Fnphases + 1); + break; // Force redefinition of number of conductors and reallocation of matrices + // default all winding kVAs to first winding so latter Donot have to be specified + case 7: + if(with0->ActiveWinding == 1) + { + int stop = 0; + for(stop = with0->NumWindings, i = 2; i <= stop; i++) + { + with0->WINDING_[i - 1].kVA = with0->WINDING_[1 - 1].kVA; + } + with0->NormMaxHkVA = 1.1 * with0->WINDING_[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * with0->WINDING_[1 - 1].kVA; + } + else + { + if(with0->NumWindings == 2) + { + with0->WINDING_[1 - 1].kVA = with0->WINDING_[2 - 1].kVA; // For 2-winding, force both kVAs to be same + } + } + break; + // Update LoadLosskW if winding %r changed. Using only windings 1 and 2 + case 9: + with0->pctLoadLoss = (with0->WINDING_[1 - 1].Rpu + with0->WINDING_[2 - 1].Rpu) * 100.0; + break; + case 15: + { + with0->NormMaxHkVA = 1.1 * with0->WINDING_[1 - 1].kVA; // Defaults for new winding rating. + with0->EmergMaxHkVA = 1.5 * with0->WINDING_[1 - 1].kVA; + } + break; + case 17: case 18: case 19: + with0->XHLChanged = true; + break; + case 20: + for(int stop = XSCSize(with0->NumWindings), i = 1; i <= stop; i++) + { + with0->XSC[i - 1] = with0->XSC[i - 1] * 0.01; + } + break; // Convert to per unit + // Assume load loss is split evenly between windings 1 and 2 + case 26: + { + with0->WINDING_[1 - 1].Rpu = with0->pctLoadLoss / 2.0 / 100.0; + with0->WINDING_[2 - 1].Rpu = with0->WINDING_[1 - 1].Rpu; + } + break; + case 37: + with0->pctLoadLoss = (with0->WINDING_[1 - 1].Rpu + with0->WINDING_[2 - 1].Rpu) * 100.0; + break; // Update + case 41: case 42: case 43: + with0->XHLChanged = true; + break; + case 46: + with0->CoreType = InterpretCoreType(Param); + break; // Assign integer number + case 47: + with0->WINDING_[with0->ActiveWinding - 1].RdcSpecified = true; + break; + default: + ; + break; + } + + //YPrim invalidation on anything that changes impedance values + switch(ParamPointer) + { + case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: + case 15: case 16: case 17: case 18: case 19: + with0->Set_YprimInvalid(ActorID,true); + break; + case 26: case 27: + with0->Set_YprimInvalid(ActorID,true); + break; + case 35: case 36: case 37: + with0->Set_YprimInvalid(ActorID,true); + break; + case 41: case 42: case 43: + with0->Set_YprimInvalid(ActorID,true); + break; + default: + ; + break; + } + + /*Advance to next property on input line*/ + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTransf::SetActiveWinding(int W) +{ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + if((W > 0) && (W <= with0->NumWindings)) + with0->ActiveWinding = W; + else + DoSimpleMsg(String("Wdg parameter invalid for \"") + ( (TDSSObject*) ActiveTransfObj )->get_Name() + + "\"", 112); + } +} + +double TTransf::TrapZero(double Value, double DefaultValue) +{ + double result = 0.0; + if(Value == 0.0) + { + DoSimpleMsg(String("Zero Reactance specified for Transformer.") + ( ( TDSSObject*)ActiveTransfObj )->get_Name(), 11201); + result = DefaultValue; + } + else + result = Value; + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +// Accepts +// delta or LL (Case insensitive) +// Y, wye, or LN + +void TTransf::InterpretConnection(const String s) +{ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + /*# with with0->WINDING^[ActiveWinding] do */ + { + + switch(LowerCase(s)[0]) + { + case L'y': case L'w': + with0->WINDING_[with0->ActiveWinding - 1].Connection = 0; + break; /*Wye*/ + case L'd': + with0->WINDING_[with0->ActiveWinding - 1].Connection = 1; + break; /*Delta or line-Line*/ + case L'l': + switch(LowerCase(s)[1]) + { + case L'n': + with0->WINDING_[with0->ActiveWinding - 1].Connection = 0; + break; + case L'l': + with0->WINDING_[with0->ActiveWinding - 1].Connection = 1; + break; + default: + ; + break; + } + break; + default: + ; + break; + } + } + with0->Yorder = with0->Fnconds * with0->Fnterms; + with0->Set_YprimInvalid(ActiveActor,true); + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding connections expressed in one array of strings + +void TTransf::InterpretAllConns(const String s) +{ + String S1; + String S2; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + S1 = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + S2 = AuxParser[ActiveActor]->MakeString_(); + if(S2.size() > 0) + InterpretConnection(S2); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding bus connections expressed in one array of strings + +void TTransf::InterpretAllBuses(const String s) +{ + String BusNam; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + BusNam = AuxParser[ActiveActor]->MakeString_(); + if(BusNam.size() > 0) + with0->SetBus(with0->ActiveWinding, BusNam); + } + } +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding bus connections expressed in one array of strings + +bool TTransf::InterpretLeadLag(const String s) +{ + bool result = false; + result = false; // default to ANSI 30 Deg Lag if can't understand S + if(CompareTextShortest(s, "lead") == 0) + result = true; + else + { + if(CompareTextShortest(s, "euro") == 0) + result = true; + } + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding kV ratings expressed in one array of strings + +void TTransf::InterpretAllkVRatings(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + with0->WINDING_[with0->ActiveWinding - 1].kVLL = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding ratings expressed in one array of strings + +void TTransf::InterpretAllkVARatings(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + with0->WINDING_[with0->ActiveWinding - 1].kVA = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding ratings expressed in one array of strings + +void TTransf::InterpretAllRs(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + with0->WINDING_[with0->ActiveWinding - 1].Rpu = AuxParser[ActiveActor]->MakeDouble_() * 0.01; + } + } +} + + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +// routine expecting all winding taps expressed in one array of strings + +void TTransf::InterpretAllTaps(const String s) +{ + String DataStr; + int i = 0; + AuxParser[ActiveActor]->SetCmdString(s); // Load up Parser + + /*Loop for no more than the expected number of windings; Ignore omitted values*/ + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + with0->ActiveWinding = i; + String dummy = AuxParser[ActiveActor]->GetNextParam(); // ignore any parameter name, not expecting any + DataStr = AuxParser[ActiveActor]->MakeString_(); + if(DataStr.size() > 0) + with0->WINDING_[with0->ActiveWinding - 1].puTap = AuxParser[ActiveActor]->MakeDouble_(); + } + } +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTransf::MakeLike(const String TransfName) +{ + int result = 0; + TTransfObj* OtherTransf = nullptr; + int i = 0; + result = 0; + /*See if we can find this Transf name in the present collection*/ + OtherTransf = ((TTransfObj*) Find(TransfName)); + if(OtherTransf != nullptr) + /*# with ActiveTransfObj do */ + { + auto with0 = ActiveTransfObj; + int stop = 0; + with0->Set_NPhases(((TDSSCktElement*)OtherTransf)->Fnphases); + with0->SetNumWindings(OtherTransf->NumWindings); + ((TDSSCktElement*)with0)->Set_Nconds(((TDSSCktElement*)with0)->Fnphases + 1); // forces reallocation of terminals and conductors + ((TDSSCktElement*)with0)->Yorder = ((TDSSCktElement*)with0)->Fnconds * ((TDSSCktElement*)with0)->Fnterms; + ((TDSSCktElement*)with0)->Set_YprimInvalid(ActiveActor,true); + for(stop = with0->NumWindings, i = 1; i <= stop; i++) + { + /*# with with0->WINDING^[i] do */ + { + + with0->WINDING_[i - 1].Connection = OtherTransf->WINDING_[i - 1].Connection; + with0->WINDING_[i - 1].kVLL = OtherTransf->WINDING_[i - 1].kVLL; + with0->WINDING_[i - 1].VBase = OtherTransf->WINDING_[i - 1].VBase; + with0->WINDING_[i - 1].kVA = OtherTransf->WINDING_[i - 1].kVA; + with0->WINDING_[i - 1].puTap = OtherTransf->WINDING_[i - 1].puTap; + with0->WINDING_[i - 1].Rpu = OtherTransf->WINDING_[i - 1].Rpu; + with0->WINDING_[i - 1].RdcOhms = OtherTransf->WINDING_[i - 1].RdcOhms; + with0->WINDING_[i - 1].RdcSpecified = OtherTransf->WINDING_[i - 1].RdcSpecified; + with0->WINDING_[i - 1].Rneut = OtherTransf->WINDING_[i - 1].Rneut; + with0->WINDING_[i - 1].Xneut = OtherTransf->WINDING_[i - 1].Xneut; + // copy the taps + with0->WINDING_[i - 1].TapIncrement = OtherTransf->WINDING_[i - 1].TapIncrement; + with0->WINDING_[i - 1].MinTap = OtherTransf->WINDING_[i - 1].MinTap; + with0->WINDING_[i - 1].MaxTap = OtherTransf->WINDING_[i - 1].MaxTap; + with0->WINDING_[i - 1].NumTaps = OtherTransf->WINDING_[i - 1].NumTaps; + } + } + with0->SetTermRef(); + with0->XHL = OtherTransf->XHL; + with0->XHT = OtherTransf->XHT; + with0->XLT = OtherTransf->XLT; + for(stop = XSCSize(with0->NumWindings), i = 1; i <= stop; i++) + { + with0->XSC[i - 1] = OtherTransf->XSC[i - 1]; + } + with0->ZB->CopyFrom(OtherTransf->ZB); + with0->Y_1Volt->CopyFrom(OtherTransf->Y_1Volt); + with0->Y_Term->CopyFrom(OtherTransf->Y_Term); + with0->Y_1Volt_NL->CopyFrom(OtherTransf->Y_1Volt_NL); + with0->Y_Term_NL->CopyFrom(OtherTransf->Y_Term_NL); + with0->ThermalTimeConst = OtherTransf->ThermalTimeConst; + with0->n_thermal = OtherTransf->n_thermal; + with0->m_thermal = OtherTransf->m_thermal; + with0->FLrise = OtherTransf->FLrise; + with0->HSrise = OtherTransf->HSrise; + with0->pctLoadLoss = OtherTransf->pctLoadLoss; + with0->pctNoLoadLoss = OtherTransf->pctNoLoadLoss; + with0->NormMaxHkVA = OtherTransf->NormMaxHkVA; + with0->EmergMaxHkVA = OtherTransf->EmergMaxHkVA; + with0->XRConst = OtherTransf->XRConst; + with0->XfmrBank = OtherTransf->XfmrBank; + with0->XfmrCode = OtherTransf->XfmrCode; + ClassMakeLike(OtherTransf); + for(stop = with0->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + if(i != 45) + // Skip readonly properties + with0->Set_PropertyValue(i,( (TDSSObject*) OtherTransf )->Get_PropertyValue(i)); + } + with0->NumAmpRatings = OtherTransf->NumAmpRatings; + with0->kVARatings.resize( with0->NumAmpRatings ); + for(stop = ( with0->kVARatings.size() - 1 ), i = 0; i <= stop; i++) + { + with0->kVARatings[i] = OtherTransf->kVARatings[i]; + } + result = 1; + } + else + DoSimpleMsg(String("Error in Transf MakeLike: \"") + TransfName + + "\" Not Found.", 113); + return result; +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +int TTransf::Init(int Handle, int ActorID) +{ + int result = 0; + DoSimpleMsg("Need to implement TTransf.Init", -1); + result = 0; + return result; +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// TTransf Obj +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTransfObj::TTransfObj(TDSSClass* ParClass, const String TransfName) + : inherited(ParClass), + DeltaDirection(1), + pctImag(0.0), + XRConst(false), + NumWindings(0), + MaxWindings(0), + XHL(0.0), + XHT(0.0), + XLT(0.0), + ZBase(0.0), + VABase(0.0), + ZB(nullptr), + Y_1Volt(nullptr), + Y_Term(nullptr), + Y_1Volt_NL(nullptr), + Y_Term_NL(nullptr), + Y_Terminal_Freqmult(0.0), + NormMaxHkVA(0.0), + EmergMaxHkVA(0.0), + ThermalTimeConst(0.0), + n_thermal(0.0), + m_thermal(0.0), + FLrise(0.0), + HSrise(0.0), + pctLoadLoss(0.0), + pctNoLoadLoss(0.0), + HVLeadsLV(false), + XHLChanged(false), + ActiveWinding(0), + IsSubstation(false), + CoreType(0) +{ + int i = 0; + int stop = 0; + + TermRef.clear(); + XSC.clear(); + Set_Name(LowerCase(TransfName)); + DSSObjType = ParClass->DSSClassType; //DSSObjType + XFMR; // override PDElement (kept in both actually) + Set_NPhases(3); // Directly set conds and phases + Fnconds = Fnphases + 1; + SetNumWindings(2); // must do this after setting number of phases + ActiveWinding = 1; + Set_NTerms(NumWindings); // Force allocation of terminals and conductors + XHL = 0.07; + XHT = 0.35; + XLT = 0.30; + XHLChanged = true; // Set flag to for calc of XSC array from XHL, etc. + SubstationName = ""; + XfmrBank = ""; + XfmrCode = ""; + CoreType = 0; + strCoreType = "shell"; + VABase = WINDING_[1 - 1].kVA * 1000.0; + ThermalTimeConst = 2.0; + n_thermal = 0.8; + m_thermal = 0.8; + FLrise = 65.0; + HSrise = 15.0; // Hot spot rise + NormMaxHkVA = 1.1 * WINDING_[1 - 1].kVA; + EmergMaxHkVA = 1.5 * WINDING_[1 - 1].kVA; + pctLoadLoss = 2.0 * WINDING_[1 - 1].Rpu * 100.0; // assume two windings for init'ing + ppm_FloatFactor = 0.000001; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1].ComputeAntiFloatAdder(ppm_FloatFactor, VABase / Fnphases); + } + + /*Default the no load properties to zero*/ + pctNoLoadLoss = 0.0; + FaultRate = 0.007; + IsSubstation = false; + HVLeadsLV = false; // Defaults to ANSI connection + Y_Terminal_Freqmult = 0.0; + Yorder = Fnterms * Fnconds; + InitPropertyValues(0); + NumAmpRatings = 1; + kVARatings.resize( NumAmpRatings ); + kVARatings[0] = NormMaxHkVA; + RecalcElementData(ActiveActor); +} + +void TTransfObj::SetNumWindings(int n) +{ + int i = 0; + int OldWdgSize = 0; + int NewWdgSize = 0; + if(n > 1) + { + int stop = 0; + // Free old winding objects + WINDING_.clear(); + OldWdgSize = XSCSize(NumWindings); // this is needed to emulate the beavior in delphi, do not remove the (double)! + NumWindings = n; + MaxWindings = n; + NewWdgSize = XSCSize(NumWindings); + Fnconds = Fnphases + 1; + Set_NTerms(NumWindings); + + WINDING_.resize(MaxWindings); // Reallocate collector array + for(stop = MaxWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1] = TWinding(); + } + + // array of short circuit measurements between pairs of windings + XSC.resize( NewWdgSize ); + for(stop = NewWdgSize, i = OldWdgSize + 1; i <= stop; i++) + { + XSC[i - 1] = 0.30; + } + TermRef.resize(2 * NumWindings * Fnphases); + + /*Reallocate impedance matrices*/ + if (ZB != nullptr) delete ZB; // ZB->~TcMatrix(); + if (Y_1Volt != nullptr) delete Y_1Volt; // Y_1Volt->~TcMatrix(); + if (Y_1Volt_NL != nullptr) delete Y_1Volt_NL; // Y_1Volt_NL->~TcMatrix(); + if (Y_Term != nullptr) delete Y_Term; // Y_Term->~TcMatrix(); + if (Y_Term_NL != nullptr) delete Y_Term_NL; // Y_Term_NL->~TcMatrix(); + + ZB = new TcMatrix(NumWindings - 1); + Y_1Volt = new TcMatrix(NumWindings); + Y_1Volt_NL = new TcMatrix(NumWindings); + Y_Term = new TcMatrix(2 * NumWindings); + Y_Term_NL = new TcMatrix(2 * NumWindings); + } + else + DoSimpleMsg(String("Invalid number of windings: (") + IntToStr(n) + + ") for Transformer " + + get_Name(), 111); +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +TTransfObj::~TTransfObj() +{ + /*Throw away stuff allocated for this object*/ + + XSC.clear(); + TermRef.clear(); + if (ZB != nullptr) delete ZB; // ZB->~TcMatrix(); + if (Y_1Volt != nullptr) delete Y_1Volt; // Y_1Volt->~TcMatrix(); + if (Y_1Volt_NL != nullptr) delete Y_1Volt_NL; // Y_1Volt_NL->~TcMatrix(); + if (Y_Term != nullptr) delete Y_Term; // Y_Term->~TcMatrix(); + if (Y_Term_NL != nullptr) delete Y_Term_NL; // Y_Term_NL->~TcMatrix(); + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTransfObj::RecalcElementData(int ActorID) +{ + int i = 0; + int ihvolt = 0; + double VFactor = 0.0; + + // Determine Delta Direction + // If high voltage is delta, delta leads y + // If high voltage is wye, delta lags wye + int stop = 0; + if(WINDING_[1 - 1].Connection == WINDING_[2 - 1].Connection) + DeltaDirection = 1; + else + { + if(WINDING_[1 - 1].kVLL >= WINDING_[2 - 1].kVLL) + ihvolt = 1; + else + ihvolt = 2; + switch(WINDING_[ihvolt - 1].Connection) + { + case 0: + if(HVLeadsLV) + DeltaDirection = -1; + else + DeltaDirection = 1; + break; + case 1: + if(HVLeadsLV) + DeltaDirection = 1; + else + DeltaDirection = -1; + break; + // ---old code --- If Winding^[2].Connection = 0 Then DeltaDirection := -1 Else DeltaDirection := 1; + default: + ; + break; + } + } + SetTermRef(); // Re-establish TermRef IF num windings or connection changed + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(WINDING_[i - 1].NumTaps > 0) + WINDING_[i - 1].TapIncrement = (WINDING_[i - 1].MaxTap - WINDING_[i - 1].MinTap) / WINDING_[i - 1].NumTaps; + else + WINDING_[i - 1].TapIncrement = 0.0; + } + } + if(XHLChanged) + /*should only happen for 2- and 3-winding transformers*/ + { + if(NumWindings <= 3) + { + int stop = 0; + for(stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + switch(i) + { + case 1: + XSC[1 - 1] = XHL; + break; + case 2: + XSC[2 - 1] = XHT; + break; + case 3: + XSC[3 - 1] = XLT; + break; + default: + ; + break; + } + } + } + XHLChanged = false; + } + + // Set winding voltage bases (in volts) + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + switch(WINDING_[i - 1].Connection) + { // Get the actual turns voltage base for each winding + case 0: + switch(Fnphases) + { + case 2: + case 3: // Wye + WINDING_[i - 1].VBase = WINDING_[i - 1].kVLL * InvSQRT3x1000; + break; // assume 3-phase for 2-phase designation + default: + WINDING_[i - 1].VBase = WINDING_[i - 1].kVLL * 1000.0; + break; + } + break; + case 1: + WINDING_[i - 1].VBase = WINDING_[i - 1].kVLL * 1000.0; + break; // delta + default: + ; + break; + } + } + } + + /*Base rating of Winding 1 */ + VABase = WINDING_[1 - 1].kVA * 1000.0; + + // Set Rdc parameters for each winding. + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(WINDING_[i - 1].RdcSpecified) + WINDING_[i - 1].Rdcpu = WINDING_[i - 1].RdcOhms / (Sqr(WINDING_[i - 1].VBase) / VABase); + else + { + WINDING_[i - 1].Rdcpu = Abs( 0.85 * WINDING_[i - 1].Rpu ); // use abs in case this resistance comes out negative. + WINDING_[i - 1].RdcOhms = WINDING_[i - 1].Rdcpu * Sqr(WINDING_[i - 1].VBase) / VABase; + } + } + } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + WINDING_[i - 1].ComputeAntiFloatAdder(ppm_FloatFactor, VABase / Fnphases); + } + + /* Normal and Emergency terminal current Rating for UE check*/ + VFactor = 1.0; // ensure initialization + switch(WINDING_[1 - 1].Connection) + { + case 0: + VFactor = WINDING_[1 - 1].VBase * 0.001; + break; // wye + case 1: + switch(Fnphases) + { + case 1: + VFactor = WINDING_[1 - 1].VBase * 0.001; + break; + case 2: + case 3: + VFactor = WINDING_[1 - 1].VBase * 0.001 / SQRT3; + break; + default: + VFactor = WINDING_[1 - 1].VBase * 0.001 * 0.5 / sin(PI / double(Fnphases)); + break; + } + break; + default: + ; + break; + } + + /*Divide per phase kVA by voltage to neutral*/ + NormAmps = NormMaxHkVA / Fnphases / VFactor; + EmergAmps = EmergMaxHkVA / Fnphases / VFactor; + AmpRatings.resize( NumAmpRatings ); + for(stop = ( NumAmpRatings - 1), i = 0; i <= stop; i++) + { + AmpRatings[i] = 1.1 * kVARatings[i] / Fnphases / VFactor; + } + CalcY_Terminal(1.0); // Calc Y_Terminal at base frequency +} + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +/*Override standard SaveWrite*/ +/*Transformer structure not conducive to standard means of saving*/ + +void TTransfObj::SaveWrite(TTextRec& f) +{ + int iProp = 0; + int i = 0; + /*Write only properties that were explicitly set in the + final order they were actually set*/ + iProp = GetNextPropertySet(0); // Works on ActiveDSSObject + while(iProp > 0) + { + /*# with ParentClass do */ + { + auto with0 = ParentClass; + switch((with0->RevPropertyIdxMap)[iProp - 1]) + { + /*Trap wdg= and write out array properties instead*/ + case 3: // if WDG= was ever used write out arrays ... + { + int stop = 0; + for(stop = 16, i = 12; i <= stop; i++) + { + String PropValue = "=" + GetPropertyValue(i); + Write(f, " " + (with0->PropertyName)[i - 1] + PropValue); + } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + Write(f, Format(" wdg=%d %%sR=%.7g RdcOhms=%.7g", i-1, WINDING_[i - 1].Rpu * 100.0, WINDING_[i - 1].RdcOhms)); + + } + } + } + break; /*do Nothing*/ + case 4: case 5: case 6: case 7: case 8: case 9: + ; + break; // Ignore these properties; use arrays instead + default: + if(Length(String(Get_PropertyValue(iProp))) > 0) + { + String PropValue = "=" + CheckForBlanks(String(Get_PropertyValue(iProp))); + Write(f, " " + (with0->PropertyName)[(with0->RevPropertyIdxMap)[iProp - 1] - 1] + PropValue); + } + break; + } + } + iProp = GetNextPropertySet(iProp); + } +} + +// sets an array which maps the two conductors of each winding to the +// phase and neutral conductors of the transformer according to the winding connection + +void TTransfObj::SetTermRef() +{ + int i = 0; + int j = 0; + int k = 0; + k = 0; + switch(Fnphases) + { + case 1: + for(int stop = NumWindings, j = 1; j <= stop; j++) + { + ++k; + TermRef[k - 1] = (j - 1) * Fnconds + 1; + ++k; + TermRef[k - 1] = j * Fnconds; + } + break; + default: + int stop = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = NumWindings, j = 1; j <= stop1; j++) + { + ++k; + switch(WINDING_[j - 1].Connection) + { + case 0: // Wye + { + TermRef[k - 1] = (j - 1) * Fnconds + i; + ++k; + TermRef[k - 1] = j * Fnconds; + } + break; +/***** WILL THIS WORK for 2-PHASE OPEN DELTA ???? Need to check this sometime*/ // Delta + case 1: + { + TermRef[k - 1] = (j-1) * Fnconds + i; + ++k; + TermRef[k - 1] = (j-1) * Fnconds + RotatePhases(i); // connect to next phase in sequence + } + break; + default: + ; + break; + } /*CASE connection*/ + } + } + break; + } /*CASE Fnphases*/ +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TTransfObj::CalcYPrim(int ActorID) +{ + double FreqMultiplier = 0.0; + if(Get_YprimInvalid(ActorID,0)) + // Reallocate YPrim if something has invalidated old allocation + { + if(YPrim_Series != nullptr) + delete YPrim_Series; + if(YPrim_Shunt != nullptr) + delete YPrim_Shunt; + if(YPrim != nullptr) + delete YPrim; + YPrim_Series = new TcMatrix(Yorder); + YPrim_Shunt = new TcMatrix(Yorder); + YPrim = new TcMatrix(Yorder); + } + else + /*Same size as last time; just zero out to start over*/ + { + YPrim_Series->Clear(); // zero out YPrim + YPrim_Shunt->Clear(); // zero out YPrim + YPrim->Clear(); + } + + // Set frequency multipliers for this calculation + FYprimFreq = ActiveCircuit[ActorID]->Solution->get_FFrequency(); + FreqMultiplier = FYprimFreq / BaseFrequency; + // Check for rebuilding Y_Terminal; Only rebuild if freq is different than last time + if(FreqMultiplier != Y_Terminal_Freqmult) + CalcY_Terminal(FreqMultiplier); + BuildYPrimComponent(YPrim_Series, Y_Term); + BuildYPrimComponent(YPrim_Shunt, Y_Term_NL); + AddNeutralToY(FreqMultiplier); + + /*Combine the two Yprim components into Yprim*/ + YPrim->CopyFrom(YPrim_Series); + YPrim->AddFrom(YPrim_Shunt); + + /*Now Account for Open Conductors*/ + /*For any conductor that is open, zero out row and column*/ + inherited::CalcYPrim(ActorID); + Set_YprimInvalid(ActorID,false); +} + +void TTransfObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + int j = 0; + TcMatrix* ZBtemp = nullptr; + int stop = 0; + inherited::DumpProperties(f, Complete); + + /*Basic Property Dump*/ + { Write(f, "~ "); Write(f, "NumWindings="); WriteLn(f, NumWindings, 0); } + { Write(f, "~ "); Write(f, "phases="); WriteLn(f, Fnphases, 0); } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(i == 1) + { Write(f, "~ "); Write(f, "Wdg="); Write(f, i, 0); Write(f, " bus="); WriteLn(f, Get_FirstBus()); } + else + { Write(f, "~ "); Write(f, "Wdg="); Write(f, i, 0); Write(f, " bus="); WriteLn(f, Get_NextBus()); } + switch(WINDING_[i - 1].Connection) + { + case 0: + WriteLn(f, "~ conn=wye"); + break; + case 1: + WriteLn(f, "~ conn=delta"); + break; + default: + ; + break; + } + { Write(f, "~ kv="); WriteLn(f, WINDING_[i - 1].kVLL, 0, 2); } + { Write(f, "~ kVA="); WriteLn(f, WINDING_[i - 1].kVA, 0, 1); } + { Write(f, "~ tap="); WriteLn(f, WINDING_[i - 1].puTap, 0, 3); } + { Write(f, "~ %R="); WriteLn(f, (WINDING_[i - 1].Rpu * 100.0), 0, 2); } + WriteLn(f, Format("~ RdcOhms=%.7g", WINDING_[i - 1].RdcOhms)); + { Write(f, "~ rneut="); WriteLn(f, WINDING_[i - 1].Rneut, 0, 3); } + { Write(f, "~ xneut="); WriteLn(f, WINDING_[i - 1].Xneut, 0, 3); } + } + } + { Write(f, "~ "); Write(f, "XHL="); WriteLn(f, XHL * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "XHT="); WriteLn(f, XHT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "XLT="); WriteLn(f, XLT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X12="); WriteLn(f, XHL * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X13="); WriteLn(f, XHT * 100.0, 0, 3); } + { Write(f, "~ "); Write(f, "X23="); WriteLn(f, XLT * 100.0, 0, 3); } + Write(f, "~ Xscmatrix= \""); + for(stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + { Write(f, XSC[i - 1] * 100.0, 0, 2); Write(f, L' '); } + } + WriteLn(f, L'\"'); + { Write(f, "~ "); Write(f, "NormMAxHkVA="); WriteLn(f, NormMaxHkVA, 0, 0); } + { Write(f, "~ "); Write(f, "EmergMAxHkVA="); WriteLn(f, EmergMaxHkVA, 0, 0); } + { Write(f, "~ "); Write(f, "thermal="); WriteLn(f, ThermalTimeConst, 0, 1); } + { Write(f, "~ "); Write(f, "n="); WriteLn(f, n_thermal, 0, 1); } + { Write(f, "~ "); Write(f, "m="); WriteLn(f, m_thermal, 0, 1); } + { Write(f, "~ "); Write(f, "flrise="); WriteLn(f, FLrise, 0, 0); } + { Write(f, "~ "); Write(f, "hsrise="); WriteLn(f, HSrise, 0, 0); } + { Write(f, "~ "); Write(f, "%loadloss="); WriteLn(f, pctLoadLoss, 0, 0); } + { Write(f, "~ "); Write(f, "%noloadloss="); WriteLn(f, pctNoLoadLoss, 0, 0); } + for(stop = NumPropsThisClass, i = 28; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (ParentClass->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + /*# with ParentClass do */ + { + auto with1 = ParentClass; + int stop = 0; + for(stop = with1->NumProperties, i = NumPropsThisClass + 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with1->PropertyName)[i - 1]); Write(f, L'='); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + { + int stop = 0; + WriteLn(f); + ZBtemp = new TcMatrix(NumWindings - 1); + ZBtemp->CopyFrom(ZB); + ZBtemp->Invert(); + WriteLn(f, "ZB:"); + /*# with ZBtemp do */ + { + auto with2 = ZBtemp; + int stop = 0; + for(stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + Write(f, Format("%g ", with2->GetElement(i, j).re)); + } + WriteLn(f); + } + for(stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + Write(f, Format("%g ", with2->GetElement(i, j).im)); + } + WriteLn(f); + } + } /*WITH*/ + delete ZBtemp; + WriteLn(f); + WriteLn(f, "ZB: (inverted)"); + /*# with ZB do */ + { + auto with3 = ZB; + int stop = 0; + for(stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with3->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(stop = NumWindings - 1, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with3->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } /*WITH*/ + WriteLn(f); + WriteLn(f, "Y_OneVolt"); + /*# with Y_1Volt do */ + { + auto with4 = Y_1Volt; + int stop = 0; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with4->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with4->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } + WriteLn(f); + WriteLn(f, "Y_Terminal"); + /*# with Y_Term do */ + { + auto with5 = Y_Term; + int stop = 0; + for(stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with5->GetElement(i, j).re, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + for(stop = 2 * NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = i, j = 1; j <= stop1; j++) + { + { Write(f, with5->GetElement(i, j).im, 0, 4); Write(f, L' '); } + } + WriteLn(f); + } + } + WriteLn(f); + Write(f, "TermRef= "); + for(stop = 2 * NumWindings * Fnphases, i = 1; i <= stop; i++) + { + { + Write(f, to_string(TermRef[i - 1]), 0); + Write(f, L' '); + } + } + WriteLn(f); + } +} + +void TWinding::ComputeAntiFloatAdder(double PPM_Factor, double VABase1ph) +{ + Y_PPM = -PPM_Factor / (Sqr(VBase) / VABase1ph) / 2.0L; //12-11-12 divided by two + // put half on each terminal of the winding. +} +/* + Make a new winding +*/ + +TWinding::TWinding() + : Connection(0), + kVLL(12.47), + VBase(kVLL / SQRT3 * 1000.0), + kVA(1000.0), + puTap(1.0), + Rpu(0.002), + Rdcpu(Rpu * 0.85), + RdcOhms(Sqr(kVLL) / (kVA / 1000.0) * Rdcpu), + Rneut(-1.0), + Xneut(0.0), + Y_PPM(0.0), + RdcSpecified(false), + TapIncrement(0.0), + MinTap(0.0), + MaxTap(0.0), + NumTaps(0) +{ + ; + RdcSpecified = false; + ComputeAntiFloatAdder(1.0e-6, kVA / 3.0 / 1000.0); // 1 PPM + TapIncrement = 0.00625; + NumTaps = 32; + MaxTap = 1.10; + MinTap = 0.90; +} + +double TTransfObj::Get_PresentTap(int i, int ActorID) const +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].puTap; + else + result = 0.0; + return result; +} + +void TTransfObj::Set_PresentTap(int i, int ActorID, double Value) +{ + double TempVal = 0.0; + if((i > 0) && (i <= NumWindings)) + /*# with WINDING^[i] do */ + { + + /*Range Checking*/ + TempVal = Value; + if(TempVal < WINDING_[i - 1].MinTap) + TempVal = WINDING_[i - 1].MinTap; + else + { + if(TempVal > WINDING_[i - 1].MaxTap) + TempVal = WINDING_[i - 1].MaxTap; + } + if(TempVal != WINDING_[i - 1].puTap) /*Only if there's been a change*/ + { + WINDING_[i - 1].puTap = TempVal; + Set_YprimInvalid(ActorID,true); // this property triggers setting SystemYChanged=true + RecalcElementData(ActorID); + } + } +} + +double TTransfObj::Get_WdgResistance(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].Rpu; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_WdgRdc(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].RdcOhms; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_WdgkVA(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].kVA; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_WdgRneutral(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].Rneut; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_WdgXneutral(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].Xneut; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_WdgYPPM(int i) +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].Y_PPM; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_Xsc(int i) +{ + double result = 0.0; + int IMax = 0; + IMax = XSCSize(NumWindings); + if((i > 0) && (i <= IMax)) + result = XSC[i - 1]; + else + result = 0.0; + return result; +} + +int TTransfObj::Get_WdgConnection(int i) +{ + int result = 0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].Connection; + else + result = 0; + return result; +} + +double TTransfObj::Get_MinTap(int i) const +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].MinTap; + else + result = 0.0; + return result; +} + +double TTransfObj::Get_MaxTap(int i) const +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].MaxTap; + else + result = 0.0; + return result; +} + +int TTransfObj::Get_NumTaps(int i) +{ + int result = 0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].NumTaps; + else + result = 0; + return result; +} + +double TTransfObj::Get_TapIncrement(int i) const +{ + double result = 0.0; + if((i > 0) && (i <= NumWindings)) + result = WINDING_[i - 1].TapIncrement; + else + result = 0.0; + return result; +} + +/* + Return a vector of complex currents for each Winding of all phases + + Iterm = Yterm * Vterm + + Yterm order is 2*NumWindings. Each phase has same Yterm. + Vterm order is 2*NumWindings . + + Calculate Iterm phase-by-phase and concatenate into CurrBuffer. +*/ + +void TTransfObj::GetAllWindingCurrents(pComplexArray CurrBuffer, int ActorID) +{ + int j = 0; + int i = 0; + int jphase = 0; + int k = 0; + int iPhase = 0; + int iWind = 0; + int NeutTerm = 0; + pComplexArray VTerm; + pComplexArray iTerm; + pComplexArray ITerm_NL; + try + { + int stop = 0; + VTerm = new complex[ 2 * NumWindings]; + iTerm = new complex[2 * NumWindings]; + ITerm_NL = new complex[2 * NumWindings]; + + /*Load up Vterminal - already allocated for all cktelements*/ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + if(!(with0->NodeV.empty())) + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + } + else + { + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + Vterminal[i - 1] = CZero; + } + } + } + k = 0; + for(stop = Fnphases, iPhase = 1; iPhase <= stop; iPhase++) + { + int stop1 = 0; + for(stop1 = NumWindings, iWind = 1; iWind <= stop1; iWind++) + { + NeutTerm = iWind * Fnconds; + i = 2 * iWind - 1; + switch(WINDING_[iWind - 1].Connection) + { + case 0: // Wye + { + VTerm[i - 1] = Vterminal[iPhase + (iWind - 1) * Fnconds - 1]; + VTerm[i + 1 - 1] = Vterminal[NeutTerm - 1]; + } + break; // Delta + case 1: + { + jphase = RotatePhases(iPhase); // Get next phase in sequence + VTerm[i - 1] = Vterminal[iPhase + (iWind - 1) * Fnconds - 1]; + VTerm[i + 1 - 1] = Vterminal[jphase + (iWind - 1) * Fnconds - 1]; + } + break; + default: + ; + break; + } /*CASE*/ + } + Y_Term->MVmult(iTerm, VTerm); // ITerm = Y_Term Vterm + Y_Term_NL->MVmult(ITerm_NL, VTerm);// no load part + // Add into Currbuffer + for(stop1 = 2 * NumWindings, i = 1; i <= stop1; i++) + { + k = k + 1; + CurrBuffer[k - 1] = cadd((iTerm)[i - 1], (ITerm_NL)[i - 1]); + } + } + free(VTerm); + free(iTerm); + free(ITerm_NL); + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error filling voltage buffer in GetAllWindingCurrents for Circuit Element:Transformer.") + get_Name() + + CRLF + + "Probable Cause: Invalid definition of element." + + CRLF + + "System Error Message: " + + (std::string) e.what(), 100114); + } +} + +// Returns string mag, angle + +String TTransfObj::GetWindingCurrentsResult(int ActorID) +{ + String result; + pComplexArray WindingCurrents; + int i = 0; + int j = 0; + int k = 0; + int stop = 0; + WindingCurrents = new complex[2 * Fnphases * NumWindings]; + GetAllWindingCurrents(WindingCurrents, ActorID); + result = ""; + k = 0; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = NumWindings, j = 1; j <= stop1; j++) + { + k = k + 1; + result = result + + Format("%.7g, (%.5g), ", cabs((WindingCurrents)[k - 1]), cdang((WindingCurrents)[k - 1])); + k = k + 1; + // Skip currents from other end of the winding + } + } + free(WindingCurrents); // throw away temp array + return result; +} + +// Voltages across indicated winding +// Fill Vbuffer array which must be adequately allocated by calling routine +// Order is Number of Phases + +void TTransfObj::GetWindingVoltages(int iWind, pComplexArray VBuffer, int ActorID) +{ + int i = 0; + int II = 0; + int k = 0; + int l = 0; + int NeutTerm = 0; + try + + + /*return Zero if winding number improperly specified*/ + { + int stop = 0; + if((iWind < 1) || (iWind > NumWindings)) + { + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + VBuffer[i - 1] = CZero; + } + return; + } + + /*Load up VTerminal - already allocated for all cktelements*/ + /*# with ActiveCircuit[ActorID].Solution do */ + { + auto with0 = ActiveCircuit[ActorID]->Solution; + int stop = 0; + for(stop = Yorder, i = 1; i <= stop; i++) + { + if(!ADiakoptics || (ActorID == 1)) + Vterminal[i - 1] = with0->NodeV[NodeRef[i - 1]]; + else + Vterminal[i - 1] = with0->VoltInActor1(NodeRef[i - 1]); + } + } + k = (iWind - 1) * Fnconds; // Offset for winding + NeutTerm = Fnphases + k + 1; + for(stop = Fnphases, i = 1; i <= stop; i++) + { + switch(WINDING_[iWind - 1].Connection) + { + case 0: // Wye + { + VBuffer[i - 1] = csub(Vterminal[i + k - 1], Vterminal[NeutTerm - 1]); + } + break; // Delta + case 1: + { + II = RotatePhases(i); // Get next phase in sequence + VBuffer[i - 1] = csub(Vterminal[i + k - 1], Vterminal[II + k - 1]); + } + break; + default: + ; + break; + } + } /*CASE*/ + } + catch (std::exception &e) + { + DoSimpleMsg(String("Error filling voltage buffer in GetWindingVoltages for Circuit Element:Transformer.") + get_Name() + + CRLF + + "Probable Cause: Invalid definition of element." + + CRLF + + "System Error Message: " + + (std::string) e.what(), 114); + } +} + +double TTransfObj::Get_BaseVoltage(int i) +{ + double result = 0.0; + if((i < 1) || (i > NumWindings)) + result = WINDING_[1 - 1].VBase; + else + result = WINDING_[i - 1].VBase; + return result; +} + +/*============================== GetLosses Override ===============================*/ + +void TTransfObj::GetLosses(complex& TotalLosses, complex& LoadLosses, complex& NoLoadLosses, int ActorID) +{ + pComplexArray cTempIterminal; + int i = 0; + /*inherited;*/ + + /*Calculates losses in watts, vars*/ + int stop = 0; + TotalLosses = Get_Losses(ActorID); // Side effect: computes Iterminal + + /*Compute No load losses in Yprim_Shunt*/ + cTempIterminal = new complex[Yorder]; + ComputeVterminal(ActorID); + YPrim_Shunt->MVmult(cTempIterminal, &(Vterminal[0])); + /*No Load Losses are sum of all powers coming into YPrim_Shunt from each terminal*/ + NoLoadLosses = CZero; + for(stop = Yorder, i = 1; i <= stop; i++) + { + caccum(NoLoadLosses, cmul(Vterminal[i - 1], conjg((cTempIterminal)[i - 1]))); + } + LoadLosses = csub(TotalLosses, NoLoadLosses); + free(cTempIterminal); +} + +/* gets the property for the active winding ; Set the active winding before calling*/ + +String TTransfObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + int k = 0; + String TempStr; + switch(Index) + { + case 12: case 13: case 14: case 15: case 16: + case 20: + case 37: + result = "["; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 1: + result = IntToStr(Get_NPhases()); + break; + case 2: + result = IntToStr(NumWindings); + break; + case 3: + result = IntToStr(ActiveWinding); + break; // return active winding + case 4: + result = GetBus(ActiveWinding); + break; // return bus spec for active winding + case 5: + switch(WINDING_[ActiveWinding - 1].Connection) + { + case 0: + result = "wye "; + break; + case 1: + result = "Delta "; + break; + default: + ; + break; + } + break; + case 6: + result = Format("%.7g", WINDING_[ActiveWinding - 1].kVLL); + break; + case 7: + result = Format("%.7g", WINDING_[ActiveWinding - 1].kVA); + break; + case 8: + result = Format("%.7g", WINDING_[ActiveWinding - 1].puTap); + break; + case 9: + result = Format("%.7g", WINDING_[ActiveWinding - 1].Rpu * 100.0); + break; // %R + case 10: + result = Format("%.7g", WINDING_[ActiveWinding - 1].Rneut); + break; + case 11: + result = Format("%.7g", WINDING_[ActiveWinding - 1].Xneut); + break; + case 12: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + GetBus(i) + ", "; + } + break; + case 13: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + switch(WINDING_[i - 1].Connection) + { + case 0: + result = result + "wye, "; + break; + case 1: + result = result + "delta, "; + break; + default: + ; + break; + } + } + break; + case 14: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i - 1].kVLL); + } + break; + case 15: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i - 1].kVA); + } + break; + case 16: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i - 1].puTap); + } + break;// InterpretAllTaps(Param); + case 17: + result = Format("%.7g", XHL * 100.0); + break; + case 18: + result = Format("%.7g", XHT * 100.0); + break; + case 19: + result = Format("%.7g", XLT * 100.0); + break; + case 20: + for(int stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + result = result + Format("%-g, ", XSC[i - 1] * 100.0); + } + break;// Parser.ParseAsVector(((NumWindings - 1)*NumWindings div 2), Xsc); + case 26: + result = Format("%.7g", pctLoadLoss); + break; + case 27: + result = Format("%.7g", pctNoLoadLoss); + break; + case 28: + result = Format("%.7g", NormMaxHkVA); + break; + case 29: + result = Format("%.7g", EmergMaxHkVA); + break; + case 31: + result = Format("%.7g", WINDING_[ActiveWinding - 1].MaxTap); + break; + case 32: + result = Format("%.7g", WINDING_[ActiveWinding - 1].MinTap); + break; + case 33: + result = Format("%-d", WINDING_[ActiveWinding - 1].NumTaps); + break; + case 35: + result = Format("%.7g", pctImag); + break; + case 36: + result = Format("%.7g", ppm_FloatFactor / 1.0e-6); + break; + case 37: + for(int stop = NumWindings, i = 1; i <= stop; i++) + { + result = result + Format("%.7g, ", WINDING_[i - 1].Rpu * 100.0); + } + break; + case 40: + if(XRConst) + result = "YES"; + else + result = "NO"; + break; + case 41: + result = Format("%.7g", XHL * 100.0); + break; + case 42: + result = Format("%.7g", XHT * 100.0); + break; + case 43: + result = Format("%.7g", XLT * 100.0); + break; + case 45: + result = GetWindingCurrentsResult(ActiveActor); + break; + case 46: + switch(CoreType) + { + case 0: + result = "shell"; + break; + case 1: + result = "1-phase"; + break; + case 3: + result = "3-leg"; + break; + case 5: + result = "5-Leg"; + break; + default: + ; + break; + } + break; + case 47: + result = Format("%.7g", WINDING_[ActiveWinding - 1].RdcOhms); + break; + case 48: + result = IntToStr(NumAmpRatings); + break; + case 49: + { + int stop = 0; + TempStr = "["; + for(stop = NumAmpRatings, k = 1; k <= stop; k++) + { + TempStr = TempStr + FloatToStrF(kVARatings[k - 1], ffGeneral, 8, 4) + ","; + } + TempStr = TempStr + "]"; + result = TempStr; + } + break; + default: + result = inherited::GetPropertyValue(Index); + break; + } + + // Overrides + switch((Index - NumPropsThisClass)) + { + case 1: + result = Format("%-.5g", NormAmps); + break; //Normamps + case 2: + result = Format("%-.5g", EmergAmps); + break; //emergamps + default: + ; + break; + } + switch(Index) + { + case 12: case 13: case 14: case 15: case 16: + case 20: + case 37: + result = result + "]"; + break; + default: + ; + break; + } + return result; +} + +void TTransfObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,"3"); //'phases'; + Set_PropertyValue(2,"2"); //'windings'; + // Winding Definition + Set_PropertyValue(3,"1"); //'wdg'; + Set_PropertyValue(4,GetBus(1)); //'bus'; + Set_PropertyValue(5,"wye"); // 'conn'; + Set_PropertyValue(6,"12.47"); // IF 2or 3-phase: phase-phase ELSE actual winding + Set_PropertyValue(7,"1000"); + Set_PropertyValue(8,"1.0"); + Set_PropertyValue(9,"0.2"); + Set_PropertyValue(10,"-1"); + Set_PropertyValue(11,"0"); + + // General Data + Set_PropertyValue(12,""); + Set_PropertyValue(13,""); + Set_PropertyValue(14,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(15,""); // IF 1-phase: actual winding rating; ELSE phase-phase + Set_PropertyValue(16,""); + Set_PropertyValue(17,"7"); + Set_PropertyValue(18,"35"); + Set_PropertyValue(19,"30"); + Set_PropertyValue(20,""); // x12 13 14... 23 24.. 34 .. + Set_PropertyValue(21,"2"); + Set_PropertyValue(22,".8"); + Set_PropertyValue(23,".8"); + Set_PropertyValue(24,"65"); + Set_PropertyValue(25,"15"); + Set_PropertyValue(26,to_string(pctLoadLoss)); + Set_PropertyValue(27,to_string(pctNoLoadLoss)); // Defaults to zero + Set_PropertyValue(28,""); + Set_PropertyValue(29,""); + Set_PropertyValue(30,"n"); // =y/n + Set_PropertyValue(31,"1.10"); + Set_PropertyValue(32,"0.90"); + Set_PropertyValue(33,"32"); + Set_PropertyValue(34,""); + Set_PropertyValue(35,"0"); + Set_PropertyValue(36,"1"); + Set_PropertyValue(37,""); + Set_PropertyValue(38,""); + Set_PropertyValue(39,""); + Set_PropertyValue(40,"NO"); + Set_PropertyValue(41,"7"); // Same as XHT ... + Set_PropertyValue(42,"35"); + Set_PropertyValue(43,"30"); + Set_PropertyValue(44,"Lag"); + Set_PropertyValue(45,"0"); + Set_PropertyValue(46,"shell"); + Set_PropertyValue(47,"26.4"); // ohms + inherited::InitPropertyValues(NumPropsThisClass); + + // Override some Inherited properties + Set_PropertyValue(NumPropsThisClass + 1,"400"); //Normamps + Set_PropertyValue(NumPropsThisClass + 2,"600"); //emergamps + Set_PropertyValue(NumPropsThisClass + 3,"0.007"); //Fault rate + Set_PropertyValue(NumPropsThisClass + 4,"100"); // Pct Perm + Set_PropertyValue(NumPropsThisClass + 5,"36"); // Hrs to repair + ClearPropSeqArray(); // so the overrides don't show up on save +} +// For Delta connections or Line-Line voltages + +int TTransfObj::RotatePhases(int iPhs) +{ + int result = 0; + result = iPhs + DeltaDirection; + + // make sure result is within limits + if(Fnphases > 2) + // Assumes 2 phase delta is open delta + { + if(result > Fnphases) + result = 1; + if(result < 1) + result = Fnphases; + } + else + { + if(result < 1) + result = 3; // For 2-phase delta, next phase will be 3rd phase + } + return result; +} +/* + Converts default 3-phase transformer model into equivalent positive-sequence + using scripting +*/ + +void TTransfObj::MakePosSequence(int ActorID) +{ + String dummy; + int IW = 0; + int i = 0; + int n = 0; + String s; + int Nodes[50/*# range 1..50*/]; // big integer buffer + bool OnPhase1 = false; + + /*Get_First(), determine if we can convert this one.*/ + int stop = 0; + if((Fnphases == 1) || (Fnphases == 2)) //disable if any terminal not connected to phase one + { + int stop = 0; + for(stop = NumWindings, IW = 1; IW <= stop; IW++) + { + int stop1 = 0; + OnPhase1 = false; + /*Load up auxiliary parser*/ + AuxParser[ActiveActor]->SetCmdString(GetBus(IW)); + dummy = AuxParser[ActiveActor]->GetNextParam(); + s = AuxParser[ActiveActor]->ParseAsBusName(n, (pIntegerArray) &Nodes, ActorID); + if(n == 0) + OnPhase1 = true; + for(stop1 = n, i = 1; i <= stop1; i++) + { + if(Nodes[i - 1] == 1) + OnPhase1 = true; + } + if(!OnPhase1) + { + Set_Enabled(false); // We won't use this one + return; + } + } + } + + /*Construct transformer definition string */ + s = "Phases=1 Conns=("; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + s = s + "Wye "; + } + s = s + ") buses=("; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + s = s + GetBus(i) + " "; + } + s = s + ") kVS=("; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if((Get_NPhases() > 1) || (WINDING_[i - 1].Connection != 0)) + s = s + Format(" %-.5g", WINDING_[i - 1].kVLL / SQRT3); + else + s = s + Format(" %-.5g", WINDING_[i - 1].kVLL); + } + } + s = s + ") kVAs=("; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + s = s + Format(" %-.5g", WINDING_[i - 1].kVA / Fnphases); + } + } + s = s + ")"; + s = s + + " NormHkVA=" + + Format(" %-.5g %-.5g", NormMaxHkVA / Fnphases, EmergMaxHkVA / Fnphases); + Parser[ActorID]->SetCmdString(s); + Edit(ActorID); + inherited::MakePosSequence(ActorID); +} + +void TTransfObj::AddNeutralToY(double FreqMultiplier) +{ + int i = 0; + complex Value = {}; + int j = 0; + /*Account for neutral impedances*/ + /*# with YPrim_Series do */ + { + auto with0 = YPrim_Series; + int stop = 0; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + if(WINDING_[i - 1].Connection == 0) + // handle wye, but ignore delta (and open wye) + { + if(WINDING_[i - 1].Rneut >= 0) + // <0 is flag for open neutral (Ignore) + { + if((WINDING_[i - 1].Rneut == 0) && (WINDING_[i - 1].Xneut == 0)) + // Solidly Grounded + Value = cmplx(1000000, 0); + else + + // 1 microohm resistor + Value = cinv(cmplx(WINDING_[i - 1].Rneut, WINDING_[i - 1].Xneut * FreqMultiplier)); + j = i * Fnconds; + with0->AddElement(j, j, Value); + } + else + + // Bump up neutral admittance a bit in case neutral is floating + { + j = i * Fnconds; + if(ppm_FloatFactor != 0.0) + with0->SetElement(j, j, cadd(with0->GetElement(j, j), cmplx(0.0, WINDING_[i - 1].Y_PPM))); + /* SetElement(j, j, CmulReal_im(GetElement(j, j), ppm_FloatFactorPlusOne));*/ + } + } + } + } + } +} + +void TTransfObj::BuildYPrimComponent(TcMatrix* YPrim_Component, TcMatrix* Y_Terminal) +{ + int NW2 = 0; + int i = 0; + int k = 0; + complex Value = {}; + int j = 0; + /*# with YPrim_Component do */ + { + auto with0 = YPrim_Component; + /* Now, Put in Yprim matrix */ + /*have to add every element of Y_terminal into Yprim somewhere*/ + NW2 = 2 * NumWindings; + for(i = 1; i <= NW2; i++) + { + for(j = 1; j <= i; j++) + { + Value = Y_Terminal->GetElement(i, j); + // This value goes in Yprim nphases times + for (k = 0; k < Fnphases; k++) + { + with0->AddElemsym(TermRef[i + k * NW2 - 1], TermRef[j + k * NW2 - 1], Value); + } + } + } + } +} + +double TTransfObj::Get_BasekVLL(int i) +{ + double result = 0.0; + result = WINDING_[i - 1].kVLL; + return result; +} +// Build YTerminal considering on resistance and no coupling to other winding. + +void TTransfObj::GICBuildYTerminal() +{ + int i = 0; + int j = 0; + int Idx = 0; + complex Yr = {}; + TTextRec f = {}; + complex Yadder = {}; + int stop = 0; + Y_Term->Clear(); + Y_Term_NL->Clear(); + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*Use Rdc to build GIC model*/ + Yr = cmplx(1.0 / (WINDING_[i - 1].RdcOhms), 0.0); // convert to Siemens + /*# with Y_Term do */ + { + auto with0 = Y_Term; + Idx = 2 * i - 1; + with0->SetElement(Idx, Idx, Yr); + with0->SetElement(Idx + 1, Idx + 1, Yr); + with0->SetElemsym(Idx, Idx + 1, cnegate(Yr)); // set off-diagonals + } + } + + /*For GIC add a small *Conductance* to both conductors of each winding so that + the matrix will always invert even if the user neglects to define a voltage + reference on all sides*/ + if(ppm_FloatFactor != 0.0) + /*# with Y_Term do */ + { + auto with1 = Y_Term; + int stop = 0; + for(stop = NumWindings, i = 1; i <= stop; i++) + { + int stop1 = 0; + Yadder = cmplx(-WINDING_[i - 1].Y_PPM, 0.0); // G + j0 + for(stop1 = (2 * i), j = (2 * i - 1); j <= stop1; j++) + { + with1->SetElement(j, j, cadd(with1->GetElement(j, j), Yadder)); + } +/* SetElement(j, j, CmulReal_im(GetElement(j, j) , ppm_FloatFactorPlusOne));*/ + } + } +} + +void TTransfObj::CalcY_Terminal(double FreqMult) +{ + int i = 0; + int j = 0; + int k = 0; + vector A; + vector ctempArray1; + vector ctempArray2; + complex cMinusOne = CZero; + TcMatrix* At = nullptr; + complex Yadder = CZero; + double Rmult = 0.0; + /*Function to fix a specification of a pu tap of 0.0*/ + /*Regcontrol can attempt to force zero tap position in some models*/ + + auto ZeroTapFix = [&](double tapvalue) -> double + { + double result = 0.0; + if(tapvalue == 0.0) + result = 0.0001; + else + result = tapvalue; + return result; + }; + if(ActiveCircuit[ActiveActor]->Solution->get_FFrequency() < 0.51) + /*Build Yterminal for GIC ~dc simulation*/ + GICBuildYTerminal(); + else + /*Normal Y matrix build*/ + { + if(XRConst) + Rmult = FreqMult; + else + Rmult = 1.0; + + + // Construct ZBMatrix; + ZB->Clear(); + ZBase = 1.0 / (VABase / Fnphases); // base ohms on 1.0 volt basis + for(i = 1; i < NumWindings; i++) + { + /* convert pu to ohms on one volt base as we go... */ + ZB->SetElement(i, i, cmulreal(cmplx(Rmult * (WINDING_[1 - 1].Rpu + WINDING_[i + 1 - 1].Rpu), FreqMult * XSC[i - 1]), ZBase)); + } + + // Off diagonals + k = NumWindings; + /*# with ZB do */ + { + auto with0 = ZB; + for( i = 1; i < NumWindings; i++) + { + for(j = i + 1; j < NumWindings; j++) + { + with0->SetElemsym(i, j, cmulreal(csub(cadd(with0->GetElement(i, i), with0->GetElement(j, j)), cmulreal(cmplx(Rmult * (WINDING_[i + 1 - 1].Rpu + WINDING_[j + 1 - 1].Rpu), FreqMult * XSC[k - 1]), ZBase)), 0.5)); + ++k; + } + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + ZB->Invert(); // mhos on one volt base + if(ZB->InvertError > 0) + { + DoErrorMsg("TTransformerObj.CalcYPrim", String("Matrix Inversion Error for Transformer \"") + get_Name() + + "\"", "Invalid impedance specified. Replaced with tiny conductance to ground.", 117); + ZB->Clear(); + for(i = 1; i <= ZB->get_Norder(); i++) + { + ZB->SetElement(i, i, cmplx(EPSILON, 0.0)); + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + + // Now construct Y_Oneturn = AT * ZB.Invert * A + /* -1 1 0 ... + A = -1 0 1 .. order: N-1 x N N = NumWindings + ... + -1 -1 ... + AT = Transpose of A = 1 0 ... N X N-1 + 0 1 .. + */ + Y_1Volt->Clear(); + Y_1Volt_NL->Clear(); + + /*Allocate temp complex arrays*/ + ctempArray1.resize(NumWindings * 2); + ctempArray2.resize(NumWindings * 2); + A.resize(NumWindings * 2); + cMinusOne = cmplx(-1.0, 0.0); + At = new TcMatrix(NumWindings * 2); + for(i = 1; i < NumWindings; i++) + { + At->SetElement(i + 1, i, cONE); + } + for(i = 1; i < NumWindings; i++) + { + At->SetElement(1, i, cMinusOne); + } + (ctempArray1)[NumWindings - 1] = CZero; + for( i = 1; i <= NumWindings; i++) + { + if(i == 1) + { + for(k = 1; k < NumWindings; k++) + { + (A)[k - 1] = cMinusOne; + } + } + else + { + for(k = 1; k < NumWindings; k++) + { + if(k == (i - 1)) + (A)[k - 1] = cONE; + else + (A)[k - 1] = CZero; + } + } + ZB->MVmult(&ctempArray1[0], &A[0]); /*Zb.invert * A*/ + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for(j = 1; j <= NumWindings; j++) + { + Y_1Volt->SetElement(j, i, (ctempArray2)[j - 1]); + } + } + + /*Add magnetizing Reactance to 2nd winding, assuming it is closest to the core + Add both resistive element representing core losses and a reactive element representing + magnetizing current + */ + Y_1Volt_NL->AddElement(2, 2, cmplx((pctNoLoadLoss / 100.0 / ZBase), -pctImag / 100.0 / ZBase / FreqMult)); + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + // should have admittance of one phase of the transformer on a one-volt, wye-connected base + + // Now make into terminal admittance matrix and correct for actual voltage ratings + // Y_Terminal = AT * Y_onevolt * A where V_onevolt = A * V_terminal + delete At; + Y_Term->Clear(); + Y_Term_NL->Clear(); + At = new TcMatrix(NumWindings * 2); + + // 8/22/2013 Added ZeroTapFix so that regcontrol can set a tap to zero + for(i = 1; i <= NumWindings; i++) + { + /*# with WINDING^[i] do */ + { + + At->SetElement(2 * i - 1, i, cmplx(1.0 / (WINDING_[i - 1].VBase * ZeroTapFix(WINDING_[i - 1].puTap)), 0.0)); + } + } + for(i = 1; i <= NumWindings; i++) + { + /*# with WINDING^[i] do */ + { + + At->SetElement(2 * i, i, cmplx(-1.0 / (WINDING_[i - 1].VBase * ZeroTapFix(WINDING_[i - 1].puTap)), 0.0)); + } + } + for(i = 1; i <= (2 * NumWindings); i++) + { + (ctempArray1)[i - 1] = CZero; + } + for(i = 1; i <= (2 * NumWindings); i++) + { + for(k = 1; k <= NumWindings; k++) + { + /*# with WINDING^[k] do */ + { + + if(i == (2 * k - 1)) + (A)[k - 1] = cmplx((1.0 / (WINDING_[k - 1].VBase * ZeroTapFix(WINDING_[k - 1].puTap))), 0.0); + else + { + if(i == 2 * k) + (A)[k - 1] = cmplx((-1.0 / (WINDING_[k - 1].VBase * ZeroTapFix(WINDING_[k - 1].puTap))), 0.0); + else + (A)[k - 1] = CZero; + } + } + } + /*Main Transformer part*/ + Y_1Volt->MVmult(&ctempArray1[0], &A[0]); + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for(j = 1; j <= (2 * NumWindings); j++) + { + Y_Term->SetElement(j, i, (ctempArray2)[j - 1]); + } + /*No Load part*/ + Y_1Volt_NL->MVmult(&ctempArray1[0], &A[0]); + At->MVmult(&ctempArray2[0], &ctempArray1[0]); /*AT * Result*/ + for(j = 1; j <= (2 * NumWindings); j++) + { + Y_Term_NL->SetElement(j, i, (ctempArray2)[j - 1]); + } + } + + /*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + + /*Add a small Admittance to both conductors of each winding so that + the matrix will always invert even if the user neglects to define a voltage + reference on all sides*/ + if(ppm_FloatFactor != 0.0) + /*# with Y_Term do */ + { + auto with4 = Y_Term; + for(i = 1; i <= NumWindings; i++) + { + int stop1 = 0; + Yadder = cmplx(0.0, WINDING_[i - 1].Y_PPM); + for(j = (2 * i - 1); j <= (2 * i); j++) + { + with4->SetElement(j, j, cadd(with4->GetElement(j, j), Yadder)); + } +/* SetElement(j, j, CmulReal_im(GetElement(j, j) , ppm_FloatFactorPlusOne));*/ + } + } + +/*******************************DEBUG*******************************************************/ + /*******************************************************************************************/ + delete At; + A.clear(); + ctempArray1.clear(); + ctempArray2.clear(); + } + Y_Terminal_Freqmult = FreqMult; +} + +void TTransfObj::FetchXfmrCode(const String Code) +{ + TXfmrCodeObj* Obj = nullptr; + int i = 0; + if(XfmrCodeClass == nullptr) + XfmrCodeClass = (TXfmrCode*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("xfmrcode")); + if(XfmrCodeClass->SetActive(Code)) + { + int stop = 0; + Obj = ((TXfmrCodeObj*) XfmrCodeClass->GetActiveObj()); + XfmrCode = LowerCase(Code); + // set sizes and copy parameters + Set_NPhases(Obj->Fnphases); + SetNumWindings(Obj->NumWindings); + Set_Nconds(Fnphases + 1); // forces reallocation of terminals and conductors + for(stop = NumWindings, i = 1; i <= stop; i++) + { + /*# with WINDING^[i] do */ + { + + WINDING_[i - 1].Connection = Obj->WINDING_[i - 1].Connection; + WINDING_[i - 1].kVLL = Obj->WINDING_[i - 1].kVLL; + WINDING_[i - 1].VBase = Obj->WINDING_[i - 1].VBase; + WINDING_[i - 1].kVA = Obj->WINDING_[i - 1].kVA; + WINDING_[i - 1].puTap = Obj->WINDING_[i - 1].puTap; + WINDING_[i - 1].Rpu = Obj->WINDING_[i - 1].Rpu; + WINDING_[i - 1].RdcOhms = Obj->WINDING_[i - 1].RdcOhms; + WINDING_[i - 1].RdcSpecified = Obj->WINDING_[i - 1].RdcSpecified; + WINDING_[i - 1].Rneut = Obj->WINDING_[i - 1].Rneut; + WINDING_[i - 1].Xneut = Obj->WINDING_[i - 1].Xneut; + WINDING_[i - 1].TapIncrement = Obj->WINDING_[i - 1].TapIncrement; + WINDING_[i - 1].MinTap = Obj->WINDING_[i - 1].MinTap; + WINDING_[i - 1].MaxTap = Obj->WINDING_[i - 1].MaxTap; + WINDING_[i - 1].NumTaps = Obj->WINDING_[i - 1].NumTaps; + } + } + SetTermRef(); + + // Parameters for all windings + XHL = Obj->XHL; + XHT = Obj->XHT; + XLT = Obj->XLT; + for(stop = XSCSize(NumWindings), i = 1; i <= stop; i++) + { + XSC[i - 1] = Obj->XSC[i - 1]; + } + ThermalTimeConst = Obj->ThermalTimeConst; + n_thermal = Obj->n_thermal; + m_thermal = Obj->m_thermal; + FLrise = Obj->FLrise; + HSrise = Obj->HSrise; + pctLoadLoss = Obj->pctLoadLoss; + pctNoLoadLoss = Obj->pctNoLoadLoss; + pctImag = Obj->pctImag; // Omission corrected 12-14-18 + NormMaxHkVA = Obj->NormMaxHkVA; + EmergMaxHkVA = Obj->EmergMaxHkVA; + ppm_FloatFactor = Obj->ppm_FloatFactor; + Yorder = Fnconds * Fnterms; + Set_YprimInvalid(ActiveActor,true); + Y_Terminal_Freqmult = 0.0; + NumAmpRatings = Obj->NumAmpRatings; + kVARatings.resize( NumAmpRatings ); + for(i = 0; i < kVARatings.size(); i++) + { + kVARatings[i] = Obj->AmpRatings[i]; + } + RecalcElementData(ActiveActor); + } + else + DoSimpleMsg(String("Xfmr Code:") + Code + " not found.", 180); +} + + + + +} // namespace Transformer + + + + diff --git a/OpenDSSC/PDElements/Transformer.h b/OpenDSSC/PDElements/Transformer.h new file mode 100644 index 0000000..c252614 --- /dev/null +++ b/OpenDSSC/PDElements/Transformer.h @@ -0,0 +1,231 @@ +#ifndef TransformerH +#define TransformerH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + +#include "Command.h" +#include "DSSClass.h" +#include "PDClass.h" +#include "PDElement.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include "ParserDel.h" +#include "Arraydef.h" +#include + +#include "DSSClassDefs.h" + + + +namespace Transformer +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Change log + 1-28-00 Added tap properties so that regulator can control it. + 1-29-00 Added GetWindingVoltages + 2-1-00 Replaced TranParser with global AuxParser + 2-9-00 Fixed Set_PresentTap bug + 1-23-03 Added code to get 30 deg lag correct of y-delta transformers + 2-18-03 changed Rneut default to open (-1) + 2-21-03 changed automatic resetting of connection designator upon changing Rneut + 9-12-11 Fixed pctLoadLoss problem with sequence of definition with kVA property +*/ + +/* You can designate a transformer to be a substation by setting the sub=yes parameter*/ + +class TTransf : public TPDClass +{ + friend class TTransfObj; +public: + typedef PDClass::TPDClass inherited; +//private: + void SetActiveWinding(int W); + void InterpretConnection(const String s); + void InterpretAllConns(const String s); + void InterpretAllBuses(const String s); + void InterpretAllTaps(const String s); + void InterpretAllkVRatings(const String s); + void InterpretAllkVARatings(const String s); + void InterpretAllRs(const String s); + double TrapZero(double Value, double DefaultValue); + bool InterpretLeadLag(const String s); + + /*PROCEDURE MakeNewBusNameForNeutral(Var NewBusName:String; Nphases:Integer);*/ +protected: + void DefineProperties(); + virtual int MakeLike(const String TransfName); +public: + TTransf(); + virtual ~TTransf(); + virtual int Edit(int ActorID); // uses global parser + virtual int Init(int Handle, int ActorID); + virtual int NewObject(const String ObjName); +}; + +class TWinding +{ +public: + int Connection; // on transformer MVABase (1st winding) + // for GIC solutions; default to 85% of Rpu + double kVLL; + double VBase; + double kVA; + double puTap; + double Rpu; + double Rdcpu; + double RdcOhms; + double Rneut; + double Xneut; + double Y_PPM; // Anti Float reactance adder + bool RdcSpecified; + + /*Tap Changer Data*/ + double TapIncrement; + double MinTap; + double MaxTap; + int NumTaps; + void ComputeAntiFloatAdder(double PPM_Factor, double VABase1ph); + TWinding(); +}; + +class TTransfObj : public PDELement::TPDElement +{ + friend class TTransf; +public: + typedef PDELement::TPDElement inherited; +//private: + int DeltaDirection; + double ppm_FloatFactor; // parts per million winding float factor + double pctImag; + bool XRConst; + double Get_PresentTap(int i, int ActorID) const; + void Set_PresentTap(int i, int ActorID, double Value); + double Get_MinTap(int i) const; + double Get_MaxTap(int i) const; + double Get_TapIncrement(int i) const; + double Get_BaseVoltage(int i); + double Get_BasekVLL(int i); + // CIM accessors + int Get_NumTaps(int i); + double Get_WdgResistance(int i); + double Get_WdgRdc(int i); + int Get_WdgConnection(int i); + double Get_WdgkVA(int i); + double Get_Xsc(int i); + double Get_WdgRneutral(int i); + double Get_WdgXneutral(int i); + double Get_WdgYPPM(int i); + void CalcY_Terminal(double FreqMult); + void GICBuildYTerminal(); + void BuildYPrimComponent(Ucmatrix::TcMatrix* YPrim_Component, Ucmatrix::TcMatrix* Y_Terminal); + void AddNeutralToY(double FreqMultiplier); + void FetchXfmrCode(const String Code); +protected: + int NumWindings; + int MaxWindings; + std::vector TermRef; // keeps track of terminal connections + double XHL; + double XHT; + double XLT; // per unit + double ZBase; + std::vector XSC; // per unit SC measurements + double VABase; // FOR impedances + Ucmatrix::TcMatrix* ZB; + Ucmatrix::TcMatrix* Y_1Volt; + Ucmatrix::TcMatrix* Y_Term; + Ucmatrix::TcMatrix* Y_1Volt_NL; // No Load Y's + Ucmatrix::TcMatrix* Y_Term_NL; + double Y_Terminal_Freqmult; + double NormMaxHkVA; + double EmergMaxHkVA; + double ThermalTimeConst; /*hr*/ + double n_thermal; + double m_thermal; /*Exponents*/ + double FLrise; + double HSrise; + bool HVLeadsLV; + bool XHLChanged; + Arraydef::TRatingsArray kVARatings; + void SetTermRef(); +public: + double pctLoadLoss; + double pctNoLoadLoss; + int ActiveWinding; // public for COM interface + bool IsSubstation; + String SubstationName; + std::vector WINDING_; + String XfmrBank; + String XfmrCode; + int CoreType; /*0=Shell; 1=1ph; 3-3leg; 5=5-leg*/ + String strCoreType; + TTransfObj(DSSClass::TDSSClass* ParClass, const String TransfName); + virtual ~TTransfObj(); + void SetNumWindings(int n); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); + + /*GetLosses override for Transformer*/ + virtual void GetLosses(Ucomplex::complex& TotalLosses, Ucomplex::complex& LoadLosses, Ucomplex::complex& NoLoadLosses, int ActorID); + int RotatePhases(int iPhs); + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + virtual void SaveWrite(System::TTextRec& f); + void GetWindingVoltages(int iWind, Ucomplex::pComplexArray VBuffer, int ActorID); + void GetAllWindingCurrents(Ucomplex::pComplexArray CurrBuffer, int ActorID); // All Winding currents in complex array + String GetWindingCurrentsResult(int ActorID); // All winding currents in string + virtual void MakePosSequence(int ActorID); // Make a positive Sequence Model + + int get_NumWindings(); + double get_XHL(); + double get_XHT(); + double get_XLT(); + double get_NormMaxHkVA(); + double get_EmergMaxHkVA(); + double get_ThermalTimeConst(); + double get_n_thermal(); + double get_m_thermal(); + double get_FLrise(); + double get_HSrise(); + double get_pctLoadLoss(); + double get_pctNoLoadLoss(); + double get_pctImag(); + double get_ppm_FloatFactor(); + double get_VABase(); + + + // CIM accessors + TTransfObj(DSSClass::TDSSClass* ParClass); + TTransfObj(String ClassName); + TTransfObj(); +}; +extern TTransfObj* ActiveTransfObj; + +int XSCSize(int NumWindings); + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +} // namespace Transformer + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Transformer; +#endif + +#endif // TransformerH + + + + diff --git a/OpenDSSC/PDElements/fuse.cpp b/OpenDSSC/PDElements/fuse.cpp new file mode 100644 index 0000000..a33e212 --- /dev/null +++ b/OpenDSSC/PDElements/fuse.cpp @@ -0,0 +1,817 @@ + +#pragma hdrstop + +#include "fuse.h" + +#include "ParserDel.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "Ucmatrix.h" +#include "mathutil.h" +#include "Utilities.h" + +using namespace std; +using namespace Circuit; +using namespace CktElement; +using namespace Command; +using namespace ControlClass; +using namespace ControlElem; +using namespace DSSClass; +using namespace DSSClassDefs; +using namespace DSSGlobals; +using namespace DSSObject; +using namespace ParserDel; +using namespace System; +using namespace TCC_Curve; +using namespace Ucmatrix; +using namespace Ucomplex; +using namespace mathutil; +using namespace Utilities; + +namespace fuse +{ + +TFuseObj::TFuseObj(DSSClass::TDSSClass* ParClass) : inherited(ParClass->get_myClass_name()) {} +TFuseObj::TFuseObj(String ClassName) : inherited(ClassName) {} +TFuseObj::TFuseObj() {} + + +TFuseObj* ActiveFuseObj = nullptr; +TFuse* FuseClass = nullptr; +const int NumPropsThisClass = 10; +TDSSClass* TCC_CurveClass = nullptr; + +/*General Module Function*/ + +TTCC_CurveObj* GetTccCurve(const String CurveName) +{ + TTCC_CurveObj* result = nullptr; + result = ((TTCC_CurveObj*) TCC_CurveClass->Find(CurveName)); + if(result == nullptr) + DoSimpleMsg(String("TCC Curve object: \"") + CurveName + "\" not found.", 401); + return result; +} + + +/*--------------------------------------------------------------------------*/ // Creates superstructure for all Fuse objects + +TFuse::TFuse() +{ + ; + Class_Name = "Fuse"; + DSSClassType = DSSClassType + FUSE_CONTROL; + DefineProperties(); + std::string* slc = Slice((PropertyName), NumProperties); + CommandList = TCommandList(slc, NumProperties); + delete[] slc; + CommandList.set_AbbrevAllowed(true); + TCC_CurveClass = (TDSSClass*) GetDSSClassPtr("TCC_Curve"); + FuseClass = this; +} + +/*--------------------------------------------------------------------------*/ + +TFuse::~TFuse() +{ + // inherited::Destroy(); +} + + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +void TFuse::DefineProperties() +{ + NumProperties = NumPropsThisClass; + CountProperties(); // Get inherited property count + AllocatePropertyArrays(); + + + // Define Property names + PropertyName[1 - 1] = "MonitoredObj"; + PropertyName[2 - 1] = "MonitoredTerm"; + PropertyName[3 - 1] = "SwitchedObj"; + PropertyName[4 - 1] = "SwitchedTerm"; + PropertyName[5 - 1] = "FuseCurve"; + PropertyName[6 - 1] = "RatedCurrent"; + PropertyName[7 - 1] = "Delay"; + PropertyName[8 - 1] = "Action"; + PropertyName[9 - 1] = "Normal"; + PropertyName[10 - 1] = "State"; + PropertyHelp[1 - 1] = "Full object name of the circuit element, typically a line, transformer, load, or generator, " + "to which the Fuse is connected." + " This is the \"monitored\" element. " + "There is no default; must be specified."; + PropertyHelp[2 - 1] = "Number of the terminal of the circuit element to which the Fuse is connected. " + "1 or 2, typically. Default is 1."; + PropertyHelp[3 - 1] = "Name of circuit element switch that the Fuse controls. " + "Specify the full object name." + "Defaults to the same as the Monitored element. " + "This is the \"controlled\" element."; + PropertyHelp[4 - 1] = "Number of the terminal of the controlled element in which the switch is controlled by the Fuse. " + "1 or 2, typically. Default is 1. Assumes all phases of the element have a fuse of this type."; + PropertyHelp[5 - 1] = "Name of the TCC Curve object that determines the fuse blowing. Must have been previously defined as a TCC_Curve object." + " Default is \"Tlink\". " + "Multiplying the current values in the curve by the \"RatedCurrent\" value gives the actual current."; + PropertyHelp[6 - 1] = "Multiplier or actual phase amps for the phase TCC curve. Defaults to 1.0."; + PropertyHelp[7 - 1] = "Fixed delay time (sec) added to Fuse blowing time determined from the TCC curve. Default is 0.0. Used to represent fuse clearing time or any other delay."; + PropertyHelp[8 - 1] = "DEPRECATED. See \"State\" property."; + PropertyHelp[9 - 1] = "ARRAY of strings {Open | Closed} representing the Normal state of the fuse in each phase of the controlled element. " + "The fuse reverts to this state for reset, change of mode, etc. " + "Defaults to \"State\" if not specifically declared."; + PropertyHelp[10 - 1] = "ARRAY of strings {Open | Closed} representing the Actual state of the fuse in each phase of the controlled element. " + "Upon setting, immediately forces state of fuse(s). Simulates manual control on Fuse. Defaults to Closed for all phases."; + ActiveProperty = NumPropsThisClass - 1; + inherited::DefineProperties(); // Add defs of inherited properties to bottom of list +} + +/*--------------------------------------------------------------------------*/ + +int TFuse::NewObject(const String ObjName) +{ + int result = 0; + // Make a new Fuse and add it to Fuse class list + /*# with ActiveCircuit[ActiveActor] do */ + { + + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(new TFuseObj(this, ObjName)); + result = AddObjectToList(ActiveDSSObject[ActiveActor]); + } + return result; +} +/*--------------------------------------------------------------------------*/ + + +/*--------------------------------------------------------------------------*/ + +int TFuse::Edit(int ActorID) +{ + int result = 0; + int ParamPointer = 0; + String ParamName; + String Param; + int DevIndex = 0; + int i = 0; + + // continue parsing WITH contents of Parser + ActiveFuseObj = (TFuseObj*) ElementList.Get_Active(); + ActiveCircuit[ActorID]->Set_ActiveCktElement(ActiveFuseObj); + result = 0; + /*# with ActiveFuseObj do */ + { + auto with0 = ActiveFuseObj; + ParamPointer = 0; + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + while(Param.size() > 0) + { + if(ParamName.size() == 0) + ++ParamPointer; + else + ParamPointer = CommandList.Getcommand(ParamName); + if((ParamPointer > 0) && (ParamPointer <= NumProperties)) + ( (TDSSObject*) with0 )->Set_PropertyValue(ParamPointer,Param); + switch(ParamPointer) + { + case 0: + DoSimpleMsg(String("Unknown parameter \"") + ParamName + + "\" for Object \"" + + Class_Name + + "." + + ( (TDSSObject*) with0 )->get_Name() + + "\"", 402); + break; + case 1: + with0->MonitoredElementName = LowerCase(Param); + break; + case 2: + with0->MonitoredElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 3: + with0->ElementName = LowerCase(Param); + break; + case 4: + with0->ElementTerminal = Parser[ActorID]->MakeInteger_(); + break; + case 5: + with0->FuseCurve = GetTccCurve(Param); + break; + case 6: + with0->RatedCurrent = Parser[ActorID]->MakeDouble_(); + break; + case 7: + with0->DelayTime = Parser[ActorID]->MakeDouble_(); + break; + case 9: + { + with0->InterpretFuseState(ActorID, Param, ParamName); // set the normal state + if(!with0->NormalStateSet) + with0->NormalStateSet = true; + } + break; + case 8: case 10: + with0->InterpretFuseState(ActorID, Param, ParamName); + break; // set the present state + + // Inherited parameters + default: + ClassEdit(ActiveFuseObj, ParamPointer - NumPropsThisClass); + break; + } + + /*Supplemental Actions*/ + switch(ParamPointer) + { + case 1: + /*Default the controlled element to the monitored element*/ + with0->ElementName = with0->MonitoredElementName; + break; + case 2: + with0->ElementTerminal = with0->MonitoredElementTerminal; + break; + case 10: + { + int stop = 0; + for(stop = ( (TDSSCktElement*) with0 )->Fnphases, i = 1; i <= stop; i++) + { + if(!with0->NormalStateSet) + (*with0->FNormalState)[i - 1] = (*with0->FPresentState)[i - 1]; + } + with0->NormalStateSet = true; // normal state will default to state only the 1st state is specified. + } + break; + default: + ; + break; + } + ParamName = Parser[ActorID]->GetNextParam(); + Param = Parser[ActorID]->MakeString_(); + } + with0->RecalcElementData(ActorID); + } + return result; +} + + + +/*--------------------------------------------------------------------------*/ + +int TFuse::MakeLike(const String FuseName) +{ + int result = 0; + TFuseObj* OtherFuse = nullptr; + int i = 0; + result = 0; + /*See if we can find this Fuse name in the present collection*/ + OtherFuse = ((TFuseObj*) Find(FuseName)); + if(OtherFuse != nullptr) + /*# with ActiveFuseObj do */ + { + auto with0 = ActiveFuseObj; + int stop = 0; + ( (TDSSCktElement*) with0 )->Set_NPhases(( (TDSSCktElement*) OtherFuse )->Fnphases); + ( (TDSSCktElement*) with0 )->Set_Nconds(( (TDSSCktElement*) OtherFuse )->Fnconds); // Force Reallocation of terminal stuff + (with0)->ElementName = OtherFuse->ElementName; + (with0)->ElementTerminal = OtherFuse->ElementTerminal; + (with0)->Set_ControlledElement(OtherFuse->get_FControlledElement()); // Pointer to target circuit element + (with0)->MonitoredElement = OtherFuse->MonitoredElement; // Pointer to target circuit element + (with0)->MonitoredElementName = OtherFuse->MonitoredElementName; // Pointer to target circuit element + (with0)->MonitoredElementTerminal = OtherFuse->MonitoredElementTerminal; // Pointer to target circuit element + (with0)->FuseCurve = OtherFuse->FuseCurve; + (with0)->RatedCurrent = OtherFuse->RatedCurrent; + + // can't copy action handles + for(stop = min(FUSEMAXDIM, with0->get_FControlledElement()->Get_NPhases()), i = 1; i <= stop; i++) + { + (*with0->FPresentState)[i - 1] = (*OtherFuse->FPresentState)[i - 1]; + (*with0->FNormalState)[i - 1] = (*OtherFuse->FNormalState)[i - 1]; + } + with0->CondOffset = OtherFuse->CondOffset; + for(stop = ( (TDSSObject*) with0 )->ParentClass->NumProperties, i = 1; i <= stop; i++) + { + ( (TDSSObject*) with0 )->Set_PropertyValue(i,( (TDSSObject*) OtherFuse )->Get_PropertyValue(i)); + } + } + else + DoSimpleMsg(String("Error in Fuse MakeLike: \"") + FuseName + "\" Not Found.", 403); + return result; +} + + + + +/*==========================================================================*/ +/* TFuseObj */ +/*==========================================================================*/ + + + +/*--------------------------------------------------------------------------*/ + +TFuseObj::TFuseObj(TDSSClass* ParClass, const String FuseName) + : inherited(ParClass), + MonitoredElement(nullptr), + FPresentState(nullptr), + FNormalState(nullptr), + CondOffset(0), + cBuffer(nullptr), + NormalStateSet(false), + FuseCurve(nullptr), + RatedCurrent(0.0), + DelayTime(0.0), + MonitoredElementTerminal(0) +{ + int i = 0; + int stop = 0; + Set_Name(LowerCase(FuseName)); + DSSObjType = ParClass->DSSClassType; + Set_NPhases(3); // Directly set conds and phases + Fnconds = 3; + Set_NTerms(1); // this forces allocation of terminals and conductors + // in base class + ElementName = ""; + Set_ControlledElement(nullptr); + ElementTerminal = 1; + MonitoredElementName = ""; + MonitoredElementTerminal = 1; + FuseCurve = GetTccCurve("tlink"); + RatedCurrent = 1.0; + FPresentState = nullptr; + FNormalState = nullptr; + + // Reallocate arrays (Must be initialized to nil for first call) + FPresentState = (pStateArray) realloc(FPresentState, sizeof((*FPresentState)[1 - 1]) * Fnphases); + FNormalState = (pStateArray) realloc(FNormalState, sizeof((*FNormalState)[1 - 1]) * Fnphases); + for(stop = min(FUSEMAXDIM, Fnphases), i = 1; i <= stop; i++) + { + (*FPresentState)[i - 1] = CTRL_CLOSE; + (*FNormalState)[i - 1] = CTRL_CLOSE; // default to present state; + ReadyToBlow[i - 1] = false; + hAction[i - 1] = 0; + } + NormalStateSet = false; + cBuffer = nullptr; // Complex buffer + DSSObjType = ParClass->DSSClassType; //cap_CONTROL; + InitPropertyValues(0); + + // RecalcElementData; +} + +TFuseObj::~TFuseObj() +{ + MonitoredElementName = ""; + FPresentState = (pStateArray) realloc(FPresentState, 0); + FNormalState = (pStateArray) realloc(FNormalState, 0); + cBuffer = (pComplexArray) realloc(cBuffer, 0); + // inherited::Destroy(); +} + + +/*--------------------------------------------------------------------------*/ + +void TFuseObj::RecalcElementData(int ActorID) +{ + int DevIndex = 0; + int i = 0; + DevIndex = GetCktElementIndex(MonitoredElementName); // Global function + if(DevIndex > 0) + { + MonitoredElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex)); + Set_NPhases(MonitoredElement->Get_NPhases()); // Force number of phases to be same + if(Fnphases > FUSEMAXDIM) + DoSimpleMsg(String("Warning: Fuse ") + this->get_Name() + + ": Number of phases > Max fuse dimension.", 404); + if(MonitoredElementTerminal > MonitoredElement->Get_NTerms()) + { + DoErrorMsg(String("Fuse: \"") + get_Name() + "\"", "Terminal no. \"" "\" does not exist.", "Re-specify terminal no.", 404); + } + else + + // Sets name of i-th terminal's connected bus in Fuse's buslist + { + SetBus(1, MonitoredElement->GetBus(MonitoredElementTerminal)); + // Allocate a buffer bigenough to hold everything from the monitored element + cBuffer = (pComplexArray) realloc(cBuffer, sizeof((cBuffer)[1 - 1]) * MonitoredElement->Yorder); + CondOffset = (MonitoredElementTerminal - 1) * MonitoredElement->Get_NConds(); // for speedy sampling + } + } + +/*Check for existence of Controlled Element*/ + + // If previously assigned, reset HasOCPDevice flag in case this is a move + if(ASSIGNED(get_FControlledElement())) + get_FControlledElement()->HasOCPDevice = false; + DevIndex = GetCktElementIndex(ElementName); // Global function + if(DevIndex > 0) // Both CktElement and monitored element must already exist + { + int stop = 0; + Set_ControlledElement(((TDSSCktElement*) ActiveCircuit[ActorID]->CktElements.Get(DevIndex))); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Make the 1 st terminal active + if(Get_Enabled()) + get_FControlledElement()->HasOCPDevice = true; // For Reliability calcs + + // Open/Close State of controlled element based on state assigned to the control + for(stop = min(FUSEMAXDIM, get_FControlledElement()->Get_NPhases()), i = 1; i <= stop; i++) + { + if((*FPresentState)[i - 1] == CTRL_OPEN) + { + get_FControlledElement()->Set_ConductorClosed(i, ActorID, false); + } + else + { + get_FControlledElement()->Set_ConductorClosed(i, ActorID, true); + } + } + for(stop = get_FControlledElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + hAction[i - 1] = 0; + } + for(stop = min(FUSEMAXDIM, get_FControlledElement()->Get_NPhases()), i = 1; i <= stop; i++) + { + ReadyToBlow[i - 1] = false; + } + } + else + { + Set_ControlledElement(nullptr); // element not found + DoErrorMsg(String("Fuse: \"") + this->get_Name() + "\"", String("CktElement Element \"") + ElementName + "\" Not Found.", " Element must be defined previously.", 405); + } +} + +/*--------------------------------------------------------------------------*/ + +void TFuseObj::CalcYPrim(int ActorID) +{ + + // leave YPrims as nil and they will be ignored + // Yprim is zeroed when created. Leave it as is. + // IF YPrim=nil THEN YPrim := TcMatrix.CreateMatrix(Yorder); +} + +/*--------------------------------------------------------------------------*/ + +void TFuseObj::GetCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} +/*--------------------------------------------------------------------------*/ + +void TFuseObj::GetInjCurrents(pComplexArray Curr, int ActorID) +{ + int i = 0; + int stop = 0; + for(stop = Fnconds, i = 1; i <= stop; i++) + { + (Curr)[i - 1] = CZero; + } +} + +/*--------------------------------------------------------------------------*/ +// Do what we're instructed by the control queue +// Theoretically, there shouldn't be anything on the queue unless we have to do something +/*Only legal action is to open one phase*/ + +void TFuseObj::DoPendingAction(int Phs, int ProxyHdl, int ActorID) +{ + if(Phs <= FUSEMAXDIM) + /*# with ControlledElement do */ + { + auto with0 = get_FControlledElement(); + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal of CktElement to terminal 1 + switch((*FPresentState)[Phs - 1]) + { + case CTRL_CLOSE: + if(ReadyToBlow[Phs - 1]) // ignore if we became disarmed in meantime + { + get_FControlledElement()->Set_ConductorClosed(Phs, ActorID, false); // Open phases of active terminal + AppendToEventLog(String("Fuse.") + this->get_Name(), String("Phase ") + IntToStr(Phs) + " Blown", ActorID); + hAction[Phs - 1] = 0; + } + break; + /*Do Nothing */ + default: + ; + break; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TFuseObj::InterpretFuseState(int ActorID, const String Param, const String property_name) +{ + int i = 0; + String DataStr1; + String DataStr2; + if(LowerCase( property_name )[0] == 'a') // action (deprecated) Will be removed + { + int stop = 0; + for(stop = FUSEMAXDIM, i = 1; i <= stop; i++) + { + switch(LowerCase(Param)[0]) + { + case L'o': + set_States(i, CTRL_OPEN); + break; + case L'c': + set_States(i, CTRL_CLOSE); + break; + default: + ; + break; + } + } + } + else + { + AuxParser[ActorID]->SetCmdString(Param); // Load up Parser + DataStr1 = AuxParser[ActorID]->GetNextParam(); // ignore + DataStr2 = AuxParser[ActorID]->MakeString_(); + i = 1; + while((DataStr2.size() > 0) && (i < FUSEMAXDIM)) + { + if(LowerCase( property_name )[0] == 's') // state + { + switch(LowerCase(DataStr2)[0]) + { + case L'o': + set_States(i, CTRL_OPEN); + break; + case L'c': + set_States(i, CTRL_CLOSE); + break; + default: + ; + break; + } + } + else + // 'normal' + { + switch(LowerCase(DataStr2)[0]) + { + case L'o': + set_NormalStates(i, CTRL_OPEN); + break; + case L'c': + set_NormalStates(i, CTRL_CLOSE); + break; + default: + ; + break; + } + } + DataStr1 = AuxParser[ActorID]->GetNextParam(); // ignore + DataStr2 = AuxParser[ActorID]->MakeString_(); + ++i; + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TFuseObj::sample(int ActorID) +{ + int i = 0; + double cmag = 0.0; + double TripTime = 0.0; + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); + MonitoredElement->GetCurrents(cBuffer, ActorID); + /*# with MonitoredElement do */ + { + auto with0 = MonitoredElement; + int stop = 0; + for(stop = min(FUSEMAXDIM, MonitoredElement->Get_NPhases()), i = 1; i <= stop; i++) + { + if(get_FControlledElement()->Get_ConductorClosed(i, ActorID)) + (*FPresentState)[i - 1] = CTRL_CLOSE; + else + (*FPresentState)[i - 1] = CTRL_OPEN; + if((*FPresentState)[i - 1] == CTRL_CLOSE) + { + TripTime = -1.0; + + /*Check Phase Trip, if any*/ + if(FuseCurve != nullptr) + { + cmag = cabs((cBuffer)[i - 1]); + TripTime = FuseCurve->GetTCCTime(cmag / RatedCurrent); + } + if(TripTime > 0.0) + { + if(!ReadyToBlow[i - 1]) + /*# with ActiveCircuit[ActorID] do */ + { + // Then arm for an open operation + auto with0 = ActiveCircuit[ActorID]; + hAction[i - 1] = ActiveCircuit[ActorID]->ControlQueue.Push(with0->Solution->DynaVars.intHour, + with0->Solution->DynaVars.T + TripTime + DelayTime, (EControlAction) i, 0, this, ActorID); + ReadyToBlow[i - 1] = true; + } /*With*/ + } + else + { + if(ReadyToBlow[i - 1]) // Current has dropped below pickup and it hasn't blown yet + { + ActiveCircuit[ActorID]->ControlQueue.Delete(hAction[i - 1], ActorID); // Delete the fuse blow action + ReadyToBlow[i - 1] = false; + } + } + } /*IF PresentState=CLOSE*/ + } + } /*With*/ +} + +void TFuseObj::DumpProperties(TTextRec& f, bool Complete) +{ + int i = 0; + TDSSCktElement::DumpProperties(f, Complete); + /*# with ParentClass do */ + { + auto with0 = ParentClass; + int stop = 0; + for(stop = with0->NumProperties, i = 1; i <= stop; i++) + { + { Write(f, "~ "); Write(f, (with0->PropertyName)[i - 1]); Write(f, "="); WriteLn(f, Get_PropertyValue(i)); } + } + } + if(Complete) + WriteLn(f); +} + +String TFuseObj::GetPropertyValue(int Index) +{ + String result; + int i = 0; + switch(Index) + { + case 9: case 10: + result = "["; + break; + default: + result = ""; + break; + } + switch(Index) + { + case 10: + if(get_FControlledElement() != nullptr) // Special cases + { + int stop = 0; + for(stop = get_FControlledElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + switch((*FPresentState)[i - 1]) + { + case CTRL_OPEN: + result = result + "open" + ", "; + break; + /*CTRL_CLOSE:*/ + default: + result = result + "closed" + ", "; + break; + } + } + } + break; + case 9: + if(get_FControlledElement() != nullptr) + { + int stop = 0; + for(stop = get_FControlledElement()->Get_NPhases(), i = 1; i <= stop; i++) + { + switch((*FNormalState)[i - 1]) + { + case CTRL_OPEN: + result = result + "open" + ", "; + break; + /*CTRL_CLOSE:*/ + default: + result = result + "closed" + ", "; + break; + } + } + } + break; + default: + result = TDSSCktElement::GetPropertyValue(Index); + break; + } + switch(Index) + { + case 9: case 10: + result = result + "]"; + break; + default: + ; + break; + } + return result; +} + +void TFuseObj::Reset(int ActorID) +{ + int i = 0; + if(get_FControlledElement() != nullptr) + { + int stop = 0; + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + for(stop = min(FUSEMAXDIM, get_FControlledElement()->Get_NPhases()), i = 1; i <= stop; i++) + { + (*FPresentState)[i - 1] = (*FNormalState)[i - 1]; // reset to normal state + ReadyToBlow[i - 1] = false; + hAction[i - 1] = 0; + switch((*FNormalState)[i - 1]) + { + case CTRL_OPEN: + get_FControlledElement()->Set_ConductorClosed(i, ActiveActor, false); + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(i, ActiveActor, true); + break; + } + } + } +} + +EControlAction TFuseObj::get_States(int Idx) +{ + EControlAction result; + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + if(get_FControlledElement()->Get_ConductorClosed(Idx, ActiveActor)) + { + /*TRUE:*/ + (*FPresentState)[Idx - 1] = CTRL_CLOSE; + } else { + /* FALSE */ + (*FPresentState)[Idx - 1] = CTRL_OPEN; + } + } + result = (*FPresentState)[Idx - 1]; + return result; +} + +void TFuseObj::set_States(int Idx, const EControlAction Value) +{ + if(get_States(Idx) != Value) + { + if(get_FControlledElement() != nullptr) + { + get_FControlledElement()->Set_ActiveTerminal(ElementTerminal); // Set active terminal + switch(Value) + { + case CTRL_OPEN: + get_FControlledElement()->Set_ConductorClosed(Idx, ActiveActor, false); + break; + /*CTRL_CLOSE:*/ + default: + get_FControlledElement()->Set_ConductorClosed(Idx, ActiveActor, true); + break; + } + } + (*FPresentState)[Idx - 1] = Value; + } +} + +EControlAction TFuseObj::get_NormalStates(int Idx) +{ + EControlAction result; + result = (*FNormalState)[Idx - 1]; + return result; +} + +void TFuseObj::set_NormalStates(int Idx, const EControlAction Value) +{ + if((*FNormalState)[Idx - 1] != Value) + { + (*FNormalState)[Idx - 1] = Value; + } +} + +void TFuseObj::InitPropertyValues(int ArrayOffset) +{ + Set_PropertyValue(1,""); //'element'; + Set_PropertyValue(2,"1"); //'terminal'; + Set_PropertyValue(3,""); + Set_PropertyValue(4,"1"); //'terminal'; + Set_PropertyValue(5,"Tlink"); + Set_PropertyValue(6,"1.0"); + Set_PropertyValue(7,"0"); + Set_PropertyValue(8,""); // action + Set_PropertyValue(9,"[close, close, close]"); // normal + Set_PropertyValue(10,"[close,close,close]"); // state + TDSSCktElement::InitPropertyValues(NumPropsThisClass); +} + + + + +} // namespace fuse + diff --git a/OpenDSSC/PDElements/fuse.h b/OpenDSSC/PDElements/fuse.h new file mode 100644 index 0000000..b938f6b --- /dev/null +++ b/OpenDSSC/PDElements/fuse.h @@ -0,0 +1,126 @@ +#ifndef fuseH +#define fuseH + +#include "System.h" +#include "Sysutils.h" + +#include "Command.h" +#include "ControlClass.h" +#include "ControlElem.h" +#include "ControlActionsDefs.h" +#include "CktElement.h" +#include "DSSClass.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "TCC_Curve.h" +#include +#include "d2c_structures.h" + + + +namespace fuse +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Created 11-1-00 from Recloser Control +*/ +/* + A Fuse is a control element that is connected to a terminal of a + circuit element and controls the switches in the same or another terminal. + + The control is usually placed in the + terminal of a line or transformer, but it could be any element + + CktElement to be controlled must already exist. + +*/ +const int FUSEMAXDIM = 6; +typedef EControlAction StateArray[6/*# range 1..FUSEMAXDIM*/]; +typedef StateArray* pStateArray; // 0 = open 1 = close + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TFuse : public ControlClass::TControlClass +{ + friend class TFuseObj; +public: + typedef ControlClass::TControlClass inherited; +private: +protected: + void DefineProperties(); + virtual int MakeLike(const String FuseName); +public: + TFuse(); + virtual ~TFuse(); + virtual int Edit(int ActorID); // uses global parser + virtual int NewObject(const String ObjName); +}; + +// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + +class TFuseObj : public ControlElem::TControlElem +{ + friend class TFuse; +public: + typedef ControlElem::TControlElem inherited; +//private: + CktElement::TDSSCktElement* MonitoredElement; + int hAction[6/*# range 1..FUSEMAXDIM*/]; // handle to control queue actions + pStateArray FPresentState; + pStateArray FNormalState; + bool ReadyToBlow[6/*# range 1..FUSEMAXDIM*/]; + int CondOffset; // Offset for monitored terminal + Ucomplex::pComplexArray cBuffer; // Complexarray buffer + bool NormalStateSet; + void InterpretFuseState(int ActorID, const String Param, const String property_name); + EControlAction get_States(int Idx); + void set_States(int Idx, const EControlAction Value); + EControlAction get_NormalStates(int Idx); + void set_NormalStates(int Idx, const EControlAction Value); +public: + TCC_Curve::TTCC_CurveObj* FuseCurve; + double RatedCurrent; + double DelayTime; + String MonitoredElementName; + int MonitoredElementTerminal; + TFuseObj(DSSClass::TDSSClass* ParClass, const String FuseName); + virtual ~TFuseObj(); + virtual void RecalcElementData(int ActorID); + virtual void CalcYPrim(int ActorID); // Always Zero for a Fuse + virtual void sample(int ActorID); // Sample control quantities and set action times in Control Queue + virtual void DoPendingAction(int Phs, int ProxyHdl, int ActorID); // Do the action that is pending from last sample + virtual void Reset(int ActorID); // Reset to initial defined state + virtual void GetCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Get present value of terminal Curr + virtual void GetInjCurrents(Ucomplex::pComplexArray Curr, int ActorID); // Returns Injextion currents + virtual String GetPropertyValue(int Index); + virtual void InitPropertyValues(int ArrayOffset); + virtual void DumpProperties(System::TTextRec& f, bool Complete); + TFuseObj(DSSClass::TDSSClass* ParClass); + TFuseObj(String ClassName); + TFuseObj(); +}; +extern TFuseObj* ActiveFuseObj; +extern TFuse* FuseClass; + +/*--------------------------------------------------------------------------*/ + + +} // namespace fuse + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace fuse; +#endif + +#endif // fuseH + + + + diff --git a/OpenDSSC/Parser/Frm_RPNcalc.cpp b/OpenDSSC/Parser/Frm_RPNcalc.cpp new file mode 100644 index 0000000..f441e71 --- /dev/null +++ b/OpenDSSC/Parser/Frm_RPNcalc.cpp @@ -0,0 +1,57 @@ +#include +#pragma hdrstop + +#include "Frm_RPNcalc.h" +#include "../Parser/ParserDel.h" + +using namespace std; +using namespace d2c_system; +using namespace ParserDel; +using namespace System; +using namespace System::Classes; +using namespace System::Sysutils; +using namespace System::Uitypes; +using namespace Vcl::Forms; + + +TRPNForm::TRPNForm(System::Classes::TComponent* AOwner) : inherited(AOwner) {} + + +TRPNForm* RPNForm = nullptr; +#pragma resource "*.DFM" + +TParser* Parser = nullptr; + +void TRPNForm::FormCreate(TObject* Sender) +{ + if (Parser != nullptr) + delete Parser; + Parser = new TParser(); +} + +void TRPNForm::Button1Click(TObject* Sender) +{ + Parser->CmdString = String(L"[") + ParserIn->Text + L"]"; + Parser->NextParam; + Answer = Parser->DblValue; + ParserOut->Text = Format(L"%10.5g", ARRAYOFCONST((Answer))); +} + +void TRPNForm::OK_ButtonClick(TObject* Sender) +{ + ParserOut->SelectAll(); + ParserOut->CopyToClipboard(); + Cancelled = false; + ModalResult = (TModalResult) mrOk; +} + +void TRPNForm::Cancel_ButtonClick(TObject* Sender) +{ + Cancelled = true; + ModalResult = (TModalResult) mrCancel; +} + + + + + diff --git a/OpenDSSC/Parser/Frm_RPNcalc.h b/OpenDSSC/Parser/Frm_RPNcalc.h new file mode 100644 index 0000000..5967a87 --- /dev/null +++ b/OpenDSSC/Parser/Frm_RPNcalc.h @@ -0,0 +1,70 @@ +#ifndef Frm_RPNcalcH +#define Frm_RPNcalcH + +#include +#include "../Support/d2c_system.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2015, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TRPNForm : public TForm +{ +__published: + TLabel* Label1; + TEdit* ParserIn; + TButton* Button1; + TLabel* Label2; + TEdit* ParserOut; + TButton* Cancel_Button; + TLabel* Label3; + TButton* OK_Button; + TLabel* Label10; + TLabel* Label11; + TLabel* Label12; + TLabel* Label5; + TLabel* Label16; + TLabel* Label8; + TGroupBox* GroupBox1; + TLabel* Label4; + TLabel* Label9; + TLabel* Label13; + TLabel* Label14; + TLabel* Label15; + TLabel* Label6; + TLabel* Label17; + TLabel* Label18; + void FormCreate(TObject* Sender); + void Button1Click(TObject* Sender); + void OK_ButtonClick(TObject* Sender); + void Cancel_ButtonClick(TObject* Sender); +private: + /* Private declarations */ +public: + /* Public declarations */ + double Answer; + bool Cancelled; + typedef TForm inherited; + TRPNForm(System::Classes::TComponent* AOwner); +}; +extern PACKAGE TRPNForm* RPNForm; +#endif // Frm_RPNcalcH + + + + diff --git a/OpenDSSC/Parser/ParserDel.cpp b/OpenDSSC/Parser/ParserDel.cpp new file mode 100644 index 0000000..055d90a --- /dev/null +++ b/OpenDSSC/Parser/ParserDel.cpp @@ -0,0 +1,1017 @@ + + +#pragma hdrstop + +#include "ParserDel.h" + +#include "CmdForms.h" + +using namespace std; + +namespace ParserDel +{ + + TParserVar::TParserVar() {} + + TParserVar* ParserVars; + //ParserVars = nullptr; + const WideChar Commentchar = L'!'; + const WideChar VariableDelimiter = L'@'; // first character of a variable + + EParserProblem::EParserProblem(const String &Msg) : inherited(Msg) {} + + /*=======================================================================================================================*/ + + int ProcessRPNCommand(const String TokenBuffer, TRPNCalc* RPN) + { + int result = 0; + String s; + double Number = 0.0; + result = 0; // Error Code on conversion error + + + /*Get_First() Try to make a valid number. If that fails, check for RPN command*/ + val(TokenBuffer, &Number, &result); + if (result == 0) // Enters number in X register + RPN->Set_X(Number); + else + /*Check for RPN command. */ + { + result = 0; // reset error return + s = LowerCase(TokenBuffer); + /*# with RPN do */ + { + auto with0 = RPN; + if (CompareStr(s, "+") == 0) + with0->Add(); + else + { + if (CompareStr(s, "-") == 0) with0->Subtract(); + else if (CompareStr(s, "*") == 0) with0->Multiply(); + else if (CompareStr(s, "/") == 0) with0->Divide(); + else if (CompareStr(s, "sqrt") == 0) with0->Sqrt(); + else if (CompareStr(s, "sqr") == 0) with0->Square(); + else if (CompareStr(s, "^") == 0) with0->YToTheXPower(); + else if (CompareStr(s, "sin") == 0) with0->Sindeg(); + else if (CompareStr(s, "cos") == 0) with0->Cosdeg(); + else if (CompareStr(s, "tan") == 0) with0->Tandeg(); + else if (CompareStr(s, "asin") == 0) with0->aSindeg(); + else if (CompareStr(s, "acos") == 0) with0->aCosdeg(); + else if (CompareStr(s, "atan") == 0) with0->aTandeg(); + else if (CompareStr(s, "atan2") == 0) with0->aTan2deg(); + else if (CompareStr(s, "swap") == 0) with0->SwapXY(); + else if (CompareStr(s, "rollup") == 0) with0->RollUp(); + else if (CompareStr(s, "rolldn") == 0) with0->RollDn(); + else if (CompareStr(s, "ln") == 0) with0->NatLog(); + else if (CompareStr(s, "pi") == 0) with0->EnterPi(); + else if (CompareStr(s, "log10") == 0) with0->TenLog(); + else if (CompareStr(s, "exp") == 0) with0->etothex(); + else if (CompareStr(s, "inv") == 0) with0->Inv(); + else result = 1; // error + //throw EParserProblem("Invalid inline math entry: \"" + TokenBuffer + "\""); + } + + } + } + return result; + } + + string TParser::get_CmdBuffer() + { + return CmdBuffer; + } + + /*=======================================================================================================================*/ + + String StriptoDotPos(int dotpos, String& s) + { + String result; + if (dotpos == 0) + result = s; + result = s.substr(0, dotpos - 1); + return result; + } + + /*Strips off everything up to a period.*/ + + /*=======================================================================================================================*/ + + void TParser::CheckforVar(String& TokenBuffer) + { + String VariableValue; + String VariableName; + size_t dotpos = 0; + size_t CaratPos = 0; + + /*-------------------------------------*/ + + auto ReplaceToDotPos = [&](const String s) -> void + { + if (dotpos != String::npos) + TokenBuffer = s + TokenBuffer.substr(dotpos, TokenBuffer.length() - dotpos + 1); + else + TokenBuffer = s; + }; + /*-------------------------------------*/ + + /*Replace TokenBuffer with Variable value if first character is VariableDelimiter character*/ + if (TokenBuffer.length() > 1) + { + if (TokenBuffer[0] == VariableDelimiter) // looking for '@' + { + dotpos = TokenBuffer.find("."); + CaratPos = TokenBuffer.find("^"); + if (CaratPos != String::npos) + dotpos = CaratPos; // Carat takes precedence + if (dotpos != String::npos) + VariableName = StriptoDotPos(dotpos, TokenBuffer); + else + VariableName = TokenBuffer; + if (ParserVars->Lookup(VariableName) > 0) + { + VariableValue = ParserVars->Get_Value(); // Retrieve the value of the variable + if (VariableValue[0] == L'{') + { + ReplaceToDotPos(VariableValue.substr(1, VariableValue.length() - 2)); // get rid of closed brace added by parservar + IsQuotedString = true; // force RPN parser to handle + } + else + ReplaceToDotPos(VariableValue); + } + } + } + } + + /*=======================================================================================================================*/ + + TParser::TParser() + : FPosition(0), + LastDelimiter(L'\0'), + MatrixRowTerminator(L'\0'), + FAutoIncrement(false), + ConvertError(false), + IsQuotedString(false) + { + ; + DelimChars = ",="; + WhiteSpaceChars = " \t"; // blank + tab + FBeginQuoteChars = "(\"'[{"; + FEndQuoteChars = ")\"']}"; + FPosition = 0; + MatrixRowTerminator = '|'; + FAutoIncrement = false; + } + + /*=======================================================================================================================*/ + + TParser::~TParser() + { + // inherited::Destroy(); + } + + + /*=======================================================================================================================*/ + + void TParser::SetCmdString(const String Value) + { + CmdBuffer.clear(); + CmdBuffer = Value + " "; // add some white space at end to get last param + FPosition = 0; + SkipWhitespace(CmdBuffer, &FPosition); // position at first non whitespace character + } + + /*=======================================================================================================================*/ + + void TParser::ResetDelims() + { + DelimChars = ",="; + WhiteSpaceChars = " \t"; + MatrixRowTerminator = '|'; + FBeginQuoteChars = "(\"'[{"; + FEndQuoteChars = ")\"']}"; + } + + /*=======================================================================================================================*/ + + bool TParser::IsWhiteSpace(Char ch) + { + bool result = false; + int i = 0; + int stop = 0; + result = false; + for (stop = (int)WhiteSpaceChars.length(), i = 1; i <= stop; i++) + { + if (ch == WhiteSpaceChars[i - 1]) + { + result = true; + return result; + } + } + return result; + } + + + /*=======================================================================================================================*/ + + bool TParser::IsDelimiter(const String LineBuffer, int& LinePos) + { + bool result = false; + int i = 0; + Char ch = L'\0'; + int stop = 0; + result = false; + if (IsCommentChar(LineBuffer, LinePos)) + { + result = true; + LastDelimiter = Commentchar; + return result; + } + ch = LineBuffer[LinePos]; + for (stop = (int)DelimChars.length(), i = 1; i <= stop; i++) + { + if (ch == DelimChars[i - 1]) + { + result = true; + LastDelimiter = ch; + return result; + } + } + for (stop = (int)WhiteSpaceChars.length(), i = 1; i <= stop; i++) + { + if (ch == WhiteSpaceChars[i - 1]) + { + result = true; + LastDelimiter = L' '; // to indicate stopped on white space + return result; + } + } + return result; + } + + + /*=======================================================================================================================*/ + + bool TParser::IsDelimChar(Char ch) + { + bool result = false; + int i = 0; + int stop = 0; + result = false; + for (stop = (int)DelimChars.length(), i = 1; i <= stop; i++) + { + if (ch == DelimChars[i - 1]) + { + result = true; + return result; + } + } + return result; + } + + /*=======================================================================================================================*/ + + int TParser::get_position() + { + return FPosition; + } + + /*=======================================================================================================================*/ + + void TParser::set_position(int myPos) + { + FPosition = myPos; + } + + /*=======================================================================================================================*/ + + std::string TParser::get_delimchars() + { + return DelimChars; + } + + /*=======================================================================================================================*/ + + void TParser::set_delimchars(std::string S) + { + DelimChars = S; + } + + /*=======================================================================================================================*/ + + std::string TParser::get_WhiteSpaceChars() + { + return WhiteSpaceChars; + } + + /*=======================================================================================================================*/ + + void TParser::set_WhiteSpaceChars(std::string S) + { + WhiteSpaceChars = S; + } + + /*=======================================================================================================================*/ + + std::string TParser::get_FBeginQuoteChars() + { + return FBeginQuoteChars; + } + + /*=======================================================================================================================*/ + + void TParser::set_FBeginQuoteChars(std::string S) + { + FBeginQuoteChars = S; + } + + /*=======================================================================================================================*/ + + std::string TParser::get_FEndQuoteChars() + { + return FEndQuoteChars; + } + + /*=======================================================================================================================*/ + + void TParser::set_FEndQuoteChars(std::string S) + { + FEndQuoteChars = S; + } + + /*=======================================================================================================================*/ + + bool TParser::get_FAutoIncrement() + { + return FAutoIncrement; + } + + /*=======================================================================================================================*/ + + void TParser::set_FAutoIncrement(bool S) + { + FAutoIncrement = S; + } + + /*=======================================================================================================================*/ + + void TParser::SkipWhitespace(const String LineBuffer, int * LinePos) + { + while ((*LinePos < LineBuffer.length()) && IsWhiteSpace(LineBuffer[*LinePos])) + *LinePos = *LinePos + 1; + } + + /*=======================================================================================================================*/ + + String TParser::GetToken(const String LineBuffer, int* LinePos) + { + String result; + int TokenStart = 0; + int CmdBufLength = 0; + int QuoteIndex = 0; // value of quote character found + + + /*---------------- Local Function -----------------------*/ + + auto ParseToEndChar = [&](Char Endchar) -> void + { + *LinePos = *LinePos + 1; + TokenStart = *LinePos; + while ((*LinePos < CmdBufLength) && (LineBuffer[*LinePos] != Endchar)) + *LinePos = *LinePos + 1; + result = LineBuffer.substr(TokenStart, *LinePos - TokenStart); + if (*LinePos < CmdBufLength) + *LinePos = *LinePos + 1; // Increment past endchar + }; + + /*---------------- Local Function -----------------------*/ + + auto ParseToEndQuote = [&]() -> void + { + ParseToEndChar(FEndQuoteChars[QuoteIndex - 1]); + IsQuotedString = true; + }; + + /*---------------- Local Function -----------------------*/ + + auto IsBeginQuote = [&](Char ch) -> bool + { + bool result = false; + QuoteIndex = Pos(ch, FBeginQuoteChars); + if (QuoteIndex > 0) + result = true; + else + result = false; + return result; + }; + result = ""; // if it doesn't find anything, return null string + CmdBufLength = (int)LineBuffer.length(); + if (*LinePos <= CmdBufLength) + + /*Handle Quotes and Parentheses around tokens*/ + { + IsQuotedString = false; + if (IsBeginQuote(LineBuffer[*LinePos])) + ParseToEndQuote(); + else + /* Copy to next delimiter or whitespace*/ + { + TokenStart = *LinePos; + while ((*LinePos < CmdBufLength) && !IsDelimiter(LineBuffer, *LinePos)) + *LinePos = *LinePos + 1; + + result = LineBuffer.substr(TokenStart, (*LinePos - TokenStart)); + } + + + /* Check for stop on comment */ + + // if stop on comment, ignore rest of line. + if (LastDelimiter == Commentchar) + *LinePos = (LineBuffer.length() + 1); + else + + + /*Get Rid of Trailing White Space*/ + { + if (LastDelimiter == L' ') + SkipWhitespace(LineBuffer, LinePos); + if (IsDelimChar(LineBuffer[*LinePos])) + { + LastDelimiter = LineBuffer[*LinePos]; + *LinePos = *LinePos + 1; // Move past terminating delimiter + } + SkipWhitespace(LineBuffer, LinePos); + } + } + return result; + } + + + /*=======================================================================================================================*/ + + String TParser::GetNextParam() + { + String result; + if (FPosition <= CmdBuffer.length()) + { + LastDelimiter = L' '; + TokenBuffer = GetToken(CmdBuffer, &FPosition); // Get entire token and put in token Buffer + if (LastDelimiter == L'=') + { + ParameterBuffer = TokenBuffer; // put first token in Parameterbuffer + TokenBuffer = GetToken(CmdBuffer, &FPosition); // get token value after the = + } + else + { + ParameterBuffer = ""; //init to null string + } + } + else + // return null strings if none left + { + ParameterBuffer = ""; + TokenBuffer = ""; + } + CheckforVar(TokenBuffer); + result = ParameterBuffer; + return result; + } + + /*=======================================================================================================================*/ + + /* Looking for "BusName.1.2.3" in the TokenBuffer + Assumes NodeArray is big enough to hold the numbers*/ + + String TParser::ParseAsBusName(int& NumNodes, Arraydef::pIntegerArray NodeArray, int ActorID) + { + String result; + size_t dotpos = 0; + int NodeBufferPos = 0; + String NodeBuffer; + String DelimSave; + String TokenSave; + if (FAutoIncrement) + GetNextParam(); + NumNodes = 0; + dotpos = TokenBuffer.find("."); + if (dotpos == String::npos) + result = TokenBuffer; + else + { + result = Trim(TokenBuffer.substr(0, dotpos)); // Bus Name + TokenSave = TokenBuffer; + /*now Get nodes*/ + NodeBuffer = TokenBuffer.substr(dotpos + 1, TokenBuffer.length() - dotpos) + " "; + NodeBufferPos = 0; + DelimSave = DelimChars; + DelimChars = "."; + TokenBuffer = GetToken(NodeBuffer, &NodeBufferPos); + try + { + while (TokenBuffer.length() > 0) + { + ++NumNodes; + NodeArray[NumNodes - 1] = MakeInteger_(); + if (ConvertError) + NodeArray[NumNodes - 1] = -1; // Indicate an error + TokenBuffer = GetToken(NodeBuffer, &NodeBufferPos); + } + } + catch (std::exception e) + { + //DSSMessageDlg("Node Buffer Too Small: " + (string) e.what(), true); + } + DelimChars = DelimSave; //restore to original delimiters + TokenBuffer = TokenSave; + } + return result; + } + + /*=======================================================================================================================*/ + + int TParser::ParseAsVector(int ExpectedSize, pDoubleArray VectorBuffer) + { + int result = 0; + int ParseBufferPos = 0; + int NumElements = 0; + int i = 0; + String ParseBuffer; + String DelimSave; + if (FAutoIncrement) + GetNextParam(); + NumElements = 0; + result = 0; // return 0 if none found or error occurred + try + { + int stop = 0; + for (stop = ExpectedSize, i = 1; i <= stop; i++) + { + (VectorBuffer)[i - 1] = 0.0; + } + + /*now Get Vector values*/ + ParseBuffer = TokenBuffer + " "; + ParseBufferPos = 0; + DelimSave = DelimChars; + DelimChars = DelimChars + MatrixRowTerminator; + SkipWhitespace(ParseBuffer, &ParseBufferPos); + TokenBuffer = GetToken(ParseBuffer, &ParseBufferPos); + CheckforVar(TokenBuffer); + while (TokenBuffer.length() > 0) + { + ++NumElements; + if (NumElements <= ExpectedSize) + (VectorBuffer)[NumElements - 1] = MakeDouble_(); + if (LastDelimiter == MatrixRowTerminator) + break; + TokenBuffer = GetToken(ParseBuffer, &ParseBufferPos); + CheckforVar(TokenBuffer); + } + result = NumElements; + } + catch (std::exception e) + { + //DSSMessageDlg("Vector Buffer in ParseAsVector Probably Too Small: " + (string) e.what(), true); + } + DelimChars = DelimSave; //restore to original delimiters + TokenBuffer = ParseBuffer.substr(ParseBufferPos, ParseBuffer.length()); // prepare for next trip + return result; + } + + /*=======================================================================================================================*/ + + int TParser::ParseAsMatrix(int ExpectedOrder, pDoubleArray MatrixBuffer) + { + int result = 0; + int i = 0; + int j = 0; + int k = 0; + int ElementsFound = 0; + pDoubleArray RowBuf; + if (FAutoIncrement) + GetNextParam(); + RowBuf = NULL; + try + { + int stop = 0; + RowBuf = new double[ExpectedOrder]; + for (stop = (ExpectedOrder * ExpectedOrder), i = 1; i <= stop; i++) + { + (MatrixBuffer)[i - 1] = 0.0; + } + for (stop = ExpectedOrder, i = 1; i <= stop; i++) + { + int stop1 = 0; + ElementsFound = ParseAsVector(ExpectedOrder, RowBuf); + + /* Returns matrix in Column Order (Fortran order) */ + k = i; + for (stop1 = ElementsFound, j = 1; j <= stop1; j++) + { + (MatrixBuffer)[k - 1] = (RowBuf)[j - 1]; + k += ExpectedOrder; + } + } + } + catch (std::exception e) + { + //DSSMessageDlg("Matrix Buffer in ParseAsMatrix Probably Too Small: " + (string) e.what(), true); + } + if (RowBuf != NULL) + free(RowBuf); //# FreeMemory accepts one parameter only; + result = ExpectedOrder; + return result; + } + + /*=======================================================================================================================*/ + + int TParser::ParseAsSymMatrix(int ExpectedOrder, pDoubleArray MatrixBuffer) + { + int result = 0; + int i = 0; + int j = 0; + int ElementsFound = 0; + pDoubleArray RowBuf; + + /*---------------- Local Function -----------------------*/ + + auto ElementIndex = [&](int II, int jj) -> int + { + int result = 0; + result = (jj - 1) * ExpectedOrder + II; + return result; + }; + if (FAutoIncrement) + GetNextParam(); + RowBuf = NULL; + try + { + int stop = 0; + RowBuf = new double[ExpectedOrder]; + for (stop = (ExpectedOrder * ExpectedOrder), i = 1; i <= stop; i++) + { + (MatrixBuffer)[i - 1] = 0.0; + } + for (stop = ExpectedOrder, i = 1; i <= stop; i++) + { + int stop1 = 0; + ElementsFound = ParseAsVector(ExpectedOrder, RowBuf); + + /* Returns matrix in Column Order (Fortran order) */ + for (stop1 = ElementsFound, j = 1; j <= stop1; j++) + { + (MatrixBuffer)[ElementIndex(i, j) - 1] = (RowBuf)[j - 1]; + if (i != j) + (MatrixBuffer)[ElementIndex(j, i) - 1] = (RowBuf)[j - 1]; + } + } + } + catch (std::exception e) + { + //DSSMessageDlg("Matrix Buffer in ParseAsSymMatrix Probably Too Small: " + (string) e.what(), true); + } + if (RowBuf != NULL) + delete[] RowBuf; //# FreeMemory accepts one parameter only; + result = ExpectedOrder; + return result; + } + + + + /*=======================================================================================================================*/ + + String TParser::MakeString_() + { + String result; + if (FAutoIncrement) + GetNextParam(); + result = TokenBuffer; + return result; + } + + /*=======================================================================================================================*/ + // Hex integers must be preceeded by "$" + + int TParser::MakeInteger_() + { + int result = 0; + int Code = 0; + double Temp = 0.0; + ConvertError = false; + if (FAutoIncrement) + GetNextParam(); + if (TokenBuffer.length() == 0) + { + result = 0; + } + else + { + if (IsQuotedString) + { + Temp = InterpretRPNString(Code); + result = (int)Round(Temp); + } + else + { + double mytemp1 = (double)result; + val(TokenBuffer, &(mytemp1), &Code); // Try direct conversion to integer + result = (int)mytemp1; + } + if (Code != 0) // on error for integer conversion + // Try again with an double result in case value specified in decimal or some other technique + { + val(TokenBuffer, &Temp, &Code); + if (Code != 0) + // not needed with Raise ... Result := 0; + { + ConvertError = true; + //throw EParserProblem("Integer number conversion error for string: \"" + TokenBuffer + // + "\""); + } + else + result = (int)Round(Temp); + } + } + return result; + } + + /*=======================================================================================================================*/ + + double TParser::MakeDouble_() + { + double result = 0.0; + int Code = 0; + if (FAutoIncrement) + GetNextParam(); + ConvertError = false; + if (TokenBuffer.length() == 0) + result = 0.0; + else + { + if (IsQuotedString) + result = InterpretRPNString(Code); + else + val(TokenBuffer, &result, &Code); + if (Code != 0) + // not needed with Raise ... Result := 0.0; + { + ConvertError = true; + //throw EParserProblem("Floating point number conversion error for string: \"" + TokenBuffer + // + "\""); + } + } + return result; + } + + /*=======================================================================================================================*/ + + String TParser::Get_Remainder() + { + String result; + result = CmdBuffer.substr(FPosition, CmdBuffer.length() - FPosition + 1); + return result; + } + + /*=======================================================================================================================*/ + + /*Checks for CommentChar and '//'*/ + + bool TParser::IsCommentChar(const String LineBuffer, int& LinePos) + { + bool result = false; + switch (LineBuffer[LinePos]) + { + case Commentchar: + result = true; + break; + case L'/': + { + if ((LineBuffer.length() > LinePos) && (LineBuffer[LinePos + 1] == L'/')) + result = true; + else + result = false; + } + break; + default: + result = false; + break; + } + return result; + } + + /*=======================================================================================================================*/ + + double TParser::InterpretRPNString(int& Code) + { + double result = 0.0; + int ParseBufferPos = 0; + String ParseBuffer; + Code = 0; + ParseBuffer = TokenBuffer + " "; + ParseBufferPos = 0; + SkipWhitespace(ParseBuffer, &ParseBufferPos); + TokenBuffer = GetToken(ParseBuffer, &ParseBufferPos); + CheckforVar(TokenBuffer); + while (TokenBuffer.length() > 0) + { + Code = ProcessRPNCommand(TokenBuffer, &RPNCalculator); + if (Code > 0) + break; // Stop on any floating point error + TokenBuffer = GetToken(ParseBuffer, &ParseBufferPos); + CheckforVar(TokenBuffer); + } + result = RPNCalculator.Get_X(); + TokenBuffer = ParseBuffer.substr(ParseBufferPos, ParseBuffer.length()); // prepare for next trip + return result; + } + + /*===================================== Variable Support =============================================================*/ + + /* TParserVar */ + + void ReallocStr(pStringArray s, int OldSize, int NewSize) + { + pStringArray X = new std::string[1]; + X = (pStringArray)realloc(X, sizeof(X[0]) * NewSize); // Zero fills new string pointer array (important!) + if (OldSize > 0) + { + Move(s, &X, OldSize); + free(s); //# FreeMemory accepts one parameter only; + } + s = X; + } + // Make a bigger block to hold the pointers to the strings + + + /*=======================================================================*/ + + int TParserVar::Add(const String VarName, const String varValue) + { + int result = 0; + unsigned int Idx = 0; + String VarDefinition; + + auto EncloseQuotes = [&](const String s) -> String + { + String result; + result = String("{") + s + "}"; + return result; + }; + + // Get_First(), check to see if the varname already exists + // if so, just change the value + Idx = (unsigned int)VarNames->Find(LowerCase(VarName)); + if (Idx == 0) + { + Idx = (unsigned int)VarNames->Add(VarName); // Hashlist will take care of itself + if (Idx > StringArraySize) + // resize String array + { + VarValues = (pStringArray) realloc(VarValues, sizeof(VarValues[0]) * (StringArraySize + FsizeIncrement)); + StringArraySize += FsizeIncrement; + } + } + + /*If a variable used in the definition of a variable, enclose in quotes.*/ + if (varValue.find("@") != String::npos) + VarDefinition = EncloseQuotes(varValue); + else + VarDefinition = varValue; + (VarValues)[Idx - 1] = VarDefinition; + NumVariables = VarNames->Get_NumElements(); + result = (int)Idx; + return result; + } + + /*=======================================================================*/ + + string TParser::get_Token() + { + return TokenBuffer; + } + + /*=======================================================================*/ + + void TParser::set_Token(std::string S) + { + TokenBuffer = S; + } + + /*=======================================================================*/ + + TParserVar::TParserVar(unsigned int initSize) + : ActiveVariable(0), + StringArraySize(0), + FsizeIncrement(0), + VarNames(nullptr), + NumVariables(0) + { + VarNames = new THashList(initSize); + VarValues = AllocStringArray((int)initSize); + StringArraySize = initSize; + FsizeIncrement = initSize; + + // Intrinsic Variables go here... + ActiveVariable = (unsigned int)VarNames->Add("@lastfile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@lastexportfile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@lastshowfile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@lastplotfile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@lastredirectfile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@lastcompilefile"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + ActiveVariable = (unsigned int)VarNames->Add("@result"); + (VarValues)[ActiveVariable - 1] = "null"; // null value + NumVariables = VarNames->Get_NumElements(); + } + + /*=======================================================================*/ + + TParserVar::~TParserVar() + { + delete VarNames; + FreeStringArray(VarValues, (int)StringArraySize); + // inherited; + } + + + /*=======================================================================*/ + + String TParserVar::Get_Value() + { + String result; + if (ActiveVariable > 0) + result = (VarValues)[ActiveVariable - 1]; + else + result = ""; + return result; + } + + String TParserVar::Get_VarString(unsigned int Idx) + { + String result; + + auto TestEmpty = [&](const String s) -> String + { + String result; + if (s.length() == 0) + result = "null"; + else + result = s; + return result; + }; + if ((Idx > 0) && (Idx <= NumVariables)) + result = VarNames->Get(Idx) + ". " + TestEmpty((VarValues)[Idx - 1]); + else + result = "Variable index out of range"; + return result; + } + + int TParserVar::Lookup(const String VarName) + { + int result = 0; + ActiveVariable = (unsigned int)VarNames->Find(VarName); + result = (int)ActiveVariable; + return result; + } + + void TParserVar::Set_Value(const String Value) + { + if ((ActiveVariable > 0) && (ActiveVariable <= NumVariables)) + (VarValues)[ActiveVariable - 1] = Value; + } + + // Variables + + + void ParserDel_initialization() + { + ParserVars = new TParserVar(100); // start with space for 100 variables + } + + void ParserDel_finalization() + { + delete ParserVars; + } + + class ParserDel_unit + { + public: + ParserDel_unit() + { + //AssertSystemInitialization(); + ParserDel_initialization(); + } + ~ParserDel_unit() { ParserDel_finalization(); } + }; + ParserDel_unit _ParserDel_unit; + + + +}// namespace ParseDel + + diff --git a/OpenDSSC/Parser/ParserDel.h b/OpenDSSC/Parser/ParserDel.h new file mode 100644 index 0000000..49ccabc --- /dev/null +++ b/OpenDSSC/Parser/ParserDel.h @@ -0,0 +1,129 @@ +#ifndef ParserDelH +#define ParserDelH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" +#include "RPN.h" +#include "HashList.h" + +namespace ParserDel +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + Command Line Parser Class + + This Version is a Simple version for embedding in Delphi Programs. + + 3/20/01 Added Quote char properties and strings +*/ + +/*$M+*//*controls,*/ + +class EParserProblem : public std::runtime_error +{ +public: + typedef std::runtime_error inherited; + EParserProblem(const String &Msg); +}; + + /*Class for keeping a list of variablel and associate values*/ + +class TParserVar : public System::TObject +{ +public: + typedef TObject inherited; +//private: + unsigned int ActiveVariable; + unsigned int StringArraySize; + unsigned int FsizeIncrement; + Hashlist::THashList* VarNames; + pStringArray VarValues; + std::string Get_Value(); + void Set_Value(const std::string Value); + std::string Get_VarString(unsigned int Idx); +public: + unsigned int NumVariables; + TParserVar(unsigned int initSize); + virtual ~TParserVar(); + int Add(const String VarName, const String varValue); // returns number of variables + int Lookup(const String VarName); // returns index or 0 + TParserVar(); +}; + +class TParser : public System::TObject +{ +public: + typedef TObject inherited; +//private: + String CmdBuffer; + int FPosition; + String ParameterBuffer; + String TokenBuffer; + String DelimChars; + String WhiteSpaceChars; + String FBeginQuoteChars; + String FEndQuoteChars; + Char LastDelimiter; + Char MatrixRowTerminator; + bool FAutoIncrement; + bool ConvertError; + bool IsQuotedString; + RPN::TRPNCalc RPNCalculator; + String Get_Remainder(); + void SetCmdString(const String Value); + String MakeString_(); + int MakeInteger_(); + double MakeDouble_(); + String GetNextParam(); + void SkipWhitespace(const String LineBuffer, int * LinePos); + bool IsWhiteSpace(Char ch); + bool IsDelimiter(const String LineBuffer, int& LinePos); + bool IsDelimChar(Char ch); + bool IsCommentChar(const String LineBuffer, int& LinePos); + String GetToken(const String LineBuffer, int* LinePos); + double InterpretRPNString(int& Code); + std::string get_CmdBuffer(); + std::string get_Token(); + void set_Token(std::string S); +//protected: +public: + TParser(); + virtual ~TParser(); + String ParseAsBusName(int& NumNodes, Arraydef::pIntegerArray NodeArray, int ActorID); + int ParseAsVector(int ExpectedSize, Arraydef::pDoubleArray VectorBuffer); + int ParseAsMatrix(int ExpectedOrder, Arraydef::pDoubleArray MatrixBuffer); + int ParseAsSymMatrix(int ExpectedOrder, Arraydef::pDoubleArray MatrixBuffer); + void ResetDelims(); // resets delimiters to default + void CheckforVar(String& TokenBuffer); + int get_position(); + void set_position(int myPos); + std::string get_delimchars(); + void set_delimchars(std::string S); + std::string get_WhiteSpaceChars(); + void set_WhiteSpaceChars(std::string S); + std::string get_FBeginQuoteChars(); + void set_FBeginQuoteChars(std::string S); + std::string get_FEndQuoteChars(); + void set_FEndQuoteChars(std::string S); + bool get_FAutoIncrement(); + void set_FAutoIncrement(bool S); +}; //Parser : TParser; +extern TParserVar* ParserVars; + +} // namespace ParserDel + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace ParserDel; +#endif + +#endif // ParserDelH + diff --git a/OpenDSSC/Parser/RPN.cpp b/OpenDSSC/Parser/RPN.cpp new file mode 100644 index 0000000..4d2065b --- /dev/null +++ b/OpenDSSC/Parser/RPN.cpp @@ -0,0 +1,222 @@ + + +#pragma hdrstop + +#include "RPN.h" +#include +#include "DSSGlobals.h" + +using namespace std; + + + +/* TRPNCalc */ +double DegToRad = 0.0; +double RadToDeg = 0.0; + +void TRPNCalc::aCosdeg() +{ + FStack[1 - 1] = RadToDeg * acos(FStack[1 - 1]); +} + +void TRPNCalc::Add() +{ + FStack[2 - 1] = FStack[1 - 1] + FStack[2 - 1]; + RollDn(); +} + +void TRPNCalc::aSindeg() +{ + FStack[1 - 1] = RadToDeg * asin(FStack[1 - 1]); +} + +void TRPNCalc::aTandeg() +{ + FStack[1 - 1] = RadToDeg * atan(FStack[1 - 1]); +} + +void TRPNCalc::aTan2deg() +{ + FStack[2 - 1] = RadToDeg * atan2(FStack[2 - 1], FStack[1 - 1]); + RollDn(); +} + +void TRPNCalc::Cosdeg() +{ + FStack[1 - 1] = cos(DegToRad * FStack[1 - 1]); +} + +TRPNCalc::TRPNCalc() +{ + int i = 0; + int stop = 0; + for(stop = MaxStackSize, i = 1; i <= stop; i++) + { + FStack[i - 1] = 0.0; + } +} + +TRPNCalc::~TRPNCalc() +{ + // inherited; +} + + +void TRPNCalc::Divide() +{ + FStack[2 - 1] = FStack[2 - 1] / FStack[1 - 1]; + RollDn(); +} + +double TRPNCalc::Get_X() +{ + double result = 0.0; + result = FStack[1 - 1]; + return result; +} + +double TRPNCalc::Get_Y() +{ + double result = 0.0; + result = FStack[2 - 1]; + return result; +} + +double TRPNCalc::Get_Z() +{ + double result = 0.0; + result = FStack[3 - 1]; + return result; +} + +void TRPNCalc::Multiply() +{ + FStack[2 - 1] = FStack[2 - 1] * FStack[1 - 1]; + RollDn(); +} + +void TRPNCalc::RollDn() +{ + int i = 0; + int stop = 0; + for(stop = MaxStackSize, i = 2; i <= stop; i++) + { + FStack[i - 1 - 1] = FStack[i - 1]; + } +} + +void TRPNCalc::RollUp() +{ + int i = 0; + int stop = 0; + for(stop = 2, i = MaxStackSize; i >= stop; i--) + { + FStack[i - 1] = FStack[i - 1 - 1]; + } +} + +void TRPNCalc::Set_X(double Value) +{ + RollUp(); + FStack[1 - 1] = Value; +} + +void TRPNCalc::Set_Y(double Value) +{ + FStack[2 - 1] = Value; +} + +void TRPNCalc::Set_Z(double Value) +{ + FStack[3 - 1] = Value; +} + +void TRPNCalc::Sindeg() +{ + FStack[1 - 1] = sin(DegToRad * FStack[1 - 1]); +} + +void TRPNCalc::Sqrt() +{ + FStack[1 - 1] = sqrt(FStack[1 - 1]); +} + +void TRPNCalc::Square() +{ + FStack[1 - 1] = pow(FStack[1 - 1],2); +} + +void TRPNCalc::Subtract() +{ + FStack[2 - 1] = FStack[2 - 1] - FStack[1 - 1]; + RollDn(); +} + +void TRPNCalc::SwapXY() +{ + double Temp = 0.0; + Temp = FStack[1 - 1]; + FStack[1 - 1] = FStack[2 - 1]; + FStack[2 - 1] = Temp; +} + +void TRPNCalc::Tandeg() +{ + FStack[1 - 1] = tan(DegToRad * FStack[1 - 1]); +} + +void TRPNCalc::YToTheXPower() +{ + FStack[2 - 1] = pow(FStack[2 - 1], FStack[1 - 1]); + RollDn(); +} + +void TRPNCalc::EnterPi() +{ + RollUp(); + FStack[1 - 1] = PI; +} + +void TRPNCalc::etothex() +{ + FStack[1 - 1] = exp(FStack[1 - 1]); +} + +void TRPNCalc::NatLog() +{ + FStack[1 - 1] = log(FStack[1 - 1]); +} + +void TRPNCalc::TenLog() +{ + FStack[1 - 1] = log10(FStack[1 - 1]); +} // invert 1/X + +void TRPNCalc::Inv() +{ + FStack[1 - 1] = 1.0 / FStack[1 - 1]; +} + + +void RPN_initialization() +{ + DegToRad = PI / 180.0; + RadToDeg = 1.0 / DegToRad; +} + + class RPN_unit + { + public: + RPN_unit() + { + //AssertSystemInitialization(); + RPN_initialization(); + } + }; + RPN_unit _RPN_unit; + + + + + + diff --git a/OpenDSSC/Parser/RPN.h b/OpenDSSC/Parser/RPN.h new file mode 100644 index 0000000..8c78e5e --- /dev/null +++ b/OpenDSSC/Parser/RPN.h @@ -0,0 +1,76 @@ +#ifndef RPNH +#define RPNH + +#include "System.h" +#include "Sysutils.h" + + +namespace RPN +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*RPN Calculator*/ + +/*$M+*/ +const int MaxStackSize = 10; + +class TRPNCalc : public System::TObject +{ +public: + typedef TObject inherited; +//private: + double FStack[10/*# range 1..MaxStackSize*/]; + double Get_X(); + double Get_Y(); + double Get_Z(); + void Set_X(double Value); + void Set_Y(double Value); + void Set_Z(double Value); +//protected: +public: + void Multiply(); + void Divide(); + void Sqrt(); + void Square(); + void Add(); + void Subtract(); + void YToTheXPower(); + void Sindeg(); + void Cosdeg(); + void Tandeg(); + void aSindeg(); + void aCosdeg(); + void aTandeg(); + void aTan2deg(); + void NatLog(); + void TenLog(); + void etothex(); + void EnterPi(); + void Inv(); + void SwapXY(); + void RollUp(); + void RollDn(); + TRPNCalc(); + virtual ~TRPNCalc(); +//__published: +}; + + +} // namespace RPN + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace RPN; +#endif + +#endif // RPNH + + + + diff --git a/OpenDSSC/Plot/DSSGraph.cpp b/OpenDSSC/Plot/DSSGraph.cpp new file mode 100644 index 0000000..7783b4b --- /dev/null +++ b/OpenDSSC/Plot/DSSGraph.cpp @@ -0,0 +1,432 @@ +#pragma hdrstop + +#include "DSSGraph.h" + + + +#include "DSSGlobals.h" +#include "Utilities.h" +#include "math.h" +#include "PDElement.h" +#include "ParserDel.h" + + + +namespace DSSGraph +{ + + TTextRec ActiveDSSGraphFile, + ActiveSolutionFileHdl; + int TextLabelCount = 0; + String ActiveFileName = "", + ActiveSolutionFileName = ""; + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + + EDSSGraphProblem::EDSSGraphProblem(const String &Msg) : inherited(Msg) {} + + + void Checkminmax(const double X, const double Y) + { + /*# with ActiveGraphProps do */ + { + ActiveGraphProps->Xmin = min(X, ActiveGraphProps->Xmin); + ActiveGraphProps->Xmax = max(X, ActiveGraphProps->Xmax); + ActiveGraphProps->Ymin = min(Y, ActiveGraphProps->Ymin); + ActiveGraphProps->YMax = max(Y, ActiveGraphProps->YMax); + } + } + + + int MakeNewGraph(const String Filename) // Call this to make a new graph file + + { + int result = 0; + result = 0; + ActiveFileName = ""; + try + { + AssignFile(ActiveDSSGraphFile, Filename); + Rewrite(ActiveDSSGraphFile); + IOResultToException(); + } + catch (exception& E) + { + { + DoSimpleMsg(String("Error opening DSSView file: ") + Filename + ", " + (string)E.what(), 45001); + return result; + } + } + ActiveFileName = Filename; + ActiveSolutionFileName = ChangeFileExt(ActiveFileName, ".dbl"); + try + { + AssignFile(ActiveSolutionFileHdl, ActiveSolutionFileName); + Rewrite(ActiveSolutionFileHdl); + IOResultToException(); + } + catch (exception& E) + { + { + DoSimpleMsg(String("Error opening DSSView Solution file: ") + Filename + ", " + (string)E.what(), 45001); + return result; + } + } + /*# with ActiveGraphProps do */ + { + ActiveGraphProps->Xmin = 1.0e50; + ActiveGraphProps->Xmax = -1.0e50; + ActiveGraphProps->Ymin = 1.0e50; + ActiveGraphProps->YMax = -1.0e50; + ActiveGraphProps->ChartColor = 0x00FFFFFF; + ActiveGraphProps->WindColor = 0x00FFFFFF; + ActiveGraphProps->Isometric = false; + ActiveGraphProps->GridStyle = gsLines; + } + TextLabelCount = 0; + Set_Properties(ActiveGraphProps); + result = 1; + return result; + } + + + int64_t WriteActiveCktElementVIToFile() + { + int64_t result = 0; + unsigned int Count = 0; + unsigned int CountWritten = 0; + // get present file position + /* Old delphi way + result = SysUtils.FileSeek(ActiveSolutionFileHdl, ((__int64)0), 1); + */ + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + with0->FActiveCktElement->ComputeVterminal(ActiveActor); + with0->FActiveCktElement->ComputeIterminal(ActiveActor); + Count = with0->FActiveCktElement->Yorder * 2 * sizeof(double); + /* Old delphi way + CountWritten = SysUtils.FileWrite(ActiveSolutionFileHdl, with0->FActiveCktElement->Vterminal, Count); + if (CountWritten == Count) + CountWritten = SysUtils.FileWrite(ActiveSolutionFileHdl, with0->FActiveCktElement->Iterminal, Count); + */ + //Write(ActiveSolutionFileHdl, with0->FActiveCktElement->Vterminal); + } + } + if (CountWritten != Count) + { + /* old delphi way + SysUtils.FileClose(ActiveSolutionFileHdl); + */ + //CloseFile(ActiveDSSGraphFile); + //throw @EDSSGraphProblem ::(String("Aborting. Problem writing solution file: ") + ActiveSolutionFileName); + } + return result; + } + + + void AddNewLine(double X1, double Y1, double X2, double Y2, int Color, unsignedchar Thickness, TPenStyle Style, bool Dots, const String LineName, bool MarkCenter, int CenterMarkerCode, int NodeMarkerCode, int NodeMarkerWidth) + { + int64_t Offset = 0; + String Bus1 = "", + Bus2 = ""; + int Bus1Idx = 0, + DataCount = 0, + NumCust = 0, + TotalCust = 0; + double kV_Base = 0.0, + Dist = 0.0; + TPDElement* pDElem = nullptr; + + Offset = WriteActiveCktElementVIToFile(); + + /*# with ActiveCircuit[ActiveActor], ActiveCircuit[ActiveActor].ActiveCktElement do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + auto with1 = with0->FActiveCktElement; + { + Bus1Idx = with1->Terminals[0].BusRef - 1; + kV_Base = with0->Buses[Bus1Idx]->kVBase; + Dist = with0->Buses[Bus1Idx]->DistFromMeter; + Bus1 = with1->GetBus(1); + Bus2 = with1->GetBus(2); + DataCount = with1->Yorder; + } + } + if (dynamic_cast(ActiveCircuit[ActiveActor]->FActiveCktElement)) + { + pDElem = (TPDElement*)ActiveCircuit[ActiveActor]->FActiveCktElement; + NumCust = pDElem->BranchNumCustomers; + TotalCust = pDElem->BranchTotalCustomers; + } + else + { + NumCust = 0; + TotalCust = 0; + } + + System::WriteLn(ActiveDSSGraphFile, Format("Line, \"%s\", \"%s\", \"%s\", %d, %d, %d, %d, %.8g, %.8g, %.8g, %.8g, %.8g, %.8g, %d, %d, %d, %d, %d, %d, %d, %d", + LineName.c_str(), Bus1.c_str(), Bus2.c_str(), Offset, DataCount, NumCust, TotalCust, kV_Base, Dist, X1, Y1, X2, Y2, Color, Thickness, Style, Dots, MarkCenter, CenterMarkerCode, NodeMarkerCode, NodeMarkerWidth)); + Checkminmax(X1, Y1); + Checkminmax(X2, Y2); + } + + + void AddNewCurve(pDoubleArray Xarray, pDoubleArray Yarray, int NumPoints, TColor Color, unsignedchar Thickness, TPenStyle Style, bool Curvemarkers, int CurveMarker, const String CurveName) + { + int i = 0; + Write(ActiveDSSGraphFile, Format("Curve, %d, %d, %d, %d, %d, %d, \"%s\"", NumPoints, Color, Thickness, Style, Curvemarkers, CurveMarker, CurveName.c_str())); + for (int stop = NumPoints, i = 0; i < stop; i++) + Write(ActiveDSSGraphFile, Format(", %.8g", Xarray[i])); + for (int stop = NumPoints, i = 0; i < stop; i++) + Write(ActiveDSSGraphFile, Format(", %.8g", Yarray[i])); + WriteLn(ActiveDSSGraphFile); + + /*???? Check min and max of curve*/ + } + + + void AddNewText(double X1, double Y1, int Color, int Size, String S) + { + WriteLn(ActiveDSSGraphFile, Format("Text, %.8g, %.8g, %d, %d, \"%s\"", X1, Y1, Color, Size, S.c_str())); + Checkminmax(X1, Y1); + } + + + void AddNewCircle(double Xc, double Yc, double Radius, int LineColor, int FColor) + { + WriteLn(ActiveDSSGraphFile, Format("Circle, %.8g, %.8g, %.8g, %d, %d", Xc, Yc, Radius, LineColor, FColor)); + Checkminmax(Xc, Yc); + } + + + void AddNewMarker(double X, double Y, int Color, unsignedchar Symbol, unsignedchar Size) + { + WriteLn(ActiveDSSGraphFile, Format("Marker, %.8g, %.8g, %d, %d, %d", X, Y, Color, Symbol, Size)); + Checkminmax(X, Y); + } + + /*Routines to manage DSSGraph Properties. */ + /*Invoke a Get_Properties to populate the Props struct first then change values*/ + + + void Set_Properties(TDSSGraphProperties* Props) + { + ActiveGraphProps = Props; + WriteLn(ActiveDSSGraphFile, Format("SetProp, %.8g, %8g, %.8g, %.8g, %d, %d, %d, %d", ActiveGraphProps->Xmin, ActiveGraphProps->Xmax, ActiveGraphProps->Ymin, ActiveGraphProps->YMax, ActiveGraphProps->ChartColor, ActiveGraphProps->WindColor, int(ActiveGraphProps->Isometric), int(ActiveGraphProps->GridStyle))); + } + + + void Get_Properties(TDSSGraphProperties* &Props) + { + Props = ActiveGraphProps; + } + + //\"%s\"" Not needed + void Set_XaxisLabel(String S) + { + WriteLn(ActiveDSSGraphFile, "Xlabel, \"" + S + "\""); + } + + + void Set_YaxisLabel(String S) + { + WriteLn(ActiveDSSGraphFile, "Ylabel, \"" + S + "\""); + } + + + void Set_Caption(String S) + { + WriteLn(ActiveDSSGraphFile, "Caption, \"" + S + "\""); + } + + + void Set_ChartCaption(String S) + { + WriteLn(ActiveDSSGraphFile, "ChartCaption, \"" + S + "\""); + } + + + void Set_LineWidth(int Width) + { + WriteLn(ActiveDSSGraphFile, Format("Width, %d", Width)); + } + + + void Set_AutoRange(double PctRim) + { + WriteLn(ActiveDSSGraphFile, Format("PctRim, %.8g", PctRim)); + } + + + void Set_KeepAspectRatio(bool Value) + { + WriteLn(ActiveDSSGraphFile, Format("KeepAspect, %d", int(Value))); + } + + + void Set_DataColor(TColor clr) + { + WriteLn(ActiveDSSGraphFile, Format("DataColor, %d", clr)); + } + + + void Set_TextAlignment(int Option) + { + WriteLn(ActiveDSSGraphFile, Format("TxtAlign, %d", Option)); + } + + + void Set_KeyClass(int Value) + { + WriteLn(ActiveDSSGraphFile, Format("KeyClass, %d", Value)); + } + + + void Set_Range(double LoX, double HiX, double LoY, double HiY) + { + WriteLn(ActiveDSSGraphFile, Format("Range, %.8g, %.8g, %.8g, %.8g", LoX, HiX, LoY, HiY)); + } + + + void Set_FontStyle(TFontStyle Fs) + { + WriteLn(ActiveDSSGraphFile, Format("FStyle, %d", Fs)); + } + + + void Set_NoScales() + { + WriteLn(ActiveDSSGraphFile, "NoScales,"); + } + + + void Set_LeftJustifyTransparent(int LabelIdx) + { + WriteLn(ActiveDSSGraphFile, Format("LJust, %d", LabelIdx)); + } + + + void MoveTo(double X, double Y) + { + WriteLn(ActiveDSSGraphFile, Format("Move, %.8g, %.8g", X, Y)); + } + + + void DrawTo(double X, double Y) + { + WriteLn(ActiveDSSGraphFile, Format("Draw, %.8g, %.8g", X, Y)); + } + + + void Rectangle(double X1, double Y1, double X2, double Y2) + { + WriteLn(ActiveDSSGraphFile, Format("Rect, %.8g, %.8g, %.8g, %.8g", X1, Y1, X2, Y2)); + } + + + void EnableClickonDiagram() + { + WriteLn(ActiveDSSGraphFile, "ClickOn"); + } + + + bool IsOpen(const TTextRec& Txt) + { + bool result = false; + const int fmTextOpenRead = 55217; + const int fmTextOpenWrite = 55218; + result = (((TTextRec*)&Txt)->Mode == fmTextOpenRead) || (((TTextRec*)&Txt)->Mode == fmTextOpenWrite); + return result; + } + + + void ShowGraph() + { + int retval = 0; + String DSSViewFile = ""; + if (IsOpen(ActiveDSSGraphFile)) + { + CloseFile(ActiveDSSGraphFile); + CloseFile(ActiveSolutionFileHdl); + } + try + { + if (FileExists(ActiveFileName)) + { + DSSViewFile = DSSDirectory + "OpenDSSView\\DSSCView.exe"; + + if (FileExists(DSSViewFile)) // Only if the file exists + { +#ifdef _WIN32 + ShellExecute(0, "open", EncloseQuotes(DSSViewFile).c_str(), EncloseQuotes(ActiveFileName).c_str(), NULL, SW_SHOWDEFAULT); +#else +#pragma message("Needs ShellExecute equivalent in DSSGraph.cpp") +#endif + } + + ParserVars->Add("@LastPlotFile", ActiveFileName); + /*switch (retval) + { + case 0: + DoSimpleMsg("System out of memory. ", 45700); + break; + case ERROR_BAD_FORMAT: + DoSimpleMsg(String("Graphics output file \"") + ActiveFileName + "\" is Invalid.", 45701); + break; + case ERROR_FILE_NOT_FOUND: + DoSimpleMsg(DSSViewFile + " File Not Found." + CRLF + "It should be in the same directory as the OpenDSS program", 45702); + break; + case ERROR_PATH_NOT_FOUND: + DoSimpleMsg(String("Path for DSSView program \"") + DSSViewFile + "\" Not Found.", 45703); + break; + } + */ + } + } + catch (exception& E) + { + DoErrorMsg("ShowGraph.", (string)E.what(), "Is DSSView.EXE correctly installed???", 45704); + } + GlobalResult = ActiveFileName; + + } + + + int AddTextLabel(double X, double Y, TColor TextColor, String Txt, int Template) + { + int result = 0; + WriteLn(ActiveDSSGraphFile, Format("Label, %.8g, %.8g, %d, \"%s\", %d", X, Y, TextColor, Txt.c_str(), Template)); + TextLabelCount++; + result = TextLabelCount; + Checkminmax(X, Y); + return result; + } + + + void LockInTextLabel(int Idx) + { + WriteLn(ActiveDSSGraphFile, Format("LockInLabel, %d", Idx)); + } + + + void BoldTextLabel(int Idx) + { + WriteLn(ActiveDSSGraphFile, Format("BoldLabel, %d", Idx)); + } + + + void MarkAt(double X, double Y, unsignedchar Marker, unsignedchar Size) + { + WriteLn(ActiveDSSGraphFile, Format("MarkAt, %.8g, %.8g, %d, %d", X, Y, Marker, Size)); + Checkminmax(X, Y); + } + + + void CenteredText15(double X, double Y, int Size, String Txt) + { + WriteLn(ActiveDSSGraphFile, Format("Center, %.8g, %.8g, %d, \"%s\"", X, Y, Size, Txt.c_str())); + Checkminmax(X, Y); + } + +} // namespace DSSGraph diff --git a/OpenDSSC/Plot/DSSGraph.h b/OpenDSSC/Plot/DSSGraph.h new file mode 100644 index 0000000..4af5581 --- /dev/null +++ b/OpenDSSC/Plot/DSSGraph.h @@ -0,0 +1,113 @@ +#ifndef DSSGraphH +#define DSSGraphH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* + Interface to DSSView Program + + Writes some files with the appropriate info and then invokes DSSView.exe + + Adapted from interface to old DSSGraph.DLL +*/ + + +#include "System.h" + +#include "Arraydef.h" + +namespace DSSGraph +{ + + class EDSSGraphProblem; + struct TDSSGraphProperties; + typedef unsigned char unsignedchar; + typedef int TColor; + typedef int TPenStyle; + typedef int TFontStyle; + + + + + enum GridStyleType { + gsNone, + gsPoints, + gsVertLines, + gsHorizLines, + gsLines, + gsHorizDotLines, + gsVertDotLines, + gsDotLines + }; + + class EDSSGraphProblem : public std::runtime_error { + typedef std::runtime_error inherited; + EDSSGraphProblem(const String &Msg); + }; + + +#pragma pack(push, 1) + struct TDSSGraphProperties { + double Xmin = 0, + Xmax = 0, + Ymin = 0, + YMax = 0; + int ChartColor = 0x000000, + WindColor = 0xFFFFFF; + bool Isometric = false; + GridStyleType GridStyle; + }; +#pragma pack(pop) + + + // Procedure DSSGraphInit(ptrCallBackStruct:pDSSCallBacks); StdCall; external 'DSSGraph.dll' name 'Init'; // Call this once + + + + int MakeNewGraph(const String Filename); // Call this to make a new graph + + void AddNewLine(double X1, double Y1, double X2, double Y2, int Color, unsignedchar Thickness, TPenStyle Style, bool Dots, const String LineName, bool MarkCenter, int CenterMarkerCode, int NodeMarkerCode, int NodeMarkerWidth); + void AddNewCurve(pDoubleArray Xarray, pDoubleArray Yarray, int NumPoints, TColor Color, unsignedchar Thickness, TPenStyle Style, bool Curvemarkers, int CurveMarker, const String CurveName); + void AddNewText(double X1, double Y1, int Color, int Size, String S); + void AddNewCircle(double Xc, double Yc, double Radius, int LineColor, int FColor); + void AddNewMarker(double X, double Y, int Color, unsignedchar Symbol, unsignedchar Size); + + /*Routines to manage DSSGraph Properties. */ + /*Invoke a Get_Properties to populate the Props struct first then change values*/ + void Set_Properties(TDSSGraphProperties* Props); + void Get_Properties(TDSSGraphProperties* &Props); + void Set_XaxisLabel(String S); + void Set_YaxisLabel(String S); + void Set_Caption(String S); + void Set_ChartCaption(String S); + void Set_LineWidth(int Width); + void Set_AutoRange(double PctRim); + void Set_KeepAspectRatio(bool Value); + void Set_DataColor(TColor clr); + void Set_TextAlignment(int Option); + void Set_KeyClass(int Value); + void Set_Range(double LoX, double HiX, double LoY, double HiY); + void Set_FontStyle(TFontStyle Fs); + void Set_NoScales(); + void Set_LeftJustifyTransparent(int LabelIdx); + void MoveTo(double X, double Y); + void DrawTo(double X, double Y); + void Rectangle(double X1, double Y1, double X2, double Y2); + void EnableClickonDiagram(); + void ShowGraph(); + int AddTextLabel(double X, double Y, TColor TextColor, String Txt, int Template); + void LockInTextLabel(int Idx); + void BoldTextLabel(int Idx); + void MarkAt(double X, double Y, unsignedchar Marker, unsignedchar Size); + void CenteredText15(double X, double Y, int Size, String Txt); + +} // namespace DSSGraph + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSGraph; +#endif + +#endif // DSSGraphH \ No newline at end of file diff --git a/OpenDSSC/Plot/DSSPlot.cpp b/OpenDSSC/Plot/DSSPlot.cpp new file mode 100644 index 0000000..a58b46e --- /dev/null +++ b/OpenDSSC/Plot/DSSPlot.cpp @@ -0,0 +1,3701 @@ + + +#pragma hdrstop + +#include "DSSPlot.h" + + + +#include "DSSGraph.h" +#include "DSSClassDefs.h" +#include "DSSGlobals.h" +#include "Circuit.h" +#include "generator.h" +#include "EnergyMeter.h" +#include "GICLine.h" +#include "Utilities.h" +#include "LoadShape.h" +#include "TempShape.h" +#include "PriceShape.h" +#include "Sysutils.h" +#include "math.h" +//#include "DlgPlotOptions.h" +#include "Bus.h" +#include "Monitor.h" +#include "Capacitor.h" +#include "PVsystem.h" +#include "Storage.h" +#include "RegControl.h" +#include "fuse.h" +#include "Recloser.h" +#include "Relay.h" + + + +#include "System.h" + +namespace DSSPlot +{ + + TDSSPlot* DSSPlotObj = NULL; + int SinglePhLineStyle = 0; + int ThreePhLineStyle = 0; + + + + const double Eps = 0.002; + + + const int DSSG_LINECLASS = 1; + const int DSSG_CIRCLECLASS = 2; + const int DSSG_TEXTCLASS = 3; + const int DSSG_MARKERCLASS = 4; + const int DSSG_CURVECLASS = 5; + const int DSSG_SUBSTCLASS = 6; + + + vector BusLabels; + + /* + TDSSPlot + */ + + + void AllocateBusLabels() + { + int i = 0; + BusLabels.resize(ActiveCircuit[ActiveActor]->NumBuses); + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + BusLabels[i - 1] = ""; + } + + + void FreeBusLabels() + { + int i = 0; + /* Get rid of string pointed to by each element */ + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + BusLabels[i - 1] = ""; + BusLabels.resize(0); + } + + + int TDSSPlot::GetAutoColor(double Scale) + + /* One way to get a gradient */ + { + int result; + if (Scale < TriColorMid) + result = Color1; + else + if (Scale < TriColorMax) + result = Color2; + else + result = Color3; + return result; + } + + + int TDSSPlot::GetColor() + { + int result = 0; + TDSSBus* pBus; + double Factor = 0.0; + int i = 0, j = 0; + switch (PlotType) + { + case ptCircuitplot: case ptdaisyplot: case ptGeneralCircuitPlot: + switch (Quantity) + { + case pqVoltage: + { + pBus = ActiveCircuit[ActiveActor]->Buses[Bus2Idx]; + if (ActiveCircuit[ActiveActor]->Issolved && (pBus->kVBase > 0.0)) + { + /* Find min phase voltage at bus - check nodes 1..3 */ + Factor = ActiveCircuit[ActiveActor]->NormalMaxVolts; + for (int stop = pBus->FNumNodesThisBus, i = 1; i <= stop; i++) + { + j = pBus->GetNum(i); + if ((j > 0) && (j <= 3)) + Factor = min(Factor, double(0.001) * cabs(ActiveCircuit[ActiveActor]->Solution->NodeV[pBus->GetRef(i)]) / pBus->kVBase); + } + if (Factor > ActiveCircuit[ActiveActor]->NormalMinVolts) + result = Color1; + else + if (Factor > ActiveCircuit[ActiveActor]->EmergMinVolts) + result = Color2; + else + result = Color3; + } + else + result = Color1; + } + break; + case pqCurrent: + { + result = Color1; + if (pLine->NormAmps > 0.0) + if (MaxCurrent() > pLine->NormAmps) + result = Color3; + } + break; + case pqPower: + result = Color1; + break; + case pqLosses: + result = Color1; + break; + case pqCapacity: + result = Color1; + break; + default: /* Case Quantity */ + result = Color1; // Default to black + if ((double(abs(pLine->GeneralPlotQuantity)) / MaxScale) > 0.99) + result = Color2; + } + break; + default: /* Case Plottype */ + result = Color1; // Default to black + } + return result; + } + + + void TDSSPlot::AddBusMarkers() + { + TBusMarker* BusMarker = nullptr; + TDSSBus* Bus = nullptr; + int i = 0; + + for (int stop = ActiveCircuit[ActiveActor]->BusMarkerList.size() - 1, i = 0; i <= stop; i++) + { + BusMarker = (TBusMarker*) ActiveCircuit[ActiveActor]->BusMarkerList[i]; + Bus1Idx = ActiveCircuit[ActiveActor]->BusList.Find(BusMarker->BusName); + if (Bus1Idx > 0) + /*# with BusMarker do */ + { + auto with0 = BusMarker; + Bus = ActiveCircuit[ActiveActor]->Buses[Bus1Idx]; + if (Bus->CoordDefined) + AddNewMarker(Bus->x, Bus->y, with0->AddMarkerColor, with0->AddMarkerCode, with0->AddMarkerSize); + else + DoSimpleMsg("Bus Coordinates not defined for bus " + with0->BusName, 28709); + } + } + } + + + bool TDSSPlot::CoordinateSame(int i1, int i2) + { + bool result = false; + result = false; + if ((i1 == 0) || (i2 == 0)) + return result; + try + { /* Trap Divide by zero error */ + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + if ((abs(1.0 - abs(with0->Buses[i1 - 1]->x / with0->Buses[i2 - 1]->x)) < Eps) && (abs(1.0 - abs(with0->Buses[i1 - 1]->y / with0->Buses[i2 - 1]->y)) < Eps)) + result = true; + else + result = false; + } + } + catch (...) + { + result = false; /* Likely a divide by zero error, ignore */ + } + return result; + } + + TDSSPlot::TDSSPlot() + : ActiveColorIdx(0), + Bus1Idx(0), + Bus2Idx(0), + FMaxLineThickness(0), + PlotType(ptAutoAddLogPlot), + MatrixType(pIncMatrix), + MaxScale(0.0), + MinScale(0.0), + Dots(false), + Labels(false), + ShowLoops(false), + ShowSubs(false), + Quantity(pqVoltage), + ValueIndex(0), + MarkerIdx(0), + PhasesToPlot(0), + ProfileScale(0), + TriColorMax(0.0), + TriColorMid(0.0), + MaxScaleIsSpecified(false), + MinScaleIsSpecified(false) + { + SetDefaults(); + DaisyBusList.resize(0); + /* Initialize Plotting DLL */ + // --deprecated --- DSSGraphInit(@CallBackRoutines); // send a pointer to the DSS Callback routines struct + PhasesToPlot = PROFILE3PH; + ProfileScale = PROFILEPUKM; + } + + TDSSPlot::~TDSSPlot() + { + // todo check: inherited::Destroy(); + } + + + void TDSSPlot::DoAutoAddPlot() + { + int Color1Save = Color1; + Dots = false; + Quantity = pqNone; + Color1 = 0x00FF0000; + DoCircuitPlot(); + Color1 = Color1Save; + DoGeneralPlot(); + } + + + void TDSSPlot::DoBusLabel(const int Idx, const String BusLabel) + { + /* Only label a bus once */ + if (Idx > 0) + if (Length(BusLabels[Idx - 1]) == 0) + switch (PlotType) + { + case ptMeterZones: + BusLabels[Idx - 1] = BusLabel + "(" + FeederName + ")"; + break; + default: + BusLabels[Idx - 1] = BusLabel; + } + } + + + void TDSSPlot::DoBusLabels(const int Idx1, const int Idx2) + { + if (CoordinateSame(Idx1, Idx2)) + { + /* Special label for overlapping labels */ + BusLabels[Idx1 - 1] = ""; // Force label to change + BusLabels[Idx2 - 1] = ""; + DoBusLabel(Idx1, ActiveCircuit[ActiveActor]->BusList.Get(Idx1) + "/" + ActiveCircuit[ActiveActor]->BusList.Get(Idx2)); + } + else + { + DoBusLabel(Idx1, ActiveCircuit[ActiveActor]->BusList.Get(Idx1)); + DoBusLabel(Idx2, ActiveCircuit[ActiveActor]->BusList.Get(Idx2)); + } + } + + + double MaxGICCurrent(TGICLineObj* pGICLine) + { + double result = 0.0; + int iGIC = 0; + pGICLine->ComputeIterminal(ActiveActor); // load element Iterminal buffer + + /* ****************** Code for GICLines ************************** */ + + /* Draw the lines */ + result = 0.0; + for (int stop = pGICLine->Fnphases, iGIC = 1; iGIC <= stop; iGIC++) + if (cabs(pGICLine->Iterminal[iGIC - 1]) > result) + result = cabs(pGICLine->Iterminal[iGIC - 1]); + return result; + } + + + void TDSSPlot::DoCircuitPlot() + { + int LineStyleType = 0; + int GICThickness = 0; + TGICLineObj* pGICLine = new TGICLineObj(); + TGICLine* pGICLineClass = new TGICLine(); + + + /* ****************** Code for GICLines ************************** */ + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != NULL) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + if (pLine->FEnabled) + { + pLine->Drawn = true; + // Idx1 := Buslist.Find(StripExtension(pLine.GetBus (1))); + // Idx2 := Buslist.Find(StripExtension(pLine.GetBus (2))); + with0->Set_ActiveCktElement(pLine); + Bus1Idx = pLine->Terminals[1 - 1].BusRef - 1; + Bus2Idx = pLine->Terminals[2 - 1].BusRef - 1; + if (with0->Buses[Bus1Idx]->CoordDefined && with0->Buses[Bus2Idx]->CoordDefined) + { + if (pLine->IsSwitch) + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, 0x000000, 1, Style(1), Dots, "Line." + pLine->LName, with0->MarkSwitches, with0->SwitchMarkerCode, with0->NodeMarkerCode, with0->NodeMarkerWidth); + else + if (pLine->IsIsolated) + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, 0x00FF00FF, 3, Style(1), Dots, "Line." + pLine->LName, with0->MarkSwitches, with0->SwitchMarkerCode, with0->NodeMarkerCode, with0->NodeMarkerWidth); + else + { + if (pLine->Fnphases == 1) + LineStyleType = Style(SinglePhLineStyle); + else + LineStyleType = Style(ThreePhLineStyle); + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, GetColor(), Thickness(), LineStyleType, Dots, "Line." + pLine->LName, false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + if (Labels) + DoBusLabels(Bus1Idx + 1, Bus2Idx + 1); + } + } + pLine = (TLineObj*) with0->Lines.Get_Next(); + } + } + + /* ****************** Code for GICLines ************************** */ + pGICLineClass = (TGICLine*) GetDSSClassPtr("GICLine"); + pGICLine = (TGICLineObj*) pGICLineClass->ElementList.Get_First(); + + while (pGICLine != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with1 = ActiveCircuit[ActiveActor]; + { + if (pGICLine->FEnabled) + { + // Idx1 := Buslist.Find(StripExtension(pLine.GetBus (1))); + // Idx2 := Buslist.Find(StripExtension(pLine.GetBus (2))); + with1->Set_ActiveCktElement(pGICLine); + Bus1Idx = pGICLine->Terminals[1 - 1].BusRef - 1; + Bus2Idx = pGICLine->Terminals[2 - 1].BusRef - 1; + if (with1->Buses[Bus1Idx]->CoordDefined && with1->Buses[Bus2Idx]->CoordDefined) + { + if (pGICLine->Fnphases == 1) + LineStyleType = Style(SinglePhLineStyle); + else + LineStyleType = Style(ThreePhLineStyle); + GICThickness = min(7, Round(5.0 * (MaxGICCurrent(pGICLine) / MaxScale))); + AddNewLine(with1->Buses[Bus1Idx]->x, with1->Buses[Bus1Idx]->y, with1->Buses[Bus2Idx]->x, with1->Buses[Bus2Idx]->y, Color1, GICThickness, LineStyleType, Dots, "GICLine." + pGICLine->LName, false, 0, with1->NodeMarkerCode, with1->NodeMarkerWidth); + if (Labels) + DoBusLabels(Bus1Idx + 1, Bus2Idx + 1); + } + } + pGICLine = (TGICLineObj*) pGICLineClass->ElementList.Get_Next(); + } + } + + /* ****************** Code for Transformers ************************** */ + pTransf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + + while (pTransf != nullptr) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with2 = ActiveCircuit[ActiveActor]; + { + if (pTransf->FEnabled) + { + with2->Set_ActiveCktElement(pTransf); + Bus1Idx = pTransf->Terminals[1 - 1].BusRef - 1; + Bus2Idx = pTransf->Terminals[2 - 1].BusRef - 1; + if (with2->Buses[Bus1Idx]->CoordDefined && with2->Buses[Bus2Idx]->CoordDefined) + AddNewLine(with2->Buses[Bus1Idx]->x, with2->Buses[Bus1Idx]->y, with2->Buses[Bus2Idx]->x, with2->Buses[Bus2Idx]->y, 0x00808080, 3, Style(1), Dots, "transformer." + pTransf->LName, false, 0, with2->NodeMarkerCode, with2->NodeMarkerWidth); + } + pTransf = (TTransfObj*) with2->Transformers.Get_Next(); + } + } + + /* ****************** Code for special Bus Markers ************************** */ + + // AddBusMarkers; + } + + + int GenPlotItemCompare(void* Item1, void* Item2) + { + int result = 0; + double Test = 0.0; + Test = ((TGenPlotItem*)Item1)->Value - ((TGenPlotItem*)Item2)->Value; + if (Test < 0.0) + result = -1; + else + if (Test > 0.0) + result = 1; + else + result = 0; + return result; + } + + void TDSSPlot::DoGeneralPlot() + { + double MaxValue = 0.0, + MinValue = 0.0, + Value = 0.0, + Diff = 0.0; + TTextRec F = {}; + String Line = "", + FieldName = ""; + int Idx = 0, + i = 0; + TGenPlotItemList GenPlotItems; + TGenPlotItem* GenPlotItem = nullptr; + + try + { + try + { + AssignFile(F, ObjectName); + Reset(F); + IOResultToException(); + ReadLn(F, Line); // Get FieldName + /*# with AuxParser[ActiveActor] do */ + { + auto with0 = AuxParser[ActiveActor]; + { + with0->set_FAutoIncrement(false); + with0->set_delimchars(",=\x09"); /* Redefine delimiters */ + with0->SetCmdString(Line); + with0->GetNextParam(); /* Bus Name */ + for (int stop = ValueIndex, i = 1; i <= stop; i++) + with0->GetNextParam(); /* Skip to parameter wanted */ + FieldName = with0->MakeString_(); /* Get field name */ + } + } + + /* Find min and max */ + MaxValue = -1.0E50; + MinValue = 1.0E50; + GenPlotItems = TGenPlotItemList(); + while (!Eof(F)) + { + ReadLn(F, Line); + if (Line.size() > 0) + /*# with AuxParser[ActiveActor] do */ + { + auto with1 = AuxParser[ActiveActor]; + { + with1->SetCmdString(Line); // Load up AuxParser + with1->GetNextParam(); /* Bus Name */ + GenPlotItem = new TGenPlotItem; + GenPlotItem->Name = with1->MakeString_(); // Bus Name + for (int stop = ValueIndex, i = 1; i <= stop; i++) + with1->GetNextParam(); // Skip to desired field + if (with1->MakeString_().size() > 0) + { /* Ignore empty fields */ + Value = with1->MakeDouble_(); + MaxValue = max(Value, MaxValue); + MinValue = min(Value, MinValue); + GenPlotItem->Value = Value; + } + GenPlotItems.push_back(GenPlotItem); + } + } + } /* WHILE */ + + /* Do some sanity checking on the numbers. Don't want to include negative numbers in autoadd plot */ + if (PlotType == ptAutoAddLogPlot) + { + if (MinValue < 0.0) + MinValue = 0.0; + if (MaxValue < 0.0) + MaxValue = 0.0; + } + if (MaxScaleIsSpecified) + MaxValue = MaxScale; // Override with user specified value + if (MinScaleIsSpecified) + MinValue = MinScale; // Override with user specified value + Diff = MaxValue - MinValue; + if (Diff == 0.0) + Diff = MaxValue; + if (Diff == 0.0) + Diff = 1.0; // Everything is zero + + // Sort min to max and plot + sort(GenPlotItems.begin(), GenPlotItems.end()); + //GenPlotItems-> (GenPlotItemCompare); + // sorts using user-written routine + Set_ChartCaption(Format("%s, Max=%-.3g ", FieldName.c_str(), MaxValue)); + for (int stop = GenPlotItems.size() - 1, i = 0; i <= stop; i++) + { + GenPlotItem = (TGenPlotItem*) GenPlotItems[i]; + Idx = ActiveCircuit[ActiveActor]->BusList.Find(GenPlotItem->Name); + if (Idx > 0) + /*# with ActiveCircuit[ActiveActor].Buses^[Idx] do */ + { + auto with3 = ActiveCircuit[ActiveActor]->Buses[Idx]; + if (with3->CoordDefined) + { + switch (PlotType) + { + case ptGeneralDataPlot: + AddNewMarker(with3->x, with3->y, InterpolateGradientColor(Color1, Color2, IntPower((GenPlotItem->Value - MinValue) / Diff, 1)), MarkerIdx, ActiveCircuit[ActiveActor]->NodeMarkerWidth); + break; + case ptAutoAddLogPlot: + AddNewMarker(with3->x, with3->y, GetAutoColor((GenPlotItem->Value - MinValue) / Diff), MarkerIdx, ActiveCircuit[ActiveActor]->NodeMarkerWidth); + break; + default: + break; + } + if (Labels) + DoBusLabel(Idx, ActiveCircuit[ActiveActor]->BusList.Get(Idx)); + } + } + } /* WHILE */ + } + catch (exception& E) + { + DoSimpleMsg(String("Error opening \"") + ObjectName + "\": " + (std::string)E.what(), 190); + } + } + catch (...) + { + } + + CloseFile(F); + GenPlotItems.resize(0); + } + + + void TDSSPlot::DoTheDaisies() + { + TGeneratorObj* pGen = nullptr; + vector BusCount; + int i = 0, + j = 0, + Idx = 0; + double Xc = 0.0, + Yc = 0.0, + Radius = 0.0, + Angle = 0.0, + StartAngle = 0.0; + + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + + BusCount.resize(ActiveCircuit[ActiveActor]->NumBuses); + if (DaisyBusList.empty()) + { + /* If Daisy Bus List not filled, then fill it with Generator Buses by default */ + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_First(); + while (pGen != NULL) + { + if (pGen->FEnabled) + { + DaisyBusList.push_back(StripExtension(pGen->GetBus(1))); + } + pGen = (TGeneratorObj*) ActiveCircuit[ActiveActor]->Generators.Get_Next(); + } + } + + /* Count the number of Objects at each bus */ + for (int stop = DaisyBusList.size(), i = 0; i < stop; i++) + { + Idx = ActiveCircuit[ActiveActor]->BusList.Find(DaisyBusList[i]); + if (Idx > 0) + BusCount[Idx - 1]++; + } + //Randomize; + + /* Draw the generators in */ + Get_Properties(ActiveGraphProps); // Get active graph properties + Radius = 0.005 * DaisySize * (ActiveGraphProps->Xmax - ActiveGraphProps->Xmin); + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + if ((BusCount[i - 1] > 0) && ActiveCircuit[ActiveActor]->Buses[i - 1]->CoordDefined) + { + StartAngle = TwoPi; /* * Random */ + Angle = (double(TwoPi) / BusCount[i - 1]); // Radians + for (int stop = BusCount[i - 1], j = 1; j <= stop; j++) + { + Xc = ActiveCircuit[ActiveActor]->Buses[i - 1]->x + 2.0 * Radius * cos(Angle * (j - 1) + StartAngle); + Yc = ActiveCircuit[ActiveActor]->Buses[i - 1]->y + 2.0 * Radius * sin(Angle * (j - 1) + StartAngle); + AddNewLine(ActiveCircuit[ActiveActor]->Buses[i - 1]->x, ActiveCircuit[ActiveActor]->Buses[i - 1]->y, Xc, Yc, clRed, 1, 0, false, "Gen", false, 0, 0, 0); + AddNewCircle(Xc, Yc, Radius, clRed, clYellow); + } + } + } + + /* Put Labels on */ + if (Labels) + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + if ((BusCount[i - 1] > 0) && ActiveCircuit[ActiveActor]->Buses[i - 1]->CoordDefined) + DoBusLabel(i, ActiveCircuit[ActiveActor]->BusList.Get(i)); + BusCount.resize(0); /* Clean up allocated memory */ + } + + void DrawMeterZoneLine(TColor clr, const String Nam, int Idx1, int Idx2, TPenStyle LineStyleType) + { /* Local proc */ + if (ActiveCircuit[ActiveActor]->Buses[Idx1]->CoordDefined && ActiveCircuit[ActiveActor]->Buses[Idx2]->CoordDefined) + { + AddNewLine(ActiveCircuit[ActiveActor]->Buses[Idx1]->x, ActiveCircuit[ActiveActor]->Buses[Idx1]->y, ActiveCircuit[ActiveActor]->Buses[Idx2]->x, ActiveCircuit[ActiveActor]->Buses[Idx2]->y, clr, 1, LineStyleType, 0, String("Line.") + Nam, false, 0, 0, 0); + /* if (Labels) + DoBusLabels(Idx1, Idx2);*/ + } + } + + + void TDSSPlot::DoMeterZonePlot() + + /* Draws feeder lines using the meter zones only + Each feeder is drawn in a different color + */ + { + TEnergyMeterObj* pMeter = nullptr; + int hMeter = 0, + Idx1 = 0, + Idx2 = 0, + FdrColor = 0; + TPenStyle LineStyleType = 0; + TLineObj* LoopLine = nullptr; + String S = ""; + + + /* --------------------------------------------------------------------------------- */ + hMeter = EnergyMeterClass[ActiveActor]->Get_First(); + ActiveColorIdx = 0; /* Nextcolor does an Inc() */ + while (hMeter > 0) + { + if (Length(ObjectName) > 0) // look for a specific object {Else Draw Them All} + if (CompareText(ObjectName, ((TDSSCktElement*) ActiveDSSObject[ActiveActor])->LName) != 0) + { + hMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + continue; + } + pMeter = (TEnergyMeterObj*)ActiveDSSObject[ActiveActor]; + if (!pMeter->FEnabled) // skip disabled energymeters + { + hMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + continue; + } + FeederName = pMeter->LName; + pLine = (TLineObj*) pMeter->BranchList->Get_First(); + + /* Mark Meter Location */ + Idx1 = pLine->Terminals[pMeter->MeteredTerminal - 1].BusRef - 1; + Set_LineWidth(4); + if (ActiveCircuit[ActiveActor]->Buses[Idx1]->CoordDefined) + AddNewMarker(ActiveCircuit[ActiveActor]->Buses[Idx1]->x, ActiveCircuit[ActiveActor]->Buses[Idx1]->y, 0x000000FF, 24, 3); + if (ShowLoops) + FdrColor = Color1; + else + FdrColor = NextColor(); + while (pLine != NULL) + { + if (pLine->FEnabled) + { + pLine->Drawn = true; + ActiveCircuit[ActiveActor]->Set_ActiveCktElement(pLine); + Idx1 = pLine->Terminals[1 - 1].BusRef - 1; + Idx2 = pLine->Terminals[2 - 1].BusRef - 1; + if (pLine->Fnphases == 1) + LineStyleType = Style(SinglePhLineStyle); + else + LineStyleType = Style(ThreePhLineStyle); + if (ShowLoops && pMeter->BranchList->PresentBranch->IsLoopedHere) + { + DrawMeterZoneLine(Color3, pLine->LName, Idx1, Idx2, LineStyleType); + + /* Draw 2nd Line in loop in alternate color, also, if coordinates defined */ + LoopLine = (TLineObj*)pMeter->BranchList->PresentBranch->LoopLineObj; + Idx1 = LoopLine->Terminals[1 - 1].BusRef - 1; + Idx2 = LoopLine->Terminals[2 - 1].BusRef - 1; + DrawMeterZoneLine(Color3, LoopLine->LName, Idx1, Idx2, LineStyleType); + } + else + DrawMeterZoneLine(FdrColor, pLine->LName, Idx1, Idx2, LineStyleType); // normal show zone + } + pLine = (TLineObj*) pMeter->BranchList->Get_Forward(); + } + hMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + } + if (Length(ObjectName) > 0) + S = "Meter Zone: " + ObjectName; + else + S = "All Meter Zones"; + Set_ChartCaption(S); + } + + + void TDSSPlot::Execute() + { + double Aspect = 0.0, + XRange = 0.0, + RangeLoX = 0.0, + RangeHiX = 0.0, + RangeLoY = 0.0, + RangeHiY = 0.0; + String S = "", + Fname = ""; + TDSSGraphProperties* DSSGraphProps = new TDSSGraphProperties(); + //Width, LRim, RRim, Height, Trim, Brim: Integer; + int i = 0; + + /*Init line.Drawn variable to Not Drawn*/ + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while ((pLine != nullptr)) + { + pLine->Drawn = false; + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + /*# with DSSPlotObj do */ + if ((PlotType == ptCircuitplot) && (Quantity == pqNone) && (FileExists(ObjectName))) + PlotType = ptGeneralCircuitPlot; + + /* *** Make a New DSSGraph Plot *** */ + // If MakeNewGraph(DSSDataDirectory + CircuitName_ + 'Plot.DSV') = 0 Then + // Begin + // DoSimpleMsg('Make New Plot failed in DSSPlot Execute.', 8734); + // Exit; + // End; + try + { + switch (PlotType) + { + case ptmonitorplot: + { + Fname = GetOutputDirectory() + CircuitName_[ActiveActor] + "MONITOR-" + UpperCase(ObjectName); + for (int stop = Channels.size(), i = 0; i < stop; i++) + Fname = Fname + Format("-ch%d", Channels[i]); + if (MakeNewGraph(Fname + ".DSV") > 0) + { + DoMonitorPlot(); + } + else + { + DoSimpleMsg("Make New Plot failed for Monitor Plot.", 87341); + } + } + break; /*Monitor Plot*/ + case ptLoadShape: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + Format("Loadshape_%s.DSV", ObjectName.c_str())) > 0) + { + DoLoadShapePlot(ObjectName); + } + else + { + DoSimpleMsg("Make New Plot failed for Loadshape Plot.", 87342); + } + } + break; + case ptTShape: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + Format("TempShape_%s.DSV", ObjectName.c_str())) > 0) + { + DoTempShapePlot(ObjectName); + } + else + { + DoSimpleMsg("Make New Plot failed for TempShape Plot.", 87343); + } + } + break; + case ptPriceShape: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + Format("Priceshape_%s.DSV", ObjectName.c_str())) > 0) + { + DoPriceShapePlot(ObjectName); + } + else + { + DoSimpleMsg("Make New Plot failed for PriceShape Plot.", 87344); + } + } + break; + case ptProfile: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + Format("Profile%d.DSV", PhasesToPlot)) > 0) + { + DoProfilePlot(); + } + else + { + DoSimpleMsg("Make New Plot failed for Profile Plot.", 87345); + } + } + break; + default: /* All other plots */ + { + switch (PlotType) + { + case ptAutoAddLogPlot: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "AutoADD.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed for AutoADD Plot.", 8734); + return; + } + } + break; + case ptCircuitplot: + { + Fname = GetOutputDirectory() + CircuitName_[ActiveActor]; + switch (Quantity) + { + case pqVoltage: + Fname = Fname + "Voltage.DSV"; + break; + case pqCurrent: + Fname = Fname + "Current.DSV"; + break; + case pqPower: + Fname = Fname + "Power.DSV"; + break; + case pqLosses: + Fname = Fname + "Losses.DSV"; + break; + case pqCapacity: + Fname = Fname + "Capacity.DSV"; + break; + case pqNone: + Fname = Fname + "Circuit.DSV"; + break; + } + if (MakeNewGraph(Fname) == 0) + { + DoSimpleMsg("Make New Plot failed for Circuit Plot.", 87346); + return; + } + } + break; + case ptGeneralDataPlot: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "General.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed for General Data Plot.", 87347); + return; + } + } + break; + case ptGeneralCircuitPlot: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "GeneralCircuit.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed for GeneralCircuit Plot.", 87348); + return; + } + } + break; + case ptMeterZones: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "MeterZone.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed for MeterZone Plot.", 87349); + return; + } + } + break; + case ptdaisyplot: + { + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "Daisy.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed for Daisy Plot.", 87340); + return; + } + } + break; + } + AllocateBusLabels(); + Get_Properties(DSSGraphProps); + /*# with DSSGraphProps do */ + { + DSSGraphProps->GridStyle = gsNone; + DSSGraphProps->ChartColor = 0x00FFFFFF; + DSSGraphProps->WindColor = 0x00FFFFFF; + DSSGraphProps->Isometric = true; + EnableClickonDiagram(); + } + Set_Properties(DSSGraphProps); + S = "X"; + Set_XaxisLabel(S); + S = "Y"; + Set_YaxisLabel(S); + Set_TextAlignment(1); /* Left Justify; 2 = center; 3=right */ + Set_KeyClass(DSSG_LINECLASS); /* Line for searches */ + + + switch (PlotType) + { + case ptAutoAddLogPlot: + { + MarkerIdx = 26; + Set_KeyClass(DSSG_MARKERCLASS); /* Marker */ + DoAutoAddPlot(); + MarkSpecialClasses(); + } + break; + case ptCircuitplot: + { + SetMaxScale(); + S = String(ActiveCircuit[ActiveActor]->FCaseName) + ":" + QuantityString() + " " + Format("max=%.3g", MaxScale); + Set_ChartCaption(S); + DoCircuitPlot(); + MarkSpecialClasses(); + } + break; + case ptGeneralDataPlot: + { + Dots = false; + DoCircuitPlot(); + Set_KeyClass(DSSG_MARKERCLASS); /* Marker */ + MarkerIdx = ActiveCircuit[ActiveActor]->NodeMarkerCode; // 24; + DoGeneralPlot(); + MarkSpecialClasses(); + } + break; + case ptGeneralCircuitPlot: + { + LoadGeneralLineData(); + SetMaxScale(); + S = String(ActiveCircuit[ActiveActor]->FCaseName) + ":" + QuantityString() + " " + Format("max=%.3g", MaxScale); + Set_ChartCaption(S); + DoGeneralCircuitPlot(); + MarkSpecialClasses(); + } + break; + case ptMeterZones: + { + DoMeterZonePlot(); + MarkSpecialClasses(); + } + break; + case ptdaisyplot: + { + S = "Device Locations / " + QuantityString(); + Set_ChartCaption(S); + if (Labels) + { + Labels = false; /* Temporarily turn off */ + DoCircuitPlot(); + Labels = true; /* Turn back on to label generators */ + } + else + DoCircuitPlot(); + MarkSpecialClasses(); + DoTheDaisies(); + } + break; + default: /* Case PlotType */ + { + /* Nada */ + } + break; + } + LabelBuses(); /* Add labels on top of lines */ + FreeBusLabels(); + + /* Make sure both X and Y have the same scale */ + // --deprecated-- Get_PlotWindowParms(Width, LRim, RRim, Height, Trim, Brim); + // --deprecated-- Aspect := (Width - LRim - RRim)/(Height - Trim - Brim); + + Aspect = 1.5; // Default aspect ratio + Get_Properties(DSSGraphProps); + /*# with DSSGraphProps do */ + + XRange = max((DSSGraphProps->Xmax - DSSGraphProps->Xmin), (DSSGraphProps->YMax - DSSGraphProps->Ymin) * Aspect); + /* Add 2%Margin */ + XRange = 1.02 * XRange; + // --deprecated-- Get_Range(RangeLoX, RangeHiX, RangeLoY, RangeHiY); + RangeLoX = (DSSGraphProps->Xmin + DSSGraphProps->Xmax - XRange) / 2.0; // Xmin - Mar; {Isometric=true forces Y to have same range as X} + RangeHiX = (DSSGraphProps->Xmin + DSSGraphProps->Xmax + XRange) / 2.0; // Xmin + HiX + Mar; + RangeLoY = DSSGraphProps->Ymin - 0.02 * XRange / Aspect; + RangeHiY = RangeLoY + (XRange / Aspect); + Set_Range(RangeLoX, RangeHiX, RangeLoY, RangeHiY); + + /* Keep this range for quick resetting */ + DSSGraphProps->Xmin = RangeLoX; + DSSGraphProps->Xmax = RangeHiX; + DSSGraphProps->Ymin = RangeLoY; + DSSGraphProps->YMax = RangeHiY; + Set_Properties(DSSGraphProps); + + Set_KeepAspectRatio(true); + } + } /* CASE */ + } + catch (...) + { + } + ShowGraph(); + } + + void TDSSPlot::DSSVizPlot() + { + /* old Delphi way - to be replaced + if (!(DSSConnectObj != NULL)) // First connection + { + DSSConnectObj = TDSSConnect.Create; // Creates the connection + } + DSSConnectObj.Connect; // Connects to the server + switch (PlotType) + { + case // Classifies the plot message + ptmonitorplot: + DSSConnectObj.MonitorPlotMsg(ObjectName); + break; + case ptLoadShape: + DSSConnectObj.LoadshapePlotMsg(ObjectName); + break; + case ptProfile: + { + DSSConnectObj.ProfilePlotMsg(ObjectName, PlotID); + PlotID = ""; + } + break; + case ptScatterPlot: + { + DSSConnectObj.ScatterPlotMsg(PlotID); + PlotID = ""; + } + break; + case ptEvolutionPlot: + DSSConnectObj.EvolutionPlotMsg; + break; + case ptEnergyPlot: + DSSConnectObj.EnergyMeterPlotMsg(ObjectName); + break; + case ptMatrixplot: + { + if (MatrixType == pLaplacian) + DSSConnectObj.MatrixPlotMsg(1); + else + DSSConnectObj.MatrixPlotMsg(0); + } + break; + case ptPhaseVoltage: + DSSConnectObj.PhaseVoltageMsg(ObjectName); + break; + } + */ + } + + + int InterpByte(int B1, int B2, double& RatioToUse) + { + int result = 0; + result = Round(B1 + RatioToUse * (B2 - B1)); + return result; + } + + + TColor TDSSPlot::InterpolateGradientColor(TColor Color1, TColor Color2, double Ratio) + { + TColor result = 0; + const int Redmask = 0x000000FF; + const int GreenMask = 0x0000FF00; + const int BlueMask = 0x00FF0000; + int R1 = 0, + G1 = 0, + B1 = 0, + R2 = 0, + G2 = 0, + B2 = 0; + double RatioToUse = 0.0; + + RatioToUse = max(0.0, min(1.0, Ratio)); // Limit to 0.0 .. 1.0 + R1 = Color1 & Redmask; + G1 = (Color1 & GreenMask) >> 8; + B1 = (Color1 & BlueMask) >> 16; + R2 = Color2 & Redmask; + G2 = (Color2 & GreenMask) >> 8; + B2 = (Color2 & BlueMask) >> 16; + result = InterpByte(R1, R2, RatioToUse) + (InterpByte(G1, G2, RatioToUse) << 8) + (InterpByte(B1, B2, RatioToUse) << 16); + if (result <= 0) + result = Color1; + return result; + } + + + double TDSSPlot::MaxCurrent() + { + double result = 0.0; + int i = 0; + pLine->ComputeIterminal(ActiveActor); // load element Iterminal buffer + result = 0.0; + for (int stop = pLine->Fnphases, i = 1; i <= stop; i++) + if (cabs(pLine->Iterminal[i - 1]) > result) + result = cabs(pLine->Iterminal[i - 1]); + return result; + } + + + TColor TDSSPlot::NextColor() + { + TColor result; + ActiveColorIdx++; + if (ActiveColorIdx > 17) + ActiveColorIdx = 1; + result = ColorArray[ActiveColorIdx - 1]; + return result; + } + + + void TDSSPlot::SetColorArray() + { + ColorArray[1 - 1] = TColor(0x000000); + ColorArray[2 - 1] = TColor(0x0000FF); + ColorArray[3 - 1] = TColor(0xFF0000); + ColorArray[4 - 1] = TColor(0xFF00FF); + ColorArray[5 - 1] = TColor(0x008000); + ColorArray[6 - 1] = TColor(0x00FF80); + ColorArray[7 - 1] = TColor(0x4080FF); + ColorArray[8 - 1] = TColor(0x21DEDA); + ColorArray[9 - 1] = TColor(0xFF6AB5); + ColorArray[10 - 1] = TColor(0x004080); + ColorArray[11 - 1] = TColor(0x008080); + ColorArray[12 - 1] = TColor(0xA00000); + ColorArray[13 - 1] = TColor(0x8080FF); + ColorArray[14 - 1] = TColor(0x800000); + ColorArray[15 - 1] = TColor(0x7F7F7F); + ColorArray[16 - 1] = TColor(0x7B0F8E); + ColorArray[17 - 1] = TColor(0x8E9607); + } + + void TDSSPlot::SetDefaults() + { + MaxScale = 0.0; // Find MaxScale + MaxScaleIsSpecified = false; // indicates take the default + MinScale = 0.0; // Find MinScale + MinScaleIsSpecified = false; // indicates take the default + Dots = false; + Labels = false; + ShowLoops = false; + ShowSubs = false; + Quantity = pqPower; + PlotType = ptCircuitplot; + MarkerIdx = 24; + ObjectName = ""; + FMaxLineThickness = 10; + Channels.resize(3); + Channels[0] = 1; + Channels[1] = 3; + Channels[2] = 5; + Bases.resize(3); + Bases[0] = 1.0; + Bases[1] = 1.0; + Bases[2] = 1.0; + Color1 = 0x00FF0000; + Color2 = 0x00008000; + Color3 = 0x000000FF; + TriColorMax = 0.85; + TriColorMid = 0.50; + ActiveColorIdx = 0; + SetColorArray(); + ThreePhLineStyle = 1; + SinglePhLineStyle = 1; + } + + TPenStyle TDSSPlot::Style(int Code) + { + TPenStyle result; + switch (Code) + { + case 1: + result = psSolid; + break; + case 2: + result = psDash; + break; + case 3: + result = psDot; + break; + case 4: + result = psDashDot; + break; + case 5: + result = psDashDotDot; + break; + case 6: + result = psClear; + break; + case 7: + result = psInsideFrame; + break; + default: + result = psSolid; + } + return result; + } + + + int TDSSPlot::Thickness() + { + int result = 0; + switch (PlotType) + { + case ptmonitorplot: + result = 1; + break; + default: + { + pLine->Set_ActiveTerminal(1); // just for good measure + switch (Quantity) + { + case pqNone: + { + if (PlotType == ptGeneralCircuitPlot) + result = Round(8.0 * (double(abs(pLine->GeneralPlotQuantity)) / MaxScale)); + else + result = 1; + } + break; + case pqVoltage: + result = 1; + break; + case pqCurrent: + { + if (pLine->NormAmps > 0.0) + result = Round(double(5.0) * MaxCurrent() / pLine->NormAmps); + else + result = 1; + } + break; + case pqPower: + { + result = Round(5.0 * (abs(pLine->Get_Power(1, ActiveActor).re) * 0.001 / MaxScale)); // kW + } + break; + case pqLosses: + { // Losses per unit length + result = Round(5.0 * (abs(pLine->Get_Losses(ActiveActor).re / pLine->Len) * 0.001 / MaxScale)); + } + break; + case pqCapacity: + { + if (pLine->NormAmps > 0.0) + result = Round(5.0 * (1.0 - MaxCurrent() / pLine->NormAmps)); + else + result = FMaxLineThickness; + } + break; + default: + result = 1; + } + } + } + if (result <= 0) + result = 1; + if (result > FMaxLineThickness) + result = FMaxLineThickness; + return result; + } + + void TDSSPlot::DoTempShapePlot(const String TempShapeName) + { + TTShapeObj* Temp_Shape = nullptr; + vector Xarray; + double X = 0.0, + Xinc = 0.0; + int i = 0, + Xsize = 0; + String XLabel = "", + S = ""; + bool UseXarray = false; + + Temp_Shape = (TTShapeObj*)TShapeClass[ActiveActor]->Find(TempShapeName); + if (Temp_Shape == NULL) + { + DoSimpleMsg(String("Tshape object not found: \"") + TempShapeName + "\"", 87341); + return; + } + UseXarray = false; + Xarray.clear(); + Xsize = 0; // Init + if (Temp_Shape->Interval != 0.0) + /*# with Temp_Shape do */ + { // have to gen up Xarray + auto with0 = Temp_Shape; + UseXarray = true; + Xsize = sizeof(Xarray[1]) * with0->FNumPoints; + Xarray.resize(Xsize); // SetLength(Xarray, Numpoints); + X = 0.0; + if (with0->Interval * with0->FNumPoints < 1.0) + { + Xinc = with0->Interval * 3600.0; // Plot secs + XLabel = "Seconds"; + } + else + { + Xinc = with0->Interval; + XLabel = "Hours"; + } + for (int stop = with0->FNumPoints, i = 1; i <= stop; i++) + { + Xarray[i] = X; + X = X + Xinc; + } + } + + // ** already exists MakeNewGraph; + S = "TShape." + TempShapeName; + Set_Caption(S); + S = "TShape = " + TempShapeName; + Set_ChartCaption(S); + Set_XaxisLabel(XLabel); + Set_YaxisLabel("Temperature"); + if (UseXarray) + AddNewCurve(&(Xarray[0]), Temp_Shape->TValues, Temp_Shape->FNumPoints, Color1, 1, 0, false, 1, TempShapeName); + else + AddNewCurve(Temp_Shape->Hours, Temp_Shape->TValues, Temp_Shape->FNumPoints, Color1, 1, 0, false, 1, TempShapeName); + Set_KeepAspectRatio(false); + if (UseXarray) + Xarray.clear(); + Set_AutoRange(2.0); // 2% rim + //*** ShowGraph; { Form Freed on close } + } + + + void TDSSPlot::DoLoadShapePlot(const String LoadShapeName) + { + TLoadShapeObj* Load_Shape = nullptr; + vector Xarray; + double X = 0.0, + Xinc = 0.0; + int i = 0, + Xsize = 0; + String S = "", + XLabel = ""; + bool UseXarray = false; + + Load_Shape = (TLoadShapeObj*) LoadShapeClass[ActiveActor]->Find(LoadShapeName); + if (Load_Shape == NULL) + { + DoSimpleMsg(String("Loadshape object not found: \"") + LoadShapeName + "\"", 87341); + return; + } + UseXarray = false; + Xarray.clear(); + Xsize = 0; // Init + if (Load_Shape->Interval != 0.0) + /*# with Load_Shape do */ + { // have to gen up Xarray + auto with0 = Load_Shape; + UseXarray = true; + Xsize = with0->FNumPoints; + Xarray.resize(Xsize); // SetLength(Xarray, Numpoints); + X = 0.0; + if (with0->Interval * with0->FNumPoints < 1.0) + { + Xinc = with0->Interval * 3600.0; // Plot secs + XLabel = "Seconds"; + } + else + { + Xinc = with0->Interval; + XLabel = "Hours"; + } + for (int stop = with0->FNumPoints, i = 0; i < stop; i++) + { + Xarray[i] = X; + X = X + Xinc; + } + } + + // ** already exists MakeNewGraph; + S = String("Loadshape.") + LoadShapeName; + Set_Caption(S); + S = String("Loadshape = ") + LoadShapeName; + Set_ChartCaption(S); + Set_XaxisLabel(XLabel); + if (Load_Shape->UseActual) + Set_YaxisLabel("kW, kvar"); + else + Set_YaxisLabel("p.u."); + if (Load_Shape->UseMMF) + { + Load_Shape->PMultipliers.resize(Load_Shape->FNumPoints); + for (int stop = Load_Shape->FNumPoints, i = 1; i <= stop; i++) + Load_Shape->PMultipliers[i - 1] = InterpretDblArrayMMF(Load_Shape->myView, Load_Shape->myFileType, Load_Shape->myColumn, i, Load_Shape->myLineLen); + } + if (UseXarray) + AddNewCurve(&(Xarray[0]), &(Load_Shape->PMultipliers[0]), Load_Shape->FNumPoints, Color1, 1, 0, false, 1, LoadShapeName); + else + AddNewCurve(&(Load_Shape->Hours[0]), &(Load_Shape->PMultipliers[0]), Load_Shape->FNumPoints, Color1, 1, 0, false, 1, LoadShapeName); + if (!(Load_Shape->QMultipliers.empty())) + { + if (Load_Shape->UseMMF) + { + Load_Shape->QMultipliers.resize(Load_Shape->FNumPoints); + for (int stop = Load_Shape->FNumPoints, i = 1; i <= stop; i++) + Load_Shape->QMultipliers[i - 1] = InterpretDblArrayMMF(Load_Shape->myViewQ, Load_Shape->myFileTypeQ, Load_Shape->myColumnQ, i, Load_Shape->myLineLenQ); + } + if (UseXarray) + AddNewCurve(&(Xarray[0]), &(Load_Shape->QMultipliers[0]), Load_Shape->FNumPoints, Color2, 1, 0, false, 1, LoadShapeName); + else + AddNewCurve(&(Load_Shape->Hours[0]), &(Load_Shape->QMultipliers[0]), Load_Shape->FNumPoints, Color2, 1, 0, false, 1, LoadShapeName); + } + Set_KeepAspectRatio(false); + if (UseXarray) + Xarray.clear(); + Set_AutoRange(2.0); // 2% rim + //*** ShowGraph; { Form Freed on close } + } + + /* --------------------------------------------------------- */ + + + void LoadRegisters(pDoubleArray RegisterArray) + { + int i = 0; + AuxParser[ActiveActor]->ParseAsVector(NumEMRegisters + 1, RegisterArray); + for (int stop = NumEMRegisters, i = 1; i <= stop; i++) + RegisterArray[i] = RegisterArray[i] * 0.001; + } + + /* --------------------------------------------------------- */ + + + void PeakDayLoadRegisters(TTextRec& F, pDoubleArray RegisterArray) + { + int iday = 0, i = 0; + double TempRegisters[NumEMRegisters]; + String S; + for (int stop = NumEMRegisters, i = 0; i < stop; i++) + RegisterArray[i] = 0.0; + for (int stop = 24, iday = 1; iday <= stop; iday++) + if (!Eof(F)) + { + ReadLn(F, S); + AuxParser[ActiveActor]->SetCmdString("\"" + S + "\""); + AuxParser[ActiveActor]->GetNextParam(); + LoadRegisters(&(TempRegisters[0])); + for (int stop = NumEMRegisters, i = 0; i < stop; i++) + RegisterArray[i] = max(RegisterArray[i], TempRegisters[i]); + } + } + + /* --------------------------------------------------------- */ + + + void TDSSPlot::DoDI_Plot(const String CaseName, int CaseYear, const int* iRegisters, int iRegisters_maxidx, bool PeakDay, const String MeterName) + { + TTextRec F; + TStringList Names; + String S = "", + FileName = "", + Param = ""; + double Registers1[NumEMRegisters - 0 + 1], + Registers2[NumEMRegisters - 0 + 1]; + int i = 0; + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + /* Plot Demand interval data from saved results DI_Totals.CSV */ + /* If PeakDay=True then we only plot the peak of a 24-hr day */ + Names.clear(); + /* Open File */ + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\" + MeterName + ".CSV"; + if (!FileExists(FileName)) + { + DoSimpleMsg("File \"" + FileName + "\" does not exist.", 191); + return; + } + else + { + try + { + AssignFile(F, FileName); + Reset(F); + IOResultToException(); + ReadLn(F, S); // Read input line + /*# with AuxParser[ActiveActor] do */ + { + auto with0 = AuxParser[ActiveActor]; + { + with0->SetCmdString(S); + with0->GetNextParam(); + Param = with0->MakeString_(); + while (Param.size() > 0) + { + Names.push_back(Param); + with0->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + } + } /* With */ + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string) E.what(), 192); + } + } + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "DIPlot.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed in DSSPlot - DI plot.", 8734); + return; + } + + /* POssibly change some properties of the graph */ + Get_Properties(ActiveGraphProps); + /*# with ActiveGraphProps do */ + { + auto with1 = ActiveGraphProps; + with1->ChartColor = 0x00FFFFFF; + with1->WindColor = 0x00FFFFFF; + } + Set_Properties(ActiveGraphProps); + S = CaseName + Format(", Yr=%d, ", CaseYear); + Set_Caption(S); + Set_XaxisLabel("Hour"); + S = "MW, MWh or MVA"; + Set_YaxisLabel(S); + S = "Registers: "; + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + S = S + Names[iRegisters[i]] + ", "; + Set_ChartCaption(S); + + /* Get started - initializer Registers 1 */ + try + { + try + { + if (!Eof(F)) + { + if (PeakDay) + { + PeakDayLoadRegisters(F, &Registers1[0]); + } + else + { + ReadLn(F, S); + /*# with AuxParser[ActiveActor] do */ + { + auto with1 = AuxParser[ActiveActor]; + { + with1->SetCmdString("\"" + S + "\""); + with1->GetNextParam(); + LoadRegisters(&Registers1[0]); + } + } + } + } + while (!Eof(F)) + { + if (PeakDay) + PeakDayLoadRegisters(F, &Registers2[0]); + else + { + ReadLn(F, S); + /*# with AuxParser[ActiveActor] do */ + { + auto with2 = AuxParser[ActiveActor]; + { + with2->SetCmdString("\"" + S + "\""); + with2->MakeString_(); + LoadRegisters(&Registers2[0]); + } + } + } + ActiveColorIdx = 0; + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + { + AddNewLine(Registers1[0], Registers1[iRegisters[i]], Registers2[0], Registers2[iRegisters[i]], NextColor(), 1, 0, false, " ", false, 0, 0, 0); + } + for (int stop = NumEMRegisters, i = 0; i <= stop; i++) + Registers1[i] = Registers2[i]; + } + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string) E.what(), 193); + } + Set_KeepAspectRatio(false); + Set_AutoRange(2.0); // 2% rim + //**** ShowGraph; { Form Freed on close } + } + catch (...) + { + } + CloseFile(F); + Names.clear(); + } + + + double GetDiff(double Yvalue, double XValue, int MaxYear, double** X, double** Y) + /* Interpolation routine */ + { + double result = 0.0; + int k = 0, lastk = 0; + lastk = 0; + for (int stop = MaxYear, k = 0; k <= stop; k++) + { + if (X[2][k - 1] > 0.0) + { + lastk = k; + if (Yvalue == 0.0) + { + result = 0.0; + return result; + } + else + if (Y[2][k - 1] == Yvalue) + { + result = X[2][k - 1] - XValue; + return result; + } + else + if (Y[2][k - 1] > Yvalue) + { + if (k == 0) + result = X[2][k - 1] - XValue; + else + if ((Y[2][k - 1] - Y[2][k - 1 - 1]) == 0.0) + result = X[2][k - 1 - 1] - XValue; + else + result = X[2][k - 1 - 1] + (Yvalue - Y[2][k - 1 - 1]) / (Y[2][k - 1] - Y[2][k - 1 - 1]) * (X[2][k - 1] - X[2][k - 1 - 1]) - XValue; + return result; + } + } + } + /* If we get here, didn't find anything. Extrapolate last two points */ + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* Plot Demand interval data from saved results DI_Totals.CSV */ + if (lastk == 0) + result = 0.0; + else + result = X[2][lastk - 1 - 1] + (Yvalue - Y[2][lastk - 1 - 1]) / (Y[2][lastk - 1] - Y[2][lastk - 1 - 1]) * (X[2][lastk - 1] - X[2][lastk - 1 - 1]) - XValue; + return result; + } + + + void MakeDiffCurve(double* HorizDiff, int MaxYear, double** X, double** Y) + { + int j = 0; + for (int stop = MaxYear, j = 0; j <= stop; j++) + { + if (X[1][j - 1] > 0.0) + HorizDiff[j] = GetDiff(Y[1][j - 1], X[1][j - 1], MaxYear, X, Y); + } + } + + + bool ReadS(TColor CaseYear, Textfile& F, String& S, bool SearchForMeterName, String WhichFile) + { + bool result = false; + result = true; + if (SearchForMeterName) + { + do + { + ReadLn(F, S); + AuxParser[ActiveActor]->SetCmdString(S); + AuxParser[ActiveActor]->GetNextParam(); + } while (!((CompareText(WhichFile, AuxParser[ActiveActor]->MakeString_()) == 0) || Eof(F))); + if (CompareText(WhichFile, AuxParser[ActiveActor]->MakeString_()) == 0) + { + S = IntToStr(CaseYear) + S.substr(S.find(","), 9999); + } + else + { + result = false; + } + } + else + ReadLn(F, S); + return result; + } + + + void TDSSPlot::DoCompareCases(String CaseName1, String CaseName2, String WhichFile, int Reg) + + /* Compare a register from to cases in the Totals.CSV file, compute horiz distance, + plot vs 1st register of totals.csv file */ + { + TTextRec F; + String S = "", + FileName = "", + Param = "", + CaseName = ""; + TStringList Names; + double Registers1[NumEMRegisters - 0 + 1] = {}, + Registers2[NumEMRegisters - 0 + 1] = {}, + X[3/*# range 1..2*/][21/*# range 0..20*/] = {}, + Y[3/*# range 1..2*/][21/*# range 0..20*/] = {}; + double HorizDiff[21/*# range 0..20*/] = {}; + double X1 = 0.0, + Y1 = 0.0, + Xinc = 0.0, + Yinc = 0.0, + LegendX = 0.0, + LegendY = 0.0; + TColor i = 0, + iPass = 0, + iCase = 0, + CaseYear = 0, + PrevCaseYear = 0, + ActiveColorStartThisCase = 0, + DiffColor = 0; + + /* Arrays to hold the two curves for diff curve */ + + int MinYear = 0, + MaxYear = 0, + LabelIdx = 0; + bool SearchForMeterName = false; + bool FirstYear = false; + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + TColor DatColor = 0; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /* Internal Procs */ + Names.clear(); + + /* Init holding array */ + for (int stop = 20, i = 0; i <= stop; i++) + { + X[1][i - 1] = -1.0; // signify no value at this point + X[2][i - 1] = -1.0; + Y[1][i - 1] = 0.0; + Y[2][i - 1] = 0.0; + } + MinYear = 20; + MaxYear = 0; + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "CompPlot.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed in DSSPlot - comparison Plot.", 8734); + return; + } + Get_Properties(ActiveGraphProps); + /*# with ActiveGraphProps do */ + { + ActiveGraphProps->ChartColor = 0x00FFFFFF; + ActiveGraphProps->WindColor = 0x00FFFFFF; + } + Set_Properties(ActiveGraphProps); + S = String("Comparision of Yearly Curves for case(s):") + CaseName1 + ", " + CaseName2; + Set_Caption(S); + S = "Total Area MW"; + Set_XaxisLabel(S); + S = "MW, MWh or MVA"; + Set_YaxisLabel(S); + + /* Loop Through Cases */ + ActiveColorStartThisCase = 0; + CaseName = CaseName1; + for (int stop = 2, iCase = 1; iCase <= stop; iCase++) + { + + // Get X values from Totals.CSV on first pass + for (int stop = 2, iPass = 1; iPass <= stop; iPass++) + { + /* Loop through possible caseyears (0..20) */ + FirstYear = true; + for (int stop = 20, CaseYear = 0; CaseYear <= stop; CaseYear++) + { + /* Open File */ + SearchForMeterName = false; + switch (iPass) + { + case 1: + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\Totals.CSV"; + break; + case 2: + if ((CompareText(WhichFile, "Totals") == 0) || (CompareText(WhichFile, "Systemmeter") == 0)) + { + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\" + WhichFile + ".CSV"; + } + else + { + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\" + "EnergyMeterTotals.CSV"; + SearchForMeterName = true; + } + break; + } + if (!FileExists(FileName)) + { + continue; // Skip if it doesnt exist + } + else + { + try + { + MaxYear = max(MaxYear, CaseYear); + MinYear = min(MinYear, CaseYear); + AssignFile(F, FileName); + Reset(F); + IOResultToException(); + ReadLn(F, S); // Read header line + if ((iCase == 1) && FirstYear) + { + AuxParser[ActiveActor]->SetCmdString(S); + AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + while (Param.size() > 0) + { + Names.push_back(Param); + AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + S = String("Meter: ") + WhichFile + " Register: " + Names[Reg]; + Set_ChartCaption(S); + } + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string)E.what(), 194); + } + } + /* Get started - initialize Registers 1 */ + PrevCaseYear = CaseYear; + try + { + try + { + if (FirstYear) + { + if (!Eof(F)) + { + if (!ReadS(CaseYear, F, S, SearchForMeterName,WhichFile)) + { + DoSimpleMsg(String("Meter Not Found: \"") + WhichFile + "\"", 1941); + return; // Abort + } + AuxParser[ActiveActor]->SetCmdString("\"" + S + "\""); + AuxParser[ActiveActor]->GetNextParam(); + LoadRegisters(&Registers1[0]); + switch (iPass) + { + case 1: + X[iCase][CaseYear - 1] = Registers1[7]; + break; + case 2: + Y[iCase][CaseYear - 1] = Registers1[Reg]; + break; + } + FirstYear = false; + } + } + else + if (!Eof(F)) + { // Gotta have at least 2 years to make a plot + ReadS(CaseYear, F, S, SearchForMeterName, WhichFile); + AuxParser[ActiveActor]->SetCmdString("\"" + S + "\""); + AuxParser[ActiveActor]->GetNextParam(); + LoadRegisters(&Registers2[0]); + switch (iPass) + { + case 1: + X[iCase][CaseYear - 1] = Registers2[7]; + break; + case 2: + Y[iCase][CaseYear - 1] = Registers2[Reg]; + break; + } + switch (iPass) + { + case 2: + { + ActiveColorIdx = ActiveColorStartThisCase; + AddNewLine(X[iCase][PrevCaseYear - 1], Registers1[Reg], X[iCase][CaseYear - 1], Registers2[Reg], NextColor(), 2, 0, false, " ", false, 0, 0, 0); + MarkAt(X[iCase][CaseYear - 1], Registers2[Reg], GetMarker(ActiveColorIdx), 1); + for (int stop = NumEMRegisters, i = 0; i <= stop; i++) + Registers1[i] = Registers2[i]; + } + break; + default: + break; + } + } + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string) E.what(), 195); + } + } + catch (...) + { + } + CloseFile(F); + } /* For CaseYear */ + } /* For iPass */ + ActiveColorStartThisCase = ActiveColorIdx; + // Start next case where this one left off + CaseName = CaseName2; + } /* For CaseNames */ + + /* Make Diff Plot and Write output file */ + MakeDiffCurve(HorizDiff,MaxYear,(double**)& X[0][0], (double**)&Y[0][0]); + DiffColor = NextColor(); + FirstYear = true; + X1 = 0.0; + Y1 = 0.0; + for (int stop = 20, CaseYear = 0; CaseYear <= stop; CaseYear++) + { + if (X[1][CaseYear - 1] >= 0.0) + { + if (FirstYear) + { + X1 = X[1][CaseYear - 1]; + Y1 = HorizDiff[CaseYear]; + FirstYear = false; + } + else + { + AddNewLine(X1, Y1, X[1][CaseYear - 1], HorizDiff[CaseYear], DiffColor, 1, 0, false, " ", false, 0, 0, 0); + MarkAt(X[1][CaseYear - 1], HorizDiff[CaseYear], GetMarker(ActiveColorIdx), 1); + X1 = X[1][CaseYear - 1]; + Y1 = HorizDiff[CaseYear]; + } + } + } + Set_AutoRange(2.0); // 2% rim + /* Put on legend in upper left hand corner */ + Get_Properties(ActiveGraphProps); + Xinc = 0.05 * (ActiveGraphProps->Xmax - ActiveGraphProps->Xmin); + Yinc = 0.05 * (ActiveGraphProps->YMax - ActiveGraphProps->Ymin); + LegendX = ActiveGraphProps->Xmin + Xinc; + LegendY = ActiveGraphProps->YMax - Yinc; + ActiveColorIdx = 0; + DatColor = NextColor(); // Next color automatically increments + Set_DataColor(DatColor); + LabelIdx = AddTextLabel(LegendX + 0.5 * Xinc, LegendY - 0.5 * Yinc, DatColor, CaseName1, 0); + LockInTextLabel(LabelIdx); + LegendY = LegendY - Yinc; + DatColor = NextColor(); // Next color automatically increments + Set_DataColor(DatColor); + LabelIdx = AddTextLabel(LegendX + 0.5 * Xinc, LegendY - 0.5 * Yinc, DatColor, CaseName2, 0); + LockInTextLabel(LabelIdx); + LegendY = LegendY - Yinc; + DatColor = NextColor(); // Next color automatically increments + Set_DataColor(DatColor); + LabelIdx = AddTextLabel(LegendX + 0.5 * Xinc, LegendY - 0.5 * Yinc, DatColor, "Difference", 0); + LockInTextLabel(LabelIdx); + + /* Write Output File */ + try + { + FileName = CaseName2 + "-" + CaseName1 + "_Reg" + Trim(IntToStr(Reg)) + ".CSV"; + AssignFile(F, FileName); + Rewrite(F); + IOResultToException(); + WriteLn(F, String("\"MW Load\", \"") + CaseName1 + "\", \"MW Load\", \"" + CaseName2 + "\", \"Incr. Cap.\""); + for (int stop = 20, CaseYear = 0; CaseYear <= stop; CaseYear++) + { + if (X[1][CaseYear - 1] >= 0.0) + WriteLn(F, Format("%-g, %-g, %-g, %-g, %-g", X[1][CaseYear - 1], Y[1][CaseYear - 1], X[2][CaseYear - 1], Y[2][CaseYear - 1], HorizDiff[CaseYear])); + } + CloseFile(F); + GlobalResult = FileName; + } + catch (exception& E) + { + DoSimpleMsg(String("Error writing file: \"") + FileName + "\". " + (string) E.what(), 196); + } + Set_KeepAspectRatio(false); + + //**** ShowGraph; { Form Freed on close } + Names.clear(); + } + + + void WriteFoutRecord(int opt, String CaseName, int CaseYear, Textfile& Fout, double* Registers1, double* Registers2, double* XValue, const int* iRegisters, int iRegisters_maxidx, int iX) + { + int i = 0; + Write(Fout, Format("%s, %d, %.7g", CaseName.c_str(), CaseYear, XValue[iX])); + switch (opt) + { + case 1: + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + Write(Fout, Format(", %.7g ", Registers1[iRegisters[i]])); + break; + case 2: + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + Write(Fout, Format(", %.7g ", Registers2[iRegisters[i]])); + break; + } + WriteLn(Fout); + } + + + void TDSSPlot::DoYearlyCurvePlot(TStringList CaseNames, String WhichFile, const int* iRegisters, int iRegisters_maxidx) + + /* Plot yearly results from specified cases and registers in Totals.CSV files + Vs Register 1 */ + { + TTextRec F, Fout; + String S = "", + FileName = "", + Param = "", + CaseName = ""; + TStringList Names; + double Registers1[NumEMRegisters + 1] = {}, + Registers2[NumEMRegisters + 1] = {}, + XValue[21/*# range 0..20*/] = {}; + int i = 0, + iPass = 0, + iX = 0, + iCase = 0, + CaseYear = 0, + ActiveColorStartThisCase = 0; + bool FirstYear = false; + double LegendX = 0.0, + LegendY = 0.0, + Xinc = 0.0, + Yinc = 0.0; + int LabelIdx = 0; + bool SearchForMeterName = false; + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + TColor DatColor = 0; + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* Internal Procs */ + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + /* Plot Demand interval data from saved results DI_Totals.CSV */ + Names.clear(); + if (MakeNewGraph(GetOutputDirectory() + CircuitName_[ActiveActor] + "YearlyPlot.DSV") == 0) + { + DoSimpleMsg("Make New Plot failed in DSSPlot -- yearly plot.", 8734); + return; + } + S = "Yearly Curves for case(s)"; + for (int stop = CaseNames.size() - 1, i = 0; i <= stop; i++) + S = S + ", " + CaseNames[i]; + Set_Caption(S); + Get_Properties(ActiveGraphProps); + /*# with ActiveGraphProps do */ + { + ActiveGraphProps->ChartColor = 0x00FFFFFF; + ActiveGraphProps->WindColor = 0x00FFFFFF; + } + Set_Properties(ActiveGraphProps); + S = "Total Area MW"; + Set_XaxisLabel(S); + S = "MW, MWh or MVA"; + Set_YaxisLabel(S); + try + { /* ... Finally */ + AssignFile(Fout, "LastYearlyCurvePlot.CSV"); + Rewrite(Fout); + IOResultToException(); + Write(Fout, "Case, Year, TotalMW"); + if ((ActiveEnergyMeterObj != NULL)) + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + Write(Fout, Format(", \"%s\"", ActiveEnergyMeterObj->RegisterNames[iRegisters[i] - 1].c_str())); + else + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + Write(Fout, Format(", \"Reg %d\"", iRegisters[i])); + WriteLn(Fout); + + /* Loop Through Cases */ + FirstYear = true; + ActiveColorStartThisCase = 0; + for (int stop = CaseNames.size(), iCase = 0; iCase < stop; iCase++) + { + CaseName = CaseNames[iCase]; + if (DirectoryExists(CaseName)) + // Do This in Two Passes to set the X Values at Register 7 of Totals.CSV + for (int stop = 2, iPass = 1; iPass <= stop; iPass++) + { + /* Loop through possible caseyears (0..20) */ + FirstYear = true; + for (int stop = 20, CaseYear = 0; CaseYear <= stop; CaseYear++) + { + /* Open File */ + SearchForMeterName = false; + switch (iPass) + { + case 1: + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\Totals.CSV"; + break; + default: + { + if ((CompareText(WhichFile, "Totals") == 0) || (CompareText(WhichFile, "Systemmeter") == 0)) + { + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\" + WhichFile + ".CSV"; + } + else + { + FileName = CaseName + "\\di_yr_" + Trim(IntToStr(CaseYear)) + "\\" + "EnergyMeterTotals.CSV"; + SearchForMeterName = true; + } + } + } + if (!FileExists(FileName)) + { + continue; // Skip if it doesnt exist + } + else + { + try + { + AssignFile(F, FileName); + Reset(F); + IOResultToException(); + ReadLn(F, S); // Read header line + switch (iPass) + { + case 2: + if ((iCase == 0) && FirstYear) + { + AuxParser[ActiveActor]->SetCmdString(S); + AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + while (Param.size() > 0) + { + Names.push_back(Param); + AuxParser[ActiveActor]->GetNextParam(); + Param = AuxParser[ActiveActor]->MakeString_(); + } + S = String("Meter: ") + WhichFile + ", Registers: "; + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + S = S + Names[iRegisters[i]] + ", "; + Set_ChartCaption(S); + } + break; + default: + /* Nada */ + break; + } + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string) E.what(), 197); + } + } + + /* Get started - initialize Registers 1 */ + try + { + try + { + if (FirstYear) + { + if (!Eof(F)) + { + if (!ReadS(CaseYear, F, S, SearchForMeterName, WhichFile)) + { // Reads S + DoSimpleMsg(String("Meter not found: \"") + WhichFile + "\"", 1971); + return; + } + AuxParser[ActiveActor]->SetCmdString("\"" + S + "\""); + AuxParser[ActiveActor]->GetNextParam(); + LoadRegisters(&Registers1[0]); // from auxparser + iX = 0; + switch (iPass) + { + case 1: + XValue[iX] = Registers1[7]; + break; + default: + WriteFoutRecord(1, CaseName, CaseYear, Fout, Registers1, Registers2, XValue, iRegisters, iRegisters_maxidx, iX); + } + FirstYear = false; + } + } + else + if (!Eof(F)) + { // Gotta have at least 2 years to make a plot + ReadS(CaseYear, F, S, SearchForMeterName, WhichFile); // Reads S -- any errors will be caught on first pass + AuxParser[ActiveActor]->SetCmdString("\"" + S + "\""); + // enclose in quotes to parse as array + AuxParser[ActiveActor]->GetNextParam(); + LoadRegisters(&Registers2[0]); // from auxparser + iX++; + switch (iPass) + { + case 1: + XValue[iX] = Registers2[7]; + break; + default: + ActiveColorIdx = ActiveColorStartThisCase; + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + { + AddNewLine(XValue[iX - 1], Registers1[iRegisters[i]], XValue[iX], Registers2[iRegisters[i]], NextColor(), 2, 0, false, " ", false, 0, 0, 0); + MarkAt(XValue[iX], Registers2[iRegisters[i]], GetMarker(ActiveColorIdx), 1); + } + WriteFoutRecord(2, CaseName, CaseYear, Fout, Registers1, Registers2, XValue, iRegisters, iRegisters_maxidx, iX); + for (int stop = NumEMRegisters, i = 0; i <= stop; i++) + Registers1[i] = Registers2[i]; + } + } + } + catch (exception& E) + { + DoSimpleMsg(String("Error Reading File \"") + FileName + "\". " + (string) E.what(), 198); + } + } + catch (...) + { + } + CloseFile(F); + } /* For CaseYear */ + } /* For iPass */ + ActiveColorStartThisCase = ActiveColorIdx; + // Start next case where this one left off + } /* For CaseNames */ + if (FirstYear) + { + DoSimpleMsg("No Files Found", 199); + } + else + { + /* Put on legend in upper left hand corner */ + Get_Properties(ActiveGraphProps); + Xinc = 0.05 * (ActiveGraphProps->Xmax - ActiveGraphProps->Xmin); + Yinc = 0.05 * (ActiveGraphProps->YMax - ActiveGraphProps->Ymin); + LegendX = ActiveGraphProps->Xmin + Xinc; + LegendY = ActiveGraphProps->YMax - Yinc; + ActiveColorIdx = 0; + for (int stop = CaseNames.size(), iCase = 0; iCase < stop; iCase++) + { + CaseName = CaseNames[iCase]; + if (DirectoryExists(CaseName)) + for (int stop = iRegisters_maxidx /*# High(iRegisters) */, i = 0; i <= stop; i++) + { + S = CaseNames[iCase] + ", " + Names[iRegisters[i]]; + DatColor = NextColor(); + Set_DataColor(DatColor); + MarkAt(LegendX, LegendY, GetMarker(ActiveColorIdx), 1); + LabelIdx = AddTextLabel(LegendX + 0.5 * Xinc, LegendY - 0.5 * Yinc, DatColor, S, 0); + Set_LeftJustifyTransparent(LabelIdx); + } + LegendY = LegendY - Yinc; + } + } + Set_KeepAspectRatio(false); + Set_AutoRange(2.0); // 2% rim + //**** ShowGraph; { Form Freed on close } + Names.clear(); + } + catch (...) + { + } + CloseFile(Fout); + GlobalResult = "LastYearlyCurvePlot.CSV"; + } + + + unsignedchar TDSSPlot::GetMarker(int Idx) + { + unsignedchar result = 0; + do + { + if (Idx > 9) + Idx = Idx - 9; + } while (!(Idx < 10)); + switch (Idx) + { + case 1: + result = 5; + break; + case 2: + result = 15; + break; + case 3: + result = 2; + break; + case 4: + result = 8; + break; + case 5: + result = 26; + break; + case 6: + result = 36; + break; + case 7: + result = 39; + break; + case 8: + result = 19; + break; + case 9: + result = 18; + break; + default: + result = 5; + } + return result; + } + + + void TDSSPlot::LabelBuses() + /* Adds text to plot labeling buses */ + { + int i = 0; + for (int stop = ActiveCircuit[ActiveActor]->NumBuses, i = 1; i <= stop; i++) + { + if (Length(BusLabels[i-1]) > 0) + if (ActiveCircuit[ActiveActor]->Buses[i - 1]->CoordDefined) + AddNewText(ActiveCircuit[ActiveActor]->Buses[i - 1]->x, ActiveCircuit[ActiveActor]->Buses[i - 1]->y, 0x00000000, 8, BusLabels[i - 1]); + } + } + + + void TDSSPlot::DoMonitorPlot() + { + int Fversion = 0, + FSignature = 0, + iMode = 0; + float hr = 0.0, + S = 0.0; + unsigned int i = 0, + Nread = 0, + RecordSize = 0, + RecordBytes = 0; + float sngBuffer[100/*# range 1..100*/] = {}; // a big buffer + + TMonitorStrBuffer dummyRec; + char* pStrBuffer = nullptr; + double time = 0.0; + bool FirstRecord = false, + Hours = false; + vector< String > ChannelNames; + String Str = ""; + bool ItsAFreqScan = false; + unsigned int NumberofRecords = 0; + vector Xarray; + vector> Yarray; + int iCount = 0; + unsigned int iChannel = 0; + + + Yarray.resize(100); + /* Plot designated channels in monitor designated by ObjectName */ + if (MonitorClass[ActiveActor]->SetActive(ObjectName)) + { + /*# with TMonitorObj(MonitorClass[ActiveActor].GetActiveObj) do */ + { + auto with0 = (TMonitorObj*)MonitorClass[ActiveActor]->GetActiveObj(); + { + with0->Save(); // Save present buffer + with0->CloseMonitorStream(ActiveActor); + FirstRecord = true; + Hours = true; + pStrBuffer = &(with0->StrBuffer[0]); + /*# with MonitorStream do */ + { // Was throwing E2251 (ambiguous olverloaded...) in Linux + auto& with1 = with0->MonitorStream; + with1.begin(); // Start at the beginning of the Stream + with1.Read(&FSignature, sizeof(FSignature)); + with1.Read(&Fversion, sizeof(Fversion)); + with1.Read(&RecordSize); + with1.Read(&iMode, sizeof(iMode)); + with1.Read(dummyRec); + } + AuxParser[ActiveActor]->set_WhiteSpaceChars(""); + AuxParser[ActiveActor]->SetCmdString((String)pStrBuffer); + ChannelNames.resize(RecordSize + 3); + for (int stop = RecordSize + 1, i = 0; i <= stop; i++) + { + AuxParser[ActiveActor]->GetNextParam(); + ChannelNames[i] = AuxParser[ActiveActor]->MakeString_(); + } + AuxParser[ActiveActor]->ResetDelims(); // restore original delimiters + if (CompareText(ChannelNames[0], "Freq") == 0) + ItsAFreqScan = true; + else + ItsAFreqScan = false; + + // pStr := @StrBuffer; + RecordBytes = sizeof(sngBuffer[1 - 1]) * RecordSize; + NumberofRecords = (with0->MonitorStream.Size() - with0->MonitorStream.Position()) / RecordBytes; + + // Allocate arrays for plotting + Xarray.resize(NumberofRecords); + for (int stop = Channels.size(), i = 0; i < stop; i++) + Yarray[i].resize(NumberofRecords); + iCount = -1; // Loop count + while (!(with0->MonitorStream.Position() >= with0->MonitorStream.Size())) + { + /*# with MonitorStream do */ + { + auto& with2 = with0->MonitorStream; + with2.Read(&hr, sizeof(hr)); + with2.Read(&S, sizeof(S)); + Nread = with2.Read(sngBuffer, RecordBytes); + } + if (Nread < RecordBytes) + break; + iCount++; + if (FirstRecord) + { + if ((S > 0.0) && (S < 100.0)) + Hours = false; + } + if (ItsAFreqScan) + time = hr; // frequency value + else + if (Hours) + time = hr + S / 3600.0; // in hrs + else + time = hr * 3600.0 + S; // in sec + Xarray[iCount] = time; + for (int stop = Channels.size(), i = 0; i < stop; i++) + { + iChannel = Channels[i]; + if (iChannel > 0 && iChannel <= RecordSize) // check for legal channel number + { + Yarray[i][iCount] = sngBuffer[iChannel - 1] / Bases[i]; + } + } + FirstRecord = false; + } + with0->CloseMonitorStream(ActiveActor); + + // Add the curves to the plot + ActiveColorIdx = 0; + for (int stop = Channels.size(), i = 0; i < stop; i++) + { + AddNewCurve(&(Xarray[0]), &(Yarray[i][0]), iCount + 1, NextColor(), 2, 0, false, 1, ChannelNames[Channels[i]]); + } + if (ItsAFreqScan) + Str = "Frequency, Hz"; + else + if (Hours) + Str = "Time, H"; + else + Str = "Time, s"; + Set_XaxisLabel(Str); + Str = "Mag"; + Set_YaxisLabel(Str); + if (Channels[0] <= RecordSize) + Str = ObjectName + ": " + ChannelNames[Channels[0] + 1]; + for (int stop = Channels.size(), i = 1; i < stop; i++) + if (Channels[i] <= RecordSize) + Str = Str + Format(", %s", ChannelNames[Channels[i] + 1].c_str()); + Set_ChartCaption(Str); + } + } /* With */ + Set_AutoRange(2.0); // 2% rim + //*** ShowGraph; + + // de-Allocate arrays used for plotting + Xarray.clear(); + for (int stop = Channels.size(), i = 0; i < stop; i++) + Yarray[i].clear(); + Yarray.clear(); + } + else + DoSimpleMsg(String("Monitor \"") + ObjectName + "\" not found.", 200); + } + + + void TDSSPlot::DoPriceShapePlot(const String PriceShapeName) + { + TPriceShapeObj* Price_Shape = nullptr; + vector Xarray; + double X = 0.0, + Xinc = 0.0; + int i = 0, + Xsize = 0; + String XLabel = "", + S = ""; + bool UseXarray = false; + + Price_Shape = (TPriceShapeObj*) PriceShapeClass[ActiveActor]->Find(PriceShapeName); + if (Price_Shape == nullptr) + { + DoSimpleMsg(String("PriceShape object not found: \"") + PriceShapeName + "\"", 87341); + return; + } + UseXarray = false; + Xarray.clear(); + Xsize = 0; // Init + if (Price_Shape->Interval != 0.0) + /*# with Price_Shape do */ + { // have to gen up Xarray + auto with0 = Price_Shape; + UseXarray = true; + Xsize = sizeof(Xarray[1]) * with0->get_FNumPoints(); + Xarray.resize(Xsize + 1); // SetLength(Xarray, Numpoints); + X = 0.0; + if (with0->Interval * with0->get_FNumPoints() < 1.0) + { + Xinc = with0->Interval * 3600.0; // Plot secs + XLabel = "Seconds"; + } + else + { + Xinc = with0->Interval; + XLabel = "Hours"; + } + for (int stop = with0->get_FNumPoints(), i = 1; i <= stop; i++) + { + Xarray[i] = X; + X = X + Xinc; + } + } + + // ** already exists MakeNewGraph; + S = String("PriceShape.") + PriceShapeName; + Set_Caption(S); + S = String("PriceShape = ") + PriceShapeName; + Set_ChartCaption(S); + Set_XaxisLabel(XLabel); + Set_YaxisLabel("Price"); + if (UseXarray) + AddNewCurve(&(Xarray[0]), Price_Shape->PriceValues, Price_Shape->get_FNumPoints(), Color1, 1, 0, false, 1, PriceShapeName); + else + AddNewCurve(&(Price_Shape->Hours[0]), Price_Shape->PriceValues, Price_Shape->get_FNumPoints(), Color1, 1, 0, false, 1, PriceShapeName); + Set_KeepAspectRatio(false); + if (UseXarray) + Xarray.clear(); + Set_AutoRange(2.0); // 2% rim + //*** ShowGraph; { Form Freed on close } + } + + void TDSSPlot::DoProfilePlot() + + /* Voltage profile plot. Tom Short Plot with lines */ + { + int iEnergyMeter = 0; + int iphs = 0; + int iphs2 = 0; + TEnergyMeterObj* ActiveEnergyMeter = nullptr; + TDSSCktElement* PresentCktElement = nullptr; + TDSSBus* Bus1 = nullptr; + TDSSBus* Bus2 = nullptr; + double puV1 = 0.0, + puV2 = 0.0; + double RangeLoY = 0.0, + RangeHiY = 0.0; + double DenomLL = 0.0, + DenomLN = 0.0, + LenScale = 0.0, + RangeScale = 0.0; + String S = ""; + TColor MyColor = 0; + TPenStyle LineType = 0; + TDSSGraphProperties* DSSGraphProps = new TDSSGraphProperties(); + + + /* New graph created before this routine is entered */ + switch (PhasesToPlot) + { + case PROFILELL: case PROFILELLALL: case PROFILELLPRI: + S = "L-L Voltage Profile"; + break; + default: + S = "L-N Voltage Profile"; + } + Set_Caption(S); + Set_ChartCaption(S); + if (ProfileScale == PROFILE120KFT) + { + Set_XaxisLabel("Distance (kft)"); + Set_YaxisLabel("120 Base Voltage"); + DenomLN = 1000.0 / 120.0; + DenomLL = 1732.0 / 120.0; + LenScale = 3.2809; + RangeScale = 120.0; + } + else + { + Set_XaxisLabel("Distance (km)"); + Set_YaxisLabel("p.u. Voltage"); + DenomLN = 1000.0; + DenomLL = 1732.0; + LenScale = 1.0; + RangeScale = 1.0; + } + Get_Properties(DSSGraphProps); + /*# with DSSGraphProps do */ + { + DSSGraphProps->GridStyle = gsDotLines; + DSSGraphProps->ChartColor = 0x00FFFFFF; + DSSGraphProps->WindColor = 0x00FFFFFF; + DSSGraphProps->Isometric = false; + EnableClickonDiagram(); + } + Set_Properties(DSSGraphProps); + Set_TextAlignment(1); + Set_KeyClass(DSSG_LINECLASS); /* Line for searches */ + iEnergyMeter = EnergyMeterClass[ActiveActor]->Get_First(); + while (iEnergyMeter > 0) + { + ActiveEnergyMeter = (TEnergyMeterObj*) EnergyMeterClass[ActiveActor]->GetActiveObj(); + /* Go down each branch list and draw a line */ + PresentCktElement = (TDSSCktElement*) ActiveEnergyMeter->BranchList->Get_First(); + while (PresentCktElement != nullptr) + { + if (IslineElement(PresentCktElement)) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + with0->Set_ActiveCktElement(PresentCktElement); + Bus1 = with0->Buses[PresentCktElement->Terminals[1 - 1].BusRef - 1]; + Bus2 = with0->Buses[PresentCktElement->Terminals[2 - 1].BusRef - 1]; + /* Now determin which phase to plot */ + if ((Bus1->kVBase > 0.0) && (Bus2->kVBase > 0.0)) + switch (PhasesToPlot) + { + case + /* 3ph only */ PROFILE3PH: + if ((PresentCktElement->Fnphases >= 3) && (Bus1->kVBase > 1.0)) + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + puV1 = cabs(with0->Solution->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))]) / Bus1->kVBase / DenomLN; + puV2 = cabs(with0->Solution->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))]) / Bus2->kVBase / DenomLN; + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, ColorArray[iphs - 1], 2, 0, + Dots, Format("%s.%s",PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + break; + /* Plot all phases present (between 1 and 3) */ + case PROFILEALL: + { + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + puV1 = cabs(with0->Solution->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))]) / Bus1->kVBase / DenomLN; + puV2 = cabs(with0->Solution->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))]) / Bus2->kVBase / DenomLN; + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s", PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + break; + /* Plot all phases present (between 1 and 3) for Primary only */ + case PROFILEALLPRI: + { + if (Bus1->kVBase > 1.0) + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + puV1 = cabs(with0->Solution->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))]) / Bus1->kVBase / DenomLN; + puV2 = cabs(with0->Solution->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))]) / Bus2->kVBase / DenomLN; + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s", PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + break; + case PROFILELL: + { + if (PresentCktElement->Fnphases >= 3) + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if (iphs2 > 3) + iphs2 = 1; + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0) && (Bus1->FindIdx(iphs2) > 0) && (Bus2->FindIdx(iphs2) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + /*# with Solution do */ + { + auto with1 = with0->Solution; + puV1 = cabs(csub(with1->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))], with1->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs2))])) / Bus1->kVBase / DenomLL; + puV2 = cabs(csub(with1->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))], with1->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs2))])) / Bus2->kVBase / DenomLL; + } + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s",PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + } + break; + case PROFILELLALL: + { + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if (iphs2 > 3) + iphs2 = 1; + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0) && (Bus1->FindIdx(iphs2) > 0) && (Bus2->FindIdx(iphs2) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + /*# with Solution do */ + { + auto with3 = with0->Solution; + puV1 = cabs(csub(with3->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))], with3->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs2))])) / Bus1->kVBase / DenomLL; + puV2 = cabs(csub(with3->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))], with3->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs2))])) / Bus2->kVBase / DenomLL; + } + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s", PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + } + break; + PROFILELLPRI: + { + if (Bus1->kVBase > 1.0) + for (int stop = 3, iphs = 1; iphs <= stop; iphs++) + { + iphs2 = iphs + 1; + if (iphs2 > 3) + iphs2 = 1; + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0) && (Bus1->FindIdx(iphs2) > 0) && (Bus2->FindIdx(iphs2) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + /*# with Solution do */ + { + auto with4 = with0->Solution; + puV1 = cabs(csub(with4->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))], with4->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs2))])) / Bus1->kVBase / DenomLL; + puV2 = cabs(csub(with4->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))], with4->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs2))])) / Bus2->kVBase / DenomLL; + } + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s", PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + } + break; + default: // plot just the selected phase + iphs = PhasesToPlot; + if ((Bus1->FindIdx(iphs) > 0) && (Bus2->FindIdx(iphs) > 0)) + { + if (Bus1->kVBase < 1.0) + LineType = psDot; + else + LineType = psSolid; + MyColor = ColorArray[iphs - 1]; + puV1 = cabs(with0->Solution->NodeV[Bus1->GetRef(Bus1->FindIdx(iphs))]) / Bus1->kVBase / DenomLN; + puV2 = cabs(with0->Solution->NodeV[Bus2->GetRef(Bus2->FindIdx(iphs))]) / Bus2->kVBase / DenomLN; + AddNewLine(Bus1->DistFromMeter * LenScale, puV1, Bus2->DistFromMeter * LenScale, puV2, MyColor, 2, LineType, + Dots, Format("%s.%s", PresentCktElement->ParentClass->Class_Name.c_str(), PresentCktElement->get_Name().c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + } + } + } + PresentCktElement = (TDSSCktElement*) ActiveEnergyMeter->BranchList->Get_Forward(); + } + iEnergyMeter = EnergyMeterClass[ActiveActor]->Get_Next(); + } + Set_KeepAspectRatio(false); + Set_AutoRange(2.0); // 2% rim + Get_Properties(DSSGraphProps); + + /*# with DSSGraphProps, ActiveCircuit[ActiveActor] do */ + { + auto with5 = ActiveCircuit[ActiveActor]; + auto with6 = DSSGraphProps; + { + // AddNewLine(0.0, NormalMaxVolts, Xmax, NormalMaxVolts, ColorArray[1], 1, psDash, FALSE, 'Upper Limit', False, 0,0,0); + // AddNewLine(0.0, NormalMinvolts, Xmax, NormalMinvolts, ColorArray[1], 1, psDash, FALSE, 'Lower Limit', False, 0,0,0); + + // --deprecated-- Get_Range(RangeLoX, RangeHiX, RangeLoY, RangeHiY); + RangeLoY = 0.90 * RangeScale; + RangeHiY = 1.10 * RangeScale; + with6->Xmin = 0.0; + Set_Range(with6->Xmin, with6->Xmax, RangeLoY, RangeHiY); + + /* Keep this range for quick resetting */ + // --deprecated-- Xmin := RangeLoX; + // --deprecated-- Xmax := RangeHiX; + with6->Ymin = RangeLoY; + with6->YMax = RangeHiY; + Set_LineWidth(3); + Set_DataColor(0x000000FF); + MoveTo(0.0, with5->NormalMaxVolts * RangeScale); + DrawTo(with6->Xmax, with5->NormalMaxVolts * RangeScale); + MoveTo(0.0, with5->NormalMinVolts * RangeScale); + DrawTo(with6->Xmax, with5->NormalMinVolts * RangeScale); + } + } + + Set_Properties(DSSGraphProps); + Set_AutoRange(2.0); // 2% rim + //**** ShowGraph; + } + + + void TDSSPlot::MarkSpecialClasses() + /* + Place markers at certain locations for special types of devices + */ + { + if (ActiveCircuit[ActiveActor]->MarkTransformers) + MarkTheTransformers(); + if (ActiveCircuit[ActiveActor]->MarkCapacitors) + MarkTheCapacitors(); + if (ActiveCircuit[ActiveActor]->MarkRegulators) + MarkTheRegulators(); + if (ActiveCircuit[ActiveActor]->MarkPVSystems) + MarkThePVSystems(); + // If ActiveCircuit[ActiveActor].MarkPVSystems2 Then MarkThePVSystems2; + if (ActiveCircuit[ActiveActor]->MarkStorage) + MarkTheStorage(); + // If ActiveCircuit[ActiveActor].MarkStorage2 Then MarkTheStorage2; + if (ActiveCircuit[ActiveActor]->MarkFuses) + MarkTheFuses(); + if (ActiveCircuit[ActiveActor]->MarkReclosers) + MarkTheReclosers(); + if (ActiveCircuit[ActiveActor]->MarkRelays) + MarkTheRelays(); + if (ShowSubs) + MarkSubTransformers(); + AddBusMarkers(); + } + + + void TDSSPlot::MarkSubTransformers() + { + /* Mark Locations of Substation Transformers */ + pTransf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + Set_LineWidth(4); + while (pTransf != nullptr) + { + if (pTransf->FEnabled) + if (pTransf->IsSubstation) + { + Bus2Idx = pTransf->Terminals[2 - 1].BusRef - 1; + if (Bus2Idx > 0) + if (ActiveCircuit[ActiveActor]->Buses[Bus2Idx]->CoordDefined) + { + AddNewMarker(ActiveCircuit[ActiveActor]->Buses[Bus2Idx]->x, ActiveCircuit[ActiveActor]->Buses[Bus2Idx]->y, 0x000000FF, 36, 4); + if (Length(pTransf->SubstationName) > 0) + AddNewText(ActiveCircuit[ActiveActor]->Buses[Bus2Idx]->x, ActiveCircuit[ActiveActor]->Buses[Bus2Idx]->y, 0x00000000, 10, (" " + pTransf->SubstationName)); + } + } + pTransf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + } + + + void TDSSPlot::MarkTheCapacitors() + { + TCapacitorObj* pCapacitor = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + + pCapacitor = (TCapacitorObj*) ActiveCircuit[ActiveActor]->ShuntCapacitors.Get_First(); + while (pCapacitor != nullptr) + { + if (pCapacitor->FEnabled) + { + BusIdx = pCapacitor->Terminals[1 - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x000000FF, with0->CapMarkerCode, with0->CapMarkerSize); + } + } + } + } + pCapacitor = (TCapacitorObj*) ActiveCircuit[ActiveActor]->ShuntCapacitors.Get_Next(); + } + } + + + void TDSSPlot::MarkTheFuses() + { + TFuseObj* pFuse = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + TFuse* FuseClass = nullptr; + + FuseClass = (TFuse*) GetDSSClassPtr("fuse"); + + pFuse = (TFuseObj*) FuseClass->ElementList.Get_First(); + while (pFuse != nullptr) + { + if (pFuse->FEnabled) + if (pFuse->FControlledElement->Drawn) + { + BusIdx = pFuse->FControlledElement->Terminals[pFuse->ElementTerminal - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x000000FF, with0->FuseMarkerCode, with0->FuseMarkerSize); + } + } + } + } + pFuse = (TFuseObj*) FuseClass->ElementList.Get_Next(); + } + } + + + void TDSSPlot::MarkTheReclosers() + { + TRecloserObj* pRecloser = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + /* Mark only reclosers on Lines that are in the circuit*/ + pRecloser = (TRecloserObj*) RecloserClass->ElementList.Get_First(); + while (pRecloser != nullptr) + { + if (pRecloser->FEnabled) + { + if (pRecloser->FControlledElement->Drawn) + { + BusIdx = pRecloser->FControlledElement->Terminals[pRecloser->ElementTerminal - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x0000FF00, with0->RecloserMarkerCode, with0->RecloserMarkerSize); + } + } + } + } + } + pRecloser = (TRecloserObj*) RecloserClass->ElementList.Get_Next(); + } + } + + + void TDSSPlot::MarkTheRelays() + { + TRelayObj* pRelay = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + TRelay* RelayClass = nullptr; + + RelayClass = (TRelay*) GetDSSClassPtr("Relay"); + + pRelay = (TRelayObj*) RelayClass->ElementList.Get_First(); + while (pRelay != nullptr) + { + if (pRelay->FEnabled) + { + if (pRelay->FControlledElement->Drawn) + { + BusIdx = pRelay->FControlledElement->Terminals[pRelay->ElementTerminal - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x00000080, with0->RelayMarkerCode, with0->RelayMarkerSize); + } + } + } + } + } + pRelay = (TRelayObj*) RelayClass->ElementList.Get_Next(); + } + } + + + void TDSSPlot::MarkThePVSystems() + { + TPVsystemObj* pPVSystem = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + + pPVSystem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_First(); + while (pPVSystem != nullptr) + { + if (pPVSystem->FEnabled) + { + BusIdx = pPVSystem->Terminals[1 - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x000000FF, with0->PVMarkerCode, with0->PVMarkerSize); + } + } + } + } + pPVSystem = (TPVsystemObj*) ActiveCircuit[ActiveActor]->PVSystems.Get_Next(); + } + } + + + void TDSSPlot::MarkTheStorage() + { + TStorageObj* pStorage = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + + pStorage = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_First(); + while (pStorage != nullptr) + { + if (pStorage->FEnabled) + { + BusIdx = pStorage->Terminals[1 - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x000000FF, with0->StoreMarkerCode, with0->StoreMarkerSize); + } + } + } + } + pStorage = (TStorageObj*) ActiveCircuit[ActiveActor]->StorageElements.Get_Next(); + } + } + + + void TDSSPlot::MarkTheRegulators() + { + TRegControlObj* pRegControl = nullptr; + TTransfObj* pXfmr = nullptr; + int BusIdx = 0; + TDSSBus* MyBus = nullptr; + + pRegControl = (TRegControlObj*) ActiveCircuit[ActiveActor]->RegControls.Get_First(); + while (pRegControl != nullptr) + { + if (pRegControl->FEnabled) + { + pXfmr = pRegControl->Get_Transformer(); + BusIdx = pXfmr->Terminals[pRegControl->Get_Winding() - 1].BusRef - 1; + if (BusIdx > 0) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + { + MyBus = with0->Buses[BusIdx]; + if (MyBus->CoordDefined) + { + AddNewMarker(MyBus->x, MyBus->y, 0x000000FF, with0->RegMarkerCode, with0->RegMarkerSize); + } + } + } + } + pRegControl = (TRegControlObj*) ActiveCircuit[ActiveActor]->RegControls.Get_Next(); + } + } + + + void TDSSPlot::MarkTheTransformers() + { + int Bus1Idx = 0; + int Bus2Idx = 0; + double Xtr = 0.0, + Ytr = 0.0; + /* Mark Locations of Transformers */ + pTransf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_First(); + Set_LineWidth(1); + while (pTransf != nullptr) + { + if (pTransf->FEnabled) + if (!pTransf->IsSubstation) + { + Bus1Idx = pTransf->Terminals[1 - 1].BusRef - 1; + Bus2Idx = pTransf->Terminals[2 - 1].BusRef - 1; + if ((Bus1Idx > 0) && (Bus2Idx > 0)) + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + if (with0->Buses[Bus1Idx]->CoordDefined || with0->Buses[Bus2Idx]->CoordDefined) + { + if (with0->Buses[Bus1Idx]->CoordDefined && with0->Buses[Bus2Idx]->CoordDefined) + { + Xtr = (with0->Buses[Bus1Idx]->x + with0->Buses[Bus2Idx]->x) / 2.0; + Ytr = (with0->Buses[Bus1Idx]->y + with0->Buses[Bus2Idx]->y) / 2.0; + } + else + if (with0->Buses[Bus1Idx]->CoordDefined) + { + Xtr = with0->Buses[Bus1Idx]->x; + Ytr = with0->Buses[Bus1Idx]->y; + } + else + { + Xtr = with0->Buses[Bus2Idx]->x; + Ytr = with0->Buses[Bus2Idx]->y; + } + AddNewMarker(Xtr, Ytr, 0x000000FF, with0->TransMarkerCode, with0->TransMarkerSize); + } + } + } + pTransf = (TTransfObj*) ActiveCircuit[ActiveActor]->Transformers.Get_Next(); + } + } + + /* TGenPlotItem */ + + /* + TGenPlotItem::TGenPlotItem() + { + Value = 0; + Name.clear(); + } + + + TGenPlotItem::~TGenPlotItem() + { + Name = ""; + // todo check: inherited::Destroy(); + } + + /* TGenPlotItemList */ + + /* + TGenPlotItemList::~TGenPlotItemList() + { + int i = 0; + for (int stop = size() - 1, i = 0; i <= stop; i++) + delete ((TGenPlotItem*)items[i]); + + // todo check: inherited::Destroy(); + } + */ + + String TDSSPlot::QuantityString() + { + String result; + switch (Quantity) + { + case pqVoltage: + result = "Voltage"; + break; + case pqPower: + result = "Power"; + break; + case pqCurrent: + result = "Current"; + break; + case pqLosses: + result = "Loss Density"; + break; + case pqCapacity: + result = "Capacity"; + break; + case pqNone: + { + if (PlotType == ptGeneralCircuitPlot) + result = FGeneralCircuitPlotQuantity; + else + result = ""; + } + break; + default: + result = ""; + } + return result; + } + + + void TDSSPlot::SetMaxScale() + { + if (!MaxScaleIsSpecified) + switch (Quantity) + { + case pqVoltage: + { + } + break; + case pqLosses: + { + MaxScale = 0.0; + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != nullptr) + { + if (pLine->FEnabled) + /*# with pLine do */ + { + // ----ActiveTerminalIdx := 1; + MaxScale = max(MaxScale, abs(double(pLine->Get_Losses(ActiveActor).re) / pLine->Len)); + } + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + MaxScale = MaxScale * 0.001; + } + break; + case pqPower: + { + MaxScale = 0.0; + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != nullptr) + { + if (pLine->FEnabled) + /*# with pLine do */ + { + // ----ActiveTerminalIdx := 1; + MaxScale = max(MaxScale, abs(pLine->Get_Power(1, ActiveActor).re)); + } + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + MaxScale = MaxScale * 0.001; + } + break; + case pqCurrent: + { + } + break; + case pqCapacity: + { + } + break; + case pqNone: + { + if (PlotType == ptGeneralCircuitPlot) + { + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != nullptr) + { + if (pLine->FEnabled) + /*# with pLine do */ + { + // ----ActiveTerminalIdx := 1; + MaxScale = max(MaxScale, abs(pLine->GeneralPlotQuantity)); + } + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + } + } + break; + default: + break; + } + } + + + void TDSSPlot::DoGeneralCircuitPlot() + { + TPenStyle LineStyleType; + + /* Draw the lines With the thickness proportional to the data loaded in the general line data file */ + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + /*# with ActiveCircuit[ActiveActor] do */ + { + auto with0 = ActiveCircuit[ActiveActor]; + while (pLine != nullptr) + { + if (pLine->FEnabled) + { + pLine->Drawn = true; + with0->Set_ActiveCktElement(pLine); + Bus1Idx = pLine->Terminals[1 - 1].BusRef - 1; + Bus2Idx = pLine->Terminals[2 - 1].BusRef - 1; + if (with0->Buses[Bus1Idx]->CoordDefined && with0->Buses[Bus2Idx]->CoordDefined) + { + if (pLine->IsSwitch) + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, TColor(0x0080FF), 1, Style(1), Dots, Format("Line.%s", pLine->LName.c_str()), with0->MarkSwitches, with0->SwitchMarkerCode, with0->NodeMarkerCode, with0->NodeMarkerWidth); + else + if (pLine->IsIsolated) + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, 0x00FF00FF, 3, Style(1), Dots, Format("Line.%s", pLine->LName.c_str()), with0->MarkSwitches, with0->SwitchMarkerCode, with0->NodeMarkerCode, with0->NodeMarkerWidth); + else + { + if (pLine->Fnphases == 1) + LineStyleType = Style(SinglePhLineStyle); + else + LineStyleType = Style(ThreePhLineStyle); + AddNewLine(with0->Buses[Bus1Idx]->x, with0->Buses[Bus1Idx]->y, with0->Buses[Bus2Idx]->x, with0->Buses[Bus2Idx]->y, GetColor(), Thickness(), LineStyleType, Dots, Format("Line.%s", pLine->LName.c_str()), false, 0, with0->NodeMarkerCode, with0->NodeMarkerWidth); + } + if (Labels) + DoBusLabels(Bus1Idx + 1, Bus2Idx + 1); + } + } + pLine = (TLineObj*) with0->Lines.Get_Next(); + } + } + // AddBusMarkers; // Add default bus markers to line plot + } + + + void TDSSPlot::LoadGeneralLineData() + { + TTextRec F; + String Line = ""; + String Param = ""; + String LineNm = ""; + int i = 0; + TLine* LineClass = nullptr; + double MaxValue = 0.0; + double MinValue = 0.0; + bool IsLine = false; + + + LineClass = (TLine*) DSSClassList[ActiveActor].Get(ClassNames[ActiveActor].Find("Line")); + + /* Initialize General Line Quantity */ + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_First(); + while (pLine != NULL) + { + if (pLine->FEnabled) + pLine->GeneralPlotQuantity = 0.0; + pLine = (TLineObj*) ActiveCircuit[ActiveActor]->Lines.Get_Next(); + } + try + { + AssignFile(F, ObjectName); + Reset(F); + IOResultToException(); + ReadLn(F, Line); // Get FieldName + AuxParser[ActiveActor]->SetCmdString(Line); + AuxParser[ActiveActor]->GetNextParam(); /* Bus Name */ + for (int stop = ValueIndex, i = 1; i <= stop; i++) + AuxParser[ActiveActor]->GetNextParam(); + FGeneralCircuitPlotQuantity = AuxParser[ActiveActor]->MakeString_(); + + /* Find min and max */ + MaxValue = -1.0E50; + MinValue = 1.0E50; + while (!Eof(F)) + { + ReadLn(F, Line); + if (Line.size() > 0) + { + AuxParser[ActiveActor]->SetCmdString(Line); + AuxParser[ActiveActor]->GetNextParam(); /* Branch Name */ + Param = AuxParser[ActiveActor]->MakeString_(); + + /* Look for a line with this name */ + IsLine = true; + if (Param.find(".") != String::npos) + { + if (CompareTextShortest(Param, "line") == 0) + LineNm = Param.substr(Param.find(".") + 1, Param.size()); + else + IsLine = false; + } + else + LineNm = Param; + if (IsLine) + if (LineClass->SetActive(LineNm)) + { + for (int stop = ValueIndex, i = 1; i <= stop; i++) + AuxParser[ActiveActor]->GetNextParam(); + if (Length(AuxParser[ActiveActor]->MakeString_()) > 0) + { /* Ignore empty fields */ + /*# with TLineObj(LineClass.GetActiveObj) do */ + { + auto with0 = (TLineObj*) LineClass->GetActiveObj(); + { + with0->GeneralPlotQuantity = AuxParser[ActiveActor]->MakeDouble_(); + MaxValue = max(with0->GeneralPlotQuantity, MaxValue); + MinValue = min(with0->GeneralPlotQuantity, MinValue); + } + } + } + } + } + } /* WHILE */ + } + catch (...) + { + } + CloseFile(F); + } + + + void GetS(int Ncond, int Quantity, String S1, String S2, pComplexArray cBuffer, int k, double* kVBase1) + { + switch (Quantity) + { + case vizPOWER: + { + S1 = Format("%-.6g + j", cBuffer[k].re); + S2 = Format("%-.6g kVA", cBuffer[k].im); + } + break; + case vizVOLTAGE: + { + if (k <= Ncond) + S1 = Format("%-.6g", cabs(cBuffer[k]) / kVBase1[1 - 1]); + else + S1 = Format("%-.6g", cabs(cBuffer[k]) / kVBase1[2 - 1]); + S2 = Format(" /_ %8.2f", cdang(cBuffer[k])); + } + break; + default: + S1 = Format("%-.6g", cabs(cBuffer[k])); + S2 = Format(" /_ %8.2f", cdang(cBuffer[k])); + } + } + + + void DrawArrow(double Y, const String Txt1, const String Txt2, int iopt, double Xmx, String arrowLeft, String arrowright) + { + Set_FontStyle(2); + if (iopt == 1) + { + MoveTo(0.0, Y); + DrawTo(100.0, Y); + CenteredText15(15.0, (Y + 2.0), 10, Txt1); + CenteredText15(60.0, (Y + 2.0), 10, Txt2); + CenteredText15(90.0, (Y + 2.0), 10, arrowright); + + // idx := AddTextLabel(50.0, (Y+1.0), clBlack, , 0); + } + else + { + MoveTo(Xmx, Y); + DrawTo(Xmx - 100.0, Y); + CenteredText15(Xmx - 90.0, (Y + 2.0), 10, arrowLeft); + CenteredText15(Xmx - 60.0, (Y + 2.0), 10, Txt1); + CenteredText15(Xmx - 20.0, (Y + 2.0), 10, Txt2); + // idx := AddTextLabel(Xmx-50, (Y+1.0), clBlack, Arrowleft+Txt, 0); + } + + // TextLabels[idx].Font.Style := [fsBold]; + + + /* ------------------------------------------------------------------- */ + /* Plot Lines representing the phases and ground */ + } + + + void TDSSPlot::DoVisualizationPlot(TDSSCktElement* Element, int Quantity) + { + vector cBuffer; + int Nterm = 0, Ncond = 0; + double kVBase1[3/*# range 1..2*/] = {}; + double TopY = 0.0, + Xmx = 0.0; + double xx = 0.0; + int i = 0, + j = 0, + k = 0; + int Idx = 0; + String S1 = "", + S2 = "", + S = "", + arrowLeft = "", + arrowright = ""; + String Fname = ""; + bool CBufferAllocated = false; + complex cResidual = CZero; + + + TDSSGraphProperties* ActiveGraphProps = new TDSSGraphProperties; + + // RangeLoX, RangeHiX, RangeLoY, RangeHiY: Double; + + /* ----------------------INTERNAL FUNCTIONS--------------------------- */ + Ncond = Element->Fnconds; + Nterm = Element->Fnterms; + CBufferAllocated = false; + Element->ComputeIterminal(ActiveActor); + Element->ComputeVterminal(ActiveActor); + Xmx = 300.0; // don't use Xmax -- already used + for (int stop = 2, i = 1; i <= stop; i++) + kVBase1[i - 1] = 1.0; + switch (Quantity) + { + case vizVOLTAGE: + { + arrowLeft = "^ "; + arrowright = " ^"; + } + break; + default: + arrowLeft = "<- "; + arrowright = " ->"; + } + Fname = GetOutputDirectory() + CircuitName_[ActiveActor]; + switch (Quantity) + { + case vizVOLTAGE: + { + Fname = Fname + Format("%s_%s_V.DSV", Element->ParentClass->Class_Name.c_str(), Element->LName.c_str()); + cBuffer = Element->Vterminal; + for (int stop = min(2, Nterm), i = 1; i <= stop; i++) + kVBase1[i - 1] = max(1.0, 1000.0 * ActiveCircuit[ActiveActor]->Buses[Element->Terminals[i - 1].BusRef - 1]->kVBase); + } + break; + case vizCURRENT: + { + Fname = Fname + Format("%s_%s_I.DSV", Element->ParentClass->Class_Name.c_str(), Element->LName.c_str()); + cBuffer = Element->Iterminal; + } + break; + case vizPOWER: + { + Fname = Fname + Format("%s_%s_PQ.DSV", Element->ParentClass->Class_Name.c_str(), Element->LName.c_str()); + cBuffer.resize(Element->Yorder + 1); + CBufferAllocated = true; + /*# with Element do */ + { + for (int stop = Element->Yorder, i = 1; i <= stop; i++) + cBuffer[i] = cmulreal(cmul(Element->Vterminal[i - 1], conjg(Element->Iterminal[i - 1])), 0.001); + } + } + break; + } + if (MakeNewGraph(Fname) == 0) + { + DoSimpleMsg("Make New Plot failed in DSSPlot - visualization plot.", 8734); + return; + } + Get_Properties(ActiveGraphProps); + xx = 0.0; + /*# with ActiveGraphProps do */ + { + auto with3 = ActiveGraphProps; + with3->ChartColor = 0x00FFFFFF; + with3->WindColor = 0x00FFFFFF; + with3->GridStyle = gsNone; + Set_NoScales(); // Set for no scales on X or Y + S1 = Element->ParentClass->Class_Name + "." + UpperCase(Element->LName); + switch (Quantity) + { + case vizVOLTAGE: + S = S1 + " Voltages"; + break; + case vizCURRENT: + S = S1 + " Currents"; + break; + case vizPOWER: + S = S1 + " Powers"; + break; + } + Set_Caption(S); + Set_ChartCaption(S); + + /* Draw a box */ + TopY = 10.0 + (Ncond + 1) * 10.0; + Rectangle(100.0, 10.0, Xmx - 100.0, TopY); + Idx = AddTextLabel(Xmx / 2.0, 15.0, 0x00000000, S1, 0); + BoldTextLabel(Idx); + + /* Draw the Ground Plane */ + Set_LineWidth(7); + Set_DataColor(0x00808080); + MoveTo(0.0, 0.0); + DrawTo(Xmx, 0.0); + Set_DataColor(0x00000000); + + /* Put the Quantities on The Box */ + k = 0; + for (int stop = min(2, Nterm), i = 1; i <= stop; i++) + { + Set_LineWidth(3); + for (int stop = Element->Fnphases, j = 1; j <= stop; j++) + { + k++; + GetS(Ncond, Quantity, S1, S2, &(cBuffer[0]), k, kVBase1); + DrawArrow(TopY - j * 10.0, S1, S2, i, Xmx, arrowLeft, arrowright); + } + Set_LineWidth(1); + for (int stop = Ncond, j = Element->Fnphases + 1; j <= stop; j++) + { + k++; + GetS(Ncond, Quantity, S1, S2, &(cBuffer[0]), k, kVBase1); + DrawArrow(TopY - j * 10.0, S1, S2, i, Xmx, arrowLeft, arrowright); + } + + /* Add Residual Current */ + if (Quantity == vizCURRENT) + { + cResidual = CZero; + for (int stop = Ncond, j = 1; j <= stop; j++) + caccum(cResidual, cnegate(cBuffer[j + (i - 1) * Ncond])); + S1 = Format("%-.6g", cabs(cResidual)); + S2 = Format(" /_ %8.2f", cdang(cResidual)); + DrawArrow(-10.0, S1, S2, i, Xmx, arrowLeft, arrowright); + } + + /* Draw Bus and Label */ + Set_LineWidth(7); + switch (i) + { + case 1: + xx = -5.0; + break; + case 2: + xx = Xmx + 5.0; + break; + } + MoveTo(xx, 5.0); + DrawTo(xx, TopY - 5.0); + switch (i) + { + case 1: + xx = 25; + break; + case 2: + xx = Xmx - 25.0; + break; + } + CenteredText15(xx, TopY, 10, UpperCase(Element->GetBus(i))); + } + switch (Quantity) + { + case vizVOLTAGE: + S = " Voltages"; + break; + case vizCURRENT: + S = " Currents"; + break; + case vizPOWER: + S = " Powers"; + break; + } + Set_Caption(S); + Set_AutoRange(5.0); // 5% rim + + /* OLD WAY + With ActiveGraphProps Do Begin + + Get_Range(RangeLoX, RangeHiX, RangeLoY, RangeHiY); + + {Keep this range for quick resetting} + Xmin := RangeLoX; + Xmax := RangeHiX; + Ymin := RangeLoY; + Ymax := RangeHiY; + End; + Set_Properties(ActiveGraphProps); + */ + ShowGraph(); + } + if (CBufferAllocated) + cBuffer.clear(); + } + + void TDSSPlot::Set_MaxLineThickness(const int Value) + { + if (Value > 0) + FMaxLineThickness = Value; + } + + void DSSPlot_initialization() + { + DSSPlotObj = nullptr; // Instantiate only if Plot command issued + SinglePhLineStyle = 1; + ThreePhLineStyle = 1; + } + + + + void DSSPlot_finalization() + { + if ((DSSPlotObj != nullptr)) + delete DSSPlotObj; + } + + class DSSPlot_unit + { + public: + DSSPlot_unit() + { + DSSPlot_initialization(); + } + ~DSSPlot_unit() { DSSPlot_finalization(); } + }; + DSSPlot_unit _DSSPlot_unit; + +} // namespace DSSPlot \ No newline at end of file diff --git a/OpenDSSC/Plot/DSSPlot.h b/OpenDSSC/Plot/DSSPlot.h new file mode 100644 index 0000000..db4a41e --- /dev/null +++ b/OpenDSSC/Plot/DSSPlot.h @@ -0,0 +1,195 @@ +#ifndef DSSPlotH +#define DSSPlotH +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + Unit for interfacing to Plotting form + 3/29/03 + 8/13/2008 +*/ +/*$M+*/ +/*$WARN UNIT_PLATFORM OFF*/ + + +#include "System.h" + +#include "Line.h" +#include "Transformer.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "CktElement.h" +#include "DSSCallBackRoutines.h" +#include "d2c_structures.h" + +namespace DSSPlot +{ + + class TDSSPlot; + class TGenPlotItem; + class TGenPlotItemList; + typedef unsigned char unsignedchar; + + + const int vizCURRENT = 1; + const int vizVOLTAGE = 2; + const int vizPOWER = 3; + + + enum TPlotType { + ptAutoAddLogPlot, + ptCircuitplot, + ptGeneralDataPlot, + ptGeneralCircuitPlot, + ptmonitorplot, + ptdaisyplot, + ptMeterZones, + ptLoadShape, + ptTShape, + ptPriceShape, + ptProfile, + ptScatterPlot, + ptEvolutionPlot, + ptEnergyPlot, + ptMatrixplot, + ptPhaseVoltage + }; + enum TPlotQuantity { + pqVoltage, + pqCurrent, + pqPower, + pqLosses, + pqCapacity, + pqNone + }; + enum TMatrixType { + pIncMatrix, + pLaplacian + }; // The types of matrices that can be plotted + + + class TDSSPlot : public TObject { + typedef TObject inherited; + friend class TGenPlotItem; + public: + int ActiveColorIdx; + int ColorArray[17/*# range 1..17*/]; + TLineObj* pLine; + TTransfObj* pTransf; + int Bus1Idx, Bus2Idx; + String FGeneralCircuitPlotQuantity; + int FMaxLineThickness; + + /* Main procedures for the various types of plots ... called from execute */ + void DoGeneralPlot(); + void DoAutoAddPlot(); + void DoTheDaisies(); + void DoCircuitPlot(); + void DoGeneralCircuitPlot(); + void DoMeterZonePlot(); + void DoMonitorPlot(); + void DoProfilePlot(); + + /* Misc support procedures */ + void MarkSubTransformers(); + void MarkTheTransformers(); + void MarkTheCapacitors(); + void MarkTheRegulators(); + void MarkThePVSystems(); + // procedure MarkThePVSystems2; + void MarkTheStorage(); + // procedure MarkTheStorage2; + void MarkTheFuses(); + void MarkTheReclosers(); + void MarkTheRelays(); + void MarkSpecialClasses(); + void DoBusLabels(const int Idx1, const int Idx2); + void DoBusLabel(const int Idx, const String BusLabel); + void LabelBuses(); + void LoadGeneralLineData(); + void SetColorArray(); + void SetMaxScale(); + void AddBusMarkers(); + int GetColor(); + int Thickness(); + double MaxCurrent(); + int NextColor(); + String QuantityString(); + int Style(int Code); + int GetAutoColor(double Scale); + unsignedchar GetMarker(int Idx); + bool CoordinateSame(int i1, int i2); + int InterpolateGradientColor(int Color1, int Color2, double Ratio); + + /* Property support */ + void Set_MaxLineThickness(const int Value); + //protected: + public: + TPlotType PlotType; + TMatrixType MatrixType; + double MaxScale, MinScale; /* applies to Meterzone plots only */ + bool Dots, Labels, ShowLoops, ShowSubs; + TPlotQuantity Quantity; + String ObjectName, FeederName; + String PlotID; + int ValueIndex, MarkerIdx; /* For General & AutoAdd */ + int PhasesToPlot; // Profile Plot + int ProfileScale; // CYMDIST or pu/km scaling + vector< unsigned int > Channels; // for Monitor Plot + vector< double > Bases; // for Monitor Plot + int Color1, Color2, Color3; + + /* Tri-color plots */ + double TriColorMax, TriColorMid; + bool MaxScaleIsSpecified; + bool MinScaleIsSpecified; + TStringList DaisyBusList; + TDSSPlot(); + virtual ~TDSSPlot(); + void Execute(); + void SetDefaults(); + void DSSVizPlot(); + void DoLoadShapePlot(const String LoadShapeName); + void DoTempShapePlot(const String TempShapeName); + void DoPriceShapePlot(const String PriceShapeName); + void DoDI_Plot(const String CaseName, int CaseYear, const int* iRegisters, int iRegisters_maxidx, bool PeakDay, const String MeterName); + void DoCompareCases(String CaseName1, String CaseName2, String WhichFile, int Reg); + void DoYearlyCurvePlot(TStringList CaseNames, String WhichFile, const int* iRegisters, int iRegisters_maxidx); + void DoVisualizationPlot(TDSSCktElement* Element, int Quantity); + }; + + + class TGenPlotItem : public TObject { + typedef TObject inherited; + public: + String Name; + double Value; + + }; + + /* List of General Plot Items */ + + + class TGenPlotItemList : public TList { + typedef TList inherited; + friend class TDSSPlot; + friend class TGenPlotItem; + + }; + + + extern TDSSPlot* DSSPlotObj; + extern int SinglePhLineStyle; + extern int ThreePhLineStyle; + +} // namespace DSSplot + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace DSSPlot; +#endif + +#endif // DSSPlotH \ No newline at end of file diff --git a/OpenDSSC/Plot/DSSView.exe b/OpenDSSC/Plot/DSSView.exe new file mode 100644 index 0000000..19899b8 Binary files /dev/null and b/OpenDSSC/Plot/DSSView.exe differ diff --git a/OpenDSSC/Shared/Arraydef.cpp b/OpenDSSC/Shared/Arraydef.cpp new file mode 100644 index 0000000..c462dcc --- /dev/null +++ b/OpenDSSC/Shared/Arraydef.cpp @@ -0,0 +1,42 @@ +//#include +#pragma hdrstop + +#include "Arraydef.h" +//#include + +using namespace std; + +namespace Arraydef +{ + + + +pStringArray AllocStringArray(int Size) +{ + pStringArray result = nullptr; + result = new std::string[ sizeof((result)[0]) * Size] ; + return result; +} +// Allocates a string array initialized with nil values + +void FreeStringArray(pStringArray& ps, int Size) +{ + int i = 0; + if(ps != nullptr) + { + int stop = 0; + for(stop = Size, i = 1; i <= stop; i++) + { + ps[i - 1] = ""; // decrement counter in string + } + delete[] ps; // Deallocate the memory + ps = nullptr; // Throw it away and set it to NIL + } +} + + +} // namespace Arraydef + + + + diff --git a/OpenDSSC/Shared/Arraydef.h b/OpenDSSC/Shared/Arraydef.h new file mode 100644 index 0000000..6b91bb7 --- /dev/null +++ b/OpenDSSC/Shared/Arraydef.h @@ -0,0 +1,60 @@ +#ifndef ArraydefH +#define ArraydefH + +#include "System.h" +#include +#include + + +namespace Arraydef +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +typedef std::vector TRatingsArray; +/* Define arrays with dummy dimension of 100 so we can hard code + constants for accessing small order elements; Otherwise, always + allocate arrays of these types before using*/ +typedef std::vector < short int > SmallIntArray; +typedef short int* pSmallIntArray; +typedef int32_t longInt; +typedef std::vector < longInt > LongIntArray; +typedef longInt* pLongIntArray; +typedef longInt* pIntegerArray; +typedef std::vector < double > DoubleArray; +typedef double* pDoubleArray; +typedef std::vector < float > SingleArray; +typedef float* pSingleArray; +typedef void * PointerArray; +typedef PointerArray* PPointerArray; +typedef std::vector < std::string > StringArray; +typedef std::string* pStringArray; +typedef std::vector DynStringArray; +typedef std::string* pDynStringArray; +typedef double* PDouble; +typedef float* PSingle; +typedef short int* PSmallInt; +typedef longInt* PLongInt; +typedef std::vector DynSlot; +pStringArray AllocStringArray(int Size); +void FreeStringArray(pStringArray &ps, int Size); +/*--------------------------------------------------------------------------*/ + + +} // namespace Arraydef + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Arraydef; +#endif + +#endif // ArraydefH + + + + diff --git a/OpenDSSC/Shared/CktTree.cpp b/OpenDSSC/Shared/CktTree.cpp new file mode 100644 index 0000000..f1662a0 --- /dev/null +++ b/OpenDSSC/Shared/CktTree.cpp @@ -0,0 +1,668 @@ +#pragma hdrstop + +#include "CktTree.h" + +#include "DSSGlobals.h" +#include "Circuit.h" + +using namespace std; + +namespace CktTree +{ + + TCktTreeNode::TCktTreeNode() {} + + + + TCktTreeNode::TCktTreeNode(TCktTreeNode* const pParent, const void* pSelfObj) + : FChildBranches(new PointerList::TPointerList(2)), + NumToBuses(0), + ToBusPtr(0), + ChildAdded(false), + LexicalLevel(0), + FParentBranch(nullptr), + FShuntObjects(nullptr), + CktObject(nullptr), + FromBusReference(0), + VoltBaseIndex(0), + FromTerminal(0), + IsLoopedHere(false), + IsParallel(false), + IsDangling(false), + LoopLineObj(nullptr) + { + ; + CktObject = const_cast(pSelfObj); + FParentBranch = const_cast(pParent); + if(FParentBranch != nullptr) + LexicalLevel = FParentBranch->LexicalLevel + 1; + else + LexicalLevel = 0; + FShuntObjects = new PointerList::TPointerList(1); + FromBusReference = 0; + VoltBaseIndex = 0; // Index to voltage base list used by energymeter and maybe others + ToBusList.clear(); + ChildAdded = false; + // TEMc - initialize some topology variables, 10/2009 + IsDangling = true; + IsLoopedHere = false; + IsParallel = false; + LoopLineObj = nullptr; + } + + TCktTreeNode::~TCktTreeNode() + { + void* pChild = nullptr; + void* pNext = nullptr; + TCktTreeNode* TempNode = nullptr; + pChild = FChildBranches->Get_First(); + while(pChild != nullptr) + { + pNext = FChildBranches->Get_Next(); + TempNode = ((TCktTreeNode*) pChild); + delete TempNode; + pChild = pNext; + } + ToBusList.clear(); + delete FChildBranches; + delete FShuntObjects; + // inherited::Destroy(); + } + + + void TCktTreeNode::Set_AddChild(TCktTreeNode* const Value) + { + FChildBranches->Set_New((void*) Value); + ChildAdded = true; + } + + void TCktTreeNode::Set_AddObject(void* Value) + { + FShuntObjects->Set_New(Value); + } + + TCktTreeNode* TCktTreeNode::Get_FirstChild() + { + TCktTreeNode* result = nullptr; + result = ((TCktTreeNode*) FChildBranches->Get_First()); + return result; + } + + TCktTreeNode* TCktTreeNode::Get_NextChild() + { + TCktTreeNode* result = nullptr; + result = ((TCktTreeNode*) FChildBranches->Get_Next()); + return result; + } + + TCktTreeNode* TCktTreeNode::Get_Parent() + { + TCktTreeNode* result = nullptr; + result = FParentBranch; + return result; + } + + TCktTree::TCktTree() + : FirstNode(nullptr), + ForwardStack(new TPstack(20)), + PresentBranch(nullptr), + ZoneEndsList(nullptr) + { + ; + PresentBranch = nullptr; + ZoneEndsList = new TZoneEndsList(); + } + + TCktTree::~TCktTree() + { + delete ForwardStack; + if(ZoneEndsList != nullptr) + delete ZoneEndsList; + if(FirstNode != nullptr) + delete FirstNode; + // inherited::Destroy(); + } + + + void TCktTree::Set_New(void* Value) + { + PresentBranch = new TCktTreeNode(PresentBranch, Value); + if(FirstNode == nullptr) + FirstNode = PresentBranch; + } + + void TCktTree::AddNewChild(void* Value, int BusRef, int TerminalNo) + { + TCktTreeNode* TempNode = nullptr; + if(PresentBranch == nullptr) + { + Set_New(Value); + } + else + { + TempNode = new TCktTreeNode(PresentBranch, Value); + /*# with TempNode do */ + { + auto with0 = TempNode; + with0->FromBusReference = BusRef; + with0->FromTerminal = TerminalNo; + } + PresentBranch->Set_AddChild(TempNode); + } + } + + void TCktTree::Set_NewObject(void* Value) + { + if(PresentBranch != nullptr) + { + PresentBranch->Set_AddObject(Value); + } + } + + void TCktTree::PushAllChildren() + { + void* pChild = nullptr; + if(PresentBranch != nullptr) + // Push all children of present node onto stack + { + pChild = PresentBranch->Get_FirstChild(); + while(pChild != nullptr) + { + ForwardStack->Push(pChild); + pChild = PresentBranch->Get_NextChild(); + } + PresentBranch->ChildAdded = false; + } + } + + void* TCktTree::Get_Forward() + { + void* result = nullptr; + // MoveForward from Present node + + // If we have added children to the present node since we opened it push em on + if(PresentBranch != nullptr) + { + if(PresentBranch->ChildAdded) + PushAllChildren(); + + // If the forward stack is empty push stuff on it to get started + } + if(ForwardStack->Size() == 0) + PushAllChildren(); + PresentBranch = ((TCktTreeNode*) ForwardStack->Pop()); + PushAllChildren(); // push all children of latest + if(PresentBranch != nullptr) + result = PresentBranch->CktObject; + else + result = nullptr; + return result; + } + + void* TCktTree::Get_Backward() + { + void* result = nullptr; + + // Move Backwardfrom Present node and reset forward stack + PresentBranch = PresentBranch->Get_Parent(); + ForwardStack->Clear(); + if(PresentBranch != nullptr) + result = PresentBranch->CktObject; + else + result = nullptr; + return result; + } + + void* TCktTree::Get_Parent() + { + void* result = nullptr; + if(PresentBranch->FParentBranch != nullptr) + result = PresentBranch->FParentBranch->CktObject; + else + result = nullptr; + return result; + } + + void* TCktTree::Get_First() + { + void* result = nullptr; + // go to beginning and reset forward stack + PresentBranch = FirstNode; + ForwardStack->Clear(); + PushAllChildren(); + if(PresentBranch != nullptr) + result = PresentBranch->CktObject; + else + result = nullptr; + return result; + } + + void* TCktTree::Get_FirstObject() + { + void* result = nullptr; + if(PresentBranch != nullptr) + result = PresentBranch->FShuntObjects->Get_First(); + else + result = nullptr; + return result; + } + + void* TCktTree::Get_NextObject() + { + void* result = nullptr; + if(PresentBranch != nullptr) + result = PresentBranch->FShuntObjects->Get_Next(); + else + result = nullptr; + return result; + } + + void* TCktTree::Get_Active() + { + void* result = nullptr; + if(PresentBranch != nullptr) + result = PresentBranch->CktObject; + else + result = nullptr; + return result; + } + + void TCktTree::Set_Active(void* P) + { + void* Temp = nullptr; + Temp = Get_First(); + while(Temp != nullptr) + { + if(PresentBranch->CktObject == P) + break; + Temp = Get_Forward(); + } + ForwardStack->Clear(); + } + + void TCktTree::StartHere() + { + ForwardStack->Clear(); + if(PresentBranch != nullptr) + ForwardStack->Push(PresentBranch); + } + + int TCktTree::Get_Level() + { + int result = 0; + if(PresentBranch != nullptr) + result = PresentBranch->LexicalLevel; + else + result = 0; + return result; + } + + int TCktTreeNode::Get_NumChildren() + { + int result = 0; + result = FChildBranches->get_myNumList(); + return result; + } + + int TCktTreeNode::Get_NumObjects() + { + int result = 0; + result = FShuntObjects->get_myNumList(); + return result; + } + + /* TZoneEndsList */ + + void TZoneEndsList::Add(TCktTreeNode* const Node, int EndBusRef) + { + ++NumEnds; + EndNodeList->Set_New((void*) Node); + EndBuses = (pIntegerArray) realloc(EndBuses, sizeof(EndBuses) * NumEnds); + EndBuses[NumEnds - 1] = EndBusRef; + } + + TZoneEndsList::TZoneEndsList() + : EndNodeList(new PointerList::TPointerList(10)), + NumEnds(0) + { + EndBuses = NULL; + NumEnds = 0; + } + + TZoneEndsList::~TZoneEndsList() + { + delete EndNodeList; + EndBuses = (pIntegerArray) realloc(EndBuses, 0); + // inherited; + } + + + int TZoneEndsList::Get(int i, TCktTreeNode*& Node) + { + int result = 0; + Node = ((TCktTreeNode*) EndNodeList->Get(i)); + result = EndBuses[i - 1]; + return result; + } + /*Sequentially access the To Bus list if more than one with each invocation of the property*/ + + int TCktTreeNode::Get_ToBusReference() + { + int result = 0; + if(NumToBuses == 1) + { + result = ToBusList[1 - 1]; // Always return the first + } + else + { + ++ToBusPtr; + if(ToBusPtr > NumToBuses) + { + result = -1; + ToBusPtr = 0; // Ready for next sequence of access + } + else + result = ToBusList[ToBusPtr - 1]; + } + return result; + } + + void TCktTreeNode::Set_ToBusReference(int Value) + { + ++NumToBuses; +// ToBusList.resize(NumToBuses); + ToBusList.push_back(Value); + } + + void TCktTreeNode::ResetToBusList() + { + ToBusPtr = 0; + } + + void* TCktTreeNode::Get_FirstObject() + { + void* result = nullptr; + result = FShuntObjects->Get_First(); + return result; + } + + void* TCktTreeNode::Get_NextObject() + { + void* result = nullptr; + result = FShuntObjects->Get_Next(); + return result; + } + + //////////////////////////////////////////////////////////////////////// + // + // utility code for building a connected tree starting from a circuit element + // + //////////////////////////////////////////////////////////////////////// + + // sources are excluded from the PC element list, so this is a brute-force search + + void GetSourcesConnectedToBus(int BusNum, TCktTree* BranchList, bool Analyze) + { + TPCElement* PSrc = nullptr; // Sources are special PC elements + /*# with ActiveCircuit[ActiveActor] do */ + { + + PSrc = ((TPCElement*) ActiveCircuit[ActiveActor]->Sources.Get_First()); + while(PSrc != nullptr) + { + if( ( (TDSSCktElement*) PSrc )->Get_Enabled()) + { + if(Analyze || (!((TDSSCktElement*)PSrc)->Checked)) + { + if((((TDSSCktElement*)PSrc)->Terminals)[0].BusRef == BusNum) // ?Connected to this bus ? + { + if(Analyze) + { + ((TDSSCktElement*)PSrc)->IsIsolated = false; + BranchList->PresentBranch->IsDangling = false; + } + if(!((TDSSCktElement*)PSrc)->Checked) + { + BranchList->Set_NewObject(PSrc); + ((TDSSCktElement*)PSrc)->Checked = true; + } + } + } + } + PSrc = ((TPCElement*) ActiveCircuit[ActiveActor]->Sources.Get_Next()); + } + }/*With*/ + } + + void GetPCElementsConnectedToBus(TList* adjLst, TCktTree* BranchList, bool Analyze) + { + TDSSCktElement* P = nullptr; + int i = 0; + int stop = 0; + for(stop = adjLst->size() - 1, i = 0; i <= stop; i++) + { + P = (TDSSCktElement*) (*adjLst)[i]; + if(P->Get_Enabled()) + { + if(Analyze) + { + P->IsIsolated = false; + BranchList->PresentBranch->IsDangling = false; + } + if(!P->Checked) + { + BranchList->Set_NewObject(P); + P->Checked = true; + } + } + } + } + + void FindAllChildBranches(TList* adjLst, int BusNum, TCktTree* BranchList, bool Analyze, TDSSCktElement* ActiveBranch) + { + int i = 0; + int j = 0; + TDSSCktElement* P = nullptr; + int stop = 0; + + for(stop = adjLst->size() - 1, i = 0; i <= stop; i++) + { + P = ((TDSSCktElement*)(*adjLst)[i]); + if(P->Get_Enabled() && !(P == ActiveBranch)) + { + if(Analyze || (!P->Checked)) + { + if((!IsShuntElement(P)) && AllTerminalsClosed(P)) + { + int stop1 = 0; + for(stop1 = P->Get_NTerms(), j = 1; j <= stop1; j++) + { + if(BusNum == ((P->Terminals)[ j - 1 ].BusRef)) + { + if(Analyze) + { + P->IsIsolated = false; + BranchList->PresentBranch->IsDangling = false; + if(P->Checked && (BranchList->Get_Level() > 0)) + { + BranchList->PresentBranch->IsLoopedHere = true; + BranchList->PresentBranch->LoopLineObj = P; + if(IslineElement(P) && IslineElement(ActiveBranch)) + { + if(CheckParallel(ActiveBranch, P)) + BranchList->PresentBranch->IsParallel = true; + } + } + } + if(!P->Checked) + { + BranchList->AddNewChild(P, BusNum, j); + (P->Terminals)[ j - 1 ].Checked = true; + P->Checked = true; + break; + } + } + } + } + } + } + } + } + + void GetShuntPDElementsConnectedToBus(TList* adjLst, TCktTree* BranchList, bool Analyze) + { + TDSSCktElement* P = nullptr; + int i = 0; + int stop = 0; + + for(stop = adjLst->size() - 1, i = 0; i <= stop; i++) + { + P = ((TDSSCktElement*) (*adjLst)[i]); + if(P->Get_Enabled() && IsShuntElement(P)) + { + if(Analyze) + { + P->IsIsolated = false; + BranchList->PresentBranch->IsDangling = false; + } + if(!P->Checked) + { + BranchList->Set_NewObject(P); + P->Checked = true; + } + } + } + } + + TCktTree* GetIsolatedSubArea(TDSSCktElement* StartElement, bool Analyze/*# = false*/) + { + TCktTree* result = nullptr; + int TestBusNum = 0; + TCktTree* BranchList = nullptr; + int iTerm = 0; + TDSSCktElement* TestBranch = nullptr; + TDSSCktElement* TestElement = nullptr; + + TAdjArray lstPD; + TAdjArray lstPC; + + lstPD.resize(1); + lstPC.resize(1); + lstPD = ActiveCircuit[ActiveActor]->GetBusAdjacentPDLists(ActiveActor); + lstPC = ActiveCircuit[ActiveActor]->GetBusAdjacentPCLists(ActiveActor); + BranchList = new TCktTree(); + TestElement = StartElement; + BranchList->Set_New((void*) TestElement); + if(Analyze) + TestElement->IsIsolated = false; + TestElement->LastTerminalChecked = 0; // We'll check things connected to both sides + + // Check off this element so we don't use it again + TestElement->Checked = true; + + // Now start looking for other branches + // Finds any branch connected to the TestBranch and adds it to the list + // Goes until end of circuit, another energy meter, an open terminal, or disabled device. + TestBranch = TestElement; + while(TestBranch != nullptr) + { + int stop = 0; + for(stop = TestBranch->Get_NTerms(), iTerm = 1; iTerm <= stop; iTerm++) + { + if(!((TestBranch->Terminals)[iTerm - 1].Checked)) + // Now find all pc Elements connected to the bus on this end of branch + // attach them as generic objects to cktTree node. + { + TestBusNum = (TestBranch->Terminals)[iTerm - 1].BusRef; + BranchList->PresentBranch->Set_ToBusReference(TestBusNum); // Add this as a "to" bus reference + if(TestBusNum > 0) + { + ActiveCircuit[ActiveActor]->Buses[TestBusNum - 1]->BusChecked = true; + GetSourcesConnectedToBus(TestBusNum, BranchList, Analyze); + GetPCElementsConnectedToBus(&(lstPC[TestBusNum]), BranchList, Analyze); + GetShuntPDElementsConnectedToBus(&(lstPD[TestBusNum]), BranchList, Analyze); + FindAllChildBranches(&(lstPD[TestBusNum]), TestBusNum, BranchList, Analyze, TestBranch); + } + } + } /*FOR iTerm*/ + TestBranch = ((TDSSCktElement*) BranchList->Get_Forward()); + } /*WHILE*/ + result = BranchList; + return result; + } + + void BuildActiveBusAdjacencyLists(TAdjArray& lstPD, TAdjArray& lstPC, int ActorID) + { + int i = 0, + j = 0, + NBus = 0; + TDSSCktElement* pCktElement = nullptr; + int stop = 0; + NBus = ActiveCircuit[ActorID]->NumBuses; + // Circuit.Buses is effectively 1-based; bus 0 is ground + lstPD.resize(NBus + 1); + lstPC.resize(NBus + 1); + for(stop = NBus, i = 0; i <= stop; i++) + { + lstPD[i] = TList(); // default capacity should be enough + lstPC[i] = TList(); + } + pCktElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get_First()); + while(pCktElement != nullptr) + { + if(pCktElement->Get_Enabled()) + { + i = ((pCktElement->Terminals)[0].BusRef); + lstPC[i].push_back(pCktElement); + } + pCktElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PCElements.Get_Next()); + } + pCktElement = ((TDSSCktElement*)ActiveCircuit[ActorID]->PDElements.Get_First()); + //Put only eligible PDElements in the list + while (pCktElement != nullptr) + { + if(pCktElement->Get_Enabled()) + { + if(IsShuntElement(pCktElement)) + { + i = (pCktElement->Terminals)[0].BusRef; + lstPC[i].push_back(pCktElement); + } + else + { + if(AllTerminalsClosed(pCktElement)) + { + int stop = 0; + for(stop = pCktElement->Get_NTerms(), j = 1; j <= stop; j++) + { + i = (pCktElement->Terminals[ j - 1 ].BusRef); + lstPD[i].push_back(pCktElement); + } + } + } + } + pCktElement = ((TDSSCktElement*) ActiveCircuit[ActorID]->PDElements.Get_Next()); + } + } + + void FreeAndNilBusAdjacencyLists(TAdjArray& lstPD, TAdjArray& lstPC) + { + int i = 0; + int stop = 0; + for(stop = lstPD.size(), i = 0; i < stop; i++) + { + lstPD[i].clear(); + lstPC[i].clear(); + } + lstPD.clear(); + lstPC.clear(); + } + + + + +} // namespace CktTree + + + + diff --git a/OpenDSSC/Shared/CktTree.h b/OpenDSSC/Shared/CktTree.h new file mode 100644 index 0000000..a1e0b3a --- /dev/null +++ b/OpenDSSC/Shared/CktTree.h @@ -0,0 +1,140 @@ +#ifndef CktTreeH +#define CktTreeH + +#include "System.h" + +#include "Arraydef.h" +#include "StackDef.h" +#include "PointerList.h" +#include "CktElement.h" +#include "d2c_structures.h" +#include "PDElement.h" +#include "PCElement.h" + + +typedef vector TAdjArray; + +namespace CktTree +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2023, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +/* Change Log + + 8/12/99 Added level number to node +*/ + +class TCktTreeNode : public System::TObject +{ +public: + typedef TObject inherited; +//private: + PointerList::TPointerList* FChildBranches; // List of CktTreeNode pointers + int NumToBuses; + int ToBusPtr; + vector ToBusList; + TCktTreeNode* Get_FirstChild(); + TCktTreeNode* Get_NextChild(); + TCktTreeNode* Get_Parent(); + void Set_AddChild(TCktTreeNode* const Value); + void Set_AddObject(void* Value); + int Get_NumChildren(); + int Get_NumObjects(); + int Get_ToBusReference(); + void Set_ToBusReference(int Value); + void* Get_FirstObject(); + void* Get_NextObject(); +//protected: + bool ChildAdded; + int LexicalLevel; + TCktTreeNode* FParentBranch; + PointerList::TPointerList* FShuntObjects; // Generic objects attached to the tree at this node +public: + void* CktObject; // Pointer to the circuit object referenced + int FromBusReference; + int VoltBaseIndex; + int FromTerminal; + bool IsLoopedHere; + bool IsParallel; + bool IsDangling; + void* LoopLineObj; + TCktTreeNode(TCktTreeNode* const pParent, const void* pSelfObj); + virtual ~TCktTreeNode(); + void ResetToBusList(); +//__published: +public: + TCktTreeNode(); +}; + +class TZoneEndsList : public System::TObject +{ +public: + typedef TObject inherited; +private: + PointerList::TPointerList* EndNodeList; + Arraydef::pIntegerArray EndBuses; +protected: +public: + int NumEnds; + TZoneEndsList(); + virtual ~TZoneEndsList(); + void Add(TCktTreeNode* const Node, int EndBusRef); + int Get(int i, TCktTreeNode*& Node); +//__published: +}; + +class TCktTree : public System::TObject +{ +public: + typedef TObject inherited; +//private: + TCktTreeNode* FirstNode; + StackDef::TPstack* ForwardStack; + void* Get_Forward(); + void* Get_Backward(); + void* Get_First(); + void* Get_Parent(); + void* Get_FirstObject(); + void* Get_NextObject(); + void* Get_Active(); + int Get_Level(); + void Set_New(void* Value); + void Set_NewObject(void* Value); + void Set_Active(void* P); // Set present node to this value + void PushAllChildren(); +//protected: +public: + TCktTreeNode* PresentBranch; + TZoneEndsList* ZoneEndsList; + TCktTree(); + virtual ~TCktTree(); + void StartHere(); // Start Forward Search at the present location + // can also use active + void AddNewChild(void* Value, int BusRef, int TerminalNo); + //Property NewChild :Pointer Write Set_NewChild; // Adds child to present, but doesn't change present +//__published: +}; + + // build a tree of connected elements beginning at StartElement + // Analyze = TRUE will check for loops, isolated components, and parallel lines (takes longer) +TCktTree* GetIsolatedSubArea(CktElement::TDSSCktElement* StartElement, bool Analyze = false); +void BuildActiveBusAdjacencyLists(TAdjArray& lstPD, TAdjArray& lstPC, int ActorID); +void FreeAndNilBusAdjacencyLists(TAdjArray& lstPD, TAdjArray& lstPC); + + +} // namespace CktTree + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace CktTree; +#endif + +#endif // CktTreeH + + + + diff --git a/OpenDSSC/Shared/Command.cpp b/OpenDSSC/Shared/Command.cpp new file mode 100644 index 0000000..f408850 --- /dev/null +++ b/OpenDSSC/Shared/Command.cpp @@ -0,0 +1,87 @@ +//#include +#pragma hdrstop + +#include "Command.h" + +using namespace std; +using namespace Hashlist; +using namespace System; + +using namespace Command; + + +Command::TCommandList::TCommandList() {} + + + +TCommandList::TCommandList(std::string* Commands, int Commands_maxidx) +:CommandList(THashList(Commands_maxidx /*# High(Commands) */ + 1)), +AbbrevAllowed(true) +{ + int i = 0; + int stop = 0; + + for(stop = (int) (Commands_maxidx - 1) /*# High(Commands) */, i = 0; i <= stop; i++) + { + // Fill the HashList + CommandList.Add(Commands[i]); + } +} + +Command::TCommandList::~TCommandList() +{ + // inherited::Destroy(); +} + + +void Command::TCommandList::AddCommand(std::string cmd) +{ + CommandList.Add(cmd); +} + +int Command::TCommandList::Getcommand(std::string cmd) +{ + int result = 0; + result = CommandList.Find(cmd); +/*If no match found on whole command, check for abbrev*/ +/*This routine will generally be faster if one enters the whole command*/ + if(result == 0) + { + if(AbbrevAllowed) + result = CommandList.FindAbbrev(cmd); + } + return result; +} + +std::string Command::TCommandList::Get(int i) +{ + string result; + result = CommandList.Get((unsigned int) i); + return result; +} + +int Command::TCommandList::Get_NumCommands() +{ + int result = 0; + result = (int) CommandList.Get_NumElements(); + return result; +} + +bool Command::TCommandList::get_AbbrevAllowed() +{ + return AbbrevAllowed; +} + +void Command::TCommandList::set_AbbrevAllowed(bool myValue) +{ + AbbrevAllowed = myValue; +} + + + + + + + + + diff --git a/OpenDSSC/Shared/Command.h b/OpenDSSC/Shared/Command.h new file mode 100644 index 0000000..b1a305b --- /dev/null +++ b/OpenDSSC/Shared/Command.h @@ -0,0 +1,58 @@ +#ifndef CommandH +#define CommandH + +#include "System.h" +#include "HashList.h" + + +//class TCommandList; + + +namespace Command +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + */ + + + /*$M+*/ + + class TCommandList + { + public: + + THashList CommandList; + bool AbbrevAllowed; + int Get_NumCommands(); + public: + TCommandList(std::string* Commands, int Commands_maxidx); + virtual ~TCommandList(); + void AddCommand(std::string cmd); + int Getcommand(std::string cmd); + + bool get_AbbrevAllowed(); + void set_AbbrevAllowed(bool myValue); + + std::string Get(int i); + //__published: + //public: + TCommandList(); + }; + + +} // namespace Command + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Command; +#endif + +#endif // CommandH + + + + diff --git a/OpenDSSC/Shared/Dynamics.cpp b/OpenDSSC/Shared/Dynamics.cpp new file mode 100644 index 0000000..0233ee5 --- /dev/null +++ b/OpenDSSC/Shared/Dynamics.cpp @@ -0,0 +1,21 @@ + +#pragma hdrstop + +#include "Dynamics.h" + +using namespace std; + + +namespace Dynamics +{ + + + + + + +} // namespace Dynamics + + + + diff --git a/OpenDSSC/Shared/Dynamics.h b/OpenDSSC/Shared/Dynamics.h new file mode 100644 index 0000000..7073276 --- /dev/null +++ b/OpenDSSC/Shared/Dynamics.h @@ -0,0 +1,78 @@ +#ifndef DynamicsH +#define DynamicsH + +#include "System.h" +#include "Sysutils.h" + + +namespace Dynamics +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/*Definitions of constants and structures for the Solution object and user-written dynamic models*/ +const int NumSolutionModes = 16; + + /*Solution modes*/ +const int SNAPSHOT = 0; +const int DAILYMODE = 1; +const int YEARLYMODE = 2; // 8760 hour +const int MONTECARLO1 = 3; +const int LOADDURATION1 = 4; +const int PEAKDAY = 5; +const int DUTYCYCLE = 6; +const int DIRECT = 7; +const int MONTEFAULT = 8; // Monte Carlo Fault Study +const int FAULTSTUDY = 9; // Run through all buses and compute Voc and Zsc; Then ask for fault current. +const int MONTECARLO2 = 10; +const int MONTECARLO3 = 11; +const int LOADDURATION2 = 12; +const int AUTOADDFLAG = 13; +const int DYNAMICMODE = 14; +const int HARMONICMODE = 15; +const int GENERALTIME = 16; +const int HARMONICMODET = 17; // Adds the variable for the Sequential-time harmonics mode +const int EMPMODE = 18; +const int EMPDAILYMODE = 19; + + + + /*Variables needed for dynamics and user-written models.*/ +#pragma pack (push, 1) + + /*time vars*/ + +struct TDynamicsRec +{ + // Time step size in sec for dynamics + // sec from top of hour + double h; + double T; + double tstart; + double tstop; + int IterationFlag; /*0=New Time Step; 1= Same Time Step as last iteration*/ + int SolutionMode; // PEAKSNAP, DAILYMODE, YEARLYMODE, MONTECARLO, etc. (see DSSGlobals) + int intHour; // time, in hours as an integer + double dblHour; // time, in hours as a floating point number including fractional part +}; +#pragma pack (pop) + + + +} // namespace Dynamics + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Dynamics; +#endif + +#endif // DynamicsH + + + + diff --git a/OpenDSSC/Shared/HashList.cpp b/OpenDSSC/Shared/HashList.cpp new file mode 100644 index 0000000..093ecdc --- /dev/null +++ b/OpenDSSC/Shared/HashList.cpp @@ -0,0 +1,501 @@ +//#include +#pragma hdrstop + +#include "HashList.h" +#include "Utilities.h" + +using namespace std; + +using namespace Hashlist; + + + +THashList::THashList() + : NumElementsAllocated(0), + NumElements(0), + AllocationInc(0), + LastFind(0), + LastHash(0), + InitialAllocation(0) +{ + NumLists = 1; + StringPtr.resize(100); + ListPtr.resize(100); + for (int i = 0; i < ListPtr.size(); i++) + { + ListPtr[i].Str.clear(); + ListPtr[i].Idx.clear(); + ListPtr[i].NAllocated = 0; + ListPtr[i].Nelem = 0; + } +} + + + +THashList::THashList(unsigned int Nelements) + : NumElementsAllocated(0), + NumLists(0), + NumElements(0), + AllocationInc(0), + LastFind(0), + LastHash(0), + InitialAllocation(0) +{ + int i = 0; + unsigned int Elementsperlist = 0; + int stop = 0; + ; + NumElements = 0; + InitialAllocation = Nelements; + StringPtr.clear(); // Allocmem(Sizeof(StringPtr^[1]) * Nelements); + NumLists = (unsigned int) Round(sqrt((long double) Nelements)); + if(NumLists < 1) + NumLists = 1; // make sure at least one list + Elementsperlist = (unsigned int)(Nelements / NumLists) + 1; + AllocationInc = Elementsperlist; + ListPtr.resize(NumLists); + for(stop = NumLists, i = 1; i <= stop; i++) + { + /*Allocate initial Sublists to zero; alocated on demand*/ + /*# with ListPtr^[i] do */ + { + + ListPtr[i - 1].Str.clear(); + ListPtr[i - 1].Idx.clear(); + ListPtr[i - 1].NAllocated = 0; + ListPtr[i - 1].Nelem = 0; + } + } + LastFind = 0; + LastHash = 0; + LastSearchString = ""; +} + +THashList::~THashList() +{ + int i = 0; + int j = 0; + int stop = 0; + for(stop = NumLists - 1, i = 1; i <= stop; i++) + { + /*DeAllocated Sublists*/ + /*# with ListPtr^[i] do */ + try + { + if (ListPtr.size() != 0) + { + if ( (int) ListPtr[i - 1].Str.size() >= 0) + ListPtr[i - 1].Str.clear(); //# FreeMemory accepts one parameter only; + + if (ListPtr[i - 1].Idx.size() != 0) + ListPtr[i - 1].Idx.clear(); //# FreeMemory accepts one parameter only; + } + } + catch (...) + { + // + } + } + if (ListPtr.size() != 0) + ListPtr.clear(); //# FreeMemory accepts one parameter only; + if (((int)StringPtr.size() > 0)) + StringPtr.clear(); //# FreeMemory accepts one parameter only; + + // inherited::Destroy(); +} + + +void ReallocStr(pStringArray(s), int OldSize, int NewSize) +{ + pStringArray X = nullptr; + X = new std::string[NewSize]; // Zero fills new string pointer array (important!) + if(OldSize > 0) + { + Move(s, X, OldSize); + free(s); //# FreeMemory accepts one parameter only; + } + s = X; +} +// Make a bigger block to hold the pointers to the strings + +void THashList::ResizeSubList(TSubList& SubList) +{ + unsigned int OldAllocation = 0; + // resize by reasonable amount + /*# with SubList do */ + { + OldAllocation = SubList.NAllocated; + SubList.NAllocated = OldAllocation + AllocationInc; + SubList.Str.resize(SubList.NAllocated); + SubList.Idx.resize(SubList.NAllocated); + } +} + +/* This one was for AnsiStrings and just moved up to 8 bytes into an integer +Function THashList.Hash(Const S:String):Integer; + +VAR + Hashvalue:UInt64; + +BEGIN + HashValue := Uint64(0); + // Only hash first 8 characters + + Move(S[1], HashValue, min(8, Length(S))); + Result := (Hashvalue mod NumLists) + 1; +END; +*/ + +/* OLD HASH FUNCTION -- only hashes 1st 8 chars + +Function THashList.Hash(Const S:String):Cardinal; + +VAR + Hashvalue:Word; + i:Integer; + + {Use Delphi Math function: it is declared as inline} + {Function Min(const a,b:Integer):Integer; + BEGIN If a(s.length())-1; i++) + { + Hashvalue = (unsigned int) (((Hashvalue << 5) | (Hashvalue >> 27)) ^ ((unsigned int) s[i])); + } + result = (Hashvalue % NumLists) + 1; + return result; +} + +// make linear string list larger + +void THashList::ResizeStrPtr() +{ + unsigned int OldAllocation = 0; + std::vector NewPointer; + OldAllocation = NumElementsAllocated; + NumElementsAllocated = OldAllocation + AllocationInc * NumLists; + + // Allocate and zero fill new string space (important!) + NewPointer.resize(NumElementsAllocated); + + //move old stuff to new location then dispose of old stuff + if(OldAllocation > 0) + { + for (int idx = 0 ; idx < OldAllocation; idx++) + NewPointer[idx] = StringPtr[idx]; + //free(StringPtr); //# FreeMemory accepts one parameter only; + } + //StringPtr.resize(NumElementsAllocated); + //for (int idx = 0; idx < NumElementsAllocated; idx++) + // StringPtr[idx] = NewPointer[idx]; + StringPtr = NewPointer; // this is easier and faster + NewPointer.clear(); +} + +int THashList::Add(const String s) +{ + int result = 0; + unsigned int HashNum = 0; + String Ss; + Ss = ToLowerCaseStr(s); + HashNum = Hash(Ss); + NumElements++; + if(NumElements > NumElementsAllocated) + ResizeStrPtr(); + result = (int) NumElements; + /*# with ListPtr^[HashNum] do */ + { + + ListPtr[HashNum - 1].Nelem++; + if(ListPtr[HashNum - 1].Nelem > ListPtr[HashNum - 1].NAllocated) + ResizeSubList(ListPtr[HashNum - 1]); + } + /*# with ListPtr^[HashNum] do */ + { + + ListPtr[HashNum - 1].Str[ListPtr[HashNum - 1].Nelem - 1] = Ss; // make copy of whole string, lower case + StringPtr[NumElements - 1] = Ss; // increments count to string + ListPtr[HashNum - 1].Idx[ListPtr[HashNum - 1].Nelem - 1] = NumElements; + } + return result; +} + +int THashList::Find(const String s) +{ + int result = 0; + int i = 0; + LastSearchString = LowerCase(s); + LastHash = Hash(LastSearchString); + result = 0; + LastFind = 0; + /*# with ListPtr^[LastHash] do */ + { + + int stop = 0; + for(stop = ListPtr[LastHash - 1].Nelem, i = 1; i <= stop; i++) + { + if(CompareStr(LastSearchString, (ListPtr[LastHash - 1].Str)[i - 1]) == 0) + { + result = ListPtr[LastHash - 1].Idx[i - 1]; // Return the index of this element + LastFind = (unsigned int) i; + break; + } + } + } + return result; +} + +// Begin search in same list as last + +int THashList::FindNext() +{ + int result = 0; + int i = 0; + result = 0; // Default return + ++LastFind; // Start with next item in hash list + if((LastHash > 0) && (LastHash <= NumLists)) + /*# with ListPtr^[LastHash] do */ + { + + int stop = 0; + for(stop = ListPtr[LastHash - 1].Nelem, i = LastFind; i <= stop; i++) + { + if(CompareStr(LastSearchString, ListPtr[LastHash - 1].Str[i - 1]) == 0) + { + result = ListPtr[LastHash - 1].Idx[i - 1]; // Return the index of this element + LastFind = (unsigned int) i; + break; + } + } + } + return result; +} +/*Just make a linear search and test each string until a string is found that + matches all the characters entered in S*/ + +int THashList::FindAbbrev(const String s) +{ + int result = 0; + String Test1; + String Test2; + int i = 0; + result = 0; + if(s.length() > 0) + { + int stop = 0; + Test1 = LowerCase(s); + for (int stop = NumElements, j = 0; j < stop; j++) + { + if (StringPtr[j] == "") + { + StringPtr[j].assign("showreports"); + } + } + for(stop = NumElements, i = 1; i <= stop; i++) + { + + Test2 = StringPtr[i - 1].substr(0, Test1.length()); + if(CompareStr(Test1, Test2) == 0) + { + result = i; + break; + } + } + } + return result; +} + +String THashList::Get(unsigned int i) +{ + String result; + if((i > 0) && (i <= NumElements)) + result = StringPtr[i - 1]; + else + result = ""; + return result; +} + +/* + This procedure creates a new set of string lists and copies the + old strings into the new, hashing for the new number of lists. + +*/ + +void THashList::Expand(unsigned int NewSize) +{ + std::vector < std::string > NewStringPtr; + unsigned int NewNumLists = 0; + unsigned int Elementsperlist = 0; + pSubListArray NewListPtr; + unsigned int HashNum = 0; + String s; + unsigned int OldNumLists = 0; + NewListPtr.clear(); + int i = 0; + int j = 0; + if(NewSize > NumElementsAllocated) + { + int stop = 0; + OldNumLists = NumLists; + NewStringPtr.resize(NewSize); + NewNumLists = (unsigned int) Round(sqrt((long double) NewSize)); + Elementsperlist = (unsigned int)(NewSize / NewNumLists) + 1; + if(NewNumLists < 1) + NewNumLists = 1; // make sure at least one list + NewListPtr.resize(NewNumLists); + for(stop = NumLists, i = 1; i <= stop; i++) + { + /*Allocate initial Sublists*/ + /*# with NewListPtr^[i] do */ + { + + NewListPtr[i - 1].Str.resize(Elementsperlist); + NewListPtr[i - 1].Idx.resize(Elementsperlist); + NewListPtr[i - 1].NAllocated = Elementsperlist; + NewListPtr[i - 1].Nelem = 0; + } + } + NumLists = NewNumLists; // Has to be set so Hash function will work + +/*Add elements from old Hash List to New Hash List*/ + for(stop = NumElements, i = 1; i <= stop; i++) + { + s = StringPtr[i - 1]; + HashNum = Hash(s); + /*# with NewListPtr^[HashNum] do */ + { + + NewListPtr[HashNum - 1].Nelem++; + if(NewListPtr[HashNum - 1].Nelem > NewListPtr[HashNum - 1].NAllocated) + ResizeSubList(NewListPtr[HashNum - 1]); + } + /*# with NewListPtr^[HashNum] do */ + { + + NewListPtr[HashNum - 1].Str[NewListPtr[HashNum - 1].Nelem - 1] = s; + NewStringPtr[NumElements - 1] = NewListPtr[HashNum - 1].Str[NewListPtr[HashNum - 1].Nelem - 1]; + NewListPtr[HashNum - 1].Idx[NewListPtr[HashNum - 1].Nelem - 1] = (unsigned int) i; + } + } + +/*Dump the old StringPtr and ListPtr storage*/ + for(stop = OldNumLists, i = 1; i <= stop; i++) + { + /*DeAllocate Sublists*/ + /*# with ListPtr^[i] do */ + { + + ListPtr[i - 1].Str.clear(); //# FreeMemory accepts one parameter only; + ListPtr[i - 1].Idx.clear(); //# FreeMemory accepts one parameter only; + } + } + ListPtr.clear(); //# FreeMemory accepts one parameter only; + StringPtr.clear(); //# FreeMemory accepts one parameter only; + +/*Assign new String and List Pointers*/ + StringPtr = NewStringPtr; + ListPtr = NewListPtr; + NumElementsAllocated = NewSize; + } +} + +void THashList::DumpToFile(const String FName) +{ + System::TTextRec f = {}; + int i = 0; + int j = 0; + int stop = 0; + AssignFile(f, FName); + Rewrite(f); + IOResultToException(); + WriteLn(f, "Number of Hash Lists = " + to_string(NumLists) + "Number of Elements = " + to_string(NumElements)); + WriteLn(f); + WriteLn(f, L"Hash List Distribution"); + for(stop = NumLists, i = 1; i <= stop; i++) + { + /*# with ListPtr^[i] do */ + { + + WriteLn(f,"List = " + to_string(i) + ", Number of elements = " + to_string((int)ListPtr[i - 1].Nelem) ); + } + } + WriteLn(f); + for(stop = NumLists, i = 1; i <= stop; i++) + { + /*# with ListPtr^[i] do */ + { + + int stop1 = 0; + WriteLn(f, "List = " + to_string(i) + ", Number of elements = " + to_string(ListPtr[i - 1].Nelem)); + for(stop1 = ListPtr[i - 1].Nelem, j = 1; j <= stop1; j++) + { + { Write(f, '\"'); Write(f, ListPtr[i - 1].Str[j - 1]); Write(f, L"\" Idx= "); WriteLn(f, to_string(ListPtr[i - 1].Idx[j - 1]), 0); } + } + } + WriteLn(f); + } + WriteLn(f, L"LINEAR LISTING..."); + for(stop = NumElements, i = 1; i <= stop; i++) + { + { Write(f, i, 3); Write(f, L" = \""); Write(f, StringPtr[i - 1]); WriteLn(f, L'\"'); } + } + CloseFile(f); +} + +void THashList::Clear() +{ + int i = 0; + int j = 0; + int stop = 0; + for(stop = NumLists, i = 1; i <= stop; i++) + { + /*# with ListPtr^[i] do */ + { + + int stop1 = 0; + ListPtr[i - 1].Nelem = 0; + for(stop1 = ListPtr[i - 1].NAllocated, j = 1; j <= stop1; j++) + { + ListPtr[i - 1].Str[j - 1] = ""; + } + } + } + for(stop = NumElementsAllocated, i = 1; i <= stop; i++) + { + StringPtr[i - 1] = ""; + } + NumElements = 0; +} + + + + + + + + diff --git a/OpenDSSC/Shared/HashList.h b/OpenDSSC/Shared/HashList.h new file mode 100644 index 0000000..be31a3c --- /dev/null +++ b/OpenDSSC/Shared/HashList.h @@ -0,0 +1,106 @@ +#ifndef HashlistH +#define HashlistH + +//#include "System.h" +//#include "d2c_system.h" +#include "Arraydef.h" +#include +#include "System.h" +#include "Sysutils.h" +#include +#include + +namespace Hashlist +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + This Hash list module is designed to make searches on arrays of strings more + efficient. The list actually consists of several short linear lists. When a string + is added, it is hashed and placed at the end of one of the lists. + + The list may by searched by string or by index. When by string, the string + is hashed and the search is restricted to the resulting linear list. When by + index, it simply goes to that index in the array of pointers that points to the + individual strings. + + All strings are saved in lower case and tested with case sensitivity. This + actually makes the search insensitive to case because everything is lower case. + + Modified 4/18/98 to allocate on demand. That way, you can create it for a certain + number of hash lists, without caring about how many actual there will be. + +*/ + +/*$M+*/ + + //pStringArray = ^StringArray; + // StringArray = Array[1..100] of String; + + + +struct TSubList +{ + std::vector Str; + std::vector Idx; + unsigned int Nelem; + unsigned int NAllocated; +}; +typedef TSubList SubListArray; +typedef std::vector pSubListArray; + +class THashList : public System::TObject +{ +public: + typedef TObject inherited; +//private: + unsigned int NumElementsAllocated; + unsigned int NumLists; + unsigned int NumElements; + std::vector StringPtr; + pSubListArray ListPtr; + unsigned int AllocationInc; + unsigned int LastFind; + unsigned int LastHash; + String LastSearchString; + void ResizeSubList(TSubList& SubList); + unsigned int Hash(const String s); + void ResizeStrPtr(); + unsigned int Get_NumElements(); +//protected: +public: + unsigned int InitialAllocation; + THashList(unsigned int Nelements); + virtual ~THashList(); + int Add(const String s); + int Find(const String s); // This is 1-based! For buses, e.g. ActiveBusIndex, remember to subtract 1. + int FindNext(); // repeat find for duplicate string in same hash list + int FindAbbrev(const String s); + String Get(unsigned int i); // This is 1-based! For buses, e.g. ActiveBusIndex, remember to sum 1. + void Expand(unsigned int NewSize); /*Expands number of elements*/ + void DumpToFile(const String FName); + void Clear(); +//__published: +public: + THashList(); +}; + + +} // namespace Hashlist + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Hashlist; +#endif + +#endif // HashlistH + + + + diff --git a/OpenDSSC/Shared/IniRegSave.cpp b/OpenDSSC/Shared/IniRegSave.cpp new file mode 100644 index 0000000..5707938 --- /dev/null +++ b/OpenDSSC/Shared/IniRegSave.cpp @@ -0,0 +1,91 @@ +//#include +#pragma hdrstop + +#include "IniRegSave.h" + +using namespace std; + + +namespace IniRegSave +{ + +TIniRegSave::TIniRegSave() {} + + + +//{$IFDEF MSWINDOWS} + +TIniRegSave::TIniRegSave(const String Name) +/* : FSection(L"MainSect"), + FIniFile(nullptr)*/ +{ +/* FName = Name; + FIniFile = new TRegIniFile(Name);*/ +} + +TIniRegSave::~TIniRegSave() +{ + // inherited; +} + + +bool TIniRegSave::ReadBool(const String key, bool Default) +{ + bool result = false; +// result = FIniFile->ReadBool(FSection, key, Default); + return result; +} + +int TIniRegSave::ReadInteger(const String key, int Default) +{ + int result = 0; + //result = FIniFile->ReadInteger(FSection, key, Default); + return result; +} + +String TIniRegSave::ReadString(const String key, const String Default) +{ + String result; + //result = FIniFile->ReadString(FSection, key, Default); + return result; +} + +void TIniRegSave::Set_FSection(const String Value) +{ + FSection = Value; +} + +void TIniRegSave::WriteBool(const String key, bool Value) +{ +// FIniFile->WriteBool(FSection, key, Value); +} + +void TIniRegSave::WriteInteger(const String key, int Value) +{ +// FIniFile->WriteInteger(FSection, key, Value); +} + +void TIniRegSave::WriteString(const String key, String Value) +{ +// FIniFile->WriteString(FSection, key, Value); +} + +string TIniRegSave::get_FSection() +{ + return FSection; +} + +void TIniRegSave::ClearSection() +{ + //FIniFile->EraseSection(FSection); +} +//{$ENDIF} + + + + +} // namespace IniRegSave + + + + diff --git a/OpenDSSC/Shared/IniRegSave.h b/OpenDSSC/Shared/IniRegSave.h new file mode 100644 index 0000000..cc5d2c9 --- /dev/null +++ b/OpenDSSC/Shared/IniRegSave.h @@ -0,0 +1,68 @@ +#ifndef IniRegSaveH +#define IniRegSaveH + +#include "System.h" + +//#include + +namespace IniRegSave +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* Simple unit to create an Ini file equivalent in the registry. + By default, creates a key under HKEY_CURRENT_USER + + Typically, you will want to move the key under 'Software' by creating as + + MyIniFile := TIniRegSave.Create('\Software\myprogramname'); + + But it'll work anywhere. + +*/ +//{$IFDEF MSWINDOWS} + +class TIniRegSave : public System::TObject +{ +public: + typedef TObject inherited; + String FSection; + String FName; +// TIniFile* FIniFile; +//private: + void Set_FSection(const String Value); + std::string get_FSection(); + /* Private declarations */ +public: + /* Public declarations */ + void ClearSection(); + void WriteBool(const String key, bool Value); + void WriteInteger(const String key, int Value); + void WriteString(const String key, String Value); + bool ReadBool(const String key, bool Default); + int ReadInteger(const String key, int Default); + String ReadString(const String key, const String Default); + TIniRegSave(const String Name); + virtual ~TIniRegSave(); + TIniRegSave(); +}; +//{$ENDIF} + + +} // namespace IniRegSave + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace IniRegSave; +#endif + +#endif // IniRegSaveH + + + + diff --git a/OpenDSSC/Shared/IntegrationMethods.cpp b/OpenDSSC/Shared/IntegrationMethods.cpp new file mode 100644 index 0000000..977a676 --- /dev/null +++ b/OpenDSSC/Shared/IntegrationMethods.cpp @@ -0,0 +1,29 @@ +#include "IntegrationMethods.h" + + +/* +* +* This file contains all the new integration methods considered for the application +* +* A list of methods implemented (or to be implemented) includes mostly explicit methods and is provided below: +* - Adams-Bashforth 2nd order +* - Euler 1st order +* - Trapezoidal (Adams-Moulton) 2nd order +* +*/ + +template +void IntegrationMethods::ab2order(ModelType *gen, double *delta) +{ + double xold, temp; + for (int i = 0; i < gen->nstates; i++) { + + // This is done to hold the state value from two time steps ago + xold = gen->ss[i]; // This is the state value at the previous time step + gen->ss[i] = gen->s[i]; // This is the state value at the current time step + + temp = gen->s[i] - xold / *delta; + gen->s[i] = gen->s[i] + *delta * (1.5 * gen->ds[i] - 0.5 * temp); // This is the state value at the next time step + } + +} diff --git a/OpenDSSC/Shared/IntegrationMethods.h b/OpenDSSC/Shared/IntegrationMethods.h new file mode 100644 index 0000000..a60627b --- /dev/null +++ b/OpenDSSC/Shared/IntegrationMethods.h @@ -0,0 +1,64 @@ +#pragma once +#ifndef INTEGRATION_METHODS_H +#define INTEGRATION_METHODS_H + + + +using namespace std; + +namespace IntegrationMethods +{ + // This file contains a list of all integration methods used + + /*template + void ab2order(ModelType *gen, double *delta);*/ + template + void ab2order(ModelType* model, double* delta) + { + double xold; + for (int i = 0; i < model->nstates; i++) { + + // This is done to hold the state value from two time steps ago + xold = model->ss[i]; // This is the state value at the previous time step + model->ss[i] = model->s[i]; // Save current state value as old state value + model->s[i] = 0.5*(model->s[i]+xold) + *delta * (1.5 * model->ds[i]); // This is the state value at the next time step + } + + }; + + /*template + void euler(ModelType *gen, double *delta);*/ + template + void euler(ModelType* model, double* delta) + { + double x_old; + for (int i = 0; i < model->nstates; i++) { + x_old = model->s[i]; + model->ss[i] = model->s[i]; + model->s[i] = x_old + (*delta) * (model->ds[i]); // This is the state value at the next time step + model->dss[i] = model->ds[i]; + } + }; + + /*template + void trapezoidal(ModelType *gen, double *delta);*/ + template + void trapezoidal(ModelType* model, double* delta) + { + double ds_old, s_old, temp; + for (int i = 0; i < model->nstates; i++) { + + // This is done to hold the state value from two time steps ago + s_old = model->ss[i]; + model->s[i] = s_old + 0.5* (*delta) * (model->ds[i]+model->dss[i]); // This is the state value at the next time step + //model->ss[i] = model->s[i]; + } + + }; + +} +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace IntegrationMethods; +#endif + +#endif // INTEGRATION_METHODS_H diff --git a/OpenDSSC/Shared/InvDynamics.cpp b/OpenDSSC/Shared/InvDynamics.cpp new file mode 100644 index 0000000..436c509 --- /dev/null +++ b/OpenDSSC/Shared/InvDynamics.cpp @@ -0,0 +1,306 @@ + +#pragma hdrstop + +#include "InvDynamics.h" +#include "DSSGlobals.h" + +using namespace std; + +namespace InvDynamics +{ + + int NumInvDynVars = 9; + + // Returns the value of the given state variable using the index lo localize it + + double TInvDynamicVars::Get_InvDynValue(int myindex, int NumPhases) + { + double result = 0.0; + switch (myindex) + { + case 0: + if (Vgrid.size() > 0) + result = Vgrid[NumPhases - 1].mag; + else + result = 0; + break; + case 1: + if (dit.size() > 0) + result = dit[NumPhases - 1]; + else + result = 0; + break; + case 2: + if (it.size() > 0) + result = it[NumPhases - 1]; + else + result = 0; + break; + case 3: + if (itHistory.size() > 0) + result = itHistory[NumPhases - 1]; + else + result = 0; + break; + case 4: + result = RatedVDC; + break; + case 5: + if (m.size() > 0) + result = m[0]; + else + result = 0; + break; + case 6: + result = ISP; + break; + case 7: + result = LS; + break; + case 8: + result = iMaxPPhase; + break; + default: + result = 0; + } + return result; + } + + // Sets the value for the state variable indicated in the index + + + + void TInvDynamicVars::Set_InvDynValue(int myindex, double myValue) + { + switch (myindex) + { + case 0: + break; // Read only + case 1: + dit[0] = myValue; + break; + case 2: + it[0] = myValue; + break; + case 3: + itHistory[0] = myValue; + break; + case 4: + RatedVDC = myValue; + break; + case 5: + m[0] = myValue; + break; + case 6: + break; // Read only + case 7: + LS = myValue; + break; + case 8: + iMaxPPhase = myValue; + break; + default: + // Do nothing + break; + } + } + + // Returns the name of the state variable located by the given index + + + + String TInvDynamicVars::Get_InvDynName(int myindex) + { + String result; + switch (myindex) + { + case 0: + result = "Grid voltage"; + break; + case 1: + result = "di/dt"; + break; + case 2: + result = "it"; + break; + case 3: + result = "it History"; + break; + case 4: + result = "Rated VDC"; + break; + case 5: + result = "Avg duty cycle"; + break; + case 6: + result = "Target (Amps)"; + break; + case 7: + result = "Series L"; + break; + case 8: + result = "Max. Amps (phase)"; + break; + default: + result = "Unknown variable"; + } + return result; + } + + // Solves the derivative term of the differential equation to be integrated + + + + void TInvDynamicVars::SolveDynamicStep(int I, int ActorID, PPICtrl PICtrl) + { + double myDCycle = 0.0, iDelta = 0.0, iErrorPct = 0.0, iError = 0.0; + /*# with ActiveCircuit[ActorID].Solution do */ + { + SolveModulation(I, ActorID, PICtrl); + if (SafeMode) + dit[I] = 0; + else + dit[I] = ((m[I] * RatedVDC) - (RS * it[I]) - Vgrid[I].mag) / LS; // Solves derivative + } + } + + // Calculates and stores the averaged modulation factor for controlling the inverter output + + + + void TInvDynamicVars::SolveModulation(int I, int ActorID, PPICtrl PICtrl) + { + double myDCycle = 0.0, iDelta = 0.0, iErrorPct = 0.0, iError = 0.0; + /*# with ActiveCircuit[ActorID].Solution do */ + auto with0 = ActiveCircuit[ActorID]->Solution; + { + if (with0->DynaVars.IterationFlag != 0) + { // duty cycle at time h + iError = (ISP - it[I]); // Only recalculated on the second iter + iErrorPct = iError / ISP; + if (Abs(iErrorPct) > CtrlTol) + { + iDelta = PICtrl->SolvePI(iError); + myDCycle = m[I] + iDelta; + if ((Vgrid[I].mag > MinVS) || (MinVS == 0)) + { + if (SafeMode || SfModePhase[I]) + { + //Coming back from safe operation, need to boost duty cycle + m[I] = ((RS * it[I]) + Vgrid[I].mag) / RatedVDC; + SafeMode = false; + SfModePhase[I] = false; + } + else + if ((myDCycle <= 1) && (myDCycle > 0)) + m[I] = myDCycle; + } + else + { + m[I] = 0; + it[I] = 0; + itHistory[I] = 0; + SafeMode = true; + SfModePhase[I] = true; + } + } + } + } + } + //--------------------------------------------------------------------------------------- + //| Calculates the current phasors to match with the target (v) | + //--------------------------------------------------------------------------------------- + + + void TInvDynamicVars::FixPhaseAngle(int ActorID, int idx) + { + double myError = 0.0; + // Corrects the phase angle + AngDelta[idx] = AngDelta[idx] + ((double((idx * TwoPi)) / -3) - Vgrid[idx].ang); + Vgrid[idx].ang = AngDelta[idx]; + } + + //--------------------------------------------------------------------------------------- + //| Calculates the equivalent short circuit impedance for the inverter operating in GFM | + //| Similar to the calculation user for VSource, replacing some variables with constants| + //--------------------------------------------------------------------------------------- + + + void TInvDynamicVars::CalcGFMYprim(int ActorID, int Nphases, pTcMatrix YMatrix) + { + TcMatrix Z; + complex Zs, Zm; + double a = 0.0, b = 0.0, c = 0.0, R0 = 0.0, X0 = 0.0, X1 = 0.0, R1 = 0.0, R2 = 0.0, X2 = 0.0, Isc1 = 0.0, Xs = 0.0, RS = 0.0, Rm = 0.0, Xm = 0.0; + int I = 0, j = 0; + Z = TcMatrix(YMatrix->get_Norder()); + X1 = (double(sqr(RatedkVLL)) / mKVARating) / sqrt(1.0 + 0.0625); + R1 = X1 / 4; // Uses defaults + R2 = R1; // default Z2 = Z1 + X2 = X1; + Isc1 = (mKVARating * 1000.0 / (sqrt(3) * RatedkVLL)) / Nphases; + // Compute R0, X0 + a = 10; + b = (4.0 * (R1 + X1 * 3)); + c = (4.0 * (R1 * R1 + X1 * X1) - Sqr(double((sqrt(3) * RatedkVLL * 1000.0)) / Isc1)); + R0 = QuadSolver(a, b, c); + X0 = R0 * 3; + // for Z matrix + Xs = (2.0 * X1 + X0) / 3.0; + RS = (2.0 * R1 + R0) / 3.0; + Rm = (R0 - R1) / 3.0; + Xm = (X0 - X1) / 3.0; + Zs = cmplx(RS, Xs); + Zm = cmplx(Rm, Xm); + for (int stop = Nphases, I = 1; I <= stop; I++) + { + Z.SetElement(I, I, Zs); + for (int stop = I - 1, j = 1; j <= stop; j++) + { + Z.SetElemsym(I, j, Zm); + } + } + Z.Invert(); + YMatrix->CopyFrom(&Z); + } + //--------------------------------------------------------------------------------------- + //| Calculates the voltage magnitudes and angles for facilitating GFM control mode | + //--------------------------------------------------------------------------------------- + + + void TInvDynamicVars::CalcGFMVoltage(int ActorID, int Nphases, pComplexArray x, double angle) + { + double refAngle = 0.0; + int I = 0; + + refAngle = angle; + for (int stop = Nphases, I = 1; I <= stop; I++) + x[I - 1] = pdegtocomplex(BaseV, (360.0 + refAngle - double(((I - 1) * 360.0)) / Nphases)); + } + //--------------------------------------------------------------------------------------- + //| Initializes all the local vectors using the number of phases given by the caller | + //--------------------------------------------------------------------------------------- + + + void TInvDynamicVars::InitDynArrays(int Nphases) + { + int I = 0; + dit.resize(Nphases); // Includes the current and past values + it.resize(Nphases); + itHistory.resize(Nphases); + Vgrid.resize(Nphases); + m.resize(Nphases); + VDelta.resize(Nphases); + ISPDelta.resize(Nphases); + AngDelta.resize(Nphases); + SfModePhase.resize(Nphases); + for (int stop = (Nphases - 1), I = 0; I <= stop; I++) + // { + SfModePhase[I] = false; + // it[I] = 0; + // itHistory[I] = 0; + // dit[I] = 0; + // m[I] = 0; + // } + SafeMode = false; + } +}// namespace InvDynamics \ No newline at end of file diff --git a/OpenDSSC/Shared/InvDynamics.h b/OpenDSSC/Shared/InvDynamics.h new file mode 100644 index 0000000..8c12ac9 --- /dev/null +++ b/OpenDSSC/Shared/InvDynamics.h @@ -0,0 +1,68 @@ +#ifndef InvDynamicsH +#define InvDynamicsH + + +#include "System.h" + +#include "Ucomplex.h" +#include "mathutil.h" +#include "Ucmatrix.h" + + +namespace InvDynamics +{ + + /*Structure for hosting data and solving for each inverter based element*/ + struct TInvDynamicVars + { + std::vector< polar > Vgrid; // Grid voltage at the point of connection per phase + std::vector< double > dit, // Current's first derivative per phase + it, // Current's integration per phase + itHistory, // Shift register for it + VDelta, // for black start operation (GFM) + ISPDelta, // for moving the current target per phase in black start operation (GFM) + AngDelta, // For correcting the phase angle + m; // Average duty cycle per phase + double iMaxPPhase = 0.0, + Kp = 0.0, // PI controller gain + CtrlTol = 0.0, // Control loop tolerance + SMThreshold = 0.0, // Voltage threshold for entering into safe mode + RatedVDC = 0.0, // Rated DC voltage at the inverter's input + LS = 0.0, // Series inductance, careful, it cannot be 0 in dyn mode + RS = 0.0, // Series resistance (filter) + BasekV = 0.0, // BAse kV depending on the number of phases + BaseV = 0.0, // For GFM mode, avoid messing with things + MaxVS = 0.0, // Max Voltage at the inverter terminal to safely operate the inverter + MinVS = 0.0, // Min Voltage at the inverter terminal to safely operate the inverter + MinAmps = 0.0, // Min amps required for exporting energy + mKVARating = 0.0, // For GFM impedance calculation and avoid messing with other calcs + RatedkVLL = 0.0, // As defined when decalred the element, for GFM impedance calculation and avoid messing with other calcs + ILimit = 0.0, // Created for limiting the output current without entering into safe mode + ISP = 0.0, // Current setpoint according to the actual DER kW + IComp = 0.0, // For storing the compensation value when the Amps limiter is active + VError = 0.0; // Stores the systemic error correction factor for current limiting + + bool Discharging = false, // To verify if the storage device is discharging + ResetIBR = false, // flag for forcing the IBR to turn OFF + SafeMode = false; // To indicate weather the Inverter has entered into safe mode + std::vector< bool > SfModePhase; // To identify when to restart the phase + + double Get_InvDynValue(int myindex, int NumPhases); + std::string Get_InvDynName(int myindex); + void Set_InvDynValue(int myindex, double myValue); + void SolveDynamicStep(int I, int ActorID, PPICtrl PICtrl); + void SolveModulation(int I, int ActorID, PPICtrl PICtrl); + void FixPhaseAngle(int ActorID, int idx); + void CalcGFMYprim(int ActorID, int Nphases, pTcMatrix YMatrix); + void CalcGFMVoltage(int ActorID, int Nphases, pComplexArray x, double angle = 0); + void InitDynArrays(int Nphases); + }; + + extern int NumInvDynVars; +} // namespace InvDynamics + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace InvDynamics; +#endif + +#endif // InvDynamicsH \ No newline at end of file diff --git a/OpenDSSC/Shared/LineUnits.cpp b/OpenDSSC/Shared/LineUnits.cpp new file mode 100644 index 0000000..65ba7dc --- /dev/null +++ b/OpenDSSC/Shared/LineUnits.cpp @@ -0,0 +1,184 @@ + +#pragma hdrstop + +#include "LineUnits.h" + + +using namespace std; + + +namespace LineUnits +{ + + + +int GetUnitsCode(const String s) +{ + int result = 0; + String Stest; + result = 0; + Stest = s.substr(0, 2); // copy first 2 chars for MOST OF the test + if(CompareText(Stest, "no") == 0) // no units specified + result = UNITS_NONE; + else + { + if(CompareText(Stest, "mi") == 0) // per mile + result = UNITS_MILES; + else + { + if(CompareText(Stest, "kf") == 0) // per 1000 ft (kft) + result = UNITS_KFT; + else + { + if(CompareText(Stest, "km") == 0) // per km + result = UNITS_KM; + else + { + if(CompareText(Stest, "m") == 0) // per meter + result = UNITS_M; + else + { + if(CompareText(Stest, "me") == 0) // per meter + result = UNITS_M; + else + { + if(CompareText(Stest, "ft") == 0) + result = UNITS_FT; + else + { + if(CompareText(Stest, "in") == 0) + result = UNITS_IN; + else + { + if(CompareText(Stest, "cm") == 0) + result = UNITS_CM; + else + { + if(CompareText(Stest, "mm") == 0) + result = UNITS_MM; + } + } + } + } + } + } + } + } + } + return result; +} + +String LineUnitsStr(int Units) +{ + String result; + switch(Units) + { + case 0: + result = "none"; + break; + case UNITS_MILES: + result = "mi"; + break; + case UNITS_KFT: + result = "kft"; + break; + case UNITS_KM: + result = "km"; + break; + case UNITS_M: + result = "m"; + break; + case UNITS_FT: + result = "ft"; + break; + case UNITS_IN: + result = "in"; + break; + case UNITS_CM: + result = "cm"; + break; + case UNITS_MM: + result = "mm"; + break; + default: + result = "none"; + break; + } + return result; +} + +double To_Meters(int Units) +{ + double result = 0.0; + switch(Units) + { + case UNITS_MILES: + result = 1609.344; + break; + case UNITS_KFT: + result = 304.8; + break; + case UNITS_KM: + result = 1000.0; + break; + case UNITS_M: + result = 1.0; + break; + case UNITS_FT: + result = 0.3048; + break; + case UNITS_IN: + result = 0.0254; + break; + case UNITS_CM: + result = 0.01; + break; + case UNITS_MM: + result = 0.001; + break; + default: + result = 1.0; + break; + } + return result; +} + +double To_per_Meter(int Units) +{ + double result = 0.0; + result = 1.0 / To_Meters(Units); + return result; +} + +double From_per_Meter(int Units) +{ + double result = 0.0; + result = To_Meters(Units); + return result; +} + +double From_Meters(int Units) +{ + double result = 0.0; + result = 1.0 / To_Meters(Units); + return result; +} + +double ConvertLineUnits(int FromUnits, int ToUnits) +{ + double result = 0.0; + if((FromUnits == UNITS_NONE) || (ToUnits == UNITS_NONE)) // Don't know what to convert + result = 1.0; + else + result = From_Meters(ToUnits) * To_Meters(FromUnits); + return result; +} + + + + +} // namespace LineUnits + + + + diff --git a/OpenDSSC/Shared/LineUnits.h b/OpenDSSC/Shared/LineUnits.h new file mode 100644 index 0000000..406b5e1 --- /dev/null +++ b/OpenDSSC/Shared/LineUnits.h @@ -0,0 +1,49 @@ +#ifndef LineUnitsH +#define LineUnitsH + +#include "System.h" +#include "Sysutils.h" + + +namespace LineUnits +{ + + + /* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +const int UNITS_MAXNUM = 9; +const int UNITS_NONE = 0; +const int UNITS_MILES = 1; +const int UNITS_KFT = 2; +const int UNITS_KM = 3; +const int UNITS_M = 4; +const int UNITS_FT = 5; +const int UNITS_IN = 6; +const int UNITS_CM = 7; +const int UNITS_MM = 8; +int GetUnitsCode(const String s); +String LineUnitsStr(int Units); + +// Conversion to and from meters and per meter +double To_Meters(int Units); +double To_per_Meter(int Units); +double From_per_Meter(int Units); +double From_Meters(int Units); +double ConvertLineUnits(int FromUnits, int ToUnits); + + +} // namespace LineUnits + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace LineUnits; +#endif + +#endif // LineUnitsH + + + + diff --git a/OpenDSSC/Shared/MathutilInterface.cpp b/OpenDSSC/Shared/MathutilInterface.cpp new file mode 100644 index 0000000..f5f5e7e --- /dev/null +++ b/OpenDSSC/Shared/MathutilInterface.cpp @@ -0,0 +1,340 @@ +#include +#pragma hdrstop + +#include "MathutilInterface.h" +#include "../Shared/mathutil.h" +#include "cbess1.h" +#include "cbess2.h" +#include "ZComplex.h" + +using namespace std; +using namespace d2c_system; +using namespace System; +using namespace Ucomplex; +using namespace ZComplex; +using namespace cbess1; +using namespace cbess2; +using namespace mathutil; + +namespace MathutilInterface +{ + + + +void __stdcall I0(complex& result, complex& A) +{ + result = Bessel_I0(A); +} + +void __stdcall I1(complex& result, complex& A) +{ + result = Bessel_I1(A); +} + +void ZBESJ(double Zr, double Zi, double FNU, int KODE, int n, VEC& CYR, VEC& CYI, int& NZ, int& IERR) +{ + double AA = 0.0; + double ALIM = 0.0; + double Arg = 0.0; + double CII = 0.0; + double CSGNI = 0.0; + double CSGNR = 0.0; + double Dig = 0.0; + double ELIM = 0.0; + double FNUL = 0.0; + double HPI = 0.0; + double RL = 0.0; + double R1M5 = 0.0; + double Str = 0.0; + double TOL = 0.0; + double ZNI = 0.0; + double ZNR = 0.0; + double BB = 0.0; + double FN = 0.0; + double AZ = 0.0; + int i = 0; + int INU = 0; + int INUH = 0; + int IR = 0; + int k = 0; + int K1 = 0; + int K2 = 0; + int NL = 0; + +/****FIRST EXECUTABLE STATEMENT ZBESJ */ + int stop = 0; + HPI = double(Pi) / 2.0; + IERR = 0; + NZ = 0; + if(FNU < 0.0) + IERR = 1; + if((KODE < 1) || (KODE > 2)) + IERR = 1; + if(n < 1) + IERR = 1; + if(IERR != 0) + goto Return; +/*----------------------------------------------------------------------- +! SET PARAMETERS RELATED TO MACHINE CONSTANTS. +! TOL IS THE APPROXIMATE UNIT ROUNDOFF LIMITED TO 1.0E-18. +! ELIM IS THE APPROXIMATE EXPONENTIAL OVER- AND UNDERFLOW LIMIT. +! EXP(-ELIM).LT.EXP(-ALIM):=EXP(-ELIM)/TOL AND +! EXP(ELIM).GT.EXP(ALIM):=EXP(ELIM)*TOL ARE INTERVALS NEAR +! UNDERFLOW AND OVERFLOW LIMITS WHERE SCALED ARITHMETIC IS DONE. +! RL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC EXPANSION FOR LARGE Z. +! DIG := NUMBER OF BASE 10 DIGITS IN TOL = 10^(-DIG). +! FNUL IS THE LOWER BOUNDARY OF THE ASYMPTOTIC SERIES FOR LARGE FNU. +!----------------------------------------------------------------------*/ + TOL = DMAX(D1MACH(4), 1E-18); + K1 = I1MACH(15); + K2 = I1MACH(16); + R1M5 = D1MACH(5); + k = IMin(Abs(K1), Abs(K2)); + ELIM = 2.303 * (k * R1M5 - 3.0); + K1 = I1MACH(14) - 1; + AA = R1M5 * K1; + Dig = DMIN(AA, 18.0); + AA = AA * 2.303; + ALIM = ELIM + DMAX(-AA, -41.45); + RL = 1.2 * Dig + 3.0; + FNUL = 10.0 + 6.0 * (Dig - 3.0); +/*----------------------------------------------------------------------- +! TEST FOR PROPER RANGE +!----------------------------------------------------------------------*/ + AZ = ZABS(Zr, Zi); + FN = FNU + 1.0 * (n - 1); + AA = 0.5 / TOL; + BB = I1MACH(9) * 0.5; + AA = DMIN(AA, BB); + if(AZ > AA) + goto 260; + if(FN > AA) + goto 260; + AA = Sqrt(AA); + if(AZ > AA) + IERR = 3; + if(FN > AA) + IERR = 3; +/*----------------------------------------------------------------------- +! CALCULATE CSGN=EXP(FNU*HPI*I) TO MINIMIZE LOSSES OF SIGNIFICANCE +! WHEN FNU IS LARGE +!----------------------------------------------------------------------*/ + CII = 1.0; + INU = (int) Round(FNU); + INUH = (int)(INU / 2); + IR = INU - 2 * INUH; + Arg = (FNU - 1.0 * (INU - IR)) * HPI; + CSGNR = Cos(Arg); + CSGNI = Sin(Arg); + if((INUH % 2) == 0) + goto 40; + CSGNR = -CSGNR; + CSGNI = -CSGNI; +/*----------------------------------------------------------------------- +! ZN IS IN THE RIGHT HALF PLANE +!----------------------------------------------------------------------*/ + 40:; + ZNR = Zi; + ZNI = -Zr; + if(Zi >= 0.0) + goto 50; + ZNR = -ZNR; + ZNI = -ZNI; + CSGNI = -CSGNI; + CII = -CII; + 50:; + ZBINU(ZNR, ZNI, FNU, KODE, n, CYR, CYI, NZ, RL, FNUL, TOL, ELIM, ALIM); + if(NZ < 0) + goto 130; + NL = n - NZ; + if(NL == 0) + goto Return; + for(stop = NL, i = 1; i <= stop; i++) + { + Str = CYR[i] * CSGNR - CYI[i] * CSGNI; + CYI[i] = CYR[i] * CSGNI + CYI[i] * CSGNR; + CYR[i] = Str; + Str = -CSGNI * CII; + CSGNI = CSGNR * CII; + CSGNR = Str; + } + goto Return; + 130:; + if(NZ == - 2) + goto 140; + NZ = 0; + IERR = 2; + goto Return; + 140:; + NZ = 0; + IERR = 5; + goto Return; + 260:; + NZ = 0; + IERR = 4; + Return:; +} +/****BEGIN PROLOGUE ZBESJ +!***DATE WRITTEN 830501 (YYMMDD) (Original Fortran 77 version). +!***REVISION DATE 830501 (YYMMDD) +!***CATEGORY NO. B5K +!***KEYWORDS J-BESSEL FUNCTION,BESSEL FUNCTION OF COMPLEX ARGUMENT, +! BESSEL FUNCTION OF FIRST KIND +!***AUTHOR AMOS, DONALD E., SANDIA NATIONAL LABORATORIES +!***PURPOSE TO COMPUTE THE J-BESSEL FUNCTION OF A COMPLEX ARGUMENT +!***DESCRIPTION +! +! ***A DOUBLE PRECISION ROUTINE*** +! ON KODE=1, CBESJ COMPUTES AN N MEMBER SEQUENCE OF COMPLEX +! BESSEL FUNCTIONS CY(I)=J(FNU+I-1,Z) FOR REAL, NONNEGATIVE +! ORDERS FNU+I-1, I=1,...,N AND COMPLEX Z IN THE CUT PLANE +! -PI < ARG(Z) <= PI. ON KODE=2, CBESJ RETURNS THE SCALED +! FUNCTIONS: +! +! CY(I)=EXP(-ABS(Y))*J(FNU+I-1,Z) I = 1,...,N , Y=AIMAG(Z) +! +! WHICH REMOVE THE EXPONENTIAL GROWTH IN BOTH THE UPPER AND +! LOWER HALF PLANES FOR Z TO INFINITY. DEFINITIONS AND NOTATION +! ARE FOUND IN THE NBS HANDBOOK OF MATHEMATICAL FUNCTIONS +! (REF. 1). +! +! INPUT ZR,ZI,FNU ARE DOUBLE PRECISION +! ZR,ZI - Z:=CMPLX(ZR,ZI), -PI.LT.ARG(Z).LE.PI +! FNU - ORDER OF INITIAL J FUNCTION, FNU.GE.0.0D0 +! KODE - A PARAMETER TO INDICATE THE SCALING OPTION +! KODE= 1 RETURNS +! CY(I)=J(FNU+I-1,Z), I=1,...,N +! = 2 RETURNS +! CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y)), I=1,...,N +! N - NUMBER OF MEMBERS OF THE SEQUENCE, N.GE.1 +! +! OUTPUT CYR,CYI ARE DOUBLE PRECISION +! CYR,CYI- DOUBLE PRECISION VECTORS WHOSE FIRST N COMPONENTS +! CONTAIN REAL AND IMAGINARY PARTS FOR THE SEQUENCE +! CY(I)=J(FNU+I-1,Z) OR +! CY(I)=J(FNU+I-1,Z)EXP(-ABS(Y)) I=1,...,N +! DEPENDING ON KODE, Y:=AIMAG(Z). +! NZ - NUMBER OF COMPONENTS SET TO ZERO DUE TO UNDERFLOW, +! NZ= 0 , NORMAL RETURN +! NZ.GT.0 , LAST NZ COMPONENTS OF CY SET ZERO DUE +! TO UNDERFLOW, CY(I):=CMPLX(0.0D0,0.0D0), +! I = N-NZ+1,...,N +! IERR - ERROR FLAG +! IERR=0, NORMAL RETURN - COMPUTATION COMPLETED +! IERR=1, INPUT ERROR - NO COMPUTATION +! IERR=2, OVERFLOW - NO COMPUTATION, AIMAG(Z) +! TOO LARGE ON KODE=1 +! IERR=3, CABS(Z) OR FNU+N-1 LARGE - COMPUTATION DONE +! BUT LOSSES OF SIGNIFCANCE BY ARGUMENT +! REDUCTION PRODUCE LESS THAN HALF OF MACHINE +! ACCURACY +! IERR=4, CABS(Z) OR FNU+N-1 TOO LARGE - NO COMPUTA- +! TION BECAUSE OF COMPLETE LOSSES OF SIGNIFI- +! CANCE BY ARGUMENT REDUCTION +! IERR=5, ERROR - NO COMPUTATION, +! ALGORITHM TERMINATION CONDITION NOT MET +! +!***LONG DESCRIPTION +! +! THE COMPUTATION IS CARRIED OUT BY THE FORMULA +! +! J(FNU,Z)=EXP( FNU*PI*I/2)*I(FNU,-I*Z) AIMAG(Z).GE.0.0 +! +! J(FNU,Z)=EXP(-FNU*PI*I/2)*I(FNU, I*Z) AIMAG(Z).LT.0.0 +! +! WHERE I^2 := -1 AND I(FNU,Z) IS THE I BESSEL FUNCTION. +! +! FOR NEGATIVE ORDERS,THE FORMULA +! +! J(-FNU,Z) = J(FNU,Z)*COS(PI*FNU) - Y(FNU,Z)*SIN(PI*FNU) +! +! CAN BE USED. HOWEVER,FOR LARGE ORDERS CLOSE TO INTEGERS, THE +! THE FUNCTION CHANGES RADICALLY. WHEN FNU IS A LARGE POSITIVE +! INTEGER,THE MAGNITUDE OF J(-FNU,Z):=J(FNU,Z)*COS(PI*FNU) IS A +! LARGE NEGATIVE POWER OF TEN. BUT WHEN FNU IS NOT AN INTEGER, +! Y(FNU,Z) DOMINATES IN MAGNITUDE WITH A LARGE POSITIVE POWER OF +! TEN AND THE MOST THAT THE SECOND TERM CAN BE REDUCED IS BY +! UNIT ROUNDOFF FROM THE COEFFICIENT. THUS, WIDE CHANGES CAN +! OCCUR WITHIN UNIT ROUNDOFF OF A LARGE INTEGER FOR FNU. HERE, +! LARGE MEANS FNU.GT.CABS(Z). +! +! IN MOST COMPLEX VARIABLE COMPUTATION, ONE MUST EVALUATE ELE- +! MENTARY FUNCTIONS. WHEN THE MAGNITUDE OF Z OR FNU+N-1 IS +! LARGE, LOSSES OF SIGNIFICANCE BY ARGUMENT REDUCTION OCCUR. +! CONSEQUENTLY, IF EITHER ONE EXCEEDS U1:=SQRT(0.5/UR), THEN +! LOSSES EXCEEDING HALF PRECISION ARE LIKELY AND AN ERROR FLAG +! IERR:=3 IS TRIGGERED WHERE UR:=DMAX1(D1MACH(4),1.0D-18) IS +! DOUBLE PRECISION UNIT ROUNDOFF LIMITED TO 18 DIGITS PRECISION. +! IF EITHER IS LARGER THAN U2:=0.5/UR, THEN ALL SIGNIFICANCE IS +! LOST AND IERR:=4. IN ORDER TO USE THE INT FUNCTION, ARGUMENTS +! MUST BE FURTHER RESTRICTED NOT TO EXCEED THE LARGEST MACHINE +! INTEGER, U3:=I1MACH(9). THUS, THE MAGNITUDE OF Z AND FNU+N-1 IS +! RESTRICTED BY MIN(U2,U3). ON 32 BIT MACHINES, U1,U2, AND U3 +! ARE APPROXIMATELY 2.0E+3, 4.2E+6, 2.1E+9 IN SINGLE PRECISION +! ARITHMETIC AND 1.3E+8, 1.8E+16, 2.1E+9 IN DOUBLE PRECISION +! ARITHMETIC RESPECTIVELY. THIS MAKES U2 AND U3 LIMITING IN +! THEIR RESPECTIVE ARITHMETICS. THIS MEANS THAT ONE CAN EXPECT +! TO RETAIN, IN THE WORST CASES ON 32 BIT MACHINES, NO DIGITS +! IN SINGLE AND ONLY 7 DIGITS IN DOUBLE PRECISION ARITHMETIC. +! SIMILAR CONSIDERATIONS HOLD FOR OTHER MACHINES. +! +! THE APPROXIMATE RELATIVE ERROR IN THE MAGNITUDE OF A COMPLEX +! BESSEL FUNCTION CAN BE EXPRESSED BY P*10**S WHERE P:=MAX(UNIT +! ROUNDOFF,1.0E-18) IS THE NOMINAL PRECISION AND 10**S REPRE- +! SENTS THE INCREASE IN ERROR DUE TO ARGUMENT REDUCTION IN THE +! ELEMENTARY FUNCTIONS. HERE, S:=MAX(1,ABS(LOG10(CABS(Z))), +! ABS(LOG10(FNU))) APPROXIMATELY (I.E. S:=MAX(1,ABS(EXPONENT OF +! CABS(Z),ABS(EXPONENT OF FNU)) ). HOWEVER, THE PHASE ANGLE MAY +! HAVE ONLY ABSOLUTE ACCURACY. THIS IS MOST LIKELY TO OCCUR WHEN +! ONE COMPONENT (IN ABSOLUTE VALUE) IS LARGER THAN THE OTHER BY +! SEVERAL ORDERS OF MAGNITUDE. IF ONE COMPONENT IS 10**K LARGER +! THAN THE OTHER, THEN ONE CAN EXPECT ONLY MAX(ABS(LOG10(P))-K, +! 0) SIGNIFICANT DIGITS; OR, STATED ANOTHER WAY, WHEN K EXCEEDS +! THE EXPONENT OF P, NO SIGNIFICANT DIGITS REMAIN IN THE SMALLER +! COMPONENT. HOWEVER, THE PHASE ANGLE RETAINS ABSOLUTE ACCURACY +! BECAUSE, IN COMPLEX ARITHMETIC WITH PRECISION P, THE SMALLER +! COMPONENT WILL NOT (AS A RULE) DECREASE BELOW P TIMES THE +! MAGNITUDE OF THE LARGER COMPONENT. IN THESE EXTREME CASES, +! THE PRINCIPAL PHASE ANGLE IS ON THE ORDER OF +P, -P, PI/2-P, +! OR -PI/2+P. +! +!***REFERENCES HANDBOOK OF MATHEMATICAL FUNCTIONS BY M. ABRAMOWITZ +! AND I. A. STEGUN, NBS AMS SERIES 55, U.S. DEPT. OF +! COMMERCE, 1955. +! +! COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +! BY D. E. AMOS, SAND83-0083, MAY, 1983. +! +! COMPUTATION OF BESSEL FUNCTIONS OF COMPLEX ARGUMENT +! AND LARGE ORDER BY D. E. AMOS, SAND83-0643, MAY, 1983 +! +! A SUBROUTINE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +! ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, SAND85- +! 1018, MAY, 1985 +! +! A PORTABLE PACKAGE FOR BESSEL FUNCTIONS OF A COMPLEX +! ARGUMENT AND NONNEGATIVE ORDER BY D. E. AMOS, TRANS. +! MATH. SOFTWARE, 1986 +! +!***ROUTINES CALLED ZABS,ZBINU,I1MACH,D1MACH +!***END PROLOGUE ZBESJ +! +! COMPLEX CI,CSGN,CY,Z,ZN */ /*ZBESJ*/ + + + /* + n:=5; + zr:=1.0; zi:=2.0; + + ZBESJ(zr,zi,0,1,n,cyr,cyi,nz,ierr); + + */ + + + + +} // namespace MathutilInterface + + + + diff --git a/OpenDSSC/Shared/MathutilInterface.h b/OpenDSSC/Shared/MathutilInterface.h new file mode 100644 index 0000000..ebeb632 --- /dev/null +++ b/OpenDSSC/Shared/MathutilInterface.h @@ -0,0 +1,32 @@ +#ifndef MathutilInterfaceH +#define MathutilInterfaceH + +#include +#include "../Support/d2c_system.h" + +#include "../Shared/Ucomplex.h" + +namespace MathutilInterface +{ + + + +/*NOTE: INCOMPLETE IMPLEMENTATION OF THE ZBEZJ ALGORITHM. + CONFIRMED OPERATION OF I0 AND I1 BEFORE FINISHING IT. 8-24-06*/ + + /*Define interface for VBA*/ +void __stdcall I0(Ucomplex::complex& result, Ucomplex::complex& A); +void __stdcall I1(Ucomplex::complex& result, Ucomplex::complex& A); + + +} // namespace MathutilInterface + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace MathutilInterface; +#endif + +#endif // MathutilInterfaceH + + + + diff --git a/OpenDSSC/Shared/PointerList.cpp b/OpenDSSC/Shared/PointerList.cpp new file mode 100644 index 0000000..3865f9d --- /dev/null +++ b/OpenDSSC/Shared/PointerList.cpp @@ -0,0 +1,167 @@ +//#include +#pragma hdrstop + +#include "PointerList.h" + + +using namespace std; +using namespace Arraydef; +using namespace System; + +namespace PointerList +{ + PointerList::TPointerList::TPointerList(): TPointerList(0) {}; + + //------------------------------------------------------------------------- + PointerList::TPointerList::TPointerList(int Size) + { + NumInList = 0; + MaxAllocated = 0; + ActiveItem = 0; + IncrementSize = 0; + MaxAllocated = Size; + if (MaxAllocated <= 0) + MaxAllocated = 10; // Default Size & Increment + List.clear(); + List.resize(MaxAllocated); + ActiveItem = 0; + IncrementSize = MaxAllocated; // Increment is equal to original allocation + } + + //------------------------------------------------------------------------- + + PointerList::TPointerList::~TPointerList() + { +// for (int i = 0; i < List.size(); i++) +// free(List[i]); //# FreeMemory accepts one parameter only; + List.clear(); + // inherited::Destroy(); + } + + //------------------------------------------------------------------------- + + int PointerList::TPointerList::get_myNumList() + { + return NumInList; + } + + //------------------------------------------------------------------------- + + int PointerList::TPointerList::get_myActiveItem() + { + return ActiveItem; + } + + + //------------------------------------------------------------------------- + + int PointerList::TPointerList::Add(void* P) + { + int result = 0; + NumInList++; + if (NumInList > MaxAllocated) + { + std::vector myTmp; + MaxAllocated = MaxAllocated + IncrementSize; + myTmp.resize(MaxAllocated); + for (int idx = 0; idx < List.size(); idx++) + myTmp[idx] = List[idx]; + List = myTmp; + }; + + List[NumInList - 1] = P; + result = NumInList; + ActiveItem = result; + return result; + } + + //------------------------------------------------------------------------- + + void PointerList::TPointerList::Set_New(void* Value) + { + Add(Value); + } + + //------------------------------------------------------------------------- + + void* PointerList::TPointerList::Get_Active() + { + void* result = nullptr; + if ((ActiveItem > 0) && (ActiveItem <= NumInList)) + result = Get(ActiveItem); + else + result = nullptr; + return result; + } + + //------------------------------------------------------------------------- + + void* PointerList::TPointerList::Get_First() + { + void* result = nullptr; + if (NumInList > 0) + { + ActiveItem = 1; + result = (void*)List[ActiveItem - 1]; + } + else + { + ActiveItem = 0; + result = nullptr; + } + return result; + } + + //------------------------------------------------------------------------- + + void* PointerList::TPointerList::Get_Next() + { + void* result = nullptr; + if (NumInList > 0) + { + ++ActiveItem; + if (ActiveItem > NumInList) + { + ActiveItem = NumInList; + result = nullptr; + } + else + result = (void*)List[ActiveItem - 1]; + } + else + { + ActiveItem = 0; + result = nullptr; + } + return result; + } + + //------------------------------------------------------------------------- + + void* PointerList::TPointerList::Get(int i) + { + void* result = NULL; + if ((i < 1) || (i > NumInList)) + result = NULL; + else + { + result = List[i - 1]; + ActiveItem = i; + } + return result; + } + + void PointerList::TPointerList::Clear() + { + ActiveItem = 0; + NumInList = 0; + } + + + +}// namespace PointerList + + + + + diff --git a/OpenDSSC/Shared/PointerList.h b/OpenDSSC/Shared/PointerList.h new file mode 100644 index 0000000..a7e5d48 --- /dev/null +++ b/OpenDSSC/Shared/PointerList.h @@ -0,0 +1,63 @@ +#ifndef PointerListH +#define PointerListH + +#include "System.h" +#include "Sysutils.h" +#include "Arraydef.h" + + + +//class TPointerList; + +namespace PointerList +{ + + + +/*$M+*/ +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TPointerList : public System::TObject +{ +public: + typedef TObject inherited; +//private: + int NumInList; + int MaxAllocated; + int ActiveItem; + std::vector List; + int IncrementSize; + void* Get_First(); + void* Get_Next(); + void* Get_Active(); + void Set_New(void* Value); +public: + int get_myNumList(); + int get_myActiveItem(); + TPointerList(int Size); + virtual ~TPointerList(); + void Clear(); + int Add(void* P); // Returns index of item + void* Get(int i); +//__published: +public: + TPointerList(); +}; + + +} // namespace PointerList + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace PointerList; +#endif + +#endif // PointerListH + + + + diff --git a/OpenDSSC/Shared/Pstcalc.cpp b/OpenDSSC/Shared/Pstcalc.cpp new file mode 100644 index 0000000..407be19 --- /dev/null +++ b/OpenDSSC/Shared/Pstcalc.cpp @@ -0,0 +1,731 @@ +#pragma hdrstop + +#include "Pstcalc.h" + +#include "DSSGlobals.h" +#include +#include + +using namespace std; + + +namespace Pstcalc +{ + + +const int MAXBINS = 50000; +typedef vector < double > BinArray; +typedef BinArray* pBinArray; +typedef double Double6Array[6/*# range 0..5*/]; +double rms_reference = 0.0; // internal rms reference value (do not change) +double FBase = 0.0; //not needed for AC signal input +double Tstep = 0.0; //internal timestep, may or may not equal DeltaT +double Pst_Time = 0.0; +double Pst_Timer = 0.0; +double Pst_Time_Max = 0.0; +double rms_input = 0.0; // nominal line-to-neutral rms input +double RMS_sample = 0.0; +double DeltaT = 0.0; +int NumPstIntervals = 0; +Double6Array vin; +Double6Array X1; +Double6Array X2; +Double6Array X3; +Double6Array X4; +Double6Array X5; +Double6Array X6; +Double6Array X7; +Double6Array X8; +Double6Array X9; +Double6Array X10; +Double6Array RMSVin; +pBinArray Bins0; +pBinArray Bins1; +double bin_ceiling = 0.0; +int number_bins = 0; + + /*Filter Coefficients*/ +double WA2 = 0.0; +double WB2 = 0.0; +double WC2 = 0.0; +double WD2 = 0.0; +double WE2 = 0.0; +double WF2 = 0.0; +double WG2 = 0.0; // weighting filter coefficients + // time constant of sliding mean filter +double IVAA = 0.0; +double IVAB = 0.0; +double IVAC = 0.0; +double IVAD = 0.0; +double IVAE = 0.0; +double BA = 0.0; +double BB = 0.0; +double BC = 0.0; +double BD = 0.0; +double BE = 0.0; +double BG = 0.0; +double BH = 0.0; +double BI = 0.0; +double BJ = 0.0; +double Bk = 0.0; +double bl = 0.0; +double BM = 0.0; +double BN = 0.0; +double BP = 0.0; +double SA = 0.0; +double internal_reference = 0.0; +int lamp_type = 0; // 0 for 120V filters, 1 for 230V filters +int input_type = 0; // 0 for AC, 1 for 1-cycle RMS, 6 for 6-cycle rms + +/////////////////////////////////////////////////////////////////////////////// +// searches through the specified array for a bin and then +// interpolates (if needed) +/////////////////////////////////////////////////////////////////////////////// + +double SB(double Y, pBinArray bins) +{ + double result = 0.0; + int n = 0; + bool Found = false; + Found = false; + n = 0; + while(((!Found) && (n < number_bins))) + if(Y <= (*bins)[n]) + Found = true; + else + n = n + 1; + if(n > 0) + // Interpolate + { + result = bin_ceiling * (n - 1) / number_bins + (Y - (*bins)[n]) * (bin_ceiling / number_bins) / ((*bins)[n] - (*bins)[n]); + } + else + result = 0.0; + return result; +} + +void ZeroOutBins() +{ + int n = 0; + int stop = 0; + for(stop = number_bins - 1, n = 0; n <= stop; n++) + { + (*Bins0)[n] = 0.0; + } + for(stop = number_bins - 1, n = 0; n <= stop; n++) + { + (*Bins1)[n] = 0.0; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Calculates the Pst +/////////////////////////////////////////////////////////////////////////////// + +double CalcPst() +{ + double result = 0.0; + double num_pts = 0.0; // ?? long double Why?? + int n = 0; + double P01 = 0.0; + double P1s = 0.0; + double P3s = 0.0; + double P10s = 0.0; + double P50s = 0.0; + int stop = 0; + num_pts = 0; + for(stop = number_bins - 1, n = 0; n <= stop; n++) + { + num_pts = num_pts + (*Bins0)[n]; + (*Bins1)[n] = num_pts; + } + for(stop = number_bins - 1, n = 0; n <= stop; n++) + { + (*Bins1)[n] = (*Bins1)[n] / num_pts; + } + P01 = SB(0.999, Bins1); + P1s = (SB(0.993, Bins1) + SB(0.990, Bins1) + SB(0.985, Bins1)) / 3.0; + P3s = (SB(0.978, Bins1) + SB(0.970, Bins1) + SB(0.960, Bins1)) / 3.0; + P10s = (SB(0.940, Bins1) + SB(0.920, Bins1) + SB(0.900, Bins1) + SB(0.870, Bins1) + SB(0.830, Bins1)) / 5.0; + P50s = (SB(0.700, Bins1) + SB(0.500, Bins1) + SB(0.200, Bins1)) / 3.0; + + // This is the Pst + result = sqrt(0.0314 * P01 + 0.0525 * P1s + 0.0657 * P3s + 0.28 * P10s + 0.08 * P50s); + return result; +} + +////////////////////////////////////////////////////////////////////// +// Calculates the coefficients for the weighting filter +////////////////////////////////////////////////////////////////////// + +void Set_Filter_Coefficients(int input_type) +{ + double k = 0.0; + double Lambda = 0.0; + double W1 = 0.0; + double W2 = 0.0; + double W3 = 0.0; + double W4 = 0.0; + + // Coefficients for Input Voltage Adapter + // L = 8.93125 H + // C = 35.725 F + // R = 1.0 Ohms + IVAA = 8.93125 * 35.725; + IVAB = 35.725; + IVAC = 4.0 * IVAA / (Tstep * Tstep) + 1.0 - 2.0 * IVAB / Tstep; + IVAD = 2.0 - 8.0 * IVAA / (Tstep * Tstep); + IVAE = 4.0 * IVAA / (Tstep * Tstep) + 1.0 + 2.0 * IVAB / Tstep; + + + // Bandpass centered at 8.5Hz + // 120V lamp + if(lamp_type == 0) + { + k = 1.6357; + Lambda = 26.1843893695; + W1 = 57.0335348916; + W2 = 18.4719490509; + W3 = 8.76170084893; + W4 = 108.794107576; + } + else + // Bandpass centered at 8.8Hz + // 230V lamp + { + k = 1.74802; + Lambda = 25.5085385419; + W1 = 57.5221844961; + W2 = 14.3243430315; + W3 = 7.69910111615; + W4 = 137.601758227; + } + + // Coefficients for Bandpass + // 1st set of substitutions + BA = 0.314159265359; + BB = 113.834561498; + BC = 48361.06156533785; + BD = 311.00180567; + BE = 424.836367168; + // 2nd set of substitutions + BG = 1 + BA * Tstep / 2.0; + BH = BA * Tstep / 2.0 - 1.0; + BI = 4.0 / (Tstep * Tstep) + 2.0 * BB / Tstep + BC; + BJ = -8.0 / (Tstep * Tstep) + 2.0 * BC; + Bk = 4.0 / (Tstep * Tstep) - 2.0 * BB / Tstep + BC; + bl = 4.0 / (Tstep * Tstep) + 2.0 * BD / Tstep + BC; + BM = 4.0 / (Tstep * Tstep) - 2.0 * BD / Tstep + BC; + BN = 4.0 / (Tstep * Tstep) + 2.0 * BE / Tstep + BC; + BP = 4.0 / (Tstep * Tstep) - 2.0 * BE / Tstep + BC; + + // Coefficients for Weighting filter + WA2 = 4.0 * k * W1 * W3 * W4 / (Tstep * Tstep); + WB2 = 2.0 * k * W1 * W2 * W3 * W4 / Tstep; + WC2 = 16.0 * W2 / pow(Tstep, 4); + WD2 = 8.0 * W2 * (2.0 * Lambda + W3 + W4) / pow(Tstep, 3); + WE2 = 4.0 * W2 * (W3 * W4 + W1 * W1 + 2.0 * Lambda * (W3 + W4)) / (Tstep * Tstep); + WF2 = 2.0 * W2 * (2.0 * Lambda * W3 * W4 + W1 * W1 * (W3 + W4)) / Tstep; + WG2 = W2 * W3 * W4 * W1 * W1; + + // time constant of sliding mean filter + SA = 0.3; + + // internal reference + if(input_type == 0) + internal_reference = 676.372; // See "new 868 testing and scaling.xls" for derivation + if(input_type == 1) + internal_reference = 0.01106784; // new scaling factor 7/25/05, based on 1-cycle RMS + // using greater than 1-cycle RMS may result in errors + if(input_type == 3) + internal_reference = 0.009; // new scaling factor 8/3/05, based on 3-cycle RMS + if(input_type == 6) + internal_reference = 0.008449; // new scaling factor 7/25/05, based on 6-cycle RMS +} + +////////////////////////////////////////////////////////////////////// +// Put samples that get through the filter in the proper bins +////////////////////////////////////////////////////////////////////// + +void Gather_Bins(double X10_value, pBinArray bins) +{ + + auto My_inc = [&](double& X) -> void + { + X = X + 1.0; + }; // special incrementer routine + if(X10_value > bin_ceiling) // increment count + My_inc((*bins)[number_bins]); + else + My_inc((*bins)[Trunc(number_bins * X10_value / bin_ceiling)]); +} + +/*Find out which bin the value belongs in and increment it.*/ + +/////////////////////////////////////////////////////////////////////////////// +// shifts every array value up (back in time) +/////////////////////////////////////////////////////////////////////////////// + +void Sample_Shift() +{ + int n = 0; + int stop = 0; + for(stop = 1, n = 5; n >= stop; n--) + { + vin[n] = vin[n]; + RMSVin[n] = RMSVin[n]; + X1[n] = X1[n]; + X2[n] = X2[n]; + X3[n] = X3[n]; + X4[n] = X4[n]; + X5[n] = X5[n]; + X6[n] = X6[n]; + X7[n] = X7[n]; + X8[n] = X8[n]; + X9[n] = X9[n]; + X10[n] = X10[n]; + } +} + +/////////////////////////////////////////////////////////////////////////////// +// Main Flicker Calculation Function +/////////////////////////////////////////////////////////////////////////////// + +void Get_Pinst() +{ + + + /*RMS input*/ + RMSVin[0] = rms_reference * RMS_sample / rms_input; // per unitize rms value + X1[0] = (RMSVin[0] + 2.0 * RMSVin[1] + RMSVin[2] - IVAD * X1[1] - IVAC * X1[2]) / IVAE; + X3[0] = RMSVin[0] * (1.0 - (X1[0] - 120.0) / RMSVin[0]); + + // Bandpass (HP at .05Hz and 6th order Butteworth LP at 35Hz) + X4[0] = (X3[0] - X3[1] - BH * X4[1]) / BG; + X5[0] = (BC * (X4[0] + 2 * X4[1] + X4[2]) - (BJ * X5[1] + Bk * X5[2])) / BI; + X6[0] = (BC * (X5[0] + 2 * X5[1] + X5[2]) - (BJ * X6[1] + BM * X6[2])) / bl; + X7[0] = (BC * (X6[0] + 2 * X6[1] + X6[2]) - (BJ * X7[1] + BP * X7[2])) / BN; + + // Weighting filter + X8[0] = ((WA2 + WB2) * X7[0] + 2 * WB2 * X7[1] - 2 * WA2 * X7[2] - 2 * WB2 * X7[3] + (WA2 - WB2) * X7[4] - (2 * WF2 + 4 * WG2 - 4 * WC2 - 2 * WD2) * X8[1] - (6 * WC2 - 2 * WE2 + 6 * WG2) * X8[2] - (2 * WD2 + 4 * WG2 - 4 * WC2 - 2 * WF2) * X8[3] - (WC2 - WD2 + WE2 - WF2 + WG2) * X8[4]) / (WC2 + WD2 + WE2 + WF2 + WG2); + + // Sliding Mean filter + X9[0] = (X8[0] * X8[0] + X8[1] * X8[1] - (1 - 2 * SA / Tstep) * X9[1]) / (1 + 2 * SA / Tstep); + X10[0] = X9[0] / internal_reference; +} + +//******************************************************************* +//******************************************************************* + +void Init6Array(Double6Array* Y, double V1, double V2, double V3, double V4, double V5, double V6) +{ + *Y[0] = V1; + *Y[1] = V2; + *Y[2] = V3; + *Y[3] = V4; + *Y[4] = V5; + *Y[5] = V6; +} + +//******************************************************************* +//******************************************************************* + +int _Pst(pDoubleArray PstResult, pDoubleArray VArray, int npts) +{ + int result = 0; + int PstInterval = 0; + double max_flicker = 0.0; + double Time = 0.0; // long double??? + int VIndex = 0; + int ipst = 0; + double FirstSample = 0.0; + double PST_STart_Time = 0.0; + int SynthesizedSamples = 0; + double SamplesPerDeltaT = 0.0; // this value is used when RMS data is used as input + + +// DEBUG file + int stop = 0; + rms_reference = 120.0; // internal rms reference value (do not change) + Init6Array(&vin, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&RMSVin, rms_reference, rms_reference, rms_reference, rms_reference, rms_reference, rms_reference); // RMS input voltage + Init6Array(&X1, rms_reference, rms_reference, rms_reference, rms_reference, rms_reference, rms_reference); + Init6Array(&X2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Output of Block 1 + Init6Array(&X3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Output of Block 2 + Init6Array(&X4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&X5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&X6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&X7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&X8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Output of Block 3 + Init6Array(&X9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + Init6Array(&X10, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Output of Block 4 + bin_ceiling = 350.0; // previously used 215, increased to be encompass high flicker levels + number_bins = 16000; + + /*Allocate Memory for bins*/ + Bins0->resize(number_bins); // 50k is max. # of bins + Bins1->resize(number_bins); // 50k is max. # of bins + Time = 0.0; // time clock + Pst_Timer = 0.0; + ZeroOutBins(); + Tstep = 1.0 / (16.0 * FBase); // time step for each cycle, fixed to 16 samples/cycle + Pst_Time_Max = npts * DeltaT; // - 6.0 ; //use the entire data set sent to calculate the flicker + Pst_Time = min(600.0, Pst_Time_Max); + NumPstIntervals = max( (int64_t) 1 , Trunc(Pst_Time_Max / Pst_Time)); // At least one interval + if(PstResult != NULL) + PstResult = (pDoubleArray) realloc(PstResult, 0); + PstResult = (pDoubleArray) realloc(PstResult,sizeof(double) * NumPstIntervals); // allocate result array + Set_Filter_Coefficients(input_type); + + // //********************************************************************************* + // Main RMS routine + // ///********************************************************************************* + SamplesPerDeltaT = DeltaT / Tstep; + max_flicker = 0.0; + FirstSample = VArray[1]; + rms_input = FirstSample; + RMS_sample = FirstSample; + + // inits filter to 1 PU for 30 s + while((Time < 30.0)) + { + Time = Time + Tstep; + Get_Pinst(); // Computes what get's through filter (X10 ) + Sample_Shift(); + } + PST_STart_Time = Time + 5.0; // Give it 5 s to settle down after real data starts + VIndex = 1; + PstInterval = 0; + for(stop = npts, ipst = 1; ipst <= stop; ipst++) + { + int stop1 = 0; + RMS_sample = VArray[VIndex]; + // The following loop holds the rms input samples constant over the RMS period + for(stop1 = Round(SamplesPerDeltaT), SynthesizedSamples = 1; SynthesizedSamples <= stop1; SynthesizedSamples++) + { + Get_Pinst(); // Computes what gets through filter (X10[0] ) + + /*////////////// This starts the Pst calculations //////////////*/ + if(Time >= PST_STart_Time) + { + Pst_Timer = Pst_Timer + Tstep; + max_flicker = max(max_flicker, X10[0]); + Gather_Bins(X10[0], Bins0); + if(Pst_Timer >= Pst_Time) + // OK, we got everything in the bins, let's compute Pst + { + ++PstInterval; + if(PstInterval <= NumPstIntervals) + PstResult[PstInterval] = CalcPst(); + Pst_Timer = 0.0; + ZeroOutBins(); // Zero Bins0 and Bins1 out for next time + } + } + Sample_Shift(); + Time = Time + Tstep; + } + ++VIndex; + } + result = PstInterval; // should be NumPstIntervals + Bins0->clear(); + Bins1->clear(); + return result; +} + +// Function call for executing PST calculator using RMS data + +int PstRMS(pDoubleArray PstResult, pDoubleArray pVoltages, double Freqbase, int NcyclesperSample, int npts, int Lamp) +{ + int result = 0; + FBase = Freqbase; + + // lamp_type := 0; // 0 for 120V filters, 1 for 230V filters + input_type = 6; // 0 for AC, 1 for 1-cycle RMS, 6 for 6-cycle rms + + //Check for the lamp type (120 or 230), default to 120 if not read properly + if(Lamp == 230) + { + lamp_type = 1; + } + else + { + lamp_type = 0; + } + DeltaT = double(NcyclesperSample) / FBase; + result = _Pst(PstResult, pVoltages, npts); + return result; +} + // returns number of Pst elements computed + // will automatically clean up PstStruct when it is reallocated; Init to nil + + +///////////////////////////////////////////////////////// +// +// RMS flickermeter implementation +// +///////////////////////////////////////////////////////// + +void Fhp(int n, float TS, float whp, pSingleArray X, pSingleArray Y) +{ + float A = 0.0F; + float A0 = 0.0F; + float A1 = 0.0F; + int j = 0; + int stop = 0; + Y[1] = 0.0F; + A = (float) (0.5F * TS * whp); + A0 = (float) (A + 1.0F); + A1 = (float) (A - 1.0F); + for(stop = n, j = 2; j <= stop; j++) + { + Y[j] = (float) ((1.0F / A0) * (X[j] - X[j - 1] - A1 * Y[j - 1])); + } +} + +void Flp(int n, float TS, float tau, pSingleArray X, pSingleArray Y) +{ + float A0 = 0.0F; + float A1 = 0.0F; + int j = 0; + int stop = 0; + Y[1] = 0.0F; + A0 = (float) (1 + 2 * tau / TS); + A1 = (float) (1 - 2 * tau / TS); + for(stop = n, j = 2; j <= stop; j++) + { + Y[j] = (float) ((1.0F / A0) * (X[j] + X[j - 1] - A1 * Y[j - 1])); + } +} + +void Fw1(int n, float TS, float W1, float k, float lam, pSingleArray X, pSingleArray Y) +{ + float A0 = 0.0F; + float A1 = 0.0F; + float A2 = 0.0F; + float B0 = 0.0F; + float B2 = 0.0F; + int j = 0; + int stop = 0; + Y[1] = 0.0F; + Y[2] = 0.0F; + B0 = (float) (2.0F * k * W1 * TS); + B2 = (float) (-2.0F * k * W1 * TS); + A0 = (float) (W1 * W1 * TS * TS + 4.0F * lam * TS + 4.0F); + A1 = (float) (2.0F * W1 * W1 * TS * TS - 8.0F); + A2 = (float) (W1 * W1 * TS * TS - 4.0F * lam * TS + 4.0F); + for(stop = n, j = 3; j <= stop; j++) + { + Y[j] = (float) ((1.0F / A0) * (B0 * X[j] + B2 * X[j - 2] - A1 * Y[j - 1] - A2 * Y[j - 2])); + } +} + +void Fw2(int n, float TS, float W2, float W3, float W4, pSingleArray X, pSingleArray Y) +{ + float A0 = 0.0F; + float A1 = 0.0F; + float A2 = 0.0F; + float B0 = 0.0F; + float B1 = 0.0F; + float B2 = 0.0F; + int j = 0; + int stop = 0; + Y[1] = 0.0F; + Y[2] = 0.0F; + B0 = (float) (W3 * W4 * (TS * TS * W2 + 2.0F * TS)); + B1 = (float) (W3 * W4 * 2.0F * TS * TS * W2); + B2 = (float) (W3 * W4 * (TS * TS * W2 - 2.0F * TS)); + A0 = (float) (W2 * (TS * TS * W3 * W4 + 2.0F * TS * (W3 + W4) + 4)); + A1 = (float) (W2 * (2.0F * TS * TS * W3 * W4 - 8.0F)); + A2 = (float) (W2 * (TS * TS * W3 * W4 - 2.0F * TS * (W3 + W4) + 4)); + for(stop = n, j = 3; j <= stop; j++) + { + Y[j] = (float) ((1.0F / A0) * (B0 * X[j] + B1 * X[j - 1] + B2 * X[j - 2] - A1 * Y[j - 1] - A2 * Y[j - 2])); + } +} + +void QuickSort(vector List, int iLo, int iHi) +{ + int Lo = 0; + int Hi = 0; + float T = 0.0F; + float mid = 0.0F; + Lo = iLo; + Hi = iHi; + mid = List[floor((Lo + Hi) / 2)]; + do + { + while(List[Lo] < mid) + ++Lo; + while(List[Hi] > mid) + --Hi; + if(Lo <= Hi) + { + T = List[Lo]; + List[Lo] = List[Hi]; + List[Hi] = T; + ++Lo; + --Hi; + } + } + while(!(Lo > Hi)); + if(Hi > iLo) + QuickSort(List, iLo, Hi); + if(Lo < iHi) + QuickSort(List, Lo, iHi); +} + +float Percentile(vector List, int iLo, int iHi, float pctExceeded) +{ + float result = 0.0F; + int nlo = 0; + int nhi = 0; + float xhst = 0.0F; + float xlo = 0.0F; + float xhi = 0.0F; + float xfrac = 0.0F; + float pct = 0.0F; + pct = (float) (100.0F - pctExceeded); + xhst = (float) (iHi - iLo + 1); + xfrac = (float) Frac(0.01F * pct * xhst); + nlo = Trunc(0.01F * pct * xhst); + nhi = nlo + 1; + xlo = List[nlo]; + xhi = List[nhi]; + result = (float) (xlo + xfrac * (xhi - xlo)); + return result; +} + +void FlickerMeter(int n, double FBase, double VBase, pSingleArray Pt, pSingleArray pRms, pSingleArray pPst) +{ + int i = 0; + int ipst = 0; + int ihst = 0; + float T = 0.0F; + float tpst = 0.0F; + // filter coefficients + float whp = 0.0F; + float W1 = 0.0F; + float W2 = 0.0F; + float W3 = 0.0F; + float W4 = 0.0F; + float k = 0.0F; + float lam = 0.0F; + float tau = 0.0F; + float TS = 0.0F; + float cf = 0.0F; + pSingleArray PBuf = new float[1]; + vector hst; + float pst = 0.0F; + float p01s = 0.0F; + float P1s = 0.0F; + float P3s = 0.0F; + float P10s = 0.0F; + float P50s = 0.0F; + float p30 = 0.0F; + float p50 = 0.0F; + float p80 = 0.0F; + float p17 = 0.0F; + float p13 = 0.0F; + float p10 = 0.0F; + float p8 = 0.0F; + float p6 = 0.0F; + float p4 = 0.0F; + float p3 = 0.0F; + float p2p2 = 0.0F; + float p1p5 = 0.0F; + float P1 = 0.0F; + float p0p7 = 0.0F; + int stop = 0; + whp = (float) (2.0 * PI * 0.05); + tau = 0.3F; + cf = (float) (1.0F / 1.285e-6F); + if(FBase == 50.0) + { + k = 1.74802F; + lam = (float) (2.0 * PI * 4.05981); + W1 = (float) (2.0 * PI * 9.15494); + W2 = (float) (2.0 * PI * 2.27979); + W3 = (float) (2.0 * PI * 1.22535); + W4 = (float) (2.0 * PI * 21.9); + } + else + { + k = (float) (1.6357F / 0.783F); + lam = (float) (2.0 * PI * 4.167375); + W1 = (float) (2.0 * PI * 9.077169); + W2 = (float) (2.0 * PI * 2.939902); + W3 = (float) (2.0 * PI * 1.394468); + W4 = (float) (2.0 * PI * 17.31512); + } + tpst = 0.0F; + ipst = 1; + TS = (float) (Pt[2] - Pt[1]); + for(stop = n, i = 1; i <= stop; i++) + { + pRms[i] = (float) (pRms[i] / VBase); + } + PBuf = (pSingleArray) realloc(PBuf, sizeof(float) * n); + Fhp(n, TS, whp, pRms, PBuf); + Fw1(n, TS, W1, k, lam, PBuf, pRms); + Fw2(n, TS, W2, W3, W4, pRms, PBuf); + for(stop = n, i = 1; i <= stop; i++) + { + PBuf[i] = (float) (PBuf[i] * PBuf[i]); + } + Flp(n, TS, tau, PBuf, pRms); + for(stop = n, i = 1; i <= stop; i++) + { + pRms[i] = (float) (cf * pRms[i]); + } + + // build the Blcok 5 Pst outputs from Block 4 instantaneous flicker levels + hst.resize(Trunc(600.0F / TS) + 1); + ihst = MinValue(&hst); + for(stop = n, i = 1; i <= stop; i++) + { + T = Pt[i]; + hst[ihst] = pRms[i]; + if((T - tpst) >= 600.0) // append a new Pst value + { + auto it0 = MinValue(&hst); + QuickSort(hst, 0, ihst); + p80 = Percentile(hst, 0, ihst, 80.0F); + p50 = Percentile(hst, 0, ihst, 50.0F); + p30 = Percentile(hst, 0, ihst, 30.0F); + p17 = Percentile(hst, 0, ihst, 17.0F); + p13 = Percentile(hst, 0, ihst, 13.0F); + p10 = Percentile(hst, 0, ihst, 10.0F); + p8 = Percentile(hst, 0, ihst, 8.0F); + p6 = Percentile(hst, 0, ihst, 6.0F); + p4 = Percentile(hst, 0, ihst, 4.0F); + p3 = Percentile(hst, 0, ihst, 3.0F); + p2p2 = Percentile(hst, 0, ihst, 2.2F); + p1p5 = Percentile(hst, 0, ihst, 1.5F); + P1 = Percentile(hst, 0, ihst, 1.0F); + p0p7 = Percentile(hst, 0, ihst, 0.7F); + p01s = Percentile(hst, 0, ihst, 0.1F); + P50s = (float) ((p30 + p50 + p80) / 3.0); + P10s = (float) ((p6 + p8 + p10 + p13 + p17) / 5.0); + P3s = (float) ((p2p2 + p3 + p4) / 3.0); + P1s = (float) ((p0p7 + P1 + p1p5) / 3.0); + pst = (float) sqrt(0.0314F * p01s + 0.0525F * P1s + 0.0657F * P3s + 0.28F * P10s + 0.08F * P50s); + pPst[ipst] = pst; + ++ipst; + tpst = T; + ihst = MinValue(&hst); + } + else + { + ++ihst; + } + } +} + + + + +} // namespace Pstcalc + + + + diff --git a/OpenDSSC/Shared/Pstcalc.h b/OpenDSSC/Shared/Pstcalc.h new file mode 100644 index 0000000..6fde980 --- /dev/null +++ b/OpenDSSC/Shared/Pstcalc.h @@ -0,0 +1,61 @@ +#ifndef PstcalcH +#define PstcalcH + +#include "System.h" +#include "Sysutils.h" +#include "Arraydef.h" +#include + + +namespace Pstcalc +{ + + + + /* + ---------------------------------------------------------- + Copyright (c) 2011-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +// IEC868 FlickerMeter +// Adapted from Jeff Smith's original C++ code +// note: the scaling factor being used has been corrected. It is scaling the output of Block 4 to +// 1.0 for the values given in Table 1 and Table 2. The last table in the std should be used for checking Pst +// 4/12/05 The meter is verified using Table 2 and Table 5 (Pinst and Pst tables) +// 7/28/05: This cpp is designed to receive a 6-cycle rms data stream from the dss and return Pst +// 8/3/05: Updated to receive single to 6-cycle rms data streams. The rms window "DeltaT" determines which scaling factor to use +// 8/4/05: added back functionality to receive AC data. Now these are 2 separate loops +// 8/31/11 Converted to Object Pascal +// 9/6/11 Removed PstAC code +// 1/22/2013 added RMS flickermeter implementation (temc) + +// Note: allocates result array of doubles!!! +int PstRMS(Arraydef::pDoubleArray PstResult, Arraydef::pDoubleArray pVoltages, double Freqbase, int NcyclesperSample, int npts, int Lamp); + // returns number of Pst elements computed in PstResult array + // That is the number of 10-minute intervals + // will automatically clean up and reallocate PstStruct when this function is called + // Init PstResult to Nil in calling routine. + // Dispose of result in colling routine when done with it. + +// input: N points of RMS voltage in pT, pRms +// fBase (50 or 60) determines the weighting coefficients +// vBase to normalize the RMS voltage to per-unit +// pre-allocate pPst to hold the Pst results at 10-minute intervals +// output: pRms overwritten with Block 4 flicker output +// pPst written with Block 5 Pst at 10-minute intervals +void FlickerMeter(int n, double FBase, double VBase, Arraydef::pSingleArray Pt, Arraydef::pSingleArray pRms, Arraydef::pSingleArray pPst); + + +} // namespace Pstcalc + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Pstcalc; +#endif + +#endif // PstcalcH + + + + diff --git a/OpenDSSC/Shared/RCDList.cpp b/OpenDSSC/Shared/RCDList.cpp new file mode 100644 index 0000000..0a8d022 --- /dev/null +++ b/OpenDSSC/Shared/RCDList.cpp @@ -0,0 +1,89 @@ + +#pragma hdrstop + +#include "RCDList.h" + +using namespace std; + + +namespace RCDList +{ + + + +TRCDList::TRCDList() + : PresentItem((short int) -1) +{ + ; +} + +TRCDList::~TRCDList() +{ + // inherited::Destroy(); +} + + +void* TRCDList::FirstItem() +{ + void* result = nullptr; + if(Count > 0) + { + result = Items[0]; + PresentItem = 0; + } + else + { + result = nullptr; + PresentItem = (short int) -1; + } + return result; +} + +void* TRCDList::NextItem(void* PrevItem) +{ + void* result = nullptr; + int i = 0; + if(PrevItem != Items[PresentItem]) + /*List has been used by someone after it was initiated.. Reset list to match PreviousItem*/ + { + int stop = 0; + PresentItem = (short int) (Count - 1); + for(stop = Count - 1, i = 0; i <= stop; i++) + { + if(Items[i] == PrevItem) + { + PresentItem = (short int) i; + break; + } + } + /*If we can't make it match, PresentItem will point to last Item and + the next operation (below) will return nil*/ + } + ++PresentItem; + if(Count > PresentItem) + { + result = Items[PresentItem]; + } + else + { + result = nullptr; + PresentItem = (short int) (Count - 1); + } + return result; +} + +int TRCDList::ItemIndex() +{ + int result = 0; + result = PresentItem; + return result; +} + + + + +} // namespace RCDList + + + + diff --git a/OpenDSSC/Shared/RCDList.h b/OpenDSSC/Shared/RCDList.h new file mode 100644 index 0000000..9457ff9 --- /dev/null +++ b/OpenDSSC/Shared/RCDList.h @@ -0,0 +1,38 @@ +#ifndef RCDListH +#define RCDListH + +#include "System.h" +#include "Sysutils.h" +#include "d2c_structures.h" + + +namespace RCDList +{ + + +class TRCDList : public TList +{ +public: + typedef TList inherited; +private: + short int PresentItem; +public: + TRCDList(); + virtual ~TRCDList(); + void* FirstItem(); + void* NextItem(void* PrevItem); + int ItemIndex(); +}; + + +} // namespace RCDList + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace RCDList; +#endif + +#endif // RCDListH + + + + diff --git a/OpenDSSC/Shared/ReportForm.cpp b/OpenDSSC/Shared/ReportForm.cpp new file mode 100644 index 0000000..10ce155 --- /dev/null +++ b/OpenDSSC/Shared/ReportForm.cpp @@ -0,0 +1,22 @@ +#include +#pragma hdrstop + +#include "ReportForm.h" + +using namespace std; +using namespace d2c_system; +using namespace System; +using namespace System::Classes; + + +TReport::TReport(System::Classes::TComponent* AOwner) : inherited(AOwner) {} + + +TReport* Report = nullptr; +#pragma resource "*.DFM" + + + + + + diff --git a/OpenDSSC/Shared/ReportForm.h b/OpenDSSC/Shared/ReportForm.h new file mode 100644 index 0000000..b8c2f77 --- /dev/null +++ b/OpenDSSC/Shared/ReportForm.h @@ -0,0 +1,35 @@ +#ifndef ReportFormH +#define ReportFormH + +#include +#include "../Support/d2c_system.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +class TReport : public TForm +{ +__published: + TMemo* Memo1; +private: + /* Private declarations */ +public: + /* Public declarations */ + typedef TForm inherited; + TReport(System::Classes::TComponent* AOwner); +}; +extern PACKAGE TReport* Report; +#endif // ReportFormH + + + + diff --git a/OpenDSSC/Shared/StackDef.cpp b/OpenDSSC/Shared/StackDef.cpp new file mode 100644 index 0000000..f7a8483 --- /dev/null +++ b/OpenDSSC/Shared/StackDef.cpp @@ -0,0 +1,129 @@ + +#pragma hdrstop + +#include "StackDef.h" + + +using namespace std; + +namespace StackDef +{ + +TStackBase::TStackBase() {} +TPstack::TPstack() {} +TiStack::TiStack() {} + + + +TStackBase::TStackBase(int initSize) + : NumItems(0), + Increment(0), + MaxItems(0) +{ + ; + MaxItems = initSize; + Increment = initSize; +} + +TStackBase::~TStackBase() +{ + // inherited::Destroy(); +} + + +void TStackBase::Clear() +{ + NumItems = 0; +} + +int TStackBase::Size() +{ + int result = 0; + result = NumItems; + return result; +} + +//------------------------------------------------------- + +TPstack::TPstack(int initSize) + : inherited(initSize), + Items((PPointerArray) malloc(sizeof((Items)[1 - 1]) * MaxItems)) +{ +} + +TPstack::~TPstack() +{ + ReallocMem(Items, 0); + // inherited::Destroy(); +} + + +void TPstack::Push(void* P) +{ + ++NumItems; + if(NumItems > MaxItems) + { + MaxItems += Increment; + ReallocMem(Items, sizeof((Items)[1 - 1]) * MaxItems); + } + (Items)[NumItems - 1] = P; +} + +void* TPstack::Pop() +{ + void* result = nullptr; + if(NumItems > 0) + { + result = (Items)[NumItems - 1]; + --NumItems; + } + else + result = nullptr; + return result; +} + +TiStack::TiStack(int initSize) + : inherited(initSize), + Items((pIntegerArray)malloc(sizeof((Items)[1 - 1])* MaxItems)) +{ +} + +TiStack::~TiStack() +{ + ReallocMem(Items, 0); + // inherited::Destroy(); +} + + +void TiStack::Push(int P) +{ + ++NumItems; + if(NumItems > MaxItems) + { + MaxItems += Increment; + ReallocMem(Items, sizeof(Items[1 - 1]) * MaxItems); + } + Items[NumItems - 1] = P; +} + +int TiStack::Pop() +{ + int result = 0; + if(NumItems > 0) + { + result = Items[NumItems - 1]; + --NumItems; + } + else + result = 0; + return result; +} + + + + +} // namespace StackDef + + + + diff --git a/OpenDSSC/Shared/StackDef.h b/OpenDSSC/Shared/StackDef.h new file mode 100644 index 0000000..ba7ad95 --- /dev/null +++ b/OpenDSSC/Shared/StackDef.h @@ -0,0 +1,76 @@ +#ifndef StackDefH +#define StackDefH + +#include "System.h" +#include "Sysutils.h" + +#include "Arraydef.h" + +namespace StackDef +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +class TStackBase : public System::TObject +{ +public: + typedef TObject inherited; +//private: +protected: + int NumItems; + int Increment; + int MaxItems; +public: + TStackBase(int initSize); + virtual ~TStackBase(); + void Clear(); + int Size(); + TStackBase(); +}; // simple pointer stack + +class TPstack : public TStackBase +{ +public: + typedef TStackBase inherited; +//private: + Arraydef::PPointerArray Items; +public: + TPstack(int initSize); + virtual ~TPstack(); + void Push(void* P); + void* Pop(); + TPstack(); +}; // simple integer stack + +class TiStack : public TStackBase +{ +public: + typedef TStackBase inherited; +//private: + Arraydef::pIntegerArray Items; +public: + TiStack(int initSize); + virtual ~TiStack(); + void Push(int P); + int Pop(); + TiStack(); +}; + + +} // namespace StackDef + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace StackDef; +#endif + +#endif // StackDefH + + + + diff --git a/OpenDSSC/Shared/TestHashForm.cpp b/OpenDSSC/Shared/TestHashForm.cpp new file mode 100644 index 0000000..5de64ec --- /dev/null +++ b/OpenDSSC/Shared/TestHashForm.cpp @@ -0,0 +1,103 @@ +#include +#pragma hdrstop + +#include "TestHashForm.h" +#include "../Shared/HashList.h" +#include "../Shared/Command.h" +#include "../Support/d2c_sysfile.h" +#include "d2c_openarray.h" + +using namespace std; +using namespace d2c_system; +using namespace Command; +using namespace Hashlist; +using namespace System; +using namespace System::Classes; +using namespace System::Sysutils; +using namespace System::Uitypes; +using namespace Vcl::Dialogs; + +#define TestHashForm__0 (TMsgDlgButtons() << System::Uitypes::TMsgDlgBtn::mbOK) + +TTestForm::TTestForm(System::Classes::TComponent* AOwner) : inherited(AOwner) {} + + +TTestForm* TestForm = nullptr; +#pragma resource "*.DFM" + +THashList* HashLst = nullptr; +TCommandList* cmdList = nullptr; + +void TTestForm::Button1Click(TObject* Sender) +{ + d2c_system::TTextRec f = {}; + String s; + int i = 0; + HashLst = new THashList(50); + try + { + AssignFile(f, L"HashNames.Txt"); + Reset(f); + IOResultToException(); + while(!Eof(f)) + { + ReadLn(f, s); + i = HashLst->Add(s); + } + } + catch(...) + { + MessageDlg(L"Error with input file", System::Uitypes::TMsgDlgType::mtError, TestHashForm__0, 0); + } + CloseFile(f); + HashLst->DumpToFile(); +} + +void TTestForm::Button2Click(TObject* Sender) +{ + Edit2->Text = IntToStr(HashLst->Find(Edit1->Text)); +} + +void TTestForm::Button4Click(TObject* Sender) +{ + int i = 0; + i = HashLst->FindAbbrev(Edit1->Text); + Edit2->Text = IntToStr(i); + Edit1->Text = HashLst->Get((unsigned int) i); +} + +void TTestForm::Button3Click(TObject* Sender) +{ + Edit1->Text = HashLst->Get((unsigned int) StrToInt(Edit2->Text)); +} + +void TTestForm::Button5Click(TObject* Sender) +{ + String cmd[10/*# range 1..10*/]; + cmd[1 - 1] = L"AddCapacitor"; + cmd[2 - 1] = L"Secondcommand"; + cmd[3 - 1] = L"Thirdcommand"; + cmd[4 - 1] = L"4thcommand"; + cmd[5 - 1] = L"5thcommand"; + cmd[6 - 1] = L"6thcommand"; + cmd[7 - 1] = L"7thcommand"; + cmd[8 - 1] = L"8thcommand"; + cmd[9 - 1] = L"9thcommand"; + cmd[10 - 1] = L"Lastcommand"; + cmdList = new TCommandList(OpenArrayEx(cmd, 10), 9); +} + +void TTestForm::Button6Click(TObject* Sender) +{ + Label1->Caption = IntToStr(cmdList->Getcommand(Edit3->Text)); +} + +void TTestForm::Button7Click(TObject* Sender) +{ + cmdList->set_AbbrevAllowed(!cmdList->get_AbbrevAllowed); +} + + + + + diff --git a/OpenDSSC/Shared/TestHashForm.h b/OpenDSSC/Shared/TestHashForm.h new file mode 100644 index 0000000..b0bf669 --- /dev/null +++ b/OpenDSSC/Shared/TestHashForm.h @@ -0,0 +1,52 @@ +#ifndef TestHashFormH +#define TestHashFormH + +#include +#include "../Support/d2c_system.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +class TTestForm : public TForm +{ +__published: + TButton* Button1; + TEdit* Edit1; + TButton* Button2; + TEdit* Edit2; + TButton* Button3; + TButton* Button4; + TButton* Button5; + TEdit* Edit3; + TButton* Button6; + TLabel* Label1; + TButton* Button7; + void Button1Click(TObject* Sender); + void Button2Click(TObject* Sender); + void Button4Click(TObject* Sender); + void Button3Click(TObject* Sender); + void Button5Click(TObject* Sender); + void Button6Click(TObject* Sender); + void Button7Click(TObject* Sender); +private: + /* Private declarations */ +public: + /* Public declarations */ + typedef TForm inherited; + TTestForm(System::Classes::TComponent* AOwner); +}; +extern PACKAGE TTestForm* TestForm; +#endif // TestHashFormH + + + + diff --git a/OpenDSSC/Shared/Ucmatrix.cpp b/OpenDSSC/Shared/Ucmatrix.cpp new file mode 100644 index 0000000..512d5b4 --- /dev/null +++ b/OpenDSSC/Shared/Ucmatrix.cpp @@ -0,0 +1,524 @@ + +#pragma hdrstop + +#include "Ucmatrix.h" + +using namespace std; + + +namespace Ucmatrix +{ + +TcMatrix::TcMatrix() {} + + +//#pragma resource "-" + /* Turn off range checking*/ +/*--------------------------------------------------------------------------*/ + +TcMatrix::TcMatrix(int n) + : Norder(0), + InvertError(0) +{ + Values.clear(); + int i = 0; + try + { + int stop = 0; + ; + Norder = n; + InvertError = 0; + Values.resize(Norder * Norder); /*Allocate*/ + for(stop = (Norder * Norder), i = 1; i <= stop; i++) + { + Values[i - 1] = cmplx(0.0, 0.0); + } + } + catch(...) + { + //Destroy(); + } +} + + /*--------------------------------------------------------------------------*/ + +TcMatrix::~TcMatrix() +{ + if(!Values.empty()) + Values.clear(); + // inherited::Destroy(); +} + +/*--------------------------------------------------------------------------*/ + +int TcMatrix::get_Norder() +{ + return Norder; +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::Clear() +{ + int i = 0; + int stop = 0; + for(stop = (Norder * Norder), i = 1; i <= stop; i++) + { + Values[i - 1] = cmplx(0.0, 0.0); + } +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::MVmult(pComplexArray B, pComplexArray X) +{ + complex Sum = {}; + int i = 0; + int j = 0; + int stop = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + Sum = cmplx(0.0, 0.0); + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + caccum(Sum, cmul(Values[((j - 1) * Norder + i) - 1], X[j - 1])); + } + B[i - 1] = Sum; + } +} + /*--------------------------------------------------------------------------*/ + // Same as MVMult except accumulates b + +void TcMatrix::MVmultAccum(pComplexArray B, pComplexArray X) +{ + complex Sum = {}; + int i = 0; + int j = 0; + int stop = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + Sum = cmplx(0.0, 0.0); + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + caccum(Sum, cmul(Values[((j - 1) * Norder + i) - 1], X[j - 1])); + } + caccum(B[i - 1], Sum); + } +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::Invert() +{ + typedef std::vector < int > IntArray; + typedef IntArray pIntArray; + int j = 0; + int k = 0; + int l = 0; + int LL = 0; + int m = 0; + int i = 0; + pIntArray LT; + double RMY = 0.0; + complex T1 = {}; + std::vector A; + + A.clear(); + auto Index = [&](int i, int j) -> int + { + int result = 0; + result = ( (j - 1) * l + i ); + return result; + }; + int stop = 0; + l = Norder; + InvertError = 0; + A = Values; /* Assign pointer to something we can use*/ + +/*Allocate LT*/ +// LT:=nil; + LT.resize(l + 1); + if(LT.empty()) + { + InvertError = 1; + return; + } + +/*Zero LT*/ + for(stop = l, j = 1; j <= stop; j++) + { + LT[j] = 0; + } + T1 = cmplx(0.0, 0.0); + k = 1; + +/*M Loop */ + for(stop = l, m = 1; m <= stop; m++) + { + int stop1 = 0; + for(stop1 = l, LL = 1; LL <= stop1; LL++) + { + if(LT[LL] != 1) + { + RMY = cabs(A[Index(LL, LL) - 1]) - cabs(T1); /*Will this work??*/ + if(RMY > 0.0) + { + T1 = A[Index(LL, LL) - 1]; + k = LL; + } /*RMY*/ + } /*IF LT*/ + } /*LL*/ + +/*Error Check. If RMY ends up zero, matrix is non-inversible*/ + RMY = cabs(T1); + if(RMY == 0.0) + { + InvertError = 2; + return; + } + T1 = cmplx(0.0, 0.0); + LT[k] = 1; + for(stop1 = l, i = 1; i <= stop1; i++) + { + if(i != k) + { + int stop2 = 0; + for(stop2 = l, j = 1; j <= stop2; j++) + { + if(j != k) + A[Index(i, j) - 1] = csub(A[Index(i, j) - 1], cdiv(cmul(A[Index(i, k) - 1], A[Index(k, j) - 1]), A[Index(k, k) - 1])); + } + } + } + A[Index(k, k) - 1] = cnegate(cinv(A[Index(k, k) - 1])); /*Invert and negate k,k element*/ + for(stop1 = l, i = 1; i <= stop1; i++) + { + if(i != k) + { + A[Index(i, k) - 1] = cmul(A[Index(i, k) - 1], A[Index(k, k) - 1]); + A[Index(k, i) - 1] = cmul(A[Index(k, i) - 1], A[Index(k, k) - 1]); + } + } /*if*/ + } /*M loop*/ + for(stop = l, j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = l, k = 1; k <= stop1; k++) + { + A[Index(j, k) - 1] = cnegate(A[Index(j, k) - 1]); + } + } + LT.clear(); //# FreeMemory accepts one parameter only; /*Dispose of LT*/ + Values = A; +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::SetElement(int i, int j, const complex& cValue) +{ + complex Value = cValue; + Values[ ( (j - 1) * Norder + i ) - 1 ] = Value; +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::AddElement(int i, int j, const complex& cValue) +{ + complex Value = cValue; + caccum(Values[ ( (j - 1) * Norder + i ) - 1 ], Value); +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::SetElemsym(int i, int j, const complex& cValue) +{ + complex Value = cValue; + Values[((j - 1) * Norder + i) - 1] = Value; + if(i != j) + Values[((i - 1) * Norder + j) - 1] = Value; /*ensure symmetry*/ +} + + /*--------------------------------------------------------------------------*/ + +void TcMatrix::AddElemsym(int i, int j, const complex& cValue) +{ + complex Value = cValue; + caccum(Values[((j - 1) * Norder + i - 1)], Value); + if (i != j) + caccum(Values[((i - 1) * Norder + j - 1)], Value); // Asegurar simetría + +} + +/*--------------------------------------------------------------------------*/ + +complex TcMatrix::GetElement(int i, int j) +{ + complex result = {}; + + // Verify Index Limits + if (i < 1 || i > Norder || j < 1 || j > Norder) + { + // Handle Error, throw exception or return. + return result; + } + + // Calc matrix index element + int index = (j - 1) * Norder + i-1; + + // Access the element in the matrix values + result = Values[index]; + + return result; +} + + + + +/*--------------------------------------------------------------------------*/ + +int TcMatrix::GetErrorCode() +{ + int result = 0; + result = InvertError; + return result; +} + +/*--------------------------------------------------------------------------*/ + /* Sum all elements in a given block of the matrix*/ + +complex TcMatrix::SumBlock(int row1, int row2, int col1, int col2) +{ + complex result = {}; + int i = 0; + int j = 0; + int RowStart = 0; + complex Sum = {}; + int stop = 0; + Sum = cmplx(0.0, 0.0); + for(stop = col2, j = col1; j <= stop; j++) + { + int stop1 = 0; + RowStart = (j - 1) * Norder; + for(stop1 = (RowStart + row2), i = (RowStart + row1); i <= stop1; i++) + { + Sum = cadd(Sum, Values[i - 1]); + } + } + result = Sum; + return result; +} +/*--------------------------------------------------------------------------*/ + +void TcMatrix::CopyFrom(TcMatrix* OtherMatrix) +{ + int i = 0; + int j = 0; + if(Norder == OtherMatrix->Norder) + { + int stop = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + SetElement(i, j, OtherMatrix->GetElement(i, j)); + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::AddFrom(TcMatrix* OtherMatrix) +{ + int i = 0; + int j = 0; + if(Norder == OtherMatrix->Norder) + { + int stop = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + AddElement(i, j, OtherMatrix->GetElement(i, j)); + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +pComplexArray TcMatrix::GetValuesArrayPtr(int& Order) +{ + pComplexArray result = &(Values[0]); + Order = Norder; + return result; +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::ZeroRow(int iRow) +{ + int i = 0; + int j = 0; + complex Zero = {}; + int stop = 0; + Zero = cmplx(0.0, 0.0); + j = iRow; + for(stop = Norder, i = 1; i <= stop; i++) + { + Values[j - 1] = Zero; + j += Norder; + } +} + +/*--------------------------------------------------------------------------*/ + +void TcMatrix::ZeroCol(int iCol) +{ + int i = 0; + complex Zero = {}; + int stop = 0; + Zero = cmplx(0.0, 0.0); + for(stop = (iCol * Norder), i = ((iCol - 1) * Norder + 1); i <= stop; i++) + { + Values[i - 1] = Zero; + } +} + +complex TcMatrix::AvgDiagonal() +{ + complex result = {}; + int i = 0; + int stop = 0; + result = cmplx(0.0, 0.0); + for(stop = Norder, i = 1; i <= stop; i++) + { + caccum(result, Values[((i - 1) * Norder + i) - 1]); + } + if(Norder > 0) + result = cdivreal(result, (double) (Norder)); + return result; +} +// Average the upper triangle off diagonals + +complex TcMatrix::AvgOffDiagonal() +{ + complex result = {}; + int i = 0; + int j = 0; + int Ntimes = 0; + int stop = 0; + result = cmplx(0.0, 0.0); + Ntimes = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + int stop1 = 0; + for(stop1 = Norder, j = i + 1; j <= stop1; j++) + { + ++Ntimes; + caccum(result, Values[((j - 1) * Norder + i) - 1]); + } + } + if(Ntimes > 0) + result = cdivreal(result, (double) (Ntimes)); + return result; +} + +/*Do Kron reduction on present matrix and return a new one*/ +/*Eliminates specified row/column*/ + +TcMatrix* TcMatrix::Kron(int EliminationRow) +{ + TcMatrix* result = nullptr; + int i = 0; + int j = 0; + int n = 0; + int II = 0; + int jj = 0; + complex NNElement = {}; + result = nullptr; // Nil result means it failed + if((Norder > 1) && (EliminationRow <= Norder) && (EliminationRow > 0)) + { + int stop = 0; + result = new TcMatrix(Norder - 1); + n = EliminationRow; + NNElement = GetElement(n, n); + II = 0; + for(stop = Norder, i = 1; i <= stop; i++) + { + if(i != n) // skip elimination row + { + int stop1 = 0; + ++II; + jj = 0; + for(stop1 = Norder, j = 1; j <= stop1; j++) + { + if(j != n) + { + ++jj; + result->SetElement(II, jj, csub(GetElement(i, j), cdiv(cmul(GetElement(i, n), GetElement(n, j)), NNElement))); + } + } + } + } + } + return result; +} +// multiply two scquare matrices of same order +// C (result) = A*B + +TcMatrix* TcMatrix::MtrxMult(TcMatrix* B) +{ + TcMatrix* result = nullptr; + int i = 0; + int j = 0; + pComplexArray cTemp1 = nullptr; + pComplexArray cTemp2 = nullptr; + result = nullptr; // returns Nil pointer if illegal operation + if(B->Norder == Norder) + { + int stop = 0; + result = new TcMatrix(Norder); + cTemp1 = new complex[Norder]; // Temp array to hold column + cTemp2 = new complex[Norder]; // Temp array + for(stop = Norder, j = 1; j <= stop; j++) + { // Column j + int stop1 = 0; + for(stop1 = Norder, i = 1; i <= stop1; i++) + { + cTemp2[i - 1] = B->GetElement(i, j); + } // Row i + MVmult(cTemp1, cTemp2); + for(stop1 = Norder, i = 1; i <= stop1; i++) + { + result->SetElement(i, j, cTemp1[i - 1]); + } + } + delete[] cTemp1; + delete[] cTemp2; + } + return result; +} + +void TcMatrix::MultByConst(double X) +{ + int i = 0; + int stop = 0; + for(stop = Norder * Norder, i = 1; i <= stop; i++) + { + Values[i - 1] = cmulreal(Values[i - 1], X); + } +} + + + + +} // namespace Ucmatrix + + + + diff --git a/OpenDSSC/Shared/Ucmatrix.h b/OpenDSSC/Shared/Ucmatrix.h new file mode 100644 index 0000000..c4f6bc4 --- /dev/null +++ b/OpenDSSC/Shared/Ucmatrix.h @@ -0,0 +1,75 @@ +#ifndef UcmatrixH +#define UcmatrixH + +#include "System.h" +#include "Ucomplex.h" + +namespace Ucmatrix +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +/* + 12-4-99 Added MvMultAccum + 2/4/03 Added Avg routines +*/ + +class TcMatrix : public System::TObject +{ +public: + typedef TObject inherited; +//private: + /* Private declarations */ + int Norder; + std::vector Values; +public: + /* Public declarations */ + int InvertError; + TcMatrix(int n); + virtual ~TcMatrix(); + void Invert(); + void Clear(); /*Zero out matrix*/ + void AddFrom(TcMatrix* OtherMatrix); + void CopyFrom(TcMatrix* OtherMatrix); + void SetElement(int i, int j, const Ucomplex::complex& Value); + void SetElemsym(int i, int j, const Ucomplex::complex& Value); + void AddElement(int i, int j, const Ucomplex::complex& Value); + void AddElemsym(int i, int j, const Ucomplex::complex& Value); + Ucomplex::complex GetElement(int i, int j); + int GetErrorCode(); + Ucomplex::complex SumBlock(int row1, int row2, int col1, int col2); + void MVmult(Ucomplex::pComplexArray B, Ucomplex::pComplexArray X); /*b = Ax*/ + void MVmultAccum(Ucomplex::pComplexArray B, Ucomplex::pComplexArray X); /*b = Ax*/ + Ucomplex::pComplexArray GetValuesArrayPtr(int& Order); + void ZeroRow(int iRow); + void ZeroCol(int iCol); + Ucomplex::complex AvgDiagonal(); // Average of Diagonal Elements + Ucomplex::complex AvgOffDiagonal(); + void MultByConst(double X); // Multiply all elements by a constant + TcMatrix* MtrxMult(TcMatrix* B); // Multiply two square matrices of same order. Result = A*B + TcMatrix* Kron(int EliminationRow); // Perform Kron reduction on last row/col and return new matrix + int get_Norder(); + + TcMatrix(); +}; +/*--------------------------------------------------------------------------*/ + +typedef TcMatrix* pTcMatrix; + +} // namespace Ucmatrix + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Ucmatrix; +#endif + +#endif // UcmatrixH + + + + diff --git a/OpenDSSC/Shared/Ucomplex.cpp b/OpenDSSC/Shared/Ucomplex.cpp new file mode 100644 index 0000000..1875134 --- /dev/null +++ b/OpenDSSC/Shared/Ucomplex.cpp @@ -0,0 +1,353 @@ + + +#pragma hdrstop + +#include "Ucomplex.h" +#include + +using namespace std; + + +namespace Ucomplex +{ + + +complex CZero = cmplx(0,0); +complex cONE = cmplx(1,0); + +/*#inline*/ +complex cmplx(double A, double B) +{ + complex result = {}; + result.re = A; + result.im = B; + return result; +} + +/*#inline*/ +complex cinv(const complex& A) +{ + complex result = {}; + double DNOM = 0.0; + DNOM = A.re * A.re + A.im * A.im; + result.re = A.re / DNOM; + result.im = (-A.im) / DNOM; + return result; +} + +/*#inline*/ +double cabs(const complex& A) +{ + double result = 0.0; + result = sqrt(A.re * A.re + A.im * A.im); + return result; +} + +/*#inline*/ +double cabs2(const complex& A) +{ + double result = 0.0; + result = A.re * A.re + A.im * A.im; + return result; +} + +/*#inline*/ +complex conjg(const complex& A) +{ + complex result = {}; + result.re = A.re; + result.im = -A.im; + return result; +} + +double ATAN2(double X, double IY) +{ + double result = 0.0; + const double Pi = 3.14159265359; /* 180 DEGREES */ + if((X < 0.0) && (IY >= 0)) + result = atan(IY / X) + Pi; + else + { + if((X < 0.0) && (IY < 0)) + result = atan(IY / X) - Pi; + else + { + if(X > 0.0) + result = atan(IY / X); + else + { + if(IY < 0.0) + result = -Pi / 2; + else + { + if(IY > 0.0) + result = Pi / 2; + else + result = 0.0; + } + } + } + } + return result; +} /* ATAN2 */ + +double cang(const complex& A) +{ + double result = 0.0; + result = ATAN2(A.re, A.im); + return result; +} + +double cdang(const complex& A) +{ + double result = 0.0; + result = ATAN2(A.re, A.im) * 57.29577951; + return result; +} + +polar ctopolar(const complex& A) +{ + polar result = {}; + /*# with result do */ + { + auto& with0 = result; + with0.mag = cabs(A); + with0.ang = cang(A); + } + return result; +} + +polar ctopolardeg(const complex& A) +{ + polar result = {}; + /*# with result do */ + { + auto& with0 = result; + with0.mag = cabs(A); + with0.ang = cdang(A); + } + return result; +} + +/*#inline*/ +complex cadd(const complex& A, const complex& B) +{ + complex result = {}; + result.re = A.re + B.re; + result.im = A.im + B.im; + return result; +} + +/*#inline*/ +void caccum(complex& A, const complex& B) +{ + A.re = A.re + B.re; + A.im = A.im + B.im; +} + +void caccumarray(pComplexArray A, pComplexArray B, short int n) +{ + int i = 0; + int stop = 0; + for(stop = n, i = 1; i <= stop; i++) + { + (A)[i - 1].re = (A)[i - 1].re + (B)[i - 1].re; + (A)[i - 1].im = (A)[i - 1].im + (B)[i - 1].im; + } +} + +/*#inline*/ +complex csub(const complex& A, const complex& B) +{ + complex result = {}; + result.re = A.re - B.re; + result.im = A.im - B.im; + return result; +} + +/*#inline*/ +complex cmul(const complex& A, const complex& B) +{ + complex result = {}; + result.re = A.re * B.re - A.im * B.im; + result.im = A.re * B.im + A.im * B.re; + return result; +} + +complex cmulreal(const complex& A, double B) +{ + complex result = {}; + result.re = A.re * B; + result.im = A.im * B; + return result; +} /* := a*b */ + +void cmulrealaccum(complex& A, double B) +{ + A.re = A.re * B; + A.im = A.im * B; +} /* a=a*b*/ + +/*#inline*/ +complex cdiv(const complex& A, const complex& B) +{ + complex result = {}; + double DNOM = 0.0; + DNOM = B.re * B.re + B.im * B.im; + result.re = (A.re * B.re + A.im * B.im) / DNOM; + result.im = (A.im * B.re - A.re * B.im) / DNOM; + return result; +} + +/*#inline*/ +complex cdivreal(const complex& A, double B) +{ + complex result = {}; + result.re = A.re / B; + result.im = A.im / B; + return result; +} /* := a /b*/ + +/*#inline*/ +complex cnegate(const complex& A) +{ + complex result = {}; + result.re = -A.re; + result.im = -A.im; + return result; +} + +complex csqrt(const complex& A) +{ + complex result = {}; + polar X = {}; + // algorithm: sqrt of magnitude/ half the angle + X = ctopolar(A); + result = ptocomplex(topolar(sqrt(X.mag), X.ang / 2.0)); + return result; +} + +complex CLn(const complex& A) +{ + complex result = {}; + polar X = {}; + // algorithm: ln of mag + j(angle), radians + X = ctopolar(A); + result = cmplx(log(X.mag), X.ang); + return result; +} + +/*#inline*/ +polar topolar(double A, double B) +{ + polar result = {}; + /*# with result do */ + { + auto& with0 = result; + with0.mag = A; + with0.ang = B; + } + return result; +} + +double prel(const polar& A) +{ + double result = 0.0; + result = A.mag * cos(A.ang); + return result; +} + +double pimg(const polar& A) +{ + double result = 0.0; + result = A.mag * sin(A.ang); + return result; +} + +complex pclx(double magn, double Angle) +{ + complex result = {}; + result.re = magn * cos(Angle); + result.im = magn * sin(Angle); + return result; +} + +complex pdegtocomplex(double magn, double Angle) +{ + complex result = {}; + double ang = 0.0; + ang = Angle / 57.29577951; + /*# with result do */ + { + auto& with0 = result; + with0.re = magn * cos(ang); + with0.im = magn * sin(ang); + } + return result; +} + +complex ptocomplex(const polar& A) +{ + complex result = {}; + /*# with result do */ + { + auto& with0 = result; + with0.re = A.mag * cos(A.ang); + with0.im = A.mag * sin(A.ang); + } + return result; +} + +polar padd(const polar& A, const polar& B) +{ + polar result = {}; + result = ctopolar(cadd(ptocomplex(A), ptocomplex(B))); + return result; +} + +polar psub(const polar& A, const polar& B) +{ + polar result = {}; + result = ctopolar(csub(ptocomplex(A), ptocomplex(B))); + return result; +} + +polar pmul(const polar& A, const polar& B) +{ + polar result = {}; + result.mag = A.mag * B.mag; + result.ang = A.ang + B.ang; + return result; +} + +polar pdiv(const polar& A, const polar& B) +{ + polar result = {}; + result.mag = A.mag / B.mag; + result.ang = A.ang - B.ang; + return result; +} + + +void Ucomplex_initialization() +{ + CZero = cmplx(0.0, 0.0); + cONE = cmplx(1.0, 0.0); +} + + class Ucomplex_unit + { + public: + Ucomplex_unit() + { + //AssertSystemInitialization(); + Ucomplex_initialization(); + } + }; + Ucomplex_unit _Ucomplex_unit; + +} // namespace Ucomplex + + + + diff --git a/OpenDSSC/Shared/Ucomplex.h b/OpenDSSC/Shared/Ucomplex.h new file mode 100644 index 0000000..f4930a3 --- /dev/null +++ b/OpenDSSC/Shared/Ucomplex.h @@ -0,0 +1,81 @@ +#ifndef UcomplexH +#define UcomplexH + +#include "System.h" +#include "Sysutils.h" + + +namespace Ucomplex +{ + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ + +struct complex +{ + double re; + double im; +}; + +typedef complex* pcomplex; +typedef complex* ComplexArray; +typedef ComplexArray pComplexArray; + +struct polar +{ + double mag; + double ang; +}; + + // 4-8-2010 added inlining selected often-used functions +complex cmplx(double A, double B);//#inline +complex cinv(const complex& A);//#inline +double cabs(const complex& A);//#inline +double cabs2(const complex& A);//#inline // best when you don't need sqrt +double cang(const complex& A); +double cdang(const complex& A); // angle of complex number, degrees +polar ctopolar(const complex& A); +polar ctopolardeg(const complex& A); // complex to polar, degrees +complex cadd(const complex& A, const complex& B);//#inline +void caccum(complex& A, const complex& B);//#inline /*a := a + b*/ +complex csub(const complex& A, const complex& B);//#inline +complex cmul(const complex& A, const complex& B);//#inline +void caccumarray(pComplexArray A, pComplexArray B, short int n); +complex cmulreal(const complex& A, double B);//#inline /* := a*b */ +void cmulrealaccum(complex& A, double B);//#inline /* a=a*b*/ +complex cdiv(const complex& A, const complex& B);//#inline +complex cdivreal(const complex& A, double B);//#inline /* := a /b*/ +complex conjg(const complex& A);//#inline +complex cnegate(const complex& A);//#inline +complex csqrt(const complex& A); +complex CLn(const complex& A); +polar topolar(double A, double B);//#inline // scalar to polar +double prel(const polar& A); // real part of polar number |a| cos() +double pimg(const polar& A); // imag part of polar number |a| sin() +complex ptocomplex(const polar& A); +polar padd(const polar& A, const polar& B); +polar psub(const polar& A, const polar& B); +polar pmul(const polar& A, const polar& B); +polar pdiv(const polar& A, const polar& B); +complex pdegtocomplex(double magn, double Angle); +complex pclx(double magn, double Angle); +extern complex CZero; +extern complex cONE; + + +} // namespace Ucomplex + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace Ucomplex; +#endif + +#endif // UcomplexH + + + + diff --git a/OpenDSSC/Shared/mathutil.cpp b/OpenDSSC/Shared/mathutil.cpp new file mode 100644 index 0000000..affedc8 --- /dev/null +++ b/OpenDSSC/Shared/mathutil.cpp @@ -0,0 +1,611 @@ + + +#pragma hdrstop + +#include "mathutil.h" + +#include "DSSGlobals.h" + + +using namespace std; + + +namespace mathutil +{ + + +TcMatrix* As2p = nullptr; +TcMatrix* Ap2s = nullptr; +TcMatrix* ClarkeF = nullptr; +TcMatrix* ClarkeR = nullptr; + +// PI controller + +TPICtrl::TPICtrl() + : kNum(0.0), + kDen(0.0), + Kp(0.0) +{ + //Initializes the constants for a rising function of 5 steps + den.resize(2); + num.resize(2); + kNum = 0.8647; + kDen = 0.1353; + Kp = 0.02; + den[1] = 0; + num[1] = 0; +} + + +TPICtrl::~TPICtrl() +{ + den.resize(0); + num.resize(0); +} + + +double TPICtrl::SolvePI(double SetPoint) +{ + double result = 0.0; + num[0] = num[1]; + num[1] = SetPoint * Kp; + den[0] = den[1]; + den[1] = (num[0] * kNum) + (den[0] * kDen); + result = den[1]; + return result; +} + + + + // Sqrt23:Double; + +void ETKInvert(pDoubleArray A, int Norder, int& Error) +{ + int j = 0; + int k = 0; + int l = 0; + int LL = 0; + int m = 0; + int i = 0; + Arraydef::pIntegerArray LT = nullptr; + double RMY = 0.0; + double T1 = 0.0; + + auto Index = [&](int i, int j) -> int + { + int result = 0; + result = (j - 1) * l + i; + return result; + }; + int stop = 0; + l = Norder; + Error = 0; + +/*Allocate LT*/ + free(LT); + LT = new longInt[l]; + if(LT == nullptr) + { + Error = 1; + return; + } + +/*Zero LT*/ + for(stop = l, j = 1; j <= stop; j++) + { + LT[j - 1] = 0; + } + T1 = 0.0; + +/*M Loop */ + // initialize a safe value of k + k = 1; + for(stop = l, m = 1; m <= stop; m++) + { + int stop1 = 0; + for(stop1 = l, LL = 1; LL <= stop1; LL++) + { + if(LT[LL - 1] != 1) + { + RMY = Abs(A[Index(LL, LL) - 1]) - Abs(T1); + if(RMY > 0.0) + { + T1 = A[Index(LL, LL) - 1]; + k = LL; + } /*RMY*/ + } /*IF LT*/ + } /*LL*/ + +/*Error Check. If RMY ends up zero, matrix is non-inversible*/ + RMY = Abs(T1); + if(RMY == 0.0) + { + Error = 2; + return; + } + T1 = 0.0; + LT[k - 1] = 1; + for(stop1 = l, i = 1; i <= stop1; i++) + { + if(i != k) + { + int stop2 = 0; + for(stop2 = l, j = 1; j <= stop2; j++) + { + if(j != k) + A[Index(i, j) - 1] = A[Index(i, j) - 1] - A[Index(i, k) - 1] * A[Index(k, j) - 1] / A[Index(k, k) - 1]; + } + } + } + A[Index(k, k) - 1] = -1.0 / A[Index(k, k) - 1]; + for(stop1 = l, i = 1; i <= stop1; i++) + { + if(i != k) + { + A[Index(i, k) - 1] = A[Index(i, k) - 1] * A[Index(k, k) - 1]; + A[Index(k, i) - 1] = A[Index(k, i) - 1] * A[Index(k, k) - 1]; + } + } /*if*/ + } /*M loop*/ + for(stop = l, j = 1; j <= stop; j++) + { + int stop1 = 0; + for(stop1 = l, k = 1; k <= stop1; k++) + { + A[Index(j, k) - 1] = -A[Index(j, k) - 1]; + } + } + free(LT); /*Dispose of LT*/ +} + +/* + Matrix= reference to matrix of DOUBLEs + Norder= order of matrix (assumed square) + Error = 0 if no error; + = 1 if not enough heap to alloc temp array + = 2 if matrix can't be inverted + + This routine will invert a non-symmetric matrix. Index is assumed to + follow the FORTRAN standard, not the Pascal standard. That is the data + are ordered by first subscript first, then second subscript. This routine + computes its own indexing, leaving nothing to the whims of a cantankerous compiler. + + It assumes that the matrix is dimensioned to exactly the number of elements + needed. Apologies to Fortran users who are accustomed to over dimensioning + stuff. + +*/ /*Proc Invert*/ + + + +/*-------------------------------------------------------------*/ + +void Phase2SymComp(pComplexArray Vph, pComplexArray V012) +{ + /*# with Ap2s do */ + { + auto& with0 = Ap2s; + with0->MVmult(V012, Vph); + } +} + +/*-------------------------------------------------------------*/ + +void SymComp2Phase(pComplexArray Vph, pComplexArray V012) +{ + /*# with As2p do */ + { + auto& with0 = As2p; + with0->MVmult(Vph, V012); + } +} + +/*-------------------------------------------------------------*/ + +void SetClarkeMatrices() +{ + double Sin2pi3 = 0.0; + Sin2pi3 = sin(2.0 * PI / 3.0); + /*# with ClarkeF do */ + { + auto& with0 = ClarkeF; // Forward Clarke + with0->SetElement(1, 1, cmplx(1.0, 0.0)); + with0->SetElement(1, 2, cmplx(-0.5, 0.0)); + with0->SetElement(1, 3, cmplx(-0.5, 0.0)); + with0->SetElement(2, 2, cmplx(Sin2pi3, 0.0)); + with0->SetElement(2, 3, cmplx(-Sin2pi3, 0.0)); + with0->SetElement(3, 1, cmplx(0.5, 0.0)); + with0->SetElement(3, 2, cmplx(0.5, 0.0)); + with0->SetElement(3, 3, cmplx(0.5, 0.0)); + with0->MultByConst(2.0 / 3.0); // multiply all elements by a const 2/3 + } + /*# with ClarkeR do */ + { + auto& with1 = ClarkeR; // Reverse Clarke + with1->SetElement(1, 1, cmplx(1.0, 0.0)); + with1->SetElement(2, 1, cmplx(-0.5, 0.0)); + with1->SetElement(3, 1, cmplx(-0.5, 0.0)); + with1->SetElement(2, 2, cmplx(Sin2pi3, 0.0)); + with1->SetElement(3, 2, cmplx(-Sin2pi3, 0.0)); + with1->SetElement(1, 3, cmplx(1.0, 0.0)); + with1->SetElement(2, 3, cmplx(1.0, 0.0)); + with1->SetElement(3, 3, cmplx(1.0, 0.0)); + } +} +/*-------------------------------------------------------------*/ + +void Phase2AB0(pComplexArray Vph, pComplexArray VaB0) +{ + /*# with ClarkeF do */ + { + auto& with0 = ClarkeF; + with0->MVmult(VaB0, Vph); + } +} // Forward Clarke + + + +/*-------------------------------------------------------------*/ + +void AB02Phase(pComplexArray Vph, pComplexArray VaB0) +{ + /*# with ClarkeR do */ + { + auto& with0 = ClarkeR; + with0->MVmult(Vph, VaB0); + } +} // Reverse Clarke + +complex TerminalPowerIn(pComplexArray V, pComplexArray i, int NPhases) +{ + complex result = {}; + int j = 0; + int stop = 0; + result = CZero; + for(stop = NPhases, j = 1; j <= stop; j++) + { + caccum(result, cmul(V[j - 1], conjg(i[j - 1]))); + } + return result; +} +// Computes total complex power given terminal voltages and currents + +/*-------------------------------------------------------------*/ + +void CalcKPowers(pComplexArray kWkvar, pComplexArray V, pComplexArray i, int n) +{ + int j = 0; + int stop = 0; + for(stop = n, j = 1; j <= stop; j++) + { + kWkvar[j - 1] = cmulreal(cmul(V[j - 1], conjg(i[j - 1])), 0.001); + } +} + +/*Compute complex power in kW and kvar in each phase*/ + +/*-------------------------------------------------------------*/ + +void SetAMatrix(TcMatrix* Amat) +{ + complex A = {}; + complex AA = {}; + int i = 0; + A = cmplx(-0.5, 0.866025403); + AA = cmplx(-0.5, -0.866025403); + /*# with Amat do */ + { + auto with0 = Amat; + int stop = 0; + for(stop = 3, i = 1; i <= stop; i++) + { + with0->SetElemsym(1, i, cmplx(1.0,0)); + } + with0->SetElement(2, 2, AA); + with0->SetElement(3, 3, AA); + with0->SetElemsym(2, 3, A); + } +} + + +/*-------------------------------------------------------------*/ + +double Gauss(double Mean, double StdDev) +{ + double result = 0.0; + int i = 0; + double A = 0.0; + int stop = 0; + A = 0.0; + for(stop = 12, i = 1; i <= stop; i++) + { + A = A + rand(); + } + result = (A - 6.0) * StdDev + Mean; + return result; +} +/*Returns a normally distributed random variable*/ + +/*-------------------------------------------------------------*/ + +double QuasiLogNormal(double Mean) +{ + double result = 0.0; + result = exp(Gauss(0.0, 1.0)) * Mean; + return result; +} + +/*Generates a quasi-lognormal distribution with approx 50% of values from 0 to Mean and the remainder from Mean to infinity*/ + +//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +long double /*register*/ RCDSUM(void* Data, int Count) +{ + long double result = 0.0L; // now EDX contains Count - 1 + // count * sizeof(Double) = count * 8 +// _asm + { + /* // IN: EAX = ptr to Data, EDX = High(Data) = Count - 1 + // Uses 4 accumulators to minimize read-after-write delays and loop overhead + // 5 clocks per loop, 4 items per loop = 1.2 clocks per item + FLDZ + SUB EDX, 1 // now EDX contains Count - 1 + MOV ECX, EDX + FLD ST(0) + AND EDX, not 3 + FLD ST(0) + AND ECX, 3 + FLD ST(0) + SHL EDX, 3 // count * sizeof(Double) = count * 8 + JMP @Vector.Pointer[ECX*4] +@Vector: + DD @@1 + DD @@2 + DD @@3 + DD @@4 +@@4: fAdd qword Ptr [EAX+EDX+24] // 1 + FXCH ST(3) // 0 +@@3: fAdd qword Ptr [EAX+EDX+16] // 1 + FXCH ST(2) // 0 +@@2: fAdd qword Ptr [EAX+EDX+8] // 1 + FXCH ST(1) // 0 +@@1: fAdd qword Ptr [EAX+EDX] // 1 + FXCH ST(2) // 0 + SUB EDX, 32 + JNS @@4 + FADDP ST(3),ST // ST(3) := ST + ST(3); Pop ST + fAdd // ST(1) := ST + ST(1); Pop ST + fAdd // ST(1) := ST + ST(1); Pop ST + FWAIT + */ + } + return result; +} + +// Sums an array of doubles quickly + +/* With register convention first 3 parameters are passed EAX, EDX, ECX and + remainder on stack*/ + +void RCDMeanAndStdDev(void* pData, int Ndata, double& Mean, double& StdDev) +{ + typedef double DoubleArray[100/*# range 1..100*/]; + typedef DoubleArray* pDoubleArray; + pDoubleArray Data = nullptr; + double s = 0.0; + int i = 0; + int stop = 0; + Data = ((pDoubleArray) pData); // make a double pointer + if(Ndata == 1) + { + Mean = (*Data)[1 - 1]; + StdDev = (*Data)[1 - 1]; + return; + } + + //Mean = RCDSUM(Data, (Ndata)) / Ndata; + Mean = 0.0; + for (stop = Ndata, i = 1; i <= stop; i++) + { + Mean = Mean + (*Data)[i - 1]; + } + Mean = Mean / Ndata; + + s = 0; // sum differences from the mean, for greater accuracy + for(stop = Ndata, i = 1; i <= stop; i++) + { + s = s + pow((Mean - (*Data)[i - 1]), 2); + } + StdDev = sqrt(s / (Ndata - 1)); +} + +void CurveMeanAndStdDev(pDoubleArray pY, pDoubleArray pX, int n, double& Mean, double& StdDev) +{ + double s = 0.0; + double dy1 = 0.0; + double dy2 = 0.0; + int i = 0; + int stop = 0; + if(n == 1) + { + Mean = pY[1 - 1]; + StdDev = pY[1 - 1]; + return; + } + s = 0; + for(stop = n - 1, i = 1; i <= stop; i++) + { + s = s + 0.5 * (pY[i - 1] + pY[i + 1 - 1]) * (pX[i + 1 - 1] - pX[i - 1]); + } + Mean = s / (pX[n - 1] - pX[1 - 1]); + s = 0; // sum differences from the mean, for greater accuracy + for(stop = n - 1, i = 1; i <= stop; i++) + { + dy1 = (pY[i - 1] - Mean); + dy2 = (pY[i + 1 - 1] - Mean); + s = s + 0.5 * (dy1 * dy1 + dy2 * dy2) * (pX[i + 1 - 1] - pX[i - 1]); + } + StdDev = sqrt(s / (pX[n - 1] - pX[1 - 1])); +} + +double GetXR(const complex& A) +{ + double result = 0.0; + if(A.re != 0.0) + { + result = A.im / A.re; + if(Abs(result) > 9999.0) + result = 9999.0; + } + else + result = 9999.0; + return result; +} + +complex ParallelZ(const complex& Z1, const complex& Z2) +{ + complex result = {}; + complex Denom = {}; + /*Parallel two complex impedances*/ + Denom = cadd(Z1, Z2); + if((Abs(Denom.re) > 0.0) || (Abs(Denom.im) > 0.0)) + result = cdiv(cmul(Z1, Z2), Denom); + else + /*Error*/ + result = CZero; + return result; +} + +// z = I0(a) + +complex Bessel_I0(const complex& A) +{ + complex result = {}; + const int MaxTerm = 1000; + const double EpsilonSqr = 1.0e-20; + int i = 0; + double SizeSqr = 0.0; + complex term = {}; + complex zSQR25 = {}; + result = cONE; // term 0 + zSQR25 = cmulreal(cmul(A, A), 0.25); + term = zSQR25; + caccum(result, zSQR25); // term 1 + i = 1; + do + { + term = cmul(zSQR25, term); + ++i; + term = cdivreal(term, Sqr(i)); + caccum(result, term); // sum := sum + term + SizeSqr = Sqr(term.re) + Sqr(term.im); + } + while(!((i > MaxTerm) || (SizeSqr < EpsilonSqr))); + return result; +} /*Bessel_I0*/ + +complex Bessel_I1(const complex& X) +{ + complex result = {}; + const double MaxTerm = 1000.0; + const double EpsilonSqr = 1.0e-20; + double i = 0.0; + complex term = {}; + complex incterm = {}; + complex newterm = {}; + double SizeSqr = 0.0; + term = cdivreal(X, 2.0); + result = term; + incterm = term; + i = 4.0; + do + { + newterm = cdivreal(X, i); + term = cmul(term, cmul(incterm, newterm)); + caccum(result, term); + incterm = newterm; + i = i + 2.0; + SizeSqr = Sqr(term.re) + Sqr(term.im); + } + while(!((i > MaxTerm) || (SizeSqr < EpsilonSqr))); + return result; +} + +double PctNemaUnbalance(pComplexArray Vph) +{ + double result = 0.0; + int i = 0; + double Vavg = 0.0; + double MaxDiff = 0.0; + double Vmag[3/*# range 1..3*/]; + int stop = 0; + for(stop = 3, i = 1; i <= stop; i++) + { + Vmag[i - 1] = cabs(Vph[i - 1]); + } + Vavg = 0.0; + for(stop = 3, i = 1; i <= stop; i++) + { + Vavg = Vavg + Vmag[i - 1]; + } + Vavg = Vavg / 3.0; + MaxDiff = 0.0; + for(stop = 3, i = 1; i <= stop; i++) + { + MaxDiff = max(MaxDiff, Abs((Vmag[i - 1] - Vavg))); + } + if(Vavg != 0.0) // pct difference + result = MaxDiff / Vavg * 100.0; + else + result = 0.0; + return result; +} + +/*Return Nema unbalance */ + +/*#inline*/ +void DblInc(double& X, double Y) +{ + X = X + Y; +} + + +void mathutil_initialization() +{ + rand(); + As2p = new TcMatrix(3); + Ap2s = new TcMatrix(3); + ClarkeF = new TcMatrix(3); + ClarkeR = new TcMatrix(3); + SetAMatrix(As2p); + SetAMatrix(Ap2s); + Ap2s->Invert(); + SetClarkeMatrices(); + // Sqrt23 := Sqrt(2.0/3.0); // for park +} + +void mathutil_finalization() +{ + delete As2p; + delete Ap2s; + delete ClarkeF; + delete ClarkeR; +} + + class mathutil_unit + { + public: + mathutil_unit() + { + //AssertSystemInitialization(); + mathutil_initialization(); + } + ~ mathutil_unit(){mathutil_finalization(); } + }; + mathutil_unit _mathutil_unit; + +} // namespace mathutil + + + + diff --git a/OpenDSSC/Shared/mathutil.h b/OpenDSSC/Shared/mathutil.h new file mode 100644 index 0000000..f7e20fd --- /dev/null +++ b/OpenDSSC/Shared/mathutil.h @@ -0,0 +1,70 @@ +#ifndef mathutilH +#define mathutilH + +#include "System.h" +#include "Sysutils.h" +#include "Arraydef.h" +#include "Ucomplex.h" +#include "Ucmatrix.h" +#include + +namespace mathutil +{ + + + /*Math utilities*/ +/* + ---------------------------------------------------------- + Copyright (c) 2008-2021, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- +*/ +extern Ucmatrix::TcMatrix* As2p; +extern Ucmatrix::TcMatrix* Ap2s; +extern Ucmatrix::TcMatrix* ClarkeF; +extern Ucmatrix::TcMatrix* ClarkeR; /*Symmetrical Component Conversion Matrices*/ +void AB02Phase(Ucomplex::pComplexArray Vph, Ucomplex::pComplexArray VaB0); // Reverse Clarke +Ucomplex::complex Bessel_I0(const Ucomplex::complex& A); +Ucomplex::complex Bessel_I1(const Ucomplex::complex& X); +void CalcKPowers(Ucomplex::pComplexArray kWkvar, Ucomplex::pComplexArray V, Ucomplex::pComplexArray i, int n); +void ETKInvert(Arraydef::pDoubleArray A, int Norder, int& Error); // Real Matrix Inversion +double Gauss(double Mean, double StdDev); +double GetXR(const Ucomplex::complex& A); +Ucomplex::complex ParallelZ(const Ucomplex::complex& Z1, const Ucomplex::complex& Z2); +void Phase2AB0(Ucomplex::pComplexArray Vph, Ucomplex::pComplexArray VaB0); // Forward Clarke +void Phase2SymComp(Ucomplex::pComplexArray Vph, Ucomplex::pComplexArray V012); +double QuasiLogNormal(double Mean); +void RCDMeanAndStdDev(void* pData, int Ndata, double& Mean, double& StdDev); +void CurveMeanAndStdDev(Arraydef::pDoubleArray pY, Arraydef::pDoubleArray pX, int n, double& Mean, double& StdDev); +// function RCDSum( Data:Pointer; Count:Integer): Extended; register; +void SymComp2Phase(Ucomplex::pComplexArray Vph, Ucomplex::pComplexArray V012); +Ucomplex::complex TerminalPowerIn(Ucomplex::pComplexArray V, Ucomplex::pComplexArray i, int NPhases); +double PctNemaUnbalance(Ucomplex::pComplexArray Vph); +void DblInc(double& X, double Y);//#inline // increment a double + +class TPICtrl : public TObject { + typedef TObject inherited; +private: + std::vector< double > den, num; +public: + double kNum, kDen, Kp; + double SolvePI(double SetPoint); + TPICtrl(); + virtual ~TPICtrl(); +}; + + +typedef TPICtrl* PPICtrl; + + +} // namespace mathutil + +#if !defined(DELPHIHEADER_NO_IMPLICIT_NAMESPACE_USE) +using namespace mathutil; +#endif + +#endif // mathutilH + + + + diff --git a/OpenDSSC/Support/DelphiSets.h b/OpenDSSC/Support/DelphiSets.h new file mode 100644 index 0000000..42241ee --- /dev/null +++ b/OpenDSSC/Support/DelphiSets.h @@ -0,0 +1,379 @@ +/* DelphiSets.h ==================================================================================== + + Dan's Substitute Sets ** (c) Copyright 2011, Daniel Flower + A high-performance template class that emulates Delphi's sets. + + Authorized for unlimited use in any Delphi2Cpp project. + + Features: + - Binary compatibility with Delphi's sets. + - All Delphi and most CBuilder operators and features. + - Supports unlimited elements (vs Delphi's limit of 256). + - Highly optimized (supports enhanced CPU instruction sets). + - Configurable element datatype, thus 8/16/32/64bit portability. + + Differences: + - The Delphi 'in' operator is now 'Contains', like CBuilder. + - The size of the set in memory is fixed, unlike Delphi's sets. + See the binary compatibility functions at the end of the template. + - Each set is considered a different type, so macros are provided + to assist with operations between different sets. + + +Example TSet declarations: +In Delphi: TAllChars = Set of Char; + In C++: typedef TSet TAllChars; + +In Delphi: TAlphabet = Set of 'a' .. 'z'; + In C++: typedef TSet TAlphabet; + +In Delphi: TDays = ( Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday ); + TWorkdays = Set of Monday .. Friday; + In C++: enum TDays { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; + typedef TSet TAlphabet; + +==================================================================================================*/ + + +// Configuration Section =========================================================================== + +// Change type of TSetElement as required, however, performance is best when the element size is +// the same as the native register size. Thus, 32bit integers are ideal for 32bit executables. +typedef unsigned int TSetElement; // Must be unsigned! + +// TSETLIMIT defines maximum number of bits to support in a set. Delphi only +// supported 256 bits, but you can use as few or as many as you require. +#define TSETLIMIT (256) // Must be a multiple of TSETBITS. + +// TSETPOWER defines where to split a set index into element and sub-element indexes. +// This must be coordinated with TSetElement's datatype: 8bit = 3, 16bit = 4, 32bit = 5, 64bit = 6. +#define TSETPOWER (5) // Exponent of 2. Example: 2 ^ (5) = 32 for 32bit ints. + +// Don' modify these... +#define TSETBITS (1 << TSETPOWER) // Number of bits per element. +#define TSETPMASK (TSETBITS - 1) // Sub-element bit mask. +#define TSETINTS (TSETLIMIT >> TSETPOWER)// Number of elements in the set. + + +// Shortcuts & Macros ============================================================================== + +// Return a typeless set (for operations between sets of dissimilar types). +#define AsSet(Set) ((Set).RawBits()) + +// Substitute Add/Sub/MulSets where sets are added/subtracted/multiplied together: +// In Delphi: Output := Apples + Oranges; +// In C++: Output = AddSets(Apples, Oranges); +#define AddSets(Set1, Set2) AsSet((Set1) + AsSet(Set2)) +#define SubSets(Set1, Set2) AsSet((Set1) - AsSet(Set2)) +#define MulSets(Set1, Set2) AsSet((Set1) * AsSet(Set2)) + +// Note: Any number of sets can be added together without the AddSet macro like so: +// In Delphi: AtoZ := AtoF + GtoQ + RtoZ; +// In C++: AtoZ := AsSet( AsSet(AtoF) + AsSet(GtoQ) + AsSet(RtoZ) ); + +// Substitute SubsetOf/SupersetOf where appropriate: +// In Delphi: if (Weekends <= Weekdays) or (ThisMonth >= Weekdays) then +// In C++: if (SubsetOf(Weekends, Weekdays) || SupersetOf(ThisMonth, Weekdays)) +#define SubsetOf(SetIs, SetOf) (SetIs <= AsSet(SetOf)) +#define SupersetOf(SetIs, SetOf) (SetIs >= AsSet(SetOf)) + + +// TSet Template Class ============================================================================= + +typedef TSetElement TSetBits[TSETINTS]; + +template class TSet { +private: + TSetBits bits; + +public: + // Constructors and Support Functions ========================================================= + + // Default constructor. + // In Delphi: CharSet : Set of Char; + // In C++: typedef TSet TCharSet; + TSet() { + Clear(); + } + + // Copy constructor (for dissimilar set types). + // In Delphi: LowerCase : Set of 'a' .. 'z'; + // UpperCase : Set of 'A' .. 'Z'; + // LowerCase := UpperCase; + // In C++: TSet LowerCase; + // TSet UpperCase; + // LowerCase = UpperCase.RawBits(); // See the AsSet() macro. + TSet(const TSetBits &RawBits) { + for (int i = 0; i < TSETINTS; bits[i] = RawBits[i], i++); + } + + // Return the raw bits indirectly (for dissimilar set types). + // In Delphi: TMixed = Set of Char; + // TLetters = Set of 'a' .. 'z' + // TNumbers = Set of '0' .. '9'; + // Mixed := Letters + Numbers; + // In C++: typedef TSet TMixed; + // typedef TSet TLetter; + // typedef TSet TLetter; + // Mixed = (Letters + Numbers.RawBits()).RawBits(); // See the AddSets() macro. + const TSetBits& RawBits() const { + return bits; + } + + // Empty this set completely. + // In Delphi: CharSet := []; + // In C++: CharSet.Clear(); + TSet& Clear() { + for (int i = 0; i < TSETINTS; bits[i++] = 0); + return *this; + } + + + // Inclusion and Exclusion Functions ========================================================== + + // Add a single element to the set. + // In Delphi: Include(MySet, 'x'); + // or: MySet := MySet + ['x']; + // In C++: MySet.Include('x'); + inline void Include(const Type Index) { + const TSetElement index = (TSetElement)Index; + //_ASSERTE(index >= 0 && index < TSETLIMIT); // Assertion version of the safeguard below. + if (index >= 0 && index < TSETLIMIT) // Remark this line for better performance. + bits[index >> TSETPOWER] |= (TSetElement)1 << (index & TSETPMASK); + } + + // Add a range of elements to the set. + // In Delphi: Include(MySet, 'x' .. 'z'); + // or: MySet := MySet + ['x' .. 'z']; + // In C++: MySet.Include('x', 'z'); + void Include(const Type xLow, const Type xHigh) { + const TSetElement low = (TSetElement)xLow, high = (TSetElement)xHigh; + //_ASSERTE(low <= high && low >= 0 && high < TSETLIMIT);// Assertion version of the safeguard below. + if (low <= high && low >= 0 && high < TSETLIMIT) // Remark this line for better performance. + for (unsigned int i = 0, o = (unsigned int)low >> TSETPOWER, + b = (unsigned int)low & TSETPMASK; i <= (unsigned int)(high - low); i++) { + bits[o] |= (TSetElement)1 << b; if (++b < TSETBITS) continue; o++; b = 0; } + } + + // Chainable inclusion operator (for unordered inclusions). + // In Delphi: Include(MySet, 'x'); + // or: MySet := MySet + ['z', 'x', 'y']; + // In C++: MySet << 'x'; + // or: MySet << 'z' << 'x' << 'y'; + TSet& operator << (const Type Index) { + Include(Index); + return *this; + } + + + // Remove a single element from a set. + // In Delphi: Exclude(MySet, 'x'); + // or: MySet := MySet - ['x']; + // In C++: MySet.Exclude('x'); + inline void Exclude(const Type Index) { + const TSetElement index = (TSetElement)Index; + //_ASSERTE(index >= 0 && index < TSETLIMIT); // Assertion version of the safeguard below. + if (index >= 0 && index < TSETLIMIT) // Remark this line for better performance. + bits[index >> TSETPOWER] &= ~((TSetElement)1 << (index & TSETPMASK)); + } + + // Remove a range of elements from the set. + // In Delphi: MySet := MySet - ['x' .. 'z']; + // In C++: MySet.Exclude('x', 'z'); + void Exclude(const Type xLow, const Type xHigh) { + const TSetElement low = (TSetElement)xLow, high = (TSetElement)xHigh; + //_ASSERTE(low <= high && low >= 0 && high < TSETLIMIT);// Assertion version of the safeguard below. + if (low <= high && low >= 0 && high < TSETLIMIT) // Remark this line for better performance. + for (unsigned int i = 0, o = (unsigned int)low >> TSETPOWER, + b = (unsigned int)low & TSETPMASK; i <= (unsigned int)(high - low); i++) { + bits[o] &= ~((TSetElement)1 << b); if (++b < TSETBITS) continue; o++; b = 0; } + } + + // Chainable exclusion operator (for unordered exclusions). + // In Delphi: Exclude(MySet, 'x'); + // or: MySet := MySet - ['z', 'x', 'y']; + // In C++: MySet >> 'x'; + // or: MySet >> 'z' >> 'x' >> 'y'; + TSet& operator >> (const Type Index) { + Exclude(Index); + return *this; + } + + + // Set Operators ============================================================================== + + // Note: The = operator is automatically provided for by the classes default copy constructor, + // and the TSet(TSetBits) constructor does the same task for dissimilar set types. + + // Returns true when the set contains no elements, or false otherwise. + bool Empty() const { + TSetElement sum = 0; + for (int i = 0; i < TSETINTS; sum += bits[i++]); + return (sum) ? false : true; + } + + // Returns true when Index is a member of the set, or false otherwise. + // In Delphi: if 'x' in CharSet then + // In C++: if (CharSet.Contains('x')) + inline bool Contains(const Type Index) const { + const TSetElement index = (TSetElement)Index; + //_ASSERTE(index >= 0 && index < TSETLIMIT); // Assertion version of the safeguard below. + if (index < 0 || index >= TSETLIMIT) return false; // Remark this line for better performance. + return ((bits[index >> TSETPOWER] & ((TSetElement)1 << (index & TSETPMASK)))) ? true : false; + } + + // Add another set to this one and return a new set containing their union. + // In Delphi: WeekdaySet := WorkdaySet + WeekendSet; + // In C++: WeekdaySet = AddSets(WorkdaySet, WeekendSet); + // or: CurrentSet = LastSet + NextSet; // Presuming they all use the same template... + TSet operator + (const TSet &AddSet) const { + TSet NewSet = *this; + for (int i = 0; i < TSETINTS; NewSet.bits[i] |= AddSet.bits[i], i++); + return NewSet; + } + + // Add a set to this one, then return this (altered) set. + // In Delphi: WorkdaySet := WorkdaySet + WeekendSet; // No "actual" Delphi usage. + // In C++: WorkdaySet += AsSet(WeekendSet); + // or: CurrentSet += NextSet; // Presuming they all use the same template... + TSet& operator += (const TSet &AddSet) { + for (int i = 0; i < TSETINTS; bits[i] |= AddSet.bits[i], i++); + return *this; + } + + // Return a copy of this set but with SubSet's items removed. + // In Delphi: WeekdaySet := WorkdaySet - WeekendSet; + // In C++: WeekdaySet = SubSets(WorkdaySet, WeekendSet); + TSet operator - (const TSet &SubSet) const { + TSet NewSet = *this; + for (int i = 0; i < TSETINTS; NewSet.bits[i] &= ~SubSet.bits[i], i++); + return NewSet; + } + + // Subtract a set from this one, then return this (altered) set. + // In Delphi: WorkdaySet := WorkdaySet - WeekendSet; // No "actual" Delphi usage. + // In C++: WorkdaySet -= AsSet(WeekendSet); + // or: CurrentSet -= LastSet; // Presuming they all use the same template... + TSet& operator -= (const TSet &SubSet) { + for (int i = 0; i < TSETINTS; bits[i] &= ~SubSet.bits[i], i++); + return *this; + } + + // Return a new "intersection" set containing only the matches between this set and MulSet. + // In Delphi: WeekdaySet := WorkdaySet * WeekendSet; + // In C++: WeekdaySet = MulSets(WorkdaySet, WeekendSet); + TSet operator * (const TSet &MulSet) const { + TSet NewSet = *this; + for (int i = 0; i < TSETINTS; NewSet.bits[i] &= MulSet.bits[i], i++); + return NewSet; + } + + // Intersect this set with MulSet, then return this (altered) set. + // In Delphi: WorkdaySet := WorkdaySet * WeekendSet; // No "actual" Delphi usage. + // In C++: WorkdaySet *= AsSet(WeekendSet); + // or: CurrentSet *= LastSet; // Presuming they all use the same template... + TSet& operator *= (const TSet &MulSet) { + for (int i = 0; i < TSETINTS; bits[i] &= ~MulSet.bits[i], i++); + return *this; + } + + // Return true if this set matches CmpSet exactly, or false if not. + // In Delphi: if AppleSet = OrangeSet then + // In C++: if (AppleSet == OrangeSet) + bool operator == (const TSet &CmpSet) const { + TSetElement sum = 0; + for (int i = 0; i < TSETINTS; sum |= bits[i] ^ CmpSet.bits[i], i++); + return (sum) ? false : true; + } + + // Return true if this set doesn't matche CmpSet exactly, or false if not. + // In Delphi: if AppleSet <> OrangeSet then + // In C++: if (AppleSet != OrangeSet) + bool operator != (const TSet &CmpSet) const { + return !(*this == CmpSet); + } + + // Return true if this set is completely contained within CmpSet, or false if not. + // In Delphi: if AppleSet <= OrangeSet then + // In C++: if (AppleSet <= OrangeSet) + bool operator <= (const TSet &CmpSet) const { + TSetElement sum = 0; + for (int i = 0; i < TSETINTS; sum |= bits[i] & ~CmpSet.bits[i], i++); + return (sum) ? false : true; + } + + // Return true if CmpSet is completely contained within this set, or false if not. + // In Delphi: if AppleSet >= OrangeSet then + // In C++: if (AppleSet >= OrangeSet) + bool operator >= (const TSet &CmpSet) const { + return (CmpSet <= *this); + } + + + // Aliases for manipulating dissimilar templates ============================================== + + TSet operator + (const TSetBits &RawBits) const { + return (*this + *(TSet*)&RawBits); + } + + TSet& operator += (const TSetBits &RawBits) { + return (*this += *(TSet*)&RawBits); + } + + TSet operator - (const TSetBits &RawBits) const { + return (*this - *(TSet*)&RawBits); + } + + TSet& operator -= (const TSetBits &RawBits) { + return (*this -= *(TSet*)&RawBits); + } + + TSet operator * (const TSetBits &RawBits) const { + return (*this * *(TSet*)&RawBits); + } + + TSet& operator *= (const TSetBits &RawBits) { + return (*this *= *(TSet*)&RawBits); + } + + bool operator == (const TSetBits &RawBits) const { + return (*this == *(TSet*)&RawBits); + } + + bool operator != (const TSetBits &RawBits) const { + return (*this != *(TSet*)&RawBits); + } + + bool operator <= (const TSetBits &RawBits) const { + return (*this <= *(TSet*)&RawBits); + } + + bool operator >= (const TSetBits &RawBits) const { + return (*this >= *(TSet*)&RawBits); + } + + + // Delphi / Binary Compatibility Functions ==================================================== + + // Return the size of this set (in bytes) according to Delphi's binary format. + // Note: If copying the actual set (in its unpacked format), use sizeof() for size calculations. + int DelphiSize() const { + return ((int)(High + 7) >> 3) - ((int)Low >> 3); + } + + // Reads the set from memory according to Delphi's binary format. + // Note: Reads the number of bytes returned by DelphiSize(). + void DelphiRead(void *pPtr) { + Clear(); if (!pPtr) return; + for (int o = (int)Low >> 3, i = 0; o <= (int)High >> 3; + ((char*)&bits)[o++] = ((char*)pPtr)[i++]); + } + + // Write the set to memory according to Delphi's binary format. + // Note: Writes the number of bytes returned by DelphiSize(). + void DelphiWrite(void *pPtr) const { + if (!pPtr) return; + for (int i = (int)Low >> 3, o = 0; i <= (int)High >> 3; + ((char*)pPtr)[o++] = ((char*)&bits)[i++]); + } +}; \ No newline at end of file diff --git a/OpenDSSC/Support/System.h b/OpenDSSC/Support/System.h new file mode 100644 index 0000000..0f06e2e --- /dev/null +++ b/OpenDSSC/Support/System.h @@ -0,0 +1,92 @@ +#ifndef SystemH +#define SystemH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#if defined( WIN32 ) || defined( WIN64 ) +#define windows 1 +#endif + +#include "d2c_system.h" // partially in Delphi2Cpp trial version +#include "d2c_systypes.h" +#include "d2c_sysconst.h" +#include "d2c_syscurr.h" +#include "d2c_sysdate.h" +//#include "d2c_systobj.h" // not in Delphi2Cpp trial version +//#include "d2c_openarray.h" // not in Delphi2Cpp trial version +#include "d2c_sysexcept.h" +#include "d2c_sysmath.h" // partially in Delphi2Cpp trial version +#include "d2c_sysstring.h" // partially in Delphi2Cpp trial version +#include "d2c_sysfile.h" + +using namespace System; + + +#endif // SystemH diff --git a/OpenDSSC/Support/Sysutils.cpp b/OpenDSSC/Support/Sysutils.cpp new file mode 100644 index 0000000..5015d8e --- /dev/null +++ b/OpenDSSC/Support/Sysutils.cpp @@ -0,0 +1,9026 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + + +#include "Sysutils.h" + +#include "d2c_sysconst.h" +#include "d2c_system.h" +#include "d2c_sysmath.h" +#include "d2c_sysexcept.h" +#include "d2c_sysstring.h" +#include +#include +#include +#include "dirsep.h" + +using namespace System; + + +#ifdef linux +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // exit_group +/* Because exit_group() appears to not be declared in linux/unistd.h */ +#include /* For SYS_exit_group definition */ +#endif + +#include +using namespace std; +using namespace System; + + +namespace Sysutils +{ + +#define Sysutils__10 ( TSet < UChar, 0, 255 >() \ + << _T('A') << _T('B') << _T('C') << _T('D') << _T('E') << _T('F') << _T('G') << _T('H') << _T('I') << _T('J') \ + << _T('K') << _T('L') << _T('M') << _T('N') << _T('O') << _T('P') << _T('Q') << _T('R') << _T('S') << _T('T') \ + << _T('U') << _T('V') << _T('W') << _T('X') << _T('Y') << _T('Z') << _T('a') << _T('b') << _T('c') << _T('d') \ + << _T('e') << _T('f') << _T('g') << _T('h') << _T('i') << _T('j') << _T('k') << _T('l') << _T('m') << _T('n') \ + << _T('o') << _T('p') << _T('q') << _T('r') << _T('s') << _T('t') << _T('u') << _T('v') << _T('w') << _T('x') \ + << _T('y') << _T('z') << _T('_') ) +#define Sysutils__11 ( TSet < UChar, 0, 255 >() \ + << _T('A') << _T('B') << _T('C') << _T('D') << _T('E') << _T('F') << _T('G') << _T('H') << _T('I') << _T('J') \ + << _T('K') << _T('L') << _T('M') << _T('N') << _T('O') << _T('P') << _T('Q') << _T('R') << _T('S') << _T('T') \ + << _T('U') << _T('V') << _T('W') << _T('X') << _T('Y') << _T('Z') << _T('a') << _T('b') << _T('c') << _T('d') \ + << _T('e') << _T('f') << _T('g') << _T('h') << _T('i') << _T('j') << _T('k') << _T('l') << _T('m') << _T('n') \ + << _T('o') << _T('p') << _T('q') << _T('r') << _T('s') << _T('t') << _T('u') << _T('v') << _T('w') << _T('x') \ + << _T('y') << _T('z') << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') \ + << _T('8') << _T('9') << _T('_') ) +#define Sysutils__12 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__13 ( TSet < int, 0, 255 >() \ + << int ( 1 ) << int ( 3 ) ) +#define Sysutils__14 ( TSet < UChar, 0, 255 >() \ + << _T('+') << _T('-') ) +#define Sysutils__15 ( TSysCharSet () \ + << _T(' ') << _T('-') << _T('\t') ) +#define Sysutils__16 ( TSet < UChar, 0, 255 >() \ + << _T('+') << _T('-') ) +#define Sysutils__17 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__18 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') \ + << _T('+') << _T('-') << _T('.') << _T('e') << _T('E') ) +#define Sysutils__2 ( TSet < UChar, 0, 255 >() \ + << _T('.') ) +#define Sysutils__3 ( TSet < UChar, 0, 255 >() \ + << Char ( '.' ) ) +#define Sysutils__4 ( TSet < UChar, 0, 255 >() \ + << _T('A') << _T('B') << _T('C') << _T('D') << _T('E') << _T('F') << _T('G') << _T('H') << _T('I') << _T('J') \ + << _T('K') << _T('L') << _T('M') << _T('N') << _T('O') << _T('P') << _T('Q') << _T('R') << _T('S') << _T('T') \ + << _T('U') << _T('V') << _T('W') << _T('X') << _T('Y') << _T('Z') << _T('a') << _T('b') << _T('c') << _T('d') \ + << _T('e') << _T('f') << _T('g') << _T('h') << _T('i') << _T('j') << _T('k') << _T('l') << _T('m') << _T('n') \ + << _T('o') << _T('p') << _T('q') << _T('r') << _T('s') << _T('t') << _T('u') << _T('v') << _T('w') << _T('x') \ + << _T('y') << _T('z') ) +#define Sysutils__5 ( TSet < UChar, 0, 255 >() \ + << _T('a') << _T('b') << _T('c') << _T('d') << _T('e') << _T('f') << _T('g') << _T('h') << _T('i') << _T('j') \ + << _T('k') << _T('l') << _T('m') << _T('n') << _T('o') << _T('p') << _T('q') << _T('r') << _T('s') << _T('t') \ + << _T('u') << _T('v') << _T('w') << _T('x') << _T('y') << _T('z') ) +#define Sysutils__6 ( TSet < UChar, 0, 255 >() \ + << _T('a') << _T('b') << _T('c') << _T('d') << _T('e') << _T('f') << _T('g') << _T('h') << _T('i') << _T('j') \ + << _T('k') << _T('l') << _T('m') << _T('n') << _T('o') << _T('p') << _T('q') << _T('r') << _T('s') << _T('t') \ + << _T('u') << _T('v') << _T('w') << _T('x') << _T('y') << _T('z') ) +#define Sysutils__7 ( TSet < UChar, 0, 255 >() \ + << _T('A') << _T('B') << _T('C') << _T('D') << _T('E') << _T('F') << _T('G') << _T('H') << _T('I') << _T('J') \ + << _T('K') << _T('L') << _T('M') << _T('N') << _T('O') << _T('P') << _T('Q') << _T('R') << _T('S') << _T('T') \ + << _T('U') << _T('V') << _T('W') << _T('X') << _T('Y') << _T('Z') ) +#define Sysutils__8 ( TSet < int, 0, 255 >() \ + << int ( 97 ) << int ( 98 ) << int ( 99 ) << int ( 100 ) << int ( 101 ) << int ( 102 ) << int ( 103 ) << int ( 104 ) << int ( 105 ) << int ( 106 ) \ + << int ( 107 ) << int ( 108 ) << int ( 109 ) << int ( 110 ) << int ( 111 ) << int ( 112 ) << int ( 113 ) << int ( 114 ) << int ( 115 ) << int ( 116 ) \ + << int ( 117 ) << int ( 118 ) << int ( 119 ) << int ( 120 ) << int ( 121 ) << int ( 122 ) ) +#define Sysutils__9 ( TSet < int, 0, 255 >() \ + << int ( 97 ) << int ( 98 ) << int ( 99 ) << int ( 100 ) << int ( 101 ) << int ( 102 ) << int ( 103 ) << int ( 104 ) << int ( 105 ) << int ( 106 ) \ + << int ( 107 ) << int ( 108 ) << int ( 109 ) << int ( 110 ) << int ( 111 ) << int ( 112 ) << int ( 113 ) << int ( 114 ) << int ( 115 ) << int ( 116 ) \ + << int ( 117 ) << int ( 118 ) << int ( 119 ) << int ( 120 ) << int ( 121 ) << int ( 122 ) ) +struct TPRecord; + + + +struct TFormatSettings { + unsigned char CurrencyFormat; + unsigned char NegCurrFormat; + Char ThousandSeparator; + Char DecimalSeparator; + unsigned char CurrencyDecimals; + Char DateSeparator; + Char TimeSeparator; + Char ListSeparator; + String CurrencyString; + String ShortDateFormat; + String LongDateFormat; + String TimeAMString; + String TimePMString; + String ShortTimeFormat; + String LongTimeFormat; + TMonthNameArray ShortMonthNames; + TMonthNameArray LongMonthNames; + TWeekNameArray ShortDayNames; + TWeekNameArray LongDayNames; + WORD TwoDigitYearCenturyWindow; +}; + +TFormatSettings DefaultFormatSettings; + + +void DefaultFormatSettingsInit( ) +{ + DefaultFormatSettings.CurrencyFormat = 1; + DefaultFormatSettings.NegCurrFormat = 5; + DefaultFormatSettings.ThousandSeparator = _T(','); + DefaultFormatSettings.DecimalSeparator = _T('.'); + DefaultFormatSettings.CurrencyDecimals = 2; + DefaultFormatSettings.DateSeparator = _T('-'); + DefaultFormatSettings.TimeSeparator = _T(':'); + DefaultFormatSettings.ListSeparator = _T(','); + DefaultFormatSettings.CurrencyString = _T('$'); + DefaultFormatSettings.ShortDateFormat = _T("d/m/y"); + DefaultFormatSettings.LongDateFormat = _T("dd\" \"mmmm\" \"yyyy"); + DefaultFormatSettings.TimeAMString = _T("AM"); + DefaultFormatSettings.TimePMString = _T("PM"); + DefaultFormatSettings.ShortTimeFormat = _T("hh:mm"); // _T("hh:nn"); + DefaultFormatSettings.LongTimeFormat = _T("hh:mm:ss"); // _T("hh:nn:ss"); + DefaultFormatSettings.ShortMonthNames[0] = _T("Jan"); + DefaultFormatSettings.ShortMonthNames[1] = _T("Feb"); + DefaultFormatSettings.ShortMonthNames[2] = _T("Mar"); + DefaultFormatSettings.ShortMonthNames[3] = _T("Apr"); + DefaultFormatSettings.ShortMonthNames[4] = _T("May"); + DefaultFormatSettings.ShortMonthNames[5] = _T("Jun"); + DefaultFormatSettings.ShortMonthNames[6] = _T("Ju_T("); + DefaultFormatSettings.ShortMonthNames[7] = _T("Aug"); + DefaultFormatSettings.ShortMonthNames[8] = _T("Sep"); + DefaultFormatSettings.ShortMonthNames[9] = _T("Oct"); + DefaultFormatSettings.ShortMonthNames[10] = _T("Nov"); + DefaultFormatSettings.ShortMonthNames[11] = _T("Dec"); + DefaultFormatSettings.LongMonthNames[0] = _T("January"); + DefaultFormatSettings.LongMonthNames[1] = _T("February"); + DefaultFormatSettings.LongMonthNames[2] = _T("March"); + DefaultFormatSettings.LongMonthNames[3] = _T("Apri_T("); + DefaultFormatSettings.LongMonthNames[4] = _T("May"); + DefaultFormatSettings.LongMonthNames[5] = _T("June"); + DefaultFormatSettings.LongMonthNames[6] = _T("July"); + DefaultFormatSettings.LongMonthNames[7] = _T("August"); + DefaultFormatSettings.LongMonthNames[8] = _T("September"); + DefaultFormatSettings.LongMonthNames[9] = _T("October"); + DefaultFormatSettings.LongMonthNames[10] = _T("November"); + DefaultFormatSettings.LongMonthNames[11] = _T("December"); + DefaultFormatSettings.ShortDayNames[0] = _T("Sun"); + DefaultFormatSettings.ShortDayNames[1] = _T("Mon"); + DefaultFormatSettings.ShortDayNames[2] = _T("Tue"); + DefaultFormatSettings.ShortDayNames[3] = _T("Wed"); + DefaultFormatSettings.ShortDayNames[4] = _T("Thu"); + DefaultFormatSettings.ShortDayNames[5] = _T("Fri"); + DefaultFormatSettings.ShortDayNames[6] = _T("Sat"); + DefaultFormatSettings.LongDayNames[0] = _T("Sunday"); + DefaultFormatSettings.LongDayNames[1] = _T("Monday"); + DefaultFormatSettings.LongDayNames[2] = _T("Tuesday"); + DefaultFormatSettings.LongDayNames[3] = _T("Wednesday"); + DefaultFormatSettings.LongDayNames[4] = _T("Thursday"); + DefaultFormatSettings.LongDayNames[5] = _T("Friday"); + DefaultFormatSettings.LongDayNames[6] = _T("Saturday"); + DefaultFormatSettings.TwoDigitYearCenturyWindow = 50; +} + +Char& DecimalSeparator = DefaultFormatSettings.DecimalSeparator; +Char& ThousandSeparator = DefaultFormatSettings.ThousandSeparator; +Char& ListSeparator = DefaultFormatSettings.ListSeparator; +unsigned char& CurrencyDecimals = DefaultFormatSettings.CurrencyDecimals; +unsigned char& CurrencyFormat = DefaultFormatSettings.CurrencyFormat; +unsigned char& NegCurrFormat = DefaultFormatSettings.NegCurrFormat; +String& CurrencyString = DefaultFormatSettings.CurrencyString; + +Char& DateSeparator = DefaultFormatSettings.DateSeparator; +String& ShortDateFormat = DefaultFormatSettings.ShortDateFormat; +String& LongDateFormat =DefaultFormatSettings.LongDateFormat; +TMonthNameArray& ShortMonthNames = DefaultFormatSettings.ShortMonthNames; +TMonthNameArray& LongMonthNames = DefaultFormatSettings.LongMonthNames; +TWeekNameArray& ShortDayNames = DefaultFormatSettings.ShortDayNames; +TWeekNameArray& LongDayNames = DefaultFormatSettings.LongDayNames; +String& ShortTimeFormat = DefaultFormatSettings.ShortTimeFormat; +String& LongTimeFormat = DefaultFormatSettings.LongTimeFormat; +Char& TimeSeparator = DefaultFormatSettings.TimeSeparator; +String& TimeAMString = DefaultFormatSettings.TimeAMString; +String& TimePMString = DefaultFormatSettings.TimePMString; +WORD& TwoDigitYearCenturyWindow = DefaultFormatSettings.TwoDigitYearCenturyWindow; + + /* Date time formatting characters: + C : ShortDateFormat + ' ' + LongTimeFormat + D : Day of Month + dd : Day of Month (leading zero) + ddd : Day of week (abbreviation) + dddd : Day of week (full) + ddddd : ShortDateFormat + dddddd : LongDateFormat + m : Month + mm : Month (leading zero) + mmm : Month (abbreviation) + mmmm : Month (full) + Y : Year (two Digits) + yy : Year (two Digits) + yyyy : Year (four Digits, with Century) + h : Hour + hh : Hour (leading zero) + n : minute + nn : minute (leading zero) + S : second + SS : second (leading zero) + T : ShortTimeFormat + TT : LongTimeFormat + AM/PM : use 12 Hour clock and display AM and PM accordingly + A/P : use 12 Hour clock and display A and P accordingly + / : Insert Date seperator + : : Insert time seperator + "xx" : literal Text + 'xx' : literal Text + */ + + +TSysLocale SysLocale; +String ConfigExtension = _T(".cfg"); +String SysConfigDir = _T(""); +TGetVendorNameEvent OnGetVendorName; +TGetAppNameEvent OnGetApplicationName; +TGetTempDirEvent OnGetTempDir; +TGetTempFileEvent OnGetTempFile; +TSet < UChar, 0, 255 > LeadBytes = TSet < UChar, 0, 255 >(); +String EmptyStr = _T(""); +PString NullStr = &EmptyStr; +wstring EmptyWideStr = L""; +// NullWideStr : PWideString = @EmptyWideStr; + +std::vector< String > TrueBoolStrs, FalseBoolStrs; + +String HexDisplayPrefix = _T("$"); +// commenting is vp fix. These idents are in A different unit there. +/*System.*/ +THandle feInvalidHandle = ((THandle) - 1 ); //return Value ON FileOpen Error + +int Win32Platform = 0; +DWORD Win32MajorVersion = 0, Win32MinorVersion = 0, Win32BuildNumber = 0; +SmallString<255> Win32CSDVersion; + +//--------------------------------------------------------------------------- +bool Win32Check( bool RES ) +{ + if ( ! RES ) + RaiseLastOSError(); + return RES; +} +//--------------------------------------------------------------------------- +void RaiseLastWin32Error( ) +{ + RaiseLastOSError(); +} +//--------------------------------------------------------------------------- +bool CheckWin32Version( int major ) +{ + return CheckWin32Version( major, 0 ); +} +//--------------------------------------------------------------------------- +bool CheckWin32Version( int major, int minor ) +{ + return ( Win32MajorVersion > ((DWORD) major ) ) || ( ( Win32MajorVersion == ((DWORD) major ) ) && ( Win32MinorVersion >= ((DWORD) minor ) ) ); +} +//--------------------------------------------------------------------------- +string StrPas( const char* str ) +{ + return str; +} +//--------------------------------------------------------------------------- +wstring StrPas( const wchar_t* str ) +{ + return str; +} + + +String ChangeFileExt( const String& Filename, const String& Extension ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators + Sysutils__2; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + if ( ( i == 0 ) || ( Filename[i - 1] != ExtensionSeparator ) ) + i = Filename.length( ) + 1; + return Filename.substr( 1 - 1, i - 1 ) + Extension; +} + + +String ExtractFilePath( const String& Filename ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + if ( i > 0 ) + return Filename.substr( 1 - 1, i ); + else + return _T(""); +} + + +String ExtractFileDir( const String& Filename ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + if ( ( i > 1 ) && ( AllowDirectorySeparators.Contains(Filename[i - 1] ) ) && ! ( EndSep.Contains(Filename[i - 1 - 1] ) ) ) + i--; + if ( i > 0 ) + return Filename.substr( 1 - 1, i ); + else + return _T(""); +} + + +String ExtractFileDrive( const String& Filename ) +{ + int i = 0, l = 0; + l = Filename.length( ); + if ( l < 2 ) + return String(); + if ( AllowDriveSeparators.Contains(Filename[2 - 1] ) ) + return Filename.substr( 1 - 1, 2 ); + else + if ( ( AllowDirectorySeparators.Contains(Filename[1 - 1] ) ) && ( AllowDirectorySeparators.Contains(Filename[2 - 1] ) ) ) + { + i = 2; + while ( ( i < l ) && ! ( AllowDirectorySeparators.Contains(Filename[i + 1 - 1] ) ) ) + i++; + if ( i > 0 ) + return Filename.substr( 1 - 1, i ); + else + return _T(""); + } + return String(); +} + + +string ExtractFileName( const string& Filename ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + return Filename.substr( i + 1 - 1, MAXINT ); +} + +wstring ExtractFileName( const wstring& Filename ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + return Filename.substr( i + 1 - 1, MAXINT ); +} + + +String ExtractFileExt( const String& Filename ) +{ + int i = 0; + TSet < UChar, 0, 255 > EndSep; + i = Filename.length( ); + EndSep = AllowDirectorySeparators + AllowDriveSeparators + Sysutils__3; + while ( ( i > 0 ) && ! ( EndSep.Contains(Filename[i - 1] ) ) ) + i--; + if ( ( i > 0 ) && ( Filename[i - 1] == ExtensionSeparator ) ) + return Filename.substr( i - 1, MAXINT ); + else + return String(); +} + +#ifdef windows +String ExtractShortPathName( const String& Filename ) +{ + String result; + result.resize( MAX_PATH ); + result.resize( GetShortPathName( Filename.c_str(), (Char*) result.c_str(), result.length( ) ) ); + return result; +} + +typedef String PathStr; + +#elif defined(linux) +typedef SmallString<255> ComStr; +//typedef SmallString<255> PathStr; +//typedef SmallString<255> dirstr; +//typedef SmallString<255> NameStr; +//typedef SmallString<255> extstr; + +typedef String PathStr; +typedef String dirstr; +typedef String NameStr; +typedef String extstr; + + +#else +#error unknown platform + +#endif + + + + +/* + this File is part of the Free pascal Run time Library. + Copyright (C) 1997-2000 by the Free pascal development team + + see the File copying.FPC, included in this distribution, + for details about the Copyright. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. + + ***********************************************************************/ + +/***************************************************************************** + A platform Independent FExpand implementation +*****************************************************************************/ + + +void GetDirIO( unsignedchar drivenr, String& Dir ) + +/* GetDirIO is supposed to return the root of the given Drive */ +/* in case of an Error for compatibility of FExpand with tp/BP. */ +{ + WORD OldInOutRes = 0; + OldInOutRes = InOutRes; + InOutRes = 0; + GetDir( drivenr, Dir ); + InOutRes = OldInOutRes; +} + + +PathStr FExpand( const PathStr Path ) + +/* LFNSupport Boolean Constant, variable or function must be declared for all + the platforms, at least locally in the DOS unit implementation part. + in addition, FPC_FEXPAND_UNC, FPC_FEXPAND_DRIVES, FPC_FEXPAND_GETENV_PCHAR, + FPC_FEXPAND_TILDE, FPC_FEXPAND_VOLUMES, FPC_FEXPAND_NO_DEFAULT_PATHS, + FPC_FEXPAND_DRIVESEP_IS_ROOT, FPC_FEXPAND_NO_CURDIR, + FPC_FEXPAND_NO_DOTS_UPDIR, FPC_FEXPAND_DIRSEP_IS_UPDIR, + FPC_FEXPAND_DIRSEP_IS_CURDIR and FPC_FEXPAND_MULTIPLE_UPDIR conditionals + might be defined to specify FExpand behaviour - see end of this File for + individual descriptions. finally, FPC_FEXPAND_SYSUTILS allows to reuse + the same implementation for Sysutils.ExpandFileName. +*/ +{ + PathStr result; +#ifdef windows + unsigned int PathStart = 0; +#elif defined(linux) + unsigned int PathStart = 1; +#else +#error unknown platform +#endif + bool RootNotNeeded = false; + PathStr pa, dirs; + String S; + unsigned int i = 0, j = 0; + +/* First convert the Path to UpperCase if appropriate for current platform. */ + if ( FileNameCaseSensitive ) + pa = Path; + else + pa = UpperCase( Path ); + +/* allow both '/' and '\' as Directory separators */ +/* by converting all to the native one. */ +/*$warnings OFF*/ + for ( i = 1; i <= pa.length( ); i++) + if ( AllowDirectorySeparators.Contains(pa[i - 1] ) ) + pa[i - 1] = DirectorySeparator; +/*$warnings ON*/ + +/* PathStart is amount of characters to strip to get beginning */ +/* of Path without volume/Drive specification. */ +#ifdef windows + PathStart = 3; +#elif defined(linux) + /*replace ~/ with $home/*/ + if ( ( pa.length( ) >= 1 ) && ( pa[1 - 1] == _T('~')) && ( ( pa[2 - 1] == DirectorySeparator ) || ( pa.length( ) == 1 ) ) ) + { + S = GetEnvironmentVariable( _T("HOME")); + if ( ( S.empty()) || ( ( S.length( ) == 1 ) && ( S[1 - 1] == DirectorySeparator ) ) ) + pa.erase( 1 - 1, 1 ); + else + if ( S[S.length( ) - 1] == DirectorySeparator ) + pa = S + pa.substr( 3 - 1, pa.length( ) - 2 ); + else + pa = S + pa.substr( 2 - 1, Pred( pa.length( ) ) ); + } +#else +#error unknown platform +#endif + +/* Expand TILDE to home Directory if appropriate. */ +/* do we have A Drive/volume specification? */ +#ifdef linux +/* do we have A Drive/volume specification? */ + if ( ( pa.length( ) > 1 ) && ( Sysutils__4.Contains(pa[1 - 1] ) ) && ( pa[2 - 1] == DriveSeparator ) ) + { + +/* we need to know current Directory ON given */ +/* volume/Drive _if_ such A thing is defined. */ + +/* if drives are not supported, but A Drive */ +/* was supplied anyway, IGNORE (remove) it. */ + pa.erase( 1 - 1, 2 ); + } + /*Check whether we don'T have an ABSOLUTE Path Already*/ + if ( (( pa.length( ) >= PathStart ) && ( pa[PathStart - 1]) != DirectorySeparator ) || ( pa.length( ) < PathStart ) ) +#else + if ( ( pa.length( ) > 1 ) && ( Sysutils__4.Contains(pa[1 - 1] ) ) && ( pa[2 - 1] == DriveSeparator ) ) + { + +/* we need to know current Directory ON given */ +/* volume/Drive _if_ such A thing is defined. */ + /* always UpperCase driveletter */ + if ( Sysutils__5.Contains(pa[1 - 1] ) ) + pa[1 - 1] = Char( int( pa[1 - 1] ) & ~ ( 0x20 ) ); + GetDirIO( int( pa[1 - 1] ) - int( 'A' ) + 1, S ); + +/* do we have more than Just Drive/volume specification? */ + if ( pa.length( ) == Pred( PathStart ) ) + +/* if not, Just use the current Directory for that Drive/volume. */ + pa = S; + else + +/* if yes, find out whether the following Path is RELATIVE or ABSOLUTE. */ + if ( pa[PathStart - 1] != DirectorySeparator ) + if ( pa[1 - 1] == S[1 - 1] ) + { + /* remove ending slash if it Already exists */ + if ( S[S.length( ) - 1] == DirectorySeparator ) + S.resize( S.length( ) - 1 ); + pa = S + Char(DirectorySeparator) + pa.substr( PathStart - 1, pa.length( ) - PathStart + 1 ); + } + else + pa = String(1, pa[1 - 1]) + Char(DriveSeparator) + Char(DirectorySeparator) + pa.substr( PathStart - 1, pa.length( ) - PathStart + 1 ); + } + else +#endif + { + +/* get current Directory ON selected Drive/volume. */ + GetDirIO( 0, S ); +#ifdef windows +/* do we have an ABSOLUTE Path without Drive or volume? */ + if ( ( pa.length( ) > 0 ) && ( pa[1 - 1] == DirectorySeparator ) ) + { + /*do not touch network Drive Names*/ + if ( ( pa.length( ) > 1 ) && ( pa[2 - 1] == DirectorySeparator ) && LFNSupport ) + { + PathStart = 3; + /*find the start of the String of directories*/ + while ( ( PathStart <= pa.length( ) ) && ( pa[PathStart - 1] != DirectorySeparator ) ) + PathStart++; + if ( PathStart > pa.length( ) ) + /*we have Just A Machine Name...*/ + if ( pa.length( ) == 2 ) + /*...or not even that one*/ + PathStart = 2; + else + pa = pa + String(1, DirectorySeparator); + else + if ( PathStart < pa.length( ) ) + /*we have A Resource Name as well*/ + { + RootNotNeeded = true; + /*let'S continue in searching*/ + do + { + PathStart++; + } + while ( ! ( ( PathStart > pa.length( ) ) || ( pa[PathStart - 1] == DirectorySeparator ) ) ); + } + } + else + pa = String(1, S[1 - 1] ) + String(1, DriveSeparator) + pa; + } + else +#endif + /* we Already have A slash if root is the curent Directory. */ + if ( S.length( ) == PathStart ) + pa = S + pa; + else + + /* we need an ending slash if FExpand was called */ + /* with an empty String for compatibility, except */ + /* for platforms Where this is Invalid. */ + if ( pa.length( ) == 0 ) + pa = S + String(1, DirectorySeparator); + else + pa = S + String(1, DirectorySeparator) + pa; + } + + /*get String of directories to only process RELATIVE references ON this one*/ + dirs = pa.substr( Succ( PathStart ) - 1, pa.length( ) - PathStart ); + /*First remove all references to '\.\'*/ + i = Pos( String(1, DirectorySeparator ) + _T(".")+ String(1, DirectorySeparator ), dirs); + while ( i != 0 ) + { + dirs.erase( i - 1, 2 ); + i = Pos( String(1, DirectorySeparator ) + _T(".")+ String(1, DirectorySeparator ), dirs); + } + + /*Now remove also all references to '\..\' + of course previous dirs..*/ + i = Pos( String(1, DirectorySeparator ) + _T("..")+ String(1, DirectorySeparator), dirs ); + while ( i != 0 ) + { + j = Pred( i ); + while ( ( j > 0 ) && ( dirs[j - 1] != DirectorySeparator ) ) + j--; + dirs.erase( Succ( j ) - 1, i - j + 3 ); + i = Pos( String(1, DirectorySeparator ) + _T("..")+ String(1, DirectorySeparator), dirs ); + } + /*then remove also A reference to '\..' at the end of Line + + the previous Directory, of course,...*/ + i = Pos( String(1, DirectorySeparator ) + _T(".."), dirs); + if ( ( i != 0 ) && ( i == dirs.length( ) - 2 ) ) + { + j = Pred( i ); + while ( ( j > 0 ) && ( dirs[j - 1] != DirectorySeparator ) ) + j--; + if ( j == 0 ) + dirs = _T(""); + else + dirs.erase( Succ( j ) - 1, i - j + 2 ); + } + /*...and also A possible reference to '\.'*/ + if ( dirs.length( ) == 1 ) + { + if ( dirs[1 - 1] == '.' ) + /*A special case*/ + dirs = _T(""); + } + else + if ( ( dirs.length( ) != 0 ) && ( dirs[dirs.length( ) - 1] == '.' ) && ( dirs[Pred( dirs.length( ) ) - 1] == DirectorySeparator ) ) + dirs.erase( dirs.length( ) - 1 - 1, 2 ); + + /*finally remove '.\' at the beginning of the String of directories...*/ + while ( ( dirs.length( ) >= 2 ) && ( dirs[1 - 1] == '.' ) && ( dirs[2 - 1] == DirectorySeparator ) ) + dirs.erase( 1 - 1, 2 ); + /*...and possible (Invalid) references to '..\' as well*/ + while ( ( dirs.length( ) >= 3 ) && ( dirs[1 - 1] == '.' ) && ( dirs[2 - 1] == '.' ) && ( dirs[3 - 1] == DirectorySeparator ) ) + dirs.erase( 1 - 1, 3 ); + + /*two special cases - '.' and '..' alone*/ + if ( ( dirs.length( ) == 1 ) && ( dirs[1 - 1] == '.' ) ) + dirs = _T(""); + if ( ( dirs.length( ) == 2 ) && ( dirs[1 - 1] == '.' ) && ( dirs[2 - 1] == '.' ) ) + dirs = _T(""); + + /*JOIN the parts back to Create the complete Path*/ + if ( dirs.length( ) == 0 ) + { + pa = pa.substr( 1 - 1, PathStart ); + if ( pa[PathStart - 1] != DirectorySeparator ) + pa = pa + String(1, DirectorySeparator); + } + else + pa = pa.substr( 1 - 1, PathStart ) + dirs; + /*remove ending \ if not supplied originally, the original String + wasn'T empty (to stay Compatible) and if not really needed*/ + if +/*A special case with UNC paths*/ + /*reference to current Directory at the end should be removed*/ ( ( pa[pa.length( ) - 1] == DirectorySeparator ) && ( ( pa.length( ) > PathStart ) || ( RootNotNeeded && ( pa.length( ) == PathStart ) ) ) && ( Path.length( ) != 0 ) && ( Path[Path.length( ) - 1] != DirectorySeparator ) ) + pa.erase( pa.length( ) - 1, 1 ); + result = pa; + return result; +} + +/* Description of individual conditional defines supported for FExpand + (Disregard the used Directory separators in Examples, Constant + System.DirectorySeparator is used in the real implemenation, of course): + + FPC_FEXPAND_UNC - UNC ("universal Naming convention") paths are + supported (usually used for networking, used in DOS (with + networking support installed), OS/2, Win32 and at least some + Netware versions as Far as i remember. an example of such A Path + is '\\servername\sharename\some\Path'. + + FPC_FEXPAND_DRIVES - Drive letters are supported (DOS-like + environments - DOS, OS/2, Win32). example is 'C:\test'. + + FPC_FEXPAND_GETENV_PCHAR - an implementation of GetEnv returning + PChar instead of A ShortString is available (Unix) to support + LONG values of environment variables. + + FPC_FEXPAND_TILDE - expansion of '~/' to GetEnv('home') - Unix. + example: '~/some/Path'. + + FPC_FEXPAND_VOLUMES - volumes are supported (Similar to drives, + but the Name can be longer; used under Netware, amiga and + probably MacOS as Far as i understand it correctly). example: + 'VolumeName:some:Path' or 'servername/volume:some\Path' + (Netware). + + FPC_FEXPAND_NO_DEFAULT_PATHS - DOS keeps information about the + current Directory for every Drive. if some platform Supports + drives or volumes, but keeps no track of current directories for + them (i.e. there'S no support for "GetDir(DriveNumber, Dir)" or + "GetDir(volume, Dir)", but only for "GetDir (0, Dir)" (i.e. the + overall current Directory), you should define this. otherwise + constructs like 'C:some\Path' refer A Path RELATIVE to the + current Directory ON the C: Drive. + + FPC_FEXPAND_DRIVESEP_IS_ROOT - this means that DriveSeparator + should be used as beginning of the "real" Path for A particular + Drive or volume instead of the DirectorySeparator. this would be + used in case that there is only one character (DriveSeparator) + delimitting the Drive Letter or volume Name from the remaining + Path _and_ the DriveSeparator marks the root of an ABSOLUTE Path + in that case. example - 'volume:this/is/ABSOLUTE/Path'. + + FPC_FEXPAND_NO_CURDIR - there is no support to refer to current + Directory explicitely (like '.' used under both Unix and DOS-like + environments). + + FPC_FEXPAND_NO_DOTS_UPDIR - '..' cannot be used to refer to the + upper Directory. + + FPC_FEXPAND_DIRSEP_IS_UPDIR - DirectorySeparator at the beginning of + A Path (or doubled DirectorySeparator inside the Path) refer to the + Parent Directory, one more DirectorySeparator to Parent Directory of + Parent Directory and So ON (amiga). Please, Note that you can decide + to support both '..' and DirectorySeparator as references to the Parent + Directory at the same time for compatibility reasons - However this + support makes it impossible to use an otherwise possibly valid Name + of '..'. + + FPC_FEXPAND_DIRSEP_IS_CURDIR - DirectorySeparator at the beginning of + A Path refers to the current Directory (i.e. Path beginning with + DirectorySeparator is always A RELATIVE Path). two DirectorySeparator + characters refer to the Parent Directory, three refer to Parent + Directory of the Parent Directory and So ON (MacOS). + + FPC_FEXPAND_MULTIPLE_UPDIR - Grouping of more characters specifying + upper Directory references Higher Directory levels. example: '...' + (Netware). + + FPC_FEXPAND_SYSUTILS allows to reuse the same implementation for + Sysutils.ExpandFileName by avoiding things specific for unit DOS. +*/ + +void DoDirSeparators( String& Filename ) +{ + unsigned int i = 0; + for ( i = 1; i <= Filename.length( ); i++) + if ( AllowDirectorySeparators.Contains(Filename[i - 1] ) ) + Filename[i - 1] = DirectorySeparator; +} + + +String SetDirSeparators( const String& Filename ) +{ + String result; + result = Filename; + DoDirSeparators( result ); + return result; +} + +String ExpandFileName( const String& Filename ) +{ + String result; + String S; + S = Filename; + DoDirSeparators( S ); + result = FExpand( S ); + return result; +} + + + +const int MaxDirs = 129; + + +String ExtractRelativePath( const String& BaseName, const String& DestName ) +{ + String result; + String Source, Dest; + int sc = 0, DC = 0, i = 0, j = 0; + Char* sd[ 129/*# range 1..MaxDirs*/ ], *dd[ 129/*# range 1..MaxDirs*/ ]; + const Char OneLevelBack[] = _T(".." DIRSEP_STR); // DirectorySeparator + if ( UpperCase( ExtractFileDrive( BaseName ) ) != UpperCase( ExtractFileDrive( DestName ) ) ) + { + result = DestName; + return result; + } + Source = ExcludeTrailingPathDelimiter( ExtractFilePath( BaseName ) ); + Dest = ExcludeTrailingPathDelimiter( ExtractFilePath( DestName ) ); + sc = GetDirs( Source, sd, MAXIDX( sd ) ); + DC = GetDirs( Dest, dd, MAXIDX( dd ) ); + i = 1; + while ( ( i <= DC ) && ( i <= sc ) ) + { + if ( StrIComp( dd[i - 1], sd[i - 1] ) == 0 ) + i++; + else + break; + } + result = _T(""); + for ( j = i; j <= sc; j++) + result = result + OneLevelBack; + for ( j = i; j <= DC; j++) + result = result + dd[j - 1] + String(1, DirectorySeparator); + result = result + ExtractFileName( DestName ); + return result; +} + + + +/* + DirName is split in A #0 separated List of Directory Names, + dirs is an array of pchars, pointing to These Directory Names. + the function returns the number of directories found, or -1 + if none were found. +*/ + + +int GetDirs( String& DirName, Char** dirs, int dirs_maxidx ) +{ + int result = 0; + unsigned int i = 0; + i = 1; + result = - 1; + while ( i <= DirName.length( ) ) + { + if + /* avoid Error in case Last char=PathDelim */ ( ( AllowDirectorySeparators.Contains(DirName[i - 1] ) ) && ( DirName.length( ) > i ) ) + { + DirName[i - 1] = '\x00'; + result++; + dirs[result] = &DirName[i + 1 - 1]; + } + i++; + } + if ( result > - 1 ) + result++; + return result; +} + + +String IncludeTrailingPathDelimiter( const String& Path ) +{ + String result; + int l = 0; + result = Path; + l = result.length( ); + if ( ( l == 0 ) || ! ( AllowDirectorySeparators.Contains(result[l - 1] ) ) ) + result = result + String(1, DirectorySeparator); + return result; +} + + +String IncludeTrailingBackslash( const String& Path ) +{ + String result; + result = IncludeTrailingPathDelimiter( Path ); + return result; +} + + +String ExcludeTrailingBackslash( const String& Path ) +{ + String result; + result = ExcludeTrailingPathDelimiter( Path ); + return result; +} + + +String ExcludeTrailingPathDelimiter( const String& Path ) +{ + String result; + int l = 0; + l = Path.length( ); + if ( ( l > 0 ) && ( AllowDirectorySeparators.Contains(Path[l - 1] ) ) ) + l--; + if ( l > 0 ) + return Path.substr( 1 - 1, l ); + else + return _T(""); +} + + +bool IsPathDelimiter( const String& Path, int Index ) +{ + bool result = false; + result = ( Index > 0 ) && ( (unsigned int) Index <= Path.length( ) ) && ( AllowDirectorySeparators.Contains(Path[Index - 1] ) ); + return result; +} + +String FileSearch( const String& Name, const String& DirList, bool ImplicitCurrentDir ) +{ + String result; + int i = 0; + String Temp; + result = Name; + Temp = SetDirSeparators( DirList ); + // start with checking the File in the current Directory + if ( ImplicitCurrentDir && ( !result.empty()) && FileExists( result ) ) + return result; + while ( true ) + { + if ( Temp.empty()) + break; // no more directories to Search - Fail + i = Pos( PathSeparator, Temp ); + if ( i != 0 ) + { + result = Temp.substr( 1 - 1, i - 1 ); + Temp.erase( 1 - 1, i ); + } + else + { + result = Temp; + Temp = _T(""); + } + if ( !result.empty()) + result = IncludeTrailingPathDelimiter( result ) + Name; + if ( ( !result.empty()) && FileExists( result ) ) + return result; + } + result = _T(""); + return result; +} + + +String ExeSearch( const String& Name, const String& DirList ) +{ + String result; + result = FileSearch( Name, DirList, true ); + return result; +} + +#ifndef linux +bool FileIsReadOnly( const String& Filename ) +{ + bool result = false; + result = ( ( FileGetAttr( Filename ) & faReadOnly ) ) != 0; + return result; +} + + +int FileSetDate( const String& Filename, int Age ) +{ + int result = 0; + THandle FD = 0; + /* at least Windows requires fmOpenWrite here */ + FD = FileOpen( Filename, fmOpenWrite ); + if ( FD != feInvalidHandle ) + { + try + { + result = FileSetDate( FD, Age ); + } + catch(...) + { + FileClose( FD ); + throw; + } + /*# finally begin */ + FileClose( FD ); + /*# finally end */ + } + else + result = (int) FD; + return result; +} +#endif + + +/* NewStr creates A New PString and assigns S to it + if Length(S) = 0 NewStr returns nil */ +PString NewStr( const String& S ) +{ + PString result = NULL; + if ( S.empty()) + result = NULL; + else + { + result = new String; + if ( result != NULL ) + *result = S; + } + return result; +} + + +/* AssignStr assigns S to P^ */ +void AssignStr( PString& P, const String& S ) +{ + *P = S; +} + +/* AppendStr appends S to Dest */ +void AppendStr( String& Dest, const String& S ) +{ + Dest = Dest + S; +} +//--------------------------------------------------------------------------- +string UpperCase( const string& xs ) +{ + string s; +#if defined(linux) or not defined(_MSC_VER) + string::const_iterator t, tEnd; + for( t = xs.begin(); t != xs.end(); ++t) + s.append(1, toupper(*t)); +#else + transform(xs.begin(), xs.end(), back_inserter(s), toupper); +#endif + return s; +} +//--------------------------------------------------------------------------- +wstring UpperCase( const wstring& xs ) +{ + wstring s; + transform(xs.begin(), xs.end(), back_inserter(s), towupper); + return s; +} +//--------------------------------------------------------------------------- +/* LowerCase returns A copy of S Where all UpperCase characters ( from A to Z ) + have been converted to LowerCase */ +string LowerCase( const string& xs ) +{ + string s; +#if defined(linux) or not defined(_MSC_VER) + string::const_iterator t, tEnd; + for( t = xs.begin(); t != xs.end(); ++t) + s.append(1, tolower(*t)); +#else + transform(xs.begin(), xs.end(), back_inserter(s), tolower); +#endif + return s; +} +//--------------------------------------------------------------------------- +wstring LowerCase( const wstring& xs ) +{ + wstring s; + transform(xs.begin(), xs.end(), back_inserter(s), towlower); + return s; +} +//--------------------------------------------------------------------------- + + +/* CompareStr compares S1 and S2, the result is the based ON + substraction of the ASCII values of the characters in S1 and S2 + case result + S1 < S2 < 0 + S1 > S2 > 0 + S1 = S2 = 0 */ + + +int CompareStr( const String& S1, const String& S2 ) +{ + int result = 0; + int Count = 0, count1 = 0, count2 = 0; + result = 0; + count1 = S1.length( ); + count2 = S2.length( ); + if ( count1 > count2 ) + Count = count2; + else + Count = count1; + result = CompareMemRange( ((void*) S1.c_str()), ((void*) S2.c_str()), Count ); + if ( result == 0 ) + result = count1 - count2; + return result; +} + +/* CompareMemRange returns the result of comparison of Length Bytes at p1 and p2 + case result + p1 < p2 < 0 + p1 > p2 > 0 + p1 = p2 = 0 */ + + +int CompareMemRange( void* p1, void* p2, unsignedint Length ) +{ + int result = 0; + unsigned int i = 0; + i = 0; + result = 0; + while ( ( result == 0 ) && ( i < Length ) ) + { + result = ((unsigned char) *( unsigned char*) p1 ) - ((unsigned char) *( unsigned char*) p2 ); + p1 = (Char*) ( p1 ) + 1; // vp Compat. + p2 = (Char*) ( p2 ) + 1; + i = i + 1; + } + return result; +} + + +bool CompareMem( void* xp1, void* xp2, unsignedint Length ) +{ + PByte p1 = (PByte) xp1, p2 = (PByte) xp2; + bool result = false; + unsigned int i = 0; + result = true; + i = 0; + if ( p1 != p2 ) + while ( result && ( i < Length ) ) + { + result = *p1 == *p2 ; + i++; + p1++; + p2++; + } + return result; +} + + +/* CompareText compares S1 and S2, the result is the based ON + substraction of the ASCII values of characters in S1 and S2 + comparison is case-insensitive + case result + S1 < S2 < 0 + S1 > S2 > 0 + S1 = S2 = 0 */ + + +int CompareText( const String& S1, const String& S2 ) +{ + int result = 0; + int i = 0, Count = 0, count1 = 0, count2 = 0; + unsigned char Chr1 = '\0', Chr2 = '\0'; + const Char* p1 = NULL,* p2 = NULL; + count1 = S1.length( ); + count2 = S2.length( ); + if ( count1 > count2 ) + Count = count2; + else + Count = count1; + p1 = &S1[1 - 1]; + p2 = &S2[1 - 1]; + i = 0; + while ( i < Count ) + { + Chr1 = ((unsigned char) *p1 ); + Chr2 = ((unsigned char) *p2 ); + if ( Chr1 != Chr2 ) + { + if ( Sysutils__8.Contains(Chr1 ) ) + Chr1 -= 32; + if ( Sysutils__9.Contains(Chr2 ) ) + Chr2 -= 32; + if ( Chr1 != Chr2 ) + break; + } + p1++; + p2++; + i++; + } + if ( i < Count ) + result = Chr1 - Chr2; + else + result = count1 - count2; + return result; +} + + +bool SameText( const String& S1, const String& S2 ) +{ + return CompareText( S1, S2 ) == 0; +} + +#ifdef linux +/*==============================================================================*/ +/* ANSI String functions */ +/* These functions rely ON the character set loaded by the OS */ +/*==============================================================================*/ + + + +typedef Char TCaseTranslationTable [ 256/*# range 0..255*/ ]; + /* tables with upper and LowerCase Forms of character sets. + must be initialized with the correct Code-Pages */ + + +TCaseTranslationTable UpperCaseTable; +TCaseTranslationTable LowerCaseTable; + + +String GenericAnsiUpperCase( const String& S ) +{ + String result; + int Len = 0, i = 0; + Len = S.length( ); + result.resize( Len ); + for ( i = 1; i <= Len; i++) + result[i - 1] = UpperCaseTable[int( S[i - 1] )]; + return result; +} + + +String GenericAnsiLowerCase( const String& S ) +{ + String result; + int Len = 0, i = 0; + Len = S.length( ); + result.resize( Len ); + for ( i = 1; i <= Len; i++) + result[i - 1] = LowerCaseTable[int( S[i - 1] )]; + return result; +} + + +PtrInt GenericAnsiCompareStr( const String& S1, const String& S2 ) +{ + PtrInt result = 0; + int i = 0, L1 = 0, L2 = 0; + result = 0; + L1 = S1.length( ); + L2 = S2.length( ); + i = 1; + while ( ( result == 0 ) && ( ( i <= L1 ) && ( i <= L2 ) ) ) + { + result = int( S1[i - 1] ) - int( S2[i - 1] ); //!! must be replaced by ANSI characters !! + i++; + } + if ( result == 0 ) + result = L1 - L2; + return result; +} + + +PtrInt GenericAnsiCompareText( const String& S1, const String& S2 ) +{ + PtrInt result = 0; + int i = 0, L1 = 0, L2 = 0; + result = 0; + L1 = S1.length( ); + L2 = S2.length( ); + i = 1; + while ( ( result == 0 ) && ( ( i <= L1 ) && ( i <= L2 ) ) ) + { + result = int( LowerCaseTable[int( S1[i - 1] )] ) - int( LowerCaseTable[int( S2[i - 1] )] ); //!! must be replaced by ANSI characters !! + i++; + } + if ( result == 0 ) + result = L1 - L2; + return result; +} + + +PtrInt GenericAnsiStrComp( const Char* S1, const Char* S2 ) +{ + PtrInt result = 0; + result = 0; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + while ( ( result == 0 ) && ( *S1 != _T('\x00')) && ( *S2 != _T('\x00')) ) + { + result = int( *S1 ) - int( *S2 ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + } + if ( ( result == 0 ) && ( *S1 != *S2 ) ){ // loop ended because Exactly one has #0 + if ( *S1 == _T('\x00')) // shorter String is smaller + result = - 1; + else + result = 1; + } + + return result; +} + + +PtrInt GenericAnsiStrIComp( const Char* S1, const Char* S2 ) +{ + PtrInt result = 0; + result = 0; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + while ( ( result == 0 ) && ( *S1 != _T('\x00')) && ( *S2 != _T('\x00')) ) + { + result = int( LowerCaseTable[int( S1[0] )] ) - int( LowerCaseTable[int( S2[0] )] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + } + if ( ( result == 0 ) && ( S1[0] != S2[0] ) ){ //Length(S1)<>Length(S2) + if ( S1[0] == _T('\x00')) + result = - 1; //S1 shorter than S2 + else + result = 1; //S1 longer than S2 + + } + return result; +} + + +PtrInt GenericAnsiStrLComp( const Char* S1, const Char* S2, PtrUInt MaxLen ) +{ + PtrInt result = 0; + unsigned int i = 0; + result = 0; + if ( MaxLen == 0 ) + return result; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + i = 0; + do + { + result = int( S1[0] ) - int( S2[0] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + i++; + } + while ( ! ( ( result != 0 ) || ( i == MaxLen ) ) ); + return result; +} + + +PtrInt GenericAnsiStrLIComp( const Char* S1, const Char* S2, PtrUInt MaxLen ) +{ + PtrInt result = 0; + unsigned int i = 0; + result = 0; + if ( MaxLen == 0 ) + return result; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + i = 0; + do + { + result = int( LowerCaseTable[int( S1[0] )] ) - int( LowerCaseTable[int( S2[0] )] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + i++; + } + while ( ! ( ( result != 0 ) || ( i == MaxLen ) ) ); + return result; +} + + +Char* GenericAnsiStrLower( Char* str ) +{ + Char* result = NULL; + result = str; + if ( str != NULL ) + { + while ( *str != _T('\x00')) + { + *str = LowerCaseTable[((unsigned char) *str )]; + str = str + 1; + } + } + return result; +} + + +Char* GenericAnsiStrUpper( Char* str ) +{ + Char* result = NULL; + result = str; + if ( str != NULL ) + { + while ( *str != _T('\x00')) + { + *str = UpperCaseTable[((unsigned char) *str )]; + str = str + 1; + } + } + return result; +} + + +bool AnsiSameText( const String& S1, const String& S2 ) +{ + bool result = false; + result = AnsiCompareText( S1, S2 ) == 0; + return result; +} + + +bool AnsiSameStr( const String& S1, const String& S2 ) +{ + bool result = false; + result = AnsiCompareStr( S1, S2 ) == 0; + return result; +} + + +Char* AnsiLastChar( const String& S ) +{ + Char* result = NULL; + //!! no MultiByte yet, So we return the Last one. + result = StrEnd( (Char*) ( ((void*) S.c_str()) ) ); // StrEnd checks for nil + result--; + return result; +} + + +Char* AnsiStrLastChar( Char* str ) +{ + Char* result = NULL; + //!! no MultiByte yet, So we return the Last one. + result = StrEnd( str ); + result--; + return result; +} + +void EnsureAnsiLen( string& S, const int Len ) +{ + if ( Len > S.length( ) ) + { + if ( S.length( ) < 10 * 256 ) + S.resize( S.length( ) + 10 ); + else + S.resize( S.length( ) + ( S.length( ) >> 8 ) ); + } +} + +void EnsureAnsiLen( wstring& S, const int Len ) +{ + if ( Len > S.length( ) ) + { + if ( S.length( ) < 10 * 256 ) + S.resize( S.length( ) + 10 ); + else + S.resize( S.length( ) + ( S.length( ) >> 8 ) ); + } +} + +void ConcatCharToAnsiStr( const char C, string& S, int& Index ) +{ + EnsureAnsiLen( S, Index ); + S[Index - 1] = C; + Index++; +} + +void ConcatCharToAnsiStr( const wchar_t C, wstring& S, int& Index ) +{ + EnsureAnsiLen( S, Index ); + S[Index - 1] = C; + Index++; +} +/* Concatenates an UTF-32 char to A WideString. S *must* be unique when entering. */ + + +void ConcatUTF32ToAnsiStr( const wint_t NC, string& S, int& Index, mbstate_t& mbstate ) +{ + char* P = NULL; + size_t mblen = 0; + /* we know that S is unique -> avoid UniqueString calls*/ + P = &S[Index - 1]; + if ( NC <= 127 ) + ConcatCharToAnsiStr( ((Char) NC ), S, Index ); + else + { + EnsureAnsiLen( S, Index + MB_CUR_MAX ); + mblen = wcrtomb( P, ((wchar_t) NC ), &mbstate ); + if ( mblen != ((size_t) - 1 ) ) + Index += mblen; + else + { + /* Invalid wide char */ + *P = L'?'; + Index++; + } + } +} + + +String LowerAnsiString( const String& S ) +{ + string result; + int i = 0, slen = 0, resindex = 0; + size_t mblen = 0; + mbstate_t ombstate, nmbstate; + wchar_t WC = 0; + FillChar( &ombstate, sizeof( ombstate ), 0 ); + FillChar( &nmbstate, sizeof( nmbstate ), 0 ); + slen = S.length( ); + result.resize( slen + 10 ); + i = 1; + resindex = 1; + while ( i <= slen ) + { + if ( S[i - 1] <= '\x7f' ) + { + WC = ((wchar_t) S[i - 1] ); + mblen = 1; + } + else + mblen = mbrtowc( &WC, (char*) ( &S[i - 1] ), slen - i + 1, &ombstate ); + switch ( mblen ) + { + case ((size_t) - 2 ): + { + /* partial Invalid character, copy literally */ + while ( i <= slen ) + { + ConcatCharToAnsiStr( S[i - 1], result, resindex ); + i++; + } + } + break; + case ((size_t) - 1 ): case 0: + { + /* Invalid or NULL character */ + ConcatCharToAnsiStr( S[i - 1], result, resindex ); + i++; + } + break; + default: + { + /* A valid sequence */ + /* even if mblen = 1, the LowerCase version may have A */ + /* different Length */ + /* we can'T do anything special if wchar_t is 16 bit... */ + ConcatUTF32ToAnsiStr( towlower( ((wint_t) WC ) ), result, resindex, nmbstate ); + i += mblen; + } + } + } + result.resize( resindex - 1 ); +#ifdef _WIDESTRING + return str2wstr(result); +#else + return result; +#endif +} + + +String UpperAnsiString( const String& S ) +{ + string result; + int i = 0, slen = 0, resindex = 0; + size_t mblen = 0; + mbstate_t ombstate, nmbstate; + wchar_t WC = 0; + FillChar( &ombstate, sizeof( ombstate ), 0 ); + FillChar( &nmbstate, sizeof( nmbstate ), 0 ); + slen = S.length( ); + result.resize( slen + 10 ); + i = 1; + resindex = 1; + while ( i <= slen ) + { + if ( S[i - 1] <= '\x7f' ) + { + WC = ((wchar_t) S[i - 1] ); + mblen = 1; + } + else + mblen = mbrtowc( &WC, (char*) ( &S[i - 1] ), slen - i + 1, &ombstate ); + switch ( mblen ) + { + case ((size_t) - 2 ): + { + /* partial Invalid character, copy literally */ + while ( i <= slen ) + { + ConcatCharToAnsiStr( S[i - 1], result, resindex ); + i++; + } + } + break; + case ((size_t) - 1 ): case 0: + { + /* Invalid or NULL character */ + ConcatCharToAnsiStr( S[i - 1], result, resindex ); + i++; + } + break; + default: + { + /* A valid sequence */ + /* even if mblen = 1, the UpperCase version may have A */ + /* different Length */ + /* we can'T do anything special if wchar_t is 16 bit... */ + ConcatUTF32ToAnsiStr( towupper( ((wint_t) WC ) ), result, resindex, nmbstate ); + i += mblen; + } + } + } + result.resize( resindex - 1 ); +#ifdef _WIDESTRING + return str2wstr(result); +#else + return result; +#endif +} + + + +String AnsiUpperCase( const String& S ) +{ + return UpperAnsiString( S ); +} + + +String AnsiLowerCase( const String& S ) +{ + return LowerAnsiString( S ); +} + +wstring LowerWideString( const std::wstring& S ) +{ + std::wstring result; + int i = 0; + result.resize( S.length( ) ); + wchar_t* p = (wchar_t*) result.c_str(); + for ( i = 0; i <= S.length( ) - 1; i++) + p[i] = ((wchar_t) ( towlower( ((wint_t) ( S[i + 1 - 1] ) ) ) ) ); + return result; +} + + +wstring UpperWideString( const std::wstring& S ) +{ + std::wstring result; + int i = 0; + result.resize( S.length( ) ); + wchar_t* p = (wchar_t*) result.c_str(); + for ( i = 0; i <= S.length( ) - 1; i++) + p[i] = ((wchar_t) ( towupper( ((wint_t) ( S[i + 1 - 1] ) ) ) ) ); + return result; +} + + + + + + + +int AnsiCompareStr( const String& S1, const String& S2 ) +{ + return GenericAnsiCompareStr( S1, S2 ); +} + + +int AnsiCompareText( const String& S1, const String& S2 ) +{ + return GenericAnsiCompareText( S1, S2 ); +} + + +int AnsiStrComp( const Char* S1, const Char* S2 ) +{ + return GenericAnsiStrComp( S1, S2 ); +} + + +int AnsiStrIComp( const Char* S1, const Char* S2 ) +{ + return GenericAnsiStrIComp( S1, S2 ); +} + + +int AnsiStrLComp( const Char* S1, const Char* S2, unsignedint MaxLen ) +{ + return GenericAnsiStrLComp( S1, S2, MaxLen ); +} + + +int AnsiStrLIComp( const Char* S1, const Char* S2, unsignedint MaxLen ) +{ + return GenericAnsiStrLIComp( S1, S2, MaxLen ); +} + + +Char* AnsiStrLower( Char* str ) +{ + return GenericAnsiStrLower( str ); +} + + +Char* AnsiStrUpper( Char* str ) +{ + return GenericAnsiStrUpper( str ); +} + + +/*==============================================================================*/ +/* end of ANSI functions */ +/*==============================================================================*/ + + +#else + + +bool AnsiSameText( const String& S1, const String& S2 ) +{ + bool result = false; + result = AnsiCompareText( S1, S2 ) == 0; + return result; +} + + +bool AnsiSameStr( const String& S1, const String& S2 ) +{ + bool result = false; + result = AnsiCompareStr( S1, S2 ) == 0; + return result; +} + + +Char* AnsiLastChar( const String& S ) +{ + Char* result = NULL; + //!! no MultiByte yet, So we return the Last one. + result = StrEnd( (Char*) ( ((void*) S.c_str()) ) ); // StrEnd checks for nil + result--; + return result; +} + + +Char* AnsiStrLastChar( Char* str ) +{ + Char* result = NULL; + //!! no MultiByte yet, So we return the Last one. + result = StrEnd( str ); + result--; + return result; +} + +////////// sysstr.inc + + + + +#define test__0 ( TSet< Char, 0, 255 >() \ + << Char ( _T('a')) << Char ( _T('b')) << Char ( _T('c')) << Char ( _T('d')) << Char ( _T('e')) << Char ( _T('f')) << Char ( _T('g')) << Char ( _T('h')) << Char ( _T('i')) << Char ( _T('j')) \ + << Char ( _T('k')) << Char ( _T('l')) << Char ( _T('m')) << Char ( _T('n')) << Char ( _T('o')) << Char ( _T('p')) << Char ( _T('q')) << Char ( _T('r')) << Char ( _T('s')) << Char ( _T('t')) \ + << Char ( _T('u')) << Char ( _T('v')) << Char ( _T('w')) << Char ( _T('x')) << Char ( _T('y')) << Char ( _T('z')) ) +#define test__1 ( TSet< Char, 0, 255 >() \ + << Char ( _T('A')) << Char ( _T('B')) << Char ( _T('C')) << Char ( _T('D')) << Char ( _T('E')) << Char ( _T('F')) << Char ( _T('G')) << Char ( _T('H')) << Char ( _T('I')) << Char ( _T('J')) \ + << Char ( _T('K')) << Char ( _T('L')) << Char ( _T('M')) << Char ( _T('N')) << Char ( _T('O')) << Char ( _T('P')) << Char ( _T('Q')) << Char ( _T('R')) << Char ( _T('S')) << Char ( _T('T')) \ + << Char ( _T('U')) << Char ( _T('V')) << Char ( _T('W')) << Char ( _T('X')) << Char ( _T('Y')) << Char ( _T('Z')) ) +#define test__2 ( TSet< int, 0, 255 >() \ + << int ( 97 ) << int ( 98 ) << int ( 99 ) << int ( 100 ) << int ( 101 ) << int ( 102 ) << int ( 103 ) << int ( 104 ) << int ( 105 ) << int ( 106 ) \ + << int ( 107 ) << int ( 108 ) << int ( 109 ) << int ( 110 ) << int ( 111 ) << int ( 112 ) << int ( 113 ) << int ( 114 ) << int ( 115 ) << int ( 116 ) \ + << int ( 117 ) << int ( 118 ) << int ( 119 ) << int ( 120 ) << int ( 121 ) << int ( 122 ) ) +#define test__3 ( TSet< int, 0, 255 >() \ + << int ( 97 ) << int ( 98 ) << int ( 99 ) << int ( 100 ) << int ( 101 ) << int ( 102 ) << int ( 103 ) << int ( 104 ) << int ( 105 ) << int ( 106 ) \ + << int ( 107 ) << int ( 108 ) << int ( 109 ) << int ( 110 ) << int ( 111 ) << int ( 112 ) << int ( 113 ) << int ( 114 ) << int ( 115 ) << int ( 116 ) \ + << int ( 117 ) << int ( 118 ) << int ( 119 ) << int ( 120 ) << int ( 121 ) << int ( 122 ) ) + + + + +/*==============================================================================*/ +/* ANSI String functions */ +/* These functions rely ON the character set loaded by the OS */ +/*==============================================================================*/ + + + +typedef Char TCaseTranslationTable [ 256/*# range 0..255*/ ]; + /* tables with upper and LowerCase Forms of character sets. + must be initialized with the correct Code-Pages */ + + +TCaseTranslationTable UpperCaseTable; +TCaseTranslationTable LowerCaseTable; + + +String GenericAnsiUpperCase( const String& S ) +{ + String result; + int Len = 0, i = 0; + Len = S.length( ); + result.resize( Len ); + for ( i = 1; i <= Len; i++) + result[i - 1] = UpperCaseTable[int( S[i - 1] )]; + return result; +} + + +String GenericAnsiLowerCase( const String& S ) +{ + String result; + int Len = 0, i = 0; + Len = S.length( ); + result.resize( Len ); + for ( i = 1; i <= Len; i++) + result[i - 1] = LowerCaseTable[int( S[i - 1] )]; + return result; +} + + +PtrInt GenericAnsiCompareStr( const String& S1, const String& S2 ) +{ + PtrInt result; + SizeInt i, L1, L2; + result = 0; + L1 = S1.length( ); + L2 = S2.length( ); + i = 1; + while ( ( result == 0 ) && ( ( i <= L1 ) && ( i <= L2 ) ) ) + { + result = int( S1[i - 1] ) - int( S2[i - 1] ); //!! must be replaced by ANSI characters !! + i++; + } + if ( result == 0 ) + result = L1 - L2; + return result; +} + + +PtrInt GenericAnsiCompareText( const String& S1, const String& S2 ) +{ + PtrInt result; + SizeInt i, L1, L2; + result = 0; + L1 = S1.length( ); + L2 = S2.length( ); + i = 1; + while ( ( result == 0 ) && ( ( i <= L1 ) && ( i <= L2 ) ) ) + { + result = int( LowerCaseTable[int( S1[i - 1] )] ) - int( LowerCaseTable[int( S2[i - 1] )] ); //!! must be replaced by ANSI characters !! + i++; + } + if ( result == 0 ) + result = L1 - L2; + return result; +} + + +PtrInt GenericAnsiStrComp( const Char* S1, const Char* S2 ) +{ + PtrInt result; + result = 0; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + while ( ( result == 0 ) && ( *S1 != _T('\x00')) && ( *S2 != _T('\x00')) ) + { + result = int( *S1 ) - int( *S2 ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + } + if ( ( result == 0 ) && ( *S1 != *S2 ) ) // loop ended because Exactly one has #0 + if ( *S1 == _T('\x00')) // shorter String is smaller + result = - 1; + else + result = 1; + return result; +} + + +PtrInt GenericAnsiStrIComp( const Char* S1, const Char* S2 ) +{ + PtrInt result; + result = 0; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + while ( ( result == 0 ) && ( *S1 != _T('\x00')) && ( *S2 != _T('\x00')) ) + { + result = int( LowerCaseTable[int( S1[0] )] ) - int( LowerCaseTable[int( S2[0] )] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + } + if ( ( result == 0 ) && ( S1[0] != S2[0] ) ) //Length(S1)<>Length(S2) + if ( S1[0] == _T('\x00')) + result = - 1; //S1 shorter than S2 + else + result = 1; //S1 longer than S2 + return result; +} + + +PtrInt GenericAnsiStrLComp( const Char* S1, const Char* S2, PtrUInt MaxLen ) +{ + PtrInt result; + unsigned int i = 0; + result = 0; + if ( MaxLen == 0 ) + return result; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + i = 0; + do + { + result = int( S1[0] ) - int( S2[0] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + i++; + } + while ( ! ( ( result != 0 ) || ( i == MaxLen ) ) ); + return result; +} + + +PtrInt GenericAnsiStrLIComp( const Char* S1, const Char* S2, PtrUInt MaxLen ) +{ + PtrInt result; + unsigned int i = 0; + result = 0; + if ( MaxLen == 0 ) + return result; + if ( S1 == NULL ) + { + if ( S2 == NULL ) + return result; + result = - 1; + return result; + } + if ( S2 == NULL ) + { + result = 1; + return result; + } + i = 0; + do + { + result = int( LowerCaseTable[int( S1[0] )] ) - int( LowerCaseTable[int( S2[0] )] ); //!! must be replaced by ANSI characters !! + S1++; + S2++; + i++; + } + while ( ! ( ( result != 0 ) || ( i == MaxLen ) ) ); + return result; +} + + +Char* GenericAnsiStrLower( Char* str ) +{ + Char* result = NULL; + result = str; + if ( str != NULL ) + { + while ( *str != _T('\x00')) + { + *str = LowerCaseTable[((unsigned char) *str )]; + str = str + 1; + } + } + return result; +} + + +Char* GenericAnsiStrUpper( Char* str ) +{ + Char* result = NULL; + result = str; + if ( str != NULL ) + { + while ( *str != _T('\x00')) + { + *str = UpperCaseTable[((unsigned char) *str )]; + str = str + 1; + } + } + return result; +} + +/////////// sysstr.inc + + +String AnsiUpperCase( const String& S ) +{ +#ifdef windows + String result; + if ( S.length( ) > 0 ) + { + result = S; + //UniqueString( result ); + CharUpperBuff( (Char*) result.c_str(), result.length( ) ); + } + else + result = _T(""); + return result; +#elif defined(linux) + return GenericAnsiUpperCase( S ); +#else +#error unknown platform +#endif +} + + +String AnsiLowerCase( const String& S ) +{ +#ifdef windows + String result; + if ( S.length( ) > 0 ) + { + result = S; + //UniqueString( result ); + CharLowerBuff( (Char*) result.c_str(), result.length( ) ); + } + else + result = _T(""); + return result; + +#elif defined(linux) + return GenericAnsiLowerCase( S ); +#else +#error unknown platform +#endif +} + + +int AnsiCompareStr( const String& S1, const String& S2 ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, 0, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; +#elif defined(linux) + return GenericAnsiCompareStr( S1, S2 ); +#else +#error unknown platform +#endif +} + + +int AnsiCompareText( const String& S1, const String& S2 ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; +#elif defined(linux) + return GenericAnsiCompareText( S1, S2 ); +#else +#error unknown platform +#endif +} + + +int AnsiStrComp( const Char* S1, const Char* S2 ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, 0, S1, - 1, S2, - 1 ) - 2; +#elif defined(linux) + return GenericAnsiStrComp( S1, S2 ); +#else +#error unknown platform +#endif +} + + +int AnsiStrIComp( const Char* S1, const Char* S2 ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, - 1, S2, - 1 ) - 2; +#elif defined(linux) + return GenericAnsiStrIComp( S1, S2 ); +#else +#error unknown platform +#endif +} + + +int AnsiStrLComp( const Char* S1, const Char* S2, unsignedint MaxLen ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, 0, S1, MaxLen, S2, MaxLen ) - 2; +#elif defined(linux) + return GenericAnsiStrLComp( S1, S2, MaxLen ); +#else +#error unknown platform +#endif +} + + +int AnsiStrLIComp( const Char* S1, const Char* S2, unsignedint MaxLen ) +{ +#ifdef windows + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, MaxLen, S2, MaxLen ) - 2; +#elif defined(linux) + return GenericAnsiStrLIComp( S1, S2, MaxLen ); +#else +#error unknown platform +#endif +} + + +Char* AnsiStrLower( Char* str ) +{ +#ifdef windows + Char* result = NULL; + CharLower( str ); + return str; +#elif defined(linux) + return GenericAnsiStrLower( str ); +#else +#error unknown platform +#endif +} + + +Char* AnsiStrUpper( Char* str ) +{ +#ifdef windows + Char* result = NULL; + CharUpper( str ); + return str; +#elif defined(linux) + return GenericAnsiStrUpper( str ); +#else +#error unknown platform +#endif +} + + +/*==============================================================================*/ +/* end of ANSI functions */ +/*==============================================================================*/ + +#endif + +/* Trim returns A copy of S with blanks characters ON the Left and Right stripped OFF */ + + +const TSet < UChar, 0, 255> WhiteSpace = ( TSet < UChar, 0, 255 >() \ + << Char ( 0 ) << Char ( 1 ) << Char ( 2 ) << Char ( 3 ) << Char ( 4 ) << Char ( 5 ) << Char ( 6 ) << Char ( 7 ) << Char ( 8 ) << Char ( _T('\t')) \ + << Char ( _T('\n')) << Char ( 11 ) << Char ( 12 ) << Char ( _T('\r')) << Char ( 14 ) << Char ( 15 ) << Char ( 16 ) << Char ( 17 ) << Char ( 18 ) << Char ( 19 ) \ + << Char ( 20 ) << Char ( 21 ) << Char ( 22 ) << Char ( 23 ) << Char ( 24 ) << Char ( 25 ) << Char ( 26 ) << Char ( 27 ) << Char ( 28 ) << Char ( 29 ) \ + << Char ( 30 ) << Char ( 31 ) << Char ( _T(' ')) ); + + +String Trim( const String& S ) +{ + String result; + int Ofs = 0, Len = 0; + Len = S.length( ); + while ( ( Len > 0 ) && ( WhiteSpace.Contains(S[Len - 1] ) ) ) + Len--; + Ofs = 1; + while ( ( Ofs <= Len ) && ( WhiteSpace.Contains(S[Ofs - 1] ) ) ) + Ofs++; + return S.substr( Ofs - 1, 1 + Len - Ofs ); +} + +/* TrimLeft returns A copy of S with all blank characters ON the Left stripped OFF */ + + +String TrimLeft( const String& S ) +{ + String result; + int i = 0, l = 0; + l = S.length( ); + i = 1; + while ( ( i <= l ) && ( WhiteSpace.Contains(S[i - 1] ) ) ) + i++; + return S.substr( i - 1, l ); +} + +/* TrimRight returns A copy of S with all blank characters ON the Right stripped OFF */ + + +String TrimRight( const String& S ) +{ + String result; + int l = 0; + l = S.length( ); + while ( ( l > 0 ) && ( WhiteSpace.Contains(S[l - 1] ) ) ) + l--; + return S.substr( 1 - 1, l ); +} + +/* QuotedStr returns S quoted Left and Right and every Single Quote in S + replaced by two quotes */ +String QuotedStr( const String& S ) +{ + return AnsiQuotedStr( S, _T('\'') ); +} + +/* AnsiQuotedStr returns S quoted Left and Right by Quote, + and every Single occurance of Quote replaced by two */ +String AnsiQuotedStr( const String& S, Char Quote ) +{ + String result; + int i = 0, j = 0, Count = 0; + result = _T(""); + result = result + Quote; + Count = S.length( ); + i = 0; + j = 0; + while ( i < Count ) + { + i = i + 1; + if ( S[i - 1] == Quote ) + { + result = result + S.substr( 1 + j - 1, i - j ) + Quote; + j = i; + } + } + if ( i != j ) + result = result + S.substr( 1 + j - 1, i - j ); + return result + Quote; +} + +/* AnsiExtractQuotedStr returns A copy of Src with Quote characters + deleted to the Left and Right and Double occurances + of Quote replaced by A Single Quote */ + + +String AnsiExtractQuotedStr( Char*& Src, Char Quote ) +{ + String result; + Char* P = NULL,* Q = NULL,* r = NULL; + P = Src; + Q = StrEnd( P ); + result = _T(""); + if ( P == Q ) + return result; + if ( *P != Quote ) + return result; + P++; + result.resize( ( Q - P ) + 1 ); + r = &result[1 - 1]; + while ( P != Q ) + { + *r = *P; + r++; + if ( *P == Quote ) + { + P = P + 1; + if ( *P != Quote ) + { + r--; + break; + } + } + P = P + 1; + } + Src = P; + result.resize( ( r - (Char*) ( &result[1 - 1] ) ) ); + return result; +} + + +/* AdjustLineBreaks returns S with all CR characters not followed by LF + replaced with CR/LF */ +// under LINUX all CR characters or CR/LF combinations should be replaced with LF + + + +String AdjustLineBreaks( const String& S ) +{ + String result; + result = AdjustLineBreaks( S, DefaultTextLineBreakStyle ); + return result; +} + + +String AdjustLineBreaks( const String& S, TTextLineBreakStyle Style ) +{ + String result; + Char* Source = NULL,* Dest = NULL; + int DestLen = 0; + int i = 0, j = 0, l = 0; + Source = (Char*) ((void*) S.c_str()); + l = S.length( ); + DestLen = l; + i = 1; + while ( i <= l ) + { + switch ( S[i - 1] ) + { + case _T('\x0a'): + if ( Style == tlbsCRLF ) + DestLen++; + break; + case _T('\x0d'): + if ( Style == tlbsCRLF ) + if ( ( i < l ) && ( S[i + 1 - 1] == '\x0a' ) ) + i++; + else + DestLen++; + else + if ( ( i < l ) && ( S[i + 1 - 1] == _T('\x0a')) ) + DestLen--; + break; + } + i++; + } + if ( DestLen == l ) + result = S; + else + { + result.resize( DestLen ); + FillChar( &result[1 - 1], DestLen, 0 ); + Dest = (Char*) ((void*) result.c_str()); + j = 0; + i = 0; + while ( i < l ) + switch ( Source[i] ) + { + case _T('\x0a'): + { + if ( Style == tlbsCRLF ) + { + Dest[j] = _T('\x0d'); + j++; + } + Dest[j] = _T('\x0a'); + j++; + i++; + } + break; + case _T('\x0d'): + { + if ( Style == tlbsCRLF ) + { + Dest[j] = _T('\x0d'); + j++; + } + Dest[j] = _T('\x0a'); + j++; + i++; + if ( Source[i] == _T('\x0a')) + i++; + } + break; + default: + Dest[j] = Source[i]; + j++; + i++; + } + } + return result; +} + + +/* IsValidIdent returns True if the First character of Ident is in: + 'A' to 'Z', 'a' to 'z' or '_' and the following characters are + ON of: 'A' to 'Z', 'a' to 'z', '0'..'9' or '_' */ + + +bool IsValidIdent( const String& Ident ) +{ + bool result = false; + int i = 0, Len = 0; + result = false; + Len = Ident.length( ); + if ( Len != 0 ) + { + result = Sysutils__10.Contains(Ident[1 - 1] ); + i = 1; + while ( ( result ) && ( i < Len ) ) + { + i = i + 1; + result = result && ( Sysutils__11.Contains(Ident[i - 1] ) ); + } + } + return result; +} + +/* IntToHex returns A String representing the hexadecimal Value of Value */ + + +Char HexDigits [ 17 ] = _T("0123456789ABCDEF"); + + +String IntToHex( int Value, int Digits ) +{ + String result; + int i = 0; + result.resize( Digits ); + for ( i = 0; i <= Digits - 1; i++) + { + result[Digits - i - 1] = HexDigits[Value & 15]; + Value = Value >> 4; + } + while ( Value != 0 ) + { + result = HexDigits[Value & 15] + result; + Value = Value >> 4; + } + return result; +} + + +String IntToHex( int64_t Value, int Digits ) +{ + String result; + int i = 0; + result.resize( Digits ); + for ( i = 0; i <= Digits - 1; i++) + { + result[Digits - i - 1] = HexDigits[Value & 15]; + Value = Value >> 4; + } + while ( Value != 0 ) + { + result = HexDigits[Value & 15] + result; + Value = Value >> 4; + } + return result; +} + + +String IntToHex( QWord Value, int Digits ) +{ + String result; + result = IntToHex( ((int64_t) Value ), Digits ); + return result; +} + + +bool TryStrToInt( const String& S, int& i ) +{ + bool result = false; + int Error = 0; + Val( S, &i, Error ); + result = Error == 0; + return result; +} + +/* StrToInt converts the String S to an Integer Value, + if S does not represent A valid Integer Value EConvertError is raised */ + + +int StrToInt( const String& S ) +{ + int result = 0; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + throw EConvertError( ErrorString(_T(SysConst_SInvalidInteger), S )); + return result; +} + + +int64_t StrToInt64( const String& S ) +{ + int64_t result = 0; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + throw EConvertError( ErrorString(_T(SysConst_SInvalidInteger), S )); + return result; +} + + +bool TryStrToInt64( const String& S, int64_t& i ) +{ + bool result = false; + int Error = 0; + Val( S, &i, Error ); + result = Error == 0; + return result; +} + + +QWord StrToQWord( const String& S ) +{ + QWord result; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + throw EConvertError( ErrorString(_T(SysConst_SInvalidInteger), S )); + return result; +} + + +bool TryStrToQWord( const String& S, QWord& Q ) +{ + bool result = false; + int Error = 0; + Val( S, &Q, Error ); + result = Error == 0; + return result; +} + +/* StrToIntDef converts the String S to an Integer Value, + Default is returned in case S does not represent A valid Integer Value */ + + +int StrToIntDef( const String& S, int deflt ) +{ + int result = 0; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + result = deflt; + return result; +} + +/* StrToInt64Def converts the String S to an Int64 Value, + Default is returned in case S does not represent A valid Int64 Value */ + + +int64_t StrToInt64Def( const String& S, int64_t deflt ) +{ + int64_t result = 0; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + result = deflt; + return result; +} + +/* StrToQWordDef converts the String S to an QWord Value, + Default is returned in case S does not represent A valid QWord Value */ + + +QWord StrToQWordDef( const String& S, QWord deflt ) +{ + QWord result; + int Error = 0; + Val( S, &result, Error ); + if ( Error != 0 ) + result = deflt; + return result; +} + +/* LoadStr returns the String Resource Ident. +String LoadStr( int Ident ) +{ + String result; + result = _T(""); + return result; +} */ + +/* FmtLoadStr returns the String Resource Ident and Formats it accordingly */ + +/* +String FmtLoadStr( int Ident, const ARRAYOFCONST& Args ) +{ + String result; + result = _T(""); + return result; +} +*/ + +const int feInvalidFormat = 1; +const int feMissingArgument = 2; +const int feInvalidArgIndex = 3; + + +void DoFormatError( int ErrCode ) +{ + String S; + //!! must be changed to contain Format String... + S = _T(""); + switch ( ErrCode ) + { + case feInvalidFormat: + throw EConvertError(ErrorString( _T(SysConst_SInvalidFormat), S )); + break; + case feMissingArgument: + throw EConvertError( ErrorString(_T(SysConst_SArgumentMissing), S )); + break; + case feInvalidArgIndex: + throw EConvertError( ErrorString(_T(SysConst_SInvalidArgIndex), S )); + break; + } +} + + +//--------------------------------------------------------------------------- +String hexstr(intptr_t val, size_t cnt) +{ + static Char HexTbl [ 17 ] = _T("0123456789ABCDEF"); + String result; + result.resize(cnt); + int i = 0; + for ( i = cnt; i >= 1; i--) + { + result[i - 1] = HexTbl[val & 0xF]; + val = val >> 4; + } + return result; +} +//--------------------------------------------------------------------------- +String space( unsignedchar B ) +{ + return String(B, _T(' ')); +} +//--------------------------------------------------------------------------- + +const int MaxDigits = 15; + + +String FloatToStrFIntl( void* Value, TFloatFormat Format, int Precision, int Digits, TFloatValue ValueType, const TFormatSettings& FormatSettings ) +{ + String result; + int P = 0; + bool Negative = false, TooSmall = false, TooLarge = false; + Char DS = _T('\0'); + DS = FormatSettings.DecimalSeparator; + switch ( Format ) + { + case ffGeneral: + { + switch ( ValueType ) + { + case fvCurrency: + { + if ( ( Precision == - 1 ) || ( Precision > 19 ) ) + Precision = 19; + TooSmall = false; + } + break; + default: + { + if ( ( Precision == - 1 ) || ( Precision > MaxDigits ) ) + Precision = MaxDigits; + TooSmall = ( Abs( *((long double*) Value) ) < 0.00001 ) && (*((long double*) &Value) != 0.0 ); + } + } + if ( ! TooSmall ) + { + switch ( ValueType ) + { + case fvDouble: + Str( *((long double*) Value), 0, Precision, result ); + break; + case fvSingle: + Str( (float) *((long double*) Value), 0, Precision, result ); + break; + case fvCurrency: + Str( *(Currency*) Value, 0, Precision, result ); + break; + default: + Str( *((long double*) Value), 0, Precision, result ); + } + P = Pos( _T("."), result ); + if ( P != 0 ) + result[P - 1] = DS; + TooLarge = ( P > Precision + 1 ) || ( Pos( _T("E"), result ) != 0 ); + } + if ( TooSmall || TooLarge ) + { + result = FloatToStrFIntl( Value, ffExponent, Precision, Digits, ValueType, FormatSettings ); + // strip unneeded zeroes. + P = Pos( _T("E"), result ) - 1; + if ( P != - 1 ) + { + /* Delete superfluous +? */ + if ( result[P + 2 - 1] == _T('+')) + result.erase( P + 2 - 1, 1 ); + while ( ( P > 1 ) && ( result[P - 1] == _T('0')) ) + { + result.erase( P - 1, 1 ); + P--; + } + if ( ( P > 0 ) && ( result[P - 1] == DS ) ) + { + result.erase( P - 1, 1 ); + P--; + } + } + } + else + if ( P != 0 ) // we have A DecimalSeparator + { + /* it seems that in this unit "Precision" must mean "number of */ + /* significant Digits" rather than "number of Digits After the */ + /* decimal Point" (as it does in the System unit) -> adjust */ + /* (Precision+1 to Count the decimal Point character) */ + if ( result[1 - 1] == _T('-')) + Precision++; + if ( ( result.length( ) > (unsigned int) Precision + 1 ) && ( Precision + 1 > P ) ) + { + P = Precision + 1; + result.resize( P ); + } + P = result.length( ); + while ( ( P > 0 ) && ( result[P - 1] == _T('0')) ) + P--; + if ( ( P > 0 ) && ( result[P - 1] == DS ) ) + P--; + result.resize( P ); + } + } + break; + case ffExponent: + { + if ( ( Precision == - 1 ) || ( Precision > MaxDigits ) ) + Precision = MaxDigits; + switch ( ValueType ) + { + case fvDouble: + Str( *((long double*) Value), Precision + 7, result ); + break; + case fvSingle: + Str( ((float)*((long double*) Value) ), Precision + 6, result ); + break; + case fvCurrency: + Str( (double) *(Currency*) Value, Precision + 8, result ); + break; + default: + Str( *((long double*) Value), Precision + 8, result ); + } + /* Delete leading spaces */ + while ( result[1 - 1] == _T(' ')) + result.erase( 1 - 1, 1 ); + if ( result[1 - 1] == _T('-')) + result[3 - 1] = DS; + else + result[2 - 1] = DS; + P = Pos( _T("E"), result ); + if ( P != 0 ) + { + P += 2; + if ( Digits > 4 ) + Digits = 4; + Digits = result.length( ) - P - Digits + 1; + if ( Digits < 0 ) + result.insert( P - 1, String( _T("0000")).substr( 1, - Digits ) ); + else + while ( ( Digits > 0 ) && ( result[P - 1] == _T('0')) ) + { + result.erase( P - 1, 1 ); + if ( (unsigned int) P > result.length( ) ) + { + result.erase( P - 2 - 1, 2 ); + break; + } + Digits--; + } + } + } + break; + case ffFixed: + { + if ( Digits == - 1 ) + Digits = 2; + else + if ( Digits > 18 ) + Digits = 18; + switch ( ValueType ) + { + case fvDouble: + Str( *((long double*) Value), 0, Digits, result ); + break; + case fvSingle: + Str( (float) *((long double*) Value), 0, Digits, result ); + break; + case fvCurrency: + Str( *(Currency*) Value, 0, Digits, result ); + break; + default: + Str( *((long double*) Value), 0, Digits, result ); + } + if ( result[1 - 1] == _T(' ')) + result.erase( 1 - 1, 1 ); + P = Pos( _T("."), result ); + if ( P != 0 ) + result[P - 1] = DS; + } + break; + case ffNumber: + { + if ( Digits == - 1 ) + Digits = 2; + else + if ( Digits > MaxDigits ) + Digits = MaxDigits; + switch ( ValueType ) + { + case fvDouble: + Str( *((long double*) Value), 0, Digits, result ); + break; + case fvSingle: + Str( (float) *((long double*) Value), 0, Digits, result ); + break; + case fvCurrency: + Str( *(Currency*) Value, 0, Digits, result ); + break; + default: + Str( *((long double*) Value), 0, Digits, result ); + } + if ( result[1 - 1] == _T(' ')) + result.erase( 1 - 1, 1 ); + P = Pos( _T("."), result ); + if ( P != 0 ) + result[P - 1] = DS; + else + P = result.length( ) + 1; + P -= 3; + while ( P > 1 ) + { + if ( FormatSettings.ThousandSeparator && result[P - 1 - 1] != _T('-')) + result.insert( P - 1, String(1, FormatSettings.ThousandSeparator) ); + P -= 3; + } + } + break; + case ffCurrency: + { + if ( Digits == - 1 ) + Digits = FormatSettings.CurrencyDecimals; + else + if ( Digits > 18 ) + Digits = 18; + switch ( ValueType ) + { + case fvDouble: + Str( *((long double*) Value), 0, Digits, result ); + break; + case fvSingle: + Str( (float) *((long double*) Value), 0, Digits, result ); + break; + case fvCurrency: + Str( *(Currency*) Value, 0, Digits, result ); + break; + default: + Str( *((long double*) Value), 0, Digits, result ); + } + Negative = result[1 - 1] == _T('-'); + if ( Negative ) + result.erase( 1 - 1, 1 ); + P = Pos( _T("."), result ); + if ( P != 0 ) + result[P - 1] = DS; + P -= 3; + while ( P > 1 ) + { + if(FormatSettings.ThousandSeparator) + result.insert( P - 1, String(1, FormatSettings.ThousandSeparator )); + P -= 3; + } + if ( ! Negative ) + { + switch ( FormatSettings.CurrencyFormat ) + { + case 0: + result = FormatSettings.CurrencyString + result; + break; + case 1: + result += FormatSettings.CurrencyString; + break; + case 2: + result = FormatSettings.CurrencyString + _T(" ") + result; + break; + case 3: + result += _T(" ")+ FormatSettings.CurrencyString; + break; + } + } + else + { + switch ( NegCurrFormat ) + { + case 0: + result = _T("(")+ FormatSettings.CurrencyString + result + _T(")"); + break; + case 1: + result = _T("-")+ FormatSettings.CurrencyString + result.c_str(); + break; + case 2: + result = FormatSettings.CurrencyString + _T("-")+ result; + break; + case 3: + result = FormatSettings.CurrencyString + result + _T("-"); + break; + case 4: + result = _T("(")+ result + FormatSettings.CurrencyString + _T(")"); + break; + case 5: + result = _T("-")+ result + FormatSettings.CurrencyString.c_str(); + break; + case 6: + result = result + _T("-")+ FormatSettings.CurrencyString; + break; + case 7: + result = result + FormatSettings.CurrencyString + _T("-"); + break; + case 8: + result = _T("-")+ result + _T(" ")+ FormatSettings.CurrencyString.c_str(); + break; + case 9: + result = _T("-")+ FormatSettings.CurrencyString + _T(" ")+ result.c_str(); + break; + case 10: + result = FormatSettings.CurrencyString + _T(" ")+ result + _T("-"); + break; + } + } + } + break; + } + + return result; +} + +String FloatToStrF( Currency Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + return FloatToStrFIntl( &Value, Format, Precision, Digits, fvCurrency, FormatSettings ); +} + + +String FloatToStrF( Currency Value, TFloatFormat Format, int Precision, int Digits ) +{ + return FloatToStrF( Value, Format, Precision, Digits, DefaultFormatSettings ); +} + + +String FloatToStrF( long double Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + long double e = 0.0; + e = Value; + return FloatToStrFIntl( &e, Format, Precision, Digits, fvDouble, FormatSettings ); +} + + +String FloatToStrF( long double Value, TFloatFormat Format, int Precision, int Digits ) +{ + return FloatToStrF( Value, Format, Precision, Digits, DefaultFormatSettings ); +} + +String FloatToStrF( double Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + long double e = 0.0; + e = Value; + return FloatToStrFIntl( &e, Format, Precision, Digits, fvDouble, FormatSettings ); +} + + +String FloatToStrF( double Value, TFloatFormat Format, int Precision, int Digits ) +{ + return FloatToStrF( Value, Format, Precision, Digits, DefaultFormatSettings ); +} + + + +String FloatToStrF( float Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + long double e = 0.0; + e = Value; + return FloatToStrFIntl( &e, Format, Precision, Digits, fvSingle, FormatSettings ); +} + + +String FloatToStrF( float Value, TFloatFormat Format, int Precision, int Digits ) +{ + return FloatToStrF( Value, Format, Precision, Digits, DefaultFormatSettings ); +} + + +String FloatToStrF( int64_t Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + long double e = 0.0; + e = (long double) Value; + return FloatToStrFIntl( &e, Format, Precision, Digits, fvComp, FormatSettings ); +} + + +String FloatToStrF( int64_t Value, TFloatFormat Format, int Precision, int Digits ) +{ + return FloatToStrF( Value, Format, Precision, Digits, DefaultFormatSettings ); +} + + +String CurrToStrF( Currency Value, TFloatFormat Format, int Digits, const TFormatSettings& FormatSettings ) +{ + return FloatToStrF( Value, Format, 19, Digits, FormatSettings ); +} + + +String CurrToStrF( Currency Value, TFloatFormat Format, int Digits ) +{ + return CurrToStrF( Value, Format, Digits, DefaultFormatSettings ); +} + + +TDateTime FloatToDateTime( const long double Value ) +{ + TDateTime result = 0.0; + if ( ( Value < (double) MinDateTime ) || ( Value > (double) MaxDateTime ) ) + { + //throw EConvertError( _T(SysConst_SInvalidDateTime), ARRAYOFCONST( Value) )); + String sError; + Str(Value, sError); + sError += _T(" is not a valid date/time value."); + throw EConvertError( sError); + } + result = (double) Value; + return result; +} + + + + +String FloatToStr( Currency Value, const TFormatSettings& FormatSettings ) +{ + return FloatToStrFIntl( &Value, ffGeneral, 15, 0, fvCurrency, FormatSettings ); +} + + +String FloatToStr( Currency Value ) +{ + return FloatToStr( Value, DefaultFormatSettings ); +} + + +String FloatToStr( double Value, const TFormatSettings& FormatSettings ) +{ + String result; + long double e = 0.0; + e = Value; + result = FloatToStrFIntl( &e, ffGeneral, 15, 0, fvDouble, FormatSettings ); + return result; +} + + +String FloatToStr( double Value ) +{ + return FloatToStr( Value, DefaultFormatSettings ); +} + +String FloatToStr( long double Value ) +{ + return FloatToStr( (double) Value, DefaultFormatSettings ); +} + +String FloatToStr( int Value ) +{ + return FloatToStr( (double) Value, DefaultFormatSettings ); +} + + + +String FloatToStr( float Value, const TFormatSettings& FormatSettings ) +{ + String result; + long double e = 0.0; + e = Value; + result = FloatToStrFIntl( &e, ffGeneral, 15, 0, fvSingle, FormatSettings ); + return result; +} + + +String FloatToStr( float Value ) +{ + return FloatToStr( Value, DefaultFormatSettings ); +} + + +String FloatToStr( int64_t Value, const TFormatSettings& FormatSettings ) +{ + String result; + long double e = 0.0; + e = (long double) Value; + result = FloatToStrFIntl( &e, ffGeneral, 15, 0, fvComp, FormatSettings ); + return result; +} + + +String FloatToStr( int64_t Value ) +{ + return FloatToStr( Value, DefaultFormatSettings ); +} + + + + + +int FloatToText( Char* Buffer, long double Value, TFloatFormat Format, int Precision, int Digits, const TFormatSettings& FormatSettings ) +{ + String tmp = FloatToStrF( (double) Value, Format, Precision, Digits, FormatSettings );; + return tmp.length(); +} + + +int FloatToText( Char* Buffer, long double Value, TFloatFormat Format, int Precision, int Digits ) +{ + int result = 0; + result = FloatToText( Buffer, Value, Format, Precision, Digits, DefaultFormatSettings ); + return result; +} + + +void ReadInteger( int64_t& Value, const String& fmt, const VECTOROFCONST& Args, int& ChPos, int& OldPos, unsigned int& ArgPos, int& Len) +{ + int Code = 0; + if ( Value != - 1 ) + return; // was Already read. + OldPos = ChPos; + while ( ( ChPos <= Len ) && ( Pos( fmt[ChPos - 1], String( _T("1234567890")) ) != 0 ) ) + ChPos++; + if ( ChPos > Len ) + DoFormatError( feInvalidFormat ); + if ( fmt[ChPos - 1] == '*' ) + { + if ( ( ChPos > OldPos ) || ( ArgPos > Args.size() - 1 /*# High(Args) */ ) ) + DoFormatError( feInvalidFormat ); + switch ( Args[ArgPos].VType ) + { + case vtInteger: + Value = Args[ArgPos].VInteger; + break; + case vtInt64: + Value = *Args[ArgPos].VInt64; + break; + case vtUInt64: + Value = *Args[ArgPos].VUInt64; + break; + default: + DoFormatError( feInvalidFormat ); + } + ArgPos++; + ChPos++; + } + else + { + if ( OldPos < ChPos ) + { + Val( fmt.substr( OldPos - 1, ChPos - OldPos ), &Value, Code ); + // this should never happen !! + if ( Code > 0 ) + DoFormatError( feInvalidFormat ); + } + else + Value = - 1; + } +} + + +void ReadIndex( int64_t& Value, const String& fmt, const VECTOROFCONST& Args, int& ChPos, int& OldPos, unsigned int& ArgPos, int& Len, int64_t& Index) +{ + if ( fmt[ChPos - 1] != ':' ) + ReadInteger(Value, fmt, Args, ChPos, OldPos, ArgPos, Len); + else + Value = 0; // Delphi undocumented behaviour, assume 0, #11099 + if ( fmt[ChPos - 1] == ':' ) + { + if ( Value == - 1 ) + DoFormatError( feMissingArgument ); + Index = Value; + Value = - 1; + ChPos++; + } +} + + +void ReadLeft( const String& fmt, int& ChPos, bool& Left) +{ + if ( fmt[ChPos - 1] == '-' ) + { + Left = true; + ChPos++; + } + else + Left = false; +} + + +void ReadWidth( int64_t& Value, const String& fmt, const VECTOROFCONST& Args, int& ChPos, int& OldPos, unsigned int& ArgPos, int& Len, int& Width) +{ + ReadInteger(Value, fmt, Args, ChPos, OldPos, ArgPos, Len); + if ( Value != - 1 ) + { + Width = (int) Value; + Value = - 1; + } +} + + +void ReadPrec( int64_t& Value, const String& fmt, const VECTOROFCONST& Args, int& ChPos, int& OldPos, unsigned int& ArgPos, int& Len, int& prec) +{ + if ( fmt[ChPos - 1] == '.' ) + { + ChPos++; + ReadInteger(Value, fmt, Args, ChPos, OldPos, ArgPos, Len); + if ( Value == - 1 ) + Value = 0; + prec = (int) Value; + } +} + + +Char ReadFormat( const String& fmt, const VECTOROFCONST& Args, int& ChPos, int& OldPos, unsigned int& ArgPos, unsigned int DoArg, int& Len, int64_t& Index, int& Width, int& prec, bool& Left ) +{ + Char result = _T('\0'); + int64_t Value = 0; + Index = - 1; + Width = - 1; + prec = - 1; + Value = - 1; + ChPos++; + if ( fmt[ChPos - 1] == '%' ) + { + result = _T('%'); + return result; // vp fix + } + ReadIndex( Value, fmt, Args, ChPos, OldPos, ArgPos, Len, Index); + ReadLeft( fmt, ChPos, Left); + ReadWidth( Value, fmt, Args, ChPos, OldPos, ArgPos, Len, Width); + ReadPrec( Value, fmt, Args, ChPos, OldPos, ArgPos, Len, prec); + return toupper( fmt[ChPos - 1] ); +} + + +bool Checkarg( int at, bool err, const VECTOROFCONST& Args, unsigned int& ArgPos, unsigned int DoArg, int64_t& Index) +/* + Check if argument Index is of correct type (at) + if Index=-1, ArgPos is used, and ArgPos is augmented with 1 + DoArg is set to the argument that must be used. +*/ +{ + bool result = false; + if ( Index == - 1 ) + DoArg = ArgPos; + else + DoArg = (unsigned int) Index; + ArgPos = DoArg + 1; + if ( ( DoArg > Args.size() - 1 /*# High(Args) */ ) || ( Args[DoArg].VType != at ) ) + { + if ( err ) + DoFormatError( feInvalidArgIndex ); + ArgPos--; + return result; + } + return true; +} + + +String Format( const String& fmt, const VECTOROFCONST& Args, const TFormatSettings& FormatSettings ) +{ + String result; + int ChPos = 0, OldPos = 0, DoArg = 0, Len = 0; + unsigned ArgPos = 0; + String hs, ToAdd; + int64_t Index = 0; + int Width = 0, prec = 0; + bool Left = false; + Char FCHAR = _T('\0'); + QWord vq; + + /* + ReadFormat reads the Format String. it returns the type character in + UpperCase, and sets Index, Width, prec to their correct values, + or -1 if not set. it sets Left to True if Left alignment was Requested. + in case of an Error, DoFormatError is called. + */ + const Char zero[] = _T("000000000000000000000000000000000000000000000000000000000000000"); + result = _T(""); + Len = fmt.length( ); + ChPos = 1; + OldPos = 1; + ArgPos = 0; + while ( ChPos <= Len ) + { + while ( ( ChPos <= Len ) && ( fmt[ChPos - 1] != '%' ) ) + ChPos++; + if ( ChPos > OldPos ) + result = result + fmt.substr( OldPos - 1, ChPos - OldPos ); + if ( ChPos < Len ) + { + FCHAR = ReadFormat(fmt, Args, ChPos, OldPos, ArgPos, DoArg, Len, Index, Width, prec, Left); + switch ( FCHAR ) + { + case _T('D'): + { + if ( Checkarg( vtInteger, false, Args, ArgPos, DoArg, Index ) ) + Str( Args[DoArg].VInteger, ToAdd ); + else + if ( Checkarg( vtInt64, false, Args, ArgPos, DoArg, Index ) ) + Str( *Args[DoArg].VInt64, ToAdd ); + else + if ( Checkarg( vtUInt64, true, Args, ArgPos, DoArg, Index ) ) + Str( ((int64_t) *Args[DoArg].VUInt64 ), ToAdd ); + Index = (int64_t) prec - ToAdd.length(); + if(Index > 0) // dme + { + if ( ToAdd[1 - 1] != '-' ) + ToAdd = String((int) Index, _T('0') ) + ToAdd; + else + { + // + 1 to accomodate for - sign in Length !! + String tmp = String( (int) Index + 1 , _T('0')); + ToAdd.insert( 1, tmp ); + } + } + } + break; + case _T('U'): + { + if ( Checkarg( vtInteger, false, Args, ArgPos, DoArg, Index ) ) + Str( ((unsigned int) Args[DoArg].VInteger ), ToAdd ); + else + if ( Checkarg( vtInt64, false, Args, ArgPos, DoArg, Index ) ) + Str( QWord( *Args[DoArg].VInt64 ), ToAdd ); + else + if ( Checkarg( vtUInt64, true, Args, ArgPos, DoArg, Index ) ) + Str( *Args[DoArg].VUInt64, ToAdd ); + Width = Abs( Width ); + Index = (int64_t) prec - ToAdd.length(); + if(Index > 0) // dme + ToAdd = String( (int) Index, _T('0') ) + ToAdd; + } + break; + case _T('E'): + { + if ( Checkarg( vtCurrency, false, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VCurrency, ffExponent, prec, 3, FormatSettings ); + else + if ( Checkarg( vtExtended, true, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VExtended, ffExponent, prec, 3, FormatSettings ); + } + break; + case _T('F'): + { + if ( Checkarg( vtCurrency, false, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VCurrency, ffFixed, 9999, prec, FormatSettings ); + else + if ( Checkarg( vtExtended, true, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VExtended, ffFixed, 9999, prec, FormatSettings ); + } + break; + case _T('G'): + { + if ( Checkarg( vtCurrency, false, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VCurrency, ffGeneral, prec, 3, FormatSettings ); + else + if ( Checkarg( vtExtended, true, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VExtended, ffGeneral, prec, 3, FormatSettings ); + } + break; + case _T('N'): + { + if ( Checkarg( vtCurrency, false, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VCurrency, ffNumber, 9999, prec, FormatSettings ); + else + if ( Checkarg( vtExtended, true, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VExtended, ffNumber, 9999, prec, FormatSettings ); + } + break; + case _T('M'): + { + if ( Checkarg( vtExtended, false, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VExtended, ffCurrency, 9999, prec, FormatSettings ); + else + if ( Checkarg( vtCurrency, true, Args, ArgPos, DoArg, Index ) ) + ToAdd = FloatToStrF( *Args[DoArg].VCurrency, ffCurrency, 9999, prec, FormatSettings ); + } + break; + case _T('S'): + { + if ( Checkarg( vtString, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = str2wstr((*Args[DoArg].VString).c_str()); +#else + hs = *Args[DoArg].VString; +#endif + else + if ( Checkarg( vtChar, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = char2wchar(Args[DoArg].VChar); +#else + hs = Args[DoArg].VChar; +#endif + else + if ( Checkarg( vtPChar, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = str2wstr(Args[DoArg].VPChar); +#else + hs = Args[DoArg].VPChar; +#endif + else + if ( Checkarg( vtPWideChar, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = Args[DoArg].VPWideChar; +#else + hs = wstr2str(Args[DoArg].VPWideChar); +#endif + else + if ( Checkarg( vtWideChar, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = String(1, Args[DoArg].VWideChar ); +#else + hs = String(1, wchar2char(Args[DoArg].VWideChar )); +#endif + else + if ( Checkarg( vtWideString, false, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = (wchar_t*) Args[DoArg].VWideString; +#else + hs = wstr2str( (wchar_t*) Args[DoArg].VWideString ); +#endif + else + if ( Checkarg( vtAnsiString, true, Args, ArgPos, DoArg, Index ) ) +#ifdef _WIDESTRING + hs = str2wstr((char*) Args[DoArg].VAnsiString ); +#else + hs = (char*) Args[DoArg].VAnsiString; +#endif + Index = hs.length(); + if ( ( prec != - 1 ) && ( Index > prec ) ) + Index = prec; + if(Index > 0) + ToAdd = hs.substr( 0, (unsigned int) Index ); + else + ToAdd = _T(""); + } + break; + case _T('P'): + { + Checkarg( vtPointer, true, Args, ArgPos, DoArg, Index ); + ToAdd = hexstr( intptr_t(Args[DoArg].VPointer), sizeof(intptr_t) * 2 ); + // Insert ':'. is this needed in 32 bit ? no it isn'T. + // Insert(':',ToAdd,5); + } + break; + case _T('X'): + { + if ( Checkarg( vtInteger, false, Args, ArgPos, DoArg, Index ) ) + { + vq = ((unsigned int) Args[DoArg].VInteger ); + Index = 16; + } + else + if ( Checkarg( vtUInt64, false, Args, ArgPos, DoArg, Index ) ) + { + vq = QWord( *Args[DoArg].VUInt64 ); + Index = 31; + } + else + { + Checkarg( vtInt64, true, Args, ArgPos, DoArg, Index ); + vq = QWord( *(Args[DoArg].VInt64) ); + Index = 31; + } + if ( prec > Index ) + ToAdd = hexstr( (int) vq, (unsigned char) Index ); + else + { + // determine minimum needed number of hex Digits. + Index = 1; + while ( ( ( QWord( 1 ) << ( Index * 4 ) ) <= vq ) && ( Index < 16 ) ) + Index++; + if ( Index > prec ) + prec = (int) Index; + ToAdd = hexstr( (int) vq, (unsigned char) prec ); + } + } + break; + case _T('%'): + ToAdd = '%'; + break; + } + if ( Width != - 1 ) + if ( ToAdd.length() < (unsigned int) Width ) + { + if ( ! Left ) + ToAdd = space( Width - ToAdd.length()) + ToAdd; + else + ToAdd = ToAdd + space( Width - ToAdd.length()); + } + result = result + ToAdd; + } + ChPos++; + OldPos = ChPos; + } + return result; +} +/*$macro OFF*/ + + +String Format( const String& fmt, const VECTOROFCONST& Args ) +{ + return Format( fmt, Args, DefaultFormatSettings ); +} + + +/* +unsignedint FormatBuf( void* Buffer, unsignedint BufLen, void* fmt, unsignedint FmtLen, const ARRAYOFCONST& Args, const TFormatSettings& FormatSettings ) +{ + unsignedint result = 0; + String S, F; + F.resize( FmtLen ); + if ( FmtLen > 0 ) + Move( fmt, &F[1 - 1], FmtLen ); + S = Format( F, Args, FormatSettings ); + if ( ((unsigned int) S.length( ) ) < BufLen ) + result = S.length( ); + else + result = BufLen; + Move( &S[1 - 1], Buffer, result ); + return result; +} + + +unsignedint FormatBuf( void* Buffer, unsignedint BufLen, void* fmt, unsignedint FmtLen, const ARRAYOFCONST& Args ) +{ + unsignedint result = 0; + result = FormatBuf( Buffer, BufLen, fmt, FmtLen, Args, DefaultFormatSettings ); + return result; +} +*/ +unsignedint FormatBuf( Char* Buffer, unsignedint BufLen, const Char* fmt, unsignedint FmtLen, const VECTOROFCONST& Args, const TFormatSettings& FormatSettings ) +{ + unsignedint result = 0; + String S, F; + F.resize( FmtLen ); + if ( FmtLen > 0 ) + Move( fmt, F, FmtLen ); + S = Format( F, Args, FormatSettings ); + if ( ((unsigned int) S.length( ) ) < BufLen ) + result = S.length( ); + else + result = BufLen; + Move( S, Buffer, result ); + return result; +} + + +unsignedint FormatBuf( Char* Buffer, unsignedint BufLen, const Char* fmt, unsignedint FmtLen, const VECTOROFCONST& Args ) +{ + return FormatBuf( Buffer, BufLen, fmt, FmtLen, Args, DefaultFormatSettings ); +} + + +void FmtStr( String& RES, const String& fmt, const VECTOROFCONST& Args, const TFormatSettings& FormatSettings ) +{ + RES = Format( fmt, Args, FormatSettings ); +} + + +void FmtStr( String& RES, const String& fmt, const VECTOROFCONST& Args ) +{ + FmtStr( RES, fmt, Args, DefaultFormatSettings ); +} + + +Char* StrFmt( Char* Buffer, const Char* fmt, const VECTOROFCONST& Args, const TFormatSettings& FormatSettings ) +{ + Char* result = NULL; +#ifdef _WIDESTRING + Buffer[FormatBuf( Buffer, MAXINT, fmt, wcslen( fmt ), Args, FormatSettings )] = _T('\x00'); +#else + Buffer[FormatBuf( Buffer, MAXINT, fmt, strlen( fmt ), Args, FormatSettings )] = _T('\x00'); +#endif + return Buffer; +} + + +Char* StrLFmt( Char* Buffer, unsignedint MaxLen, const Char* fmt, const VECTOROFCONST& Args, const TFormatSettings& FormatSettings ) +{ + Char* result = NULL; +#ifdef _WIDESTRING + Buffer[FormatBuf( Buffer, MaxLen, fmt, wcslen( fmt ), Args, FormatSettings )] = _T('\x00'); +#else + Buffer[FormatBuf( Buffer, MaxLen, fmt, strlen( fmt ), Args, FormatSettings )] = _T('\x00'); +#endif + return Buffer; +} + +Char* StrFmt( Char* Buffer, const Char* fmt, const VECTOROFCONST& Args ) +{ + return StrFmt( Buffer, fmt, Args, DefaultFormatSettings ); +} + +Char* StrLFmt( Char* Buffer, unsignedint MaxLen, const Char* fmt, const VECTOROFCONST& Args ) +{ + return StrLFmt( Buffer, MaxLen, fmt, Args, DefaultFormatSettings ); +} + +bool TextToFloat( const Char* Buffer, long double& Value, const TFormatSettings& FormatSettings ) +{ + bool result = false; + int e = 0, P = 0; + String S; + S = Buffer; + P = Pos( FormatSettings.DecimalSeparator, S ); + if ( P != 0 ) + S[P - 1] = '.'; + Val( Trim( S ), &Value, e ); + return ( e == 0 ); +} + + +bool TextToFloat( const Char* Buffer, void* Value, TFloatValue ValueType, const TFormatSettings& FormatSettings ) +{ + bool result = false; + int e = 0, P = 0; + String S; + long double TempValue = 0.0; + S = Buffer; + P = Pos( FormatSettings.ThousandSeparator, S ); + while ( P != 0 ) + { + S.erase( P - 1, 1 ); + P = Pos( FormatSettings.ThousandSeparator, S ); + } + P = Pos( FormatSettings.DecimalSeparator, S ); + if ( P != 0 ) + S[P - 1] = _T('.'); + switch ( ValueType ) + { + case fvCurrency: + { + // needed for platforms Where Currency = Int64 + Val( S, &TempValue, e ); + Currency Value = (double) TempValue; + } + break; + case fvExtended: + Val( S, ((long double*) Value), e ); + break; + case fvDouble: + Val( S, ((double*) Value), e ); + break; + case fvSingle: + Val( S, ((float*) Value), e ); + break; + case fvComp: + Val( S, ((complex*) Value), e ); + break; + case fvReal: + Val( S, ((double*) Value), e ); + break; + } + return ( e == 0 ); +} + +bool TextToFloat( const Char* Buffer, long double& Value ) +{ + return TextToFloat( Buffer, Value, DefaultFormatSettings ); +} + + + +bool TryStrToFloat( const String& S, float& Value, const TFormatSettings& FormatSettings ) +{ + return TextToFloat( (Char*) ( ((void*) S.c_str()) ), &Value, fvSingle, FormatSettings ); +} + + +bool TryStrToFloat( const String& S, double& Value, const TFormatSettings& FormatSettings ) +{ + return TextToFloat( (Char*) ( ((void*) S.c_str()) ), &Value, fvDouble, FormatSettings ); +} + +bool TextToFloat( const Char* Buffer, void* Value, TFloatValue ValueType ) +{ + return TextToFloat( Buffer, Value, ValueType, DefaultFormatSettings ); +} + + +bool TryStrToFloat( const String& S, float& Value ) +{ + return TryStrToFloat( S, Value, DefaultFormatSettings ); +} + +bool TryStrToFloat( const String& S, double& Value ) +{ + return TryStrToFloat( S, Value, DefaultFormatSettings ); +} + + +long double StrToFloatDef( const String& S, const long double deflt, const TFormatSettings& FormatSettings ) +{ + long double result = 0.0; + if ( ! TextToFloat( S.c_str(), (void*) &result, fvExtended, FormatSettings ) ) + result = deflt; + return result; +} + +long double StrToFloat( const String& S, const TFormatSettings& FormatSettings ) +{ + long double result = 0.0; // TextToFloat handles nil properly + if ( ! TextToFloat( (Char*) ( ((void*) S.c_str()) ), result, FormatSettings ) ) + throw EConvertError( ErrorString(_T(SysConst_SInvalidFloat), S )); + return result; +} + +long double StrToFloat( const String& S ) +{ + return StrToFloat( S, DefaultFormatSettings ); +} + + +long double StrToFloatDef( const String& S, const long double deflt ) +{ + long double result = 0.0; + return StrToFloatDef( S, deflt, DefaultFormatSettings ); +} + + + + +String AnsiDequotedStr( const String& S, Char AQuote ) +{ + String result; + Char* P = NULL; + P = (Char*) ( ((void*) S.c_str()) ); // work around const. Ansiextract is safe for nil + result = AnsiExtractQuotedStr( P, AQuote ); + if ( result.empty()) + result = S; + return result; +} + + + + +bool StrToBool( const String& S ) +{ + bool result = false; + if ( ! ( TryStrToBool( S, result ) ) ) + throw EConvertError( ErrorString(_T(SysConst_SInvalidBoolean), S )); + return result; +} + + +void CheckStrs( bool& B, bool& UseBoolStrs, String& result ) +{ + if ( TrueBoolStrs.size( ) == 0 ) + { + TrueBoolStrs.resize( 1 ); + TrueBoolStrs[0] = _T("True"); + } + if ( FalseBoolStrs.size( ) == 0 ) + { + FalseBoolStrs.resize( 1 ); + FalseBoolStrs[0] = _T("False"); + } +} + + +String BoolToStr( bool B, bool UseBoolStrs ) +{ + String result; + if ( UseBoolStrs ) + { + CheckStrs(B, UseBoolStrs, result); + if ( B ) + result = TrueBoolStrs[0]; + else + result = FalseBoolStrs[0]; + } + else + if ( B ) + result = _T("-1"); + else + result = _T("0"); + return result; +} + + +bool StrToBoolDef( const String& S, bool deflt ) +{ + bool result = false; + if ( ! ( TryStrToBool( S, result ) ) ) + result = deflt; + return result; +} + + +bool TryStrToBool( const String& S, bool& Value ) +{ + bool result = false; + String Temp; + double D = 0.0; + int Code = 0; + Temp = UpperCase( S ); + Val( Temp, &D, Code ); + result = true; + if ( Code == 0 ) + Value = ( D != 0.0 ); + else + if ( Temp == _T("TRUE")) + Value = true; + else + if ( Temp == _T("FALSE")) + Value = false; + else + result = false; + return result; +} + + +bool GetSectionEnd( Char*& P ) +{ + bool result = false; + Char C = _T('\0'); + bool SQ = false, DQ = false; + result = false; + SQ = false; + DQ = false; + C = P[0]; + while ( ( C != _T('\x00')) && ( ( C != _T(';')) || SQ || DQ ) ) + { + result = true; + switch ( C ) + { + case _T('\x22'): + if ( ! SQ ) + DQ = ! DQ; + break; + case _T('\x27'): + if ( ! DQ ) + SQ = ! SQ; + break; + } + P++; + C = P[0]; + } + return result; +} + + +void GetSectionRange( int section, long double& Value, Char*& Format, Char*& FmtStart, Char*& FmtStop ) +{ + Char* Sec[ 3/*# range 1..3*/ ]; + bool SecOk[ 3/*# range 1..3*/ ]; + Sec[1 - 1] = Format; + SecOk[1 - 1] = GetSectionEnd( Sec[1 - 1] ); + if ( section > 1 ) + { + Sec[2 - 1] = Sec[1 - 1]; + if ( Sec[2 - 1][0] != _T('\x00')) + Sec[2 - 1]++; + SecOk[2 - 1] = GetSectionEnd( Sec[2 - 1] ); + if ( section > 2 ) + { + Sec[3 - 1] = Sec[2 - 1]; + if ( Sec[3 - 1][0] != _T('\x00')) + Sec[3 - 1]++; + SecOk[3 - 1] = GetSectionEnd( Sec[3 - 1] ); + } + } + if ( ! SecOk[1 - 1] ) + FmtStart = NULL; + else + { + if ( ! SecOk[section - 1] ) + section = 1; + else + if ( section == 2 ) + Value = - Value; /* remove sign */ + + /* find Format section ranging from FmtStart to FmtStop. */ + if ( section == 1 ) + FmtStart = Format; + else + { + FmtStart = Sec[section - 1 - 1]; + FmtStart++; + } + FmtStop = Sec[section - 1]; + } +} + +void GetFormatOptions( Char*& FmtStart, Char*& FmtStop, int& ExpFmt, int& ExpSize, int* Placehold, bool& thousand ) +{ + Char* fmt = NULL; + bool SQ = false, DQ = false; + int area = 0; + SQ = false; + DQ = false; + fmt = FmtStart; + ExpFmt = 0; + area = 1; + thousand = false; + Placehold[1 - 1] = 0; + Placehold[2 - 1] = 0; + Placehold[3 - 1] = 0; + Placehold[4 - 1] = 0; + while ( fmt < FmtStop ) + { + switch ( fmt[0] ) + { + case _T('\x22'): + { + if ( ! SQ ) + DQ = ! DQ; + fmt++; + } + break; + case _T('\x27'): + { + if ( ! DQ ) + SQ = ! SQ; + fmt++; + } + break; + default: + /* if not in quotes, then interpret*/ + if ( ! ( SQ || DQ ) ) + { + switch ( fmt[0] ) + { + case _T('0'): + { + switch ( area ) + { + case 1: + area = 2; + break; + case 4: + { + area = 3; + Placehold[3 - 1] += Placehold[4 - 1]; + Placehold[4 - 1] = 0; + } + break; + } + Placehold[area - 1]++; + fmt++; + } + break; + case _T('#'): + { + if ( area == 3 ) + area = 4; + Placehold[area - 1]++; + fmt++; + } + break; + case _T('.'): + { + if ( area < 3 ) + area = 3; + fmt++; + } + break; + case _T(','): + { + thousand = true; + fmt++; + } + break; + case _T('e'): case _T('E'): + if ( ExpFmt == 0 ) + { + if ( fmt[0] == _T('E')) + ExpFmt = 1; + else + ExpFmt = 3; + fmt++; + if ( fmt < FmtStop ) + { + switch ( fmt[0] ) + { + case _T('+'): + { + } + break; + case _T('-'): + ExpFmt++; + break; + default: + ExpFmt = 0; + } + if ( ExpFmt != 0 ) + { + fmt++; + ExpSize = 0; + while ( ( fmt < FmtStop ) && ( ExpSize < 4 ) && ( Sysutils__12.Contains(fmt[0] ) ) ) + { + ExpSize++; + fmt++; + } + } + } + } + else + fmt++; + break; + default: /* case */ + fmt++; + } /* case */ + } /* begin */ + else + fmt++; + } /* case */ + } /* While .. begin */ +} + + + + +void FloatToStr( long double& Value, String& Digits, String& Exponent, int& ExpFmt, int& ExpSize, int* Placehold, int& UnexpectedDigits, int& DigitExponent ) +{ + int i = 0, j = 0, Exp = 0, Width = 0, Decimals = 0, DecimalPoint = 0, Len = 0; + if ( ExpFmt == 0 ) + { + /* Fixpoint */ + Decimals = Placehold[3 - 1] + Placehold[4 - 1]; + Width = Placehold[1 - 1] + Placehold[2 - 1] + Decimals; + /* + if ( Decimals == 0 ) + Str( Value, Width, 0, Digits ); + else + Str( Value, Width + 1, Decimals, Digits ); +*/ + Char buf[160]; +#ifdef _WIDESTRING + if ( Decimals == 0 ) + swprintf(buf, 160, L"%*.*f", Width, 0, Value); + else + swprintf(buf, 160, L"%*.*f", Width + 1, 0, Value); +#else + if ( Decimals == 0 ) + sprintf(buf, "%*.*Lf", Width, 0, Value); + else + sprintf(buf, "%*.*Lf", Width + 1, 0, Value); +#endif + Digits = buf; + + Len = Digits.size(); // [0]; + /* find the decimal Point */ + if ( Decimals == 0 ) + DecimalPoint = Len + 1; + else + DecimalPoint = Len - Decimals; + /* if Value is very small, and no decimal places + are desired, remove the leading 0. */ + if ( ( Abs( Value ) < 1 ) && ( Placehold[2 - 1] == 0 ) ) + { + if ( Placehold[1 - 1] == 0 ) + Digits.erase( max(0, DecimalPoint - 1 - 1), 1 ); + else + Digits[DecimalPoint - 1 - 1] = _T(' '); + } + + /* convert Optional zeroes to spaces. */ + i = Len; + j = DecimalPoint + Placehold[3 - 1]; + while ( ( i > j ) && ( Digits[i - 1] == _T('0') ) ) + { + Digits[i - 1] = _T(' '); + i--; + } + /* if Integer Value and no obligatory decimal + places, remove decimal Point. */ + if ( ( DecimalPoint < Len ) && ( Digits[DecimalPoint + 1 - 1] == _T(' ') ) ) + Digits[DecimalPoint - 1] = _T(' '); + /* convert spaces Left from obligatory decimal Point to zeroes. */ + i = DecimalPoint - Placehold[2 - 1]; + while ( ( i < DecimalPoint ) && ( Digits[i - 1] == _T(' ') ) ) + { + Digits[i - 1] = _T('0'); + i++; + } + Exp = 0; + } + else + { + /* Scientific: Exactly Digits with Decimals + and adjusted Exponent. */ + if ( Placehold[1 - 1] + Placehold[2 - 1] == 0 ) + Placehold[1 - 1] = 1; + Decimals = Placehold[3 - 1] + Placehold[4 - 1]; + Width = Placehold[1 - 1] + Placehold[2 - 1] + Decimals; + /* depending ON the maximally supported Precision, the Exponent field */ + /* is longer/shorter */ + Str( Value, Width + 6, Digits ); // dme: 1234.567 : 14 -> 1.234567E+0003 + + /* find and cut out Exponent. always the + Last 6 characters in the String. + -> 0000e+0000 + *** no, not always the Last 6 characters, this depends ON + the maximally supported Precision (JM)*/ + i = Pos( _T("E"), Digits ); + Val( Digits.substr( i + 1 - 1, 255 ), &Exp, j ); + Exp = Exp + 1 - ( Placehold[1 - 1] + Placehold[2 - 1] ); + //Digits.erase( i - 1, 255 ); + if(i > 0) + Digits.erase( i - 1 ); // if len parameter is missing all remaining characters are removed + /* str() always returns at least one digit After the decimal Point. + if we don'T Want it, we have to remove it. */ + if ( ( Decimals == 0 ) && ( Placehold[1 - 1] + Placehold[2 - 1] <= 1 ) ) + { + if ( Digits[4 - 1] >= _T('5') ) + { + Digits[2 - 1]++; + if ( Digits[2 - 1] > _T('9') ) + { + Digits[2 - 1] = _T('1'); + Exp++; + } + } + Digits.erase( 3 - 1, 2 ); + DecimalPoint = Digits.length( ) + 1; + } + else + { + /* Move decimal Point at the desired position */ + /* dme + Digits.erase( 3 - 1, 1 ); + DecimalPoint = 2 + Placehold[1 - 1] + Placehold[2 - 1]; + if ( Decimals != 0 ) + Digits.insert( DecimalPoint - 1, _T(".") ); + */ + } + + /* convert Optional zeroes to spaces. */ + i = Digits.length( ); + j = DecimalPoint + Placehold[3 - 1]; + while ( ( i > j ) && ( Digits[i - 1] == _T('0') ) ) + { + Digits[i - 1] = _T(' '); + i--; + } + + /* if Integer number and no obligatory decimal paces, remove decimal Point */ + if ( ( DecimalPoint < (int) Digits.length( ) ) && ( Digits[DecimalPoint + 1 - 1] == _T(' ') ) ) + Digits[DecimalPoint - 1] = _T(' '); + if ( Digits[1 - 1] == _T(' ') ) + { + Digits.erase( 1 - 1, 1 ); + DecimalPoint--; + } + /* Calculate Exponent String */ + Str( Abs( Exp ), Exponent ); + while ( (int) Exponent.length( ) < ExpSize ) + Exponent.insert( 1 - 1, _T("0") ); + if ( Exp >= 0 ) + { + if ( Sysutils__13.Contains(ExpFmt ) ) + Exponent.insert( 1 - 1, _T("+") ); + } + else + Exponent.insert( 1 - 1, _T("-") ); + if ( ExpFmt < 3 ) + Exponent.insert( 1 - 1, _T("E") ); + else + Exponent.insert( 1 - 1, _T("e") ); + } + DigitExponent = DecimalPoint - 2; + if ( !Digits.empty() && Digits[1 - 1] == _T('-') ) + DigitExponent--; + UnexpectedDigits = DecimalPoint - 1 - ( Placehold[1 - 1] + Placehold[2 - 1] ); +} + + +int PutResult( Char*& Buffer, const TFormatSettings& FormatSettings, String& Digits, String& Exponent, Char*& FmtStart, Char*& FmtStop, int& ExpFmt, int& ExpSize, bool& thousand, int& UnexpectedDigits, int& DigitExponent ) +{ + int result = 0; + bool SQ = false, DQ = false; + Char* fmt = NULL,* Buf = NULL; + int dig = 0, n = 0; + SQ = false; + DQ = false; + fmt = FmtStart; + Buf = Buffer; + dig = 1; + while ( fmt < FmtStop ) + { + //write(fmt[0]); + switch ( fmt[0] ) + { + case _T('\x22'): + { + if ( ! SQ ) + DQ = ! DQ; + fmt++; + } + break; + case _T('\x27'): + { + if ( ! DQ ) + SQ = ! SQ; + fmt++; + } + break; + default: + if ( ! ( SQ || DQ ) ) + { + switch ( fmt[0] ) + { + case _T('0'): case _T('#'): case _T('.'): + { + if ( ( dig == 1 ) && ( UnexpectedDigits > 0 ) ) + { + /* everything unexpected is written before the First digit */ + for ( n = 1; n <= UnexpectedDigits; n++) + { + Buf[0] = Digits[n - 1]; + Buf++; + if ( thousand && ( Digits[n - 1] != _T('-') ) ) + { + if ( ( DigitExponent % 3 == 0 ) && ( DigitExponent > 0 ) ) + { + Buf[0] = FormatSettings.ThousandSeparator; + Buf++; + } + DigitExponent--; + } + } + dig += UnexpectedDigits; + } + if ( dig <= (int) Digits.size() && Digits[dig - 1] != _T(' ') ) + { + if ( Digits[dig - 1] == _T('.') ) + Buf[0] = FormatSettings.DecimalSeparator; + else + Buf[0] = Digits[dig - 1]; + Buf++; + if ( thousand && ( DigitExponent % 3 == 0 ) && ( DigitExponent > 0 ) ) + { + Buf[0] = FormatSettings.ThousandSeparator; + Buf++; + } + } + dig++; + DigitExponent--; + fmt++; + } + break; + case _T('e'): case _T('E'): + { + if ( ExpFmt != 0 ) + { + fmt++; + if ( fmt < FmtStop ) + { + if ( Sysutils__14.Contains(fmt[0] ) ) + { + fmt += ExpSize; + for ( n = 1; n <= (int) Exponent.length( ); n++) + Buf[n - 1] = Exponent[n - 1]; + Buf += Exponent.length( ); + ExpFmt = 0; + } + fmt++; + } + } + else + { + /* no Legal Exponential Format. + simply write the 'E' to the result. */ + Buf[0] = fmt[0]; + Buf++; + fmt++; + } + } + break; + default: /* case */ + /* usual character */ + if ( fmt[0] != _T(',')) + { + Buf[0] = fmt[0]; + Buf++; + } + fmt++; + } /* case */ + } + else /* if */ + { + /* character inside Single or Double quotes */ + Buf[0] = fmt[0]; + Buf++; + fmt++; + } + } /* case */ + } /* While .. begin */ + //result = ((PtrUInt) Buf ) - ((PtrUInt) Buffer ); + return Buf- Buffer; +} + + +int FloatToTextFmt( Char* Buffer, long double Value, Char* Format, const TFormatSettings& FormatSettings ) +{ + int result = 0; + String Digits; /* String of Digits */ + Digits.resize(40); + String Exponent; /* Exponent strIn */ + Exponent.resize(8); + Char* FmtStart = NULL,* FmtStop /* start and end of relevant part */ + /* of Format String */ = NULL; + int ExpFmt = 0, ExpSize /* type and Length of */ + /* Exponential Format chosen */ = 0; + int Placehold[ 4/*# range 1..4*/ ]; /* number of placeholders in all */ + /* four sections */ + bool thousand /* thousand separators? */ = false; + int UnexpectedDigits /* number of unexpected Digits that */ + /* have to be inserted before the */ + /* First placeholder. */ = 0; + int DigitExponent /* Exponent of First digit in */ + /* Digits array. */ + + /* find end of Format section starting at P. False, if empty */ = 0; + + /* find start and end of Format section to apply. if section doesn'T exist, + use section 1. if section 2 is used, the sign of Value is ignored. */ + if ( Value > 0 ) + GetSectionRange( 1, Value, Format, FmtStart, FmtStop ); + else + if ( Value < 0 ) + GetSectionRange( 2, Value, Format, FmtStart, FmtStop ); + else + GetSectionRange( 3, Value, Format, FmtStart, FmtStop ); + if ( FmtStart == NULL ) + { + result = FloatToText( Buffer, Value, ffGeneral, 15, 4, FormatSettings ); + } + else + { + GetFormatOptions( FmtStart, FmtStop, ExpFmt, ExpSize, Placehold, thousand); + if ( ( ExpFmt == 0 ) && ( Abs( Value ) >= 1E18) ) + result = FloatToText( Buffer, Value, ffGeneral, 15, 4, FormatSettings ); + else + { + FloatToStr( Value, Digits, Exponent, ExpFmt, ExpSize, Placehold, UnexpectedDigits, DigitExponent ); + result = PutResult(Buffer, FormatSettings, Digits, Exponent, FmtStart, FmtStop, ExpFmt, ExpSize, thousand, UnexpectedDigits, DigitExponent); + } + } + return result; +} + +int FloatToTextFmt( Char* Buffer, long double Value, Char* Format ) +{ + return FloatToTextFmt( Buffer, Value, Format, DefaultFormatSettings ); +} + +void FloatToDecimal( TFloatRec& result, void* Value, TFloatValue ValueType, int Precision, int Decimals ) +{ + String Buffer; + int Error = 0, n = 0, l = 0, start = 0, C = 0; + bool GotNonZeroBeforeDot = false, BeforeDot = false; + switch ( ValueType ) + { + case fvExtended: + Str( *(long double*) Value, 25, Buffer ); + break; + case fvDouble: case fvReal: + Str( *(double*) Value, 23, Buffer ); + break; + case fvSingle: + Str( *(float*) Value, 16, Buffer ); + break; + case fvCurrency: + Str( *(Currency*) Value, 25, 2, Buffer ); + break; + case fvComp: + Str( *(Currency*) Value, 23, 2, Buffer ); + break; + } + n = 1; + l = ((unsigned char) Buffer[0] ); + while ( Buffer[n] == ' ' ) + n++; + result.Negative = ( Buffer[n] == '-' ); + if ( result.Negative ) + n++; + start = n; //start of Digits + result.Exponent = 0; + BeforeDot = true; + GotNonZeroBeforeDot = false; + while ( ( l >= n ) && ( Buffer[n] != 'E' ) ) + { + if ( Buffer[n] == '.' ) + BeforeDot = false; + else + { + if ( BeforeDot ) + { // Currently this is always 1 char + result.Exponent++; + result.Digits[n - start] = Buffer[n]; + if ( Buffer[n] != '0' ) + GotNonZeroBeforeDot = true; + } + else + result.Digits[n - start - 1] = Buffer[n]; + } + n++; + } + n++; // Pass through 'e' + if ( n <= l ) + { + Val( String( Buffer ).substr( n, l - n + 1 ), &C, Error ); // get Exponent After 'e' + result.Exponent += C; + } + // Calculate number of Digits we have from str + if ( BeforeDot ) + n = n - start - 1; + else + n = n - start - 2; + l = sizeof( result.Digits ); // todo + if ( n < l ) + FillChar( &result.Digits[n], l - n, '0' ); //zero remaining space + if ( Decimals + result.Exponent < Precision ) //After this it is the same as in FloatToDecimal + n = Decimals + result.Exponent; + else + n = Precision; + if ( n >= l ) + n = l - 1; + if ( n == 0 ) + { + if ( result.Digits[0] >= _T('5')) + { + result.Digits[0] = _T('1'); + result.Digits[1] = _T('\x00'); + result.Exponent++; + } + else + result.Digits[0] = _T('\x00'); + } //n=0 + else + if ( n > 0 ) + { + if ( result.Digits[n] >= _T('5')) + { + do + { + result.Digits[n] = _T('\x00'); + n--; + result.Digits[n]++; + } + while ( ! ( ( n == 0 ) || ( result.Digits[n] < _T(':')) ) ); + if ( result.Digits[0] == _T(':')) + { + result.Digits[0] = _T('1'); + result.Exponent++; + } + } + else + { + result.Digits[n] = _T('0'); + while ( ( n > - 1 ) && ( result.Digits[n] == _T('0')) ) + { + result.Digits[n] = _T('\x00'); + n--; + } + } + } //n>0 + else + result.Digits[0] = _T('\x00'); + if ( ( result.Digits[0] == _T('\x00')) && ! GotNonZeroBeforeDot ) + { + result.Exponent = 0; + result.Negative = false; + } +} + + +void FloatToDecimal( TFloatRec& result, long double Value, int Precision, int Decimals ) +{ + FloatToDecimal( result, &Value, fvExtended, Precision, Decimals ); +} + + +String FormatFloat( const String& Format, long double Value, const TFormatSettings& FormatSettings ) +{ + String result; + Char Buf[ 1025/*# range 0..1024*/ ]; // not changed to PChar(Pointer(). possibly not safe + Buf[FloatToTextFmt( Buf, Value, (Char*) Format.c_str(), FormatSettings )] = _T('\x00'); + result = Buf; + return result; +} + + +String FormatFloat( const String& Format, long double Value ) +{ + return FormatFloat( Format, Value, DefaultFormatSettings ); +} + +String FormatCurr( const String& Format, Currency Value, const TFormatSettings& FormatSettings ) +{ + return FormatFloat( Format, (double) Value, FormatSettings ); +} + + +String FormatCurr( const String& Format, Currency Value ) +{ + return FormatCurr( Format, Value, DefaultFormatSettings ); +} + +int LastDelimiter( const String& Delimiters, const String& S ) +{ + int result = 0; + TSysCharSet cHS; + unsigned int i = 0; + cHS = TSysCharSet () ; + for ( i = 1; i <= Delimiters.length( ); i++) + cHS << Delimiters[i - 1]; + result = S.length( ); + while ( ( result > 0 ) && ! ( cHS.Contains(S[result - 1] ) ) ) + result--; + return result; +} + + +String StringReplace( const String& S, const String& OldPattern, const String& NewPattern, TReplaceFlags Flags ) +{ + String result; + String SrcH, OldP, RemS; // SrcH and OldP can contain UpperCase versions of S,OldPattern + + int P = 0; + SrcH = S; + OldP = OldPattern; + if ( Flags.Contains(rfIgnoreCase ) ) + { + SrcH = AnsiUpperCase( SrcH ); + OldP = AnsiUpperCase( OldP ); + } + RemS = S; + result = _T(""); + while ( SrcH.length( ) != 0 ) + { + P = AnsiPos( OldP, SrcH ); + if ( P == 0 ) + { + result = result + RemS; + SrcH = _T(""); + } + else + { + result = result + RemS.substr( 1 - 1, P - 1 ) + NewPattern; + P = P + OldP.length( ); + RemS = RemS.substr( P - 1, RemS.length( ) - P + 1 ); + if ( ! ( Flags.Contains(rfReplaceAll ) ) ) + { + result = result + RemS; + SrcH = _T(""); + } + else + SrcH = SrcH.substr( P - 1, SrcH.length( ) - P + 1 ); + } + } + return result; +} + + +bool IsDelimiter( const String& Delimiters, const String& S, int Index ) +{ + bool result = false; + result = false; + if ( ( Index > 0 ) && ( (unsigned int) Index <= S.length( ) ) ) + result = Pos( S[Index - 1], Delimiters ) != 0; // Note we don'T do MBCS yet + return result; +} + + +int ByteToCharLen( const String& S, int MaxLen ) +{ + int result = 0; + result = S.length( ); + if ( result > MaxLen ) + result = MaxLen; + return result; +} + + +int ByteToCharIndex( const String& S, int Index ) +{ + int result = 0; + result = Index; + return result; +} + + +int CharToByteLen( const String& S, int MaxLen ) +{ + int result = 0; + result = S.length( ); + if ( result > MaxLen ) + result = MaxLen; + return result; +} + + +int CharToByteIndex( const String& S, int Index ) +{ + int result = 0; + result = Index; + return result; +} + + +TMbcsByteType ByteType( const String& S, int Index ) +{ + TMbcsByteType result; + result = mbSingleByte; + return result; +} + + +TMbcsByteType StrByteType( Char* str, unsignedint Index ) +{ + TMbcsByteType result; + result = mbSingleByte; + return result; +} + +PtrInt CharLengthPChar( const char* str ) +{ + PtrInt result; + PtrInt nextlen; + const char* S = NULL; + mbstate_t mbstate; + result = 0; + S = str; + do + { + nextlen = PtrInt( mbrlen( str, MB_CUR_MAX, &mbstate ) ); + if ( nextlen < 0 ) + nextlen = 1; + result += nextlen; + S += nextlen; + } + while ( ! ( nextlen == 0 ) ); + return result; +} + + +int StrCharLength( const char* str ) +{ + int result = 0; + //result = widestringmanager.CharLengthPCharProc( str ); + result = CharLengthPChar( str ); + return result; +} + +const char* StrNextChar( const char* str ) +{ + const char* result = NULL; + result = str + StrCharLength( str ); + return result; +} + + +bool FindCmdLineSwitch( const String& Switch, const TSysCharSet Chars, bool IgnoreCase ) +{ + bool result = false; + int i = 0, l = 0; + String S, T; + result = false; + S = Switch; + if ( IgnoreCase ) + S = UpperCase( S ); + i = ParamCount(); + while ( ( ! result ) && ( i > 0 ) ) + { + l = ParamStr( i ).length( ); + if ( ( l > 0 ) && ( Chars.Contains(ParamStr( i )[1] ) ) ) + { + T = ParamStr( i ).substr( 2 - 1, l - 1 ); + if ( IgnoreCase ) + T = UpperCase( T ); + result = S == T; + } + i--; + } + return result; +} + + +bool FindCmdLineSwitch( const String& Switch, bool IgnoreCase ) +{ + bool result = false; + result = FindCmdLineSwitch( Switch, SwitchChars, IgnoreCase ); + return result; +} + + +bool FindCmdLineSwitch( const String& Switch ) +{ + bool result = false; + result = FindCmdLineSwitch( Switch, SwitchChars, false ); + return result; +} + + +String WrapText( const String& Line, const String& BreakStr, const TSysCharSet BreakChars, int MaxCol ) +{ + String result; + const TSet < UChar, 0, 255> quotes = ( TSet < UChar, 0, 255 >() << _T('\'') << _T('"') ); + String l; + Char C = _T('\0'), LQ = _T('\0'), BC = _T('\0'); + int P = 0, BLen = 0, Len = 0; + bool HB = false, IBC = false; + result = _T(""); + l = Line; + BLen = BreakStr.length( ); + if ( BLen > 0 ) + BC = BreakStr[1 - 1]; + else + BC = _T('\x00'); + Len = l.length( ); + while ( Len > 0 ) + { + P = 1; + LQ = _T('\x00'); + HB = false; + IBC = false; + while ( ( ( P <= Len ) && ( ( P <= MaxCol ) || ! IBC ) ) && ( ( LQ != _T('\x00')) || ! HB ) ) + { + C = l[P - 1]; + if ( C == LQ ) + LQ = _T('\x00'); + else + if ( quotes.Contains(C ) ) + LQ = C; + if ( LQ != _T('\x00')) + P++; + else + { + HB = ( ( C == BC ) && ( BreakStr == l.substr( P - 1, BLen ) ) ); + if ( HB ) + P += BLen; + else + { + if ( P > MaxCol ) + IBC = BreakChars.Contains(C ); + P++; + } + } +// WriteLn('"',C,'" : IBC : ',IBC,' HB : ',HB,' LQ : ',LQ,' P>MaxCol : ',P>MaxCol); + } + result = result + l.substr( 1 - 1, P - 1 ); + if ( ! HB ) + result = result + BreakStr; + l.erase( 1 - 1, P - 1 ); + Len = l.length( ); + } + return result; +} + +#ifdef windows +const Char sLineBreak[] = _T("\x0d\x0a"); +#elif defined (linux) +const Char sLineBreak[] = _T("\x0a"); +#else +#error unknown platform +#endif + +String WrapText( const String& Line, int MaxCol ) +{ + return WrapText( Line, sLineBreak, Sysutils__15, MaxCol ); +} + +#ifdef linux + +/* + case translation tables + can be used in internationalization support. + + Although These tables can be obtained through System calls +CD it is better to not use those, since most implementation are not 100% + Warning: + before modifying A translation Table make sure that the current CodePage + of the OS corresponds to the one you make changes to +*/ + /* upper case translation Table for character set 850 */ + + +Char CP850UCT [ 128/*# range 128..255*/ ]; +void CP850UCTInit( ) +{ + CP850UCT[0] = _T('\x80'); + CP850UCT[1] = _T('\x9a'); + CP850UCT[2] = _T('\x90'); + CP850UCT[3] = _T('\xb6'); + CP850UCT[4] = _T('\x8e'); + CP850UCT[5] = _T('\xb6'); + CP850UCT[6] = _T('\x8f'); + CP850UCT[7] = _T('\x80'); + CP850UCT[8] = _T('\xd2'); + CP850UCT[9] = _T('\xd3'); + CP850UCT[10] = _T('\xd4'); + CP850UCT[11] = _T('\xd8'); + CP850UCT[12] = _T('\xd7'); + CP850UCT[13] = _T('\xde'); + CP850UCT[14] = _T('\x8e'); + CP850UCT[15] = _T('\x8f'); + CP850UCT[16] = _T('\x90'); + CP850UCT[17] = _T('\x92'); + CP850UCT[18] = _T('\x92'); + CP850UCT[19] = _T('\xe2'); + CP850UCT[20] = _T('\x99'); + CP850UCT[21] = _T('\xe3'); + CP850UCT[22] = _T('\xea'); + CP850UCT[23] = _T('\xeb'); + CP850UCT[24] = _T('Y'); + CP850UCT[25] = _T('\x99'); + CP850UCT[26] = _T('\x9a'); + CP850UCT[27] = _T('\x9d'); + CP850UCT[28] = _T('\x9c'); + CP850UCT[29] = _T('\x9d'); + CP850UCT[30] = _T('\x9e'); + CP850UCT[31] = _T('\x9f'); + CP850UCT[32] = _T('\xb5'); + CP850UCT[33] = _T('\xd6'); + CP850UCT[34] = _T('\xe0'); + CP850UCT[35] = _T('\xe9'); + CP850UCT[36] = _T('\xa5'); + CP850UCT[37] = _T('\xa5'); + CP850UCT[38] = _T('\xa6'); + CP850UCT[39] = _T('\xa7'); + CP850UCT[40] = _T('\xa8'); + CP850UCT[41] = _T('\xa9'); + CP850UCT[42] = _T('\xaa'); + CP850UCT[43] = _T('\xab'); + CP850UCT[44] = _T('\xac'); + CP850UCT[45] = _T('\xad'); + CP850UCT[46] = _T('\xae'); + CP850UCT[47] = _T('\xaf'); + CP850UCT[48] = _T('\xb0'); + CP850UCT[49] = _T('\xb1'); + CP850UCT[50] = _T('\xb2'); + CP850UCT[51] = _T('\xb3'); + CP850UCT[52] = _T('\xb4'); + CP850UCT[53] = _T('\xb5'); + CP850UCT[54] = _T('\xb6'); + CP850UCT[55] = _T('\xb7'); + CP850UCT[56] = _T('\xb8'); + CP850UCT[57] = _T('\xb9'); + CP850UCT[58] = _T('\xba'); + CP850UCT[59] = _T('\xbb'); + CP850UCT[60] = _T('\xbc'); + CP850UCT[61] = _T('\xbd'); + CP850UCT[62] = _T('\xbe'); + CP850UCT[63] = _T('\xbf'); + CP850UCT[64] = _T('\xc0'); + CP850UCT[65] = _T('\xc1'); + CP850UCT[66] = _T('\xc2'); + CP850UCT[67] = _T('\xc3'); + CP850UCT[68] = _T('\xc4'); + CP850UCT[69] = _T('\xc5'); + CP850UCT[70] = _T('\xc7'); + CP850UCT[71] = _T('\xc7'); + CP850UCT[72] = _T('\xc8'); + CP850UCT[73] = _T('\xc9'); + CP850UCT[74] = _T('\xca'); + CP850UCT[75] = _T('\xcb'); + CP850UCT[76] = _T('\xcc'); + CP850UCT[77] = _T('\xcd'); + CP850UCT[78] = _T('\xce'); + CP850UCT[79] = _T('\xcf'); + CP850UCT[80] = _T('\xd0'); + CP850UCT[81] = _T('\xd1'); + CP850UCT[82] = _T('\xd2'); + CP850UCT[83] = _T('\xd3'); + CP850UCT[84] = _T('\xd4'); + CP850UCT[85] = _T('\xd5'); + CP850UCT[86] = _T('\xd6'); + CP850UCT[87] = _T('\xd7'); + CP850UCT[88] = _T('\xd8'); + CP850UCT[89] = _T('\xd9'); + CP850UCT[90] = _T('\xda'); + CP850UCT[91] = _T('\xdb'); + CP850UCT[92] = _T('\xdc'); + CP850UCT[93] = _T('\xdd'); + CP850UCT[94] = _T('\xde'); + CP850UCT[95] = _T('\xdf'); + CP850UCT[96] = _T('\xe0'); + CP850UCT[97] = _T('\xe1'); + CP850UCT[98] = _T('\xe2'); + CP850UCT[99] = _T('\xe3'); + CP850UCT[100] = _T('\xe5'); + CP850UCT[101] = _T('\xe5'); + CP850UCT[102] = _T('\xe6'); + CP850UCT[103] = _T('\xed'); + CP850UCT[104] = _T('\xe8'); + CP850UCT[105] = _T('\xe9'); + CP850UCT[106] = _T('\xea'); + CP850UCT[107] = _T('\xeb'); + CP850UCT[108] = _T('\xed'); + CP850UCT[109] = _T('\xed'); + CP850UCT[110] = _T('\xee'); + CP850UCT[111] = _T('\xef'); + CP850UCT[112] = _T('\xf0'); + CP850UCT[113] = _T('\xf1'); + CP850UCT[114] = _T('\xf2'); + CP850UCT[115] = _T('\xf3'); + CP850UCT[116] = _T('\xf4'); + CP850UCT[117] = _T('\xf5'); + CP850UCT[118] = _T('\xf6'); + CP850UCT[119] = _T('\xf7'); + CP850UCT[120] = _T('\xf8'); + CP850UCT[121] = _T('\xf9'); + CP850UCT[122] = _T('\xfa'); + CP850UCT[123] = _T('\xfb'); + CP850UCT[124] = _T('\xfc'); + CP850UCT[125] = _T('\xfd'); + CP850UCT[126] = _T('\xfe'); + CP850UCT[127] = _T('\xff'); +} + + /* lower case translation Table for character set 850 */ +Char CP850LCT [ 128/*# range 128..255*/ ]; +void CP850LCTInit( ) +{ + CP850LCT[0] = _T('\x87'); + CP850LCT[1] = _T('\x81'); + CP850LCT[2] = _T('\x82'); + CP850LCT[3] = _T('\x83'); + CP850LCT[4] = _T('\x84'); + CP850LCT[5] = _T('\x85'); + CP850LCT[6] = _T('\x86'); + CP850LCT[7] = _T('\x87'); + CP850LCT[8] = _T('\x88'); + CP850LCT[9] = _T('\x89'); + CP850LCT[10] = _T('\x8a'); + CP850LCT[11] = _T('\x8b'); + CP850LCT[12] = _T('\x8c'); + CP850LCT[13] = _T('\x8d'); + CP850LCT[14] = _T('\x84'); + CP850LCT[15] = _T('\x86'); + CP850LCT[16] = _T('\x82'); + CP850LCT[17] = _T('\x91'); + CP850LCT[18] = _T('\x91'); + CP850LCT[19] = _T('\x93'); + CP850LCT[20] = _T('\x94'); + CP850LCT[21] = _T('\x95'); + CP850LCT[22] = _T('\x96'); + CP850LCT[23] = _T('\x97'); + CP850LCT[24] = _T('\x98'); + CP850LCT[25] = _T('\x94'); + CP850LCT[26] = _T('\x81'); + CP850LCT[27] = _T('\x9b'); + CP850LCT[28] = _T('\x9c'); + CP850LCT[29] = _T('\x9b'); + CP850LCT[30] = _T('\x9e'); + CP850LCT[31] = _T('\x9f'); + CP850LCT[32] = _T('\xa0'); + CP850LCT[33] = _T('\xa1'); + CP850LCT[34] = _T('\xa2'); + CP850LCT[35] = _T('\xa3'); + CP850LCT[36] = _T('\xa4'); + CP850LCT[37] = _T('\xa4'); + CP850LCT[38] = _T('\xa6'); + CP850LCT[39] = _T('\xa7'); + CP850LCT[40] = _T('\xa8'); + CP850LCT[41] = _T('\xa9'); + CP850LCT[42] = _T('\xaa'); + CP850LCT[43] = _T('\xab'); + CP850LCT[44] = _T('\xac'); + CP850LCT[45] = _T('\xad'); + CP850LCT[46] = _T('\xae'); + CP850LCT[47] = _T('\xaf'); + CP850LCT[48] = _T('\xb0'); + CP850LCT[49] = _T('\xb1'); + CP850LCT[50] = _T('\xb2'); + CP850LCT[51] = _T('\xb3'); + CP850LCT[52] = _T('\xb4'); + CP850LCT[53] = _T('\xa0'); + CP850LCT[54] = _T('\x83'); + CP850LCT[55] = _T('\x85'); + CP850LCT[56] = _T('\xb8'); + CP850LCT[57] = _T('\xb9'); + CP850LCT[58] = _T('\xba'); + CP850LCT[59] = _T('\xbb'); + CP850LCT[60] = _T('\xbc'); + CP850LCT[61] = _T('\xbd'); + CP850LCT[62] = _T('\xbe'); + CP850LCT[63] = _T('\xbf'); + CP850LCT[64] = _T('\xc0'); + CP850LCT[65] = _T('\xc1'); + CP850LCT[66] = _T('\xc2'); + CP850LCT[67] = _T('\xc3'); + CP850LCT[68] = _T('\xc4'); + CP850LCT[69] = _T('\xc5'); + CP850LCT[70] = _T('\xc6'); + CP850LCT[71] = _T('\xc6'); + CP850LCT[72] = _T('\xc8'); + CP850LCT[73] = _T('\xc9'); + CP850LCT[74] = _T('\xca'); + CP850LCT[75] = _T('\xcb'); + CP850LCT[76] = _T('\xcc'); + CP850LCT[77] = _T('\xcd'); + CP850LCT[78] = _T('\xce'); + CP850LCT[79] = _T('\xcf'); + CP850LCT[80] = _T('\xd0'); + CP850LCT[81] = _T('\xd1'); + CP850LCT[82] = _T('\x88'); + CP850LCT[83] = _T('\x89'); + CP850LCT[84] = _T('\x8a'); + CP850LCT[85] = _T('\xd5'); + CP850LCT[86] = _T('\xa1'); + CP850LCT[87] = _T('\x8c'); + CP850LCT[88] = _T('\x8b'); + CP850LCT[89] = _T('\xd9'); + CP850LCT[90] = _T('\xda'); + CP850LCT[91] = _T('\xdb'); + CP850LCT[92] = _T('\xdc'); + CP850LCT[93] = _T('\xdd'); + CP850LCT[94] = _T('\x8d'); + CP850LCT[95] = _T('\xdf'); + CP850LCT[96] = _T('\xa2'); + CP850LCT[97] = _T('\xe1'); + CP850LCT[98] = _T('\x93'); + CP850LCT[99] = _T('\x95'); + CP850LCT[100] = _T('\xe4'); + CP850LCT[101] = _T('\xe4'); + CP850LCT[102] = _T('\xe6'); + CP850LCT[103] = _T('\xed'); + CP850LCT[104] = _T('\xe8'); + CP850LCT[105] = _T('\xa3'); + CP850LCT[106] = _T('\x96'); + CP850LCT[107] = _T('\x97'); + CP850LCT[108] = _T('\xec'); + CP850LCT[109] = _T('\xec'); + CP850LCT[110] = _T('\xee'); + CP850LCT[111] = _T('\xef'); + CP850LCT[112] = _T('\xf0'); + CP850LCT[113] = _T('\xf1'); + CP850LCT[114] = _T('\xf2'); + CP850LCT[115] = _T('\xf3'); + CP850LCT[116] = _T('\xf4'); + CP850LCT[117] = _T('\xf5'); + CP850LCT[118] = _T('\xf6'); + CP850LCT[119] = _T('\xf7'); + CP850LCT[120] = _T('\xf8'); + CP850LCT[121] = _T('\xf9'); + CP850LCT[122] = _T('\xfa'); + CP850LCT[123] = _T('\xfb'); + CP850LCT[124] = _T('\xfc'); + CP850LCT[125] = _T('\xfd'); + CP850LCT[126] = _T('\xfe'); + CP850LCT[127] = _T('\xff'); +} + + /* upper case translation Table for character set ISO 8859/1 Latin 1 */ +Char CPISO88591UCT [ 64/*# range 192..255*/ ]; +void CPISO88591UCTInit( ) +{ + CPISO88591UCT[0] = _T('\xc0'); + CPISO88591UCT[1] = _T('\xc1'); + CPISO88591UCT[2] = _T('\xc2'); + CPISO88591UCT[3] = _T('\xc3'); + CPISO88591UCT[4] = _T('\xc4'); + CPISO88591UCT[5] = _T('\xc5'); + CPISO88591UCT[6] = _T('\xc6'); + CPISO88591UCT[7] = _T('\xc7'); + CPISO88591UCT[8] = _T('\xc8'); + CPISO88591UCT[9] = _T('\xc9'); + CPISO88591UCT[10] = _T('\xca'); + CPISO88591UCT[11] = _T('\xcb'); + CPISO88591UCT[12] = _T('\xcc'); + CPISO88591UCT[13] = _T('\xcd'); + CPISO88591UCT[14] = _T('\xce'); + CPISO88591UCT[15] = _T('\xcf'); + CPISO88591UCT[16] = _T('\xd0'); + CPISO88591UCT[17] = _T('\xd1'); + CPISO88591UCT[18] = _T('\xd2'); + CPISO88591UCT[19] = _T('\xd3'); + CPISO88591UCT[20] = _T('\xd4'); + CPISO88591UCT[21] = _T('\xd5'); + CPISO88591UCT[22] = _T('\xd6'); + CPISO88591UCT[23] = _T('\xd7'); + CPISO88591UCT[24] = _T('\xd8'); + CPISO88591UCT[25] = _T('\xd9'); + CPISO88591UCT[26] = _T('\xda'); + CPISO88591UCT[27] = _T('\xdb'); + CPISO88591UCT[28] = _T('\xdc'); + CPISO88591UCT[29] = _T('\xdd'); + CPISO88591UCT[30] = _T('\xde'); + CPISO88591UCT[31] = _T('\xdf'); + CPISO88591UCT[32] = _T('\xc0'); + CPISO88591UCT[33] = _T('\xc1'); + CPISO88591UCT[34] = _T('\xc2'); + CPISO88591UCT[35] = _T('\xc3'); + CPISO88591UCT[36] = _T('\xc4'); + CPISO88591UCT[37] = _T('\xc5'); + CPISO88591UCT[38] = _T('\xc6'); + CPISO88591UCT[39] = _T('\xc7'); + CPISO88591UCT[40] = _T('\xc8'); + CPISO88591UCT[41] = _T('\xc9'); + CPISO88591UCT[42] = _T('\xca'); + CPISO88591UCT[43] = _T('\xcb'); + CPISO88591UCT[44] = _T('\xcc'); + CPISO88591UCT[45] = _T('\xcd'); + CPISO88591UCT[46] = _T('\xce'); + CPISO88591UCT[47] = _T('\xcf'); + CPISO88591UCT[48] = _T('\xd0'); + CPISO88591UCT[49] = _T('\xd1'); + CPISO88591UCT[50] = _T('\xd2'); + CPISO88591UCT[51] = _T('\xd3'); + CPISO88591UCT[52] = _T('\xd4'); + CPISO88591UCT[53] = _T('\xd5'); + CPISO88591UCT[54] = _T('\xd6'); + CPISO88591UCT[55] = _T('\xf7'); + CPISO88591UCT[56] = _T('\xd8'); + CPISO88591UCT[57] = _T('\xd9'); + CPISO88591UCT[58] = _T('\xda'); + CPISO88591UCT[59] = _T('\xdb'); + CPISO88591UCT[60] = _T('\xdc'); + CPISO88591UCT[61] = _T('\xdd'); + CPISO88591UCT[62] = _T('\xde'); + CPISO88591UCT[63] = _T('\x59'); +} + + /* lower case translation Table for character set ISO 8859/1 Latin 1 */ +Char CPISO88591LCT [ 64/*# range 192..255*/ ]; +void CPISO88591LCTInit( ) +{ + CPISO88591LCT[0] = _T('\xe0'); + CPISO88591LCT[1] = _T('\xe1'); + CPISO88591LCT[2] = _T('\xe2'); + CPISO88591LCT[3] = _T('\xe3'); + CPISO88591LCT[4] = _T('\xe4'); + CPISO88591LCT[5] = _T('\xe5'); + CPISO88591LCT[6] = _T('\xe6'); + CPISO88591LCT[7] = _T('\xe7'); + CPISO88591LCT[8] = _T('\xe8'); + CPISO88591LCT[9] = _T('\xe9'); + CPISO88591LCT[10] = _T('\xea'); + CPISO88591LCT[11] = _T('\xeb'); + CPISO88591LCT[12] = _T('\xec'); + CPISO88591LCT[13] = _T('\xed'); + CPISO88591LCT[14] = _T('\xee'); + CPISO88591LCT[15] = _T('\xef'); + CPISO88591LCT[16] = _T('\xf0'); + CPISO88591LCT[17] = _T('\xf1'); + CPISO88591LCT[18] = _T('\xf2'); + CPISO88591LCT[19] = _T('\xf3'); + CPISO88591LCT[20] = _T('\xf4'); + CPISO88591LCT[21] = _T('\xf5'); + CPISO88591LCT[22] = _T('\xf6'); + CPISO88591LCT[23] = _T('\xd7'); + CPISO88591LCT[24] = _T('\xf8'); + CPISO88591LCT[25] = _T('\xf9'); + CPISO88591LCT[26] = _T('\xfa'); + CPISO88591LCT[27] = _T('\xfb'); + CPISO88591LCT[28] = _T('\xfc'); + CPISO88591LCT[29] = _T('\xfd'); + CPISO88591LCT[30] = _T('\xfe'); + CPISO88591LCT[31] = _T('\xdf'); + CPISO88591LCT[32] = _T('\xe0'); + CPISO88591LCT[33] = _T('\xe1'); + CPISO88591LCT[34] = _T('\xe2'); + CPISO88591LCT[35] = _T('\xe3'); + CPISO88591LCT[36] = _T('\xe4'); + CPISO88591LCT[37] = _T('\xe5'); + CPISO88591LCT[38] = _T('\xe6'); + CPISO88591LCT[39] = _T('\xe7'); + CPISO88591LCT[40] = _T('\xe8'); + CPISO88591LCT[41] = _T('\xe9'); + CPISO88591LCT[42] = _T('\xea'); + CPISO88591LCT[43] = _T('\xeb'); + CPISO88591LCT[44] = _T('\xec'); + CPISO88591LCT[45] = _T('\xed'); + CPISO88591LCT[46] = _T('\xee'); + CPISO88591LCT[47] = _T('\xef'); + CPISO88591LCT[48] = _T('\xf0'); + CPISO88591LCT[49] = _T('\xf1'); + CPISO88591LCT[50] = _T('\xf2'); + CPISO88591LCT[51] = _T('\xf3'); + CPISO88591LCT[52] = _T('\xf4'); + CPISO88591LCT[53] = _T('\xf5'); + CPISO88591LCT[54] = _T('\xf6'); + CPISO88591LCT[55] = _T('\xf7'); + CPISO88591LCT[56] = _T('\xf8'); + CPISO88591LCT[57] = _T('\xf9'); + CPISO88591LCT[58] = _T('\xfa'); + CPISO88591LCT[59] = _T('\xfb'); + CPISO88591LCT[60] = _T('\xfc'); + CPISO88591LCT[61] = _T('\xfd'); + CPISO88591LCT[62] = _T('\xfe'); + CPISO88591LCT[63] = _T('\xff'); +} + +#endif + + +int GetInt( bool usigned, const String& S, const String& fmt, const void** pointers, int& pointers_maxidx, int& xResult, int& i, int& j, unsigned int& n, unsigned int& m, String& S1 ) +{ + int result = 0; + S1 = _T(""); + while ( ( S.length( ) > n ) && ( S[n - 1] == _T(' ')) ) + n++; + /* read sign */ + if ( ( S.length( ) >= n ) && ( Sysutils__16.Contains(S[n - 1] ) ) ) + { + /* don'T accept - when Reading unsigned */ + if ( usigned && ( S[n - 1] == _T('-')) ) + { + result = S1.length( ); + return result; + } + else + { + S1 = S1 + S[n - 1]; + n++; + } + } + /* read numbers */ + while ( ( S.length( ) >= n ) && ( Sysutils__17.Contains(S[n - 1] ) ) ) + { + S1 = S1 + S[n - 1]; + n++; + } + result = S1.length( ); + return result; +} + + +int GetFloat( const String& S, const String& fmt, const void** pointers, int& pointers_maxidx, int& xResult, int& i, int& j, unsigned int& n, unsigned int& m, String& S1 ) +{ + int result = 0; + S1 = _T(""); + while ( ( S.length( ) > n ) && ( S[n - 1] == _T(' ')) ) + n++; + while ( ( S.length( ) >= n ) && ( Sysutils__18.Contains(S[n - 1] ) ) ) + { + S1 = S1 + S[n - 1]; + n++; + } + result = S1.length( ); + return result; +} + + +int GetString( const String& S, const String& fmt, const void** pointers, int& pointers_maxidx, int& xResult, int& i, int& j, unsigned int& n, unsigned int& m, String& S1 ) +{ + int result = 0; + S1 = _T(""); + while ( ( S.length( ) > n ) && ( S[n - 1] == _T(' ')) ) + n++; + while ( ( S.length( ) >= n ) && ( S[n - 1] != _T(' ')) ) + { + S1 = S1 + S[n - 1]; + n++; + } + result = S1.length( ); + return result; +} + + +bool ScanStr( Char C, const String& S, const String& fmt, const void** pointers, int& pointers_maxidx, int& xResult, int& i, int& j, unsigned int& n, unsigned int& m, String& S1 ) +{ + bool result = false; + while ( ( S.length( ) > n ) && ( S[n - 1] != C ) ) + n++; + n++; + if ( n <= S.length( ) ) + result = true; + else + result = false; + return result; +} + + +int GetFmt( const String& S, const String& fmt, const void** pointers, int& pointers_maxidx, int& xResult, int& i, int& j, unsigned int& n, unsigned int& m, String& S1 ) +{ + int result = 0; + result = - 1; + while ( true ) + { + while ( ( fmt.length( ) > m ) && ( fmt[m - 1] == _T(' ')) ) + m++; + if ( m >= fmt.length( ) ) + break; + if ( fmt[m - 1] == _T('%')) + { + m++; + switch ( fmt[m - 1] ) + { + case _T('d'): + result = vtInteger; + break; + case _T('f'): + result = vtExtended; + break; + case _T('s'): + result = vtString; + break; + case _T('c'): + result = vtChar; + break; + default: + throw EFormatError( ErrorString(_T(SysConst_SInvalidFormat), fmt ) ); + } + m++; + break; + } + if ( ! ( ScanStr( fmt[m - 1], S, fmt, pointers, pointers_maxidx, xResult, i, j, n, m, S1 ) ) ) + break; + m++; + } + return result; +} + + +int SScanf( const String& S, const String& fmt, const void** pointers, int pointers_maxidx ) +{ + int result = 0; + int i = 0, j = 0; + unsigned int n = 0, m = 0; + String S1; + n = 1; + m = 1; + result = 0; + for ( i = 0; i <= pointers_maxidx /*# High(pointers) */; i++) + { + j = GetFmt(S, fmt, pointers, pointers_maxidx, result, i, j, n, m, S1); + switch ( j ) + { + case vtInteger: + { + if ( GetInt( false, S, fmt, pointers, pointers_maxidx, result, i, j, n, m, S1) > 0 ) + { + *((PLongint) pointers[i] ) = StrToInt( S1 ); + result++; + } + else + break; + } + break; + case vtChar: + { + if ( S.length( ) > n ) + { + *(Char*) ( pointers[i] ) = S[n - 1]; + n++; + result++; + } + else + break; + } + break; + case vtExtended: + { + if ( GetFloat(S, fmt, pointers, pointers_maxidx, result, i, j, n, m, S1) > 0 ) + { + *((PExtended) pointers[i] ) = StrToFloat( S1 ); + result++; + } + else + break; + } + break; + case vtString: + { + if ( GetString(S, fmt, pointers, pointers_maxidx, result, i, j, n, m, S1) > 0 ) + { + //*((PAnsiString) pointers[i] ) = S1; // todo ? + *((PString) pointers[i] ) = S1; // todo ? + result++; + } + else + break; + } + break; + default: + break; + } + } + return result; +} + + /* read PChar handling functions implementation */ + /* + ********************************************************************* + Copyright (C) 1997, 1998 Gertjan Schouten + + this program is Free Software; you can redistribute it and/or modify + it under the terms of the GNU general public License as published by + the Free Software Foundation; either version 2 of the License, or + (at Your option) Any later version. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. see the + GNU general public License for more details. + + you should have received A copy of the GNU general public License + along with this program; if not, write to the Free Software + Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ********************************************************************* + + System Utilities for Free pascal +*/ + +/* PChar functions */ + + + +typedef Char CharArray [ 1/*# range 0..0*/ ]; + +/* processor dependent part, shared withs Strings unit */ +/* + this File is part of the Free pascal Run time Library. + Copyright (C) 1999-2000 by the Free pascal development team + + processor dependent part of Strings.pp, that can be shared with + Sysutils unit. + + see the File copying.FPC, included in this distribution, + for details about the Copyright. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. + + ***********************************************************************/ + +/*$asmmode ATT*/ + +/* read generic String functions that are not implemented for the processor */ +/* + this File is part of the Free pascal Run time Library. + Copyright (C) 1999-2000 by Carl-Eric Codere, + member of the Free pascal development team. + + see the File copying.FPC, included in this distribution, + for details about the Copyright. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. + + ***********************************************************************/ + + +/* processor Independent part, shared with Strings unit */ +/* + this File is part of the Free pascal Run time Library. + Copyright (C) 1999-2000 by the Free pascal development team + + processor Independent part for Strings and Sysutils units + + see the File copying.FPC, included in this distribution, + for details about the Copyright. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. + + ***********************************************************************/ + + +unsigned int StrLen( char* P ) +{ + return strlen(P); +} + +unsigned int StrLen( wchar_t* P ) +{ + return wcslen(P); +} + +char* StrCopy( char* Dest, const char* Source ) +{ + return strcpy(Dest, Source); +} + +wchar_t* StrCopy( wchar_t* Dest, const wchar_t* Source ) +{ + return wcscpy(Dest, Source); +} + +wchar_t* StrLCopy( wchar_t* Dest, const wchar_t* Source, int MaxLen ) +{ + return wcsncpy(Dest, Source, MaxLen); +} + +char* StrLCopy( char* Dest, const char* Source, int MaxLen ) +{ + return strncpy(Dest, Source, MaxLen); +} + +wchar_t* StrECopy( wchar_t* Dest, const wchar_t* Source ) +{ + return StrEnd(wcscpy(Dest, Source)); +} + +char* StrECopy( char* Dest, const char* Source ) +{ + return StrEnd(strcpy(Dest, Source)); +} + +char* StrEnd( char* P ) +{ + return strchr(P, 0); +} + +wchar_t* StrEnd( wchar_t* P ) +{ + return wcschr(P, 0); +} + +wchar_t* StrCat( wchar_t* Dest, const wchar_t* Source ) +{ + return wcscat(Dest, Source); +} + +char* StrCat( char* Dest, const char* Source ) +{ + return strcat(Dest, Source); +} + +char* StrLCat( char* Dest, const char* Source, int l ) +{ + return strncat(Dest, Source, l); +} + +wchar_t* StrLCat( wchar_t* Dest, const wchar_t* Source, int l ) +{ + return wcsncat(Dest, Source, l); +} + +int StrComp( const char* Str1, const char* Str2 ) +{ + return strcmp(Str1, Str2); +} + +int StrComp( const wchar_t* Str1, const wchar_t* Str2 ) +{ + return wcscmp(Str1, Str2); +} + +int StrLComp( const char* Str1, const char* Str2, int l ) +{ + return strncmp(Str1, Str2, l); +} + +int StrLComp( const wchar_t* Str1, const wchar_t* Str2, int l ) +{ + return wcsncmp(Str1, Str2, l); +} + +int StrIComp( const char* Str1, const char* Str2 ) +{ +#ifdef windows + return _strcmpi(Str1, Str2); +#elif defined(linux) + return strcasecmp(Str1, Str2); +#else +#error unknown platform +#endif +} + +int StrIComp( const wchar_t* Str1, const wchar_t* Str2 ) +{ +#ifdef windows + return _wcsicmp(Str1, Str2); +#elif defined(linux) + return wcscasecmp(Str1, Str2); +#else +#error unknown platform +#endif +} + +int StrLIComp( const char* Str1, const char* Str2, int l ) +{ +#ifdef windows + return _strnicmp(Str1, Str2, l); +#elif defined(linux) + return strncasecmp(Str1, Str2, l); +#else +#error unknown platform +#endif +} + +int StrLIComp( const wchar_t* Str1, const wchar_t* Str2, int l ) +{ +#ifdef windows + return _wcsnicmp(Str1, Str2, l); +#elif defined(linux) + return wcsncasecmp(Str1, Str2, l); +#else +#error unknown platform +#endif +} + +char* StrMove( char* Dest, const char* Source ) +{ + return strcpy(Dest, Source); +} + +wchar_t* StrMove( wchar_t* Dest, const wchar_t* Source ) +{ + return wcscpy(Dest, Source); +} + +char* StrMove( char* Dest, const char* Source, int MaxLen ) +{ + return strncpy(Dest, Source, MaxLen); +} + +wchar_t* StrMove( wchar_t* Dest, const wchar_t* Source, int MaxLen ) +{ + return wcsncpy(Dest, Source, MaxLen); +} + +char* StrScan( char* P, char C ) +{ + return strchr(P,C); +} + +wchar_t* StrScan( wchar_t* P, wchar_t C ) +{ + return wcschr(P,C); +} + +char* StrRScan( char* P, char C ) +{ + return strrchr(P,C); +} + +wchar_t* StrRScan( wchar_t* P, wchar_t C ) +{ + return wcsrchr(P,C); +} + +Char* StrLower( Char* xP ) +{ + Char* P = xP; +#ifdef _WIDESTRING + while(*P != L'\0') + *P++ = towlower(*P); +#else + while(*P != '\0'){ + *P = tolower(*P); + ++(*P); + } +#endif + return xP; +} + +Char* StrUpper( Char* xP ) +{ + Char* P = xP; + #ifdef _WIDESTRING + while(*P != L'\0') + *P++ = towupper(*P); +#else + while(*P != '\0'){ + *P = toupper(*P); + ++(*P); + } +#endif + return xP; +} + + + +Char* StrPos( Char* Str1, Char* Str2 ) +{ + Char* result = NULL; + Char* P = NULL; + int lstr2 = 0; + result = NULL; + if ( ( Str1 == NULL ) || ( Str2 == NULL ) ) + return result; + P = StrScan( Str1, *Str2 ); + if ( P == NULL ) + return result; + lstr2 = StrLen( Str2 ); + while ( P != NULL ) + { + if ( StrLComp( P, Str2, lstr2 ) == 0 ) + { + result = P; + return result; + } + P++; + P = StrScan( P, *Str2 ); + } + return result; +} + + +/* StrPCopy copies the pascal String Source to Dest and returns Dest */ +//--------------------------------------------------------------------------- +char* StrPCopy( char* Dest, const string& Source ) +{ + strcpy(Dest, Source.c_str()); + return Dest; +} +//--------------------------------------------------------------------------- +wchar_t* StrPCopy( wchar_t* Dest, const wstring& Source ) +{ + wcscpy(Dest, Source.c_str()); + return Dest; +} + +/* StrPLCopy copies MaxLen or less characters from the pascal String + Source to Dest and returns Dest */ + + +Char* StrPLCopy( Char* Dest, const String& Source, SizeUInt MaxLen ) +{ + Char* result = NULL; + SizeUInt Count = 0; + result = Dest; + if ( ( result != NULL ) && ( MaxLen != 0 ) ) + { + Count = Source.length( ); + if ( Count > MaxLen ) + Count = MaxLen; + StrMove( Dest, Source.c_str(), Count ); + ((Char*) result )[Count] = _T('\x00'); /* Terminate ! */ + } + return result; +} + + + + +void InitInternationalGeneric( ) +{ + FillChar( &SysLocale, sizeof( SysLocale ), 0 ); +} + +int AnsiCompareFileName( const String& S1, const String& S2 ) +{ + int result = 0; + if ( FileNameCaseSensitive ) + result = AnsiCompareStr( S1, S2 ); // compare case sensitive + else + result = AnsiCompareText( S1, S2 ); // compare case insensitive. no MBCS yet. + return result; +} + + +bool SameFileName( const String& S1, const String& S2 ) +{ + return AnsiCompareFileName( S1, S2 ) == 0; +} + + +String AnsiLowerCaseFileName( const String& S ) +{ + return AnsiLowerCase( S ); // no Locale support or MBCS yet. +} + + +String AnsiUpperCaseFileName( const String& S ) +{ + return AnsiUpperCase( S ); // no Locale support or MBCS yet. +} + + +int AnsiPos( const String& Substr, const String& S ) +{ + return Pos( Substr, S ); // no MBCS yet. +} + + +Char* AnsiStrPos( Char* str, Char* Substr ) +{ + return StrPos( str, Substr ); +} + + +Char* AnsiStrRScan( Char* str, Char Chr ) +{ + return StrRScan( str, Chr ); +} + + +Char* AnsiStrScan( Char* str, Char Chr ) +{ + return StrScan( str, Chr ); +} + + + +/* --------------------------------------------------------------------- + environment variable Auxiliary routines + ---------------------------------------------------------------------*/ + + +int FPC_EnvCount = - 1; + + +int FPCCountEnvVar( char** ep ) +{ + int result = 0; + if ( FPC_EnvCount == - 1 ) + { + FPC_EnvCount = 0; + if ( ep != NULL ) + while ( *ep != NULL ) + { + FPC_EnvCount++; + ep++; + } + } + return FPC_EnvCount; +} + + +String FPCGetEnvVarFromP( PPChar ep, const String& EnvVar ) +{ + String result; + PPChar hp = NULL; + String lenvvar, hs; + int eqpos = 0; + lenvvar = UpperCase( EnvVar ); + hp = ep; + result = _T(""); + if ( hp != NULL ) + while (( *hp != NULL ) ) + { + hs = *hp; + eqpos = Pos( _T("="), hs ); +#ifdef _WIDESTRING + if ( wcscmp(UpperCase( hs.substr( 1 - 1, eqpos - 1 ) ).c_str(), lenvvar.c_str()) == 0 ) +#else + if ( strcmp(UpperCase( hs.substr( 1 - 1, eqpos - 1 ) ).c_str(), lenvvar.c_str() ) == 0 ) +#endif + { + result = hs.substr( eqpos + 1 - 1, hs.length( ) - eqpos ); + return result; + } + hp++; + } + return result; +} + + +string FPCGetEnvStrFromP( char** ep, int Index ) +{ + string result; + while (( *ep != NULL ) && ( Index > 1 ) ) + { + Index--; + ep++; + } + if (( *ep != NULL ) ) + result = *ep; + return result; +} + + +/* --------------------------------------------------------------------- + Application Name + ---------------------------------------------------------------------*/ + + +String VendorName( ) +{ + String result; + if (( OnGetVendorName != NULL ) ) + result = OnGetVendorName( ); + else + result = _T(""); + return result; +} + + +String applicationName( ) +{ + String result; + if (( OnGetApplicationName != NULL ) ) + result = OnGetApplicationName( ); + else + result = ChangeFileExt( ExtractFileName( ParamStr( 0 ) ), _T("")); + return result; +} + + +/* --------------------------------------------------------------------- + get TEMPORARY Directory Name + ---------------------------------------------------------------------*/ + +#ifdef windows +String GetTempDir( bool Global ) +{ + String result; + if (( OnGetTempDir != NULL ) ) + result = OnGetTempDir( Global ); + else + { + result = GetEnvironmentVariable( _T("TEMP")); + if ( result.empty()) + result = GetEnvironmentVariable( _T("TMP")); + } + if ( !result.empty()) + result = IncludeTrailingPathDelimiter( result ); + return result; +} +#elif defined(linux) +String GetTempDir( bool Global ) +{ + String result; + if (( OnGetTempDir != NULL ) ) + result = OnGetTempDir( Global ); + else + { + result = GetEnvironmentVariable( _T("TEMP") ); + if ( result.empty()) + result = GetEnvironmentVariable( _T("TMP") ); + if ( result.empty()) + result = _T("/tmp/"); // fallback. + } + if ( !result.empty()) + result = IncludeTrailingPathDelimiter( result ); + return result; +} +#else +#error unknown platform +#endif + +String GetTempDir( ) +{ + return GetTempDir( true ); +} + +/* --------------------------------------------------------------------- + get TEMPORARY File Name + ---------------------------------------------------------------------*/ + + +String GetTempFileName( const String& Dir, const String& prefix ) +{ + String result; + int i = 0; + String start; + if (( OnGetTempFile != NULL ) ) + result = OnGetTempFile( Dir, prefix ); + else + { + if ( Dir.empty()) + start = GetTempDir(); + else + start = IncludeTrailingPathDelimiter( Dir ); + if ( prefix.empty()) + start = start + _T("TMP"); + else + start = start + prefix; + i = 0; + do + { +// result = Format( "%s%.5d.tmp", ARRAYOFCONST(( start, i )) ); +#ifdef _WIDESTRING + wstringstream buf; +#else + stringstream buf; +#endif + buf << start << std::setprecision(5) << i << _T(".tmp"); + result = buf.str(); + i++; + } + while ( ! ( ! FileExists( result ) ) ); + } + return result; +} + + +String GetTempFileName( ) +{ + return GetTempFileName( _T(""), _T("")); +} + + + +DWORD GetTempFileName( Char* Dir, Char* prefix, DWORD uUnique, Char* TempFileName ) +{ + DWORD result = 0; + String P( prefix ), Buf; + int l = 0; + if ( uUnique != 0 ) + { + //P = P + Format( "%.4x", ARRAYOFCONST(( uUnique )) ); +#ifdef _WIDESTRING + wstringstream buf; +#else + stringstream buf; +#endif + buf << setprecision(4) << uUnique; + P += buf.str(); + } + Buf = GetTempFileName( Dir, P.c_str()); + l = Buf.length( ); + if ( l > 0 ) + memcpy( TempFileName, &Buf[1 - 1], (l + 1) * sizeof(Char) ); + if ( uUnique != 0 ) + result = uUnique; + else + result = 1; + return result; +} + + +void FreeAndNil( void*& Obj ) +{ + TObject* Temp = NULL; + Temp = ((TObject*) Obj ); + Obj = NULL; + delete Temp; +} + + + +/* --------------------------------------------------------------------- + Diskh functions, OS Independent. + ---------------------------------------------------------------------*/ + + +bool DoForceDirectories( const String& Dir, bool& xResult, EInOutError*& e, String& ADrv ) +{ + bool result = false; + String ADir; + String APath; + result = true; + ADir = ExcludeTrailingPathDelimiter( Dir ); + if ( ADir.empty()) + return result; + if ( ! DirectoryExists( ADir ) ) + { + APath = ExtractFilePath( ADir ); + //this can happen ON Windows if User Specifies Dir like \User\Name/test/ + //and would, if not Checked for, cause an INFINITE recusrsion and A stack overflow + if ( APath == ADir ) + result = false; + else + result = DoForceDirectories( APath, xResult, e, ADrv ); + if ( result ) + result = CreateDir( ADir ); + } + return result; +} + + +bool IsUncDrive( const String& DRV, const String& Dir, bool& xResult, EInOutError*& e, String& ADrv ) +{ + bool result = false; + result = ( DRV.length( ) > 2 ) && ( DRV[1 - 1] == PathDelim ) && ( DRV[2 - 1] == PathDelim ); + return result; +} + + +bool ForceDirectories( const String& Dir ) +{ + bool result = false; + EInOutError* e = NULL; + String ADrv; + result = false; + ADrv = ExtractFileDrive( Dir ); + if ( ( !ADrv.empty()) && ( ! DirectoryExists( ADrv ) ) && ( ! IsUncDrive( ADrv, Dir, result, e, ADrv ) ) ) + return result; + if ( Dir.empty()) + { + e = new EInOutError( _T(SysConst_SCannotCreateEmptyDir) ); + e->ErrorCode = 3; + throw e; + } + result = DoForceDirectories( SetDirSeparators( Dir ), result, e, ADrv ); + return result; +} + + +/* +HMODULE SafeLoadLibrary( const std::string& Filename, DWORD ErrorMode ) +{ + HMODULE result = 0; + try + { + result = 0; + } + catch(...) + { + throw; + } + return result; +} */ + +#ifdef windows + +// struct.inc +struct REMOTE_NAME_INFO { + LPTSTR lpUniversalName; + LPTSTR lpConnectionName; + LPTSTR lpRemainingPath; +}; + + +typedef REMOTE_NAME_INFO _REMOTE_NAME_INFO; +typedef REMOTE_NAME_INFO TREMOTENAMEINFO; +typedef REMOTE_NAME_INFO *PREMOTENAMEINFO; + +String ExpandUNCFileName( const String& Filename ) +/* returns empty String ON errors */ +{ + String result; + String S; + DWORD Size = 0; + DWORD rc = 0; + wchar_t* Buf = NULL; + S = ExpandFileName( Filename ); + S = S + _T("\x00"); + Size = MAX_PATH; + GetMem( Buf, Size * sizeof(Char) ); + try + {/* + rc = WNetGetUniversalName( S.c_str(), UNIVERSAL_NAME_INFO_LEVEL, Buf, &Size ); + if ( rc == ERROR_MORE_DATA ) + { + ReallocMem( Buf, Size * sizeof(Char) ); + rc = WNetGetUniversalName( S.c_str(), UNIVERSAL_NAME_INFO_LEVEL, Buf, &Size ); + } + if ( rc == NO_ERROR ) + result = ((PREMOTENAMEINFO) Buf )->lpUniversalName; + else + if ( rc == ERROR_NOT_CONNECTED ) + result = Filename; + else*/ + result = _T(""); + } + catch(...) + { + FreeMem( Buf ); + throw; + } + /*# finally begin */ + FreeMem( Buf ); + /*# finally end */ + return result; +} + + +/***************************************************************************** + File functions +*****************************************************************************/ + + + +THandle FileOpen( const String& Filename, int Mode ) +{ + THandle result = 0; + unsigned int AccessMode [ 3/*# range 0..2*/ ]; + AccessMode[0] = GENERIC_READ; + AccessMode[1] = GENERIC_WRITE; + AccessMode[2] = GENERIC_READ | GENERIC_WRITE; + int ShareMode [ 5/*# range 0..4*/ ]; + ShareMode[0] = 0; + ShareMode[1] = 0; + ShareMode[2] = FILE_SHARE_READ; + ShareMode[3] = FILE_SHARE_WRITE; + ShareMode[4] = FILE_SHARE_READ | FILE_SHARE_WRITE; + String fn; + fn = Filename + _T("\x00"); + result = CreateFile( &fn[1 - 1], ((DWORD) ( AccessMode[Mode & 3] ) ), ((DWORD) ( ShareMode[( Mode & 0xF0 ) >> 4] ) ), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 ); + //if Fail API return feInvalidHandle (INVALIDE_HANDLE=feInvalidHandle=-1) + return result; +} + + +THandle FileCreate( const String& Filename ) +{ + THandle result = 0; + String fn; + fn = Filename + _T("\x00"); + result = CreateFile( &fn[1 - 1], GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 ); + return result; +} + + +THandle FileCreate( const String& Filename, int Mode ) +{ + THandle result = 0; + result = FileCreate( Filename ); + return result; +} + + +int FileRead( THandle Handle, void* Buffer, int Count ) +{ + int result = 0; + DWORD RES = 0; + if ( ReadFile( Handle, Buffer, Count, &RES, NULL ) ) + result = RES; + else + result = - 1; + return result; +} + + +int FileWrite( THandle Handle, void* Buffer, int Count ) +{ + int result = 0; + DWORD RES = 0; + if ( WriteFile( Handle, Buffer, Count, &RES, NULL ) ) + result = RES; + else + result = - 1; + return result; +} + + +int FileSeek( THandle Handle, int FOffset, int Origin ) +{ + int result = 0; + result = ((int) SetFilePointer( Handle, FOffset, NULL, Origin ) ); + return result; +} + + +int64_t FileSeek( THandle Handle, int64_t FOffset, int Origin ) +{ + int64_t result = 0; + if (( SetFilePointerEx != NULL ) ) + { + LARGE_INTEGER li; + li.QuadPart = FOffset; + LARGE_INTEGER li2; + if ( ! ( SetFilePointerEx( Handle, li, &li2, Origin ) ) ) + result = - 1; + FOffset = li.QuadPart; + result = li2.QuadPart; + } + else + result = ((int) SetFilePointer( Handle, (long) FOffset, NULL, Origin ) ); + return result; +} + + +void FileClose( THandle Handle ) +{ + if ( Handle <= (THandle) 4 ) + return; + CloseHandle( Handle ); +} + + +// types.pp / Windef.h +typedef _FILETIME TFileTime; + + +BOOL DosToWinTime( int DTime, TFileTime& Wtime ) +{ + BOOL result = false; + TFileTime lft; + result = DosDateTimeToFileTime( ((LongRec*) &DTime )->Hi, ((LongRec*) &DTime )->Lo, &lft ) && LocalFileTimeToFileTime( &lft, &Wtime ); + return result; +} + + +BOOL WinToDosTime( TFileTime& Wtime, int& DTime ) +{ + BOOL result = false; + TFileTime lft; + result = FileTimeToLocalFileTime( &Wtime, &lft ) && FileTimeToDosDateTime( &lft, &((LongRec*) &DTime )->Hi, &((LongRec*) &DTime )->Lo ); + return result; +} + + +int FileAge( const String& Filename ) +{ + int result = 0; + THandle Handle = 0; + TWin32FindData FindData; + Handle = FindFirstFile( Filename.c_str(), &FindData ); + if ( Handle != INVALID_HANDLE_VALUE ) + { + ::FindClose( Handle ); + if ( ( ( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) == 0 ) + if ( WinToDosTime( FindData.ftLastWriteTime, result ) ) + return result; + } + result = - 1; + return result; +} + + +bool FileExists( const String& Filename ) +{ + bool result = false; + DWORD Attr = 0; + Attr = GetFileAttributes( Filename.c_str()); + if ( Attr != 0xFFFFFFFF ) + result = ( ( Attr & FILE_ATTRIBUTE_DIRECTORY ) ) == 0; + else + result = false; + return result; +} + + +bool DirectoryExists( const String& Directory ) +{ + bool result = false; + DWORD Attr = 0; + Attr = GetFileAttributes( Directory.c_str()); + if ( Attr != 0xFFFFFFFF ) + result = ( ( Attr & FILE_ATTRIBUTE_DIRECTORY ) ) > 0; + else + result = false; + return result; +} + + +int findmatch( TSearchRec& F ) +{ + int result = 0; + /* find File with correct attribute */ + while ( ( ( F.FindData.dwFileAttributes & ((unsigned int) F.ExcludeAttr ) ) ) != 0 ) + { + if ( ! FindNextFile( F.FindHandle, &F.FindData ) ) + { + result = GetLastError(); + return result; + } + } + /* convert some Attributes back */ + WinToDosTime( F.FindData.ftLastWriteTime, F.Time ); + F.Size = F.FindData.nFileSizeLow; + F.Attr = F.FindData.dwFileAttributes; + F.Name = F.FindData.cFileName; + return 0; +} + + +int FindFirst( const String& Path, int Attr, TSearchRec& Rslt ) +{ + int result = 0; + Rslt.Name = Path; + Rslt.Attr = Attr; + Rslt.ExcludeAttr = ( ~ Attr ) & ( 0x1e ); + /* $1e = faHidden or faSysFile or faVolumeID or faDirectory */ + /* FindFirstFile is A Win32 call */ + Rslt.FindHandle = FindFirstFile( Path.c_str(), &Rslt.FindData ); + if ( Rslt.FindHandle == INVALID_HANDLE_VALUE ) + { + result = GetLastError(); + return result; + } + /* find File with correct attribute */ + result = findmatch( Rslt ); + return result; +} + + +int FindNext( TSearchRec& Rslt ) +{ + int result = 0; + if ( FindNextFile( Rslt.FindHandle, &Rslt.FindData ) ) + result = findmatch( Rslt ); + else + result = GetLastError(); + return result; +} + + +void FindClose( TSearchRec& F ) +{ + if ( F.FindHandle != INVALID_HANDLE_VALUE ) + ::FindClose( F.FindHandle ); +} + + +int FileGetDate( THandle Handle ) +{ + int result = 0; + TFileTime ft; + if ( GetFileTime( Handle, NULL, NULL, &ft ) & WinToDosTime( ft, result ) ) + return result; + result = - 1; + return result; +} + + +int FileSetDate( THandle Handle, int Age ) +{ + int result = 0; + TFileTime ft; + result = 0; + if ( DosToWinTime( Age, ft ) & SetFileTime( Handle, NULL, NULL, &ft ) ) + return result; + result = GetLastError(); + return result; +} + + +int FileGetAttr( const String& Filename ) +{ + int result = 0; + result = GetFileAttributes( Filename.c_str()); + return result; +} + + +int FileSetAttr( const String& Filename, int Attr ) +{ + int result = 0; + if ( SetFileAttributes( Filename.c_str(), Attr ) ) + result = 0; + else + result = GetLastError(); + return result; +} + + +bool DeleteFile( const String& Filename ) +{ + return ::DeleteFile( Filename.c_str()) == TRUE; +} + + +bool RenameFile( const String& OldName, const String& newName ) +{ + return MoveFile( OldName.c_str(), newName.c_str()) == TRUE; +} + + +/***************************************************************************** + disk functions +*****************************************************************************/ + + +/* +#ifdef _WIDESTRING +typedef BOOL ( __stdcall * TGetDiskFreeSpaceEx )( wchar_t* , void* , void* , void* ); +#else +typedef BOOL ( __stdcall * TGetDiskFreeSpaceEx )( char* , void* , void* , void* ); +#endif + + +TGetDiskFreeSpaceEx GetDiskFreeSpaceEx; +*/ + +int64_t DiskFree( unsignedchar Drive ) +{ + int64_t result = 0; + Char disk[ 4/*# range 1..4*/ ]; + ULARGE_INTEGER qwtotal, qwfree, qwcaller; + if ( Drive == 0 ) + { + disk[1 - 1] = _T('\\'); + disk[2 - 1] = _T('\x00'); + } + else + { + disk[1 - 1] = Char( Drive + 64 ); + disk[2 - 1] = _T(':'); + disk[3 - 1] = _T('\\'); + disk[4 - 1] = _T('\x00'); + } + if ( GetDiskFreeSpaceEx( &disk[1 - 1], &qwcaller, &qwtotal, &qwfree ) ) + result = qwfree.QuadPart; + else + result = - 1; +/* } + else + { + DWORD secs = 0, Bytes = 0, Free = 0, total = 0; + if ( GetDiskFreeSpace( &disk[1 - 1], &secs, &Bytes, &Free, &total ) ) + result = ((int64_t) Free ) * secs * Bytes; + else + result = - 1; + }*/ + return result; +} + + +int64_t DiskSize( unsignedchar Drive ) +{ + int64_t result = 0; + Char disk[ 4/*# range 1..4*/ ]; + ULARGE_INTEGER qwtotal, qwfree, qwcaller; + if ( Drive == 0 ) + { + disk[1 - 1] = _T('\\'); + disk[2 - 1] = _T('\x00'); + } + else + { + disk[1 - 1] = Char( Drive + 64 ); + disk[2 - 1] = _T(':'); + disk[3 - 1] = _T('\\'); + disk[4 - 1] = _T('\x00'); + } + + if ( GetDiskFreeSpaceEx( &disk[1 - 1], &qwcaller, &qwtotal, &qwfree ) ) + result = qwtotal.QuadPart; + else + result = - 1; + return result; +} + + +String GetCurrentDir( ) +{ + String result; + GetDir( 0, result ); + return result; +} + + +bool SetCurrentDir( const String& newdir ) +{ + bool result = false; + result = SetCurrentDirectory( newdir.c_str()) == TRUE; + return result; +} + + +bool CreateDir( const String& newdir ) +{ + bool result = false; + result = CreateDirectory( newdir.c_str(), NULL ) == TRUE; + return result; +} + + +bool RemoveDir( const String& Dir ) +{ + return RemoveDirectory( Dir.c_str()) == TRUE; +} + +void SetString(std::string Str, char* myPtr, int size) +{ + +} + +/***************************************************************************** + Locale functions +*****************************************************************************/ + + +String GetLocaleStr( int lid, int LT, const String& def ) +{ + String result; + int l = 0; + Char Buf[ 256/*# range 0..255*/ ]; +#ifdef _WIDESTRING + l = GetLocaleInfoW( lid, LT, Buf, sizeof( Buf ) ); +#else + l = GetLocaleInfoA( lid, LT, Buf, sizeof( Buf ) ); +#endif + if ( l > 0 ) + SetString( result, &Buf[0], l - 1 ); + else + result = def; + return result; +} + + +Char GetLocaleChar( int lid, int LT, Char def ) +{ + Char Buf[ 2/*# range 0..1*/ ]; + if ( GetLocaleInfo( lid, LT, Buf, 2 ) > 0 ) + return Buf[0]; + else + return def; +} + + +int GetLocaleInt( int lid, int tp, int def ) +{ + int result = 0; + String S; + int C = 0; + S = GetLocaleStr( lid, tp, _T("0")); + Val( S, &result, C ); + if ( C != 0 ) + result = def; + return result; +} + + +void GetFormatSettings( ) +{ + String HF; + LCID lid = 0; + int i = 0, Day = 0; + lid = GetThreadLocale(); + /* Date stuff */ + for ( i = 1; i <= 12; i++) + { + ShortMonthNames[i - 1] = GetLocaleStr( lid, LOCALE_SABBREVMONTHNAME1 + i - 1, ShortMonthNames[i - 1] ); + LongMonthNames[i - 1] = GetLocaleStr( lid, LOCALE_SMONTHNAME1 + i - 1, LongMonthNames[i - 1] ); + } + for ( i = 1; i <= 7; i++) + { + Day = ( i + 5 ) % 7; + ShortDayNames[i - 1] = GetLocaleStr( lid, LOCALE_SABBREVDAYNAME1 + Day, ShortDayNames[i - 1] ); + LongDayNames[i - 1] = GetLocaleStr( lid, LOCALE_SDAYNAME1 + Day, LongDayNames[i - 1] ); + } + DateSeparator = GetLocaleChar( lid, LOCALE_SDATE, _T('/')); + ShortDateFormat = GetLocaleStr( lid, LOCALE_SSHORTDATE, _T("m/d/yy")); + LongDateFormat = GetLocaleStr( lid, LOCALE_SLONGDATE, _T("mmmm d, yyyy")); + /* time stuff */ + TimeSeparator = GetLocaleChar( lid, LOCALE_STIME, _T(':')); + TimeAMString = GetLocaleStr( lid, LOCALE_S1159, _T("AM")); + TimePMString = GetLocaleStr( lid, LOCALE_S2359, _T("PM")); + if ( StrToIntDef( GetLocaleStr( lid, LOCALE_ITLZERO, _T("0")), 0 ) == 0 ) + HF = _T("h"); + else + HF = _T("hh"); + // no support for 12 Hour stuff at the moment... + ShortTimeFormat = String( HF ) + _T(":mm"); //_T(":nn"); + LongTimeFormat = String( HF ) +_T(":mm:ss"); // _T(":nn:ss"); + /* Currency stuff */ + CurrencyString = GetLocaleStr( lid, LOCALE_SCURRENCY, _T("")); + CurrencyFormat = StrToIntDef( GetLocaleStr( lid, LOCALE_ICURRENCY, _T("0")), 0 ); + NegCurrFormat = StrToIntDef( GetLocaleStr( lid, LOCALE_INEGCURR, _T("0")), 0 ); + /* number stuff */ + ThousandSeparator = GetLocaleChar( lid, LOCALE_STHOUSAND, _T(',')); + DecimalSeparator = GetLocaleChar( lid, LOCALE_SDECIMAL, _T('.')); + CurrencyDecimals = StrToIntDef( GetLocaleStr( lid, LOCALE_ICURRDIGITS, _T("0")), 0 ); +} + + +void InitInternational( ) +{ + /* A call to GetSystemMetrics changes the Value of the 8087 Control WORD ON + Pentium4 with WINXP SP2 */ + WORD old8087CW = 0; + InitInternationalGeneric(); +// old8087CW = Get8087CW; + SysLocale.MBCS = GetSystemMetrics( SM_DBCSENABLED ) != 0; + SysLocale.RightToLeft = GetSystemMetrics( SM_MIDEASTENABLED ) != 0; + SysLocale.DefaultLCID = 0x0409; + SysLocale.PriLangID = LANG_ENGLISH; + SysLocale.SubLangID = SUBLANG_ENGLISH_US; + // probably needs Update with GetThreadLocale. post 2.0.2 +// todo Set8087CW( old8087CW ); + GetFormatSettings(); +} + + + + +//#ifdef windows + + +String GetEnvironmentVariable( const String& EnvVar ) +{ + String result; + String S; + int i = 0; + Char* hp = NULL,* P = NULL; + result = _T(""); + P = GetEnvironmentStrings(); + hp = P; + while ( *hp != _T('\x00')) + { + S = hp; + i = Pos( _T("="), S ); + if ( i > 0 && UpperCase( S.substr( 1 - 1, i - 1 ) ) == UpperCase( EnvVar ) ) + { + result = S.substr( i + 1 - 1, S.length( ) - i ); + break; + } + /* Next String entry*/ +#ifdef _WIDESTRING + hp = hp + wcslen( hp ) + 1; +#else + hp = hp + strlen( hp ) + 1; +#endif + } + FreeEnvironmentStrings( P ); + return result; +} + + +int GetEnvironmentVariableCount( ) +{ + int result = 0; + Char* hp = NULL,* P = NULL; + result = 0; + P = GetEnvironmentStrings(); + hp = P; + if ( hp != NULL ) + while ( *hp != _T('\x00')) + { + result++; +#ifdef _WIDESTRING + hp = hp + wcslen( hp ) + 1; +#else + hp = hp + strlen( hp ) + 1; +#endif + } + FreeEnvironmentStrings( P ); + return result; +} + + +String GetEnvironmentString( int Index ) +{ + String result; + Char* hp = NULL,* P = NULL; + result = _T(""); + P = GetEnvironmentStrings(); + hp = P; + if ( hp != NULL ) + { + while ( ( *hp != _T('\x00')) && ( Index > 1 ) ) + { + Index--; +#ifdef _WIDESTRING + hp = hp + wcslen( hp ) + 1; +#else + hp = hp + strlen( hp ) + 1; +#endif + } + if ( *hp != _T('\x00')) + result = hp; + } + FreeEnvironmentStrings( P ); + return result; +} + + + +int ExecuteProcess( const String& Path, const String& comline ) +{ + int result = 0; + STARTUPINFO SI; + PROCESS_INFORMATION pi; + THandle Proc = 0; + DWORD l = 0; + String commandLine; + EOSError* e = NULL; + FillChar( &SI, sizeof( SI ), 0 ); + SI.cb = sizeof( SI ); + SI.wShowWindow = 1; + /* always surround the Name of the Application by quotes + So that LONG filenames will always be accepted. but don'T + do it if there are Already Double quotes, since Win32 does not + like Double quotes which are duplicated! + */ + if ( Pos( _T("\""), Path ) == 0 ) + commandLine = String( _T("\"") ) + Path + _T("\""); + else + commandLine = Path; + if ( !comline.empty()) + commandLine = commandLine + _T(" ")+ comline + _T("\x00"); + else + commandLine = commandLine + _T("\x00"); + if ( ! CreateProcess( NULL, (Char*) commandLine.c_str(), NULL, NULL, false, 0x20, NULL, NULL, &SI, &pi ) ) + { + //e = new EOSError( _T(SysConst_SExecuteProcessFailed), ARRAYOFCONST( commandLine, (int) GetLastError() ) ); + String sError = _T("Failed to execute "); + sError += commandLine; + sError += _T(", error code: "); + sError += IntToStr(GetLastError()); + e = new EOSError( sError ); + e->ErrorCode = GetLastError(); + throw e; + } + Proc = pi.hProcess; + if ( WaitForSingleObject( Proc, ((DWORD) 0xFFFFFFFF ) ) != 0xFFFFFFFF ) + { + GetExitCodeProcess( Proc, &l ); + CloseHandle( Proc ); + CloseHandle( pi.hThread ); + result = l; + } + else + { + //e = new EOSError( _T(SysConst_SExecuteProcessFailed), ARRAYOFCONST( commandLine, (int) GetLastError() ) ); + String sError = _T("Failed to execute "); + sError += commandLine; + sError += _T(", error code: "); + sError += IntToStr(GetLastError()); + e = new EOSError( sError ); + e->ErrorCode = GetLastError(); + CloseHandle( Proc ); + CloseHandle( pi.hThread ); + throw e; + } + return result; +} + + +int ExecuteProcess( const String& Path, const String* comline, int comline_maxidx ) +{ + int result = 0; + String commandLine; + int i = 0; + commandLine = _T(""); + for ( i = 0; i <= comline_maxidx /*# High(comline) */; i++) + if ( Pos( _T(" "), comline[i] ) != 0 ) + commandLine = commandLine + _T(" ")+ _T("\"") + comline[i] + _T("\""); + else + commandLine = commandLine + _T(" ")+ comline[i]; + result = ExecuteProcess( Path, commandLine ); + return result; +} + + +#elif defined(linux) +String GetEnvironmentVariable( const String& EnvVar ) +{ + char* p; +#ifdef _WIDESTRING + string s = wstr2str(EnvVar); + p = getenv( s.c_str()); + if(p != NULL) + return str2wstr( p ); +#else + p = getenv( EnvVar.c_str()); + if(p != NULL) + return StrPas( p ); +#endif + else + return String(); +} + +char** envp = NULL; + +int GetEnvironmentVariableCount( ) +{ + return FPCCountEnvVar( envp ); +} + + +String GetEnvironmentString( int Index ) +{ +#ifdef _WIDESTRING + return str2wstr(FPCGetEnvStrFromP( envp, Index )); +#else + return FPCGetEnvStrFromP( envp, Index ); +#endif +} + +char** ArrayStringToPPchar( const string* S, int S_maxidx, int reserveentries ) // const ? +// extra allocate reserveentries PChar'S at the beginning (Default Param=0 After 1.0.X ?) +// Note: for Internal use by skilled programmers only +// if "S" goes out of scope in the Parent procedure, the Pointer is dangling. + +{ + char** P = NULL; + int i = 0; + if ( S_maxidx /*# High(S) */ < 0 /*# Low(S) */ ) + return NULL; + GetMem( P, sizeof( char* ) * ( S_maxidx /*# High(S) */ - 0 /*# Low(S) */ + reserveentries + 2 ) ); // one more for nil, one more + // for cmd + if ( P == NULL ) + { + return NULL; + } + for ( i = 0 /*# Low(S) */; i <= S_maxidx /*# High(S) */; i++) + P[i + reserveentries] = (char*) S[i].c_str(); + P[S_maxidx /*# High(S) */ + 1 + reserveentries] = NULL; + return P; +} + +/* +#define System__38 ( TSet < Char, 0, 255 >() \ + << Char ( _T(' ') ) << Char ( _T('\t') ) << Char ( _T('\n') ) ) +#define System__39 ( TSet < Char, 0, 255 >() \ + << Char ( 0 ) << Char ( _T('"') ) ) +#define System__40 ( TSet < Char, 0, 255 >() \ + << Char ( _T(' ') ) << Char ( 0 ) << Char ( _T('\t') ) << Char ( _T('\n') ) ) +#define System__41 ( TSet < Char, 0, 255 >() \ + << Char ( _T(' ') ) << Char ( _T('\t') ) << Char ( _T('\n') ) ) +#define System__42 ( TSet < Char, 0, 255 >() \ + << Char ( 0 ) << Char ( _T('"') ) ) +#define System__43 ( TSet < Char, 0, 255 >() \ + << Char ( _T(' ') ) << Char ( 0 ) << Char ( _T('\t') ) << Char ( _T('\n') ) ) + +*/ +#define System__38 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( ' ' ) << (unsigned char) ( '\t' ) << (unsigned char) ( '\n' ) ) +#define System__39 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( 0 ) << (unsigned char) ( '"' ) ) +#define System__40 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( ' ' ) << (unsigned char) ( 0 ) << (unsigned char) ( '\t' ) << (unsigned char) ( '\n' ) ) +#define System__41 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( ' ' ) << (unsigned char) ( '\t' ) << (unsigned char) ( '\n' ) ) +#define System__42 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( 0 ) << (unsigned char) ( '"' ) ) +#define System__43 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( ' ' ) << (unsigned char) ( 0 ) << (unsigned char) ( '\t' ) << (unsigned char) ( '\n' ) ) +char** StringToPPChar( char* S, int reserveentries ) +{ + char** result = NULL; + int i = 0, nr = 0; + char* Buf = NULL; + char** P = NULL; + Buf = S; + nr = 1; + while ( *Buf != _T('\x00') ) // Count nr of Args + { + while ( System__38.Contains(*Buf ) ) // Kill separators. + Buf++; + nr++; + if ( *Buf == _T('\"') ) // quotes argument? + { + Buf++; + while ( ! ( System__39.Contains(*Buf ) ) ) // then end of argument is end of String or Next Quote + Buf++; + if ( *Buf == _T('\"') ) // Skip Closing Quote. + Buf++; + } + else + { // else Std + while ( ! ( System__40.Contains(*Buf ) ) ) + Buf++; + } + } + GetMem( P, ( reserveentries + nr ) * sizeof( Char* ) ); + result = P; + if ( P == NULL ) + { + return result; + } + for ( i = 1; i <= reserveentries; i++) + P++; // Skip empty slots + Buf = S; + while ( *Buf != _T('\x00') ) + { + while ( System__41.Contains(*Buf ) ) // Kill separators. + { + *Buf = _T('\x00'); + Buf++; + } + if ( *Buf == _T('\"') ) // quotes argument? + { + Buf++; + *P = Buf; + P++; + *P = NULL; + while ( ! ( System__42.Contains(*Buf ) ) ) // then end of argument is end of String or Next Quote + Buf++; + if ( *Buf == _T('\"') ) // Skip Closing Quote. + { + *Buf = _T('\x00'); + Buf++; + } + } + else + { + *P = Buf; + P++; + *P = NULL; + while ( ! ( System__43.Contains(*Buf ) ) ) + Buf++; + } + } + return result; +} + +char** StringToPPChar( std::string& S, int reserveentries ) +/* + Create A PPChar to structure of pchars which are the Arguments specified + in the String S. especially usefull for creating an Argv for Exec-calls +*/ +{ + return StringToPPChar( (char*) S.c_str(), reserveentries ); +} + +cint FpExecV( const char* Path, char** Argv ) +{ + cint r = execve(Path, Argv, envp); + return r==-1 ? -errno : r; +} + +void Fpexit( int Status ) +{ + syscall(SYS_exit_group, Status); +} + +pid_t fpfork( ) +/* + this function issues the 'fork' System call. the program is duplicated in memory + and execution continues in Parent and Child process. + in the Parent process, fork returns the pid of the Child. in the Child process, + zero is returned. + A Negative Value indicates that an Error has occurred, the Error is returned in + LinuxError. +*/ +{ + pid_t r = fork(); + return r==-1 ? -errno : r; +} + +/******************************************************************************* + utility calls +*******************************************************************************/ + +enum TFSearchOption {NoCurrentDirectory, + CurrentDirectoryFirst, + CurrentDirectoryLast }; + +typedef struct stat Stat; + +bool FpS_ISDIR( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFDIR ); +} + + +string FSearch( const string& Path, string DirList, TFSearchOption CurrentDirStrategy ) +/* + searches for A File 'path' in the List of direcories in 'dirlist'. + returns an empty String if not found. wildcards are not allowed. + if DirList is empty, it is set to '.' + +this function tries to make FSearch use AnsiStrings, and decrease +stringhandling Overhead at the same Time. + +*/ +{ + string result; + string mydir, newdir; + cint p1 = 0; + Stat info; + cint i = 0, j = 0; + const char* P = NULL; + if ( CurrentDirStrategy == CurrentDirectoryFirst ) + DirList = string( ".:" ) + DirList; /*make sure current Dir is First to be searched.*/ + if ( CurrentDirStrategy == CurrentDirectoryLast ) + DirList = DirList + ":."; /*make sure current Dir is Last to be searched.*/ + +/*replace ':' and ';' with #0*/ + for ( p1 = 1; p1 <= DirList.length( ); p1++) + if ( ( DirList[p1 - 1] == ':' ) || ( DirList[p1 - 1] == ';' ) ) + DirList[p1 - 1] = '\x00'; + +/*Check for wildcards*/ + if ( ( Pos( "?", Path ) != 0 ) || ( Pos( "*", Path ) != 0 ) ) + result = ""; /*no wildcards allowed in These things.*/ + else + { + P = DirList.c_str(); + i = DirList.length( ); + j = 1; + do + { + mydir = P; + if ( ( mydir.length( ) > 0 ) && ( mydir[mydir.length( ) - 1] != '/' ) ) + mydir = mydir + "/"; + newdir = mydir + Path; + if ( ( stat( newdir.c_str(), &info ) >= 0 ) && ( ! FpS_ISDIR( info.st_mode ) ) ) + { + if ( Pos( "./", newdir ) == 1 ) + newdir.erase( 1 - 1, 2 ); + /*DOS strips OFF an Initial .\*/ + } + else + newdir = ""; + while ( ( j <= i ) && ( *P != '\x00' ) ) + { + j++; + P++; + } + if ( *P == '\x00') + P++; + } + while ( ! ( ( j >= i ) || ( newdir.length( ) > 0 ) ) ); + result = newdir; + } + return result; +} + + +string FSearch( const string& Path, string DirList ) +{ + return FSearch( Path, DirList, CurrentDirectoryFirst ); +} + +/******************************************************************************* + process related calls +*******************************************************************************/ + +/* most calls of waitpid do not Handle the result correctly, this funktion treats errors more correctly */ + + +cint fpexecve( const char* Path, char** Argv, char** envp ) +{ + cint r = execve(Path, Argv, envp); + return r==-1 ? -errno : r; +} + + +cint intFpExecVEMaybeP( const string& pathname, char** Args, char** MyEnv, bool SearchPath ) +// does an Execve, but still has to Handle P +// Execv Variants call this directly, Execl Variants indirectly via +// intfpexecl + +{ + cint result = 0; + string NewCmd; + string thepath; + if ( SearchPath && ( Pos( "/", pathname ) == 0 ) ) + { + // the above could be better. (Check if not escaped/quoted '/'S) ? + // (Jilles says this is ok) + // Stevens says only Search if NewCmd contains no '/' + // FSearch is not AnsiString clean yet. + + thepath = getenv( "PATH"); + if ( thepath.empty()) + thepath = "."; // FreeBSD uses _PATH_DEFPATH = /usr/bin:/bin + // but A quick Check showed that _PATH_DEFPATH + // varied from OS to OS + NewCmd = FSearch( pathname, thepath, NoCurrentDirectory ); + // FreeBSD libc keeps ON Trying till A File is successfully Run. + // Stevens says "try each Path prefix" + + // execp puts NewCmd here. + *Args = (char*) NewCmd.c_str(); + } + else + NewCmd = pathname; + // Repeat +// if SearchPath then Args^:=PChar(commandtorun) + result = fpexecve( NewCmd.c_str(), Args, MyEnv ); + +/* +// Code that if Exec fails due to permissions, tries to Run it with sh +// should we deallocate P ON Fail? -> no Fpexit is Run no matter What +// +*/ +// if intFpExecVEMaybeP=-1 then zoekvolgende File. +// until (Goexit) or SearchExit; + + +/* + if IntFpExec=-1 then + begin + Error:=fpgeterrno + case Error of + ESysE2BIG : exit(-1); + ESysELOOP, + : exit(-1); + +*/ + return result; +} + + + + +pid_t fpwaitpid( pid_t pid, cint* stat_loc, cint Options ) +/* + waits until A Child with pid pid exits, or returns if it is exited Already. + Any resources used by the Child are freed. + the exit Status is reported in the adress referred to by Status. it should + be A Longint. +*/ +{ + pid_t r = waitpid(pid, stat_loc, Options ); + return r==-1 ? -errno : r; +} + +cint intfpexecl( const string& pathname, const string* S, int S_maxidx, char** MyEnv, bool SearchPath ) +/* handles the array of AnsiString -> PPChar conversion. + Base for the the "l" Variants. +*/ +{ + cint result = 0; + char** P = NULL; + if ( pathname.empty()) + { + seterrno( ESysENOENT ); + return - 1; // errno? + } + P = ArrayStringToPPchar( S, S_maxidx, 1 ); + if ( P == NULL ) + { + GetMem( P, 2 * sizeof( Char* ) ); + if ( P == NULL ) + { + seterrno( ESysENOENT ); + return - 1; + } + P[1] = NULL; + } + *P = (char*) pathname.c_str(); + result = intFpExecVEMaybeP( pathname, P, MyEnv, SearchPath ); + // if we come here, no attempts were executed successfully. + FreeMem( P, -1 ); + return result; +} + + +cint FpExecLE( const string& pathname, const string* S, int S_maxidx, char** MyEnv ) +{ + return intfpexecl( pathname, S, S_maxidx, MyEnv, false ); +} + + +cint FpExecL( const string& pathname, const string* S, int S_maxidx ) +{ + return intfpexecl( pathname, S, S_maxidx, envp, false ); +} + + +cint FpExecLP( const string& pathname, const string* S, int S_maxidx ) +{ + return intfpexecl( pathname, S, S_maxidx, envp, true ); +} + + +cint FpExecLPE( const string& pathname, const string* S, int S_maxidx, char** env ) +{ + return intfpexecl( pathname, S, S_maxidx, env, true ); +} + + +cint FpExecV( const string& pathname, char** Args ) +{ + return intFpExecVEMaybeP( pathname, Args, envp, false ); +} + + +cint FpExecVP( const string& pathname, char** Args ) +{ + return intFpExecVEMaybeP( pathname, Args, envp, true ); +} + + +cint FpExecVPE( const string& pathname, char** Args, char** env ) +{ + return intFpExecVEMaybeP( pathname, Args, env, true ); +} + + + +/* most calls of waitpid do not Handle the result correctly, this funktion treats errors more correctly */ + + +cint WaitProcess( cint pid ) /* like waitpid(pid,@result,0) handling of signal interrupts (errno=EINTR), returning the ExitCode of process (>=0) or -Status if terminated*/ +{ + cint result = 0; + cint r = 0, S = 0; + S = 0x7F00; + do + { + r = fpwaitpid( pid, &S, 0 ); + if ( ( r == - 1 ) && ( geterrno() == ESysEINTR ) ) + r = 0; + } + while ( ! ( r != 0 ) ); + if ( ( r == - 1 ) || ( r == 0 ) ) // 0 is not A valid return and should never occur (it means Status Invalid when Using WNOHANG) + result = - 1; // return -1 to indicate an Error. fpwaitpid updated it. + else + { + if ( WIFEXITED( S ) ) + result = WEXITSTATUS( S ); + else + if ( S > 0 ) // until Now there is not use of the highest bit , but Check this for the future + result = - S; // normal case + else + result = S; // S<0 should not occur, but wie return also A negativ Value + } + return result; +} + + +int ExecuteProcess( const std::string& Path, const std::string& comline ) +{ + int result = 0; + int pid = 0; + EOSError* e = NULL; + std::string commandLine; + char** cmdline2 = NULL; + /* always surround the Name of the Application by quotes + So that LONG filenames will always be accepted. but don'T + do it if there are Already Double quotes! + */ + + // only place we still parse + cmdline2 = NULL; + if ( !comline.empty()) + { + commandLine = comline; + /* make an unique copy because StringToPPChar modifies the + String */ + //UniqueString( commandLine ); + cmdline2 = StringToPPChar( ( char*) commandLine.c_str(), 1 ); + *cmdline2 = (char*) Path.c_str(); + } + else + { + GetMem( cmdline2, 2 * sizeof( char* ) ); + *cmdline2 = (char*) Path.c_str(); + cmdline2[1] = NULL; + } + pid = fpfork(); + if ( pid == 0 ) + { + /*the Child does the Actual Exec, and then exits*/ + FpExecV( (char*) Path.c_str(), cmdline2 ); + /* if the Execve fails, we return an exitvalue of 127, to let it be known*/ + Fpexit( 127 ); + } + else + if ( pid == - 1 ) /*fork Failed*/ + { + //e = new EOSError( str2wstr(SysConst_SExecuteProcessFailed), ARRAYOFCONST(( Path, -1 )) ); + String sError = _T("Failed to execute "); +#ifdef _WIDESTRING + sError += str2wstr(Path); +#else + sError += Path; +#endif + e = new EOSError( sError ); + e->ErrorCode = - 1; + throw e; + } + + /* we're in the parent, let'S wait. */ + result = WaitProcess( pid ); // waitpid and result-convert + if ( !comline.empty()) + FreeMem( cmdline2, -1 ); + if ( ( result < 0 ) || ( result == 127 ) ) + { + //e = new EOSError( str2wstr(SysConst_SExecuteProcessFailed), ARRAYOFCONST(( Path, 0 )) ); + String sError = _T("Failed to execute "); +#ifdef _WIDESTRING + sError += str2wstr(Path); +#else + sError += Path; +#endif + e->ErrorCode = result; + throw e; + } + return result; +} + + +int ExecuteProcess( const string& Path, const string* comline, int comline_maxidx ) +{ + int result = 0; + int pid = 0; + EOSError* e = NULL; + pid = fpfork(); + if ( pid == 0 ) + { + /*the Child does the Actual Exec, and then exits*/ + FpExecL( Path, comline, comline_maxidx ); + /* if the Execve fails, we return an exitvalue of 127, to let it be known*/ + Fpexit( 127 ); + } + else + if ( pid == - 1 ) /*fork Failed*/ + { + //e = new EOSError( str2wstr(SysConst_SExecuteProcessFailed), ARRAYOFCONST(( Path, -1 )) ); + String sError = _T("Failed to execute "); +#ifdef _WIDESTRING + sError += str2wstr(Path); +#else + sError += Path; +#endif + e = new EOSError( sError ); + e->ErrorCode = - 1; + throw e; + } + + /* we're in the parent, let'S wait. */ + result = WaitProcess( pid ); // waitpid and result-convert + if ( ( result < 0 ) || ( result == 127 ) ) + { + //e = new EOSError( str2wstr(SysConst_SExecuteProcessFailed), ARRAYOFCONST(( Path, 0 )) ); + String sError = _T("Failed to execute "); +#ifdef _WIDESTRING + sError += str2wstr(Path); +#else + sError += Path; +#endif + e = new EOSError( sError ); + e->ErrorCode = result; + throw e; + } + return result; +} + +//typedef timespec* ptimespec; +typedef timespec TTimeSpec; + +void Sleep( unsignedint milliseconds ) +{ + TTimeSpec timeout, timeoutresult; + timeout.tv_sec = milliseconds / 1000; + timeout.tv_nsec = 1000 * 1000 * ( milliseconds % 1000 ); +// FpNanoSleep( &timeout, &timeoutresult ); + nanosleep( &timeout, &timeoutresult ); +} + + +TLibHandle LoadLibrary( string Name ) +{ + return ((TLibHandle) ((uintptr_t) dlopen( Name.c_str(), RTLD_LAZY ))); +} + +TLibHandle LoadLibrary( wstring Name ) +{ + string s = wstr2str(Name); + return LoadLibrary(s); +} + + + +void* GetProcedureAddress( TLibHandle lib, string ProcName ) +{ + return dlsym( (void*) lib, ProcName.c_str()); +} + +void* GetProcedureAddress( TLibHandle lib, wstring ProcName ) +{ + string s = wstr2str(ProcName); + return GetProcedureAddress(lib, s); +} + + + +bool UnloadLibrary( TLibHandle lib ) +{ + return dlclose( (void*) lib ) == 0; +} + + +bool FreeLibrary( TLibHandle lib ) +{ + return UnloadLibrary( lib ); +} + + +void* GetProcAddress( TLibHandle lib, string ProcName ) +{ + return GetProcedureAddress( lib, ProcName ); +} + +void* GetProcAddress( TLibHandle lib, wstring ProcName ) +{ + string s = wstr2str(ProcName); + return GetProcedureAddress(lib, s); +} + + + +TLibHandle SafeLoadLibrary( string Name ) +{ + TLibHandle result = 0; + WORD W = 0; +// W = Get8087CW(); + result = LoadLibrary( Name ); +// Set8087CW( W ); + return result; +} + +TLibHandle SafeLoadLibrary( wstring Name ) +{ + string s = wstr2str(Name); + return SafeLoadLibrary(s); +} + +#else +#error unknown platform +#endif + + +#ifdef windows +/***************************************************************************** + Target dependent WideString stuff +*****************************************************************************/ + + +PtrInt Win32CompareWideString( const std::wstring& S1, const std::wstring& S2 ) +{ + PtrInt result = 0; + SetLastError( 0 ); + result = CompareStringW( LOCALE_USER_DEFAULT, 0, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; + if ( GetLastError() != 0 ) + RaiseLastOSError(); + return result; +} + + +PtrInt Win32CompareTextWideString( const std::wstring& S1, const std::wstring& S2 ) +{ + PtrInt result = 0; + SetLastError( 0 ); + result = CompareStringW( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; + if ( GetLastError() != 0 ) + RaiseLastOSError(); + return result; +} + + +String Win32AnsiUpperCase( const String& S ) +{ + String result; + if ( S.length( ) > 0 ) + { + result = S; +// UniqueString( result ); + CharUpperBuff( (Char*) result.c_str(), result.length( ) ); + } + else + result = _T(""); + return result; +} + + +String Win32AnsiLowerCase( const String& S ) +{ + String result; + if ( S.length( ) > 0 ) + { + result = S; +// UniqueString( result ); + CharLowerBuff( (Char*) result.c_str(), result.length( ) ); + } + else + result = _T(""); + return result; +} + + +PtrInt Win32AnsiCompareStr( const String& S1, const String& S2 ) +{ + return CompareString( LOCALE_USER_DEFAULT, 0, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; +} + + +PtrInt Win32AnsiCompareText( const String& S1, const String& S2 ) +{ + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1.c_str(), S1.length( ), S2.c_str(), S2.length( ) ) - 2; +} + + +PtrInt Win32AnsiStrComp( Char* S1, Char* S2 ) +{ + return CompareString( LOCALE_USER_DEFAULT, 0, S1, - 1, S2, - 1 ) - 2; +} + + +PtrInt Win32AnsiStrIComp( Char* S1, Char* S2 ) +{ + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, - 1, S2, - 1 ) - 2; +} + + +PtrInt Win32AnsiStrLComp( Char* S1, Char* S2, PtrUInt MaxLen ) +{ + return CompareString( LOCALE_USER_DEFAULT, 0, S1, MaxLen, S2, MaxLen ) - 2; +} + + +PtrInt Win32AnsiStrLIComp( Char* S1, Char* S2, PtrUInt MaxLen ) +{ + return CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE, S1, MaxLen, S2, MaxLen ) - 2; +} + + +Char* Win32AnsiStrLower( Char* str ) +{ + CharLower( str ); + return str; +} + + +Char* Win32AnsiStrUpper( Char* str ) +{ + CharUpper( str ); + return str; +} + +THandle kernel32dll = 0; + + +void LoadVersionInfo( ) // and getfreespaceex +{ + OSVERSIONINFO VersionInfo; + kernel32dll = 0; + //GetDiskFreeSpaceEx = NULL; + VersionInfo.dwOSVersionInfoSize = sizeof( VersionInfo ); + GetVersionEx( &VersionInfo ); + Win32Platform = VersionInfo.dwPlatformId; + Win32MajorVersion = VersionInfo.dwMajorVersion; + Win32MinorVersion = VersionInfo.dwMinorVersion; + Win32BuildNumber = VersionInfo.dwBuildNumber; + Move( (void*) VersionInfo.szCSDVersion, &Win32CSDVersion[1], 128 ); + Win32CSDVersion.SetLength((unsigned char)( StrLen( (Char*) ( &VersionInfo.szCSDVersion[0] ) ) ) ); +} + +void Beep( ) +{ + MessageBeep( 0 ); +} + +String AdjustPath(const String& S) +{ + return S; +} + +#elif defined(linux) + + +void Beep( ) +{ + cout << "/a"; +} + + + +String ExpandUNCFileName( const String& Filename ) +{ + String result; + result = ExpandFileName( Filename ); + //!! here should follow Code to replace the Drive: part with UNC... + return result; +} + +/***************************************************************************** + File functions +*****************************************************************************/ + + +cint fpopen( const char* Path, cint Flags, mode_t Mode ) +{ + cint r = open(Path, Flags | O_LARGEFILE, Mode); + return r==-1 ? -errno : r; +} + +cint fpopen( string Path, cint Flags, mode_t Mode ) +{ + return fpopen( Path.c_str(), Flags, Mode ); +} + +cint fpopen( wstring Path, cint Flags, mode_t Mode ) +{ + string s = wstr2str(Path); + return fpopen( s, Flags, Mode ); +} + +cint fpopen( string Path, cint Flags ) +{ + return fpopen( Path, Flags, 438 ); +} + + +cint fpopen( wstring Path, cint Flags ) +{ + string s = wstr2str(Path); + return fpopen( s, Flags, 438 ); +} + + +cint fpclose( cint FD ) +{ + cint r = close(FD); + return r==-1 ? -errno : r; +} + + +off_t Fplseek( cint FD, off_t Offset, cint Whence ) +{ + return lseek(FD, Offset, Whence); +} + + +ssize_t fpRead( cint FD, char* Buf, size_t nBytes ) +{ + ssize_t r = read(FD, Buf, nBytes); + return r==-1 ? -errno : r; +} + + +ssize_t fpWrite( cint FD, const char* Buf, size_t nBytes ) +{ + ssize_t r = write(FD, Buf, nBytes); + return r==-1 ? -errno : r; +} + + +// d2c_in sysfiles too +cint Fpunlink( const char* Path ) +{ + cint r = unlink(Path); + return r==-1 ? -errno : r; +} + + +cint Fprename( const char* old, const char* NewPath ) +{ + cint r = rename(old, NewPath); + return r==-1 ? -errno : r; +} + +typedef struct stat Stat; + + +cint fpstat( const char* Path, Stat& Buf ) +{ + cint r = stat(Path, &Buf); + return r==-1 ? -errno : r; +} + +/****************************************************************************** + --- Directory:Directory related calls --- +******************************************************************************/ + + +void FSplit( const PathStr Path, dirstr& Dir, NameStr& Name, extstr& Ext ) +{ + int DotPos = 0, slashPos = 0, i = 0; + slashPos = 0; + DotPos = 256; + i = Path.length( ); + while ( ( i > 0 ) && ( slashPos == 0 ) ) + { + if ( ( DotPos == 256 ) && ( Path[i - 1] == _T('.') ) ) + { + DotPos = i; + } + if ( Path[i - 1] == _T('/') ) + slashPos = i; + i--; + } + Ext = Path.substr( DotPos - 1, 255 ); + Dir = Path.substr( 1 - 1, slashPos ); + Name = Path.substr( slashPos + 1 - 1, DotPos - slashPos - 1 ); +} + + +uintptr_t FileOpen( const string& Filename, int Mode ) +{ + int result = 0; + int LinuxFlags = 0; + LinuxFlags = 0; + switch ( Mode & 3 ) + { + case 0: + LinuxFlags = LinuxFlags | O_RDONLY; + break; + case 1: + LinuxFlags = LinuxFlags | O_WRONLY; + break; + case 2: + LinuxFlags = LinuxFlags | O_RDWR; + break; + } + result = fpopen( Filename.c_str(), LinuxFlags ); + //!! we need to set Locking based ON Mode !! + return result; +} + +uintptr_t FileOpen( const wstring& Filename, int Mode ) +{ + string s = wstr2str(Filename); + return FileOpen(s, Mode); +} + +THandle FileCreate( const string& Filename ) +{ + return fpopen( Filename.c_str(), O_RDWR | O_CREAT | O_TRUNC ); +} + + +THandle FileCreate( const string& Filename, int Mode ) +{ + return fpopen( Filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, Mode ); +} + +THandle FileCreate( const wstring& Filename ) +{ + string s = wstr2str(Filename); + return FileCreate(s); +} + + +THandle FileCreate( const wstring& Filename, int Mode ) +{ + string s = wstr2str(Filename); + return FileCreate(s, Mode); +} + + +int FileRead( int Handle, void* Buffer, int Count ) +{ + return fpRead( Handle, (char*) Buffer, Count ); +} + + +int FileWrite( int Handle, const void* Buffer, int Count ) +{ + return fpWrite( Handle, (const char*) Buffer, Count ); +} + +int64_t FileSeek( int Handle, int64_t FOffset, int Origin ) +{ + return Fplseek( Handle, FOffset, Origin ); +} + + +void FileClose( int Handle ) +{ + fpclose( Handle ); +} + +cint Fpftruncate( cint FD, off_t flength ) +/* see Notes lseek. this one is completely Similar for the Parameter (but +doesn'T have the ReturnValue 64-bit problem)*/ +{ + cint r = ftruncate(FD, flength); + return r==-1 ? -errno : r; +} + + +int UnixToWinAge( time_t UnixAge ) +{ + int result = 0; + WORD Y = 0, m = 0, D = 0, hh = 0, mm = 0, SS = 0; + EpochToLocal( UnixAge, Y, m, D, hh, mm, SS ); + result = DateTimeToFileDate( EncodeDate( Y, m, D ) + EncodeTime( hh, mm, SS, 0 ) ); + return result; +} + + +int FileAge( const string& Filename ) +{ + int result = 0; + Stat info; + if ( fpstat( (char*) Filename.c_str(), info ) < 0 ) + return - 1; + else + result = UnixToWinAge( info.st_mtime ); + return result; +} + +int FileAge( const wstring& Filename ) +{ + string s = wstr2str(Filename); + return FileAge(s); +} + +cint Fpaccess( const char* pathname, cint AMode ) +/* + test users access Rights ON the specified File. + Mode is A Mask xosisting of one or more of R_OK, W_OK, X_OK, F_OK. + r,W,X stAnd for read,write and execute access, simultaneously. + F_OK checks whether the test would be allowed ON the File. + i.e. it checks the Search permissions in all Directory components + of the Path. + the test is done with the real User-id, instead of the effective. + if access is denied, or an Error occurred, False is returned. + if access is granted, True is returned. + errors other than no access,are reported in unixerror. +*/ +{ + cint r = access(pathname, AMode); + return r==-1 ? -errno : r; +} + +String AdjustPath(const String &S) +{ + string res = S; + for (auto &ch: res) + { + if (ch == '\\') + { + ch = '/'; + } + } + return res; +} + +bool FileExists( const string& Filename ) +{ + // don'T use Stat. it fails ON files >2 GB. + // access obeys the same access rules, So the result should be the same. + return Fpaccess( (char*) AdjustPath(Filename).c_str(), F_OK ) == 0; +} + +bool FileExists( const wstring& Filename ) +{ + string s = wstr2str(Filename); + // don'T use Stat. it fails ON files >2 GB. + // access obeys the same access rules, So the result should be the same. + return FileExists( s ); +} + +/* +bool FpS_ISDIR( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFDIR ); +}*/ + +bool DirectoryExists( const string& Directory ) +{ + Stat info; + return ( fpstat( (char*) AdjustPath(Directory).c_str(), info ) >= 0 ) && FpS_ISDIR( info.st_mode ); +} + +bool DirectoryExists( const wstring& Directory ) +{ + Stat info; + string s = wstr2str(Directory); + return DirectoryExists(s); +} + + +bool FpS_ISCHR( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFCHR ); +} + + +bool FpS_ISBLK( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFBLK ); +} + + +bool FpS_ISREG( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFREG ); +} + + +bool FpS_ISFIFO( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFIFO ); +} + + +bool FPS_ISLNK( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFLNK ); +} + + +bool FPS_ISSOCK( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFSOCK ); +} + +/* +bool WIFEXITED( cint Status ) +{ + bool result = false; + result = ( ( Status & 0x7F ) ) == 0; + return result; +} + + +cint WEXITSTATUS( cint Status ) +{ + cint result = 0; + result = ( Status & 0xFF00 ) >> 8; + return result; +} + + +cint WSTOPSIG( cint Status ) +{ + cint result = 0; + result = ( Status & 0xFF00 ) >> 8; + return result; +} + + +const int wstopped = 127; + + +bool WIFSIGNALED( cint Status ) +{ + bool result = false; + result = ( ( ( Status & 0xFF ) ) != wstopped ) && ( ( ( Status & 127 ) ) != 0 ); + return result; +} + + +cint WTERMSIG( cint Status ) +{ + cint result = 0; + result = ((cint) ( Status & 127 ) ); + return result; +} +*/ +int LinuxToWinAttr( char* fn, const Stat& info ) +{ + int result = 0; + string FNL; + Stat LinkInfo; + result = faArchive; + if ( FpS_ISDIR( info.st_mode ) ) + result = result | faDirectory; + if ( ( fn[0] == '.' ) && ( ! ( fn[1] == '\'' || fn[1] == '"') ) ) + result = result | faHidden; + if ( ( ( info.st_mode & S_IWUSR ) ) == 0 ) + result = result | faReadOnly; + if ( FPS_ISSOCK( info.st_mode ) || FpS_ISBLK( info.st_mode ) || FpS_ISCHR( info.st_mode ) || FpS_ISFIFO( info.st_mode ) ) + result = result | faSysFile; + if ( FPS_ISLNK( info.st_mode ) ) + { + result = result | faSymLink; + // Windows reports if the link Points to A Directory. + FNL = StrPas( fn ); + if ( ( fpstat( (char*) FNL.c_str(), LinkInfo ) >= 0 ) && FpS_ISDIR( LinkInfo.st_mode ) ) + result = result | faDirectory; + } + return result; +} + + +bool DoFNMatch( int i, int j, const string& pattern, const string& Name, bool& xResult, int& LenPat, int& LenName ) +{ + bool result = false; + bool found = false; + found = true; + while ( found && ( i <= LenPat ) ) + { + switch ( pattern[i - 1] ) + { + case '?': + found = ( j <= LenName ); + break; + case '*': + { + /*find the Next character in pattern, different of ? and **/ + while ( found ) + { + i++; + if ( i > LenPat ) + break; + switch ( pattern[i - 1] ) + { + case '*': + break; + case '?': + { + if ( j > LenName ) + { + result = false; + return result; + } + j++; + } + break; + default: + found = false; + } + } + Assert( ( i > LenPat ) || ( ( pattern[i - 1] != '*' ) && ( pattern[i - 1] != '?' ) ) ); + /*Now, find in Name the character which i Points to, if the * or ? + wasn'T the Last character in the pattern, else, use UP all the + Chars in Name*/ + found = false; + if ( i <= LenPat ) + { + do + { + /*find A Letter (not only First !) which maches pattern[i]*/ + while ( ( j <= LenName ) && ( Name[j - 1] != pattern[i - 1] ) ) + j++; + if ( j < LenName ) + { + if ( DoFNMatch( i + 1, j + 1, pattern, Name, xResult, LenPat, LenName ) ) + { + i = LenPat; + j = LenName;/*we can Stop*/ + found = true; + break; + } + else + j++;/*we didn'T find one, need to look further*/ + } + else + if ( j == LenName ) + { + found = true; + break; + } + /* this 'until' condition must be j>LenName, not j>=LenName. + that's because when we 'need to look further' and + j = LenName then loop must not Terminate. */ + } + while ( ! ( j > LenName ) ); + } + else + { + j = LenName;/*we can Stop*/ + found = true; + } + } + break; + default: /*not A WildCard character in pattern*/ + found = ( j <= LenName ) && ( pattern[i - 1] == Name[j - 1] ); + } + i++; + j++; + } + result = found && ( j > LenName ); + return result; +} + + +bool FNMatch( const string& pattern, const string& Name ) +{ + bool result = false; + int LenPat = 0, LenName = 0; /*start FNMatch*/ + LenPat = pattern.length( ); + LenName = Name.length( ); + return DoFNMatch( 1, 1, pattern, Name, result, LenPat, LenName ); +} + + + +struct TUnixFindData { + int NamePos; /*to track which Search this is*/ + void* DirPtr; /*Directory Pointer for Reading Directory*/ + string SearchSpec; + unsigned char SearchType; /*0=normal, 1=Open will Close, 2=only 1 File*/ + unsigned char SearchAttr; /*attribute we are searching for*/ +}; + + +typedef TUnixFindData* PUnixFindData; + + +int CurrSearchNum = 0; + + +void FindClose( TSearchRec& F ) +{ + PUnixFindData UnixFindData = NULL; + UnixFindData = ((PUnixFindData) F.FindHandle ); + if ( UnixFindData == NULL ) + return; + if ( UnixFindData->SearchType == 0 ) + { + if ( UnixFindData->DirPtr != NULL ) + Fpclosedir( ((Dir*) UnixFindData->DirPtr ) ); + } + delete UnixFindData; + F.FindHandle = NULL; +} + +typedef Stat* Pstat; + +cint fpLstat( const char* Path, Pstat info ) +/* + get all information ON A link (the link itself), and return it in info. +*/ +{ + cint r = lstat(Path, info); + return r==-1 ? -errno : r; +} + +bool FindGetFileInfo( const string& S, TSearchRec& F ) +{ + bool result = false; + Stat st; + int WinAttr = 0; + result = false; + if (( F.FindHandle != NULL ) && ( ( ( ( ( ((PUnixFindData) F.FindHandle )->SearchAttr ) ) & faSymLink ) ) > 0 ) ) + result = ( fpLstat( (char*) S.c_str(), &st ) == 0 ); + else + result = ( fpstat( (char*) S.c_str(), st ) == 0 ); + if ( ! &FindGetFileInfo ) + return result; + WinAttr = LinuxToWinAttr( (char*) S.c_str(), st ); + if ( ( F.FindHandle == NULL ) || ( ( ( WinAttr & ~ ( ((PUnixFindData) F.FindHandle )->SearchAttr ) ) ) == 0 ) ) + { +#ifdef _WIDESTRING + F.Name = ExtractFileName( str2wstr(S) ); +#else + F.Name = ExtractFileName( S ); +#endif + F.Attr = WinAttr; + F.Size = st.st_size; + F.Mode = st.st_mode; + F.Time = UnixToWinAge( st.st_mtime ); + result = true; + } + return result; +} + + +int FindNext( TSearchRec& Rslt ) +/* + re-opens Dir if not Already in array and calls FindGetFileInfo +*/ +{ + int result = 0; + string DirName; + string FName, SName; + bool found = false, Finished = false; + dirent* P = NULL; + PUnixFindData UnixFindData = NULL; + result = - 1; + UnixFindData = ((PUnixFindData) Rslt.FindHandle ); + if ( UnixFindData == NULL ) + return result; + if ( ( UnixFindData->SearchType == 0 ) && ( UnixFindData->DirPtr == NULL ) ) + { + if ( UnixFindData->NamePos == 0 ) + DirName = "./"; + else + DirName = UnixFindData->SearchSpec.substr( 1 - 1, UnixFindData->NamePos ); + UnixFindData->DirPtr = Fpopendir( DirName.c_str() ); + } + SName = UnixFindData->SearchSpec.substr( UnixFindData->NamePos + 1 - 1, UnixFindData->SearchSpec.length( ) ); + found = false; + Finished = ( UnixFindData->DirPtr == NULL ); + while ( ! Finished ) + { + P = Fpreaddir( ((Dir*) UnixFindData->DirPtr ) ); + if ( P == NULL ) + FName = ""; + else + FName = P->d_name; + if ( FName.empty()) + Finished = true; + else + { + if ( FNMatch( SName, FName ) ) + { + found = FindGetFileInfo( UnixFindData->SearchSpec.substr( 1 - 1, UnixFindData->NamePos ) + FName, Rslt ); + if ( found ) + { + result = 0; + return result; + } + } + } + } + return result; +} + + +int FindFirst( const String& Path, int Attr, TSearchRec& Rslt ) +/* + opens Dir and calls FindNext if needed. +*/ +{ + int result = 0; + PUnixFindData UnixFindData = NULL; + result = - 1; + //FillChar( &Rslt, sizeof( Rslt ), 0 ); + Rslt.Time = 0; + Rslt.Size = 0; + Rslt.Attr = 0; + Rslt.Name.clear(); + Rslt.ExcludeAttr = 0; + #ifdef unix + Rslt.FindHandle = 0; + Rslt.Mode = 0; + Rslt.PathOnly.clear(); + #else + Rslt.FindHandle = 0; + #endif + + if ( Path.empty()) + return result; + /*wildcards?*/ + if ( ( Pos( _T("?"), Path ) == 0 ) && ( Pos( _T("*"), Path ) == 0 ) ) + { +#ifdef _WIDESTRING + if ( FindGetFileInfo( wstr2str(Path), Rslt ) ) +#else + if ( FindGetFileInfo( Path, Rslt ) ) +#endif + result = 0; + } + else + { + /* allocate UnixFindData */ + UnixFindData = new TUnixFindData; + //FillChar( UnixFindData, sizeof( *UnixFindData ), 0 ); + UnixFindData->NamePos = 0; + UnixFindData->DirPtr = NULL; + UnixFindData->SearchType = '\0'; + UnixFindData->SearchAttr = '\0'; + + Rslt.FindHandle = UnixFindData; + /*Create info*/ +#ifdef _WIDESTRING + UnixFindData->SearchSpec = wstr2str(Path); +#else + UnixFindData->SearchSpec = Path; +#endif + /*we always also Search for ReadOnly and archive, regardless of Attr:*/ + UnixFindData->SearchAttr = Attr | faArchive | faReadOnly; + UnixFindData->NamePos = UnixFindData->SearchSpec.length( ); + while ( ( UnixFindData->NamePos > 0 ) && ( UnixFindData->SearchSpec[UnixFindData->NamePos - 1] != '/' ) ) + UnixFindData->NamePos--; + result = FindNext( Rslt ); + } + return result; +} + +cint fpfstat( cint FD, Stat& sb ) +{ + cint r = fstat(FD, &sb); + return r==-1 ? -errno : r; +} + + +int FileGetDate( int Handle ) +{ + int result = 0; + Stat info; + if ( ( fpfstat( Handle, info ) ) < 0 ) + result = - 1; + else + result = info.st_mtime; + return result; +} + + +int FileSetDate( int Handle, int Age ) +{ + int result = 0; + // impossible under LINUX from FileHandle !! + result = - 1; + return result; +} + + +int FileGetAttr( const string& Filename ) +{ + int result = 0; + Stat info; + if ( fpstat( (char*) Filename.c_str(), info ) < 0 ) + result = - 1; + else + { + string Sysutils__28( ExtractFileName( Filename ) ); + result = LinuxToWinAttr( (char*) Sysutils__28.c_str(), info ); + } + return result; +} + +int FileGetAttr( const wstring& Filename ) +{ + string s = wstr2str(Filename); + return FileGetAttr(s); +} + + + +int FileSetAttr( const string& Filename, int Attr ) +{ + int result = 0; + result = - 1; + return result; +} + +int FileSetAttr( const wstring& Filename, int Attr ) +{ + string s = wstr2str(Filename); + return FileSetAttr(s, Attr); +} + + +bool DeleteFile( const string& Filename ) +{ + return Fpunlink( Filename.c_str()) >= 0; +} + +bool DeleteFile( const wstring& Filename ) +{ + string s = wstr2str(Filename); + return DeleteFile(s); +} + +bool RenameFile( const string& OldName, const string& newName ) +{ + return Fprename( OldName.c_str(), newName.c_str()) >= 0; +} + +bool RenameFile( const wstring& OldName, const wstring& newName ) +{ + string sOld = wstr2str(OldName); + string sNew = wstr2str(newName); + return RenameFile( sOld, sNew); +} + + +bool FileIsReadOnly( const string& Filename ) +{ + return Fpaccess( Filename.c_str(), W_OK ) != 0; +} + +bool FileIsReadOnly( const wstring& Filename ) +{ + string s = wstr2str(Filename); + return FileIsReadOnly(s); +} + +cint FpUtime( const char* Path, utimbuf* Times ) +{ + cint r = utime(Path, Times); + return r==-1 ? -errno : r; +} + +int FileSetDate( const string& Filename, int Age ) +{ + int result = 0; + utimbuf T; + result = 0; + T.actime = Age; + T.modtime = Age; + if ( FpUtime( Filename.c_str(), &T ) == - 1 ) + result = errno; //fpgeterrno(); + return result; +} + +int FileSetDate( const wstring& Filename, int Age ) +{ + string s = wstr2str(Filename); + return FileSetDate(s, Age); +} +/***************************************************************************** + disk functions +*****************************************************************************/ + +/* + the DiskFree and DiskSize functions need A File ON the specified Drive, since this + is required for the statfs System call. + These filenames are set in DriveStr[0..26], and have been Preset to : + 0 - '.' (Default Drive - Hence current Dir is ok.) + 1 - '/fd0/.' (floppy Drive 1 - should be adapted to Local System ) + 2 - '/fd1/.' (floppy Drive 2 - should be adapted to Local System ) + 3 - '/' (C: equivalent of DOS is the root partition) + 4..26 (can be set by you're own Applications) + ! use AddDisk() to Add New drives ! + they both return -1 when A failure occurs. +*/ + + +const char* FixDriveStr [ 4/*# range 0..3*/ ]; +void FixDriveStrInit( ) +{ + FixDriveStr[0] = "."; + FixDriveStr[1] = "/fd0/."; + FixDriveStr[2] = "/fd1/."; + FixDriveStr[3] = "/."; +} + + +unsigned char drives = '\0'; +char* DriveStr[ 23/*# range 4..26*/ ]; + + +unsignedchar AddDisk( const string& Path ) +{ + if ( ! ( DriveStr[drives - 4] == NULL ) ) + FreeMem( DriveStr[drives - 4], StrLen( DriveStr[drives - 4] ) + 1 ); + GetMem( DriveStr[drives - 4], Path.length( ) + 1 ); + strcpy(DriveStr[drives - 4], Path.c_str()); + drives++; + if ( drives > 26 ) + drives = 4; + return drives; +} + + +int64_t DiskFree( unsignedchar Drive ) +{ + int64_t result = 0; + struct statfs fs; + if ( ( Drive >= 0 && Drive <= 3 && FixDriveStr[Drive] != NULL && statfs( FixDriveStr[Drive], &fs ) != - 1 ) || + ( ( Drive <= 26 ) && DriveStr[Drive - 4] != NULL && statfs( DriveStr[Drive - 4], &fs ) != - 1 ) ) + result = ((int64_t) fs.f_bavail ) * ((int64_t) fs.f_bsize ); + else + result = - 1; + return result; +} + + +int64_t DiskSize( unsignedchar Drive ) +{ + int64_t result = 0; + struct statfs fs; + if ( ( Drive >= 0 && Drive <= 3 && FixDriveStr[Drive] != NULL && statfs( FixDriveStr[Drive], &fs ) != - 1 ) || + ( ( Drive <= 26 ) && DriveStr[Drive - 4] != NULL && statfs( DriveStr[Drive - 4], &fs ) != - 1 ) ) + result = ((int64_t) fs.f_blocks ) * ((int64_t) fs.f_bsize ); + else + result = - 1; + return result; +} + + +String GetCurrentDir( ) +{ + String result; + GetDir( 0, result ); + return result; +} + + +bool SetCurrentDir( const String& newdir ) +{ + bool result = false; + ChDir( newdir ); + result = ( IOResult() == 0 ); + return result; +} + + +bool CreateDir( const String& newdir ) +{ + bool result = false; + MkDir( newdir ); + result = ( IOResult() == 0 ); + return result; +} + + +bool RemoveDir( const String& Dir ) +{ + bool result = false; + RmDir( Dir ); + result = ( IOResult() == 0 ); + return result; +} + +// clocale + +#define clocale__0 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( _T('E') ) << (unsigned char) ( _T('O') ) ) +#define clocale__1 ( TSet < unsigned char, 0, 255 >() \ + << (unsigned char) ( _T('E') ) << (unsigned char) ( _T('O') ) ) +#define clocale__2 ( TSet < int, 0, 255 >() \ + << int ( 0 ) << int ( 1 ) << int ( 2 ) << int ( 3 ) << int ( 4 ) ) +#define clocale__3 ( TSet < int, 0, 255 >() \ + << int ( 0 ) << int ( 1 ) ) +#define clocale__4 ( TSet < int, 0, 255 >() \ + << int ( 0 ) << int ( 1 ) ) + + + +const int ABDAY_1 = ( __LC_TIME << 16 ); +const int DAY_1 = ( ABDAY_1 ) + 7; +const int ABMON_1 = ( ABDAY_1 ) + 14; +const int MON_1 = ( ABDAY_1 ) + 26; +const int AM_STR = ( ABDAY_1 ) + 38; +const int PM_STR = ( ABDAY_1 ) + 39; +const int D_T_FMT = ( ABDAY_1 ) + 40; +const int D_FMT = ( ABDAY_1 ) + 41; +const int T_FMT = ( ABDAY_1 ) + 42; +const int T_FMT_AMPM = ( ABDAY_1 ) + 43; +const int __DECIMAL_POINT = ( __LC_NUMERIC << 16 ); +const int RADIXCHAR = __DECIMAL_POINT; +const int __THOUSANDS_SEP = ( __DECIMAL_POINT ) + 1; +const int __INT_CURR_SYMBOL = ( __LC_MONETARY << 16 ); +const int __CURRENCY_SYMBOL = ( __INT_CURR_SYMBOL ) + 1; +const int __MON_DECIMAL_POINT = ( __INT_CURR_SYMBOL ) + 2; +const int __MON_THOUSANDS_SEP = ( __INT_CURR_SYMBOL ) + 3; +const int __MON_GROUPING = ( __INT_CURR_SYMBOL ) + 4; +const int __POSITIVE_SIGN = ( __INT_CURR_SYMBOL ) + 5; +const int __NEGATIVE_SIGN = ( __INT_CURR_SYMBOL ) + 6; +const int __INT_FRAC_DIGITS = ( __INT_CURR_SYMBOL ) + 7; +const int __FRAC_DIGITS = ( __INT_CURR_SYMBOL ) + 8; +const int __P_CS_PRECEDES = ( __INT_CURR_SYMBOL ) + 9; +const int __P_SEP_BY_SPACE = ( __INT_CURR_SYMBOL ) + 10; +const int __N_CS_PRECEDES = ( __INT_CURR_SYMBOL ) + 11; +const int __N_SEP_BY_SPACE = ( __INT_CURR_SYMBOL ) + 12; +const int __P_SIGN_POSN = ( __INT_CURR_SYMBOL ) + 13; +const int __N_SIGN_POSN = ( __INT_CURR_SYMBOL ) + 14; +const int _NL_MONETARY_CRNCYSTR = ( __INT_CURR_SYMBOL ) + 15; + + +String GetLocaleStr( cint item ) +{ +#ifdef _WIDESTRING + return str2wstr(nl_langinfo( item )); +#else + return nl_langinfo( item ); +#endif +} + + +Char GetLocaleChar( cint item ) +{ + return nl_langinfo( item )[0]; // b? +} + + +Char FindSeparator( const String& S, Char def ) +{ + Char result = _T('\0'); + int i = 0, l = 0; + result = def; + i = Pos( _T("%"), S ); + if ( i == 0 ) + return result; + l = S.length( ); + i++; + if ( ( i <= l ) && ( clocale__0.Contains(S[i - 1] ) ) ) //possible modifier + i++; + i++; + if ( i <= l ) + result = S[i - 1]; + return result; +} + + +String TransformFormatStr( const String& S ) +{ + String result; + int i = 0, l = 0; + bool Clock12 = false; + Clock12 = false; // should ampm get appended? + result = _T(""); + i = 1; + l = S.length( ); + while ( i <= l ) + { + if ( S[i - 1] == _T('%') ) + { + i++; + if ( ( i <= l ) && ( clocale__1.Contains(S[i - 1] ) ) ) //IGNORE modifier + i++; + if ( i > l ) + return result; + switch ( S[i - 1] ) + { + case _T('a'): + result += _T("ddd"); + break; + case _T('A'): + result += _T("dddd"); + break; + case _T('b'): + result += _T("mmm"); + break; + case _T('B'): + result += _T("mmmm"); + break; + case _T('c'): + result += _T("c"); + break; + //'C'): + + case _T('d'): + result += _T("dd"); + break; + case _T('D'): + result += _T("mm\"/\"dd\"/\"yy"); + break; + case _T('e'): + result += _T("d"); + break; + case _T('F'): + result += _T("yyyy-mm-dd"); + break; + case _T('g'): + result += _T("yy"); + break; + case _T('G'): + result += _T("yyyy"); + break; + case _T('h'): + result += _T("mmm"); + break; + case _T('H'): + result += _T("hh"); + break; + case _T('I'): + { + result += _T("hh"); + Clock12 = true; + } + break; + //'j'): + + case _T('k'): + result += _T("h"); + break; + case _T('l'): + { + result += _T("h"); + Clock12 = true; + } + break; + case _T('m'): + result += _T("mm"); + break; + case _T('M'): + result += _T("nn"); + break; + case _T('n'): + result += sLineBreak; + break; + case _T('p'): case _T('P'): + { + result += _T("ampm"); + Clock12 = false; + } + break; + case _T('r'): + { + result += _T("hh:nn:ss"); + Clock12 = true; + } + break; + case _T('R'): + result += _T("hh:nn"); + break; + //'S'): + + case _T('S'): + result += _T("ss"); + break; + case _T('t'): + result += _T("\x09"); + break; + case _T('T'): + result += _T("hh:nn:ss"); + break; + //'U'): + //'U'): + //'V'): + //'W'): + //'W'): + + case _T('x'): + result += _T("ddddd"); + break; + case _T('X'): + result += _T("t"); + break; + case _T('y'): + result += _T("yy"); + break; + case _T('Y'): + result += _T("yyyy"); + break; + //'Z'): + //'Z'): + + case _T('%'): + result += _T("%"); + break; + } + } + else + result += S[i - 1]; + i++; + } + i = result.length( ); + if ( Clock12 && ( i > 0 ) ) + { + if ( result[i] != _T(' ') ) + result += _T(" "); + result += _T("ampm"); + } + return result; +} + + +void GetFormatSettings( ) +{ + // sign prec sep + unsigned char NegFormatsTable [ 5/*# range 0..4*/ ][ 2/*# range 0..1*/ ][ 2/*# range 0..1*/ ]; + NegFormatsTable[0][0][0] = 4; + NegFormatsTable[0][0][1] = 15; + NegFormatsTable[0][1][0] = 0; + NegFormatsTable[0][1][1] = 14; + NegFormatsTable[1][0][0] = 5; + NegFormatsTable[1][0][1] = 8; + NegFormatsTable[1][1][0] = 1; + NegFormatsTable[1][1][1] = 9; + NegFormatsTable[2][0][0] = 7; + NegFormatsTable[2][0][1] = 10; + NegFormatsTable[2][1][0] = 3; + NegFormatsTable[2][1][1] = 11; + NegFormatsTable[3][0][0] = 6; + NegFormatsTable[3][0][1] = 13; + NegFormatsTable[3][1][0] = 1; + NegFormatsTable[3][1][1] = 9; + NegFormatsTable[4][0][0] = 7; + NegFormatsTable[4][0][1] = 10; + NegFormatsTable[4][1][0] = 2; + NegFormatsTable[4][1][1] = 12; //the sign String immediately follows the currency_symbol + + int i = 0; + unsigned char prec = '\0', sep = '\0', signp = '\0'; + setlocale( __LC_ALL, "" ); + for ( i = 1; i <= 12; i++) + { + ShortMonthNames[i - 1] = GetLocaleStr( ABMON_1 + i - 1 ); + LongMonthNames[i - 1] = GetLocaleStr( MON_1 + i - 1 ); + } + for ( i = 1; i <= 7; i++) + { + ShortDayNames[i - 1] = GetLocaleStr( ABDAY_1 + i - 1 ); + LongDayNames[i - 1] = GetLocaleStr( DAY_1 + i - 1 ); + } + //Date stuff + ShortDateFormat = GetLocaleStr( D_FMT ); + DateSeparator = FindSeparator( ShortDateFormat, DateSeparator ); + ShortDateFormat = TransformFormatStr( ShortDateFormat ); + LongDateFormat = GetLocaleStr( D_T_FMT ); + LongDateFormat = TransformFormatStr( LongDateFormat ); + //Time stuff + TimeAMString = GetLocaleStr( AM_STR ); + TimePMString = GetLocaleStr( PM_STR ); + ShortTimeFormat = GetLocaleStr( T_FMT ); + TimeSeparator = FindSeparator( ShortTimeFormat, TimeSeparator ); + ShortTimeFormat = TransformFormatStr( ShortTimeFormat ); + LongTimeFormat = GetLocaleStr( T_FMT_AMPM ); + LongTimeFormat = TransformFormatStr( LongTimeFormat ); + //Currency stuff + CurrencyString = GetLocaleStr( _NL_MONETARY_CRNCYSTR ); + CurrencyString = CurrencyString.substr( 2 - 1, CurrencyString.length( ) ); + CurrencyDecimals = StrToIntDef( GetLocaleStr( __FRAC_DIGITS ), CurrencyDecimals ); + prec = ((unsigned char) GetLocaleChar( __P_CS_PRECEDES ) ); + sep = ((unsigned char) GetLocaleChar( __P_SEP_BY_SPACE ) ); + if ( ( prec <= 1 ) && ( sep <= 1 ) ) + CurrencyFormat = ((unsigned char) ! ((bool) prec ) ) + ( sep << 1 ); + prec = ((unsigned char) GetLocaleChar( __N_CS_PRECEDES ) ); + sep = ((unsigned char) GetLocaleChar( __N_SEP_BY_SPACE ) ); + signp = ((unsigned char) GetLocaleChar( __N_SIGN_POSN ) ); + if ( ( clocale__2.Contains(signp ) ) && ( clocale__3.Contains(prec ) ) && ( clocale__4.Contains(sep ) ) ) + NegCurrFormat = NegFormatsTable[signp][ prec][ sep]; + //number stuff + ThousandSeparator = GetLocaleChar( __THOUSANDS_SEP ); + DecimalSeparator = GetLocaleChar( RADIXCHAR ); +} + +// clocale end + +void InitAnsi( ) +{ + int i = 0; + /* Fill Table Entries 0 to 127 */ + for ( i = 0; i <= 96; i++) + UpperCaseTable[i] = Char( i ); + for ( i = 97; i <= 122; i++) + UpperCaseTable[i] = Char( i - 32 ); + for ( i = 123; i <= 191; i++) + UpperCaseTable[i] = Char( i ); + Move( &CPISO88591UCT, &UpperCaseTable[192], sizeof( CPISO88591UCT ) ); + for ( i = 0; i <= 64; i++) + LowerCaseTable[i] = Char( i ); + for ( i = 65; i <= 90; i++) + LowerCaseTable[i] = Char( i + 32 ); + for ( i = 91; i <= 191; i++) + LowerCaseTable[i] = Char( i ); + Move( &CPISO88591LCT, &LowerCaseTable[192], sizeof( CPISO88591UCT ) ); +} + +void InitInternational( ) +{ + InitInternationalGeneric(); + InitAnsi(); + GetFormatSettings(); +} +#else +#error unknown platform +#endif + + + +void Sysutils_initialization() +{ + + InitInternational(); /* Initialize internationalization settings */ + +#ifdef windows + LoadVersionInfo(); +#elif defined(linux) + FixDriveStrInit(); +#endif +} + +void Sysutils_finalization() +{ + ; +} + +class Sysutils_unit +{ +public: +Sysutils_unit() +{ + DefaultFormatSettingsInit(); + Sysutils_initialization(); +} +~Sysutils_unit(){ Sysutils_finalization(); } +}; +Sysutils_unit _Sysutils_unit; + +} // namespace Sysutils + + diff --git a/OpenDSSC/Support/Sysutils.h b/OpenDSSC/Support/Sysutils.h new file mode 100644 index 0000000..9dddc96 --- /dev/null +++ b/OpenDSSC/Support/Sysutils.h @@ -0,0 +1,730 @@ + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +#ifndef sysutilsH +#define sysutilsH + + +#include "d2c_systypes.h" +#include "d2c_syscurr.h" +#include "d2c_sysfile.h" +#include "d2c_varrec.h" +#include "dirsep.h" + + +namespace Sysutils +{ + +typedef String TMonthNameArray [ 12/*# range 1..12*/ ]; +typedef String TWeekNameArray [ 7/*# range 1..7*/ ]; + +/* --------------------------------------------------------------------- + number formatting constants + ---------------------------------------------------------------------*/ + +extern Char& DecimalSeparator; // character that comes between Integer and fractional part of A number +extern Char& ThousandSeparator; // character that is Put every 3 numbers in A Currency +extern Char& ListSeparator; +extern unsigned char& CurrencyDecimals; // number of Decimals to use when formatting A Currency. + /* Format to use when formatting Currency : + 0 = $1 + 1 = 1$ + 2 = $ 1 + 3 = 1 $ + 4 = Currency String replaces decimal indicator. e.g. 1$50 + */ + +extern unsigned char& CurrencyFormat; + /* same as above, only for Negative currencies: + 0 = ($1) + 1 = -$1 + 2 = $-1 + 3 = $1- + 4 = (1$) + 5 = -1$ + 6 = 1-$ + 7 = 1$- + 8 = -1 $ + 9 = -$ 1 + 10 = $ 1- + */ +extern unsigned char& NegCurrFormat; +extern String& CurrencyString; + +/* --------------------------------------------------------------------- + Date formatting settings + ---------------------------------------------------------------------*/ + +extern Char& DateSeparator; // character to be Put between Date, Month and Year +extern String& ShortDateFormat; // Format used for SHORT Date notation +extern String& LongDateFormat; // Format used for LONG Date notation +extern TMonthNameArray& ShortMonthNames; // SHORT Names of months. +extern TMonthNameArray& LongMonthNames; // LONG Names of months. +extern TWeekNameArray& ShortDayNames; // SHORT Names of Days +extern TWeekNameArray& LongDayNames; // full Names of Days +extern String& ShortTimeFormat; // Format used for SHORT time notation +extern String& LongTimeFormat; // Format used for LONG time notation +extern Char& TimeSeparator; // character to be Put between hours and minutes +extern String& TimeAMString; // String to indicate AM time when Using 12 Hour clock. +extern String& TimePMString; // String to indicate PM time when Using 12 Hour clock. +extern WORD& TwoDigitYearCenturyWindow; // Threshold to be subtracted from Year before Age-Detection. + + /* Delphi Compat fields*/ +struct TSysLocale { + int DefaultLCID, PriLangID, SubLangID; + /*# case Byte */ + union { + /* Win32 Names */ + /*# 1 */ + struct { + bool FarEast; + bool MiddleEast; + }; + /* real meaning */ + /*# 2 */ + struct { + bool MBCS; + bool RightToLeft; + }; + }; //union +}; + + +extern TSysLocale SysLocale; + +String GetEnvironmentVariable( const String& EnvVar ); +int GetEnvironmentVariableCount( ); +String GetEnvironmentString( int Index ); +#ifdef linux + + const PtrInt NilHandle = ((TLibHandle) 0 ); + TLibHandle SafeLoadLibrary( std::string Name ); + TLibHandle SafeLoadLibrary( std::wstring Name ); + TLibHandle LoadLibrary( std::string Name ); + TLibHandle LoadLibrary( std::wstring Name ); + void* GetProcedureAddress( TLibHandle lib, std::string ProcName ); + void* GetProcedureAddress( TLibHandle lib, std::wstring ProcName ); + bool UnloadLibrary( TLibHandle lib ); + + // Kylix/Delphi compability + + bool FreeLibrary( TLibHandle lib ); + void* GetProcAddress( TLibHandle lib, std::string ProcName ); + void* GetProcAddress( TLibHandle lib, std::wstring ProcName ); + + // These are for easier crossplatform construction of DLL Names in dynloading libs. + const Char SharedSuffix[] = _T("so"); + + void Sleep( unsignedint milliseconds ); +#endif +int ExecuteProcess( const String& Path, const String& comline ); +int ExecuteProcess( const String& Path, const String* comline, int comline_maxidx ); +String GetTempDir( bool Global ); +String GetTempDir( ); +String GetTempFileName( const String& Dir, const String& prefix ); +String GetTempFileName( ); +DWORD GetTempFileName( Char* Dir, Char* prefix, DWORD uUnique, Char* TempFileName ); +String GetAppConfigDir( bool Global ); +String GetAppConfigFile( bool Global ); +String GetAppConfigFile( bool Global, bool subdir ); +String GetUserDir( ); +String VendorName( ); +String applicationName( ); +extern String ConfigExtension; +extern String SysConfigDir; + + +typedef String ( * TGetVendorNameEvent )( ); +typedef String ( * TGetAppNameEvent )( ); +typedef String ( * TGetTempDirEvent )( bool ); +typedef String ( * TGetTempFileEvent )( const String& , const String& ); +extern TGetVendorNameEvent OnGetVendorName; +extern TGetAppNameEvent OnGetApplicationName; +extern TGetTempDirEvent OnGetTempDir; +extern TGetTempFileEvent OnGetTempFile; + + + /* for FloatToText */ +enum TFloatFormat {ffGeneral, + ffExponent, + ffFixed, + ffNumber, + ffCurrency }; +enum TFloatValue {fvExtended, + fvCurrency, + fvSingle, + fvReal, + fvDouble, + fvComp }; + +enum Sysutils__0 {rfReplaceAll, rfIgnoreCase }; +typedef TSet < Sysutils__0, rfReplaceAll, rfIgnoreCase > TReplaceFlags; + +struct TFloatRec { + int Exponent; + bool Negative; + Char Digits [ 19/*# range 0..18*/ ]; +}; + /* for FloatToDateTime and VariantToDate */ + + +extern Currency MinCurrency; +extern Currency MaxCurrency; +extern TSet < UChar, 0, 255 > LeadBytes; +extern String EmptyStr; +extern PString NullStr; +extern std::wstring EmptyWideStr; +extern std::vector< String > TrueBoolStrs, FalseBoolStrs; + + +std::string StrPas( const char* str ); +std::wstring StrPas( const wchar_t* str ); +char* StrPCopy( char* Dest, const std::string& Source ); +wchar_t* StrPCopy( wchar_t* Dest, const std::wstring& Source ); + + +//void Delete( SmallString<255>& S, int Index, int Count ); +//void Insert( const SmallString<255> Source, SmallString<255>& S, int Index ); +//void Insert( char Source, SmallString<255>& S, int Index ); +//int Pos( const SmallString<255> Substr, const SmallString<255> S ); +//int Pos( char C, const SmallString<255> S ); +//int Pos( const SmallString<255> Substr, const std::string& Source ); +//void SetString( SmallString<255>& S, char* Buffer, int Len ); +//void SetLength( SmallString<255>& S, int Len ); +//int Length(const SmallString<255>& S); +//int Pos( const SmallString<255> Substr, wchar_t C ); + + + +//PString NewStr( const String& S ); +//void DisposeStr( PString S ); +void AssignStr( PString& P, const String& S ); +void AppendStr( String& Dest, const String& S ); +std::string UpperCase( const std::string& S ); +std::wstring UpperCase( const std::wstring& S ); +std::string LowerCase( const std::string& S ); +std::wstring LowerCase( const std::wstring& S ); +int CompareStr( const String& S1, const String& S2 ); +int CompareMemRange( void* p1, void* p2, unsignedint Length ); +bool CompareMem( void* p1, void* p2, unsignedint Length ); +int CompareText( const String& S1, const String& S2 ); +bool SameText( const String& S1, const String& S2 ); +String AnsiUpperCase( const String& S ); +String AnsiLowerCase( const String& S ); +int AnsiCompareStr( const String& S1, const String& S2 ); +int AnsiCompareText( const String& S1, const String& S2 ); +bool AnsiSameText( const String& S1, const String& S2 ); +bool AnsiSameStr( const String& S1, const String& S2 ); +int AnsiStrComp( const Char* S1, const Char* S2 ); +int AnsiStrIComp( const Char* S1, const Char* S2 ); +int AnsiStrLComp( const Char* S1, const Char* S2, unsignedint MaxLen ); +int AnsiStrLIComp( const Char* S1, const Char* S2, unsignedint MaxLen ); +Char* AnsiStrLower( Char* str ); +Char* AnsiStrUpper( Char* str ); +Char* AnsiLastChar( const String& S ); +Char* AnsiStrLastChar( Char* str ); +String Trim( const String& S ); +String TrimLeft( const String& S ); +String TrimRight( const String& S ); +String QuotedStr( const String& S ); +String AnsiQuotedStr( const String& S, Char Quote ); +String AnsiDequotedStr( const String& S, Char AQuote ); +String AnsiExtractQuotedStr( Char*& Src, Char Quote ); +String AdjustLineBreaks( const String& S ); +String AdjustLineBreaks( const String& S, System::TTextLineBreakStyle Style ); +bool IsValidIdent( const String& Ident ); +#define IntToStr(x) std::to_string(x) +String IntToHex( int Value, int Digits ); +String IntToHex( int64_t Value, int Digits ); +String IntToHex( QWord Value, int Digits ); +int StrToInt( const String& S ); +bool TryStrToInt( const String& S, int& i ); +int64_t StrToInt64( const String& S ); +bool TryStrToInt64( const String& S, int64_t& i ); +QWord StrToQWord( const String& S ); +bool TryStrToQWord( const String& S, QWord& Q ); +int StrToIntDef( const String& S, int deflt ); +int64_t StrToInt64Def( const String& S, int64_t deflt ); +QWord StrToQWordDef( const String& S, QWord deflt ); +//String LoadStr( int Ident ); +// function FmtLoadStr(Ident: Integer; const Args: array of const): String; + + +String Format( const String& fmt, const VECTOROFCONST& Args ); +unsignedint FormatBuf( wchar_t* Buffer, unsignedint BufLen, const wchar_t* fmt, unsignedint FmtLen, const VECTOROFCONST& Args ); +Char* StrFmt( Char* Buffer, const Char* fmt, const VECTOROFCONST& Args ); +Char* StrLFmt( Char* Buffer, unsignedint MaxLen, const Char* fmt, const VECTOROFCONST& Args ); +void FmtStr( String& RES, const String& fmt, const VECTOROFCONST& Args ); + +String FloatToStrF( long double Value, TFloatFormat Format, int Precision, int Digits ); +String FloatToStrF( double Value, TFloatFormat Format, int Precision, int Digits ); +String FloatToStrF( float Value, TFloatFormat Format, int Precision, int Digits ); +String FloatToStrF( int64_t Value, TFloatFormat Format, int Precision, int Digits ); +String FloatToStrF( Currency Value, TFloatFormat Format, int Precision, int Digits ); +String FloatToStrF( int64_t Value, TFloatFormat Format, int Precision, int Digits ); +String CurrToStrF( Currency Value, TFloatFormat Format, int Digits ); +String FloatToStr( long double Value ); +String FloatToStr( double Value ); +String FloatToStr( float Value ); +String FloatToStr( int Value ); +String FloatToStr( Currency Value ); +String FloatToStr( int64_t Value ); +long double StrToFloat( const String& S ); +long double StrToFloatDef( const String& S, const long double deflt ); +bool TryStrToFloat( const String& S, float& Value ); +bool TryStrToFloat( const String& S, double& Value ); +bool TextToFloat( const Char* Buffer, long double& Value ); +bool TextToFloat( const Char* Buffer, void* Value, TFloatValue ValueType ); +int FloatToText( Char* Buffer, long double Value, TFloatFormat Format, int Precision, int Digits ); +bool StrToBool( const String& S ); +String BoolToStr( bool B, bool UseBoolStrs = false ); +bool StrToBoolDef( const String& S, bool deflt ); +bool TryStrToBool( const String& S, bool& Value ); +int LastDelimiter( const String& Delimiters, const String& S ); +String StringReplace( const String& S, const String& OldPattern, const String& NewPattern, TReplaceFlags Flags ); +int FloatToTextFmt( Char* Buffer, long double Value, Char* Format ); +void FloatToDecimal( TFloatRec& result, void* Value, TFloatValue ValueType, int Precision, int Decimals ); +void FloatToDecimal( TFloatRec& result, long double Value, int Precision, int Decimals ); +String FormatFloat( const String& Format, long double Value ); +bool IsDelimiter( const String& Delimiters, const String& S, int Index ); +String FormatCurr( const String& Format, Currency Value ); +int SScanf( const String& S, const String& fmt, const void** pointers, int pointers_maxidx ); + +/*// MBCS functions. no MBCS yet, So mostly These are calls to the regular counterparts.*/ + + +enum TMbcsByteType {mbSingleByte, + mbLeadByte, + mbTrailByte }; +TMbcsByteType ByteType( const String& S, int Index ); +TMbcsByteType StrByteType( Char* str, unsignedint Index ); +int ByteToCharLen( const String& S, int MaxLen ); +int CharToByteLen( const String& S, int MaxLen ); +int ByteToCharIndex( const String& S, int Index ); +int StrCharLength( const char* str ); +const char* StrNextChar( const char* str ); +const TSet < UChar, 0, 255> SwitchChars = ( TSet < UChar, 0, 255 >() << _T('/') << _T('-') ); + + +typedef TSet < UChar, 0, 255 > TSysCharSet; +typedef TSysCharSet *PSysCharSet; +bool FindCmdLineSwitch( const String& Switch, const TSysCharSet Chars, bool IgnoreCase ); +bool FindCmdLineSwitch( const String& Switch, bool IgnoreCase ); +bool FindCmdLineSwitch( const String& Switch ); +String WrapText( const String& Line, const String& BreakStr, const TSysCharSet BreakChars, int MaxCol ); +String WrapText( const String& Line, int MaxCol ); +int LastDelimiter( const String& Delimiters, const String& S ); + + +typedef String TFileName; +typedef TSet < int/*# range sizeof(int)*8-1-0+1*/, 0, 255 > TIntegerSet; + +#pragma pack(push, 1) +struct LongRec { + /*# case Integer */ + union { + /*# 0 */ + struct { + WORD Lo, Hi; + }; + /*# 1 */ + struct { + unsigned char Bytes [ 4/*# range 0..3*/ ]; + }; + }; //union +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct WordRec { + unsigned char Lo, Hi; +}; +#pragma pack(pop) + + +#pragma pack(push, 1) +struct Int64Rec { + /*# case Integer */ + union { + /*# 0 */ + struct { + unsigned int Lo, Hi; + }; + /*# 1 */ + struct { + WORD Words [ 4/*# range 0..3*/ ]; + }; + /*# 2 */ + struct { + unsigned char Bytes [ 8/*# range 0..7*/ ]; + }; + }; //union +}; +#pragma pack(pop) + + +typedef unsigned char *PByteArray; +typedef unsigned char TByteArray [ 32768/*# range 0..32767*/ ]; +typedef WORD *PWordArray; +typedef WORD TWordArray [ 16384/*# range 0..16383*/ ]; + + + +extern String HexDisplayPrefix; + +const char PathDelim = DIRSEP_CHAR;/*System.*/ +#ifdef windows +const char DriveDelim = ':';/*System.*/ +const char PathSep = ';';/*System.*/ +// in WinDef.h const int MAX_PATH = MAXPATHLEN; +#else +const char DriveDelim = '/';/*System.*/ +const char PathSep = ':';/*System.*/ +const int MAX_PATH = MAXPATHLEN; +extern char** envp; +#endif + + + /* read PChar handling functions declaration */ + /* + ********************************************************************* + Copyright (C) 1997, 1998 Gertjan Schouten + + this program is Free Software; you can redistribute it and/or modify + it under the terms of the GNU general public License as published by + the Free Software Foundation; either version 2 of the License, or + (at Your option) Any later version. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. see the + GNU general public License for more details. + + you should have received A copy of the GNU general public License + along with this program; if not, write to the Free Software + Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ********************************************************************* + + System Utilities for Free p4ascal +*/ + +/* shared with Strings unit */ +unsigned int StrLen( char* P ); +unsigned int StrLen( wchar_t* P ); +wchar_t* StrCopy( wchar_t* Dest, const wchar_t* Source ); +char* StrCopy( char* Dest, const char* Source ); +wchar_t* StrLCopy( wchar_t* Dest, const wchar_t* Source, int MaxLen ); +char* StrLCopy( char* Dest, const char* Source, int MaxLen ); +wchar_t* StrECopy( wchar_t* Dest, const wchar_t* Source ); +char* StrECopy( char* Dest, const char* Source ); +wchar_t* StrEnd( wchar_t* P ); +char* StrEnd( char* P ); +wchar_t* StrCat( wchar_t* Dest, const wchar_t* Source ); +char* StrCat( char* Dest, const char* Source ); + +int StrComp( const char* Str1, const char* Str2 ); +int StrComp( const wchar_t* Str1, const wchar_t* Str2 ); +int StrLComp( const char* Str1, const char* Str2, int l ); +int StrLComp( const wchar_t* Str1, const wchar_t* Str2, int l ); +int StrIComp( const char* Str1, const char* Str2 ); +int StrIComp( const wchar_t* Str1, const wchar_t* Str2 ); +int StrLIComp( const char* Str1, const char* Str2, int l ); +int StrLIComp( const wchar_t* Str1, const wchar_t* Str2, int l ); + + +char* StrMove( char* Dest, const char* Source, int l ); +wchar_t* StrMove( wchar_t* Dest, const wchar_t* Source, int l ); +char* StrLCat( char* Dest, const char* Source, int l ); +wchar_t* StrLCat( wchar_t* Dest, const wchar_t* Source, int l ); +char* StrScan( char* P, char C ); +wchar_t* StrScan( wchar_t* P, wchar_t C ); +char* StrRScan( char* P, char C ); +wchar_t* StrRScan( wchar_t* P, wchar_t C ); + +Char* StrLower( Char* P ); +Char* StrUpper( Char* P ); +Char* StrPos( Char* Str1, Char* Str2 ); +Char* StrNew( Char* P ); + +/* different from Strings unit - AnsiStrings or different behaviour / +wchar_t* StrPCopy( wchar_t* Dest, const String& Source ); +wchar_t* StrPLCopy( wchar_t* Dest, const String& Source, SizeUInt MaxLen ); +wchar_t* StrAlloc( unsignedint Size ); +SizeUInt StrBufSize( wchar_t* str ); +void StrDispose( wchar_t* str ); +*/ + /* MCBS functions */ + /* + ********************************************************************* + Copyright (C) 2002 by Florian Klaempfl + + this program is Free Software; you can redistribute it and/or modify + it under the terms of the GNU general public License as published by + the Free Software Foundation; either version 2 of the License, or + (at Your option) Any later version. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. see the + GNU general public License for more details. + + you should have received A copy of the GNU general public License + along with this program; if not, write to the Free Software + Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ********************************************************************* +*/ +int AnsiCompareFileName( const String& S1, const String& S2 ); +String AnsiLowerCaseFileName( const String& S ); +String AnsiUpperCaseFileName( const String& S ); +int AnsiPos( const String& Substr, const String& S ); +Char* AnsiStrPos( Char* str, Char* Substr ); +Char* AnsiStrRScan( Char* str, Char Chr ); +Char* AnsiStrScan( Char* str, Char Chr ); + + /* wide String functions */ + /* + ********************************************************************* + Copyright (C) 2002 by Florian Klaempfl + + this program is Free Software; you can redistribute it and/or modify + it under the terms of the GNU general public License as published by + the Free Software Foundation; either version 2 of the License, or + (at Your option) Any later version. + + this program is distributed in the hope that it will be useful, + but without Any WARRANTY; without even the implied WARRANTY of + MERCHANTABILITY or FITNESS for A particular purpose. see the + GNU general public License for more details. + + you should have received A copy of the GNU general public License + along with this program; if not, write to the Free Software + Foundation, inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ********************************************************************* +*/ + +std::wstring WideUpperCase( const std::wstring& S ); +std::wstring WideLowerCase( const std::wstring& S ); +PtrInt WideCompareStr( const std::wstring& S1, const std::wstring& S2 ); +bool WideSameStr( const std::wstring& S1, const std::wstring& S2 ); +PtrInt WideCompareText( const std::wstring& S1, const std::wstring& S2 ); +bool WideSameText( const std::wstring& S1, const std::wstring& S2 ); +std::wstring WideFormat( const std::wstring& fmt, const VECTOROFCONST& Args ); +unsignedint WideFormatBuf( void* Buffer, unsignedint BufLen, void* fmt, unsignedint FmtLen, const VECTOROFCONST& Args ); +void WideFmtStr( std::wstring& RES, const std::wstring& fmt, const VECTOROFCONST& Args ); + + +String ChangeFileExt( const String& Filename, const String& Extension ); +String ExtractFilePath( const String& Filename ); +String ExtractFileDrive( const String& Filename ); +std::string ExtractFileName( const std::string& Filename ); +std::wstring ExtractFileName( const std::wstring& Filename ); +String ExtractFileExt( const String& Filename ); +String ExtractFileDir( const String& Filename ); +String ExtractRelativePath( const String& BaseName, const String& DestName ); +#ifdef windows +String ExtractShortPathName( const String& Filename ); +#endif +String ExpandFileName( const String& Filename ); +String ExpandUNCFileName( const String& Filename ); +String ExtractRelativePath( const String& BaseName, const String& DestName ); +String IncludeTrailingPathDelimiter( const String& Path ); +String IncludeTrailingBackslash( const String& Path ); +String ExcludeTrailingBackslash( const String& Path ); +String ExcludeTrailingPathDelimiter( const String& Path ); +bool IsPathDelimiter( const String& Path, int Index ); +int GetDirs( String& DirName, Char** dirs, int dirs_maxidx ); +bool SameFileName( const String& S1, const String& S2 ); + +#ifdef windows +#ifdef _WIDESTRING + typedef WIN32_FIND_DATAW TWin32FindData; +#else + typedef WIN32_FIND_DATAA TWin32FindData; +#endif +#endif + +struct TSearchRec { + int Time; + int64_t Size; + int Attr; + TFileName Name; + int ExcludeAttr; + #ifdef unix + void* FindHandle; + mode_t Mode; + AnsiString PathOnly; + #else + THandle FindHandle; + #endif + #ifdef windows + TWin32FindData FindData; + #endif +}; + + + /* File errors */ +extern THandle feInvalidHandle; +THandle FileOpen( const std::string& Filename, int Mode ); +THandle FileOpen( const std::wstring& Filename, int Mode ); +THandle FileCreate( const std::string& Filename ); +THandle FileCreate( const std::string& Filename, int Mode ); +THandle FileCreate( const std::wstring& Filename ); +THandle FileCreate( const std::wstring& Filename, int Mode ); +int FileRead( THandle Handle, void* Buffer, int Count ); +int FileWrite( THandle Handle, void* Buffer, int Count ); +int FileSeek( THandle Handle, int FOffset, int Origin ); +int64_t FileSeek( THandle Handle, int64_t FOffset, int Origin ); +void FileClose( THandle Handle ); +int FileAge( const std::string& Filename ); +int FileAge( const std::wstring& Filename ); +bool FileExists( const std::string& Filename ); +bool FileExists( const std::wstring& Filename ); +bool DirectoryExists( const std::string& Directory ); +bool DirectoryExists( const std::wstring& Directory ); +int FindFirst( const std::string& Path, int Attr, TSearchRec& Rslt ); +int FindFirst( const std::wstring& Path, int Attr, TSearchRec& Rslt ); +int FindNext( TSearchRec& Rslt ); +void FindClose( TSearchRec& F ); +int FileGetDate( THandle Handle ); +int FileSetDate( THandle Handle, int Age ); +int FileSetDate( const std::string& Filename, int Age ); +int FileSetDate( const std::wstring& Filename, int Age ); +int FileGetAttr( const std::string& Filename ); +int FileGetAttr( const std::wstring& Filename ); +int FileSetAttr( const std::string& Filename, int Attr ); +int FileSetAttr( const std::wstring& Filename, int Attr ); +bool DeleteFile( const std::string& Filename ); +bool DeleteFile( const std::wstring& Filename ); +bool RenameFile( const std::string& OldName, const String& newName ); +bool RenameFile( const std::wstring& OldName, const String& newName ); +std::string FileSearch( const std::string& Name, const std::string& DirList, bool ImplicitCurrentDir = true ); +std::wstring FileSearch( const std::wstring& Name, const std::wstring& DirList, bool ImplicitCurrentDir = true ); +std::string ExeSearch( const std::string& Name, const std::string& DirList ); +std::wstring ExeSearch( const std::wstring& Name, const std::wstring& DirList ); +bool FileIsReadOnly( const std::string& Filename ); +bool FileIsReadOnly( const std::wstring& Filename ); + +int64_t DiskFree( unsignedchar Drive ); +int64_t DiskSize( unsignedchar Drive ); +String GetCurrentDir( ); +bool SetCurrentDir( const String& newdir ); +bool CreateDir( const String& newdir ); +bool RemoveDir( const String& Dir ); +bool ForceDirectories( const String& Dir ); + + +void FreeAndNil( void*& Obj ); + + +//HMODULE SafeLoadLibrary( const std::string& Filename, DWORD ErrorMode = 0 ); + +/* some packages and unit related constants for compatibility */ +const int pfExeModule = 0x00000000; +const int pfNeverBuild = 0x00000001; +const int pfDesignOnly = 0x00000002; +const int pfRunOnly = 0x00000004; +const int pfIgnoreDupUnits = 0x00000008; +const int pfPackageModule = 0x40000000; +const int pfModuleTypeMask = 0xC0000000; +const int pfV3Produced = 0x00000000; +const int pfProducerUndefined = 0x04000000; +const int pfBCB4Produced = 0x08000000; +const int pfDelphi4Produced = 0x0C000000; +const int pfLibraryModule = 0x80000000; +const int pfProducerMask = 0x0C000000; +const int ufMainUnit = 0x01; +const int ufPackageUnit = 0x02; +const int ufWeakUnit = 0x04; +const int ufOrgWeakUnit = 0x08; +const int ufImplicitUnit = 0x10; +const int ufWeakPackageUnit = ufPackageUnit | ufWeakUnit; + +extern int Win32Platform; +extern DWORD Win32MajorVersion, Win32MinorVersion, Win32BuildNumber; +extern SmallString<255> Win32CSDVersion; // csd record is 128 Bytes only? + +/* compatibility with Delphi */ + +bool Win32Check( bool RES ); +bool CheckWin32Version( int major, int minor ); +bool CheckWin32Version( int major ); +void RaiseLastWin32Error( ); +// not in Sysutils unsignedint GetFileVersion( const String& AFileName ); +void GetFormatSettings( ); + +void Beep(); +String AdjustPath(const String &S); + +} // namespace Sysutils + + +using namespace Sysutils; + +#endif // sysutilsH diff --git a/OpenDSSC/Support/d2c_smallstring.h b/OpenDSSC/Support/d2c_smallstring.h new file mode 100644 index 0000000..be2132c --- /dev/null +++ b/OpenDSSC/Support/d2c_smallstring.h @@ -0,0 +1,219 @@ +#ifndef d2c_smallstringH +#define d2c_smallstringH + + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +/******************************************************************************* + + the class SmallString is constructed in analogy to + the SmallString class of the Borland VCL as + described in the CBuilder help file. + +*******************************************************************************/ + +#include +#include + +template class SmallString +{ +public: + static unsigned char High() { return sz; } + + SmallString() : m_Len(0) {} + + SmallString(const SmallString& xsOther) + { + m_Len = xsOther.m_Len; + strcpy(m_Data, xsOther.m_Data); + } + + SmallString& operator =(const SmallString& xsOther) + { + if (this != &xsOther) + { + m_Len = xsOther.m_Len; + strcpy(m_Data, xsOther.m_Data); + } + return *this; + } + + SmallString(const char* xpChar) + { + int len = strlen(xpChar); + m_Len = (unsigned char)((len > sz) ? sz : len); + strncpy(m_Data, xpChar, m_Len); + m_Data[m_Len] = '\0'; + } + + SmallString& operator =(const char* xpChar) + { + int len = strlen(xpChar); + m_Len = (unsigned char)((len > sz) ? sz : len); + strncpy(m_Data, xpChar, m_Len); + m_Data[m_Len] = '\0'; + return *this; + } + + SmallString(char xChar) + { + m_Len = 1; + m_Data[0] = xChar; + m_Data[1] = '\0'; + } + + + SmallString(const std::string& xsOther) + { + int len = xsOther.length(); + m_Len = (unsigned char)((len > sz) ? sz : len); + strncpy(m_Data, xsOther.c_str(), m_Len); + m_Data[m_Len] = '\0'; + } + + SmallString& operator =(const std::string& xsOther) + { + int len = xsOther.length(); + m_Len = (unsigned char)((len > sz) ? sz : len); + strncpy(m_Data, xsOther.c_str(), m_Len); + m_Data[m_Len] = '\0'; + return *this; + } + + + template + bool operator ==(const SmallString& xOther) const + { + return strcmp(m_Data, xOther.c_str()) == 0; + } + + template + bool operator !=(const SmallString& xOther) const + { + return strcmp(m_Data, xOther.c_str()) != 0; + } + + + inline const char* c_str() const + { + return (m_Len > 0)? m_Data : ""; + } + + + inline char operator [] (const unsigned char xiIndex) const + { + return m_Data[xiIndex-1]; + } + + inline char& operator [](const unsigned char xiIndex) + { + return m_Data[xiIndex-1]; + } + + inline operator std::string() const + { + return std::string(m_Data); + } + + inline operator std::wstring() const + { + return std::wstring(m_Data, m_Data + m_Len); + } + + inline int Length() const {return m_Len; } + inline bool IsEmpty() const {return m_Len == 0; } + inline void SetLength(unsigned char len) + { + m_Len = (unsigned char)((len > sz) ? sz : len); + m_Data[m_Len] = '\0'; + } + + +private: + + unsigned char m_Len; + char m_Data[sz + 1]; + +}; + +//--------------------------------------------------------------------------- +template +SmallString UpperCase( const SmallString& S ) +{ + SmallString result; + int i = 0; + result[0] = S[0]; + for ( i = 1; i <= S[0]; i++) + result[i] = toupper( S[i] ); + return result; +} + + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_structures.cpp b/OpenDSSC/Support/d2c_structures.cpp new file mode 100644 index 0000000..e4f9ae0 --- /dev/null +++ b/OpenDSSC/Support/d2c_structures.cpp @@ -0,0 +1,927 @@ + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + library tcreated to complement the missing units or function equivalent in Delphi + +*/ + +#include // uint8_t +#include "d2c_structures.h" +#include "Sysutils.h" +#include +#include +#include "CNData.h" +#include +#include +#include +#include "DSSGlobals.h" + +GUID StringToGuid(const std::string& str) +{ + GUID guid; + sscanf(str.c_str(), + "{%8x-%4hx-%4hx-%2hhx%2hhx-%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx}", + &guid.Data1, &guid.Data2, &guid.Data3, + &guid.Data4[0], &guid.Data4[1], &guid.Data4[2], &guid.Data4[3], + &guid.Data4[4], &guid.Data4[5], &guid.Data4[6], &guid.Data4[7]); + return guid; +} + +std::string GuidToString(const GUID& guid) +{ + char guid_cstr[39]; + snprintf(guid_cstr, sizeof(guid_cstr), + "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + + return std::string(guid_cstr); +} + + +std::string Format(const char* arg, ...) +{ + std::string result; + char Buff[10000]; + + va_list argptr; + va_start(argptr, arg); + vsnprintf(Buff, 10000, arg, argptr); + va_end(argptr); + + result = Buff; + + return result; +} + + +const std::string WHITESPACE = " \n\r\t\f\v"; + +std::string ltrim(const std::string& s) +{ + size_t start = s.find_first_not_of(WHITESPACE); + return (start == std::string::npos) ? "" : s.substr(start); +} + +std::string rtrim(const std::string& s) +{ + size_t end = s.find_last_not_of(WHITESPACE); + return (end == std::string::npos) ? "" : s.substr(0, end + 1); +} + +std::string trim(const std::string& s) { + return rtrim(ltrim(s)); +} + +void Move2(pIntegerArray Source, pIntegerArray Dest, int Count) +{ + int myCount = Count / sizeof(longInt); + for (int idx = 0; idx < myCount; idx++) + Dest[idx] = Source[idx]; +} + +void val(std::string S, double* result, int* Code) +{ + S = trim(S); + double myNum = 0; + bool HasLettrs = false; + try + { + myNum = stod(S); + // if everything was OK, then check again for no numeric chars + // otherwise it will jump into the exception + HasLettrs = (S[S.size() - 1] > 57) || (S[S.size() - 1] < 44); + + if (HasLettrs) + {// It has a letter at the end + *result = 0; + *Code = 1; + } + else + { + *result = myNum; + *Code = 0; + } + } + catch (...) + { + *result = 0; + *Code = 1; + } +} + +int MaxIntValue(std::vector < int > * myarray) +{ + int i; + + // Initialize maximum element + int max = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current max + for (i = 0; i < ((*myarray).size() - 1); i++) + if ((*myarray)[i] > max) + max = (*myarray)[i]; + + return max; +} + +int MinIntValue(std::vector < int >* myarray) +{ + int i; + + // Initialize maximum element + int min = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current min + for (i = 0; i < ((*myarray).size() - 1); i++) + if ((*myarray)[i] < min) + min = (*myarray)[i]; + + return min; +} + +double MaxValue(std::vector * myarray) +{ + int i; + + // Initialize maximum element + double max = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current max + for (i = 1; i < myarray->size(); i++) + if ((*myarray)[i] > max) + max = (*myarray)[i]; + + return max; +} + + +double MinValue(std::vector * myarray) +{ + int i; + + // Initialize maximum element + double min = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current min + for (i = 0; i < ((*myarray).size() - 1); i++) + if ((*myarray)[i] < min) + min = (*myarray)[i]; + + return min; +} + +float MaxValue(std::vector * myarray) +{ + int i; + + // Initialize maximum element + float max = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current max + for (i = 0; i < ((*myarray).size() - 1); i++) + if ((*myarray)[i] > max) + max = (*myarray)[i]; + + return max; +} + + +float MinValue(std::vector * myarray) +{ + int i; + + // Initialize maximum element + float min = (*myarray)[0]; + + // Traverse array elements + // from second and compare + // every element with current min + for (i = 0; i < ((*myarray).size() - 1); i++) + if ((*myarray)[i] < min) + min = (*myarray)[i]; + + return min; +} + +int FindInStrVector(std::vector* myarray, std::string myValue) +{ + int idx = -1; + for (int i = 0; i < myarray->size(); i++) + if ((*myarray)[i] == myValue) + { + idx = i; + break; + } + return idx; +} +int Find(std::vector* myarray, int myvalue) +{ + int idx = -1; + for (int i = 0; i < myarray->size(); i++) + if ((*myarray)[i] == myvalue) + { + idx = i; + break; + } + return idx; +} + + +std::string* Slice(std::string* myArray, int mySlice) +{ + std::string* myCopy = new std::string[mySlice]; + if (myCopy != NULL) + { + for(int j = 0; j < mySlice ; j++) + myCopy[j] = myArray[j]; + } + + return myCopy; +} + +wchar_t* Str2WChar(std::string s) +{ + wchar_t* wide_string = new wchar_t[s.length() + 1]; + std::copy(s.begin(), s.end(), wide_string); + wide_string[s.length()] = 0; + + return wide_string; +} + +bool ASSIGNED(void* myPtr) +{ + bool result = ( myPtr != NULL ); + + return result; +} + +std::string ToUpperCaseStr(const std::string &myString) +{ + std::string myUpString = myString; + transform(myUpString.begin(), myUpString.end(), myUpString.begin(), ::toupper); + return myUpString; +} + +std::string ToLowerCaseStr(const std::string &myString) +{ + std::string myUpString = myString; + transform(myUpString.begin(), myUpString.end(), myUpString.begin(), ::tolower); + return myUpString; +} + +double Random() +{ + double myRandNum = ((double)rand()) / ((double)RAND_MAX); + return myRandNum; +} + +double sqr(double myNumber) +{ + return pow(myNumber, 2); +} + +void SaveStrArr2File(vector * myStrVector, std::string myPath) +{ + TTextRec F; + int i; + AssignFile(F, myPath); + Rewrite(F); + + for (i = 0; i < myStrVector->size(); i++) + { + System::WriteLn(F, (*myStrVector)[i]); + } + CloseFile(F); +} + +int mean(std::vector < int >* myarray) +{ + int i; + int accumulator = 0; + + for (i = 0; i < myarray->size(); i++) + accumulator = accumulator + (*myarray)[i]; + accumulator = accumulator / myarray->size(); + + return accumulator; +} + +double mean(std::vector < double > myarray) +{ + int i; + double accumulator = 0; + + for (i = 0; i < myarray.size(); i++) + accumulator = accumulator + (myarray)[i]; + accumulator = accumulator / myarray.size(); + + return accumulator; +} + +float mean(std::vector < float >* myarray) +{ + int i; + float accumulator = 0; + + for (i = 0; i < myarray->size(); i++) + accumulator = accumulator + (*myarray)[i]; + accumulator = accumulator / myarray->size(); + + return accumulator; +} + +int Length(vector < TCmplx_Data >* myPtr) +{ + return (int) myPtr->size(); +} + +int Length(std::string myStr) +{ + return (int) myStr.size(); +} + +int ansipos(std::string myChar, std::string mySrc) +{ + int myidx = mySrc.find(myChar); + return myidx; +} + +double Sqr(double myNum) +{ + double result = myNum * myNum; + return result; +} + +std::vector Copy(std::vector myArray) +{ + std::vector result; + result.clear(); + + for (int i = 0; i < myArray.size(); i++) + result.push_back((myArray)[i]); + + return result; +} + +pDoubleArray Copy(pDoubleArray myArray) +{ + double* result; + result = new double[sizeof(myArray)]; + + for (int i = 0; i < sizeof(myArray); i++) + result[i] = myArray[i]; + + return result; +} + +double Sign(double myNum) +{ + double result; + if (myNum == 0) + result = 0; + else if (myNum > 0) + result = 1; + else + result = -1; + return result; +} + +void Val(std::string myStr, int* myVal, int myCode) +{ + *myVal = stoi(myStr); +} + +void Val(std::string myStr, double* myVal, int myCode) +{ + *myVal = stod(myStr); +} + +//========================================================================= + +void TMemoryStream::Write(int* value, int offset) +{ + uint8_t myBytes[4]; + int IntVar = 0; + + bool OW = true; + if ( ( myPos + (sizeof(int) ) >= myMStrm.size() ) ) + OW = false; + + IntVar = *value; + memcpy(&myBytes, &IntVar, sizeof(int)); + + for (int i = 0; i < (sizeof(int)); i++) + { + if (OW) + myMStrm[myPos] = myBytes[i]; + else + myMStrm.push_back(myBytes[i]); + ++myPos; + } +} + +void TMemoryStream::Write(AnsiChar* value, int offset) +{ + bool OW = true; + if ((myPos + (256) > myMStrm.size())) + OW = false; + + for (int i = 0; i < (256); i++) + { + static_assert(sizeof(uint8_t) == sizeof(AnsiChar), "Wrong uint8_t size!"); + if (OW) + myMStrm[myPos] = value[i]; + else + myMStrm.push_back(value[i]); + ++myPos; + } +} + +void TMemoryStream::Write(std::vector * value, int offset) +{ + + uint8_t myBytes[4]; + float Fvar; + + bool OW = true; + if ((myPos + ( sizeof( value[0] ) * offset) > myMStrm.size())) + OW = false; + + for (int i = 0; i < offset; i++) + { + Fvar = (*value)[i]; + memcpy(&myBytes, &Fvar, 4); + + for (int j = 0; j < sizeof(float); j++) + { + if (OW) + myMStrm[myPos] = myBytes[j]; + else + myMStrm.push_back(myBytes[j]); + ++myPos; + } + } +} + +void TMemoryStream::Write(float* value, int offset) +{ + uint8_t myBytes[4]; + + float Fvar; + + bool OW = true; + if ((myPos + (sizeof(value[0]) - offset) > myMStrm.size())) + OW = false; + + + Fvar = *value; + memcpy(&myBytes, &Fvar, 4); + + for (int j = 0; j < sizeof(float); j++) + { + if (OW) + myMStrm[myPos] = myBytes[j]; + else + myMStrm.push_back(myBytes[j]); + ++myPos; + } + +} + +int TMemoryStream::Read(int* value) +{ + unsigned char bytes[sizeof(int)]; + int myInit = myPos; + int myValue; + + for (int i = 0; i < sizeof(int); i++) + { + bytes[i] = (unsigned char) myMStrm[myPos]; + myPos++; + } + + std::memcpy(&myValue, bytes, sizeof(int)); + *value = myValue; + + return (myPos - myInit); +} + +int TMemoryStream::Read(unsigned int* value) +{ + int myInit = myPos; + unsigned int myValue = 0; + + unsigned char bytes[sizeof(unsigned int)]; + for (int i = 0; i < sizeof(unsigned int); i++) + { + bytes[i] = (unsigned char) myMStrm[myPos]; + myPos++; + } + + std::memcpy(&myValue, bytes, sizeof(unsigned int)); + + *value = myValue; + + return (myPos - myInit); +} + +int TMemoryStream::Read(float* value) +{ + int myInit = myPos; + + unsigned char bytes[sizeof(float)]; + for (int i = 0; i < sizeof(float); i++) + { + bytes[i] = (unsigned char) myMStrm[myPos]; + myPos++; + } + + std::memcpy(value, bytes, sizeof(unsigned int)); + + return (myPos - myInit); +} + +int TMemoryStream::Read(float* value, int Size) +{ + int myInit = myPos; + unsigned char bytes[sizeof(float)]; + int NumRegs = (int)(Size / sizeof(float)); + + for (int j = 0; j < NumRegs; j++) + { + for (int i = 0; i < sizeof(float); i++) + { + bytes[i] = (unsigned char)myMStrm[myPos]; + myPos++; + } + + std::memcpy(&(value[j]), bytes, sizeof(unsigned int)); + } + + return (myPos - myInit); +} + +//-------------------------------------------------------------------------------------- + +int IntPower(int Base, int exponent) +{ + int result = 0; + result = (int)pow(Base, exponent); + return result; +} + +int IntPower(double Base, int exponent) +{ + int result = 0; + result = (int)pow(Base, exponent); + return result; +} +//-------------------------------------------------------------------------------------- + + +int TMemoryStream::Read(double* value, int Size) +{ + int myInit = myPos; + unsigned char bytes[sizeof(double)]; + int NumRegs = (int)(Size / sizeof(double)); + + for (int j = 0; j < NumRegs; j++) + { + for (int i = 0; i < sizeof(double); i++) + { + bytes[i] = (unsigned char)myMStrm[myPos]; + myPos++; + } + + std::memcpy(&(value[j]), bytes, sizeof(unsigned int)); + } + + return (myPos - myInit); +} + +int TMemoryStream::Read(int* value, int Size) +{ + int myInit = myPos; + unsigned char bytes[sizeof(float)]; + int NumRegs = (int)(Size / sizeof(int)); + + for (int j = 0; j < NumRegs; j++) + { + for (int i = 0; i < sizeof(float); i++) + { + bytes[i] = (unsigned char)myMStrm[myPos]; + myPos++; + } + + std::memcpy(&(value[j]), bytes, sizeof(unsigned int)); + } + + return (myPos - myInit); +} + +int TMemoryStream::Read(uint8_t* value, int Size) +{ + int myInit = myPos; + int NumRegs = Size; + int MaxPos = myMStrm.size(); + + for (int j = 0; j < NumRegs; j++) + { + if (myPos < MaxPos) + { + value[j] = myMStrm[myPos]; + myPos++; + } + } + return (myPos - myInit); +} + + +int TMemoryStream::Read(AnsiChar* value) +{ + int myInit = myPos; + + for (int i = 0; i < 256; i++) + { + static_assert(sizeof(uint8_t) == sizeof(AnsiChar), "Wrong uint8_t size!"); + value[i] = AnsiChar(myMStrm[myPos]); + myPos++; + } + + return (myPos - myInit); +} + + +int TMemoryStream::begin() +{ + myPos = 0; + return myPos; +} + +int TMemoryStream::end() +{ + myPos = myMStrm.size() - 1; + return myPos; +} + +int TMemoryStream::Position() +{ + return myPos; +} + +int TMemoryStream::Size() +{ + return myMStrm.size(); +} + +void TMemoryStream::clear() +{ + myMStrm.clear(); + myPos = 0; +} + +//========================================================================= + +void TBytesStream::Write(int* value, int offset) +{ + bool OW = true; + if ((myPos + (sizeof(*value)) > myMStrm.size())) + OW = false; + + for (int i = 0; i < (sizeof(*value)); i++) + if (OW) + { + myMStrm[myPos] = (*value >> (i * 8)); + myPos++; + } + else + myMStrm.push_back(*value >> (i * 8)); + +} + +void TBytesStream::Write(AnsiChar* value, int offset) +{ + bool OW = true; + if ((myPos + (256) > myMStrm.size())) + OW = false; + + for (int i = 0; i < (256); i++) + if (OW) + { + myMStrm[myPos] = value[i]; + myPos++; + } + else + myMStrm.push_back(value[i]); +} + +void TBytesStream::Write(pSingleArray value, int offset) +{ + uint32_t value2; + + bool OW = true; + if ((myPos + (sizeof((value)[0]) * sizeof(value) - offset) > myMStrm.size())) + OW = false; + + for (int i = offset; i < sizeof(value); i++) + { + value2 = (uint32_t)(value)[i]; + + for (int j = 0; j < sizeof(value2); j++) + if (OW) + { + myMStrm[myPos] = value2 >> (j * 8); + myPos++; + } + else + myMStrm.push_back(value2 >> (j * 8)); + } +} + +int TBytesStream::Read(unsigned char* value, int count) +{ + int myInit = myPos; + + *value = (unsigned char)myMStrm[myPos]; + + return (myPos - myInit); +} + +int TBytesStream::ReadData(double* value, int count) +{ + int myInit = myPos; + float myData = 0; + + unsigned char bytes[sizeof(float)]; + for (int i = 0; i < sizeof(float); i++) + { + bytes[i] = (unsigned char)myMStrm[myPos]; + myPos++; + } + + std::memcpy(&myData, bytes, sizeof(float)); + *value = (double) myData; + + return (myPos - myInit); +} + + +int TBytesStream::begin() +{ + myPos = 0; + return myPos; +} + +int TBytesStream::end() +{ + myPos = myMStrm.size() - 1; + return myPos; +} + +int TBytesStream::Position() +{ + return myPos; +} + +int TBytesStream::Size() +{ + return (int) myMStrm.size(); +} + +void TBytesStream::clear() +{ + myMStrm.clear(); + myPos = 0; +} + +int TBytesStream::WriteData(int16_t Value) +{ + int myInit = myPos; + + unsigned char bytes[sizeof(int16_t)]; + + memcpy(&bytes, &Value, sizeof(int16_t)); + + for (int i = 0; i < sizeof(int16_t); i++) + { + myMStrm.push_back(bytes[i]); + myPos++; + } + + + + return (myPos - myInit); +} + +int TBytesStream::WriteData(char Value) +{ + int myInit = myPos; + + myMStrm.push_back((uint8_t)Value); + myPos++; + + + + + return (myPos - myInit); +} + +int TBytesStream::WriteData(float Value) +{ + int myInit = myPos; + + unsigned char bytes[sizeof(float)]; + + memcpy(&bytes, &Value, sizeof(float)); + + for (int i = 0; i < sizeof(float); i++) + { + myMStrm.push_back(bytes[i]); + myPos++; + } + + return (myPos - myInit); +} + +//========================================================================== + +TPerlRegExOptions TPerlRegEx::get_FOptions() +{ + return FOptions; +} + +void TPerlRegEx::set_Options(TPerlRegExOptions value) +{ + if (FOptions != value) + { + + } +} + +std::string TPerlRegEx::get_FRegEx() +{ + return FRegEx; +} + +void TPerlRegEx::set_FRegEx(std::string value) +{ + FRegEx = value; +} + +std::string TPerlRegEx::get_mySubject() +{ + return mySubject; +} + +void TPerlRegEx::set_mySubject(std::string value) +{ + mySubject = value; +} + +bool TPerlRegEx::Match() +{ + bool result = false; + + std::string exp1 = ToLowerCaseStr(mySubject); + std::string exp2 = ToLowerCaseStr(FRegEx); + if (exp2 == ".*") + result = true; + else + result = ( exp1 == exp2 ); + + return result; +} + +//=================================================================================== + +std::string PadRight(int myNum, std::string myChar) +{ + std::string result; + for (int i = 0; i < myNum; i++) + result = result + myChar; + return result; +} + +void CoutLn(std::string myStr) +{ + if (NoFormsAllowed) + return; + cout << myStr; + cout << "\n"; +} diff --git a/OpenDSSC/Support/d2c_structures.h b/OpenDSSC/Support/d2c_structures.h new file mode 100644 index 0000000..2f4712d --- /dev/null +++ b/OpenDSSC/Support/d2c_structures.h @@ -0,0 +1,246 @@ +#ifndef d2c_structuresH +#define d2c_structuresH + + +/* + ---------------------------------------------------------- + Copyright (c) 2008-2022, Electric Power Research Institute, Inc. + All rights reserved. + ---------------------------------------------------------- + + library tcreated to complement the missing units or function equivalent in Delphi + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include // uint8_t +#include +#include +#include +#include "Sysutils.h" +#include "Arraydef.h" +#include "Sparse_Math.h" + + +using namespace std; + +typedef std::vector TStringList; +typedef std::vector< void* > TList; +typedef TTextRec Textfile; +typedef std::thread TThread; +typedef int TFontStyles; +#ifdef linux +typedef int32_t int32; +typedef int32_t TEvent; +typedef int8_t DynamicArrayByte; +#else +typedef __int32 int32; +typedef __int32 TEvent; +typedef __int8* DynamicArrayByte; +#endif +typedef char* pUTF8Char; +typedef wchar_t WideChar; + +#ifndef _WIN32 +typedef struct _GUID { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} GUID; +#endif + +GUID StringToGuid(const std::string& str); +std::string GuidToString(const GUID& guid); +void val(std::string S, double* result, int* Code); + +//----------------------------------------------------------------------------------- + +int MaxIntValue(std::vector < int >* myarray); +int MinIntValue(std::vector < int >* myarray); +double MaxValue(std:: vector * myarray); +double MinValue(std::vector * myarray); +float MaxValue(std::vector * myarray); +float MinValue(std::vector * myarray); + +//----------------------------------------------------------------------------------- + +int mean(std::vector < int >* myarray); +double mean(std::vector < double >* myarray); +float mean(std::vector < float >* myarray); + +//----------------------------------------------------------------------------------- + +std::string* Slice(std::string* myArray, int mySlice); +wchar_t* Str2WChar(std::string s); +bool ASSIGNED(void* myPtr); +double sqr(double myNumber); +std::string ToUpperCaseStr(const std::string &myString); +std::string ToLowerCaseStr(const std::string &myString); +void SaveStrArr2File(vector * myStrVector, std::string myPath); + +double Random(); + +int FindInStrVector(std::vector* myarray, std::string myValue); +int Find(std::vector* myarray, int myvalue); + + + +//-------------------------------------------------------------------------------------- + +int Length(std::vector < TCmplx_Data >* myPtr); +int Length(std::string myStr); + +int ansipos(std::string myChar, std::string mySrc); + +double Sqr(double myNum); + +double Sign(double myNum); + +//-------------------------------------------------------------------------------------- + +std::vector Copy(std::vector myArray); + +pDoubleArray Copy(pDoubleArray myArray); + +void Val(std::string myStr, int* myVal, int myCode); + +void Val(std::string myStr, double* myVal, int myCode); + +void Move2(pIntegerArray Source, pIntegerArray Dest, int Count); + +std::string Format(const char* arg, ...); //override + +//-------------------------------------------------------------------------------------- + +int IntPower(int Base, int exponent); + +int IntPower(double Base, int exponent); + +//-------------------------------------------------------------------------------------- + +class TMemoryStream +{ +public: + //-------------------------------------------------------------------------------------- + int myPos; + std::vector myMStrm; + + int begin(); // sets the pointer at the beginning + int end(); // sets the pointer at the end + int Position(); // returns the pointer's location + void clear(); + int Size(); + + void Write(int* value, int offset=0); + void Write(AnsiChar* value, int offset = 0); + void Write(std::vector * value, int offset = 0); + void Write(float* value, int offset = 0); + + //-------------------------------------------------------------------------------------- + + int Read(int* value); + int Read(unsigned int* value); + int Read(float* value); + int Read(float* value, int Size); + int Read(double* value, int Size); + int Read(int* value, int Size); + int Read(uint8_t* value, int Size); +// int Read(float value[100]); + + int Read(AnsiChar* value); + + //-------------------------------------------------------------------------------------- + +}; + +class TBytesStream +{ +public: + //-------------------------------------------------------------------------------------- + int myPos; + std::vector myMStrm; + + int begin(); // sets the pointer at the beginning + int end(); // sets the pointer at the end + int Position(); // returns the pointer's location + void clear(); + int Size(); + + void Write(int* value, int offset = 0); + void Write(AnsiChar* value, int offset = 0); + void Write(pSingleArray value, int offset = 0); + + int WriteData(int16_t Value); + int WriteData(char Value); + int WriteData(float Value); + + //-------------------------------------------------------------------------------------- + + int Read(unsigned char* value, int count); + + int ReadData(double* value, int count); + + //-------------------------------------------------------------------------------------- +}; + +//=========================================================================================== + +enum TPerlRegExOptions +{ + preCaseLess, // /i -> Case insensitive + preMultiLine, // /m -> ^ and $ also match before/after a newline, not just at the beginning and the end of the string + preSingleLine, // /s -> Dot matches any character, including \n (newline). Otherwise, it matches anything except \n + preExtended, // /x -> Allow regex to contain extra whitespace, newlines and Perl-style comments, all of which will be filtered out + preAnchored, // /A -> Successful match can only occur at the start of the subject or right after the previous match + preUnGreedy, // Repeat operators (+, *, ?) are not greedy by default (i.e. they try to match the minimum number of characters instead of the maximum) + preNoAutoCapture +}; + +enum TPerlRegExState +{ + preNotBOL, // Not Beginning Of Line: ^ does not match at the start of Subject + preNotEOL, // Not End Of Line: $ does not match at the end of Subject + preNotEmpty // Empty matches not allowed +}; + +class TPerlRegEx +{ +public: + bool FCompiled, FStudied; + TPerlRegExOptions FOptions; + TPerlRegExState FState; + std::string FRegEx, mySubject; +// PCREString FReplacement; +// PCREString FSubject; + int FStart, FStop; + + + TPerlRegExOptions get_FOptions(); + void set_Options(TPerlRegExOptions value); + + std::string get_FRegEx(); + void set_FRegEx(std::string value); + + std::string get_mySubject(); + void set_mySubject(std::string value); + + bool Match(); + +}; + +//====================================================================================== + +std::string PadRight(int myNum, std::string myChar); + +void CoutLn(std::string myStr); + + +#endif // d2c_structures diff --git a/OpenDSSC/Support/d2c_sysconst.h b/OpenDSSC/Support/d2c_sysconst.h new file mode 100644 index 0000000..aec89b1 --- /dev/null +++ b/OpenDSSC/Support/d2c_sysconst.h @@ -0,0 +1,216 @@ + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#ifndef d2c_sysconstH +#define d2c_sysconstH + + +namespace System +{ +// made with SysConst.ttp +#define SysConst_SAbortError "Operation aborted" +#define SysConst_SAbstractError "Abstract method called" +#define SysConst_SAccessDenied "Access denied" +#define SysConst_SAccessViolation "Access violation" +#define SysConst_SArgumentMissing "Missing argument in format \"%s\"" +#define SysConst_SAssertError "%s (%s, line %d)" +#define SysConst_SAssertionFailed "Assertion failed" +#define SysConst_SBusError "Bus error or misaligned data access" +#define SysConst_SCannotCreateEmptyDir "Cannot create empty directory" +#define SysConst_SControlC "Control-C hit" +#define SysConst_SDiskFull "Disk Full" +#define SysConst_SDispatchError "No variant method call dispatch" +#define SysConst_SDivByZero "Division by zero" +#define SysConst_SEndOfFile "Read past end of file" +#define SysConst_SErrInvalidDateMonthWeek "Year %d, month %d, Week %d and day %d is not a valid date." +#define SysConst_SErrInvalidDateWeek "%d %d %d is not a valid dateweek" +#define SysConst_SErrInvalidDayOfWeek "%d is not a valid day of the week" +#define SysConst_SErrInvalidDayOfWeekInMonth "Year %d Month %d NDow %d DOW %d is not a valid date" +#define SysConst_SErrInvalidDayOfYear "Year %d does not have a day number %d" +#define SysConst_SErrInvalidTimeStamp "Invalid date/timestamp : \"%s\"" +#define SysConst_SExceptionErrorMessage "exception at %p" +#define SysConst_SExceptionStack "Exception stack error" +#define SysConst_SExecuteProcessFailed "Failed to execute \"%s\", error code: %d" +#define SysConst_SExternalException "External exception %x" +#define SysConst_SFileNotAssigned "File not assigned" +#define SysConst_SFileNotFound "File not found" +#define SysConst_SFileNotOpen "File not open" +#define SysConst_SFileNotOpenForInput "File not open for input" +#define SysConst_SFileNotOpenForOutput "File not open for output" +#define SysConst_SInValidFileName "Invalid filename" +#define SysConst_SIntOverflow "Arithmetic overflow" +#define SysConst_SIntfCastError "Interface not supported" +#define SysConst_SInvalidArgIndex "Invalid argument index in format \"%s\"" +#define SysConst_SInvalidBoolean "\"%s\" is not a valid boolean." +#define SysConst_SInvalidCast "Invalid type cast" +#define SysConst_SinvalidCurrency "Invalid Currency: \"%s\"" +#define SysConst_SInvalidDateTime "%f is not a valid date/time value." +#define SysConst_SInvalidDrive "Invalid drive specified" +#define SysConst_SInvalidFileHandle "Invalid file handle" +#define SysConst_SInvalidFloat "\"%s\" is an invalid float" +#define SysConst_SInvalidFormat "Invalid format specifier : \"%s\"" +#define SysConst_SInvalidGUID "\"%s\" is not a valid TGUID value" +#define SysConst_SInvalidInput "Invalid input" +#define SysConst_SInvalidInteger "\"%s\" is an invalid integer" +#define SysConst_SInvalidOp "Invalid floating point operation" +#define SysConst_SInvalidPointer "Invalid pointer operation" +#define SysConst_SInvalidVarCast "Invalid variant type cast" +#define SysConst_SInvalidvarNullOp "Invalid NULL variant operation" +#define SysConst_SInvalidVarOp "Invalid variant operation" +#define SysConst_SInvalidBinaryVarOp "Invalid variant operation %s %s %s" +#define SysConst_SInvalidUnaryVarOp "Invalid variant operation %s %s" +#define SysConst_SInvalidVarOpWithHResultWithPrefix "Invalid variant operation (%s%.8x)" +#define SysConst_SNoError "No error." +#define SysConst_SNoThreadSupport "Threads not supported. Recompile program with thread driver." +#define SysConst_SMissingWStringManager "Widestring manager not available. Recompile program with appropiate manager." +#define SysConst_SOSError "System error, (OS Code %d):" +#define SysConst_SOutOfMemory "Out of memory" +#define SysConst_SOverflow "Floating point overflow" +#define SysConst_SPrivilege "Privileged instruction" +#define SysConst_SRangeError "Range check error" +#define SysConst_SSafecallException "Exception in safecall method" +#define SysConst_SiconvError "iconv error" +#define SysConst_STooManyOpenFiles "Too many open files" +#define SysConst_SUnKnownRunTimeError "Unknown Run-Time error : %3.3d" +#define SysConst_SUnderflow "Floating point underflow" +#define SysConst_SUnkOSError "An operating system call failed." +#define SysConst_SUnknown "Unknown run-time error code: " +#define SysConst_SUnknownErrorCode "Unknown error code: %d" +#define SysConst_SVarArrayBounds "Variant array bounds error" +#define SysConst_SVarArrayCreate "Variant array cannot be created" +#define SysConst_SVarArrayLocked "Variant array locked" +#define SysConst_SVarBadType "Invalid variant type" +#define SysConst_SVarInvalid "Invalid argument" +#define SysConst_SVarInvalid1 "Invalid argument: %s" +#define SysConst_SVarNotArray "Variant doesn't contain an array" +#define SysConst_SVarNotImplemented "Operation not supported" +#define SysConst_SVarOutOfMemory "Variant operation ran out memory" +#define SysConst_SVarOverflow "Variant overflow" +#define SysConst_SVarParamNotFound "Variant Parameter not found" +#define SysConst_SVarTypeAlreadyUsedWithPrefix "Custom variant type (%s%.4x) already used by %s" +#define SysConst_SVarTypeConvertOverflow "Overflow while converting variant of type (%s) into type (%s)" +#define SysConst_SVarTypeCouldNotConvert "Could not convert variant of type (%s) into type (%s)" +#define SysConst_SVarTypeNotUsableWithPrefix "Custom variant type (%s%.4x) is not usable" +#define SysConst_SVarTypeOutOfRangeWithPrefix "Custom variant type (%s%.4x) is out of range" +#define SysConst_SVarTypeRangeCheck1 "Range check error for variant of type (%s)" +#define SysConst_SVarTypeRangeCheck2 "Range check error while converting variant of type (%s) into type (%s)" +#define SysConst_SVarTypeTooManyCustom "Too many custom variant types have been registered" +#define SysConst_SVarUnexpected "Unexpected variant error" +#define SysConst_SFallbackError "An error, whose error code is larger than can be returned to the OS, has occured" +#define SysConst_SNoToolserver "Toolserver is not installed, cannot execute Tool" +#define SysConst_SNoArrayMatch "Can't match any allowed value at pattern position %d, string position %d." +#define SysConst_SNoCharMatch "Mismatch char \"%s\" <> \"%s\" at pattern position %d, string position %d." +#define SysConst_Shhmmerror "mm in a sequence hh:mm is interpreted as minutes. No longer versions allowed! (Position : %d)." +#define SysConst_SFullpattern "Couldn't match entire pattern string. Input too short at pattern position %d." +#define SysConst_SPatternCharMismatch "Pattern mismatch char \"%s\" at position %d." +#define SysConst_SShortMonthNameJan "Jan" +#define SysConst_SShortMonthNameFeb "Feb" +#define SysConst_SShortMonthNameMar "Mar" +#define SysConst_SShortMonthNameApr "Apr" +#define SysConst_SShortMonthNameMay "May" +#define SysConst_SShortMonthNameJun "Jun" +#define SysConst_SShortMonthNameJul "Jul" +#define SysConst_SShortMonthNameAug "Aug" +#define SysConst_SShortMonthNameSep "Sep" +#define SysConst_SShortMonthNameOct "Oct" +#define SysConst_SShortMonthNameNov "Nov" +#define SysConst_SShortMonthNameDec "Dec" +#define SysConst_SLongMonthNameJan "January" +#define SysConst_SLongMonthNameFeb "February" +#define SysConst_SLongMonthNameMar "March" +#define SysConst_SLongMonthNameApr "April" +#define SysConst_SLongMonthNameMay "May" +#define SysConst_SLongMonthNameJun "June" +#define SysConst_SLongMonthNameJul "July" +#define SysConst_SLongMonthNameAug "August" +#define SysConst_SLongMonthNameSep "September" +#define SysConst_SLongMonthNameOct "October" +#define SysConst_SLongMonthNameNov "November" +#define SysConst_SLongMonthNameDec "December" +#define SysConst_SShortDayNameMon "Mon" +#define SysConst_SShortDayNameTue "Tue" +#define SysConst_SShortDayNameWed "Wed" +#define SysConst_SShortDayNameThu "Thu" +#define SysConst_SShortDayNameFri "Fri" +#define SysConst_SShortDayNameSat "Sat" +#define SysConst_SShortDayNameSun "Sun" +#define SysConst_SLongDayNameMon "Monday" +#define SysConst_SLongDayNameTue "Tuesday" +#define SysConst_SLongDayNameWed "Wednesday" +#define SysConst_SLongDayNameThu "Thursday" +#define SysConst_SLongDayNameFri "Friday" +#define SysConst_SLongDayNameSat "Saturday" +#define SysConst_SLongDayNameSun "Sunday" + + +} // namespace System + + +#endif // d2c_sysconstH \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_syscurr.cpp b/OpenDSSC/Support/d2c_syscurr.cpp new file mode 100644 index 0000000..97bc714 --- /dev/null +++ b/OpenDSSC/Support/d2c_syscurr.cpp @@ -0,0 +1,172 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +#include "d2c_syscurr.h" +#include "d2c_sysconst.h" +#include "d2c_sysexcept.h" +#include "Sysutils.h" +#include "d2c_sysexcept.h" + + +using namespace System; + +Currency MinCurrency = - 922337203685477.0000; +Currency MaxCurrency = 922337203685477.0000; + +Currency::Currency() + : Val(0) {} + +Currency::Currency(double val) +{ + Val = static_cast(10000 * val); +} + +Currency::Currency(int val) +{ + Val = 10000*(int64_t)val; +} + +Currency::Currency(const Currency& src) +{ + Val = src.Val; +} + +Currency::Currency(const String& src) +{ + *this = StrToCurr( src ); +} + +Currency& Currency::operator =(double rhs) +{ + Val = static_cast(10000 * rhs); + return *this; +} + +Currency& Currency::operator =(int rhs) +{ + Val = 10000*(int64_t) rhs; + return *this; +} + +Currency& Currency::operator =(const Currency& rhs) +{ + Val = rhs.Val; + return *this; +} + +Currency Currency::operator -() const +{ + Currency tmp(*this); + tmp.Val = -(tmp.Val); + return tmp; +} + +Currency::operator double() const +{ + return ((double)Val) / 10000; +} + +Currency::operator int() const +{ + return (int) (Val / 10000); +} + + +Currency StrToCurr( const String& S ) +{ + Currency result; + if ( ! TextToFloat( (Char*) ( ((void*) S.c_str()) ), &result, fvCurrency ) ) +// throw EConvertError( _T(SysConst_SInvalidFloat), ARRAYOFCONST( S )); + throw EConvertError( ErrorString(_T(SysConst_SInvalidFloat), S )); + return result; +} + + +bool TryStrToCurr( const String& S, Currency& Value ) +{ + return TextToFloat( (Char*) ( ((void*) S.c_str()) ), &Value, fvCurrency ); +} + + +Currency StrToCurrDef( const String& S, Currency deflt ) +{ + Currency result; + if ( ! TextToFloat( (Char*) ( ((void*) S.c_str()) ), &result, fvCurrency ) ) + result = deflt; + return result; +} + + +String CurrToStr( Currency Value ) +{ + return FloatToStrF( Value, ffGeneral, - 1, 0 ); +} + + diff --git a/OpenDSSC/Support/d2c_syscurr.h b/OpenDSSC/Support/d2c_syscurr.h new file mode 100644 index 0000000..2b1453a --- /dev/null +++ b/OpenDSSC/Support/d2c_syscurr.h @@ -0,0 +1,106 @@ +#ifndef d2c_syscurrH +#define d2c_syscurrH + + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_systypes.h" + + +class Currency +{ +public: + Currency(); + Currency(double val); + Currency(int val); + Currency(const Currency& src); + Currency(const String& src); + + Currency& operator =(double rhs); + Currency& operator =(int rhs); + Currency& operator =(const Currency& rhs); + + Currency operator -() const; + + operator double() const; + operator int() const; + +private: + int64_t Val; +}; + + +typedef Currency* PCurrency; + + +Currency StrToCurr( const String& S ); +String CurrToStr( Currency Value ); + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_sysdate.cpp b/OpenDSSC/Support/d2c_sysdate.cpp new file mode 100644 index 0000000..99da11a --- /dev/null +++ b/OpenDSSC/Support/d2c_sysdate.cpp @@ -0,0 +1,1562 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_sysdate.h" +#include "d2c_system.h" +#include "d2c_sysmath.h" +#include "Sysutils.h" +#include "d2c_sysexcept.h" +#include "d2c_sysconst.h" +#include "d2c_sysstring.h" +#include + +#ifdef linux +#include +#include +#endif + +#undef max + +using namespace System; +using namespace std; + + +typedef WORD *PDayTable; +typedef WORD TDayTable [ 12/*# range 1..12*/ ]; + + +//const int64_t UnixDateDelta = Trunc( UnixEpoch ); //25569 + + + /* True=Leapyear */ + +extern TDayTable MonthDays [ 2 /*# Boolean */ ]; + + +TDayTable MonthDays [ 2 /*# Boolean */ ]; +void MonthDaysInit( ) +{ + MonthDays[0][0] = 31; + MonthDays[0][1] = 28; + MonthDays[0][2] = 31; + MonthDays[0][3] = 30; + MonthDays[0][4] = 31; + MonthDays[0][5] = 30; + MonthDays[0][6] = 31; + MonthDays[0][7] = 31; + MonthDays[0][8] = 30; + MonthDays[0][9] = 31; + MonthDays[0][10] = 30; + MonthDays[0][11] = 31; + MonthDays[1][0] = 31; + MonthDays[1][1] = 29; + MonthDays[1][2] = 31; + MonthDays[1][3] = 30; + MonthDays[1][4] = 31; + MonthDays[1][5] = 30; + MonthDays[1][6] = 31; + MonthDays[1][7] = 31; + MonthDays[1][8] = 30; + MonthDays[1][9] = 31; + MonthDays[1][10] = 30; + MonthDays[1][11] = 31; +} + +TDateTime MinDateTime = - 693593.0; /* 01/01/0001 12:00:00.000 AM */ +TDateTime MaxDateTime = 2958465.99999; /* 12/31/9999 11:59:59.999 PM */ + + +string DateErrorString( const char* xpFormat, const WORD x1, const WORD x2, const WORD x3, const WORD x4 ) +{ + char buf[1000]; + if(x4 != WORD(-1)) + sprintf(buf, xpFormat, x1, x2, x3, x4); + else + if(x3 != WORD(-1)) + sprintf(buf, xpFormat, x1, x2, x3); + else + sprintf(buf, xpFormat, x1, x2); + return buf; +} + +wstring DateErrorString( const wchar_t* xpFormat, const WORD x1, const WORD x2, const WORD x3, const WORD x4 ) +{ + wchar_t buf[1000]; + if(x4 != WORD(-1)) + swprintf(buf, 999, xpFormat, x1, x2, x3, x4); + else + if(x3 != WORD(-1)) + swprintf(buf, 999, xpFormat, x1, x2, x3); + else + swprintf(buf, 999, xpFormat, x1, x2); + return buf; +} + + +/*==============================================================================*/ +/* Internal functions */ +/*==============================================================================*/ + +#define Sysutils__19 ( TSet < int, 0, 255 >() \ + << int ( 1 ) << int ( 2 ) << int ( 3 ) << int ( 4 ) << int ( 5 ) << int ( 6 ) << int ( 7 ) << int ( 8 ) << int ( 9 ) << int ( 10 ) \ + << int ( 11 ) << int ( 12 ) ) +#define Sysutils__20 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__21 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__22 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__23 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__24 ( TSet < UChar, 0, 255 >() \ + << _T('0') << _T('1') << _T('2') << _T('3') << _T('4') << _T('5') << _T('6') << _T('7') << _T('8') << _T('9') ) +#define Sysutils__25 ( TSet < UChar, 0, 255 >() \ + << _T('a') << _T('A') ) +#define Sysutils__26 ( TSet < UChar, 0, 255 >() \ + << _T('p') << _T('P') ) +#define Sysutils__27 ( TSet < UChar, 0, 255 >() \ + << _T('"') << _T('\'') ) + + +const int LFAI = numeric_limits< WORD >::max(); // less typing, readable Code + +String DoField( WORD arg, WORD def, String Unknown, const WORD& AYear, const WORD& AMonth, const WORD& ADay, const WORD& AHour, const WORD& AMinute, const WORD& ASecond, const WORD& AMilliSecond, const TDateTime& ABaseDate ) +{ + String result; + if ( arg != LFAI ) +// result = Format( _T("%.*d"), ARRAYOFCONST(( Unknown.length(), arg )) ); + result = IntToStr(arg); + else + if ( (double) ABaseDate == 0 ) + result = Unknown; + else + // result = Format( _T("%.*d"), ARRAYOFCONST(( Unknown.length(), arg )) ); + result = IntToStr(arg); + return result; +} + +void InvalidDateTimeError( const WORD AYear, const WORD AMonth, const WORD ADay, const WORD AHour, const WORD AMinute, const WORD ASecond, const WORD AMilliSecond, const TDateTime ABaseDate ) +{ + WORD Y = 0, m = 0, D = 0, h = 0, n = 0, S = 0, MS = 0; + String Msg; + DecodeDateTime( ABaseDate, Y, m, D, h, n, S, MS ); + Msg = DoField( AYear, Y, _T("????"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + DateSeparator + DoField( AMonth, m, _T("??"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + DateSeparator + DoField( ADay, D, _T("??"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + _T(" ") + DoField( AHour, h, _T("??"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + TimeSeparator + DoField( AMinute, n, _T("??"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + TimeSeparator + DoField( ASecond, S, _T("??"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + Msg = Msg + DecimalSeparator + DoField( AMilliSecond, MS, _T("???"), AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, ABaseDate ); + throw EConvertError( ErrorString(_T(SysConst_SErrInvalidTimeStamp), Msg ) ); +} + + +void InvalidDateTimeError( const WORD AYear, const WORD AMonth, const WORD ADay, const WORD AHour, const WORD AMinute, const WORD ASecond, const WORD AMilliSecond ) // const ABaseDate: TDateTime = 0 + +{ + InvalidDateTimeError( AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, 0 ); +} + + +void InvalidDateWeekError( const WORD AYear, const WORD AWeekOfYear, const WORD ADayOfWeek ) +{ +// throw EConvertError( _T(SysConst_SErrInvalidDateWeek), ARRAYOFCONST(( AYear, AWeekOfYear, ADayOfWeek )) ); + throw EConvertError( DateErrorString(_T(SysConst_SErrInvalidDateWeek), AYear, AWeekOfYear, ADayOfWeek, -1 ) ); +} + + +void InvalidDateDayError( const WORD AYear, const WORD ADayOfYear ) +{ + throw EConvertError( DateErrorString(_T(SysConst_SErrInvalidDayOfYear), AYear, ADayOfYear, -1, -1 ) ); +} + + +void InvalidDateMonthWeekError( const WORD AYear, const WORD AMonth, const WORD AWeekOfMonth, const WORD ADayOfWeek ) +{ + throw EConvertError( DateErrorString(_T(SysConst_SErrInvalidDateMonthWeek), AYear, AMonth, AWeekOfMonth, ADayOfWeek ) ); +} + + +void InvalidDayOfWeekInMonthError( const WORD AYear, const WORD AMonth, const WORD ANthDayOfWeek, const WORD ADayOfWeek ) +{ + throw EConvertError( DateErrorString(_T(SysConst_SErrInvalidDayOfWeekInMonth), AYear, AMonth, ANthDayOfWeek, ADayOfWeek ) ); +} + +bool TryEncodeDate( WORD Year, WORD Month, WORD Day, TDateTime& Date ) +{ + bool result = false; + unsigned int C = 0, YA = 0; + result = ( Year > 0 ) && ( Year < 10000 ) && ( Sysutils__19.Contains(Month ) ) && ( Day > 0 ) && ( Day <= MonthDays[IsLeapYear( Year )][ Month - 1] ); // dme Month - 1 + if ( result ) + { + if ( Month > 2 ) + Month -= 3; + else + { + Month += 9; + Year--; + } + C = Year / 100; + YA = Year - 100 * C; + Date = (long double) ( ( 146097 * C ) >> 2 ) + ( ( 1461 * YA ) >> 2 ) + ( 153 * ((unsigned int) Month ) + 2 ) / 5 + ((unsigned int) Day ); + // Note that this Line can'T be part of the Line above, since TDateTime is + // signed and C and YA are not + Date = (double) Date - 693900; + } + return result; +} + + +bool TryEncodeTime( WORD Hour, WORD Min, WORD Sec, WORD MSec, TDateTime& time ) +{ + bool result = false; + result = ( Hour < 24 ) && ( Min < 60 ) && ( Sec < 60 ) && ( MSec < 1000 ); + if ( result ) +// time = ((TDateTime) ( ((unsigned int) Hour ) * 3600000 + ((unsigned int) Min ) * 60000 + ((unsigned int) Sec ) * 1000 + MSec ) ) / MSecsPerDay; + time = ((double) ( ((unsigned int) Hour ) * 3600000 + ((unsigned int) Min ) * 60000 + ((unsigned int) Sec ) * 1000 + MSec ) ) / MSecsPerDay; + return result; +} + + +int DoEncodeDate( WORD Year, WORD Month, WORD Day ) +{ + int result = 0; + TDateTime D = 0.0; + if ( TryEncodeDate( Year, Month, Day, D ) ) + result = (int) Trunc( D ); + else + result = 0; + return result; +} + + +TDateTime DoEncodeTime( WORD Hour, WORD minute, WORD second, WORD millisecond ) +{ + TDateTime result = 0.0; + if ( ! TryEncodeTime( Hour, minute, second, millisecond, result ) ) + result = 0; + return result; +} + +// ComposeDateTime converts A Date and A time into one TDateTime +TDateTime ComposeDateTime( TDateTime Date, TDateTime time ) +{ + TDateTime result = 0.0; + if ( (double) Date < 0 ) + result = Trunc( Date ) - Abs( Frac( time ) ); + else + result = Trunc( Date ) + Abs( Frac( time ) ); + return result; +} + +bool TryEncodeDateTime( const WORD AYear, const WORD AMonth, const WORD ADay, const WORD AHour, const WORD AMinute, const WORD ASecond, const WORD AMilliSecond, TDateTime& AValue ) +{ + bool result = false; + TDateTime tmp = 0.0; + result = TryEncodeDate( AYear, AMonth, ADay, AValue ); + result = result && TryEncodeTime( AHour, AMinute, ASecond, AMilliSecond, tmp ); + if ( result ) + AValue = ComposeDateTime( AValue, tmp ); + return result; +} + +TDateTime EncodeDateTime( const WORD AYear, const WORD AMonth, const WORD ADay, const WORD AHour, const WORD AMinute, const WORD ASecond, const WORD AMilliSecond ) +{ + TDateTime result = 0.0; + if ( ! TryEncodeDateTime( AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond, result ) ) + InvalidDateTimeError( AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond ); + return result; +} + +void DecodeDateTime( const TDateTime AValue, WORD& AYear, WORD& AMonth, WORD& ADay, WORD& AHour, WORD& AMinute, WORD& ASecond, WORD& AMilliSecond ) +{ + DecodeDate( AValue, AYear, AMonth, ADay ); + DecodeTime( AValue, AHour, AMinute, ASecond, AMilliSecond ); +} + +/*==============================================================================*/ +/* public functions */ +/*==============================================================================*/ + + +/***************************************************************************** + time functions +*****************************************************************************/ + +#ifdef windows +void GetLocalTime( TSystemTime& SYSTEMTIME ) +{ +// LPSYSTEMTIME l; + /*# Windows*/ ::TSystemTime Syst; + /*# Windows*/ ::GetLocalTime( &Syst ); + SYSTEMTIME.wYear = Syst.wYear; + SYSTEMTIME.wMonth = Syst.wMonth; + SYSTEMTIME.wDay = Syst.wDay; + SYSTEMTIME.wHour = Syst.wHour; + SYSTEMTIME.wMinute = Syst.wMinute; + SYSTEMTIME.wSecond = Syst.wSecond; + SYSTEMTIME.wMilliseconds = Syst.wMilliseconds; +} +#elif defined(linux) + +time_t Fptime( ) +{ + return time(NULL); +} + +typedef timeval* PTimeVal; + +cint fpGetTimeOfDay( PTimeVal tp, struct timezone* tzp ) +{ + cint r = gettimeofday(tp, tzp); + return r==-1 ? -errno : r; +} +/***************************************************************************** + Locale functions +*****************************************************************************/ + + +cint GetEpochTime( ) +/* + get the number of seconds since 00:00, January 1 1970, GMT + the Time not corrected Any way +*/ +{ + cint result = 0; + result = Fptime(); + return result; +} + +int tzseconds = 0; +const int C1970 = 2440588; +const int D0 = 1461; +const int D1 = 146097; +const int D2 = 1721119; + + +void JulianToGregorian( int JulianDN, WORD& Year, WORD& Month, WORD& Day ) +{ + int YYear = 0, XYear = 0, Temp = 0, TempMonth = 0; + Temp = ( ( JulianDN - D2 ) << 2 ) - 1; + JulianDN = Temp / D1; + XYear = ( Temp % D1 ) | 3; + YYear = ( XYear / D0 ); + Temp = ( ( ( ( XYear % D0 ) + 4 ) >> 2 ) * 5 ) - 3; + Day = ( ( Temp % 153 ) + 5 ) / 5; + TempMonth = Temp / 153; + if ( TempMonth >= 10 ) + { + YYear++; + TempMonth -= 12; + } + TempMonth += 3; + Month = TempMonth; + Year = YYear + ( JulianDN * 100 ); +} + + +void EpochToLocal( int Epoch, WORD& Year, WORD& Month, WORD& Day, WORD& Hour, WORD& minute, WORD& second ) +/* + transforms Epoch Time into Local Time (Hour, minute,seconds) +*/ +{ + int DateNum = 0; + Epoch += tzseconds; + DateNum = ( Epoch / 86400 ) + C1970; + JulianToGregorian( DateNum, Year, Month, Day ); + Epoch = Abs( Epoch % 86400 ); + Hour = Epoch / 3600; + Epoch = Epoch % 3600; + minute = Epoch / 60; + second = Epoch % 60; +} + + +void GetTime( WORD& Hour, WORD& Min, WORD& Sec, WORD& MSec, WORD& usec ) +/* + gets the current Time, adjusted to Local Time +*/ +{ + WORD Year = 0, Day = 0, Month = 0; + timeval tz; + fpGetTimeOfDay( &tz, NULL ); + EpochToLocal( tz.tv_sec, Year, Month, Day, Hour, Min, Sec ); + MSec = tz.tv_usec / 1000; + usec = tz.tv_usec % 1000; +} + + +void GetTime( WORD& Hour, WORD& Min, WORD& Sec, WORD& sec100 ) +/* + gets the current Time, adjusted to Local Time +*/ +{ + WORD usec = 0; + GetTime( Hour, Min, Sec, sec100, usec ); + sec100 = sec100 / 10; +} + + +void GetTime( WORD& Hour, WORD& Min, WORD& Sec ) +/* + gets the current Time, adjusted to Local Time +*/ +{ + WORD MSec = 0, usec = 0; + GetTime( Hour, Min, Sec, MSec, usec ); +} + + +void GetDate( WORD& Year, WORD& Month, WORD& Day ) +/* + gets the current Date, adjusted to Local Time +*/ +{ + WORD Hour = 0, minute = 0, second = 0; + EpochToLocal( Fptime(), Year, Month, Day, Hour, minute, second ); +} + + +void GetDateTime( WORD& Year, WORD& Month, WORD& Day, WORD& Hour, WORD& minute, WORD& second ) +/* + gets the current Date, adjusted to Local Time +*/ +{ + EpochToLocal( Fptime(), Year, Month, Day, Hour, minute, second ); +} + + +void GetLocalTime( TSystemTime& SYSTEMTIME ) +{ + WORD usecs = 0; + GetTime( SYSTEMTIME.wHour, SYSTEMTIME.wMinute, SYSTEMTIME.wSecond, SYSTEMTIME.wMilliseconds, usecs ); + GetDate( SYSTEMTIME.wYear, SYSTEMTIME.wMonth, SYSTEMTIME.wDay ); +// SYSTEMTIME.millisecond := 0; +} +#else +#error unknown platform +#endif + +// DateTimeToSystemTime converts DateTime Value to SYSTEMTIME +void DateTimeToSystemTime( TDateTime DateTime, TSystemTime& SYSTEMTIME ) +{ + DecodeDate( DateTime, SYSTEMTIME.wYear, SYSTEMTIME.wMonth, SYSTEMTIME.wDay ); + DecodeTime( DateTime, SYSTEMTIME.wHour, SYSTEMTIME.wMinute, SYSTEMTIME.wSecond, SYSTEMTIME.wMilliseconds ); +} + +// SystemTimeToDateTime converts SYSTEMTIME to A TDateTime Value +TDateTime SystemTimeToDateTime( const TSystemTime& SYSTEMTIME ) +{ + TDateTime result = 0.0; + result = ComposeDateTime( DoEncodeDate( SYSTEMTIME.wYear, SYSTEMTIME.wMonth, SYSTEMTIME.wDay ), DoEncodeTime( SYSTEMTIME.wHour, SYSTEMTIME.wMinute, SYSTEMTIME.wSecond, SYSTEMTIME.wMilliseconds ) ); + return result; +} + +// DayOfWeek returns the Day of the week (Sunday is Day 1) +int DayOfWeek( TDateTime DateTime ) +{ + //return 1 + ( Abs( Trunc( DateTime ) - 1 ) % 7 ); + return DateTime.DayOfWeek(); +} + +// Date returns the current Date +TDateTime Date( ) +{ + return TDateTime::CurrentDate(); +} + +// time returns the current time +TDateTime Time( ) +{ + return TDateTime::CurrentTime(); +} + +// Now returns the current Date and time +TDateTime Now( ) +{ + return TDateTime::CurrentDateTime(); +} + + + +/* DateTimeToTimeStamp converts DateTime to A TTimeStamp */ +TTimeStamp DateTimeToTimeStamp( TDateTime DateTime ) +{ + TTimeStamp result; + result.time = (int) Round( Abs( Frac( DateTime ) ) * MSecsPerDay ); + result.Date = DateDelta + (int) Trunc( DateTime ); + return result; +} + +/* TimeStampToDateTime converts TimeStamp to A TDateTime Value */ + + +TDateTime TimeStampToDateTime( const TTimeStamp& TimeStamp ) +{ + return ComposeDateTime( TimeStamp.Date - DateDelta, double( TimeStamp.time ) / MSecsPerDay ); +} + +/* MSecsToTimeStamp */ + + +TTimeStamp MSecsToTimeStamp( int64_t MSecs ) +{ + TTimeStamp result; + result.Date = (int) Trunc( double( MSecs ) / MSecsPerDay ); +// MSecs = MSecs - ((Comp) result.Date ) * MSecsPerDay; + MSecs = MSecs - ((int64_t) result.Date ) * MSecsPerDay; + result.time = (int) Round( (long double) MSecs ); + return result; +} + +/* TimeStampToMSecs */ + + +int64_t TimeStampToMSecs( const TTimeStamp& TimeStamp ) +{ + int64_t result = 0; +// result = TimeStamp.time + ((Comp) TimeStamp.Date ) * MSecsPerDay; + result = TimeStamp.time + ((int64_t) TimeStamp.Date ) * MSecsPerDay; + return result; +} + + + +/* EncodeDate Packs three variables Year, Month and Day into A + TDateTime Value the result is the number of Days since 12/30/1899 */ +TDateTime EncodeDate( WORD Year, WORD Month, WORD Day ) +{ + TDateTime result = 0.0; + if ( ! TryEncodeDate( Year, Month, Day, result ) ) + throw EConvertError( DateErrorString(_T("%d-%d-%d is not a valid date specification"), Year, Month, Day, -1 )); + return result; +} + +/* EncodeTime Packs four variables Hour, minute, second and millisecond into + A TDateTime Value */ + + +TDateTime EncodeTime( WORD Hour, WORD minute, WORD second, WORD millisecond ) +{ + TDateTime result = 0.0; + if ( ! TryEncodeTime( Hour, minute, second, millisecond, result ) ) + throw EConvertError( DateErrorString(_T("%d:%d:%d.%d is not a valid time specification"), Hour, minute, second, millisecond )); + return result; +} + + +// DecodeDate unpacks the Value Date into three values: Year, Month and Day +void DecodeDate( long double Date, WORD& Year, WORD& Month, WORD& Day ) +{ +// unsigned int ly = 0, ld = 0, lm = 0, j = 0; + int64_t ly = 0, ld = 0, lm = 0, j = 0; + if ( (double) Date <= - DateDelta ) // if Date is before 1-1-1 then return 0-0-0 + { + Year = 0; + Month = 0; + Day = 0; + } + else + { + j = Pred( ( Trunc( /*# System*/ int( Date ) ) + 693900 ) << 2 ); + ly = j / 146097; + j = j - 146097 * ((unsigned int) ly ); + ld = j >> 2; + j = ( ( ld << 2 ) + 3 ) / 1461; + ld = ( ( ((unsigned int) ld ) << 2 ) + 7 - 1461 * j ) >> 2; + lm = ( 5 * ld - 3 ) / 153; + ld = ( 5 * ld + 2 - 153 * lm ) / 5; + ly = 100 * ((unsigned int) ly ) + j; + if ( lm < 10 ) + lm += 3; + else + { + lm -= 9; + ly++; + } + Year = (WORD) ly; + Month = (WORD) lm; + Day = (WORD) ld; + } +} + +// DecodeDate unpacks the Value Date into three values: Year, Month and Day +void DecodeDate( TDateTime Date, WORD& Year, WORD& Month, WORD& Day ) +{ + Date.DecodeDate(&Year, &Month, &Day); +} + +bool DecodeDateFully( const TDateTime DateTime, WORD& Year, WORD& Month, WORD& Day, WORD& DOW ) +{ + bool result = false; + //DecodeDate( DateTime, Year, Month, Day ); + DateTime.DecodeDate(&Year, &Month, &Day); + DOW = DateTime.DayOfWeek( ); + return IsLeapYear( Year ); +} + + +// DecodeTime unpacks time into four values: Hour, minute, second and millisecond +void DecodeTime( long double time, WORD& Hour, WORD& minute, WORD& second, WORD& millisecond ) +{ + int64_t l = 0; + l = Round( Abs( Frac( time ) ) * MSecsPerDay ); + Hour = (WORD) (l / 3600000); + l = l % 3600000; + minute = (WORD) (l / 60000); + l = l % 60000; + second = (WORD) (l / 1000); + l = l % 1000; + millisecond = (WORD) l; +} + +// DecodeTime unpacks time into four values: Hour, minute, second and millisecond +void DecodeTime( TDateTime Time, WORD& Hour, WORD& minute, WORD& second, WORD& millisecond ) +{ + Time.DecodeTime( &Hour, &minute, &second, &millisecond ); +} + + +// IncAMonth is the same as IncMonth, but operates ON decoded Date +void IncAMonth( WORD& Year, WORD& Month, WORD& Day, int NumberOfMonths ) +{ + int TempMonth = 0, S = 0; + if ( NumberOfMonths >= 0 ) + S = 1; + else + S = - 1; + Year += ( NumberOfMonths / 12 ); + TempMonth = Month + ( NumberOfMonths % 12 ) - 1; + if ( ( TempMonth > 11 ) || ( TempMonth < 0 ) ) + { + TempMonth -= S * 12; + Year += S; + } + Month = TempMonth + 1; /* months from 1 to 12 */ + if ( Day > MonthDays[IsLeapYear( Year )][Month - 1] ) // dme Month - 1 + Day = MonthDays[IsLeapYear( Year )][Month - 1]; // dme Month - 1 +} + + +// IncMonth increments DateTime with NumberOfMonths months, +// NumberOfMonths can be less than zero +TDateTime IncMonth( const TDateTime DateTime, int NumberOfMonths ) +{ + TDateTime result = 0.0; + WORD Year = 0, Month = 0, Day = 0; + DecodeDate( DateTime, Year, Month, Day ); + IncAMonth( Year, Month, Day, NumberOfMonths ); + result = ComposeDateTime( DoEncodeDate( Year, Month, Day ), DateTime ); + return result; +} + + +/* IsLeapYear returns True if Year is A leap Year */ +bool IsLeapYear( WORD Year ) +{ + return ( Year % 4 == 0 ) && ( ( Year % 100 != 0 ) || ( Year % 400 == 0 ) ); +} + +/* DateToStr returns A String representation of Date Using ShortDateFormat */ +String DateToStr( TDateTime Date ) +{ + return Date.DateString(); +} + +/* TimeToStr returns A String representation of time Using LongTimeFormat */ +String TimeToStr( TDateTime Time ) +{ + return Time.TimeString(); +} + +/* DateTimeToStr returns A String representation of DateTime Using LongDateTimeFormat */ + + +String DateTimeToStr( TDateTime DateTime ) +{ + return DateTime.DateTimeString(); +} + +/* StrToDate converts the String S to A TDateTime Value + if S does not represent A valid Date Value + an EConvertError will be raised */ +TDateTime StrToDate( const String& S ) +{ + String DF; + WORD D = 0, m = 0, Y = 0, ly = 0; + unsigned int n = 0, i = 0; + int C = 0; + unsigned char dp = '\0', mp = '\0', yp = '\0', which = '\0'; +// SmallString<4> S1; + String S1; + int values[ 3/*# range 1..3*/ ]; + TSystemTime localtime; + bool YearMoreThenTwoDigits = false; + YearMoreThenTwoDigits = false; + DF = UpperCase( ShortDateFormat ); + /* determine order of D,m,Y */ + yp = 0; + mp = 0; + dp = 0; + which = 0; + i = 0; + while ( ( i < DF.length( ) ) && ( which < 3 ) ) + { + i++; + switch ( DF[i - 1] ) + { + case _T('Y'): + if ( yp == 0 ) + { + which++; + yp = which; + } + break; + case _T('M'): + if ( mp == 0 ) + { + which++; + mp = which; + } + break; + case _T('D'): + if ( dp == 0 ) + { + which++; + dp = which; + } + break; + } + } + if ( which != 3 ) + throw EConvertError( _T("Illegal format string") ); +/* get Actual values */ + for ( i = 1; i <= 3; i++) + values[i - 1] = 0; + S1 = _T(""); + n = 0; + for ( i = 1; i <= S.length( ); i++) + { + if ( Sysutils__20.Contains(S[i - 1] ) ) + S1 = String( S1 ) + S[i - 1]; + + /* space can be part of the ShortDateFormat, and is defaultly in slovak + Windows, therefor it Shouldn'T be taken as separator (unless So specified) + and ignored */ + if ( ( DateSeparator != _T(' ') ) && ( S[i - 1] == _T(' ') ) ) + continue; + if ( ( S[i - 1] == DateSeparator ) || ( ( i == S.length( ) ) && ( Sysutils__21.Contains(S[i - 1] ) ) ) ) + { + n++; + if ( n > 3 ) + throw EConvertError( _T("Invalid date format") ); + // Check if the Year has more then two Digits (if n=yp, then we are evaluating the Year.) + if ( ( n == yp ) && ( S1[0] > 2 ) ) + YearMoreThenTwoDigits = true; + Val( S1, &values[n - 1], C ); + if ( C != 0 ) + throw EConvertError( _T("Invalid date format") ); + S1 = _T(""); + } + else + if ( ! ( Sysutils__22.Contains(S[i - 1] ) ) ) + throw EConvertError( _T("Invalid date format") ); + } + // Fill in values. + GetLocalTime( localtime ); + ly = localtime.wYear; + if ( n == 3 ) + { + Y = values[yp - 1]; + m = values[mp - 1]; + D = values[dp - 1]; + } + else + { + Y = ly; + if ( n < 2 ) + { + D = values[1 - 1]; + m = localtime.wMonth; + } + else + if ( dp < mp ) + { + D = values[1 - 1]; + m = values[2 - 1]; + } + else + { + D = values[2 - 1]; + m = values[1 - 1]; + } + } + if ( ( Y >= 0 ) && ( Y < 100 ) && ! YearMoreThenTwoDigits ) + { + ly = ly - Sysutils::TwoDigitYearCenturyWindow; + Y += ly / 100 * 100; + if ( ( TwoDigitYearCenturyWindow > 0 ) && ( Y < ly ) ) + Y += 100; + } + return EncodeDate( Y, m, D ); +} + + +/* StrToTime converts the String S to A TDateTime Value + if S does not represent A valid time Value an + EConvertError will be raised */ + + +int GetElement( const String& S, TDateTime& xResult, int& Len, int& current, int& PM ) +{ + int result = 0; + int j = 0, C = 0; + result = - 1; + current++; + while ( ( result == - 1 ) && ( current <= Len ) ) + { + if ( Sysutils__23.Contains(S[current - 1] ) ) + { + j = current; + while ( ( current < Len ) && ( Sysutils__24.Contains(S[current + 1 - 1] ) ) ) + current++; + Val( S.substr( j - 1, 1 + current - j ), &result, C ); + } + else + if ( ( ( !TimeAMString.empty()) && ( S[current - 1] == TimeAMString[1 - 1] ) ) || ( Sysutils__25.Contains(S[current - 1] ) ) ) + { + PM = 1; + current = 1 + Len; + } + else + if ( ( ( !TimePMString.empty()) && ( S[current - 1] == TimePMString[1 - 1] ) ) || ( Sysutils__26.Contains(S[current - 1] ) ) ) + { + current = 1 + Len; + PM = 2; + } + else + if ( ( S[current - 1] == TimeSeparator ) || ( S[current - 1] == _T(' ') ) ) + current++; + else + throw EConvertError( _T("Invalid Time format") ); + } + return result; +} + + +TDateTime StrToTime( const String& S ) +{ + TDateTime result = 0.0; + int Len = 0, current = 0; + int PM = 0; + int i = 0; + int TimeValues[ 5/*# range 0..4*/ ]; + current = 0; + Len = S.length( ); + PM = 0; + for ( i = 0; i <= 4; i++) + TimeValues[i] = 0; + i = 0; + TimeValues[i] = GetElement(S, result, Len, current, PM); + while ( ( i < 5 ) && ( TimeValues[i] != - 1 ) ) + { + i = i + 1; + TimeValues[i] = GetElement(S, result, Len, current, PM); + } + if ( ( i < 5 ) && ( TimeValues[i] == - 1 ) ) + TimeValues[i] = 0; + if ( PM == 2 ) + { + if ( TimeValues[0] != 12 ) + TimeValues[0] += 12; + } + else + { + if ( ( PM == 1 ) && ( ( TimeValues[0] == 12 ) ) ) + TimeValues[0] = 0; + } + result = EncodeTime( TimeValues[0], TimeValues[1], TimeValues[2], TimeValues[3] ); + return result; +} + +/* StrToDateTime converts the String S to A TDateTime Value + if S does not represent A valid Date and/or time Value + an EConvertError will be raised */ +TDateTime StrToDateTime( const String& S ) +{ + TDateTime result = 0.0; + int i = 0, j = 0, k = 0, l = 0; + String sd, st; + l = S.length( ); + i = 1; + while ( ( i <= l ) && ( S[i - 1] == _T(' ') ) ) + i++; + j = i; + while ( ( j <= l ) && ( S[j - 1] != _T(' ') ) ) + j++; + k = j; + while ( ( k <= l ) && ( S[k - 1] == _T(' ') ) ) + k++; + sd = S.substr( i - 1, j - i ); + st = S.substr( k - 1, l ); + if ( ( st.empty()) && ( sd.find( TimeSeparator) != String::npos ) ) + { + st = sd; + sd = _T(""); + } + if ( ( !sd.empty()) && ( !st.empty()) ) + result = ComposeDateTime( StrToDate( sd ), StrToTime( st ) ); + else + if ( st.empty()) + result = StrToDate( sd ); + else + result = StrToTime( st ); + return result; +} + + + +String FormatDateTime( const String& FormatStr, TDateTime DateTime ) +{ + return DateTime.FormatString(FormatStr); +} + +/* DateTimeToString Formats DateTime to the given Format in FormatStr */ +void DateTimeToString( String& result, const String& FormatStr, const TDateTime DateTime ) +{ + result = FormatDateTime( FormatStr, DateTime ); +} + + +int DateTimeToFileDate( TDateTime DateTime ) +{ + return DateTime.FileDate(); +} + + +WORD CurrentYear( ) +{ + WORD result = 0; + WORD yy = 0, mm = 0, dd = 0; + DecodeDate( Now(), yy, mm, dd ); + result = yy; + return result; +} + + +TDateTime FileDateToDateTime( int FileDate ) +{ + return TDateTime::FileDateToDateTime( FileDate ); +} + +// ieuw. These should be written to work without Exceptions? + + + +bool TryStrToDate( const String& S, TDateTime& Value ) +{ + bool result = true; + try + { + Value = StrToDate( S ); + } + catch( EConvertError & ) + { + result = false; + } + return result; +} + + +// function TryStrToDate(const S: String; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean; + + + +bool TryStrToTime( const String& S, TDateTime& Value ) +{ + bool result = true; + try + { + Value = StrToTime( S ); + } + catch( EConvertError & ) + { + result = false; + } + return result; +} + + +// function TryStrToTime(const S: String; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean; + + + +bool TryStrToDateTime( const String& S, TDateTime& Value ) +{ + bool result = false; + result = true; + try + { + Value = StrToDateTime( S ); + } + catch( EConvertError & ) + { + result = false; + } + return result; +} + + +// function TryStrToDateTime(const S: String; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean; + + + +TDateTime StrToDateDef( const String& S, const TDateTime DefValue ) +{ + TDateTime result = 0.0; + if ( ! TryStrToDate( S, result ) ) + result = DefValue; + return result; +} + + +TDateTime StrToTimeDef( const String& S, const TDateTime DefValue ) +{ + TDateTime result = 0.0; + if ( ! TryStrToTime( S, result ) ) + result = DefValue; + return result; +} + + +TDateTime StrToDateTimeDef( const String& S, const TDateTime DefValue ) +{ + TDateTime result = 0.0; + if ( ! TryStrToDateTime( S, result ) ) + result = DefValue; + return result; +} + + +void ReplaceTime( TDateTime& dati, TDateTime NewTime ) +{ + dati = ComposeDateTime( dati, NewTime ); +} + + +void ReplaceDate( TDateTime& DateTime, const TDateTime NewDate ) +{ + TDateTime tmp = 0.0; + tmp = NewDate; + ReplaceTime( tmp, DateTime ); + DateTime = tmp; +} + + + +/***************************************************************************** + time functions +*****************************************************************************/ + +/*static*/ TDateTime TDateTime::CurrentDate() +{ + TSystemTime SYSTEMTIME; + GetLocalTime( SYSTEMTIME ); + return DoEncodeDate( SYSTEMTIME.wYear, SYSTEMTIME.wMonth, SYSTEMTIME.wDay ); +} + +/*static*/ TDateTime TDateTime::CurrentTime() +{ + TSystemTime SYSTEMTIME; + GetLocalTime( SYSTEMTIME ); + return DoEncodeTime( SYSTEMTIME.wHour, SYSTEMTIME.wMinute, SYSTEMTIME.wSecond, SYSTEMTIME.wMilliseconds ); +} + +/*static*/ TDateTime TDateTime::CurrentDateTime() +{ + TSystemTime SYSTEMTIME; + GetLocalTime( SYSTEMTIME ); + return SystemTimeToDateTime( SYSTEMTIME ); +} + +/*static*/ TDateTime TDateTime::FileDateToDateTime(int FileDate) +{ + //return ::FileDateToDateTime(fileDate); + WORD Date = 0, time = 0; + Date = FileDate >> 16; + time = FileDate & 0xFFFF; + return ComposeDateTime( EncodeDate( ( Date >> 9 ) + 1980, ( Date >> 5 ) & 15, Date & 31 ), EncodeTime( time >> 11, ( time >> 5 ) & 63, ( time & 31 ) << 1, 0 ) ); +} + + +TDateTime::TDateTime(const String& src, TDateTimeFlag flag /*= DateTime*/) +{ + switch(flag) + { + case Date: + Val = StrToDate(src); + break; + case Time: + Val = StrToTime(src); + break; + case DateTime: + Val = StrToDateTime(src); + break; + } +} + +TDateTime::TDateTime(unsigned short Year, unsigned short Month, unsigned short Day) +{ // DoEncodeDate + TDateTime d; + if ( TryEncodeDate( Year, Month, Day, d ) ) + Val = (int) Trunc( d ); + else + Val = 0.0; +} + + +TDateTime::TDateTime(unsigned short Hour, unsigned short Minute, unsigned short Second, unsigned short Millisecond) +{ // DoEncodeTime + TDateTime d; + if ( TryEncodeTime( Hour, Minute, Second, Millisecond, d ) ) + Val = d; + else + Val = 0.0; +} + + +String TDateTime::FormatString(const String& FormatStr) const +{ + //return ::FormatDateTime( format, Val ); + String result; + int ResultLen = 0; + const int BufLen = 255; + Char ResultBuffer[ 256/*# range 0..255*/ ]; + Char* ResultCurrent = NULL; + WORD Year = 0, Month = 0, Day = 0, DayOfWeek = 0, Hour = 0, minute = 0, second = 0, millisecond = 0; + DecodeDateFully( Val, Year, Month, Day, DayOfWeek ); + DecodeTime( &Hour, &minute, &second, &millisecond ); + ResultLen = 0; + ResultCurrent = &ResultBuffer[0]; + StoreFormat( FormatStr, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + ResultBuffer[ResultLen] = _T('\x00'); + return ResultBuffer; +} + +String TDateTime::DateString() const +{ + return FormatString( _T("ddddd")); +} + +String TDateTime::TimeString() const +{ + return FormatString( _T("tt") ); +} + +String TDateTime::DateTimeString() const +{ + return FormatString( _T("c") ); +} + + +int TDateTime::DayOfWeek() const +{ + return 1 + ( Abs( Trunc( Val ) - 1 ) % 7 ); +} + + +int TDateTime::FileDate() const +{ // DateTimeToFileDate + int result = 0; + WORD yy = 0, mm = 0, dd = 0, h = 0, m = 0, S = 0, MSec = 0; + ::DecodeDate( Val, yy, mm, dd ); + ::DecodeTime( Val, h, m, S, MSec ); + if ( ( yy < 1980 ) || ( yy > 2099 ) ) + result = 0; + else + { + result = ( S >> 1 ) | ( m << 5 ) | ( h << 11 ); + result = result | dd << 16 | ( mm << 21 ) | ( ( yy - 1980 ) << 25 ); + } + return result; +} + + +void TDateTime::DecodeDate(unsigned short* xYear, unsigned short* xMonth, unsigned short* xDay) const +{ + unsigned short Year, Month, Day; + ::DecodeDate(Val, Year, Month, Day); + *xYear = Year; + *xMonth = Month; + *xDay = Day; +} + +void TDateTime::DecodeTime(unsigned short* xHour, unsigned short* xMinute, unsigned short* xSecond, unsigned short* xMillisecond) const +{ + unsigned short Hour, Minute, Second, Millisecond; + ::DecodeTime(Val, Hour, Minute, Second, Millisecond); + *xHour = Hour; + *xMinute = Minute; + *xSecond = Second; + *xMillisecond = Millisecond; +} + + +////////// internal + +/* FormatDateTime Formats DateTime to the given Format String FormatStr */ +void TDateTime::StoreStr( const Char* str, int Len, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const +{ + if ( ResultLen + Len < BufLen ) //sizeof( ResultBuffer ) ) + { + StrMove( ResultCurrent, str, Len ); + ResultCurrent = ResultCurrent + Len; + ResultLen = ResultLen + Len; + } +} + + +void TDateTime::StoreString( const String& str, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const +{ + int Len = 0; + Len = str.length( ); + if ( ResultLen + Len < BufLen ) //sizeof( ResultBuffer ) ) + { // StrMove not safe + StrMove( ResultCurrent, str.c_str(), Len ); + ResultCurrent = ResultCurrent + Len; + ResultLen = ResultLen + Len; + } +} + + +void TDateTime::StoreInt( int Value, int Digits, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const +{ + String S; + int Len = 0; + S = IntToStr( Value ); + Len = S.length( ); + if ( Len < Digits ) + { + S = String( _T("0000") ).substr( 1, Digits - Len ) + S; + Len = Digits; + } + StoreStr( (Char*) S.c_str(), Len, ResultLen, ResultBuffer, BufLen, ResultCurrent ); +} + + +void TDateTime::StoreFormat( const String& FormatStr, String& result, int& ResultLen, Char* ResultBuffer, int BufLen, Char*& ResultCurrent, WORD& Year, WORD& Month, WORD& Day, WORD& DayOfWeek, WORD& Hour, WORD& minute, WORD& second, WORD& millisecond ) const +{ + Char Token = _T('\0'), lastformattoken = _T('\0'); + Char* FormatCurrent = NULL; + Char* FormatEnd = NULL; + int Count = 0; + bool Clock12 = false; + Char* P = NULL; + int tmp = 0; + FormatCurrent = (Char*) ( ((void*) FormatStr.c_str()) ); + FormatEnd = FormatCurrent + FormatStr.length( ); + Clock12 = false; + P = FormatCurrent; + while ( P < FormatEnd ) + { + Token = UpCase( *P ); + if ( Sysutils__27.Contains(Token ) ) + { + P = P + 1; + while ( ( P < FormatEnd ) && ( *P != Token ) ) + P = P + 1; + } + else + if ( Token == _T('A') ) + { + if ( ( StrLIComp( P, _T("A/P"), 3 ) == 0 ) || ( StrLIComp( P, _T("AMPM"), 4 ) == 0 ) || ( StrLIComp( P, _T("AM/PM"), 5 ) == 0 ) ) + { + Clock12 = true; + break; + } + } + P = P + 1; + } + Token = _T('\xff'); + lastformattoken = _T(' '); + while ( FormatCurrent < FormatEnd ) + { + Token = UpCase( *FormatCurrent ); + Count = 1; + P = FormatCurrent + 1; + switch ( Token ) + { + case _T('\''): case _T('\"'): + { + while ( ( P < FormatEnd ) && ( *P != Token ) ) + P = P + 1; + P = P + 1; + Count = P - FormatCurrent; + StoreStr( FormatCurrent + 1, Count - 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + break; + case _T('A'): + { + if ( StrLIComp( FormatCurrent, _T("AMPM"), 4 ) == 0 ) + { + Count = 4; + if ( Hour < 12 ) + StoreString( TimeAMString, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreString( TimePMString, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + else + if ( StrLIComp( FormatCurrent, _T("AM/PM"), 5 ) == 0 ) + { + Count = 5; + if ( Hour < 12 ) + StoreStr( _T("am"), 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreStr( _T("pm"), 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + else + if ( StrLIComp( FormatCurrent, _T("A/P"), 3 ) == 0 ) + { + Count = 3; + if ( Hour < 12 ) + StoreStr( _T("a"), 1, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreStr( _T("p"), 1, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + else + throw EConvertError( _T("Illegal character in format string") ); + } + break; + case _T('/'): + StoreStr( &DateSeparator, 1, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case _T(':'): + StoreStr( &TimeSeparator, 1, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case _T(' '): case _T('C'): case _T('D'): case _T('H'): case _T('M'): case _T('N'): case _T('S'): case _T('T'): case _T('Y'): case _T('Z'): + { +// while ( ( P < FormatEnd ) && ( wcscmp(&UpCase( *P )[1], Token ) == 0 ) ) + while ( ( P < FormatEnd ) && ( UpCase( *P ) == Token ) ) + P = P + 1; + Count = P - FormatCurrent; + switch ( Token ) + { + case _T(' '): + StoreStr( FormatCurrent, Count, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case _T('Y'): + { + if ( Count > 2 ) + StoreInt( Year, 4, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( Year % 100, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + break; + case _T('M'): + { + if ( lastformattoken == _T('H') ) + { + if ( Count == 1 ) + StoreInt( minute, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( minute, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + else + { + switch ( Count ) + { + case 1: + StoreInt( Month, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 2: + StoreInt( Month, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 3: + StoreString( ShortMonthNames[Month - 1], ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 4: + StoreString( LongMonthNames[Month - 1], ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + } + } + } + break; + case _T('D'): + { + switch ( Count ) + { + case 1: + StoreInt( Day, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 2: + StoreInt( Day, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 3: + StoreString( ShortDayNames[DayOfWeek - 1], ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 4: + StoreString( LongDayNames[DayOfWeek - 1], ResultLen, ResultBuffer, BufLen, ResultCurrent ); + break; + case 5: + StoreFormat( ShortDateFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + break; + case 6: + StoreFormat( LongDateFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + break; + } + } + break; + case _T('H'): + { + if ( Clock12 ) + { + tmp = Hour % 12; + if ( tmp == 0 ) + tmp = 12; + if ( Count == 1 ) + StoreInt( tmp, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( tmp, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + else + { + if ( Count == 1 ) + StoreInt( Hour, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( Hour, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + } + break; + case _T('N'): + { + if ( Count == 1 ) + StoreInt( minute, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( minute, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + break; + case _T('S'): + { + if ( Count == 1 ) + StoreInt( second, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( second, 2, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + break; + case _T('Z'): + { + if ( Count == 1 ) + StoreInt( millisecond, 0, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + else + StoreInt( millisecond, 3, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + break; + case _T('T'): + { + if ( Count == 1 ) + StoreFormat( ShortTimeFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + else + StoreFormat( LongTimeFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + } + break; + case _T('C'): + { + StoreFormat( ShortDateFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + if ( ( Hour != 0 ) || ( minute != 0 ) || ( second != 0 ) ) + { + StoreString( _T(" "), ResultLen, ResultBuffer, BufLen, ResultCurrent ); + StoreFormat( LongTimeFormat, result, ResultLen, ResultBuffer, BufLen, ResultCurrent, Year, Month, Day, DayOfWeek, Hour, minute, second, millisecond ); + } + } + break; + } + lastformattoken = Token; + } + break; + default: + StoreStr( &Token, 1, ResultLen, ResultBuffer, BufLen, ResultCurrent ); + } + FormatCurrent = FormatCurrent + Count; + } +} + + + +class Sysdate_unit +{ +public: +Sysdate_unit() +{ + MonthDaysInit(); +} +~Sysdate_unit(){ } +}; +Sysdate_unit _Sysdate_unit; diff --git a/OpenDSSC/Support/d2c_sysdate.h b/OpenDSSC/Support/d2c_sysdate.h new file mode 100644 index 0000000..43fe782 --- /dev/null +++ b/OpenDSSC/Support/d2c_sysdate.h @@ -0,0 +1,316 @@ +#ifndef d2c_sysdateH +#define d2c_sysdateH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +#include "d2c_systypes.h" + + + + + class TDateTime + { + public: + enum TDateTimeFlag {Date, Time, DateTime}; + + static TDateTime CurrentDate(); + static TDateTime CurrentTime(); + static TDateTime CurrentDateTime(); + static TDateTime FileDateToDateTime(int fileDate); + + TDateTime() {Val = 0;} + TDateTime(const TDateTime& src) {Val = src.Val;} + TDateTime(const long double src) {Val = src;} + TDateTime(const double src) {Val = src;} + TDateTime(const int src) {Val = src;} + TDateTime(const String& src, TDateTimeFlag flag = DateTime); + TDateTime(unsigned short Year, unsigned short Month, unsigned short Day); + TDateTime(unsigned short Hour, unsigned short Minute, unsigned short Second, unsigned short Millisecond); + + TDateTime& operator =(const TDateTime& rhs) + {Val = rhs.Val;return *this;} + TDateTime& operator =(const long double rhs) + {Val = rhs; return *this;} + TDateTime& operator =(const double rhs) + {Val = rhs; return *this;} + TDateTime& operator =(const int rhs) + {Val = rhs; return *this;} + + TDateTime& operator +=(const TDateTime& rhs) + {Val+=rhs.Val;return *this;} + TDateTime& operator +=(const long double rhs) + {Val += rhs; return *this;} + TDateTime& operator +=(const double rhs) + {Val += rhs; return *this;} + TDateTime& operator +=(const int rhs) + {Val += rhs; return *this;} + + TDateTime& operator -=(const TDateTime& rhs) + {Val-=rhs.Val;return *this;} + TDateTime& operator -=(const long double rhs) + {Val -= rhs; return *this;} + TDateTime& operator -=(const double rhs) + {Val -= rhs; return *this;} + TDateTime& operator -=(const int rhs) + {Val -= rhs; return *this;} + + TDateTime& operator ++() {Val++; return *this;} + TDateTime operator ++(int) {TDateTime tmp(*this); Val++; return tmp;} + TDateTime& operator --() {Val--; return *this;} + TDateTime operator --(int) {TDateTime tmp(*this); Val--; return tmp;} + + TDateTime operator +(const TDateTime& rhs) const + {return Val+rhs.Val;} + TDateTime operator +(const long double rhs) const {return Val+rhs;} + TDateTime operator +(const double rhs) const {return Val+rhs;} + TDateTime operator +(const int rhs) const {return Val+rhs;} + + TDateTime operator -(const TDateTime& rhs) const + {return Val-rhs.Val;} + TDateTime operator -(const long double rhs) const {return Val-rhs;} + TDateTime operator -(const double rhs) const {return Val-rhs;} + TDateTime operator -(const int rhs) const {return Val-rhs;} + + // comparisons + bool operator ==(const TDateTime& rhs) const + {return Val == rhs.Val;} + bool operator >(const TDateTime& rhs) const + {return Val > rhs.Val;} + bool operator <(const TDateTime& rhs) const + {return Val < rhs.Val;} + bool operator >=(const TDateTime& rhs) const + {return Val >= rhs.Val;} + bool operator <=(const TDateTime& rhs) const + {return Val <= rhs.Val;} + + operator String() const;//String(smart) + String FormatString(const String& format) const; + String DateString() const; + String TimeString() const; + String DateTimeString() const; + operator long double() const {return Val;} + operator double() const {return Val;} + operator int() const {return (int)Val;} + + int DayOfWeek() const; + int FileDate() const; + void DecodeDate(unsigned short* Year, unsigned short* Month, unsigned short* Day) const; + void DecodeTime(unsigned short* Hour, unsigned short* Minute, unsigned short* Second, unsigned short* Millisecond) const; + + private: + long double Val; + + void StoreStr( const Char* str, int Len, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const; + void StoreString( const String& str, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const; + void StoreInt( int Value, int Digits, int& ResultLen, Char*& ResultBuffer, int BufLen, Char*& ResultCurrent ) const; + void StoreFormat( const String& FormatStr, String& result, int& ResultLen, Char* ResultBuffer, int BufLen, Char*& ResultCurrent, WORD& Year, WORD& Month, WORD& Day, WORD& DayOfWeek, WORD& Hour, WORD& minute, WORD& second, WORD& millisecond ) const; + + }; + + +typedef TDateTime *PDate; +typedef TDateTime *PDateTime; + + +const int DateDelta = 693594; // Days between 1/1/0001 and 12/31/1899 +const int HoursPerDay = 24; +const int MinsPerHour = 60; +const int SecsPerMin = 60; +const int MSecsPerSec = 1000; +const int MinsPerDay = HoursPerDay * MinsPerHour; +const int SecsPerDay = MinsPerDay * SecsPerMin; +const int MSecsPerDay = SecsPerDay * MSecsPerSec; + +#ifdef windows + +typedef SYSTEMTIME TSystemTime; +void DateTimeToSystemTime( TDateTime DateTime, TSystemTime& SYSTEMTIME ); +TDateTime SystemTimeToDateTime( const TSystemTime& SYSTEMTIME ); +void GetLocalTime( TSystemTime& SYSTEMTIME ); + +#elif defined(linux) + +typedef WORD* PDayTable; +typedef WORD TDayTable [ 12/*# range 1..12*/ ]; + +/*TDateTime holds the Date as the number of Days since 30 Dec 1899, known as +Microsoft Excel Epoch*/ +const double JulianEpoch = ((TDateTime) - 2415018.5 ); +const double UnixEpoch = JulianEpoch + (double) ((TDateTime) 2440587.5 ); + +void EpochToLocal( int Epoch, WORD& Year, WORD& Month, WORD& Day, WORD& Hour, WORD& minute, WORD& second ); + + +//const int64_t UnixDateDelta = Trunc( UnixEpoch ); //25569 + + + /* True=Leapyear */ + +extern TDayTable MonthDays [ 2 /*# Boolean */ ]; + /* Threshold to be subtracted from Year before + Age-Detection.*/ + + /* Date Time formatting characters: + C : ShortDateFormat + ' ' + LongTimeFormat + D : Day of Month + dd : Day of Month (leading zero) + ddd : Day of week (abbreviation) + dddd : Day of week (full) + ddddd : ShortDateFormat + dddddd : LongDateFormat + m : Month + mm : Month (leading zero) + mmm : Month (abbreviation) + mmmm : Month (full) + Y : Year (two Digits) + yy : Year (two Digits) + yyyy : Year (four Digits, with Century) + h : Hour + hh : Hour (leading zero) + n : minute + nn : minute (leading zero) + S : second + SS : second (leading zero) + T : ShortTimeFormat + TT : LongTimeFormat + AM/PM : use 12 Hour clock and display AM and PM accordingly + A/P : use 12 Hour clock and display A and P accordingly + / : Insert Date seperator + : : Insert Time seperator + "xx" : literal Text + 'xx' : literal Text + */ + + +/* Windows isn'T defined in 2.0.2 (FK) */ + /* Win32 reuses the struct from the Windows unit */ +struct TSystemTime { + WORD wYear, wMonth, wDay; + WORD wHour, wMinute, wSecond, wMilliseconds; +}; + +#else +#error unknown System +#endif + +struct TTimeStamp { + int time; /* number of milliseconds since midnight */ + int Date; /* one plus number of Days since 1/1/0001 */ +}; + +TTimeStamp DateTimeToTimeStamp( TDateTime DateTime ); +TDateTime TimeStampToDateTime( const TTimeStamp& TimeStamp ); +TTimeStamp MSecsToTimeStamp( int64_t MSecs ); +int64_t TimeStampToMSecs( const TTimeStamp& TimeStamp ); +bool TryEncodeDate( WORD Year, WORD Month, WORD Day, TDateTime& Date ); +bool TryEncodeTime( WORD Hour, WORD Min, WORD Sec, WORD MSec, TDateTime& time ); +TDateTime EncodeDate( WORD Year, WORD Month, WORD Day ); +TDateTime EncodeTime( WORD Hour, WORD minute, WORD second, WORD millisecond ); +TDateTime ComposeDateTime( TDateTime Date, TDateTime time ); +void DecodeDate( TDateTime Date, WORD& Year, WORD& Month, WORD& Day ); +bool DecodeDateFully( const TDateTime DateTime, WORD& Year, WORD& Month, WORD& Day, WORD& DOW ); +void DecodeTime( TDateTime time, WORD& Hour, WORD& minute, WORD& second, WORD& millisecond ); +TDateTime EncodeDateTime( const WORD AYear, const WORD AMonth, const WORD ADay, const WORD AHour, const WORD AMinute, const WORD ASecond, const WORD AMilliSecond ); +void DecodeDateTime( const TDateTime AValue, WORD& AYear, WORD& AMonth, WORD& ADay, WORD& AHour, WORD& AMinute, WORD& ASecond, WORD& AMilliSecond ); +//void DateTimeToSystemTime( TDateTime DateTime, TSystemTime& SYSTEMTIME ); +//TDateTime SystemTimeToDateTime( const TSystemTime& SYSTEMTIME ); +int DayOfWeek( TDateTime DateTime ); +TDateTime Date( ); +TDateTime Time( ); +TDateTime Now( ); +TDateTime IncMonth( const TDateTime DateTime, int NumberOfMonths = 1 ); +void IncAMonth( WORD& Year, WORD& Month, WORD& Day, int NumberOfMonths = 1 ); +bool IsLeapYear( WORD Year ); +String DateToStr( TDateTime Date ); +String TimeToStr( TDateTime time ); +String DateTimeToStr( TDateTime DateTime ); +TDateTime StrToDate( const String& S ); +TDateTime StrToTime( const String& S ); +TDateTime StrToDateTime( const String& S ); +String FormatDateTime( const String& FormatStr, TDateTime DateTime ); +void DateTimeToString( String& result, const String& FormatStr, const TDateTime DateTime ); +int DateTimeToFileDate( TDateTime DateTime ); +TDateTime FileDateToDateTime( int FileDate ); +bool TryStrToDate( const String& S, TDateTime& Value ); +bool TryStrToTime( const String& S, TDateTime& Value ); +bool TryStrToDateTime( const String& S, TDateTime& Value ); +TDateTime StrToDateDef( const String& S, const TDateTime DefValue ); +TDateTime StrToTimeDef( const String& S, const TDateTime DefValue ); +TDateTime StrToDateTimeDef( const String& S, const TDateTime DefValue ); +WORD CurrentYear( ); +/* FPC extra */ +//void GetLocalTime( TSystemTime& SYSTEMTIME ); +void ReplaceTime( TDateTime& dati, TDateTime NewTime ); +void ReplaceDate( TDateTime& DateTime, const TDateTime NewDate ); + +extern TDateTime MinDateTime; +extern TDateTime MaxDateTime; + + +#endif // lpl_sysdateH \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_sysexcept.cpp b/OpenDSSC/Support/d2c_sysexcept.cpp new file mode 100644 index 0000000..fcf90ed --- /dev/null +++ b/OpenDSSC/Support/d2c_sysexcept.cpp @@ -0,0 +1,743 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +#include "d2c_sysexcept.h" +#include +#include "d2c_system.h" +#include "Sysutils.h" +#include "d2c_varrec.h" +#include "d2c_sysconst.h" +#include "d2c_sysstring.h" +#include + +#ifdef linux +#include +#endif + +using namespace std; +using namespace System; + + + +namespace System +{ + +EOutOfMemory* OutOfMemory = NULL; +EInvalidPointer* InvalidPointer = NULL; +TOnShowException OnShowException = NULL; +int ExitCode = 0; + +#ifdef linux +int geterrno( ) +{ + return errno; +} + +void seterrno( int err ) +{ + errno = err; +} + + +/****************************************************************************** + Error conversion +******************************************************************************/ + +/* + the lowlevel File functions should take care of setting the InOutRes to the + correct Value if an Error has occured, else leave it untouched +*/ + + +WORD PosixToRunError( int PosixErrno ) +/* + convert errno Error to the correct InOutRes Value +*/ +{ + WORD result = 0; +/* + if PosixErrno=0 then {else it will go through all the cases} + exit(0); + + Statement commented out. it will not go through all the cases. (dm) +*/ + switch ( PosixErrno ) + { + case ESysENFILE: case ESysEMFILE: + result = 4; + break; + case ESysENOENT: + result = 2; + break; + case ESysEBADF: + result = 6; + break; + case ESysENOMEM: case ESysEFAULT: + result = 217; + break; + case ESysEINVAL: + result = 218; + break; + case ESysEPIPE: case ESysEINTR: case ESysEIO: case ESysEAGAIN: case ESysENOSPC: + result = 101; + break; + case ESysENAMETOOLONG: + result = 3; + break; + case ESysEROFS: case ESysEEXIST: case ESysENOTEMPTY: case ESysEACCES: + result = 5; + break; + case ESysEISDIR: + result = 5; + break; + default: + result = PosixErrno; + } + InOutRes = result; + return result; +} +#endif + + + +/***************************************************************************** + Target independent RunError +*****************************************************************************/ + + + +WORD ErrorCode = 0; + +enum TRuntimeError {reNone, + reOutOfMemory, + reInvalidPtr, + reDivByZero, + reRangeError, + reIntOverflow, + reInvalidOp, + reZeroDivide, + reOverflow, + reUnderflow, + reInvalidCast, + reAccessViolation, + rePrivInstruction, + reControlBreak, + reStackOverflow, + reVarTypeCast, + reVarInvalidOp, + reVarDispatch, + reVarArrayCreate, + reVarNotArray, + reVarArrayBounds, + reAssertionFailed, + reExternalException, + reIntfCastError, + reSafeCallError, + reQuit, + reCodesetConversion }; + +void Halt( WORD errnum ) +{ + ExitCode = errnum; + exit(errnum); +} + +void Halt( ) +{ + Halt( 0 ); +} + +void RunError( WORD W ) +{ + ErrorCode = W; +// todo ErrorAddr = get_caller_addr( Get_frame() ); +// todo ErrorBase = get_caller_frame( Get_frame() ); + if ( ErrorCode <= maxExitCode ) + Halt( (unsigned char) ErrorCode ); + else + Halt( 255 ); +} + +void RunError( ) +{ + RunError( 0 ); +} + +int ExceptionErrorMessage( TObject* ExceptObject, void* ExceptAddr, Char* Buffer, int Size ) +{ + int result = 0; + String S; + int Len = 0; + //S = Format( _T(SysConst_SExceptionErrorMessage), ARRAYOFCONST(( ExceptAddr, ExceptObject->ClassName() )) ); + S = _T("exception at "); + Char buf[20]; +#ifdef _WIDESTRING + swprintf( buf, 19, _T("%p"), ExceptAddr); +#else + snprintf( buf, 19, "%p", ExceptAddr); +#endif + buf[19]=0; + S += buf; + if(dynamic_cast< Exception* >( ExceptObject ) != NULL) + { + //S = Format( _T("%s:\x0a%s"), ARRAYOFCONST(( S, ((Exception*)ExceptObject)->ReadPropertyMessage() )) ); + S += _T(":\x0a"); + S += ((Exception*)ExceptObject)->ReadPropertyMessage(); + } + Len = S.length( ); + if ( S[Len - 1] != '.' ) + { + S = S + _T("."); + Len++; + } + if ( Len > Size ) + Len = Size; + if ( Len > 0 ) + memmove(Buffer, S.c_str(), Len * sizeof(Char)); + result = Len; + return result; +} + +void ShowException( TObject* ExceptObject, void* ExceptAddr ) +// use ShortString. ON Exception, the heap may be corrupt. +{ + //SmallString<255> Buf; + Char Buf[256]; + Buf[0] = ExceptionErrorMessage( ExceptObject, ExceptAddr, Buf, 255 ); + if ( IsConsole ) + WriteLn( Buf ); + else + if (( OnShowException != NULL ) ) + OnShowException( Buf ); +} + + +void Abort( ) +{ + throw EAbort( _T(SysConst_SAbortError) ) /* at ((void*) get_caller_addr( Get_frame() ) ) */; +} + + +void OutOfMemoryError( ) +{ + throw OutOfMemory; +} + +/***************************************************************************** + Target dependent RaiseLastOSError +*****************************************************************************/ + + +#ifdef windows + +// Please keep locations corresponding to location in array above +unsigned char RuntimeErrorExitCodes [ 27 /*# TRuntimeError */ ]; +void RuntimeErrorExitCodesInit( ) +{ + RuntimeErrorExitCodes[0] = 0; + RuntimeErrorExitCodes[1] = 203; + RuntimeErrorExitCodes[2] = 204; + RuntimeErrorExitCodes[3] = 200; + RuntimeErrorExitCodes[4] = 201; + RuntimeErrorExitCodes[5] = 215; + RuntimeErrorExitCodes[6] = 207; + RuntimeErrorExitCodes[7] = 200; + RuntimeErrorExitCodes[8] = 205; + RuntimeErrorExitCodes[9] = 206; + RuntimeErrorExitCodes[10] = 219; + RuntimeErrorExitCodes[11] = 216; + RuntimeErrorExitCodes[12] = 218; + RuntimeErrorExitCodes[13] = 217; + RuntimeErrorExitCodes[14] = 202; + RuntimeErrorExitCodes[15] = 220; + RuntimeErrorExitCodes[16] = 221; + RuntimeErrorExitCodes[17] = 222; + RuntimeErrorExitCodes[18] = 223; + RuntimeErrorExitCodes[19] = 224; + RuntimeErrorExitCodes[20] = 225; + RuntimeErrorExitCodes[21] = 227; + RuntimeErrorExitCodes[22] = 212; + RuntimeErrorExitCodes[23] = 228; + RuntimeErrorExitCodes[24] = 229; + RuntimeErrorExitCodes[25] = 233; + RuntimeErrorExitCodes[26] = 234; +} + + +String SysErrorMessage( int ErrorCode ) +{ + String result; + const int MaxMsgSize = FORMAT_MESSAGE_MAX_WIDTH_MASK; + Char* MsgBuffer = NULL; + GetMem( MsgBuffer, MaxMsgSize * sizeof(Char) ); + FillChar( MsgBuffer, MaxMsgSize * sizeof(Char), '\x00' ); + // nSize: number of bytes (ANSI version) or characters (Unicode version) + FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), MsgBuffer, MaxMsgSize, NULL ); /* this function allocs the memory */ /* maximum Message Size */ + result = MsgBuffer; + System::FreeMem( MsgBuffer, MaxMsgSize * sizeof(Char) ); + return result; +} + +int GetLastOSError( ) +{ + return GetLastError(); +} +#elif defined(linux) + +const Char* sys_errlist [ 125/*# range 0..sys_errn-1*/ ]; +void sys_errlistInit( ) +{ + sys_errlist[0] = _T("Success"); + sys_errlist[1] = _T("Operation not permitted"); + sys_errlist[2] = _T("No such file or directory"); + sys_errlist[3] = _T("No such process"); + sys_errlist[4] = _T("Interrupted system cal_T("); + sys_errlist[5] = _T("I/O error"); + sys_errlist[6] = _T("No such device or address"); + sys_errlist[7] = _T("Arg list too long"); + sys_errlist[8] = _T("Exec format error"); + sys_errlist[9] = _T("Bad file number"); + sys_errlist[10] = _T("No child processes"); + sys_errlist[11] = _T("Try again"); + sys_errlist[12] = _T("Out of memory"); + sys_errlist[13] = _T("Permission denied"); + sys_errlist[14] = _T("Bad address"); + sys_errlist[15] = _T("Block device required"); + sys_errlist[16] = _T("Device or resource busy"); + sys_errlist[17] = _T("File exists"); + sys_errlist[18] = _T("Cross-device link"); + sys_errlist[19] = _T("No such device"); + sys_errlist[20] = _T("Not a directory"); + sys_errlist[21] = _T("Is a directory"); + sys_errlist[22] = _T("Invalid argument"); + sys_errlist[23] = _T("File table overflow"); + sys_errlist[24] = _T("Too many open files"); + sys_errlist[25] = _T("Not a typewriter"); + sys_errlist[26] = _T("Text (code segment) file busy"); + sys_errlist[27] = _T("File too large"); + sys_errlist[28] = _T("No space left on device"); + sys_errlist[29] = _T("Illegal seek"); + sys_errlist[30] = _T("Read-only file system"); + sys_errlist[31] = _T("Too many links"); + sys_errlist[32] = _T("Broken pipe"); + sys_errlist[33] = _T("Math argument out of domain of func"); + sys_errlist[34] = _T("Math result not representable"); + sys_errlist[35] = _T("Resource deadlock would occur"); + sys_errlist[36] = _T("File name too long"); + sys_errlist[37] = _T("No record locks available"); + sys_errlist[38] = _T("Function not implemented"); + sys_errlist[39] = _T("Directory not empty"); + sys_errlist[40] = _T("Too many symbolic links encountered"); + sys_errlist[41] = _T("Operation would block"); + sys_errlist[42] = _T("No message of desired type"); + sys_errlist[43] = _T("Identifier removed"); + sys_errlist[44] = _T("Channel number out of range"); + sys_errlist[45] = _T("Level 2 not synchronized"); + sys_errlist[46] = _T("Level 3 halted"); + sys_errlist[47] = _T("Level 3 reset"); + sys_errlist[48] = _T("Link number out of range"); + sys_errlist[49] = _T("Protocol driver not attached"); + sys_errlist[50] = _T("No CSI structure available"); + sys_errlist[51] = _T("Level 2 halted"); + sys_errlist[52] = _T("Invalid exchange"); + sys_errlist[53] = _T("Invalid request descriptor"); + sys_errlist[54] = _T("Exchange ful_T("); + sys_errlist[55] = _T("No anode"); + sys_errlist[56] = _T("Invalid request code"); + sys_errlist[57] = _T("Invalid slot"); + sys_errlist[58] = _T("File locking deadlock error"); + sys_errlist[59] = _T("Bad font file format"); + sys_errlist[60] = _T("Device not a stream"); + sys_errlist[61] = _T("No data available"); + sys_errlist[62] = _T("Timer expired"); + sys_errlist[63] = _T("Out of streams resources"); + sys_errlist[64] = _T("Machine is not on the network"); + sys_errlist[65] = _T("Package not installed"); + sys_errlist[66] = _T("Object is remote"); + sys_errlist[67] = _T("Link has been severed"); + sys_errlist[68] = _T("Advertise error"); + sys_errlist[69] = _T("Srmount error"); + sys_errlist[70] = _T("Communication error on send"); + sys_errlist[71] = _T("Protocol error"); + sys_errlist[72] = _T("Multihop attempted"); + sys_errlist[73] = _T("RFS specific error"); + sys_errlist[74] = _T("Not a data message"); + sys_errlist[75] = _T("Value too large for defined data type"); + sys_errlist[76] = _T("Name not unique on network"); + sys_errlist[77] = _T("File descriptor in bad state"); + sys_errlist[78] = _T("Remote address changed"); + sys_errlist[79] = _T("Can not access a needed shared library"); + sys_errlist[80] = _T("Accessing a corrupted shared library"); + sys_errlist[81] = _T(".lib section in a.out corrupted"); + sys_errlist[82] = _T("Attempting to link in too many shared libraries"); + sys_errlist[83] = _T("Cannot exec a shared library directly"); + sys_errlist[84] = _T("Illegal byte sequence"); + sys_errlist[85] = _T("Interrupted system call should be restarted"); + sys_errlist[86] = _T("Streams pipe error"); + sys_errlist[87] = _T("Too many users"); + sys_errlist[88] = _T("Socket operation on non-socket"); + sys_errlist[89] = _T("Destination address required"); + sys_errlist[90] = _T("Message too long"); + sys_errlist[91] = _T("Protocol wrong type for socket"); + sys_errlist[92] = _T("Protocol not available"); + sys_errlist[93] = _T("Protocol not supported"); + sys_errlist[94] = _T("Socket type not supported"); + sys_errlist[95] = _T("Operation not supported on transport endpoint"); + sys_errlist[96] = _T("Protocol family not supported"); + sys_errlist[97] = _T("Address family not supported by protoco_T("); + sys_errlist[98] = _T("Address already in use"); + sys_errlist[99] = _T("Cannot assign requested address"); + sys_errlist[100] = _T("Network is down"); + sys_errlist[101] = _T("Network is unreachable"); + sys_errlist[102] = _T("Network dropped connection because of reset"); + sys_errlist[103] = _T("Software caused connection abort"); + sys_errlist[104] = _T("Connection reset by peer"); + sys_errlist[105] = _T("No buffer space available"); + sys_errlist[106] = _T("Transport endpoint is already connected"); + sys_errlist[107] = _T("Transport endpoint is not connected"); + sys_errlist[108] = _T("Cannot send after transport endpoint shutdown"); + sys_errlist[109] = _T("Too many references: cannot splice"); + sys_errlist[110] = _T("Connection timed out"); + sys_errlist[111] = _T("Connection refused"); + sys_errlist[112] = _T("Host is down"); + sys_errlist[113] = _T("No route to host"); + sys_errlist[114] = _T("Operation already in progress"); + sys_errlist[115] = _T("Operation now in progress"); + sys_errlist[116] = _T("Stale NFS file handle"); + sys_errlist[117] = _T("Structure needs cleaning"); + sys_errlist[118] = _T("Not a XENIX named type file"); + sys_errlist[119] = _T("No XENIX semaphores available"); + sys_errlist[120] = _T("Is a named type file"); + sys_errlist[121] = _T("Remote I/O error"); + sys_errlist[122] = _T("Quota exceeded"); + sys_errlist[123] = _T("No medium found"); + sys_errlist[124] = _T("Wrong medium type"); +} + + + +String StrError( cint err ) +{ + String result; + String S; + if ( ( err < 0 ) || ( err >= sys_errn ) ) + { + Str( err, S ); + result = String( _T("Unknown Error (") ) + S + _T(")"); + } + else + result = StrPas( sys_errlist[err] ); + return result; +} + + +void PError( const String& S, cint errno ) +{ + Write( Stderr, S ); Write( Stderr, _T(": ") ); WriteLn( Stderr, StrError( errno ) ); +} + + +int GetLastOSError( ) +{ + return geterrno(); +} + +String SysErrorMessage( int ErrorCode ) +{ + return StrError( ErrorCode ); +} + +int GetLastError() +{ + return GetLastOSError( ); +} + +#else +#error unknown platform +#endif + + + + + +void RaiseLastOSError( ) +{ + int ECode = 0; + EOSError* e = NULL; + ECode = GetLastOSError(); + if ( ECode != 0 ) +// e = new EOSError( _T(SysConst_SOSError), ARRAYOFCONST(( ECode, SysErrorMessage(ECode) )) ); + e = new EOSError( ErrorString(_T(SysConst_SOSError), IntToStr(ECode) )); + else + e = new EOSError( _T(SysConst_SUnkOSError) ); + e->ErrorCode = ECode; + throw e; +} + + +/****************************************************************************** + internal Error handling +******************************************************************************/ + +void HandleError( int err ) +/* + procedure to Handle Internal errors, i.e. not User-invoked errors + Internal function should always call HandleError instead of RunError. +*/ +{ + //HandleErrorFrame( err, Get_frame() ); + throw runtime_error("internal error"); +} + + +int Exception::ReadPropertyHelpContext( ) const { + return FHelpContext; +} +void Exception::WritePropertyHelpContext( int Value ) { + FHelpContext = Value; +} +String Exception::ReadPropertyMessage( ) const { + return FMessage; +} +void Exception::WritePropertyMessage( String Value ) { + FMessage = Value; +} + + +Exception::Exception( const String& Msg ) +{ + // inherited::Create(); + FMessage = Msg; +} + +Exception::Exception( const String& Msg, const VECTOROFCONST& Args ) +{ + // inherited::Create(); + FMessage = Format( Msg, Args ); +} + +Exception::Exception( PString ResString ) +{ + // inherited::Create(); + FMessage = *ResString; +} + +Exception::Exception( PString ResString, const VECTOROFCONST& Args ) +{ + // inherited::Create(); + FMessage = Format( *ResString, Args ); +} + + +Exception::Exception( const String& Msg, int AHelpContext ) +{ + // inherited::Create(); + FMessage = Msg; + FHelpContext = AHelpContext; +} + + +Exception::Exception( const String& Msg, const VECTOROFCONST& Args, int AHelpContext ) +{ + // inherited::Create(); + FMessage = Format( Msg, Args ); + FHelpContext = AHelpContext; +} + +Exception::Exception( PString ResString, int AHelpContext ) +{ + // inherited::Create(); + FMessage = *ResString; + FHelpContext = AHelpContext; +} + +Exception::Exception( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) +{ + // inherited::Create(); + FMessage = Format( *ResString, Args ); + FHelpContext = AHelpContext; +} + + +void EHeapMemoryError::FreeInstance( ) +{ +// if ( AllowFree ) +// inherited::FreeInstance(); +} + +const int VAR_OK = 0x00000000; // HRESULT +const int VAR_PARAMNOTFOUND = 0x80020004; // HRESULT +const int VAR_TYPEMISMATCH = 0x80020005; // HRESULT +const int VAR_BADVARTYPE = 0x80020008; // HRESULT +const int VAR_EXCEPTION = 0x80020009; // HRESULT +const int VAR_OVERFLOW = 0x8002000A; // HRESULT +const int VAR_BADINDEX = 0x8002000B; // HRESULT +const int VAR_ARRAYISLOCKED = 0x8002000D; // HRESULT +const int VAR_NOTIMPL = 0x80004001; // HRESULT +const int VAR_OUTOFMEMORY = 0x8007000e; // HRESULT +const int VAR_INVALIDARG = 0x80070057; // HRESULT +const int VAR_UNEXPECTED = 0x8000FFFF; // HRESULT + +EVariantError::EVariantError( int Code ) +{ + switch ( Code ) + { + case VAR_OK: + FMessage = _T(SysConst_SNoError); + break; + case VAR_PARAMNOTFOUND: + FMessage = _T(SysConst_SVarParamNotFound); + break; + case VAR_TYPEMISMATCH: + FMessage = _T(SysConst_SInvalidVarCast); + break; + case VAR_BADVARTYPE: + FMessage = _T(SysConst_SVarBadType); + break; + case VAR_OVERFLOW: + FMessage = _T(SysConst_SVarOverflow); + break; + case VAR_BADINDEX: + FMessage = _T(SysConst_SVarArrayBounds); + break; + case VAR_ARRAYISLOCKED: + FMessage = _T(SysConst_SVarArrayLocked); + break; + case VAR_NOTIMPL: + FMessage = _T(SysConst_SVarNotImplemented); + break; + case VAR_OUTOFMEMORY: + FMessage = _T(SysConst_SVarOutOfMemory); + break; + case VAR_INVALIDARG: + FMessage = _T(SysConst_SVarInvalid); + break; + case VAR_UNEXPECTED: case VAR_EXCEPTION: + FMessage = _T(SysConst_SVarUnexpected); + break; + default: +// FMessage = Format( _T(SysConst_SUnknownErrorCode), OpenArray(Code) ); + FMessage = _T("Unknown error code: "); + FMessage += IntToStr(Code); + break; + } + ErrCode = Code; +} + +void ErrorHandling_initialization() +{ + //InitExceptions(); /* Initialize Exceptions. OS Independent */ + OutOfMemory = new EOutOfMemory( _T(SysConst_SOutOfMemory) ); + OutOfMemory->AllowFree = false; + InvalidPointer = new EInvalidPointer( _T(SysConst_SInvalidPointer) ); + InvalidPointer->AllowFree = false; + #ifdef windows + RuntimeErrorExitCodesInit( ); + #endif +} + +void ErrorHandling_finalization() +{ + OutOfMemory->AllowFree = true; + delete OutOfMemory; + InvalidPointer->AllowFree = true; + delete InvalidPointer; +} + +class ErrorHandling_unit +{ +public: +ErrorHandling_unit() +{ + ErrorHandling_initialization(); +#ifdef linux + sys_errlistInit(); +#endif +} +~ErrorHandling_unit(){ ErrorHandling_finalization(); } +}; +ErrorHandling_unit _ErrorHandling_unit; + +} + +string ErrorString(const char* xpFormat, const string& xsValue) +{ + char buf[1024]; + snprintf( buf, 1024, xpFormat, xsValue.c_str()); + buf[1023] = 0; + return buf; +} + +wstring ErrorString(const wchar_t* xpFormat, const wstring& xsValue) +{ + wchar_t buf[1000]; + swprintf( buf, 999, xpFormat, xsValue.c_str()); + return buf; +} diff --git a/OpenDSSC/Support/d2c_sysexcept.h b/OpenDSSC/Support/d2c_sysexcept.h new file mode 100644 index 0000000..414c453 --- /dev/null +++ b/OpenDSSC/Support/d2c_sysexcept.h @@ -0,0 +1,849 @@ +#ifndef d2c_sysexceptH +#define d2c_sysexceptH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_systypes.h" +#include "d2c_systobj.h" +#include "d2c_varrec.h" + +#ifdef linux +#include "errno.h" +#endif + + + +namespace System { + +#ifdef linux + +const int ESysEPERM = 1; /* operation not permitted */ +const int ESysENOENT = 2; /* no such File or Directory */ +const int ESysESRCH = 3; /* no such process */ +const int ESysEINTR = 4; /* Interrupted System call */ +const int ESysEIO = 5; /* i/O Error */ +const int ESysENXIO = 6; /* no such device or Address */ +const int ESysE2BIG = 7; /* arg List Too LONG */ +const int ESysENOEXEC = 8; /* Exec Format Error */ +const int ESysEBADF = 9; /* bad File number */ +const int ESysECHILD = 10; /* no Child processes */ +const int ESysEAGAIN = 11; /* try again */ +const int ESysENOMEM = 12; /* out of memory */ +const int ESysEACCES = 13; /* permission denied */ +const int ESysEFAULT = 14; /* bad Address */ +const int ESysENOTBLK = 15; /* block device required, not Posix! */ +const int ESysEBUSY = 16; /* device or Resource busy */ +const int ESysEEXIST = 17; /* File exists */ +const int ESysEXDEV = 18; /* Cross-device link */ +const int ESysENODEV = 19; /* no such device */ +const int ESysENOTDIR = 20; /* not A Directory */ +const int ESysEISDIR = 21; /* is A Directory */ +const int ESysEINVAL = 22; /* Invalid argument */ +const int ESysENFILE = 23; /* File Table overflow */ +const int ESysEMFILE = 24; /* Too many Open files */ +const int ESysENOTTY = 25; /* not A typewriter */ +const int ESysETXTBSY = 26; /* Text File busy. the New process was + A PURE procedure (shared Text) File which was + Open for writing by another process, or File + which was Open for writing by another process, + or While the PURE procedure File was being + executed an Open(2) call Requested write access + Requested write access.*/ +const int ESysEFBIG = 27; /* File Too large */ +const int ESysENOSPC = 28; /* no space Left ON device */ +const int ESysESPIPE = 29; /* Illegal seek */ +const int ESysEROFS = 30; /* read-only File System */ +const int ESysEMLINK = 31; /* Too many links */ +const int ESysEPIPE = 32; /* broken Pipe */ +const int ESysEDOM = 33; /* math argument out of domain of Func */ +const int ESysERANGE = 34; /* math result not representable */ +const int ESysEDEADLK = 35; /* Resource deadlock would occur */ +const int ESysENAMETOOLONG = 36; /* File Name Too LONG */ +const int ESysENOLCK = 37; /* no record locks available */ +const int ESysENOSYS = 38; /* function not implemented */ +const int ESysENOTEMPTY = 39; /* Directory not empty */ +const int ESysELOOP = 40; /* Too many symbolic links encountered */ +const int ESysEWOULDBLOCK = ESysEAGAIN; /* operation would block */ +const int ESysENOMSG = 42; /* no Message of desired type */ +const int ESysEIDRM = 43; /* Identifier removed */ +const int ESysECHRNG = 44; /* channel number out of Range */ +const int ESysEL2NSYNC = 45; /* Level 2 not synchronized */ +const int ESysEL3HLT = 46; /* Level 3 halted */ +const int ESysEL3RST = 47; /* Level 3 Reset */ +const int ESysELNRNG = 48; /* link number out of Range */ +const int ESysEUNATCH = 49; /* protocol driver not attached */ +const int ESysENOCSI = 50; /* no CSI structure available */ +const int ESysEL2HLT = 51; /* Level 2 halted */ +const int ESysEBADE = 52; /* Invalid Exchange */ +const int ESysEBADR = 53; /* Invalid request Descriptor */ +const int ESysEXFULL = 54; /* Exchange full */ +const int ESysENOANO = 55; /* no ANode */ +const int ESysEBADRQC = 56; /* Invalid request Code */ +const int ESysEBADSLT = 57; /* Invalid slot */ +const int ESysEDEADLOCK = 58; /* File Locking deadlock Error */ +const int ESysEBFONT = 59; /* bad Font File Format */ +const int ESysENOSTR = 60; /* device not A Stream */ +const int ESysENODATA = 61; /* no Data available */ +const int ESysETIME = 62; /* timer expired */ +const int ESysENOSR = 63; /* out of streams resources */ +const int ESysENONET = 64; /* Machine is not ON the network */ +const int ESysENOPKG = 65; /* package not installed */ +const int ESysEREMOTE = 66; /* object is remote */ +const int ESysENOLINK = 67; /* link has been severed */ +const int ESysEADV = 68; /* advertise Error */ +const int ESysESRMNT = 69; /* Srmount Error */ +const int ESysECOMM = 70; /* communication Error ON send */ +const int ESysEPROTO = 71; /* protocol Error */ +const int ESysEMULTIHOP = 72; /* Multihop attempted */ +const int ESysEDOTDOT = 73; /* RFS specific Error */ +const int ESysEBADMSG = 74; /* not A Data Message */ +const int ESysEOVERFLOW = 75; /* Value Too large for defined Data type */ +const int ESysENOTUNIQ = 76; /* Name not unique ON network */ +const int ESysEBADFD = 77; /* File Descriptor in bad State */ +const int ESysEREMCHG = 78; /* remote Address changed */ +const int ESysELIBACC = 79; /* can not access A needed shared Library */ +const int ESysELIBBAD = 80; /* accessing A corrupted shared Library */ +const int ESysELIBSCN = 81; /* .lib section in A.out corrupted */ +const int ESysELIBMAX = 82; /* Attempting to link in Too many shared Libraries */ +const int ESysELIBEXEC = 83; /* cannot Exec A shared Library directly */ +const int ESysEILSEQ = 84; /* Illegal Byte sequence */ +const int ESysERESTART = 85; /* Interrupted System call should be restarted */ +const int ESysESTRPIPE = 86; /* streams Pipe Error */ +const int ESysEUSERS = 87; /* Too many users */ +const int EsysENOTSOCK = 88; /* socket operation ON non-socket */ +const int ESysEDESTADDRREQ = 89; /* Destination Address required */ +const int ESysEMSGSIZE = 90; /* Message Too LONG */ +const int ESysEPROTOTYPE = 91; /* protocol wrong type for socket */ +const int ESysENOPROTOOPT = 92; /* protocol not available */ +const int ESysEPROTONOSUPPORT = 93; /* protocol not supported */ +const int ESysESOCKTNOSUPPORT = 94; /* socket type not supported */ +const int ESysEOPNOTSUPP = 95; /* operation not supported ON transport endpoint */ +const int ESysEPFNOSUPPORT = 96; /* protocol family not supported */ +const int ESysEAFNOSUPPORT = 97; /* Address family not supported by protocol */ +const int ESysEADDRINUSE = 98; /* Address Already in use */ +const int ESysEADDRNOTAVAIL = 99; /* cannot Assign Requested Address */ +const int ESysENETDOWN = 100; /* network is down */ +const int ESysENETUNREACH = 101; /* network is unreachable */ +const int ESysENETRESET = 102; /* network dropped connection because of Reset */ +const int ESysECONNABORTED = 103; /* Software caused connection Abort */ +const int ESysECONNRESET = 104; /* connection Reset by peer */ +const int ESysENOBUFS = 105; /* no Buffer space available */ +const int ESysEISCONN = 106; /* transport endpoint is Already connected */ +const int ESysENOTCONN = 107; /* transport endpoint is not connected */ +const int ESysESHUTDOWN = 108; /* cannot send After transport endpoint shutdown */ +const int ESysETOOMANYREFS = 109; /* Too many references: cannot SPLICE */ +const int ESysETIMEDOUT = 110; /* connection timed out */ +const int ESysECONNREFUSED = 111; /* connection refused */ +const int ESysEHOSTDOWN = 112; /* host is down */ +const int ESysEHOSTUNREACH = 113; /* no route to host */ +const int ESysEALREADY = 114; /* operation Already in progress */ +const int ESysEINPROGRESS = 115; /* operation Now in progress */ +const int ESysESTALE = 116; /* Stale NFS File Handle */ +const int ESysEUCLEAN = 117; /* structure needs cleaning */ +const int ESysENOTNAM = 118; /* not A XENIX Named type File */ +const int ESysENAVAIL = 119; /* no XENIX semaphores available */ +const int ESysEISNAM = 120; /* is A Named type File */ +const int ESysEREMOTEIO = 121; /* remote i/O Error */ +const int ESysEDQUOT = 122; /* quota exceeded */ // Error numbers + +int geterrno( ); +void seterrno( int err ); +WORD PosixToRunError( int PosixErrno ); + +const int sys_errn = 125; +extern const Char* sys_errlist [ 125/*# range 0..sys_errn-1*/ ]; /* EMEDIUMTYPE */ // BSD or LINUX ones + +String StrError( cint err ); +void PError( const String& S, cint errno ); + +int GetLastError(); + + +#endif + +extern int ExitCode; +const int maxExitCode = 65535; +typedef void ( * TOnShowException )( Char* Msg ); +extern TOnShowException OnShowException; + + +void RunError( WORD W ); +void RaiseLastOSError( ); +void HandleError( int err ); + +void Halt( WORD errnum ); +void Halt( ); + +int ExceptionErrorMessage( System::TObject* ExceptObject, void* ExceptAddr, Char* Buffer, int Size ); +void ShowException( TObject* ExceptObject, void* ExceptAddr ); +void Abort( ); +void OutOfMemoryError( ); + +String SysErrorMessage( int ErrorCode ); + + /* Exceptions */ + +class Exception: public System::TObject { + typedef System::TObject inherited; + friend class EAbort; + friend class EAbstractError; + friend class EAccessViolation; + friend class EAssertionFailed; + friend class EBusError; + friend class EControlC; + friend class EConvertError; + friend class EDivByZero; + friend class EExternal; + friend class EExternalException; + friend class EFormatError; + friend class EInOutError; + friend class EIntError; + friend class EIntOverflow; + friend class EIntfCastError; + friend class EInvalidCast; + friend class EInvalidContainer; + friend class EInvalidInsert; + friend class EInvalidOp; + friend class EInvalidPointer; + friend class EMathError; + friend class ENoThreadSupport; + friend class ENoWideStringSupport; + friend class EOSError; + friend class EOutOfMemory; + friend class EOverflow; + friend class EPackageError; + friend class EPrivilege; + friend class EPropReadOnly; + friend class EPropWriteOnly; + friend class ERangeError; + friend class ESafecallException; + friend class EStackOverflow; + friend class EUnderflow; + friend class EVariantError; + friend class EWin32Error; + friend class EZeroDivide; + friend class TMultiReadExclusiveWriteSynchronizer; + private: + String FMessage; + int FHelpContext = 0; + public: + Exception( const String& Msg ); + Exception( const String& Msg, const VECTOROFCONST& Args ); + Exception( PString ResString ); + Exception( PString ResString, const VECTOROFCONST& Args ); + Exception( const String& Msg, int AHelpContext ); + Exception( const String& Msg, const VECTOROFCONST& Args, int AHelpContext ); + Exception( PString ResString, int AHelpContext ); + Exception( PString ResString, const VECTOROFCONST& Args, int AHelpContext ); + + /* !!!! */ + /*# __property int HelpContext */ + virtual int ReadPropertyHelpContext( ) const; + virtual void WritePropertyHelpContext( int Value ); + /*# __property String Message */ + virtual String ReadPropertyMessage( ) const; + virtual void WritePropertyMessage( String Value ); + //public: + inline Exception () {} +}; + + +typedef System::TMetaClass* /*# Exception */ ExceptClass; + + +class EExternal: public Exception { + typedef Exception inherited; + public: + public: inline EExternal( const String Msg ) : inherited( Msg ) {} + public: inline EExternal( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EExternal( PString ResString ) : inherited( ResString ) {} + public: inline EExternal( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EExternal( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EExternal( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EExternal( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EExternal( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + /* Integer math Exceptions */ + + +class EIntError: public EExternal { + typedef EExternal inherited; + public: inline EIntError( const String Msg ) : inherited( Msg ) {} + public: inline EIntError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EIntError( PString ResString ) : inherited( ResString ) {} + public: inline EIntError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EIntError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EIntError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EIntError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EIntError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EDivByZero: public EIntError { + typedef EIntError inherited; + public: inline EDivByZero( const String Msg ) : inherited( Msg ) {} + public: inline EDivByZero( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EDivByZero( PString ResString ) : inherited( ResString ) {} + public: inline EDivByZero( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EDivByZero( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EDivByZero( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EDivByZero( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EDivByZero( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class ERangeError: public EIntError { + typedef EIntError inherited; + public: inline ERangeError( const String Msg ) : inherited( Msg ) {} + public: inline ERangeError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline ERangeError( PString ResString ) : inherited( ResString ) {} + public: inline ERangeError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline ERangeError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline ERangeError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline ERangeError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline ERangeError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EIntOverflow: public EIntError { + typedef EIntError inherited; + public: inline EIntOverflow( const String Msg ) : inherited( Msg ) {} + public: inline EIntOverflow( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EIntOverflow( PString ResString ) : inherited( ResString ) {} + public: inline EIntOverflow( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EIntOverflow( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EIntOverflow( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EIntOverflow( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EIntOverflow( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + /* general math errors */ + + +class EMathError: public EExternal { + typedef EExternal inherited; + public: inline EMathError( const String Msg ) : inherited( Msg ) {} + public: inline EMathError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EMathError( PString ResString ) : inherited( ResString ) {} + public: inline EMathError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EMathError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EMathError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EMathError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EMathError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EInvalidOp: public EMathError { + typedef EMathError inherited; + public: inline EInvalidOp( const String Msg ) : inherited( Msg ) {} + public: inline EInvalidOp( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EInvalidOp( PString ResString ) : inherited( ResString ) {} + public: inline EInvalidOp( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EInvalidOp( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EInvalidOp( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EInvalidOp( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EInvalidOp( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EZeroDivide: public EMathError { + typedef EMathError inherited; + public: inline EZeroDivide( const String Msg ) : inherited( Msg ) {} + public: inline EZeroDivide( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EZeroDivide( PString ResString ) : inherited( ResString ) {} + public: inline EZeroDivide( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EZeroDivide( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EZeroDivide( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EZeroDivide( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EZeroDivide( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EOverflow: public EMathError { + typedef EMathError inherited; + public: inline EOverflow( const String Msg ) : inherited( Msg ) {} + public: inline EOverflow( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EOverflow( PString ResString ) : inherited( ResString ) {} + public: inline EOverflow( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EOverflow( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EOverflow( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EOverflow( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EOverflow( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EUnderflow: public EMathError { + typedef EMathError inherited; + public: inline EUnderflow( const String Msg ) : inherited( Msg ) {} + public: inline EUnderflow( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EUnderflow( PString ResString ) : inherited( ResString ) {} + public: inline EUnderflow( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EUnderflow( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EUnderflow( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EUnderflow( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EUnderflow( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + /* Run-time and i/O errors */ + + +class EInOutError: public Exception { + typedef Exception inherited; + public: + int ErrorCode = 0; + inline EInOutError( const String Msg ) : inherited( Msg ) {} + inline EInOutError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + inline EInOutError( PString ResString ) : inherited( ResString ) {} + inline EInOutError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + inline EInOutError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + inline EInOutError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + inline EInOutError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + inline EInOutError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + + }; + + +class EHeapMemoryError: public Exception { + typedef Exception inherited; + public: + bool AllowFree = false; // access in InitExceptions( ) + protected: + virtual void FreeInstance( ); + public: inline EHeapMemoryError( const String Msg ) : inherited( Msg ) {} + public: inline EHeapMemoryError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EHeapMemoryError( PString ResString ) : inherited( ResString ) {} + public: inline EHeapMemoryError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EHeapMemoryError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EHeapMemoryError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EHeapMemoryError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EHeapMemoryError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +typedef EHeapMemoryError EHeapException; + +class EExternalException: public EExternal { + typedef EExternal inherited; + public: inline EExternalException( const String Msg ) : inherited( Msg ) {} + public: inline EExternalException( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EExternalException( PString ResString ) : inherited( ResString ) {} + public: inline EExternalException( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EExternalException( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EExternalException( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EExternalException( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EExternalException( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EInvalidPointer: public EHeapMemoryError { + typedef EHeapMemoryError inherited; + public: inline EInvalidPointer( const String Msg ) : inherited( Msg ) {} + public: inline EInvalidPointer( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EInvalidPointer( PString ResString ) : inherited( ResString ) {} + public: inline EInvalidPointer( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EInvalidPointer( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EInvalidPointer( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EInvalidPointer( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EInvalidPointer( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EOutOfMemory: public EHeapMemoryError { + typedef EHeapMemoryError inherited; + public: inline EOutOfMemory( const String Msg ) : inherited( Msg ) {} + public: inline EOutOfMemory( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EOutOfMemory( PString ResString ) : inherited( ResString ) {} + public: inline EOutOfMemory( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EOutOfMemory( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EOutOfMemory( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EOutOfMemory( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EOutOfMemory( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EInvalidCast: public Exception { + typedef Exception inherited; + public: inline EInvalidCast( const String Msg ) : inherited( Msg ) {} + public: inline EInvalidCast( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EInvalidCast( PString ResString ) : inherited( ResString ) {} + public: inline EInvalidCast( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EInvalidCast( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EInvalidCast( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EInvalidCast( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EInvalidCast( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EVariantError: public Exception { + typedef Exception inherited; + public: + int ErrCode = 0; + EVariantError( int Code ); + inline EVariantError( const String Msg ) : inherited( Msg ) {} + inline EVariantError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + inline EVariantError( PString ResString ) : inherited( ResString ) {} + inline EVariantError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + inline EVariantError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + inline EVariantError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + inline EVariantError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + inline EVariantError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + + }; + + +class EAccessViolation: public EExternal { + typedef EExternal inherited; + public: inline EAccessViolation( const String Msg ) : inherited( Msg ) {} + public: inline EAccessViolation( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EAccessViolation( PString ResString ) : inherited( ResString ) {} + public: inline EAccessViolation( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EAccessViolation( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EAccessViolation( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EAccessViolation( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EAccessViolation( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EBusError: public EAccessViolation { + typedef EAccessViolation inherited; + public: inline EBusError( const String Msg ) : inherited( Msg ) {} + public: inline EBusError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EBusError( PString ResString ) : inherited( ResString ) {} + public: inline EBusError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EBusError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EBusError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EBusError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EBusError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EPrivilege: public EExternal { + typedef EExternal inherited; + public: inline EPrivilege( const String Msg ) : inherited( Msg ) {} + public: inline EPrivilege( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EPrivilege( PString ResString ) : inherited( ResString ) {} + public: inline EPrivilege( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EPrivilege( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EPrivilege( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EPrivilege( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EPrivilege( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EStackOverflow: public EExternal { + typedef EExternal inherited; + public: inline EStackOverflow( const String Msg ) : inherited( Msg ) {} + public: inline EStackOverflow( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EStackOverflow( PString ResString ) : inherited( ResString ) {} + public: inline EStackOverflow( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EStackOverflow( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EStackOverflow( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EStackOverflow( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EStackOverflow( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EControlC: public EExternal { + typedef EExternal inherited; + public: inline EControlC( const String Msg ) : inherited( Msg ) {} + public: inline EControlC( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EControlC( PString ResString ) : inherited( ResString ) {} + public: inline EControlC( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EControlC( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EControlC( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EControlC( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EControlC( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + /* String conversion errors */ + + +class EConvertError: public Exception { + typedef Exception inherited; + public: inline EConvertError( const String Msg ) : inherited( Msg ) {} + public: inline EConvertError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EConvertError( PString ResString ) : inherited( ResString ) {} + public: inline EConvertError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EConvertError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EConvertError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EConvertError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EConvertError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EFormatError: public Exception { + typedef Exception inherited; + public: inline EFormatError( const String Msg ) : inherited( Msg ) {} + public: inline EFormatError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EFormatError( PString ResString ) : inherited( ResString ) {} + public: inline EFormatError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EFormatError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EFormatError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EFormatError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EFormatError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + /* other errors */ + + +class EAbort: public Exception { + typedef Exception inherited; + public: inline EAbort( const String Msg ) : inherited( Msg ) {} + public: inline EAbort( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EAbort( PString ResString ) : inherited( ResString ) {} + public: inline EAbort( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EAbort( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EAbort( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EAbort( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EAbort( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EAbstractError: public Exception { + typedef Exception inherited; + public: inline EAbstractError( const String Msg ) : inherited( Msg ) {} + public: inline EAbstractError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EAbstractError( PString ResString ) : inherited( ResString ) {} + public: inline EAbstractError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EAbstractError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EAbstractError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EAbstractError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EAbstractError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + }; + + +class EAssertionFailed: public Exception { + typedef Exception inherited; + public: inline EAssertionFailed( const String Msg ) : inherited( Msg ) {} + public: inline EAssertionFailed( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EAssertionFailed( PString ResString ) : inherited( ResString ) {} + public: inline EAssertionFailed( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EAssertionFailed( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EAssertionFailed( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EAssertionFailed( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EAssertionFailed( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EPropReadOnly: public Exception { + typedef Exception inherited; + public: inline EPropReadOnly( const String Msg ) : inherited( Msg ) {} + public: inline EPropReadOnly( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EPropReadOnly( PString ResString ) : inherited( ResString ) {} + public: inline EPropReadOnly( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EPropReadOnly( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EPropReadOnly( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EPropReadOnly( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EPropReadOnly( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EPropWriteOnly: public Exception { + typedef Exception inherited; + public: inline EPropWriteOnly( const String Msg ) : inherited( Msg ) {} + public: inline EPropWriteOnly( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EPropWriteOnly( PString ResString ) : inherited( ResString ) {} + public: inline EPropWriteOnly( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EPropWriteOnly( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EPropWriteOnly( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EPropWriteOnly( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EPropWriteOnly( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EIntfCastError: public Exception { + typedef Exception inherited; + public: inline EIntfCastError( const String Msg ) : inherited( Msg ) {} + public: inline EIntfCastError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EIntfCastError( PString ResString ) : inherited( ResString ) {} + public: inline EIntfCastError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EIntfCastError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EIntfCastError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EIntfCastError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EIntfCastError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EInvalidContainer: public Exception { + typedef Exception inherited; + public: inline EInvalidContainer( const String Msg ) : inherited( Msg ) {} + public: inline EInvalidContainer( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EInvalidContainer( PString ResString ) : inherited( ResString ) {} + public: inline EInvalidContainer( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EInvalidContainer( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EInvalidContainer( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EInvalidContainer( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EInvalidContainer( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EInvalidInsert: public Exception { + typedef Exception inherited; + public: inline EInvalidInsert( const String Msg ) : inherited( Msg ) {} + public: inline EInvalidInsert( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EInvalidInsert( PString ResString ) : inherited( ResString ) {} + public: inline EInvalidInsert( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EInvalidInsert( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EInvalidInsert( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EInvalidInsert( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EInvalidInsert( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EPackageError: public Exception { + typedef Exception inherited; + public: inline EPackageError( const String Msg ) : inherited( Msg ) {} + public: inline EPackageError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EPackageError( PString ResString ) : inherited( ResString ) {} + public: inline EPackageError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EPackageError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EPackageError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EPackageError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EPackageError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class EOSError: public Exception { + typedef Exception inherited; + public: + int ErrorCode = 0; + public: inline EOSError( const String Msg ) : inherited( Msg ) {} + public: inline EOSError( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EOSError( PString ResString ) : inherited( ResString ) {} + public: inline EOSError( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EOSError( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EOSError( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EOSError( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EOSError( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} + +}; + + +class ESafecallException: public Exception { + typedef Exception inherited; + public: inline ESafecallException( const String Msg ) : inherited( Msg ) {} + public: inline ESafecallException( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline ESafecallException( PString ResString ) : inherited( ResString ) {} + public: inline ESafecallException( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline ESafecallException( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline ESafecallException( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline ESafecallException( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline ESafecallException( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class ENoThreadSupport: public Exception { + typedef Exception inherited; + public: inline ENoThreadSupport( const String Msg ) : inherited( Msg ) {} + public: inline ENoThreadSupport( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline ENoThreadSupport( PString ResString ) : inherited( ResString ) {} + public: inline ENoThreadSupport( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline ENoThreadSupport( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline ENoThreadSupport( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline ENoThreadSupport( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline ENoThreadSupport( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +class ENoWideStringSupport: public Exception { + typedef Exception inherited; + public: inline ENoWideStringSupport( const String Msg ) : inherited( Msg ) {} + public: inline ENoWideStringSupport( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline ENoWideStringSupport( PString ResString ) : inherited( ResString ) {} + public: inline ENoWideStringSupport( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline ENoWideStringSupport( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline ENoWideStringSupport( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline ENoWideStringSupport( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline ENoWideStringSupport( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + +class EWin32Error: public Exception { + typedef Exception inherited; + public: + DWORD ErrorCode = 0; + public: inline EWin32Error( const String Msg ) : inherited( Msg ) {} + public: inline EWin32Error( const String Msg, const VECTOROFCONST& Args ) : inherited( Msg, Args ) {} + public: inline EWin32Error( PString ResString ) : inherited( ResString ) {} + public: inline EWin32Error( PString ResString, const VECTOROFCONST& Args ) : inherited( ResString, Args ) {} + public: inline EWin32Error( const String Msg, int AHelpContext ) : inherited( Msg, AHelpContext ) {} + public: inline EWin32Error( const String Msg, const VECTOROFCONST& Args, int AHelpContext ) : inherited( Msg, Args, AHelpContext ) {} + public: inline EWin32Error( PString ResString, int AHelpContext ) : inherited( ResString, AHelpContext ) {} + public: inline EWin32Error( PString ResString, const VECTOROFCONST& Args, int AHelpContext ) : inherited( ResString, Args, AHelpContext ) {} +}; + + +} // namespace System + +std::string ErrorString(const char* xpFormat, const std::string& xsValue); +std::wstring ErrorString(const wchar_t* xpFormat, const std::wstring& xsValue); + + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_sysfile.cpp b/OpenDSSC/Support/d2c_sysfile.cpp new file mode 100644 index 0000000..2b5581b --- /dev/null +++ b/OpenDSSC/Support/d2c_sysfile.cpp @@ -0,0 +1,4202 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_sysfile.h" +#include "d2c_system.h" +#include "d2c_sysstring.h" + +#include "d2c_sysexcept.h" +#include +#include "Sysutils.h" + +#include // strnlen +#ifdef linux +#include /* For SYS_xxx definitions */ +#include +#include +#include +typedef struct stat Stat; +#include +#include +#include +#include +#endif + +using namespace std; + +//#define _CRT_SECURE_NO_WARNINGS 1 + + +namespace System +{ + +#ifdef linux + +#include "d2c_sysmath.h" // Hi +#undef __GLIBC__ +#define __GLIBC__ 1 +#include //S_IWUSR etc. + + +cint fpopen( const char* Path, cint Flags, mode_t Mode ) +{ + cint r = open(Path, Flags | O_LARGEFILE, Mode); + return r==-1 ? -errno : r; +} + +cint fpopen( const wchar_t* Path, cint Flags, mode_t Mode ) +{ + string s = wstr2str(Path); + return fpopen(s.c_str(), Flags | O_LARGEFILE, Mode); +} + + + +cint fpclose( cint FD ) +{ + cint r = close(FD); + return r==-1 ? -errno : r; +} + + +off_t Fplseek( cint FD, off_t Offset, cint Whence ) +{ + return lseek(FD, Offset, Whence); +} + + +ssize_t fpRead( cint FD, char* Buf, size_t nBytes ) +{ + ssize_t r = read(FD, Buf, nBytes); + return r==-1 ? -errno : r; +} + + +ssize_t fpWrite( cint FD, const char* Buf, size_t nBytes ) +{ + ssize_t r = write(FD, Buf, nBytes); + return r==-1 ? -errno : r; +} + +// in SysUtils too +cint Fpunlink( const char* Path ) +{ + cint r = unlink(Path); + return r==-1 ? -errno : r; +} + + +cint Fprename( const char* old, const char* NewPath ) +{ + cint r = rename(old, NewPath); + return r==-1 ? -errno : r; +} + +cint fpstat( const char* Path, Stat& Buf ) +{ + cint r = stat(Path, &Buf); + return r==-1 ? -errno : r; +} + +/****************************************************************************** + --- Directory:Directory related calls --- +******************************************************************************/ + + +cint Fpchdir( const char* Path ) +{ + cint r = chdir(Path); + return r==-1 ? -errno : r; +} + + +cint Fpmkdir( const char* Path, mode_t Mode ) +{ + cint r = mkdir(Path, Mode); + return r==-1 ? -errno : r; +} + + +cint Fprmdir( const char* Path ) +{ + cint r = rmdir(Path); + return r==-1 ? -errno : r; +} + + +Dir* Fpopendir( const char* DirName ) +{ + Dir* result = NULL; + int FD = 0; + Stat st; + Dir* ptr = NULL; + if ( fpstat( (char*) DirName, st ) < 0 ) + return result; +/* is it A Dir ? */ + if ( ! ( ( ( st.st_mode & 0xF000 ) ) == 0x4000 ) ) + { + errno = ESysENOTDIR; + return result; + } +/* Open it*/ + FD = fpopen( DirName, O_RDONLY, 438 ); + if ( FD < 0 ) + return result; + ptr = new Dir; + if ( ptr == NULL ) + return result; + ptr->dd_buf = new dirent; + if ( ptr->dd_buf == NULL ) + return result; + ptr->dd_fd = FD; + ptr->dd_loc = 0; + ptr->dd_size = 0; + ptr->dd_nextoff = 0; + ptr->dd_max = sizeof( *ptr->dd_buf ); + return ptr; +} + +Dir* Fpopendir( const wchar_t* DirName ) +{ + string s = wstr2str(DirName); + return Fpopendir(s.c_str()); +} + + + + +cint Fpclosedir( Dir* dirP ) +{ + cint result = 0; + result = fpclose( dirP->dd_fd ); + delete dirP->dd_buf; + delete dirP; + return result; +} + + +dirent* Fpreaddir( Dir* dirP ) +{ + dirent* result = NULL; + int Bytes = 0; + dirent* dp = NULL; + do + { + if ( dirP->dd_nextoff >= dirP->dd_size ) + { + Bytes = syscall( SYS_getdents64, dirP->dd_fd, dirP->dd_buf, dirP->dd_max ); + if ( Bytes <= 0 ) + { + result = NULL; + return result; + } + dirP->dd_size = Bytes; + dirP->dd_nextoff = 0; + } + dp = ((dirent*) ( ((PtrUInt) dirP->dd_buf ) + dirP->dd_nextoff ) ); + dirP->dd_nextoff += dp->d_reclen; + dirP->dd_loc += dp->d_reclen; + } + while ( ! ( dp->d_fileno != 0 ) ); // don'T show deleted files + return dp; +} + +#endif +typedef unsigned char* PByte; +const int TextRecNameLength = 256; +const int TextRecBufSize = 256; +const int FilerecNameLength = 255; +#ifndef linux +THandle UnusedHandle = ((THandle) - 1 ); +THandle StdInputHandle = 0; +THandle StdOutputHandle = 0; +THandle StdErrorHandle = 0; +#endif +bool FileNameCaseSensitive = true; +#ifdef linux +bool CtrlZMarksEOF = false; /* #26 not considered as end of File */ +TTextLineBreakStyle DefaultTextLineBreakStyle = tlbsLF; +#else +bool CtrlZMarksEOF = true; /* #26 is considered as end of File */ +TTextLineBreakStyle DefaultTextLineBreakStyle = tlbsCRLF; +#endif + +WORD InOutRes = 0; + +TSet < UChar, 0, 255 > AllowDirectorySeparators = ( TSet < UChar, 0, 255 >() << _T('\\') << _T('/') ); +TSet < UChar, 0, 255 > AllowDriveSeparators = ( TSet < UChar, 0, 255 >() << _T(':') ); + +TTextRec ErrOutput, Output, Input, Stdout, Stderr; +unsigned char FileMode = 2; + + +const char ctlbsLF[] = "\x0a"; +const char ctlbsCRLF[] = "\x0d\x0a"; +const char ctlbsCR[] = "\x0d"; + +void StrCpy(char* pDest, const char* pSource) +{ + strcpy( pDest, pSource); +} + +void StrCpy(wchar_t* pDest, const wchar_t* pSource) +{ + wcscpy( pDest, pSource); +} + +void StrCpy(wchar_t* pDest, const char* pSource) +{ + wstring ws = str2wstr(pSource); + wcscpy( pDest, ws.c_str()); +} + +void StrnCpy(char* pDest, const char* pSource, int len) +{ + strncpy( pDest, pSource, len); +} + +void StrnCpy(wchar_t* pDest, const wchar_t* pSource, int len) +{ + wcsncpy( pDest, pSource, len); +} + +char* strcpy_max(char* pDest, const char* pSource, int SourceLen, int High) +{ + int len = ((SourceLen > High) ? High : SourceLen); + strncpy( pDest, pSource, len); + pDest[len] = '\0'; + return pDest; +} + +int StrLen(const char* p) +{ + return strlen(p); +} + +int StrLen(const wchar_t* p) +{ + return wcslen(p); +} + +wchar_t* strcpy_max(wchar_t* pDest, const wchar_t* pSource, int SourceLen, int High) +{ + int len = ((SourceLen > High) ? High : SourceLen); + wcsncpy( pDest, pSource, len); + pDest[len] = L'\0'; + return pDest; +} + + +#ifdef linux +/****************************************************************************** + Low Level File routines +******************************************************************************/ + +bool do_isdevice( THandle Handle ) +/* + interface to Unix IOCTL call. + performs various operations ON the FILEDESCRIPTOR Handle. + Ndx describes the operation to perform. + Data Points to Data needed for the Ndx function. the structure of this + Data is function-dependent. +*/ +{ + bool result = false; + const int IOCtl_TCGETS = 0x5401; // TCGETS is also in Termios.inc, but the sysunix needs only this + + unsigned char Data[ 256/*# range 0..255*/ ]; /*large enough for Termios info*/ + result = ( ioctl( Handle, IOCtl_TCGETS, &Data[0] ) != - 1 ); + return result; +} +#else +bool do_isdevice( THandle Handle ) +{ + bool result = false; + result = ( GetFileType( Handle ) == 2 ); + return result; +} +#endif + +#ifdef linux +void do_close( THandle Handle ) +{ + fpclose( ((cint) Handle ) ); +} +#else +void do_close( THandle h ) +{ + if ( do_isdevice( h ) ) + return; + CloseHandle( (void*) h ); +} +#endif + +#ifdef linux +WORD Errno2InOutRes( ) +{ + InOutRes = PosixToRunError( geterrno() ); + return InOutRes; +} +#else + +void Errno2InOutRes( ) +{ + WORD res = 0; + int* pErrno = NULL; + /* DO NOT MODIFY UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING */ + pErrno = &errno; + switch ( *pErrno ) + { + case ERROR_WRITE_PROTECT: + case ERROR_BAD_UNIT: + case ERROR_NOT_READY: + case ERROR_BAD_COMMAND: + case ERROR_CRC: + case ERROR_BAD_LENGTH: + case ERROR_SEEK: + case ERROR_NOT_DOS_DISK: + case ERROR_SECTOR_NOT_FOUND: + case ERROR_OUT_OF_PAPER: + case ERROR_WRITE_FAULT: + case ERROR_READ_FAULT: + case ERROR_GEN_FAILURE: + { + /* This is the offset to the Win32 to add to directly map */ + /* to the DOS/TP compatible error codes when in this range */ + res = ((WORD) *pErrno ) + 131; + } + break; + case ERROR_DIR_NOT_EMPTY: + case ERROR_ALREADY_EXISTS: + case ERROR_SHARING_VIOLATION: + { + res = 5; + } + break; + default: + { + /* other error codes can directly be mapped */ + res = ((WORD) *pErrno ); + } + } + *pErrno = 0; + InOutRes = res; +} +#endif + +#ifdef linux +int64_t do_seekend( THandle Handle ) +{ + int64_t result = 0; + result = Fplseek( Handle, 0, SEEK_END ); + if ( result < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; + return result; +} +#else + +int64_t do_seekend( THandle Handle ) +{ + int64_t result; + if (( SetFilePointerEx != NULL ) ) + { + LARGE_INTEGER li; + li.QuadPart = 0; + LARGE_INTEGER li2; + if ( ! ( SetFilePointerEx( Handle, li, &li2, FILE_END ) ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + result = li2.QuadPart; + } + else + { +// do_seekend:=SetFilePointer(handle,0,nil,FILE_END); +// if do_seekend=-1 then + result = SetFilePointer( Handle, 0, NULL, FILE_END ); + if ( result == - 1 ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + } + return result; +} +#endif + +void DoDirSeparators( char* P ) +{ + unsigned int i = 0; + for ( i = 0; i <= strlen( P ); i++) + if (P[i] == '\\' || P[i] == '/' ) + P[i] = DirectorySeparator; +} + +void DoDirSeparators( wchar_t* P ) +{ + unsigned int i = 0; + for ( i = 0; i <= wcslen( P ); i++) + if (P[i] == L'\\' || P[i] == L'/' ) + P[i] = DirectorySeparator; +} + +#ifdef linux +void Do_Open( void* F, Char* P, int Flags ) +/* + FileRec and TextRec have both Handle and Mode as the First items So + they could use the same routine for opening/creating. + when (Flags and $100) the File will be Append + when (Flags and $1000) the File will be Truncate/rewritten + when (Flags and $10000) there is no Check for Close (needed for textfiles) +*/ +{ + + + /* read/write permission for everyone */ + const int MODE_OPEN = S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH; + cint oflags = 0; +/* Close First if opened */ + if ( ( ( Flags & 0x10000 ) ) == 0 ) + { + switch ( ((TFileRec*) F )->Mode ) + { + case fmInput: case fmOutput: case fmInOut: + do_close( ((TFileRec*) F )->Handle ); + break; + case fmClosed: + break; + default: + { + InOutRes = 102; /*not assigned*/ + return; + } + } + } +/* Reset File Handle */ + ((TFileRec*) F )->Handle = UnusedHandle; +/* we do the conversion of filemodes here, concentrated ON 1 place */ + switch ( Flags & 3 ) + { + case 0: + { + oflags = O_RDONLY; + ((TFileRec*) F )->Mode = fmInput; + } + break; + case 1: + { + oflags = O_WRONLY; + ((TFileRec*) F )->Mode = fmOutput; + } + break; + case 2: + { + oflags = O_RDWR; + ((TFileRec*) F )->Mode = fmInOut; + } + break; + } + if ( ( ( Flags & 0x1000 ) ) == 0x1000 ) + oflags = oflags | ( O_CREAT | O_TRUNC ); + else + if ( ( ( Flags & 0x100 ) ) == 0x100 ) + oflags = oflags | ( O_APPEND ); +/* empty Name is special */ + if ( P[0] == _T('\x00') ) + { + switch ( ((TFileRec*) F )->Mode ) + { + case fmInput: + ((TFileRec*) F )->Handle = STDIN_FILENO; + break; + case fmInOut: case /* this is set by Rewrite */ fmOutput: + ((TFileRec*) F )->Handle = STDOUT_FILENO; + break; + case fmAppend: + { + ((TFileRec*) F )->Handle = STDOUT_FILENO; + ((TFileRec*) F )->Mode = fmOutput; /*fool fmAppend*/ + } + break; + } + return; + } +/* real Open call */ + ((TFileRec*) F )->Handle = fpopen( P, oflags, MODE_OPEN ); + if ( ( ((TFileRec*) F )->Handle < 0 ) && ( geterrno() == ESysEROFS ) && ( ( ( oflags & O_RDWR ) ) != 0 ) ) + { + oflags = oflags & ~ ( O_RDWR ); + ((TFileRec*) F )->Handle = fpopen( P, oflags, MODE_OPEN ); + } + if ( ((TFileRec*) F )->Handle < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} +#else +void Do_Open( void* f, Char* P, int Flags ) +/* + filerec and textrec have both handle and mode as the first items so + they could use the same routine for opening/creating. + when (flags and $100) the file will be append + when (flags and $1000) the file will be truncate/rewritten + when (flags and $10000) there is no check for close (needed for textfiles) +*/ +{ + // in winnt.h const int FILE_SHARE_READ = 0x00000001; + // in winnt.h const int FILE_SHARE_WRITE = 0x00000002; + int shflags = 0, oflags = 0, cd = 0; + SECURITY_ATTRIBUTES security; + DoDirSeparators( P ); + /* close first if opened */ + if ( ( ( Flags & 0x10000 ) ) == 0 ) + { + switch ( ((TFileRec*) f )->Mode ) + { + case fmInput: + case fmOutput: + case fmInOut: + do_close( ((TFileRec*) f )->Handle ); + break; + case fmClosed: + break; + default: + { + /*not assigned*/ + InOutRes = 102; + return; + } + } + } + /* reset file handle */ + ((TFileRec*) f )->Handle = UnusedHandle; + /* convert filesharing */ + shflags = 0; + if ( ( FileMode & fmShareExclusive ) == fmShareExclusive ) + ;/* no sharing */ + else + if ( ( FileMode == fmShareCompat ) || ( ( ( FileMode & fmShareDenyWrite ) ) == fmShareDenyWrite ) ) + shflags = FILE_SHARE_READ; + else + if ( ( ( FileMode & fmShareDenyRead ) ) == fmShareDenyRead ) + shflags = FILE_SHARE_WRITE; + else + if ( ( ( FileMode & fmShareDenyNone ) ) == fmShareDenyNone ) + shflags = FILE_SHARE_READ + FILE_SHARE_WRITE; + /* convert FileMode to filerec modes */ + switch ( Flags & 3 ) + { + case 0: + { + ((TFileRec*) f )->Mode = fmInput; + oflags = ((int) GENERIC_READ ); + } + break; + case 1: + { + ((TFileRec*) f )->Mode = fmOutput; + oflags = ((int) GENERIC_WRITE ); + } + break; + case 2: + { + ((TFileRec*) f )->Mode = fmInOut; + oflags = ((int) ( GENERIC_WRITE | GENERIC_READ ) ); + } + break; + } + /* create it ? */ + if ( ( ( Flags & 0x1000 ) ) != 0 ) + cd = CREATE_ALWAYS; + /* or Append/Open ? */ + else + cd = OPEN_EXISTING; + /* empty name is special */ + if ( P[0] == _T('\x00') ) + { + switch ( ((TFileRec*) f )->Mode ) + { + case fmInput: + ((TFileRec*) f )->Handle = StdInputHandle; + break; + case fmInOut: + case /* this is set by rewrite */ fmOutput: + ((TFileRec*) f )->Handle = StdOutputHandle; + break; + case fmAppend: + { + ((TFileRec*) f )->Handle = StdOutputHandle; + ((TFileRec*) f )->Mode = fmOutput; /*fool fmappend*/ + } + break; + } + return; + } + security.nLength = sizeof( SECURITY_ATTRIBUTES ); + security.bInheritHandle = true; + security.lpSecurityDescriptor = NULL; + ((TFileRec*) f )->Handle = CreateFile( P, oflags, shflags, &security, cd, FILE_ATTRIBUTE_NORMAL, 0 ); + + /* append mode */ + if ( ( ( ( Flags & 0x100 ) ) != 0 ) && ( ((TFileRec*) f )->Handle != 0 ) && ( ((TFileRec*) f )->Handle != UnusedHandle ) ) + { + do_seekend( ((TFileRec*) f )->Handle ); + ((TFileRec*) f )->Mode = fmOutput; /*fool fmappend*/ + } + + /* get errors */ + /* handle -1 is returned sometimes !! (PM) */ + if ( ( ((TFileRec*) f )->Handle == 0 ) || ( ((TFileRec*) f )->Handle == UnusedHandle ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } +} +#endif + +#ifdef linux + +typedef mode_t mode_t; +typedef mode_t* pMode; + + +bool FpS_ISDIR( mode_t m ) +{ + return ( ( ( m & S_IFMT ) ) == S_IFDIR ); +} + +void do_erase( char* P ) +{ + Stat FileInfo; + /* verify if the Filename is actually A Directory */ + /* if So return Error and do nothing, as defined */ + /* by Posix */ + if ( fpstat( P, FileInfo ) < 0 ) + { + Errno2InOutRes(); + return; + } + if ( FpS_ISDIR( FileInfo.st_mode ) ) + { + InOutRes = 2; + return; + } + if ( Fpunlink( P ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} + +void do_erase( wchar_t* P ) +{ + string s = wstr2str(P); + do_erase((char*) s.c_str()); +} +#else + +void do_erase( char* P ) +{ + DoDirSeparators( P ); + // if DeleteFile(p)=0 then + if ( /*# windows::*/ DeleteFileA( P ) == ((BOOL) 0 ) ) // dme + { + errno = GetLastError(); + if ( errno == 5 ) + { + if ( ( ( GetFileAttributesA( P ) & FILE_ATTRIBUTE_DIRECTORY ) ) == FILE_ATTRIBUTE_DIRECTORY ) + errno = 2; + } + Errno2InOutRes(); + } +} + +void do_erase( wchar_t* P ) +{ + DoDirSeparators( P ); + // if DeleteFile(p)=0 then + if ( /*# windows::*/ DeleteFileW( P ) == ((BOOL) 0 ) ) // dme + { + errno = GetLastError(); + if ( errno == 5 ) + { + if ( ( ( GetFileAttributesW( P ) & FILE_ATTRIBUTE_DIRECTORY ) ) == FILE_ATTRIBUTE_DIRECTORY ) + errno = 2; + } + Errno2InOutRes(); + } +} +#endif + +#ifdef linux +void do_rename( const char* p1, const char* p2 ) +{ + if ( Fprename( p1, p2 ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} + +void do_rename( const wchar_t* p1, const char* p2 ) +{ + string s1 = wstr2str(p1); + if ( Fprename( s1.c_str(), p2 ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} +#else +void do_rename( char* p1, char* p2 ) +{ + DoDirSeparators( p1 ); + DoDirSeparators( p2 ); + if ( MoveFileA( p1, p2 ) == ((BOOL) 0 ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } +} + +void do_rename( wchar_t* p1, char* p2 ) +{ + string s1 = wstr2str(p1); + do_rename((char*) s1.c_str(), p2); +} +#endif + + +#ifdef linux +int do_write( THandle Handle, void* Addr, int Len ) +{ + int result = 0; + cint j = 0; + do + { + result = fpWrite( Handle, (char*) Addr, Len ); + j = geterrno(); + } + while ( ! ( ( result != - 1 ) || ( ( j != ESysEINTR ) && ( j != ESysEAGAIN ) ) ) ); + if ( result < 0 ) + { + Errno2InOutRes(); + result = 0; + } + else + InOutRes = 0; + return result; +} +#else +int do_write( THandle h, void* addr, int Len ) +{ + int result = 0; + DWORD size = 0; + if ( WriteFile( h, addr, Len, &size, NULL ) == ((BOOL) 0 ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + result = size; + return result; +} +#endif + +#ifdef linux +int do_read( THandle Handle, void* Addr, int Len ) +{ + int result = 0; + cint j = 0; + do + { + result = fpRead( Handle, (char*) Addr, Len ); + j = geterrno(); + } + while ( ! ( ( result != - 1 ) || ( ( j != ESysEINTR ) && ( j != ESysEAGAIN ) ) ) ); + if ( result < 0 ) + { + Errno2InOutRes(); + result = 0; + } + else + InOutRes = 0; + return result; +} +#else +int do_read( THandle h, void* addr, int Len ) +{ + int result = 0; + DWORD _result = 0; + if ( ReadFile( (void*) h, addr, Len, &_result, NULL ) == ((BOOL) 0 ) ) + { + errno = GetLastError(); + if ( errno == ERROR_BROKEN_PIPE ) + errno = 0; + else + Errno2InOutRes(); + } + result = _result; + return result; +} +#endif + +#ifdef linux +int64_t do_filepos( THandle Handle ) +{ + int64_t result = 0; + result = Fplseek( Handle, 0, SEEK_CUR ); + if ( result < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; + return result; +} +#else +int64_t do_filepos( THandle Handle ) +{ + int64_t result; + int l = 0; + if (( SetFilePointerEx != NULL ) ) + { + LARGE_INTEGER li; + li.QuadPart = 0; + LARGE_INTEGER liResult; + + if ( ! ( SetFilePointerEx( Handle, li, &liResult, FILE_CURRENT ) ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + result = liResult.QuadPart; + } + else + { + l = SetFilePointer( Handle, 0, NULL, FILE_CURRENT ); + if ( l == - 1 ) + { + l = 0; + errno = GetLastError(); + Errno2InOutRes(); + } + result = l; + } + return result; +} +#endif + +#ifdef linux +void do_seek( THandle Handle, int64_t pos ) +{ + if ( Fplseek( Handle, pos, SEEK_SET ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} +#else +void do_seek( THandle Handle, int64_t Pos ) +{ + if (( SetFilePointerEx != NULL ) ) + { + LARGE_INTEGER li; + li.QuadPart = 0; + LARGE_INTEGER liPos; + liPos.QuadPart = Pos; + if ( ! ( SetFilePointerEx( Handle, liPos, &li, FILE_BEGIN ) ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + } + else + { + if ( SetFilePointer( Handle, (long) Pos, NULL, FILE_BEGIN ) == ((DWORD) - 1 ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } + } +} +#endif + +#ifdef linux +cint fpfstat( cint FD, Stat& sb ) +{ + cint r = fstat(FD, &sb); + return r==-1 ? -errno : r; +} + +int64_t do_filesize( THandle Handle ) +{ + int64_t result = 0; + Stat info; + int ret = 0; + ret = fpfstat( Handle, info ); + if ( ret == 0 ) + result = info.st_size; + else + result = 0; + if ( ret < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; + return result; +} +#else +int64_t do_filesize( THandle Handle ) +{ + int64_t result = 0; + int64_t aktfilepos = 0; + aktfilepos = do_filepos( Handle ); + result = do_seekend( Handle ); + do_seek( Handle, aktfilepos ); + return result; +} +#endif + +// Truncate at A given position +#ifdef linux +cint Fpftruncate( cint FD, off_t flength ) +/* see Notes lseek. this one is completely Similar for the Parameter (but +doesn'T have the ReturnValue 64-bit problem)*/ +{ + cint r = ftruncate(FD, flength); + return r==-1 ? -errno : r; +} + +void do_truncate( THandle Handle, int fPos ) +{ + /* should be simulated in cases Where it is not */ + /* available. */ + if ( Fpftruncate( Handle, fPos ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} +#else +void do_truncate( THandle Handle, int64_t Pos ) +{ + do_seek( Handle, Pos ); + if ( ! ( SetEndOfFile( Handle ) ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } +} +#endif + +void FileCloseFuncA( TTextRec& t ) +{ + do_close( t.Handle ); + t.Handle = UnusedHandle; +} + +void FileReadFuncA( TTextRec& t ) +{ + t.BufEnd = do_read( t.Handle, t.BufPtr, t.BufSize ); + t.BufPos = 0; +} + +void FileWriteFuncA( TTextRec& t ) +{ + unsigned int i = 0; + /* prevent unecessary system call */ + if ( t.BufPos == 0 ) + return; + i = do_write( t.Handle, t.BufPtr, t.BufPos ); + if ( i != t.BufPos ) + InOutRes = 101; + t.BufPos = 0; +} + +void FileOpenFuncA( TTextRec& t ) +{ + int Flags = 0; + switch ( t.Mode ) + { + case fmInput: + Flags = 0x10000; + break; + case fmOutput: + Flags = 0x11001; + break; + case fmAppend: + Flags = 0x10101; + break; + default: + { + InOutRes = 102; + return; + } + } + Do_Open( &t, t.Name, Flags ); + t.CloseFunc = (void*) FileCloseFuncA; + t.FlushFunc = NULL; + if ( t.Mode == fmInput ) + t.InOutFunc = (void*) FileReadFuncA; + else + { + t.InOutFunc = (void*) FileWriteFuncA; + /* Only install flushing if its a NOT a file, and only check if there + was no error opening the file, becuase else we always get a bad + file handle error 6 (PFV) */ + if ( ( InOutRes == 0 ) && do_isdevice( t.Handle ) ) + t.FlushFunc = (void*) FileWriteFuncA; + } +} + + +void CloseFile( TFileRec& f ) +/* + CloseFile file f +*/ +{ + if ( InOutRes != 0 ) + return; + switch ( f.Mode ) + { + case fmInOut: + case fmInput: + case fmOutput: + { + do_close( f.Handle ); + f.Mode = fmClosed; + } + break; + default: + InOutRes = 103; + } +} + + +void Close( TFileRec& f ) +{ + CloseFile(f); +} + +void CloseFile( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + switch ( t.Mode ) + { + case fmInput: + case fmOutput: + case fmAppend: + { + /* Write pending buffer */ + if ( t.Mode == fmOutput ) + FileFunc( t.InOutFunc )( t ); + /* Only close functions not connected to Stdout.*/ +#ifdef linux + if ( ( t.Handle != STDIN_FILENO ) && ( t.Handle != STDOUT_FILENO ) && ( t.Handle != STDERR_FILENO ) ) +#else + if ( ( t.Handle != StdInputHandle ) && ( t.Handle != StdOutputHandle ) && ( t.Handle != StdErrorHandle ) ) +#endif + FileFunc( t.CloseFunc )( t ); + t.Mode = fmClosed; + /* Reset buffer for safety */ + t.BufPos = 0; + t.BufEnd = 0; + } + break; + default: + InOutRes = 103; + } +} + + +void Close( TTextRec& t ) +{ + CloseFile(t); +} + +void OpenText( TTextRec& t, int Mode, int defHdl ) +{ + switch ( t.Mode ) + { + case fmInput: /*This gives the fastest code*/ + case fmOutput: + case fmInOut: + CloseFile( t ); + break; + case fmClosed: + break; + default: + { + InOutRes = 102; + return; + } + } + t.Mode = Mode; + t.BufPos = 0; + t.BufEnd = 0; + FileFunc( t.OpenFunc )( t ); + /* reset the mode to closed when an error has occured */ + if ( InOutRes != 0 ) + t.Mode = fmClosed; +} + + +int64_t FilePos( TFileRec& f, int l) +/* + Return current Position In file f in records +*/ +{ + int64_t result = 0; + result = 0; + if ( InOutRes != 0 ) + return result; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: case fmInput: case fmOutput: + result = do_filepos( f.Handle ) / l; //((TFileRec*) &f )->RecSize; + break; + default: + InOutRes = 103; + } + return result; +} + + +int64_t FileSize( TFileRec& f ) +/* + Return the size of file f in records +*/ +{ + int64_t result = 0; + result = 0; + if ( InOutRes != 0 ) + return result; + switch ( f.Mode ) + { + case fmInOut: case fmInput: case fmOutput: + { + if ( f.RecSize > 0 ) + result = do_filesize( f.Handle ) / f.RecSize; + } + break; + default: + InOutRes = 103; + } + return result; +} + + + +bool Eof( TFileRec& f, int l ) +/* + Return True if we're at the end of the file f, else False is returned +*/ +{ + bool result = false; + result = false; + if ( InOutRes != 0 ) + return result; + switch ( ((TFileRec*) &f )->Mode ) + { + case + /*Can't use do_ routines because we need record support*/ fmInOut: case fmInput: case fmOutput: + result = ( FileSize( f ) <= FilePos( f, l ) ); + break; + default: + InOutRes = 103; + } + return result; +} + + + +bool Eof( TTextRec& t ) +{ + bool result = false; + result = true; + if ( InOutRes != 0 ) + return result; //(true); + if ( t.Mode != fmInput ) + { + if ( t.Mode == fmOutput ) + InOutRes = 104; + else + InOutRes = 103; + return result; //(true); + } + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + return result; //(true); + } + result = CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ); + return result; +} + + +bool Eof( ) +{ + bool result = false; + result = Eof( Input ); + return result; +} + + +void Seek( TTypedFile& f, int64_t Pos ) +/* + Goto record Pos in file f +*/ +{ + if ( InOutRes != 0 ) + return; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: case fmInput: case fmOutput: + do_seek( ((TFileRec*) &f )->Handle, Pos * ((TFileRec*) &f )->RecSize ); + break; + default: + InOutRes = 103; + } +} + + +void Truncate( TFileRec& f, int RecSize ) +/* + Truncate/Cut file f at the current record Position +*/ +{ + if ( InOutRes != 0 ) + return; + switch ( f.Mode ) + { + case fmInOut: case fmOutput: + do_truncate( f.Handle, FilePos( f, RecSize ) * RecSize); + break; + default: + InOutRes = 103; + } +} + + +void Erase( TTypedFile& f ) +{ + if ( InOutRes != 0 ) + return; + if ( ((TFileRec*) &f )->Mode == fmClosed ) + do_erase( (Char*) ( &((TFileRec*) &f )->Name[0] ) ); +} + + + + +void Rename( TTypedFile& f, char* P ) +{ + if ( InOutRes != 0 ) + return; + if ( f.Mode == fmClosed ) + { + do_rename( f.Name, P ); + /* check error code of do_rename */ + if ( InOutRes == 0 ) + StrCpy( f.Name, P ); + } +} + + +void Rename( TTypedFile& f, const char* xp ) +{ + char p[ FilerecNameLength + 1 ]; + strcpy_max(p, xp, StrLen(xp), FilerecNameLength); + Rename( f, p ); +} + +void Rename( TTypedFile& f, wchar_t* P ) +{ + string s = wstr2str(P); + Rename(f, s.c_str()); +} + +void Rename( TTypedFile& f, const wchar_t* P ) +{ + string s = wstr2str(P); + Rename(f, s.c_str()); +} + +void Rename( TTypedFile& f, const AnsiString& s ) +{ + char P[ FilerecNameLength + 1 ]; + if ( InOutRes != 0 ) + return; + strcpy_max(P, s.c_str(), s.length(), FilerecNameLength); + Rename( f, P ); +} + +void Rename( TTypedFile& f, const WideString& S ) +{ + string s = wstr2str(S); + Rename( f, s ); +} + +void Rename( TTypedFile& f, char c ) +{ + char P[ 2/*# range 0..1*/ ]; + if ( InOutRes != 0 ) + return; + P[0] = c; + P[1] = '\x00'; + Rename( f, P ); +} + +void Rename( TTypedFile& f, wchar_t xc ) +{ + char c = wchar2char(xc); + Rename( f, c ); +} + +void Rename( TTextRec& t, char* P ) +{ + if ( InOutRes != 0 ) + return; + if ( t.Mode == fmClosed ) + { + do_rename( t.Name, P); + /* check error code of do_rename */ + if ( InOutRes == 0 ) + { + StrCpy( t.Name, P ); + } + } +} + +void Rename( TTextRec& t, wchar_t* P ) +{ + string s = wstr2str(P); + Rename(t, s); +} + + +void Rename( TTextRec& t, const char* xp ) +{ + char p[ 256 ]; + StrnCpy(p, xp, 255); + Rename( t, p ); +} + +void Rename( TTextRec& t, const wchar_t* P ) +{ + string s = wstr2str(P); + Rename(t, s); +} + +void Rename( TTextRec& t, const AnsiString& S ) +{ + char P[ FilerecNameLength + 1 ]; + if ( InOutRes != 0 ) + return; + strcpy_max(P, S.c_str(), S.length(), FilerecNameLength); + Rename( t, P ); +} + +void Rename( TTextRec& t, const WideString& S ) +{ + string s = wstr2str(S); + Rename( t, s ); +} + +void Rename( TTextRec& t, char c ) +{ + char P[ 2/*# range 0..1*/ ]; + if ( InOutRes != 0 ) + return; + P[0] = c; + P[1] = '\x00'; + Rename( t, P); +} + +void Rename( TTextRec& t, wchar_t xc ) +{ + char c = wchar2char(xc); + Rename( t, c); +} + + +void Rewrite( TFileRec& f, int l ) +/* + Create file f with recordsize of l +*/ +{ + if ( InOutRes != 0 ) + return; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: case fmInput: case fmOutput: + CloseFile( f ); + break; + case fmClosed: + break; + default: + { + InOutRes = 102; + return; + } + } + if ( l == 0 ) + InOutRes = 2; + else + { + /* Reopen with FileMode 2, to be Tp compatible (PFV) */ + Do_Open( &f, f.Name, 0x1002 ); + f.RecSize = l; + } +} + + +void Rewrite( TFileRec& f ) +/* + Create file with (default) 128 byte records +*/ +{ + if ( InOutRes != 0 ) + return; + Rewrite( f, 128 ); +} + + +void Rewrite( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + OpenText( t, fmOutput, 1 ); +} + + +void Reset( TFileRec& f, int l ) +/* + Open file f with recordsize of l and FileMode +*/ +{ + if ( InOutRes != 0 ) + return; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: case fmInput: case fmOutput: + CloseFile( f ); + break; + case fmClosed: + break; + default: + { + InOutRes = 102; + return; + } + } + if ( l == 0 ) + InOutRes = 2; + else + { + Do_Open( &f, f.Name, FileMode ); + f.RecSize = l; + } +} + + +void Reset( TFileRec& f ) +/* + Open file with (default) 128 byte records +*/ +{ + if ( InOutRes != 0 ) + return; + Reset( f, 128 ); +} + +void Reset( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + OpenText( t, fmInput, 0 ); +} + + +intptr_t GetFileHandle( file& F ) +{ + return (intptr_t) ((TFileRec*) &F )->Handle; +} + + +intptr_t GetFileHandle( TTextRec& F ) +{ + return (intptr_t) ((TTextRec*) &F )->Handle; +} + + +void BlockWrite64( TTypedFile& f, void* buf, int64_t Count, int64_t& Result ) +/* + Write Count records from Buf to file f, return written records in result +*/ +{ + Result = 0; + if ( InOutRes != 0 ) + return; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: + case fmOutput: + Result = do_write( ((TFileRec*) &f )->Handle, buf, (int) Count * ((TFileRec*) &f )->RecSize ) / ((TFileRec*) &f )->RecSize; + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + +void BlockWrite( TTypedFile& f, void* buf, int Count, int64_t& Result ) +/* + Write Count records from Buf to file f, return written records in result +*/ +{ + BlockWrite64( f, buf, Count, Result ); +} + + +void BlockWrite( TTypedFile& f, void* buf, int Count, int& Result ) +/* + Write Count records from Buf to file f, return written records in result +*/ +{ + int64_t l = 0; + BlockWrite64( f, buf, Count, l ); + Result = (int) l; +} + +void BlockWrite( TTypedFile& f, void* buf, WORD Count, WORD& Result ) +/* + Write Count records from Buf to file f, return written records in Result +*/ +{ + int64_t l = 0; + BlockWrite64( f, buf, Count, l ); + Result = (WORD) l; +} + +void BlockWrite( TTypedFile& f, void* buf, unsigned int Count, unsigned int& Result ) +/* + Write Count records from Buf to file f, return written records in Result +*/ +{ + int64_t l = 0; + BlockWrite64( f, buf, Count, l ); + Result = (unsigned int) l; +} + +void BlockWrite( TTypedFile& f, void* buf, WORD Count, int& Result ) +/* + Write Count records from Buf to file f, return written records in Result +*/ +{ + int64_t l = 0; + BlockWrite64( f, buf, Count, l ); + Result = (int) l; +} + +void BlockWrite( TTypedFile& f, void* buf, int Count ) +/* + Write Count records from Buf to file f, if none a Read and Count>0 then + InOutRes is set +*/ +{ + int64_t result = 0; + BlockWrite64( f, buf, Count, result ); + if ( ( InOutRes == 0 ) && ( result < Count ) && ( Count > 0 ) ) + InOutRes = 101; +} + + + +void BlockRead64( TTypedFile& f, void* buf, int64_t Count, int64_t& Result ) +/* + Read Count records from file f ro Buf, return number of read records in + Result +*/ +{ + Result = 0; + if ( InOutRes != 0 ) + return; + switch ( ((TFileRec*) &f )->Mode ) + { + case fmInOut: + case fmInput: + Result = do_read( ((TFileRec*) &f )->Handle, buf, (int) Count * ((TFileRec*) &f )->RecSize ) / ((TFileRec*) &f )->RecSize; + break; + case fmOutput: + InOutRes = 104; + break; + default: + InOutRes = 103; + } +} + +void BlockRead( TTypedFile& f, void* buf, int Count, int64_t& Result ) +/* + Read Count records from file f ro Buf, return number of read records in + Result +*/ +{ + BlockRead64( f, buf, Count, Result ); +} + +void BlockRead( TTypedFile& f, void* buf, int Count, int& Result ) +/* + Read Count records from file f ro Buf, return number of read records in + Result +*/ +{ + int64_t l = 0; + BlockRead64( f, buf, Count, l ); + Result = (int)l; +} + +void BlockRead( TTypedFile& f, void* buf, WORD Count, WORD& Result ) +/* + Read Count records from file f to Buf, return number of read records in + Result +*/ +{ + int64_t l = 0; + BlockRead64( f, buf, Count, l ); + Result = (WORD) l; +} + +void BlockRead( TTypedFile& f, void* buf, unsigned int Count, unsigned int& Result ) +/* + Read Count records from file f to Buf, return number of read records in + Result +*/ +{ + int64_t l = 0; + BlockRead64( f, buf, Count, l ); + Result = (unsigned int) l; +} + +void BlockRead( TTypedFile& f, void* buf, WORD Count, int& Result ) +/* + Read Count records from file f to Buf, return number of read records in + Result +*/ +{ + int64_t l = 0; + BlockRead64( f, buf, Count, l ); + Result = (int) l; +} + + +void BlockRead( TTypedFile& f, void* buf, int64_t Count ) +/* + Read Count records from file f to Buf, if none are read and Count>0 then + InOutRes is set +*/ +{ + int64_t result = 0; + BlockRead64( f, buf, Count, result ); + if ( ( InOutRes == 0 ) && ( result < Count ) && ( Count > 0 ) ) + InOutRes = 100; +} + + +SmallString<255> fpc_pchar_to_shortstr( char* P ) +{ + SmallString<255> result; + int l = 0; + SmallString<255> s; + if ( P == NULL ) + l = 0; + else + l = strlen( P ); + if ( l > 255 ) + l = 255; + if ( l > 0 ) + { + strncpy(&s[1], P, l); + s[l] = '\0'; + } + s[0] = char( l ); + result = s; + return result; +} + + +void AssignFile( TTextRec& t, const String& Name ) +{ + FillChar( &t, sizeof( TTextRec ), 0 ); +/* only set things that are not zero */ + t.Handle = UnusedHandle; + t.Mode = fmClosed; + t.BufSize = TextRecBufSize; + t.BufPtr = &t.Buffer[0]; + t.OpenFunc = (void*) FileOpenFuncA; + switch ( DefaultTextLineBreakStyle ) + { + case tlbsLF: + StrCpy(t.LineEnd, ctlbsLF); + break; + case tlbsCRLF: + StrCpy(t.LineEnd, ctlbsCRLF); + break; + case tlbsCR: + StrCpy(t.LineEnd, ctlbsCR); + break; + } + StrCpy( t.Name, Name.c_str()); +} + +void AssignFile( TTextRec& t, Char c ) +{ + String s; + s.append(1, c); + AssignFile( t, s.c_str()); +} + +void Assign( TTextRec& f, const String& Name ) +{ + AssignFile(f, Name); +} + +void Assign( TTextRec& t, Char c ) +{ + AssignFile(t, c); +} + + +void Append( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + OpenText( t, fmAppend, 1 ); +} + +void Flush( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + if ( t.Mode != fmOutput ) + { + if ( t.Mode == fmInput ) + InOutRes = 105; + else + InOutRes = 103; + return; + } +/* Not the FlushFunc but the InOutFunc should be used, becuase that + writes the data, FlushFunc doesn't need to be assigned */ + FileFunc( t.InOutFunc )( t ); +} + + +void Erase( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + if ( t.Mode == fmClosed ) + do_erase( t.Name ); +} + +bool SeekEof( TTextRec& t ) +{ + bool result = false; + int64_t oldfilepos = 0; + int oldbufpos = 0, oldbufend = 0; + int reads = 0; + bool isdevice = false; + result = true; + if ( InOutRes != 0 ) + return result; //(true); + if ( t.Mode != fmInput ) + { + if ( t.Mode == fmOutput ) + InOutRes = 104; + else + InOutRes = 103; + return result; //(true); + } + /* try to save the current position in the file, seekeof() should not move */ + /* the current file position (JM) */ + oldbufpos = t.BufPos; + oldbufend = t.BufEnd; + reads = 0; + oldfilepos = - 1; + isdevice = do_isdevice( t.Handle ); + do + { + if ( t.BufPos >= t.BufEnd ) + { + /* signal that the we will have to do a seek */ + reads++; + if ( ! isdevice && ( reads == 1 ) ) + { + oldfilepos = do_filepos( t.Handle ) - t.BufEnd; + InOutRes = 0; + } + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + { + /* if we only did a read in which we didn't read anything, the */ + /* old buffer is still valid and we can simply restore the */ + /* pointers (JM) */ + reads--; + result = true; + break; + } + } + switch ( t.BufPtr[t.BufPos] ) + { + case '\x1a': + if ( CtrlZMarksEOF ) + { + result = true; + break; + } + break; + case '\x0a': case '\x0d': case '\x09': case ' ': + break; + default: + { + result = false; + break; + } + } + t.BufPos++; + } + while ( ! ( false ) ); + /* restore file position if not working with a device */ + if ( ! isdevice ) + { + /* if we didn't modify the buffer, simply restore the BufPos and BufEnd */ + /* (the latter becuase it's now probably set to zero because nothing was */ + /* was read anymore) */ + if ( reads == 0 ) + { + t.BufPos = oldbufpos; + t.BufEnd = oldbufend; + } + /* otherwise return to the old filepos and reset the buffer */ + else + { + do_seek( t.Handle, oldfilepos ); + InOutRes = 0; + FileFunc( t.InOutFunc )( t ); + t.BufPos = oldbufpos; + } + } + return result; +} + + +bool SeekEof( ) +{ + bool result = false; + result = SeekEof( Input ); + return result; +} + + +bool EoLn( TTextRec& t ) +{ + bool result = false; + result = true; + if ( InOutRes != 0 ) + return result; //(true); + if ( t.Mode != fmInput ) + { + if ( t.Mode == fmOutput ) + InOutRes = 104; + else + InOutRes = 103; + return result; //(true); + } + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + return result; //(true); + } + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + return result; // (true); + result = ( t.BufPtr[t.BufPos] == '\n' || t.BufPtr[t.BufPos] == '\r' ); + return result; +} + + +bool EoLn( ) +{ + bool result = false; + result = EoLn( Input ); + return result; +} + + +bool SeekEoLn( TTextRec& t ) +{ + bool result = false; + result = true; + if ( InOutRes != 0 ) + return result; //(true); + if ( t.Mode != fmInput ) + { + if ( t.Mode == fmOutput ) + InOutRes = 104; + else + InOutRes = 103; + return result; //(true); + } + do + { + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + return result; //(true); + } + switch ( t.BufPtr[t.BufPos] ) + { + case '\x1a': + if ( CtrlZMarksEOF ) + return result; + break;// (true); + + case '\x0a': case '\x0d': + return result; + //break; //(true); + + case '\x09': case ' ': + break; + default: + result = false; + return result; //(false); + } + t.BufPos++; + } + while ( ! ( false ) ); + //return result; +} + + +bool SeekEoLn( ) +{ + bool result = false; + result = SeekEoLn( Input ); + return result; +} + + +void SetTextBuf( TTextRec& t, void* buf, int size ) + +{ + t.BufPtr = (char*) buf; + t.BufSize = size; + t.BufPos = 0; + t.BufEnd = 0; +} + + +void SetTextLineEnding( TTextRec& t, AnsiString Ending ) +{ + strcpy(t.LineEnd, Ending.c_str()); +} + + +TTextRec* fpc_get_input( ) +{ + return &Input; +} + + +TTextRec* fpc_get_output( ) +{ + return &Output; +} + + +/****************************************************************************** + Write(Ln) +******************************************************************************/ + +void fpc_WriteBuffer( TTextRec& t, const void* b, int Len ) + +{ + char* P = NULL; + int Left = 0, idx = 0; + P = (char*) b; + idx = 0; + Left = t.BufSize - t.BufPos; + while ( Len > Left ) + { + memcpy( &t.BufPtr[t.BufPos], &P[idx], Left ); + Len -= Left; + idx += Left; + t.BufPos += Left; + FileFunc( t.InOutFunc )( t ); + Left = t.BufSize - t.BufPos; + } + memcpy( &t.BufPtr[t.BufPos], &P[idx], Len ); + t.BufPos += Len; +} + + +void fpc_WriteBlanksA( TTextRec& t, int Len ) +{ + int Left = 0; + Left = t.BufSize - t.BufPos; + while ( Len > Left ) + { + FillChar( &t.BufPtr[t.BufPos], Left, ' ' ); + Len -= Left; + t.BufPos += Left; + FileFunc( t.InOutFunc )( t ); + Left = t.BufSize - t.BufPos; + } + FillChar( &t.BufPtr[t.BufPos], Len, ' ' ); + t.BufPos += Len; +} + +void fpc_Write_End( TTextRec& t ) +{ + if ( t.FlushFunc != NULL ) + FileFunc( t.FlushFunc )( t ); +} + +void fpc_Writeln_End( TTextRec& t ) +{ + if ( InOutRes != 0 ) + return; + switch ( t.Mode ) + { + case fmOutput: /* fmAppend gets changed to fmOutPut in do_open (JM) */ + { + /* Write EOL */ + fpc_WriteBuffer( t, t.LineEnd, StrLen(t.LineEnd) ); + /* Flush */ + if ( t.FlushFunc != NULL ) + FileFunc( t.FlushFunc )( t ); + } + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + + +void fpc_Write_Text_ShortStr( unsigned int Len, TTextRec& t, const AnsiString& s ) +{ + if ( InOutRes != 0 ) + return; + switch ( t.Mode ) + { + case fmOutput /* fmAppend gets changed to fmOutPut in do_open (JM) */ : // 55218: + { + if ( Len > s.length( ) ) + fpc_WriteBlanksA( t, Len - s.length( ) ); + fpc_WriteBuffer( t, (char*) s.c_str(), s.length( ) ); + } + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + + +void fpc_Write_Text_Pchar_as_Array( int Len, TTextRec& t, const char* s, int s_maxidx, bool zerobased = true ) +{ + int ArrayLen = 0; + const char* P = NULL; + if ( InOutRes != 0 ) + return; + switch ( t.Mode ) + { + case fmOutput: /* fmAppend gets changed to fmOutPut in do_open (JM) */ + { + P = s; + if ( zerobased ) + { + /* can't use strlen, since that one could try to read past the end */ + /* of the heap (JM), but strnlen is safe. */ + ArrayLen = strnlen(P, s_maxidx /*# High(s) */ + 1); + } + else + ArrayLen = s_maxidx /*# High(s) */ + 1; + if ( Len > ArrayLen ) + fpc_WriteBlanksA( t, Len - ArrayLen ); + fpc_WriteBuffer( t, P, ArrayLen ); + } + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + + +void fpc_Write_Text_PChar_As_Pointer( int Len, TTextRec& t, const char* P ) +{ + int PCharLen = 0; + if ( ( P == NULL ) || ( InOutRes != 0 ) ) + return; + switch ( t.Mode ) + { + case fmOutput: /* fmAppend gets changed to fmOutPut in do_open (JM) */ // 55218: + { + PCharLen = strlen( P ); + if ( Len > PCharLen ) + fpc_WriteBlanksA( t, Len - PCharLen ); + fpc_WriteBuffer( t, P, PCharLen ); + } + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + +void fpc_Write_Text_AnsiStr( int Len, TTextRec& t, const AnsiString& s ) +/* + Writes a AnsiString to the TTextRec file T +*/ +{ + int SLen = 0; + if ( InOutRes != 0 ) + return; + switch ( t.Mode ) + { + case fmOutput :/* fmAppend gets changed to fmOutPut in do_open (JM) */ // 55218: + { + SLen = s.length( ); + if ( Len > SLen ) + fpc_WriteBlanksA( t, Len - SLen ); + if ( SLen > 0 ) + fpc_WriteBuffer( t, s.c_str(), SLen ); + } + break; + case /*# fmInput */ 55217: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} + + +void Write_Str( int Len, TTextRec& t, const AnsiString& s ) //IOCheck; [external Name 'FPC_WRITE_TEXT_SHORTSTR']; + +{ + fpc_Write_Text_ShortStr( Len, t, s ); +} + + +void fpc_Write_Text_SInt( int Len, TTextRec& t, int l ) +{ + AnsiString s; + if ( InOutRes != 0 ) + return; + Str( l, s ); + Write_Str( Len, t, s ); +} + + +void fpc_Write_Text_UInt( int Len, TTextRec& t, unsigned int l ) + +{ + AnsiString s; + if ( InOutRes != 0 ) + return; + Str( l, s ); + Write_Str( Len, t, s ); +} + + +void fpc_write_text_qword( int Len, TTextRec& t, uint64_t q ) + +{ + AnsiString s; + if ( InOutRes != 0 ) + return; + Str( q, s ); + Write_Str( Len, t, s ); +} + + +void fpc_write_text_int64( int Len, TTextRec& t, int64_t i ) +{ + AnsiString s; + if ( InOutRes != 0 ) + return; + Str( i, s ); + Write_Str( Len, t, s ); +} + + +void fpc_Write_Text_Float( int rt, int fixkomma, int Len, TTextRec& t, long double r ) + +{ + AnsiString s; + if ( InOutRes != 0 ) + return; +// Str_real(Len,fixkomma,r,treal_type(rt),s); +// Str_real(Len,fixkomma,r,rt_c64bit,s); + + if(rt != -1) + { + if(fixkomma != -1) + Str(r, rt, fixkomma, s); + else + Str(r, rt, s); + } + else + Str(r, s); + + Write_Str( Len, t, s ); +} + +void fpc_Write_Text_Currency( int fixkomma, int Len, TTextRec& t, Currency c ) +{ + AnsiString s; + if ( InOutRes != 0 ) + return; + Str( c, Len, fixkomma, s ); + Write_Str( Len, t, s ); +} + + +void fpc_Write_Text_Boolean( int Len, TTextRec& t, bool b ) +{ + if ( InOutRes != 0 ) + return; +/* Can't use array[boolean] because b can be >0 ! */ + if ( b ) + Write_Str( Len, t, "TRUE" ); + else + Write_Str( Len, t, "FALSE" ); +} + + +void fpc_Write_Text_Char( int Len, TTextRec& t, char c ) +{ + if ( InOutRes != 0 ) + return; + if ( t.Mode != fmOutput ) + { + if ( t.Mode == fmClosed ) + InOutRes = 103; + else + InOutRes = 105; + return; + } + if ( Len > 1 ) + fpc_WriteBlanksA( t, Len - 1 ); + if ( t.BufPos >= t.BufSize ) + FileFunc( t.InOutFunc )( t ); + t.BufPtr[t.BufPos] = c; + t.BufPos++; +} + + + +/****************************************************************************** + Read(Ln) +******************************************************************************/ + + +bool NextChar( TTextRec& t, AnsiString& s ) +{ + bool result = false; + result = false; + if ( t.BufPos < t.BufEnd ) + if ( ! ( CtrlZMarksEOF ) || ( t.BufPtr[t.BufPos] != '\x1a' ) ) + { + /* + if length(s)BufPtr[((TTextRec*) &f )->BufPos]; + s += t.BufPtr[t.BufPos]; + t.BufPos++; + if ( t.BufPos >= t.BufEnd ) + FileFunc( t.InOutFunc )( t ); + result = true; + } + return result; +} + + +bool IgnoreSpaces( TTextRec& t ) +/* + Removes all leading spaces,tab,eols from the input buffer, returns true if + the buffer is empty +*/ +{ + bool result = false; + AnsiString s; + s = ""; + result = false; + /* Return false when already at EOF */ + if ( t.BufPos >= t.BufEnd ) + return result; +/* Check performed separately to avoid accessing memory outside buffer */ + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + return result; + while ( t.BufPtr[t.BufPos] <= ' ' ) + { + if ( ! NextChar( t, s ) ) + return result; + /* EOF? */ + if ( t.BufPos >= t.BufEnd ) + break; + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + break; + } + result = true; + return result; +} + + + +void ReadNumeric( TTextRec& t, AnsiString& s ) +/* + Read numeric input, if buffer is empty then return True +*/ +{ + do + { + if ( ! NextChar( t, s ) ) + return; +// until (length(s)=high(s)) or (TTextRec(f).BufPtr^[TTextRec(f).BufPos] <= ' '); + } + while ( ! ( t.BufPtr[t.BufPos] <= ' ' ) ); +} + + +bool CheckRead( TTextRec& t ) +{ + bool result = false; + result = false; +/* Check error and if file is open and load buf if empty */ + if ( InOutRes != 0 ) + return result; + if ( t.Mode != fmInput ) + { + switch ( t.Mode ) + { + case fmOutput: case fmAppend: + InOutRes = 104; + break; + default: + InOutRes = 103; + } + return result; + } + if ( t.BufPos >= t.BufEnd ) + FileFunc( t.InOutFunc )( t ); + result = true; + return result; +} + + + +void fpc_Read_End( TTextRec& t ) +{ + if ( t.FlushFunc != NULL ) + FileFunc( t.FlushFunc )( t ); +} + + +void fpc_ReadLn_End( TTextRec& t ) +{ + char prev = '\0'; + if ( ! CheckRead( t ) ) + return; + if ( t.BufPos >= t.BufEnd ) + /* Flush if set */ + { + if ( t.FlushFunc != NULL ) + FileFunc( t.FlushFunc )( t ); + return; + } + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + return; + do + { + prev = t.BufPtr[t.BufPos]; + t.BufPos++; +/* no system uses #10#13 as line seperator (#10 = *nix, #13 = Mac, */ +/* #13#10 = Dos), so if we've got #10, we can safely exit */ + if ( prev == '\x0a' ) + return; + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + /* Flush if set */ + { + if ( t.FlushFunc != NULL ) + FileFunc( t.FlushFunc )( t ); + return; + } + } + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + return; + if ( prev == '\x0d' ) + /* is there also a #10 after it? */ + { + if ( t.BufPtr[t.BufPos] == '\x0a' ) + /* yes, skip that one as well */ + t.BufPos++; + return; + } + } + while ( ! ( false ) ); +} + + +int ReadPCharLenA( TTextRec& t, char* s, unsigned int maxlen ) +{ + int result = 0; + unsigned int sPos = 0, Len = 0; + char* P = NULL,* startp = NULL,* maxp = NULL; + bool end_of_string = false; + result = 0; + if ( ! CheckRead( t ) ) + return result; +/* Read maximal until Maxlen is reached */ + sPos = 0; + end_of_string = false; + do + { + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + break; + } + P = &t.BufPtr[t.BufPos]; + if ( sPos + t.BufEnd - t.BufPos > maxlen ) + maxp = &t.BufPtr[t.BufPos + maxlen - sPos]; + else + maxp = &t.BufPtr[t.BufEnd]; + startp = P; + char* startp2 = &s[sPos];; + /* find stop character */ + while ( P < maxp ) + { + /* Optimization: Do a quick check for a control character first */ + if ( *P < ' ' ) + { + if ( *P == '\n' || *P == '\r' || ( CtrlZMarksEOF && ( *P == '\x1a' ) ) ) + { + *startp2 = *P; // dme + end_of_string = true; + break; + } + } + *startp2++ = *P; // dme + P++; + } + /* calculate read bytes */ + Len = P - startp; + t.BufPos += Len; + //memcpy( &s[sPos], startp, Len ); + sPos += Len; + } + while ( ! ( ( sPos == maxlen ) || end_of_string ) ); + result = sPos; + return result; +} + + +int ReadPCharLen( TTextRec& t, wchar_t* s, unsigned int maxlen ) +{ + int result = 0; + unsigned int sPos = 0, Len = 0; + char* P = NULL,* startp = NULL,* maxp = NULL; + bool end_of_string = false; + result = 0; + if ( ! CheckRead( t ) ) + return result; +/* Read maximal until Maxlen is reached */ + sPos = 0; + end_of_string = false; + do + { + if ( t.BufPos >= t.BufEnd ) + { + FileFunc( t.InOutFunc )( t ); + if ( t.BufPos >= t.BufEnd ) + break; + } + P = &t.BufPtr[t.BufPos]; + if ( sPos + t.BufEnd - t.BufPos > maxlen ) + maxp = &t.BufPtr[t.BufPos + maxlen - sPos]; + else + maxp = &t.BufPtr[t.BufEnd]; + startp = P; + wchar_t* startp2 = &s[sPos]; + /* find stop character */ + while ( P < maxp ) + { + /* Optimization: Do a quick check for a control character first */ + if ( *P < ' ' ) + { + if ( *P == '\n' || *P == '\r' || ( CtrlZMarksEOF && ( *P == '\x1a' ) ) ) + { + *startp2 = *P; // dme + end_of_string = true; + break; + } + } + *startp2++ = *P; // dme + P++; + } + /* calculate read bytes */ + Len = P - startp; + t.BufPos += Len; + //MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, startp, Len, &s[sPos], maxlen ); + sPos += Len; + } + while ( ! ( ( sPos == maxlen ) || end_of_string ) ); + result = sPos; + return result; +} + + + +void fpc_Read_Text_ShortStr( TTextRec& t, SmallString<255>& s ) +{ + s[0] = char( ReadPCharLenA( t, &s[1], 255 /*# High(s) */ ) ); +} + + +void fpc_Read_Text_PChar_As_Pointer( TTextRec& t, char* s, int maxlen ) +{ + *( s + ReadPCharLenA( t, s, maxlen ) ) = '\x00'; +} + +void fpc_Read_Text_PChar_As_Pointer( TTextRec& t, wchar_t* s, int maxlen ) +{ + *( s + ReadPCharLen( t, s, maxlen ) ) = '\x00'; +} + + +void fpc_Read_Text_PChar_As_Array( TTextRec& t, char* s, int s_maxidx, bool zerobased = false ) +{ + int Len = 0; + Len = ReadPCharLenA( t, (char*) ( &s[0] ), s_maxidx /*# High(s) */ + 1 ); + if ( zerobased && ( Len > s_maxidx /*# High(s) */ ) ) + Len = s_maxidx /*# High(s) */; + if ( Len <= s_maxidx /*# High(s) */ ) + s[Len] = '\x00'; +} + +void fpc_Read_Text_PChar_As_Array( TTextRec& t, wchar_t* s, int s_maxidx, bool zerobased = false ) +{ + int Len = 0; + Len = ReadPCharLen( t, s, s_maxidx /*# High(s) */ + 1 ); + if ( zerobased && ( Len > s_maxidx /*# High(s) */ ) ) + Len = s_maxidx /*# High(s) */; + if ( Len <= s_maxidx /*# High(s) */ ) + s[Len] = '\x00'; +} + + +void fpc_Read_Text_AnsiStr( TTextRec& t, AnsiString& s ) +{ + int SLen = 0, Len = 0; + SLen = 0; + do + { + // resize will reallocate the length. +// len:=ReadPCharLen(f,pchar(Pointer(S)+slen),255); + s.resize(SLen + 255); + Len = ReadPCharLenA( t, (char*) &s[SLen], 255 ); + SLen += Len; + } + while ( ! ( Len < 255 ) ); + // Set actual length + + s.resize( SLen ); +} + + +void fpc_Read_Text_Char( TTextRec& t, char& c ) +{ + c = '\x00'; + if ( ! CheckRead( t ) ) + return; + if ( t.BufPos >= t.BufEnd ) + { + c = '\x1a'; + return; + } + c = t.BufPtr[t.BufPos]; + t.BufPos++; +} + + +void fpc_Read_Text_SInt( TTextRec& t, int& l ) //ValSInt); + +{ + AnsiString hs; + int code = 0; + l = 0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + if ( CtrlZMarksEOF && ( t.BufPtr[t.BufPos] == '\x1a' ) ) + return; + ReadNumeric( t, hs ); + } + if ( hs.empty()) + l = 0; + else + { + Val( hs, &l, code ); + if ( code != 0 ) + InOutRes = 106; + } +} + + + +void fpc_Read_Text_UInt( TTextRec& t, unsigned int& u ) + +{ + AnsiString hs; + int code = 0; + u = 0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + ReadNumeric( t, hs ); + } + if ( hs.empty()) + u = 0; + else + { + Val( hs, &u, code ); + if ( code != 0 ) + InOutRes = 106; + } +} + + +void fpc_Read_Text_UInt( TTextRec& t, unsigned short& u ) + +{ + AnsiString hs; + int code = 0; + u = 0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + ReadNumeric( t, hs ); + } + if ( hs.empty()) + u = 0; + else + { + Val( hs, &u, code ); + if ( code != 0 ) + InOutRes = 106; + } +} + + + +void fpc_Read_Text_Float( TTextRec& t, long double& v ) //ValReal); +{ + AnsiString hs; + int code = 0; + v = 0.0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + ReadNumeric( t, hs ); + } + Val( hs, &v, code ); + if ( code != 0 ) + InOutRes = 106; +} + +void fpc_Read_Text_Currency( TTextRec& f, Currency& v ) +{ + AnsiString hs; + int code = 0; + v = 0.0; + double d = 0.0; + if ( ! CheckRead( f ) ) + return; + hs = ""; + if ( IgnoreSpaces( f ) ) + { + // When spaces were found and we are now at EOF, then we return 0 + if ( ((TTextRec*) &f )->BufPos >= ((TTextRec*) &f )->BufEnd ) + return; + ReadNumeric( f, hs ); + } + Val( hs, &d, code ); + v = d; + if ( code != 0 ) + InOutRes = 106; +} + +void fpc_Read_Text_QWord( TTextRec& t, uint64_t& q ) +{ + AnsiString hs; + int code = 0; + q = 0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + ReadNumeric( t, hs ); + } + Val( hs, &q, code ); + if ( code != 0 ) + InOutRes = 106; +} + + +void fpc_Read_Text_Int64( TTextRec& t, int64_t& i ) +{ + AnsiString hs; + int code = 0; + i = 0; + if ( ! CheckRead( t ) ) + return; + hs = ""; + if ( IgnoreSpaces( t ) ) + { + /* When spaces were found and we are now at EOF, + then we return 0 */ + if ( t.BufPos >= t.BufEnd ) + return; + ReadNumeric( t, hs ); + } + Val( hs, &i, code ); + if ( code != 0 ) + InOutRes = 106; +} + + +/***************************************************************************** + subroutines for typed file handling +*****************************************************************************/ + + +void AssignFile( TFileRec& f, const String& Name ) +{ + FillChar( &f, sizeof( TFileRec ), 0 ); + f.Handle = UnusedHandle; + f.Mode = fmClosed; + StrCpy(f.Name, Name.c_str()); +} + +void AssignFile( TFileRec& f, Char c ) +{ + Char buf[2]; + buf[0] = c; + buf[1] = _T('\0'); + AssignFile( f, buf); +} + +void Assign( TFileRec& f, const String& Name ) +{ + AssignFile(f, Name); +} + +void Assign( TFileRec& f, Char c ) +{ + AssignFile(f, c); +} + +//--------------------------------------------------------------------------- +void fpc_typed_write( int typesize, TFileRec& f, void* buf ) +{ + if ( InOutRes != 0 ) + return; + switch ( f.Mode ) + { + case fmOutput: case fmInOut: + do_write( f.Handle, buf, typesize ); + break; + case fmInput: + InOutRes = 105; + break; + default: + InOutRes = 103; + } +} +//--------------------------------------------------------------------------- +void fpc_typed_read( int typesize, TFileRec& f, void* buf ) +{ + int result = 0; + if ( InOutRes != 0 ) + return; + switch ( f.Mode ) + { + case fmInput: case fmInOut: + { + result = do_read( f.Handle, buf, typesize ); + if ( result < typesize ) + InOutRes = 100; + } + break; + case fmOutput: + InOutRes = 104; + break; + default: + InOutRes = 103; + } +} + +/***************************************************************************** + interface functions +*****************************************************************************/ + + +void Write( TTextRec& t, const SmallString<255> s, int Len ) +{ + fpc_Write_Text_ShortStr( Len, t, s ); +} + + +void Write( TTextRec& t, const char* s, int s_maxidx, int Len, bool zerobased ) +{ + fpc_Write_Text_Pchar_as_Array( Len, t, s, s_maxidx, zerobased ); +} + + +void Write( TTextRec& t, const char* P, int Len ) +{ + fpc_Write_Text_PChar_As_Pointer( Len, t, P ); +} + + +void Write( TTextRec& t, const AnsiString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, t, s ); +} + +void Write( TTextRec& t, const wchar_t* P, int Len ) +{ + AnsiString s = wstr2str(P); + fpc_Write_Text_PChar_As_Pointer( Len, t, s.c_str() ); +} + + +void Write( TTextRec& t, const WideString& xs, int Len ) +{ + AnsiString s; + s = wstr2str(xs); + fpc_Write_Text_AnsiStr( Len, t, s ); +} + +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void Write( TTextRec& t, long l, int Len ) +{ + fpc_Write_Text_SInt( Len, t, l ); +} +#endif + +void Write( TTextRec& t, int l, int Len ) +{ + fpc_Write_Text_SInt( Len, t, l ); +} + +void Write( TTextRec& t, unsigned int l, int Len ) +{ + fpc_Write_Text_UInt( Len, t, l ); +} + +void Write( TTextRec& t, unsigned short l, int Len ) +{ + fpc_Write_Text_UInt( Len, t, (int) l ); +} + + +void Write( TTextRec& t, uint64_t q, int Len ) +{ + fpc_write_text_qword( Len, t, q ); +} + +void Write( TTextRec& t, int64_t i, int Len ) +{ + fpc_write_text_int64( Len, t, i ); +} + +void Write( TTextRec& t, long double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, t, r ); +} + +void Write( TTextRec& t, double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, t, r ); +} + +void Write( TTextRec& t, Currency c, int fixkomma, int Len ) +{ + fpc_Write_Text_Currency( fixkomma, Len, t, c ); +} + +void Write( TTextRec& t, bool b, int Len ) +{ + fpc_Write_Text_Boolean( Len, t, b ); +} + +void Write( TTextRec& t, char c, int Len ) +{ + fpc_Write_Text_Char( Len, t, c ); +} + +void Write( TTextRec& t, unsigned char c, int Len ) +{ + fpc_Write_Text_Char( Len, t, c ); +} + +void Write( TTextRec& t, wchar_t c, int Len ) +{ + fpc_Write_Text_Char( Len, t, wchar2char( c )); +} + + +void WriteLn( TTextRec& t ) +{ + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, const SmallString<255> s, int Len ) +{ + fpc_Write_Text_ShortStr( Len, t, s ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, const char* P, int Len ) +{ + fpc_Write_Text_PChar_As_Pointer( Len, t, P ); + fpc_Writeln_End( t ); +} + + +void WriteLn( TTextRec& t, const AnsiString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, t, s ); + fpc_Writeln_End( t ); +} + + +void WriteLn( TTextRec& t, const wchar_t* P, int Len ) +{ + //fpc_Write_Text_WideStr( Len, t, P ); + Write(t, P, Len); + fpc_Writeln_End( t ); +} + + +void WriteLn( TTextRec& t, const WideString& s, int Len ) +{ + Write(t, s, Len); + fpc_Writeln_End( t ); +} + +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void WriteLn( TTextRec& t, long l, int Len ) +{ + fpc_Write_Text_SInt( Len, t, l ); + fpc_Writeln_End( t ); +} +#endif + + +void WriteLn( TTextRec& t, int l, int Len ) +{ + fpc_Write_Text_SInt( Len, t, l ); + fpc_Writeln_End( t ); +} + + +void WriteLn( TTextRec& t, unsigned int l, int Len ) +{ + fpc_Write_Text_UInt( Len, t, l ); + fpc_Writeln_End( t ); +} + + +void WriteLn( TTextRec& t, unsigned short l, int Len ) +{ + fpc_Write_Text_UInt( Len, t, (int) l ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, uint64_t q, int Len ) +{ + fpc_write_text_qword( Len, t, q ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, int64_t i, int Len ) +{ + fpc_write_text_int64( Len, t, i ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, long double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, t, r ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, t, r ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, Currency c, int fixkomma, int Len ) +{ + fpc_Write_Text_Currency( fixkomma, Len, t, c ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, bool b, int Len ) +{ + fpc_Write_Text_Boolean( Len, t, b ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, char c, int Len ) +{ + fpc_Write_Text_Char( Len, t, c ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, unsigned char c, int Len ) +{ + fpc_Write_Text_Char( Len, t, c ); + fpc_Writeln_End( t ); +} + +void WriteLn( TTextRec& t, wchar_t c, int Len ) +{ + fpc_Write_Text_Char( Len, t, wchar2char(c) ); + fpc_Writeln_End( t ); +} + +void Write( const SmallString<255> s, int Len ) +{ + fpc_Write_Text_ShortStr( Len, Output, s ); +} + +void Write( const char* P, int Len ) +{ + fpc_Write_Text_PChar_As_Pointer( Len, Output, P ); +} + + +void Write( const AnsiString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, Output, s ); +} + +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void Write( long l, int Len ) +{ + fpc_Write_Text_SInt( Len, Output, l ); +} +#endif + +void Write( int l, int Len ) +{ + fpc_Write_Text_SInt( Len, Output, l ); +} + + +void Write( unsigned int l, int Len ) + +{ + fpc_Write_Text_UInt( Len, Output, l ); +} + + +void Write( uint64_t q, int Len ) + +{ + fpc_write_text_qword( Len, Output, q ); +} + + +void Write( int64_t i, int Len ) +{ + fpc_write_text_int64( Len, Output, i ); +} + + +void Write( double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, Output, r ); //ValReal); +} + +void Write( Currency c, int fixkomma, int Len ) +{ + fpc_Write_Text_Currency( fixkomma, Len, Output, c ); +} + +void Write( bool b, int Len ) +{ + fpc_Write_Text_Boolean( Len, Output, b ); +} + + +void Write( char c, int Len ) +{ + fpc_Write_Text_Char( Len, Output, c ); +} + +void WriteLn( ) +{ + fpc_Writeln_End( Output ); +} + +void WriteLn( const SmallString<255> s, int Len ) +{ + fpc_Write_Text_ShortStr( Len, Output, s ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( const char* P, int Len ) +{ + fpc_Write_Text_PChar_As_Pointer( Len, Output, P ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( const AnsiString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, Output, s ); + fpc_Writeln_End( Output ); +} + + +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void WriteLn( long l, int Len ) +{ + fpc_Write_Text_SInt( Len, Output, l ); + fpc_Writeln_End( Output ); +} +#endif + +void WriteLn( int l, int Len ) +{ + fpc_Write_Text_SInt( Len, Output, l ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( unsigned int l, int Len ) +{ + fpc_Write_Text_UInt( Len, Output, l ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( uint64_t q, int Len ) +{ + fpc_write_text_qword( Len, Output, q ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( int64_t i, int Len ) +{ + fpc_write_text_int64( Len, Output, i ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( long double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, Output, r ); + fpc_Writeln_End( Output ); +} + +void WriteLn( double r, int rt, int fixkomma ) +{ + fpc_Write_Text_Float( rt, fixkomma, 0, Output, r ); + fpc_Writeln_End( Output ); +} + +void WriteLn( Currency c, int fixkomma, int Len ) +{ + fpc_Write_Text_Currency( fixkomma, Len, Output, c ); + fpc_Writeln_End( Output ); +} + +void WriteLn( bool b, int Len ) +{ + fpc_Write_Text_Boolean( Len, Output, b ); + fpc_Writeln_End( Output ); +} + + +void WriteLn( char c, int Len ) +{ + fpc_Write_Text_Char( Len, Output, c ); + fpc_Writeln_End( Output ); +} + +// Redirecting wide strings into the console + +void Write( wchar_t c, int Len ) +{ + fpc_Write_Text_Char( Len, Output, wchar2char(c) ); +} + +void WriteLn( wchar_t c, int Len ) +{ + fpc_Write_Text_Char( Len, Output, wchar2char(c) ); + fpc_Writeln_End( Output ); +} + +void Write( const wchar_t* P, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, Output, wstr2str(P) ); +} + +void Write( const WideString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, Output, wstr2str(s) ); +} + +void WriteLn( const wchar_t* P, int Len ) +{ + if(P != NULL) + fpc_Write_Text_AnsiStr( Len, Output, wstr2str(P) ); + fpc_Writeln_End( Output ); +} + +void WriteLn( const WideString& s, int Len ) +{ + fpc_Write_Text_AnsiStr( Len, Output, wstr2str(s) ); + fpc_Writeln_End( Output ); +} + +///////////// Read + + +void Read( TTextRec& t, SmallString<255>& s ) +{ + fpc_Read_Text_ShortStr( t, s ); +} + + +void Read( TTextRec& t, char* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( t, s, maxlen ); +} + +void Read( TTextRec& t, char*& s, bool zerobased) +{ + fpc_Read_Text_PChar_As_Array(t, s, zerobased); +} + +void Read( TTextRec& t, wchar_t*& s, bool zerobased) +{ + fpc_Read_Text_PChar_As_Array(t, s, zerobased); +} + +void Read( TTextRec& t, wchar_t* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( t, s, maxlen ); +} + +void Read( TTextRec& t, AnsiString& s ) +{ + fpc_Read_Text_AnsiStr( t, s ); +} + +void Read( TTextRec& t, WideString& xs ) +{ + AnsiString s; + fpc_Read_Text_AnsiStr( t, s ); + xs = str2wstr(s); +} + +void Read( TTextRec& t, char& c ) +{ + fpc_Read_Text_Char( t, c ); +} + +void Read( TTextRec& t, wchar_t& xc ) +{ + char c; + fpc_Read_Text_Char( t, c ); + xc = c; +} + +void Read( TTextRec& t, int& l ) +{ + fpc_Read_Text_SInt( t, l ); +} + + +void Read( TTextRec& t, unsigned int& u ) +{ + fpc_Read_Text_UInt( t, u ); +} + +void Read( TTextRec& t, unsigned short& u ) +{ + fpc_Read_Text_UInt( t, u ); +} + +void Read( TTextRec& t, long double& v ) +{ + fpc_Read_Text_Float( t, v ); +} + +void Read( TTextRec& t, double& xv ) +{ + long double v; + fpc_Read_Text_Float( t, v ); + xv = (double) v; +} + +void Read( TTextRec& f, Currency& v ) +{ + fpc_Read_Text_Currency( f, v ); +} + +void Read( TTextRec& t, int64_t& i ) +{ + fpc_Read_Text_Int64( t, i ); +} + +void Read( TTextRec& t, uint64_t& q ) +{ + fpc_Read_Text_QWord( t, q ); +} + +void ReadLn( TTextRec& t ) +{ + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, SmallString<255>& s ) +{ + fpc_Read_Text_ShortStr( t, s ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, char* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( t, s, maxlen ); + fpc_ReadLn_End( t ); +} + + +void ReadLn( TTextRec& t, char*& s, bool zerobased ) +{ + fpc_Read_Text_PChar_As_Array(t, s, zerobased); + fpc_ReadLn_End( t ); +} + + +void ReadLn( TTextRec& t, AnsiString& s ) +{ + fpc_Read_Text_AnsiStr( t, s ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, WideString& xs ) +{ + AnsiString s; + fpc_Read_Text_AnsiStr( t, s ); + xs = str2wstr(s); + fpc_ReadLn_End( t ); +} + + +void ReadLn( TTextRec& t, char& c ) +{ + fpc_Read_Text_Char( t, c ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, wchar_t& xc ) +{ + char c; // todo MultiByteToWideChar + fpc_Read_Text_Char( t, c ); + xc = c; + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, int& l ) +{ + fpc_Read_Text_SInt( t, l ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, unsigned int& u ) +{ + fpc_Read_Text_UInt( t, u ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, unsigned short& u ) +{ + fpc_Read_Text_UInt( t, u ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, long double& v ) +{ + fpc_Read_Text_Float( t, v ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, double& v ) +{ + Read( t, v ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& f, Currency& v ) +{ + fpc_Read_Text_Currency( f, v ); + fpc_ReadLn_End( f ); +} + +void ReadLn( TTextRec& t, int64_t& i ) +{ + fpc_Read_Text_Int64( t, i ); + fpc_ReadLn_End( t ); +} + +void ReadLn( TTextRec& t, uint64_t& q ) +{ + fpc_Read_Text_QWord( t, q ); + fpc_ReadLn_End( t ); +} + +void Read( SmallString<255>& s ) +{ + fpc_Read_Text_ShortStr( Input, s ); +} + + +void Read( char* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( Input, s, maxlen ); +} + +void Read( wchar_t* xp, int maxlen ) +{ + char* p = (char*) xp; + fpc_Read_Text_PChar_As_Pointer( Input, p, 2 * maxlen ); +} + + +void Read( AnsiString& s ) +{ + fpc_Read_Text_AnsiStr( Input, s ); +} + +void Read( WideString& xs ) +{ + AnsiString s; + fpc_Read_Text_AnsiStr( Input, s ); + xs = WideString(s.begin(), s.end()); +} + +void Read( char& c ) +{ + fpc_Read_Text_Char( Input, c ); +} + +void Read( wchar_t& xc ) +{ + char c; + fpc_Read_Text_Char( Input, c ); + xc = c; +} + + +void Read( int& l ) + +{ + fpc_Read_Text_SInt( Input, l ); +} + + +void Read( unsigned int& u ) + +{ + fpc_Read_Text_UInt( Input, u ); +} + +void Read( unsigned short& u ) + +{ + fpc_Read_Text_UInt( Input, u ); +} + +void Read( double& v ) + +{ + Read( Input, v ); +} + +void Read( Currency& v ) +{ + fpc_Read_Text_Currency( Input, v ); +} + +void Read( int64_t& i ) +{ + fpc_Read_Text_Int64( Input, i ); +} + + +void Read( uint64_t& q ) +{ + fpc_Read_Text_QWord( Input, q ); +} + + +void ReadLn( ) +{ + fpc_ReadLn_End( Input ); +} + +void ReadLn( SmallString<255>& s ) +{ + fpc_Read_Text_ShortStr( Input, s ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( char* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( Input, s, maxlen ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( wchar_t* s, int maxlen ) +{ + fpc_Read_Text_PChar_As_Pointer( Input, (char*) s, 2 * maxlen ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( AnsiString& s ) +{ + fpc_Read_Text_AnsiStr( Input, s ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( WideString& xs ) +{ + AnsiString s; + fpc_Read_Text_AnsiStr( Input, s ); + xs = WideString(s.begin(), s.end()); + fpc_ReadLn_End( Input ); +} + + +void ReadLn( char& c ) +{ + fpc_Read_Text_Char( Input, c ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( wchar_t& xc ) +{ + char c; + fpc_Read_Text_Char( Input, c ); + xc = c; + fpc_ReadLn_End( Input ); +} + + +void ReadLn( int& l ) + +{ + fpc_Read_Text_SInt( Input, l ); + fpc_ReadLn_End( Input ); +} + + +void ReadLn( unsigned int& u ) + +{ + fpc_Read_Text_UInt( Input, u ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( unsigned short& u ) +{ + fpc_Read_Text_UInt( Input, u ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( double& v ) + +{ + Read( Input, v ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( Currency& v ) +{ + fpc_Read_Text_Currency( Input, v ); + fpc_ReadLn_End( Input ); +} + +void ReadLn( int64_t& i ) +{ + fpc_Read_Text_Int64( Input, i ); + fpc_ReadLn_End( Input ); +} + + +void ReadLn( uint64_t& q ) +{ + fpc_Read_Text_QWord( Input, q ); + fpc_ReadLn_End( Input ); +} + +/****************************************************************************** + Directory handling +******************************************************************************/ + +#ifdef windows + +typedef BOOL ( __stdcall * TDirFnType )( void* ); + + +void dirfn( TDirFnType AFunc, const AnsiString& S ) +{ + char Buffer[ 256 ]; + strcpy( Buffer, S.c_str() ); + Buffer[S.length( )] = '\x00'; + DoDirSeparators( Buffer ); + if ( ! AFunc( &Buffer[0] ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } +} + +void dirfn( TDirFnType AFunc, const WideString& S ) +{ + wchar_t Buffer[ 256 ]; + wcscpy( Buffer, S.c_str() ); + Buffer[S.length( )] = L'\x00'; + + DoDirSeparators( Buffer ); + if ( ! AFunc( &Buffer[0] ) ) + { + errno = GetLastError(); + Errno2InOutRes(); + } +} + + + +BOOL __stdcall CreateDirectoryTrunc( void* Name ) +{ + BOOL result = false; + result = CreateDirectory( (Char*) Name, NULL ); + return result; +} +#endif + +#ifdef linux +void MkDir( const string& S ) +{ + // read/write Search permission for everyone + const int MODE_MKDIR = S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IWOTH | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH; + char Buffer[ 256 ]; + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; +// Move( &S[1 - 1], Buffer, S.length( ) ); + Move( S, Buffer, S.length( ) ); + Buffer[S.length( )] = '\x00'; + if ( Fpmkdir( &Buffer[0], MODE_MKDIR ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} + +#else +void MkDir( const string& S ) +{ + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; + dirfn( TDirFnType( CreateDirectoryTrunc ), S ); +} +#endif + +void MkDir( const wstring& S ) +{ + string s = wstr2str(S); + MkDir(s); +} + +#ifdef linux +void RmDir( const string& S ) +{ + char Buffer[ 256 ]; + if ( S == "." ) + InOutRes = 16; + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; +// Move( &S[1 - 1], Buffer, S.length( ) * sizeof(Char) ); + Move( S, Buffer, S.length( ) ); + Buffer[S.length( )] = '\x00'; + Move( S, Buffer, S.length( ) ); + Buffer[S.length( )] = '\x00'; + + if ( Fprmdir( &Buffer[0] ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; +} + + +#else +void RmDir( const string& S ) +{ + if ( S == "." ) + InOutRes = 16; + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; + dirfn( TDirFnType( RemoveDirectory ), S ); +} +#endif + +void RmDir( const wstring& S ) +{ + string s = wstr2str(S); + RmDir(s); +} + +#ifdef linux +void ChDir( const string& S ) +{ + char Buffer[ 256 ]; + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; +// Move( &S[1 - 1], Buffer, S.length( ) * sizeof(Char) ); + Move( S, Buffer, S.length( ) ); + Buffer[S.length( )] = '\x00'; + if ( Fpchdir( &Buffer[0] ) < 0 ) + Errno2InOutRes(); + else + InOutRes = 0; + // File not exists is Path not found under tp7 + if ( InOutRes == 2 ) + InOutRes = 3; +} + +#else +void ChDir( const string& S ) +{ + if ( ( S.empty()) || ( InOutRes != 0 ) ) + return; + dirfn( TDirFnType( SetCurrentDirectory ), S ); + if ( InOutRes == 2 ) + InOutRes = 3; +} +#endif + +void ChDir( const wstring& S ) +{ + string s = wstr2str(S); + ChDir(s); +} + +#ifdef windows +//--------------------------------------------------------------------------- +void GetDir( unsignedchar drivenr, SmallString<255>& Dir ) +{ + char Drive [ 4 ]; + Drive[0] = '\x00'; + Drive[1] = ':'; + Drive[2] = '\x00'; + Drive[3] = '\x00'; + bool defaultdrive = false; + char DirBuf[ 260 ], SaveBuf[ 260 ]; + defaultdrive = drivenr == 0; + if ( ! defaultdrive ) + { + Drive[0]= char(drivenr + 64); + GetCurrentDirectoryA( sizeof( SaveBuf ), SaveBuf ); + if ( ! SetCurrentDirectoryA( &Drive[0] ) ) + { + errno = ((WORD) GetLastError() ); + Errno2InOutRes(); + Dir = ((char) ( drivenr + 64 ) ) + ":\\"; + SetCurrentDirectoryA( &SaveBuf[0] ); + return; + } + } + GetCurrentDirectoryA( sizeof( DirBuf ), DirBuf ); + if ( ! defaultdrive ) + SetCurrentDirectoryA( &SaveBuf[0] ); + Dir = DirBuf; + if ( ! FileNameCaseSensitive ) + Dir = UpperCase( Dir ); +} + +void GetDir( unsignedchar drivenr, String& Dir ) +{ + Char Drive [ 4 ]; + Drive[0] = _T('\x00'); + Drive[1] = _T(':'); + Drive[2] = _T('\x00'); + Drive[3] = _T('\x00'); + bool defaultdrive = false; + Char DirBuf[ 260 ], SaveBuf[ 260 ]; + defaultdrive = drivenr == 0; + if ( ! defaultdrive ) + { + Drive[0]= char(drivenr + 64); + GetCurrentDirectory( 259, SaveBuf ); + if ( ! SetCurrentDirectory( Drive ) ) + { + /* dme + errno = ((WORD) GetLastError() ); + Errno2InOutRes(); + Dir = String( 1, drivenr + 64 ) + _T(":\\"); + SetCurrentDirectory( &SaveBuf[0] ); + return; + */ + } + } + GetCurrentDirectory( 259, DirBuf ); + if ( ! defaultdrive ) + SetCurrentDirectory( SaveBuf ); + Dir = DirBuf; + if ( ! FileNameCaseSensitive ) + Dir = UpperCase( Dir ); +} +#elif defined(linux) +// !! for Now we use getcwd, unless we are fpc_use_libc. +// !! the old Code is _still needed_ since the syscall sometimes doesn'T work +// !! ON special filesystems like NFS etc. +// !! in the libc versions, the Alt Code is Already integrated in the libc Code. +// !! also SIGNIFICANTLY boosted BufferSize. this will make failure of the +// !! DOS Legacy API'S better visibile due to cut-OFF Path, instead of "empty" + + + +void GetDir( unsignedchar drivenr, String& sDir ) +{ + char Buf[ 2048 ]; + Stat cwdinfo; + Stat rootinfo; + AnsiString thedir, Dummy; + Dir* dirstream = NULL; + dirent* D = NULL; + AnsiString Name; + Stat thisdir; + AnsiString tmp; + sDir = _T(""); + if ( getcwd( &Buf[0], sizeof( Buf ) ) != NULL ) +#ifdef _WIDESTRING + sDir = str2wstr(Buf); +#else + sDir = Buf; +#endif + else + { + thedir = ""; + Dummy = ""; + + // get root Directory information + tmp = "/" ; + if ( fpstat( &tmp[1], rootinfo ) < 0 ) + return; + do + { + tmp = AnsiString( Dummy ) + "." + "\x00"; + // get current Directory information + if ( fpstat( &tmp[1], cwdinfo ) < 0 ) + return; + tmp = AnsiString( Dummy ) + ".." + "\x00"; + // Open Directory Stream + // try to find the current inode number of the cwd + AnsiString ws = tmp; + dirstream = Fpopendir( ws.c_str() ); + if ( dirstream == NULL ) + return; + do + { + Name = ""; + D = Fpreaddir( dirstream ); + // no more Entries to read ... + if ( !( D != NULL ) ) + break; + tmp = AnsiString( Dummy ) + "../" + D->d_name + "\x00"; + if ( fpstat( &tmp[1], thisdir ) == 0 ) + { + // found the entry for this Directory Name + if ( ( cwdinfo.st_dev == thisdir.st_dev ) && ( cwdinfo.st_ino == thisdir.st_ino ) ) + { + // are the filenames of type '.' or '..' ? + // then do not set the Name. + if ( ! ( ( D->d_name[0] == '.' ) && ( ( D->d_name[1] == '\x00' ) || ( ( D->d_name[1] == '.' ) && ( D->d_name[2] == '\x00' ) ) ) ) ) + Name = AnsiString( "/" ) + D->d_name; + } + } + } + while ( ! ( strcmp(&Name[1], "" ) != 0 ) ); + if ( Fpclosedir( dirstream ) < 0 ) + return; + thedir = AnsiString( Name ) + thedir.c_str(); + Dummy = AnsiString( Dummy ) + "../"; + if ( ( cwdinfo.st_dev == rootinfo.st_dev ) && ( cwdinfo.st_ino == rootinfo.st_ino ) ) + { + if ( strcmp(&thedir[1], "" ) == 0 ) + sDir = _T("/"); + else + +#ifdef _WIDESTRING + sDir = str2wstr(thedir); +#else + sDir = thedir; +#endif + return; + } + } + while ( ! ( false ) ); + } +} +#else +#error unknown platform +#endif + + + +/****************************************************************************** + Initializing +******************************************************************************/ + + +void OpenStdIO( TTextRec& t, int Mode, THandle hdl ) +{ + AssignFile( t, _T("") ); + t.Handle = hdl; + t.Mode = Mode; + t.CloseFunc = (void*) FileCloseFuncA; + switch ( Mode ) + { + case fmInput: + t.InOutFunc = (void*) FileReadFuncA; + break; + case fmOutput: + { + t.InOutFunc = (void*) FileWriteFuncA; + if ( do_isdevice( hdl ) ) + t.FlushFunc = (void*) FileWriteFuncA; + } + break; + default: + //HandleError(102); + throw runtime_error("internal error"); + } +} + +#ifdef linux +void SysInitStdIO( ) +{ + OpenStdIO( Input, fmInput, STDIN_FILENO ); + OpenStdIO( Output, fmOutput, STDOUT_FILENO ); + OpenStdIO( ErrOutput, fmOutput, STDERR_FILENO ); + OpenStdIO( Stdout, fmOutput, STDOUT_FILENO ); + OpenStdIO( Stderr, fmOutput, STDERR_FILENO ); +} +#else +void SysInitStdIO( ) +{ + /* Setup stdin, stdout and stderr, for GUI apps redirect stderr,stdout to be + displayed in a messagebox */ + + StdInputHandle = GetStdHandle( STD_INPUT_HANDLE ) ; + StdOutputHandle = GetStdHandle( STD_OUTPUT_HANDLE ) ; + StdErrorHandle = GetStdHandle( STD_ERROR_HANDLE ) ; + + if ( ! IsConsole ) + { + //AssignError(stderr); + //AssignError(stdout); + AssignFile( Output, _T("") ); + AssignFile( Input, _T("") ); + AssignFile( ErrOutput, _T("") ); + } + else + { + OpenStdIO( Input, fmInput, StdInputHandle ); + OpenStdIO( Output, fmOutput, StdOutputHandle ); + OpenStdIO( ErrOutput, fmOutput, StdErrorHandle ); + OpenStdIO( Stdout, fmOutput, StdOutputHandle ); + OpenStdIO( Stderr, fmOutput, StdErrorHandle ); + } +} +#endif + +WORD IOResult( ) +{ + WORD result = 0; + WORD* HInoutRes; + HInoutRes = &InOutRes; + result = *HInoutRes; + HInoutRes = 0; + InOutRes = 0; // Per Delphi docs: "Calling IOResult clears the internal error flag". Without this, other checks break. + return result; +} + + +void d2c_file_initialization() +{ + FileMode = 2; + ((TTextRec*) &Input )->Mode = fmClosed; + ((TTextRec*) &Output )->Mode = fmClosed; + ((TTextRec*) &ErrOutput )->Mode = fmClosed; + SysInitStdIO(); +} + +void d2c_file_finalization() +{ + CloseFile( Input ); + CloseFile( Output ); + CloseFile( ErrOutput ); +} + +class d2c_file_unit +{ +public: +d2c_file_unit() +{ + d2c_file_initialization(); +} +~d2c_file_unit(){ d2c_file_finalization(); } +}; +d2c_file_unit _d2c_file_unit; + +} //namespace System + diff --git a/OpenDSSC/Support/d2c_sysfile.h b/OpenDSSC/Support/d2c_sysfile.h new file mode 100644 index 0000000..3e8e87a --- /dev/null +++ b/OpenDSSC/Support/d2c_sysfile.h @@ -0,0 +1,613 @@ +#ifndef d2c_sysfileH +#define d2c_sysfileH + +#include "d2c_systypes.h" +#include "dirsep.h" + + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +class Currency; + +#ifdef linux +#include +#endif + + +namespace System +{ + +struct TFileRec { + THandle Handle; + int Mode; + unsigned int RecSize; + unsigned char _private [ 28 ]; + unsigned char UserData [ 32 ]; + Char Name [ 260 ]; +}; + +template +struct TTypedFile +{ + THandle Handle; + int Mode; + unsigned int RecSize; + unsigned char _private [ 28 ]; + unsigned char UserData [ 32 ]; + Char Name [ 260 ]; +}; + +typedef char TextBufA [ 260 ]; + +struct TTextRec { + THandle Handle; + int Mode; + unsigned int BufSize; + unsigned int BufPos; + unsigned int BufEnd; + char* BufPtr; + void* OpenFunc; + void* InOutFunc; + void* FlushFunc; + void* CloseFunc; + unsigned char UserData [ 32 ]; + Char Name [ 260 ]; + char LineEnd[3]; + TextBufA Buffer; +}; + +typedef TTypedFile file; +typedef TTextRec Text; +typedef TTextRec *ptext; + +enum TTextLineBreakStyle {tlbsLF, tlbsCRLF, tlbsCR }; + +extern bool FileNameCaseSensitive; +extern bool CtrlZMarksEOF; +extern TTextLineBreakStyle DefaultTextLineBreakStyle; + +#ifndef windows +const Char DirectorySeparator = _T(DIRSEP_CHAR); +const Char DriveSeparator = _T('/'); +const Char PathSeparator = _T(';'); +//const int maxExitCode = 255; +const int MAXPATHLEN = 4096; // LINUX has always got to be bigger + +const int UnusedHandle = - 1; +//const int StdInputHandle = 0; +//const int StdOutputHandle = 1; +//const int StdErrorHandle = 2; +#else +const Char DirectorySeparator = _T(DIRSEP_CHAR); +const Char DriveSeparator = _T(':'); +const Char PathSeparator = _T(';'); +const int MaxPathLen = 260; + +extern THandle UnusedHandle; +extern THandle StdInputHandle; +extern THandle StdOutputHandle; +extern THandle StdErrorHandle; + +#endif + + +const bool LFNSupport = true; +const char ExtensionSeparator = '.'; +extern TSet < UChar, 0, 255 > AllowDirectorySeparators; +extern TSet < UChar, 0, 255 > AllowDriveSeparators; + +extern bool FileNameCaseSensitive; +extern bool CtrlZMarksEOF; + +/* File attributes */ +const int fmCreate = 0xffff; +const int faReadOnly = 0x00000001; +const int faHidden = 0x00000002; +const int faSysFile = 0x00000004; +const int faVolumeId = 0x00000008; +const int faDirectory = 0x00000010; +const int faArchive = 0x00000020; +const int faSymLink = 0x00000040; +const int faAnyFile = 0x0000003f; +const int fmOpenRead = 0x0000; +const int fmOpenWrite = 0x0001; +const int fmOpenReadWrite = 0x0002; +const int fmShareCompat = 0x0000; +const int fmShareExclusive = 0x0010; +const int fmShareDenyWrite = 0x0020; +const int fmShareDenyRead = 0x0030; +const int fmShareDenyNone = 0x0040; +const int fsFromBeginning = 0; +const int fsFromCurrent = 1; +const int fsFromEnd = 2; +const THandle feInvalidHandle = ((THandle) - 1 ); //return value on FileOpen error + + +/* file input modes */ +const int fmClosed = 0xD7B0; +const int fmInput = 0xD7B1; +const int fmOutput = 0xD7B2; +const int fmInOut = 0xD7B3; +//const int fmAppend = 0xD7B4; +extern TTextRec ErrOutput, Output, Input, Stdout, Stderr; +extern unsigned char FileMode; +WORD IOResult( ); + +const int fmAppend = 0xD7B4; // unknown in C++Builder 6? + + +typedef void ( * FileFunc )( TTextRec& ); + +/* Standard In- and Output */ +extern WORD InOutRes; + + +/**************************************************************************** + Untyped File Management +****************************************************************************/ + +void AssignFile( TFileRec& f, const String& Name ); +void AssignFile( TFileRec& f, Char c ); +void Assign( TFileRec& f, const String& Name ); + +void Rewrite( TFileRec& f, int l = 128 ); +void Reset( TFileRec& f, int l = 128 ); +void CloseFile( TFileRec& f ); +void Close( TFileRec& f ); + +void BlockWrite( TTypedFile& f, void* buf, int64_t Count, int& Result ); +void BlockWrite( TTypedFile& f, void* buf, int Count, int& Result ); +void BlockWrite( TTypedFile& f, void* buf, WORD Count, WORD& Result ); +void BlockWrite( TTypedFile& f, void* buf, unsigned int Count, unsigned int& Result ); +void BlockWrite( TTypedFile& f, void* buf, WORD Count, int& Result ); +void BlockWrite( TTypedFile& f, void* buf, int Count ); +void BlockRead( TTypedFile& f, void* buf, int Count, int& Result ); +void BlockRead( TTypedFile& f, void* buf, int64_t Count ); +int64_t FileSize( TFileRec& f ); // FileSize can't be used on a text TTypedFile. +int64_t FilePos( TFileRec& f, int l = 128 ); +void Seek( TTypedFile& f, int64_t Pos ); +void Rename( TTypedFile& f, const char* P ); +void Rename( TTypedFile& f, const wchar_t* P ); +void Rename( TTypedFile& f, const AnsiString& s ); +void Rename( TTypedFile& f, const WideString& s ); +void Rename( TTypedFile& f, char c ); +void Rename( TTypedFile& f, wchar_t c ); +bool Eof( TFileRec& f, int l = 128 ); +void Truncate( TFileRec& f, int RecSize ); + + +/**************************************************************************** + Typed File Management +****************************************************************************/ + +void fpc_typed_write( int typesize, TFileRec& f, void* buf ); +void fpc_typed_read( int typesize, TFileRec& f, void* buf ); + +//--------------------------------------------------------------------------- +template +void AssignFile( TTypedFile& f, const String& Name ) +{ + AssignFile(*((TFileRec*) &f), Name); +} +//--------------------------------------------------------------------------- +template +void AssignFile( TTypedFile& f, const Char* P ) +{ + AssignFile(*((TFileRec*) &f), P); +} +//--------------------------------------------------------------------------- +template +void AssignFile( TTypedFile& f, Char c ) +{ + AssignFile(*((TFileRec*) &f), c); +} +//--------------------------------------------------------------------------- +template +int64_t FileSize( TTypedFile& f ) // FileSize can't be used on a text file. +{ + return FileSize(*((TFileRec*) &f)); +} +//--------------------------------------------------------------------------- +template +bool Eof( TTypedFile& f ) +{ + return Eof(*((TFileRec*) &f), sizeof(T) ); +} +//--------------------------------------------------------------------------- +template +void CloseFile( TTypedFile& f ) +{ + CloseFile(*((TFileRec*) &f)); +} +//--------------------------------------------------------------------------- +template +void Close( TTypedFile& f ) +{ + CloseFile(*((TFileRec*) &f)); +} +//--------------------------------------------------------------------------- +template +void Reset( TTypedFile& f, int l = -1 ) +{ + if( InOutRes != 0) + return; + if(l == -1) + Reset( *((TFileRec*) &f), sizeof(T) ); + else + Reset( *((TFileRec*) &f), l ); + +} +//--------------------------------------------------------------------------- +template +void Rewrite( TTypedFile& f, int l = -1 ) +{ + if( InOutRes != 0) + return; + if(l == -1) + Rewrite(*((TFileRec*) &f), sizeof(T) ); + else + Rewrite(*((TFileRec*) &f), l ); +} +//--------------------------------------------------------------------------- +template +void Write( TTypedFile& f, void* buf ) +{ + fpc_typed_write( f.RecSize, *((TFileRec*)&f), buf ); +} +//--------------------------------------------------------------------------- +template +void Read( TTypedFile& f, void* buf ) +{ + fpc_typed_read( f.RecSize, *((TFileRec*)&f), buf ); +} + +///////// +//--------------------------------------------------------------------------- +template +void Truncate( TTypedFile& f ) +{ + if( InOutRes != 0) + return; + Truncate(*((TFileRec*) &f), ((TFileRec*) &f )->RecSize ); +} + +/**************************************************************************** + Text File Management +****************************************************************************/ + + +void Assign( TTextRec& f, const String& Name ); +void Assign( TTextRec& t, Char c ); +void AssignFile( TTextRec& f, const String& Name ); +void AssignFile( TTextRec& t, Char c ); +void CloseFile( TTextRec& t ); +void Close( TTextRec& t ); +void Rewrite( TTextRec& t ); +void Reset( TTextRec& t ); +void Append( TTextRec& t ); +void Flush( TTextRec& t ); +void Erase( TTextRec& t ); +void Rename( TTextRec& t, const char* P ); +void Rename( TTextRec& t, const wchar_t* P ); +void Rename( TTextRec& t, const AnsiString& s ); +void Rename( TTextRec& t, const WideString& s ); +void Rename( TTextRec& t, char c ); +void Rename( TTextRec& t, wchar_t c ); +bool Eof( TTextRec& t ); +bool Eof( ); +bool EoLn( TTextRec& t ); +bool EoLn( ); +bool SeekEof( TTextRec& t ); +bool SeekEof( ); +bool SeekEoLn( TTextRec& t ); +bool SeekEoLn( ); +void SetTextBuf( TTextRec& t, void* buf, int size ); +void SetTextLineEnding(TTextRec& t, String& Ending); + + +void Write( TTextRec& t, const SmallString<255> s, int Len = 0 ); +void Write( TTextRec& t, const char* P, int Len = 0 ); +void Write( TTextRec& t, const AnsiString& s, int Len = 0 ); +void Write( TTextRec& t, const wchar_t* P, int Len = 0 ); +void Write( TTextRec& t, const WideString& s, int Len = 0 ); +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void Write( TTextRec& t, long l, int Len = 0 ); +#endif +void Write( TTextRec& t, int l, int Len = 0 ); +void Write( TTextRec& t, unsigned int l, int Len = 0 ); +void Write( TTextRec& t, unsigned short l, int Len = 0 ); +void Write( TTextRec& t, uint64_t q, int Len = 0 ); +void Write( TTextRec& t, int64_t i, int Len = 0 ); +void Write( TTextRec& t, long double r, int rt = -1, int fixkomma = -1 ); +void Write( TTextRec& t, double r, int rt = -1, int fixkomma = -1 ); +void Write( TTextRec& t, Currency c, int fixkomma = -1, int Len = 0 ); +void Write( TTextRec& t, bool b, int Len = 0 ); +void Write( TTextRec& t, char c, int Len = 0 ); +void Write( TTextRec& t, unsigned char c, int Len = 0 ); +void Write( TTextRec& t, wchar_t c, int Len = 0 ); +void WriteLn( TTextRec& t ); +void WriteLn( TTextRec& t, const SmallString<255> s, int Len = 0 ); +void WriteLn( TTextRec& t, const char* P, int Len = 0 ); +void WriteLn( TTextRec& t, const AnsiString& s, int Len = 0 ); +void WriteLn( TTextRec& t, const wchar_t* P, int Len = 0 ); +void WriteLn( TTextRec& t, const WideString& s, int Len = 0 ); +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void WriteLn( TTextRec& t, long l, int Len = 0 ); +#endif +void WriteLn( TTextRec& t, int l, int Len = 0 ); +void WriteLn( TTextRec& t, unsigned int l, int Len = 0 ); +void WriteLn( TTextRec& t, unsigned short l, int Len = 0 ); +void WriteLn( TTextRec& t, uint64_t q, int Len = 0 ); +void WriteLn( TTextRec& t, int64_t i, int Len = 0 ); +void WriteLn( TTextRec& t, long double r, int rt = -1, int fixkomma = -1 ); +void WriteLn( TTextRec& t, double r, int rt = -1, int fixkomma = -1 ); +void WriteLn( TTextRec& t, Currency c, int fixkomma, int Len = -1 ); +void WriteLn( TTextRec& t, bool b, int Len = 0 ); +void WriteLn( TTextRec& t, char c, int Len = 0 ); +void WriteLn( TTextRec& t, unsigned char c, int Len = 0 ); +void WriteLn( TTextRec& t, wchar_t c, int Len = 0 ); +void Write( const SmallString<255> s, int Len = 0 ); +void Write( const char* P, int Len = 0 ); +void Write( const AnsiString& s, int Len = 0 ); +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void Write( long l, int Len = 0 ); +#endif +void Write( int l, int Len = 0 ); +void Write( unsigned int l, int Len = 0 ); +void Write( uint64_t q, int Len = 0 ); +void Write( int64_t i, int Len = 0 ); +void Write( long double r, int rt = -1, int fixkomma = -1 ); +void Write( double r, int rt = -1, int fixkomma = -1 ); +void Write( Currency c, int fixkomma = -1, int Len = 0 ); +void Write( bool b, int Len = 0 ); +void Write( char c, int Len = 0 ); +void WriteLn( ); +void WriteLn( const SmallString<255> s, int Len = 0 ); +void WriteLn( const char* P, int Len = 0 ); +void WriteLn( const AnsiString& s, int Len = 0 ); +#ifndef _D2C_SYSFILE_H_LONG_IS_INT64 +void WriteLn( long l, int Len = 0 ); +#endif +void WriteLn( int l, int Len = 0 ); +void WriteLn( unsigned int l, int Len = 0 ); +void WriteLn( uint64_t q, int Len = 0 ); +void WriteLn( int64_t i, int Len = 0 ); +void WriteLn( long double r, int rt = -1, int fixkomma = -1 ); +void WriteLn( double r, int rt = -1, int fixkomma = -1 ); +void WriteLn( Currency c, int fixkomma = -1, int Len = 0 ); +void WriteLn( bool b, int Len = 0 ); +void WriteLn( char c, int Len = 0 ); +void Write( wchar_t c, int Len = 0); +void WriteLn( wchar_t c, int Len = 0 ); +void Write( const wchar_t* P, int Len = 0 ); +void Write( const WideString& s, int Len = 0 ); +void WriteLn( const wchar_t* P, int Len = 0 ); +void WriteLn( const WideString& s, int Len = 0 ); +// ---------- +void Read( TTextRec& t, SmallString<255>& s ); +void Read( TTextRec& t, char* s, int maxlen = 0x7FFFFFFF ); +void Read( TTextRec& t, AnsiString& s ); +void Read( TTextRec& t, char& c ); +void Read( TTextRec& t, WideString& s ); +void Read( TTextRec& t, wchar_t& c ); +void Read( TTextRec& t, unsigned int& u ); +void Read( TTextRec& t, unsigned short& u ); +void Read( TTextRec& t, long double& v ); +void Read( TTextRec& f, Currency& v ); +void Read( TTextRec& t, double& v ); +void Read( TTextRec& t, int64_t& i ); +void Read( TTextRec& t, uint64_t& q ); +void ReadLn( TTextRec& t); +void ReadLn( TTextRec& t, SmallString<255>& s ); +void ReadLn( TTextRec& t, char* s, int maxlen = 0x7FFFFFFF ); +void ReadLn( TTextRec& t, AnsiString& s ); +void ReadLn( TTextRec& t, char& c ); +void ReadLn( TTextRec& t, WideString& s ); +void ReadLn( TTextRec& t, wchar_t& c ); +void ReadLn( TTextRec& t, int& l ); +void ReadLn( TTextRec& t, unsigned int& u ); +void ReadLn( TTextRec& t, unsigned short& u ); +void ReadLn( TTextRec& t, long double& v ); +void ReadLn( TTextRec& f, Currency& v ); +void ReadLn( TTextRec& t, double& v ); +void ReadLn( TTextRec& t, int64_t& i ); +void ReadLn( TTextRec& t, uint64_t& q ); +void Read( SmallString<255>& s ); +void Read( char* s, int maxlen = 0x7FFFFFFF ); +void Read( AnsiString& s ); +void Read( char& c ); +void Read( WideString& s ); +void Read( wchar_t& c ); +void Read( int& l ); +void Read( unsigned int& u ); +void Read( long double& v ); +void Read( double& v ); +void Read( Currency& v ); +void Read( int64_t& i ); +void Read( uint64_t& q ); +void ReadLn( ); +void ReadLn( SmallString<255>& s ); +void ReadLn( char* s, int maxlen = 0x7FFFFFFF ); +void ReadLn( AnsiString& s ); +void ReadLn( char& c ); +void ReadLn( WideString& s ); +void ReadLn( wchar_t& c ); +void ReadLn( int& l ); +void ReadLn( unsigned int& u ); +void ReadLn( unsigned short& u ); +void ReadLn( long double& v ); +void ReadLn( double& v ); +void ReadLn( Currency& v ); +void ReadLn( int64_t& i ); +void ReadLn( uint64_t& q ); + + +template +void Write( TTextRec& t, SmallString s, int Len = 0 ) +{ + Write( t, &s[1], s[0] - 1, Len, true ); +} +//--------------------------------------------------------------------------- +template +void WriteLn( TTextRec& t, SmallString s, int Len = 0 ) +{ + WriteLn( t, &s[1], s[0] - 1, Len, true ); +} +//--------------------------------------------------------------------------- +template +void Write( SmallString s, int Len = 0 ) +{ + Write( &s[1], s[0] - 1, Len, true ); +} +//--------------------------------------------------------------------------- +template +void WriteLn( SmallString s, int Len = 0 ) +{ + WriteLn( &s[1], s[0] - 1, Len, true ); +} +//--------------------------------------------------------------------------- +template +void Read( TTextRec& t, SmallString& s ) +{ + char buf[sz + 1]; + Read( t, buf, sz); + buf[sz] = '\0'; + s = buf; +} +//--------------------------------------------------------------------------- +template +void ReadLn( TTextRec& t, SmallString& s ) +{ + char buf[sz + 1]; + ReadLn( t, buf, sz); + buf[sz] = '\0'; + s = buf; +} +//--------------------------------------------------------------------------- +template +void Read( SmallString& s ) +{ + char buf[sz + 1]; + Read( buf, sz); + buf[sz] = '\0'; + s = buf; +} +//--------------------------------------------------------------------------- +template +void ReadLn( SmallString& s ) +{ + char buf[sz + 1]; + ReadLn( buf, sz); + buf[sz] = '\0'; + s = buf; +} + +/***************************************************************************** + Directory Management +*****************************************************************************/ +void ChDir( const std::string& S ); +void ChDir( const std::wstring& S ); +void RmDir( const std::string& S ); +void RmDir( const std::wstring& S ); +void MkDir( const std::string& S ); +void MkDir( const std::wstring& S ); +void GetDir( unsignedchar drivenr, SmallString<255>& Dir ); +void GetDir( unsignedchar drivenr, String& Dir ); + +#ifdef linux + /* Directory services */ + +struct Dir { + int dd_fd; + int dd_loc; + int dd_size; + dirent* dd_buf; + /*the following are used in libc, but not in the LINUX kernel Sources ??*/ + unsigned int dd_nextoff; + int dd_max; /*Size of Buf. irrelevant, as Buf is of type dirent*/ + void* dd_lock; +}; + + +//typedef Dir TDir; +//typedef DIR* DIR*; + +Dir* Fpopendir( const char* DirName ); +Dir* Fpopendir( const wchar_t* DirName ); +cint Fpclosedir( Dir* dirP ); +dirent* Fpreaddir( Dir* dirP ); + +#endif + + +} // namespace System + +//using namespace System; + +#endif // System diff --git a/OpenDSSC/Support/d2c_sysmath.cpp b/OpenDSSC/Support/d2c_sysmath.cpp new file mode 100644 index 0000000..55b2fc8 --- /dev/null +++ b/OpenDSSC/Support/d2c_sysmath.cpp @@ -0,0 +1,46 @@ +//#include "stdafx.h" + +/******************************************************************************* + + Delphi2Cpp Library d2c_sysmath.h + + Copyright (c) 2011 Dr. Detlef Meyer-Eltz + ALL RIGHTS RESERVED + + + mathematical routines according to the Delphi system unit + + Authorized for unlimited use in any Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + + +*******************************************************************************/ + +#include "d2c_sysmath.h" +#include +#include + + +namespace System +{ + +//--------------------------------------------------------------------------- +int64_t Round( long double X ) +{ + return (int64_t) ( X < 0 ? X -.5 : X + .5) ; //floor(X + 0.5); +} +//--------------------------------------------------------------------------- +long double Frac( long double X ) +{ + return X - int(X); +} +//--------------------------------------------------------------------------- +int64_t Trunc( long double X ) +{ + long double ld; + modfl(X, &ld); + return (int64_t) ld; +} + +} // namespace System diff --git a/OpenDSSC/Support/d2c_sysmath.h b/OpenDSSC/Support/d2c_sysmath.h new file mode 100644 index 0000000..2064258 --- /dev/null +++ b/OpenDSSC/Support/d2c_sysmath.h @@ -0,0 +1,50 @@ +#ifndef d2c_sysmathH +#define d2c_sysmathH + +/******************************************************************************* + + Delphi2Cpp Library d2c_sysmath.h + + Copyright (c) 2011 Dr. Detlef Meyer-Eltz + ALL RIGHTS RESERVED + + + mathematical routines according to the Delphi system unit + + Authorized for unlimited use in any Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + + +*******************************************************************************/ + +#include "d2c_systypes.h" + + +namespace System { + + +int64_t Round( long double d ); +long double Frac( long double d ); +int64_t Trunc( long double d ); + +/* +// from here on not contained in Delphi2Cpp trial +RandSeed; +Random +Randomize +Sqr +Pi +Sqr +Sqrt +ArcTan +Ln +Sin +Cos +Exp +Int +*/ + +} // namespace System + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_sysstring.cpp b/OpenDSSC/Support/d2c_sysstring.cpp new file mode 100644 index 0000000..a15dd9e --- /dev/null +++ b/OpenDSSC/Support/d2c_sysstring.cpp @@ -0,0 +1,998 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_sysstring.h" +#include "d2c_system.h" +#include "d2c_sysexcept.h" +#include "Sysutils.h" +#include + +#ifdef linux +#include +#include +#endif + +#undef max + +using namespace std; + +/***************************************************************************** + subroutines for String handling +*****************************************************************************/ + +namespace System +{ + +//--------------------------------------------------------------------------- +char UpCase( char C ) +{ + return toupper(C); +} +//--------------------------------------------------------------------------- +wchar_t UpCase( wchar_t C ) +{ + return towupper(C); +} +//--------------------------------------------------------------------------- +int Pos(const string& Substr, const string& S) +{ + string::size_type pos = S.find(Substr); + if(pos == string::npos) + return 0; + else + return pos + 1; // postion which Substr would have in a 1 based Delphi-String +} +//--------------------------------------------------------------------------- +int Pos(const char* Substr, const string& S) +{ + string::size_type pos = S.find(Substr); + if(pos == string::npos) + return 0; + else + return pos + 1; // postion which Substr would have in a 1 based Delphi-String +} +//--------------------------------------------------------------------------- +int Pos(const wstring& Substr, const wstring& S) +{ + wstring::size_type pos = S.find(Substr); + if(pos == wstring::npos) + return 0; + else + return pos + 1; // postion which Substr would have in a 1 based Delphi-String +}//--------------------------------------------------------------------------- +int Pos(char Substr, const string& S) +{ + string::size_type pos = S.find(Substr); + if(pos == string::npos) + return 0; + else + return pos + 1; // postion which Substr would have in a 1 based Delphi-String +} +//--------------------------------------------------------------------------- +int Pos(wchar_t Substr, const wstring& S) +{ + wstring::size_type pos = S.find(Substr); + if(pos == wstring::npos) + return 0; + else + return pos + 1; // postion which Substr would have in a 1 based Delphi-String +} + + +#ifdef windows +/***************************************************************************** + OS dependend WideStrings +*****************************************************************************/ + /* MultiByteToWideChar */ + + + +// MFC MBCS/Unicode Conversion Macros +// A2CW (LPCSTR) -> (LPCWSTR) +// A2W (LPCSTR) -> (LPWSTR) +// W2CA (LPCWSTR) -> (LPCSTR) +// W2A (LPCWSTR) -> (LPSTR) + +//If Len parameter is -1, the function processes the entire input string, including the terminating null character. +void Wide2AnsiMove( const wchar_t* Source, std::string& Dest, int Len ) +{ + int DestLen = 0; + // retrieve Length including trailing #0 + // not anymore, because this must also be usable for Single characters + DestLen = WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, Source, Len, NULL, 0, NULL, NULL ); + // this will NULL-Terminate + Dest.resize( DestLen ); + WideCharToMultiByte( CP_ACP, WC_NO_BEST_FIT_CHARS, Source, Len, (char*) Dest.c_str(), DestLen, NULL, NULL ); +} + +//If Len parameter is -1, the function processes the entire input string, including the terminating null character. +void Ansi2WideMove( const char* Source, std::wstring& Dest, int Len ) +{ + int DestLen = 0; + // retrieve Length including trailing #0 + // not anymore, because this must also be usable for Single characters + DestLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Source, Len, NULL, 0 ); + // this will NULL-Terminate + Dest.resize( DestLen); + MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, Source, Len, (wchar_t*) Dest.c_str(), DestLen ); +} + + +std::wstring Win32WideUpper( const std::wstring& S ) +{ + std::wstring result; + result = S; + //UniqueString( result ); + if ( result.length( ) > 0 ) + CharUpperBuffW( ((wchar_t*) result.c_str()), result.length( ) ); + return result; +} + + +std::wstring Win32WideLower( const std::wstring& S ) +{ + std::wstring result; + result = S; + //UniqueString( result ); + if ( result.length( ) > 0 ) + CharLowerBuffW( ((wchar_t*) result.c_str()), result.length( ) ); + return result; +} + + +void WideCharLenToStrVar( wchar_t* Src, int Len, std::string& Dest ) +{ + Dest = WideCharLenToString( Src, Len ); +} + + +void WideCharToStrVar( wchar_t* S, std::string& Dest ) +{ + Dest = WideCharToString( S ); +} + + + + +/* converts an UTF-16 Code Point or surrogate pair to UTF-32 */ +UCS4Char utf16toutf32( const std::wstring& S, const unsigned int Index, int& Len ) +{ + UCS4Char result; + wchar_t W = L'\0'; + /* UTF-16 Points in the Range #$0-#$D7FF and #$E000-#$FFFF */ + /* are the same in UTF-32 */ + W = S[Index - 1]; + if ( ( W <= L'\xff' ) || ( W >= L'\x00' ) ) + { + result = ((UCS4Char) W ); + Len = 1; + } + /* valid surrogate pair? */ + else /* W>=#$D7FF Check not needed, Checked above */ + if ( ( W <= L'\xff' ) && ( Index < S.length( ) ) && ( S[Index + 1 - 1] >= L'\x00' ) && ( S[Index + 1 - 1] <= L'\xff' ) ) + /* convert the surrogate pair to UTF-32 */ + { + result = ( ( ((UCS4Char) W ) - 0xD800 ) << 10 ) + ( ((UCS4Char) ( S[Index + 1 - 1] ) ) - 0xDC00 ) + 0x10000; + Len = 2; + } + else + /* Invalid surrogate -> do nothing */ + { + result = ((UCS4Char) W ); + Len = 1; + } + return result; +} + + +UCS4String WideStringToUCS4String( const std::wstring& S ) +{ + UCS4String result; + int i = 0, slen = 0, destindex = 0; + int Len = 0; + slen = S.length( ); + result.resize( slen + 1 ); + i = 1; + destindex = 0; + while ( i <= slen ) + { + result[destindex] = utf16toutf32( S, i, Len ); + destindex++; + i += Len; + } + /* destindex <= slen (surrogate pairs may have been merged) */ + /* destindex+1 for terminating #0 (dynamic arrays are */ + /* implicitely filled with zero) */ + result.resize( destindex + 1 ); + return result; +} + + +/* Concatenates an UTF-32 char to A WideString. S *must* be unique when entering. */ +void ConcatUTF32ToWideStr( const UCS4Char NC, std::wstring& S, unsigned int& Index ) +{ + wchar_t* P = NULL; + /* if NC > $FFFF, we need two places */ + if ( Index + int( NC > 0xFFFF ) > S.length( ) ) + if ( S.length( ) < 10 * 256 ) + S.resize( S.length( ) + 10 ); + else + S.resize( S.length( ) + ( S.length( ) >> 8 ) ); + /* we know that S is unique -> avoid UniqueString calls*/ + P = &S[Index - 1]; + if ( NC < 0xFFFF ) + { + *P = ((wchar_t) NC ); + Index++; + } + else + if ( ((DWORD) NC ) <= 0x10FFFF ) + { + *P = ((wchar_t) ( ( ( NC - 0x10000 ) >> 10 ) + 0xD800 ) ); + *( P + 1 ) = ((wchar_t) ( ( NC - 0x10000 ) & 0x3FF + 0xDC00 ) ); + Index += 2; + } + else + /* Invalid Code Point */ + { + *P = L'?'; + Index++; + } +} + + +std::wstring UCS4StringToWideString( const UCS4String& S ) +{ + std::wstring result; + unsigned int i = 0; + unsigned int resindex = 0; + /* Skip terminating #0 */ + result.resize( S.size( ) - 1 ); + resindex = 1; + for ( i = 0; i <= S.size() - 1 /*# High() */ - 1; i++) + ConcatUTF32ToWideStr( S[i], result, resindex ); + /* adjust result Length (may be Too big due to Growing */ + /* for surrogate pairs) */ + result.resize( resindex - 1 ); + return result; +} +#elif defined (linux) +/* Unicode encoding Name */ + + +const char unicode_encoding2[] = "UTF-16LE"; +const char unicode_encoding4[] = "UCS-4LE"; + +/* en_US.UTF-8 needs maximally 6 Chars, UCS-4/UTF-32 needs 4 */ +/* -> 10 should be enough? should actually use MB_CUR_MAX, but */ +/* that'S A libc macro mapped to Internal functions/variables */ +/* and Thus not A stable external API ON systems Where libc */ +/* breaks backwards compatibility every Now and then */ +//const int MB_CUR_MAX = 10; + + +cint fpgetCerrno( ) +{ + return *__errno_location(); +} + + +void fpsetCerrno( cint err ) +{ + errno = err; +} + + +__thread iconv_t iconv_ansi2wide = NULL, iconv_wide2ansi = NULL; +/* +void DefaultWide2AnsiMove( wchar_t* Source, std::string& Dest, int Len ) +{ + int i = 0; + Dest.resize( Len ); + for ( i = 1; i <= Len; i++) + { + if ( ((WORD) *Source ) < 256 ) + Dest[i - 1] = ((Char) ((WORD) *Source ) ); + else + Dest[i - 1] = '?'; + Source++; + } +} + + +void DefaultAnsi2WideMove( Char* Source, std::wstring& Dest, int Len ) +{ + int i = 0; + Dest.resize( Len ); + for ( i = 1; i <= Len; i++) + { + Dest[i - 1] = ((wchar_t) ((unsigned char) *Source ) ); + Source++; + } +} +*/ +// http://www.gnu.org/s/hello/manual/libc/iconv-Examples.html#iconv-Examples +void Wide2AnsiMove( wchar_t* Source, std::string& Dest, int Len ) +{ + size_t outlength = 0, outoffset = 0, SrcLen = 0, outleft = 0; + wchar_t* SrcPos = NULL; + char* destPos = NULL; + char* mynil = NULL; + size_t my0 = 0; + cint err = 0; + Dest.resize( Len * 3 ); // rought estimation + outlength = Len * 3; + SrcLen = Len * sizeof(wchar_t); + SrcPos = Source; + destPos = (char*) Dest.c_str(); + outleft = outlength; + while ( iconv( iconv_wide2ansi, ((char**) &SrcPos ), &SrcLen, &destPos, &outleft ) == ((size_t) - 1 ) ) + { + err = fpgetCerrno(); + switch ( err ) + { + case + /* Last character is incomplete sequence */ ESysEINVAL: case + /* incomplete sequence in the middle */ ESysEILSEQ: + { + /* Skip and set to '?' */ + SrcPos++; + SrcLen -= 2; + *destPos = L'?'; + destPos++; + outleft--; + /* Reset */ + iconv( iconv_wide2ansi, &mynil, &my0, &mynil, &my0 ); + if ( err == ESysEINVAL ) + break; + } + break; + case ESysE2BIG: + { + outoffset = destPos - Dest.c_str(); + /* extend */ + Dest.resize( outlength + Len * 3 ); + outleft += Len * 3; + outlength += Len * 3; + /* String could have been moved */ + destPos = (char*) Dest.c_str() + outoffset; + } + break; + default: + RunError( 231 ); + } + } + // Truncate String + Dest.resize( Dest.length( ) - outleft ); +} + +void Wide2AnsiMove( const wchar_t* Source, std::string& Dest, int Len ) +{ + Wide2AnsiMove( (wchar_t*) Source, Dest, Len ); +} + +void Ansi2WideMove( char* Source, std::wstring& Dest, int Len ) +{ + size_t outlength = 0, outoffset = 0, outleft = 0; + char* SrcPos = NULL,* destPos = NULL; + char* mynil = NULL; + size_t my0 = 0; + cint err = 0; + mynil = NULL; + my0 = 0; + // extra space + outlength = Len + 1; + Dest.resize( outlength ); + SrcPos = Source; + destPos = (char*) Dest.c_str(); + outleft = outlength * 2; + while ( iconv( iconv_ansi2wide, &SrcPos, ((size_t*) &Len ), &destPos, &outleft ) == ((size_t) - 1 ) ) + { + err = fpgetCerrno(); + switch ( err ) + { + case ESysEINVAL: case ESysEILSEQ: + { + /* Skip and set to '?' */ + SrcPos++; + Len--; + *(wchar_t*) ( destPos ) = '?'; + destPos += 2; + outleft -= 2; + /* Reset */ + iconv( iconv_ansi2wide, &mynil, &my0, &mynil, &my0 ); + if ( err == ESysEINVAL ) + break; + } + break; + case ESysE2BIG: + { + outoffset = destPos - (char*) Dest.c_str(); + /* extend */ + Dest.resize( outlength + Len ); + outleft += Len * 2; + outlength += Len; + /* String could have been moved */ + destPos = (char*) Dest.c_str() + outoffset; + } + break; + default: + RunError( 231 ); + } + } + // Truncate String + Dest.resize( Dest.length( ) - outleft / 2 ); +} + +void Ansi2WideMove( const char* Source, std::wstring& Dest, int Len ) +{ + Ansi2WideMove( (char*) Source, Dest, Len ); +} + +/* converts an UTF-16 Code Point or surrogate pair to UTF-32 */ +UCS4Char utf16toutf32( const std::wstring& S, const int Index, int& Len ) +{ + UCS4Char result; + wchar_t W = L'\0'; + /* UTF-16 Points in the Range #$0-#$D7FF and #$E000-#$FFFF */ + /* are the same in UTF-32 */ + W = S[Index - 1]; + if ( ( W <= L'\xff' ) || ( W >= L'\x00' ) ) + { + result = ((UCS4Char) W ); + Len = 1; + } + /* valid surrogate pair? */ + else + if( ( W <= L'\xff' ) && ( (unsigned int) Index < S.length( ) ) && ( S[Index + 1 - 1] >= L'\x00' ) && ( S[Index + 1 - 1] <= L'\xff' ) ) + /* W>=#$D7FF Check not needed, Checked above */ + /* convert the surrogate pair to UTF-32 */ + { + result = ( ( ((UCS4Char) W ) - 0xD800 ) << 10 ) + ( ((UCS4Char) ( S[Index + 1 - 1] ) ) - 0xDC00 ) + 0x10000; + Len = 2; + } + else + /* Invalid surrogate -> do nothing */ + { + result = ((UCS4Char) W ); + Len = 1; + } + return result; +} + + +UCS4String WideStringToUCS4String( const std::wstring& S ) +{ + UCS4String result; + int i = 0, slen = 0, destindex = 0; + int Len = 0; + slen = S.length( ); + result.resize( slen + 1 ); + i = 1; + destindex = 0; + while ( i <= slen ) + { + result[destindex] = utf16toutf32( S, i, Len ); + destindex++; + i += Len; + } + /* destindex <= slen (surrogate pairs may have been merged) */ + /* destindex+1 for terminating #0 (dynamic arrays are */ + /* implicitely filled with zero) */ + result.resize( destindex + 1 ); + return result; +} + +/* Concatenates an UTF-32 char to A WideString. S *must* be unique when entering. */ + + +void ConcatUTF32ToWideStr( const UCS4Char NC, std::wstring& S, int& Index ) +{ + wchar_t* P = NULL; + /* if NC > $FFFF, we need two places */ + if ( Index + int( NC > 0xFFFF ) > (int) S.length( ) ) + { + if ( S.length( ) < 10 * 256 ) + S.resize( S.length( ) + 10 ); + else + S.resize( S.length( ) + ( S.length( ) >> 8 ) ); + } + /* we know that S is unique -> avoid UniqueString calls*/ + P = &S[Index - 1]; + if ( NC < 0xFFFF ) + { + *P = ((wchar_t) NC ); + Index++; + } + else + if ( ((DWORD) NC ) <= 0x10FFFF ) + { + *P = ((wchar_t) ( ( ( NC - 0x10000 ) >> 10 ) + 0xD800 ) ); + *( P + 1 ) = ((wchar_t) ( ( NC - 0x10000 ) & 0x3FF + 0xDC00 ) ); + Index += 2; + } + else + /* Invalid Code Point */ + { + *P = L'?'; + Index++; + } +} + + + +std::wstring UCS4StringToWideString( const UCS4String& S ) +{ + std::wstring result; + unsigned int i = 0; + int resindex = 0; + /* Skip terminating #0 */ + result.resize( S.size( ) - 1 ); + resindex = 1; + for ( i = 0; i <= S.size( ) - 1 - 1; i++) + ConcatUTF32ToWideStr( S[i], result, resindex ); + /* adjust result Length (may be Too big due to Growing */ + /* for surrogate pairs) */ + result.resize( resindex - 1 ); + return result; +} + + +UCS4String WideStringToUCS4StringNoNulls( const std::wstring& S ) +{ + UCS4String result; + int i = 0, slen = 0, destindex = 0; + int Len = 0; + UCS4Char uch; + slen = S.length( ); + result.resize( slen + 1 ); + i = 1; + destindex = 0; + while ( i <= slen ) + { + uch = utf16toutf32( S, i, Len ); + if ( uch == ((UCS4Char) 0 ) ) + uch = ((UCS4Char) 32 ); + result[destindex] = uch; + destindex++; + i += Len; + } + result[destindex] = ((UCS4Char) 0 ); + /* destindex <= slen */ + result.resize( destindex + 1 ); + return result; +} + + + +#else +#error unknown platform +#endif + +wchar_t* StringToWideChar( const std::string& Src, wchar_t* Dest, int DestSize ) +{ + std::wstring Temp; + Ansi2WideMove( Src.c_str(), Temp, Src.length( ) ); + if ( Temp.length( ) < (unsigned int) DestSize ) + Move( Temp, Dest, Temp.length( ) ); + else + Move( Temp, Dest, ( DestSize - 1 ) ); + Dest[DestSize - 1] = L'\x00'; + return Dest; +} + +std::string WideCharLenToString( wchar_t* S, int Len ) +{ + std::string result; + Wide2AnsiMove( S, result, Len ); + return result; +} + +std::string WideCharToString( wchar_t* S ) +{ + return WideCharLenToString( S, wcslen(S)); +} + +unsigned int indexword( const char* Buf, int Len, WORD B ) +{ + unsigned int result = 0; + WORD* pSrc = NULL, * pEnd = NULL; + pSrc = (WORD*) Buf; + /* Simulate assembler implementations behaviour, which is expected */ + /* fpc_PChar_To_AnsiStr in AStrings.inc */ + if ( ( Len < 0 ) || /* is this ever True? */ ( Len > numeric_limits< PtrInt >::max() ) || ( pSrc + Len < pSrc ) ) + pEnd = ((WORD*) ( numeric_limits< PtrUInt >::max() - sizeof( WORD ) ) ); + else + pEnd = pSrc + Len; + while ( pSrc < pEnd ) + { + if ( *pSrc == B ) + { + result = pSrc - ((WORD*) Buf ); + return result; + } + pSrc++; + } + result = - 1; + return result; +} + +//unsigned int indexword( const wchar_t* Buf, int Len, WORD B ) +unsigned int indexword( const wchar_t* Buf, int Len, wchar_t B ) +{ + unsigned int result = 0; + wchar_t* pSrc = NULL, *pEnd = NULL; + pSrc = (wchar_t*) Buf; + /* Simulate assembler implementations behaviour, which is expected */ + /* fpc_PChar_To_AnsiStr in AStrings.inc */ + if ( ( Len < 0 ) || /* is this ever True? */ ( Len > numeric_limits< PtrInt >::max() ) || ( pSrc + Len < pSrc ) ) + pEnd = ((wchar_t*) ( numeric_limits< PtrUInt >::max() - sizeof( wchar_t ) ) ); + else + pEnd = pSrc + Len; + while ( pSrc < pEnd ) + { + if ( *pSrc == B ) + { + result = pSrc - ((wchar_t*) Buf ); + return result; + } + pSrc++; + } + result = - 1; + return result; +} + +unsigned int UnicodeToUtf8( Char* Dest, unsigned int MaxDestBytes, const wchar_t* Source, unsigned int SourceChars ) +{ + unsigned int result = 0; + unsigned int i = 0, j = 0; + WORD W = 0; + result = 0; + if ( Source == NULL ) + return result; + i = 0; + j = 0; + if (( Dest != NULL ) ) + { + while ( ( i < SourceChars ) && ( j < MaxDestBytes ) ) + { + W = ((WORD) Source[i] ); + if( W >= 1 && W <= 127) + { + Dest[j] = ((char) W ); + j++; + } + else + if( W >= 0x80 && W <= 0x7FF) + { + if ( j + 1 >= MaxDestBytes ) + break; + Dest[j] = ((char) ( 0xC0 | ( W >> 6 ) ) ); + Dest[j + 1] = ((char) ( 0x80 | ( W & 0x3F ) ) ); + j += 2; + } + else + { + if ( j + 2 >= MaxDestBytes ) + break; + Dest[j] = ((char) ( 0xE0 | ( W >> 12 ) ) ); + Dest[j + 1] = ((char) ( 0x80 | ( ( W >> 6 ) & 0x3F ) ) ); + Dest[j + 2] = ((char) ( 0x80 | ( W & 0x3F ) ) ); + j += 3; + } + + i++; + } + if ( j > MaxDestBytes - 1 ) + j = MaxDestBytes - 1; + Dest[j] = L'\x00'; + } + else + { + while ( i < SourceChars ) + { + if( (WORD) Source[i] >= 1 && (WORD) Source[i] <= 127) + j++; + else + if( (WORD) Source[i] >= 0x80 && (WORD) Source[i] <= 0x7FF) + j += 2; + else + j += 3; + + i++; + } + } + result = j + 1; + return result; +} + + +int UnicodeToUtf8( Char* Dest, const wchar_t* Source, unsigned int MaxChars ) +{ + int result = 0; + if (( Source != NULL ) ) + result = UnicodeToUtf8( Dest, MaxChars, Source, indexword( Source, - 1, (WORD) 0 ) ); + else + result = 0; + return result; +} + +unsigned int Utf8ToUnicode( wchar_t* Dest, unsigned int MaxDestChars, const char* Source, unsigned int SourceBytes ) +{ + unsigned int i = 0, j = 0; + unsigned int W = 0; + unsigned char B = '\0'; + if (Source == NULL) + return 0; + i = 0; + j = 0; + if ( Dest != NULL ) + { + while ( ( j < MaxDestChars ) && ( i < SourceBytes ) ) + { + B = ((unsigned char) Source[i] ); + W = B; + i++; + // 2 or 3 Bytes? + if ( B >= 0x80 ) + { + W = B & 0x3F; + if ( i >= SourceBytes ) + return - 1; + // 3 Bytes? + if ( ( ( B & 0x20 ) ) != 0 ) + { + B = ((unsigned char) Source[i] ); + i++; + if ( i >= SourceBytes ) + return - 1; + if ( ( ( B & 0xC0 ) ) != 0x80 ) + return - 1; + W = ( W << 6 ) | ( B & 0x3F ); + } + B = ((unsigned char) Source[i] ); + W = ( W << 6 ) | ( B & 0x3F ); + if ( ( ( B & 0xC0 ) ) != 0x80 ) + return - 1; + i++; + } + Dest[j] = (wchar_t) W; + j++; + } + if ( j >= MaxDestChars ) + j = MaxDestChars - 1; + Dest[j] = L'\x00'; + } + else + { + while ( i < SourceBytes ) + { + B = ((unsigned char) Source[i] ); + i++; + // 2 or 3 Bytes? + if ( B >= 0x80 ) + { + if ( i >= SourceBytes ) + return - 1; + // 3 Bytes? + B = B & 0x3F; + if ( ( ( B & 0x20 ) ) != 0 ) + { + B = ((unsigned char) Source[i] ); + i++; + if ( i >= SourceBytes ) + return - 1; + if ( ( ( B & 0xC0 ) ) != 0x80 ) + return - 1; + } + if ( ( ( ((unsigned char) Source[i] ) & 0xC0 ) ) != 0x80 ) + return - 1; + i++; + } + j++; + } + } + return j + 1; +} + +int Utf8ToUnicode( wchar_t* Dest, const Char* Source, unsigned int MaxChars ) +{ + int result = 0; + if (( Source != NULL ) ) + result = Utf8ToUnicode( Dest, MaxChars, Source, StrLen( (Char*) Source ) ); + else + result = 0; + return result; +} + +UTF8String UTF8Encode( const std::wstring& S ) +{ + UTF8String result; + int i = 0; + UTF8String hs; + result = _T(""); + if ( S.empty()) + return result; + hs.resize( S.length( ) * 3 ); + i = UnicodeToUtf8( (Char*) hs.c_str(), hs.length( ) + 1, S.c_str(), S.length( ) ); + if ( i > 0 ) + { + hs.resize( i - 1 ); + result = hs; + } + return result; +} + +std::wstring UTF8Decode( const UTF8String S ) +{ + int i = 0; + wstring hs; + if ( S.empty()) + return wstring(); + hs.resize( S.length( ) ); + i = Utf8ToUnicode( (wchar_t*) hs.c_str(), (int) hs.length( ) + 1, S.c_str(), S.length( ) ); + if ( i > 0 ) + { + hs.resize( i - 1 ); + return hs; + } + return wstring(); +} + + +UTF8String AnsiToUtf8( const String& S ) +{ +#ifdef _WIDESTRING + return UTF8Encode( S ); +#else + return UTF8Encode( str2wstr(S) ); +#endif +} + + +String Utf8ToAnsi( const UTF8String S ) +{ +#ifdef _WIDESTRING + return UTF8Decode( S ); +#else + return wstr2str(UTF8Decode( S )); +#endif +} + + + +} // namespace System + + +std::string wstr2str(const std::wstring& xs) +{ + return std::string(xs.begin(), xs.end()); +} + +std::wstring str2wstr(const std::string& xs) +{ + return std::wstring(xs.begin(), xs.end()); +} + +char wchar2char(wchar_t xc) +{ + return (char) xc; +} + +wchar_t char2wchar(char xc) +{ + return (wchar_t) xc; +} + + +#ifdef linux + +void InitThread( ) +{ // unicode_encoding4, because under linux sizeof(wchar_t) == 4 + iconv_wide2ansi = iconv_open( nl_langinfo( CODESET ), unicode_encoding4 ); + iconv_ansi2wide = iconv_open( unicode_encoding4, nl_langinfo( CODESET ) ); +} + + +void FiniThread( ) +{ + if ( iconv_wide2ansi != ((iconv_t) - 1 ) ) + iconv_close( iconv_wide2ansi ); + if ( iconv_ansi2wide != ((iconv_t) - 1 ) ) + iconv_close( iconv_ansi2wide ); +} + +void SysString_initialization() +{ + setlocale( LC_ALL, "" ); + + /* Init conversion tables for main program */ + InitThread(); +} + +void SysString_finalization() +{ + FiniThread( ); +} + +class SysString_unit +{ +public: +SysString_unit() +{ + SysString_initialization(); +} +~SysString_unit(){ SysString_finalization(); } +}; +SysString_unit _SysString_unit; + +#endif + diff --git a/OpenDSSC/Support/d2c_sysstring.h b/OpenDSSC/Support/d2c_sysstring.h new file mode 100644 index 0000000..a90eeee --- /dev/null +++ b/OpenDSSC/Support/d2c_sysstring.h @@ -0,0 +1,127 @@ +#ifndef d2c_sysstring +#define d2c_sysstring + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_systypes.h" +#include + + + + +namespace System +{ + +char UpCase( char C ); +wchar_t UpCase( wchar_t C ); +int Pos(const std::string& Substr, const std::string& S); +int Pos(const char* Substr, const std::string& S); // else SmallString/strin ambigouity +int Pos(char Substr, const std::string& S); +int Pos( const std::wstring& Substr, const std::wstring& Source ); +int Pos( wchar_t C, const std::wstring& S ); + +std::string WideCharToString( wchar_t* S ); +wchar_t* StringToWideChar( const std::string& Src, wchar_t* Dest, int DestSize ); +std::string WideCharLenToString( wchar_t* S, int Len ); +void WideCharLenToStrVar( wchar_t* Src, int Len, std::string& Dest ); +void WideCharToStrVar( wchar_t* S, std::string& Dest ); +int UnicodeToUtf8( Char* Dest, const wchar_t* Source, unsigned int MaxBytes ); +unsigned int UnicodeToUtf8( Char* Dest, unsigned int MaxDestByte, const wchar_t* Source, unsigned int SourceChars ); +int Utf8ToUnicode( wchar_t* Dest, const Char* Source, unsigned int MaxChars ); +//unsigned int Utf8ToUnicode( wchar_t* Dest, int MaxDestChars, const Char* Source, unsigned int SourceBytes ); +UTF8String UTF8Encode( const std::wstring& S ); +std::wstring UTF8Decode( const UTF8String S ); +UTF8String AnsiToUtf8( const String& S ); +String Utf8ToAnsi( const UTF8String S ); +UCS4String WideStringToUCS4String( const std::wstring& S ); +std::wstring UCS4StringToWideString( const UCS4String& S ); + +/* +// from here on not contained in Delphi2Cpp trial + +Copy +Chr +LowerCase +Insert +Delete +StringOfChar +SetString +Concat +*/ + +} // namespace d2c_string + +std::string wstr2str(const std::wstring& xs); +std::wstring str2wstr(const std::string& xs); +char wchar2char(wchar_t xc); +wchar_t char2wchar(char xc); + + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/d2c_system.cpp b/OpenDSSC/Support/d2c_system.cpp new file mode 100644 index 0000000..033d6f7 --- /dev/null +++ b/OpenDSSC/Support/d2c_system.cpp @@ -0,0 +1,942 @@ +//#include "stdafx.h" + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_system.h" +#include "d2c_syscurr.h" + +#include +#include +#include +#include +#include +#include + +#if !defined(windows) +#include +#include "windows2posix.h" +#endif + +#if defined(windows) && defined (_WIDESTRING) +#include // CommandLineToArgvW +#endif +#if defined(windows) +#ifdef _MSC_VER +#include +#endif +#endif +#include + +using namespace std; + + + +// #define _CRT_NON_CONFORMING_SWPRINTFS 1 + + + + + +namespace System +{ + +int Argc = 0; +PPChar Argv = NULL; +Char* CmdLine = NULL; +int CmdShow = 0; +bool IsLibrary = false; +bool IsConsole = false; +int HPrevInst = 0, MainInstance = 0; + + + + +void FillChar( void* X, int Count, unsignedchar Value ) +{ + memset(X, Value, Count); +} + +void FillChar( char* X, int Count, unsignedchar Value ) +{ + memset(X, Value, Count); +} + +void FillChar( wchar_t* X, int Count, unsignedchar Value ) +{ + wchar_t* p = X; + if(Count <= 0) + return; + while(Count--) + *p++ = (wchar_t) Value; +} + +void FillChar( string& X, int Count, unsignedchar Value ) +{ + if(Count <= 0) + return; + string::iterator t = X.begin(); + while(Count--) + *t++ = Value; +} + +void FillChar( wstring& X, int Count, unsignedchar Value ) +{ + if(Count <= 0) + return; + wstring::iterator t = X.begin(); + while(Count--) + *t++ = (wchar_t) Value; +} + +void Str(long double xd, string& xs) +{ + ostringstream oss; + oss << scientific << uppercase << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(double xd, string& xs) +{ + ostringstream oss; + oss << scientific << uppercase << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(int xi, int xiMinWidth, string& xs) +{ + ostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xi; + xs = oss.str(); +} + +void Str(double xd, int xiMinWidth, string& xs) +{ + ostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(long double xd, int xiMinWidth, string& xs) +{ + ostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(double xd, int xiMinWidth, int xiDecPlaces, string& xs) +{ + ostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << xd; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << xd; + } + else + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(xiDecPlaces) << xd; + xs = oss.str(); +} + +void Str(long double xd, int xiMinWidth, int xiDecPlaces, string& xs) +{ + ostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << xd; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << xd; + } + else + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(xiDecPlaces) << xd; + xs = oss.str(); +} + +void Str(const Currency& xcr, int xiMinWidth, int xiDecPlaces, string& xs) +{ + ostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << (double) xcr; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << (double) xcr; + } + else + oss << setw(xiMinWidth) << setprecision(xiDecPlaces) << (double) xcr; + xs = oss.str(); +} + + +void Str(long double xd, wstring& xs) +{ + wostringstream oss; + oss << scientific << uppercase << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(double xd, wstring& xs) +{ + wostringstream oss; + oss << scientific << uppercase << setprecision(14) << xd; + xs = oss.str(); +} + + +void Str(double xd, int xiMinWidth, wstring& xs) +{ + wostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(int xi, int xiMinWidth, wstring& xs) +{ + wostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xi; + xs = oss.str(); +} + + +void Str(long double xd, int xiMinWidth, wstring& xs) +{ + wostringstream oss; + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(14) << xd; + xs = oss.str(); +} + +void Str(double xd, int xiMinWidth, int xiDecPlaces, wstring& xs) +{ + wostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << xd; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << xd; + } + else + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(xiDecPlaces) << xd; + xs = oss.str(); +} + +void Str(long double xd, int xiMinWidth, int xiDecPlaces, wstring& xs) +{ + wostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << xd; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << xd; + } + else + oss << scientific << uppercase << setw(xiMinWidth) << setprecision(xiDecPlaces) << xd; + xs = oss.str(); +} + +void Str(const Currency& xcr, int xiMinWidth, int xiDecPlaces, wstring& xs) +{ + wostringstream oss; + if(xiMinWidth == 0) + { + if(xiDecPlaces == 0) + oss << fixed << setprecision(xiDecPlaces) << (double) xcr; + else + oss << fixed << showpoint << setprecision(xiDecPlaces) << (double) xcr; + } + else + oss << setw(xiMinWidth) << setprecision(xiDecPlaces) << (double) xcr; + xs = oss.str(); +} + +void Move(void* Source, void* Dest, int Count) +{ + memmove(Dest, Source, Count); +} + +void Move(const string& Source, string& Dest, unsigned int Count) +{ + if(Count == Source.length()) + Dest = Source; + else + Dest = Source.substr(0, Count); +} + +void Move(const wstring& Source, wstring& Dest, unsigned int Count) +{ + if(Count == Source.length()) + Dest = Source; + else + Dest = Source.substr(0, Count); +} + +void Move(const char* Source, string& Dest, unsigned int Count) +{ + if(Count == strlen(Source)) + Dest = Source; + else + Dest = string(Source, Source + Count); +} + +void Move(const wchar_t* Source, wstring& Dest, unsigned int Count) +{ + if(Count == wcslen(Source)) + Dest = Source; + else + Dest = wstring(Source, Source + Count); +} + +void Move(const std::string& Source, char* Dest, unsigned int Count) +{ + strncpy(Dest, Source.c_str(), Count); +} + +void Move(const std::wstring& Source, wchar_t* Dest, unsigned int Count) +{ + wcsncpy(Dest, Source.c_str(), Count); +} + + + +//////// + +WORD Swap( WORD X ) +{ + return ((WORD) ( ( X >> 8 ) | ( X << 8 ) ) ); +} + +int Swap( int X ) +{ + return ( ( X & 0xFFFF ) << 16 ) + ( X >> 16 ); +} + +unsignedint Swap( unsignedint X ) +{ + return ( ( X & 0xFFFF ) << 16 ) + ( X >> 16 ); +} + +int64_t Swap( int64_t X ) +{ + return ( ( X & 0xFFFFFFFF ) << 32 ) + ( X >> 32 ); +} + +//////// + +void Assert( bool expr ) +{ + if(!expr) + throw runtime_error("assertion failed"); +} + +void Assert( bool expr, const string& Msg ) +{ + if(!expr) + throw runtime_error(Msg.c_str()); +} + + +// -> not contained in Delphi2Cpp trial + + +//#ifdef WIN64 +Char ModuleName[ 256/*# range 0..255*/ ]; + + +Char* GetCommandFile( ) +{ + Char* result = NULL; + GetModuleFileName( 0, ModuleName, 255 ); + return ModuleName; +} +//#endif + +void allocarg( int idx, int Len, int& argvlen ) +{ + int oldargvlen = 0; + if ( idx >= argvlen ) + { + oldargvlen = argvlen; + argvlen = ( idx + 8 ) & ( ~ 7 ); + ReallocMem( Argv, argvlen * sizeof( void* ) ); + FillChar( &Argv[oldargvlen], ( argvlen - oldargvlen ) * sizeof( void* ), 0 ); + } + /* use Realloc to reuse Already Existing memory */ + /* always allocate, even if Length is zero, since */ + /* the arg. is still present! */ + ReallocMem( Argv[idx], Len + 1 ); +} + +#define System__39 ( TSet < wchar_t, 0, 255 >() \ + << wchar_t ( 1 ) << wchar_t ( 2 ) << wchar_t ( 3 ) << wchar_t ( 4 ) << wchar_t ( 5 ) << wchar_t ( 6 ) << wchar_t ( 7 ) << wchar_t ( 8 ) << wchar_t ( L'\t' ) << wchar_t ( L'\n' ) \ + << wchar_t ( 11 ) << wchar_t ( 12 ) << wchar_t ( L'\r' ) << wchar_t ( 14 ) << wchar_t ( 15 ) << wchar_t ( 16 ) << wchar_t ( 17 ) << wchar_t ( 18 ) << wchar_t ( 19 ) << wchar_t ( 20 ) \ + << wchar_t ( 21 ) << wchar_t ( 22 ) << wchar_t ( 23 ) << wchar_t ( 24 ) << wchar_t ( 25 ) << wchar_t ( 26 ) << wchar_t ( 27 ) << wchar_t ( 28 ) << wchar_t ( 29 ) << wchar_t ( 30 ) \ + << wchar_t ( 31 ) << wchar_t ( L' ' ) ) + +#ifdef windows +#ifdef WIN64 +void setup_arguments( ) +{ + int arglen = 0, Count = 0; + char* argstart = NULL,* pc = NULL,* arg = NULL; + char Quote = L'\0'; + int argvlen = 0; + //SetupProcVars(); + /* Create commandLine, it starts with the executed Filename which is Argv[0] */ + /* Win32 passes the command not via the Args, but via GetModuleFileName*/ + Count = 0; + Argv = NULL; + argvlen = 0; + pc = GetCommandFile(); + arglen = 0; + do + { + arglen++; + } + while ( ! ( pc[arglen] == L'\x00' ) ); + allocarg( 0, arglen, argvlen ); + Move( (void*) pc, Argv[Count], arglen + 1 ); + /* setup CmdLine variable */ + CmdLine = GetCommandLine(); + /* process Arguments */ + pc = CmdLine; + while ( *pc != L'\x00' ) + { + /* Skip leading spaces */ + while ( System__39.Contains(*pc ) ) + pc++; + if ( *pc == L'\x00' ) + break; + /* Calc argument Length */ + Quote = L' '; + argstart = pc; + arglen = 0; + bool bContinue = true; + while ( bContinue && *pc != L'\x00' ) + { + switch ( *pc ) + { + case /*# L'\x01' .. L'\x20' */ 1 : + case 2: case 3: case 4: case 5: case 6: case 7: case 8: case L'\t': case L'\n': case 11 : + case 12: case L'\r': case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21 : + case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31 : + case L' ': + { + if ( Quote != L' ' ) + arglen++; + else + bContinue = false; + } + break; + case L'\"': + { + if ( Quote != L'\'' ) + { + if ( *(wchar_t*) ( pc + 1 ) != L'\"' ) + { + if ( Quote == L'\"' ) + Quote = L' '; + else + Quote = L'\"'; + } + else + pc++; + } + else + arglen++; + } + break; + case L'\'': + { + if ( Quote != L'\"' ) + { + if ( *(wchar_t*) ( pc + 1 ) != L'\'' ) + { + if ( Quote == L'\'' ) + Quote = L' '; + else + Quote = L'\''; + } + else + pc++; + } + else + arglen++; + } + break; + default: + arglen++; + } + pc++; + } + /* copy argument */ + /* don'T copy the First one, it is Already there.*/ + if ( Count != 0 ) + { + allocarg( Count, arglen, argvlen ); + Quote = L' '; + pc = argstart; + arg = Argv[Count]; + bContinue = true; + while ( bContinue && *pc != L'\x00' ) + { + switch ( *pc ) + { + case /*# L'\x01' .. L'\x20' */ 1 : + case 2: case 3: case 4: case 5: case 6: case 7: case 8: case L'\t': case L'\n': case 11 : + case 12: case L'\r': case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21 : + case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31 : + case L' ': + { + if ( Quote != L' ' ) + { + *arg = *pc; + arg++; + } + else + bContinue = false; + } + break; + case L'\"': + { + if ( Quote != L'\'' ) + { + if ( *(wchar_t*) ( pc + 1 ) != L'\"' ) + { + if ( Quote == L'\"' ) + Quote = L' '; + else + Quote = L'\"'; + } + else + pc++; + } + else + { + *arg = *pc; + arg++; + } + } + break; + case L'\'': + { + if ( Quote != L'\"' ) + { + if ( *(wchar_t*) ( pc + 1 ) != L'\'' ) + { + if ( Quote == L'\'' ) + Quote = L' '; + else + Quote = L'\''; + } + else + pc++; + } + else + { + *arg = *pc; + arg++; + } + } + break; + default: + { + *arg = *pc; + arg++; + } + } + pc++; + } + *arg = L'\x00'; + } + Count++; + } + /* get Argc and Create an nil entry */ + Argc = Count; + allocarg( Argc, arglen, argvlen ); + /* Free Unused memory */ + ReallocMem( Argv, ( Argc + 1 ) * sizeof( void* ) ); +} +#else +#ifndef _WIDESTRING +void setup_arguments( ) +{ + int arglen = 0, Count = 0; + Char* argstart = NULL,* pc = NULL,* arg = NULL; + bool Quote = false; + int argvlen = 0; + Char Buf[ 260 ]; // need MAX_PATH Bytes, not 256! +// SetupProcVars(); + // Create commandLine, it starts with the executed Filename which is Argv[0] + // Win32 passes the command not via the Args, but via GetModuleFileName + Count = 0; + Argv = NULL; + argvlen = 0; + arglen = GetModuleFileName( 0, &Buf[0], sizeof( Buf ) ); + Buf[arglen] = L'\x00'; // be safe + allocarg( 0, arglen, argvlen ); + Move( (void*) Buf, Argv[0], arglen + 1 ); + // setup CmdLine variable + CmdLine = GetCommandLine(); + // process Arguments + pc = CmdLine; + while ( *pc != L'\x00' ) + { + // Skip leading spaces + while ( System__39.Contains(*pc ) ) + pc++; + if ( *pc == L'\x00' ) + break; + // Calc argument Length + Quote = false; + argstart = pc; + arglen = 0; + bool bContinue = true; + while ( bContinue && *pc != L'\x00' ) + { + switch ( *pc ) + { + case 1 : + case 2: case 3: case 4: case 5: case 6: case 7: case 8: case L'\t': case L'\n': case 11 : + case 12: case L'\r': case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21 : + case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31 : + case L' ': + { + if ( Quote ) + arglen++; + else + bContinue = false; + //break; + } + break; + case L'\"': + if ( pc[1] != L'\"' ) + Quote = ! Quote; + else + pc++; + break; + default: + arglen++; + } + pc++; + } + // copy argument + // don'T copy the First one, it is Already there. + if ( Count != 0 ) + { + allocarg( Count, arglen, argvlen ); + Quote = false; + pc = argstart; + arg = Argv[Count]; + bContinue = true; + while ( bContinue && *pc != L'\x00' ) + { + switch ( *pc ) + { + case 1 : + case 2: case 3: case 4: case 5: case 6: case 7: case 8: case L'\t': case L'\n': case 11 : + case 12: case L'\r': case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21 : + case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31 : + case L' ': + { + if ( Quote ) + { + *arg = *pc; + arg++; + } + else + bContinue = false; + //break; + } + break; + case L'\"': + if ( pc[1] != L'\"' ) + Quote = ! Quote; + else + pc++; + break; + default: + { + *arg = *pc; + arg++; + } + } + pc++; + } + *arg = L'\x00'; + } + Count++; + } + // get Argc + Argc = Count; + // Free Unused memory, leaving A nil entry at the end + ReallocMem( Argv, ( Count + 1 ) * sizeof( void* ) ); + Argv[Count] = NULL; +} +#else +// win32 / wchar_t +void setup_arguments( ) +{ +} +#endif // WIDESTRING + +#endif // WIN32 + + + +int ParamCount( ) +{ + //if(Argc == 0) + // setup_arguments(); + //Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); + return Argc - 1; +} + +String ParamStr( int l ) +{ + //if(Argc == 0) + // setup_arguments(); + //Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); + String result; + if ( ( l >= 0 ) && ( l < Argc ) ) + result = Argv[l]; + else + result = _T(""); + return result; +} + +// looks up Module in list of all loaded modules +HMODULE FindResourceHInstance(unsigned int Module) +{ // not in free pascal and proprietary copyright in Borland sources + if(Module == NULL) + return ::GetModuleHandle(NULL); + else + return (HMODULE) Module; +} + +class ResourceString +{ +public: + unsigned int* module; + int identifier; +}; + +String LoadResourceString(const ResourceString* const rsrc) +{ + if ( rsrc == NULL ) + return String(); + + // Resource strings are identified by a 16 bit unsigned integer and in Win32, the first 64KB of address space is permanently invalid + if( rsrc->identifier < 64 * 1024 ) + { + String s; + wchar_t* buf; + HINSTANCE h; + if(rsrc->module == NULL) + h = ::GetModuleHandle(NULL); + else + h = FindResourceHInstance(*rsrc->module); + String::size_type len = ::LoadStringW(h, rsrc->identifier, (wchar_t*) &buf, 0); + if (len > 0) +#ifdef _WIDESTRING + s.assign(buf, len); +#else + { + len *= sizeof(wchar_t) + 1; + s.resize(len); // make room for trailing '\0' in worst case + len = ::LoadStringA(h, rsrc->identifier, (char*) s.c_str(), len); + s.resize(len); + } +#endif + return s; + } + else + return (Char*) ( rsrc->identifier ); +} + +String d2c_LoadResourceString(int Ident) +{ + ResourceString ResString; + HMODULE h = ::GetModuleHandle(NULL); + ResString.module = (unsigned int*) &h; + ResString.identifier = (int) Ident; + return LoadResourceString( &ResString ); +} + + +#elif defined(linux) + +int ParamCount( ) +{ + int result = 0; + result = Argc - 1; + return result; +} + +SmallString<255> execpathstr; + +String ParamStr( int l ) +{ + /* stricly conforming Posix Applications */ + /* have the executing Filename as Argv[0] */ + if ( l == 0 ) + return execpathstr; + else + if ( l < Argc ) + return Argv[l]; + else + return String(); +} + +cint FpReadLink( const char* Name, char* LinkName, size_t MaxLen ) +{ + cint r = readlink(Name, LinkName, MaxLen); + return r==-1 ? -errno : r; +} + +void SysInitExecPath( ) +{ + int i = 0; + execpathstr[0] = '\x00'; + i = FpReadLink( "/proc/self/exe", &execpathstr[1], 255 /*# High(execpathstr) */ ); + /* it must also be an ABSOLUTE Filename, LINUX 2.0 Points to A memory + location So this will Skip that */ + if ( ( i > 0 ) && ( execpathstr[1] == '/' ) ) + execpathstr[0] = ((Char) i ); +} + +#else +#error unknown platform +#endif + + +void System_initialization() +{ +#ifdef _USRDLL // todo use SHGFI_EXETYPE ? + IsLibrary = true; +#endif + +#ifdef _CONSOLE + IsConsole = true; +#endif + +#ifdef windows + STARTUPINFO SI; + GetStartupInfo( &SI ); + /* some Misc Win32 stuff */ + HPrevInst = 0; + /* + if ( ! IsLibrary ) + SysInstance = GetModuleHandle( NULL ); + MainInstance = HInstance(); + */ + + if(!IsLibrary) + CmdShow = SI.wShowWindow; + +#ifdef _WIDESTRING + CmdLine = GetCommandLine(); + Argv = CommandLineToArgvW(GetCommandLineW(), &Argc); +#else + setup_arguments( ); +#endif + +#elif defined(linux) + SysInitExecPath( ); +#else + #error system not defined +#endif + +} + +void System_finalization() +{ +#ifdef _CONSOLE +#ifdef windows + if(Argv != NULL) + GlobalFree(Argv); +#endif +#endif +} + +class System_unit +{ +public: +System_unit() +{ + System_initialization(); +} +~System_unit(){ System_finalization(); } +}; +System_unit _System_unit; + + +} // namespace System diff --git a/OpenDSSC/Support/d2c_system.h b/OpenDSSC/Support/d2c_system.h new file mode 100644 index 0000000..ba1785f --- /dev/null +++ b/OpenDSSC/Support/d2c_system.h @@ -0,0 +1,257 @@ +#ifndef d2c_systemH +#define d2c_systemH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + +#include "d2c_systypes.h" +#include +#include + + +#define MAXIDX(x) (sizeof(x)/sizeof(x[0]))-1 + +class Currency; + + +namespace System +{ +extern int Argc; +extern PPChar Argv; +extern Char* CmdLine; +extern int CmdShow; +extern bool IsLibrary; +extern bool IsConsole; + +template +void GetMem(T*& P, int Size) +{ + P = ( T* ) malloc(Size); +} + +template +void FreeMem(T*& P, int Size = -1) +{ + free(P); +} + +template +void ReallocMem(T*& P, int Size) +{ + if(P != NULL) + { + if(Size > 0) + P = ( T* ) realloc ( P, Size ); + else + if(Size == 0) + { + free(P); + P = NULL; + } + } + else + { + if(Size > 0) + P = ( T* ) malloc(Size); + } +} + +template +T Pred(const T& xT) +{ + int t = (int) xT; // typecast to "int" allows incrementation of enumerated values + return (T) --t; +} + +template +T Succ(const T& xT) +{ + int t = (int) xT; // typecast to "int" allows incrementation of enumerated values + return (T) ++t; +} + +template +T Abs(const T xT) +{ + return xT < 0 ? -xT : xT; +} + + +void FillChar( void* X, int Count, unsignedchar Value ); +void FillChar( char* X, int Count, unsignedchar Value ); +void FillChar( wchar_t* X, int Count, unsignedchar Value ); +void FillChar( std::string& X, int Count, unsignedchar Value ); +void FillChar( std::wstring& X, int Count, unsignedchar Value ); + +template +void Val(const std::string& S, T* V, int& Code) +{ + std::istringstream iss(S); + iss >> *V; + Code = 0; +} + +template +void Val(const std::wstring& S, T* V, int& Code) +{ + std::wistringstream iss(S); + iss >> *V; + Code = 0; +} + + +template +void Str(T xT, std::string& xs) +{ + std::ostringstream oss; + oss << xT; + xs = oss.str(); +} + +template +void Str(T xT, std::wstring& xs) +{ + std::wostringstream oss; + oss << xT; + xs = oss.str(); +} + +void Str(double xd, std::string& xs); +void Str(long double xd, std::string& xs); +void Str(int xd, int xiMinWidth, std::string& xs); +void Str(double xd, int xiMinWidth, std::string& xs); +void Str(long double xd, int xiMinWidth, std::string& xs); +void Str(long double xd, int xiMinWidth, std::string& xs); +void Str(double xd, int xiMinWidth, int xiDecPlaces, std::string& xs); +void Str(long double xd, int xiMinWidth, int xiDecPlaces, std::string& xs); +void Str(const Currency& xcr, int xiMinWidth, int xiDecPlaces, std::string& xs); + +void Str(double xd, std::wstring& xs); +void Str(long double xd, std::wstring& xs); +void Str(int xd, int xiMinWidth, std::wstring& xs); +void Str(double xd, int xiMinWidth, std::wstring& xs); +void Str(long double xd, int xiMinWidth, std::wstring& xs); +void Str(double xd, int xiMinWidth, int xiDecPlaces, std::wstring& xs); +void Str(long double xd, int xiMinWidth, int xiDecPlaces, std::wstring& xs); +void Str(const Currency& xcr, int xiMinWidth, int xiDecPlaces, std::wstring& xs); + +void Move(void* Source, void* Dest, int Count); +void Move(const std::string& Source, std::string& Dest, unsigned int Count); +void Move(const std::wstring& Source, std::wstring& Dest, unsigned int Count); +void Move(const char* Source, std::string& Dest, unsigned int Count); +void Move(const wchar_t* Source, std::wstring& Dest, unsigned int Count); +void Move(const std::string& Source, char* Dest, unsigned int Count); +void Move(const std::wstring& Source, wchar_t* Dest, unsigned int Count); + + + +String ParamStr( int Index ); +int ParamCount( ); + + +WORD Swap( WORD X ); +int Swap( int X ); +unsignedint Swap( unsignedint X ); +int64_t Swap( int64_t X ); + + +void Assert( bool expr ); +void Assert( bool expr, const String& Msg ); + + +/* +// from here on not contained in Delphi2Cpp trial +ObjectIs +Hi +Lo +Odd +Sqt +Dec +Inc +Assert +Assigned +Ptr +Add +High +Low + +void* AllocMem( unsignedint Size ); +void GetMem( void*& P, int Size ); +void FreeMem( void*& P, int Size = - 1 ); +void ReallocMem( void*& P, int Size ); + +// maximum Value of the biggest signed and unsigned Integer type available +MaxSIntValue +MaxUIntValue + +*/ + +} // namespace System + + +#endif // lpl_systemH diff --git a/OpenDSSC/Support/d2c_systobj.h b/OpenDSSC/Support/d2c_systobj.h new file mode 100644 index 0000000..91b9a51 --- /dev/null +++ b/OpenDSSC/Support/d2c_systobj.h @@ -0,0 +1,23 @@ +#ifndef d2c_systobjH +#define d2c_systobjH + + + + +namespace System { + + +class TObject +{ + +public: + TObject() {} +// Free(); -> use delete + virtual ~TObject(){} +}; + + +} //namespace System + + +#endif diff --git a/OpenDSSC/Support/d2c_systypes.h b/OpenDSSC/Support/d2c_systypes.h new file mode 100644 index 0000000..1e14be7 --- /dev/null +++ b/OpenDSSC/Support/d2c_systypes.h @@ -0,0 +1,275 @@ +#ifndef d2c_systypesH +#define d2c_systypesH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysexcept.h d2c_sysexcept.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + Windows.pas + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#if defined( WIN32 ) || defined( WIN64 ) +#define NOMINMAX +#include "windows.h" +#define windows 1 + +#elif defined(linux) + +#include +#include +#include +#include +//#define _WIDESTRING 1 + +#endif + +#include + +#include +#include +#include +#include "d2c_smallstring.h" +#include "DelphiSets.h" + + +#ifdef _UNICODE // Visual C** +#define _WIDESTRING 1 +#endif + +#ifdef _MSC_VER +typedef ptrdiff_t ssize_t; +#endif + +// definitions in one word are needed with C++Builder for properties +typedef short int shortint; +typedef unsigned char unsignedchar; +typedef unsigned int unsignedint; +typedef unsigned short unsignedshort; + +#ifdef _WIDESTRING + #define __T(x) L ## x + typedef std::wstring String; + typedef wchar_t Char; + typedef wchar_t UChar; +#else + #define __T(x) x + typedef std::string String; + typedef char Char; + typedef unsigned char UChar; +#endif + +#define _T(x) __T(x) + + +namespace System +{ + +typedef std::string AnsiString; +typedef std::wstring WideString; +typedef SmallString<255> ShortString; +typedef std::string *PAnsiString; +typedef std::wstring *PWideString; +typedef String *PString; + +typedef long double ValReal; +typedef unsigned int Cardinal; +typedef short int Integer; + + +typedef uint64_t QWord; + + +typedef void ( * TProcedure )( ); + + + +#ifdef windows +typedef HANDLE THandle; +typedef THandle TThreadID; +#else + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; +typedef int BOOL; + +typedef unsigned char cuint8; +typedef cuint8 cuchar; +typedef WORD cuint16; +typedef cuint16 cushort; +typedef int32_t cint32; +typedef cint32 cint; + +#define __cdecl +#define __stdcall +#define __fastcall +typedef long HRESULT; + +#endif + + +// Updated below to use standard int types +// (original version was bonkers on 64-bit systems) +typedef double real; +typedef ssize_t SizeInt; +typedef size_t SizeUInt; +typedef intptr_t PtrInt; +typedef uintptr_t PtrUInt; +typedef int ValSInt; +typedef unsigned int ValUInt; + + +/* zero - terminated Strings */ +typedef Char* PChar; +typedef Char** PPChar; + + /* AnsiChar is equivalent of char, So we need + to use type renamings */ +typedef Char TAnsiChar; +typedef Char AnsiChar; +typedef Char* PAnsiChar; +typedef PPChar PPAnsiChar; +typedef unsigned int UCS4Char; +typedef UCS4Char* PUCS4Char; +typedef UCS4Char TUCS4CharArray [ 251658240/*# range 0..0xeffffff*/ ]; +typedef UCS4Char* PUCS4CharArray; +typedef std::vector< UCS4Char > UCS4String; +typedef String UTF8String; +typedef UTF8String* PUTF8String; + + //HRESULT = type Longint; + //TDateTime = type Double; + +typedef int TError; +typedef float* PSingle; +typedef double* PDouble; +typedef long double* PExtended; +typedef shortint* PSmallInt; +typedef shortint* PShortInt; +typedef int* PInteger; +typedef unsignedchar* PByte; +typedef unsignedint* PLongWord; +typedef int* PLongint; +typedef unsignedint* PCardinal; +typedef QWord* PQWord; +typedef int64_t* PInt64; +typedef PtrInt* PPtrInt; +typedef PtrUInt* PPtrUInt; +typedef SizeInt* psizeint; +typedef void** PPointer; +typedef PPointer* PPPointer; +typedef bool* PBoolean; +typedef unsignedshort* PWordBool; +typedef BOOL* PLongBool; +typedef SmallString<255>* PShortString; +typedef std::string* PAnsiString; +typedef wchar_t* PWideChar; +typedef wchar_t** PPWideChar; +typedef wchar_t UCS2Char; +typedef wchar_t* PUCS2Char; + + +const int MaxLongint = 0x7FFFFFFF; +#ifndef __BORLANDC__ +#ifdef linux +const int MAXINT = std::numeric_limits::max(); +const int MaxInt = MAXINT; +#else +const int MaxInt = INT_MAX; +#endif +#endif + + + + +typedef int IntegerArray [ 251658240/*# range 0..0xeffffff*/ ]; +typedef int* PIntegerArray; +typedef void* PointerArray [ 0x7fffff/*# range 0..512*1024*1024-2*/ ]; +typedef void** PPointerArray; +typedef std::vector< SizeInt > TBoundArray; + +#pragma pack(push, 1) +typedef Char* TPCharArray [ ( MaxLongint / sizeof( Char* ) ) - 1 - 0 + 1 ]; +#pragma pack(pop) + + +typedef Char** PPCharArray; + +typedef uintptr_t NativeUInt; + +#ifdef linux + +typedef uintptr_t THandle; +typedef uintptr_t TLibHandle; +typedef TLibHandle HMODULE; + +#endif + +} // namespace System + + +using namespace System; + +#endif // d2c_systypesH diff --git a/OpenDSSC/Support/d2c_varrec.h b/OpenDSSC/Support/d2c_varrec.h new file mode 100644 index 0000000..13c9e2a --- /dev/null +++ b/OpenDSSC/Support/d2c_varrec.h @@ -0,0 +1,315 @@ +#ifndef d2c_varrecH +#define d2c_varrecH + +/* + Copyright of the basic file version + ----------------------------------- + + Explanation: in the following license "library" means + the following files: + + System.pas / d2c_system.pas + System.h + d2c_sysconst.h + d2c_syscurr.h d2c_syscurr.cpp + d2c_sysdate.h d2c_sysdate.cpp + d2c_sysfile.h, d2c_sysfile.cpp + d2c_sysmath.h d2c_sysmath.cpp + d2c_sysstring.h d2c_sysstring.cpp + d2c_systypes.h + d2c_varrec.h + d2c_smallstring.h + + Sysutils.pas + Sysutils.h Sysutils.cpp + + AS THEY ARE CONTAINED IN THE FREE TRIAL VERSION OF Delphi2Cpp. + + This library is derived from the FreePascal library: + + http://www.freepascal.org/ + + FreePascal is published under the terms of GNU Lesser General + Public License and the same terms apply to this library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with d2c_sysfile.h/cpp; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + + Copyright of the extended file version + -------------------------------------- + + + The terms of the license above don't apply to extended versions + of these files, which are distributed with commercial versions of + Delphi2Cpp. Individual licenses are applied to them. + The library doesn't depend on the commercial extensions and the + the commercial extensions only originates from the author + Dr. Detlef Meyer-Eltz or might use code which has no copyright restrictions + + Copyright (C) <2011> + + The extended version of this file is authorized for unlimited use in any + Delphi2Cpp project. + + http://www.texttransformer.com/Delphi2Cpp_en.html + +*/ + + +#include "d2c_systypes.h" +#include "d2c_sysdate.h" +#include "d2c_syscurr.h" +#include + + +namespace System { + class TObject; + class TMetaClass; + typedef const TMetaClass* TClass; +} + +class Variant; +typedef Variant* PVariant; +typedef uint64_t* puint64_t; + + +const int vtInteger = 0; +const int vtBoolean = 1; +const int vtChar = 2; +const int vtExtended = 3; +const int vtString = 4; +const int vtPointer = 5; +const int vtPChar = 6; +const int vtObject = 7; +const int vtClass = 8; +const int vtWideChar = 9; +const int vtPWideChar = 10; +const int vtAnsiString = 11; +const int vtCurrency = 12; +const int vtVariant = 13; +const int vtInterface = 14; +const int vtWideString = 15; +const int vtInt64 = 16; +const int vtUInt64 = 17; + + + +struct TVarRec { + uint64_t VType; + union + { + +#if defined(ENDIAN_BIG) && defined(CPU64) + int32_t IntegerDummy; +#endif + int VInteger; +#if defined(ENDIAN_BIG) && defined(CPU64) + int32_t BoolDummy; +#endif + bool VBoolean; +#if defined(ENDIAN_BIG) && defined(CPU64) + int32_t CharDummy; +#endif + char VChar; +#if defined(ENDIAN_BIG) && defined(CPU64) + int32_t WCharDummy; +#endif + wchar_t VWideChar; + PExtended VExtended; + PShortString VString; + void* VPointer; + char* VPChar; + System::TObject* VObject; + System::TClass VClass; + wchar_t* VPWideChar; + void* VAnsiString; + PCurrency VCurrency; + PVariant VVariant; + void* VInterface; + void* VWideString; + PInt64 VInt64; + puint64_t VUInt64; + }; //union + + TVarRec(): VType(vtInteger), VInteger(0) {} + TVarRec(int src): VType(vtInteger), VInteger(src) {} + TVarRec(unsigned int src): VType(vtInteger), VInteger(static_cast(src)) {} + TVarRec(bool src): VType(vtBoolean), VBoolean(src) {} + TVarRec(char src): VType(vtChar), VChar(src) {} + TVarRec(wchar_t src): VType(vtWideChar), VWideChar(src) {} + TVarRec(const long double& src): VType(vtExtended), VExtended(const_cast(&src)) {} + TVarRec(const double& src): VType(vtExtended), VExtended(reinterpret_cast(const_cast(&src))) {} + TVarRec(const float& src): VType(vtExtended), VExtended(reinterpret_cast(const_cast(&src))) {} + TVarRec(const ShortString& src): VType(vtString), VString(const_cast(&src)) {} + TVarRec(const void* src): VType(vtPointer), VPointer(const_cast(src)) {} + TVarRec(const char* src): VType(vtPChar), VPChar(const_cast(src)) {} + TVarRec(const System::TObject& src): VType(vtObject), VObject(const_cast(&src)) {} + TVarRec(System::TClass src): VType(vtClass), VClass(src) {} + TVarRec(const wchar_t* src): VType(vtPWideChar), VPWideChar(const_cast(src)) {} + TVarRec(const std::string& src): VType(vtAnsiString), VAnsiString(reinterpret_cast(const_cast(src.c_str()))) {} + TVarRec(const std::wstring& src): VType(vtWideString), VWideString(reinterpret_cast(const_cast(src.c_str()))) {} + TVarRec(const Currency& src): VType(vtCurrency), VCurrency(const_cast(&src)) {} + TVarRec(const int64_t& src): VType(vtInt64), VInt64(const_cast(&src)) {} + TVarRec(const uint64_t& src): VType(vtUInt64), VUInt64(const_cast(&src)) {} + TVarRec(const Variant& src): VType(vtVariant), VVariant(const_cast(&src)) {} + + TVarRec& operator =(int src) + { + VType = vtInteger; + VInteger = src; + return *this; + } + + TVarRec& operator =(bool src) + { + VType = vtBoolean; + VBoolean = src; + return *this; + } + + TVarRec& operator =(char src) + { + VType = vtChar; + VChar = src; + return *this; + } + + TVarRec& operator =(wchar_t src) + { + VType = vtWideChar; + VWideChar = src; + return *this; + } + + TVarRec& operator =(const long double& src) + { + VType = vtExtended; + VExtended = const_cast(&src); + return *this; + } + + TVarRec& operator =(const double& src) + { + VType = vtExtended; + VExtended = reinterpret_cast(const_cast(&src)); + return *this; + } + + TVarRec& operator =(const float& src) + { + VType = vtExtended; + VExtended = reinterpret_cast(const_cast(&src)); + return *this; + } + + TVarRec& operator =(const ShortString& src) + { + VType = vtString; + VString = const_cast(&src); + return *this; + } + + TVarRec& operator =(const void* src) + { + VType = vtPointer; + VPointer = const_cast(src); + return *this; + } + + TVarRec& operator =(const char* src) + { + VType = vtPChar; + VPChar = const_cast(src); + return *this; + } + + TVarRec& operator =(const wchar_t* src) + { + VType = vtPWideChar; + VPWideChar = const_cast(src); + return *this; + } + + TVarRec& operator =(const System::TObject& src) + { + VType = vtObject; + VObject = const_cast(&src); + return *this; + } + + TVarRec& operator =(System::TClass src) + { + VType = vtClass; + VClass = src; + return *this; + } + + + TVarRec& operator =(const PWideChar src) + { + VType = vtPWideChar; + VPWideChar = src; + return *this; + } + + TVarRec& operator =(const std::string& src) + { + VType = vtAnsiString; + VAnsiString = reinterpret_cast(const_cast(src.c_str())); + return *this; + } + + TVarRec& operator =(const std::wstring& src) + { + VType = vtWideString; + VWideString = reinterpret_cast(const_cast(src.c_str())); + return *this; + } + + TVarRec& operator =(const Currency& src) + { + VType = vtCurrency; + VCurrency = const_cast(&src); + return *this; + } + + TVarRec& operator =(const int64_t& src) + { + VType = vtInt64; + VInt64 = const_cast(&src); + return *this; + } + + TVarRec& operator =(const uint64_t& src) + { + VType = vtUInt64; + VUInt64 = const_cast(&src); + return *this; + } + + TVarRec& operator =(const Variant& src) + { + VType = vtVariant; + VVariant = const_cast(&src); + return *this; + } + +}; + +typedef TVarRec *PVarRec; +typedef std::vector VECTOROFCONST; + +#endif \ No newline at end of file diff --git a/OpenDSSC/Support/dirsep.h b/OpenDSSC/Support/dirsep.h new file mode 100644 index 0000000..3b0d555 --- /dev/null +++ b/OpenDSSC/Support/dirsep.h @@ -0,0 +1,12 @@ +#ifndef _DIRSEP_H +#define _DIRSEP_H + +#ifdef windows +#define DIRSEP_STR "\\" +#define DIRSEP_CHAR '\\' +#else +#define DIRSEP_STR "/" +#define DIRSEP_CHAR '/' +#endif + +#endif // _DIRSEP_H diff --git a/OpenDSSC/Support/readme.txt b/OpenDSSC/Support/readme.txt new file mode 100644 index 0000000..11f78ba --- /dev/null +++ b/OpenDSSC/Support/readme.txt @@ -0,0 +1,98 @@ + +For Visual C++, gcc and other compilers most parts of the most basic +Delphi units System.pas and Sysutils.pas are translated from the free +pascal sources: + +http://www.freepascal.org/ + +Remarks to the copyright are at the top of each file. + + +Though free pascal is made for use with many different operating +systems, the translation here is for Windows and Linux only. + +For use under Linux or with other compilers than VisualC++ either +the line + +#include "stdafx.h" + +has to be removed from the sources or a dummy header with this name +has to be made. Some definitions, which are created by Visual Studio +automatically are presupposed: + +_UNICODE for unicode/widestring applications +_CONSOLE for console applications +_USRDLL for dll's + + +Under Linux the command line arguments aren't accessible before +entering the main function of a program. This function therefore +should start with something like: + + System::Argv = argv; + System::Argc = argc; + + +The C++ counterpart of Sysutils.pas is written in a single source +file. System.pas however is split into some smaller files. But all +headers of these smaller files are put together into "System.h", which +is: + + +#ifndef SystemH +#define SystemH + +#if defined( WIN32 ) || defined( WIN64 ) +#define windows 1 +#endif + +#include "d2c_system.h" +#include "d2c_systypes.h" +#include "d2c_sysconst.h" +#include "d2c_syscurr.h" +#include "d2c_sysdate.h" +#include "d2c_systobj.h" +#include "d2c_openarray.h" +#include "d2c_sysexcept.h" +#include "d2c_sysmath.h" +#include "d2c_sysstring.h" +#include "d2c_sysfile.h" + +using namespace System; + +#endif // SystemH + + +There are three pas-file, which contains the according interface +declarations. These pas-files have to be put into the search paths for +files not to convert (VCL) in the option dialog of Delphi2Cpp. + + +Restrictions +------------ + +The code was made originally by automatic translation with a special +version of Delphi2Cpp: FreePascal2Cpp. Some parts of the generated C++ +code were improved manually. Large parts were tested and are working +well, but there isn't any guarantee that the code is completely +bug-free. There is no translation for the Variant class and only a +minimal implementation of a Currency class. The formatting of real +types in free pascal depend on a special binary layout of that types. +The formatting couldn't be reproduced exactly. Free pascal uses +Mersenne twister for the generation of random numbers. This part was +not translated back to C++ because there are a lot of C++ +implementations of Mersenne twister in C++ + +http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/c-lang.html + +Currently a primitive random generator based on C++ standard +functions is used. Such standard function were preferred to +direct translations of Delphi functions at other places too. So there +might be slight differences to the original Delphi behavior. For +example the error position returned in the Code-parameter of the Val +procedure, is a dummy only in C++. + + +Despite of these restrictions for many users this provided C++ code will make +the migration of their Delphi code much easier. + diff --git a/OpenDSSC/commit_3820.txt b/OpenDSSC/commit_3820.txt new file mode 100644 index 0000000..e69de29 diff --git a/OpenDSSC/compile b/OpenDSSC/compile new file mode 100644 index 0000000..a025892 --- /dev/null +++ b/OpenDSSC/compile @@ -0,0 +1,36 @@ +#!/bin/sh +set -e +set -u +# Extract our directory from $0: +base_dir="${0%/*}" +if ! test -d "${base_dir}" ; then + printf 'Cannot determine base_dir from $0=%s\n' "$0" 1>&2 + exit 1 +fi + +# Always start our build from the top-level: +cd "${base_dir}" + +if test -e build ; then + rm -rf build +fi +export CC=clang +export CXX=clang++ +cmake -S . -B build +if false ; then + exec cmake --build build +else + # If cmake is building Makefiles, this is an alternative way which + # compiles all source files in parallel (adjust -j16 to your system), + # and count of the total numbers of unique warnings and errors. + cd build + make -k -j16 --output-sync=target 2> make_err.txt && st="$?" || st="$?" + # Show a scoreboard of unique warnings & errors: + #grep -E '\<(warning|error):' make_err.txt | sort | uniq -c | sort -n || true + # Show a scoreboard of warnings & errors summed up over all files: + grep -E '\<(warning|error):' make_err.txt | sed -E -s 's/^.*(\<(warning|error):.*$)/\1/' | sort | uniq -c | sort -n || true + # And print the total counts of errors and warnings: + grep -E '\<(warning|error):' make_err.txt | sed -E -s 's/^.*\<(warning|error):.*/\1/' | sort | uniq -c || true + # Now provide make's exit status: + exit "${st}" +fi diff --git a/OpenDSSC/klusolve/AMD/Demo/Makefile b/OpenDSSC/klusolve/AMD/Demo/Makefile new file mode 100644 index 0000000..7c42d29 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/Makefile @@ -0,0 +1,91 @@ +#----------------------------------------------------------------------------- +# compile the AMD demo (for both GNU make or original make) +#----------------------------------------------------------------------------- + +default: amd_simple amd_demo amd_demo2 amd_l_demo + +include ../../UFconfig/UFconfig.mk + +C = $(CC) $(CF) -I../Include -I../../UFconfig + +INC = ../Include/amd.h ../../UFconfig/UFconfig.h + +library: + ( cd ../Lib ; $(MAKE) ) + +f77lib: + ( cd ../Lib ; $(MAKE) fortran ) + +#------------------------------------------------------------------------------ +# Create the demo program, run it, and compare the output +#------------------------------------------------------------------------------ + +dist: + +amd_demo: amd_demo.c library $(INC) + $(C) -o amd_demo amd_demo.c ../Lib/libamd.a $(LIB) + ./amd_demo > my_amd_demo.out + - diff amd_demo.out my_amd_demo.out + +amd_l_demo: amd_l_demo.c library $(INC) + $(C) -o amd_l_demo amd_l_demo.c ../Lib/libamd.a $(LIB) + ./amd_l_demo > my_amd_l_demo.out + - diff amd_l_demo.out my_amd_l_demo.out + +amd_demo2: amd_demo2.c library $(INC) + $(C) -o amd_demo2 amd_demo2.c ../Lib/libamd.a $(LIB) + ./amd_demo2 > my_amd_demo2.out + - diff amd_demo2.out my_amd_demo2.out + +amd_simple: amd_simple.c library $(INC) + $(C) -o amd_simple amd_simple.c ../Lib/libamd.a $(LIB) + ./amd_simple > my_amd_simple.out + - diff amd_simple.out my_amd_simple.out + +#------------------------------------------------------------------------------ +# compile the Fortran demo +#------------------------------------------------------------------------------ + +fortran: amd_f77demo amd_f77simple + +cross: amd_f77cross + +amd_f77demo: amd_f77demo.f f77lib + $(F77) $(F77FLAGS) -o amd_f77demo amd_f77demo.f ../Lib/libamdf77.a \ + $(F77LIB) + ./amd_f77demo > my_amd_f77demo.out + - diff amd_f77demo.out my_amd_f77demo.out + +amd_f77simple: amd_f77simple.f f77lib + $(F77) $(F77FLAGS) -o amd_f77simple amd_f77simple.f \ + ../Lib/libamdf77.a $(F77LIB) + ./amd_f77simple > my_amd_f77simple.out + - diff amd_f77simple.out my_amd_f77simple.out + +amd_f77wrapper.o: amd_f77wrapper.c + $(C) -DDINT -c amd_f77wrapper.c + +amd_f77cross: amd_f77cross.f amd_f77wrapper.o ../Lib/libamd.a + $(F77) $(F77FLAGS) -o amd_f77cross amd_f77cross.f amd_f77wrapper.o \ + ../Lib/libamd.a $(F77LIB) + ./amd_f77cross > my_amd_f77cross.out + - diff amd_f77cross.out my_amd_f77cross.out + +#------------------------------------------------------------------------------ +# Remove all but the files in the original distribution +#------------------------------------------------------------------------------ + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) amd_demo my_amd_demo.out + - $(RM) amd_l_demo my_amd_l_demo.out + - $(RM) amd_demo2 my_amd_demo2.out + - $(RM) amd_simple my_amd_simple.out + - $(RM) amd_f77demo my_amd_f77demo.out + - $(RM) amd_f77simple my_amd_f77simple.out + - $(RM) amd_f77cross my_amd_f77cross.out + - $(RM) -r *.dSYM diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_demo.c b/OpenDSSC/klusolve/AMD/Demo/amd_demo.c new file mode 100644 index 0000000..1e8c045 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_demo.c @@ -0,0 +1,178 @@ +/* ========================================================================= */ +/* === AMD demo main program =============================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Copyright (c) by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* A simple C main program that illustrates the use of the ANSI C interface + * to AMD. + */ + +#include "amd.h" +#include +#include + +int main (void) +{ + /* The symmetric can_24 Harwell/Boeing matrix, including upper and lower + * triangular parts, and the diagonal entries. Note that this matrix is + * 0-based, with row and column indices in the range 0 to n-1. */ + int n = 24, nz, + Ap [ ] = { 0, 9, 15, 21, 27, 33, 39, 48, 57, 61, 70, 76, 82, 88, 94, 100, + 106, 110, 119, 128, 137, 143, 152, 156, 160 }, + Ai [ ] = { + /* column 0: */ 0, 5, 6, 12, 13, 17, 18, 19, 21, + /* column 1: */ 1, 8, 9, 13, 14, 17, + /* column 2: */ 2, 6, 11, 20, 21, 22, + /* column 3: */ 3, 7, 10, 15, 18, 19, + /* column 4: */ 4, 7, 9, 14, 15, 16, + /* column 5: */ 0, 5, 6, 12, 13, 17, + /* column 6: */ 0, 2, 5, 6, 11, 12, 19, 21, 23, + /* column 7: */ 3, 4, 7, 9, 14, 15, 16, 17, 18, + /* column 8: */ 1, 8, 9, 14, + /* column 9: */ 1, 4, 7, 8, 9, 13, 14, 17, 18, + /* column 10: */ 3, 10, 18, 19, 20, 21, + /* column 11: */ 2, 6, 11, 12, 21, 23, + /* column 12: */ 0, 5, 6, 11, 12, 23, + /* column 13: */ 0, 1, 5, 9, 13, 17, + /* column 14: */ 1, 4, 7, 8, 9, 14, + /* column 15: */ 3, 4, 7, 15, 16, 18, + /* column 16: */ 4, 7, 15, 16, + /* column 17: */ 0, 1, 5, 7, 9, 13, 17, 18, 19, + /* column 18: */ 0, 3, 7, 9, 10, 15, 17, 18, 19, + /* column 19: */ 0, 3, 6, 10, 17, 18, 19, 20, 21, + /* column 20: */ 2, 10, 19, 20, 21, 22, + /* column 21: */ 0, 2, 6, 10, 11, 19, 20, 21, 22, + /* column 22: */ 2, 20, 21, 22, + /* column 23: */ 6, 11, 12, 23 } ; + + int P [24], Pinv [24], i, j, k, jnew, p, inew, result ; + double Control [AMD_CONTROL], Info [AMD_INFO] ; + char A [24][24] ; + + /* here is an example of how to use AMD_VERSION. This code will work in + * any version of AMD. */ +#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) + printf ("AMD version %d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, + AMD_DATE) ; +#else + printf ("AMD version: 1.1 or earlier\n") ; +#endif + + printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; + + /* get the default parameters, and print them */ + amd_defaults (Control) ; + amd_control (Control) ; + + /* print the input matrix */ + nz = Ap [n] ; + printf ("\nInput matrix: %d-by-%d, with %d entries.\n" + " Note that for a symmetric matrix such as this one, only the\n" + " strictly lower or upper triangular parts would need to be\n" + " passed to AMD, since AMD computes the ordering of A+A'. The\n" + " diagonal entries are also not needed, since AMD ignores them.\n" + , n, n, nz) ; + for (j = 0 ; j < n ; j++) + { + printf ("\nColumn: %d, number of entries: %d, with row indices in" + " Ai [%d ... %d]:\n row indices:", + j, Ap [j+1] - Ap [j], Ap [j], Ap [j+1]-1) ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + printf (" %d", i) ; + } + printf ("\n") ; + } + + /* print a character plot of the input matrix. This is only reasonable + * because the matrix is small. */ + printf ("\nPlot of input matrix pattern:\n") ; + for (j = 0 ; j < n ; j++) + { + for (i = 0 ; i < n ; i++) A [i][j] = '.' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + A [i][j] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2d: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + /* order the matrix */ + result = amd_order (n, Ap, Ai, P, Control, Info) ; + printf ("return value from amd_order: %d (should be %d)\n", + result, AMD_OK) ; + + /* print the statistics */ + amd_info (Info) ; + + if (result != AMD_OK) + { + printf ("AMD failed\n") ; + exit (1) ; + } + + /* print the permutation vector, P, and compute the inverse permutation */ + printf ("Permutation vector:\n") ; + for (k = 0 ; k < n ; k++) + { + /* row/column j is the kth row/column in the permuted matrix */ + j = P [k] ; + Pinv [j] = k ; + printf (" %2d", j) ; + } + printf ("\n\n") ; + + printf ("Inverse permutation vector:\n") ; + for (j = 0 ; j < n ; j++) + { + k = Pinv [j] ; + printf (" %2d", k) ; + } + printf ("\n\n") ; + + /* print a character plot of the permuted matrix. */ + printf ("\nPlot of permuted matrix pattern:\n") ; + for (jnew = 0 ; jnew < n ; jnew++) + { + j = P [jnew] ; + for (inew = 0 ; inew < n ; inew++) A [inew][jnew] = '.' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + inew = Pinv [Ai [p]] ; + A [inew][jnew] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2d: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + return (0) ; +} diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_demo.out b/OpenDSSC/klusolve/AMD/Demo/amd_demo.out new file mode 100644 index 0000000..fc75800 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_demo.out @@ -0,0 +1,179 @@ +AMD version 2.2, date: Dec 7, 2011 +AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24: + +AMD version 2.2.3, Dec 7, 2011: approximate minimum degree ordering + dense row parameter: 10 + (rows with more than max (10 * sqrt (n), 16) entries are + considered "dense", and placed last in output permutation) + aggressive absorption: yes + size of AMD integer: 4 + + +Input matrix: 24-by-24, with 160 entries. + Note that for a symmetric matrix such as this one, only the + strictly lower or upper triangular parts would need to be + passed to AMD, since AMD computes the ordering of A+A'. The + diagonal entries are also not needed, since AMD ignores them. + +Column: 0, number of entries: 9, with row indices in Ai [0 ... 8]: + row indices: 0 5 6 12 13 17 18 19 21 + +Column: 1, number of entries: 6, with row indices in Ai [9 ... 14]: + row indices: 1 8 9 13 14 17 + +Column: 2, number of entries: 6, with row indices in Ai [15 ... 20]: + row indices: 2 6 11 20 21 22 + +Column: 3, number of entries: 6, with row indices in Ai [21 ... 26]: + row indices: 3 7 10 15 18 19 + +Column: 4, number of entries: 6, with row indices in Ai [27 ... 32]: + row indices: 4 7 9 14 15 16 + +Column: 5, number of entries: 6, with row indices in Ai [33 ... 38]: + row indices: 0 5 6 12 13 17 + +Column: 6, number of entries: 9, with row indices in Ai [39 ... 47]: + row indices: 0 2 5 6 11 12 19 21 23 + +Column: 7, number of entries: 9, with row indices in Ai [48 ... 56]: + row indices: 3 4 7 9 14 15 16 17 18 + +Column: 8, number of entries: 4, with row indices in Ai [57 ... 60]: + row indices: 1 8 9 14 + +Column: 9, number of entries: 9, with row indices in Ai [61 ... 69]: + row indices: 1 4 7 8 9 13 14 17 18 + +Column: 10, number of entries: 6, with row indices in Ai [70 ... 75]: + row indices: 3 10 18 19 20 21 + +Column: 11, number of entries: 6, with row indices in Ai [76 ... 81]: + row indices: 2 6 11 12 21 23 + +Column: 12, number of entries: 6, with row indices in Ai [82 ... 87]: + row indices: 0 5 6 11 12 23 + +Column: 13, number of entries: 6, with row indices in Ai [88 ... 93]: + row indices: 0 1 5 9 13 17 + +Column: 14, number of entries: 6, with row indices in Ai [94 ... 99]: + row indices: 1 4 7 8 9 14 + +Column: 15, number of entries: 6, with row indices in Ai [100 ... 105]: + row indices: 3 4 7 15 16 18 + +Column: 16, number of entries: 4, with row indices in Ai [106 ... 109]: + row indices: 4 7 15 16 + +Column: 17, number of entries: 9, with row indices in Ai [110 ... 118]: + row indices: 0 1 5 7 9 13 17 18 19 + +Column: 18, number of entries: 9, with row indices in Ai [119 ... 127]: + row indices: 0 3 7 9 10 15 17 18 19 + +Column: 19, number of entries: 9, with row indices in Ai [128 ... 136]: + row indices: 0 3 6 10 17 18 19 20 21 + +Column: 20, number of entries: 6, with row indices in Ai [137 ... 142]: + row indices: 2 10 19 20 21 22 + +Column: 21, number of entries: 9, with row indices in Ai [143 ... 151]: + row indices: 0 2 6 10 11 19 20 21 22 + +Column: 22, number of entries: 4, with row indices in Ai [152 ... 155]: + row indices: 2 20 21 22 + +Column: 23, number of entries: 4, with row indices in Ai [156 ... 159]: + row indices: 6 11 12 23 + +Plot of input matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X . . . . X X . . . . . X X . . . X X X . X . . + 1: . X . . . . . . X X . . . X X . . X . . . . . . + 2: . . X . . . X . . . . X . . . . . . . . X X X . + 3: . . . X . . . X . . X . . . . X . . X X . . . . + 4: . . . . X . . X . X . . . . X X X . . . . . . . + 5: X . . . . X X . . . . . X X . . . X . . . . . . + 6: X . X . . X X . . . . X X . . . . . . X . X . X + 7: . . . X X . . X . X . . . . X X X X X . . . . . + 8: . X . . . . . . X X . . . . X . . . . . . . . . + 9: . X . . X . . X X X . . . X X . . X X . . . . . +10: . . . X . . . . . . X . . . . . . . X X X X . . +11: . . X . . . X . . . . X X . . . . . . . . X . X +12: X . . . . X X . . . . X X . . . . . . . . . . X +13: X X . . . X . . . X . . . X . . . X . . . . . . +14: . X . . X . . X X X . . . . X . . . . . . . . . +15: . . . X X . . X . . . . . . . X X . X . . . . . +16: . . . . X . . X . . . . . . . X X . . . . . . . +17: X X . . . X . X . X . . . X . . . X X X . . . . +18: X . . X . . . X . X X . . . . X . X X X . . . . +19: X . . X . . X . . . X . . . . . . X X X X X . . +20: . . X . . . . . . . X . . . . . . . . X X X X . +21: X . X . . . X . . . X X . . . . . . . X X X X . +22: . . X . . . . . . . . . . . . . . . . . X X X . +23: . . . . . . X . . . . X X . . . . . . . . . . X +return value from amd_order: 0 (should be 0) + +AMD version 2.2.3, Dec 7, 2011, results: + status: OK + n, dimension of A: 24 + nz, number of nonzeros in A: 160 + symmetry of A: 1.0000 + number of nonzeros on diagonal: 24 + nonzeros in pattern of A+A' (excl. diagonal): 136 + # dense rows/columns of A+A': 0 + memory used, in bytes: 1516 + # of memory compactions: 0 + + The following approximate statistics are for a subsequent + factorization of A(P,P) + A(P,P)'. They are slight upper + bounds if there are no dense rows/columns in A+A', and become + looser if dense rows/columns exist. + + nonzeros in L (excluding diagonal): 97 + nonzeros in L (including diagonal): 121 + # divide operations for LDL' or LU: 97 + # multiply-subtract operations for LDL': 275 + # multiply-subtract operations for LU: 453 + max nz. in any column of L (incl. diagonal): 8 + + chol flop count for real A, sqrt counted as 1 flop: 671 + LDL' flop count for real A: 647 + LDL' flop count for complex A: 3073 + LU flop count for real A (with no pivoting): 1003 + LU flop count for complex A (with no pivoting): 4497 + +Permutation vector: + 22 20 10 23 12 5 16 8 14 4 15 7 1 9 13 17 0 2 3 6 11 18 21 19 + +Inverse permutation vector: + 16 12 17 18 9 5 19 11 7 13 2 20 4 14 8 10 6 15 21 23 1 22 0 3 + + +Plot of permuted matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X X . . . . . . . . . . . . . . . X . . . . X . + 1: X X X . . . . . . . . . . . . . . X . . . . X X + 2: . X X . . . . . . . . . . . . . . . X . . X X X + 3: . . . X X . . . . . . . . . . . . . . X X . . . + 4: . . . X X X . . . . . . . . . . X . . X X . . . + 5: . . . . X X . . . . . . . . X X X . . X . . . . + 6: . . . . . . X . . X X X . . . . . . . . . . . . + 7: . . . . . . . X X . . . X X . . . . . . . . . . + 8: . . . . . . . X X X . X X X . . . . . . . . . . + 9: . . . . . . X . X X X X . X . . . . . . . . . . +10: . . . . . . X . . X X X . . . . . . X . . X . . +11: . . . . . . X . X X X X . X . X . . X . . X . . +12: . . . . . . . X X . . . X X X X . . . . . . . . +13: . . . . . . . X X X . X X X X X . . . . . X . . +14: . . . . . X . . . . . . X X X X X . . . . . . . +15: . . . . . X . . . . . X X X X X X . . . . X . X +16: . . . . X X . . . . . . . . X X X . . X . X X X +17: X X . . . . . . . . . . . . . . . X . X X . X . +18: . . X . . . . . . . X X . . . . . . X . . X . X +19: . . . X X X . . . . . . . . . . X X . X X . X X +20: . . . X X . . . . . . . . . . . . X . X X . X . +21: . . X . . . . . . . X X . X . X X . X . . X . X +22: X X X . . . . . . . . . . . . . X X . X X . X X +23: . X X . . . . . . . . . . . . X X . X X . X X X diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_demo2.c b/OpenDSSC/klusolve/AMD/Demo/amd_demo2.c new file mode 100644 index 0000000..b718580 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_demo2.c @@ -0,0 +1,209 @@ +/* ========================================================================= */ +/* === AMD demo main program (jumbled matrix version) ====================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Copyright (c) by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* A simple C main program that illustrates the use of the ANSI C interface + * to AMD. + * + * Identical to amd_demo.c, except that it operates on an input matrix that has + * unsorted columns and duplicate entries. + */ + +#include "amd.h" +#include +#include + +int main (void) +{ + /* The symmetric can_24 Harwell/Boeing matrix (jumbled, and not symmetric). + * Since AMD operates on A+A', only A(i,j) or A(j,i) need to be specified, + * or both. The diagonal entries are optional (some are missing). + * There are many duplicate entries, which must be removed. */ + int n = 24, nz, + Ap [ ] = { 0, 9, 14, 20, 28, 33, 37, 44, 53, 58, 63, 63, 66, 69, 72, 75, + 78, 82, 86, 91, 97, 101, 112, 112, 116 }, + Ai [ ] = { + /* column 0: */ 0, 17, 18, 21, 5, 12, 5, 0, 13, + /* column 1: */ 14, 1, 8, 13, 17, + /* column 2: */ 2, 20, 11, 6, 11, 22, + /* column 3: */ 3, 3, 10, 7, 18, 18, 15, 19, + /* column 4: */ 7, 9, 15, 14, 16, + /* column 5: */ 5, 13, 6, 17, + /* column 6: */ 5, 0, 11, 6, 12, 6, 23, + /* column 7: */ 3, 4, 9, 7, 14, 16, 15, 17, 18, + /* column 8: */ 1, 9, 14, 14, 14, + /* column 9: */ 7, 13, 8, 1, 17, + /* column 10: */ + /* column 11: */ 2, 12, 23, + /* column 12: */ 5, 11, 12, + /* column 13: */ 0, 13, 17, + /* column 14: */ 1, 9, 14, + /* column 15: */ 3, 15, 16, + /* column 16: */ 16, 4, 4, 15, + /* column 17: */ 13, 17, 19, 17, + /* column 18: */ 15, 17, 19, 9, 10, + /* column 19: */ 17, 19, 20, 0, 6, 10, + /* column 20: */ 22, 10, 20, 21, + /* column 21: */ 6, 2, 10, 19, 20, 11, 21, 22, 22, 22, 22, + /* column 22: */ + /* column 23: */ 12, 11, 12, 23 } ; + + int P [24], Pinv [24], i, j, k, jnew, p, inew, result ; + double Control [AMD_CONTROL], Info [AMD_INFO] ; + char A [24][24] ; + + printf ("AMD demo, with a jumbled version of the 24-by-24\n") ; + printf ("Harwell/Boeing matrix, can_24:\n") ; + + /* get the default parameters, and print them */ + amd_defaults (Control) ; + amd_control (Control) ; + + /* print the input matrix */ + nz = Ap [n] ; + printf ("\nJumbled input matrix: %d-by-%d, with %d entries.\n" + " Note that for a symmetric matrix such as this one, only the\n" + " strictly lower or upper triangular parts would need to be\n" + " passed to AMD, since AMD computes the ordering of A+A'. The\n" + " diagonal entries are also not needed, since AMD ignores them.\n" + " This version of the matrix has jumbled columns and duplicate\n" + " row indices.\n", n, n, nz) ; + for (j = 0 ; j < n ; j++) + { + printf ("\nColumn: %d, number of entries: %d, with row indices in" + " Ai [%d ... %d]:\n row indices:", + j, Ap [j+1] - Ap [j], Ap [j], Ap [j+1]-1) ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + printf (" %d", i) ; + } + printf ("\n") ; + } + + /* print a character plot of the input matrix. This is only reasonable + * because the matrix is small. */ + printf ("\nPlot of (jumbled) input matrix pattern:\n") ; + for (j = 0 ; j < n ; j++) + { + for (i = 0 ; i < n ; i++) A [i][j] = '.' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + A [i][j] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2d: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + /* print a character plot of the matrix A+A'. */ + printf ("\nPlot of symmetric matrix to be ordered by amd_order:\n") ; + for (j = 0 ; j < n ; j++) + { + for (i = 0 ; i < n ; i++) A [i][j] = '.' ; + } + for (j = 0 ; j < n ; j++) + { + A [j][j] = 'X' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + A [i][j] = 'X' ; + A [j][i] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2d: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + /* order the matrix */ + result = amd_order (n, Ap, Ai, P, Control, Info) ; + printf ("return value from amd_order: %d (should be %d)\n", + result, AMD_OK_BUT_JUMBLED) ; + + /* print the statistics */ + amd_info (Info) ; + + if (result != AMD_OK_BUT_JUMBLED) + { + printf ("AMD failed\n") ; + exit (1) ; + } + + /* print the permutation vector, P, and compute the inverse permutation */ + printf ("Permutation vector:\n") ; + for (k = 0 ; k < n ; k++) + { + /* row/column j is the kth row/column in the permuted matrix */ + j = P [k] ; + Pinv [j] = k ; + printf (" %2d", j) ; + } + printf ("\n\n") ; + + printf ("Inverse permutation vector:\n") ; + for (j = 0 ; j < n ; j++) + { + k = Pinv [j] ; + printf (" %2d", k) ; + } + printf ("\n\n") ; + + /* print a character plot of the permuted matrix. */ + printf ("\nPlot of (symmetrized) permuted matrix pattern:\n") ; + for (j = 0 ; j < n ; j++) + { + for (i = 0 ; i < n ; i++) A [i][j] = '.' ; + } + for (jnew = 0 ; jnew < n ; jnew++) + { + j = P [jnew] ; + A [jnew][jnew] = 'X' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + inew = Pinv [Ai [p]] ; + A [inew][jnew] = 'X' ; + A [jnew][inew] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1d", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2d: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + return (0) ; +} diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_demo2.out b/OpenDSSC/klusolve/AMD/Demo/amd_demo2.out new file mode 100644 index 0000000..1a38d34 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_demo2.out @@ -0,0 +1,208 @@ +AMD demo, with a jumbled version of the 24-by-24 +Harwell/Boeing matrix, can_24: + +AMD version 2.2.3, Dec 7, 2011: approximate minimum degree ordering + dense row parameter: 10 + (rows with more than max (10 * sqrt (n), 16) entries are + considered "dense", and placed last in output permutation) + aggressive absorption: yes + size of AMD integer: 4 + + +Jumbled input matrix: 24-by-24, with 116 entries. + Note that for a symmetric matrix such as this one, only the + strictly lower or upper triangular parts would need to be + passed to AMD, since AMD computes the ordering of A+A'. The + diagonal entries are also not needed, since AMD ignores them. + This version of the matrix has jumbled columns and duplicate + row indices. + +Column: 0, number of entries: 9, with row indices in Ai [0 ... 8]: + row indices: 0 17 18 21 5 12 5 0 13 + +Column: 1, number of entries: 5, with row indices in Ai [9 ... 13]: + row indices: 14 1 8 13 17 + +Column: 2, number of entries: 6, with row indices in Ai [14 ... 19]: + row indices: 2 20 11 6 11 22 + +Column: 3, number of entries: 8, with row indices in Ai [20 ... 27]: + row indices: 3 3 10 7 18 18 15 19 + +Column: 4, number of entries: 5, with row indices in Ai [28 ... 32]: + row indices: 7 9 15 14 16 + +Column: 5, number of entries: 4, with row indices in Ai [33 ... 36]: + row indices: 5 13 6 17 + +Column: 6, number of entries: 7, with row indices in Ai [37 ... 43]: + row indices: 5 0 11 6 12 6 23 + +Column: 7, number of entries: 9, with row indices in Ai [44 ... 52]: + row indices: 3 4 9 7 14 16 15 17 18 + +Column: 8, number of entries: 5, with row indices in Ai [53 ... 57]: + row indices: 1 9 14 14 14 + +Column: 9, number of entries: 5, with row indices in Ai [58 ... 62]: + row indices: 7 13 8 1 17 + +Column: 10, number of entries: 0, with row indices in Ai [63 ... 62]: + row indices: + +Column: 11, number of entries: 3, with row indices in Ai [63 ... 65]: + row indices: 2 12 23 + +Column: 12, number of entries: 3, with row indices in Ai [66 ... 68]: + row indices: 5 11 12 + +Column: 13, number of entries: 3, with row indices in Ai [69 ... 71]: + row indices: 0 13 17 + +Column: 14, number of entries: 3, with row indices in Ai [72 ... 74]: + row indices: 1 9 14 + +Column: 15, number of entries: 3, with row indices in Ai [75 ... 77]: + row indices: 3 15 16 + +Column: 16, number of entries: 4, with row indices in Ai [78 ... 81]: + row indices: 16 4 4 15 + +Column: 17, number of entries: 4, with row indices in Ai [82 ... 85]: + row indices: 13 17 19 17 + +Column: 18, number of entries: 5, with row indices in Ai [86 ... 90]: + row indices: 15 17 19 9 10 + +Column: 19, number of entries: 6, with row indices in Ai [91 ... 96]: + row indices: 17 19 20 0 6 10 + +Column: 20, number of entries: 4, with row indices in Ai [97 ... 100]: + row indices: 22 10 20 21 + +Column: 21, number of entries: 11, with row indices in Ai [101 ... 111]: + row indices: 6 2 10 19 20 11 21 22 22 22 22 + +Column: 22, number of entries: 0, with row indices in Ai [112 ... 111]: + row indices: + +Column: 23, number of entries: 4, with row indices in Ai [112 ... 115]: + row indices: 12 11 12 23 + +Plot of (jumbled) input matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X . . . . . X . . . . . . X . . . . . X . . . . + 1: . X . . . . . . X X . . . . X . . . . . . . . . + 2: . . X . . . . . . . . X . . . . . . . . . X . . + 3: . . . X . . . X . . . . . . . X . . . . . . . . + 4: . . . . . . . X . . . . . . . . X . . . . . . . + 5: X . . . . X X . . . . . X . . . . . . . . . . . + 6: . . X . . X X . . . . . . . . . . . . X . X . . + 7: . . . X X . . X . X . . . . . . . . . . . . . . + 8: . X . . . . . . . X . . . . . . . . . . . . . . + 9: . . . . X . . X X . . . . . X . . . X . . . . . +10: . . . X . . . . . . . . . . . . . . X X X X . . +11: . . X . . . X . . . . . X . . . . . . . . X . X +12: X . . . . . X . . . . X X . . . . . . . . . . X +13: X X . . . X . . . X . . . X . . . X . . . . . . +14: . X . . X . . X X . . . . . X . . . . . . . . . +15: . . . X X . . X . . . . . . . X X . X . . . . . +16: . . . . X . . X . . . . . . . X X . . . . . . . +17: X X . . . X . X . X . . . X . . . X X X . . . . +18: X . . X . . . X . . . . . . . . . . . . . . . . +19: . . . X . . . . . . . . . . . . . X X X . X . . +20: . . X . . . . . . . . . . . . . . . . X X X . . +21: X . . . . . . . . . . . . . . . . . . . X X . . +22: . . X . . . . . . . . . . . . . . . . . X X . . +23: . . . . . . X . . . . X . . . . . . . . . . . X + +Plot of symmetric matrix to be ordered by amd_order: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X . . . . X X . . . . . X X . . . X X X . X . . + 1: . X . . . . . . X X . . . X X . . X . . . . . . + 2: . . X . . . X . . . . X . . . . . . . . X X X . + 3: . . . X . . . X . . X . . . . X . . X X . . . . + 4: . . . . X . . X . X . . . . X X X . . . . . . . + 5: X . . . . X X . . . . . X X . . . X . . . . . . + 6: X . X . . X X . . . . X X . . . . . . X . X . X + 7: . . . X X . . X . X . . . . X X X X X . . . . . + 8: . X . . . . . . X X . . . . X . . . . . . . . . + 9: . X . . X . . X X X . . . X X . . X X . . . . . +10: . . . X . . . . . . X . . . . . . . X X X X . . +11: . . X . . . X . . . . X X . . . . . . . . X . X +12: X . . . . X X . . . . X X . . . . . . . . . . X +13: X X . . . X . . . X . . . X . . . X . . . . . . +14: . X . . X . . X X X . . . . X . . . . . . . . . +15: . . . X X . . X . . . . . . . X X . X . . . . . +16: . . . . X . . X . . . . . . . X X . . . . . . . +17: X X . . . X . X . X . . . X . . . X X X . . . . +18: X . . X . . . X . X X . . . . X . X X X . . . . +19: X . . X . . X . . . X . . . . . . X X X X X . . +20: . . X . . . . . . . X . . . . . . . . X X X X . +21: X . X . . . X . . . X X . . . . . . . X X X X . +22: . . X . . . . . . . . . . . . . . . . . X X X . +23: . . . . . . X . . . . X X . . . . . . . . . . X +return value from amd_order: 1 (should be 1) + +AMD version 2.2.3, Dec 7, 2011, results: + status: OK, but jumbled + n, dimension of A: 24 + nz, number of nonzeros in A: 102 + symmetry of A: 0.4000 + number of nonzeros on diagonal: 17 + nonzeros in pattern of A+A' (excl. diagonal): 136 + # dense rows/columns of A+A': 0 + memory used, in bytes: 2080 + # of memory compactions: 0 + + The following approximate statistics are for a subsequent + factorization of A(P,P) + A(P,P)'. They are slight upper + bounds if there are no dense rows/columns in A+A', and become + looser if dense rows/columns exist. + + nonzeros in L (excluding diagonal): 97 + nonzeros in L (including diagonal): 121 + # divide operations for LDL' or LU: 97 + # multiply-subtract operations for LDL': 275 + # multiply-subtract operations for LU: 453 + max nz. in any column of L (incl. diagonal): 8 + + chol flop count for real A, sqrt counted as 1 flop: 671 + LDL' flop count for real A: 647 + LDL' flop count for complex A: 3073 + LU flop count for real A (with no pivoting): 1003 + LU flop count for complex A (with no pivoting): 4497 + +Permutation vector: + 22 20 10 23 12 5 16 8 14 4 15 7 1 9 13 17 0 2 3 6 11 18 21 19 + +Inverse permutation vector: + 16 12 17 18 9 5 19 11 7 13 2 20 4 14 8 10 6 15 21 23 1 22 0 3 + + +Plot of (symmetrized) permuted matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X X . . . . . . . . . . . . . . . X . . . . X . + 1: X X X . . . . . . . . . . . . . . X . . . . X X + 2: . X X . . . . . . . . . . . . . . . X . . X X X + 3: . . . X X . . . . . . . . . . . . . . X X . . . + 4: . . . X X X . . . . . . . . . . X . . X X . . . + 5: . . . . X X . . . . . . . . X X X . . X . . . . + 6: . . . . . . X . . X X X . . . . . . . . . . . . + 7: . . . . . . . X X . . . X X . . . . . . . . . . + 8: . . . . . . . X X X . X X X . . . . . . . . . . + 9: . . . . . . X . X X X X . X . . . . . . . . . . +10: . . . . . . X . . X X X . . . . . . X . . X . . +11: . . . . . . X . X X X X . X . X . . X . . X . . +12: . . . . . . . X X . . . X X X X . . . . . . . . +13: . . . . . . . X X X . X X X X X . . . . . X . . +14: . . . . . X . . . . . . X X X X X . . . . . . . +15: . . . . . X . . . . . X X X X X X . . . . X . X +16: . . . . X X . . . . . . . . X X X . . X . X X X +17: X X . . . . . . . . . . . . . . . X . X X . X . +18: . . X . . . . . . . X X . . . . . . X . . X . X +19: . . . X X X . . . . . . . . . . X X . X X . X X +20: . . . X X . . . . . . . . . . . . X . X X . X . +21: . . X . . . . . . . X X . X . X X . X . . X . X +22: X X X . . . . . . . . . . . . . X X . X X . X X +23: . X X . . . . . . . . . . . . X X . X X . X X X diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.f b/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.f new file mode 100644 index 0000000..26513e0 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.f @@ -0,0 +1,51 @@ +C ====================================================================== +C === AMD_cross ======================================================== +C ====================================================================== + +C ---------------------------------------------------------------------- +C AMD, Copyright (c) by Timothy A. Davis, Patrick R. +C Amestoy, and Iain S. Duff. See ../README.txt for +C License. email: davis at cise.ufl.edu CISE Department, Univ. of +C Florida. web: http://www.cise.ufl.edu/research/sparse/amd +C ---------------------------------------------------------------------- + +C This program provides an example of how to call the C version of AMD +C from a Fortran program. It is HIGHLY non-portable. + +C The amd_order routine returns PERM (1) < 0 if an error occurs. +C (-1: out of memory, -2: invalid matrix) + +C Note that the input matrix is 0-based. From Fortran, column j of the +C matrix is in AI (AP (I)+1 ... AP (I+1)). The row indices in this +C set are in the range 0 to N-1. To demonstrate this translation, +C the input matrix is printed in 1-based form. This program uses +C the same 5-by-5 test matrix as amd_simple.c. + + INTEGER N, NZ, K, P + PARAMETER (N = 5, NZ = 14) + INTEGER AP (N+1), AI (NZ), PERM (N) + DATA AP / 0, 2, 6, 10, 12, 14 / + DATA AI / 0,1, 0,1,2,4, 1,2,3,4, 2,3, 1,4 / + DOUBLE PRECISION CONTROL (5), INFO (20) + +C print the input matrix + PRINT 10, N, N, NZ +10 FORMAT ('Input matrix:', I2, '-by-', I2, ' with',I3,' entries') + DO 40 J = 1, N + PRINT 20, J, AP (J+1) - AP (J), AP (J)+1, AP (J+1) +20 FORMAT ( /, 'Column: ', I2, ' number of entries: ', I2, + $ ' with row indices in AI (', I3, ' ... ', I3, ')') + PRINT 30, ((AI (P) + 1), P = AP (J) + 1, AP (J+1)) +30 FORMAT (' row indices: ', 24I3) +40 CONTINUE + + CALL AMDDEFAULTS (CONTROL) + CALL AMDORDER (N, AP, AI, PERM, CONTROL, INFO) + CALL AMDINFO (INFO) + + DO 60 K = 1, N + PRINT 50, K, PERM (K) + 1 +50 FORMAT ('PERM (',I2,') = ', I2) +60 CONTINUE + END + diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.out b/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.out new file mode 100644 index 0000000..6d8a670 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77cross.out @@ -0,0 +1,51 @@ +Input matrix: 5-by- 5 with 14 entries + +Column: 1 number of entries: 2 with row indices in AI ( 1 ... 2) + row indices: 1 2 + +Column: 2 number of entries: 4 with row indices in AI ( 3 ... 6) + row indices: 1 2 3 5 + +Column: 3 number of entries: 4 with row indices in AI ( 7 ... 10) + row indices: 2 3 4 5 + +Column: 4 number of entries: 2 with row indices in AI ( 11 ... 12) + row indices: 3 4 + +Column: 5 number of entries: 2 with row indices in AI ( 13 ... 14) + row indices: 2 5 + +amd: approximate minimum degree ordering, results: + status: OK + n, dimension of A: 5 + nz, number of nonzeros in A: 14 + symmetry of A: 0.8889 + number of nonzeros on diagonal: 5 + nonzeros in pattern of A+A' (excl. diagonal): 10 + # dense rows/columns of A+A': 0 + memory used, in bytes: 228 + # of memory compactions: 0 + + The following approximate statistics are for a subsequent + factorization of A(P,P) + A(P,P)'. They are slight upper + bounds if there are no dense rows/columns in A+A', and become + looser if dense rows/columns exist. + + nonzeros in L (excluding diagonal): 5 + nonzeros in L (including diagonal): 10 + # divide operations for LDL' or LU: 5 + # multiply-subtract operations for LDL': 6 + # multiply-subtract operations for LU: 7 + max nz. in any column of L (incl. diagonal): 3 + + chol flop count for real A, sqrt counted as 1 flop: 22 + LDL' flop count for real A: 17 + LDL' flop count for complex A: 93 + LU flop count for real A (with no pivoting): 19 + LU flop count for complex A (with no pivoting): 101 + +PERM ( 1) = 1 +PERM ( 2) = 4 +PERM ( 3) = 3 +PERM ( 4) = 5 +PERM ( 5) = 2 diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.f b/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.f new file mode 100644 index 0000000..47b69fb --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.f @@ -0,0 +1,161 @@ +C ====================================================================== +C === Fortran AMD demo main program ==================================== +C ====================================================================== + +C ---------------------------------------------------------------------- +C AMD, Copyright (c) by Timothy A. Davis, Patrick R. +C Amestoy, and Iain S. Duff. See ../README.txt for +C License. email: davis at cise.ufl.edu CISE Department, Univ. of +C Florida. web: http://www.cise.ufl.edu/research/sparse/amd +C ---------------------------------------------------------------------- + +C A simple Fortran 77 main program that illustrates the use of the +C Fortran version of AMD (both the AMD and AMDBAR routines). Note +C that aggressive absorption has no effect on this particular matrix. + +C AP and AI contain the symmetric can_24 Harwell/Boeing matrix, +C including upper and lower triangular parts, but excluding the +C diagonal entries. Note that this matrix is 1-based, with row +C and column indices in the range 1 to N. + + INTEGER N, NZ, IWLEN, PFREE, I, J, K, JNEW, P, INEW, + $ METHOD, NCMPA + PARAMETER (N = 24, NZ = 136, IWLEN = 200) + INTEGER PE (N), DEGREE (N), NV (N), NEXT (N), PERM (N), W (N), + $ HEAD (N), PINV (N), LEN (N), AP (N+1), AI (NZ), IW (IWLEN) + CHARACTER A (24,24) + + DATA AP + $ / 1, 9, 14, 19, 24, 29, 34, 42, 50, 53, 61, 66, 71, + $ 76, 81, 86, 91, 94, 102, 110, 118, 123, 131, 134, 137 / + DATA AI / + $ 6, 7, 13, 14, 18, 19, 20, 22, + $ 9, 10, 14, 15, 18, + $ 7, 12, 21, 22, 23, + $ 8, 11, 16, 19, 20, + $ 8, 10, 15, 16, 17, + $ 1, 7, 13, 14, 18, + $ 1, 3, 6, 12, 13, 20, 22, 24, + $ 4, 5, 10, 15, 16, 17, 18, 19, + $ 2, 10, 15, + $ 2, 5, 8, 9, 14, 15, 18, 19, + $ 4, 19, 20, 21, 22, + $ 3, 7, 13, 22, 24, + $ 1, 6, 7, 12, 24, + $ 1, 2, 6, 10, 18, + $ 2, 5, 8, 9, 10, + $ 4, 5, 8, 17, 19, + $ 5, 8, 16, + $ 1, 2, 6, 8, 10, 14, 19, 20, + $ 1, 4, 8, 10, 11, 16, 18, 20, + $ 1, 4, 7, 11, 18, 19, 21, 22, + $ 3, 11, 20, 22, 23, + $ 1, 3, 7, 11, 12, 20, 21, 23, + $ 3, 21, 22, + $ 7, 12, 13 / + +C print the input matrix + PRINT 11, N, N, NZ +11 FORMAT ('AMD Fortran 77 demo, with the 24-by-24', + $ ' Harwell/Boeing matrix, can_24:' + $ /, 'Input matrix: ', I2, '-by-', I2,' with ',I3,' entries', + $ /, 'Note that the Fortran version of AMD requires that' + $ /, 'no diagonal entries be present.') + DO 20 J = 1, N + PRINT 21, J, AP (J+1) - AP (J), AP (J), AP (J+1)-1 +21 FORMAT ( /, 'Column: ', I2, ' number of entries: ', I2, + $ ' with row indices in AI (', I3, ' ... ', I3, ')') + PRINT 10, ((AI (P)), P = AP (J), AP (J+1) - 1) +10 FORMAT (' row indices: ', 24I3) +20 CONTINUE + +C print a character plot of the input matrix. This is only +C reasonable because the matrix is small. + PRINT 31 +31 FORMAT ('Plot of input matrix pattern:') + DO 50 J = 1,N + DO 30 I = 1,N + A (I, J) = '.' +30 CONTINUE +C add the diagonal entry to the plot + A (J, J) = 'X' + DO 40 P = AP (J), AP (J+1) - 1 + I = AI (P) + A (I, J) = 'X' +40 CONTINUE +50 CONTINUE + PRINT 60, ((MOD (J, 10)), J = 1,N) +60 FORMAT (' ', 24I2) + DO 80 I = 1,N + PRINT 70, I, (A (I, J), J = 1,N) +70 FORMAT (' ', I2, ': ', 24A2) +80 CONTINUE + + DO 190 METHOD = 1,2 + +C load the matrix into AMD's workspace + DO 90 J = 1,N + PE (J) = AP (J) + LEN (J) = AP (J+1) - AP (J) +90 CONTINUE + DO 100 P = 1,NZ + IW (P) = AI (P) +100 CONTINUE + PFREE = NZ + 1 + +C order the matrix using AMD or AMDBAR + IF (METHOD .EQ. 1) THEN + PRINT 101 +101 FORMAT (/, '------------------------------------------', + $ /, 'ordering the matrix with AMD', + $ /, '------------------------------------------') + CALL AMD (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ PERM, HEAD, PINV, DEGREE, NCMPA, W) + ELSE + PRINT 102 +102 FORMAT (/, '------------------------------------------', + $ /, 'ordering the matrix with AMDBAR', + $ /, '------------------------------------------') + CALL AMDBAR (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ PERM, HEAD, PINV, DEGREE, NCMPA, W) + ENDIF + +C print the permutation vector, PERM, and its inverse, PINV. +C row/column J = PERM (K) is the Kth row/column in the +C permuted matrix. + PRINT 110, (PERM (K), K = 1,N) +110 FORMAT (/, 'Permutation vector: ', /, 24I3) + PRINT 120, (PINV (J), J = 1,N) +120 FORMAT (/, 'Inverse permutation vector: ', /, 24I3) + +C print a character plot of the permuted matrix. + PRINT 121 +121 FORMAT ('Plot of permuted matrix pattern:') + DO 150 JNEW = 1,N + J = PERM (JNEW) + DO 130 INEW = 1,N + A (INEW, JNEW) = '.' +130 CONTINUE +C add the diagonal entry to the plot + A (JNEW, JNEW) = 'X' + DO 140 P = AP (J), AP (J+1) - 1 + INEW = PINV (AI (P)) + A (INEW, JNEW) = 'X' +140 CONTINUE +150 CONTINUE + PRINT 60, ((MOD (J, 10)), J = 1,N) + DO 160 I = 1,N + PRINT 70, I, (A (I, J), J = 1,N) +160 CONTINUE + +C print the permuted matrix, PERM*A*PERM' + DO 180 JNEW = 1,N + J = PERM (JNEW) + PRINT 171, JNEW, J, AP (J+1) - AP (J) +171 FORMAT (/, 'New column: ', I2, ' old column: ', I2, + $ ' number of entries: ', I2) + PRINT 170, (PINV (AI (P)), P = AP (J), AP (J+1) - 1) +170 FORMAT (' new row indices: ', 24I3) +180 CONTINUE +190 CONTINUE + END diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.out b/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.out new file mode 100644 index 0000000..10758dd --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77demo.out @@ -0,0 +1,318 @@ +AMD Fortran 77 demo, with the 24-by-24 Harwell/Boeing matrix, can_24: +Input matrix: 24-by-24 with 136 entries +Note that the Fortran version of AMD requires that +no diagonal entries be present. + +Column: 1 number of entries: 8 with row indices in AI ( 1 ... 8) + row indices: 6 7 13 14 18 19 20 22 + +Column: 2 number of entries: 5 with row indices in AI ( 9 ... 13) + row indices: 9 10 14 15 18 + +Column: 3 number of entries: 5 with row indices in AI ( 14 ... 18) + row indices: 7 12 21 22 23 + +Column: 4 number of entries: 5 with row indices in AI ( 19 ... 23) + row indices: 8 11 16 19 20 + +Column: 5 number of entries: 5 with row indices in AI ( 24 ... 28) + row indices: 8 10 15 16 17 + +Column: 6 number of entries: 5 with row indices in AI ( 29 ... 33) + row indices: 1 7 13 14 18 + +Column: 7 number of entries: 8 with row indices in AI ( 34 ... 41) + row indices: 1 3 6 12 13 20 22 24 + +Column: 8 number of entries: 8 with row indices in AI ( 42 ... 49) + row indices: 4 5 10 15 16 17 18 19 + +Column: 9 number of entries: 3 with row indices in AI ( 50 ... 52) + row indices: 2 10 15 + +Column: 10 number of entries: 8 with row indices in AI ( 53 ... 60) + row indices: 2 5 8 9 14 15 18 19 + +Column: 11 number of entries: 5 with row indices in AI ( 61 ... 65) + row indices: 4 19 20 21 22 + +Column: 12 number of entries: 5 with row indices in AI ( 66 ... 70) + row indices: 3 7 13 22 24 + +Column: 13 number of entries: 5 with row indices in AI ( 71 ... 75) + row indices: 1 6 7 12 24 + +Column: 14 number of entries: 5 with row indices in AI ( 76 ... 80) + row indices: 1 2 6 10 18 + +Column: 15 number of entries: 5 with row indices in AI ( 81 ... 85) + row indices: 2 5 8 9 10 + +Column: 16 number of entries: 5 with row indices in AI ( 86 ... 90) + row indices: 4 5 8 17 19 + +Column: 17 number of entries: 3 with row indices in AI ( 91 ... 93) + row indices: 5 8 16 + +Column: 18 number of entries: 8 with row indices in AI ( 94 ... 101) + row indices: 1 2 6 8 10 14 19 20 + +Column: 19 number of entries: 8 with row indices in AI (102 ... 109) + row indices: 1 4 8 10 11 16 18 20 + +Column: 20 number of entries: 8 with row indices in AI (110 ... 117) + row indices: 1 4 7 11 18 19 21 22 + +Column: 21 number of entries: 5 with row indices in AI (118 ... 122) + row indices: 3 11 20 22 23 + +Column: 22 number of entries: 8 with row indices in AI (123 ... 130) + row indices: 1 3 7 11 12 20 21 23 + +Column: 23 number of entries: 3 with row indices in AI (131 ... 133) + row indices: 3 21 22 + +Column: 24 number of entries: 3 with row indices in AI (134 ... 136) + row indices: 7 12 13 +Plot of input matrix pattern: + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 + 1: X . . . . X X . . . . . X X . . . X X X . X . . + 2: . X . . . . . . X X . . . X X . . X . . . . . . + 3: . . X . . . X . . . . X . . . . . . . . X X X . + 4: . . . X . . . X . . X . . . . X . . X X . . . . + 5: . . . . X . . X . X . . . . X X X . . . . . . . + 6: X . . . . X X . . . . . X X . . . X . . . . . . + 7: X . X . . X X . . . . X X . . . . . . X . X . X + 8: . . . X X . . X . X . . . . X X X X X . . . . . + 9: . X . . . . . . X X . . . . X . . . . . . . . . + 10: . X . . X . . X X X . . . X X . . X X . . . . . + 11: . . . X . . . . . . X . . . . . . . X X X X . . + 12: . . X . . . X . . . . X X . . . . . . . . X . X + 13: X . . . . X X . . . . X X . . . . . . . . . . X + 14: X X . . . X . . . X . . . X . . . X . . . . . . + 15: . X . . X . . X X X . . . . X . . . . . . . . . + 16: . . . X X . . X . . . . . . . X X . X . . . . . + 17: . . . . X . . X . . . . . . . X X . . . . . . . + 18: X X . . . X . X . X . . . X . . . X X X . . . . + 19: X . . X . . . X . X X . . . . X . X X X . . . . + 20: X . . X . . X . . . X . . . . . . X X X X X . . + 21: . . X . . . . . . . X . . . . . . . . X X X X . + 22: X . X . . . X . . . X X . . . . . . . X X X X . + 23: . . X . . . . . . . . . . . . . . . . . X X X . + 24: . . . . . . X . . . . X X . . . . . . . . . . X + +------------------------------------------ +ordering the matrix with AMD +------------------------------------------ + +Permutation vector: + 24 23 17 9 15 5 21 13 6 11 16 8 2 10 14 18 1 3 4 19 7 12 22 20 + +Inverse permutation vector: + 17 13 18 19 6 9 21 12 4 14 10 22 8 15 5 11 3 16 20 24 7 23 2 1 +Plot of permuted matrix pattern: + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 + 1: X . . . . . . X . . . . . . . . . . . . X X . . + 2: . X . . . . X . . . . . . . . . . X . . . . X . + 3: . . X . . X . . . . X X . . . . . . . . . . . . + 4: . . . X X . . . . . . . X X . . . . . . . . . . + 5: . . . X X X . . . . . X X X . . . . . . . . . . + 6: . . X . X X . . . . X X . X . . . . . . . . . . + 7: . X . . . . X . . X . . . . . . . X . . . . X X + 8: X . . . . . . X X . . . . . . . X . . . X X . . + 9: . . . . . . . X X . . . . . X X X . . . X . . . + 10: . . . . . . X . . X . . . . . . . . X X . . X X + 11: . . X . . X . . . . X X . . . . . . X X . . . . + 12: . . X . X X . . . . X X . X . X . . X X . . . . + 13: . . . X X . . . . . . . X X X X . . . . . . . . + 14: . . . X X X . . . . . X X X X X . . . X . . . . + 15: . . . . . . . . X . . . X X X X X . . . . . . . + 16: . . . . . . . . X . . X X X X X X . . X . . . X + 17: . . . . . . . X X . . . . . X X X . . X X . X X + 18: . X . . . . X . . . . . . . . . . X . . X X X . + 19: . . . . . . . . . X X X . . . . . . X X . . . X + 20: . . . . . . . . . X X X . X . X X . X X . . . X + 21: X . . . . . . X X . . . . . . . X X . . X X X X + 22: X . . . . . . X . . . . . . . . . X . . X X X . + 23: . X . . . . X . . X . . . . . . X X . . X X X X + 24: . . . . . . X . . X . . . . . X X . X X X . X X + +New column: 1 old column: 24 number of entries: 3 + new row indices: 21 22 8 + +New column: 2 old column: 23 number of entries: 3 + new row indices: 18 7 23 + +New column: 3 old column: 17 number of entries: 3 + new row indices: 6 12 11 + +New column: 4 old column: 9 number of entries: 3 + new row indices: 13 14 5 + +New column: 5 old column: 15 number of entries: 5 + new row indices: 13 6 12 4 14 + +New column: 6 old column: 5 number of entries: 5 + new row indices: 12 14 5 11 3 + +New column: 7 old column: 21 number of entries: 5 + new row indices: 18 10 24 23 2 + +New column: 8 old column: 13 number of entries: 5 + new row indices: 17 9 21 22 1 + +New column: 9 old column: 6 number of entries: 5 + new row indices: 17 21 8 15 16 + +New column: 10 old column: 11 number of entries: 5 + new row indices: 19 20 24 7 23 + +New column: 11 old column: 16 number of entries: 5 + new row indices: 19 6 12 3 20 + +New column: 12 old column: 8 number of entries: 8 + new row indices: 19 6 14 5 11 3 16 20 + +New column: 13 old column: 2 number of entries: 5 + new row indices: 4 14 15 5 16 + +New column: 14 old column: 10 number of entries: 8 + new row indices: 13 6 12 4 15 5 16 20 + +New column: 15 old column: 14 number of entries: 5 + new row indices: 17 13 9 14 16 + +New column: 16 old column: 18 number of entries: 8 + new row indices: 17 13 9 12 14 15 20 24 + +New column: 17 old column: 1 number of entries: 8 + new row indices: 9 21 8 15 16 20 24 23 + +New column: 18 old column: 3 number of entries: 5 + new row indices: 21 22 7 23 2 + +New column: 19 old column: 4 number of entries: 5 + new row indices: 12 10 11 20 24 + +New column: 20 old column: 19 number of entries: 8 + new row indices: 17 19 12 14 10 11 16 24 + +New column: 21 old column: 7 number of entries: 8 + new row indices: 17 18 9 22 8 24 23 1 + +New column: 22 old column: 12 number of entries: 5 + new row indices: 18 21 8 23 1 + +New column: 23 old column: 22 number of entries: 8 + new row indices: 17 18 21 10 22 24 7 2 + +New column: 24 old column: 20 number of entries: 8 + new row indices: 17 19 21 10 16 20 7 23 + +------------------------------------------ +ordering the matrix with AMDBAR +------------------------------------------ + +Permutation vector: + 24 23 17 9 15 5 21 13 6 11 16 8 2 10 14 18 1 3 4 19 7 12 22 20 + +Inverse permutation vector: + 17 13 18 19 6 9 21 12 4 14 10 22 8 15 5 11 3 16 20 24 7 23 2 1 +Plot of permuted matrix pattern: + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 + 1: X . . . . . . X . . . . . . . . . . . . X X . . + 2: . X . . . . X . . . . . . . . . . X . . . . X . + 3: . . X . . X . . . . X X . . . . . . . . . . . . + 4: . . . X X . . . . . . . X X . . . . . . . . . . + 5: . . . X X X . . . . . X X X . . . . . . . . . . + 6: . . X . X X . . . . X X . X . . . . . . . . . . + 7: . X . . . . X . . X . . . . . . . X . . . . X X + 8: X . . . . . . X X . . . . . . . X . . . X X . . + 9: . . . . . . . X X . . . . . X X X . . . X . . . + 10: . . . . . . X . . X . . . . . . . . X X . . X X + 11: . . X . . X . . . . X X . . . . . . X X . . . . + 12: . . X . X X . . . . X X . X . X . . X X . . . . + 13: . . . X X . . . . . . . X X X X . . . . . . . . + 14: . . . X X X . . . . . X X X X X . . . X . . . . + 15: . . . . . . . . X . . . X X X X X . . . . . . . + 16: . . . . . . . . X . . X X X X X X . . X . . . X + 17: . . . . . . . X X . . . . . X X X . . X X . X X + 18: . X . . . . X . . . . . . . . . . X . . X X X . + 19: . . . . . . . . . X X X . . . . . . X X . . . X + 20: . . . . . . . . . X X X . X . X X . X X . . . X + 21: X . . . . . . X X . . . . . . . X X . . X X X X + 22: X . . . . . . X . . . . . . . . . X . . X X X . + 23: . X . . . . X . . X . . . . . . X X . . X X X X + 24: . . . . . . X . . X . . . . . X X . X X X . X X + +New column: 1 old column: 24 number of entries: 3 + new row indices: 21 22 8 + +New column: 2 old column: 23 number of entries: 3 + new row indices: 18 7 23 + +New column: 3 old column: 17 number of entries: 3 + new row indices: 6 12 11 + +New column: 4 old column: 9 number of entries: 3 + new row indices: 13 14 5 + +New column: 5 old column: 15 number of entries: 5 + new row indices: 13 6 12 4 14 + +New column: 6 old column: 5 number of entries: 5 + new row indices: 12 14 5 11 3 + +New column: 7 old column: 21 number of entries: 5 + new row indices: 18 10 24 23 2 + +New column: 8 old column: 13 number of entries: 5 + new row indices: 17 9 21 22 1 + +New column: 9 old column: 6 number of entries: 5 + new row indices: 17 21 8 15 16 + +New column: 10 old column: 11 number of entries: 5 + new row indices: 19 20 24 7 23 + +New column: 11 old column: 16 number of entries: 5 + new row indices: 19 6 12 3 20 + +New column: 12 old column: 8 number of entries: 8 + new row indices: 19 6 14 5 11 3 16 20 + +New column: 13 old column: 2 number of entries: 5 + new row indices: 4 14 15 5 16 + +New column: 14 old column: 10 number of entries: 8 + new row indices: 13 6 12 4 15 5 16 20 + +New column: 15 old column: 14 number of entries: 5 + new row indices: 17 13 9 14 16 + +New column: 16 old column: 18 number of entries: 8 + new row indices: 17 13 9 12 14 15 20 24 + +New column: 17 old column: 1 number of entries: 8 + new row indices: 9 21 8 15 16 20 24 23 + +New column: 18 old column: 3 number of entries: 5 + new row indices: 21 22 7 23 2 + +New column: 19 old column: 4 number of entries: 5 + new row indices: 12 10 11 20 24 + +New column: 20 old column: 19 number of entries: 8 + new row indices: 17 19 12 14 10 11 16 24 + +New column: 21 old column: 7 number of entries: 8 + new row indices: 17 18 9 22 8 24 23 1 + +New column: 22 old column: 12 number of entries: 5 + new row indices: 18 21 8 23 1 + +New column: 23 old column: 22 number of entries: 8 + new row indices: 17 18 21 10 22 24 7 2 + +New column: 24 old column: 20 number of entries: 8 + new row indices: 17 19 21 10 16 20 7 23 diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.f b/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.f new file mode 100644 index 0000000..398681b --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.f @@ -0,0 +1,38 @@ +C ---------------------------------------------------------------------- +C AMD, Copyright (c) by Timothy A. Davis, Patrick R. +C Amestoy, and Iain S. Duff. See ../README.txt for +C License. email: davis at cise.ufl.edu CISE Department, Univ. of +C Florida. web: http://www.cise.ufl.edu/research/sparse/amd +C ---------------------------------------------------------------------- + +C This program provides an example of how to call the Fortran version +C of AMD. It uses the same matrix as the amd_simple.c demo (in C). +C Note that the diagonal entries are not present, and the matrix is +C symmetric. + + INTEGER N, NZ, J, K, P, IWLEN, PFREE, NCMPA + PARAMETER (N = 5, NZ = 10, IWLEN = 17) + INTEGER AP (N+1), AI (NZ), LAST (N), PE (N), LEN (N), ELEN (N), + $ IW (IWLEN), DEGREE (N), NV (N), NEXT (N), HEAD (N), W (N) + DATA AP / 1, 2, 5, 8, 9, 11/ + DATA AI / 2, 1,3,5, 2,4,5, 3, 2,3 / + +C load the matrix into the AMD workspace + DO 10 J = 1,N + PE (J) = AP (J) + LEN (J) = AP (J+1) - AP (J) +10 CONTINUE + DO 20 P = 1,NZ + IW (P) = AI (P) +20 CONTINUE + PFREE = NZ + 1 + +C order the matrix (destroys the copy of A in IW, PE, and LEN) + CALL AMD (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, LAST, HEAD, + $ ELEN, DEGREE, NCMPA, W) + + DO 60 K = 1, N + PRINT 50, K, LAST (K) +50 FORMAT ('P (',I2,') = ', I2) +60 CONTINUE + END diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.out b/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.out new file mode 100644 index 0000000..c7f902e --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77simple.out @@ -0,0 +1,5 @@ +P ( 1) = 4 +P ( 2) = 1 +P ( 3) = 3 +P ( 4) = 5 +P ( 5) = 2 diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_f77wrapper.c b/OpenDSSC/klusolve/AMD/Demo/amd_f77wrapper.c new file mode 100644 index 0000000..eb1cd54 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_f77wrapper.c @@ -0,0 +1,96 @@ +/* ========================================================================= */ +/* === amd_f77wrapper ====================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Copyright (c) by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Fortran interface for the C-callable AMD library (int version only). This + * is HIGHLY non-portable. You will need to modify this depending on how your + * Fortran and C compilers behave. Two examples are provided. + * + * To avoid using I/O, and to avoid the extra porting step of a Fortran + * function, the status code is returned as the first entry in P (P [0] in C + * and P (1) in Fortran) if an error occurs. The error codes are negative + * (-1: out of memory, -2: invalid matrix). + * + * For some C and Fortran compilers, the Fortran compiler appends a single "_" + * after each routine name. C doesn't do this, so the translation is made + * here. Some Fortran compilers don't append an underscore (xlf on IBM AIX, + * for * example). + * + * Tested with the following compilers: + * Solaris with cc and f77 from Sun WorkShop 6 update 1. + * SGI Irix with MIPSpro cc and f77 compilers version 7.4 + * Linux with GNU gcc or Intel's icc, and GNU g77 Intel's ifc Fortran compiler. + * (any combination). Note that with g77, a call to amd_order in Fortran + * gets translated to a call to amd_order__, with two underscores ("_"). + * Thus, the Fortran names do not include an underscore. + */ + +#include "amd.h" +#include + +/* ------------------------------------------------------------------------- */ +/* Linux, Solaris, SGI */ +/* ------------------------------------------------------------------------- */ + +void amdorder_ (int *n, const int *Ap, const int *Ai, int *P, + double *Control, double *Info) +{ + int result = amd_order (*n, Ap, Ai, P, Control, Info) ; + if (result != AMD_OK && P) P [0] = result ; +} + +void amddefaults_ (double *Control) +{ + amd_defaults (Control) ; +} + +void amdcontrol_ (double *Control) +{ + fflush (stdout) ; + amd_control (Control) ; + fflush (stdout) ; +} + +void amdinfo_ (double *Info) +{ + fflush (stdout) ; + amd_info (Info) ; + fflush (stdout) ; +} + +/* ------------------------------------------------------------------------- */ +/* IBM AIX. Probably Windows, Compaq Alpha, and HP Unix as well. */ +/* ------------------------------------------------------------------------- */ + +void amdorder (int *n, const int *Ap, const int *Ai, int *P, + double *Control, double *Info) +{ + int result = amd_order (*n, Ap, Ai, P, Control, Info) ; + if (result != AMD_OK && P) P [0] = result ; +} + +void amddefaults (double *Control) +{ + amd_defaults (Control) ; +} + +void amdcontrol (double *Control) +{ + fflush (stdout) ; + amd_control (Control) ; + fflush (stdout) ; +} + +void amdinfo (double *Info) +{ + fflush (stdout) ; + amd_info (Info) ; + fflush (stdout) ; +} diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.c b/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.c new file mode 100644 index 0000000..342f085 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.c @@ -0,0 +1,179 @@ +/* ========================================================================= */ +/* === AMD demo main program (UF_long integer version) ===================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Copyright (c) by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* A simple C main program that illustrates the use of the ANSI C interface + * to AMD. + */ + +#include "amd.h" +#include +#include +#include "UFconfig.h" + +int main (void) +{ + /* The symmetric can_24 Harwell/Boeing matrix, including upper and lower + * triangular parts, and the diagonal entries. Note that this matrix is + * 0-based, with row and column indices in the range 0 to n-1. */ + UF_long n = 24, nz, + Ap [ ] = { 0, 9, 15, 21, 27, 33, 39, 48, 57, 61, 70, 76, 82, 88, 94, 100, + 106, 110, 119, 128, 137, 143, 152, 156, 160 }, + Ai [ ] = { + /* column 0: */ 0, 5, 6, 12, 13, 17, 18, 19, 21, + /* column 1: */ 1, 8, 9, 13, 14, 17, + /* column 2: */ 2, 6, 11, 20, 21, 22, + /* column 3: */ 3, 7, 10, 15, 18, 19, + /* column 4: */ 4, 7, 9, 14, 15, 16, + /* column 5: */ 0, 5, 6, 12, 13, 17, + /* column 6: */ 0, 2, 5, 6, 11, 12, 19, 21, 23, + /* column 7: */ 3, 4, 7, 9, 14, 15, 16, 17, 18, + /* column 8: */ 1, 8, 9, 14, + /* column 9: */ 1, 4, 7, 8, 9, 13, 14, 17, 18, + /* column 10: */ 3, 10, 18, 19, 20, 21, + /* column 11: */ 2, 6, 11, 12, 21, 23, + /* column 12: */ 0, 5, 6, 11, 12, 23, + /* column 13: */ 0, 1, 5, 9, 13, 17, + /* column 14: */ 1, 4, 7, 8, 9, 14, + /* column 15: */ 3, 4, 7, 15, 16, 18, + /* column 16: */ 4, 7, 15, 16, + /* column 17: */ 0, 1, 5, 7, 9, 13, 17, 18, 19, + /* column 18: */ 0, 3, 7, 9, 10, 15, 17, 18, 19, + /* column 19: */ 0, 3, 6, 10, 17, 18, 19, 20, 21, + /* column 20: */ 2, 10, 19, 20, 21, 22, + /* column 21: */ 0, 2, 6, 10, 11, 19, 20, 21, 22, + /* column 22: */ 2, 20, 21, 22, + /* column 23: */ 6, 11, 12, 23 } ; + + UF_long P [24], Pinv [24], i, j, k, jnew, p, inew, result ; + double Control [AMD_CONTROL], Info [AMD_INFO] ; + char A [24][24] ; + + /* here is an example of how to use AMD_VERSION. This code will work in + * any version of AMD. */ +#if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE(1,2)) + printf ("AMD version %d.%d, date: %s\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, + AMD_DATE) ; +#else + printf ("AMD version: 1.1 or earlier\n") ; +#endif + + printf ("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:\n") ; + + /* get the default parameters, and print them */ + amd_l_defaults (Control) ; + amd_l_control (Control) ; + + /* print the input matrix */ + nz = Ap [n] ; + printf ("\nInput matrix: %ld-by-%ld, with %ld entries.\n" + " Note that for a symmetric matrix such as this one, only the\n" + " strictly lower or upper triangular parts would need to be\n" + " passed to AMD, since AMD computes the ordering of A+A'. The\n" + " diagonal entries are also not needed, since AMD ignores them.\n" + , n, n, nz) ; + for (j = 0 ; j < n ; j++) + { + printf ("\nColumn: %ld, number of entries: %ld, with row indices in" + " Ai [%ld ... %ld]:\n row indices:", + j, Ap [j+1] - Ap [j], Ap [j], Ap [j+1]-1) ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + printf (" %ld", i) ; + } + printf ("\n") ; + } + + /* print a character plot of the input matrix. This is only reasonable + * because the matrix is small. */ + printf ("\nPlot of input matrix pattern:\n") ; + for (j = 0 ; j < n ; j++) + { + for (i = 0 ; i < n ; i++) A [i][j] = '.' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + A [i][j] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1ld", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2ld: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + /* order the matrix */ + result = amd_l_order (n, Ap, Ai, P, Control, Info) ; + printf ("return value from amd_l_order: %ld (should be %d)\n", + result, AMD_OK) ; + + /* print the statistics */ + amd_l_info (Info) ; + + if (result != AMD_OK) + { + printf ("AMD failed\n") ; + exit (1) ; + } + + /* print the permutation vector, P, and compute the inverse permutation */ + printf ("Permutation vector:\n") ; + for (k = 0 ; k < n ; k++) + { + /* row/column j is the kth row/column in the permuted matrix */ + j = P [k] ; + Pinv [j] = k ; + printf (" %2ld", j) ; + } + printf ("\n\n") ; + + printf ("Inverse permutation vector:\n") ; + for (j = 0 ; j < n ; j++) + { + k = Pinv [j] ; + printf (" %2ld", k) ; + } + printf ("\n\n") ; + + /* print a character plot of the permuted matrix. */ + printf ("\nPlot of permuted matrix pattern:\n") ; + for (jnew = 0 ; jnew < n ; jnew++) + { + j = P [jnew] ; + for (inew = 0 ; inew < n ; inew++) A [inew][jnew] = '.' ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + inew = Pinv [Ai [p]] ; + A [inew][jnew] = 'X' ; + } + } + printf (" ") ; + for (j = 0 ; j < n ; j++) printf (" %1ld", j % 10) ; + printf ("\n") ; + for (i = 0 ; i < n ; i++) + { + printf ("%2ld: ", i) ; + for (j = 0 ; j < n ; j++) + { + printf (" %c", A [i][j]) ; + } + printf ("\n") ; + } + + return (0) ; +} diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.out b/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.out new file mode 100644 index 0000000..80b574f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_l_demo.out @@ -0,0 +1,179 @@ +AMD version 2.2, date: Dec 7, 2011 +AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24: + +AMD version 2.2.3, Dec 7, 2011: approximate minimum degree ordering + dense row parameter: 10 + (rows with more than max (10 * sqrt (n), 16) entries are + considered "dense", and placed last in output permutation) + aggressive absorption: yes + size of AMD integer: 8 + + +Input matrix: 24-by-24, with 160 entries. + Note that for a symmetric matrix such as this one, only the + strictly lower or upper triangular parts would need to be + passed to AMD, since AMD computes the ordering of A+A'. The + diagonal entries are also not needed, since AMD ignores them. + +Column: 0, number of entries: 9, with row indices in Ai [0 ... 8]: + row indices: 0 5 6 12 13 17 18 19 21 + +Column: 1, number of entries: 6, with row indices in Ai [9 ... 14]: + row indices: 1 8 9 13 14 17 + +Column: 2, number of entries: 6, with row indices in Ai [15 ... 20]: + row indices: 2 6 11 20 21 22 + +Column: 3, number of entries: 6, with row indices in Ai [21 ... 26]: + row indices: 3 7 10 15 18 19 + +Column: 4, number of entries: 6, with row indices in Ai [27 ... 32]: + row indices: 4 7 9 14 15 16 + +Column: 5, number of entries: 6, with row indices in Ai [33 ... 38]: + row indices: 0 5 6 12 13 17 + +Column: 6, number of entries: 9, with row indices in Ai [39 ... 47]: + row indices: 0 2 5 6 11 12 19 21 23 + +Column: 7, number of entries: 9, with row indices in Ai [48 ... 56]: + row indices: 3 4 7 9 14 15 16 17 18 + +Column: 8, number of entries: 4, with row indices in Ai [57 ... 60]: + row indices: 1 8 9 14 + +Column: 9, number of entries: 9, with row indices in Ai [61 ... 69]: + row indices: 1 4 7 8 9 13 14 17 18 + +Column: 10, number of entries: 6, with row indices in Ai [70 ... 75]: + row indices: 3 10 18 19 20 21 + +Column: 11, number of entries: 6, with row indices in Ai [76 ... 81]: + row indices: 2 6 11 12 21 23 + +Column: 12, number of entries: 6, with row indices in Ai [82 ... 87]: + row indices: 0 5 6 11 12 23 + +Column: 13, number of entries: 6, with row indices in Ai [88 ... 93]: + row indices: 0 1 5 9 13 17 + +Column: 14, number of entries: 6, with row indices in Ai [94 ... 99]: + row indices: 1 4 7 8 9 14 + +Column: 15, number of entries: 6, with row indices in Ai [100 ... 105]: + row indices: 3 4 7 15 16 18 + +Column: 16, number of entries: 4, with row indices in Ai [106 ... 109]: + row indices: 4 7 15 16 + +Column: 17, number of entries: 9, with row indices in Ai [110 ... 118]: + row indices: 0 1 5 7 9 13 17 18 19 + +Column: 18, number of entries: 9, with row indices in Ai [119 ... 127]: + row indices: 0 3 7 9 10 15 17 18 19 + +Column: 19, number of entries: 9, with row indices in Ai [128 ... 136]: + row indices: 0 3 6 10 17 18 19 20 21 + +Column: 20, number of entries: 6, with row indices in Ai [137 ... 142]: + row indices: 2 10 19 20 21 22 + +Column: 21, number of entries: 9, with row indices in Ai [143 ... 151]: + row indices: 0 2 6 10 11 19 20 21 22 + +Column: 22, number of entries: 4, with row indices in Ai [152 ... 155]: + row indices: 2 20 21 22 + +Column: 23, number of entries: 4, with row indices in Ai [156 ... 159]: + row indices: 6 11 12 23 + +Plot of input matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X . . . . X X . . . . . X X . . . X X X . X . . + 1: . X . . . . . . X X . . . X X . . X . . . . . . + 2: . . X . . . X . . . . X . . . . . . . . X X X . + 3: . . . X . . . X . . X . . . . X . . X X . . . . + 4: . . . . X . . X . X . . . . X X X . . . . . . . + 5: X . . . . X X . . . . . X X . . . X . . . . . . + 6: X . X . . X X . . . . X X . . . . . . X . X . X + 7: . . . X X . . X . X . . . . X X X X X . . . . . + 8: . X . . . . . . X X . . . . X . . . . . . . . . + 9: . X . . X . . X X X . . . X X . . X X . . . . . +10: . . . X . . . . . . X . . . . . . . X X X X . . +11: . . X . . . X . . . . X X . . . . . . . . X . X +12: X . . . . X X . . . . X X . . . . . . . . . . X +13: X X . . . X . . . X . . . X . . . X . . . . . . +14: . X . . X . . X X X . . . . X . . . . . . . . . +15: . . . X X . . X . . . . . . . X X . X . . . . . +16: . . . . X . . X . . . . . . . X X . . . . . . . +17: X X . . . X . X . X . . . X . . . X X X . . . . +18: X . . X . . . X . X X . . . . X . X X X . . . . +19: X . . X . . X . . . X . . . . . . X X X X X . . +20: . . X . . . . . . . X . . . . . . . . X X X X . +21: X . X . . . X . . . X X . . . . . . . X X X X . +22: . . X . . . . . . . . . . . . . . . . . X X X . +23: . . . . . . X . . . . X X . . . . . . . . . . X +return value from amd_l_order: 0 (should be 0) + +AMD version 2.2.3, Dec 7, 2011, results: + status: OK + n, dimension of A: 24 + nz, number of nonzeros in A: 160 + symmetry of A: 1.0000 + number of nonzeros on diagonal: 24 + nonzeros in pattern of A+A' (excl. diagonal): 136 + # dense rows/columns of A+A': 0 + memory used, in bytes: 3032 + # of memory compactions: 0 + + The following approximate statistics are for a subsequent + factorization of A(P,P) + A(P,P)'. They are slight upper + bounds if there are no dense rows/columns in A+A', and become + looser if dense rows/columns exist. + + nonzeros in L (excluding diagonal): 97 + nonzeros in L (including diagonal): 121 + # divide operations for LDL' or LU: 97 + # multiply-subtract operations for LDL': 275 + # multiply-subtract operations for LU: 453 + max nz. in any column of L (incl. diagonal): 8 + + chol flop count for real A, sqrt counted as 1 flop: 671 + LDL' flop count for real A: 647 + LDL' flop count for complex A: 3073 + LU flop count for real A (with no pivoting): 1003 + LU flop count for complex A (with no pivoting): 4497 + +Permutation vector: + 22 20 10 23 12 5 16 8 14 4 15 7 1 9 13 17 0 2 3 6 11 18 21 19 + +Inverse permutation vector: + 16 12 17 18 9 5 19 11 7 13 2 20 4 14 8 10 6 15 21 23 1 22 0 3 + + +Plot of permuted matrix pattern: + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + 0: X X . . . . . . . . . . . . . . . X . . . . X . + 1: X X X . . . . . . . . . . . . . . X . . . . X X + 2: . X X . . . . . . . . . . . . . . . X . . X X X + 3: . . . X X . . . . . . . . . . . . . . X X . . . + 4: . . . X X X . . . . . . . . . . X . . X X . . . + 5: . . . . X X . . . . . . . . X X X . . X . . . . + 6: . . . . . . X . . X X X . . . . . . . . . . . . + 7: . . . . . . . X X . . . X X . . . . . . . . . . + 8: . . . . . . . X X X . X X X . . . . . . . . . . + 9: . . . . . . X . X X X X . X . . . . . . . . . . +10: . . . . . . X . . X X X . . . . . . X . . X . . +11: . . . . . . X . X X X X . X . X . . X . . X . . +12: . . . . . . . X X . . . X X X X . . . . . . . . +13: . . . . . . . X X X . X X X X X . . . . . X . . +14: . . . . . X . . . . . . X X X X X . . . . . . . +15: . . . . . X . . . . . X X X X X X . . . . X . X +16: . . . . X X . . . . . . . . X X X . . X . X X X +17: X X . . . . . . . . . . . . . . . X . X X . X . +18: . . X . . . . . . . X X . . . . . . X . . X . X +19: . . . X X X . . . . . . . . . . X X . X X . X X +20: . . . X X . . . . . . . . . . . . X . X X . X . +21: . . X . . . . . . . X X . X . X X . X . . X . X +22: X X X . . . . . . . . . . . . . X X . X X . X X +23: . X X . . . . . . . . . . . . X X . X X . X X X diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_simple.c b/OpenDSSC/klusolve/AMD/Demo/amd_simple.c new file mode 100644 index 0000000..2eae945 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_simple.c @@ -0,0 +1,23 @@ +/* ------------------------------------------------------------------------- */ +/* AMD Copyright (c) by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +#include +#include "amd.h" + +int n = 5 ; +int Ap [ ] = { 0, 2, 6, 10, 12, 14} ; +int Ai [ ] = { 0,1, 0,1,2,4, 1,2,3,4, 2,3, 1,4 } ; +int P [5] ; + +int main (void) +{ + int k ; + (void) amd_order (n, Ap, Ai, P, (double *) NULL, (double *) NULL) ; + for (k = 0 ; k < n ; k++) printf ("P [%d] = %d\n", k, P [k]) ; + return (0) ; +} + diff --git a/OpenDSSC/klusolve/AMD/Demo/amd_simple.out b/OpenDSSC/klusolve/AMD/Demo/amd_simple.out new file mode 100644 index 0000000..08a04e0 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Demo/amd_simple.out @@ -0,0 +1,5 @@ +P [0] = 0 +P [1] = 3 +P [2] = 2 +P [3] = 4 +P [4] = 1 diff --git a/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.bib b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.bib new file mode 100644 index 0000000..03fbfa8 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.bib @@ -0,0 +1,98 @@ +@string{SIREV = "{SIAM} Review"} +@string{SIMAX = "{SIAM} J. Matrix Anal. Applic."} +@string{SIAMJSC = "{SIAM} J. Sci. Comput."} +@string{TOMS = "{ACM} Trans. Math. Softw."} + +@article{schu:01, + author = {J. Schulze}, + title = {Towards a tighter coupling of bottom-up and top-down sparse matrix ordering methods}, + journal = {BIT}, + volume = {41}, + number = {4}, + pages = "800--841", + year = {2001} + } + +@article{GeorgeLiu89, + author={George, A. and Liu, J. W. H.}, + year={1989}, + title={The Evolution of the Minimum Degree Ordering Algorithm}, + journal=SIREV, + volume={31}, + number={1}, + pages={1--19}} + +@article{AmestoyDavisDuff96, + author={Amestoy, P. R. and Davis, T. A. and Duff, I. S.}, + title={An approximate minimum degree ordering algorithm}, + journal=SIMAX, + year={1996} + ,volume={17} + ,number={4} + ,pages={886-905} + } + +@article{AmestoyDavisDuff04, + author={Amestoy, P. R. and Davis, T. A. and Duff, I. S.}, + title={Algorithm 837: An approximate minimum degree ordering algorithm}, + journal=TOMS, + year={2004} + ,volume={30} + ,number={3} + ,pages={381-388} + } + +@misc{hsl:2002, + author = {HSL}, + title = "{HSL} 2002: {A} collection of {F}ortran codes for large + scale scientific computation", + note = {{\tt www.cse.clrc.ac.uk/nag/hsl}}, + year = 2002} + + +@article{RothbergEisenstat98, + author={Rothberg, E. and Eisenstat, S. C.}, + title={Node selection strategies for bottom-up sparse matrix orderings}, + journal=SIMAX, + year={1998} + ,volume={19} + ,number={3} + ,pages={682-695} + } + +@article{KarypisKumar98e, + author={Karypis, G. and Kumar, V.}, + title={A fast and high quality multilevel scheme for partitioning irregular graphs}, + journal=SIAMJSC, + year={1998} + ,volume={20} + ,pages={359-392} + } + +@article{Chaco, + author={B. Hendrickson and E. Rothberg}, + title={Improving the runtime and quality of nested dissection ordering}, + journal=SIAMJSC, + year={1999} + ,volume={20} + ,pages={468--489} + } + +@article{PellegriniRomanAmestoy00, + author={Pellegrini, F. and Roman, J. and Amestoy, P.}, + title={Hybridizing nested dissection and halo approximate minimum degree for efficient sparse matrix ordering}, + journal={Concurrency: Practice and Experience}, + year={2000} + ,volume={12} + ,pages={68-84} + } + +@article{DavisGilbertLarimoreNg04, + author={Davis, T. A. and Gilbert, J. R. and Larimore, S. I. and Ng, E. G.}, + title={A column approximate minimum degree ordering algorithm}, + journal=TOMS, + year={2004} + ,volume={30} + ,pages={353-376} + } + diff --git a/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.pdf b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.pdf new file mode 100644 index 0000000..b643474 Binary files /dev/null and b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.pdf differ diff --git a/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.tex b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.tex new file mode 100644 index 0000000..d40ca76 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/AMD_UserGuide.tex @@ -0,0 +1,1205 @@ +\documentclass[11pt]{article} + +\newcommand{\m}[1]{{\bf{#1}}} % for matrices and vectors +\newcommand{\tr}{^{\sf T}} % transpose + +\topmargin 0in +\textheight 9in +\oddsidemargin 0pt +\evensidemargin 0pt +\textwidth 6.5in + +%------------------------------------------------------------------------------ +\begin{document} +%------------------------------------------------------------------------------ + +\title{AMD User Guide} +\author{Patrick R. Amestoy\thanks{ENSEEIHT-IRIT, +2 rue Camichel 31017 Toulouse, France. +email: amestoy@enseeiht.fr. http://www.enseeiht.fr/$\sim$amestoy.} +\and Timothy A. Davis\thanks{ +Dept.~of Computer and Information Science and Engineering, +Univ.~of Florida, Gainesville, FL, USA. +email: davis@cise.ufl.edu. +http://www.cise.ufl.edu/$\sim$davis. +This work was supported by the National +Science Foundation, under grants ASC-9111263, DMS-9223088, and CCR-0203270. +Portions of the work were done while on sabbatical at Stanford University +and Lawrence Berkeley National Laboratory (with funding from Stanford +University and the SciDAC program). +} +\and Iain S. Duff\thanks{Rutherford Appleton Laboratory, Chilton, Didcot, +Oxon OX11 0QX, England. email: i.s.duff@rl.ac.uk. +http://www.numerical.rl.ac.uk/people/isd/isd.html. +This work was supported by the EPSRC under grant GR/R46441. +}} + +\date{VERSION 2.2.3, Dec 7, 2011} +\maketitle + +%------------------------------------------------------------------------------ +\begin{abstract} +AMD is a set of routines that implements the approximate minimum degree ordering +algorithm to permute sparse matrices prior to +numerical factorization. +There are versions written in both C and Fortran 77. +A MATLAB interface is included. +\end{abstract} +%------------------------------------------------------------------------------ + +Technical report TR-04-002 (revised), CISE Department, University of Florida, +Gainesville, FL, 2007. + +AMD Copyright\copyright 2011 by Timothy A. +Davis, Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. +AMD is available under alternate licences; contact T. Davis for details. + +{\bf AMD License:} + Your use or distribution of AMD or any modified version of + AMD implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + +{\bf Availability:} + http://www.cise.ufl.edu/research/sparse/amd + +{\bf Acknowledgments:} + + This work was supported by the National Science Foundation, under + grants ASC-9111263 and DMS-9223088 and CCR-0203270. + The conversion to C, the addition of the elimination tree + post-ordering, and the handling of dense rows and columns + were done while Davis was on sabbatical at + Stanford University and Lawrence Berkeley National Laboratory. + +%------------------------------------------------------------------------------ +\newpage +\section{Overview} +%------------------------------------------------------------------------------ + +AMD is a set of routines for preordering a sparse matrix prior to +numerical factorization. It uses an approximate minimum degree ordering +algorithm \cite{AmestoyDavisDuff96,AmestoyDavisDuff04} +to find a permutation matrix $\m{P}$ +so that the Cholesky factorization $\m{PAP}\tr=\m{LL}\tr$ has fewer +(often much fewer) nonzero entries than the Cholesky factorization of $\m{A}$. +The algorithm is typically much faster than other ordering methods +and minimum degree ordering +algorithms that compute an exact degree \cite{GeorgeLiu89}. +Some methods, such as approximate deficiency +\cite{RothbergEisenstat98} and graph-partitioning based methods +\cite{Chaco,KarypisKumar98e,PellegriniRomanAmestoy00,schu:01} +can produce better orderings, depending on the matrix. + +The algorithm starts with an undirected graph representation of a +symmetric sparse matrix $\m{A}$. Node $i$ in the graph corresponds to row +and column $i$ of the matrix, and there is an edge $(i,j)$ in the graph if +$a_{ij}$ is nonzero. +The degree of a node is initialized to the number of off-diagonal nonzeros +in row $i$, which is the size of the set of nodes +adjacent to $i$ in the graph. + +The selection of a pivot $a_{ii}$ from the diagonal of $\m{A}$ and the first +step of Gaussian elimination corresponds to one step of graph elimination. +Numerical fill-in causes new nonzero entries in the matrix +(fill-in refers to +nonzeros in $\m{L}$ that are not in $\m{A}$). +Node $i$ is eliminated and edges are added to its neighbors +so that they form a clique (or {\em element}). To reduce fill-in, +node $i$ is selected as the node of least degree in the graph. +This process repeats until the graph is eliminated. + +The clique is represented implicitly. Rather than listing all the +new edges in the graph, a single list of nodes is kept which represents +the clique. This list corresponds to the nonzero pattern of the first +column of $\m{L}$. As the elimination proceeds, some of these cliques +become subsets of subsequent cliques, and are removed. This graph +can be stored in place, that is +using the same amount of memory as the original graph. + +The most costly part of the minimum degree algorithm is the recomputation +of the degrees of nodes adjacent to the current pivot element. +Rather than keep track of the exact degree, the approximate minimum degree +algorithm finds an upper bound on the degree that is easier to compute. +For nodes of least degree, this bound tends to be tight. Using the +approximate degree instead of the exact degree leads to a substantial savings +in run time, particularly for very irregularly structured matrices. +It has no effect on the quality of the ordering. + +In the C version of AMD, the elimination phase is followed by an +elimination tree post-ordering. This has no effect on fill-in, but +reorganizes the ordering so that the subsequent numerical factorization is +more efficient. It also includes a pre-processing phase in which nodes of +very high degree are removed (without causing fill-in), and placed last in the +permutation $\m{P}$. This reduces the run time substantially if the matrix +has a few rows with many nonzero entries, and has little effect on the quality +of the ordering. +The C version operates on the +symmetric nonzero pattern of $\m{A}+\m{A}\tr$, so it can be given +an unsymmetric matrix, or either the lower or upper triangular part of +a symmetric matrix. + +The two Fortran versions of AMD are essentially identical to two versions of +the AMD algorithm discussed in an earlier paper \cite{AmestoyDavisDuff96} +(approximate minimum external degree, both with and without aggressive +absorption). +For a discussion of the long history of the minimum degree algorithm, +see \cite{GeorgeLiu89}. + +%------------------------------------------------------------------------------ +\section{Availability} +%------------------------------------------------------------------------------ + +In addition to appearing as a Collected Algorithm of the ACM, \newline +AMD is available at http://www.cise.ufl.edu/research/sparse. +The Fortran version is available as the routine {\tt MC47} in HSL +(formerly the Harwell Subroutine Library) \cite{hsl:2002}. + +%------------------------------------------------------------------------------ +\section{Using AMD in MATLAB} +%------------------------------------------------------------------------------ + +The MATLAB function {\tt amd} is now a built-in function in MATLAB 7.3 +(R2006b). The built-in {\tt amd} and the {\tt amd2} function provided here +differ in how the optional parameters are passed +(the 2nd input parameter). + +To use AMD2 in MATLAB, you must first compile the AMD2 mexFunction. +Just type {\tt make} in the Unix system shell, while in the {\tt AMD/MATLAB} +directory. You can also type {\tt amd\_make} in MATLAB, while in the +{\tt AMD/MATLAB} directory. Place the {\tt AMD/MATLAB} directory in your +MATLAB path. This can be done on any system with MATLAB, including Windows. +See Section~\ref{Install} for more details on how to install AMD. + +The MATLAB statement {\tt p=amd(A)} finds a permutation vector {\tt p} such +that the Cholesky factorization {\tt chol(A(p,p))} is typically sparser than +{\tt chol(A)}. +If {\tt A} is unsymmetric, {\tt amd(A)} is identical to {\tt amd(A+A')} +(ignoring numerical cancellation). +If {\tt A} is not symmetric positive definite, +but has substantial diagonal entries and a mostly symmetric nonzero pattern, +then this ordering is also suitable for LU factorization. A partial pivoting +threshold may be required to prevent pivots from being selected off the +diagonal, such as the statement {\tt [L,U,P] = lu (A (p,p), 0.1)}. +Type {\tt help lu} for more details. +The statement {\tt [L,U,P,Q] = lu (A (p,p))} in MATLAB 6.5 is +not suitable, however, because it uses UMFPACK Version 4.0 and thus +does not attempt to select pivots from the diagonal. +UMFPACK Version 4.1 in MATLAB 7.0 and later +uses several strategies, including a symmetric pivoting strategy, and +will give you better results if you want to factorize an unsymmetric matrix +of this type. Refer to the UMFPACK User Guide for more details, at +http://www.cise.ufl.edu/research/sparse/umfpack. + +The AMD mexFunction is much faster than the built-in MATLAB symmetric minimum +degree ordering methods, SYMAMD and SYMMMD. Its ordering quality is +comparable to SYMAMD, and better than SYMMMD +\cite{DavisGilbertLarimoreNg04}. + +An optional input argument can be used to modify the control parameters for +AMD (aggressive absorption, dense row/column handling, and printing of +statistics). An optional output +argument provides statistics on the ordering, including an analysis of the +fill-in and the floating-point operation count for a subsequent factorization. +For more details (once AMD is installed), +type {\tt help amd} in the MATLAB command window. + +%------------------------------------------------------------------------------ +\section{Using AMD in a C program} +\label{Cversion} +%------------------------------------------------------------------------------ + +The C-callable AMD library consists of seven user-callable routines and one +include file. There are two versions of each of the routines, with +{\tt int} and {\tt long} integers. +The routines with prefix +{\tt amd\_l\_} use {\tt long} integer arguments; the others use +{\tt int} integer arguments. If you compile AMD in the standard +ILP32 mode (32-bit {\tt int}'s, {\tt long}'s, and pointers) then the versions +are essentially identical. You will be able to solve problems using up to 2GB +of memory. If you compile AMD in the standard LP64 mode, the size of an +{\tt int} remains 32-bits, but the size of a {\tt long} and a pointer both get +promoted to 64-bits. + +The following routines are fully described in Section~\ref{Primary}: + +\begin{itemize} +\item {\tt amd\_order} +({\tt long} version: {\tt amd\_l\_order}) + {\footnotesize + \begin{verbatim} + #include "amd.h" + int n, Ap [n+1], Ai [nz], P [n] ; + double Control [AMD_CONTROL], Info [AMD_INFO] ; + int result = amd_order (n, Ap, Ai, P, Control, Info) ; + \end{verbatim} + } + Computes the approximate minimum degree ordering of an $n$-by-$n$ matrix + $\m{A}$. Returns a permutation vector {\tt P} of size {\tt n}, where + {\tt P[k] = i} if row and column {\tt i} are the {\tt k}th row and + column in the permuted matrix. + This routine allocates its own memory of size $1.2e+9n$ integers, + where $e$ is the number of nonzeros in $\m{A}+\m{A}\tr$. + It computes statistics about the matrix $\m{A}$, such as the symmetry of + its nonzero pattern, the number of nonzeros in $\m{L}$, + and the number of floating-point operations required for Cholesky and LU + factorizations (which are returned in the {\tt Info} array). + The user's input matrix is not modified. + It returns {\tt AMD\_OK} if successful, + {\tt AMD\_OK\_BUT\_JUMBLED} if successful (but the matrix had unsorted + and/or duplicate row indices), + {\tt AMD\_INVALID} if the matrix is invalid, + {\tt AMD\_OUT\_OF\_MEMORY} if out of memory. + +\item {\tt amd\_defaults} +({\tt long} version: {\tt amd\_l\_defaults}) + {\footnotesize + \begin{verbatim} + #include "amd.h" + double Control [AMD_CONTROL] ; + amd_defaults (Control) ; + \end{verbatim} + } + Sets the default control parameters in the {\tt Control} array. These can + then be modified as desired before passing the array to the other AMD + routines. + +\item {\tt amd\_control} +({\tt long} version: {\tt amd\_l\_control}) + {\footnotesize + \begin{verbatim} + #include "amd.h" + double Control [AMD_CONTROL] ; + amd_control (Control) ; + \end{verbatim} + } + Prints a description of the control parameters, and their values. + +\item {\tt amd\_info} +({\tt long} version: {\tt amd\_l\_info}) + {\footnotesize + \begin{verbatim} + #include "amd.h" + double Info [AMD_INFO] ; + amd_info (Info) ; + \end{verbatim} + } + Prints a description of the statistics computed by AMD, and their values. + +\item {\tt amd\_valid} +({\tt long} version: {\tt amd\_valid}) + {\footnotesize + \begin{verbatim} + #include "amd.h" + int n, Ap [n+1], Ai [nz] ; + int result = amd_valid (n, n, Ap, Ai) ; + \end{verbatim} + } + Returns {\tt AMD\_OK} or {\tt AMD\_OK\_BUT\_JUMBLED} + if the matrix is valid as input to {\tt amd\_order}; + the latter is returned if the matrix has unsorted and/or duplicate + row indices in one or more columns. + Returns {\tt AMD\_INVALID} if the matrix cannot be passed to + {\tt amd\_order}. + For {\tt amd\_order}, the matrix must + also be square. The first two arguments are the number of rows and the + number of columns of the matrix. For its use in AMD, these must both + equal {\tt n}. + +\item {\tt amd\_2} +({\tt long} version: {\tt amd\_l2}) + AMD ordering kernel. It is faster than {\tt amd\_order}, and + can be called by the user, but it is difficult to use. + It does not check its inputs for errors. + It does not require the columns of its input matrix to be sorted, + but it destroys the matrix on output. Additional workspace must be passed. + Refer to the source file {\tt AMD/Source/amd\_2.c} for a description. + +\end{itemize} + +The nonzero pattern of the matrix $\m{A}$ is represented in compressed column +form. +For an $n$-by-$n$ matrix $\m{A}$ with {\tt nz} nonzero entries, the +representation consists of two arrays: {\tt Ap} of size {\tt n+1} and {\tt Ai} +of size {\tt nz}. The row indices of entries in column {\tt j} are stored in + {\tt Ai[Ap[j]} $\ldots$ {\tt Ap[j+1]-1]}. +For {\tt amd\_order}, +if duplicate row indices are present, or if the row indices in any given +column are not sorted in ascending order, then {\tt amd\_order} creates +an internal copy of the matrix with sorted rows and no duplicate entries, +and orders the copy. This adds slightly to the time and memory usage of +{\tt amd\_order}, but is not an error condition. + +The matrix is 0-based, and thus +row indices must be in the range {\tt 0} to {\tt n-1}. +The first entry {\tt Ap[0]} must be zero. +The total number of entries in the matrix is thus {\tt nz = Ap[n]}. + +The matrix must be square, but it does not need to be symmetric. +The {\tt amd\_order} routine constructs the nonzero pattern of +$\m{B} = \m{A}+\m{A}\tr$ (without forming $\m{A}\tr$ explicitly if +$\m{A}$ has sorted columns and no duplicate entries), +and then orders the matrix $\m{B}$. Thus, either the +lower triangular part of $\m{A}$, the upper triangular part, +or any combination may be passed. The transpose $\m{A}\tr$ may also be +passed to {\tt amd\_order}. +The diagonal entries may be present, but are ignored. + +%------------------------------------------------------------------------------ +\subsection{Control parameters} +\label{control_param} +%------------------------------------------------------------------------------ + +Control parameters are set in an optional {\tt Control} array. +It is optional in the sense that if +a {\tt NULL} pointer is passed for the {\tt Control} input argument, +then default control parameters are used. +% +\begin{itemize} +\item {\tt Control[AMD\_DENSE]} (or {\tt Control(1)} in MATLAB): +controls the threshold for ``dense'' +rows/columns. A dense row/column in $\m{A}+\m{A}\tr$ +can cause AMD to spend significant time +in ordering the matrix. If {\tt Control[AMD\_DENSE]} $\ge 0$, +rows/columns with +more than {\tt Control[AMD\_DENSE]} $\sqrt{n}$ entries are ignored during +the ordering, and placed last in the output order. The default +value of {\tt Control[AMD\_DENSE]} is 10. If negative, no rows/columns +are treated as ``dense.'' Rows/columns with 16 or fewer off-diagonal +entries are never considered ``dense.'' +% +\item {\tt Control[AMD\_AGGRESSIVE]} (or {\tt Control(2)} in MATLAB): +controls whether or not to use +aggressive absorption, in which a prior element is absorbed into the current +element if it is a subset of the current element, even if it is not +adjacent to the current pivot element (refer +to \cite{AmestoyDavisDuff96,AmestoyDavisDuff04} +for more details). The default value is nonzero, +which means that aggressive absorption will be performed. This nearly always +leads to a better ordering (because the approximate degrees are more +accurate) and a lower execution time. There are cases where it can +lead to a slightly worse ordering, however. To turn it off, set +{\tt Control[AMD\_AGGRESSIVE]} to 0. +% +\end{itemize} + +Statistics are returned in the {\tt Info} array +(if {\tt Info} is {\tt NULL}, then no statistics are returned). +Refer to {\tt amd.h} file, for more details +(14 different statistics are returned, so the list is not included here). + +%------------------------------------------------------------------------------ +\subsection{Sample C program} +%------------------------------------------------------------------------------ + +The following program, {\tt amd\_demo.c}, illustrates the basic use of AMD. +See Section~\ref{Synopsis} for a short description +of each calling sequence. + +{\footnotesize +\begin{verbatim} +#include +#include "amd.h" + +int n = 5 ; +int Ap [ ] = { 0, 2, 6, 10, 12, 14} ; +int Ai [ ] = { 0,1, 0,1,2,4, 1,2,3,4, 2,3, 1,4 } ; +int P [5] ; + +int main (void) +{ + int k ; + (void) amd_order (n, Ap, Ai, P, (double *) NULL, (double *) NULL) ; + for (k = 0 ; k < n ; k++) printf ("P [%d] = %d\n", k, P [k]) ; + return (0) ; +} +\end{verbatim} +} + +The {\tt Ap} and {\tt Ai} arrays represent the binary matrix +\[ +\m{A} = \left[ +\begin{array}{rrrrr} + 1 & 1 & 0 & 0 & 0 \\ + 1 & 1 & 1 & 0 & 1 \\ + 0 & 1 & 1 & 1 & 0 \\ + 0 & 0 & 1 & 1 & 0 \\ + 0 & 1 & 1 & 0 & 1 \\ +\end{array} +\right]. +\] +The diagonal entries are ignored. +% +AMD constructs the pattern of $\m{A}+\m{A}\tr$, +and returns a permutation vector of $(0, 3, 1, 4, 2)$. +% +Since the matrix is unsymmetric but with a mostly symmetric nonzero +pattern, this would be a suitable permutation for an LU factorization of a +matrix with this nonzero pattern and whose diagonal entries are not too small. +The program uses default control settings and does not return any statistics +about the ordering, factorization, or solution ({\tt Control} and {\tt Info} +are both {\tt (double *) NULL}). It also ignores the status value returned by +{\tt amd\_order}. + +More example programs are included with the AMD package. +The {\tt amd\_demo.c} program provides a more detailed demo of AMD. +Another example is the AMD mexFunction, {\tt amd\_mex.c}. + +%------------------------------------------------------------------------------ +\subsection{A note about zero-sized arrays} +%------------------------------------------------------------------------------ + +AMD uses several user-provided arrays of size {\tt n} or {\tt nz}. +Either {\tt n} or {\tt nz} can be zero. +If you attempt to {\tt malloc} an array of size zero, +however, {\tt malloc} will return a null pointer which AMD will report +as invalid. If you {\tt malloc} an array of +size {\tt n} or {\tt nz} to pass to AMD, make sure that you handle the +{\tt n} = 0 and {\tt nz = 0} cases correctly. + +%------------------------------------------------------------------------------ +\section{Synopsis of C-callable routines} +\label{Synopsis} +%------------------------------------------------------------------------------ + +The matrix $\m{A}$ is {\tt n}-by-{\tt n} with {\tt nz} entries. + +{\footnotesize +\begin{verbatim} +#include "amd.h" +int n, status, Ap [n+1], Ai [nz], P [n] ; +double Control [AMD_CONTROL], Info [AMD_INFO] ; +amd_defaults (Control) ; +status = amd_order (n, Ap, Ai, P, Control, Info) ; +amd_control (Control) ; +amd_info (Info) ; +status = amd_valid (n, n, Ap, Ai) ; +\end{verbatim} +} + +The {\tt amd\_l\_*} routines are identical, except that all {\tt int} +arguments become {\tt long}: + +{\footnotesize +\begin{verbatim} +#include "amd.h" +long n, status, Ap [n+1], Ai [nz], P [n] ; +double Control [AMD_CONTROL], Info [AMD_INFO] ; +amd_l_defaults (Control) ; +status = amd_l_order (n, Ap, Ai, P, Control, Info) ; +amd_l_control (Control) ; +amd_l_info (Info) ; +status = amd_l_valid (n, n, Ap, Ai) ; +\end{verbatim} +} + +%------------------------------------------------------------------------------ +\section{Using AMD in a Fortran program} +%------------------------------------------------------------------------------ + +Two Fortran versions of AMD are provided. The {\tt AMD} routine computes the +approximate minimum degree ordering, using aggressive absorption. The +{\tt AMDBAR} routine is identical, except that it does not perform aggressive +absorption. The {\tt AMD} routine is essentially identical to the HSL +routine {\tt MC47B/BD}. +Note that earlier versions of the Fortran +{\tt AMD} and {\tt AMDBAR} routines included an {\tt IOVFLO} argument, +which is no longer present. + +In contrast to the C version, the Fortran routines require a symmetric +nonzero pattern, with no diagonal entries present although the {\tt MC47A/AD} +wrapper in HSL allows duplicates, ignores out-of-range entries, and only +uses entries from the upper triangular part of the matrix. Although we +have an experimental Fortran code for treating ``dense'' rows, the Fortran +codes in this release do not treat +``dense'' rows and columns of $\m{A}$ differently, and thus their run time +can be high if there are a few dense rows and columns in the matrix. +They do not perform a post-ordering of the elimination tree, +compute statistics on the ordering, or check the validity of their input +arguments. These facilities are provided by {\tt MC47A/AD} and other +subroutines from HSL. +Only one {\tt integer} +version of each Fortran routine is provided. +Both Fortran routines overwrite the user's input +matrix, in contrast to the C version. +% +The C version does not return the elimination or assembly tree. +The Fortran version returns an assembly tree; +refer to the User Guide for details. +The following is the syntax of the {\tt AMD} Fortran routine. +The {\tt AMDBAR} routine is identical except for the routine name. + +{\footnotesize +\begin{verbatim} + INTEGER N, IWLEN, PFREE, NCMPA, IW (IWLEN), PE (N), DEGREE (N), NV (N), + $ NEXT (N), LAST (N), HEAD (N), ELEN (N), W (N), LEN (N) + CALL AMD (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ LAST, HEAD, ELEN, DEGREE, NCMPA, W) + CALL AMDBAR (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ LAST, HEAD, ELEN, DEGREE, NCMPA, W) +\end{verbatim} +} + +The input matrix is provided to {\tt AMD} and {\tt AMDBAR} +in three arrays, {\tt PE}, of size {\tt N}, +{\tt LEN}, of size {\tt N}, and {\tt IW}, of size {\tt IWLEN}. The size of +{\tt IW} must be at least {\tt NZ+N}. The recommended size is +{\tt 1.2*NZ + N}. +On input, the indices of nonzero entries in row {\tt I} are stored in {\tt IW}. +{\tt PE(I)} is the index in {\tt IW} of the start of row {\tt I}. +{\tt LEN(I)} is the number of entries in row {\tt I}. +The matrix is 1-based, with row and column indices in the range 1 to {\tt N}. +Row {\tt I} is contained in +{\tt IW (PE(I)} $\ldots \:$ {\tt PE(I) + LEN(I) - 1)}. +The diagonal entries must not be present. The indices within each row must +not contain any duplicates, but they need not be sorted. The rows +themselves need not be in any particular order, and there may be empty space +between the rows. If {\tt LEN(I)} is zero, then there are no off-diagonal +entries in row {\tt I}, and {\tt PE(I)} is ignored. The integer +{\tt PFREE} defines what part of {\tt IW} contains the user's input matrix, +which is held in {\tt IW(1}~$\ldots~\:${\tt PFREE-1)}. +The contents of {\tt IW} and {\tt LEN} are undefined on output, +and {\tt PE} is modified to contain information about the ordering. + +As the algorithm proceeds, it modifies the {\tt IW} array, placing the +pattern of the partially eliminated matrix in +{\tt IW(PFREE} $\ldots \:${\tt IWLEN)}. +If this space is exhausted, the space is compressed. +The number of compressions performed on the {\tt IW} array is +returned in the scalar {\tt NCMPA}. The value of {\tt PFREE} on output is the +length of {\tt IW} required for no compressions to be needed. + +The output permutation is returned in the array {\tt LAST}, of size {\tt N}. +If {\tt I=LAST(K)}, then {\tt I} is the {\tt K}th row in the permuted +matrix. The inverse permutation is returned in the array {\tt ELEN}, where +{\tt K=ELEN(I)} if {\tt I} is the {\tt K}th row in the permuted matrix. +On output, the {\tt PE} and {\tt NV} arrays hold the assembly tree, +a supernodal elimination tree that represents the relationship between +columns of the Cholesky factor $\m{L}$. +If {\tt NV(I)} $> 0$, then {\tt I} is a node in the assembly +tree, and the parent of {\tt I} is {\tt -PE(I)}. If {\tt I} is a root of +the tree, then {\tt PE(I)} is zero. The value of {\tt NV(I)} is the +number of entries in the corresponding column of $\m{L}$, including the +diagonal. +If {\tt NV(I)} is zero, then {\tt I} is a non-principal node that is +not in the assembly tree. Node {\tt -PE(I)} is the parent of node {\tt I} +in a subtree, the root of which is a node in the assembly tree. All nodes +in one subtree belong to the same supernode in the assembly tree. +The other size {\tt N} arrays +({\tt DEGREE}, {\tt HEAD}, {\tt NEXT}, and {\tt W}) are used as workspace, +and are not defined on input or output. + +If you want to use a simpler user-interface and compute the elimination +tree post-ordering, you should be able to call the C routines {\tt amd\_order} +or {\tt amd\_l\_order} from a Fortran program. Just be sure to take into +account the 0-based indexing in the {\tt P}, {\tt Ap}, and {\tt Ai} arguments +to {\tt amd\_order} and {\tt amd\_l\_order}. A sample interface is provided +in the files {\tt AMD/Demo/amd\_f77cross.f} and +{\tt AMD/Demo/amd\_f77wrapper.c}. To compile the {\tt amd\_f77cross} program, +type {\tt make cross} in the {\tt AMD/Demo} directory. The +Fortran-to-C calling conventions are highly non-portable, so this example +is not guaranteed to work with your compiler C and Fortran compilers. +The output of {\tt amd\_f77cross} is in {\tt amd\_f77cross.out}. + +%------------------------------------------------------------------------------ +\section{Sample Fortran main program} +%------------------------------------------------------------------------------ + +The following program illustrates the basic usage of the Fortran version of AMD. +The {\tt AP} and {\tt AI} arrays represent the binary matrix +\[ +\m{A} = \left[ +\begin{array}{rrrrr} + 1 & 1 & 0 & 0 & 0 \\ + 1 & 1 & 1 & 0 & 1 \\ + 0 & 1 & 1 & 1 & 1 \\ + 0 & 0 & 1 & 1 & 0 \\ + 0 & 1 & 1 & 0 & 1 \\ +\end{array} +\right] +\] +in a conventional 1-based column-oriented form, +except that the diagonal entries are not present. +The matrix has the same as nonzero pattern of $\m{A}+\m{A}\tr$ in the C +program, in Section~\ref{Cversion}. +The output permutation is $(4, 1, 3, 5, 2)$. +It differs from the permutation returned by the C routine {\tt amd\_order} +because a post-order of the elimination tree has not yet been performed. + +{\footnotesize +\begin{verbatim} + INTEGER N, NZ, J, K, P, IWLEN, PFREE, NCMPA + PARAMETER (N = 5, NZ = 10, IWLEN = 17) + INTEGER AP (N+1), AI (NZ), LAST (N), PE (N), LEN (N), ELEN (N), + $ IW (IWLEN), DEGREE (N), NV (N), NEXT (N), HEAD (N), W (N) + DATA AP / 1, 2, 5, 8, 9, 11/ + DATA AI / 2, 1,3,5, 2,4,5, 3, 2,3 / +C load the matrix into the AMD workspace + DO 10 J = 1,N + PE (J) = AP (J) + LEN (J) = AP (J+1) - AP (J) +10 CONTINUE + DO 20 P = 1,NZ + IW (P) = AI (P) +20 CONTINUE + PFREE = NZ + 1 +C order the matrix (destroys the copy of A in IW, PE, and LEN) + CALL AMD (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, LAST, HEAD, + $ ELEN, DEGREE, NCMPA, W) + DO 60 K = 1, N + PRINT 50, K, LAST (K) +50 FORMAT ('P (',I2,') = ', I2) +60 CONTINUE + END +\end{verbatim} +} + +The {\tt Demo} directory contains an example of how the C version +may be called from a Fortran program, but this is highly non-portable. +For this reason, it is placed in the {\tt Demo} directory, not in the +primary {\tt Source} directory. + +%------------------------------------------------------------------------------ +\section{Installation} +\label{Install} +%------------------------------------------------------------------------------ + +The following discussion assumes you have the {\tt make} program, either in +Unix, or in Windows with Cygwin. + +System-dependent configurations are in the {\tt ../UFconfig/UFconfig.mk} +file. You can edit that file to customize the compilation. The default +settings will work on most systems. +Sample configuration files are provided +for Linux, Sun Solaris, SGI IRIX, IBM AIX, and the DEC/Compaq Alpha. + +To compile and install the C-callable AMD library, +go to the {\tt AMD} directory and type {\tt make}. +The library will be placed in {\tt AMD/Lib/libamd.a}. +Three demo programs of the AMD ordering routine will be compiled and tested in +the {\tt AMD/Demo} directory. +The outputs of these demo programs will then be compared with output +files in the distribution. + +To compile and install the Fortran-callable AMD library, +go to the {\tt AMD} directory and type {\tt make fortran}. +The library will be placed in {\tt AMD/Lib/libamdf77.a}. +A demo program will be compiled and tested in the {\tt AMD/Demo} directory. +The output will be compared with an output file in the distribution. + +Typing {\tt make clean} will remove all but the final compiled libraries +and demo programs. Typing {\tt make purge} or {\tt make distclean} +removes all files not in the original distribution. +If you compile AMD and then later change the {\tt ../UFconfig/UFconfig.mk} file +then you should type {\tt make purge} and then {\tt make} to recompile. + +When you compile your program that uses the C-callable AMD library, +you need to add the {\tt AMD/Lib/libamd.a} library +and you need to tell your compiler to look in the +{\tt AMD/Include} directory for include +files. To compile a Fortran program that calls the Fortran AMD library, +you need to add the {\tt AMD/Lib/libamdf77.a} library. +See {\tt AMD/Demo/Makefile} for an example. + +If all you want to use is the AMD2 mexFunction in MATLAB, you can skip +the use of the {\tt make} command entirely. Simply type +{\tt amd\_make} in MATLAB while in the {\tt AMD/MATLAB} directory. +This works on any system with MATLAB, including Windows. +Alternately, type {\tt make} in the {\tt AMD/MATLAB} directory, +or just use the built-in {\tt amd} in MATLAB 7.3 or later. + +If you have MATLAB 7.2 or earlier, you must first edit UFconfig/UFconfig.h to +remove the "-largeArrayDims" option from the MEX command, prior to +{\tt make mex} or {\tt make} in the MATLAB directory +(or just use {\tt amd\_make.m} inside MATLAB. + +If you are including AMD as a subset of a larger library and do not want +to link the C standard I/O library, or if you simply do not need to use +them, you can safely remove the {\tt amd\_control.c} and {\tt amd\_info.c} +files. Similarly, if you use default parameters (or define your +own {\tt Control} array), then you can exclude the {\tt amd\_defaults.c} +file. +Each of these files contains the user-callable routines of the same +name. None of these auxiliary routines are directly called by +{\tt amd\_order}. +The {\tt amd\_dump.c} file contains debugging routines +that are neither used nor compiled unless debugging is enabled. +The {\tt amd\_internal.h} file must be edited to enable debugging; +refer to the instructions in that file. +The bare minimum files required to use just {\tt amd\_order} are +{\tt amd.h} and {\tt amd\_internal.h} +in the {\tt Include} directory, +and +{\tt amd\_1.c}, +{\tt amd\_2.c}, +{\tt amd\_aat.c}, +{\tt amd\_global.c}, +{\tt and\_order.c}, +{\tt amd\_postorder.c}, +{\tt amd\_post\_tree.c}, +{\tt amd\_preprocess.c}, +and +{\tt amd\_valid.c} +in the {\tt Source} directory. + +%------------------------------------------------------------------------------ +\newpage +\section{The AMD routines} +\label{Primary} +%------------------------------------------------------------------------------ + +The file {\tt AMD/Include/amd.h} listed below +describes each user-callable routine in the C version of AMD, +and gives details on their use. + +{\footnotesize +\begin{verbatim} + +/* ========================================================================= */ +/* === AMD: approximate minimum degree ordering =========================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Version 2.2, Copyright (c) 2007 by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD finds a symmetric ordering P of a matrix A so that the Cholesky + * factorization of P*A*P' has fewer nonzeros and takes less work than the + * Cholesky factorization of A. If A is not symmetric, then it performs its + * ordering on the matrix A+A'. Two sets of user-callable routines are + * provided, one for int integers and the other for UF_long integers. + * + * The method is based on the approximate minimum degree algorithm, discussed + * in Amestoy, Davis, and Duff, "An approximate degree ordering algorithm", + * SIAM Journal of Matrix Analysis and Applications, vol. 17, no. 4, pp. + * 886-905, 1996. This package can perform both the AMD ordering (with + * aggressive absorption), and the AMDBAR ordering (without aggressive + * absorption) discussed in the above paper. This package differs from the + * Fortran codes discussed in the paper: + * + * (1) it can ignore "dense" rows and columns, leading to faster run times + * (2) it computes the ordering of A+A' if A is not symmetric + * (3) it is followed by a depth-first post-ordering of the assembly tree + * (or supernodal elimination tree) + * + * For historical reasons, the Fortran versions, amd.f and amdbar.f, have + * been left (nearly) unchanged. They compute the identical ordering as + * described in the above paper. + */ + +#ifndef AMD_H +#define AMD_H + +/* make it easy for C++ programs to include AMD */ +#ifdef __cplusplus +extern "C" { +#endif + +/* get the definition of size_t: */ +#include + +/* define UF_long */ +#include "UFconfig.h" + +int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, + * AMD_INVALID, or AMD_OUT_OF_MEMORY */ +( + int n, /* A is n-by-n. n must be >= 0. */ + const int Ap [ ], /* column pointers for A, of size n+1 */ + const int Ai [ ], /* row indices of A, of size nz = Ap [n] */ + int P [ ], /* output permutation, of size n */ + double Control [ ], /* input Control settings, of size AMD_CONTROL */ + double Info [ ] /* output Info statistics, of size AMD_INFO */ +) ; + +UF_long amd_l_order /* see above for description of arguments */ +( + UF_long n, + const UF_long Ap [ ], + const UF_long Ai [ ], + UF_long P [ ], + double Control [ ], + double Info [ ] +) ; + +/* Input arguments (not modified): + * + * n: the matrix A is n-by-n. + * Ap: an int/UF_long array of size n+1, containing column pointers of A. + * Ai: an int/UF_long array of size nz, containing the row indices of A, + * where nz = Ap [n]. + * Control: a double array of size AMD_CONTROL, containing control + * parameters. Defaults are used if Control is NULL. + * + * Output arguments (not defined on input): + * + * P: an int/UF_long array of size n, containing the output permutation. If + * row i is the kth pivot row, then P [k] = i. In MATLAB notation, + * the reordered matrix is A (P,P). + * Info: a double array of size AMD_INFO, containing statistical + * information. Ignored if Info is NULL. + * + * On input, the matrix A is stored in column-oriented form. The row indices + * of nonzero entries in column j are stored in Ai [Ap [j] ... Ap [j+1]-1]. + * + * If the row indices appear in ascending order in each column, and there + * are no duplicate entries, then amd_order is slightly more efficient in + * terms of time and memory usage. If this condition does not hold, a copy + * of the matrix is created (where these conditions do hold), and the copy is + * ordered. This feature is new to v2.0 (v1.2 and earlier required this + * condition to hold for the input matrix). + * + * Row indices must be in the range 0 to + * n-1. Ap [0] must be zero, and thus nz = Ap [n] is the number of nonzeros + * in A. The array Ap is of size n+1, and the array Ai is of size nz = Ap [n]. + * The matrix does not need to be symmetric, and the diagonal does not need to + * be present (if diagonal entries are present, they are ignored except for + * the output statistic Info [AMD_NZDIAG]). The arrays Ai and Ap are not + * modified. This form of the Ap and Ai arrays to represent the nonzero + * pattern of the matrix A is the same as that used internally by MATLAB. + * If you wish to use a more flexible input structure, please see the + * umfpack_*_triplet_to_col routines in the UMFPACK package, at + * http://www.cise.ufl.edu/research/sparse/umfpack. + * + * Restrictions: n >= 0. Ap [0] = 0. Ap [j] <= Ap [j+1] for all j in the + * range 0 to n-1. nz = Ap [n] >= 0. Ai [0..nz-1] must be in the range 0 + * to n-1. Finally, Ai, Ap, and P must not be NULL. If any of these + * restrictions are not met, AMD returns AMD_INVALID. + * + * AMD returns: + * + * AMD_OK if the matrix is valid and sufficient memory can be allocated to + * perform the ordering. + * + * AMD_OUT_OF_MEMORY if not enough memory can be allocated. + * + * AMD_INVALID if the input arguments n, Ap, Ai are invalid, or if P is + * NULL. + * + * AMD_OK_BUT_JUMBLED if the matrix had unsorted columns, and/or duplicate + * entries, but was otherwise valid. + * + * The AMD routine first forms the pattern of the matrix A+A', and then + * computes a fill-reducing ordering, P. If P [k] = i, then row/column i of + * the original is the kth pivotal row. In MATLAB notation, the permuted + * matrix is A (P,P), except that 0-based indexing is used instead of the + * 1-based indexing in MATLAB. + * + * The Control array is used to set various parameters for AMD. If a NULL + * pointer is passed, default values are used. The Control array is not + * modified. + * + * Control [AMD_DENSE]: controls the threshold for "dense" rows/columns. + * A dense row/column in A+A' can cause AMD to spend a lot of time in + * ordering the matrix. If Control [AMD_DENSE] >= 0, rows/columns + * with more than Control [AMD_DENSE] * sqrt (n) entries are ignored + * during the ordering, and placed last in the output order. The + * default value of Control [AMD_DENSE] is 10. If negative, no + * rows/columns are treated as "dense". Rows/columns with 16 or + * fewer off-diagonal entries are never considered "dense". + * + * Control [AMD_AGGRESSIVE]: controls whether or not to use aggressive + * absorption, in which a prior element is absorbed into the current + * element if is a subset of the current element, even if it is not + * adjacent to the current pivot element (refer to Amestoy, Davis, + * & Duff, 1996, for more details). The default value is nonzero, + * which means to perform aggressive absorption. This nearly always + * leads to a better ordering (because the approximate degrees are + * more accurate) and a lower execution time. There are cases where + * it can lead to a slightly worse ordering, however. To turn it off, + * set Control [AMD_AGGRESSIVE] to 0. + * + * Control [2..4] are not used in the current version, but may be used in + * future versions. + * + * The Info array provides statistics about the ordering on output. If it is + * not present, the statistics are not returned. This is not an error + * condition. + * + * Info [AMD_STATUS]: the return value of AMD, either AMD_OK, + * AMD_OK_BUT_JUMBLED, AMD_OUT_OF_MEMORY, or AMD_INVALID. + * + * Info [AMD_N]: n, the size of the input matrix + * + * Info [AMD_NZ]: the number of nonzeros in A, nz = Ap [n] + * + * Info [AMD_SYMMETRY]: the symmetry of the matrix A. It is the number + * of "matched" off-diagonal entries divided by the total number of + * off-diagonal entries. An entry A(i,j) is matched if A(j,i) is also + * an entry, for any pair (i,j) for which i != j. In MATLAB notation, + * S = spones (A) ; + * B = tril (S, -1) + triu (S, 1) ; + * symmetry = nnz (B & B') / nnz (B) ; + * + * Info [AMD_NZDIAG]: the number of entries on the diagonal of A. + * + * Info [AMD_NZ_A_PLUS_AT]: the number of nonzeros in A+A', excluding the + * diagonal. If A is perfectly symmetric (Info [AMD_SYMMETRY] = 1) + * with a fully nonzero diagonal, then Info [AMD_NZ_A_PLUS_AT] = nz-n + * (the smallest possible value). If A is perfectly unsymmetric + * (Info [AMD_SYMMETRY] = 0, for an upper triangular matrix, for + * example) with no diagonal, then Info [AMD_NZ_A_PLUS_AT] = 2*nz + * (the largest possible value). + * + * Info [AMD_NDENSE]: the number of "dense" rows/columns of A+A' that were + * removed from A prior to ordering. These are placed last in the + * output order P. + * + * Info [AMD_MEMORY]: the amount of memory used by AMD, in bytes. In the + * current version, this is 1.2 * Info [AMD_NZ_A_PLUS_AT] + 9*n + * times the size of an integer. This is at most 2.4nz + 9n. This + * excludes the size of the input arguments Ai, Ap, and P, which have + * a total size of nz + 2*n + 1 integers. + * + * Info [AMD_NCMPA]: the number of garbage collections performed. + * + * Info [AMD_LNZ]: the number of nonzeros in L (excluding the diagonal). + * This is a slight upper bound because mass elimination is combined + * with the approximate degree update. It is a rough upper bound if + * there are many "dense" rows/columns. The rest of the statistics, + * below, are also slight or rough upper bounds, for the same reasons. + * The post-ordering of the assembly tree might also not exactly + * correspond to a true elimination tree postordering. + * + * Info [AMD_NDIV]: the number of divide operations for a subsequent LDL' + * or LU factorization of the permuted matrix A (P,P). + * + * Info [AMD_NMULTSUBS_LDL]: the number of multiply-subtract pairs for a + * subsequent LDL' factorization of A (P,P). + * + * Info [AMD_NMULTSUBS_LU]: the number of multiply-subtract pairs for a + * subsequent LU factorization of A (P,P), assuming that no numerical + * pivoting is required. + * + * Info [AMD_DMAX]: the maximum number of nonzeros in any column of L, + * including the diagonal. + * + * Info [14..19] are not used in the current version, but may be used in + * future versions. + */ + +/* ------------------------------------------------------------------------- */ +/* direct interface to AMD */ +/* ------------------------------------------------------------------------- */ + +/* amd_2 is the primary AMD ordering routine. It is not meant to be + * user-callable because of its restrictive inputs and because it destroys + * the user's input matrix. It does not check its inputs for errors, either. + * However, if you can work with these restrictions it can be faster than + * amd_order and use less memory (assuming that you can create your own copy + * of the matrix for AMD to destroy). Refer to AMD/Source/amd_2.c for a + * description of each parameter. */ + +void amd_2 +( + int n, + int Pe [ ], + int Iw [ ], + int Len [ ], + int iwlen, + int pfree, + int Nv [ ], + int Next [ ], + int Last [ ], + int Head [ ], + int Elen [ ], + int Degree [ ], + int W [ ], + double Control [ ], + double Info [ ] +) ; + +void amd_l2 +( + UF_long n, + UF_long Pe [ ], + UF_long Iw [ ], + UF_long Len [ ], + UF_long iwlen, + UF_long pfree, + UF_long Nv [ ], + UF_long Next [ ], + UF_long Last [ ], + UF_long Head [ ], + UF_long Elen [ ], + UF_long Degree [ ], + UF_long W [ ], + double Control [ ], + double Info [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* amd_valid */ +/* ------------------------------------------------------------------------- */ + +/* Returns AMD_OK or AMD_OK_BUT_JUMBLED if the matrix is valid as input to + * amd_order; the latter is returned if the matrix has unsorted and/or + * duplicate row indices in one or more columns. Returns AMD_INVALID if the + * matrix cannot be passed to amd_order. For amd_order, the matrix must also + * be square. The first two arguments are the number of rows and the number + * of columns of the matrix. For its use in AMD, these must both equal n. + * + * NOTE: this routine returned TRUE/FALSE in v1.2 and earlier. + */ + +int amd_valid +( + int n_row, /* # of rows */ + int n_col, /* # of columns */ + const int Ap [ ], /* column pointers, of size n_col+1 */ + const int Ai [ ] /* row indices, of size Ap [n_col] */ +) ; + +UF_long amd_l_valid +( + UF_long n_row, + UF_long n_col, + const UF_long Ap [ ], + const UF_long Ai [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* AMD memory manager and printf routines */ +/* ------------------------------------------------------------------------- */ + +/* The user can redefine these to change the malloc, free, and printf routines + * that AMD uses. */ + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN void *(*amd_malloc) (size_t) ; /* pointer to malloc */ +EXTERN void (*amd_free) (void *) ; /* pointer to free */ +EXTERN void *(*amd_realloc) (void *, size_t) ; /* pointer to realloc */ +EXTERN void *(*amd_calloc) (size_t, size_t) ; /* pointer to calloc */ +EXTERN int (*amd_printf) (const char *, ...) ; /* pointer to printf */ + +/* ------------------------------------------------------------------------- */ +/* AMD Control and Info arrays */ +/* ------------------------------------------------------------------------- */ + +/* amd_defaults: sets the default control settings */ +void amd_defaults (double Control [ ]) ; +void amd_l_defaults (double Control [ ]) ; + +/* amd_control: prints the control settings */ +void amd_control (double Control [ ]) ; +void amd_l_control (double Control [ ]) ; + +/* amd_info: prints the statistics */ +void amd_info (double Info [ ]) ; +void amd_l_info (double Info [ ]) ; + +#define AMD_CONTROL 5 /* size of Control array */ +#define AMD_INFO 20 /* size of Info array */ + +/* contents of Control */ +#define AMD_DENSE 0 /* "dense" if degree > Control [0] * sqrt (n) */ +#define AMD_AGGRESSIVE 1 /* do aggressive absorption if Control [1] != 0 */ + +/* default Control settings */ +#define AMD_DEFAULT_DENSE 10.0 /* default "dense" degree 10*sqrt(n) */ +#define AMD_DEFAULT_AGGRESSIVE 1 /* do aggressive absorption by default */ + +/* contents of Info */ +#define AMD_STATUS 0 /* return value of amd_order and amd_l_order */ +#define AMD_N 1 /* A is n-by-n */ +#define AMD_NZ 2 /* number of nonzeros in A */ +#define AMD_SYMMETRY 3 /* symmetry of pattern (1 is sym., 0 is unsym.) */ +#define AMD_NZDIAG 4 /* # of entries on diagonal */ +#define AMD_NZ_A_PLUS_AT 5 /* nz in A+A' */ +#define AMD_NDENSE 6 /* number of "dense" rows/columns in A */ +#define AMD_MEMORY 7 /* amount of memory used by AMD */ +#define AMD_NCMPA 8 /* number of garbage collections in AMD */ +#define AMD_LNZ 9 /* approx. nz in L, excluding the diagonal */ +#define AMD_NDIV 10 /* number of fl. point divides for LU and LDL' */ +#define AMD_NMULTSUBS_LDL 11 /* number of fl. point (*,-) pairs for LDL' */ +#define AMD_NMULTSUBS_LU 12 /* number of fl. point (*,-) pairs for LU */ +#define AMD_DMAX 13 /* max nz. in any column of L, incl. diagonal */ + +/* ------------------------------------------------------------------------- */ +/* return values of AMD */ +/* ------------------------------------------------------------------------- */ + +#define AMD_OK 0 /* success */ +#define AMD_OUT_OF_MEMORY -1 /* malloc failed, or problem too large */ +#define AMD_INVALID -2 /* input arguments are not valid */ +#define AMD_OK_BUT_JUMBLED 1 /* input matrix is OK for amd_order, but + * columns were not sorted, and/or duplicate entries were present. AMD had + * to do extra work before ordering the matrix. This is a warning, not an + * error. */ + +/* ========================================================================== */ +/* === AMD version ========================================================== */ +/* ========================================================================== */ + +/* AMD Version 1.2 and later include the following definitions. + * As an example, to test if the version you are using is 1.2 or later: + * + * #ifdef AMD_VERSION + * if (AMD_VERSION >= AMD_VERSION_CODE (1,2)) ... + * #endif + * + * This also works during compile-time: + * + * #if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE (1,2)) + * printf ("This is version 1.2 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + * + * Versions 1.1 and earlier of AMD do not include a #define'd version number. + */ + +#define AMD_DATE "Dec 7, 2011" +#define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define AMD_MAIN_VERSION 2 +#define AMD_SUB_VERSION 2 +#define AMD_SUBSUB_VERSION 3 +#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) + +#ifdef __cplusplus +} +#endif + +#endif +\end{verbatim} +} + + +%------------------------------------------------------------------------------ +\newpage +% References +%------------------------------------------------------------------------------ + +\bibliographystyle{plain} +\bibliography{AMD_UserGuide} + +\end{document} diff --git a/OpenDSSC/klusolve/AMD/Doc/ChangeLog b/OpenDSSC/klusolve/AMD/Doc/ChangeLog new file mode 100644 index 0000000..2e62d5e --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/ChangeLog @@ -0,0 +1,145 @@ +May 15, 2011: version 2.2.4 + + * minor fix to SIZE_T_MAX definition (finicky compiler workaround) + +Dec 7, 2011: version 2.2.3 + + * fixed the Makefile to better align with CFLAGS and other standards + +Jan 25, 2011: version 2.2.2 + + * minor fix to "make install" + +Nov 30, 2009: version 2.2.1 + + * added "make install" and "make uninstall" + +May 31, 2007: version 2.2.0 + + * port to 64-bit MATLAB + + * Makefile moved from Source/ to Lib/ + + * minor changes to printing routines (amd_control.c, amd_info.c) + +Dec 12, 2006, version 2.0.4 + + * minor MATLAB code cleanup + +Nov 29, 2006, version 2.0.3 + + * changed MATLAB function name to amd2, so as not to conflict with + the now built-in version of AMD in MATLAB (which is the same thing + as the AMD here...). + +Sept 28, 2006, version 2.0.2 + + * #define SIZE_T_MAX not done if already defined (Mac OSX). + +Aug 31, 2006: + + * trivial change to comments in amd.m + +Apr 30, 2006: AMD Version 2.0: + + * long integer redefined as UF_long, controlled by UFconfig.h. + + * amd_order no longer requires its input to have sorted columns. It can + also tolerate duplicate entries in each column. If these conditions + hold, but the matrix is otherwise valid, amd_order returns + AMD_OK_BUT_JUMBLED (a warning, not an error). + + * amd_preprocess no longer deemed user-callable, since it is no longer + needed (it was used to ensure the input matrix had sorted columns with + no duplicate entries). It still exists, with additional parameters, + and is called by amd_order if necessary. amd_wpreprocess and + amd_preprocess_valid removed. Fortran interface routine amdpreproc + removed. + + * Integer overflow computations modified, to extend the size of problem + that the "int" version can solve when used in an LP64 compilation. + + * amd_demo2.c simplified (it tests AMD with a jumbled matrix). + + * amd_valid returned TRUE/FALSE in v1.2. It now returns AMD_OK, + AMD_OK_BUT_JUMBLED, or AMD_INVALID. Only in the latter case is the + matrix unsuitable as input to amd_order. + + * amd_internal.h include file moved from AMD/Source to AMD/Include. + +Nov 15, 2005: + + * minor editting of comments; version number (1.2) unchanged. + +Aug. 30, 2005: AMD Version 1.2 + + * AMD v1.2 is upward compatible with v1.1 and v1.0, except that v1.2 no + longer includes the compile-time redefinition of malloc and free. + + * Makefile modified to use UFconfig.mk. "Make" directory removed. + + * License changed to GNU LGPL. + + * Easier inclusion in C++ programs. + + * option to allow compile-time redefinition of malloc and free + (added to v1.1) removed for v1.2. Replaced with a run-time + redefinition. AMD includes function pointers for malloc, free, + calloc, realloc, and printf, so that all those routines can be + redefined at compile time. These function pointers are global + variables, and so are not technically thread-safe, unless you + use defaults and don't need to change them (the common case) + or if you change them in one thread before using them in other + threads. + + * added #define'd version number + + * minor modification to AMD_2 to ensure all lines can be tested, without + conditional compilation. + + * moved the prototype for AMD_2 from amd_internal.h to amd.h + + * moved the prototype for AMD_valid from amd_internal.h to amd.h + + * MATLAB mexFunction uses libamd.a (compiled with cc) instead of compiling + each AMD source file with the mex command + + * long demo (amd_l_demo.c) added. + +Jan. 21, 2004: AMD Version 1.1 + + * No bugs found or fixed - new features added, only + * amd_preprocess added, to allow for more general input of the matrix A. + * ME=0 added to amd*.f, unused DEXT variable removed from amdbar.f, + to avoid spurious compiler warnings (this was not a bug). + * amd_demo2.c and amd_demo2.out added, to test/demo amd_preprocess. + * option to allow compile-time redefinition of malloc, free, printf added + * amd_demo.c shortened slightly (removed printing of PAP') + * User Guide modified (more details added) + * linewidth reduced from 80 to 79 columns + +Oct. 7, 2003: AMD version 1.0.1. + + * MATLAB mexFunction modified, to remove call to mexCallMATLAB function. + This function can take a long time to call, particularly if you are + ordering many small matrices. + +May 6, 2003: AMD Version 1.0 released. + + * converted to C (compare amd.f and amdbar.f with amd_2.c) + * dense rows/column removed prior to ordering + * elimination tree post-ordering added + * demos, user guide written + * statistics added (nz in L, flop count, symmetry of A) + * computes the pattern of A+A' if A is unsymmetric + * user's input matrix no longer overwritten + * degree lists initialized differently + * IOVFLO argument removed from Fortran versions (amd.f and amdbar.f) + * parameters added (dense row/column detection, aggressive absorption) + * MATLAB mexFunction added + +Jan, 1996: + + * amdbar.f posted at http://www.netlib.org (with a restricted License) + * amd.f appears as MC47B/BD in the Harwell Subroutine Library + (without the IOVFLO argument) diff --git a/OpenDSSC/klusolve/AMD/Doc/License b/OpenDSSC/klusolve/AMD/Doc/License new file mode 100644 index 0000000..b01008a --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/License @@ -0,0 +1,39 @@ +AMD, Copyright (c) by Timothy A. Davis, +Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. +AMD is available under alternate licenses, contact T. Davis for details. + +AMD License: + + Your use or distribution of AMD or any modified version of + AMD implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + +Availability: + + http://www.cise.ufl.edu/research/sparse/amd + +------------------------------------------------------------------------------- diff --git a/OpenDSSC/klusolve/AMD/Doc/Makefile b/OpenDSSC/klusolve/AMD/Doc/Makefile new file mode 100644 index 0000000..8b593fa --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/Makefile @@ -0,0 +1,33 @@ +#------------------------------------------------------------------------------ +# AMD Makefile for compiling on Unix systems (for GNU or original make) +#------------------------------------------------------------------------------ + +default: dist + +include ../../UFconfig/UFconfig.mk + +#------------------------------------------------------------------------------ +# Remove all but the files in the original distribution +#------------------------------------------------------------------------------ + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) *.aux *.bbl *.blg *.log *.toc + +#------------------------------------------------------------------------------ +# Create the User Guide and Quick Start Guide +#------------------------------------------------------------------------------ + +AMD_UserGuide.pdf: AMD_UserGuide.tex AMD_UserGuide.bib + pdflatex AMD_UserGuide + bibtex AMD_UserGuide + pdflatex AMD_UserGuide + pdflatex AMD_UserGuide + +dist: AMD_UserGuide.pdf + - $(RM) *.aux *.bbl *.blg *.log *.toc + diff --git a/OpenDSSC/klusolve/AMD/Doc/lesser.txt b/OpenDSSC/klusolve/AMD/Doc/lesser.txt new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/OpenDSSC/klusolve/AMD/Include/amd.h b/OpenDSSC/klusolve/AMD/Include/amd.h new file mode 100644 index 0000000..80cc6d5 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Include/amd.h @@ -0,0 +1,412 @@ +/* ========================================================================= */ +/* === AMD: approximate minimum degree ordering =========================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Version 2.2, Copyright (c) 2007 by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD finds a symmetric ordering P of a matrix A so that the Cholesky + * factorization of P*A*P' has fewer nonzeros and takes less work than the + * Cholesky factorization of A. If A is not symmetric, then it performs its + * ordering on the matrix A+A'. Two sets of user-callable routines are + * provided, one for int integers and the other for UF_long integers. + * + * The method is based on the approximate minimum degree algorithm, discussed + * in Amestoy, Davis, and Duff, "An approximate degree ordering algorithm", + * SIAM Journal of Matrix Analysis and Applications, vol. 17, no. 4, pp. + * 886-905, 1996. This package can perform both the AMD ordering (with + * aggressive absorption), and the AMDBAR ordering (without aggressive + * absorption) discussed in the above paper. This package differs from the + * Fortran codes discussed in the paper: + * + * (1) it can ignore "dense" rows and columns, leading to faster run times + * (2) it computes the ordering of A+A' if A is not symmetric + * (3) it is followed by a depth-first post-ordering of the assembly tree + * (or supernodal elimination tree) + * + * For historical reasons, the Fortran versions, amd.f and amdbar.f, have + * been left (nearly) unchanged. They compute the identical ordering as + * described in the above paper. + */ + +#ifndef AMD_H +#define AMD_H + +/* make it easy for C++ programs to include AMD */ +#ifdef __cplusplus +extern "C" { +#endif + +/* get the definition of size_t: */ +#include + +/* define UF_long */ +#include "UFconfig.h" + +int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, + * AMD_INVALID, or AMD_OUT_OF_MEMORY */ +( + int n, /* A is n-by-n. n must be >= 0. */ + const int Ap [ ], /* column pointers for A, of size n+1 */ + const int Ai [ ], /* row indices of A, of size nz = Ap [n] */ + int P [ ], /* output permutation, of size n */ + double Control [ ], /* input Control settings, of size AMD_CONTROL */ + double Info [ ] /* output Info statistics, of size AMD_INFO */ +) ; + +UF_long amd_l_order /* see above for description of arguments */ +( + UF_long n, + const UF_long Ap [ ], + const UF_long Ai [ ], + UF_long P [ ], + double Control [ ], + double Info [ ] +) ; + +/* Input arguments (not modified): + * + * n: the matrix A is n-by-n. + * Ap: an int/UF_long array of size n+1, containing column pointers of A. + * Ai: an int/UF_long array of size nz, containing the row indices of A, + * where nz = Ap [n]. + * Control: a double array of size AMD_CONTROL, containing control + * parameters. Defaults are used if Control is NULL. + * + * Output arguments (not defined on input): + * + * P: an int/UF_long array of size n, containing the output permutation. If + * row i is the kth pivot row, then P [k] = i. In MATLAB notation, + * the reordered matrix is A (P,P). + * Info: a double array of size AMD_INFO, containing statistical + * information. Ignored if Info is NULL. + * + * On input, the matrix A is stored in column-oriented form. The row indices + * of nonzero entries in column j are stored in Ai [Ap [j] ... Ap [j+1]-1]. + * + * If the row indices appear in ascending order in each column, and there + * are no duplicate entries, then amd_order is slightly more efficient in + * terms of time and memory usage. If this condition does not hold, a copy + * of the matrix is created (where these conditions do hold), and the copy is + * ordered. This feature is new to v2.0 (v1.2 and earlier required this + * condition to hold for the input matrix). + * + * Row indices must be in the range 0 to + * n-1. Ap [0] must be zero, and thus nz = Ap [n] is the number of nonzeros + * in A. The array Ap is of size n+1, and the array Ai is of size nz = Ap [n]. + * The matrix does not need to be symmetric, and the diagonal does not need to + * be present (if diagonal entries are present, they are ignored except for + * the output statistic Info [AMD_NZDIAG]). The arrays Ai and Ap are not + * modified. This form of the Ap and Ai arrays to represent the nonzero + * pattern of the matrix A is the same as that used internally by MATLAB. + * If you wish to use a more flexible input structure, please see the + * umfpack_*_triplet_to_col routines in the UMFPACK package, at + * http://www.cise.ufl.edu/research/sparse/umfpack. + * + * Restrictions: n >= 0. Ap [0] = 0. Ap [j] <= Ap [j+1] for all j in the + * range 0 to n-1. nz = Ap [n] >= 0. Ai [0..nz-1] must be in the range 0 + * to n-1. Finally, Ai, Ap, and P must not be NULL. If any of these + * restrictions are not met, AMD returns AMD_INVALID. + * + * AMD returns: + * + * AMD_OK if the matrix is valid and sufficient memory can be allocated to + * perform the ordering. + * + * AMD_OUT_OF_MEMORY if not enough memory can be allocated. + * + * AMD_INVALID if the input arguments n, Ap, Ai are invalid, or if P is + * NULL. + * + * AMD_OK_BUT_JUMBLED if the matrix had unsorted columns, and/or duplicate + * entries, but was otherwise valid. + * + * The AMD routine first forms the pattern of the matrix A+A', and then + * computes a fill-reducing ordering, P. If P [k] = i, then row/column i of + * the original is the kth pivotal row. In MATLAB notation, the permuted + * matrix is A (P,P), except that 0-based indexing is used instead of the + * 1-based indexing in MATLAB. + * + * The Control array is used to set various parameters for AMD. If a NULL + * pointer is passed, default values are used. The Control array is not + * modified. + * + * Control [AMD_DENSE]: controls the threshold for "dense" rows/columns. + * A dense row/column in A+A' can cause AMD to spend a lot of time in + * ordering the matrix. If Control [AMD_DENSE] >= 0, rows/columns + * with more than Control [AMD_DENSE] * sqrt (n) entries are ignored + * during the ordering, and placed last in the output order. The + * default value of Control [AMD_DENSE] is 10. If negative, no + * rows/columns are treated as "dense". Rows/columns with 16 or + * fewer off-diagonal entries are never considered "dense". + * + * Control [AMD_AGGRESSIVE]: controls whether or not to use aggressive + * absorption, in which a prior element is absorbed into the current + * element if is a subset of the current element, even if it is not + * adjacent to the current pivot element (refer to Amestoy, Davis, + * & Duff, 1996, for more details). The default value is nonzero, + * which means to perform aggressive absorption. This nearly always + * leads to a better ordering (because the approximate degrees are + * more accurate) and a lower execution time. There are cases where + * it can lead to a slightly worse ordering, however. To turn it off, + * set Control [AMD_AGGRESSIVE] to 0. + * + * Control [2..4] are not used in the current version, but may be used in + * future versions. + * + * The Info array provides statistics about the ordering on output. If it is + * not present, the statistics are not returned. This is not an error + * condition. + * + * Info [AMD_STATUS]: the return value of AMD, either AMD_OK, + * AMD_OK_BUT_JUMBLED, AMD_OUT_OF_MEMORY, or AMD_INVALID. + * + * Info [AMD_N]: n, the size of the input matrix + * + * Info [AMD_NZ]: the number of nonzeros in A, nz = Ap [n] + * + * Info [AMD_SYMMETRY]: the symmetry of the matrix A. It is the number + * of "matched" off-diagonal entries divided by the total number of + * off-diagonal entries. An entry A(i,j) is matched if A(j,i) is also + * an entry, for any pair (i,j) for which i != j. In MATLAB notation, + * S = spones (A) ; + * B = tril (S, -1) + triu (S, 1) ; + * symmetry = nnz (B & B') / nnz (B) ; + * + * Info [AMD_NZDIAG]: the number of entries on the diagonal of A. + * + * Info [AMD_NZ_A_PLUS_AT]: the number of nonzeros in A+A', excluding the + * diagonal. If A is perfectly symmetric (Info [AMD_SYMMETRY] = 1) + * with a fully nonzero diagonal, then Info [AMD_NZ_A_PLUS_AT] = nz-n + * (the smallest possible value). If A is perfectly unsymmetric + * (Info [AMD_SYMMETRY] = 0, for an upper triangular matrix, for + * example) with no diagonal, then Info [AMD_NZ_A_PLUS_AT] = 2*nz + * (the largest possible value). + * + * Info [AMD_NDENSE]: the number of "dense" rows/columns of A+A' that were + * removed from A prior to ordering. These are placed last in the + * output order P. + * + * Info [AMD_MEMORY]: the amount of memory used by AMD, in bytes. In the + * current version, this is 1.2 * Info [AMD_NZ_A_PLUS_AT] + 9*n + * times the size of an integer. This is at most 2.4nz + 9n. This + * excludes the size of the input arguments Ai, Ap, and P, which have + * a total size of nz + 2*n + 1 integers. + * + * Info [AMD_NCMPA]: the number of garbage collections performed. + * + * Info [AMD_LNZ]: the number of nonzeros in L (excluding the diagonal). + * This is a slight upper bound because mass elimination is combined + * with the approximate degree update. It is a rough upper bound if + * there are many "dense" rows/columns. The rest of the statistics, + * below, are also slight or rough upper bounds, for the same reasons. + * The post-ordering of the assembly tree might also not exactly + * correspond to a true elimination tree postordering. + * + * Info [AMD_NDIV]: the number of divide operations for a subsequent LDL' + * or LU factorization of the permuted matrix A (P,P). + * + * Info [AMD_NMULTSUBS_LDL]: the number of multiply-subtract pairs for a + * subsequent LDL' factorization of A (P,P). + * + * Info [AMD_NMULTSUBS_LU]: the number of multiply-subtract pairs for a + * subsequent LU factorization of A (P,P), assuming that no numerical + * pivoting is required. + * + * Info [AMD_DMAX]: the maximum number of nonzeros in any column of L, + * including the diagonal. + * + * Info [14..19] are not used in the current version, but may be used in + * future versions. + */ + +/* ------------------------------------------------------------------------- */ +/* direct interface to AMD */ +/* ------------------------------------------------------------------------- */ + +/* amd_2 is the primary AMD ordering routine. It is not meant to be + * user-callable because of its restrictive inputs and because it destroys + * the user's input matrix. It does not check its inputs for errors, either. + * However, if you can work with these restrictions it can be faster than + * amd_order and use less memory (assuming that you can create your own copy + * of the matrix for AMD to destroy). Refer to AMD/Source/amd_2.c for a + * description of each parameter. */ + +void amd_2 +( + int n, + int Pe [ ], + int Iw [ ], + int Len [ ], + int iwlen, + int pfree, + int Nv [ ], + int Next [ ], + int Last [ ], + int Head [ ], + int Elen [ ], + int Degree [ ], + int W [ ], + double Control [ ], + double Info [ ] +) ; + +void amd_l2 +( + UF_long n, + UF_long Pe [ ], + UF_long Iw [ ], + UF_long Len [ ], + UF_long iwlen, + UF_long pfree, + UF_long Nv [ ], + UF_long Next [ ], + UF_long Last [ ], + UF_long Head [ ], + UF_long Elen [ ], + UF_long Degree [ ], + UF_long W [ ], + double Control [ ], + double Info [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* amd_valid */ +/* ------------------------------------------------------------------------- */ + +/* Returns AMD_OK or AMD_OK_BUT_JUMBLED if the matrix is valid as input to + * amd_order; the latter is returned if the matrix has unsorted and/or + * duplicate row indices in one or more columns. Returns AMD_INVALID if the + * matrix cannot be passed to amd_order. For amd_order, the matrix must also + * be square. The first two arguments are the number of rows and the number + * of columns of the matrix. For its use in AMD, these must both equal n. + * + * NOTE: this routine returned TRUE/FALSE in v1.2 and earlier. + */ + +int amd_valid +( + int n_row, /* # of rows */ + int n_col, /* # of columns */ + const int Ap [ ], /* column pointers, of size n_col+1 */ + const int Ai [ ] /* row indices, of size Ap [n_col] */ +) ; + +UF_long amd_l_valid +( + UF_long n_row, + UF_long n_col, + const UF_long Ap [ ], + const UF_long Ai [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* AMD memory manager and printf routines */ +/* ------------------------------------------------------------------------- */ + +/* The user can redefine these to change the malloc, free, and printf routines + * that AMD uses. */ + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN void *(*amd_malloc) (size_t) ; /* pointer to malloc */ +EXTERN void (*amd_free) (void *) ; /* pointer to free */ +EXTERN void *(*amd_realloc) (void *, size_t) ; /* pointer to realloc */ +EXTERN void *(*amd_calloc) (size_t, size_t) ; /* pointer to calloc */ +EXTERN int (*amd_printf) (const char *, ...) ; /* pointer to printf */ + +/* ------------------------------------------------------------------------- */ +/* AMD Control and Info arrays */ +/* ------------------------------------------------------------------------- */ + +/* amd_defaults: sets the default control settings */ +void amd_defaults (double Control [ ]) ; +void amd_l_defaults (double Control [ ]) ; + +/* amd_control: prints the control settings */ +void amd_control (double Control [ ]) ; +void amd_l_control (double Control [ ]) ; + +/* amd_info: prints the statistics */ +void amd_info (double Info [ ]) ; +void amd_l_info (double Info [ ]) ; + +#define AMD_CONTROL 5 /* size of Control array */ +#define AMD_INFO 20 /* size of Info array */ + +/* contents of Control */ +#define AMD_DENSE 0 /* "dense" if degree > Control [0] * sqrt (n) */ +#define AMD_AGGRESSIVE 1 /* do aggressive absorption if Control [1] != 0 */ + +/* default Control settings */ +#define AMD_DEFAULT_DENSE 10.0 /* default "dense" degree 10*sqrt(n) */ +#define AMD_DEFAULT_AGGRESSIVE 1 /* do aggressive absorption by default */ + +/* contents of Info */ +#define AMD_STATUS 0 /* return value of amd_order and amd_l_order */ +#define AMD_N 1 /* A is n-by-n */ +#define AMD_NZ 2 /* number of nonzeros in A */ +#define AMD_SYMMETRY 3 /* symmetry of pattern (1 is sym., 0 is unsym.) */ +#define AMD_NZDIAG 4 /* # of entries on diagonal */ +#define AMD_NZ_A_PLUS_AT 5 /* nz in A+A' */ +#define AMD_NDENSE 6 /* number of "dense" rows/columns in A */ +#define AMD_MEMORY 7 /* amount of memory used by AMD */ +#define AMD_NCMPA 8 /* number of garbage collections in AMD */ +#define AMD_LNZ 9 /* approx. nz in L, excluding the diagonal */ +#define AMD_NDIV 10 /* number of fl. point divides for LU and LDL' */ +#define AMD_NMULTSUBS_LDL 11 /* number of fl. point (*,-) pairs for LDL' */ +#define AMD_NMULTSUBS_LU 12 /* number of fl. point (*,-) pairs for LU */ +#define AMD_DMAX 13 /* max nz. in any column of L, incl. diagonal */ + +/* ------------------------------------------------------------------------- */ +/* return values of AMD */ +/* ------------------------------------------------------------------------- */ + +#define AMD_OK 0 /* success */ +#define AMD_OUT_OF_MEMORY -1 /* malloc failed, or problem too large */ +#define AMD_INVALID -2 /* input arguments are not valid */ +#define AMD_OK_BUT_JUMBLED 1 /* input matrix is OK for amd_order, but + * columns were not sorted, and/or duplicate entries were present. AMD had + * to do extra work before ordering the matrix. This is a warning, not an + * error. */ + +/* ========================================================================== */ +/* === AMD version ========================================================== */ +/* ========================================================================== */ + +/* AMD Version 1.2 and later include the following definitions. + * As an example, to test if the version you are using is 1.2 or later: + * + * #ifdef AMD_VERSION + * if (AMD_VERSION >= AMD_VERSION_CODE (1,2)) ... + * #endif + * + * This also works during compile-time: + * + * #if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE (1,2)) + * printf ("This is version 1.2 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + * + * Versions 1.1 and earlier of AMD do not include a #define'd version number. + */ + +#define AMD_DATE "May 15, 2012" +#define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define AMD_MAIN_VERSION 2 +#define AMD_SUB_VERSION 2 +#define AMD_SUBSUB_VERSION 4 +#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/OpenDSSC/klusolve/AMD/Include/amd_internal.h b/OpenDSSC/klusolve/AMD/Include/amd_internal.h new file mode 100644 index 0000000..7ce9f95 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Include/amd_internal.h @@ -0,0 +1,355 @@ +/* ========================================================================= */ +/* === amd_internal.h ====================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* This file is for internal use in AMD itself, and does not normally need to + * be included in user code (it is included in UMFPACK, however). All others + * should use amd.h instead. + * + * The following compile-time definitions affect how AMD is compiled. + * + * -DNPRINT + * + * Disable all printing. stdio.h will not be included. Printing can + * be re-enabled at run-time by setting the global pointer amd_printf + * to printf (or mexPrintf for a MATLAB mexFunction). + * + * -DNMALLOC + * + * No memory manager is defined at compile-time. You MUST define the + * function pointers amd_malloc, amd_free, amd_realloc, and + * amd_calloc at run-time for AMD to work properly. + */ + +/* ========================================================================= */ +/* === NDEBUG ============================================================== */ +/* ========================================================================= */ + +/* + * Turning on debugging takes some work (see below). If you do not edit this + * file, then debugging is always turned off, regardless of whether or not + * -DNDEBUG is specified in your compiler options. + * + * If AMD is being compiled as a mexFunction, then MATLAB_MEX_FILE is defined, + * and mxAssert is used instead of assert. If debugging is not enabled, no + * MATLAB include files or functions are used. Thus, the AMD library libamd.a + * can be safely used in either a stand-alone C program or in another + * mexFunction, without any change. + */ + +/* + AMD will be exceedingly slow when running in debug mode. The next three + lines ensure that debugging is turned off. +*/ +#ifndef NDEBUG +#define NDEBUG +#endif + +/* + To enable debugging, uncomment the following line: +#undef NDEBUG +*/ + +/* ------------------------------------------------------------------------- */ +/* ANSI include files */ +/* ------------------------------------------------------------------------- */ + +/* from stdlib.h: size_t, malloc, free, realloc, and calloc */ +#include + +#if !defined(NPRINT) || !defined(NDEBUG) +/* from stdio.h: printf. Not included if NPRINT is defined at compile time. + * fopen and fscanf are used when debugging. */ +#include +#endif + +/* from limits.h: INT_MAX and LONG_MAX */ +#include + +/* from math.h: sqrt */ +#include + +/* ------------------------------------------------------------------------- */ +/* MATLAB include files (only if being used in or via MATLAB) */ +/* ------------------------------------------------------------------------- */ + +#ifdef MATLAB_MEX_FILE +#include "matrix.h" +#include "mex.h" +#endif + +/* ------------------------------------------------------------------------- */ +/* basic definitions */ +/* ------------------------------------------------------------------------- */ + +#ifdef FLIP +#undef FLIP +#endif + +#ifdef MAX +#undef MAX +#endif + +#ifdef MIN +#undef MIN +#endif + +#ifdef EMPTY +#undef EMPTY +#endif + +#ifdef GLOBAL +#undef GLOBAL +#endif + +#ifdef PRIVATE +#undef PRIVATE +#endif + +/* FLIP is a "negation about -1", and is used to mark an integer i that is + * normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY + * is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i + * for all integers i. UNFLIP (i) is >= EMPTY. */ +#define EMPTY (-1) +#define FLIP(i) (-(i)-2) +#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i)) + +/* for integer MAX/MIN, or for doubles when we don't care how NaN's behave: */ +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* logical expression of p implies q: */ +#define IMPLIES(p,q) (!(p) || (q)) + +/* Note that the IBM RS 6000 xlc predefines TRUE and FALSE in . */ +/* The Compaq Alpha also predefines TRUE and FALSE. */ +#ifdef TRUE +#undef TRUE +#endif +#ifdef FALSE +#undef FALSE +#endif + +#define TRUE (1) +#define FALSE (0) +#define PRIVATE static +#define GLOBAL +#define EMPTY (-1) + +/* Note that Linux's gcc 2.96 defines NULL as ((void *) 0), but other */ +/* compilers (even gcc 2.95.2 on Solaris) define NULL as 0 or (0). We */ +/* need to use the ANSI standard value of 0. */ +#ifdef NULL +#undef NULL +#endif + +#define NULL 0 + +/* largest value of size_t */ +#ifndef SIZE_T_MAX +#ifdef SIZE_MAX +/* C99 only */ +#define SIZE_T_MAX SIZE_MAX +#else +#define SIZE_T_MAX ((size_t) (-1)) +#endif +#endif + +/* ------------------------------------------------------------------------- */ +/* integer type for AMD: int or UF_long */ +/* ------------------------------------------------------------------------- */ + +/* define UF_long */ +#include "UFconfig.h" + +#if defined (DLONG) || defined (ZLONG) + +#define Int UF_long +#define ID UF_long_id +#define Int_MAX UF_long_max + +#define AMD_order amd_l_order +#define AMD_defaults amd_l_defaults +#define AMD_control amd_l_control +#define AMD_info amd_l_info +#define AMD_1 amd_l1 +#define AMD_2 amd_l2 +#define AMD_valid amd_l_valid +#define AMD_aat amd_l_aat +#define AMD_postorder amd_l_postorder +#define AMD_post_tree amd_l_post_tree +#define AMD_dump amd_l_dump +#define AMD_debug amd_l_debug +#define AMD_debug_init amd_l_debug_init +#define AMD_preprocess amd_l_preprocess + +#else + +#define Int int +#define ID "%d" +#define Int_MAX INT_MAX + +#define AMD_order amd_order +#define AMD_defaults amd_defaults +#define AMD_control amd_control +#define AMD_info amd_info +#define AMD_1 amd_1 +#define AMD_2 amd_2 +#define AMD_valid amd_valid +#define AMD_aat amd_aat +#define AMD_postorder amd_postorder +#define AMD_post_tree amd_post_tree +#define AMD_dump amd_dump +#define AMD_debug amd_debug +#define AMD_debug_init amd_debug_init +#define AMD_preprocess amd_preprocess + +#endif + +/* ========================================================================= */ +/* === PRINTF macro ======================================================== */ +/* ========================================================================= */ + +/* All output goes through the PRINTF macro. */ +#define PRINTF(params) { if (amd_printf != NULL) (void) amd_printf params ; } + +/* ------------------------------------------------------------------------- */ +/* AMD routine definitions (user-callable) */ +/* ------------------------------------------------------------------------- */ + +#include "amd.h" + +/* ------------------------------------------------------------------------- */ +/* AMD routine definitions (not user-callable) */ +/* ------------------------------------------------------------------------- */ + +GLOBAL size_t AMD_aat +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Len [ ], + Int Tp [ ], + double Info [ ] +) ; + +GLOBAL void AMD_1 +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int P [ ], + Int Pinv [ ], + Int Len [ ], + Int slen, + Int S [ ], + double Control [ ], + double Info [ ] +) ; + +GLOBAL void AMD_postorder +( + Int nn, + Int Parent [ ], + Int Npiv [ ], + Int Fsize [ ], + Int Order [ ], + Int Child [ ], + Int Sibling [ ], + Int Stack [ ] +) ; + +GLOBAL Int AMD_post_tree +( + Int root, + Int k, + Int Child [ ], + const Int Sibling [ ], + Int Order [ ], + Int Stack [ ] +#ifndef NDEBUG + , Int nn +#endif +) ; + +GLOBAL void AMD_preprocess +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Rp [ ], + Int Ri [ ], + Int W [ ], + Int Flag [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* debugging definitions */ +/* ------------------------------------------------------------------------- */ + +#ifndef NDEBUG + +/* from assert.h: assert macro */ +#include + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN Int AMD_debug ; + +GLOBAL void AMD_debug_init ( char *s ) ; + +GLOBAL void AMD_dump +( + Int n, + Int Pe [ ], + Int Iw [ ], + Int Len [ ], + Int iwlen, + Int pfree, + Int Nv [ ], + Int Next [ ], + Int Last [ ], + Int Head [ ], + Int Elen [ ], + Int Degree [ ], + Int W [ ], + Int nel +) ; + +#ifdef ASSERT +#undef ASSERT +#endif + +/* Use mxAssert if AMD is compiled into a mexFunction */ +#ifdef MATLAB_MEX_FILE +#define ASSERT(expression) (mxAssert ((expression), "")) +#else +#define ASSERT(expression) (assert (expression)) +#endif + +#define AMD_DEBUG0(params) { PRINTF (params) ; } +#define AMD_DEBUG1(params) { if (AMD_debug >= 1) PRINTF (params) ; } +#define AMD_DEBUG2(params) { if (AMD_debug >= 2) PRINTF (params) ; } +#define AMD_DEBUG3(params) { if (AMD_debug >= 3) PRINTF (params) ; } +#define AMD_DEBUG4(params) { if (AMD_debug >= 4) PRINTF (params) ; } + +#else + +/* no debugging */ +#define ASSERT(expression) +#define AMD_DEBUG0(params) +#define AMD_DEBUG1(params) +#define AMD_DEBUG2(params) +#define AMD_DEBUG3(params) +#define AMD_DEBUG4(params) + +#endif diff --git a/OpenDSSC/klusolve/AMD/MATLAB/Contents.m b/OpenDSSC/klusolve/AMD/MATLAB/Contents.m new file mode 100644 index 0000000..8d43c30 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/Contents.m @@ -0,0 +1,19 @@ +%Contents of the AMD sparse matrix ordering package: +% +% amd2 - p = amd2 (A), the approximate minimum degree ordering of A +% amd_demo - a demo of amd2, using the can_24 matrix +% amd_make - to compile amd2 for use in MATLAB +% amd_install - compile and install amd2 for use in MATLAB +% +% See also: amd, amd2, colamd, symamd, colmmd, symmmd, umfpack +% +% Note that amd2 and the built-in amd function in MATLAB 7.3 and later are one +% and the same. +% +% Example: +% p = amd2 (A) ; + +% Copyright 1994-2007, Tim Davis, University of Florida, +% Patrick R. Amestoy, and Iain S. Duff. + +help Contents diff --git a/OpenDSSC/klusolve/AMD/MATLAB/Makefile b/OpenDSSC/klusolve/AMD/MATLAB/Makefile new file mode 100644 index 0000000..9abad3c --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/Makefile @@ -0,0 +1,34 @@ +#------------------------------------------------------------------------------ +# Makefile for the AMD MATLAB mexFunction +#------------------------------------------------------------------------------ + +default: amd2 + +include ../../UFconfig/UFconfig.mk + +AMD = ../Lib/libamd.a + +I = -I../Include -I../../UFconfig + +INC = ../Include/amd.h ../Include/amd_internal.h ../../UFconfig/UFconfig.h + +SRC = ../Source/amd_1.c ../Source/amd_2.c ../Source/amd_aat.c \ + ../Source/amd_control.c ../Source/amd_defaults.c ../Source/amd_dump.c \ + ../Source/amd_global.c ../Source/amd_info.c ../Source/amd_order.c \ + ../Source/amd_postorder.c ../Source/amd_post_tree.c \ + ../Source/amd_preprocess.c ../Source/amd_valid.c + +amd2: $(SRC) $(INC) amd_mex.c + $(MEX) -DDLONG $(I) -output amd2 amd_mex.c $(SRC) + +#------------------------------------------------------------------------------ +# Remove all but the files in the original distribution +#------------------------------------------------------------------------------ + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) amd2.mex* diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd2.m b/OpenDSSC/klusolve/AMD/MATLAB/amd2.m new file mode 100644 index 0000000..41aa874 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd2.m @@ -0,0 +1,76 @@ +function [p, Info] = amd2 (A, Control) %#ok +%AMD2 p = amd2 (A), the approximate minimum degree ordering of A +% P = AMD2 (S) returns the approximate minimum degree permutation vector for +% the sparse matrix C = S+S'. The Cholesky factorization of C (P,P), or +% S (P,P), tends to be sparser than that of C or S. AMD tends to be faster +% than SYMMMD and SYMAMD, and tends to return better orderings than SYMMMD. +% S must be square. If S is full, amd(S) is equivalent to amd(sparse(S)). +% +% Note that the built-in AMD routine in MATLAB is identical to AMD2, +% except that AMD in MATLAB allows for a struct input to set the parameters. +% +% Usage: P = amd2 (S) ; % finds the ordering +% [P, Info] = amd2 (S, Control) ; % optional parameters & statistics +% Control = amd2 ; % returns default parameters +% amd2 ; % prints default parameters. +% +% Control (1); If S is n-by-n, then rows/columns with more than +% max (16, (Control (1))* sqrt(n)) entries in S+S' are considered +% "dense", and ignored during ordering. They are placed last in the +% output permutation. The default is 10.0 if Control is not present. +% Control (2): If nonzero, then aggressive absorption is performed. +% This is the default if Control is not present. +% Control (3): If nonzero, print statistics about the ordering. +% +% Info (1): status (0: ok, -1: out of memory, -2: matrix invalid) +% Info (2): n = size (A,1) +% Info (3): nnz (A) +% Info (4): the symmetry of the matrix S (0.0 means purely unsymmetric, +% 1.0 means purely symmetric). Computed as: +% B = tril (S, -1) + triu (S, 1) ; symmetry = nnz (B & B') / nnz (B); +% Info (5): nnz (diag (S)) +% Info (6): nnz in S+S', excluding the diagonal (= nnz (B+B')) +% Info (7): number "dense" rows/columns in S+S' +% Info (8): the amount of memory used by AMD, in bytes +% Info (9): the number of memory compactions performed by AMD +% +% The following statistics are slight upper bounds because of the +% approximate degree in AMD. The bounds are looser if "dense" rows/columns +% are ignored during ordering (Info (7) > 0). The statistics are for a +% subsequent factorization of the matrix C (P,P). The LU factorization +% statistics assume no pivoting. +% +% Info (10): the number of nonzeros in L, excluding the diagonal +% Info (11): the number of divide operations for LL', LDL', or LU +% Info (12): the number of multiply-subtract pairs for LL' or LDL' +% Info (13): the number of multiply-subtract pairs for LU +% Info (14): the max # of nonzeros in any column of L (incl. diagonal) +% Info (15:20): unused, reserved for future use +% +% An assembly tree post-ordering is performed, which is typically the same +% as an elimination tree post-ordering. It is not always identical because +% of the approximate degree update used, and because "dense" rows/columns +% do not take part in the post-order. It well-suited for a subsequent +% "chol", however. If you require a precise elimination tree post-ordering, +% then see the example below: +% +% Example: +% +% P = amd2 (S) ; +% C = spones (S) + spones (S') ; % skip this if S already symmetric +% [ignore, Q] = etree (C (P,P)) ; +% P = P (Q) ; +% +% See also AMD, COLMMD, COLAMD, COLPERM, SYMAMD, SYMMMD, SYMRCM. + +% -------------------------------------------------------------------------- +% Copyright 1994-2007, Tim Davis, University of Florida +% Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. +% email: davis at cise.ufl.edu CISE Department, Univ. of Florida. +% web: http://www.cise.ufl.edu/research/sparse/amd +% -------------------------------------------------------------------------- +% +% Acknowledgements: This work was supported by the National Science +% Foundation, under grants ASC-9111263, DMS-9223088, and CCR-0203270. + +error ('amd2 mexFunction not found') ; diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m b/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m new file mode 100644 index 0000000..c214bc7 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m @@ -0,0 +1,81 @@ +function amd_demo +%AMD_DEMO a demo of amd2, using the can_24 matrix +% +% A demo of AMD for MATLAB. +% +% Example: +% amd_demo +% +% See also: amd, amd2, amd_make + +% Copyright 1994-2007, Tim Davis, University of Florida, +% Patrick R. Amestoy, and Iain S. Duff. + +% This orders the same matrix as the ANSI C demo, amd_demo.c. It includes an +% additional analysis of the matrix via MATLAB's symbfact routine. + +% First, print the help information for AMD +help amd2 + +% Get the Harwell/Boeing can_24 matrix. + +load can_24 +A = spconvert (can_24) ; + +n = size (A,1) ; + +clf +subplot (2,2,1) ; +spy (A) +title ('HB/can24 matrix') ; + +% order the matrix. Note that the Info argument is optional. +fprintf ('\nIf the next step fails, then you have\n') ; +fprintf ('not yet compiled the AMD mexFunction.\n') ; +[p, Info] = amd2 (A) ; %#ok + +% order again, but this time print some statistics +[p, Info] = amd2 (A, [10 1 1]) ; + +fprintf ('Permutation vector:\n') ; +fprintf (' %2d', p) ; +fprintf ('\n\n') ; + +subplot (2,2,2) ; +spy (A (p,p)) ; +title ('Permuted matrix') ; + +% The amd_demo.c program stops here. + +fprintf ('Analyze A(p,p) with MATLAB''s symbfact routine:\n') ; +[cn, height, parent, post, R] = symbfact (A (p,p)) ; + +subplot (2,2,3) ; +spy (R') ; +title ('Cholesky factor, L') ; + +subplot (2,2,4) ; +treeplot (parent) ; +title ('elimination tree') ; + +% results from symbfact +lnz = sum (cn) ; % number of nonzeros in L, incl. diagonal +cn = cn - 1 ; % get the count of off-diagonal entries +fl = n + sum (cn.^2 + 2*cn) ; % flop count for chol (A (p,p) +fprintf ('number of nonzeros in L (including diagonal): %d\n', lnz) ; +fprintf ('floating point operation count for chol (A (p,p)): %d\n', fl) ; + +% approximations from amd: +lnz2 = n + Info (10) ; +fl2 = n + Info (11) + 2 * Info (12) ; +fprintf ('\nResults from AMD''s approximate analysis:\n') ; +fprintf ('number of nonzeros in L (including diagonal): %d\n', lnz2) ; +fprintf ('floating point operation count for chol (A (p,p)): %d\n\n', fl2) ; + +if (lnz2 ~= lnz | fl ~= fl2) %#ok + fprintf ('Note that the nonzero and flop counts from AMD are slight\n') ; + fprintf ('upper bounds. This is due to the approximate minimum degree\n'); + fprintf ('method used, in conjunction with "mass elimination".\n') ; + fprintf ('See the discussion about mass elimination in amd.h and\n') ; + fprintf ('amd_2.c for more details.\n') ; +end diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m.out b/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m.out new file mode 100644 index 0000000..4e64482 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd_demo.m.out @@ -0,0 +1,125 @@ +amd_demo + AMD2 p = amd2 (A), the approximate minimum degree ordering of A + P = AMD2 (S) returns the approximate minimum degree permutation vector for + the sparse matrix C = S+S'. The Cholesky factorization of C (P,P), or + S (P,P), tends to be sparser than that of C or S. AMD tends to be faster + than SYMMMD and SYMAMD, and tends to return better orderings than SYMMMD. + S must be square. If S is full, amd(S) is equivalent to amd(sparse(S)). + + Note that the built-in AMD routine in MATLAB is identical to AMD2, + except that AMD in MATLAB allows for a struct input to set the parameters. + + Usage: P = amd2 (S) ; % finds the ordering + [P, Info] = amd2 (S, Control) ; % optional parameters & statistics + Control = amd2 ; % returns default parameters + amd2 ; % prints default parameters. + + Control (1); If S is n-by-n, then rows/columns with more than + max (16, (Control (1))* sqrt(n)) entries in S+S' are considered + "dense", and ignored during ordering. They are placed last in the + output permutation. The default is 10.0 if Control is not present. + Control (2): If nonzero, then aggressive absorption is performed. + This is the default if Control is not present. + Control (3): If nonzero, print statistics about the ordering. + + Info (1): status (0: ok, -1: out of memory, -2: matrix invalid) + Info (2): n = size (A,1) + Info (3): nnz (A) + Info (4): the symmetry of the matrix S (0.0 means purely unsymmetric, + 1.0 means purely symmetric). Computed as: + B = tril (S, -1) + triu (S, 1) ; symmetry = nnz (B & B') / nnz (B); + Info (5): nnz (diag (S)) + Info (6): nnz in S+S', excluding the diagonal (= nnz (B+B')) + Info (7): number "dense" rows/columns in S+S' + Info (8): the amount of memory used by AMD, in bytes + Info (9): the number of memory compactions performed by AMD + + The following statistics are slight upper bounds because of the + approximate degree in AMD. The bounds are looser if "dense" rows/columns + are ignored during ordering (Info (7) > 0). The statistics are for a + subsequent factorization of the matrix C (P,P). The LU factorization + statistics assume no pivoting. + + Info (10): the number of nonzeros in L, excluding the diagonal + Info (11): the number of divide operations for LL', LDL', or LU + Info (12): the number of multiply-subtract pairs for LL' or LDL' + Info (13): the number of multiply-subtract pairs for LU + Info (14): the max # of nonzeros in any column of L (incl. diagonal) + Info (15:20): unused, reserved for future use + + An assembly tree post-ordering is performed, which is typically the same + as an elimination tree post-ordering. It is not always identical because + of the approximate degree update used, and because "dense" rows/columns + do not take part in the post-order. It well-suited for a subsequent + "chol", however. If you require a precise elimination tree post-ordering, + then see the example below: + + Example: + + P = amd2 (S) ; + C = spones (S) + spones (S') ; % skip this if S already symmetric + [ignore, Q] = etree (C (P,P)) ; + P = P (Q) ; + + See also AMD, COLMMD, COLAMD, COLPERM, SYMAMD, SYMMMD, SYMRCM. + + +If the next step fails, then you have +not yet compiled the AMD mexFunction. + +AMD version 2.2.0, May 31, 2007: approximate minimum degree ordering + dense row parameter: 10 + (rows with more than max (10 * sqrt (n), 16) entries are + considered "dense", and placed last in output permutation) + aggressive absorption: yes + size of AMD integer: 4 + + input matrix A is 24-by-24 + input matrix A has 160 nonzero entries + +AMD version 2.2.0, May 31, 2007, results: + status: OK + n, dimension of A: 24 + nz, number of nonzeros in A: 160 + symmetry of A: 1.0000 + number of nonzeros on diagonal: 24 + nonzeros in pattern of A+A' (excl. diagonal): 136 + # dense rows/columns of A+A': 0 + memory used, in bytes: 1516 + # of memory compactions: 0 + + The following approximate statistics are for a subsequent + factorization of A(P,P) + A(P,P)'. They are slight upper + bounds if there are no dense rows/columns in A+A', and become + looser if dense rows/columns exist. + + nonzeros in L (excluding diagonal): 97 + nonzeros in L (including diagonal): 121 + # divide operations for LDL' or LU: 97 + # multiply-subtract operations for LDL': 275 + # multiply-subtract operations for LU: 453 + max nz. in any column of L (incl. diagonal): 8 + + chol flop count for real A, sqrt counted as 1 flop: 671 + LDL' flop count for real A: 647 + LDL' flop count for complex A: 3073 + LU flop count for real A (with no pivoting): 1003 + LU flop count for complex A (with no pivoting): 4497 + +Permutation vector: + 23 21 11 24 13 6 17 9 15 5 16 8 2 10 14 18 1 3 4 7 12 19 22 20 + +Analyze A(p,p) with MATLAB's symbfact routine: +number of nonzeros in L (including diagonal): 120 +floating point operation count for chol (A (p,p)): 656 + +Results from AMD's approximate analysis: +number of nonzeros in L (including diagonal): 121 +floating point operation count for chol (A (p,p)): 671 + +Note that the nonzero and flop counts from AMD are slight +upper bounds. This is due to the approximate minimum degree +method used, in conjunction with "mass elimination". +See the discussion about mass elimination in amd.h and +amd_2.c for more details. +diary off diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd_install.m b/OpenDSSC/klusolve/AMD/MATLAB/amd_install.m new file mode 100644 index 0000000..844fc85 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd_install.m @@ -0,0 +1,20 @@ +function amd_install +%AMD_INSTALL compile and install amd2 for use in MATLAB +% Your current directory must be AMD/MATLAB for this function to work. +% +% Example: +% amd_install +% +% See also amd, amd2. + +% Copyright 1994-2007, Tim Davis, University of Florida, +% Patrick R. Amestoy, and Iain S. Duff. + +% This orders the same matrix as the ANSI C demo, amd_demo.c. It includes an + +amd_make +addpath (pwd) +fprintf ('\nThe following path has been added. You may wish to add it\n') ; +fprintf ('permanently, using the MATLAB pathtool command.\n') ; +fprintf ('%s\n\n', pwd) ; +amd_demo diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd_make.m b/OpenDSSC/klusolve/AMD/MATLAB/amd_make.m new file mode 100644 index 0000000..18e5b50 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd_make.m @@ -0,0 +1,32 @@ +function amd_make +%AMD_MAKE to compile amd2 for use in MATLAB +% +% Example: +% amd_make +% +% See also amd, amd2. + +% Copyright 1994-2007, Tim Davis, University of Florida, +% Patrick R. Amestoy, and Iain S. Duff. + +details = 0 ; % 1 if details of each command are to be printed + +d = '' ; +if (~isempty (strfind (computer, '64'))) + d = '-largeArrayDims' ; +end + +i = sprintf ('-I..%sInclude -I..%s..%sUFconfig', filesep, filesep, filesep) ; +cmd = sprintf ('mex -O %s -DDLONG -output amd2 %s amd_mex.c', d, i) ; +files = {'amd_order', 'amd_dump', 'amd_postorder', 'amd_post_tree', ... + 'amd_aat', 'amd_2', 'amd_1', 'amd_defaults', 'amd_control', ... + 'amd_info', 'amd_valid', 'amd_global', 'amd_preprocess' } ; +for i = 1 : length (files) + cmd = sprintf ('%s ..%sSource%s%s.c', cmd, filesep, filesep, files {i}) ; +end +if (details) + fprintf ('%s\n', cmd) ; +end +eval (cmd) ; + +fprintf ('AMD successfully compiled.\n') ; diff --git a/OpenDSSC/klusolve/AMD/MATLAB/amd_mex.c b/OpenDSSC/klusolve/AMD/MATLAB/amd_mex.c new file mode 100644 index 0000000..1d36c7b --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/amd_mex.c @@ -0,0 +1,199 @@ +/* ========================================================================= */ +/* === AMD mexFunction ===================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* + * Usage: + * p = amd (A) + * p = amd (A, Control) + * [p, Info] = amd (A) + * [p, Info] = amd (A, Control) + * Control = amd ; % return the default Control settings for AMD + * amd ; % print the default Control settings for AMD + * + * Given a square matrix A, compute a permutation P suitable for a Cholesky + * factorization of the matrix B (P,P), where B = spones (A) + spones (A'). + * The method used is the approximate minimum degree ordering method. See + * amd.m and amd.h for more information. + * + * The input matrix need not have sorted columns, and can have duplicate + * entries. + */ + +#include "amd.h" +#include "mex.h" +#include "matrix.h" +#include "UFconfig.h" + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + UF_long i, m, n, *Ap, *Ai, *P, nc, result, spumoni, full ; + double *Pout, *InfoOut, Control [AMD_CONTROL], Info [AMD_INFO], *ControlIn ; + mxArray *A ; + + /* --------------------------------------------------------------------- */ + /* get control parameters */ + /* --------------------------------------------------------------------- */ + + amd_malloc = mxMalloc ; + amd_free = mxFree ; + amd_calloc = mxCalloc ; + amd_realloc = mxRealloc ; + amd_printf = mexPrintf ; + + spumoni = 0 ; + if (nargin == 0) + { + /* get the default control parameters, and return */ + pargout [0] = mxCreateDoubleMatrix (AMD_CONTROL, 1, mxREAL) ; + amd_l_defaults (mxGetPr (pargout [0])) ; + if (nargout == 0) + { + amd_l_control (mxGetPr (pargout [0])) ; + } + return ; + } + + amd_l_defaults (Control) ; + if (nargin > 1) + { + ControlIn = mxGetPr (pargin [1]) ; + nc = mxGetM (pargin [1]) * mxGetN (pargin [1]) ; + Control [AMD_DENSE] + = (nc > 0) ? ControlIn [AMD_DENSE] : AMD_DEFAULT_DENSE ; + Control [AMD_AGGRESSIVE] + = (nc > 1) ? ControlIn [AMD_AGGRESSIVE] : AMD_DEFAULT_AGGRESSIVE ; + spumoni = (nc > 2) ? (ControlIn [2] != 0) : 0 ; + } + + if (spumoni > 0) + { + amd_l_control (Control) ; + } + + /* --------------------------------------------------------------------- */ + /* get inputs */ + /* --------------------------------------------------------------------- */ + + if (nargout > 2 || nargin > 2) + { + mexErrMsgTxt ("Usage: p = amd (A)\nor [p, Info] = amd (A, Control)") ; + } + + A = (mxArray *) pargin [0] ; + n = mxGetN (A) ; + m = mxGetM (A) ; + if (spumoni > 0) + { + mexPrintf (" input matrix A is %d-by-%d\n", m, n) ; + } + if (mxGetNumberOfDimensions (A) != 2) + { + mexErrMsgTxt ("amd: A must be 2-dimensional") ; + } + if (m != n) + { + mexErrMsgTxt ("amd: A must be square") ; + } + + /* --------------------------------------------------------------------- */ + /* allocate workspace for output permutation */ + /* --------------------------------------------------------------------- */ + + P = mxMalloc ((n+1) * sizeof (UF_long)) ; + + /* --------------------------------------------------------------------- */ + /* if A is full, convert to a sparse matrix */ + /* --------------------------------------------------------------------- */ + + full = !mxIsSparse (A) ; + if (full) + { + if (spumoni > 0) + { + mexPrintf ( + " input matrix A is full (sparse copy of A will be created)\n"); + } + mexCallMATLAB (1, &A, 1, (mxArray **) pargin, "sparse") ; + } + Ap = (UF_long *) mxGetJc (A) ; + Ai = (UF_long *) mxGetIr (A) ; + if (spumoni > 0) + { + mexPrintf (" input matrix A has %d nonzero entries\n", Ap [n]) ; + } + + /* --------------------------------------------------------------------- */ + /* order the matrix */ + /* --------------------------------------------------------------------- */ + + result = amd_l_order (n, Ap, Ai, P, Control, Info) ; + + /* --------------------------------------------------------------------- */ + /* if A is full, free the sparse copy of A */ + /* --------------------------------------------------------------------- */ + + if (full) + { + mxDestroyArray (A) ; + } + + /* --------------------------------------------------------------------- */ + /* print results (including return value) */ + /* --------------------------------------------------------------------- */ + + if (spumoni > 0) + { + amd_l_info (Info) ; + } + + /* --------------------------------------------------------------------- */ + /* check error conditions */ + /* --------------------------------------------------------------------- */ + + if (result == AMD_OUT_OF_MEMORY) + { + mexErrMsgTxt ("amd: out of memory") ; + } + else if (result == AMD_INVALID) + { + mexErrMsgTxt ("amd: input matrix A is corrupted") ; + } + + /* --------------------------------------------------------------------- */ + /* copy the outputs to MATLAB */ + /* --------------------------------------------------------------------- */ + + /* output permutation, P */ + pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; + Pout = mxGetPr (pargout [0]) ; + for (i = 0 ; i < n ; i++) + { + Pout [i] = P [i] + 1 ; /* change to 1-based indexing for MATLAB */ + } + mxFree (P) ; + + /* Info */ + if (nargout > 1) + { + pargout [1] = mxCreateDoubleMatrix (AMD_INFO, 1, mxREAL) ; + InfoOut = mxGetPr (pargout [1]) ; + for (i = 0 ; i < AMD_INFO ; i++) + { + InfoOut [i] = Info [i] ; + } + } +} diff --git a/OpenDSSC/klusolve/AMD/MATLAB/can_24 b/OpenDSSC/klusolve/AMD/MATLAB/can_24 new file mode 100644 index 0000000..38158a1 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/MATLAB/can_24 @@ -0,0 +1,160 @@ + 1 1 1 + 6 1 1 + 7 1 1 +13 1 1 +14 1 1 +18 1 1 +19 1 1 +20 1 1 +22 1 1 + 2 2 1 + 9 2 1 +10 2 1 +14 2 1 +15 2 1 +18 2 1 + 3 3 1 + 7 3 1 +12 3 1 +21 3 1 +22 3 1 +23 3 1 + 4 4 1 + 8 4 1 +11 4 1 +16 4 1 +19 4 1 +20 4 1 + 5 5 1 + 8 5 1 +10 5 1 +15 5 1 +16 5 1 +17 5 1 + 1 6 1 + 6 6 1 + 7 6 1 +13 6 1 +14 6 1 +18 6 1 + 1 7 1 + 3 7 1 + 6 7 1 + 7 7 1 +12 7 1 +13 7 1 +20 7 1 +22 7 1 +24 7 1 + 4 8 1 + 5 8 1 + 8 8 1 +10 8 1 +15 8 1 +16 8 1 +17 8 1 +18 8 1 +19 8 1 + 2 9 1 + 9 9 1 +10 9 1 +15 9 1 + 2 10 1 + 5 10 1 + 8 10 1 + 9 10 1 +10 10 1 +14 10 1 +15 10 1 +18 10 1 +19 10 1 + 4 11 1 +11 11 1 +19 11 1 +20 11 1 +21 11 1 +22 11 1 + 3 12 1 + 7 12 1 +12 12 1 +13 12 1 +22 12 1 +24 12 1 + 1 13 1 + 6 13 1 + 7 13 1 +12 13 1 +13 13 1 +24 13 1 + 1 14 1 + 2 14 1 + 6 14 1 +10 14 1 +14 14 1 +18 14 1 + 2 15 1 + 5 15 1 + 8 15 1 + 9 15 1 +10 15 1 +15 15 1 + 4 16 1 + 5 16 1 + 8 16 1 +16 16 1 +17 16 1 +19 16 1 + 5 17 1 + 8 17 1 +16 17 1 +17 17 1 + 1 18 1 + 2 18 1 + 6 18 1 + 8 18 1 +10 18 1 +14 18 1 +18 18 1 +19 18 1 +20 18 1 + 1 19 1 + 4 19 1 + 8 19 1 +10 19 1 +11 19 1 +16 19 1 +18 19 1 +19 19 1 +20 19 1 + 1 20 1 + 4 20 1 + 7 20 1 +11 20 1 +18 20 1 +19 20 1 +20 20 1 +21 20 1 +22 20 1 + 3 21 1 +11 21 1 +20 21 1 +21 21 1 +22 21 1 +23 21 1 + 1 22 1 + 3 22 1 + 7 22 1 +11 22 1 +12 22 1 +20 22 1 +21 22 1 +22 22 1 +23 22 1 + 3 23 1 +21 23 1 +22 23 1 +23 23 1 + 7 24 1 +12 24 1 +13 24 1 +24 24 1 diff --git a/OpenDSSC/klusolve/AMD/Makefile b/OpenDSSC/klusolve/AMD/Makefile new file mode 100644 index 0000000..8ef7887 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Makefile @@ -0,0 +1,83 @@ +#------------------------------------------------------------------------------ +# AMD Makefile (for GNU Make or original make) +#------------------------------------------------------------------------------ + +VERSION = 2.2.4 + +default: demos + +include ../UFconfig/UFconfig.mk + +# Compile all C code, including the C-callable routines. +# Do not compile the FORTRAN versions, or MATLAB interface. +demos: + ( cd Lib ; $(MAKE) ) + ( cd Demo ; $(MAKE) ) + +# Compile all C code, including the C-callable routine and the mexFunctions. +# Do not compile the FORTRAN versions. +all: + ( cd Lib ; $(MAKE) ) + ( cd Demo ; $(MAKE) ) + ( cd MATLAB ; $(MAKE) ) + +# compile just the C-callable libraries (not mexFunctions or Demos) +library: + ( cd Lib ; $(MAKE) ) + +# compile the FORTRAN libraries and demo programs (not compiled by "make all") +fortran: + ( cd Lib ; $(MAKE) fortran ) + ( cd Demo ; $(MAKE) fortran ) + +# compile a FORTRAN demo program that calls the C version of AMD +# (not compiled by "make all") +cross: + ( cd Demo ; $(MAKE) cross ) + +# remove object files, but keep the compiled programs and library archives +clean: + ( cd Lib ; $(MAKE) clean ) + ( cd Demo ; $(MAKE) clean ) + ( cd MATLAB ; $(MAKE) clean ) + ( cd Doc ; $(MAKE) clean ) + +# clean, and then remove compiled programs and library archives +purge: + ( cd Lib ; $(MAKE) purge ) + ( cd Demo ; $(MAKE) purge ) + ( cd MATLAB ; $(MAKE) purge ) + ( cd Doc ; $(MAKE) purge ) + +distclean: purge + +# create PDF documents for the original distribution +docs: + ( cd Doc ; $(MAKE) ) + +# get ready for distribution +dist: purge + ( cd Demo ; $(MAKE) dist ) + ( cd Doc ; $(MAKE) ) + +ccode: library + +lib: library + +# compile the MATLAB mexFunction +mex: + ( cd MATLAB ; $(MAKE) ) + +# install AMD +install: + $(CP) Lib/libamd.a $(INSTALL_LIB)/libamd.$(VERSION).a + ( cd $(INSTALL_LIB) ; ln -sf libamd.$(VERSION).a libamd.a ) + $(CP) Include/amd.h $(INSTALL_INCLUDE) + chmod 644 $(INSTALL_LIB)/libamd* + chmod 644 $(INSTALL_INCLUDE)/amd.h + +# uninstall AMD +uninstall: + $(RM) $(INSTALL_LIB)/libamd*.a + $(RM) $(INSTALL_INCLUDE)/amd.h + diff --git a/OpenDSSC/klusolve/AMD/README.txt b/OpenDSSC/klusolve/AMD/README.txt new file mode 100644 index 0000000..6383827 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/README.txt @@ -0,0 +1,215 @@ +AMD, Copyright (c) 2009-2011 by Timothy A. +Davis, Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. +AMD is available under alternate licences; contact T. Davis for details. + +AMD: a set of routines for permuting sparse matrices prior to + factorization. Includes a version in C, a version in Fortran, and a MATLAB + mexFunction. + +Requires UFconfig, in the ../UFconfig directory relative to this directory. + +Quick start (Unix, or Windows with Cygwin): + + To compile, test, and install AMD, you may wish to first configure the + installation by editting the ../UFconfig/UFconfig.mk file. Next, cd to this + directory (AMD) and type "make" (or "make lib" if you do not have MATLAB). + To compile and run a demo program for the Fortran version, type + "make fortran". When done, type "make clean" to remove unused *.o files + (keeps the compiled libraries and demo programs). See the User Guide + (Doc/AMD_UserGuide.pdf), or ../UFconfig/UFconfig.mk for more details. + +Quick start (for MATLAB users); + + To compile, test, and install the AMD mexFunction, cd to the + AMD/MATLAB directory and type amd_make at the MATLAB prompt. + +If you have MATLAB 7.2 or earlier and use "make mex", you must first edit +UFconfig/UFconfig.h to remove the "-largeArrayDims" option from the MEX command +(or just use amd_make.m inside MATLAB). + +------------------------------------------------------------------------------- + +AMD License: + + Your use or distribution of AMD or any modified version of + AMD implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + +Availability: + + http://www.cise.ufl.edu/research/sparse/amd + +------------------------------------------------------------------------------- + +This is the AMD README file. It is a terse overview of AMD. +Refer to the User Guide (Doc/AMD_UserGuide.pdf) for how to install +and use AMD. + +Description: + + AMD is a set of routines for pre-ordering sparse matrices prior to Cholesky + or LU factorization, using the approximate minimum degree ordering + algorithm. Written in ANSI/ISO C with a MATLAB interface, and in + Fortran 77. + +Authors: + + Timothy A. Davis (davis at cise.ufl.edu), University of Florida. + Patrick R. Amestory, ENSEEIHT, Toulouse, France. + Iain S. Duff, Rutherford Appleton Laboratory, UK. + +Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974, DMS-9803599, and CCR-0203270. + + Portions of this work were done while on sabbatical at Stanford University + and Lawrence Berkeley National Laboratory (with funding from the SciDAC + program). I would like to thank Gene Golub, Esmond Ng, and Horst Simon + for making this sabbatical possible. + +------------------------------------------------------------------------------- +Files and directories in the AMD distribution: +------------------------------------------------------------------------------- + + --------------------------------------------------------------------------- + Subdirectories of the AMD directory: + --------------------------------------------------------------------------- + + Doc documentation + Source primary source code + Include include file for use in your code that calls AMD + Demo demo programs. also serves as test of the AMD installation. + MATLAB AMD mexFunction for MATLAB, and supporting m-files + Lib where the compiled C-callable and Fortran-callable + AMD libraries placed. + + --------------------------------------------------------------------------- + Files in the AMD directory: + --------------------------------------------------------------------------- + + Makefile top-level Makefile for GNU make or original make. + Windows users would require Cygwin to use "make" + + README.txt this file + + --------------------------------------------------------------------------- + Doc directory: documentation + --------------------------------------------------------------------------- + + ChangeLog change log + License the AMD License + Makefile for creating the documentation + AMD_UserGuide.bib AMD User Guide (references) + AMD_UserGuide.tex AMD User Guide (LaTeX) + AMD_UserGuide.pdf AMD User Guide (PDF) + lesser.txt the GNU LGPL license + + --------------------------------------------------------------------------- + Source directory: + --------------------------------------------------------------------------- + + amd_order.c user-callable, primary AMD ordering routine + amd_control.c user-callable, prints the control parameters + amd_defaults.c user-callable, sets default control parameters + amd_info.c user-callable, prints the statistics from AMD + + amd_1.c non-user-callable, construct A+A' + amd_2.c user-callable, primary ordering kernel + (a C version of amd.f and amdbar.f, with + post-ordering added) + amd_aat.c non-user-callable, computes nnz (A+A') + amd_dump.c non-user-callable, debugging routines + amd_postorder.c non-user-callable, postorder + amd_post_tree.c non-user-callable, postorder just one tree + amd_valid.c non-user-callable, verifies a matrix + amd_preprocess.c non-user-callable, computes A', removes duplic + + amd.f user-callable Fortran 77 version + amdbar.f user-callable Fortran 77 version + + --------------------------------------------------------------------------- + Include directory: + --------------------------------------------------------------------------- + + amd.h include file for C programs that use AMD + amd_internal.h non-user-callable, include file for AMD + + --------------------------------------------------------------------------- + Demo directory: + --------------------------------------------------------------------------- + + Makefile for GNU make or original make + + amd_demo.c C demo program for AMD + amd_demo.out output of amd_demo.c + + amd_demo2.c C demo program for AMD, jumbled matrix + amd_demo2.out output of amd_demo2.c + + amd_l_demo.c C demo program for AMD (UF_long version) + amd_l_demo.out output of amd_l_demo.c + + amd_simple.c simple C demo program for AMD + amd_simple.out output of amd_simple.c + + amd_f77demo.f Fortran 77 demo program for AMD + amd_f77demo.out output of amd_f77demo.f + + amd_f77simple.c simple Fortran 77 demo program for AMD + amd_f77simple.out output of amd_f77simple.f + + amd_f77cross.f Fortran 77 demo, calls the C version of AMD + amd_f77cross.out output of amd_f77cross.f + amd_f77wrapper.c Fortran-callable wrapper for C version of AMD + + --------------------------------------------------------------------------- + MATLAB directory: + --------------------------------------------------------------------------- + + GNUmakefile a nice Makefile, for GNU make + Makefile an ugly Unix Makefile (for older make's) + + Contents.m for "help amd2" listing of toolbox contents + + amd2.m MATLAB help file for AMD + amd_make.m MATLAB m-file for compiling AMD mexFunction + amd_install.m compile and install the AMD mexFunction + + amd_mex.c AMD mexFunction for MATLAB + + amd_demo.m MATLAB demo for AMD + amd_demo.m.out diary output of amd_demo.m + can_24.mat input file for AMD demo + + --------------------------------------------------------------------------- + Lib directory: libamd.a and libamdf77.a libraries placed here + --------------------------------------------------------------------------- + + GNUmakefile a nice Makefile, for GNU make + Makefile an ugly Unix Makefile (for older make's) + libamd.def AMD definitions for Windows diff --git a/OpenDSSC/klusolve/AMD/Source/amd.f b/OpenDSSC/klusolve/AMD/Source/amd.f new file mode 100644 index 0000000..ccfe3e8 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd.f @@ -0,0 +1,1214 @@ +C----------------------------------------------------------------------- +C AMD: approximate minimum degree, with aggressive absorption +C----------------------------------------------------------------------- + + SUBROUTINE AMD + $ (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ LAST, HEAD, ELEN, DEGREE, NCMPA, W) + + INTEGER N, IWLEN, PFREE, NCMPA, IW (IWLEN), PE (N), + $ DEGREE (N), NV (N), NEXT (N), LAST (N), HEAD (N), + $ ELEN (N), W (N), LEN (N) + +C Given a representation of the nonzero pattern of a symmetric matrix, +C A, (excluding the diagonal) perform an approximate minimum +C (UMFPACK/MA38-style) degree ordering to compute a pivot order +C such that the introduction of nonzeros (fill-in) in the Cholesky +C factors A = LL^T are kept low. At each step, the pivot +C selected is the one with the minimum UMFPACK/MA38-style +C upper-bound on the external degree. +C +C Aggresive absorption is used to tighten the bound on the degree. + +C ********************************************************************** +C ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** +C ********************************************************************** + +C References: +C +C [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern +C multifrontal method for sparse LU factorization", SIAM J. +C Matrix Analysis and Applications, vol. 18, no. 1, pp. +C 140-158. Discusses UMFPACK / MA38, which first introduced +C the approximate minimum degree used by this routine. +C +C [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An +C approximate degree ordering algorithm," SIAM J. Matrix +C Analysis and Applications, vol. 17, no. 4, pp. 886-905, +C 1996. Discusses AMD, AMDBAR, and MC47B. +C +C [3] Alan George and Joseph Liu, "The evolution of the minimum +C degree ordering algorithm," SIAM Review, vol. 31, no. 1, +C pp. 1-19, 1989. We list below the features mentioned in +C that paper that this code includes: +C +C mass elimination: +C Yes. MA27 relied on supervariable detection for mass +C elimination. +C indistinguishable nodes: +C Yes (we call these "supervariables"). This was also in +C the MA27 code - although we modified the method of +C detecting them (the previous hash was the true degree, +C which we no longer keep track of). A supervariable is +C a set of rows with identical nonzero pattern. All +C variables in a supervariable are eliminated together. +C Each supervariable has as its numerical name that of +C one of its variables (its principal variable). +C quotient graph representation: +C Yes. We use the term "element" for the cliques formed +C during elimination. This was also in the MA27 code. +C The algorithm can operate in place, but it will work +C more efficiently if given some "elbow room." +C element absorption: +C Yes. This was also in the MA27 code. +C external degree: +C Yes. The MA27 code was based on the true degree. +C incomplete degree update and multiple elimination: +C No. This was not in MA27, either. Our method of +C degree update within MC47B/BD is element-based, not +C variable-based. It is thus not well-suited for use +C with incomplete degree update or multiple elimination. + +C----------------------------------------------------------------------- +C Authors, and Copyright (C) 1995 by: +C Timothy A. Davis, Patrick Amestoy, Iain S. Duff, & John K. Reid. +C +C Acknowledgements: +C This work (and the UMFPACK package) was supported by the +C National Science Foundation (ASC-9111263 and DMS-9223088). +C The UMFPACK/MA38 approximate degree update algorithm, the +C unsymmetric analog which forms the basis of MC47B/BD, was +C developed while Tim Davis was supported by CERFACS (Toulouse, +C France) in a post-doctoral position. +C +C Date: September, 1995 +C----------------------------------------------------------------------- + +C----------------------------------------------------------------------- +C INPUT ARGUMENTS (unaltered): +C----------------------------------------------------------------------- + +C n: The matrix order. +C +C Restriction: 1 .le. n .lt. (iovflo/2)-2, where iovflo is +C the largest positive integer that your computer can represent. + +C iwlen: The length of iw (1..iwlen). On input, the matrix is +C stored in iw (1..pfree-1). However, iw (1..iwlen) should be +C slightly larger than what is required to hold the matrix, at +C least iwlen .ge. pfree + n is recommended. Otherwise, +C excessive compressions will take place. +C *** We do not recommend running this algorithm with *** +C *** iwlen .lt. pfree + n. *** +C *** Better performance will be obtained if *** +C *** iwlen .ge. pfree + n *** +C *** or better yet *** +C *** iwlen .gt. 1.2 * pfree *** +C *** (where pfree is its value on input). *** +C The algorithm will not run at all if iwlen .lt. pfree-1. +C +C Restriction: iwlen .ge. pfree-1 + +C----------------------------------------------------------------------- +C INPUT/OUPUT ARGUMENTS: +C----------------------------------------------------------------------- + +C pe: On input, pe (i) is the index in iw of the start of row i, or +C zero if row i has no off-diagonal non-zeros. +C +C During execution, it is used for both supervariables and +C elements: +C +C * Principal supervariable i: index into iw of the +C description of supervariable i. A supervariable +C represents one or more rows of the matrix +C with identical nonzero pattern. +C * Non-principal supervariable i: if i has been absorbed +C into another supervariable j, then pe (i) = -j. +C That is, j has the same pattern as i. +C Note that j might later be absorbed into another +C supervariable j2, in which case pe (i) is still -j, +C and pe (j) = -j2. +C * Unabsorbed element e: the index into iw of the description +C of element e, if e has not yet been absorbed by a +C subsequent element. Element e is created when +C the supervariable of the same name is selected as +C the pivot. +C * Absorbed element e: if element e is absorbed into element +C e2, then pe (e) = -e2. This occurs when the pattern of +C e (that is, Le) is found to be a subset of the pattern +C of e2 (that is, Le2). If element e is "null" (it has +C no nonzeros outside its pivot block), then pe (e) = 0. +C +C On output, pe holds the assembly tree/forest, which implicitly +C represents a pivot order with identical fill-in as the actual +C order (via a depth-first search of the tree). +C +C On output: +C If nv (i) .gt. 0, then i represents a node in the assembly tree, +C and the parent of i is -pe (i), or zero if i is a root. +C If nv (i) = 0, then (i,-pe (i)) represents an edge in a +C subtree, the root of which is a node in the assembly tree. + +C pfree: On input the tail end of the array, iw (pfree..iwlen), +C is empty, and the matrix is stored in iw (1..pfree-1). +C During execution, additional data is placed in iw, and pfree +C is modified so that iw (pfree..iwlen) is always the unused part +C of iw. On output, pfree is set equal to the size of iw that +C would have been needed for no compressions to occur. If +C ncmpa is zero, then pfree (on output) is less than or equal to +C iwlen, and the space iw (pfree+1 ... iwlen) was not used. +C Otherwise, pfree (on output) is greater than iwlen, and all the +C memory in iw was used. + +C----------------------------------------------------------------------- +C INPUT/MODIFIED (undefined on output): +C----------------------------------------------------------------------- + +C len: On input, len (i) holds the number of entries in row i of the +C matrix, excluding the diagonal. The contents of len (1..n) +C are undefined on output. + +C iw: On input, iw (1..pfree-1) holds the description of each row i +C in the matrix. The matrix must be symmetric, and both upper +C and lower triangular parts must be present. The diagonal must +C not be present. Row i is held as follows: +C +C len (i): the length of the row i data structure +C iw (pe (i) ... pe (i) + len (i) - 1): +C the list of column indices for nonzeros +C in row i (simple supervariables), excluding +C the diagonal. All supervariables start with +C one row/column each (supervariable i is just +C row i). +C if len (i) is zero on input, then pe (i) is ignored +C on input. +C +C Note that the rows need not be in any particular order, +C and there may be empty space between the rows. +C +C During execution, the supervariable i experiences fill-in. +C This is represented by placing in i a list of the elements +C that cause fill-in in supervariable i: +C +C len (i): the length of supervariable i +C iw (pe (i) ... pe (i) + elen (i) - 1): +C the list of elements that contain i. This list +C is kept short by removing absorbed elements. +C iw (pe (i) + elen (i) ... pe (i) + len (i) - 1): +C the list of supervariables in i. This list +C is kept short by removing nonprincipal +C variables, and any entry j that is also +C contained in at least one of the elements +C (j in Le) in the list for i (e in row i). +C +C When supervariable i is selected as pivot, we create an +C element e of the same name (e=i): +C +C len (e): the length of element e +C iw (pe (e) ... pe (e) + len (e) - 1): +C the list of supervariables in element e. +C +C An element represents the fill-in that occurs when supervariable +C i is selected as pivot (which represents the selection of row i +C and all non-principal variables whose principal variable is i). +C We use the term Le to denote the set of all supervariables +C in element e. Absorbed supervariables and elements are pruned +C from these lists when computationally convenient. +C +C CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. +C The contents of iw are undefined on output. + +C----------------------------------------------------------------------- +C OUTPUT (need not be set on input): +C----------------------------------------------------------------------- + +C nv: During execution, abs (nv (i)) is equal to the number of rows +C that are represented by the principal supervariable i. If i is +C a nonprincipal variable, then nv (i) = 0. Initially, +C nv (i) = 1 for all i. nv (i) .lt. 0 signifies that i is a +C principal variable in the pattern Lme of the current pivot +C element me. On output, nv (e) holds the true degree of element +C e at the time it was created (including the diagonal part). + +C ncmpa: The number of times iw was compressed. If this is +C excessive, then the execution took longer than what could have +C been. To reduce ncmpa, try increasing iwlen to be 10% or 20% +C larger than the value of pfree on input (or at least +C iwlen .ge. pfree + n). The fastest performance will be +C obtained when ncmpa is returned as zero. If iwlen is set to +C the value returned by pfree on *output*, then no compressions +C will occur. + +C elen: See the description of iw above. At the start of execution, +C elen (i) is set to zero. During execution, elen (i) is the +C number of elements in the list for supervariable i. When e +C becomes an element, elen (e) = -nel is set, where nel is the +C current step of factorization. elen (i) = 0 is done when i +C becomes nonprincipal. +C +C For variables, elen (i) .ge. 0 holds until just before the +C permutation vectors are computed. For elements, +C elen (e) .lt. 0 holds. +C +C On output elen (1..n) holds the inverse permutation (the same +C as the 'INVP' argument in Sparspak). That is, if k = elen (i), +C then row i is the kth pivot row. Row i of A appears as the +C (elen(i))-th row in the permuted matrix, PAP^T. + +C last: In a degree list, last (i) is the supervariable preceding i, +C or zero if i is the head of the list. In a hash bucket, +C last (i) is the hash key for i. last (head (hash)) is also +C used as the head of a hash bucket if head (hash) contains a +C degree list (see head, below). +C +C On output, last (1..n) holds the permutation (the same as the +C 'PERM' argument in Sparspak). That is, if i = last (k), then +C row i is the kth pivot row. Row last (k) of A is the k-th row +C in the permuted matrix, PAP^T. + +C----------------------------------------------------------------------- +C LOCAL (not input or output - used only during execution): +C----------------------------------------------------------------------- + +C degree: If i is a supervariable, then degree (i) holds the +C current approximation of the external degree of row i (an upper +C bound). The external degree is the number of nonzeros in row i, +C minus abs (nv (i)) (the diagonal part). The bound is equal to +C the external degree if elen (i) is less than or equal to two. +C +C We also use the term "external degree" for elements e to refer +C to |Le \ Lme|. If e is an element, then degree (e) holds |Le|, +C which is the degree of the off-diagonal part of the element e +C (not including the diagonal part). + +C head: head is used for degree lists. head (deg) is the first +C supervariable in a degree list (all supervariables i in a +C degree list deg have the same approximate degree, namely, +C deg = degree (i)). If the list deg is empty then +C head (deg) = 0. +C +C During supervariable detection head (hash) also serves as a +C pointer to a hash bucket. +C If head (hash) .gt. 0, there is a degree list of degree hash. +C The hash bucket head pointer is last (head (hash)). +C If head (hash) = 0, then the degree list and hash bucket are +C both empty. +C If head (hash) .lt. 0, then the degree list is empty, and +C -head (hash) is the head of the hash bucket. +C After supervariable detection is complete, all hash buckets +C are empty, and the (last (head (hash)) = 0) condition is +C restored for the non-empty degree lists. + +C next: next (i) is the supervariable following i in a link list, or +C zero if i is the last in the list. Used for two kinds of +C lists: degree lists and hash buckets (a supervariable can be +C in only one kind of list at a time). + +C w: The flag array w determines the status of elements and +C variables, and the external degree of elements. +C +C for elements: +C if w (e) = 0, then the element e is absorbed +C if w (e) .ge. wflg, then w (e) - wflg is the size of +C the set |Le \ Lme|, in terms of nonzeros (the +C sum of abs (nv (i)) for each principal variable i that +C is both in the pattern of element e and NOT in the +C pattern of the current pivot element, me). +C if wflg .gt. w (e) .gt. 0, then e is not absorbed and has +C not yet been seen in the scan of the element lists in +C the computation of |Le\Lme| in loop 150 below. +C +C for variables: +C during supervariable detection, if w (j) .ne. wflg then j is +C not in the pattern of variable i +C +C The w array is initialized by setting w (i) = 1 for all i, +C and by setting wflg = 2. It is reinitialized if wflg becomes +C too large (to ensure that wflg+n does not cause integer +C overflow). + +C----------------------------------------------------------------------- +C LOCAL INTEGERS: +C----------------------------------------------------------------------- + + INTEGER DEG, DEGME, DEXT, DMAX, E, ELENME, ELN, HASH, HMOD, I, + $ ILAST, INEXT, J, JLAST, JNEXT, K, KNT1, KNT2, KNT3, + $ LENJ, LN, MAXMEM, ME, MEM, MINDEG, NEL, NEWMEM, + $ NLEFT, NVI, NVJ, NVPIV, SLENME, WE, WFLG, WNVI, X + +C deg: the degree of a variable or element +C degme: size, |Lme|, of the current element, me (= degree (me)) +C dext: external degree, |Le \ Lme|, of some element e +C dmax: largest |Le| seen so far +C e: an element +C elenme: the length, elen (me), of element list of pivotal var. +C eln: the length, elen (...), of an element list +C hash: the computed value of the hash function +C hmod: the hash function is computed modulo hmod = max (1,n-1) +C i: a supervariable +C ilast: the entry in a link list preceding i +C inext: the entry in a link list following i +C j: a supervariable +C jlast: the entry in a link list preceding j +C jnext: the entry in a link list, or path, following j +C k: the pivot order of an element or variable +C knt1: loop counter used during element construction +C knt2: loop counter used during element construction +C knt3: loop counter used during compression +C lenj: len (j) +C ln: length of a supervariable list +C maxmem: amount of memory needed for no compressions +C me: current supervariable being eliminated, and the +C current element created by eliminating that +C supervariable +C mem: memory in use assuming no compressions have occurred +C mindeg: current minimum degree +C nel: number of pivots selected so far +C newmem: amount of new memory needed for current pivot element +C nleft: n - nel, the number of nonpivotal rows/columns remaining +C nvi: the number of variables in a supervariable i (= nv (i)) +C nvj: the number of variables in a supervariable j (= nv (j)) +C nvpiv: number of pivots in current element +C slenme: number of variables in variable list of pivotal variable +C we: w (e) +C wflg: used for flagging the w array. See description of iw. +C wnvi: wflg - nv (i) +C x: either a supervariable or an element + +C----------------------------------------------------------------------- +C LOCAL POINTERS: +C----------------------------------------------------------------------- + + INTEGER P, P1, P2, P3, PDST, PEND, PJ, PME, PME1, PME2, PN, PSRC + +C Any parameter (pe (...) or pfree) or local variable +C starting with "p" (for Pointer) is an index into iw, +C and all indices into iw use variables starting with +C "p." The only exception to this rule is the iwlen +C input argument. + +C p: pointer into lots of things +C p1: pe (i) for some variable i (start of element list) +C p2: pe (i) + elen (i) - 1 for some var. i (end of el. list) +C p3: index of first supervariable in clean list +C pdst: destination pointer, for compression +C pend: end of memory to compress +C pj: pointer into an element or variable +C pme: pointer into the current element (pme1...pme2) +C pme1: the current element, me, is stored in iw (pme1...pme2) +C pme2: the end of the current element +C pn: pointer into a "clean" variable, also used to compress +C psrc: source pointer, for compression + +C----------------------------------------------------------------------- +C FUNCTIONS CALLED: +C----------------------------------------------------------------------- + + INTRINSIC MAX, MIN, MOD + +C======================================================================= +C INITIALIZATIONS +C======================================================================= + + WFLG = 2 + MINDEG = 1 + NCMPA = 0 + NEL = 0 + HMOD = MAX (1, N-1) + DMAX = 0 + MEM = PFREE - 1 + MAXMEM = MEM + ME = 0 + + DO 10 I = 1, N + LAST (I) = 0 + HEAD (I) = 0 + NV (I) = 1 + W (I) = 1 + ELEN (I) = 0 + DEGREE (I) = LEN (I) +10 CONTINUE + +C ---------------------------------------------------------------- +C initialize degree lists and eliminate rows with no off-diag. nz. +C ---------------------------------------------------------------- + + DO 20 I = 1, N + + DEG = DEGREE (I) + + IF (DEG .GT. 0) THEN + +C ---------------------------------------------------------- +C place i in the degree list corresponding to its degree +C ---------------------------------------------------------- + + INEXT = HEAD (DEG) + IF (INEXT .NE. 0) LAST (INEXT) = I + NEXT (I) = INEXT + HEAD (DEG) = I + + ELSE + +C ---------------------------------------------------------- +C we have a variable that can be eliminated at once because +C there is no off-diagonal non-zero in its row. +C ---------------------------------------------------------- + + NEL = NEL + 1 + ELEN (I) = -NEL + PE (I) = 0 + W (I) = 0 + + ENDIF + +20 CONTINUE + +C======================================================================= +C WHILE (selecting pivots) DO +C======================================================================= + +30 CONTINUE + IF (NEL .LT. N) THEN + +C======================================================================= +C GET PIVOT OF MINIMUM DEGREE +C======================================================================= + +C ------------------------------------------------------------- +C find next supervariable for elimination +C ------------------------------------------------------------- + + DO 40 DEG = MINDEG, N + ME = HEAD (DEG) + IF (ME .GT. 0) GOTO 50 +40 CONTINUE +50 CONTINUE + MINDEG = DEG + +C ------------------------------------------------------------- +C remove chosen variable from link list +C ------------------------------------------------------------- + + INEXT = NEXT (ME) + IF (INEXT .NE. 0) LAST (INEXT) = 0 + HEAD (DEG) = INEXT + +C ------------------------------------------------------------- +C me represents the elimination of pivots nel+1 to nel+nv(me). +C place me itself as the first in this set. It will be moved +C to the nel+nv(me) position when the permutation vectors are +C computed. +C ------------------------------------------------------------- + + ELENME = ELEN (ME) + ELEN (ME) = - (NEL + 1) + NVPIV = NV (ME) + NEL = NEL + NVPIV + +C======================================================================= +C CONSTRUCT NEW ELEMENT +C======================================================================= + +C ------------------------------------------------------------- +C At this point, me is the pivotal supervariable. It will be +C converted into the current element. Scan list of the +C pivotal supervariable, me, setting tree pointers and +C constructing new list of supervariables for the new element, +C me. p is a pointer to the current position in the old list. +C ------------------------------------------------------------- + +C flag the variable "me" as being in Lme by negating nv (me) + NV (ME) = -NVPIV + DEGME = 0 + + IF (ELENME .EQ. 0) THEN + +C ---------------------------------------------------------- +C construct the new element in place +C ---------------------------------------------------------- + + PME1 = PE (ME) + PME2 = PME1 - 1 + + DO 60 P = PME1, PME1 + LEN (ME) - 1 + I = IW (P) + NVI = NV (I) + IF (NVI .GT. 0) THEN + +C ---------------------------------------------------- +C i is a principal variable not yet placed in Lme. +C store i in new list +C ---------------------------------------------------- + + DEGME = DEGME + NVI +C flag i as being in Lme by negating nv (i) + NV (I) = -NVI + PME2 = PME2 + 1 + IW (PME2) = I + +C ---------------------------------------------------- +C remove variable i from degree list. +C ---------------------------------------------------- + + ILAST = LAST (I) + INEXT = NEXT (I) + IF (INEXT .NE. 0) LAST (INEXT) = ILAST + IF (ILAST .NE. 0) THEN + NEXT (ILAST) = INEXT + ELSE +C i is at the head of the degree list + HEAD (DEGREE (I)) = INEXT + ENDIF + + ENDIF +60 CONTINUE +C this element takes no new memory in iw: + NEWMEM = 0 + + ELSE + +C ---------------------------------------------------------- +C construct the new element in empty space, iw (pfree ...) +C ---------------------------------------------------------- + + P = PE (ME) + PME1 = PFREE + SLENME = LEN (ME) - ELENME + + DO 120 KNT1 = 1, ELENME + 1 + + IF (KNT1 .GT. ELENME) THEN +C search the supervariables in me. + E = ME + PJ = P + LN = SLENME + ELSE +C search the elements in me. + E = IW (P) + P = P + 1 + PJ = PE (E) + LN = LEN (E) + ENDIF + +C ------------------------------------------------------- +C search for different supervariables and add them to the +C new list, compressing when necessary. this loop is +C executed once for each element in the list and once for +C all the supervariables in the list. +C ------------------------------------------------------- + + DO 110 KNT2 = 1, LN + I = IW (PJ) + PJ = PJ + 1 + NVI = NV (I) + IF (NVI .GT. 0) THEN + +C ------------------------------------------------- +C compress iw, if necessary +C ------------------------------------------------- + + IF (PFREE .GT. IWLEN) THEN +C prepare for compressing iw by adjusting +C pointers and lengths so that the lists being +C searched in the inner and outer loops contain +C only the remaining entries. + + PE (ME) = P + LEN (ME) = LEN (ME) - KNT1 + IF (LEN (ME) .EQ. 0) THEN +C nothing left of supervariable me + PE (ME) = 0 + ENDIF + PE (E) = PJ + LEN (E) = LN - KNT2 + IF (LEN (E) .EQ. 0) THEN +C nothing left of element e + PE (E) = 0 + ENDIF + + NCMPA = NCMPA + 1 +C store first item in pe +C set first entry to -item + DO 70 J = 1, N + PN = PE (J) + IF (PN .GT. 0) THEN + PE (J) = IW (PN) + IW (PN) = -J + ENDIF +70 CONTINUE + +C psrc/pdst point to source/destination + PDST = 1 + PSRC = 1 + PEND = PME1 - 1 + +C while loop: +80 CONTINUE + IF (PSRC .LE. PEND) THEN +C search for next negative entry + J = -IW (PSRC) + PSRC = PSRC + 1 + IF (J .GT. 0) THEN + IW (PDST) = PE (J) + PE (J) = PDST + PDST = PDST + 1 +C copy from source to destination + LENJ = LEN (J) + DO 90 KNT3 = 0, LENJ - 2 + IW (PDST + KNT3) = IW (PSRC + KNT3) +90 CONTINUE + PDST = PDST + LENJ - 1 + PSRC = PSRC + LENJ - 1 + ENDIF + GOTO 80 + ENDIF + +C move the new partially-constructed element + P1 = PDST + DO 100 PSRC = PME1, PFREE - 1 + IW (PDST) = IW (PSRC) + PDST = PDST + 1 +100 CONTINUE + PME1 = P1 + PFREE = PDST + PJ = PE (E) + P = PE (ME) + ENDIF + +C ------------------------------------------------- +C i is a principal variable not yet placed in Lme +C store i in new list +C ------------------------------------------------- + + DEGME = DEGME + NVI +C flag i as being in Lme by negating nv (i) + NV (I) = -NVI + IW (PFREE) = I + PFREE = PFREE + 1 + +C ------------------------------------------------- +C remove variable i from degree link list +C ------------------------------------------------- + + ILAST = LAST (I) + INEXT = NEXT (I) + IF (INEXT .NE. 0) LAST (INEXT) = ILAST + IF (ILAST .NE. 0) THEN + NEXT (ILAST) = INEXT + ELSE +C i is at the head of the degree list + HEAD (DEGREE (I)) = INEXT + ENDIF + + ENDIF +110 CONTINUE + + IF (E .NE. ME) THEN +C set tree pointer and flag to indicate element e is +C absorbed into new element me (the parent of e is me) + PE (E) = -ME + W (E) = 0 + ENDIF +120 CONTINUE + + PME2 = PFREE - 1 +C this element takes newmem new memory in iw (possibly zero) + NEWMEM = PFREE - PME1 + MEM = MEM + NEWMEM + MAXMEM = MAX (MAXMEM, MEM) + ENDIF + +C ------------------------------------------------------------- +C me has now been converted into an element in iw (pme1..pme2) +C ------------------------------------------------------------- + +C degme holds the external degree of new element + DEGREE (ME) = DEGME + PE (ME) = PME1 + LEN (ME) = PME2 - PME1 + 1 + +C ------------------------------------------------------------- +C make sure that wflg is not too large. With the current +C value of wflg, wflg+n must not cause integer overflow +C ------------------------------------------------------------- + + IF (WFLG + N .LE. WFLG) THEN + DO 130 X = 1, N + IF (W (X) .NE. 0) W (X) = 1 +130 CONTINUE + WFLG = 2 + ENDIF + +C======================================================================= +C COMPUTE (w (e) - wflg) = |Le\Lme| FOR ALL ELEMENTS +C======================================================================= + +C ------------------------------------------------------------- +C Scan 1: compute the external degrees of previous elements +C with respect to the current element. That is: +C (w (e) - wflg) = |Le \ Lme| +C for each element e that appears in any supervariable in Lme. +C The notation Le refers to the pattern (list of +C supervariables) of a previous element e, where e is not yet +C absorbed, stored in iw (pe (e) + 1 ... pe (e) + iw (pe (e))). +C The notation Lme refers to the pattern of the current element +C (stored in iw (pme1..pme2)). If (w (e) - wflg) becomes +C zero, then the element e will be absorbed in scan 2. +C ------------------------------------------------------------- + + DO 150 PME = PME1, PME2 + I = IW (PME) + ELN = ELEN (I) + IF (ELN .GT. 0) THEN +C note that nv (i) has been negated to denote i in Lme: + NVI = -NV (I) + WNVI = WFLG - NVI + DO 140 P = PE (I), PE (I) + ELN - 1 + E = IW (P) + WE = W (E) + IF (WE .GE. WFLG) THEN +C unabsorbed element e has been seen in this loop + WE = WE - NVI + ELSE IF (WE .NE. 0) THEN +C e is an unabsorbed element +C this is the first we have seen e in all of Scan 1 + WE = DEGREE (E) + WNVI + ENDIF + W (E) = WE +140 CONTINUE + ENDIF +150 CONTINUE + +C======================================================================= +C DEGREE UPDATE AND ELEMENT ABSORPTION +C======================================================================= + +C ------------------------------------------------------------- +C Scan 2: for each i in Lme, sum up the degree of Lme (which +C is degme), plus the sum of the external degrees of each Le +C for the elements e appearing within i, plus the +C supervariables in i. Place i in hash list. +C ------------------------------------------------------------- + + DO 180 PME = PME1, PME2 + I = IW (PME) + P1 = PE (I) + P2 = P1 + ELEN (I) - 1 + PN = P1 + HASH = 0 + DEG = 0 + +C ---------------------------------------------------------- +C scan the element list associated with supervariable i +C ---------------------------------------------------------- + + DO 160 P = P1, P2 + E = IW (P) +C dext = | Le \ Lme | + DEXT = W (E) - WFLG + IF (DEXT .GT. 0) THEN + DEG = DEG + DEXT + IW (PN) = E + PN = PN + 1 + HASH = HASH + E + ELSE IF (DEXT .EQ. 0) THEN +C aggressive absorption: e is not adjacent to me, but +C the |Le \ Lme| is 0, so absorb it into me + PE (E) = -ME + W (E) = 0 + ELSE +C element e has already been absorbed, due to +C regular absorption, in do loop 120 above. Ignore it. + CONTINUE + ENDIF +160 CONTINUE + +C count the number of elements in i (including me): + ELEN (I) = PN - P1 + 1 + +C ---------------------------------------------------------- +C scan the supervariables in the list associated with i +C ---------------------------------------------------------- + + P3 = PN + DO 170 P = P2 + 1, P1 + LEN (I) - 1 + J = IW (P) + NVJ = NV (J) + IF (NVJ .GT. 0) THEN +C j is unabsorbed, and not in Lme. +C add to degree and add to new list + DEG = DEG + NVJ + IW (PN) = J + PN = PN + 1 + HASH = HASH + J + ENDIF +170 CONTINUE + +C ---------------------------------------------------------- +C update the degree and check for mass elimination +C ---------------------------------------------------------- + + IF (DEG .EQ. 0) THEN + +C ------------------------------------------------------- +C mass elimination +C ------------------------------------------------------- + +C There is nothing left of this node except for an +C edge to the current pivot element. elen (i) is 1, +C and there are no variables adjacent to node i. +C Absorb i into the current pivot element, me. + + PE (I) = -ME + NVI = -NV (I) + DEGME = DEGME - NVI + NVPIV = NVPIV + NVI + NEL = NEL + NVI + NV (I) = 0 + ELEN (I) = 0 + + ELSE + +C ------------------------------------------------------- +C update the upper-bound degree of i +C ------------------------------------------------------- + +C the following degree does not yet include the size +C of the current element, which is added later: + DEGREE (I) = MIN (DEGREE (I), DEG) + +C ------------------------------------------------------- +C add me to the list for i +C ------------------------------------------------------- + +C move first supervariable to end of list + IW (PN) = IW (P3) +C move first element to end of element part of list + IW (P3) = IW (P1) +C add new element to front of list. + IW (P1) = ME +C store the new length of the list in len (i) + LEN (I) = PN - P1 + 1 + +C ------------------------------------------------------- +C place in hash bucket. Save hash key of i in last (i). +C ------------------------------------------------------- + + HASH = MOD (HASH, HMOD) + 1 + J = HEAD (HASH) + IF (J .LE. 0) THEN +C the degree list is empty, hash head is -j + NEXT (I) = -J + HEAD (HASH) = -I + ELSE +C degree list is not empty +C use last (head (hash)) as hash head + NEXT (I) = LAST (J) + LAST (J) = I + ENDIF + LAST (I) = HASH + ENDIF +180 CONTINUE + + DEGREE (ME) = DEGME + +C ------------------------------------------------------------- +C Clear the counter array, w (...), by incrementing wflg. +C ------------------------------------------------------------- + + DMAX = MAX (DMAX, DEGME) + WFLG = WFLG + DMAX + +C make sure that wflg+n does not cause integer overflow + IF (WFLG + N .LE. WFLG) THEN + DO 190 X = 1, N + IF (W (X) .NE. 0) W (X) = 1 +190 CONTINUE + WFLG = 2 + ENDIF +C at this point, w (1..n) .lt. wflg holds + +C======================================================================= +C SUPERVARIABLE DETECTION +C======================================================================= + + DO 250 PME = PME1, PME2 + I = IW (PME) + IF (NV (I) .LT. 0) THEN +C i is a principal variable in Lme + +C ------------------------------------------------------- +C examine all hash buckets with 2 or more variables. We +C do this by examing all unique hash keys for super- +C variables in the pattern Lme of the current element, me +C ------------------------------------------------------- + + HASH = LAST (I) +C let i = head of hash bucket, and empty the hash bucket + J = HEAD (HASH) + IF (J .EQ. 0) GOTO 250 + IF (J .LT. 0) THEN +C degree list is empty + I = -J + HEAD (HASH) = 0 + ELSE +C degree list is not empty, restore last () of head + I = LAST (J) + LAST (J) = 0 + ENDIF + IF (I .EQ. 0) GOTO 250 + +C while loop: +200 CONTINUE + IF (NEXT (I) .NE. 0) THEN + +C ---------------------------------------------------- +C this bucket has one or more variables following i. +C scan all of them to see if i can absorb any entries +C that follow i in hash bucket. Scatter i into w. +C ---------------------------------------------------- + + LN = LEN (I) + ELN = ELEN (I) +C do not flag the first element in the list (me) + DO 210 P = PE (I) + 1, PE (I) + LN - 1 + W (IW (P)) = WFLG +210 CONTINUE + +C ---------------------------------------------------- +C scan every other entry j following i in bucket +C ---------------------------------------------------- + + JLAST = I + J = NEXT (I) + +C while loop: +220 CONTINUE + IF (J .NE. 0) THEN + +C ------------------------------------------------- +C check if j and i have identical nonzero pattern +C ------------------------------------------------- + + IF (LEN (J) .NE. LN) THEN +C i and j do not have same size data structure + GOTO 240 + ENDIF + IF (ELEN (J) .NE. ELN) THEN +C i and j do not have same number of adjacent el + GOTO 240 + ENDIF +C do not flag the first element in the list (me) + DO 230 P = PE (J) + 1, PE (J) + LN - 1 + IF (W (IW (P)) .NE. WFLG) THEN +C an entry (iw(p)) is in j but not in i + GOTO 240 + ENDIF +230 CONTINUE + +C ------------------------------------------------- +C found it! j can be absorbed into i +C ------------------------------------------------- + + PE (J) = -I +C both nv (i) and nv (j) are negated since they +C are in Lme, and the absolute values of each +C are the number of variables in i and j: + NV (I) = NV (I) + NV (J) + NV (J) = 0 + ELEN (J) = 0 +C delete j from hash bucket + J = NEXT (J) + NEXT (JLAST) = J + GOTO 220 + +C ------------------------------------------------- +240 CONTINUE +C j cannot be absorbed into i +C ------------------------------------------------- + + JLAST = J + J = NEXT (J) + GOTO 220 + ENDIF + +C ---------------------------------------------------- +C no more variables can be absorbed into i +C go to next i in bucket and clear flag array +C ---------------------------------------------------- + + WFLG = WFLG + 1 + I = NEXT (I) + IF (I .NE. 0) GOTO 200 + ENDIF + ENDIF +250 CONTINUE + +C======================================================================= +C RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVAR. FROM ELEMENT +C======================================================================= + + P = PME1 + NLEFT = N - NEL + DO 260 PME = PME1, PME2 + I = IW (PME) + NVI = -NV (I) + IF (NVI .GT. 0) THEN +C i is a principal variable in Lme +C restore nv (i) to signify that i is principal + NV (I) = NVI + +C ------------------------------------------------------- +C compute the external degree (add size of current elem) +C ------------------------------------------------------- + + DEG = MIN (DEGREE (I) + DEGME - NVI, NLEFT - NVI) + +C ------------------------------------------------------- +C place the supervariable at the head of the degree list +C ------------------------------------------------------- + + INEXT = HEAD (DEG) + IF (INEXT .NE. 0) LAST (INEXT) = I + NEXT (I) = INEXT + LAST (I) = 0 + HEAD (DEG) = I + +C ------------------------------------------------------- +C save the new degree, and find the minimum degree +C ------------------------------------------------------- + + MINDEG = MIN (MINDEG, DEG) + DEGREE (I) = DEG + +C ------------------------------------------------------- +C place the supervariable in the element pattern +C ------------------------------------------------------- + + IW (P) = I + P = P + 1 + ENDIF +260 CONTINUE + +C======================================================================= +C FINALIZE THE NEW ELEMENT +C======================================================================= + + NV (ME) = NVPIV + DEGME +C nv (me) is now the degree of pivot (including diagonal part) +C save the length of the list for the new element me + LEN (ME) = P - PME1 + IF (LEN (ME) .EQ. 0) THEN +C there is nothing left of the current pivot element + PE (ME) = 0 + W (ME) = 0 + ENDIF + IF (NEWMEM .NE. 0) THEN +C element was not constructed in place: deallocate part +C of it (final size is less than or equal to newmem, +C since newly nonprincipal variables have been removed). + PFREE = P + MEM = MEM - NEWMEM + LEN (ME) + ENDIF + +C======================================================================= +C END WHILE (selecting pivots) + GOTO 30 + ENDIF +C======================================================================= + +C======================================================================= +C COMPUTE THE PERMUTATION VECTORS +C======================================================================= + +C ---------------------------------------------------------------- +C The time taken by the following code is O(n). At this +C point, elen (e) = -k has been done for all elements e, +C and elen (i) = 0 has been done for all nonprincipal +C variables i. At this point, there are no principal +C supervariables left, and all elements are absorbed. +C ---------------------------------------------------------------- + +C ---------------------------------------------------------------- +C compute the ordering of unordered nonprincipal variables +C ---------------------------------------------------------------- + + DO 290 I = 1, N + IF (ELEN (I) .EQ. 0) THEN + +C ---------------------------------------------------------- +C i is an un-ordered row. Traverse the tree from i until +C reaching an element, e. The element, e, was the +C principal supervariable of i and all nodes in the path +C from i to when e was selected as pivot. +C ---------------------------------------------------------- + + J = -PE (I) +C while (j is a variable) do: +270 CONTINUE + IF (ELEN (J) .GE. 0) THEN + J = -PE (J) + GOTO 270 + ENDIF + E = J + +C ---------------------------------------------------------- +C get the current pivot ordering of e +C ---------------------------------------------------------- + + K = -ELEN (E) + +C ---------------------------------------------------------- +C traverse the path again from i to e, and compress the +C path (all nodes point to e). Path compression allows +C this code to compute in O(n) time. Order the unordered +C nodes in the path, and place the element e at the end. +C ---------------------------------------------------------- + + J = I +C while (j is a variable) do: +280 CONTINUE + IF (ELEN (J) .GE. 0) THEN + JNEXT = -PE (J) + PE (J) = -E + IF (ELEN (J) .EQ. 0) THEN +C j is an unordered row + ELEN (J) = K + K = K + 1 + ENDIF + J = JNEXT + GOTO 280 + ENDIF +C leave elen (e) negative, so we know it is an element + ELEN (E) = -K + ENDIF +290 CONTINUE + +C ---------------------------------------------------------------- +C reset the inverse permutation (elen (1..n)) to be positive, +C and compute the permutation (last (1..n)). +C ---------------------------------------------------------------- + + DO 300 I = 1, N + K = ABS (ELEN (I)) + LAST (K) = I + ELEN (I) = K +300 CONTINUE + +C======================================================================= +C RETURN THE MEMORY USAGE IN IW +C======================================================================= + +C If maxmem is less than or equal to iwlen, then no compressions +C occurred, and iw (maxmem+1 ... iwlen) was unused. Otherwise +C compressions did occur, and iwlen would have had to have been +C greater than or equal to maxmem for no compressions to occur. +C Return the value of maxmem in the pfree argument. + + PFREE = MAXMEM + + RETURN + END + diff --git a/OpenDSSC/klusolve/AMD/Source/amd_1.c b/OpenDSSC/klusolve/AMD/Source/amd_1.c new file mode 100644 index 0000000..30cb277 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_1.c @@ -0,0 +1,181 @@ +/* ========================================================================= */ +/* === AMD_1 =============================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_1: Construct A+A' for a sparse matrix A and perform the AMD ordering. + * + * The n-by-n sparse matrix A can be unsymmetric. It is stored in MATLAB-style + * compressed-column form, with sorted row indices in each column, and no + * duplicate entries. Diagonal entries may be present, but they are ignored. + * Row indices of column j of A are stored in Ai [Ap [j] ... Ap [j+1]-1]. + * Ap [0] must be zero, and nz = Ap [n] is the number of entries in A. The + * size of the matrix, n, must be greater than or equal to zero. + * + * This routine must be preceded by a call to AMD_aat, which computes the + * number of entries in each row/column in A+A', excluding the diagonal. + * Len [j], on input, is the number of entries in row/column j of A+A'. This + * routine constructs the matrix A+A' and then calls AMD_2. No error checking + * is performed (this was done in AMD_valid). + */ + +#include "amd_internal.h" + +GLOBAL void AMD_1 +( + Int n, /* n > 0 */ + const Int Ap [ ], /* input of size n+1, not modified */ + const Int Ai [ ], /* input of size nz = Ap [n], not modified */ + Int P [ ], /* size n output permutation */ + Int Pinv [ ], /* size n output inverse permutation */ + Int Len [ ], /* size n input, undefined on output */ + Int slen, /* slen >= sum (Len [0..n-1]) + 7n, + * ideally slen = 1.2 * sum (Len) + 8n */ + Int S [ ], /* size slen workspace */ + double Control [ ], /* input array of size AMD_CONTROL */ + double Info [ ] /* output array of size AMD_INFO */ +) +{ + Int i, j, k, p, pfree, iwlen, pj, p1, p2, pj2, *Iw, *Pe, *Nv, *Head, + *Elen, *Degree, *s, *W, *Sp, *Tp ; + + /* --------------------------------------------------------------------- */ + /* construct the matrix for AMD_2 */ + /* --------------------------------------------------------------------- */ + + ASSERT (n > 0) ; + + iwlen = slen - 6*n ; + s = S ; + Pe = s ; s += n ; + Nv = s ; s += n ; + Head = s ; s += n ; + Elen = s ; s += n ; + Degree = s ; s += n ; + W = s ; s += n ; + Iw = s ; s += iwlen ; + + ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; + + /* construct the pointers for A+A' */ + Sp = Nv ; /* use Nv and W as workspace for Sp and Tp [ */ + Tp = W ; + pfree = 0 ; + for (j = 0 ; j < n ; j++) + { + Pe [j] = pfree ; + Sp [j] = pfree ; + pfree += Len [j] ; + } + + /* Note that this restriction on iwlen is slightly more restrictive than + * what is strictly required in AMD_2. AMD_2 can operate with no elbow + * room at all, but it will be very slow. For better performance, at + * least size-n elbow room is enforced. */ + ASSERT (iwlen >= pfree + n) ; + +#ifndef NDEBUG + for (p = 0 ; p < iwlen ; p++) Iw [p] = EMPTY ; +#endif + + for (k = 0 ; k < n ; k++) + { + AMD_DEBUG1 (("Construct row/column k= "ID" of A+A'\n", k)) ; + p1 = Ap [k] ; + p2 = Ap [k+1] ; + + /* construct A+A' */ + for (p = p1 ; p < p2 ; ) + { + /* scan the upper triangular part of A */ + j = Ai [p] ; + ASSERT (j >= 0 && j < n) ; + if (j < k) + { + /* entry A (j,k) in the strictly upper triangular part */ + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + ASSERT (Sp [k] < (k == n-1 ? pfree : Pe [k+1])) ; + Iw [Sp [j]++] = k ; + Iw [Sp [k]++] = j ; + p++ ; + } + else if (j == k) + { + /* skip the diagonal */ + p++ ; + break ; + } + else /* j > k */ + { + /* first entry below the diagonal */ + break ; + } + /* scan lower triangular part of A, in column j until reaching + * row k. Start where last scan left off. */ + ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; + pj2 = Ap [j+1] ; + for (pj = Tp [j] ; pj < pj2 ; ) + { + i = Ai [pj] ; + ASSERT (i >= 0 && i < n) ; + if (i < k) + { + /* A (i,j) is only in the lower part, not in upper */ + ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + Iw [Sp [i]++] = j ; + Iw [Sp [j]++] = i ; + pj++ ; + } + else if (i == k) + { + /* entry A (k,j) in lower part and A (j,k) in upper */ + pj++ ; + break ; + } + else /* i > k */ + { + /* consider this entry later, when k advances to i */ + break ; + } + } + Tp [j] = pj ; + } + Tp [k] = p ; + } + + /* clean up, for remaining mismatched entries */ + for (j = 0 ; j < n ; j++) + { + for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) + { + i = Ai [pj] ; + ASSERT (i >= 0 && i < n) ; + /* A (i,j) is only in the lower part, not in upper */ + ASSERT (Sp [i] < (i == n-1 ? pfree : Pe [i+1])) ; + ASSERT (Sp [j] < (j == n-1 ? pfree : Pe [j+1])) ; + Iw [Sp [i]++] = j ; + Iw [Sp [j]++] = i ; + } + } + +#ifndef NDEBUG + for (j = 0 ; j < n-1 ; j++) ASSERT (Sp [j] == Pe [j+1]) ; + ASSERT (Sp [n-1] == pfree) ; +#endif + + /* Tp and Sp no longer needed ] */ + + /* --------------------------------------------------------------------- */ + /* order the matrix */ + /* --------------------------------------------------------------------- */ + + AMD_2 (n, Pe, Iw, Len, iwlen, pfree, + Nv, Pinv, P, Head, Elen, Degree, W, Control, Info) ; +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_2.c b/OpenDSSC/klusolve/AMD/Source/amd_2.c new file mode 100644 index 0000000..97b4f7a --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_2.c @@ -0,0 +1,1842 @@ +/* ========================================================================= */ +/* === AMD_2 =============================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_2: performs the AMD ordering on a symmetric sparse matrix A, followed + * by a postordering (via depth-first search) of the assembly tree using the + * AMD_postorder routine. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === clear_flag ========================================================== */ +/* ========================================================================= */ + +static Int clear_flag (Int wflg, Int wbig, Int W [ ], Int n) +{ + Int x ; + if (wflg < 2 || wflg >= wbig) + { + for (x = 0 ; x < n ; x++) + { + if (W [x] != 0) W [x] = 1 ; + } + wflg = 2 ; + } + /* at this point, W [0..n-1] < wflg holds */ + return (wflg) ; +} + + +/* ========================================================================= */ +/* === AMD_2 =============================================================== */ +/* ========================================================================= */ + +GLOBAL void AMD_2 +( + Int n, /* A is n-by-n, where n > 0 */ + Int Pe [ ], /* Pe [0..n-1]: index in Iw of row i on input */ + Int Iw [ ], /* workspace of size iwlen. Iw [0..pfree-1] + * holds the matrix on input */ + Int Len [ ], /* Len [0..n-1]: length for row/column i on input */ + Int iwlen, /* length of Iw. iwlen >= pfree + n */ + Int pfree, /* Iw [pfree ... iwlen-1] is empty on input */ + + /* 7 size-n workspaces, not defined on input: */ + Int Nv [ ], /* the size of each supernode on output */ + Int Next [ ], /* the output inverse permutation */ + Int Last [ ], /* the output permutation */ + Int Head [ ], + Int Elen [ ], /* the size columns of L for each supernode */ + Int Degree [ ], + Int W [ ], + + /* control parameters and output statistics */ + double Control [ ], /* array of size AMD_CONTROL */ + double Info [ ] /* array of size AMD_INFO */ +) +{ + +/* + * Given a representation of the nonzero pattern of a symmetric matrix, A, + * (excluding the diagonal) perform an approximate minimum (UMFPACK/MA38-style) + * degree ordering to compute a pivot order such that the introduction of + * nonzeros (fill-in) in the Cholesky factors A = LL' is kept low. At each + * step, the pivot selected is the one with the minimum UMFAPACK/MA38-style + * upper-bound on the external degree. This routine can optionally perform + * aggresive absorption (as done by MC47B in the Harwell Subroutine + * Library). + * + * The approximate degree algorithm implemented here is the symmetric analog of + * the degree update algorithm in MA38 and UMFPACK (the Unsymmetric-pattern + * MultiFrontal PACKage, both by Davis and Duff). The routine is based on the + * MA27 minimum degree ordering algorithm by Iain Duff and John Reid. + * + * This routine is a translation of the original AMDBAR and MC47B routines, + * in Fortran, with the following modifications: + * + * (1) dense rows/columns are removed prior to ordering the matrix, and placed + * last in the output order. The presence of a dense row/column can + * increase the ordering time by up to O(n^2), unless they are removed + * prior to ordering. + * + * (2) the minimum degree ordering is followed by a postordering (depth-first + * search) of the assembly tree. Note that mass elimination (discussed + * below) combined with the approximate degree update can lead to the mass + * elimination of nodes with lower exact degree than the current pivot + * element. No additional fill-in is caused in the representation of the + * Schur complement. The mass-eliminated nodes merge with the current + * pivot element. They are ordered prior to the current pivot element. + * Because they can have lower exact degree than the current element, the + * merger of two or more of these nodes in the current pivot element can + * lead to a single element that is not a "fundamental supernode". The + * diagonal block can have zeros in it. Thus, the assembly tree used here + * is not guaranteed to be the precise supernodal elemination tree (with + * "funadmental" supernodes), and the postordering performed by this + * routine is not guaranteed to be a precise postordering of the + * elimination tree. + * + * (3) input parameters are added, to control aggressive absorption and the + * detection of "dense" rows/columns of A. + * + * (4) additional statistical information is returned, such as the number of + * nonzeros in L, and the flop counts for subsequent LDL' and LU + * factorizations. These are slight upper bounds, because of the mass + * elimination issue discussed above. + * + * (5) additional routines are added to interface this routine to MATLAB + * to provide a simple C-callable user-interface, to check inputs for + * errors, compute the symmetry of the pattern of A and the number of + * nonzeros in each row/column of A+A', to compute the pattern of A+A', + * to perform the assembly tree postordering, and to provide debugging + * ouput. Many of these functions are also provided by the Fortran + * Harwell Subroutine Library routine MC47A. + * + * (6) both int and UF_long versions are provided. In the descriptions below + * and integer is and int or UF_long depending on which version is + * being used. + + ********************************************************************** + ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** + ********************************************************************** + ** If you want error checking, a more versatile input format, and a ** + ** simpler user interface, use amd_order or amd_l_order instead. ** + ** This routine is not meant to be user-callable. ** + ********************************************************************** + + * ---------------------------------------------------------------------------- + * References: + * ---------------------------------------------------------------------------- + * + * [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern multifrontal + * method for sparse LU factorization", SIAM J. Matrix Analysis and + * Applications, vol. 18, no. 1, pp. 140-158. Discusses UMFPACK / MA38, + * which first introduced the approximate minimum degree used by this + * routine. + * + * [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An approximate + * minimum degree ordering algorithm," SIAM J. Matrix Analysis and + * Applications, vol. 17, no. 4, pp. 886-905, 1996. Discusses AMDBAR and + * MC47B, which are the Fortran versions of this routine. + * + * [3] Alan George and Joseph Liu, "The evolution of the minimum degree + * ordering algorithm," SIAM Review, vol. 31, no. 1, pp. 1-19, 1989. + * We list below the features mentioned in that paper that this code + * includes: + * + * mass elimination: + * Yes. MA27 relied on supervariable detection for mass elimination. + * + * indistinguishable nodes: + * Yes (we call these "supervariables"). This was also in the MA27 + * code - although we modified the method of detecting them (the + * previous hash was the true degree, which we no longer keep track + * of). A supervariable is a set of rows with identical nonzero + * pattern. All variables in a supervariable are eliminated together. + * Each supervariable has as its numerical name that of one of its + * variables (its principal variable). + * + * quotient graph representation: + * Yes. We use the term "element" for the cliques formed during + * elimination. This was also in the MA27 code. The algorithm can + * operate in place, but it will work more efficiently if given some + * "elbow room." + * + * element absorption: + * Yes. This was also in the MA27 code. + * + * external degree: + * Yes. The MA27 code was based on the true degree. + * + * incomplete degree update and multiple elimination: + * No. This was not in MA27, either. Our method of degree update + * within MC47B is element-based, not variable-based. It is thus + * not well-suited for use with incomplete degree update or multiple + * elimination. + * + * Authors, and Copyright (C) 2004 by: + * Timothy A. Davis, Patrick Amestoy, Iain S. Duff, John K. Reid. + * + * Acknowledgements: This work (and the UMFPACK package) was supported by the + * National Science Foundation (ASC-9111263, DMS-9223088, and CCR-0203270). + * The UMFPACK/MA38 approximate degree update algorithm, the unsymmetric analog + * which forms the basis of AMD, was developed while Tim Davis was supported by + * CERFACS (Toulouse, France) in a post-doctoral position. This C version, and + * the etree postorder, were written while Tim Davis was on sabbatical at + * Stanford University and Lawrence Berkeley National Laboratory. + + * ---------------------------------------------------------------------------- + * INPUT ARGUMENTS (unaltered): + * ---------------------------------------------------------------------------- + + * n: The matrix order. Restriction: n >= 1. + * + * iwlen: The size of the Iw array. On input, the matrix is stored in + * Iw [0..pfree-1]. However, Iw [0..iwlen-1] should be slightly larger + * than what is required to hold the matrix, at least iwlen >= pfree + n. + * Otherwise, excessive compressions will take place. The recommended + * value of iwlen is 1.2 * pfree + n, which is the value used in the + * user-callable interface to this routine (amd_order.c). The algorithm + * will not run at all if iwlen < pfree. Restriction: iwlen >= pfree + n. + * Note that this is slightly more restrictive than the actual minimum + * (iwlen >= pfree), but AMD_2 will be very slow with no elbow room. + * Thus, this routine enforces a bare minimum elbow room of size n. + * + * pfree: On input the tail end of the array, Iw [pfree..iwlen-1], is empty, + * and the matrix is stored in Iw [0..pfree-1]. During execution, + * additional data is placed in Iw, and pfree is modified so that + * Iw [pfree..iwlen-1] is always the unused part of Iw. + * + * Control: A double array of size AMD_CONTROL containing input parameters + * that affect how the ordering is computed. If NULL, then default + * settings are used. + * + * Control [AMD_DENSE] is used to determine whether or not a given input + * row is "dense". A row is "dense" if the number of entries in the row + * exceeds Control [AMD_DENSE] times sqrt (n), except that rows with 16 or + * fewer entries are never considered "dense". To turn off the detection + * of dense rows, set Control [AMD_DENSE] to a negative number, or to a + * number larger than sqrt (n). The default value of Control [AMD_DENSE] + * is AMD_DEFAULT_DENSE, which is defined in amd.h as 10. + * + * Control [AMD_AGGRESSIVE] is used to determine whether or not aggressive + * absorption is to be performed. If nonzero, then aggressive absorption + * is performed (this is the default). + + * ---------------------------------------------------------------------------- + * INPUT/OUPUT ARGUMENTS: + * ---------------------------------------------------------------------------- + * + * Pe: An integer array of size n. On input, Pe [i] is the index in Iw of + * the start of row i. Pe [i] is ignored if row i has no off-diagonal + * entries. Thus Pe [i] must be in the range 0 to pfree-1 for non-empty + * rows. + * + * During execution, it is used for both supervariables and elements: + * + * Principal supervariable i: index into Iw of the description of + * supervariable i. A supervariable represents one or more rows of + * the matrix with identical nonzero pattern. In this case, + * Pe [i] >= 0. + * + * Non-principal supervariable i: if i has been absorbed into another + * supervariable j, then Pe [i] = FLIP (j), where FLIP (j) is defined + * as (-(j)-2). Row j has the same pattern as row i. Note that j + * might later be absorbed into another supervariable j2, in which + * case Pe [i] is still FLIP (j), and Pe [j] = FLIP (j2) which is + * < EMPTY, where EMPTY is defined as (-1) in amd_internal.h. + * + * Unabsorbed element e: the index into Iw of the description of element + * e, if e has not yet been absorbed by a subsequent element. Element + * e is created when the supervariable of the same name is selected as + * the pivot. In this case, Pe [i] >= 0. + * + * Absorbed element e: if element e is absorbed into element e2, then + * Pe [e] = FLIP (e2). This occurs when the pattern of e (which we + * refer to as Le) is found to be a subset of the pattern of e2 (that + * is, Le2). In this case, Pe [i] < EMPTY. If element e is "null" + * (it has no nonzeros outside its pivot block), then Pe [e] = EMPTY, + * and e is the root of an assembly subtree (or the whole tree if + * there is just one such root). + * + * Dense variable i: if i is "dense", then Pe [i] = EMPTY. + * + * On output, Pe holds the assembly tree/forest, which implicitly + * represents a pivot order with identical fill-in as the actual order + * (via a depth-first search of the tree), as follows. If Nv [i] > 0, + * then i represents a node in the assembly tree, and the parent of i is + * Pe [i], or EMPTY if i is a root. If Nv [i] = 0, then (i, Pe [i]) + * represents an edge in a subtree, the root of which is a node in the + * assembly tree. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Info: A double array of size AMD_INFO. If present, (that is, not NULL), + * then statistics about the ordering are returned in the Info array. + * See amd.h for a description. + + * ---------------------------------------------------------------------------- + * INPUT/MODIFIED (undefined on output): + * ---------------------------------------------------------------------------- + * + * Len: An integer array of size n. On input, Len [i] holds the number of + * entries in row i of the matrix, excluding the diagonal. The contents + * of Len are undefined on output. + * + * Iw: An integer array of size iwlen. On input, Iw [0..pfree-1] holds the + * description of each row i in the matrix. The matrix must be symmetric, + * and both upper and lower triangular parts must be present. The + * diagonal must not be present. Row i is held as follows: + * + * Len [i]: the length of the row i data structure in the Iw array. + * Iw [Pe [i] ... Pe [i] + Len [i] - 1]: + * the list of column indices for nonzeros in row i (simple + * supervariables), excluding the diagonal. All supervariables + * start with one row/column each (supervariable i is just row i). + * If Len [i] is zero on input, then Pe [i] is ignored on input. + * + * Note that the rows need not be in any particular order, and there + * may be empty space between the rows. + * + * During execution, the supervariable i experiences fill-in. This is + * represented by placing in i a list of the elements that cause fill-in + * in supervariable i: + * + * Len [i]: the length of supervariable i in the Iw array. + * Iw [Pe [i] ... Pe [i] + Elen [i] - 1]: + * the list of elements that contain i. This list is kept short + * by removing absorbed elements. + * Iw [Pe [i] + Elen [i] ... Pe [i] + Len [i] - 1]: + * the list of supervariables in i. This list is kept short by + * removing nonprincipal variables, and any entry j that is also + * contained in at least one of the elements (j in Le) in the list + * for i (e in row i). + * + * When supervariable i is selected as pivot, we create an element e of + * the same name (e=i): + * + * Len [e]: the length of element e in the Iw array. + * Iw [Pe [e] ... Pe [e] + Len [e] - 1]: + * the list of supervariables in element e. + * + * An element represents the fill-in that occurs when supervariable i is + * selected as pivot (which represents the selection of row i and all + * non-principal variables whose principal variable is i). We use the + * term Le to denote the set of all supervariables in element e. Absorbed + * supervariables and elements are pruned from these lists when + * computationally convenient. + * + * CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. + * The contents of Iw are undefined on output. + + * ---------------------------------------------------------------------------- + * OUTPUT (need not be set on input): + * ---------------------------------------------------------------------------- + * + * Nv: An integer array of size n. During execution, ABS (Nv [i]) is equal to + * the number of rows that are represented by the principal supervariable + * i. If i is a nonprincipal or dense variable, then Nv [i] = 0. + * Initially, Nv [i] = 1 for all i. Nv [i] < 0 signifies that i is a + * principal variable in the pattern Lme of the current pivot element me. + * After element me is constructed, Nv [i] is set back to a positive + * value. + * + * On output, Nv [i] holds the number of pivots represented by super + * row/column i of the original matrix, or Nv [i] = 0 for non-principal + * rows/columns. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Elen: An integer array of size n. See the description of Iw above. At the + * start of execution, Elen [i] is set to zero for all rows i. During + * execution, Elen [i] is the number of elements in the list for + * supervariable i. When e becomes an element, Elen [e] = FLIP (esize) is + * set, where esize is the size of the element (the number of pivots, plus + * the number of nonpivotal entries). Thus Elen [e] < EMPTY. + * Elen (i) = EMPTY set when variable i becomes nonprincipal. + * + * For variables, Elen (i) >= EMPTY holds until just before the + * postordering and permutation vectors are computed. For elements, + * Elen [e] < EMPTY holds. + * + * On output, Elen [i] is the degree of the row/column in the Cholesky + * factorization of the permuted matrix, corresponding to the original row + * i, if i is a super row/column. It is equal to EMPTY if i is + * non-principal. Note that i refers to a row/column in the original + * matrix, not the permuted matrix. + * + * Note that the contents of Elen on output differ from the Fortran + * version (Elen holds the inverse permutation in the Fortran version, + * which is instead returned in the Next array in this C version, + * described below). + * + * Last: In a degree list, Last [i] is the supervariable preceding i, or EMPTY + * if i is the head of the list. In a hash bucket, Last [i] is the hash + * key for i. + * + * Last [Head [hash]] is also used as the head of a hash bucket if + * Head [hash] contains a degree list (see the description of Head, + * below). + * + * On output, Last [0..n-1] holds the permutation. That is, if + * i = Last [k], then row i is the kth pivot row (where k ranges from 0 to + * n-1). Row Last [k] of A is the kth row in the permuted matrix, PAP'. + * + * Next: Next [i] is the supervariable following i in a link list, or EMPTY if + * i is the last in the list. Used for two kinds of lists: degree lists + * and hash buckets (a supervariable can be in only one kind of list at a + * time). + * + * On output Next [0..n-1] holds the inverse permutation. That is, if + * k = Next [i], then row i is the kth pivot row. Row i of A appears as + * the (Next[i])-th row in the permuted matrix, PAP'. + * + * Note that the contents of Next on output differ from the Fortran + * version (Next is undefined on output in the Fortran version). + + * ---------------------------------------------------------------------------- + * LOCAL WORKSPACE (not input or output - used only during execution): + * ---------------------------------------------------------------------------- + * + * Degree: An integer array of size n. If i is a supervariable, then + * Degree [i] holds the current approximation of the external degree of + * row i (an upper bound). The external degree is the number of nonzeros + * in row i, minus ABS (Nv [i]), the diagonal part. The bound is equal to + * the exact external degree if Elen [i] is less than or equal to two. + * + * We also use the term "external degree" for elements e to refer to + * |Le \ Lme|. If e is an element, then Degree [e] is |Le|, which is the + * degree of the off-diagonal part of the element e (not including the + * diagonal part). + * + * Head: An integer array of size n. Head is used for degree lists. + * Head [deg] is the first supervariable in a degree list. All + * supervariables i in a degree list Head [deg] have the same approximate + * degree, namely, deg = Degree [i]. If the list Head [deg] is empty then + * Head [deg] = EMPTY. + * + * During supervariable detection Head [hash] also serves as a pointer to + * a hash bucket. If Head [hash] >= 0, there is a degree list of degree + * hash. The hash bucket head pointer is Last [Head [hash]]. If + * Head [hash] = EMPTY, then the degree list and hash bucket are both + * empty. If Head [hash] < EMPTY, then the degree list is empty, and + * FLIP (Head [hash]) is the head of the hash bucket. After supervariable + * detection is complete, all hash buckets are empty, and the + * (Last [Head [hash]] = EMPTY) condition is restored for the non-empty + * degree lists. + * + * W: An integer array of size n. The flag array W determines the status of + * elements and variables, and the external degree of elements. + * + * for elements: + * if W [e] = 0, then the element e is absorbed. + * if W [e] >= wflg, then W [e] - wflg is the size of the set + * |Le \ Lme|, in terms of nonzeros (the sum of ABS (Nv [i]) for + * each principal variable i that is both in the pattern of + * element e and NOT in the pattern of the current pivot element, + * me). + * if wflg > W [e] > 0, then e is not absorbed and has not yet been + * seen in the scan of the element lists in the computation of + * |Le\Lme| in Scan 1 below. + * + * for variables: + * during supervariable detection, if W [j] != wflg then j is + * not in the pattern of variable i. + * + * The W array is initialized by setting W [i] = 1 for all i, and by + * setting wflg = 2. It is reinitialized if wflg becomes too large (to + * ensure that wflg+n does not cause integer overflow). + + * ---------------------------------------------------------------------------- + * LOCAL INTEGERS: + * ---------------------------------------------------------------------------- + */ + + Int deg, degme, dext, lemax, e, elenme, eln, i, ilast, inext, j, + jlast, jnext, k, knt1, knt2, knt3, lenj, ln, me, mindeg, nel, nleft, + nvi, nvj, nvpiv, slenme, wbig, we, wflg, wnvi, ok, ndense, ncmpa, + dense, aggressive ; + + unsigned Int hash ; /* unsigned, so that hash % n is well defined.*/ + +/* + * deg: the degree of a variable or element + * degme: size, |Lme|, of the current element, me (= Degree [me]) + * dext: external degree, |Le \ Lme|, of some element e + * lemax: largest |Le| seen so far (called dmax in Fortran version) + * e: an element + * elenme: the length, Elen [me], of element list of pivotal variable + * eln: the length, Elen [...], of an element list + * hash: the computed value of the hash function + * i: a supervariable + * ilast: the entry in a link list preceding i + * inext: the entry in a link list following i + * j: a supervariable + * jlast: the entry in a link list preceding j + * jnext: the entry in a link list, or path, following j + * k: the pivot order of an element or variable + * knt1: loop counter used during element construction + * knt2: loop counter used during element construction + * knt3: loop counter used during compression + * lenj: Len [j] + * ln: length of a supervariable list + * me: current supervariable being eliminated, and the current + * element created by eliminating that supervariable + * mindeg: current minimum degree + * nel: number of pivots selected so far + * nleft: n - nel, the number of nonpivotal rows/columns remaining + * nvi: the number of variables in a supervariable i (= Nv [i]) + * nvj: the number of variables in a supervariable j (= Nv [j]) + * nvpiv: number of pivots in current element + * slenme: number of variables in variable list of pivotal variable + * wbig: = INT_MAX - n for the int version, UF_long_max - n for the + * UF_long version. wflg is not allowed to be >= wbig. + * we: W [e] + * wflg: used for flagging the W array. See description of Iw. + * wnvi: wflg - Nv [i] + * x: either a supervariable or an element + * + * ok: true if supervariable j can be absorbed into i + * ndense: number of "dense" rows/columns + * dense: rows/columns with initial degree > dense are considered "dense" + * aggressive: true if aggressive absorption is being performed + * ncmpa: number of garbage collections + + * ---------------------------------------------------------------------------- + * LOCAL DOUBLES, used for statistical output only (except for alpha): + * ---------------------------------------------------------------------------- + */ + + double f, r, ndiv, s, nms_lu, nms_ldl, dmax, alpha, lnz, lnzme ; + +/* + * f: nvpiv + * r: degme + nvpiv + * ndiv: number of divisions for LU or LDL' factorizations + * s: number of multiply-subtract pairs for LU factorization, for the + * current element me + * nms_lu number of multiply-subtract pairs for LU factorization + * nms_ldl number of multiply-subtract pairs for LDL' factorization + * dmax: the largest number of entries in any column of L, including the + * diagonal + * alpha: "dense" degree ratio + * lnz: the number of nonzeros in L (excluding the diagonal) + * lnzme: the number of nonzeros in L (excl. the diagonal) for the + * current element me + + * ---------------------------------------------------------------------------- + * LOCAL "POINTERS" (indices into the Iw array) + * ---------------------------------------------------------------------------- +*/ + + Int p, p1, p2, p3, p4, pdst, pend, pj, pme, pme1, pme2, pn, psrc ; + +/* + * Any parameter (Pe [...] or pfree) or local variable starting with "p" (for + * Pointer) is an index into Iw, and all indices into Iw use variables starting + * with "p." The only exception to this rule is the iwlen input argument. + * + * p: pointer into lots of things + * p1: Pe [i] for some variable i (start of element list) + * p2: Pe [i] + Elen [i] - 1 for some variable i + * p3: index of first supervariable in clean list + * p4: + * pdst: destination pointer, for compression + * pend: end of memory to compress + * pj: pointer into an element or variable + * pme: pointer into the current element (pme1...pme2) + * pme1: the current element, me, is stored in Iw [pme1...pme2] + * pme2: the end of the current element + * pn: pointer into a "clean" variable, also used to compress + * psrc: source pointer, for compression +*/ + +/* ========================================================================= */ +/* INITIALIZATIONS */ +/* ========================================================================= */ + + /* Note that this restriction on iwlen is slightly more restrictive than + * what is actually required in AMD_2. AMD_2 can operate with no elbow + * room at all, but it will be slow. For better performance, at least + * size-n elbow room is enforced. */ + ASSERT (iwlen >= pfree + n) ; + ASSERT (n > 0) ; + + /* initialize output statistics */ + lnz = 0 ; + ndiv = 0 ; + nms_lu = 0 ; + nms_ldl = 0 ; + dmax = 1 ; + me = EMPTY ; + + mindeg = 0 ; + ncmpa = 0 ; + nel = 0 ; + lemax = 0 ; + + /* get control parameters */ + if (Control != (double *) NULL) + { + alpha = Control [AMD_DENSE] ; + aggressive = (Control [AMD_AGGRESSIVE] != 0) ; + } + else + { + alpha = AMD_DEFAULT_DENSE ; + aggressive = AMD_DEFAULT_AGGRESSIVE ; + } + /* Note: if alpha is NaN, this is undefined: */ + if (alpha < 0) + { + /* only remove completely dense rows/columns */ + dense = n-2 ; + } + else + { + dense = alpha * sqrt ((double) n) ; + } + dense = MAX (16, dense) ; + dense = MIN (n, dense) ; + AMD_DEBUG1 (("\n\nAMD (debug), alpha %g, aggr. "ID"\n", + alpha, aggressive)) ; + + for (i = 0 ; i < n ; i++) + { + Last [i] = EMPTY ; + Head [i] = EMPTY ; + Next [i] = EMPTY ; + /* if separate Hhead array is used for hash buckets: * + Hhead [i] = EMPTY ; + */ + Nv [i] = 1 ; + W [i] = 1 ; + Elen [i] = 0 ; + Degree [i] = Len [i] ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("\n======Nel "ID" initial\n", nel)) ; + AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, Last, + Head, Elen, Degree, W, -1) ; +#endif + + /* initialize wflg */ + wbig = Int_MAX - n ; + wflg = clear_flag (0, wbig, W, n) ; + + /* --------------------------------------------------------------------- */ + /* initialize degree lists and eliminate dense and empty rows */ + /* --------------------------------------------------------------------- */ + + ndense = 0 ; + + for (i = 0 ; i < n ; i++) + { + deg = Degree [i] ; + ASSERT (deg >= 0 && deg < n) ; + if (deg == 0) + { + + /* ------------------------------------------------------------- + * we have a variable that can be eliminated at once because + * there is no off-diagonal non-zero in its row. Note that + * Nv [i] = 1 for an empty variable i. It is treated just + * the same as an eliminated element i. + * ------------------------------------------------------------- */ + + Elen [i] = FLIP (1) ; + nel++ ; + Pe [i] = EMPTY ; + W [i] = 0 ; + + } + else if (deg > dense) + { + + /* ------------------------------------------------------------- + * Dense variables are not treated as elements, but as unordered, + * non-principal variables that have no parent. They do not take + * part in the postorder, since Nv [i] = 0. Note that the Fortran + * version does not have this option. + * ------------------------------------------------------------- */ + + AMD_DEBUG1 (("Dense node "ID" degree "ID"\n", i, deg)) ; + ndense++ ; + Nv [i] = 0 ; /* do not postorder this node */ + Elen [i] = EMPTY ; + nel++ ; + Pe [i] = EMPTY ; + + } + else + { + + /* ------------------------------------------------------------- + * place i in the degree list corresponding to its degree + * ------------------------------------------------------------- */ + + inext = Head [deg] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = i ; + Next [i] = inext ; + Head [deg] = i ; + + } + } + +/* ========================================================================= */ +/* WHILE (selecting pivots) DO */ +/* ========================================================================= */ + + while (nel < n) + { + +#ifndef NDEBUG + AMD_DEBUG1 (("\n======Nel "ID"\n", nel)) ; + if (AMD_debug >= 2) + { + AMD_dump (n, Pe, Iw, Len, iwlen, pfree, Nv, Next, + Last, Head, Elen, Degree, W, nel) ; + } +#endif + +/* ========================================================================= */ +/* GET PIVOT OF MINIMUM DEGREE */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- */ + /* find next supervariable for elimination */ + /* ----------------------------------------------------------------- */ + + ASSERT (mindeg >= 0 && mindeg < n) ; + for (deg = mindeg ; deg < n ; deg++) + { + me = Head [deg] ; + if (me != EMPTY) break ; + } + mindeg = deg ; + ASSERT (me >= 0 && me < n) ; + AMD_DEBUG1 (("=================me: "ID"\n", me)) ; + + /* ----------------------------------------------------------------- */ + /* remove chosen variable from link list */ + /* ----------------------------------------------------------------- */ + + inext = Next [me] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = EMPTY ; + Head [deg] = inext ; + + /* ----------------------------------------------------------------- */ + /* me represents the elimination of pivots nel to nel+Nv[me]-1. */ + /* place me itself as the first in this set. */ + /* ----------------------------------------------------------------- */ + + elenme = Elen [me] ; + nvpiv = Nv [me] ; + ASSERT (nvpiv > 0) ; + nel += nvpiv ; + +/* ========================================================================= */ +/* CONSTRUCT NEW ELEMENT */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * At this point, me is the pivotal supervariable. It will be + * converted into the current element. Scan list of the pivotal + * supervariable, me, setting tree pointers and constructing new list + * of supervariables for the new element, me. p is a pointer to the + * current position in the old list. + * ----------------------------------------------------------------- */ + + /* flag the variable "me" as being in Lme by negating Nv [me] */ + Nv [me] = -nvpiv ; + degme = 0 ; + ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; + + if (elenme == 0) + { + + /* ------------------------------------------------------------- */ + /* construct the new element in place */ + /* ------------------------------------------------------------- */ + + pme1 = Pe [me] ; + pme2 = pme1 - 1 ; + + for (p = pme1 ; p <= pme1 + Len [me] - 1 ; p++) + { + i = Iw [p] ; + ASSERT (i >= 0 && i < n && Nv [i] >= 0) ; + nvi = Nv [i] ; + if (nvi > 0) + { + + /* ----------------------------------------------------- */ + /* i is a principal variable not yet placed in Lme. */ + /* store i in new list */ + /* ----------------------------------------------------- */ + + /* flag i as being in Lme by negating Nv [i] */ + degme += nvi ; + Nv [i] = -nvi ; + Iw [++pme2] = i ; + + /* ----------------------------------------------------- */ + /* remove variable i from degree list. */ + /* ----------------------------------------------------- */ + + ilast = Last [i] ; + inext = Next [i] ; + ASSERT (ilast >= EMPTY && ilast < n) ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = ilast ; + if (ilast != EMPTY) + { + Next [ilast] = inext ; + } + else + { + /* i is at the head of the degree list */ + ASSERT (Degree [i] >= 0 && Degree [i] < n) ; + Head [Degree [i]] = inext ; + } + } + } + } + else + { + + /* ------------------------------------------------------------- */ + /* construct the new element in empty space, Iw [pfree ...] */ + /* ------------------------------------------------------------- */ + + p = Pe [me] ; + pme1 = pfree ; + slenme = Len [me] - elenme ; + + for (knt1 = 1 ; knt1 <= elenme + 1 ; knt1++) + { + + if (knt1 > elenme) + { + /* search the supervariables in me. */ + e = me ; + pj = p ; + ln = slenme ; + AMD_DEBUG2 (("Search sv: "ID" "ID" "ID"\n", me,pj,ln)) ; + } + else + { + /* search the elements in me. */ + e = Iw [p++] ; + ASSERT (e >= 0 && e < n) ; + pj = Pe [e] ; + ln = Len [e] ; + AMD_DEBUG2 (("Search element e "ID" in me "ID"\n", e,me)) ; + ASSERT (Elen [e] < EMPTY && W [e] > 0 && pj >= 0) ; + } + ASSERT (ln >= 0 && (ln == 0 || (pj >= 0 && pj < iwlen))) ; + + /* --------------------------------------------------------- + * search for different supervariables and add them to the + * new list, compressing when necessary. this loop is + * executed once for each element in the list and once for + * all the supervariables in the list. + * --------------------------------------------------------- */ + + for (knt2 = 1 ; knt2 <= ln ; knt2++) + { + i = Iw [pj++] ; + ASSERT (i >= 0 && i < n && (i == me || Elen [i] >= EMPTY)); + nvi = Nv [i] ; + AMD_DEBUG2 ((": "ID" "ID" "ID" "ID"\n", + i, Elen [i], Nv [i], wflg)) ; + + if (nvi > 0) + { + + /* ------------------------------------------------- */ + /* compress Iw, if necessary */ + /* ------------------------------------------------- */ + + if (pfree >= iwlen) + { + + AMD_DEBUG1 (("GARBAGE COLLECTION\n")) ; + + /* prepare for compressing Iw by adjusting pointers + * and lengths so that the lists being searched in + * the inner and outer loops contain only the + * remaining entries. */ + + Pe [me] = p ; + Len [me] -= knt1 ; + /* check if nothing left of supervariable me */ + if (Len [me] == 0) Pe [me] = EMPTY ; + Pe [e] = pj ; + Len [e] = ln - knt2 ; + /* nothing left of element e */ + if (Len [e] == 0) Pe [e] = EMPTY ; + + ncmpa++ ; /* one more garbage collection */ + + /* store first entry of each object in Pe */ + /* FLIP the first entry in each object */ + for (j = 0 ; j < n ; j++) + { + pn = Pe [j] ; + if (pn >= 0) + { + ASSERT (pn >= 0 && pn < iwlen) ; + Pe [j] = Iw [pn] ; + Iw [pn] = FLIP (j) ; + } + } + + /* psrc/pdst point to source/destination */ + psrc = 0 ; + pdst = 0 ; + pend = pme1 - 1 ; + + while (psrc <= pend) + { + /* search for next FLIP'd entry */ + j = FLIP (Iw [psrc++]) ; + if (j >= 0) + { + AMD_DEBUG2 (("Got object j: "ID"\n", j)) ; + Iw [pdst] = Pe [j] ; + Pe [j] = pdst++ ; + lenj = Len [j] ; + /* copy from source to destination */ + for (knt3 = 0 ; knt3 <= lenj - 2 ; knt3++) + { + Iw [pdst++] = Iw [psrc++] ; + } + } + } + + /* move the new partially-constructed element */ + p1 = pdst ; + for (psrc = pme1 ; psrc <= pfree-1 ; psrc++) + { + Iw [pdst++] = Iw [psrc] ; + } + pme1 = p1 ; + pfree = pdst ; + pj = Pe [e] ; + p = Pe [me] ; + + } + + /* ------------------------------------------------- */ + /* i is a principal variable not yet placed in Lme */ + /* store i in new list */ + /* ------------------------------------------------- */ + + /* flag i as being in Lme by negating Nv [i] */ + degme += nvi ; + Nv [i] = -nvi ; + Iw [pfree++] = i ; + AMD_DEBUG2 ((" s: "ID" nv "ID"\n", i, Nv [i])); + + /* ------------------------------------------------- */ + /* remove variable i from degree link list */ + /* ------------------------------------------------- */ + + ilast = Last [i] ; + inext = Next [i] ; + ASSERT (ilast >= EMPTY && ilast < n) ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = ilast ; + if (ilast != EMPTY) + { + Next [ilast] = inext ; + } + else + { + /* i is at the head of the degree list */ + ASSERT (Degree [i] >= 0 && Degree [i] < n) ; + Head [Degree [i]] = inext ; + } + } + } + + if (e != me) + { + /* set tree pointer and flag to indicate element e is + * absorbed into new element me (the parent of e is me) */ + AMD_DEBUG1 ((" Element "ID" => "ID"\n", e, me)) ; + Pe [e] = FLIP (me) ; + W [e] = 0 ; + } + } + + pme2 = pfree - 1 ; + } + + /* ----------------------------------------------------------------- */ + /* me has now been converted into an element in Iw [pme1..pme2] */ + /* ----------------------------------------------------------------- */ + + /* degme holds the external degree of new element */ + Degree [me] = degme ; + Pe [me] = pme1 ; + Len [me] = pme2 - pme1 + 1 ; + ASSERT (Pe [me] >= 0 && Pe [me] < iwlen) ; + + Elen [me] = FLIP (nvpiv + degme) ; + /* FLIP (Elen (me)) is now the degree of pivot (including + * diagonal part). */ + +#ifndef NDEBUG + AMD_DEBUG2 (("New element structure: length= "ID"\n", pme2-pme1+1)) ; + for (pme = pme1 ; pme <= pme2 ; pme++) AMD_DEBUG3 ((" "ID"", Iw[pme])); + AMD_DEBUG3 (("\n")) ; +#endif + + /* ----------------------------------------------------------------- */ + /* make sure that wflg is not too large. */ + /* ----------------------------------------------------------------- */ + + /* With the current value of wflg, wflg+n must not cause integer + * overflow */ + + wflg = clear_flag (wflg, wbig, W, n) ; + +/* ========================================================================= */ +/* COMPUTE (W [e] - wflg) = |Le\Lme| FOR ALL ELEMENTS */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * Scan 1: compute the external degrees of previous elements with + * respect to the current element. That is: + * (W [e] - wflg) = |Le \ Lme| + * for each element e that appears in any supervariable in Lme. The + * notation Le refers to the pattern (list of supervariables) of a + * previous element e, where e is not yet absorbed, stored in + * Iw [Pe [e] + 1 ... Pe [e] + Len [e]]. The notation Lme + * refers to the pattern of the current element (stored in + * Iw [pme1..pme2]). If aggressive absorption is enabled, and + * (W [e] - wflg) becomes zero, then the element e will be absorbed + * in Scan 2. + * ----------------------------------------------------------------- */ + + AMD_DEBUG2 (("me: ")) ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + eln = Elen [i] ; + AMD_DEBUG3 ((""ID" Elen "ID": \n", i, eln)) ; + if (eln > 0) + { + /* note that Nv [i] has been negated to denote i in Lme: */ + nvi = -Nv [i] ; + ASSERT (nvi > 0 && Pe [i] >= 0 && Pe [i] < iwlen) ; + wnvi = wflg - nvi ; + for (p = Pe [i] ; p <= Pe [i] + eln - 1 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + AMD_DEBUG4 ((" e "ID" we "ID" ", e, we)) ; + if (we >= wflg) + { + /* unabsorbed element e has been seen in this loop */ + AMD_DEBUG4 ((" unabsorbed, first time seen")) ; + we -= nvi ; + } + else if (we != 0) + { + /* e is an unabsorbed element */ + /* this is the first we have seen e in all of Scan 1 */ + AMD_DEBUG4 ((" unabsorbed")) ; + we = Degree [e] + wnvi ; + } + AMD_DEBUG4 (("\n")) ; + W [e] = we ; + } + } + } + AMD_DEBUG2 (("\n")) ; + +/* ========================================================================= */ +/* DEGREE UPDATE AND ELEMENT ABSORPTION */ +/* ========================================================================= */ + + /* ----------------------------------------------------------------- + * Scan 2: for each i in Lme, sum up the degree of Lme (which is + * degme), plus the sum of the external degrees of each Le for the + * elements e appearing within i, plus the supervariables in i. + * Place i in hash list. + * ----------------------------------------------------------------- */ + + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n && Nv [i] < 0 && Elen [i] >= 0) ; + AMD_DEBUG2 (("Updating: i "ID" "ID" "ID"\n", i, Elen[i], Len [i])); + p1 = Pe [i] ; + p2 = p1 + Elen [i] - 1 ; + pn = p1 ; + hash = 0 ; + deg = 0 ; + ASSERT (p1 >= 0 && p1 < iwlen && p2 >= -1 && p2 < iwlen) ; + + /* ------------------------------------------------------------- */ + /* scan the element list associated with supervariable i */ + /* ------------------------------------------------------------- */ + + /* UMFPACK/MA38-style approximate degree: */ + if (aggressive) + { + for (p = p1 ; p <= p2 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + if (we != 0) + { + /* e is an unabsorbed element */ + /* dext = | Le \ Lme | */ + dext = we - wflg ; + if (dext > 0) + { + deg += dext ; + Iw [pn++] = e ; + hash += e ; + AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; + } + else + { + /* external degree of e is zero, absorb e into me*/ + AMD_DEBUG1 ((" Element "ID" =>"ID" (aggressive)\n", + e, me)) ; + ASSERT (dext == 0) ; + Pe [e] = FLIP (me) ; + W [e] = 0 ; + } + } + } + } + else + { + for (p = p1 ; p <= p2 ; p++) + { + e = Iw [p] ; + ASSERT (e >= 0 && e < n) ; + we = W [e] ; + if (we != 0) + { + /* e is an unabsorbed element */ + dext = we - wflg ; + ASSERT (dext >= 0) ; + deg += dext ; + Iw [pn++] = e ; + hash += e ; + AMD_DEBUG4 ((" e: "ID" hash = "ID"\n",e,hash)) ; + } + } + } + + /* count the number of elements in i (including me): */ + Elen [i] = pn - p1 + 1 ; + + /* ------------------------------------------------------------- */ + /* scan the supervariables in the list associated with i */ + /* ------------------------------------------------------------- */ + + /* The bulk of the AMD run time is typically spent in this loop, + * particularly if the matrix has many dense rows that are not + * removed prior to ordering. */ + p3 = pn ; + p4 = p1 + Len [i] ; + for (p = p2 + 1 ; p < p4 ; p++) + { + j = Iw [p] ; + ASSERT (j >= 0 && j < n) ; + nvj = Nv [j] ; + if (nvj > 0) + { + /* j is unabsorbed, and not in Lme. */ + /* add to degree and add to new list */ + deg += nvj ; + Iw [pn++] = j ; + hash += j ; + AMD_DEBUG4 ((" s: "ID" hash "ID" Nv[j]= "ID"\n", + j, hash, nvj)) ; + } + } + + /* ------------------------------------------------------------- */ + /* update the degree and check for mass elimination */ + /* ------------------------------------------------------------- */ + + /* with aggressive absorption, deg==0 is identical to the + * Elen [i] == 1 && p3 == pn test, below. */ + ASSERT (IMPLIES (aggressive, (deg==0) == (Elen[i]==1 && p3==pn))) ; + + if (Elen [i] == 1 && p3 == pn) + { + + /* --------------------------------------------------------- */ + /* mass elimination */ + /* --------------------------------------------------------- */ + + /* There is nothing left of this node except for an edge to + * the current pivot element. Elen [i] is 1, and there are + * no variables adjacent to node i. Absorb i into the + * current pivot element, me. Note that if there are two or + * more mass eliminations, fillin due to mass elimination is + * possible within the nvpiv-by-nvpiv pivot block. It is this + * step that causes AMD's analysis to be an upper bound. + * + * The reason is that the selected pivot has a lower + * approximate degree than the true degree of the two mass + * eliminated nodes. There is no edge between the two mass + * eliminated nodes. They are merged with the current pivot + * anyway. + * + * No fillin occurs in the Schur complement, in any case, + * and this effect does not decrease the quality of the + * ordering itself, just the quality of the nonzero and + * flop count analysis. It also means that the post-ordering + * is not an exact elimination tree post-ordering. */ + + AMD_DEBUG1 ((" MASS i "ID" => parent e "ID"\n", i, me)) ; + Pe [i] = FLIP (me) ; + nvi = -Nv [i] ; + degme -= nvi ; + nvpiv += nvi ; + nel += nvi ; + Nv [i] = 0 ; + Elen [i] = EMPTY ; + + } + else + { + + /* --------------------------------------------------------- */ + /* update the upper-bound degree of i */ + /* --------------------------------------------------------- */ + + /* the following degree does not yet include the size + * of the current element, which is added later: */ + + Degree [i] = MIN (Degree [i], deg) ; + + /* --------------------------------------------------------- */ + /* add me to the list for i */ + /* --------------------------------------------------------- */ + + /* move first supervariable to end of list */ + Iw [pn] = Iw [p3] ; + /* move first element to end of element part of list */ + Iw [p3] = Iw [p1] ; + /* add new element, me, to front of list. */ + Iw [p1] = me ; + /* store the new length of the list in Len [i] */ + Len [i] = pn - p1 + 1 ; + + /* --------------------------------------------------------- */ + /* place in hash bucket. Save hash key of i in Last [i]. */ + /* --------------------------------------------------------- */ + + /* NOTE: this can fail if hash is negative, because the ANSI C + * standard does not define a % b when a and/or b are negative. + * That's why hash is defined as an unsigned Int, to avoid this + * problem. */ + hash = hash % n ; + ASSERT (((Int) hash) >= 0 && ((Int) hash) < n) ; + + /* if the Hhead array is not used: */ + j = Head [hash] ; + if (j <= EMPTY) + { + /* degree list is empty, hash head is FLIP (j) */ + Next [i] = FLIP (j) ; + Head [hash] = FLIP (i) ; + } + else + { + /* degree list is not empty, use Last [Head [hash]] as + * hash head. */ + Next [i] = Last [j] ; + Last [j] = i ; + } + + /* if a separate Hhead array is used: * + Next [i] = Hhead [hash] ; + Hhead [hash] = i ; + */ + + Last [i] = hash ; + } + } + + Degree [me] = degme ; + + /* ----------------------------------------------------------------- */ + /* Clear the counter array, W [...], by incrementing wflg. */ + /* ----------------------------------------------------------------- */ + + /* make sure that wflg+n does not cause integer overflow */ + lemax = MAX (lemax, degme) ; + wflg += lemax ; + wflg = clear_flag (wflg, wbig, W, n) ; + /* at this point, W [0..n-1] < wflg holds */ + +/* ========================================================================= */ +/* SUPERVARIABLE DETECTION */ +/* ========================================================================= */ + + AMD_DEBUG1 (("Detecting supervariables:\n")) ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + AMD_DEBUG2 (("Consider i "ID" nv "ID"\n", i, Nv [i])) ; + if (Nv [i] < 0) + { + /* i is a principal variable in Lme */ + + /* --------------------------------------------------------- + * examine all hash buckets with 2 or more variables. We do + * this by examing all unique hash keys for supervariables in + * the pattern Lme of the current element, me + * --------------------------------------------------------- */ + + /* let i = head of hash bucket, and empty the hash bucket */ + ASSERT (Last [i] >= 0 && Last [i] < n) ; + hash = Last [i] ; + + /* if Hhead array is not used: */ + j = Head [hash] ; + if (j == EMPTY) + { + /* hash bucket and degree list are both empty */ + i = EMPTY ; + } + else if (j < EMPTY) + { + /* degree list is empty */ + i = FLIP (j) ; + Head [hash] = EMPTY ; + } + else + { + /* degree list is not empty, restore Last [j] of head j */ + i = Last [j] ; + Last [j] = EMPTY ; + } + + /* if separate Hhead array is used: * + i = Hhead [hash] ; + Hhead [hash] = EMPTY ; + */ + + ASSERT (i >= EMPTY && i < n) ; + AMD_DEBUG2 (("----i "ID" hash "ID"\n", i, hash)) ; + + while (i != EMPTY && Next [i] != EMPTY) + { + + /* ----------------------------------------------------- + * this bucket has one or more variables following i. + * scan all of them to see if i can absorb any entries + * that follow i in hash bucket. Scatter i into w. + * ----------------------------------------------------- */ + + ln = Len [i] ; + eln = Elen [i] ; + ASSERT (ln >= 0 && eln >= 0) ; + ASSERT (Pe [i] >= 0 && Pe [i] < iwlen) ; + /* do not flag the first element in the list (me) */ + for (p = Pe [i] + 1 ; p <= Pe [i] + ln - 1 ; p++) + { + ASSERT (Iw [p] >= 0 && Iw [p] < n) ; + W [Iw [p]] = wflg ; + } + + /* ----------------------------------------------------- */ + /* scan every other entry j following i in bucket */ + /* ----------------------------------------------------- */ + + jlast = i ; + j = Next [i] ; + ASSERT (j >= EMPTY && j < n) ; + + while (j != EMPTY) + { + /* ------------------------------------------------- */ + /* check if j and i have identical nonzero pattern */ + /* ------------------------------------------------- */ + + AMD_DEBUG3 (("compare i "ID" and j "ID"\n", i,j)) ; + + /* check if i and j have the same Len and Elen */ + ASSERT (Len [j] >= 0 && Elen [j] >= 0) ; + ASSERT (Pe [j] >= 0 && Pe [j] < iwlen) ; + ok = (Len [j] == ln) && (Elen [j] == eln) ; + /* skip the first element in the list (me) */ + for (p = Pe [j] + 1 ; ok && p <= Pe [j] + ln - 1 ; p++) + { + ASSERT (Iw [p] >= 0 && Iw [p] < n) ; + if (W [Iw [p]] != wflg) ok = 0 ; + } + if (ok) + { + /* --------------------------------------------- */ + /* found it! j can be absorbed into i */ + /* --------------------------------------------- */ + + AMD_DEBUG1 (("found it! j "ID" => i "ID"\n", j,i)); + Pe [j] = FLIP (i) ; + /* both Nv [i] and Nv [j] are negated since they */ + /* are in Lme, and the absolute values of each */ + /* are the number of variables in i and j: */ + Nv [i] += Nv [j] ; + Nv [j] = 0 ; + Elen [j] = EMPTY ; + /* delete j from hash bucket */ + ASSERT (j != Next [j]) ; + j = Next [j] ; + Next [jlast] = j ; + + } + else + { + /* j cannot be absorbed into i */ + jlast = j ; + ASSERT (j != Next [j]) ; + j = Next [j] ; + } + ASSERT (j >= EMPTY && j < n) ; + } + + /* ----------------------------------------------------- + * no more variables can be absorbed into i + * go to next i in bucket and clear flag array + * ----------------------------------------------------- */ + + wflg++ ; + i = Next [i] ; + ASSERT (i >= EMPTY && i < n) ; + + } + } + } + AMD_DEBUG2 (("detect done\n")) ; + +/* ========================================================================= */ +/* RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVARIABLES FROM ELEMENT */ +/* ========================================================================= */ + + p = pme1 ; + nleft = n - nel ; + for (pme = pme1 ; pme <= pme2 ; pme++) + { + i = Iw [pme] ; + ASSERT (i >= 0 && i < n) ; + nvi = -Nv [i] ; + AMD_DEBUG3 (("Restore i "ID" "ID"\n", i, nvi)) ; + if (nvi > 0) + { + /* i is a principal variable in Lme */ + /* restore Nv [i] to signify that i is principal */ + Nv [i] = nvi ; + + /* --------------------------------------------------------- */ + /* compute the external degree (add size of current element) */ + /* --------------------------------------------------------- */ + + deg = Degree [i] + degme - nvi ; + deg = MIN (deg, nleft - nvi) ; + ASSERT (IMPLIES (aggressive, deg > 0) && deg >= 0 && deg < n) ; + + /* --------------------------------------------------------- */ + /* place the supervariable at the head of the degree list */ + /* --------------------------------------------------------- */ + + inext = Head [deg] ; + ASSERT (inext >= EMPTY && inext < n) ; + if (inext != EMPTY) Last [inext] = i ; + Next [i] = inext ; + Last [i] = EMPTY ; + Head [deg] = i ; + + /* --------------------------------------------------------- */ + /* save the new degree, and find the minimum degree */ + /* --------------------------------------------------------- */ + + mindeg = MIN (mindeg, deg) ; + Degree [i] = deg ; + + /* --------------------------------------------------------- */ + /* place the supervariable in the element pattern */ + /* --------------------------------------------------------- */ + + Iw [p++] = i ; + + } + } + AMD_DEBUG2 (("restore done\n")) ; + +/* ========================================================================= */ +/* FINALIZE THE NEW ELEMENT */ +/* ========================================================================= */ + + AMD_DEBUG2 (("ME = "ID" DONE\n", me)) ; + Nv [me] = nvpiv ; + /* save the length of the list for the new element me */ + Len [me] = p - pme1 ; + if (Len [me] == 0) + { + /* there is nothing left of the current pivot element */ + /* it is a root of the assembly tree */ + Pe [me] = EMPTY ; + W [me] = 0 ; + } + if (elenme != 0) + { + /* element was not constructed in place: deallocate part of */ + /* it since newly nonprincipal variables may have been removed */ + pfree = p ; + } + + /* The new element has nvpiv pivots and the size of the contribution + * block for a multifrontal method is degme-by-degme, not including + * the "dense" rows/columns. If the "dense" rows/columns are included, + * the frontal matrix is no larger than + * (degme+ndense)-by-(degme+ndense). + */ + + if (Info != (double *) NULL) + { + f = nvpiv ; + r = degme + ndense ; + dmax = MAX (dmax, f + r) ; + + /* number of nonzeros in L (excluding the diagonal) */ + lnzme = f*r + (f-1)*f/2 ; + lnz += lnzme ; + + /* number of divide operations for LDL' and for LU */ + ndiv += lnzme ; + + /* number of multiply-subtract pairs for LU */ + s = f*r*r + r*(f-1)*f + (f-1)*f*(2*f-1)/6 ; + nms_lu += s ; + + /* number of multiply-subtract pairs for LDL' */ + nms_ldl += (s + lnzme)/2 ; + } + +#ifndef NDEBUG + AMD_DEBUG2 (("finalize done nel "ID" n "ID"\n ::::\n", nel, n)) ; + for (pme = Pe [me] ; pme <= Pe [me] + Len [me] - 1 ; pme++) + { + AMD_DEBUG3 ((" "ID"", Iw [pme])) ; + } + AMD_DEBUG3 (("\n")) ; +#endif + + } + +/* ========================================================================= */ +/* DONE SELECTING PIVOTS */ +/* ========================================================================= */ + + if (Info != (double *) NULL) + { + + /* count the work to factorize the ndense-by-ndense submatrix */ + f = ndense ; + dmax = MAX (dmax, (double) ndense) ; + + /* number of nonzeros in L (excluding the diagonal) */ + lnzme = (f-1)*f/2 ; + lnz += lnzme ; + + /* number of divide operations for LDL' and for LU */ + ndiv += lnzme ; + + /* number of multiply-subtract pairs for LU */ + s = (f-1)*f*(2*f-1)/6 ; + nms_lu += s ; + + /* number of multiply-subtract pairs for LDL' */ + nms_ldl += (s + lnzme)/2 ; + + /* number of nz's in L (excl. diagonal) */ + Info [AMD_LNZ] = lnz ; + + /* number of divide ops for LU and LDL' */ + Info [AMD_NDIV] = ndiv ; + + /* number of multiply-subtract pairs for LDL' */ + Info [AMD_NMULTSUBS_LDL] = nms_ldl ; + + /* number of multiply-subtract pairs for LU */ + Info [AMD_NMULTSUBS_LU] = nms_lu ; + + /* number of "dense" rows/columns */ + Info [AMD_NDENSE] = ndense ; + + /* largest front is dmax-by-dmax */ + Info [AMD_DMAX] = dmax ; + + /* number of garbage collections in AMD */ + Info [AMD_NCMPA] = ncmpa ; + + /* successful ordering */ + Info [AMD_STATUS] = AMD_OK ; + } + +/* ========================================================================= */ +/* POST-ORDERING */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- + * Variables at this point: + * + * Pe: holds the elimination tree. The parent of j is FLIP (Pe [j]), + * or EMPTY if j is a root. The tree holds both elements and + * non-principal (unordered) variables absorbed into them. + * Dense variables are non-principal and unordered. + * + * Elen: holds the size of each element, including the diagonal part. + * FLIP (Elen [e]) > 0 if e is an element. For unordered + * variables i, Elen [i] is EMPTY. + * + * Nv: Nv [e] > 0 is the number of pivots represented by the element e. + * For unordered variables i, Nv [i] is zero. + * + * Contents no longer needed: + * W, Iw, Len, Degree, Head, Next, Last. + * + * The matrix itself has been destroyed. + * + * n: the size of the matrix. + * No other scalars needed (pfree, iwlen, etc.) + * ------------------------------------------------------------------------- */ + + /* restore Pe */ + for (i = 0 ; i < n ; i++) + { + Pe [i] = FLIP (Pe [i]) ; + } + + /* restore Elen, for output information, and for postordering */ + for (i = 0 ; i < n ; i++) + { + Elen [i] = FLIP (Elen [i]) ; + } + +/* Now the parent of j is Pe [j], or EMPTY if j is a root. Elen [e] > 0 + * is the size of element e. Elen [i] is EMPTY for unordered variable i. */ + +#ifndef NDEBUG + AMD_DEBUG2 (("\nTree:\n")) ; + for (i = 0 ; i < n ; i++) + { + AMD_DEBUG2 ((" "ID" parent: "ID" ", i, Pe [i])) ; + ASSERT (Pe [i] >= EMPTY && Pe [i] < n) ; + if (Nv [i] > 0) + { + /* this is an element */ + e = i ; + AMD_DEBUG2 ((" element, size is "ID"\n", Elen [i])) ; + ASSERT (Elen [e] > 0) ; + } + AMD_DEBUG2 (("\n")) ; + } + AMD_DEBUG2 (("\nelements:\n")) ; + for (e = 0 ; e < n ; e++) + { + if (Nv [e] > 0) + { + AMD_DEBUG3 (("Element e= "ID" size "ID" nv "ID" \n", e, + Elen [e], Nv [e])) ; + } + } + AMD_DEBUG2 (("\nvariables:\n")) ; + for (i = 0 ; i < n ; i++) + { + Int cnt ; + if (Nv [i] == 0) + { + AMD_DEBUG3 (("i unordered: "ID"\n", i)) ; + j = Pe [i] ; + cnt = 0 ; + AMD_DEBUG3 ((" j: "ID"\n", j)) ; + if (j == EMPTY) + { + AMD_DEBUG3 ((" i is a dense variable\n")) ; + } + else + { + ASSERT (j >= 0 && j < n) ; + while (Nv [j] == 0) + { + AMD_DEBUG3 ((" j : "ID"\n", j)) ; + j = Pe [j] ; + AMD_DEBUG3 ((" j:: "ID"\n", j)) ; + cnt++ ; + if (cnt > n) break ; + } + e = j ; + AMD_DEBUG3 ((" got to e: "ID"\n", e)) ; + } + } + } +#endif + +/* ========================================================================= */ +/* compress the paths of the variables */ +/* ========================================================================= */ + + for (i = 0 ; i < n ; i++) + { + if (Nv [i] == 0) + { + + /* ------------------------------------------------------------- + * i is an un-ordered row. Traverse the tree from i until + * reaching an element, e. The element, e, was the principal + * supervariable of i and all nodes in the path from i to when e + * was selected as pivot. + * ------------------------------------------------------------- */ + + AMD_DEBUG1 (("Path compression, i unordered: "ID"\n", i)) ; + j = Pe [i] ; + ASSERT (j >= EMPTY && j < n) ; + AMD_DEBUG3 ((" j: "ID"\n", j)) ; + if (j == EMPTY) + { + /* Skip a dense variable. It has no parent. */ + AMD_DEBUG3 ((" i is a dense variable\n")) ; + continue ; + } + + /* while (j is a variable) */ + while (Nv [j] == 0) + { + AMD_DEBUG3 ((" j : "ID"\n", j)) ; + j = Pe [j] ; + AMD_DEBUG3 ((" j:: "ID"\n", j)) ; + ASSERT (j >= 0 && j < n) ; + } + /* got to an element e */ + e = j ; + AMD_DEBUG3 (("got to e: "ID"\n", e)) ; + + /* ------------------------------------------------------------- + * traverse the path again from i to e, and compress the path + * (all nodes point to e). Path compression allows this code to + * compute in O(n) time. + * ------------------------------------------------------------- */ + + j = i ; + /* while (j is a variable) */ + while (Nv [j] == 0) + { + jnext = Pe [j] ; + AMD_DEBUG3 (("j "ID" jnext "ID"\n", j, jnext)) ; + Pe [j] = e ; + j = jnext ; + ASSERT (j >= 0 && j < n) ; + } + } + } + +/* ========================================================================= */ +/* postorder the assembly tree */ +/* ========================================================================= */ + + AMD_postorder (n, Pe, Nv, Elen, + W, /* output order */ + Head, Next, Last) ; /* workspace */ + +/* ========================================================================= */ +/* compute output permutation and inverse permutation */ +/* ========================================================================= */ + + /* W [e] = k means that element e is the kth element in the new + * order. e is in the range 0 to n-1, and k is in the range 0 to + * the number of elements. Use Head for inverse order. */ + + for (k = 0 ; k < n ; k++) + { + Head [k] = EMPTY ; + Next [k] = EMPTY ; + } + for (e = 0 ; e < n ; e++) + { + k = W [e] ; + ASSERT ((k == EMPTY) == (Nv [e] == 0)) ; + if (k != EMPTY) + { + ASSERT (k >= 0 && k < n) ; + Head [k] = e ; + } + } + + /* construct output inverse permutation in Next, + * and permutation in Last */ + nel = 0 ; + for (k = 0 ; k < n ; k++) + { + e = Head [k] ; + if (e == EMPTY) break ; + ASSERT (e >= 0 && e < n && Nv [e] > 0) ; + Next [e] = nel ; + nel += Nv [e] ; + } + ASSERT (nel == n - ndense) ; + + /* order non-principal variables (dense, & those merged into supervar's) */ + for (i = 0 ; i < n ; i++) + { + if (Nv [i] == 0) + { + e = Pe [i] ; + ASSERT (e >= EMPTY && e < n) ; + if (e != EMPTY) + { + /* This is an unordered variable that was merged + * into element e via supernode detection or mass + * elimination of i when e became the pivot element. + * Place i in order just before e. */ + ASSERT (Next [i] == EMPTY && Nv [e] > 0) ; + Next [i] = Next [e] ; + Next [e]++ ; + } + else + { + /* This is a dense unordered variable, with no parent. + * Place it last in the output order. */ + Next [i] = nel++ ; + } + } + } + ASSERT (nel == n) ; + + AMD_DEBUG2 (("\n\nPerm:\n")) ; + for (i = 0 ; i < n ; i++) + { + k = Next [i] ; + ASSERT (k >= 0 && k < n) ; + Last [k] = i ; + AMD_DEBUG2 ((" perm ["ID"] = "ID"\n", k, i)) ; + } +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_aat.c b/OpenDSSC/klusolve/AMD/Source/amd_aat.c new file mode 100644 index 0000000..4f02b75 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_aat.c @@ -0,0 +1,185 @@ +/* ========================================================================= */ +/* === AMD_aat ============================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* AMD_aat: compute the symmetry of the pattern of A, and count the number of + * nonzeros each column of A+A' (excluding the diagonal). Assumes the input + * matrix has no errors, with sorted columns and no duplicates + * (AMD_valid (n, n, Ap, Ai) must be AMD_OK, but this condition is not + * checked). + */ + +#include "amd_internal.h" + +GLOBAL size_t AMD_aat /* returns nz in A+A' */ +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Len [ ], /* Len [j]: length of column j of A+A', excl diagonal*/ + Int Tp [ ], /* workspace of size n */ + double Info [ ] +) +{ + Int p1, p2, p, i, j, pj, pj2, k, nzdiag, nzboth, nz ; + double sym ; + size_t nzaat ; + +#ifndef NDEBUG + AMD_debug_init ("AMD AAT") ; + for (k = 0 ; k < n ; k++) Tp [k] = EMPTY ; + ASSERT (AMD_valid (n, n, Ap, Ai) == AMD_OK) ; +#endif + + if (Info != (double *) NULL) + { + /* clear the Info array, if it exists */ + for (i = 0 ; i < AMD_INFO ; i++) + { + Info [i] = EMPTY ; + } + Info [AMD_STATUS] = AMD_OK ; + } + + for (k = 0 ; k < n ; k++) + { + Len [k] = 0 ; + } + + nzdiag = 0 ; + nzboth = 0 ; + nz = Ap [n] ; + + for (k = 0 ; k < n ; k++) + { + p1 = Ap [k] ; + p2 = Ap [k+1] ; + AMD_DEBUG2 (("\nAAT Column: "ID" p1: "ID" p2: "ID"\n", k, p1, p2)) ; + + /* construct A+A' */ + for (p = p1 ; p < p2 ; ) + { + /* scan the upper triangular part of A */ + j = Ai [p] ; + if (j < k) + { + /* entry A (j,k) is in the strictly upper triangular part, + * add both A (j,k) and A (k,j) to the matrix A+A' */ + Len [j]++ ; + Len [k]++ ; + AMD_DEBUG3 ((" upper ("ID","ID") ("ID","ID")\n", j,k, k,j)); + p++ ; + } + else if (j == k) + { + /* skip the diagonal */ + p++ ; + nzdiag++ ; + break ; + } + else /* j > k */ + { + /* first entry below the diagonal */ + break ; + } + /* scan lower triangular part of A, in column j until reaching + * row k. Start where last scan left off. */ + ASSERT (Tp [j] != EMPTY) ; + ASSERT (Ap [j] <= Tp [j] && Tp [j] <= Ap [j+1]) ; + pj2 = Ap [j+1] ; + for (pj = Tp [j] ; pj < pj2 ; ) + { + i = Ai [pj] ; + if (i < k) + { + /* A (i,j) is only in the lower part, not in upper. + * add both A (i,j) and A (j,i) to the matrix A+A' */ + Len [i]++ ; + Len [j]++ ; + AMD_DEBUG3 ((" lower ("ID","ID") ("ID","ID")\n", + i,j, j,i)) ; + pj++ ; + } + else if (i == k) + { + /* entry A (k,j) in lower part and A (j,k) in upper */ + pj++ ; + nzboth++ ; + break ; + } + else /* i > k */ + { + /* consider this entry later, when k advances to i */ + break ; + } + } + Tp [j] = pj ; + } + /* Tp [k] points to the entry just below the diagonal in column k */ + Tp [k] = p ; + } + + /* clean up, for remaining mismatched entries */ + for (j = 0 ; j < n ; j++) + { + for (pj = Tp [j] ; pj < Ap [j+1] ; pj++) + { + i = Ai [pj] ; + /* A (i,j) is only in the lower part, not in upper. + * add both A (i,j) and A (j,i) to the matrix A+A' */ + Len [i]++ ; + Len [j]++ ; + AMD_DEBUG3 ((" lower cleanup ("ID","ID") ("ID","ID")\n", + i,j, j,i)) ; + } + } + + /* --------------------------------------------------------------------- */ + /* compute the symmetry of the nonzero pattern of A */ + /* --------------------------------------------------------------------- */ + + /* Given a matrix A, the symmetry of A is: + * B = tril (spones (A), -1) + triu (spones (A), 1) ; + * sym = nnz (B & B') / nnz (B) ; + * or 1 if nnz (B) is zero. + */ + + if (nz == nzdiag) + { + sym = 1 ; + } + else + { + sym = (2 * (double) nzboth) / ((double) (nz - nzdiag)) ; + } + + nzaat = 0 ; + for (k = 0 ; k < n ; k++) + { + nzaat += Len [k] ; + } + + AMD_DEBUG1 (("AMD nz in A+A', excluding diagonal (nzaat) = %g\n", + (double) nzaat)) ; + AMD_DEBUG1 ((" nzboth: "ID" nz: "ID" nzdiag: "ID" symmetry: %g\n", + nzboth, nz, nzdiag, sym)) ; + + if (Info != (double *) NULL) + { + Info [AMD_STATUS] = AMD_OK ; + Info [AMD_N] = n ; + Info [AMD_NZ] = nz ; + Info [AMD_SYMMETRY] = sym ; /* symmetry of pattern of A */ + Info [AMD_NZDIAG] = nzdiag ; /* nonzeros on diagonal of A */ + Info [AMD_NZ_A_PLUS_AT] = nzaat ; /* nonzeros in A+A' */ + } + + return (nzaat) ; +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_control.c b/OpenDSSC/klusolve/AMD/Source/amd_control.c new file mode 100644 index 0000000..c2aec9f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_control.c @@ -0,0 +1,64 @@ +/* ========================================================================= */ +/* === AMD_control ========================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Prints the control parameters for AMD. See amd.h + * for details. If the Control array is not present, the defaults are + * printed instead. + */ + +#include "amd_internal.h" + +GLOBAL void AMD_control +( + double Control [ ] +) +{ + double alpha ; + Int aggressive ; + + if (Control != (double *) NULL) + { + alpha = Control [AMD_DENSE] ; + aggressive = Control [AMD_AGGRESSIVE] != 0 ; + } + else + { + alpha = AMD_DEFAULT_DENSE ; + aggressive = AMD_DEFAULT_AGGRESSIVE ; + } + + PRINTF (("\nAMD version %d.%d.%d, %s: approximate minimum degree ordering\n" + " dense row parameter: %g\n", AMD_MAIN_VERSION, AMD_SUB_VERSION, + AMD_SUBSUB_VERSION, AMD_DATE, alpha)) ; + + if (alpha < 0) + { + PRINTF ((" no rows treated as dense\n")) ; + } + else + { + PRINTF (( + " (rows with more than max (%g * sqrt (n), 16) entries are\n" + " considered \"dense\", and placed last in output permutation)\n", + alpha)) ; + } + + if (aggressive) + { + PRINTF ((" aggressive absorption: yes\n")) ; + } + else + { + PRINTF ((" aggressive absorption: no\n")) ; + } + + PRINTF ((" size of AMD integer: %d\n\n", sizeof (Int))) ; +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_defaults.c b/OpenDSSC/klusolve/AMD/Source/amd_defaults.c new file mode 100644 index 0000000..ffe3f4b --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_defaults.c @@ -0,0 +1,38 @@ +/* ========================================================================= */ +/* === AMD_defaults ======================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Sets default control parameters for AMD. See amd.h + * for details. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD defaults ======================================================== */ +/* ========================================================================= */ + +GLOBAL void AMD_defaults +( + double Control [ ] +) +{ + Int i ; + + if (Control != (double *) NULL) + { + for (i = 0 ; i < AMD_CONTROL ; i++) + { + Control [i] = 0 ; + } + Control [AMD_DENSE] = AMD_DEFAULT_DENSE ; + Control [AMD_AGGRESSIVE] = AMD_DEFAULT_AGGRESSIVE ; + } +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_dump.c b/OpenDSSC/klusolve/AMD/Source/amd_dump.c new file mode 100644 index 0000000..89d67b8 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_dump.c @@ -0,0 +1,180 @@ +/* ========================================================================= */ +/* === AMD_dump ============================================================ */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Debugging routines for AMD. Not used if NDEBUG is not defined at compile- + * time (the default). See comments in amd_internal.h on how to enable + * debugging. Not user-callable. + */ + +#include "amd_internal.h" + +#ifndef NDEBUG + +/* This global variable is present only when debugging */ +GLOBAL Int AMD_debug = -999 ; /* default is no debug printing */ + +/* ========================================================================= */ +/* === AMD_debug_init ====================================================== */ +/* ========================================================================= */ + +/* Sets the debug print level, by reading the file debug.amd (if it exists) */ + +GLOBAL void AMD_debug_init ( char *s ) +{ + FILE *f ; + f = fopen ("debug.amd", "r") ; + if (f == (FILE *) NULL) + { + AMD_debug = -999 ; + } + else + { + fscanf (f, ID, &AMD_debug) ; + fclose (f) ; + } + if (AMD_debug >= 0) + { + printf ("%s: AMD_debug_init, D= "ID"\n", s, AMD_debug) ; + } +} + +/* ========================================================================= */ +/* === AMD_dump ============================================================ */ +/* ========================================================================= */ + +/* Dump AMD's data structure, except for the hash buckets. This routine + * cannot be called when the hash buckets are non-empty. + */ + +GLOBAL void AMD_dump ( + Int n, /* A is n-by-n */ + Int Pe [ ], /* pe [0..n-1]: index in iw of start of row i */ + Int Iw [ ], /* workspace of size iwlen, iwlen [0..pfree-1] + * holds the matrix on input */ + Int Len [ ], /* len [0..n-1]: length for row i */ + Int iwlen, /* length of iw */ + Int pfree, /* iw [pfree ... iwlen-1] is empty on input */ + Int Nv [ ], /* nv [0..n-1] */ + Int Next [ ], /* next [0..n-1] */ + Int Last [ ], /* last [0..n-1] */ + Int Head [ ], /* head [0..n-1] */ + Int Elen [ ], /* size n */ + Int Degree [ ], /* size n */ + Int W [ ], /* size n */ + Int nel +) +{ + Int i, pe, elen, nv, len, e, p, k, j, deg, w, cnt, ilast ; + + if (AMD_debug < 0) return ; + ASSERT (pfree <= iwlen) ; + AMD_DEBUG3 (("\nAMD dump, pfree: "ID"\n", pfree)) ; + for (i = 0 ; i < n ; i++) + { + pe = Pe [i] ; + elen = Elen [i] ; + nv = Nv [i] ; + len = Len [i] ; + w = W [i] ; + + if (elen >= EMPTY) + { + if (nv == 0) + { + AMD_DEBUG3 (("\nI "ID": nonprincipal: ", i)) ; + ASSERT (elen == EMPTY) ; + if (pe == EMPTY) + { + AMD_DEBUG3 ((" dense node\n")) ; + ASSERT (w == 1) ; + } + else + { + ASSERT (pe < EMPTY) ; + AMD_DEBUG3 ((" i "ID" -> parent "ID"\n", i, FLIP (Pe[i]))); + } + } + else + { + AMD_DEBUG3 (("\nI "ID": active principal supervariable:\n",i)); + AMD_DEBUG3 ((" nv(i): "ID" Flag: %d\n", nv, (nv < 0))) ; + ASSERT (elen >= 0) ; + ASSERT (nv > 0 && pe >= 0) ; + p = pe ; + AMD_DEBUG3 ((" e/s: ")) ; + if (elen == 0) AMD_DEBUG3 ((" : ")) ; + ASSERT (pe + len <= pfree) ; + for (k = 0 ; k < len ; k++) + { + j = Iw [p] ; + AMD_DEBUG3 ((" "ID"", j)) ; + ASSERT (j >= 0 && j < n) ; + if (k == elen-1) AMD_DEBUG3 ((" : ")) ; + p++ ; + } + AMD_DEBUG3 (("\n")) ; + } + } + else + { + e = i ; + if (w == 0) + { + AMD_DEBUG3 (("\nE "ID": absorbed element: w "ID"\n", e, w)) ; + ASSERT (nv > 0 && pe < 0) ; + AMD_DEBUG3 ((" e "ID" -> parent "ID"\n", e, FLIP (Pe [e]))) ; + } + else + { + AMD_DEBUG3 (("\nE "ID": unabsorbed element: w "ID"\n", e, w)) ; + ASSERT (nv > 0 && pe >= 0) ; + p = pe ; + AMD_DEBUG3 ((" : ")) ; + ASSERT (pe + len <= pfree) ; + for (k = 0 ; k < len ; k++) + { + j = Iw [p] ; + AMD_DEBUG3 ((" "ID"", j)) ; + ASSERT (j >= 0 && j < n) ; + p++ ; + } + AMD_DEBUG3 (("\n")) ; + } + } + } + + /* this routine cannot be called when the hash buckets are non-empty */ + AMD_DEBUG3 (("\nDegree lists:\n")) ; + if (nel >= 0) + { + cnt = 0 ; + for (deg = 0 ; deg < n ; deg++) + { + if (Head [deg] == EMPTY) continue ; + ilast = EMPTY ; + AMD_DEBUG3 ((ID": \n", deg)) ; + for (i = Head [deg] ; i != EMPTY ; i = Next [i]) + { + AMD_DEBUG3 ((" "ID" : next "ID" last "ID" deg "ID"\n", + i, Next [i], Last [i], Degree [i])) ; + ASSERT (i >= 0 && i < n && ilast == Last [i] && + deg == Degree [i]) ; + cnt += Nv [i] ; + ilast = i ; + } + AMD_DEBUG3 (("\n")) ; + } + ASSERT (cnt == n - nel) ; + } + +} + +#endif diff --git a/OpenDSSC/klusolve/AMD/Source/amd_global.c b/OpenDSSC/klusolve/AMD/Source/amd_global.c new file mode 100644 index 0000000..93f2b45 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_global.c @@ -0,0 +1,84 @@ +/* ========================================================================= */ +/* === amd_global ========================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +#include + +#ifdef MATLAB_MEX_FILE +#include "mex.h" +#include "matrix.h" +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* ========================================================================= */ +/* === Default AMD memory manager ========================================== */ +/* ========================================================================= */ + +/* The user can redefine these global pointers at run-time to change the memory + * manager used by AMD. AMD only uses malloc and free; realloc and calloc are + * include for completeness, in case another package wants to use the same + * memory manager as AMD. + * + * If compiling as a MATLAB mexFunction, the default memory manager is mxMalloc. + * You can also compile AMD as a standard ANSI-C library and link a mexFunction + * against it, and then redefine these pointers at run-time, in your + * mexFunction. + * + * If -DNMALLOC is defined at compile-time, no memory manager is specified at + * compile-time. You must then define these functions at run-time, before + * calling AMD, for AMD to work properly. + */ + +#ifndef NMALLOC +#ifdef MATLAB_MEX_FILE +/* MATLAB mexFunction: */ +void *(*amd_malloc) (size_t) = mxMalloc ; +void (*amd_free) (void *) = mxFree ; +void *(*amd_realloc) (void *, size_t) = mxRealloc ; +void *(*amd_calloc) (size_t, size_t) = mxCalloc ; +#else +/* standard ANSI-C: */ +void *(*amd_malloc) (size_t) = malloc ; +void (*amd_free) (void *) = free ; +void *(*amd_realloc) (void *, size_t) = realloc ; +void *(*amd_calloc) (size_t, size_t) = calloc ; +#endif +#else +/* no memory manager defined at compile-time; you MUST define one at run-time */ +void *(*amd_malloc) (size_t) = NULL ; +void (*amd_free) (void *) = NULL ; +void *(*amd_realloc) (void *, size_t) = NULL ; +void *(*amd_calloc) (size_t, size_t) = NULL ; +#endif + +/* ========================================================================= */ +/* === Default AMD printf routine ========================================== */ +/* ========================================================================= */ + +/* The user can redefine this global pointer at run-time to change the printf + * routine used by AMD. If NULL, no printing occurs. + * + * If -DNPRINT is defined at compile-time, stdio.h is not included. Printing + * can then be enabled at run-time by setting amd_printf to a non-NULL function. + */ + +#ifndef NPRINT +#ifdef MATLAB_MEX_FILE +int (*amd_printf) (const char *, ...) = mexPrintf ; +#else +#include +int (*amd_printf) (const char *, ...) = printf ; +#endif +#else +int (*amd_printf) (const char *, ...) = NULL ; +#endif diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_1.c b/OpenDSSC/klusolve/AMD/Source/amd_i_1.c new file mode 100644 index 0000000..70d2d17 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_1.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_1.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_2.c b/OpenDSSC/klusolve/AMD/Source/amd_i_2.c new file mode 100644 index 0000000..f9f1edf --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_2.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_2.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_aat.c b/OpenDSSC/klusolve/AMD/Source/amd_i_aat.c new file mode 100644 index 0000000..f90f001 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_aat.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_aat.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_control.c b/OpenDSSC/klusolve/AMD/Source/amd_i_control.c new file mode 100644 index 0000000..17327ea --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_control.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_control.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_defaults.c b/OpenDSSC/klusolve/AMD/Source/amd_i_defaults.c new file mode 100644 index 0000000..2e2ffd1 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_defaults.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_defaults.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_dump.c b/OpenDSSC/klusolve/AMD/Source/amd_i_dump.c new file mode 100644 index 0000000..211cb0e --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_dump.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_dump.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_info.c b/OpenDSSC/klusolve/AMD/Source/amd_i_info.c new file mode 100644 index 0000000..7792d2c --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_info.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_info.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_order.c b/OpenDSSC/klusolve/AMD/Source/amd_i_order.c new file mode 100644 index 0000000..d4371d5 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_order.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_order.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_post_tree.c b/OpenDSSC/klusolve/AMD/Source/amd_i_post_tree.c new file mode 100644 index 0000000..1ba0a80 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_post_tree.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_post_tree.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_postorder.c b/OpenDSSC/klusolve/AMD/Source/amd_i_postorder.c new file mode 100644 index 0000000..3c2c64b --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_postorder.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_postorder.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_preprocess.c b/OpenDSSC/klusolve/AMD/Source/amd_i_preprocess.c new file mode 100644 index 0000000..130bb6f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_preprocess.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_preprocess.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_i_valid.c b/OpenDSSC/klusolve/AMD/Source/amd_i_valid.c new file mode 100644 index 0000000..3f86d0f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_i_valid.c @@ -0,0 +1,2 @@ +#define DINT 1 +#include "amd_valid.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_info.c b/OpenDSSC/klusolve/AMD/Source/amd_info.c new file mode 100644 index 0000000..0a842ad --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_info.c @@ -0,0 +1,120 @@ +/* ========================================================================= */ +/* === AMD_info ============================================================ */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable. Prints the output statistics for AMD. See amd.h + * for details. If the Info array is not present, nothing is printed. + */ + +#include "amd_internal.h" + +#define PRI(format,x) { if (x >= 0) { PRINTF ((format, x)) ; }} + +GLOBAL void AMD_info +( + double Info [ ] +) +{ + double n, ndiv, nmultsubs_ldl, nmultsubs_lu, lnz, lnzd ; + + PRINTF (("\nAMD version %d.%d.%d, %s, results:\n", + AMD_MAIN_VERSION, AMD_SUB_VERSION, AMD_SUBSUB_VERSION, AMD_DATE)) ; + + if (!Info) + { + return ; + } + + n = Info [AMD_N] ; + ndiv = Info [AMD_NDIV] ; + nmultsubs_ldl = Info [AMD_NMULTSUBS_LDL] ; + nmultsubs_lu = Info [AMD_NMULTSUBS_LU] ; + lnz = Info [AMD_LNZ] ; + lnzd = (n >= 0 && lnz >= 0) ? (n + lnz) : (-1) ; + + /* AMD return status */ + PRINTF ((" status: ")) ; + if (Info [AMD_STATUS] == AMD_OK) + { + PRINTF (("OK\n")) ; + } + else if (Info [AMD_STATUS] == AMD_OUT_OF_MEMORY) + { + PRINTF (("out of memory\n")) ; + } + else if (Info [AMD_STATUS] == AMD_INVALID) + { + PRINTF (("invalid matrix\n")) ; + } + else if (Info [AMD_STATUS] == AMD_OK_BUT_JUMBLED) + { + PRINTF (("OK, but jumbled\n")) ; + } + else + { + PRINTF (("unknown\n")) ; + } + + /* statistics about the input matrix */ + PRI (" n, dimension of A: %.20g\n", n); + PRI (" nz, number of nonzeros in A: %.20g\n", + Info [AMD_NZ]) ; + PRI (" symmetry of A: %.4f\n", + Info [AMD_SYMMETRY]) ; + PRI (" number of nonzeros on diagonal: %.20g\n", + Info [AMD_NZDIAG]) ; + PRI (" nonzeros in pattern of A+A' (excl. diagonal): %.20g\n", + Info [AMD_NZ_A_PLUS_AT]) ; + PRI (" # dense rows/columns of A+A': %.20g\n", + Info [AMD_NDENSE]) ; + + /* statistics about AMD's behavior */ + PRI (" memory used, in bytes: %.20g\n", + Info [AMD_MEMORY]) ; + PRI (" # of memory compactions: %.20g\n", + Info [AMD_NCMPA]) ; + + /* statistics about the ordering quality */ + PRINTF (("\n" + " The following approximate statistics are for a subsequent\n" + " factorization of A(P,P) + A(P,P)'. They are slight upper\n" + " bounds if there are no dense rows/columns in A+A', and become\n" + " looser if dense rows/columns exist.\n\n")) ; + + PRI (" nonzeros in L (excluding diagonal): %.20g\n", + lnz) ; + PRI (" nonzeros in L (including diagonal): %.20g\n", + lnzd) ; + PRI (" # divide operations for LDL' or LU: %.20g\n", + ndiv) ; + PRI (" # multiply-subtract operations for LDL': %.20g\n", + nmultsubs_ldl) ; + PRI (" # multiply-subtract operations for LU: %.20g\n", + nmultsubs_lu) ; + PRI (" max nz. in any column of L (incl. diagonal): %.20g\n", + Info [AMD_DMAX]) ; + + /* total flop counts for various factorizations */ + + if (n >= 0 && ndiv >= 0 && nmultsubs_ldl >= 0 && nmultsubs_lu >= 0) + { + PRINTF (("\n" + " chol flop count for real A, sqrt counted as 1 flop: %.20g\n" + " LDL' flop count for real A: %.20g\n" + " LDL' flop count for complex A: %.20g\n" + " LU flop count for real A (with no pivoting): %.20g\n" + " LU flop count for complex A (with no pivoting): %.20g\n\n", + n + ndiv + 2*nmultsubs_ldl, + ndiv + 2*nmultsubs_ldl, + 9*ndiv + 8*nmultsubs_ldl, + ndiv + 2*nmultsubs_lu, + 9*ndiv + 8*nmultsubs_lu)) ; + } +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_1.c b/OpenDSSC/klusolve/AMD/Source/amd_l_1.c new file mode 100644 index 0000000..454814d --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_1.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_1.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_2.c b/OpenDSSC/klusolve/AMD/Source/amd_l_2.c new file mode 100644 index 0000000..f81b368 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_2.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_2.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_aat.c b/OpenDSSC/klusolve/AMD/Source/amd_l_aat.c new file mode 100644 index 0000000..9b99d1f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_aat.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_aat.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_control.c b/OpenDSSC/klusolve/AMD/Source/amd_l_control.c new file mode 100644 index 0000000..4f82302 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_control.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_control.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_defaults.c b/OpenDSSC/klusolve/AMD/Source/amd_l_defaults.c new file mode 100644 index 0000000..67b0033 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_defaults.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_defaults.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_dump.c b/OpenDSSC/klusolve/AMD/Source/amd_l_dump.c new file mode 100644 index 0000000..acd6cf5 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_dump.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_dump.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_info.c b/OpenDSSC/klusolve/AMD/Source/amd_l_info.c new file mode 100644 index 0000000..e840eba --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_info.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_info.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_order.c b/OpenDSSC/klusolve/AMD/Source/amd_l_order.c new file mode 100644 index 0000000..2b89a4a --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_order.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_order.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_post_tree.c b/OpenDSSC/klusolve/AMD/Source/amd_l_post_tree.c new file mode 100644 index 0000000..4073b30 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_post_tree.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_post_tree.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_postorder.c b/OpenDSSC/klusolve/AMD/Source/amd_l_postorder.c new file mode 100644 index 0000000..46dec50 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_postorder.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_postorder.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_preprocess.c b/OpenDSSC/klusolve/AMD/Source/amd_l_preprocess.c new file mode 100644 index 0000000..1615cd6 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_preprocess.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_preprocess.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_l_valid.c b/OpenDSSC/klusolve/AMD/Source/amd_l_valid.c new file mode 100644 index 0000000..05bd63a --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_l_valid.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "amd_valid.c" diff --git a/OpenDSSC/klusolve/AMD/Source/amd_order.c b/OpenDSSC/klusolve/AMD/Source/amd_order.c new file mode 100644 index 0000000..d3f6853 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_order.c @@ -0,0 +1,200 @@ +/* ========================================================================= */ +/* === AMD_order =========================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* User-callable AMD minimum degree ordering routine. See amd.h for + * documentation. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD_order =========================================================== */ +/* ========================================================================= */ + +GLOBAL Int AMD_order +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int P [ ], + double Control [ ], + double Info [ ] +) +{ + Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ; + size_t nzaat, slen ; + double mem = 0 ; + +#ifndef NDEBUG + AMD_debug_init ("amd") ; +#endif + + /* clear the Info array, if it exists */ + info = Info != (double *) NULL ; + if (info) + { + for (i = 0 ; i < AMD_INFO ; i++) + { + Info [i] = EMPTY ; + } + Info [AMD_N] = n ; + Info [AMD_STATUS] = AMD_OK ; + } + + /* make sure inputs exist and n is >= 0 */ + if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; /* arguments are invalid */ + } + + if (n == 0) + { + return (AMD_OK) ; /* n is 0 so there's nothing to do */ + } + + nz = Ap [n] ; + if (info) + { + Info [AMD_NZ] = nz ; + } + if (nz < 0) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; + } + + /* check if n or nz will cause size_t overflow */ + if (((size_t) n) >= SIZE_T_MAX / sizeof (Int) + || ((size_t) nz) >= SIZE_T_MAX / sizeof (Int)) + { + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; /* problem too large */ + } + + /* check the input matrix: AMD_OK, AMD_INVALID, or AMD_OK_BUT_JUMBLED */ + status = AMD_valid (n, n, Ap, Ai) ; + + if (status == AMD_INVALID) + { + if (info) Info [AMD_STATUS] = AMD_INVALID ; + return (AMD_INVALID) ; /* matrix is invalid */ + } + + /* allocate two size-n integer workspaces */ + Len = amd_malloc (n * sizeof (Int)) ; + Pinv = amd_malloc (n * sizeof (Int)) ; + mem += n ; + mem += n ; + if (!Len || !Pinv) + { + /* :: out of memory :: */ + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + + if (status == AMD_OK_BUT_JUMBLED) + { + /* sort the input matrix and remove duplicate entries */ + AMD_DEBUG1 (("Matrix is jumbled\n")) ; + Rp = amd_malloc ((n+1) * sizeof (Int)) ; + Ri = amd_malloc (MAX (nz,1) * sizeof (Int)) ; + mem += (n+1) ; + mem += MAX (nz,1) ; + if (!Rp || !Ri) + { + /* :: out of memory :: */ + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + /* use Len and Pinv as workspace to create R = A' */ + AMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ; + Cp = Rp ; + Ci = Ri ; + } + else + { + /* order the input matrix as-is. No need to compute R = A' first */ + Rp = NULL ; + Ri = NULL ; + Cp = (Int *) Ap ; + Ci = (Int *) Ai ; + } + + /* --------------------------------------------------------------------- */ + /* determine the symmetry and count off-diagonal nonzeros in A+A' */ + /* --------------------------------------------------------------------- */ + + nzaat = AMD_aat (n, Cp, Ci, Len, P, Info) ; + AMD_DEBUG1 (("nzaat: %g\n", (double) nzaat)) ; + ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ; + + /* --------------------------------------------------------------------- */ + /* allocate workspace for matrix, elbow room, and 6 size-n vectors */ + /* --------------------------------------------------------------------- */ + + S = NULL ; + slen = nzaat ; /* space for matrix */ + ok = ((slen + nzaat/5) >= slen) ; /* check for size_t overflow */ + slen += nzaat/5 ; /* add elbow room */ + for (i = 0 ; ok && i < 7 ; i++) + { + ok = ((slen + n) > slen) ; /* check for size_t overflow */ + slen += n ; /* size-n elbow room, 6 size-n work */ + } + mem += slen ; + ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */ + ok = ok && (slen < Int_MAX) ; /* S[i] for Int i must be OK */ + if (ok) + { + S = amd_malloc (slen * sizeof (Int)) ; + } + AMD_DEBUG1 (("slen %g\n", (double) slen)) ; + if (!S) + { + /* :: out of memory :: (or problem too large) */ + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ; + return (AMD_OUT_OF_MEMORY) ; + } + if (info) + { + /* memory usage, in bytes. */ + Info [AMD_MEMORY] = mem * sizeof (Int) ; + } + + /* --------------------------------------------------------------------- */ + /* order the matrix */ + /* --------------------------------------------------------------------- */ + + AMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info) ; + + /* --------------------------------------------------------------------- */ + /* free the workspace */ + /* --------------------------------------------------------------------- */ + + amd_free (Rp) ; + amd_free (Ri) ; + amd_free (Len) ; + amd_free (Pinv) ; + amd_free (S) ; + if (info) Info [AMD_STATUS] = status ; + return (status) ; /* successful ordering */ +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_post_tree.c b/OpenDSSC/klusolve/AMD/Source/amd_post_tree.c new file mode 100644 index 0000000..b4e063d --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_post_tree.c @@ -0,0 +1,121 @@ +/* ========================================================================= */ +/* === AMD_post_tree ======================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Post-ordering of a supernodal elimination tree. */ + +#include "amd_internal.h" + +GLOBAL Int AMD_post_tree +( + Int root, /* root of the tree */ + Int k, /* start numbering at k */ + Int Child [ ], /* input argument of size nn, undefined on + * output. Child [i] is the head of a link + * list of all nodes that are children of node + * i in the tree. */ + const Int Sibling [ ], /* input argument of size nn, not modified. + * If f is a node in the link list of the + * children of node i, then Sibling [f] is the + * next child of node i. + */ + Int Order [ ], /* output order, of size nn. Order [i] = k + * if node i is the kth node of the reordered + * tree. */ + Int Stack [ ] /* workspace of size nn */ +#ifndef NDEBUG + , Int nn /* nodes are in the range 0..nn-1. */ +#endif +) +{ + Int f, head, h, i ; + +#if 0 + /* --------------------------------------------------------------------- */ + /* recursive version (Stack [ ] is not used): */ + /* --------------------------------------------------------------------- */ + + /* this is simple, but can caouse stack overflow if nn is large */ + i = root ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ; + } + Order [i] = k++ ; + return (k) ; +#endif + + /* --------------------------------------------------------------------- */ + /* non-recursive version, using an explicit stack */ + /* --------------------------------------------------------------------- */ + + /* push root on the stack */ + head = 0 ; + Stack [0] = root ; + + while (head >= 0) + { + /* get head of stack */ + ASSERT (head < nn) ; + i = Stack [head] ; + AMD_DEBUG1 (("head of stack "ID" \n", i)) ; + ASSERT (i >= 0 && i < nn) ; + + if (Child [i] != EMPTY) + { + /* the children of i are not yet ordered */ + /* push each child onto the stack in reverse order */ + /* so that small ones at the head of the list get popped first */ + /* and the biggest one at the end of the list gets popped last */ + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + head++ ; + ASSERT (head < nn) ; + ASSERT (f >= 0 && f < nn) ; + } + h = head ; + ASSERT (head < nn) ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (h > 0) ; + Stack [h--] = f ; + AMD_DEBUG1 (("push "ID" on stack\n", f)) ; + ASSERT (f >= 0 && f < nn) ; + } + ASSERT (Stack [h] == i) ; + + /* delete child list so that i gets ordered next time we see it */ + Child [i] = EMPTY ; + } + else + { + /* the children of i (if there were any) are already ordered */ + /* remove i from the stack and order it. Front i is kth front */ + head-- ; + AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ; + Order [i] = k++ ; + ASSERT (k <= nn) ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("\nStack:")) ; + for (h = head ; h >= 0 ; h--) + { + Int j = Stack [h] ; + AMD_DEBUG1 ((" "ID, j)) ; + ASSERT (j >= 0 && j < nn) ; + } + AMD_DEBUG1 (("\n\n")) ; + ASSERT (head < nn) ; +#endif + + } + return (k) ; +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_postorder.c b/OpenDSSC/klusolve/AMD/Source/amd_postorder.c new file mode 100644 index 0000000..4adcea3 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_postorder.c @@ -0,0 +1,207 @@ +/* ========================================================================= */ +/* === AMD_postorder ======================================================= */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Perform a postordering (via depth-first search) of an assembly tree. */ + +#include "amd_internal.h" + +GLOBAL void AMD_postorder +( + /* inputs, not modified on output: */ + Int nn, /* nodes are in the range 0..nn-1 */ + Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */ + Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j, + * or zero if j is not a node. */ + Int Fsize [ ], /* Fsize [j]: size of node j */ + + /* output, not defined on input: */ + Int Order [ ], /* output post-order */ + + /* workspaces of size nn: */ + Int Child [ ], + Int Sibling [ ], + Int Stack [ ] +) +{ + Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ; + + for (j = 0 ; j < nn ; j++) + { + Child [j] = EMPTY ; + Sibling [j] = EMPTY ; + } + + /* --------------------------------------------------------------------- */ + /* place the children in link lists - bigger elements tend to be last */ + /* --------------------------------------------------------------------- */ + + for (j = nn-1 ; j >= 0 ; j--) + { + if (Nv [j] > 0) + { + /* this is an element */ + parent = Parent [j] ; + if (parent != EMPTY) + { + /* place the element in link list of the children its parent */ + /* bigger elements will tend to be at the end of the list */ + Sibling [j] = Child [parent] ; + Child [parent] = j ; + } + } + } + +#ifndef NDEBUG + { + Int nels, ff, nchild ; + AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n")); + nels = 0 ; + for (j = 0 ; j < nn ; j++) + { + if (Nv [j] > 0) + { + AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID + " parent "ID" maxfr "ID"\n", j, nels, + Nv [j], Fsize [j], Parent [j], Fsize [j])) ; + /* this is an element */ + /* dump the link list of children */ + nchild = 0 ; + AMD_DEBUG1 ((" Children: ")) ; + for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff]) + { + AMD_DEBUG1 ((ID" ", ff)) ; + ASSERT (Parent [ff] == j) ; + nchild++ ; + ASSERT (nchild < nn) ; + } + AMD_DEBUG1 (("\n")) ; + parent = Parent [j] ; + if (parent != EMPTY) + { + ASSERT (Nv [parent] > 0) ; + } + nels++ ; + } + } + } + AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n" + "the biggest child last in each list:\n")) ; +#endif + + /* --------------------------------------------------------------------- */ + /* place the largest child last in the list of children for each node */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < nn ; i++) + { + if (Nv [i] > 0 && Child [i] != EMPTY) + { + +#ifndef NDEBUG + Int nchild ; + AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ; + nchild = 0 ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ; + nchild++ ; + ASSERT (nchild <= nn) ; + } +#endif + + /* find the biggest element in the child list */ + fprev = EMPTY ; + maxfrsize = EMPTY ; + bigfprev = EMPTY ; + bigf = EMPTY ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + frsize = Fsize [f] ; + if (frsize >= maxfrsize) + { + /* this is the biggest seen so far */ + maxfrsize = frsize ; + bigfprev = fprev ; + bigf = f ; + } + fprev = f ; + } + ASSERT (bigf != EMPTY) ; + + fnext = Sibling [bigf] ; + + AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID + " fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ; + + if (fnext != EMPTY) + { + /* if fnext is EMPTY then bigf is already at the end of list */ + + if (bigfprev == EMPTY) + { + /* delete bigf from the element of the list */ + Child [i] = fnext ; + } + else + { + /* delete bigf from the middle of the list */ + Sibling [bigfprev] = fnext ; + } + + /* put bigf at the end of the list */ + Sibling [bigf] = EMPTY ; + ASSERT (Child [i] != EMPTY) ; + ASSERT (fprev != bigf) ; + ASSERT (fprev != EMPTY) ; + Sibling [fprev] = bigf ; + } + +#ifndef NDEBUG + AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ; + for (f = Child [i] ; f != EMPTY ; f = Sibling [f]) + { + ASSERT (f >= 0 && f < nn) ; + AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ; + ASSERT (Nv [f] > 0) ; + nchild-- ; + } + ASSERT (nchild == 0) ; +#endif + + } + } + + /* --------------------------------------------------------------------- */ + /* postorder the assembly tree */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < nn ; i++) + { + Order [i] = EMPTY ; + } + + k = 0 ; + + for (i = 0 ; i < nn ; i++) + { + if (Parent [i] == EMPTY && Nv [i] > 0) + { + AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ; + k = AMD_post_tree (i, k, Child, Sibling, Order, Stack +#ifndef NDEBUG + , nn +#endif + ) ; + } + } +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_preprocess.c b/OpenDSSC/klusolve/AMD/Source/amd_preprocess.c new file mode 100644 index 0000000..86ea07f --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_preprocess.c @@ -0,0 +1,119 @@ +/* ========================================================================= */ +/* === AMD_preprocess ====================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Sorts, removes duplicate entries, and transposes from the nonzero pattern of + * a column-form matrix A, to obtain the matrix R. The input matrix can have + * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be + * AMD_INVALID). + * + * This input condition is NOT checked. This routine is not user-callable. + */ + +#include "amd_internal.h" + +/* ========================================================================= */ +/* === AMD_preprocess ====================================================== */ +/* ========================================================================= */ + +/* AMD_preprocess does not check its input for errors or allocate workspace. + * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold. + */ + +GLOBAL void AMD_preprocess +( + Int n, /* input matrix: A is n-by-n */ + const Int Ap [ ], /* size n+1 */ + const Int Ai [ ], /* size nz = Ap [n] */ + + /* output matrix R: */ + Int Rp [ ], /* size n+1 */ + Int Ri [ ], /* size nz (or less, if duplicates present) */ + + Int W [ ], /* workspace of size n */ + Int Flag [ ] /* workspace of size n */ +) +{ + + /* --------------------------------------------------------------------- */ + /* local variables */ + /* --------------------------------------------------------------------- */ + + Int i, j, p, p2 ; + + ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ; + + /* --------------------------------------------------------------------- */ + /* count the entries in each row of A (excluding duplicates) */ + /* --------------------------------------------------------------------- */ + + for (i = 0 ; i < n ; i++) + { + W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */ + Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */ + } + for (j = 0 ; j < n ; j++) + { + p2 = Ap [j+1] ; + for (p = Ap [j] ; p < p2 ; p++) + { + i = Ai [p] ; + if (Flag [i] != j) + { + /* row index i has not yet appeared in column j */ + W [i]++ ; /* one more entry in row i */ + Flag [i] = j ; /* flag row index i as appearing in col j*/ + } + } + } + + /* --------------------------------------------------------------------- */ + /* compute the row pointers for R */ + /* --------------------------------------------------------------------- */ + + Rp [0] = 0 ; + for (i = 0 ; i < n ; i++) + { + Rp [i+1] = Rp [i] + W [i] ; + } + for (i = 0 ; i < n ; i++) + { + W [i] = Rp [i] ; + Flag [i] = EMPTY ; + } + + /* --------------------------------------------------------------------- */ + /* construct the row form matrix R */ + /* --------------------------------------------------------------------- */ + + /* R = row form of pattern of A */ + for (j = 0 ; j < n ; j++) + { + p2 = Ap [j+1] ; + for (p = Ap [j] ; p < p2 ; p++) + { + i = Ai [p] ; + if (Flag [i] != j) + { + /* row index i has not yet appeared in column j */ + Ri [W [i]++] = j ; /* put col j in row i */ + Flag [i] = j ; /* flag row index i as appearing in col j*/ + } + } + } + +#ifndef NDEBUG + ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ; + for (j = 0 ; j < n ; j++) + { + ASSERT (W [j] == Rp [j+1]) ; + } +#endif +} diff --git a/OpenDSSC/klusolve/AMD/Source/amd_valid.c b/OpenDSSC/klusolve/AMD/Source/amd_valid.c new file mode 100644 index 0000000..4d05925 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amd_valid.c @@ -0,0 +1,93 @@ +/* ========================================================================= */ +/* === AMD_valid =========================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: davis at cise.ufl.edu CISE Department, Univ. of Florida. */ +/* web: http://www.cise.ufl.edu/research/sparse/amd */ +/* ------------------------------------------------------------------------- */ + +/* Check if a column-form matrix is valid or not. The matrix A is + * n_row-by-n_col. The row indices of entries in column j are in + * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: + * + * n_row >= 0 + * n_col >= 0 + * nz = Ap [n_col] >= 0 number of entries in the matrix + * Ap [0] == 0 + * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. + * Ai [0 ... nz-1] must be in the range 0 to n_row-1. + * + * If any of the above conditions hold, AMD_INVALID is returned. If the + * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning, + * not an error): + * + * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending + * order, and/or duplicate entries exist. + * + * Otherwise, AMD_OK is returned. + * + * In v1.2 and earlier, this function returned TRUE if the matrix was valid + * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or + * AMD_OK_BUT_JUMBLED). + */ + +#include "amd_internal.h" + +GLOBAL Int AMD_valid +( + /* inputs, not modified on output: */ + Int n_row, /* A is n_row-by-n_col */ + Int n_col, + const Int Ap [ ], /* column pointers of A, of size n_col+1 */ + const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */ +) +{ + Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ; + + if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL) + { + return (AMD_INVALID) ; + } + nz = Ap [n_col] ; + if (Ap [0] != 0 || nz < 0) + { + /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ + AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ; + return (AMD_INVALID) ; + } + for (j = 0 ; j < n_col ; j++) + { + p1 = Ap [j] ; + p2 = Ap [j+1] ; + AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ; + if (p1 > p2) + { + /* column pointers must be ascending */ + AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ; + return (AMD_INVALID) ; + } + ilast = EMPTY ; + for (p = p1 ; p < p2 ; p++) + { + i = Ai [p] ; + AMD_DEBUG3 (("row: "ID"\n", i)) ; + if (i < 0 || i >= n_row) + { + /* row index out of range */ + AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i)); + return (AMD_INVALID) ; + } + if (i <= ilast) + { + /* row index unsorted, or duplicate entry present */ + AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i)); + result = AMD_OK_BUT_JUMBLED ; + } + ilast = i ; + } + } + return (result) ; +} diff --git a/OpenDSSC/klusolve/AMD/Source/amdbar.f b/OpenDSSC/klusolve/AMD/Source/amdbar.f new file mode 100644 index 0000000..1384392 --- /dev/null +++ b/OpenDSSC/klusolve/AMD/Source/amdbar.f @@ -0,0 +1,1206 @@ +C----------------------------------------------------------------------- +C AMDBAR: approximate minimum degree, without aggressive absorption +C----------------------------------------------------------------------- + + SUBROUTINE AMDBAR + $ (N, PE, IW, LEN, IWLEN, PFREE, NV, NEXT, + $ LAST, HEAD, ELEN, DEGREE, NCMPA, W) + + INTEGER N, IWLEN, PFREE, NCMPA, IW (IWLEN), PE (N), + $ DEGREE (N), NV (N), NEXT (N), LAST (N), HEAD (N), + $ ELEN (N), W (N), LEN (N) + +C Given a representation of the nonzero pattern of a symmetric matrix, +C A, (excluding the diagonal) perform an approximate minimum +C (UMFPACK/MA38-style) degree ordering to compute a pivot order +C such that the introduction of nonzeros (fill-in) in the Cholesky +C factors A = LL^T are kept low. At each step, the pivot +C selected is the one with the minimum UMFPACK/MA38-style +C upper-bound on the external degree. +C +C This routine does not do aggresive absorption (as done by AMD). + +C ********************************************************************** +C ***** CAUTION: ARGUMENTS ARE NOT CHECKED FOR ERRORS ON INPUT. ****** +C ********************************************************************** + +C References: +C +C [1] Timothy A. Davis and Iain Duff, "An unsymmetric-pattern +C multifrontal method for sparse LU factorization", SIAM J. +C Matrix Analysis and Applications, vol. 18, no. 1, pp. +C 140-158. Discusses UMFPACK / MA38, which first introduced +C the approximate minimum degree used by this routine. +C +C [2] Patrick Amestoy, Timothy A. Davis, and Iain S. Duff, "An +C approximate degree ordering algorithm," SIAM J. Matrix +C Analysis and Applications, vol. 17, no. 4, pp. 886-905, +C 1996. Discusses AMD, AMDBAR, and MC47B. +C +C [3] Alan George and Joseph Liu, "The evolution of the minimum +C degree ordering algorithm," SIAM Review, vol. 31, no. 1, +C pp. 1-19, 1989. We list below the features mentioned in +C that paper that this code includes: +C +C mass elimination: +C Yes. MA27 relied on supervariable detection for mass +C elimination. +C indistinguishable nodes: +C Yes (we call these "supervariables"). This was also in +C the MA27 code - although we modified the method of +C detecting them (the previous hash was the true degree, +C which we no longer keep track of). A supervariable is +C a set of rows with identical nonzero pattern. All +C variables in a supervariable are eliminated together. +C Each supervariable has as its numerical name that of +C one of its variables (its principal variable). +C quotient graph representation: +C Yes. We use the term "element" for the cliques formed +C during elimination. This was also in the MA27 code. +C The algorithm can operate in place, but it will work +C more efficiently if given some "elbow room." +C element absorption: +C Yes. This was also in the MA27 code. +C external degree: +C Yes. The MA27 code was based on the true degree. +C incomplete degree update and multiple elimination: +C No. This was not in MA27, either. Our method of +C degree update within MC47B/BD is element-based, not +C variable-based. It is thus not well-suited for use +C with incomplete degree update or multiple elimination. + +C----------------------------------------------------------------------- +C Authors, and Copyright (C) 1995 by: +C Timothy A. Davis, Patrick Amestoy, Iain S. Duff, & John K. Reid. +C +C Acknowledgements: +C This work (and the UMFPACK package) was supported by the +C National Science Foundation (ASC-9111263 and DMS-9223088). +C The UMFPACK/MA38 approximate degree update algorithm, the +C unsymmetric analog which forms the basis of MC47B/BD, was +C developed while Tim Davis was supported by CERFACS (Toulouse, +C France) in a post-doctoral position. +C +C Date: September, 1995 +C----------------------------------------------------------------------- + +C----------------------------------------------------------------------- +C INPUT ARGUMENTS (unaltered): +C----------------------------------------------------------------------- + +C n: The matrix order. +C +C Restriction: 1 .le. n .lt. (iovflo/2)-2, where iovflo is +C the largest positive integer that your computer can represent. + +C iwlen: The length of iw (1..iwlen). On input, the matrix is +C stored in iw (1..pfree-1). However, iw (1..iwlen) should be +C slightly larger than what is required to hold the matrix, at +C least iwlen .ge. pfree + n is recommended. Otherwise, +C excessive compressions will take place. +C *** We do not recommend running this algorithm with *** +C *** iwlen .lt. pfree + n. *** +C *** Better performance will be obtained if *** +C *** iwlen .ge. pfree + n *** +C *** or better yet *** +C *** iwlen .gt. 1.2 * pfree *** +C *** (where pfree is its value on input). *** +C The algorithm will not run at all if iwlen .lt. pfree-1. +C +C Restriction: iwlen .ge. pfree-1 + +C----------------------------------------------------------------------- +C INPUT/OUPUT ARGUMENTS: +C----------------------------------------------------------------------- + +C pe: On input, pe (i) is the index in iw of the start of row i, or +C zero if row i has no off-diagonal non-zeros. +C +C During execution, it is used for both supervariables and +C elements: +C +C * Principal supervariable i: index into iw of the +C description of supervariable i. A supervariable +C represents one or more rows of the matrix +C with identical nonzero pattern. +C * Non-principal supervariable i: if i has been absorbed +C into another supervariable j, then pe (i) = -j. +C That is, j has the same pattern as i. +C Note that j might later be absorbed into another +C supervariable j2, in which case pe (i) is still -j, +C and pe (j) = -j2. +C * Unabsorbed element e: the index into iw of the description +C of element e, if e has not yet been absorbed by a +C subsequent element. Element e is created when +C the supervariable of the same name is selected as +C the pivot. +C * Absorbed element e: if element e is absorbed into element +C e2, then pe (e) = -e2. This occurs when the pattern of +C e (that is, Le) is found to be a subset of the pattern +C of e2 (that is, Le2). If element e is "null" (it has +C no nonzeros outside its pivot block), then pe (e) = 0. +C +C On output, pe holds the assembly tree/forest, which implicitly +C represents a pivot order with identical fill-in as the actual +C order (via a depth-first search of the tree). +C +C On output: +C If nv (i) .gt. 0, then i represents a node in the assembly tree, +C and the parent of i is -pe (i), or zero if i is a root. +C If nv (i) = 0, then (i,-pe (i)) represents an edge in a +C subtree, the root of which is a node in the assembly tree. + +C pfree: On input the tail end of the array, iw (pfree..iwlen), +C is empty, and the matrix is stored in iw (1..pfree-1). +C During execution, additional data is placed in iw, and pfree +C is modified so that iw (pfree..iwlen) is always the unused part +C of iw. On output, pfree is set equal to the size of iw that +C would have been needed for no compressions to occur. If +C ncmpa is zero, then pfree (on output) is less than or equal to +C iwlen, and the space iw (pfree+1 ... iwlen) was not used. +C Otherwise, pfree (on output) is greater than iwlen, and all the +C memory in iw was used. + +C----------------------------------------------------------------------- +C INPUT/MODIFIED (undefined on output): +C----------------------------------------------------------------------- + +C len: On input, len (i) holds the number of entries in row i of the +C matrix, excluding the diagonal. The contents of len (1..n) +C are undefined on output. + +C iw: On input, iw (1..pfree-1) holds the description of each row i +C in the matrix. The matrix must be symmetric, and both upper +C and lower triangular parts must be present. The diagonal must +C not be present. Row i is held as follows: +C +C len (i): the length of the row i data structure +C iw (pe (i) ... pe (i) + len (i) - 1): +C the list of column indices for nonzeros +C in row i (simple supervariables), excluding +C the diagonal. All supervariables start with +C one row/column each (supervariable i is just +C row i). +C if len (i) is zero on input, then pe (i) is ignored +C on input. +C +C Note that the rows need not be in any particular order, +C and there may be empty space between the rows. +C +C During execution, the supervariable i experiences fill-in. +C This is represented by placing in i a list of the elements +C that cause fill-in in supervariable i: +C +C len (i): the length of supervariable i +C iw (pe (i) ... pe (i) + elen (i) - 1): +C the list of elements that contain i. This list +C is kept short by removing absorbed elements. +C iw (pe (i) + elen (i) ... pe (i) + len (i) - 1): +C the list of supervariables in i. This list +C is kept short by removing nonprincipal +C variables, and any entry j that is also +C contained in at least one of the elements +C (j in Le) in the list for i (e in row i). +C +C When supervariable i is selected as pivot, we create an +C element e of the same name (e=i): +C +C len (e): the length of element e +C iw (pe (e) ... pe (e) + len (e) - 1): +C the list of supervariables in element e. +C +C An element represents the fill-in that occurs when supervariable +C i is selected as pivot (which represents the selection of row i +C and all non-principal variables whose principal variable is i). +C We use the term Le to denote the set of all supervariables +C in element e. Absorbed supervariables and elements are pruned +C from these lists when computationally convenient. +C +C CAUTION: THE INPUT MATRIX IS OVERWRITTEN DURING COMPUTATION. +C The contents of iw are undefined on output. + +C----------------------------------------------------------------------- +C OUTPUT (need not be set on input): +C----------------------------------------------------------------------- + +C nv: During execution, abs (nv (i)) is equal to the number of rows +C that are represented by the principal supervariable i. If i is +C a nonprincipal variable, then nv (i) = 0. Initially, +C nv (i) = 1 for all i. nv (i) .lt. 0 signifies that i is a +C principal variable in the pattern Lme of the current pivot +C element me. On output, nv (e) holds the true degree of element +C e at the time it was created (including the diagonal part). + +C ncmpa: The number of times iw was compressed. If this is +C excessive, then the execution took longer than what could have +C been. To reduce ncmpa, try increasing iwlen to be 10% or 20% +C larger than the value of pfree on input (or at least +C iwlen .ge. pfree + n). The fastest performance will be +C obtained when ncmpa is returned as zero. If iwlen is set to +C the value returned by pfree on *output*, then no compressions +C will occur. + +C elen: See the description of iw above. At the start of execution, +C elen (i) is set to zero. During execution, elen (i) is the +C number of elements in the list for supervariable i. When e +C becomes an element, elen (e) = -nel is set, where nel is the +C current step of factorization. elen (i) = 0 is done when i +C becomes nonprincipal. +C +C For variables, elen (i) .ge. 0 holds until just before the +C permutation vectors are computed. For elements, +C elen (e) .lt. 0 holds. +C +C On output elen (1..n) holds the inverse permutation (the same +C as the 'INVP' argument in Sparspak). That is, if k = elen (i), +C then row i is the kth pivot row. Row i of A appears as the +C (elen(i))-th row in the permuted matrix, PAP^T. + +C last: In a degree list, last (i) is the supervariable preceding i, +C or zero if i is the head of the list. In a hash bucket, +C last (i) is the hash key for i. last (head (hash)) is also +C used as the head of a hash bucket if head (hash) contains a +C degree list (see head, below). +C +C On output, last (1..n) holds the permutation (the same as the +C 'PERM' argument in Sparspak). That is, if i = last (k), then +C row i is the kth pivot row. Row last (k) of A is the k-th row +C in the permuted matrix, PAP^T. + +C----------------------------------------------------------------------- +C LOCAL (not input or output - used only during execution): +C----------------------------------------------------------------------- + +C degree: If i is a supervariable, then degree (i) holds the +C current approximation of the external degree of row i (an upper +C bound). The external degree is the number of nonzeros in row i, +C minus abs (nv (i)) (the diagonal part). The bound is equal to +C the external degree if elen (i) is less than or equal to two. +C +C We also use the term "external degree" for elements e to refer +C to |Le \ Lme|. If e is an element, then degree (e) holds |Le|, +C which is the degree of the off-diagonal part of the element e +C (not including the diagonal part). + +C head: head is used for degree lists. head (deg) is the first +C supervariable in a degree list (all supervariables i in a +C degree list deg have the same approximate degree, namely, +C deg = degree (i)). If the list deg is empty then +C head (deg) = 0. +C +C During supervariable detection head (hash) also serves as a +C pointer to a hash bucket. +C If head (hash) .gt. 0, there is a degree list of degree hash. +C The hash bucket head pointer is last (head (hash)). +C If head (hash) = 0, then the degree list and hash bucket are +C both empty. +C If head (hash) .lt. 0, then the degree list is empty, and +C -head (hash) is the head of the hash bucket. +C After supervariable detection is complete, all hash buckets +C are empty, and the (last (head (hash)) = 0) condition is +C restored for the non-empty degree lists. + +C next: next (i) is the supervariable following i in a link list, or +C zero if i is the last in the list. Used for two kinds of +C lists: degree lists and hash buckets (a supervariable can be +C in only one kind of list at a time). + +C w: The flag array w determines the status of elements and +C variables, and the external degree of elements. +C +C for elements: +C if w (e) = 0, then the element e is absorbed +C if w (e) .ge. wflg, then w (e) - wflg is the size of +C the set |Le \ Lme|, in terms of nonzeros (the +C sum of abs (nv (i)) for each principal variable i that +C is both in the pattern of element e and NOT in the +C pattern of the current pivot element, me). +C if wflg .gt. w (e) .gt. 0, then e is not absorbed and has +C not yet been seen in the scan of the element lists in +C the computation of |Le\Lme| in loop 150 below. +C +C for variables: +C during supervariable detection, if w (j) .ne. wflg then j is +C not in the pattern of variable i +C +C The w array is initialized by setting w (i) = 1 for all i, +C and by setting wflg = 2. It is reinitialized if wflg becomes +C too large (to ensure that wflg+n does not cause integer +C overflow). + +C----------------------------------------------------------------------- +C LOCAL INTEGERS: +C----------------------------------------------------------------------- + + INTEGER DEG, DEGME, DMAX, E, ELENME, ELN, HASH, HMOD, I, + $ ILAST, INEXT, J, JLAST, JNEXT, K, KNT1, KNT2, KNT3, + $ LENJ, LN, MAXMEM, ME, MEM, MINDEG, NEL, NEWMEM, + $ NLEFT, NVI, NVJ, NVPIV, SLENME, WE, WFLG, WNVI, X + +C deg: the degree of a variable or element +C degme: size, |Lme|, of the current element, me (= degree (me)) +C dext: external degree, |Le \ Lme|, of some element e +C dmax: largest |Le| seen so far +C e: an element +C elenme: the length, elen (me), of element list of pivotal var. +C eln: the length, elen (...), of an element list +C hash: the computed value of the hash function +C hmod: the hash function is computed modulo hmod = max (1,n-1) +C i: a supervariable +C ilast: the entry in a link list preceding i +C inext: the entry in a link list following i +C j: a supervariable +C jlast: the entry in a link list preceding j +C jnext: the entry in a link list, or path, following j +C k: the pivot order of an element or variable +C knt1: loop counter used during element construction +C knt2: loop counter used during element construction +C knt3: loop counter used during compression +C lenj: len (j) +C ln: length of a supervariable list +C maxmem: amount of memory needed for no compressions +C me: current supervariable being eliminated, and the +C current element created by eliminating that +C supervariable +C mem: memory in use assuming no compressions have occurred +C mindeg: current minimum degree +C nel: number of pivots selected so far +C newmem: amount of new memory needed for current pivot element +C nleft: n - nel, the number of nonpivotal rows/columns remaining +C nvi: the number of variables in a supervariable i (= nv (i)) +C nvj: the number of variables in a supervariable j (= nv (j)) +C nvpiv: number of pivots in current element +C slenme: number of variables in variable list of pivotal variable +C we: w (e) +C wflg: used for flagging the w array. See description of iw. +C wnvi: wflg - nv (i) +C x: either a supervariable or an element + +C----------------------------------------------------------------------- +C LOCAL POINTERS: +C----------------------------------------------------------------------- + + INTEGER P, P1, P2, P3, PDST, PEND, PJ, PME, PME1, PME2, PN, PSRC + +C Any parameter (pe (...) or pfree) or local variable +C starting with "p" (for Pointer) is an index into iw, +C and all indices into iw use variables starting with +C "p." The only exception to this rule is the iwlen +C input argument. + +C p: pointer into lots of things +C p1: pe (i) for some variable i (start of element list) +C p2: pe (i) + elen (i) - 1 for some var. i (end of el. list) +C p3: index of first supervariable in clean list +C pdst: destination pointer, for compression +C pend: end of memory to compress +C pj: pointer into an element or variable +C pme: pointer into the current element (pme1...pme2) +C pme1: the current element, me, is stored in iw (pme1...pme2) +C pme2: the end of the current element +C pn: pointer into a "clean" variable, also used to compress +C psrc: source pointer, for compression + +C----------------------------------------------------------------------- +C FUNCTIONS CALLED: +C----------------------------------------------------------------------- + + INTRINSIC MAX, MIN, MOD + +C======================================================================= +C INITIALIZATIONS +C======================================================================= + + WFLG = 2 + MINDEG = 1 + NCMPA = 0 + NEL = 0 + HMOD = MAX (1, N-1) + DMAX = 0 + MEM = PFREE - 1 + MAXMEM = MEM + ME = 0 + + DO 10 I = 1, N + LAST (I) = 0 + HEAD (I) = 0 + NV (I) = 1 + W (I) = 1 + ELEN (I) = 0 + DEGREE (I) = LEN (I) +10 CONTINUE + +C ---------------------------------------------------------------- +C initialize degree lists and eliminate rows with no off-diag. nz. +C ---------------------------------------------------------------- + + DO 20 I = 1, N + + DEG = DEGREE (I) + + IF (DEG .GT. 0) THEN + +C ---------------------------------------------------------- +C place i in the degree list corresponding to its degree +C ---------------------------------------------------------- + + INEXT = HEAD (DEG) + IF (INEXT .NE. 0) LAST (INEXT) = I + NEXT (I) = INEXT + HEAD (DEG) = I + + ELSE + +C ---------------------------------------------------------- +C we have a variable that can be eliminated at once because +C there is no off-diagonal non-zero in its row. +C ---------------------------------------------------------- + + NEL = NEL + 1 + ELEN (I) = -NEL + PE (I) = 0 + W (I) = 0 + + ENDIF + +20 CONTINUE + +C======================================================================= +C WHILE (selecting pivots) DO +C======================================================================= + +30 CONTINUE + IF (NEL .LT. N) THEN + +C======================================================================= +C GET PIVOT OF MINIMUM DEGREE +C======================================================================= + +C ------------------------------------------------------------- +C find next supervariable for elimination +C ------------------------------------------------------------- + + DO 40 DEG = MINDEG, N + ME = HEAD (DEG) + IF (ME .GT. 0) GOTO 50 +40 CONTINUE +50 CONTINUE + MINDEG = DEG + +C ------------------------------------------------------------- +C remove chosen variable from link list +C ------------------------------------------------------------- + + INEXT = NEXT (ME) + IF (INEXT .NE. 0) LAST (INEXT) = 0 + HEAD (DEG) = INEXT + +C ------------------------------------------------------------- +C me represents the elimination of pivots nel+1 to nel+nv(me). +C place me itself as the first in this set. It will be moved +C to the nel+nv(me) position when the permutation vectors are +C computed. +C ------------------------------------------------------------- + + ELENME = ELEN (ME) + ELEN (ME) = - (NEL + 1) + NVPIV = NV (ME) + NEL = NEL + NVPIV + +C======================================================================= +C CONSTRUCT NEW ELEMENT +C======================================================================= + +C ------------------------------------------------------------- +C At this point, me is the pivotal supervariable. It will be +C converted into the current element. Scan list of the +C pivotal supervariable, me, setting tree pointers and +C constructing new list of supervariables for the new element, +C me. p is a pointer to the current position in the old list. +C ------------------------------------------------------------- + +C flag the variable "me" as being in Lme by negating nv (me) + NV (ME) = -NVPIV + DEGME = 0 + + IF (ELENME .EQ. 0) THEN + +C ---------------------------------------------------------- +C construct the new element in place +C ---------------------------------------------------------- + + PME1 = PE (ME) + PME2 = PME1 - 1 + + DO 60 P = PME1, PME1 + LEN (ME) - 1 + I = IW (P) + NVI = NV (I) + IF (NVI .GT. 0) THEN + +C ---------------------------------------------------- +C i is a principal variable not yet placed in Lme. +C store i in new list +C ---------------------------------------------------- + + DEGME = DEGME + NVI +C flag i as being in Lme by negating nv (i) + NV (I) = -NVI + PME2 = PME2 + 1 + IW (PME2) = I + +C ---------------------------------------------------- +C remove variable i from degree list. +C ---------------------------------------------------- + + ILAST = LAST (I) + INEXT = NEXT (I) + IF (INEXT .NE. 0) LAST (INEXT) = ILAST + IF (ILAST .NE. 0) THEN + NEXT (ILAST) = INEXT + ELSE +C i is at the head of the degree list + HEAD (DEGREE (I)) = INEXT + ENDIF + + ENDIF +60 CONTINUE +C this element takes no new memory in iw: + NEWMEM = 0 + + ELSE + +C ---------------------------------------------------------- +C construct the new element in empty space, iw (pfree ...) +C ---------------------------------------------------------- + + P = PE (ME) + PME1 = PFREE + SLENME = LEN (ME) - ELENME + + DO 120 KNT1 = 1, ELENME + 1 + + IF (KNT1 .GT. ELENME) THEN +C search the supervariables in me. + E = ME + PJ = P + LN = SLENME + ELSE +C search the elements in me. + E = IW (P) + P = P + 1 + PJ = PE (E) + LN = LEN (E) + ENDIF + +C ------------------------------------------------------- +C search for different supervariables and add them to the +C new list, compressing when necessary. this loop is +C executed once for each element in the list and once for +C all the supervariables in the list. +C ------------------------------------------------------- + + DO 110 KNT2 = 1, LN + I = IW (PJ) + PJ = PJ + 1 + NVI = NV (I) + IF (NVI .GT. 0) THEN + +C ------------------------------------------------- +C compress iw, if necessary +C ------------------------------------------------- + + IF (PFREE .GT. IWLEN) THEN +C prepare for compressing iw by adjusting +C pointers and lengths so that the lists being +C searched in the inner and outer loops contain +C only the remaining entries. + + PE (ME) = P + LEN (ME) = LEN (ME) - KNT1 + IF (LEN (ME) .EQ. 0) THEN +C nothing left of supervariable me + PE (ME) = 0 + ENDIF + PE (E) = PJ + LEN (E) = LN - KNT2 + IF (LEN (E) .EQ. 0) THEN +C nothing left of element e + PE (E) = 0 + ENDIF + + NCMPA = NCMPA + 1 +C store first item in pe +C set first entry to -item + DO 70 J = 1, N + PN = PE (J) + IF (PN .GT. 0) THEN + PE (J) = IW (PN) + IW (PN) = -J + ENDIF +70 CONTINUE + +C psrc/pdst point to source/destination + PDST = 1 + PSRC = 1 + PEND = PME1 - 1 + +C while loop: +80 CONTINUE + IF (PSRC .LE. PEND) THEN +C search for next negative entry + J = -IW (PSRC) + PSRC = PSRC + 1 + IF (J .GT. 0) THEN + IW (PDST) = PE (J) + PE (J) = PDST + PDST = PDST + 1 +C copy from source to destination + LENJ = LEN (J) + DO 90 KNT3 = 0, LENJ - 2 + IW (PDST + KNT3) = IW (PSRC + KNT3) +90 CONTINUE + PDST = PDST + LENJ - 1 + PSRC = PSRC + LENJ - 1 + ENDIF + GOTO 80 + ENDIF + +C move the new partially-constructed element + P1 = PDST + DO 100 PSRC = PME1, PFREE - 1 + IW (PDST) = IW (PSRC) + PDST = PDST + 1 +100 CONTINUE + PME1 = P1 + PFREE = PDST + PJ = PE (E) + P = PE (ME) + ENDIF + +C ------------------------------------------------- +C i is a principal variable not yet placed in Lme +C store i in new list +C ------------------------------------------------- + + DEGME = DEGME + NVI +C flag i as being in Lme by negating nv (i) + NV (I) = -NVI + IW (PFREE) = I + PFREE = PFREE + 1 + +C ------------------------------------------------- +C remove variable i from degree link list +C ------------------------------------------------- + + ILAST = LAST (I) + INEXT = NEXT (I) + IF (INEXT .NE. 0) LAST (INEXT) = ILAST + IF (ILAST .NE. 0) THEN + NEXT (ILAST) = INEXT + ELSE +C i is at the head of the degree list + HEAD (DEGREE (I)) = INEXT + ENDIF + + ENDIF +110 CONTINUE + + IF (E .NE. ME) THEN +C set tree pointer and flag to indicate element e is +C absorbed into new element me (the parent of e is me) + PE (E) = -ME + W (E) = 0 + ENDIF +120 CONTINUE + + PME2 = PFREE - 1 +C this element takes newmem new memory in iw (possibly zero) + NEWMEM = PFREE - PME1 + MEM = MEM + NEWMEM + MAXMEM = MAX (MAXMEM, MEM) + ENDIF + +C ------------------------------------------------------------- +C me has now been converted into an element in iw (pme1..pme2) +C ------------------------------------------------------------- + +C degme holds the external degree of new element + DEGREE (ME) = DEGME + PE (ME) = PME1 + LEN (ME) = PME2 - PME1 + 1 + +C ------------------------------------------------------------- +C make sure that wflg is not too large. With the current +C value of wflg, wflg+n must not cause integer overflow +C ------------------------------------------------------------- + + IF (WFLG + N .LE. WFLG) THEN + DO 130 X = 1, N + IF (W (X) .NE. 0) W (X) = 1 +130 CONTINUE + WFLG = 2 + ENDIF + +C======================================================================= +C COMPUTE (w (e) - wflg) = |Le\Lme| FOR ALL ELEMENTS +C======================================================================= + +C ------------------------------------------------------------- +C Scan 1: compute the external degrees of previous elements +C with respect to the current element. That is: +C (w (e) - wflg) = |Le \ Lme| +C for each element e that appears in any supervariable in Lme. +C The notation Le refers to the pattern (list of +C supervariables) of a previous element e, where e is not yet +C absorbed, stored in iw (pe (e) + 1 ... pe (e) + iw (pe (e))). +C The notation Lme refers to the pattern of the current element +C (stored in iw (pme1..pme2)). If (w (e) - wflg) becomes +C zero, then the element e will be absorbed in scan 2. +C ------------------------------------------------------------- + + DO 150 PME = PME1, PME2 + I = IW (PME) + ELN = ELEN (I) + IF (ELN .GT. 0) THEN +C note that nv (i) has been negated to denote i in Lme: + NVI = -NV (I) + WNVI = WFLG - NVI + DO 140 P = PE (I), PE (I) + ELN - 1 + E = IW (P) + WE = W (E) + IF (WE .GE. WFLG) THEN +C unabsorbed element e has been seen in this loop + WE = WE - NVI + ELSE IF (WE .NE. 0) THEN +C e is an unabsorbed element +C this is the first we have seen e in all of Scan 1 + WE = DEGREE (E) + WNVI + ENDIF + W (E) = WE +140 CONTINUE + ENDIF +150 CONTINUE + +C======================================================================= +C DEGREE UPDATE AND ELEMENT ABSORPTION +C======================================================================= + +C ------------------------------------------------------------- +C Scan 2: for each i in Lme, sum up the degree of Lme (which +C is degme), plus the sum of the external degrees of each Le +C for the elements e appearing within i, plus the +C supervariables in i. Place i in hash list. +C ------------------------------------------------------------- + + DO 180 PME = PME1, PME2 + I = IW (PME) + P1 = PE (I) + P2 = P1 + ELEN (I) - 1 + PN = P1 + HASH = 0 + DEG = 0 + +C ---------------------------------------------------------- +C scan the element list associated with supervariable i +C ---------------------------------------------------------- + +C UMFPACK/MA38-style approximate degree: + DO 160 P = P1, P2 + E = IW (P) + WE = W (E) + IF (WE .NE. 0) THEN +C e is an unabsorbed element + DEG = DEG + WE - WFLG + IW (PN) = E + PN = PN + 1 + HASH = HASH + E + ENDIF +160 CONTINUE + +C count the number of elements in i (including me): + ELEN (I) = PN - P1 + 1 + +C ---------------------------------------------------------- +C scan the supervariables in the list associated with i +C ---------------------------------------------------------- + + P3 = PN + DO 170 P = P2 + 1, P1 + LEN (I) - 1 + J = IW (P) + NVJ = NV (J) + IF (NVJ .GT. 0) THEN +C j is unabsorbed, and not in Lme. +C add to degree and add to new list + DEG = DEG + NVJ + IW (PN) = J + PN = PN + 1 + HASH = HASH + J + ENDIF +170 CONTINUE + +C ---------------------------------------------------------- +C update the degree and check for mass elimination +C ---------------------------------------------------------- + + IF (ELEN (I) .EQ. 1 .AND. P3 .EQ. PN) THEN + +C ------------------------------------------------------- +C mass elimination +C ------------------------------------------------------- + +C There is nothing left of this node except for an +C edge to the current pivot element. elen (i) is 1, +C and there are no variables adjacent to node i. +C Absorb i into the current pivot element, me. + + PE (I) = -ME + NVI = -NV (I) + DEGME = DEGME - NVI + NVPIV = NVPIV + NVI + NEL = NEL + NVI + NV (I) = 0 + ELEN (I) = 0 + + ELSE + +C ------------------------------------------------------- +C update the upper-bound degree of i +C ------------------------------------------------------- + +C the following degree does not yet include the size +C of the current element, which is added later: + DEGREE (I) = MIN (DEGREE (I), DEG) + +C ------------------------------------------------------- +C add me to the list for i +C ------------------------------------------------------- + +C move first supervariable to end of list + IW (PN) = IW (P3) +C move first element to end of element part of list + IW (P3) = IW (P1) +C add new element to front of list. + IW (P1) = ME +C store the new length of the list in len (i) + LEN (I) = PN - P1 + 1 + +C ------------------------------------------------------- +C place in hash bucket. Save hash key of i in last (i). +C ------------------------------------------------------- + + HASH = MOD (HASH, HMOD) + 1 + J = HEAD (HASH) + IF (J .LE. 0) THEN +C the degree list is empty, hash head is -j + NEXT (I) = -J + HEAD (HASH) = -I + ELSE +C degree list is not empty +C use last (head (hash)) as hash head + NEXT (I) = LAST (J) + LAST (J) = I + ENDIF + LAST (I) = HASH + ENDIF +180 CONTINUE + + DEGREE (ME) = DEGME + +C ------------------------------------------------------------- +C Clear the counter array, w (...), by incrementing wflg. +C ------------------------------------------------------------- + + DMAX = MAX (DMAX, DEGME) + WFLG = WFLG + DMAX + +C make sure that wflg+n does not cause integer overflow + IF (WFLG + N .LE. WFLG) THEN + DO 190 X = 1, N + IF (W (X) .NE. 0) W (X) = 1 +190 CONTINUE + WFLG = 2 + ENDIF +C at this point, w (1..n) .lt. wflg holds + +C======================================================================= +C SUPERVARIABLE DETECTION +C======================================================================= + + DO 250 PME = PME1, PME2 + I = IW (PME) + IF (NV (I) .LT. 0) THEN +C i is a principal variable in Lme + +C ------------------------------------------------------- +C examine all hash buckets with 2 or more variables. We +C do this by examing all unique hash keys for super- +C variables in the pattern Lme of the current element, me +C ------------------------------------------------------- + + HASH = LAST (I) +C let i = head of hash bucket, and empty the hash bucket + J = HEAD (HASH) + IF (J .EQ. 0) GOTO 250 + IF (J .LT. 0) THEN +C degree list is empty + I = -J + HEAD (HASH) = 0 + ELSE +C degree list is not empty, restore last () of head + I = LAST (J) + LAST (J) = 0 + ENDIF + IF (I .EQ. 0) GOTO 250 + +C while loop: +200 CONTINUE + IF (NEXT (I) .NE. 0) THEN + +C ---------------------------------------------------- +C this bucket has one or more variables following i. +C scan all of them to see if i can absorb any entries +C that follow i in hash bucket. Scatter i into w. +C ---------------------------------------------------- + + LN = LEN (I) + ELN = ELEN (I) +C do not flag the first element in the list (me) + DO 210 P = PE (I) + 1, PE (I) + LN - 1 + W (IW (P)) = WFLG +210 CONTINUE + +C ---------------------------------------------------- +C scan every other entry j following i in bucket +C ---------------------------------------------------- + + JLAST = I + J = NEXT (I) + +C while loop: +220 CONTINUE + IF (J .NE. 0) THEN + +C ------------------------------------------------- +C check if j and i have identical nonzero pattern +C ------------------------------------------------- + + IF (LEN (J) .NE. LN) THEN +C i and j do not have same size data structure + GOTO 240 + ENDIF + IF (ELEN (J) .NE. ELN) THEN +C i and j do not have same number of adjacent el + GOTO 240 + ENDIF +C do not flag the first element in the list (me) + DO 230 P = PE (J) + 1, PE (J) + LN - 1 + IF (W (IW (P)) .NE. WFLG) THEN +C an entry (iw(p)) is in j but not in i + GOTO 240 + ENDIF +230 CONTINUE + +C ------------------------------------------------- +C found it! j can be absorbed into i +C ------------------------------------------------- + + PE (J) = -I +C both nv (i) and nv (j) are negated since they +C are in Lme, and the absolute values of each +C are the number of variables in i and j: + NV (I) = NV (I) + NV (J) + NV (J) = 0 + ELEN (J) = 0 +C delete j from hash bucket + J = NEXT (J) + NEXT (JLAST) = J + GOTO 220 + +C ------------------------------------------------- +240 CONTINUE +C j cannot be absorbed into i +C ------------------------------------------------- + + JLAST = J + J = NEXT (J) + GOTO 220 + ENDIF + +C ---------------------------------------------------- +C no more variables can be absorbed into i +C go to next i in bucket and clear flag array +C ---------------------------------------------------- + + WFLG = WFLG + 1 + I = NEXT (I) + IF (I .NE. 0) GOTO 200 + ENDIF + ENDIF +250 CONTINUE + +C======================================================================= +C RESTORE DEGREE LISTS AND REMOVE NONPRINCIPAL SUPERVAR. FROM ELEMENT +C======================================================================= + + P = PME1 + NLEFT = N - NEL + DO 260 PME = PME1, PME2 + I = IW (PME) + NVI = -NV (I) + IF (NVI .GT. 0) THEN +C i is a principal variable in Lme +C restore nv (i) to signify that i is principal + NV (I) = NVI + +C ------------------------------------------------------- +C compute the external degree (add size of current elem) +C ------------------------------------------------------- + + DEG = MAX (1, MIN (DEGREE (I) + DEGME-NVI, NLEFT-NVI)) + +C ------------------------------------------------------- +C place the supervariable at the head of the degree list +C ------------------------------------------------------- + + INEXT = HEAD (DEG) + IF (INEXT .NE. 0) LAST (INEXT) = I + NEXT (I) = INEXT + LAST (I) = 0 + HEAD (DEG) = I + +C ------------------------------------------------------- +C save the new degree, and find the minimum degree +C ------------------------------------------------------- + + MINDEG = MIN (MINDEG, DEG) + DEGREE (I) = DEG + +C ------------------------------------------------------- +C place the supervariable in the element pattern +C ------------------------------------------------------- + + IW (P) = I + P = P + 1 + ENDIF +260 CONTINUE + +C======================================================================= +C FINALIZE THE NEW ELEMENT +C======================================================================= + + NV (ME) = NVPIV + DEGME +C nv (me) is now the degree of pivot (including diagonal part) +C save the length of the list for the new element me + LEN (ME) = P - PME1 + IF (LEN (ME) .EQ. 0) THEN +C there is nothing left of the current pivot element + PE (ME) = 0 + W (ME) = 0 + ENDIF + IF (NEWMEM .NE. 0) THEN +C element was not constructed in place: deallocate part +C of it (final size is less than or equal to newmem, +C since newly nonprincipal variables have been removed). + PFREE = P + MEM = MEM - NEWMEM + LEN (ME) + ENDIF + +C======================================================================= +C END WHILE (selecting pivots) + GOTO 30 + ENDIF +C======================================================================= + +C======================================================================= +C COMPUTE THE PERMUTATION VECTORS +C======================================================================= + +C ---------------------------------------------------------------- +C The time taken by the following code is O(n). At this +C point, elen (e) = -k has been done for all elements e, +C and elen (i) = 0 has been done for all nonprincipal +C variables i. At this point, there are no principal +C supervariables left, and all elements are absorbed. +C ---------------------------------------------------------------- + +C ---------------------------------------------------------------- +C compute the ordering of unordered nonprincipal variables +C ---------------------------------------------------------------- + + DO 290 I = 1, N + IF (ELEN (I) .EQ. 0) THEN + +C ---------------------------------------------------------- +C i is an un-ordered row. Traverse the tree from i until +C reaching an element, e. The element, e, was the +C principal supervariable of i and all nodes in the path +C from i to when e was selected as pivot. +C ---------------------------------------------------------- + + J = -PE (I) +C while (j is a variable) do: +270 CONTINUE + IF (ELEN (J) .GE. 0) THEN + J = -PE (J) + GOTO 270 + ENDIF + E = J + +C ---------------------------------------------------------- +C get the current pivot ordering of e +C ---------------------------------------------------------- + + K = -ELEN (E) + +C ---------------------------------------------------------- +C traverse the path again from i to e, and compress the +C path (all nodes point to e). Path compression allows +C this code to compute in O(n) time. Order the unordered +C nodes in the path, and place the element e at the end. +C ---------------------------------------------------------- + + J = I +C while (j is a variable) do: +280 CONTINUE + IF (ELEN (J) .GE. 0) THEN + JNEXT = -PE (J) + PE (J) = -E + IF (ELEN (J) .EQ. 0) THEN +C j is an unordered row + ELEN (J) = K + K = K + 1 + ENDIF + J = JNEXT + GOTO 280 + ENDIF +C leave elen (e) negative, so we know it is an element + ELEN (E) = -K + ENDIF +290 CONTINUE + +C ---------------------------------------------------------------- +C reset the inverse permutation (elen (1..n)) to be positive, +C and compute the permutation (last (1..n)). +C ---------------------------------------------------------------- + + DO 300 I = 1, N + K = ABS (ELEN (I)) + LAST (K) = I + ELEN (I) = K +300 CONTINUE + +C======================================================================= +C RETURN THE MEMORY USAGE IN IW +C======================================================================= + +C If maxmem is less than or equal to iwlen, then no compressions +C occurred, and iw (maxmem+1 ... iwlen) was unused. Otherwise +C compressions did occur, and iwlen would have had to have been +C greater than or equal to maxmem for no compressions to occur. +C Return the value of maxmem in the pfree argument. + + PFREE = MAXMEM + + RETURN + END + diff --git a/OpenDSSC/klusolve/BTF/Doc/ChangeLog b/OpenDSSC/klusolve/BTF/Doc/ChangeLog new file mode 100644 index 0000000..ee289d4 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Doc/ChangeLog @@ -0,0 +1,38 @@ +Nov 1, 2007: version 1.0.1 + + * trivial change to BTF/MATLAB/btf.c mexFunction: unused variable removed. + +May 31, 2007: version 1.0 released + + * the C application program interface has been modified (see below) + + * maxtrans function renamed to btf_maxtrans + + * strongcomp function renamed to btf_strongcomp + + * full statement coverage tests (KLU/Tcov) + + * maxwork parameter added to btf_maxtrans and btf_order + + * btf_maxtrans modified; now returns Q[i] = -1 if row i is unmatched; + code to complete the permutation moved to btf_order. This also + changes the maxtrans mexFunction. + + * btf_install added for easy MATLAB installation + + * illustrative recursive version of maxtrans removed (see the recursive + version of cs_maxtrans in CSparse instead) + + * MAXTRANS_* macros renamed BTF_* + + * no bug fixes in this release + +Dec 12, 2006: version 0.11 + + * minor MATLAB cleanup + +Apr 30, 2006: + + * minor editing of comments. dmperm.c moved to MATLAB directory, since + it requires MATLAB. Version number not changed. + diff --git a/OpenDSSC/klusolve/BTF/Doc/lesser.txt b/OpenDSSC/klusolve/BTF/Doc/lesser.txt new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/OpenDSSC/klusolve/BTF/Include/btf.h b/OpenDSSC/klusolve/BTF/Include/btf.h new file mode 100644 index 0000000..b62d009 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Include/btf.h @@ -0,0 +1,263 @@ +/* ========================================================================== */ +/* === BTF package ========================================================== */ +/* ========================================================================== */ + +/* BTF_MAXTRANS: find a column permutation Q to give A*Q a zero-free diagonal + * BTF_STRONGCOMP: find a symmetric permutation P to put P*A*P' into block + * upper triangular form. + * BTF_ORDER: do both of the above (btf_maxtrans then btf_strongcomp). + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + + +/* ========================================================================== */ +/* === BTF_MAXTRANS ========================================================= */ +/* ========================================================================== */ + +/* BTF_MAXTRANS: finds a permutation of the columns of a matrix so that it has a + * zero-free diagonal. The input is an m-by-n sparse matrix in compressed + * column form. The array Ap of size n+1 gives the starting and ending + * positions of the columns in the array Ai. Ap[0] must be zero. The array Ai + * contains the row indices of the nonzeros of the matrix A, and is of size + * Ap[n]. The row indices of column j are located in Ai[Ap[j] ... Ap[j+1]-1]. + * Row indices must be in the range 0 to m-1. Duplicate entries may be present + * in any given column. The input matrix is not checked for validity (row + * indices out of the range 0 to m-1 will lead to an undeterminate result - + * possibly a core dump, for example). Row indices in any given column need + * not be in sorted order. However, if they are sorted and the matrix already + * has a zero-free diagonal, then the identity permutation is returned. + * + * The output of btf_maxtrans is an array Match of size n. If row i is matched + * with column j, then A(i,j) is nonzero, and then Match[i] = j. If the matrix + * is structurally nonsingular, all entries in the Match array are unique, and + * Match can be viewed as a column permutation if A is square. That is, column + * k of the original matrix becomes column Match[k] of the permuted matrix. In + * MATLAB, this can be expressed as (for non-structurally singular matrices): + * + * Match = maxtrans (A) ; + * B = A (:, Match) ; + * + * except of course here the A matrix and Match vector are all 0-based (rows + * and columns in the range 0 to n-1), not 1-based (rows/cols in range 1 to n). + * The MATLAB dmperm routine returns a row permutation. See the maxtrans + * mexFunction for more details. + * + * If row i is not matched to any column, then Match[i] is == -1. The + * btf_maxtrans routine returns the number of nonzeros on diagonal of the + * permuted matrix. + * + * In the MATLAB mexFunction interface to btf_maxtrans, 1 is added to the Match + * array to obtain a 1-based permutation. Thus, in MATLAB where A is m-by-n: + * + * q = maxtrans (A) ; % has entries in the range 0:n + * q % a column permutation (only if sprank(A)==n) + * B = A (:, q) ; % permuted matrix (only if sprank(A)==n) + * sum (q > 0) ; % same as "sprank (A)" + * + * This behaviour differs from p = dmperm (A) in MATLAB, which returns the + * matching as p(j)=i if row i and column j are matched, and p(j)=0 if column j + * is unmatched. + * + * p = dmperm (A) ; % has entries in the range 0:m + * p % a row permutation (only if sprank(A)==m) + * B = A (p, :) ; % permuted matrix (only if sprank(A)==m) + * sum (p > 0) ; % definition of sprank (A) + * + * This algorithm is based on the paper "On Algorithms for obtaining a maximum + * transversal" by Iain Duff, ACM Trans. Mathematical Software, vol 7, no. 1, + * pp. 315-330, and "Algorithm 575: Permutations for a zero-free diagonal", + * same issue, pp. 387-390. Algorithm 575 is MC21A in the Harwell Subroutine + * Library. This code is not merely a translation of the Fortran code into C. + * It is a completely new implementation of the basic underlying method (depth + * first search over a subgraph with nodes corresponding to columns matched so + * far, and cheap matching). This code was written with minimal observation of + * the MC21A/B code itself. See comments below for a comparison between the + * maxtrans and MC21A/B codes. + * + * This routine operates on a column-form matrix and produces a column + * permutation. MC21A uses a row-form matrix and produces a row permutation. + * The difference is merely one of convention in the comments and interpretation + * of the inputs and outputs. If you want a row permutation, simply pass a + * compressed-row sparse matrix to this routine and you will get a row + * permutation (just like MC21A). Similarly, you can pass a column-oriented + * matrix to MC21A and it will happily return a column permutation. + */ + +#ifndef _BTF_H +#define _BTF_H + +/* make it easy for C++ programs to include BTF */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "UFconfig.h" + +int btf_maxtrans /* returns # of columns matched */ +( + /* --- input, not modified: --- */ + int nrow, /* A is nrow-by-ncol in compressed column form */ + int ncol, + int Ap [ ], /* size ncol+1 */ + int Ai [ ], /* size nz = Ap [ncol] */ + double maxwork, /* maximum amount of work to do is maxwork*nnz(A); no limit + * if <= 0 */ + + /* --- output, not defined on input --- */ + double *work, /* work = -1 if maxwork > 0 and the total work performed + * reached the maximum of maxwork*nnz(A). + * Otherwise, work = the total work performed. */ + + int Match [ ], /* size nrow. Match [i] = j if column j matched to row i + * (see above for the singular-matrix case) */ + + /* --- workspace, not defined on input or output --- */ + int Work [ ] /* size 5*ncol */ +) ; + +/* long integer version (all "int" parameters become "UF_long") */ +UF_long btf_l_maxtrans (UF_long, UF_long, UF_long *, UF_long *, double, + double *, UF_long *, UF_long *) ; + + +/* ========================================================================== */ +/* === BTF_STRONGCOMP ======================================================= */ +/* ========================================================================== */ + +/* BTF_STRONGCOMP finds the strongly connected components of a graph, returning + * a symmetric permutation. The matrix A must be square, and is provided on + * input in compressed-column form (see BTF_MAXTRANS, above). The diagonal of + * the input matrix A (or A*Q if Q is provided on input) is ignored. + * + * If Q is not NULL on input, then the strongly connected components of A*Q are + * found. Q may be flagged on input, where Q[k] < 0 denotes a flagged column k. + * The permutation is j = BTF_UNFLIP (Q [k]). On output, Q is modified (the + * flags are preserved) so that P*A*Q is in block upper triangular form. + * + * If Q is NULL, then the permutation P is returned so that P*A*P' is in upper + * block triangular form. + * + * The vector R gives the block boundaries, where block b is in rows/columns + * R[b] to R[b+1]-1 of the permuted matrix, and where b ranges from 1 to the + * number of strongly connected components found. + */ + +int btf_strongcomp /* return # of strongly connected components */ +( + /* input, not modified: */ + int n, /* A is n-by-n in compressed column form */ + int Ap [ ], /* size n+1 */ + int Ai [ ], /* size nz = Ap [n] */ + + /* optional input, modified (if present) on output: */ + int Q [ ], /* size n, input column permutation */ + + /* output, not defined on input */ + int P [ ], /* size n. P [k] = j if row and column j are kth row/col + * in permuted matrix. */ + + int R [ ], /* size n+1. block b is in rows/cols R[b] ... R[b+1]-1 */ + + /* workspace, not defined on input or output */ + int Work [ ] /* size 4n */ +) ; + +UF_long btf_l_strongcomp (UF_long, UF_long *, UF_long *, UF_long *, UF_long *, + UF_long *, UF_long *) ; + + +/* ========================================================================== */ +/* === BTF_ORDER ============================================================ */ +/* ========================================================================== */ + +/* BTF_ORDER permutes a square matrix into upper block triangular form. It + * does this by first finding a maximum matching (or perhaps a limited matching + * if the work is limited), via the btf_maxtrans function. If a complete + * matching is not found, BTF_ORDER completes the permutation, but flags the + * columns of P*A*Q to denote which columns are not matched. If the matrix is + * structurally rank deficient, some of the entries on the diagonal of the + * permuted matrix will be zero. BTF_ORDER then calls btf_strongcomp to find + * the strongly-connected components. + * + * On output, P and Q are the row and column permutations, where i = P[k] if + * row i of A is the kth row of P*A*Q, and j = BTF_UNFLIP(Q[k]) if column j of + * A is the kth column of P*A*Q. If Q[k] < 0, then the (k,k)th entry in P*A*Q + * is structurally zero. + * + * The vector R gives the block boundaries, where block b is in rows/columns + * R[b] to R[b+1]-1 of the permuted matrix, and where b ranges from 1 to the + * number of strongly connected components found. + */ + +int btf_order /* returns number of blocks found */ +( + /* --- input, not modified: --- */ + int n, /* A is n-by-n in compressed column form */ + int Ap [ ], /* size n+1 */ + int Ai [ ], /* size nz = Ap [n] */ + double maxwork, /* do at most maxwork*nnz(A) work in the maximum + * transversal; no limit if <= 0 */ + + /* --- output, not defined on input --- */ + double *work, /* return value from btf_maxtrans */ + int P [ ], /* size n, row permutation */ + int Q [ ], /* size n, column permutation */ + int R [ ], /* size n+1. block b is in rows/cols R[b] ... R[b+1]-1 */ + int *nmatch, /* # nonzeros on diagonal of P*A*Q */ + + /* --- workspace, not defined on input or output --- */ + int Work [ ] /* size 5n */ +) ; + +UF_long btf_l_order (UF_long, UF_long *, UF_long *, double , double *, + UF_long *, UF_long *, UF_long *, UF_long *, UF_long *) ; + + +/* ========================================================================== */ +/* === BTF marking of singular columns ====================================== */ +/* ========================================================================== */ + +/* BTF_FLIP is a "negation about -1", and is used to mark an integer j + * that is normally non-negative. BTF_FLIP (-1) is -1. BTF_FLIP of + * a number > -1 is negative, and BTF_FLIP of a number < -1 is positive. + * BTF_FLIP (BTF_FLIP (j)) = j for all integers j. UNFLIP (j) acts + * like an "absolute value" operation, and is always >= -1. You can test + * whether or not an integer j is "flipped" with the BTF_ISFLIPPED (j) + * macro. + */ + +#define BTF_FLIP(j) (-(j)-2) +#define BTF_ISFLIPPED(j) ((j) < -1) +#define BTF_UNFLIP(j) ((BTF_ISFLIPPED (j)) ? BTF_FLIP (j) : (j)) + +/* ========================================================================== */ +/* === BTF version ========================================================== */ +/* ========================================================================== */ + +/* All versions of BTF include these definitions. + * As an example, to test if the version you are using is 1.2 or later: + * + * if (BTF_VERSION >= BTF_VERSION_CODE (1,2)) ... + * + * This also works during compile-time: + * + * #if (BTF >= BTF_VERSION_CODE (1,2)) + * printf ("This is version 1.2 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + */ + +#define BTF_DATE "Nov 1, 2007" +#define BTF_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define BTF_MAIN_VERSION 1 +#define BTF_SUB_VERSION 0 +#define BTF_SUBSUB_VERSION 1 +#define BTF_VERSION BTF_VERSION_CODE(BTF_MAIN_VERSION,BTF_SUB_VERSION) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OpenDSSC/klusolve/BTF/Include/btf_internal.h b/OpenDSSC/klusolve/BTF/Include/btf_internal.h new file mode 100644 index 0000000..83f76f1 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Include/btf_internal.h @@ -0,0 +1,64 @@ +/* ========================================================================== */ +/* === btf_internal include file ============================================ */ +/* ========================================================================== */ + +#ifndef _BTF_INTERNAL_H +#define _BTF_INTERNAL_H + +/* + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + +/* Not to be included in any user program. */ + +#ifdef DLONG +#define Int UF_long +#define Int_id UF_long_id +#define BTF(name) btf_l_ ## name +#else +#define Int int +#define Int_id "%d" +#define BTF(name) btf_ ## name +#endif + +/* ========================================================================== */ +/* make sure debugging and printing is turned off */ + +#ifndef NDEBUG +#define NDEBUG +#endif +#ifndef NPRINT +#define NPRINT +#endif + +/* To enable debugging and assertions, uncomment this line: + #undef NDEBUG +*/ +/* To enable diagnostic printing, uncomment this line: + #undef NPRINT +*/ + +/* ========================================================================== */ + +#include +#include +#define ASSERT(a) assert(a) + +#undef TRUE +#undef FALSE +#undef PRINTF +#undef MIN + +#ifndef NPRINT +#define PRINTF(s) { printf s ; } ; +#else +#define PRINTF(s) +#endif + +#define TRUE 1 +#define FALSE 0 +#define EMPTY (-1) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#endif diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Contents.m b/OpenDSSC/klusolve/BTF/MATLAB/Contents.m new file mode 100644 index 0000000..9b6e0bc --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Contents.m @@ -0,0 +1,20 @@ +% BTF ordering toolbox: +% +% Primary functions: +% +% btf - permute a square sparse matrix into upper block triangular form +% maxtrans - permute the columns of a sparse matrix so it has a zero-free diagonal +% strongcomp - symmetric permutation to upper block triangular form +% +% Other: +% btf_install - compile and install BTF for use in MATLAB. +% btf_demo - demo for BTF +% drawbtf - plot the BTF form of a matrix +% btf_make - compile BTF for use in MATLAB +% +% Example: +% q = maxtrans (A) +% [p,q,r] = btf (A) +% [p,r] = strongcomp (A) + +% Copyright 2004-2007, Tim Davis, University of Florida diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Makefile b/OpenDSSC/klusolve/BTF/MATLAB/Makefile new file mode 100644 index 0000000..7cb1bcf --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Makefile @@ -0,0 +1,37 @@ + +include ../../UFconfig/UFconfig.mk + +I = -I../Include -I../../UFconfig + +MX = $(MEX) $(I) -DDLONG + +all: maxtrans.mexglx strongcomp.mexglx btf.mexglx + +recursive: strongcomp_recursive.mexglx + +maxtrans.mexglx: ../Source/btf_maxtrans.c ../Include/btf.h maxtrans.c \ + ../Include/btf_internal.h + $(MX) maxtrans.c ../Source/btf_maxtrans.c + +strongcomp.mexglx: ../Source/btf_strongcomp.c ../Include/btf.h \ + strongcomp.c ../Include/btf_internal.h + $(MX) strongcomp.c ../Source/btf_strongcomp.c + +strongcomp_recursive.mexglx: ../Source/btf_strongcomp.c ../Include/btf.h \ + strongcomp.c ../Include/btf_internal.h + $(MX) -DRECURSIVE -output strongcomp_recursive \ + ../Source/btf_strongcomp.c strongcomp.c + +btf.mexglx: ../Source/btf_strongcomp.c ../Include/btf.h btf.c \ + ../Include/btf_internal.h \ + ../Source/btf_maxtrans.c ../Source/btf_order.c + $(MX) btf.c ../Source/btf_maxtrans.c \ + ../Source/btf_strongcomp.c ../Source/btf_order.c + +distclean: purge + +purge: clean + - $(RM) *.o *.mex* + +clean: + - $(RM) $(CLEAN) diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/btf_test.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/btf_test.m new file mode 100644 index 0000000..9def379 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/btf_test.m @@ -0,0 +1,19 @@ +function btf_test (nmat) +%BTF_TEST test for BTF +% Requires CSparse (or CXSparse) and UFget +% Example: +% btf_test +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5, test6. + +if (nargin < 1) + nmat = 800 ; +end + +test1 (nmat) ; +test2 (nmat) ; +test3 (nmat) ; +test4 (nmat) ; +test5 (nmat) ; +test6 ; + diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/checkbtf.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/checkbtf.m new file mode 100644 index 0000000..95bceca --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/checkbtf.m @@ -0,0 +1,46 @@ +function checkbtf (A, p, q, r) +%CHECKBTF ensure A(p,q) is in BTF form +% +% A(p,q) is in BTF form, r the block boundaries +% +% Example: +% [p,q,r] = dmperm (A) +% checkbtf (A, p, q, r) +% +% See also drawbtf, maxtrans, strongcomp. + +% Copyright 2007, Timothy A. Davis, University of Florida + +[m n] = size (A) ; +if (m ~= n) + error ('A must be square') ; +end + +if (any (sort (p) ~= 1:n)) + error ('p not a permutation') ; +end + +if (any (sort (q) ~= 1:n)) + error ('q not a permutation') ; +end + +nblocks = length (r) - 1 ; + +if (r (1) ~= 1) + error ('r(1) not one') ; +end + +if (r (end) ~= n+1) + error ('r(end) not n+1') ; +end + +if (nblocks < 1 | nblocks > n) %#ok + error ('nblocks wrong') ; +end + +nblocks = length (r) - 1 ; +rdiff = r (2:(nblocks+1)) - r (1:nblocks) ; +if (any (rdiff < 1) | any (rdiff > n)) %#ok + error ('r bad') +end + diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test1.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test1.m new file mode 100644 index 0000000..c44e9db --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test1.m @@ -0,0 +1,141 @@ +function test1 (nmat) +%TEST1 test for BTF +% Requires CSparse and UFget +% Example: +% test1 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, University of Florida + +index = UFget ; +% f = find (index.sprank < min (index.nrows, index.ncols)) ; +f = 1:length (index.nrows) ; + +% too much time: +skip = [1514 1297 1876 1301] ; + +f = setdiff (f, skip) ; + +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +if (nargin < 1) + nmat = 1000 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +T0 = zeros (nmat,1) ; +T1 = zeros (nmat,1) ; +Anz = zeros (nmat,1) ; +figure (1) ; +MN = zeros (nmat, 2) ; +Nzdiag = zeros (nmat,1) ; + +% warmup +p = maxtrans (sparse (1)) ; %#ok +p = cs_dmperm (sparse (1)) ; %#ok +a = cs_transpose (sparse (1)) ; %#ok + +h = waitbar (0, 'BTF test 1 of 6') ; + +try + + for k = 1:nmat + + Prob = UFget (f (k), index) ; + A = Prob.A ; + clear Prob + t = 0 ; + + waitbar (k/nmat, h) ; + + r = full (sum (spones (A), 2)) ; + c = full (sum (spones (A))) ; + m2 = length (find (r > 0)) ; + n2 = length (find (c > 0)) ; + + if (m2 < n2) + tic + A = cs_transpose (A) ; + t = toc ; + end + + Nzdiag (k) = nnz (diag (A)) ; + + [m n] = size (A) ; + Anz (k) = nnz (A) ; + MN (k,:) = [m n] ; + + tic + q = maxtrans (A) ; + t0 = toc ; + s0 = sum (q > 0) ; + T0 (k) = max (1e-9, t0) ; + + tic + p = cs_dmperm (A) ; + t1 = toc ; + s1 = sum (p > 0) ; + T1 (k) = max (1e-9, t1) ; + + fprintf (... + '%4d maxtrans %10.6f %10.6f cs_dmperm %10.6f m/n %8.2f', ... + f(k), t, t0, t1, m/n) ; + if (t1 ~= 0) + fprintf (' rel: %8.4f', t0 / t1) ; + end + fprintf ('\n') ; + if (s0 ~= s1) + error ('!') ; + end + + if (s0 == n & m == n) %#ok + B = A (:, q) ; + subplot (2,2,1) ; + cspy (B) ; + if (nnz (diag (B)) ~= n) + error ('?') + end + clear B + else + cspy (0) ; + end + + maxnz = nnz (A) ; + + zfree = find (MN (1:k,1) == MN (1:k,2) & Nzdiag (1:k) == MN(1:k,1)) ; + square = find (MN (1:k,1) == MN (1:k,2) & Nzdiag (1:k) ~= MN(1:k,1)) ; + tall = find (MN (1:k,1) > MN (1:k,2)) ; + squat = find (MN (1:k,1) < MN (1:k,2)) ; + + subplot (2,2,2) ; + loglog (Anz (square), T0 (square) ./ T1 (square), ... + 'o', [1 maxnz], [1 1], 'r-') ; + title ('square') ; + subplot (2,2,3) ; + loglog (Anz (tall), T0 (tall) ./ T1 (tall), ... + 'o', [1 maxnz], [1 1], 'r-') ; + title ('tall') ; + subplot (2,2,4) ; + title ('square, intially zero-free') ; + loglog (Anz (zfree), T0 (zfree) ./ T1 (zfree), ... + 'o', [1 maxnz], [1 1], 'r-') ; + title ('square, zero-free diag') ; + + drawnow + + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test2.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test2.m new file mode 100644 index 0000000..abcc3cd --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test2.m @@ -0,0 +1,109 @@ +function test2 (nmat) +%TEST2 test for BTF +% Requires CSparse and UFget +% Example: +% test2 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, University of Florida + +index = UFget ; +f = find (index.nrows == index.ncols) ; + +% too much time: +skip = [1514 1297 1876 1301] ; +f = setdiff (f, skip) ; + +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +if (nargin < 1) + nmat = 1000 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +T0 = zeros (nmat,1) ; +T1 = zeros (nmat,1) ; +Anz = zeros (nmat,1) ; +figure (1) ; +clf +MN = zeros (nmat, 2) ; +Nzdiag = zeros (nmat,1) ; + +% warmup +p = maxtrans (sparse (1)) ; %#ok +p = btf (sparse (1)) ; %#ok +p = cs_dmperm (sparse (1)) ; %#ok +a = cs_transpose (sparse (1)) ; %#ok + +h = waitbar (0, 'BTF test 2 of 6') ; + +try + for k = 1:nmat + + Prob = UFget (f (k), index) ; + A = Prob.A ; + + waitbar (k/nmat, h) ; + + Nzdiag (k) = nnz (diag (A)) ; + + [m n] = size (A) ; + Anz (k) = nnz (A) ; + MN (k,:) = [m n] ; + + tic + [p,q,r] = btf (A) ; + t0 = toc ; + s0 = sum (q > 0) ; + T0 (k) = max (1e-9, t0) ; + + tic + [p2,q2,r2] = cs_dmperm (A) ; + t1 = toc ; + s1 = sum (dmperm (A) > 0) ; + T1 (k) = max (1e-9, t1) ; + + fprintf ('%4d btf %10.6f cs_dmperm %10.6f', f(k), t0, t1) ; + if (t1 ~= 0) + fprintf (' rel: %8.4f', t0 / t1) ; + end + fprintf ('\n') ; + + if (s0 ~= s1) + error ('!') ; + end + + C = A (p, abs (q)) ; + subplot (1,2,1) ; + cspy (C) ; + z = find (q < 0) ; + zd = nnz (diag (C (z,z))) ; + if (zd > 0) + error ('?') ; + end + + minnz = Anz (1) ; + maxnz = nnz (A) ; + + subplot (1,2,2) ; + loglog (Anz (1:k), T0 (1:k) ./ T1 (1:k), ... + 'o', [minnz maxnz], [1 1], 'r-') ; + drawnow + + clear C A Prob + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test3.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test3.m new file mode 100644 index 0000000..40b236e --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test3.m @@ -0,0 +1,530 @@ +function test3 (nmat) +%TEST3 test for BTF +% Requires UFget +% Example: +% test3 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, Univ. of Florida + +doplot = 1 ; +dopause = 0 ; +dostrong = 1 ; + +index = UFget ; +f = find (index.nrows == index.ncols) ; +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; +clear i + +figure (1) + +% short test set: seg faults, lots of blocks, lots of work, and so on: +nasty = [ + % --- various test matrices (no seg fault, quick run time) + -(1:8)' % generated matrices + 904 % vanHeukelum/cage3 (5-by-5) + 819 % Simon/raefsky6 (permuted triangular matrix) + % + % --- older seg faults: + 264 % HB/west0156, causes older strongcomp_recursive to fail + 824 % TOKAMAK/utm300 (300-by-300), causes older code to fail + 868 % Pothen/bodyy4 + % + % --- seg faults in old MATLAB dmperm + 290 % Averous/epb3 + 983 % Sanghavi/ecl32 + 885 % Pothen/tandem_dual + 879 % Pothen/onera_dual + 955 % Schenk_IBMSDS/2D_54019_highK + 957 % Schenk_IBMSDS/3D_51448_3D + 958 % Schenk_IBMSDS/ibm_matrix_2 + 912 % vanHeukelum/cage11 + 924 % Andrews/Andrews + 960 % Schenk_IBMSDS/matrix-new_3 + 862 % Kim/kim1 + 544 % Hamm/scircuit + 897 % Norris/torso2 + 801 % Ronis/xenon1 + 53 % HB/bcsstk31 + 958 % Schenk_IBMSDS/matrix_9 + 844 % Cunningham/qa8fk + 845 % Cunningham/qa8fk + 821 % Simon/venkat25 + 822 % Simon/venkat50 + 820 % Simon/venkat01 + 812 % Simon/bbmat + 804 % Rothberg/cfd1 + 54 % HB/bcsstk32 + 913 % vanHeukelum/cage12 + 846 % Boeing/bcsstk39 + 972 % Schenk_IBMSDS/para-10 + 974 % Schenk_IBMSDS/para-5 + 975 % Schenk_IBMSDS/para-6 + 976 % Schenk_IBMSDS/para-7 + 977 % Schenk_IBMSDS/para-8 + 978 % Schenk_IBMSDS/para-9 + 961 % Schenk_ISEI/barrier2-10 + 962 % Schenk_ISEI/barrier2-11 + 963 % Schenk_ISEI/barrier2-12 + 964 % Schenk_ISEI/barrier2-1 + 965 % Schenk_ISEI/barrier2-2 + 966 % Schenk_ISEI/barrier2-3 + 967 % Schenk_ISEI/barrier2-4 + 968 % Schenk_ISEI/barrier2-9 + 851 % Chen/pkustk05 + 979 % Kamvar/Stanford + 374 % Bova/rma10 + % + % --- lots of time: + 395 % DRIVCAV/cavity16 + 396 % DRIVCAV/cavity17 + 397 % DRIVCAV/cavity18 + 398 % DRIVCAV/cavity19 + 399 % DRIVCAV/cavity20 + 400 % DRIVCAV/cavity21 + 401 % DRIVCAV/cavity22 + 402 % DRIVCAV/cavity23 + 403 % DRIVCAV/cavity24 + 404 % DRIVCAV/cavity25 + 405 % DRIVCAV/cavity26 + 1109 % Sandia/mult_dcop_01 + 1110 % Sandia/mult_dcop_02 + 1111 % Sandia/mult_dcop_03 + 376 % Brethour/coater2 + 284 % ATandT/onetone2 + 588 % Hollinger/mark3jac100 + 589 % Hollinger/mark3jac100sc + 452 % Grund/bayer01 + 920 % Hohn/sinc12 + 590 % Hollinger/mark3jac120 + 591 % Hollinger/mark3jac120sc + 809 % Shyy/shyy161 + 448 % Graham/graham1 + 283 % ATandT/onetone1 + 445 % Garon/garon2 + 541 % Hamm/bcircuit + 592 % Hollinger/mark3jac140 + 593 % Hollinger/mark3jac140sc + 435 % FIDAP/ex40 + 912 % Hohn/sinc15 + 894 % Norris/lung2 + 542 % Hamm/hcircuit + 752 % Mulvey/finan512 + 753 % Mulvey/pfinan512 + 564 % Hollinger/g7jac180 + 565 % Hollinger/g7jac180sc + 566 % Hollinger/g7jac200 + 567 % Hollinger/g7jac200sc + 748 % Mallya/lhr34 + 749 % Mallya/lhr34c + 922 % Hohn/sinc18 + 447 % Goodwin/rim + 807 % Rothberg/struct3 + 286 % ATandT/twotone + 982 % Tromble/language + 953 % Schenk_IBMNA/c-73 + 890 % Norris/heart1 + 750 % Mallya/lhr71 + 751 % Mallya/lhr71c + 925 % FEMLAB/ns3Da + 827 % Vavasis/av41092 + 931 % FEMLAB/sme3Db + 1297 % GHS_index/boyd2 + 1301 % GHS_indef/cont-300 + % + % --- lots of time, and seg faults: + 285 % ATandT/pre2 + % --- huge matrix, turn off plotting + 940 % Shenk/af_shell1, memory leak in plot, after call to btf, once. + % ---- +]' ; + +% maxtrans_recursive causes a seg fault on these matrices, because of +% stack overflow (this is expected) +skip_list_maxtrans_recursive = 285 ; + +% p = dmperm (A) in MATLAB 7.4 causes a seg fault on these matrices: +skip_list_dmperm = [285 1301 1231 1251 1232 1241] ; + +% [p,q,r] = dmperm (A) in MATLAB 7.4 causes a seg fault on these matrices: +skip_list_dmperm_btf = ... +[ 285 879 885 290 955 957 958 924 960 897 959 844 845 ... + 821 822 820 804 913 846 972 974:978 961:968 979 940 ... + 1422 1513 1412 1510 1301 1231 1251 1434 1213 1232 1241 1357 1579 1431 1281] ; +% length(skip_list_dmperm_btf) + +% time intensive +skip_costly = [1514 1297 1876 1301] ; + +% strongcomp (recursive) causes a seg fault on these matrices because of +% stack overflow (this is expected). +skip_list_strongcomp_recursive = ... +[983 285 879 885 290 955 957 958 912 924 960 862 544 897 801 53 959 844 845 ... + 821 822 820 812 804 54 913 846 972 974:978 961:968 851 374 940] ; +skip_list_strongcomp_recursive = ... +[ skip_list_strongcomp_recursive 592 593 752 753 807 286 982 855 566 567 ] ; + +% matrices with the largest # of nonzeros in the set (untested) +toobig = [ +928 853 852 356 761 368 973 895 805 849 932 ... +803 854 936 802 850 537 856 898 857 859 971 937 ... +914 858 980 896 806 538 863 369 938 860 941 942 ... +943 944 945 946 947 948 915 939 916 ] ; + +f = [ -(1:8) f ] ; +% f = nasty ; + +h = waitbar (0, 'BTF test 3 of 6') ; + +if (nargin < 1) + nmat = 1000 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +try + + for matnum = 1:nmat + + waitbar (matnum/nmat, h) ; + + j = f (matnum) ; + + if (any (j == toobig) | any (j == skip_costly)) %#ok + fprintf ('\n%4d: %3d %s/%s too big\n', ... + matnum, j, index.Group{j}, index.Name{j}) ; + continue ; + end + + rand ('state', 0) ; + + % clear all unused variables. + % nothing here is left that is proportional to the matrix size + clear A p1 p2 p3 q3 r3 match1 match2 match4 pa ra sa qa B C pb rb pc rc + clear jumble B11 B12 B13 B21 B22 B23 B31 B32 B33 pjumble qjumble ans + clear c kbad kgood + % whos + % pause + + if (j > 0) + Problem = UFget (j, index) ; + name = Problem.name ; + A = Problem.A ; + clear Problem + else + % construct the jth test matrix + j = -j ; + if (j == 1 | j == 2) %#ok + B11 = UFget ('Grund/b1_ss') ; % 7-by-7 diagonal block + B11 = B11.A ; + B12 = sparse (zeros (7,2)) ; + B12 (3,2) = 1 ; + B13 = sparse (ones (7,5)) ; + B21 = sparse (zeros (2,7)) ; + B22 = sparse (ones (2,2)) ; % 2-by-2 diagonal block + B23 = sparse (ones (2,5)) ; + B31 = sparse (zeros (5,7)) ; + B32 = sparse (zeros (5,2)) ; + B33 = UFget ('vanHeukelum/cage3') ; % 5-by-5 diagonal block + B33 = B33.A ; + A = [ B11 B12 B13 ; B21 B22 B23 ; B31 B32 B33 ] ; + name = '(j=1 test matrix)' ; + end + if (j == 2) + pjumble = [ 10 7 11 1 13 12 8 2 5 14 9 6 4 3 ] ; + qjumble = [ 3 14 2 11 1 8 5 7 10 12 4 13 9 6 ] ; + A = A (pjumble, qjumble) ; + name = '(j=2 test matrix)' ; + elseif (j == 3) + A = sparse (1) ; + elseif (j == 4) + A = sparse (0) ; + elseif (j == 5) + A = sparse (ones (2)) ; + elseif (j == 6) + A = sparse (2,2) ; + elseif (j == 7) + A = speye (2) ; + elseif (j == 8) + A = sparse (2,2) ; + A (2,1) = 1 ; + end + if (j > 2) + full (A) + end + end + + [m n] = size (A) ; + if (m ~= n) + continue ; + end + fprintf ('\n%4d: ', matnum) ; + fprintf (' =========================== Matrix: %3d %s\n', j, name) ; + fprintf ('n: %d nz: %d\n', n, nnz (A)) ; + + if (nnz (A) > 6e6) + doplot = 0 ; + end + + %----------------------------------------------------------------------- + % now try maxtrans + tic + match1 = maxtrans (A) ; + t = toc ; + s1 = sum (match1 > 0) ; + fprintf ('n-sprank: %d\n', n-s1) ; + fprintf ('maxtrans: %8.2f seconds\n', t) ; + singular = s1 < n ; + + if (doplot) + % figure (1) + clf + subplot (2,4,1) + spy (A) + title (name) ; + end + + p1 = match1 ; + if (any (p1 <= 0)) + % complete the permutation + badrow = find (p1 <= 0) ; + + badcol = ones (1,n) ; + badcol (p1 (p1 > 0)) = 0 ; + badcol = find (badcol) ; + + p1 (badrow) = badcol ; + + % construct the older form of match1 + match1 (badrow) = -p1 (badrow) ; + end + if (any (sort (p1) ~= 1:n)) + error ('!!') ; + end + + B = A (:,p1) ; + + if (doplot) + subplot (2,4,2) + hold off + spy (B) + hold on + badcol = find (match1 < 0) ; + Junk = sparse (badcol, badcol, ones (length (badcol), 1), n, n) ; + % if (~isempty (A)) + % spy (Junk, 'ro') ; + % end + title ('maxtrans') ; + end + + d = nnz (diag (B)) ; + if (d ~= s1) + error ('bad sprank') ; + end + clear B + + %----------------------------------------------------------------------- + % try p = dmperm(A) + skip_dmperm = any (j == skip_list_dmperm) ; + + if (~skip_dmperm) + tic + match4 = dmperm (A) ; + t = toc ; + fprintf ('p=dmperm(A): %8.2f seconds\n', t) ; + s4 = sum (match4 > 0) ; + singular4 = (s4 < n) ; + + if (doplot) + if (~singular4) + subplot (2,4,3) + spy (A (match4,:)) + title ('dmperm') ; + end + end + if (singular ~= singular4) + error ('s4?') ; + end + if (s1 ~= s4) + error ('bad sprank') ; + end + else + fprintf ('p=dmperm(A): skip\n') ; + end + + %----------------------------------------------------------------------- + nblocks = -1 ; + skip_dmperm_btf = any (j == skip_list_dmperm_btf) ; + if (~skip_dmperm_btf) + % get btf form + tic + [pa,qa,ra,sa] = dmperm (A) ; + t = toc ; + fprintf ('[p,q,r,s]=dmperm(A): %8.2f seconds\n', t) ; + nblocks = length (ra) - 1 ; + fprintf ('nblocks: %d\n', nblocks) ; + if (~singular4) + checkbtf (A, pa, qa, ra) ; + if (doplot) + subplot (2,4,4) + drawbtf (A, pa, qa, ra) + title ('dmperm blocks') + end + end + else + fprintf ('[p,q,r,s]=dmperm(A): skip\n') ; + end + + jumble = randperm (n) ; + + %----------------------------------------------------------------------- + % try strongcomp, non-recursive version + + %------------------------------------------------------------------- + % try strongcomp on original matrix + B = A (:,p1) ; + tic ; + [pb,rb] = strongcomp (B) ; + t = toc ; + fprintf ('strongcomp %8.2f seconds\n', t) ; + if (~singular & ~skip_dmperm_btf & (length (rb) ~= nblocks+1)) %#ok + error ('BTF:invalid (rb)') ; + end + checkbtf (B, pb, pb, rb) ; + if (doplot) + subplot (2,4,5) + drawbtf (B, pb, pb, rb) ; + title ('strongcomp') ; + end + + %------------------------------------------------------------------- + % try btf on original matrix + tic ; + [pw,qw,rw] = btf (A) ; + t = toc ; + fprintf ('btf %8.2f seconds nblocks %d\n', ... + t, length (rw)-1) ; + + if (any (pw ~= pb)) + error ('pw') ; + end + if (any (rw ~= rb)) + error ('rw') ; + end + if (any (abs (qw) ~= p1 (pw))) + error ('qw') ; + end + c = diag (A (pw,abs (qw))) ; + if (~singular & ~skip_dmperm_btf & (length (rw) ~= nblocks+1)) %#ok + error ('BTF:invalid (rw)') ; + end + checkbtf (A, pw, abs (qw), rw) ; + + kbad = find (qw < 0) ; + kgood = find (qw > 0) ; + if (any (c (kbad) ~= 0)) + error ('kbad') ; + end + if (any (c (kgood) == 0)) %#ok + error ('kgood') ; + end + + if (doplot) + subplot (2,4,6) + drawbtf (A, pw, abs (qw), rw) ; + if (n < 500) + for k = kbad + plot ([k (k+1) (k+1) k k]-.5, ... + [k k (k+1) (k+1) k]-.5, 'r') ; + end + end + title ('btf') ; + end + + %------------------------------------------------------------------- + % try [p,q,r] = strongcomp (A, qin) form + tic + [pz,qz,rz] = strongcomp (A, match1) ; + t = toc ; + fprintf ('[p,q,r]=strongcomp(A,qin)%8.2f seconds\n', t) ; + if (any (pz ~= pb)) + error ('pz') ; + end + if (any (rz ~= rb)) + error ('rz') ; + end + if (any (abs (qz) ~= p1 (pz))) + error ('qz') ; + end + c = diag (A (pz,abs (qz))) ; + if (~singular & ~skip_dmperm_btf & (length (rz) ~= nblocks+1)) %#ok + error ('BTF:invalid (rz)') ; + end + checkbtf (A, pz, abs (qz), rz) ; + + kbad = find (qz < 0) ; + kgood = find (qz > 0) ; + if (any (c (kbad) ~= 0)) + error ('kbad') ; + end + if (any (c (kgood) == 0)) %#ok + error ('kgood') ; + end + + if (doplot) + subplot (2,4,7) + drawbtf (A, pz, abs (qz), rz) ; + if (n < 500) + for k = kbad + plot ([k (k+1) (k+1) k k]-.5, ... + [k k (k+1) (k+1) k]-.5, 'r') ; + end + end + title ('strongcomp(A,qin)') ; + end + + %------------------------------------------------------------------- + % try strongcomp again, on a randomly jumbled matrix + C = sparse (B (jumble, jumble)) ; + tic ; + [pc,rc] = strongcomp (C) ; + t = toc ; + fprintf ('strongcomp (rand) %8.2f seconds\n', t) ; + if (~singular & ~skip_dmperm_btf & (length (rc) ~= nblocks+1)) %#ok + error ('BTF:invalid (rc)') ; + end + checkbtf (C, pc, pc, rc) ; + if (doplot) + subplot (2,4,8) + drawbtf (C, pc, pc, rc) ; + title ('strongcomp(rand)') ; + end + + if (length (rc) ~= length (rb)) + error ('strongcomp random mismatch') ; + end + + %----------------------------------------------------------------------- + if (doplot) + drawnow + end + + if (matnum ~= nmat & dopause) %#ok + input ('Hit enter: ') ; + end + + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test4.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test4.m new file mode 100644 index 0000000..4e82083 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test4.m @@ -0,0 +1,86 @@ +function test4 (nmat) +%TEST4 test for BTF +% Requires UFget +% Example: +% test4 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, University of Florida + +index = UFget ; +f = find (index.nrows == index.ncols) ; +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +% time intensive +skip_costly = [1514 1297 1876 1301] ; +f = setdiff (f, skip_costly) ; + +if (nargin < 1) + nmat = 1000 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +h = waitbar (0, 'BTF test 4 of 6') ; + +try + for k = 1:nmat + + Prob = UFget (f (k), index) ; + A = Prob.A ; + + waitbar (k/nmat, h) ; + + for tr = [1 -1] + + if (tr == -1) + AT = A' ; + [m n] = size (A) ; + if (m == n) + if (nnz (spones (AT) - spones (A)) == 0) + fprintf ('skip transpose\n') ; + continue ; + end + end + A = AT ; + end + + tic + [p1,q1,r1,work1] = btf (A) ; + t1 = toc ; + n1 = length (r1) - 1 ; + + tic + [p2,q2,r2,work2] = btf (A, 10) ; + t2 = toc ; + n2 = length (r2) - 1 ; + + fprintf (... + '%4d %4d : %10.4f %8d %8g : %10.4f %8d %8g :', ... + k, f(k), t1, n1, work1, t2, n2, work2) ; + if (t2 ~= 0) + fprintf (' rel %8.4f %8.4f' , t1 / t2, n2 / (max (1, n1))) ; + end + fprintf ('\n') ; + + if (n1 ~= n2 | work1 ~= work2) %#ok + disp (Prob) ; + fprintf ('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n') ; + end + + end + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test5.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test5.m new file mode 100644 index 0000000..97358ac --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test5.m @@ -0,0 +1,86 @@ +function test5 (nmat) +%TEST5 test for BTF +% Requires UFget +% Example: +% test5 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, University of Florida + +index = UFget ; + +[ignore f] = sort (index.nnz) ; + +% time intensive +skip_costly = [1514 1297 1876 1301] ; +f = setdiff (f, skip_costly) ; + +if (nargin < 1) + nmat = 1000 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +h = waitbar (0, 'BTF test 5 of 6') ; + +try + for k = 1:nmat + + i = f(k) ; + Prob = UFget (i, index) ; + A = Prob.A ; + + waitbar (k/nmat, h) ; + + for tr = [1 -1] + + if (tr == -1) + AT = A' ; + [m n] = size (A) ; + if (m == n) + if (nnz (spones (AT) - spones (A)) == 0) + fprintf ('skip test with transpose\n') ; + continue ; + end + end + A = AT ; + end + + tic + q1 = maxtrans (A) ; + t1 = toc ; + r1 = sum (q1 > 0) ; + + tic + q2 = maxtrans (A, 10) ; + t2 = toc ; + r2 = sum (q2 > 0) ; + + fprintf (... + '%4d %4d : %10.4f %8d : %10.4f %8d', k, f(k), t1, r1, t2, r2) ; + fprintf (' rel sprank %8.4f', r2 / (max (1, r1))) ; + if (t2 ~= 0) + fprintf (': rel time %8.4f', t1 / t2) ; + end + fprintf ('\n') ; + + if (r1 ~= r2) + disp (Prob) ; + fprintf ('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n') ; + end + + end + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/Test/test6.m b/OpenDSSC/klusolve/BTF/MATLAB/Test/test6.m new file mode 100644 index 0000000..c27ca82 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/Test/test6.m @@ -0,0 +1,138 @@ +function test6 +%TEST6 test for BTF +% Requires UFget +% Example: +% test6 +% See also btf, maxtrans, strongcomp, dmperm, UFget, +% test1, test2, test3, test4, test5. + +% Copyright 2007, Timothy A. Davis, University of Florida + +quick2 = [ ... + 1522 -272 1463 1521 460 1507 -838 1533 -1533 -1456 -1512 734 211 ... + -385 -735 394 -397 1109 -744 ... + -734 -375 -1200 -1536 -837 519 -519 520 -520 189 -189 454 385 ... + 387 -387 384 -384 386 -386 388 -388 525 -525 526 -526 735 ... + 1508 209 210 1243 -1243 1534 -840 1234 -1234 390 -390 392 -392 ... + -394 1472 1242 -1242 389 -389 391 -391 393 -393 1215 -1215 1216 ... +-1216 736 -736 737 -737 455 -455 -224 -839 1426 -1426 -1473 396 ... + -396 398 -398 400 -400 402 -402 404 -404 -1531 395 -395 397 ... + 399 -399 401 -401 403 -403 405 -405 -738 -739 1459 -1459 1111 ... + 1110 376 -376 284 -284 -740 -742 -741 -743 1293 -1293 452 920 ... + -745 -446 1462 -1461 448 -448 283 -283 1502 -1502 1292 -1292 1503 ... +-1503 1291 -1291 445 -445 -746 -747 1300 -1300 435 -435 -1343 -1345 ... +-1344 1305 -1305 921 -1513 1307 -1307 1369 -1369 1374 -1374 1377 ... +-1377 748 -748 -749 1510 922 -922 ] ; + +index = UFget ; +nmat = length (quick2) ; +dopause = 0 ; + +h = waitbar (0, 'BTF test 6 of 6') ; + +try + + for k = 1:nmat + + waitbar (k/nmat, h) ; + + i = quick2 (k) ; + Prob = UFget (abs (i), index) ; + disp (Prob) ; + if (i < 0) + fprintf ('transposed\n') ; + A = Prob.A' ; + [m n] = size (A) ; + if (m == n) + if (nnz (spones (A) - spones (Prob.A)) == 0) + fprintf ('skip...\n') ; + continue ; + end + end + else + A = Prob.A ; + end + + tic + [p1,q1,r1,work1] = btf (A) ; + t1 = toc ; + n1 = length (r1) - 1 ; + m1 = nnz (diag (A (p1, abs (q1)))) ; + + limit = work1/nnz(A) ; + + fprintf ('full search: %g * nnz(A)\n', limit) ; + + works = linspace(0,limit,9) ; + works (1) = eps ; + nw = length (works) ; + + T2 = zeros (nw, 1) ; + N2 = zeros (nw, 1) ; + M2 = zeros (nw, 1) ; + + T2 (end) = t1 ; + N2 (end) = n1 ; + M2 (end) = m1 ; + + fprintf ('full time %10.4f blocks %8d nnz(diag) %8d\n\n', t1, n1, m1) ; + + subplot (3,4,4) ; + drawbtf (A, p1, abs (q1), r1) ; + title (Prob.name, 'Interpreter', 'none') ; + + for j = 1:nw-1 + + maxwork = works (j) ; + + tic + [p2,q2,r2,work2] = btf (A, maxwork) ; + t2 = toc ; + n2 = length (r2) - 1 ; + m2 = nnz (diag (A (p2, abs (q2)))) ; + T2 (j) = t2 ; + N2 (j) = n2 ; + M2 (j) = m2 ; + + fprintf ('%9.1f %10.4f blocks %8d nnz(diag) %8d\n', ... + maxwork, t2, n2, m2) ; + + subplot (3,4,4+j) ; + drawbtf (A, p2, abs (q2), r2) ; + title (sprintf ('%g', maxwork)) ; + + ss = [1:j nw] ; + + subplot (3,4,1) ; + plot (works(ss), T2(ss), 'o-') ; title ('time vs work') ; + axis ([0 limit 0 max(0.1,max(T2))]) ; + + subplot (3,4,2) ; + plot (works(ss), N2(ss), 'o-') ; title ('blocks vs work') ; + axis ([0 limit 0 n1]) ; + + subplot (3,4,3) ; + plot (works(ss), M2(ss), 'o-') ; title ('nnz(diag) vs work') ; + axis ([0 limit 0 m1]) ; + drawnow + + end + fprintf ('full time %10.4f blocks %8d nnz(diag) %8d\n', t1, n1, m1) ; + + if (dopause) + input ('hit enter: ') ; + end + + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/btf.c b/OpenDSSC/klusolve/BTF/MATLAB/btf.c new file mode 100644 index 0000000..79d1ba2 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/btf.c @@ -0,0 +1,144 @@ +/* ========================================================================== */ +/* === btf mexFunction ====================================================== */ +/* ========================================================================== */ + +/* BTF: Permute a square matrix to upper block triangular form with a zero-free + * diagonal, or with a maximum number of nonzeros along the diagonal if a + * zero-free permutation does not exist. + * + * Usage: + * + * [p,q,r] = btf (A) ; + * [p,q,r] = btf (A, maxwork) ; + * + * If the matrix has structural full rank, this is essentially identical to + * + * [p,q,r] = dmperm (A) + * + * except that p, q, and r will differ in trivial ways. Both return an upper + * block triangular form with a zero-free diagonal, if the matrix is + * structurally non-singular. The number and sizes of the blocks will be + * identical, but the order of the blocks, and the ordering within the blocks, + * can be different. + * + * If the matrix is structurally singular, q will contain negative entries. + * The permuted matrix is C = A(p,abs(q)), and find(q<0) gives a list of + * indices of the diagonal of C that are equal to zero. This differs from + * dmperm, which does not place the maximum matching along the main diagonal + * of C=A(p,q), but places it above the diagonal instead. + * + * See maxtrans, or btf.m, for a description of maxwork. + * + * An optional fourth output [p,q,r,work] = btf (...) returns the amount of + * work performed, or -1 if the maximum work limit is reached (in which case + * the maximum matching might not have been found). + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + * + * See also maxtrans, strongcomp, dmperm + */ + +/* ========================================================================== */ + +#include "mex.h" +#include "btf.h" + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double work, maxwork ; + UF_long b, n, k, *Ap, *Ai, *P, *R, nblocks, *Work, *Q, nmatch ; + double *Px, *Rx, *Qx, *w ; + + /* ---------------------------------------------------------------------- */ + /* get inputs and allocate workspace */ + /* ---------------------------------------------------------------------- */ + + if (nargin < 1 || nargin > 2 || nargout > 4) + { + mexErrMsgTxt ("Usage: [p,q,r] = btf (A)") ; + } + n = mxGetM (pargin [0]) ; + if (!mxIsSparse (pargin [0]) || n != mxGetN (pargin [0])) + { + mexErrMsgTxt ("btf: A must be sparse, square, and non-empty") ; + } + + /* get sparse matrix A */ + Ap = (UF_long *) mxGetJc (pargin [0]) ; + Ai = (UF_long *) mxGetIr (pargin [0]) ; + + /* get output arrays */ + Q = mxMalloc (n * sizeof (UF_long)) ; + P = mxMalloc (n * sizeof (UF_long)) ; + R = mxMalloc ((n+1) * sizeof (UF_long)) ; + + /* get workspace */ + Work = mxMalloc (5*n * sizeof (UF_long)) ; + + maxwork = 0 ; + if (nargin > 1) + { + maxwork = mxGetScalar (pargin [1]) ; + } + work = 0 ; + + /* ---------------------------------------------------------------------- */ + /* find the permutation to BTF */ + /* ---------------------------------------------------------------------- */ + + nblocks = btf_l_order (n, Ap, Ai, maxwork, &work, P, Q, R, &nmatch, Work) ; + + /* ---------------------------------------------------------------------- */ + /* create outputs and free workspace */ + /* ---------------------------------------------------------------------- */ + + /* create P */ + pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; + Px = mxGetPr (pargout [0]) ; + for (k = 0 ; k < n ; k++) + { + Px [k] = P [k] + 1 ; /* convert to 1-based */ + } + + /* create Q */ + if (nargout > 1) + { + pargout [1] = mxCreateDoubleMatrix (1, n, mxREAL) ; + Qx = mxGetPr (pargout [1]) ; + for (k = 0 ; k < n ; k++) + { + Qx [k] = Q [k] + 1 ; /* convert to 1-based */ + } + } + + /* create R */ + if (nargout > 2) + { + pargout [2] = mxCreateDoubleMatrix (1, nblocks+1, mxREAL) ; + Rx = mxGetPr (pargout [2]) ; + for (b = 0 ; b <= nblocks ; b++) + { + Rx [b] = R [b] + 1 ; /* convert to 1-based */ + } + } + + /* create work output */ + if (nargout > 3) + { + pargout [3] = mxCreateDoubleMatrix (1, 1, mxREAL) ; + w = mxGetPr (pargout [3]) ; + w [0] = work ; + } + + mxFree (P) ; + mxFree (R) ; + mxFree (Work) ; + mxFree (Q) ; +} diff --git a/OpenDSSC/klusolve/BTF/MATLAB/btf.m b/OpenDSSC/klusolve/BTF/MATLAB/btf.m new file mode 100644 index 0000000..14d7ac4 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/btf.m @@ -0,0 +1,38 @@ +function [p,q,r] = btf (A) %#ok +%BTF permute a square sparse matrix into upper block triangular form +% with a zero-free diagonal, or with a maximum number of nonzeros along the +% diagonal if a zero-free permutation does not exist. +% +% Example: +% [p,q,r] = btf (A) ; +% [p,q,r] = btf (A,maxwork) ; +% +% If the matrix has structural full rank, this is essentially identical to +% +% [p,q,r] = dmperm (A) +% +% except that p, q, and r will differ in trivial ways. Both return an upper +% block triangular form with a zero-free diagonal, if the matrix is +% structurally non-singular. The number and sizes of the blocks will be +% identical, but the order of the blocks, and the ordering within the blocks, +% can be different. +% +% If the matrix is structurally singular, the q from btf will contain negative +% entries. The permuted matrix is C = A(p,abs(q)), and find(q<0) gives a list +% of indices of the diagonal of C that are equal to zero. This differs from +% dmperm, which does not place the maximum matching along the main diagonal +% of C=A(p,q), but places it above the diagonal instead. +% +% The second input limits the maximum amount of work the function does to +% be maxwork*nnz(A), or no limit at all if maxwork <= 0. If the function +% terminates early as a result, a maximum matching may not be found, and the +% diagonal of A(p,abs(q)) might not have the maximum number of nonzeros +% possible. Also, the number of blocks (length(r)-1) may be larger than +% what btf(A) or dmperm(A) would compute. +% +% See also maxtrans, strongcomp, dmperm, sprank + +% Copyright 2004-2007, Tim Davis, University of Florida +% with support from Sandia National Laboratories. All Rights Reserved. + +error ('btf mexFunction not found') ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/btf_demo.m b/OpenDSSC/klusolve/BTF/MATLAB/btf_demo.m new file mode 100644 index 0000000..8f2e7d4 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/btf_demo.m @@ -0,0 +1,48 @@ +%BTF_DEMO demo for BTF +% +% Example: +% btf_demo +% +% See also btf, dmperm, strongcomp, maxtrans + +% Copyright 2004-2007, Tim Davis, University of Florida + +load west0479 ; +A = west0479 ; + +figure (1) +clf + +subplot (2,3,1) ; +spy (A) +title ('west0479') ; + +subplot (2,3,2) ; +[p, q, r] = btf (A) ; +% spy (A (p, abs(q))) ; +drawbtf (A, p, q, r) ; +title ('btf') ; + +fprintf ('\nbtf_demo: n %d nnz(A) %d # of blocks %d\n', ... + size (A,1), nnz (A), length (r) - 1) ; + +subplot (2,3,3) ; +[p, q, r, s] = dmperm (A) ; +drawbtf (A, p, q, r) ; +title ('dmperm btf') + +subplot (2,3,4) ; +[p, r] = strongcomp (A) ; +% spy (A (p, abs(q))) ; +drawbtf (A, p, p, r) ; +title ('strongly conn. comp.') ; + +subplot (2,3,5) ; +q = maxtrans (A) ; +spy (A (:,q)) +title ('max transversal') ; + +subplot (2,3,6) ; +p = dmperm (A) ; +spy (A (p,:)) +title ('dmperm maxtrans') ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/btf_install.m b/OpenDSSC/klusolve/BTF/MATLAB/btf_install.m new file mode 100644 index 0000000..4507c6b --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/btf_install.m @@ -0,0 +1,17 @@ +function btf_install +%BTF_INSTALL compile and install BTF for use in MATLAB. +% Your current working directory must be BTF/MATLAB for this function to work. +% +% Example: +% btf_install +% +% See also btf, maxtrans, stroncomp, dmperm. + +% Copyright 2004-2007, Tim Davis, University of Florida + +btf_make +addpath (pwd) ; +fprintf ('BTF has been compiled and installed. The path:\n') ; +disp (pwd) ; +fprintf ('has been added to your path. Use pathtool to add it permanently.\n'); +btf_demo diff --git a/OpenDSSC/klusolve/BTF/MATLAB/btf_make.m b/OpenDSSC/klusolve/BTF/MATLAB/btf_make.m new file mode 100644 index 0000000..a0c105d --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/btf_make.m @@ -0,0 +1,37 @@ +function btf_make +%BTF_MAKE compile BTF for use in MATLAB +% Your current working directory must be BTF/MATLAB for this function to work. +% +% Example: +% btf_make +% +% See also btf, maxtrans, stroncomp, dmperm. + +% Copyright 2004-2007, Tim Davis, University of Florida + +details = 0 ; % if 1, print details of each command + +mexcmd = 'mex -O -DDLONG -I../Include -I../../UFconfig ' ; +if (~isempty (strfind (computer, '64'))) + mexcmd = [mexcmd '-largeArrayDims '] ; +end + +s = [mexcmd 'maxtrans.c ../Source/btf_maxtrans.c'] ; +if (details) + fprintf ('%s\n', s) ; +end +eval (s) ; + +s = [mexcmd 'strongcomp.c ../Source/btf_strongcomp.c'] ; +if (details) + fprintf ('%s\n', s) ; +end +eval (s) ; + +s = [mexcmd 'btf.c ../Source/btf_maxtrans.c ../Source/btf_strongcomp.c ../Source/btf_order.c'] ; +if (details) + fprintf ('%s\n', s) ; +end +eval (s) ; + +fprintf ('BTF successfully compiled.\n') ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/drawbtf.m b/OpenDSSC/klusolve/BTF/MATLAB/drawbtf.m new file mode 100644 index 0000000..55725b9 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/drawbtf.m @@ -0,0 +1,27 @@ +function drawbtf (A, p, q, r) +%DRAWBTF plot the BTF form of a matrix +% +% A(p,q) is in BTF form, r the block boundaries +% +% Example: +% [p,q,r] = dmperm (A) +% drawbtf (A, p, q, r) +% +% See also btf, maxtrans, strongcomp, dmperm. + +% Copyright 2004-2007, Tim Davis, University of Florida + +nblocks = length (r) - 1 ; + +hold off +spy (A (p,abs(q))) +hold on + +for k = 1:nblocks + k1 = r (k) ; + k2 = r (k+1) ; + nk = k2 - k1 ; + if (nk > 1) + plot ([k1 k2 k2 k1 k1]-.5, [k1 k1 k2 k2 k1]-.5, 'r') ; + end +end diff --git a/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.c b/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.c new file mode 100644 index 0000000..f89c2e8 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.c @@ -0,0 +1,101 @@ +/* ========================================================================== */ +/* === maxtrans mexFunction ================================================= */ +/* ========================================================================== */ + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* MAXTRANS: Find a column permutation for a zero-free diagonal. + * + * Usage: + * + * q = maxtrans (A) ; + * q = maxtrans (A,maxwork) ; + * + * A (:,q) has a zero-free diagonal if sprank(A) == n. + * If the matrix is structurally singular, q will contain zeros. Similar + * to p = dmperm (A), except that dmperm returns a row permutation. + * + * An optional second output [q,work] = maxtrans (...) returns the amount of + * work performed, or -1 if the maximum work limit is reached (in which case + * the maximum matching might not have been found). + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + +/* ========================================================================== */ + +#include "mex.h" +#include "btf.h" + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double maxwork, work ; + UF_long nrow, ncol, i, *Ap, *Ai, *Match, nmatch, *Work ; + double *Matchx, *w ; + + /* ---------------------------------------------------------------------- */ + /* get inputs and allocate workspace */ + /* ---------------------------------------------------------------------- */ + + if (nargin < 1 || nargin > 2 || nargout > 2) + { + mexErrMsgTxt ("Usage: q = maxtrans (A)") ; + } + nrow = mxGetM (pargin [0]) ; + ncol = mxGetN (pargin [0]) ; + if (!mxIsSparse (pargin [0])) + { + mexErrMsgTxt ("maxtrans: A must be sparse, and non-empty") ; + } + + /* get sparse matrix A */ + Ap = (UF_long *) mxGetJc (pargin [0]) ; + Ai = (UF_long *) mxGetIr (pargin [0]) ; + + /* get output array */ + Match = mxMalloc (nrow * sizeof (UF_long)) ; + + /* get workspace of size 5n (recursive version needs only 2n) */ + Work = mxMalloc (5*ncol * sizeof (UF_long)) ; + + maxwork = 0 ; + if (nargin > 1) + { + maxwork = mxGetScalar (pargin [1]) ; + } + work = 0 ; + + /* ---------------------------------------------------------------------- */ + /* perform the maximum transversal */ + /* ---------------------------------------------------------------------- */ + + nmatch = btf_l_maxtrans (nrow, ncol, Ap, Ai, maxwork, &work, Match, Work) ; + + /* ---------------------------------------------------------------------- */ + /* create outputs and free workspace */ + /* ---------------------------------------------------------------------- */ + + pargout [0] = mxCreateDoubleMatrix (1, nrow, mxREAL) ; + Matchx = mxGetPr (pargout [0]) ; + for (i = 0 ; i < nrow ; i++) + { + Matchx [i] = Match [i] + 1 ; /* convert to 1-based */ + } + + if (nargout > 1) + { + pargout [1] = mxCreateDoubleMatrix (1, 1, mxREAL) ; + w = mxGetPr (pargout [1]) ; + w [0] = work ; + } + + mxFree (Work) ; + mxFree (Match) ; +} diff --git a/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.m b/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.m new file mode 100644 index 0000000..1fad193 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/maxtrans.m @@ -0,0 +1,30 @@ +function q = maxtrans (A) %#ok +%MAXTRANS permute the columns of a sparse matrix so it has a zero-free diagonal +% (if it exists). If no zero-free diagonal exists, then a maximum matching is +% found. Note that this differs from p=dmperm(A), which returns a row +% permutation. +% +% Example: +% q = maxtrans (A) +% q = maxtrans (A,maxwork) +% +% If row i and column j are matched, then q(i) = j. Otherwise, if row is +% unmatched, then q(i) = 0. This is similar to dmperm, except that +% p = dmperm(A) returns p(j)=i if row i and column j are matched, or p(j)=0 if +% column j is unmatched. +% +% If A is structurally nonsingular, then A(:,maxtrans(A)) has a zero-free +% diagonal, as does A (dmperm(A),:). +% +% The second input limits the maximum amount of work the function does +% (excluding the O(nnz(A)) cheap match phase) to be maxwork*nnz(A), or no limit +% at all if maxwork <= 0. If the function terminates early as a result, a +% maximum matching may not be found. An optional second output +% [q,work] = maxtrans (...) returns the amount of work performed, or -1 if the +% maximum work limit is reached. +% +% See also: btf, strongcomp, dmperm, sprank + +% Copyright 2004-2007, Tim Davis, University of Florida + +error ('maxtrans mexfunction not found') ; diff --git a/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.c b/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.c new file mode 100644 index 0000000..16d7dc3 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.c @@ -0,0 +1,179 @@ +/* ========================================================================== */ +/* === stongcomp mexFunction ================================================ */ +/* ========================================================================== */ + +/* STRONGCOMP: Find a symmetric permutation to upper block triangular form of + * a sparse square matrix. + * + * Usage: + * + * [p,r] = strongcomp (A) ; + * + * [p,q,r] = strongcomp (A,qin) ; + * + * In the first usage, the permuted matrix is C = A (p,p). In the second usage, + * the matrix A (:,qin) is symmetrically permuted to upper block triangular + * form, where qin is an input column permutation, and the final permuted + * matrix is C = A (p,q). This second usage is equivalent to + * + * [p,r] = strongcomp (A (:,qin)) ; + * q = qin (p) ; + * + * That is, if qin is not present it is assumed to be qin = 1:n. + * + * C is the permuted matrix, with a number of blocks equal to length(r)-1. + * The kth block is from row/col r(k) to row/col r(k+1)-1 of C. + * r(1) is one and the last entry in r is equal to n+1. + * The diagonal of A (or A (:,qin)) is ignored. + * + * strongcomp is normally proceeded by a maximum transversal: + * + * [p,q,r] = strongcomp (A, maxtrans (A)) + * + * if the matrix has full structural rank. This is identical to + * + * [p,q,r] = btf (A) + * + * (except that btf handles the case when A is structurally rank-deficient). + * It essentially the same as + * + * [p,q,r] = dmperm (A) + * + * except that p, q, and r will differ between btf and dmperm. Both return an + * upper block triangular form with a zero-free diagonal. The number and sizes + * of the blocks will be identical, but the order of the blocks, and the + * ordering within the blocks, can be different. For structurally rank + * deficient matrices, dmpmerm returns the maximum matching as a zero-free + * diagonal that is above the main diagonal; btf always returns the matching as + * the main diagonal (which will thus contain zeros). + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + * + * See also maxtrans, btf, dmperm + */ + +/* ========================================================================== */ + +#include "mex.h" +#include "btf.h" + +void mexFunction +( + int nargout, + mxArray *pargout[], + int nargin, + const mxArray *pargin[] +) +{ + UF_long b, n, i, k, j, *Ap, *Ai, *P, *R, nblocks, *Work, *Q, jj ; + double *Px, *Rx, *Qx ; + + /* ---------------------------------------------------------------------- */ + /* get inputs and allocate workspace */ + /* ---------------------------------------------------------------------- */ + + if (!((nargin == 1 && nargout <= 2) || (nargin == 2 && nargout <= 3))) + { + mexErrMsgTxt ("Usage: [p,r] = strongcomp (A)" + " or [p,q,r] = strongcomp (A,qin)") ; + } + n = mxGetM (pargin [0]) ; + if (!mxIsSparse (pargin [0]) || n != mxGetN (pargin [0])) + { + mexErrMsgTxt ("strongcomp: A must be sparse, square, and non-empty") ; + } + + /* get sparse matrix A */ + Ap = (UF_long *) mxGetJc (pargin [0]) ; + Ai = (UF_long *) mxGetIr (pargin [0]) ; + + /* get output arrays */ + P = mxMalloc (n * sizeof (UF_long)) ; + R = mxMalloc ((n+1) * sizeof (UF_long)) ; + + /* get workspace of size 4n (recursive code only needs 2n) */ + Work = mxMalloc (4*n * sizeof (UF_long)) ; + + /* get the input column permutation Q */ + if (nargin == 2) + { + if (mxGetNumberOfElements (pargin [1]) != n) + { + mexErrMsgTxt + ("strongcomp: qin must be a permutation vector of size n") ; + } + Qx = mxGetPr (pargin [1]) ; + Q = mxMalloc (n * sizeof (UF_long)) ; + /* connvert Qin to 0-based and check validity */ + for (i = 0 ; i < n ; i++) + { + Work [i] = 0 ; + } + for (k = 0 ; k < n ; k++) + { + j = Qx [k] - 1 ; /* convert to 0-based */ + jj = BTF_UNFLIP (j) ; + if (jj < 0 || jj >= n || Work [jj] == 1) + { + mexErrMsgTxt + ("strongcomp: qin must be a permutation vector of size n") ; + } + Work [jj] = 1 ; + Q [k] = j ; + } + } + else + { + /* no input column permutation */ + Q = (UF_long *) NULL ; + } + + /* ---------------------------------------------------------------------- */ + /* find the strongly-connected components of A */ + /* ---------------------------------------------------------------------- */ + + nblocks = btf_l_strongcomp (n, Ap, Ai, Q, P, R, Work) ; + + /* ---------------------------------------------------------------------- */ + /* create outputs and free workspace */ + /* ---------------------------------------------------------------------- */ + + /* create P */ + pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; + Px = mxGetPr (pargout [0]) ; + for (k = 0 ; k < n ; k++) + { + Px [k] = P [k] + 1 ; /* convert to 1-based */ + } + + /* create Q */ + if (nargin == 2 && nargout > 1) + { + pargout [1] = mxCreateDoubleMatrix (1, n, mxREAL) ; + Qx = mxGetPr (pargout [1]) ; + for (k = 0 ; k < n ; k++) + { + Qx [k] = Q [k] + 1 ; /* convert to 1-based */ + } + } + + /* create R */ + if (nargout == nargin + 1) + { + pargout [nargin] = mxCreateDoubleMatrix (1, nblocks+1, mxREAL) ; + Rx = mxGetPr (pargout [nargin]) ; + for (b = 0 ; b <= nblocks ; b++) + { + Rx [b] = R [b] + 1 ; /* convert to 1-based */ + } + } + + mxFree (P) ; + mxFree (R) ; + mxFree (Work) ; + if (nargin == 2) + { + mxFree (Q) ; + } +} diff --git a/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.m b/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.m new file mode 100644 index 0000000..86546db --- /dev/null +++ b/OpenDSSC/klusolve/BTF/MATLAB/strongcomp.m @@ -0,0 +1,45 @@ +function [p,q,r] = strongcomp (A, qin) %#ok +%STRONGCOMP symmetric permutation to upper block triangular form +% The matrix must be sparse and square. +% +% Example: +% [p,r] = strongcomp (A) ; +% [p,q,r] = strongcomp (A,qin) ; +% +% In the first usage, the permuted matrix is C = A (p,p). In the second usage, +% the matrix A (:,qin) is symmetrically permuted to upper block triangular +% form, where qin is an input column permutation, and the final permuted +% matrix is C = A (p,q). This second usage is equivalent to +% +% [p,r] = strongcomp (A (:,qin)) ; +% q = qin (p) ; +% +% That is, if qin is not present it is assumed to be qin = 1:n. +% +% C is the permuted matrix, with a number of blocks equal to length(r)-1. +% The kth block is from row/col r(k) to row/col r(k+1)-1 of C. +% r(1) is one and the last entry in r is equal to n+1. +% The diagonal of A (or A (:,qin)) is ignored. +% +% strongcomp is normally proceeded by a maximum transversal. +% Assuming A is square and structurally nonsingular, +% +% [p,q,r] = strongcomp (A, maxtrans (A)) +% +% is essentially identical to +% +% [p,q,r] = dmperm (A) +% +% except that p, q, and r will differ. Both return an upper block triangular +% form with a zero-free diagonal. The number and sizes of the blocks will be +% identical, but the order of the blocks, and the ordering within the blocks, +% can be different. If the matrix is structurally singular, both strongcomp +% and maxtrans return a vector q containing negative entries. abs(q) is a +% permutation of 1:n, and find(q<0) gives a list of the indices of the +% diagonal of A(p,q) that are zero. +% +% See also btf, maxtrans, dmperm + +% Copyright 2004-2007, Tim Davis, University of Florida + +error ('strongcomp mexFunction not found') ; diff --git a/OpenDSSC/klusolve/BTF/Makefile b/OpenDSSC/klusolve/BTF/Makefile new file mode 100644 index 0000000..796d8c1 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Makefile @@ -0,0 +1,18 @@ +default: library + +include ../UFconfig/UFconfig.mk + +library: + ( cd Lib ; $(MAKE) ) + +clean: + ( cd Lib ; $(MAKE) clean ) + +distclean: + ( cd Lib ; $(MAKE) distclean ) + ( cd MATLAB ; $(MAKE) distclean ) + +mex: + ( cd MATLAB ; $(MAKE) ) + +purge: distclean diff --git a/OpenDSSC/klusolve/BTF/README.txt b/OpenDSSC/klusolve/BTF/README.txt new file mode 100644 index 0000000..efc84f8 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/README.txt @@ -0,0 +1,109 @@ +BTF Version 1.0, May 31, 2007, by Timothy A. Davis +Copyright (C) 2004-2007, University of Florida +BTF is also available under other licenses; contact the author for details. +http://www.cise.ufl.edu/research/sparse + +BTF is a software package for permuting a matrix into block upper triangular +form. It includes a maximum transversal algorithm, which finds a permutation +of a square or rectangular matrix so that it has a zero-free diagonal (if one +exists); otherwise, it finds a maximal matching which maximizes the number of +nonzeros on the diagonal. The package also includes a method for finding the +strongly connected components of a graph. These two methods together give the +permutation to block upper triangular form. + +Requires UFconfig, in the ../UFconfig directory relative to this directory. +KLU relies on this package to permute + +To compile the libbtf.a library, type "make". The compiled library is located +in BTF/Lib/libbtf.a. Compile code that uses BTF with -IBTF/Include. + +Type "make clean" to remove all but the compiled library, and "make distclean" +to remove all files not in the original distribution. + +This package does not include a statement coverage test (Tcov directory) or +demo program (Demo directory). See the KLU package for both. The BTF package +does include a MATLAB interface, a MATLAB test suite (in the MATLAB/Test +directory), and a MATLAB demo. + +See BTF/Include/btf.h for documentation on how to use the C-callable functions. +Use "help btf", "help maxtrans" and "help strongcomp" in MATLAB, for details on +how to use the MATLAB-callable functions. Additional details on the use of BTF +are given in the KLU User Guide, normally in ../KLU/Doc/KLU_UserGuide.pdf +relative to this directory. + +-------------------------------------------------------------------------------- + +BTF is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This Module is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +-------------------------------------------------------------------------------- + +A full text of the license is in Doc/lesser.txt. + +-------------------------------------------------------------------------------- + +Files and directories in the BTF package: + + Doc documentation and license + Include include files + Lib compiled BTF library + Makefile Makefile for C and MATLAB versions + MATLAB MATLAB interface + README.txt this file + Source BTF source code + +./Doc: + + ChangeLog changes in BTF + lesser.txt license + +./Include: + + btf.h primary user include file + btf_internal.h internal include file, not for user programs + +./Lib: + + Makefile Makefile for C library + +./MATLAB: + + btf.c btf mexFunction + btf_install.m compile and install BTF for use in MATLAB + btf.m btf help + Contents.m contents of MATLAB interface + Makefile Makefile for MATLAB functions + maxtrans.c maxtrans mexFunction + maxtrans.m maxtrans help + strongcomp.c strongcomp mexFunction + strongcomp.m strongcomp help + Test MATLAB test directory + +./MATLAB/Test: + + checkbtf.m check a BTF ordering + drawbtf.m plot a BTF ordering + test1.m compare maxtrans and cs_dmperm + test2.m compare btf and cs_dmperm + test3.m extensive test (maxtrans, strongcomp, and btf) + test4b.m test btf maxwork option + test4.m test btf maxwork option + test5.m test maxtrans maxwork option + +./Source: + + btf_maxtrans.c btf_maxtrans C function + btf_order.c btf_order C function + btf_strongcomp.c btf_strongcomp C function + diff --git a/OpenDSSC/klusolve/BTF/Source/btf_l_maxtrans.c b/OpenDSSC/klusolve/BTF/Source/btf_l_maxtrans.c new file mode 100644 index 0000000..c9b8a45 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_l_maxtrans.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "btf_maxtrans.c" diff --git a/OpenDSSC/klusolve/BTF/Source/btf_l_order.c b/OpenDSSC/klusolve/BTF/Source/btf_l_order.c new file mode 100644 index 0000000..b3e167a --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_l_order.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "btf_order.c" diff --git a/OpenDSSC/klusolve/BTF/Source/btf_l_strongcomp.c b/OpenDSSC/klusolve/BTF/Source/btf_l_strongcomp.c new file mode 100644 index 0000000..e26faa0 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_l_strongcomp.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "btf_strongcomp.c" diff --git a/OpenDSSC/klusolve/BTF/Source/btf_maxtrans.c b/OpenDSSC/klusolve/BTF/Source/btf_maxtrans.c new file mode 100644 index 0000000..7583e71 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_maxtrans.c @@ -0,0 +1,387 @@ +/* ========================================================================== */ +/* === BTF_MAXTRANS ========================================================= */ +/* ========================================================================== */ + +/* Finds a column permutation that maximizes the number of entries on the + * diagonal of a sparse matrix. See btf.h for more information. + * + * This function is identical to cs_maxtrans in CSparse, with the following + * exceptions: + * + * (1) cs_maxtrans finds both jmatch and imatch, where jmatch [i] = j and + * imatch [j] = i if row i is matched to column j. This function returns + * just jmatch (the Match array). The MATLAB interface to cs_maxtrans + * (the single-output cs_dmperm) returns imatch, not jmatch to the MATLAB + * caller. + * + * (2) cs_maxtrans includes a pre-pass that counts the number of non-empty + * rows and columns (m2 and n2, respectively), and computes the matching + * using the transpose of A if m2 < n2. cs_maxtrans also returns quickly + * if the diagonal of the matrix is already zero-free. This pre-pass + * allows cs_maxtrans to be much faster than maxtrans, if the use of the + * transpose is warranted. + * + * However, for square structurally non-singular matrices with one or more + * zeros on the diagonal, the pre-pass is a waste of time, and for these + * matrices, maxtrans can be twice as fast as cs_maxtrans. Since the + * maxtrans function is intended primarily for square matrices that are + * typically structurally nonsingular, the pre-pass is not included here. + * If this maxtrans function is used on a matrix with many more columns + * than rows, consider passing the transpose to this function, or use + * cs_maxtrans instead. + * + * (3) cs_maxtrans can operate as a randomized algorithm, to help avoid + * rare cases of excessive run-time. + * + * (4) this maxtrans function includes an option that limits the total work + * performed. If this limit is reached, the maximum transveral might not + * be found. + * + * Thus, for general usage, cs_maxtrans is preferred. For square matrices that + * are typically structurally non-singular, maxtrans is preferred. A partial + * maxtrans can still be very useful when solving a sparse linear system. + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + +#include "btf.h" +#include "btf_internal.h" + + +/* ========================================================================== */ +/* === augment ============================================================== */ +/* ========================================================================== */ + +/* Perform a depth-first-search starting at column k, to find an augmenting + * path. An augmenting path is a sequence of row/column pairs (i1,k), (i2,j1), + * (i3,j2), ..., (i(s+1), js), such that all of the following properties hold: + * + * * column k is not matched to any row + * * entries in the path are nonzero + * * the pairs (i1,j1), (i2,j2), (i3,j3) ..., (is,js) have been + * previously matched to each other + * * (i(s+1), js) is nonzero, and row i(s+1) is not matched to any column + * + * Once this path is found, the matching can be changed to the set of pairs + * path. An augmenting path is a sequence of row/column pairs + * + * (i1,k), (i2,j1), (i3,j2), ..., (i(s+1), js) + * + * Once a row is matched with a column it remains matched with some column, but + * not necessarily the column it was first matched with. + * + * In the worst case, this function can examine every nonzero in A. Since it + * is called n times by maxtrans, the total time of maxtrans can be as high as + * O(n*nnz(A)). To limit this work, pass a value of maxwork > 0. Then at + * most O((maxwork+1)*nnz(A)) work will be performed; the maximum matching might + * not be found, however. + * + * This routine is very similar to the dfs routine in klu_kernel.c, in the + * KLU sparse LU factorization package. It is essentially identical to the + * cs_augment routine in CSparse, and its recursive version (augment function + * in cs_maxtransr_mex.c), except that this routine allows for the search to be + * terminated early if too much work is being performed. + * + * The algorithm is based on the paper "On Algorithms for obtaining a maximum + * transversal" by Iain Duff, ACM Trans. Mathematical Software, vol 7, no. 1, + * pp. 315-330, and "Algorithm 575: Permutations for a zero-free diagonal", + * same issue, pp. 387-390. The code here is a new implementation of that + * algorithm, with different data structures and control flow. After writing + * this code, I carefully compared my algorithm with MC21A/B (ACM Algorithm 575) + * Some of the comparisons are partial because I didn't dig deeply into all of + * the details of MC21A/B, such as how the stack is maintained. The following + * arguments are essentially identical between this code and MC21A: + * + * maxtrans MC21A,B + * -------- ------- + * n N identical + * k JORD identical + * Ap IP column / row pointers + * Ai ICN row / column indices + * Ap[n] LICN length of index array (# of nonzeros in A) + * Match IPERM output column / row permutation + * nmatch NUMNZ # of nonzeros on diagonal of permuted matrix + * Flag CV mark a node as visited by the depth-first-search + * + * The following are different, but analogous: + * + * Cheap ARP indicates what part of the a column / row has + * already been matched. + * + * The following arguments are very different: + * + * - LENR # of entries in each row/column (unused in maxtrans) + * Pstack OUT Pstack keeps track of where we are in the depth- + * first-search scan of column j. I think that OUT + * plays a similar role in MC21B, but I'm unsure. + * Istack PR keeps track of the rows in the path. PR is a link + * list, though, whereas Istack is a stack. Maxtrans + * does not use any link lists. + * Jstack OUT? PR? the stack for nodes in the path (unsure) + * + * The following control structures are roughly comparable: + * + * maxtrans MC21B + * -------- ----- + * for (k = 0 ; k < n ; k++) DO 100 JORD=1,N + * while (head >= 0) DO 70 K=1,JORD + * for (p = Cheap [j] ; ...) DO 20 II=IN1,IN2 + * for (p = head ; ...) DO 90 K=1,JORD + */ + +static Int augment +( + Int k, /* which stage of the main loop we're in */ + Int Ap [ ], /* column pointers, size n+1 */ + Int Ai [ ], /* row indices, size nz = Ap [n] */ + Int Match [ ], /* size n, Match [i] = j if col j matched to i */ + Int Cheap [ ], /* rows Ai [Ap [j] .. Cheap [j]-1] alread matched */ + Int Flag [ ], /* Flag [j] = k if j already visited this stage */ + Int Istack [ ], /* size n. Row index stack. */ + Int Jstack [ ], /* size n. Column index stack. */ + Int Pstack [ ], /* size n. Keeps track of position in adjacency list */ + double *work, /* work performed by the depth-first-search */ + double maxwork /* maximum work allowed */ +) +{ + /* local variables, but "global" to all DFS levels: */ + Int found ; /* true if match found. */ + Int head ; /* top of stack */ + + /* variables that are purely local to any one DFS level: */ + Int j2 ; /* the next DFS goes to node j2 */ + Int pend ; /* one past the end of the adjacency list for node j */ + Int pstart ; + Int quick ; + + /* variables that need to be pushed then popped from the stack: */ + Int i ; /* the row tentatively matched to i if DFS successful */ + Int j ; /* the DFS is at the current node j */ + Int p ; /* current index into the adj. list for node j */ + /* the variables i, j, and p are stacked in Istack, Jstack, and Pstack */ + + quick = (maxwork > 0) ; + + /* start a DFS to find a match for column k */ + found = FALSE ; + i = EMPTY ; + head = 0 ; + Jstack [0] = k ; + ASSERT (Flag [k] != k) ; + + while (head >= 0) + { + j = Jstack [head] ; + pend = Ap [j+1] ; + + if (Flag [j] != k) /* a node is not yet visited */ + { + + /* -------------------------------------------------------------- */ + /* prework for node j */ + /* -------------------------------------------------------------- */ + + /* first time that j has been visited */ + Flag [j] = k ; + /* cheap assignment: find the next unmatched row in col j. This + * loop takes at most O(nnz(A)) time for the sum total of all + * calls to augment. */ + for (p = Cheap [j] ; p < pend && !found ; p++) + { + i = Ai [p] ; + found = (Match [i] == EMPTY) ; + } + Cheap [j] = p ; + + /* -------------------------------------------------------------- */ + + /* prepare for DFS */ + if (found) + { + /* end of augmenting path, column j matched with row i */ + Istack [head] = i ; + break ; + } + /* set Pstack [head] to the first entry in column j to scan */ + Pstack [head] = Ap [j] ; + } + + /* ------------------------------------------------------------------ */ + /* quick return if too much work done */ + /* ------------------------------------------------------------------ */ + + if (quick && *work > maxwork) + { + /* too much work has been performed; abort the search */ + return (EMPTY) ; + } + + /* ------------------------------------------------------------------ */ + /* DFS for nodes adjacent to j */ + /* ------------------------------------------------------------------ */ + + /* If cheap assignment not made, continue the depth-first search. All + * rows in column j are already matched. Add the adjacent nodes to the + * stack by iterating through until finding another non-visited node. + * + * It is the following loop that can force maxtrans to take + * O(n*nnz(A)) time. */ + + pstart = Pstack [head] ; + for (p = pstart ; p < pend ; p++) + { + i = Ai [p] ; + j2 = Match [i] ; + ASSERT (j2 != EMPTY) ; + if (Flag [j2] != k) + { + /* Node j2 is not yet visited, start a depth-first search on + * node j2. Keep track of where we left off in the scan of adj + * list of node j so we can restart j where we left off. */ + Pstack [head] = p + 1 ; + /* Push j2 onto the stack and immediately break so we can + * recurse on node j2. Also keep track of row i which (if this + * search for an augmenting path works) will be matched with the + * current node j. */ + Istack [head] = i ; + Jstack [++head] = j2 ; + break ; + } + } + + /* ------------------------------------------------------------------ */ + /* determine how much work was just performed */ + /* ------------------------------------------------------------------ */ + + *work += (p - pstart + 1) ; + + /* ------------------------------------------------------------------ */ + /* node j is done, but the postwork is postponed - see below */ + /* ------------------------------------------------------------------ */ + + if (p == pend) + { + /* If all adjacent nodes of j are already visited, pop j from + * stack and continue. We failed to find a match. */ + head-- ; + } + } + + /* postwork for all nodes j in the stack */ + /* unwind the path and make the corresponding matches */ + if (found) + { + for (p = head ; p >= 0 ; p--) + { + j = Jstack [p] ; + i = Istack [p] ; + + /* -------------------------------------------------------------- */ + /* postwork for node j */ + /* -------------------------------------------------------------- */ + /* if found, match row i with column j */ + Match [i] = j ; + } + } + return (found) ; +} + + +/* ========================================================================== */ +/* === maxtrans ============================================================= */ +/* ========================================================================== */ + +Int BTF(maxtrans) /* returns # of columns in the matching */ +( + /* --- input --- */ + Int nrow, /* A is nrow-by-ncol in compressed column form */ + Int ncol, + Int Ap [ ], /* size ncol+1 */ + Int Ai [ ], /* size nz = Ap [ncol] */ + double maxwork, /* do at most maxwork*nnz(A) work; no limit if <= 0. This + * work limit excludes the O(nnz(A)) cheap-match phase. */ + + /* --- output --- */ + double *work, /* work = -1 if maxwork > 0 and the total work performed + * reached the maximum of maxwork*nnz(A)). + * Otherwise, work = the total work performed. */ + + Int Match [ ], /* size nrow. Match [i] = j if column j matched to row i */ + + /* --- workspace --- */ + Int Work [ ] /* size 5*ncol */ +) +{ + Int *Cheap, *Flag, *Istack, *Jstack, *Pstack ; + Int i, j, k, nmatch, work_limit_reached, result ; + + /* ---------------------------------------------------------------------- */ + /* get workspace and initialize */ + /* ---------------------------------------------------------------------- */ + + Cheap = Work ; Work += ncol ; + Flag = Work ; Work += ncol ; + + /* stack for non-recursive depth-first search in augment function */ + Istack = Work ; Work += ncol ; + Jstack = Work ; Work += ncol ; + Pstack = Work ; + + /* in column j, rows Ai [Ap [j] .. Cheap [j]-1] are known to be matched */ + for (j = 0 ; j < ncol ; j++) + { + Cheap [j] = Ap [j] ; + Flag [j] = EMPTY ; + } + + /* all rows and columns are currently unmatched */ + for (i = 0 ; i < nrow ; i++) + { + Match [i] = EMPTY ; + } + + if (maxwork > 0) + { + maxwork *= Ap [ncol] ; + } + *work = 0 ; + + /* ---------------------------------------------------------------------- */ + /* find a matching row for each column k */ + /* ---------------------------------------------------------------------- */ + + nmatch = 0 ; + work_limit_reached = FALSE ; + for (k = 0 ; k < ncol ; k++) + { + /* find an augmenting path to match some row i to column k */ + result = augment (k, Ap, Ai, Match, Cheap, Flag, Istack, Jstack, Pstack, + work, maxwork) ; + if (result == TRUE) + { + /* we found it. Match [i] = k for some row i has been done. */ + nmatch++ ; + } + else if (result == EMPTY) + { + /* augment gave up because of too much work, and no match found */ + work_limit_reached = TRUE ; + } + } + + /* ---------------------------------------------------------------------- */ + /* return the Match, and the # of matches made */ + /* ---------------------------------------------------------------------- */ + + /* At this point, row i is matched to j = Match [i] if j >= 0. i is an + * unmatched row if Match [i] == EMPTY. */ + + if (work_limit_reached) + { + /* return -1 if the work limit of maxwork*nnz(A) was reached */ + *work = EMPTY ; + } + + return (nmatch) ; +} diff --git a/OpenDSSC/klusolve/BTF/Source/btf_order.c b/OpenDSSC/klusolve/BTF/Source/btf_order.c new file mode 100644 index 0000000..7ed04f1 --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_order.c @@ -0,0 +1,132 @@ +/* ========================================================================== */ +/* === BTF_ORDER ============================================================ */ +/* ========================================================================== */ + +/* Find a permutation P and Q to permute a square sparse matrix into upper block + * triangular form. A(P,Q) will contain a zero-free diagonal if A has + * structural full-rank. Otherwise, the number of nonzeros on the diagonal of + * A(P,Q) will be maximized, and will equal the structural rank of A. + * + * Q[k] will be "flipped" if a zero-free diagonal was not found. Q[k] will be + * negative, and j = BTF_UNFLIP (Q [k]) gives the corresponding permutation. + * + * R defines the block boundaries of A(P,Q). The kth block consists of rows + * and columns R[k] to R[k+1]-1. + * + * If maxwork > 0 on input, then the work performed in btf_maxtrans is limited + * to maxwork*nnz(A) (excluding the "cheap match" phase, which can take another + * nnz(A) work). On output, the work parameter gives the actual work performed, + * or -1 if the limit was reached. In the latter case, the diagonal of A(P,Q) + * might not be zero-free, and the number of nonzeros on the diagonal of A(P,Q) + * might not be equal to the structural rank. + * + * See btf.h for more details. + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + +#include "btf.h" +#include "btf_internal.h" + +/* This function only operates on square matrices (either structurally full- + * rank, or structurally rank deficient). */ + +Int BTF(order) /* returns number of blocks found */ +( + /* input, not modified: */ + Int n, /* A is n-by-n in compressed column form */ + Int Ap [ ], /* size n+1 */ + Int Ai [ ], /* size nz = Ap [n] */ + double maxwork, /* do at most maxwork*nnz(A) work in the maximum + * transversal; no limit if <= 0 */ + + /* output, not defined on input */ + double *work, /* work performed in maxtrans, or -1 if limit reached */ + Int P [ ], /* size n, row permutation */ + Int Q [ ], /* size n, column permutation */ + Int R [ ], /* size n+1. block b is in rows/cols R[b] ... R[b+1]-1 */ + Int *nmatch, /* # nonzeros on diagonal of P*A*Q */ + + /* workspace, not defined on input or output */ + Int Work [ ] /* size 5n */ +) +{ + Int *Flag ; + Int nblocks, i, j, nbadcol ; + + /* ---------------------------------------------------------------------- */ + /* compute the maximum matching */ + /* ---------------------------------------------------------------------- */ + + /* if maxwork > 0, then a maximum matching might not be found */ + + *nmatch = BTF(maxtrans) (n, n, Ap, Ai, maxwork, work, Q, Work) ; + + /* ---------------------------------------------------------------------- */ + /* complete permutation if the matrix is structurally singular */ + /* ---------------------------------------------------------------------- */ + + /* Since the matrix is square, ensure BTF_UNFLIP(Q[0..n-1]) is a + * permutation of the columns of A so that A has as many nonzeros on the + * diagonal as possible. + */ + + if (*nmatch < n) + { + /* get a size-n work array */ + Flag = Work + n ; + for (j = 0 ; j < n ; j++) + { + Flag [j] = 0 ; + } + + /* flag all matched columns */ + for (i = 0 ; i < n ; i++) + { + j = Q [i] ; + if (j != EMPTY) + { + /* row i and column j are matched to each other */ + Flag [j] = 1 ; + } + } + + /* make a list of all unmatched columns, in Work [0..nbadcol-1] */ + nbadcol = 0 ; + for (j = n-1 ; j >= 0 ; j--) + { + if (!Flag [j]) + { + /* j is matched to nobody */ + Work [nbadcol++] = j ; + } + } + ASSERT (*nmatch + nbadcol == n) ; + + /* make an assignment for each unmatched row */ + for (i = 0 ; i < n ; i++) + { + if (Q [i] == EMPTY && nbadcol > 0) + { + /* get an unmatched column j */ + j = Work [--nbadcol] ; + /* assign j to row i and flag the entry by "flipping" it */ + Q [i] = BTF_FLIP (j) ; + } + } + } + + /* The permutation of a square matrix can be recovered as follows: Row i is + * matched with column j, where j = BTF_UNFLIP (Q [i]) and where j + * will always be in the valid range 0 to n-1. The entry A(i,j) is zero + * if BTF_ISFLIPPED (Q [i]) is true, and nonzero otherwise. nmatch + * is the number of entries in the Q array that are non-negative. */ + + /* ---------------------------------------------------------------------- */ + /* find the strongly connected components */ + /* ---------------------------------------------------------------------- */ + + nblocks = BTF(strongcomp) (n, Ap, Ai, Q, P, R, Work) ; + return (nblocks) ; +} diff --git a/OpenDSSC/klusolve/BTF/Source/btf_strongcomp.c b/OpenDSSC/klusolve/BTF/Source/btf_strongcomp.c new file mode 100644 index 0000000..4474bec --- /dev/null +++ b/OpenDSSC/klusolve/BTF/Source/btf_strongcomp.c @@ -0,0 +1,593 @@ +/* ========================================================================== */ +/* === BTF_STRONGCOMP ======================================================= */ +/* ========================================================================== */ + +/* Finds the strongly connected components of a graph, or equivalently, permutes + * the matrix into upper block triangular form. See btf.h for more details. + * Input matrix and Q are not checked on input. + * + * Copyright (c) 2004-2007. Tim Davis, University of Florida, + * with support from Sandia National Laboratories. All Rights Reserved. + */ + +#include "btf.h" +#include "btf_internal.h" + +#define UNVISITED (-2) /* Flag [j] = UNVISITED if node j not visited yet */ +#define UNASSIGNED (-1) /* Flag [j] = UNASSIGNED if node j has been visited, + * but not yet assigned to a strongly-connected + * component (aka block). Flag [j] = k (k in the + * range 0 to nblocks-1) if node j has been visited + * (and completed, with its postwork done) and + * assigned to component k. */ + +/* This file contains two versions of the depth-first-search, a recursive one + * and a non-recursive one. By default, the non-recursive one is used. */ + +#ifndef RECURSIVE + +/* ========================================================================== */ +/* === dfs: non-recursive version (default) ================================= */ +/* ========================================================================== */ + +/* Perform a depth-first-search of a graph, stored in an adjacency-list form. + * The row indices of column j (equivalently, the out-adjacency list of node j) + * are stored in Ai [Ap[j] ... Ap[j+1]-1]. Self-edge (diagonal entries) are + * ignored. Ap[0] must be zero, and thus nz = Ap[n] is the number of entries + * in the matrix (or edges in the graph). The row indices in each column need + * not be in any particular order. If an input column permutation is given, + * node j (in the permuted matrix A*Q) is located in + * Ai [Ap[Q[j]] ... Ap[Q[j]+1]-1]. This Q can be the same as the Match array + * output from the maxtrans routine, for a square matrix that is structurally + * full rank. + * + * The algorithm is from the paper by Robert E. Tarjan, "Depth-first search and + * linear graph algorithms," SIAM Journal on Computing, vol. 1, no. 2, + * pp. 146-160, 1972. The time taken by strongcomp is O(nnz(A)). + * + * See also MC13A/B in the Harwell subroutine library (Iain S. Duff and John + * K. Reid, "Algorithm 529: permutations to block triangular form," ACM Trans. + * on Mathematical Software, vol. 4, no. 2, pp. 189-192, 1978, and "An + * implementation of Tarjan's algorithm for the block triangular form of a + * matrix," same journal, pp. 137-147. This code is implements the same + * algorithm as MC13A/B, except that the data structures are very different. + * Also, unlike MC13A/B, the output permutation preserves the natural ordering + * within each block. + */ + +static void dfs +( + /* inputs, not modified on output: */ + Int j, /* start the DFS at node j */ + Int Ap [ ], /* size n+1, column pointers for the matrix A */ + Int Ai [ ], /* row indices, size nz = Ap [n] */ + Int Q [ ], /* input column permutation */ + + /* inputs, modified on output (each array is of size n): */ + Int Time [ ], /* Time [j] = "time" that node j was first visited */ + Int Flag [ ], /* Flag [j]: see above */ + Int Low [ ], /* Low [j]: see definition below */ + Int *p_nblocks, /* number of blocks (aka strongly-connected-comp.)*/ + Int *p_timestamp, /* current "time" */ + + /* workspace, not defined on input or output: */ + Int Cstack [ ], /* size n, output stack to hold nodes of components */ + Int Jstack [ ], /* size n, stack for the variable j */ + Int Pstack [ ] /* size n, stack for the variable p */ +) +{ + /* ---------------------------------------------------------------------- */ + /* local variables, and initializations */ + /* ---------------------------------------------------------------------- */ + + /* local variables, but "global" to all DFS levels: */ + Int chead ; /* top of Cstack */ + Int jhead ; /* top of Jstack and Pstack */ + + /* variables that are purely local to any one DFS level: */ + Int i ; /* edge (j,i) considered; i can be next node to traverse */ + Int parent ; /* parent of node j in the DFS tree */ + Int pend ; /* one past the end of the adjacency list for node j */ + Int jj ; /* column j of A*Q is column jj of the input matrix A */ + + /* variables that need to be pushed then popped from the stack: */ + Int p ; /* current index into the adj. list for node j */ + /* the variables j and p are stacked in Jstack and Pstack */ + + /* local copies of variables in the calling routine */ + Int nblocks = *p_nblocks ; + Int timestamp = *p_timestamp ; + + /* ---------------------------------------------------------------------- */ + /* start a DFS at node j (same as the recursive call dfs (EMPTY, j)) */ + /* ---------------------------------------------------------------------- */ + + chead = 0 ; /* component stack is empty */ + jhead = 0 ; /* Jstack and Pstack are empty */ + Jstack [0] = j ; /* put the first node j on the Jstack */ + ASSERT (Flag [j] == UNVISITED) ; + + while (jhead >= 0) + { + j = Jstack [jhead] ; /* grab the node j from the top of Jstack */ + + /* determine which column jj of the A is column j of A*Q */ + jj = (Q == (Int *) NULL) ? (j) : (BTF_UNFLIP (Q [j])) ; + pend = Ap [jj+1] ; /* j's row index list ends at Ai [pend-1] */ + + if (Flag [j] == UNVISITED) + { + + /* -------------------------------------------------------------- */ + /* prework at node j */ + /* -------------------------------------------------------------- */ + + /* node j is being visited for the first time */ + Cstack [++chead] = j ; /* push j onto the stack */ + timestamp++ ; /* get a timestamp */ + Time [j] = timestamp ; /* give the timestamp to node j */ + Low [j] = timestamp ; + Flag [j] = UNASSIGNED ; /* flag node j as visited */ + + /* -------------------------------------------------------------- */ + /* set Pstack [jhead] to the first entry in column j to scan */ + /* -------------------------------------------------------------- */ + + Pstack [jhead] = Ap [jj] ; + } + + /* ------------------------------------------------------------------ */ + /* DFS rooted at node j (start it, or continue where left off) */ + /* ------------------------------------------------------------------ */ + + for (p = Pstack [jhead] ; p < pend ; p++) + { + i = Ai [p] ; /* examine the edge from node j to node i */ + if (Flag [i] == UNVISITED) + { + /* Node i has not been visited - start a DFS at node i. + * Keep track of where we left off in the scan of adjacency list + * of node j so we can restart j where we left off. */ + Pstack [jhead] = p + 1 ; + /* Push i onto the stack and immediately break + * so we can recurse on node i. */ + Jstack [++jhead] = i ; + ASSERT (Time [i] == EMPTY) ; + ASSERT (Low [i] == EMPTY) ; + /* break here to do what the recursive call dfs (j,i) does */ + break ; + } + else if (Flag [i] == UNASSIGNED) + { + /* Node i has been visited, but still unassigned to a block + * this is a back or cross edge if Time [i] < Time [j]. + * Note that i might equal j, in which case this code does + * nothing. */ + ASSERT (Time [i] > 0) ; + ASSERT (Low [i] > 0) ; + Low [j] = MIN (Low [j], Time [i]) ; + } + } + + if (p == pend) + { + /* If all adjacent nodes of j are already visited, pop j from + * Jstack and do the post work for node j. This also pops p + * from the Pstack. */ + jhead-- ; + + /* -------------------------------------------------------------- */ + /* postwork at node j */ + /* -------------------------------------------------------------- */ + + /* determine if node j is the head of a component */ + if (Low [j] == Time [j]) + { + /* pop all nodes in this SCC from Cstack */ + while (TRUE) + { + ASSERT (chead >= 0) ; /* stack not empty (j in it) */ + i = Cstack [chead--] ; /* pop a node from the Cstack */ + ASSERT (i >= 0) ; + ASSERT (Flag [i] == UNASSIGNED) ; + Flag [i] = nblocks ; /* assign i to current block */ + if (i == j) break ; /* current block ends at j */ + } + nblocks++ ; /* one more block has been found */ + } + /* update Low [parent], if the parent exists */ + if (jhead >= 0) + { + parent = Jstack [jhead] ; + Low [parent] = MIN (Low [parent], Low [j]) ; + } + } + } + + /* ---------------------------------------------------------------------- */ + /* cleanup: update timestamp and nblocks */ + /* ---------------------------------------------------------------------- */ + + *p_timestamp = timestamp ; + *p_nblocks = nblocks ; +} + +#else + +/* ========================================================================== */ +/* === dfs: recursive version (only for illustration) ======================= */ +/* ========================================================================== */ + +/* The following is a recursive version of dfs, which computes identical results + * as the non-recursive dfs. It is included here because it is easier to read. + * Compare the comments in the code below with the identical comments in the + * non-recursive code above, and that will help you see the correlation between + * the two routines. + * + * This routine can cause stack overflow, and is thus not recommended for heavy + * usage, particularly for large matrices. To help in delaying stack overflow, + * global variables are used, reducing the amount of information each call to + * dfs places on the call/return stack (the integers i, j, p, parent, and the + * return address). Note that this means the recursive code is not thread-safe. + * To try this version, compile the code with -DRECURSIVE or include the + * following line at the top of this file: + +#define RECURSIVE + + */ + +static Int /* for recursive illustration only, not for production use */ + chead, timestamp, nblocks, n, *Ap, *Ai, *Flag, *Cstack, *Time, *Low, + *P, *R, *Q ; + +static void dfs +( + Int parent, /* came from parent node */ + Int j /* at node j in the DFS */ +) +{ + Int p ; /* current index into the adj. list for node j */ + Int i ; /* edge (j,i) considered; i can be next node to traverse */ + Int jj ; /* column j of A*Q is column jj of the input matrix A */ + + /* ---------------------------------------------------------------------- */ + /* prework at node j */ + /* ---------------------------------------------------------------------- */ + + /* node j is being visited for the first time */ + Cstack [++chead] = j ; /* push j onto the stack */ + timestamp++ ; /* get a timestamp */ + Time [j] = timestamp ; /* give the timestamp to node j */ + Low [j] = timestamp ; + Flag [j] = UNASSIGNED ; /* flag node j as visited */ + + /* ---------------------------------------------------------------------- */ + /* DFS rooted at node j */ + /* ---------------------------------------------------------------------- */ + + /* determine which column jj of the A is column j of A*Q */ + jj = (Q == (Int *) NULL) ? (j) : (BTF_UNFLIP (Q [j])) ; + for (p = Ap [jj] ; p < Ap [jj+1] ; p++) + { + i = Ai [p] ; /* examine the edge from node j to node i */ + if (Flag [i] == UNVISITED) + { + /* Node i has not been visited - start a DFS at node i. */ + dfs (j, i) ; + } + else if (Flag [i] == UNASSIGNED) + { + /* Node i has been visited, but still unassigned to a block + * this is a back or cross edge if Time [i] < Time [j]. + * Note that i might equal j, in which case this code does + * nothing. */ + Low [j] = MIN (Low [j], Time [i]) ; + } + } + + /* ---------------------------------------------------------------------- */ + /* postwork at node j */ + /* ---------------------------------------------------------------------- */ + + /* determine if node j is the head of a component */ + if (Low [j] == Time [j]) + { + /* pop all nodes in this strongly connected component from Cstack */ + while (TRUE) + { + i = Cstack [chead--] ; /* pop a node from the Cstack */ + Flag [i] = nblocks ; /* assign node i to current block */ + if (i == j) break ; /* current block ends at node j */ + } + nblocks++ ; /* one more block has been found */ + } + /* update Low [parent] */ + if (parent != EMPTY) + { + /* Note that this could be done with Low[j] = MIN(Low[j],Low[i]) just + * after the dfs (j,i) statement above, and then parent would not have + * to be an input argument. Putting it here places all the postwork + * for node j in one place, thus making the non-recursive DFS easier. */ + Low [parent] = MIN (Low [parent], Low [j]) ; + } +} + +#endif + +/* ========================================================================== */ +/* === btf_strongcomp ======================================================= */ +/* ========================================================================== */ + +#ifndef RECURSIVE + +Int BTF(strongcomp) /* return # of strongly connected components */ +( + /* input, not modified: */ + Int n, /* A is n-by-n in compressed column form */ + Int Ap [ ], /* size n+1 */ + Int Ai [ ], /* size nz = Ap [n] */ + + /* optional input, modified (if present) on output: */ + Int Q [ ], /* size n, input column permutation. The permutation Q can + * include a flag which indicates an unmatched row. + * jold = BTF_UNFLIP (Q [jnew]) is the permutation; + * this function ingnores these flags. On output, it is + * modified according to the permutation P. */ + + /* output, not defined on input: */ + Int P [ ], /* size n. P [k] = j if row and column j are kth row/col + * in permuted matrix. */ + Int R [ ], /* size n+1. kth block is in rows/cols R[k] ... R[k+1]-1 + * of the permuted matrix. */ + + /* workspace, not defined on input or output: */ + Int Work [ ] /* size 4n */ +) + +#else + +Int BTF(strongcomp) /* recursive version - same as above except for Work size */ +( + Int n_in, + Int Ap_in [ ], + Int Ai_in [ ], + Int Q_in [ ], + Int P_in [ ], + Int R_in [ ], + Int Work [ ] /* size 2n */ +) + +#endif + +{ + Int j, k, b ; + +#ifndef RECURSIVE + Int timestamp, nblocks, *Flag, *Cstack, *Time, *Low, *Jstack, *Pstack ; +#else + n = n_in ; + Ap = Ap_in ; + Ai = Ai_in ; + Q = Q_in ; + P = P_in ; + R = R_in ; + chead = EMPTY ; +#endif + + /* ---------------------------------------------------------------------- */ + /* get and initialize workspace */ + /* ---------------------------------------------------------------------- */ + + /* timestamp is incremented each time a new node is visited. + * + * Time [j] is the timestamp given to node j. + * + * Low [j] is the lowest timestamp of any node reachable from j via either + * a path to any descendent of j in the DFS tree, or via a single edge to + * an either an ancestor (a back edge) or another node that's neither an + * ancestor nor a descendant (a cross edge). If Low [j] is equal to + * the timestamp of node j (Time [j]), then node j is the "head" of a + * strongly connected component (SCC). That is, it is the first node + * visited in its strongly connected component, and the DFS subtree rooted + * at node j spans all the nodes of the strongly connected component. + * + * The term "block" and "component" are used interchangebly in this code; + * "block" being a matrix term and "component" being a graph term for the + * same thing. + * + * When a node is visited, it is placed on the Cstack (for "component" + * stack). When node j is found to be an SCC head, all the nodes from the + * top of the stack to node j itself form the nodes in the SCC. This Cstack + * is used for both the recursive and non-recursive versions. + */ + + Time = Work ; Work += n ; + Flag = Work ; Work += n ; + Low = P ; /* use output array P as workspace for Low */ + Cstack = R ; /* use output array R as workspace for Cstack */ + +#ifndef RECURSIVE + /* stack for non-recursive dfs */ + Jstack = Work ; Work += n ; /* stack for j */ + Pstack = Work ; /* stack for p */ +#endif + + for (j = 0 ; j < n ; j++) + { + Flag [j] = UNVISITED ; + Low [j] = EMPTY ; + Time [j] = EMPTY ; +#ifndef NDEBUG + Cstack [j] = EMPTY ; +#ifndef RECURSIVE + Jstack [j] = EMPTY ; + Pstack [j] = EMPTY ; +#endif +#endif + } + + timestamp = 0 ; /* each node given a timestamp when it is visited */ + nblocks = 0 ; /* number of blocks found so far */ + + /* ---------------------------------------------------------------------- */ + /* find the connected components via a depth-first-search */ + /* ---------------------------------------------------------------------- */ + + for (j = 0 ; j < n ; j++) + { + /* node j is unvisited or assigned to a block. Cstack is empty. */ + ASSERT (Flag [j] == UNVISITED || (Flag [j] >= 0 && Flag [j] < nblocks)); + if (Flag [j] == UNVISITED) + { +#ifndef RECURSIVE + /* non-recursive dfs (default) */ + dfs (j, Ap, Ai, Q, Time, Flag, Low, &nblocks, ×tamp, + Cstack, Jstack, Pstack) ; +#else + /* recursive dfs (for illustration only) */ + ASSERT (chead == EMPTY) ; + dfs (EMPTY, j) ; + ASSERT (chead == EMPTY) ; +#endif + } + } + ASSERT (timestamp == n) ; + + /* ---------------------------------------------------------------------- */ + /* construct the block boundary array, R */ + /* ---------------------------------------------------------------------- */ + + for (b = 0 ; b < nblocks ; b++) + { + R [b] = 0 ; + } + for (j = 0 ; j < n ; j++) + { + /* node j has been assigned to block b = Flag [j] */ + ASSERT (Time [j] > 0 && Time [j] <= n) ; + ASSERT (Low [j] > 0 && Low [j] <= n) ; + ASSERT (Flag [j] >= 0 && Flag [j] < nblocks) ; + R [Flag [j]]++ ; + } + /* R [b] is now the number of nodes in block b. Compute cumulative sum + * of R, using Time [0 ... nblocks-1] as workspace. */ + Time [0] = 0 ; + for (b = 1 ; b < nblocks ; b++) + { + Time [b] = Time [b-1] + R [b-1] ; + } + for (b = 0 ; b < nblocks ; b++) + { + R [b] = Time [b] ; + } + R [nblocks] = n ; + + /* ---------------------------------------------------------------------- */ + /* construct the permutation, preserving the natural order */ + /* ---------------------------------------------------------------------- */ + +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + P [k] = EMPTY ; + } +#endif + + for (j = 0 ; j < n ; j++) + { + /* place column j in the permutation */ + P [Time [Flag [j]]++] = j ; + } + +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + ASSERT (P [k] != EMPTY) ; + } +#endif + + /* Now block b consists of the nodes k1 to k2-1 in the permuted matrix, + * where k1 = R [b] and k2 = R [b+1]. Row and column j of the original + * matrix becomes row and column P [k] of the permuted matrix. The set of + * of rows/columns (nodes) in block b is given by P [k1 ... k2-1], and this + * set is sorted in ascending order. Thus, if the matrix consists of just + * one block, P is the identity permutation. */ + + /* ---------------------------------------------------------------------- */ + /* if Q is present on input, set Q = Q*P' */ + /* ---------------------------------------------------------------------- */ + + if (Q != (Int *) NULL) + { + /* We found a symmetric permutation P for the matrix A*Q. The overall + * permutation is thus P*(A*Q)*P'. Set Q=Q*P' so that the final + * permutation is P*A*Q. Use Time as workspace. Note that this + * preserves the negative values of Q if the matrix is structurally + * singular. */ + for (k = 0 ; k < n ; k++) + { + Time [k] = Q [P [k]] ; + } + for (k = 0 ; k < n ; k++) + { + Q [k] = Time [k] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* how to traverse the permuted matrix */ + /* ---------------------------------------------------------------------- */ + + /* If Q is not present, the following code can be used to traverse the + * permuted matrix P*A*P' + * + * // compute the inverse of P + * for (knew = 0 ; knew < n ; knew++) + * { + * // row and column kold in the old matrix is row/column knew + * // in the permuted matrix P*A*P' + * kold = P [knew] ; + * Pinv [kold] = knew ; + * } + * for (b = 0 ; b < nblocks ; b++) + * { + * // traverse block b of the permuted matrix P*A*P' + * k1 = R [b] ; + * k2 = R [b+1] ; + * nk = k2 - k1 ; + * for (jnew = k1 ; jnew < k2 ; jnew++) + * { + * jold = P [jnew] ; + * for (p = Ap [jold] ; p < Ap [jold+1] ; p++) + * { + * iold = Ai [p] ; + * inew = Pinv [iold] ; + * // Entry in the old matrix is A (iold, jold), and its + * // position in the new matrix P*A*P' is (inew, jnew). + * // Let B be the bth diagonal block of the permuted + * // matrix. If inew >= k1, then this entry is in row/ + * // column (inew-k1, jnew-k1) of the nk-by-nk matrix B. + * // Otherwise, the entry is in the upper block triangular + * // part, not in any diagonal block. + * } + * } + * } + * + * If Q is present replace the above statement + * jold = P [jnew] ; + * with + * jold = Q [jnew] ; + * or + * jold = BTF_UNFLIP (Q [jnew]) ; + * + * then entry A (iold,jold) in the old (unpermuted) matrix is at (inew,jnew) + * in the permuted matrix P*A*Q. Everything else remains the same as the + * above (simply replace P*A*P' with P*A*Q in the above comments). + */ + + /* ---------------------------------------------------------------------- */ + /* return # of blocks / # of strongly connected components */ + /* ---------------------------------------------------------------------- */ + + return (nblocks) ; +} diff --git a/OpenDSSC/klusolve/CMakeLists.txt b/OpenDSSC/klusolve/CMakeLists.txt new file mode 100644 index 0000000..1bca1dc --- /dev/null +++ b/OpenDSSC/klusolve/CMakeLists.txt @@ -0,0 +1,182 @@ +cmake_minimum_required(VERSION 3.15) + +project(klusolve VERSION 0.0.0 DESCRIPTION "klusolve") + +# klusolve library - Here, we'll bypass this submodule's Makefile system in +# favor of cmake's default rules on how to build a shared library so that we +# may automatically produce a .dll for Windows, .so for Linux, .dylib for +# macOS, etc... + +add_library(klusolve_all SHARED + KLUSolve/Source/KLUSolve.cpp + KLUSolve/Source/KLUSystem.cpp + CSparse/Source/cs_add.c + CSparse/Source/cs_amd.c + CSparse/Source/cs_chol.c + CSparse/Source/cs_cholsol.c + CSparse/Source/cs_compress.c + CSparse/Source/cs_counts.c + CSparse/Source/cs_cumsum.c + CSparse/Source/cs_dfs.c + CSparse/Source/cs_dmperm.c + CSparse/Source/cs_droptol.c + CSparse/Source/cs_dropzeros.c + CSparse/Source/cs_dupl.c + CSparse/Source/cs_entry.c + CSparse/Source/cs_ereach.c + CSparse/Source/cs_etree.c + CSparse/Source/cs_fkeep.c + CSparse/Source/cs_gaxpy.c + CSparse/Source/cs_happly.c + CSparse/Source/cs_house.c + CSparse/Source/cs_ipvec.c + CSparse/Source/cs_leaf.c + CSparse/Source/cs_load.c + CSparse/Source/cs_lsolve.c + CSparse/Source/cs_ltsolve.c + CSparse/Source/cs_lu.c + CSparse/Source/cs_lusol.c + CSparse/Source/cs_malloc.c + CSparse/Source/cs_maxtrans.c + CSparse/Source/cs_multiply.c + CSparse/Source/cs_norm.c + CSparse/Source/cs_permute.c + CSparse/Source/cs_pinv.c + CSparse/Source/cs_post.c + CSparse/Source/cs_print.c + CSparse/Source/cs_pvec.c + CSparse/Source/cs_qr.c + CSparse/Source/cs_qrsol.c + CSparse/Source/cs_randperm.c + CSparse/Source/cs_reach.c + CSparse/Source/cs_scatter.c + CSparse/Source/cs_scc.c + CSparse/Source/cs_schol.c + CSparse/Source/cs_spsolve.c + CSparse/Source/cs_sqr.c + CSparse/Source/cs_symperm.c + CSparse/Source/cs_tdfs.c + CSparse/Source/cs_transpose.c + CSparse/Source/cs_updown.c + CSparse/Source/cs_usolve.c + CSparse/Source/cs_util.c + CSparse/Source/cs_utsolve.c + CZSparse/Source/csz_stuff.c + KLU/Source/klu.c + KLU/Source/klu_analyze.c + KLU/Source/klu_analyze_given.c + KLU/Source/klu_defaults.c + KLU/Source/klu_diagnostics.c + KLU/Source/klu_dump.c + KLU/Source/klu_extract.c + KLU/Source/klu_factor.c + KLU/Source/klu_free_numeric.c + KLU/Source/klu_free_symbolic.c + KLU/Source/klu_kernel.c + KLU/Source/klu_memory.c + KLU/Source/klu_refactor.c + KLU/Source/klu_scale.c + KLU/Source/klu_solve.c + KLU/Source/klu_sort.c + KLU/Source/klu_tsolve.c + KLU/Source/klu_l.c + KLU/Source/klu_l_analyze.c + KLU/Source/klu_l_analyze_given.c + KLU/Source/klu_l_defaults.c + KLU/Source/klu_l_diagnostics.c + KLU/Source/klu_l_dump.c + KLU/Source/klu_l_extract.c + KLU/Source/klu_l_factor.c + KLU/Source/klu_l_free_numeric.c + KLU/Source/klu_l_free_symbolic.c + KLU/Source/klu_l_kernel.c + KLU/Source/klu_l_memory.c + KLU/Source/klu_l_refactor.c + KLU/Source/klu_l_scale.c + KLU/Source/klu_l_solve.c + KLU/Source/klu_l_sort.c + KLU/Source/klu_l_tsolve.c + KLU/Source/klu_z.c + KLU/Source/klu_z_diagnostics.c + KLU/Source/klu_z_dump.c + KLU/Source/klu_z_extract.c + KLU/Source/klu_z_factor.c + KLU/Source/klu_z_free_numeric.c + KLU/Source/klu_z_kernel.c + KLU/Source/klu_z_refactor.c + KLU/Source/klu_z_scale.c + KLU/Source/klu_z_solve.c + KLU/Source/klu_z_sort.c + KLU/Source/klu_z_tsolve.c + KLU/Source/klu_zl.c + KLU/Source/klu_zl_diagnostics.c + KLU/Source/klu_zl_dump.c + KLU/Source/klu_zl_extract.c + KLU/Source/klu_zl_factor.c + KLU/Source/klu_zl_free_numeric.c + KLU/Source/klu_zl_kernel.c + KLU/Source/klu_zl_refactor.c + KLU/Source/klu_zl_scale.c + KLU/Source/klu_zl_solve.c + KLU/Source/klu_zl_sort.c + KLU/Source/klu_zl_tsolve.c + AMD/Source/amd_global.c + AMD/Source/amd_i_1.c + AMD/Source/amd_i_2.c + AMD/Source/amd_i_aat.c + AMD/Source/amd_i_control.c + AMD/Source/amd_i_defaults.c + AMD/Source/amd_i_dump.c + AMD/Source/amd_i_info.c + AMD/Source/amd_i_order.c + AMD/Source/amd_i_postorder.c + AMD/Source/amd_i_post_tree.c + AMD/Source/amd_i_preprocess.c + AMD/Source/amd_i_valid.c + AMD/Source/amd_l_1.c + AMD/Source/amd_l_2.c + AMD/Source/amd_l_aat.c + AMD/Source/amd_l_control.c + AMD/Source/amd_l_defaults.c + AMD/Source/amd_l_dump.c + AMD/Source/amd_l_info.c + AMD/Source/amd_l_order.c + AMD/Source/amd_l_postorder.c + AMD/Source/amd_l_post_tree.c + AMD/Source/amd_l_preprocess.c + AMD/Source/amd_l_valid.c + COLAMD/Source/colamd_global.c + COLAMD/Source/colamd.c + COLAMD/Source/colamd_l.c + BTF/Source/btf_maxtrans.c + BTF/Source/btf_order.c + BTF/Source/btf_strongcomp.c + BTF/Source/btf_l_maxtrans.c + BTF/Source/btf_l_order.c + BTF/Source/btf_l_strongcomp.c + UFconfig/UFconfig.c +) +set_target_properties(klusolve_all PROPERTIES + VERSION 0.0.0 + SOVERSION 0 +) +target_include_directories(klusolve_all + PUBLIC + KLUSolve/Include + PRIVATE + CSparse/Include + CZSparse/Include + KLU/Include + AMD/Include + COLAMD/Include + BTF/Include + UFconfig +) +if(MSVC) +target_compile_definitions(klusolve_all + PRIVATE + KLUSOLVE_IMPORTS=0 + INTERFACE + KLUSOLVE_IMPORTS=1 +) +endif() diff --git a/OpenDSSC/klusolve/COLAMD/Demo/Makefile b/OpenDSSC/klusolve/COLAMD/Demo/Makefile new file mode 100644 index 0000000..03658f4 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Demo/Makefile @@ -0,0 +1,44 @@ +#----------------------------------------------------------------------------- +# compile the COLAMD demo +#----------------------------------------------------------------------------- + +default: colamd_example colamd_l_example + +include ../../UFconfig/UFconfig.mk + +I = -I../Include -I../../UFconfig + +C = $(CC) $(CF) $(I) + +library: + ( cd ../Lib ; $(MAKE) ) + +#------------------------------------------------------------------------------ +# Create the demo program, run it, and compare the output +#------------------------------------------------------------------------------ + +dist: + +colamd_example: colamd_example.c library + $(C) -o colamd_example colamd_example.c ../Lib/libcolamd.a -lm + - ./colamd_example > my_colamd_example.out + - diff colamd_example.out my_colamd_example.out + +colamd_l_example: colamd_l_example.c library + $(C) -o colamd_l_example colamd_l_example.c ../Lib/libcolamd.a -lm + - ./colamd_l_example > my_colamd_l_example.out + - diff colamd_l_example.out my_colamd_l_example.out + +#------------------------------------------------------------------------------ +# Remove all but the files in the original distribution +#------------------------------------------------------------------------------ + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) colamd_example colamd_l_example + - $(RM) my_colamd_example.out my_colamd_l_example.out + - $(RM) -r *.dSYM diff --git a/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.c b/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.c new file mode 100644 index 0000000..fe824d8 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.c @@ -0,0 +1,181 @@ +/* ========================================================================== */ +/* === colamd and symamd example ============================================ */ +/* ========================================================================== */ + +/* COLAMD / SYMAMD example + + colamd example of use, to order the columns of a 5-by-4 matrix with + 11 nonzero entries in the following nonzero pattern, with default knobs. + + x 0 x 0 + x 0 x x + 0 x x 0 + 0 0 x x + x x 0 0 + + symamd example of use, to order the rows and columns of a 5-by-5 + matrix with 13 nonzero entries in the following nonzero pattern, + with default knobs. + + x x 0 0 0 + x x x x 0 + 0 x x 0 0 + 0 x 0 x x + 0 0 0 x x + + (where x denotes a nonzero value). + + See http://www.cise.ufl.edu/research/sparse/colamd/ (the colamd.c file) + for the routines this program calls, and for the License. +*/ + +/* ========================================================================== */ + +#include +#include "colamd.h" + +#define A_NNZ 11 +#define A_NROW 5 +#define A_NCOL 4 +#define ALEN 150 + +#define B_NNZ 4 +#define B_N 5 + +int main (void) +{ + + /* ====================================================================== */ + /* input matrix A definition */ + /* ====================================================================== */ + + int A [ALEN] = { + + 0, 1, 4, /* row indices of nonzeros in column 0 */ + 2, 4, /* row indices of nonzeros in column 1 */ + 0, 1, 2, 3, /* row indices of nonzeros in column 2 */ + 1, 3} ; /* row indices of nonzeros in column 3 */ + + int p [ ] = { + + 0, /* column 0 is in A [0..2] */ + 3, /* column 1 is in A [3..4] */ + 5, /* column 2 is in A [5..8] */ + 9, /* column 3 is in A [9..10] */ + A_NNZ} ; /* number of nonzeros in A */ + + /* ====================================================================== */ + /* input matrix B definition */ + /* ====================================================================== */ + + int B [ ] = { /* Note: only strictly lower triangular part */ + /* is included, since symamd ignores the */ + /* diagonal and upper triangular part of B. */ + + 1, /* row indices of nonzeros in column 0 */ + 2, 3, /* row indices of nonzeros in column 1 */ + /* row indices of nonzeros in column 2 (none) */ + 4 /* row indices of nonzeros in column 3 */ + } ; /* row indices of nonzeros in column 4 (none) */ + + int q [ ] = { + + 0, /* column 0 is in B [0] */ + 1, /* column 1 is in B [1..2] */ + 3, /* column 2 is empty */ + 3, /* column 3 is in B [3] */ + 4, /* column 4 is empty */ + B_NNZ} ; /* number of nonzeros in strictly lower B */ + + /* ====================================================================== */ + /* other variable definitions */ + /* ====================================================================== */ + + int perm [B_N+1] ; /* note the size is N+1 */ + int stats [COLAMD_STATS] ; /* for colamd and symamd output statistics */ + + int row, col, pp, length, ok ; + + /* ====================================================================== */ + /* dump the input matrix A */ + /* ====================================================================== */ + + printf ("colamd %d-by-%d input matrix:\n", A_NROW, A_NCOL) ; + for (col = 0 ; col < A_NCOL ; col++) + { + length = p [col+1] - p [col] ; + printf ("Column %d, with %d entries:\n", col, length) ; + for (pp = p [col] ; pp < p [col+1] ; pp++) + { + row = A [pp] ; + printf (" row %d\n", row) ; + } + } + + /* ====================================================================== */ + /* order the matrix. Note that this destroys A and overwrites p */ + /* ====================================================================== */ + + ok = colamd (A_NROW, A_NCOL, ALEN, A, p, (double *) NULL, stats) ; + colamd_report (stats) ; + + if (!ok) + { + printf ("colamd error!\n") ; + exit (1) ; + } + + /* ====================================================================== */ + /* print the column ordering */ + /* ====================================================================== */ + + printf ("colamd column ordering:\n") ; + printf ("1st column: %d\n", p [0]) ; + printf ("2nd column: %d\n", p [1]) ; + printf ("3rd column: %d\n", p [2]) ; + printf ("4th column: %d\n", p [3]) ; + + /* ====================================================================== */ + /* dump the strictly lower triangular part of symmetric input matrix B */ + /* ====================================================================== */ + + printf ("\n\nsymamd %d-by-%d input matrix:\n", B_N, B_N) ; + printf ("Entries in strictly lower triangular part:\n") ; + for (col = 0 ; col < B_N ; col++) + { + length = q [col+1] - q [col] ; + printf ("Column %d, with %d entries:\n", col, length) ; + for (pp = q [col] ; pp < q [col+1] ; pp++) + { + row = B [pp] ; + printf (" row %d\n", row) ; + } + } + + /* ====================================================================== */ + /* order the matrix B. Note that this does not modify B or q. */ + /* ====================================================================== */ + + ok = symamd (B_N, B, q, perm, (double *) NULL, stats, &calloc, &free) ; + symamd_report (stats) ; + + if (!ok) + { + printf ("symamd error!\n") ; + exit (1) ; + } + + /* ====================================================================== */ + /* print the symmetric ordering */ + /* ====================================================================== */ + + printf ("symamd column ordering:\n") ; + printf ("1st row/column: %d\n", perm [0]) ; + printf ("2nd row/column: %d\n", perm [1]) ; + printf ("3rd row/column: %d\n", perm [2]) ; + printf ("4th row/column: %d\n", perm [3]) ; + printf ("5th row/column: %d\n", perm [4]) ; + + exit (0) ; +} + diff --git a/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.out b/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.out new file mode 100644 index 0000000..f509ea0 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Demo/colamd_example.out @@ -0,0 +1,50 @@ +colamd 5-by-4 input matrix: +Column 0, with 3 entries: + row 0 + row 1 + row 4 +Column 1, with 2 entries: + row 2 + row 4 +Column 2, with 4 entries: + row 0 + row 1 + row 2 + row 3 +Column 3, with 2 entries: + row 1 + row 3 + +colamd version 2.7, Dec 7, 2011: OK. +colamd: number of dense or empty rows ignored: 0 +colamd: number of dense or empty columns ignored: 0 +colamd: number of garbage collections performed: 0 +colamd column ordering: +1st column: 1 +2nd column: 0 +3rd column: 2 +4th column: 3 + + +symamd 5-by-5 input matrix: +Entries in strictly lower triangular part: +Column 0, with 1 entries: + row 1 +Column 1, with 2 entries: + row 2 + row 3 +Column 2, with 0 entries: +Column 3, with 1 entries: + row 4 +Column 4, with 0 entries: + +symamd version 2.7, Dec 7, 2011: OK. +symamd: number of dense or empty rows ignored: 0 +symamd: number of dense or empty columns ignored: 0 +symamd: number of garbage collections performed: 0 +symamd column ordering: +1st row/column: 0 +2nd row/column: 2 +3rd row/column: 1 +4th row/column: 3 +5th row/column: 4 diff --git a/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.c b/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.c new file mode 100644 index 0000000..9ff9aeb --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.c @@ -0,0 +1,185 @@ +/* ========================================================================== */ +/* === colamd and symamd example ============================================ */ +/* ========================================================================== */ + +/* COLAMD / SYMAMD example + + colamd example of use, to order the columns of a 5-by-4 matrix with + 11 nonzero entries in the following nonzero pattern, with default knobs. + + x 0 x 0 + x 0 x x + 0 x x 0 + 0 0 x x + x x 0 0 + + symamd example of use, to order the rows and columns of a 5-by-5 + matrix with 13 nonzero entries in the following nonzero pattern, + with default knobs. + + x x 0 0 0 + x x x x 0 + 0 x x 0 0 + 0 x 0 x x + 0 0 0 x x + + (where x denotes a nonzero value). + + + See http://www.cise.ufl.edu/research/sparse/colamd/ (the colamd.c file) + for the routines this program calls, and for the License. +*/ + +/* ========================================================================== */ + +#include +#include "colamd.h" + +#define A_NNZ 11 +#define A_NROW 5 +#define A_NCOL 4 +#define ALEN 150 + +#define B_NNZ 4 +#define B_N 5 + +/* define UF_long */ +#include "UFconfig.h" + +int main (void) +{ + + /* ====================================================================== */ + /* input matrix A definition */ + /* ====================================================================== */ + + UF_long A [ALEN] = { + + 0, 1, 4, /* row indices of nonzeros in column 0 */ + 2, 4, /* row indices of nonzeros in column 1 */ + 0, 1, 2, 3, /* row indices of nonzeros in column 2 */ + 1, 3} ; /* row indices of nonzeros in column 3 */ + + UF_long p [ ] = { + + 0, /* column 0 is in A [0..2] */ + 3, /* column 1 is in A [3..4] */ + 5, /* column 2 is in A [5..8] */ + 9, /* column 3 is in A [9..10] */ + A_NNZ} ; /* number of nonzeros in A */ + + /* ====================================================================== */ + /* input matrix B definition */ + /* ====================================================================== */ + + UF_long B [ ] = { /* Note: only strictly lower triangular part */ + /* is included, since symamd ignores the */ + /* diagonal and upper triangular part of B. */ + + 1, /* row indices of nonzeros in column 0 */ + 2, 3, /* row indices of nonzeros in column 1 */ + /* row indices of nonzeros in column 2 (none) */ + 4 /* row indices of nonzeros in column 3 */ + } ; /* row indices of nonzeros in column 4 (none) */ + + UF_long q [ ] = { + + 0, /* column 0 is in B [0] */ + 1, /* column 1 is in B [1..2] */ + 3, /* column 2 is empty */ + 3, /* column 3 is in B [3] */ + 4, /* column 4 is empty */ + B_NNZ} ; /* number of nonzeros in strictly lower B */ + + /* ====================================================================== */ + /* other variable definitions */ + /* ====================================================================== */ + + UF_long perm [B_N+1] ; /* note the size is N+1 */ + UF_long stats [COLAMD_STATS] ;/* for colamd and symamd output statistics */ + + UF_long row, col, pp, length, ok ; + + /* ====================================================================== */ + /* dump the input matrix A */ + /* ====================================================================== */ + + printf ("colamd %d-by-%d input matrix:\n", A_NROW, A_NCOL) ; + for (col = 0 ; col < A_NCOL ; col++) + { + length = p [col+1] - p [col] ; + printf ("Column %ld, with %ld entries:\n", col, length) ; + for (pp = p [col] ; pp < p [col+1] ; pp++) + { + row = A [pp] ; + printf (" row %ld\n", row) ; + } + } + + /* ====================================================================== */ + /* order the matrix. Note that this destroys A and overwrites p */ + /* ====================================================================== */ + + ok = colamd_l (A_NROW, A_NCOL, ALEN, A, p, (double *) NULL, stats) ; + colamd_l_report (stats) ; + + if (!ok) + { + printf ("colamd error!\n") ; + exit (1) ; + } + + /* ====================================================================== */ + /* print the column ordering */ + /* ====================================================================== */ + + printf ("colamd_l column ordering:\n") ; + printf ("1st column: %ld\n", p [0]) ; + printf ("2nd column: %ld\n", p [1]) ; + printf ("3rd column: %ld\n", p [2]) ; + printf ("4th column: %ld\n", p [3]) ; + + /* ====================================================================== */ + /* dump the strictly lower triangular part of symmetric input matrix B */ + /* ====================================================================== */ + + printf ("\n\nsymamd_l %d-by-%d input matrix:\n", B_N, B_N) ; + printf ("Entries in strictly lower triangular part:\n") ; + for (col = 0 ; col < B_N ; col++) + { + length = q [col+1] - q [col] ; + printf ("Column %ld, with %ld entries:\n", col, length) ; + for (pp = q [col] ; pp < q [col+1] ; pp++) + { + row = B [pp] ; + printf (" row %ld\n", row) ; + } + } + + /* ====================================================================== */ + /* order the matrix B. Note that this does not modify B or q. */ + /* ====================================================================== */ + + ok = symamd_l (B_N, B, q, perm, (double *) NULL, stats, &calloc, &free) ; + symamd_l_report (stats) ; + + if (!ok) + { + printf ("symamd error!\n") ; + exit (1) ; + } + + /* ====================================================================== */ + /* print the symmetric ordering */ + /* ====================================================================== */ + + printf ("symamd_l column ordering:\n") ; + printf ("1st row/column: %ld\n", perm [0]) ; + printf ("2nd row/column: %ld\n", perm [1]) ; + printf ("3rd row/column: %ld\n", perm [2]) ; + printf ("4th row/column: %ld\n", perm [3]) ; + printf ("5th row/column: %ld\n", perm [4]) ; + + exit (0) ; +} + diff --git a/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.out b/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.out new file mode 100644 index 0000000..03033ed --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Demo/colamd_l_example.out @@ -0,0 +1,50 @@ +colamd 5-by-4 input matrix: +Column 0, with 3 entries: + row 0 + row 1 + row 4 +Column 1, with 2 entries: + row 2 + row 4 +Column 2, with 4 entries: + row 0 + row 1 + row 2 + row 3 +Column 3, with 2 entries: + row 1 + row 3 + +colamd version 2.7, Dec 7, 2011: OK. +colamd: number of dense or empty rows ignored: 0 +colamd: number of dense or empty columns ignored: 0 +colamd: number of garbage collections performed: 0 +colamd_l column ordering: +1st column: 1 +2nd column: 0 +3rd column: 2 +4th column: 3 + + +symamd_l 5-by-5 input matrix: +Entries in strictly lower triangular part: +Column 0, with 1 entries: + row 1 +Column 1, with 2 entries: + row 2 + row 3 +Column 2, with 0 entries: +Column 3, with 1 entries: + row 4 +Column 4, with 0 entries: + +symamd version 2.7, Dec 7, 2011: OK. +symamd: number of dense or empty rows ignored: 0 +symamd: number of dense or empty columns ignored: 0 +symamd: number of garbage collections performed: 0 +symamd_l column ordering: +1st row/column: 0 +2nd row/column: 2 +3rd row/column: 1 +4th row/column: 3 +5th row/column: 4 diff --git a/OpenDSSC/klusolve/COLAMD/Doc/ChangeLog b/OpenDSSC/klusolve/COLAMD/Doc/ChangeLog new file mode 100644 index 0000000..67015c2 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Doc/ChangeLog @@ -0,0 +1,141 @@ +Dec 7, 2011: version 2.7.4 + + * fixed the Makefile to better align with CFLAGS and other standards + +Jan 25, 2011: version 2.7.3 + + * minor fix to "make install" + +Nov 30, 2009: version 2.7.2 + + * added "make install" and "make uninstall" + +May 31, 2007: version 2.7.0 + + * ported to 64-bit MATLAB + + * subdirectories added (Source/, Include/, Lib/, Doc/, MATLAB/, Demo/) + +Dec 12, 2006, version 2.5.2 + + * minor MATLAB cleanup. MATLAB functions renamed colamd2 and symamd2, + so that they do not conflict with the built-in versions. Note that + the MATLAB built-in functions colamd and symamd are identical to + the colamd and symamd functions here. + +Aug 31, 2006: Version 2.5.1 + + * minor change to colamd.m and symamd.m, to use etree instead + of sparsfun. + +Apr. 30, 2006: Version 2.5 + + * colamd_recommended modified, to do more careful integer overflow + checking. It now returns size_t, not int. colamd_l_recommended + also returns size_t. A zero is returned if an error occurs. A + postive return value denotes success. In v2.4 and earlier, + -1 was returned on error (an int or long). + + * long replaced with UF_long integer, which is long except on WIN64. + +Nov 15, 2005: + + * minor editting of comments; version number (2.4) unchanged. + +Changes from Version 2.3 to 2.4 (Aug 30, 2005) + + * Makefile now relies on ../UFconfig/UFconfig.mk + + * changed the dense row/col detection. The meaning of the knobs + has thus changed. + + * added an option to turn off aggressive absorption. It was + always on in versions 2.3 and earlier. + + * added a #define'd version number + + * added a function pointer (colamd_printf) for COLAMD's printing. + + * added a -DNPRINT option, to turn off printing at compile-time. + + * added a check for integer overflow in colamd_recommended + + * minor changes to allow for more simpler 100% test coverage + + * bug fix. If symamd v2.3 fails to allocate its copy of the input + matrix, then it erroneously frees a calloc'd workspace twice. + This bug has no effect on the MATLAB symamd mexFunction, since + mxCalloc terminates the mexFunction if it fails to allocate + memory. Similarly, UMFPACK is not affected because it does not + use symamd. The bug has no effect on the colamd ordering + routine in v2.3. + +Changes from Version 2.2 to 2.3 (Sept. 8, 2003) + + * removed the call to the MATLAB spparms ('spumoni') function. + This can take a lot of time if you are ordering many small + matrices. Only affects the MATLAB interface (colamdmex.c, + symamdmex.c, colamdtestmex.c, and symamdtestmex.c). The + usage of the optional 2nd argument to the colamd and symamd + mexFunctions was changed accordingly. + +Changes from Version 2.1 to 2.2 (Sept. 23, 2002) + + * extensive testing routines added (colamd_test.m, colamdtestmex.c, + and symamdtestmex.c), and the Makefile modified accordingly. + + * a few typos in the comments corrected + + * use of the MATLAB "flops" command removed from colamd_demo, and an + m-file routine luflops.m added. + + * an explicit typecast from unsigned to int added, for COLAMD_C and + COLAMD_R in colamd.h. + + * #include added to colamd_example.c + + +Changes from Version 2.0 to 2.1 (May 4, 2001) + + * TRUE and FALSE are predefined on some systems, so they are defined + here only if not already defined. + + * web site changed + + * UNIX Makefile modified, to handle the case if "." is not in your path. + + +Changes from Version 1.0 to 2.0 (January 31, 2000) + + No bugs were found in version 1.1. These changes merely add new + functionality. + + * added the COLAMD_RECOMMENDED (nnz, n_row, n_col) macro. + + * moved the output statistics, from A, to a separate output argument. + The arguments changed for the C-callable routines. + + * added colamd_report and symamd_report. + + * added a C-callable symamd routine. Formerly, symamd was only + available as a mexFunction from MATLAB. + + * added error-checking to symamd. Formerly, it assumed its input + was error-free. + + * added the optional stats and knobs arguments to the symamd mexFunction + + * deleted colamd_help. A help message is still available from + "help colamd" and "help symamd" in MATLAB. + + * deleted colamdtree.m and symamdtree.m. Now, colamd.m and symamd.m + also do the elimination tree post-ordering. The Version 1.1 + colamd and symamd mexFunctions, which do not do the post- + ordering, are now visible as colamdmex and symamdmex from + MATLAB. Essentialy, the post-ordering is now the default + behavior of colamd.m and symamd.m, to match the behavior of + colmmd and symmmd. The post-ordering is only available in the + MATLAB interface, not the C-callable interface. + + * made a slight change to the dense row/column detection in symamd, + to match the stated specifications. diff --git a/OpenDSSC/klusolve/COLAMD/Doc/lesser.txt b/OpenDSSC/klusolve/COLAMD/Doc/lesser.txt new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/OpenDSSC/klusolve/COLAMD/Include/colamd.h b/OpenDSSC/klusolve/COLAMD/Include/colamd.h new file mode 100644 index 0000000..91665ce --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Include/colamd.h @@ -0,0 +1,255 @@ +/* ========================================================================== */ +/* === colamd/symamd prototypes and definitions ============================= */ +/* ========================================================================== */ + +/* COLAMD / SYMAMD include file + + You must include this file (colamd.h) in any routine that uses colamd, + symamd, or the related macros and definitions. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Notice: + + Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. + + THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + + Permission is hereby granted to use, copy, modify, and/or distribute + this program, provided that the Copyright, this License, and the + Availability of the original version is retained on all copies and made + accessible to the end-user of any code or package that includes COLAMD + or any modified version of COLAMD. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.h + file. It is required by the colamd.c, colamdmex.c, and symamdmex.c + files, and by any C code that calls the routines whose prototypes are + listed below, or that uses the colamd/symamd definitions listed below. + +*/ + +#ifndef COLAMD_H +#define COLAMD_H + +/* make it easy for C++ programs to include COLAMD */ +#ifdef __cplusplus +extern "C" { +#endif + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include + +/* ========================================================================== */ +/* === COLAMD version ======================================================= */ +/* ========================================================================== */ + +/* COLAMD Version 2.4 and later will include the following definitions. + * As an example, to test if the version you are using is 2.4 or later: + * + * #ifdef COLAMD_VERSION + * if (COLAMD_VERSION >= COLAMD_VERSION_CODE (2,4)) ... + * #endif + * + * This also works during compile-time: + * + * #if defined(COLAMD_VERSION) && (COLAMD_VERSION >= COLAMD_VERSION_CODE (2,4)) + * printf ("This is version 2.4 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + * + * Versions 2.3 and earlier of COLAMD do not include a #define'd version number. + */ + +#define COLAMD_DATE "Dec 7, 2011" +#define COLAMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define COLAMD_MAIN_VERSION 2 +#define COLAMD_SUB_VERSION 7 +#define COLAMD_SUBSUB_VERSION 4 +#define COLAMD_VERSION \ + COLAMD_VERSION_CODE(COLAMD_MAIN_VERSION,COLAMD_SUB_VERSION) + +/* ========================================================================== */ +/* === Knob and statistics definitions ====================================== */ +/* ========================================================================== */ + +/* size of the knobs [ ] array. Only knobs [0..1] are currently used. */ +#define COLAMD_KNOBS 20 + +/* number of output statistics. Only stats [0..6] are currently used. */ +#define COLAMD_STATS 20 + +/* knobs [0] and stats [0]: dense row knob and output statistic. */ +#define COLAMD_DENSE_ROW 0 + +/* knobs [1] and stats [1]: dense column knob and output statistic. */ +#define COLAMD_DENSE_COL 1 + +/* knobs [2]: aggressive absorption */ +#define COLAMD_AGGRESSIVE 2 + +/* stats [2]: memory defragmentation count output statistic */ +#define COLAMD_DEFRAG_COUNT 2 + +/* stats [3]: colamd status: zero OK, > 0 warning or notice, < 0 error */ +#define COLAMD_STATUS 3 + +/* stats [4..6]: error info, or info on jumbled columns */ +#define COLAMD_INFO1 4 +#define COLAMD_INFO2 5 +#define COLAMD_INFO3 6 + +/* error codes returned in stats [3]: */ +#define COLAMD_OK (0) +#define COLAMD_OK_BUT_JUMBLED (1) +#define COLAMD_ERROR_A_not_present (-1) +#define COLAMD_ERROR_p_not_present (-2) +#define COLAMD_ERROR_nrow_negative (-3) +#define COLAMD_ERROR_ncol_negative (-4) +#define COLAMD_ERROR_nnz_negative (-5) +#define COLAMD_ERROR_p0_nonzero (-6) +#define COLAMD_ERROR_A_too_small (-7) +#define COLAMD_ERROR_col_length_negative (-8) +#define COLAMD_ERROR_row_index_out_of_bounds (-9) +#define COLAMD_ERROR_out_of_memory (-10) +#define COLAMD_ERROR_internal_error (-999) + + +/* ========================================================================== */ +/* === Prototypes of user-callable routines ================================= */ +/* ========================================================================== */ + +/* define UF_long */ +#include "UFconfig.h" + +size_t colamd_recommended /* returns recommended value of Alen, */ + /* or 0 if input arguments are erroneous */ +( + int nnz, /* nonzeros in A */ + int n_row, /* number of rows in A */ + int n_col /* number of columns in A */ +) ; + +size_t colamd_l_recommended /* returns recommended value of Alen, */ + /* or 0 if input arguments are erroneous */ +( + UF_long nnz, /* nonzeros in A */ + UF_long n_row, /* number of rows in A */ + UF_long n_col /* number of columns in A */ +) ; + +void colamd_set_defaults /* sets default parameters */ +( /* knobs argument is modified on output */ + double knobs [COLAMD_KNOBS] /* parameter settings for colamd */ +) ; + +void colamd_l_set_defaults /* sets default parameters */ +( /* knobs argument is modified on output */ + double knobs [COLAMD_KNOBS] /* parameter settings for colamd */ +) ; + +int colamd /* returns (1) if successful, (0) otherwise*/ +( /* A and p arguments are modified on output */ + int n_row, /* number of rows in A */ + int n_col, /* number of columns in A */ + int Alen, /* size of the array A */ + int A [], /* row indices of A, of size Alen */ + int p [], /* column pointers of A, of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameter settings for colamd */ + int stats [COLAMD_STATS] /* colamd output statistics and error codes */ +) ; + +UF_long colamd_l /* returns (1) if successful, (0) otherwise*/ +( /* A and p arguments are modified on output */ + UF_long n_row, /* number of rows in A */ + UF_long n_col, /* number of columns in A */ + UF_long Alen, /* size of the array A */ + UF_long A [], /* row indices of A, of size Alen */ + UF_long p [], /* column pointers of A, of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameter settings for colamd */ + UF_long stats [COLAMD_STATS]/* colamd output statistics and error codes */ +) ; + +int symamd /* return (1) if OK, (0) otherwise */ +( + int n, /* number of rows and columns of A */ + int A [], /* row indices of A */ + int p [], /* column pointers of A */ + int perm [], /* output permutation, size n_col+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + int stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) ; + +UF_long symamd_l /* return (1) if OK, (0) otherwise */ +( + UF_long n, /* number of rows and columns of A */ + UF_long A [], /* row indices of A */ + UF_long p [], /* column pointers of A */ + UF_long perm [], /* output permutation, size n_col+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + UF_long stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) ; + +void colamd_report +( + int stats [COLAMD_STATS] +) ; + +void colamd_l_report +( + UF_long stats [COLAMD_STATS] +) ; + +void symamd_report +( + int stats [COLAMD_STATS] +) ; + +void symamd_l_report +( + UF_long stats [COLAMD_STATS] +) ; + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN int (*colamd_printf) (const char *, ...) ; + +#ifdef __cplusplus +} +#endif + +#endif /* COLAMD_H */ diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/Contents.m b/OpenDSSC/klusolve/COLAMD/MATLAB/Contents.m new file mode 100644 index 0000000..960fd14 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/Contents.m @@ -0,0 +1,19 @@ +% COLAMD, column approximate minimum degree ordering +% +% Primary: +% colamd2 - Column approximate minimum degree permutation. +% symamd2 - SYMAMD Symmetric approximate minimum degree permutation. +% +% helper and test functions: +% colamd_demo - demo for colamd, column approx minimum degree ordering algorithm +% colamd_make - compiles COLAMD2 and SYMAMD2 for MATLAB +% colamd_make - compiles and installs COLAMD2 and SYMAMD2 for MATLAB +% colamd_test - test colamd2 and symamd2 +% luflops - compute the flop count for sparse LU factorization +% +% Example: +% p = colamd2 (A) +% + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/Makefile b/OpenDSSC/klusolve/COLAMD/MATLAB/Makefile new file mode 100644 index 0000000..ee9415f --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/Makefile @@ -0,0 +1,35 @@ +# COLAMD Makefile for MATLAB mexFunctions + +default: colamd2 symamd2 + +include ../../UFconfig/UFconfig.mk + +I = -I../../UFconfig -I../Include + +INC = ../Include/colamd.h ../../UFconfig/UFconfig.h + +SRC = ../Source/colamd.c ../Source/colamd_global.c + +MX = $(MEX) -DDLONG $(I) + +# Compiles the MATLAB-callable routines +mex: colamd2 symamd2 + +symamd2: symamdmex.c $(INC) $(SRC) + $(MX) -output symamd2mex symamdmex.c $(SRC) + +colamd2: colamdmex.c $(INC) $(SRC) + $(MX) -output colamd2mex colamdmex.c $(SRC) + +# Compiles the extensive test code +test: mex colamdtestmex.c symamdtestmex.c $(INC) $(SRC) + $(MX) colamdtestmex.c $(SRC) + $(MX) symamdtestmex.c $(SRC) + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) *.mex* *.dll diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamd2.m b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd2.m new file mode 100644 index 0000000..9916cc7 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd2.m @@ -0,0 +1,87 @@ +function [p,stats] = colamd2 (S, knobs) +%COLAMD2 Column approximate minimum degree permutation. +% P = COLAMD2(S) returns the column approximate minimum degree permutation +% vector for the sparse matrix S. For a non-symmetric matrix S, S(:,P) +% tends to have sparser LU factors than S. The Cholesky factorization of +% S(:,P)'*S(:,P) also tends to be sparser than that of S'*S. The ordering +% is followed by a column elimination tree post-ordering. +% +% Note that this function is the source code for the built-in MATLAB colamd +% function. It has been renamed here to colamd2 to avoid a filename clash. +% colamd and colamd2 are identical. +% +% See also COLAMD, AMD, SYMAMD, SYMAMD2. +% +% Example: +% P = colamd2 (S) +% [P, stats] = colamd2 (S, knobs) +% +% knobs is an optional one- to three-element input vector. If S is m-by-n, +% then rows with more than max(16,knobs(1)*sqrt(n)) entries are ignored. +% Columns with more than max(16,knobs(2)*sqrt(min(m,n))) entries are +% removed prior to ordering, and ordered last in the output permutation P. +% Only completely dense rows or columns are removed if knobs(1) and knobs(2) +% are < 0, respectively. If knobs(3) is nonzero, stats and knobs are +% printed. The default is knobs = [10 10 0]. Note that knobs differs from +% earlier versions of colamd. + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. +% +% Acknowledgements: This work was supported by the National Science +% Foundation, under grants DMS-9504974 and DMS-9803599. + +%------------------------------------------------------------------------------- +% Perform the colamd ordering: +%------------------------------------------------------------------------------- + +if (nargout <= 1 & nargin == 1) %#ok + p = colamd2mex (S) ; +elseif (nargout <= 1 & nargin == 2) %#ok + p = colamd2mex (S, knobs) ; +elseif (nargout == 2 & nargin == 1) %#ok + [p, stats] = colamd2mex (S) ; +elseif (nargout == 2 & nargin == 2) %#ok + [p, stats] = colamd2mex (S, knobs) ; +else + error ('colamd: incorrect number of input and/or output arguments') ; +end + +%------------------------------------------------------------------------------- +% column elimination tree post-ordering: +%------------------------------------------------------------------------------- + +[ignore, q] = etree (S (:,p), 'col') ; +p = p (q) ; + +% stats is an optional 20-element output vector that provides data about the +% ordering and the validity of the input matrix S. Ordering statistics are +% in stats (1:3). stats (1) and stats (2) are the number of dense or empty +% rows and columns ignored by COLAMD and stats (3) is the number of +% garbage collections performed on the internal data structure used by +% COLAMD (roughly of size 2.2*nnz(S) + 4*m + 7*n integers). +% +% MATLAB built-in functions are intended to generate valid sparse matrices, +% with no duplicate entries, with ascending row indices of the nonzeros +% in each column, with a non-negative number of entries in each column (!) +% and so on. If a matrix is invalid, then COLAMD may or may not be able +% to continue. If there are duplicate entries (a row index appears two or +% more times in the same column) or if the row indices in a column are out +% of order, then COLAMD can correct these errors by ignoring the duplicate +% entries and sorting each column of its internal copy of the matrix S (the +% input matrix S is not repaired, however). If a matrix is invalid in other +% ways then COLAMD cannot continue, an error message is printed, and no +% output arguments (P or stats) are returned. COLAMD is thus a simple way +% to check a sparse matrix to see if it's valid. +% +% stats (4:7) provide information if COLAMD was able to continue. The +% matrix is OK if stats (4) is zero, or 1 if invalid. stats (5) is the +% rightmost column index that is unsorted or contains duplicate entries, +% or zero if no such column exists. stats (6) is the last seen duplicate +% or out-of-order row index in the column index given by stats (5), or zero +% if no such row index exists. stats (7) is the number of duplicate or +% out-of-order row indices. +% +% stats (8:20) is always zero in the current version of COLAMD (reserved +% for future use). + diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_demo.m b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_demo.m new file mode 100644 index 0000000..f2fd442 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_demo.m @@ -0,0 +1,179 @@ +%COLAMD_DEMO demo for colamd, column approx minimum degree ordering algorithm +% +% Example: +% colamd_demo +% +% The following m-files and mexFunctions provide alternative sparse matrix +% ordering methods for MATLAB. They are typically faster (sometimes much +% faster) and typically provide better orderings than their MATLAB counterparts: +% +% colamd a replacement for colmmd. +% +% Typical usage: p = colamd (A) ; +% +% symamd a replacement for symmmd. Based on colamd. +% +% Typical usage: p = symamd (A) ; +% +% For a description of the methods used, see the colamd.c file. +% +% http://www.cise.ufl.edu/research/sparse/colamd/ +% +% See also colamd, symamd + +% Minor changes: in MATLAB 7, symmmd and colmmd are flagged as "obsolete". +% This demo checks if they exist, so it should still work when they are removed. + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. + +%------------------------------------------------------------------------------- +% Print the introduction, the help info, and compile the mexFunctions +%------------------------------------------------------------------------------- + +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Colamd2/symamd2 demo.') ; +fprintf (1, '\n-----------------------------------------------------------\n') ; +help colamd_demo ; + +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Colamd help information:') ; +fprintf (1, '\n-----------------------------------------------------------\n') ; +help colamd2 ; + +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Symamd help information:') ; +fprintf (1, '\n-----------------------------------------------------------\n') ; +help symamd2 ; + +%------------------------------------------------------------------------------- +% Solving Ax=b +%------------------------------------------------------------------------------- + +n = 100 ; +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Solving Ax=b for a small %d-by-%d random matrix:', n, n) ; +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, '\nNote: Random sparse matrices are AWFUL test cases.\n') ; +fprintf (1, 'They''re just easy to generate in a demo.\n') ; + +% set up the system + +rand ('state', 0) ; +randn ('state', 0) ; +spparms ('default') ; +A = sprandn (n, n, 5/n) + speye (n) ; +b = (1:n)' ; + +fprintf (1, '\n\nSolving via lu (PAQ = LU), where Q is from colamd2:\n') ; +q = colamd2 (A) ; +I = speye (n) ; +Q = I (:, q) ; +[L,U,P] = lu (A*Q) ; +fl = luflops (L, U) ; +x = Q * (U \ (L \ (P * b))) ; +fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q): %d\n', fl) ; +fprintf (1, 'residual: %e\n', norm (A*x-b)); + +try + fprintf (1, '\n\nSolving via lu (PAQ = LU), where Q is from colmmd:\n') ; + q = colmmd (A) ; + I = speye (n) ; + Q = I (:, q) ; + [L,U,P] = lu (A*Q) ; + fl = luflops (L, U) ; + x = Q * (U \ (L \ (P * b))) ; + fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q): %d\n', fl) ; + fprintf (1, 'residual: %e\n', ... + norm (A*x-b)) ; +catch + fprintf (1, 'colmmd is obsolete; test skipped\n') ; +end + +fprintf (1, '\n\nSolving via lu (PA = LU), without regard for sparsity:\n') ; +[L,U,P] = lu (A) ; +fl = luflops (L, U) ; +x = U \ (L \ (P * b)) ; +fprintf (1, '\nFlop count for [L,U,P] = lu (A*Q): %d\n', fl) ; +fprintf (1, 'residual: %e\n', norm (A*x-b)); + +%------------------------------------------------------------------------------- +% Large demo for colamd2 +%------------------------------------------------------------------------------- + +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Large demo for colamd2 (symbolic analysis only):') ; +fprintf (1, '\n-----------------------------------------------------------\n') ; + +rand ('state', 0) ; +randn ('state', 0) ; +spparms ('default') ; +n = 1000 ; +fprintf (1, 'Generating a random %d-by-%d sparse matrix.\n', n, n) ; +A = sprandn (n, n, 5/n) + speye (n) ; + +fprintf (1, '\n\nUnordered matrix:\n') ; +lnz = symbfact (A, 'col') ; +fprintf (1, 'nz in Cholesky factors of A''A: %d\n', sum (lnz)) ; +fprintf (1, 'flop count for Cholesky of A''A: %d\n', sum (lnz.^2)) ; + +tic ; +p = colamd2 (A) ; +t = toc ; +lnz = symbfact (A (:,p), 'col') ; +fprintf (1, '\n\nColamd run time: %f\n', t) ; +fprintf (1, 'colamd2 ordering quality: \n') ; +fprintf (1, 'nz in Cholesky factors of A(:,p)''A(:,p): %d\n', sum (lnz)) ; +fprintf (1, 'flop count for Cholesky of A(:,p)''A(:,p): %d\n', sum (lnz.^2)) ; + +try + tic ; + p = colmmd (A) ; + t = toc ; + lnz = symbfact (A (:,p), 'col') ; + fprintf (1, '\n\nColmmd run time: %f\n', t) ; + fprintf (1, 'colmmd ordering quality: \n') ; + fprintf (1, 'nz in Cholesky factors of A(:,p)''A(:,p): %d\n', sum (lnz)) ; + fprintf (1, 'flop count for Cholesky of A(:,p)''A(:,p): %d\n', ... + sum (lnz.^2)) ; +catch + fprintf (1, 'colmmd is obsolete; test skipped\n') ; +end + +%------------------------------------------------------------------------------- +% Large demo for symamd2 +%------------------------------------------------------------------------------- + +fprintf (1, '\n-----------------------------------------------------------\n') ; +fprintf (1, 'Large demo for symamd2 (symbolic analysis only):') ; +fprintf (1, '\n-----------------------------------------------------------\n') ; + +fprintf (1, 'Generating a random symmetric %d-by-%d sparse matrix.\n', n, n) ; +A = A+A' ; + +fprintf (1, '\n\nUnordered matrix:\n') ; +lnz = symbfact (A, 'sym') ; +fprintf (1, 'nz in Cholesky factors of A: %d\n', sum (lnz)) ; +fprintf (1, 'flop count for Cholesky of A: %d\n', sum (lnz.^2)) ; + +tic ; +p = symamd2 (A) ; +t = toc ; +lnz = symbfact (A (p,p), 'sym') ; +fprintf (1, '\n\nSymamd run time: %f\n', t) ; +fprintf (1, 'symamd2 ordering quality: \n') ; +fprintf (1, 'nz in Cholesky factors of A(p,p): %d\n', sum (lnz)) ; +fprintf (1, 'flop count for Cholesky of A(p,p): %d\n', sum (lnz.^2)) ; + +try + tic ; + p = symmmd (A) ; + t = toc ; + lnz = symbfact (A (p,p), 'sym') ; + fprintf (1, '\n\nSymmmd run time: %f\n', t) ; + fprintf (1, 'symmmd ordering quality: \n') ; + fprintf (1, 'nz in Cholesky factors of A(p,p): %d\n', sum (lnz)) ; + fprintf (1, 'flop count for Cholesky of A(p,p): %d\n', sum (lnz.^2)) ; +catch + fprintf (1, 'symmmd is obsolete\n') ; +end diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_install.m b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_install.m new file mode 100644 index 0000000..7ac0110 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_install.m @@ -0,0 +1,18 @@ +function colamd_install +%COLAMD_MAKE to compile and install the colamd2 and symamd2 mexFunction. +% Your current directory must be COLAMD/MATLAB for this function to work. +% +% Example: +% colamd_install +% +% See also colamd2, symamd2. + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. + +colamd_make +addpath (pwd) +fprintf ('\nThe following path has been added. You may wish to add it\n') ; +fprintf ('permanently, using the MATLAB pathtool command.\n') ; +fprintf ('%s\n\n', pwd) ; +colamd_demo diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_make.m b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_make.m new file mode 100644 index 0000000..1748f9d --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_make.m @@ -0,0 +1,29 @@ +function colamd_make +%COLAMD_MAKE compiles COLAMD2 and SYMAMD2 for MATLAB +% +% Example: +% colamd_make +% +% See also colamd, symamd + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. + +details = 0 ; % 1 if details of each command are to be printed +d = '' ; +if (~isempty (strfind (computer, '64'))) + d = '-largeArrayDims' ; +end +src = '../Source/colamd.c ../Source/colamd_global.c' ; +cmd = sprintf ('mex -DDLONG -O %s -I../../UFconfig -I../Include -output ', d) ; +s = [cmd 'colamd2mex colamdmex.c ' src] ; +if (details) + fprintf ('%s\n', s) ; +end +eval (s) ; +s = [cmd 'symamd2mex symamdmex.c ' src] ; +if (details) + fprintf ('%s\n', s) ; +end +eval (s) ; +fprintf ('COLAMD2 and SYMAMD2 successfully compiled.\n') ; diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_test.m b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_test.m new file mode 100644 index 0000000..8addcb0 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamd_test.m @@ -0,0 +1,505 @@ +function colamd_test +%COLAMD_TEST test colamd2 and symamd2 +% Example: +% colamd_test +% +% COLAMD and SYMAMD testing function. Here we try to give colamd2 and symamd2 +% every possible type of matrix and erroneous input that they may encounter. +% We want either a valid permutation returned or we want them to fail +% gracefully. +% +% You are prompted as to whether or not the colamd2 and symand routines and +% the test mexFunctions are to be compiled. +% +% See also colamd2, symamd2 + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. + + +help colamd_test + + + fprintf ('Compiling colamd2, symamd2, and test mexFunctions.\n') ; + colamd_make ; + + d = '' ; + if (~isempty (strfind (computer, '64'))) + d = '-largeArrayDims' ; + end + cmd = sprintf ('mex -DDLONG -O %s -I../../UFconfig -I../Include ', d) ; + src = '../Source/colamd.c ../Source/colamd_global.c' ; + eval ([cmd 'colamdtestmex.c ' src]) ; + eval ([cmd 'symamdtestmex.c ' src]) ; + fprintf ('Done compiling.\n') ; + + +fprintf ('\nThe following codes will be tested:\n') ; +which colamd2 +which symamd2 +which colamd2mex +which symamd2mex +which colamdtestmex +which symamdtestmex + +fprintf ('\nStarting the tests. Please be patient.\n') ; + +h = waitbar (0, 'COLAMD test') ; + +rand ('state', 0) ; +randn ('state', 0) ; + +A = sprandn (500,500,0.4) ; + +p = colamd2 (A, [10 10 1]) ; check_perm (p, A) ; +p = colamd2 (A, [2 7 1]) ; check_perm (p, A) ; +p = symamd2 (A, [10 1]) ; check_perm (p, A) ; +p = symamd2 (A, [7 1]) ; check_perm (p, A) ; +p = symamd2 (A, [4 1]) ; check_perm (p, A) ; + + +fprintf ('Null matrices') ; +A = zeros (0,0) ; +A = sparse (A) ; + +[p, stats] = colamd2 (A, [10 10 0]) ; %#ok +check_perm (p, A) ; + +[p, stats] = symamd2 (A, [10 0]) ; %#ok +check_perm (p, A) ; + +A = zeros (0, 100) ; +A = sparse (A) ; +[p, stats] = colamd2 (A, [10 10 0]) ; %#ok +check_perm (p, A) ; + +A = zeros (100, 0) ; +A = sparse (A) ; +[p, stats] = colamd2 (A, [10 10 0]) ; +check_perm (p, A) ; +fprintf (' OK\n') ; + + +fprintf ('Matrices with a few dense row/cols\n') ; + +for trial = 1:20 + + waitbar (trial/20, h, 'COLAMD: with dense rows/cols') ; + + % random square unsymmetric matrix + A = rand_matrix (1000, 1000, 1, 10, 20) ; + + for tol = [0:.1:2 3:20 1e6] + + [p, stats] = colamd2 (A, [tol tol 0]) ; %#ok + check_perm (p, A) ; + + B = A + A' ; + [p, stats] = symamd2 (B, [tol 0]) ; %#ok + check_perm (p, A) ; + + [p, stats] = colamd2 (A, [tol 1 0]) ; %#ok + check_perm (p, A) ; + + [p, stats] = colamd2 (A, [1 tol 0]) ; %#ok + check_perm (p, A) ; + end +end +fprintf (' OK\n') ; + +fprintf ('General matrices\n') ; +for trial = 1:400 + + waitbar (trial/400, h, 'COLAMD: general') ; + + % matrix of random mtype + mtype = irand (3) ; + A = rand_matrix (2000, 2000, mtype, 0, 0) ; + p = colamd2 (A) ; + check_perm (p, A) ; + if (mtype == 3) + p = symamd2 (A) ; + check_perm (p, A) ; + end + +end +fprintf (' OK\n') ; + +fprintf ('Test error handling with invalid inputs\n') ; + +% Check different erroneous input. +for trial = 1:30 + + waitbar (trial/30, h, 'COLAMD: error handling') ; + + A = rand_matrix (1000, 1000, 2, 0, 0) ; + [m n] = size (A) ; + + for err = 1:13 + + p = Tcolamd (A, [n n 0 0 err]) ; + if (p ~= -1) %#ok + check_perm (p, A) ; + end + + if (err == 1) + % check different (valid) input args to colamd2 + p = Acolamd (A) ; + + p2 = Acolamd (A, [10 10 0 0 0]) ; + if (any (p ~= p2)) + error ('colamd2: mismatch 1!') ; + end + [p2 stats] = Acolamd (A) ; %#ok + if (any (p ~= p2)) + error ('colamd2: mismatch 2!') ; + end + [p2 stats] = Acolamd (A, [10 10 0 0 0]) ; + if (any (p ~= p2)) + error ('colamd2: mismatch 3!') ; + end + end + + B = A'*A ; + p = Tsymamd (B, [n 0 err]) ; + if (p ~= -1) %#ok + check_perm (p, A) ; + end + + if (err == 1) + + % check different (valid) input args to symamd2 + p = Asymamd (B) ; + check_perm (p, A) ; + p2 = Asymamd (B, [10 0 0]) ; + if (any (p ~= p2)) + error ('symamd2: mismatch 1!') ; + end + [p2 stats] = Asymamd (B) ; %#ok + if (any (p ~= p2)) + error ('symamd2: mismatch 2!') ; + end + [p2 stats] = Asymamd (B, [10 0 0]) ; %#ok + if (any (p ~= p2)) + error ('symamd2: mismatch 3!') ; + end + end + + end + +end +fprintf (' OK\n') ; + +fprintf ('Matrices with a few empty columns\n') ; + +for trial = 1:400 + + % some are square, some are rectangular + n = 0 ; + while (n < 5) + A = rand_matrix (1000, 1000, irand (2), 0, 0) ; + [m n] = size (A) ; + end + + % Add 5 null columns at random locations. + null_col = randperm (n) ; + null_col = sort (null_col (1:5)) ; + A (:, null_col) = 0 ; + + % Order the matrix and make sure that the null columns are ordered last. + [p, stats] = colamd2 (A, [1e6 1e6 0]) ; + check_perm (p, A) ; + +% if (stats (2) ~= 5) +% stats (2) +% error ('colamd2: wrong number of null columns') ; +% end + + % find all null columns in A + null_col = find (sum (spones (A), 1) == 0) ; + nnull = length (null_col) ; %#ok + if (any (null_col ~= p ((n-4):n))) + error ('colamd2: Null cols are not ordered last in natural order') ; + end + + +end +fprintf (' OK\n') ; + +fprintf ('Matrices with a few empty rows and columns\n') ; + +for trial = 1:400 + + waitbar (trial/400, h, 'COLAMD: with empty rows/cols') ; + + % symmetric matrices + n = 0 ; + while (n < 5) + A = rand_matrix (1000, 1000, 3, 0, 0) ; + [m n] = size (A) ; + end + + % Add 5 null columns and rows at random locations. + null_col = randperm (n) ; + null_col = sort (null_col (1:5)) ; + A (:, null_col) = 0 ; + A (null_col, :) = 0 ; + + % Order the matrix and make sure that the null rows/cols are ordered last. + [p,stats] = symamd2 (A, [10 0]) ; + check_perm (p, A) ; + + % find actual number of null rows and columns + Alo = tril (A, -1) ; + nnull = length (find (sum (Alo') == 0 & sum (Alo) == 0)) ; %#ok + + if (stats (2) ~= nnull | nnull < 5) %#ok + error ('symamd2: wrong number of null columns') ; + end + if (any (null_col ~= p ((n-4):n))) + error ('symamd2: Null cols are not ordered last in natural order') ; + end + +end +fprintf (' OK\n') ; + +fprintf ('Matrices with a few empty rows\n') ; + +% Test matrices with null rows inserted. + +for trial = 1:400 + + waitbar (trial/400, h, 'COLAMD: with null rows') ; + + m = 0 ; + while (m < 5) + A = rand_matrix (1000, 1000, 2, 0, 0) ; + [m n] = size (A) ; %#ok + end + + % Add 5 null rows at random locations. + null_row = randperm (m) ; + null_row = sort (null_row (1:5)) ; + A (null_row, :) = 0 ; + + p = colamd2 (A, [10 10 0]) ; + check_perm (p, A) ; + if (stats (1) ~= 5) + error ('colamd2: wrong number of null rows') ; + end + +end +fprintf (' OK\n') ; + + +fprintf ('\ncolamd2 and symamd2: all tests passed\n\n') ; +close (h) ; + +%------------------------------------------------------------------------------- + +function [p,stats] = Acolamd (S, knobs) +% Acolamd: compare colamd2 and Tcolamd results + +if (nargin < 3) + if (nargout == 1) + [p] = colamd2 (S) ; + [p1] = Tcolamd (S, [10 10 0 0 0]) ; + else + [p, stats] = colamd2 (S) ; + [p1, stats1] = Tcolamd (S, [10 10 0 0 0]) ; %#ok + end +else + if (nargout == 1) + [p] = colamd2 (S, knobs (1:3)) ; + [p1] = Tcolamd (S, knobs) ; + else + [p, stats] = colamd2 (S, knobs (1:3)) ; + [p1, stats1] = Tcolamd (S, knobs) ; %#ok + end +end + +check_perm (p, S) ; +check_perm (p1, S) ; + +if (any (p1 ~= p)) + error ('Acolamd mismatch!') ; +end + + +%------------------------------------------------------------------------------- + +function [p,stats] = Asymamd (S, knobs) +% Asymamd: compare symamd2 and Tsymamd results + +if (nargin < 3) + if (nargout == 1) + [p] = symamd2 (S) ; + [p1] = Tsymamd (S, [10 0 0]) ; + else + [p, stats] = symamd2 (S) ; + [p1, stats1] = Tsymamd (S, [10 0 0]) ; %#ok + end +else + if (nargout == 1) + [p] = symamd2 (S, knobs (1:2)) ; + [p1] = Tsymamd (S, knobs) ; + else + [p, stats] = symamd2 (S, knobs (1:2)) ; + [p1, stats1] = Tsymamd (S, knobs) ; %#ok + end +end + +if (any (p1 ~= p)) + error ('Asymamd mismatch!') ; +end + + +%------------------------------------------------------------------------------- + +function check_perm (p, A) +% check_perm: check for a valid permutation vector + +if (isempty (A) & isempty (p)) %#ok + % empty permutation vectors of empty matrices are OK + return +end + +if (isempty (p)) + error ('bad permutation: cannot be empty') ; +end + +[m n] = size (A) ; +[pm pn] = size (p) ; +if (pn == 1) + % force p to be a row vector + p = p' ; + [pm pn] = size (p) ; +end + +if (n ~= pn) + error ('bad permutation: wrong size') ; +end + +if (pm ~= 1) ; + % p must be a vector + error ('bad permutation: not a vector') ; +else + if (any (sort (p) - (1:pn))) + error ('bad permutation') ; + end +end + +%------------------------------------------------------------------------------- + +function i = irand (n) +% irand: return a random integer between 1 and n +i = min (n, 1 + floor (rand * n)) ; + +%------------------------------------------------------------------------------- + +function A = rand_matrix (nmax, mmax, mtype, drows, dcols) +% rand_matrix: return a random sparse matrix +% +% A = rand_matrix (nmax, mmax, mtype, drows, dcols) +% +% A binary matrix of random size, at most nmax-by-mmax, with drows dense rows +% and dcols dense columns. +% +% mtype 1: square unsymmetric (mmax is ignored) +% mtype 2: rectangular +% mtype 3: symmetric (mmax is ignored) + +n = irand (nmax) ; +if (mtype ~= 2) + % square + m = n ; +else + m = irand (mmax) ; +end + +A = sprand (m, n, 10 / max (m,n)) ; + +if (drows > 0) + % add dense rows + for k = 1:drows + i = irand (m) ; + nz = irand (n) ; + p = randperm (n) ; + p = p (1:nz) ; + A (i,p) = 1 ; + end +end + +if (dcols > 0) + % add dense cols + for k = 1:dcols + j = irand (n) ; + nz = irand (m) ; + p = randperm (m) ; + p = p (1:nz) ; + A (p,j) = 1 ; + end +end + +A = spones (A) ; + +% ensure that there are no empty columns +d = find (full (sum (A)) == 0) ; %#ok +A (m,d) = 1 ; %#ok + +% ensure that there are no empty rows +d = find (full (sum (A,2)) == 0) ; %#ok +A (d,n) = 1 ; %#ok + +if (mtype == 3) + % symmetric + A = A + A' + speye (n) ; +end + +A = spones (A) ; + +%------------------------------------------------------------------------------- + +function [p,stats] = Tcolamd (S, knobs) +% Tcolamd: run colamd2 in a testing mode + +if (nargout <= 1 & nargin == 1) %#ok + p = colamdtestmex (S) ; +elseif (nargout <= 1 & nargin == 2) %#ok + p = colamdtestmex (S, knobs) ; +elseif (nargout == 2 & nargin == 1) %#ok + [p, stats] = colamdtestmex (S) ; +elseif (nargout == 2 & nargin == 2) %#ok + [p, stats] = colamdtestmex (S, knobs) ; +else + error ('colamd2: incorrect number of input and/or output arguments') ; +end + +if (p (1) ~= -1) + [ignore, q] = etree (S (:,p), 'col') ; + p = p (q) ; + check_perm (p, S) ; +end + +%------------------------------------------------------------------------------- + +function [p, stats] = Tsymamd (S, knobs) +% Tsymamd: run symamd2 in a testing mode + +if (nargout <= 1 & nargin == 1) %#ok + p = symamdtestmex (S) ; +elseif (nargout <= 1 & nargin == 2) %#ok + p = symamdtestmex (S, knobs) ; +elseif (nargout == 2 & nargin == 1) %#ok + [p, stats] = symamdtestmex (S) ; +elseif (nargout == 2 & nargin == 2) %#ok + [p, stats] = symamdtestmex (S, knobs) ; +else + error ('symamd2: incorrect number of input and/or output arguments') ; +end + +if (p (1) ~= -1) + [ignore, q] = etree (S (p,p)) ; + p = p (q) ; + check_perm (p, S) ; +end diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamdmex.c b/OpenDSSC/klusolve/COLAMD/MATLAB/colamdmex.c new file mode 100644 index 0000000..93f16d5 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamdmex.c @@ -0,0 +1,220 @@ +/* ========================================================================== */ +/* === colamd mexFunction =================================================== */ +/* ========================================================================== */ + +/* Usage: + + P = colamd2 (A) ; + [ P, stats ] = colamd2 (A, knobs) ; + + see colamd.m for a description. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Notice: + + Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. + + See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c + file) for the License. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the http://www.cise.ufl.edu/research/sparse/colamd/colamdmex.c + file. It requires the colamd.c and colamd.h files. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include "mex.h" +#include "matrix.h" +#include +#include +#include "UFconfig.h" + +/* ========================================================================== */ +/* === colamd mexFunction =================================================== */ +/* ========================================================================== */ + +void mexFunction +( + /* === Parameters ======================================================= */ + + int nlhs, /* number of left-hand sides */ + mxArray *plhs [], /* left-hand side matrices */ + int nrhs, /* number of right--hand sides */ + const mxArray *prhs [] /* right-hand side matrices */ +) +{ + /* === Local variables ================================================== */ + + UF_long *A ; /* colamd's copy of the matrix, and workspace */ + UF_long *p ; /* colamd's copy of the column pointers */ + UF_long Alen ; /* size of A */ + UF_long n_col ; /* number of columns of A */ + UF_long n_row ; /* number of rows of A */ + UF_long nnz ; /* number of entries in A */ + UF_long full ; /* TRUE if input matrix full, FALSE if sparse */ + double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */ + double *out_perm ; /* output permutation vector */ + double *out_stats ; /* output stats vector */ + double *in_knobs ; /* input knobs vector */ + UF_long i ; /* loop counter */ + mxArray *Ainput ; /* input matrix handle */ + UF_long spumoni ; /* verbosity variable */ + UF_long stats [COLAMD_STATS] ; /* stats for colamd */ + + colamd_printf = mexPrintf ; /* COLAMD printf routine */ + + /* === Check inputs ===================================================== */ + + if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2) + { + mexErrMsgTxt ( + "colamd: incorrect number of input and/or output arguments") ; + } + + /* === Get knobs ======================================================== */ + + colamd_l_set_defaults (knobs) ; + spumoni = 0 ; + + /* check for user-passed knobs */ + if (nrhs == 2) + { + in_knobs = mxGetPr (prhs [1]) ; + i = mxGetNumberOfElements (prhs [1]) ; + if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ; + if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ; + if (i > 2) spumoni = (UF_long) (in_knobs [2] != 0) ; + } + + /* print knob settings if spumoni is set */ + if (spumoni) + { + mexPrintf ("\ncolamd version %d.%d, %s:\n", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ; + if (knobs [COLAMD_DENSE_ROW] >= 0) + { + mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))" + " entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ; + } + else + { + mexPrintf ("knobs(1): %g, only completely dense rows removed\n", + in_knobs [0]) ; + } + if (knobs [COLAMD_DENSE_COL] >= 0) + { + mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))" + " entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ; + } + else + { + mexPrintf ("knobs(2): %g, only completely dense columns removed\n", + in_knobs [1]) ; + } + mexPrintf ("knobs(3): %g, statistics and knobs printed\n", + in_knobs [2]) ; + } + + /* === If A is full, convert to a sparse matrix ========================= */ + + Ainput = (mxArray *) prhs [0] ; + if (mxGetNumberOfDimensions (Ainput) != 2) + { + mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ; + } + full = !mxIsSparse (Ainput) ; + if (full) + { + mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ; + } + + /* === Allocate workspace for colamd ==================================== */ + + /* get size of matrix */ + n_row = mxGetM (Ainput) ; + n_col = mxGetN (Ainput) ; + + /* get column pointer vector so we can find nnz */ + p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ; + (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ; + nnz = p [n_col] ; + Alen = (UF_long) colamd_l_recommended (nnz, n_row, n_col) ; + if (Alen == 0) + { + mexErrMsgTxt ("colamd: problem too large") ; + } + + /* === Copy input matrix into workspace ================================= */ + + A = (UF_long *) mxCalloc (Alen, sizeof (UF_long)) ; + (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ; + + if (full) + { + mxDestroyArray (Ainput) ; + } + + /* === Order the columns (destroys A) =================================== */ + + if (!colamd_l (n_row, n_col, Alen, A, p, knobs, stats)) + { + colamd_l_report (stats) ; + mexErrMsgTxt ("colamd error!") ; + } + mxFree (A) ; + + /* === Return the permutation vector ==================================== */ + + plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + for (i = 0 ; i < n_col ; i++) + { + /* colamd is 0-based, but MATLAB expects this to be 1-based */ + out_perm [i] = p [i] + 1 ; + } + mxFree (p) ; + + /* === Return the stats vector ========================================== */ + + /* print stats if spumoni is set */ + if (spumoni) + { + colamd_l_report (stats) ; + } + + if (nlhs == 2) + { + plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ; + out_stats = mxGetPr (plhs [1]) ; + for (i = 0 ; i < COLAMD_STATS ; i++) + { + out_stats [i] = stats [i] ; + } + + /* fix stats (5) and (6), for 1-based information on jumbled matrix. */ + /* note that this correction doesn't occur if symamd returns FALSE */ + out_stats [COLAMD_INFO1] ++ ; + out_stats [COLAMD_INFO2] ++ ; + } +} diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/colamdtestmex.c b/OpenDSSC/klusolve/COLAMD/MATLAB/colamdtestmex.c new file mode 100644 index 0000000..9b90a46 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/colamdtestmex.c @@ -0,0 +1,577 @@ +/* ========================================================================== */ +/* === colamdtest mexFunction =============================================== */ +/* ========================================================================== */ + +/* COLAMD test function + + This MATLAB mexFunction is for testing only. It is not meant for + production use. See colamdmex.c instead. + + Usage: + + [ P, stats ] = colamdtest (A, knobs) ; + + See colamd.m for a description. knobs is required. + + knobs (1) dense row control + knobs (2) dense column control + knobs (3) spumoni + knobs (4) for testing only. Controls the workspace used by + colamd. + + knobs (5) for testing only. Controls how the input matrix is + jumbled prior to calling colamd, to test its error + handling capability. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Notice: + + Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. + + See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c + file) for the License. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the + http://www.cise.ufl.edu/research/sparse/colamd/colamdtestmex.c + file. It requires the colamd.c and colamd.h files. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include "mex.h" +#include "matrix.h" +#include +#include +#include "UFconfig.h" + +static void dump_matrix +( + UF_long A [ ], + UF_long p [ ], + UF_long n_row, + UF_long n_col, + UF_long Alen, + UF_long limit +) ; + +/* ========================================================================== */ +/* === colamd mexFunction =================================================== */ +/* ========================================================================== */ + +void mexFunction +( + /* === Parameters ======================================================= */ + + int nlhs, /* number of left-hand sides */ + mxArray *plhs [], /* left-hand side matrices */ + int nrhs, /* number of right--hand sides */ + const mxArray *prhs [] /* right-hand side matrices */ +) +{ + /* === Local variables ================================================== */ + + UF_long *A ; /* colamd's copy of the matrix, and workspace */ + UF_long *p ; /* colamd's copy of the column pointers */ + UF_long Alen ; /* size of A */ + UF_long n_col ; /* number of columns of A */ + UF_long n_row ; /* number of rows of A */ + UF_long nnz ; /* number of entries in A */ + UF_long full ; /* TRUE if input matrix full, FALSE if sparse */ + double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */ + double *out_perm ; /* output permutation vector */ + double *out_stats ; /* output stats vector */ + double *in_knobs ; /* input knobs vector */ + UF_long i ; /* loop counter */ + mxArray *Ainput ; /* input matrix handle */ + UF_long spumoni ; /* verbosity variable */ + UF_long stats2 [COLAMD_STATS] ; /* stats for colamd */ + + UF_long *cp, *cp_end, result, col, length ; + UF_long *stats ; + stats = stats2 ; + + colamd_printf = mexPrintf ; /* COLAMD printf routine */ + + /* === Check inputs ===================================================== */ + + if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2) + { + mexErrMsgTxt ( + "colamd: incorrect number of input and/or output arguments") ; + } + + if (nrhs != 2) + { + mexErrMsgTxt ("colamdtest: knobs are required") ; + } + /* for testing we require all 5 knobs */ + if (mxGetNumberOfElements (prhs [1]) != 5) + { + mexErrMsgTxt ("colamd: must have all 5 knobs for testing") ; + } + + /* === Get knobs ======================================================== */ + + colamd_l_set_defaults (knobs) ; + spumoni = 0 ; + + /* check for user-passed knobs */ + if (nrhs == 2) + { + in_knobs = mxGetPr (prhs [1]) ; + i = mxGetNumberOfElements (prhs [1]) ; + if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ; + if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ; + if (i > 2) spumoni = (UF_long) in_knobs [2] ; + } + + /* print knob settings if spumoni is set */ + if (spumoni) + { + mexPrintf ("\ncolamd version %d.%d, %s:\n", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ; + if (knobs [COLAMD_DENSE_ROW] >= 0) + { + mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))" + " entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ; + } + else + { + mexPrintf ("knobs(1): %g, only completely dense rows removed\n", + in_knobs [0]) ; + } + if (knobs [COLAMD_DENSE_COL] >= 0) + { + mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))" + " entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ; + } + else + { + mexPrintf ("knobs(2): %g, only completely dense columns removed\n", + in_knobs [1]) ; + } + mexPrintf ("knobs(3): %g, statistics and knobs printed\n", + in_knobs [2]) ; + } + + /* === If A is full, convert to a sparse matrix ========================= */ + + Ainput = (mxArray *) prhs [0] ; + if (mxGetNumberOfDimensions (Ainput) != 2) + { + mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ; + } + full = !mxIsSparse (Ainput) ; + if (full) + { + mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ; + } + + /* === Allocate workspace for colamd ==================================== */ + + /* get size of matrix */ + n_row = mxGetM (Ainput) ; + n_col = mxGetN (Ainput) ; + + /* get column pointer vector so we can find nnz */ + p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ; + (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ; + nnz = p [n_col] ; + Alen = (UF_long) colamd_l_recommended (nnz, n_row, n_col) ; + if (Alen == 0) + { + mexErrMsgTxt ("colamd: problem too large") ; + } + + +/* === Modify size of Alen if testing ======================================= */ + +/* + knobs [3] amount of workspace given to colamd. + < 0 : TIGHT memory + > 0 : MIN + knob [3] - 1 + == 0 : RECOMMENDED memory +*/ + +/* Here only for testing */ +/* size of the Col and Row structures */ +#define COLAMD_C(n_col) (((n_col) + 1) * 24 / sizeof (UF_long)) +#define COLAMD_R(n_row) (((n_row) + 1) * 16 / sizeof (UF_long)) +#ifdef MIN +#undef MIN +#endif +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define COLAMD_MIN_MEMORY(nnz,n_row,n_col) \ + (2 * (nnz) + COLAMD_C (n_col) + COLAMD_R (n_row)) + + /* get knob [3], if negative */ + if (in_knobs [3] < 0) + { + Alen = COLAMD_MIN_MEMORY (nnz, n_row, n_col) + n_col ; + } + else if (in_knobs [3] > 0) + { + Alen = COLAMD_MIN_MEMORY (nnz, n_row, n_col) + in_knobs [3] - 1 ; + } + + /* otherwise, we use the recommended amount set above */ + + /* === Copy input matrix into workspace ================================= */ + + A = (UF_long *) mxCalloc (Alen, sizeof (UF_long)) ; + (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ; + + if (full) + { + mxDestroyArray (Ainput) ; + } + + +/* === Jumble matrix ======================================================== */ + +/* + knobs [4] FOR TESTING ONLY: Specifies how to jumble matrix + 0 : No jumbling + 1 : Make n_row less than zero + 2 : Make first pointer non-zero + 3 : Make column pointers not non-decreasing + 4 : Make a column pointer greater or equal to Alen + 5 : Make row indices not strictly increasing + 6 : Make a row index greater or equal to n_row + 7 : Set A = NULL + 8 : Set p = NULL + 9 : Repeat row index + 10: make row indices not sorted + 11: jumble columns massively (note this changes + the pattern of the matrix A.) + 12: Set stats = NULL + 13: Make n_col less than zero +*/ + + /* jumble appropriately */ + switch ((UF_long) in_knobs [4]) + { + + case 0 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: no errors expected\n") ; + } + result = 1 ; /* no errors */ + break ; + + case 1 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: nrow out of range\n") ; + } + result = 0 ; /* nrow out of range */ + n_row = -1 ; + break ; + + case 2 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: p [0] nonzero\n") ; + } + result = 0 ; /* p [0] must be zero */ + p [0] = 1 ; + break ; + + case 3 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: negative length last column\n") ; + } + result = (n_col == 0) ; /* p must be monotonically inc. */ + p [n_col] = p [0] ; + break ; + + case 4 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: Alen too small\n") ; + } + result = 0 ; /* out of memory */ + p [n_col] = Alen ; + break ; + + case 5 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: row index out of range (-1)\n") ; + } + if (nnz > 0) /* row index out of range */ + { + result = 0 ; + A [nnz-1] = -1 ; + } + else + { + if (spumoni > 0) + { + mexPrintf ("Note: no row indices to put out of range\n") ; + } + result = 1 ; + } + break ; + + case 6 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: row index out of range (n_row)\n") ; + } + if (nnz > 0) /* row index out of range */ + { + if (spumoni > 0) + { + mexPrintf ("Changing A[nnz-1] from %d to %d\n", + A [nnz-1], n_row) ; + } + result = 0 ; + A [nnz-1] = n_row ; + } + else + { + if (spumoni > 0) + { + mexPrintf ("Note: no row indices to put out of range\n") ; + } + result = 1 ; + } + break ; + + case 7 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: A not present\n") ; + } + result = 0 ; /* A not present */ + A = (UF_long *) NULL ; + break ; + + case 8 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: p not present\n") ; + } + result = 0 ; /* p not present */ + p = (UF_long *) NULL ; + break ; + + case 9 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: duplicate row index\n") ; + } + result = 1 ; /* duplicate row index */ + + for (col = 0 ; col < n_col ; col++) + { + length = p [col+1] - p [col] ; + if (length > 1) + { + A [p [col]] = A [p [col] + 1] ; + if (spumoni > 0) + { + mexPrintf ("Made duplicate row %d in col %d\n", + A [p [col] + 1], col) ; + } + break ; + } + } + + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, Alen, col+2) ; + } + break ; + + case 10 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: unsorted column\n") ; + } + result = 1 ; /* jumbled columns */ + + for (col = 0 ; col < n_col ; col++) + { + length = p [col+1] - p [col] ; + if (length > 1) + { + i = A[p [col]] ; + A [p [col]] = A[p [col] + 1] ; + A [p [col] + 1] = i ; + if (spumoni > 0) + { + mexPrintf ("Unsorted column %d \n", col) ; + } + break ; + } + } + + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, Alen, col+2) ; + } + break ; + + case 11 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: massive jumbling\n") ; + } + result = 1 ; /* massive jumbling, but no errors */ + srand (1) ; + for (i = 0 ; i < n_col ; i++) + { + cp = &A [p [i]] ; + cp_end = &A [p [i+1]] ; + while (cp < cp_end) + { + *cp++ = rand() % n_row ; + } + } + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, Alen, n_col) ; + } + break ; + + case 12 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: stats not present\n") ; + } + result = 0 ; /* stats not present */ + stats = (UF_long *) NULL ; + break ; + + case 13 : + if (spumoni > 0) + { + mexPrintf ("colamdtest: ncol out of range\n") ; + } + result = 0 ; /* ncol out of range */ + n_col = -1 ; + break ; + + } + + + /* === Order the columns (destroys A) =================================== */ + + if (!colamd_l (n_row, n_col, Alen, A, p, knobs, stats)) + { + + /* return p = -1 if colamd failed */ + plhs [0] = mxCreateDoubleMatrix (1, 1, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + out_perm [0] = -1 ; + mxFree (p) ; + mxFree (A) ; + + if (spumoni > 0 || result) + { + colamd_l_report (stats) ; + } + + if (result) + { + mexErrMsgTxt ("colamd should have returned TRUE\n") ; + } + + return ; + /* mexErrMsgTxt ("colamd error!") ; */ + } + + if (!result) + { + colamd_l_report (stats) ; + mexErrMsgTxt ("colamd should have returned FALSE\n") ; + } + mxFree (A) ; + + /* === Return the permutation vector ==================================== */ + + plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + for (i = 0 ; i < n_col ; i++) + { + /* colamd is 0-based, but MATLAB expects this to be 1-based */ + out_perm [i] = p [i] + 1 ; + } + mxFree (p) ; + + /* === Return the stats vector ========================================== */ + + /* print stats if spumoni > 0 */ + if (spumoni > 0) + { + colamd_l_report (stats) ; + } + + if (nlhs == 2) + { + plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ; + out_stats = mxGetPr (plhs [1]) ; + for (i = 0 ; i < COLAMD_STATS ; i++) + { + out_stats [i] = stats [i] ; + } + + /* fix stats (5) and (6), for 1-based information on jumbled matrix. */ + /* note that this correction doesn't occur if symamd returns FALSE */ + out_stats [COLAMD_INFO1] ++ ; + out_stats [COLAMD_INFO2] ++ ; + } +} + + +static void dump_matrix +( + UF_long A [ ], + UF_long p [ ], + UF_long n_row, + UF_long n_col, + UF_long Alen, + UF_long limit +) +{ + UF_long col, k, row ; + + mexPrintf ("dump matrix: nrow %d ncol %d Alen %d\n", n_row, n_col, Alen) ; + + for (col = 0 ; col < MIN (n_col, limit) ; col++) + { + mexPrintf ("column %d, p[col] %d, p [col+1] %d, length %d\n", + col, p [col], p [col+1], p [col+1] - p [col]) ; + for (k = p [col] ; k < p [col+1] ; k++) + { + row = A [k] ; + mexPrintf (" %d", row) ; + } + mexPrintf ("\n") ; + } +} diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/luflops.m b/OpenDSSC/klusolve/COLAMD/MATLAB/luflops.m new file mode 100644 index 0000000..f3c9e45 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/luflops.m @@ -0,0 +1,34 @@ +function fl = luflops (L, U) +%LUFLOPS compute the flop count for sparse LU factorization +% +% Example: +% fl = luflops (L,U) +% +% Given a sparse LU factorization (L and U), return the flop count required +% by a conventional LU factorization algorithm to compute it. L and U can +% be either sparse or full matrices. L must be lower triangular and U must +% be upper triangular. Do not attempt to use this on the permuted L from +% [L,U] = lu (A). Instead, use [L,U,P] = lu (A) or [L,U,P,Q] = lu (A). +% +% Note that there is a subtle undercount in this estimate. Suppose A is +% completely dense, but during LU factorization exact cancellation occurs, +% causing some of the entries in L and U to become identically zero. The +% flop count returned by this routine is an undercount. There is a simple +% way to fix this (L = spones (L) + spones (tril (A))), but the fix is partial. +% It can also occur that some entry in L is a "symbolic" fill-in (zero in +% A, but a fill-in entry and thus must be computed), but numerically +% zero. The only way to get a reliable LU factorization would be to do a +% purely symbolic factorization of A. This cannot be done with +% symbfact (A, 'col'). +% +% See NA Digest, Vol 00, #50, Tuesday, Dec. 5, 2000 +% +% See also symbfact + +% Copyright 1998-2007, Timothy A. Davis + + +Lnz = full (sum (spones (L))) - 1 ; % off diagonal nz in cols of L +Unz = full (sum (spones (U')))' - 1 ; % off diagonal nz in rows of U +fl = 2*Lnz*Unz + sum (Lnz) ; + diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/symamd2.m b/OpenDSSC/klusolve/COLAMD/MATLAB/symamd2.m new file mode 100644 index 0000000..ecae450 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/symamd2.m @@ -0,0 +1,86 @@ +function [p, stats] = symamd2 (S, knobs) +%SYMAMD Symmetric approximate minimum degree permutation. +% P = SYMAMD2(S) for a symmetric positive definite matrix S, returns the +% permutation vector p such that S(p,p) tends to have a sparser Cholesky +% factor than S. Sometimes SYMAMD works well for symmetric indefinite +% matrices too. The matrix S is assumed to be symmetric; only the +% strictly lower triangular part is referenced. S must be square. +% Note that p = amd(S) is much faster and generates comparable orderings. +% The ordering is followed by an elimination tree post-ordering. +% +% Note that this function is source code for the built-in MATLAB symamd +% function. It has been renamed here to symamd2 to avoid a filename clash. +% symamd and symamd2 are identical. +% +% See also SYMAMD, AMD, COLAMD, COLAMD2. +% +% Example: +% P = symamd2 (S) +% [P, stats] = symamd2 (S, knobs) +% +% knobs is an optional one- to two-element input vector. If S is n-by-n, +% then rows and columns with more than max(16,knobs(1)*sqrt(n)) entries are +% removed prior to ordering, and ordered last in the output permutation P. +% No rows/columns are removed if knobs(1)<0. If knobs(2) is nonzero, stats +% and knobs are printed. The default is knobs = [10 0]. Note that knobs +% differs from earlier versions of symamd. + +% Copyright 1998-2007, Timothy A. Davis, and Stefan Larimore +% Developed in collaboration with J. Gilbert and E. Ng. +% Acknowledgements: This work was supported by the National Science +% Foundation, under grants DMS-9504974 and DMS-9803599. + +%------------------------------------------------------------------------------- +% perform the symamd ordering: +%------------------------------------------------------------------------------- + +if (nargout <= 1 & nargin == 1) %#ok + p = symamd2mex (S) ; +elseif (nargout <= 1 & nargin == 2) %#ok + p = symamd2mex (S, knobs) ; +elseif (nargout == 2 & nargin == 1) %#ok + [p, stats] = symamd2mex (S) ; +elseif (nargout == 2 & nargin == 2) %#ok + [p, stats] = symamd2mex (S, knobs) ; +else + error('symamd: incorrect number of input and/or output arguments.') ; +end + +%------------------------------------------------------------------------------- +% symmetric elimination tree post-ordering: +%------------------------------------------------------------------------------- + +[ignore, q] = etree (S (p,p)) ; +p = p (q) ; + + +% stats is an optional 20-element output vector that provides data about the +% ordering and the validity of the input matrix S. Ordering statistics are +% in stats (1:3). stats (1) = stats (2) is the number of dense or empty +% rows and columns ignored by SYMAMD and stats (3) is the number of +% garbage collections performed on the internal data structure used by +% SYMAMD (roughly of size 8.4*nnz(tril(S,-1)) + 9*n integers). +% +% MATLAB built-in functions are intended to generate valid sparse matrices, +% with no duplicate entries, with ascending row indices of the nonzeros +% in each column, with a non-negative number of entries in each column (!) +% and so on. If a matrix is invalid, then SYMAMD may or may not be able +% to continue. If there are duplicate entries (a row index appears two or +% more times in the same column) or if the row indices in a column are out +% of order, then SYMAMD can correct these errors by ignoring the duplicate +% entries and sorting each column of its internal copy of the matrix S (the +% input matrix S is not repaired, however). If a matrix is invalid in other +% ways then SYMAMD cannot continue, an error message is printed, and no +% output arguments (P or stats) are returned. SYMAMD is thus a simple way +% to check a sparse matrix to see if it's valid. +% +% stats (4:7) provide information if SYMAMD was able to continue. The +% matrix is OK if stats (4) is zero, or 1 if invalid. stats (5) is the +% rightmost column index that is unsorted or contains duplicate entries, +% or zero if no such column exists. stats (6) is the last seen duplicate +% or out-of-order row index in the column index given by stats (5), or zero +% if no such row index exists. stats (7) is the number of duplicate or +% out-of-order row indices. +% +% stats (8:20) is always zero in the current version of SYMAMD (reserved +% for future use). diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/symamdmex.c b/OpenDSSC/klusolve/COLAMD/MATLAB/symamdmex.c new file mode 100644 index 0000000..253366d --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/symamdmex.c @@ -0,0 +1,201 @@ +/* ========================================================================== */ +/* === symamd mexFunction =================================================== */ +/* ========================================================================== */ + +/* SYMAMD mexFunction + + Usage: + + P = symamd2 (A) ; + [ P, stats ] = symamd2 (A, knobs) ; + + See symamd.m for a description. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Notice: + + Copyright (c) 1998-2007, Timothy A. Davis. All Rights Reserved. + + See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c + file) for the License. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the http://www.cise.ufl.edu/research/sparse/colamd/symamdmex.c + file. It requires the colamd.c and colamd.h files. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include "mex.h" +#include "matrix.h" +#include +#include "UFconfig.h" + +/* ========================================================================== */ +/* === symamd mexFunction =================================================== */ +/* ========================================================================== */ + +void mexFunction +( + /* === Parameters ======================================================= */ + + int nlhs, /* number of left-hand sides */ + mxArray *plhs [], /* left-hand side matrices */ + int nrhs, /* number of right--hand sides */ + const mxArray *prhs [] /* right-hand side matrices */ +) +{ + /* === Local variables ================================================== */ + + UF_long *perm ; /* column ordering of M and ordering of A */ + UF_long *A ; /* row indices of input matrix A */ + UF_long *p ; /* column pointers of input matrix A */ + UF_long n_col ; /* number of columns of A */ + UF_long n_row ; /* number of rows of A */ + UF_long full ; /* TRUE if input matrix full, FALSE if sparse */ + double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */ + double *out_perm ; /* output permutation vector */ + double *out_stats ; /* output stats vector */ + double *in_knobs ; /* input knobs vector */ + UF_long i ; /* loop counter */ + mxArray *Ainput ; /* input matrix handle */ + UF_long spumoni ; /* verbosity variable */ + UF_long stats [COLAMD_STATS] ; /* stats for symamd */ + + colamd_printf = mexPrintf ; /* COLAMD printf routine */ + + /* === Check inputs ===================================================== */ + + if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2) + { + mexErrMsgTxt ( + "symamd: incorrect number of input and/or output arguments.") ; + } + + /* === Get knobs ======================================================== */ + + colamd_l_set_defaults (knobs) ; + spumoni = 0 ; + + /* check for user-passed knobs */ + if (nrhs == 2) + { + in_knobs = mxGetPr (prhs [1]) ; + i = mxGetNumberOfElements (prhs [1]) ; + if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ; + if (i > 1) spumoni = (UF_long) (in_knobs [1] != 0) ; + } + + /* print knob settings if spumoni is set */ + if (spumoni) + { + mexPrintf ("\nsymamd version %d.%d, %s:\n", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ; + if (knobs [COLAMD_DENSE_ROW] >= 0) + { + mexPrintf ("knobs(1): %g, rows/cols with > " + "max(16,%g*sqrt(size(A,2))) entries removed\n", + in_knobs [0], knobs [COLAMD_DENSE_ROW]) ; + } + else + { + mexPrintf ("knobs(1): %g, no dense rows removed\n", in_knobs [0]) ; + } + mexPrintf ("knobs(2): %g, statistics and knobs printed\n", + in_knobs [1]) ; + } + + /* === If A is full, convert to a sparse matrix ========================= */ + + Ainput = (mxArray *) prhs [0] ; + if (mxGetNumberOfDimensions (Ainput) != 2) + { + mexErrMsgTxt ("symamd: input matrix must be 2-dimensional.") ; + } + full = !mxIsSparse (Ainput) ; + if (full) + { + mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ; + } + + /* === Allocate workspace for symamd ==================================== */ + + /* get size of matrix */ + n_row = mxGetM (Ainput) ; + n_col = mxGetN (Ainput) ; + if (n_col != n_row) + { + mexErrMsgTxt ("symamd: matrix must be square.") ; + } + + A = (UF_long *) mxGetIr (Ainput) ; + p = (UF_long *) mxGetJc (Ainput) ; + perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ; + + /* === Order the rows and columns of A (does not destroy A) ============= */ + + if (!symamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree)) + { + symamd_l_report (stats) ; + mexErrMsgTxt ("symamd error!") ; + } + + if (full) + { + mxDestroyArray (Ainput) ; + } + + /* === Return the permutation vector ==================================== */ + + plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + for (i = 0 ; i < n_col ; i++) + { + /* symamd is 0-based, but MATLAB expects this to be 1-based */ + out_perm [i] = perm [i] + 1 ; + } + mxFree (perm) ; + + /* === Return the stats vector ========================================== */ + + /* print stats if spumoni is set */ + if (spumoni) + { + symamd_l_report (stats) ; + } + + if (nlhs == 2) + { + plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ; + out_stats = mxGetPr (plhs [1]) ; + for (i = 0 ; i < COLAMD_STATS ; i++) + { + out_stats [i] = stats [i] ; + } + + /* fix stats (5) and (6), for 1-based information on jumbled matrix. */ + /* note that this correction doesn't occur if symamd returns FALSE */ + out_stats [COLAMD_INFO1] ++ ; + out_stats [COLAMD_INFO2] ++ ; + } +} diff --git a/OpenDSSC/klusolve/COLAMD/MATLAB/symamdtestmex.c b/OpenDSSC/klusolve/COLAMD/MATLAB/symamdtestmex.c new file mode 100644 index 0000000..c41101f --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/MATLAB/symamdtestmex.c @@ -0,0 +1,543 @@ +/* ========================================================================== */ +/* === symamdtest mexFunction =============================================== */ +/* ========================================================================== */ + +/* SYMAMD test function + + This MATLAB mexFunction is for testing only. It is not meant for + production use. See symamdmex.c instead. + + Usage: + + [ P, stats ] = symamdtest (A, knobs) ; + + See symamd.m for a description. knobs is required. + + knobs (1) dense row control + knobs (2) spumoni + knobs (3) for testing only. Controls how the input matrix is + jumbled prior to calling symamd, to test its error + handling capability. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Notice: + + Copyright (c) 1998-2007, Timothy A. Davis. All Rights Reserved. + + See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c + file) for the License. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the + http://www.cise.ufl.edu/research/sparse/colamd/symamdtestmex.c + file. It requires the colamd.c and colamd.h files. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include "mex.h" +#include "matrix.h" +#include +#include +#include "UFconfig.h" + +static void dump_matrix +( + UF_long A [ ], + UF_long p [ ], + UF_long n_row, + UF_long n_col, + UF_long Alen, + UF_long limit +) ; + +/* ========================================================================== */ +/* === symamd mexFunction =================================================== */ +/* ========================================================================== */ + +void mexFunction +( + /* === Parameters ======================================================= */ + + int nlhs, /* number of left-hand sides */ + mxArray *plhs [], /* left-hand side matrices */ + int nrhs, /* number of right--hand sides */ + const mxArray *prhs [] /* right-hand side matrices */ +) +{ + /* === Local variables ================================================== */ + + UF_long *perm ; /* column ordering of M and ordering of A */ + UF_long *A ; /* row indices of input matrix A */ + UF_long *p ; /* column pointers of input matrix A */ + UF_long n_col ; /* number of columns of A */ + UF_long n_row ; /* number of rows of A */ + UF_long full ; /* TRUE if input matrix full, FALSE if sparse */ + double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */ + double *out_perm ; /* output permutation vector */ + double *out_stats ; /* output stats vector */ + double *in_knobs ; /* input knobs vector */ + UF_long i ; /* loop counter */ + mxArray *Ainput ; /* input matrix handle */ + UF_long spumoni ; /* verbosity variable */ + UF_long stats2 [COLAMD_STATS] ; /* stats for symamd */ + + UF_long *cp, *cp_end, result, nnz, col, length ; + UF_long *stats ; + stats = stats2 ; + + colamd_printf = mexPrintf ; /* COLAMD printf routine */ + + /* === Check inputs ===================================================== */ + + if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2) + { + mexErrMsgTxt ( + "symamd: incorrect number of input and/or output arguments.") ; + } + + if (nrhs != 2) + { + mexErrMsgTxt ("symamdtest: knobs are required") ; + } + /* for testing we require all 3 knobs */ + if (mxGetNumberOfElements (prhs [1]) != 3) + { + mexErrMsgTxt ("symamdtest: must have all 3 knobs for testing") ; + } + + /* === Get knobs ======================================================== */ + + colamd_l_set_defaults (knobs) ; + spumoni = 0 ; + + /* check for user-passed knobs */ + if (nrhs == 2) + { + in_knobs = mxGetPr (prhs [1]) ; + i = mxGetNumberOfElements (prhs [1]) ; + if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ; + if (i > 1) spumoni = (UF_long) in_knobs [1] ; + } + + /* print knob settings if spumoni is set */ + if (spumoni) + { + mexPrintf ("\nsymamd version %d.%d, %s:\n", + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ; + if (knobs [COLAMD_DENSE_ROW] >= 0) + { + mexPrintf ("knobs(1): %g, rows/cols with > " + "max(16,%g*sqrt(size(A,2))) entries removed\n", + in_knobs [0], knobs [COLAMD_DENSE_ROW]) ; + } + else + { + mexPrintf ("knobs(1): %g, no dense rows removed\n", in_knobs [0]) ; + } + mexPrintf ("knobs(2): %g, statistics and knobs printed\n", + in_knobs [1]) ; + mexPrintf ("Testing %d\n", in_knobs [2]) ; + } + + /* === If A is full, convert to a sparse matrix ========================= */ + + Ainput = (mxArray *) prhs [0] ; + if (mxGetNumberOfDimensions (Ainput) != 2) + { + mexErrMsgTxt ("symamd: input matrix must be 2-dimensional.") ; + } + full = !mxIsSparse (Ainput) ; + if (full) + { + mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ; + } + + /* === Allocate workspace for symamd ==================================== */ + + /* get size of matrix */ + n_row = mxGetM (Ainput) ; + n_col = mxGetN (Ainput) ; + if (n_col != n_row) + { + mexErrMsgTxt ("symamd: matrix must be square.") ; + } + + /* p = mxGetJc (Ainput) ; */ + p = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ; + (void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (UF_long)) ; + + nnz = p [n_col] ; + if (spumoni > 0) + { + mexPrintf ("symamdtest: nnz %d\n", nnz) ; + } + + /* A = mxGetIr (Ainput) ; */ + A = (UF_long *) mxCalloc (nnz+1, sizeof (UF_long)) ; + (void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (UF_long)) ; + + perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ; + +/* === Jumble matrix ======================================================== */ + + +/* + knobs [2] FOR TESTING ONLY: Specifies how to jumble matrix + 0 : No jumbling + 1 : (no errors) + 2 : Make first pointer non-zero + 3 : Make column pointers not non-decreasing + 4 : (no errors) + 5 : Make row indices not strictly increasing + 6 : Make a row index greater or equal to n_row + 7 : Set A = NULL + 8 : Set p = NULL + 9 : Repeat row index + 10: make row indices not sorted + 11: jumble columns massively (note this changes + the pattern of the matrix A.) + 12: Set stats = NULL + 13: Make n_col less than zero +*/ + + /* jumble appropriately */ + switch ((UF_long) in_knobs [2]) + { + + case 0 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: no errors expected\n") ; + } + result = 1 ; /* no errors */ + break ; + + case 1 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: no errors expected (1)\n") ; + } + result = 1 ; + break ; + + case 2 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: p [0] nonzero\n") ; + } + result = 0 ; /* p [0] must be zero */ + p [0] = 1 ; + break ; + + case 3 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: negative length last column\n") ; + } + result = (n_col == 0) ; /* p must be monotonically inc. */ + p [n_col] = p [0] ; + break ; + + case 4 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: no errors expected (4)\n") ; + } + result = 1 ; + break ; + + case 5 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: row index out of range (-1)\n") ; + } + if (nnz > 0) /* row index out of range */ + { + result = 0 ; + A [nnz-1] = -1 ; + } + else + { + if (spumoni > 0) + { + mexPrintf ("Note: no row indices to put out of range\n") ; + } + result = 1 ; + } + break ; + + case 6 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: row index out of range (ncol)\n") ; + } + if (nnz > 0) /* row index out of range */ + { + result = 0 ; + A [nnz-1] = n_col ; + } + else + { + if (spumoni > 0) + { + mexPrintf ("Note: no row indices to put out of range\n") ; + } + result = 1 ; + } + break ; + + case 7 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: A not present\n") ; + } + result = 0 ; /* A not present */ + A = (UF_long *) NULL ; + break ; + + case 8 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: p not present\n") ; + } + result = 0 ; /* p not present */ + p = (UF_long *) NULL ; + break ; + + case 9 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: duplicate row index\n") ; + } + result = 1 ; /* duplicate row index */ + + for (col = 0 ; col < n_col ; col++) + { + length = p [col+1] - p [col] ; + if (length > 1) + { + A [p [col+1]-2] = A [p [col+1] - 1] ; + if (spumoni > 0) + { + mexPrintf ("Made duplicate row %d in col %d\n", + A [p [col+1] - 1], col) ; + } + break ; + } + } + + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, nnz, col+2) ; + } + break ; + + case 10 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: unsorted column\n") ; + } + result = 1 ; /* jumbled columns */ + + for (col = 0 ; col < n_col ; col++) + { + length = p [col+1] - p [col] ; + if (length > 1) + { + i = A[p [col]] ; + A [p [col]] = A[p [col] + 1] ; + A [p [col] + 1] = i ; + if (spumoni > 0) + { + mexPrintf ("Unsorted column %d \n", col) ; + } + break ; + } + } + + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, nnz, col+2) ; + } + break ; + + case 11 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: massive jumbling\n") ; + } + result = 1 ; /* massive jumbling, but no errors */ + srand (1) ; + for (i = 0 ; i < n_col ; i++) + { + cp = &A [p [i]] ; + cp_end = &A [p [i+1]] ; + while (cp < cp_end) + { + *cp++ = rand() % n_row ; + } + } + if (spumoni > 1) + { + dump_matrix (A, p, n_row, n_col, nnz, n_col) ; + } + break ; + + case 12 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: stats not present\n") ; + } + result = 0 ; /* stats not present */ + stats = (UF_long *) NULL ; + break ; + + case 13 : + if (spumoni > 0) + { + mexPrintf ("symamdtest: ncol out of range\n") ; + } + result = 0 ; /* ncol out of range */ + n_col = -1 ; + break ; + + } + + /* === Order the rows and columns of A (does not destroy A) ============= */ + + if (!symamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree)) + { + + /* return p = -1 if colamd failed */ + plhs [0] = mxCreateDoubleMatrix (1, 1, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + out_perm [0] = -1 ; + mxFree (p) ; + mxFree (A) ; + + if (spumoni > 0 || result) + { + symamd_l_report (stats) ; + } + + if (result) + { + mexErrMsgTxt ("symamd should have returned TRUE\n") ; + } + + return ; + /* mexErrMsgTxt ("symamd error!") ; */ + } + + if (!result) + { + symamd_l_report (stats) ; + mexErrMsgTxt ("symamd should have returned FALSE\n") ; + } + + if (full) + { + mxDestroyArray (Ainput) ; + } + + /* === Return the permutation vector ==================================== */ + + plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ; + out_perm = mxGetPr (plhs [0]) ; + for (i = 0 ; i < n_col ; i++) + { + /* symamd is 0-based, but MATLAB expects this to be 1-based */ + out_perm [i] = perm [i] + 1 ; + } + mxFree (perm) ; + + /* === Return the stats vector ========================================== */ + + /* print stats if spumoni > 0 */ + if (spumoni > 0) + { + symamd_l_report (stats) ; + } + + if (nlhs == 2) + { + plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ; + out_stats = mxGetPr (plhs [1]) ; + for (i = 0 ; i < COLAMD_STATS ; i++) + { + out_stats [i] = stats [i] ; + } + + /* fix stats (5) and (6), for 1-based information on jumbled matrix. */ + /* note that this correction doesn't occur if symamd returns FALSE */ + out_stats [COLAMD_INFO1] ++ ; + out_stats [COLAMD_INFO2] ++ ; + } +} + + +#ifdef MIN +#undef MIN +#endif +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + + +static void dump_matrix +( + UF_long A [ ], + UF_long p [ ], + UF_long n_row, + UF_long n_col, + UF_long Alen, + UF_long limit +) +{ + UF_long col, k, row ; + + mexPrintf ("dump matrix: nrow %d ncol %d Alen %d\n", n_row, n_col, Alen) ; + + if (!A) + { + mexPrintf ("A not present\n") ; + return ; + } + + if (!p) + { + mexPrintf ("p not present\n") ; + return ; + } + + for (col = 0 ; col < MIN (n_col, limit) ; col++) + { + mexPrintf ("column %d, p[col] %d, p [col+1] %d, length %d\n", + col, p [col], p [col+1], p [col+1] - p [col]) ; + for (k = p [col] ; k < p [col+1] ; k++) + { + row = A [k] ; + mexPrintf (" %d", row) ; + } + mexPrintf ("\n") ; + } +} diff --git a/OpenDSSC/klusolve/COLAMD/Makefile b/OpenDSSC/klusolve/COLAMD/Makefile new file mode 100644 index 0000000..5bc58e1 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Makefile @@ -0,0 +1,65 @@ +#------------------------------------------------------------------------------ +# COLAMD Makefile +#------------------------------------------------------------------------------ + +VERSION = 2.7.4 + +default: demos + +include ../UFconfig/UFconfig.mk + +# Compile all C code, including the C-callable routine and the mexFunctions. +# Do not the MATLAB interface. +demos: + ( cd Lib ; $(MAKE) ) + ( cd Demo ; $(MAKE) ) + +# Compile all C code, including the C-callable routine and the mexFunctions. +all: + ( cd Lib ; $(MAKE) ) + ( cd Demo ; $(MAKE) ) + ( cd MATLAB ; $(MAKE) ) + +# compile just the C-callable libraries (not mexFunctions or Demos) +library: + ( cd Lib ; $(MAKE) ) + +# remove object files, but keep the compiled programs and library archives +clean: + ( cd Lib ; $(MAKE) clean ) + ( cd Demo ; $(MAKE) clean ) + ( cd MATLAB ; $(MAKE) clean ) + +# clean, and then remove compiled programs and library archives +purge: + ( cd Lib ; $(MAKE) purge ) + ( cd Demo ; $(MAKE) purge ) + ( cd MATLAB ; $(MAKE) purge ) + +distclean: purge + +# get ready for distribution +dist: purge + ( cd Demo ; $(MAKE) dist ) + +ccode: library + +lib: library + +# compile the MATLAB mexFunction +mex: + ( cd MATLAB ; $(MAKE) ) + +# install COLAMD +install: + $(CP) Lib/libcolamd.a $(INSTALL_LIB)/libcolamd.$(VERSION).a + ( cd $(INSTALL_LIB) ; ln -sf libcolamd.$(VERSION).a libcolamd.a ) + $(CP) Include/colamd.h $(INSTALL_INCLUDE) + chmod 644 $(INSTALL_LIB)/libcolamd*.a + chmod 644 $(INSTALL_INCLUDE)/colamd.h + +# uninstall COLAMD +uninstall: + $(RM) $(INSTALL_LIB)/libcolamd*.a + $(RM) $(INSTALL_INCLUDE)/colamd.h + diff --git a/OpenDSSC/klusolve/COLAMD/README.txt b/OpenDSSC/klusolve/COLAMD/README.txt new file mode 100644 index 0000000..47da68e --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/README.txt @@ -0,0 +1,125 @@ +The COLAMD ordering method, Copyright 1998-2011, Timothy A. Davis. +------------------------------------------------------------------------------- + +The COLAMD column approximate minimum degree ordering algorithm computes +a permutation vector P such that the LU factorization of A (:,P) +tends to be sparser than that of A. The Cholesky factorization of +(A (:,P))'*(A (:,P)) will also tend to be sparser than that of A'*A. +SYMAMD is a symmetric minimum degree ordering method based on COLAMD, +available as a MATLAB-callable function. It constructs a matrix M such +that M'*M has the same pattern as A, and then uses COLAMD to compute a column +ordering of M. Colamd and symamd tend to be faster and generate better +orderings than their MATLAB counterparts, colmmd and symmmd. + +To compile and test the colamd m-files and mexFunctions, just unpack the +COLAMD/ directory from the COLAMD.tar.gz file, and run MATLAB from +within that directory. Next, type colamd_test to compile and test colamd +and symamd. This will work on any computer with MATLAB (Unix, PC, or Mac). +Alternatively, type "make" (in Unix) to compile and run a simple example C +code, without using MATLAB. + +To compile and install the colamd m-files and mexFunctions, just cd to +COLAMD/MATLAB and type colamd_install in the MATLAB command window. +A short demo will run. Optionally, type colamd_test to run an extensive tests. +Type "make" in Unix in the COLAMD directory to compile the C-callable +library and to run a short demo. + +If you have MATLAB 7.2 or earlier, you must first edit UFconfig/UFconfig.h to +remove the "-largeArrayDims" option from the MEX command (or just use +colamd_make.m inside MATLAB). + +Colamd is a built-in routine in MATLAB, available from The +Mathworks, Inc. Under most cases, the compiled COLAMD from Versions 2.0 to the +current version do not differ. Colamd Versions 2.2 and 2.3 differ only in their +mexFunction interaces to MATLAB. v2.4 fixes a bug in the symamd routine in +v2.3. The bug (in v2.3 and earlier) has no effect on the MATLAB symamd +mexFunction. v2.5 adds additional checks for integer overflow, so that +the "int" version can be safely used with 64-bit pointers. Refer to the +ChangeLog for more details. + +To use colamd and symamd within an application written in C, all you need are +colamd.c, colamd_global.c, and colamd.h, which are the C-callable +colamd/symamd codes. See colamd.c for more information on how to call +colamd from a C program. + +Requires UFconfig, in the ../UFconfig directory relative to this directory. + + See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c + file) for the License. + + +Related papers: + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column + minimum degree ordering algorithm, ACM Transactions on Mathematical + Software, vol. 30, no. 3., pp. 353-376, 2004. + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, + an approximate column minimum degree ordering algorithm, ACM + Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, + 2004. + + "An approximate minimum degree column ordering algorithm", + S. I. Larimore, MS Thesis, Dept. of Computer and Information + Science and Engineering, University of Florida, Gainesville, FL, + 1998. CISE Tech Report TR-98-016. Available at + ftp://ftp.cise.ufl.edu/cis/tech-reports/tr98/tr98-016.ps + via anonymous ftp. + + Approximate Deficiency for Ordering the Columns of a Matrix, + J. L. Kern, Senior Thesis, Dept. of Computer and Information + Science and Engineering, University of Florida, Gainesville, FL, + 1999. Available at http://www.cise.ufl.edu/~davis/Kern/kern.ps + + +Authors: Stefan I. Larimore and Timothy A. Davis, University of Florida, +in collaboration with John Gilbert, Xerox PARC (now at UC Santa Barbara), +and Esmong Ng, Lawrence Berkeley National Laboratory (much of this work +he did while at Oak Ridge National Laboratory). + +COLAMD files: + + Demo simple demo + Doc additional documentation (see colamd.c for more) + Include include file + Lib compiled C-callable library + Makefile primary Unix Makefile + MATLAB MATLAB functions + README.txt this file + Source C source code + + ./Demo: + colamd_example.c simple example + colamd_example.out output of colamd_example.c + colamd_l_example.c simple example, long integers + colamd_l_example.out output of colamd_l_example.c + Makefile Makefile for C demos + + ./Doc: + ChangeLog change log + lesser.txt license + + ./Include: + colamd.h include file + + ./Lib: + Makefile Makefile for C-callable library + + ./MATLAB: + colamd2.m MATLAB interface for colamd2 + colamd_demo.m simple demo + colamd_install.m compile and install colamd2 and symamd2 + colamd_make.m compile colamd2 and symamd2 + colamdmex.ca MATLAB mexFunction for colamd2 + colamd_test.m extensive test + colamdtestmex.c test function for colamd + Contents.m contents of the MATLAB directory + luflops.m test code + Makefile Makefile for MATLAB functions + symamd2.m MATLAB interface for symamd2 + symamdmex.c MATLAB mexFunction for symamd2 + symamdtestmex.c test function for symamd + + ./Source: + colamd.c primary source code + colamd_global.c globally defined function pointers (malloc, free, ...) diff --git a/OpenDSSC/klusolve/COLAMD/Source/colamd.c b/OpenDSSC/klusolve/COLAMD/Source/colamd.c new file mode 100644 index 0000000..5fe20d6 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Source/colamd.c @@ -0,0 +1,3611 @@ +/* ========================================================================== */ +/* === colamd/symamd - a sparse matrix column ordering algorithm ============ */ +/* ========================================================================== */ + +/* COLAMD / SYMAMD + + colamd: an approximate minimum degree column ordering algorithm, + for LU factorization of symmetric or unsymmetric matrices, + QR factorization, least squares, interior point methods for + linear programming problems, and other related problems. + + symamd: an approximate minimum degree ordering algorithm for Cholesky + factorization of symmetric matrices. + + Purpose: + + Colamd computes a permutation Q such that the Cholesky factorization of + (AQ)'(AQ) has less fill-in and requires fewer floating point operations + than A'A. This also provides a good ordering for sparse partial + pivoting methods, P(AQ) = LU, where Q is computed prior to numerical + factorization, and P is computed during numerical factorization via + conventional partial pivoting with row interchanges. Colamd is the + column ordering method used in SuperLU, part of the ScaLAPACK library. + It is also available as built-in function in MATLAB Version 6, + available from MathWorks, Inc. (http://www.mathworks.com). This + routine can be used in place of colmmd in MATLAB. + + Symamd computes a permutation P of a symmetric matrix A such that the + Cholesky factorization of PAP' has less fill-in and requires fewer + floating point operations than A. Symamd constructs a matrix M such + that M'M has the same nonzero pattern of A, and then orders the columns + of M using colmmd. The column ordering of M is then returned as the + row and column ordering P of A. + + Authors: + + The authors of the code itself are Stefan I. Larimore and Timothy A. + Davis (davis at cise.ufl.edu), University of Florida. The algorithm was + developed in collaboration with John Gilbert, Xerox PARC, and Esmond + Ng, Oak Ridge National Laboratory. + + Acknowledgements: + + This work was supported by the National Science Foundation, under + grants DMS-9504974 and DMS-9803599. + + Copyright and License: + + Copyright (c) 1998-2007, Timothy A. Davis, All Rights Reserved. + COLAMD is also available under alternate licenses, contact T. Davis + for details. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + + Availability: + + The colamd/symamd library is available at + + http://www.cise.ufl.edu/research/sparse/colamd/ + + This is the http://www.cise.ufl.edu/research/sparse/colamd/colamd.c + file. It requires the colamd.h file. It is required by the colamdmex.c + and symamdmex.c files, for the MATLAB interface to colamd and symamd. + Appears as ACM Algorithm 836. + + See the ChangeLog file for changes since Version 1.0. + + References: + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, An approximate column + minimum degree ordering algorithm, ACM Transactions on Mathematical + Software, vol. 30, no. 3., pp. 353-376, 2004. + + T. A. Davis, J. R. Gilbert, S. Larimore, E. Ng, Algorithm 836: COLAMD, + an approximate column minimum degree ordering algorithm, ACM + Transactions on Mathematical Software, vol. 30, no. 3., pp. 377-380, + 2004. + +*/ + +/* ========================================================================== */ +/* === Description of user-callable routines ================================ */ +/* ========================================================================== */ + +/* COLAMD includes both int and UF_long versions of all its routines. The + * description below is for the int version. For UF_long, all int arguments + * become UF_long. UF_long is normally defined as long, except for WIN64. + + ---------------------------------------------------------------------------- + colamd_recommended: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + size_t colamd_recommended (int nnz, int n_row, int n_col) ; + size_t colamd_l_recommended (UF_long nnz, UF_long n_row, + UF_long n_col) ; + + Purpose: + + Returns recommended value of Alen for use by colamd. Returns 0 + if any input argument is negative. The use of this routine + is optional. Not needed for symamd, which dynamically allocates + its own memory. + + Note that in v2.4 and earlier, these routines returned int or long. + They now return a value of type size_t. + + Arguments (all input arguments): + + int nnz ; Number of nonzeros in the matrix A. This must + be the same value as p [n_col] in the call to + colamd - otherwise you will get a wrong value + of the recommended memory to use. + + int n_row ; Number of rows in the matrix A. + + int n_col ; Number of columns in the matrix A. + + ---------------------------------------------------------------------------- + colamd_set_defaults: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + colamd_set_defaults (double knobs [COLAMD_KNOBS]) ; + colamd_l_set_defaults (double knobs [COLAMD_KNOBS]) ; + + Purpose: + + Sets the default parameters. The use of this routine is optional. + + Arguments: + + double knobs [COLAMD_KNOBS] ; Output only. + + NOTE: the meaning of the dense row/col knobs has changed in v2.4 + + knobs [0] and knobs [1] control dense row and col detection: + + Colamd: rows with more than + max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n_col)) + entries are removed prior to ordering. Columns with more than + max (16, knobs [COLAMD_DENSE_COL] * sqrt (MIN (n_row,n_col))) + entries are removed prior to + ordering, and placed last in the output column ordering. + + Symamd: uses only knobs [COLAMD_DENSE_ROW], which is knobs [0]. + Rows and columns with more than + max (16, knobs [COLAMD_DENSE_ROW] * sqrt (n)) + entries are removed prior to ordering, and placed last in the + output ordering. + + COLAMD_DENSE_ROW and COLAMD_DENSE_COL are defined as 0 and 1, + respectively, in colamd.h. Default values of these two knobs + are both 10. Currently, only knobs [0] and knobs [1] are + used, but future versions may use more knobs. If so, they will + be properly set to their defaults by the future version of + colamd_set_defaults, so that the code that calls colamd will + not need to change, assuming that you either use + colamd_set_defaults, or pass a (double *) NULL pointer as the + knobs array to colamd or symamd. + + knobs [2]: aggressive absorption + + knobs [COLAMD_AGGRESSIVE] controls whether or not to do + aggressive absorption during the ordering. Default is TRUE. + + + ---------------------------------------------------------------------------- + colamd: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + int colamd (int n_row, int n_col, int Alen, int *A, int *p, + double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS]) ; + UF_long colamd_l (UF_long n_row, UF_long n_col, UF_long Alen, + UF_long *A, UF_long *p, double knobs [COLAMD_KNOBS], + UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Computes a column ordering (Q) of A such that P(AQ)=LU or + (AQ)'AQ=LL' have less fill-in and require fewer floating point + operations than factorizing the unpermuted matrix A or A'A, + respectively. + + Returns: + + TRUE (1) if successful, FALSE (0) otherwise. + + Arguments: + + int n_row ; Input argument. + + Number of rows in the matrix A. + Restriction: n_row >= 0. + Colamd returns FALSE if n_row is negative. + + int n_col ; Input argument. + + Number of columns in the matrix A. + Restriction: n_col >= 0. + Colamd returns FALSE if n_col is negative. + + int Alen ; Input argument. + + Restriction (see note): + Alen >= 2*nnz + 6*(n_col+1) + 4*(n_row+1) + n_col + Colamd returns FALSE if these conditions are not met. + + Note: this restriction makes an modest assumption regarding + the size of the two typedef's structures in colamd.h. + We do, however, guarantee that + + Alen >= colamd_recommended (nnz, n_row, n_col) + + will be sufficient. Note: the macro version does not check + for integer overflow, and thus is not recommended. Use + the colamd_recommended routine instead. + + int A [Alen] ; Input argument, undefined on output. + + A is an integer array of size Alen. Alen must be at least as + large as the bare minimum value given above, but this is very + low, and can result in excessive run time. For best + performance, we recommend that Alen be greater than or equal to + colamd_recommended (nnz, n_row, n_col), which adds + nnz/5 to the bare minimum value given above. + + On input, the row indices of the entries in column c of the + matrix are held in A [(p [c]) ... (p [c+1]-1)]. The row indices + in a given column c need not be in ascending order, and + duplicate row indices may be be present. However, colamd will + work a little faster if both of these conditions are met + (Colamd puts the matrix into this format, if it finds that the + the conditions are not met). + + The matrix is 0-based. That is, rows are in the range 0 to + n_row-1, and columns are in the range 0 to n_col-1. Colamd + returns FALSE if any row index is out of range. + + The contents of A are modified during ordering, and are + undefined on output. + + int p [n_col+1] ; Both input and output argument. + + p is an integer array of size n_col+1. On input, it holds the + "pointers" for the column form of the matrix A. Column c of + the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first + entry, p [0], must be zero, and p [c] <= p [c+1] must hold + for all c in the range 0 to n_col-1. The value p [n_col] is + thus the total number of entries in the pattern of the matrix A. + Colamd returns FALSE if these conditions are not met. + + On output, if colamd returns TRUE, the array p holds the column + permutation (Q, for P(AQ)=LU or (AQ)'(AQ)=LL'), where p [0] is + the first column index in the new ordering, and p [n_col-1] is + the last. That is, p [k] = j means that column j of A is the + kth pivot column, in AQ, where k is in the range 0 to n_col-1 + (p [0] = j means that column j of A is the first column in AQ). + + If colamd returns FALSE, then no permutation is returned, and + p is undefined on output. + + double knobs [COLAMD_KNOBS] ; Input argument. + + See colamd_set_defaults for a description. + + int stats [COLAMD_STATS] ; Output argument. + + Statistics on the ordering, and error status. + See colamd.h for related definitions. + Colamd returns FALSE if stats is not present. + + stats [0]: number of dense or empty rows ignored. + + stats [1]: number of dense or empty columns ignored (and + ordered last in the output permutation p) + Note that a row can become "empty" if it + contains only "dense" and/or "empty" columns, + and similarly a column can become "empty" if it + only contains "dense" and/or "empty" rows. + + stats [2]: number of garbage collections performed. + This can be excessively high if Alen is close + to the minimum required value. + + stats [3]: status code. < 0 is an error code. + > 1 is a warning or notice. + + 0 OK. Each column of the input matrix contained + row indices in increasing order, with no + duplicates. + + 1 OK, but columns of input matrix were jumbled + (unsorted columns or duplicate entries). Colamd + had to do some extra work to sort the matrix + first and remove duplicate entries, but it + still was able to return a valid permutation + (return value of colamd was TRUE). + + stats [4]: highest numbered column that + is unsorted or has duplicate + entries. + stats [5]: last seen duplicate or + unsorted row index. + stats [6]: number of duplicate or + unsorted row indices. + + -1 A is a null pointer + + -2 p is a null pointer + + -3 n_row is negative + + stats [4]: n_row + + -4 n_col is negative + + stats [4]: n_col + + -5 number of nonzeros in matrix is negative + + stats [4]: number of nonzeros, p [n_col] + + -6 p [0] is nonzero + + stats [4]: p [0] + + -7 A is too small + + stats [4]: required size + stats [5]: actual size (Alen) + + -8 a column has a negative number of entries + + stats [4]: column with < 0 entries + stats [5]: number of entries in col + + -9 a row index is out of bounds + + stats [4]: column with bad row index + stats [5]: bad row index + stats [6]: n_row, # of rows of matrx + + -10 (unused; see symamd.c) + + -999 (unused; see symamd.c) + + Future versions may return more statistics in the stats array. + + Example: + + See http://www.cise.ufl.edu/research/sparse/colamd/example.c + for a complete example. + + To order the columns of a 5-by-4 matrix with 11 nonzero entries in + the following nonzero pattern + + x 0 x 0 + x 0 x x + 0 x x 0 + 0 0 x x + x x 0 0 + + with default knobs and no output statistics, do the following: + + #include "colamd.h" + #define ALEN 100 + int A [ALEN] = {0, 1, 4, 2, 4, 0, 1, 2, 3, 1, 3} ; + int p [ ] = {0, 3, 5, 9, 11} ; + int stats [COLAMD_STATS] ; + colamd (5, 4, ALEN, A, p, (double *) NULL, stats) ; + + The permutation is returned in the array p, and A is destroyed. + + ---------------------------------------------------------------------------- + symamd: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + int symamd (int n, int *A, int *p, int *perm, + double knobs [COLAMD_KNOBS], int stats [COLAMD_STATS], + void (*allocate) (size_t, size_t), void (*release) (void *)) ; + UF_long symamd_l (UF_long n, UF_long *A, UF_long *p, UF_long *perm, + double knobs [COLAMD_KNOBS], UF_long stats [COLAMD_STATS], + void (*allocate) (size_t, size_t), void (*release) (void *)) ; + + Purpose: + + The symamd routine computes an ordering P of a symmetric sparse + matrix A such that the Cholesky factorization PAP' = LL' remains + sparse. It is based on a column ordering of a matrix M constructed + so that the nonzero pattern of M'M is the same as A. The matrix A + is assumed to be symmetric; only the strictly lower triangular part + is accessed. You must pass your selected memory allocator (usually + calloc/free or mxCalloc/mxFree) to symamd, for it to allocate + memory for the temporary matrix M. + + Returns: + + TRUE (1) if successful, FALSE (0) otherwise. + + Arguments: + + int n ; Input argument. + + Number of rows and columns in the symmetrix matrix A. + Restriction: n >= 0. + Symamd returns FALSE if n is negative. + + int A [nnz] ; Input argument. + + A is an integer array of size nnz, where nnz = p [n]. + + The row indices of the entries in column c of the matrix are + held in A [(p [c]) ... (p [c+1]-1)]. The row indices in a + given column c need not be in ascending order, and duplicate + row indices may be present. However, symamd will run faster + if the columns are in sorted order with no duplicate entries. + + The matrix is 0-based. That is, rows are in the range 0 to + n-1, and columns are in the range 0 to n-1. Symamd + returns FALSE if any row index is out of range. + + The contents of A are not modified. + + int p [n+1] ; Input argument. + + p is an integer array of size n+1. On input, it holds the + "pointers" for the column form of the matrix A. Column c of + the matrix A is held in A [(p [c]) ... (p [c+1]-1)]. The first + entry, p [0], must be zero, and p [c] <= p [c+1] must hold + for all c in the range 0 to n-1. The value p [n] is + thus the total number of entries in the pattern of the matrix A. + Symamd returns FALSE if these conditions are not met. + + The contents of p are not modified. + + int perm [n+1] ; Output argument. + + On output, if symamd returns TRUE, the array perm holds the + permutation P, where perm [0] is the first index in the new + ordering, and perm [n-1] is the last. That is, perm [k] = j + means that row and column j of A is the kth column in PAP', + where k is in the range 0 to n-1 (perm [0] = j means + that row and column j of A are the first row and column in + PAP'). The array is used as a workspace during the ordering, + which is why it must be of length n+1, not just n. + + double knobs [COLAMD_KNOBS] ; Input argument. + + See colamd_set_defaults for a description. + + int stats [COLAMD_STATS] ; Output argument. + + Statistics on the ordering, and error status. + See colamd.h for related definitions. + Symamd returns FALSE if stats is not present. + + stats [0]: number of dense or empty row and columns ignored + (and ordered last in the output permutation + perm). Note that a row/column can become + "empty" if it contains only "dense" and/or + "empty" columns/rows. + + stats [1]: (same as stats [0]) + + stats [2]: number of garbage collections performed. + + stats [3]: status code. < 0 is an error code. + > 1 is a warning or notice. + + 0 OK. Each column of the input matrix contained + row indices in increasing order, with no + duplicates. + + 1 OK, but columns of input matrix were jumbled + (unsorted columns or duplicate entries). Symamd + had to do some extra work to sort the matrix + first and remove duplicate entries, but it + still was able to return a valid permutation + (return value of symamd was TRUE). + + stats [4]: highest numbered column that + is unsorted or has duplicate + entries. + stats [5]: last seen duplicate or + unsorted row index. + stats [6]: number of duplicate or + unsorted row indices. + + -1 A is a null pointer + + -2 p is a null pointer + + -3 (unused, see colamd.c) + + -4 n is negative + + stats [4]: n + + -5 number of nonzeros in matrix is negative + + stats [4]: # of nonzeros (p [n]). + + -6 p [0] is nonzero + + stats [4]: p [0] + + -7 (unused) + + -8 a column has a negative number of entries + + stats [4]: column with < 0 entries + stats [5]: number of entries in col + + -9 a row index is out of bounds + + stats [4]: column with bad row index + stats [5]: bad row index + stats [6]: n_row, # of rows of matrx + + -10 out of memory (unable to allocate temporary + workspace for M or count arrays using the + "allocate" routine passed into symamd). + + Future versions may return more statistics in the stats array. + + void * (*allocate) (size_t, size_t) + + A pointer to a function providing memory allocation. The + allocated memory must be returned initialized to zero. For a + C application, this argument should normally be a pointer to + calloc. For a MATLAB mexFunction, the routine mxCalloc is + passed instead. + + void (*release) (size_t, size_t) + + A pointer to a function that frees memory allocated by the + memory allocation routine above. For a C application, this + argument should normally be a pointer to free. For a MATLAB + mexFunction, the routine mxFree is passed instead. + + + ---------------------------------------------------------------------------- + colamd_report: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + colamd_report (int stats [COLAMD_STATS]) ; + colamd_l_report (UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Prints the error status and statistics recorded in the stats + array on the standard error output (for a standard C routine) + or on the MATLAB output (for a mexFunction). + + Arguments: + + int stats [COLAMD_STATS] ; Input only. Statistics from colamd. + + + ---------------------------------------------------------------------------- + symamd_report: + ---------------------------------------------------------------------------- + + C syntax: + + #include "colamd.h" + symamd_report (int stats [COLAMD_STATS]) ; + symamd_l_report (UF_long stats [COLAMD_STATS]) ; + + Purpose: + + Prints the error status and statistics recorded in the stats + array on the standard error output (for a standard C routine) + or on the MATLAB output (for a mexFunction). + + Arguments: + + int stats [COLAMD_STATS] ; Input only. Statistics from symamd. + + +*/ + +/* ========================================================================== */ +/* === Scaffolding code definitions ======================================== */ +/* ========================================================================== */ + +/* Ensure that debugging is turned off: */ +#ifndef NDEBUG +#define NDEBUG +#endif + +/* turn on debugging by uncommenting the following line + #undef NDEBUG +*/ + +/* + Our "scaffolding code" philosophy: In our opinion, well-written library + code should keep its "debugging" code, and just normally have it turned off + by the compiler so as not to interfere with performance. This serves + several purposes: + + (1) assertions act as comments to the reader, telling you what the code + expects at that point. All assertions will always be true (unless + there really is a bug, of course). + + (2) leaving in the scaffolding code assists anyone who would like to modify + the code, or understand the algorithm (by reading the debugging output, + one can get a glimpse into what the code is doing). + + (3) (gasp!) for actually finding bugs. This code has been heavily tested + and "should" be fully functional and bug-free ... but you never know... + + The code will become outrageously slow when debugging is + enabled. To control the level of debugging output, set an environment + variable D to 0 (little), 1 (some), 2, 3, or 4 (lots). When debugging, + you should see the following message on the standard output: + + colamd: debug version, D = 1 (THIS WILL BE SLOW!) + + or a similar message for symamd. If you don't, then debugging has not + been enabled. + +*/ + +/* ========================================================================== */ +/* === Include files ======================================================== */ +/* ========================================================================== */ + +#include "colamd.h" +#include +#include + +#ifdef MATLAB_MEX_FILE +#include "mex.h" +#include "matrix.h" +#endif /* MATLAB_MEX_FILE */ + +#if !defined (NPRINT) || !defined (NDEBUG) +#include +#endif + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +/* ========================================================================== */ +/* === int or UF_long ======================================================= */ +/* ========================================================================== */ + +/* define UF_long */ +#include "UFconfig.h" + +#ifdef DLONG + +#define Int UF_long +#define ID UF_long_id +#define Int_MAX UF_long_max + +#define COLAMD_recommended colamd_l_recommended +#define COLAMD_set_defaults colamd_l_set_defaults +#define COLAMD_MAIN colamd_l +#define SYMAMD_MAIN symamd_l +#define COLAMD_report colamd_l_report +#define SYMAMD_report symamd_l_report + +#else + +#define Int int +#define ID "%d" +#define Int_MAX INT_MAX + +#define COLAMD_recommended colamd_recommended +#define COLAMD_set_defaults colamd_set_defaults +#define COLAMD_MAIN colamd +#define SYMAMD_MAIN symamd +#define COLAMD_report colamd_report +#define SYMAMD_report symamd_report + +#endif + +/* ========================================================================== */ +/* === Row and Column structures ============================================ */ +/* ========================================================================== */ + +/* User code that makes use of the colamd/symamd routines need not directly */ +/* reference these structures. They are used only for colamd_recommended. */ + +typedef struct Colamd_Col_struct +{ + Int start ; /* index for A of first row in this column, or DEAD */ + /* if column is dead */ + Int length ; /* number of rows in this column */ + union + { + Int thickness ; /* number of original columns represented by this */ + /* col, if the column is alive */ + Int parent ; /* parent in parent tree super-column structure, if */ + /* the column is dead */ + } shared1 ; + union + { + Int score ; /* the score used to maintain heap, if col is alive */ + Int order ; /* pivot ordering of this column, if col is dead */ + } shared2 ; + union + { + Int headhash ; /* head of a hash bucket, if col is at the head of */ + /* a degree list */ + Int hash ; /* hash value, if col is not in a degree list */ + Int prev ; /* previous column in degree list, if col is in a */ + /* degree list (but not at the head of a degree list) */ + } shared3 ; + union + { + Int degree_next ; /* next column, if col is in a degree list */ + Int hash_next ; /* next column, if col is in a hash list */ + } shared4 ; + +} Colamd_Col ; + +typedef struct Colamd_Row_struct +{ + Int start ; /* index for A of first col in this row */ + Int length ; /* number of principal columns in this row */ + union + { + Int degree ; /* number of principal & non-principal columns in row */ + Int p ; /* used as a row pointer in init_rows_cols () */ + } shared1 ; + union + { + Int mark ; /* for computing set differences and marking dead rows*/ + Int first_column ;/* first column in row (used in garbage collection) */ + } shared2 ; + +} Colamd_Row ; + +/* ========================================================================== */ +/* === Definitions ========================================================== */ +/* ========================================================================== */ + +/* Routines are either PUBLIC (user-callable) or PRIVATE (not user-callable) */ +#define PUBLIC +#define PRIVATE static + +#define DENSE_DEGREE(alpha,n) \ + ((Int) MAX (16.0, (alpha) * sqrt ((double) (n)))) + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define ONES_COMPLEMENT(r) (-(r)-1) + +/* -------------------------------------------------------------------------- */ +/* Change for version 2.1: define TRUE and FALSE only if not yet defined */ +/* -------------------------------------------------------------------------- */ + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* -------------------------------------------------------------------------- */ + +#define EMPTY (-1) + +/* Row and column status */ +#define ALIVE (0) +#define DEAD (-1) + +/* Column status */ +#define DEAD_PRINCIPAL (-1) +#define DEAD_NON_PRINCIPAL (-2) + +/* Macros for row and column status update and checking. */ +#define ROW_IS_DEAD(r) ROW_IS_MARKED_DEAD (Row[r].shared2.mark) +#define ROW_IS_MARKED_DEAD(row_mark) (row_mark < ALIVE) +#define ROW_IS_ALIVE(r) (Row [r].shared2.mark >= ALIVE) +#define COL_IS_DEAD(c) (Col [c].start < ALIVE) +#define COL_IS_ALIVE(c) (Col [c].start >= ALIVE) +#define COL_IS_DEAD_PRINCIPAL(c) (Col [c].start == DEAD_PRINCIPAL) +#define KILL_ROW(r) { Row [r].shared2.mark = DEAD ; } +#define KILL_PRINCIPAL_COL(c) { Col [c].start = DEAD_PRINCIPAL ; } +#define KILL_NON_PRINCIPAL_COL(c) { Col [c].start = DEAD_NON_PRINCIPAL ; } + +/* ========================================================================== */ +/* === Colamd reporting mechanism =========================================== */ +/* ========================================================================== */ + +#if defined (MATLAB_MEX_FILE) || defined (MATHWORKS) +/* In MATLAB, matrices are 1-based to the user, but 0-based internally */ +#define INDEX(i) ((i)+1) +#else +/* In C, matrices are 0-based and indices are reported as such in *_report */ +#define INDEX(i) (i) +#endif + +/* All output goes through the PRINTF macro. */ +#define PRINTF(params) { if (colamd_printf != NULL) (void) colamd_printf params ; } + +/* ========================================================================== */ +/* === Prototypes of PRIVATE routines ======================================= */ +/* ========================================================================== */ + +PRIVATE Int init_rows_cols +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int p [], + Int stats [COLAMD_STATS] +) ; + +PRIVATE void init_scoring +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int head [], + double knobs [COLAMD_KNOBS], + Int *p_n_row2, + Int *p_n_col2, + Int *p_max_deg +) ; + +PRIVATE Int find_ordering +( + Int n_row, + Int n_col, + Int Alen, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int head [], + Int n_col2, + Int max_deg, + Int pfree, + Int aggressive +) ; + +PRIVATE void order_children +( + Int n_col, + Colamd_Col Col [], + Int p [] +) ; + +PRIVATE void detect_super_cols +( + +#ifndef NDEBUG + Int n_col, + Colamd_Row Row [], +#endif /* NDEBUG */ + + Colamd_Col Col [], + Int A [], + Int head [], + Int row_start, + Int row_length +) ; + +PRIVATE Int garbage_collection +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int *pfree +) ; + +PRIVATE Int clear_mark +( + Int tag_mark, + Int max_mark, + Int n_row, + Colamd_Row Row [] +) ; + +PRIVATE void print_report +( + char *method, + Int stats [COLAMD_STATS] +) ; + +/* ========================================================================== */ +/* === Debugging prototypes and definitions ================================= */ +/* ========================================================================== */ + +#ifndef NDEBUG + +#include + +/* colamd_debug is the *ONLY* global variable, and is only */ +/* present when debugging */ + +PRIVATE Int colamd_debug = 0 ; /* debug print level */ + +#define DEBUG0(params) { PRINTF (params) ; } +#define DEBUG1(params) { if (colamd_debug >= 1) PRINTF (params) ; } +#define DEBUG2(params) { if (colamd_debug >= 2) PRINTF (params) ; } +#define DEBUG3(params) { if (colamd_debug >= 3) PRINTF (params) ; } +#define DEBUG4(params) { if (colamd_debug >= 4) PRINTF (params) ; } + +#ifdef MATLAB_MEX_FILE +#define ASSERT(expression) (mxAssert ((expression), "")) +#else +#define ASSERT(expression) (assert (expression)) +#endif /* MATLAB_MEX_FILE */ + +PRIVATE void colamd_get_debug /* gets the debug print level from getenv */ +( + char *method +) ; + +PRIVATE void debug_deg_lists +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int head [], + Int min_score, + Int should, + Int max_deg +) ; + +PRIVATE void debug_mark +( + Int n_row, + Colamd_Row Row [], + Int tag_mark, + Int max_mark +) ; + +PRIVATE void debug_matrix +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [] +) ; + +PRIVATE void debug_structures +( + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int n_col2 +) ; + +#else /* NDEBUG */ + +/* === No debugging ========================================================= */ + +#define DEBUG0(params) ; +#define DEBUG1(params) ; +#define DEBUG2(params) ; +#define DEBUG3(params) ; +#define DEBUG4(params) ; + +#define ASSERT(expression) + +#endif /* NDEBUG */ + +/* ========================================================================== */ +/* === USER-CALLABLE ROUTINES: ============================================== */ +/* ========================================================================== */ + +/* ========================================================================== */ +/* === colamd_recommended =================================================== */ +/* ========================================================================== */ + +/* + The colamd_recommended routine returns the suggested size for Alen. This + value has been determined to provide good balance between the number of + garbage collections and the memory requirements for colamd. If any + argument is negative, or if integer overflow occurs, a 0 is returned as an + error condition. 2*nnz space is required for the row and column + indices of the matrix. COLAMD_C (n_col) + COLAMD_R (n_row) space is + required for the Col and Row arrays, respectively, which are internal to + colamd (roughly 6*n_col + 4*n_row). An additional n_col space is the + minimal amount of "elbow room", and nnz/5 more space is recommended for + run time efficiency. + + Alen is approximately 2.2*nnz + 7*n_col + 4*n_row + 10. + + This function is not needed when using symamd. +*/ + +/* add two values of type size_t, and check for integer overflow */ +static size_t t_add (size_t a, size_t b, int *ok) +{ + (*ok) = (*ok) && ((a + b) >= MAX (a,b)) ; + return ((*ok) ? (a + b) : 0) ; +} + +/* compute a*k where k is a small integer, and check for integer overflow */ +static size_t t_mult (size_t a, size_t k, int *ok) +{ + size_t i, s = 0 ; + for (i = 0 ; i < k ; i++) + { + s = t_add (s, a, ok) ; + } + return (s) ; +} + +/* size of the Col and Row structures */ +#define COLAMD_C(n_col,ok) \ + ((t_mult (t_add (n_col, 1, ok), sizeof (Colamd_Col), ok) / sizeof (Int))) + +#define COLAMD_R(n_row,ok) \ + ((t_mult (t_add (n_row, 1, ok), sizeof (Colamd_Row), ok) / sizeof (Int))) + + +PUBLIC size_t COLAMD_recommended /* returns recommended value of Alen. */ +( + /* === Parameters ======================================================= */ + + Int nnz, /* number of nonzeros in A */ + Int n_row, /* number of rows in A */ + Int n_col /* number of columns in A */ +) +{ + size_t s, c, r ; + int ok = TRUE ; + if (nnz < 0 || n_row < 0 || n_col < 0) + { + return (0) ; + } + s = t_mult (nnz, 2, &ok) ; /* 2*nnz */ + c = COLAMD_C (n_col, &ok) ; /* size of column structures */ + r = COLAMD_R (n_row, &ok) ; /* size of row structures */ + s = t_add (s, c, &ok) ; + s = t_add (s, r, &ok) ; + s = t_add (s, n_col, &ok) ; /* elbow room */ + s = t_add (s, nnz/5, &ok) ; /* elbow room */ + ok = ok && (s < Int_MAX) ; + return (ok ? s : 0) ; +} + + +/* ========================================================================== */ +/* === colamd_set_defaults ================================================== */ +/* ========================================================================== */ + +/* + The colamd_set_defaults routine sets the default values of the user- + controllable parameters for colamd and symamd: + + Colamd: rows with more than max (16, knobs [0] * sqrt (n_col)) + entries are removed prior to ordering. Columns with more than + max (16, knobs [1] * sqrt (MIN (n_row,n_col))) entries are removed + prior to ordering, and placed last in the output column ordering. + + Symamd: Rows and columns with more than max (16, knobs [0] * sqrt (n)) + entries are removed prior to ordering, and placed last in the + output ordering. + + knobs [0] dense row control + + knobs [1] dense column control + + knobs [2] if nonzero, do aggresive absorption + + knobs [3..19] unused, but future versions might use this + +*/ + +PUBLIC void COLAMD_set_defaults +( + /* === Parameters ======================================================= */ + + double knobs [COLAMD_KNOBS] /* knob array */ +) +{ + /* === Local variables ================================================== */ + + Int i ; + + if (!knobs) + { + return ; /* no knobs to initialize */ + } + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + knobs [i] = 0 ; + } + knobs [COLAMD_DENSE_ROW] = 10 ; + knobs [COLAMD_DENSE_COL] = 10 ; + knobs [COLAMD_AGGRESSIVE] = TRUE ; /* default: do aggressive absorption*/ +} + + +/* ========================================================================== */ +/* === symamd =============================================================== */ +/* ========================================================================== */ + +PUBLIC Int SYMAMD_MAIN /* return TRUE if OK, FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + Int n, /* number of rows and columns of A */ + Int A [], /* row indices of A */ + Int p [], /* column pointers of A */ + Int perm [], /* output permutation, size n+1 */ + double knobs [COLAMD_KNOBS], /* parameters (uses defaults if NULL) */ + Int stats [COLAMD_STATS], /* output statistics and error codes */ + void * (*allocate) (size_t, size_t), + /* pointer to calloc (ANSI C) or */ + /* mxCalloc (for MATLAB mexFunction) */ + void (*release) (void *) + /* pointer to free (ANSI C) or */ + /* mxFree (for MATLAB mexFunction) */ +) +{ + /* === Local variables ================================================== */ + + Int *count ; /* length of each column of M, and col pointer*/ + Int *mark ; /* mark array for finding duplicate entries */ + Int *M ; /* row indices of matrix M */ + size_t Mlen ; /* length of M */ + Int n_row ; /* number of rows in M */ + Int nnz ; /* number of entries in A */ + Int i ; /* row index of A */ + Int j ; /* column index of A */ + Int k ; /* row index of M */ + Int mnz ; /* number of nonzeros in M */ + Int pp ; /* index into a column of A */ + Int last_row ; /* last row seen in the current column */ + Int length ; /* number of nonzeros in a column */ + + double cknobs [COLAMD_KNOBS] ; /* knobs for colamd */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs for colamd */ + +#ifndef NDEBUG + colamd_get_debug ("symamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("symamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("symamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("symamd: p not present\n")) ; + return (FALSE) ; + } + + if (n < 0) /* n must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n ; + DEBUG0 (("symamd: n negative %d\n", n)) ; + return (FALSE) ; + } + + nnz = p [n] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("symamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("symamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + COLAMD_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + /* === Allocate count and mark ========================================== */ + + count = (Int *) ((*allocate) (n+1, sizeof (Int))) ; + if (!count) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + DEBUG0 (("symamd: allocate count (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + mark = (Int *) ((*allocate) (n+1, sizeof (Int))) ; + if (!mark) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + DEBUG0 (("symamd: allocate mark (size %d) failed\n", n+1)) ; + return (FALSE) ; + } + + /* === Compute column counts of M, check if A is valid ================== */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + + for (j = 0 ; j < n ; j++) + { + last_row = -1 ; + + length = p [j+1] - p [j] ; + if (length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = length ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: col %d negative length %d\n", j, length)) ; + return (FALSE) ; + } + + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + if (i < 0 || i >= n) + { + /* row index i, in column j, is out of bounds */ + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + stats [COLAMD_INFO3] = n ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: row %d col %d out of bounds\n", i, j)) ; + return (FALSE) ; + } + + if (i <= last_row || mark [i] == j) + { + /* row index is unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = j ; + stats [COLAMD_INFO2] = i ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("symamd: row %d col %d unsorted/duplicate\n", i, j)) ; + } + + if (i > j && mark [i] != j) + { + /* row k of M will contain column indices i and j */ + count [i]++ ; + count [j]++ ; + } + + /* mark the row as having been seen in this column */ + mark [i] = j ; + + last_row = i ; + } + } + + /* v2.4: removed free(mark) */ + + /* === Compute column pointers of M ===================================== */ + + /* use output permutation, perm, for column pointers of M */ + perm [0] = 0 ; + for (j = 1 ; j <= n ; j++) + { + perm [j] = perm [j-1] + count [j-1] ; + } + for (j = 0 ; j < n ; j++) + { + count [j] = perm [j] ; + } + + /* === Construct M ====================================================== */ + + mnz = perm [n] ; + n_row = mnz / 2 ; + Mlen = COLAMD_recommended (mnz, n_row, n) ; + M = (Int *) ((*allocate) (Mlen, sizeof (Int))) ; + DEBUG0 (("symamd: M is %d-by-%d with %d entries, Mlen = %g\n", + n_row, n, mnz, (double) Mlen)) ; + + if (!M) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_out_of_memory ; + (*release) ((void *) count) ; + (*release) ((void *) mark) ; + DEBUG0 (("symamd: allocate M (size %g) failed\n", (double) Mlen)) ; + return (FALSE) ; + } + + k = 0 ; + + if (stats [COLAMD_STATUS] == COLAMD_OK) + { + /* Matrix is OK */ + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + } + } + } + } + else + { + /* Matrix is jumbled. Do not add duplicates to M. Unsorted cols OK. */ + DEBUG0 (("symamd: Duplicates in A.\n")) ; + for (i = 0 ; i < n ; i++) + { + mark [i] = -1 ; + } + for (j = 0 ; j < n ; j++) + { + ASSERT (p [j+1] - p [j] >= 0) ; + for (pp = p [j] ; pp < p [j+1] ; pp++) + { + i = A [pp] ; + ASSERT (i >= 0 && i < n) ; + if (i > j && mark [i] != j) + { + /* row k of M contains column indices i and j */ + M [count [i]++] = k ; + M [count [j]++] = k ; + k++ ; + mark [i] = j ; + } + } + } + /* v2.4: free(mark) moved below */ + } + + /* count and mark no longer needed */ + (*release) ((void *) count) ; + (*release) ((void *) mark) ; /* v2.4: free (mark) moved here */ + ASSERT (k == n_row) ; + + /* === Adjust the knobs for M =========================================== */ + + for (i = 0 ; i < COLAMD_KNOBS ; i++) + { + cknobs [i] = knobs [i] ; + } + + /* there are no dense rows in M */ + cknobs [COLAMD_DENSE_ROW] = -1 ; + cknobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW] ; + + /* === Order the columns of M =========================================== */ + + /* v2.4: colamd cannot fail here, so the error check is removed */ + (void) COLAMD_MAIN (n_row, n, (Int) Mlen, M, perm, cknobs, stats) ; + + /* Note that the output permutation is now in perm */ + + /* === get the statistics for symamd from colamd ======================== */ + + /* a dense column in colamd means a dense row and col in symamd */ + stats [COLAMD_DENSE_ROW] = stats [COLAMD_DENSE_COL] ; + + /* === Free M =========================================================== */ + + (*release) ((void *) M) ; + DEBUG0 (("symamd: done.\n")) ; + return (TRUE) ; + +} + +/* ========================================================================== */ +/* === colamd =============================================================== */ +/* ========================================================================== */ + +/* + The colamd routine computes a column ordering Q of a sparse matrix + A such that the LU factorization P(AQ) = LU remains sparse, where P is + selected via partial pivoting. The routine can also be viewed as + providing a permutation Q such that the Cholesky factorization + (AQ)'(AQ) = LL' remains sparse. +*/ + +PUBLIC Int COLAMD_MAIN /* returns TRUE if successful, FALSE otherwise*/ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows in A */ + Int n_col, /* number of columns in A */ + Int Alen, /* length of A */ + Int A [], /* row indices of A */ + Int p [], /* pointers to columns in A */ + double knobs [COLAMD_KNOBS],/* parameters (uses defaults if NULL) */ + Int stats [COLAMD_STATS] /* output statistics and error codes */ +) +{ + /* === Local variables ================================================== */ + + Int i ; /* loop index */ + Int nnz ; /* nonzeros in A */ + size_t Row_size ; /* size of Row [], in integers */ + size_t Col_size ; /* size of Col [], in integers */ + size_t need ; /* minimum required length of A */ + Colamd_Row *Row ; /* pointer into A of Row [0..n_row] array */ + Colamd_Col *Col ; /* pointer into A of Col [0..n_col] array */ + Int n_col2 ; /* number of non-dense, non-empty columns */ + Int n_row2 ; /* number of non-dense, non-empty rows */ + Int ngarbage ; /* number of garbage collections performed */ + Int max_deg ; /* maximum row degree */ + double default_knobs [COLAMD_KNOBS] ; /* default knobs array */ + Int aggressive ; /* do aggressive absorption */ + int ok ; + +#ifndef NDEBUG + colamd_get_debug ("colamd") ; +#endif /* NDEBUG */ + + /* === Check the input arguments ======================================== */ + + if (!stats) + { + DEBUG0 (("colamd: stats not present\n")) ; + return (FALSE) ; + } + for (i = 0 ; i < COLAMD_STATS ; i++) + { + stats [i] = 0 ; + } + stats [COLAMD_STATUS] = COLAMD_OK ; + stats [COLAMD_INFO1] = -1 ; + stats [COLAMD_INFO2] = -1 ; + + if (!A) /* A is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_A_not_present ; + DEBUG0 (("colamd: A not present\n")) ; + return (FALSE) ; + } + + if (!p) /* p is not present */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p_not_present ; + DEBUG0 (("colamd: p not present\n")) ; + return (FALSE) ; + } + + if (n_row < 0) /* n_row must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nrow_negative ; + stats [COLAMD_INFO1] = n_row ; + DEBUG0 (("colamd: nrow negative %d\n", n_row)) ; + return (FALSE) ; + } + + if (n_col < 0) /* n_col must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_ncol_negative ; + stats [COLAMD_INFO1] = n_col ; + DEBUG0 (("colamd: ncol negative %d\n", n_col)) ; + return (FALSE) ; + } + + nnz = p [n_col] ; + if (nnz < 0) /* nnz must be >= 0 */ + { + stats [COLAMD_STATUS] = COLAMD_ERROR_nnz_negative ; + stats [COLAMD_INFO1] = nnz ; + DEBUG0 (("colamd: number of entries negative %d\n", nnz)) ; + return (FALSE) ; + } + + if (p [0] != 0) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_p0_nonzero ; + stats [COLAMD_INFO1] = p [0] ; + DEBUG0 (("colamd: p[0] not zero %d\n", p [0])) ; + return (FALSE) ; + } + + /* === If no knobs, set default knobs =================================== */ + + if (!knobs) + { + COLAMD_set_defaults (default_knobs) ; + knobs = default_knobs ; + } + + aggressive = (knobs [COLAMD_AGGRESSIVE] != FALSE) ; + + /* === Allocate the Row and Col arrays from array A ===================== */ + + ok = TRUE ; + Col_size = COLAMD_C (n_col, &ok) ; /* size of Col array of structs */ + Row_size = COLAMD_R (n_row, &ok) ; /* size of Row array of structs */ + + /* need = 2*nnz + n_col + Col_size + Row_size ; */ + need = t_mult (nnz, 2, &ok) ; + need = t_add (need, n_col, &ok) ; + need = t_add (need, Col_size, &ok) ; + need = t_add (need, Row_size, &ok) ; + + if (!ok || need > (size_t) Alen || need > Int_MAX) + { + /* not enough space in array A to perform the ordering */ + stats [COLAMD_STATUS] = COLAMD_ERROR_A_too_small ; + stats [COLAMD_INFO1] = need ; + stats [COLAMD_INFO2] = Alen ; + DEBUG0 (("colamd: Need Alen >= %d, given only Alen = %d\n", need,Alen)); + return (FALSE) ; + } + + Alen -= Col_size + Row_size ; + Col = (Colamd_Col *) &A [Alen] ; + Row = (Colamd_Row *) &A [Alen + Col_size] ; + + /* === Construct the row and column data structures ===================== */ + + if (!init_rows_cols (n_row, n_col, Row, Col, A, p, stats)) + { + /* input matrix is invalid */ + DEBUG0 (("colamd: Matrix invalid\n")) ; + return (FALSE) ; + } + + /* === Initialize scores, kill dense rows/columns ======================= */ + + init_scoring (n_row, n_col, Row, Col, A, p, knobs, + &n_row2, &n_col2, &max_deg) ; + + /* === Order the supercolumns =========================================== */ + + ngarbage = find_ordering (n_row, n_col, Alen, Row, Col, A, p, + n_col2, max_deg, 2*nnz, aggressive) ; + + /* === Order the non-principal columns ================================== */ + + order_children (n_col, Col, p) ; + + /* === Return statistics in stats ======================================= */ + + stats [COLAMD_DENSE_ROW] = n_row - n_row2 ; + stats [COLAMD_DENSE_COL] = n_col - n_col2 ; + stats [COLAMD_DEFRAG_COUNT] = ngarbage ; + DEBUG0 (("colamd: done.\n")) ; + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === colamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void COLAMD_report +( + Int stats [COLAMD_STATS] +) +{ + print_report ("colamd", stats) ; +} + + +/* ========================================================================== */ +/* === symamd_report ======================================================== */ +/* ========================================================================== */ + +PUBLIC void SYMAMD_report +( + Int stats [COLAMD_STATS] +) +{ + print_report ("symamd", stats) ; +} + + + +/* ========================================================================== */ +/* === NON-USER-CALLABLE ROUTINES: ========================================== */ +/* ========================================================================== */ + +/* There are no user-callable routines beyond this point in the file */ + + +/* ========================================================================== */ +/* === init_rows_cols ======================================================= */ +/* ========================================================================== */ + +/* + Takes the column form of the matrix in A and creates the row form of the + matrix. Also, row and column attributes are stored in the Col and Row + structs. If the columns are un-sorted or contain duplicate row indices, + this routine will also sort and remove duplicate row indices from the + column form of the matrix. Returns FALSE if the matrix is invalid, + TRUE otherwise. Not user-callable. +*/ + +PRIVATE Int init_rows_cols /* returns TRUE if OK, or FALSE otherwise */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* row indices of A, of size Alen */ + Int p [], /* pointers to columns in A, of size n_col+1 */ + Int stats [COLAMD_STATS] /* colamd statistics */ +) +{ + /* === Local variables ================================================== */ + + Int col ; /* a column index */ + Int row ; /* a row index */ + Int *cp ; /* a column pointer */ + Int *cp_end ; /* a pointer to the end of a column */ + Int *rp ; /* a row pointer */ + Int *rp_end ; /* a pointer to the end of a row */ + Int last_row ; /* previous row */ + + /* === Initialize columns, and check column pointers ==================== */ + + for (col = 0 ; col < n_col ; col++) + { + Col [col].start = p [col] ; + Col [col].length = p [col+1] - p [col] ; + + if (Col [col].length < 0) + { + /* column pointers must be non-decreasing */ + stats [COLAMD_STATUS] = COLAMD_ERROR_col_length_negative ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = Col [col].length ; + DEBUG0 (("colamd: col %d length %d < 0\n", col, Col [col].length)) ; + return (FALSE) ; + } + + Col [col].shared1.thickness = 1 ; + Col [col].shared2.score = 0 ; + Col [col].shared3.prev = EMPTY ; + Col [col].shared4.degree_next = EMPTY ; + } + + /* p [0..n_col] no longer needed, used as "head" in subsequent routines */ + + /* === Scan columns, compute row degrees, and check row indices ========= */ + + stats [COLAMD_INFO3] = 0 ; /* number of duplicate or unsorted row indices*/ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].length = 0 ; + Row [row].shared2.mark = -1 ; + } + + for (col = 0 ; col < n_col ; col++) + { + last_row = -1 ; + + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + + while (cp < cp_end) + { + row = *cp++ ; + + /* make sure row indices within range */ + if (row < 0 || row >= n_row) + { + stats [COLAMD_STATUS] = COLAMD_ERROR_row_index_out_of_bounds ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + stats [COLAMD_INFO3] = n_row ; + DEBUG0 (("colamd: row %d col %d out of bounds\n", row, col)) ; + return (FALSE) ; + } + + if (row <= last_row || Row [row].shared2.mark == col) + { + /* row index are unsorted or repeated (or both), thus col */ + /* is jumbled. This is a notice, not an error condition. */ + stats [COLAMD_STATUS] = COLAMD_OK_BUT_JUMBLED ; + stats [COLAMD_INFO1] = col ; + stats [COLAMD_INFO2] = row ; + (stats [COLAMD_INFO3]) ++ ; + DEBUG1 (("colamd: row %d col %d unsorted/duplicate\n",row,col)); + } + + if (Row [row].shared2.mark != col) + { + Row [row].length++ ; + } + else + { + /* this is a repeated entry in the column, */ + /* it will be removed */ + Col [col].length-- ; + } + + /* mark the row as having been seen in this column */ + Row [row].shared2.mark = col ; + + last_row = row ; + } + } + + /* === Compute row pointers ============================================= */ + + /* row form of the matrix starts directly after the column */ + /* form of matrix in A */ + Row [0].start = p [n_col] ; + Row [0].shared1.p = Row [0].start ; + Row [0].shared2.mark = -1 ; + for (row = 1 ; row < n_row ; row++) + { + Row [row].start = Row [row-1].start + Row [row-1].length ; + Row [row].shared1.p = Row [row].start ; + Row [row].shared2.mark = -1 ; + } + + /* === Create row form ================================================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + /* if cols jumbled, watch for repeated row indices */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + row = *cp++ ; + if (Row [row].shared2.mark != col) + { + A [(Row [row].shared1.p)++] = col ; + Row [row].shared2.mark = col ; + } + } + } + } + else + { + /* if cols not jumbled, we don't need the mark (this is faster) */ + for (col = 0 ; col < n_col ; col++) + { + cp = &A [p [col]] ; + cp_end = &A [p [col+1]] ; + while (cp < cp_end) + { + A [(Row [*cp++].shared1.p)++] = col ; + } + } + } + + /* === Clear the row marks and set row degrees ========================== */ + + for (row = 0 ; row < n_row ; row++) + { + Row [row].shared2.mark = 0 ; + Row [row].shared1.degree = Row [row].length ; + } + + /* === See if we need to re-create columns ============================== */ + + if (stats [COLAMD_STATUS] == COLAMD_OK_BUT_JUMBLED) + { + DEBUG0 (("colamd: reconstructing column form, matrix jumbled\n")) ; + +#ifndef NDEBUG + /* make sure column lengths are correct */ + for (col = 0 ; col < n_col ; col++) + { + p [col] = Col [col].length ; + } + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + p [*rp++]-- ; + } + } + for (col = 0 ; col < n_col ; col++) + { + ASSERT (p [col] == 0) ; + } + /* now p is all zero (different than when debugging is turned off) */ +#endif /* NDEBUG */ + + /* === Compute col pointers ========================================= */ + + /* col form of the matrix starts at A [0]. */ + /* Note, we may have a gap between the col form and the row */ + /* form if there were duplicate entries, if so, it will be */ + /* removed upon the first garbage collection */ + Col [0].start = 0 ; + p [0] = Col [0].start ; + for (col = 1 ; col < n_col ; col++) + { + /* note that the lengths here are for pruned columns, i.e. */ + /* no duplicate row indices will exist for these columns */ + Col [col].start = Col [col-1].start + Col [col-1].length ; + p [col] = Col [col].start ; + } + + /* === Re-create col form =========================================== */ + + for (row = 0 ; row < n_row ; row++) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + A [(p [*rp++])++] = row ; + } + } + } + + /* === Done. Matrix is not (or no longer) jumbled ====================== */ + + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === init_scoring ========================================================= */ +/* ========================================================================== */ + +/* + Kills dense or empty columns and rows, calculates an initial score for + each column, and places all columns in the degree lists. Not user-callable. +*/ + +PRIVATE void init_scoring +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* column form and row form of A */ + Int head [], /* of size n_col+1 */ + double knobs [COLAMD_KNOBS],/* parameters */ + Int *p_n_row2, /* number of non-dense, non-empty rows */ + Int *p_n_col2, /* number of non-dense, non-empty columns */ + Int *p_max_deg /* maximum row degree */ +) +{ + /* === Local variables ================================================== */ + + Int c ; /* a column index */ + Int r, row ; /* a row index */ + Int *cp ; /* a column pointer */ + Int deg ; /* degree of a row or column */ + Int *cp_end ; /* a pointer to the end of a column */ + Int *new_cp ; /* new column pointer */ + Int col_length ; /* length of pruned column */ + Int score ; /* current column score */ + Int n_col2 ; /* number of non-dense, non-empty columns */ + Int n_row2 ; /* number of non-dense, non-empty rows */ + Int dense_row_count ; /* remove rows with more entries than this */ + Int dense_col_count ; /* remove cols with more entries than this */ + Int min_score ; /* smallest column score */ + Int max_deg ; /* maximum row degree */ + Int next_col ; /* Used to add to degree list.*/ + +#ifndef NDEBUG + Int debug_count ; /* debug only. */ +#endif /* NDEBUG */ + + /* === Extract knobs ==================================================== */ + + /* Note: if knobs contains a NaN, this is undefined: */ + if (knobs [COLAMD_DENSE_ROW] < 0) + { + /* only remove completely dense rows */ + dense_row_count = n_col-1 ; + } + else + { + dense_row_count = DENSE_DEGREE (knobs [COLAMD_DENSE_ROW], n_col) ; + } + if (knobs [COLAMD_DENSE_COL] < 0) + { + /* only remove completely dense columns */ + dense_col_count = n_row-1 ; + } + else + { + dense_col_count = + DENSE_DEGREE (knobs [COLAMD_DENSE_COL], MIN (n_row, n_col)) ; + } + + DEBUG1 (("colamd: densecount: %d %d\n", dense_row_count, dense_col_count)) ; + max_deg = 0 ; + n_col2 = n_col ; + n_row2 = n_row ; + + /* === Kill empty columns =============================================== */ + + /* Put the empty columns at the end in their natural order, so that LU */ + /* factorization can proceed as far as possible. */ + for (c = n_col-1 ; c >= 0 ; c--) + { + deg = Col [c].length ; + if (deg == 0) + { + /* this is a empty column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense columns =============================================== */ + + /* Put the dense columns at the end, in their natural order */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip any dead columns */ + if (COL_IS_DEAD (c)) + { + continue ; + } + deg = Col [c].length ; + if (deg > dense_col_count) + { + /* this is a dense column, kill and order it last */ + Col [c].shared2.order = --n_col2 ; + /* decrement the row degrees */ + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + Row [*cp++].shared1.degree-- ; + } + KILL_PRINCIPAL_COL (c) ; + } + } + DEBUG1 (("colamd: Dense and null columns killed: %d\n", n_col - n_col2)) ; + + /* === Kill dense and empty rows ======================================== */ + + for (r = 0 ; r < n_row ; r++) + { + deg = Row [r].shared1.degree ; + ASSERT (deg >= 0 && deg <= n_col) ; + if (deg > dense_row_count || deg == 0) + { + /* kill a dense or empty row */ + KILL_ROW (r) ; + --n_row2 ; + } + else + { + /* keep track of max degree of remaining rows */ + max_deg = MAX (max_deg, deg) ; + } + } + DEBUG1 (("colamd: Dense and null rows killed: %d\n", n_row - n_row2)) ; + + /* === Compute initial column scores ==================================== */ + + /* At this point the row degrees are accurate. They reflect the number */ + /* of "live" (non-dense) columns in each row. No empty rows exist. */ + /* Some "live" columns may contain only dead rows, however. These are */ + /* pruned in the code below. */ + + /* now find the initial matlab score for each column */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* skip dead column */ + if (COL_IS_DEAD (c)) + { + continue ; + } + score = 0 ; + cp = &A [Col [c].start] ; + new_cp = cp ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + /* skip if dead */ + if (ROW_IS_DEAD (row)) + { + continue ; + } + /* compact the column */ + *new_cp++ = row ; + /* add row's external degree */ + score += Row [row].shared1.degree - 1 ; + /* guard against integer overflow */ + score = MIN (score, n_col) ; + } + /* determine pruned column length */ + col_length = (Int) (new_cp - &A [Col [c].start]) ; + if (col_length == 0) + { + /* a newly-made null column (all rows in this col are "dense" */ + /* and have already been killed) */ + DEBUG2 (("Newly null killed: %d\n", c)) ; + Col [c].shared2.order = --n_col2 ; + KILL_PRINCIPAL_COL (c) ; + } + else + { + /* set column length and set score */ + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + Col [c].length = col_length ; + Col [c].shared2.score = score ; + } + } + DEBUG1 (("colamd: Dense, null, and newly-null columns killed: %d\n", + n_col-n_col2)) ; + + /* At this point, all empty rows and columns are dead. All live columns */ + /* are "clean" (containing no dead rows) and simplicial (no supercolumns */ + /* yet). Rows may contain dead columns, but all live rows contain at */ + /* least one live column. */ + +#ifndef NDEBUG + debug_structures (n_row, n_col, Row, Col, A, n_col2) ; +#endif /* NDEBUG */ + + /* === Initialize degree lists ========================================== */ + +#ifndef NDEBUG + debug_count = 0 ; +#endif /* NDEBUG */ + + /* clear the hash buckets */ + for (c = 0 ; c <= n_col ; c++) + { + head [c] = EMPTY ; + } + min_score = n_col ; + /* place in reverse order, so low column indices are at the front */ + /* of the lists. This is to encourage natural tie-breaking */ + for (c = n_col-1 ; c >= 0 ; c--) + { + /* only add principal columns to degree lists */ + if (COL_IS_ALIVE (c)) + { + DEBUG4 (("place %d score %d minscore %d ncol %d\n", + c, Col [c].shared2.score, min_score, n_col)) ; + + /* === Add columns score to DList =============================== */ + + score = Col [c].shared2.score ; + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (score >= 0) ; + ASSERT (score <= n_col) ; + ASSERT (head [score] >= EMPTY) ; + + /* now add this column to dList at proper score location */ + next_col = head [score] ; + Col [c].shared3.prev = EMPTY ; + Col [c].shared4.degree_next = next_col ; + + /* if there already was a column with the same score, set its */ + /* previous pointer to this new column */ + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = c ; + } + head [score] = c ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, score) ; + +#ifndef NDEBUG + debug_count++ ; +#endif /* NDEBUG */ + + } + } + +#ifndef NDEBUG + DEBUG1 (("colamd: Live cols %d out of %d, non-princ: %d\n", + debug_count, n_col, n_col-debug_count)) ; + ASSERT (debug_count == n_col2) ; + debug_deg_lists (n_row, n_col, Row, Col, head, min_score, n_col2, max_deg) ; +#endif /* NDEBUG */ + + /* === Return number of remaining columns, and max row degree =========== */ + + *p_n_col2 = n_col2 ; + *p_n_row2 = n_row2 ; + *p_max_deg = max_deg ; +} + + +/* ========================================================================== */ +/* === find_ordering ======================================================== */ +/* ========================================================================== */ + +/* + Order the principal columns of the supercolumn form of the matrix + (no supercolumns on input). Uses a minimum approximate column minimum + degree ordering method. Not user-callable. +*/ + +PRIVATE Int find_ordering /* return the number of garbage collections */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows of A */ + Int n_col, /* number of columns of A */ + Int Alen, /* size of A, 2*nnz + n_col or larger */ + Colamd_Row Row [], /* of size n_row+1 */ + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* column form and row form of A */ + Int head [], /* of size n_col+1 */ + Int n_col2, /* Remaining columns to order */ + Int max_deg, /* Maximum row degree */ + Int pfree, /* index of first free slot (2*nnz on entry) */ + Int aggressive +) +{ + /* === Local variables ================================================== */ + + Int k ; /* current pivot ordering step */ + Int pivot_col ; /* current pivot column */ + Int *cp ; /* a column pointer */ + Int *rp ; /* a row pointer */ + Int pivot_row ; /* current pivot row */ + Int *new_cp ; /* modified column pointer */ + Int *new_rp ; /* modified row pointer */ + Int pivot_row_start ; /* pointer to start of pivot row */ + Int pivot_row_degree ; /* number of columns in pivot row */ + Int pivot_row_length ; /* number of supercolumns in pivot row */ + Int pivot_col_score ; /* score of pivot column */ + Int needed_memory ; /* free space needed for pivot row */ + Int *cp_end ; /* pointer to the end of a column */ + Int *rp_end ; /* pointer to the end of a row */ + Int row ; /* a row index */ + Int col ; /* a column index */ + Int max_score ; /* maximum possible score */ + Int cur_score ; /* score of current column */ + unsigned Int hash ; /* hash value for supernode detection */ + Int head_column ; /* head of hash bucket */ + Int first_col ; /* first column in hash bucket */ + Int tag_mark ; /* marker value for mark array */ + Int row_mark ; /* Row [row].shared2.mark */ + Int set_difference ; /* set difference size of row with pivot row */ + Int min_score ; /* smallest column score */ + Int col_thickness ; /* "thickness" (no. of columns in a supercol) */ + Int max_mark ; /* maximum value of tag_mark */ + Int pivot_col_thickness ; /* number of columns represented by pivot col */ + Int prev_col ; /* Used by Dlist operations. */ + Int next_col ; /* Used by Dlist operations. */ + Int ngarbage ; /* number of garbage collections performed */ + +#ifndef NDEBUG + Int debug_d ; /* debug loop counter */ + Int debug_step = 0 ; /* debug loop counter */ +#endif /* NDEBUG */ + + /* === Initialization and clear mark ==================================== */ + + max_mark = INT_MAX - n_col ; /* INT_MAX defined in */ + tag_mark = clear_mark (0, max_mark, n_row, Row) ; + min_score = 0 ; + ngarbage = 0 ; + DEBUG1 (("colamd: Ordering, n_col2=%d\n", n_col2)) ; + + /* === Order the columns ================================================ */ + + for (k = 0 ; k < n_col2 ; /* 'k' is incremented below */) + { + +#ifndef NDEBUG + if (debug_step % 100 == 0) + { + DEBUG2 (("\n... Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + else + { + DEBUG3 (("\n----------Step k: %d out of n_col2: %d\n", k, n_col2)) ; + } + debug_step++ ; + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + + /* === Select pivot column, and order it ============================ */ + + /* make sure degree list isn't empty */ + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (head [min_score] >= EMPTY) ; + +#ifndef NDEBUG + for (debug_d = 0 ; debug_d < min_score ; debug_d++) + { + ASSERT (head [debug_d] == EMPTY) ; + } +#endif /* NDEBUG */ + + /* get pivot column from head of minimum degree list */ + while (head [min_score] == EMPTY && min_score < n_col) + { + min_score++ ; + } + pivot_col = head [min_score] ; + ASSERT (pivot_col >= 0 && pivot_col <= n_col) ; + next_col = Col [pivot_col].shared4.degree_next ; + head [min_score] = next_col ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = EMPTY ; + } + + ASSERT (COL_IS_ALIVE (pivot_col)) ; + + /* remember score for defrag check */ + pivot_col_score = Col [pivot_col].shared2.score ; + + /* the pivot column is the kth column in the pivot order */ + Col [pivot_col].shared2.order = k ; + + /* increment order count by column thickness */ + pivot_col_thickness = Col [pivot_col].shared1.thickness ; + k += pivot_col_thickness ; + ASSERT (pivot_col_thickness > 0) ; + DEBUG3 (("Pivot col: %d thick %d\n", pivot_col, pivot_col_thickness)) ; + + /* === Garbage_collection, if necessary ============================= */ + + needed_memory = MIN (pivot_col_score, n_col - k) ; + if (pfree + needed_memory >= Alen) + { + pfree = garbage_collection (n_row, n_col, Row, Col, A, &A [pfree]) ; + ngarbage++ ; + /* after garbage collection we will have enough */ + ASSERT (pfree + needed_memory < Alen) ; + /* garbage collection has wiped out the Row[].shared2.mark array */ + tag_mark = clear_mark (0, max_mark, n_row, Row) ; + +#ifndef NDEBUG + debug_matrix (n_row, n_col, Row, Col, A) ; +#endif /* NDEBUG */ + } + + /* === Compute pivot row pattern ==================================== */ + + /* get starting location for this new merged row */ + pivot_row_start = pfree ; + + /* initialize new row counts to zero */ + pivot_row_degree = 0 ; + + /* tag pivot column as having been visited so it isn't included */ + /* in merged pivot row */ + Col [pivot_col].shared1.thickness = -pivot_col_thickness ; + + /* pivot row is the union of all rows in the pivot column pattern */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + DEBUG4 (("Pivot col pattern %d %d\n", ROW_IS_ALIVE (row), row)) ; + /* skip if row is dead */ + if (ROW_IS_ALIVE (row)) + { + rp = &A [Row [row].start] ; + rp_end = rp + Row [row].length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + /* add the column, if alive and untagged */ + col_thickness = Col [col].shared1.thickness ; + if (col_thickness > 0 && COL_IS_ALIVE (col)) + { + /* tag column in pivot row */ + Col [col].shared1.thickness = -col_thickness ; + ASSERT (pfree < Alen) ; + /* place column in pivot row */ + A [pfree++] = col ; + pivot_row_degree += col_thickness ; + } + } + } + } + + /* clear tag on pivot column */ + Col [pivot_col].shared1.thickness = pivot_col_thickness ; + max_deg = MAX (max_deg, pivot_row_degree) ; + +#ifndef NDEBUG + DEBUG3 (("check2\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Kill all rows used to construct pivot row ==================== */ + + /* also kill pivot row, temporarily */ + cp = &A [Col [pivot_col].start] ; + cp_end = cp + Col [pivot_col].length ; + while (cp < cp_end) + { + /* may be killing an already dead row */ + row = *cp++ ; + DEBUG3 (("Kill row in pivot col: %d\n", row)) ; + KILL_ROW (row) ; + } + + /* === Select a row index to use as the new pivot row =============== */ + + pivot_row_length = pfree - pivot_row_start ; + if (pivot_row_length > 0) + { + /* pick the "pivot" row arbitrarily (first row in col) */ + pivot_row = A [Col [pivot_col].start] ; + DEBUG3 (("Pivotal row is %d\n", pivot_row)) ; + } + else + { + /* there is no pivot row, since it is of zero length */ + pivot_row = EMPTY ; + ASSERT (pivot_row_length == 0) ; + } + ASSERT (Col [pivot_col].length > 0 || pivot_row_length == 0) ; + + /* === Approximate degree computation =============================== */ + + /* Here begins the computation of the approximate degree. The column */ + /* score is the sum of the pivot row "length", plus the size of the */ + /* set differences of each row in the column minus the pattern of the */ + /* pivot row itself. The column ("thickness") itself is also */ + /* excluded from the column score (we thus use an approximate */ + /* external degree). */ + + /* The time taken by the following code (compute set differences, and */ + /* add them up) is proportional to the size of the data structure */ + /* being scanned - that is, the sum of the sizes of each column in */ + /* the pivot row. Thus, the amortized time to compute a column score */ + /* is proportional to the size of that column (where size, in this */ + /* context, is the column "length", or the number of row indices */ + /* in that column). The number of row indices in a column is */ + /* monotonically non-decreasing, from the length of the original */ + /* column on input to colamd. */ + + /* === Compute set differences ====================================== */ + + DEBUG3 (("** Computing set differences phase. **\n")) ; + + /* pivot row is currently dead - it will be revived later. */ + + DEBUG3 (("Pivot row: ")) ; + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + DEBUG3 (("Col: %d\n", col)) ; + + /* clear tags used to construct pivot row pattern */ + col_thickness = -Col [col].shared1.thickness ; + ASSERT (col_thickness > 0) ; + Col [col].shared1.thickness = col_thickness ; + + /* === Remove column from degree list =========================== */ + + cur_score = Col [col].shared2.score ; + prev_col = Col [col].shared3.prev ; + next_col = Col [col].shared4.degree_next ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (cur_score >= EMPTY) ; + if (prev_col == EMPTY) + { + head [cur_score] = next_col ; + } + else + { + Col [prev_col].shared4.degree_next = next_col ; + } + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = prev_col ; + } + + /* === Scan the column ========================================== */ + + cp = &A [Col [col].start] ; + cp_end = cp + Col [col].length ; + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + continue ; + } + ASSERT (row != pivot_row) ; + set_difference = row_mark - tag_mark ; + /* check if the row has been seen yet */ + if (set_difference < 0) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + set_difference = Row [row].shared1.degree ; + } + /* subtract column thickness from this row's set difference */ + set_difference -= col_thickness ; + ASSERT (set_difference >= 0) ; + /* absorb this row if the set difference becomes zero */ + if (set_difference == 0 && aggressive) + { + DEBUG3 (("aggressive absorption. Row: %d\n", row)) ; + KILL_ROW (row) ; + } + else + { + /* save the new mark */ + Row [row].shared2.mark = set_difference + tag_mark ; + } + } + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k-pivot_row_degree, max_deg) ; +#endif /* NDEBUG */ + + /* === Add up set differences for each column ======================= */ + + DEBUG3 (("** Adding set differences phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + /* get a column */ + col = *rp++ ; + ASSERT (COL_IS_ALIVE (col) && col != pivot_col) ; + hash = 0 ; + cur_score = 0 ; + cp = &A [Col [col].start] ; + /* compact the column */ + new_cp = cp ; + cp_end = cp + Col [col].length ; + + DEBUG4 (("Adding set diffs for Col: %d.\n", col)) ; + + while (cp < cp_end) + { + /* get a row */ + row = *cp++ ; + ASSERT(row >= 0 && row < n_row) ; + row_mark = Row [row].shared2.mark ; + /* skip if dead */ + if (ROW_IS_MARKED_DEAD (row_mark)) + { + DEBUG4 ((" Row %d, dead\n", row)) ; + continue ; + } + DEBUG4 ((" Row %d, set diff %d\n", row, row_mark-tag_mark)); + ASSERT (row_mark >= tag_mark) ; + /* compact the column */ + *new_cp++ = row ; + /* compute hash function */ + hash += row ; + /* add set difference */ + cur_score += row_mark - tag_mark ; + /* integer overflow... */ + cur_score = MIN (cur_score, n_col) ; + } + + /* recompute the column's length */ + Col [col].length = (Int) (new_cp - &A [Col [col].start]) ; + + /* === Further mass elimination ================================= */ + + if (Col [col].length == 0) + { + DEBUG4 (("further mass elimination. Col: %d\n", col)) ; + /* nothing left but the pivot row in this column */ + KILL_PRINCIPAL_COL (col) ; + pivot_row_degree -= Col [col].shared1.thickness ; + ASSERT (pivot_row_degree >= 0) ; + /* order it */ + Col [col].shared2.order = k ; + /* increment order count by column thickness */ + k += Col [col].shared1.thickness ; + } + else + { + /* === Prepare for supercolumn detection ==================== */ + + DEBUG4 (("Preparing supercol detection for Col: %d.\n", col)) ; + + /* save score so far */ + Col [col].shared2.score = cur_score ; + + /* add column to hash table, for supercolumn detection */ + hash %= n_col + 1 ; + + DEBUG4 ((" Hash = %d, n_col = %d.\n", hash, n_col)) ; + ASSERT (((Int) hash) <= n_col) ; + + head_column = head [hash] ; + if (head_column > EMPTY) + { + /* degree list "hash" is non-empty, use prev (shared3) of */ + /* first column in degree list as head of hash bucket */ + first_col = Col [head_column].shared3.headhash ; + Col [head_column].shared3.headhash = col ; + } + else + { + /* degree list "hash" is empty, use head as hash bucket */ + first_col = - (head_column + 2) ; + head [hash] = - (col + 2) ; + } + Col [col].shared4.hash_next = first_col ; + + /* save hash function in Col [col].shared3.hash */ + Col [col].shared3.hash = (Int) hash ; + ASSERT (COL_IS_ALIVE (col)) ; + } + } + + /* The approximate external column degree is now computed. */ + + /* === Supercolumn detection ======================================== */ + + DEBUG3 (("** Supercolumn detection phase. **\n")) ; + + detect_super_cols ( + +#ifndef NDEBUG + n_col, Row, +#endif /* NDEBUG */ + + Col, A, head, pivot_row_start, pivot_row_length) ; + + /* === Kill the pivotal column ====================================== */ + + KILL_PRINCIPAL_COL (pivot_col) ; + + /* === Clear mark =================================================== */ + + tag_mark = clear_mark (tag_mark+max_deg+1, max_mark, n_row, Row) ; + +#ifndef NDEBUG + DEBUG3 (("check3\n")) ; + debug_mark (n_row, Row, tag_mark, max_mark) ; +#endif /* NDEBUG */ + + /* === Finalize the new pivot row, and column scores ================ */ + + DEBUG3 (("** Finalize scores phase. **\n")) ; + + /* for each column in pivot row */ + rp = &A [pivot_row_start] ; + /* compact the pivot row */ + new_rp = rp ; + rp_end = rp + pivot_row_length ; + while (rp < rp_end) + { + col = *rp++ ; + /* skip dead columns */ + if (COL_IS_DEAD (col)) + { + continue ; + } + *new_rp++ = col ; + /* add new pivot row to column */ + A [Col [col].start + (Col [col].length++)] = pivot_row ; + + /* retrieve score so far and add on pivot row's degree. */ + /* (we wait until here for this in case the pivot */ + /* row's degree was reduced due to mass elimination). */ + cur_score = Col [col].shared2.score + pivot_row_degree ; + + /* calculate the max possible score as the number of */ + /* external columns minus the 'k' value minus the */ + /* columns thickness */ + max_score = n_col - k - Col [col].shared1.thickness ; + + /* make the score the external degree of the union-of-rows */ + cur_score -= Col [col].shared1.thickness ; + + /* make sure score is less or equal than the max score */ + cur_score = MIN (cur_score, max_score) ; + ASSERT (cur_score >= 0) ; + + /* store updated score */ + Col [col].shared2.score = cur_score ; + + /* === Place column back in degree list ========================= */ + + ASSERT (min_score >= 0) ; + ASSERT (min_score <= n_col) ; + ASSERT (cur_score >= 0) ; + ASSERT (cur_score <= n_col) ; + ASSERT (head [cur_score] >= EMPTY) ; + next_col = head [cur_score] ; + Col [col].shared4.degree_next = next_col ; + Col [col].shared3.prev = EMPTY ; + if (next_col != EMPTY) + { + Col [next_col].shared3.prev = col ; + } + head [cur_score] = col ; + + /* see if this score is less than current min */ + min_score = MIN (min_score, cur_score) ; + + } + +#ifndef NDEBUG + debug_deg_lists (n_row, n_col, Row, Col, head, + min_score, n_col2-k, max_deg) ; +#endif /* NDEBUG */ + + /* === Resurrect the new pivot row ================================== */ + + if (pivot_row_degree > 0) + { + /* update pivot row length to reflect any cols that were killed */ + /* during super-col detection and mass elimination */ + Row [pivot_row].start = pivot_row_start ; + Row [pivot_row].length = (Int) (new_rp - &A[pivot_row_start]) ; + ASSERT (Row [pivot_row].length > 0) ; + Row [pivot_row].shared1.degree = pivot_row_degree ; + Row [pivot_row].shared2.mark = 0 ; + /* pivot row is no longer dead */ + + DEBUG1 (("Resurrect Pivot_row %d deg: %d\n", + pivot_row, pivot_row_degree)) ; + } + } + + /* === All principal columns have now been ordered ====================== */ + + return (ngarbage) ; +} + + +/* ========================================================================== */ +/* === order_children ======================================================= */ +/* ========================================================================== */ + +/* + The find_ordering routine has ordered all of the principal columns (the + representatives of the supercolumns). The non-principal columns have not + yet been ordered. This routine orders those columns by walking up the + parent tree (a column is a child of the column which absorbed it). The + final permutation vector is then placed in p [0 ... n_col-1], with p [0] + being the first column, and p [n_col-1] being the last. It doesn't look + like it at first glance, but be assured that this routine takes time linear + in the number of columns. Although not immediately obvious, the time + taken by this routine is O (n_col), that is, linear in the number of + columns. Not user-callable. +*/ + +PRIVATE void order_children +( + /* === Parameters ======================================================= */ + + Int n_col, /* number of columns of A */ + Colamd_Col Col [], /* of size n_col+1 */ + Int p [] /* p [0 ... n_col-1] is the column permutation*/ +) +{ + /* === Local variables ================================================== */ + + Int i ; /* loop counter for all columns */ + Int c ; /* column index */ + Int parent ; /* index of column's parent */ + Int order ; /* column's order */ + + /* === Order each non-principal column ================================== */ + + for (i = 0 ; i < n_col ; i++) + { + /* find an un-ordered non-principal column */ + ASSERT (COL_IS_DEAD (i)) ; + if (!COL_IS_DEAD_PRINCIPAL (i) && Col [i].shared2.order == EMPTY) + { + parent = i ; + /* once found, find its principal parent */ + do + { + parent = Col [parent].shared1.parent ; + } while (!COL_IS_DEAD_PRINCIPAL (parent)) ; + + /* now, order all un-ordered non-principal columns along path */ + /* to this parent. collapse tree at the same time */ + c = i ; + /* get order of parent */ + order = Col [parent].shared2.order ; + + do + { + ASSERT (Col [c].shared2.order == EMPTY) ; + + /* order this column */ + Col [c].shared2.order = order++ ; + /* collaps tree */ + Col [c].shared1.parent = parent ; + + /* get immediate parent of this column */ + c = Col [c].shared1.parent ; + + /* continue until we hit an ordered column. There are */ + /* guarranteed not to be anymore unordered columns */ + /* above an ordered column */ + } while (Col [c].shared2.order == EMPTY) ; + + /* re-order the super_col parent to largest order for this group */ + Col [parent].shared2.order = order ; + } + } + + /* === Generate the permutation ========================================= */ + + for (c = 0 ; c < n_col ; c++) + { + p [Col [c].shared2.order] = c ; + } +} + + +/* ========================================================================== */ +/* === detect_super_cols ==================================================== */ +/* ========================================================================== */ + +/* + Detects supercolumns by finding matches between columns in the hash buckets. + Check amongst columns in the set A [row_start ... row_start + row_length-1]. + The columns under consideration are currently *not* in the degree lists, + and have already been placed in the hash buckets. + + The hash bucket for columns whose hash function is equal to h is stored + as follows: + + if head [h] is >= 0, then head [h] contains a degree list, so: + + head [h] is the first column in degree bucket h. + Col [head [h]].headhash gives the first column in hash bucket h. + + otherwise, the degree list is empty, and: + + -(head [h] + 2) is the first column in hash bucket h. + + For a column c in a hash bucket, Col [c].shared3.prev is NOT a "previous + column" pointer. Col [c].shared3.hash is used instead as the hash number + for that column. The value of Col [c].shared4.hash_next is the next column + in the same hash bucket. + + Assuming no, or "few" hash collisions, the time taken by this routine is + linear in the sum of the sizes (lengths) of each column whose score has + just been computed in the approximate degree computation. + Not user-callable. +*/ + +PRIVATE void detect_super_cols +( + /* === Parameters ======================================================= */ + +#ifndef NDEBUG + /* these two parameters are only needed when debugging is enabled: */ + Int n_col, /* number of columns of A */ + Colamd_Row Row [], /* of size n_row+1 */ +#endif /* NDEBUG */ + + Colamd_Col Col [], /* of size n_col+1 */ + Int A [], /* row indices of A */ + Int head [], /* head of degree lists and hash buckets */ + Int row_start, /* pointer to set of columns to check */ + Int row_length /* number of columns to check */ +) +{ + /* === Local variables ================================================== */ + + Int hash ; /* hash value for a column */ + Int *rp ; /* pointer to a row */ + Int c ; /* a column index */ + Int super_c ; /* column index of the column to absorb into */ + Int *cp1 ; /* column pointer for column super_c */ + Int *cp2 ; /* column pointer for column c */ + Int length ; /* length of column super_c */ + Int prev_c ; /* column preceding c in hash bucket */ + Int i ; /* loop counter */ + Int *rp_end ; /* pointer to the end of the row */ + Int col ; /* a column index in the row to check */ + Int head_column ; /* first column in hash bucket or degree list */ + Int first_col ; /* first column in hash bucket */ + + /* === Consider each column in the row ================================== */ + + rp = &A [row_start] ; + rp_end = rp + row_length ; + while (rp < rp_end) + { + col = *rp++ ; + if (COL_IS_DEAD (col)) + { + continue ; + } + + /* get hash number for this column */ + hash = Col [col].shared3.hash ; + ASSERT (hash <= n_col) ; + + /* === Get the first column in this hash bucket ===================== */ + + head_column = head [hash] ; + if (head_column > EMPTY) + { + first_col = Col [head_column].shared3.headhash ; + } + else + { + first_col = - (head_column + 2) ; + } + + /* === Consider each column in the hash bucket ====================== */ + + for (super_c = first_col ; super_c != EMPTY ; + super_c = Col [super_c].shared4.hash_next) + { + ASSERT (COL_IS_ALIVE (super_c)) ; + ASSERT (Col [super_c].shared3.hash == hash) ; + length = Col [super_c].length ; + + /* prev_c is the column preceding column c in the hash bucket */ + prev_c = super_c ; + + /* === Compare super_c with all columns after it ================ */ + + for (c = Col [super_c].shared4.hash_next ; + c != EMPTY ; c = Col [c].shared4.hash_next) + { + ASSERT (c != super_c) ; + ASSERT (COL_IS_ALIVE (c)) ; + ASSERT (Col [c].shared3.hash == hash) ; + + /* not identical if lengths or scores are different */ + if (Col [c].length != length || + Col [c].shared2.score != Col [super_c].shared2.score) + { + prev_c = c ; + continue ; + } + + /* compare the two columns */ + cp1 = &A [Col [super_c].start] ; + cp2 = &A [Col [c].start] ; + + for (i = 0 ; i < length ; i++) + { + /* the columns are "clean" (no dead rows) */ + ASSERT (ROW_IS_ALIVE (*cp1)) ; + ASSERT (ROW_IS_ALIVE (*cp2)) ; + /* row indices will same order for both supercols, */ + /* no gather scatter nessasary */ + if (*cp1++ != *cp2++) + { + break ; + } + } + + /* the two columns are different if the for-loop "broke" */ + if (i != length) + { + prev_c = c ; + continue ; + } + + /* === Got it! two columns are identical =================== */ + + ASSERT (Col [c].shared2.score == Col [super_c].shared2.score) ; + + Col [super_c].shared1.thickness += Col [c].shared1.thickness ; + Col [c].shared1.parent = super_c ; + KILL_NON_PRINCIPAL_COL (c) ; + /* order c later, in order_children() */ + Col [c].shared2.order = EMPTY ; + /* remove c from hash bucket */ + Col [prev_c].shared4.hash_next = Col [c].shared4.hash_next ; + } + } + + /* === Empty this hash bucket ======================================= */ + + if (head_column > EMPTY) + { + /* corresponding degree list "hash" is not empty */ + Col [head_column].shared3.headhash = EMPTY ; + } + else + { + /* corresponding degree list "hash" is empty */ + head [hash] = EMPTY ; + } + } +} + + +/* ========================================================================== */ +/* === garbage_collection =================================================== */ +/* ========================================================================== */ + +/* + Defragments and compacts columns and rows in the workspace A. Used when + all avaliable memory has been used while performing row merging. Returns + the index of the first free position in A, after garbage collection. The + time taken by this routine is linear is the size of the array A, which is + itself linear in the number of nonzeros in the input matrix. + Not user-callable. +*/ + +PRIVATE Int garbage_collection /* returns the new value of pfree */ +( + /* === Parameters ======================================================= */ + + Int n_row, /* number of rows */ + Int n_col, /* number of columns */ + Colamd_Row Row [], /* row info */ + Colamd_Col Col [], /* column info */ + Int A [], /* A [0 ... Alen-1] holds the matrix */ + Int *pfree /* &A [0] ... pfree is in use */ +) +{ + /* === Local variables ================================================== */ + + Int *psrc ; /* source pointer */ + Int *pdest ; /* destination pointer */ + Int j ; /* counter */ + Int r ; /* a row index */ + Int c ; /* a column index */ + Int length ; /* length of a row or column */ + +#ifndef NDEBUG + Int debug_rows ; + DEBUG2 (("Defrag..\n")) ; + for (psrc = &A[0] ; psrc < pfree ; psrc++) ASSERT (*psrc >= 0) ; + debug_rows = 0 ; +#endif /* NDEBUG */ + + /* === Defragment the columns =========================================== */ + + pdest = &A[0] ; + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + psrc = &A [Col [c].start] ; + + /* move and compact the column */ + ASSERT (pdest <= psrc) ; + Col [c].start = (Int) (pdest - &A [0]) ; + length = Col [c].length ; + for (j = 0 ; j < length ; j++) + { + r = *psrc++ ; + if (ROW_IS_ALIVE (r)) + { + *pdest++ = r ; + } + } + Col [c].length = (Int) (pdest - &A [Col [c].start]) ; + } + } + + /* === Prepare to defragment the rows =================================== */ + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_DEAD (r) || (Row [r].length == 0)) + { + /* This row is already dead, or is of zero length. Cannot compact + * a row of zero length, so kill it. NOTE: in the current version, + * there are no zero-length live rows. Kill the row (for the first + * time, or again) just to be safe. */ + KILL_ROW (r) ; + } + else + { + /* save first column index in Row [r].shared2.first_column */ + psrc = &A [Row [r].start] ; + Row [r].shared2.first_column = *psrc ; + ASSERT (ROW_IS_ALIVE (r)) ; + /* flag the start of the row with the one's complement of row */ + *psrc = ONES_COMPLEMENT (r) ; +#ifndef NDEBUG + debug_rows++ ; +#endif /* NDEBUG */ + } + } + + /* === Defragment the rows ============================================== */ + + psrc = pdest ; + while (psrc < pfree) + { + /* find a negative number ... the start of a row */ + if (*psrc++ < 0) + { + psrc-- ; + /* get the row index */ + r = ONES_COMPLEMENT (*psrc) ; + ASSERT (r >= 0 && r < n_row) ; + /* restore first column index */ + *psrc = Row [r].shared2.first_column ; + ASSERT (ROW_IS_ALIVE (r)) ; + ASSERT (Row [r].length > 0) ; + /* move and compact the row */ + ASSERT (pdest <= psrc) ; + Row [r].start = (Int) (pdest - &A [0]) ; + length = Row [r].length ; + for (j = 0 ; j < length ; j++) + { + c = *psrc++ ; + if (COL_IS_ALIVE (c)) + { + *pdest++ = c ; + } + } + Row [r].length = (Int) (pdest - &A [Row [r].start]) ; + ASSERT (Row [r].length > 0) ; +#ifndef NDEBUG + debug_rows-- ; +#endif /* NDEBUG */ + } + } + /* ensure we found all the rows */ + ASSERT (debug_rows == 0) ; + + /* === Return the new value of pfree ==================================== */ + + return ((Int) (pdest - &A [0])) ; +} + + +/* ========================================================================== */ +/* === clear_mark =========================================================== */ +/* ========================================================================== */ + +/* + Clears the Row [].shared2.mark array, and returns the new tag_mark. + Return value is the new tag_mark. Not user-callable. +*/ + +PRIVATE Int clear_mark /* return the new value for tag_mark */ +( + /* === Parameters ======================================================= */ + + Int tag_mark, /* new value of tag_mark */ + Int max_mark, /* max allowed value of tag_mark */ + + Int n_row, /* number of rows in A */ + Colamd_Row Row [] /* Row [0 ... n_row-1].shared2.mark is set to zero */ +) +{ + /* === Local variables ================================================== */ + + Int r ; + + if (tag_mark <= 0 || tag_mark >= max_mark) + { + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + Row [r].shared2.mark = 0 ; + } + } + tag_mark = 1 ; + } + + return (tag_mark) ; +} + + +/* ========================================================================== */ +/* === print_report ========================================================= */ +/* ========================================================================== */ + +PRIVATE void print_report +( + char *method, + Int stats [COLAMD_STATS] +) +{ + + Int i1, i2, i3 ; + + PRINTF (("\n%s version %d.%d, %s: ", method, + COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE)) ; + + if (!stats) + { + PRINTF (("No statistics available.\n")) ; + return ; + } + + i1 = stats [COLAMD_INFO1] ; + i2 = stats [COLAMD_INFO2] ; + i3 = stats [COLAMD_INFO3] ; + + if (stats [COLAMD_STATUS] >= 0) + { + PRINTF (("OK. ")) ; + } + else + { + PRINTF (("ERROR. ")) ; + } + + switch (stats [COLAMD_STATUS]) + { + + case COLAMD_OK_BUT_JUMBLED: + + PRINTF(("Matrix has unsorted or duplicate row indices.\n")) ; + + PRINTF(("%s: number of duplicate or out-of-order row indices: %d\n", + method, i3)) ; + + PRINTF(("%s: last seen duplicate or out-of-order row index: %d\n", + method, INDEX (i2))) ; + + PRINTF(("%s: last seen in column: %d", + method, INDEX (i1))) ; + + /* no break - fall through to next case instead */ + + case COLAMD_OK: + + PRINTF(("\n")) ; + + PRINTF(("%s: number of dense or empty rows ignored: %d\n", + method, stats [COLAMD_DENSE_ROW])) ; + + PRINTF(("%s: number of dense or empty columns ignored: %d\n", + method, stats [COLAMD_DENSE_COL])) ; + + PRINTF(("%s: number of garbage collections performed: %d\n", + method, stats [COLAMD_DEFRAG_COUNT])) ; + break ; + + case COLAMD_ERROR_A_not_present: + + PRINTF(("Array A (row indices of matrix) not present.\n")) ; + break ; + + case COLAMD_ERROR_p_not_present: + + PRINTF(("Array p (column pointers for matrix) not present.\n")) ; + break ; + + case COLAMD_ERROR_nrow_negative: + + PRINTF(("Invalid number of rows (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_ncol_negative: + + PRINTF(("Invalid number of columns (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_nnz_negative: + + PRINTF(("Invalid number of nonzero entries (%d).\n", i1)) ; + break ; + + case COLAMD_ERROR_p0_nonzero: + + PRINTF(("Invalid column pointer, p [0] = %d, must be zero.\n", i1)); + break ; + + case COLAMD_ERROR_A_too_small: + + PRINTF(("Array A too small.\n")) ; + PRINTF((" Need Alen >= %d, but given only Alen = %d.\n", + i1, i2)) ; + break ; + + case COLAMD_ERROR_col_length_negative: + + PRINTF + (("Column %d has a negative number of nonzero entries (%d).\n", + INDEX (i1), i2)) ; + break ; + + case COLAMD_ERROR_row_index_out_of_bounds: + + PRINTF + (("Row index (row %d) out of bounds (%d to %d) in column %d.\n", + INDEX (i2), INDEX (0), INDEX (i3-1), INDEX (i1))) ; + break ; + + case COLAMD_ERROR_out_of_memory: + + PRINTF(("Out of memory.\n")) ; + break ; + + /* v2.4: internal-error case deleted */ + } +} + + + + +/* ========================================================================== */ +/* === colamd debugging routines ============================================ */ +/* ========================================================================== */ + +/* When debugging is disabled, the remainder of this file is ignored. */ + +#ifndef NDEBUG + + +/* ========================================================================== */ +/* === debug_structures ===================================================== */ +/* ========================================================================== */ + +/* + At this point, all empty rows and columns are dead. All live columns + are "clean" (containing no dead rows) and simplicial (no supercolumns + yet). Rows may contain dead columns, but all live rows contain at + least one live column. +*/ + +PRIVATE void debug_structures +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [], + Int n_col2 +) +{ + /* === Local variables ================================================== */ + + Int i ; + Int c ; + Int *cp ; + Int *cp_end ; + Int len ; + Int score ; + Int r ; + Int *rp ; + Int *rp_end ; + Int deg ; + + /* === Check A, Row, and Col ============================================ */ + + for (c = 0 ; c < n_col ; c++) + { + if (COL_IS_ALIVE (c)) + { + len = Col [c].length ; + score = Col [c].shared2.score ; + DEBUG4 (("initial live col %5d %5d %5d\n", c, len, score)) ; + ASSERT (len > 0) ; + ASSERT (score >= 0) ; + ASSERT (Col [c].shared1.thickness == 1) ; + cp = &A [Col [c].start] ; + cp_end = cp + len ; + while (cp < cp_end) + { + r = *cp++ ; + ASSERT (ROW_IS_ALIVE (r)) ; + } + } + else + { + i = Col [c].shared2.order ; + ASSERT (i >= n_col2 && i < n_col) ; + } + } + + for (r = 0 ; r < n_row ; r++) + { + if (ROW_IS_ALIVE (r)) + { + i = 0 ; + len = Row [r].length ; + deg = Row [r].shared1.degree ; + ASSERT (len > 0) ; + ASSERT (deg > 0) ; + rp = &A [Row [r].start] ; + rp_end = rp + len ; + while (rp < rp_end) + { + c = *rp++ ; + if (COL_IS_ALIVE (c)) + { + i++ ; + } + } + ASSERT (i > 0) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_deg_lists ====================================================== */ +/* ========================================================================== */ + +/* + Prints the contents of the degree lists. Counts the number of columns + in the degree list and compares it to the total it should have. Also + checks the row degrees. +*/ + +PRIVATE void debug_deg_lists +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int head [], + Int min_score, + Int should, + Int max_deg +) +{ + /* === Local variables ================================================== */ + + Int deg ; + Int col ; + Int have ; + Int row ; + + /* === Check the degree lists =========================================== */ + + if (n_col > 10000 && colamd_debug <= 0) + { + return ; + } + have = 0 ; + DEBUG4 (("Degree lists: %d\n", min_score)) ; + for (deg = 0 ; deg <= n_col ; deg++) + { + col = head [deg] ; + if (col == EMPTY) + { + continue ; + } + DEBUG4 (("%d:", deg)) ; + while (col != EMPTY) + { + DEBUG4 ((" %d", col)) ; + have += Col [col].shared1.thickness ; + ASSERT (COL_IS_ALIVE (col)) ; + col = Col [col].shared4.degree_next ; + } + DEBUG4 (("\n")) ; + } + DEBUG4 (("should %d have %d\n", should, have)) ; + ASSERT (should == have) ; + + /* === Check the row degrees ============================================ */ + + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (row = 0 ; row < n_row ; row++) + { + if (ROW_IS_ALIVE (row)) + { + ASSERT (Row [row].shared1.degree <= max_deg) ; + } + } +} + + +/* ========================================================================== */ +/* === debug_mark =========================================================== */ +/* ========================================================================== */ + +/* + Ensures that the tag_mark is less that the maximum and also ensures that + each entry in the mark array is less than the tag mark. +*/ + +PRIVATE void debug_mark +( + /* === Parameters ======================================================= */ + + Int n_row, + Colamd_Row Row [], + Int tag_mark, + Int max_mark +) +{ + /* === Local variables ================================================== */ + + Int r ; + + /* === Check the Row marks ============================================== */ + + ASSERT (tag_mark > 0 && tag_mark <= max_mark) ; + if (n_row > 10000 && colamd_debug <= 0) + { + return ; + } + for (r = 0 ; r < n_row ; r++) + { + ASSERT (Row [r].shared2.mark < tag_mark) ; + } +} + + +/* ========================================================================== */ +/* === debug_matrix ========================================================= */ +/* ========================================================================== */ + +/* + Prints out the contents of the columns and the rows. +*/ + +PRIVATE void debug_matrix +( + /* === Parameters ======================================================= */ + + Int n_row, + Int n_col, + Colamd_Row Row [], + Colamd_Col Col [], + Int A [] +) +{ + /* === Local variables ================================================== */ + + Int r ; + Int c ; + Int *rp ; + Int *rp_end ; + Int *cp ; + Int *cp_end ; + + /* === Dump the rows and columns of the matrix ========================== */ + + if (colamd_debug < 3) + { + return ; + } + DEBUG3 (("DUMP MATRIX:\n")) ; + for (r = 0 ; r < n_row ; r++) + { + DEBUG3 (("Row %d alive? %d\n", r, ROW_IS_ALIVE (r))) ; + if (ROW_IS_DEAD (r)) + { + continue ; + } + DEBUG3 (("start %d length %d degree %d\n", + Row [r].start, Row [r].length, Row [r].shared1.degree)) ; + rp = &A [Row [r].start] ; + rp_end = rp + Row [r].length ; + while (rp < rp_end) + { + c = *rp++ ; + DEBUG4 ((" %d col %d\n", COL_IS_ALIVE (c), c)) ; + } + } + + for (c = 0 ; c < n_col ; c++) + { + DEBUG3 (("Col %d alive? %d\n", c, COL_IS_ALIVE (c))) ; + if (COL_IS_DEAD (c)) + { + continue ; + } + DEBUG3 (("start %d length %d shared1 %d shared2 %d\n", + Col [c].start, Col [c].length, + Col [c].shared1.thickness, Col [c].shared2.score)) ; + cp = &A [Col [c].start] ; + cp_end = cp + Col [c].length ; + while (cp < cp_end) + { + r = *cp++ ; + DEBUG4 ((" %d row %d\n", ROW_IS_ALIVE (r), r)) ; + } + } +} + +PRIVATE void colamd_get_debug +( + char *method +) +{ + FILE *f ; + colamd_debug = 0 ; /* no debug printing */ + f = fopen ("debug", "r") ; + if (f == (FILE *) NULL) + { + colamd_debug = 0 ; + } + else + { + fscanf (f, "%d", &colamd_debug) ; + fclose (f) ; + } + DEBUG0 (("%s: debug version, D = %d (THIS WILL BE SLOW!)\n", + method, colamd_debug)) ; +} + +#endif /* NDEBUG */ diff --git a/OpenDSSC/klusolve/COLAMD/Source/colamd_global.c b/OpenDSSC/klusolve/COLAMD/Source/colamd_global.c new file mode 100644 index 0000000..4d1ae22 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Source/colamd_global.c @@ -0,0 +1,24 @@ +/* ========================================================================== */ +/* === colamd_global.c ====================================================== */ +/* ========================================================================== */ + +/* ---------------------------------------------------------------------------- + * COLAMD, Copyright (C) 2007, Timothy A. Davis. + * See License.txt for the Version 2.1 of the GNU Lesser General Public License + * http://www.cise.ufl.edu/research/sparse + * -------------------------------------------------------------------------- */ + +/* Global variables for COLAMD */ + +#ifndef NPRINT +#ifdef MATLAB_MEX_FILE +#include "mex.h" +int (*colamd_printf) (const char *, ...) = mexPrintf ; +#else +#include +int (*colamd_printf) (const char *, ...) = printf ; +#endif +#else +int (*colamd_printf) (const char *, ...) = ((void *) 0) ; +#endif + diff --git a/OpenDSSC/klusolve/COLAMD/Source/colamd_l.c b/OpenDSSC/klusolve/COLAMD/Source/colamd_l.c new file mode 100644 index 0000000..4078624 --- /dev/null +++ b/OpenDSSC/klusolve/COLAMD/Source/colamd_l.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "colamd.c" diff --git a/OpenDSSC/klusolve/CSparse/Demo/Makefile b/OpenDSSC/klusolve/CSparse/Demo/Makefile new file mode 100644 index 0000000..ee46101 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/Makefile @@ -0,0 +1,37 @@ +CF = $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -O +I = -I../Include + +CS = ../Lib/libcsparse.a + +all: lib cs_demo1 cs_demo2 cs_demo3 + - ./cs_demo1 < ../Matrix/t1 + - ./cs_demo2 < ../Matrix/t1 + - ./cs_demo2 < ../Matrix/ash219 + - ./cs_demo2 < ../Matrix/bcsstk01 + - ./cs_demo2 < ../Matrix/fs_183_1 + - ./cs_demo2 < ../Matrix/mbeacxc + - ./cs_demo2 < ../Matrix/west0067 + - ./cs_demo2 < ../Matrix/lp_afiro + - ./cs_demo2 < ../Matrix/bcsstk16 + - ./cs_demo3 < ../Matrix/bcsstk01 + - ./cs_demo3 < ../Matrix/bcsstk16 + +lib: + ( cd ../Lib ; $(MAKE) ) + +cs_demo1: lib cs_demo1.c Makefile + $(CC) $(CF) $(I) -o cs_demo1 cs_demo1.c $(CS) -lm + +cs_demo2: lib cs_demo2.c cs_demo.c cs_demo.h Makefile + $(CC) $(CF) $(I) -o cs_demo2 cs_demo2.c cs_demo.c $(CS) -lm + +cs_demo3: lib cs_demo3.c cs_demo.c cs_demo.h Makefile + $(CC) $(CF) $(I) -o cs_demo3 cs_demo3.c cs_demo.c $(CS) -lm + +clean: + - $(RM) *.o + +purge: distclean + +distclean: clean + - $(RM) -r cs_demo1 cs_demo2 cs_demo3 *.a *.dSYM *.obj *.dll diff --git a/OpenDSSC/klusolve/CSparse/Demo/README.txt b/OpenDSSC/klusolve/CSparse/Demo/README.txt new file mode 100644 index 0000000..ea7385f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/README.txt @@ -0,0 +1,4 @@ +CSparse/Demo: to compile a run the demos, just type "make" in this directory. +The printed residuals should all be small, except for the mbeacxc matrix +(which is numerically and structurally singular), and ash219 (which is a +least-squares problem). See cs_demo.out for the proper output of "make". diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo.c b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.c new file mode 100644 index 0000000..558f97c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.c @@ -0,0 +1,286 @@ +#include "cs_demo.h" +#include +/* 1 if A is square & upper tri., -1 if square & lower tri., 0 otherwise */ +static int is_sym (cs *A) +{ + int is_upper, is_lower, j, p, n = A->n, m = A->m, *Ap = A->p, *Ai = A->i ; + if (m != n) return (0) ; + is_upper = 1 ; + is_lower = 1 ; + for (j = 0 ; j < n ; j++) + { + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + if (Ai [p] > j) is_upper = 0 ; + if (Ai [p] < j) is_lower = 0 ; + } + } + return (is_upper ? 1 : (is_lower ? -1 : 0)) ; +} + +/* true for off-diagonal entries */ +static int dropdiag (int i, int j, double aij, void *other) { return (i != j) ;} + +/* C = A + triu(A,1)' */ +static cs *make_sym (cs *A) +{ + cs *AT, *C ; + AT = cs_transpose (A, 1) ; /* AT = A' */ + cs_fkeep (AT, &dropdiag, NULL) ; /* drop diagonal entries from AT */ + C = cs_add (A, AT, 1, 1) ; /* C = A+AT */ + cs_spfree (AT) ; + return (C) ; +} + +/* create a right-hand side */ +static void rhs (double *x, double *b, int m) +{ + int i ; + for (i = 0 ; i < m ; i++) b [i] = 1 + ((double) i) / m ; + for (i = 0 ; i < m ; i++) x [i] = b [i] ; +} + +/* infinity-norm of x */ +static double norm (double *x, int n) +{ + int i ; + double normx = 0 ; + for (i = 0 ; i < n ; i++) normx = CS_MAX (normx, fabs (x [i])) ; + return (normx) ; +} + +/* compute residual, norm(A*x-b,inf) / (norm(A,1)*norm(x,inf) + norm(b,inf)) */ +static void print_resid (int ok, cs *A, double *x, double *b, double *resid) +{ + int i, m, n ; + if (!ok) { printf (" (failed)\n") ; return ; } + m = A->m ; n = A->n ; + for (i = 0 ; i < m ; i++) resid [i] = -b [i] ; /* resid = -b */ + cs_gaxpy (A, x, resid) ; /* resid = resid + A*x */ + printf ("resid: %8.2e\n", norm (resid,m) / ((n == 0) ? 1 : + (cs_norm (A) * norm (x,n) + norm (b,m)))) ; +} + +static double tic (void) { return (clock () / (double) CLOCKS_PER_SEC) ; } +static double toc (double t) { double s = tic () ; return (CS_MAX (0, s-t)) ; } + +static void print_order (int order) +{ + switch (order) + { + case 0: printf ("natural ") ; break ; + case 1: printf ("amd(A+A') ") ; break ; + case 2: printf ("amd(S'*S) ") ; break ; + case 3: printf ("amd(A'*A) ") ; break ; + } +} + +/* read a problem from a file */ +problem *get_problem (FILE *f, double tol) +{ + cs *T, *A, *C ; + int sym, m, n, mn, nz1, nz2 ; + problem *Prob ; + Prob = cs_calloc (1, sizeof (problem)) ; + if (!Prob) return (NULL) ; + T = cs_load (f) ; /* load triplet matrix T from a file */ + Prob->A = A = cs_compress (T) ; /* A = compressed-column form of T */ + cs_spfree (T) ; /* clear T */ + if (!cs_dupl (A)) return (free_problem (Prob)) ; /* sum up duplicates */ + Prob->sym = sym = is_sym (A) ; /* determine if A is symmetric */ + m = A->m ; n = A->n ; + mn = CS_MAX (m,n) ; + nz1 = A->p [n] ; + cs_dropzeros (A) ; /* drop zero entries */ + nz2 = A->p [n] ; + if (tol > 0) cs_droptol (A, tol) ; /* drop tiny entries (just to test) */ + Prob->C = C = sym ? make_sym (A) : A ; /* C = A + triu(A,1)', or C=A */ + if (!C) return (free_problem (Prob)) ; + printf ("\n--- Matrix: %d-by-%d, nnz: %d (sym: %d: nnz %d), norm: %8.2e\n", + m, n, A->p [n], sym, sym ? C->p [n] : 0, cs_norm (C)) ; + if (nz1 != nz2) printf ("zero entries dropped: %d\n", nz1 - nz2) ; + if (nz2 != A->p [n]) printf ("tiny entries dropped: %d\n", nz2 - A->p [n]) ; + Prob->b = cs_malloc (mn, sizeof (double)) ; + Prob->x = cs_malloc (mn, sizeof (double)) ; + Prob->resid = cs_malloc (mn, sizeof (double)) ; + return ((!Prob->b || !Prob->x || !Prob->resid) ? free_problem (Prob) : Prob) ; +} + +/* free a problem */ +problem *free_problem (problem *Prob) +{ + if (!Prob) return (NULL) ; + cs_spfree (Prob->A) ; + if (Prob->sym) cs_spfree (Prob->C) ; + cs_free (Prob->b) ; + cs_free (Prob->x) ; + cs_free (Prob->resid) ; + return (cs_free (Prob)) ; +} + +/* solve a linear system using Cholesky, LU, and QR, with various orderings */ +int demo2 (problem *Prob) +{ + cs *A, *C ; + double *b, *x, *resid, t, tol ; + int k, m, n, ok, order, nb, ns, *r, *s, *rr, sprank ; + csd *D ; + if (!Prob) return (0) ; + A = Prob->A ; C = Prob->C ; b = Prob->b ; x = Prob->x ; resid = Prob->resid; + m = A->m ; n = A->n ; + tol = Prob->sym ? 0.001 : 1 ; /* partial pivoting tolerance */ + D = cs_dmperm (C, 1) ; /* randomized dmperm analysis */ + if (!D) return (0) ; + nb = D->nb ; r = D->r ; s = D->s ; rr = D->rr ; + sprank = rr [3] ; + for (ns = 0, k = 0 ; k < nb ; k++) + { + ns += ((r [k+1] == r [k]+1) && (s [k+1] == s [k]+1)) ; + } + printf ("blocks: %d singletons: %d structural rank: %d\n", nb, ns, sprank) ; + cs_dfree (D) ; + for (order = 0 ; order <= 3 ; order += 3) /* natural and amd(A'*A) */ + { + if (!order && m > 1000) continue ; + printf ("QR ") ; + print_order (order) ; + rhs (x, b, m) ; /* compute right-hand side */ + t = tic () ; + ok = cs_qrsol (order, C, x) ; /* min norm(Ax-b) with QR */ + printf ("time: %8.2f ", toc (t)) ; + print_resid (ok, C, x, b, resid) ; /* print residual */ + } + if (m != n || sprank < n) return (1) ; /* return if rect. or singular*/ + for (order = 0 ; order <= 3 ; order++) /* try all orderings */ + { + if (!order && m > 1000) continue ; + printf ("LU ") ; + print_order (order) ; + rhs (x, b, m) ; /* compute right-hand side */ + t = tic () ; + ok = cs_lusol (order, C, x, tol) ; /* solve Ax=b with LU */ + printf ("time: %8.2f ", toc (t)) ; + print_resid (ok, C, x, b, resid) ; /* print residual */ + } + if (!Prob->sym) return (1) ; + for (order = 0 ; order <= 1 ; order++) /* natural and amd(A+A') */ + { + if (!order && m > 1000) continue ; + printf ("Chol ") ; + print_order (order) ; + rhs (x, b, m) ; /* compute right-hand side */ + t = tic () ; + ok = cs_cholsol (order, C, x) ; /* solve Ax=b with Cholesky */ + printf ("time: %8.2f ", toc (t)) ; + print_resid (ok, C, x, b, resid) ; /* print residual */ + } + return (1) ; +} + +/* free workspace for demo3 */ +static int done3 (int ok, css *S, csn *N, double *y, cs *W, cs *E, int *p) +{ + cs_sfree (S) ; + cs_nfree (N) ; + cs_free (y) ; + cs_spfree (W) ; + cs_spfree (E) ; + cs_free (p) ; + return (ok) ; +} + +/* Cholesky update/downdate */ +int demo3 (problem *Prob) +{ + cs *A, *C, *W = NULL, *WW, *WT, *E = NULL, *W2 ; + int n, k, *Li, *Lp, *Wi, *Wp, p1, p2, *p = NULL, ok ; + double *b, *x, *resid, *y = NULL, *Lx, *Wx, s, t, t1 ; + css *S = NULL ; + csn *N = NULL ; + if (!Prob || !Prob->sym || Prob->A->n == 0) return (0) ; + A = Prob->A ; C = Prob->C ; b = Prob->b ; x = Prob->x ; resid = Prob->resid; + n = A->n ; + if (!Prob->sym || n == 0) return (1) ; + rhs (x, b, n) ; /* compute right-hand side */ + printf ("\nchol then update/downdate ") ; + print_order (1) ; + y = cs_malloc (n, sizeof (double)) ; + t = tic () ; + S = cs_schol (1, C) ; /* symbolic Chol, amd(A+A') */ + printf ("\nsymbolic chol time %8.2f\n", toc (t)) ; + t = tic () ; + N = cs_chol (C, S) ; /* numeric Cholesky */ + printf ("numeric chol time %8.2f\n", toc (t)) ; + if (!S || !N || !y) return (done3 (0, S, N, y, W, E, p)) ; + t = tic () ; + cs_ipvec (S->pinv, b, y, n) ; /* y = P*b */ + cs_lsolve (N->L, y) ; /* y = L\y */ + cs_ltsolve (N->L, y) ; /* y = L'\y */ + cs_pvec (S->pinv, y, x, n) ; /* x = P'*y */ + printf ("solve chol time %8.2f\n", toc (t)) ; + printf ("original: ") ; + print_resid (1, C, x, b, resid) ; /* print residual */ + k = n/2 ; /* construct W */ + W = cs_spalloc (n, 1, n, 1, 0) ; + if (!W) return (done3 (0, S, N, y, W, E, p)) ; + Lp = N->L->p ; Li = N->L->i ; Lx = N->L->x ; + Wp = W->p ; Wi = W->i ; Wx = W->x ; + Wp [0] = 0 ; + p1 = Lp [k] ; + Wp [1] = Lp [k+1] - p1 ; + s = Lx [p1] ; + srand (1) ; + for ( ; p1 < Lp [k+1] ; p1++) + { + p2 = p1 - Lp [k] ; + Wi [p2] = Li [p1] ; + Wx [p2] = s * rand () / ((double) RAND_MAX) ; + } + t = tic () ; + ok = cs_updown (N->L, +1, W, S->parent) ; /* update: L*L'+W*W' */ + t1 = toc (t) ; + printf ("update: time: %8.2f\n", t1) ; + if (!ok) return (done3 (0, S, N, y, W, E, p)) ; + t = tic () ; + cs_ipvec (S->pinv, b, y, n) ; /* y = P*b */ + cs_lsolve (N->L, y) ; /* y = L\y */ + cs_ltsolve (N->L, y) ; /* y = L'\y */ + cs_pvec (S->pinv, y, x, n) ; /* x = P'*y */ + t = toc (t) ; + p = cs_pinv (S->pinv, n) ; + W2 = cs_permute (W, p, NULL, 1) ; /* E = C + (P'W)*(P'W)' */ + WT = cs_transpose (W2,1) ; + WW = cs_multiply (W2, WT) ; + cs_spfree (WT) ; + cs_spfree (W2) ; + E = cs_add (C, WW, 1, 1) ; + cs_spfree (WW) ; + if (!E || !p) return (done3 (0, S, N, y, W, E, p)) ; + printf ("update: time: %8.2f (incl solve) ", t1+t) ; + print_resid (1, E, x, b, resid) ; /* print residual */ + cs_nfree (N) ; /* clear N */ + t = tic () ; + N = cs_chol (E, S) ; /* numeric Cholesky */ + if (!N) return (done3 (0, S, N, y, W, E, p)) ; + cs_ipvec (S->pinv, b, y, n) ; /* y = P*b */ + cs_lsolve (N->L, y) ; /* y = L\y */ + cs_ltsolve (N->L, y) ; /* y = L'\y */ + cs_pvec (S->pinv, y, x, n) ; /* x = P'*y */ + t = toc (t) ; + printf ("rechol: time: %8.2f (incl solve) ", t) ; + print_resid (1, E, x, b, resid) ; /* print residual */ + t = tic () ; + ok = cs_updown (N->L, -1, W, S->parent) ; /* downdate: L*L'-W*W' */ + t1 = toc (t) ; + if (!ok) return (done3 (0, S, N, y, W, E, p)) ; + printf ("downdate: time: %8.2f\n", t1) ; + t = tic () ; + cs_ipvec (S->pinv, b, y, n) ; /* y = P*b */ + cs_lsolve (N->L, y) ; /* y = L\y */ + cs_ltsolve (N->L, y) ; /* y = L'\y */ + cs_pvec (S->pinv, y, x, n) ; /* x = P'*y */ + t = toc (t) ; + printf ("downdate: time: %8.2f (incl solve) ", t1+t) ; + print_resid (1, C, x, b, resid) ; /* print residual */ + return (done3 (1, S, N, y, W, E, p)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo.h b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.h new file mode 100644 index 0000000..a0e9e72 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.h @@ -0,0 +1,15 @@ +#include "cs.h" +typedef struct problem_struct +{ + cs *A ; + cs *C ; + int sym ; + double *x ; + double *b ; + double *resid ; +} problem ; + +problem *get_problem (FILE *f, double tol) ; +int demo2 (problem *Prob) ; +int demo3 (problem *Prob) ; +problem *free_problem (problem *Prob) ; diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo.out b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.out new file mode 100644 index 0000000..e73a51b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo.out @@ -0,0 +1,177 @@ +( cd ../Lib ; make ) +make[1]: Entering directory `/cise/research/sparse/SuiteSparse/CSparse/Lib' +make[1]: Nothing to be done for `all'. +make[1]: Leaving directory `/cise/research/sparse/SuiteSparse/CSparse/Lib' +cc -O -I../Include -o cs_demo1 cs_demo1.c ../Lib/libcsparse.a -lm +cc -O -I../Include -o cs_demo2 cs_demo2.c cs_demo.c ../Lib/libcsparse.a -lm +cc -O -I../Include -o cs_demo3 cs_demo3.c cs_demo.c ../Lib/libcsparse.a -lm +./cs_demo1 < ../Matrix/t1 +T: +CSparse Version 2.2.6, Dec 7, 2011. Copyright (c) Timothy A. Davis, 2006-2011 +triplet: 4-by-4, nzmax: 16 nnz: 10 + 2 2 : 3 + 1 0 : 3.1 + 3 3 : 1 + 0 2 : 3.2 + 1 1 : 2.9 + 3 0 : 3.5 + 3 1 : 0.4 + 1 3 : 0.9 + 0 0 : 4.5 + 2 1 : 1.7 +A: +CSparse Version 2.2.6, Dec 7, 2011. Copyright (c) Timothy A. Davis, 2006-2011 +4-by-4, nzmax: 10 nnz: 10, 1-norm: 11.1 + col 0 : locations 0 to 2 + 1 : 3.1 + 3 : 3.5 + 0 : 4.5 + col 1 : locations 3 to 5 + 1 : 2.9 + 3 : 0.4 + 2 : 1.7 + col 2 : locations 6 to 7 + 2 : 3 + 0 : 3.2 + col 3 : locations 8 to 9 + 3 : 1 + 1 : 0.9 +AT: +CSparse Version 2.2.6, Dec 7, 2011. Copyright (c) Timothy A. Davis, 2006-2011 +4-by-4, nzmax: 10 nnz: 10, 1-norm: 7.7 + col 0 : locations 0 to 1 + 0 : 4.5 + 2 : 3.2 + col 1 : locations 2 to 4 + 0 : 3.1 + 1 : 2.9 + 3 : 0.9 + col 2 : locations 5 to 6 + 1 : 1.7 + 2 : 3 + col 3 : locations 7 to 9 + 0 : 3.5 + 1 : 0.4 + 3 : 1 +D: +CSparse Version 2.2.6, Dec 7, 2011. Copyright (c) Timothy A. Davis, 2006-2011 +4-by-4, nzmax: 16 nnz: 16, 1-norm: 139.58 + col 0 : locations 0 to 3 + 1 : 13.95 + 3 : 15.75 + 0 : 100.28 + 2 : 9.6 + col 1 : locations 4 to 7 + 1 : 88.62 + 3 : 12.91 + 0 : 13.95 + 2 : 4.93 + col 2 : locations 8 to 11 + 1 : 4.93 + 3 : 0.68 + 2 : 81.68 + 0 : 9.6 + col 3 : locations 12 to 15 + 1 : 12.91 + 3 : 83.2 + 0 : 15.75 + 2 : 0.68 +./cs_demo2 < ../Matrix/t1 + +--- Matrix: 4-by-4, nnz: 10 (sym: 0: nnz 0), norm: 1.11e+01 +blocks: 1 singletons: 0 structural rank: 4 +QR natural time: 0.00 resid: 3.06e-17 +QR amd(A'*A) time: 0.00 resid: 3.06e-17 +LU natural time: 0.00 resid: 1.53e-17 +LU amd(A+A') time: 0.00 resid: 1.53e-17 +LU amd(S'*S) time: 0.00 resid: 0.00e+00 +LU amd(A'*A) time: 0.00 resid: 1.53e-17 +./cs_demo2 < ../Matrix/ash219 + +--- Matrix: 219-by-85, nnz: 438 (sym: 0: nnz 0), norm: 9.00e+00 +blocks: 1 singletons: 0 structural rank: 85 +QR natural time: 0.00 resid: 1.61e-02 +QR amd(A'*A) time: 0.00 resid: 1.61e-02 +./cs_demo2 < ../Matrix/bcsstk01 + +--- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 +blocks: 1 singletons: 0 structural rank: 48 +QR natural time: 0.00 resid: 2.62e-19 +QR amd(A'*A) time: 0.00 resid: 5.27e-19 +LU natural time: 0.00 resid: 2.17e-19 +LU amd(A+A') time: 0.00 resid: 1.87e-19 +LU amd(S'*S) time: 0.00 resid: 2.38e-19 +LU amd(A'*A) time: 0.00 resid: 2.38e-19 +Chol natural time: 0.00 resid: 2.64e-19 +Chol amd(A+A') time: 0.00 resid: 2.55e-19 +./cs_demo2 < ../Matrix/fs_183_1 + +--- Matrix: 183-by-183, nnz: 988 (sym: 0: nnz 0), norm: 1.70e+09 +zero entries dropped: 71 +tiny entries dropped: 10 +blocks: 38 singletons: 37 structural rank: 183 +QR natural time: 0.00 resid: 6.84e-28 +QR amd(A'*A) time: 0.00 resid: 9.38e-28 +LU natural time: 0.00 resid: 6.20e-28 +LU amd(A+A') time: 0.00 resid: 1.55e-27 +LU amd(S'*S) time: 0.00 resid: 6.98e-28 +LU amd(A'*A) time: 0.00 resid: 6.98e-28 +./cs_demo2 < ../Matrix/mbeacxc + +--- Matrix: 492-by-490, nnz: 49920 (sym: 0: nnz 0), norm: 9.29e-01 +blocks: 10 singletons: 8 structural rank: 448 +QR natural time: 0.05 resid: nan +QR amd(A'*A) time: 0.07 resid: nan +./cs_demo2 < ../Matrix/west0067 + +--- Matrix: 67-by-67, nnz: 294 (sym: 0: nnz 0), norm: 6.14e+00 +blocks: 2 singletons: 1 structural rank: 67 +QR natural time: 0.00 resid: 7.14e-17 +QR amd(A'*A) time: 0.00 resid: 3.10e-17 +LU natural time: 0.00 resid: 3.89e-17 +LU amd(A+A') time: 0.00 resid: 2.27e-17 +LU amd(S'*S) time: 0.00 resid: 1.95e-17 +LU amd(A'*A) time: 0.00 resid: 2.60e-17 +./cs_demo2 < ../Matrix/lp_afiro + +--- Matrix: 27-by-51, nnz: 102 (sym: 0: nnz 0), norm: 3.43e+00 +blocks: 1 singletons: 0 structural rank: 27 +QR natural time: 0.00 resid: 3.96e-16 +QR amd(A'*A) time: 0.00 resid: 2.25e-16 +./cs_demo2 < ../Matrix/bcsstk16 + +--- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 +blocks: 75 singletons: 74 structural rank: 4884 +QR amd(A'*A) time: 0.63 resid: 1.39e-22 +LU amd(A+A') time: 0.40 resid: 1.10e-22 +LU amd(S'*S) time: 0.39 resid: 1.28e-22 +LU amd(A'*A) time: 0.41 resid: 1.78e-22 +Chol amd(A+A') time: 0.11 resid: 1.19e-22 +./cs_demo3 < ../Matrix/bcsstk01 + +--- Matrix: 48-by-48, nnz: 224 (sym: -1: nnz 400), norm: 3.57e+09 + +chol then update/downdate amd(A+A') +symbolic chol time 0.00 +numeric chol time 0.00 +solve chol time 0.00 +original: resid: 2.55e-19 +update: time: 0.00 +update: time: 0.00 (incl solve) resid: 9.66e-19 +rechol: time: 0.00 (incl solve) resid: 1.55e-18 +downdate: time: 0.00 +downdate: time: 0.00 (incl solve) resid: 3.74e-17 +./cs_demo3 < ../Matrix/bcsstk16 + +--- Matrix: 4884-by-4884, nnz: 147631 (sym: -1: nnz 290378), norm: 7.01e+09 + +chol then update/downdate amd(A+A') +symbolic chol time 0.01 +numeric chol time 0.10 +solve chol time 0.00 +original: resid: 1.19e-22 +update: time: 0.00 +update: time: 0.01 (incl solve) resid: 1.12e-23 +rechol: time: 0.11 (incl solve) resid: 1.17e-23 +downdate: time: 0.00 +downdate: time: 0.00 (incl solve) resid: 4.09e-22 diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo1.c b/OpenDSSC/klusolve/CSparse/Demo/cs_demo1.c new file mode 100644 index 0000000..faf4743 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo1.c @@ -0,0 +1,27 @@ +#include "cs.h" +int main (void) +{ + cs *T, *A, *Eye, *AT, *C, *D ; + int i, m ; + T = cs_load (stdin) ; /* load triplet matrix T from stdin */ + printf ("T:\n") ; cs_print (T, 0) ; /* print T */ + A = cs_compress (T) ; /* A = compressed-column form of T */ + printf ("A:\n") ; cs_print (A, 0) ; /* print A */ + cs_spfree (T) ; /* clear T */ + AT = cs_transpose (A, 1) ; /* AT = A' */ + printf ("AT:\n") ; cs_print (AT, 0) ; /* print AT */ + m = A ? A->m : 0 ; /* m = # of rows of A */ + T = cs_spalloc (m, m, m, 1, 1) ; /* create triplet identity matrix */ + for (i = 0 ; i < m ; i++) cs_entry (T, i, i, 1) ; + Eye = cs_compress (T) ; /* Eye = speye (m) */ + cs_spfree (T) ; + C = cs_multiply (A, AT) ; /* C = A*A' */ + D = cs_add (C, Eye, 1, cs_norm (C)) ; /* D = C + Eye*norm (C,1) */ + printf ("D:\n") ; cs_print (D, 0) ; /* print D */ + cs_spfree (A) ; /* clear A AT C D Eye */ + cs_spfree (AT) ; + cs_spfree (C) ; + cs_spfree (D) ; + cs_spfree (Eye) ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo2.c b/OpenDSSC/klusolve/CSparse/Demo/cs_demo2.c new file mode 100644 index 0000000..71e7ad0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo2.c @@ -0,0 +1,9 @@ +#include "cs_demo.h" +/* cs_demo2: read a matrix and solve a linear system */ +int main (void) +{ + problem *Prob = get_problem (stdin, 1e-14) ; + demo2 (Prob) ; + free_problem (Prob) ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Demo/cs_demo3.c b/OpenDSSC/klusolve/CSparse/Demo/cs_demo3.c new file mode 100644 index 0000000..726fc39 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Demo/cs_demo3.c @@ -0,0 +1,9 @@ +#include "cs_demo.h" +/* cs_demo3: read a matrix and test Cholesky update/downdate */ +int main (void) +{ + problem *Prob = get_problem (stdin, 0) ; + demo3 (Prob) ; + free_problem (Prob) ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Doc/ChangeLog b/OpenDSSC/klusolve/CSparse/Doc/ChangeLog new file mode 100644 index 0000000..0788566 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Doc/ChangeLog @@ -0,0 +1,286 @@ +Dec 7, 2011: version 2.2.6 + + * fixed the Makefile to better align with CFLAGS and other standards + * minor fix to cs_install.m + +Jan 25, 2011: version 2.2.5 + + * minor fix to "make install" + * minor change to cs_util.c, typecast return (cs_free (...)) + * minor fixes to UFget: help file, UFsettings.txt + +Nov 30, 2009: version 2.2.4 + + * added "make install" and "make uninstall" to CXSparse + * minor change to cs_make.m + +Jan 20, 2009, v2.2.3 + + * all tabs expanded to 8 spaces (except for Makefiles) + * example corrected in cs_gaxpy.m + * minor change to cs_sparse to allow for i,j,x to be either + row or column vectors (or any mixture) + +Sept 8, 2008, v2.2.2 + + * minor change to cs_make.m, to change "/" to filesep ("/" on Unix, "\" + on Windows), to handle limitations in some Windows compilers + +Nov 1, 2007, v2.2.1 + + * very minor change to Include/cs.h: Changed name of 2nd argument of + cs_permute, to match the code. This has no affect on the code itself, + since the type ("int *") is unchanged. It's just a documentation issue. + + * minor lint cleanup in mexFunctions + +Mar 31, 2007, v2.2.0 + + * few changes to primary Source/ files. Changes mostly affect MATLAB + interface. + + * Source/cs_house.c: correction to comment + + * Souce/cs_updown.c: whitespace changed to reflect change in CXSparse, + no impact at all on CSparse itself. + + * Doc/, Lib/ and Include/ directories created. + + * Source/cs.h moved to Include/cs.h, version number changed to 2.2.0. + + * modification to Makefiles, cs_make.m + + * correction to help comments in cs_dmperm.m, cs_qr.m, cs_scc2.m, cs_scc.m + + * if complex matrix passed to CSparse in MATLAB, error message + suggests using CXSparse instead + + * minor performance fix to cs_sparse_mex.c + + * cs_randperm added to MATLAB/Makefile; already appeared in cs_make.m + + * minor improvements to MATLAB/ demos. + +Mar 1, 2007, v2.1.0 + + * Source/cs_add.c: added test for matrix dimensions + + * Source/cs_multiply.c: added test for matrix dimensions + + * correction to MATLAB demo3 (no error in C code version of the demo) + + * minor corrections to MATLAB m-file help comments. + +Dec 12, 2006, v2.0.7 + + * minor MATLAB cleanup + +Dec 6, 2006, v2.0.6 + + * Update to UFget. Now relies on the MATLAB urlwrite function instead of + my own Java code. + +Nov 2006, v2.0.5 + + * Added UFgrep to UFget toolbox. + + * No changes to C Source code, except for version number and date. + + * Added two test matrices: ibm32a and ibm32b. ibm32a is the Harwell/ + Boeing matrix ibm32, but with the last column removed. ibm32b + is the transpose of ibm32a. With optimization enabled (-O), + 2 lines in cs_maxtrans.c are not tested; these matrices correct + that problem. + + * Fixed UFget. Earlier version could not download matrices larger than + 32MB. + + * Modified UFget/UFweb, to reflect changes in the UF Sparse Matrix + Collection. + + * Added ccspy.m and cs_scc2.m MATLAB functions + + * Added examples to help info in each *.m MATLAB file + + * modified cs_dmspy to speed up the plotting of large matrices with many + singletons + + * minor change to cspy: now draws a box around the matrix. + + * minor changes to MATLAB demos and tests. + +Oct 13, 2006, v2.0.4 + + * minor modification to cs_updown.c. "n" was incorrectly declared "double". + It should be "int". This was safe, just a little confusing (n was only + used in an argument to cs_malloc, and is thus typecast). + +Sept 28, 2006, v2.0.3 + + * minor modifications to MATLAB interface, to allow CSparse to be used + in MATLAB 6.5. + + * added examples to m-files, other minor m-file cleanup. + + * bug fix to cspy, to handle NaN's properly. + +Aug 23, 2006: v2.0.2 + + * change to cs_updown mexFunction, to handle multiple rank updates + + * symbolic links removed from Tcov/ directory in the distribution. + They are now created by Tcov/Makefile as needed. This makes the + zip files cleaner. Tcov/*test.c test files renamed. + +July 19, 2006: + + * minor fix to cs_must_compile.m and cs_make.m, to allow CSparse to be + compiled in MATLAB 6.5 with cs_make. + + * minor fix to cspy for complex matrices (imaginary part was ignored). + + * no change to version number or date, since there are no changes that + affect the appearance of CSparse in the book ("Direct Methods for + Sparse Linear Systems", SIAM, 2006). + +June 24, 2006: + + * minor typos in comments corrected. No change in code itself, + and no change in version number or date. + +May 27, 2006, v2.0.1: (this version is printed in the book) + + * minor bug fix. cs_util.c modified, so that cs_sprealloc (T,0) works + properly for a triplet matrix T (setting T->nzmax equal to T->nz). + The line in v2.0.0: + + nzmax = (nzmax <= 0) ? (A->p [A->n]) : nzmax ; + + changes to the following in v2.0.1: + + if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ; + + * minor typographical changes arising from the editting of the book. + +Apr 12, 2006, v2.0.0: + + * random permutation option added to cs_maxtrans and cs_dmperm, to help + avoid rare cases where the O(|A|n) time complexity is reached in + practice (GHS_indef/boyd2 in the UF sparse matrix collection, for + example). New cs_randperm function added. + +Apr 10, 2006: + + * stylistic changes for the book (except for the bug fix): + + * "int order" parameter of cs_amd, cs_lusol, cs_cholsol, cs_qrsol, cs_sqr, + cs_schol changed. Now 0 means no ordering, 1 is A+A', 2 is S*S', and + 3 is A*A'. In v1.2 and earlier, "order" took on a value ranging from + -1 to 2. "int n" parameter rearranged for cs_ipvec, cs_pvec, cs_post + (int n moved to the end). cs_triplet renamed cs_compress. + + To ensure that these changes are propagated into user code that calls + CSparse, the "order" parameter has been placed as the first parameter + in all these routines. Your compiler will complain (gcc will halt) if + you upgrade from v1.2 to v2.0 without changing your code. This is much + better than a silent error in which you get the wrong ordering by + mistake (with a huge penalty in run-time performance and no compiler + warnings). + + New syntax (v2.0 and later): + ---------------------------- + + order = 0: natural ordering + order = 1: amd (A+A') + order = 2: amd (S'*S), where S=A except dense rows dropped + order = 3: amd (A'*A) + + int cs_cholsol (int order, const cs *A, double *b) ; + int cs_lusol (int order, const cs *A, double *b, double tol) ; + int cs_qrsol (int order, const cs *A, double *b) ; + int *cs_amd (int order, const cs *A) ; + css *cs_schol (int order, const cs *A) ; + css *cs_sqr (int order, const cs *A, int qr) ; + + int *cs_post (const int *parent, int n) ; + int cs_ipvec (const int *p, const double *b, double *x, int n) ; + int cs_pvec (const int *p, const double *b, double *x, int n) ; + + cs *cs_compress (const cs *T) ; + + Old syntax (v1.2 and earlier): + ------------------------------ + + order = -1: natural ordering + order = 0: amd (A+A') + order = 1: amd (S'*S), where S=A except dense rows dropped + order = 2: amd (A'*A) + + int cs_cholsol (const cs *A, double *b, int order) ; + int cs_lusol (const cs *A, double *b, int order, double tol) ; + int cs_qrsol (const cs *A, double *b, int order) ; + int *cs_amd (const cs *A, int order) ; + css *cs_schol (const cs *A, int order) ; + css *cs_sqr (const cs *A, int order, int qr) ; + + int *cs_post (int n, const int *parent) ; + int cs_ipvec (int n, const int *p, const double *b, double *x) ; + int cs_pvec (int n, const int *p, const double *b, double *x) ; + + cs *cs_triplet (const cs *T) ; + + * CS_OVERFLOW macro removed (removed from cs_malloc.c; not needed). + + * S->leftmost added to css (it was tacked onto S->pinv before). + + * P,Q,R,S components of csd struct changed to p,q,r,s. + + * Pinv and Q components of css struct changed to pinv and q. + + * CS_CSC and CS_TRIPLET macros added, to clarify which CSparse functions + accept cs matrices in compressed column form, triplet form, or both. + + * check for negative row/column indices added to cs_entry. + + * cs_ereach and cs_leaf functions added. + + * call to cs_sprealloc added to cs_fkeep. + + * bug fixes in cs_counts and cs_amd (memory leak under rare out-of-memory + conditions). + +Mar 15, 2006: + + * cs_scc modified so that the row and columns of each component are put in + their natural order. cs_dmperm modified so that columns of each block + (instead of rows) are placed in their natural order. + + * cs_splsolve renamed cs_spsolve, generalized to handle both Lx=b and + Ux=b, and non-unit diagonal, and placed in its own file (cs_spsolve.c; + it was a static function in cs_lu.c). cs_lsolve_mex.c and + cs_splsolve_mex.c merged (the latter was removed). cs_spsolve.c file + added + + * cs_dmspy changed, so that block borders line up better with the matrix. + +Mar 6, 2006: + + * Makefile modified so that the Tcov tests (which may not be portable) + are not compiled and run by the default "make" in the CSparse directory. + To compile everything, including the Tcov tests, use "make all". + Trivial change to cs.h. + +Feb 27, 2006: + + * cs_reach, cs_dfs, cs_splsolve, cs_lu, and cs_scc changed to remove O(n) + initialized workspace. + * cs_reach and cs_splsolve now user-callable (were static in cs_lu.c). + +Feb 20, 2006: + + * various changes to simplify the construction of CXSparse + +Feb 7, 2006: + + * changed prototypes, adding "const" where appropriate. + diff --git a/OpenDSSC/klusolve/CSparse/Doc/License.txt b/OpenDSSC/klusolve/CSparse/Doc/License.txt new file mode 100644 index 0000000..55ff722 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Doc/License.txt @@ -0,0 +1,19 @@ +CSparse: a Concise Sparse matrix package. +Copyright (c) 2006, Timothy A. Davis. +http://www.cise.ufl.edu/research/sparse/CSparse + +-------------------------------------------------------------------------------- + +CSparse is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +CSparse is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/OpenDSSC/klusolve/CSparse/Doc/lesser.txt b/OpenDSSC/klusolve/CSparse/Doc/lesser.txt new file mode 100644 index 0000000..783bd5e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/OpenDSSC/klusolve/CSparse/Include/cs.h b/OpenDSSC/klusolve/CSparse/Include/cs.h new file mode 100644 index 0000000..400e3aa --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Include/cs.h @@ -0,0 +1,143 @@ +#ifndef _CS_H +#define _CS_H +#include +#include +#include +#include +#ifdef MATLAB_MEX_FILE +#include "mex.h" +#endif +#define CS_VER 2 /* CSparse Version */ +#define CS_SUBVER 2 +#define CS_SUBSUB 6 +#define CS_DATE "Dec 7, 2011" /* CSparse release date */ +#define CS_COPYRIGHT "Copyright (c) Timothy A. Davis, 2006-2011" + +/* --- primary CSparse routines and data structures ------------------------- */ +typedef struct cs_sparse /* matrix in compressed-column or triplet form */ +{ + int nzmax ; /* maximum number of entries */ + int m ; /* number of rows */ + int n ; /* number of columns */ + int *p ; /* column pointers (size n+1) or col indices (size nzmax) */ + int *i ; /* row indices, size nzmax */ + double *x ; /* numerical values, size nzmax */ + int nz ; /* # of entries in triplet matrix, -1 for compressed-col */ +} cs ; + +cs *cs_add (const cs *A, const cs *B, double alpha, double beta) ; +int cs_cholsol (int order, const cs *A, double *b) ; +cs *cs_compress (const cs *T) ; +int cs_dupl (cs *A) ; +int cs_entry (cs *T, int i, int j, double x) ; +int cs_gaxpy (const cs *A, const double *x, double *y) ; +cs *cs_load (FILE *f) ; +int cs_lusol (int order, const cs *A, double *b, double tol) ; +cs *cs_multiply (const cs *A, const cs *B) ; +double cs_norm (const cs *A) ; +int cs_print (const cs *A, int brief) ; +int cs_qrsol (int order, const cs *A, double *b) ; +cs *cs_transpose (const cs *A, int values) ; +/* utilities */ +void *cs_calloc (int n, size_t size) ; +void *cs_free (void *p) ; +void *cs_realloc (void *p, int n, size_t size, int *ok) ; +cs *cs_spalloc (int m, int n, int nzmax, int values, int triplet) ; +cs *cs_spfree (cs *A) ; +int cs_sprealloc (cs *A, int nzmax) ; +void *cs_malloc (int n, size_t size) ; + +/* --- secondary CSparse routines and data structures ----------------------- */ +typedef struct cs_symbolic /* symbolic Cholesky, LU, or QR analysis */ +{ + int *pinv ; /* inverse row perm. for QR, fill red. perm for Chol */ + int *q ; /* fill-reducing column permutation for LU and QR */ + int *parent ; /* elimination tree for Cholesky and QR */ + int *cp ; /* column pointers for Cholesky, row counts for QR */ + int *leftmost ; /* leftmost[i] = min(find(A(i,:))), for QR */ + int m2 ; /* # of rows for QR, after adding fictitious rows */ + double lnz ; /* # entries in L for LU or Cholesky; in V for QR */ + double unz ; /* # entries in U for LU; in R for QR */ +} css ; + +typedef struct cs_numeric /* numeric Cholesky, LU, or QR factorization */ +{ + cs *L ; /* L for LU and Cholesky, V for QR */ + cs *U ; /* U for LU, R for QR, not used for Cholesky */ + int *pinv ; /* partial pivoting for LU */ + double *B ; /* beta [0..n-1] for QR */ +} csn ; + +typedef struct cs_dmperm_results /* cs_dmperm or cs_scc output */ +{ + int *p ; /* size m, row permutation */ + int *q ; /* size n, column permutation */ + int *r ; /* size nb+1, block k is rows r[k] to r[k+1]-1 in A(p,q) */ + int *s ; /* size nb+1, block k is cols s[k] to s[k+1]-1 in A(p,q) */ + int nb ; /* # of blocks in fine dmperm decomposition */ + int rr [5] ; /* coarse row decomposition */ + int cc [5] ; /* coarse column decomposition */ +} csd ; + +int *cs_amd (int order, const cs *A) ; +csn *cs_chol (const cs *A, const css *S) ; +csd *cs_dmperm (const cs *A, int seed) ; +int cs_droptol (cs *A, double tol) ; +int cs_dropzeros (cs *A) ; +int cs_happly (const cs *V, int i, double beta, double *x) ; +int cs_ipvec (const int *p, const double *b, double *x, int n) ; +int cs_lsolve (const cs *L, double *x) ; +int cs_ltsolve (const cs *L, double *x) ; +csn *cs_lu (const cs *A, const css *S, double tol) ; +cs *cs_permute (const cs *A, const int *pinv, const int *q, int values) ; +int *cs_pinv (const int *p, int n) ; +int cs_pvec (const int *p, const double *b, double *x, int n) ; +csn *cs_qr (const cs *A, const css *S) ; +css *cs_schol (int order, const cs *A) ; +css *cs_sqr (int order, const cs *A, int qr) ; +cs *cs_symperm (const cs *A, const int *pinv, int values) ; +int cs_updown (cs *L, int sigma, const cs *C, const int *parent) ; +int cs_usolve (const cs *U, double *x) ; +int cs_utsolve (const cs *U, double *x) ; +/* utilities */ +css *cs_sfree (css *S) ; +csn *cs_nfree (csn *N) ; +csd *cs_dfree (csd *D) ; + +/* --- tertiary CSparse routines -------------------------------------------- */ +int *cs_counts (const cs *A, const int *parent, const int *post, int ata) ; +double cs_cumsum (int *p, int *c, int n) ; +int cs_dfs (int j, cs *G, int top, int *xi, int *pstack, const int *pinv) ; +int cs_ereach (const cs *A, int k, const int *parent, int *s, int *w) ; +int *cs_etree (const cs *A, int ata) ; +int cs_fkeep (cs *A, int (*fkeep) (int, int, double, void *), void *other) ; +double cs_house (double *x, double *beta, int n) ; +int cs_leaf (int i, int j, const int *first, int *maxfirst, int *prevleaf, + int *ancestor, int *jleaf) ; +int *cs_maxtrans (const cs *A, int seed) ; +int *cs_post (const int *parent, int n) ; +int *cs_randperm (int n, int seed) ; +int cs_reach (cs *G, const cs *B, int k, int *xi, const int *pinv) ; +int cs_scatter (const cs *A, int j, double beta, int *w, double *x, int mark, + cs *C, int nz) ; +csd *cs_scc (cs *A) ; +int cs_spsolve (cs *G, const cs *B, int k, int *xi, double *x, + const int *pinv, int lo) ; +int cs_tdfs (int j, int k, int *head, const int *next, int *post, + int *stack) ; +/* utilities */ +csd *cs_dalloc (int m, int n) ; +csd *cs_ddone (csd *D, cs *C, void *w, int ok) ; +cs *cs_done (cs *C, void *w, void *x, int ok) ; +int *cs_idone (int *p, cs *C, void *w, int ok) ; +csn *cs_ndone (csn *N, cs *C, void *w, void *x, int ok) ; + +#define CS_MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define CS_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define CS_FLIP(i) (-(i)-2) +#define CS_UNFLIP(i) (((i) < 0) ? CS_FLIP(i) : (i)) +#define CS_MARKED(w,j) (w [j] < 0) +#define CS_MARK(w,j) { w [j] = CS_FLIP (w [j]) ; } +#define CS_CSC(A) (A && (A->nz == -1)) +#define CS_TRIPLET(A) (A && (A->nz >= 0)) +#endif diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Contents.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Contents.m new file mode 100644 index 0000000..e2d0b0e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Contents.m @@ -0,0 +1,53 @@ +% CSparse: a Concise Sparse matrix Package. +% +% Matrices used in CSparse must in general be either sparse and real, +% or dense vectors. Ordering methods can accept any sparse matrix. +% +% cs_add - sparse matrix addition. +% cs_amd - approximate minimum degree ordering. +% cs_chol - sparse Cholesky factorization. +% cs_cholsol - solve A*x=b using a sparse Cholesky factorization. +% cs_counts - column counts for sparse Cholesky factor L. +% cs_dmperm - maximum matching or Dulmage-Mendelsohn permutation. +% cs_dmsol - x=A\b using the coarse Dulmage-Mendelsohn decomposition. +% cs_dmspy - plot the Dulmage-Mendelsohn decomposition of a matrix. +% cs_droptol - remove small entries from a sparse matrix. +% cs_esep - find an edge separator of a symmetric matrix A +% cs_etree - elimination tree of A or A'*A. +% cs_gaxpy - sparse matrix times vector. +% cs_lsolve - solve a sparse lower triangular system L*x=b. +% cs_ltsolve - solve a sparse upper triangular system L'*x=b. +% cs_lu - sparse LU factorization, with fill-reducing ordering. +% cs_lusol - solve Ax=b using LU factorization. +% cs_make - compiles CSparse for use in MATLAB. +% cs_multiply - sparse matrix multiply. +% cs_nd - generalized nested dissection ordering. +% cs_nsep - find a node separator of a symmetric matrix A. +% cs_permute - permute a sparse matrix. +% cs_print - print the contents of a sparse matrix. +% cs_qr - sparse QR factorization. +% cs_qleft - apply Householder vectors on the left. +% cs_qright - apply Householder vectors on the right. +% cs_qrsol - solve a sparse least-squares problem. +% cs_randperm - random permutation. +% cs_sep - convert an edge separator into a node separator. +% cs_scc - strongly-connected components of a square sparse matrix. +% cs_scc2 - cs_scc, or connected components of a bipartite graph. +% cs_sparse - convert a triplet form into a sparse matrix. +% cs_sqr - symbolic sparse QR factorization. +% cs_symperm - symmetric permutation of a symmetric matrix. +% cs_transpose - transpose a real sparse matrix. +% cs_updown - rank-1 update/downdate of a sparse Cholesky factorization. +% cs_usolve - solve a sparse upper triangular system U*x=b. +% cs_utsolve - solve a sparse lower triangular system U'*x=b. +% cspy - plot a matrix in color. +% ccspy - plot the connected components of a matrix. + +% Example: +% help cs_add + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +% helper function: +% cs_must_compile - return 1 if source code f must be compiled, 0 otherwise diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Makefile b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Makefile new file mode 100644 index 0000000..8e60efa --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/Makefile @@ -0,0 +1,259 @@ +MEX = mex -O +ARCHIVE = ar rv +RANLIB = ranlib + +I = -I../../Include + +all: mexcsparse.a cs_mex.h + $(MEX) cs_thumb_mex.c $(I) mexcsparse.a -output cs_thumb + $(MEX) cs_print_mex.c $(I) mexcsparse.a -output cs_print + $(MEX) cs_updown_mex.c $(I) mexcsparse.a -output cs_updown + $(MEX) cs_gaxpy_mex.c $(I) mexcsparse.a -output cs_gaxpy + $(MEX) cs_transpose_mex.c $(I) mexcsparse.a -output cs_transpose + $(MEX) cs_sparse_mex.c $(I) mexcsparse.a -output cs_sparse + $(MEX) cs_multiply_mex.c $(I) mexcsparse.a -output cs_multiply + $(MEX) cs_add_mex.c $(I) mexcsparse.a -output cs_add + $(MEX) cs_permute_mex.c $(I) mexcsparse.a -output cs_permute + $(MEX) cs_symperm_mex.c $(I) mexcsparse.a -output cs_symperm + $(MEX) cs_lsolve_mex.c $(I) mexcsparse.a -output cs_lsolve + $(MEX) cs_ltsolve_mex.c $(I) mexcsparse.a -output cs_ltsolve + $(MEX) cs_usolve_mex.c $(I) mexcsparse.a -output cs_usolve + $(MEX) cs_utsolve_mex.c $(I) mexcsparse.a -output cs_utsolve + $(MEX) cs_chol_mex.c $(I) mexcsparse.a -output cs_chol + $(MEX) cs_etree_mex.c $(I) mexcsparse.a -output cs_etree + $(MEX) cs_counts_mex.c $(I) mexcsparse.a -output cs_counts + $(MEX) cs_qr_mex.c $(I) mexcsparse.a -output cs_qr + $(MEX) cs_amd_mex.c $(I) mexcsparse.a -output cs_amd + $(MEX) cs_lu_mex.c $(I) mexcsparse.a -output cs_lu + $(MEX) cs_cholsol_mex.c $(I) mexcsparse.a -output cs_cholsol + $(MEX) cs_lusol_mex.c $(I) mexcsparse.a -output cs_lusol + $(MEX) cs_droptol_mex.c $(I) mexcsparse.a -output cs_droptol + $(MEX) cs_qrsol_mex.c $(I) mexcsparse.a -output cs_qrsol + $(MEX) cs_dmperm_mex.c $(I) mexcsparse.a -output cs_dmperm + $(MEX) cs_scc_mex.c $(I) mexcsparse.a -output cs_scc + $(MEX) cs_sqr_mex.c $(I) mexcsparse.a -output cs_sqr + $(MEX) cs_randperm_mex.c $(I) mexcsparse.a -output cs_randperm + +CS = cs_mex.o \ + cs_amd.o \ + cs_chol.o \ + cs_counts.o \ + cs_cumsum.o \ + cs_fkeep.o \ + cs_dfs.o \ + cs_dmperm.o \ + cs_droptol.o \ + cs_dropzeros.o \ + cs_dupl.o \ + cs_entry.o \ + cs_etree.o \ + cs_gaxpy.o \ + cs_ipvec.o \ + cs_lsolve.o \ + cs_ltsolve.o \ + cs_lu.o \ + cs_maxtrans.o \ + cs_util.o \ + cs_malloc.o \ + cs_multiply.o \ + cs_add.o \ + cs_scatter.o \ + cs_permute.o \ + cs_pinv.o \ + cs_post.o \ + cs_tdfs.o \ + cs_pvec.o \ + cs_qr.o \ + cs_happly.o \ + cs_house.o \ + cs_schol.o \ + cs_scc.o \ + cs_sqr.o \ + cs_symperm.o \ + cs_transpose.o \ + cs_compress.o \ + cs_usolve.o \ + cs_utsolve.o \ + cs_cholsol.o \ + cs_lusol.o \ + cs_qrsol.o \ + cs_updown.o \ + cs_norm.o \ + cs_print.o \ + cs_load.o \ + cs_spsolve.o \ + cs_reach.o \ + cs_ereach.o \ + cs_leaf.o \ + cs_randperm.o + +mexcsparse.a: $(CS) + $(ARCHIVE) mexcsparse.a $(CS) + $(RANLIB) mexcsparse.a + +$(CS): ../../Include/cs.h + + +cs_mex.o: cs_mex.c cs_mex.h + $(MEX) -c $(I) $< + +cs_amd.o: ../../Source/cs_amd.c + $(MEX) -c $(I) $< + +cs_chol.o: ../../Source/cs_chol.c + $(MEX) -c $(I) $< + +cs_ereach.o: ../../Source/cs_ereach.c + $(MEX) -c $(I) $< + +cs_cholsol.o: ../../Source/cs_cholsol.c + $(MEX) -c $(I) $< + +cs_lusol.o: ../../Source/cs_lusol.c + $(MEX) -c $(I) $< + +cs_qrsol.o: ../../Source/cs_qrsol.c + $(MEX) -c $(I) $< + +cs_counts.o: ../../Source/cs_counts.c + $(MEX) -c $(I) $< + +cs_leaf.o: ../../Source/cs_leaf.c + $(MEX) -c $(I) $< + +cs_cumsum.o: ../../Source/cs_cumsum.c + $(MEX) -c $(I) $< + +cs_fkeep.o: ../../Source/cs_fkeep.c + $(MEX) -c $(I) $< + +cs_dfs.o: ../../Source/cs_dfs.c + $(MEX) -c $(I) $< + +cs_droptol.o: ../../Source/cs_droptol.c + $(MEX) -c $(I) $< + +cs_dropzeros.o: ../../Source/cs_dropzeros.c + $(MEX) -c $(I) $< + +cs_dupl.o: ../../Source/cs_dupl.c + $(MEX) -c $(I) $< + +cs_entry.o: ../../Source/cs_entry.c + $(MEX) -c $(I) $< + +cs_etree.o: ../../Source/cs_etree.c + $(MEX) -c $(I) $< + +cs_gaxpy.o: ../../Source/cs_gaxpy.c + $(MEX) -c $(I) $< + +cs_ipvec.o: ../../Source/cs_ipvec.c + $(MEX) -c $(I) $< + +cs_lsolve.o: ../../Source/cs_lsolve.c + $(MEX) -c $(I) $< + +cs_ltsolve.o: ../../Source/cs_ltsolve.c + $(MEX) -c $(I) $< + +cs_lu.o: ../../Source/cs_lu.c + $(MEX) -c $(I) $< + +cs_util.o: ../../Source/cs_util.c + $(MEX) -c $(I) $< + +cs_malloc.o: ../../Source/cs_malloc.c + $(MEX) -c $(I) $< + +cs_multiply.o: ../../Source/cs_multiply.c + $(MEX) -c $(I) $< + +cs_add.o: ../../Source/cs_add.c + $(MEX) -c $(I) $< + +cs_scatter.o: ../../Source/cs_scatter.c + $(MEX) -c $(I) $< + +cs_permute.o: ../../Source/cs_permute.c + $(MEX) -c $(I) $< + +cs_pinv.o: ../../Source/cs_pinv.c + $(MEX) -c $(I) $< + +cs_post.o: ../../Source/cs_post.c + $(MEX) -c $(I) $< + +cs_tdfs.o: ../../Source/cs_tdfs.c + $(MEX) -c $(I) $< + +cs_pvec.o: ../../Source/cs_pvec.c + $(MEX) -c $(I) $< + +cs_qr.o: ../../Source/cs_qr.c + $(MEX) -c $(I) $< + +cs_happly.o: ../../Source/cs_happly.c + $(MEX) -c $(I) $< + +cs_house.o: ../../Source/cs_house.c + $(MEX) -c $(I) $< + +cs_schol.o: ../../Source/cs_schol.c + $(MEX) -c $(I) $< + +cs_spsolve.o: ../../Source/cs_spsolve.c + $(MEX) -c $(I) $< + +cs_reach.o: ../../Source/cs_reach.c + $(MEX) -c $(I) $< + +cs_sqr.o: ../../Source/cs_sqr.c + $(MEX) -c $(I) $< + +cs_symperm.o: ../../Source/cs_symperm.c + $(MEX) -c $(I) $< + +cs_transpose.o: ../../Source/cs_transpose.c + $(MEX) -c $(I) $< + +cs_compress.o: ../../Source/cs_compress.c + $(MEX) -c $(I) $< + +cs_usolve.o: ../../Source/cs_usolve.c + $(MEX) -c $(I) $< + +cs_utsolve.o: ../../Source/cs_utsolve.c + $(MEX) -c $(I) $< + +cs_dmperm.o: ../../Source/cs_dmperm.c + $(MEX) -c $(I) $< + +cs_randperm.o: ../../Source/cs_randperm.c + $(MEX) -c $(I) $< + +cs_maxtrans.o: ../../Source/cs_maxtrans.c + $(MEX) -c $(I) $< + +cs_scc.o: ../../Source/cs_scc.c + $(MEX) -c $(I) $< + +cs_updown.o: ../../Source/cs_updown.c + $(MEX) -c $(I) $< + +cs_print.o: ../../Source/cs_print.c + $(MEX) -c $(I) $< + +cs_norm.o: ../../Source/cs_norm.c + $(MEX) -c $(I) $< + +cs_load.o: ../../Source/cs_load.c + $(MEX) -c $(I) $< + +clean: + - $(RM) *.o + +distclean: clean + - $(RM) *.mex* *.dll *.a + +purge: distclean diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/README.txt b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/README.txt new file mode 100644 index 0000000..7c97060 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/README.txt @@ -0,0 +1 @@ +MATLAB interface for CSparse. See Contents.m for details. diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/ccspy.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/ccspy.m new file mode 100644 index 0000000..787eada --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/ccspy.m @@ -0,0 +1,67 @@ +function [p, q, r, s] = ccspy (A, bipartite, res) +%CCSPY plot the connected components of a matrix. +% +% Example: +% [p, q, r, s] = ccspy (A, bipartite, res) +% +% If A is square, [p,q,r,s] = ccspy(A) finds a permutation p so that A(p,q) +% is permuted into block upper triangular form. In this case, r=s, p=q and +% the kth diagonal block is given by A (t,t) where t = r(k):r(k+1)-1. +% The diagonal of A is ignored. +% +% If A is not square (or for [p,q,r,s] = ccspy(A,1)), then the connected +% components of the bipartite graph of A are found. A(p,q) is permuted into +% block diagonal form, where the diagonal blocks are rectangular. The kth +% block is given by A(r(k):r(k+1)-1,s(k):s(k+1)-1). A can be rectangular. +% +% It then plots the result via cspy, drawing a greenbox around each component. +% A 3rd input argument (res) controls the resolution (see cspy for a +% description of the res parameter). +% +% See also CSPY, CS_DMPERM, DMPERM, CS_SCC, CS_SCC2, CS_DMSPY. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (~issparse (A)) + A = sparse (A) ; +end +[m n] = size (A) ; +if (nargin < 3) + res = 256 ; +end +if (nargin < 2) + bipartite = [ ] ; +end +if (isempty (bipartite)) + bipartite = (m ~= n) ; +end + +% find the strongly connected components +[p1 q r s] = cs_scc2 (A, bipartite) ; +if (nargout > 0) + p = p1 ; +end + +nb = length (r)-1 ; + +% plot the result +S = A (p1,q) ; +if (res == 0) + spy (S) ; + e = 1 ; +else + e = cspy (S,res) ; +end +hold on + +title (sprintf ('%d-by-%d, strongly connected commponents: %d\n', m, n, nb)) ; + +if (~bipartite) + plot ([.5 .5 n+.5 n+.5], [.5 .5 n+.5 n+.5], 'r') ; +end + +drawboxes (nb, e, r, s) ; + +drawbox (1,m+1,1,n+1,'k',1,e) ; +hold off diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add.m new file mode 100644 index 0000000..46649a7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add.m @@ -0,0 +1,17 @@ +function C = cs_add (A,B,alpha,beta) %#ok +%CS_ADD sparse matrix addition. +% C = cs_add(A,B,alpha,beta) computes C = alpha*A+beta*B, +% where alpha and beta default to 1 if not present. +% +% Example: +% Prob1 = UFget ('HB/ibm32') ; A = Prob1.A ; +% Prob2 = UFget ('Hamrle/Hamrle1') ; B = Prob2.A ; +% C = cs_add (A,B) ; +% D = A+B ; % same as C +% +% See also CS_MULTIPLY, CS_GAXPY, PLUS, MINUS. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_add mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add_mex.c new file mode 100644 index 0000000..f4bac35 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_add_mex.c @@ -0,0 +1,28 @@ +#include "cs_mex.h" +/* cs_add: sparse matrix addition */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double alpha, beta ; + cs Amatrix, Bmatrix, *A, *B, *C, *D ; + if (nargout > 1 || nargin < 2 || nargin > 4) + { + mexErrMsgTxt ("Usage: C = cs_add(A,B,alpha,beta)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ; /* get B */ + alpha = (nargin < 3) ? 1 : mxGetScalar (pargin [2]) ; /* get alpha */ + beta = (nargin < 4) ? 1 : mxGetScalar (pargin [3]) ; /* get beta */ + C = cs_add (A,B,alpha,beta) ; /* C = alpha*A + beta *B */ + cs_dropzeros (C) ; /* drop zeros */ + D = cs_transpose (C, 1) ; /* sort result via double transpose */ + cs_spfree (C) ; + C = cs_transpose (D, 1) ; + cs_spfree (D) ; + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd.m new file mode 100644 index 0000000..f9081bb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd.m @@ -0,0 +1,25 @@ +function p = cs_amd (A,order) %#ok +%CS_AMD approximate minimum degree ordering. +% p = cs_amd(A) finds a minimum degree ordering of A+A' +% p = cs_amd(A,order): +% order = 1: same as cs_amd(A) +% order = 2: minimum degree ordering of S'*S where S = A except that +% "dense" rows of A are removed from S (a dense row has +% 10*sqrt(n) or more entries where n = size(A,2)). Similar +% to p = colamd(A), except that colamd does not form A'*A +% explicitly. +% order = 3: minimum degree ordering of A'*A. Similar to colamd(A,[n m]) +% where [m n] = size(A), except that colamd does not form A'*A +% explicitly. +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; +% p = cs_amd (A) ; +% nnz (chol (A)) +% nnz (chol (A (p,p))) +% +% See also AMD, COLAMD, SYMAMD. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_amd mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd_mex.c new file mode 100644 index 0000000..10bcd3d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_amd_mex.c @@ -0,0 +1,23 @@ +#include "cs_mex.h" +/* cs_amd: approximate minimum degree ordering */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + int *P, order ; + if (nargout > 1 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: p = cs_amd(A,order)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ; /* get A */ + order = (nargin > 1) ? mxGetScalar (pargin [1]) : 1 ; /* get ordering */ + order = CS_MAX (order, 1) ; + order = CS_MIN (order, 3) ; + P = cs_amd (order, A) ; /* min. degree ordering */ + pargout [0] = cs_mex_put_int (P, A->n, 1, 1) ; /* return P */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol.m new file mode 100644 index 0000000..0a39f02 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol.m @@ -0,0 +1,19 @@ +function [L,p] = cs_chol (A,drop) %#ok +%CS_CHOL sparse Cholesky factorization. +% L = cs_chol(A) is the same as L = chol(A)', using triu(A). +% [L,p] = cs_chol(A) first orders A with p=cs_amd(A), so that L*L' = A(p,p). +% A second optional input argument controls whether or not numerically zero +% entries are removed from L. cs_chol(A) and cs_chol(A,1) drop them; +% cs_chol(A,0) keeps them. They must be kept for cs_updown to work properly. +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; [L,p] = cs_chol (A) ; +% cspy (A (p,p)) ; +% cspy (L) ; +% +% See also CS_AMD, CS_UPDOWN, CHOL, AMD, SYMAMD. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_chol mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol_mex.c new file mode 100644 index 0000000..4a38139 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_chol_mex.c @@ -0,0 +1,28 @@ +#include "cs_mex.h" +/* cs_chol: sparse Cholesky factorization */ +void mexFunction (int nargout, mxArray *pargout [ ], int nargin, + const mxArray *pargin [ ]) +{ + cs Amatrix, *A ; + int order, n, drop, *p ; + css *S ; + csn *N ; + if (nargout > 2 || nargin < 1 || nargin > 2) + mexErrMsgTxt ("Usage: [L,p] = cs_chol(A,drop)") ; + A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; /* get A */ + n = A->n ; + order = (nargout > 1) ? 1 : 0 ; /* determine ordering */ + S = cs_schol (order, A) ; /* symbolic Cholesky */ + N = cs_chol (A, S) ; /* numeric Cholesky */ + if (!N) mexErrMsgTxt ("cs_chol failed: not positive definite\n") ; + drop = (nargin == 1) ? 1 : mxGetScalar (pargin [1]) ; + if (drop) cs_dropzeros (N->L) ; /* drop zeros if requested*/ + pargout [0] = cs_mex_put_sparse (&(N->L)) ; /* return L */ + if (nargout > 1) + { + p = cs_pinv (S->pinv, n) ; /* p=pinv' */ + pargout [1] = cs_mex_put_int (p, n, 1, 1) ; /* return p */ + } + cs_nfree (N) ; + cs_sfree (S) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol.m new file mode 100644 index 0000000..e3c9f56 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol.m @@ -0,0 +1,17 @@ +function x = cs_cholsol (A,b,order) %#ok +%CS_CHOLSOL solve A*x=b using a sparse Cholesky factorization. +% x = cs_cholsol(A,b) computes x = A\b, where A sparse symmetric positive +% definite, and b is a full vector. A 3rd input parameter allows the +% ordering to be modified: 0: natural, 1:amd(A), 2: amd(S'*S) where S=A except +% with no dense rows, 3:amd(A'*A). The default ordering option is 1. +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; b = rand (size (A,1),1) ; +% x = cs_cholsol (A,b) ; norm (A*x-b) +% +% See also CS_CHOL, CS_AMD, CS_LUSOL, CS_QRSOL, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_cholsol mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol_mex.c new file mode 100644 index 0000000..c71aecc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_cholsol_mex.c @@ -0,0 +1,28 @@ +#include "cs_mex.h" +/* cs_cholsol: solve A*x=b using a sparse Cholesky factorization */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, Amatrix ; + double *x, *b ; + int order ; + if (nargout > 1 || nargin < 2 || nargin > 3) + { + mexErrMsgTxt ("Usage: x = cs_cholsol(A,b,order)") ; + } + A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; /* get A */ + b = cs_mex_get_double (A->n, pargin [1]) ; /* get b */ + x = cs_mex_put_double (A->n, b, &(pargout [0])) ; /* x = b */ + order = (nargin < 3) ? 1 : mxGetScalar (pargin [2]) ; + order = CS_MAX (order, 0) ; + order = CS_MIN (order, 3) ; + if (!cs_cholsol (order, A, x)) /* x = A\x */ + { + mexErrMsgTxt ("A not positive definite") ; + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts.m new file mode 100644 index 0000000..5be596a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts.m @@ -0,0 +1,19 @@ +function c = cs_counts (A,mode) %#ok +%CS_COUNTS column counts for sparse Cholesky factor L. +% c = cs_counts(A) returns a vector of the column counts of L, for the +% Cholesky factorization L*L' = A. That is, c = sum(spones(chol(A)')), +% except the Cholesky factorization is not computed. +% c = cs_counts(A), returns counts for cs_chol(A). +% c = cs_counts(A,'col'), returns counts for cs_chol(A'*A). +% c = cs_counts(A,'sym'), same as cs_counts(A). +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; c = cs_counts (A) +% full (sum (spones (chol (A)'))) +% +% See also SYMBFACT. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_counts mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts_mex.c new file mode 100644 index 0000000..32444e7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_counts_mex.c @@ -0,0 +1,32 @@ +#include "cs_mex.h" +/* cs_counts: column counts for sparse Cholesky factor L. */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + int n, ata, *parent, *post, *c ; + char mode [20] ; + if (nargout > 2 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: c = cs_counts(A,mode)") ; + } + ata = 0 ; /* get mode */ + if (nargin > 1 && mxIsChar (pargin [1])) + { + mxGetString (pargin [1], mode, 8) ; + ata = (mode [0] == 'c') ; + } + A = cs_mex_get_sparse (&Amatrix, !ata, 0, pargin [0]) ; /* get A */ + n = A->n ; + parent = cs_etree (A, ata) ; /* compute etree */ + post = cs_post (parent, n) ; /* postorder the etree*/ + c = cs_counts (A, parent, post, ata) ; /* get column counts */ + pargout [0] = cs_mex_put_int (c, n, 0, 1) ; /* return counts */ + cs_free (parent) ; + cs_free (post) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm.m new file mode 100644 index 0000000..5be1129 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm.m @@ -0,0 +1,64 @@ +function [p,q,r,s,cc,rr] = cs_dmperm (A,seed) %#ok +%CS_DMPERM maximum matching or Dulmage-Mendelsohn permutation. +% p = cs_dmperm(A) finds a maximum matching p such that p(j) = i if column j +% is matched to row i, or 0 if column j is unmatched. If A is square and +% full structural rank, p is a row permutation and A(p,:) has a zero-free +% diagonal. The structural rank of A is sprank(A) = sum(p>0). +% +% [p,q,r,s,cc,rr] = cs_dmperm(A) finds the Dulmage-Mendelsohn decomposition +% of A. p and q are permutation vectors. cc and rr are vectors of length 5. +% C = A(p,q) is split into a 4-by-4 set of coarse blocks: +% +% A11 A12 A13 A14 +% 0 0 A23 A24 +% 0 0 0 A34 +% 0 0 0 A44 +% +% where A12, A23, and A34 are square with zero-free diagonals. The columns of +% A11 are the unmatched columns, and the rows of A44 are the unmatched rows. +% Any of these blocks can be empty. In the "coarse" decomposition, the +% (i,j)th block is C(rr(i):rr(i+1)-1,cc(j):cc(j+1)-1). In terms of a linear +% system, [A11 A12] is the underdetermined part of the system (it is always +% rectangular and with more columns and rows, or 0-by-0), A23 is the well- +% determined part of the system (it is always square), and [A34 ; A44] is +% the over-determined part of the system (it is always rectangular with more +% rows than columns, or 0-by-0). +% +% The structural rank of A is sprank(A) = rr(4)-1, which is an upper bound on +% the numerical rank of A. sprank(A) = rank(full(sprand(A))) with probability +% 1 in exact arithmetic. +% +% The A23 submatrix is further subdivided into block upper triangular form +% via the "fine" decomposition (the strongly-connected components of A23). +% If A is square and structurally non-singular, A23 is the entire matrix. +% +% C(r(i):r(i+1)-1,s(j):s(j+1)-1) is the (i,j)th block of the fine +% decomposition. The (1,1) block is the rectangular block [A11 A12], unless +% this block is 0-by-0. The (b,b) block is the rectangular block [A34 ; A44], +% unless this block is 0-by-0, where b = length(r)-1. All other blocks of the +% form C(r(i):r(i+1)-1,s(i):s(i+1)-1) are diagonal blocks of A23, and are +% square with a zero-free diagonal. +% +% The matching algorithm used in cs_dmperm can take a very long time +% in rare cases. This can be avoided by exploiting a randomized algorithm, +% with cs_dmperm(A,seed). If seed=0, the non-randomized algorithm is used +% (columns are considered in order 1:n). If seed=-1, columns are considered +% in reverse order. Otherwise, the columns are considered in a random order, +% using seed as the random number generator seed. Try cs_dmpmerm(A,1) or +% cs_dmperm(A,rand), for a randomized order, for example. Seed defaults to 0. +% +% +% Example: +% Prob = UFget ('HB/west0479') ; A = Prob.A ; cspy (A) ; +% p = cs_dmperm (A) ; +% cspy (A (p,:)) ; +% [p q r s cc rr] = cs_dmperm (A) ; +% cspy (A (p,q)) ; +% cs_dmspy (A) ; +% +% See also CS_DMSPY, CS_DMSOL, DMPERM, SPRANK, CS_RANDPERM, RAND + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_dmperm mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm_mex.c new file mode 100644 index 0000000..9e18ff4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmperm_mex.c @@ -0,0 +1,41 @@ +#include "cs_mex.h" +/* cs_dmperm: maximum matching or Dulmage-Mendelsohn permutation. */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double seed ; + cs *A, Amatrix ; + csd *D ; + int m, n, *jmatch, iseed ; + if (nargin < 1 || nargin > 2 || nargout > 6) + { + mexErrMsgTxt ("Usage: [p,q,r,s,cc,rr] = cs_dmperm (A,seed)") ; + } + seed = (nargin > 1) ? mxGetScalar (pargin [1]) : 0 ; /* get seed */ + iseed = (seed > 0 && seed < 1) ? (seed * RAND_MAX) : seed ; + A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ; /* get A */ + n = A->n ; + m = A->m ; + if (nargout <= 1) + { + jmatch = cs_maxtrans (A, iseed) ; /* max. matching */ + pargout [0] = cs_mex_put_int (jmatch+m, n, 1, 0) ; /* return imatch */ + cs_free (jmatch) ; + } + else + { + D = cs_dmperm (A, iseed) ; /* Dulmage-Mendelsohn decomposition */ + pargout [0] = cs_mex_put_int (D->p, m, 1, 0) ; + pargout [1] = cs_mex_put_int (D->q, n, 1, 0) ; + pargout [2] = cs_mex_put_int (D->r, D->nb+1, 1, 0) ; + pargout [3] = cs_mex_put_int (D->s, D->nb+1, 1, 0) ; + pargout [4] = cs_mex_put_int (D->cc, 5, 1, 0) ; + pargout [5] = cs_mex_put_int (D->rr, 5, 1, 0) ; + cs_dfree (D) ; + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmsol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmsol.m new file mode 100644 index 0000000..28d3598 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmsol.m @@ -0,0 +1,33 @@ +function x = cs_dmsol (A,b) +%CS_DMSOL x=A\b using the coarse Dulmage-Mendelsohn decomposition. +% x = cs_dmsol(A,b) computes x=A\b where A may be rectangular and/or +% structurally rank deficient, and b is a full vector. +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; b = rand (size (A,1),1) ; +% x = cs_dmsol (A,b) ; norm (A*x-b) +% +% See also CS_QRSOL, CS_LUSOL, CS_DMPERM, SPRANK, RANK. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +[p q r s cc rr] = cs_dmperm (A) ; +C = A (p,q) ; +b = b (p) ; +x = zeros (n,1) ; +if (rr(3) <= m & cc(4) <= n) %#ok + x (cc(4):n) = cs_qrsol (C (rr(3):m, cc(4):n), b (rr(3):m)) ; + b (1:rr(3)-1) = b (1:rr(3)-1) - C (1:rr(3)-1, cc(4):n) * x (cc(4):n) ; +end +if (rr(2) < rr (3) & cc(3) < cc(4)) %#ok + x (cc(3):cc(4)-1) = ... + cs_lusol (C (rr(2):rr(3)-1, cc(3):cc(4)-1), b (rr(2):rr(3)-1)) ; + b (1:rr(2)-1) = ... + b (1:rr(2)-1) - C (1:rr(2)-1, cc(3):cc(4)-1) * x (cc(3):cc(4)-1) ; +end +if (rr(2) > 1 & cc(3) > 1) %#ok + x (1:cc(3)-1) = cs_qrsol (C (1:rr(2)-1, 1:cc(3)-1), b (1:rr(2)-1)) ; +end +x (q) = x ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmspy.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmspy.m new file mode 100644 index 0000000..5539cca --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_dmspy.m @@ -0,0 +1,66 @@ +function [p,q,r,s,cc,rr] = cs_dmspy (A,res,seed) +%CS_DMSPY plot the Dulmage-Mendelsohn decomposition of a matrix. +% [p,q,r,s,cc,rr] = cs_dmspy(A) computes [p,q,r,s,cc,rr] = cs_dmperm(A), +% does spy(A(p,q)), and then draws boxes around the coarse and fine +% decompositions. A 2nd input argument (cs_dmspy(A,res)) changes the +% resolution of the image to res-by-res (default resolution is 256). +% If res is zero, spy is used instead of cspy. If the resolution is low, the +% picture of the blocks in the figure can overlap. They do not actually +% overlap in the matrix. With 3 arguments, cs_dmspy(A,res,seed), +% cs_dmperm(A,seed) is used, where seed controls the randomized algorithm +% used by cs_dmperm. +% +% Example: +% Prob = UFget ('HB/arc130') ; cs_dmspy (Prob.A) ; +% +% See also CS_DMPERM, CS_DMSOL, DMPERM, SPRANK, SPY. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (~issparse (A)) + A = sparse (A) ; +end +if (nargin < 2) + res = 256 ; +end +if (nargin < 3) + seed = 0 ; +end + +% Dulmage-Mendelsohn permutation +[p1,q,r,s,cc,rr] = cs_dmperm (A,seed) ; +if (nargout > 0) + p = p1 ; +end + +nb = length (r)-1 ; + +% plot the result +S = A (p1,q) ; +if (res == 0) + spy (S) ; + e = 1 ; +else + e = cspy (S,res) ; +end +hold on + +title (sprintf ( ... + '%d-by-%d, sprank: %d, fine blocks: %d, coarse blocks: %d-by-%d\n', ... + size (A), rr(4)-1, nb, length (find (diff (rr))), ... + length (find (diff (cc))))) ; + +drawboxes (nb, e, r, s) ; + +[m n] = size (A) ; +drawbox (1,m+1,1,n+1,'k',1,e) ; + +drawbox (rr(1), rr(2), cc(1), cc (2), 'r', 2, e) ; +drawbox (rr(1), rr(2), cc(2), cc (3), 'r', 2, e) ; +drawbox (rr(2), rr(3), cc(3), cc (4), 'k', 2, e) ; +drawbox (rr(3), rr(4), cc(4), cc (5), 'r', 2, e) ; +drawbox (rr(4), rr(5), cc(4), cc (5), 'r', 2, e) ; + +hold off + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol.m new file mode 100644 index 0000000..ff1b2d8 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol.m @@ -0,0 +1,18 @@ +function C = cs_droptol (A, tol) %#ok +%CS_DROPTOL remove small entries from a sparse matrix. +% C = cs_droptol(A,tol) removes entries from A of magnitude less than or +% equal to tol. Same as A = A .* (abs (A) >= tol). +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; +% cspy (abs (A) >= 1e-10) ; +% C = cs_droptol (A, 1e-10) ; +% cspy (C) ; +% +% See also: RELOP, ABS + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_droptol mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol_mex.c new file mode 100644 index 0000000..950a87d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_droptol_mex.c @@ -0,0 +1,26 @@ +#include "cs_mex.h" +/* cs_droptol: remove small entries from A */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *C, *A ; + int j, k ; + double tol ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: C = cs_droptol(A,tol)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + tol = mxGetScalar (pargin [1]) ; /* get tol */ + C = cs_spalloc (A->m, A->n, A->nzmax, 1, 0) ; /* C = A */ + for (j = 0 ; j <= A->n ; j++) C->p [j] = A->p [j] ; + for (k = 0 ; k < A->nzmax ; k++) C->i [k] = A->i [k] ; + for (k = 0 ; k < A->nzmax ; k++) C->x [k] = A->x [k] ; + cs_droptol (C, tol) ; /* drop from C */ + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_esep.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_esep.m new file mode 100644 index 0000000..db51fc1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_esep.m @@ -0,0 +1,20 @@ +function [a,b] = cs_esep (A) +%CS_ESEP find an edge separator of a symmetric matrix A +% [a,b] = cs_esep(A) finds a edge separator s that splits the graph of A +% into two parts a and b of roughly equal size. The edge separator is the +% set of entries in A(a,b). +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; +% [a,b] = cs_esep (A) ; +% cspy (A (a,b)) ; +% +% See also CS_NSEP, CS_SEP, CS_ND, SYMRCM. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +p = symrcm (A) ; +n2 = fix (size(A,1)/2) ; +a = p (1:n2) ; +b = p (n2+1:end) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree.m new file mode 100644 index 0000000..0bb091d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree.m @@ -0,0 +1,19 @@ +function [parent, post] = cs_etree (A, mode) %#ok +%CS_ETREE elimination tree of A or A'*A. +% parent = cs_etree (A) returns the elimination tree of A. +% parent = cs_etree (A,'col') returns the elimination tree of A'*A. +% parent = cs_etree (A,'sym') is the same as cs_etree(A). +% For the symmetric case (cs_etree(A)), only triu(A) is used. +% +% [parent,post] = cs_etree(...) also returns a postorder of the tree. +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; +% parent = cs_etree (A) ; treeplot (parent) ; +% +% See also ETREE, TREEPLOT. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_etree mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree_mex.c new file mode 100644 index 0000000..45d31fc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_etree_mex.c @@ -0,0 +1,33 @@ +#include "cs_mex.h" +/* cs_etree: elimination tree of A or A'*A */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + int n, ata, *parent, *post ; + char mode [20] ; + if (nargout > 2 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: [parent,post] = cs_etree(A,mode)") ; + } + ata = 0 ; /* get mode */ + if (nargin > 1 && mxIsChar (pargin [1])) + { + mxGetString (pargin [1], mode, 8) ; + ata = (mode [0] == 'c') ; + } + A = cs_mex_get_sparse (&Amatrix, !ata, 0, pargin [0]) ; /* get A */ + n = A->n ; + parent = cs_etree (A, ata) ; /* compute etree */ + if (nargout > 1) + { + post = cs_post (parent, n) ; /* postorder the etree*/ + pargout [1] = cs_mex_put_int (post, n, 1, 1) ; /* return post */ + } + pargout [0] = cs_mex_put_int (parent, n, 1, 1) ; /* return parent */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy.m new file mode 100644 index 0000000..6551b4e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy.m @@ -0,0 +1,15 @@ +function z = cs_gaxpy (A,x,y) %#ok +%CS_GAXPY sparse matrix times vector. +% z = cs_gaxpy(A,x,y) computes z = A*x+y where x and y are full vectors. +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; [m n] = size (A) ; +% x = rand (n,1) ; y = rand (m,1) ; +% z = cs_gaxpy (A, x, y) ; +% +% See also PLUS, MTIMES. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_gaxpy mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy_mex.c new file mode 100644 index 0000000..1ac8209 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_gaxpy_mex.c @@ -0,0 +1,22 @@ +#include "cs_mex.h" +/* z = cs_gaxpy (A,x,y) computes z = A*x+y */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + double *x, *y, *z ; + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: z = cs_gaxpy(A,x,y)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + x = cs_mex_get_double (A->n, pargin [1]) ; /* get x */ + y = cs_mex_get_double (A->m, pargin [2]) ; /* get y */ + z = cs_mex_put_double (A->m, y, &(pargout [0])) ; /* z = y */ + cs_gaxpy (A, x, z) ; /* z = z + A*x */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve.m new file mode 100644 index 0000000..84d4c3a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve.m @@ -0,0 +1,17 @@ +function x = cs_lsolve (L,b) %#ok +%CS_LSOLVE solve a sparse lower triangular system L*x=b. +% x = cs_lsolve(L,b) computes x = L\b, L must be lower triangular with a +% zero-free diagonal. b must be a column vector. x is full if b is full. +% If b is sparse, x is sparse but the nonzero pattern of x is NOT sorted (it +% is returned in topological order). +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; L = cs_chol (Prob.A) ; n = size (L,1) ; +% b = rand (n,1) ; x = cs_lsolve (L,b) ; norm (L*x-b) +% +% See also CS_LTSOLVE, CS_USOLVE, CS_UTSOLVE, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_lsolve mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve_mex.c new file mode 100644 index 0000000..0b6f202 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lsolve_mex.c @@ -0,0 +1,59 @@ +#include "cs_mex.h" +/* cs_lsolve: x=L\b. L must be sparse, real, and lower triangular. b must be a + * real full or sparse vector. x is full or sparse, depending on b. + * + * Time taken is O(flop count), which may be less than n if b is sparse, + * depending on L and b. + * + * This function works with MATLAB 7.2, but is not perfectly compatible with + * the requirements of a MATLAB mexFunction when b is sparse. X is returned + * as an unsorted sparse vector. Also, this mexFunction temporarily modifies + * its input, L, by modifying L->p (in the cs_dfs function) and then restoring + * it. This could be corrected by creating a copy of L->p + * (see cs_dmperm_mex.c), but this would take O(n) time, destroying the + * O(flop count) time complexity of this function. + */ + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Lmatrix, Bmatrix, *L, *B, *X ; + double *x, *b ; + int top, nz, p, *xi ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_lsolve(L,b)") ; + } + L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; /* get L */ + if (mxIsSparse (pargin [1])) + { + B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ;/* get sparse b */ + cs_mex_check (0, L->n, 1, 0, 1, 1, pargin [1]) ; + xi = cs_malloc (2*L->n, sizeof (int)) ; /* get workspace */ + x = cs_malloc (L->n, sizeof (double)) ; + top = cs_spsolve (L, B, 0, xi, x, NULL, 1) ; /* x = L\b */ + X = cs_spalloc (L->n, 1, L->n-top, 1, 0) ; /* create sparse x*/ + X->p [0] = 0 ; + nz = 0 ; + for (p = top ; p < L->n ; p++) + { + X->i [nz] = xi [p] ; + X->x [nz++] = x [xi [p]] ; + } + X->p [1] = nz ; + pargout [0] = cs_mex_put_sparse (&X) ; + cs_free (x) ; + cs_free (xi) ; + } + else + { + b = cs_mex_get_double (L->n, pargin [1]) ; /* get full b */ + x = cs_mex_put_double (L->n, b, &(pargout [0])) ; /* x = b */ + cs_lsolve (L, x) ; /* x = L\x */ + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve.m new file mode 100644 index 0000000..f4f2621 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve.m @@ -0,0 +1,15 @@ +function x = cs_ltsolve (L,b) %#ok +%CS_LTSOLVE solve a sparse upper triangular system L'*x=b. +% x = cs_ltsolve(L,b) computes x = L'\b, L must be lower triangular with a +% zero-free diagonal. b must be a full vector. +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; L = cs_chol (Prob.A) ; n = size (L,1) ; +% b = rand (n,1) ; x = cs_ltsolve (L,b) ; norm (L'*x-b) +% +% See also CS_LSOLVE, CS_USOLVE, CS_UTSOLVE, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_ltsolve mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve_mex.c new file mode 100644 index 0000000..1a59340 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_ltsolve_mex.c @@ -0,0 +1,21 @@ +#include "cs_mex.h" +/* cs_ltsolve: solve an upper triangular system L'*x=b */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Lmatrix, *L ; + double *x, *b ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_ltsolve(L,b)") ; + } + L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; /* get L */ + b = cs_mex_get_double (L->n, pargin [1]) ; /* get b */ + x = cs_mex_put_double (L->n, b, &(pargout [0])) ; /* x = b */ + cs_ltsolve (L, x) ; /* x = L'\x */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu.m new file mode 100644 index 0000000..b4b5843 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu.m @@ -0,0 +1,29 @@ +function [L,U,p,q] = cs_lu (A,tol) %#ok +%CS_LU sparse LU factorization, with fill-reducing ordering. +% [L,U,p] = cs_lu(A) factorizes A(p,:) into L*U using no fill-reducing +% ordering. +% +% [L,U,p] = cs_lu(A,tol) factorizes A(p,:) into L*U using no fill-reducing +% ordering. Entries on the diagonal are given preference in partial pivoting. +% +% [L,U,p,q] = cs_lu(A) factorizes A(p,q) into L*U using a fill-reducing +% ordering q = cs_amd(A,2). Normal partial pivoting is used. +% +% [L,U,p,q] = cs_lu(A,tol) factorizes A(p,q) into L*U, using a fill-reducing +% ordering q = cs_amd(A,1). Entries on the diagonal are given preference in +% partial pivoting. With a pivot tolerance tol, the entries in L have +% magnitude 1/tol or less. tol = 1 is normal partial pivoting (with +% q = cs_amd(A)). tol = 0 ensures p = q. 0= tol * max(abs(A(:,k))). +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; [L,U,p,q] = cs_lu (A) ; +% cspy (A (p,q)) ; cspy (L+U) ; +% norm (L*U - A(p,q), 1) +% +% See also CS_AMD, LU, UMFPACK, AMD, COLAMD. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_lu mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu_mex.c new file mode 100644 index 0000000..294b29c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lu_mex.c @@ -0,0 +1,53 @@ +#include "cs_mex.h" +/* cs_lu: sparse LU factorization, with optional fill-reducing ordering */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + css *S ; + csn *N ; + cs Amatrix, *A, *D ; + int n, order, *p ; + double tol ; + if (nargout > 4 || nargin > 3 || nargin < 1) + { + mexErrMsgTxt ("Usage: [L,U,p,q] = cs_lu (A,tol)") ; + } + A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; /* get A */ + n = A->n ; + if (nargin == 2) /* determine tol and ordering */ + { + tol = mxGetScalar (pargin [1]) ; + order = (nargout == 4) ? 1 : 0 ; /* amd (A+A'), or natural */ + } + else + { + tol = 1 ; + order = (nargout == 4) ? 2 : 0 ; /* amd(S'*S) w/dense rows or I */ + } + S = cs_sqr (order, A, 0) ; /* symbolic ordering, no QR bound */ + N = cs_lu (A, S, tol) ; /* numeric factorization */ + if (!N) mexErrMsgTxt ("cs_lu failed (singular, or out of memory)") ; + cs_dropzeros (N->L) ; /* drop zeros from L and sort it */ + D = cs_transpose (N->L, 1) ; + cs_spfree (N->L) ; + N->L = cs_transpose (D, 1) ; + cs_spfree (D) ; + cs_dropzeros (N->U) ; /* drop zeros from U and sort it */ + D = cs_transpose (N->U, 1) ; + cs_spfree (N->U) ; + N->U = cs_transpose (D, 1) ; + cs_spfree (D) ; + p = cs_pinv (N->pinv, n) ; /* p=pinv' */ + pargout [0] = cs_mex_put_sparse (&(N->L)) ; /* return L */ + pargout [1] = cs_mex_put_sparse (&(N->U)) ; /* return U */ + pargout [2] = cs_mex_put_int (p, n, 1, 1) ; /* return p */ + /* return Q */ + if (nargout == 4) pargout [3] = cs_mex_put_int (S->q, n, 1, 0) ; + cs_nfree (N) ; + cs_sfree (S) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol.m new file mode 100644 index 0000000..0b6ecf4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol.m @@ -0,0 +1,23 @@ +function x = cs_lusol (A,b,order,tol) %#ok +%CS_LUSOL solve Ax=b using LU factorization. +% x = cs_lusol(A,b) computes x = A\b, where A is sparse and square, and b is a +% full vector. The ordering cs_amd(A,2) is used. +% +% x = cs_lusol(A,b,1) also computes x = A\b, but uses the cs_amd(A) ordering +% with diagonal preference (tol=0.001). +% +% x = cs_lusol(A,b,order,tol) allows both the ordering and tolerance to be +% defined. The ordering defaults to 1, and tol defaults to 1. +% ordering: 0: natural, 1: amd(A+A'), 2: amd(S'*S) where S=A except with no +% dense rows, 3: amd(A'*A). +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; n = size(A,1) ; +% b = rand (n,1) ; x = cs_lusol (A,b) ; norm (A*x-b) +% +% See also CS_LU, CS_AMD, CS_CHOLSOL, CS_QRSOL, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_lusol mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol_mex.c new file mode 100644 index 0000000..0c51bcd --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_lusol_mex.c @@ -0,0 +1,40 @@ +#include "cs_mex.h" +/* cs_lusol: solve A*x=b using a sparse LU factorization */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, Amatrix ; + int order ; + double *x, *b, tol ; + if (nargout > 1 || nargin < 2 || nargin > 4) + { + mexErrMsgTxt ("Usage: x = cs_lusol(A,b,order,tol)") ; + } + A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; /* get A */ + b = cs_mex_get_double (A->n, pargin [1]) ; /* get b */ + x = cs_mex_put_double (A->n, b, &(pargout [0])) ; /* x = b */ + order = (nargin < 3) ? 2 : mxGetScalar (pargin [2]) ; + order = CS_MAX (order, 0) ; + order = CS_MIN (order, 3) ; + if (nargin == 2) + { + tol = 1 ; /* normal partial pivoting */ + } + else if (nargin == 3) + { + tol = (order == 1) ? 0.001 : 1 ; /* tol = 0.001 for amd(A+A') */ + } + else + { + tol = mxGetScalar (pargin [3]) ; + } + if (!cs_lusol (order, A, x, tol)) /* x = A\x */ + { + mexErrMsgTxt ("LU factorization failed (singular or out of memory)") ; + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_make.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_make.m new file mode 100644 index 0000000..911d45b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_make.m @@ -0,0 +1,170 @@ +function [objfiles, timestamp_out] = cs_make (f) +%CS_MAKE compiles CSparse for use in MATLAB. +% Usage: +% cs_make +% [objfiles, timestamp] = cs_make (f) +% +% With no input arguments, or with f=0, only those files needing to be +% compiled are compiled (like the Unix/Linux/GNU "make" command, but not +% requiring "make"). If f is a nonzero number, all files are compiled. +% If f is a string, only that mexFunction is compiled. For example, +% cs_make ('cs_add') just compiles the cs_add mexFunction. This option is +% useful when developing a single new mexFunction. This function can only be +% used if the current directory is CSparse/MATLAB/CSparse. Returns a list of +% the object files in CSparse, and the latest modification time of any source +% codes. +% +% To add a new function and its MATLAB mexFunction to CSparse: +% +% (1) Create a source code file CSparse/Source/cs_mynewfunc.c. +% (2) Create a help file, CSparse/MATLAB/CSparse/cs_mynewfunc.m. +% This is very useful, but not strictly required. +% (3) Add the prototype of cs_mynewfunc to CSparse/Include/cs.h. +% (4) Create its MATLAB mexFunction, CSparse/MATLAB/cs_mynewfunc_mex.c. +% (5) Edit cs_make.m, and add 'cs_mynewfunc' to the 'cs' and 'csm' lists. +% (6) Type 'cs_make' in the CSparse/MATLAB/CSparse directory. +% If all goes well, your new function is ready for use in MATLAB. +% +% (7) Optionally add 'cs_mynewfunc' to CSparse/Source/Makefile +% and CSparse/MATLAB/CSparse/Makefile, if you want to use the +% Unix/Linux/GNU make command instead of cs_make.m. See where +% 'cs_add' and 'cs_add_mex' appear in those files, and add +% 'cs_mynewfunc' accordingly. +% (8) Optionally add 'cs_mynewfunc' to Tcov/Makefile, and add additional +% test code to cs_test.c, and add MATLAB test code to MATLAB/Test/*. +% +% Example: +% cs_make % compile everything +% cs_make ('cs_chol') ; % just compile cs_chol mexFunction +% +% See also MEX. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +fprintf ('Compiling CSparse\n') ; + +% CSparse source files, in ../../Source, such as ../../Source/cs_add.c. +% Note that not all CSparse source files have their own mexFunction. +cs = { 'cs_add', 'cs_amd', 'cs_chol', 'cs_cholsol', 'cs_counts', ... + 'cs_cumsum', 'cs_dfs', 'cs_dmperm', 'cs_droptol', 'cs_dropzeros', ... + 'cs_dupl', 'cs_entry', 'cs_etree', 'cs_fkeep', 'cs_gaxpy', 'cs_happly', ... + 'cs_house', 'cs_ipvec', 'cs_load', 'cs_lsolve', 'cs_ltsolve', 'cs_lu', ... + 'cs_lusol', 'cs_malloc', 'cs_maxtrans', 'cs_multiply', 'cs_norm', ... + 'cs_permute', 'cs_pinv', 'cs_post', 'cs_print', 'cs_pvec', 'cs_qr', ... + 'cs_qrsol', 'cs_scatter', 'cs_scc', 'cs_schol', 'cs_sqr', 'cs_symperm', ... + 'cs_tdfs', 'cs_transpose', 'cs_compress', 'cs_updown', 'cs_usolve', ... + 'cs_utsolve', 'cs_util', 'cs_reach', 'cs_spsolve', 'cs_ereach', ... + 'cs_leaf', 'cs_randperm' } ; + % add cs_mynewfunc to the above list + +details = 0 ; +kk = 0 ; +csm = { } ; +if (nargin == 0) + force = 0 ; +elseif (ischar (f)) + fprintf ('cs_make: compiling ../../Source files and %s_mex.c\n', f) ; + force = 0 ; + csm = {f} ; +else + force = f ; + details = details | (force > 1) ; %#ok + if (force & details) %#ok + fprintf ('cs_make: re-compiling everything\n') ; + end +end +if (force) + fprintf ('Compiling CSparse\n') ; +end + +if (isempty (csm)) + % mexFunctions, of the form cs_add_mex.c, etc, in this directory + csm = { 'cs_add', 'cs_amd', 'cs_chol', 'cs_cholsol', 'cs_counts', ... + 'cs_dmperm', 'cs_droptol', 'cs_etree', 'cs_gaxpy', 'cs_lsolve', ... + 'cs_ltsolve', 'cs_lu', 'cs_lusol', 'cs_multiply', 'cs_permute', ... + 'cs_print', 'cs_qr', 'cs_qrsol', 'cs_scc', 'cs_symperm', 'cs_thumb', ... + 'cs_transpose', 'cs_sparse', 'cs_updown', 'cs_usolve', ... + 'cs_utsolve', 'cs_randperm', 'cs_sqr' } ; + % add cs_mynewfunc to the above list +end + +try + % ispc does not appear in MATLAB 5.3 + pc = ispc ; +catch + % if ispc fails, assume we are on a Windows PC if it's not unix + pc = ~isunix ; +end + +if (pc) + obj = '.obj' ; +else + obj = '.o' ; +end + +srcdir = '../../Source/' ; +hfile = '../../Include/cs.h' ; + +% compile each CSparse source file +[anysrc timestamp kk] = compile_source ('', 'cs_mex', obj, hfile, force, ... + kk, details) ; +CS = ['cs_mex' obj] ; +if (nargout > 0) + objfiles = ['..' filesep 'CSparse' filesep 'cs_mex' obj] ; +end +for i = 1:length (cs) + [s t kk] = compile_source (srcdir, cs {i}, obj, hfile, force, kk, details) ; + timestamp = max (timestamp, t) ; + anysrc = anysrc | s ; %#ok + CS = [CS ' ' cs{i} obj] ; %#ok + if (nargout > 0) + objfiles = [objfiles ' ..' filesep 'CSparse' filesep cs{i} obj] ; %#ok + end +end + +% compile each CSparse mexFunction +obj = ['.' mexext] ; +for i = 1:length (csm) + [s t] = cs_must_compile ('', csm{i}, '_mex', obj, hfile, force) ; + timestamp = max (timestamp, t) ; + if (anysrc | s) %#ok + cmd = sprintf ('mex -O -I../../Include %s_mex.c %s -output %s', ... + csm{i}, CS, csm{i}) ; + kk = do_cmd (cmd, kk, details) ; + end +end + +fprintf ('\n') ; +if (nargout > 1) + timestamp_out = timestamp ; +end + +if (force) + fprintf ('CSparse successfully compiled.\n') ; +end + +%------------------------------------------------------------------------------- +function [s,t,kk] = compile_source (srcdir, f, obj, hfile, force, kk, details) +% compile a source code file in ../../Source, leaving object file in +% this directory. +[s t] = cs_must_compile (srcdir, f, '', obj, hfile, force) ; +if (s) + cmd = sprintf ('mex -O -c -I../../Include %s%s.c', srcdir, f) ; + kk = do_cmd (cmd, kk, details) ; +end + +%------------------------------------------------------------------------------- +function kk = do_cmd (s, kk, details) +%DO_CMD: evaluate a command, and either print it or print a "." +s = strrep (s, '/', filesep) ; +if (details) + fprintf ('%s\n', s) ; +else + if (mod (kk, 60) == 0) + fprintf ('\n') ; + end + kk = kk + 1 ; + fprintf ('.') ; +end +eval (s) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.c new file mode 100644 index 0000000..96b8ceb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.c @@ -0,0 +1,118 @@ +#include "cs_mex.h" +/* check MATLAB input argument */ +void cs_mex_check (int nel, int m, int n, int square, int sparse, int values, + const mxArray *A) +{ + int nnel, mm = mxGetM (A), nn = mxGetN (A) ; + if (values) + { + if (mxIsComplex (A)) + { + mexErrMsgTxt ("matrix must be real; try CXSparse instead") ; + } + } + if (sparse && !mxIsSparse (A)) mexErrMsgTxt ("matrix must be sparse") ; + if (!sparse) + { + if (mxIsSparse (A)) mexErrMsgTxt ("matrix must be full") ; + if (values && !mxIsDouble (A)) mexErrMsgTxt ("matrix must be double") ; + } + if (nel) + { + /* check number of elements */ + nnel = mxGetNumberOfElements (A) ; + if (m >= 0 && n >= 0 && m*n != nnel) mexErrMsgTxt ("wrong length") ; + } + else + { + /* check row and/or column dimensions */ + if (m >= 0 && m != mm) mexErrMsgTxt ("wrong dimension") ; + if (n >= 0 && n != nn) mexErrMsgTxt ("wrong dimension") ; + } + if (square && mm != nn) mexErrMsgTxt ("matrix must be square") ; +} + +/* get a MATLAB sparse matrix and convert to cs */ +cs *cs_mex_get_sparse (cs *A, int square, int values, const mxArray *Amatlab) +{ + cs_mex_check (0, -1, -1, square, 1, values, Amatlab) ; + A->m = mxGetM (Amatlab) ; + A->n = mxGetN (Amatlab) ; + A->p = mxGetJc (Amatlab) ; + A->i = mxGetIr (Amatlab) ; + A->x = values ? mxGetPr (Amatlab) : NULL ; + A->nzmax = mxGetNzmax (Amatlab) ; + A->nz = -1 ; /* denotes a compressed-col matrix, instead of triplet */ + return (A) ; +} + +/* return a sparse matrix to MATLAB */ +mxArray *cs_mex_put_sparse (cs **Ahandle) +{ + cs *A ; + mxArray *Amatlab ; + A = *Ahandle ; + Amatlab = mxCreateSparse (0, 0, 0, mxREAL) ; + mxSetM (Amatlab, A->m) ; + mxSetN (Amatlab, A->n) ; + mxSetNzmax (Amatlab, A->nzmax) ; + cs_free (mxGetJc (Amatlab)) ; + cs_free (mxGetIr (Amatlab)) ; + cs_free (mxGetPr (Amatlab)) ; + mxSetJc (Amatlab, A->p) ; /* assign A->p pointer to MATLAB A */ + mxSetIr (Amatlab, A->i) ; + mxSetPr (Amatlab, A->x) ; + mexMakeMemoryPersistent (A->p) ; /* ensure MATLAB does not free A->p */ + mexMakeMemoryPersistent (A->i) ; + mexMakeMemoryPersistent (A->x) ; + cs_free (A) ; /* frees A struct only, not A->p, etc */ + *Ahandle = NULL ; + return (Amatlab) ; +} + +/* get a MATLAB dense column vector */ +double *cs_mex_get_double (int n, const mxArray *X) +{ + cs_mex_check (0, n, 1, 0, 0, 1, X) ; + return (mxGetPr (X)) ; +} + +/* return a double vector to MATLAB */ +double *cs_mex_put_double (int n, const double *b, mxArray **X) +{ + double *x ; + int k ; + *X = mxCreateDoubleMatrix (n, 1, mxREAL) ; /* create x */ + x = mxGetPr (*X) ; + for (k = 0 ; k < n ; k++) x [k] = b [k] ; /* copy x = b */ + return (x) ; +} + +/* get a MATLAB flint array and convert to int */ +int *cs_mex_get_int (int n, const mxArray *Imatlab, int *imax, int lo) +{ + double *p ; + int i, k, *C = cs_malloc (n, sizeof (int)) ; + cs_mex_check (1, n, 1, 0, 0, 1, Imatlab) ; + p = mxGetPr (Imatlab) ; + *imax = 0 ; + for (k = 0 ; k < n ; k++) + { + i = p [k] ; + C [k] = i - 1 ; + if (i < lo) mexErrMsgTxt ("index out of bounds") ; + *imax = CS_MAX (*imax, i) ; + } + return (C) ; +} + +/* return an int array to MATLAB as a flint row vector */ +mxArray *cs_mex_put_int (int *p, int n, int offset, int do_free) +{ + mxArray *X = mxCreateDoubleMatrix (1, n, mxREAL) ; + double *x = mxGetPr (X) ; + int k ; + for (k = 0 ; k < n ; k++) x [k] = (p ? p [k] : k) + offset ; + if (do_free) cs_free (p) ; + return (X) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.h b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.h new file mode 100644 index 0000000..e238bdc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_mex.h @@ -0,0 +1,10 @@ +#include "cs.h" +#include "mex.h" +cs *cs_mex_get_sparse (cs *A, int square, int values, const mxArray *Amatlab) ; +mxArray *cs_mex_put_sparse (cs **A) ; +void cs_mex_check (int nel, int m, int n, int square, int sparse, int values, + const mxArray *A) ; +int *cs_mex_get_int (int n, const mxArray *Imatlab, int *imax, int lo) ; +mxArray *cs_mex_put_int (int *p, int n, int offset, int do_free) ; +double *cs_mex_get_double (int n, const mxArray *X) ; +double *cs_mex_put_double (int n, const double *b, mxArray **X) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply.m new file mode 100644 index 0000000..da4de07 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply.m @@ -0,0 +1,16 @@ +function C = cs_multiply (A,B) %#ok +%CS_MULTIPLY sparse matrix multiply. +% C = cs_multiply(A,B) computes C = A*B. +% +% Example: +% Prob1 = UFget ('HB/ibm32') ; A = Prob1.A ; +% Prob2 = UFget ('Hamrle/Hamrle1') ; B = Prob2.A ; +% C = cs_multiply (A,B) ; +% D = A*B ; % same as C +% +% See also CS_GAXPY, CS_ADD, MTIMES. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_mult mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply_mex.c new file mode 100644 index 0000000..48eab3d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_multiply_mex.c @@ -0,0 +1,25 @@ +#include "cs_mex.h" +/* cs_multiply: sparse matrix multiply */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, Bmatrix, *A, *B, *C, *D ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: C = cs_multiply(A,B)") ; + } + A = cs_transpose (cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]), 1) ; + B = cs_transpose (cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]), 1) ; + D = cs_multiply (B,A) ; /* D = B'*A' */ + cs_spfree (A) ; + cs_spfree (B) ; + cs_dropzeros (D) ; /* drop zeros from D */ + C = cs_transpose (D, 1) ; /* C = D', so that C is sorted */ + cs_spfree (D) ; + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_must_compile.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_must_compile.m new file mode 100644 index 0000000..7b56fe1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_must_compile.m @@ -0,0 +1,23 @@ +function [s, t, tobj] = cs_must_compile (srcdir, f, suffix, obj, hfile, force) +%CS_MUST_COMPILE return 1 if source code f must be compiled, 0 otherwise +% Used by cs_make, and MATLAB/Test/cs_test_make.m. +% +% Example: +% none, not meant for end users. +% See also: CS_MAKE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +dobj = dir ([f obj]) ; +if (force | isempty (dobj)) %#ok + s = 1 ; + t = Inf ; + tobj = -1 ; + return +end +dsrc = dir ([srcdir f suffix '.c']) ; +dh = dir (hfile) ; +t = max (datenum (dsrc.date), datenum (dh.date)) ; +tobj = datenum (dobj.date) ; +s = (tobj < t) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nd.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nd.m new file mode 100644 index 0000000..7171c11 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nd.m @@ -0,0 +1,27 @@ +function p = cs_nd (A) +%CS_ND generalized nested dissection ordering. +% p = cs_nd(A) computes the nested dissection ordering of a matrix. Small +% submatrices (order 500 or less) are ordered via cs_amd. A must be sparse +% and symmetric (use p = cs_nd(A|A') if it is not symmetric). +% +% Example: +% A = delsq (numgrid ('L', 300)) ; % matrix used in 'bench' +% p = cs_nd (A) ; +% cspy (A (p,p)) ; +% +% See also CS_AMD, CS_SEP, CS_ESEP, CS_NSEP, AMD. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +if (n == 1) + p = 1 ; +elseif (n < 500) + p = cs_amd (A) ; % use cs_amd on small graphs +else + [s a b] = cs_nsep (A) ; % find a node separator + a = a (cs_nd (A (a,a))) ; % order A(a,a) recursively + b = b (cs_nd (A (b,b))) ; % order A(b,b) recursively + p = [a b s] ; % concatenate to obtain the final ordering +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nsep.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nsep.m new file mode 100644 index 0000000..b7a22fc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_nsep.m @@ -0,0 +1,18 @@ +function [s,a,b] = cs_nsep (A) +%CS_NSEP find a node separator of a symmetric matrix A. +% [s,a,b] = cs_nsep(A) finds a node separator s that splits the graph of A +% into two parts a and b of roughly equal size. If A is unsymmetric, use +% cs_nsep(A|A'). The permutation p = [a b s] is a one-level dissection of A. +% +% Example: +% A = delsq (numgrid ('L', 10)) ; % smaller version as used in 'bench' +% [s a b] = cs_nsep (A) ; p = [a b s] ; +% cspy (A (p,p)) ; +% +% See also CS_SEP, CS_ESEP, CS_ND. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[a b] = cs_esep (A) ; +[s a b] = cs_sep (A, a, b) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute.m new file mode 100644 index 0000000..550876d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute.m @@ -0,0 +1,15 @@ +function C = cs_permute (A,p,q) %#ok +%CS_PERMUTE permute a sparse matrix. +% C = cs_permute(A,p,q) computes C = A(p,q) +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; [m n] = size (A) ; +% p = randperm (m) ; q = randperm (n) ; +% C = cs_permute (A,p,q) ; % C = A(p,q) +% +% See also CS_SYMPERM, SUBSREF. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_permute mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute_mex.c new file mode 100644 index 0000000..5306fd2 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_permute_mex.c @@ -0,0 +1,30 @@ +#include "cs_mex.h" +/* cs_permute: permute a sparse matrix */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A, *C, *D ; + int ignore, *P, *Q, *Pinv ; + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: C = cs_permute(A,p,q)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + P = cs_mex_get_int (A->m, pargin [1], &ignore, 1) ; /* get P */ + Q = cs_mex_get_int (A->n, pargin [2], &ignore, 1) ; /* get Q */ + Pinv = cs_pinv (P, A->m) ; /* P = Pinv' */ + C = cs_permute (A, Pinv, Q, 1) ; /* C = A(p,q) */ + D = cs_transpose (C, 1) ; /* sort C via double transpose */ + cs_spfree (C) ; + C = cs_transpose (D, 1) ; + cs_spfree (D) ; + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ + cs_free (Pinv) ; + cs_free (P) ; + cs_free (Q) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print.m new file mode 100644 index 0000000..5d85afc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print.m @@ -0,0 +1,14 @@ +function cs_print (A,brief) %#ok +%CS_PRINT print the contents of a sparse matrix. +% cs_print(A) prints a sparse matrix. cs_print(A,1) prints just a few entries. +% +% Example: +% Prob = UFget ('vanHeukelum/cage3') ; A = Prob.A +% cs_print (A) ; +% +% See also: DISPLAY. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_print mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print_mex.c new file mode 100644 index 0000000..1c6deca --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_print_mex.c @@ -0,0 +1,20 @@ +#include "cs_mex.h" +/* cs_print: print the contents of a sparse matrix. */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + int brief ; + if (nargout > 0 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: cs_print(A,brief)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + brief = (nargin < 2) ? 0 : mxGetScalar (pargin [1]) ; /* get brief */ + cs_print (A, brief) ; /* print A */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qleft.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qleft.m new file mode 100644 index 0000000..45107af --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qleft.m @@ -0,0 +1,36 @@ +function X = cs_qleft (V, Beta, p, Y) +%CS_QLEFT apply Householder vectors on the left. +% X = cs_qleft(V,Beta,p,Y) computes X = Hn*...*H2*H1*P*Y = Q'*Y where Q is +% represented by the Householder vectors V, coefficients Beta, and +% permutation p. p can be [], which denotes the identity permutation. +% +% Example: +% Prob = UFget ('HB/well1033') ; A = Prob.A ; [m n] = size (A) ; +% b = rand (m,1) ; +% [V,beta,p,R] = cs_qr (A) ; % QR factorization of A(p,:) +% b1 = cs_qleft (V, beta, p, b) ; +% x1 = R (1:n,1:n) \ b1 (1:n) ; +% x2 = A\b ; +% norm (x1-x2) +% +% See also CS_QR, CS_QRIGHT. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m2 n] = size (V) ; +[m ny] = size (Y) ; +X = Y ; +if (m2 > m) + if (issparse (Y)) + X = [X ; sparse(m2-m,ny)] ; + else + X = [X ; zeros(m2-m,ny)] ; + end +end +if (~isempty (p)) + X = X (p,:) ; +end +for k = 1:n + X = X - V (:,k) * (Beta (k) * (V (:,k)' * X)) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr.m new file mode 100644 index 0000000..d723f55 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr.m @@ -0,0 +1,33 @@ +function [V,beta,p,R,q] = cs_qr (A) %#ok +%CS_QR sparse QR factorization (Householder-based). +% [V,beta,p,R] = cs_qr(A) computes the QR factorization of A(p,:). +% [V,beta,p,R,q] = cs_qr(A) computes the QR factorization of A(p,q). +% The V, beta, and p terms represent the Householder vectors and coefficients. +% The fill-reducing ordering q is found via q = cs_amd(A,3). +% The orthogonal factor Q can be obtained via +% Q = cs_qright(V,beta,p,speye(size(V,1))), in which case Q*R=A(:,q) is the +% resulting factorization (the permutation p is folded into Q). A must be +% m-by-n with m >= n. If A is structurally rank deficient, additional empty +% rows may have been added to V and R. Note that V is typically much sparser +% than Q. +% +% Example: +% +% Prob = UFget ('HB/well1033') ; A = Prob.A ; [m n] = size (A) ; +% b = rand (m,1) ; +% [V,beta,p,R,q] = cs_qr (A) ; % QR factorization of A(p,q) +% b1 = cs_qleft (V, beta, p, b) ; +% x1 = R (1:n,1:n) \ b1 (1:n) ; +% x1 (q) = x1 ; +% x2 = A\b ; +% norm (x1-x2) +% Q = cs_qright(V,beta,p,speye(size(V,1))) ; % Note: p accounted for in Q +% norm (Q*R-A(:,q),1) +% fprintf ('nnz(R) %d, nnz(V) %d, nnz(Q) %d\n', nnz(R), nnz(V), nnz(Q)) ; +% +% See also CS_AMD, CS_QRIGHT, CS_QR, CS_DMPERM, QR, COLAMD. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_qr mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr_mex.c new file mode 100644 index 0000000..c2d8c0b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qr_mex.c @@ -0,0 +1,46 @@ +#include "cs_mex.h" +/* cs_qr: sparse QR factorization */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + css *S ; + csn *N ; + cs Amatrix, *A, *D ; + int m, n, order, *p ; + if (nargout > 5 || nargin != 1) + { + mexErrMsgTxt ("Usage: [V,beta,p,R,q] = cs_qr(A)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + m = A->m ; + n = A->n ; + if (m < n) mexErrMsgTxt ("A must have # rows >= # columns") ; + order = (nargout == 5) ? 3 : 0 ; /* determine ordering */ + S = cs_sqr (order, A, 1) ; /* symbolic QR ordering & analysis*/ + N = cs_qr (A, S) ; /* numeric QR factorization */ + if (!N) mexErrMsgTxt ("qr failed") ; + cs_dropzeros (N->L) ; /* drop zeros from V and sort */ + D = cs_transpose (N->L, 1) ; + cs_spfree (N->L) ; + N->L = cs_transpose (D, 1) ; + cs_spfree (D) ; + cs_dropzeros (N->U) ; /* drop zeros from R and sort */ + D = cs_transpose (N->U, 1) ; + cs_spfree (N->U) ; + N->U = cs_transpose (D, 1) ; + cs_spfree (D) ; + m = N->L->m ; /* m may be larger now */ + p = cs_pinv (S->pinv, m) ; /* p = pinv' */ + pargout [0] = cs_mex_put_sparse (&(N->L)) ; /* return V */ + cs_mex_put_double (n, N->B, &(pargout [1])) ; /* return beta */ + pargout [2] = cs_mex_put_int (p, m, 1, 1) ; /* return p */ + pargout [3] = cs_mex_put_sparse (&(N->U)) ; /* return R */ + pargout [4] = cs_mex_put_int (S->q, n, 1, 0) ; /* return q */ + cs_nfree (N) ; + cs_sfree (S) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qright.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qright.m new file mode 100644 index 0000000..951c60a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qright.m @@ -0,0 +1,26 @@ +function X = cs_qright (V, Beta, p, Y) +%CS_QRIGHT apply Householder vectors on the right. +% X = cs_qright(V,Beta,p,Y) computes X = Y*P'*H1*H2*...*Hn = Y*Q where Q is +% represented by the Householder vectors V, coefficients Beta, and +% permutation p. p can be [], which denotes the identity permutation. +% To obtain Q itself, use Q = cs_qright(V,Beta,p,speye(size(V,1))). +% +% Example: +% load west0479 ; q = colamd (west0479) ; A = west0479 (:,q) ; +% [Q,R] = qr (A) ; norm (Q*R-A, 1) +% [V,beta,p,R2] = cs_qr (A) ; +% Q2 = cs_qright (V, beta, p, speye(size(V,1))) ; norm (Q2*R2-A, 1) +% +% See also CS_QR, CS_QLEFT. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (V) ; +X = Y ; +if (~isempty (p)) + X = X (:,p) ; +end +for k = 1:n + X = X - (X * (Beta (k) * V (:,k))) * V (:,k)' ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol.m new file mode 100644 index 0000000..1380b5e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol.m @@ -0,0 +1,23 @@ +function x = cs_qrsol (A,b,order) %#ok +%CS_QRSOL solve a sparse least-squares problem. +% x = cs_qrsol(A,b) solves the over-determined least squares problem to +% find x that minimizes norm(A*x-b), where b is a full vector and +% A is m-by-n with m >= n. If m < n, it solves the underdetermined system +% Ax=b. A 3rd input argument specifies the ordering method to use +% (0: natural, 3: amd(A'*A)). The default ordering is 3. +% +% Example: +% Prob = UFget ('HB/well1033') ; A = Prob.A ; [m n] = size (A) ; +% b = rand (m,1) ; +% x1 = cs_qrsol (A,b) ; +% x2 = A\b ; +% norm (x1-x2) +% +% For this example, cs_qrsol is about 3 times faster than A\b in MATLAB 7.3. +% +% See also CS_QR, CS_AMD, CS_LUSOL, CS_CHOLSOL, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_qrsol mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol_mex.c new file mode 100644 index 0000000..d028cf5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_qrsol_mex.c @@ -0,0 +1,31 @@ +#include "cs_mex.h" +/* cs_qrsol: solve least squares or underdetermined problem */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, Amatrix ; + double *x, *b ; + int k, order ; + if (nargout > 1 || nargin < 2 || nargin > 3) + { + mexErrMsgTxt ("Usage: x = cs_qrsol(A,b,order)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + b = cs_mex_get_double (A->m, pargin [1]) ; /* get b */ + x = cs_calloc (CS_MAX (A->m, A->n), sizeof (double)) ; /* x = b */ + for (k = 0 ; k < A->m ; k++) x [k] = b [k] ; + order = (nargin < 3) ? 3 : mxGetScalar (pargin [2]) ; + order = CS_MAX (order, 0) ; + order = CS_MIN (order, 3) ; + if (!cs_qrsol (order, A, x)) /* x = A\x */ + { + mexErrMsgTxt ("QR solve failed") ; + } + cs_mex_put_double (A->n, x, &(pargout [0])) ; /* return x */ + cs_free (x) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm.m new file mode 100644 index 0000000..74cc7cc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm.m @@ -0,0 +1,18 @@ +function p = cs_randperm (n, seed) %#ok +%CS_RANDPERM random permutation. +% p = cs_randperm (n) returns a repeatable random permutation of 1:n. +% p = cs_randperm (n,seed) returns the random permutation using the given +% seed for the random number generator (try cs_randperm (n,rand)), where +% seed is not 0 or -1. Two special cases are not random permutations at all: +% p=cs_randperm (n,0) is 1:n, and p=cs_randperm (n,-1) is n:-1:1. +% This function does not change RAND's state. +% +% Example: +% p = cs_randperm (10) +% +% See also CS_DMPERM, RAND, RANDPERM + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_randperm mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm_mex.c new file mode 100644 index 0000000..acbcedb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_randperm_mex.c @@ -0,0 +1,28 @@ +#include "cs_mex.h" +/* cs_randperm: random permutation. p=cs_randperm(n,0) is 1:n, + * p=cs_randperm(n,-1) is n:-1:1. p = cs_randperm (n,seed) is a random + * permutation using the given seed (where seed is not 0 or -1). + * seed defaults to 1. A single seed always gives a repeatable permutation. + * Use p = cs_randperm(n,rand) to get a permutation that varies with each use. + */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double seed ; + int iseed, n, *p ; + if (nargout > 1 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: p = cs_randperm(n,seed)") ; + } + seed = (nargin > 1) ? mxGetScalar (pargin [1]) : 1 ; + iseed = (seed > 0 && seed < 1) ? (seed * RAND_MAX) : seed ; + n = mxGetScalar (pargin [0]) ; + n = CS_MAX (n, 0) ; + p = cs_randperm (n, iseed) ; + pargout [0] = cs_mex_put_int (p, n, 1, 1) ; /* return p */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc.m new file mode 100644 index 0000000..8d71366 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc.m @@ -0,0 +1,17 @@ +function [p,r] = cs_scc (A) %#ok +%CS_SCC strongly-connected components of a square sparse matrix. +% [p,r] = cs_scc(A) finds a permutation p so that A(p,p) is permuted into +% block upper triangular form. The diagonal of A is ignored. The kth block +% is given by A (s,s) where s = r(k):r(k+1)-1. A must be square. +% For bipartite or rectangular graphs, use cs_scc2. +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; [p r] = cs_scc (A) ; +% cspy (A (p,p)) ; +% +% See also CS_DMPERM, DMPERM, CS_SCC2. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_scc mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc2.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc2.m new file mode 100644 index 0000000..c73ef23 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc2.m @@ -0,0 +1,61 @@ +function [p, q, r, s] = cs_scc2 (A, bipartite) +%CS_SCC2 cs_scc, or connected components of a bipartite graph. +% [p,q,r,s] = cs_scc2(A) finds a permutation p so that A(p,q) is permuted into +% block upper triangular form (if A is square). In this case, r=s, p=q and +% the kth diagonal block is given by A (t,t) where t = r(k):r(k)+1. +% The diagonal of A is ignored. Each block is one strongly connected +% component of A. +% +% If A is not square (or for [p,q,r,s] = cs_scc2(A,1)), then the connected +% components of the bipartite graph of A are found. A(p,q) is permuted into +% block diagonal form, where the diagonal blocks are rectangular. The kth +% block is given by A(r(k):r(k+1)-1,s(k):s(k+1)-1). A can be rectangular. +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; [p q r s] = cs_scc2 (A) ; +% cspy (A (p,q)) ; +% Prob = UFget ('HB/wm1') ; A = Prob.A ; [p q r s] = cs_scc2 (A) ; +% cspy (A (p,q)) ; +% +% See also CS_DMPERM, DMPERM, CS_SCC, CCSPY. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +if (nargin < 2) + bipartite = 0 ; +end + +if (m ~= n | bipartite) %#ok + + % find the connected components of [I A ; A' 0] + S = spaugment (A) ; + [psym,rsym] = cs_scc (S) ; + p = psym (find (psym <= m)) ; %#ok + q = psym (find (psym > m)) - m ; %#ok + nb = length (rsym) - 1 ; + r = zeros (1,nb+1) ; + s = zeros (1,nb+1) ; + krow = 1 ; + kcol = 1 ; + for k = 1:nb + % find the rows and columns in the kth component + r (k) = krow ; + s (k) = kcol ; + ksym = psym (rsym (k):rsym (k+1)-1) ; + krow = krow + length (find (ksym <= m)) ; + kcol = kcol + length (find (ksym > m)) ; + end + r (nb+1) = m+1 ; + s (nb+1) = n+1 ; + +else + + % find the strongly connected components of A + [p,r] = cs_scc (A) ; + q = p ; + s = r ; + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc_mex.c new file mode 100644 index 0000000..3dc8540 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_scc_mex.c @@ -0,0 +1,32 @@ +#include "cs_mex.h" +/* [p,r] = cs_scc (A) finds the strongly connected components of A */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + csd *D ; + int n, j, *Ap2 ; + if (nargout > 2 || nargin != 1) + { + mexErrMsgTxt ("Usage: [p,r] = cs_scc(A)") ; + } + A = cs_mex_get_sparse (&Amatrix, 1, 0, pargin [0]) ; /* get A */ + /* cs_scc modifies A->p and then restores it (in cs_dfs). Avoid the issue + * of a mexFunction modifying its input (even temporarily) by making a copy + * of A->p. This issue does not arise in cs_dmperm, because that function + * applies cs_scc to a submatrix C, not to A directly. */ + n = A->n ; + Ap2 = cs_malloc (n+1, sizeof (int)) ; + for (j = 0 ; j <= n ; j++) Ap2 [j] = A->p [j] ; + A->p = Ap2 ; + D = cs_scc (A) ; /* find conn. comp. */ + pargout [0] = cs_mex_put_int (D->p, n, 1, 0) ; /* return p */ + pargout [1] = cs_mex_put_int (D->r, D->nb+1, 1, 0) ; /* return r */ + cs_dfree (D) ; + cs_free (Ap2) ; /* free the copy of A->p */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sep.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sep.m new file mode 100644 index 0000000..2c43607 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sep.m @@ -0,0 +1,21 @@ +function [s,as,bs] = cs_sep (A,a,b) +%CS_SEP convert an edge separator into a node separator. +% [s,as,bs] = cs_sep (A,a,b) converts an edge separator into a node separator. +% [a b] is a partition of 1:n, thus the edges in A(a,b) are an edge separator +% of A. s is the node separator, consisting of a node cover of the edges of +% A(a,b). as and bs are the sets a and b with s removed. +% +% Example: +% type cs_nsep ; % to see a simple example of use in cs_nsep.m +% +% See also CS_DMPERM, CS_NSEP, CS_ESEP, CS_ND. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[p q r s cc rr] = cs_dmperm (A (a,b)) ; +s = [(a (p (1:rr(2)-1))) (b (q (cc(3):(cc(5)-1))))] ; +w = ones (1, size (A,1)) ; +w (s) = 0 ; +as = a (find (w (a))) ; %#ok +bs = b (find (w (b))) ; %#ok diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse.m new file mode 100644 index 0000000..58835a0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse.m @@ -0,0 +1,17 @@ +function A = cs_sparse (i,j,x) %#ok +%CS_SPARSE convert a triplet form into a sparse matrix. +% A = cs_sparse(i,j,x) is identical to A = sparse(i,j,x), except that x must +% be real, and the length of i, j, and x must be the same. +% +% Example: +% Prob = UFget ('HB/arc130') ; S = Prob.A ; +% [i j x] = find (S) ; +% A = cs_sparse (i,j,x) ; +% S-A +% +% See also FIND, SPARSE, SPCONVERT. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_sparse mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse_mex.c new file mode 100644 index 0000000..4e637cb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sparse_mex.c @@ -0,0 +1,31 @@ +#include "cs_mex.h" +/* cs_sparse: convert triplet form into compress-column form sparse matrix */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, *C, *T, Tmatrix ; + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: A = cs_sparse(i,j,x)") ; + } + T = &Tmatrix ; /* get i,j,x and copy to triplet form */ + T->nz = mxGetNumberOfElements (pargin [0]) ; + T->p = cs_mex_get_int (T->nz, pargin [0], &(T->n), 1) ; + T->i = cs_mex_get_int (T->nz, pargin [1], &(T->m), 1) ; + cs_mex_check (1, T->nz, 1, 0, 0, 1, pargin [2]) ; + T->x = mxGetPr (pargin [2]) ; + T->nzmax = T->nz ; + C = cs_compress (T) ; /* create sparse matrix C */ + cs_dupl (C) ; /* remove duplicates from C */ + cs_dropzeros (C) ; /* remove zeros from C */ + A = cs_transpose (C, 1) ; /* A=C' */ + cs_spfree (C) ; + pargout [0] = cs_mex_put_sparse (&A) ; /* return A */ + cs_free (T->p) ; + cs_free (T->i) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr.m new file mode 100644 index 0000000..1c1a949 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr.m @@ -0,0 +1,25 @@ +function [vnz,rnz,parent,c,leftmost,p,q] = cs_sqr (A) %#ok +%CS_SQR symbolic sparse QR factorization. +% [vnz,rnz,parent,c,leftmost,p] = cs_sqr(A): symbolic QR of A(p,:). +% [vnz,rnz,parent,c,leftmost,p,q] = cs_sqr(A) computes the symbolic QR +% factorization of A(p,q). The fill-reducing ordering q is found via +% q = cs_amd(A,3). +% +% vnz is the number of entries in the matrix of Householder vectors, V. +% rnz is the number of entries in R. parent is elimination tree. +% c(i) is the number of entries in R(i,:). leftmost(i) = min(find(A(i,q))). +% p is the row permutation used to ensure R has a symbolically zero-free +% diagonal (it can be larger than m if A is structurally rank deficient). +% q is the fill-reducing ordering, if requested. +% +% Example: +% Prob = UFget ('HB/ibm32') ; A = Prob.A ; +% [vnz, rnz, parent, c, leftmost, p, q] = cs_sqr (A) ; +% cspy (A (p,q)) ; +% +% See also CS_AMD, CS_QR. +% +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_sqr mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr_mex.c new file mode 100644 index 0000000..8f56d18 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_sqr_mex.c @@ -0,0 +1,40 @@ +#include "cs_mex.h" +/* cs_sqr: symbolic sparse QR factorization */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double s ; + css *S ; + cs Amatrix, *A ; + int m, n, order, *p ; + if (nargout > 7 || nargin != 1) + { + mexErrMsgTxt ("Usage: [vnz,rnz,parent,c,leftmost,p,q] = cs_sqr(A)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + m = A->m ; + n = A->n ; + if (m < n) mexErrMsgTxt ("A must have # rows >= # columns") ; + order = (nargout == 7) ? 3 : 0 ; /* determine ordering */ + S = cs_sqr (order, A, 1) ; /* symbolic QR ordering & analysis*/ + if (!S) mexErrMsgTxt ("cs_sqr failed") ; + s = S->lnz ; + cs_mex_put_double (1, &s, &(pargout [0])) ; /* return nnz(V) */ + s = S->unz ; + cs_mex_put_double (1, &s, &(pargout [1])) ; /* return nnz(R) */ + pargout [2] = cs_mex_put_int (S->parent, n, 1, 0) ; /* return parent */ + pargout [3] = cs_mex_put_int (S->cp, n, 0, 0) ; /* return c */ + pargout [4] = cs_mex_put_int (S->leftmost, m, 1, 0) ; /* return leftmost*/ + p = cs_pinv (S->pinv, S->m2) ; /* p = pinv' */ + pargout [5] = cs_mex_put_int (p, S->m2, 1, 1) ; /* return p */ + if (nargout > 6) + { + pargout [6] = cs_mex_put_int (S->q, n, 1, 0) ; /* return q */ + } + cs_sfree (S) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm.m new file mode 100644 index 0000000..9356944 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm.m @@ -0,0 +1,20 @@ +function C = cs_symperm (A,p) %#ok +%CS_SYMPERM symmetric permutation of a symmetric matrix. +% C = cs_symperm(A,p) computes C = A(p,p), but accesses only the +% upper triangular part of A, and returns C upper triangular (A and C are +% symmetric with just their upper triangular parts stored). A must be square. +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; +% p = cs_amd (A) ; +% C = cs_symperm (A, p) ; +% cspy (A (p,p)) ; +% cspy (C) ; +% C - triu (A (p,p)) +% +% See also CS_PERMUTE, SUBSREF, TRIU. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_symperm mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm_mex.c new file mode 100644 index 0000000..0dd21de --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_symperm_mex.c @@ -0,0 +1,29 @@ +#include "cs_mex.h" +/* cs_symperm: symmetric permutation of a symmetric sparse matrix. */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A, *C, *D ; + int ignore, n, *P, *Pinv ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: C = cs_symperm(A,p)") ; + } + A = cs_mex_get_sparse (&Amatrix, 1, 1, pargin [0]) ; + n = A->n ; + P = cs_mex_get_int (n, pargin [1], &ignore, 1) ; /* get P */ + Pinv = cs_pinv (P, n) ; /* P=Pinv' */ + C = cs_symperm (A, Pinv, 1) ; /* C = A(p,p) */ + D = cs_transpose (C, 1) ; /* sort C */ + cs_spfree (C) ; + C = cs_transpose (D, 1) ; + cs_spfree (D) ; + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ + cs_free (P) ; + cs_free (Pinv) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_thumb_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_thumb_mex.c new file mode 100644 index 0000000..135b6fb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_thumb_mex.c @@ -0,0 +1,56 @@ +#include "cs_mex.h" +/* cs_thumb: convert a sparse matrix to a dense 2D thumbnail matrix of size + * at most k-by-k. k defaults to 256. A helper mexFunction for cspy. */ + +#define INDEX(i,j,lda) ((i)+(j)*(lda)) +#define ISNAN(x) ((x) != (x)) +#ifdef DBL_MAX +#define BIG_VALUE DBL_MAX +#else +#define BIG_VALUE 1.7e308 +#endif + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A ; + int m, n, mn, m2, n2, k, s, j, ij, sj, si, p, *Ap, *Ai ; + double aij, *S, *Ax ; + if (nargout > 1 || nargin < 1 || nargin > 2) + { + mexErrMsgTxt ("Usage: S = cs_thumb(A,k)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + m = A->m ; + n = A->n ; + mn = CS_MAX (m,n) ; + k = (nargin == 1) ? 256 : mxGetScalar (pargin [1]) ; /* get k */ + /* s = size of each submatrix; A(1:s,1:s) maps to S(1,1) */ + s = (mn < k) ? 1 : (int) ceil ((double) mn / (double) k) ; + m2 = (int) ceil ((double) m / (double) s) ; + n2 = (int) ceil ((double) n / (double) s) ; + /* create S */ + pargout [0] = mxCreateDoubleMatrix (m2, n2, mxREAL) ; + S = mxGetPr (pargout [0]) ; + Ap = A->p ; + Ai = A->i ; + Ax = A->x ; + for (j = 0 ; j < n ; j++) + { + sj = j/s ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + si = Ai [p] / s ; + ij = INDEX (si,sj,m2) ; + aij = fabs (Ax [p]) ; + if (ISNAN (aij)) aij = BIG_VALUE ; + aij = CS_MIN (BIG_VALUE, aij) ; + S [ij] = CS_MAX (S [ij], aij) ; + } + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose.m new file mode 100644 index 0000000..5aee7bf --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose.m @@ -0,0 +1,17 @@ +function C = cs_transpose (A) %#ok +%CS_TRANSPOSE transpose a real sparse matrix. +% C = cs_transpose(A), computes C = A' where A must be sparse and real. +% +% Example: +% Prob = UFget ('HB/ibm32') ; A = Prob.A ; +% C = cs_transpose (A) ; +% C-A' +% +% See also TRANSPOSE, CTRANSPOSE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_transpose mexFunction not found') ; + + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose_mex.c new file mode 100644 index 0000000..7ed3411 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_transpose_mex.c @@ -0,0 +1,19 @@ +#include "cs_mex.h" +/* C = cs_transpose (A), computes C=A', where A must be sparse and real */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Amatrix, *A, *C ; + if (nargout > 1 || nargin != 1) + { + mexErrMsgTxt ("Usage: C = cs_transpose(A)") ; + } + A = cs_mex_get_sparse (&Amatrix, 0, 1, pargin [0]) ; /* get A */ + C = cs_transpose (A, 1) ; /* C = A' */ + pargout [0] = cs_mex_put_sparse (&C) ; /* return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown.m new file mode 100644 index 0000000..4477e59 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown.m @@ -0,0 +1,26 @@ +function L = cs_updown (L, c, parent, sigma) %#ok +%CS_UPDOWN rank-1 update/downdate of a sparse Cholesky factorization. +% L = cs_updown(L,c,parent) computes the rank-1 update L = chol(L*L'+c*c')', +% where parent is the elimination tree of L. c must be a sparse column +% vector, and find(c) must be a subset of find(L(:,k)) where k = min(find(c)). +% L = cs_updown(L,c,parent,'-') is the downdate L = chol(L*L'-c*c'). +% L = cs_updown(L,c,parent,'+') is the update L = chol(L*L'+c*c'). +% Updating/downdating is much faster than refactorizing the matrix with +% cs_chol or chol. L must not have an entries dropped due to numerical +% cancellation (use cs_chol(A,0)). +% +% Example: +% Prob = UFget ('HB/bcsstk01') ; A = Prob.A ; n = size (A,1) ; +% L = cs_chol (A,0) ; +% parent = cs_etree (A) ; +% c = sprand (L (:, floor(n/2))) ; +% L1 = cs_updown (L, c, parent) ; +% L2 = cs_chol (A + c*c', 0) ; +% norm (L1-L2, 1) +% +% See also CS_ETREE, CS_CHOL, ETREE, CHOLUPDATE, CHOL. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_updown mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown_mex.c new file mode 100644 index 0000000..ff6c1d7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_updown_mex.c @@ -0,0 +1,53 @@ +#include "cs_mex.h" +/* cs_updown: sparse Cholesky update/downdate (rank-1 or multiple rank) */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Lmatrix, *Lin, Cmatrix, *C, *L, Cvector, *Cvec ; + int ignore, j, k, n, lnz, *parent, sigma = 1, cp [2] ; + char sigma_string [20] ; + + if (nargout > 1 || nargin < 3 || nargin > 4) + { + mexErrMsgTxt ("Usage: L = cs_updown(L,C,parent,sigma)") ; + } + Lin = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; /* get input L */ + n = Lin->n ; + if (nargin > 3 && mxIsChar (pargin [3])) + { + mxGetString (pargin [3], sigma_string, 8) ; + sigma = (sigma_string [0] == '-') ? (-1) : 1 ; + } + /* make a copy of L (this can take more work than updating L itself) */ + lnz = Lin->p [n] ; + L = cs_spalloc (n, n, lnz, 1, 0) ; + for (j = 0 ; j <= n ; j++) L->p [j] = Lin->p [j] ; + for (k = 0 ; k < lnz ; k++) L->i [k] = Lin->i [k] ; + for (k = 0 ; k < lnz ; k++) L->x [k] = Lin->x [k] ; + cs_mex_check (0, n, -1, 0, 1, 1, pargin [1]) ; /* get C */ + C = cs_mex_get_sparse (&Cmatrix, 0, 1, pargin [1]) ; + parent = cs_mex_get_int (n, pargin [2], &ignore, 0) ; /* get parent */ + + /* do the update one column at a time */ + Cvec = &Cvector ; + Cvec->m = n ; + Cvec->n = 1 ; + Cvec->p = cp ; + Cvec->nz = -1 ; + cp [0] = 0 ; + for (k = 0 ; k < C->n ; k++) + { + /* extract C(:,k) */ + cp [1] = C->p [k+1] - C->p [k] ; + Cvec->nzmax = cp [1] ; + Cvec->i = C->i + C->p [k] ; + Cvec->x = C->x + C->p [k] ; + cs_updown (L, sigma, Cvec, parent) ; /* update/downdate */ + } + pargout [0] = cs_mex_put_sparse (&L) ; /* return new L */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve.m new file mode 100644 index 0000000..1a75cc9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve.m @@ -0,0 +1,21 @@ +function x = cs_usolve (U,b) %#ok +%CS_USOLVE solve a sparse upper triangular system U*x=b. +% x = cs_usolve(U,b) computes x = U\b, U must be lower triangular with a +% zero-free diagonal. b must be a column vector. x is full if b is full. +% If b is sparse, x is sparse but nonzero pattern of x is NOT sorted (it is +% returned in topological order). +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; n = size (A,1) ; +% b = rand (n,1); +% [L U p q] = cs_lu (A) ; +% x = cs_usolve (U, cs_lsolve (L, b(p))) ; % x = U \ (L \ b(p)) ; +% x (q) = x ; +% norm (A*x-b) +% +% See also CS_LSOLVE, CS_LTSOLVE, CS_UTSOLVE, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_usolve mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve_mex.c new file mode 100644 index 0000000..4d61f51 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_usolve_mex.c @@ -0,0 +1,59 @@ +#include "cs_mex.h" +/* cs_usolve: x=U\b. U must be sparse, real, and upper triangular. b must be a + * real full or sparse vector. x is full or sparse, depending on b. + * + * Time taken is O(flop count), which may be less than n if b is sparse, + * depending on U and b. + * + * This function works with MATLAB 7.2, but is not perfectly compatible with + * the requirements of a MATLAB mexFunction when b is sparse. X is returned + * as an unsorted sparse vector. Also, this mexFunction temporarily modifies + * its input, U, by modifying U->p (in the cs_dfs function) and then restoring + * it. This could be corrected by creating a copy of U->p (see + * cs_dmperm_mex.c), but this would take O(n) time, destroying the + * O(flop count) time complexity of this function. + */ + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Umatrix, Bmatrix, *U, *B, *X ; + double *x, *b ; + int top, nz, p, *xi ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_usolve(U,b)") ; + } + U = cs_mex_get_sparse (&Umatrix, 1, 1, pargin [0]) ; /* get U */ + if (mxIsSparse (pargin [1])) + { + B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ;/* get sparse b */ + cs_mex_check (0, U->n, 1, 0, 1, 1, pargin [1]) ; + xi = cs_malloc (2*U->n, sizeof (int)) ; /* get workspace */ + x = cs_malloc (U->n, sizeof (double)) ; + top = cs_spsolve (U, B, 0, xi, x, NULL, 0) ; /* x = U\b */ + X = cs_spalloc (U->n, 1, U->n-top, 1, 0) ; /* create sparse x*/ + X->p [0] = 0 ; + nz = 0 ; + for (p = top ; p < U->n ; p++) + { + X->i [nz] = xi [p] ; + X->x [nz++] = x [xi [p]] ; + } + X->p [1] = nz ; + pargout [0] = cs_mex_put_sparse (&X) ; + cs_free (x) ; + cs_free (xi) ; + } + else + { + b = cs_mex_get_double (U->n, pargin [1]) ; /* get full b */ + x = cs_mex_put_double (U->n, b, &(pargout [0])) ; /* x = b */ + cs_usolve (U, x) ; /* x = U\x */ + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve.m new file mode 100644 index 0000000..1ed5923 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve.m @@ -0,0 +1,19 @@ +function x = cs_utsolve (U,b) %#ok +%CS_UTSOLVE solve a sparse lower triangular system U'*x=b. +% x = cs_utsolve(U,b) computes x = U'\b, U must be upper triangular with a +% zero-free diagonal. b must be a full vector. +% +% Example: +% Prob = UFget ('HB/arc130') ; A = Prob.A ; n = size (A,1) ; +% b = rand (n,1); +% [L U p q] = cs_lu (A) ; +% x = cs_ltsolve (L, cs_utsolve (U, b(q))) ; % x = L' \ (U' \ b(q)) ; +% x (p) = x ; +% norm (A'*x-b) +% +% See also CS_LSOLVE, CS_LTSOLVE, CS_USOLVE, MLDIVIDE. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_utsolve mexFunction not found') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve_mex.c new file mode 100644 index 0000000..8993f9e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cs_utsolve_mex.c @@ -0,0 +1,21 @@ +#include "cs_mex.h" +/* cs_utsolve: solve a lower triangular system U'*x=b */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Umatrix, *U ; + double *x, *b ; + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_utsolve(U,b)") ; + } + U = cs_mex_get_sparse (&Umatrix, 1, 1, pargin [0]) ; /* get U */ + b = cs_mex_get_double (U->n, pargin [1]) ; /* get b */ + x = cs_mex_put_double (U->n, b, &(pargout [0])) ; /* x = b */ + cs_utsolve (U, x) ; /* x = U'\x */ +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cspy.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cspy.m new file mode 100644 index 0000000..db24483 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/cspy.m @@ -0,0 +1,100 @@ +function [s,M,H] = cspy (A,res) +%CSPY plot a matrix in color. +% cspy(A) plots a matrix, in color, with a default resolution of +% 256-by-256. cspy(A,res) changes the resolution to res. Zero entries are +% white. Entries with tiny absolute value are light orange. Entries with +% large magnitude are black. Entries in the midrange (the median of the +% log10 of the nonzero values, +/- one standard deviation) range from light +% green to deep blue. With no inputs, the color legend of cspy is plotted. +% [s,M,H] = cspy(A) returns the scale factor s, the image M, and colormap H. +% +% The matrix A can be full or sparse, and either numeric (double, single, +% integer) or character type, and either complex or real. +% +% Example +% A = delsq (numgrid ('L', 10)) ; +% cspy (A) ; +% +% See also CS_DMSPY, SPY. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if nargin < 2 + res = 256 ; +end + +h = jet (64) ; +h = h (64:-1:1,:) ; +h = h (30:end,:) ; +hmax = size (h,1) ; + +h (1,:) = [1 1 1] ; % white for zero +h (2,:) = [1 .9 .5] ; % light orange for tiny entries +h (hmax,:) = [0 0 0] ; % black for very large entries +colormap (h) ; + +if (nargin == 0) + image (1:hmax) ; + title ('cspy color map') ; + return +end + +% convert complex, integers, and strings to real double +if (~isreal (A) | ~isa (A, 'double') | ~issparse (A)) %#ok + A = sparse (abs (double (A))) ; +end + +[m1 n1] = size (A) ; +if (m1 == 0 | n1 == 0) %#ok + A (1,1) = 0 ; +end +[m1 n1] = size (A) ; + +S = cs_thumb (A,res) ; % get the thumbnail of the matrix +[m n] = size (S) ; +[i j x] = find (S) ; +x = log10 (x) ; + +if (isempty (x)) + S = zeros (size (S)) ; +else + med = median (x) ; + sdev = std (x) ; + big = med + sdev ; + tiny = med - sdev ; + imid = find (x > tiny & x < big) ; + itiny = find (x <= tiny) ; + ibig = find (x >= big) ; + x (imid) = 1 + ceil ((hmax-2) * (x (imid) - tiny) / (big - tiny)) ; + x (itiny) = 1 ; %#ok + x (ibig) = hmax-1 ; %#ok + S = full (1 + sparse (i,j,x,m,n)) ; + +% title (sprintf ('tiny: %-8.2g median: %-8.2g big: %-8.2g\n', ... +% 10^tiny, 10^med, 10^big)) ; +end + +% draw the matrix +image (S) ; +axis equal ; +axis ([-1 n+1 -1 m+1]) ; +axis off + +% draw a box around the whole matrix +e = ceil (max (m1,n1) / max (m,n)) ; % scale factor +hold on +drawbox (1,m1+1,1,n1+1,'k',1,e) ; +hold off + +% return results +if (nargout > 0) + s = e ; +end +if (nargout > 1) + M = S ; % image +end +if (nargout > 2) + H = h ; % colormap +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawbox.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawbox.m new file mode 100644 index 0000000..96e0f5c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawbox.m @@ -0,0 +1,29 @@ +function drawbox (r1,r2,c1,c2,color,w,e) +%DRAWBOX draw a box around a submatrix in the figure. +% Used by cspy, cs_dmspy, and ccspy. +% Example: +% drawbox (r1,r2,c1,c2,color,w,e) +% See also drawboxes, plot + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (r1 == r2 | c1 == c2) %#ok + return +end + +if (e == 1) + r1 = r1 - .5 ; + r2 = r2 - .5 ; + c1 = c1 - .5 ; + c2 = c2 - .5 ; +else + r1 = ceil (r1 / e) - .5 ; + r2 = ceil ((r2 - 1) / e) + .5 ; + c1 = ceil (c1 / e) - .5 ; + c2 = ceil ((c2 - 1) / e) + .5 ; +end + +if (c2 > c1 | r2 > r1) %#ok + plot ([c1 c2 c2 c1 c1], [r1 r1 r2 r2 r1], color, 'LineWidth', w) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawboxes.m b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawboxes.m new file mode 100644 index 0000000..c53f3a1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/CSparse/private/drawboxes.m @@ -0,0 +1,29 @@ +function drawboxes (nb, e, r, s) +%DRAWBOXES: helper function for cs_dmpsy and ccspy +% Example: +% drawboxes (nb, e, r, s) +% See also drawbox, plot + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nb > 1) + if (e == 1) + r1 = r (1:nb) - .5 ; + r2 = r (2:nb+1) - .5 ; + c1 = s (1:nb) - .5 ; + c2 = s (2:nb+1) - .5 ; + else + r1 = ceil (r (1:nb) / e) - .5 ; + r2 = ceil ((r (2:nb+1) - 1) / e) + .5 ; + c1 = ceil (s (1:nb) / e) - .5 ; + c2 = ceil ((s (2:nb+1) - 1) / e) + .5 ; + end + kk = find (diff (c1) > 0 | diff (c2) > 0 | diff (r1) > 0 | diff (r2) > 0) ; + kk = [1 kk+1] ; + for k = kk + plot ([c1(k) c2(k) c2(k) c1(k) c1(k)], ... + [r1(k) r1(k) r2(k) r2(k) r1(k)], 'k', 'LineWidth', 1) ; + end +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/Contents.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/Contents.m new file mode 100644 index 0000000..1a3bda9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/Contents.m @@ -0,0 +1,11 @@ +% CSparse MATLAB demos. +% +% cs_demo - run all CSparse demos. +% cs_demo1 - MATLAB version of the CSparse/Demo/cs_demo1.c program. +% cs_demo2 - MATLAB version of the CSparse/Demo/cs_demo2.c program. +% cs_demo3 - MATLAB version of the CSparse/Demo/cs_demo3.c program. + +% Example: +% help cs_demo + +% Copyright 2006-2007, Timothy A. Davis diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/README.txt b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/README.txt new file mode 100644 index 0000000..bcc9eec --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/README.txt @@ -0,0 +1 @@ +Demo for MATLAB interface for CSparse. See Contents.m for details. diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo.m new file mode 100644 index 0000000..e1f24cf --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo.m @@ -0,0 +1,46 @@ +function cs_demo (do_pause, matrixpath) +%CS_DEMO run all CSparse demos. +% cs_demo(0) will run all demos without pausing. +% +% Example: +% cs_demo +% See also: cs_demo1, cs_demo2, cs_demo3 + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +help cs_demo +if (nargin < 1) + do_pause = 1 ; +end +if (nargin < 2) + matrixpath = [] ; +end + +clf + +fprintf ('\n\n-------------------------------------------------------\n') ; +help cs_demo1 ; +cs_demo1 (matrixpath) ; + +fprintf ('\n\n-------------------------------------------------------\n') ; +help cs_demo2 +cs_demo2 (do_pause, matrixpath) ; + +fprintf ('\n\n-------------------------------------------------------\n') ; +help cs_demo3 +cs_demo3 (do_pause, matrixpath) ; + +fprintf ('\n\n-------------------------------------------------------\n') ; +help private/ex_1 +ex_1 + +fprintf ('\n\n-------------------------------------------------------\n') ; +help private/ex2 +ex2 + +fprintf ('\n\n-------------------------------------------------------\n') ; +help private/ex3 +ex3 + +fprintf ('\nAll CSparse demos finished.\n') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo1.m new file mode 100644 index 0000000..b716427 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo1.m @@ -0,0 +1,56 @@ +function cs_demo1 (matrixpath) +%CS_DEMO1 MATLAB version of the CSparse/Demo/cs_demo1.c program. +% Uses both MATLAB functions and CSparse mexFunctions, and compares the two +% results. This demo also plots the results, which the C version does not do. +% +% Example: +% cs_demo1 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 1) + matrixpath = [] ; +end + +if (isempty (matrixpath)) + try + % older versions of MATLAB do not have an input argument to mfilename + p = mfilename ('fullpath') ; + t = strfind (p, filesep) ; + matrixpath = [ p(1:t(end)) '../../Matrix' ] ; + catch + % assume we are in the C*Sparse/MATLAB/CSparse/Demo directory + matrixpath = '../../Matrix' ; + end +end + +t1 = load ([matrixpath '/t1']) ; + +T = t1 %#ok +A = sparse (T(:,1)+1, T(:,2)+1, T(:,3)) %#ok +A2 = cs_sparse (T(:,1)+1, T(:,2)+1, T(:,3)) %#ok +fprintf ('A difference: %g\n', norm (A-A2,1)) ; +% CSparse/Demo/cs_demo1.c also clears the triplet matrix T at this point: +% clear T +clf +subplot (2,2,1) ; cspy (A) ; title ('A', 'FontSize', 16) ; +AT = A' %#ok +AT2 = cs_transpose (A) %#ok +fprintf ('AT difference: %g\n', norm (AT-AT2,1)) ; +subplot (2,2,2) ; cspy (AT) ; title ('A''', 'FontSize', 16) ; +n = size (A,2) ; +I = speye (n) ; +C = A*AT ; +C2 = cs_multiply (A, AT) %#ok +fprintf ('C difference: %g\n', norm (C-C2,1)) ; +subplot (2,2,3) ; cspy (C) ; title ('C=A*A''', 'FontSize', 16) ; +cnorm = norm (C,1) ; +D = C + I*cnorm %#ok +D2 = cs_add (C, I, 1, cnorm) %#ok +fprintf ('D difference: %g\n', norm (D-D2,1)) ; +subplot (2,2,4) ; cspy (D) ; title ('D=C+I*norm(C,1)', 'FontSize', 16) ; +% CSparse/Demo/cs_demo1.c clears all matrices at this point: +% clear A AT C D I +% clear A2 AT2 C2 D2 diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo2.m new file mode 100644 index 0000000..e19ced9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo2.m @@ -0,0 +1,42 @@ +function cs_demo2 (do_pause, matrixpath) +%CS_DEMO2 MATLAB version of the CSparse/Demo/cs_demo2.c program. +% Solves a linear system using Cholesky, LU, and QR, with various orderings. +% +% Example: +% cs_demo2 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 2) + matrixpath = [] ; +end + +if (isempty (matrixpath)) + try + % older versions of MATLAB do not have an input argument to mfilename + p = mfilename ('fullpath') ; + t = strfind (p, filesep) ; + matrixpath = [ p(1:t(end)) '../../Matrix' ] ; + catch + % assume we are in the C*Sparse/MATLAB/CSparse/Demo directory + matrixpath = '../../Matrix' ; + end +end + +matrices = { 't1', 'HB/fs_183_1', 'HB/west0067', 'LPnetlib/lp_afiro', ... +'HB/ash219', 'HB/mbeacxc', 'HB/bcsstk01', 'HB/bcsstk16' } ; + +if (nargin < 1) + do_pause = 1 ; +end + +for i = 1:length(matrices) + name = matrices {i} ; + [C sym] = get_problem (matrixpath, name, 1e-14) ; + demo2 (C, sym, name) ; + if (do_pause) + input ('Hit enter to continue: ') ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo3.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo3.m new file mode 100644 index 0000000..1715d08 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/cs_demo3.m @@ -0,0 +1,41 @@ +function cs_demo3 (do_pause, matrixpath) +%CS_DEMO3 MATLAB version of the CSparse/Demo/cs_demo3.c program. +% Cholesky update/downdate. +% +% Example: +% cs_demo3 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 2) + matrixpath = [] ; +end + +if (isempty (matrixpath)) + try + % older versions of MATLAB do not have an input argument to mfilename + p = mfilename ('fullpath') ; + t = strfind (p, filesep) ; + matrixpath = [ p(1:t(end)) '../../Matrix' ] ; + catch + % assume we are in the C*Sparse/MATLAB/CSparse/Demo directory + matrixpath = '../../Matrix' ; + end +end + +matrices = { 'HB/bcsstk01', 'HB/bcsstk16' } ; + +if (nargin < 1) + do_pause = 1 ; +end + +for i = 1:length(matrices) + name = matrices {i} ; + [C sym] = get_problem (matrixpath, name, 1e-14) ; + demo3 (C, sym, name) ; + if (do_pause) + input ('Hit enter to continue: ') ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo2.m new file mode 100644 index 0000000..fd90ded --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo2.m @@ -0,0 +1,109 @@ +function demo2 (C, sym, name) +%DEMO2: solve a linear system using Cholesky, LU, and QR, with various orderings +% +% Example: +% demo2 (C, 1, 'name of system') +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +clf +subplot (2,2,1) ; cspy (C) ; +title (name, 'FontSize', 16, 'Interpreter', 'none') ; +[m n] = size (C) ; +[p,q,r,s,cc,rr] = cs_dmperm (C) ; +subplot (2,2,3) ; cs_dmspy (C) ; +subplot (2,2,2) ; ccspy (C) ; +drawnow + +sprnk = rr (4) - 1 ; +nb = length (r) - 1 ; +ns = sum ((r (2:nb+1) == r (1:nb)+1) & (s (2:nb+1) == s (1:nb)+1)) ; +fprintf ('blocks: %d singletons %d structural rank %d\n', nb, ns, sprnk) ; + +if (sprnk ~= sprank (C)) + error ('sprank mismatch!') ; +end + +if (sprnk < min (m,n)) + return ; % return if structurally singular +end + + +% the following code is not in the C version of this demo: +if (m == n) + if (sym) + try + [L,p] = cs_chol (C) ; %#ok + subplot (2,2,4) ; + cspy (L+triu(L',1)) ; title ('L+L''') ; + catch + % tol = 0.001 ; + [L,U,p,q] = cs_lu (C,0.001) ; %#ok + subplot (2,2,4) ; + cspy (L+U-speye(n)) ; title ('L+U') ; + end + else + [L,U,p,q] = cs_lu (C) ; %#ok + subplot (2,2,4) ; + cspy (L+U-speye(n)) ; title ('L+U') ; + end +else + if (m < n) + [V,beta,p,R,q] = cs_qr (C') ; %#ok + else + [V,beta,p,R,q] = cs_qr (C) ; %#ok + end + subplot (2,2,4) ; + cspy (V+R) ; title ('V+R') ; +end +drawnow + +% continue with the MATLAB equivalent of the C cs_demo2 program +for order = [0 3] + if (order == 0 & m > 1000) %#ok + continue ; + end + fprintf ('QR ') ; + print_order (order) ; + b = rhs (m) ; % compute right-hand-side + tic ; + x = cs_qrsol (C, b, order) ; + fprintf ('time %8.2f ', toc) ; + print_resid (C, x, b) ; +end + +if (m ~= n) + return ; +end + +for order = 0:3 + if (order == 0 & m > 1000) %#ok + continue ; + end + fprintf ('LU ') ; + print_order (order) ; + b = rhs (m) ; % compute right-hand-side + tic ; + x = cs_lusol (C, b, order) ; + fprintf ('time %8.2f ', toc) ; + print_resid (C, x, b) ; +end + +if (sym == 0) + return ; +end + +for order = 0:1 + if (order == 0 & m > 1000) %#ok + continue ; + end + fprintf ('Chol ') ; + print_order (order) ; + b = rhs (m) ; % compute right-hand-side + tic ; + x = cs_cholsol (C, b, order) ; + fprintf ('time %8.2f ', toc) ; + print_resid (C, x, b) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo3.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo3.m new file mode 100644 index 0000000..28fbbca --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/demo3.m @@ -0,0 +1,97 @@ +function demo3 (C, sym, name) +%DEMO3: Cholesky update/downdate +% +% Example: +% demo3 (C, 1, 'name of system') +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clf +subplot (2,2,1) ; cspy (C) ; +title (name, 'FontSize', 16, 'Interpreter', 'none') ; +drawnow + +[m n] = size (C) ; +if (m ~= n | ~sym) %#ok + return ; +end + +b = rhs (n) ; +fprintf ('chol then update/downdate ') ; +print_order (0) ; + +tic ; +[L,p] = cs_chol (C) ; +t = toc ; +fprintf ('\nchol time: %8.2f\n', t) ; + +subplot (2,2,2) ; cspy (L) ; title ('L') ; +drawnow + +tic ; +x = b (p) ; +x = cs_lsolve (L,x) ; +x = cs_ltsolve (L,x) ; +x (p) = x ; +t = toc ; +fprintf ('solve time: %8.2f\n', t) ; + +fprintf ('original: ') ; +print_resid (C, x, b) ; + +k = fix (n/2) ; +w = L(k,k) * sprand (L (:,k)) ; + +parent = cs_etree (C (p,p)) ; + +tic ; +L2 = cs_updown (L, w, parent, '+') ; +t1 = toc ; +fprintf ('update: time: %8.2f\n', t1) ; + +subplot (2,2,3) ; cspy (L2) ; title ('updated L') ; +subplot (2,2,4) ; cspy (L-L2) ; title ('L - updated L') ; +drawnow + +tic ; +x = b (p) ; +x = cs_lsolve (L2,x) ; +x = cs_ltsolve (L2,x) ; +x (p) = x ; +t = toc ; + +w2 = sparse (n,1) ; +w2 (p) = w ; % w2 = P'*w +wt = cs_transpose (w2) ; +ww = cs_multiply (w2,wt) ; +E = cs_add (C, ww, 1, 1) ; % E = C + w2*w2' ; + +fprintf ('update: time: %8.2f (incl solve) ', t1+t) ; +print_resid (E, x, b) ; + +tic +[L,p2] = cs_chol (E) ; +x = b (p2) ; +x = cs_lsolve (L,x) ; +x = cs_ltsolve (L,x) ; +x (p2) = x ; +t = toc ; +fprintf ('rechol: time: %8.2f (incl solve) ', t) ; +print_resid (E, x, b) ; + +tic ; +L3 = cs_updown (L2, w, parent, '-') ; +t1 = toc ; +fprintf ('downdate: time: %8.2f\n', t1) ; + +tic ; +x = b (p) ; +x = cs_lsolve (L3,x) ; +x = cs_ltsolve (L3,x) ; +x (p) = x ; +t = toc ; +fprintf ('downdate: time: %8.2f (incl solve) ', t1+t) ; +print_resid (C, x, b) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex2.m new file mode 100644 index 0000000..99abd1f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex2.m @@ -0,0 +1,91 @@ +function ex2 (n) +%EX2: create an n-by-n 2D mesh, four different ways + +% Example: +% ex2 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 1) + n = 30 ; +end + +subplot (1,2,1) ; + +% method 1: create an n-by-n 2D mesh for the 2nd difference operator +tic +ii = zeros (5*n^2, 1) ; +jj = zeros (5*n^2, 1) ; +xx = zeros (5*n^2, 1) ; +k = 1 ; +for j = 0:n-1 + for i = 0:n-1 + s = j*n+i + 1 ; + ii (k:k+4) = [(j-1)*n+i j*n+(i-1) j*n+i j*n+(i+1) (j+1)*n+i ] + 1 ; + jj (k:k+4) = [s s s s s] ; + xx (k:k+4) = [-1 -1 4 -1 -1] ; + k = k + 5 ; + end +end + +% remove entries beyond the boundary +keep = find (ii >= 1 & ii <= n^2 & jj >= 1 & jj <= n^2) ; +ii = ii (keep) ; +jj = jj (keep) ; +xx = xx (keep) ; +A = sparse (ii,jj,xx) ; +t1 = toc ; disp (t1) ; +% subplot (2,2,1) ; +spy (A) +title (sprintf ('%d-by-%d 2D mesh\n', n, n)) ; + +% method 2, using no for loops +tic +nn = 1:n^2 ; +i2 = [nn-n ; nn-1 ; nn ; nn+1 ; nn+n] ; +j2 = repmat (nn, 5, 1) ; +x2 = repmat ([-1 -1 4 -1 -1]', 1, n^2) ; +keep = find (i2 >= 1 & i2 <= n^2 & j2 >= 1 & j2 <= n^2) ; +i2 = i2 (keep) ; +j2 = j2 (keep) ; +x2 = x2 (keep) ; +C = sparse (i2,j2,x2) ; +t2 = toc ; disp (t2) ; + +% subplot (2,2,2) ; plot (j2) ; +% title ('2D fast j2') ; +disp (A-C) ; + +any (ii-i2) +any (jj-jj) + +% method 3: create an n-by-n-by-n 3D mesh for the 2nd difference operator +tic +[A, keep, ii, jj, xx] = mesh3d1 (n) ; +ii = ii (keep) ; +jj = jj (keep) ; +xx = xx (keep) ; +t3 = toc ; disp (t3) ; +tic +E = sparse (ii,jj,xx) ; +t3b = toc ; disp (t3b) ; +subplot (1,2,2) ; spy (E) ; +title (sprintf ('%d-by-%d-by-%d 3D mesh\n', n, n, n)) ; + +% method 4, using no for loops +tic +nn = 1:n^3 ; +i2 = [nn-n^2 ; nn-n ; nn-1 ; nn ; nn+1 ; nn+n ; nn+n^2] ; +j2 = repmat (nn, 7, 1) ; +x2 = repmat ([-1 -1 -1 6 -1 -1 -1]', 1, n^3) ; +keep = find (i2 >= 1 & i2 <= n^3 & j2 >= 1 & j2 <= n^3) ; +i2 = i2 (keep) ; +j2 = j2 (keep) ; +x2 = x2 (keep) ; +t4 = toc ; disp (t4) ; +tic +F = sparse (i2,j2,x2) ; +t4b = toc ; disp (t4b) ; +disp (E-F) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex3.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex3.m new file mode 100644 index 0000000..b425900 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex3.m @@ -0,0 +1,42 @@ +function ex3 +%EX3: create 2D and 3D meshes using mesh2d1, mesh2d2, mesh3d1, mesh3d2. + +% Example: +% ex3 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +t1 = zeros (50,1) ; +t2 = zeros (50,1) ; +t3 = zeros (50,1) ; +t4 = zeros (50,1) ; + +fprintf ('run times for each method, given n:\n') ; +for n = 2:50 + + tic ; + A = mesh2d1 (n) ; + t1 (n) = toc ; + + tic + B = mesh2d2 (n) ; + t2 (n) = toc ; + + tic + C = mesh3d1 (n) ; + t3 (n) = toc ; + + tic + D = mesh3d2 (n) ; + t4 (n) = toc ; + + fprintf ('%3d: %8.3f %8.3f %8.3f %8.3f\n', n, t1(n), t2(n), t3(n), t4(n)) ; + + subplot (2,2,1) ; spy (A) ; title ('2D mesh, method 1') ; + subplot (2,2,2) ; spy (B) ; title ('2D mesh, method 2') ; + subplot (2,2,3) ; spy (C) ; title ('3D mesh, method 1') ; + subplot (2,2,4) ; spy (D) ; title ('3D mesh, method 2') ; + drawnow +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex_1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex_1.m new file mode 100644 index 0000000..71d5787 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/ex_1.m @@ -0,0 +1,86 @@ +function ex_1 +%EX_1: four methods for creating the same matrix. +% (please wait, this can take a while...) + +% Example: +% ex_1 +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = 1000 ; +nz = 1e5 ; + +tic +% method 1: A(i,j) = ... +rand ('state', 0) ; +A = sparse (n,n) ; +for k = 1:nz + % compute some arbitrary entry and add it into the matrix + i = 1 + fix (n * rand (1)) ; + j = 1 + fix (n * rand (1)) ; + x = rand (1) ; + A (i,j) = A (i,j) + x ; % VERY slow, esp. if A(i,j) not already nonzero! +end +fprintf ('Method 1: ') ; +toc +A1 = A ; + +tic +% method 2: triplet form, one entry at a time +rand ('state', 0) ; +ii = zeros (nz, 1) ; % preallocate ii, jj, and xx +jj = zeros (nz, 1) ; +xx = zeros (nz, 1) ; +for k = 1:nz + % compute some arbitrary entry and add it into the matrix + ii (k) = 1 + fix (n * rand (1)) ; + jj (k) = 1 + fix (n * rand (1)) ; + xx (k) = rand (1) ; +end +A = sparse (ii,jj,xx) ; +fprintf ('Method 2: ') ; +toc +A2 = A ; +disp (A1-A2) ; + +tic +% method 3: triplet form, one entry at a time, pretend nz is unknown +rand ('state', 0) ; +len = 16 ; +ii = zeros (len, 1) ; +jj = zeros (len, 1) ; +xx = zeros (len, 1) ; +for k = 1:nz + % compute some arbitrary entry and add it into the matrix + if (k > len) + % double the size of ii,jj,xx + len = 2*len ; + ii (len) = 0 ; + jj (len) = 0 ; + xx (len) = 0 ; + end + ii (k) = 1 + fix (n * rand (1)) ; + jj (k) = 1 + fix (n * rand (1)) ; + xx (k) = rand (1) ; +end +A = sparse (ii (1:k), jj (1:k), xx (1:k)) ; +fprintf ('Method 3: ') ; +toc + +A3 = A ; +disp (A1-A3) ; + +tic +% method 4: avoid the for loop +rand ('state', 0) ; +e = rand (3, nz) ; +e (1,:) = 1 + fix (n * e (1,:)) ; +e (2,:) = 1 + fix (n * e (2,:)) ; +A = sparse (e (1,:), e (2,:), e (3,:)) ; +fprintf ('Method 4: ') ; +toc + +A4 = A ; +disp (A1-A4) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/frand.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/frand.m new file mode 100644 index 0000000..4d3b16a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/frand.m @@ -0,0 +1,28 @@ +function A = frand (n,nel,s) +% A = frand (n,nel,s) creates an n-by-n sparse matrix consisting of nel finite +% elements, each of which are of size s-by-s with random symmetric nonzero +% pattern, plus the identity matrix. +% +% Example: +% A = frand (100, 100, 4) ; cspy (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse +ss = s^2 ; +nz = nel*ss ; +ii = zeros (nz,1) ; +jj = zeros (nz,1) ; +xx = zeros (nz,1) ; +k = 1 ; +for e = 1:nel + i = 1 + fix (n * rand (s,1)) ; + i = repmat (i, 1, s) ; + j = i' ; + x = rand (s,s) ; + ii (k:k+ss-1) = i (:) ; + jj (k:k+ss-1) = j (:) ; + xx (k:k+ss-1) = x (:) ; + k = k + ss ; +end +A = sparse (ii,jj,xx,n,n) + speye (n) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/get_problem.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/get_problem.m new file mode 100644 index 0000000..a2dc3d6 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/get_problem.m @@ -0,0 +1,57 @@ +function [C, sym] = get_problem (prefix, name, tol) +% [C, sym] = get_problem(prefix, name,tol) +% read a problem from a file, drop entries with abs value < tol +% tol defaults to zero if not present +% +% Example: +% [C, sym] = get_problem ('', 'west0067') ; +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +fprintf ('\n------------------- Matrix: %s\n', name) ; + +if (nargin < 2) + tol = 0 ; +end + +s = find (name == '/') ; +if (isempty (s)) + s = 0 ; +end +% f = sprintf ('%s..%s..%sMatrix%s%s', ... +% prefix, filesep, filesep, filesep, name (s+1:end)) ; + +% load the triplet version of the matrix +T = load ([ prefix '/' name(s+1:end) ]) ; + +% convert into a sparse matrix and compare with cs_sparse +A = sparse (T (:,1)+1, T (:,2)+1, T (:,3)) ; +A2 = cs_sparse (T (:,1)+1, T (:,2)+1, T (:,3)) ; +err = norm (A-A2,1) ; +if (err > 0) + fprintf ('A difference: %g\n', err) ; +end + +[m n] = size (A) ; +nz2 = nnz (A) ; + +if (tol > 0) + A = cs_droptol (A, tol) ; +end + +% assume A is symmetric if it is upper or lower triangular +sym = is_sym (A) ; +if (sym) + C = A + (A' - diag (diag (A))) ; +else + C = A ; +end + +fprintf ('--- Matrix: %d-by-%d, nnz: %d (sym: %d nnz %d), norm: %8.2e\n', ... + m, n, nnz(A), sym, abs(sym)*nnz(C), norm (C,1)) ; + +if (nz2 ~= nnz(A)) + fprintf ('tiny entries dropped: %d\n', nz2 - nnz(A)) +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/is_sym.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/is_sym.m new file mode 100644 index 0000000..22f3af5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/is_sym.m @@ -0,0 +1,23 @@ +function sym = is_sym (A) +% sym = is_sym(A) +% 1 if A is square and upper tri., -1 if square and lower tri., 0 otherwise +% +% Example: +% sym = is_sym (A) ; +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +sym = 0 ; +if (m == n) + is_upper = nnz (tril (A,-1)) == 0 ; + is_lower = nnz (triu (A,1)) == 0 ; + if (is_upper) + sym = 1 ; + elseif (is_lower) + sym = -1 ; + end +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d1.m new file mode 100644 index 0000000..8dc7a31 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d1.m @@ -0,0 +1,25 @@ +function A = mesh2d1 (n) +% create an n-by-n 2D mesh for the 2nd difference operator +% Example: +% A = mesh2d1 (30) ; % a 30-by-30 mesh +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +ii = zeros (5*n^2, 1) ; % preallocate ii, jj, and xx +jj = zeros (5*n^2, 1) ; +xx = zeros (5*n^2, 1) ; +k = 1 ; +for j = 0:n-1 + for i = 0:n-1 + s = j*n+i + 1 ; + ii (k:k+4) = [(j-1)*n+i j*n+(i-1) j*n+i j*n+(i+1) (j+1)*n+i ] + 1 ; + jj (k:k+4) = [s s s s s] ; + xx (k:k+4) = [-1 -1 4 -1 -1] ; + k = k + 5 ; + end +end +% remove entries beyond the boundary +keep = find (ii >= 1 & ii <= n^2 & jj >= 1 & jj <= n^2) ; +A = sparse (ii (keep), jj (keep), xx (keep)) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d2.m new file mode 100644 index 0000000..f3133bf --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh2d2.m @@ -0,0 +1,15 @@ +function A = mesh2d2 (n) +% create an n-by-n 2D mesh for the 2nd difference operator +% Example: +% A = mesh2d2 (30) ; % a 30-by-30 mesh +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +nn = 1:n^2 ; +ii = [nn-n ; nn-1 ; nn ; nn+1 ; nn+n] ; +jj = repmat (nn, 5, 1) ; +xx = repmat ([-1 -1 4 -1 -1]', 1, n^2) ; +keep = find (ii >= 1 & ii <= n^2 & jj >= 1 & jj <= n^2) ; +A = sparse (ii (keep), jj (keep), xx (keep)) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d1.m new file mode 100644 index 0000000..5aaf8b5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d1.m @@ -0,0 +1,33 @@ +function [A, keep, ii, jj, xx] = mesh3d1 (n) +% create an n-by-n-by-n 3D mesh for the 2nd difference operator +% Example: +% A = mesh3d1 (10) ; % a 10-by-10-by-10 mesh +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +ii = zeros (7*n^3, 1) ; +jj = zeros (7*n^3, 1) ; +xx = zeros (7*n^3, 1) ; +t = 1 ; +for k = 0:n-1 + for j = 0:n-1 + for i = 0:n-1 + s = k*n^2 + j*n+i + 1 ; + ii (t:t+6) = [ + (k-1)*n^2 + j*n+i + k*n^2 + (j-1)*n+i + k*n^2 + j*n+(i-1) + k*n^2 + j*n+i + k*n^2 + j*n+(i+1) + k*n^2 + (j+1)*n+i + (k+1)*n^2 + j*n+i ]' + 1 ; + jj (t:t+6) = [s s s s s s s] ; + xx (t:t+6) = [-1 -1 -1 6 -1 -1 -1] ; + t = t + 7 ; + end + end +end +keep = find (ii >= 1 & ii <= n^3 & jj >= 1 & jj <= n^3) ; +A = sparse (ii (keep), jj (keep), xx (keep)) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d2.m new file mode 100644 index 0000000..4a644f3 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/mesh3d2.m @@ -0,0 +1,15 @@ +function A = mesh3d2 (n) +% create an n-by-n-by-n 3D mesh for the 2nd difference operator +% Example: +% A = mesh3d2 (10) ; % a 10-by-10-by-10 mesh +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +nn = 1:n^3 ; +ii = [nn-n^2 ; nn-n ; nn-1 ; nn ; nn+1 ; nn+n ; nn+n^2] ; +jj = repmat (nn, 7, 1) ; +xx = repmat ([-1 -1 -1 6 -1 -1 -1]', 1, n^3) ; +keep = find (ii >= 1 & ii <= n^3 & jj >= 1 & jj <= n^3) ; +A = sparse (ii (keep), jj (keep), xx (keep)) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_order.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_order.m new file mode 100644 index 0000000..c196f84 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_order.m @@ -0,0 +1,21 @@ +function print_order (order) +% print_order(order) prints the ordering determined by the order parameter +% Example: +% print_order (0) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +switch (fix (order)) + case 0 + fprintf ('natural ') ; + case 1 + fprintf ('amd(A+A'') ') ; + case 2 + fprintf ('amd(S''*S) ') ; + case 3 + fprintf ('amd(A''*A) ') ; + otherwise + fprintf ('undefined ') ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_resid.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_resid.m new file mode 100644 index 0000000..4b22047 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/print_resid.m @@ -0,0 +1,12 @@ +function print_resid (A, x, b) +% print_resid (A, x, b), print the relative residual, +% norm (A*x-b,inf) / (norm(A,1)*norm(x,inf) + norm(b,inf)) +% Example: +% print_resid (A, x, b) ; +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +fprintf ('resid: %8.2e\n', ... + norm (A*x-b,inf) / (norm(A,1)*norm(x,inf) + norm(b,inf))) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/rhs.m b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/rhs.m new file mode 100644 index 0000000..f7bc531 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Demo/private/rhs.m @@ -0,0 +1,10 @@ +function b = rhs (m) +% b = rhs (m), compute a right-hand-side +% Example: +% b = rhs (30) ; +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +b = ones (m,1) + (0:m-1)'/m ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Makefile b/OpenDSSC/klusolve/CSparse/MATLAB/Makefile new file mode 100644 index 0000000..4636246 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Makefile @@ -0,0 +1,14 @@ +all: + ( cd CSparse ; $(MAKE) ) + ( cd Test ; $(MAKE) ) + +clean: + ( cd CSparse ; $(MAKE) clean ) + ( cd Test ; $(MAKE) clean ) + +purge: + ( cd CSparse ; $(MAKE) purge ) + ( cd Test ; $(MAKE) purge ) + +distclean: purge + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/README.txt b/OpenDSSC/klusolve/CSparse/MATLAB/README.txt new file mode 100644 index 0000000..6153439 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/README.txt @@ -0,0 +1,18 @@ +CSparse/MATLAB directory, which contains the MATLAB mexFunction interfaces +for CSparse, demos, and tests. It includes various "textbook" files +that are printed in the book, but not a proper part of CSparse itself. +It also includes "UFget", a MATLAB interface for the UF Sparse Matrix +Collection. + +Type the command "cs_install" while in this directory. It will compile +CSparse, and add the directories: + + CSparse/MATLAB/CSparse + CSparse/MATLAB/Demo + CSparse/MATLAB/UFget + +to your MATLAB path (see the "pathtool" command to add these to your path +permanently, for future MATLAB sessions). + +To run the MATLAB demo programs, run cs_demo in the Demo directory. +To run the MATLAB test programs, run testall in the Test directory. diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/Contents.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/Contents.m new file mode 100644 index 0000000..54d0d83 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/Contents.m @@ -0,0 +1,102 @@ +% CSparse "textbook" MATLAB M-files and mexFunctions, related to CSparse but +% not a part of CSparse itself. +% +% M-files: +% +% chol_downdate - downdate a Cholesky factorization. +% chol_left - left-looking Cholesky factorization. +% chol_left2 - left-looking Cholesky factorization, more details. +% chol_right - right-looking Cholesky factorization. +% chol_super - left-looking "supernodal" Cholesky factorization. +% chol_up - up-looking Cholesky factorization. +% chol_update - update a Cholesky factorization. +% chol_updown - update or downdate a Cholesky factorization. +% cond1est - 1-norm condition estimate. +% cs_fiedler - the Fiedler vector of a connected graph. +% givens2 - find a Givens rotation. +% house - find a Householder reflection. +% lu_left - left-looking LU factorization. +% lu_right - right-looking LU factorization. +% lu_rightp - right-looking LU factorization, with partial pivoting. +% lu_rightpr - recursive right-looking LU, with partial pivoting. +% lu_rightr - recursive right-looking LU. +% norm1est - 1-norm estimate. +% qr_givens - Givens-rotation QR factorization. +% qr_givens_full - Givens-rotation QR factorization, for full matrices. +% qr_left - left-looking Householder QR factorization. +% qr_right - right-looking Householder QR factorization. +% +% mexFunctions: +% +% cs_frand - generate a random finite-element matrix +% cs_ipvec - x(p)=b +% cs_maxtransr - recursive maximum matching algorithm +% cs_pvec - x=b(p) +% cs_reach - non-recursive reach (interface to CSparse cs_reach) +% cs_reachr - recursive reach (interface to CSparse cs_reachr) +% cs_rowcnt - row counts for sparse Cholesky +% cs_sparse2 - same as cs_sparse, to test cs_entry function +% +% Extensive test functions, not for normal usage: +% +% check_if_same - check if two inputs are identical or not +% choldn - Cholesky downdate +% cholup - Cholesky update, using Given's rotations +% cholupdown - Cholesky update/downdate (Bischof, Pan, and Tang method) +% cs_q1 - construct Q from Householder vectors +% cs_test_make - compiles the CSparse, Demo, and Test mexFunctions. +% dmperm_test - test cs_dmperm +% chol_example - simple Cholesky factorization example +% etree_sample - construct a sample etree and symbolic factorization +% gqr3 - QR factorization, based on Givens rotations +% happly - apply Householder reflection to a vector +% hmake1 - construct a Householder reflection +% mynormest1 - estimate norm(A,1), using LU factorization (L*U = P*A*Q). +% myqr - QR factorization using Householder reflections +% another_colormap - try another color map +% cspy_test - test cspy and cs_dmspy +% qr2 - QR factorization based on Householder reflections +% sample_colormap - try a colormap for use in cspy +% signum - compute and display the sign of a column vector x +% sqr_example - test cs_sqr +% dmspy_test - test cspy, cs_dmspy, and cs_dmperm +% test_qr - test various QR factorization methods +% test_randperms - test random permutations +% testh - test Householder reflections +% test_qr1 - test QR factorizations +% test_qrsol - test cs_qrsol +% test_sep - test cs_sep, and compare with Gilbert's meshpart vtxsep +% testall - test all CSparse functions (run tests 1 to 28 below) +% test1 - test cs_transpose +% test2 - test cs_sparse +% test3 - test cs_lsolve, cs_ltsolve, cs_usolve, cs_chol +% test4 - test cs_multiply +% test5 - test cs_add +% test6 - test cs_reach, cs_reachr, cs_lsolve, cs_usolve +% test7 - test cs_lu +% test8 - test cs_cholsol, cs_lusol +% test9 - test cs_qr +% test10 - test cs_qr +% test11 - test cs_rowcnt +% test12 - test cs_qr and compare with svd +% test13 - test cs_counts, cs_etree +% test14 - test cs_droptol +% test15 - test cs_amd +% test16 - test cs_amd +% test17 - test cs_qr, cs_qright, cs_q1, cs_qrleft, cs_qrsol +% test18 - test iterative refinement after backslash +% test19 - test cs_dmperm, cs_maxtransr, cs_dmspy, cs_scc +% test20 - test cholupdown +% test21 - test cs_updown +% test22 - test cond1est +% test23 - test cs_dmspy +% test24 - test cs_fielder +% test25 - test cs_nd +% test26 - test cs_dmsol and cs_dmspy +% test27 - test cs_qr, cs_utsolve, cs_qrsol +% test28 - test cs_randperm, cs_dmperm + +% Example: +% help chol_update + +% Copyright 2006-2007, Timothy A. Davis diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/Makefile b/OpenDSSC/klusolve/CSparse/MATLAB/Test/Makefile new file mode 100644 index 0000000..2ed8702 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/Makefile @@ -0,0 +1,49 @@ +MEX = mex -O + +all: cs_sparse2.mexglx \ + cs_ipvec.mexglx \ + cs_pvec.mexglx \ + cs_reach.mexglx \ + cs_maxtransr.mexglx \ + cs_reachr.mexglx \ + cs_rowcnt.mexglx \ + cs_frand.mexglx + +mexcsparse: + ( cd ../CSparse ; $(MAKE) mexcsparse.a ) + +I = -I../../Include -I../CSparse + +cs_ipvec.mexglx: cs_ipvec_mex.c mexcsparse + $(MEX) -output cs_ipvec $< $(I) ../CSparse/mexcsparse.a + +cs_pvec.mexglx: cs_pvec_mex.c mexcsparse + $(MEX) -output cs_pvec $< $(I) ../CSparse/mexcsparse.a + +cs_reach.mexglx: cs_reach_mex.c mexcsparse + $(MEX) -output cs_reach $< $(I) ../CSparse/mexcsparse.a + +cs_sparse2.mexglx: cs_sparse2_mex.c mexcsparse + $(MEX) -output cs_sparse2 $< $(I) ../CSparse/mexcsparse.a + +cs_maxtransr.mexglx: cs_maxtransr_mex.c mexcsparse + $(MEX) -output cs_maxtransr $< $(I) ../CSparse/mexcsparse.a + +cs_reachr.mexglx: cs_reachr_mex.c mexcsparse + $(MEX) -output cs_reachr $< $(I) ../CSparse/mexcsparse.a + +cs_rowcnt.mexglx: cs_rowcnt_mex.c mexcsparse + $(MEX) -output cs_rowcnt $< $(I) ../CSparse/mexcsparse.a + +cs_frand.mexglx: cs_frand_mex.c mexcsparse + $(MEX) -output cs_frand $< $(I) ../CSparse/mexcsparse.a + + + +clean: + - $(RM) *.o + +distclean: clean + - $(RM) *.mex* *.dll *.a + +purge: distclean diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/README.txt b/OpenDSSC/klusolve/CSparse/MATLAB/Test/README.txt new file mode 100644 index 0000000..d42da19 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/README.txt @@ -0,0 +1,4 @@ +Test for MATLAB interface for CSparse. Type "testall" to run all the tests. + +Also includes "textbook" codes for the book "Direct Methods for Sparse Linear +Systems", which are not part of CSparse proper, but are used in the tests. diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/another_colormap.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/another_colormap.m new file mode 100644 index 0000000..0c5cada --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/another_colormap.m @@ -0,0 +1,30 @@ +function another_colormap +%ANOTHER_COLORMAP try another color map +% +% Example: +% another_colormap +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +j = jet (128) ; +j = j (48:112, :) ; + +% jj = linspace (0,1,64)' ./ sum (jet,2) ; +% j (:,1) = j (:,1) .* jj ; +% j (:,2) = j (:,2) .* jj ; +% j (:,3) = j (:,3) .* jj ; + + +% white = [1 1 1] ; +% gray = [.5 .5 .5] ; %#ok + +% j = [white ; purple ; j ] ; +disp ('j = ') ; +disp (j) + + +image (1:size(j,1)) ; +colormap (j) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/check_if_same.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/check_if_same.m new file mode 100644 index 0000000..db53034 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/check_if_same.m @@ -0,0 +1,22 @@ +function check_if_same (p1,p2) +%CHECK_IF_SAME check if two inputs are identical or not +% +% Example: +% check_if_same (1:5, 2:6) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + if (isempty (p1)) + if (~isempty (p2)) + p1 %#ok + p2 %#ok + error ('empty!') ; + end + elseif (any (p1 ~= p2)) + p1 %#ok + p2 %#ok + error ('!') ; + end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_downdate.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_downdate.m new file mode 100644 index 0000000..74a7212 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_downdate.m @@ -0,0 +1,28 @@ +function [L, w] = chol_downdate (L, w) +%CHOL_DOWNDATE downdate a Cholesky factorization. +% Example +% [L, w] = chol_downdate (L, w) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +beta = 1 ; +n = size (L,1) ; +for j = 1:n + alpha = w (j) / L (j,j) ; + beta2 = sqrt (beta^2 - alpha^2) ; + if (~isreal (beta2)) + error ('not positive definite') ; + end + gamma = alpha / (beta2 * beta) ; + delta = beta2 / beta ; + L (j,j) = delta * L (j,j) ; + w (j) = alpha ; + beta = beta2 ; + if (j == n) + return + end + w (j+1:n) = w (j+1:n) - alpha * L (j+1:n,j) ; + L (j+1:n,j) = delta * L (j+1:n,j) - gamma * w (j+1:n) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_example.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_example.m new file mode 100644 index 0000000..f488f7d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_example.m @@ -0,0 +1,35 @@ +function chol_example +%CHOL_EXAMPLE simple Cholesky factorization example +% Example +% chol_example +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +D = 10 ; +X = 1 ; +o = 0 ; + +A = sparse ([ +D o X o o o o X o o +o D o o X o o o o X +X o D o o o X o o o +o o o D o o o o X X +o X o o D o o o X X +o o o o o D X X o o +o o X o o X D o o o +X o o o o X o D X X +o o o X X o o X D o +o X o X X o o X o D ]) ; + +disp ('A = ') ; disp (A) ; + +L = chol(A)' ; + +disp ('L = ') ; disp (L) ; + +clf +subplot (1,2,1) ; spy (A) ; +subplot (1,2,2) ; spy (L+L') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left.m new file mode 100644 index 0000000..ec75416 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left.m @@ -0,0 +1,15 @@ +function L = chol_left (A) +%CHOL_LEFT left-looking Cholesky factorization. +% Example +% L = chol_left (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +L = zeros (n) ; +for k = 1:n + L (k,k) = sqrt (A (k,k) - L (k,1:k-1) * L (k,1:k-1)') ; + L (k+1:n,k) = (A (k+1:n,k) - L (k+1:n,1:k-1) * L (k,1:k-1)') / L (k,k) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left2.m new file mode 100644 index 0000000..0116ac5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_left2.m @@ -0,0 +1,20 @@ +function L = chol_left2 (A) +%CHOL_LEFT2 left-looking Cholesky factorization, more details. +% Example +% L = chol_left2 (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +L = sparse (n,n) ; +a = sparse (n,1) ; +for k = 1:n + a (k:n) = A (k:n,k) ; + for j = find (L (k,:)) + a (k:n) = a (k:n) - L (k:n,j) * L (k,j) ; + end + L (k,k) = sqrt (a (k)) ; + L (k+1:n,k) = a (k+1:n) / L (k,k) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_right.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_right.m new file mode 100644 index 0000000..7aa60e1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_right.m @@ -0,0 +1,16 @@ +function L = chol_right (A) +%CHOL_RIGHT right-looking Cholesky factorization. +% Example +% L = chol_right (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A) ; +L = zeros (n) ; +for k = 1:n + L (k,k) = sqrt (A (k,k)) ; + L (k+1:n,k) = A (k+1:n,k) / L (k,k) ; + A (k+1:n,k+1:n) = A (k+1:n,k+1:n) - L (k+1:n,k) * L (k+1:n,k)' ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_super.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_super.m new file mode 100644 index 0000000..1744130 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_super.m @@ -0,0 +1,19 @@ +function L = chol_super (A,s) +%CHOL_SUPER left-looking "supernodal" Cholesky factorization. +% Example: +% L = chol_super (A,s) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A) ; +L = zeros (n) ; +ss = cumsum ([1 s]) ; +for j = 1:length (s) + k1 = ss (j) ; + k2 = ss (j+1) ; + k = k1:(k2-1) ; + L (k,k) = chol (A (k,k) - L (k,1:k1-1) * L (k,1:k1-1)')' ; + L (k2:n,k) = (A (k2:n,k) - L (k2:n,1:k1-1) * L (k,1:k1-1)') / L (k,k)' ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_up.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_up.m new file mode 100644 index 0000000..09d0218 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_up.m @@ -0,0 +1,15 @@ +function L = chol_up (A) +%CHOL_UP up-looking Cholesky factorization. +% Example: +% L = chol_up (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A) ; +L = zeros (n) ; +for k = 1:n + L (k,1:k-1) = (L (1:k-1,1:k-1) \ A (1:k-1,k))' ; + L (k,k) = sqrt (A (k,k) - L (k,1:k-1) * L (k,1:k-1)') ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_update.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_update.m new file mode 100644 index 0000000..ea12d0c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_update.m @@ -0,0 +1,26 @@ +function [L, w] = chol_update (L, w) +%CHOL_UPDATE update a Cholesky factorization. +% Example: +% [L, w] = chol_update (L, w) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +beta = 1 ; +n = size (L,1) ; +for j = 1:n + alpha = w (j) / L (j,j) ; + beta2 = sqrt (beta^2 + alpha^2) ; + gamma = alpha / (beta2 * beta) ; + delta = beta / beta2 ; + L (j,j) = delta * L (j,j) + gamma * w (j) ; + w (j) = alpha ; + beta = beta2 ; + if (j == n) + return + end + w1 = w (j+1:n) ; + w (j+1:n) = w (j+1:n) - alpha * L (j+1:n,j) ; + L (j+1:n,j) = delta * L (j+1:n,j) + gamma * w1 ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_updown.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_updown.m new file mode 100644 index 0000000..6cac855 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/chol_updown.m @@ -0,0 +1,36 @@ +function [L, w] = chol_updown (L, sigma, w) +%CHOL_UPDOWN update or downdate a Cholesky factorization. +% Example: +% [L, w] = chol_updown (L, sigma, w) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +beta = 1 ; +n = size (L,1) ; +if (n == 1) + L = sqrt (L*L'+sigma*w*w') ; + return ; +end +for k = 1:n + alpha = w(k) / L(k,k) ; + beta2 = sqrt (beta^2 + sigma*alpha^2) ; + gamma = sigma * alpha / (beta2 * beta) ; + if (sigma > 0) + % update + delta = beta / beta2 ; + L (k,k) = delta * L (k,k) + gamma * w (k) ; + w1 = w (k+1:n) ; + w (k+1:n) = w (k+1:n) - alpha * L (k+1:n,k) ; + L (k+1:n,k) = delta * L (k+1:n,k) + gamma * w1 ; + else + % downdate + delta = beta2 / beta ; + L (k,k) = delta * L (k,k) ; + w (k+1:n) = w (k+1:n) - alpha * L (k+1:n,k) ; + L (k+1:n,k) = delta * L (k+1:n,k) + gamma * w (k+1:n) ; + end + w (k) = alpha ; + beta = beta2 ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/choldn.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/choldn.m new file mode 100644 index 0000000..1b3d43d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/choldn.m @@ -0,0 +1,46 @@ +function L = choldn (Lold,w) +%CHOLDN Cholesky downdate +% given Lold and w, compute L so that L*L' = Lold*Lold' - w*w' +% +% Example: +% L = cholnd (Lold,w) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (Lold,1) ; +L = Lold ; + +alpha = 1 ; +beta = 1 ; + +wold = w ; +wnew = zeros (n,1) ; + +for i = 1:n + + a = w (i) / L(i,i) ; + alpha = alpha - a^2 ; + if (alpha <= 0) + error ('not pos def') ; + end + beta_new = sqrt (alpha) ; + b = beta_new / beta ; + c = (a / (beta*beta_new)) ; + beta = beta_new ; + + % L (i,i) = b * L (i,i) ; + + wnew (i) = a ; + + for k = i:n + w (k) = w (k) - a * L (k,i) ; + L (k,i) = b * L (k,i) - c * w(k) ; + end + +end + +% w +% wnew +disp (wnew - Lold\wold) diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholup.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholup.m new file mode 100644 index 0000000..e8f196c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholup.m @@ -0,0 +1,26 @@ +function L = cholup (Lold,w) +%CHOLUP Cholesky update, using Given's rotations +% given Lold and w, compute L so that L*L' = Lold*Lold' + w*w' +% Example: +% L = cholup (Lold,w) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (Lold,1) ; +L = [Lold w] ; + +for k = 1:n + + g = givens (L(k,k), L(k,n+1)) ; + + L (:, [k n+1]) = L (:, [k n+1]) * g' ; + + disp ('L:') ; + disp (L) + pause +end + +L = L (:,1:n) ; +disp (L) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholupdown.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholupdown.m new file mode 100644 index 0000000..2a8ef82 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cholupdown.m @@ -0,0 +1,58 @@ +function L = cholupdown (Lold, sigma, w) +%CHOLUPDOWN Cholesky update/downdate (Bischof, Pan, and Tang method) +% Example: +% L = cholupdown (Lold, sigma, w) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +beta = 1 ; +n = size (Lold,1) ; +L = Lold ; +% x = weros (n,1) ; +worig = w ; + +for k = 1:n + + alpha = w(k) / L(k,k) ; + beta_new = sqrt (beta^2 + sigma*alpha^2) ; + gamma = alpha / (beta_new * beta) ; + + if (sigma < 0) + + % downdate + bratio = beta_new / beta ; + w (k+1:n) = w (k+1:n) - alpha * L (k+1:n,k) ; + L (k,k) = bratio * L (k,k) ; + L (k+1:n,k) = bratio * L (k+1:n,k) - gamma*w(k+1:n) ; + + else + + % update + bratio = beta / beta_new ; + +% wold = w (k+1:n) ; +% w (k+1:n) = w (k+1:n) - alpha * L (k+1:n,k) ; +% L (k ,k) = bratio * L (k ,k) + gamma*w(k) ; +% L (k+1:n,k) = bratio * L (k+1:n,k) + gamma*wold ; + + L (k,k) = bratio * L (k,k) + gamma*w(k) ; + for i = k+1:n + + wold = w (i) ; + w (i) = w (i) - alpha * L (i,k) ; + L (i,k) = bratio * L (i,k) + gamma*wold ; + + end + + end + + w (k) = alpha ; + + beta = beta_new ; + +end + +norm (w-(Lold\worig)) diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cond1est.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cond1est.m new file mode 100644 index 0000000..1bee865 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cond1est.m @@ -0,0 +1,23 @@ +function c = cond1est (A) +%COND1EST 1-norm condition estimate. +% Example: +% c = cond1est(A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +if (m ~= n | ~isreal (A)) %#ok + error ('A must be square and real') ; +end +if isempty(A) + c = 0 ; + return ; +end +[L,U,P,Q] = lu (A) ; +if (~isempty (find (abs (diag (U)) == 0))) %#ok + c = Inf ; +else + c = norm (A,1) * norm1est (L,U,P,Q) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_fiedler.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_fiedler.m new file mode 100644 index 0000000..5960d30 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_fiedler.m @@ -0,0 +1,27 @@ +function [p,v,d] = cs_fiedler (A) +%CS_FIEDLER the Fiedler vector of a connected graph. +% [p,v,d] = cs_fiedler(A) computes the Fiedler vector v (the eigenvector +% corresponding to the 2nd smallest eigenvalue d of the Laplacian of the graph +% of A+A'). p is the permutation obtained when v is sorted. A should be a +% connected graph. +% +% Example: +% [p,v,d] = cs_fiedler (A) ; +% +% See also CS_SCC, EIGS, SYMRCM, UNMESH. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +if (n < 2) + p = 1 ; v = 1 ; d = 0 ; return ; +end +opt.disp = 0 ; % turn off printing in eigs +opt.tol = sqrt (eps) ; +S = A | A' | speye (n) ; % compute the Laplacian of A +S = diag (sum (S)) - S ; +[v,d] = eigs (S, 2, 'SA', opt) ; % find the Fiedler vector v +v = v (:,2) ; +d = d (2,2) ; +[ignore p] = sort (v) ; % sort it to get p diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand.m new file mode 100644 index 0000000..01398fc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand.m @@ -0,0 +1,15 @@ +function A = cs_frand (n,nel,s) %#ok +%CS_FRAND generate a random finite-element matrix +% A = cs_frand (n,nel,s) creates an n-by-n sparse matrix consisting of nel +% finite elements, each of which are of size s-by-s with random symmetric +% nonzero pattern, plus the identity matrix. +% +% Example +% A = cs_frand (100, 100, 3) ; +% See also cs_demo. + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_frand mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand_mex.c new file mode 100644 index 0000000..6962006 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_frand_mex.c @@ -0,0 +1,60 @@ +#include "cs_mex.h" +/* A = cs_frand (n,nel,s) creates an n-by-n sparse matrix consisting of nel + * finite elements, each of which are of size s-by-s with random symmetric + * nonzero pattern, plus the identity matrix. + * See also MATLAB/Demo/private/frand.m */ + +static +cs *cs_frand (int n, int nel, int s) +{ + int ss = s*s, nz = nel*ss, e, i, j, *P ; + cs *A, *T = cs_spalloc (n, n, nz, 1, 1) ; + if (!T) return (NULL) ; + P = cs_malloc (s, sizeof (int)) ; + if (!P) return (cs_spfree (T)) ; + for (e = 0 ; e < nel ; e++) + { + for (i = 0 ; i < s ; i++) P [i] = rand () % n ; + for (j = 0 ; j < s ; j++) + { + for (i = 0 ; i < s ; i++) + { + cs_entry (T, P [i], P [j], rand () / (double) RAND_MAX) ; + } + } + } + for (i = 0 ; i < n ; i++) cs_entry (T, i, i, 1) ; + A = cs_compress (T) ; + cs_spfree (T) ; + return (cs_dupl (A) ? A : cs_spfree (A)) ; +} + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + int n, nel, s ; + cs *A, *AT ; + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: C = cs_frand(n,nel,s)") ; + } + n = mxGetScalar (pargin [0]) ; + nel = mxGetScalar (pargin [1]) ; + s = mxGetScalar (pargin [2]) ; + + n = CS_MAX (1,n) ; + nel = CS_MAX (1,nel) ; + s = CS_MAX (1,s) ; + + AT = cs_frand (n, nel, s) ; + A = cs_transpose (AT, 1) ; + cs_spfree (AT) ; + cs_dropzeros (A) ; + + pargout [0] = cs_mex_put_sparse (&A) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec.m new file mode 100644 index 0000000..c9709a5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec.m @@ -0,0 +1,12 @@ +function x = cs_ipvec (b,p) %#ok +%CS_IPVEC x(p)=b +% +% Example: +% x = cs_ipvec (b,p) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_ipvec mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec_mex.c new file mode 100644 index 0000000..36b8490 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_ipvec_mex.c @@ -0,0 +1,37 @@ +#include "cs_mex.h" +/* x(p) = b */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + int n, k, *p ; + double *x, *b, *xx ; + + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_ipvec(b,p)") ; + } + + b = mxGetPr (pargin [0]) ; + n = mxGetNumberOfElements (pargin [0]) ; + + if (n != mxGetNumberOfElements (pargin [1])) + { + mexErrMsgTxt ("b or p wrong size") ; + } + + pargout [0] = mxCreateDoubleMatrix (n, 1, mxREAL) ; + + xx = mxGetPr (pargin [1]) ; + p = cs_malloc (n, sizeof (int)) ; + for (k = 0 ; k < n ; k++) p [k] = xx [k] - 1 ; + + x = mxGetPr (pargout [0]) ; + cs_ipvec (p, b, x, n) ; + + cs_free (p) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr.m new file mode 100644 index 0000000..d3f36b5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr.m @@ -0,0 +1,12 @@ +function p = cs_maxtransr(A) %#ok +%CS_MAXTRANSR recursive maximum matching algorithm +% Example: +% p = cs_maxtransr(A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_maxtransr mexFunction not found') ; + + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr_mex.c new file mode 100644 index 0000000..5823049 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_maxtransr_mex.c @@ -0,0 +1,87 @@ +#include "cs_mex.h" +/* find an augmenting path starting at column j and extend the match if found */ +static +int augment (int k, cs *A, int *jmatch, int *cheap, int *w, int j) +{ + int found = 0, p, i = -1, *Ap = A->p, *Ai = A->i ; + /* --- Start depth-first-search at node j ------------------------------- */ + w [j] = k ; /* mark j as visited for kth path */ + for (p = cheap [j] ; p < Ap [j+1] && !found ; p++) + { + i = Ai [p] ; /* try a cheap assignment (i,j) */ + found = (jmatch [i] == -1) ; + } + cheap [j] = p ; /* start here next time for j */ + /* --- Depth-first-search of neighbors of j ----------------------------- */ + for (p = Ap [j] ; p < Ap [j+1] && !found ; p++) + { + i = Ai [p] ; /* consider row i */ + if (w [jmatch [i]] == k) continue ; /* skip col jmatch [i] if marked */ + found = augment (k, A, jmatch, cheap, w, jmatch [i]) ; + } + if (found) jmatch [i] = j ; /* augment jmatch if path found */ + return (found) ; +} + +/* find a maximum transveral */ +static +int *maxtrans (cs *A) /* returns jmatch [0..m-1] */ +{ + int i, j, k, n, m, *Ap, *jmatch, *w, *cheap ; + if (!A) return (NULL) ; /* check inputs */ + n = A->n ; m = A->m ; Ap = A->p ; + jmatch = cs_malloc (m, sizeof (int)) ; /* allocate result */ + w = cs_malloc (2*n, sizeof (int)) ; /* allocate workspace */ + if (!w || !jmatch) return (cs_idone (jmatch, NULL, w, 0)) ; + cheap = w + n ; + for (j = 0 ; j < n ; j++) cheap [j] = Ap [j] ; /* for cheap assignment */ + for (j = 0 ; j < n ; j++) w [j] = -1 ; /* all columns unflagged */ + for (i = 0 ; i < m ; i++) jmatch [i] = -1 ; /* no rows matched yet */ + for (k = 0 ; k < n ; k++) augment (k, A, jmatch, cheap, w, k) ; + return (cs_idone (jmatch, NULL, w, 1)) ; +} + +/* invert a maximum matching */ +static int *invmatch (int *jmatch, int m, int n) +{ + int i, j, *imatch ; + if (!jmatch) return (NULL) ; + imatch = cs_malloc (n, sizeof (int)) ; + if (!imatch) return (NULL) ; + for (j = 0 ; j < n ; j++) imatch [j] = -1 ; + for (i = 0 ; i < m ; i++) if (jmatch [i] >= 0) imatch [jmatch [i]] = i ; + return (imatch) ; +} + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, Amatrix ; + double *x ; + int i, m, n, *imatch, *jmatch ; + + if (nargout > 1 || nargin != 1) + { + mexErrMsgTxt ("Usage: p = cr_maxtransr(A)") ; + } + + /* get inputs */ + A = cs_mex_get_sparse (&Amatrix, 0, 0, pargin [0]) ; + m = A->m ; + n = A->n ; + + jmatch = maxtrans (A) ; + imatch = invmatch (jmatch, m, n) ; /* imatch = inverse of jmatch */ + + pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; + x = mxGetPr (pargout [0]) ; + for (i = 0 ; i < n ; i++) x [i] = imatch [i] + 1 ; + + cs_free (jmatch) ; + cs_free (imatch) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec.m new file mode 100644 index 0000000..4721529 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec.m @@ -0,0 +1,12 @@ +function x = cs_pvec (b,p) %#ok +%CS_PVEC x=b(p) +% +% Example: +% x = cs_pvec (b,p) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_pvec mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec_mex.c new file mode 100644 index 0000000..1a52568 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_pvec_mex.c @@ -0,0 +1,37 @@ +#include "cs_mex.h" +/* x = b(p) */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + int n, k, *p ; + double *x, *b, *xx ; + + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_pvec(b,p)") ; + } + + b = mxGetPr (pargin [0]) ; + n = mxGetNumberOfElements (pargin [0]) ; + + if (n != mxGetNumberOfElements (pargin [1])) + { + mexErrMsgTxt ("b or p wrong size") ; + } + + pargout [0] = mxCreateDoubleMatrix (n, 1, mxREAL) ; + + xx = mxGetPr (pargin [1]) ; + p = cs_malloc (n, sizeof (int)) ; + for (k = 0 ; k < n ; k++) p [k] = xx [k] - 1 ; + + x = mxGetPr (pargout [0]) ; + cs_pvec (p, b, x, n) ; + + cs_free (p) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_q1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_q1.m new file mode 100644 index 0000000..d1fd3ce --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_q1.m @@ -0,0 +1,19 @@ +function Q = cs_q1 (V, Beta, p) +%CS_Q1 construct Q from Householder vectors +% Example: +% Q = cs_q1 (V, beta, p) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (V) ; +Q = speye (m) ; +if (nargin > 2) + Q = Q (:,p) ; +end +for i = 1:m + for k = 1:n + Q (i,:) = Q (i,:) - ((Q(i,:) * V(:,k)) * Beta(k)) * V(:,k)' ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach.m new file mode 100644 index 0000000..a43b727 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach.m @@ -0,0 +1,14 @@ +function x = cs_reach(L,b) %#ok +%CS_REACH non-recursive reach (interface to CSparse cs_reach) +% find nonzero pattern of x=L\sparse(b). L must be sparse, real, and lower +% triangular. b must be a real sparse vector. +% +% Example: +% x = cs_reach(L,b) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +error ('cs_reach mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach_mex.c new file mode 100644 index 0000000..fbdd369 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reach_mex.c @@ -0,0 +1,39 @@ +#include "cs_mex.h" +/* find nonzero pattern of x=L\sparse(b). L must be sparse, real, and lower + * triangular. b must be a real sparse vector. */ + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Lmatrix, Bmatrix, *L, *B ; + double *x ; + int k, i, j, top, *xi, *perm ; + + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_reach(L,b)") ; + } + + /* get inputs */ + L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; + B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ; + cs_mex_check (0, L->n, 1, 0, 1, 1, pargin [1]) ; + perm = cs_malloc (L->n, sizeof (int)) ; + for (k = 0 ; k < L->n ; k++) perm [k] = k ; + + xi = cs_calloc (3*L->n, sizeof (int)) ; + + top = cs_reach (L, B, 0, xi, perm) ; + + pargout [0] = mxCreateDoubleMatrix (L->n - top, 1, mxREAL) ; + x = mxGetPr (pargout [0]) ; + for (j = 0, i = top ; i < L->n ; i++, j++) x [j] = xi [i] ; + + cs_free (xi) ; + cs_free (perm) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr.m new file mode 100644 index 0000000..0ec6977 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr.m @@ -0,0 +1,15 @@ +function x = cs_reachr(L,b) %#ok +%CS_REACHR recursive reach (interface to CSparse cs_reachr) +% find nonzero pattern of x=L\sparse(b). L must be sparse, real, and lower +% triangular. b must be a real sparse vector. +% +% Example: +% x = cs_reachr(L,b) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +error ('cs_reach mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr_mex.c new file mode 100644 index 0000000..c456e9e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_reachr_mex.c @@ -0,0 +1,67 @@ +#include "cs_mex.h" +/* find nonzero pattern of x=L\sparse(b). L must be sparse, real, and lower + * triangular. b must be a real sparse vector. */ + +static +void dfsr (int j, const cs *L, int *top, int *xi, int *w) +{ + int p ; + w [j] = 1 ; /* mark node j */ + for (p = L->p [j] ; p < L->p [j+1] ; p++) /* for each i in L(:,j) */ + { + if (w [L->i [p]] != 1) /* if i is unmarked */ + { + dfsr (L->i [p], L, top, xi, w) ; /* start a dfs at i */ + } + } + xi [--(*top)] = j ; /* push j onto the stack */ +} + +/* w [0..n-1] == 0 on input, <= 1 on output. size n */ +static +int reachr (const cs *L, const cs *B, int *xi, int *w) +{ + int p, n = L->n ; + int top = n ; /* stack is empty */ + for (p = B->p [0] ; p < B->p [1] ; p++) /* for each i in pattern of b */ + { + if (w [B->i [p]] != 1) /* if i is unmarked */ + { + dfsr (B->i [p], L, &top, xi, w) ; /* start a dfs at i */ + } + } + return (top) ; /* return top of stack */ +} + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs Lmatrix, Bmatrix, *L, *B ; + double *x ; + int i, j, top, *xi ; + + if (nargout > 1 || nargin != 2) + { + mexErrMsgTxt ("Usage: x = cs_reachr(L,b)") ; + } + + /* get inputs */ + L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; + B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ; + cs_mex_check (0, L->n, 1, 0, 1, 1, pargin [1]) ; + + xi = cs_calloc (2*L->n, sizeof (int)) ; + + top = reachr (L, B, xi, xi + L->n) ; + + pargout [0] = mxCreateDoubleMatrix (L->n - top, 1, mxREAL) ; + x = mxGetPr (pargout [0]) ; + for (j = 0, i = top ; i < L->n ; i++, j++) x [j] = xi [i] ; + + cs_free (xi) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt.m new file mode 100644 index 0000000..0e7a871 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt.m @@ -0,0 +1,15 @@ +function r = cs_rowcnt(A,parent,post) %#ok +%CS_ROWCNT row counts for sparse Cholesky +% Compute the row counts of the Cholesky factor L of the matrix A. Uses +% the lower triangular part of A. +% +% Example: +% r = cs_rowcnt(A,parent,post) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +error ('cs_rowcnt mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt_mex.c new file mode 100644 index 0000000..74e3370 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_rowcnt_mex.c @@ -0,0 +1,86 @@ +/* Compute the row counts of the Cholesky factor L of the matrix A. Uses + * the lower triangular part of A. */ + +#include "cs_mex.h" + +static +void firstdesc (int n, int *parent, int *post, int *first, int *level) +{ + int len, i, k, r, s ; + for (i = 0 ; i < n ; i++) first [i] = -1 ; + for (k = 0 ; k < n ; k++) + { + i = post [k] ; /* node i of etree is kth postordered node */ + len = 0 ; /* traverse from i towards the root */ + for (r = i ; r != -1 && first [r] == -1 ; r = parent [r], len++) + first [r] = k ; + len += (r == -1) ? (-1) : level [r] ; /* root node or end of path */ + for (s = i ; s != r ; s = parent [s]) level [s] = len-- ; + } +} + +static +int *rowcnt (cs *A, int *parent, int *post) /* return rowcount [0..n-1] */ +{ + int i, j, k, p, q, n, jleaf, *Ap, *Ai, *maxfirst, + *ancestor, *prevleaf, *w, *first, *level, *rowcount ; + n = A->n ; Ap = A->p ; Ai = A->i ; /* get A */ + w = cs_malloc (5*n, sizeof (int)) ; /* get workspace */ + ancestor = w ; maxfirst = w+n ; prevleaf = w+2*n ; first = w+3*n ; + level = w+4*n ; + rowcount = cs_malloc (n, sizeof (int)) ; /* allocate result */ + firstdesc (n, parent, post, first, level) ; /* find first and level */ + for (i = 0 ; i < n ; i++) + { + rowcount [i] = 1 ; /* count the diagonal of L */ + prevleaf [i] = -1 ; /* no previous leaf of the ith row subtree */ + maxfirst [i] = -1 ; /* max first[j] for node j in ith subtree */ + ancestor [i] = i ; /* every node is in its own set, by itself */ + } + for (k = 0 ; k < n ; k++) + { + j = post [k] ; /* j is the kth node in the postordered etree */ + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + q = cs_leaf (i, j, first, maxfirst, prevleaf, ancestor, &jleaf) ; + if (jleaf) rowcount [i] += (level [j] - level [q]) ; + } + if (parent [j] != -1) ancestor [j] = parent [j] ; + } + cs_free (w) ; + return (rowcount) ; +} + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + cs *A, Amatrix ; + double *x ; + int i, n, *parent, *post, *rowcount ; + + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: r = rowcnt(A,parent,post)") ; + } + + /* get inputs */ + A = cs_mex_get_sparse (&Amatrix, 1, 0, pargin [0]) ; + n = A->n ; + + parent = cs_mex_get_int (n, pargin [1], &i, 0) ; + post = cs_mex_get_int (n, pargin [2], &i, 1) ; + + rowcount = rowcnt (A, parent, post) ; + + pargout [0] = mxCreateDoubleMatrix (1, n, mxREAL) ; + x = mxGetPr (pargout [0]) ; + for (i = 0 ; i < n ; i++) x [i] = rowcount [i] ; + + cs_free (rowcount) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2.m new file mode 100644 index 0000000..6a2bc41 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2.m @@ -0,0 +1,15 @@ +function A = cs_sparse2 (i,j,x) %#ok +%CS_SPARSE2 same as cs_sparse, to test cs_entry function +% A = cs_sparse2 (i,j,x), removing duplicates and numerically zero entries, +% and returning A sorted (test cs_entry) +% +% Example: +% A = cs_sparse2 (i,j,x) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +error ('cs_sparse2 mexFunction not found') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2_mex.c b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2_mex.c new file mode 100644 index 0000000..821c08e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_sparse2_mex.c @@ -0,0 +1,41 @@ +#include "cs_mex.h" +/* A = cs_sparse2 (i,j,x), removing duplicates and numerically zero entries, + * and returning A sorted (test cs_entry) */ +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double *Tx ; + cs *A, *C, *T ; + int k, m, n, nz, *Ti, *Tj ; + if (nargout > 1 || nargin != 3) + { + mexErrMsgTxt ("Usage: A = cs_sparse2(i,j,x)") ; + } + nz = mxGetNumberOfElements (pargin [0]) ; + Ti = cs_mex_get_int (nz, pargin [0], &m, 1) ; + Tj = cs_mex_get_int (nz, pargin [1], &n, 1) ; + cs_mex_check (1, nz, 1, 0, 0, 1, pargin [2]) ; + Tx = mxGetPr (pargin [2]) ; + + T = cs_spalloc (n, m, 1, 1, 1) ; + for (k = 0 ; k < nz ; k++) + { + cs_entry (T, Tj [k], Ti [k], Tx [k]) ; + } + + C = cs_compress (T) ; + cs_spfree (T) ; + + cs_dupl (C) ; + cs_dropzeros (C) ; + A = cs_transpose (C, 1) ; + cs_spfree (C) ; + pargout [0] = cs_mex_put_sparse (&A) ; + cs_free (Ti) ; + cs_free (Tj) ; +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_test_make.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_test_make.m new file mode 100644 index 0000000..d44f99c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cs_test_make.m @@ -0,0 +1,33 @@ +function cs_test_make (force) +%CS_TEST_MAKE compiles the CSparse, Demo, and Test mexFunctions. +% The current directory must be CSparse/MATLAB/Test to use this function. +% +% Example: +% cs_test_make +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 1) + force = 0 ; +end + +cd ('../CSparse') ; +[object_files timestamp] = cs_make ; +cd ('../Test') ; + +mexfunc = { 'cs_ipvec', 'cs_pvec', 'cs_sparse2', ... + 'cs_reach', 'cs_maxtransr', 'cs_reachr', 'cs_rowcnt', 'cs_frand' } ; + +for i = 1:length(mexfunc) + [s t tobj] = cs_must_compile ('', mexfunc{i}, '_mex', ... + ['.' mexext], 'cs_test_make.m', force) ; + if (s | tobj < timestamp) %#ok + cmd = ['mex -O -output ' mexfunc{i} ' ' mexfunc{i} '_mex.c -I..' ... + filesep '..' filesep 'Include -I..' ... + filesep 'CSparse ' object_files] ; + fprintf ('%s\n', cmd) ; + eval (cmd) ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/cspy_test.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cspy_test.m new file mode 100644 index 0000000..a7c34e8 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/cspy_test.m @@ -0,0 +1,50 @@ +function cspy_test +%CSPY_TEST test cspy and cs_dmspy +% Example +% cspy_test +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; + +[ignore f] = sort (max (index.nrows, index.ncols)) ; + +clf + +% f = f (523:end) ; +% f = f ((find (f == 938)):end) ; + +for i = f + + Prob = UFget (i,index) ; + disp (Prob) ; + A = Prob.A ; + try + subplot (1,4,1) ; cspy (A) ; + drawnow + subplot (1,4,2) ; cspy (A,64) ; + drawnow + subplot (1,4,3) ; cs_dmspy (A) ; + drawnow + subplot (1,4,4) ; cs_dmspy (A,0) ; + drawnow + catch + fprintf ('failed...\n') ; + end + + [m n] = size (A) ; + if (m == n & nnz (diag (A)) == n) %#ok + p = cs_dmperm (A) ; + if (any (p ~= 1:n)) + error ('!') ; + end + [p q r s cc rr] = cs_dmperm (A) ; %#ok + if (any (p ~= q)) + error ('not sym!') ; + end + end + + drawnow +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmperm_test.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmperm_test.m new file mode 100644 index 0000000..d2cd94f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmperm_test.m @@ -0,0 +1,126 @@ +function dmperm_test +%DMPERM_TEST test cs_dmperm +% +% Example: +% dmperm_test +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; + +f = find (index.nrows ~= index.ncols) ; +[ignore i] = sort (index.nrows(f) ./ index.ncols(f)) ; +f = [209:211 f(i)] ; + +nmat = length(f) ; + +tt1 = zeros (1,nmat) ; +tt2 = zeros (1,nmat) ; +tt3 = zeros (1,nmat) ; +tt4 = zeros (1,nmat) ; +mm = zeros (1,nmat) ; +nn = zeros (1,nmat) ; +ss = zeros (1,nmat) ; +me = zeros (1,nmat) ; +ne = zeros (1,nmat) ; + +p = cs_dmperm (sparse (1)) ; + +for k = 1:length(f) + + i = f(k) ; + + Prob = UFget (i) %#ok + + A = Prob.A ; + [m n] = size (A) ; + if (m > n) + % make sure A is short and fat + A = A' ; + end + % C is tall and thin + C = A' ; + [m n] = size (A) ; + + k1 = 0 ; + t1 = 0 ; + while (t1 < 1) + tic + p = cs_dmperm (A) ; + t = toc ; + t1 = t1 + t ; + k1 = k1 + 1 ; + end + t1 = t1 / k1 ; + s1 = sum (p > 0) ; + + k2 = 0 ; + t2 = 0 ; + while (t2 < 1) + tic + p = cs_dmperm (C) ; + t = toc ; + t2 = t2 + t ; + k2 = k2 + 1 ; + end + t2 = t2 / k2 ; + s2 = sum (p > 0) ; + + k3 = 0 ; + t3 = 0 ; + while (t3 < 1) + tic + p = cs_dmperm_orig (A) ; + t = toc ; + t3 = t3 + t ; + k3 = k3 + 1 ; + end + t3 = t3 / k3 ; + + k4 = 0 ; + t4 = 0 ; + while (t4 < 1) + tic + p = cs_dmperm_orig (A') ; + t = toc ; + t4 = t4 + t ; + k4 = k4 + 1 ; + end + t4 = t4 / k4 ; + + sprnk = sum (p > 0) ; + nempty = full (sum (sum (spones (A)) == 0)) ; + mempty = full (sum (sum (spones (C)) == 0)) ; + + fprintf ('[m %d:%d n %d:%d (%d)]:\n', m, mempty, n, nempty, sprnk) ; + fprintf (' A: t1 %10.6f (%6d) C: t2 %10.6f (%6d) new\n', ... + t1, k1, t2, k2) ; + fprintf (' A: t3 %10.6f (%6d) C: t4 %10.6f (%6d) orig\n', ... + t3, k3, t4, k4) ; + + if (s1 ~= sprnk | s2 ~= sprnk) %#ok + s1 %#ok + s2 %#ok + sprnk %#ok + error ('!') ; + end + + tt1 (k) = t1 ; + tt2 (k) = t2 ; + tt3 (k) = t3 ; + tt4 (k) = t4 ; + mm (k) = m ; + nn (k) = n ; + ss (k) = sprnk ; + me (k) = mempty ; + ne (k) = nempty ; + + clear A C + + semilogy (ss(1:k) ./ nn(1:k), tt1(1:k) ./ tt3(1:k), 'o', ... + [0 1], [1 1], 'r-') ; + drawnow + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmspy_test.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmspy_test.m new file mode 100644 index 0000000..b9d4617 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/dmspy_test.m @@ -0,0 +1,28 @@ +function dmspy_test +%DMSPY_TEST test cspy, cs_dmspy, and cs_dmperm +% Example: +% dmspy_test +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +index = UFget ; +f = find (index.nblocks > 1) ; +% f = find (index.nblocks > 1 & index.nrows == index.ncols & ... +% index.nnzdiag == index.nrows) ; +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +for i = f + Prob = UFget (i,index) ; + disp (Prob) ; + clf + subplot (2,2,1) ; cspy (Prob.A) ; + subplot (2,2,2) ; cs_dmspy (Prob.A) ; + [p,q,r,s,cc,rr] = cs_dmperm (Prob.A) ; %#ok + subplot (2,2,3) ; plot (p) ; + subplot (2,2,4) ; plot (q) ; + drawnow +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/etree_sample.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/etree_sample.m new file mode 100644 index 0000000..11177c4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/etree_sample.m @@ -0,0 +1,71 @@ +function etree_sample +% ETREE_SAMPLE construct a sample etree and symbolic factorization +% +% Example +% etree_sample +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +clf + +% desired etree: +% 1 2 3 4 5 6 7 8 9 10 11 +goal = [6 3 8 6 8 7 9 10 10 11 0] ; + +o = 0 ; +X = 1 ; +x = 0 ; + +A = [ +1 o o o o o o o o o o +o 2 o o o o o o o o o +o X 3 o o o o o o o o +o o o 4 o o o o o o o +o o o o 5 o o o o o o +X o o X o 6 o o o o o +X o o x o x 7 o o o o +o X x o X o o 8 o o o +x o o x o X x o 9 o o +x x X X x X x X x 10 o +x x X x X x X X x X 11 ] ; + +A = A + tril(A,-1)' ; +disp ('A = ') ; +disp (A) + +[count,h,parent,post,R] = symbfact (A) ; +L = R' ; + +subplot (2,3,1) ; +spy (A) +title ('A') ; + +subplot (2,3,2) ; +etreeplot (A) +title ('etree') ; + +% [parent, post] = etree (A) ; + +subplot (2,3,3) ; +spy (L) +title ('L, not postordered') ; + +n = size (A,1) ; +for k = 1:n + fprintf ('parent (%d) = %d goal: %d ok: %d\n', ... + k, parent (k), goal (k), goal (k) == parent(k)) ; +end + + +[count,h,parent2,post2,R] = symbfact (A (post,post)) ; +L = R' ; + +subplot (2,3,5) ; +spy (A (post,post)) +title ('A postordered') ; + +subplot (2,3,6) ; +spy (L) +title ('L postordered') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/givens2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/givens2.m new file mode 100644 index 0000000..5420101 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/givens2.m @@ -0,0 +1,17 @@ +function g = givens2(a,b) +%GIVENS2 find a Givens rotation. +% Example: +% g = givens2(a,b) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +if (b == 0) + c = 1 ; s = 0 ; +elseif (abs (b) > abs (a)) + tau = -a/b ; s = 1 / sqrt (1+tau^2) ; c = s*tau ; +else + tau = -b/a ; c = 1 / sqrt (1+tau^2) ; s = c*tau ; +end +g = [c -s ; s c] ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/gqr3.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/gqr3.m new file mode 100644 index 0000000..ec85720 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/gqr3.m @@ -0,0 +1,30 @@ +function R = gqr3 (A) +%GQR3 QR factorization, based on Givens rotations +% +% Example: +% R = gqr3 (A) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +[m n] = size (A) ; + +% parent = cs_etree (sparse (A), 'col') ; + +for i = 2:m + % i + for k = 1:min(i-1,n) + % k + % Givens rotation to zero out A(i,k) using A(k,k) + G = givens2 (A(k,k), A(i,k)) ; + A ([k i],k:n) = G * A ([k i],k:n) ; + A (i,k) = 0 ; + % fprintf ('A(21,25)=%g\n', A(21,25)) ; + % if (A(21,25) ~= 0) + % pause + % end + end +end +R = A ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/happly.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/happly.m new file mode 100644 index 0000000..770c5d9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/happly.m @@ -0,0 +1,11 @@ +function hx = happly (v, beta, x) +%HAPPLY apply Householder reflection to a vector +% Example: +% hx = happly (v,beta,x) ; % computes hx = x - v * (beta * (v' *x)) ; +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +hx = x - v * (beta * (v' *x)) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/hmake1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/hmake1.m new file mode 100644 index 0000000..63d85ed --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/hmake1.m @@ -0,0 +1,39 @@ +function [v,beta,xnorm] = hmake1 (x) +%HMAKE1 construct a Householder reflection +% Example: +% [v,beta,xnorm] = hmake1 (x) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = length (x) ; +if (n == 1) + v = 1 ; + xnorm = norm (x) ; + if (x (1) < 0) + beta = 2 ; + else + beta = 0 ; + end + return +end +sigma = x (2:n)'*x(2:n) ; +xnorm = sqrt (x (1)^2 + sigma) ; +v = x ; +if (sigma == 0) + v (1) = 1 ; + if (x (1) < 0) + beta = 2 ; + else + beta = 0 ; + end +else + if (x (1) <= 0) + v (1) = x(1) - xnorm ; + else + v (1) = -sigma / (x(1) + xnorm) ; + end + beta = (2*v(1)^2) / (sigma + v(1)^2) ; + v = v / v(1) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/house.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/house.m new file mode 100644 index 0000000..9b0590a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/house.m @@ -0,0 +1,29 @@ +function [v,beta,s] = house (x) +%HOUSE find a Householder reflection. +% Example: +% [v,beta,s] = house (x) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = length (x) ; +if (n == 1) + sigma = 0 ; +else + sigma = x (2:n)' * x (2:n) ; +end +v = x ; +if (sigma == 0) + s = x (1) ; + v (1) = 0 ; + beta = 0 ; +else + s = sqrt (x(1)^2 + sigma) ; + if (x (1) <= 0) + v (1) = x (1) - s ; + else + v (1) = -sigma / (x (1) + s) ; + end + beta = -1 / (s * v(1)) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_left.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_left.m new file mode 100644 index 0000000..650dc64 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_left.m @@ -0,0 +1,25 @@ +function [L,U,P] = lu_left (A) +%LU_LEFT left-looking LU factorization. +% Example: +% [L,U,P] = lu_left (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +P = eye (n) ; +L = zeros (n) ; +U = zeros (n) ; +for k = 1:n + x = [ L(:,1:k-1) [ zeros(k-1,n-k+1) ; eye(n-k+1) ]] \ (P * A (:,k)) ; + U (1:k-1,k) = x (1:k-1) ; % the column of U + [a i] = max (abs (x (k:n))) ; % find the pivot row i + i = i + k - 1 ; + L ([i k],:) = L ([k i], :) ; % swap rows i and k of L, P, and x + P ([i k],:) = P ([k i], :) ; + x ([i k]) = x ([k i]) ; + U (k,k) = x (k) ; + L (k,k) = 1 ; + L (k+1:n,k) = x (k+1:n) / x (k) ; % divide the pivot column by U(k,k) +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_right.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_right.m new file mode 100644 index 0000000..ef2f9eb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_right.m @@ -0,0 +1,17 @@ +function [L,U] = lu_right (A) +%LU_RIGHT right-looking LU factorization. +% Example: +% [L,U] = lu_right (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +L = eye (n) ; +U = zeros (n) ; +for k = 1:n + U (k,k:n) = A (k,k:n) ; % (6.4) and (6.5) + L (k+1:n,k) = A (k+1:n,k) / U (k,k) ; % (6.6) + A (k+1:n,k+1:n) = A (k+1:n,k+1:n) - L (k+1:n,k) * U (k,k+1:n) ; % (6.7) +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightp.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightp.m new file mode 100644 index 0000000..402781b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightp.m @@ -0,0 +1,22 @@ +function [L,U,P] = lu_rightp (A) +%LU_RIGHTP right-looking LU factorization, with partial pivoting. +% +% Example: +% [L,U,P] = lu_rightp (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +P = eye (n) ; +for k = 1:n + [x,i] = max (abs (A (k:n,k))) ; % partial pivoting + i = i+k-1 ; + P ([k i],:) = P ([i k], :) ; + A ([k i],:) = A ([i k], :) ; % (6.10), (6.11) + A (k+1:n,k) = A (k+1:n,k) / A (k,k) ; % (6.12) + A (k+1:n,k+1:n) = A (k+1:n,k+1:n) - A (k+1:n,k) * A (k,k+1:n) ; % (6.9) +end +L = tril (A,-1) + eye (n) ; +U = triu (A) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightpr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightpr.m new file mode 100644 index 0000000..322e626 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightpr.m @@ -0,0 +1,29 @@ +function [L,U,P] = lu_rightpr (A) +%LU_RIGHTPR recursive right-looking LU, with partial pivoting. +% +% Example: +% [L,U,P] = lu_rightpr (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +if (n == 1) + P = 1 ; + L = 1 ; + U = A ; +else + [x,i] = max (abs (A (1:n,1))) ; % partial pivoting + P1 = eye (n) ; + P1 ([1 i],:) = P1 ([i 1], :) ; + A = P1*A ; + u11 = A (1,1) ; % (6.10) + u12 = A (1,2:n) ; % (6.11) + l21 = A (2:n,1) / u11 ; % (6.12) + [L22,U22,P2] = lu_rightpr (A (2:n,2:n) - l21*u12) ; % (6.9) or (6.13) + o = zeros(1,n-1) ; + L = [ 1 o ; P2*l21 L22 ] ; % (6.14) + U = [ u11 u12 ; o' U22 ] ; + P = [ 1 o ; o' P2] * P1 ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightr.m new file mode 100644 index 0000000..67a9fbd --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/lu_rightr.m @@ -0,0 +1,21 @@ +function [L,U] = lu_rightr (A) +%LU_RIGHTR recursive right-looking LU. +% Example: +% [L,U] = lu_rightr (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (A,1) ; +if (n == 1) + L = 1 ; + U = A ; +else + u11 = A (1,1) ; % (6.4) + u12 = A (1,2:n) ; % (6.5) + l21 = A (2:n,1) / u11 ; % (6.6) + [L22,U22] = lu_rightr (A (2:n,2:n) - l21*u12) ; % (6.7) + L = [ 1 zeros(1,n-1) ; l21 L22 ] ; + U = [ u11 u12 ; zeros(n-1,1) U22 ] ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/mynormest1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/mynormest1.m new file mode 100644 index 0000000..9993d24 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/mynormest1.m @@ -0,0 +1,92 @@ +function est = mynormest1 (L, U, P, Q) +%MYNORMEST1 estimate norm(A,1), using LU factorization (L*U = P*A*Q). +% +% Example: +% est = mynormest1 (L, U, P, Q) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +n = size (L,1) ; +est = 0 ; +S = zeros (n,1) ; + +for k = 1:5 + + if k == 1 + x = ones (n,1) / n ; + else + + j = find (abs (x) == max (abs (x))) ; + j = j (1) ; + x = zeros (n,1) ; + x (j) = 1 ; + + % fprintf ('eka: k %d j %d est %g\n', k, j, est) ; + end + + + % x=A\x, but use the existing P*A*Q=L*U factorization + + x = Q * (U \ (L \ (P*x))) ; + + est_old = est ; + est = sum (abs (x)) ; + + unchanged = 1 ; + for i = 1:n + if (x (i) >= 0) + s = 1 ; + else + s = -1 ; + end + if (s ~= S (i)) + S (i) = s ; + unchanged = 0 ; + end + end + + if (any (S ~= signum (x))) + S' %#ok + signum(x)' %#ok + error ('Hey!') ; + end + + if k > 1 & (est <= est_old | unchanged) %#ok + break ; + end + x = S ; + + % x=A'\x, but use the existing P*A*Q=L*U factorization + x = P' * (L' \ (U' \ (Q'*x))) ; + + if k > 1 + jnew = find (abs (x) == max (abs (x))) ; + if (jnew == j) + break ; + end + end + +end + +for k = 1:n + x (k) = power (-1, k+1) * (1 + ((k-1)/(n-1))) ; +end + +% x=A\x, but use the existing P*A*Q=L*U factorization +x = Q * (U \ (L \ (P*x))) ; + +est_new = 2 * sum (abs (x)) / (3 * n) ; +if (est_new > est) + est = est_new ; +end + + + + +function s = signum (x) +%SIGNUM compute sign of x +s = ones (length (x),1) ; +s (find (x < 0)) = -1 ; %#ok diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/myqr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/myqr.m new file mode 100644 index 0000000..25a1212 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/myqr.m @@ -0,0 +1,56 @@ +function [H,R] = myqr (A) +%MYQR QR factorization using Householder reflections +% uses function [v,beta,xnorm] = hmake1 (x) +% and function hx = happly (v, beta, x) +% +% Example +% [H,R] = myqr (A) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +[m n] = size (A) ; + +H = zeros (m,n) ; +R = zeros (m,n) ; + +for k = 1:n + + % apply prior H's + % fprintf ('\n-----------------init %d\n', k) ; + x = A (:,k) ; + for i = 1:k-1 + v = H(((i+1):m),i) ; + v = [1 ; v] ; %#ok + beta = H (i,i) ; + % n1 = norm (x (i:m)) ; + x (i:m) = happly (v, beta, x (i:m)) ; + % n2 = norm (x (i:m)) ; + % fprintf ('=============== i %d %g %g\n', i, n1, n2) ; + % beta + % v' + % X = x' + % pause + % i + % x + end + % k + % x + + % make Hk + % fprintf ('x(k:m) = ') ; x (k:m) + [v,beta,xnorm] = hmake1 (x (k:m)) ; + + H (k,k) = beta ; + H (k+1:m, k) = v (2:end) ; + + R (1:(k-1),k) = x (1:(k-1)) ; + R (k,k) = xnorm ; + % full (R) + % pause +end + +% s2 = svd (full (R)) ; +% [s1 s2 s1-s2] diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/norm1est.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/norm1est.m new file mode 100644 index 0000000..a1859ae --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/norm1est.m @@ -0,0 +1,34 @@ +function est = norm1est (L,U,P,Q) +%NORM1EST 1-norm estimate. +% Example: +% est = norm1est (L,U,P,Q) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +n = size (L,1) ; +for k = 1:5 + if (k == 1) + est = 0 ; + x = ones (n,1) / n ; + jold = -1 ; + else + j = min (find (abs (x) == norm (x,inf))) ; %#ok + if (j == jold) + break + end ; + x = zeros (n,1) ; + x (j) = 1 ; + jold = j ; + end + x = Q * (U \ (L \ (P*x))) ; + est_old = est ; + est = norm (x,1) ; + if (k > 1 & est <= est_old) %#ok + break + end ; + s = ones (n,1) ; + s (find (x < 0)) = -1 ; %#ok + x = P' * (L' \ (U' \ (Q'*s))) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr2.m new file mode 100644 index 0000000..d9b19a5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr2.m @@ -0,0 +1,21 @@ +function [V,Beta,R] = qr2 (A) +%QR2 QR factorization based on Householder reflections +% +% Example: +% [V,beta,R] = qr2 (A) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +V = zeros (m,n) ; +Beta = zeros (1,n) ; +for k = 1:n + % [v,beta,s] = gallery ('house', A (k:m,k), 2) ; + [v,beta] = house (A (k:m,k)) ; + V (k:m,k) = v ; + Beta (k) = beta ; + A (k:m,k:n) = A (k:m,k:n) - v * (beta * (v' * A (k:m,k:n))) ; +end +R = triu (A) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens.m new file mode 100644 index 0000000..58afded --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens.m @@ -0,0 +1,24 @@ +function R = qr_givens (A) +%QR_GIVENS Givens-rotation QR factorization. +% Example: +% R = qr_givens (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +parent = cs_etree (sparse (A), 'col') ; +A = full (A) ; +for i = 2:m + k = min (find (A (i,:))) ; %#ok + if (isempty (k)) + continue ; + end + while (k > 0 & k <= min (i-1,n)) %#ok + A ([k i],k:n) = givens2 (A(k,k), A(i,k)) * A ([k i],k:n) ; + A (i,k) = 0 ; + k = parent (k) ; + end +end +R = sparse (A) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens_full.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens_full.m new file mode 100644 index 0000000..ff23d62 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_givens_full.m @@ -0,0 +1,17 @@ +function R = qr_givens_full (A) +%QR_GIVENS_FULL Givens-rotation QR factorization, for full matrices. +% Example: +% R = qr_givens_full (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +for i = 2:m + for k = 1:min(i-1,n) + A ([k i],k:n) = givens2 (A(k,k), A(i,k)) * A ([k i],k:n) ; + A (i,k) = 0 ; + end +end +R = A ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_left.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_left.m new file mode 100644 index 0000000..2ee6419 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_left.m @@ -0,0 +1,26 @@ +function [V,Beta,R] = qr_left (A) +%QR_LEFT left-looking Householder QR factorization. +% Example: +% [V,Beta,R] = qr_left (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +V = zeros (m,n) ; +Beta = zeros (1,n) ; +R = zeros (m,n) ; +for k = 1:n + x = A (:,k) ; + for i = 1:k-1 + v = V (i:m,i) ; + beta = Beta (i) ; + x (i:m) = x (i:m) - v * (beta * (v' * x (i:m))) ; + end + [v,beta,s] = gallery ('house', x (k:m), 2) ; + V (k:m,k) = v ; + Beta (k) = beta ; + R (1:(k-1),k) = x (1:(k-1)) ; + R (k,k) = s ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_right.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_right.m new file mode 100644 index 0000000..24de54c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/qr_right.m @@ -0,0 +1,19 @@ +function [V,Beta,R] = qr_right (A) +%QR_RIGHT right-looking Householder QR factorization. +% Example: +% [V,Beta,R] = qr_right (A) +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +[m n] = size (A) ; +V = zeros (m,n) ; +Beta = zeros (1,n) ; +for k = 1:n + [v,beta] = gallery ('house', A (k:m,k), 2) ; + V (k:m,k) = v ; + Beta (k) = beta ; + A (k:m,k:n) = A (k:m,k:n) - v * (beta * (v' * A (k:m,k:n))) ; +end +R = A ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/sample_colormap.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/sample_colormap.m new file mode 100644 index 0000000..a762b7c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/sample_colormap.m @@ -0,0 +1,41 @@ +function sample_colormap +%SAMPLE_COLORMAP try a colormap for use in cspy +% +% Example: +% sample_colormap +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +h = jet (64) ; +h = h (64:-1:1,:) ; +h = h (20:end,:) ; + +% h = h (17:128,:) ; + +% s = sum (jet,2) ; +% h (:,1) = h (:,1) ./ s ; +% h (:,2) = h (:,2) ./ s ; +% h (:,3) = h (:,3) ./ s ; + +h (1,:) = [1 1 1] ; % white +h (2,:) = [1 1 .8] ; % light yellow + +% h +colormap (h) ; + +clf +subplot (5,1,1) ; +image (1:size(h,1)) ; + +h = rgb2hsv (h) ; +% h (:,3) = linspace (1,0,64) ; +% h= hsv2rgb (h) ; + +subplot (5,1,2) ; plot (h(:,1)) ; axis ([1 64 0 1]) ; ylabel ('red') ; +subplot (5,1,3) ; plot (h(:,2)) ; axis ([1 64 0 1]) ; ylabel ('green') ; +subplot (5,1,4) ; plot (h(:,3)) ; axis ([1 64 0 1]) ; ylabel ('blue') ; +subplot (5,1,5) ; plot (sum(h,2)) ; axis ([1 64 0 3]) ; ylabel ('sum') ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/signum.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/signum.m new file mode 100644 index 0000000..1c6c4db --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/signum.m @@ -0,0 +1,13 @@ +function s = signum (x) +%SIGNUM compute and display the sign of a column vector x +% Example +% s = signum(x) +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +s = ones (length (x),1) ; +s (find (x < 0)) = -1 ; %#ok +disp ('s =') ; +disp (s) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/sqr_example.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/sqr_example.m new file mode 100644 index 0000000..9c07379 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/sqr_example.m @@ -0,0 +1,29 @@ +function sqr_example +%SQR_EXAMPLE test cs_sqr +% Example: +% sqr_example +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +Prob = UFget (706) ; + +A = Prob.A' ; +q = colamd (A) ; +A = A (:,q) ; +A = sprandn (A) ; +[m n] = size (A) ; + +[vnz, rnz, parent, c, leftmost, p] = cs_sqr(A) ; + +m2 = length (p) ; +B = [A ; sparse(m2-m,n)] ; +B = B (p,q) ; + +R1 = gqr3 (B) ; + +clf +subplot (2,2,1) ; spy(A) +subplot (2,2,3) ; spy (chol (A'*A + 100*speye(n))) ; +subplot (2,2,4) ; spy (R1) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test1.m new file mode 100644 index 0000000..7c4bad6 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test1.m @@ -0,0 +1,71 @@ +function test1 +%TEST1 test cs_transpose +% +% Example: +% test1 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +for ii = f + Prob = UFget (ii) ; + disp (Prob) ; + A = Prob.A ; + if (~isreal (A)) + continue + end + B = A' ; + + C = cs_transpose (A) ; + if (nnz (B-C) ~= 0) + error ('!') + end + + [m n] = size (A) ; + % if (m == n) + x = rand (n,1) ; + y = rand (m,1) ; + z = y+A*x ; + q = cs_gaxpy (A,x,y) ; + err = norm (z-q,1) / norm (z,1) ; + disp (err) ; + if (err > 1e-14) + error ('!') + end + % end + + + [i j x] = find (A) ; + p = randperm (length (i)) ; + i = i (p) ; + j = j (p) ; + x = x (p) ; + if (m == 1) + % find returns rows vectors if A is 1-by-n, + % but cs_sparse requires column vectors + i = i (:) ; + j = j (:) ; + x = x (:) ; + end + D = sparse (i,j,x) ; + E = cs_sparse (i,j,x) ; + % [i j x] + F = cs_sparse2 (i,j,x) ; + if (nnz (D-E) ~= 0) + error ('!') + end + if (nnz (F-E) ~= 0) + error ('!') + end + + clear A B C D E F + % pause + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test10.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test10.m new file mode 100644 index 0000000..ac6598c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test10.m @@ -0,0 +1,96 @@ +function test10 +%TEST10 test cs_qr +% +% Example: +% test10 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +rand ('state', 0) ; + + +% f = 185 ; +% f = 449 ; +clf + +for trials = 1:100 + + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + d = 0.1 * rand (1) ; + A = sprandn (m, n, d) ; + [m n] = size (A) ; + if (m < n) + A = A' ; + end + [m n] = size (A) ; + sp = sprank (A) ; + % if (sp < n) + % continue ; + % end + + Aorig = A ; + + % A = A (:, colamd (A)) ; + + tic ; + R = qr (A) ; + t1 = toc ; + + % tic ; + % [Q,R] = qr (A) ; + % t1 = toc ; + + [c,h,parent] = symbfact (A, 'col') ; %#ok + rnz = sum (c) ; %#ok + tic ; + [V2,Beta2,p,R2] = cs_qr (sparse(A)) ; + t2 = toc ; + + C = A ; + m2 = size (V2,1) ; + if (m2 > m) + C = [A ; sparse(m2-m, n)] ; + end + C = C (p,:) ; + + [H1,R1] = myqr (C) ; + err1 = norm (R1-R2,1) / norm (R1) ; + disp ('err1 = ') ; + disp (err1) ; + % [svd(A) svd(R1) svd(full(R2))] + s1 = svd (full (A)) ; + s2 = svd (full (R2)) ; + if (n > 0) + err2 = norm (s1 - s2) / s1 (1) ; + disp ('err2 = ') ; + disp (err2) ; + else + err2 = 0 ; + end + fprintf ('%10.6f %10.6f cs speedup %8.3f sprank %d vs %d\n', t1, t2, t1/t2, sp, n) ; + + % H2 = full (H2) + % R2 = full (R2) + + subplot (2,4,1) ; spy (A) ; title ('A colamd') ; + subplot (2,4,4) ; spy (Aorig) ; title ('Aorig') ; + subplot (2,4,2) ; spy (C) ; title ('A rperm') ; + subplot (2,4,5) ; spy (abs(R2)>0) ; title ('spqr R, no zeros') ; + subplot (2,4,6) ; spy (R) ; title ('matlab R') ; + subplot (2,4,7) ; spy (R2) ; title ('spqr R') ; + subplot (2,4,8) ; spy (V2) ; title ('spqr H') ; + drawnow + + if (err2 > 1e-9) + error ('!') ; + end + + if (m2 > m) + fprintf ('added %d rows, sprank %d n %d\n', m2-m, sp, n) ; + end +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test11.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test11.m new file mode 100644 index 0000000..fc08907 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test11.m @@ -0,0 +1,50 @@ +function test11 +%TEST11 test cs_rowcnt +% +% Example: +% test11 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +clear functions +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:200) ; + +for i = f + Prob = UFget (i, index) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (~isreal (A) | m ~= n) %#ok + continue + end + + A = spones (A) ; + A = A+A' + speye(n) ; + + [cc h pa po R] = symbfact (A) ; + rc1 = full (sum (R)) ; + rc2 = cs_rowcnt (A, pa, po) ; + if (any (rc1 ~= rc2)) + error ('!') ; + end + + try + p = amd (A) ; + catch + p = symamd (A) ; + end + A = A (p,p) ; + + [cc h pa po R] = symbfact (A) ; + rc1 = full (sum (R)) ; + rc2 = cs_rowcnt (A, pa, po) ; + if (any (rc1 ~= rc2)) + error ('!') ; + end + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test12.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test12.m new file mode 100644 index 0000000..b5ad075 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test12.m @@ -0,0 +1,44 @@ +function test12 +%TEST12 test cs_qr and compare with svd +% +% Example: +% test12 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +fprintf ('test 12\n') ; +rand ('state',0) ; +% A = rand (3,4) + +for trial = 1:100 + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + d = .1 * rand (1) ; + A = sprandn (m,n,d) ; + fprintf ('m %d n %d nnz %d\n', m, n, nnz(A)) ; + if (m < n) + continue ; + end + if (m == 0 | n == 0) %#ok + continue ; + end + % save A A + fprintf ('[ ') ; + [V,Beta,p,R] = cs_qr (A) ; + % [Q,R] = svd (full(A)) ; + fprintf (']\n') ; + + s1 = svd (full (A)) ; + s2 = svd (full (R)) ; + s2 = s2 (1:length(s1)) ; + err = norm (s1-s2) ; + if (length (s1) > 1) + err = err / s1 (1) ; + end + fprintf ('err %g\n', err) ; + if (err > 1e-12) + error ('!') ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test13.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test13.m new file mode 100644 index 0000000..0b2d8e6 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test13.m @@ -0,0 +1,82 @@ +function test13 +%TEST13 test cs_counts, cs_etree +% +% Example: +% test13 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions +randn ('state',0) ; +rand ('state',0) ; + +for trial = 1:100 + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + d = .1 * rand (1) ; + A = sprandn (n,n,d) ; + C = sprandn (m,n,d) ; + A = A+A' ; + fprintf ('m %4d n %4d nnz(A) %6d nnz(C) %6d\n', m, n, nnz(A), nnz(C)) ; + + [p1,po1] = etree (A) ; + + [p2,po2] = cs_etree (A) ; + [p3,po3] = cs_etree (A, 'sym') ; + % po2 = cs_post (p2) ; + + check_if_same (p1,p2) ; + check_if_same (po1,po2) ; + + check_if_same (p1,p3) ; + check_if_same (po1,po3) ; + + c1 = symbfact (A) ; + c2 = cs_counts (A) ; + + % A-A' + + check_if_same (c1,c2) ; + + c2 = cs_counts (triu (A)) ; + check_if_same (c1,c2) ; + % pause + + p0 = etree (A, 'col') ; + % p1 = etree2 (A, 'col') ; % CHOLMOD + p2 = cs_etree (A, 'col') ; + + if (~isempty (A)) + check_if_same (p0,p2) ; + end + + p0 = etree (C, 'col') ; + % p1 = etree2 (C, 'col') ; % CHOLMOD + p2 = cs_etree (C, 'col') ; + + if (~isempty (C)) + check_if_same (p0,p2) ; + end + + % find etree of A'A, and postorder it + [m n] = size (A) ; %#ok + % full (A) + + [cp0 cpo0] = etree (A, 'col') ; + % [cp1 cpo1] = etree2 (A, 'col') ; % CHOLMOD + [cp2 cpo2] = cs_etree (A, 'col') ; + % cpo2 = cs_post (cp2) ; + + check_if_same (cp0, cp2) ; + check_if_same (cpo0, cpo2) ; + + c0 = symbfact (A, 'col') ; + % c1 = symbfact2 (A, 'col') ; % CHOLMOD + c2 = cs_counts (A, 'col') ; + + check_if_same (c0, c2) ; + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test14.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test14.m new file mode 100644 index 0000000..990c0d0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test14.m @@ -0,0 +1,38 @@ +function test14 +%TEST14 test cs_droptol +% +% Example: +% test14 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +rand ('state', 0) ; + +for trial = 1:100 + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + d = 0.1*rand (1) ; + A = sprandn (m,n,d) ; + [i j x] = find (A) ; + A = sparse (i,j,2*x-1) ; + fprintf ('test14 m %3d n %3d nz %d\n', m, n, nnz (A)) ; + + % using CSparse + tol = 0.5 ; + B = cs_droptol (A, tol) ; + + % using MATLAB + A = A .* (abs (A) > tol) ; +% [m n] = size (A) ; +% s = abs (A) > tol ; +% [i j] = find (s) ; +% x = A (find (s)) ; +% A = sparse (i, j, x, m, n) ; + + if (norm (A-B,1) > 0) + error ('!') ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test15.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test15.m new file mode 100644 index 0000000..c88d90c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test15.m @@ -0,0 +1,48 @@ +function test15 +%TEST15 test cs_amd +% +% Example: +% test15 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +rand ('state', 0) ; +randn ('state', 0) ; +clf + +for trials = 1:100 + n = fix (200 * rand (1)) ; + d = 0.05 * rand (1) ; + A = sprandn (n, n, d) ; + + % add a randomly placed dense column + k = fix (n * rand (1)) ; + k = max (1, k) ; + k = min (n, k) ; + A (:,k) = 1 ; + + try + p0 = amd (A) ; + catch + p0 = symamd (A) ; + end + p1 = cs_amd (A) ; + + if (any (sort (p1) ~= 1:n)) + error ('not perm!') ; + end + + C = A+A' + speye (n) ; + lnz0 = sum (symbfact (C (p0,p0))) ; + lnz1 = sum (symbfact (C (p1,p1))) ; + subplot (1,3,1) ; spy (C) + subplot (1,3,2) ; spy (C (p0,p0)) + subplot (1,3,3) ; spy (C (p1,p1)) + fprintf ('n %4d nz %6d lnz %6d %6d\n', n, nnz(A), lnz0, lnz1) ; + drawnow + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test16.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test16.m new file mode 100644 index 0000000..d348c37 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test16.m @@ -0,0 +1,90 @@ +function test16 +%TEST16 test cs_amd +% +% Example: +% test16 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +rand ('state', 0) ; +randn ('state', 0) ; +clf + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:200) ; +skip = 811 ; + +% f = 719 + +for i = f + if (any (i == skip)) + continue + end + Prob = UFget (i) ; + A = spones (Prob.A) ; + Aorig = A ; + [m n] = size (A) ; + if (m < n) + A = A' ; + end + [m n] = size (A) ; + if (m ~= n) + A = A'*A ; + end + + fprintf ('n %4d nz %d\n', n, nnz (A)) ; + + try + p0 = amd (A) ; + catch + p0 = symamd (A) ; + end + fprintf ('symmetric case:\n') ; + p1 = cs_amd (A) ; + + if (any (sort (p1) ~= 1:n)) + error ('not perm!') ; + end + + C = A+A' + speye (n) ; + lnz0 = sum (symbfact (C (p0,p0))) ; + lnz1 = sum (symbfact (C (p1,p1))) ; + subplot (2,3,1) ; spy (C) + subplot (2,3,2) ; spy (C (p0,p0)) ; title ('amd') ; + subplot (2,3,3) ; spy (C (p1,p1)) ; title ('csamd') ; + drawnow + + if (lnz0 ~= lnz1) + fprintf ('----------------- lnz %d %d %9.4f\n', ... + lnz0, lnz1, 100*(lnz0-lnz1)/max([1 lnz0])) ; + end + + if (1) + + p0 = colamd (Aorig) ; + [m n] = size (Aorig) ; + fprintf ('m %d n %d\n', m, n) ; + + fprintf ('A''A case, no dense rows (for QR):\n') ; + p1 = cs_amd (Aorig, 3) ; + if (any (sort (p1) ~= 1:n)) + error ('not perm!') ; + end + + subplot (2,3,4) ; spy (Aorig) + subplot (2,3,5) ; spy (Aorig (:,p0)) ; title ('colamd') ; + subplot (2,3,6) ; spy (Aorig (:,p1)) ; title ('cs amd(A''A)') ; + lnz0 = sum (symbfact (Aorig (:,p0), 'col')) ; + lnz1 = sum (symbfact (Aorig (:,p1), 'col')) ; + fprintf (' A''A: %7d %7d %9.4f\n', ... + lnz0, lnz1, 100*(lnz0-lnz1)/max([1 lnz0])) ; + drawnow + + % pause + + end +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test17.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test17.m new file mode 100644 index 0000000..f797f5d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test17.m @@ -0,0 +1,108 @@ +function test17 +%TEST17 test cs_qr, cs_qright, cs_q1, cs_qrleft, cs_qrsol +% +% Example: +% test17 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions +clf + +rand ('state', 0) ; +randn ('state', 0) ; + +for trials = 1:100 + + m = 1 + fix (10 * rand (1)) ; + n = 1 + fix (10 * rand (1)) ; + d = rand (1) ; +% n = m ; + + A = sprandn (m, n, d) ; + if (m < n) + A = A' ; + end + [m n] = size (A) ; + + subplot (3,4,1) ; spy (A) ; + + [V1, Beta1, p1, R1, q1] = cs_qr (A) ; + Q1 = cs_qright (V1, Beta1, p1, speye (size (V1,1))) ; + Q1b = cs_q1 (V1, Beta1, p1) ; + + err = norm (Q1-Q1b,1) ; + disp ('err = ') ; + disp (err) ; + if (err > 1e-12) + error ('!') ; + end + + m2 = size (Q1,1) ; + A1 = [A ; sparse(m2-m,n)] ; + + subplot (3,4,5) ; spy (A1 (p1,q1)) ; + subplot (3,4,6) ; spy (V1) ; + subplot (3,4,7) ; spy (R1) ; + subplot (3,4,8) ; spy (Q1) ; + + [V3, Beta3, R3] = qr2 (A) ; + % Q3 = cs_qmake (V3, Beta3) ; + Q3 = cs_q1 (V3, Beta3) ; + subplot (3,4,9) ; spy (A) ; + subplot (3,4,10) ; spy (V3) ; + subplot (3,4,11) ; spy (R3) ; + subplot (3,4,12) ; spy (Q3) ; + + err1 = norm (Q1*R1 - A1(:,q1), 1) ; +% err2 = norm (Q2*R2 - A (:,q2), 1) ; + err3 = norm (Q3*R3 - A, 1) ; + + fprintf ('m %3d m2 %3d n %3d ::: %3d %6.2e %6.2e\n', ... + m, m2, n, m2-m, err1, err3) ; + + if (err1 > 1e-12) + error ('!') ; + end + +% if (err2 > 1e-12) +% error ('!') ; +% end + + if (err3 > 1e-12) + error ('!') ; + end + +try + + b = rand (m,1) ; + [Q,R] = qr (A (:,q1)) ; + x = R\(Q'*b) ; + x (q1) = x ; + r1 = norm (A*x-b) ; + + x2 = cs_qrsol (A,b) ; + r2 = norm (A*x2(1:n)-b) ; + + qt = cs_qleft (V1, Beta1, p1, speye(size(V1,1))) ; + fprintf ('Q''*A-R: %6.2e\n', norm (qt*A1(:,q1)-R1,1)) ; + + qtb = cs_qleft (V1, Beta1, p1, b) ; + % [V1, Beta1, p1, R1, q1] = cs_qr (A) ; + x3 = R1 \ qtb ; + r3 = norm (A(:,q1)*x3(1:n)-b) ; + + fprintf ('least sq: %6.2e %6.2e %6.2e diff %6.2e %6.2e\n', ... + r1, r2, r3, r1-r2, r1-r3) ; + +catch +end + + drawnow + + % pause + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test18.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test18.m new file mode 100644 index 0000000..d7d276c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test18.m @@ -0,0 +1,34 @@ +function test18 +%TEST18 test iterative refinement after backslash +% +% Example: +% test18 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +clf +% f = f(1) + +for i = f + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (~isreal (A) | m ~= n) %#ok + continue + end + + b = rand (n,1) ; + x = A\b ; + r = b - A*x ; + x = x + A\r ; + + fprintf ('\n%6.2e to %6.2e\n', norm (r), norm (b-A*x)) ; +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test19.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test19.m new file mode 100644 index 0000000..4489af1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test19.m @@ -0,0 +1,200 @@ +function test19 +%TEST19 test cs_dmperm, cs_maxtransr, cs_dmspy, cs_scc +% +% Example: +% test19 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +randn ('state', 0) ; +rand ('state', 0) ; + +clf + +for trials = 1:1000 + + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + % d = 0.1 * rand (1) ; + d = rand (1) * 4 * max (m,n) / max (m*n,1) ; + A = sprandn (m,n,d) ; + S = sprandn (m,m,d) + speye (m) ; + + subplot (2,3,1) ; + cspy (A) ; + + pp = dmperm (A) ; + + sprnk = sum (pp > 0) ; + + pp2 = cs_dmperm (A) ; + spr2 = sum (pp2 > 0) ; + if (spr2 ~= sprnk) + error ('!') + end + + pp2 = cs_maxtransr (A) ; + spr2 = sum (pp2 > 0) ; + if (spr2 ~= sprnk) + error ('!') + end + + [p,q,r,s] = dmperm (A) ; + C = A (p,q) ; + % r + % s + + nk = length (r) - 1 ; + + fprintf ('sprnk: %d m %d n %d nb: %d\n', sprnk, m, n, nk) ; + + subplot (2,3,2) ; + hold off + spy (C) + hold on + + for k = 1:nk + r1 = r(k) ; + r2 = r(k+1) ; + c1 = s(k) ; + c2 = s(k+1) ; + plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + end + + [p2,q2,rr2,ss2,cp,rp] = cs_dmperm (A) ; + + if (min (m,n) > 0) + if (length (rr2) ~= length (r)) + error ('# fine blocks!') ; + end + end + + if (rp (4) - 1 ~= sprnk) + rp %#ok + sprnk %#ok + error ('!') ; + end + + if (any (sort (p2) ~= 1:m)) + error ('p2!') ; + end + + if (any (sort (q2) ~= 1:n)) + error ('q2!') ; + end + + if (cp (5) ~= n+1) + error ('cp!') ; + end + + if (rp (5) ~= m+1) + error ('rp!') ; + end + + C = A (p2,q2) ; + + subplot (2,3,3) ; cs_dmspy (A,0) ; + + % hold off + % spy (C) ; + % hold on + + % r1 = rp(1) ; + % r2 = rp(2) ; + % c1 = cp(1) ; + % c2 = cp(2) ; + % plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + + r1 = rp(1) ; + r2 = rp(2) ; + c1 = cp(2) ; + c2 = cp(3) ; + % plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + + B = C (r1:r2-1, c1:c2-1) ; + if (nnz (diag (B)) ~= size (B,1)) + error ('C1 diag!') ; + end + + r1 = rp(2) ; + r2 = rp(3) ; + c1 = cp(3) ; + c2 = cp(4) ; + % plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'r') ; + + B = C (r1:r2-1, c1:c2-1) ; + if (nnz (diag (B)) ~= size (B,1)) + error ('C2 diag!') ; + end + + r1 = rp(3) ; + r2 = rp(4) ; + c1 = cp(4) ; + c2 = cp(5) ; + % plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + + B = C (r1:r2-1, c1:c2-1) ; + if (nnz (diag (B)) ~= size (B,1)) + error ('C3 diag!') ; + end + + r1 = rp(4) ; %#ok + r2 = rp(5) ; %#ok + c1 = cp(4) ; %#ok + c2 = cp(5) ; %#ok + % plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + + if (~isempty (S)) + + [p1,q1,r0,s0] = dmperm (S) ; + [p3,r3] = cs_scc (S) ; + if (length (r3) ~= length (r0)) + error ('scc size!') ; + end + + if (any (sort (p3) ~= 1:m)) + error ('scc perm!') ; + end + + nk = length (r0)-1 ; + + subplot (2,3,4) ; + hold off + spy (S (p1,q1)) ; + hold on + for k = 1:nk + r1 = r0(k) ; + r2 = r0(k+1) ; + c1 = s0(k) ; + c2 = s0(k+1) ; + plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + end + + subplot (2,3,5) ; + hold off + spy (S (p3,p3)) ; + hold on + for k = 1:nk + r1 = r3(k) ; + r2 = r3(k+1) ; + c1 = r3(k) ; + c2 = r3(k+1) ; + plot ([c1 c2 c2 c1 c1]-.5, [r1 r1 r2 r2 r1]-.5, 'g') ; + end + + end + + subplot (2,3,6) ; + cs_dmspy (A) ; + drawnow + % pause + + + + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test2.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test2.m new file mode 100644 index 0000000..13ca9ba --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test2.m @@ -0,0 +1,102 @@ +function test2 +%TEST2 test cs_sparse +% +% Example: +% test2 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +rand ('state', 0) +% clf + +for trial = 1:100 + m = fix (10 * rand (1)) ; + n = fix (10 * rand (1)) ; + nz = fix (100 * rand (1)) ; + + i = 1 + fix (m * rand (nz,1)) ; + j = 1 + fix (n * rand (nz,1)) ; + x = rand (nz,1) ; + + A = sparse (i,j,x) ; + B = cs_sparse (i,j,x) ; + D = cs_sparse2 (i,j,x) ; + fprintf ('%3d %3d %6d : %6d %6d : %d\n', ... + m, n, nz, nnz (A), nnz(B), nz-nnz(A)) ; + + err = norm (A-B,1) / norm (A,1) ; + if (err > 0) + disp ('err = ') ; + disp (err) ; + end + if (err > 1e-14) + error ('!') ; + end + + if (nnz (B-D) > 0) + error ('!') ; + end + + if (nnz (A) ~= nnz (B)) + error ('nz!') ; + end + + if (max (1,nnz (B)) ~= max (1,nzmax (B))) + nnz (B) + nzmax (B) + error ('nzmax!') ; + end + % pack + + + [m n] = size (A) ; + p = randperm (m) ; + q = randperm (n) ; + C1 = A (p,q) ; + C2 = cs_permute (A,p,q) ; + err = norm (C1-C2,1) ; + if (err > 0) + error ('!') ; + end + +% subplot (1,2,1) ; spy (A) +% subplot (1,2,2) ; spy (C2) +% drawnow + + x = rand (m,1) ; + x1 = x (p) ; + x2 = cs_pvec (x, p) ; + + err = norm (x1-x2,1) ; + if (err > 0) + error ('!') ; + end + + x1 = zeros (m,1) ; + x1 (p) = x ; %#ok + x2 = cs_ipvec (x, p) ; %#ok + + n = min (m,n) ; + B = A (1:n, 1:n) ; + p = randperm (n) ; + B = B+B' ; + + C1 = triu (B (p,p)) ; + C2 = cs_symperm (B,p) ; + + try + pp = amd (C2) ; %#ok + catch + pp = symamd (C2) ; %#ok + end + + err = norm (C1-C2,1) ; + if (err > 0) + error ('!') ; + end + + + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test20.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test20.m new file mode 100644 index 0000000..f0fb760 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test20.m @@ -0,0 +1,47 @@ +function test20 +%TEST20 test cholupdown +% +% Example: +% test20 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +rand ('state', 0) ; + +for trials = 1:10 + + n = fix (100 * rand (1)) ; + A = rand (n) ; + A1 = A*A' + n*eye (n) ; + + try + L1 = chol (A1)' ; + catch + continue ; + end + err1 = norm (L1*L1'-A1) ; + + w = rand (n,1) ; + + A2 = A1 + w*w' ; + + L2 = chol (A2)' ; + err2 = norm (L2*L2'-A2) ; + + % try an update + L2b = cholupdown (L1, +1, w) ; + err2b = norm (L2b*L2b'-A2) ; + + % try a downdate + L1b = cholupdown (L2, -1, w) ; %#ok + err1b = norm (L2b*L2b'-A2) ; + + + fprintf ('%3d: %6.2e %6.2e : %6.2e %6.2e\n', n, err1, err2, err2b, err1b) ; + % pause +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test21.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test21.m new file mode 100644 index 0000000..1bd07d0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test21.m @@ -0,0 +1,118 @@ +function test21 +%TEST21 test cs_updown +% +% Example: +% test21 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions +rand ('state', 0) ; +randn ('state', 0) ; + +clf + +for trials = 1:10 + if (trials <= 1) + n = trials ; + else + n = 1+fix (100 * rand (1)) ; + end + fprintf ('n: %d\n', n) ; + d = 0.1 * rand (1) ; + A = sprandn (n,n,d) ; + A = A+A' + 100 * speye (n) ; + try + p = amd (A) ; + catch + p = symamd (A) ; + end + A = sparse (A (p,p)) ; + + try + L = chol (A)' ; + catch + continue ; + end + + parent = etree (A) ; + + subplot (1,3,1) ; + spy (A) ; + + if (n > 0) + subplot (1,3,2) ; + treeplot (parent) ; + end + + subplot (1,3,3) ; + spy (L) ; + + drawnow + + for trials2 = 1:10 + + k = 1+fix (n * rand (1)) ; + if (k <= 0 | k > n) %#ok + k = 1 ; + end + + w = sprandn (L (:,k)) ; + Anew = A + w*w' ; + + % Lnew = cs_update (L, w, parent) ; + % err1 = norm (Lnew*Lnew' - Anew, 1) ; + + Lnew = cs_updown (L, w, parent) ; + err6 = norm (Lnew*Lnew' - Anew, 1) ; + + Lnew = cs_updown (L, w, parent, '+') ; + err7 = norm (Lnew*Lnew' - Anew, 1) ; + + [Lnew, wnew] = chol_update (L, w) ; + err2 = norm (Lnew*Lnew' - Anew, 1) ; + err10 = norm (wnew - (L\w)) ; + + L3 = chol_updown (L, +1, w) ; + err9 = norm (L3*L3' - Anew, 1) ; + + + + [L2, wnew] = chol_downdate (Lnew, w) ; + err3 = norm (L2*L2' - A, 1) ; + err11 = norm (wnew - (Lnew\w)) ; + + % L2 = cs_downdate (Lnew, w, parent) ; + % err4 = norm (L2*L2' - A, 1) ; + + L2 = cs_updown (Lnew, w, parent, '-') ; + err5 = norm (L2*L2' - A, 1) ; + + L2 = chol_updown (Lnew, -1, w) ; + err8 = norm (L2*L2' - A, 1) ; + + err = max ([err2 err3 err5 err6 err7 err9 err8 err10 err11]) ; + + fprintf (' k %3d %6.2e\n', k, err) ; + + if (err > 1e-11) + err2 %#ok + err3 %#ok + err5 %#ok + err6 %#ok + err7 %#ok + err8 %#ok + err9 %#ok + err10 %#ok + err11 %#ok + pause + end + + + end + % pause + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test22.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test22.m new file mode 100644 index 0000000..e1a1f66 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test22.m @@ -0,0 +1,71 @@ +function test22 +%TEST22 test cond1est +% +% Example: +% test22 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:200) ; + +clf +% f = f(1) + +nprob = length (f) ; +C1 = zeros (nprob,1) ; +C2 = zeros (nprob,1) ; +C3 = zeros (nprob,1) ; + + +for k = 1:length (f) + + i = f (k) ; + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (~isreal (A) | m ~= n) %#ok + continue + end + + c1 = condest (A) ; + c2 = cond1est (A) ; + if (c1 == c2) + err = 0 ; + else + err = (c1-c2)/max(1,c1) ; + end + + c3 = cond (full (A), 1) ; + + fprintf ('%10.4e %10.4e (%10.4e) : %10.4e\n', c1, c2, c3, err) ; + + if (err ~= 0) + % pause + end + + C1 (k) = c1 ; + C2 (k) = c2 ; + C3 (k) = c3 ; + + subplot (1,2,1) ; + loglog (C1, C2, 'x', [1 1e20], [1 1e20], 'r') ; + subplot (1,2,2) ; + loglog (C3, C2, 'x', [1 1e20], [1 1e20], 'r') ; + drawnow + + % pause + +% if (c3 < c2) +% c3 +% c2 +% c2-c3 +% pause +% end + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test23.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test23.m new file mode 100644 index 0000000..e27f90c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test23.m @@ -0,0 +1,32 @@ +function test23 +%TEST23 test cs_dmspy +% +% Example: +% test23 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +clear functions + +randn ('state', 0) ; +rand ('state', 0) ; + +clf + +for trials = 1:1000 + + % m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + m = n ; + % d = 0.1 * rand (1) ; + d = rand (1) * 4 * max (m,n) / max (m*n,1) ; + A = sprandn (m,n,d) ; + % S = sprandn (m,m,d) + speye (m) ; + + cs_dmspy (A) ; + drawnow + + % pause +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test24.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test24.m new file mode 100644 index 0000000..e3f7059 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test24.m @@ -0,0 +1,55 @@ +function test24 +%TEST24 test cs_fielder +% +% Example: +% test24 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:200) ; + +clf +% f = f(1) + +for k = 1:length (f) + + i = f (k) ; + Prob = UFget (i) ; + disp (Prob) ; + A = real (Prob.A) ; + [m n] = size (A) ; + if (m ~= n) + continue + end + + tic + p1 = symrcm (A) ; + t1 = toc ; + + tic + p2 = cs_fiedler (A) ; + t2 = toc ; + + rel = t2 / max (t1,1e-6) ; + + fprintf ('time: symrcm %8.3f fiedler %8.3f rel %8.2f\n', t1, t2, rel) ; + + A = A|A' ; + + subplot (1,3,1) ; spy (A) ; + subplot (1,3,2) ; spy (A (p1,p1)) ; + subplot (1,3,3) ; spy (A (p2,p2)) ; + + % evaluate the profile ... + + + drawnow + % pause +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test25.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test25.m new file mode 100644 index 0000000..305ad8f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test25.m @@ -0,0 +1,66 @@ +function test25 +%TEST25 test cs_nd +% +% Example: +% test25 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +clf +% f = f(1) + +for k = 1:length (f) + + i = f (k) ; + Prob = UFget (i) ; + disp (Prob) ; + A = real (Prob.A) ; + [m n] = size (A) ; + if (m ~= n) + continue + end + + A = A|A' ; + + tic ; + p1 = symrcm (A) ; + t1 = toc ; + + tic ; + p2 = cs_nd (sparse (1)) ; + toc ; + if (p2 ~= 1) + error ('!') ; + end + + tic ; + p2 = cs_nd (A) ; + t2 = toc ; + + if (any (sort (p2) ~= 1:n)) + error ('!') ; + end + + rel = t2 / max (t1,1e-6) ; + + fprintf ('time: symrcm %8.3f nd %8.3f rel %8.2f\n', t1, t2, rel) ; + + subplot (1,3,1) ; spy (A) ; + subplot (1,3,2) ; spy (A (p1,p1)) ; + subplot (1,3,3) ; spy (A (p2,p2)) ; + + % evaluate the profile ... + + + drawnow + % pause +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test26.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test26.m new file mode 100644 index 0000000..154c995 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test26.m @@ -0,0 +1,70 @@ +function test26 +%TEST26 test cs_dmsol and cs_dmspy +% +% Example: +% test26 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +randn ('state', 0) ; +rand ('state', 0) ; + +clf + +ntrials = 1000 ; +e1 = zeros (ntrials,1) ; +e2 = zeros (ntrials,1) ; + +for trials = 1:ntrials + + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + % d = 0.1 * rand (1) ; + d = rand (1) * 4 * max (m,n) / max (m*n,1) ; + A = sprandn (m,n,d) ; + % S = sprandn (m,m,d) + speye (m) ; + + subplot (1,3,2) ; spy (A) ; + subplot (1,3,3) ; cs_dmspy (A) ; + + b = rand (m,1) ; + + x1 = A\b ; + x2 = cs_dmsol (A,b) ; + + err1 = norm (A*x1-b) ; + err2 = norm (A*x2-b) ; + + lerr1 = log10 (max (err1, eps)) ; + lerr2 = log10 (max (err2, eps)) ; + + fprintf ('rank: %3d %3d err %6.2e %6.2e : %6.1f\n', ... + sprank(A), rank(full(A)), err1, err2, lerr1 - lerr2) ; + + if (isnan (err1)) + lerr1 = 10 ; + end + if (isnan (err2)) + lerr2 = 10 ; + end + + if (lerr2 > lerr1 + 5) + % pause + end + + e1 (trials) = lerr1 ; + e2 (trials) = lerr2 ; + + subplot (1,3,1) ; plot (e1, e2, 'o', [-16 10], [-16 10], 'r') ; + xlabel ('MATLAB error') ; + ylabel ('dmsol error') ; + + + drawnow + % pause +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test27.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test27.m new file mode 100644 index 0000000..3c1418c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test27.m @@ -0,0 +1,47 @@ +function test27 +%TEST27 test cs_qr, cs_utsolve, cs_qrsol +% +% Example: +% test27 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + + +clear functions +rand ('state', 0) ; + +Prob = UFget ('HB/ibm32') ; +A = Prob.A ; +A = A (1:10,:) ; +[m n] = size (A) ; + +[V,Beta,p,R,q] = cs_qr (A') ; + +b = rand (m,1) ; + +Rm = R (1:m,1:m) ; + +bq = b (q) ; +rtbq = Rm' \ bq ; + +rt2 = cs_utsolve (Rm, bq) ; + +norm (rtbq - rt2) + +x = [rt2 ; zeros(n-m,1)] ; + +for k = m:-1:1 + x = x - V(:,k) * (Beta (k) * (V (:,k)' * x)) ; +end + +x (p) = x ; + +norm (A*x-b) + +x2 = cs_qrsol (A,b) ; + +norm (A*x2-b) +norm (x-x2) diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test28.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test28.m new file mode 100644 index 0000000..bc6343a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test28.m @@ -0,0 +1,113 @@ +function test28 +%TEST28 test cs_randperm, cs_dmperm +% +% Example: +% test28 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +clear functions + +rand ('state', 0) ; +for n = 1:100 + for trials = 1:1000 + p = cs_randperm (n, rand) ; + if (any (sort (p) ~= 1:n)) + n %#ok + p %#ok + error ('!') + end + end +end + +index = UFget ; +[ignore f] = sort (index.nnz) ; + +fprintf ('p=dmperm (std, rand, rev) [p,q,r,s]=dmperm (std, rand, rev)\n') ; + +nmat = min (100, length (f)) ; +T1 = zeros (nmat,1) ; +T2 = zeros (nmat,1) ; +T3 = zeros (nmat,1) ; +D1 = zeros (nmat,1) ; +D2 = zeros (nmat,1) ; +D3 = zeros (nmat,1) ; + + +for k = 1:nmat + + i = f (k) ; + Prob = UFget (i,index) ; + A = Prob.A ; + [m n] = size (A) ; + fprintf ('%35s: ', Prob.name) ; + + tic + p = cs_dmperm (A) ; + t1 = toc ; + sprank1 = sum (p > 0) ; + fprintf (' %8.2f', t1) ; + T1 (k) = t1 ; + + tic + p = cs_dmperm (A,1) ; + t2 = toc ; + sprank2 = sum (p > 0) ; + fprintf (' %8.2f', t2) ; + T2 (k) = t2 ; + + tic + p = cs_dmperm (A,-1) ; + t3 = toc ; + sprank3 = sum (p > 0) ; + fprintf (' %8.2f', t3) ; + T3 (k) = t3 ; + + if (sprank1 ~= sprank2 | sprank1 ~= sprank3) %#ok + error ('!') ; + end + + tic + [p1,q1,r1,s1,cc1,rr1] = cs_dmperm (A) ; %#ok + d1 = toc ; + fprintf (' %8.2f', d1) ; + D1 (k) = d1 ; + + tic + [p2,q2,r2,s2,cc2,rr2] = cs_dmperm (A,1) ; %#ok + d2 = toc ; + fprintf (' %8.2f', d2) ; + D2 (k) = d2 ; + + tic + [p3,q3,r3,s3,cc3,rr3] = cs_dmperm (A,-1) ; %#ok + d3 = toc ; + fprintf (' %8.2f\n', d3) ; + D3 (k) = d3 ; + + if (sprank1 == max (m,n)) + nz1 = nnz (diag (A (p1,q1))) ; + nz2 = nnz (diag (A (p2,q2))) ; + nz3 = nnz (diag (A (p3,q3))) ; + + if (nz1 ~= sprank1 | nz2 ~= sprank2 | nz3 ~= sprank3) %#ok + error ('!') + end + end + + subplot (1,2,1) + loglog (T1 (1:k), T2 (1:k), 'x', ... + T1 (1:k), T3 (1:k), 'go', ... + [1e-5 1e3], [1e-5 1e3], 'r-') ; + axis equal + + subplot (1,2,2) + loglog (D1 (1:k), D2 (1:k), 'x', ... + D1 (1:k), D3 (1:k), 'go', ... + [1e-5 1e3], [1e-5 1e3], 'r-') ; + axis equal + + drawnow +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test3.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test3.m new file mode 100644 index 0000000..459c036 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test3.m @@ -0,0 +1,97 @@ +function test3 +%TEST3 test cs_lsolve, cs_ltsolve, cs_usolve, cs_chol +% +% Example: +% test3 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +clf +% f = f(1) + +for i = f + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (~isreal (A) | m ~= n) %#ok + continue + end + + A = A*A' + 2*n*speye (n) ; + try + p = amd (A) ; + catch + p = symamd (A) ; + end + try + L0 = chol (A)' ; + catch + continue + end + b = rand (n,1) ; + + C = A(p,p) ; + c = condest (C) ; + fprintf ('condest: %g\n', c) ; + + x1 = L0\b ; + x2 = cs_lsolve (L0,b) ; + err = norm (x1-x2,1) ; + if (err > 1e-12 * c) + error ('!') ; + end + + x1 = L0'\b ; + x2 = cs_ltsolve (L0,b) ; + err = norm (x1-x2,1) ; + if (err > 1e-10 * c) + error ('!') ; + end + + U = L0' ; + + x1 = U\b ; + x2 = cs_usolve (U,b) ; + err = norm (x1-x2,1) ; + if (err > 1e-10 * c) + error ('!') ; + end + + L2 = cs_chol (A) ; + subplot (2,3,1) ; spy (L0) ; + subplot (2,3,4) ; spy (L2) ; + err = norm (L0-L2,1) ; + if (err > 1e-8 * c) + error ('!') ; + end + + L1 = chol (C)' ; + L2 = cs_chol (C) ; + subplot (2,3,2) ; spy (L1) ; + subplot (2,3,5) ; spy (L2) ; + err = norm (L1-L2,1) ; + if (err > 1e-8 * c) + error ('!') ; + end + + [L3,p] = cs_chol (A) ; + C = A(p,p) ; + L4 = chol (C)' ; + subplot (2,3,3) ; spy (L4) ; + subplot (2,3,6) ; spy (L3) ; + err = norm (L4-L3,1) ; + if (err > 1e-8 * c) + error ('!') ; + end + + drawnow + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test4.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test4.m new file mode 100644 index 0000000..cc6b9e4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test4.m @@ -0,0 +1,33 @@ +function test4 +%TEST4 test cs_multiply +% +% Example: +% test4 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +rand ('state', 0) ; + +for trial = 1:100 + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + k = fix (100 * rand (1)) ; + d = rand (1) ; + A = sprandn (m,n,d) ; + B = sprandn (n,k,d) ; + C = A*B ; + D = cs_multiply (A,B) ; + err = nnz (spones (C) - spones (D)) ; + if (err > 0) + error ('nz!') ; + end + err = norm (C-D,1) ; + fprintf ('m %3d n %3d k %3d nnz(A) %6d nnz(B) %6d nnz(C) %6d err %g\n', ... + m, n, k, nnz(A), nnz(B), nnz(C), err) ; + if (err > 1e-12) + error ('!') ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test5.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test5.m new file mode 100644 index 0000000..d535fe1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test5.m @@ -0,0 +1,60 @@ +function test5 +%TEST5 test cs_add +% +% Example: +% test5 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +rand ('state', 0) ; + +for trial = 1:100 + m = fix (100 * rand (1)) ; + n = fix (100 * rand (1)) ; + d = rand (1) ; + A = sprandn (m,n,d) ; + B = sprandn (m,n,d) ; + + C = A+B ; + D = cs_add (A,B) ; + err = nnz (spones (C) - spones (D)) ; + if (err > 0) + error ('nz!') ; + end + err = norm (C-D,1) ; + fprintf ('m %3d n %3d nnz(A) %6d nnz(B) %6d nnz(C) %6d err %g\n', ... + m, n, nnz(A), nnz(B), nnz(C), err) ; + if (err > 1e-12) + error ('!') ; + end + + C = pi*A+B ; + D = cs_add (A,B,pi) ; + err = nnz (spones (C) - spones (D)) ; + if (err > 0) + error ('nz!') ; + end + err = norm (C-D,1) ; + fprintf ('m %3d n %3d nnz(A) %6d nnz(B) %6d nnz(C) %6d err %g\n', ... + m, n, nnz(A), nnz(B), nnz(C), err) ; + if (err > 1e-12) + error ('!') ; + end + + C = pi*A+3*B ; + D = cs_add (A,B,pi,3) ; + err = nnz (spones (C) - spones (D)) ; + if (err > 0) + error ('nz!') ; + end + err = norm (C-D,1) ; + fprintf ('m %3d n %3d nnz(A) %6d nnz(B) %6d nnz(C) %6d err %g\n', ... + m, n, nnz(A), nnz(B), nnz(C), err) ; + if (err > 1e-12) + error ('!') ; + end + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test6.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test6.m new file mode 100644 index 0000000..dfa70e7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test6.m @@ -0,0 +1,96 @@ +function test6 +%TEST6 test cs_reach, cs_reachr, cs_lsolve, cs_usolve +% +% Example: +% test6 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +rand ('state', 0) +maxerr = 0 ; +clf +for trial = 1:201 + n = fix (100 * rand (1)) ; + d = 0.1 * rand (1) ; + L = tril (sprandn (n,n,d),-1) + sprand (speye (n)) ; + b = sprandn (n,1,d) ; + + for uplo = 0:1 + + if (uplo == 1) + % solve Ux=b instead ; + L = L' ; + end + + x = L\b ; + sr = 1 + cs_reachr (L,b) ; + sz = 1 + cs_reachr (L,b) ; + + check_if_same (sr,sz) ; + + s2 = 1 + cs_reach (L,b) ; + + if (uplo == 0) + x3 = cs_lsolve (L,b) ; + else + x3 = cs_usolve (L,b) ; + end + % cs_lsolve and cs_usolve return sparse vectors with + % unsorted indices and possibly with explicit zeros. + x3 = 1 * x3'' ; + + spy ([L b x x3]) + drawnow + + s = sort (sr) ; + [i j xx] = find (x) ; %#ok + [i3 j3 xx3] = find (x3) ; %#ok + + if (isempty (i)) + if (~isempty (s)) + i %#ok + s %#ok + error ('!') ; + end + elseif (any (s ~= i)) + i %#ok + s %#ok + error ('!') ; + end + + if (isempty (i3)) + if (~isempty (s)) + i3 %#ok + s %#ok + error ('!') ; + end + elseif (any (s ~= sort (i3))) + s %#ok + i3 %#ok + error ('!') ; + end + + if (any (s2 ~= sr)) + s2 %#ok + sr %#ok + error ('!') ; + end + + err = norm (x-x3,1) ; + if (err > 1e-12) + x %#ok + x3 %#ok + uplo %#ok + err %#ok + error ('!') + end + + maxerr = max (maxerr, err) ; + + end + + drawnow +end +fprintf ('maxerr = %g\n', maxerr) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test7.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test7.m new file mode 100644 index 0000000..2c80e1c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test7.m @@ -0,0 +1,107 @@ +function test7 +%TEST7 test cs_lu +% +% Example: +% test7 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +clf + +for i = f + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + if (~isreal (A)) + continue + end + [m n] = size (A) ; + if (m ~= n) + continue + end + + [L,U,P] = lu (A) ; + + udiag = full (diag (U)) ; + umin = min (abs (udiag)) ; + fprintf ('umin %g\n', umin) ; + + if (umin > 1e-14) + + [L2,U2,p] = cs_lu (A) ; + + subplot (3,4,1) ; spy (A) ; + subplot (3,4,2) ; spy (A(p,:)) ; + subplot (3,4,3) ; spy (L2) ; + subplot (3,4,4) ; spy (U2) ; + + err1 = norm (L*U-P*A,1) ; + err2 = norm (L2*U2-A(p,:),1) ; + fprintf ('err %g %g\n', err1, err2) ; + end + + q = colamd (A) ; + + [L,U,P] = lu (A (:,q)) ; + + udiag = full (diag (U)) ; + umin = min (abs (udiag)) ; + fprintf ('umin %g with q\n', umin) ; + + if (umin > 1e-14) + + [L2,U2,p,q2] = cs_lu (A) ; + + subplot (3,4,5) ; spy (A) ; + subplot (3,4,6) ; spy (A(p,q2)) ; + subplot (3,4,7) ; spy (L2) ; + subplot (3,4,8) ; spy (U2) ; + + err1 = norm (L*U-P*A(:,q),1) ; + err2 = norm (L2*U2-A(p,q2),1) ; + fprintf ('err %g %g\n', err1, err2) ; + end + + + try + q = amd (A) ; + catch + q = symamd (A) ; + end + + tol = 0.01 ; + + [L,U,P] = lu (A (q,q), tol) ; + + udiag = full (diag (U)) ; + umin = min (abs (udiag)) ; + fprintf ('umin %g with amd q\n', umin) ; + + if (umin > 1e-14) + + [L2,U2,p,q2] = cs_lu (A,tol) ; + + subplot (3,4,9) ; spy (A) ; + subplot (3,4,10) ; spy (A(p,q2)) ; + subplot (3,4,11) ; spy (L2) ; + subplot (3,4,12) ; spy (U2) ; + + err1 = norm (L*U-P*A(q,q),1) ; + err2 = norm (L2*U2-A(p,q2),1) ; + lbig = full (max (max (abs (L2)))) ; + fprintf ('err %g %g lbig %g\n', err1, err2, lbig) ; + if (lbig > 1/tol) + error ('L!') ; + end + end + + drawnow + % pause + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test8.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test8.m new file mode 100644 index 0000000..af6a029 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test8.m @@ -0,0 +1,85 @@ +%TEST8 test cs_cholsol, cs_lusol +% +% Example: +% test8 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; + +% f = f(1) + +for i = f + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (~isreal (A) | m ~= n) %#ok + continue + end + + spd = 0 ; + if (m == n) + if (nnz (A-A') == 0) + try + p = amd (A) ; + catch + p = symamd (A) ; + end + [R,p] = chol (A (p,p)) ; + spd = (p == 0) ; + end + end + + if (spd) + C = A ; + else + C = A*A' + n*speye (n) ; + try + p = amd (C) ; + catch + p = symamd (C) ; + end + try + R = chol (C (p,p)) ; + catch + continue + end + end + + b = rand (n,1) ; + + x1 = C\b ; + x2 = cs_cholsol (C,b) ; + r1 = norm (C*x1-b,1) / norm (C,1) ; + r2 = norm (C*x2-b,1) / norm (C,1) ; + err = abs (r1-r2) ; + fprintf ('err %g\n', err) ; + if (err > 1e-10) + error ('!') ; + end + + x2 = cs_lusol (C,b, 1, 0.001) ; + r2 = norm (C*x2-b,1) / norm (C,1) ; + err = abs (r1-r2) ; + fprintf ('err %g (lu with amd(A+A'')\n', err) ; + if (err > 1e-10) + error ('!') ; + end + + if (m ~= n) + continue ; + end + + x1 = A\b ; + r1 = norm (A*x1-b,1) / norm (A,1) ; + if (r1 < 1e-6) + x2 = cs_lusol (A,b) ; + r2 = norm (A*x2-b,1) / norm (A,1) ; + fprintf ('lu resid %g %g\n', r1, r2) ; + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test9.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test9.m new file mode 100644 index 0000000..fe0ce06 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test9.m @@ -0,0 +1,114 @@ +function test9 +%TEST9 test cs_qr +% +% Example: +% test9 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +rand ('state', 0) ; + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; +f = f (1:100) ; +clf + +% f = 185 ; +% f = 449 ; +% f = 186 + +for i = f + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (m < n) + A = A' ; + end + [m n] = size (A) ; + sp = sprank (A) ; +% if (sprank (A) < min (m,n)) +% continue +% end + Aorig = A ; + + A = A (:, colamd (A)) ; + s1 = svd (full (A)) ; + + tic ; + R = qr (A) ; + t1 = toc ; %#ok + + % tic ; + % [Q,R] = qr (A) ; + % t1 = toc ; + + [c,h,parent] = symbfact (A, 'col') ; + rnz = sum (c) ; %#ok + tic ; + [V2,Beta2,p,R2] = cs_qr (sparse(A)) ; + t2 = toc ; %#ok + + v2 = full (V2) ; + if (any (spones (v2) ~= spones (V2))) + error ('got zeros!') ; + end + + C = A ; + m2 = size (V2,1) ; + if (m2 > m) + C = [A ; sparse(m2-m, n)] ; + end + C = C (p,:) ; + +% [H1,R1] = myqr (C) ; +% err1 = norm (R1-R2,1) / norm (R1) +% % [svd(A) svd(R1) svd(full(R2))] +% s2 = svd (full (R2)) ; +% err2 = norm (s1 - s2) / s1 (1) +% fprintf ('%10.6f %10.6f cs speedup %8.3f sprank %d n %d\n', ... +% t1, t2, t1/t2, sp, n) ; +% err2 + + % left-looking: + [V,Beta3,R3] = qr_left (C) ; %#ok + s3 = svd (full (R2)) ; + err3 = norm (s1 - s3) / s1 (1) ; + disp ('err3 = ') ; disp (err3) ; + if (err3 > 1e-12) + error ('!') ; + end + + % right-looking: + [V,Beta4,R4] = qr_right (C) ; %#ok + s4 = svd (full (R2)) ; + err4 = norm (s1 - s4) / s1 (1) ; + disp ('err4 = ') ; disp (err4) ; + if (err4 > 1e-12) + error ('!') ; + end + + % H2 = full (H2) + % R2 = full (R2) + + subplot (2,4,1) ; spy (A) ; title ('A colamd') ; + subplot (2,4,2) ; spy (C) ; title ('A rperm') ; + subplot (2,4,3) ; treeplot (parent) ; + subplot (2,4,4) ; spy (Aorig) ; title ('Aorig') ; + subplot (2,4,5) ; spy (abs(R2)>0) ; title ('spqr R, no zeros') ; + subplot (2,4,6) ; spy (R) ; title ('matlab R') ; + subplot (2,4,7) ; spy (R2) ; title ('spqr R') ; + subplot (2,4,8) ; spy (V2) ; title ('spqr V') ; + drawnow + +% if (err2 > 1e-9) +% error ('!') ; +% end + if (m2 > m) + fprintf ('added %d rows, sprank %d n %d\n', m2-m, sp, n) ; + end + % pause +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr.m new file mode 100644 index 0000000..9f2550c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr.m @@ -0,0 +1,55 @@ +function test_qr +%TEST_QR test various QR factorization methods +% +% Example: +% test_qr +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; +[ignore f] = sort (max (index.nrows,index.ncols)) ; + +% f = 276 +% f = 706 +f = f (1:100) ; + +for i = f + + % Prob = UFget (i,index) + Prob = UFget (i) ; + disp (Prob) ; + A = Prob.A ; + [m n] = size (A) ; + if (m < n) + A = A' ; + end + [m n] = size (A) ; + if (sprank (A) < n | ~isreal (A)) %#ok + continue ; + end + + [V,beta,p,R1,q] = cs_qr(A) ; + A = A (p,q) ; + parent = etree (A, 'col') ; %#ok + + R0 = qr (A) ; + R2 = qr_givens (full (A)) ; + R3 = qr_givens_full (full (A)) ; + + subplot (2,2,1) ; cspy (R0) ; title ('matlab') ; + subplot (2,2,2) ; cspy (R3) ; title ('qr-full') ; + subplot (2,2,3) ; cspy (R2) ; title ('qr-givens') ; + subplot (2,2,4) ; cspy (R1) ; title ('cs-qr') ; + + e0 = norm (A'*A-R0'*R0,1) / norm (A,1) ; + e1 = norm (A'*A-R1'*R1,1) / norm (A,1) ; + e2 = norm (A'*A-R2'*R2,1) / norm (A,1) ; + e3 = norm (A'*A-R3'*R3,1) / norm (A,1) ; + fprintf ('error %6.2e %6.2e %6.2e %6.2e\n', e0, e1, e2, e3) ; + drawnow + if (e1 > e0*1e3 | e2 > e0*1e3) %#ok + pause + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr1.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr1.m new file mode 100644 index 0000000..c6031f1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qr1.m @@ -0,0 +1,58 @@ +function test_qr1 +%TEST_QR1 test QR factorizations +% +% Example: +% test_qr1 +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; + +for i = f + Prob = UFget (i,index) ; + A = Prob.A ; + if (~isreal (A)) + continue ; + end + + [m n] = size (A) ; + if (m < n) + A = A' ; + end + + t0 = 0 ; + k0 = 0 ; + while (t0 < 0.1) + tic + q = colamd (A, [-1 10]) ; + % [Q,R] = qr (A (:,q)) ; + R = qr (A (:,q)) ; %#ok + t = toc ; + t0 = t0 + t ; + k0 = k0 + 1 ; + end + t0 = t0 / k0 ; + + t1 = 0 ; + k1 = 0 ; + while (t1 < 0.1) + tic + [V,beta, p, R,q] = cs_qr (A) ; %#ok + t = toc ; + t1 = t1 + t ; + k1 = k1 + 1 ; + end + t1 = t1 / k1 ; + + fprintf (... + '%25s MATLAB: %10.4f (%8d) CS: %10.4f (%8d) speedup: %8.2f\n', ... + Prob.name, t0, k0, t1, k1, t0/t1) ; + + + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qrsol.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qrsol.m new file mode 100644 index 0000000..3e11e1d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_qrsol.m @@ -0,0 +1,50 @@ +function test_qrsol +%TEST_QRSOL test cs_qrsol +% +% Example: +% test_qrsol +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; + +k = 0 ; +rs1 = zeros (1,0) ; +rs2 = zeros (1,0) ; + +for i = f + Prob = UFget (i,index) ; + A = Prob.A ; + if (~isreal (A)) + continue ; + end + + [m n] = size (A) ; %#ok + b = rand (m,1) ; + + x1 = A\b ; + x2 = cs_qrsol (A,b) ; + + x1 (~isfinite (x1)) = 0 ; + x2 (~isfinite (x2)) = 0 ; + + r1 = norm (A*x1-b) ; + r2 = norm (A*x2-b) ; + + k = k + 1 ; + rs1 (k) = r1 ; + rs2 (k) = r2 ; + + fprintf ('%30s MATLAB: %6.2e CS: %6.2e\n', Prob.name, r1, r2) ; + + loglog (rs1, rs2, 'o') ; + drawnow + + clear A b x1 x2 + % pack + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_randperms.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_randperms.m new file mode 100644 index 0000000..bab0dc7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_randperms.m @@ -0,0 +1,60 @@ +function test_randperms +%TEST_RANDPERMS test random permutations +% Example: +% test_randperms +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +rand ('state', 0) + +for trial = 1:100 + m = fix (30 * rand (1)) ; + n = fix (30 * rand (1)) ; + d = rand (1) ; + A = sprandn (m,n,d) ; + + if (m == 0) + p = [] ; + else + p = randperm (m) ; + end + if (n == 0) + q = [] ; + else + q = randperm (n) ; + end + + C = A(p,q) ; + + Im = speye (m) ; + In = speye (n) ; + P = Im (p,:) ; + Q = In (:,q) ; + + q2 = find (Q) ; + if (any (q ~= q2')) + error ('!') + end + + p2 = find (P') ; + if (any (p ~= p2')) + error ('!') + end + + E = P*A*Q ; + if (norm (C-E,1) ~= 0) + error ('!') + end + + P = sparse (1:m, p, 1) ; + Q = sparse (q, 1:n, 1) ; + + E = P*A*Q ; + if (norm (C-E,1) ~= 0) + error ('2!') + end + +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_sep.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_sep.m new file mode 100644 index 0000000..c74e92e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/test_sep.m @@ -0,0 +1,102 @@ +function test_sep +%TEST_SEP test cs_sep, and compare with Gilbert's meshpart vtxsep +% (requires MESHPART). +% +% Example: +% test_sep +% +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +clear functions + +index = UFget ; +[ignore f] = sort (max (index.nrows, index.ncols)) ; + +clf + +for k = 1:length(f) + + i = f (k) ; + Prob = UFget (i) ; + disp (Prob) ; + A = spones (Prob.A) ; + [m n] = size (A) ; + if (m ~= n) + A = A'*A ; + end + + A = A|A' ; + + p = symrcm (A) ; + + n = size (A,1) ; + n2 = fix (n/2) ; + a = p (1:n2) ; + b = p ((n2+1):n) ; + + clf + + subplot (2,3,1) ; spy (A) ; + subplot (2,3,2) ; spy (A (p,p)) ; + + hold on + plot ([.5 n2+.5 n2+.5 .5 .5], [.5 .5 n2+.5 n2+.5 .5], 'r', 'LineWidth', 2) ; + hold off + + subplot (2,3,3) ; spy (A (a,b)) ; title ('edge sep') ; + subplot (2,3,6) ; cs_dmspy (A (a,b)) ; title ('node sep') ; + + [s as bs] = vtxsep (A,a,b) ; %#ok + [s2 a2 b2] = cs_sep (A,a,b) ; + + p2 = [a2 b2 s2] ; + B = A (p2,p2) ; + subplot (2,3,5) ; spy (B) ; + hold on + + px = [s2 a2 b2] ; + if (any (sort (px) ~= 1:n)) + px %#ok + n %#ok + error ('!') ; + end + + na = length (a2) ; + nb = length (b2) ; + ns = length (s2) ; %#ok + + nab = na + nb ; + + plot ([.5 na+.5 na+.5 .5 .5], [.5 .5 na+.5 na+.5 .5], 'r', 'LineWidth', 2) ; + + plot ([na nab nab na na]+0.5, [na na nab nab na]+0.5, 'r', 'LineWidth', 2) ; + + plot ([.5 nab+.5 nab+.5 .5 .5], [.5 .5 nab+.5 nab+.5 .5], 'g', 'LineWidth', 1) ; + + hold off + + nz1 = nnz (A (a2,b2)) ; + if (nz1 ~= 0) + nz1 %#ok + error ('!') ; + end + + nz2 = nnz (A (a2,b2)) ; + if (nz2 ~= 0) + nz2 %#ok + error ('!') ; + end + + if (length (s) ~= length (s2)) + fprintf ('lengths differ: %d %d\n', length (s), length (s2)) ; + end + + drawnow + % pause + + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/testall.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/testall.m new file mode 100644 index 0000000..b0373cb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/testall.m @@ -0,0 +1,52 @@ +function testall +%TESTALL test all CSparse functions (run tests 1 to 28 below) +% +% Example: +% testall +% See also: cs_demo + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +h = waitbar (0, 'CSparse') ; + +cs_test_make % compile all CSparse, Demo, Text, and Test mexFunctions + +ntests = 28 ; + +testwait (1, ntests, h) ; test1 ; +testwait (2, ntests, h) ; test2 ; +testwait (3, ntests, h) ; test3 ; +testwait (4, ntests, h) ; test4 ; +testwait (5, ntests, h) ; test5 ; +testwait (6, ntests, h) ; test6 ; +testwait (7, ntests, h) ; test7 ; +testwait (8, ntests, h) ; test8 ; +testwait (9, ntests, h) ; test9 ; +testwait (10, ntests, h) ; test10 ; +testwait (11, ntests, h) ; test11 ; +testwait (12, ntests, h) ; test12 ; +testwait (13, ntests, h) ; test13 ; +testwait (14, ntests, h) ; test14 ; +testwait (15, ntests, h) ; test15 ; +testwait (16, ntests, h) ; test16 ; +testwait (17, ntests, h) ; test17 ; +testwait (18, ntests, h) ; test18 ; +testwait (19, ntests, h) ; test19 ; +testwait (20, ntests, h) ; test20 ; +testwait (21, ntests, h) ; test21 ; +testwait (22, ntests, h) ; test22 ; +testwait (23, ntests, h) ; test23 ; +testwait (24, ntests, h) ; test24 ; +testwait (25, ntests, h) ; test25 ; +testwait (26, ntests, h) ; test26 ; +testwait (27, ntests, h) ; test27 ; +testwait (28, ntests, h) ; test28 ; + +close (h) +fprintf ('All CSparse tests passed\n') ; + +function testwait (n,ntests,h) +fprintf ('\n------------------------ test%d\n', n) ; +waitbar (n/(ntests+1), h, sprintf ('CSparse test %d of %d\n', n, ntests)) ; + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/Test/testh.m b/OpenDSSC/klusolve/CSparse/MATLAB/Test/testh.m new file mode 100644 index 0000000..883e103 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/Test/testh.m @@ -0,0 +1,85 @@ +function testh +%TESTH test Householder reflections +% +% Example: +% testh +% See also: testall + +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + + +format long e +fprintf ('-------------------------------------------------\n') ; +x = [-3 4 5]' ; +disp (x) ; +[v, beta, s] = house (x) ; +disp ('v = ') ; +disp (v) ; +disp ('beta = ') ; +disp (beta) ; +disp ('s = ') ; +disp (s) ; +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; + + +x = [3 4 5]' ; +disp (x) ; +[v, beta, s] = house (x) ; +disp ('v = ') ; +disp (v) ; +disp ('beta = ') ; +disp (beta) ; +disp ('s = ') ; +disp (s) ; +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; + +x = [1 eps]' ; +disp (x) ; +[v, beta, s] = house (x) ; +disp ('v = ') ; +disp (v) ; +disp ('beta = ') ; +disp (beta) ; +disp ('s = ') ; +disp (s) ; +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; + +x = pi ; +disp (x) ; +[v, beta, s] = house (x) ; +disp ('v = ') ; +disp (v) ; +disp ('beta = ') ; +disp (beta) ; +disp ('s = ') ; +disp (s) ; +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; + +x = -pi ; +disp (x) ; +[v, beta, s] = house (x) ; +disp ('v = ') ; +disp (v) ; +disp ('beta = ') ; +disp (beta) ; +disp ('s = ') ; +disp (s) ; +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; + +x = [1 0 0]' ; +disp (x) ; +[v, beta, s] = house (x) ; %#ok +x = x - v*(beta*(v'*x)) ; +disp (x) ; +fprintf ('-------------------------------------------------\n') ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Contents.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Contents.m new file mode 100644 index 0000000..5af7679 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Contents.m @@ -0,0 +1,17 @@ +% UFget: MATLAB interface for the UF Sparse Matrix Collection. +% +% UFget - loads a matrix from the UF Sparse Matrix Collection. +% UFweb - opens the URL for a matrix. +% UFgrep - search for matrices in the UF Sparse Matrix Collection. +% UFkinds - get 'kind' of each problem in the UF collection. +% +% Helper functions: +% +% UFget_defaults - returns default parameter settings for UFget. +% UFget_example - a demo for UFget. +% UFget_lookup - gets the group, name, and id of a matrix. +% +% Example: +% help UFget + +% Copyright 2009, Timothy A. Davis diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Makefile b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Makefile new file mode 100644 index 0000000..54dab27 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/Makefile @@ -0,0 +1,7 @@ +UFgui.jar: UFgui.java UFhelp.html + javac UFgui.java + jar cfe UFgui.jar UFgui *.class UFhelp.html + - $(RM) *.class + +run: UFgui.jar + java -jar UFgui.jar diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/README.txt b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/README.txt new file mode 100644 index 0000000..acb87d7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/README.txt @@ -0,0 +1,126 @@ +UFget: MATLAB and Java interfaces to the UF sparse matrix collection. + +REQUIREMENTS: + + Java JRE 1.6.0 or later is required for the UFgui Java program. + UFget requires MATLAB 7.0. A few of the largest matrices require MATLAB + 7.3 or later. + +Copyright 2005-2009, Tim Davis, University of Florida. +Availability: http://www.cise.ufl.edu/research/sparse/mat/UFget.html + +See http://www.cise.ufl.edu/research/sparse/mat/UFget +for a single archive file with all the files listed below: + + UFget/README.txt this file + UFget/UFsettings.txt default settings for Java and MATLAB + + for Java: + UFget/UFgui.java a stand-alone Java interface to the collection + UFget/UFgui.jar the compiled UFgui program + UFget/UFhelp.html help for UFgui + UFget/Makefile for compiling UFgui.java into UFgui.jar + UFget/matrices/UFstats.txt matrix statistics file for UFgui.java + + for MATLAB: + UFget/Contents.m help for UFget in MATLAB + UFget/UFget_defaults.m default parameter settings for UFget + UFget/UFget_example.m demo for UFget + UFget/UFget_lookup.m get the group, name, and id of a matrix + UFget/UFget.m primary user interface + UFget/UFgrep.m searches for matrices by name + UFget/UFkinds.m returns the 'kind' for all matrices + UFget/UFweb.m opens the URL for a matrix or collection + UFget/mat/UF_Index.mat index to the UF sparse matrix collection + + download directories: + UFget/MM for Matrix Market files + UFget/RB for Rutherford/Boeing files + UFget/mat for *.mat files + UFget/matrices for *.png icon images of the matrices + +For the Java UFgui program: + + To run the UFgui on Windows or Mac OS X, just double-click the UFgui.jar + file. Or, on any platform, type the following command in your command + window: + + java -jar UFgui.jar + + If that doesn't work, then you need to install the Java JDK or JRE and add + it to your path. See http://java.sun.com/javase/downloads/index.jsp and + http://java.sun.com/javase/6/webnotes/install/index.html for more + information. For Ubuntu, you can install Java by running the Synaptics + package manager. + + The UFgui.jar file is the compiled version of UFgui.java. If you modify + UFgui.java, you can recompile it (for Unix/Linux/Mac/Solaris) by typing + the command: + + make + + To run the UFgui in Linux/Solaris/Unix, your window manager might support + double-clicking the UFgui.jar file as well. If not, type either of + the following commands: + + java -jar UFgui.jar + + or + + make run + + +For the UFget.m MATLAB interface: + + To install the MATLAB package, just add the path containing the UFget + directory to your MATLAB path. Type "pathtool" in MATLAB for more details. + + For a simple example of use, type this command in MATLAB: + + UFget_example + + The MATLAB statement + + Problem = UFget ('HB/arc130') + + (for example), will download a sparse matrix called HB/arc130 (a laser + simulation problem) and load it into MATLAB. You don't need to use your + web browser to load the matrix. The statement + + Problem = UFget (6) + + will also load same the HB/arc130 matrix. Each matrix in the collection + has a unique identifier, in the range 1 to the number of matrices. As new + matrices are added, the id's of existing matrices will not change. + + To view an index of the entire collection, just type + + UFget + + in MATLAB. To modify your download directory, edit the UFget_defaults.m + file (note that this will not modify the download directory for the + UFgui java program, however). + + To open a URL of the entire collection, just type + + UFweb + + To open the URL of a group of matrices in the collection: + + UFweb ('HB') + + To open the web page for one matrix, use either of these formats: + + UFweb ('HB/arc130') + UFweb (6) + + To download a new index, to get access to new matrices: + + UFget ('refresh') + + (by default, using UFget downloads the index every 90 days anyway). + + To search for matrices + +For more information on how the matrix statistics were created, see +http://www.cise.ufl.edu/research/sparse/SuiteSparse. diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget.m new file mode 100644 index 0000000..3d8119c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget.m @@ -0,0 +1,198 @@ +function Problem = UFget (matrix, UF_Index) +%UFGET loads a matrix from the UF Sparse Matrix Collection. +% +% Problem = UFget(matrix) loads a matrix from the UF sparse matrix collection, +% specified as either a number (1 to the # of matrices in the collection) or +% as a string (the name of the matrix). With no input parameters, index=UFget +% returns an index of matrices in the collection. A local copy of the matrix +% is saved. If no input or output arguments are provided, the index is +% printed. With a 2nd parameter (Problem = UFget (matrix, index)), the index +% file is not loaded. This is faster if you are loading lots of matrices. +% +% Examples: +% index = UFget ; % loads index +% index = UFget ('refresh') ; % forces download of new index +% index = UFget ('update') ; % same as 'refresh' +% +% Problem = UFget (6) % 4 ways of loading the same Problem +% Problem = UFget ('HB/arc130') +% Problem = UFget (6, index) +% Problem = UFget ('HB/arc130', index) +% +% See also UFgrep, UFweb, UFget_example, UFget_defaults, urlwrite. + +% Copyright 2009, Tim Davis, University of Florida. + +%------------------------------------------------------------------------------- +% get the parameter settings +%------------------------------------------------------------------------------- + +params = UFget_defaults ; + +% The UF_Index.mat file is used by UFget only, not by UFgui.java. +indexfile = sprintf ('%sUF_Index.mat', params.dir) ; +indexurl = sprintf ('%s/UF_Index.mat', params.url) ; + +% The UFstats.csv file is used by the UFgui.java program. It is also used by +% the UFkinds.m function, which reads the file to find the problem kind for +% each matrix in the collection. +statfile = sprintf ('%smatrices/UFstats.csv', params.topdir) ; +staturl = sprintf ('%s/matrices/UFstats.csv', params.topurl) ; + +%------------------------------------------------------------------------------- +% get the index file (download a new one if necessary) +%------------------------------------------------------------------------------- + +refresh = 0 ; +if nargin == 0 + % if the user passed in a zero or no argument at all, return the index file + matrix = 0 ; +else + % UFget ('refresh') downloads the latest index file from the web + if (ischar (matrix)) + if (strcmp (matrix, 'refresh') || strcmp (matrix, 'update')) + matrix = 0 ; + refresh = 1 ; + end + end +end + +if (~refresh) + try + % load the existing index file + if (nargin < 2) + load (indexfile) ; + end + % see if the index file is old; if so, download a fresh copy + fileinfo = dir (indexfile) ; + refresh = (fileinfo.datenum + params.refresh < now) ; + catch + % oops, no index file, or a refresh is due. download it. + refresh = 1 ; + end +end + +err = '' ; % to catch a download error, if any + +if (refresh) + % a new UF_Index.mat file to get access to new matrices (if any) + try + if (~exist (params.dir, 'dir')) + mkdir (params.dir) ; + end + + % get a new UF_index.mat file + tmp = tempname ; % download to a temp file first + old = sprintf ('%sUF_Index_old.mat', params.dir) ; + urlwrite (indexurl, tmp) ; % download the latest index file + try + movefile (indexfile, old, 'f') ; % keep a backup of the old index + catch + % backup failed, continue anyway + end + movefile (tmp, indexfile, 'f') ; % move the new index into place + + % get a new UFstats.csv file + tmp = tempname ; % download to a temp file first + old = sprintf ('%smatrices/UFstats_old.csv', params.topdir) ; + urlwrite (staturl, tmp) ; % download the latest stats file + try + movefile (statfile, old, 'f') ; % keep a backup of the old stats + catch + % backup failed, continue anyway + end + movefile (tmp, statfile, 'f') ; % move the new index into place + + catch + err = lasterr ; + end + load (indexfile) ; + UF_Index.DownloadTimeStamp = now ; + save (indexfile, 'UF_Index') ; +end + +%------------------------------------------------------------------------------- +% return the index file if requested +%------------------------------------------------------------------------------- + +if (matrix == 0) + if (nargout == 0) + % no output arguments have been passed, so print the index file + fprintf ('\nUF sparse matrix collection index: %s\n', ... + UF_Index.LastRevisionDate) ; + fprintf ('\nLegend:\n') ; + fprintf ('(p,n)sym: symmetry of the pattern and values\n') ; + fprintf (' (0 = unsymmetric, 1 = symmetric, - = not computed)\n') ; + fprintf ('type: real\n') ; + fprintf (' complex\n') ; + fprintf (' binary: all entries are 0 or 1\n') ; + nmat = length (UF_Index.nrows) ; + for j = 1:nmat + if (mod (j, 25) == 1) + fprintf ('\n') ; + fprintf ('ID Group/Name nrows-by- ncols nonzeros (p,n)sym type\n') ; + end + s = sprintf ('%s/%s', UF_Index.Group {j}, UF_Index.Name {j}) ; + fprintf ('%4d %-30s %7d-by-%7d %9d ', ... + j, s, UF_Index.nrows (j), UF_Index.ncols (j), UF_Index.nnz (j)) ; + psym = UF_Index.pattern_symmetry (j) ; + nsym = UF_Index.numerical_symmetry (j) ; + if (psym < 0) + fprintf (' - ') ; + else + fprintf (' %4.2f', psym) ; + end + if (nsym < 0) + fprintf (' - ') ; + else + fprintf (' %4.2f', nsym) ; + end + if (UF_Index.isBinary (j)) + fprintf (' binary\n') ; + elseif (~UF_Index.isReal (j)) + fprintf (' complex\n') ; + else + fprintf (' real\n') ; + end + end + else + Problem = UF_Index ; + end + + if (~isempty (err)) + fprintf ('\nUFget: unable to download latest index; using old one.\n') ; + disp (err) ; + end + return ; +end + +%------------------------------------------------------------------------------- +% determine if the matrix parameter is a matrix index or name +%------------------------------------------------------------------------------- + +[group matrix id] = UFget_lookup (matrix, UF_Index) ; + +if (id == 0) + error ('invalid matrix') ; +end + +%------------------------------------------------------------------------------- +% download the matrix (if needed) and load it into MATLAB + +matdir = sprintf ('%s%s%s%s.mat', params.dir, group) ; +matfile = sprintf ('%s%s%s.mat', matdir, filesep, matrix) ; +maturl = sprintf ('%s/%s/%s.mat', params.url, group, matrix) ; + +if (~exist (matdir, 'dir')) + mkdir (matdir) ; % create the Group directory +end + +if (~exist (matfile, 'file')) + fprintf ('downloading %s\n', maturl) ; + fprintf ('to %s\n', matfile) ; + tmp = tempname ; % download to a temp file first + urlwrite (maturl, tmp) ; + movefile (tmp, matfile, 'f') ; % move the new matrix into place +end + +load (matfile) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_defaults.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_defaults.m new file mode 100644 index 0000000..a907e94 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_defaults.m @@ -0,0 +1,71 @@ +function params = UFget_defaults +%UFGET_DEFAULTS returns default parameter settings for UFget. +% Usage: params = UFget_defaults ; Returns the default parameter settings for +% UFget. Edit the UFget/UFsettings.txt file to change these settings. +% +% params.url: URL for *.mat files +% params.dir: your local directory for downloaded *.mat files +% params.refresh: how many days should elapse before re-downloading the +% index file (for obtaining access to new matrices in the collection). +% params.topurl: URL for UF Sparse Matrix Collection +% params.topdir: your directory for mat/, matrices/, MM/ and RB/ directories +% +% Example: +% params = UFget_defaults ; +% +% See also UFget. + +% Copyright 2009, Tim Davis, University of Florida. + +% decode the current directory for this M-file +s = which (mfilename) ; +i = find (s == filesep) ; +this = s (1:i(end)) ; + +% defaults, if UFsettings.txt is not present +params.topdir = '' ; +params.topurl = 'http://www.cise.ufl.edu/research/sparse' ; +params.refresh = 30 ; + +% open the UFsettings.txt file, if present, and read the default settings + +f = -1 ; +try + f = fopen (sprintf ('%sUFsettings.txt', this), 'r') ; + if (f >= 0) + % get the location of the mat directory + s = fgetl (f) ; + if (ischar (s)) + params.topdir = s ; + end + % get the default URL + s = fgetl (f) ; + if (ischar (s)) + params.topurl = s ; + end + % get the refresh rate + s = fgetl (f) ; + if (ischar (s) && ~isempty (s)) + params.refresh = str2double (s) ; + end + end +catch +end + +try + if (f >= 0) + fclose (f) ; + end +catch +end + +if (isempty (params.topdir)) + params.topdir = this ; +end + +if (params.topdir (end) ~= filesep) + params.topdir = [params.topdir filesep] ; +end + +params.url = [params.topurl '/mat'] ; +params.dir = sprintf ('%smat%s', params.topdir, filesep) ; diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_example.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_example.m new file mode 100644 index 0000000..cd45c09 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_example.m @@ -0,0 +1,30 @@ +%UFGET_EXAMPLE a demo for UFget. +% This example script gets the index file of the UF sparse matrix collection, +% and then loads in all symmetric non-binary matrices, in increasing order of +% number of rows in the matrix. +% +% Example: +% type UFget_example ; % to see an example of how to use UFget +% +% See also UFget, UFweb, UFgrep. + +% Copyright 2009, Tim Davis, University of Florida. + +type UFget_example ; + +index = UFget ; +f = find (index.numerical_symmetry == 1 & ~index.isBinary) ; +[y, j] = sort (index.nrows (f)) ; +f = f (j) ; + +for i = f + fprintf ('Loading %s%s%s, please wait ...\n', ... + index.Group {i}, filesep, index.Name {i}) ; + Problem = UFget (i,index) ; + disp (Problem) ; + spy (Problem.A) ; + title (sprintf ('%s:%s', Problem.name, Problem.title')) ; + UFweb (i) ; + input ('hit enter to continue:') ; +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_lookup.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_lookup.m new file mode 100644 index 0000000..5cef1b2 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFget_lookup.m @@ -0,0 +1,77 @@ +function [group, name, id] = UFget_lookup (matrix, UF_Index) +%UFGET_LOOKUP gets the group, name, and id of a matrix. +% +% Example: +% [group name id] = UFget_lookup (matrix, UF_Index) +% +% See also UFget. + +% Copyright 2009, Tim Davis, University of Florida. + +if (isnumeric (matrix)) + + % make sure that the matrix parameter is only one integer value + % this means that if we get an array, just use the first value + id = fix (full (matrix (1))) ; + + % if the index is less than one or bigger than the length of the array, + % then no particular matrix is accessed + if (id > length (UF_Index.nrows) | id < 1) %#ok + id = 0 ; + group = '' ; + name = '' ; + else + % assign the group and name for the given id + group = UF_Index.Group {matrix} ; + name = UF_Index.Name {matrix} ; + end + +elseif (ischar (matrix)) + + % the group and matrix name are in the string as in GroupName\MatrixName + + % find the group index for the file separator + % check both types of slashes, and a colon + gi = find (matrix == '/') ; + if (length (gi) == 0) %#ok + gi = find (matrix == '\') ; + end + if (length (gi) == 0) %#ok + gi = find (matrix == ':') ; + end + + % if no name divider is in the string, a whole group is specified + if (length (gi) == 0) %#ok + + id = 0 ; + group = matrix ; + name = '' ; + + else + + % group equals the first part of the string up to the character before + % the last file separator + group = matrix (1:gi(end)-1) ; + + % group equals the last section of the string after the last file + % separator + name = matrix (gi(end)+1:end) ; + + % validate the given name and group by checking the index for a match + refName = strmatch (name, UF_Index.Name) ; + refGroup = strmatch (group, UF_Index.Group) ; + id = intersect (refName, refGroup) ; + if (length (id) >= 1) + id = id (1) ; + else + % the given group/matrix does not exist in the index file + id = 0 ; + end + end + +else + + % there is an error in the argument types passed into the function + error ('invalid input') ; + +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFgrep.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFgrep.m new file mode 100644 index 0000000..6712139 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFgrep.m @@ -0,0 +1,53 @@ +function list = UFgrep (expression, index) +%UFGREP search for matrices in the UF Sparse Matrix Collection. +% UFgrep returns a list of Problem id's whose Problem.name string matches an +% expression. With no output arguments, the list is displayed. Otherwise, it +% is returned as a list of integer id's. +% +% Example: +% UFgrep ('HB') ; % all matrices in the HB group +% UFgrep ('\ 0 && s.charAt (0) == 'd') ; + + close_reader (in_reader) ; + + // set up the HTTP proxy + if (proxy_server.length ( ) > 0) + { + if (proxy_port.length ( ) == 0) + { + proxy_port = "80" ; + } + // set the proxy server and port + System.setProperty ("proxySet", "true" ) ; + System.setProperty ("http.proxyHost", proxy_server) ; + System.setProperty ("http.proxyPort", proxy_port) ; + } + + // UFarchive defaults to current working directory, if empty + if (UFarchive.length ( ) == 0) + { + UFarchive = System.getProperty ("user.dir") ; + } + UFarchive = UFarchive.replace ('\\', File.separatorChar) ; + UFarchive = UFarchive.replace ('/', File.separatorChar) ; + char c = UFarchive.charAt (UFarchive.length ( ) - 1) ; + if (c != File.separatorChar) + { + UFarchive += File.separatorChar ; + } + + if (debug) + { + System.out.println ("") ; + System.out.println ("UFgui, debugging enabled.") ; + System.out.println ("local archive: [" + UFarchive + "]") ; + System.out.println ("UF url: [" + UFsite + "]") ; + System.out.println ("refresh: [" + refresh + "]") ; + System.out.println ("proxy server: [" + proxy_server + "]") ; + System.out.println ("proxy port: [" + proxy_port + "]") ; + } + + //---------------------------------------------------------------------- + // make sure the top-level directories exist + + mat = CheckDir ("mat") ; + MM = CheckDir ("MM") ; + RB = CheckDir ("RB") ; + iconDir = CheckDir ("matrices") ; + + //---------------------------------------------------------------------- + // read in the matrix statistics + + Stats = load_UFstats ( ) ; + + if (Stats == null || + ((today.getTime ( ) - last_download.getTime ( )) / MSEC_PER_DAY + > refresh)) + { + // UFstats file is missing, or old. Download both + // matrices/UFstats.csv and mat/UF_Index.mat. + Stats = download_matrix_stats ( ) ; + if (debug) System.out.println ("downloading new UFstats.csv file") ; + } + + if (Stats == null) + { + // display error dialog and quit + JOptionPane.showMessageDialog (this, + "Download of matrix statistics file failed.", + "Error", JOptionPane.ERROR_MESSAGE) ; + System.exit (-1) ; + } + + //---------------------------------------------------------------------- + // set the title, and close on [x] + + setTitle ("UFgui: UF Sparse Matrix Collection") ; + setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE) ; + + //---------------------------------------------------------------------- + // selection buttons + + JPanel select_Button_Panel = new JPanel ( ) ; + + JButton select_Button = new JButton ("Select") ; + JButton unselect_Button = new JButton ("Deselect") ; + JButton reset_Button = new JButton ("Reset criteria") ; + JButton clear_Button = new JButton ("Clear selections") ; + JButton help_Button = new JButton ("Help") ; + + select_Button_Panel.add (select_Button) ; + select_Button_Panel.add (unselect_Button) ; + select_Button_Panel.add (reset_Button) ; + select_Button_Panel.add (clear_Button) ; + select_Button_Panel.add (help_Button) ; + + select_Button.setToolTipText + ("Click to add matrices that fit the criteria to your selection.") ; + unselect_Button.setToolTipText ("Click to remove matrices " + + "that fit the criteria from your selection.") ; + reset_Button.setToolTipText ("Click to reset criteria, above. " + + "Prior selections, below, are not cleared.") ; + clear_Button.setToolTipText ("Click to clear selections, below. " + + "Criteria, above, is not reset).") ; + help_Button.setToolTipText ("For help, click here") ; + + select_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + make_selection (true) ; + } + } + ) ; + + unselect_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + make_selection (false) ; + } + } + ) ; + + reset_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + reset_Button_action (e) ; + } + } + ) ; + + clear_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + clear_Button_action (e) ; + } + } + ) ; + + help_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + help_Button_action (e) ; + } + } + ) ; + + //---------------------------------------------------------------------- + // download button and format options + + JPanel format_Panel = new JPanel ( ) ; + + format_mat_Button = new JCheckBox ("MATLAB (mat)") ; + format_mm_Button = new JCheckBox ("Matrix Market (MM)") ; + format_rb_Button = new JCheckBox ("Rutherford/Boeing (RB) ") ; + + format_mat_Button.setSelected (true) ; + + format_mat_Button.setToolTipText ("Download in MATLAB *.mat format.") ; + format_mm_Button.setToolTipText ("Download in Matrix Market.") ; + format_rb_Button.setToolTipText + ("Download in Rutherford/Boeing format.") ; + + nselected = 0 ; + nselected_Label = new JLabel ( ) ; + download_Button = new JButton ("Download") ; + // update_Button = new JButton ("Update") ; + // update_Button_status (true) ; + + format_Panel.add (download_Button) ; + format_Panel.add (format_mat_Button) ; + format_Panel.add (format_mm_Button) ; + format_Panel.add (format_rb_Button) ; + format_Panel.add (nselected_Label) ; + // format_Panel.add (update_Button) ; + format_Panel.setMaximumSize (new Dimension (0,0)) ; + + // progress bar and cancel button + FlowLayout progress_Layout = new FlowLayout (FlowLayout.LEADING) ; + JPanel progress_Panel = new JPanel (progress_Layout) ; + + cancel_Button = new JButton ("Cancel") ; + cancel_Button.setEnabled (false) ; + progress1_Bar = new JProgressBar ( ) ; + progress2_Bar = new JProgressBar ( ) ; + progress_size_Label = new JLabel ("") ; + progress1_Bar.setMinimumSize (new Dimension (200,16)) ; + progress2_Bar.setMinimumSize (new Dimension (200,16)) ; + progress_Panel.add (cancel_Button) ; + progress_Panel.add (new JLabel (" Overall progress:")) ; + progress_Panel.add (progress1_Bar) ; + progress_Panel.add (new JLabel (" Current file:")) ; + progress_Panel.add (progress2_Bar) ; + progress_Panel.add (progress_size_Label) ; + progress_Panel.setMaximumSize (new Dimension (0,0)) ; + cancel_Button.setToolTipText ("No downloads in progress.") ; + + download_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + download_Button_action (e) ; + } + } + ) ; + + cancel_Button.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + cancel_Button_action (e) ; + } + } + ) ; + +// update_Button.addActionListener +// ( +// new ActionListener ( ) +// { +// public void actionPerformed (ActionEvent e) +// { +// update_Button_action (e) ; +// } +// } +// ) ; + + JPanel download_Panel = new JPanel ( ) ; + GroupLayout layout3 = new GroupLayout (download_Panel) ; + download_Panel.setLayout (layout3) ; + + layout3.setAutoCreateGaps (true) ; + layout3.setAutoCreateContainerGaps (false) ; + + layout3.setHorizontalGroup + ( + layout3.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (format_Panel) + .addComponent (progress_Panel) + ) ; + + layout3.setVerticalGroup + ( + layout3.createSequentialGroup ( ) + .addComponent (format_Panel) + .addComponent (progress_Panel) + ) ; + + download_Panel.setBorder + (BorderFactory.createTitledBorder ("download")) ; + download_Panel.setMaximumSize (new Dimension (0,0)) ; + + //---------------------------------------------------------------------- + // panel for m, n, nnz, psym, and nsym + + // # of rows + minrow_Field = new JTextField ("") ; + JLabel rowlabel = new JLabel (" \u2264 number of rows \u2264 ") ; + maxrow_Field = new JTextField ("") ; + minrow_Field.setColumns (16) ; + maxrow_Field.setColumns (16) ; + minrow_Field.setToolTipText ("Leave blank for 'zero'.") ; + maxrow_Field.setToolTipText ("Leave blank for 'infinite'.") ; + minrow_Field.setMinimumSize (new Dimension (120,0)) ; + maxrow_Field.setMinimumSize (new Dimension (120,0)) ; + + // # of columns + mincol_Field = new JTextField ("") ; + JLabel collabel = new JLabel (" \u2264 number of columns \u2264 ") ; + maxcol_Field = new JTextField ("") ; + mincol_Field.setColumns (16) ; + maxcol_Field.setColumns (16) ; + mincol_Field.setToolTipText ("Leave blank for 'zero'.") ; + maxcol_Field.setToolTipText ("Leave blank for 'infinite'.") ; + mincol_Field.setMinimumSize (new Dimension (120,0)) ; + maxcol_Field.setMinimumSize (new Dimension (120,0)) ; + + // # of entries + minnz_Field = new JTextField ("") ; + JLabel nnzlabel = new JLabel (" \u2264 number of nonzeros \u2264 ") ; + maxnz_Field = new JTextField ("") ; + minnz_Field.setColumns (16) ; + maxnz_Field.setColumns (16) ; + minnz_Field.setToolTipText ("Leave blank for 'zero'.") ; + maxnz_Field.setToolTipText ("Leave blank for 'infinite'.") ; + minnz_Field.setMinimumSize (new Dimension (120,0)) ; + maxnz_Field.setMinimumSize (new Dimension (120,0)) ; + + // pattern symmetry + minpsym_Field = new JTextField ("0.0") ; + JLabel psymlabel = new JLabel (" \u2264 pattern symmetry \u2264 ") ; + maxpsym_Field = new JTextField ("1.0") ; + minpsym_Field.setColumns (16) ; + maxpsym_Field.setColumns (16) ; + maxpsym_Field.setToolTipText ( + "Refers to position of nonzeros, not their values.\n" + + "1 = perfectly symmetric pattern, 0 = perfectly unsymmetric pattern.") ; + minpsym_Field.setMinimumSize (new Dimension (120,0)) ; + maxpsym_Field.setMinimumSize (new Dimension (120,0)) ; + + // numerical symmetry + minnsym_Field = new JTextField ("0.0") ; + JLabel nsymlabel = new JLabel (" \u2264 numerical symmetry \u2264 ") ; + maxnsym_Field = new JTextField ("1.0") ; + minnsym_Field.setColumns (16) ; + maxnsym_Field.setColumns (16) ; + maxnsym_Field.setToolTipText ( + "1 means A=A', 0 means no nonzero entry A(i,j) = A(j,i).") ; + minnsym_Field.setMinimumSize (new Dimension (120,0)) ; + maxnsym_Field.setMinimumSize (new Dimension (120,0)) ; + + JPanel range_Panel = new JPanel ( ) ; + GroupLayout layout5 = new GroupLayout (range_Panel) ; + range_Panel.setLayout (layout5) ; + layout5.setAutoCreateGaps (false) ; + layout5.setAutoCreateContainerGaps (false) ; + + layout5.setHorizontalGroup + ( + layout5.createSequentialGroup ( ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (minrow_Field) + .addComponent (mincol_Field) + .addComponent (minnz_Field) + .addComponent (minpsym_Field) + .addComponent (minnsym_Field) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (rowlabel) + .addComponent (collabel) + .addComponent (nnzlabel) + .addComponent (psymlabel) + .addComponent (nsymlabel) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (maxrow_Field) + .addComponent (maxcol_Field) + .addComponent (maxnz_Field) + .addComponent (maxpsym_Field) + .addComponent (maxnsym_Field) + ) + ) ; + + layout5.setVerticalGroup + ( + layout5.createSequentialGroup ( ) + + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (minrow_Field) + .addComponent (rowlabel) + .addComponent (maxrow_Field) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (mincol_Field) + .addComponent (collabel) + .addComponent (maxcol_Field) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (minnz_Field) + .addComponent (nnzlabel) + .addComponent (maxnz_Field) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (minpsym_Field) + .addComponent (psymlabel) + .addComponent (maxpsym_Field) + ) + .addGroup + ( + layout5.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (minnsym_Field) + .addComponent (nsymlabel) + .addComponent (maxnsym_Field) + ) + + ) ; + + range_Panel.setMaximumSize (new Dimension (0,0)) ; + // range_Panel.setBorder (BorderFactory.createTitledBorder ("range")) ; + + //---------------------------------------------------------------------- + // checkbox panel for posdef, ND, real, and format + + // square or rectangular + JLabel shape_label = new JLabel ("shape ") ; + shape_square_Button = new JRadioButton ("square ") ; + shape_rect_Button = new JRadioButton ("rectangular ") ; + shape_either_Button = new JRadioButton ("either ") ; + shape_either_Button.setSelected (true) ; + ButtonGroup shape_group = new ButtonGroup ( ) ; + shape_group.add (shape_square_Button) ; + shape_group.add (shape_rect_Button) ; + shape_group.add (shape_either_Button) ; + shape_square_Button.setToolTipText + ("Select 'yes' for square matrices.") ; + shape_rect_Button.setToolTipText + ("Select 'no' for rectangular matrices only.") ; + shape_either_Button.setToolTipText + ("Select 'either' for any matrix.") ; + + // positive definite + JLabel posdef_label = new JLabel ("positive definite? ") ; + posdef_yes_Button = new JRadioButton ("yes") ; + posdef_no_Button = new JRadioButton ("no") ; + posdef_either_Button = new JRadioButton ("either") ; + posdef_either_Button.setSelected (true) ; + ButtonGroup posdef_group = new ButtonGroup ( ) ; + posdef_group.add (posdef_yes_Button) ; + posdef_group.add (posdef_no_Button) ; + posdef_group.add (posdef_either_Button) ; + + posdef_yes_Button.setToolTipText + ("Select 'yes' for symmetric positive definite matrices only.") ; + posdef_no_Button.setToolTipText + ("Select 'no' for non-positive definite matrices only.") ; + posdef_either_Button.setToolTipText + ("Select 'either' for any matrix.") ; + + // 2D/3D + JLabel nd_label = new JLabel ("2D/3D discretization? ") ; + nd_yes_Button = new JRadioButton ("yes") ; + nd_no_Button = new JRadioButton ("no") ; + nd_either_Button = new JRadioButton ("either") ; + nd_either_Button.setSelected (true) ; + ButtonGroup nd_group = new ButtonGroup ( ) ; + nd_group.add (nd_yes_Button) ; + nd_group.add (nd_no_Button) ; + nd_group.add (nd_either_Button) ; + + nd_yes_Button.setToolTipText + ("Select 'yes' for matrices " + + "arising from 2D or 3D discretizations only.") ; + nd_no_Button.setToolTipText + ("Select 'no' to exclude matrices " + + "arising from 2D or 3D discretizations.") ; + nd_either_Button.setToolTipText ("Select 'either' for any matrix.") ; + + // real or complex + JLabel real_label = new JLabel ("real or complex? ") ; + real_yes_Button = new JRadioButton ("real") ; + real_no_Button = new JRadioButton ("complex") ; + real_either_Button = new JRadioButton ("either") ; + real_either_Button.setSelected (true) ; + ButtonGroup real_group = new ButtonGroup ( ) ; + real_group.add (real_yes_Button) ; + real_group.add (real_no_Button) ; + real_group.add (real_either_Button) ; + + real_yes_Button.setToolTipText + ("Select 'real' for real matrices only (includes integer and binary).") ; + real_no_Button.setToolTipText + ("Select 'complex' for complex matrices only.") ; + real_either_Button.setToolTipText + ("Select 'either' for any matrix.") ; + + JPanel check_Panel = new JPanel ( ) ; + GroupLayout layout4 = new GroupLayout (check_Panel) ; + check_Panel.setLayout (layout4) ; + layout4.setAutoCreateGaps (false) ; + layout4.setAutoCreateContainerGaps (false) ; + + layout4.setHorizontalGroup + ( + layout4.createSequentialGroup ( ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (shape_label) + .addComponent (posdef_label) + .addComponent (nd_label) + .addComponent (real_label) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (shape_square_Button) + .addComponent (posdef_yes_Button) + .addComponent (nd_yes_Button) + .addComponent (real_yes_Button) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (shape_rect_Button) + .addComponent (posdef_no_Button) + .addComponent (nd_no_Button) + .addComponent (real_no_Button) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (shape_either_Button) + .addComponent (posdef_either_Button) + .addComponent (nd_either_Button) + .addComponent (real_either_Button) + ) + ) ; + + layout4.setVerticalGroup + ( + layout4.createSequentialGroup ( ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (shape_label) + .addComponent (shape_square_Button) + .addComponent (shape_rect_Button) + .addComponent (shape_either_Button) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (posdef_label) + .addComponent (posdef_yes_Button) + .addComponent (posdef_no_Button) + .addComponent (posdef_either_Button) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (nd_label) + .addComponent (nd_yes_Button) + .addComponent (nd_no_Button) + .addComponent (nd_either_Button) + ) + .addGroup + ( + layout4.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (real_label) + .addComponent (real_yes_Button) + .addComponent (real_no_Button) + .addComponent (real_either_Button) + ) + ) ; + + check_Panel.setMaximumSize (new Dimension (0,0)) ; + + //---------------------------------------------------------------------- + // Group and Kind lists + + Kinds = FindKinds ( ) ; + Groups = FindGroups ( ) ; + + Group_List = new JList ((Object [ ]) Groups) ; + Kind_List = new JList ((Object [ ]) Kinds) ; + + JScrollPane Group_Pane = new JScrollPane (Group_List) ; + JScrollPane Kind_Pane = new JScrollPane (Kind_List) ; + + Kind_Pane.setBorder (BorderFactory.createTitledBorder ("kind")) ; + Group_Pane.setBorder (BorderFactory.createTitledBorder ("group")) ; + + Group_List.setFont (plain_Font) ; + Kind_List.setFont (plain_Font) ; + + Group_Pane.setVerticalScrollBarPolicy + (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ; + Kind_Pane.setVerticalScrollBarPolicy + (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) ; + + Group_List.setVisibleRowCount (5) ; + Kind_List.setVisibleRowCount (5) ; + + // Group_List.setPreferredSize (new Dimension (200,100)) ; + // Kind_List.setPreferredSize (new Dimension (200,100)) ; + + JPanel list_Panel = new JPanel ( ) ; + GroupLayout layout9 = new GroupLayout (list_Panel) ; + list_Panel.setLayout (layout9) ; + + layout9.setAutoCreateGaps (true) ; + layout9.setAutoCreateContainerGaps (false) ; + + layout9.setHorizontalGroup + ( + layout9.createSequentialGroup ( ) + .addComponent (Group_Pane) + .addComponent (Kind_Pane) + ) ; + + layout9.setVerticalGroup + ( + layout9.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (Group_Pane) + .addComponent (Kind_Pane) + ) ; + + list_Panel.setMinimumSize (new Dimension (450,150)) ; + + //---------------------------------------------------------------------- + // selection panel + JPanel selection_Panel = new JPanel ( ) ; + GroupLayout layout2 = new GroupLayout (selection_Panel) ; + selection_Panel.setLayout (layout2) ; + layout2.setAutoCreateGaps (true) ; + layout2.setAutoCreateContainerGaps (false) ; + layout2.setHorizontalGroup + ( + layout2.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (range_Panel) + .addComponent (check_Panel) + .addComponent (list_Panel) + .addComponent (select_Button_Panel) + ) ; + layout2.setVerticalGroup + ( + layout2.createSequentialGroup ( ) + .addComponent (range_Panel) + .addComponent (check_Panel) + .addComponent (list_Panel) + .addComponent (select_Button_Panel) + ) ; + selection_Panel.setBorder + (BorderFactory.createTitledBorder ("selection criteria")) ; + selection_Panel.setMaximumSize (new Dimension (0,0)) ; + + //---------------------------------------------------------------------- + // create the table of matrices + + matrix_model = new matrix_Table_Model ( ) ; + matrix_Table = new JTable (matrix_model) + { + // table header tool tips + protected JTableHeader createDefaultTableHeader ( ) + { + return new JTableHeader (columnModel) + { + public String getToolTipText (MouseEvent e) + { + String tip = null ; + java.awt.Point p = e.getPoint ( ) ; + int i = columnModel.getColumnIndexAtX (p.x) ; + int j = columnModel.getColumn (i).getModelIndex ( ) ; + return matrix_column_tooltips [j] ; + } + } ; + } + } ; + + JTableHeader header = matrix_Table.getTableHeader ( ) ; + final TableCellRenderer hr = header.getDefaultRenderer ( ) ; + header.setDefaultRenderer + ( + new TableCellRenderer ( ) + { + public Component getTableCellRendererComponent (JTable table, + Object value, boolean isSelected, boolean hasFocus, + int row, int column) + { + Component co = hr.getTableCellRendererComponent ( + table, value, isSelected, hasFocus, row, column) ; + co.setFont (small_Font) ; + return (co) ; + } + } + ) ; + + matrix_model.load_data (Stats) ; + + //---------------------------------------------------------------------- + // popup menu for the table + + JPopupMenu popup = new JPopupMenu ( ) ; + + JMenuItem select_menuItem = + new JMenuItem ("Select highlighted matrices") ; + select_menuItem.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + popup_action (e, true) ; + } + } + ) ; + + JMenuItem unselect_menuItem = + new JMenuItem ("Deselect highlighted matrices") ; + unselect_menuItem.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + popup_action (e, false) ; + } + } + ) ; + + JMenuItem exportcsv_menuItem = + new JMenuItem ("Export selected matrices as CSV file") ; + exportcsv_menuItem.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + export_list_action (e, true) ; + } + } + ) ; + + JMenuItem exportm_menuItem = + new JMenuItem ("Export selected matrices as MATLAB *.m file") ; + exportm_menuItem.addActionListener + ( + new ActionListener ( ) + { + public void actionPerformed (ActionEvent e) + { + export_list_action (e, false) ; + } + } + ) ; + + popup.add (select_menuItem) ; + popup.add (unselect_menuItem) ; + popup.add (exportcsv_menuItem) ; + popup.add (exportm_menuItem) ; + + // Add listener to components that can bring up popup menus. + matrix_Table.addMouseListener (new matrix_Table_PopupListener (popup)) ; + + //---------------------------------------------------------------------- + // set default column widths + + int [ ] columnwidth = { + 40, // 0:select + 30, // 1:mat + 25, // 2:MM + 25, // 3:RB + 38, // 4:id + 110, // 5:Group + 150, // 6:Name + 70, // 7:nrows + 70, // 8:ncols + 70, // 9:nnz + 40, // 10:isReal + 40, // 11:isBinary + 40, // 12:isND + 40, // 13:posdef + 50, // 14:psym + 50, // 15:nsym + 200 } ; // 16:kind + + TableColumn column = null ; + for (int col = 0 ; col < 17 ; col++) + { + column = matrix_Table.getColumnModel ( ).getColumn (col) ; + column.setPreferredWidth (columnwidth [col]) ; + } + + //---------------------------------------------------------------------- + // set the view size, sort by id, and add the table to a scroll pane + + matrix_Table.setPreferredScrollableViewportSize + (new Dimension (500,70)) ; + matrix_Table.setFillsViewportHeight (true) ; + matrix_Table.setAutoCreateRowSorter (true) ; + + matrix_Table.getSelectionModel ( ) + .addListSelectionListener (new matrix_Table_RowListener ( )) ; + + // sort by id + java.util.List sortKeys = + new ArrayList ( ) ; + sortKeys.add (new RowSorter.SortKey (4, SortOrder.ASCENDING)) ; + (matrix_Table.getRowSorter ( )).setSortKeys (sortKeys) ; + + matrix_Table.getTableHeader ( ).setReorderingAllowed (false) ; + JScrollPane scroll_Pane = new JScrollPane (matrix_Table) ; + scroll_Pane.setBorder (BorderFactory.createTitledBorder (UFarchive)) ; + + //---------------------------------------------------------------------- + // create the icon and display the default matrix + + icon_Label = new JLabel ( ) ; + icon_Label.setFont (plain_Font) ; + icon_Label.setVerticalTextPosition (JLabel.BOTTOM) ; + icon_Label.setHorizontalTextPosition (JLabel.CENTER) ; + icon_Label.setBorder (BorderFactory.createTitledBorder ("matrix icon")); + update_icon ("HB/west0479") ; + + //---------------------------------------------------------------------- + // create the top panel (selection panel and icon) + + JPanel top_Panel = new JPanel ( ) ; + GroupLayout layout8 = new GroupLayout (top_Panel) ; + top_Panel.setLayout (layout8) ; + + layout8.setAutoCreateGaps (true) ; + layout8.setAutoCreateContainerGaps (false) ; + + layout8.setHorizontalGroup + ( + layout8.createSequentialGroup ( ) + .addComponent (selection_Panel) + .addComponent (icon_Label) + ) ; + + layout8.setVerticalGroup + ( + layout8.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (selection_Panel) + .addComponent (icon_Label) + ) ; + + top_Panel.setMaximumSize (new Dimension (0,0)) ; + + //---------------------------------------------------------------------- + // create the root layout manager + + Container pane = getContentPane ( ) ; + GroupLayout layout = new GroupLayout (pane) ; + pane.setLayout (layout) ; + layout.setAutoCreateGaps (true) ; + layout.setAutoCreateContainerGaps (false) ; + + layout.setHorizontalGroup + ( + layout.createParallelGroup (GroupLayout.Alignment.LEADING) + .addComponent (top_Panel) + .addComponent (scroll_Pane) + .addComponent (download_Panel) + ) ; + + layout.setVerticalGroup + ( + layout.createSequentialGroup ( ) + .addComponent (top_Panel) + .addComponent (scroll_Pane) + .addComponent (download_Panel) + ) ; + + setSize (1100,750) ; + + //---------------------------------------------------------------------- + // create the file chooser; not shown until "export" is chosen + + chooser = new JFileChooser ( ) ; + chooser.setFileSelectionMode (JFileChooser.FILES_AND_DIRECTORIES) ; + + gui_ready = true ; + set_selected_label (true) ; + + //---------------------------------------------------------------------- + // start a thread to download any icons not present + + get_all_icons ( ) ; + } + + //-------------------------------------------------------------------------- + // yes/no/unknown + //-------------------------------------------------------------------------- + + private String yes_no (int k) + { + if (k < 0) + { + return ("?") ; + } + else if (k == 0) + { + return ("no") ; + } + else + { + return ("yes") ; + } + } + + //-------------------------------------------------------------------------- + // ternary + //-------------------------------------------------------------------------- + + private int ternary (String s) + { + long k = Long.parseLong (s) ; + if (k < 0) + { + return (-1) ; + } + else if (k == 0) + { + return (0) ; + } + else + { + return (1) ; + } + } + + //-------------------------------------------------------------------------- + // read the UFstats file + //-------------------------------------------------------------------------- + + private Object [ ][ ] load_UFstats ( ) + { + if (debug) System.out.println ("reading UFstats.csv file") ; + Object [ ][ ] S = null ; + int nmatrices = 0 ; + in_reader = null ; + try + { + // get the number of matrices in the UF Sparse Matrix Collection + in_reader = new BufferedReader (new FileReader + (fix_name (UFstats))) ; + nmatrices = Integer.parseInt (in_reader.readLine ( )) ; + // skip past the creation date and time + String ignore = in_reader.readLine ( ) ; + // get the time of last download from the file modification time + last_download = + new Date (new File (fix_name (UFstats)).lastModified ( )) ; + } + catch (Exception e) + { + // this is OK, for now, since we can try to download a new one + if (debug) System.out.println ("reading UFstats.csv file failed") ; + return (null) ; + } + try + { + // read the rest of the file + S = new Object [nmatrices][13] ; + for (int id = 1 ; id <= nmatrices ; id++) + { + // split the tokens by comma + String [ ] r = (in_reader.readLine ( )).split (",") ; + S [id-1][0] = id ; // id + S [id-1][1] = r [0] ; // Group + S [id-1][2] = r [1] ; // Name + S [id-1][3] = Long.parseLong (r [2]) ; // nrows + S [id-1][4] = Long.parseLong (r [3]) ; // ncols + S [id-1][5] = Long.parseLong (r [4]) ; // nnz + + S [id-1][6] = ternary (r [5]) ; // isReal + S [id-1][7] = ternary (r [6]) ; // isBinary + S [id-1][8] = ternary (r [7]) ; // isND + S [id-1][9] = ternary (r [8]) ; // posdef + + S [id-1][10] = Double.parseDouble (r [9]) ; // psym + S [id-1][11] = Double.parseDouble (r [10]) ; // nsym + S [id-1][12] = r [11] ; // kind + } + } + catch (Exception e) + { + // this is OK, for now, since we can try to download a new one + if (debug) System.out.println ("reading UFstats.csv file failed") ; + return (null) ; + } + finally + { + close_reader (in_reader) ; + } + return (S) ; + } + + //-------------------------------------------------------------------------- + // tool tips for each column of the matrix table + //-------------------------------------------------------------------------- + + protected String [ ] matrix_column_tooltips = + { + // 0:select: + "Click to select a matrix. This is the only column you can edit.", + "'x' if MAT format already downloaded", // 1:mat + "'x' if MM format already downloaded", // 2:MM + "'x' if RB format already downloaded", // 3:MM + "matrix id", // 4:id + "matrix group (typically a person or organization)",// 5:Group + "matrix name (full name is Group/Name)", // 6:Name + "# of rows in the matrix", // 7:nrows + "# of columns in the matrix", // 8:ncols + "# of nonzeros in the matrix", // 9:nnz + "if the matrix is real (not complex)", // 10:isReal + "if the matrix is binary", // 11:isBinary + "if the matrix arises from a 2D/3D discretization", // 12:isND + "if the matrix is symmetric positive definite", // 13:posdef + // 14:psym: + "symmetry of nonzero pattern (0: none, 1: pattern(A)=pattern(A')", + "symmetry of nonzero values (0: none, 1: A=A'", // 15:nsym + // 16:kind: + "the matrix 'kind' is the problem domain from which it arises" + } ; + + //-------------------------------------------------------------------------- + // control whether changes to the table cause updates to fire + //-------------------------------------------------------------------------- + + public boolean fire_status = true ; + + public void fire_updates (boolean fire) + { + fire_status = fire ; + if (fire) + { + // touch the table to force a fire + set_table_value (get_table_value (1, 0), 1, 0) ; + } + } + + //-------------------------------------------------------------------------- + // table of matrix statistics + //-------------------------------------------------------------------------- + + class matrix_Table_Model extends AbstractTableModel + { + private String [ ] columnNames = + { + "select", "mat", "MM", "RB", + "id", "Group", "Name", "# rows", "# cols", "# nonzeros", "real", + "binary", "2D/3D", "posdef", "psym", "nsym", "kind" } ; + + private Object [ ][ ] data = null ; + + public int getColumnCount ( ) + { + return (columnNames.length) ; + } + + public int getRowCount ( ) + { + return (data.length) ; + } + + public String getColumnName (int col) + { + return (columnNames [col]) ; + } + + public Object getValueAt (int row, int col) + { + return (data [row][col]) ; + } + + public boolean isCellEditable (int row, int col) + { + // only the "select" column is edittable + return (col == 0) ; + } + + public void setValueAt (Object value, int row, int col) + { + if (col == 0 && gui_ready && ((Boolean) data [row][0]) != value) + { + if ((Boolean) value == false) + { + // changing from selected to unselected + nselected-- ; + } + else + { + // changing from unselected to selected + nselected++ ; + } + set_selected_label (download_Button.isEnabled ( )) ; + } + data [row][col] = value ; + if (fire_status) fireTableDataChanged ( ) ; + } + + public Class getColumnClass (int col) + { + return (getValueAt (0, col).getClass ( )) ; + } + + public void load_data (Object [ ][ ] newstats) + { + // load the matrix table with all matrix statistics + data = new Object [newstats.length][17] ; + nselected = 0 ; + for (int i = 0 ; i < newstats.length ; i++) + { + // i and j are in terms of the view, but the table is not yet + // sorted because it is not yet visible + data [i][0] = false ; // select column is false + for (int j = 1 ; j < 4 ; j++) + { + // mat, MM, and RB, which can change later: + data [i][j] = "-" ; + } + for (int j = 0 ; j < 13 ; j++) + { + // matrix stats, which do not change: + // 4:id, 5:Group, 6:Name, 7:nrows, 8:ncols, 9:nnz, + // 10:isreal, 11:isBinary, 12:isND, 13:posdef, 14: psym, + // 15:nsym, 16:kind + if (j >= 6 && j <= 9) + { + int k = (Integer) newstats [i][j] ; + if (k < 0) + { + data [i][j+4] = " ?" ; + } + else if (k == 0) + { + data [i][j+4] = " no" ; + } + else + { + data [i][j+4] = " yes" ; + } + } + else + { + data [i][j+4] = newstats [i][j] ; + } + } + } + fireTableDataChanged ( ) ; + } + } + + //-------------------------------------------------------------------------- + // get a value from the matrix table + //-------------------------------------------------------------------------- + + private Object get_table_value (int id, int j) + { + // id is in the range 1 to Stats.length. The model index is id-1. + // Convert this to the row index of the view and then get the data. + // j is in the range 0 to 16, and is the same in the view and the + // model, since column rearranging is never done. + + int i = matrix_Table.convertRowIndexToView (id-1) ; + return (matrix_Table.getValueAt (i, j)) ; + } + + //-------------------------------------------------------------------------- + // set a value in the matrix table + //-------------------------------------------------------------------------- + + private void set_table_value (Object value, int id, int j) + { + // just like get_table_value, setting the data instead of getting it + + int i = matrix_Table.convertRowIndexToView (id-1) ; + matrix_Table.setValueAt (value, i, j) ; + } + + //-------------------------------------------------------------------------- + // get ids of highlighted matrices + //-------------------------------------------------------------------------- + + private int [ ] get_highlighted_ids ( ) + { + // return a list of highlighted matrix id's + + // get the highlighted row indices in the current view + int [ ] highlighted = matrix_Table.getSelectedRows ( ) ; + // convert the row view indices to matrix id's + for (int k = 0 ; k < highlighted.length ; k++) + { + int i = highlighted [k] ; + int id = 1 + matrix_Table.convertRowIndexToModel (i) ; + highlighted [k] = id ; + } + return (highlighted) ; + } + + //-------------------------------------------------------------------------- + // get ids of matrices selected for download + //-------------------------------------------------------------------------- + + private int [ ] get_download_ids ( ) + { + // get the list of ids to download, in view order + nselected = 0 ; + for (int i = 0 ; i < Stats.length ; i++) + { + if ((Boolean) matrix_Table.getValueAt (i, 0)) + { + nselected++ ; + } + } + int [ ] downloads = new int [nselected] ; + int k = 0 ; + for (int i = 0 ; i < Stats.length ; i++) + { + if ((Boolean) matrix_Table.getValueAt (i, 0)) + { + int id = 1 + matrix_Table.convertRowIndexToModel (i) ; + downloads [k++] = id ; + } + } + return (downloads) ; + } + + //-------------------------------------------------------------------------- + // set "Matrices selected:" label and download tool tip + //-------------------------------------------------------------------------- + + private void set_selected_label (boolean enabled) + { + if (gui_ready) + { + nselected_Label.setText + (" Matrices selected: " + nselected + " ") ; + download_Button.setEnabled (enabled) ; + if (enabled) + { + if (nselected == 0) + { + download_Button.setToolTipText + ("No matrices have been selected for download") ; + } + else if (nselected == 1) + { + download_Button.setToolTipText + ("Click to download the single selected matrix") ; + } + else + { + download_Button.setToolTipText + ("Click to download the " + nselected + + " selected matrices") ; + } + } + else + { + download_Button.setToolTipText ("Download in progress.") ; + } + } + } + + //-------------------------------------------------------------------------- + // show matrix icon + //-------------------------------------------------------------------------- + + private void show_highlighted_icon ( ) + { + // show icon of last entry in the highlighted list + int [ ] highlighted = get_highlighted_ids ( ) ; + int n = highlighted.length ; + if (n > 0) + { + int id = highlighted [n-1] ; + String Group = (String) Stats [id-1][1] ; + String Name = (String) Stats [id-1][2] ; + update_icon (Group + "/" + Name) ; + } + } + + //-------------------------------------------------------------------------- + // matrix table popup listener + //-------------------------------------------------------------------------- + + private class matrix_Table_PopupListener extends MouseAdapter + { + JPopupMenu pop ; + + matrix_Table_PopupListener (JPopupMenu popupMenu) + { + pop = popupMenu ; + } + + public void mousePressed (MouseEvent e) + { + maybeShowPopup (e) ; + } + + public void mouseReleased (MouseEvent e) + { + maybeShowPopup (e) ; + } + + private void maybeShowPopup (MouseEvent e) + { + if (e.isPopupTrigger ( )) + { + pop.show (e.getComponent ( ), e.getX ( ), e.getY ( )) ; + } + } + } + + //-------------------------------------------------------------------------- + // matrix table row listener + //-------------------------------------------------------------------------- + + private class matrix_Table_RowListener implements ListSelectionListener + { + public void valueChanged (ListSelectionEvent event) + { + if (event.getValueIsAdjusting ( )) + { + return ; + } + show_highlighted_icon ( ) ; + } + } + + //-------------------------------------------------------------------------- + // FindKinds: determine the set of all Problem kinds + //-------------------------------------------------------------------------- + + private String [ ] FindKinds ( ) + { + Set KindSet = new TreeSet ( ) ; + KindSet.add (all_kinds) ; + for (int id = 1 ; id <= Stats.length ; id++) + { + KindSet.add (SimplifyKind ((String) Stats [id-1][12])) ; + } + return ((String [ ]) KindSet.toArray (new String [0])) ; + } + + //-------------------------------------------------------------------------- + // FindGroups: determine the set of all groups + //-------------------------------------------------------------------------- + + private String [ ] FindGroups ( ) + { + Set GroupSet = new TreeSet ( ) ; + GroupSet.add (all_groups) ; + for (int id = 1 ; id <= Stats.length ; id++) + { + GroupSet.add ((String) Stats [id-1][1]) ; + } + return ((String [ ]) GroupSet.toArray (new String [0])) ; + } + + //-------------------------------------------------------------------------- + // SimplifyKind: remove extranneous terms from a string + //-------------------------------------------------------------------------- + + private String SimplifyKind (String kind) + { + // remove terms from a matrix-kind string + String result = null ; + String [ ] token = kind.split (" ") ; + for (int i = 0 ; i < token.length ; i++) + { + if (! (token [i].equals ("subsequent") + || token [i].equals ("sequence") + || token [i].equals ("problem") + || token [i].equals ("duplicate"))) + { + if (result == null) + { + result = token [i] ; + } + else + { + result = result + " " + token [i] ; + } + } + } + return (result) ; + } + + //-------------------------------------------------------------------------- + // CheckDir: return a directory, creating it if it doesn't exist + //-------------------------------------------------------------------------- + + private File CheckDir (String directory_name) + { + File dir = new File (fix_name (directory_name)) ; + if (!dir.isDirectory ( )) + { + dir.mkdirs ( ) ; + } + return (dir) ; + } + + //-------------------------------------------------------------------------- + // CheckExistence: determine which files exist in the local file system + //-------------------------------------------------------------------------- + + private void CheckExistence ( ) + { + // check the existence all matrices in all 3 formats + fire_updates (false) ; + for (int id = 1 ; id <= Stats.length ; id++) + { + CheckExistence (id) ; + } + fire_updates (true) ; + } + + private boolean [ ] CheckExistence (int id) + { + // check the existence of a single file (in all 3 formats) + boolean [ ] exists = new boolean [4] ; + boolean [ ] etable = new boolean [3] ; + + String Group = (String) Stats [id-1][1] ; + String Name = (String) Stats [id-1][2] ; + + for (int j = 0 ; j < 3 ; j++) + { + etable [j] = (((String) get_table_value (id, j+1)).charAt (0) == 'x') ; + } + + for (int j = 0 ; j < 4 ; j++) + { + exists [j] = false ; + } + + // check for mat/HB/west0067.mat + File G = new File (mat, Group) ; + if (G.isDirectory ( ) && (new File (G, Name + ".mat")).exists ( )) + { + exists [0] = true ; + } + + // check for MM/HB/west0067.tar.gz + G = new File (MM, Group) ; + if (G.isDirectory ( ) && (new File (G, Name + ".tar.gz")).exists ( )) + { + exists [1] = true ; + } + + // check for MM/HB/west0067.tar.gz + G = new File (RB, Group) ; + if (G.isDirectory ( ) && (new File (G, Name + ".tar.gz")).exists ( )) + { + exists [2] = true ; + } + + // check for matrices/HB/west0067.png + G = new File (iconDir, Group) ; + if (G.isDirectory ( ) && (new File (G, Name + ".png")).exists ( )) + { + exists [3] = true ; + } + + // update the matrix table (mat, MM, and RB columns) + for (int j = 0 ; j < 3 ; j++) + { + if (etable [j] != exists [j]) + { + // only update the table if the existence status has changed + set_table_value (exists [j] ? "x" : "-", id, j+1) ; + } + } + return (exists) ; + } + + //------------------------------------------------------------------------- + // get long from JTextField + //------------------------------------------------------------------------- + + private long getLong (JTextField tfield, long Default) + { + String s = tfield.getText ( ) ; + long result = Default ; + if (s.length ( ) > 0) + { + try + { + result = Long.parseLong (s) ; + } + catch (Exception e) + { + } + } + return (result) ; + } + + //------------------------------------------------------------------------- + // get double from JTextField + //------------------------------------------------------------------------- + + private double getDouble (JTextField tfield, double Default) + { + String s = tfield.getText ( ) ; + double result = Default ; + if (s.length ( ) > 0) + { + try + { + result = Double.parseDouble (s) ; + } + catch (Exception e) + { + } + } + return (result) ; + } + + //------------------------------------------------------------------------- + // change to a wait cursor + //------------------------------------------------------------------------- + + private void please_wait ( ) + { + this.setCursor (Cursor.getPredefinedCursor (Cursor.WAIT_CURSOR)) ; + } + + //------------------------------------------------------------------------- + // change to a normal cursor + //------------------------------------------------------------------------- + + private void the_long_wait_is_over ( ) + { + this.setCursor (Cursor.getDefaultCursor ( )) ; + } + + //------------------------------------------------------------------------- + // make or clear a selection + //------------------------------------------------------------------------- + + private void make_selection (boolean action) + { + // set selections according to controls + please_wait ( ) ; + fire_updates (false) ; + + long minrow = getLong (minrow_Field, 0) ; + long maxrow = getLong (maxrow_Field, INF) ; + + long mincol = getLong (mincol_Field, 0) ; + long maxcol = getLong (maxcol_Field, INF) ; + + long minnz = getLong (minnz_Field, 0) ; + long maxnz = getLong (maxnz_Field, INF) ; + + double minpsym = getDouble (minpsym_Field, 0) ; + double maxpsym = getDouble (maxpsym_Field, 1.0) ; + + double minnsym = getDouble (minnsym_Field, 0) ; + double maxnsym = getDouble (maxnsym_Field, 1.0) ; + + boolean shape_square = shape_square_Button.isSelected ( ) ; + boolean shape_rect = shape_rect_Button.isSelected ( ) ; + boolean shape_either = shape_either_Button.isSelected ( ) ; + + boolean posdef_yes = posdef_yes_Button.isSelected ( ) ; + boolean posdef_no = posdef_no_Button.isSelected ( ) ; + boolean posdef_either = posdef_either_Button.isSelected ( ) ; + + boolean nd_yes = nd_yes_Button.isSelected ( ) ; + boolean nd_no = nd_no_Button.isSelected ( ) ; + boolean nd_either = nd_either_Button.isSelected ( ) ; + + boolean real_yes = real_yes_Button.isSelected ( ) ; + boolean real_no = real_no_Button.isSelected ( ) ; + boolean real_either = real_either_Button.isSelected ( ) ; + + // create HashSet for the selected groups + Set Gset = null ; + Object [ ] Gsel = Group_List.getSelectedValues ( ) ; + int ngroups = Gsel.length ; + if (ngroups > 0) + { + for (int i = 0 ; i < ngroups ; i++) + { + if (((String) Gsel [i]).equals (all_groups)) ngroups = 0 ; + } + Gset = new HashSet ( ) ; + for (int i = 0 ; i < ngroups ; i++) + { + Gset.add ((String) Gsel [i]) ; + } + } + + // create HashSet for the selected kinds + Set Kset = null ; + Object [ ] Ksel = Kind_List.getSelectedValues ( ) ; + int nkinds = Ksel.length ; + if (nkinds > 0) + { + for (int i = 0 ; i < nkinds ; i++) + { + if (((String) Ksel [i]).equals (all_kinds)) nkinds = 0 ; + } + Kset = new HashSet ( ) ; + for (int i = 0 ; i < nkinds ; i++) + { + Kset.add ((String) Ksel [i]) ; + } + } + + for (int id = 1 ; id <= Stats.length ; id++) + { + + // look at the matrix properties to see if it fits the selection + long nrows = (Long) Stats [id-1][3] ; + long ncols = (Long) Stats [id-1][4] ; + long nnz = (Long) Stats [id-1][5] ; + + int isReal = (Integer) Stats [id-1][6] ; + int isBinary = (Integer) Stats [id-1][7] ; + int isND = (Integer) Stats [id-1][8] ; + int posdef = (Integer) Stats [id-1][9] ; + + double psym = (Double) Stats [id-1][10] ; + double nsym = (Double) Stats [id-1][11] ; + + boolean choose_group = true ; + if (ngroups > 0) + { + String group = (String) Stats [id-1][1] ; + choose_group = Gset.contains (group) ; + } + + boolean choose_kind = true ; + if (nkinds > 0) + { + String kind = SimplifyKind ((String) Stats [id-1][12]) ; + choose_kind = Kset.contains (kind) ; + } + + if ((minrow <= nrows && nrows <= maxrow) && + (mincol <= ncols && ncols <= maxcol) && + (minnz <= nnz && nnz <= maxnz) && + (minpsym <= psym && psym <= maxpsym) && + (minnsym <= nsym && nsym <= maxnsym) && + (posdef_either || + (posdef_yes && posdef == 1) || + (posdef_no && posdef == 0)) && + (nd_either || + (nd_yes && isND == 1) || + (nd_no && isND == 0)) && + (real_either || + (real_yes && isReal == 1) || + (real_no && isReal == 0)) && + (shape_either || + (shape_square && nrows == ncols) || + (shape_rect && nrows != ncols)) && + choose_group && choose_kind) + { + // change the selection box for this matrix id + set_table_value (action, id, 0) ; + } + } + fire_updates (true) ; + progress1_Bar.setValue (0) ; + progress2_Bar.setValue (0) ; + the_long_wait_is_over ( ) ; + } + + //------------------------------------------------------------------------- + // reset button + //------------------------------------------------------------------------- + + private void reset_Button_action (ActionEvent e) + { + // reset the selection criteria to the defaults + minrow_Field.setText ("") ; + maxrow_Field.setText ("") ; + + mincol_Field.setText ("") ; + maxcol_Field.setText ("") ; + + minnz_Field.setText ("") ; + maxnz_Field.setText ("") ; + + minpsym_Field.setText ("0.0") ; + maxpsym_Field.setText ("1.0") ; + + minnsym_Field.setText ("0.0") ; + maxnsym_Field.setText ("1.0") ; + + shape_either_Button.setSelected (true) ; + posdef_either_Button.setSelected (true) ; + nd_either_Button.setSelected (true) ; + real_either_Button.setSelected (true) ; + + Group_List.clearSelection ( ) ; + Kind_List.clearSelection ( ) ; + + progress1_Bar.setValue (0) ; + progress2_Bar.setValue (0) ; + } + + //------------------------------------------------------------------------- + // clear button + //------------------------------------------------------------------------- + + private void clear_Button_action (ActionEvent e) + { + // set selections according to controls + please_wait ( ) ; + fire_updates (false) ; + + for (int id = 1 ; id <= Stats.length ; id++) + { + // clear the selection box for this matrix id + set_table_value (false, id, 0) ; + } + fire_updates (true) ; + progress1_Bar.setValue (0) ; + progress2_Bar.setValue (0) ; + the_long_wait_is_over ( ) ; + } + + //------------------------------------------------------------------------- + // select popup menu item + //------------------------------------------------------------------------- + + private void popup_action (ActionEvent e, boolean action) + { + // select or deselect the highlight matrices + please_wait ( ) ; + int [ ] highlighted = get_highlighted_ids ( ) ; + int n = highlighted.length ; + for (int k = 0 ; k < n ; k++) + { + set_table_value (action, highlighted [k], 0) ; + } + the_long_wait_is_over ( ) ; + } + + //------------------------------------------------------------------------- + // export popup menu item + //------------------------------------------------------------------------- + + private void export_list_action (ActionEvent e, boolean csv) + { + // export the list in the order of the current view + if (chooser.showSaveDialog (UFgui.this) == JFileChooser.APPROVE_OPTION) + { + please_wait ( ) ; + print_out = null ; + try + { + print_out = new PrintWriter (chooser.getSelectedFile ( )) ; + int [ ] ids = get_download_ids ( ) ; + int n = ids.length ; + + // print the header + if (csv) + { + print_out.println ("mat, MM, RB, id, Group, Name, rows, " + + "cols, nonzeros, real, binary, 2D/3D, posdef, psym, " + + "nsym, kind") ; + } + else + { + print_out.println ("%% Matrices selected from UFgui:") ; + print_out.println ("% Example usage:") ; + print_out.println ("% for k = 1:length(ids)") ; + print_out.println ("% Problem = UFget (ids (k))") ; + print_out.println ("% end") ; + print_out.println ("ids = [") ; + } + + for (int k = 0 ; k < n ; k++) + { + // get the matrix id and stats + int id = ids [k] ; + boolean [ ] exists = CheckExistence (id) ; + String Group = (String) Stats [id-1][1] ; + String Name = (String) Stats [id-1][2] ; + long nrows = (Long) Stats [id-1][3] ; + long ncols = (Long) Stats [id-1][4] ; + long nnz = (Long) Stats [id-1][5] ; + int isReal = (Integer) Stats [id-1][6] ; + int isBinary = (Integer) Stats [id-1][7] ; + int isND = (Integer) Stats [id-1][8] ; + int posdef = (Integer) Stats [id-1][9] ; + double psym = (Double) Stats [id-1][10] ; + double nsym = (Double) Stats [id-1][11] ; + String kind = (String) Stats [id-1][12] ; + + if (csv) + { + // print the matrix stats in a single CSV line of text + print_out.println ( + exists [0] + ", " + exists [1] + ", " + + exists [2] + ", " + id + ", " + Group + ", " + + Name + ", " + nrows + ", " + ncols + ", " + + nnz + ", " + isReal + ", " + isBinary + ", " + + isND + ", " + posdef + ", " + psym + ", " + + nsym + ", " + kind) ; + } + else + { + // print the matrix id, with a comment for the name + print_out.println (id + " % " + Group + "/" + Name) ; + } + } + if (!csv) + { + print_out.println ("] ;") ; + } + } + catch (Exception err) + { + // display warning dialog + JOptionPane.showMessageDialog (this, "Export failed.", + "Warning", JOptionPane.WARNING_MESSAGE) ; + } + finally + { + close_printer_stream (print_out) ; + } + the_long_wait_is_over ( ) ; + } + } + + //------------------------------------------------------------------------- + // help button + //------------------------------------------------------------------------- + + private void help_Button_action (ActionEvent e) + { + // create the Help window + please_wait ( ) ; + JFrame help_Frame = new JFrame ("Help: UF Sparse Matrix Collection") ; + + // open the HTML help file and put it in an editor pane + JEditorPane editorPane = new JEditorPane ( ) ; + editorPane.setEditable (false) ; + URL helpURL = UFgui.class.getResource ("UFhelp.html") ; + if (helpURL != null) + { + try + { + editorPane.setPage (helpURL) ; + } + catch (IOException error) + { + // display warning dialog + JOptionPane.showMessageDialog (this, + "Sorry, Help document UFhelp.html not found.", + "Warning", JOptionPane.WARNING_MESSAGE) ; + } + } + + // Put the editor pane in a scroll pane. + JScrollPane editorScrollPane = new JScrollPane (editorPane) ; + + // Add the scroll pane to the Help window + help_Frame.getContentPane ( ).add (editorScrollPane) ; + help_Frame.setSize (800,600) ; + help_Frame.setVisible (true) ; + + the_long_wait_is_over ( ) ; + } + + //------------------------------------------------------------------------- + // get the icon filename + //------------------------------------------------------------------------- + + private String icon_file (String fullname) + { + return ("matrices/" + fullname + ".png") ; + } + + //------------------------------------------------------------------------- + // update the icon + //------------------------------------------------------------------------- + + private void update_icon (String fullname) + { + // fullname is of the form Group/Name (HB/west0479, for example) + icon_Label.setText (fullname) ; + ImageIcon icon = new ImageIcon (fix_name (icon_file (fullname))) ; + if (icon.getIconWidth ( ) < 0) + { + // icon image failed to load; get the image from the web + icon = new ImageIcon (get_url (UFsite +"/"+ icon_file (fullname))) ; + } + icon_Label.setIcon (icon) ; + } + + //-------------------------------------------------------------------------- + // cancel button + //-------------------------------------------------------------------------- + + private void cancel_Button_action (ActionEvent e) + { + if (downloading && !cancel) + { + cancel = true ; + cancel_Button.setEnabled (false) ; + cancel_Button.setToolTipText ("canceling...") ; + } + } + + //------------------------------------------------------------------------- + // get all icons + //------------------------------------------------------------------------- + + private void get_all_icons ( ) + { + // get all icons + start_download_thread (0) ; + } + + //------------------------------------------------------------------------- + // update button + //------------------------------------------------------------------------- + +// private void update_Button_action (ActionEvent e) +// { +// // get the latest UFstats file +// start_download_thread (1) ; +// } + + //------------------------------------------------------------------------- + // download button + //------------------------------------------------------------------------- + + private void download_Button_action (ActionEvent e) + { + // get the selected matrices + start_download_thread (2) ; + } + + //------------------------------------------------------------------------- + // enable/disable update button + //------------------------------------------------------------------------- + +/* + private void update_Button_status (boolean enable) + { + if (new_matrices) + { + update_Button.setEnabled (false) ; + update_Button.setToolTipText + ("New matrices available (restart required).") ; + } + else if (enable) + { + update_Button.setEnabled (true) ; + update_Button.setToolTipText ("Click to update matrix table.") ; + } + else + { + update_Button.setEnabled (false) ; + update_Button.setToolTipText ("Update in progress.") ; + } + } +*/ + + //------------------------------------------------------------------------- + // start the downloader thread + //------------------------------------------------------------------------- + + private void start_download_thread (int what) + { + if (!downloading) + { + // only allow one active download at a time + downloading = true ; + cancel = false ; + + if (gui_ready) + { + cancel_Button.setEnabled (true) ; + cancel_Button.setToolTipText + ("Click to cancel the current download.") ; + // update_Button_status (false) ; + } + + if (what == 0) + { + // get all the icons + // get_UFstats = false ; + get_icons = true ; + download_ids = null ; + } +// else if (what == 1) +// { +// // download the UFstats file and then get all the new icons +// get_UFstats = true ; +// get_icons = true ; +// download_ids = null ; +// } + else + { + // download one or more matrices + // get_UFstats = false ; + get_icons = false ; + download_ids = get_download_ids ( ) ; + } + set_selected_label (false) ; + // start the downloader thread + UFdownload tt = new UFdownload ( ) ; + } + } + + //-------------------------------------------------------------------------- + // downloader thread + //-------------------------------------------------------------------------- + + private class UFdownload implements Runnable + { + + // constructor starts the downloader thread + public UFdownload ( ) + { + Thread thread = new Thread (this) ; + thread.start ( ) ; + } + + // thread.start calls the run method + public void run ( ) + { + +// if (get_UFstats) +// { +// // get the UFstats file +// Object [ ][ ] S2 = download_matrix_stats ( ) ; +// if (S2 != null && S2.length > Stats.length) +// { +// // new matrices available +// new_matrices = true ; +// } +// } + + if (get_icons) + { + // get all missing icons + progress1_Bar.setValue (1) ; + progress1_Bar.setMaximum (Stats.length) ; + icon_Label.setBorder (BorderFactory.createTitledBorder + ("checking for new matrix icons")) ; + for (int id = 1 ; !cancel && id <= Stats.length ; id++) + { + boolean [ ] exists = CheckExistence (id) ; + if (!exists [3]) + { + icon_Label.setBorder (BorderFactory.createTitledBorder + ("downloading new matrix icons")) ; + String Group = (String) Stats [id-1][1] ; + String Name = (String) Stats [id-1][2] ; + String fullname = Group + "/" + Name ; + CheckDir ("matrices/" + Group) ; + download_file (icon_file (fullname)) ; + update_icon (fullname) ; + } + progress1_Bar.setValue (id+2) ; + } + progress1_Bar.setValue (Stats.length) ; + icon_Label.setBorder (BorderFactory.createTitledBorder + ("matrix icon")) ; + } + + if (download_ids != null && download_ids.length > 0) + { + // download all selected matrices in the requested formats + + // determine which formats to download + int barmax = download_ids.length + 2 ; + + boolean format_mat = format_mat_Button.isSelected ( ) ; + boolean format_mm = format_mm_Button.isSelected ( ) ; + boolean format_rb = format_rb_Button.isSelected ( ) ; + + // start the overall progress bar + progress1_Bar.setValue (1) ; + progress1_Bar.setMaximum (barmax) ; + + // download all the files + for (int k = 0 ; !cancel && k < download_ids.length ; k++) + { + int id = download_ids [k] ; + + // get matrxx + String Group = (String) Stats [id-1][1] ; + String Name = (String) Stats [id-1][2] ; + String fullname = Group + "/" + Name ; + + // recheck to see if the matrix exists in the 4 formats + boolean [ ] exists = CheckExistence (id) ; + + if (!exists [3]) + { + // always download the matrix icon if it doesn't exist + CheckDir ("matrices/" + Group) ; + download_file (icon_file (fullname)) ; + update_icon (fullname) ; + } + + if (!exists [0] && format_mat) + { + // download the matrix in MATLAB format + update_icon (fullname) ; + CheckDir ("mat/" + Group) ; + download_file ("mat/" + fullname + ".mat") ; + } + + if (!exists [1] && format_mm) + { + // download the matrix in Matrix Market format + update_icon (fullname) ; + CheckDir ("MM/" + Group) ; + download_file ("MM/" + fullname + ".tar.gz") ; + } + + if (!exists [2] && format_rb) + { + // download the matrix in Rutherford/Boeing format + update_icon (fullname) ; + CheckDir ("RB/" + Group) ; + download_file ("RB/" + fullname + ".tar.gz") ; + } + + progress1_Bar.setValue (k+2) ; + } + + // update the mat/MM/RB check boxes + for (int k = 0 ; k < download_ids.length ; k++) + { + int id = download_ids [k] ; + CheckExistence (id) ; + } + + // finish the overall progress bar + progress1_Bar.setValue (barmax) ; + } + + // update_Button_status (true) ; + cancel_Button.setEnabled (false) ; + cancel_Button.setToolTipText ("No downloads in progress.") ; + + set_selected_label (true) ; + cancel = false ; + downloading = false ; + } + } + + //-------------------------------------------------------------------------- + // get a URL + //-------------------------------------------------------------------------- + + private URL get_url (String urlstring) + { + try + { + return (new URL (urlstring)) ; + } + catch (MalformedURLException e) + { + // display warning dialog + JOptionPane.showMessageDialog (this, "Invalid URL: " + + urlstring, "Warning", JOptionPane.WARNING_MESSAGE) ; + return (null) ; + } + } + + //-------------------------------------------------------------------------- + // download a file + //-------------------------------------------------------------------------- + + private void download_file (String filename) + { + boolean ok = true ; + if (cancel) return ; + String urlstring = UFsite + "/" + filename ; + if (debug) System.out.println ("downloading: " + urlstring) ; + + // create the URL + URL url = get_url (urlstring) ; + if (url == null) return ; + + // download the file + url_in = null ; + ftemp_out = null ; + ftemp_name = filename + "_IN_PROGRESS" ; + int barmax = 1 ; + + try + { + // determine the file size (fails for files > 2GB) + int len = url.openConnection ( ).getContentLength ( ) ; + + // start the progress bar + if (gui_ready) + { + if (len < 0) + { + progress2_Bar.setIndeterminate (true) ; + progress_size_Label.setText ("") ; + } + else + { + progress2_Bar.setValue (0) ; + // display the filesize to the right of the progress bar + if (len < M) + { + barmax = 1 + len / K ; + progress_size_Label.setText (((len+K/2) / K) + " KB") ; + } + else + { + barmax = 1 + len / M ; + progress_size_Label.setText (((len+M/2) / M) + " MB") ; + } + } + progress2_Bar.setMaximum (barmax) ; + } + + // open the source and destination files + url_in = new BufferedInputStream (url.openStream ( )) ; + ftemp_out = new BufferedOutputStream (new FileOutputStream + (fix_name (ftemp_name)), BUFSIZE) ; + + // transfer the data + byte buffer [ ] = new byte [BUFSIZE] ; + long bytes_read = 0 ; + int count = 0 ; + while (!cancel && (count = url_in.read (buffer, 0, BUFSIZE)) >= 0) + { + if (ftemp_out != null) ftemp_out.write (buffer, 0, count) ; + bytes_read += count ; + if (gui_ready && len > 0) + { + if (len < M) + { + progress2_Bar.setValue ((int) (bytes_read / K)) ; + } + else + { + progress2_Bar.setValue ((int) (bytes_read / M)) ; + } + } + } + } + catch (Exception e) + { + // display warning dialog + JOptionPane.showMessageDialog (this, "Download failed: " + + urlstring, "Warning", JOptionPane.WARNING_MESSAGE) ; + ok = false ; + } + + if (gui_ready) + { + progress2_Bar.setIndeterminate (false) ; + progress2_Bar.setValue (barmax) ; + progress_size_Label.setText ("") ; + } + + // wrap-up + if (ok && !cancel) + { + // success: rename the temp file to the permanent filename + cleanup (false) ; + File fsrc = new File (fix_name (ftemp_name)) ; + File fdst = new File (fix_name (filename)) ; + fsrc.renameTo (fdst) ; + } + else + { + // cancelled, or something failed: delete the files if they exist + cleanup (true) ; + } + } + + //-------------------------------------------------------------------------- + // download the latest matrix stats + //-------------------------------------------------------------------------- + + private Object [ ][ ] download_matrix_stats ( ) + { + download_file (UFindex) ; // download mat/UF_Index.mat for UFget.m + download_file (UFstats) ; // download matrices/UFstats.csv + return (load_UFstats ( )) ; // load the UFstats.csv file + } + + //-------------------------------------------------------------------------- + // prepend the UF archive directory and replace '/' with the file separator + //-------------------------------------------------------------------------- + + private static String fix_name (String s) + { + // file separator is '/' on Unix/Solaris/Linux/Mac, and '\' on Windows + String r = UFarchive ; + if (s != null) + { + r = r + s ; + } + return (r.replace ('/', File.separatorChar)) ; + } + + //-------------------------------------------------------------------------- + // close an output stream + //-------------------------------------------------------------------------- + + private static void close_output (OutputStream out) + { + try + { + if (out != null) out.close ( ) ; + } + catch (IOException e) + { + } + } + + //-------------------------------------------------------------------------- + // close an input stream + //-------------------------------------------------------------------------- + + private static void close_reader (Reader in) + { + try + { + if (in != null) in.close ( ) ; + } + catch (IOException e) + { + } + } + + //-------------------------------------------------------------------------- + // close a printer stream + //-------------------------------------------------------------------------- + + private static void close_printer_stream (PrintWriter out) + { + if (out != null) out.close ( ) ; + } + + //-------------------------------------------------------------------------- + // delete a file + //-------------------------------------------------------------------------- + + private static void delete_file (String filename) + { + if (filename != null) + { + File ff = new File (fix_name (filename)) ; + if (ff.exists ( )) ff.delete ( ) ; + } + } + + //-------------------------------------------------------------------------- + // cleanup + //-------------------------------------------------------------------------- + + private static void cleanup (boolean delete) + { + // close input streams, if any + try + { + if (url_in != null) url_in.close ( ) ; + } + catch (IOException e) + { + } + url_in = null ; + + // close temporary file + close_output (ftemp_out) ; + ftemp_out = null ; + + if (delete) + { + // delete temporary file + delete_file (ftemp_name) ; + ftemp_name = null ; + } + + // close the printer stream, if any + close_printer_stream (print_out) ; + + // close the reader stream, if any + close_reader (in_reader) ; + } + + //-------------------------------------------------------------------------- + // main method + //-------------------------------------------------------------------------- + + public static void main (String args [ ]) + { + // register a shutdown hook + Runtime.getRuntime ( ).addShutdownHook + ( + new Thread ( ) + { + public void run ( ) + { + // delete any temporary files when the UFgui shuts down, + // and close any files + cleanup (true) ; + } + } + ) ; + + // start the GUI in its own thread + EventQueue.invokeLater + ( + new Runnable ( ) + { + public void run ( ) + { + new UFgui ( ).setVisible (true) ; + } + } + ) ; + } +} diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFhelp.html b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFhelp.html new file mode 100644 index 0000000..935a905 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFhelp.html @@ -0,0 +1,547 @@ + + + + + +

The University of Florida Sparse Matrix Collection

+ +Tim Davis, University of Florida, +http://www.cise.ufl.edu/~davis + +

1. Overview

+ +UFgui is a Java GUI interface to the University of Florida Sparse Matrix +Collection at http://www.cise.ufl.edu/research/sparse/matrices. It provides an +easy way to select matrices from the collection based on their matrix +properties. As of October 2010, there were 2328 matrices ranging in size +from 1-by-2 (with a single nonzero entry) to a square matrix with nearly 28 +million rows and 760 million entries. The total size of the collection in all +three formats exceeds 47 GB, and is constantly growing in size. + +

2. Quick Start

+ +First, download the UFget archive (tar.gz or zip file), and uncompress it. +Open the UFget folder. + +

+If your web browswer requires an HTTP proxy, or if you wish to change +the download location, first see the Customization section below, +to configure UFgui before you run it. + +

+To run UFgui, double-click its icon or type the following command in your +command window / terminal: + +

+        java -jar UFgui.jar
+
+ +If the above command fails, then you need to install Java. +See +http://www.java.com/en/download/manual.jsp for details. + +

+You can skip reading this document by simply navigating the GUI itself. Most +of the buttons, check boxes, lists, and table columns have a short "tool tip" +which is visible if you hover your mouse over the item. + +

When the UFgui starts, it checks for any missing matrix icons and +downloads a new table if needed. This might take a few minutes, so +just sit back and enjoy the slideshow. It will only happen occassionaly. + +

3. A Sparse Matrix Problem

+ +The UF Sparse Matrix Collection is a simplified name. It is actually a +collection +of sparse matrix problems, not just sparse matrices. Each problem +includes one primary sparse matrix and meta-data about that matrix. Some +problems include additional matrices and vectors (sparse or dense) such as +right-hand-sides to a linear system Ax=b, or cost constraints for a +linear programming problem. As a short-hand, a "problem" in the collection is +often called simply a "matrix", refering to the primary sparse matrix in the +problem (A, below). + +

+The following data is always present in any sparse matrix problem +(not all fields are shown in the table in the UFgui program, however): + +

    +
  • name: the full name of the problem, in the form + Group/Name, where Group indicates the source of the + problem (a person, organization, or other collection), and Name + is the name of the problem within that Group. As of September + 2009, there were 153 matrix Groups. + +
  • title: a short descriptive title. + +
  • A: the primary sparse matrix itself. + It is the properties of this matrix that determine + the selection criteria. + +
  • id: a unique serial number ranging from 1 to the number of + matrices in the collection. As new matrices are added to the + collection they are given higher id's, so new matrices are always + at the end of the table when sorted by id. + +
  • date: the date the matrix was created, or the date it was + added to the UF Sparse Matrix Collection if the creation date is not + known. + +
  • author: the person or persons who created the matrix. + +
  • ed: the person or persons to acquired the matrix from the + author and placed it in a widely accessible collection (this + one or others such as the Rutherford/Boeing collection or + the Matrix Market collection). + +
  • kind: the domain of the problem, such as "circuit simulation", + "chemical process simulation", "finite-element problem", and so on. + As of September 2009, there were 36 different matrix kinds. + +
+ +The following data is present in some problems but not all: + +
    +
  • Zeros: a binary matrix holding the pattern of + entries explicitly provided by the matrix author which are equal to + zero. These may represent entries that may become nonzero later on in + a simulation, but they are equal to zero in this instance of the + matrix. Since they were provided by the matrix author(s), they are + preserved in this collection. In the MATLAB format, this matrix is + held as a different sparse matrix, since MATLAB removes explicit zeros + from its sparse matrices. In the Matrix Market and Rutherford/Boeing + collection, these entries are included in the primary sparse matrix + itself, as explicitly zero entries. + +
  • b: the right-hand-side to a linear system or least-squares + problem. This can be a vector or matrix, real or complex, and + sparse or dense. + +
  • x: the solution to a linear system or least-squares problem. + +
  • notes: text, with a discussion about the problem, in no + particular format. + +
  • aux: Any number of matrices, vectors, or text. For example, an + optimization problem may include a cost vector c, and vectors + that specify upper/lower bounds on the solution. Details of how to + interpret this auxiliary data are normally given in the notes + field. In the MATLAB format this is a struct containing each of the + items. In the Matrix Market and Rutherford/Boeing formats, this data + resides alongsize the primary matrix in a single compressed folder. + +
+ +

4. Matrix Formats

+ +Each matrix in the collection appears in three different formats. The data +within each format is identical, down to the very last bit (if you find a +discrepency between the same problem in different formats, please let me know). + +
    +
  • MATLAB™ *.mat file. This can be loaded into MATLAB directly, + or it can be accessed via the UFget.m MATLAB interface to the collection. + Type help UFget in MATLAB for more details. The name of the MATLAB + file is of the form mat/Group/Name.mat (such as mat/HB/west0067.mat for the + west0067 matrix from the HB, or Harwell/Boeing, group). + +
  • Matrix Market *.mtx file and associated files. Short meta-data + (name, title, id, date, author, ed, kind, and notes) is given as structured + comments in the primary *.mtx file. This file and any associated files (b, + x, and any aux matrices) are in a single folder which is then archived into + a *.tar.gz file. Windows users will need a 3rd-party program for handling + *.tar.gz files. For example, the Matrix Market format for the HB/west0067 + matrix is held in the MM/HB/west0067.tar.gz file. See + http://math.nist.gov/MatrixMarket/index.html for more information about the + Matrix Market format. + +
  • Rutherford/Boeing *.rb file and associated files. Short meta-data + (name, title, id, date, author, ed, kind, and notes) is given as structured + comments in a separate text file. The matrix file, the informational text + file, and any associated files (b, x, and any aux matrices) are in a single + folder which is then archived into a *.tar.gz file. For example, the + Rutherford/Boeing format for the HB/west0067 file is held in the + RB/HB/west0067.tar.gz file. See http://www.cse.scitech.ac.uk/nag/hb/ for + more information about the Rutherford/Boeing format. + +
+ +

5. Selecting Matrices

+ +In the UFgui you are presented with four primary panels. + +

Selection Criteria panel: + +This is used for rule-based selections of matrix subsets. A matrix must +satisfy all properties in this panel to be selected. With the default settings +(available when the UFgui starts or after clicking Reset criteria) all +matrices fit the criteria. However, no matrix is selected until you press the +Select button or select them individually in the table by clicking the +checkbox in the select column. + +

The selection criteria are based on the matrices properties described in +the matrix table (described below). To select matrices from one or more groups +and/or "kinds," click on the choices in the "group" and/or "kind" lists. +Shift-click the list to select a range of groups or kinds, and control-click +the list to add a single item to your highlighted choices. To clear your +choices, click the Reset criteria button, described below. + +

When you select/deselect matrices, the boxes to the left of each matrix in +the Table of Matrices get checked/unchecked. You still see all the matrices +in the list, because you can then modify your selection by checking/unchecking +matrices one at a time in the Table itself. + +

+At the bottom of the Selection Criteria panel is a row of buttons: + +

    +
  • Select: Click this to add matrices to your selection + that fit the criteria. No matrix is removed from any prior selection. + For example, to select all square matrices with fewer than 1000 rows, + plus all complex matrices, do the following. First enter 1000 in the + top-right text field, click the square radio button, and then + click Select. Then click Reset criteria. Next, click + complex and then Select. + +
  • Deselect: Click this to remove matrices from your selection + that fit the criteria. In general, if you want matrices that meet some + criteria (a) but not (b), then set the controls for (a) and click + Select. Next, click Reset criteria, set the criteria + (b), and click Deselect. For example, to select all square + matrices with fewer than 1000 rows that are not complex, you could just + do this with a single click of Select (click square, + real, and enter 1000 in the top-right text field, then click + Select). Alternatively, you could click square and enter + 1000 as the upper bound on the number of rows and click Select + then Reset criteria, select complex, and click + Deselect. + +
  • Reset criteria: This has no effect on your selection. It + simply resets the criteria to the default (all matrices). Thus, to + select all matrices, click Reset criteria and then + Select. To deselect all matrices, click Reset criteria + and then Deselect. + +
  • Clear selections: This has no effect on your selection + criteria. It simply clears all selections, deselecting all matrices by + unchecking the select column in the table. This is useful if + you have a complex selection criteria and don't want to lose it by + clicking Reset criteria, but you wish to clear all your + selections anyway. + +
  • Help: this button brings up the text you're reading. + +
+ +

Matrix icon panel: + +To the right of the Selection Criteria panel is an icon of the most recent +matrix highlighted, downloaded, or in the process of being downloaded. + +

Table of matrices: + +This is a list of all the matrices in the collection. You can click on any +column header to sort the table by that column. Clicking a row (to the right +of the select column) will highlight that row. You can highlight a range of +rows by shift-clicking another row. Control-click will add individual rows. +Next, right-clicking in the table will pull up a pop-up menu allowing you to +select or deselect the highlighted matrices and to export your selection to a +file. You can export a list of your selected matrices to a comma-separarted +file (*.csv) or to a MATLAB (*.m) file. When you highlight a matrix, its icon +is displayed. + +

The table contains the following columns (you can also hover your mouse +over each column header for a short description): + +

    +
  • select: whether or not you have selected the matrix. + You can click on the check boxes in this column to modify your + selection on a matrix-by-matrix basis. This is the only column in + the table that you can edit. + +
  • mat: this box is checked if you have downloaded the matrix + in its MATLAB format. The location of the HB/west0067.mat file + will be UFget/mat/HB/west0067.mat, for example. + +
  • MM: this is checked if you have already downloaded + the matrix in its Matrix Market format. + +
  • RB: this is checked if you have already downloaded + the matrix in its Rutherford/Boeing format. + +
  • id: the matrix id, in the range 1 to the number of + matrices in the collection. When the UFgui starts, + the table is sorted in this order. + +
  • Group: the group the matrix belongs to. + +
  • Name: the (short) name of the matrix. The full name of + a matrix is Group/Name. + +
  • # rows: the number of rows of the matrix. + +
  • # cols: the number of columns of the matrix. + +
  • # nonzeros: the number of nonzeros in the matrix. + +
  • real: this box is checked if the matrix is real. + It is complex otherwise. + Note that real matrices include any matrix that is not + complex. In particular, integer and binary matrices are + considered real in this search criterion. + +
  • binary: this box is checked if the matrix is binary. + It is non-binary otherwise (there are no binary complex matrices, + so any matrix that is binary is also marked as real). + +
  • 2D/3D: this box is checked if the matrix comes + from a discretization of a 2D or 3D geometry. + +
  • posdef: this box is checked if the matrix is + symmetric and positive definite. + +
  • psym: the symmetry of the nonzero pattern of the + matrix A (including the binary Zeros matrix as well). Let + S = pattern(pattern(A)+Zeros) where pattern(A) is a + binary matrix with entries equal to 1 where A(i,j) is + nonzero, and zero elsewhere. The psym metric is zero if the + pattern of S is completely unsymmetric, and 1.0 if the + pattern is exactly symmetric. Let pmatched be the number of + off-diagonal entries S(i,j) for which S(i,j)=S(j,i) + and let pnzoffdiag be the total number off-diagonal entries + in S. Then psym is the ratio + pmatched/pnzoffdiag. + +
  • nsym: the symmetry of the numerical values of the + matrix. This property ignores the Zeros matrix. It is + equal to 0 for a perfectly unsymmetric matrix, and 1.0 for a + symmetric matrix. Let matched be the number of nonzero + off-diagonal entries A(i,j) for which A(i,j)=A(j,i) + and let nzoffdiag be the total number off-diagonal nonzero + entries in A. Then psym is the ratio + matched/nzoffdiag. + +
  • kind: the problem domain. Note that this is typically + related to the problem group, since many matrix authors submit + matrices to the collection that arise from a single problem domain. + Some group have problems from many domains, however. + +
+ +

Download panel: + +This panel controls the downloading of matrices, with +three check boxes, three buttons, and informational items: + +

    + +
  • Download: click this to begin the download of the + selected matrices. Matrices that are already downloaded are skipped + (thus, if one of your matrix files happens to get corrupted, simply + remove the file and restart the UFgui). Matrices are downloaded into + the mat, MM, and RB folders inside the UFget + folder, in the same order as they appear in the table view. For + example, if you click on the # nonzeros column heading prior to + clicking Download, your selected matrices will be downloaded in + order of increasing number of nonzero entries. If you hover your mouse + over the download button, a tool tip will tell you what it will do. + +
  • MATLAB (mat) format: click this to download the selected + matrices in MATLAB *.mat format. + +
  • Matrix Market (MM) format: click this to download the selected + matrices in Matrix Market format. + +
  • Rutherford/Boeing (RB) format: click this to download the + selected matrices in Rutherford/Boeing format. + +
  • Matrices selected: gives a running total of the number of + matrices selected in the table. + +
  • Cancel: click to cancel the current download, deleting the + matrix currently being downloaded. Matrices already fully downloaded + are never deleted by the UFgui program. + +
  • Overall progress: this progress bar advances after each + matrix is downloaded. + +
  • Current file: this progress bar advances as the current + matrix is downloaded. The icon and name of the matrix currently + being downloaded is shown in the icon panel. + +
+ + +

The contents of the mat, matrices, MM, and RB + folders ("directories" for Unix users), and the UFstats.txt file itself, + maybe be deleted at will when the program is not running. They will be + recreated when the program restarts. If you delete the matrices + directory, for example, matrix icons are redownloaded, which makes for a + fun slide show. Sit back and watch. + +

6. Customization

+ +The UFsettings.txt includes six lines of text, each with parameters +that you can modify. If this file is missing, or shorter than 6 lines +long, then defaults are used. + +
    +
  • The first line is the default folder containing the mat, + matrices, MM, and RB directories. It is displayed + on the GUI just above the table of matrices. The line is blank + by default. If left blank, these four folders are to be found in the + current working directory. You can modify this first line to refer to + another folder. For example, if I were to create my own folder called + MyMatrices in my home directory, I would use + /home/davis/MyMatrices/ in Unix/Linux, + /Users/davis/MyMatrices/ in Mac OS X, or C:\Documents and + Settings\davis\My Documents\MyMatrices\ in Windows. The trailing + file-separator is optional. Both the slash (\) and backslash (/) + characters are interpretted as your system's file-separator ('\' for + Windows, '/' for everything else). + +
  • The second line is the root URL of the UF Sparse Matrix Collection, + http://www.cise.ufl.edu/research/sparse. This only needs to change in the + unlikely event that the entire collection moves to a new URL. + +
  • The third line is the number of days after which a new list of matrices (in + matrices/UFstats.csv and mat/UF_Index.mat) should be + downloaded. By default this is set to 30. A value of inf means + that this UFstats.csv file is never downloaded automatically. If + the matrices/UFstats.csv is missing or corrupted when UFgui starts, + it will download fresh copies of both files. Thus, to force a refresh, + simply delete the matrices/UFstats.csv file and then start UFgui. + You may also download the files with the MATLAB command + UFget('refresh') prior to running UFgui. The UFsettings.txt + is also used by the UFget MATLAB interface. + +
  • The fourth line gives the name of your HTTP proxy server, if you connect to + the internet via a proxy. If left blank, no proxy is used. + +
  • The fifth line is the port number for your HTTP proxy. If blank, + the default of 80 is used. + +
  • The sixth and final line controls debug diagnostics. If this line is + "debug" (without the quotes), then diagnostics are printed on the standard + output (System.out). You should also start the UFgui.jar via the + command line, otherwise the diagnostic output is not visible. + +
+ +

7. Limitations and known issues

+ +
    + +
  • When a download is complete, the table order jitters slightly. This is + because the mat, MM, and RB columns are updated. The + table sort order is temporarily modified, even if you have not currently + selected one of those columns to sort. It then returns to the proper order + immediately. This appears to be a limitation of the Java Swing library in + JDK 6. + +
  • When cancelling a download with the Cancel button, or terminating the + program normally (by clicking the [x] icon to close the UFgui window), any + partial file currently being downloaded is safely deleted. These files + have the term _IN_PROGRESS appended to their name. If the UFgui program + terminates abnormally and suddenly in the middle of a download, however, it + will leave behind files of this form. You can safely delete any + *_IN_PROGRESS file when the UFgui program is not running. + +
  • Working through an HTTP proxy can be sluggish, and I have even seen + downloads stall completely. I am currently investigating why this + occurs and how to work around a sluggish proxy. If you are using a + proxy and the download stalls, try clicking Cancel and then + Download. If that fails, terminate UFgui. If you terminate it + abnormally (not by clicking the [x] in the window, but with "kill -9" + in Linux, or by forcing it to quit via your OS), you may need to + delete the *_IN_PROGRESS file. Please let me know if this happens. + +
+ +

8. Copyright and License

+ +Copyright (c) 2009-2010, Timothy A. Davis. All rights reserved. + +

Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +

    +
  • Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +
  • Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution +
  • Neither the name of the University of Florida nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. +
+ +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +

9. Version and Change-Log

+ +
    +
  • Version 1.0.4, October 27, 2010. Update to this help file only. + +
  • Version 1.0.3, October 9, 2009. Removed the Update button which when + clicked would download a fresh copy of matrices/UFstats.csv. UFgui + updates itself automatically every 30 days. If you want to force a + refresh, just delete that file and restart UFgui. Changed the appearence + of the mat, MM, RB columns. (from Iain Duff's comments). + +
  • Version 1.0.2, October 8, 2009. Added HTTP proxy option + (suggested by Iain Duff), and debug diagnostic option. + +
  • Version 1.0.1, October 7, 2009. Added "Clear selections" button + (suggested by Xiangrui Meng). + +
  • UFgui Version 1.0, October 7, 2009, released. + +
  • When a new version of this software is available, simply move the + mat, matrices, MM, and RB folders from the old + UFget folder into the new one, to preserve the matrices you have + already downloaded. Alternatively, you can edit the UFsettings.txt + file to reflect the folder containing your previous mat, + matrices, MM, and RB folders (see the + Customization section, above). + +
+ +

10. For Further Help

+ +Contact the author of this UFgui program, and the maintainer of the UF Sparse +Matrix Collection: Tim Davis ( +http://www.cise.ufl.edu/~davis, email +davis@cise.ufl.edu +or +DrTimothyAldenDavis@gmail.com). +To print this document, +open the file UFhelp.html in your favorite web browser. + +

11. Acknowledgements

+ +I would like to thank Iain Duff and Xiangrui Meng for their feedback, +which has improved this package. Designing a GUI is an art, and getting +usability feedback from others is vital. + +
+ + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFkinds.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFkinds.m new file mode 100644 index 0000000..b6ff1ae --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFkinds.m @@ -0,0 +1,72 @@ +function kinds = UFkinds +%UFKINDS: get 'kind' of each problem in the UF collection. +% +% A problem 'kind' is the domain from which the problem arises. Examples +% include 'circuit simulation', 'optimization', 'least squares', and 'robotics'. +% See http://www.cise.ufl.edu/research/sparse/matrices/kind.html for a +% complete list. +% +% A 'kind' is related to the matrix 'Group'. The latter is determined by +% person, persons, or organization that created the matrix. 'Group' may also +% refer to another matrix collection that has been included in this collection +% (such as 'HB' for the Harwell/Boeing collection). +% +% kinds = UFkinds returns a cell array with one row per matrix. kinds{id} +% is the same as Problem.kind where Problem=UFget(id). If an error occurs, +% an empty cell array is returned. +% +% Example: +% +% kinds = UFkinds ; +% Problem = UFget (42) +% kinds{42} +% +% results in the following output: +% +% Problem = +% title: 'SYMMETRIC STIFFNESS MATRIX - FRAME WITHIN A SUSPENSION BRIDGE' +% A: [485x485 double] +% name: 'HB/bcsstk20' +% id: 42 +% date: '1984' +% author: 'J. Lewis' +% ed: 'I. Duff, R. Grimes, J. Lewis' +% kind: 'structural problem' +% +% ans = +% 'structural problem' +% +% To find a list t of the id's all matrices from material science: +% +% kinds = UFkinds ; +% t = zeros (1, length (kinds)) ; +% for id = 1:length(kinds) +% t (id) = ~isempty (strfind (kinds {id}, 'material')) ; +% end +% t = find (t) ; +% for id = t +% Problem = UFget (id) +% end +% +% See also UFget. + +% Copyright 2009, Tim Davis, University of Florida. + +params = UFget_defaults ; +statfile = sprintf ('%smatrices/UFstats.csv', params.topdir) ; + +try + f = fopen (statfile, 'r') ; + nmat = str2double (fgetl (f)) ; % number of matrices + s = fgetl (f) ; % date the UFstats.csv file was created + kinds = cell (nmat,1) ; + for id = 1:nmat + s = fgetl (f) ; + t = find (s == ',', 1, 'last') ; + r = s ((t+1):end) ; + kinds {id} = r ; + end +catch + kinds = cell (0,0) ; % return empty string on error +end + diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFsettings.txt b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFsettings.txt new file mode 100644 index 0000000..7103fa7 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFsettings.txt @@ -0,0 +1,6 @@ + +http://www.cise.ufl.edu/research/sparse +30 + + +no debug diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFweb.m b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFweb.m new file mode 100644 index 0000000..a4f1f2e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/UFweb.m @@ -0,0 +1,124 @@ +function stats = UFweb (matrix, opts) +%UFWEB opens the URL for a matrix. +% +% UFweb(matrix) opens the URL for a matrix. This parameter can be a string, +% or an integer. If it is a string with no "/" character, the web page for a +% matrix group is displayed. With no arguments, a list of all the matrix +% groups is displayed. +% +% Example: +% +% If Problem = UFget ('HB/arc130'), the first four examples display +% the same thing, the web page for the HB/arc130 matrix: +% +% UFweb (6) +% UFweb ('HB/arc130') +% stats = UFweb (6) +% +% The latter also returns statistics about the matrix or matrix group. +% To display the web page for the HB (Harwell-Boeing) group: +% +% UFweb ('HB') +% +% To display the home page for the UF sparse matrix collection: +% +% UFweb +% UFweb (0) +% UFweb ('') +% +% The latter two are useful if a second optional parameter is specified. +% The second optional argument is a string passed as additional parameters to +% the MATLAB web command. To use the system web browser instead of the MATLAB +% browser, for example, use UFweb ('HB/arc130', '-browser'). +% +% See also web, UFget, UFget_defaults. + +% Copyright 2009, Tim Davis, University of Florida. + +params = UFget_defaults ; +UF_Index = UFget ; + +if (nargin < 1) + matrix = '' ; +end +if (nargin < 2) + opts = '' ; +end + +% get the matrix group, name, and id +[group name id] = UFget_lookup (matrix, UF_Index) ; + +url = params.url ; +len = length (url) ; +if (strcmp (url ((len-3):len), '/mat')) + % remove the trailing '/mat' + url = url (1:(len-4)) ; +end + +% open the web page for the matrix, group, or whole collection +if (id == 0) + if (isempty (group)) + eval (['web ' url '/matrices/index.html ' opts]) + else + eval (['web ' url '/matrices/' group '/index.html ' opts]) + end +else + eval (['web ' url '/matrices/' group '/' name '.html ' opts]) +end + +% return stats +if (nargout > 0) + + if (id == 0) + + if (isempty (group)) + + % return stats about the whole collection + stats.nmatrices = length (UF_Index.nrows) ; + stats.LastRevisionDate = UF_Index.LastRevisionDate ; + stats.DownloadTime = datestr (UF_Index.DownloadTimeStamp) ; + + else + + % return stats about one matrix group + nmat = length (UF_Index.nrows) ; + ngroup = 0 ; + for i = 1:nmat + if (strcmp (group, UF_Index.Group {i})) + ngroup = ngroup + 1 ; + end + end + stats.nmatrices = ngroup ; + stats.LastRevisionDate = UF_Index.LastRevisionDate ; + stats.DownloadTime = datestr (UF_Index.DownloadTimeStamp) ; + + end + else + + % look up the matrix statistics + stats.Group = group ; + stats.Name = name ; + stats.nrows = UF_Index.nrows (id) ; + stats.ncols = UF_Index.ncols (id) ; + stats.nnz = UF_Index.nnz (id) ; + stats.nzero = UF_Index.nzero (id) ; + stats.pattern_symmetry = UF_Index.pattern_symmetry (id) ; + stats.numerical_symmetry = UF_Index.numerical_symmetry (id) ; + stats.isBinary = UF_Index.isBinary (id) ; + stats.isReal = UF_Index.isReal (id) ; + stats.nnzdiag = UF_Index.nnzdiag (id) ; + stats.posdef = UF_Index.posdef (id) ; + stats.amd_lnz = UF_Index.amd_lnz (id) ; + stats.amd_flops = UF_Index.amd_flops (id) ; + stats.amd_vnz = UF_Index.amd_vnz (id) ; + stats.amd_rnz = UF_Index.amd_rnz (id) ; + stats.nblocks = UF_Index.nblocks (id) ; + stats.sprank = UF_Index.sprank (id) ; + stats.RBtype = UF_Index.RBtype (id,:) ; + stats.cholcand = UF_Index.cholcand (id) ; + stats.ncc = UF_Index.ncc (id) ; + stats.isND = UF_Index.isND (id) ; + stats.isGraph = UF_Index.isGraph (id) ; + + end +end diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/mat/UF_Index.mat b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/mat/UF_Index.mat new file mode 100644 index 0000000..1c49c8b Binary files /dev/null and b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/mat/UF_Index.mat differ diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/UFget/matrices/UFstats.csv b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/matrices/UFstats.csv new file mode 100644 index 0000000..fd769d3 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/UFget/matrices/UFstats.csv @@ -0,0 +1,2549 @@ +2547 +06-Jul-2011 14:40:37 +HB,1138_bus,1138,1138,4054,1,0,0,1,1,1,power network problem +HB,494_bus,494,494,1666,1,0,0,1,1,1,power network problem +HB,662_bus,662,662,2474,1,0,0,1,1,1,power network problem +HB,685_bus,685,685,3249,1,0,0,1,1,1,power network problem +HB,abb313,313,176,1557,1,1,0,0,0,0,least squares problem +HB,arc130,130,130,1037,1,0,1,0,0.7586805555555556,0,materials problem +HB,ash219,219,85,438,1,1,0,0,0,0,least squares problem +HB,ash292,292,292,2208,1,1,0,0,1,1,least squares problem +HB,ash331,331,104,662,1,1,0,0,0,0,least squares problem +HB,ash608,608,188,1216,1,1,0,0,0,0,least squares problem +HB,ash85,85,85,523,1,1,0,0,1,1,least squares problem +HB,ash958,958,292,1916,1,1,0,0,0,0,least squares problem +HB,bcspwr01,39,39,131,1,1,0,0,1,1,power network problem +HB,bcspwr02,49,49,167,1,1,0,0,1,1,power network problem +HB,bcspwr03,118,118,476,1,1,0,0,1,1,power network problem +HB,bcspwr04,274,274,1612,1,1,0,0,1,1,power network problem +HB,bcspwr05,443,443,1623,1,1,0,0,1,1,power network problem +HB,bcspwr06,1454,1454,5300,1,1,0,0,1,1,power network problem +HB,bcspwr07,1612,1612,5824,1,1,0,0,1,1,power network problem +HB,bcspwr08,1624,1624,6050,1,1,0,0,1,1,power network problem +HB,bcspwr09,1723,1723,6511,1,1,0,0,1,1,power network problem +HB,bcspwr10,5300,5300,21842,1,1,0,0,1,1,power network problem +HB,bcsstk01,48,48,400,1,0,1,1,1,1,structural problem +HB,bcsstk02,66,66,4356,1,0,1,1,1,1,structural problem +HB,bcsstk03,112,112,640,1,0,1,1,1,1,structural problem +HB,bcsstk04,132,132,3648,1,0,1,1,1,1,structural problem +HB,bcsstk05,153,153,2423,1,0,1,1,1,1,structural problem +HB,bcsstk06,420,420,7860,1,0,1,1,1,1,structural problem +HB,bcsstk07,420,420,7860,1,0,1,1,1,1,duplicate structural problem +HB,bcsstk08,1074,1074,12960,1,0,1,1,1,1,structural problem +HB,bcsstk09,1083,1083,18437,1,0,1,1,1,1,structural problem +HB,bcsstk10,1086,1086,22070,1,0,1,1,1,1,structural problem +HB,bcsstk11,1473,1473,34241,1,0,1,1,1,1,structural problem +HB,bcsstk12,1473,1473,34241,1,0,1,1,1,1,duplicate structural problem +HB,bcsstk13,2003,2003,83883,1,0,1,1,1,1,computational fluid dynamics problem +HB,bcsstk14,1806,1806,63454,1,0,1,1,1,1,structural problem +HB,bcsstk15,3948,3948,117816,1,0,1,1,1,1,structural problem +HB,bcsstk16,4884,4884,290378,1,0,1,1,1,1,structural problem +HB,bcsstk17,10974,10974,428650,1,0,1,1,1,1,structural problem +HB,bcsstk18,11948,11948,149090,1,0,1,1,1,1,structural problem +HB,bcsstk19,817,817,6853,1,0,1,1,1,1,structural problem +HB,bcsstk20,485,485,3135,1,0,1,1,1,1,structural problem +HB,bcsstk21,3600,3600,26600,1,0,1,1,1,1,structural problem +HB,bcsstk22,138,138,696,1,0,1,1,1,1,structural problem +HB,bcsstk23,3134,3134,45178,1,0,1,1,1,1,structural problem +HB,bcsstk24,3562,3562,159910,1,0,1,1,1,1,structural problem +HB,bcsstk25,15439,15439,252241,1,0,1,1,1,1,structural problem +HB,bcsstk26,1922,1922,30336,1,0,1,1,1,1,structural problem +HB,bcsstk27,1224,1224,56126,1,0,1,1,1,1,structural problem +HB,bcsstk28,4410,4410,219024,1,0,1,1,1,1,structural problem +HB,bcsstk29,13992,13992,619488,1,1,1,0,1,1,structural problem +HB,bcsstk30,28924,28924,2043492,1,1,1,0,1,1,structural problem +HB,bcsstk31,35588,35588,1181416,1,1,1,0,1,1,structural problem +HB,bcsstk32,44609,44609,2014701,1,1,1,0,1,1,structural problem +HB,bcsstk33,8738,8738,591904,1,1,1,0,1,1,structural problem +HB,bcsstm01,48,48,24,1,0,1,0,1,1,structural problem +HB,bcsstm02,66,66,66,1,0,1,1,1,1,structural problem +HB,bcsstm03,112,112,72,1,0,1,0,1,1,structural problem +HB,bcsstm04,132,132,66,1,0,1,0,1,1,structural problem +HB,bcsstm05,153,153,153,1,0,1,1,1,1,structural problem +HB,bcsstm06,420,420,420,1,0,1,1,1,1,structural problem +HB,bcsstm07,420,420,7252,1,0,1,1,1,1,structural problem +HB,bcsstm08,1074,1074,1074,1,0,1,1,1,1,structural problem +HB,bcsstm09,1083,1083,1083,1,0,1,1,1,1,structural problem +HB,bcsstm10,1086,1086,22092,1,0,1,0,1,1,structural problem +HB,bcsstm11,1473,1473,1473,1,0,1,1,1,1,structural problem +HB,bcsstm12,1473,1473,19659,1,0,1,1,1,1,structural problem +HB,bcsstm13,2003,2003,21181,1,0,1,0,1,1,computational fluid dynamics problem +HB,bcsstm19,817,817,817,1,0,1,1,1,1,structural problem +HB,bcsstm20,485,485,485,1,0,1,1,1,1,structural problem +HB,bcsstm21,3600,3600,3600,1,0,1,1,1,1,structural problem +HB,bcsstm22,138,138,138,1,0,1,1,1,1,structural problem +HB,bcsstm23,3134,3134,3134,1,0,1,1,1,1,structural problem +HB,bcsstm24,3562,3562,3562,1,0,1,1,1,1,structural problem +HB,bcsstm25,15439,15439,15439,1,0,1,1,1,1,structural problem +HB,bcsstm26,1922,1922,1922,1,0,1,1,1,1,structural problem +HB,bcsstm27,1224,1224,56126,1,0,1,0,1,1,structural problem +HB,beacxc,497,506,50409,1,0,0,0,0,0,economic problem +HB,beaflw,497,507,53403,1,0,0,0,0,0,economic problem +HB,beause,497,507,44551,1,0,0,0,0,0,economic problem +HB,blckhole,2132,2132,14872,1,1,1,0,1,1,structural problem +HB,bp_0,822,822,3276,1,0,0,0,0.009160305343511451,0.001221374045801527,optimization problem sequence +HB,bp_1000,822,822,4661,1,0,0,0,0.009448142581060769,0.0004294610264118531,subsequent optimization problem +HB,bp_1200,822,822,4726,1,0,0,0,0.009322033898305085,0.000423728813559322,subsequent optimization problem +HB,bp_1400,822,822,4790,1,0,0,0,0.01044932079414838,0.0004179728317659352,subsequent optimization problem +HB,bp_1600,822,822,4841,1,0,0,0,0.01075491209927611,0.0004136504653567735,subsequent optimization problem +HB,bp_200,822,822,3802,1,0,0,0,0.00631578947368421,0,subsequent optimization problem +HB,bp_400,822,822,4028,1,0,0,0,0.00546448087431694,0.0004967709885742673,subsequent optimization problem +HB,bp_600,822,822,4172,1,0,0,0,0.006235011990407674,0.0004796163069544365,subsequent optimization problem +HB,bp_800,822,822,4534,1,0,0,0,0.005298013245033113,0.0004415011037527594,subsequent optimization problem +HB,can_1054,1054,1054,12196,1,1,1,0,1,1,structural problem +HB,can_1072,1072,1072,12444,1,1,1,0,1,1,structural problem +HB,can_144,144,144,1296,1,1,1,0,1,1,structural problem +HB,can_161,161,161,1377,1,1,1,0,1,1,structural problem +HB,can_187,187,187,1491,1,1,1,0,1,1,structural problem +HB,can_229,229,229,1777,1,1,1,0,1,1,structural problem +HB,can_24,24,24,160,1,1,1,0,1,1,structural problem +HB,can_256,256,256,2916,1,1,1,0,1,1,structural problem +HB,can_268,268,268,3082,1,1,1,0,1,1,structural problem +HB,can_292,292,292,2540,1,1,1,0,1,1,structural problem +HB,can_445,445,445,3809,1,1,1,0,1,1,structural problem +HB,can_61,61,61,557,1,1,1,0,1,1,structural problem +HB,can_62,62,62,218,1,1,1,0,1,1,structural problem +HB,can_634,634,634,7228,1,1,1,0,1,1,structural problem +HB,can_715,715,715,6665,1,1,1,0,1,1,structural problem +HB,can_73,73,73,377,1,1,1,0,1,1,structural problem +HB,can_838,838,838,10010,1,1,1,0,1,1,structural problem +HB,can_96,96,96,768,1,1,1,0,1,1,structural problem +HB,curtis54,54,54,291,1,1,1,0,0.9535864978902954,0.9535864978902954,2D/3D problem +HB,dwt_1005,1005,1005,8621,1,1,1,0,1,1,structural problem +HB,dwt_1007,1007,1007,8575,1,1,1,0,1,1,structural problem +HB,dwt_1242,1242,1242,10426,1,1,1,0,1,1,structural problem +HB,dwt_162,162,162,1182,1,1,1,0,1,1,structural problem +HB,dwt_193,193,193,3493,1,1,1,0,1,1,structural problem +HB,dwt_198,198,198,1392,1,1,1,0,1,1,structural problem +HB,dwt_209,209,209,1743,1,1,1,0,1,1,structural problem +HB,dwt_221,221,221,1629,1,1,1,0,1,1,structural problem +HB,dwt_234,234,234,834,1,1,1,0,1,1,structural problem +HB,dwt_245,245,245,1461,1,1,1,0,1,1,structural problem +HB,dwt_2680,2680,2680,25026,1,1,1,0,1,1,structural problem +HB,dwt_307,307,307,2523,1,1,1,0,1,1,structural problem +HB,dwt_310,310,310,2448,1,1,1,0,1,1,structural problem +HB,dwt_346,346,346,3226,1,1,1,0,1,1,structural problem +HB,dwt_361,361,361,2953,1,1,1,0,1,1,structural problem +HB,dwt_419,419,419,3563,1,1,1,0,1,1,structural problem +HB,dwt_492,492,492,3156,1,1,1,0,1,1,structural problem +HB,dwt_503,503,503,6027,1,1,1,0,1,1,structural problem +HB,dwt_512,512,512,3502,1,1,1,0,1,1,structural problem +HB,dwt_59,59,59,267,1,1,1,0,1,1,structural problem +HB,dwt_592,592,592,5104,1,1,1,0,1,1,structural problem +HB,dwt_607,607,607,5131,1,1,1,0,1,1,structural problem +HB,dwt_66,66,66,320,1,1,1,0,1,1,structural problem +HB,dwt_72,72,72,222,1,1,1,0,1,1,structural problem +HB,dwt_758,758,758,5994,1,1,1,0,1,1,structural problem +HB,dwt_869,869,869,7285,1,1,1,0,1,1,structural problem +HB,dwt_87,87,87,541,1,1,1,0,1,1,structural problem +HB,dwt_878,878,878,7448,1,1,1,0,1,1,structural problem +HB,dwt_918,918,918,7384,1,1,1,0,1,1,structural problem +HB,dwt_992,992,992,16744,1,1,1,0,1,1,structural problem +HB,eris1176,1176,1176,18552,1,1,0,0,1,1,power network problem +HB,fs_183_1,183,183,998,1,0,1,0,0.417607223476298,0,2D/3D problem sequence +HB,fs_183_3,183,183,1069,1,0,1,0,0.417607223476298,0,subsequent 2D/3D problem +HB,fs_183_4,183,183,1069,1,0,1,0,0.417607223476298,0,subsequent 2D/3D problem +HB,fs_183_6,183,183,1000,1,0,1,0,0.417607223476298,0,subsequent 2D/3D problem +HB,fs_541_1,541,541,4282,1,0,1,0,0.6826923076923077,0,2D/3D problem sequence +HB,fs_541_2,541,541,4282,1,0,1,0,0.6826923076923077,0,subsequent 2D/3D problem +HB,fs_541_3,541,541,4282,1,0,1,0,0.6826923076923077,0,subsequent 2D/3D problem +HB,fs_541_4,541,541,4273,1,0,1,0,0.6826923076923077,0,subsequent 2D/3D problem +HB,fs_680_1,680,680,2184,1,0,1,0,0.5106815869786369,0,2D/3D problem sequence +HB,fs_680_2,680,680,2424,1,0,1,0,0.5106815869786369,0,subsequent 2D/3D problem +HB,fs_680_3,680,680,2471,1,0,1,0,0.5106815869786369,0,subsequent 2D/3D problem +HB,fs_760_1,760,760,5739,1,0,1,0,0.6510736196319018,0,2D/3D problem sequence +HB,fs_760_2,760,760,5739,1,0,1,0,0.6510736196319018,0,subsequent 2D/3D problem +HB,fs_760_3,760,760,5816,1,0,1,0,0.6510736196319018,0,subsequent 2D/3D problem +HB,gemat1,4929,10595,46591,1,0,0,0,0,0,power network problem +HB,gemat11,4929,4929,33108,1,0,0,0,0.001326419872181358,0,power network problem sequence +HB,gemat12,4929,4929,33044,1,0,0,0,0.001450063440275512,0,subsequent power network problem +HB,gent113,113,113,655,1,1,0,0,0.05663716814159292,0.05663716814159292,statistical/mathematical problem +HB,gr_30_30,900,900,7744,1,0,1,1,1,1,2D/3D problem +HB,gre_1107,1107,1107,5664,1,0,0,0,0,0,directed weighted graph +HB,gre_115,115,115,421,1,0,0,0,0.2549019607843137,0,directed weighted graph +HB,gre_185,185,185,975,1,0,0,0,0.4146341463414634,0,directed weighted graph +HB,gre_216a,216,216,812,1,0,0,0,0,0,directed weighted graph +HB,gre_216b,216,216,812,1,0,0,0,0,0,directed weighted graph +HB,gre_343,343,343,1310,1,0,0,0,0,0,directed weighted graph +HB,gre_512,512,512,1976,1,0,0,0,0,0,directed weighted graph +HB,hor_131,434,434,4182,1,0,0,0,1,0.3740661686232657,directed weighted graph +HB,ibm32,32,32,126,1,1,0,0,0.0851063829787234,0.0851063829787234,directed graph +HB,illc1033,1033,320,4719,1,0,0,0,0,0,least squares problem +HB,illc1850,1850,712,8636,1,0,0,0,0,0,least squares problem +HB,impcol_a,207,207,572,1,0,0,0,0.02482269503546099,0.01063829787234043,chemical process simulation problem +HB,impcol_b,59,59,271,1,0,0,0,0.09491525423728814,0,chemical process simulation problem +HB,impcol_c,137,137,400,1,0,0,0,0.04444444444444445,0.01146131805157593,chemical process simulation problem +HB,impcol_d,425,425,1255,1,0,0,0,0.05674846625766871,0.0228198859005705,chemical process simulation problem +HB,impcol_e,225,225,1303,1,0,0,0,0.1038338658146965,0.001603849238171612,chemical process simulation problem +HB,jagmesh1,936,936,6264,1,1,1,0,1,1,2D/3D problem +HB,jagmesh2,1009,1009,6865,1,1,1,0,1,1,2D/3D problem +HB,jagmesh3,1089,1089,7361,1,1,1,0,1,1,2D/3D problem +HB,jagmesh4,1440,1440,9504,1,1,1,0,1,1,2D/3D problem +HB,jagmesh5,1180,1180,7750,1,1,1,0,1,1,2D/3D problem +HB,jagmesh6,1377,1377,8993,1,1,1,0,1,1,2D/3D problem +HB,jagmesh7,1138,1138,7450,1,1,1,0,1,1,2D/3D problem +HB,jagmesh8,1141,1141,7465,1,1,1,0,1,1,2D/3D problem +HB,jagmesh9,1349,1349,9101,1,1,1,0,1,1,2D/3D problem +HB,jgl009,9,9,50,1,1,0,0,0.4761904761904762,0.4761904761904762,counter-example problem +HB,jgl011,11,11,76,1,1,0,0,0.5151515151515151,0.5151515151515151,counter-example problem +HB,jpwh_991,991,991,6027,1,0,1,0,0.9364575059571089,0.9364575059571089,semiconductor device problem +HB,lns_131,131,131,536,1,0,1,0,0.7028301886792453,0.01886792452830189,computational fluid dynamics problem +HB,lns_3937,3937,3937,25407,1,0,1,0,0.849666726715907,0.001351107908484958,computational fluid dynamics problem +HB,lns_511,511,511,2796,1,0,1,0,0.7994945240101096,0.02021903959561921,computational fluid dynamics problem +HB,lnsp3937,3937,3937,25407,1,0,1,0,0.849666726715907,0.001351107908484958,computational fluid dynamics problem +HB,lnsp_131,131,131,536,1,0,1,0,0.7028301886792453,0.01886792452830189,computational fluid dynamics problem +HB,lnsp_511,511,511,2796,1,0,1,0,0.7994945240101096,0.02021903959561921,computational fluid dynamics problem +HB,lshp1009,1009,1009,6865,1,1,1,0,1,1,duplicate thermal problem +HB,lshp1270,1270,1270,8668,1,1,1,0,1,1,thermal problem +HB,lshp1561,1561,1561,10681,1,1,1,0,1,1,thermal problem +HB,lshp1882,1882,1882,12904,1,1,1,0,1,1,thermal problem +HB,lshp2233,2233,2233,15337,1,1,1,0,1,1,thermal problem +HB,lshp2614,2614,2614,17980,1,1,1,0,1,1,thermal problem +HB,lshp3025,3025,3025,20833,1,1,1,0,1,1,thermal problem +HB,lshp3466,3466,3466,23896,1,1,1,0,1,1,thermal problem +HB,lshp_265,265,265,1753,1,1,1,0,1,1,thermal problem +HB,lshp_406,406,406,2716,1,1,1,0,1,1,thermal problem +HB,lshp_577,577,577,3889,1,1,1,0,1,1,thermal problem +HB,lshp_778,778,778,5272,1,1,1,0,1,1,thermal problem +HB,lund_a,147,147,2449,1,0,1,1,1,1,structural problem +HB,lund_b,147,147,2441,1,0,1,1,1,1,structural problem +HB,mahindas,1258,1258,7682,1,0,0,0,0.01663146779303062,0,economic problem +HB,mbeacxc,496,496,49920,1,0,0,0,0.3162614104531868,0,economic problem +HB,mbeaflw,496,496,49920,1,0,0,0,0.3162614104531868,0,economic problem +HB,mbeause,496,496,41063,1,0,0,0,0.2190689324447286,0.007771192484568281,economic problem +HB,mcca,180,180,2659,1,0,1,0,0.6446147640177491,0,2D/3D problem +HB,mcfe,765,765,24382,1,0,1,0,0.699411440911208,0,2D/3D problem +HB,nnc1374,1374,1374,8588,1,0,1,0,0.8169596690796277,0.5918631769888573,2D/3D problem +HB,nnc261,261,261,1500,1,0,1,0,0.8237037037037037,0.6133333333333333,2D/3D problem +HB,nnc666,666,666,4032,1,0,1,0,0.817831590533847,0.5919381557150746,2D/3D problem +HB,nos1,237,237,1017,1,0,1,1,1,1,structural problem +HB,nos2,957,957,4137,1,0,1,1,1,1,structural problem +HB,nos3,960,960,15844,1,0,1,1,1,1,structural problem +HB,nos4,100,100,594,1,0,1,1,1,1,structural problem +HB,nos5,468,468,5172,1,0,1,1,1,1,structural problem +HB,nos6,675,675,3255,1,0,1,1,1,1,2D/3D problem +HB,nos7,729,729,4617,1,0,1,1,1,1,2D/3D problem +HB,orani678,2529,2529,90158,1,0,0,0,0.07068607068607069,2.223531635296341e-05,economic problem +HB,orsirr_1,1030,1030,6858,1,0,1,0,1,0.4094028826355525,computational fluid dynamics problem +HB,orsirr_2,886,886,5970,1,0,1,0,1,0.4118804091266719,computational fluid dynamics problem +HB,orsreg_1,2205,2205,14133,1,0,1,0,1,0.4119718309859155,computational fluid dynamics problem +HB,plat1919,1919,1919,32399,1,0,1,1,1,1,2D/3D problem +HB,plat362,362,362,5786,1,0,1,1,1,1,2D/3D problem +HB,plsk1919,1919,1919,9662,1,0,1,0,1,0,2D/3D problem +HB,plskz362,362,362,1760,1,0,1,0,1,0,2D/3D problem +HB,pores_1,30,30,180,1,0,1,0,0.6266666666666667,0.2933333333333333,computational fluid dynamics problem +HB,pores_2,1224,1224,9613,1,0,1,0,0.6119918941470974,0.3914650137084277,computational fluid dynamics problem +HB,pores_3,532,532,3474,1,0,1,0,0.7423521414004078,0.3052345343303875,computational fluid dynamics problem +HB,psmigr_1,3140,3140,543160,1,0,0,0,0.4786508697793794,0.01044772250019444,economic problem +HB,psmigr_2,3140,3140,540022,1,0,0,0,0.4786508697793794,0,economic problem +HB,psmigr_3,3140,3140,543160,1,0,0,0,0.4786508697793794,0,economic problem +HB,rgg010,10,10,76,1,1,0,0,0.6363636363636364,0.6363636363636364,counter-example problem +HB,saylr1,238,238,1128,1,0,1,0,1,0.647191011235955,computational fluid dynamics problem +HB,saylr3,1000,1000,3750,1,0,1,0,1,1,computational fluid dynamics problem +HB,saylr4,3564,3564,22316,1,0,1,0,1,1,computational fluid dynamics problem +HB,sherman1,1000,1000,3750,1,0,1,0,1,1,computational fluid dynamics problem +HB,sherman2,1080,1080,23094,1,0,1,0,0.6708458253838466,0.004905968928863451,computational fluid dynamics problem +HB,sherman3,5005,5005,20033,1,0,1,0,1,0.4532871972318339,computational fluid dynamics problem +HB,sherman4,1104,1104,3786,1,0,1,0,1,0,computational fluid dynamics problem +HB,sherman5,3312,3312,20793,1,0,1,0,0.7386305131285396,0.1534237171786511,computational fluid dynamics problem +HB,shl_0,663,663,1687,1,0,0,0,0,0,optimization problem sequence +HB,shl_200,663,663,1726,1,0,0,0,0,0,subsequent optimization problem +HB,shl_400,663,663,1712,1,0,0,0,0,0,subsequent optimization problem +HB,sstmodel,3345,3345,22749,1,1,1,0,1,1,structural problem +HB,steam1,240,240,2248,1,0,1,0,1,0.2729083665338645,computational fluid dynamics problem +HB,steam2,600,600,5660,1,0,1,0,1,0.1877470355731225,computational fluid dynamics problem +HB,steam3,80,80,314,1,0,1,0,1,0.3247863247863248,computational fluid dynamics problem +HB,str_0,363,363,2454,1,0,0,0,0.004893964110929853,0,optimization problem sequence +HB,str_200,363,363,3068,1,0,0,0,0.01108936725375081,0,subsequent optimization problem +HB,str_400,363,363,3157,1,0,0,0,0.0196513470681458,0,subsequent optimization problem +HB,str_600,363,363,3279,1,0,0,0,0.01893129770992366,0,subsequent optimization problem +HB,watt_1,1856,1856,11360,1,0,1,0,0.9865319865319865,0.9865319865319865,computational fluid dynamics problem +HB,watt_2,1856,1856,11550,1,0,1,0,0.9804002475758201,0.9671962038374252,computational fluid dynamics problem +HB,well1033,1033,320,4732,1,0,0,0,0,0,least squares problem +HB,well1850,1850,712,8755,1,0,0,0,0,0,least squares problem +HB,west0067,67,67,294,1,0,0,0,0.03424657534246575,0,chemical process simulation problem +HB,west0132,132,132,413,1,0,0,0,0.0196078431372549,0.004914004914004914,chemical process simulation problem +HB,west0156,156,156,362,1,0,0,0,0,0,chemical process simulation problem +HB,west0167,167,167,506,1,0,0,0,0.01622718052738337,0,chemical process simulation problem +HB,west0381,381,381,2134,1,0,0,0,0.005565862708719851,0.0009376465072667605,chemical process simulation problem +HB,west0479,479,479,1888,1,0,0,0,0.01366982124079916,0,chemical process simulation problem +HB,west0497,497,497,1721,1,0,0,0,0.006972690296339338,0,chemical process simulation problem +HB,west0655,655,655,2808,1,0,0,0,0.005616005616005616,0,chemical process simulation problem +HB,west0989,989,989,3518,1,0,0,0,0.01812004530011325,0.003985197836606889,chemical process simulation problem +HB,west1505,1505,1505,5414,1,0,0,0,0.001102941176470588,0,chemical process simulation problem +HB,west2021,2021,2021,7310,1,0,0,0,0.00326619488296135,0,chemical process simulation problem +HB,will199,199,199,701,1,1,1,0,0.05596465390279824,0.05596465390279824,structural problem +HB,will57,57,57,281,1,1,1,0,0.8660714285714286,0.8660714285714286,semiconductor device problem +HB,wm1,207,277,2909,1,0,0,0,0,0,economic problem +HB,wm2,207,260,2942,1,0,0,0,0,0,economic problem +HB,wm3,207,260,2948,1,0,0,0,0,0,economic problem +HB,young1c,841,841,4089,0,0,1,0,1,0.8479064039408867,acoustics problem +HB,young2c,841,841,4089,0,0,1,0,1,0.8479064039408867,duplicate acoustics problem +HB,young3c,841,841,3988,1,0,1,0,0.9380362249761678,0.8071178900540197,acoustics problem +HB,young4c,841,841,4089,0,0,1,0,1,0.8004926108374384,acoustics problem +HB,zenios,2873,2873,1314,1,0,0,0,1,1,optimization problem +ATandT,onetone1,36057,36057,335552,1,0,0,0,0.0742956282869174,0.04331285111284008,frequency-domain circuit simulation problem +ATandT,onetone2,36057,36057,222596,1,0,0,0,0.1128682425939654,0.06622764699821082,frequency-domain circuit simulation problem +ATandT,pre2,659033,659033,5834044,1,0,0,0,0.3317760910564062,0.06536187196755584,frequency-domain circuit simulation problem +ATandT,twotone,120750,120750,1206265,1,0,0,0,0.2445668624008717,0.1058542372000797,frequency-domain circuit simulation problem +Averous,epb0,1794,1794,7764,1,0,1,0,0.5008375209380235,0,thermal problem +Averous,epb1,14734,14734,95053,1,0,1,0,0.7293915511896314,0,thermal problem +Averous,epb2,25228,25228,175027,1,0,1,0,0.6705385216189694,0,thermal problem +Averous,epb3,84617,84617,463625,1,0,1,0,0.6674107142857143,0.03155606214116852,thermal problem +Bai,af23560,23560,23560,460598,1,0,1,0,0.9973084203031934,0,computational fluid dynamics problem +Bai,bfwa398,398,398,3678,1,0,1,0,0.9890243902439024,0.9432926829268292,electromagnetics problem +Bai,bfwa62,62,62,450,1,0,1,0,0.9690721649484536,0.8144329896907216,electromagnetics problem +Bai,bfwa782,782,782,7514,1,0,1,0,0.9916815210932858,0.9604872251931076,electromagnetics problem +Bai,bfwb398,398,398,2910,1,0,1,0,1,1,electromagnetics problem +Bai,bfwb62,62,62,342,1,0,1,0,1,1,electromagnetics problem +Bai,bfwb782,782,782,5982,1,0,1,0,1,1,electromagnetics problem +Bai,bwm200,200,200,796,1,0,0,0,1,0.6644295302013423,chemical process simulation problem +Bai,bwm2000,2000,2000,7996,1,0,0,0,1,0.6664442961974649,chemical process simulation problem +Bai,cdde1,961,961,4681,1,0,1,0,1,0,computational fluid dynamics problem sequence +Bai,cdde2,961,961,4681,1,0,1,0,1,0,subsequent computational fluid dynamics problem +Bai,cdde3,961,961,4681,1,0,1,0,1,0,subsequent computational fluid dynamics problem +Bai,cdde4,961,961,4681,1,0,1,0,1,0,subsequent computational fluid dynamics problem +Bai,cdde5,961,961,4681,1,0,1,0,1,0,subsequent computational fluid dynamics problem +Bai,cdde6,961,961,4681,1,0,1,0,1,0,subsequent computational fluid dynamics problem +Bai,ck104,104,104,992,1,0,1,0,1,0,2D/3D problem +Bai,ck400,400,400,2860,1,0,1,0,0.9886178861788618,0.001626016260162602,2D/3D problem +Bai,ck656,656,656,3884,1,0,1,0,0.9913258983890955,0,2D/3D problem +Bai,dw1024,2048,2048,10114,1,0,1,0,0.9848747830399207,0.9481775353334987,electromagnetics problem +Bai,dw256A,512,512,2480,1,0,1,0,0.9796747967479674,0.9146341463414634,electromagnetics problem +Bai,dw256B,512,512,2500,1,0,1,0,0.9698189134808853,0.8832997987927566,electromagnetics problem +Bai,dw4096,8192,8192,41746,1,0,1,0,0.9626274065685164,0.9154199201287477,electromagnetics problem +Bai,lop163,163,163,935,1,0,0,0,0.4507772020725389,0,statistical/mathematical problem +Bai,mhda416,416,416,8562,1,0,1,0,0.7675276752767528,0.2675871920009523,electromagnetics problem +Bai,mhdb416,416,416,2312,1,0,1,1,1,1,electromagnetics problem +Bai,odepa400,400,400,1201,1,0,1,0,0.9962546816479401,0.9937578027465668,2D/3D problem +Bai,odepb400,400,400,399,1,0,1,0,1,1,2D/3D problem +Bai,olm100,100,100,396,1,0,1,0,0.668918918918919,0.3310810810810811,computational fluid dynamics problem +Bai,olm1000,1000,1000,3996,1,0,1,0,0.6668891855807744,0.3331108144192256,computational fluid dynamics problem +Bai,olm2000,2000,2000,7996,1,0,1,0,0.6667778519012675,0.3332221480987325,computational fluid dynamics problem +Bai,olm500,500,500,1996,1,0,1,0,0.6671122994652406,0.3328877005347594,computational fluid dynamics problem +Bai,olm5000,5000,5000,19996,1,0,1,0,0.6667111229661243,0.3332888770338757,computational fluid dynamics problem +Bai,pde225,225,225,1065,1,0,1,0,1,0.5,2D/3D problem +Bai,pde2961,2961,2961,14585,1,0,1,0,1,0.5013764624913971,2D/3D problem +Bai,pde900,900,900,4380,1,0,1,0,1,0.5,2D/3D problem +Bai,qc2534,2534,2534,463360,0,0,1,0,1,0,electromagnetics problem +Bai,qc324,324,324,26730,0,0,1,0,1,0,electromagnetics problem +Bai,qh882,882,882,3354,1,0,0,0,0.9264705882352942,0,power network problem +Bai,rbsa480,480,480,17088,1,0,1,0,0.07485627126598615,0.0007039774727208729,robotics problem +Bai,rbsb480,480,480,17088,1,0,1,0,0.07568201818715166,0.0008213552361396304,robotics problem +Bai,rdb2048,2048,2048,12032,1,0,1,0,1,0.7948717948717948,computational fluid dynamics problem +Bai,rdb5000,5000,5000,29600,1,0,1,0,1,0.7967479674796748,computational fluid dynamics problem +Bai,rdb968,968,968,5632,1,0,1,0,1,0.7924528301886793,computational fluid dynamics problem +Bai,rw136,136,136,479,1,0,0,0,0.44258872651357,0.02922755741127349,statistical/mathematical problem +Bai,rw496,496,496,1859,1,0,0,0,0.4690693921463152,0,statistical/mathematical problem +Bai,rw5151,5151,5151,20199,1,0,0,0,0.4902222882320907,0,statistical/mathematical problem +Bai,tub100,100,100,396,1,0,1,0,1,0,computational fluid dynamics problem +Bai,tub1000,1000,1000,3996,1,0,1,0,1,0,computational fluid dynamics problem +Boeing,bcsstk34,588,588,21418,1,0,1,1,1,1,structural problem +Boeing,bcsstk35,30237,30237,1450163,1,0,1,0,1,1,structural problem +Boeing,bcsstk36,23052,23052,1143140,1,0,1,1,1,1,structural problem +Boeing,bcsstk37,25503,25503,1140977,1,0,1,0,1,1,structural problem +Boeing,bcsstk38,8032,8032,355460,1,0,1,1,1,1,structural problem +Boeing,bcsstm34,588,588,24270,1,0,1,0,1,1,structural problem +Boeing,bcsstm35,30237,30237,20619,1,0,1,0,1,1,structural problem +Boeing,bcsstm36,23052,23052,320606,1,0,1,0,1,1,structural problem +Boeing,bcsstm37,25503,25503,15525,1,0,1,0,1,1,structural problem +Boeing,bcsstm38,8032,8032,10485,1,0,1,0,1,1,structural problem +Boeing,bcsstm39,46772,46772,46772,1,0,1,1,1,1,structural problem +Boeing,crystk01,4875,4875,315891,1,0,1,0,1,1,materials problem +Boeing,crystk02,13965,13965,968583,1,0,1,0,1,1,materials problem +Boeing,crystk03,24696,24696,1751178,1,0,1,0,1,1,materials problem +Boeing,crystm01,4875,4875,105339,1,0,1,1,1,1,materials problem +Boeing,crystm02,13965,13965,322905,1,0,1,1,1,1,materials problem +Boeing,crystm03,24696,24696,583770,1,0,1,1,1,1,materials problem +Boeing,ct20stif,52329,52329,2600295,1,0,1,1,1,1,structural problem +Boeing,msc00726,726,726,34518,1,0,1,1,1,1,structural problem +Boeing,msc01050,1050,1050,26198,1,0,1,1,1,1,structural problem +Boeing,msc01440,1440,1440,44998,1,0,1,1,1,1,structural problem +Boeing,msc04515,4515,4515,97707,1,0,1,1,1,1,structural problem +Boeing,msc10848,10848,10848,1229776,1,0,1,1,1,1,structural problem +Boeing,msc23052,23052,23052,1142686,1,0,1,1,1,1,structural problem +Boeing,nasa1824,1824,1824,39208,1,0,1,0,1,1,duplicate structural problem +Boeing,nasa2910,2910,2910,174296,1,1,1,0,1,1,duplicate structural problem +Boeing,nasa4704,4704,4704,104756,1,1,1,0,1,1,duplicate structural problem +Boeing,pcrystk02,13965,13965,968583,1,1,1,0,1,1,duplicate materials problem +Boeing,pcrystk03,24696,24696,1751178,1,1,1,0,1,1,duplicate materials problem +Boeing,pct20stif,52329,52329,2698463,1,1,1,0,1,1,structural problem +Boeing,pwtk,217918,217918,11524432,1,0,1,1,1,1,structural problem +Bomhof,circuit_1,2624,2624,35823,1,0,0,0,0.999548641410646,0.2060602413263924,circuit simulation problem +Bomhof,circuit_2,4510,4510,21199,1,0,0,0,0.8065636603186011,0.4152593124925141,circuit simulation problem +Bomhof,circuit_3,12127,12127,48137,1,0,0,0,0.7700717835450027,0.3001104362230811,circuit simulation problem +Bomhof,circuit_4,80209,80209,307604,1,0,0,0,0.8292028705104302,0.3635452210926232,circuit simulation problem +Bova,rma10,46835,46835,2329092,1,0,1,0,1,0.2355549300354827,computational fluid dynamics problem +Brethour,coater1,1348,1348,19457,1,0,1,0,0.5922916666666667,0.395,computational fluid dynamics problem +Brethour,coater2,9540,9540,207308,1,0,1,0,0.5941884735804569,0.1280874338061923,computational fluid dynamics problem +Brunetiere,thermal,3456,3456,66528,1,0,1,0,1,0.0730593607305936,thermal problem +Cote,mplate,5962,5962,142190,0,0,1,0,1,0.05311683354376486,acoustics problem +Cote,vibrobox,12328,12328,301700,1,0,1,0,1,1,acoustics problem +DRIVCAV,cavity01,317,317,7280,1,0,1,0,0.8037831733483908,0.5198237885462555,computational fluid dynamics problem sequence +DRIVCAV,cavity02,317,317,5923,1,0,1,0,0.8037831733483908,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity03,317,317,7311,1,0,1,0,0.8037831733483908,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity04,317,317,5923,1,0,1,0,0.8037831733483908,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity05,1182,1182,32632,1,0,1,0,0.9049083605322621,0.6103499322813317,computational fluid dynamics problem sequence +DRIVCAV,cavity06,1182,1182,29675,1,0,1,0,0.9049083605322621,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity07,1182,1182,32702,1,0,1,0,0.9049083605322621,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity08,1182,1182,29675,1,0,1,0,0.9049083605322621,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity09,1182,1182,32702,1,0,1,0,0.9049083605322621,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity10,2597,2597,76171,1,0,1,0,0.9372682821986997,0.6400172395216033,computational fluid dynamics problem sequence +DRIVCAV,cavity11,2597,2597,71601,1,0,1,0,0.9372682821986997,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity12,2597,2597,76258,1,0,1,0,0.9372682821986997,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity13,2597,2597,71601,1,0,1,0,0.9372682821986997,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity14,2597,2597,76258,1,0,1,0,0.9372682821986997,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity15,2597,2597,71601,1,0,1,0,0.9372682821986997,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity16,4562,4562,137887,1,0,1,0,0.9531982436361479,0.6542773036781541,computational fluid dynamics problem sequence +DRIVCAV,cavity17,4562,4562,131735,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity18,4562,4562,138040,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity19,4562,4562,131735,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity20,4562,4562,138040,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity21,4562,4562,131735,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity22,4562,4562,138040,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity23,4562,4562,131735,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity24,4562,4562,138040,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity25,4562,4562,131735,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +DRIVCAV,cavity26,4562,4562,138040,1,0,1,0,0.9531982436361479,0,subsequent computational fluid dynamics problem +FIDAP,ex1,216,216,4317,1,0,1,0,1,0.9980657640232108,computational fluid dynamics problem +FIDAP,ex10,2410,2410,54840,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex10hs,2548,2548,57308,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex11,16614,16614,1096948,1,0,1,0,1,0.9999981487206734,computational fluid dynamics problem +FIDAP,ex12,3973,3973,79077,1,0,1,0,1,1,computational fluid dynamics problem +FIDAP,ex13,2568,2568,75628,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex14,3251,3251,65875,1,0,1,0,1,1,computational fluid dynamics problem +FIDAP,ex15,6867,6867,98671,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex18,5773,5773,71701,1,0,1,0,1,0.4973910933139182,computational fluid dynamics problem +FIDAP,ex19,12005,12005,259577,1,0,1,0,1,0.4284006268883396,computational fluid dynamics problem +FIDAP,ex2,441,441,26839,1,0,1,0,1,1,computational fluid dynamics problem +FIDAP,ex20,2203,2203,67830,1,0,1,0,1,0.9705407160221662,computational fluid dynamics problem +FIDAP,ex21,656,656,18964,1,0,1,0,1,0.9422327996538296,computational fluid dynamics problem +FIDAP,ex22,839,839,22460,1,0,1,0,1,0.88617551561714,computational fluid dynamics problem +FIDAP,ex23,1409,1409,42760,1,0,1,0,1,0.9386855719486492,computational fluid dynamics problem +FIDAP,ex24,2283,2283,47901,1,0,1,0,1,0.862361129122898,computational fluid dynamics problem +FIDAP,ex25,848,848,24369,1,0,1,0,1,0.9755481671646816,computational fluid dynamics problem +FIDAP,ex26,2163,2163,74464,1,0,1,0,1,0.7325380026938618,computational fluid dynamics problem +FIDAP,ex27,974,974,37652,1,0,1,0,1,0.5304041225928939,computational fluid dynamics problem +FIDAP,ex28,2603,2603,77031,1,0,1,0,1,0.9877623772912288,computational fluid dynamics problem +FIDAP,ex29,2870,2870,23754,1,0,1,0,1,0.9963608504117986,computational fluid dynamics problem +FIDAP,ex3,1821,1821,52685,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex31,3909,3909,91223,1,0,1,0,1,0.7266897116346767,computational fluid dynamics problem +FIDAP,ex32,1159,1159,11047,1,0,1,0,1,1,computational fluid dynamics problem +FIDAP,ex33,1733,1733,22189,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex35,19716,19716,227872,1,0,1,0,1,0.4608754972232364,computational fluid dynamics problem +FIDAP,ex36,3079,3079,53099,1,0,1,0,1,0.9952497822816879,computational fluid dynamics problem +FIDAP,ex37,3565,3565,67591,1,0,1,0,1,0.9536750695030144,computational fluid dynamics problem +FIDAP,ex4,1601,1601,31849,1,0,1,0,1,1,computational fluid dynamics problem +FIDAP,ex40,7740,7740,456188,1,0,1,0,1,0.7709917560940942,computational fluid dynamics problem +FIDAP,ex5,27,27,279,1,0,1,1,1,1,computational fluid dynamics problem +FIDAP,ex6,1651,1651,49062,1,0,1,0,1,0.9792406332233408,computational fluid dynamics problem +FIDAP,ex7,1633,1633,46626,1,0,1,0,1,0.8240392950014447,computational fluid dynamics problem +FIDAP,ex8,3096,3096,90841,1,0,1,0,1,0.4310900906034532,computational fluid dynamics problem +FIDAP,ex9,3363,3363,99471,1,0,1,1,1,1,computational fluid dynamics problem +Gaertner,big,13209,13209,91465,1,0,0,0,1,0.999974442854222,directed weighted graph +Gaertner,nopoly,10774,10774,70842,1,0,0,0,1,1,undirected weighted graph +Gaertner,pesa,11738,11738,79566,1,0,0,0,1,0.999970513652179,directed weighted graph +Garon,garon1,3175,3175,84723,1,0,1,0,1,0.6720847366622736,computational fluid dynamics problem +Garon,garon2,13535,13535,373235,1,0,1,0,1,0.6726819817326322,computational fluid dynamics problem +Goodwin,goodwin,7320,7320,324772,1,0,1,0,0.6353114022282706,0.001199255331506196,computational fluid dynamics problem +Goodwin,rim,22560,22560,1014951,1,0,1,0,0.6390640220938991,0,computational fluid dynamics problem +Graham,graham1,9035,9035,335472,1,0,1,0,0.718197839525901,0.0004322586733311619,computational fluid dynamics problem +Grund,b1_ss,7,7,15,1,0,0,0,0,0,chemical process simulation problem +Grund,b2_ss,1089,1089,3895,1,0,0,0,0.0146710837671557,0.0005136106831022085,chemical process simulation problem +Grund,b_dyn,1089,1089,4144,1,0,0,0,0.01454716095729704,0.0004828585224529213,chemical process simulation problem +Grund,bayer01,57735,57735,275094,1,0,0,0,0.0002304047924196823,2.908118011428904e-05,chemical process simulation problem +Grund,bayer02,13935,13935,63307,1,0,0,0,0.001884570082449941,0.000284346713425904,chemical process simulation problem +Grund,bayer03,6747,6747,29195,1,0,0,0,0.003132397173723459,0.0002740852405097985,chemical process simulation problem +Grund,bayer04,20545,20545,85537,1,0,0,0,0.001584088708967702,0.0002104352502425851,chemical process simulation problem +Grund,bayer05,3268,3268,20712,1,0,0,0,0.006682474671265359,0.00135200386286818,chemical process simulation problem +Grund,bayer06,3008,3008,20715,1,0,0,0,0.006745484877058098,0.001351808043257857,chemical process simulation problem +Grund,bayer07,3268,3268,20963,1,0,0,0,0.006682474671265359,0.0013358141310052,chemical process simulation problem +Grund,bayer08,3008,3008,20698,1,0,0,0,0.006745484877058098,0.001352918438345574,chemical process simulation problem +Grund,bayer09,3083,3083,11767,1,0,0,0,0.02112012068640392,0.0001700246535747683,chemical process simulation problem +Grund,bayer10,13436,13436,71594,1,0,0,0,0.002528365095919851,0.0002234917796929782,chemical process simulation problem +Grund,d_dyn,87,87,230,1,0,0,0,0.07692307692307693,0.01769911504424779,chemical process simulation problem +Grund,d_dyn1,87,87,232,1,0,0,0,0.07692307692307693,0.01754385964912281,chemical process simulation problem +Grund,d_ss,53,53,144,1,0,0,0,0.04137931034482759,0,chemical process simulation problem +Grund,meg1,2904,2904,58142,1,0,0,0,0.002374602082078637,0.001996042329863202,circuit simulation problem +Grund,meg4,5860,5860,25258,1,0,0,0,1,1,circuit simulation problem +Grund,poli,4008,4008,8188,1,0,0,0,0.0291866028708134,0.002392344497607655,economic problem +Grund,poli_large,15575,15575,33033,1,0,0,0,0.003543059603405909,0.0004582426394776034,economic problem +Gset,G1,800,800,38352,1,1,0,0,1,1,undirected random graph +Gset,G10,800,800,38352,1,0,0,0,1,1,undirected weighted random graph +Gset,G11,800,800,3200,1,0,0,0,1,1,undirected weighted random graph +Gset,G12,800,800,3200,1,0,0,0,1,1,undirected weighted random graph +Gset,G13,800,800,3200,1,0,0,0,1,1,undirected weighted random graph +Gset,G14,800,800,9388,1,1,0,0,1,1,duplicate undirected random graph +Gset,G15,800,800,9322,1,1,0,0,1,1,duplicate undirected random graph +Gset,G16,800,800,9344,1,1,0,0,1,1,duplicate undirected random graph +Gset,G17,800,800,9334,1,1,0,0,1,1,duplicate undirected random graph +Gset,G18,800,800,9388,1,0,0,0,1,1,undirected weighted random graph +Gset,G19,800,800,9322,1,0,0,0,1,1,undirected weighted random graph +Gset,G2,800,800,38352,1,1,0,0,1,1,undirected random graph +Gset,G20,800,800,9344,1,0,0,0,1,1,undirected weighted random graph +Gset,G21,800,800,9334,1,0,0,0,1,1,undirected weighted random graph +Gset,G22,2000,2000,39980,1,1,0,0,1,1,undirected random graph +Gset,G23,2000,2000,39980,1,1,0,0,1,1,undirected random graph +Gset,G24,2000,2000,39980,1,1,0,0,1,1,undirected random graph +Gset,G25,2000,2000,39980,1,1,0,0,1,1,undirected random graph +Gset,G26,2000,2000,39980,1,1,0,0,1,1,undirected random graph +Gset,G27,2000,2000,39980,1,0,0,0,1,1,undirected weighted random graph +Gset,G28,2000,2000,39980,1,0,0,0,1,1,undirected weighted random graph +Gset,G29,2000,2000,39980,1,0,0,0,1,1,undirected weighted random graph +Gset,G3,800,800,38352,1,1,0,0,1,1,undirected random graph +Gset,G30,2000,2000,39980,1,0,0,0,1,1,undirected weighted random graph +Gset,G31,2000,2000,39980,1,0,0,0,1,1,undirected weighted random graph +Gset,G32,2000,2000,8000,1,0,0,0,1,1,undirected weighted random graph +Gset,G33,2000,2000,8000,1,0,0,0,1,1,undirected weighted random graph +Gset,G34,2000,2000,8000,1,0,0,0,1,1,undirected weighted random graph +Gset,G35,2000,2000,23556,1,1,0,0,1,1,duplicate undirected random graph +Gset,G36,2000,2000,23532,1,1,0,0,1,1,duplicate undirected random graph +Gset,G37,2000,2000,23570,1,1,0,0,1,1,duplicate undirected random graph +Gset,G38,2000,2000,23558,1,1,0,0,1,1,duplicate undirected random graph +Gset,G39,2000,2000,23556,1,0,0,0,1,1,undirected weighted random graph +Gset,G4,800,800,38352,1,1,0,0,1,1,undirected random graph +Gset,G40,2000,2000,23532,1,0,0,0,1,1,undirected weighted random graph +Gset,G41,2000,2000,23570,1,0,0,0,1,1,undirected weighted random graph +Gset,G42,2000,2000,23558,1,0,0,0,1,1,undirected weighted random graph +Gset,G43,1000,1000,19980,1,1,0,0,1,1,undirected random graph +Gset,G44,1000,1000,19980,1,1,0,0,1,1,undirected random graph +Gset,G45,1000,1000,19980,1,1,0,0,1,1,undirected random graph +Gset,G46,1000,1000,19980,1,1,0,0,1,1,undirected random graph +Gset,G47,1000,1000,19980,1,1,0,0,1,1,undirected random graph +Gset,G48,3000,3000,12000,1,1,0,0,1,1,undirected random graph +Gset,G49,3000,3000,12000,1,1,0,0,1,1,undirected random graph +Gset,G5,800,800,38352,1,1,0,0,1,1,undirected random graph +Gset,G50,3000,3000,12000,1,1,0,0,1,1,undirected random graph +Gset,G51,1000,1000,11818,1,1,0,0,1,1,undirected random graph +Gset,G52,1000,1000,11832,1,1,0,0,1,1,undirected random graph +Gset,G53,1000,1000,11828,1,1,0,0,1,1,undirected random graph +Gset,G54,1000,1000,11832,1,1,0,0,1,1,undirected random graph +Gset,G55,5000,5000,24996,1,1,0,0,1,1,duplicate undirected random graph +Gset,G56,5000,5000,24996,1,0,0,0,1,1,undirected weighted random graph +Gset,G57,5000,5000,20000,1,0,0,0,1,1,undirected weighted random graph +Gset,G58,5000,5000,59140,1,1,0,0,1,1,duplicate undirected random graph +Gset,G59,5000,5000,59140,1,0,0,0,1,1,undirected weighted random graph +Gset,G6,800,800,38352,1,0,0,0,1,1,undirected weighted random graph +Gset,G60,7000,7000,34296,1,1,0,0,1,1,duplicate undirected random graph +Gset,G61,7000,7000,34296,1,0,0,0,1,1,undirected weighted random graph +Gset,G62,7000,7000,28000,1,0,0,0,1,1,undirected weighted random graph +Gset,G63,7000,7000,82918,1,1,0,0,1,1,duplicate undirected random graph +Gset,G64,7000,7000,82918,1,0,0,0,1,1,undirected weighted random graph +Gset,G65,8000,8000,32000,1,0,0,0,1,1,undirected weighted random graph +Gset,G66,9000,9000,36000,1,0,0,0,1,1,undirected weighted random graph +Gset,G67,10000,10000,40000,1,0,0,0,1,1,undirected weighted random graph +Gset,G7,800,800,38352,1,0,0,0,1,1,undirected weighted random graph +Gset,G8,800,800,38352,1,0,0,0,1,1,undirected weighted random graph +Gset,G9,800,800,38352,1,0,0,0,1,1,undirected weighted random graph +Gupta,gupta1,31802,31802,2164210,1,1,0,0,1,1,optimization problem +Gupta,gupta2,62064,62064,4248286,1,1,0,0,1,1,optimization problem +Gupta,gupta3,16783,16783,9323427,1,1,0,0,1,1,optimization problem +Hamm,add20,2395,2395,13151,1,0,0,0,1,0.5265898103384158,circuit simulation problem +Hamm,add32,4960,4960,19848,1,0,0,0,1,0.3052122514777001,circuit simulation problem +Hamm,bcircuit,68902,68902,375558,1,0,0,0,1,0.9084315976207868,circuit simulation problem +Hamm,hcircuit,105676,105676,513072,1,0,0,0,0.9999410961997232,0.1951139297670355,circuit simulation problem +Hamm,memplus,17758,17758,99147,1,0,0,0,1,0.4962095614886533,circuit simulation problem +Hamm,scircuit,170998,170998,958936,1,0,0,0,0.9999467019956295,0.8008355096685118,circuit simulation problem +Hollinger,g7jac010,2880,2880,18229,1,0,0,0,0.07102357505222322,0,economic problem +Hollinger,g7jac010sc,2880,2880,18229,1,0,0,0,0.07102357505222322,0,economic problem +Hollinger,g7jac020,5850,5850,42568,1,0,0,0,0.06184526063359838,0,economic problem +Hollinger,g7jac020sc,5850,5850,42568,1,0,0,0,0.06184526063359838,0,economic problem +Hollinger,g7jac040,11790,11790,107383,1,0,0,0,0.04830823961664447,0,economic problem +Hollinger,g7jac040sc,11790,11790,107383,1,0,0,0,0.04830823961664447,0,economic problem +Hollinger,g7jac050sc,14760,14760,145157,1,0,0,0,0.04349647420233192,0,economic problem +Hollinger,g7jac060,17730,17730,183325,1,0,0,0,0.04035864774282543,0,economic problem +Hollinger,g7jac060sc,17730,17730,183325,1,0,0,0,0.04035864774282543,0,economic problem +Hollinger,g7jac080,23670,23670,259648,1,0,0,0,0.03703210435580416,0,economic problem +Hollinger,g7jac080sc,23670,23670,259648,1,0,0,0,0.03703210435580416,0,economic problem +Hollinger,g7jac100,29610,29610,335972,1,0,0,0,0.03529318979455026,0,economic problem +Hollinger,g7jac100sc,29610,29610,335972,1,0,0,0,0.03529318979455026,0,economic problem +Hollinger,g7jac120,35550,35550,412306,1,0,0,0,0.0342243022108217,0,economic problem +Hollinger,g7jac120sc,35550,35550,412306,1,0,0,0,0.0342243022108217,0,economic problem +Hollinger,g7jac140,41490,41490,488633,1,0,0,0,0.03350074170680273,0,economic problem +Hollinger,g7jac140sc,41490,41490,488633,1,0,0,0,0.03350074170680273,0,economic problem +Hollinger,g7jac160,47430,47430,564952,1,0,0,0,0.03297843351620031,0,economic problem +Hollinger,g7jac160sc,47430,47430,564952,1,0,0,0,0.03297843351620031,0,economic problem +Hollinger,g7jac180,53370,53370,641290,1,0,0,0,0.03258366406977314,0,economic problem +Hollinger,g7jac180sc,53370,53370,641290,1,0,0,0,0.03258366406977314,0,economic problem +Hollinger,g7jac200,59310,59310,717620,1,0,0,0,0.03227480202305086,0,economic problem +Hollinger,g7jac200sc,59310,59310,717620,1,0,0,0,0.03227480202305086,0,economic problem +Hollinger,jan99jac020,6774,6774,33744,1,0,0,0,0.003759634062284604,0,economic problem +Hollinger,jan99jac020sc,6774,6774,33744,1,0,0,0,0.003759634062284604,0,economic problem +Hollinger,jan99jac040,13694,13694,72734,1,0,0,0,0.003470816220281136,0,economic problem +Hollinger,jan99jac040sc,13694,13694,72734,1,0,0,0,0.003470816220281136,0,economic problem +Hollinger,jan99jac060,20614,20614,111903,1,0,0,0,0.003378124765408002,0,economic problem +Hollinger,jan99jac060sc,20614,20614,111903,1,0,0,0,0.003378124765408002,0,economic problem +Hollinger,jan99jac080,27534,27534,151063,1,0,0,0,0.003333611134261188,0,economic problem +Hollinger,jan99jac080sc,27534,27534,151063,1,0,0,0,0.003333611134261188,0,economic problem +Hollinger,jan99jac100,34454,34454,190224,1,0,0,0,0.003307461633445052,0,economic problem +Hollinger,jan99jac100sc,34454,34454,190224,1,0,0,0,0.003307461633445052,0,economic problem +Hollinger,jan99jac120,41374,41374,229385,1,0,0,0,0.003290255360374358,0,economic problem +Hollinger,jan99jac120sc,41374,41374,229385,1,0,0,0,0.003290255360374358,0,economic problem +Hollinger,mark3jac020,9129,9129,52883,1,0,0,0,0.07363006419249245,0.01351166293878669,economic problem +Hollinger,mark3jac020sc,9129,9129,52883,1,0,0,0,0.07363006419249245,0.007349249098461679,economic problem +Hollinger,mark3jac040,18289,18289,106803,1,0,0,0,0.07382338721543732,0.01389985784236298,economic problem +Hollinger,mark3jac040sc,18289,18289,106803,1,0,0,0,0.07382338721543732,0.01173364623056615,economic problem +Hollinger,mark3jac060,27449,27449,160723,1,0,0,0,0.07388687991287715,0.01402730528871371,economic problem +Hollinger,mark3jac060sc,27449,27449,160723,1,0,0,0,0.07388687991287715,0.0121839735039789,economic problem +Hollinger,mark3jac080,36609,36609,214643,1,0,0,0,0.07391845139171971,0.01409066941898426,economic problem +Hollinger,mark3jac080sc,36609,36609,214643,1,0,0,0,0.07391845139171971,0.0125985842018466,economic problem +Hollinger,mark3jac100,45769,45769,268563,1,0,0,0,0.07393733869014309,0.01412857360574466,economic problem +Hollinger,mark3jac100sc,45769,45769,268563,1,0,0,0,0.07393733869014309,0.01261351717213372,economic problem +Hollinger,mark3jac120,54929,54929,322483,1,0,0,0,0.07394990714529154,0.01415379562098285,economic problem +Hollinger,mark3jac120sc,54929,54929,322483,1,0,0,0,0.07394990714529154,0.01276529035436745,economic problem +Hollinger,mark3jac140,64089,64089,376395,1,0,0,0,0.07395887333678935,0.01417215070061332,economic problem +Hollinger,mark3jac140sc,64089,64089,376395,1,0,0,0,0.07395887333678935,0.0128291219789848,economic problem +LPnetlib,lp_25fv47,821,1876,10705,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_80bau3b,2262,12061,23264,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_adlittle,56,138,424,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_afiro,27,51,102,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_agg,488,615,2862,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_agg2,516,758,4740,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_agg3,516,758,4756,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_bandm,305,472,2494,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_beaconfd,173,295,3408,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_blend,74,114,522,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_bnl1,643,1586,5532,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_bnl2,2324,4486,14996,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_bore3d,233,334,1448,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_brandy,220,303,2202,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_capri,271,482,1896,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_cre_a,3516,7248,18168,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_cre_b,9648,77137,260785,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_cre_c,3068,6411,15977,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_cre_d,8926,73948,246614,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_cycle,1903,3371,21234,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_czprob,929,3562,10708,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_d2q06c,2171,5831,33081,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_d6cube,415,6184,37704,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_degen2,444,757,4201,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_degen3,1503,2604,25432,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_dfl001,6071,12230,35632,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_e226,223,472,2768,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_etamacro,400,816,2537,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_fffff800,524,1028,6401,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_finnis,497,1064,2760,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_fit1d,24,1049,13427,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_fit1p,627,1677,9868,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_fit2d,25,10524,129042,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_fit2p,3000,13525,50284,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ganges,1309,1706,6937,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_gfrd_pnc,616,1160,2445,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_greenbea,2392,5598,31070,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_greenbeb,2392,5598,31070,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_grow15,300,645,5620,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_grow22,440,946,8252,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_grow7,140,301,2612,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_israel,174,316,2443,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_kb2,43,68,313,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ken_07,2426,3602,8404,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ken_11,14694,21349,49058,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ken_13,28632,42659,97246,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ken_18,105127,154699,358171,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_lotfi,153,366,1136,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_maros,846,1966,10137,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_maros_r7,3136,9408,144848,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_modszk1,687,1620,3168,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_osa_07,1118,25067,144812,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_osa_14,2337,54797,317097,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_osa_30,4350,104374,604488,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_osa_60,10280,243246,1408073,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pds_02,2953,7716,16571,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pds_06,9881,29351,63220,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pds_10,16558,49932,107605,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pds_20,33874,108175,232647,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_perold,625,1506,6148,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilot,1441,4860,44375,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilot4,410,1123,5264,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilot87,2030,6680,74949,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilot_ja,940,2267,14977,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilot_we,722,2928,9265,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_pilotnov,975,2446,13331,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_qap12,3192,8856,38304,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_qap15,6330,22275,94950,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_qap8,912,1632,7296,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_recipe,91,204,687,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sc105,105,163,340,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sc205,205,317,665,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sc50a,50,78,160,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sc50b,50,78,148,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scagr25,471,671,1725,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scagr7,129,185,465,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scfxm1,330,600,2732,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scfxm2,660,1200,5469,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scfxm3,990,1800,8206,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scorpion,388,466,1534,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scrs8,490,1275,3288,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scsd1,77,760,2388,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scsd6,147,1350,4316,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_scsd8,397,2750,8584,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sctap1,300,660,1872,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sctap2,1090,2500,7334,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sctap3,1480,3340,9734,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_share1b,117,253,1179,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_share2b,96,162,777,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_shell,536,1777,3558,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship04l,402,2166,6380,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship04s,402,1506,4400,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship08l,778,4363,12882,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship08s,778,2467,7194,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship12l,1151,5533,16276,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_ship12s,1151,2869,8284,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_sierra,1227,2735,8001,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_stair,356,614,4003,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_standata,359,1274,3230,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_standgub,361,1383,3338,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_standmps,467,1274,3878,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_stocfor1,117,165,501,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_stocfor2,2157,3045,9357,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_stocfor3,16675,23541,72721,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_truss,1000,8806,27836,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_tuff,333,628,4561,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_vtp_base,198,346,1051,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_wood1p,244,2595,70216,1,0,0,0,0,0,linear programming problem +LPnetlib,lp_woodw,1098,8418,37487,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_bgdbg1,348,629,1662,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_bgetam,400,816,2537,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_bgindy,2671,10880,66266,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_bgprtr,20,40,70,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_box1,231,261,651,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_ceria3d,3576,4400,21178,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_chemcom,288,744,1590,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_cplex1,3005,5224,10947,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_cplex2,224,378,1215,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_ex72a,197,215,467,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_ex73a,193,211,457,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_forest6,66,131,246,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_galenet,8,14,22,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_gosh,3792,13455,99953,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_gran,2658,2525,20111,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_greenbea,2393,5596,31074,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_itest2,9,13,26,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_itest6,11,17,29,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_klein1,54,108,750,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_klein2,477,531,5062,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_klein3,994,1082,13101,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_mondou2,312,604,1208,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_pang,361,741,2933,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_pilot4i,410,1123,5264,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_qual,323,464,1646,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_reactor,318,808,2591,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_refinery,323,464,1626,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_vol1,323,464,1646,1,0,0,0,0,0,linear programming problem +LPnetlib,lpi_woodinfe,35,89,140,1,0,0,0,0,0,linear programming problem +Li,li,22695,22695,1215181,1,0,1,0,1,0.8685670104303111,electromagnetics problem +Li,pli,22695,22695,1350309,1,1,1,0,1,1,duplicate electromagnetics problem +Mallya,lhr01,1477,1477,18427,1,0,0,0,0.007324823611784348,0,chemical process simulation problem +Mallya,lhr02,2954,2954,36875,1,0,0,0,0.007320486597050275,0,chemical process simulation problem +Mallya,lhr04,4101,4101,81057,1,0,0,0,0.01515885315769082,0,chemical process simulation problem +Mallya,lhr04c,4101,4101,82682,1,0,0,0,0.01515885315769082,0,chemical process simulation problem +Mallya,lhr07,7337,7337,154660,1,0,0,0,0.0173680609288971,0,chemical process simulation problem +Mallya,lhr07c,7337,7337,156508,1,0,0,0,0.0173680609288971,0,chemical process simulation problem +Mallya,lhr10,10672,10672,228395,1,0,0,0,0.008791586915847653,1.752395305332977e-05,chemical process simulation problem +Mallya,lhr10c,10672,10672,232633,1,0,0,0,0.008791586915847653,1.720467106819501e-05,chemical process simulation problem +Mallya,lhr11,10964,10964,231806,1,0,0,0,0.008200580375103791,3.452591601570929e-05,chemical process simulation problem +Mallya,lhr11c,10964,10964,233741,1,0,0,0,0.008200580375103791,4.280052387841227e-05,chemical process simulation problem +Mallya,lhr14,14270,14270,305750,1,0,0,0,0.006622946983926842,0,chemical process simulation problem +Mallya,lhr14c,14270,14270,307858,1,0,0,0,0.006622946983926842,0,chemical process simulation problem +Mallya,lhr17,17576,17576,379761,1,0,0,0,0.001513390098553639,0.0001527473453564807,chemical process simulation problem +Mallya,lhr17c,17576,17576,381975,1,0,0,0,0.001513390098553639,5.236643939631969e-06,chemical process simulation problem +Mallya,lhr34,35152,35152,746972,1,0,0,0,0.00151326330781556,0.0001553140154832006,chemical process simulation problem +Mallya,lhr34c,35152,35152,764014,1,0,0,0,0.00151326330781556,5.236205217354879e-06,chemical process simulation problem +Mallya,lhr71,70304,70304,1494006,1,0,0,0,0.001513199920413014,0.0001553075692357127,chemical process simulation problem +Mallya,lhr71c,70304,70304,1528092,1,0,0,0,0.001513199920413014,5.235985883782057e-06,chemical process simulation problem +Mulvey,finan512,74752,74752,596992,1,0,0,1,1,1,economic problem +Mulvey,pfinan512,74752,74752,596992,1,1,0,0,1,1,duplicate economic problem +Nasa,barth,6691,6691,26439,1,1,1,0,0,0,duplicate structural problem +Nasa,barth4,6019,6019,23492,1,1,1,0,0,0,duplicate structural problem +Nasa,barth5,15606,15606,61484,1,1,1,0,0,0,duplicate structural problem +Nasa,nasa1824,1824,1824,39208,1,0,1,1,1,1,structural problem +Nasa,nasa2146,2146,2146,72250,1,0,1,1,1,1,structural problem +Nasa,nasa2910,2910,2910,174296,1,0,1,1,1,1,structural problem +Nasa,nasa4704,4704,4704,104756,1,0,1,1,1,1,structural problem +Nasa,nasasrb,54870,54870,2677324,1,0,1,1,1,1,structural problem +Nasa,pwt,36519,36519,326107,1,1,1,0,1,1,duplicate structural problem +Nasa,shuttle_eddy,10429,10429,103599,1,1,1,0,1,1,duplicate structural problem +Nasa,skirt,12598,12598,196520,1,1,1,0,1,1,duplicate structural problem +Nemeth,nemeth01,9506,9506,725054,1,0,0,0,1,1,theoretical/quantum chemistry problem sequence +Nemeth,nemeth02,9506,9506,394808,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth03,9506,9506,394808,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth04,9506,9506,394808,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth05,9506,9506,394808,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth06,9506,9506,394808,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth07,9506,9506,394812,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth08,9506,9506,394816,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth09,9506,9506,395506,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth10,9506,9506,401448,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth11,9506,9506,408264,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth12,9506,9506,446818,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth13,9506,9506,474472,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth14,9506,9506,496144,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth15,9506,9506,539802,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth16,9506,9506,587012,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth17,9506,9506,629620,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth18,9506,9506,695234,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth19,9506,9506,818302,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth20,9506,9506,971870,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth21,9506,9506,1173746,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth22,9506,9506,1358832,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth23,9506,9506,1506810,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth24,9506,9506,1506550,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth25,9506,9506,1511758,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Nemeth,nemeth26,9506,9506,1511760,1,0,0,0,1,1,subsequent theoretical/quantum chemistry problem +Okunbor,aft01,8205,8205,125567,1,0,1,1,1,1,acoustics problem +Okunbor,aft02,8184,8184,127762,0,0,1,0,1,0.9963538443526401,acoustics problem +Qaplib,lp_nug05,210,225,1050,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug06,372,486,2232,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug07,602,931,4214,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug08,912,1632,7296,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug12,3192,8856,38304,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug15,6330,22275,94950,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug20,15240,72600,304800,1,0,0,0,0,0,linear programming problem +Qaplib,lp_nug30,52260,379350,1567800,1,0,0,0,0,0,linear programming problem +Ronis,xenon1,48600,48600,1181120,1,0,1,0,1,0.775813230671423,materials problem +Ronis,xenon2,157464,157464,3866688,1,0,1,0,1,0.7756792256277864,materials problem +Rothberg,3dtube,45330,45330,3213618,1,1,1,0,1,1,computational fluid dynamics problem +Rothberg,cfd1,70656,70656,1825580,1,0,1,1,1,1,computational fluid dynamics problem +Rothberg,cfd2,123440,123440,3085406,1,0,1,1,1,1,computational fluid dynamics problem +Rothberg,gearbox,153746,153746,9080404,1,1,1,0,1,1,structural problem +Rothberg,struct3,53570,53570,1173694,1,1,1,0,1,1,structural problem +Rothberg,struct4,4350,4350,237798,1,1,1,0,1,1,structural problem +Shyy,shyy161,76480,76480,329762,1,0,1,0,0.7263358696509635,0.1824427535660244,computational fluid dynamics problem +Shyy,shyy41,4720,4720,20042,1,0,1,0,0.7234369459874719,0.1843753693416854,computational fluid dynamics problem +Simon,appu,14000,14000,1853104,1,0,0,0,1,0.9429754924136972,directed weighted random graph +Simon,bbmat,38744,38744,1771722,1,0,1,0,0.5295358625441292,0.0005851199495896658,computational fluid dynamics problem +Simon,olafu,16146,16146,1015156,1,0,1,1,1,1,structural problem +Simon,raefsky1,3242,3242,293409,1,0,1,0,1,0.09040311269027836,computational fluid dynamics problem sequence +Simon,raefsky2,3242,3242,293551,1,0,1,0,1,0.09753745147411895,subsequent computational fluid dynamics problem +Simon,raefsky3,21200,21200,1488768,1,0,1,0,1,0.4763745189320018,computational fluid dynamics problem +Simon,raefsky4,19779,19779,1316789,1,0,1,1,1,1,structural problem +Simon,raefsky5,6316,6316,167178,1,0,1,0,0,0,structural problem +Simon,raefsky6,3402,3402,130371,1,0,1,0,0,0,structural problem +Simon,venkat01,62424,62424,1717792,1,0,1,0,1,0.05542936676316082,computational fluid dynamics problem sequence +Simon,venkat25,62424,62424,1717763,1,0,1,0,1,0.05539650790563141,subsequent computational fluid dynamics problem +Simon,venkat50,62424,62424,1717777,1,0,1,0,1,0.05539603939461855,subsequent computational fluid dynamics problem +TOKAMAK,utm1700b,1700,1700,21509,1,0,1,0,0.5232974910394266,0,electromagnetics problem +TOKAMAK,utm300,300,300,3155,1,0,1,0,0.4651488616462347,0,electromagnetics problem +TOKAMAK,utm3060,3060,3060,42211,1,0,1,0,0.524686470332814,0,electromagnetics problem +TOKAMAK,utm5940,5940,5940,83842,1,0,1,0,0.5290493183743677,0,electromagnetics problem +Vavasis,av41092,41092,41092,1683902,1,0,1,0,0.0009359570219938022,0,2D/3D problem +Wang,swang1,3169,3169,20841,1,0,1,0,1,0,semiconductor device problem sequence +Wang,swang2,3169,3169,20841,1,0,1,0,1,0,subsequent semiconductor device problem +Wang,wang1,2903,2903,19093,1,0,1,0,1,0.808153180975911,semiconductor device problem sequence +Wang,wang2,2903,2903,19093,1,0,1,0,1,0.808153180975911,subsequent semiconductor device problem +Wang,wang3,26064,26064,177168,1,0,1,0,1,0.9780019059720457,semiconductor device problem +Wang,wang4,26068,26068,177196,1,0,1,0,1,0.04647715843523371,semiconductor device problem +Zhao,Zhao1,33861,33861,166453,1,0,1,0,0.9224990949680222,0,electromagnetics problem +Zhao,Zhao2,33861,33861,166453,1,0,1,0,0.9224990949680222,0,electromagnetics problem +Zitney,extr1,2837,2837,10967,1,0,0,0,0.004209049456331112,0.000364797081623347,chemical process simulation problem +Zitney,hydr1,5308,5308,22680,1,0,0,0,0.004126315789473685,0.0006173383896287151,chemical process simulation problem +Zitney,radfr1,1048,1048,13299,1,0,0,0,0.05374309287714783,0,chemical process simulation problem +Zitney,rdist1,4134,4134,94408,1,0,0,0,0.05878038669628716,0,chemical process simulation problem +Zitney,rdist2,3198,3198,56834,1,0,0,0,0.04562603575332323,0,chemical process simulation problem +Zitney,rdist3a,2398,2398,61896,1,0,0,0,0.1404154186743065,0,chemical process simulation problem +Cunningham,k3plates,11107,11107,378927,1,0,1,0,1,0.999260507857104,acoustics problem +Cunningham,m3plates,11107,11107,6639,1,0,1,0,1,1,acoustics problem +Cunningham,qa8fk,66127,66127,1660579,1,0,1,0,1,1,acoustics problem +Cunningham,qa8fm,66127,66127,1660579,1,0,1,1,1,1,acoustics problem +Boeing,bcsstk39,46772,46772,2060662,1,0,1,0,1,1,structural problem +Chen,pkustk01,22044,22044,979380,1,1,1,0,1,1,structural problem +Chen,pkustk02,10800,10800,810000,1,1,1,0,1,1,structural problem +Chen,pkustk03,63336,63336,3130416,1,1,1,0,1,1,structural problem +Chen,pkustk04,55590,55590,4218660,1,1,1,0,1,1,structural problem +Chen,pkustk05,37164,37164,2205144,1,1,1,0,1,1,structural problem +Chen,pkustk06,43164,43164,2571768,1,1,1,0,1,1,structural problem +Chen,pkustk07,16860,16860,2418804,1,1,1,0,1,1,structural problem +Chen,pkustk08,22209,22209,3226671,1,1,1,0,1,1,structural problem +Chen,pkustk09,33960,33960,1583640,1,1,1,0,1,1,structural problem +Chen,pkustk10,80676,80676,4308984,1,1,1,0,1,1,structural problem +Chen,pkustk11,87804,87804,5217912,1,1,1,0,1,1,structural problem +Chen,pkustk12,94653,94653,7512317,1,1,1,0,1,1,structural problem +Chen,pkustk13,94893,94893,6616827,1,1,1,0,1,1,structural problem +Chen,pkustk14,151926,151926,14836504,1,1,1,0,1,1,structural problem +MathWorks,pivtol,102,102,306,1,0,0,0,0.9901960784313726,0,statistical/mathematical problem +Kim,kim1,38415,38415,933195,0,0,1,0,0.9897360244976419,0,2D/3D problem +Kim,kim2,456976,456976,11330020,0,0,1,0,0.9970363405132914,0,2D/3D problem +Langemyr,comsol,1500,1500,97645,1,0,1,0,0.9990327110094128,0.0008944822923708982,structural problem +Pothen,barth,6691,6691,46187,1,1,1,0,1,1,structural problem +Pothen,barth4,6019,6019,40965,1,1,1,0,1,1,structural problem +Pothen,barth5,15606,15606,107362,1,1,1,0,1,1,structural problem +Pothen,bodyy4,17546,17546,121550,1,0,1,1,1,1,structural problem +Pothen,bodyy5,18589,18589,128853,1,0,1,1,1,1,structural problem +Pothen,bodyy6,19366,19366,134208,1,0,1,1,1,1,structural problem +Pothen,commanche_dual,7920,7920,31680,1,1,1,0,1,1,structural problem +Pothen,mesh1e1,48,48,306,1,0,1,1,1,1,structural problem +Pothen,mesh1em1,48,48,306,1,0,1,1,1,1,structural problem +Pothen,mesh1em6,48,48,306,1,0,1,1,1,1,structural problem +Pothen,mesh2e1,306,306,2018,1,0,1,1,1,1,structural problem +Pothen,mesh2em5,306,306,2018,1,0,1,1,1,1,structural problem +Pothen,mesh3e1,289,289,1377,1,0,1,1,1,1,structural problem +Pothen,mesh3em5,289,289,1377,1,0,1,1,1,1,structural problem +Pothen,onera_dual,85567,85567,419201,1,1,1,0,1,1,structural problem +Pothen,pwt,36519,36519,326107,1,1,1,0,1,1,structural problem +Pothen,shuttle_eddy,10429,10429,103599,1,1,1,0,1,1,structural problem +Pothen,skirt,12598,12598,196520,1,1,1,0,1,1,structural problem +Pothen,sphere2,66,66,450,1,1,1,0,1,1,structural problem +Pothen,sphere3,258,258,1794,1,1,1,0,1,1,structural problem +Pothen,tandem_dual,94069,94069,460493,1,1,1,0,1,1,structural problem +Pothen,tandem_vtx,18454,18454,253350,1,1,1,0,1,1,structural problem +Norris,fv1,9604,9604,85264,1,0,1,1,1,1,2D/3D problem +Norris,fv2,9801,9801,87025,1,0,1,1,1,1,2D/3D problem +Norris,fv3,9801,9801,87025,1,0,1,1,1,1,2D/3D problem +Norris,heart1,3557,3557,1385317,1,0,1,0,1,0,2D/3D problem +Norris,heart2,2339,2339,680341,1,0,1,0,1,0,2D/3D problem +Norris,heart3,2339,2339,680341,1,0,1,0,1,0,2D/3D problem +Norris,lung1,1650,1650,7419,1,0,1,0,0.5713295198474606,0,computational fluid dynamics problem +Norris,lung2,109460,109460,492564,1,0,1,0,0.5714270798529903,0,computational fluid dynamics problem +Norris,stomach,213360,213360,3021648,1,0,1,0,0.8474914253808726,0,2D/3D problem +Norris,torso1,116158,116158,8516500,1,0,1,0,0.4243874832715144,0,2D/3D problem +Norris,torso2,115967,115967,1033473,1,0,1,0,0.9916360219987662,0,2D/3D problem +Norris,torso3,259156,259156,4429042,1,0,1,0,0.9513722917125312,0,2D/3D problem +Shen,e40r0100,17281,17281,553562,1,0,1,0,0.3079877899832364,0.001965387548691824,2D/3D problem +Shen,shermanACa,3432,3432,25220,1,0,1,0,0.163759867817147,0.02157150725169818,2D/3D problem +Shen,shermanACb,18510,18510,145149,1,0,1,0,0.1493062958488302,0.02665845434660729,2D/3D problem +Shen,shermanACd,6136,6136,53329,1,0,1,0,0.1520140698832454,0.01665501239590617,2D/3D problem +Pereyra,landmark,71952,2704,1146848,1,0,0,0,0,0,least squares problem +vanHeukelum,cage3,5,5,19,1,0,0,0,1,0,directed weighted graph +vanHeukelum,cage4,9,9,49,1,0,0,0,1,0,directed weighted graph +vanHeukelum,cage5,37,37,233,1,0,0,0,1,0.04081632653061224,directed weighted graph +vanHeukelum,cage6,93,93,785,1,0,0,0,1,0.09248554913294797,directed weighted graph +vanHeukelum,cage7,340,340,3084,1,0,0,0,1,0.1020408163265306,directed weighted graph +vanHeukelum,cage8,1015,1015,11003,1,0,0,0,1,0.144973968762515,directed weighted graph +vanHeukelum,cage9,3534,3534,41594,1,0,0,0,1,0.1535470310036784,directed weighted graph +vanHeukelum,cage10,11397,11397,150645,1,0,0,0,1,0.1743077099850626,directed weighted graph +vanHeukelum,cage11,39082,39082,559722,1,0,0,0,1,0.1821988322065151,directed weighted graph +vanHeukelum,cage12,130228,130228,2032536,1,0,0,0,1,0.1935123018985359,directed weighted graph +vanHeukelum,cage13,445315,445315,7479343,1,0,0,0,1,0.2004785878020389,directed weighted graph +vanHeukelum,cage14,1505785,1505785,27130349,1,0,0,0,1,0.2073316837703073,directed weighted graph +vanHeukelum,cage15,5154859,5154859,99199551,1,0,0,0,1,0.2131193964673732,directed weighted graph +Hohn,fd12,7500,7500,28462,1,0,1,0,0.0002810765230834094,0,materials problem +Hohn,fd15,11532,11532,44206,1,0,1,0,0,0,materials problem +Hohn,fd18,16428,16428,63406,1,0,1,0,3.154275620603729e-05,0,materials problem +Hohn,sinc12,7500,7500,283992,1,0,1,0,0.01755337541442645,0,materials problem +Hohn,sinc15,11532,11532,551184,1,0,1,0,0.01378652867239141,0,materials problem +Hohn,sinc18,16428,16428,948696,1,0,1,0,0.01157085557378834,0,materials problem +Alemdar,Alemdar,6245,6245,42581,1,0,1,0,1,1,2D/3D problem +Andrews,Andrews,60000,60000,760154,1,0,1,1,1,1,computer graphics/vision problem +FEMLAB,ns3Da,20414,20414,1679599,1,0,1,0,0.9999825339398674,0,computational fluid dynamics problem +FEMLAB,poisson2D,367,367,2417,1,0,1,0,1,0,computational fluid dynamics problem +FEMLAB,poisson3Da,13514,13514,352762,1,0,1,0,1,0,computational fluid dynamics problem +FEMLAB,poisson3Db,85623,85623,2374949,1,0,1,0,1,0,computational fluid dynamics problem +FEMLAB,problem1,415,415,2779,1,0,1,0,1,0.6548223350253807,2D/3D problem +FEMLAB,sme3Da,12504,12504,874887,1,0,1,0,0.9999710105602732,0.4370888572710733,structural problem +FEMLAB,sme3Db,29067,29067,2081063,1,0,1,0,0.999978557463075,0.4406373111838425,structural problem +FEMLAB,sme3Dc,42930,42930,3148656,1,0,1,0,0.9999793929020139,0.4391179389295772,structural problem +FEMLAB,waveguide3D,21036,21036,303468,0,0,1,0,1,0,electromagnetics problem +Lucifora,cell1,7055,7055,30082,1,0,0,0,0.9970503597122302,0,directed weighted graph +Lucifora,cell2,7055,7055,30082,1,0,0,0,0.9970503597122302,0.004342728101793546,directed weighted graph +ND,nd3k,9000,9000,3279690,1,0,1,1,1,1,2D/3D problem +ND,nd6k,18000,18000,6897316,1,0,1,1,1,1,2D/3D problem +ND,nd12k,36000,36000,14220946,1,0,1,1,1,1,2D/3D problem +ND,nd24k,72000,72000,28715634,1,0,1,1,1,1,2D/3D problem +Schenk_AFE,af_shell1,504855,504855,17562051,1,0,1,0,1,1,structural problem sequence +Schenk_AFE,af_shell2,504855,504855,17562051,1,0,1,0,1,1,subsequent structural problem +Schenk_AFE,af_shell3,504855,504855,17562051,1,0,1,1,1,1,subsequent structural problem +Schenk_AFE,af_shell4,504855,504855,17562051,1,0,1,1,1,1,subsequent structural problem +Schenk_AFE,af_shell5,504855,504855,17579155,1,0,1,0,1,1,subsequent structural problem +Schenk_AFE,af_shell6,504855,504855,17579155,1,0,1,0,1,1,subsequent structural problem +Schenk_AFE,af_shell7,504855,504855,17579155,1,0,1,1,1,1,subsequent structural problem +Schenk_AFE,af_shell8,504855,504855,17579155,1,0,1,1,1,1,subsequent structural problem +Schenk_AFE,af_shell9,504855,504855,17588845,1,0,1,0,1,1,subsequent structural problem +Schenk_IBMNA,c-62,41731,41731,559341,1,0,0,0,1,1,optimization problem sequence +Schenk_IBMNA,c-64,51035,51035,707985,1,0,0,0,1,1,optimization problem sequence +Schenk_IBMNA,c-66,49989,49989,444853,1,0,0,0,1,1,optimization problem sequence +Schenk_IBMNA,c-67,57975,57975,530229,1,0,0,0,1,1,optimization problem sequence +Schenk_IBMNA,c-73,169422,169422,1279274,1,0,0,0,1,1,optimization problem sequence +Schenk_IBMSDS,2D_27628_bjtcai,27628,27628,206670,1,0,1,0,0.9995761793531919,0.2185967538342959,semiconductor device problem +Schenk_IBMSDS,2D_54019_highK,54019,54019,486129,1,0,1,0,0.9980889117620531,0.189734095484946,semiconductor device problem +Schenk_IBMSDS,3D_28984_Tetra,28984,28984,285092,1,0,1,0,0.9874041102377119,0.3613007012666531,semiconductor device problem +Schenk_IBMSDS,3D_51448_3D,51448,51448,537038,1,0,1,0,0.9920908271502504,0.1870343293725159,semiconductor device problem +Schenk_IBMSDS,ibm_matrix_2,51448,51448,537038,1,0,1,0,0.9920908271502504,0.185666920653226,semiconductor device problem +Schenk_IBMSDS,matrix_9,103430,103430,1205518,1,0,1,0,0.9966503478484926,0.1744833443427385,semiconductor device problem +Schenk_IBMSDS,matrix-new_3,125329,125329,893984,1,0,1,0,0.9871118002084263,0.2826079320371298,semiconductor device problem +Schenk_ISEI,barrier2-10,115625,115625,2158759,1,0,1,0,1,0.1989334147759642,subsequent semiconductor device problem +Schenk_ISEI,barrier2-11,115625,115625,2158759,1,0,1,0,1,0.1988805553760946,subsequent semiconductor device problem +Schenk_ISEI,barrier2-12,115625,115625,2158759,1,0,1,0,1,0.1983617501551521,subsequent semiconductor device problem +Schenk_ISEI,barrier2-1,113076,113076,2129496,1,0,1,0,1,0.1972208170916773,semiconductor device problem sequence +Schenk_ISEI,barrier2-2,113076,113076,2129496,1,0,1,0,1,0.1971642812509299,subsequent semiconductor device problem +Schenk_ISEI,barrier2-3,113076,113076,2129496,1,0,1,0,1,0.1980361234266671,subsequent semiconductor device problem +Schenk_ISEI,barrier2-4,113076,113076,2129496,1,0,1,0,1,0.189249263546285,subsequent semiconductor device problem +Schenk_ISEI,barrier2-9,115625,115625,2158759,1,0,1,0,1,0.2036036406422221,semiconductor device problem sequence +Schenk_ISEI,igbt3,10938,10938,130500,1,0,1,0,1,0.1720279018417223,semiconductor device problem +Schenk_ISEI,nmos3,18588,18588,237130,1,0,1,0,1,0.1670891636390259,semiconductor device problem +Schenk_ISEI,ohne2,181343,181343,6869939,1,0,1,0,1,0.09493801090692276,semiconductor device problem +Schenk_ISEI,para-10,155924,155924,2094873,1,0,1,0,1,0.1980866954210761,subsequent semiconductor device problem +Schenk_ISEI,para-4,153226,153226,2930882,1,0,1,0,1,0.2900222345747638,semiconductor device problem +Schenk_ISEI,para-5,155924,155924,2094873,1,0,1,0,1,0.3692588097985042,semiconductor device problem sequence +Schenk_ISEI,para-6,155924,155924,2094873,1,0,1,0,1,0.3692588097985042,subsequent semiconductor device problem +Schenk_ISEI,para-7,155924,155924,2094873,1,0,1,0,1,0.3692588097985042,subsequent semiconductor device problem +Schenk_ISEI,para-8,155924,155924,2094873,1,0,1,0,1,0.1779654854253516,subsequent semiconductor device problem +Schenk_ISEI,para-9,155924,155924,2094873,1,0,1,0,1,0.1810599453621524,subsequent semiconductor device problem +Kamvar,Stanford,281903,281903,2312497,1,1,0,0,0.2766368994208425,0.2766368994208425,directed graph +Kamvar,Stanford_Berkeley,683446,683446,7583376,1,1,0,0,0.2502051856587356,0.2502051856587356,directed graph +Sumner,graphics,29493,11822,117954,1,0,1,0,0,0,computer graphics/vision problem +Tromble,language,399130,399130,1216334,1,0,0,0,0.05790231080611451,0,directed weighted graph +Sanghavi,ecl32,51993,51993,380415,1,0,1,0,0.9219175329301935,0.6030290297239527,semiconductor device problem +Sandia,adder_dcop_01,1813,1813,11156,1,0,0,0,0.6544094067343666,0.01582041688936398,subsequent circuit simulation problem +Sandia,adder_dcop_02,1813,1813,11246,1,0,0,0,0.6481736368448915,0.02604552673372154,subsequent circuit simulation problem +Sandia,adder_dcop_03,1813,1813,11148,1,0,0,0,0.6429870546699475,0.03509147319995721,subsequent circuit simulation problem +Sandia,adder_dcop_04,1813,1813,11107,1,0,0,0,0.6505480335267569,0.003868471953578337,subsequent circuit simulation problem +Sandia,adder_dcop_05,1813,1813,11097,1,0,0,0,0.6473752151462995,0.01333907056798623,subsequent circuit simulation problem +Sandia,adder_dcop_06,1813,1813,11224,1,0,0,0,0.6486257030669638,0.01464501751034702,subsequent circuit simulation problem +Sandia,adder_dcop_07,1813,1813,11226,1,0,0,0,0.6484880636604774,0.005941644562334218,subsequent circuit simulation problem +Sandia,adder_dcop_08,1813,1813,11242,1,0,0,0,0.6478127317021501,0.005296049147336087,subsequent circuit simulation problem +Sandia,adder_dcop_09,1813,1813,11239,1,0,0,0,0.6484424666242848,0.006145369781733418,subsequent circuit simulation problem +Sandia,adder_dcop_10,1813,1813,11232,1,0,0,0,0.6478634291167427,0.00572579790054077,subsequent circuit simulation problem +Sandia,adder_dcop_11,1813,1813,11243,1,0,0,0,0.6481677610675705,0.00487184918449481,subsequent circuit simulation problem +Sandia,adder_dcop_12,1813,1813,11246,1,0,0,0,0.6481736368448915,0.004446797247220751,subsequent circuit simulation problem +Sandia,adder_dcop_13,1813,1813,11245,1,0,0,0,0.6482422702244811,0.002753070732740364,subsequent circuit simulation problem +Sandia,adder_dcop_14,1813,1813,11246,1,0,0,0,0.6481736368448915,0.008258337744838539,subsequent circuit simulation problem +Sandia,adder_dcop_15,1813,1813,11246,1,0,0,0,0.6481736368448915,0.005929062996294336,subsequent circuit simulation problem +Sandia,adder_dcop_16,1813,1813,11246,1,0,0,0,0.6481736368448915,0.008258337744838539,subsequent circuit simulation problem +Sandia,adder_dcop_17,1813,1813,11246,1,0,0,0,0.6481736368448915,0.009105346744309158,subsequent circuit simulation problem +Sandia,adder_dcop_18,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_19,1813,1813,11245,1,0,0,0,0.6482422702244811,0.007623888182973317,subsequent circuit simulation problem +Sandia,adder_dcop_20,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_21,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_22,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_23,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_24,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_25,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_26,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_27,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_28,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_29,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_30,1813,1813,11246,1,0,0,0,0.6481736368448915,0.008046585494970884,subsequent circuit simulation problem +Sandia,adder_dcop_31,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_32,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_33,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_34,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_35,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_36,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_37,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_38,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_39,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_40,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_41,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_42,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_43,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_44,1813,1813,11245,1,0,0,0,0.6482422702244811,0.007623888182973317,subsequent circuit simulation problem +Sandia,adder_dcop_45,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_46,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_47,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_48,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_49,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_50,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_51,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_52,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_53,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007411328745367919,subsequent circuit simulation problem +Sandia,adder_dcop_54,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_55,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_56,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007623080995235574,subsequent circuit simulation problem +Sandia,adder_dcop_57,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_58,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_59,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_60,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_61,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_62,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_63,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_64,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_65,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_66,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_67,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_68,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_dcop_69,1813,1813,11246,1,0,0,0,0.6481736368448915,0.007834833245103229,subsequent circuit simulation problem +Sandia,adder_trans_01,1814,1814,14579,1,0,0,0,1,0.03115703773289494,circuit simulation problem sequence +Sandia,adder_trans_02,1814,1814,14579,1,0,0,0,1,0.03115703773289494,subsequent circuit simulation problem +Sandia,fpga_dcop_01,1220,1220,5892,1,0,0,0,0.8183347350714887,0.2733389402859546,circuit simulation problem sequence +Sandia,fpga_dcop_02,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3271656854499579,subsequent circuit simulation problem +Sandia,fpga_dcop_03,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3448275862068966,subsequent circuit simulation problem +Sandia,fpga_dcop_04,1220,1220,5884,1,0,0,0,0.818871103622578,0.3546756529064869,subsequent circuit simulation problem +Sandia,fpga_dcop_05,1220,1220,5852,1,0,0,0,0.8210347752332485,0.359626802374894,subsequent circuit simulation problem +Sandia,fpga_dcop_06,1220,1220,5860,1,0,0,0,0.8204911092294666,0.3539373412362405,subsequent circuit simulation problem +Sandia,fpga_dcop_07,1220,1220,5855,1,0,0,0,0.8205128205128205,0.3432930705657978,subsequent circuit simulation problem +Sandia,fpga_dcop_08,1220,1220,5888,1,0,0,0,0.8186026936026936,0.3425925925925926,subsequent circuit simulation problem +Sandia,fpga_dcop_09,1220,1220,5888,1,0,0,0,0.8186026936026936,0.3337542087542087,subsequent circuit simulation problem +Sandia,fpga_dcop_10,1220,1220,5884,1,0,0,0,0.818871103622578,0.3323504633529907,subsequent circuit simulation problem +Sandia,fpga_dcop_11,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3301093355761144,subsequent circuit simulation problem +Sandia,fpga_dcop_12,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3216989066442388,subsequent circuit simulation problem +Sandia,fpga_dcop_13,1220,1220,5892,1,0,0,0,0.8183347350714887,0.325063078216989,subsequent circuit simulation problem +Sandia,fpga_dcop_14,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3187552565180824,subsequent circuit simulation problem +Sandia,fpga_dcop_15,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3221194280908327,subsequent circuit simulation problem +Sandia,fpga_dcop_16,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3221194280908327,subsequent circuit simulation problem +Sandia,fpga_dcop_17,1220,1220,5892,1,0,0,0,0.8183347350714887,0.31959629941127,subsequent circuit simulation problem +Sandia,fpga_dcop_18,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3191757779646762,subsequent circuit simulation problem +Sandia,fpga_dcop_19,1220,1220,5892,1,0,0,0,0.8183347350714887,0.31959629941127,subsequent circuit simulation problem +Sandia,fpga_dcop_20,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3212783851976451,subsequent circuit simulation problem +Sandia,fpga_dcop_21,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3216989066442388,subsequent circuit simulation problem +Sandia,fpga_dcop_22,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3263246425567704,subsequent circuit simulation problem +Sandia,fpga_dcop_23,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3216989066442388,subsequent circuit simulation problem +Sandia,fpga_dcop_24,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3254835996635829,subsequent circuit simulation problem +Sandia,fpga_dcop_25,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3259041211101766,subsequent circuit simulation problem +Sandia,fpga_dcop_26,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3254835996635829,subsequent circuit simulation problem +Sandia,fpga_dcop_27,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3271656854499579,subsequent circuit simulation problem +Sandia,fpga_dcop_28,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3284272497897393,subsequent circuit simulation problem +Sandia,fpga_dcop_29,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3280067283431455,subsequent circuit simulation problem +Sandia,fpga_dcop_30,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3292682926829268,subsequent circuit simulation problem +Sandia,fpga_dcop_31,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3284272497897393,subsequent circuit simulation problem +Sandia,fpga_dcop_32,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3280067283431455,subsequent circuit simulation problem +Sandia,fpga_dcop_33,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3280067283431455,subsequent circuit simulation problem +Sandia,fpga_dcop_34,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3275862068965517,subsequent circuit simulation problem +Sandia,fpga_dcop_35,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3288477712363331,subsequent circuit simulation problem +Sandia,fpga_dcop_36,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3288477712363331,subsequent circuit simulation problem +Sandia,fpga_dcop_37,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3296888141295206,subsequent circuit simulation problem +Sandia,fpga_dcop_38,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3296888141295206,subsequent circuit simulation problem +Sandia,fpga_dcop_39,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3296888141295206,subsequent circuit simulation problem +Sandia,fpga_dcop_40,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3313708999158957,subsequent circuit simulation problem +Sandia,fpga_dcop_41,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3301093355761144,subsequent circuit simulation problem +Sandia,fpga_dcop_42,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3313708999158957,subsequent circuit simulation problem +Sandia,fpga_dcop_43,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_44,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3322119428090833,subsequent circuit simulation problem +Sandia,fpga_dcop_45,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3322119428090833,subsequent circuit simulation problem +Sandia,fpga_dcop_46,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_47,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_48,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_49,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_50,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3317914213624895,subsequent circuit simulation problem +Sandia,fpga_dcop_51,1220,1220,5892,1,0,0,0,0.8183347350714887,0.3322119428090833,subsequent circuit simulation problem +Sandia,fpga_trans_01,1220,1220,7382,1,0,0,0,1,0.214193962748876,circuit simulation problem sequence +Sandia,fpga_trans_02,1220,1220,7382,1,0,0,0,1,0.2138728323699422,subsequent circuit simulation problem +Sandia,init_adder1,1813,1813,11156,1,0,0,0,0.6544094067343666,0.01582041688936398,circuit simulation problem sequence +Sandia,mult_dcop_01,25187,25187,193276,1,0,0,0,0.6144759258929472,0.003383612629779353,circuit simulation problem sequence +Sandia,mult_dcop_02,25187,25187,193276,1,0,0,0,0.6144759258929472,0.003383612629779353,subsequent circuit simulation problem +Sandia,mult_dcop_03,25187,25187,193216,1,0,0,0,0.6142197994049846,0.01294544504421048,subsequent circuit simulation problem +Sandia,oscil_dcop_01,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,circuit simulation problem sequence +Sandia,oscil_dcop_02,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_03,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_04,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_05,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_06,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_07,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_08,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_09,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_10,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_11,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_12,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_13,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_14,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_15,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_16,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_17,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_18,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_19,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_20,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_21,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_22,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_23,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_24,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_25,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_26,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_27,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_28,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_29,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_30,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_31,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_32,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_33,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_34,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_35,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_36,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_37,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_38,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_39,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_40,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_41,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_42,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_43,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_44,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_45,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_46,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_47,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_48,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_49,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_50,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_51,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_52,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_53,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_54,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_55,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_56,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_dcop_57,430,430,1544,1,0,0,0,0.9762308998302207,0.6977928692699491,subsequent circuit simulation problem +Sandia,oscil_trans_01,430,430,1614,1,0,0,0,0.9737274220032841,0.7175697865353038,circuit simulation problem +MathWorks,Pd,8081,8081,13036,1,0,0,0,0,0,counter-example problem +MathWorks,Pd_rhs,8081,12406,6323,1,0,0,0,0,0,counter-example problem +MathWorks,Harvard500,500,500,2636,1,1,0,0,0.4057744830277019,0.4057744830277019,directed graph +HB,cegb2802,2802,2802,277362,1,1,1,0,1,1,structural problem +HB,cegb2919,2919,2919,321543,1,1,1,0,1,1,structural problem +HB,cegb3024,3024,3024,79848,1,1,1,0,1,1,structural problem +HB,cegb3306,3306,3306,74916,1,1,1,0,1,1,structural problem +HB,lap_25,25,25,169,1,1,1,0,1,1,structural problem +HB,lock1074,1074,1074,51588,1,1,1,0,1,1,structural problem +HB,lock2232,2232,2232,80352,1,1,1,0,1,1,structural problem +HB,lock3491,3491,3491,160444,1,1,1,0,1,1,structural problem +HB,lock_700,700,700,22175,1,1,1,0,1,1,structural problem +HB,man_5976,5976,5976,225046,1,1,1,0,1,1,structural problem +IBM_Austin,coupled,11341,11341,97193,1,0,0,0,1,0.7823373235828404,circuit simulation problem +ACUSIM,Pres_Poisson,14822,14822,715804,1,0,1,1,1,1,computational fluid dynamics problem +Rajat,rajat01,6833,6833,43250,1,1,0,0,0.9957479284779764,0.9957479284779764,circuit simulation problem +Rajat,rajat02,1960,1960,11187,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat03,7602,7602,32653,1,0,0,0,1,0.4024380527448012,circuit simulation problem +Rajat,rajat04,1041,1041,8725,1,0,0,0,1,0.03991188285603214,circuit simulation problem +Rajat,rajat05,301,301,1250,1,0,0,0,0.7697974217311234,0.7058823529411765,circuit simulation problem +Rajat,rajat06,10922,10922,46983,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat07,14842,14842,63913,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat08,19362,19362,83443,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat09,24482,24482,105573,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat10,30202,30202,130303,1,1,0,0,1,1,circuit simulation problem +Rajat,rajat11,135,135,665,1,0,0,0,0.8911764705882353,0.6303939962476548,circuit simulation problem +Rajat,rajat12,1879,1879,12818,1,0,0,0,1,0.4548776032151991,circuit simulation problem +Rajat,rajat13,7598,7598,48762,1,0,0,0,1,0.2965265970366772,circuit simulation problem +Rajat,rajat14,180,180,1475,1,0,0,0,1,0.0245398773006135,circuit simulation problem +Hamrle,Hamrle1,32,32,98,1,0,0,0,0.06451612903225806,0,circuit simulation problem +Hamrle,Hamrle2,5952,5952,22162,1,0,0,0,0.0009930486593843098,0.0001805543017062382,circuit simulation problem +Hamrle,Hamrle3,1447360,1447360,5514242,1,0,0,0,2.538882993038383e-06,0,circuit simulation problem +Oberwolfach,gyro_k,17361,17361,1021159,1,0,1,1,1,1,duplicate model reduction problem +Oberwolfach,gyro_m,17361,17361,340431,1,0,1,1,1,1,duplicate model reduction problem +Oberwolfach,t2dah_a,11445,11445,176117,1,0,1,0,1,1,duplicate model reduction problem +Oberwolfach,t2dah_e,11445,11445,176117,1,0,1,1,1,1,duplicate model reduction problem +Oberwolfach,t2dal_a,4257,4257,37465,1,0,1,0,1,1,duplicate model reduction problem +Oberwolfach,t2dal_e,4257,4257,4257,1,0,1,1,1,1,duplicate model reduction problem +Oberwolfach,t3dh_a,79171,79171,4352105,1,0,1,0,1,1,duplicate model reduction problem +Oberwolfach,t3dh_e,79171,79171,4352105,1,0,1,0,1,1,duplicate model reduction problem +Oberwolfach,t3dl_a,20360,20360,509866,1,0,1,0,1,1,duplicate model reduction problem +Oberwolfach,t3dl_e,20360,20360,20360,1,0,1,1,1,1,duplicate model reduction problem +LiuWenzhuo,powersim,15838,15838,64424,1,0,0,0,0.5913695769855386,0.5337339974478245,power network problem +Lin,Lin,256000,256000,1766400,1,0,1,0,1,1,structural problem +Cannizzo,sts4098,4098,4098,72356,1,0,1,1,1,1,structural problem +GHS_indef,aug2d,29008,29008,76832,1,0,1,0,1,1,2D/3D problem +GHS_indef,aug2dc,30200,30200,80000,1,0,1,0,1,1,2D/3D problem +GHS_indef,aug3d,24300,24300,69984,1,0,1,0,1,1,2D/3D problem +GHS_indef,aug3dcqp,35543,35543,128115,1,0,1,0,1,1,2D/3D problem +GHS_indef,bmw3_2,227362,227362,11288630,1,0,1,0,1,1,structural problem +GHS_indef,c-55,32780,32780,403450,1,0,0,0,1,1,optimization problem +GHS_indef,c-58,37595,37595,552551,1,0,0,0,1,1,optimization problem +GHS_indef,c-59,41282,41282,480536,1,0,0,0,1,1,optimization problem +GHS_indef,c-62ghs,41731,41731,559339,1,0,0,0,1,1,subsequent optimization problem +GHS_indef,c-63,44234,44234,434704,1,0,0,0,1,1,optimization problem +GHS_indef,c-68,64810,64810,565996,1,0,0,0,1,1,optimization problem +GHS_indef,c-69,67458,67458,623914,1,0,0,0,1,1,optimization problem +GHS_indef,c-70,68924,68924,658986,1,0,0,0,1,1,optimization problem +GHS_indef,c-71,76638,76638,859520,1,0,0,0,1,1,optimization problem +GHS_indef,c-72,84064,84064,707546,1,0,0,0,1,1,optimization problem +GHS_indef,copter2,55476,55476,759952,1,0,1,0,1,1,computational fluid dynamics problem +GHS_indef,d_pretok,182730,182730,1641672,1,0,1,0,1,1,2D/3D problem +GHS_indef,darcy003,389874,389874,2097566,1,0,1,0,1,1,2D/3D problem +GHS_indef,dawson5,51537,51537,1010777,1,0,1,0,1,1,structural problem +GHS_indef,dtoc,24993,24993,69972,1,0,0,0,1,1,optimization problem +GHS_indef,exdata_1,6001,6001,2269500,1,0,0,0,1,1,optimization problem +GHS_indef,helm2d03,392257,392257,2741935,1,0,1,0,1,1,2D/3D problem +GHS_indef,helm3d01,32226,32226,428444,1,0,1,0,1,1,2D/3D problem +GHS_indef,k1_san,67759,67759,559774,1,0,1,0,1,1,2D/3D problem +GHS_indef,laser,3002,3002,9000,1,0,1,0,1,1,materials problem +GHS_indef,mario001,38434,38434,204912,1,0,1,0,1,1,2D/3D problem +GHS_indef,mario002,389874,389874,2097566,1,0,1,0,1,1,duplicate 2D/3D problem +GHS_indef,ncvxqp1,12111,12111,73963,1,0,0,0,1,1,optimization problem +GHS_indef,ncvxqp9,16554,16554,54040,1,0,0,0,1,1,optimization problem +GHS_indef,olesnik0,88263,88263,744216,1,0,1,0,1,1,2D/3D problem +GHS_indef,sit100,10262,10262,61046,1,0,1,0,1,1,2D/3D problem +GHS_indef,stokes128,49666,49666,558594,1,0,1,0,1,1,computational fluid dynamics problem +GHS_indef,stokes64,12546,12546,140034,1,0,1,0,1,1,computational fluid dynamics problem +GHS_indef,stokes64s,12546,12546,140034,1,0,1,0,1,1,computational fluid dynamics problem +GHS_indef,tuma1,22967,22967,87760,1,0,1,0,1,1,2D/3D problem +GHS_indef,tuma2,12992,12992,49365,1,0,1,0,1,1,2D/3D problem +GHS_indef,turon_m,189924,189924,1690876,1,0,1,0,1,1,2D/3D problem +GHS_psdef,audikw_1,943695,943695,77651847,1,0,1,1,1,1,structural problem +GHS_psdef,bmw7st_1,141347,141347,7318399,1,0,1,1,1,1,structural problem +GHS_psdef,bmwcra_1,148770,148770,10641602,1,0,1,1,1,1,structural problem +GHS_psdef,copter1,17222,17222,211064,1,1,1,0,1,1,computational fluid dynamics problem +GHS_psdef,copter2,55476,55476,759952,1,1,1,0,1,1,duplicate computational fluid dynamics problem +GHS_psdef,crankseg_1,52804,52804,10614210,1,0,1,1,1,1,structural problem +GHS_psdef,crankseg_2,63838,63838,14148858,1,0,1,1,1,1,structural problem +DNVS,crplat2,18010,18010,960946,1,1,1,0,1,1,structural problem +DNVS,fcondp2,201822,201822,11294316,1,1,1,0,1,1,structural problem +GHS_psdef,finance256,37376,37376,298496,1,1,0,0,1,1,optimization problem +GHS_psdef,ford1,18728,18728,101576,1,1,1,0,1,1,structural problem +GHS_psdef,ford2,100196,100196,544688,1,1,1,0,1,1,structural problem +DNVS,fullb,199187,199187,11708077,1,1,1,0,1,1,structural problem +DNVS,halfb,224617,224617,12387821,1,1,1,0,1,1,structural problem +GHS_psdef,hood,220542,220542,9895422,1,0,1,1,1,1,structural problem +GHS_psdef,inline_1,503712,503712,36816170,1,0,1,1,1,1,structural problem +GHS_psdef,ldoor,952203,952203,42493817,1,0,1,1,1,1,structural problem +DNVS,m_t1,97578,97578,9753570,1,0,1,1,1,1,structural problem +GHS_psdef,oilpan,73752,73752,2148558,1,0,1,1,1,1,structural problem +GHS_psdef,opt1,15449,15449,1930655,1,1,1,0,1,1,structural problem +GHS_psdef,pds10,16558,16558,149658,1,1,0,0,1,1,optimization problem +GHS_psdef,pwt,36519,36519,326107,1,1,1,0,1,1,duplicate structural problem +GHS_psdef,ramage02,16830,16830,2866352,1,1,1,0,1,1,computational fluid dynamics problem +GHS_psdef,s3dkq4m2,90449,90449,4427725,1,0,1,1,1,1,structural problem +GHS_psdef,s3dkt3m2,90449,90449,3686223,1,0,1,1,1,1,structural problem +DNVS,ship_001,34920,34920,3896496,1,0,1,1,1,1,structural problem +DNVS,ship_003,121728,121728,3777036,1,0,1,1,1,1,structural problem +DNVS,shipsec1,140874,140874,3568176,1,0,1,1,1,1,structural problem +DNVS,shipsec5,179860,179860,4598604,1,0,1,1,1,1,structural problem +DNVS,shipsec8,114919,114919,3303553,1,0,1,1,1,1,structural problem +GHS_psdef,srb1,54924,54924,2962152,1,1,1,0,1,1,structural problem +DNVS,thread,29736,29736,4444880,1,0,1,1,1,1,structural problem +DNVS,trdheim,22098,22098,1935324,1,1,1,0,1,1,structural problem +DNVS,troll,213453,213453,11985111,1,1,1,0,1,1,structural problem +DNVS,tsyl201,20685,20685,2454957,1,1,1,0,1,1,structural problem +GHS_psdef,vanbody,47072,47072,2329056,1,0,1,1,1,1,structural problem +GHS_psdef,wathen100,30401,30401,471601,1,0,1,1,1,1,random 2D/3D problem +GHS_psdef,wathen120,36441,36441,565761,1,0,1,1,1,1,random 2D/3D problem +DNVS,x104,108384,108384,8713602,1,0,1,1,1,1,structural problem +GHS_indef,a0nsdsil,80016,80016,355034,1,0,0,0,1,1,optimization problem +GHS_indef,a2nnsnsl,80016,80016,347222,1,0,0,0,1,1,optimization problem +GHS_indef,a5esindl,60008,60008,255004,1,0,0,0,1,1,optimization problem +GHS_indef,blockqp1,60012,60012,640033,1,0,0,0,1,1,optimization problem +GHS_indef,bloweya,30004,30004,150009,1,0,1,0,1,1,materials problem +GHS_indef,boyd1,93279,93279,1211231,1,0,0,0,1,1,optimization problem +GHS_indef,boyd2,466316,466316,1500397,1,0,0,0,1,1,optimization problem +GHS_indef,brainpc2,27607,27607,179395,1,0,0,0,1,1,optimization problem +GHS_indef,bratu3d,27792,27792,173796,1,0,1,0,1,1,2D/3D problem +GHS_indef,cont-201,80595,80595,438795,1,0,0,0,1,1,optimization problem +GHS_indef,cont-300,180895,180895,988195,1,0,0,0,1,1,optimization problem +GHS_indef,dixmaanl,60000,60000,299998,1,0,0,0,1,1,optimization problem +GHS_indef,linverse,11999,11999,95977,1,0,0,0,1,1,statistical/mathematical problem +GHS_indef,ncvxbqp1,50000,50000,349968,1,0,0,0,1,1,optimization problem +GHS_indef,ncvxqp3,75000,75000,499964,1,0,0,0,1,1,optimization problem +GHS_indef,ncvxqp5,62500,62500,424966,1,0,0,0,1,1,optimization problem +GHS_indef,ncvxqp7,87500,87500,574962,1,0,0,0,1,1,optimization problem +GHS_indef,sparsine,50000,50000,1548988,1,0,1,0,1,1,structural problem +GHS_indef,spmsrtls,29995,29995,229947,1,0,0,0,1,1,statistical/mathematical problem +GHS_psdef,cvxbqp1,50000,50000,349968,1,0,0,1,1,1,optimization problem +GHS_psdef,gridgena,48962,48962,512084,1,0,0,1,1,1,optimization problem +GHS_psdef,jnlbrng1,40000,40000,199200,1,0,0,1,1,1,optimization problem +GHS_psdef,minsurfo,40806,40806,203622,1,0,0,1,1,1,optimization problem +GHS_psdef,obstclae,40000,40000,197608,1,0,0,1,1,1,optimization problem +GHS_psdef,torsion1,40000,40000,197608,1,0,0,1,1,1,duplicate optimization problem +Rajat,rajat15,37261,37261,443573,1,0,0,0,1,0.943060217954145,circuit simulation problem +Bydder,mri1,65536,147456,589824,1,0,1,0,0,0,computer graphics/vision problem +Bydder,mri2,63240,147456,569160,1,0,1,0,0,0,computer graphics/vision problem +Engwirda,airfoil_2d,14214,14214,259688,1,0,1,0,0.981668119637925,0,computational fluid dynamics problem +IBM_EDA,dc1,116835,116835,766396,1,0,0,0,0.8542477149952045,0.2426284829292399,circuit simulation problem sequence +IBM_EDA,dc2,116835,116835,766396,1,0,0,0,0.8542477149952045,0.2426284829292399,subsequent circuit simulation problem +IBM_EDA,dc3,116835,116835,766396,1,0,0,0,0.8542477149952045,0.2426407989395915,subsequent circuit simulation problem +IBM_EDA,trans4,116835,116835,749800,1,0,0,0,0.8542477149952045,0.3020988522272163,circuit simulation problem sequence +IBM_EDA,trans5,116835,116835,749800,1,0,0,0,0.8542477149952045,0.3018997890878642,subsequent circuit simulation problem +Morandini,robot,120,120,870,1,0,1,0,0.2177215189873418,0.05316455696202532,robotics problem +Morandini,rotor1,100,100,708,1,0,1,0,0.514018691588785,0.07165109034267912,structural problem +Morandini,rotor2,791,791,10685,1,0,1,0,0.2341063574570172,0.1155537784886046,structural problem +MathWorks,tomography,500,500,28726,1,0,1,0,1,0.9331113158081201,computer graphics/vision problem +Kemelmacher,Kemelmacher,28452,9693,100875,1,0,1,0,0,0,computer graphics/vision problem +MathWorks,Kuu,7102,7102,340200,1,0,1,1,1,1,structural problem +MathWorks,Muu,7102,7102,170134,1,0,1,1,1,1,structural problem +Toledo,deltaX,68600,21961,247424,1,0,0,0,0,0,counter-example problem +VanVelzen,std1_Jac2_db,21982,21982,498771,1,0,0,0,0.3261820218167785,8.389455293641422e-06,chemical process simulation problem +VanVelzen,std1_Jac2,21982,21982,1248213,1,0,0,0,1.441471454060305e-05,0,chemical process simulation problem +VanVelzen,std1_Jac3_db,21982,21982,531826,1,0,0,0,0.3593020610225873,7.84553706623987e-06,chemical process simulation problem +VanVelzen,std1_Jac3,21982,21982,1455374,1,0,0,0,1.37377639453759e-05,0,chemical process simulation problem +VanVelzen,Zd_Jac2_db,22835,22835,676439,1,0,0,0,0.3038965489807284,3.059956793410077e-06,chemical process simulation problem +VanVelzen,Zd_Jac2,22835,22835,1642407,1,0,0,0,0.000249569948369456,0,chemical process simulation problem +VanVelzen,Zd_Jac3_db,22835,22835,713907,1,0,0,0,0.3299540424152621,2.894054454528616e-06,chemical process simulation problem +VanVelzen,Zd_Jac3,22835,22835,1915726,1,0,0,0,0.0002609405864378739,0,chemical process simulation problem +VanVelzen,Zd_Jac6_db,22835,22835,663643,1,0,0,0,0.3245527521504101,3.121059662176502e-06,chemical process simulation problem +VanVelzen,Zd_Jac6,22835,22835,1711557,1,0,0,0,0.0002161245251101651,0,chemical process simulation problem +Rajat,rajat16,94294,94294,476766,1,0,0,0,0.9900237892855388,0.6363336955309653,circuit simulation problem +Rajat,rajat17,94294,94294,479246,1,0,0,0,0.9900237892855388,0.2705152684049277,circuit simulation problem +Rajat,rajat18,94294,94294,479151,1,0,0,0,0.626033640830624,0.2849580148146621,circuit simulation problem +Rajat,rajat19,1157,1157,3699,1,0,0,0,0.9041281299345816,0.9193154034229829,circuit simulation problem +Lourakis,bundle1,10581,10581,770811,1,0,1,1,1,1,computer graphics/vision problem +PARSEC,benzene,8219,8219,242669,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,CO,221119,221119,7666057,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ga10As10H30,113081,113081,6115633,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ga19As19H42,133123,133123,8884839,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ga3As3H12,61349,61349,5970947,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ga41As41H72,268096,268096,18488476,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,GaAsH6,61349,61349,3381809,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ge87H76,112985,112985,7892195,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Ge99H100,112985,112985,8451395,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,H2O,67024,67024,2216736,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Na5,5832,5832,305630,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si10H16,17077,17077,875923,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si2,769,769,17801,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si34H36,97569,97569,5156379,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si41Ge41H72,185639,185639,15011265,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si5H12,19896,19896,738598,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,Si87H76,240369,240369,10661631,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,SiH4,5041,5041,171903,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,SiNa,5743,5743,198787,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,SiO2,155331,155331,11283503,1,0,0,0,1,1,theoretical/quantum chemistry problem +PARSEC,SiO,33401,33401,1317655,1,0,0,0,1,1,theoretical/quantum chemistry problem +Rajat,rajat20,86916,86916,604299,1,0,0,0,0.9906228863063395,0.1122042623922186,circuit simulation problem +Rajat,rajat21,411676,411676,1876011,1,0,0,0,0.7647530446640561,0.6145057622905241,circuit simulation problem +Rajat,rajat22,39899,39899,195429,1,0,0,0,0.9800702079331211,0.3342735182643515,circuit simulation problem +Rajat,rajat23,110355,110355,555441,1,0,0,0,0.9891581094231137,0.3324988529606978,circuit simulation problem +Rajat,rajat24,358172,358172,1946979,1,0,0,0,0.996935347128458,0.2716106951495262,circuit simulation problem +Rajat,rajat25,87190,87190,606489,1,0,0,0,0.9906572831072957,0.1118151951820715,circuit simulation problem +Rajat,rajat26,51032,51032,247528,1,0,0,0,0.9853537517311467,0.3271800826884766,circuit simulation problem +Rajat,rajat27,20640,20640,97353,1,0,0,0,0.9645908149382882,0.3035747337767303,circuit simulation problem +Rajat,rajat28,87190,87190,606489,1,0,0,0,0.9906572831072957,0.1072533437604223,circuit simulation problem +MathWorks,Sieber,2290,2290,14873,1,0,0,0,0.7272727272727273,0,counter-example problem +Andrianov,ex3sta1,16782,16782,678998,1,1,0,0,1,1,optimization problem +Andrianov,fxm3_6,5026,5026,94026,1,1,0,0,1,1,optimization problem +Andrianov,fxm4_6,18892,18892,497844,1,1,0,0,1,1,optimization problem +Andrianov,ins2,309412,309412,2751484,1,1,0,0,1,1,optimization problem +Andrianov,lp1,534388,534388,1643420,1,1,0,0,1,1,optimization problem +Andrianov,lpl1,32460,32460,328036,1,1,0,0,1,1,optimization problem +Andrianov,mip1,66463,66463,10352819,1,1,0,0,1,1,optimization problem +Andrianov,net100,29920,29920,2033200,1,1,0,0,1,1,optimization problem +Andrianov,net125,36720,36720,2577200,1,1,0,0,1,1,optimization problem +Andrianov,net150,43520,43520,3121200,1,1,0,0,1,1,optimization problem +Andrianov,net25,9520,9520,401200,1,1,0,0,1,1,optimization problem +Andrianov,net4-1,88343,88343,2441727,1,1,0,0,1,1,optimization problem +Andrianov,net50,16320,16320,945200,1,1,0,0,1,1,optimization problem +Andrianov,net75,23120,23120,1489200,1,1,0,0,1,1,optimization problem +Andrianov,pattern1,19242,19242,9323432,1,1,0,0,1,1,optimization problem +Andrianov,pf2177,9728,9728,725144,1,1,0,0,1,1,optimization problem +MKS,fp,7548,7548,834222,1,0,1,0,0.7575174939506899,0.002912877385765126,electromagnetics problem +Rajat,rajat29,643994,643994,3760246,1,0,0,0,0.6856406275660725,0.6910598008173955,circuit simulation problem +Rajat,rajat30,643994,643994,6175244,1,0,0,0,0.9945912407336421,0.009194565053000587,circuit simulation problem +Rajat,rajat31,4690002,4690002,20316253,1,0,0,0,1,0.4000960614178773,circuit simulation problem +Raju,laminar_duct3D,67173,67173,3788857,1,0,1,0,0.9022908019592145,0.5518386226500883,computational fluid dynamics problem +Bates,Chem97Zt,2541,31022,62044,1,1,0,0,0,0,statistical/mathematical problem +Bates,Chem97ZtZ,2541,2541,7361,1,0,0,1,1,1,statistical/mathematical problem +Schmid,thermal1,82654,82654,574458,1,0,1,1,1,1,thermal problem +Schmid,thermal2,1228045,1228045,8580313,1,0,1,1,1,1,thermal problem +MathWorks,Kaufhold,8765,8765,42471,1,0,0,0,1,0.778437073518068,counter-example problem +Bindel,ted_A,10605,10605,424587,1,0,1,0,0.5657922767749357,0.1057079149564699,thermal problem +Bindel,ted_B,10605,10605,144579,1,0,1,1,1,1,thermal problem +Bindel,ted_AB,10605,10605,522387,0,0,1,0,0.6415700434950818,0,thermal problem +Bindel,ted_A_unscaled,10605,10605,424587,1,0,1,0,0.5657922767749357,0.1057079149564699,thermal problem +Bindel,ted_B_unscaled,10605,10605,144579,1,0,1,1,1,1,thermal problem +Bindel,ted_AB_unscaled,10605,10605,522387,0,0,1,0,0.6415700434950818,0,thermal problem +Koutsovasilis,F1,343791,343791,26837113,1,0,1,0,1,1,structural problem +AMD,G2_circuit,150102,150102,726674,1,0,0,1,1,1,circuit simulation problem +IBM_EDA,ckt11752_dc_1,49702,49702,333029,1,0,0,0,0.9838102263462359,0.7355387943965807,circuit simulation problem +IBM_EDA,ckt11752_tr_0,49702,49702,332807,1,0,0,0,0.9838102263462359,0.7360237367761078,circuit simulation problem +Sandia,ASIC_100k,99340,99340,940621,1,0,0,0,1,0.002631466347182405,circuit simulation problem +Sandia,ASIC_100ks,99190,99190,578890,1,0,0,0,1,0.0007546383156139254,circuit simulation problem +Sandia,ASIC_320k,321821,321821,1931828,1,0,0,0,1,0.3578041366837217,circuit simulation problem +Sandia,ASIC_320ks,321671,321671,1316085,1,0,0,0,1,0.2891089626654492,circuit simulation problem +Sandia,ASIC_680k,682862,682862,2638997,1,0,0,0,1,0.004444308126428144,circuit simulation problem +Sandia,ASIC_680ks,682712,682712,1693767,1,0,0,0,1,0.005801860432914134,circuit simulation problem +AMD,G3_circuit,1585478,1585478,7660826,1,0,0,1,1,1,circuit simulation problem +GHS_psdef,apache1,80800,80800,542184,1,0,1,1,1,1,structural problem +GHS_psdef,apache2,715176,715176,4817870,1,0,1,1,1,1,structural problem +GHS_indef,bloweybl,30003,30003,109999,1,0,1,0,1,1,materials problem +GHS_indef,bloweybq,10001,10001,49999,1,0,1,1,1,1,materials problem +GHS_indef,cvxqp3,17500,17500,114962,1,0,0,0,1,1,optimization problem +GHS_indef,qpband,20000,20000,45000,1,0,0,0,1,1,optimization problem +Oberwolfach,chipcool0,20082,20082,281150,1,0,1,0,1,0.8688617524936032,model reduction problem +Oberwolfach,chipcool1,20082,20082,281150,1,0,1,0,1,0.08556391438245974,model reduction problem +Oberwolfach,filter2D,1668,1668,10750,1,0,1,0,1,1,model reduction problem +Oberwolfach,filter3D,106437,106437,2707179,1,0,1,0,1,1,model reduction problem +Oberwolfach,flowmeter0,9669,9669,67391,1,0,1,0,1,1,model reduction problem +Oberwolfach,flowmeter5,9669,9669,67391,1,0,1,0,1,0.06222930598385364,model reduction problem +Oberwolfach,gas_sensor,66917,66917,1703365,1,0,1,0,1,1,model reduction problem +Oberwolfach,gyro,17361,17361,1021159,1,0,1,1,1,1,model reduction problem +Oberwolfach,inlet,11730,11730,328323,1,0,1,0,0.6083330964361183,9.475888601453601e-05,model reduction problem +Oberwolfach,LF10000,19998,19998,99982,1,0,1,1,1,1,model reduction problem +Oberwolfach,LF10,18,18,82,1,0,1,1,1,1,model reduction problem +Oberwolfach,LFAT5000,19994,19994,79966,1,0,1,1,1,1,model reduction problem +Oberwolfach,LFAT5,14,14,46,1,0,1,1,1,1,model reduction problem +Oberwolfach,piston,2025,2025,100015,1,0,1,0,1,0.03275844473925911,model reduction problem +Oberwolfach,rail_1357,1357,1357,8985,1,0,1,0,1,1,model reduction problem +Oberwolfach,rail_20209,20209,20209,139233,1,0,1,0,1,1,model reduction problem +Oberwolfach,rail_5177,5177,5177,35185,1,0,1,0,1,1,model reduction problem +Oberwolfach,rail_79841,79841,79841,553921,1,0,1,0,1,1,model reduction problem +Oberwolfach,spiral,1434,1434,18228,1,0,1,0,1,1,model reduction problem +Oberwolfach,t2dah,11445,11445,176117,1,0,1,0,1,1,model reduction problem +Oberwolfach,t2dal_bci,4257,4257,37465,1,0,1,0,1,1,model reduction problem +Oberwolfach,t2dal,4257,4257,37465,1,0,1,0,1,1,model reduction problem +Oberwolfach,t3dh,79171,79171,4352105,1,0,1,0,1,1,model reduction problem +Oberwolfach,t3dl,20360,20360,509866,1,0,1,0,1,1,model reduction problem +Oberwolfach,windscreen,22692,22692,1482390,0,0,1,0,1,0,model reduction problem +Oberwolfach,bone010,986703,986703,47851783,1,0,1,1,1,1,model reduction problem +Oberwolfach,boneS01,127224,127224,5516602,1,0,1,1,1,1,model reduction problem +Oberwolfach,boneS10,914898,914898,40878708,1,0,1,1,1,1,model reduction problem +Pajek,California,9664,9664,16150,1,1,0,0,0.02241486068111455,0.02241486068111455,directed graph +Pajek,Cities,55,46,1342,1,0,0,0,0,0,weighted bipartite graph +Pajek,CSphd,1882,1882,1740,1,1,0,0,0,0,directed graph +Pajek,dictionary28,52652,52652,178076,1,1,0,0,1,1,undirected graph +Pajek,divorce,50,9,225,1,1,0,0,0,0,bipartite graph +Pajek,EAT_RS,23219,23219,325592,1,0,0,0,0.1236262721980876,0.03102501938294547,directed weighted graph +Pajek,EAT_SR,23219,23219,325589,1,0,0,0,0.1236274132759018,0.03102530574571187,directed weighted graph +Pajek,EPA,4772,4772,8965,1,1,0,0,0.01249302844394869,0.01249302844394869,directed graph +Pajek,Erdos02,6927,6927,16944,1,1,0,0,1,1,undirected graph +Pajek,Erdos971,472,472,2628,1,1,0,0,1,1,undirected graph +Pajek,Erdos972,5488,5488,14170,1,1,0,0,1,1,undirected graph +Pajek,Erdos981,485,485,2762,1,1,0,0,1,1,undirected graph +Pajek,Erdos982,5822,5822,14750,1,1,0,0,1,1,undirected graph +Pajek,Erdos991,492,492,2834,1,1,0,0,1,1,undirected graph +Pajek,Erdos992,6100,6100,15030,1,1,0,0,1,1,undirected graph +Pajek,EVA,8497,8497,6726,1,1,0,0,0.003866745984533016,0.003866745984533016,directed graph +Pajek,FA,10617,10617,72176,1,0,0,0,0.232333869090506,0.005847142936318794,directed weighted graph +Pajek,foldoc,13356,13356,120238,1,0,0,0,0.4785009730700777,0.459472047106572,directed weighted graph +Pajek,football,35,35,118,1,0,0,0,0,0,directed weighted graph +Pajek,GD00_a,352,352,458,1,1,0,0,0,0,directed graph +Pajek,GD00_c,638,638,1041,1,0,0,0,0.02133850630455868,0.01551891367604268,directed multigraph +Pajek,GD01_a,311,311,645,1,0,0,0,0.01550387596899225,0.01550387596899225,directed weighted graph +Pajek,GD01_A,953,953,645,1,0,0,0,0.01550387596899225,0.01550387596899225,directed multigraph +Pajek,GD01_b,18,18,37,1,1,0,0,0.5142857142857142,0.5142857142857142,directed graph +Pajek,GD01_c,33,33,135,1,0,0,0,0,0,directed multigraph +Pajek,GD02_a,23,23,87,1,1,0,0,0.6436781609195402,0.6436781609195402,directed graph +Pajek,GD02_b,80,80,232,1,1,0,0,0,0,directed graph +Pajek,GD06_Java,1538,1538,8032,1,1,0,0,0.05353585657370518,0.05353585657370518,directed graph +Pajek,GD06_theory,101,101,380,1,1,0,0,1,1,undirected graph +Pajek,GD95_a,36,36,57,1,1,0,0,0.03508771929824561,0.03508771929824561,directed graph +Pajek,GD95_b,73,73,96,1,1,0,0,0,0,directed graph +Pajek,GD95_c,62,62,287,1,1,0,0,0.9965156794425087,0.9965156794425087,directed graph +Pajek,GD96_a,1096,1096,1677,1,0,0,0,0,0,directed multigraph +Pajek,GD96_b,111,111,193,1,1,0,0,0,0,directed graph +Pajek,GD96_c,65,65,250,1,1,0,0,1,1,undirected graph +Pajek,GD96_d,180,180,229,1,1,0,0,0.008733624454148471,0.008733624454148471,directed graph +Pajek,GD97_a,84,84,332,1,1,0,0,1,1,directed graph +Pajek,GD97_b,47,47,264,1,0,0,0,1,1,undirected weighted graph +Pajek,GD97_c,452,452,460,1,0,0,0,0,0,directed multigraph +Pajek,GD98_a,38,38,50,1,1,0,0,0.16,0.16,directed graph +Pajek,GD98_b,121,121,207,1,1,0,0,0.7246376811594203,0.7246376811594203,directed graph +Pajek,GD98_c,112,112,336,1,1,0,0,1,1,undirected graph +Pajek,GD99_b,64,64,252,1,0,0,0,1,1,undirected multigraph +Pajek,GD99_c,105,105,149,1,1,0,0,0.3892617449664429,0.3892617449664429,directed graph +Pajek,geom,7343,7343,23796,1,0,0,0,1,1,undirected weighted graph +Pajek,GlossGT,72,72,122,1,1,0,0,0.06557377049180328,0.06557377049180328,directed graph +Pajek,HEP-th,27240,27240,342437,1,1,0,0,0.002774548916757691,0.002774548916757691,directed graph +Pajek,HEP-th-new,27770,27770,352807,1,1,0,0,0.002738343613933237,0.002738343613933237,directed graph +Pajek,IMDB,428440,896308,3782463,1,1,0,0,0,0,bipartite graph +Pajek,internet,124651,124651,207214,1,0,0,0,0.01444913320583093,0.002245819852432203,directed weighted graph +Pajek,Journals,124,124,12068,1,0,0,1,1,1,undirected weighted graph +Pajek,Kohonen,4470,4470,12731,1,1,0,0,0.001728336868567837,0.001728336868567837,directed graph +Pajek,Lederberg,8843,8843,41601,1,0,0,0,0.003029210241615579,0.003029210241615579,directed multigraph +Barabasi,NotreDame_actors,392400,127823,1470404,1,1,0,0,0,0,bipartite graph +Barabasi,NotreDame_www,325729,325729,929849,1,1,0,0,0.3315875213545298,0.3315875213545298,directed graph +Barabasi,NotreDame_yeast,2114,2114,4480,1,1,0,0,1,1,undirected graph +Pajek,ODLIS,2909,2909,18246,1,0,0,0,0.2043747601556932,0.1997697494654898,directed multigraph +Pajek,patents_main,240547,240547,560943,1,0,0,0,0,0,directed weighted graph +Pajek,patents,3774768,3774768,14970767,1,1,0,0,0,0,directed graph +Pajek,Ragusa16,24,24,81,1,0,0,0,0.3661971830985916,0.1971830985915493,directed weighted graph +Pajek,Ragusa18,23,23,64,1,0,0,0,0.3278688524590164,0.1967213114754098,directed weighted graph +Pajek,Reuters911,13332,13332,296076,1,0,0,0,1,1,undirected weighted graph sequence +Pajek,Roget,1022,1022,5075,1,1,0,0,0.5620811982656682,0.5620811982656682,directed graph +Pajek,Sandi_authors,86,86,248,1,0,0,0,1,1,undirected weighted graph +Pajek,Sandi_sandi,314,360,613,1,1,0,0,0,0,bipartite graph +Pajek,SciMet,3084,3084,10413,1,0,0,0,0.002497118709181713,0.002497118709181713,directed multigraph +Pajek,SmaGri,1059,1059,4919,1,0,0,0,0.0008133387555917039,0.0008133387555917039,directed multigraph +Pajek,SmallW,396,396,994,1,0,0,0,0,0,directed multigraph +Pajek,Stranke94,10,10,90,1,0,0,0,1,1,undirected weighted graph +Pajek,Tina_AskCal,11,11,29,1,1,0,0,0.2758620689655172,0.2758620689655172,directed graph +Pajek,Tina_AskCog,11,11,36,1,1,0,0,0.5,0.5,directed graph +Pajek,Tina_DisCal,11,11,41,1,1,0,0,0.4390243902439024,0.4390243902439024,directed graph +Pajek,Tina_DisCog,11,11,48,1,1,0,0,0.5,0.5,directed graph +Pajek,USAir97,332,332,4252,1,0,0,0,1,1,undirected weighted graph +Pajek,USpowerGrid,4941,4941,13188,1,1,0,0,1,1,undirected graph +Pajek,Wordnet3,82670,82670,132964,1,0,0,0,0.1765463136851033,0.1741230992912098,directed weighted graph +Pajek,WorldCities,315,100,7518,1,0,0,0,0,0,weighted bipartite graph +Pajek,yeast,2361,2361,13828,1,1,0,0,1,1,undirected graph +Pajek,Zewail,6752,6752,54233,1,0,0,0,0.001843929783153858,0.001843929783153858,directed multigraph +Zitney,extr1b,2836,2836,10965,1,0,0,0,0.003859310586790632,0,chemical process simulation problem sequence +Zitney,hydr1c,5308,5308,22592,1,0,0,0,0.004126315789473685,0.0006197432492253209,chemical process simulation problem sequence +Schenk_IBMNA,c-18,2169,2169,15145,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-19,2327,2327,21817,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-20,2921,2921,20445,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-21,3509,3509,32145,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-22,3792,3792,28870,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-23,3969,3969,31079,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-24,4119,4119,35699,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-25,3797,3797,49635,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-26,4307,4307,34537,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-27,4563,4563,30927,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-28,4598,4598,30590,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-29,5033,5033,43731,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-30,5321,5321,65693,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-31,5339,5339,78571,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-32,5975,5975,54471,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-33,6317,6317,56123,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-34,6611,6611,64333,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-35,6537,6537,62891,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-36,7479,7479,65941,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-37,8204,8204,74676,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-38,8127,8127,77689,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-39,9271,9271,116587,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-40,9941,9941,81501,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-41,9769,9769,101635,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-42,10471,10471,110285,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-43,11125,11125,123659,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-44,10728,10728,85000,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-45,13206,13206,174452,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-46,14913,14913,130397,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-47,15343,15343,211401,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-48,18354,18354,166080,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-49,21132,21132,157040,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-50,22401,22401,180245,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-51,23196,23196,203048,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-52,23948,23948,202708,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-53,30235,30235,355139,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-54,31793,31793,385987,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-56,35910,35910,380240,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-57,37833,37833,403373,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-60,43640,43640,298570,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-61,43618,43618,310016,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-65,48066,48066,360428,1,0,0,0,1,1,optimization problem +Schenk_IBMNA,c-big,345241,345241,2340859,1,0,0,0,1,1,optimization problem +Schenk_AFE,af_0_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_1_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_2_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_3_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_4_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_5_k101,503625,503625,17550675,1,0,1,1,1,1,structural problem +Schenk_AFE,af_shell10,1508065,1508065,52259885,1,0,1,0,1,1,structural problem +Schenk_IBMNA,c-64b,51035,51035,707601,1,0,0,0,1,1,subsequent optimization problem +Schenk_IBMNA,c-66b,49989,49989,444851,1,0,0,0,1,1,subsequent optimization problem +Schenk_IBMNA,c-67b,57975,57975,530583,1,0,0,0,1,1,subsequent optimization problem +Schenk_IBMNA,c-73b,169422,169422,1279274,1,0,0,0,1,1,subsequent optimization problem +QCD,conf5_0-4x4-10,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_0-4x4-14,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_0-4x4-18,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_0-4x4-22,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_0-4x4-26,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf6_0-4x4-20,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf6_0-4x4-30,3072,3072,119808,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_4-8x8-05,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_4-8x8-10,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_4-8x8-15,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf5_4-8x8-20,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf6_0-8x8-20,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf6_0-8x8-30,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +QCD,conf6_0-8x8-80,49152,49152,1916928,0,0,0,0,0.9230769230769231,0.4615384615384616,theoretical/quantum chemistry problem +Cylshell,s1rmq4m1,5489,5489,262411,1,0,1,1,1,1,structural problem +Cylshell,s2rmq4m1,5489,5489,263351,1,0,1,1,1,1,structural problem +Cylshell,s3rmq4m1,5489,5489,262943,1,0,1,1,1,1,structural problem +Cylshell,s1rmt3m1,5489,5489,217651,1,0,1,1,1,1,structural problem +Cylshell,s2rmt3m1,5489,5489,217681,1,0,1,1,1,1,structural problem +Cylshell,s3rmt3m1,5489,5489,217669,1,0,1,1,1,1,structural problem +Cylshell,s3rmt3m3,5357,5357,207123,1,0,1,1,1,1,structural problem +Bai,cryg10000,10000,10000,49699,1,0,1,0,0.9974558553112169,0,materials problem +Bai,cryg2500,2500,2500,12349,1,0,1,0,0.9948218093207433,0,materials problem +Bai,dw2048,2048,2048,10114,1,0,1,0,0.9848747830399207,0.9481775353334987,electromagnetics problem +Bai,dw8192,8192,8192,41746,1,0,1,0,0.9626274065685164,0.9154199201287477,electromagnetics problem +Bai,dwa512,512,512,2480,1,0,1,0,0.9796747967479674,0.9146341463414634,electromagnetics problem +Bai,dwb512,512,512,2500,1,0,1,0,0.9698189134808853,0.8832997987927566,electromagnetics problem +Bai,dwg961a,961,961,3405,0,0,1,0,1,0.36,electromagnetics problem +Bai,dwg961b,961,961,10591,0,0,1,0,1,0.3476635514018692,electromagnetics problem +Bai,mhd1280a,1280,1280,47906,0,0,1,0,0.8978403914290535,0.3060992070187278,electromagnetics problem +Bai,mhd1280b,1280,1280,22778,0,0,1,1,1,1,electromagnetics problem +Bai,mhd3200a,3200,3200,68026,1,0,1,0,0.7676029990571827,0.2674009667619461,electromagnetics problem +Bai,mhd3200b,3200,3200,18316,1,0,1,1,1,1,electromagnetics problem +Bai,mhd4800a,4800,4800,102252,1,0,1,0,0.7677879876950033,0.2677033659541848,electromagnetics problem +Bai,mhd4800b,4800,4800,27520,1,0,1,1,1,1,electromagnetics problem +Bai,qh1484,1484,1484,6110,1,0,0,0,1,0.05377207062600321,power network problem +Bai,qh768,768,768,2934,1,0,0,0,0.9347300564061241,0,power network problem +Bai,rdb1250,1250,1250,7300,1,0,1,0,1,0.7933884297520661,computational fluid dynamics problem +Bai,rdb1250l,1250,1250,7300,1,0,1,0,1,0.7933884297520661,computational fluid dynamics problem +Bai,rdb200,200,200,1120,1,0,1,0,1,0.7826086956521739,computational fluid dynamics problem +Bai,rdb200l,200,200,1120,1,0,1,0,1,0.7826086956521739,computational fluid dynamics problem +Bai,rdb2048_noL,2048,2048,12032,1,0,1,0,1,0.7948717948717948,computational fluid dynamics problem +Bai,rdb3200l,3200,3200,18880,1,0,1,0,1,0.7959183673469388,computational fluid dynamics problem +Bai,rdb450,450,450,2580,1,0,1,0,1,0.7887323943661971,computational fluid dynamics problem +Bai,rdb450l,450,450,2580,1,0,1,0,1,0.7887323943661971,computational fluid dynamics problem +Bai,rdb800l,800,800,4640,1,0,1,0,1,0.7916666666666666,computational fluid dynamics problem +Bai,tols1090,1090,1090,3546,1,0,1,0,0.3178758414360509,0,computational fluid dynamics problem +Bai,tols2000,2000,2000,5184,1,0,1,0,0.3387276785714285,0,computational fluid dynamics problem +Bai,tols340,340,340,2196,1,0,1,0,0.2858627858627859,0,computational fluid dynamics problem +Bai,tols4000,4000,4000,8784,1,0,1,0,0.3606733524355301,0,computational fluid dynamics problem +Bai,tols90,90,90,1746,1,0,1,0,0.2688172043010753,0,computational fluid dynamics problem +POLYFLOW,invextr1_new,30412,30412,1793881,1,0,1,0,0.971442083756505,0.7213486599424203,computational fluid dynamics problem +POLYFLOW,mixtank_new,29957,29957,1990919,1,0,1,0,1,0.9890905426943581,computational fluid dynamics problem +INPRO,msdoor,415863,415863,19173163,1,0,1,1,1,1,structural problem +Mittelmann,nug08-3rd,19728,29856,148416,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-30,49944,158489,340635,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-40,66844,217531,466800,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-50,83060,275814,590833,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-60,99431,336421,719557,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-70,114944,390005,833465,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-80,129181,434580,927826,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-90,142823,475448,1014136,1,0,0,0,0,0,linear programming problem +Mittelmann,pds-100,156243,514577,1096002,1,0,0,0,0,0,linear programming problem +Mittelmann,rail507,507,63516,409856,1,0,0,0,0,0,linear programming problem +Mittelmann,rail516,516,47827,315412,1,0,0,0,0,0,linear programming problem +Mittelmann,rail582,582,56097,402290,1,0,0,0,0,0,linear programming problem +Mittelmann,rail2586,2586,923269,8011362,1,0,0,0,0,0,linear programming problem +Mittelmann,rail4284,4284,1096894,11284032,1,0,0,0,0,0,linear programming problem +Mittelmann,sgpf5y6,246077,312540,831976,1,0,0,0,0,0,linear programming problem +Mittelmann,stormG2_1000,528185,1377306,3459881,1,0,0,0,0,0,linear programming problem +Mittelmann,watson_1,201155,386992,1055093,1,0,0,0,0,0,linear programming problem +Mittelmann,watson_2,352013,677224,1846391,1,0,0,0,0,0,linear programming problem +Mittelmann,cont11_l,1468599,1961394,5382999,1,0,0,0,0,0,linear programming problem +Mittelmann,cont1_l,1918399,1921596,7031999,1,0,0,0,0,0,linear programming problem +Mittelmann,fome11,12142,24460,71264,1,0,0,0,0,0,linear programming problem +Mittelmann,fome12,24284,48920,142528,1,0,0,0,0,0,linear programming problem +Mittelmann,fome13,48568,97840,285056,1,0,0,0,0,0,linear programming problem +Mittelmann,fome20,33874,108175,232647,1,0,0,0,0,0,linear programming problem +Mittelmann,fome21,67748,216350,465294,1,0,0,0,0,0,linear programming problem +Mittelmann,neos,479119,515905,1526794,1,0,0,0,0,0,linear programming problem +Mittelmann,neos1,131581,133473,599590,1,0,0,0,0,0,linear programming problem +Mittelmann,neos2,132568,134128,685087,1,0,0,0,0,0,linear programming problem +Mittelmann,neos3,512209,518832,2055024,1,0,0,0,0,0,linear programming problem +Mittelmann,spal_004,10203,321696,46168124,1,0,0,0,0,0,linear programming problem +Meszaros,gams10am,114,171,407,1,0,0,0,0,0,linear programming problem +Meszaros,gams30am,354,531,1287,1,0,0,0,0,0,linear programming problem +Meszaros,gams60am,714,1071,2607,1,0,0,0,0,0,linear programming problem +Meszaros,gas11,459,862,2166,1,0,0,0,0,0,linear programming problem +Meszaros,aa01,823,8904,72965,1,1,0,0,0,0,linear programming problem +Meszaros,aa03,825,8627,70806,1,1,0,0,0,0,linear programming problem +Meszaros,aa3,825,8627,70806,1,1,0,0,0,0,linear programming problem +Meszaros,aa4,426,7195,52121,1,1,0,0,0,0,linear programming problem +Meszaros,aa5,801,8308,65953,1,1,0,0,0,0,linear programming problem +Meszaros,aa6,646,7292,51728,1,1,0,0,0,0,linear programming problem +Meszaros,air02,50,6774,61555,1,1,0,0,0,0,linear programming problem +Meszaros,air03,124,10757,91028,1,1,0,0,0,0,linear programming problem +Meszaros,air04,823,8904,72965,1,1,0,0,0,0,linear programming problem +Meszaros,air05,426,7195,52121,1,1,0,0,0,0,linear programming problem +Meszaros,air06,825,8627,70806,1,1,0,0,0,0,linear programming problem +Meszaros,aircraft,3754,7517,20267,1,0,0,0,0,0,linear programming problem +Meszaros,bas1lp,5411,9825,587775,1,0,0,0,0,0,linear programming problem +Meszaros,baxter,27441,30733,111576,1,0,0,0,0,0,linear programming problem +Meszaros,car4,16384,33052,63724,1,0,0,0,0,0,linear programming problem +Meszaros,cari,400,1200,152800,1,0,0,0,0,0,linear programming problem +Meszaros,ch,3700,8291,24102,1,0,0,0,0,0,linear programming problem +Meszaros,co5,5774,12325,57993,1,0,0,0,0,0,linear programming problem +Meszaros,co9,10789,22924,109651,1,0,0,0,0,0,linear programming problem +Meszaros,complex,1023,1408,46463,1,0,0,0,0,0,linear programming problem +Meszaros,cq5,5048,11748,51571,1,0,0,0,0,0,linear programming problem +Meszaros,cq9,9278,21534,96653,1,0,0,0,0,0,linear programming problem +Meszaros,cr42,905,1513,6614,1,0,0,0,0,0,linear programming problem +Meszaros,crew1,135,6469,46950,1,1,0,0,0,0,linear programming problem +Meszaros,dano3mip,3202,15851,81633,1,0,0,0,0,0,linear programming problem +Meszaros,dbic1,43200,226317,1081843,1,0,0,0,0,0,linear programming problem +Meszaros,dbir1,18804,45775,1077025,1,0,0,0,0,0,linear programming problem +Meszaros,dbir2,18906,45877,1158159,1,0,0,0,0,0,linear programming problem +Meszaros,df2177,630,10358,22336,1,1,0,0,0,0,linear programming problem +Meszaros,e18,24617,38602,156466,1,0,0,0,0,0,linear programming problem +Meszaros,ex3sta1,17443,17516,68779,1,0,0,0,0,0,linear programming problem +Meszaros,farm,7,17,41,1,0,0,0,0,0,linear programming problem +Meszaros,gams10a,114,171,407,1,0,0,0,0,0,linear programming problem +Meszaros,gams30a,354,531,1287,1,0,0,0,0,0,linear programming problem +Meszaros,ge,10099,16369,44825,1,0,0,0,0,0,linear programming problem +Meszaros,iiasa,669,3639,7317,1,0,0,0,0,0,linear programming problem +Meszaros,jendrec1,2109,4228,89608,1,0,0,0,0,0,linear programming problem +Meszaros,kl02,71,36699,212536,1,1,0,0,0,0,linear programming problem +Meszaros,l9,244,1483,4659,1,0,0,0,0,0,linear programming problem +Meszaros,lp22,2958,16392,68518,1,0,0,0,0,0,linear programming problem +Meszaros,lpl2,3294,10881,32232,1,0,0,0,0,0,linear programming problem +Meszaros,lpl3,10828,33686,100525,1,0,0,0,0,0,linear programming problem +Meszaros,mod2,34774,66409,199810,1,0,0,0,0,0,linear programming problem +Meszaros,model1,362,798,3028,1,0,0,0,0,0,linear programming problem +Meszaros,model2,379,1321,7607,1,0,0,0,0,0,linear programming problem +Meszaros,model3,1609,4578,23974,1,0,0,0,0,0,linear programming problem +Meszaros,model4,1337,4962,45753,1,0,0,0,0,0,linear programming problem +Meszaros,model5,1888,11802,89925,1,0,0,0,0,0,linear programming problem +Meszaros,model6,2096,5289,27628,1,0,0,0,0,0,linear programming problem +Meszaros,model7,3358,9582,51027,1,0,0,0,0,0,linear programming problem +Meszaros,model8,2896,6464,25277,1,0,0,0,0,0,linear programming problem +Meszaros,model9,2879,10939,55956,1,0,0,0,0,0,linear programming problem +Meszaros,model10,4400,16819,150372,1,0,0,0,0,0,linear programming problem +Meszaros,nemsafm,334,2348,2826,1,0,0,0,0,0,linear programming problem +Meszaros,nemscem,651,1712,3840,1,0,0,0,0,0,linear programming problem +Meszaros,nemsemm1,3945,75352,1053986,1,0,0,0,0,0,linear programming problem +Meszaros,nemsemm2,6943,48878,182012,1,0,0,0,0,0,linear programming problem +Meszaros,nemspmm1,2372,8903,55867,1,0,0,0,0,0,linear programming problem +Meszaros,nemspmm2,2301,8734,68225,1,0,0,0,0,0,linear programming problem +Meszaros,nemswrld,7138,28550,192283,1,0,0,0,0,0,linear programming problem +Meszaros,nl,7039,15325,47035,1,0,0,0,0,0,linear programming problem +Meszaros,nw14,73,123409,904910,1,1,0,0,0,0,linear programming problem +Meszaros,p0033,15,48,113,1,0,0,0,0,0,linear programming problem +Meszaros,p0040,23,63,133,1,0,0,0,0,0,linear programming problem +Meszaros,p010,10090,19090,118000,1,0,0,0,0,0,linear programming problem +Meszaros,p0201,133,334,2056,1,0,0,0,0,0,linear programming problem +Meszaros,p0282,241,523,2207,1,0,0,0,0,0,linear programming problem +Meszaros,p0291,252,543,2283,1,0,0,0,0,0,linear programming problem +Meszaros,p0548,176,724,1887,1,0,0,0,0,0,linear programming problem +Meszaros,p05,5090,9590,59045,1,0,0,0,0,0,linear programming problem +Meszaros,p2756,755,3511,9692,1,0,0,0,0,0,linear programming problem +Meszaros,p6000,2095,7967,19826,1,0,0,0,0,0,linear programming problem +Meszaros,pcb1000,1565,2820,20463,1,0,0,0,0,0,linear programming problem +Meszaros,pcb3000,3960,7732,57479,1,0,0,0,0,0,linear programming problem +Meszaros,pf2177,9728,10178,30984,1,1,0,0,0,0,linear programming problem +Meszaros,primagaz,1554,10836,21665,1,0,0,0,0,0,linear programming problem +Meszaros,problem,12,46,86,1,0,0,0,0,0,linear programming problem +Meszaros,progas,1650,1900,8897,1,0,0,0,0,0,linear programming problem +Meszaros,qiulp,1192,1900,4492,1,0,0,0,0,0,linear programming problem +Meszaros,r05,5190,9690,104145,1,0,0,0,0,0,linear programming problem +Meszaros,refine,29,62,153,1,0,0,0,0,0,linear programming problem +Meszaros,rlfddd,4050,61521,264627,1,0,0,0,0,0,linear programming problem +Meszaros,rlfdual,8052,74970,282031,1,0,0,0,0,0,linear programming problem +Meszaros,rlfprim,58866,62716,320591,1,0,0,0,0,0,linear programming problem +Meszaros,rosen1,520,1544,23794,1,0,0,0,0,0,linear programming problem +Meszaros,rosen2,1032,3080,47536,1,0,0,0,0,0,linear programming problem +Meszaros,rosen7,264,776,8034,1,0,0,0,0,0,linear programming problem +Meszaros,rosen8,520,1544,16058,1,0,0,0,0,0,linear programming problem +Meszaros,rosen10,2056,6152,64192,1,0,0,0,0,0,linear programming problem +Meszaros,route,20894,43019,206782,1,0,0,0,0,0,linear programming problem +Meszaros,seymourl,4944,6316,38493,1,0,0,0,0,0,linear programming problem +Meszaros,slptsk,2861,3347,72465,1,0,0,0,0,0,linear programming problem +Meszaros,south31,18425,36321,112398,1,0,0,0,0,0,linear programming problem +Meszaros,stat96v1,5995,197472,588798,1,0,0,0,0,0,linear programming problem +Meszaros,stat96v2,29089,957432,2852184,1,0,0,0,0,0,linear programming problem +Meszaros,stat96v3,33841,1113780,3317736,1,0,0,0,0,0,linear programming problem +Meszaros,stat96v4,3173,63076,491336,1,0,0,0,0,0,linear programming problem +Meszaros,stat96v5,2307,75779,233921,1,0,0,0,0,0,linear programming problem +Meszaros,t0331-4l,664,46915,430982,1,1,0,0,0,0,linear programming problem +Meszaros,testbig,17613,31223,61639,1,0,0,0,0,0,linear programming problem +Meszaros,ulevimin,6590,46937,164538,1,0,0,0,0,0,linear programming problem +Meszaros,us04,163,28016,297538,1,1,0,0,0,0,linear programming problem +Meszaros,world,34506,67147,198883,1,0,0,0,0,0,linear programming problem +Meszaros,zed,116,142,666,1,0,0,0,0,0,linear programming problem +Meszaros,de063155,852,1848,4913,1,0,0,0,0,0,linear programming problem +Meszaros,de063157,936,1908,5119,1,0,0,0,0,0,linear programming problem +Meszaros,de080285,936,1908,5082,1,0,0,0,0,0,linear programming problem +Meszaros,gen1,769,2561,63086,1,0,0,0,0,0,linear programming problem +Meszaros,gen2,1121,3264,81855,1,0,0,0,0,0,linear programming problem +Meszaros,gen4,1537,4298,107103,1,0,0,0,0,0,linear programming problem +Meszaros,gen,769,2561,63086,1,0,0,0,0,0,linear programming problem +Meszaros,iprob,3001,3001,9000,1,0,0,0,1,0.5,linear programming problem +Meszaros,l30,2701,16281,52070,1,0,0,0,0,0,linear programming problem +Meszaros,stoch_aircraft,3754,7517,20267,1,0,0,0,0,0,linear programming problem +Meszaros,cep1,1521,4769,8233,1,0,0,0,0,0,linear programming problem +Meszaros,deter0,1923,5468,11173,1,0,0,0,0,0,linear programming problem +Meszaros,deter1,5527,15737,32187,1,0,0,0,0,0,linear programming problem +Meszaros,deter2,6095,17313,35731,1,0,0,0,0,0,linear programming problem +Meszaros,deter3,7647,21777,44547,1,0,0,0,0,0,linear programming problem +Meszaros,deter4,3235,9133,19231,1,0,0,0,0,0,linear programming problem +Meszaros,deter5,5103,14529,29715,1,0,0,0,0,0,linear programming problem +Meszaros,deter6,4255,12113,24771,1,0,0,0,0,0,linear programming problem +Meszaros,deter7,6375,18153,37131,1,0,0,0,0,0,linear programming problem +Meszaros,deter8,3831,10905,22299,1,0,0,0,0,0,linear programming problem +Meszaros,fxm2-6,1520,2845,12812,1,0,0,0,0,0,linear programming problem +Meszaros,fxm2-16,3900,7335,32972,1,0,0,0,0,0,linear programming problem +Meszaros,fxm3_6,6200,12625,57722,1,0,0,0,0,0,linear programming problem +Meszaros,fxm3_16,41340,85575,392252,1,0,0,0,0,0,linear programming problem +Meszaros,fxm4_6,22400,47185,265442,1,0,0,0,0,0,linear programming problem +Meszaros,pgp2,4034,13254,22474,1,0,0,0,0,0,linear programming problem +Meszaros,stormg2-125,66185,172431,433256,1,0,0,0,0,0,linear programming problem +Meszaros,stormg2-27,14441,37485,94274,1,0,0,0,0,0,linear programming problem +Meszaros,stormg2-8,4409,11322,28553,1,0,0,0,0,0,linear programming problem +Meszaros,degme,185501,659415,8127528,1,0,0,0,0,0,linear programming problem +Meszaros,karted,46502,133115,1770349,1,0,0,0,0,0,linear programming problem +Meszaros,tp-6,142752,1014301,11537419,1,0,0,0,0,0,linear programming problem +Meszaros,ts-palko,22002,47235,1076903,1,0,0,0,0,0,linear programming problem +Meszaros,delf,3170,6654,15397,1,0,0,0,0,0,linear programming problem sequence +Meszaros,kleemin,8,16,44,1,0,0,0,0,0,linear programming problem sequence +Meszaros,large,4282,8617,20635,1,0,0,0,0,0,linear programming problem sequence +Meszaros,nsct,23003,37563,697738,1,0,0,0,0,0,linear programming problem sequence +Meszaros,nsic,465,897,3449,1,0,0,0,0,0,linear programming problem sequence +Meszaros,nsir,4453,10057,154939,1,0,0,0,0,0,linear programming problem sequence +Meszaros,plddb,3069,5049,10839,1,0,0,0,0,0,linear programming problem sequence +Meszaros,rat,3136,9408,268908,1,0,0,0,0,0,linear programming problem sequence +Meszaros,small,677,1400,3207,1,0,0,0,0,0,linear programming problem sequence +Meszaros,pltexpa,26894,70364,143059,1,0,0,0,0,0,linear programming problem sequence +Meszaros,sc205-2r,35213,62423,123239,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scagr7-2b,9743,13847,35885,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scagr7-2c,2447,3479,9005,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scagr7-2r,32847,46679,120141,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scfxm1-2b,19036,33047,111052,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scfxm1-2r,37980,65943,221388,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scrs8-2b,1820,3499,7367,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scrs8-2c,1820,3499,7367,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scrs8-2r,14364,27691,58439,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scsd8-2b,5130,35910,112770,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scsd8-2c,5130,35910,112770,1,0,0,0,0,0,linear programming problem sequence +Meszaros,scsd8-2r,8650,60550,190210,1,0,0,0,0,0,linear programming problem sequence +Meszaros,sctap1-2b,15390,33858,99454,1,0,0,0,0,0,linear programming problem sequence +Meszaros,sctap1-2c,3390,7458,21854,1,0,0,0,0,0,linear programming problem sequence +Meszaros,sctap1-2r,28830,63426,186366,1,0,0,0,0,0,linear programming problem sequence +Gleich,wb-cs-stanford,9914,9914,36854,1,1,0,0,0.4572071438616228,0.4572071438616228,directed graph +Gleich,wb-edu,9845725,9845725,57156537,1,1,0,0,0.3281596169311674,0.3281596169311674,directed graph +Gleich,wikipedia-20051105,1634989,1634989,19753078,1,1,0,0,0.1211282592272251,0.1211282592272251,directed graph +Gleich,wikipedia-20060925,2983494,2983494,37269096,1,1,0,0,0.1182841447575249,0.1182841447575249,directed graph +Gleich,wikipedia-20061104,3148440,3148440,39383235,1,1,0,0,0.1179357318284389,0.1179357318284389,directed graph +Gleich,wikipedia-20070206,3566907,3566907,45030389,1,1,0,0,0.1171832378930545,0.1171832378930545,directed graph +UTEP,Dubcova1,16129,16129,253009,1,0,1,1,1,1,2D/3D problem +UTEP,Dubcova2,65025,65025,1030225,1,0,1,1,1,1,2D/3D problem +UTEP,Dubcova3,146689,146689,3636643,1,0,1,1,1,1,2D/3D problem +BenElechi,BenElechi1,245874,245874,13150496,1,0,1,1,1,1,2D/3D problem +Botonakis,FEM_3D_thermal1,17880,17880,430740,1,0,1,0,1,0.950733904955675,thermal problem +Botonakis,FEM_3D_thermal2,147900,147900,3489300,1,0,1,0,1,0.9502082959238642,thermal problem +Wissgott,parabolic_fem,525825,525825,3674625,1,0,1,1,1,1,computational fluid dynamics problem +Watson,chem_master1,40401,40401,201201,1,0,1,0,1,0,2D/3D problem +Watson,Baumann,112211,112211,748331,1,0,1,0,1,0,2D/3D problem +Sinclair,3Dspectralwave,680943,680943,30290827,0,0,1,0,1,1,materials problem +Sinclair,3Dspectralwave2,292008,292008,12935272,0,0,1,0,1,1,materials problem +QLi,crashbasis,160000,160000,1750416,1,0,0,0,0.5503013048158469,0.0002439613283568576,optimization problem +QLi,majorbasis,160000,160000,1750416,1,0,0,0,0.5503013048158469,0.0002376736652548767,optimization problem +Springer,ESOC,327062,37830,6019939,1,0,0,0,0,0,least squares problem +Koutsovasilis,F2,71505,71505,5294285,1,0,1,0,1,1,structural problem +Szczerba,Ill_Stokes,20896,20896,191368,1,0,1,0,0.9897436481194791,0.3299904380293234,computational fluid dynamics problem +Rajat,Raj1,263743,263743,1300261,1,0,0,0,0.998585875116119,0.5762090211971218,circuit simulation problem +Muite,Chebyshev1,261,261,2319,1,0,1,0,0.5014577259475219,0,structural problem +Muite,Chebyshev2,2053,2053,18447,1,0,1,0,0.5001829937782115,0,structural problem +Muite,Chebyshev3,4101,4101,36879,1,0,1,0,0.5000915248032217,0,structural problem +Muite,Chebyshev4,68121,68121,5377761,1,0,1,0,0.3020408163265306,0.0002369275506437348,structural problem +Quaglino,viscoplastic1,4326,4326,61166,1,0,1,0,0.7408163265306122,0,materials problem +Quaglino,viscoplastic2,32769,32769,381326,1,0,1,0,0.5699899872904575,0,materials problem +YCheng,psse0,26722,11028,102432,1,0,0,0,0,0,power network problem +YCheng,psse1,14318,11028,57376,1,0,0,0,0,0,power network problem +YCheng,psse2,28634,11028,115262,1,0,0,0,0,0,power network problem +Dehghani,light_in_tissue,29282,29282,406084,0,0,1,0,1,0,electromagnetics problem +HVDC,hvdc1,24842,24842,158426,1,0,0,0,0.9817003233707516,0.09899271099935641,power network problem +HVDC,hvdc2,189860,189860,1339638,1,0,0,0,0.9885955341075688,0.06323365458033522,power network problem +Zaoui,kkt_power,2063494,2063494,12771361,1,0,0,0,1,1,optimization problem +Rost,RFdevice,74104,74104,365580,0,0,1,0,0.0001203589980660497,0.0001148881345175929,semiconductor device problem +Lee,fem_filter,74062,74062,1731206,0,0,1,0,1,0.6131971633123011,electromagnetics problem +Mancktelow,viscorocks,37762,37762,1133641,1,0,1,0,1,0.279507135368047,materials problem +Rudnyi,water_tank,60740,60740,2035281,1,0,1,0,0.9691204183655847,0.9180067671423384,computational fluid dynamics problem +Rucci,Rucci1,1977885,109900,7791168,1,0,0,0,0,0,least squares problem +McRae,ecology1,1000000,1000000,4996000,1,0,1,0,1,1,2D/3D problem +McRae,ecology2,999999,999999,4995991,1,0,1,1,1,1,2D/3D problem +NYPA,Maragal_1,32,14,234,1,0,0,0,0,0,least squares problem +NYPA,Maragal_2,555,350,4357,1,0,0,0,0,0,least squares problem +NYPA,Maragal_3,1690,860,18391,1,0,0,0,0,0,least squares problem +NYPA,Maragal_4,1964,1034,26719,1,0,0,0,0,0,least squares problem +NYPA,Maragal_5,4654,3320,93091,1,0,0,0,0,0,least squares problem +NYPA,Maragal_6,21255,10152,537694,1,0,0,0,0,0,least squares problem +NYPA,Maragal_7,46845,26564,1200537,1,0,0,0,0,0,least squares problem +Marini,eurqsa,7245,7245,46142,1,0,0,0,1,1,economic problem +Castrillon,denormal,89400,89400,1156224,1,0,0,1,1,1,counter-example problem +QLi,largebasis,440020,440020,5240084,1,0,0,0,1,0,optimization problem +MathWorks,QRpivot,660,749,3808,1,0,0,0,0,0,counter-example problem +Luong,photogrammetry,1388,390,11816,1,0,1,0,0,0,computer graphics/vision problem +YZhou,circuit204,1020,1020,5883,1,0,0,0,0.4379791625712601,0.3727147631216827,circuit simulation problem +CEMW,t2em,921632,921632,4590832,1,0,1,0,0.9988182710127548,0.9988182710127548,electromagnetics problem +CEMW,tmt_unsym,917825,917825,4584801,1,0,1,0,1,0,electromagnetics problem +CEMW,tmt_sym,726713,726713,5080961,1,0,1,1,1,1,electromagnetics problem +CEMW,vfem,93476,93476,1434636,0,0,1,0,1,0.8209624504160578,electromagnetics problem +Schenk,nlpkkt80,1062400,1062400,28192672,1,0,0,0,1,1,optimization problem +Schenk,nlpkkt120,3542400,3542400,95117792,1,0,0,0,1,1,optimization problem +Schenk,nlpkkt160,8345600,8345600,225422112,1,0,0,0,1,1,optimization problem +Schenk,nlpkkt200,16240000,16240000,440225632,1,0,0,0,1,1,optimization problem +Schenk,nlpkkt240,27993600,27993600,760648352,1,0,0,0,1,1,optimization problem +TKK,s4dkt3m2,90449,90449,3753461,1,1,1,0,1,1,structural problem +TKK,g3rmt3m3,5357,5357,207695,1,1,1,0,1,1,structural problem +TKK,t520,5563,5563,286341,1,0,1,0,1,1,structural problem +TKK,smt,25710,25710,3749582,1,0,1,1,1,1,structural problem +TKK,engine,143571,143571,4706073,1,0,1,0,1,1,structural problem +TKK,plbuckle,1282,1282,30644,1,0,1,1,1,1,structural problem +TKK,cbuckle,13681,13681,676515,1,0,1,1,1,1,structural problem +TKK,cyl6,13681,13681,714241,1,0,1,0,1,1,structural problem +TKK,tube1,21498,21498,897056,1,1,1,0,1,1,structural problem +TKK,tube2,21498,21498,897056,1,0,1,0,1,1,structural problem +TKK,t2d_q4,9801,9801,87025,1,0,1,0,1,0.6937221589143272,structural problem sequence +TKK,t2d_q9,9801,9801,87025,1,0,1,0,1,0.6937221589143272,structural problem sequence +Luong,photogrammetry2,4472,936,37056,1,0,1,0,0,0,computer graphics/vision problem +Um,2cubes_sphere,101492,101492,1647264,1,0,1,1,1,1,electromagnetics problem +JGD_BIBD,bibd_9_3,36,84,252,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_9_5,36,126,1260,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_11_5,55,462,4620,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_12_4,66,495,2970,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_12_5,66,792,7920,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_13_6,78,1716,25740,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_14_7,91,3432,72072,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_15_3,105,455,1365,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_15_7,105,6435,135135,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_16_8,120,12870,360360,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_17_3,136,680,2040,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_17_4b,136,2380,14280,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_17_4,136,2380,14280,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_17_8,136,24310,680680,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_18_9,153,48620,1750320,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_19_9,171,92378,3325608,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_20_10,190,184756,8314020,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_22_8,231,319770,8953560,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_49_3,1176,18424,55272,1,1,0,0,0,0,combinatorial problem +JGD_BIBD,bibd_81_2,3240,3240,3240,1,1,0,1,1,1,combinatorial problem +JGD_BIBD,bibd_81_3,3240,85320,255960,1,1,0,0,0,0,combinatorial problem +JGD_CAG,CAG_mat1916,1916,1916,195985,1,0,0,0,0.3002540333592691,0.2119864584245809,combinatorial problem +JGD_CAG,CAG_mat364,364,364,13585,1,0,0,0,0.4155510173209288,0.2804628999319265,combinatorial problem +JGD_CAG,CAG_mat72,72,72,1012,1,0,0,0,0.5574468085106383,0.3340425531914893,combinatorial problem +JGD_Forest,TF10,99,107,622,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF11,216,236,1607,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF12,488,552,4231,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF13,1121,1302,11185,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF14,2644,3160,29862,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF15,6334,7742,80057,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF16,15437,19321,216173,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF17,38132,48630,586218,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF18,95368,123867,1597545,1,0,0,0,0,0,combinatorial problem +JGD_Forest,TF19,241029,317955,4370721,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz1,2240,768,5120,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz2,4032,4480,21504,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz3,1280,2800,11520,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz4,6784,5252,46528,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz5,7382,2882,44056,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz6,7576,3016,45456,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz7,10164,1740,40424,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz8,16728,7176,100368,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz9,19588,4164,97508,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz10,19588,4164,97508,1,0,0,0,0,0,combinatorial problem +JGD_Franz,Franz11,47104,30144,329728,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-6,30,77,251,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-7,62,150,549,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-8,156,292,1711,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-9,342,540,4570,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-10,652,976,10273,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-11,1227,1692,22110,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-12,2296,2875,46260,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-13,3994,4731,91209,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-14,6735,7621,173337,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-15,11369,11987,323509,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-16,18846,18485,588326,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-17,30162,27944,1035008,1,0,0,0,0,0,combinatorial problem +JGD_G5,IG5-18,47894,41550,1790490,1,0,0,0,0,0,combinatorial problem +JGD_GL6,GL6_D_6,469,201,2526,1,0,0,0,0,0,combinatorial problem +JGD_GL6,GL6_D_7,636,470,5378,1,0,0,0,0,0,combinatorial problem +JGD_GL6,GL6_D_8,544,637,6153,1,0,0,0,0,0,combinatorial problem +JGD_GL6,GL6_D_9,340,545,4349,1,0,0,0,0,0,combinatorial problem +JGD_GL6,GL6_D_10,163,341,2053,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d10,1,60,8,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d11,1019,60,1513,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d12,8899,1019,37519,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d13,47271,8899,356232,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d14,171375,47271,1831183,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d15,460261,171375,6080381,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d16,955128,460261,14488881,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d17,1548650,955128,25978098,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d18,1955309,1548650,35590540,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d19,1911130,1955309,37322725,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d20,1437547,1911130,29893084,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d21,822922,1437547,18174775,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d22,349443,822922,8251000,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d23,105054,349443,2695430,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d24,21074,105054,593892,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d25,2798,21074,81671,1,0,0,0,0,0,combinatorial problem +JGD_GL7d,GL7d26,305,2798,7412,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,c8_mat11,4562,5761,2462970,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,c8_mat11_I,4562,5761,2462970,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,f855_mat9,2456,2511,171214,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,f855_mat9_I,2456,2511,171214,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,HFE18_96_in,2372,4096,933343,1,1,0,0,0,0,combinatorial problem +JGD_Groebner,rkat7_mat5,694,738,38114,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,robot24c1_mat5,404,302,15118,1,0,0,0,0,0,combinatorial problem +JGD_Groebner,robot24c1_mat5_J,302,404,15118,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch3-3-b1,18,9,36,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch3-3-b2,6,18,18,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch4-4-b1,72,16,144,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch4-4-b2,96,72,288,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch4-4-b3,24,96,96,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch5-5-b1,200,25,400,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch5-5-b2,600,200,1800,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch5-5-b3,600,600,2400,1,0,0,0,0.02168473728106756,0.01417848206839033,combinatorial problem +JGD_Homology,ch5-5-b4,120,600,600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch6-6-b1,450,36,900,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch6-6-b2,2400,450,7200,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch6-6-b3,5400,2400,21600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch6-6-b4,4320,5400,21600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch6-6-b5,720,4320,4320,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-6-b1,630,42,1260,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-6-b2,4200,630,12600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-6-b3,12600,4200,50400,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-6-b4,15120,12600,75600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-6-b5,5040,15120,30240,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-7-b1,882,49,1764,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-7-b2,7350,882,22050,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-7-b5,35280,52920,211680,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-8-b1,1176,56,2352,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-8-b2,11760,1176,35280,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-8-b3,58800,11760,235200,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-8-b4,141120,58800,705600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-8-b5,141120,141120,846720,1,0,0,0,0.0003732057190233348,0.0002054993516141147,combinatorial problem +JGD_Homology,ch7-9-b1,1512,63,3024,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-9-b2,17640,1512,52920,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-9-b3,105840,17640,423360,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-9-b4,317520,105840,1587600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch7-9-b5,423360,317520,2540160,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch8-8-b1,1568,64,3136,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch8-8-b2,18816,1568,56448,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch8-8-b3,117600,18816,470400,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch8-8-b4,376320,117600,1881600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,ch8-8-b5,564480,376320,3386880,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b1,210,21,420,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b13,6300,25605,88200,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b14,920,6300,13800,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b15,60,920,960,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b2,1330,210,3990,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b3,5970,1330,23880,1,0,0,0,0,0,combinatorial problem +JGD_Homology,cis-n4c6-b4,20058,5970,100290,1,0,0,0,0,0,combinatorial problem +JGD_Homology,D6-6,120576,23740,146520,1,0,0,0,0,0,combinatorial problem +JGD_Homology,klein-b1,30,10,60,1,0,0,0,0,0,combinatorial problem +JGD_Homology,klein-b2,20,30,60,1,0,0,0,0,0,combinatorial problem +JGD_Homology,lutz30-23-b6,1716,3003,12012,1,0,0,0,0,0,combinatorial problem +JGD_Homology,m133-b3,200200,200200,800800,1,0,0,0,4.495504495504496e-05,2.747252747252747e-05,combinatorial problem +JGD_Homology,mk10-b1,630,45,1260,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk10-b2,3150,630,9450,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk10-b3,4725,3150,18900,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk10-b4,945,4725,4725,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk11-b1,990,55,1980,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk11-b2,6930,990,20790,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk11-b3,17325,6930,69300,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk11-b4,10395,17325,51975,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk11-b4b,9450,17325,47250,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk12-b1,1485,66,2970,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk12-b2,13860,1485,41580,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk12-b3,51975,13860,207900,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk12-b4,62370,51975,311850,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk12-b5,10395,62370,62370,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk13-b5,135135,270270,810810,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk9-b1,378,36,756,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk9-b2,1260,378,3780,1,0,0,0,0,0,combinatorial problem +JGD_Homology,mk9-b3,945,1260,3780,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b10,30,306,330,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b1,105,15,210,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b2,455,105,1365,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b3,1365,455,5460,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b4,3003,1365,15015,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b5,4945,3003,29670,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b6,5715,4945,40005,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b7,3990,5715,31920,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b8,1470,3990,13230,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n2c6-b9,306,1470,3060,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c4-b1,15,6,30,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c4-b2,20,15,60,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c4-b3,15,20,60,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c4-b4,6,15,30,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b1,45,10,90,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b2,120,45,360,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b3,210,120,840,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b4,252,210,1260,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b5,210,252,1260,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b6,120,210,840,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c5-b7,30,120,240,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b10,675,2511,7425,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b1,105,105,210,1,0,0,0,0.08571428571428572,0.0761904761904762,combinatorial problem +JGD_Homology,n3c6-b11,60,675,720,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b2,455,105,1365,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b3,1365,455,5460,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b4,3003,1365,15015,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b5,5005,3003,30030,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b6,6435,5005,45045,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b7,6435,6435,51480,1,0,0,0,1,0.5333333333333333,combinatorial problem +JGD_Homology,n3c6-b8,4935,6435,44415,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n3c6-b9,2511,4935,25110,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b10,120,630,1320,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b1,105,15,210,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b11,10,120,120,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b2,455,105,1365,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b3,1350,455,5400,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b4,2852,1350,14260,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b5,4340,2852,26040,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b6,4735,4340,33145,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b7,3635,4735,29080,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b8,1895,3635,17055,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c5-b9,630,1895,6300,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b10,132402,186558,1456422,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b11,69235,132402,830820,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b1,210,21,420,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b12,25605,69235,332865,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b13,6300,25605,88200,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b14,920,6300,13800,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b15,60,920,960,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b2,1330,210,3990,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b3,5970,1330,23880,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b4,20058,5970,100290,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b5,51813,20058,310878,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b6,104115,51813,728805,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b7,163215,104115,1305720,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b8,198895,163215,1790055,1,0,0,0,0,0,combinatorial problem +JGD_Homology,n4c6-b9,186558,198895,1865580,1,0,0,0,0,0,combinatorial problem +JGD_Homology,shar_te2-b1,17160,286,34320,1,0,0,0,0,0,combinatorial problem +JGD_Homology,shar_te2-b2,200200,17160,600600,1,0,0,0,0,0,combinatorial problem +JGD_Homology,shar_te2-b3,200200,200200,800800,1,0,0,0,7.492516848797264e-05,2.997006739518906e-05,combinatorial problem +QY,case39,40216,40216,1042160,1,0,0,0,1,1,power network problem sequence +JGD_Kocay,Trec3,1,2,1,1,1,0,0,0,0,combinatorial problem +JGD_Kocay,Trec4,2,3,3,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec5,3,7,12,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec6,6,15,40,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec7,11,36,147,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec8,23,84,549,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec9,47,201,2147,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec10,106,478,8612,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec11,235,1138,35705,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec12,551,2726,151219,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec13,1301,6561,654517,1,0,0,0,0,0,combinatorial problem +JGD_Kocay,Trec14,3159,15905,2872265,1,0,0,0,0,0,combinatorial problem +JGD_Margulies,cat_ears_2_1,85,85,254,1,1,0,0,0.03252032520325204,0.03252032520325204,combinatorial problem +JGD_Margulies,cat_ears_2_4,1009,2689,7982,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,cat_ears_3_1,204,181,542,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,cat_ears_3_4,5226,13271,39592,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,cat_ears_4_1,377,313,938,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,cat_ears_4_4,19020,44448,132888,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_4_1,121,129,386,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_4_4,1837,5529,16466,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_5_1,211,201,602,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_5_4,5226,14721,43942,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_7_1,463,393,1178,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_7_4,27693,67593,202218,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_8_1,625,513,1538,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,flower_8_4,55081,125361,375266,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,kneser_10_4_1,349651,330751,992252,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,kneser_6_2_1,601,676,2027,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,kneser_8_3_1,15737,15681,47042,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_3_1,21,25,74,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_4_1,36,41,122,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_5_1,57,61,182,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_601,902103,723605,2170814,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_6_1,83,85,254,1,1,0,0,0,0,combinatorial problem +JGD_Margulies,wheel_7_1,114,113,338,1,1,0,0,0,0,combinatorial problem +JGD_Relat,rel3,12,5,18,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel4,66,12,104,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel5,340,35,656,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel6,2340,157,5101,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel7,21924,1045,50636,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel8,345688,12347,821839,1,0,0,0,0,0,combinatorial problem +JGD_Relat,rel9,9888048,274669,23667183,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat3,12,5,24,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat4,66,12,172,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat5,340,35,1058,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat6,2340,157,8108,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat7b,21924,1045,81355,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat7,21924,1045,81355,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat8,345688,12347,1334038,1,0,0,0,0,0,combinatorial problem +JGD_Relat,relat9,12360060,549336,38955420,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_5,434,115,1832,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_6,970,435,6491,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_7,1270,971,12714,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_8,1132,1271,14966,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_9,815,1133,12395,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_10,460,816,7614,1,0,0,0,0,0,combinatorial problem +JGD_SL6,D_11,169,461,2952,1,0,0,0,0,0,combinatorial problem +JGD_SPG,08blocks,300,300,592,1,0,0,0,0.0273972602739726,0,combinatorial problem +JGD_SPG,EX1,560,560,8736,1,1,0,0,1,1,combinatorial problem +JGD_SPG,EX2,560,560,8736,1,1,0,0,1,1,combinatorial problem +JGD_SPG,EX3,2600,2600,71760,1,1,0,0,1,1,combinatorial problem +JGD_SPG,EX4,2600,2600,71760,1,1,0,0,1,1,combinatorial problem +JGD_SPG,EX5,6545,6545,295680,1,1,0,0,1,1,combinatorial problem +JGD_SPG,EX6,6545,6545,295680,1,1,0,0,1,1,combinatorial problem +JGD_Taha,abtaha2,37932,331,137228,1,0,0,0,0,0,combinatorial problem +JGD_Taha,abtaha1,14596,209,51307,1,0,0,0,0,0,combinatorial problem +JGD_Trefethen,Trefethen_20b,19,19,147,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_20,20,20,158,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_150,150,150,2040,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_200b,199,199,2873,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_200,200,200,2890,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_300,300,300,4678,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_500,500,500,8478,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_700,700,700,12654,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_2000,2000,2000,41906,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_20000b,19999,19999,554435,1,0,0,1,1,1,combinatorial problem +JGD_Trefethen,Trefethen_20000,20000,20000,554466,1,0,0,1,1,1,combinatorial problem +QY,case9,14454,14454,147972,1,0,0,0,1,1,power network problem sequence +FreeFieldTechnologies,mono_500Hz,169410,169410,5033796,0,0,1,0,1,0.820796293715178,acoustics problem +Freescale,Freescale1,3428755,3428755,17052626,1,0,0,0,0.9061379876258038,0.3945743467477048,circuit simulation problem +NYPA,Maragal_8,33212,75077,1308415,1,0,0,0,0,0,least squares problem +Bates,sls,1748122,62729,6804304,1,0,0,0,0,0,least squares problem +TSOPF,TSOPF_RS_b2383,38120,38120,16171169,1,0,0,0,0.002485718029041526,0.0003350401831305099,power network problem +TSOPF,TSOPF_FS_b300,29214,29214,4400122,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b162_c1,10798,10798,608540,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b162_c3,30798,30798,1801300,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b162_c4,40798,40798,2398220,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b300_c1,29214,29214,4400122,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b300_c2,56814,56814,8767466,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b300_c3,84414,84414,13135930,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b39_c19,76216,76216,1977600,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b39_c30,120216,120216,3121160,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b39_c7,28216,28216,730080,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b9_c1,2454,2454,25032,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_FS_b9_c6,14454,14454,147972,1,0,0,0,1,1,power network problem +TSOPF,TSOPF_RS_b162_c1,5374,5374,205399,1,0,0,0,0.02981942459702805,0.002418331351367556,power network problem +TSOPF,TSOPF_RS_b162_c3,15374,15374,610299,1,0,0,0,0.02683526094131803,0.0008133934303355415,power network problem +TSOPF,TSOPF_RS_b162_c4,20374,20374,812749,1,0,0,0,0.02645844479664045,0.0006107347997698388,power network problem +TSOPF,TSOPF_RS_b2052_c1,25626,25626,6761100,1,0,0,0,0.003886561090908282,0.0002050869579089441,power network problem +TSOPF,TSOPF_RS_b2383_c1,38120,38120,16171169,1,0,0,0,0.002485718029041526,0.0003350401831305099,power network problem +TSOPF,TSOPF_RS_b300_c1,14538,14538,1474325,1,0,0,0,0.01034334678703541,0.0003506683588241378,power network problem +TSOPF,TSOPF_RS_b300_c2,28338,28338,2943887,1,0,0,0,0.00991209710027776,0.0001755931670937033,power network problem +TSOPF,TSOPF_RS_b300_c3,42138,42138,4413449,1,0,0,0,0.009768063952888569,0.0001171197776188222,power network problem +TSOPF,TSOPF_RS_b39_c19,38098,38098,684206,1,0,0,0,0.05914025923776359,0.0001300058038305281,power network problem +TSOPF,TSOPF_RS_b39_c30,60098,60098,1079986,1,0,0,0,0.05903687108113011,8.236061201778597e-05,power network problem +TSOPF,TSOPF_RS_b39_c7,14098,14098,252446,1,0,0,0,0.05962284731399325,0.0003524007299729407,power network problem +TSOPF,TSOPF_RS_b678_c1,18696,18696,4396289,1,0,0,0,0.004448301852317109,0.0003256971884064591,power network problem +TSOPF,TSOPF_RS_b678_c2,35696,35696,8781949,1,0,0,0,0.004170134538170976,0.0001630280691806068,power network problem +TSOPF,TSOPF_RS_b9_c6,7224,7224,54082,1,0,0,0,0.1544436146377894,0.0002560546249866638,power network problem +Lee,fem_hifreq_circuit,491100,491100,20239237,0,0,1,0,0.999999037883928,0.4990933575151925,electromagnetics problem +Buss,connectus,512,394792,1127525,1,1,0,0,0,0,undirected bipartite graph +Yoshiyasu,image_interp,240000,120000,711683,1,0,1,0,0,0,computer graphics/vision problem +Yoshiyasu,mesh_deform,234023,9393,853829,1,0,1,0,0,0,computer graphics/vision problem +Priebel,130bit,584,575,6120,1,1,0,0,0,0,combinatorial problem +Priebel,145bit,1002,993,11315,1,1,0,0,0,0,combinatorial problem +Priebel,162bit,3606,3597,37118,1,1,0,0,0,0,combinatorial problem +Priebel,176bit,7441,7431,82270,1,1,0,0,0,0,combinatorial problem +Priebel,192bit,13691,13682,154303,1,1,0,0,0,0,combinatorial problem +Priebel,208bit,24430,24421,299756,1,1,0,0,0,0,combinatorial problem +MathWorks,TS,2142,2142,45262,1,0,0,0,0.9525732031943213,0.04130434782608695,counter-example problem +Botonakis,thermomech_TC,102158,102158,711558,1,0,1,1,1,1,thermal problem +Botonakis,thermomech_TK,102158,102158,711558,1,0,1,1,1,1,thermal problem +Botonakis,thermomech_dM,204316,204316,1423116,1,0,1,1,1,1,thermal problem +Botonakis,thermomech_dK,204316,204316,2846228,1,0,1,0,1,0.6652727267221619,thermal problem +MaxPlanck,shallow_water1,81920,81920,327680,1,0,1,1,1,1,computational fluid dynamics problem +MaxPlanck,shallow_water2,81920,81920,327680,1,0,1,1,1,1,computational fluid dynamics problem +Buss,12month1,12471,872622,22624727,1,1,0,0,0,0,undirected bipartite graph +Clark,tomographic1,73159,59498,647495,1,0,1,0,0,0,computer graphics/vision problem +Bourchtein,atmosmodd,1270432,1270432,8814880,1,0,1,0,1,0.6690207156308852,computational fluid dynamics problem +Bourchtein,atmosmodj,1270432,1270432,8814880,1,0,1,0,1,0.6690207156308852,computational fluid dynamics problem +Bourchtein,atmosmodl,1489752,1489752,10319760,1,0,1,0,1,0.6714503542918647,computational fluid dynamics problem +Bourchtein,atmosmodm,1489752,1489752,10319760,1,0,1,0,1,0.6714503542918647,computational fluid dynamics problem +Puri,ABACUS_shell_ud,23412,23412,218484,1,0,1,0,1,0.9753731955380578,model reduction problem +Puri,ABACUS_shell_ld,23412,23412,218484,0,0,1,0,1,0.8850885826771654,model reduction problem +Puri,ABACUS_shell_md,23412,23412,218484,0,0,1,0,1,0.8850885826771654,model reduction problem +Puri,ABACUS_shell_hd,23412,23412,218484,0,0,1,0,1,0.8850885826771654,model reduction problem +Stevenson,LargeRegFile,2111154,801374,4944201,1,0,0,0,0,0,circuit simulation problem +Freescale,memchip,2707524,2707524,13343948,1,0,0,0,0.9058013004223939,0.4015860962358702,circuit simulation problem +Freescale,transient,178866,178866,961368,1,0,0,0,0.9996742983044353,0.243597788123496,circuit simulation problem +Freescale,circuit5M,5558326,5558326,59524291,1,0,0,0,0.9999998517635799,0.4198865531852634,circuit simulation problem +Freescale,circuit5M_dc,3523317,3523317,14865409,1,0,0,0,0.9072118240231114,0.7150571517141635,circuit simulation problem +Grund,poli3,16955,16955,37849,1,0,0,0,0.00507322676366421,0.0005743275581506652,economic problem +Grund,poli4,33833,33833,73249,1,0,0,0,0.003551857113862391,0.0002029632636492795,economic problem +Belcastro,human_gene1,22283,22283,24669643,1,0,0,0,1,1,undirected weighted graph +Belcastro,human_gene2,14340,14340,18068388,1,0,0,0,1,1,undirected weighted graph +Belcastro,mouse_gene,45101,45101,28967291,1,0,0,0,1,1,undirected weighted graph +Um,offshore,259789,259789,4242673,1,0,1,1,1,1,electromagnetics problem +SNAP,soc-Epinions1,75888,75888,508837,1,1,0,0,0.405226035056413,0.405226035056413,directed graph +SNAP,soc-LiveJournal1,4847571,4847571,68993773,1,1,0,0,0.7484193555024753,0.7484193555024753,directed graph +SNAP,soc-Slashdot0811,77360,77360,905468,1,1,0,0,0.8669352939826918,0.8669352939826918,directed graph +SNAP,soc-Slashdot0902,82168,82168,948464,1,1,0,0,0.8410650442849082,0.8410650442849082,directed graph +SNAP,wiki-Vote,8297,8297,103689,1,1,0,0,0.0564572905515532,0.0564572905515532,directed graph +SNAP,email-EuAll,265214,265214,420045,1,1,0,0,0.2600511748250413,0.2600511748250413,directed graph +SNAP,email-Enron,36692,36692,367662,1,1,0,0,1,1,directed graph +SNAP,wiki-Talk,2394385,2394385,5021410,1,1,0,0,0.1441208744157517,0.1441208744157517,directed graph +SNAP,cit-HepPh,34546,34546,421578,1,1,0,0,0.003117186276789061,0.003117186276789061,directed graph +SNAP,cit-HepTh,27770,27770,352807,1,1,0,0,0.002738343613933237,0.002738343613933237,directed graph +SNAP,cit-Patents,3774768,3774768,16518948,1,1,0,0,0,0,directed graph +SNAP,ca-AstroPh,18772,18772,396160,1,1,0,0,1,1,undirected graph +SNAP,ca-CondMat,23133,23133,186936,1,1,0,0,1,1,undirected graph +SNAP,ca-GrQc,5242,5242,28980,1,1,0,0,1,1,undirected graph +SNAP,ca-HepPh,12008,12008,237010,1,1,0,0,1,1,undirected graph +SNAP,ca-HepTh,9877,9877,51971,1,1,0,0,1,1,undirected graph +SNAP,web-BerkStan,685230,685230,7600595,1,1,0,0,0.2502764586193581,0.2502764586193581,directed graph +SNAP,web-Google,916428,916428,5105039,1,1,0,0,0.3067510355944391,0.3067510355944391,directed graph +SNAP,web-NotreDame,325729,325729,1497134,1,1,0,0,0.5165359238309862,0.5165359238309862,directed graph +SNAP,web-Stanford,281903,281903,2312497,1,1,0,0,0.2766368994208425,0.2766368994208425,directed graph +SNAP,amazon0302,262111,262111,1234877,1,1,0,0,0.5427018237443891,0.5427018237443891,directed graph +SNAP,amazon0312,400727,400727,3200440,1,1,0,0,0.5315337891039982,0.5315337891039982,directed graph +SNAP,amazon0505,410236,410236,3356824,1,1,0,0,0.5465803390347542,0.5465803390347542,directed graph +SNAP,amazon0601,403394,403394,3387388,1,1,0,0,0.5573497928197183,0.5573497928197183,directed graph +SNAP,p2p-Gnutella04,10879,10879,39994,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella05,8846,8846,31839,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella06,8717,8717,31525,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella08,6301,6301,20777,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella09,8114,8114,26013,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella24,26518,26518,65369,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella25,22687,22687,54705,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella30,36682,36682,88328,1,1,0,0,0,0,directed graph +SNAP,p2p-Gnutella31,62586,62586,147892,1,1,0,0,0,0,directed graph +SNAP,roadNet-CA,1971281,1971281,5533214,1,1,0,0,1,1,undirected graph +SNAP,roadNet-PA,1090920,1090920,3083796,1,1,0,0,1,1,undirected graph +SNAP,roadNet-TX,1393383,1393383,3843320,1,1,0,0,1,1,undirected graph +SNAP,as-735,7716,7716,26467,1,1,0,0,1,1,undirected graph sequence +SNAP,as-Skitter,1696415,1696415,22190596,1,1,0,0,1,1,undirected graph +SNAP,as-caida,31379,31379,106762,1,0,0,0,1,0.07869841329311927,directed weighted graph sequence +SNAP,Oregon-1,11492,11492,46818,1,1,0,0,1,1,undirected graph sequence +SNAP,Oregon-2,11806,11806,65460,1,1,0,0,1,1,undirected graph sequence +SNAP,soc-sign-epinions,131828,131828,841372,1,0,0,0,0.3082520316984202,0.3018224331855771,directed weighted graph +SNAP,soc-sign-Slashdot081106,77357,77357,516575,1,0,0,0,0.1859207278710739,0.1786110438948846,directed weighted graph +SNAP,soc-sign-Slashdot090216,81871,81871,545671,1,0,0,0,0.175926519826049,0.168574104176326,directed weighted graph +SNAP,soc-sign-Slashdot090221,82144,82144,549202,1,0,0,0,0.1774246998372184,0.1703271291801559,directed weighted graph +Dziekonski,gsm_106857,589446,589446,21758924,1,0,1,0,1,1,electromagnetics problem +Gleich,flickr,820878,820878,9837214,1,1,0,0,0.653017002578169,0.653017002578169,directed graph +Gleich,minnesota,2642,2642,6606,1,1,0,0,1,1,undirected graph +Gleich,usroads-48,126146,126146,323900,1,1,0,0,1,1,undirected graph +Gleich,usroads,129164,129164,330870,1,1,0,0,1,1,undirected graph +Fluorem,DK01R,903,903,11766,1,0,1,0,0.9614287029365737,0,computational fluid dynamics problem +Fluorem,GT01R,7980,7980,430909,1,0,1,0,0.8811455350661695,9.457852263618717e-06,computational fluid dynamics problem +Fluorem,PR02R,161070,161070,8185136,1,0,1,0,0.9476492341912441,0.0001697393815055858,computational fluid dynamics problem +Fluorem,RM07R,381689,381689,37464962,1,0,1,0,0.9261667922354103,4.260681089287885e-06,computational fluid dynamics problem +Rommes,ww_36_pmec_36,66,66,1194,1,0,1,0,0.3339191564147627,0,eigenvalue/model reduction problem +Rommes,ww_vref_6405,13251,13251,48737,1,0,1,0,0.707540090603374,0.5856980072816208,eigenvalue/model reduction problem +Rommes,xingo_afonso_itaipu,13250,13250,48735,1,0,1,0,0.7075597554196776,0.5857142857142857,eigenvalue/model reduction problem +Rommes,mimo8x8_system,13309,13309,48872,1,0,1,0,0.7060291752177048,0.5844472793832159,eigenvalue/model reduction problem +Rommes,mimo28x28_system,13251,13251,48737,1,0,1,0,0.707540090603374,0.5856980072816208,eigenvalue/model reduction problem +Rommes,mimo46x46_system,13250,13250,48735,1,0,1,0,0.7075597554196776,0.5857142857142857,eigenvalue/model reduction problem +Rommes,juba40k,40337,40337,144945,1,0,1,0,0.6934462083788981,0.5830536596402579,eigenvalue/model reduction problem +Rommes,bauru5727,40366,40366,145019,1,0,1,0,0.6931521565005984,0.5828064190876452,eigenvalue/model reduction problem +Rommes,zeros_nopss_13k,13296,13296,48827,1,0,1,0,0.7083056110002218,0.5842204479929031,eigenvalue/model reduction problem +Rommes,descriptor_xingo6u,20738,20738,73916,1,0,1,0,0.6848202865775669,0.5745268504272713,eigenvalue/model reduction problem +Rommes,nopss_11k,11685,11685,44941,1,0,1,0,0.7502077151335311,0.6233827893175075,eigenvalue/model reduction problem +Rommes,xingo3012,20944,20944,74386,1,0,1,0,0.681002526603102,0.5712336093539642,eigenvalue/model reduction problem +Rommes,bips98_606,7135,7135,34738,1,0,1,0,0.9086859688195991,0.7583878152166104,eigenvalue/model reduction problem +Rommes,bips98_1142,9735,9735,40983,1,0,1,0,0.8020552507215579,0.6694154587839767,eigenvalue/model reduction problem +Rommes,bips98_1450,11305,11305,44678,1,0,1,0,0.7593684272891549,0.6277809047012471,eigenvalue/model reduction problem +Rommes,bips07_1693,13275,13275,49044,1,0,1,0,0.706761938919083,0.5845449278560985,eigenvalue/model reduction problem +Rommes,bips07_1998,15066,15066,62198,1,0,1,0,0.7978660841804587,0.6687809795849786,eigenvalue/model reduction problem +Rommes,bips07_2476,16861,16861,66498,1,0,1,0,0.7574573297176583,0.6349098739830914,eigenvalue/model reduction problem +Rommes,bips07_3078,21128,21128,75729,1,0,1,0,0.6861363964744979,0.5750975292587777,eigenvalue/model reduction problem +Rommes,M10PI_n1,528,528,1317,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,M20PI_n1,1028,1028,2547,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,M40PI_n1,2028,2028,5007,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,M80PI_n1,4028,4028,9927,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,M10PI_n,682,682,1633,1,0,1,0,1,0.1132075471698113,eigenvalue/model reduction problem +Rommes,M20PI_n,1182,1182,2881,1,0,1,0,1,0.04173622704507512,eigenvalue/model reduction problem +Rommes,M40PI_n,2182,2182,5341,1,0,1,0,1,0.02274795268425842,eigenvalue/model reduction problem +Rommes,M80PI_n,4182,4182,10261,1,0,1,0,1,0.01191043353978085,eigenvalue/model reduction problem +Rommes,S10PI_n1,528,528,1317,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,S20PI_n1,1028,1028,2547,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,S40PI_n1,2028,2028,5007,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,S80PI_n1,4028,4028,9927,1,0,1,0,1,0,eigenvalue/model reduction problem +Rommes,S10PI_n,682,682,1633,1,0,1,0,1,0.1132075471698113,eigenvalue/model reduction problem +Rommes,S20PI_n,1182,1182,2881,1,0,1,0,1,0.04173622704507512,eigenvalue/model reduction problem +Rommes,S40PI_n,2182,2182,5341,1,0,1,0,1,0.02274795268425842,eigenvalue/model reduction problem +Rommes,S80PI_n,4182,4182,10261,1,0,1,0,1,0.01191043353978085,eigenvalue/model reduction problem +Williams,pdb1HYS,36417,36417,4344765,1,0,0,1,1,1,weighted undirected graph +Williams,consph,83334,83334,6010480,1,0,1,1,1,1,2D/3D problem +Williams,cant,62451,62451,4007383,1,0,1,1,1,1,2D/3D problem +Williams,mac_econ_fwd500,206500,206500,1273389,1,0,0,0,0.05995735832675801,0.005599217836274841,economic problem +Williams,mc2depi,525825,525825,2100225,1,0,1,0,0,0,2D/3D problem +Williams,cop20k_A,121192,121192,2624331,1,0,1,0,1,1,2D/3D problem +Williams,webbase-1M,1000005,1000005,3105536,1,0,0,0,0.09552554676231316,0.01588957844838191,weighted directed graph +Freescale,FullChip,2987012,2987012,26621983,1,0,0,0,0.9999996192108144,0.005614865134161801,circuit simulation problem +Dattorro,EternityII_E,11077,262144,1503732,1,0,0,0,0,0,optimization problem +Dattorro,EternityII_Etilde,10054,204304,1170516,1,0,0,0,0,0,optimization problem +Dattorro,EternityII_A,7362,150638,782087,1,0,0,0,0,0,optimization problem +Fluorem,HV15R,2017169,2017169,283073458,1,0,1,0,0.8446615474952066,0.0007082780488857875,computational fluid dynamics problem +Dziekonski,dielFilterV2clx,607232,607232,25309272,0,0,1,0,1,0.9712899015627859,electromagnetics problem +Dziekonski,dielFilterV2real,1157456,1157456,48538952,1,0,1,0,1,1,electromagnetics problem +Dziekonski,dielFilterV3clx,420408,420408,32886208,0,0,1,0,1,0.8873627016737613,electromagnetics problem +Dziekonski,dielFilterV3real,1102824,1102824,89306020,1,0,1,0,1,1,electromagnetics problem +Newman,adjnoun,112,112,850,1,1,0,0,1,1,undirected graph +Newman,as-22july06,22963,22963,96872,1,1,0,0,1,1,undirected graph +Newman,astro-ph,16706,16706,242502,1,0,0,0,1,1,undirected weighted graph +Newman,celegansneural,297,297,2345,1,0,0,0,0.1680170575692964,0.04946695095948828,directed weighted graph +Newman,cond-mat,16726,16726,95188,1,0,0,0,1,1,undirected weighted graph +Newman,cond-mat-2003,31163,31163,240058,1,0,0,0,1,1,undirected weighted graph +Newman,cond-mat-2005,40421,40421,351382,1,0,0,0,1,1,undirected weighted graph +Newman,dolphins,62,62,318,1,1,0,0,1,1,undirected graph +Newman,football,115,115,1226,1,0,0,0,1,1,undirected multigraph +Newman,hep-th,8361,8361,31502,1,0,0,0,1,1,undirected weighted graph +Newman,karate,34,34,156,1,1,0,0,1,1,undirected graph +Newman,lesmis,77,77,508,1,0,0,0,1,1,undirected weighted graph +Newman,netscience,1589,1589,5484,1,0,0,0,1,1,undirected weighted graph +Newman,polblogs,1490,1490,19025,1,0,0,0,0.242561244874356,0.2414046893071181,directed multigraph +Newman,polbooks,105,105,882,1,1,0,0,1,1,undirected graph +Newman,power,4941,4941,13188,1,1,0,0,1,1,undirected graph +Arenas,PGPgiantcompo,10680,10680,48632,1,0,0,0,1,1,undirected multigraph +Arenas,jazz,198,198,5484,1,0,0,0,1,1,undirected multigraph +Arenas,celegans_metabolic,453,453,4065,1,0,0,0,1,1,undirected multigraph +Arenas,email,1133,1133,10902,1,1,0,0,1,1,undirected graph +AG-Monien,3elt,4720,4720,27444,1,1,1,0,1,1,2D/3D problem +AG-Monien,3elt_dual,9000,9000,26556,1,1,1,0,1,1,2D/3D problem +AG-Monien,airfoil1,4253,4253,24578,1,1,1,0,1,1,2D/3D problem +AG-Monien,airfoil1_dual,8034,8034,23626,1,1,1,0,1,1,2D/3D problem +AG-Monien,big_dual,30269,30269,89858,1,1,1,0,1,1,2D/3D problem +AG-Monien,crack,10240,10240,60760,1,1,1,0,1,1,2D/3D problem +AG-Monien,crack_dual,20141,20141,60086,1,1,1,0,1,1,2D/3D problem +AG-Monien,grid1,252,252,952,1,1,1,0,1,1,2D/3D problem +AG-Monien,grid1_dual,224,224,840,1,1,1,0,1,1,2D/3D problem +AG-Monien,grid2,3296,3296,12864,1,1,1,0,1,1,2D/3D problem +AG-Monien,grid2_dual,3136,3136,12224,1,1,1,0,1,1,2D/3D problem +AG-Monien,netz4504,1961,1961,5156,1,1,1,0,1,1,2D/3D problem +AG-Monien,netz4504_dual,615,615,2342,1,1,1,0,1,1,2D/3D problem +AG-Monien,ukerbe1,5981,5981,15704,1,1,1,0,1,1,2D/3D problem +AG-Monien,ukerbe1_dual,1866,1866,7076,1,1,1,0,1,1,2D/3D problem +AG-Monien,whitaker3,9800,9800,57978,1,1,1,0,1,1,2D/3D problem +AG-Monien,whitaker3_dual,19190,19190,57162,1,1,1,0,1,1,2D/3D problem +AG-Monien,brack2,62631,62631,733118,1,1,1,0,1,1,2D/3D problem +AG-Monien,wave,156317,156317,2118662,1,1,1,0,1,1,2D/3D problem +AG-Monien,diag,2559,2559,8184,1,1,1,0,1,1,2D/3D problem +AG-Monien,L,956,956,3640,1,1,1,0,1,1,2D/3D problem +AG-Monien,L-9,17983,17983,71192,1,1,1,0,1,1,2D/3D problem +AG-Monien,stufe,1036,1036,3736,1,1,1,0,1,1,2D/3D problem +AG-Monien,stufe-10,24010,24010,92828,1,1,1,0,1,1,2D/3D problem +AG-Monien,biplane-9,21701,21701,84076,1,1,1,0,1,1,2D/3D problem +AG-Monien,shock-9,36476,36476,142580,1,1,1,0,1,1,2D/3D problem +AG-Monien,bfly,49152,49152,196608,1,1,0,0,1,1,undirected graph sequence +AG-Monien,cage,366,366,5124,1,1,0,0,1,1,undirected graph sequence +AG-Monien,cca,49152,49152,139264,1,1,0,0,1,1,undirected graph sequence +AG-Monien,ccc,49152,49152,147456,1,1,0,0,1,1,undirected graph sequence +AG-Monien,debr,1048576,1048576,4194298,1,1,0,0,1,1,undirected graph sequence +AG-Monien,se,32768,32768,98300,1,1,0,0,1,1,undirected graph sequence +LAW,cnr-2000,325557,325557,3216152,1,1,0,0,0.2491384628169437,0.2491384628169437,directed graph +LAW,in-2004,1382908,1382908,16917053,1,1,0,0,0.3564974165403691,0.3564974165403691,directed graph +LAW,eu-2005,862664,862664,19235140,1,1,0,0,0.277066804642518,0.277066804642518,directed graph +LAW,enron,69244,69244,276143,1,1,0,0,0.1468201946046729,0.1468201946046729,directed graph +LAW,amazon-2008,735323,735323,5158388,1,1,0,0,0.6338864001699756,0.6338864001699756,directed graph +LAW,ljournal-2008,5363260,5363260,79023142,1,1,0,0,0.7302651670539438,0.7302651670539438,directed graph +LAW,hollywood-2009,1139905,1139905,113891327,1,1,0,-1,1,1,undirected graph +LAW,dblp-2010,326186,326186,1615400,1,1,0,0,1,1,undirected graph +LAW,webbase-2001,118142155,118142155,1019903190,1,1,0,0,0.2780598082364509,0.2780598082364509,directed graph +LAW,uk-2002,18520486,18520486,298113762,1,1,0,0,0.2084315853924949,0.2084315853924949,directed graph +LAW,indochina-2004,7414866,7414866,194109311,1,1,0,0,0.4240142027924715,0.4240142027924715,directed graph +LAW,it-2004,41291594,41291594,1150725436,1,1,0,0,0.1906175218924703,0.1906175218924703,directed graph +LAW,arabic-2005,22744080,22744080,639999458,1,1,0,0,0.2447917196533005,0.2447917196533005,directed graph +LAW,sk-2005,50636154,50636154,1949412601,1,1,0,0,0.1245713694644861,0.1245713694644861,directed graph +LAW,uk-2005,39459925,39459925,936364282,1,1,0,0,0.3002522210250522,0.3002522210250522,directed graph +DIMACS10,caidaRouterLevel,192244,192244,1218132,1,1,0,0,1,1,undirected graph +DIMACS10,chesapeake,39,39,340,1,1,0,0,1,1,undirected graph +DIMACS10,road_central,14081816,14081816,33866826,1,1,0,0,1,1,undirected graph +DIMACS10,road_usa,23947347,23947347,57708624,1,1,0,0,1,1,undirected graph +DIMACS10,citationCiteseer,268495,268495,2313294,1,1,0,0,1,1,undirected graph +DIMACS10,coAuthorsCiteseer,227320,227320,1628268,1,1,0,0,1,1,undirected graph +DIMACS10,coAuthorsDBLP,299067,299067,1955352,1,1,0,0,1,1,undirected graph +DIMACS10,coPapersCiteseer,434102,434102,32073440,1,1,0,0,1,1,undirected graph +DIMACS10,coPapersDBLP,540486,540486,30491458,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n10,1024,1024,6112,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n11,2048,2048,12254,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n12,4096,4096,24528,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n13,8192,8192,49094,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n14,16384,16384,98244,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n15,32768,32768,196548,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n16,65536,65536,393150,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n17,131072,131072,786352,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n18,262144,262144,1572792,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n19,524288,524288,3145646,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n20,1048576,1048576,6291372,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n21,2097152,2097152,12582816,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n22,4194304,4194304,25165738,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n23,8388608,8388608,50331568,1,1,0,0,1,1,undirected graph +DIMACS10,delaunay_n24,16777216,16777216,100663202,1,1,0,0,1,1,undirected graph +DIMACS10,hugebubbles-00000,18318143,18318143,54940162,1,1,0,0,1,1,undirected graph +DIMACS10,hugebubbles-00010,19458087,19458087,58359528,1,1,0,0,1,1,undirected graph +DIMACS10,hugebubbles-00020,21198119,21198119,63580358,1,1,0,0,1,1,undirected graph +DIMACS10,hugetrace-00000,4588484,4588484,13758266,1,1,0,0,1,1,undirected graph +DIMACS10,hugetrace-00010,12057441,12057441,36164358,1,1,0,0,1,1,undirected graph +DIMACS10,hugetrace-00020,16002413,16002413,47997626,1,1,0,0,1,1,undirected graph +DIMACS10,hugetric-00000,5824554,5824554,17467046,1,1,0,0,1,1,undirected graph +DIMACS10,hugetric-00010,6592765,6592765,19771708,1,1,0,0,1,1,undirected graph +DIMACS10,hugetric-00020,7122792,7122792,21361554,1,1,0,0,1,1,undirected graph +DIMACS10,kron_g500-logn16,65536,65536,4912469,1,0,0,0,1,1,undirected multigraph +DIMACS10,kron_g500-logn17,131072,131072,10228360,1,0,0,0,1,1,undirected multigraph +DIMACS10,kron_g500-logn18,262144,262144,21165908,1,0,0,0,1,1,undirected multigraph +DIMACS10,kron_g500-logn19,524288,524288,43562265,1,0,0,0,1,1,undirected multigraph +DIMACS10,kron_g500-logn20,1048576,1048576,89239674,1,0,0,0,1,1,undirected multigraph +DIMACS10,kron_g500-logn21,2097152,2097152,182082942,1,0,0,0,1,1,undirected multigraph +DIMACS10,adaptive,6815744,6815744,27248640,1,1,0,0,1,1,undirected graph +DIMACS10,channel-500x100x100-b050,4802000,4802000,85362744,1,1,0,0,1,1,undirected graph +DIMACS10,packing-500x100x100-b050,2145852,2145852,34976486,1,1,0,0,1,1,undirected graph +DIMACS10,venturiLevel3,4026819,4026819,16108474,1,1,0,0,1,1,undirected graph +DIMACS10,rgg_n_2_15_s0,32768,32768,320480,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_16_s0,65536,65536,684254,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_17_s0,131072,131072,1457506,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_18_s0,262144,262144,3094566,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_19_s0,524288,524288,6539532,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_20_s0,1048576,1048576,13783240,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_21_s0,2097152,2097152,28975990,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_22_s0,4194304,4194304,60718396,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_23_s0,8388608,8388608,127002786,1,1,0,0,1,1,undirected random graph +DIMACS10,rgg_n_2_24_s0,16777216,16777216,265114400,1,1,0,0,1,1,undirected random graph +DIMACS10,asia_osm,11950757,11950757,25423206,1,1,0,0,1,1,undirected graph +DIMACS10,belgium_osm,1441295,1441295,3099940,1,1,0,0,1,1,undirected graph +DIMACS10,europe_osm,50912018,50912018,108109320,1,1,0,0,1,1,undirected graph +DIMACS10,germany_osm,11548845,11548845,24738362,1,1,0,0,1,1,undirected graph +DIMACS10,great-britain_osm,7733822,7733822,16313034,1,1,0,0,1,1,undirected graph +DIMACS10,italy_osm,6686493,6686493,14027956,1,1,0,0,1,1,undirected graph +DIMACS10,luxembourg_osm,114599,114599,239332,1,1,0,0,1,1,undirected graph +DIMACS10,netherlands_osm,2216688,2216688,4882476,1,1,0,0,1,1,undirected graph +DIMACS10,144,144649,144649,2148786,1,1,0,0,1,1,undirected graph +DIMACS10,598a,110971,110971,1483868,1,1,0,0,1,1,undirected graph +DIMACS10,auto,448695,448695,6629222,1,1,0,0,1,1,undirected graph +DIMACS10,cs4,22499,22499,87716,1,1,0,0,1,1,undirected graph +DIMACS10,cti,16840,16840,96464,1,1,0,0,1,1,undirected graph +DIMACS10,data,2851,2851,30186,1,1,0,0,1,1,undirected graph +DIMACS10,fe_4elt2,11143,11143,65636,1,1,0,0,1,1,undirected graph +DIMACS10,fe_body,45087,45087,327468,1,1,0,0,1,1,undirected graph +DIMACS10,fe_ocean,143437,143437,819186,1,1,0,0,1,1,undirected graph +DIMACS10,fe_rotor,99617,99617,1324862,1,1,0,0,1,1,undirected graph +DIMACS10,fe_sphere,16386,16386,98304,1,1,0,0,1,1,undirected graph +DIMACS10,fe_tooth,78136,78136,905182,1,1,0,0,1,1,undirected graph +DIMACS10,m14b,214765,214765,3358036,1,1,0,0,1,1,undirected graph +DIMACS10,t60k,60005,60005,178880,1,1,0,0,1,1,undirected graph +DIMACS10,uk,4824,4824,13674,1,1,0,0,1,1,undirected graph +DIMACS10,wing,62032,62032,243088,1,1,0,0,1,1,undirected graph +DIMACS10,wing_nodal,10937,10937,150976,1,1,0,0,1,1,undirected graph +IPSO,HTC_336_4438,226340,226340,783496,1,0,0,0,1,1,power network problem +IPSO,HTC_336_9129,226340,226340,762969,1,0,0,0,1,1,power network problem +IPSO,OPF_10000,43887,43887,426898,1,0,0,0,1,1,power network problem +IPSO,OPF_3754,15435,15435,141478,1,0,0,0,1,1,power network problem +IPSO,OPF_6000,29902,29902,274697,1,0,0,0,1,1,power network problem +IPSO,TSC_OPF_1047,8140,8140,2012833,1,0,0,0,1,1,power network problem +IPSO,TSC_OPF_300,9774,9774,820783,1,0,0,0,1,1,power network problem +Janna,Serena,1391349,1391349,64131971,1,0,1,1,1,1,structural problem +Janna,Emilia_923,923136,923136,40373538,1,0,1,1,1,1,structural problem +Janna,Fault_639,638802,638802,27245944,1,0,1,1,1,1,structural problem +Janna,Flan_1565,1564794,1564794,114165372,1,0,1,1,1,1,structural problem +Janna,Geo_1438,1437960,1437960,60236322,1,0,1,1,1,1,structural problem +Janna,Hook_1498,1498023,1498023,59374451,1,0,1,1,1,1,structural problem +Janna,StocF-1465,1465137,1465137,21005389,1,0,1,1,1,1,computational fluid dynamics problem diff --git a/OpenDSSC/klusolve/CSparse/MATLAB/cs_install.m b/OpenDSSC/klusolve/CSparse/MATLAB/cs_install.m new file mode 100644 index 0000000..09094aa --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/MATLAB/cs_install.m @@ -0,0 +1,53 @@ +function cs_install (do_pause) +%CS_INSTALL: compile and install CSparse for use in MATLAB. +% Your current working directory must be CSparse/MATLAB in order to use this +% function. +% +% The directories +% +% CSparse/MATLAB/CSparse +% CSparse/MATLAB/Demo +% CSparse/MATLAB/UFget +% +% are added to your MATLAB path (see the "pathtool" command to add these to +% your path permanently, for future MATLAB sessions). +% +% Next, the MATLAB CSparse demo program, CSparse/MATLAB/cs_demo is executed. +% To run the demo with pauses so you can see the results, use cs_install(1). +% To run the full MATLAB test programs for CSparse, run testall in the +% Test directory. +% +% Example: +% cs_install % install and run demo with no pauses +% cs_install(1) % install and run demo with pauses +% +% See also: cs_demo +% +% Copyright 2006-2007, Timothy A. Davis. +% http://www.cise.ufl.edu/research/sparse + +fprintf ('Compiling and installing CSparse\n') ; +if (nargin < 1) + do_pause = 0 ; +end + +if (~isempty (strfind (computer, '64'))) + error ('64-bit version not supported; use CXSparse instead') ; +end + +if (do_pause) + input ('Hit enter to continue: ') ; +end +addpath ([pwd filesep 'CSparse']) ; +addpath ([pwd filesep 'Demo']) ; + +if (verLessThan ('matlab', '7.0')) + fprintf ('UFget not installed (MATLAB 7.0 or later required)\n') ; +else + addpath ([pwd filesep 'UFget']) ; +end + +cd ('CSparse') ; +cs_make (1) ; +cd ('../Demo') ; +cs_demo (do_pause) diff --git a/OpenDSSC/klusolve/CSparse/Makefile b/OpenDSSC/klusolve/CSparse/Makefile new file mode 100644 index 0000000..d01cdcc --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Makefile @@ -0,0 +1,41 @@ +#------------------------------------------------------------------------------ +# CSparse Makefile +#------------------------------------------------------------------------------ + +VERSION = 2.2.6 + +C: + ( cd Lib ; $(MAKE) ) + ( cd Demo ; $(MAKE) ) + +all: C cov + +library: + ( cd Lib ; $(MAKE) ) + +cov: + ( cd Tcov ; $(MAKE) ) + +mex: + ( cd MATLAB ; $(MAKE) ) + +clean: + ( cd Lib ; $(MAKE) clean ) + ( cd Demo ; $(MAKE) clean ) + ( cd Tcov ; $(MAKE) clean ) + ( cd MATLAB ; $(MAKE) clean ) + +purge: + ( cd Lib ; $(MAKE) purge ) + ( cd Demo ; $(MAKE) purge ) + ( cd Tcov ; $(MAKE) purge ) + ( cd MATLAB ; $(MAKE) purge ) + +distclean: purge + +# do not install CSparse; use CXSparse instead +install: + +# uninstall CSparse: do nothing +uninstall: + diff --git a/OpenDSSC/klusolve/CSparse/Matrix/ash219 b/OpenDSSC/klusolve/CSparse/Matrix/ash219 new file mode 100644 index 0000000..b092930 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/ash219 @@ -0,0 +1,438 @@ +0 0 1 +1 0 1 +2 0 1 +3 0 1 +0 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +4 2 1 +8 2 1 +9 2 1 +8 3 1 +10 3 1 +11 3 1 +12 3 1 +13 3 1 +10 4 1 +14 4 1 +15 4 1 +3 5 1 +16 5 1 +17 5 1 +18 5 1 +19 5 1 +2 6 1 +16 6 1 +20 6 1 +21 6 1 +22 6 1 +23 6 1 +1 7 1 +7 7 1 +22 7 1 +24 7 1 +25 7 1 +26 7 1 +6 8 1 +26 8 1 +27 8 1 +28 8 1 +29 8 1 +30 8 1 +31 8 1 +5 9 1 +9 9 1 +13 9 1 +29 9 1 +32 9 1 +12 10 1 +30 10 1 +32 10 1 +33 10 1 +34 10 1 +35 10 1 +36 10 1 +11 11 1 +15 11 1 +34 11 1 +37 11 1 +38 11 1 +19 12 1 +39 12 1 +40 12 1 +17 13 1 +21 13 1 +41 13 1 +42 13 1 +43 13 1 +44 13 1 +20 14 1 +44 14 1 +45 14 1 +46 14 1 +47 14 1 +48 14 1 +49 14 1 +23 15 1 +25 15 1 +48 15 1 +50 15 1 +51 15 1 +49 16 1 +50 16 1 +52 16 1 +53 16 1 +54 16 1 +55 16 1 +24 17 1 +28 17 1 +51 17 1 +54 17 1 +56 17 1 +57 17 1 +58 17 1 +27 18 1 +57 18 1 +59 18 1 +60 18 1 +61 18 1 +31 19 1 +33 19 1 +60 19 1 +62 19 1 +63 19 1 +36 20 1 +63 20 1 +64 20 1 +65 20 1 +66 20 1 +67 20 1 +68 20 1 +35 21 1 +37 21 1 +66 21 1 +69 21 1 +70 21 1 +14 22 1 +38 22 1 +69 22 1 +71 22 1 +72 22 1 +67 23 1 +70 23 1 +72 23 1 +73 23 1 +74 23 1 +75 23 1 +76 23 1 +68 24 1 +74 24 1 +77 24 1 +78 24 1 +64 25 1 +77 25 1 +79 25 1 +80 25 1 +81 25 1 +82 25 1 +61 26 1 +62 26 1 +65 26 1 +81 26 1 +83 26 1 +84 26 1 +85 26 1 +58 27 1 +59 27 1 +85 27 1 +86 27 1 +87 27 1 +55 28 1 +56 28 1 +87 28 1 +88 28 1 +89 28 1 +90 28 1 +52 29 1 +89 29 1 +91 29 1 +92 29 1 +93 29 1 +94 29 1 +45 30 1 +53 30 1 +93 30 1 +95 30 1 +96 30 1 +97 30 1 +71 31 1 +75 31 1 +98 31 1 +99 31 1 +76 32 1 +99 32 1 +100 32 1 +101 32 1 +102 32 1 +73 33 1 +78 33 1 +82 33 1 +102 33 1 +103 33 1 +104 33 1 +105 33 1 +106 33 1 +104 34 1 +107 34 1 +108 34 1 +109 34 1 +110 34 1 +79 35 1 +105 35 1 +109 35 1 +111 35 1 +112 35 1 +80 36 1 +83 36 1 +112 36 1 +113 36 1 +114 36 1 +108 37 1 +111 37 1 +114 37 1 +115 37 1 +116 37 1 +117 37 1 +118 37 1 +84 38 1 +86 38 1 +90 38 1 +113 38 1 +116 38 1 +119 38 1 +120 38 1 +121 38 1 +122 38 1 +88 39 1 +94 39 1 +121 39 1 +123 39 1 +124 39 1 +125 39 1 +120 40 1 +125 40 1 +126 40 1 +127 40 1 +91 41 1 +124 41 1 +128 41 1 +129 41 1 +130 41 1 +131 41 1 +92 42 1 +95 42 1 +130 42 1 +132 42 1 +133 42 1 +134 42 1 +40 43 1 +135 43 1 +136 43 1 +137 43 1 +138 43 1 +18 44 1 +39 44 1 +43 44 1 +135 44 1 +139 44 1 +140 44 1 +141 44 1 +42 45 1 +139 45 1 +142 45 1 +143 45 1 +144 45 1 +41 46 1 +47 46 1 +142 46 1 +145 46 1 +146 46 1 +46 47 1 +97 47 1 +145 47 1 +147 47 1 +148 47 1 +149 47 1 +96 48 1 +134 48 1 +147 48 1 +150 48 1 +151 48 1 +152 48 1 +129 49 1 +132 49 1 +153 49 1 +154 49 1 +155 49 1 +133 50 1 +150 50 1 +154 50 1 +156 50 1 +157 50 1 +158 50 1 +136 51 1 +141 51 1 +159 51 1 +160 51 1 +161 51 1 +138 52 1 +162 52 1 +163 52 1 +164 52 1 +137 53 1 +161 53 1 +162 53 1 +165 53 1 +166 53 1 +167 53 1 +163 54 1 +167 54 1 +168 54 1 +169 54 1 +170 54 1 +171 54 1 +166 55 1 +168 55 1 +172 55 1 +173 55 1 +174 55 1 +140 56 1 +144 56 1 +159 56 1 +175 56 1 +176 56 1 +177 56 1 +143 57 1 +146 57 1 +149 57 1 +177 57 1 +178 57 1 +179 57 1 +148 58 1 +152 58 1 +178 58 1 +180 58 1 +181 58 1 +182 58 1 +183 58 1 +151 59 1 +158 59 1 +183 59 1 +184 59 1 +157 60 1 +180 60 1 +184 60 1 +185 60 1 +186 60 1 +187 60 1 +188 60 1 +189 60 1 +185 61 1 +190 61 1 +191 61 1 +192 61 1 +193 61 1 +100 62 1 +194 62 1 +98 63 1 +101 63 1 +106 63 1 +194 63 1 +195 63 1 +103 64 1 +110 64 1 +195 64 1 +196 64 1 +107 65 1 +117 65 1 +196 65 1 +197 65 1 +118 66 1 +197 66 1 +198 66 1 +199 66 1 +198 67 1 +200 67 1 +115 68 1 +122 68 1 +199 68 1 +200 68 1 +201 68 1 +119 69 1 +127 69 1 +201 69 1 +202 69 1 +123 70 1 +126 70 1 +131 70 1 +202 70 1 +203 70 1 +128 71 1 +155 71 1 +203 71 1 +204 71 1 +153 72 1 +156 72 1 +189 72 1 +193 72 1 +204 72 1 +205 72 1 +190 73 1 +205 73 1 +206 73 1 +207 73 1 +206 74 1 +208 74 1 +186 75 1 +191 75 1 +207 75 1 +208 75 1 +209 75 1 +210 75 1 +209 76 1 +211 76 1 +187 77 1 +192 77 1 +210 77 1 +211 77 1 +212 77 1 +181 78 1 +188 78 1 +212 78 1 +213 78 1 +175 79 1 +179 79 1 +182 79 1 +213 79 1 +214 79 1 +160 80 1 +165 80 1 +172 80 1 +176 80 1 +214 80 1 +215 80 1 +173 81 1 +215 81 1 +216 81 1 +169 82 1 +174 82 1 +216 82 1 +217 82 1 +170 83 1 +217 83 1 +218 83 1 +164 84 1 +171 84 1 +218 84 1 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/bcsstk01 b/OpenDSSC/klusolve/CSparse/Matrix/bcsstk01 new file mode 100644 index 0000000..b529e93 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/bcsstk01 @@ -0,0 +1,224 @@ +0 0 2.83226851852e+06 +4 0 1.0e+06 +5 0 2.08333333333e+06 +6 0 -3.33333333333e+03 +10 0 1.0e+06 +18 0 -2.8e+06 +24 0 -2.89351851852e+04 +29 0 2.08333333333e+06 +1 1 1.63544753086e+06 +3 1 -2.0e+06 +5 1 5.55555555555e+06 +7 1 -6.66666666667e+03 +9 1 -2.0e+06 +19 1 -3.08641975309e+04 +23 1 5.55555555555e+06 +25 1 -1.59791666667e+06 +2 2 1.72436728395e+06 +3 2 -2.08333333333e+06 +4 2 -2.77777777778e+06 +8 2 -1.68e+06 +20 2 -1.54320987654e+04 +22 2 -2.77777777778e+06 +26 2 -2.89351851852e+04 +27 2 -2.08333333333e+06 +3 3 1.00333333333e+09 +7 3 2.0e+06 +9 3 4.0e+08 +21 3 -3.33333333333e+06 +26 3 2.08333333333e+06 +27 3 1.0e+08 +4 4 1.06750000000e+09 +6 4 -1.0e+06 +10 4 2.0e+08 +20 4 2.77777777778e+06 +22 4 3.33333333333e+08 +28 4 -8.33333333333e+05 +5 5 1.53533333333e+09 +11 5 -2.0e+06 +19 5 -5.55555555555e+06 +23 5 6.66666666667e+08 +24 5 -2.08333333333e+06 +29 5 1.0e+08 +6 6 2.83226851852e+06 +10 6 -1.0e+06 +11 6 2.08333333333e+06 +12 6 -2.8e+06 +30 6 -2.89351851852e+04 +35 6 2.08333333333e+06 +7 7 1.63544753086e+06 +9 7 2.0e+06 +11 7 5.55555555555e+06 +13 7 -3.08641975309e+04 +17 7 5.55555555555e+06 +31 7 -1.59791666667e+06 +8 8 1.72436728395e+06 +9 8 -2.08333333333e+06 +10 8 -2.77777777778e+06 +14 8 -1.54320987654e+04 +16 8 -2.77777777778e+06 +32 8 -2.89351851852e+04 +33 8 -2.08333333333e+06 +9 9 1.00333333333e+09 +15 9 -3.33333333333e+06 +32 9 2.08333333333e+06 +33 9 1.0e+08 +10 10 1.06750000000e+09 +14 10 2.77777777778e+06 +16 10 3.33333333333e+08 +34 10 -8.33333333333e+05 +11 11 1.53533333333e+09 +13 11 -5.55555555555e+06 +17 11 6.66666666667e+08 +30 11 -2.08333333333e+06 +35 11 1.0e+08 +12 12 2.83609946950e+06 +16 12 -2.14928529451e+06 +17 12 2.35916180402e+06 +18 12 -3.33333333333e+03 +22 12 -1.0e+06 +36 12 -2.89351851852e+04 +41 12 2.08333333333e+06 +42 12 -3.83095098171e+03 +46 12 -1.14928529451e+06 +47 12 2.75828470683e+05 +13 13 1.76741074446e+06 +14 13 5.17922131816e+05 +15 13 4.29857058902e+06 +17 13 -5.55555555555e+06 +19 13 -6.66666666667e+03 +21 13 2.0e+06 +37 13 -1.59791666667e+06 +43 13 -1.31963213599e+05 +44 13 -5.17922131816e+05 +45 13 2.29857058902e+06 +14 14 3.89003806848e+06 +15 14 -2.63499027470e+06 +16 14 2.77777777778e+06 +20 14 -1.68e+06 +38 14 -2.89351851852e+04 +39 14 -2.08333333333e+06 +43 14 -5.17922131816e+05 +44 14 -2.16567078453e+06 +45 14 -5.51656941367e+05 +15 15 1.97572063531e+09 +19 15 -2.0e+06 +21 15 4.0e+08 +38 15 2.08333333333e+06 +39 15 1.0e+08 +43 15 -2.29857058902e+06 +44 15 5.51656941366e+05 +45 15 4.86193650990e+08 +16 16 1.52734651547e+09 +17 16 -1.09779731332e+08 +18 16 1.0e+06 +22 16 2.0e+08 +40 16 -8.33333333333e+05 +42 16 1.14928529451e+06 +46 16 2.29724661236e+08 +47 16 -5.57173510779e+07 +17 17 1.56411143711e+09 +23 17 -2.0e+06 +36 17 -2.08333333333e+06 +41 17 1.0e+08 +42 17 -2.75828470683e+05 +46 17 -5.57173510779e+07 +47 17 1.09411960038e+07 +18 18 2.83226851852e+06 +22 18 1.0e+06 +23 18 2.08333333333e+06 +42 18 -2.89351851852e+04 +47 18 2.08333333333e+06 +19 19 1.63544753086e+06 +21 19 -2.0e+06 +23 19 -5.55555555555e+06 +43 19 -1.59791666667e+06 +20 20 1.72436728395e+06 +21 20 -2.08333333333e+06 +22 20 2.77777777778e+06 +44 20 -2.89351851852e+04 +45 20 -2.08333333333e+06 +21 21 1.00333333333e+09 +44 21 2.08333333333e+06 +45 21 1.0e+08 +22 22 1.06750000000e+09 +46 22 -8.33333333333e+05 +23 23 1.53533333333e+09 +42 23 -2.08333333333e+06 +47 23 1.0e+08 +24 24 6.08796296296e+04 +28 24 1.25e+06 +29 24 4.16666666667e+05 +30 24 -4.16666666667e+03 +34 24 1.25e+06 +25 25 3.37291666667e+06 +27 25 -2.5e+06 +31 25 -8.33333333333e+03 +33 25 -2.5e+06 +26 26 2.41171296296e+06 +27 26 -4.16666666667e+05 +32 26 -2.35500000000e+06 +27 27 1.5e+09 +31 27 2.5e+06 +33 27 5.0e+08 +28 28 5.01833333333e+08 +30 28 -1.25e+06 +34 28 2.5e+08 +29 29 5.02500000000e+08 +35 29 -2.5e+06 +30 30 3.98587962963e+06 +34 30 -1.25e+06 +35 30 4.16666666667e+05 +36 30 -3.92500000000e+06 +31 31 3.41149691358e+06 +33 31 2.5e+06 +35 31 6.94444444444e+06 +37 31 -3.85802469136e+04 +41 31 6.94444444445e+06 +32 32 2.43100308642e+06 +33 32 -4.16666666667e+05 +34 32 -3.47222222222e+06 +38 32 -1.92901234568e+04 +40 32 -3.47222222222e+06 +33 33 1.50416666667e+09 +39 33 -4.16666666667e+06 +34 34 1.33516666667e+09 +38 34 3.47222222222e+06 +40 34 4.16666666667e+08 +35 35 2.16916666667e+09 +37 35 -6.94444444444e+06 +41 35 8.33333333333e+08 +36 36 3.98587962963e+06 +40 36 -1.25e+06 +41 36 4.16666666667e+05 +42 36 -4.16666666667e+03 +46 36 -1.25e+06 +37 37 3.41149691358e+06 +39 37 2.5e+06 +41 37 -6.94444444445e+06 +43 37 -8.33333333333e+03 +45 37 2.5e+06 +38 38 2.43100308642e+06 +39 38 -4.16666666667e+05 +40 38 3.47222222222e+06 +44 38 -2.35500000000e+06 +39 39 1.50416666667e+09 +43 39 -2.5e+06 +45 39 5.0e+08 +40 40 1.33516666667e+09 +42 40 1.25e+06 +46 40 2.5e+08 +41 41 2.16916666667e+09 +47 41 -2.5e+06 +42 42 6.47105806113e+04 +46 42 2.39928529451e+06 +47 42 1.40838195984e+05 +43 43 3.50487988027e+06 +44 43 5.17922131816e+05 +45 43 -4.79857058902e+06 +44 44 4.57738374749e+06 +45 44 1.34990274700e+05 +45 45 2.47238730198e+09 +46 46 9.61679848804e+08 +47 46 -1.09779731332e+08 +47 47 5.31278103775e+08 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/bcsstk16 b/OpenDSSC/klusolve/CSparse/Matrix/bcsstk16 new file mode 100644 index 0000000..8dd72b3 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/bcsstk16 @@ -0,0 +1,147631 @@ +0 0 285559874.9195 +1 0 26666666.66228 +3 0 -146456504.1625 +4 0 -26666666.44895 +6 0 9767101.054332 +7 0 21333333.1165 +111 0 45108925.89256 +112 0 13333333.33771 +113 0 13177222.19231 +114 0 -107413106.5112 +115 0 -13333333.23104 +116 0 -65886110.96157 +117 0 -9767101.054335 +118 0 10666666.5635 +119 0 -13177221.94221 +1 1 245557954.5208 +3 1 -26666666.34228 +4 1 -21122150.29068 +6 1 31999999.67474 +7 1 9767101.054331 +111 1 13333333.33771 +112 1 25107965.68335 +113 1 10541666.55379 +114 1 -13333333.17771 +115 1 -44745929.54446 +116 1 -13177083.26329 +117 1 15999999.84525 +118 1 -9767101.054335 +119 1 15812499.93082 +2 2 1 +3 3 494473574.2688 +4 3 26666666.12895 +6 3 15679616.33822 +7 3 -26666666.44895 +9 3 -99111631.13552 +10 3 2.384185791016e-07 +12 3 -37577772.88735 +13 3 26666666.66229 +111 3 -107413106.5112 +112 3 -13333333.17771 +113 3 65886110.96157 +114 3 100730268.7541 +115 3 13333333.07105 +116 3 0.02774140238762 +117 3 -26345045.89131 +118 3 -13333333.23105 +119 3 16471527.49884 +120 3 -88624220.55292 +121 3 2.235174179077e-07 +122 3 -65886111.10029 +123 3 -28555987.69793 +124 3 13333333.33771 +125 3 -16471527.78319 +4 4 422470117.3622 +6 4 -26666666.34229 +7 4 -77653201.26574 +9 4 1.490116119385e-07 +10 4 18222339.27204 +12 4 26666666.66229 +13 4 -29577388.75645 +111 4 -13333333.23104 +112 4 -44745929.54447 +113 4 13177083.28808 +114 4 13333333.07105 +115 4 64728540.28304 +116 4 0.022192299366 +117 4 -13333333.17771 +118 4 -73011454.71628 +119 4 52708333.03581 +120 4 1.9371509552e-07 +121 4 -29957235.32024 +122 4 -3.8743019104e-07 +123 4 13333333.33771 +124 4 -24555795.63051 +125 4 13177083.33766 +5 5 1 +6 6 285559874.9195 +7 6 26666666.66228 +9 6 -37577772.88735 +10 6 -26666666.66229 +12 6 -146456504.1625 +13 6 -26666666.44895 +15 6 9767101.054332 +16 6 21333333.1165 +111 6 -9767101.054335 +112 6 15999999.84525 +113 6 19765832.91331 +114 6 -26345045.8913 +115 6 -13333333.17771 +116 6 -16471527.35667 +117 6 45108925.89256 +118 6 13333333.33771 +119 6 13177222.19231 +120 6 -28555987.69793 +121 6 -13333333.33771 +122 6 -16471527.78319 +123 6 -107413106.5112 +124 6 -13333333.23104 +125 6 -65886110.96157 +126 6 -9767101.054335 +127 6 10666666.5635 +128 6 -13177221.94221 +7 7 245557954.5208 +9 7 -26666666.66229 +10 7 -29577388.75645 +12 7 -26666666.34228 +13 7 -21122150.29068 +15 7 31999999.67474 +16 7 9767101.054331 +111 7 10666666.5635 +112 7 -9767101.054336 +113 7 -10541666.62055 +114 7 -13333333.23105 +115 7 -73011454.71627 +116 7 -52708332.94687 +117 7 13333333.33771 +118 7 25107965.68335 +119 7 10541666.55379 +120 7 -13333333.33771 +121 7 -24555795.63051 +122 7 -13177083.33766 +123 7 -13333333.17771 +124 7 -44745929.54446 +125 7 -13177083.26329 +126 7 15999999.84525 +127 7 -9767101.054335 +128 7 15812499.93082 +8 8 1 +9 9 456895802.7167 +10 9 3.695487976074e-06 +12 9 63024490.39561 +13 9 -1.102685928345e-06 +18 9 -99111631.13552 +19 9 2.384185791016e-07 +21 9 -37577772.88735 +22 9 26666666.66229 +114 9 -88624220.55292 +115 9 1.043081283569e-07 +116 9 65886111.10029 +117 9 -28555987.69793 +118 9 -13333333.33771 +119 9 16471527.78319 +120 9 72174281.7049 +121 9 1.728534698486e-06 +122 9 1.221895217896e-06 +123 9 -7556159.747413 +124 9 -7.450580596924e-07 +125 9 1.341104507446e-06 +129 9 -88624220.55292 +130 9 2.235174179077e-07 +131 9 -65886111.10029 +132 9 -28555987.69793 +133 9 13333333.33771 +134 9 -16471527.78319 +10 10 392892729.701 +12 10 -1.311302185059e-06 +13 10 -38308711.76591 +18 10 1.490116119385e-07 +19 10 18222339.27204 +21 10 26666666.66229 +22 10 -29577388.75645 +114 10 4.470348358154e-08 +115 10 -29957235.32024 +116 10 2.831220626831e-07 +117 10 -13333333.33771 +118 10 -24555795.63051 +119 10 13177083.33766 +120 10 1.728534698486e-06 +121 10 40172745.1813 +122 10 -5.960464477539e-08 +123 10 -7.003545761108e-07 +124 10 -58222760.85313 +125 10 52708333.32467 +129 10 1.9371509552e-07 +130 10 -29957235.32024 +131 10 -3.8743019104e-07 +132 10 13333333.33771 +133 10 -24555795.63051 +134 10 13177083.33766 +11 11 1 +12 12 494473574.2688 +13 12 26666666.12895 +15 12 15679616.33822 +16 12 -26666666.44895 +18 12 -37577772.88735 +19 12 -26666666.66229 +21 12 -99111631.13552 +22 12 2.384185791016e-07 +24 12 -37577772.88735 +25 12 26666666.66229 +114 12 -28555987.69793 +115 12 13333333.33771 +116 12 16471527.78319 +117 12 -107413106.5112 +118 12 -13333333.17771 +119 12 65886110.96157 +120 12 -7556159.747413 +121 12 -3.278255462646e-07 +122 12 -1.206994056702e-06 +123 12 100730268.7541 +124 12 13333333.07105 +125 12 0.02774140238762 +126 12 -26345045.89131 +127 12 -13333333.23105 +128 12 16471527.49884 +129 12 -28555987.69793 +130 12 -13333333.33771 +131 12 -16471527.78319 +132 12 -88624220.55292 +133 12 2.235174179077e-07 +134 12 -65886111.10029 +135 12 -28555987.69793 +136 12 13333333.33771 +137 12 -16471527.78319 +13 13 422470117.3622 +15 13 -26666666.34229 +16 13 -77653201.26574 +18 13 -26666666.66229 +19 13 -29577388.75645 +21 13 1.490116119385e-07 +22 13 18222339.27204 +24 13 26666666.66229 +25 13 -29577388.75645 +114 13 13333333.33771 +115 13 -24555795.63051 +116 13 -13177083.33766 +117 13 -13333333.23104 +118 13 -44745929.54447 +119 13 13177083.28808 +120 13 -2.98023223877e-07 +121 13 -58222760.85313 +122 13 -52708333.32467 +123 13 13333333.07105 +124 13 64728540.28304 +125 13 0.022192299366 +126 13 -13333333.17771 +127 13 -73011454.71628 +128 13 52708333.03581 +129 13 -13333333.33771 +130 13 -24555795.63051 +131 13 -13177083.33766 +132 13 1.9371509552e-07 +133 13 -29957235.32024 +134 13 -3.8743019104e-07 +135 13 13333333.33771 +136 13 -24555795.63051 +137 13 13177083.33766 +14 14 1 +15 15 285559874.9195 +16 15 26666666.66228 +21 15 -37577772.88735 +22 15 -26666666.66229 +24 15 -146456504.1625 +25 15 -26666666.44895 +27 15 9767101.054332 +28 15 21333333.1165 +117 15 -9767101.054335 +118 15 15999999.84525 +119 15 19765832.91331 +123 15 -26345045.8913 +124 15 -13333333.17771 +125 15 -16471527.35667 +126 15 45108925.89256 +127 15 13333333.33771 +128 15 13177222.19231 +132 15 -28555987.69793 +133 15 -13333333.33771 +134 15 -16471527.78319 +135 15 -107413106.5112 +136 15 -13333333.23104 +137 15 -65886110.96157 +138 15 -9767101.054335 +139 15 10666666.5635 +140 15 -13177221.94221 +16 16 245557954.5208 +21 16 -26666666.66229 +22 16 -29577388.75645 +24 16 -26666666.34228 +25 16 -21122150.29068 +27 16 31999999.67474 +28 16 9767101.054331 +117 16 10666666.5635 +118 16 -9767101.054336 +119 16 -10541666.62055 +123 16 -13333333.23105 +124 16 -73011454.71627 +125 16 -52708332.94687 +126 16 13333333.33771 +127 16 25107965.68335 +128 16 10541666.55379 +132 16 -13333333.33771 +133 16 -24555795.63051 +134 16 -13177083.33766 +135 16 -13333333.17771 +136 16 -44745929.54446 +137 16 -13177083.26329 +138 16 15999999.84525 +139 16 -9767101.054335 +140 16 15812499.93082 +17 17 1 +18 18 456895802.7167 +19 18 3.695487976074e-06 +21 18 63024490.39561 +22 18 -1.102685928345e-06 +30 18 -99111631.13552 +31 18 2.384185791016e-07 +33 18 -37577772.88735 +34 18 26666666.66229 +120 18 -88624220.55292 +121 18 1.043081283569e-07 +122 18 65886111.10029 +123 18 -28555987.69793 +124 18 -13333333.33771 +125 18 16471527.78319 +129 18 72174281.7049 +130 18 1.728534698486e-06 +131 18 1.221895217896e-06 +132 18 -7556159.747413 +133 18 -7.450580596924e-07 +134 18 1.341104507446e-06 +141 18 -88624220.55292 +142 18 2.235174179077e-07 +143 18 -65886111.10029 +144 18 -28555987.69793 +145 18 13333333.33771 +146 18 -16471527.78319 +19 19 392892729.701 +21 19 -1.311302185059e-06 +22 19 -38308711.76591 +30 19 1.490116119385e-07 +31 19 18222339.27204 +33 19 26666666.66229 +34 19 -29577388.75645 +120 19 4.470348358154e-08 +121 19 -29957235.32024 +122 19 2.831220626831e-07 +123 19 -13333333.33771 +124 19 -24555795.63051 +125 19 13177083.33766 +129 19 1.728534698486e-06 +130 19 40172745.1813 +131 19 -5.960464477539e-08 +132 19 -7.003545761108e-07 +133 19 -58222760.85313 +134 19 52708333.32467 +141 19 1.9371509552e-07 +142 19 -29957235.32024 +143 19 -3.8743019104e-07 +144 19 13333333.33771 +145 19 -24555795.63051 +146 19 13177083.33766 +20 20 1 +21 21 456895802.7167 +22 21 3.695487976074e-06 +24 21 63024490.39561 +25 21 -1.102685928345e-06 +30 21 -37577772.88735 +31 21 -26666666.66229 +33 21 -99111631.13552 +34 21 2.384185791016e-07 +36 21 -37577772.88735 +37 21 26666666.66229 +120 21 -28555987.69793 +121 21 13333333.33771 +122 21 16471527.78319 +123 21 -88624220.55292 +124 21 1.043081283569e-07 +125 21 65886111.10029 +126 21 -28555987.69793 +127 21 -13333333.33771 +128 21 16471527.78319 +129 21 -7556159.747413 +130 21 -3.278255462646e-07 +131 21 -1.206994056702e-06 +132 21 72174281.7049 +133 21 1.728534698486e-06 +134 21 1.221895217896e-06 +135 21 -7556159.747413 +136 21 -7.450580596924e-07 +137 21 1.341104507446e-06 +141 21 -28555987.69793 +142 21 -13333333.33771 +143 21 -16471527.78319 +144 21 -88624220.55292 +145 21 2.235174179077e-07 +146 21 -65886111.10029 +147 21 -28555987.69793 +148 21 13333333.33771 +149 21 -16471527.78319 +22 22 392892729.701 +24 22 -1.311302185059e-06 +25 22 -38308711.76591 +30 22 -26666666.66229 +31 22 -29577388.75645 +33 22 1.490116119385e-07 +34 22 18222339.27204 +36 22 26666666.66229 +37 22 -29577388.75645 +120 22 13333333.33771 +121 22 -24555795.63051 +122 22 -13177083.33766 +123 22 4.470348358154e-08 +124 22 -29957235.32024 +125 22 2.831220626831e-07 +126 22 -13333333.33771 +127 22 -24555795.63051 +128 22 13177083.33766 +129 22 -2.98023223877e-07 +130 22 -58222760.85313 +131 22 -52708333.32467 +132 22 1.728534698486e-06 +133 22 40172745.1813 +134 22 -5.960464477539e-08 +135 22 -7.003545761108e-07 +136 22 -58222760.85313 +137 22 52708333.32467 +141 22 -13333333.33771 +142 22 -24555795.63051 +143 22 -13177083.33766 +144 22 1.9371509552e-07 +145 22 -29957235.32024 +146 22 -3.8743019104e-07 +147 22 13333333.33771 +148 22 -24555795.63051 +149 22 13177083.33766 +23 23 1 +24 24 494473574.2688 +25 24 26666666.12895 +27 24 15679616.33822 +28 24 -26666666.44895 +33 24 -37577772.88735 +34 24 -26666666.66229 +36 24 -99111631.13552 +37 24 2.384185791016e-07 +39 24 -37577772.88735 +40 24 26666666.66229 +123 24 -28555987.69793 +124 24 13333333.33771 +125 24 16471527.78319 +126 24 -107413106.5112 +127 24 -13333333.17771 +128 24 65886110.96157 +132 24 -7556159.747413 +133 24 -3.278255462646e-07 +134 24 -1.206994056702e-06 +135 24 100730268.7541 +136 24 13333333.07105 +137 24 0.02774140238762 +138 24 -26345045.89131 +139 24 -13333333.23105 +140 24 16471527.49884 +144 24 -28555987.69793 +145 24 -13333333.33771 +146 24 -16471527.78319 +147 24 -88624220.55292 +148 24 2.235174179077e-07 +149 24 -65886111.10029 +150 24 -28555987.69793 +151 24 13333333.33771 +152 24 -16471527.78319 +25 25 422470117.3622 +27 25 -26666666.34229 +28 25 -77653201.26574 +33 25 -26666666.66229 +34 25 -29577388.75645 +36 25 1.490116119385e-07 +37 25 18222339.27204 +39 25 26666666.66229 +40 25 -29577388.75645 +123 25 13333333.33771 +124 25 -24555795.63051 +125 25 -13177083.33766 +126 25 -13333333.23104 +127 25 -44745929.54447 +128 25 13177083.28808 +132 25 -2.98023223877e-07 +133 25 -58222760.85313 +134 25 -52708333.32467 +135 25 13333333.07105 +136 25 64728540.28304 +137 25 0.022192299366 +138 25 -13333333.17771 +139 25 -73011454.71628 +140 25 52708333.03581 +144 25 -13333333.33771 +145 25 -24555795.63051 +146 25 -13177083.33766 +147 25 1.9371509552e-07 +148 25 -29957235.32024 +149 25 -3.8743019104e-07 +150 25 13333333.33771 +151 25 -24555795.63051 +152 25 13177083.33766 +26 26 1 +27 27 285559874.9195 +28 27 26666666.66228 +36 27 -37577772.88735 +37 27 -26666666.66229 +39 27 -146456504.1625 +40 27 -26666666.44895 +42 27 9767101.054332 +43 27 21333333.1165 +126 27 -9767101.054335 +127 27 15999999.84525 +128 27 19765832.91331 +135 27 -26345045.8913 +136 27 -13333333.17771 +137 27 -16471527.35667 +138 27 45108925.89256 +139 27 13333333.33771 +140 27 13177222.19231 +147 27 -28555987.69793 +148 27 -13333333.33771 +149 27 -16471527.78319 +150 27 -107413106.5112 +151 27 -13333333.23104 +152 27 -65886110.96157 +153 27 -9767101.054335 +154 27 10666666.5635 +155 27 -13177221.94221 +28 28 245557954.5208 +36 28 -26666666.66229 +37 28 -29577388.75645 +39 28 -26666666.34228 +40 28 -21122150.29068 +42 28 31999999.67474 +43 28 9767101.054331 +126 28 10666666.5635 +127 28 -9767101.054336 +128 28 -10541666.62055 +135 28 -13333333.23105 +136 28 -73011454.71627 +137 28 -52708332.94687 +138 28 13333333.33771 +139 28 25107965.68335 +140 28 10541666.55379 +147 28 -13333333.33771 +148 28 -24555795.63051 +149 28 -13177083.33766 +150 28 -13333333.17771 +151 28 -44745929.54446 +152 28 -13177083.26329 +153 28 15999999.84525 +154 28 -9767101.054335 +155 28 15812499.93082 +29 29 1 +30 30 456895802.7167 +31 30 3.695487976074e-06 +33 30 63024490.39561 +34 30 -1.102685928345e-06 +45 30 -99111631.13552 +46 30 2.384185791016e-07 +48 30 -37577772.88735 +49 30 26666666.66229 +129 30 -88624220.55292 +130 30 1.043081283569e-07 +131 30 65886111.10029 +132 30 -28555987.69793 +133 30 -13333333.33771 +134 30 16471527.78319 +141 30 72174281.7049 +142 30 1.728534698486e-06 +143 30 1.221895217896e-06 +144 30 -7556159.747413 +145 30 -7.450580596924e-07 +146 30 1.341104507446e-06 +156 30 -88624220.55292 +157 30 2.235174179077e-07 +158 30 -65886111.10029 +159 30 -28555987.69793 +160 30 13333333.33771 +161 30 -16471527.78319 +31 31 392892729.701 +33 31 -1.311302185059e-06 +34 31 -38308711.76591 +45 31 1.490116119385e-07 +46 31 18222339.27204 +48 31 26666666.66229 +49 31 -29577388.75645 +129 31 4.470348358154e-08 +130 31 -29957235.32024 +131 31 2.831220626831e-07 +132 31 -13333333.33771 +133 31 -24555795.63051 +134 31 13177083.33766 +141 31 1.728534698486e-06 +142 31 40172745.1813 +143 31 -5.960464477539e-08 +144 31 -7.003545761108e-07 +145 31 -58222760.85313 +146 31 52708333.32467 +156 31 1.9371509552e-07 +157 31 -29957235.32024 +158 31 -3.8743019104e-07 +159 31 13333333.33771 +160 31 -24555795.63051 +161 31 13177083.33766 +32 32 1 +33 33 456895802.7167 +34 33 3.695487976074e-06 +36 33 63024490.39561 +37 33 -1.102685928345e-06 +45 33 -37577772.88735 +46 33 -26666666.66229 +48 33 -99111631.13552 +49 33 2.384185791016e-07 +51 33 -37577772.88735 +52 33 26666666.66229 +129 33 -28555987.69793 +130 33 13333333.33771 +131 33 16471527.78319 +132 33 -88624220.55292 +133 33 1.043081283569e-07 +134 33 65886111.10029 +135 33 -28555987.69793 +136 33 -13333333.33771 +137 33 16471527.78319 +141 33 -7556159.747413 +142 33 -3.278255462646e-07 +143 33 -1.206994056702e-06 +144 33 72174281.7049 +145 33 1.728534698486e-06 +146 33 1.221895217896e-06 +147 33 -7556159.747413 +148 33 -7.450580596924e-07 +149 33 1.341104507446e-06 +156 33 -28555987.69793 +157 33 -13333333.33771 +158 33 -16471527.78319 +159 33 -88624220.55292 +160 33 2.235174179077e-07 +161 33 -65886111.10029 +162 33 -28555987.69793 +163 33 13333333.33771 +164 33 -16471527.78319 +34 34 392892729.701 +36 34 -1.311302185059e-06 +37 34 -38308711.76591 +45 34 -26666666.66229 +46 34 -29577388.75645 +48 34 1.490116119385e-07 +49 34 18222339.27204 +51 34 26666666.66229 +52 34 -29577388.75645 +129 34 13333333.33771 +130 34 -24555795.63051 +131 34 -13177083.33766 +132 34 4.470348358154e-08 +133 34 -29957235.32024 +134 34 2.831220626831e-07 +135 34 -13333333.33771 +136 34 -24555795.63051 +137 34 13177083.33766 +141 34 -2.98023223877e-07 +142 34 -58222760.85313 +143 34 -52708333.32467 +144 34 1.728534698486e-06 +145 34 40172745.1813 +146 34 -5.960464477539e-08 +147 34 -7.003545761108e-07 +148 34 -58222760.85313 +149 34 52708333.32467 +156 34 -13333333.33771 +157 34 -24555795.63051 +158 34 -13177083.33766 +159 34 1.9371509552e-07 +160 34 -29957235.32024 +161 34 -3.8743019104e-07 +162 34 13333333.33771 +163 34 -24555795.63051 +164 34 13177083.33766 +35 35 1 +36 36 456895802.7167 +37 36 3.695487976074e-06 +39 36 63024490.39561 +40 36 -1.102685928345e-06 +48 36 -37577772.88735 +49 36 -26666666.66229 +51 36 -99111631.13552 +52 36 2.384185791016e-07 +54 36 -37577772.88735 +55 36 26666666.66229 +132 36 -28555987.69793 +133 36 13333333.33771 +134 36 16471527.78319 +135 36 -88624220.55292 +136 36 1.043081283569e-07 +137 36 65886111.10029 +138 36 -28555987.69793 +139 36 -13333333.33771 +140 36 16471527.78319 +144 36 -7556159.747413 +145 36 -3.278255462646e-07 +146 36 -1.206994056702e-06 +147 36 72174281.7049 +148 36 1.728534698486e-06 +149 36 1.221895217896e-06 +150 36 -7556159.747413 +151 36 -7.450580596924e-07 +152 36 1.341104507446e-06 +159 36 -28555987.69793 +160 36 -13333333.33771 +161 36 -16471527.78319 +162 36 -88624220.55292 +163 36 2.235174179077e-07 +164 36 -65886111.10029 +165 36 -28555987.69793 +166 36 13333333.33771 +167 36 -16471527.78319 +37 37 392892729.701 +39 37 -1.311302185059e-06 +40 37 -38308711.76591 +48 37 -26666666.66229 +49 37 -29577388.75645 +51 37 1.490116119385e-07 +52 37 18222339.27204 +54 37 26666666.66229 +55 37 -29577388.75645 +132 37 13333333.33771 +133 37 -24555795.63051 +134 37 -13177083.33766 +135 37 4.470348358154e-08 +136 37 -29957235.32024 +137 37 2.831220626831e-07 +138 37 -13333333.33771 +139 37 -24555795.63051 +140 37 13177083.33766 +144 37 -2.98023223877e-07 +145 37 -58222760.85313 +146 37 -52708333.32467 +147 37 1.728534698486e-06 +148 37 40172745.1813 +149 37 -5.960464477539e-08 +150 37 -7.003545761108e-07 +151 37 -58222760.85313 +152 37 52708333.32467 +159 37 -13333333.33771 +160 37 -24555795.63051 +161 37 -13177083.33766 +162 37 1.9371509552e-07 +163 37 -29957235.32024 +164 37 -3.8743019104e-07 +165 37 13333333.33771 +166 37 -24555795.63051 +167 37 13177083.33766 +38 38 1 +39 39 494473574.2688 +40 39 26666666.12895 +42 39 15679616.33822 +43 39 -26666666.44895 +51 39 -37577772.88735 +52 39 -26666666.66229 +54 39 -99111631.13552 +55 39 2.384185791016e-07 +57 39 -37577772.88735 +58 39 26666666.66229 +135 39 -28555987.69793 +136 39 13333333.33771 +137 39 16471527.78319 +138 39 -107413106.5112 +139 39 -13333333.17771 +140 39 65886110.96157 +147 39 -7556159.747413 +148 39 -3.278255462646e-07 +149 39 -1.206994056702e-06 +150 39 100730268.7541 +151 39 13333333.07105 +152 39 0.02774140238762 +153 39 -26345045.89131 +154 39 -13333333.23105 +155 39 16471527.49884 +162 39 -28555987.69793 +163 39 -13333333.33771 +164 39 -16471527.78319 +165 39 -88624220.55292 +166 39 2.235174179077e-07 +167 39 -65886111.10029 +168 39 -28555987.69793 +169 39 13333333.33771 +170 39 -16471527.78319 +40 40 422470117.3622 +42 40 -26666666.34229 +43 40 -77653201.26574 +51 40 -26666666.66229 +52 40 -29577388.75645 +54 40 1.490116119385e-07 +55 40 18222339.27204 +57 40 26666666.66229 +58 40 -29577388.75645 +135 40 13333333.33771 +136 40 -24555795.63051 +137 40 -13177083.33766 +138 40 -13333333.23104 +139 40 -44745929.54447 +140 40 13177083.28808 +147 40 -2.98023223877e-07 +148 40 -58222760.85313 +149 40 -52708333.32467 +150 40 13333333.07105 +151 40 64728540.28304 +152 40 0.022192299366 +153 40 -13333333.17771 +154 40 -73011454.71628 +155 40 52708333.03581 +162 40 -13333333.33771 +163 40 -24555795.63051 +164 40 -13177083.33766 +165 40 1.9371509552e-07 +166 40 -29957235.32024 +167 40 -3.8743019104e-07 +168 40 13333333.33771 +169 40 -24555795.63051 +170 40 13177083.33766 +41 41 1 +42 42 285559874.9195 +43 42 26666666.66228 +54 42 -37577772.88735 +55 42 -26666666.66229 +57 42 -146456504.1625 +58 42 -26666666.44895 +60 42 9767101.054332 +61 42 21333333.1165 +138 42 -9767101.054335 +139 42 15999999.84525 +140 42 19765832.91331 +150 42 -26345045.8913 +151 42 -13333333.17771 +152 42 -16471527.35667 +153 42 45108925.89256 +154 42 13333333.33771 +155 42 13177222.19231 +165 42 -28555987.69793 +166 42 -13333333.33771 +167 42 -16471527.78319 +168 42 -107413106.5112 +169 42 -13333333.23104 +170 42 -65886110.96157 +171 42 -9767101.054335 +172 42 10666666.5635 +173 42 -13177221.94221 +43 43 245557954.5208 +54 43 -26666666.66229 +55 43 -29577388.75645 +57 43 -26666666.34228 +58 43 -21122150.29068 +60 43 31999999.67474 +61 43 9767101.054331 +138 43 10666666.5635 +139 43 -9767101.054336 +140 43 -10541666.62055 +150 43 -13333333.23105 +151 43 -73011454.71627 +152 43 -52708332.94687 +153 43 13333333.33771 +154 43 25107965.68335 +155 43 10541666.55379 +165 43 -13333333.33771 +166 43 -24555795.63051 +167 43 -13177083.33766 +168 43 -13333333.17771 +169 43 -44745929.54446 +170 43 -13177083.26329 +171 43 15999999.84525 +172 43 -9767101.054335 +173 43 15812499.93082 +44 44 1 +45 45 456895802.7167 +46 45 3.695487976074e-06 +48 45 63024490.39561 +49 45 -1.102685928345e-06 +63 45 -99111631.13552 +64 45 2.384185791016e-07 +66 45 -37577772.88735 +67 45 26666666.66229 +141 45 -88624220.55292 +142 45 1.043081283569e-07 +143 45 65886111.10029 +144 45 -28555987.69793 +145 45 -13333333.33771 +146 45 16471527.78319 +156 45 72174281.7049 +157 45 1.728534698486e-06 +158 45 1.221895217896e-06 +159 45 -7556159.747413 +160 45 -7.450580596924e-07 +161 45 1.341104507446e-06 +174 45 -88624220.55292 +175 45 2.235174179077e-07 +176 45 -65886111.10029 +177 45 -28555987.69793 +178 45 13333333.33771 +179 45 -16471527.78319 +46 46 392892729.701 +48 46 -1.311302185059e-06 +49 46 -38308711.76591 +63 46 1.490116119385e-07 +64 46 18222339.27204 +66 46 26666666.66229 +67 46 -29577388.75645 +141 46 4.470348358154e-08 +142 46 -29957235.32024 +143 46 2.831220626831e-07 +144 46 -13333333.33771 +145 46 -24555795.63051 +146 46 13177083.33766 +156 46 1.728534698486e-06 +157 46 40172745.1813 +158 46 -5.960464477539e-08 +159 46 -7.003545761108e-07 +160 46 -58222760.85313 +161 46 52708333.32467 +174 46 1.9371509552e-07 +175 46 -29957235.32024 +176 46 -3.8743019104e-07 +177 46 13333333.33771 +178 46 -24555795.63051 +179 46 13177083.33766 +47 47 1 +48 48 456895802.7167 +49 48 3.695487976074e-06 +51 48 63024490.39561 +52 48 -1.102685928345e-06 +63 48 -37577772.88735 +64 48 -26666666.66229 +66 48 -99111631.13552 +67 48 2.384185791016e-07 +69 48 -37577772.88735 +70 48 26666666.66229 +141 48 -28555987.69793 +142 48 13333333.33771 +143 48 16471527.78319 +144 48 -88624220.55292 +145 48 1.043081283569e-07 +146 48 65886111.10029 +147 48 -28555987.69793 +148 48 -13333333.33771 +149 48 16471527.78319 +156 48 -7556159.747413 +157 48 -3.278255462646e-07 +158 48 -1.206994056702e-06 +159 48 72174281.7049 +160 48 1.728534698486e-06 +161 48 1.221895217896e-06 +162 48 -7556159.747413 +163 48 -7.450580596924e-07 +164 48 1.341104507446e-06 +174 48 -28555987.69793 +175 48 -13333333.33771 +176 48 -16471527.78319 +177 48 -88624220.55292 +178 48 2.235174179077e-07 +179 48 -65886111.10029 +180 48 -28555987.69793 +181 48 13333333.33771 +182 48 -16471527.78319 +49 49 392892729.701 +51 49 -1.311302185059e-06 +52 49 -38308711.76591 +63 49 -26666666.66229 +64 49 -29577388.75645 +66 49 1.490116119385e-07 +67 49 18222339.27204 +69 49 26666666.66229 +70 49 -29577388.75645 +141 49 13333333.33771 +142 49 -24555795.63051 +143 49 -13177083.33766 +144 49 4.470348358154e-08 +145 49 -29957235.32024 +146 49 2.831220626831e-07 +147 49 -13333333.33771 +148 49 -24555795.63051 +149 49 13177083.33766 +156 49 -2.98023223877e-07 +157 49 -58222760.85313 +158 49 -52708333.32467 +159 49 1.728534698486e-06 +160 49 40172745.1813 +161 49 -5.960464477539e-08 +162 49 -7.003545761108e-07 +163 49 -58222760.85313 +164 49 52708333.32467 +174 49 -13333333.33771 +175 49 -24555795.63051 +176 49 -13177083.33766 +177 49 1.9371509552e-07 +178 49 -29957235.32024 +179 49 -3.8743019104e-07 +180 49 13333333.33771 +181 49 -24555795.63051 +182 49 13177083.33766 +50 50 1 +51 51 456895802.7167 +52 51 3.695487976074e-06 +54 51 63024490.39561 +55 51 -1.102685928345e-06 +66 51 -37577772.88735 +67 51 -26666666.66229 +69 51 -99111631.13552 +70 51 2.384185791016e-07 +72 51 -37577772.88735 +73 51 26666666.66229 +144 51 -28555987.69793 +145 51 13333333.33771 +146 51 16471527.78319 +147 51 -88624220.55292 +148 51 1.043081283569e-07 +149 51 65886111.10029 +150 51 -28555987.69793 +151 51 -13333333.33771 +152 51 16471527.78319 +159 51 -7556159.747413 +160 51 -3.278255462646e-07 +161 51 -1.206994056702e-06 +162 51 72174281.7049 +163 51 1.728534698486e-06 +164 51 1.221895217896e-06 +165 51 -7556159.747413 +166 51 -7.450580596924e-07 +167 51 1.341104507446e-06 +177 51 -28555987.69793 +178 51 -13333333.33771 +179 51 -16471527.78319 +180 51 -88624220.55292 +181 51 2.235174179077e-07 +182 51 -65886111.10029 +183 51 -28555987.69793 +184 51 13333333.33771 +185 51 -16471527.78319 +52 52 392892729.701 +54 52 -1.311302185059e-06 +55 52 -38308711.76591 +66 52 -26666666.66229 +67 52 -29577388.75645 +69 52 1.490116119385e-07 +70 52 18222339.27204 +72 52 26666666.66229 +73 52 -29577388.75645 +144 52 13333333.33771 +145 52 -24555795.63051 +146 52 -13177083.33766 +147 52 4.470348358154e-08 +148 52 -29957235.32024 +149 52 2.831220626831e-07 +150 52 -13333333.33771 +151 52 -24555795.63051 +152 52 13177083.33766 +159 52 -2.98023223877e-07 +160 52 -58222760.85313 +161 52 -52708333.32467 +162 52 1.728534698486e-06 +163 52 40172745.1813 +164 52 -5.960464477539e-08 +165 52 -7.003545761108e-07 +166 52 -58222760.85313 +167 52 52708333.32467 +177 52 -13333333.33771 +178 52 -24555795.63051 +179 52 -13177083.33766 +180 52 1.9371509552e-07 +181 52 -29957235.32024 +182 52 -3.8743019104e-07 +183 52 13333333.33771 +184 52 -24555795.63051 +185 52 13177083.33766 +53 53 1 +54 54 456895802.7167 +55 54 3.695487976074e-06 +57 54 63024490.39561 +58 54 -1.102685928345e-06 +69 54 -37577772.88735 +70 54 -26666666.66229 +72 54 -99111631.13552 +73 54 2.384185791016e-07 +75 54 -37577772.88735 +76 54 26666666.66229 +147 54 -28555987.69793 +148 54 13333333.33771 +149 54 16471527.78319 +150 54 -88624220.55292 +151 54 1.043081283569e-07 +152 54 65886111.10029 +153 54 -28555987.69793 +154 54 -13333333.33771 +155 54 16471527.78319 +162 54 -7556159.747413 +163 54 -3.278255462646e-07 +164 54 -1.206994056702e-06 +165 54 72174281.7049 +166 54 1.728534698486e-06 +167 54 1.221895217896e-06 +168 54 -7556159.747413 +169 54 -7.450580596924e-07 +170 54 1.341104507446e-06 +180 54 -28555987.69793 +181 54 -13333333.33771 +182 54 -16471527.78319 +183 54 -88624220.55292 +184 54 2.235174179077e-07 +185 54 -65886111.10029 +186 54 -28555987.69793 +187 54 13333333.33771 +188 54 -16471527.78319 +55 55 392892729.701 +57 55 -1.311302185059e-06 +58 55 -38308711.76591 +69 55 -26666666.66229 +70 55 -29577388.75645 +72 55 1.490116119385e-07 +73 55 18222339.27204 +75 55 26666666.66229 +76 55 -29577388.75645 +147 55 13333333.33771 +148 55 -24555795.63051 +149 55 -13177083.33766 +150 55 4.470348358154e-08 +151 55 -29957235.32024 +152 55 2.831220626831e-07 +153 55 -13333333.33771 +154 55 -24555795.63051 +155 55 13177083.33766 +162 55 -2.98023223877e-07 +163 55 -58222760.85313 +164 55 -52708333.32467 +165 55 1.728534698486e-06 +166 55 40172745.1813 +167 55 -5.960464477539e-08 +168 55 -7.003545761108e-07 +169 55 -58222760.85313 +170 55 52708333.32467 +180 55 -13333333.33771 +181 55 -24555795.63051 +182 55 -13177083.33766 +183 55 1.9371509552e-07 +184 55 -29957235.32024 +185 55 -3.8743019104e-07 +186 55 13333333.33771 +187 55 -24555795.63051 +188 55 13177083.33766 +56 56 1 +57 57 494473574.2688 +58 57 26666666.12895 +60 57 15679616.33822 +61 57 -26666666.44895 +72 57 -37577772.88735 +73 57 -26666666.66229 +75 57 -99111631.13552 +76 57 2.384185791016e-07 +78 57 -37577772.88735 +79 57 26666666.66229 +150 57 -28555987.69793 +151 57 13333333.33771 +152 57 16471527.78319 +153 57 -107413106.5112 +154 57 -13333333.17771 +155 57 65886110.96157 +165 57 -7556159.747413 +166 57 -3.278255462646e-07 +167 57 -1.206994056702e-06 +168 57 100730268.7541 +169 57 13333333.07105 +170 57 0.02774140238762 +171 57 -26345045.89131 +172 57 -13333333.23105 +173 57 16471527.49884 +183 57 -28555987.69793 +184 57 -13333333.33771 +185 57 -16471527.78319 +186 57 -88624220.55292 +187 57 2.235174179077e-07 +188 57 -65886111.10029 +189 57 -28555987.69793 +190 57 13333333.33771 +191 57 -16471527.78319 +58 58 422470117.3622 +60 58 -26666666.34229 +61 58 -77653201.26574 +72 58 -26666666.66229 +73 58 -29577388.75645 +75 58 1.490116119385e-07 +76 58 18222339.27204 +78 58 26666666.66229 +79 58 -29577388.75645 +150 58 13333333.33771 +151 58 -24555795.63051 +152 58 -13177083.33766 +153 58 -13333333.23104 +154 58 -44745929.54447 +155 58 13177083.28808 +165 58 -2.98023223877e-07 +166 58 -58222760.85313 +167 58 -52708333.32467 +168 58 13333333.07105 +169 58 64728540.28304 +170 58 0.022192299366 +171 58 -13333333.17771 +172 58 -73011454.71628 +173 58 52708333.03581 +183 58 -13333333.33771 +184 58 -24555795.63051 +185 58 -13177083.33766 +186 58 1.9371509552e-07 +187 58 -29957235.32024 +188 58 -3.8743019104e-07 +189 58 13333333.33771 +190 58 -24555795.63051 +191 58 13177083.33766 +59 59 1 +60 60 254577284.4124 +61 60 12542819.63852 +75 60 -37577772.88735 +76 60 -26666666.66229 +78 60 -114012622.4679 +79 60 -12542819.42519 +81 60 -2041494.77529 +82 60 21333333.1165 +153 60 -9767101.054335 +154 60 15999999.84525 +155 60 19765832.91331 +168 60 -26345045.8913 +169 60 -13333333.17771 +170 60 -16471527.35667 +171 60 37378109.13818 +172 60 6271409.822349 +173 60 11432222.19995 +186 60 -28555987.69793 +187 60 -13333333.33771 +188 60 -16471527.78319 +189 60 -87310926.38278 +190 60 -6271409.715683 +191 60 -57161110.99975 +192 60 -11791159.78617 +193 60 10666666.5635 +194 60 -9687222.01637 +61 61 236302495.3909 +75 61 -26666666.66229 +76 61 -29577388.75645 +78 61 -12542819.31852 +79 61 4964216.203455 +81 61 31999999.67474 +82 61 -17411110.95215 +153 61 10666666.5635 +154 61 -9767101.054336 +155 61 -10541666.62055 +168 61 -13333333.23105 +169 61 -73011454.71627 +170 61 -52708332.94687 +171 61 6271409.822349 +172 61 28240714.62293 +173 61 9145833.226567 +186 61 -13333333.33771 +187 61 -24555795.63051 +188 61 -13177083.33766 +189 61 -6271409.66235 +190 61 -27822507.01778 +191 61 -6197916.627156 +192 61 15999999.84526 +193 61 -19475967.87838 +194 61 18604166.53816 +62 62 1 +63 63 456895802.7167 +64 63 3.695487976074e-06 +66 63 63024490.39561 +67 63 -1.102685928345e-06 +84 63 -99111631.13552 +85 63 2.384185791016e-07 +87 63 -37577772.88735 +88 63 26666666.66229 +156 63 -88624220.55292 +157 63 1.043081283569e-07 +158 63 65886111.10029 +159 63 -28555987.69793 +160 63 -13333333.33771 +161 63 16471527.78319 +174 63 72174281.7049 +175 63 1.728534698486e-06 +176 63 1.221895217896e-06 +177 63 -7556159.747413 +178 63 -7.450580596924e-07 +179 63 1.341104507446e-06 +195 63 -88624220.55292 +196 63 2.235174179077e-07 +197 63 -65886111.10029 +198 63 -28555987.69793 +199 63 13333333.33771 +200 63 -16471527.78319 +64 64 392892729.701 +66 64 -1.311302185059e-06 +67 64 -38308711.76591 +84 64 1.490116119385e-07 +85 64 18222339.27204 +87 64 26666666.66229 +88 64 -29577388.75645 +156 64 4.470348358154e-08 +157 64 -29957235.32024 +158 64 2.831220626831e-07 +159 64 -13333333.33771 +160 64 -24555795.63051 +161 64 13177083.33766 +174 64 1.728534698486e-06 +175 64 40172745.1813 +176 64 -5.960464477539e-08 +177 64 -7.003545761108e-07 +178 64 -58222760.85313 +179 64 52708333.32467 +195 64 1.9371509552e-07 +196 64 -29957235.32024 +197 64 -3.8743019104e-07 +198 64 13333333.33771 +199 64 -24555795.63051 +200 64 13177083.33766 +65 65 1 +66 66 456895802.7167 +67 66 3.695487976074e-06 +69 66 63024490.39561 +70 66 -1.102685928345e-06 +84 66 -37577772.88735 +85 66 -26666666.66229 +87 66 -99111631.13552 +88 66 2.384185791016e-07 +90 66 -37577772.88735 +91 66 26666666.66229 +156 66 -28555987.69793 +157 66 13333333.33771 +158 66 16471527.78319 +159 66 -88624220.55292 +160 66 1.043081283569e-07 +161 66 65886111.10029 +162 66 -28555987.69793 +163 66 -13333333.33771 +164 66 16471527.78319 +174 66 -7556159.747413 +175 66 -3.278255462646e-07 +176 66 -1.206994056702e-06 +177 66 72174281.7049 +178 66 1.728534698486e-06 +179 66 1.221895217896e-06 +180 66 -7556159.747413 +181 66 -7.450580596924e-07 +182 66 1.341104507446e-06 +195 66 -28555987.69793 +196 66 -13333333.33771 +197 66 -16471527.78319 +198 66 -88624220.55292 +199 66 2.235174179077e-07 +200 66 -65886111.10029 +201 66 -28555987.69793 +202 66 13333333.33771 +203 66 -16471527.78319 +67 67 392892729.701 +69 67 -1.311302185059e-06 +70 67 -38308711.76591 +84 67 -26666666.66229 +85 67 -29577388.75645 +87 67 1.490116119385e-07 +88 67 18222339.27204 +90 67 26666666.66229 +91 67 -29577388.75645 +156 67 13333333.33771 +157 67 -24555795.63051 +158 67 -13177083.33766 +159 67 4.470348358154e-08 +160 67 -29957235.32024 +161 67 2.831220626831e-07 +162 67 -13333333.33771 +163 67 -24555795.63051 +164 67 13177083.33766 +174 67 -2.98023223877e-07 +175 67 -58222760.85313 +176 67 -52708333.32467 +177 67 1.728534698486e-06 +178 67 40172745.1813 +179 67 -5.960464477539e-08 +180 67 -7.003545761108e-07 +181 67 -58222760.85313 +182 67 52708333.32467 +195 67 -13333333.33771 +196 67 -24555795.63051 +197 67 -13177083.33766 +198 67 1.9371509552e-07 +199 67 -29957235.32024 +200 67 -3.8743019104e-07 +201 67 13333333.33771 +202 67 -24555795.63051 +203 67 13177083.33766 +68 68 1 +69 69 456895802.7167 +70 69 3.695487976074e-06 +72 69 63024490.39561 +73 69 -1.102685928345e-06 +87 69 -37577772.88735 +88 69 -26666666.66229 +90 69 -99111631.13552 +91 69 2.384185791016e-07 +93 69 -37577772.88735 +94 69 26666666.66229 +159 69 -28555987.69793 +160 69 13333333.33771 +161 69 16471527.78319 +162 69 -88624220.55292 +163 69 1.043081283569e-07 +164 69 65886111.10029 +165 69 -28555987.69793 +166 69 -13333333.33771 +167 69 16471527.78319 +177 69 -7556159.747413 +178 69 -3.278255462646e-07 +179 69 -1.206994056702e-06 +180 69 72174281.7049 +181 69 1.728534698486e-06 +182 69 1.221895217896e-06 +183 69 -7556159.747413 +184 69 -7.450580596924e-07 +185 69 1.341104507446e-06 +198 69 -28555987.69793 +199 69 -13333333.33771 +200 69 -16471527.78319 +201 69 -88624220.55292 +202 69 2.235174179077e-07 +203 69 -65886111.10029 +204 69 -28555987.69793 +205 69 13333333.33771 +206 69 -16471527.78319 +70 70 392892729.701 +72 70 -1.311302185059e-06 +73 70 -38308711.76591 +87 70 -26666666.66229 +88 70 -29577388.75645 +90 70 1.490116119385e-07 +91 70 18222339.27204 +93 70 26666666.66229 +94 70 -29577388.75645 +159 70 13333333.33771 +160 70 -24555795.63051 +161 70 -13177083.33766 +162 70 4.470348358154e-08 +163 70 -29957235.32024 +164 70 2.831220626831e-07 +165 70 -13333333.33771 +166 70 -24555795.63051 +167 70 13177083.33766 +177 70 -2.98023223877e-07 +178 70 -58222760.85313 +179 70 -52708333.32467 +180 70 1.728534698486e-06 +181 70 40172745.1813 +182 70 -5.960464477539e-08 +183 70 -7.003545761108e-07 +184 70 -58222760.85313 +185 70 52708333.32467 +198 70 -13333333.33771 +199 70 -24555795.63051 +200 70 -13177083.33766 +201 70 1.9371509552e-07 +202 70 -29957235.32024 +203 70 -3.8743019104e-07 +204 70 13333333.33771 +205 70 -24555795.63051 +206 70 13177083.33766 +71 71 1 +72 72 456895802.7167 +73 72 3.695487976074e-06 +75 72 63024490.39561 +76 72 -1.102685928345e-06 +90 72 -37577772.88735 +91 72 -26666666.66229 +93 72 -99111631.13552 +94 72 2.384185791016e-07 +96 72 -37577772.88735 +97 72 26666666.66229 +162 72 -28555987.69793 +163 72 13333333.33771 +164 72 16471527.78319 +165 72 -88624220.55292 +166 72 1.043081283569e-07 +167 72 65886111.10029 +168 72 -28555987.69793 +169 72 -13333333.33771 +170 72 16471527.78319 +180 72 -7556159.747413 +181 72 -3.278255462646e-07 +182 72 -1.206994056702e-06 +183 72 72174281.7049 +184 72 1.728534698486e-06 +185 72 1.221895217896e-06 +186 72 -7556159.747413 +187 72 -7.450580596924e-07 +188 72 1.341104507446e-06 +201 72 -28555987.69793 +202 72 -13333333.33771 +203 72 -16471527.78319 +204 72 -88624220.55292 +205 72 2.235174179077e-07 +206 72 -65886111.10029 +207 72 -28555987.69793 +208 72 13333333.33771 +209 72 -16471527.78319 +73 73 392892729.701 +75 73 -1.311302185059e-06 +76 73 -38308711.76591 +90 73 -26666666.66229 +91 73 -29577388.75645 +93 73 1.490116119385e-07 +94 73 18222339.27204 +96 73 26666666.66229 +97 73 -29577388.75645 +162 73 13333333.33771 +163 73 -24555795.63051 +164 73 -13177083.33766 +165 73 4.470348358154e-08 +166 73 -29957235.32024 +167 73 2.831220626831e-07 +168 73 -13333333.33771 +169 73 -24555795.63051 +170 73 13177083.33766 +180 73 -2.98023223877e-07 +181 73 -58222760.85313 +182 73 -52708333.32467 +183 73 1.728534698486e-06 +184 73 40172745.1813 +185 73 -5.960464477539e-08 +186 73 -7.003545761108e-07 +187 73 -58222760.85313 +188 73 52708333.32467 +201 73 -13333333.33771 +202 73 -24555795.63051 +203 73 -13177083.33766 +204 73 1.9371509552e-07 +205 73 -29957235.32024 +206 73 -3.8743019104e-07 +207 73 13333333.33771 +208 73 -24555795.63051 +209 73 13177083.33766 +74 74 1 +75 75 456895802.7167 +76 75 3.695487976074e-06 +78 75 63024490.39561 +79 75 -1.102685928345e-06 +93 75 -37577772.88735 +94 75 -26666666.66229 +96 75 -99111631.13552 +97 75 2.384185791016e-07 +99 75 -37577772.88735 +100 75 26666666.66229 +165 75 -28555987.69793 +166 75 13333333.33771 +167 75 16471527.78319 +168 75 -88624220.55292 +169 75 1.043081283569e-07 +170 75 65886111.10029 +171 75 -28555987.69793 +172 75 -13333333.33771 +173 75 16471527.78319 +183 75 -7556159.747413 +184 75 -3.278255462646e-07 +185 75 -1.206994056702e-06 +186 75 72174281.7049 +187 75 1.728534698486e-06 +188 75 1.221895217896e-06 +189 75 -7556159.747413 +190 75 -7.450580596924e-07 +191 75 1.341104507446e-06 +204 75 -28555987.69793 +205 75 -13333333.33771 +206 75 -16471527.78319 +207 75 -88624220.55292 +208 75 2.235174179077e-07 +209 75 -65886111.10029 +210 75 -28555987.69793 +211 75 13333333.33771 +212 75 -16471527.78319 +76 76 392892729.701 +78 76 -1.311302185059e-06 +79 76 -38308711.76591 +93 76 -26666666.66229 +94 76 -29577388.75645 +96 76 1.490116119385e-07 +97 76 18222339.27204 +99 76 26666666.66229 +100 76 -29577388.75645 +165 76 13333333.33771 +166 76 -24555795.63051 +167 76 -13177083.33766 +168 76 4.470348358154e-08 +169 76 -29957235.32024 +170 76 2.831220626831e-07 +171 76 -13333333.33771 +172 76 -24555795.63051 +173 76 13177083.33766 +183 76 -2.98023223877e-07 +184 76 -58222760.85313 +185 76 -52708333.32467 +186 76 1.728534698486e-06 +187 76 40172745.1813 +188 76 -5.960464477539e-08 +189 76 -7.003545761108e-07 +190 76 -58222760.85313 +191 76 52708333.32467 +204 76 -13333333.33771 +205 76 -24555795.63051 +206 76 -13177083.33766 +207 76 1.9371509552e-07 +208 76 -29957235.32024 +209 76 -3.8743019104e-07 +210 76 13333333.33771 +211 76 -24555795.63051 +212 76 13177083.33766 +77 77 1 +78 78 443038053.544 +79 78 14753289.29481 +81 78 -7825052.860854 +82 78 -33997652.77504 +96 78 -37577772.88735 +97 78 -26666666.66229 +99 78 -84996673.21432 +100 78 6792787.185364 +102 78 -24718984.37946 +103 78 24994395.61339 +168 78 -28555987.69793 +169 78 13333333.33771 +170 78 16471527.78319 +171 78 -87310926.38278 +172 78 -6271409.66235 +173 78 57161110.99975 +186 78 -7556159.747413 +187 78 -3.278255462646e-07 +188 78 -1.206994056702e-06 +189 78 87947441.63499 +190 78 7376644.65104 +191 78 0.02039501070976 +192 78 -32923131.70809 +193 78 -16998826.39589 +194 78 16470833.12799 +207 78 -28555987.69793 +208 78 -13333333.33771 +209 78 -16471527.78319 +210 78 -80272721.40676 +211 78 3396393.594356 +212 78 -61522916.65699 +213 78 -22126192.23639 +214 78 12497197.81285 +215 78 -12109027.78175 +79 79 410708568.3999 +81 79 -33997652.66837 +82 79 -102930724.6535 +96 79 -26666666.66229 +97 79 -29577388.75645 +99 79 6792787.185364 +100 79 24210319.49286 +102 79 24994395.61339 +103 79 -40135224.92162 +168 79 13333333.33771 +169 79 -24555795.63051 +170 79 -13177083.33766 +171 79 -6271409.715683 +172 79 -27822507.01778 +173 79 6197916.651945 +186 79 -2.98023223877e-07 +187 79 -58222760.85313 +188 79 -52708333.32467 +189 79 7376644.65104 +190 79 71782699.055 +191 79 0.01631674170494 +192 79 -16998826.34256 +193 79 -80475967.62785 +194 79 52708333.09468 +207 79 -13333333.33771 +208 79 -24555795.63051 +209 79 -13177083.33766 +210 79 3396393.594355 +211 79 -25669225.02627 +212 79 3489583.332416 +213 79 12497197.81285 +214 79 -29834312.51126 +215 79 16666666.67214 +80 80 1 +81 81 265887547.5234 +82 81 4251691.216096 +99 81 -40185009.13188 +100 81 -26453880.6983 +102 81 -56727888.77942 +103 81 9054179.643625 +105 81 34241530.0939 +106 81 -9372296.81691 +108 81 -21164769.40107 +109 81 24517959.64911 +171 81 -11791159.78616 +172 81 15999999.84526 +173 81 14530833.02455 +189 81 -32923131.7081 +190 81 -16998826.34256 +191 81 -16470833.02261 +192 81 14669982.03611 +193 81 2125845.609096 +194 81 12968611.10898 +210 81 -29859204.61641 +211 81 -13226940.35567 +212 81 -16470833.33874 +213 81 -76387958.09069 +214 81 4527089.824043 +215 81 -64843055.54491 +216 81 -11712307.86994 +217 81 -4686148.410764 +218 81 8424305.555742 +219 81 -24181082.63358 +220 81 12258979.8306 +221 81 -15950694.44968 +82 82 313462909.2146 +99 82 -26453880.6983 +100 82 -27436535.90625 +102 82 9054179.643625 +103 82 48935939.89062 +105 82 1294369.848004 +106 82 -17586593.12844 +108 82 24517959.64911 +109 82 -24849021.79609 +171 82 10666666.5635 +172 82 -19475967.87838 +173 82 -14729166.53156 +189 82 -16998826.39589 +190 82 -80475967.62786 +191 82 -52708333.03516 +192 82 2125845.609096 +193 82 38457662.89345 +194 82 3874999.888226 +210 82 -13226940.35567 +211 82 -23484968.00046 +212 82 -13177083.33766 +213 82 4527089.824043 +214 82 -23556043.72965 +215 82 3489583.332417 +216 82 647184.9243208 +217 82 -37626369.49388 +218 82 33333333.32786 +219 82 12258979.8306 +220 82 -26023208.832 +221 82 16666666.67214 +83 83 1 +84 84 228447901.3583 +85 84 2.026557922363e-06 +87 84 31512245.19781 +88 84 5333333.332457 +174 84 -88624220.55292 +175 84 1.043081283569e-07 +176 84 65886111.10029 +177 84 -28555987.69793 +178 84 -13333333.33771 +179 84 16471527.78319 +195 84 36087140.85245 +196 84 8.344650268555e-07 +197 84 -13177222.22006 +198 84 -3778079.873706 +199 84 2666666.667542 +200 84 -3294305.556637 +85 85 196446364.8505 +87 85 -5333333.332458 +88 85 -19154355.88295 +174 85 4.470348358154e-08 +175 85 -29957235.32024 +176 85 2.831220626831e-07 +177 85 -13333333.33771 +178 85 -24555795.63051 +179 85 13177083.33766 +195 85 8.940696716309e-07 +196 85 20086372.59065 +197 85 -2.98023223877e-08 +198 85 -2666666.667543 +199 85 -29111380.42657 +200 85 26354166.66234 +86 86 1 +87 87 228447901.3583 +88 87 2.026557922363e-06 +90 87 31512245.19781 +91 87 5333333.332457 +174 87 -28555987.69793 +175 87 13333333.33771 +176 87 16471527.78319 +177 87 -88624220.55292 +178 87 1.043081283569e-07 +179 87 65886111.10029 +180 87 -28555987.69793 +181 87 -13333333.33771 +182 87 16471527.78319 +195 87 -3778079.873706 +196 87 -2666666.667542 +197 87 -3294305.556638 +198 87 36087140.85245 +199 87 8.344650268555e-07 +200 87 -13177222.22006 +201 87 -3778079.873706 +202 87 2666666.667542 +203 87 -3294305.556637 +88 88 196446364.8505 +90 88 -5333333.332458 +91 88 -19154355.88295 +174 88 13333333.33771 +175 88 -24555795.63051 +176 88 -13177083.33766 +177 88 4.470348358154e-08 +178 88 -29957235.32024 +179 88 2.831220626831e-07 +180 88 -13333333.33771 +181 88 -24555795.63051 +182 88 13177083.33766 +195 88 2666666.667542 +196 88 -29111380.42657 +197 88 -26354166.66234 +198 88 8.940696716309e-07 +199 88 20086372.59065 +200 88 -2.98023223877e-08 +201 88 -2666666.667543 +202 88 -29111380.42657 +203 88 26354166.66234 +89 89 1 +90 90 228447901.3583 +91 90 2.026557922363e-06 +93 90 31512245.19781 +94 90 5333333.332457 +177 90 -28555987.69793 +178 90 13333333.33771 +179 90 16471527.78319 +180 90 -88624220.55292 +181 90 1.043081283569e-07 +182 90 65886111.10029 +183 90 -28555987.69793 +184 90 -13333333.33771 +185 90 16471527.78319 +198 90 -3778079.873706 +199 90 -2666666.667542 +200 90 -3294305.556638 +201 90 36087140.85245 +202 90 8.344650268555e-07 +203 90 -13177222.22006 +204 90 -3778079.873706 +205 90 2666666.667542 +206 90 -3294305.556637 +91 91 196446364.8505 +93 91 -5333333.332458 +94 91 -19154355.88295 +177 91 13333333.33771 +178 91 -24555795.63051 +179 91 -13177083.33766 +180 91 4.470348358154e-08 +181 91 -29957235.32024 +182 91 2.831220626831e-07 +183 91 -13333333.33771 +184 91 -24555795.63051 +185 91 13177083.33766 +198 91 2666666.667542 +199 91 -29111380.42657 +200 91 -26354166.66234 +201 91 8.940696716309e-07 +202 91 20086372.59065 +203 91 -2.98023223877e-08 +204 91 -2666666.667543 +205 91 -29111380.42657 +206 91 26354166.66234 +92 92 1 +93 93 228447901.3583 +94 93 2.026557922363e-06 +96 93 31512245.19781 +97 93 5333333.332457 +180 93 -28555987.69793 +181 93 13333333.33771 +182 93 16471527.78319 +183 93 -88624220.55292 +184 93 1.043081283569e-07 +185 93 65886111.10029 +186 93 -28555987.69793 +187 93 -13333333.33771 +188 93 16471527.78319 +201 93 -3778079.873706 +202 93 -2666666.667542 +203 93 -3294305.556638 +204 93 36087140.85245 +205 93 8.344650268555e-07 +206 93 -13177222.22006 +207 93 -3778079.873706 +208 93 2666666.667542 +209 93 -3294305.556637 +94 94 196446364.8505 +96 94 -5333333.332458 +97 94 -19154355.88295 +180 94 13333333.33771 +181 94 -24555795.63051 +182 94 -13177083.33766 +183 94 4.470348358154e-08 +184 94 -29957235.32024 +185 94 2.831220626831e-07 +186 94 -13333333.33771 +187 94 -24555795.63051 +188 94 13177083.33766 +201 94 2666666.667542 +202 94 -29111380.42657 +203 94 -26354166.66234 +204 94 8.940696716309e-07 +205 94 20086372.59065 +206 94 -2.98023223877e-08 +207 94 -2666666.667543 +208 94 -29111380.42657 +209 94 26354166.66234 +95 95 1 +96 96 228447901.3583 +97 96 2.026557922363e-06 +99 96 31512245.19781 +100 96 5333333.332457 +183 96 -28555987.69793 +184 96 13333333.33771 +185 96 16471527.78319 +186 96 -88624220.55292 +187 96 1.043081283569e-07 +188 96 65886111.10029 +189 96 -28555987.69793 +190 96 -13333333.33771 +191 96 16471527.78319 +204 96 -3778079.873706 +205 96 -2666666.667542 +206 96 -3294305.556638 +207 96 36087140.85245 +208 96 8.344650268555e-07 +209 96 -13177222.22006 +210 96 -3778079.873706 +211 96 2666666.667542 +212 96 -3294305.556637 +97 97 196446364.8505 +99 97 -5333333.332458 +100 97 -19154355.88295 +183 97 13333333.33771 +184 97 -24555795.63051 +185 97 -13177083.33766 +186 97 4.470348358154e-08 +187 97 -29957235.32024 +188 97 2.831220626831e-07 +189 97 -13333333.33771 +190 97 -24555795.63051 +191 97 13177083.33766 +204 97 2666666.667542 +205 97 -29111380.42657 +206 97 -26354166.66234 +207 97 8.940696716309e-07 +208 97 20086372.59065 +209 97 -2.98023223877e-08 +210 97 -2666666.667543 +211 97 -29111380.42657 +212 97 26354166.66234 +98 98 1 +99 99 225836329.6274 +100 99 212728.6534935 +102 99 22613666.86668 +103 99 -1884968.470388 +186 99 -28555987.69793 +187 99 13333333.33771 +188 99 16471527.78319 +189 99 -80272721.40676 +190 99 3396393.594356 +191 99 61522916.65613 +192 99 -29859204.61641 +193 99 -13226940.35567 +194 99 16470833.33874 +207 99 -3778079.873706 +208 99 -2666666.667542 +209 99 -3294305.556638 +210 99 34782980.96289 +211 99 106364.3267991 +212 99 -13176944.44228 +213 99 -9519773.826407 +214 99 -942484.2356579 +215 99 1067638.88752 +100 100 198587519.4449 +102 100 -12551635.1353 +103 100 -29426771.93377 +186 100 13333333.33771 +187 100 -24555795.63051 +188 100 -13177083.33766 +189 100 3396393.594355 +190 100 -25669225.02627 +191 100 -3489583.333104 +192 100 -13226940.35567 +193 100 -23484968.00045 +194 100 13177083.33766 +207 100 2666666.667542 +208 100 -29111380.42657 +209 100 -26354166.66234 +210 100 106364.3267991 +211 100 21158575.86493 +212 100 2.682209014893e-07 +213 100 -6275817.570742 +214 100 -35539993.23945 +215 100 29843749.99544 +101 101 1 +102 102 222322244.5873 +103 102 6540964.785291 +105 102 -43497213.84184 +106 102 -28815373.67546 +108 102 22102059.00906 +109 102 777468.7684572 +189 102 -22126192.23639 +190 102 12497197.81285 +191 102 12109027.78176 +192 102 -76387958.09069 +193 102 4527089.824043 +194 102 64843055.54491 +210 102 -9519773.826409 +211 102 -6275817.570743 +212 102 -7655972.222158 +213 102 15798034.7999 +214 102 3270482.394257 +215 102 -12968611.10898 +216 102 -35347304.85947 +217 102 -14407686.84483 +218 102 20312500.00667 +219 102 -14510689.24923 +220 102 388734.3844201 +221 102 1171666.664472 +103 103 224877122.8958 +105 103 -28815373.67546 +106 103 -33223688.46138 +108 103 -9889197.896457 +109 103 -28933494.0074 +189 103 12497197.81285 +190 103 -29834312.51127 +191 103 -16666666.67214 +192 103 4527089.824043 +193 103 -23556043.72965 +194 103 -3489583.333103 +210 103 -942484.2356579 +211 103 -35539993.23945 +212 103 -29843749.99475 +213 103 3270482.394257 +214 103 17075473.95481 +215 103 9.536743164063e-07 +216 103 -14407686.84483 +217 103 -30210542.16671 +218 103 16666666.67214 +219 103 -4944598.950664 +220 103 -40028465.77003 +221 103 33333333.32786 +104 104 1 +105 105 127424615.7113 +106 105 30705630.14674 +108 105 -33305390.29881 +109 105 -3184626.319285 +192 105 -11712307.86995 +193 105 647184.9243208 +194 105 -299305.5539346 +213 105 -35347304.85947 +214 105 -14407686.84483 +215 105 -20312500.00667 +216 105 6046162.064774 +217 105 15352815.08093 +218 105 8124999.998666 +219 105 -43850090.99987 +220 105 -1592313.160427 +221 105 -36263194.43806 +106 106 114252738.9443 +108 106 7482040.345629 +109 106 21421084.31006 +192 106 -4686148.410764 +193 106 -37626369.49388 +194 106 -33333333.32786 +213 106 -14407686.84483 +214 106 -30210542.16671 +215 106 -16666666.67214 +216 106 15352815.08093 +217 106 -539776.3219635 +218 106 6666666.665572 +219 106 3741020.174657 +220 106 -16486853.68196 +221 106 3333333.334428 +107 107 1 +108 108 110688934.0263 +109 108 -22110802.09829 +192 108 -24181082.63358 +193 108 12258979.8306 +194 108 15950694.44968 +213 108 -14510689.24923 +214 108 -4944598.950664 +215 108 -7551944.445206 +216 108 -43850090.99987 +217 108 3741020.174657 +218 108 36263194.43892 +219 108 4221029.5472 +220 108 -11055401.05459 +221 108 -6380277.77673 +109 109 110682264.8289 +192 109 12258979.8306 +193 109 -26023208.832 +194 109 -16666666.67214 +213 109 388734.38442 +214 109 -40028465.77003 +215 109 -33333333.32786 +216 109 -1592313.160427 +217 109 -16486853.68196 +218 109 3333333.334428 +219 109 -11055401.05459 +220 109 4217694.948508 +221 109 6666666.665572 +110 110 1 +111 111 571119749.839 +112 111 53333333.32457 +113 111 -5.960464477539e-06 +114 111 -292913008.3249 +115 111 -53333332.8979 +116 111 6.556510925293e-06 +117 111 19534202.10867 +118 111 42666666.23299 +119 111 -1.490116119385e-06 +222 111 45108925.89256 +223 111 13333333.33771 +224 111 13177222.19231 +225 111 -107413106.5112 +226 111 -13333333.23104 +227 111 -65886110.96157 +228 111 -9767101.054335 +229 111 10666666.5635 +230 111 -13177221.94221 +112 112 491115909.0416 +113 112 -2.855678641392e-06 +114 112 -53333332.68457 +115 112 -42244300.58137 +116 112 2.145767211914e-06 +117 112 63999999.34949 +118 112 19534202.10866 +119 112 -2.384185791016e-06 +222 112 13333333.33771 +223 112 25107965.68335 +224 112 10541666.55379 +225 112 -13333333.17771 +226 112 -44745929.54446 +227 112 -13177083.26329 +228 112 15999999.84525 +229 112 -9767101.054335 +230 112 15812499.93082 +113 113 565941879.2302 +114 113 6.943941116333e-06 +115 113 1.609325408936e-06 +116 113 5277897.861165 +117 113 -2.145767211914e-06 +118 113 -1.54972076416e-06 +119 113 52091205.62311 +222 113 -13177222.19232 +223 113 -10541666.5538 +224 113 -118970561.1562 +225 113 -65886110.96157 +226 113 -13177083.28808 +227 113 -89840137.25117 +228 113 -19765832.91331 +229 113 10541666.62055 +230 113 -26045602.81156 +114 114 988947148.5376 +115 114 53333332.25791 +116 114 -8.940696716309e-06 +117 114 31359232.67644 +118 114 -53333332.8979 +119 114 1.251697540283e-06 +120 114 -198223262.271 +121 114 2.98023223877e-07 +122 114 5.960464477539e-08 +123 114 -75155545.7747 +124 114 53333333.32457 +125 114 -1.490116119385e-08 +222 114 -107413106.5112 +223 114 -13333333.17771 +224 114 65886110.96157 +225 114 100730268.7541 +226 114 13333333.07105 +227 114 0.02774140238762 +228 114 -26345045.89131 +229 114 -13333333.23105 +230 114 16471527.49884 +231 114 -88624220.55292 +232 114 2.235174179077e-07 +233 114 -65886111.10029 +234 114 -28555987.69793 +235 114 13333333.33771 +236 114 -16471527.78319 +115 115 844940234.7245 +116 115 -7.867813110352e-06 +117 115 -53333332.68457 +118 115 -155306402.5315 +119 115 5.394220352173e-06 +120 115 3.576278686523e-07 +121 115 36444678.54407 +122 115 -4.172325134277e-07 +123 115 53333333.32457 +124 115 -59154777.5129 +125 115 2.98023223877e-08 +222 115 -13333333.23104 +223 115 -44745929.54447 +224 115 13177083.28808 +225 115 13333333.07105 +226 115 64728540.28304 +227 115 0.022192299366 +228 115 -13333333.17771 +229 115 -73011454.71628 +230 115 52708333.03581 +231 115 1.9371509552e-07 +232 115 -29957235.32024 +233 115 -3.8743019104e-07 +234 115 13333333.33771 +235 115 -24555795.63051 +236 115 13177083.33766 +116 116 914512974.9691 +117 116 1.728534698486e-06 +118 116 4.559755325317e-06 +119 116 62880662.12465 +120 116 1.192092895508e-07 +121 116 -4.768371582031e-07 +122 116 66375066.93519 +123 116 4.470348358154e-08 +124 116 -4.470348358154e-08 +125 116 -9005963.440553 +222 116 65886110.96157 +223 116 13177083.26329 +224 116 -89840137.25118 +225 116 -0.0277450978756 +226 116 -0.02219566702843 +227 116 -162055805.4842 +228 116 16471527.35667 +229 116 52708332.94687 +230 116 -75439445.29918 +231 116 -65886111.10029 +232 116 -2.831220626831e-07 +233 116 -87588646.48668 +234 116 -16471527.78319 +235 116 13177083.33766 +236 116 -28297094.18124 +117 117 571119749.839 +118 117 53333333.32457 +119 117 -6.198883056641e-06 +120 117 -75155545.77471 +121 117 -53333333.32457 +122 117 5.066394805908e-07 +123 117 -292913008.3249 +124 117 -53333332.8979 +125 117 6.556510925293e-06 +126 117 19534202.10867 +127 117 42666666.23299 +128 117 -1.490116119385e-06 +222 117 -9767101.054335 +223 117 15999999.84525 +224 117 19765832.91331 +225 117 -26345045.8913 +226 117 -13333333.17771 +227 117 -16471527.35667 +228 117 45108925.89256 +229 117 13333333.33771 +230 117 13177222.19231 +231 117 -28555987.69793 +232 117 -13333333.33771 +233 117 -16471527.78319 +234 117 -107413106.5112 +235 117 -13333333.23104 +236 117 -65886110.96157 +237 117 -9767101.054335 +238 117 10666666.5635 +239 117 -13177221.94221 +118 118 491115909.0416 +119 118 -2.974887930942e-06 +120 118 -53333333.32457 +121 118 -59154777.5129 +122 118 2.086162567139e-07 +123 118 -53333332.68457 +124 118 -42244300.58137 +125 118 2.145767211914e-06 +126 118 63999999.34949 +127 118 19534202.10866 +128 118 -2.384185791016e-06 +222 118 10666666.5635 +223 118 -9767101.054336 +224 118 -10541666.62055 +225 118 -13333333.23105 +226 118 -73011454.71627 +227 118 -52708332.94687 +228 118 13333333.33771 +229 118 25107965.68335 +230 118 10541666.55379 +231 118 -13333333.33771 +232 118 -24555795.63051 +233 118 -13177083.33766 +234 118 -13333333.17771 +235 118 -44745929.54446 +236 118 -13177083.26329 +237 118 15999999.84525 +238 118 -9767101.054335 +239 118 15812499.93082 +119 119 565941879.2302 +120 119 5.811452865601e-07 +121 119 3.129243850708e-07 +122 119 -9005963.440556 +123 119 6.943941116333e-06 +124 119 1.609325408936e-06 +125 119 5277897.861165 +126 119 -2.145767211914e-06 +127 119 -1.54972076416e-06 +128 119 52091205.62311 +222 119 13177221.94221 +223 119 -15812499.93082 +224 119 -26045602.81156 +225 119 -16471527.49884 +226 119 -52708333.03581 +227 119 -75439445.29917 +228 119 -13177222.19232 +229 119 -10541666.5538 +230 119 -118970561.1562 +231 119 -16471527.78319 +232 119 -13177083.33766 +233 119 -28297094.18124 +234 119 -65886110.96157 +235 119 -13177083.28808 +236 119 -89840137.25117 +237 119 -19765832.91331 +238 119 10541666.62055 +239 119 -26045602.81156 +120 120 913791605.4334 +121 120 7.748603820801e-06 +122 120 -2.622604370117e-06 +123 120 126048980.7912 +124 120 -2.175569534302e-06 +125 120 -1.490116119385e-06 +129 120 -198223262.271 +130 120 2.98023223877e-07 +131 120 5.960464477539e-08 +132 120 -75155545.7747 +133 120 53333333.32457 +134 120 -1.490116119385e-08 +225 120 -88624220.55292 +226 120 1.043081283569e-07 +227 120 65886111.10029 +228 120 -28555987.69793 +229 120 -13333333.33771 +230 120 16471527.78319 +231 120 72174281.7049 +232 120 1.728534698486e-06 +233 120 1.221895217896e-06 +234 120 -7556159.747413 +235 120 -7.450580596924e-07 +236 120 1.341104507446e-06 +240 120 -88624220.55292 +241 120 2.235174179077e-07 +242 120 -65886111.10029 +243 120 -28555987.69793 +244 120 13333333.33771 +245 120 -16471527.78319 +121 121 785785459.402 +122 121 -1.788139343262e-06 +123 121 -2.086162567139e-06 +124 121 -76617423.53181 +125 121 5.066394805908e-07 +129 121 3.576278686523e-07 +130 121 36444678.54407 +131 121 -4.172325134277e-07 +132 121 53333333.32457 +133 121 -59154777.5129 +134 121 2.98023223877e-08 +225 121 4.470348358154e-08 +226 121 -29957235.32024 +227 121 2.831220626831e-07 +228 121 -13333333.33771 +229 121 -24555795.63051 +230 121 13177083.33766 +231 121 1.728534698486e-06 +232 121 40172745.1813 +233 121 -5.960464477539e-08 +234 121 -7.003545761108e-07 +235 121 -58222760.85313 +236 121 52708333.32467 +240 121 1.9371509552e-07 +241 121 -29957235.32024 +242 121 -3.8743019104e-07 +243 121 13333333.33771 +244 121 -24555795.63051 +245 121 13177083.33766 +122 122 905507012.9075 +123 122 -1.668930053711e-06 +124 122 4.470348358154e-07 +125 122 123977832.6588 +129 122 1.192092895508e-07 +130 122 -4.768371582031e-07 +131 122 66375066.93519 +132 122 4.470348358154e-08 +133 122 -4.470348358154e-08 +134 122 -9005963.440553 +225 122 65886111.10029 +226 122 3.8743019104e-07 +227 122 -87588646.48668 +228 122 16471527.78319 +229 122 13177083.33766 +230 122 -28297094.18124 +231 122 8.642673492432e-07 +232 122 1.788139343262e-07 +233 122 -190352899.3709 +234 122 1.475214958191e-06 +235 122 52708333.32467 +236 122 -73187955.0487 +240 122 -65886111.10029 +241 122 -2.831220626831e-07 +242 122 -87588646.48668 +243 122 -16471527.78319 +244 122 13177083.33766 +245 122 -28297094.18124 +123 123 988947148.5376 +124 123 53333332.25791 +125 123 -9.298324584961e-06 +126 123 31359232.67644 +127 123 -53333332.8979 +128 123 1.251697540283e-06 +129 123 -75155545.77471 +130 123 -53333333.32457 +131 123 5.066394805908e-07 +132 123 -198223262.271 +133 123 2.98023223877e-07 +134 123 5.960464477539e-08 +135 123 -75155545.7747 +136 123 53333333.32457 +137 123 -1.490116119385e-08 +225 123 -28555987.69793 +226 123 13333333.33771 +227 123 16471527.78319 +228 123 -107413106.5112 +229 123 -13333333.17771 +230 123 65886110.96157 +231 123 -7556159.747413 +232 123 -3.278255462646e-07 +233 123 -1.206994056702e-06 +234 123 100730268.7541 +235 123 13333333.07105 +236 123 0.02774140238762 +237 123 -26345045.89131 +238 123 -13333333.23105 +239 123 16471527.49884 +240 123 -28555987.69793 +241 123 -13333333.33771 +242 123 -16471527.78319 +243 123 -88624220.55292 +244 123 2.235174179077e-07 +245 123 -65886111.10029 +246 123 -28555987.69793 +247 123 13333333.33771 +248 123 -16471527.78319 +124 124 844940234.7245 +125 124 -7.987022399902e-06 +126 124 -53333332.68457 +127 124 -155306402.5315 +128 124 5.394220352173e-06 +129 124 -53333333.32457 +130 124 -59154777.5129 +131 124 2.086162567139e-07 +132 124 3.576278686523e-07 +133 124 36444678.54407 +134 124 -4.172325134277e-07 +135 124 53333333.32457 +136 124 -59154777.5129 +137 124 2.98023223877e-08 +225 124 13333333.33771 +226 124 -24555795.63051 +227 124 -13177083.33766 +228 124 -13333333.23104 +229 124 -44745929.54447 +230 124 13177083.28808 +231 124 -2.98023223877e-07 +232 124 -58222760.85313 +233 124 -52708333.32467 +234 124 13333333.07105 +235 124 64728540.28304 +236 124 0.022192299366 +237 124 -13333333.17771 +238 124 -73011454.71628 +239 124 52708333.03581 +240 124 -13333333.33771 +241 124 -24555795.63051 +242 124 -13177083.33766 +243 124 1.9371509552e-07 +244 124 -29957235.32024 +245 124 -3.8743019104e-07 +246 124 13333333.33771 +247 124 -24555795.63051 +248 124 13177083.33766 +125 125 914512974.9691 +126 125 1.728534698486e-06 +127 125 4.559755325317e-06 +128 125 62880662.12465 +129 125 5.811452865601e-07 +130 125 3.129243850708e-07 +131 125 -9005963.440556 +132 125 1.192092895508e-07 +133 125 -4.768371582031e-07 +134 125 66375066.93519 +135 125 4.470348358154e-08 +136 125 -4.470348358154e-08 +137 125 -9005963.440553 +225 125 16471527.78319 +226 125 -13177083.33766 +227 125 -28297094.18124 +228 125 65886110.96157 +229 125 13177083.26329 +230 125 -89840137.25118 +231 125 -9.983777999878e-07 +232 125 -52708333.32467 +233 125 -73187955.04869 +234 125 -0.0277450978756 +235 125 -0.02219566702843 +236 125 -162055805.4842 +237 125 16471527.35667 +238 125 52708332.94687 +239 125 -75439445.29918 +240 125 -16471527.78319 +241 125 -13177083.33766 +242 125 -28297094.18124 +243 125 -65886111.10029 +244 125 -2.831220626831e-07 +245 125 -87588646.48668 +246 125 -16471527.78319 +247 125 13177083.33766 +248 125 -28297094.18124 +126 126 571119749.839 +127 126 53333333.32457 +128 126 -6.198883056641e-06 +132 126 -75155545.77471 +133 126 -53333333.32457 +134 126 5.066394805908e-07 +135 126 -292913008.3249 +136 126 -53333332.8979 +137 126 6.556510925293e-06 +138 126 19534202.10867 +139 126 42666666.23299 +140 126 -1.490116119385e-06 +228 126 -9767101.054335 +229 126 15999999.84525 +230 126 19765832.91331 +234 126 -26345045.8913 +235 126 -13333333.17771 +236 126 -16471527.35667 +237 126 45108925.89256 +238 126 13333333.33771 +239 126 13177222.19231 +243 126 -28555987.69793 +244 126 -13333333.33771 +245 126 -16471527.78319 +246 126 -107413106.5112 +247 126 -13333333.23104 +248 126 -65886110.96157 +249 126 -9767101.054335 +250 126 10666666.5635 +251 126 -13177221.94221 +127 127 491115909.0416 +128 127 -2.974887930942e-06 +132 127 -53333333.32457 +133 127 -59154777.5129 +134 127 2.086162567139e-07 +135 127 -53333332.68457 +136 127 -42244300.58137 +137 127 2.145767211914e-06 +138 127 63999999.34949 +139 127 19534202.10866 +140 127 -2.384185791016e-06 +228 127 10666666.5635 +229 127 -9767101.054336 +230 127 -10541666.62055 +234 127 -13333333.23105 +235 127 -73011454.71627 +236 127 -52708332.94687 +237 127 13333333.33771 +238 127 25107965.68335 +239 127 10541666.55379 +243 127 -13333333.33771 +244 127 -24555795.63051 +245 127 -13177083.33766 +246 127 -13333333.17771 +247 127 -44745929.54446 +248 127 -13177083.26329 +249 127 15999999.84525 +250 127 -9767101.054335 +251 127 15812499.93082 +128 128 565941879.2302 +132 128 5.811452865601e-07 +133 128 3.129243850708e-07 +134 128 -9005963.440556 +135 128 6.943941116333e-06 +136 128 1.609325408936e-06 +137 128 5277897.861165 +138 128 -2.145767211914e-06 +139 128 -1.54972076416e-06 +140 128 52091205.62311 +228 128 13177221.94221 +229 128 -15812499.93082 +230 128 -26045602.81156 +234 128 -16471527.49884 +235 128 -52708333.03581 +236 128 -75439445.29917 +237 128 -13177222.19232 +238 128 -10541666.5538 +239 128 -118970561.1562 +243 128 -16471527.78319 +244 128 -13177083.33766 +245 128 -28297094.18124 +246 128 -65886110.96157 +247 128 -13177083.28808 +248 128 -89840137.25117 +249 128 -19765832.91331 +250 128 10541666.62055 +251 128 -26045602.81156 +129 129 913791605.4334 +130 129 7.748603820801e-06 +131 129 -2.622604370117e-06 +132 129 126048980.7912 +133 129 -2.175569534302e-06 +134 129 -1.490116119385e-06 +141 129 -198223262.271 +142 129 2.98023223877e-07 +143 129 5.960464477539e-08 +144 129 -75155545.7747 +145 129 53333333.32457 +146 129 -1.490116119385e-08 +231 129 -88624220.55292 +232 129 1.043081283569e-07 +233 129 65886111.10029 +234 129 -28555987.69793 +235 129 -13333333.33771 +236 129 16471527.78319 +240 129 72174281.7049 +241 129 1.728534698486e-06 +242 129 1.221895217896e-06 +243 129 -7556159.747413 +244 129 -7.450580596924e-07 +245 129 1.341104507446e-06 +252 129 -88624220.55292 +253 129 2.235174179077e-07 +254 129 -65886111.10029 +255 129 -28555987.69793 +256 129 13333333.33771 +257 129 -16471527.78319 +130 130 785785459.402 +131 130 -1.788139343262e-06 +132 130 -2.086162567139e-06 +133 130 -76617423.53181 +134 130 5.066394805908e-07 +141 130 3.576278686523e-07 +142 130 36444678.54407 +143 130 -4.172325134277e-07 +144 130 53333333.32457 +145 130 -59154777.5129 +146 130 2.98023223877e-08 +231 130 4.470348358154e-08 +232 130 -29957235.32024 +233 130 2.831220626831e-07 +234 130 -13333333.33771 +235 130 -24555795.63051 +236 130 13177083.33766 +240 130 1.728534698486e-06 +241 130 40172745.1813 +242 130 -5.960464477539e-08 +243 130 -7.003545761108e-07 +244 130 -58222760.85313 +245 130 52708333.32467 +252 130 1.9371509552e-07 +253 130 -29957235.32024 +254 130 -3.8743019104e-07 +255 130 13333333.33771 +256 130 -24555795.63051 +257 130 13177083.33766 +131 131 905507012.9075 +132 131 -1.668930053711e-06 +133 131 4.470348358154e-07 +134 131 123977832.6588 +141 131 1.192092895508e-07 +142 131 -4.768371582031e-07 +143 131 66375066.93519 +144 131 4.470348358154e-08 +145 131 -4.470348358154e-08 +146 131 -9005963.440553 +231 131 65886111.10029 +232 131 3.8743019104e-07 +233 131 -87588646.48668 +234 131 16471527.78319 +235 131 13177083.33766 +236 131 -28297094.18124 +240 131 8.642673492432e-07 +241 131 1.788139343262e-07 +242 131 -190352899.3709 +243 131 1.475214958191e-06 +244 131 52708333.32467 +245 131 -73187955.0487 +252 131 -65886111.10029 +253 131 -2.831220626831e-07 +254 131 -87588646.48668 +255 131 -16471527.78319 +256 131 13177083.33766 +257 131 -28297094.18124 +132 132 913791605.4334 +133 132 7.748603820801e-06 +134 132 -2.622604370117e-06 +135 132 126048980.7912 +136 132 -2.175569534302e-06 +137 132 -1.490116119385e-06 +141 132 -75155545.77471 +142 132 -53333333.32457 +143 132 5.066394805908e-07 +144 132 -198223262.271 +145 132 2.98023223877e-07 +146 132 5.960464477539e-08 +147 132 -75155545.7747 +148 132 53333333.32457 +149 132 -1.490116119385e-08 +231 132 -28555987.69793 +232 132 13333333.33771 +233 132 16471527.78319 +234 132 -88624220.55292 +235 132 1.043081283569e-07 +236 132 65886111.10029 +237 132 -28555987.69793 +238 132 -13333333.33771 +239 132 16471527.78319 +240 132 -7556159.747413 +241 132 -3.278255462646e-07 +242 132 -1.206994056702e-06 +243 132 72174281.7049 +244 132 1.728534698486e-06 +245 132 1.221895217896e-06 +246 132 -7556159.747413 +247 132 -7.450580596924e-07 +248 132 1.341104507446e-06 +252 132 -28555987.69793 +253 132 -13333333.33771 +254 132 -16471527.78319 +255 132 -88624220.55292 +256 132 2.235174179077e-07 +257 132 -65886111.10029 +258 132 -28555987.69793 +259 132 13333333.33771 +260 132 -16471527.78319 +133 133 785785459.402 +134 133 -1.788139343262e-06 +135 133 -2.086162567139e-06 +136 133 -76617423.53181 +137 133 5.066394805908e-07 +141 133 -53333333.32457 +142 133 -59154777.5129 +143 133 2.086162567139e-07 +144 133 3.576278686523e-07 +145 133 36444678.54407 +146 133 -4.172325134277e-07 +147 133 53333333.32457 +148 133 -59154777.5129 +149 133 2.98023223877e-08 +231 133 13333333.33771 +232 133 -24555795.63051 +233 133 -13177083.33766 +234 133 4.470348358154e-08 +235 133 -29957235.32024 +236 133 2.831220626831e-07 +237 133 -13333333.33771 +238 133 -24555795.63051 +239 133 13177083.33766 +240 133 -2.98023223877e-07 +241 133 -58222760.85313 +242 133 -52708333.32467 +243 133 1.728534698486e-06 +244 133 40172745.1813 +245 133 -5.960464477539e-08 +246 133 -7.003545761108e-07 +247 133 -58222760.85313 +248 133 52708333.32467 +252 133 -13333333.33771 +253 133 -24555795.63051 +254 133 -13177083.33766 +255 133 1.9371509552e-07 +256 133 -29957235.32024 +257 133 -3.8743019104e-07 +258 133 13333333.33771 +259 133 -24555795.63051 +260 133 13177083.33766 +134 134 905507012.9075 +135 134 -1.668930053711e-06 +136 134 4.470348358154e-07 +137 134 123977832.6588 +141 134 5.811452865601e-07 +142 134 3.129243850708e-07 +143 134 -9005963.440556 +144 134 1.192092895508e-07 +145 134 -4.768371582031e-07 +146 134 66375066.93519 +147 134 4.470348358154e-08 +148 134 -4.470348358154e-08 +149 134 -9005963.440553 +231 134 16471527.78319 +232 134 -13177083.33766 +233 134 -28297094.18124 +234 134 65886111.10029 +235 134 3.8743019104e-07 +236 134 -87588646.48668 +237 134 16471527.78319 +238 134 13177083.33766 +239 134 -28297094.18124 +240 134 -9.983777999878e-07 +241 134 -52708333.32467 +242 134 -73187955.04869 +243 134 8.642673492432e-07 +244 134 1.788139343262e-07 +245 134 -190352899.3709 +246 134 1.475214958191e-06 +247 134 52708333.32467 +248 134 -73187955.0487 +252 134 -16471527.78319 +253 134 -13177083.33766 +254 134 -28297094.18124 +255 134 -65886111.10029 +256 134 -2.831220626831e-07 +257 134 -87588646.48668 +258 134 -16471527.78319 +259 134 13177083.33766 +260 134 -28297094.18124 +135 135 988947148.5376 +136 135 53333332.25791 +137 135 -9.298324584961e-06 +138 135 31359232.67644 +139 135 -53333332.8979 +140 135 1.251697540283e-06 +144 135 -75155545.77471 +145 135 -53333333.32457 +146 135 5.066394805908e-07 +147 135 -198223262.271 +148 135 2.98023223877e-07 +149 135 5.960464477539e-08 +150 135 -75155545.7747 +151 135 53333333.32457 +152 135 -1.490116119385e-08 +234 135 -28555987.69793 +235 135 13333333.33771 +236 135 16471527.78319 +237 135 -107413106.5112 +238 135 -13333333.17771 +239 135 65886110.96157 +243 135 -7556159.747413 +244 135 -3.278255462646e-07 +245 135 -1.206994056702e-06 +246 135 100730268.7541 +247 135 13333333.07105 +248 135 0.02774140238762 +249 135 -26345045.89131 +250 135 -13333333.23105 +251 135 16471527.49884 +255 135 -28555987.69793 +256 135 -13333333.33771 +257 135 -16471527.78319 +258 135 -88624220.55292 +259 135 2.235174179077e-07 +260 135 -65886111.10029 +261 135 -28555987.69793 +262 135 13333333.33771 +263 135 -16471527.78319 +136 136 844940234.7245 +137 136 -7.987022399902e-06 +138 136 -53333332.68457 +139 136 -155306402.5315 +140 136 5.394220352173e-06 +144 136 -53333333.32457 +145 136 -59154777.5129 +146 136 2.086162567139e-07 +147 136 3.576278686523e-07 +148 136 36444678.54407 +149 136 -4.172325134277e-07 +150 136 53333333.32457 +151 136 -59154777.5129 +152 136 2.98023223877e-08 +234 136 13333333.33771 +235 136 -24555795.63051 +236 136 -13177083.33766 +237 136 -13333333.23104 +238 136 -44745929.54447 +239 136 13177083.28808 +243 136 -2.98023223877e-07 +244 136 -58222760.85313 +245 136 -52708333.32467 +246 136 13333333.07105 +247 136 64728540.28304 +248 136 0.022192299366 +249 136 -13333333.17771 +250 136 -73011454.71628 +251 136 52708333.03581 +255 136 -13333333.33771 +256 136 -24555795.63051 +257 136 -13177083.33766 +258 136 1.9371509552e-07 +259 136 -29957235.32024 +260 136 -3.8743019104e-07 +261 136 13333333.33771 +262 136 -24555795.63051 +263 136 13177083.33766 +137 137 914512974.9691 +138 137 1.728534698486e-06 +139 137 4.559755325317e-06 +140 137 62880662.12465 +144 137 5.811452865601e-07 +145 137 3.129243850708e-07 +146 137 -9005963.440556 +147 137 1.192092895508e-07 +148 137 -4.768371582031e-07 +149 137 66375066.93519 +150 137 4.470348358154e-08 +151 137 -4.470348358154e-08 +152 137 -9005963.440553 +234 137 16471527.78319 +235 137 -13177083.33766 +236 137 -28297094.18124 +237 137 65886110.96157 +238 137 13177083.26329 +239 137 -89840137.25118 +243 137 -9.983777999878e-07 +244 137 -52708333.32467 +245 137 -73187955.04869 +246 137 -0.0277450978756 +247 137 -0.02219566702843 +248 137 -162055805.4842 +249 137 16471527.35667 +250 137 52708332.94687 +251 137 -75439445.29918 +255 137 -16471527.78319 +256 137 -13177083.33766 +257 137 -28297094.18124 +258 137 -65886111.10029 +259 137 -2.831220626831e-07 +260 137 -87588646.48668 +261 137 -16471527.78319 +262 137 13177083.33766 +263 137 -28297094.18124 +138 138 571119749.839 +139 138 53333333.32457 +140 138 -6.198883056641e-06 +147 138 -75155545.77471 +148 138 -53333333.32457 +149 138 5.066394805908e-07 +150 138 -292913008.3249 +151 138 -53333332.8979 +152 138 6.556510925293e-06 +153 138 19534202.10867 +154 138 42666666.23299 +155 138 -1.490116119385e-06 +237 138 -9767101.054335 +238 138 15999999.84525 +239 138 19765832.91331 +246 138 -26345045.8913 +247 138 -13333333.17771 +248 138 -16471527.35667 +249 138 45108925.89256 +250 138 13333333.33771 +251 138 13177222.19231 +258 138 -28555987.69793 +259 138 -13333333.33771 +260 138 -16471527.78319 +261 138 -107413106.5112 +262 138 -13333333.23104 +263 138 -65886110.96157 +264 138 -9767101.054335 +265 138 10666666.5635 +266 138 -13177221.94221 +139 139 491115909.0416 +140 139 -2.974887930942e-06 +147 139 -53333333.32457 +148 139 -59154777.5129 +149 139 2.086162567139e-07 +150 139 -53333332.68457 +151 139 -42244300.58137 +152 139 2.145767211914e-06 +153 139 63999999.34949 +154 139 19534202.10866 +155 139 -2.384185791016e-06 +237 139 10666666.5635 +238 139 -9767101.054336 +239 139 -10541666.62055 +246 139 -13333333.23105 +247 139 -73011454.71627 +248 139 -52708332.94687 +249 139 13333333.33771 +250 139 25107965.68335 +251 139 10541666.55379 +258 139 -13333333.33771 +259 139 -24555795.63051 +260 139 -13177083.33766 +261 139 -13333333.17771 +262 139 -44745929.54446 +263 139 -13177083.26329 +264 139 15999999.84525 +265 139 -9767101.054335 +266 139 15812499.93082 +140 140 565941879.2302 +147 140 5.811452865601e-07 +148 140 3.129243850708e-07 +149 140 -9005963.440556 +150 140 6.943941116333e-06 +151 140 1.609325408936e-06 +152 140 5277897.861165 +153 140 -2.145767211914e-06 +154 140 -1.54972076416e-06 +155 140 52091205.62311 +237 140 13177221.94221 +238 140 -15812499.93082 +239 140 -26045602.81156 +246 140 -16471527.49884 +247 140 -52708333.03581 +248 140 -75439445.29917 +249 140 -13177222.19232 +250 140 -10541666.5538 +251 140 -118970561.1562 +258 140 -16471527.78319 +259 140 -13177083.33766 +260 140 -28297094.18124 +261 140 -65886110.96157 +262 140 -13177083.28808 +263 140 -89840137.25117 +264 140 -19765832.91331 +265 140 10541666.62055 +266 140 -26045602.81156 +141 141 913791605.4334 +142 141 7.748603820801e-06 +143 141 -2.622604370117e-06 +144 141 126048980.7912 +145 141 -2.175569534302e-06 +146 141 -1.490116119385e-06 +156 141 -198223262.271 +157 141 2.98023223877e-07 +158 141 5.960464477539e-08 +159 141 -75155545.7747 +160 141 53333333.32457 +161 141 -1.490116119385e-08 +240 141 -88624220.55292 +241 141 1.043081283569e-07 +242 141 65886111.10029 +243 141 -28555987.69793 +244 141 -13333333.33771 +245 141 16471527.78319 +252 141 72174281.7049 +253 141 1.728534698486e-06 +254 141 1.221895217896e-06 +255 141 -7556159.747413 +256 141 -7.450580596924e-07 +257 141 1.341104507446e-06 +267 141 -88624220.55292 +268 141 2.235174179077e-07 +269 141 -65886111.10029 +270 141 -28555987.69793 +271 141 13333333.33771 +272 141 -16471527.78319 +142 142 785785459.402 +143 142 -1.788139343262e-06 +144 142 -2.086162567139e-06 +145 142 -76617423.53181 +146 142 5.066394805908e-07 +156 142 3.576278686523e-07 +157 142 36444678.54407 +158 142 -4.172325134277e-07 +159 142 53333333.32457 +160 142 -59154777.5129 +161 142 2.98023223877e-08 +240 142 4.470348358154e-08 +241 142 -29957235.32024 +242 142 2.831220626831e-07 +243 142 -13333333.33771 +244 142 -24555795.63051 +245 142 13177083.33766 +252 142 1.728534698486e-06 +253 142 40172745.1813 +254 142 -5.960464477539e-08 +255 142 -7.003545761108e-07 +256 142 -58222760.85313 +257 142 52708333.32467 +267 142 1.9371509552e-07 +268 142 -29957235.32024 +269 142 -3.8743019104e-07 +270 142 13333333.33771 +271 142 -24555795.63051 +272 142 13177083.33766 +143 143 905507012.9075 +144 143 -1.668930053711e-06 +145 143 4.470348358154e-07 +146 143 123977832.6588 +156 143 1.192092895508e-07 +157 143 -4.768371582031e-07 +158 143 66375066.93519 +159 143 4.470348358154e-08 +160 143 -4.470348358154e-08 +161 143 -9005963.440553 +240 143 65886111.10029 +241 143 3.8743019104e-07 +242 143 -87588646.48668 +243 143 16471527.78319 +244 143 13177083.33766 +245 143 -28297094.18124 +252 143 8.642673492432e-07 +253 143 1.788139343262e-07 +254 143 -190352899.3709 +255 143 1.475214958191e-06 +256 143 52708333.32467 +257 143 -73187955.0487 +267 143 -65886111.10029 +268 143 -2.831220626831e-07 +269 143 -87588646.48668 +270 143 -16471527.78319 +271 143 13177083.33766 +272 143 -28297094.18124 +144 144 913791605.4334 +145 144 7.748603820801e-06 +146 144 -2.622604370117e-06 +147 144 126048980.7912 +148 144 -2.175569534302e-06 +149 144 -1.490116119385e-06 +156 144 -75155545.77471 +157 144 -53333333.32457 +158 144 5.066394805908e-07 +159 144 -198223262.271 +160 144 2.98023223877e-07 +161 144 5.960464477539e-08 +162 144 -75155545.7747 +163 144 53333333.32457 +164 144 -1.490116119385e-08 +240 144 -28555987.69793 +241 144 13333333.33771 +242 144 16471527.78319 +243 144 -88624220.55292 +244 144 1.043081283569e-07 +245 144 65886111.10029 +246 144 -28555987.69793 +247 144 -13333333.33771 +248 144 16471527.78319 +252 144 -7556159.747413 +253 144 -3.278255462646e-07 +254 144 -1.206994056702e-06 +255 144 72174281.7049 +256 144 1.728534698486e-06 +257 144 1.221895217896e-06 +258 144 -7556159.747413 +259 144 -7.450580596924e-07 +260 144 1.341104507446e-06 +267 144 -28555987.69793 +268 144 -13333333.33771 +269 144 -16471527.78319 +270 144 -88624220.55292 +271 144 2.235174179077e-07 +272 144 -65886111.10029 +273 144 -28555987.69793 +274 144 13333333.33771 +275 144 -16471527.78319 +145 145 785785459.402 +146 145 -1.788139343262e-06 +147 145 -2.086162567139e-06 +148 145 -76617423.53181 +149 145 5.066394805908e-07 +156 145 -53333333.32457 +157 145 -59154777.5129 +158 145 2.086162567139e-07 +159 145 3.576278686523e-07 +160 145 36444678.54407 +161 145 -4.172325134277e-07 +162 145 53333333.32457 +163 145 -59154777.5129 +164 145 2.98023223877e-08 +240 145 13333333.33771 +241 145 -24555795.63051 +242 145 -13177083.33766 +243 145 4.470348358154e-08 +244 145 -29957235.32024 +245 145 2.831220626831e-07 +246 145 -13333333.33771 +247 145 -24555795.63051 +248 145 13177083.33766 +252 145 -2.98023223877e-07 +253 145 -58222760.85313 +254 145 -52708333.32467 +255 145 1.728534698486e-06 +256 145 40172745.1813 +257 145 -5.960464477539e-08 +258 145 -7.003545761108e-07 +259 145 -58222760.85313 +260 145 52708333.32467 +267 145 -13333333.33771 +268 145 -24555795.63051 +269 145 -13177083.33766 +270 145 1.9371509552e-07 +271 145 -29957235.32024 +272 145 -3.8743019104e-07 +273 145 13333333.33771 +274 145 -24555795.63051 +275 145 13177083.33766 +146 146 905507012.9075 +147 146 -1.668930053711e-06 +148 146 4.470348358154e-07 +149 146 123977832.6588 +156 146 5.811452865601e-07 +157 146 3.129243850708e-07 +158 146 -9005963.440556 +159 146 1.192092895508e-07 +160 146 -4.768371582031e-07 +161 146 66375066.93519 +162 146 4.470348358154e-08 +163 146 -4.470348358154e-08 +164 146 -9005963.440553 +240 146 16471527.78319 +241 146 -13177083.33766 +242 146 -28297094.18124 +243 146 65886111.10029 +244 146 3.8743019104e-07 +245 146 -87588646.48668 +246 146 16471527.78319 +247 146 13177083.33766 +248 146 -28297094.18124 +252 146 -9.983777999878e-07 +253 146 -52708333.32467 +254 146 -73187955.04869 +255 146 8.642673492432e-07 +256 146 1.788139343262e-07 +257 146 -190352899.3709 +258 146 1.475214958191e-06 +259 146 52708333.32467 +260 146 -73187955.0487 +267 146 -16471527.78319 +268 146 -13177083.33766 +269 146 -28297094.18124 +270 146 -65886111.10029 +271 146 -2.831220626831e-07 +272 146 -87588646.48668 +273 146 -16471527.78319 +274 146 13177083.33766 +275 146 -28297094.18124 +147 147 913791605.4334 +148 147 7.748603820801e-06 +149 147 -2.622604370117e-06 +150 147 126048980.7912 +151 147 -2.175569534302e-06 +152 147 -1.490116119385e-06 +159 147 -75155545.77471 +160 147 -53333333.32457 +161 147 5.066394805908e-07 +162 147 -198223262.271 +163 147 2.98023223877e-07 +164 147 5.960464477539e-08 +165 147 -75155545.7747 +166 147 53333333.32457 +167 147 -1.490116119385e-08 +243 147 -28555987.69793 +244 147 13333333.33771 +245 147 16471527.78319 +246 147 -88624220.55292 +247 147 1.043081283569e-07 +248 147 65886111.10029 +249 147 -28555987.69793 +250 147 -13333333.33771 +251 147 16471527.78319 +255 147 -7556159.747413 +256 147 -3.278255462646e-07 +257 147 -1.206994056702e-06 +258 147 72174281.7049 +259 147 1.728534698486e-06 +260 147 1.221895217896e-06 +261 147 -7556159.747413 +262 147 -7.450580596924e-07 +263 147 1.341104507446e-06 +270 147 -28555987.69793 +271 147 -13333333.33771 +272 147 -16471527.78319 +273 147 -88624220.55292 +274 147 2.235174179077e-07 +275 147 -65886111.10029 +276 147 -28555987.69793 +277 147 13333333.33771 +278 147 -16471527.78319 +148 148 785785459.402 +149 148 -1.788139343262e-06 +150 148 -2.086162567139e-06 +151 148 -76617423.53181 +152 148 5.066394805908e-07 +159 148 -53333333.32457 +160 148 -59154777.5129 +161 148 2.086162567139e-07 +162 148 3.576278686523e-07 +163 148 36444678.54407 +164 148 -4.172325134277e-07 +165 148 53333333.32457 +166 148 -59154777.5129 +167 148 2.98023223877e-08 +243 148 13333333.33771 +244 148 -24555795.63051 +245 148 -13177083.33766 +246 148 4.470348358154e-08 +247 148 -29957235.32024 +248 148 2.831220626831e-07 +249 148 -13333333.33771 +250 148 -24555795.63051 +251 148 13177083.33766 +255 148 -2.98023223877e-07 +256 148 -58222760.85313 +257 148 -52708333.32467 +258 148 1.728534698486e-06 +259 148 40172745.1813 +260 148 -5.960464477539e-08 +261 148 -7.003545761108e-07 +262 148 -58222760.85313 +263 148 52708333.32467 +270 148 -13333333.33771 +271 148 -24555795.63051 +272 148 -13177083.33766 +273 148 1.9371509552e-07 +274 148 -29957235.32024 +275 148 -3.8743019104e-07 +276 148 13333333.33771 +277 148 -24555795.63051 +278 148 13177083.33766 +149 149 905507012.9075 +150 149 -1.668930053711e-06 +151 149 4.470348358154e-07 +152 149 123977832.6588 +159 149 5.811452865601e-07 +160 149 3.129243850708e-07 +161 149 -9005963.440556 +162 149 1.192092895508e-07 +163 149 -4.768371582031e-07 +164 149 66375066.93519 +165 149 4.470348358154e-08 +166 149 -4.470348358154e-08 +167 149 -9005963.440553 +243 149 16471527.78319 +244 149 -13177083.33766 +245 149 -28297094.18124 +246 149 65886111.10029 +247 149 3.8743019104e-07 +248 149 -87588646.48668 +249 149 16471527.78319 +250 149 13177083.33766 +251 149 -28297094.18124 +255 149 -9.983777999878e-07 +256 149 -52708333.32467 +257 149 -73187955.04869 +258 149 8.642673492432e-07 +259 149 1.788139343262e-07 +260 149 -190352899.3709 +261 149 1.475214958191e-06 +262 149 52708333.32467 +263 149 -73187955.0487 +270 149 -16471527.78319 +271 149 -13177083.33766 +272 149 -28297094.18124 +273 149 -65886111.10029 +274 149 -2.831220626831e-07 +275 149 -87588646.48668 +276 149 -16471527.78319 +277 149 13177083.33766 +278 149 -28297094.18124 +150 150 988947148.5376 +151 150 53333332.25791 +152 150 -9.298324584961e-06 +153 150 31359232.67644 +154 150 -53333332.8979 +155 150 1.251697540283e-06 +162 150 -75155545.77471 +163 150 -53333333.32457 +164 150 5.066394805908e-07 +165 150 -198223262.271 +166 150 2.98023223877e-07 +167 150 5.960464477539e-08 +168 150 -75155545.7747 +169 150 53333333.32457 +170 150 -1.490116119385e-08 +246 150 -28555987.69793 +247 150 13333333.33771 +248 150 16471527.78319 +249 150 -107413106.5112 +250 150 -13333333.17771 +251 150 65886110.96157 +258 150 -7556159.747413 +259 150 -3.278255462646e-07 +260 150 -1.206994056702e-06 +261 150 100730268.7541 +262 150 13333333.07105 +263 150 0.02774140238762 +264 150 -26345045.89131 +265 150 -13333333.23105 +266 150 16471527.49884 +273 150 -28555987.69793 +274 150 -13333333.33771 +275 150 -16471527.78319 +276 150 -88624220.55292 +277 150 2.235174179077e-07 +278 150 -65886111.10029 +279 150 -28555987.69793 +280 150 13333333.33771 +281 150 -16471527.78319 +151 151 844940234.7245 +152 151 -7.987022399902e-06 +153 151 -53333332.68457 +154 151 -155306402.5315 +155 151 5.394220352173e-06 +162 151 -53333333.32457 +163 151 -59154777.5129 +164 151 2.086162567139e-07 +165 151 3.576278686523e-07 +166 151 36444678.54407 +167 151 -4.172325134277e-07 +168 151 53333333.32457 +169 151 -59154777.5129 +170 151 2.98023223877e-08 +246 151 13333333.33771 +247 151 -24555795.63051 +248 151 -13177083.33766 +249 151 -13333333.23104 +250 151 -44745929.54447 +251 151 13177083.28808 +258 151 -2.98023223877e-07 +259 151 -58222760.85313 +260 151 -52708333.32467 +261 151 13333333.07105 +262 151 64728540.28304 +263 151 0.022192299366 +264 151 -13333333.17771 +265 151 -73011454.71628 +266 151 52708333.03581 +273 151 -13333333.33771 +274 151 -24555795.63051 +275 151 -13177083.33766 +276 151 1.9371509552e-07 +277 151 -29957235.32024 +278 151 -3.8743019104e-07 +279 151 13333333.33771 +280 151 -24555795.63051 +281 151 13177083.33766 +152 152 914512974.9691 +153 152 1.728534698486e-06 +154 152 4.559755325317e-06 +155 152 62880662.12465 +162 152 5.811452865601e-07 +163 152 3.129243850708e-07 +164 152 -9005963.440556 +165 152 1.192092895508e-07 +166 152 -4.768371582031e-07 +167 152 66375066.93519 +168 152 4.470348358154e-08 +169 152 -4.470348358154e-08 +170 152 -9005963.440553 +246 152 16471527.78319 +247 152 -13177083.33766 +248 152 -28297094.18124 +249 152 65886110.96157 +250 152 13177083.26329 +251 152 -89840137.25118 +258 152 -9.983777999878e-07 +259 152 -52708333.32467 +260 152 -73187955.04869 +261 152 -0.0277450978756 +262 152 -0.02219566702843 +263 152 -162055805.4842 +264 152 16471527.35667 +265 152 52708332.94687 +266 152 -75439445.29918 +273 152 -16471527.78319 +274 152 -13177083.33766 +275 152 -28297094.18124 +276 152 -65886111.10029 +277 152 -2.831220626831e-07 +278 152 -87588646.48668 +279 152 -16471527.78319 +280 152 13177083.33766 +281 152 -28297094.18124 +153 153 571119749.839 +154 153 53333333.32457 +155 153 -6.198883056641e-06 +165 153 -75155545.77471 +166 153 -53333333.32457 +167 153 5.066394805908e-07 +168 153 -292913008.3249 +169 153 -53333332.8979 +170 153 6.556510925293e-06 +171 153 19534202.10867 +172 153 42666666.23299 +173 153 -1.490116119385e-06 +249 153 -9767101.054335 +250 153 15999999.84525 +251 153 19765832.91331 +261 153 -26345045.8913 +262 153 -13333333.17771 +263 153 -16471527.35667 +264 153 45108925.89256 +265 153 13333333.33771 +266 153 13177222.19231 +276 153 -28555987.69793 +277 153 -13333333.33771 +278 153 -16471527.78319 +279 153 -107413106.5112 +280 153 -13333333.23104 +281 153 -65886110.96157 +282 153 -9767101.054335 +283 153 10666666.5635 +284 153 -13177221.94221 +154 154 491115909.0416 +155 154 -2.974887930942e-06 +165 154 -53333333.32457 +166 154 -59154777.5129 +167 154 2.086162567139e-07 +168 154 -53333332.68457 +169 154 -42244300.58137 +170 154 2.145767211914e-06 +171 154 63999999.34949 +172 154 19534202.10866 +173 154 -2.384185791016e-06 +249 154 10666666.5635 +250 154 -9767101.054336 +251 154 -10541666.62055 +261 154 -13333333.23105 +262 154 -73011454.71627 +263 154 -52708332.94687 +264 154 13333333.33771 +265 154 25107965.68335 +266 154 10541666.55379 +276 154 -13333333.33771 +277 154 -24555795.63051 +278 154 -13177083.33766 +279 154 -13333333.17771 +280 154 -44745929.54446 +281 154 -13177083.26329 +282 154 15999999.84525 +283 154 -9767101.054335 +284 154 15812499.93082 +155 155 565941879.2302 +165 155 5.811452865601e-07 +166 155 3.129243850708e-07 +167 155 -9005963.440556 +168 155 6.943941116333e-06 +169 155 1.609325408936e-06 +170 155 5277897.861165 +171 155 -2.145767211914e-06 +172 155 -1.54972076416e-06 +173 155 52091205.62311 +249 155 13177221.94221 +250 155 -15812499.93082 +251 155 -26045602.81156 +261 155 -16471527.49884 +262 155 -52708333.03581 +263 155 -75439445.29917 +264 155 -13177222.19232 +265 155 -10541666.5538 +266 155 -118970561.1562 +276 155 -16471527.78319 +277 155 -13177083.33766 +278 155 -28297094.18124 +279 155 -65886110.96157 +280 155 -13177083.28808 +281 155 -89840137.25117 +282 155 -19765832.91331 +283 155 10541666.62055 +284 155 -26045602.81156 +156 156 913791605.4334 +157 156 7.748603820801e-06 +158 156 -2.622604370117e-06 +159 156 126048980.7912 +160 156 -2.175569534302e-06 +161 156 -1.490116119385e-06 +174 156 -198223262.271 +175 156 2.98023223877e-07 +176 156 5.960464477539e-08 +177 156 -75155545.7747 +178 156 53333333.32457 +179 156 -1.490116119385e-08 +252 156 -88624220.55292 +253 156 1.043081283569e-07 +254 156 65886111.10029 +255 156 -28555987.69793 +256 156 -13333333.33771 +257 156 16471527.78319 +267 156 72174281.7049 +268 156 1.728534698486e-06 +269 156 1.221895217896e-06 +270 156 -7556159.747413 +271 156 -7.450580596924e-07 +272 156 1.341104507446e-06 +285 156 -88624220.55292 +286 156 2.235174179077e-07 +287 156 -65886111.10029 +288 156 -28555987.69793 +289 156 13333333.33771 +290 156 -16471527.78319 +157 157 785785459.402 +158 157 -1.788139343262e-06 +159 157 -2.086162567139e-06 +160 157 -76617423.53181 +161 157 5.066394805908e-07 +174 157 3.576278686523e-07 +175 157 36444678.54407 +176 157 -4.172325134277e-07 +177 157 53333333.32457 +178 157 -59154777.5129 +179 157 2.98023223877e-08 +252 157 4.470348358154e-08 +253 157 -29957235.32024 +254 157 2.831220626831e-07 +255 157 -13333333.33771 +256 157 -24555795.63051 +257 157 13177083.33766 +267 157 1.728534698486e-06 +268 157 40172745.1813 +269 157 -5.960464477539e-08 +270 157 -7.003545761108e-07 +271 157 -58222760.85313 +272 157 52708333.32467 +285 157 1.9371509552e-07 +286 157 -29957235.32024 +287 157 -3.8743019104e-07 +288 157 13333333.33771 +289 157 -24555795.63051 +290 157 13177083.33766 +158 158 905507012.9075 +159 158 -1.668930053711e-06 +160 158 4.470348358154e-07 +161 158 123977832.6588 +174 158 1.192092895508e-07 +175 158 -4.768371582031e-07 +176 158 66375066.93519 +177 158 4.470348358154e-08 +178 158 -4.470348358154e-08 +179 158 -9005963.440553 +252 158 65886111.10029 +253 158 3.8743019104e-07 +254 158 -87588646.48668 +255 158 16471527.78319 +256 158 13177083.33766 +257 158 -28297094.18124 +267 158 8.642673492432e-07 +268 158 1.788139343262e-07 +269 158 -190352899.3709 +270 158 1.475214958191e-06 +271 158 52708333.32467 +272 158 -73187955.0487 +285 158 -65886111.10029 +286 158 -2.831220626831e-07 +287 158 -87588646.48668 +288 158 -16471527.78319 +289 158 13177083.33766 +290 158 -28297094.18124 +159 159 913791605.4334 +160 159 7.748603820801e-06 +161 159 -2.622604370117e-06 +162 159 126048980.7912 +163 159 -2.175569534302e-06 +164 159 -1.490116119385e-06 +174 159 -75155545.77471 +175 159 -53333333.32457 +176 159 5.066394805908e-07 +177 159 -198223262.271 +178 159 2.98023223877e-07 +179 159 5.960464477539e-08 +180 159 -75155545.7747 +181 159 53333333.32457 +182 159 -1.490116119385e-08 +252 159 -28555987.69793 +253 159 13333333.33771 +254 159 16471527.78319 +255 159 -88624220.55292 +256 159 1.043081283569e-07 +257 159 65886111.10029 +258 159 -28555987.69793 +259 159 -13333333.33771 +260 159 16471527.78319 +267 159 -7556159.747413 +268 159 -3.278255462646e-07 +269 159 -1.206994056702e-06 +270 159 72174281.7049 +271 159 1.728534698486e-06 +272 159 1.221895217896e-06 +273 159 -7556159.747413 +274 159 -7.450580596924e-07 +275 159 1.341104507446e-06 +285 159 -28555987.69793 +286 159 -13333333.33771 +287 159 -16471527.78319 +288 159 -88624220.55292 +289 159 2.235174179077e-07 +290 159 -65886111.10029 +291 159 -28555987.69793 +292 159 13333333.33771 +293 159 -16471527.78319 +160 160 785785459.402 +161 160 -1.788139343262e-06 +162 160 -2.086162567139e-06 +163 160 -76617423.53181 +164 160 5.066394805908e-07 +174 160 -53333333.32457 +175 160 -59154777.5129 +176 160 2.086162567139e-07 +177 160 3.576278686523e-07 +178 160 36444678.54407 +179 160 -4.172325134277e-07 +180 160 53333333.32457 +181 160 -59154777.5129 +182 160 2.98023223877e-08 +252 160 13333333.33771 +253 160 -24555795.63051 +254 160 -13177083.33766 +255 160 4.470348358154e-08 +256 160 -29957235.32024 +257 160 2.831220626831e-07 +258 160 -13333333.33771 +259 160 -24555795.63051 +260 160 13177083.33766 +267 160 -2.98023223877e-07 +268 160 -58222760.85313 +269 160 -52708333.32467 +270 160 1.728534698486e-06 +271 160 40172745.1813 +272 160 -5.960464477539e-08 +273 160 -7.003545761108e-07 +274 160 -58222760.85313 +275 160 52708333.32467 +285 160 -13333333.33771 +286 160 -24555795.63051 +287 160 -13177083.33766 +288 160 1.9371509552e-07 +289 160 -29957235.32024 +290 160 -3.8743019104e-07 +291 160 13333333.33771 +292 160 -24555795.63051 +293 160 13177083.33766 +161 161 905507012.9075 +162 161 -1.668930053711e-06 +163 161 4.470348358154e-07 +164 161 123977832.6588 +174 161 5.811452865601e-07 +175 161 3.129243850708e-07 +176 161 -9005963.440556 +177 161 1.192092895508e-07 +178 161 -4.768371582031e-07 +179 161 66375066.93519 +180 161 4.470348358154e-08 +181 161 -4.470348358154e-08 +182 161 -9005963.440553 +252 161 16471527.78319 +253 161 -13177083.33766 +254 161 -28297094.18124 +255 161 65886111.10029 +256 161 3.8743019104e-07 +257 161 -87588646.48668 +258 161 16471527.78319 +259 161 13177083.33766 +260 161 -28297094.18124 +267 161 -9.983777999878e-07 +268 161 -52708333.32467 +269 161 -73187955.04869 +270 161 8.642673492432e-07 +271 161 1.788139343262e-07 +272 161 -190352899.3709 +273 161 1.475214958191e-06 +274 161 52708333.32467 +275 161 -73187955.0487 +285 161 -16471527.78319 +286 161 -13177083.33766 +287 161 -28297094.18124 +288 161 -65886111.10029 +289 161 -2.831220626831e-07 +290 161 -87588646.48668 +291 161 -16471527.78319 +292 161 13177083.33766 +293 161 -28297094.18124 +162 162 913791605.4334 +163 162 7.748603820801e-06 +164 162 -2.622604370117e-06 +165 162 126048980.7912 +166 162 -2.175569534302e-06 +167 162 -1.490116119385e-06 +177 162 -75155545.77471 +178 162 -53333333.32457 +179 162 5.066394805908e-07 +180 162 -198223262.271 +181 162 2.98023223877e-07 +182 162 5.960464477539e-08 +183 162 -75155545.7747 +184 162 53333333.32457 +185 162 -1.490116119385e-08 +255 162 -28555987.69793 +256 162 13333333.33771 +257 162 16471527.78319 +258 162 -88624220.55292 +259 162 1.043081283569e-07 +260 162 65886111.10029 +261 162 -28555987.69793 +262 162 -13333333.33771 +263 162 16471527.78319 +270 162 -7556159.747413 +271 162 -3.278255462646e-07 +272 162 -1.206994056702e-06 +273 162 72174281.7049 +274 162 1.728534698486e-06 +275 162 1.221895217896e-06 +276 162 -7556159.747413 +277 162 -7.450580596924e-07 +278 162 1.341104507446e-06 +288 162 -28555987.69793 +289 162 -13333333.33771 +290 162 -16471527.78319 +291 162 -88624220.55292 +292 162 2.235174179077e-07 +293 162 -65886111.10029 +294 162 -28555987.69793 +295 162 13333333.33771 +296 162 -16471527.78319 +163 163 785785459.402 +164 163 -1.788139343262e-06 +165 163 -2.086162567139e-06 +166 163 -76617423.53181 +167 163 5.066394805908e-07 +177 163 -53333333.32457 +178 163 -59154777.5129 +179 163 2.086162567139e-07 +180 163 3.576278686523e-07 +181 163 36444678.54407 +182 163 -4.172325134277e-07 +183 163 53333333.32457 +184 163 -59154777.5129 +185 163 2.98023223877e-08 +255 163 13333333.33771 +256 163 -24555795.63051 +257 163 -13177083.33766 +258 163 4.470348358154e-08 +259 163 -29957235.32024 +260 163 2.831220626831e-07 +261 163 -13333333.33771 +262 163 -24555795.63051 +263 163 13177083.33766 +270 163 -2.98023223877e-07 +271 163 -58222760.85313 +272 163 -52708333.32467 +273 163 1.728534698486e-06 +274 163 40172745.1813 +275 163 -5.960464477539e-08 +276 163 -7.003545761108e-07 +277 163 -58222760.85313 +278 163 52708333.32467 +288 163 -13333333.33771 +289 163 -24555795.63051 +290 163 -13177083.33766 +291 163 1.9371509552e-07 +292 163 -29957235.32024 +293 163 -3.8743019104e-07 +294 163 13333333.33771 +295 163 -24555795.63051 +296 163 13177083.33766 +164 164 905507012.9075 +165 164 -1.668930053711e-06 +166 164 4.470348358154e-07 +167 164 123977832.6588 +177 164 5.811452865601e-07 +178 164 3.129243850708e-07 +179 164 -9005963.440556 +180 164 1.192092895508e-07 +181 164 -4.768371582031e-07 +182 164 66375066.93519 +183 164 4.470348358154e-08 +184 164 -4.470348358154e-08 +185 164 -9005963.440553 +255 164 16471527.78319 +256 164 -13177083.33766 +257 164 -28297094.18124 +258 164 65886111.10029 +259 164 3.8743019104e-07 +260 164 -87588646.48668 +261 164 16471527.78319 +262 164 13177083.33766 +263 164 -28297094.18124 +270 164 -9.983777999878e-07 +271 164 -52708333.32467 +272 164 -73187955.04869 +273 164 8.642673492432e-07 +274 164 1.788139343262e-07 +275 164 -190352899.3709 +276 164 1.475214958191e-06 +277 164 52708333.32467 +278 164 -73187955.0487 +288 164 -16471527.78319 +289 164 -13177083.33766 +290 164 -28297094.18124 +291 164 -65886111.10029 +292 164 -2.831220626831e-07 +293 164 -87588646.48668 +294 164 -16471527.78319 +295 164 13177083.33766 +296 164 -28297094.18124 +165 165 913791605.4334 +166 165 7.748603820801e-06 +167 165 -2.622604370117e-06 +168 165 126048980.7912 +169 165 -2.175569534302e-06 +170 165 -1.490116119385e-06 +180 165 -75155545.77471 +181 165 -53333333.32457 +182 165 5.066394805908e-07 +183 165 -198223262.271 +184 165 2.98023223877e-07 +185 165 5.960464477539e-08 +186 165 -75155545.7747 +187 165 53333333.32457 +188 165 -1.490116119385e-08 +258 165 -28555987.69793 +259 165 13333333.33771 +260 165 16471527.78319 +261 165 -88624220.55292 +262 165 1.043081283569e-07 +263 165 65886111.10029 +264 165 -28555987.69793 +265 165 -13333333.33771 +266 165 16471527.78319 +273 165 -7556159.747413 +274 165 -3.278255462646e-07 +275 165 -1.206994056702e-06 +276 165 72174281.7049 +277 165 1.728534698486e-06 +278 165 1.221895217896e-06 +279 165 -7556159.747413 +280 165 -7.450580596924e-07 +281 165 1.341104507446e-06 +291 165 -28555987.69793 +292 165 -13333333.33771 +293 165 -16471527.78319 +294 165 -88624220.55292 +295 165 2.235174179077e-07 +296 165 -65886111.10029 +297 165 -28555987.69793 +298 165 13333333.33771 +299 165 -16471527.78319 +166 166 785785459.402 +167 166 -1.788139343262e-06 +168 166 -2.086162567139e-06 +169 166 -76617423.53181 +170 166 5.066394805908e-07 +180 166 -53333333.32457 +181 166 -59154777.5129 +182 166 2.086162567139e-07 +183 166 3.576278686523e-07 +184 166 36444678.54407 +185 166 -4.172325134277e-07 +186 166 53333333.32457 +187 166 -59154777.5129 +188 166 2.98023223877e-08 +258 166 13333333.33771 +259 166 -24555795.63051 +260 166 -13177083.33766 +261 166 4.470348358154e-08 +262 166 -29957235.32024 +263 166 2.831220626831e-07 +264 166 -13333333.33771 +265 166 -24555795.63051 +266 166 13177083.33766 +273 166 -2.98023223877e-07 +274 166 -58222760.85313 +275 166 -52708333.32467 +276 166 1.728534698486e-06 +277 166 40172745.1813 +278 166 -5.960464477539e-08 +279 166 -7.003545761108e-07 +280 166 -58222760.85313 +281 166 52708333.32467 +291 166 -13333333.33771 +292 166 -24555795.63051 +293 166 -13177083.33766 +294 166 1.9371509552e-07 +295 166 -29957235.32024 +296 166 -3.8743019104e-07 +297 166 13333333.33771 +298 166 -24555795.63051 +299 166 13177083.33766 +167 167 905507012.9075 +168 167 -1.668930053711e-06 +169 167 4.470348358154e-07 +170 167 123977832.6588 +180 167 5.811452865601e-07 +181 167 3.129243850708e-07 +182 167 -9005963.440556 +183 167 1.192092895508e-07 +184 167 -4.768371582031e-07 +185 167 66375066.93519 +186 167 4.470348358154e-08 +187 167 -4.470348358154e-08 +188 167 -9005963.440553 +258 167 16471527.78319 +259 167 -13177083.33766 +260 167 -28297094.18124 +261 167 65886111.10029 +262 167 3.8743019104e-07 +263 167 -87588646.48668 +264 167 16471527.78319 +265 167 13177083.33766 +266 167 -28297094.18124 +273 167 -9.983777999878e-07 +274 167 -52708333.32467 +275 167 -73187955.04869 +276 167 8.642673492432e-07 +277 167 1.788139343262e-07 +278 167 -190352899.3709 +279 167 1.475214958191e-06 +280 167 52708333.32467 +281 167 -73187955.0487 +291 167 -16471527.78319 +292 167 -13177083.33766 +293 167 -28297094.18124 +294 167 -65886111.10029 +295 167 -2.831220626831e-07 +296 167 -87588646.48668 +297 167 -16471527.78319 +298 167 13177083.33766 +299 167 -28297094.18124 +168 168 988947148.5376 +169 168 53333332.25791 +170 168 -9.298324584961e-06 +171 168 31359232.67644 +172 168 -53333332.8979 +173 168 1.251697540283e-06 +183 168 -75155545.77471 +184 168 -53333333.32457 +185 168 5.066394805908e-07 +186 168 -198223262.271 +187 168 2.98023223877e-07 +188 168 5.960464477539e-08 +189 168 -75155545.7747 +190 168 53333333.32457 +191 168 -1.490116119385e-08 +261 168 -28555987.69793 +262 168 13333333.33771 +263 168 16471527.78319 +264 168 -107413106.5112 +265 168 -13333333.17771 +266 168 65886110.96157 +276 168 -7556159.747413 +277 168 -3.278255462646e-07 +278 168 -1.206994056702e-06 +279 168 100730268.7541 +280 168 13333333.07105 +281 168 0.02774140238762 +282 168 -26345045.89131 +283 168 -13333333.23105 +284 168 16471527.49884 +294 168 -28555987.69793 +295 168 -13333333.33771 +296 168 -16471527.78319 +297 168 -88624220.55292 +298 168 2.235174179077e-07 +299 168 -65886111.10029 +300 168 -28555987.69793 +301 168 13333333.33771 +302 168 -16471527.78319 +169 169 844940234.7245 +170 169 -7.987022399902e-06 +171 169 -53333332.68457 +172 169 -155306402.5315 +173 169 5.394220352173e-06 +183 169 -53333333.32457 +184 169 -59154777.5129 +185 169 2.086162567139e-07 +186 169 3.576278686523e-07 +187 169 36444678.54407 +188 169 -4.172325134277e-07 +189 169 53333333.32457 +190 169 -59154777.5129 +191 169 2.98023223877e-08 +261 169 13333333.33771 +262 169 -24555795.63051 +263 169 -13177083.33766 +264 169 -13333333.23104 +265 169 -44745929.54447 +266 169 13177083.28808 +276 169 -2.98023223877e-07 +277 169 -58222760.85313 +278 169 -52708333.32467 +279 169 13333333.07105 +280 169 64728540.28304 +281 169 0.022192299366 +282 169 -13333333.17771 +283 169 -73011454.71628 +284 169 52708333.03581 +294 169 -13333333.33771 +295 169 -24555795.63051 +296 169 -13177083.33766 +297 169 1.9371509552e-07 +298 169 -29957235.32024 +299 169 -3.8743019104e-07 +300 169 13333333.33771 +301 169 -24555795.63051 +302 169 13177083.33766 +170 170 914512974.9691 +171 170 1.728534698486e-06 +172 170 4.559755325317e-06 +173 170 62880662.12465 +183 170 5.811452865601e-07 +184 170 3.129243850708e-07 +185 170 -9005963.440556 +186 170 1.192092895508e-07 +187 170 -4.768371582031e-07 +188 170 66375066.93519 +189 170 4.470348358154e-08 +190 170 -4.470348358154e-08 +191 170 -9005963.440553 +261 170 16471527.78319 +262 170 -13177083.33766 +263 170 -28297094.18124 +264 170 65886110.96157 +265 170 13177083.26329 +266 170 -89840137.25118 +276 170 -9.983777999878e-07 +277 170 -52708333.32467 +278 170 -73187955.04869 +279 170 -0.0277450978756 +280 170 -0.02219566702843 +281 170 -162055805.4842 +282 170 16471527.35667 +283 170 52708332.94687 +284 170 -75439445.29918 +294 170 -16471527.78319 +295 170 -13177083.33766 +296 170 -28297094.18124 +297 170 -65886111.10029 +298 170 -2.831220626831e-07 +299 170 -87588646.48668 +300 170 -16471527.78319 +301 170 13177083.33766 +302 170 -28297094.18124 +171 171 509154568.8248 +172 171 25085639.27704 +173 171 -5.960464477539e-07 +186 171 -75155545.77471 +187 171 -53333333.32457 +188 171 5.066394805908e-07 +189 171 -228025244.9359 +190 171 -25085638.85037 +191 171 7.152557373047e-07 +192 171 -4082989.550575 +193 171 42666666.23299 +194 171 -1.251697540283e-06 +264 171 -9767101.054335 +265 171 15999999.84525 +266 171 19765832.91331 +279 171 -26345045.8913 +280 171 -13333333.17771 +281 171 -16471527.35667 +282 171 37378109.13818 +283 171 6271409.822349 +284 171 11432222.19995 +297 171 -28555987.69793 +298 171 -13333333.33771 +299 171 -16471527.78319 +300 171 -87310926.38278 +301 171 -6271409.715683 +302 171 -57161110.99975 +303 171 -11791159.78617 +304 171 10666666.5635 +305 171 -9687222.01637 +172 172 472604990.7818 +173 172 -2.652406692505e-06 +186 172 -53333333.32457 +187 172 -59154777.5129 +188 172 2.086162567139e-07 +189 172 -25085638.63704 +190 172 9928432.40691 +191 172 2.384185791016e-07 +192 172 63999999.34949 +193 172 -34822221.9043 +194 172 -1.788139343262e-07 +264 172 10666666.5635 +265 172 -9767101.054336 +266 172 -10541666.62055 +279 172 -13333333.23105 +280 172 -73011454.71627 +281 172 -52708332.94687 +282 172 6271409.822349 +283 172 28240714.62293 +284 172 9145833.226567 +297 172 -13333333.33771 +298 172 -24555795.63051 +299 172 -13177083.33766 +300 172 -6271409.66235 +301 172 -27822507.01778 +302 172 -6197916.627156 +303 172 15999999.84526 +304 172 -19475967.87838 +305 172 18604166.53816 +173 173 522045024.059 +186 173 5.811452865601e-07 +187 173 3.129243850708e-07 +188 173 -9005963.440556 +189 173 7.450580596924e-07 +190 173 2.384185791016e-07 +191 173 26229073.67805 +192 173 -1.490116119385e-06 +193 173 2.384185791016e-07 +194 173 19851260.21887 +264 173 13177221.94221 +265 173 -15812499.93082 +266 173 -26045602.81156 +279 173 -16471527.49884 +280 173 -52708333.03581 +281 173 -75439445.29917 +282 173 -11432222.19995 +283 173 -9145833.22657 +284 173 -109250165.6029 +297 173 -16471527.78319 +298 173 -13177083.33766 +299 173 -28297094.18124 +300 173 -57161110.99975 +301 173 -6197916.651946 +302 173 -74255038.56586 +303 173 -14530833.02455 +304 173 14729166.53156 +305 173 -23758284.67089 +174 174 913791605.4334 +175 174 7.748603820801e-06 +176 174 -2.622604370117e-06 +177 174 126048980.7912 +178 174 -2.175569534302e-06 +179 174 -1.490116119385e-06 +195 174 -198223262.271 +196 174 2.98023223877e-07 +197 174 5.960464477539e-08 +198 174 -75155545.7747 +199 174 53333333.32457 +200 174 -1.490116119385e-08 +267 174 -88624220.55292 +268 174 1.043081283569e-07 +269 174 65886111.10029 +270 174 -28555987.69793 +271 174 -13333333.33771 +272 174 16471527.78319 +285 174 72174281.7049 +286 174 1.728534698486e-06 +287 174 1.221895217896e-06 +288 174 -7556159.747413 +289 174 -7.450580596924e-07 +290 174 1.341104507446e-06 +306 174 -88624220.55292 +307 174 2.235174179077e-07 +308 174 -65886111.10029 +309 174 -28555987.69793 +310 174 13333333.33771 +311 174 -16471527.78319 +175 175 785785459.402 +176 175 -1.788139343262e-06 +177 175 -2.086162567139e-06 +178 175 -76617423.53181 +179 175 5.066394805908e-07 +195 175 3.576278686523e-07 +196 175 36444678.54407 +197 175 -4.172325134277e-07 +198 175 53333333.32457 +199 175 -59154777.5129 +200 175 2.98023223877e-08 +267 175 4.470348358154e-08 +268 175 -29957235.32024 +269 175 2.831220626831e-07 +270 175 -13333333.33771 +271 175 -24555795.63051 +272 175 13177083.33766 +285 175 1.728534698486e-06 +286 175 40172745.1813 +287 175 -5.960464477539e-08 +288 175 -7.003545761108e-07 +289 175 -58222760.85313 +290 175 52708333.32467 +306 175 1.9371509552e-07 +307 175 -29957235.32024 +308 175 -3.8743019104e-07 +309 175 13333333.33771 +310 175 -24555795.63051 +311 175 13177083.33766 +176 176 905507012.9075 +177 176 -1.668930053711e-06 +178 176 4.470348358154e-07 +179 176 123977832.6588 +195 176 1.192092895508e-07 +196 176 -4.768371582031e-07 +197 176 66375066.93519 +198 176 4.470348358154e-08 +199 176 -4.470348358154e-08 +200 176 -9005963.440553 +267 176 65886111.10029 +268 176 3.8743019104e-07 +269 176 -87588646.48668 +270 176 16471527.78319 +271 176 13177083.33766 +272 176 -28297094.18124 +285 176 8.642673492432e-07 +286 176 1.788139343262e-07 +287 176 -190352899.3709 +288 176 1.475214958191e-06 +289 176 52708333.32467 +290 176 -73187955.0487 +306 176 -65886111.10029 +307 176 -2.831220626831e-07 +308 176 -87588646.48668 +309 176 -16471527.78319 +310 176 13177083.33766 +311 176 -28297094.18124 +177 177 913791605.4334 +178 177 7.748603820801e-06 +179 177 -2.622604370117e-06 +180 177 126048980.7912 +181 177 -2.175569534302e-06 +182 177 -1.490116119385e-06 +195 177 -75155545.77471 +196 177 -53333333.32457 +197 177 5.066394805908e-07 +198 177 -198223262.271 +199 177 2.98023223877e-07 +200 177 5.960464477539e-08 +201 177 -75155545.7747 +202 177 53333333.32457 +203 177 -1.490116119385e-08 +267 177 -28555987.69793 +268 177 13333333.33771 +269 177 16471527.78319 +270 177 -88624220.55292 +271 177 1.043081283569e-07 +272 177 65886111.10029 +273 177 -28555987.69793 +274 177 -13333333.33771 +275 177 16471527.78319 +285 177 -7556159.747413 +286 177 -3.278255462646e-07 +287 177 -1.206994056702e-06 +288 177 72174281.7049 +289 177 1.728534698486e-06 +290 177 1.221895217896e-06 +291 177 -7556159.747413 +292 177 -7.450580596924e-07 +293 177 1.341104507446e-06 +306 177 -28555987.69793 +307 177 -13333333.33771 +308 177 -16471527.78319 +309 177 -88624220.55292 +310 177 2.235174179077e-07 +311 177 -65886111.10029 +312 177 -28555987.69793 +313 177 13333333.33771 +314 177 -16471527.78319 +178 178 785785459.402 +179 178 -1.788139343262e-06 +180 178 -2.086162567139e-06 +181 178 -76617423.53181 +182 178 5.066394805908e-07 +195 178 -53333333.32457 +196 178 -59154777.5129 +197 178 2.086162567139e-07 +198 178 3.576278686523e-07 +199 178 36444678.54407 +200 178 -4.172325134277e-07 +201 178 53333333.32457 +202 178 -59154777.5129 +203 178 2.98023223877e-08 +267 178 13333333.33771 +268 178 -24555795.63051 +269 178 -13177083.33766 +270 178 4.470348358154e-08 +271 178 -29957235.32024 +272 178 2.831220626831e-07 +273 178 -13333333.33771 +274 178 -24555795.63051 +275 178 13177083.33766 +285 178 -2.98023223877e-07 +286 178 -58222760.85313 +287 178 -52708333.32467 +288 178 1.728534698486e-06 +289 178 40172745.1813 +290 178 -5.960464477539e-08 +291 178 -7.003545761108e-07 +292 178 -58222760.85313 +293 178 52708333.32467 +306 178 -13333333.33771 +307 178 -24555795.63051 +308 178 -13177083.33766 +309 178 1.9371509552e-07 +310 178 -29957235.32024 +311 178 -3.8743019104e-07 +312 178 13333333.33771 +313 178 -24555795.63051 +314 178 13177083.33766 +179 179 905507012.9075 +180 179 -1.668930053711e-06 +181 179 4.470348358154e-07 +182 179 123977832.6588 +195 179 5.811452865601e-07 +196 179 3.129243850708e-07 +197 179 -9005963.440556 +198 179 1.192092895508e-07 +199 179 -4.768371582031e-07 +200 179 66375066.93519 +201 179 4.470348358154e-08 +202 179 -4.470348358154e-08 +203 179 -9005963.440553 +267 179 16471527.78319 +268 179 -13177083.33766 +269 179 -28297094.18124 +270 179 65886111.10029 +271 179 3.8743019104e-07 +272 179 -87588646.48668 +273 179 16471527.78319 +274 179 13177083.33766 +275 179 -28297094.18124 +285 179 -9.983777999878e-07 +286 179 -52708333.32467 +287 179 -73187955.04869 +288 179 8.642673492432e-07 +289 179 1.788139343262e-07 +290 179 -190352899.3709 +291 179 1.475214958191e-06 +292 179 52708333.32467 +293 179 -73187955.0487 +306 179 -16471527.78319 +307 179 -13177083.33766 +308 179 -28297094.18124 +309 179 -65886111.10029 +310 179 -2.831220626831e-07 +311 179 -87588646.48668 +312 179 -16471527.78319 +313 179 13177083.33766 +314 179 -28297094.18124 +180 180 913791605.4334 +181 180 7.748603820801e-06 +182 180 -2.622604370117e-06 +183 180 126048980.7912 +184 180 -2.175569534302e-06 +185 180 -1.490116119385e-06 +198 180 -75155545.77471 +199 180 -53333333.32457 +200 180 5.066394805908e-07 +201 180 -198223262.271 +202 180 2.98023223877e-07 +203 180 5.960464477539e-08 +204 180 -75155545.7747 +205 180 53333333.32457 +206 180 -1.490116119385e-08 +270 180 -28555987.69793 +271 180 13333333.33771 +272 180 16471527.78319 +273 180 -88624220.55292 +274 180 1.043081283569e-07 +275 180 65886111.10029 +276 180 -28555987.69793 +277 180 -13333333.33771 +278 180 16471527.78319 +288 180 -7556159.747413 +289 180 -3.278255462646e-07 +290 180 -1.206994056702e-06 +291 180 72174281.7049 +292 180 1.728534698486e-06 +293 180 1.221895217896e-06 +294 180 -7556159.747413 +295 180 -7.450580596924e-07 +296 180 1.341104507446e-06 +309 180 -28555987.69793 +310 180 -13333333.33771 +311 180 -16471527.78319 +312 180 -88624220.55292 +313 180 2.235174179077e-07 +314 180 -65886111.10029 +315 180 -28555987.69793 +316 180 13333333.33771 +317 180 -16471527.78319 +181 181 785785459.402 +182 181 -1.788139343262e-06 +183 181 -2.086162567139e-06 +184 181 -76617423.53181 +185 181 5.066394805908e-07 +198 181 -53333333.32457 +199 181 -59154777.5129 +200 181 2.086162567139e-07 +201 181 3.576278686523e-07 +202 181 36444678.54407 +203 181 -4.172325134277e-07 +204 181 53333333.32457 +205 181 -59154777.5129 +206 181 2.98023223877e-08 +270 181 13333333.33771 +271 181 -24555795.63051 +272 181 -13177083.33766 +273 181 4.470348358154e-08 +274 181 -29957235.32024 +275 181 2.831220626831e-07 +276 181 -13333333.33771 +277 181 -24555795.63051 +278 181 13177083.33766 +288 181 -2.98023223877e-07 +289 181 -58222760.85313 +290 181 -52708333.32467 +291 181 1.728534698486e-06 +292 181 40172745.1813 +293 181 -5.960464477539e-08 +294 181 -7.003545761108e-07 +295 181 -58222760.85313 +296 181 52708333.32467 +309 181 -13333333.33771 +310 181 -24555795.63051 +311 181 -13177083.33766 +312 181 1.9371509552e-07 +313 181 -29957235.32024 +314 181 -3.8743019104e-07 +315 181 13333333.33771 +316 181 -24555795.63051 +317 181 13177083.33766 +182 182 905507012.9075 +183 182 -1.668930053711e-06 +184 182 4.470348358154e-07 +185 182 123977832.6588 +198 182 5.811452865601e-07 +199 182 3.129243850708e-07 +200 182 -9005963.440556 +201 182 1.192092895508e-07 +202 182 -4.768371582031e-07 +203 182 66375066.93519 +204 182 4.470348358154e-08 +205 182 -4.470348358154e-08 +206 182 -9005963.440553 +270 182 16471527.78319 +271 182 -13177083.33766 +272 182 -28297094.18124 +273 182 65886111.10029 +274 182 3.8743019104e-07 +275 182 -87588646.48668 +276 182 16471527.78319 +277 182 13177083.33766 +278 182 -28297094.18124 +288 182 -9.983777999878e-07 +289 182 -52708333.32467 +290 182 -73187955.04869 +291 182 8.642673492432e-07 +292 182 1.788139343262e-07 +293 182 -190352899.3709 +294 182 1.475214958191e-06 +295 182 52708333.32467 +296 182 -73187955.0487 +309 182 -16471527.78319 +310 182 -13177083.33766 +311 182 -28297094.18124 +312 182 -65886111.10029 +313 182 -2.831220626831e-07 +314 182 -87588646.48668 +315 182 -16471527.78319 +316 182 13177083.33766 +317 182 -28297094.18124 +183 183 913791605.4334 +184 183 7.748603820801e-06 +185 183 -2.622604370117e-06 +186 183 126048980.7912 +187 183 -2.175569534302e-06 +188 183 -1.490116119385e-06 +201 183 -75155545.77471 +202 183 -53333333.32457 +203 183 5.066394805908e-07 +204 183 -198223262.271 +205 183 2.98023223877e-07 +206 183 5.960464477539e-08 +207 183 -75155545.7747 +208 183 53333333.32457 +209 183 -1.490116119385e-08 +273 183 -28555987.69793 +274 183 13333333.33771 +275 183 16471527.78319 +276 183 -88624220.55292 +277 183 1.043081283569e-07 +278 183 65886111.10029 +279 183 -28555987.69793 +280 183 -13333333.33771 +281 183 16471527.78319 +291 183 -7556159.747413 +292 183 -3.278255462646e-07 +293 183 -1.206994056702e-06 +294 183 72174281.7049 +295 183 1.728534698486e-06 +296 183 1.221895217896e-06 +297 183 -7556159.747413 +298 183 -7.450580596924e-07 +299 183 1.341104507446e-06 +312 183 -28555987.69793 +313 183 -13333333.33771 +314 183 -16471527.78319 +315 183 -88624220.55292 +316 183 2.235174179077e-07 +317 183 -65886111.10029 +318 183 -28555987.69793 +319 183 13333333.33771 +320 183 -16471527.78319 +184 184 785785459.402 +185 184 -1.788139343262e-06 +186 184 -2.086162567139e-06 +187 184 -76617423.53181 +188 184 5.066394805908e-07 +201 184 -53333333.32457 +202 184 -59154777.5129 +203 184 2.086162567139e-07 +204 184 3.576278686523e-07 +205 184 36444678.54407 +206 184 -4.172325134277e-07 +207 184 53333333.32457 +208 184 -59154777.5129 +209 184 2.98023223877e-08 +273 184 13333333.33771 +274 184 -24555795.63051 +275 184 -13177083.33766 +276 184 4.470348358154e-08 +277 184 -29957235.32024 +278 184 2.831220626831e-07 +279 184 -13333333.33771 +280 184 -24555795.63051 +281 184 13177083.33766 +291 184 -2.98023223877e-07 +292 184 -58222760.85313 +293 184 -52708333.32467 +294 184 1.728534698486e-06 +295 184 40172745.1813 +296 184 -5.960464477539e-08 +297 184 -7.003545761108e-07 +298 184 -58222760.85313 +299 184 52708333.32467 +312 184 -13333333.33771 +313 184 -24555795.63051 +314 184 -13177083.33766 +315 184 1.9371509552e-07 +316 184 -29957235.32024 +317 184 -3.8743019104e-07 +318 184 13333333.33771 +319 184 -24555795.63051 +320 184 13177083.33766 +185 185 905507012.9075 +186 185 -1.668930053711e-06 +187 185 4.470348358154e-07 +188 185 123977832.6588 +201 185 5.811452865601e-07 +202 185 3.129243850708e-07 +203 185 -9005963.440556 +204 185 1.192092895508e-07 +205 185 -4.768371582031e-07 +206 185 66375066.93519 +207 185 4.470348358154e-08 +208 185 -4.470348358154e-08 +209 185 -9005963.440553 +273 185 16471527.78319 +274 185 -13177083.33766 +275 185 -28297094.18124 +276 185 65886111.10029 +277 185 3.8743019104e-07 +278 185 -87588646.48668 +279 185 16471527.78319 +280 185 13177083.33766 +281 185 -28297094.18124 +291 185 -9.983777999878e-07 +292 185 -52708333.32467 +293 185 -73187955.04869 +294 185 8.642673492432e-07 +295 185 1.788139343262e-07 +296 185 -190352899.3709 +297 185 1.475214958191e-06 +298 185 52708333.32467 +299 185 -73187955.0487 +312 185 -16471527.78319 +313 185 -13177083.33766 +314 185 -28297094.18124 +315 185 -65886111.10029 +316 185 -2.831220626831e-07 +317 185 -87588646.48668 +318 185 -16471527.78319 +319 185 13177083.33766 +320 185 -28297094.18124 +186 186 913791605.4334 +187 186 7.748603820801e-06 +188 186 -2.622604370117e-06 +189 186 126048980.7912 +190 186 -2.175569534302e-06 +191 186 -1.490116119385e-06 +204 186 -75155545.77471 +205 186 -53333333.32457 +206 186 5.066394805908e-07 +207 186 -198223262.271 +208 186 2.98023223877e-07 +209 186 5.960464477539e-08 +210 186 -75155545.7747 +211 186 53333333.32457 +212 186 -1.490116119385e-08 +276 186 -28555987.69793 +277 186 13333333.33771 +278 186 16471527.78319 +279 186 -88624220.55292 +280 186 1.043081283569e-07 +281 186 65886111.10029 +282 186 -28555987.69793 +283 186 -13333333.33771 +284 186 16471527.78319 +294 186 -7556159.747413 +295 186 -3.278255462646e-07 +296 186 -1.206994056702e-06 +297 186 72174281.7049 +298 186 1.728534698486e-06 +299 186 1.221895217896e-06 +300 186 -7556159.747413 +301 186 -7.450580596924e-07 +302 186 1.341104507446e-06 +315 186 -28555987.69793 +316 186 -13333333.33771 +317 186 -16471527.78319 +318 186 -88624220.55292 +319 186 2.235174179077e-07 +320 186 -65886111.10029 +321 186 -28555987.69793 +322 186 13333333.33771 +323 186 -16471527.78319 +187 187 785785459.402 +188 187 -1.788139343262e-06 +189 187 -2.086162567139e-06 +190 187 -76617423.53181 +191 187 5.066394805908e-07 +204 187 -53333333.32457 +205 187 -59154777.5129 +206 187 2.086162567139e-07 +207 187 3.576278686523e-07 +208 187 36444678.54407 +209 187 -4.172325134277e-07 +210 187 53333333.32457 +211 187 -59154777.5129 +212 187 2.98023223877e-08 +276 187 13333333.33771 +277 187 -24555795.63051 +278 187 -13177083.33766 +279 187 4.470348358154e-08 +280 187 -29957235.32024 +281 187 2.831220626831e-07 +282 187 -13333333.33771 +283 187 -24555795.63051 +284 187 13177083.33766 +294 187 -2.98023223877e-07 +295 187 -58222760.85313 +296 187 -52708333.32467 +297 187 1.728534698486e-06 +298 187 40172745.1813 +299 187 -5.960464477539e-08 +300 187 -7.003545761108e-07 +301 187 -58222760.85313 +302 187 52708333.32467 +315 187 -13333333.33771 +316 187 -24555795.63051 +317 187 -13177083.33766 +318 187 1.9371509552e-07 +319 187 -29957235.32024 +320 187 -3.8743019104e-07 +321 187 13333333.33771 +322 187 -24555795.63051 +323 187 13177083.33766 +188 188 905507012.9075 +189 188 -1.668930053711e-06 +190 188 4.470348358154e-07 +191 188 123977832.6588 +204 188 5.811452865601e-07 +205 188 3.129243850708e-07 +206 188 -9005963.440556 +207 188 1.192092895508e-07 +208 188 -4.768371582031e-07 +209 188 66375066.93519 +210 188 4.470348358154e-08 +211 188 -4.470348358154e-08 +212 188 -9005963.440553 +276 188 16471527.78319 +277 188 -13177083.33766 +278 188 -28297094.18124 +279 188 65886111.10029 +280 188 3.8743019104e-07 +281 188 -87588646.48668 +282 188 16471527.78319 +283 188 13177083.33766 +284 188 -28297094.18124 +294 188 -9.983777999878e-07 +295 188 -52708333.32467 +296 188 -73187955.04869 +297 188 8.642673492432e-07 +298 188 1.788139343262e-07 +299 188 -190352899.3709 +300 188 1.475214958191e-06 +301 188 52708333.32467 +302 188 -73187955.0487 +315 188 -16471527.78319 +316 188 -13177083.33766 +317 188 -28297094.18124 +318 188 -65886111.10029 +319 188 -2.831220626831e-07 +320 188 -87588646.48668 +321 188 -16471527.78319 +322 188 13177083.33766 +323 188 -28297094.18124 +189 189 886076107.088 +190 189 29506578.58962 +191 189 -4.172325134277e-06 +192 189 -15650105.72171 +193 189 -67995305.55008 +194 189 -1.788139343262e-06 +207 189 -75155545.77471 +208 189 -53333333.32457 +209 189 5.066394805908e-07 +210 189 -169993346.4286 +211 189 13585574.37073 +212 189 1.579523086548e-06 +213 189 -49437968.75893 +214 189 49988791.22677 +215 189 2.637505531311e-06 +279 189 -28555987.69793 +280 189 13333333.33771 +281 189 16471527.78319 +282 189 -87310926.38278 +283 189 -6271409.66235 +284 189 57161110.99975 +297 189 -7556159.747413 +298 189 -3.278255462646e-07 +299 189 -1.206994056702e-06 +300 189 87947441.63499 +301 189 7376644.65104 +302 189 0.02039501070976 +303 189 -32923131.70809 +304 189 -16998826.39589 +305 189 16470833.12799 +318 189 -28555987.69793 +319 189 -13333333.33771 +320 189 -16471527.78319 +321 189 -80272721.40676 +322 189 3396393.594356 +323 189 -61522916.65699 +324 189 -22126192.23639 +325 189 12497197.81285 +326 189 -12109027.78175 +190 190 821417136.7999 +191 190 5.125999450684e-06 +192 190 -67995305.33675 +193 190 -205861449.307 +194 190 -3.56137752533e-06 +207 190 -53333333.32457 +208 190 -59154777.5129 +209 190 2.086162567139e-07 +210 190 13585574.37073 +211 190 48420638.98572 +212 190 8.940696716309e-07 +213 190 49988791.22677 +214 190 -80270449.84323 +215 190 -2.548098564148e-06 +279 190 13333333.33771 +280 190 -24555795.63051 +281 190 -13177083.33766 +282 190 -6271409.715683 +283 190 -27822507.01778 +284 190 6197916.651945 +297 190 -2.98023223877e-07 +298 190 -58222760.85313 +299 190 -52708333.32467 +300 190 7376644.65104 +301 190 71782699.055 +302 190 0.01631674170494 +303 190 -16998826.34256 +304 190 -80475967.62785 +305 190 52708333.09468 +318 190 -13333333.33771 +319 190 -24555795.63051 +320 190 -13177083.33766 +321 190 3396393.594355 +322 190 -25669225.02627 +323 190 3489583.332416 +324 190 12497197.81285 +325 190 -29834312.51126 +326 190 16666666.67214 +191 191 843458196.4419 +192 191 1.192092895508e-07 +193 191 -3.039836883545e-06 +194 191 21637954.44543 +207 191 5.811452865601e-07 +208 191 3.129243850708e-07 +209 191 -9005963.440556 +210 191 6.85453414917e-07 +211 191 1.072883605957e-06 +212 191 73680450.86193 +213 191 1.996755599976e-06 +214 191 -2.592802047729e-06 +215 191 -7752033.245933 +279 191 16471527.78319 +280 191 -13177083.33766 +281 191 -28297094.18124 +282 191 57161110.99975 +283 191 6197916.627155 +284 191 -74255038.56586 +297 191 -9.983777999878e-07 +298 191 -52708333.32467 +299 191 -73187955.04869 +300 191 -0.02039638161659 +301 191 -0.01631587743759 +302 191 -145326344.7753 +303 191 16470833.02261 +304 191 52708333.03516 +305 191 -71952125.45461 +318 191 -16471527.78319 +319 191 -13177083.33766 +320 191 -28297094.18124 +321 191 -61522916.65613 +322 191 3489583.333104 +323 191 -82311580.01855 +324 191 -12109027.78175 +325 191 16666666.67214 +326 191 -27982541.75396 +192 192 531775095.0468 +193 192 8503382.432196 +210 192 -80370018.26376 +211 192 -52907761.3966 +212 192 -1.847743988037e-06 +213 192 -113455777.5588 +214 192 18108359.28725 +215 192 1.311302185059e-06 +216 192 68483060.18779 +217 192 -18744593.63382 +218 192 5.960464477539e-07 +219 192 -42329538.80213 +220 192 49035919.29823 +221 192 1.922249794006e-06 +282 192 -11791159.78616 +283 192 15999999.84526 +284 192 14530833.02455 +300 192 -32923131.7081 +301 192 -16998826.34256 +302 192 -16470833.02261 +303 192 14669982.03611 +304 192 2125845.609096 +305 192 12968611.10898 +321 192 -29859204.61641 +322 192 -13226940.35567 +323 192 -16470833.33874 +324 192 -76387958.09069 +325 192 4527089.824043 +326 192 -64843055.54491 +327 192 -11712307.86994 +328 192 -4686148.410764 +329 192 8424305.555742 +330 192 -24181082.63358 +331 192 12258979.8306 +332 192 -15950694.44968 +193 193 626925818.4292 +194 193 3.933906555176e-06 +210 193 -52907761.3966 +211 193 -54873071.8125 +212 193 -8.642673492432e-07 +213 193 18108359.28725 +214 193 97871879.78123 +215 193 3.337860107422e-06 +216 193 2588739.696008 +217 193 -35173186.25688 +218 193 -3.695487976074e-06 +219 193 49035919.29823 +220 193 -49698043.59219 +221 193 -1.505017280579e-06 +282 193 10666666.5635 +283 193 -19475967.87838 +284 193 -14729166.53156 +300 193 -16998826.39589 +301 193 -80475967.62786 +302 193 -52708333.03516 +303 193 2125845.609096 +304 193 38457662.89345 +305 193 3874999.888226 +321 193 -13226940.35567 +322 193 -23484968.00046 +323 193 -13177083.33766 +324 193 4527089.824043 +325 193 -23556043.72965 +326 193 3489583.332417 +327 193 647184.9243208 +328 193 -37626369.49388 +329 193 33333333.32786 +330 193 12258979.8306 +331 193 -26023208.832 +332 193 16666666.67214 +194 194 650521074.3426 +210 194 -1.788139343262e-06 +211 194 -7.748603820801e-07 +212 194 -9261489.102506 +213 194 1.117587089539e-06 +214 194 3.337860107422e-06 +215 194 131575339.2945 +216 194 1.54972076416e-06 +217 194 -3.75509262085e-06 +218 194 90632596.10001 +219 194 2.279877662659e-06 +220 194 -1.594424247742e-06 +221 194 13362532.26789 +282 194 9687222.01637 +283 194 -18604166.53816 +284 194 -23758284.67089 +300 194 -16470833.12799 +301 194 -52708333.09468 +302 194 -71952125.45462 +303 194 -12968611.10898 +304 194 -3874999.888222 +305 194 -152766509.4438 +321 194 -16470833.33874 +322 194 -13177083.33766 +323 194 -28359905.71829 +324 194 -64843055.54491 +325 194 3489583.333105 +326 194 -95170201.65885 +327 194 299305.5539342 +328 194 33333333.32786 +329 194 -54230045.43137 +330 194 -15950694.44968 +331 194 16666666.67214 +332 194 -32922561.4056 +195 195 456895802.7167 +196 195 3.933906555176e-06 +197 195 -1.668930053711e-06 +198 195 63024490.39562 +199 195 10666666.66491 +200 195 -1.013278961182e-06 +285 195 -88624220.55292 +286 195 1.043081283569e-07 +287 195 65886111.10029 +288 195 -28555987.69793 +289 195 -13333333.33771 +290 195 16471527.78319 +306 195 36087140.85245 +307 195 8.344650268555e-07 +308 195 -13177222.22006 +309 195 -3778079.873706 +310 195 2666666.667542 +311 195 -3294305.556637 +196 196 392892729.701 +197 196 -7.152557373047e-07 +198 196 -10666666.66491 +199 196 -38308711.7659 +200 196 3.8743019104e-07 +285 196 4.470348358154e-08 +286 196 -29957235.32024 +287 196 2.831220626831e-07 +288 196 -13333333.33771 +289 196 -24555795.63051 +290 196 13177083.33766 +306 196 8.940696716309e-07 +307 196 20086372.59065 +308 196 -2.98023223877e-08 +309 196 -2666666.667543 +310 196 -29111380.42657 +311 196 26354166.66234 +197 197 452753506.4538 +198 197 -8.940696716309e-07 +199 197 1.490116119385e-07 +200 197 61988916.32938 +285 197 65886111.10029 +286 197 3.8743019104e-07 +287 197 -87588646.48668 +288 197 16471527.78319 +289 197 13177083.33766 +290 197 -28297094.18124 +306 197 13177222.22006 +307 197 1.490116119385e-07 +308 197 -95176449.68545 +309 197 3294305.556638 +310 197 26354166.66234 +311 197 -36593977.52435 +198 198 456895802.7167 +199 198 3.933906555176e-06 +200 198 -1.668930053711e-06 +201 198 63024490.39562 +202 198 10666666.66491 +203 198 -1.013278961182e-06 +285 198 -28555987.69793 +286 198 13333333.33771 +287 198 16471527.78319 +288 198 -88624220.55292 +289 198 1.043081283569e-07 +290 198 65886111.10029 +291 198 -28555987.69793 +292 198 -13333333.33771 +293 198 16471527.78319 +306 198 -3778079.873706 +307 198 -2666666.667542 +308 198 -3294305.556638 +309 198 36087140.85245 +310 198 8.344650268555e-07 +311 198 -13177222.22006 +312 198 -3778079.873706 +313 198 2666666.667542 +314 198 -3294305.556637 +199 199 392892729.701 +200 199 -7.152557373047e-07 +201 199 -10666666.66491 +202 199 -38308711.7659 +203 199 3.8743019104e-07 +285 199 13333333.33771 +286 199 -24555795.63051 +287 199 -13177083.33766 +288 199 4.470348358154e-08 +289 199 -29957235.32024 +290 199 2.831220626831e-07 +291 199 -13333333.33771 +292 199 -24555795.63051 +293 199 13177083.33766 +306 199 2666666.667542 +307 199 -29111380.42657 +308 199 -26354166.66234 +309 199 8.940696716309e-07 +310 199 20086372.59065 +311 199 -2.98023223877e-08 +312 199 -2666666.667543 +313 199 -29111380.42657 +314 199 26354166.66234 +200 200 452753506.4538 +201 200 -8.940696716309e-07 +202 200 1.490116119385e-07 +203 200 61988916.32938 +285 200 16471527.78319 +286 200 -13177083.33766 +287 200 -28297094.18124 +288 200 65886111.10029 +289 200 3.8743019104e-07 +290 200 -87588646.48668 +291 200 16471527.78319 +292 200 13177083.33766 +293 200 -28297094.18124 +306 200 3294305.556637 +307 200 -26354166.66234 +308 200 -36593977.52435 +309 200 13177222.22006 +310 200 1.490116119385e-07 +311 200 -95176449.68545 +312 200 3294305.556638 +313 200 26354166.66234 +314 200 -36593977.52435 +201 201 456895802.7167 +202 201 3.933906555176e-06 +203 201 -1.668930053711e-06 +204 201 63024490.39562 +205 201 10666666.66491 +206 201 -1.013278961182e-06 +288 201 -28555987.69793 +289 201 13333333.33771 +290 201 16471527.78319 +291 201 -88624220.55292 +292 201 1.043081283569e-07 +293 201 65886111.10029 +294 201 -28555987.69793 +295 201 -13333333.33771 +296 201 16471527.78319 +309 201 -3778079.873706 +310 201 -2666666.667542 +311 201 -3294305.556638 +312 201 36087140.85245 +313 201 8.344650268555e-07 +314 201 -13177222.22006 +315 201 -3778079.873706 +316 201 2666666.667542 +317 201 -3294305.556637 +202 202 392892729.701 +203 202 -7.152557373047e-07 +204 202 -10666666.66491 +205 202 -38308711.7659 +206 202 3.8743019104e-07 +288 202 13333333.33771 +289 202 -24555795.63051 +290 202 -13177083.33766 +291 202 4.470348358154e-08 +292 202 -29957235.32024 +293 202 2.831220626831e-07 +294 202 -13333333.33771 +295 202 -24555795.63051 +296 202 13177083.33766 +309 202 2666666.667542 +310 202 -29111380.42657 +311 202 -26354166.66234 +312 202 8.940696716309e-07 +313 202 20086372.59065 +314 202 -2.98023223877e-08 +315 202 -2666666.667543 +316 202 -29111380.42657 +317 202 26354166.66234 +203 203 452753506.4538 +204 203 -8.940696716309e-07 +205 203 1.490116119385e-07 +206 203 61988916.32938 +288 203 16471527.78319 +289 203 -13177083.33766 +290 203 -28297094.18124 +291 203 65886111.10029 +292 203 3.8743019104e-07 +293 203 -87588646.48668 +294 203 16471527.78319 +295 203 13177083.33766 +296 203 -28297094.18124 +309 203 3294305.556637 +310 203 -26354166.66234 +311 203 -36593977.52435 +312 203 13177222.22006 +313 203 1.490116119385e-07 +314 203 -95176449.68545 +315 203 3294305.556638 +316 203 26354166.66234 +317 203 -36593977.52435 +204 204 456895802.7167 +205 204 3.933906555176e-06 +206 204 -1.668930053711e-06 +207 204 63024490.39562 +208 204 10666666.66491 +209 204 -1.013278961182e-06 +291 204 -28555987.69793 +292 204 13333333.33771 +293 204 16471527.78319 +294 204 -88624220.55292 +295 204 1.043081283569e-07 +296 204 65886111.10029 +297 204 -28555987.69793 +298 204 -13333333.33771 +299 204 16471527.78319 +312 204 -3778079.873706 +313 204 -2666666.667542 +314 204 -3294305.556638 +315 204 36087140.85245 +316 204 8.344650268555e-07 +317 204 -13177222.22006 +318 204 -3778079.873706 +319 204 2666666.667542 +320 204 -3294305.556637 +205 205 392892729.701 +206 205 -7.152557373047e-07 +207 205 -10666666.66491 +208 205 -38308711.7659 +209 205 3.8743019104e-07 +291 205 13333333.33771 +292 205 -24555795.63051 +293 205 -13177083.33766 +294 205 4.470348358154e-08 +295 205 -29957235.32024 +296 205 2.831220626831e-07 +297 205 -13333333.33771 +298 205 -24555795.63051 +299 205 13177083.33766 +312 205 2666666.667542 +313 205 -29111380.42657 +314 205 -26354166.66234 +315 205 8.940696716309e-07 +316 205 20086372.59065 +317 205 -2.98023223877e-08 +318 205 -2666666.667543 +319 205 -29111380.42657 +320 205 26354166.66234 +206 206 452753506.4538 +207 206 -8.940696716309e-07 +208 206 1.490116119385e-07 +209 206 61988916.32938 +291 206 16471527.78319 +292 206 -13177083.33766 +293 206 -28297094.18124 +294 206 65886111.10029 +295 206 3.8743019104e-07 +296 206 -87588646.48668 +297 206 16471527.78319 +298 206 13177083.33766 +299 206 -28297094.18124 +312 206 3294305.556637 +313 206 -26354166.66234 +314 206 -36593977.52435 +315 206 13177222.22006 +316 206 1.490116119385e-07 +317 206 -95176449.68545 +318 206 3294305.556638 +319 206 26354166.66234 +320 206 -36593977.52435 +207 207 456895802.7167 +208 207 3.933906555176e-06 +209 207 -1.668930053711e-06 +210 207 63024490.39562 +211 207 10666666.66491 +212 207 -1.013278961182e-06 +294 207 -28555987.69793 +295 207 13333333.33771 +296 207 16471527.78319 +297 207 -88624220.55292 +298 207 1.043081283569e-07 +299 207 65886111.10029 +300 207 -28555987.69793 +301 207 -13333333.33771 +302 207 16471527.78319 +315 207 -3778079.873706 +316 207 -2666666.667542 +317 207 -3294305.556638 +318 207 36087140.85245 +319 207 8.344650268555e-07 +320 207 -13177222.22006 +321 207 -3778079.873706 +322 207 2666666.667542 +323 207 -3294305.556637 +208 208 392892729.701 +209 208 -7.152557373047e-07 +210 208 -10666666.66491 +211 208 -38308711.7659 +212 208 3.8743019104e-07 +294 208 13333333.33771 +295 208 -24555795.63051 +296 208 -13177083.33766 +297 208 4.470348358154e-08 +298 208 -29957235.32024 +299 208 2.831220626831e-07 +300 208 -13333333.33771 +301 208 -24555795.63051 +302 208 13177083.33766 +315 208 2666666.667542 +316 208 -29111380.42657 +317 208 -26354166.66234 +318 208 8.940696716309e-07 +319 208 20086372.59065 +320 208 -2.98023223877e-08 +321 208 -2666666.667543 +322 208 -29111380.42657 +323 208 26354166.66234 +209 209 452753506.4538 +210 209 -8.940696716309e-07 +211 209 1.490116119385e-07 +212 209 61988916.32938 +294 209 16471527.78319 +295 209 -13177083.33766 +296 209 -28297094.18124 +297 209 65886111.10029 +298 209 3.8743019104e-07 +299 209 -87588646.48668 +300 209 16471527.78319 +301 209 13177083.33766 +302 209 -28297094.18124 +315 209 3294305.556637 +316 209 -26354166.66234 +317 209 -36593977.52435 +318 209 13177222.22006 +319 209 1.490116119385e-07 +320 209 -95176449.68545 +321 209 3294305.556638 +322 209 26354166.66234 +323 209 -36593977.52435 +210 210 451672659.2548 +211 210 425457.3069872 +213 210 45227333.73336 +214 210 -3769936.940774 +215 210 5.960464477539e-07 +297 210 -28555987.69793 +298 210 13333333.33771 +299 210 16471527.78319 +300 210 -80272721.40676 +301 210 3396393.594356 +302 210 61522916.65613 +303 210 -29859204.61641 +304 210 -13226940.35567 +305 210 16470833.33874 +318 210 -3778079.873706 +319 210 -2666666.667542 +320 210 -3294305.556638 +321 210 34782980.96289 +322 210 106364.3267991 +323 210 -13176944.44228 +324 210 -9519773.826407 +325 210 -942484.2356579 +326 210 1067638.88752 +211 211 397175038.8898 +212 211 1.072883605957e-06 +213 211 -25103270.2706 +214 211 -58853543.86754 +215 211 -1.341104507446e-06 +297 211 13333333.33771 +298 211 -24555795.63051 +299 211 -13177083.33766 +300 211 3396393.594355 +301 211 -25669225.02627 +302 211 -3489583.333104 +303 211 -13226940.35567 +304 211 -23484968.00045 +305 211 13177083.33766 +318 211 2666666.667542 +319 211 -29111380.42657 +320 211 -26354166.66234 +321 211 106364.3267991 +322 211 21158575.86493 +323 211 2.682209014893e-07 +324 211 -6275817.570742 +325 211 -35539993.23945 +326 211 29843749.99544 +212 212 452492316.5668 +214 212 -1.490116119385e-06 +215 212 55187296.56271 +297 212 16471527.78319 +298 212 -13177083.33766 +299 212 -28297094.18124 +300 212 61522916.65699 +301 212 -3489583.332416 +302 212 -82311580.01855 +303 212 16470833.33874 +304 212 13177083.33766 +305 212 -28359905.71829 +318 212 3294305.556637 +319 212 -26354166.66234 +320 212 -36593977.52435 +321 212 13176944.44228 +322 212 3.8743019104e-07 +323 212 -95237411.21973 +324 212 7655972.222158 +325 212 29843749.99475 +326 212 -41740795.2267 +213 213 444644489.1745 +214 213 13081929.57058 +215 213 9.536743164063e-07 +216 213 -86994427.68368 +217 213 -57630747.35091 +218 213 -2.384185791016e-06 +219 213 44204118.01812 +220 213 1554937.536914 +221 213 -1.192092895508e-06 +300 213 -22126192.23639 +301 213 12497197.81285 +302 213 12109027.78176 +303 213 -76387958.09069 +304 213 4527089.824043 +305 213 64843055.54491 +321 213 -9519773.826409 +322 213 -6275817.570743 +323 213 -7655972.222158 +324 213 15798034.7999 +325 213 3270482.394257 +326 213 -12968611.10898 +327 213 -35347304.85947 +328 213 -14407686.84483 +329 213 20312500.00667 +330 213 -14510689.24923 +331 213 388734.3844201 +332 213 1171666.664472 +214 214 449754245.7917 +215 214 4.64916229248e-06 +216 214 -57630747.35091 +217 214 -66447376.92277 +218 214 -1.296401023865e-06 +219 214 -19778395.79291 +220 214 -57866988.0148 +221 214 -2.086162567139e-06 +300 214 12497197.81285 +301 214 -29834312.51127 +302 214 -16666666.67214 +303 214 4527089.824043 +304 214 -23556043.72965 +305 214 -3489583.333103 +321 214 -942484.2356579 +322 214 -35539993.23945 +323 214 -29843749.99475 +324 214 3270482.394257 +325 214 17075473.95481 +326 214 9.536743164063e-07 +327 214 -14407686.84483 +328 214 -30210542.16671 +329 214 16666666.67214 +330 214 -4944598.950664 +331 214 -40028465.77003 +332 214 33333333.32786 +215 215 513640710.6392 +216 215 -3.159046173096e-06 +217 215 -1.370906829834e-06 +218 215 -3386801.062691 +219 215 -1.907348632813e-06 +220 215 -2.235174179077e-06 +221 215 68569532.94435 +300 215 12109027.78176 +301 215 -16666666.67214 +302 215 -27982541.75396 +303 215 64843055.54491 +304 215 -3489583.332416 +305 215 -95170201.65886 +321 215 -1067638.887521 +322 215 -29843749.99544 +323 215 -41740795.22671 +324 215 12968611.10898 +325 215 1.013278961182e-06 +326 215 -125891389.0729 +327 215 20312500.00667 +328 215 16666666.67214 +329 215 -37109894.74031 +330 215 7551944.445205 +331 215 33333333.32786 +332 215 -51022200.11333 +216 216 254849231.4225 +217 216 61411260.29348 +218 216 3.814697265625e-06 +219 216 -66610780.59762 +220 216 -6369252.63857 +221 216 -1.132488250732e-06 +303 216 -11712307.86995 +304 216 647184.9243208 +305 216 -299305.5539346 +324 216 -35347304.85947 +325 216 -14407686.84483 +326 216 -20312500.00667 +327 216 6046162.064774 +328 216 15352815.08093 +329 216 8124999.998666 +330 216 -43850090.99987 +331 216 -1592313.160427 +332 216 -36263194.43806 +217 217 228505477.8886 +218 217 4.172325134277e-06 +219 217 14964080.69126 +220 217 42842168.62011 +221 217 1.728534698486e-06 +303 217 -4686148.410764 +304 217 -37626369.49388 +305 217 -33333333.32786 +324 217 -14407686.84483 +325 217 -30210542.16671 +326 217 -16666666.67214 +327 217 15352815.08093 +328 217 -539776.3219635 +329 217 6666666.665572 +330 217 3741020.174657 +331 217 -16486853.68196 +332 217 3333333.334428 +218 218 294920181.6058 +220 218 1.788139343262e-06 +221 218 70439578.90092 +303 218 -8424305.555743 +304 218 -33333333.32786 +305 218 -54230045.43139 +324 218 -20312500.00667 +325 218 -16666666.67214 +326 218 -37109894.74031 +327 218 -8124999.998665 +328 218 -6666666.665571 +329 218 -80046343.42155 +330 218 -36263194.43892 +331 218 -3333333.334428 +332 218 -54916494.1788 +219 219 221377868.0526 +220 219 -44221604.19657 +221 219 -1.311302185059e-06 +303 219 -24181082.63358 +304 219 12258979.8306 +305 219 15950694.44968 +324 219 -14510689.24923 +325 219 -4944598.950664 +326 219 -7551944.445206 +327 219 -43850090.99987 +328 219 3741020.174657 +329 219 36263194.43892 +330 219 4221029.5472 +331 219 -11055401.05459 +332 219 -6380277.77673 +220 220 221364529.6578 +221 220 2.861022949219e-06 +303 220 12258979.8306 +304 220 -26023208.832 +305 220 -16666666.67214 +324 220 388734.38442 +325 220 -40028465.77003 +326 220 -33333333.32786 +327 220 -1592313.160427 +328 220 -16486853.68196 +329 220 3333333.334428 +330 220 -11055401.05459 +331 220 4217694.948508 +332 220 6666666.665572 +221 221 265339467.0094 +303 221 15950694.44968 +304 221 -16666666.67214 +305 221 -32922561.4056 +324 221 -1171666.664473 +325 221 -33333333.32786 +326 221 -51022200.11334 +327 221 36263194.43806 +328 221 -3333333.334428 +329 221 -54916494.1788 +330 221 6380277.77673 +331 221 -6666666.665571 +332 221 -69994299.86354 +222 222 571119749.839 +223 222 53333333.32457 +224 222 -6.198883056641e-06 +225 222 -292913008.3249 +226 222 -53333332.8979 +227 222 6.556510925293e-06 +228 222 19534202.10867 +229 222 42666666.23299 +230 222 -1.490116119385e-06 +333 222 45108925.89256 +334 222 13333333.33771 +335 222 13177222.19231 +336 222 -107413106.5112 +337 222 -13333333.23104 +338 222 -65886110.96157 +339 222 -9767101.054335 +340 222 10666666.5635 +341 222 -13177221.94221 +223 223 491115909.0416 +224 223 -3.094097220493e-06 +225 223 -53333332.68457 +226 223 -42244300.58137 +227 223 2.145767211914e-06 +228 223 63999999.34949 +229 223 19534202.10866 +230 223 -2.384185791016e-06 +333 223 13333333.33771 +334 223 25107965.68335 +335 223 10541666.55379 +336 223 -13333333.17771 +337 223 -44745929.54446 +338 223 -13177083.26329 +339 223 15999999.84525 +340 223 -9767101.054335 +341 223 15812499.93082 +224 224 565941879.2302 +225 224 6.943941116333e-06 +226 224 1.609325408936e-06 +227 224 5277897.861165 +228 224 -2.145767211914e-06 +229 224 -1.54972076416e-06 +230 224 52091205.62311 +333 224 -13177222.19232 +334 224 -10541666.5538 +335 224 -118970561.1562 +336 224 -65886110.96157 +337 224 -13177083.28808 +338 224 -89840137.25117 +339 224 -19765832.91331 +340 224 10541666.62055 +341 224 -26045602.81156 +225 225 988947148.5376 +226 225 53333332.25791 +227 225 -9.298324584961e-06 +228 225 31359232.67644 +229 225 -53333332.8979 +230 225 1.251697540283e-06 +231 225 -198223262.271 +232 225 2.98023223877e-07 +233 225 5.960464477539e-08 +234 225 -75155545.7747 +235 225 53333333.32457 +236 225 -1.490116119385e-08 +333 225 -107413106.5112 +334 225 -13333333.17771 +335 225 65886110.96157 +336 225 100730268.7541 +337 225 13333333.07105 +338 225 0.02774140238762 +339 225 -26345045.89131 +340 225 -13333333.23105 +341 225 16471527.49884 +342 225 -88624220.55292 +343 225 2.235174179077e-07 +344 225 -65886111.10029 +345 225 -28555987.69793 +346 225 13333333.33771 +347 225 -16471527.78319 +226 226 844940234.7245 +227 226 -7.987022399902e-06 +228 226 -53333332.68457 +229 226 -155306402.5315 +230 226 5.394220352173e-06 +231 226 3.576278686523e-07 +232 226 36444678.54407 +233 226 -4.172325134277e-07 +234 226 53333333.32457 +235 226 -59154777.5129 +236 226 2.98023223877e-08 +333 226 -13333333.23104 +334 226 -44745929.54447 +335 226 13177083.28808 +336 226 13333333.07105 +337 226 64728540.28304 +338 226 0.022192299366 +339 226 -13333333.17771 +340 226 -73011454.71628 +341 226 52708333.03581 +342 226 1.9371509552e-07 +343 226 -29957235.32024 +344 226 -3.8743019104e-07 +345 226 13333333.33771 +346 226 -24555795.63051 +347 226 13177083.33766 +227 227 914512974.9691 +228 227 1.728534698486e-06 +229 227 4.559755325317e-06 +230 227 62880662.12465 +231 227 1.192092895508e-07 +232 227 -4.768371582031e-07 +233 227 66375066.93519 +234 227 4.470348358154e-08 +235 227 -4.470348358154e-08 +236 227 -9005963.440553 +333 227 65886110.96157 +334 227 13177083.26329 +335 227 -89840137.25118 +336 227 -0.0277450978756 +337 227 -0.02219566702843 +338 227 -162055805.4842 +339 227 16471527.35667 +340 227 52708332.94687 +341 227 -75439445.29918 +342 227 -65886111.10029 +343 227 -2.831220626831e-07 +344 227 -87588646.48668 +345 227 -16471527.78319 +346 227 13177083.33766 +347 227 -28297094.18124 +228 228 571119749.839 +229 228 53333333.32457 +230 228 -6.198883056641e-06 +231 228 -75155545.77471 +232 228 -53333333.32457 +233 228 5.066394805908e-07 +234 228 -292913008.3249 +235 228 -53333332.8979 +236 228 6.556510925293e-06 +237 228 19534202.10867 +238 228 42666666.23299 +239 228 -1.490116119385e-06 +333 228 -9767101.054335 +334 228 15999999.84525 +335 228 19765832.91331 +336 228 -26345045.8913 +337 228 -13333333.17771 +338 228 -16471527.35667 +339 228 45108925.89256 +340 228 13333333.33771 +341 228 13177222.19231 +342 228 -28555987.69793 +343 228 -13333333.33771 +344 228 -16471527.78319 +345 228 -107413106.5112 +346 228 -13333333.23104 +347 228 -65886110.96157 +348 228 -9767101.054335 +349 228 10666666.5635 +350 228 -13177221.94221 +229 229 491115909.0416 +230 229 -2.974887930942e-06 +231 229 -53333333.32457 +232 229 -59154777.5129 +233 229 2.086162567139e-07 +234 229 -53333332.68457 +235 229 -42244300.58137 +236 229 2.145767211914e-06 +237 229 63999999.34949 +238 229 19534202.10866 +239 229 -2.384185791016e-06 +333 229 10666666.5635 +334 229 -9767101.054336 +335 229 -10541666.62055 +336 229 -13333333.23105 +337 229 -73011454.71627 +338 229 -52708332.94687 +339 229 13333333.33771 +340 229 25107965.68335 +341 229 10541666.55379 +342 229 -13333333.33771 +343 229 -24555795.63051 +344 229 -13177083.33766 +345 229 -13333333.17771 +346 229 -44745929.54446 +347 229 -13177083.26329 +348 229 15999999.84525 +349 229 -9767101.054335 +350 229 15812499.93082 +230 230 565941879.2302 +231 230 5.811452865601e-07 +232 230 3.129243850708e-07 +233 230 -9005963.440556 +234 230 6.943941116333e-06 +235 230 1.609325408936e-06 +236 230 5277897.861165 +237 230 -2.145767211914e-06 +238 230 -1.54972076416e-06 +239 230 52091205.62311 +333 230 13177221.94221 +334 230 -15812499.93082 +335 230 -26045602.81156 +336 230 -16471527.49884 +337 230 -52708333.03581 +338 230 -75439445.29917 +339 230 -13177222.19232 +340 230 -10541666.5538 +341 230 -118970561.1562 +342 230 -16471527.78319 +343 230 -13177083.33766 +344 230 -28297094.18124 +345 230 -65886110.96157 +346 230 -13177083.28808 +347 230 -89840137.25117 +348 230 -19765832.91331 +349 230 10541666.62055 +350 230 -26045602.81156 +231 231 913791605.4334 +232 231 7.748603820801e-06 +233 231 -2.622604370117e-06 +234 231 126048980.7912 +235 231 -2.175569534302e-06 +236 231 -1.490116119385e-06 +240 231 -198223262.271 +241 231 2.98023223877e-07 +242 231 5.960464477539e-08 +243 231 -75155545.7747 +244 231 53333333.32457 +245 231 -1.490116119385e-08 +336 231 -88624220.55292 +337 231 1.043081283569e-07 +338 231 65886111.10029 +339 231 -28555987.69793 +340 231 -13333333.33771 +341 231 16471527.78319 +342 231 72174281.7049 +343 231 1.728534698486e-06 +344 231 1.221895217896e-06 +345 231 -7556159.747413 +346 231 -7.450580596924e-07 +347 231 1.341104507446e-06 +351 231 -88624220.55292 +352 231 2.235174179077e-07 +353 231 -65886111.10029 +354 231 -28555987.69793 +355 231 13333333.33771 +356 231 -16471527.78319 +232 232 785785459.402 +233 232 -1.788139343262e-06 +234 232 -2.086162567139e-06 +235 232 -76617423.53181 +236 232 5.066394805908e-07 +240 232 3.576278686523e-07 +241 232 36444678.54407 +242 232 -4.172325134277e-07 +243 232 53333333.32457 +244 232 -59154777.5129 +245 232 2.98023223877e-08 +336 232 4.470348358154e-08 +337 232 -29957235.32024 +338 232 2.831220626831e-07 +339 232 -13333333.33771 +340 232 -24555795.63051 +341 232 13177083.33766 +342 232 1.728534698486e-06 +343 232 40172745.1813 +344 232 -5.960464477539e-08 +345 232 -7.003545761108e-07 +346 232 -58222760.85313 +347 232 52708333.32467 +351 232 1.9371509552e-07 +352 232 -29957235.32024 +353 232 -3.8743019104e-07 +354 232 13333333.33771 +355 232 -24555795.63051 +356 232 13177083.33766 +233 233 905507012.9075 +234 233 -1.668930053711e-06 +235 233 4.470348358154e-07 +236 233 123977832.6588 +240 233 1.192092895508e-07 +241 233 -4.768371582031e-07 +242 233 66375066.93519 +243 233 4.470348358154e-08 +244 233 -4.470348358154e-08 +245 233 -9005963.440553 +336 233 65886111.10029 +337 233 3.8743019104e-07 +338 233 -87588646.48668 +339 233 16471527.78319 +340 233 13177083.33766 +341 233 -28297094.18124 +342 233 8.642673492432e-07 +343 233 1.788139343262e-07 +344 233 -190352899.3709 +345 233 1.475214958191e-06 +346 233 52708333.32467 +347 233 -73187955.0487 +351 233 -65886111.10029 +352 233 -2.831220626831e-07 +353 233 -87588646.48668 +354 233 -16471527.78319 +355 233 13177083.33766 +356 233 -28297094.18124 +234 234 988947148.5376 +235 234 53333332.25791 +236 234 -9.298324584961e-06 +237 234 31359232.67644 +238 234 -53333332.8979 +239 234 1.251697540283e-06 +240 234 -75155545.77471 +241 234 -53333333.32457 +242 234 5.066394805908e-07 +243 234 -198223262.271 +244 234 2.98023223877e-07 +245 234 5.960464477539e-08 +246 234 -75155545.7747 +247 234 53333333.32457 +248 234 -1.490116119385e-08 +336 234 -28555987.69793 +337 234 13333333.33771 +338 234 16471527.78319 +339 234 -107413106.5112 +340 234 -13333333.17771 +341 234 65886110.96157 +342 234 -7556159.747413 +343 234 -3.278255462646e-07 +344 234 -1.206994056702e-06 +345 234 100730268.7541 +346 234 13333333.07105 +347 234 0.02774140238762 +348 234 -26345045.89131 +349 234 -13333333.23105 +350 234 16471527.49884 +351 234 -28555987.69793 +352 234 -13333333.33771 +353 234 -16471527.78319 +354 234 -88624220.55292 +355 234 2.235174179077e-07 +356 234 -65886111.10029 +357 234 -28555987.69793 +358 234 13333333.33771 +359 234 -16471527.78319 +235 235 844940234.7245 +236 235 -7.987022399902e-06 +237 235 -53333332.68457 +238 235 -155306402.5315 +239 235 5.394220352173e-06 +240 235 -53333333.32457 +241 235 -59154777.5129 +242 235 2.086162567139e-07 +243 235 3.576278686523e-07 +244 235 36444678.54407 +245 235 -4.172325134277e-07 +246 235 53333333.32457 +247 235 -59154777.5129 +248 235 2.98023223877e-08 +336 235 13333333.33771 +337 235 -24555795.63051 +338 235 -13177083.33766 +339 235 -13333333.23104 +340 235 -44745929.54447 +341 235 13177083.28808 +342 235 -2.98023223877e-07 +343 235 -58222760.85313 +344 235 -52708333.32467 +345 235 13333333.07105 +346 235 64728540.28304 +347 235 0.022192299366 +348 235 -13333333.17771 +349 235 -73011454.71628 +350 235 52708333.03581 +351 235 -13333333.33771 +352 235 -24555795.63051 +353 235 -13177083.33766 +354 235 1.9371509552e-07 +355 235 -29957235.32024 +356 235 -3.8743019104e-07 +357 235 13333333.33771 +358 235 -24555795.63051 +359 235 13177083.33766 +236 236 914512974.9691 +237 236 1.728534698486e-06 +238 236 4.559755325317e-06 +239 236 62880662.12465 +240 236 5.811452865601e-07 +241 236 3.129243850708e-07 +242 236 -9005963.440556 +243 236 1.192092895508e-07 +244 236 -4.768371582031e-07 +245 236 66375066.93519 +246 236 4.470348358154e-08 +247 236 -4.470348358154e-08 +248 236 -9005963.440553 +336 236 16471527.78319 +337 236 -13177083.33766 +338 236 -28297094.18124 +339 236 65886110.96157 +340 236 13177083.26329 +341 236 -89840137.25118 +342 236 -9.983777999878e-07 +343 236 -52708333.32467 +344 236 -73187955.04869 +345 236 -0.0277450978756 +346 236 -0.02219566702843 +347 236 -162055805.4842 +348 236 16471527.35667 +349 236 52708332.94687 +350 236 -75439445.29918 +351 236 -16471527.78319 +352 236 -13177083.33766 +353 236 -28297094.18124 +354 236 -65886111.10029 +355 236 -2.831220626831e-07 +356 236 -87588646.48668 +357 236 -16471527.78319 +358 236 13177083.33766 +359 236 -28297094.18124 +237 237 571119749.839 +238 237 53333333.32457 +239 237 -6.198883056641e-06 +243 237 -75155545.77471 +244 237 -53333333.32457 +245 237 5.066394805908e-07 +246 237 -292913008.3249 +247 237 -53333332.8979 +248 237 6.556510925293e-06 +249 237 19534202.10867 +250 237 42666666.23299 +251 237 -1.490116119385e-06 +339 237 -9767101.054335 +340 237 15999999.84525 +341 237 19765832.91331 +345 237 -26345045.8913 +346 237 -13333333.17771 +347 237 -16471527.35667 +348 237 45108925.89256 +349 237 13333333.33771 +350 237 13177222.19231 +354 237 -28555987.69793 +355 237 -13333333.33771 +356 237 -16471527.78319 +357 237 -107413106.5112 +358 237 -13333333.23104 +359 237 -65886110.96157 +360 237 -9767101.054335 +361 237 10666666.5635 +362 237 -13177221.94221 +238 238 491115909.0416 +239 238 -2.974887930942e-06 +243 238 -53333333.32457 +244 238 -59154777.5129 +245 238 2.086162567139e-07 +246 238 -53333332.68457 +247 238 -42244300.58137 +248 238 2.145767211914e-06 +249 238 63999999.34949 +250 238 19534202.10866 +251 238 -2.384185791016e-06 +339 238 10666666.5635 +340 238 -9767101.054336 +341 238 -10541666.62055 +345 238 -13333333.23105 +346 238 -73011454.71627 +347 238 -52708332.94687 +348 238 13333333.33771 +349 238 25107965.68335 +350 238 10541666.55379 +354 238 -13333333.33771 +355 238 -24555795.63051 +356 238 -13177083.33766 +357 238 -13333333.17771 +358 238 -44745929.54446 +359 238 -13177083.26329 +360 238 15999999.84525 +361 238 -9767101.054335 +362 238 15812499.93082 +239 239 565941879.2302 +243 239 5.811452865601e-07 +244 239 3.129243850708e-07 +245 239 -9005963.440556 +246 239 6.943941116333e-06 +247 239 1.609325408936e-06 +248 239 5277897.861165 +249 239 -2.145767211914e-06 +250 239 -1.54972076416e-06 +251 239 52091205.62311 +339 239 13177221.94221 +340 239 -15812499.93082 +341 239 -26045602.81156 +345 239 -16471527.49884 +346 239 -52708333.03581 +347 239 -75439445.29917 +348 239 -13177222.19232 +349 239 -10541666.5538 +350 239 -118970561.1562 +354 239 -16471527.78319 +355 239 -13177083.33766 +356 239 -28297094.18124 +357 239 -65886110.96157 +358 239 -13177083.28808 +359 239 -89840137.25117 +360 239 -19765832.91331 +361 239 10541666.62055 +362 239 -26045602.81156 +240 240 913791605.4334 +241 240 7.748603820801e-06 +242 240 -2.622604370117e-06 +243 240 126048980.7912 +244 240 -2.175569534302e-06 +245 240 -1.490116119385e-06 +252 240 -198223262.271 +253 240 2.98023223877e-07 +254 240 5.960464477539e-08 +255 240 -75155545.7747 +256 240 53333333.32457 +257 240 -1.490116119385e-08 +342 240 -88624220.55292 +343 240 1.043081283569e-07 +344 240 65886111.10029 +345 240 -28555987.69793 +346 240 -13333333.33771 +347 240 16471527.78319 +351 240 72174281.7049 +352 240 1.728534698486e-06 +353 240 1.221895217896e-06 +354 240 -7556159.747413 +355 240 -7.450580596924e-07 +356 240 1.341104507446e-06 +363 240 -88624220.55292 +364 240 2.235174179077e-07 +365 240 -65886111.10029 +366 240 -28555987.69793 +367 240 13333333.33771 +368 240 -16471527.78319 +241 241 785785459.402 +242 241 -1.788139343262e-06 +243 241 -2.086162567139e-06 +244 241 -76617423.53181 +245 241 5.066394805908e-07 +252 241 3.576278686523e-07 +253 241 36444678.54407 +254 241 -4.172325134277e-07 +255 241 53333333.32457 +256 241 -59154777.5129 +257 241 2.98023223877e-08 +342 241 4.470348358154e-08 +343 241 -29957235.32024 +344 241 2.831220626831e-07 +345 241 -13333333.33771 +346 241 -24555795.63051 +347 241 13177083.33766 +351 241 1.728534698486e-06 +352 241 40172745.1813 +353 241 -5.960464477539e-08 +354 241 -7.003545761108e-07 +355 241 -58222760.85313 +356 241 52708333.32467 +363 241 1.9371509552e-07 +364 241 -29957235.32024 +365 241 -3.8743019104e-07 +366 241 13333333.33771 +367 241 -24555795.63051 +368 241 13177083.33766 +242 242 905507012.9075 +243 242 -1.668930053711e-06 +244 242 4.470348358154e-07 +245 242 123977832.6588 +252 242 1.192092895508e-07 +253 242 -4.768371582031e-07 +254 242 66375066.93519 +255 242 4.470348358154e-08 +256 242 -4.470348358154e-08 +257 242 -9005963.440553 +342 242 65886111.10029 +343 242 3.8743019104e-07 +344 242 -87588646.48668 +345 242 16471527.78319 +346 242 13177083.33766 +347 242 -28297094.18124 +351 242 8.642673492432e-07 +352 242 1.788139343262e-07 +353 242 -190352899.3709 +354 242 1.475214958191e-06 +355 242 52708333.32467 +356 242 -73187955.0487 +363 242 -65886111.10029 +364 242 -2.831220626831e-07 +365 242 -87588646.48668 +366 242 -16471527.78319 +367 242 13177083.33766 +368 242 -28297094.18124 +243 243 913791605.4334 +244 243 7.748603820801e-06 +245 243 -2.622604370117e-06 +246 243 126048980.7912 +247 243 -2.175569534302e-06 +248 243 -1.490116119385e-06 +252 243 -75155545.77471 +253 243 -53333333.32457 +254 243 5.066394805908e-07 +255 243 -198223262.271 +256 243 2.98023223877e-07 +257 243 5.960464477539e-08 +258 243 -75155545.7747 +259 243 53333333.32457 +260 243 -1.490116119385e-08 +342 243 -28555987.69793 +343 243 13333333.33771 +344 243 16471527.78319 +345 243 -88624220.55292 +346 243 1.043081283569e-07 +347 243 65886111.10029 +348 243 -28555987.69793 +349 243 -13333333.33771 +350 243 16471527.78319 +351 243 -7556159.747413 +352 243 -3.278255462646e-07 +353 243 -1.206994056702e-06 +354 243 72174281.7049 +355 243 1.728534698486e-06 +356 243 1.221895217896e-06 +357 243 -7556159.747413 +358 243 -7.450580596924e-07 +359 243 1.341104507446e-06 +363 243 -28555987.69793 +364 243 -13333333.33771 +365 243 -16471527.78319 +366 243 -88624220.55292 +367 243 2.235174179077e-07 +368 243 -65886111.10029 +369 243 -28555987.69793 +370 243 13333333.33771 +371 243 -16471527.78319 +244 244 785785459.402 +245 244 -1.788139343262e-06 +246 244 -2.086162567139e-06 +247 244 -76617423.53181 +248 244 5.066394805908e-07 +252 244 -53333333.32457 +253 244 -59154777.5129 +254 244 2.086162567139e-07 +255 244 3.576278686523e-07 +256 244 36444678.54407 +257 244 -4.172325134277e-07 +258 244 53333333.32457 +259 244 -59154777.5129 +260 244 2.98023223877e-08 +342 244 13333333.33771 +343 244 -24555795.63051 +344 244 -13177083.33766 +345 244 4.470348358154e-08 +346 244 -29957235.32024 +347 244 2.831220626831e-07 +348 244 -13333333.33771 +349 244 -24555795.63051 +350 244 13177083.33766 +351 244 -2.98023223877e-07 +352 244 -58222760.85313 +353 244 -52708333.32467 +354 244 1.728534698486e-06 +355 244 40172745.1813 +356 244 -5.960464477539e-08 +357 244 -7.003545761108e-07 +358 244 -58222760.85313 +359 244 52708333.32467 +363 244 -13333333.33771 +364 244 -24555795.63051 +365 244 -13177083.33766 +366 244 1.9371509552e-07 +367 244 -29957235.32024 +368 244 -3.8743019104e-07 +369 244 13333333.33771 +370 244 -24555795.63051 +371 244 13177083.33766 +245 245 905507012.9075 +246 245 -1.668930053711e-06 +247 245 4.470348358154e-07 +248 245 123977832.6588 +252 245 5.811452865601e-07 +253 245 3.129243850708e-07 +254 245 -9005963.440556 +255 245 1.192092895508e-07 +256 245 -4.768371582031e-07 +257 245 66375066.93519 +258 245 4.470348358154e-08 +259 245 -4.470348358154e-08 +260 245 -9005963.440553 +342 245 16471527.78319 +343 245 -13177083.33766 +344 245 -28297094.18124 +345 245 65886111.10029 +346 245 3.8743019104e-07 +347 245 -87588646.48668 +348 245 16471527.78319 +349 245 13177083.33766 +350 245 -28297094.18124 +351 245 -9.983777999878e-07 +352 245 -52708333.32467 +353 245 -73187955.04869 +354 245 8.642673492432e-07 +355 245 1.788139343262e-07 +356 245 -190352899.3709 +357 245 1.475214958191e-06 +358 245 52708333.32467 +359 245 -73187955.0487 +363 245 -16471527.78319 +364 245 -13177083.33766 +365 245 -28297094.18124 +366 245 -65886111.10029 +367 245 -2.831220626831e-07 +368 245 -87588646.48668 +369 245 -16471527.78319 +370 245 13177083.33766 +371 245 -28297094.18124 +246 246 988947148.5376 +247 246 53333332.25791 +248 246 -9.298324584961e-06 +249 246 31359232.67644 +250 246 -53333332.8979 +251 246 1.251697540283e-06 +255 246 -75155545.77471 +256 246 -53333333.32457 +257 246 5.066394805908e-07 +258 246 -198223262.271 +259 246 2.98023223877e-07 +260 246 5.960464477539e-08 +261 246 -75155545.7747 +262 246 53333333.32457 +263 246 -1.490116119385e-08 +345 246 -28555987.69793 +346 246 13333333.33771 +347 246 16471527.78319 +348 246 -107413106.5112 +349 246 -13333333.17771 +350 246 65886110.96157 +354 246 -7556159.747413 +355 246 -3.278255462646e-07 +356 246 -1.206994056702e-06 +357 246 100730268.7541 +358 246 13333333.07105 +359 246 0.02774140238762 +360 246 -26345045.89131 +361 246 -13333333.23105 +362 246 16471527.49884 +366 246 -28555987.69793 +367 246 -13333333.33771 +368 246 -16471527.78319 +369 246 -88624220.55292 +370 246 2.235174179077e-07 +371 246 -65886111.10029 +372 246 -28555987.69793 +373 246 13333333.33771 +374 246 -16471527.78319 +247 247 844940234.7245 +248 247 -7.987022399902e-06 +249 247 -53333332.68457 +250 247 -155306402.5315 +251 247 5.394220352173e-06 +255 247 -53333333.32457 +256 247 -59154777.5129 +257 247 2.086162567139e-07 +258 247 3.576278686523e-07 +259 247 36444678.54407 +260 247 -4.172325134277e-07 +261 247 53333333.32457 +262 247 -59154777.5129 +263 247 2.98023223877e-08 +345 247 13333333.33771 +346 247 -24555795.63051 +347 247 -13177083.33766 +348 247 -13333333.23104 +349 247 -44745929.54447 +350 247 13177083.28808 +354 247 -2.98023223877e-07 +355 247 -58222760.85313 +356 247 -52708333.32467 +357 247 13333333.07105 +358 247 64728540.28304 +359 247 0.022192299366 +360 247 -13333333.17771 +361 247 -73011454.71628 +362 247 52708333.03581 +366 247 -13333333.33771 +367 247 -24555795.63051 +368 247 -13177083.33766 +369 247 1.9371509552e-07 +370 247 -29957235.32024 +371 247 -3.8743019104e-07 +372 247 13333333.33771 +373 247 -24555795.63051 +374 247 13177083.33766 +248 248 914512974.9691 +249 248 1.728534698486e-06 +250 248 4.559755325317e-06 +251 248 62880662.12465 +255 248 5.811452865601e-07 +256 248 3.129243850708e-07 +257 248 -9005963.440556 +258 248 1.192092895508e-07 +259 248 -4.768371582031e-07 +260 248 66375066.93519 +261 248 4.470348358154e-08 +262 248 -4.470348358154e-08 +263 248 -9005963.440553 +345 248 16471527.78319 +346 248 -13177083.33766 +347 248 -28297094.18124 +348 248 65886110.96157 +349 248 13177083.26329 +350 248 -89840137.25118 +354 248 -9.983777999878e-07 +355 248 -52708333.32467 +356 248 -73187955.04869 +357 248 -0.0277450978756 +358 248 -0.02219566702843 +359 248 -162055805.4842 +360 248 16471527.35667 +361 248 52708332.94687 +362 248 -75439445.29918 +366 248 -16471527.78319 +367 248 -13177083.33766 +368 248 -28297094.18124 +369 248 -65886111.10029 +370 248 -2.831220626831e-07 +371 248 -87588646.48668 +372 248 -16471527.78319 +373 248 13177083.33766 +374 248 -28297094.18124 +249 249 571119749.839 +250 249 53333333.32457 +251 249 -6.198883056641e-06 +258 249 -75155545.77471 +259 249 -53333333.32457 +260 249 5.066394805908e-07 +261 249 -292913008.3249 +262 249 -53333332.8979 +263 249 6.556510925293e-06 +264 249 19534202.10867 +265 249 42666666.23299 +266 249 -1.490116119385e-06 +348 249 -9767101.054335 +349 249 15999999.84525 +350 249 19765832.91331 +357 249 -26345045.8913 +358 249 -13333333.17771 +359 249 -16471527.35667 +360 249 45108925.89256 +361 249 13333333.33771 +362 249 13177222.19231 +369 249 -28555987.69793 +370 249 -13333333.33771 +371 249 -16471527.78319 +372 249 -107413106.5112 +373 249 -13333333.23104 +374 249 -65886110.96157 +375 249 -9767101.054335 +376 249 10666666.5635 +377 249 -13177221.94221 +250 250 491115909.0416 +251 250 -2.974887930942e-06 +258 250 -53333333.32457 +259 250 -59154777.5129 +260 250 2.086162567139e-07 +261 250 -53333332.68457 +262 250 -42244300.58137 +263 250 2.145767211914e-06 +264 250 63999999.34949 +265 250 19534202.10866 +266 250 -2.384185791016e-06 +348 250 10666666.5635 +349 250 -9767101.054336 +350 250 -10541666.62055 +357 250 -13333333.23105 +358 250 -73011454.71627 +359 250 -52708332.94687 +360 250 13333333.33771 +361 250 25107965.68335 +362 250 10541666.55379 +369 250 -13333333.33771 +370 250 -24555795.63051 +371 250 -13177083.33766 +372 250 -13333333.17771 +373 250 -44745929.54446 +374 250 -13177083.26329 +375 250 15999999.84525 +376 250 -9767101.054335 +377 250 15812499.93082 +251 251 565941879.2302 +258 251 5.811452865601e-07 +259 251 3.129243850708e-07 +260 251 -9005963.440556 +261 251 6.943941116333e-06 +262 251 1.609325408936e-06 +263 251 5277897.861165 +264 251 -2.145767211914e-06 +265 251 -1.54972076416e-06 +266 251 52091205.62311 +348 251 13177221.94221 +349 251 -15812499.93082 +350 251 -26045602.81156 +357 251 -16471527.49884 +358 251 -52708333.03581 +359 251 -75439445.29917 +360 251 -13177222.19232 +361 251 -10541666.5538 +362 251 -118970561.1562 +369 251 -16471527.78319 +370 251 -13177083.33766 +371 251 -28297094.18124 +372 251 -65886110.96157 +373 251 -13177083.28808 +374 251 -89840137.25117 +375 251 -19765832.91331 +376 251 10541666.62055 +377 251 -26045602.81156 +252 252 913791605.4334 +253 252 7.748603820801e-06 +254 252 -2.622604370117e-06 +255 252 126048980.7912 +256 252 -2.175569534302e-06 +257 252 -1.490116119385e-06 +267 252 -198223262.271 +268 252 2.98023223877e-07 +269 252 5.960464477539e-08 +270 252 -75155545.7747 +271 252 53333333.32457 +272 252 -1.490116119385e-08 +351 252 -88624220.55292 +352 252 1.043081283569e-07 +353 252 65886111.10029 +354 252 -28555987.69793 +355 252 -13333333.33771 +356 252 16471527.78319 +363 252 72174281.7049 +364 252 1.728534698486e-06 +365 252 1.221895217896e-06 +366 252 -7556159.747413 +367 252 -7.450580596924e-07 +368 252 1.341104507446e-06 +378 252 -88624220.55292 +379 252 2.235174179077e-07 +380 252 -65886111.10029 +381 252 -28555987.69793 +382 252 13333333.33771 +383 252 -16471527.78319 +253 253 785785459.402 +254 253 -1.788139343262e-06 +255 253 -2.086162567139e-06 +256 253 -76617423.53181 +257 253 5.066394805908e-07 +267 253 3.576278686523e-07 +268 253 36444678.54407 +269 253 -4.172325134277e-07 +270 253 53333333.32457 +271 253 -59154777.5129 +272 253 2.98023223877e-08 +351 253 4.470348358154e-08 +352 253 -29957235.32024 +353 253 2.831220626831e-07 +354 253 -13333333.33771 +355 253 -24555795.63051 +356 253 13177083.33766 +363 253 1.728534698486e-06 +364 253 40172745.1813 +365 253 -5.960464477539e-08 +366 253 -7.003545761108e-07 +367 253 -58222760.85313 +368 253 52708333.32467 +378 253 1.9371509552e-07 +379 253 -29957235.32024 +380 253 -3.8743019104e-07 +381 253 13333333.33771 +382 253 -24555795.63051 +383 253 13177083.33766 +254 254 905507012.9075 +255 254 -1.668930053711e-06 +256 254 4.470348358154e-07 +257 254 123977832.6588 +267 254 1.192092895508e-07 +268 254 -4.768371582031e-07 +269 254 66375066.93519 +270 254 4.470348358154e-08 +271 254 -4.470348358154e-08 +272 254 -9005963.440553 +351 254 65886111.10029 +352 254 3.8743019104e-07 +353 254 -87588646.48668 +354 254 16471527.78319 +355 254 13177083.33766 +356 254 -28297094.18124 +363 254 8.642673492432e-07 +364 254 1.788139343262e-07 +365 254 -190352899.3709 +366 254 1.475214958191e-06 +367 254 52708333.32467 +368 254 -73187955.0487 +378 254 -65886111.10029 +379 254 -2.831220626831e-07 +380 254 -87588646.48668 +381 254 -16471527.78319 +382 254 13177083.33766 +383 254 -28297094.18124 +255 255 913791605.4334 +256 255 7.748603820801e-06 +257 255 -2.622604370117e-06 +258 255 126048980.7912 +259 255 -2.175569534302e-06 +260 255 -1.490116119385e-06 +267 255 -75155545.77471 +268 255 -53333333.32457 +269 255 5.066394805908e-07 +270 255 -198223262.271 +271 255 2.98023223877e-07 +272 255 5.960464477539e-08 +273 255 -75155545.7747 +274 255 53333333.32457 +275 255 -1.490116119385e-08 +351 255 -28555987.69793 +352 255 13333333.33771 +353 255 16471527.78319 +354 255 -88624220.55292 +355 255 1.043081283569e-07 +356 255 65886111.10029 +357 255 -28555987.69793 +358 255 -13333333.33771 +359 255 16471527.78319 +363 255 -7556159.747413 +364 255 -3.278255462646e-07 +365 255 -1.206994056702e-06 +366 255 72174281.7049 +367 255 1.728534698486e-06 +368 255 1.221895217896e-06 +369 255 -7556159.747413 +370 255 -7.450580596924e-07 +371 255 1.341104507446e-06 +378 255 -28555987.69793 +379 255 -13333333.33771 +380 255 -16471527.78319 +381 255 -88624220.55292 +382 255 2.235174179077e-07 +383 255 -65886111.10029 +384 255 -28555987.69793 +385 255 13333333.33771 +386 255 -16471527.78319 +256 256 785785459.402 +257 256 -1.788139343262e-06 +258 256 -2.086162567139e-06 +259 256 -76617423.53181 +260 256 5.066394805908e-07 +267 256 -53333333.32457 +268 256 -59154777.5129 +269 256 2.086162567139e-07 +270 256 3.576278686523e-07 +271 256 36444678.54407 +272 256 -4.172325134277e-07 +273 256 53333333.32457 +274 256 -59154777.5129 +275 256 2.98023223877e-08 +351 256 13333333.33771 +352 256 -24555795.63051 +353 256 -13177083.33766 +354 256 4.470348358154e-08 +355 256 -29957235.32024 +356 256 2.831220626831e-07 +357 256 -13333333.33771 +358 256 -24555795.63051 +359 256 13177083.33766 +363 256 -2.98023223877e-07 +364 256 -58222760.85313 +365 256 -52708333.32467 +366 256 1.728534698486e-06 +367 256 40172745.1813 +368 256 -5.960464477539e-08 +369 256 -7.003545761108e-07 +370 256 -58222760.85313 +371 256 52708333.32467 +378 256 -13333333.33771 +379 256 -24555795.63051 +380 256 -13177083.33766 +381 256 1.9371509552e-07 +382 256 -29957235.32024 +383 256 -3.8743019104e-07 +384 256 13333333.33771 +385 256 -24555795.63051 +386 256 13177083.33766 +257 257 905507012.9075 +258 257 -1.668930053711e-06 +259 257 4.470348358154e-07 +260 257 123977832.6588 +267 257 5.811452865601e-07 +268 257 3.129243850708e-07 +269 257 -9005963.440556 +270 257 1.192092895508e-07 +271 257 -4.768371582031e-07 +272 257 66375066.93519 +273 257 4.470348358154e-08 +274 257 -4.470348358154e-08 +275 257 -9005963.440553 +351 257 16471527.78319 +352 257 -13177083.33766 +353 257 -28297094.18124 +354 257 65886111.10029 +355 257 3.8743019104e-07 +356 257 -87588646.48668 +357 257 16471527.78319 +358 257 13177083.33766 +359 257 -28297094.18124 +363 257 -9.983777999878e-07 +364 257 -52708333.32467 +365 257 -73187955.04869 +366 257 8.642673492432e-07 +367 257 1.788139343262e-07 +368 257 -190352899.3709 +369 257 1.475214958191e-06 +370 257 52708333.32467 +371 257 -73187955.0487 +378 257 -16471527.78319 +379 257 -13177083.33766 +380 257 -28297094.18124 +381 257 -65886111.10029 +382 257 -2.831220626831e-07 +383 257 -87588646.48668 +384 257 -16471527.78319 +385 257 13177083.33766 +386 257 -28297094.18124 +258 258 913791605.4334 +259 258 7.748603820801e-06 +260 258 -2.622604370117e-06 +261 258 126048980.7912 +262 258 -2.175569534302e-06 +263 258 -1.490116119385e-06 +270 258 -75155545.77471 +271 258 -53333333.32457 +272 258 5.066394805908e-07 +273 258 -198223262.271 +274 258 2.98023223877e-07 +275 258 5.960464477539e-08 +276 258 -75155545.7747 +277 258 53333333.32457 +278 258 -1.490116119385e-08 +354 258 -28555987.69793 +355 258 13333333.33771 +356 258 16471527.78319 +357 258 -88624220.55292 +358 258 1.043081283569e-07 +359 258 65886111.10029 +360 258 -28555987.69793 +361 258 -13333333.33771 +362 258 16471527.78319 +366 258 -7556159.747413 +367 258 -3.278255462646e-07 +368 258 -1.206994056702e-06 +369 258 72174281.7049 +370 258 1.728534698486e-06 +371 258 1.221895217896e-06 +372 258 -7556159.747413 +373 258 -7.450580596924e-07 +374 258 1.341104507446e-06 +381 258 -28555987.69793 +382 258 -13333333.33771 +383 258 -16471527.78319 +384 258 -88624220.55292 +385 258 2.235174179077e-07 +386 258 -65886111.10029 +387 258 -28555987.69793 +388 258 13333333.33771 +389 258 -16471527.78319 +259 259 785785459.402 +260 259 -1.788139343262e-06 +261 259 -2.086162567139e-06 +262 259 -76617423.53181 +263 259 5.066394805908e-07 +270 259 -53333333.32457 +271 259 -59154777.5129 +272 259 2.086162567139e-07 +273 259 3.576278686523e-07 +274 259 36444678.54407 +275 259 -4.172325134277e-07 +276 259 53333333.32457 +277 259 -59154777.5129 +278 259 2.98023223877e-08 +354 259 13333333.33771 +355 259 -24555795.63051 +356 259 -13177083.33766 +357 259 4.470348358154e-08 +358 259 -29957235.32024 +359 259 2.831220626831e-07 +360 259 -13333333.33771 +361 259 -24555795.63051 +362 259 13177083.33766 +366 259 -2.98023223877e-07 +367 259 -58222760.85313 +368 259 -52708333.32467 +369 259 1.728534698486e-06 +370 259 40172745.1813 +371 259 -5.960464477539e-08 +372 259 -7.003545761108e-07 +373 259 -58222760.85313 +374 259 52708333.32467 +381 259 -13333333.33771 +382 259 -24555795.63051 +383 259 -13177083.33766 +384 259 1.9371509552e-07 +385 259 -29957235.32024 +386 259 -3.8743019104e-07 +387 259 13333333.33771 +388 259 -24555795.63051 +389 259 13177083.33766 +260 260 905507012.9075 +261 260 -1.668930053711e-06 +262 260 4.470348358154e-07 +263 260 123977832.6588 +270 260 5.811452865601e-07 +271 260 3.129243850708e-07 +272 260 -9005963.440556 +273 260 1.192092895508e-07 +274 260 -4.768371582031e-07 +275 260 66375066.93519 +276 260 4.470348358154e-08 +277 260 -4.470348358154e-08 +278 260 -9005963.440553 +354 260 16471527.78319 +355 260 -13177083.33766 +356 260 -28297094.18124 +357 260 65886111.10029 +358 260 3.8743019104e-07 +359 260 -87588646.48668 +360 260 16471527.78319 +361 260 13177083.33766 +362 260 -28297094.18124 +366 260 -9.983777999878e-07 +367 260 -52708333.32467 +368 260 -73187955.04869 +369 260 8.642673492432e-07 +370 260 1.788139343262e-07 +371 260 -190352899.3709 +372 260 1.475214958191e-06 +373 260 52708333.32467 +374 260 -73187955.0487 +381 260 -16471527.78319 +382 260 -13177083.33766 +383 260 -28297094.18124 +384 260 -65886111.10029 +385 260 -2.831220626831e-07 +386 260 -87588646.48668 +387 260 -16471527.78319 +388 260 13177083.33766 +389 260 -28297094.18124 +261 261 988947148.5376 +262 261 53333332.25791 +263 261 -9.298324584961e-06 +264 261 31359232.67644 +265 261 -53333332.8979 +266 261 1.251697540283e-06 +273 261 -75155545.77471 +274 261 -53333333.32457 +275 261 5.066394805908e-07 +276 261 -198223262.271 +277 261 2.98023223877e-07 +278 261 5.960464477539e-08 +279 261 -75155545.7747 +280 261 53333333.32457 +281 261 -1.490116119385e-08 +357 261 -28555987.69793 +358 261 13333333.33771 +359 261 16471527.78319 +360 261 -107413106.5112 +361 261 -13333333.17771 +362 261 65886110.96157 +369 261 -7556159.747413 +370 261 -3.278255462646e-07 +371 261 -1.206994056702e-06 +372 261 100730268.7541 +373 261 13333333.07105 +374 261 0.02774140238762 +375 261 -26345045.89131 +376 261 -13333333.23105 +377 261 16471527.49884 +384 261 -28555987.69793 +385 261 -13333333.33771 +386 261 -16471527.78319 +387 261 -88624220.55292 +388 261 2.235174179077e-07 +389 261 -65886111.10029 +390 261 -28555987.69793 +391 261 13333333.33771 +392 261 -16471527.78319 +262 262 844940234.7245 +263 262 -7.987022399902e-06 +264 262 -53333332.68457 +265 262 -155306402.5315 +266 262 5.394220352173e-06 +273 262 -53333333.32457 +274 262 -59154777.5129 +275 262 2.086162567139e-07 +276 262 3.576278686523e-07 +277 262 36444678.54407 +278 262 -4.172325134277e-07 +279 262 53333333.32457 +280 262 -59154777.5129 +281 262 2.98023223877e-08 +357 262 13333333.33771 +358 262 -24555795.63051 +359 262 -13177083.33766 +360 262 -13333333.23104 +361 262 -44745929.54447 +362 262 13177083.28808 +369 262 -2.98023223877e-07 +370 262 -58222760.85313 +371 262 -52708333.32467 +372 262 13333333.07105 +373 262 64728540.28304 +374 262 0.022192299366 +375 262 -13333333.17771 +376 262 -73011454.71628 +377 262 52708333.03581 +384 262 -13333333.33771 +385 262 -24555795.63051 +386 262 -13177083.33766 +387 262 1.9371509552e-07 +388 262 -29957235.32024 +389 262 -3.8743019104e-07 +390 262 13333333.33771 +391 262 -24555795.63051 +392 262 13177083.33766 +263 263 914512974.9691 +264 263 1.728534698486e-06 +265 263 4.559755325317e-06 +266 263 62880662.12465 +273 263 5.811452865601e-07 +274 263 3.129243850708e-07 +275 263 -9005963.440556 +276 263 1.192092895508e-07 +277 263 -4.768371582031e-07 +278 263 66375066.93519 +279 263 4.470348358154e-08 +280 263 -4.470348358154e-08 +281 263 -9005963.440553 +357 263 16471527.78319 +358 263 -13177083.33766 +359 263 -28297094.18124 +360 263 65886110.96157 +361 263 13177083.26329 +362 263 -89840137.25118 +369 263 -9.983777999878e-07 +370 263 -52708333.32467 +371 263 -73187955.04869 +372 263 -0.0277450978756 +373 263 -0.02219566702843 +374 263 -162055805.4842 +375 263 16471527.35667 +376 263 52708332.94687 +377 263 -75439445.29918 +384 263 -16471527.78319 +385 263 -13177083.33766 +386 263 -28297094.18124 +387 263 -65886111.10029 +388 263 -2.831220626831e-07 +389 263 -87588646.48668 +390 263 -16471527.78319 +391 263 13177083.33766 +392 263 -28297094.18124 +264 264 571119749.839 +265 264 53333333.32457 +266 264 -6.198883056641e-06 +276 264 -75155545.77471 +277 264 -53333333.32457 +278 264 5.066394805908e-07 +279 264 -292913008.3249 +280 264 -53333332.8979 +281 264 6.556510925293e-06 +282 264 19534202.10867 +283 264 42666666.23299 +284 264 -1.490116119385e-06 +360 264 -9767101.054335 +361 264 15999999.84525 +362 264 19765832.91331 +372 264 -26345045.8913 +373 264 -13333333.17771 +374 264 -16471527.35667 +375 264 45108925.89256 +376 264 13333333.33771 +377 264 13177222.19231 +387 264 -28555987.69793 +388 264 -13333333.33771 +389 264 -16471527.78319 +390 264 -107413106.5112 +391 264 -13333333.23104 +392 264 -65886110.96157 +393 264 -9767101.054335 +394 264 10666666.5635 +395 264 -13177221.94221 +265 265 491115909.0416 +266 265 -2.974887930942e-06 +276 265 -53333333.32457 +277 265 -59154777.5129 +278 265 2.086162567139e-07 +279 265 -53333332.68457 +280 265 -42244300.58137 +281 265 2.145767211914e-06 +282 265 63999999.34949 +283 265 19534202.10866 +284 265 -2.384185791016e-06 +360 265 10666666.5635 +361 265 -9767101.054336 +362 265 -10541666.62055 +372 265 -13333333.23105 +373 265 -73011454.71627 +374 265 -52708332.94687 +375 265 13333333.33771 +376 265 25107965.68335 +377 265 10541666.55379 +387 265 -13333333.33771 +388 265 -24555795.63051 +389 265 -13177083.33766 +390 265 -13333333.17771 +391 265 -44745929.54446 +392 265 -13177083.26329 +393 265 15999999.84525 +394 265 -9767101.054335 +395 265 15812499.93082 +266 266 565941879.2302 +276 266 5.811452865601e-07 +277 266 3.129243850708e-07 +278 266 -9005963.440556 +279 266 6.943941116333e-06 +280 266 1.609325408936e-06 +281 266 5277897.861165 +282 266 -2.145767211914e-06 +283 266 -1.54972076416e-06 +284 266 52091205.62311 +360 266 13177221.94221 +361 266 -15812499.93082 +362 266 -26045602.81156 +372 266 -16471527.49884 +373 266 -52708333.03581 +374 266 -75439445.29917 +375 266 -13177222.19232 +376 266 -10541666.5538 +377 266 -118970561.1562 +387 266 -16471527.78319 +388 266 -13177083.33766 +389 266 -28297094.18124 +390 266 -65886110.96157 +391 266 -13177083.28808 +392 266 -89840137.25117 +393 266 -19765832.91331 +394 266 10541666.62055 +395 266 -26045602.81156 +267 267 913791605.4334 +268 267 7.748603820801e-06 +269 267 -2.622604370117e-06 +270 267 126048980.7912 +271 267 -2.175569534302e-06 +272 267 -1.490116119385e-06 +285 267 -198223262.271 +286 267 2.98023223877e-07 +287 267 5.960464477539e-08 +288 267 -75155545.7747 +289 267 53333333.32457 +290 267 -1.490116119385e-08 +363 267 -88624220.55292 +364 267 1.043081283569e-07 +365 267 65886111.10029 +366 267 -28555987.69793 +367 267 -13333333.33771 +368 267 16471527.78319 +378 267 72174281.7049 +379 267 1.728534698486e-06 +380 267 1.221895217896e-06 +381 267 -7556159.747413 +382 267 -7.450580596924e-07 +383 267 1.341104507446e-06 +396 267 -88624220.55292 +397 267 2.235174179077e-07 +398 267 -65886111.10029 +399 267 -28555987.69793 +400 267 13333333.33771 +401 267 -16471527.78319 +268 268 785785459.402 +269 268 -1.788139343262e-06 +270 268 -2.086162567139e-06 +271 268 -76617423.53181 +272 268 5.066394805908e-07 +285 268 3.576278686523e-07 +286 268 36444678.54407 +287 268 -4.172325134277e-07 +288 268 53333333.32457 +289 268 -59154777.5129 +290 268 2.98023223877e-08 +363 268 4.470348358154e-08 +364 268 -29957235.32024 +365 268 2.831220626831e-07 +366 268 -13333333.33771 +367 268 -24555795.63051 +368 268 13177083.33766 +378 268 1.728534698486e-06 +379 268 40172745.1813 +380 268 -5.960464477539e-08 +381 268 -7.003545761108e-07 +382 268 -58222760.85313 +383 268 52708333.32467 +396 268 1.9371509552e-07 +397 268 -29957235.32024 +398 268 -3.8743019104e-07 +399 268 13333333.33771 +400 268 -24555795.63051 +401 268 13177083.33766 +269 269 905507012.9075 +270 269 -1.668930053711e-06 +271 269 4.470348358154e-07 +272 269 123977832.6588 +285 269 1.192092895508e-07 +286 269 -4.768371582031e-07 +287 269 66375066.93519 +288 269 4.470348358154e-08 +289 269 -4.470348358154e-08 +290 269 -9005963.440553 +363 269 65886111.10029 +364 269 3.8743019104e-07 +365 269 -87588646.48668 +366 269 16471527.78319 +367 269 13177083.33766 +368 269 -28297094.18124 +378 269 8.642673492432e-07 +379 269 1.788139343262e-07 +380 269 -190352899.3709 +381 269 1.475214958191e-06 +382 269 52708333.32467 +383 269 -73187955.0487 +396 269 -65886111.10029 +397 269 -2.831220626831e-07 +398 269 -87588646.48668 +399 269 -16471527.78319 +400 269 13177083.33766 +401 269 -28297094.18124 +270 270 913791605.4334 +271 270 7.748603820801e-06 +272 270 -2.622604370117e-06 +273 270 126048980.7912 +274 270 -2.175569534302e-06 +275 270 -1.490116119385e-06 +285 270 -75155545.77471 +286 270 -53333333.32457 +287 270 5.066394805908e-07 +288 270 -198223262.271 +289 270 2.98023223877e-07 +290 270 5.960464477539e-08 +291 270 -75155545.7747 +292 270 53333333.32457 +293 270 -1.490116119385e-08 +363 270 -28555987.69793 +364 270 13333333.33771 +365 270 16471527.78319 +366 270 -88624220.55292 +367 270 1.043081283569e-07 +368 270 65886111.10029 +369 270 -28555987.69793 +370 270 -13333333.33771 +371 270 16471527.78319 +378 270 -7556159.747413 +379 270 -3.278255462646e-07 +380 270 -1.206994056702e-06 +381 270 72174281.7049 +382 270 1.728534698486e-06 +383 270 1.221895217896e-06 +384 270 -7556159.747413 +385 270 -7.450580596924e-07 +386 270 1.341104507446e-06 +396 270 -28555987.69793 +397 270 -13333333.33771 +398 270 -16471527.78319 +399 270 -88624220.55292 +400 270 2.235174179077e-07 +401 270 -65886111.10029 +402 270 -28555987.69793 +403 270 13333333.33771 +404 270 -16471527.78319 +271 271 785785459.402 +272 271 -1.788139343262e-06 +273 271 -2.086162567139e-06 +274 271 -76617423.53181 +275 271 5.066394805908e-07 +285 271 -53333333.32457 +286 271 -59154777.5129 +287 271 2.086162567139e-07 +288 271 3.576278686523e-07 +289 271 36444678.54407 +290 271 -4.172325134277e-07 +291 271 53333333.32457 +292 271 -59154777.5129 +293 271 2.98023223877e-08 +363 271 13333333.33771 +364 271 -24555795.63051 +365 271 -13177083.33766 +366 271 4.470348358154e-08 +367 271 -29957235.32024 +368 271 2.831220626831e-07 +369 271 -13333333.33771 +370 271 -24555795.63051 +371 271 13177083.33766 +378 271 -2.98023223877e-07 +379 271 -58222760.85313 +380 271 -52708333.32467 +381 271 1.728534698486e-06 +382 271 40172745.1813 +383 271 -5.960464477539e-08 +384 271 -7.003545761108e-07 +385 271 -58222760.85313 +386 271 52708333.32467 +396 271 -13333333.33771 +397 271 -24555795.63051 +398 271 -13177083.33766 +399 271 1.9371509552e-07 +400 271 -29957235.32024 +401 271 -3.8743019104e-07 +402 271 13333333.33771 +403 271 -24555795.63051 +404 271 13177083.33766 +272 272 905507012.9075 +273 272 -1.668930053711e-06 +274 272 4.470348358154e-07 +275 272 123977832.6588 +285 272 5.811452865601e-07 +286 272 3.129243850708e-07 +287 272 -9005963.440556 +288 272 1.192092895508e-07 +289 272 -4.768371582031e-07 +290 272 66375066.93519 +291 272 4.470348358154e-08 +292 272 -4.470348358154e-08 +293 272 -9005963.440553 +363 272 16471527.78319 +364 272 -13177083.33766 +365 272 -28297094.18124 +366 272 65886111.10029 +367 272 3.8743019104e-07 +368 272 -87588646.48668 +369 272 16471527.78319 +370 272 13177083.33766 +371 272 -28297094.18124 +378 272 -9.983777999878e-07 +379 272 -52708333.32467 +380 272 -73187955.04869 +381 272 8.642673492432e-07 +382 272 1.788139343262e-07 +383 272 -190352899.3709 +384 272 1.475214958191e-06 +385 272 52708333.32467 +386 272 -73187955.0487 +396 272 -16471527.78319 +397 272 -13177083.33766 +398 272 -28297094.18124 +399 272 -65886111.10029 +400 272 -2.831220626831e-07 +401 272 -87588646.48668 +402 272 -16471527.78319 +403 272 13177083.33766 +404 272 -28297094.18124 +273 273 913791605.4334 +274 273 7.748603820801e-06 +275 273 -2.622604370117e-06 +276 273 126048980.7912 +277 273 -2.175569534302e-06 +278 273 -1.490116119385e-06 +288 273 -75155545.77471 +289 273 -53333333.32457 +290 273 5.066394805908e-07 +291 273 -198223262.271 +292 273 2.98023223877e-07 +293 273 5.960464477539e-08 +294 273 -75155545.7747 +295 273 53333333.32457 +296 273 -1.490116119385e-08 +366 273 -28555987.69793 +367 273 13333333.33771 +368 273 16471527.78319 +369 273 -88624220.55292 +370 273 1.043081283569e-07 +371 273 65886111.10029 +372 273 -28555987.69793 +373 273 -13333333.33771 +374 273 16471527.78319 +381 273 -7556159.747413 +382 273 -3.278255462646e-07 +383 273 -1.206994056702e-06 +384 273 72174281.7049 +385 273 1.728534698486e-06 +386 273 1.221895217896e-06 +387 273 -7556159.747413 +388 273 -7.450580596924e-07 +389 273 1.341104507446e-06 +399 273 -28555987.69793 +400 273 -13333333.33771 +401 273 -16471527.78319 +402 273 -88624220.55292 +403 273 2.235174179077e-07 +404 273 -65886111.10029 +405 273 -28555987.69793 +406 273 13333333.33771 +407 273 -16471527.78319 +274 274 785785459.402 +275 274 -1.788139343262e-06 +276 274 -2.086162567139e-06 +277 274 -76617423.53181 +278 274 5.066394805908e-07 +288 274 -53333333.32457 +289 274 -59154777.5129 +290 274 2.086162567139e-07 +291 274 3.576278686523e-07 +292 274 36444678.54407 +293 274 -4.172325134277e-07 +294 274 53333333.32457 +295 274 -59154777.5129 +296 274 2.98023223877e-08 +366 274 13333333.33771 +367 274 -24555795.63051 +368 274 -13177083.33766 +369 274 4.470348358154e-08 +370 274 -29957235.32024 +371 274 2.831220626831e-07 +372 274 -13333333.33771 +373 274 -24555795.63051 +374 274 13177083.33766 +381 274 -2.98023223877e-07 +382 274 -58222760.85313 +383 274 -52708333.32467 +384 274 1.728534698486e-06 +385 274 40172745.1813 +386 274 -5.960464477539e-08 +387 274 -7.003545761108e-07 +388 274 -58222760.85313 +389 274 52708333.32467 +399 274 -13333333.33771 +400 274 -24555795.63051 +401 274 -13177083.33766 +402 274 1.9371509552e-07 +403 274 -29957235.32024 +404 274 -3.8743019104e-07 +405 274 13333333.33771 +406 274 -24555795.63051 +407 274 13177083.33766 +275 275 905507012.9075 +276 275 -1.668930053711e-06 +277 275 4.470348358154e-07 +278 275 123977832.6588 +288 275 5.811452865601e-07 +289 275 3.129243850708e-07 +290 275 -9005963.440556 +291 275 1.192092895508e-07 +292 275 -4.768371582031e-07 +293 275 66375066.93519 +294 275 4.470348358154e-08 +295 275 -4.470348358154e-08 +296 275 -9005963.440553 +366 275 16471527.78319 +367 275 -13177083.33766 +368 275 -28297094.18124 +369 275 65886111.10029 +370 275 3.8743019104e-07 +371 275 -87588646.48668 +372 275 16471527.78319 +373 275 13177083.33766 +374 275 -28297094.18124 +381 275 -9.983777999878e-07 +382 275 -52708333.32467 +383 275 -73187955.04869 +384 275 8.642673492432e-07 +385 275 1.788139343262e-07 +386 275 -190352899.3709 +387 275 1.475214958191e-06 +388 275 52708333.32467 +389 275 -73187955.0487 +399 275 -16471527.78319 +400 275 -13177083.33766 +401 275 -28297094.18124 +402 275 -65886111.10029 +403 275 -2.831220626831e-07 +404 275 -87588646.48668 +405 275 -16471527.78319 +406 275 13177083.33766 +407 275 -28297094.18124 +276 276 913791605.4334 +277 276 7.748603820801e-06 +278 276 -2.622604370117e-06 +279 276 126048980.7912 +280 276 -2.175569534302e-06 +281 276 -1.490116119385e-06 +291 276 -75155545.77471 +292 276 -53333333.32457 +293 276 5.066394805908e-07 +294 276 -198223262.271 +295 276 2.98023223877e-07 +296 276 5.960464477539e-08 +297 276 -75155545.7747 +298 276 53333333.32457 +299 276 -1.490116119385e-08 +369 276 -28555987.69793 +370 276 13333333.33771 +371 276 16471527.78319 +372 276 -88624220.55292 +373 276 1.043081283569e-07 +374 276 65886111.10029 +375 276 -28555987.69793 +376 276 -13333333.33771 +377 276 16471527.78319 +384 276 -7556159.747413 +385 276 -3.278255462646e-07 +386 276 -1.206994056702e-06 +387 276 72174281.7049 +388 276 1.728534698486e-06 +389 276 1.221895217896e-06 +390 276 -7556159.747413 +391 276 -7.450580596924e-07 +392 276 1.341104507446e-06 +402 276 -28555987.69793 +403 276 -13333333.33771 +404 276 -16471527.78319 +405 276 -88624220.55292 +406 276 2.235174179077e-07 +407 276 -65886111.10029 +408 276 -28555987.69793 +409 276 13333333.33771 +410 276 -16471527.78319 +277 277 785785459.402 +278 277 -1.788139343262e-06 +279 277 -2.086162567139e-06 +280 277 -76617423.53181 +281 277 5.066394805908e-07 +291 277 -53333333.32457 +292 277 -59154777.5129 +293 277 2.086162567139e-07 +294 277 3.576278686523e-07 +295 277 36444678.54407 +296 277 -4.172325134277e-07 +297 277 53333333.32457 +298 277 -59154777.5129 +299 277 2.98023223877e-08 +369 277 13333333.33771 +370 277 -24555795.63051 +371 277 -13177083.33766 +372 277 4.470348358154e-08 +373 277 -29957235.32024 +374 277 2.831220626831e-07 +375 277 -13333333.33771 +376 277 -24555795.63051 +377 277 13177083.33766 +384 277 -2.98023223877e-07 +385 277 -58222760.85313 +386 277 -52708333.32467 +387 277 1.728534698486e-06 +388 277 40172745.1813 +389 277 -5.960464477539e-08 +390 277 -7.003545761108e-07 +391 277 -58222760.85313 +392 277 52708333.32467 +402 277 -13333333.33771 +403 277 -24555795.63051 +404 277 -13177083.33766 +405 277 1.9371509552e-07 +406 277 -29957235.32024 +407 277 -3.8743019104e-07 +408 277 13333333.33771 +409 277 -24555795.63051 +410 277 13177083.33766 +278 278 905507012.9075 +279 278 -1.668930053711e-06 +280 278 4.470348358154e-07 +281 278 123977832.6588 +291 278 5.811452865601e-07 +292 278 3.129243850708e-07 +293 278 -9005963.440556 +294 278 1.192092895508e-07 +295 278 -4.768371582031e-07 +296 278 66375066.93519 +297 278 4.470348358154e-08 +298 278 -4.470348358154e-08 +299 278 -9005963.440553 +369 278 16471527.78319 +370 278 -13177083.33766 +371 278 -28297094.18124 +372 278 65886111.10029 +373 278 3.8743019104e-07 +374 278 -87588646.48668 +375 278 16471527.78319 +376 278 13177083.33766 +377 278 -28297094.18124 +384 278 -9.983777999878e-07 +385 278 -52708333.32467 +386 278 -73187955.04869 +387 278 8.642673492432e-07 +388 278 1.788139343262e-07 +389 278 -190352899.3709 +390 278 1.475214958191e-06 +391 278 52708333.32467 +392 278 -73187955.0487 +402 278 -16471527.78319 +403 278 -13177083.33766 +404 278 -28297094.18124 +405 278 -65886111.10029 +406 278 -2.831220626831e-07 +407 278 -87588646.48668 +408 278 -16471527.78319 +409 278 13177083.33766 +410 278 -28297094.18124 +279 279 988947148.5376 +280 279 53333332.25791 +281 279 -9.298324584961e-06 +282 279 31359232.67644 +283 279 -53333332.8979 +284 279 1.251697540283e-06 +294 279 -75155545.77471 +295 279 -53333333.32457 +296 279 5.066394805908e-07 +297 279 -198223262.271 +298 279 2.98023223877e-07 +299 279 5.960464477539e-08 +300 279 -75155545.7747 +301 279 53333333.32457 +302 279 -1.490116119385e-08 +372 279 -28555987.69793 +373 279 13333333.33771 +374 279 16471527.78319 +375 279 -107413106.5112 +376 279 -13333333.17771 +377 279 65886110.96157 +387 279 -7556159.747413 +388 279 -3.278255462646e-07 +389 279 -1.206994056702e-06 +390 279 100730268.7541 +391 279 13333333.07105 +392 279 0.02774140238762 +393 279 -26345045.89131 +394 279 -13333333.23105 +395 279 16471527.49884 +405 279 -28555987.69793 +406 279 -13333333.33771 +407 279 -16471527.78319 +408 279 -88624220.55292 +409 279 2.235174179077e-07 +410 279 -65886111.10029 +411 279 -28555987.69793 +412 279 13333333.33771 +413 279 -16471527.78319 +280 280 844940234.7245 +281 280 -7.987022399902e-06 +282 280 -53333332.68457 +283 280 -155306402.5315 +284 280 5.394220352173e-06 +294 280 -53333333.32457 +295 280 -59154777.5129 +296 280 2.086162567139e-07 +297 280 3.576278686523e-07 +298 280 36444678.54407 +299 280 -4.172325134277e-07 +300 280 53333333.32457 +301 280 -59154777.5129 +302 280 2.98023223877e-08 +372 280 13333333.33771 +373 280 -24555795.63051 +374 280 -13177083.33766 +375 280 -13333333.23104 +376 280 -44745929.54447 +377 280 13177083.28808 +387 280 -2.98023223877e-07 +388 280 -58222760.85313 +389 280 -52708333.32467 +390 280 13333333.07105 +391 280 64728540.28304 +392 280 0.022192299366 +393 280 -13333333.17771 +394 280 -73011454.71628 +395 280 52708333.03581 +405 280 -13333333.33771 +406 280 -24555795.63051 +407 280 -13177083.33766 +408 280 1.9371509552e-07 +409 280 -29957235.32024 +410 280 -3.8743019104e-07 +411 280 13333333.33771 +412 280 -24555795.63051 +413 280 13177083.33766 +281 281 914512974.9691 +282 281 1.728534698486e-06 +283 281 4.559755325317e-06 +284 281 62880662.12465 +294 281 5.811452865601e-07 +295 281 3.129243850708e-07 +296 281 -9005963.440556 +297 281 1.192092895508e-07 +298 281 -4.768371582031e-07 +299 281 66375066.93519 +300 281 4.470348358154e-08 +301 281 -4.470348358154e-08 +302 281 -9005963.440553 +372 281 16471527.78319 +373 281 -13177083.33766 +374 281 -28297094.18124 +375 281 65886110.96157 +376 281 13177083.26329 +377 281 -89840137.25118 +387 281 -9.983777999878e-07 +388 281 -52708333.32467 +389 281 -73187955.04869 +390 281 -0.0277450978756 +391 281 -0.02219566702843 +392 281 -162055805.4842 +393 281 16471527.35667 +394 281 52708332.94687 +395 281 -75439445.29918 +405 281 -16471527.78319 +406 281 -13177083.33766 +407 281 -28297094.18124 +408 281 -65886111.10029 +409 281 -2.831220626831e-07 +410 281 -87588646.48668 +411 281 -16471527.78319 +412 281 13177083.33766 +413 281 -28297094.18124 +282 282 509154568.8248 +283 282 25085639.27704 +284 282 -5.960464477539e-07 +297 282 -75155545.77471 +298 282 -53333333.32457 +299 282 5.066394805908e-07 +300 282 -228025244.9359 +301 282 -25085638.85037 +302 282 7.152557373047e-07 +303 282 -4082989.550575 +304 282 42666666.23299 +305 282 -1.251697540283e-06 +375 282 -9767101.054335 +376 282 15999999.84525 +377 282 19765832.91331 +390 282 -26345045.8913 +391 282 -13333333.17771 +392 282 -16471527.35667 +393 282 37378109.13818 +394 282 6271409.822349 +395 282 11432222.19995 +408 282 -28555987.69793 +409 282 -13333333.33771 +410 282 -16471527.78319 +411 282 -87310926.38278 +412 282 -6271409.715683 +413 282 -57161110.99975 +414 282 -11791159.78617 +415 282 10666666.5635 +416 282 -9687222.01637 +283 283 472604990.7818 +284 283 -2.652406692505e-06 +297 283 -53333333.32457 +298 283 -59154777.5129 +299 283 2.086162567139e-07 +300 283 -25085638.63704 +301 283 9928432.40691 +302 283 2.384185791016e-07 +303 283 63999999.34949 +304 283 -34822221.9043 +305 283 -1.788139343262e-07 +375 283 10666666.5635 +376 283 -9767101.054336 +377 283 -10541666.62055 +390 283 -13333333.23105 +391 283 -73011454.71627 +392 283 -52708332.94687 +393 283 6271409.822349 +394 283 28240714.62293 +395 283 9145833.226567 +408 283 -13333333.33771 +409 283 -24555795.63051 +410 283 -13177083.33766 +411 283 -6271409.66235 +412 283 -27822507.01778 +413 283 -6197916.627156 +414 283 15999999.84526 +415 283 -19475967.87838 +416 283 18604166.53816 +284 284 522045024.059 +297 284 5.811452865601e-07 +298 284 3.129243850708e-07 +299 284 -9005963.440556 +300 284 7.450580596924e-07 +301 284 2.384185791016e-07 +302 284 26229073.67805 +303 284 -1.490116119385e-06 +304 284 2.384185791016e-07 +305 284 19851260.21887 +375 284 13177221.94221 +376 284 -15812499.93082 +377 284 -26045602.81156 +390 284 -16471527.49884 +391 284 -52708333.03581 +392 284 -75439445.29917 +393 284 -11432222.19995 +394 284 -9145833.22657 +395 284 -109250165.6029 +408 284 -16471527.78319 +409 284 -13177083.33766 +410 284 -28297094.18124 +411 284 -57161110.99975 +412 284 -6197916.651946 +413 284 -74255038.56586 +414 284 -14530833.02455 +415 284 14729166.53156 +416 284 -23758284.67089 +285 285 913791605.4334 +286 285 7.748603820801e-06 +287 285 -2.622604370117e-06 +288 285 126048980.7912 +289 285 -2.175569534302e-06 +290 285 -1.490116119385e-06 +306 285 -198223262.271 +307 285 2.98023223877e-07 +308 285 5.960464477539e-08 +309 285 -75155545.7747 +310 285 53333333.32457 +311 285 -1.490116119385e-08 +378 285 -88624220.55292 +379 285 1.043081283569e-07 +380 285 65886111.10029 +381 285 -28555987.69793 +382 285 -13333333.33771 +383 285 16471527.78319 +396 285 72174281.7049 +397 285 1.728534698486e-06 +398 285 1.221895217896e-06 +399 285 -7556159.747413 +400 285 -7.450580596924e-07 +401 285 1.341104507446e-06 +417 285 -88624220.55292 +418 285 2.235174179077e-07 +419 285 -65886111.10029 +420 285 -28555987.69793 +421 285 13333333.33771 +422 285 -16471527.78319 +286 286 785785459.402 +287 286 -1.788139343262e-06 +288 286 -2.086162567139e-06 +289 286 -76617423.53181 +290 286 5.066394805908e-07 +306 286 3.576278686523e-07 +307 286 36444678.54407 +308 286 -4.172325134277e-07 +309 286 53333333.32457 +310 286 -59154777.5129 +311 286 2.98023223877e-08 +378 286 4.470348358154e-08 +379 286 -29957235.32024 +380 286 2.831220626831e-07 +381 286 -13333333.33771 +382 286 -24555795.63051 +383 286 13177083.33766 +396 286 1.728534698486e-06 +397 286 40172745.1813 +398 286 -5.960464477539e-08 +399 286 -7.003545761108e-07 +400 286 -58222760.85313 +401 286 52708333.32467 +417 286 1.9371509552e-07 +418 286 -29957235.32024 +419 286 -3.8743019104e-07 +420 286 13333333.33771 +421 286 -24555795.63051 +422 286 13177083.33766 +287 287 905507012.9075 +288 287 -1.668930053711e-06 +289 287 4.470348358154e-07 +290 287 123977832.6588 +306 287 1.192092895508e-07 +307 287 -4.768371582031e-07 +308 287 66375066.93519 +309 287 4.470348358154e-08 +310 287 -4.470348358154e-08 +311 287 -9005963.440553 +378 287 65886111.10029 +379 287 3.8743019104e-07 +380 287 -87588646.48668 +381 287 16471527.78319 +382 287 13177083.33766 +383 287 -28297094.18124 +396 287 8.642673492432e-07 +397 287 1.788139343262e-07 +398 287 -190352899.3709 +399 287 1.475214958191e-06 +400 287 52708333.32467 +401 287 -73187955.0487 +417 287 -65886111.10029 +418 287 -2.831220626831e-07 +419 287 -87588646.48668 +420 287 -16471527.78319 +421 287 13177083.33766 +422 287 -28297094.18124 +288 288 913791605.4334 +289 288 7.748603820801e-06 +290 288 -2.622604370117e-06 +291 288 126048980.7912 +292 288 -2.175569534302e-06 +293 288 -1.490116119385e-06 +306 288 -75155545.77471 +307 288 -53333333.32457 +308 288 5.066394805908e-07 +309 288 -198223262.271 +310 288 2.98023223877e-07 +311 288 5.960464477539e-08 +312 288 -75155545.7747 +313 288 53333333.32457 +314 288 -1.490116119385e-08 +378 288 -28555987.69793 +379 288 13333333.33771 +380 288 16471527.78319 +381 288 -88624220.55292 +382 288 1.043081283569e-07 +383 288 65886111.10029 +384 288 -28555987.69793 +385 288 -13333333.33771 +386 288 16471527.78319 +396 288 -7556159.747413 +397 288 -3.278255462646e-07 +398 288 -1.206994056702e-06 +399 288 72174281.7049 +400 288 1.728534698486e-06 +401 288 1.221895217896e-06 +402 288 -7556159.747413 +403 288 -7.450580596924e-07 +404 288 1.341104507446e-06 +417 288 -28555987.69793 +418 288 -13333333.33771 +419 288 -16471527.78319 +420 288 -88624220.55292 +421 288 2.235174179077e-07 +422 288 -65886111.10029 +423 288 -28555987.69793 +424 288 13333333.33771 +425 288 -16471527.78319 +289 289 785785459.402 +290 289 -1.788139343262e-06 +291 289 -2.086162567139e-06 +292 289 -76617423.53181 +293 289 5.066394805908e-07 +306 289 -53333333.32457 +307 289 -59154777.5129 +308 289 2.086162567139e-07 +309 289 3.576278686523e-07 +310 289 36444678.54407 +311 289 -4.172325134277e-07 +312 289 53333333.32457 +313 289 -59154777.5129 +314 289 2.98023223877e-08 +378 289 13333333.33771 +379 289 -24555795.63051 +380 289 -13177083.33766 +381 289 4.470348358154e-08 +382 289 -29957235.32024 +383 289 2.831220626831e-07 +384 289 -13333333.33771 +385 289 -24555795.63051 +386 289 13177083.33766 +396 289 -2.98023223877e-07 +397 289 -58222760.85313 +398 289 -52708333.32467 +399 289 1.728534698486e-06 +400 289 40172745.1813 +401 289 -5.960464477539e-08 +402 289 -7.003545761108e-07 +403 289 -58222760.85313 +404 289 52708333.32467 +417 289 -13333333.33771 +418 289 -24555795.63051 +419 289 -13177083.33766 +420 289 1.9371509552e-07 +421 289 -29957235.32024 +422 289 -3.8743019104e-07 +423 289 13333333.33771 +424 289 -24555795.63051 +425 289 13177083.33766 +290 290 905507012.9075 +291 290 -1.668930053711e-06 +292 290 4.470348358154e-07 +293 290 123977832.6588 +306 290 5.811452865601e-07 +307 290 3.129243850708e-07 +308 290 -9005963.440556 +309 290 1.192092895508e-07 +310 290 -4.768371582031e-07 +311 290 66375066.93519 +312 290 4.470348358154e-08 +313 290 -4.470348358154e-08 +314 290 -9005963.440553 +378 290 16471527.78319 +379 290 -13177083.33766 +380 290 -28297094.18124 +381 290 65886111.10029 +382 290 3.8743019104e-07 +383 290 -87588646.48668 +384 290 16471527.78319 +385 290 13177083.33766 +386 290 -28297094.18124 +396 290 -9.983777999878e-07 +397 290 -52708333.32467 +398 290 -73187955.04869 +399 290 8.642673492432e-07 +400 290 1.788139343262e-07 +401 290 -190352899.3709 +402 290 1.475214958191e-06 +403 290 52708333.32467 +404 290 -73187955.0487 +417 290 -16471527.78319 +418 290 -13177083.33766 +419 290 -28297094.18124 +420 290 -65886111.10029 +421 290 -2.831220626831e-07 +422 290 -87588646.48668 +423 290 -16471527.78319 +424 290 13177083.33766 +425 290 -28297094.18124 +291 291 913791605.4334 +292 291 7.748603820801e-06 +293 291 -2.622604370117e-06 +294 291 126048980.7912 +295 291 -2.175569534302e-06 +296 291 -1.490116119385e-06 +309 291 -75155545.77471 +310 291 -53333333.32457 +311 291 5.066394805908e-07 +312 291 -198223262.271 +313 291 2.98023223877e-07 +314 291 5.960464477539e-08 +315 291 -75155545.7747 +316 291 53333333.32457 +317 291 -1.490116119385e-08 +381 291 -28555987.69793 +382 291 13333333.33771 +383 291 16471527.78319 +384 291 -88624220.55292 +385 291 1.043081283569e-07 +386 291 65886111.10029 +387 291 -28555987.69793 +388 291 -13333333.33771 +389 291 16471527.78319 +399 291 -7556159.747413 +400 291 -3.278255462646e-07 +401 291 -1.206994056702e-06 +402 291 72174281.7049 +403 291 1.728534698486e-06 +404 291 1.221895217896e-06 +405 291 -7556159.747413 +406 291 -7.450580596924e-07 +407 291 1.341104507446e-06 +420 291 -28555987.69793 +421 291 -13333333.33771 +422 291 -16471527.78319 +423 291 -88624220.55292 +424 291 2.235174179077e-07 +425 291 -65886111.10029 +426 291 -28555987.69793 +427 291 13333333.33771 +428 291 -16471527.78319 +292 292 785785459.402 +293 292 -1.788139343262e-06 +294 292 -2.086162567139e-06 +295 292 -76617423.53181 +296 292 5.066394805908e-07 +309 292 -53333333.32457 +310 292 -59154777.5129 +311 292 2.086162567139e-07 +312 292 3.576278686523e-07 +313 292 36444678.54407 +314 292 -4.172325134277e-07 +315 292 53333333.32457 +316 292 -59154777.5129 +317 292 2.98023223877e-08 +381 292 13333333.33771 +382 292 -24555795.63051 +383 292 -13177083.33766 +384 292 4.470348358154e-08 +385 292 -29957235.32024 +386 292 2.831220626831e-07 +387 292 -13333333.33771 +388 292 -24555795.63051 +389 292 13177083.33766 +399 292 -2.98023223877e-07 +400 292 -58222760.85313 +401 292 -52708333.32467 +402 292 1.728534698486e-06 +403 292 40172745.1813 +404 292 -5.960464477539e-08 +405 292 -7.003545761108e-07 +406 292 -58222760.85313 +407 292 52708333.32467 +420 292 -13333333.33771 +421 292 -24555795.63051 +422 292 -13177083.33766 +423 292 1.9371509552e-07 +424 292 -29957235.32024 +425 292 -3.8743019104e-07 +426 292 13333333.33771 +427 292 -24555795.63051 +428 292 13177083.33766 +293 293 905507012.9075 +294 293 -1.668930053711e-06 +295 293 4.470348358154e-07 +296 293 123977832.6588 +309 293 5.811452865601e-07 +310 293 3.129243850708e-07 +311 293 -9005963.440556 +312 293 1.192092895508e-07 +313 293 -4.768371582031e-07 +314 293 66375066.93519 +315 293 4.470348358154e-08 +316 293 -4.470348358154e-08 +317 293 -9005963.440553 +381 293 16471527.78319 +382 293 -13177083.33766 +383 293 -28297094.18124 +384 293 65886111.10029 +385 293 3.8743019104e-07 +386 293 -87588646.48668 +387 293 16471527.78319 +388 293 13177083.33766 +389 293 -28297094.18124 +399 293 -9.983777999878e-07 +400 293 -52708333.32467 +401 293 -73187955.04869 +402 293 8.642673492432e-07 +403 293 1.788139343262e-07 +404 293 -190352899.3709 +405 293 1.475214958191e-06 +406 293 52708333.32467 +407 293 -73187955.0487 +420 293 -16471527.78319 +421 293 -13177083.33766 +422 293 -28297094.18124 +423 293 -65886111.10029 +424 293 -2.831220626831e-07 +425 293 -87588646.48668 +426 293 -16471527.78319 +427 293 13177083.33766 +428 293 -28297094.18124 +294 294 913791605.4334 +295 294 7.748603820801e-06 +296 294 -2.622604370117e-06 +297 294 126048980.7912 +298 294 -2.175569534302e-06 +299 294 -1.490116119385e-06 +312 294 -75155545.77471 +313 294 -53333333.32457 +314 294 5.066394805908e-07 +315 294 -198223262.271 +316 294 2.98023223877e-07 +317 294 5.960464477539e-08 +318 294 -75155545.7747 +319 294 53333333.32457 +320 294 -1.490116119385e-08 +384 294 -28555987.69793 +385 294 13333333.33771 +386 294 16471527.78319 +387 294 -88624220.55292 +388 294 1.043081283569e-07 +389 294 65886111.10029 +390 294 -28555987.69793 +391 294 -13333333.33771 +392 294 16471527.78319 +402 294 -7556159.747413 +403 294 -3.278255462646e-07 +404 294 -1.206994056702e-06 +405 294 72174281.7049 +406 294 1.728534698486e-06 +407 294 1.221895217896e-06 +408 294 -7556159.747413 +409 294 -7.450580596924e-07 +410 294 1.341104507446e-06 +423 294 -28555987.69793 +424 294 -13333333.33771 +425 294 -16471527.78319 +426 294 -88624220.55292 +427 294 2.235174179077e-07 +428 294 -65886111.10029 +429 294 -28555987.69793 +430 294 13333333.33771 +431 294 -16471527.78319 +295 295 785785459.402 +296 295 -1.788139343262e-06 +297 295 -2.086162567139e-06 +298 295 -76617423.53181 +299 295 5.066394805908e-07 +312 295 -53333333.32457 +313 295 -59154777.5129 +314 295 2.086162567139e-07 +315 295 3.576278686523e-07 +316 295 36444678.54407 +317 295 -4.172325134277e-07 +318 295 53333333.32457 +319 295 -59154777.5129 +320 295 2.98023223877e-08 +384 295 13333333.33771 +385 295 -24555795.63051 +386 295 -13177083.33766 +387 295 4.470348358154e-08 +388 295 -29957235.32024 +389 295 2.831220626831e-07 +390 295 -13333333.33771 +391 295 -24555795.63051 +392 295 13177083.33766 +402 295 -2.98023223877e-07 +403 295 -58222760.85313 +404 295 -52708333.32467 +405 295 1.728534698486e-06 +406 295 40172745.1813 +407 295 -5.960464477539e-08 +408 295 -7.003545761108e-07 +409 295 -58222760.85313 +410 295 52708333.32467 +423 295 -13333333.33771 +424 295 -24555795.63051 +425 295 -13177083.33766 +426 295 1.9371509552e-07 +427 295 -29957235.32024 +428 295 -3.8743019104e-07 +429 295 13333333.33771 +430 295 -24555795.63051 +431 295 13177083.33766 +296 296 905507012.9075 +297 296 -1.668930053711e-06 +298 296 4.470348358154e-07 +299 296 123977832.6588 +312 296 5.811452865601e-07 +313 296 3.129243850708e-07 +314 296 -9005963.440556 +315 296 1.192092895508e-07 +316 296 -4.768371582031e-07 +317 296 66375066.93519 +318 296 4.470348358154e-08 +319 296 -4.470348358154e-08 +320 296 -9005963.440553 +384 296 16471527.78319 +385 296 -13177083.33766 +386 296 -28297094.18124 +387 296 65886111.10029 +388 296 3.8743019104e-07 +389 296 -87588646.48668 +390 296 16471527.78319 +391 296 13177083.33766 +392 296 -28297094.18124 +402 296 -9.983777999878e-07 +403 296 -52708333.32467 +404 296 -73187955.04869 +405 296 8.642673492432e-07 +406 296 1.788139343262e-07 +407 296 -190352899.3709 +408 296 1.475214958191e-06 +409 296 52708333.32467 +410 296 -73187955.0487 +423 296 -16471527.78319 +424 296 -13177083.33766 +425 296 -28297094.18124 +426 296 -65886111.10029 +427 296 -2.831220626831e-07 +428 296 -87588646.48668 +429 296 -16471527.78319 +430 296 13177083.33766 +431 296 -28297094.18124 +297 297 913791605.4334 +298 297 7.748603820801e-06 +299 297 -2.622604370117e-06 +300 297 126048980.7912 +301 297 -2.175569534302e-06 +302 297 -1.490116119385e-06 +315 297 -75155545.77471 +316 297 -53333333.32457 +317 297 5.066394805908e-07 +318 297 -198223262.271 +319 297 2.98023223877e-07 +320 297 5.960464477539e-08 +321 297 -75155545.7747 +322 297 53333333.32457 +323 297 -1.490116119385e-08 +387 297 -28555987.69793 +388 297 13333333.33771 +389 297 16471527.78319 +390 297 -88624220.55292 +391 297 1.043081283569e-07 +392 297 65886111.10029 +393 297 -28555987.69793 +394 297 -13333333.33771 +395 297 16471527.78319 +405 297 -7556159.747413 +406 297 -3.278255462646e-07 +407 297 -1.206994056702e-06 +408 297 72174281.7049 +409 297 1.728534698486e-06 +410 297 1.221895217896e-06 +411 297 -7556159.747413 +412 297 -7.450580596924e-07 +413 297 1.341104507446e-06 +426 297 -28555987.69793 +427 297 -13333333.33771 +428 297 -16471527.78319 +429 297 -88624220.55292 +430 297 2.235174179077e-07 +431 297 -65886111.10029 +432 297 -28555987.69793 +433 297 13333333.33771 +434 297 -16471527.78319 +298 298 785785459.402 +299 298 -1.788139343262e-06 +300 298 -2.086162567139e-06 +301 298 -76617423.53181 +302 298 5.066394805908e-07 +315 298 -53333333.32457 +316 298 -59154777.5129 +317 298 2.086162567139e-07 +318 298 3.576278686523e-07 +319 298 36444678.54407 +320 298 -4.172325134277e-07 +321 298 53333333.32457 +322 298 -59154777.5129 +323 298 2.98023223877e-08 +387 298 13333333.33771 +388 298 -24555795.63051 +389 298 -13177083.33766 +390 298 4.470348358154e-08 +391 298 -29957235.32024 +392 298 2.831220626831e-07 +393 298 -13333333.33771 +394 298 -24555795.63051 +395 298 13177083.33766 +405 298 -2.98023223877e-07 +406 298 -58222760.85313 +407 298 -52708333.32467 +408 298 1.728534698486e-06 +409 298 40172745.1813 +410 298 -5.960464477539e-08 +411 298 -7.003545761108e-07 +412 298 -58222760.85313 +413 298 52708333.32467 +426 298 -13333333.33771 +427 298 -24555795.63051 +428 298 -13177083.33766 +429 298 1.9371509552e-07 +430 298 -29957235.32024 +431 298 -3.8743019104e-07 +432 298 13333333.33771 +433 298 -24555795.63051 +434 298 13177083.33766 +299 299 905507012.9075 +300 299 -1.668930053711e-06 +301 299 4.470348358154e-07 +302 299 123977832.6588 +315 299 5.811452865601e-07 +316 299 3.129243850708e-07 +317 299 -9005963.440556 +318 299 1.192092895508e-07 +319 299 -4.768371582031e-07 +320 299 66375066.93519 +321 299 4.470348358154e-08 +322 299 -4.470348358154e-08 +323 299 -9005963.440553 +387 299 16471527.78319 +388 299 -13177083.33766 +389 299 -28297094.18124 +390 299 65886111.10029 +391 299 3.8743019104e-07 +392 299 -87588646.48668 +393 299 16471527.78319 +394 299 13177083.33766 +395 299 -28297094.18124 +405 299 -9.983777999878e-07 +406 299 -52708333.32467 +407 299 -73187955.04869 +408 299 8.642673492432e-07 +409 299 1.788139343262e-07 +410 299 -190352899.3709 +411 299 1.475214958191e-06 +412 299 52708333.32467 +413 299 -73187955.0487 +426 299 -16471527.78319 +427 299 -13177083.33766 +428 299 -28297094.18124 +429 299 -65886111.10029 +430 299 -2.831220626831e-07 +431 299 -87588646.48668 +432 299 -16471527.78319 +433 299 13177083.33766 +434 299 -28297094.18124 +300 300 886076107.088 +301 300 29506578.58962 +302 300 -4.172325134277e-06 +303 300 -15650105.72171 +304 300 -67995305.55008 +305 300 -1.788139343262e-06 +318 300 -75155545.77471 +319 300 -53333333.32457 +320 300 5.066394805908e-07 +321 300 -169993346.4286 +322 300 13585574.37073 +323 300 1.579523086548e-06 +324 300 -49437968.75893 +325 300 49988791.22677 +326 300 2.637505531311e-06 +390 300 -28555987.69793 +391 300 13333333.33771 +392 300 16471527.78319 +393 300 -87310926.38278 +394 300 -6271409.66235 +395 300 57161110.99975 +408 300 -7556159.747413 +409 300 -3.278255462646e-07 +410 300 -1.206994056702e-06 +411 300 87947441.63499 +412 300 7376644.65104 +413 300 0.02039501070976 +414 300 -32923131.70809 +415 300 -16998826.39589 +416 300 16470833.12799 +429 300 -28555987.69793 +430 300 -13333333.33771 +431 300 -16471527.78319 +432 300 -80272721.40676 +433 300 3396393.594356 +434 300 -61522916.65699 +435 300 -22126192.23639 +436 300 12497197.81285 +437 300 -12109027.78175 +301 301 821417136.7999 +302 301 5.125999450684e-06 +303 301 -67995305.33675 +304 301 -205861449.307 +305 301 -3.56137752533e-06 +318 301 -53333333.32457 +319 301 -59154777.5129 +320 301 2.086162567139e-07 +321 301 13585574.37073 +322 301 48420638.98572 +323 301 8.940696716309e-07 +324 301 49988791.22677 +325 301 -80270449.84323 +326 301 -2.548098564148e-06 +390 301 13333333.33771 +391 301 -24555795.63051 +392 301 -13177083.33766 +393 301 -6271409.715683 +394 301 -27822507.01778 +395 301 6197916.651945 +408 301 -2.98023223877e-07 +409 301 -58222760.85313 +410 301 -52708333.32467 +411 301 7376644.65104 +412 301 71782699.055 +413 301 0.01631674170494 +414 301 -16998826.34256 +415 301 -80475967.62785 +416 301 52708333.09468 +429 301 -13333333.33771 +430 301 -24555795.63051 +431 301 -13177083.33766 +432 301 3396393.594355 +433 301 -25669225.02627 +434 301 3489583.332416 +435 301 12497197.81285 +436 301 -29834312.51126 +437 301 16666666.67214 +302 302 843458196.4419 +303 302 1.192092895508e-07 +304 302 -3.039836883545e-06 +305 302 21637954.44543 +318 302 5.811452865601e-07 +319 302 3.129243850708e-07 +320 302 -9005963.440556 +321 302 6.85453414917e-07 +322 302 1.072883605957e-06 +323 302 73680450.86193 +324 302 1.996755599976e-06 +325 302 -2.592802047729e-06 +326 302 -7752033.245933 +390 302 16471527.78319 +391 302 -13177083.33766 +392 302 -28297094.18124 +393 302 57161110.99975 +394 302 6197916.627155 +395 302 -74255038.56586 +408 302 -9.983777999878e-07 +409 302 -52708333.32467 +410 302 -73187955.04869 +411 302 -0.02039638161659 +412 302 -0.01631587743759 +413 302 -145326344.7753 +414 302 16470833.02261 +415 302 52708333.03516 +416 302 -71952125.45461 +429 302 -16471527.78319 +430 302 -13177083.33766 +431 302 -28297094.18124 +432 302 -61522916.65613 +433 302 3489583.333104 +434 302 -82311580.01855 +435 302 -12109027.78175 +436 302 16666666.67214 +437 302 -27982541.75396 +303 303 531775095.0468 +304 303 8503382.432196 +321 303 -80370018.26376 +322 303 -52907761.3966 +323 303 -1.847743988037e-06 +324 303 -113455777.5588 +325 303 18108359.28725 +326 303 1.311302185059e-06 +327 303 68483060.18779 +328 303 -18744593.63382 +329 303 5.960464477539e-07 +330 303 -42329538.80213 +331 303 49035919.29823 +332 303 1.922249794006e-06 +393 303 -11791159.78616 +394 303 15999999.84526 +395 303 14530833.02455 +411 303 -32923131.7081 +412 303 -16998826.34256 +413 303 -16470833.02261 +414 303 14669982.03611 +415 303 2125845.609096 +416 303 12968611.10898 +432 303 -29859204.61641 +433 303 -13226940.35567 +434 303 -16470833.33874 +435 303 -76387958.09069 +436 303 4527089.824043 +437 303 -64843055.54491 +438 303 -11712307.86994 +439 303 -4686148.410764 +440 303 8424305.555742 +441 303 -24181082.63358 +442 303 12258979.8306 +443 303 -15950694.44968 +304 304 626925818.4292 +305 304 3.933906555176e-06 +321 304 -52907761.3966 +322 304 -54873071.8125 +323 304 -8.642673492432e-07 +324 304 18108359.28725 +325 304 97871879.78123 +326 304 3.337860107422e-06 +327 304 2588739.696008 +328 304 -35173186.25688 +329 304 -3.695487976074e-06 +330 304 49035919.29823 +331 304 -49698043.59219 +332 304 -1.505017280579e-06 +393 304 10666666.5635 +394 304 -19475967.87838 +395 304 -14729166.53156 +411 304 -16998826.39589 +412 304 -80475967.62786 +413 304 -52708333.03516 +414 304 2125845.609096 +415 304 38457662.89345 +416 304 3874999.888226 +432 304 -13226940.35567 +433 304 -23484968.00046 +434 304 -13177083.33766 +435 304 4527089.824043 +436 304 -23556043.72965 +437 304 3489583.332417 +438 304 647184.9243208 +439 304 -37626369.49388 +440 304 33333333.32786 +441 304 12258979.8306 +442 304 -26023208.832 +443 304 16666666.67214 +305 305 650521074.3426 +321 305 -1.788139343262e-06 +322 305 -7.748603820801e-07 +323 305 -9261489.102506 +324 305 1.117587089539e-06 +325 305 3.337860107422e-06 +326 305 131575339.2945 +327 305 1.54972076416e-06 +328 305 -3.75509262085e-06 +329 305 90632596.10001 +330 305 2.279877662659e-06 +331 305 -1.594424247742e-06 +332 305 13362532.26789 +393 305 9687222.01637 +394 305 -18604166.53816 +395 305 -23758284.67089 +411 305 -16470833.12799 +412 305 -52708333.09468 +413 305 -71952125.45462 +414 305 -12968611.10898 +415 305 -3874999.888222 +416 305 -152766509.4438 +432 305 -16470833.33874 +433 305 -13177083.33766 +434 305 -28359905.71829 +435 305 -64843055.54491 +436 305 3489583.333105 +437 305 -95170201.65885 +438 305 299305.5539342 +439 305 33333333.32786 +440 305 -54230045.43137 +441 305 -15950694.44968 +442 305 16666666.67214 +443 305 -32922561.4056 +306 306 456895802.7167 +307 306 3.933906555176e-06 +308 306 -1.668930053711e-06 +309 306 63024490.39562 +310 306 10666666.66491 +311 306 -1.013278961182e-06 +396 306 -88624220.55292 +397 306 1.043081283569e-07 +398 306 65886111.10029 +399 306 -28555987.69793 +400 306 -13333333.33771 +401 306 16471527.78319 +417 306 36087140.85245 +418 306 8.344650268555e-07 +419 306 -13177222.22006 +420 306 -3778079.873706 +421 306 2666666.667542 +422 306 -3294305.556637 +307 307 392892729.701 +308 307 -7.152557373047e-07 +309 307 -10666666.66491 +310 307 -38308711.7659 +311 307 3.8743019104e-07 +396 307 4.470348358154e-08 +397 307 -29957235.32024 +398 307 2.831220626831e-07 +399 307 -13333333.33771 +400 307 -24555795.63051 +401 307 13177083.33766 +417 307 8.940696716309e-07 +418 307 20086372.59065 +419 307 -2.98023223877e-08 +420 307 -2666666.667543 +421 307 -29111380.42657 +422 307 26354166.66234 +308 308 452753506.4538 +309 308 -8.940696716309e-07 +310 308 1.490116119385e-07 +311 308 61988916.32938 +396 308 65886111.10029 +397 308 3.8743019104e-07 +398 308 -87588646.48668 +399 308 16471527.78319 +400 308 13177083.33766 +401 308 -28297094.18124 +417 308 13177222.22006 +418 308 1.490116119385e-07 +419 308 -95176449.68545 +420 308 3294305.556638 +421 308 26354166.66234 +422 308 -36593977.52435 +309 309 456895802.7167 +310 309 3.933906555176e-06 +311 309 -1.668930053711e-06 +312 309 63024490.39562 +313 309 10666666.66491 +314 309 -1.013278961182e-06 +396 309 -28555987.69793 +397 309 13333333.33771 +398 309 16471527.78319 +399 309 -88624220.55292 +400 309 1.043081283569e-07 +401 309 65886111.10029 +402 309 -28555987.69793 +403 309 -13333333.33771 +404 309 16471527.78319 +417 309 -3778079.873706 +418 309 -2666666.667542 +419 309 -3294305.556638 +420 309 36087140.85245 +421 309 8.344650268555e-07 +422 309 -13177222.22006 +423 309 -3778079.873706 +424 309 2666666.667542 +425 309 -3294305.556637 +310 310 392892729.701 +311 310 -7.152557373047e-07 +312 310 -10666666.66491 +313 310 -38308711.7659 +314 310 3.8743019104e-07 +396 310 13333333.33771 +397 310 -24555795.63051 +398 310 -13177083.33766 +399 310 4.470348358154e-08 +400 310 -29957235.32024 +401 310 2.831220626831e-07 +402 310 -13333333.33771 +403 310 -24555795.63051 +404 310 13177083.33766 +417 310 2666666.667542 +418 310 -29111380.42657 +419 310 -26354166.66234 +420 310 8.940696716309e-07 +421 310 20086372.59065 +422 310 -2.98023223877e-08 +423 310 -2666666.667543 +424 310 -29111380.42657 +425 310 26354166.66234 +311 311 452753506.4538 +312 311 -8.940696716309e-07 +313 311 1.490116119385e-07 +314 311 61988916.32938 +396 311 16471527.78319 +397 311 -13177083.33766 +398 311 -28297094.18124 +399 311 65886111.10029 +400 311 3.8743019104e-07 +401 311 -87588646.48668 +402 311 16471527.78319 +403 311 13177083.33766 +404 311 -28297094.18124 +417 311 3294305.556637 +418 311 -26354166.66234 +419 311 -36593977.52435 +420 311 13177222.22006 +421 311 1.490116119385e-07 +422 311 -95176449.68545 +423 311 3294305.556638 +424 311 26354166.66234 +425 311 -36593977.52435 +312 312 456895802.7167 +313 312 3.933906555176e-06 +314 312 -1.668930053711e-06 +315 312 63024490.39562 +316 312 10666666.66491 +317 312 -1.013278961182e-06 +399 312 -28555987.69793 +400 312 13333333.33771 +401 312 16471527.78319 +402 312 -88624220.55292 +403 312 1.043081283569e-07 +404 312 65886111.10029 +405 312 -28555987.69793 +406 312 -13333333.33771 +407 312 16471527.78319 +420 312 -3778079.873706 +421 312 -2666666.667542 +422 312 -3294305.556638 +423 312 36087140.85245 +424 312 8.344650268555e-07 +425 312 -13177222.22006 +426 312 -3778079.873706 +427 312 2666666.667542 +428 312 -3294305.556637 +313 313 392892729.701 +314 313 -7.152557373047e-07 +315 313 -10666666.66491 +316 313 -38308711.7659 +317 313 3.8743019104e-07 +399 313 13333333.33771 +400 313 -24555795.63051 +401 313 -13177083.33766 +402 313 4.470348358154e-08 +403 313 -29957235.32024 +404 313 2.831220626831e-07 +405 313 -13333333.33771 +406 313 -24555795.63051 +407 313 13177083.33766 +420 313 2666666.667542 +421 313 -29111380.42657 +422 313 -26354166.66234 +423 313 8.940696716309e-07 +424 313 20086372.59065 +425 313 -2.98023223877e-08 +426 313 -2666666.667543 +427 313 -29111380.42657 +428 313 26354166.66234 +314 314 452753506.4538 +315 314 -8.940696716309e-07 +316 314 1.490116119385e-07 +317 314 61988916.32938 +399 314 16471527.78319 +400 314 -13177083.33766 +401 314 -28297094.18124 +402 314 65886111.10029 +403 314 3.8743019104e-07 +404 314 -87588646.48668 +405 314 16471527.78319 +406 314 13177083.33766 +407 314 -28297094.18124 +420 314 3294305.556637 +421 314 -26354166.66234 +422 314 -36593977.52435 +423 314 13177222.22006 +424 314 1.490116119385e-07 +425 314 -95176449.68545 +426 314 3294305.556638 +427 314 26354166.66234 +428 314 -36593977.52435 +315 315 456895802.7167 +316 315 3.933906555176e-06 +317 315 -1.668930053711e-06 +318 315 63024490.39562 +319 315 10666666.66491 +320 315 -1.013278961182e-06 +402 315 -28555987.69793 +403 315 13333333.33771 +404 315 16471527.78319 +405 315 -88624220.55292 +406 315 1.043081283569e-07 +407 315 65886111.10029 +408 315 -28555987.69793 +409 315 -13333333.33771 +410 315 16471527.78319 +423 315 -3778079.873706 +424 315 -2666666.667542 +425 315 -3294305.556638 +426 315 36087140.85245 +427 315 8.344650268555e-07 +428 315 -13177222.22006 +429 315 -3778079.873706 +430 315 2666666.667542 +431 315 -3294305.556637 +316 316 392892729.701 +317 316 -7.152557373047e-07 +318 316 -10666666.66491 +319 316 -38308711.7659 +320 316 3.8743019104e-07 +402 316 13333333.33771 +403 316 -24555795.63051 +404 316 -13177083.33766 +405 316 4.470348358154e-08 +406 316 -29957235.32024 +407 316 2.831220626831e-07 +408 316 -13333333.33771 +409 316 -24555795.63051 +410 316 13177083.33766 +423 316 2666666.667542 +424 316 -29111380.42657 +425 316 -26354166.66234 +426 316 8.940696716309e-07 +427 316 20086372.59065 +428 316 -2.98023223877e-08 +429 316 -2666666.667543 +430 316 -29111380.42657 +431 316 26354166.66234 +317 317 452753506.4538 +318 317 -8.940696716309e-07 +319 317 1.490116119385e-07 +320 317 61988916.32938 +402 317 16471527.78319 +403 317 -13177083.33766 +404 317 -28297094.18124 +405 317 65886111.10029 +406 317 3.8743019104e-07 +407 317 -87588646.48668 +408 317 16471527.78319 +409 317 13177083.33766 +410 317 -28297094.18124 +423 317 3294305.556637 +424 317 -26354166.66234 +425 317 -36593977.52435 +426 317 13177222.22006 +427 317 1.490116119385e-07 +428 317 -95176449.68545 +429 317 3294305.556638 +430 317 26354166.66234 +431 317 -36593977.52435 +318 318 456895802.7167 +319 318 3.933906555176e-06 +320 318 -1.668930053711e-06 +321 318 63024490.39562 +322 318 10666666.66491 +323 318 -1.013278961182e-06 +405 318 -28555987.69793 +406 318 13333333.33771 +407 318 16471527.78319 +408 318 -88624220.55292 +409 318 1.043081283569e-07 +410 318 65886111.10029 +411 318 -28555987.69793 +412 318 -13333333.33771 +413 318 16471527.78319 +426 318 -3778079.873706 +427 318 -2666666.667542 +428 318 -3294305.556638 +429 318 36087140.85245 +430 318 8.344650268555e-07 +431 318 -13177222.22006 +432 318 -3778079.873706 +433 318 2666666.667542 +434 318 -3294305.556637 +319 319 392892729.701 +320 319 -7.152557373047e-07 +321 319 -10666666.66491 +322 319 -38308711.7659 +323 319 3.8743019104e-07 +405 319 13333333.33771 +406 319 -24555795.63051 +407 319 -13177083.33766 +408 319 4.470348358154e-08 +409 319 -29957235.32024 +410 319 2.831220626831e-07 +411 319 -13333333.33771 +412 319 -24555795.63051 +413 319 13177083.33766 +426 319 2666666.667542 +427 319 -29111380.42657 +428 319 -26354166.66234 +429 319 8.940696716309e-07 +430 319 20086372.59065 +431 319 -2.98023223877e-08 +432 319 -2666666.667543 +433 319 -29111380.42657 +434 319 26354166.66234 +320 320 452753506.4538 +321 320 -8.940696716309e-07 +322 320 1.490116119385e-07 +323 320 61988916.32938 +405 320 16471527.78319 +406 320 -13177083.33766 +407 320 -28297094.18124 +408 320 65886111.10029 +409 320 3.8743019104e-07 +410 320 -87588646.48668 +411 320 16471527.78319 +412 320 13177083.33766 +413 320 -28297094.18124 +426 320 3294305.556637 +427 320 -26354166.66234 +428 320 -36593977.52435 +429 320 13177222.22006 +430 320 1.490116119385e-07 +431 320 -95176449.68545 +432 320 3294305.556638 +433 320 26354166.66234 +434 320 -36593977.52435 +321 321 451672659.2548 +322 321 425457.3069872 +324 321 45227333.73336 +325 321 -3769936.940774 +326 321 5.960464477539e-07 +408 321 -28555987.69793 +409 321 13333333.33771 +410 321 16471527.78319 +411 321 -80272721.40676 +412 321 3396393.594356 +413 321 61522916.65613 +414 321 -29859204.61641 +415 321 -13226940.35567 +416 321 16470833.33874 +429 321 -3778079.873706 +430 321 -2666666.667542 +431 321 -3294305.556638 +432 321 34782980.96289 +433 321 106364.3267991 +434 321 -13176944.44228 +435 321 -9519773.826407 +436 321 -942484.2356579 +437 321 1067638.88752 +322 322 397175038.8898 +323 322 1.072883605957e-06 +324 322 -25103270.2706 +325 322 -58853543.86754 +326 322 -1.341104507446e-06 +408 322 13333333.33771 +409 322 -24555795.63051 +410 322 -13177083.33766 +411 322 3396393.594355 +412 322 -25669225.02627 +413 322 -3489583.333104 +414 322 -13226940.35567 +415 322 -23484968.00045 +416 322 13177083.33766 +429 322 2666666.667542 +430 322 -29111380.42657 +431 322 -26354166.66234 +432 322 106364.3267991 +433 322 21158575.86493 +434 322 2.682209014893e-07 +435 322 -6275817.570742 +436 322 -35539993.23945 +437 322 29843749.99544 +323 323 452492316.5668 +325 323 -1.490116119385e-06 +326 323 55187296.56271 +408 323 16471527.78319 +409 323 -13177083.33766 +410 323 -28297094.18124 +411 323 61522916.65699 +412 323 -3489583.332416 +413 323 -82311580.01855 +414 323 16470833.33874 +415 323 13177083.33766 +416 323 -28359905.71829 +429 323 3294305.556637 +430 323 -26354166.66234 +431 323 -36593977.52435 +432 323 13176944.44228 +433 323 3.8743019104e-07 +434 323 -95237411.21973 +435 323 7655972.222158 +436 323 29843749.99475 +437 323 -41740795.2267 +324 324 444644489.1745 +325 324 13081929.57058 +326 324 9.536743164063e-07 +327 324 -86994427.68368 +328 324 -57630747.35091 +329 324 -2.384185791016e-06 +330 324 44204118.01812 +331 324 1554937.536914 +332 324 -1.192092895508e-06 +411 324 -22126192.23639 +412 324 12497197.81285 +413 324 12109027.78176 +414 324 -76387958.09069 +415 324 4527089.824043 +416 324 64843055.54491 +432 324 -9519773.826409 +433 324 -6275817.570743 +434 324 -7655972.222158 +435 324 15798034.7999 +436 324 3270482.394257 +437 324 -12968611.10898 +438 324 -35347304.85947 +439 324 -14407686.84483 +440 324 20312500.00667 +441 324 -14510689.24923 +442 324 388734.3844201 +443 324 1171666.664472 +325 325 449754245.7917 +326 325 4.64916229248e-06 +327 325 -57630747.35091 +328 325 -66447376.92277 +329 325 -1.296401023865e-06 +330 325 -19778395.79291 +331 325 -57866988.0148 +332 325 -2.086162567139e-06 +411 325 12497197.81285 +412 325 -29834312.51127 +413 325 -16666666.67214 +414 325 4527089.824043 +415 325 -23556043.72965 +416 325 -3489583.333103 +432 325 -942484.2356579 +433 325 -35539993.23945 +434 325 -29843749.99475 +435 325 3270482.394257 +436 325 17075473.95481 +437 325 9.536743164063e-07 +438 325 -14407686.84483 +439 325 -30210542.16671 +440 325 16666666.67214 +441 325 -4944598.950664 +442 325 -40028465.77003 +443 325 33333333.32786 +326 326 513640710.6392 +327 326 -3.159046173096e-06 +328 326 -1.370906829834e-06 +329 326 -3386801.062691 +330 326 -1.907348632813e-06 +331 326 -2.235174179077e-06 +332 326 68569532.94435 +411 326 12109027.78176 +412 326 -16666666.67214 +413 326 -27982541.75396 +414 326 64843055.54491 +415 326 -3489583.332416 +416 326 -95170201.65886 +432 326 -1067638.887521 +433 326 -29843749.99544 +434 326 -41740795.22671 +435 326 12968611.10898 +436 326 1.013278961182e-06 +437 326 -125891389.0729 +438 326 20312500.00667 +439 326 16666666.67214 +440 326 -37109894.74031 +441 326 7551944.445205 +442 326 33333333.32786 +443 326 -51022200.11333 +327 327 254849231.4225 +328 327 61411260.29348 +329 327 3.814697265625e-06 +330 327 -66610780.59762 +331 327 -6369252.63857 +332 327 -1.132488250732e-06 +414 327 -11712307.86995 +415 327 647184.9243208 +416 327 -299305.5539346 +435 327 -35347304.85947 +436 327 -14407686.84483 +437 327 -20312500.00667 +438 327 6046162.064774 +439 327 15352815.08093 +440 327 8124999.998666 +441 327 -43850090.99987 +442 327 -1592313.160427 +443 327 -36263194.43806 +328 328 228505477.8886 +329 328 4.172325134277e-06 +330 328 14964080.69126 +331 328 42842168.62011 +332 328 1.728534698486e-06 +414 328 -4686148.410764 +415 328 -37626369.49388 +416 328 -33333333.32786 +435 328 -14407686.84483 +436 328 -30210542.16671 +437 328 -16666666.67214 +438 328 15352815.08093 +439 328 -539776.3219635 +440 328 6666666.665572 +441 328 3741020.174657 +442 328 -16486853.68196 +443 328 3333333.334428 +329 329 294920181.6058 +331 329 1.788139343262e-06 +332 329 70439578.90092 +414 329 -8424305.555743 +415 329 -33333333.32786 +416 329 -54230045.43139 +435 329 -20312500.00667 +436 329 -16666666.67214 +437 329 -37109894.74031 +438 329 -8124999.998665 +439 329 -6666666.665571 +440 329 -80046343.42155 +441 329 -36263194.43892 +442 329 -3333333.334428 +443 329 -54916494.1788 +330 330 221377868.0526 +331 330 -44221604.19657 +332 330 -1.311302185059e-06 +414 330 -24181082.63358 +415 330 12258979.8306 +416 330 15950694.44968 +435 330 -14510689.24923 +436 330 -4944598.950664 +437 330 -7551944.445206 +438 330 -43850090.99987 +439 330 3741020.174657 +440 330 36263194.43892 +441 330 4221029.5472 +442 330 -11055401.05459 +443 330 -6380277.77673 +331 331 221364529.6578 +332 331 2.861022949219e-06 +414 331 12258979.8306 +415 331 -26023208.832 +416 331 -16666666.67214 +435 331 388734.38442 +436 331 -40028465.77003 +437 331 -33333333.32786 +438 331 -1592313.160427 +439 331 -16486853.68196 +440 331 3333333.334428 +441 331 -11055401.05459 +442 331 4217694.948508 +443 331 6666666.665572 +332 332 265339467.0094 +414 332 15950694.44968 +415 332 -16666666.67214 +416 332 -32922561.4056 +435 332 -1171666.664473 +436 332 -33333333.32786 +437 332 -51022200.11334 +438 332 36263194.43806 +439 332 -3333333.334428 +440 332 -54916494.1788 +441 332 6380277.77673 +442 332 -6666666.665571 +443 332 -69994299.86354 +333 333 571119749.839 +334 333 53333333.32457 +335 333 -6.198883056641e-06 +336 333 -292913008.3249 +337 333 -53333332.8979 +338 333 6.556510925293e-06 +339 333 19534202.10867 +340 333 42666666.23299 +341 333 -1.490116119385e-06 +444 333 45108925.89256 +445 333 13333333.33771 +446 333 13177222.19231 +447 333 -107413106.5112 +448 333 -13333333.23104 +449 333 -65886110.96157 +450 333 -9767101.054335 +451 333 10666666.5635 +452 333 -13177221.94221 +334 334 491115909.0416 +335 334 -3.094097220493e-06 +336 334 -53333332.68457 +337 334 -42244300.58137 +338 334 2.145767211914e-06 +339 334 63999999.34949 +340 334 19534202.10866 +341 334 -2.384185791016e-06 +444 334 13333333.33771 +445 334 25107965.68335 +446 334 10541666.55379 +447 334 -13333333.17771 +448 334 -44745929.54446 +449 334 -13177083.26329 +450 334 15999999.84525 +451 334 -9767101.054335 +452 334 15812499.93082 +335 335 565941879.2302 +336 335 6.943941116333e-06 +337 335 1.609325408936e-06 +338 335 5277897.861165 +339 335 -2.145767211914e-06 +340 335 -1.54972076416e-06 +341 335 52091205.62311 +444 335 -13177222.19232 +445 335 -10541666.5538 +446 335 -118970561.1562 +447 335 -65886110.96157 +448 335 -13177083.28808 +449 335 -89840137.25117 +450 335 -19765832.91331 +451 335 10541666.62055 +452 335 -26045602.81156 +336 336 988947148.5376 +337 336 53333332.25791 +338 336 -9.298324584961e-06 +339 336 31359232.67644 +340 336 -53333332.8979 +341 336 1.251697540283e-06 +342 336 -198223262.271 +343 336 2.98023223877e-07 +344 336 5.960464477539e-08 +345 336 -75155545.7747 +346 336 53333333.32457 +347 336 -1.490116119385e-08 +444 336 -107413106.5112 +445 336 -13333333.17771 +446 336 65886110.96157 +447 336 100730268.7541 +448 336 13333333.07105 +449 336 0.02774140238762 +450 336 -26345045.89131 +451 336 -13333333.23105 +452 336 16471527.49884 +453 336 -88624220.55292 +454 336 2.235174179077e-07 +455 336 -65886111.10029 +456 336 -28555987.69793 +457 336 13333333.33771 +458 336 -16471527.78319 +337 337 844940234.7245 +338 337 -7.987022399902e-06 +339 337 -53333332.68457 +340 337 -155306402.5315 +341 337 5.394220352173e-06 +342 337 3.576278686523e-07 +343 337 36444678.54407 +344 337 -4.172325134277e-07 +345 337 53333333.32457 +346 337 -59154777.5129 +347 337 2.98023223877e-08 +444 337 -13333333.23104 +445 337 -44745929.54447 +446 337 13177083.28808 +447 337 13333333.07105 +448 337 64728540.28304 +449 337 0.022192299366 +450 337 -13333333.17771 +451 337 -73011454.71628 +452 337 52708333.03581 +453 337 1.9371509552e-07 +454 337 -29957235.32024 +455 337 -3.8743019104e-07 +456 337 13333333.33771 +457 337 -24555795.63051 +458 337 13177083.33766 +338 338 914512974.9691 +339 338 1.728534698486e-06 +340 338 4.559755325317e-06 +341 338 62880662.12465 +342 338 1.192092895508e-07 +343 338 -4.768371582031e-07 +344 338 66375066.93519 +345 338 4.470348358154e-08 +346 338 -4.470348358154e-08 +347 338 -9005963.440553 +444 338 65886110.96157 +445 338 13177083.26329 +446 338 -89840137.25118 +447 338 -0.0277450978756 +448 338 -0.02219566702843 +449 338 -162055805.4842 +450 338 16471527.35667 +451 338 52708332.94687 +452 338 -75439445.29918 +453 338 -65886111.10029 +454 338 -2.831220626831e-07 +455 338 -87588646.48668 +456 338 -16471527.78319 +457 338 13177083.33766 +458 338 -28297094.18124 +339 339 571119749.839 +340 339 53333333.32457 +341 339 -6.198883056641e-06 +342 339 -75155545.77471 +343 339 -53333333.32457 +344 339 5.066394805908e-07 +345 339 -292913008.3249 +346 339 -53333332.8979 +347 339 6.556510925293e-06 +348 339 19534202.10867 +349 339 42666666.23299 +350 339 -1.490116119385e-06 +444 339 -9767101.054335 +445 339 15999999.84525 +446 339 19765832.91331 +447 339 -26345045.8913 +448 339 -13333333.17771 +449 339 -16471527.35667 +450 339 45108925.89256 +451 339 13333333.33771 +452 339 13177222.19231 +453 339 -28555987.69793 +454 339 -13333333.33771 +455 339 -16471527.78319 +456 339 -107413106.5112 +457 339 -13333333.23104 +458 339 -65886110.96157 +459 339 -9767101.054335 +460 339 10666666.5635 +461 339 -13177221.94221 +340 340 491115909.0416 +341 340 -2.974887930942e-06 +342 340 -53333333.32457 +343 340 -59154777.5129 +344 340 2.086162567139e-07 +345 340 -53333332.68457 +346 340 -42244300.58137 +347 340 2.145767211914e-06 +348 340 63999999.34949 +349 340 19534202.10866 +350 340 -2.384185791016e-06 +444 340 10666666.5635 +445 340 -9767101.054336 +446 340 -10541666.62055 +447 340 -13333333.23105 +448 340 -73011454.71627 +449 340 -52708332.94687 +450 340 13333333.33771 +451 340 25107965.68335 +452 340 10541666.55379 +453 340 -13333333.33771 +454 340 -24555795.63051 +455 340 -13177083.33766 +456 340 -13333333.17771 +457 340 -44745929.54446 +458 340 -13177083.26329 +459 340 15999999.84525 +460 340 -9767101.054335 +461 340 15812499.93082 +341 341 565941879.2302 +342 341 5.811452865601e-07 +343 341 3.129243850708e-07 +344 341 -9005963.440556 +345 341 6.943941116333e-06 +346 341 1.609325408936e-06 +347 341 5277897.861165 +348 341 -2.145767211914e-06 +349 341 -1.54972076416e-06 +350 341 52091205.62311 +444 341 13177221.94221 +445 341 -15812499.93082 +446 341 -26045602.81156 +447 341 -16471527.49884 +448 341 -52708333.03581 +449 341 -75439445.29917 +450 341 -13177222.19232 +451 341 -10541666.5538 +452 341 -118970561.1562 +453 341 -16471527.78319 +454 341 -13177083.33766 +455 341 -28297094.18124 +456 341 -65886110.96157 +457 341 -13177083.28808 +458 341 -89840137.25117 +459 341 -19765832.91331 +460 341 10541666.62055 +461 341 -26045602.81156 +342 342 913791605.4334 +343 342 7.748603820801e-06 +344 342 -2.622604370117e-06 +345 342 126048980.7912 +346 342 -2.175569534302e-06 +347 342 -1.490116119385e-06 +351 342 -198223262.271 +352 342 2.98023223877e-07 +353 342 5.960464477539e-08 +354 342 -75155545.7747 +355 342 53333333.32457 +356 342 -1.490116119385e-08 +447 342 -88624220.55292 +448 342 1.043081283569e-07 +449 342 65886111.10029 +450 342 -28555987.69793 +451 342 -13333333.33771 +452 342 16471527.78319 +453 342 72174281.7049 +454 342 1.728534698486e-06 +455 342 1.221895217896e-06 +456 342 -7556159.747413 +457 342 -7.450580596924e-07 +458 342 1.341104507446e-06 +462 342 -88624220.55292 +463 342 2.235174179077e-07 +464 342 -65886111.10029 +465 342 -28555987.69793 +466 342 13333333.33771 +467 342 -16471527.78319 +343 343 785785459.402 +344 343 -1.788139343262e-06 +345 343 -2.086162567139e-06 +346 343 -76617423.53181 +347 343 5.066394805908e-07 +351 343 3.576278686523e-07 +352 343 36444678.54407 +353 343 -4.172325134277e-07 +354 343 53333333.32457 +355 343 -59154777.5129 +356 343 2.98023223877e-08 +447 343 4.470348358154e-08 +448 343 -29957235.32024 +449 343 2.831220626831e-07 +450 343 -13333333.33771 +451 343 -24555795.63051 +452 343 13177083.33766 +453 343 1.728534698486e-06 +454 343 40172745.1813 +455 343 -5.960464477539e-08 +456 343 -7.003545761108e-07 +457 343 -58222760.85313 +458 343 52708333.32467 +462 343 1.9371509552e-07 +463 343 -29957235.32024 +464 343 -3.8743019104e-07 +465 343 13333333.33771 +466 343 -24555795.63051 +467 343 13177083.33766 +344 344 905507012.9075 +345 344 -1.668930053711e-06 +346 344 4.470348358154e-07 +347 344 123977832.6588 +351 344 1.192092895508e-07 +352 344 -4.768371582031e-07 +353 344 66375066.93519 +354 344 4.470348358154e-08 +355 344 -4.470348358154e-08 +356 344 -9005963.440553 +447 344 65886111.10029 +448 344 3.8743019104e-07 +449 344 -87588646.48668 +450 344 16471527.78319 +451 344 13177083.33766 +452 344 -28297094.18124 +453 344 8.642673492432e-07 +454 344 1.788139343262e-07 +455 344 -190352899.3709 +456 344 1.475214958191e-06 +457 344 52708333.32467 +458 344 -73187955.0487 +462 344 -65886111.10029 +463 344 -2.831220626831e-07 +464 344 -87588646.48668 +465 344 -16471527.78319 +466 344 13177083.33766 +467 344 -28297094.18124 +345 345 988947148.5376 +346 345 53333332.25791 +347 345 -9.298324584961e-06 +348 345 31359232.67644 +349 345 -53333332.8979 +350 345 1.251697540283e-06 +351 345 -75155545.77471 +352 345 -53333333.32457 +353 345 5.066394805908e-07 +354 345 -198223262.271 +355 345 2.98023223877e-07 +356 345 5.960464477539e-08 +357 345 -75155545.7747 +358 345 53333333.32457 +359 345 -1.490116119385e-08 +447 345 -28555987.69793 +448 345 13333333.33771 +449 345 16471527.78319 +450 345 -107413106.5112 +451 345 -13333333.17771 +452 345 65886110.96157 +453 345 -7556159.747413 +454 345 -3.278255462646e-07 +455 345 -1.206994056702e-06 +456 345 100730268.7541 +457 345 13333333.07105 +458 345 0.02774140238762 +459 345 -26345045.89131 +460 345 -13333333.23105 +461 345 16471527.49884 +462 345 -28555987.69793 +463 345 -13333333.33771 +464 345 -16471527.78319 +465 345 -88624220.55292 +466 345 2.235174179077e-07 +467 345 -65886111.10029 +468 345 -28555987.69793 +469 345 13333333.33771 +470 345 -16471527.78319 +346 346 844940234.7245 +347 346 -7.987022399902e-06 +348 346 -53333332.68457 +349 346 -155306402.5315 +350 346 5.394220352173e-06 +351 346 -53333333.32457 +352 346 -59154777.5129 +353 346 2.086162567139e-07 +354 346 3.576278686523e-07 +355 346 36444678.54407 +356 346 -4.172325134277e-07 +357 346 53333333.32457 +358 346 -59154777.5129 +359 346 2.98023223877e-08 +447 346 13333333.33771 +448 346 -24555795.63051 +449 346 -13177083.33766 +450 346 -13333333.23104 +451 346 -44745929.54447 +452 346 13177083.28808 +453 346 -2.98023223877e-07 +454 346 -58222760.85313 +455 346 -52708333.32467 +456 346 13333333.07105 +457 346 64728540.28304 +458 346 0.022192299366 +459 346 -13333333.17771 +460 346 -73011454.71628 +461 346 52708333.03581 +462 346 -13333333.33771 +463 346 -24555795.63051 +464 346 -13177083.33766 +465 346 1.9371509552e-07 +466 346 -29957235.32024 +467 346 -3.8743019104e-07 +468 346 13333333.33771 +469 346 -24555795.63051 +470 346 13177083.33766 +347 347 914512974.9691 +348 347 1.728534698486e-06 +349 347 4.559755325317e-06 +350 347 62880662.12465 +351 347 5.811452865601e-07 +352 347 3.129243850708e-07 +353 347 -9005963.440556 +354 347 1.192092895508e-07 +355 347 -4.768371582031e-07 +356 347 66375066.93519 +357 347 4.470348358154e-08 +358 347 -4.470348358154e-08 +359 347 -9005963.440553 +447 347 16471527.78319 +448 347 -13177083.33766 +449 347 -28297094.18124 +450 347 65886110.96157 +451 347 13177083.26329 +452 347 -89840137.25118 +453 347 -9.983777999878e-07 +454 347 -52708333.32467 +455 347 -73187955.04869 +456 347 -0.0277450978756 +457 347 -0.02219566702843 +458 347 -162055805.4842 +459 347 16471527.35667 +460 347 52708332.94687 +461 347 -75439445.29918 +462 347 -16471527.78319 +463 347 -13177083.33766 +464 347 -28297094.18124 +465 347 -65886111.10029 +466 347 -2.831220626831e-07 +467 347 -87588646.48668 +468 347 -16471527.78319 +469 347 13177083.33766 +470 347 -28297094.18124 +348 348 571119749.839 +349 348 53333333.32457 +350 348 -6.198883056641e-06 +354 348 -75155545.77471 +355 348 -53333333.32457 +356 348 5.066394805908e-07 +357 348 -292913008.3249 +358 348 -53333332.8979 +359 348 6.556510925293e-06 +360 348 19534202.10867 +361 348 42666666.23299 +362 348 -1.490116119385e-06 +450 348 -9767101.054335 +451 348 15999999.84525 +452 348 19765832.91331 +456 348 -26345045.8913 +457 348 -13333333.17771 +458 348 -16471527.35667 +459 348 45108925.89256 +460 348 13333333.33771 +461 348 13177222.19231 +465 348 -28555987.69793 +466 348 -13333333.33771 +467 348 -16471527.78319 +468 348 -107413106.5112 +469 348 -13333333.23104 +470 348 -65886110.96157 +471 348 -9767101.054335 +472 348 10666666.5635 +473 348 -13177221.94221 +349 349 491115909.0416 +350 349 -2.974887930942e-06 +354 349 -53333333.32457 +355 349 -59154777.5129 +356 349 2.086162567139e-07 +357 349 -53333332.68457 +358 349 -42244300.58137 +359 349 2.145767211914e-06 +360 349 63999999.34949 +361 349 19534202.10866 +362 349 -2.384185791016e-06 +450 349 10666666.5635 +451 349 -9767101.054336 +452 349 -10541666.62055 +456 349 -13333333.23105 +457 349 -73011454.71627 +458 349 -52708332.94687 +459 349 13333333.33771 +460 349 25107965.68335 +461 349 10541666.55379 +465 349 -13333333.33771 +466 349 -24555795.63051 +467 349 -13177083.33766 +468 349 -13333333.17771 +469 349 -44745929.54446 +470 349 -13177083.26329 +471 349 15999999.84525 +472 349 -9767101.054335 +473 349 15812499.93082 +350 350 565941879.2302 +354 350 5.811452865601e-07 +355 350 3.129243850708e-07 +356 350 -9005963.440556 +357 350 6.943941116333e-06 +358 350 1.609325408936e-06 +359 350 5277897.861165 +360 350 -2.145767211914e-06 +361 350 -1.54972076416e-06 +362 350 52091205.62311 +450 350 13177221.94221 +451 350 -15812499.93082 +452 350 -26045602.81156 +456 350 -16471527.49884 +457 350 -52708333.03581 +458 350 -75439445.29917 +459 350 -13177222.19232 +460 350 -10541666.5538 +461 350 -118970561.1562 +465 350 -16471527.78319 +466 350 -13177083.33766 +467 350 -28297094.18124 +468 350 -65886110.96157 +469 350 -13177083.28808 +470 350 -89840137.25117 +471 350 -19765832.91331 +472 350 10541666.62055 +473 350 -26045602.81156 +351 351 913791605.4334 +352 351 7.748603820801e-06 +353 351 -2.622604370117e-06 +354 351 126048980.7912 +355 351 -2.175569534302e-06 +356 351 -1.490116119385e-06 +363 351 -198223262.271 +364 351 2.98023223877e-07 +365 351 5.960464477539e-08 +366 351 -75155545.7747 +367 351 53333333.32457 +368 351 -1.490116119385e-08 +453 351 -88624220.55292 +454 351 1.043081283569e-07 +455 351 65886111.10029 +456 351 -28555987.69793 +457 351 -13333333.33771 +458 351 16471527.78319 +462 351 72174281.7049 +463 351 1.728534698486e-06 +464 351 1.221895217896e-06 +465 351 -7556159.747413 +466 351 -7.450580596924e-07 +467 351 1.341104507446e-06 +474 351 -88624220.55292 +475 351 2.235174179077e-07 +476 351 -65886111.10029 +477 351 -28555987.69793 +478 351 13333333.33771 +479 351 -16471527.78319 +352 352 785785459.402 +353 352 -1.788139343262e-06 +354 352 -2.086162567139e-06 +355 352 -76617423.53181 +356 352 5.066394805908e-07 +363 352 3.576278686523e-07 +364 352 36444678.54407 +365 352 -4.172325134277e-07 +366 352 53333333.32457 +367 352 -59154777.5129 +368 352 2.98023223877e-08 +453 352 4.470348358154e-08 +454 352 -29957235.32024 +455 352 2.831220626831e-07 +456 352 -13333333.33771 +457 352 -24555795.63051 +458 352 13177083.33766 +462 352 1.728534698486e-06 +463 352 40172745.1813 +464 352 -5.960464477539e-08 +465 352 -7.003545761108e-07 +466 352 -58222760.85313 +467 352 52708333.32467 +474 352 1.9371509552e-07 +475 352 -29957235.32024 +476 352 -3.8743019104e-07 +477 352 13333333.33771 +478 352 -24555795.63051 +479 352 13177083.33766 +353 353 905507012.9075 +354 353 -1.668930053711e-06 +355 353 4.470348358154e-07 +356 353 123977832.6588 +363 353 1.192092895508e-07 +364 353 -4.768371582031e-07 +365 353 66375066.93519 +366 353 4.470348358154e-08 +367 353 -4.470348358154e-08 +368 353 -9005963.440553 +453 353 65886111.10029 +454 353 3.8743019104e-07 +455 353 -87588646.48668 +456 353 16471527.78319 +457 353 13177083.33766 +458 353 -28297094.18124 +462 353 8.642673492432e-07 +463 353 1.788139343262e-07 +464 353 -190352899.3709 +465 353 1.475214958191e-06 +466 353 52708333.32467 +467 353 -73187955.0487 +474 353 -65886111.10029 +475 353 -2.831220626831e-07 +476 353 -87588646.48668 +477 353 -16471527.78319 +478 353 13177083.33766 +479 353 -28297094.18124 +354 354 913791605.4334 +355 354 7.748603820801e-06 +356 354 -2.622604370117e-06 +357 354 126048980.7912 +358 354 -2.175569534302e-06 +359 354 -1.490116119385e-06 +363 354 -75155545.77471 +364 354 -53333333.32457 +365 354 5.066394805908e-07 +366 354 -198223262.271 +367 354 2.98023223877e-07 +368 354 5.960464477539e-08 +369 354 -75155545.7747 +370 354 53333333.32457 +371 354 -1.490116119385e-08 +453 354 -28555987.69793 +454 354 13333333.33771 +455 354 16471527.78319 +456 354 -88624220.55292 +457 354 1.043081283569e-07 +458 354 65886111.10029 +459 354 -28555987.69793 +460 354 -13333333.33771 +461 354 16471527.78319 +462 354 -7556159.747413 +463 354 -3.278255462646e-07 +464 354 -1.206994056702e-06 +465 354 72174281.7049 +466 354 1.728534698486e-06 +467 354 1.221895217896e-06 +468 354 -7556159.747413 +469 354 -7.450580596924e-07 +470 354 1.341104507446e-06 +474 354 -28555987.69793 +475 354 -13333333.33771 +476 354 -16471527.78319 +477 354 -88624220.55292 +478 354 2.235174179077e-07 +479 354 -65886111.10029 +480 354 -28555987.69793 +481 354 13333333.33771 +482 354 -16471527.78319 +355 355 785785459.402 +356 355 -1.788139343262e-06 +357 355 -2.086162567139e-06 +358 355 -76617423.53181 +359 355 5.066394805908e-07 +363 355 -53333333.32457 +364 355 -59154777.5129 +365 355 2.086162567139e-07 +366 355 3.576278686523e-07 +367 355 36444678.54407 +368 355 -4.172325134277e-07 +369 355 53333333.32457 +370 355 -59154777.5129 +371 355 2.98023223877e-08 +453 355 13333333.33771 +454 355 -24555795.63051 +455 355 -13177083.33766 +456 355 4.470348358154e-08 +457 355 -29957235.32024 +458 355 2.831220626831e-07 +459 355 -13333333.33771 +460 355 -24555795.63051 +461 355 13177083.33766 +462 355 -2.98023223877e-07 +463 355 -58222760.85313 +464 355 -52708333.32467 +465 355 1.728534698486e-06 +466 355 40172745.1813 +467 355 -5.960464477539e-08 +468 355 -7.003545761108e-07 +469 355 -58222760.85313 +470 355 52708333.32467 +474 355 -13333333.33771 +475 355 -24555795.63051 +476 355 -13177083.33766 +477 355 1.9371509552e-07 +478 355 -29957235.32024 +479 355 -3.8743019104e-07 +480 355 13333333.33771 +481 355 -24555795.63051 +482 355 13177083.33766 +356 356 905507012.9075 +357 356 -1.668930053711e-06 +358 356 4.470348358154e-07 +359 356 123977832.6588 +363 356 5.811452865601e-07 +364 356 3.129243850708e-07 +365 356 -9005963.440556 +366 356 1.192092895508e-07 +367 356 -4.768371582031e-07 +368 356 66375066.93519 +369 356 4.470348358154e-08 +370 356 -4.470348358154e-08 +371 356 -9005963.440553 +453 356 16471527.78319 +454 356 -13177083.33766 +455 356 -28297094.18124 +456 356 65886111.10029 +457 356 3.8743019104e-07 +458 356 -87588646.48668 +459 356 16471527.78319 +460 356 13177083.33766 +461 356 -28297094.18124 +462 356 -9.983777999878e-07 +463 356 -52708333.32467 +464 356 -73187955.04869 +465 356 8.642673492432e-07 +466 356 1.788139343262e-07 +467 356 -190352899.3709 +468 356 1.475214958191e-06 +469 356 52708333.32467 +470 356 -73187955.0487 +474 356 -16471527.78319 +475 356 -13177083.33766 +476 356 -28297094.18124 +477 356 -65886111.10029 +478 356 -2.831220626831e-07 +479 356 -87588646.48668 +480 356 -16471527.78319 +481 356 13177083.33766 +482 356 -28297094.18124 +357 357 988947148.5376 +358 357 53333332.25791 +359 357 -9.298324584961e-06 +360 357 31359232.67644 +361 357 -53333332.8979 +362 357 1.251697540283e-06 +366 357 -75155545.77471 +367 357 -53333333.32457 +368 357 5.066394805908e-07 +369 357 -198223262.271 +370 357 2.98023223877e-07 +371 357 5.960464477539e-08 +372 357 -75155545.7747 +373 357 53333333.32457 +374 357 -1.490116119385e-08 +456 357 -28555987.69793 +457 357 13333333.33771 +458 357 16471527.78319 +459 357 -107413106.5112 +460 357 -13333333.17771 +461 357 65886110.96157 +465 357 -7556159.747413 +466 357 -3.278255462646e-07 +467 357 -1.206994056702e-06 +468 357 100730268.7541 +469 357 13333333.07105 +470 357 0.02774140238762 +471 357 -26345045.89131 +472 357 -13333333.23105 +473 357 16471527.49884 +477 357 -28555987.69793 +478 357 -13333333.33771 +479 357 -16471527.78319 +480 357 -88624220.55292 +481 357 2.235174179077e-07 +482 357 -65886111.10029 +483 357 -28555987.69793 +484 357 13333333.33771 +485 357 -16471527.78319 +358 358 844940234.7245 +359 358 -7.987022399902e-06 +360 358 -53333332.68457 +361 358 -155306402.5315 +362 358 5.394220352173e-06 +366 358 -53333333.32457 +367 358 -59154777.5129 +368 358 2.086162567139e-07 +369 358 3.576278686523e-07 +370 358 36444678.54407 +371 358 -4.172325134277e-07 +372 358 53333333.32457 +373 358 -59154777.5129 +374 358 2.98023223877e-08 +456 358 13333333.33771 +457 358 -24555795.63051 +458 358 -13177083.33766 +459 358 -13333333.23104 +460 358 -44745929.54447 +461 358 13177083.28808 +465 358 -2.98023223877e-07 +466 358 -58222760.85313 +467 358 -52708333.32467 +468 358 13333333.07105 +469 358 64728540.28304 +470 358 0.022192299366 +471 358 -13333333.17771 +472 358 -73011454.71628 +473 358 52708333.03581 +477 358 -13333333.33771 +478 358 -24555795.63051 +479 358 -13177083.33766 +480 358 1.9371509552e-07 +481 358 -29957235.32024 +482 358 -3.8743019104e-07 +483 358 13333333.33771 +484 358 -24555795.63051 +485 358 13177083.33766 +359 359 914512974.9691 +360 359 1.728534698486e-06 +361 359 4.559755325317e-06 +362 359 62880662.12465 +366 359 5.811452865601e-07 +367 359 3.129243850708e-07 +368 359 -9005963.440556 +369 359 1.192092895508e-07 +370 359 -4.768371582031e-07 +371 359 66375066.93519 +372 359 4.470348358154e-08 +373 359 -4.470348358154e-08 +374 359 -9005963.440553 +456 359 16471527.78319 +457 359 -13177083.33766 +458 359 -28297094.18124 +459 359 65886110.96157 +460 359 13177083.26329 +461 359 -89840137.25118 +465 359 -9.983777999878e-07 +466 359 -52708333.32467 +467 359 -73187955.04869 +468 359 -0.0277450978756 +469 359 -0.02219566702843 +470 359 -162055805.4842 +471 359 16471527.35667 +472 359 52708332.94687 +473 359 -75439445.29918 +477 359 -16471527.78319 +478 359 -13177083.33766 +479 359 -28297094.18124 +480 359 -65886111.10029 +481 359 -2.831220626831e-07 +482 359 -87588646.48668 +483 359 -16471527.78319 +484 359 13177083.33766 +485 359 -28297094.18124 +360 360 571119749.839 +361 360 53333333.32457 +362 360 -6.198883056641e-06 +369 360 -75155545.77471 +370 360 -53333333.32457 +371 360 5.066394805908e-07 +372 360 -292913008.3249 +373 360 -53333332.8979 +374 360 6.556510925293e-06 +375 360 19534202.10867 +376 360 42666666.23299 +377 360 -1.490116119385e-06 +459 360 -9767101.054335 +460 360 15999999.84525 +461 360 19765832.91331 +468 360 -26345045.8913 +469 360 -13333333.17771 +470 360 -16471527.35667 +471 360 45108925.89256 +472 360 13333333.33771 +473 360 13177222.19231 +480 360 -28555987.69793 +481 360 -13333333.33771 +482 360 -16471527.78319 +483 360 -107413106.5112 +484 360 -13333333.23104 +485 360 -65886110.96157 +486 360 -9767101.054335 +487 360 10666666.5635 +488 360 -13177221.94221 +361 361 491115909.0416 +362 361 -2.974887930942e-06 +369 361 -53333333.32457 +370 361 -59154777.5129 +371 361 2.086162567139e-07 +372 361 -53333332.68457 +373 361 -42244300.58137 +374 361 2.145767211914e-06 +375 361 63999999.34949 +376 361 19534202.10866 +377 361 -2.384185791016e-06 +459 361 10666666.5635 +460 361 -9767101.054336 +461 361 -10541666.62055 +468 361 -13333333.23105 +469 361 -73011454.71627 +470 361 -52708332.94687 +471 361 13333333.33771 +472 361 25107965.68335 +473 361 10541666.55379 +480 361 -13333333.33771 +481 361 -24555795.63051 +482 361 -13177083.33766 +483 361 -13333333.17771 +484 361 -44745929.54446 +485 361 -13177083.26329 +486 361 15999999.84525 +487 361 -9767101.054335 +488 361 15812499.93082 +362 362 565941879.2302 +369 362 5.811452865601e-07 +370 362 3.129243850708e-07 +371 362 -9005963.440556 +372 362 6.943941116333e-06 +373 362 1.609325408936e-06 +374 362 5277897.861165 +375 362 -2.145767211914e-06 +376 362 -1.54972076416e-06 +377 362 52091205.62311 +459 362 13177221.94221 +460 362 -15812499.93082 +461 362 -26045602.81156 +468 362 -16471527.49884 +469 362 -52708333.03581 +470 362 -75439445.29917 +471 362 -13177222.19232 +472 362 -10541666.5538 +473 362 -118970561.1562 +480 362 -16471527.78319 +481 362 -13177083.33766 +482 362 -28297094.18124 +483 362 -65886110.96157 +484 362 -13177083.28808 +485 362 -89840137.25117 +486 362 -19765832.91331 +487 362 10541666.62055 +488 362 -26045602.81156 +363 363 913791605.4334 +364 363 7.748603820801e-06 +365 363 -2.622604370117e-06 +366 363 126048980.7912 +367 363 -2.175569534302e-06 +368 363 -1.490116119385e-06 +378 363 -198223262.271 +379 363 2.98023223877e-07 +380 363 5.960464477539e-08 +381 363 -75155545.7747 +382 363 53333333.32457 +383 363 -1.490116119385e-08 +462 363 -88624220.55292 +463 363 1.043081283569e-07 +464 363 65886111.10029 +465 363 -28555987.69793 +466 363 -13333333.33771 +467 363 16471527.78319 +474 363 72174281.7049 +475 363 1.728534698486e-06 +476 363 1.221895217896e-06 +477 363 -7556159.747413 +478 363 -7.450580596924e-07 +479 363 1.341104507446e-06 +489 363 -88624220.55292 +490 363 2.235174179077e-07 +491 363 -65886111.10029 +492 363 -28555987.69793 +493 363 13333333.33771 +494 363 -16471527.78319 +364 364 785785459.402 +365 364 -1.788139343262e-06 +366 364 -2.086162567139e-06 +367 364 -76617423.53181 +368 364 5.066394805908e-07 +378 364 3.576278686523e-07 +379 364 36444678.54407 +380 364 -4.172325134277e-07 +381 364 53333333.32457 +382 364 -59154777.5129 +383 364 2.98023223877e-08 +462 364 4.470348358154e-08 +463 364 -29957235.32024 +464 364 2.831220626831e-07 +465 364 -13333333.33771 +466 364 -24555795.63051 +467 364 13177083.33766 +474 364 1.728534698486e-06 +475 364 40172745.1813 +476 364 -5.960464477539e-08 +477 364 -7.003545761108e-07 +478 364 -58222760.85313 +479 364 52708333.32467 +489 364 1.9371509552e-07 +490 364 -29957235.32024 +491 364 -3.8743019104e-07 +492 364 13333333.33771 +493 364 -24555795.63051 +494 364 13177083.33766 +365 365 905507012.9075 +366 365 -1.668930053711e-06 +367 365 4.470348358154e-07 +368 365 123977832.6588 +378 365 1.192092895508e-07 +379 365 -4.768371582031e-07 +380 365 66375066.93519 +381 365 4.470348358154e-08 +382 365 -4.470348358154e-08 +383 365 -9005963.440553 +462 365 65886111.10029 +463 365 3.8743019104e-07 +464 365 -87588646.48668 +465 365 16471527.78319 +466 365 13177083.33766 +467 365 -28297094.18124 +474 365 8.642673492432e-07 +475 365 1.788139343262e-07 +476 365 -190352899.3709 +477 365 1.475214958191e-06 +478 365 52708333.32467 +479 365 -73187955.0487 +489 365 -65886111.10029 +490 365 -2.831220626831e-07 +491 365 -87588646.48668 +492 365 -16471527.78319 +493 365 13177083.33766 +494 365 -28297094.18124 +366 366 913791605.4334 +367 366 7.748603820801e-06 +368 366 -2.622604370117e-06 +369 366 126048980.7912 +370 366 -2.175569534302e-06 +371 366 -1.490116119385e-06 +378 366 -75155545.77471 +379 366 -53333333.32457 +380 366 5.066394805908e-07 +381 366 -198223262.271 +382 366 2.98023223877e-07 +383 366 5.960464477539e-08 +384 366 -75155545.7747 +385 366 53333333.32457 +386 366 -1.490116119385e-08 +462 366 -28555987.69793 +463 366 13333333.33771 +464 366 16471527.78319 +465 366 -88624220.55292 +466 366 1.043081283569e-07 +467 366 65886111.10029 +468 366 -28555987.69793 +469 366 -13333333.33771 +470 366 16471527.78319 +474 366 -7556159.747413 +475 366 -3.278255462646e-07 +476 366 -1.206994056702e-06 +477 366 72174281.7049 +478 366 1.728534698486e-06 +479 366 1.221895217896e-06 +480 366 -7556159.747413 +481 366 -7.450580596924e-07 +482 366 1.341104507446e-06 +489 366 -28555987.69793 +490 366 -13333333.33771 +491 366 -16471527.78319 +492 366 -88624220.55292 +493 366 2.235174179077e-07 +494 366 -65886111.10029 +495 366 -28555987.69793 +496 366 13333333.33771 +497 366 -16471527.78319 +367 367 785785459.402 +368 367 -1.788139343262e-06 +369 367 -2.086162567139e-06 +370 367 -76617423.53181 +371 367 5.066394805908e-07 +378 367 -53333333.32457 +379 367 -59154777.5129 +380 367 2.086162567139e-07 +381 367 3.576278686523e-07 +382 367 36444678.54407 +383 367 -4.172325134277e-07 +384 367 53333333.32457 +385 367 -59154777.5129 +386 367 2.98023223877e-08 +462 367 13333333.33771 +463 367 -24555795.63051 +464 367 -13177083.33766 +465 367 4.470348358154e-08 +466 367 -29957235.32024 +467 367 2.831220626831e-07 +468 367 -13333333.33771 +469 367 -24555795.63051 +470 367 13177083.33766 +474 367 -2.98023223877e-07 +475 367 -58222760.85313 +476 367 -52708333.32467 +477 367 1.728534698486e-06 +478 367 40172745.1813 +479 367 -5.960464477539e-08 +480 367 -7.003545761108e-07 +481 367 -58222760.85313 +482 367 52708333.32467 +489 367 -13333333.33771 +490 367 -24555795.63051 +491 367 -13177083.33766 +492 367 1.9371509552e-07 +493 367 -29957235.32024 +494 367 -3.8743019104e-07 +495 367 13333333.33771 +496 367 -24555795.63051 +497 367 13177083.33766 +368 368 905507012.9075 +369 368 -1.668930053711e-06 +370 368 4.470348358154e-07 +371 368 123977832.6588 +378 368 5.811452865601e-07 +379 368 3.129243850708e-07 +380 368 -9005963.440556 +381 368 1.192092895508e-07 +382 368 -4.768371582031e-07 +383 368 66375066.93519 +384 368 4.470348358154e-08 +385 368 -4.470348358154e-08 +386 368 -9005963.440553 +462 368 16471527.78319 +463 368 -13177083.33766 +464 368 -28297094.18124 +465 368 65886111.10029 +466 368 3.8743019104e-07 +467 368 -87588646.48668 +468 368 16471527.78319 +469 368 13177083.33766 +470 368 -28297094.18124 +474 368 -9.983777999878e-07 +475 368 -52708333.32467 +476 368 -73187955.04869 +477 368 8.642673492432e-07 +478 368 1.788139343262e-07 +479 368 -190352899.3709 +480 368 1.475214958191e-06 +481 368 52708333.32467 +482 368 -73187955.0487 +489 368 -16471527.78319 +490 368 -13177083.33766 +491 368 -28297094.18124 +492 368 -65886111.10029 +493 368 -2.831220626831e-07 +494 368 -87588646.48668 +495 368 -16471527.78319 +496 368 13177083.33766 +497 368 -28297094.18124 +369 369 913791605.4334 +370 369 7.748603820801e-06 +371 369 -2.622604370117e-06 +372 369 126048980.7912 +373 369 -2.175569534302e-06 +374 369 -1.490116119385e-06 +381 369 -75155545.77471 +382 369 -53333333.32457 +383 369 5.066394805908e-07 +384 369 -198223262.271 +385 369 2.98023223877e-07 +386 369 5.960464477539e-08 +387 369 -75155545.7747 +388 369 53333333.32457 +389 369 -1.490116119385e-08 +465 369 -28555987.69793 +466 369 13333333.33771 +467 369 16471527.78319 +468 369 -88624220.55292 +469 369 1.043081283569e-07 +470 369 65886111.10029 +471 369 -28555987.69793 +472 369 -13333333.33771 +473 369 16471527.78319 +477 369 -7556159.747413 +478 369 -3.278255462646e-07 +479 369 -1.206994056702e-06 +480 369 72174281.7049 +481 369 1.728534698486e-06 +482 369 1.221895217896e-06 +483 369 -7556159.747413 +484 369 -7.450580596924e-07 +485 369 1.341104507446e-06 +492 369 -28555987.69793 +493 369 -13333333.33771 +494 369 -16471527.78319 +495 369 -88624220.55292 +496 369 2.235174179077e-07 +497 369 -65886111.10029 +498 369 -28555987.69793 +499 369 13333333.33771 +500 369 -16471527.78319 +370 370 785785459.402 +371 370 -1.788139343262e-06 +372 370 -2.086162567139e-06 +373 370 -76617423.53181 +374 370 5.066394805908e-07 +381 370 -53333333.32457 +382 370 -59154777.5129 +383 370 2.086162567139e-07 +384 370 3.576278686523e-07 +385 370 36444678.54407 +386 370 -4.172325134277e-07 +387 370 53333333.32457 +388 370 -59154777.5129 +389 370 2.98023223877e-08 +465 370 13333333.33771 +466 370 -24555795.63051 +467 370 -13177083.33766 +468 370 4.470348358154e-08 +469 370 -29957235.32024 +470 370 2.831220626831e-07 +471 370 -13333333.33771 +472 370 -24555795.63051 +473 370 13177083.33766 +477 370 -2.98023223877e-07 +478 370 -58222760.85313 +479 370 -52708333.32467 +480 370 1.728534698486e-06 +481 370 40172745.1813 +482 370 -5.960464477539e-08 +483 370 -7.003545761108e-07 +484 370 -58222760.85313 +485 370 52708333.32467 +492 370 -13333333.33771 +493 370 -24555795.63051 +494 370 -13177083.33766 +495 370 1.9371509552e-07 +496 370 -29957235.32024 +497 370 -3.8743019104e-07 +498 370 13333333.33771 +499 370 -24555795.63051 +500 370 13177083.33766 +371 371 905507012.9075 +372 371 -1.668930053711e-06 +373 371 4.470348358154e-07 +374 371 123977832.6588 +381 371 5.811452865601e-07 +382 371 3.129243850708e-07 +383 371 -9005963.440556 +384 371 1.192092895508e-07 +385 371 -4.768371582031e-07 +386 371 66375066.93519 +387 371 4.470348358154e-08 +388 371 -4.470348358154e-08 +389 371 -9005963.440553 +465 371 16471527.78319 +466 371 -13177083.33766 +467 371 -28297094.18124 +468 371 65886111.10029 +469 371 3.8743019104e-07 +470 371 -87588646.48668 +471 371 16471527.78319 +472 371 13177083.33766 +473 371 -28297094.18124 +477 371 -9.983777999878e-07 +478 371 -52708333.32467 +479 371 -73187955.04869 +480 371 8.642673492432e-07 +481 371 1.788139343262e-07 +482 371 -190352899.3709 +483 371 1.475214958191e-06 +484 371 52708333.32467 +485 371 -73187955.0487 +492 371 -16471527.78319 +493 371 -13177083.33766 +494 371 -28297094.18124 +495 371 -65886111.10029 +496 371 -2.831220626831e-07 +497 371 -87588646.48668 +498 371 -16471527.78319 +499 371 13177083.33766 +500 371 -28297094.18124 +372 372 988947148.5376 +373 372 53333332.25791 +374 372 -9.298324584961e-06 +375 372 31359232.67644 +376 372 -53333332.8979 +377 372 1.251697540283e-06 +384 372 -75155545.77471 +385 372 -53333333.32457 +386 372 5.066394805908e-07 +387 372 -198223262.271 +388 372 2.98023223877e-07 +389 372 5.960464477539e-08 +390 372 -75155545.7747 +391 372 53333333.32457 +392 372 -1.490116119385e-08 +468 372 -28555987.69793 +469 372 13333333.33771 +470 372 16471527.78319 +471 372 -107413106.5112 +472 372 -13333333.17771 +473 372 65886110.96157 +480 372 -7556159.747413 +481 372 -3.278255462646e-07 +482 372 -1.206994056702e-06 +483 372 100730268.7541 +484 372 13333333.07105 +485 372 0.02774140238762 +486 372 -26345045.89131 +487 372 -13333333.23105 +488 372 16471527.49884 +495 372 -28555987.69793 +496 372 -13333333.33771 +497 372 -16471527.78319 +498 372 -88624220.55292 +499 372 2.235174179077e-07 +500 372 -65886111.10029 +501 372 -28555987.69793 +502 372 13333333.33771 +503 372 -16471527.78319 +373 373 844940234.7245 +374 373 -7.987022399902e-06 +375 373 -53333332.68457 +376 373 -155306402.5315 +377 373 5.394220352173e-06 +384 373 -53333333.32457 +385 373 -59154777.5129 +386 373 2.086162567139e-07 +387 373 3.576278686523e-07 +388 373 36444678.54407 +389 373 -4.172325134277e-07 +390 373 53333333.32457 +391 373 -59154777.5129 +392 373 2.98023223877e-08 +468 373 13333333.33771 +469 373 -24555795.63051 +470 373 -13177083.33766 +471 373 -13333333.23104 +472 373 -44745929.54447 +473 373 13177083.28808 +480 373 -2.98023223877e-07 +481 373 -58222760.85313 +482 373 -52708333.32467 +483 373 13333333.07105 +484 373 64728540.28304 +485 373 0.022192299366 +486 373 -13333333.17771 +487 373 -73011454.71628 +488 373 52708333.03581 +495 373 -13333333.33771 +496 373 -24555795.63051 +497 373 -13177083.33766 +498 373 1.9371509552e-07 +499 373 -29957235.32024 +500 373 -3.8743019104e-07 +501 373 13333333.33771 +502 373 -24555795.63051 +503 373 13177083.33766 +374 374 914512974.9691 +375 374 1.728534698486e-06 +376 374 4.559755325317e-06 +377 374 62880662.12465 +384 374 5.811452865601e-07 +385 374 3.129243850708e-07 +386 374 -9005963.440556 +387 374 1.192092895508e-07 +388 374 -4.768371582031e-07 +389 374 66375066.93519 +390 374 4.470348358154e-08 +391 374 -4.470348358154e-08 +392 374 -9005963.440553 +468 374 16471527.78319 +469 374 -13177083.33766 +470 374 -28297094.18124 +471 374 65886110.96157 +472 374 13177083.26329 +473 374 -89840137.25118 +480 374 -9.983777999878e-07 +481 374 -52708333.32467 +482 374 -73187955.04869 +483 374 -0.0277450978756 +484 374 -0.02219566702843 +485 374 -162055805.4842 +486 374 16471527.35667 +487 374 52708332.94687 +488 374 -75439445.29918 +495 374 -16471527.78319 +496 374 -13177083.33766 +497 374 -28297094.18124 +498 374 -65886111.10029 +499 374 -2.831220626831e-07 +500 374 -87588646.48668 +501 374 -16471527.78319 +502 374 13177083.33766 +503 374 -28297094.18124 +375 375 571119749.839 +376 375 53333333.32457 +377 375 -6.198883056641e-06 +387 375 -75155545.77471 +388 375 -53333333.32457 +389 375 5.066394805908e-07 +390 375 -292913008.3249 +391 375 -53333332.8979 +392 375 6.556510925293e-06 +393 375 19534202.10867 +394 375 42666666.23299 +395 375 -1.490116119385e-06 +471 375 -9767101.054335 +472 375 15999999.84525 +473 375 19765832.91331 +483 375 -26345045.8913 +484 375 -13333333.17771 +485 375 -16471527.35667 +486 375 45108925.89256 +487 375 13333333.33771 +488 375 13177222.19231 +498 375 -28555987.69793 +499 375 -13333333.33771 +500 375 -16471527.78319 +501 375 -107413106.5112 +502 375 -13333333.23104 +503 375 -65886110.96157 +504 375 -9767101.054335 +505 375 10666666.5635 +506 375 -13177221.94221 +376 376 491115909.0416 +377 376 -2.974887930942e-06 +387 376 -53333333.32457 +388 376 -59154777.5129 +389 376 2.086162567139e-07 +390 376 -53333332.68457 +391 376 -42244300.58137 +392 376 2.145767211914e-06 +393 376 63999999.34949 +394 376 19534202.10866 +395 376 -2.384185791016e-06 +471 376 10666666.5635 +472 376 -9767101.054336 +473 376 -10541666.62055 +483 376 -13333333.23105 +484 376 -73011454.71627 +485 376 -52708332.94687 +486 376 13333333.33771 +487 376 25107965.68335 +488 376 10541666.55379 +498 376 -13333333.33771 +499 376 -24555795.63051 +500 376 -13177083.33766 +501 376 -13333333.17771 +502 376 -44745929.54446 +503 376 -13177083.26329 +504 376 15999999.84525 +505 376 -9767101.054335 +506 376 15812499.93082 +377 377 565941879.2302 +387 377 5.811452865601e-07 +388 377 3.129243850708e-07 +389 377 -9005963.440556 +390 377 6.943941116333e-06 +391 377 1.609325408936e-06 +392 377 5277897.861165 +393 377 -2.145767211914e-06 +394 377 -1.54972076416e-06 +395 377 52091205.62311 +471 377 13177221.94221 +472 377 -15812499.93082 +473 377 -26045602.81156 +483 377 -16471527.49884 +484 377 -52708333.03581 +485 377 -75439445.29917 +486 377 -13177222.19232 +487 377 -10541666.5538 +488 377 -118970561.1562 +498 377 -16471527.78319 +499 377 -13177083.33766 +500 377 -28297094.18124 +501 377 -65886110.96157 +502 377 -13177083.28808 +503 377 -89840137.25117 +504 377 -19765832.91331 +505 377 10541666.62055 +506 377 -26045602.81156 +378 378 913791605.4334 +379 378 7.748603820801e-06 +380 378 -2.622604370117e-06 +381 378 126048980.7912 +382 378 -2.175569534302e-06 +383 378 -1.490116119385e-06 +396 378 -198223262.271 +397 378 2.98023223877e-07 +398 378 5.960464477539e-08 +399 378 -75155545.7747 +400 378 53333333.32457 +401 378 -1.490116119385e-08 +474 378 -88624220.55292 +475 378 1.043081283569e-07 +476 378 65886111.10029 +477 378 -28555987.69793 +478 378 -13333333.33771 +479 378 16471527.78319 +489 378 72174281.7049 +490 378 1.728534698486e-06 +491 378 1.221895217896e-06 +492 378 -7556159.747413 +493 378 -7.450580596924e-07 +494 378 1.341104507446e-06 +507 378 -88624220.55292 +508 378 2.235174179077e-07 +509 378 -65886111.10029 +510 378 -28555987.69793 +511 378 13333333.33771 +512 378 -16471527.78319 +379 379 785785459.402 +380 379 -1.788139343262e-06 +381 379 -2.086162567139e-06 +382 379 -76617423.53181 +383 379 5.066394805908e-07 +396 379 3.576278686523e-07 +397 379 36444678.54407 +398 379 -4.172325134277e-07 +399 379 53333333.32457 +400 379 -59154777.5129 +401 379 2.98023223877e-08 +474 379 4.470348358154e-08 +475 379 -29957235.32024 +476 379 2.831220626831e-07 +477 379 -13333333.33771 +478 379 -24555795.63051 +479 379 13177083.33766 +489 379 1.728534698486e-06 +490 379 40172745.1813 +491 379 -5.960464477539e-08 +492 379 -7.003545761108e-07 +493 379 -58222760.85313 +494 379 52708333.32467 +507 379 1.9371509552e-07 +508 379 -29957235.32024 +509 379 -3.8743019104e-07 +510 379 13333333.33771 +511 379 -24555795.63051 +512 379 13177083.33766 +380 380 905507012.9075 +381 380 -1.668930053711e-06 +382 380 4.470348358154e-07 +383 380 123977832.6588 +396 380 1.192092895508e-07 +397 380 -4.768371582031e-07 +398 380 66375066.93519 +399 380 4.470348358154e-08 +400 380 -4.470348358154e-08 +401 380 -9005963.440553 +474 380 65886111.10029 +475 380 3.8743019104e-07 +476 380 -87588646.48668 +477 380 16471527.78319 +478 380 13177083.33766 +479 380 -28297094.18124 +489 380 8.642673492432e-07 +490 380 1.788139343262e-07 +491 380 -190352899.3709 +492 380 1.475214958191e-06 +493 380 52708333.32467 +494 380 -73187955.0487 +507 380 -65886111.10029 +508 380 -2.831220626831e-07 +509 380 -87588646.48668 +510 380 -16471527.78319 +511 380 13177083.33766 +512 380 -28297094.18124 +381 381 913791605.4334 +382 381 7.748603820801e-06 +383 381 -2.622604370117e-06 +384 381 126048980.7912 +385 381 -2.175569534302e-06 +386 381 -1.490116119385e-06 +396 381 -75155545.77471 +397 381 -53333333.32457 +398 381 5.066394805908e-07 +399 381 -198223262.271 +400 381 2.98023223877e-07 +401 381 5.960464477539e-08 +402 381 -75155545.7747 +403 381 53333333.32457 +404 381 -1.490116119385e-08 +474 381 -28555987.69793 +475 381 13333333.33771 +476 381 16471527.78319 +477 381 -88624220.55292 +478 381 1.043081283569e-07 +479 381 65886111.10029 +480 381 -28555987.69793 +481 381 -13333333.33771 +482 381 16471527.78319 +489 381 -7556159.747413 +490 381 -3.278255462646e-07 +491 381 -1.206994056702e-06 +492 381 72174281.7049 +493 381 1.728534698486e-06 +494 381 1.221895217896e-06 +495 381 -7556159.747413 +496 381 -7.450580596924e-07 +497 381 1.341104507446e-06 +507 381 -28555987.69793 +508 381 -13333333.33771 +509 381 -16471527.78319 +510 381 -88624220.55292 +511 381 2.235174179077e-07 +512 381 -65886111.10029 +513 381 -28555987.69793 +514 381 13333333.33771 +515 381 -16471527.78319 +382 382 785785459.402 +383 382 -1.788139343262e-06 +384 382 -2.086162567139e-06 +385 382 -76617423.53181 +386 382 5.066394805908e-07 +396 382 -53333333.32457 +397 382 -59154777.5129 +398 382 2.086162567139e-07 +399 382 3.576278686523e-07 +400 382 36444678.54407 +401 382 -4.172325134277e-07 +402 382 53333333.32457 +403 382 -59154777.5129 +404 382 2.98023223877e-08 +474 382 13333333.33771 +475 382 -24555795.63051 +476 382 -13177083.33766 +477 382 4.470348358154e-08 +478 382 -29957235.32024 +479 382 2.831220626831e-07 +480 382 -13333333.33771 +481 382 -24555795.63051 +482 382 13177083.33766 +489 382 -2.98023223877e-07 +490 382 -58222760.85313 +491 382 -52708333.32467 +492 382 1.728534698486e-06 +493 382 40172745.1813 +494 382 -5.960464477539e-08 +495 382 -7.003545761108e-07 +496 382 -58222760.85313 +497 382 52708333.32467 +507 382 -13333333.33771 +508 382 -24555795.63051 +509 382 -13177083.33766 +510 382 1.9371509552e-07 +511 382 -29957235.32024 +512 382 -3.8743019104e-07 +513 382 13333333.33771 +514 382 -24555795.63051 +515 382 13177083.33766 +383 383 905507012.9075 +384 383 -1.668930053711e-06 +385 383 4.470348358154e-07 +386 383 123977832.6588 +396 383 5.811452865601e-07 +397 383 3.129243850708e-07 +398 383 -9005963.440556 +399 383 1.192092895508e-07 +400 383 -4.768371582031e-07 +401 383 66375066.93519 +402 383 4.470348358154e-08 +403 383 -4.470348358154e-08 +404 383 -9005963.440553 +474 383 16471527.78319 +475 383 -13177083.33766 +476 383 -28297094.18124 +477 383 65886111.10029 +478 383 3.8743019104e-07 +479 383 -87588646.48668 +480 383 16471527.78319 +481 383 13177083.33766 +482 383 -28297094.18124 +489 383 -9.983777999878e-07 +490 383 -52708333.32467 +491 383 -73187955.04869 +492 383 8.642673492432e-07 +493 383 1.788139343262e-07 +494 383 -190352899.3709 +495 383 1.475214958191e-06 +496 383 52708333.32467 +497 383 -73187955.0487 +507 383 -16471527.78319 +508 383 -13177083.33766 +509 383 -28297094.18124 +510 383 -65886111.10029 +511 383 -2.831220626831e-07 +512 383 -87588646.48668 +513 383 -16471527.78319 +514 383 13177083.33766 +515 383 -28297094.18124 +384 384 913791605.4334 +385 384 7.748603820801e-06 +386 384 -2.622604370117e-06 +387 384 126048980.7912 +388 384 -2.175569534302e-06 +389 384 -1.490116119385e-06 +399 384 -75155545.77471 +400 384 -53333333.32457 +401 384 5.066394805908e-07 +402 384 -198223262.271 +403 384 2.98023223877e-07 +404 384 5.960464477539e-08 +405 384 -75155545.7747 +406 384 53333333.32457 +407 384 -1.490116119385e-08 +477 384 -28555987.69793 +478 384 13333333.33771 +479 384 16471527.78319 +480 384 -88624220.55292 +481 384 1.043081283569e-07 +482 384 65886111.10029 +483 384 -28555987.69793 +484 384 -13333333.33771 +485 384 16471527.78319 +492 384 -7556159.747413 +493 384 -3.278255462646e-07 +494 384 -1.206994056702e-06 +495 384 72174281.7049 +496 384 1.728534698486e-06 +497 384 1.221895217896e-06 +498 384 -7556159.747413 +499 384 -7.450580596924e-07 +500 384 1.341104507446e-06 +510 384 -28555987.69793 +511 384 -13333333.33771 +512 384 -16471527.78319 +513 384 -88624220.55292 +514 384 2.235174179077e-07 +515 384 -65886111.10029 +516 384 -28555987.69793 +517 384 13333333.33771 +518 384 -16471527.78319 +385 385 785785459.402 +386 385 -1.788139343262e-06 +387 385 -2.086162567139e-06 +388 385 -76617423.53181 +389 385 5.066394805908e-07 +399 385 -53333333.32457 +400 385 -59154777.5129 +401 385 2.086162567139e-07 +402 385 3.576278686523e-07 +403 385 36444678.54407 +404 385 -4.172325134277e-07 +405 385 53333333.32457 +406 385 -59154777.5129 +407 385 2.98023223877e-08 +477 385 13333333.33771 +478 385 -24555795.63051 +479 385 -13177083.33766 +480 385 4.470348358154e-08 +481 385 -29957235.32024 +482 385 2.831220626831e-07 +483 385 -13333333.33771 +484 385 -24555795.63051 +485 385 13177083.33766 +492 385 -2.98023223877e-07 +493 385 -58222760.85313 +494 385 -52708333.32467 +495 385 1.728534698486e-06 +496 385 40172745.1813 +497 385 -5.960464477539e-08 +498 385 -7.003545761108e-07 +499 385 -58222760.85313 +500 385 52708333.32467 +510 385 -13333333.33771 +511 385 -24555795.63051 +512 385 -13177083.33766 +513 385 1.9371509552e-07 +514 385 -29957235.32024 +515 385 -3.8743019104e-07 +516 385 13333333.33771 +517 385 -24555795.63051 +518 385 13177083.33766 +386 386 905507012.9075 +387 386 -1.668930053711e-06 +388 386 4.470348358154e-07 +389 386 123977832.6588 +399 386 5.811452865601e-07 +400 386 3.129243850708e-07 +401 386 -9005963.440556 +402 386 1.192092895508e-07 +403 386 -4.768371582031e-07 +404 386 66375066.93519 +405 386 4.470348358154e-08 +406 386 -4.470348358154e-08 +407 386 -9005963.440553 +477 386 16471527.78319 +478 386 -13177083.33766 +479 386 -28297094.18124 +480 386 65886111.10029 +481 386 3.8743019104e-07 +482 386 -87588646.48668 +483 386 16471527.78319 +484 386 13177083.33766 +485 386 -28297094.18124 +492 386 -9.983777999878e-07 +493 386 -52708333.32467 +494 386 -73187955.04869 +495 386 8.642673492432e-07 +496 386 1.788139343262e-07 +497 386 -190352899.3709 +498 386 1.475214958191e-06 +499 386 52708333.32467 +500 386 -73187955.0487 +510 386 -16471527.78319 +511 386 -13177083.33766 +512 386 -28297094.18124 +513 386 -65886111.10029 +514 386 -2.831220626831e-07 +515 386 -87588646.48668 +516 386 -16471527.78319 +517 386 13177083.33766 +518 386 -28297094.18124 +387 387 913791605.4334 +388 387 7.748603820801e-06 +389 387 -2.622604370117e-06 +390 387 126048980.7912 +391 387 -2.175569534302e-06 +392 387 -1.490116119385e-06 +402 387 -75155545.77471 +403 387 -53333333.32457 +404 387 5.066394805908e-07 +405 387 -198223262.271 +406 387 2.98023223877e-07 +407 387 5.960464477539e-08 +408 387 -75155545.7747 +409 387 53333333.32457 +410 387 -1.490116119385e-08 +480 387 -28555987.69793 +481 387 13333333.33771 +482 387 16471527.78319 +483 387 -88624220.55292 +484 387 1.043081283569e-07 +485 387 65886111.10029 +486 387 -28555987.69793 +487 387 -13333333.33771 +488 387 16471527.78319 +495 387 -7556159.747413 +496 387 -3.278255462646e-07 +497 387 -1.206994056702e-06 +498 387 72174281.7049 +499 387 1.728534698486e-06 +500 387 1.221895217896e-06 +501 387 -7556159.747413 +502 387 -7.450580596924e-07 +503 387 1.341104507446e-06 +513 387 -28555987.69793 +514 387 -13333333.33771 +515 387 -16471527.78319 +516 387 -88624220.55292 +517 387 2.235174179077e-07 +518 387 -65886111.10029 +519 387 -28555987.69793 +520 387 13333333.33771 +521 387 -16471527.78319 +388 388 785785459.402 +389 388 -1.788139343262e-06 +390 388 -2.086162567139e-06 +391 388 -76617423.53181 +392 388 5.066394805908e-07 +402 388 -53333333.32457 +403 388 -59154777.5129 +404 388 2.086162567139e-07 +405 388 3.576278686523e-07 +406 388 36444678.54407 +407 388 -4.172325134277e-07 +408 388 53333333.32457 +409 388 -59154777.5129 +410 388 2.98023223877e-08 +480 388 13333333.33771 +481 388 -24555795.63051 +482 388 -13177083.33766 +483 388 4.470348358154e-08 +484 388 -29957235.32024 +485 388 2.831220626831e-07 +486 388 -13333333.33771 +487 388 -24555795.63051 +488 388 13177083.33766 +495 388 -2.98023223877e-07 +496 388 -58222760.85313 +497 388 -52708333.32467 +498 388 1.728534698486e-06 +499 388 40172745.1813 +500 388 -5.960464477539e-08 +501 388 -7.003545761108e-07 +502 388 -58222760.85313 +503 388 52708333.32467 +513 388 -13333333.33771 +514 388 -24555795.63051 +515 388 -13177083.33766 +516 388 1.9371509552e-07 +517 388 -29957235.32024 +518 388 -3.8743019104e-07 +519 388 13333333.33771 +520 388 -24555795.63051 +521 388 13177083.33766 +389 389 905507012.9075 +390 389 -1.668930053711e-06 +391 389 4.470348358154e-07 +392 389 123977832.6588 +402 389 5.811452865601e-07 +403 389 3.129243850708e-07 +404 389 -9005963.440556 +405 389 1.192092895508e-07 +406 389 -4.768371582031e-07 +407 389 66375066.93519 +408 389 4.470348358154e-08 +409 389 -4.470348358154e-08 +410 389 -9005963.440553 +480 389 16471527.78319 +481 389 -13177083.33766 +482 389 -28297094.18124 +483 389 65886111.10029 +484 389 3.8743019104e-07 +485 389 -87588646.48668 +486 389 16471527.78319 +487 389 13177083.33766 +488 389 -28297094.18124 +495 389 -9.983777999878e-07 +496 389 -52708333.32467 +497 389 -73187955.04869 +498 389 8.642673492432e-07 +499 389 1.788139343262e-07 +500 389 -190352899.3709 +501 389 1.475214958191e-06 +502 389 52708333.32467 +503 389 -73187955.0487 +513 389 -16471527.78319 +514 389 -13177083.33766 +515 389 -28297094.18124 +516 389 -65886111.10029 +517 389 -2.831220626831e-07 +518 389 -87588646.48668 +519 389 -16471527.78319 +520 389 13177083.33766 +521 389 -28297094.18124 +390 390 988947148.5376 +391 390 53333332.25791 +392 390 -9.298324584961e-06 +393 390 31359232.67644 +394 390 -53333332.8979 +395 390 1.251697540283e-06 +405 390 -75155545.77471 +406 390 -53333333.32457 +407 390 5.066394805908e-07 +408 390 -198223262.271 +409 390 2.98023223877e-07 +410 390 5.960464477539e-08 +411 390 -75155545.7747 +412 390 53333333.32457 +413 390 -1.490116119385e-08 +483 390 -28555987.69793 +484 390 13333333.33771 +485 390 16471527.78319 +486 390 -107413106.5112 +487 390 -13333333.17771 +488 390 65886110.96157 +498 390 -7556159.747413 +499 390 -3.278255462646e-07 +500 390 -1.206994056702e-06 +501 390 100730268.7541 +502 390 13333333.07105 +503 390 0.02774140238762 +504 390 -26345045.89131 +505 390 -13333333.23105 +506 390 16471527.49884 +516 390 -28555987.69793 +517 390 -13333333.33771 +518 390 -16471527.78319 +519 390 -88624220.55292 +520 390 2.235174179077e-07 +521 390 -65886111.10029 +522 390 -28555987.69793 +523 390 13333333.33771 +524 390 -16471527.78319 +391 391 844940234.7245 +392 391 -7.987022399902e-06 +393 391 -53333332.68457 +394 391 -155306402.5315 +395 391 5.394220352173e-06 +405 391 -53333333.32457 +406 391 -59154777.5129 +407 391 2.086162567139e-07 +408 391 3.576278686523e-07 +409 391 36444678.54407 +410 391 -4.172325134277e-07 +411 391 53333333.32457 +412 391 -59154777.5129 +413 391 2.98023223877e-08 +483 391 13333333.33771 +484 391 -24555795.63051 +485 391 -13177083.33766 +486 391 -13333333.23104 +487 391 -44745929.54447 +488 391 13177083.28808 +498 391 -2.98023223877e-07 +499 391 -58222760.85313 +500 391 -52708333.32467 +501 391 13333333.07105 +502 391 64728540.28304 +503 391 0.022192299366 +504 391 -13333333.17771 +505 391 -73011454.71628 +506 391 52708333.03581 +516 391 -13333333.33771 +517 391 -24555795.63051 +518 391 -13177083.33766 +519 391 1.9371509552e-07 +520 391 -29957235.32024 +521 391 -3.8743019104e-07 +522 391 13333333.33771 +523 391 -24555795.63051 +524 391 13177083.33766 +392 392 914512974.9691 +393 392 1.728534698486e-06 +394 392 4.559755325317e-06 +395 392 62880662.12465 +405 392 5.811452865601e-07 +406 392 3.129243850708e-07 +407 392 -9005963.440556 +408 392 1.192092895508e-07 +409 392 -4.768371582031e-07 +410 392 66375066.93519 +411 392 4.470348358154e-08 +412 392 -4.470348358154e-08 +413 392 -9005963.440553 +483 392 16471527.78319 +484 392 -13177083.33766 +485 392 -28297094.18124 +486 392 65886110.96157 +487 392 13177083.26329 +488 392 -89840137.25118 +498 392 -9.983777999878e-07 +499 392 -52708333.32467 +500 392 -73187955.04869 +501 392 -0.0277450978756 +502 392 -0.02219566702843 +503 392 -162055805.4842 +504 392 16471527.35667 +505 392 52708332.94687 +506 392 -75439445.29918 +516 392 -16471527.78319 +517 392 -13177083.33766 +518 392 -28297094.18124 +519 392 -65886111.10029 +520 392 -2.831220626831e-07 +521 392 -87588646.48668 +522 392 -16471527.78319 +523 392 13177083.33766 +524 392 -28297094.18124 +393 393 509154568.8248 +394 393 25085639.27704 +395 393 -5.960464477539e-07 +408 393 -75155545.77471 +409 393 -53333333.32457 +410 393 5.066394805908e-07 +411 393 -228025244.9359 +412 393 -25085638.85037 +413 393 7.152557373047e-07 +414 393 -4082989.550575 +415 393 42666666.23299 +416 393 -1.251697540283e-06 +486 393 -9767101.054335 +487 393 15999999.84525 +488 393 19765832.91331 +501 393 -26345045.8913 +502 393 -13333333.17771 +503 393 -16471527.35667 +504 393 37378109.13818 +505 393 6271409.822349 +506 393 11432222.19995 +519 393 -28555987.69793 +520 393 -13333333.33771 +521 393 -16471527.78319 +522 393 -87310926.38278 +523 393 -6271409.715683 +524 393 -57161110.99975 +525 393 -11791159.78617 +526 393 10666666.5635 +527 393 -9687222.01637 +394 394 472604990.7818 +395 394 -2.652406692505e-06 +408 394 -53333333.32457 +409 394 -59154777.5129 +410 394 2.086162567139e-07 +411 394 -25085638.63704 +412 394 9928432.40691 +413 394 2.384185791016e-07 +414 394 63999999.34949 +415 394 -34822221.9043 +416 394 -1.788139343262e-07 +486 394 10666666.5635 +487 394 -9767101.054336 +488 394 -10541666.62055 +501 394 -13333333.23105 +502 394 -73011454.71627 +503 394 -52708332.94687 +504 394 6271409.822349 +505 394 28240714.62293 +506 394 9145833.226567 +519 394 -13333333.33771 +520 394 -24555795.63051 +521 394 -13177083.33766 +522 394 -6271409.66235 +523 394 -27822507.01778 +524 394 -6197916.627156 +525 394 15999999.84526 +526 394 -19475967.87838 +527 394 18604166.53816 +395 395 522045024.059 +408 395 5.811452865601e-07 +409 395 3.129243850708e-07 +410 395 -9005963.440556 +411 395 7.450580596924e-07 +412 395 2.384185791016e-07 +413 395 26229073.67805 +414 395 -1.490116119385e-06 +415 395 2.384185791016e-07 +416 395 19851260.21887 +486 395 13177221.94221 +487 395 -15812499.93082 +488 395 -26045602.81156 +501 395 -16471527.49884 +502 395 -52708333.03581 +503 395 -75439445.29917 +504 395 -11432222.19995 +505 395 -9145833.22657 +506 395 -109250165.6029 +519 395 -16471527.78319 +520 395 -13177083.33766 +521 395 -28297094.18124 +522 395 -57161110.99975 +523 395 -6197916.651946 +524 395 -74255038.56586 +525 395 -14530833.02455 +526 395 14729166.53156 +527 395 -23758284.67089 +396 396 913791605.4334 +397 396 7.748603820801e-06 +398 396 -2.622604370117e-06 +399 396 126048980.7912 +400 396 -2.175569534302e-06 +401 396 -1.490116119385e-06 +417 396 -198223262.271 +418 396 2.98023223877e-07 +419 396 5.960464477539e-08 +420 396 -75155545.7747 +421 396 53333333.32457 +422 396 -1.490116119385e-08 +489 396 -88624220.55292 +490 396 1.043081283569e-07 +491 396 65886111.10029 +492 396 -28555987.69793 +493 396 -13333333.33771 +494 396 16471527.78319 +507 396 72174281.7049 +508 396 1.728534698486e-06 +509 396 1.221895217896e-06 +510 396 -7556159.747413 +511 396 -7.450580596924e-07 +512 396 1.341104507446e-06 +528 396 -88624220.55292 +529 396 2.235174179077e-07 +530 396 -65886111.10029 +531 396 -28555987.69793 +532 396 13333333.33771 +533 396 -16471527.78319 +397 397 785785459.402 +398 397 -1.788139343262e-06 +399 397 -2.086162567139e-06 +400 397 -76617423.53181 +401 397 5.066394805908e-07 +417 397 3.576278686523e-07 +418 397 36444678.54407 +419 397 -4.172325134277e-07 +420 397 53333333.32457 +421 397 -59154777.5129 +422 397 2.98023223877e-08 +489 397 4.470348358154e-08 +490 397 -29957235.32024 +491 397 2.831220626831e-07 +492 397 -13333333.33771 +493 397 -24555795.63051 +494 397 13177083.33766 +507 397 1.728534698486e-06 +508 397 40172745.1813 +509 397 -5.960464477539e-08 +510 397 -7.003545761108e-07 +511 397 -58222760.85313 +512 397 52708333.32467 +528 397 1.9371509552e-07 +529 397 -29957235.32024 +530 397 -3.8743019104e-07 +531 397 13333333.33771 +532 397 -24555795.63051 +533 397 13177083.33766 +398 398 905507012.9075 +399 398 -1.668930053711e-06 +400 398 4.470348358154e-07 +401 398 123977832.6588 +417 398 1.192092895508e-07 +418 398 -4.768371582031e-07 +419 398 66375066.93519 +420 398 4.470348358154e-08 +421 398 -4.470348358154e-08 +422 398 -9005963.440553 +489 398 65886111.10029 +490 398 3.8743019104e-07 +491 398 -87588646.48668 +492 398 16471527.78319 +493 398 13177083.33766 +494 398 -28297094.18124 +507 398 8.642673492432e-07 +508 398 1.788139343262e-07 +509 398 -190352899.3709 +510 398 1.475214958191e-06 +511 398 52708333.32467 +512 398 -73187955.0487 +528 398 -65886111.10029 +529 398 -2.831220626831e-07 +530 398 -87588646.48668 +531 398 -16471527.78319 +532 398 13177083.33766 +533 398 -28297094.18124 +399 399 913791605.4334 +400 399 7.748603820801e-06 +401 399 -2.622604370117e-06 +402 399 126048980.7912 +403 399 -2.175569534302e-06 +404 399 -1.490116119385e-06 +417 399 -75155545.77471 +418 399 -53333333.32457 +419 399 5.066394805908e-07 +420 399 -198223262.271 +421 399 2.98023223877e-07 +422 399 5.960464477539e-08 +423 399 -75155545.7747 +424 399 53333333.32457 +425 399 -1.490116119385e-08 +489 399 -28555987.69793 +490 399 13333333.33771 +491 399 16471527.78319 +492 399 -88624220.55292 +493 399 1.043081283569e-07 +494 399 65886111.10029 +495 399 -28555987.69793 +496 399 -13333333.33771 +497 399 16471527.78319 +507 399 -7556159.747413 +508 399 -3.278255462646e-07 +509 399 -1.206994056702e-06 +510 399 72174281.7049 +511 399 1.728534698486e-06 +512 399 1.221895217896e-06 +513 399 -7556159.747413 +514 399 -7.450580596924e-07 +515 399 1.341104507446e-06 +528 399 -28555987.69793 +529 399 -13333333.33771 +530 399 -16471527.78319 +531 399 -88624220.55292 +532 399 2.235174179077e-07 +533 399 -65886111.10029 +534 399 -28555987.69793 +535 399 13333333.33771 +536 399 -16471527.78319 +400 400 785785459.402 +401 400 -1.788139343262e-06 +402 400 -2.086162567139e-06 +403 400 -76617423.53181 +404 400 5.066394805908e-07 +417 400 -53333333.32457 +418 400 -59154777.5129 +419 400 2.086162567139e-07 +420 400 3.576278686523e-07 +421 400 36444678.54407 +422 400 -4.172325134277e-07 +423 400 53333333.32457 +424 400 -59154777.5129 +425 400 2.98023223877e-08 +489 400 13333333.33771 +490 400 -24555795.63051 +491 400 -13177083.33766 +492 400 4.470348358154e-08 +493 400 -29957235.32024 +494 400 2.831220626831e-07 +495 400 -13333333.33771 +496 400 -24555795.63051 +497 400 13177083.33766 +507 400 -2.98023223877e-07 +508 400 -58222760.85313 +509 400 -52708333.32467 +510 400 1.728534698486e-06 +511 400 40172745.1813 +512 400 -5.960464477539e-08 +513 400 -7.003545761108e-07 +514 400 -58222760.85313 +515 400 52708333.32467 +528 400 -13333333.33771 +529 400 -24555795.63051 +530 400 -13177083.33766 +531 400 1.9371509552e-07 +532 400 -29957235.32024 +533 400 -3.8743019104e-07 +534 400 13333333.33771 +535 400 -24555795.63051 +536 400 13177083.33766 +401 401 905507012.9075 +402 401 -1.668930053711e-06 +403 401 4.470348358154e-07 +404 401 123977832.6588 +417 401 5.811452865601e-07 +418 401 3.129243850708e-07 +419 401 -9005963.440556 +420 401 1.192092895508e-07 +421 401 -4.768371582031e-07 +422 401 66375066.93519 +423 401 4.470348358154e-08 +424 401 -4.470348358154e-08 +425 401 -9005963.440553 +489 401 16471527.78319 +490 401 -13177083.33766 +491 401 -28297094.18124 +492 401 65886111.10029 +493 401 3.8743019104e-07 +494 401 -87588646.48668 +495 401 16471527.78319 +496 401 13177083.33766 +497 401 -28297094.18124 +507 401 -9.983777999878e-07 +508 401 -52708333.32467 +509 401 -73187955.04869 +510 401 8.642673492432e-07 +511 401 1.788139343262e-07 +512 401 -190352899.3709 +513 401 1.475214958191e-06 +514 401 52708333.32467 +515 401 -73187955.0487 +528 401 -16471527.78319 +529 401 -13177083.33766 +530 401 -28297094.18124 +531 401 -65886111.10029 +532 401 -2.831220626831e-07 +533 401 -87588646.48668 +534 401 -16471527.78319 +535 401 13177083.33766 +536 401 -28297094.18124 +402 402 913791605.4334 +403 402 7.748603820801e-06 +404 402 -2.622604370117e-06 +405 402 126048980.7912 +406 402 -2.175569534302e-06 +407 402 -1.490116119385e-06 +420 402 -75155545.77471 +421 402 -53333333.32457 +422 402 5.066394805908e-07 +423 402 -198223262.271 +424 402 2.98023223877e-07 +425 402 5.960464477539e-08 +426 402 -75155545.7747 +427 402 53333333.32457 +428 402 -1.490116119385e-08 +492 402 -28555987.69793 +493 402 13333333.33771 +494 402 16471527.78319 +495 402 -88624220.55292 +496 402 1.043081283569e-07 +497 402 65886111.10029 +498 402 -28555987.69793 +499 402 -13333333.33771 +500 402 16471527.78319 +510 402 -7556159.747413 +511 402 -3.278255462646e-07 +512 402 -1.206994056702e-06 +513 402 72174281.7049 +514 402 1.728534698486e-06 +515 402 1.221895217896e-06 +516 402 -7556159.747413 +517 402 -7.450580596924e-07 +518 402 1.341104507446e-06 +531 402 -28555987.69793 +532 402 -13333333.33771 +533 402 -16471527.78319 +534 402 -88624220.55292 +535 402 2.235174179077e-07 +536 402 -65886111.10029 +537 402 -28555987.69793 +538 402 13333333.33771 +539 402 -16471527.78319 +403 403 785785459.402 +404 403 -1.788139343262e-06 +405 403 -2.086162567139e-06 +406 403 -76617423.53181 +407 403 5.066394805908e-07 +420 403 -53333333.32457 +421 403 -59154777.5129 +422 403 2.086162567139e-07 +423 403 3.576278686523e-07 +424 403 36444678.54407 +425 403 -4.172325134277e-07 +426 403 53333333.32457 +427 403 -59154777.5129 +428 403 2.98023223877e-08 +492 403 13333333.33771 +493 403 -24555795.63051 +494 403 -13177083.33766 +495 403 4.470348358154e-08 +496 403 -29957235.32024 +497 403 2.831220626831e-07 +498 403 -13333333.33771 +499 403 -24555795.63051 +500 403 13177083.33766 +510 403 -2.98023223877e-07 +511 403 -58222760.85313 +512 403 -52708333.32467 +513 403 1.728534698486e-06 +514 403 40172745.1813 +515 403 -5.960464477539e-08 +516 403 -7.003545761108e-07 +517 403 -58222760.85313 +518 403 52708333.32467 +531 403 -13333333.33771 +532 403 -24555795.63051 +533 403 -13177083.33766 +534 403 1.9371509552e-07 +535 403 -29957235.32024 +536 403 -3.8743019104e-07 +537 403 13333333.33771 +538 403 -24555795.63051 +539 403 13177083.33766 +404 404 905507012.9075 +405 404 -1.668930053711e-06 +406 404 4.470348358154e-07 +407 404 123977832.6588 +420 404 5.811452865601e-07 +421 404 3.129243850708e-07 +422 404 -9005963.440556 +423 404 1.192092895508e-07 +424 404 -4.768371582031e-07 +425 404 66375066.93519 +426 404 4.470348358154e-08 +427 404 -4.470348358154e-08 +428 404 -9005963.440553 +492 404 16471527.78319 +493 404 -13177083.33766 +494 404 -28297094.18124 +495 404 65886111.10029 +496 404 3.8743019104e-07 +497 404 -87588646.48668 +498 404 16471527.78319 +499 404 13177083.33766 +500 404 -28297094.18124 +510 404 -9.983777999878e-07 +511 404 -52708333.32467 +512 404 -73187955.04869 +513 404 8.642673492432e-07 +514 404 1.788139343262e-07 +515 404 -190352899.3709 +516 404 1.475214958191e-06 +517 404 52708333.32467 +518 404 -73187955.0487 +531 404 -16471527.78319 +532 404 -13177083.33766 +533 404 -28297094.18124 +534 404 -65886111.10029 +535 404 -2.831220626831e-07 +536 404 -87588646.48668 +537 404 -16471527.78319 +538 404 13177083.33766 +539 404 -28297094.18124 +405 405 913791605.4334 +406 405 7.748603820801e-06 +407 405 -2.622604370117e-06 +408 405 126048980.7912 +409 405 -2.175569534302e-06 +410 405 -1.490116119385e-06 +423 405 -75155545.77471 +424 405 -53333333.32457 +425 405 5.066394805908e-07 +426 405 -198223262.271 +427 405 2.98023223877e-07 +428 405 5.960464477539e-08 +429 405 -75155545.7747 +430 405 53333333.32457 +431 405 -1.490116119385e-08 +495 405 -28555987.69793 +496 405 13333333.33771 +497 405 16471527.78319 +498 405 -88624220.55292 +499 405 1.043081283569e-07 +500 405 65886111.10029 +501 405 -28555987.69793 +502 405 -13333333.33771 +503 405 16471527.78319 +513 405 -7556159.747413 +514 405 -3.278255462646e-07 +515 405 -1.206994056702e-06 +516 405 72174281.7049 +517 405 1.728534698486e-06 +518 405 1.221895217896e-06 +519 405 -7556159.747413 +520 405 -7.450580596924e-07 +521 405 1.341104507446e-06 +534 405 -28555987.69793 +535 405 -13333333.33771 +536 405 -16471527.78319 +537 405 -88624220.55292 +538 405 2.235174179077e-07 +539 405 -65886111.10029 +540 405 -28555987.69793 +541 405 13333333.33771 +542 405 -16471527.78319 +406 406 785785459.402 +407 406 -1.788139343262e-06 +408 406 -2.086162567139e-06 +409 406 -76617423.53181 +410 406 5.066394805908e-07 +423 406 -53333333.32457 +424 406 -59154777.5129 +425 406 2.086162567139e-07 +426 406 3.576278686523e-07 +427 406 36444678.54407 +428 406 -4.172325134277e-07 +429 406 53333333.32457 +430 406 -59154777.5129 +431 406 2.98023223877e-08 +495 406 13333333.33771 +496 406 -24555795.63051 +497 406 -13177083.33766 +498 406 4.470348358154e-08 +499 406 -29957235.32024 +500 406 2.831220626831e-07 +501 406 -13333333.33771 +502 406 -24555795.63051 +503 406 13177083.33766 +513 406 -2.98023223877e-07 +514 406 -58222760.85313 +515 406 -52708333.32467 +516 406 1.728534698486e-06 +517 406 40172745.1813 +518 406 -5.960464477539e-08 +519 406 -7.003545761108e-07 +520 406 -58222760.85313 +521 406 52708333.32467 +534 406 -13333333.33771 +535 406 -24555795.63051 +536 406 -13177083.33766 +537 406 1.9371509552e-07 +538 406 -29957235.32024 +539 406 -3.8743019104e-07 +540 406 13333333.33771 +541 406 -24555795.63051 +542 406 13177083.33766 +407 407 905507012.9075 +408 407 -1.668930053711e-06 +409 407 4.470348358154e-07 +410 407 123977832.6588 +423 407 5.811452865601e-07 +424 407 3.129243850708e-07 +425 407 -9005963.440556 +426 407 1.192092895508e-07 +427 407 -4.768371582031e-07 +428 407 66375066.93519 +429 407 4.470348358154e-08 +430 407 -4.470348358154e-08 +431 407 -9005963.440553 +495 407 16471527.78319 +496 407 -13177083.33766 +497 407 -28297094.18124 +498 407 65886111.10029 +499 407 3.8743019104e-07 +500 407 -87588646.48668 +501 407 16471527.78319 +502 407 13177083.33766 +503 407 -28297094.18124 +513 407 -9.983777999878e-07 +514 407 -52708333.32467 +515 407 -73187955.04869 +516 407 8.642673492432e-07 +517 407 1.788139343262e-07 +518 407 -190352899.3709 +519 407 1.475214958191e-06 +520 407 52708333.32467 +521 407 -73187955.0487 +534 407 -16471527.78319 +535 407 -13177083.33766 +536 407 -28297094.18124 +537 407 -65886111.10029 +538 407 -2.831220626831e-07 +539 407 -87588646.48668 +540 407 -16471527.78319 +541 407 13177083.33766 +542 407 -28297094.18124 +408 408 913791605.4334 +409 408 7.748603820801e-06 +410 408 -2.622604370117e-06 +411 408 126048980.7912 +412 408 -2.175569534302e-06 +413 408 -1.490116119385e-06 +426 408 -75155545.77471 +427 408 -53333333.32457 +428 408 5.066394805908e-07 +429 408 -198223262.271 +430 408 2.98023223877e-07 +431 408 5.960464477539e-08 +432 408 -75155545.7747 +433 408 53333333.32457 +434 408 -1.490116119385e-08 +498 408 -28555987.69793 +499 408 13333333.33771 +500 408 16471527.78319 +501 408 -88624220.55292 +502 408 1.043081283569e-07 +503 408 65886111.10029 +504 408 -28555987.69793 +505 408 -13333333.33771 +506 408 16471527.78319 +516 408 -7556159.747413 +517 408 -3.278255462646e-07 +518 408 -1.206994056702e-06 +519 408 72174281.7049 +520 408 1.728534698486e-06 +521 408 1.221895217896e-06 +522 408 -7556159.747413 +523 408 -7.450580596924e-07 +524 408 1.341104507446e-06 +537 408 -28555987.69793 +538 408 -13333333.33771 +539 408 -16471527.78319 +540 408 -88624220.55292 +541 408 2.235174179077e-07 +542 408 -65886111.10029 +543 408 -28555987.69793 +544 408 13333333.33771 +545 408 -16471527.78319 +409 409 785785459.402 +410 409 -1.788139343262e-06 +411 409 -2.086162567139e-06 +412 409 -76617423.53181 +413 409 5.066394805908e-07 +426 409 -53333333.32457 +427 409 -59154777.5129 +428 409 2.086162567139e-07 +429 409 3.576278686523e-07 +430 409 36444678.54407 +431 409 -4.172325134277e-07 +432 409 53333333.32457 +433 409 -59154777.5129 +434 409 2.98023223877e-08 +498 409 13333333.33771 +499 409 -24555795.63051 +500 409 -13177083.33766 +501 409 4.470348358154e-08 +502 409 -29957235.32024 +503 409 2.831220626831e-07 +504 409 -13333333.33771 +505 409 -24555795.63051 +506 409 13177083.33766 +516 409 -2.98023223877e-07 +517 409 -58222760.85313 +518 409 -52708333.32467 +519 409 1.728534698486e-06 +520 409 40172745.1813 +521 409 -5.960464477539e-08 +522 409 -7.003545761108e-07 +523 409 -58222760.85313 +524 409 52708333.32467 +537 409 -13333333.33771 +538 409 -24555795.63051 +539 409 -13177083.33766 +540 409 1.9371509552e-07 +541 409 -29957235.32024 +542 409 -3.8743019104e-07 +543 409 13333333.33771 +544 409 -24555795.63051 +545 409 13177083.33766 +410 410 905507012.9075 +411 410 -1.668930053711e-06 +412 410 4.470348358154e-07 +413 410 123977832.6588 +426 410 5.811452865601e-07 +427 410 3.129243850708e-07 +428 410 -9005963.440556 +429 410 1.192092895508e-07 +430 410 -4.768371582031e-07 +431 410 66375066.93519 +432 410 4.470348358154e-08 +433 410 -4.470348358154e-08 +434 410 -9005963.440553 +498 410 16471527.78319 +499 410 -13177083.33766 +500 410 -28297094.18124 +501 410 65886111.10029 +502 410 3.8743019104e-07 +503 410 -87588646.48668 +504 410 16471527.78319 +505 410 13177083.33766 +506 410 -28297094.18124 +516 410 -9.983777999878e-07 +517 410 -52708333.32467 +518 410 -73187955.04869 +519 410 8.642673492432e-07 +520 410 1.788139343262e-07 +521 410 -190352899.3709 +522 410 1.475214958191e-06 +523 410 52708333.32467 +524 410 -73187955.0487 +537 410 -16471527.78319 +538 410 -13177083.33766 +539 410 -28297094.18124 +540 410 -65886111.10029 +541 410 -2.831220626831e-07 +542 410 -87588646.48668 +543 410 -16471527.78319 +544 410 13177083.33766 +545 410 -28297094.18124 +411 411 886076107.088 +412 411 29506578.58962 +413 411 -4.172325134277e-06 +414 411 -15650105.72171 +415 411 -67995305.55008 +416 411 -1.788139343262e-06 +429 411 -75155545.77471 +430 411 -53333333.32457 +431 411 5.066394805908e-07 +432 411 -169993346.4286 +433 411 13585574.37073 +434 411 1.579523086548e-06 +435 411 -49437968.75893 +436 411 49988791.22677 +437 411 2.637505531311e-06 +501 411 -28555987.69793 +502 411 13333333.33771 +503 411 16471527.78319 +504 411 -87310926.38278 +505 411 -6271409.66235 +506 411 57161110.99975 +519 411 -7556159.747413 +520 411 -3.278255462646e-07 +521 411 -1.206994056702e-06 +522 411 87947441.63499 +523 411 7376644.65104 +524 411 0.02039501070976 +525 411 -32923131.70809 +526 411 -16998826.39589 +527 411 16470833.12799 +540 411 -28555987.69793 +541 411 -13333333.33771 +542 411 -16471527.78319 +543 411 -80272721.40676 +544 411 3396393.594356 +545 411 -61522916.65699 +546 411 -22126192.23639 +547 411 12497197.81285 +548 411 -12109027.78175 +412 412 821417136.7999 +413 412 5.125999450684e-06 +414 412 -67995305.33675 +415 412 -205861449.307 +416 412 -3.56137752533e-06 +429 412 -53333333.32457 +430 412 -59154777.5129 +431 412 2.086162567139e-07 +432 412 13585574.37073 +433 412 48420638.98572 +434 412 8.940696716309e-07 +435 412 49988791.22677 +436 412 -80270449.84323 +437 412 -2.548098564148e-06 +501 412 13333333.33771 +502 412 -24555795.63051 +503 412 -13177083.33766 +504 412 -6271409.715683 +505 412 -27822507.01778 +506 412 6197916.651945 +519 412 -2.98023223877e-07 +520 412 -58222760.85313 +521 412 -52708333.32467 +522 412 7376644.65104 +523 412 71782699.055 +524 412 0.01631674170494 +525 412 -16998826.34256 +526 412 -80475967.62785 +527 412 52708333.09468 +540 412 -13333333.33771 +541 412 -24555795.63051 +542 412 -13177083.33766 +543 412 3396393.594355 +544 412 -25669225.02627 +545 412 3489583.332416 +546 412 12497197.81285 +547 412 -29834312.51126 +548 412 16666666.67214 +413 413 843458196.4419 +414 413 1.192092895508e-07 +415 413 -3.039836883545e-06 +416 413 21637954.44543 +429 413 5.811452865601e-07 +430 413 3.129243850708e-07 +431 413 -9005963.440556 +432 413 6.85453414917e-07 +433 413 1.072883605957e-06 +434 413 73680450.86193 +435 413 1.996755599976e-06 +436 413 -2.592802047729e-06 +437 413 -7752033.245933 +501 413 16471527.78319 +502 413 -13177083.33766 +503 413 -28297094.18124 +504 413 57161110.99975 +505 413 6197916.627155 +506 413 -74255038.56586 +519 413 -9.983777999878e-07 +520 413 -52708333.32467 +521 413 -73187955.04869 +522 413 -0.02039638161659 +523 413 -0.01631587743759 +524 413 -145326344.7753 +525 413 16470833.02261 +526 413 52708333.03516 +527 413 -71952125.45461 +540 413 -16471527.78319 +541 413 -13177083.33766 +542 413 -28297094.18124 +543 413 -61522916.65613 +544 413 3489583.333104 +545 413 -82311580.01855 +546 413 -12109027.78175 +547 413 16666666.67214 +548 413 -27982541.75396 +414 414 531775095.0468 +415 414 8503382.432196 +432 414 -80370018.26376 +433 414 -52907761.3966 +434 414 -1.847743988037e-06 +435 414 -113455777.5588 +436 414 18108359.28725 +437 414 1.311302185059e-06 +438 414 68483060.18779 +439 414 -18744593.63382 +440 414 5.960464477539e-07 +441 414 -42329538.80213 +442 414 49035919.29823 +443 414 1.922249794006e-06 +504 414 -11791159.78616 +505 414 15999999.84526 +506 414 14530833.02455 +522 414 -32923131.7081 +523 414 -16998826.34256 +524 414 -16470833.02261 +525 414 14669982.03611 +526 414 2125845.609096 +527 414 12968611.10898 +543 414 -29859204.61641 +544 414 -13226940.35567 +545 414 -16470833.33874 +546 414 -76387958.09069 +547 414 4527089.824043 +548 414 -64843055.54491 +549 414 -11712307.86994 +550 414 -4686148.410764 +551 414 8424305.555742 +552 414 -24181082.63358 +553 414 12258979.8306 +554 414 -15950694.44968 +415 415 626925818.4292 +416 415 3.933906555176e-06 +432 415 -52907761.3966 +433 415 -54873071.8125 +434 415 -8.642673492432e-07 +435 415 18108359.28725 +436 415 97871879.78123 +437 415 3.337860107422e-06 +438 415 2588739.696008 +439 415 -35173186.25688 +440 415 -3.695487976074e-06 +441 415 49035919.29823 +442 415 -49698043.59219 +443 415 -1.505017280579e-06 +504 415 10666666.5635 +505 415 -19475967.87838 +506 415 -14729166.53156 +522 415 -16998826.39589 +523 415 -80475967.62786 +524 415 -52708333.03516 +525 415 2125845.609096 +526 415 38457662.89345 +527 415 3874999.888226 +543 415 -13226940.35567 +544 415 -23484968.00046 +545 415 -13177083.33766 +546 415 4527089.824043 +547 415 -23556043.72965 +548 415 3489583.332417 +549 415 647184.9243208 +550 415 -37626369.49388 +551 415 33333333.32786 +552 415 12258979.8306 +553 415 -26023208.832 +554 415 16666666.67214 +416 416 650521074.3426 +432 416 -1.788139343262e-06 +433 416 -7.748603820801e-07 +434 416 -9261489.102506 +435 416 1.117587089539e-06 +436 416 3.337860107422e-06 +437 416 131575339.2945 +438 416 1.54972076416e-06 +439 416 -3.75509262085e-06 +440 416 90632596.10001 +441 416 2.279877662659e-06 +442 416 -1.594424247742e-06 +443 416 13362532.26789 +504 416 9687222.01637 +505 416 -18604166.53816 +506 416 -23758284.67089 +522 416 -16470833.12799 +523 416 -52708333.09468 +524 416 -71952125.45462 +525 416 -12968611.10898 +526 416 -3874999.888222 +527 416 -152766509.4438 +543 416 -16470833.33874 +544 416 -13177083.33766 +545 416 -28359905.71829 +546 416 -64843055.54491 +547 416 3489583.333105 +548 416 -95170201.65885 +549 416 299305.5539342 +550 416 33333333.32786 +551 416 -54230045.43137 +552 416 -15950694.44968 +553 416 16666666.67214 +554 416 -32922561.4056 +417 417 456895802.7167 +418 417 3.933906555176e-06 +419 417 -1.668930053711e-06 +420 417 63024490.39562 +421 417 10666666.66491 +422 417 -1.013278961182e-06 +507 417 -88624220.55292 +508 417 1.043081283569e-07 +509 417 65886111.10029 +510 417 -28555987.69793 +511 417 -13333333.33771 +512 417 16471527.78319 +528 417 36087140.85245 +529 417 8.344650268555e-07 +530 417 -13177222.22006 +531 417 -3778079.873706 +532 417 2666666.667542 +533 417 -3294305.556637 +418 418 392892729.701 +419 418 -7.152557373047e-07 +420 418 -10666666.66491 +421 418 -38308711.7659 +422 418 3.8743019104e-07 +507 418 4.470348358154e-08 +508 418 -29957235.32024 +509 418 2.831220626831e-07 +510 418 -13333333.33771 +511 418 -24555795.63051 +512 418 13177083.33766 +528 418 8.940696716309e-07 +529 418 20086372.59065 +530 418 -2.98023223877e-08 +531 418 -2666666.667543 +532 418 -29111380.42657 +533 418 26354166.66234 +419 419 452753506.4538 +420 419 -8.940696716309e-07 +421 419 1.490116119385e-07 +422 419 61988916.32938 +507 419 65886111.10029 +508 419 3.8743019104e-07 +509 419 -87588646.48668 +510 419 16471527.78319 +511 419 13177083.33766 +512 419 -28297094.18124 +528 419 13177222.22006 +529 419 1.490116119385e-07 +530 419 -95176449.68545 +531 419 3294305.556638 +532 419 26354166.66234 +533 419 -36593977.52435 +420 420 456895802.7167 +421 420 3.933906555176e-06 +422 420 -1.668930053711e-06 +423 420 63024490.39562 +424 420 10666666.66491 +425 420 -1.013278961182e-06 +507 420 -28555987.69793 +508 420 13333333.33771 +509 420 16471527.78319 +510 420 -88624220.55292 +511 420 1.043081283569e-07 +512 420 65886111.10029 +513 420 -28555987.69793 +514 420 -13333333.33771 +515 420 16471527.78319 +528 420 -3778079.873706 +529 420 -2666666.667542 +530 420 -3294305.556638 +531 420 36087140.85245 +532 420 8.344650268555e-07 +533 420 -13177222.22006 +534 420 -3778079.873706 +535 420 2666666.667542 +536 420 -3294305.556637 +421 421 392892729.701 +422 421 -7.152557373047e-07 +423 421 -10666666.66491 +424 421 -38308711.7659 +425 421 3.8743019104e-07 +507 421 13333333.33771 +508 421 -24555795.63051 +509 421 -13177083.33766 +510 421 4.470348358154e-08 +511 421 -29957235.32024 +512 421 2.831220626831e-07 +513 421 -13333333.33771 +514 421 -24555795.63051 +515 421 13177083.33766 +528 421 2666666.667542 +529 421 -29111380.42657 +530 421 -26354166.66234 +531 421 8.940696716309e-07 +532 421 20086372.59065 +533 421 -2.98023223877e-08 +534 421 -2666666.667543 +535 421 -29111380.42657 +536 421 26354166.66234 +422 422 452753506.4538 +423 422 -8.940696716309e-07 +424 422 1.490116119385e-07 +425 422 61988916.32938 +507 422 16471527.78319 +508 422 -13177083.33766 +509 422 -28297094.18124 +510 422 65886111.10029 +511 422 3.8743019104e-07 +512 422 -87588646.48668 +513 422 16471527.78319 +514 422 13177083.33766 +515 422 -28297094.18124 +528 422 3294305.556637 +529 422 -26354166.66234 +530 422 -36593977.52435 +531 422 13177222.22006 +532 422 1.490116119385e-07 +533 422 -95176449.68545 +534 422 3294305.556638 +535 422 26354166.66234 +536 422 -36593977.52435 +423 423 456895802.7167 +424 423 3.933906555176e-06 +425 423 -1.668930053711e-06 +426 423 63024490.39562 +427 423 10666666.66491 +428 423 -1.013278961182e-06 +510 423 -28555987.69793 +511 423 13333333.33771 +512 423 16471527.78319 +513 423 -88624220.55292 +514 423 1.043081283569e-07 +515 423 65886111.10029 +516 423 -28555987.69793 +517 423 -13333333.33771 +518 423 16471527.78319 +531 423 -3778079.873706 +532 423 -2666666.667542 +533 423 -3294305.556638 +534 423 36087140.85245 +535 423 8.344650268555e-07 +536 423 -13177222.22006 +537 423 -3778079.873706 +538 423 2666666.667542 +539 423 -3294305.556637 +424 424 392892729.701 +425 424 -7.152557373047e-07 +426 424 -10666666.66491 +427 424 -38308711.7659 +428 424 3.8743019104e-07 +510 424 13333333.33771 +511 424 -24555795.63051 +512 424 -13177083.33766 +513 424 4.470348358154e-08 +514 424 -29957235.32024 +515 424 2.831220626831e-07 +516 424 -13333333.33771 +517 424 -24555795.63051 +518 424 13177083.33766 +531 424 2666666.667542 +532 424 -29111380.42657 +533 424 -26354166.66234 +534 424 8.940696716309e-07 +535 424 20086372.59065 +536 424 -2.98023223877e-08 +537 424 -2666666.667543 +538 424 -29111380.42657 +539 424 26354166.66234 +425 425 452753506.4538 +426 425 -8.940696716309e-07 +427 425 1.490116119385e-07 +428 425 61988916.32938 +510 425 16471527.78319 +511 425 -13177083.33766 +512 425 -28297094.18124 +513 425 65886111.10029 +514 425 3.8743019104e-07 +515 425 -87588646.48668 +516 425 16471527.78319 +517 425 13177083.33766 +518 425 -28297094.18124 +531 425 3294305.556637 +532 425 -26354166.66234 +533 425 -36593977.52435 +534 425 13177222.22006 +535 425 1.490116119385e-07 +536 425 -95176449.68545 +537 425 3294305.556638 +538 425 26354166.66234 +539 425 -36593977.52435 +426 426 456895802.7167 +427 426 3.933906555176e-06 +428 426 -1.668930053711e-06 +429 426 63024490.39562 +430 426 10666666.66491 +431 426 -1.013278961182e-06 +513 426 -28555987.69793 +514 426 13333333.33771 +515 426 16471527.78319 +516 426 -88624220.55292 +517 426 1.043081283569e-07 +518 426 65886111.10029 +519 426 -28555987.69793 +520 426 -13333333.33771 +521 426 16471527.78319 +534 426 -3778079.873706 +535 426 -2666666.667542 +536 426 -3294305.556638 +537 426 36087140.85245 +538 426 8.344650268555e-07 +539 426 -13177222.22006 +540 426 -3778079.873706 +541 426 2666666.667542 +542 426 -3294305.556637 +427 427 392892729.701 +428 427 -7.152557373047e-07 +429 427 -10666666.66491 +430 427 -38308711.7659 +431 427 3.8743019104e-07 +513 427 13333333.33771 +514 427 -24555795.63051 +515 427 -13177083.33766 +516 427 4.470348358154e-08 +517 427 -29957235.32024 +518 427 2.831220626831e-07 +519 427 -13333333.33771 +520 427 -24555795.63051 +521 427 13177083.33766 +534 427 2666666.667542 +535 427 -29111380.42657 +536 427 -26354166.66234 +537 427 8.940696716309e-07 +538 427 20086372.59065 +539 427 -2.98023223877e-08 +540 427 -2666666.667543 +541 427 -29111380.42657 +542 427 26354166.66234 +428 428 452753506.4538 +429 428 -8.940696716309e-07 +430 428 1.490116119385e-07 +431 428 61988916.32938 +513 428 16471527.78319 +514 428 -13177083.33766 +515 428 -28297094.18124 +516 428 65886111.10029 +517 428 3.8743019104e-07 +518 428 -87588646.48668 +519 428 16471527.78319 +520 428 13177083.33766 +521 428 -28297094.18124 +534 428 3294305.556637 +535 428 -26354166.66234 +536 428 -36593977.52435 +537 428 13177222.22006 +538 428 1.490116119385e-07 +539 428 -95176449.68545 +540 428 3294305.556638 +541 428 26354166.66234 +542 428 -36593977.52435 +429 429 456895802.7167 +430 429 3.933906555176e-06 +431 429 -1.668930053711e-06 +432 429 63024490.39562 +433 429 10666666.66491 +434 429 -1.013278961182e-06 +516 429 -28555987.69793 +517 429 13333333.33771 +518 429 16471527.78319 +519 429 -88624220.55292 +520 429 1.043081283569e-07 +521 429 65886111.10029 +522 429 -28555987.69793 +523 429 -13333333.33771 +524 429 16471527.78319 +537 429 -3778079.873706 +538 429 -2666666.667542 +539 429 -3294305.556638 +540 429 36087140.85245 +541 429 8.344650268555e-07 +542 429 -13177222.22006 +543 429 -3778079.873706 +544 429 2666666.667542 +545 429 -3294305.556637 +430 430 392892729.701 +431 430 -7.152557373047e-07 +432 430 -10666666.66491 +433 430 -38308711.7659 +434 430 3.8743019104e-07 +516 430 13333333.33771 +517 430 -24555795.63051 +518 430 -13177083.33766 +519 430 4.470348358154e-08 +520 430 -29957235.32024 +521 430 2.831220626831e-07 +522 430 -13333333.33771 +523 430 -24555795.63051 +524 430 13177083.33766 +537 430 2666666.667542 +538 430 -29111380.42657 +539 430 -26354166.66234 +540 430 8.940696716309e-07 +541 430 20086372.59065 +542 430 -2.98023223877e-08 +543 430 -2666666.667543 +544 430 -29111380.42657 +545 430 26354166.66234 +431 431 452753506.4538 +432 431 -8.940696716309e-07 +433 431 1.490116119385e-07 +434 431 61988916.32938 +516 431 16471527.78319 +517 431 -13177083.33766 +518 431 -28297094.18124 +519 431 65886111.10029 +520 431 3.8743019104e-07 +521 431 -87588646.48668 +522 431 16471527.78319 +523 431 13177083.33766 +524 431 -28297094.18124 +537 431 3294305.556637 +538 431 -26354166.66234 +539 431 -36593977.52435 +540 431 13177222.22006 +541 431 1.490116119385e-07 +542 431 -95176449.68545 +543 431 3294305.556638 +544 431 26354166.66234 +545 431 -36593977.52435 +432 432 451672659.2548 +433 432 425457.3069872 +435 432 45227333.73336 +436 432 -3769936.940774 +437 432 5.960464477539e-07 +519 432 -28555987.69793 +520 432 13333333.33771 +521 432 16471527.78319 +522 432 -80272721.40676 +523 432 3396393.594356 +524 432 61522916.65613 +525 432 -29859204.61641 +526 432 -13226940.35567 +527 432 16470833.33874 +540 432 -3778079.873706 +541 432 -2666666.667542 +542 432 -3294305.556638 +543 432 34782980.96289 +544 432 106364.3267991 +545 432 -13176944.44228 +546 432 -9519773.826407 +547 432 -942484.2356579 +548 432 1067638.88752 +433 433 397175038.8898 +434 433 1.072883605957e-06 +435 433 -25103270.2706 +436 433 -58853543.86754 +437 433 -1.341104507446e-06 +519 433 13333333.33771 +520 433 -24555795.63051 +521 433 -13177083.33766 +522 433 3396393.594355 +523 433 -25669225.02627 +524 433 -3489583.333104 +525 433 -13226940.35567 +526 433 -23484968.00045 +527 433 13177083.33766 +540 433 2666666.667542 +541 433 -29111380.42657 +542 433 -26354166.66234 +543 433 106364.3267991 +544 433 21158575.86493 +545 433 2.682209014893e-07 +546 433 -6275817.570742 +547 433 -35539993.23945 +548 433 29843749.99544 +434 434 452492316.5668 +436 434 -1.490116119385e-06 +437 434 55187296.56271 +519 434 16471527.78319 +520 434 -13177083.33766 +521 434 -28297094.18124 +522 434 61522916.65699 +523 434 -3489583.332416 +524 434 -82311580.01855 +525 434 16470833.33874 +526 434 13177083.33766 +527 434 -28359905.71829 +540 434 3294305.556637 +541 434 -26354166.66234 +542 434 -36593977.52435 +543 434 13176944.44228 +544 434 3.8743019104e-07 +545 434 -95237411.21973 +546 434 7655972.222158 +547 434 29843749.99475 +548 434 -41740795.2267 +435 435 444644489.1745 +436 435 13081929.57058 +437 435 9.536743164063e-07 +438 435 -86994427.68368 +439 435 -57630747.35091 +440 435 -2.384185791016e-06 +441 435 44204118.01812 +442 435 1554937.536914 +443 435 -1.192092895508e-06 +522 435 -22126192.23639 +523 435 12497197.81285 +524 435 12109027.78176 +525 435 -76387958.09069 +526 435 4527089.824043 +527 435 64843055.54491 +543 435 -9519773.826409 +544 435 -6275817.570743 +545 435 -7655972.222158 +546 435 15798034.7999 +547 435 3270482.394257 +548 435 -12968611.10898 +549 435 -35347304.85947 +550 435 -14407686.84483 +551 435 20312500.00667 +552 435 -14510689.24923 +553 435 388734.3844201 +554 435 1171666.664472 +436 436 449754245.7917 +437 436 4.64916229248e-06 +438 436 -57630747.35091 +439 436 -66447376.92277 +440 436 -1.296401023865e-06 +441 436 -19778395.79291 +442 436 -57866988.0148 +443 436 -2.086162567139e-06 +522 436 12497197.81285 +523 436 -29834312.51127 +524 436 -16666666.67214 +525 436 4527089.824043 +526 436 -23556043.72965 +527 436 -3489583.333103 +543 436 -942484.2356579 +544 436 -35539993.23945 +545 436 -29843749.99475 +546 436 3270482.394257 +547 436 17075473.95481 +548 436 9.536743164063e-07 +549 436 -14407686.84483 +550 436 -30210542.16671 +551 436 16666666.67214 +552 436 -4944598.950664 +553 436 -40028465.77003 +554 436 33333333.32786 +437 437 513640710.6392 +438 437 -3.159046173096e-06 +439 437 -1.370906829834e-06 +440 437 -3386801.062691 +441 437 -1.907348632813e-06 +442 437 -2.235174179077e-06 +443 437 68569532.94435 +522 437 12109027.78176 +523 437 -16666666.67214 +524 437 -27982541.75396 +525 437 64843055.54491 +526 437 -3489583.332416 +527 437 -95170201.65886 +543 437 -1067638.887521 +544 437 -29843749.99544 +545 437 -41740795.22671 +546 437 12968611.10898 +547 437 1.013278961182e-06 +548 437 -125891389.0729 +549 437 20312500.00667 +550 437 16666666.67214 +551 437 -37109894.74031 +552 437 7551944.445205 +553 437 33333333.32786 +554 437 -51022200.11333 +438 438 254849231.4225 +439 438 61411260.29348 +440 438 3.814697265625e-06 +441 438 -66610780.59762 +442 438 -6369252.63857 +443 438 -1.132488250732e-06 +525 438 -11712307.86995 +526 438 647184.9243208 +527 438 -299305.5539346 +546 438 -35347304.85947 +547 438 -14407686.84483 +548 438 -20312500.00667 +549 438 6046162.064774 +550 438 15352815.08093 +551 438 8124999.998666 +552 438 -43850090.99987 +553 438 -1592313.160427 +554 438 -36263194.43806 +439 439 228505477.8886 +440 439 4.172325134277e-06 +441 439 14964080.69126 +442 439 42842168.62011 +443 439 1.728534698486e-06 +525 439 -4686148.410764 +526 439 -37626369.49388 +527 439 -33333333.32786 +546 439 -14407686.84483 +547 439 -30210542.16671 +548 439 -16666666.67214 +549 439 15352815.08093 +550 439 -539776.3219635 +551 439 6666666.665572 +552 439 3741020.174657 +553 439 -16486853.68196 +554 439 3333333.334428 +440 440 294920181.6058 +442 440 1.788139343262e-06 +443 440 70439578.90092 +525 440 -8424305.555743 +526 440 -33333333.32786 +527 440 -54230045.43139 +546 440 -20312500.00667 +547 440 -16666666.67214 +548 440 -37109894.74031 +549 440 -8124999.998665 +550 440 -6666666.665571 +551 440 -80046343.42155 +552 440 -36263194.43892 +553 440 -3333333.334428 +554 440 -54916494.1788 +441 441 221377868.0526 +442 441 -44221604.19657 +443 441 -1.311302185059e-06 +525 441 -24181082.63358 +526 441 12258979.8306 +527 441 15950694.44968 +546 441 -14510689.24923 +547 441 -4944598.950664 +548 441 -7551944.445206 +549 441 -43850090.99987 +550 441 3741020.174657 +551 441 36263194.43892 +552 441 4221029.5472 +553 441 -11055401.05459 +554 441 -6380277.77673 +442 442 221364529.6578 +443 442 2.861022949219e-06 +525 442 12258979.8306 +526 442 -26023208.832 +527 442 -16666666.67214 +546 442 388734.38442 +547 442 -40028465.77003 +548 442 -33333333.32786 +549 442 -1592313.160427 +550 442 -16486853.68196 +551 442 3333333.334428 +552 442 -11055401.05459 +553 442 4217694.948508 +554 442 6666666.665572 +443 443 265339467.0094 +525 443 15950694.44968 +526 443 -16666666.67214 +527 443 -32922561.4056 +546 443 -1171666.664473 +547 443 -33333333.32786 +548 443 -51022200.11334 +549 443 36263194.43806 +550 443 -3333333.334428 +551 443 -54916494.1788 +552 443 6380277.77673 +553 443 -6666666.665571 +554 443 -69994299.86354 +444 444 571119749.839 +445 444 53333333.32457 +446 444 -6.198883056641e-06 +447 444 -292913008.3249 +448 444 -53333332.8979 +449 444 6.556510925293e-06 +450 444 19534202.10867 +451 444 42666666.23299 +452 444 -1.490116119385e-06 +555 444 45108925.89256 +556 444 13333333.33771 +557 444 13177222.19231 +558 444 -107413106.5112 +559 444 -13333333.23104 +560 444 -65886110.96157 +561 444 -9767101.054335 +562 444 10666666.5635 +563 444 -13177221.94221 +445 445 491115909.0416 +446 445 -3.094097220493e-06 +447 445 -53333332.68457 +448 445 -42244300.58137 +449 445 2.145767211914e-06 +450 445 63999999.34949 +451 445 19534202.10866 +452 445 -2.384185791016e-06 +555 445 13333333.33771 +556 445 25107965.68335 +557 445 10541666.55379 +558 445 -13333333.17771 +559 445 -44745929.54446 +560 445 -13177083.26329 +561 445 15999999.84525 +562 445 -9767101.054335 +563 445 15812499.93082 +446 446 565941879.2302 +447 446 6.943941116333e-06 +448 446 1.609325408936e-06 +449 446 5277897.861165 +450 446 -2.145767211914e-06 +451 446 -1.54972076416e-06 +452 446 52091205.62311 +555 446 -13177222.19232 +556 446 -10541666.5538 +557 446 -118970561.1562 +558 446 -65886110.96157 +559 446 -13177083.28808 +560 446 -89840137.25117 +561 446 -19765832.91331 +562 446 10541666.62055 +563 446 -26045602.81156 +447 447 988947148.5376 +448 447 53333332.25791 +449 447 -9.298324584961e-06 +450 447 31359232.67644 +451 447 -53333332.8979 +452 447 1.251697540283e-06 +453 447 -198223262.271 +454 447 2.98023223877e-07 +455 447 5.960464477539e-08 +456 447 -75155545.7747 +457 447 53333333.32457 +458 447 -1.490116119385e-08 +555 447 -107413106.5112 +556 447 -13333333.17771 +557 447 65886110.96157 +558 447 100730268.7541 +559 447 13333333.07105 +560 447 0.02774140238762 +561 447 -26345045.89131 +562 447 -13333333.23105 +563 447 16471527.49884 +564 447 -88624220.55292 +565 447 2.235174179077e-07 +566 447 -65886111.10029 +567 447 -28555987.69793 +568 447 13333333.33771 +569 447 -16471527.78319 +448 448 844940234.7245 +449 448 -7.987022399902e-06 +450 448 -53333332.68457 +451 448 -155306402.5315 +452 448 5.394220352173e-06 +453 448 3.576278686523e-07 +454 448 36444678.54407 +455 448 -4.172325134277e-07 +456 448 53333333.32457 +457 448 -59154777.5129 +458 448 2.98023223877e-08 +555 448 -13333333.23104 +556 448 -44745929.54447 +557 448 13177083.28808 +558 448 13333333.07105 +559 448 64728540.28304 +560 448 0.022192299366 +561 448 -13333333.17771 +562 448 -73011454.71628 +563 448 52708333.03581 +564 448 1.9371509552e-07 +565 448 -29957235.32024 +566 448 -3.8743019104e-07 +567 448 13333333.33771 +568 448 -24555795.63051 +569 448 13177083.33766 +449 449 914512974.9691 +450 449 1.728534698486e-06 +451 449 4.559755325317e-06 +452 449 62880662.12465 +453 449 1.192092895508e-07 +454 449 -4.768371582031e-07 +455 449 66375066.93519 +456 449 4.470348358154e-08 +457 449 -4.470348358154e-08 +458 449 -9005963.440553 +555 449 65886110.96157 +556 449 13177083.26329 +557 449 -89840137.25118 +558 449 -0.0277450978756 +559 449 -0.02219566702843 +560 449 -162055805.4842 +561 449 16471527.35667 +562 449 52708332.94687 +563 449 -75439445.29918 +564 449 -65886111.10029 +565 449 -2.831220626831e-07 +566 449 -87588646.48668 +567 449 -16471527.78319 +568 449 13177083.33766 +569 449 -28297094.18124 +450 450 571119749.839 +451 450 53333333.32457 +452 450 -6.198883056641e-06 +453 450 -75155545.77471 +454 450 -53333333.32457 +455 450 5.066394805908e-07 +456 450 -292913008.3249 +457 450 -53333332.8979 +458 450 6.556510925293e-06 +459 450 19534202.10867 +460 450 42666666.23299 +461 450 -1.490116119385e-06 +555 450 -9767101.054335 +556 450 15999999.84525 +557 450 19765832.91331 +558 450 -26345045.8913 +559 450 -13333333.17771 +560 450 -16471527.35667 +561 450 45108925.89256 +562 450 13333333.33771 +563 450 13177222.19231 +564 450 -28555987.69793 +565 450 -13333333.33771 +566 450 -16471527.78319 +567 450 -107413106.5112 +568 450 -13333333.23104 +569 450 -65886110.96157 +570 450 -9767101.054335 +571 450 10666666.5635 +572 450 -13177221.94221 +451 451 491115909.0416 +452 451 -2.974887930942e-06 +453 451 -53333333.32457 +454 451 -59154777.5129 +455 451 2.086162567139e-07 +456 451 -53333332.68457 +457 451 -42244300.58137 +458 451 2.145767211914e-06 +459 451 63999999.34949 +460 451 19534202.10866 +461 451 -2.384185791016e-06 +555 451 10666666.5635 +556 451 -9767101.054336 +557 451 -10541666.62055 +558 451 -13333333.23105 +559 451 -73011454.71627 +560 451 -52708332.94687 +561 451 13333333.33771 +562 451 25107965.68335 +563 451 10541666.55379 +564 451 -13333333.33771 +565 451 -24555795.63051 +566 451 -13177083.33766 +567 451 -13333333.17771 +568 451 -44745929.54446 +569 451 -13177083.26329 +570 451 15999999.84525 +571 451 -9767101.054335 +572 451 15812499.93082 +452 452 565941879.2302 +453 452 5.811452865601e-07 +454 452 3.129243850708e-07 +455 452 -9005963.440556 +456 452 6.943941116333e-06 +457 452 1.609325408936e-06 +458 452 5277897.861165 +459 452 -2.145767211914e-06 +460 452 -1.54972076416e-06 +461 452 52091205.62311 +555 452 13177221.94221 +556 452 -15812499.93082 +557 452 -26045602.81156 +558 452 -16471527.49884 +559 452 -52708333.03581 +560 452 -75439445.29917 +561 452 -13177222.19232 +562 452 -10541666.5538 +563 452 -118970561.1562 +564 452 -16471527.78319 +565 452 -13177083.33766 +566 452 -28297094.18124 +567 452 -65886110.96157 +568 452 -13177083.28808 +569 452 -89840137.25117 +570 452 -19765832.91331 +571 452 10541666.62055 +572 452 -26045602.81156 +453 453 913791605.4334 +454 453 7.748603820801e-06 +455 453 -2.622604370117e-06 +456 453 126048980.7912 +457 453 -2.175569534302e-06 +458 453 -1.490116119385e-06 +462 453 -198223262.271 +463 453 2.98023223877e-07 +464 453 5.960464477539e-08 +465 453 -75155545.7747 +466 453 53333333.32457 +467 453 -1.490116119385e-08 +558 453 -88624220.55292 +559 453 1.043081283569e-07 +560 453 65886111.10029 +561 453 -28555987.69793 +562 453 -13333333.33771 +563 453 16471527.78319 +564 453 72174281.7049 +565 453 1.728534698486e-06 +566 453 1.221895217896e-06 +567 453 -7556159.747413 +568 453 -7.450580596924e-07 +569 453 1.341104507446e-06 +573 453 -88624220.55292 +574 453 2.235174179077e-07 +575 453 -65886111.10029 +576 453 -28555987.69793 +577 453 13333333.33771 +578 453 -16471527.78319 +454 454 785785459.402 +455 454 -1.788139343262e-06 +456 454 -2.086162567139e-06 +457 454 -76617423.53181 +458 454 5.066394805908e-07 +462 454 3.576278686523e-07 +463 454 36444678.54407 +464 454 -4.172325134277e-07 +465 454 53333333.32457 +466 454 -59154777.5129 +467 454 2.98023223877e-08 +558 454 4.470348358154e-08 +559 454 -29957235.32024 +560 454 2.831220626831e-07 +561 454 -13333333.33771 +562 454 -24555795.63051 +563 454 13177083.33766 +564 454 1.728534698486e-06 +565 454 40172745.1813 +566 454 -5.960464477539e-08 +567 454 -7.003545761108e-07 +568 454 -58222760.85313 +569 454 52708333.32467 +573 454 1.9371509552e-07 +574 454 -29957235.32024 +575 454 -3.8743019104e-07 +576 454 13333333.33771 +577 454 -24555795.63051 +578 454 13177083.33766 +455 455 905507012.9075 +456 455 -1.668930053711e-06 +457 455 4.470348358154e-07 +458 455 123977832.6588 +462 455 1.192092895508e-07 +463 455 -4.768371582031e-07 +464 455 66375066.93519 +465 455 4.470348358154e-08 +466 455 -4.470348358154e-08 +467 455 -9005963.440553 +558 455 65886111.10029 +559 455 3.8743019104e-07 +560 455 -87588646.48668 +561 455 16471527.78319 +562 455 13177083.33766 +563 455 -28297094.18124 +564 455 8.642673492432e-07 +565 455 1.788139343262e-07 +566 455 -190352899.3709 +567 455 1.475214958191e-06 +568 455 52708333.32467 +569 455 -73187955.0487 +573 455 -65886111.10029 +574 455 -2.831220626831e-07 +575 455 -87588646.48668 +576 455 -16471527.78319 +577 455 13177083.33766 +578 455 -28297094.18124 +456 456 988947148.5376 +457 456 53333332.25791 +458 456 -9.298324584961e-06 +459 456 31359232.67644 +460 456 -53333332.8979 +461 456 1.251697540283e-06 +462 456 -75155545.77471 +463 456 -53333333.32457 +464 456 5.066394805908e-07 +465 456 -198223262.271 +466 456 2.98023223877e-07 +467 456 5.960464477539e-08 +468 456 -75155545.7747 +469 456 53333333.32457 +470 456 -1.490116119385e-08 +558 456 -28555987.69793 +559 456 13333333.33771 +560 456 16471527.78319 +561 456 -107413106.5112 +562 456 -13333333.17771 +563 456 65886110.96157 +564 456 -7556159.747413 +565 456 -3.278255462646e-07 +566 456 -1.206994056702e-06 +567 456 100730268.7541 +568 456 13333333.07105 +569 456 0.02774140238762 +570 456 -26345045.89131 +571 456 -13333333.23105 +572 456 16471527.49884 +573 456 -28555987.69793 +574 456 -13333333.33771 +575 456 -16471527.78319 +576 456 -88624220.55292 +577 456 2.235174179077e-07 +578 456 -65886111.10029 +579 456 -28555987.69793 +580 456 13333333.33771 +581 456 -16471527.78319 +457 457 844940234.7245 +458 457 -7.987022399902e-06 +459 457 -53333332.68457 +460 457 -155306402.5315 +461 457 5.394220352173e-06 +462 457 -53333333.32457 +463 457 -59154777.5129 +464 457 2.086162567139e-07 +465 457 3.576278686523e-07 +466 457 36444678.54407 +467 457 -4.172325134277e-07 +468 457 53333333.32457 +469 457 -59154777.5129 +470 457 2.98023223877e-08 +558 457 13333333.33771 +559 457 -24555795.63051 +560 457 -13177083.33766 +561 457 -13333333.23104 +562 457 -44745929.54447 +563 457 13177083.28808 +564 457 -2.98023223877e-07 +565 457 -58222760.85313 +566 457 -52708333.32467 +567 457 13333333.07105 +568 457 64728540.28304 +569 457 0.022192299366 +570 457 -13333333.17771 +571 457 -73011454.71628 +572 457 52708333.03581 +573 457 -13333333.33771 +574 457 -24555795.63051 +575 457 -13177083.33766 +576 457 1.9371509552e-07 +577 457 -29957235.32024 +578 457 -3.8743019104e-07 +579 457 13333333.33771 +580 457 -24555795.63051 +581 457 13177083.33766 +458 458 914512974.9691 +459 458 1.728534698486e-06 +460 458 4.559755325317e-06 +461 458 62880662.12465 +462 458 5.811452865601e-07 +463 458 3.129243850708e-07 +464 458 -9005963.440556 +465 458 1.192092895508e-07 +466 458 -4.768371582031e-07 +467 458 66375066.93519 +468 458 4.470348358154e-08 +469 458 -4.470348358154e-08 +470 458 -9005963.440553 +558 458 16471527.78319 +559 458 -13177083.33766 +560 458 -28297094.18124 +561 458 65886110.96157 +562 458 13177083.26329 +563 458 -89840137.25118 +564 458 -9.983777999878e-07 +565 458 -52708333.32467 +566 458 -73187955.04869 +567 458 -0.0277450978756 +568 458 -0.02219566702843 +569 458 -162055805.4842 +570 458 16471527.35667 +571 458 52708332.94687 +572 458 -75439445.29918 +573 458 -16471527.78319 +574 458 -13177083.33766 +575 458 -28297094.18124 +576 458 -65886111.10029 +577 458 -2.831220626831e-07 +578 458 -87588646.48668 +579 458 -16471527.78319 +580 458 13177083.33766 +581 458 -28297094.18124 +459 459 571119749.839 +460 459 53333333.32457 +461 459 -6.198883056641e-06 +465 459 -75155545.77471 +466 459 -53333333.32457 +467 459 5.066394805908e-07 +468 459 -292913008.3249 +469 459 -53333332.8979 +470 459 6.556510925293e-06 +471 459 19534202.10867 +472 459 42666666.23299 +473 459 -1.490116119385e-06 +561 459 -9767101.054335 +562 459 15999999.84525 +563 459 19765832.91331 +567 459 -26345045.8913 +568 459 -13333333.17771 +569 459 -16471527.35667 +570 459 45108925.89256 +571 459 13333333.33771 +572 459 13177222.19231 +576 459 -28555987.69793 +577 459 -13333333.33771 +578 459 -16471527.78319 +579 459 -107413106.5112 +580 459 -13333333.23104 +581 459 -65886110.96157 +582 459 -9767101.054335 +583 459 10666666.5635 +584 459 -13177221.94221 +460 460 491115909.0416 +461 460 -2.974887930942e-06 +465 460 -53333333.32457 +466 460 -59154777.5129 +467 460 2.086162567139e-07 +468 460 -53333332.68457 +469 460 -42244300.58137 +470 460 2.145767211914e-06 +471 460 63999999.34949 +472 460 19534202.10866 +473 460 -2.384185791016e-06 +561 460 10666666.5635 +562 460 -9767101.054336 +563 460 -10541666.62055 +567 460 -13333333.23105 +568 460 -73011454.71627 +569 460 -52708332.94687 +570 460 13333333.33771 +571 460 25107965.68335 +572 460 10541666.55379 +576 460 -13333333.33771 +577 460 -24555795.63051 +578 460 -13177083.33766 +579 460 -13333333.17771 +580 460 -44745929.54446 +581 460 -13177083.26329 +582 460 15999999.84525 +583 460 -9767101.054335 +584 460 15812499.93082 +461 461 565941879.2302 +465 461 5.811452865601e-07 +466 461 3.129243850708e-07 +467 461 -9005963.440556 +468 461 6.943941116333e-06 +469 461 1.609325408936e-06 +470 461 5277897.861165 +471 461 -2.145767211914e-06 +472 461 -1.54972076416e-06 +473 461 52091205.62311 +561 461 13177221.94221 +562 461 -15812499.93082 +563 461 -26045602.81156 +567 461 -16471527.49884 +568 461 -52708333.03581 +569 461 -75439445.29917 +570 461 -13177222.19232 +571 461 -10541666.5538 +572 461 -118970561.1562 +576 461 -16471527.78319 +577 461 -13177083.33766 +578 461 -28297094.18124 +579 461 -65886110.96157 +580 461 -13177083.28808 +581 461 -89840137.25117 +582 461 -19765832.91331 +583 461 10541666.62055 +584 461 -26045602.81156 +462 462 913791605.4334 +463 462 7.748603820801e-06 +464 462 -2.622604370117e-06 +465 462 126048980.7912 +466 462 -2.175569534302e-06 +467 462 -1.490116119385e-06 +474 462 -198223262.271 +475 462 2.98023223877e-07 +476 462 5.960464477539e-08 +477 462 -75155545.7747 +478 462 53333333.32457 +479 462 -1.490116119385e-08 +564 462 -88624220.55292 +565 462 1.043081283569e-07 +566 462 65886111.10029 +567 462 -28555987.69793 +568 462 -13333333.33771 +569 462 16471527.78319 +573 462 72174281.7049 +574 462 1.728534698486e-06 +575 462 1.221895217896e-06 +576 462 -7556159.747413 +577 462 -7.450580596924e-07 +578 462 1.341104507446e-06 +585 462 -88624220.55292 +586 462 2.235174179077e-07 +587 462 -65886111.10029 +588 462 -28555987.69793 +589 462 13333333.33771 +590 462 -16471527.78319 +463 463 785785459.402 +464 463 -1.788139343262e-06 +465 463 -2.086162567139e-06 +466 463 -76617423.53181 +467 463 5.066394805908e-07 +474 463 3.576278686523e-07 +475 463 36444678.54407 +476 463 -4.172325134277e-07 +477 463 53333333.32457 +478 463 -59154777.5129 +479 463 2.98023223877e-08 +564 463 4.470348358154e-08 +565 463 -29957235.32024 +566 463 2.831220626831e-07 +567 463 -13333333.33771 +568 463 -24555795.63051 +569 463 13177083.33766 +573 463 1.728534698486e-06 +574 463 40172745.1813 +575 463 -5.960464477539e-08 +576 463 -7.003545761108e-07 +577 463 -58222760.85313 +578 463 52708333.32467 +585 463 1.9371509552e-07 +586 463 -29957235.32024 +587 463 -3.8743019104e-07 +588 463 13333333.33771 +589 463 -24555795.63051 +590 463 13177083.33766 +464 464 905507012.9075 +465 464 -1.668930053711e-06 +466 464 4.470348358154e-07 +467 464 123977832.6588 +474 464 1.192092895508e-07 +475 464 -4.768371582031e-07 +476 464 66375066.93519 +477 464 4.470348358154e-08 +478 464 -4.470348358154e-08 +479 464 -9005963.440553 +564 464 65886111.10029 +565 464 3.8743019104e-07 +566 464 -87588646.48668 +567 464 16471527.78319 +568 464 13177083.33766 +569 464 -28297094.18124 +573 464 8.642673492432e-07 +574 464 1.788139343262e-07 +575 464 -190352899.3709 +576 464 1.475214958191e-06 +577 464 52708333.32467 +578 464 -73187955.0487 +585 464 -65886111.10029 +586 464 -2.831220626831e-07 +587 464 -87588646.48668 +588 464 -16471527.78319 +589 464 13177083.33766 +590 464 -28297094.18124 +465 465 913791605.4334 +466 465 7.748603820801e-06 +467 465 -2.622604370117e-06 +468 465 126048980.7912 +469 465 -2.175569534302e-06 +470 465 -1.490116119385e-06 +474 465 -75155545.77471 +475 465 -53333333.32457 +476 465 5.066394805908e-07 +477 465 -198223262.271 +478 465 2.98023223877e-07 +479 465 5.960464477539e-08 +480 465 -75155545.7747 +481 465 53333333.32457 +482 465 -1.490116119385e-08 +564 465 -28555987.69793 +565 465 13333333.33771 +566 465 16471527.78319 +567 465 -88624220.55292 +568 465 1.043081283569e-07 +569 465 65886111.10029 +570 465 -28555987.69793 +571 465 -13333333.33771 +572 465 16471527.78319 +573 465 -7556159.747413 +574 465 -3.278255462646e-07 +575 465 -1.206994056702e-06 +576 465 72174281.7049 +577 465 1.728534698486e-06 +578 465 1.221895217896e-06 +579 465 -7556159.747413 +580 465 -7.450580596924e-07 +581 465 1.341104507446e-06 +585 465 -28555987.69793 +586 465 -13333333.33771 +587 465 -16471527.78319 +588 465 -88624220.55292 +589 465 2.235174179077e-07 +590 465 -65886111.10029 +591 465 -28555987.69793 +592 465 13333333.33771 +593 465 -16471527.78319 +466 466 785785459.402 +467 466 -1.788139343262e-06 +468 466 -2.086162567139e-06 +469 466 -76617423.53181 +470 466 5.066394805908e-07 +474 466 -53333333.32457 +475 466 -59154777.5129 +476 466 2.086162567139e-07 +477 466 3.576278686523e-07 +478 466 36444678.54407 +479 466 -4.172325134277e-07 +480 466 53333333.32457 +481 466 -59154777.5129 +482 466 2.98023223877e-08 +564 466 13333333.33771 +565 466 -24555795.63051 +566 466 -13177083.33766 +567 466 4.470348358154e-08 +568 466 -29957235.32024 +569 466 2.831220626831e-07 +570 466 -13333333.33771 +571 466 -24555795.63051 +572 466 13177083.33766 +573 466 -2.98023223877e-07 +574 466 -58222760.85313 +575 466 -52708333.32467 +576 466 1.728534698486e-06 +577 466 40172745.1813 +578 466 -5.960464477539e-08 +579 466 -7.003545761108e-07 +580 466 -58222760.85313 +581 466 52708333.32467 +585 466 -13333333.33771 +586 466 -24555795.63051 +587 466 -13177083.33766 +588 466 1.9371509552e-07 +589 466 -29957235.32024 +590 466 -3.8743019104e-07 +591 466 13333333.33771 +592 466 -24555795.63051 +593 466 13177083.33766 +467 467 905507012.9075 +468 467 -1.668930053711e-06 +469 467 4.470348358154e-07 +470 467 123977832.6588 +474 467 5.811452865601e-07 +475 467 3.129243850708e-07 +476 467 -9005963.440556 +477 467 1.192092895508e-07 +478 467 -4.768371582031e-07 +479 467 66375066.93519 +480 467 4.470348358154e-08 +481 467 -4.470348358154e-08 +482 467 -9005963.440553 +564 467 16471527.78319 +565 467 -13177083.33766 +566 467 -28297094.18124 +567 467 65886111.10029 +568 467 3.8743019104e-07 +569 467 -87588646.48668 +570 467 16471527.78319 +571 467 13177083.33766 +572 467 -28297094.18124 +573 467 -9.983777999878e-07 +574 467 -52708333.32467 +575 467 -73187955.04869 +576 467 8.642673492432e-07 +577 467 1.788139343262e-07 +578 467 -190352899.3709 +579 467 1.475214958191e-06 +580 467 52708333.32467 +581 467 -73187955.0487 +585 467 -16471527.78319 +586 467 -13177083.33766 +587 467 -28297094.18124 +588 467 -65886111.10029 +589 467 -2.831220626831e-07 +590 467 -87588646.48668 +591 467 -16471527.78319 +592 467 13177083.33766 +593 467 -28297094.18124 +468 468 988947148.5376 +469 468 53333332.25791 +470 468 -9.298324584961e-06 +471 468 31359232.67644 +472 468 -53333332.8979 +473 468 1.251697540283e-06 +477 468 -75155545.77471 +478 468 -53333333.32457 +479 468 5.066394805908e-07 +480 468 -198223262.271 +481 468 2.98023223877e-07 +482 468 5.960464477539e-08 +483 468 -75155545.7747 +484 468 53333333.32457 +485 468 -1.490116119385e-08 +567 468 -28555987.69793 +568 468 13333333.33771 +569 468 16471527.78319 +570 468 -107413106.5112 +571 468 -13333333.17771 +572 468 65886110.96157 +576 468 -7556159.747413 +577 468 -3.278255462646e-07 +578 468 -1.206994056702e-06 +579 468 100730268.7541 +580 468 13333333.07105 +581 468 0.02774140238762 +582 468 -26345045.89131 +583 468 -13333333.23105 +584 468 16471527.49884 +588 468 -28555987.69793 +589 468 -13333333.33771 +590 468 -16471527.78319 +591 468 -88624220.55292 +592 468 2.235174179077e-07 +593 468 -65886111.10029 +594 468 -28555987.69793 +595 468 13333333.33771 +596 468 -16471527.78319 +469 469 844940234.7245 +470 469 -7.987022399902e-06 +471 469 -53333332.68457 +472 469 -155306402.5315 +473 469 5.394220352173e-06 +477 469 -53333333.32457 +478 469 -59154777.5129 +479 469 2.086162567139e-07 +480 469 3.576278686523e-07 +481 469 36444678.54407 +482 469 -4.172325134277e-07 +483 469 53333333.32457 +484 469 -59154777.5129 +485 469 2.98023223877e-08 +567 469 13333333.33771 +568 469 -24555795.63051 +569 469 -13177083.33766 +570 469 -13333333.23104 +571 469 -44745929.54447 +572 469 13177083.28808 +576 469 -2.98023223877e-07 +577 469 -58222760.85313 +578 469 -52708333.32467 +579 469 13333333.07105 +580 469 64728540.28304 +581 469 0.022192299366 +582 469 -13333333.17771 +583 469 -73011454.71628 +584 469 52708333.03581 +588 469 -13333333.33771 +589 469 -24555795.63051 +590 469 -13177083.33766 +591 469 1.9371509552e-07 +592 469 -29957235.32024 +593 469 -3.8743019104e-07 +594 469 13333333.33771 +595 469 -24555795.63051 +596 469 13177083.33766 +470 470 914512974.9691 +471 470 1.728534698486e-06 +472 470 4.559755325317e-06 +473 470 62880662.12465 +477 470 5.811452865601e-07 +478 470 3.129243850708e-07 +479 470 -9005963.440556 +480 470 1.192092895508e-07 +481 470 -4.768371582031e-07 +482 470 66375066.93519 +483 470 4.470348358154e-08 +484 470 -4.470348358154e-08 +485 470 -9005963.440553 +567 470 16471527.78319 +568 470 -13177083.33766 +569 470 -28297094.18124 +570 470 65886110.96157 +571 470 13177083.26329 +572 470 -89840137.25118 +576 470 -9.983777999878e-07 +577 470 -52708333.32467 +578 470 -73187955.04869 +579 470 -0.0277450978756 +580 470 -0.02219566702843 +581 470 -162055805.4842 +582 470 16471527.35667 +583 470 52708332.94687 +584 470 -75439445.29918 +588 470 -16471527.78319 +589 470 -13177083.33766 +590 470 -28297094.18124 +591 470 -65886111.10029 +592 470 -2.831220626831e-07 +593 470 -87588646.48668 +594 470 -16471527.78319 +595 470 13177083.33766 +596 470 -28297094.18124 +471 471 571119749.839 +472 471 53333333.32457 +473 471 -6.198883056641e-06 +480 471 -75155545.77471 +481 471 -53333333.32457 +482 471 5.066394805908e-07 +483 471 -292913008.3249 +484 471 -53333332.8979 +485 471 6.556510925293e-06 +486 471 19534202.10867 +487 471 42666666.23299 +488 471 -1.490116119385e-06 +570 471 -9767101.054335 +571 471 15999999.84525 +572 471 19765832.91331 +579 471 -26345045.8913 +580 471 -13333333.17771 +581 471 -16471527.35667 +582 471 45108925.89256 +583 471 13333333.33771 +584 471 13177222.19231 +591 471 -28555987.69793 +592 471 -13333333.33771 +593 471 -16471527.78319 +594 471 -107413106.5112 +595 471 -13333333.23104 +596 471 -65886110.96157 +597 471 -9767101.054335 +598 471 10666666.5635 +599 471 -13177221.94221 +472 472 491115909.0416 +473 472 -2.974887930942e-06 +480 472 -53333333.32457 +481 472 -59154777.5129 +482 472 2.086162567139e-07 +483 472 -53333332.68457 +484 472 -42244300.58137 +485 472 2.145767211914e-06 +486 472 63999999.34949 +487 472 19534202.10866 +488 472 -2.384185791016e-06 +570 472 10666666.5635 +571 472 -9767101.054336 +572 472 -10541666.62055 +579 472 -13333333.23105 +580 472 -73011454.71627 +581 472 -52708332.94687 +582 472 13333333.33771 +583 472 25107965.68335 +584 472 10541666.55379 +591 472 -13333333.33771 +592 472 -24555795.63051 +593 472 -13177083.33766 +594 472 -13333333.17771 +595 472 -44745929.54446 +596 472 -13177083.26329 +597 472 15999999.84525 +598 472 -9767101.054335 +599 472 15812499.93082 +473 473 565941879.2302 +480 473 5.811452865601e-07 +481 473 3.129243850708e-07 +482 473 -9005963.440556 +483 473 6.943941116333e-06 +484 473 1.609325408936e-06 +485 473 5277897.861165 +486 473 -2.145767211914e-06 +487 473 -1.54972076416e-06 +488 473 52091205.62311 +570 473 13177221.94221 +571 473 -15812499.93082 +572 473 -26045602.81156 +579 473 -16471527.49884 +580 473 -52708333.03581 +581 473 -75439445.29917 +582 473 -13177222.19232 +583 473 -10541666.5538 +584 473 -118970561.1562 +591 473 -16471527.78319 +592 473 -13177083.33766 +593 473 -28297094.18124 +594 473 -65886110.96157 +595 473 -13177083.28808 +596 473 -89840137.25117 +597 473 -19765832.91331 +598 473 10541666.62055 +599 473 -26045602.81156 +474 474 913791605.4334 +475 474 7.748603820801e-06 +476 474 -2.622604370117e-06 +477 474 126048980.7912 +478 474 -2.175569534302e-06 +479 474 -1.490116119385e-06 +489 474 -198223262.271 +490 474 2.98023223877e-07 +491 474 5.960464477539e-08 +492 474 -75155545.7747 +493 474 53333333.32457 +494 474 -1.490116119385e-08 +573 474 -88624220.55292 +574 474 1.043081283569e-07 +575 474 65886111.10029 +576 474 -28555987.69793 +577 474 -13333333.33771 +578 474 16471527.78319 +585 474 72174281.7049 +586 474 1.728534698486e-06 +587 474 1.221895217896e-06 +588 474 -7556159.747413 +589 474 -7.450580596924e-07 +590 474 1.341104507446e-06 +600 474 -88624220.55292 +601 474 2.235174179077e-07 +602 474 -65886111.10029 +603 474 -28555987.69793 +604 474 13333333.33771 +605 474 -16471527.78319 +475 475 785785459.402 +476 475 -1.788139343262e-06 +477 475 -2.086162567139e-06 +478 475 -76617423.53181 +479 475 5.066394805908e-07 +489 475 3.576278686523e-07 +490 475 36444678.54407 +491 475 -4.172325134277e-07 +492 475 53333333.32457 +493 475 -59154777.5129 +494 475 2.98023223877e-08 +573 475 4.470348358154e-08 +574 475 -29957235.32024 +575 475 2.831220626831e-07 +576 475 -13333333.33771 +577 475 -24555795.63051 +578 475 13177083.33766 +585 475 1.728534698486e-06 +586 475 40172745.1813 +587 475 -5.960464477539e-08 +588 475 -7.003545761108e-07 +589 475 -58222760.85313 +590 475 52708333.32467 +600 475 1.9371509552e-07 +601 475 -29957235.32024 +602 475 -3.8743019104e-07 +603 475 13333333.33771 +604 475 -24555795.63051 +605 475 13177083.33766 +476 476 905507012.9075 +477 476 -1.668930053711e-06 +478 476 4.470348358154e-07 +479 476 123977832.6588 +489 476 1.192092895508e-07 +490 476 -4.768371582031e-07 +491 476 66375066.93519 +492 476 4.470348358154e-08 +493 476 -4.470348358154e-08 +494 476 -9005963.440553 +573 476 65886111.10029 +574 476 3.8743019104e-07 +575 476 -87588646.48668 +576 476 16471527.78319 +577 476 13177083.33766 +578 476 -28297094.18124 +585 476 8.642673492432e-07 +586 476 1.788139343262e-07 +587 476 -190352899.3709 +588 476 1.475214958191e-06 +589 476 52708333.32467 +590 476 -73187955.0487 +600 476 -65886111.10029 +601 476 -2.831220626831e-07 +602 476 -87588646.48668 +603 476 -16471527.78319 +604 476 13177083.33766 +605 476 -28297094.18124 +477 477 913791605.4334 +478 477 7.748603820801e-06 +479 477 -2.622604370117e-06 +480 477 126048980.7912 +481 477 -2.175569534302e-06 +482 477 -1.490116119385e-06 +489 477 -75155545.77471 +490 477 -53333333.32457 +491 477 5.066394805908e-07 +492 477 -198223262.271 +493 477 2.98023223877e-07 +494 477 5.960464477539e-08 +495 477 -75155545.7747 +496 477 53333333.32457 +497 477 -1.490116119385e-08 +573 477 -28555987.69793 +574 477 13333333.33771 +575 477 16471527.78319 +576 477 -88624220.55292 +577 477 1.043081283569e-07 +578 477 65886111.10029 +579 477 -28555987.69793 +580 477 -13333333.33771 +581 477 16471527.78319 +585 477 -7556159.747413 +586 477 -3.278255462646e-07 +587 477 -1.206994056702e-06 +588 477 72174281.7049 +589 477 1.728534698486e-06 +590 477 1.221895217896e-06 +591 477 -7556159.747413 +592 477 -7.450580596924e-07 +593 477 1.341104507446e-06 +600 477 -28555987.69793 +601 477 -13333333.33771 +602 477 -16471527.78319 +603 477 -88624220.55292 +604 477 2.235174179077e-07 +605 477 -65886111.10029 +606 477 -28555987.69793 +607 477 13333333.33771 +608 477 -16471527.78319 +478 478 785785459.402 +479 478 -1.788139343262e-06 +480 478 -2.086162567139e-06 +481 478 -76617423.53181 +482 478 5.066394805908e-07 +489 478 -53333333.32457 +490 478 -59154777.5129 +491 478 2.086162567139e-07 +492 478 3.576278686523e-07 +493 478 36444678.54407 +494 478 -4.172325134277e-07 +495 478 53333333.32457 +496 478 -59154777.5129 +497 478 2.98023223877e-08 +573 478 13333333.33771 +574 478 -24555795.63051 +575 478 -13177083.33766 +576 478 4.470348358154e-08 +577 478 -29957235.32024 +578 478 2.831220626831e-07 +579 478 -13333333.33771 +580 478 -24555795.63051 +581 478 13177083.33766 +585 478 -2.98023223877e-07 +586 478 -58222760.85313 +587 478 -52708333.32467 +588 478 1.728534698486e-06 +589 478 40172745.1813 +590 478 -5.960464477539e-08 +591 478 -7.003545761108e-07 +592 478 -58222760.85313 +593 478 52708333.32467 +600 478 -13333333.33771 +601 478 -24555795.63051 +602 478 -13177083.33766 +603 478 1.9371509552e-07 +604 478 -29957235.32024 +605 478 -3.8743019104e-07 +606 478 13333333.33771 +607 478 -24555795.63051 +608 478 13177083.33766 +479 479 905507012.9075 +480 479 -1.668930053711e-06 +481 479 4.470348358154e-07 +482 479 123977832.6588 +489 479 5.811452865601e-07 +490 479 3.129243850708e-07 +491 479 -9005963.440556 +492 479 1.192092895508e-07 +493 479 -4.768371582031e-07 +494 479 66375066.93519 +495 479 4.470348358154e-08 +496 479 -4.470348358154e-08 +497 479 -9005963.440553 +573 479 16471527.78319 +574 479 -13177083.33766 +575 479 -28297094.18124 +576 479 65886111.10029 +577 479 3.8743019104e-07 +578 479 -87588646.48668 +579 479 16471527.78319 +580 479 13177083.33766 +581 479 -28297094.18124 +585 479 -9.983777999878e-07 +586 479 -52708333.32467 +587 479 -73187955.04869 +588 479 8.642673492432e-07 +589 479 1.788139343262e-07 +590 479 -190352899.3709 +591 479 1.475214958191e-06 +592 479 52708333.32467 +593 479 -73187955.0487 +600 479 -16471527.78319 +601 479 -13177083.33766 +602 479 -28297094.18124 +603 479 -65886111.10029 +604 479 -2.831220626831e-07 +605 479 -87588646.48668 +606 479 -16471527.78319 +607 479 13177083.33766 +608 479 -28297094.18124 +480 480 913791605.4334 +481 480 7.748603820801e-06 +482 480 -2.622604370117e-06 +483 480 126048980.7912 +484 480 -2.175569534302e-06 +485 480 -1.490116119385e-06 +492 480 -75155545.77471 +493 480 -53333333.32457 +494 480 5.066394805908e-07 +495 480 -198223262.271 +496 480 2.98023223877e-07 +497 480 5.960464477539e-08 +498 480 -75155545.7747 +499 480 53333333.32457 +500 480 -1.490116119385e-08 +576 480 -28555987.69793 +577 480 13333333.33771 +578 480 16471527.78319 +579 480 -88624220.55292 +580 480 1.043081283569e-07 +581 480 65886111.10029 +582 480 -28555987.69793 +583 480 -13333333.33771 +584 480 16471527.78319 +588 480 -7556159.747413 +589 480 -3.278255462646e-07 +590 480 -1.206994056702e-06 +591 480 72174281.7049 +592 480 1.728534698486e-06 +593 480 1.221895217896e-06 +594 480 -7556159.747413 +595 480 -7.450580596924e-07 +596 480 1.341104507446e-06 +603 480 -28555987.69793 +604 480 -13333333.33771 +605 480 -16471527.78319 +606 480 -88624220.55292 +607 480 2.235174179077e-07 +608 480 -65886111.10029 +609 480 -28555987.69793 +610 480 13333333.33771 +611 480 -16471527.78319 +481 481 785785459.402 +482 481 -1.788139343262e-06 +483 481 -2.086162567139e-06 +484 481 -76617423.53181 +485 481 5.066394805908e-07 +492 481 -53333333.32457 +493 481 -59154777.5129 +494 481 2.086162567139e-07 +495 481 3.576278686523e-07 +496 481 36444678.54407 +497 481 -4.172325134277e-07 +498 481 53333333.32457 +499 481 -59154777.5129 +500 481 2.98023223877e-08 +576 481 13333333.33771 +577 481 -24555795.63051 +578 481 -13177083.33766 +579 481 4.470348358154e-08 +580 481 -29957235.32024 +581 481 2.831220626831e-07 +582 481 -13333333.33771 +583 481 -24555795.63051 +584 481 13177083.33766 +588 481 -2.98023223877e-07 +589 481 -58222760.85313 +590 481 -52708333.32467 +591 481 1.728534698486e-06 +592 481 40172745.1813 +593 481 -5.960464477539e-08 +594 481 -7.003545761108e-07 +595 481 -58222760.85313 +596 481 52708333.32467 +603 481 -13333333.33771 +604 481 -24555795.63051 +605 481 -13177083.33766 +606 481 1.9371509552e-07 +607 481 -29957235.32024 +608 481 -3.8743019104e-07 +609 481 13333333.33771 +610 481 -24555795.63051 +611 481 13177083.33766 +482 482 905507012.9075 +483 482 -1.668930053711e-06 +484 482 4.470348358154e-07 +485 482 123977832.6588 +492 482 5.811452865601e-07 +493 482 3.129243850708e-07 +494 482 -9005963.440556 +495 482 1.192092895508e-07 +496 482 -4.768371582031e-07 +497 482 66375066.93519 +498 482 4.470348358154e-08 +499 482 -4.470348358154e-08 +500 482 -9005963.440553 +576 482 16471527.78319 +577 482 -13177083.33766 +578 482 -28297094.18124 +579 482 65886111.10029 +580 482 3.8743019104e-07 +581 482 -87588646.48668 +582 482 16471527.78319 +583 482 13177083.33766 +584 482 -28297094.18124 +588 482 -9.983777999878e-07 +589 482 -52708333.32467 +590 482 -73187955.04869 +591 482 8.642673492432e-07 +592 482 1.788139343262e-07 +593 482 -190352899.3709 +594 482 1.475214958191e-06 +595 482 52708333.32467 +596 482 -73187955.0487 +603 482 -16471527.78319 +604 482 -13177083.33766 +605 482 -28297094.18124 +606 482 -65886111.10029 +607 482 -2.831220626831e-07 +608 482 -87588646.48668 +609 482 -16471527.78319 +610 482 13177083.33766 +611 482 -28297094.18124 +483 483 988947148.5376 +484 483 53333332.25791 +485 483 -9.298324584961e-06 +486 483 31359232.67644 +487 483 -53333332.8979 +488 483 1.251697540283e-06 +495 483 -75155545.77471 +496 483 -53333333.32457 +497 483 5.066394805908e-07 +498 483 -198223262.271 +499 483 2.98023223877e-07 +500 483 5.960464477539e-08 +501 483 -75155545.7747 +502 483 53333333.32457 +503 483 -1.490116119385e-08 +579 483 -28555987.69793 +580 483 13333333.33771 +581 483 16471527.78319 +582 483 -107413106.5112 +583 483 -13333333.17771 +584 483 65886110.96157 +591 483 -7556159.747413 +592 483 -3.278255462646e-07 +593 483 -1.206994056702e-06 +594 483 100730268.7541 +595 483 13333333.07105 +596 483 0.02774140238762 +597 483 -26345045.89131 +598 483 -13333333.23105 +599 483 16471527.49884 +606 483 -28555987.69793 +607 483 -13333333.33771 +608 483 -16471527.78319 +609 483 -88624220.55292 +610 483 2.235174179077e-07 +611 483 -65886111.10029 +612 483 -28555987.69793 +613 483 13333333.33771 +614 483 -16471527.78319 +484 484 844940234.7245 +485 484 -7.987022399902e-06 +486 484 -53333332.68457 +487 484 -155306402.5315 +488 484 5.394220352173e-06 +495 484 -53333333.32457 +496 484 -59154777.5129 +497 484 2.086162567139e-07 +498 484 3.576278686523e-07 +499 484 36444678.54407 +500 484 -4.172325134277e-07 +501 484 53333333.32457 +502 484 -59154777.5129 +503 484 2.98023223877e-08 +579 484 13333333.33771 +580 484 -24555795.63051 +581 484 -13177083.33766 +582 484 -13333333.23104 +583 484 -44745929.54447 +584 484 13177083.28808 +591 484 -2.98023223877e-07 +592 484 -58222760.85313 +593 484 -52708333.32467 +594 484 13333333.07105 +595 484 64728540.28304 +596 484 0.022192299366 +597 484 -13333333.17771 +598 484 -73011454.71628 +599 484 52708333.03581 +606 484 -13333333.33771 +607 484 -24555795.63051 +608 484 -13177083.33766 +609 484 1.9371509552e-07 +610 484 -29957235.32024 +611 484 -3.8743019104e-07 +612 484 13333333.33771 +613 484 -24555795.63051 +614 484 13177083.33766 +485 485 914512974.9691 +486 485 1.728534698486e-06 +487 485 4.559755325317e-06 +488 485 62880662.12465 +495 485 5.811452865601e-07 +496 485 3.129243850708e-07 +497 485 -9005963.440556 +498 485 1.192092895508e-07 +499 485 -4.768371582031e-07 +500 485 66375066.93519 +501 485 4.470348358154e-08 +502 485 -4.470348358154e-08 +503 485 -9005963.440553 +579 485 16471527.78319 +580 485 -13177083.33766 +581 485 -28297094.18124 +582 485 65886110.96157 +583 485 13177083.26329 +584 485 -89840137.25118 +591 485 -9.983777999878e-07 +592 485 -52708333.32467 +593 485 -73187955.04869 +594 485 -0.0277450978756 +595 485 -0.02219566702843 +596 485 -162055805.4842 +597 485 16471527.35667 +598 485 52708332.94687 +599 485 -75439445.29918 +606 485 -16471527.78319 +607 485 -13177083.33766 +608 485 -28297094.18124 +609 485 -65886111.10029 +610 485 -2.831220626831e-07 +611 485 -87588646.48668 +612 485 -16471527.78319 +613 485 13177083.33766 +614 485 -28297094.18124 +486 486 571119749.839 +487 486 53333333.32457 +488 486 -6.198883056641e-06 +498 486 -75155545.77471 +499 486 -53333333.32457 +500 486 5.066394805908e-07 +501 486 -292913008.3249 +502 486 -53333332.8979 +503 486 6.556510925293e-06 +504 486 19534202.10867 +505 486 42666666.23299 +506 486 -1.490116119385e-06 +582 486 -9767101.054335 +583 486 15999999.84525 +584 486 19765832.91331 +594 486 -26345045.8913 +595 486 -13333333.17771 +596 486 -16471527.35667 +597 486 45108925.89256 +598 486 13333333.33771 +599 486 13177222.19231 +609 486 -28555987.69793 +610 486 -13333333.33771 +611 486 -16471527.78319 +612 486 -107413106.5112 +613 486 -13333333.23104 +614 486 -65886110.96157 +615 486 -9767101.054335 +616 486 10666666.5635 +617 486 -13177221.94221 +487 487 491115909.0416 +488 487 -2.974887930942e-06 +498 487 -53333333.32457 +499 487 -59154777.5129 +500 487 2.086162567139e-07 +501 487 -53333332.68457 +502 487 -42244300.58137 +503 487 2.145767211914e-06 +504 487 63999999.34949 +505 487 19534202.10866 +506 487 -2.384185791016e-06 +582 487 10666666.5635 +583 487 -9767101.054336 +584 487 -10541666.62055 +594 487 -13333333.23105 +595 487 -73011454.71627 +596 487 -52708332.94687 +597 487 13333333.33771 +598 487 25107965.68335 +599 487 10541666.55379 +609 487 -13333333.33771 +610 487 -24555795.63051 +611 487 -13177083.33766 +612 487 -13333333.17771 +613 487 -44745929.54446 +614 487 -13177083.26329 +615 487 15999999.84525 +616 487 -9767101.054335 +617 487 15812499.93082 +488 488 565941879.2302 +498 488 5.811452865601e-07 +499 488 3.129243850708e-07 +500 488 -9005963.440556 +501 488 6.943941116333e-06 +502 488 1.609325408936e-06 +503 488 5277897.861165 +504 488 -2.145767211914e-06 +505 488 -1.54972076416e-06 +506 488 52091205.62311 +582 488 13177221.94221 +583 488 -15812499.93082 +584 488 -26045602.81156 +594 488 -16471527.49884 +595 488 -52708333.03581 +596 488 -75439445.29917 +597 488 -13177222.19232 +598 488 -10541666.5538 +599 488 -118970561.1562 +609 488 -16471527.78319 +610 488 -13177083.33766 +611 488 -28297094.18124 +612 488 -65886110.96157 +613 488 -13177083.28808 +614 488 -89840137.25117 +615 488 -19765832.91331 +616 488 10541666.62055 +617 488 -26045602.81156 +489 489 913791605.4334 +490 489 7.748603820801e-06 +491 489 -2.622604370117e-06 +492 489 126048980.7912 +493 489 -2.175569534302e-06 +494 489 -1.490116119385e-06 +507 489 -198223262.271 +508 489 2.98023223877e-07 +509 489 5.960464477539e-08 +510 489 -75155545.7747 +511 489 53333333.32457 +512 489 -1.490116119385e-08 +585 489 -88624220.55292 +586 489 1.043081283569e-07 +587 489 65886111.10029 +588 489 -28555987.69793 +589 489 -13333333.33771 +590 489 16471527.78319 +600 489 72174281.7049 +601 489 1.728534698486e-06 +602 489 1.221895217896e-06 +603 489 -7556159.747413 +604 489 -7.450580596924e-07 +605 489 1.341104507446e-06 +618 489 -88624220.55292 +619 489 2.235174179077e-07 +620 489 -65886111.10029 +621 489 -28555987.69793 +622 489 13333333.33771 +623 489 -16471527.78319 +490 490 785785459.402 +491 490 -1.788139343262e-06 +492 490 -2.086162567139e-06 +493 490 -76617423.53181 +494 490 5.066394805908e-07 +507 490 3.576278686523e-07 +508 490 36444678.54407 +509 490 -4.172325134277e-07 +510 490 53333333.32457 +511 490 -59154777.5129 +512 490 2.98023223877e-08 +585 490 4.470348358154e-08 +586 490 -29957235.32024 +587 490 2.831220626831e-07 +588 490 -13333333.33771 +589 490 -24555795.63051 +590 490 13177083.33766 +600 490 1.728534698486e-06 +601 490 40172745.1813 +602 490 -5.960464477539e-08 +603 490 -7.003545761108e-07 +604 490 -58222760.85313 +605 490 52708333.32467 +618 490 1.9371509552e-07 +619 490 -29957235.32024 +620 490 -3.8743019104e-07 +621 490 13333333.33771 +622 490 -24555795.63051 +623 490 13177083.33766 +491 491 905507012.9075 +492 491 -1.668930053711e-06 +493 491 4.470348358154e-07 +494 491 123977832.6588 +507 491 1.192092895508e-07 +508 491 -4.768371582031e-07 +509 491 66375066.93519 +510 491 4.470348358154e-08 +511 491 -4.470348358154e-08 +512 491 -9005963.440553 +585 491 65886111.10029 +586 491 3.8743019104e-07 +587 491 -87588646.48668 +588 491 16471527.78319 +589 491 13177083.33766 +590 491 -28297094.18124 +600 491 8.642673492432e-07 +601 491 1.788139343262e-07 +602 491 -190352899.3709 +603 491 1.475214958191e-06 +604 491 52708333.32467 +605 491 -73187955.0487 +618 491 -65886111.10029 +619 491 -2.831220626831e-07 +620 491 -87588646.48668 +621 491 -16471527.78319 +622 491 13177083.33766 +623 491 -28297094.18124 +492 492 913791605.4334 +493 492 7.748603820801e-06 +494 492 -2.622604370117e-06 +495 492 126048980.7912 +496 492 -2.175569534302e-06 +497 492 -1.490116119385e-06 +507 492 -75155545.77471 +508 492 -53333333.32457 +509 492 5.066394805908e-07 +510 492 -198223262.271 +511 492 2.98023223877e-07 +512 492 5.960464477539e-08 +513 492 -75155545.7747 +514 492 53333333.32457 +515 492 -1.490116119385e-08 +585 492 -28555987.69793 +586 492 13333333.33771 +587 492 16471527.78319 +588 492 -88624220.55292 +589 492 1.043081283569e-07 +590 492 65886111.10029 +591 492 -28555987.69793 +592 492 -13333333.33771 +593 492 16471527.78319 +600 492 -7556159.747413 +601 492 -3.278255462646e-07 +602 492 -1.206994056702e-06 +603 492 72174281.7049 +604 492 1.728534698486e-06 +605 492 1.221895217896e-06 +606 492 -7556159.747413 +607 492 -7.450580596924e-07 +608 492 1.341104507446e-06 +618 492 -28555987.69793 +619 492 -13333333.33771 +620 492 -16471527.78319 +621 492 -88624220.55292 +622 492 2.235174179077e-07 +623 492 -65886111.10029 +624 492 -28555987.69793 +625 492 13333333.33771 +626 492 -16471527.78319 +493 493 785785459.402 +494 493 -1.788139343262e-06 +495 493 -2.086162567139e-06 +496 493 -76617423.53181 +497 493 5.066394805908e-07 +507 493 -53333333.32457 +508 493 -59154777.5129 +509 493 2.086162567139e-07 +510 493 3.576278686523e-07 +511 493 36444678.54407 +512 493 -4.172325134277e-07 +513 493 53333333.32457 +514 493 -59154777.5129 +515 493 2.98023223877e-08 +585 493 13333333.33771 +586 493 -24555795.63051 +587 493 -13177083.33766 +588 493 4.470348358154e-08 +589 493 -29957235.32024 +590 493 2.831220626831e-07 +591 493 -13333333.33771 +592 493 -24555795.63051 +593 493 13177083.33766 +600 493 -2.98023223877e-07 +601 493 -58222760.85313 +602 493 -52708333.32467 +603 493 1.728534698486e-06 +604 493 40172745.1813 +605 493 -5.960464477539e-08 +606 493 -7.003545761108e-07 +607 493 -58222760.85313 +608 493 52708333.32467 +618 493 -13333333.33771 +619 493 -24555795.63051 +620 493 -13177083.33766 +621 493 1.9371509552e-07 +622 493 -29957235.32024 +623 493 -3.8743019104e-07 +624 493 13333333.33771 +625 493 -24555795.63051 +626 493 13177083.33766 +494 494 905507012.9075 +495 494 -1.668930053711e-06 +496 494 4.470348358154e-07 +497 494 123977832.6588 +507 494 5.811452865601e-07 +508 494 3.129243850708e-07 +509 494 -9005963.440556 +510 494 1.192092895508e-07 +511 494 -4.768371582031e-07 +512 494 66375066.93519 +513 494 4.470348358154e-08 +514 494 -4.470348358154e-08 +515 494 -9005963.440553 +585 494 16471527.78319 +586 494 -13177083.33766 +587 494 -28297094.18124 +588 494 65886111.10029 +589 494 3.8743019104e-07 +590 494 -87588646.48668 +591 494 16471527.78319 +592 494 13177083.33766 +593 494 -28297094.18124 +600 494 -9.983777999878e-07 +601 494 -52708333.32467 +602 494 -73187955.04869 +603 494 8.642673492432e-07 +604 494 1.788139343262e-07 +605 494 -190352899.3709 +606 494 1.475214958191e-06 +607 494 52708333.32467 +608 494 -73187955.0487 +618 494 -16471527.78319 +619 494 -13177083.33766 +620 494 -28297094.18124 +621 494 -65886111.10029 +622 494 -2.831220626831e-07 +623 494 -87588646.48668 +624 494 -16471527.78319 +625 494 13177083.33766 +626 494 -28297094.18124 +495 495 913791605.4334 +496 495 7.748603820801e-06 +497 495 -2.622604370117e-06 +498 495 126048980.7912 +499 495 -2.175569534302e-06 +500 495 -1.490116119385e-06 +510 495 -75155545.77471 +511 495 -53333333.32457 +512 495 5.066394805908e-07 +513 495 -198223262.271 +514 495 2.98023223877e-07 +515 495 5.960464477539e-08 +516 495 -75155545.7747 +517 495 53333333.32457 +518 495 -1.490116119385e-08 +588 495 -28555987.69793 +589 495 13333333.33771 +590 495 16471527.78319 +591 495 -88624220.55292 +592 495 1.043081283569e-07 +593 495 65886111.10029 +594 495 -28555987.69793 +595 495 -13333333.33771 +596 495 16471527.78319 +603 495 -7556159.747413 +604 495 -3.278255462646e-07 +605 495 -1.206994056702e-06 +606 495 72174281.7049 +607 495 1.728534698486e-06 +608 495 1.221895217896e-06 +609 495 -7556159.747413 +610 495 -7.450580596924e-07 +611 495 1.341104507446e-06 +621 495 -28555987.69793 +622 495 -13333333.33771 +623 495 -16471527.78319 +624 495 -88624220.55292 +625 495 2.235174179077e-07 +626 495 -65886111.10029 +627 495 -28555987.69793 +628 495 13333333.33771 +629 495 -16471527.78319 +496 496 785785459.402 +497 496 -1.788139343262e-06 +498 496 -2.086162567139e-06 +499 496 -76617423.53181 +500 496 5.066394805908e-07 +510 496 -53333333.32457 +511 496 -59154777.5129 +512 496 2.086162567139e-07 +513 496 3.576278686523e-07 +514 496 36444678.54407 +515 496 -4.172325134277e-07 +516 496 53333333.32457 +517 496 -59154777.5129 +518 496 2.98023223877e-08 +588 496 13333333.33771 +589 496 -24555795.63051 +590 496 -13177083.33766 +591 496 4.470348358154e-08 +592 496 -29957235.32024 +593 496 2.831220626831e-07 +594 496 -13333333.33771 +595 496 -24555795.63051 +596 496 13177083.33766 +603 496 -2.98023223877e-07 +604 496 -58222760.85313 +605 496 -52708333.32467 +606 496 1.728534698486e-06 +607 496 40172745.1813 +608 496 -5.960464477539e-08 +609 496 -7.003545761108e-07 +610 496 -58222760.85313 +611 496 52708333.32467 +621 496 -13333333.33771 +622 496 -24555795.63051 +623 496 -13177083.33766 +624 496 1.9371509552e-07 +625 496 -29957235.32024 +626 496 -3.8743019104e-07 +627 496 13333333.33771 +628 496 -24555795.63051 +629 496 13177083.33766 +497 497 905507012.9075 +498 497 -1.668930053711e-06 +499 497 4.470348358154e-07 +500 497 123977832.6588 +510 497 5.811452865601e-07 +511 497 3.129243850708e-07 +512 497 -9005963.440556 +513 497 1.192092895508e-07 +514 497 -4.768371582031e-07 +515 497 66375066.93519 +516 497 4.470348358154e-08 +517 497 -4.470348358154e-08 +518 497 -9005963.440553 +588 497 16471527.78319 +589 497 -13177083.33766 +590 497 -28297094.18124 +591 497 65886111.10029 +592 497 3.8743019104e-07 +593 497 -87588646.48668 +594 497 16471527.78319 +595 497 13177083.33766 +596 497 -28297094.18124 +603 497 -9.983777999878e-07 +604 497 -52708333.32467 +605 497 -73187955.04869 +606 497 8.642673492432e-07 +607 497 1.788139343262e-07 +608 497 -190352899.3709 +609 497 1.475214958191e-06 +610 497 52708333.32467 +611 497 -73187955.0487 +621 497 -16471527.78319 +622 497 -13177083.33766 +623 497 -28297094.18124 +624 497 -65886111.10029 +625 497 -2.831220626831e-07 +626 497 -87588646.48668 +627 497 -16471527.78319 +628 497 13177083.33766 +629 497 -28297094.18124 +498 498 913791605.4334 +499 498 7.748603820801e-06 +500 498 -2.622604370117e-06 +501 498 126048980.7912 +502 498 -2.175569534302e-06 +503 498 -1.490116119385e-06 +513 498 -75155545.77471 +514 498 -53333333.32457 +515 498 5.066394805908e-07 +516 498 -198223262.271 +517 498 2.98023223877e-07 +518 498 5.960464477539e-08 +519 498 -75155545.7747 +520 498 53333333.32457 +521 498 -1.490116119385e-08 +591 498 -28555987.69793 +592 498 13333333.33771 +593 498 16471527.78319 +594 498 -88624220.55292 +595 498 1.043081283569e-07 +596 498 65886111.10029 +597 498 -28555987.69793 +598 498 -13333333.33771 +599 498 16471527.78319 +606 498 -7556159.747413 +607 498 -3.278255462646e-07 +608 498 -1.206994056702e-06 +609 498 72174281.7049 +610 498 1.728534698486e-06 +611 498 1.221895217896e-06 +612 498 -7556159.747413 +613 498 -7.450580596924e-07 +614 498 1.341104507446e-06 +624 498 -28555987.69793 +625 498 -13333333.33771 +626 498 -16471527.78319 +627 498 -88624220.55292 +628 498 2.235174179077e-07 +629 498 -65886111.10029 +630 498 -28555987.69793 +631 498 13333333.33771 +632 498 -16471527.78319 +499 499 785785459.402 +500 499 -1.788139343262e-06 +501 499 -2.086162567139e-06 +502 499 -76617423.53181 +503 499 5.066394805908e-07 +513 499 -53333333.32457 +514 499 -59154777.5129 +515 499 2.086162567139e-07 +516 499 3.576278686523e-07 +517 499 36444678.54407 +518 499 -4.172325134277e-07 +519 499 53333333.32457 +520 499 -59154777.5129 +521 499 2.98023223877e-08 +591 499 13333333.33771 +592 499 -24555795.63051 +593 499 -13177083.33766 +594 499 4.470348358154e-08 +595 499 -29957235.32024 +596 499 2.831220626831e-07 +597 499 -13333333.33771 +598 499 -24555795.63051 +599 499 13177083.33766 +606 499 -2.98023223877e-07 +607 499 -58222760.85313 +608 499 -52708333.32467 +609 499 1.728534698486e-06 +610 499 40172745.1813 +611 499 -5.960464477539e-08 +612 499 -7.003545761108e-07 +613 499 -58222760.85313 +614 499 52708333.32467 +624 499 -13333333.33771 +625 499 -24555795.63051 +626 499 -13177083.33766 +627 499 1.9371509552e-07 +628 499 -29957235.32024 +629 499 -3.8743019104e-07 +630 499 13333333.33771 +631 499 -24555795.63051 +632 499 13177083.33766 +500 500 905507012.9075 +501 500 -1.668930053711e-06 +502 500 4.470348358154e-07 +503 500 123977832.6588 +513 500 5.811452865601e-07 +514 500 3.129243850708e-07 +515 500 -9005963.440556 +516 500 1.192092895508e-07 +517 500 -4.768371582031e-07 +518 500 66375066.93519 +519 500 4.470348358154e-08 +520 500 -4.470348358154e-08 +521 500 -9005963.440553 +591 500 16471527.78319 +592 500 -13177083.33766 +593 500 -28297094.18124 +594 500 65886111.10029 +595 500 3.8743019104e-07 +596 500 -87588646.48668 +597 500 16471527.78319 +598 500 13177083.33766 +599 500 -28297094.18124 +606 500 -9.983777999878e-07 +607 500 -52708333.32467 +608 500 -73187955.04869 +609 500 8.642673492432e-07 +610 500 1.788139343262e-07 +611 500 -190352899.3709 +612 500 1.475214958191e-06 +613 500 52708333.32467 +614 500 -73187955.0487 +624 500 -16471527.78319 +625 500 -13177083.33766 +626 500 -28297094.18124 +627 500 -65886111.10029 +628 500 -2.831220626831e-07 +629 500 -87588646.48668 +630 500 -16471527.78319 +631 500 13177083.33766 +632 500 -28297094.18124 +501 501 988947148.5376 +502 501 53333332.25791 +503 501 -9.298324584961e-06 +504 501 31359232.67644 +505 501 -53333332.8979 +506 501 1.251697540283e-06 +516 501 -75155545.77471 +517 501 -53333333.32457 +518 501 5.066394805908e-07 +519 501 -198223262.271 +520 501 2.98023223877e-07 +521 501 5.960464477539e-08 +522 501 -75155545.7747 +523 501 53333333.32457 +524 501 -1.490116119385e-08 +594 501 -28555987.69793 +595 501 13333333.33771 +596 501 16471527.78319 +597 501 -107413106.5112 +598 501 -13333333.17771 +599 501 65886110.96157 +609 501 -7556159.747413 +610 501 -3.278255462646e-07 +611 501 -1.206994056702e-06 +612 501 100730268.7541 +613 501 13333333.07105 +614 501 0.02774140238762 +615 501 -26345045.89131 +616 501 -13333333.23105 +617 501 16471527.49884 +627 501 -28555987.69793 +628 501 -13333333.33771 +629 501 -16471527.78319 +630 501 -88624220.55292 +631 501 2.235174179077e-07 +632 501 -65886111.10029 +633 501 -28555987.69793 +634 501 13333333.33771 +635 501 -16471527.78319 +502 502 844940234.7245 +503 502 -7.987022399902e-06 +504 502 -53333332.68457 +505 502 -155306402.5315 +506 502 5.394220352173e-06 +516 502 -53333333.32457 +517 502 -59154777.5129 +518 502 2.086162567139e-07 +519 502 3.576278686523e-07 +520 502 36444678.54407 +521 502 -4.172325134277e-07 +522 502 53333333.32457 +523 502 -59154777.5129 +524 502 2.98023223877e-08 +594 502 13333333.33771 +595 502 -24555795.63051 +596 502 -13177083.33766 +597 502 -13333333.23104 +598 502 -44745929.54447 +599 502 13177083.28808 +609 502 -2.98023223877e-07 +610 502 -58222760.85313 +611 502 -52708333.32467 +612 502 13333333.07105 +613 502 64728540.28304 +614 502 0.022192299366 +615 502 -13333333.17771 +616 502 -73011454.71628 +617 502 52708333.03581 +627 502 -13333333.33771 +628 502 -24555795.63051 +629 502 -13177083.33766 +630 502 1.9371509552e-07 +631 502 -29957235.32024 +632 502 -3.8743019104e-07 +633 502 13333333.33771 +634 502 -24555795.63051 +635 502 13177083.33766 +503 503 914512974.9691 +504 503 1.728534698486e-06 +505 503 4.559755325317e-06 +506 503 62880662.12465 +516 503 5.811452865601e-07 +517 503 3.129243850708e-07 +518 503 -9005963.440556 +519 503 1.192092895508e-07 +520 503 -4.768371582031e-07 +521 503 66375066.93519 +522 503 4.470348358154e-08 +523 503 -4.470348358154e-08 +524 503 -9005963.440553 +594 503 16471527.78319 +595 503 -13177083.33766 +596 503 -28297094.18124 +597 503 65886110.96157 +598 503 13177083.26329 +599 503 -89840137.25118 +609 503 -9.983777999878e-07 +610 503 -52708333.32467 +611 503 -73187955.04869 +612 503 -0.0277450978756 +613 503 -0.02219566702843 +614 503 -162055805.4842 +615 503 16471527.35667 +616 503 52708332.94687 +617 503 -75439445.29918 +627 503 -16471527.78319 +628 503 -13177083.33766 +629 503 -28297094.18124 +630 503 -65886111.10029 +631 503 -2.831220626831e-07 +632 503 -87588646.48668 +633 503 -16471527.78319 +634 503 13177083.33766 +635 503 -28297094.18124 +504 504 509154568.8248 +505 504 25085639.27704 +506 504 -5.960464477539e-07 +519 504 -75155545.77471 +520 504 -53333333.32457 +521 504 5.066394805908e-07 +522 504 -228025244.9359 +523 504 -25085638.85037 +524 504 7.152557373047e-07 +525 504 -4082989.550575 +526 504 42666666.23299 +527 504 -1.251697540283e-06 +597 504 -9767101.054335 +598 504 15999999.84525 +599 504 19765832.91331 +612 504 -26345045.8913 +613 504 -13333333.17771 +614 504 -16471527.35667 +615 504 37378109.13818 +616 504 6271409.822349 +617 504 11432222.19995 +630 504 -28555987.69793 +631 504 -13333333.33771 +632 504 -16471527.78319 +633 504 -87310926.38278 +634 504 -6271409.715683 +635 504 -57161110.99975 +636 504 -11791159.78617 +637 504 10666666.5635 +638 504 -9687222.01637 +505 505 472604990.7818 +506 505 -2.652406692505e-06 +519 505 -53333333.32457 +520 505 -59154777.5129 +521 505 2.086162567139e-07 +522 505 -25085638.63704 +523 505 9928432.40691 +524 505 2.384185791016e-07 +525 505 63999999.34949 +526 505 -34822221.9043 +527 505 -1.788139343262e-07 +597 505 10666666.5635 +598 505 -9767101.054336 +599 505 -10541666.62055 +612 505 -13333333.23105 +613 505 -73011454.71627 +614 505 -52708332.94687 +615 505 6271409.822349 +616 505 28240714.62293 +617 505 9145833.226567 +630 505 -13333333.33771 +631 505 -24555795.63051 +632 505 -13177083.33766 +633 505 -6271409.66235 +634 505 -27822507.01778 +635 505 -6197916.627156 +636 505 15999999.84526 +637 505 -19475967.87838 +638 505 18604166.53816 +506 506 522045024.059 +519 506 5.811452865601e-07 +520 506 3.129243850708e-07 +521 506 -9005963.440556 +522 506 7.450580596924e-07 +523 506 2.384185791016e-07 +524 506 26229073.67805 +525 506 -1.490116119385e-06 +526 506 2.384185791016e-07 +527 506 19851260.21887 +597 506 13177221.94221 +598 506 -15812499.93082 +599 506 -26045602.81156 +612 506 -16471527.49884 +613 506 -52708333.03581 +614 506 -75439445.29917 +615 506 -11432222.19995 +616 506 -9145833.22657 +617 506 -109250165.6029 +630 506 -16471527.78319 +631 506 -13177083.33766 +632 506 -28297094.18124 +633 506 -57161110.99975 +634 506 -6197916.651946 +635 506 -74255038.56586 +636 506 -14530833.02455 +637 506 14729166.53156 +638 506 -23758284.67089 +507 507 913791605.4334 +508 507 7.748603820801e-06 +509 507 -2.622604370117e-06 +510 507 126048980.7912 +511 507 -2.175569534302e-06 +512 507 -1.490116119385e-06 +528 507 -198223262.271 +529 507 2.98023223877e-07 +530 507 5.960464477539e-08 +531 507 -75155545.7747 +532 507 53333333.32457 +533 507 -1.490116119385e-08 +600 507 -88624220.55292 +601 507 1.043081283569e-07 +602 507 65886111.10029 +603 507 -28555987.69793 +604 507 -13333333.33771 +605 507 16471527.78319 +618 507 72174281.7049 +619 507 1.728534698486e-06 +620 507 1.221895217896e-06 +621 507 -7556159.747413 +622 507 -7.450580596924e-07 +623 507 1.341104507446e-06 +639 507 -88624220.55292 +640 507 2.235174179077e-07 +641 507 -65886111.10029 +642 507 -28555987.69793 +643 507 13333333.33771 +644 507 -16471527.78319 +508 508 785785459.402 +509 508 -1.788139343262e-06 +510 508 -2.086162567139e-06 +511 508 -76617423.53181 +512 508 5.066394805908e-07 +528 508 3.576278686523e-07 +529 508 36444678.54407 +530 508 -4.172325134277e-07 +531 508 53333333.32457 +532 508 -59154777.5129 +533 508 2.98023223877e-08 +600 508 4.470348358154e-08 +601 508 -29957235.32024 +602 508 2.831220626831e-07 +603 508 -13333333.33771 +604 508 -24555795.63051 +605 508 13177083.33766 +618 508 1.728534698486e-06 +619 508 40172745.1813 +620 508 -5.960464477539e-08 +621 508 -7.003545761108e-07 +622 508 -58222760.85313 +623 508 52708333.32467 +639 508 1.9371509552e-07 +640 508 -29957235.32024 +641 508 -3.8743019104e-07 +642 508 13333333.33771 +643 508 -24555795.63051 +644 508 13177083.33766 +509 509 905507012.9075 +510 509 -1.668930053711e-06 +511 509 4.470348358154e-07 +512 509 123977832.6588 +528 509 1.192092895508e-07 +529 509 -4.768371582031e-07 +530 509 66375066.93519 +531 509 4.470348358154e-08 +532 509 -4.470348358154e-08 +533 509 -9005963.440553 +600 509 65886111.10029 +601 509 3.8743019104e-07 +602 509 -87588646.48668 +603 509 16471527.78319 +604 509 13177083.33766 +605 509 -28297094.18124 +618 509 8.642673492432e-07 +619 509 1.788139343262e-07 +620 509 -190352899.3709 +621 509 1.475214958191e-06 +622 509 52708333.32467 +623 509 -73187955.0487 +639 509 -65886111.10029 +640 509 -2.831220626831e-07 +641 509 -87588646.48668 +642 509 -16471527.78319 +643 509 13177083.33766 +644 509 -28297094.18124 +510 510 913791605.4334 +511 510 7.748603820801e-06 +512 510 -2.622604370117e-06 +513 510 126048980.7912 +514 510 -2.175569534302e-06 +515 510 -1.490116119385e-06 +528 510 -75155545.77471 +529 510 -53333333.32457 +530 510 5.066394805908e-07 +531 510 -198223262.271 +532 510 2.98023223877e-07 +533 510 5.960464477539e-08 +534 510 -75155545.7747 +535 510 53333333.32457 +536 510 -1.490116119385e-08 +600 510 -28555987.69793 +601 510 13333333.33771 +602 510 16471527.78319 +603 510 -88624220.55292 +604 510 1.043081283569e-07 +605 510 65886111.10029 +606 510 -28555987.69793 +607 510 -13333333.33771 +608 510 16471527.78319 +618 510 -7556159.747413 +619 510 -3.278255462646e-07 +620 510 -1.206994056702e-06 +621 510 72174281.7049 +622 510 1.728534698486e-06 +623 510 1.221895217896e-06 +624 510 -7556159.747413 +625 510 -7.450580596924e-07 +626 510 1.341104507446e-06 +639 510 -28555987.69793 +640 510 -13333333.33771 +641 510 -16471527.78319 +642 510 -88624220.55292 +643 510 2.235174179077e-07 +644 510 -65886111.10029 +645 510 -28555987.69793 +646 510 13333333.33771 +647 510 -16471527.78319 +511 511 785785459.402 +512 511 -1.788139343262e-06 +513 511 -2.086162567139e-06 +514 511 -76617423.53181 +515 511 5.066394805908e-07 +528 511 -53333333.32457 +529 511 -59154777.5129 +530 511 2.086162567139e-07 +531 511 3.576278686523e-07 +532 511 36444678.54407 +533 511 -4.172325134277e-07 +534 511 53333333.32457 +535 511 -59154777.5129 +536 511 2.98023223877e-08 +600 511 13333333.33771 +601 511 -24555795.63051 +602 511 -13177083.33766 +603 511 4.470348358154e-08 +604 511 -29957235.32024 +605 511 2.831220626831e-07 +606 511 -13333333.33771 +607 511 -24555795.63051 +608 511 13177083.33766 +618 511 -2.98023223877e-07 +619 511 -58222760.85313 +620 511 -52708333.32467 +621 511 1.728534698486e-06 +622 511 40172745.1813 +623 511 -5.960464477539e-08 +624 511 -7.003545761108e-07 +625 511 -58222760.85313 +626 511 52708333.32467 +639 511 -13333333.33771 +640 511 -24555795.63051 +641 511 -13177083.33766 +642 511 1.9371509552e-07 +643 511 -29957235.32024 +644 511 -3.8743019104e-07 +645 511 13333333.33771 +646 511 -24555795.63051 +647 511 13177083.33766 +512 512 905507012.9075 +513 512 -1.668930053711e-06 +514 512 4.470348358154e-07 +515 512 123977832.6588 +528 512 5.811452865601e-07 +529 512 3.129243850708e-07 +530 512 -9005963.440556 +531 512 1.192092895508e-07 +532 512 -4.768371582031e-07 +533 512 66375066.93519 +534 512 4.470348358154e-08 +535 512 -4.470348358154e-08 +536 512 -9005963.440553 +600 512 16471527.78319 +601 512 -13177083.33766 +602 512 -28297094.18124 +603 512 65886111.10029 +604 512 3.8743019104e-07 +605 512 -87588646.48668 +606 512 16471527.78319 +607 512 13177083.33766 +608 512 -28297094.18124 +618 512 -9.983777999878e-07 +619 512 -52708333.32467 +620 512 -73187955.04869 +621 512 8.642673492432e-07 +622 512 1.788139343262e-07 +623 512 -190352899.3709 +624 512 1.475214958191e-06 +625 512 52708333.32467 +626 512 -73187955.0487 +639 512 -16471527.78319 +640 512 -13177083.33766 +641 512 -28297094.18124 +642 512 -65886111.10029 +643 512 -2.831220626831e-07 +644 512 -87588646.48668 +645 512 -16471527.78319 +646 512 13177083.33766 +647 512 -28297094.18124 +513 513 913791605.4334 +514 513 7.748603820801e-06 +515 513 -2.622604370117e-06 +516 513 126048980.7912 +517 513 -2.175569534302e-06 +518 513 -1.490116119385e-06 +531 513 -75155545.77471 +532 513 -53333333.32457 +533 513 5.066394805908e-07 +534 513 -198223262.271 +535 513 2.98023223877e-07 +536 513 5.960464477539e-08 +537 513 -75155545.7747 +538 513 53333333.32457 +539 513 -1.490116119385e-08 +603 513 -28555987.69793 +604 513 13333333.33771 +605 513 16471527.78319 +606 513 -88624220.55292 +607 513 1.043081283569e-07 +608 513 65886111.10029 +609 513 -28555987.69793 +610 513 -13333333.33771 +611 513 16471527.78319 +621 513 -7556159.747413 +622 513 -3.278255462646e-07 +623 513 -1.206994056702e-06 +624 513 72174281.7049 +625 513 1.728534698486e-06 +626 513 1.221895217896e-06 +627 513 -7556159.747413 +628 513 -7.450580596924e-07 +629 513 1.341104507446e-06 +642 513 -28555987.69793 +643 513 -13333333.33771 +644 513 -16471527.78319 +645 513 -88624220.55292 +646 513 2.235174179077e-07 +647 513 -65886111.10029 +648 513 -28555987.69793 +649 513 13333333.33771 +650 513 -16471527.78319 +514 514 785785459.402 +515 514 -1.788139343262e-06 +516 514 -2.086162567139e-06 +517 514 -76617423.53181 +518 514 5.066394805908e-07 +531 514 -53333333.32457 +532 514 -59154777.5129 +533 514 2.086162567139e-07 +534 514 3.576278686523e-07 +535 514 36444678.54407 +536 514 -4.172325134277e-07 +537 514 53333333.32457 +538 514 -59154777.5129 +539 514 2.98023223877e-08 +603 514 13333333.33771 +604 514 -24555795.63051 +605 514 -13177083.33766 +606 514 4.470348358154e-08 +607 514 -29957235.32024 +608 514 2.831220626831e-07 +609 514 -13333333.33771 +610 514 -24555795.63051 +611 514 13177083.33766 +621 514 -2.98023223877e-07 +622 514 -58222760.85313 +623 514 -52708333.32467 +624 514 1.728534698486e-06 +625 514 40172745.1813 +626 514 -5.960464477539e-08 +627 514 -7.003545761108e-07 +628 514 -58222760.85313 +629 514 52708333.32467 +642 514 -13333333.33771 +643 514 -24555795.63051 +644 514 -13177083.33766 +645 514 1.9371509552e-07 +646 514 -29957235.32024 +647 514 -3.8743019104e-07 +648 514 13333333.33771 +649 514 -24555795.63051 +650 514 13177083.33766 +515 515 905507012.9075 +516 515 -1.668930053711e-06 +517 515 4.470348358154e-07 +518 515 123977832.6588 +531 515 5.811452865601e-07 +532 515 3.129243850708e-07 +533 515 -9005963.440556 +534 515 1.192092895508e-07 +535 515 -4.768371582031e-07 +536 515 66375066.93519 +537 515 4.470348358154e-08 +538 515 -4.470348358154e-08 +539 515 -9005963.440553 +603 515 16471527.78319 +604 515 -13177083.33766 +605 515 -28297094.18124 +606 515 65886111.10029 +607 515 3.8743019104e-07 +608 515 -87588646.48668 +609 515 16471527.78319 +610 515 13177083.33766 +611 515 -28297094.18124 +621 515 -9.983777999878e-07 +622 515 -52708333.32467 +623 515 -73187955.04869 +624 515 8.642673492432e-07 +625 515 1.788139343262e-07 +626 515 -190352899.3709 +627 515 1.475214958191e-06 +628 515 52708333.32467 +629 515 -73187955.0487 +642 515 -16471527.78319 +643 515 -13177083.33766 +644 515 -28297094.18124 +645 515 -65886111.10029 +646 515 -2.831220626831e-07 +647 515 -87588646.48668 +648 515 -16471527.78319 +649 515 13177083.33766 +650 515 -28297094.18124 +516 516 913791605.4334 +517 516 7.748603820801e-06 +518 516 -2.622604370117e-06 +519 516 126048980.7912 +520 516 -2.175569534302e-06 +521 516 -1.490116119385e-06 +534 516 -75155545.77471 +535 516 -53333333.32457 +536 516 5.066394805908e-07 +537 516 -198223262.271 +538 516 2.98023223877e-07 +539 516 5.960464477539e-08 +540 516 -75155545.7747 +541 516 53333333.32457 +542 516 -1.490116119385e-08 +606 516 -28555987.69793 +607 516 13333333.33771 +608 516 16471527.78319 +609 516 -88624220.55292 +610 516 1.043081283569e-07 +611 516 65886111.10029 +612 516 -28555987.69793 +613 516 -13333333.33771 +614 516 16471527.78319 +624 516 -7556159.747413 +625 516 -3.278255462646e-07 +626 516 -1.206994056702e-06 +627 516 72174281.7049 +628 516 1.728534698486e-06 +629 516 1.221895217896e-06 +630 516 -7556159.747413 +631 516 -7.450580596924e-07 +632 516 1.341104507446e-06 +645 516 -28555987.69793 +646 516 -13333333.33771 +647 516 -16471527.78319 +648 516 -88624220.55292 +649 516 2.235174179077e-07 +650 516 -65886111.10029 +651 516 -28555987.69793 +652 516 13333333.33771 +653 516 -16471527.78319 +517 517 785785459.402 +518 517 -1.788139343262e-06 +519 517 -2.086162567139e-06 +520 517 -76617423.53181 +521 517 5.066394805908e-07 +534 517 -53333333.32457 +535 517 -59154777.5129 +536 517 2.086162567139e-07 +537 517 3.576278686523e-07 +538 517 36444678.54407 +539 517 -4.172325134277e-07 +540 517 53333333.32457 +541 517 -59154777.5129 +542 517 2.98023223877e-08 +606 517 13333333.33771 +607 517 -24555795.63051 +608 517 -13177083.33766 +609 517 4.470348358154e-08 +610 517 -29957235.32024 +611 517 2.831220626831e-07 +612 517 -13333333.33771 +613 517 -24555795.63051 +614 517 13177083.33766 +624 517 -2.98023223877e-07 +625 517 -58222760.85313 +626 517 -52708333.32467 +627 517 1.728534698486e-06 +628 517 40172745.1813 +629 517 -5.960464477539e-08 +630 517 -7.003545761108e-07 +631 517 -58222760.85313 +632 517 52708333.32467 +645 517 -13333333.33771 +646 517 -24555795.63051 +647 517 -13177083.33766 +648 517 1.9371509552e-07 +649 517 -29957235.32024 +650 517 -3.8743019104e-07 +651 517 13333333.33771 +652 517 -24555795.63051 +653 517 13177083.33766 +518 518 905507012.9075 +519 518 -1.668930053711e-06 +520 518 4.470348358154e-07 +521 518 123977832.6588 +534 518 5.811452865601e-07 +535 518 3.129243850708e-07 +536 518 -9005963.440556 +537 518 1.192092895508e-07 +538 518 -4.768371582031e-07 +539 518 66375066.93519 +540 518 4.470348358154e-08 +541 518 -4.470348358154e-08 +542 518 -9005963.440553 +606 518 16471527.78319 +607 518 -13177083.33766 +608 518 -28297094.18124 +609 518 65886111.10029 +610 518 3.8743019104e-07 +611 518 -87588646.48668 +612 518 16471527.78319 +613 518 13177083.33766 +614 518 -28297094.18124 +624 518 -9.983777999878e-07 +625 518 -52708333.32467 +626 518 -73187955.04869 +627 518 8.642673492432e-07 +628 518 1.788139343262e-07 +629 518 -190352899.3709 +630 518 1.475214958191e-06 +631 518 52708333.32467 +632 518 -73187955.0487 +645 518 -16471527.78319 +646 518 -13177083.33766 +647 518 -28297094.18124 +648 518 -65886111.10029 +649 518 -2.831220626831e-07 +650 518 -87588646.48668 +651 518 -16471527.78319 +652 518 13177083.33766 +653 518 -28297094.18124 +519 519 913791605.4334 +520 519 7.748603820801e-06 +521 519 -2.622604370117e-06 +522 519 126048980.7912 +523 519 -2.175569534302e-06 +524 519 -1.490116119385e-06 +537 519 -75155545.77471 +538 519 -53333333.32457 +539 519 5.066394805908e-07 +540 519 -198223262.271 +541 519 2.98023223877e-07 +542 519 5.960464477539e-08 +543 519 -75155545.7747 +544 519 53333333.32457 +545 519 -1.490116119385e-08 +609 519 -28555987.69793 +610 519 13333333.33771 +611 519 16471527.78319 +612 519 -88624220.55292 +613 519 1.043081283569e-07 +614 519 65886111.10029 +615 519 -28555987.69793 +616 519 -13333333.33771 +617 519 16471527.78319 +627 519 -7556159.747413 +628 519 -3.278255462646e-07 +629 519 -1.206994056702e-06 +630 519 72174281.7049 +631 519 1.728534698486e-06 +632 519 1.221895217896e-06 +633 519 -7556159.747413 +634 519 -7.450580596924e-07 +635 519 1.341104507446e-06 +648 519 -28555987.69793 +649 519 -13333333.33771 +650 519 -16471527.78319 +651 519 -88624220.55292 +652 519 2.235174179077e-07 +653 519 -65886111.10029 +654 519 -28555987.69793 +655 519 13333333.33771 +656 519 -16471527.78319 +520 520 785785459.402 +521 520 -1.788139343262e-06 +522 520 -2.086162567139e-06 +523 520 -76617423.53181 +524 520 5.066394805908e-07 +537 520 -53333333.32457 +538 520 -59154777.5129 +539 520 2.086162567139e-07 +540 520 3.576278686523e-07 +541 520 36444678.54407 +542 520 -4.172325134277e-07 +543 520 53333333.32457 +544 520 -59154777.5129 +545 520 2.98023223877e-08 +609 520 13333333.33771 +610 520 -24555795.63051 +611 520 -13177083.33766 +612 520 4.470348358154e-08 +613 520 -29957235.32024 +614 520 2.831220626831e-07 +615 520 -13333333.33771 +616 520 -24555795.63051 +617 520 13177083.33766 +627 520 -2.98023223877e-07 +628 520 -58222760.85313 +629 520 -52708333.32467 +630 520 1.728534698486e-06 +631 520 40172745.1813 +632 520 -5.960464477539e-08 +633 520 -7.003545761108e-07 +634 520 -58222760.85313 +635 520 52708333.32467 +648 520 -13333333.33771 +649 520 -24555795.63051 +650 520 -13177083.33766 +651 520 1.9371509552e-07 +652 520 -29957235.32024 +653 520 -3.8743019104e-07 +654 520 13333333.33771 +655 520 -24555795.63051 +656 520 13177083.33766 +521 521 905507012.9075 +522 521 -1.668930053711e-06 +523 521 4.470348358154e-07 +524 521 123977832.6588 +537 521 5.811452865601e-07 +538 521 3.129243850708e-07 +539 521 -9005963.440556 +540 521 1.192092895508e-07 +541 521 -4.768371582031e-07 +542 521 66375066.93519 +543 521 4.470348358154e-08 +544 521 -4.470348358154e-08 +545 521 -9005963.440553 +609 521 16471527.78319 +610 521 -13177083.33766 +611 521 -28297094.18124 +612 521 65886111.10029 +613 521 3.8743019104e-07 +614 521 -87588646.48668 +615 521 16471527.78319 +616 521 13177083.33766 +617 521 -28297094.18124 +627 521 -9.983777999878e-07 +628 521 -52708333.32467 +629 521 -73187955.04869 +630 521 8.642673492432e-07 +631 521 1.788139343262e-07 +632 521 -190352899.3709 +633 521 1.475214958191e-06 +634 521 52708333.32467 +635 521 -73187955.0487 +648 521 -16471527.78319 +649 521 -13177083.33766 +650 521 -28297094.18124 +651 521 -65886111.10029 +652 521 -2.831220626831e-07 +653 521 -87588646.48668 +654 521 -16471527.78319 +655 521 13177083.33766 +656 521 -28297094.18124 +522 522 886076107.088 +523 522 29506578.58962 +524 522 -4.172325134277e-06 +525 522 -15650105.72171 +526 522 -67995305.55008 +527 522 -1.788139343262e-06 +540 522 -75155545.77471 +541 522 -53333333.32457 +542 522 5.066394805908e-07 +543 522 -169993346.4286 +544 522 13585574.37073 +545 522 1.579523086548e-06 +546 522 -49437968.75893 +547 522 49988791.22677 +548 522 2.637505531311e-06 +612 522 -28555987.69793 +613 522 13333333.33771 +614 522 16471527.78319 +615 522 -87310926.38278 +616 522 -6271409.66235 +617 522 57161110.99975 +630 522 -7556159.747413 +631 522 -3.278255462646e-07 +632 522 -1.206994056702e-06 +633 522 87947441.63499 +634 522 7376644.65104 +635 522 0.02039501070976 +636 522 -32923131.70809 +637 522 -16998826.39589 +638 522 16470833.12799 +651 522 -28555987.69793 +652 522 -13333333.33771 +653 522 -16471527.78319 +654 522 -80272721.40676 +655 522 3396393.594356 +656 522 -61522916.65699 +657 522 -22126192.23639 +658 522 12497197.81285 +659 522 -12109027.78175 +523 523 821417136.7999 +524 523 5.125999450684e-06 +525 523 -67995305.33675 +526 523 -205861449.307 +527 523 -3.56137752533e-06 +540 523 -53333333.32457 +541 523 -59154777.5129 +542 523 2.086162567139e-07 +543 523 13585574.37073 +544 523 48420638.98572 +545 523 8.940696716309e-07 +546 523 49988791.22677 +547 523 -80270449.84323 +548 523 -2.548098564148e-06 +612 523 13333333.33771 +613 523 -24555795.63051 +614 523 -13177083.33766 +615 523 -6271409.715683 +616 523 -27822507.01778 +617 523 6197916.651945 +630 523 -2.98023223877e-07 +631 523 -58222760.85313 +632 523 -52708333.32467 +633 523 7376644.65104 +634 523 71782699.055 +635 523 0.01631674170494 +636 523 -16998826.34256 +637 523 -80475967.62785 +638 523 52708333.09468 +651 523 -13333333.33771 +652 523 -24555795.63051 +653 523 -13177083.33766 +654 523 3396393.594355 +655 523 -25669225.02627 +656 523 3489583.332416 +657 523 12497197.81285 +658 523 -29834312.51126 +659 523 16666666.67214 +524 524 843458196.4419 +525 524 1.192092895508e-07 +526 524 -3.039836883545e-06 +527 524 21637954.44543 +540 524 5.811452865601e-07 +541 524 3.129243850708e-07 +542 524 -9005963.440556 +543 524 6.85453414917e-07 +544 524 1.072883605957e-06 +545 524 73680450.86193 +546 524 1.996755599976e-06 +547 524 -2.592802047729e-06 +548 524 -7752033.245933 +612 524 16471527.78319 +613 524 -13177083.33766 +614 524 -28297094.18124 +615 524 57161110.99975 +616 524 6197916.627155 +617 524 -74255038.56586 +630 524 -9.983777999878e-07 +631 524 -52708333.32467 +632 524 -73187955.04869 +633 524 -0.02039638161659 +634 524 -0.01631587743759 +635 524 -145326344.7753 +636 524 16470833.02261 +637 524 52708333.03516 +638 524 -71952125.45461 +651 524 -16471527.78319 +652 524 -13177083.33766 +653 524 -28297094.18124 +654 524 -61522916.65613 +655 524 3489583.333104 +656 524 -82311580.01855 +657 524 -12109027.78175 +658 524 16666666.67214 +659 524 -27982541.75396 +525 525 531775095.0468 +526 525 8503382.432196 +543 525 -80370018.26376 +544 525 -52907761.3966 +545 525 -1.847743988037e-06 +546 525 -113455777.5588 +547 525 18108359.28725 +548 525 1.311302185059e-06 +549 525 68483060.18779 +550 525 -18744593.63382 +551 525 5.960464477539e-07 +552 525 -42329538.80213 +553 525 49035919.29823 +554 525 1.922249794006e-06 +615 525 -11791159.78616 +616 525 15999999.84526 +617 525 14530833.02455 +633 525 -32923131.7081 +634 525 -16998826.34256 +635 525 -16470833.02261 +636 525 14669982.03611 +637 525 2125845.609096 +638 525 12968611.10898 +654 525 -29859204.61641 +655 525 -13226940.35567 +656 525 -16470833.33874 +657 525 -76387958.09069 +658 525 4527089.824043 +659 525 -64843055.54491 +660 525 -11712307.86994 +661 525 -4686148.410764 +662 525 8424305.555742 +663 525 -24181082.63358 +664 525 12258979.8306 +665 525 -15950694.44968 +526 526 626925818.4292 +527 526 3.933906555176e-06 +543 526 -52907761.3966 +544 526 -54873071.8125 +545 526 -8.642673492432e-07 +546 526 18108359.28725 +547 526 97871879.78123 +548 526 3.337860107422e-06 +549 526 2588739.696008 +550 526 -35173186.25688 +551 526 -3.695487976074e-06 +552 526 49035919.29823 +553 526 -49698043.59219 +554 526 -1.505017280579e-06 +615 526 10666666.5635 +616 526 -19475967.87838 +617 526 -14729166.53156 +633 526 -16998826.39589 +634 526 -80475967.62786 +635 526 -52708333.03516 +636 526 2125845.609096 +637 526 38457662.89345 +638 526 3874999.888226 +654 526 -13226940.35567 +655 526 -23484968.00046 +656 526 -13177083.33766 +657 526 4527089.824043 +658 526 -23556043.72965 +659 526 3489583.332417 +660 526 647184.9243208 +661 526 -37626369.49388 +662 526 33333333.32786 +663 526 12258979.8306 +664 526 -26023208.832 +665 526 16666666.67214 +527 527 650521074.3426 +543 527 -1.788139343262e-06 +544 527 -7.748603820801e-07 +545 527 -9261489.102506 +546 527 1.117587089539e-06 +547 527 3.337860107422e-06 +548 527 131575339.2945 +549 527 1.54972076416e-06 +550 527 -3.75509262085e-06 +551 527 90632596.10001 +552 527 2.279877662659e-06 +553 527 -1.594424247742e-06 +554 527 13362532.26789 +615 527 9687222.01637 +616 527 -18604166.53816 +617 527 -23758284.67089 +633 527 -16470833.12799 +634 527 -52708333.09468 +635 527 -71952125.45462 +636 527 -12968611.10898 +637 527 -3874999.888222 +638 527 -152766509.4438 +654 527 -16470833.33874 +655 527 -13177083.33766 +656 527 -28359905.71829 +657 527 -64843055.54491 +658 527 3489583.333105 +659 527 -95170201.65885 +660 527 299305.5539342 +661 527 33333333.32786 +662 527 -54230045.43137 +663 527 -15950694.44968 +664 527 16666666.67214 +665 527 -32922561.4056 +528 528 456895802.7167 +529 528 3.933906555176e-06 +530 528 -1.668930053711e-06 +531 528 63024490.39562 +532 528 10666666.66491 +533 528 -1.013278961182e-06 +618 528 -88624220.55292 +619 528 1.043081283569e-07 +620 528 65886111.10029 +621 528 -28555987.69793 +622 528 -13333333.33771 +623 528 16471527.78319 +639 528 36087140.85245 +640 528 8.344650268555e-07 +641 528 -13177222.22006 +642 528 -3778079.873706 +643 528 2666666.667542 +644 528 -3294305.556637 +529 529 392892729.701 +530 529 -7.152557373047e-07 +531 529 -10666666.66491 +532 529 -38308711.7659 +533 529 3.8743019104e-07 +618 529 4.470348358154e-08 +619 529 -29957235.32024 +620 529 2.831220626831e-07 +621 529 -13333333.33771 +622 529 -24555795.63051 +623 529 13177083.33766 +639 529 8.940696716309e-07 +640 529 20086372.59065 +641 529 -2.98023223877e-08 +642 529 -2666666.667543 +643 529 -29111380.42657 +644 529 26354166.66234 +530 530 452753506.4538 +531 530 -8.940696716309e-07 +532 530 1.490116119385e-07 +533 530 61988916.32938 +618 530 65886111.10029 +619 530 3.8743019104e-07 +620 530 -87588646.48668 +621 530 16471527.78319 +622 530 13177083.33766 +623 530 -28297094.18124 +639 530 13177222.22006 +640 530 1.490116119385e-07 +641 530 -95176449.68545 +642 530 3294305.556638 +643 530 26354166.66234 +644 530 -36593977.52435 +531 531 456895802.7167 +532 531 3.933906555176e-06 +533 531 -1.668930053711e-06 +534 531 63024490.39562 +535 531 10666666.66491 +536 531 -1.013278961182e-06 +618 531 -28555987.69793 +619 531 13333333.33771 +620 531 16471527.78319 +621 531 -88624220.55292 +622 531 1.043081283569e-07 +623 531 65886111.10029 +624 531 -28555987.69793 +625 531 -13333333.33771 +626 531 16471527.78319 +639 531 -3778079.873706 +640 531 -2666666.667542 +641 531 -3294305.556638 +642 531 36087140.85245 +643 531 8.344650268555e-07 +644 531 -13177222.22006 +645 531 -3778079.873706 +646 531 2666666.667542 +647 531 -3294305.556637 +532 532 392892729.701 +533 532 -7.152557373047e-07 +534 532 -10666666.66491 +535 532 -38308711.7659 +536 532 3.8743019104e-07 +618 532 13333333.33771 +619 532 -24555795.63051 +620 532 -13177083.33766 +621 532 4.470348358154e-08 +622 532 -29957235.32024 +623 532 2.831220626831e-07 +624 532 -13333333.33771 +625 532 -24555795.63051 +626 532 13177083.33766 +639 532 2666666.667542 +640 532 -29111380.42657 +641 532 -26354166.66234 +642 532 8.940696716309e-07 +643 532 20086372.59065 +644 532 -2.98023223877e-08 +645 532 -2666666.667543 +646 532 -29111380.42657 +647 532 26354166.66234 +533 533 452753506.4538 +534 533 -8.940696716309e-07 +535 533 1.490116119385e-07 +536 533 61988916.32938 +618 533 16471527.78319 +619 533 -13177083.33766 +620 533 -28297094.18124 +621 533 65886111.10029 +622 533 3.8743019104e-07 +623 533 -87588646.48668 +624 533 16471527.78319 +625 533 13177083.33766 +626 533 -28297094.18124 +639 533 3294305.556637 +640 533 -26354166.66234 +641 533 -36593977.52435 +642 533 13177222.22006 +643 533 1.490116119385e-07 +644 533 -95176449.68545 +645 533 3294305.556638 +646 533 26354166.66234 +647 533 -36593977.52435 +534 534 456895802.7167 +535 534 3.933906555176e-06 +536 534 -1.668930053711e-06 +537 534 63024490.39562 +538 534 10666666.66491 +539 534 -1.013278961182e-06 +621 534 -28555987.69793 +622 534 13333333.33771 +623 534 16471527.78319 +624 534 -88624220.55292 +625 534 1.043081283569e-07 +626 534 65886111.10029 +627 534 -28555987.69793 +628 534 -13333333.33771 +629 534 16471527.78319 +642 534 -3778079.873706 +643 534 -2666666.667542 +644 534 -3294305.556638 +645 534 36087140.85245 +646 534 8.344650268555e-07 +647 534 -13177222.22006 +648 534 -3778079.873706 +649 534 2666666.667542 +650 534 -3294305.556637 +535 535 392892729.701 +536 535 -7.152557373047e-07 +537 535 -10666666.66491 +538 535 -38308711.7659 +539 535 3.8743019104e-07 +621 535 13333333.33771 +622 535 -24555795.63051 +623 535 -13177083.33766 +624 535 4.470348358154e-08 +625 535 -29957235.32024 +626 535 2.831220626831e-07 +627 535 -13333333.33771 +628 535 -24555795.63051 +629 535 13177083.33766 +642 535 2666666.667542 +643 535 -29111380.42657 +644 535 -26354166.66234 +645 535 8.940696716309e-07 +646 535 20086372.59065 +647 535 -2.98023223877e-08 +648 535 -2666666.667543 +649 535 -29111380.42657 +650 535 26354166.66234 +536 536 452753506.4538 +537 536 -8.940696716309e-07 +538 536 1.490116119385e-07 +539 536 61988916.32938 +621 536 16471527.78319 +622 536 -13177083.33766 +623 536 -28297094.18124 +624 536 65886111.10029 +625 536 3.8743019104e-07 +626 536 -87588646.48668 +627 536 16471527.78319 +628 536 13177083.33766 +629 536 -28297094.18124 +642 536 3294305.556637 +643 536 -26354166.66234 +644 536 -36593977.52435 +645 536 13177222.22006 +646 536 1.490116119385e-07 +647 536 -95176449.68545 +648 536 3294305.556638 +649 536 26354166.66234 +650 536 -36593977.52435 +537 537 456895802.7167 +538 537 3.933906555176e-06 +539 537 -1.668930053711e-06 +540 537 63024490.39562 +541 537 10666666.66491 +542 537 -1.013278961182e-06 +624 537 -28555987.69793 +625 537 13333333.33771 +626 537 16471527.78319 +627 537 -88624220.55292 +628 537 1.043081283569e-07 +629 537 65886111.10029 +630 537 -28555987.69793 +631 537 -13333333.33771 +632 537 16471527.78319 +645 537 -3778079.873706 +646 537 -2666666.667542 +647 537 -3294305.556638 +648 537 36087140.85245 +649 537 8.344650268555e-07 +650 537 -13177222.22006 +651 537 -3778079.873706 +652 537 2666666.667542 +653 537 -3294305.556637 +538 538 392892729.701 +539 538 -7.152557373047e-07 +540 538 -10666666.66491 +541 538 -38308711.7659 +542 538 3.8743019104e-07 +624 538 13333333.33771 +625 538 -24555795.63051 +626 538 -13177083.33766 +627 538 4.470348358154e-08 +628 538 -29957235.32024 +629 538 2.831220626831e-07 +630 538 -13333333.33771 +631 538 -24555795.63051 +632 538 13177083.33766 +645 538 2666666.667542 +646 538 -29111380.42657 +647 538 -26354166.66234 +648 538 8.940696716309e-07 +649 538 20086372.59065 +650 538 -2.98023223877e-08 +651 538 -2666666.667543 +652 538 -29111380.42657 +653 538 26354166.66234 +539 539 452753506.4538 +540 539 -8.940696716309e-07 +541 539 1.490116119385e-07 +542 539 61988916.32938 +624 539 16471527.78319 +625 539 -13177083.33766 +626 539 -28297094.18124 +627 539 65886111.10029 +628 539 3.8743019104e-07 +629 539 -87588646.48668 +630 539 16471527.78319 +631 539 13177083.33766 +632 539 -28297094.18124 +645 539 3294305.556637 +646 539 -26354166.66234 +647 539 -36593977.52435 +648 539 13177222.22006 +649 539 1.490116119385e-07 +650 539 -95176449.68545 +651 539 3294305.556638 +652 539 26354166.66234 +653 539 -36593977.52435 +540 540 456895802.7167 +541 540 3.933906555176e-06 +542 540 -1.668930053711e-06 +543 540 63024490.39562 +544 540 10666666.66491 +545 540 -1.013278961182e-06 +627 540 -28555987.69793 +628 540 13333333.33771 +629 540 16471527.78319 +630 540 -88624220.55292 +631 540 1.043081283569e-07 +632 540 65886111.10029 +633 540 -28555987.69793 +634 540 -13333333.33771 +635 540 16471527.78319 +648 540 -3778079.873706 +649 540 -2666666.667542 +650 540 -3294305.556638 +651 540 36087140.85245 +652 540 8.344650268555e-07 +653 540 -13177222.22006 +654 540 -3778079.873706 +655 540 2666666.667542 +656 540 -3294305.556637 +541 541 392892729.701 +542 541 -7.152557373047e-07 +543 541 -10666666.66491 +544 541 -38308711.7659 +545 541 3.8743019104e-07 +627 541 13333333.33771 +628 541 -24555795.63051 +629 541 -13177083.33766 +630 541 4.470348358154e-08 +631 541 -29957235.32024 +632 541 2.831220626831e-07 +633 541 -13333333.33771 +634 541 -24555795.63051 +635 541 13177083.33766 +648 541 2666666.667542 +649 541 -29111380.42657 +650 541 -26354166.66234 +651 541 8.940696716309e-07 +652 541 20086372.59065 +653 541 -2.98023223877e-08 +654 541 -2666666.667543 +655 541 -29111380.42657 +656 541 26354166.66234 +542 542 452753506.4538 +543 542 -8.940696716309e-07 +544 542 1.490116119385e-07 +545 542 61988916.32938 +627 542 16471527.78319 +628 542 -13177083.33766 +629 542 -28297094.18124 +630 542 65886111.10029 +631 542 3.8743019104e-07 +632 542 -87588646.48668 +633 542 16471527.78319 +634 542 13177083.33766 +635 542 -28297094.18124 +648 542 3294305.556637 +649 542 -26354166.66234 +650 542 -36593977.52435 +651 542 13177222.22006 +652 542 1.490116119385e-07 +653 542 -95176449.68545 +654 542 3294305.556638 +655 542 26354166.66234 +656 542 -36593977.52435 +543 543 451672659.2548 +544 543 425457.3069872 +546 543 45227333.73336 +547 543 -3769936.940774 +548 543 5.960464477539e-07 +630 543 -28555987.69793 +631 543 13333333.33771 +632 543 16471527.78319 +633 543 -80272721.40676 +634 543 3396393.594356 +635 543 61522916.65613 +636 543 -29859204.61641 +637 543 -13226940.35567 +638 543 16470833.33874 +651 543 -3778079.873706 +652 543 -2666666.667542 +653 543 -3294305.556638 +654 543 34782980.96289 +655 543 106364.3267991 +656 543 -13176944.44228 +657 543 -9519773.826407 +658 543 -942484.2356579 +659 543 1067638.88752 +544 544 397175038.8898 +545 544 1.072883605957e-06 +546 544 -25103270.2706 +547 544 -58853543.86754 +548 544 -1.341104507446e-06 +630 544 13333333.33771 +631 544 -24555795.63051 +632 544 -13177083.33766 +633 544 3396393.594355 +634 544 -25669225.02627 +635 544 -3489583.333104 +636 544 -13226940.35567 +637 544 -23484968.00045 +638 544 13177083.33766 +651 544 2666666.667542 +652 544 -29111380.42657 +653 544 -26354166.66234 +654 544 106364.3267991 +655 544 21158575.86493 +656 544 2.682209014893e-07 +657 544 -6275817.570742 +658 544 -35539993.23945 +659 544 29843749.99544 +545 545 452492316.5668 +547 545 -1.490116119385e-06 +548 545 55187296.56271 +630 545 16471527.78319 +631 545 -13177083.33766 +632 545 -28297094.18124 +633 545 61522916.65699 +634 545 -3489583.332416 +635 545 -82311580.01855 +636 545 16470833.33874 +637 545 13177083.33766 +638 545 -28359905.71829 +651 545 3294305.556637 +652 545 -26354166.66234 +653 545 -36593977.52435 +654 545 13176944.44228 +655 545 3.8743019104e-07 +656 545 -95237411.21973 +657 545 7655972.222158 +658 545 29843749.99475 +659 545 -41740795.2267 +546 546 444644489.1745 +547 546 13081929.57058 +548 546 9.536743164063e-07 +549 546 -86994427.68368 +550 546 -57630747.35091 +551 546 -2.384185791016e-06 +552 546 44204118.01812 +553 546 1554937.536914 +554 546 -1.192092895508e-06 +633 546 -22126192.23639 +634 546 12497197.81285 +635 546 12109027.78176 +636 546 -76387958.09069 +637 546 4527089.824043 +638 546 64843055.54491 +654 546 -9519773.826409 +655 546 -6275817.570743 +656 546 -7655972.222158 +657 546 15798034.7999 +658 546 3270482.394257 +659 546 -12968611.10898 +660 546 -35347304.85947 +661 546 -14407686.84483 +662 546 20312500.00667 +663 546 -14510689.24923 +664 546 388734.3844201 +665 546 1171666.664472 +547 547 449754245.7917 +548 547 4.64916229248e-06 +549 547 -57630747.35091 +550 547 -66447376.92277 +551 547 -1.296401023865e-06 +552 547 -19778395.79291 +553 547 -57866988.0148 +554 547 -2.086162567139e-06 +633 547 12497197.81285 +634 547 -29834312.51127 +635 547 -16666666.67214 +636 547 4527089.824043 +637 547 -23556043.72965 +638 547 -3489583.333103 +654 547 -942484.2356579 +655 547 -35539993.23945 +656 547 -29843749.99475 +657 547 3270482.394257 +658 547 17075473.95481 +659 547 9.536743164063e-07 +660 547 -14407686.84483 +661 547 -30210542.16671 +662 547 16666666.67214 +663 547 -4944598.950664 +664 547 -40028465.77003 +665 547 33333333.32786 +548 548 513640710.6392 +549 548 -3.159046173096e-06 +550 548 -1.370906829834e-06 +551 548 -3386801.062691 +552 548 -1.907348632813e-06 +553 548 -2.235174179077e-06 +554 548 68569532.94435 +633 548 12109027.78176 +634 548 -16666666.67214 +635 548 -27982541.75396 +636 548 64843055.54491 +637 548 -3489583.332416 +638 548 -95170201.65886 +654 548 -1067638.887521 +655 548 -29843749.99544 +656 548 -41740795.22671 +657 548 12968611.10898 +658 548 1.013278961182e-06 +659 548 -125891389.0729 +660 548 20312500.00667 +661 548 16666666.67214 +662 548 -37109894.74031 +663 548 7551944.445205 +664 548 33333333.32786 +665 548 -51022200.11333 +549 549 254849231.4225 +550 549 61411260.29348 +551 549 3.814697265625e-06 +552 549 -66610780.59762 +553 549 -6369252.63857 +554 549 -1.132488250732e-06 +636 549 -11712307.86995 +637 549 647184.9243208 +638 549 -299305.5539346 +657 549 -35347304.85947 +658 549 -14407686.84483 +659 549 -20312500.00667 +660 549 6046162.064774 +661 549 15352815.08093 +662 549 8124999.998666 +663 549 -43850090.99987 +664 549 -1592313.160427 +665 549 -36263194.43806 +550 550 228505477.8886 +551 550 4.172325134277e-06 +552 550 14964080.69126 +553 550 42842168.62011 +554 550 1.728534698486e-06 +636 550 -4686148.410764 +637 550 -37626369.49388 +638 550 -33333333.32786 +657 550 -14407686.84483 +658 550 -30210542.16671 +659 550 -16666666.67214 +660 550 15352815.08093 +661 550 -539776.3219635 +662 550 6666666.665572 +663 550 3741020.174657 +664 550 -16486853.68196 +665 550 3333333.334428 +551 551 294920181.6058 +553 551 1.788139343262e-06 +554 551 70439578.90092 +636 551 -8424305.555743 +637 551 -33333333.32786 +638 551 -54230045.43139 +657 551 -20312500.00667 +658 551 -16666666.67214 +659 551 -37109894.74031 +660 551 -8124999.998665 +661 551 -6666666.665571 +662 551 -80046343.42155 +663 551 -36263194.43892 +664 551 -3333333.334428 +665 551 -54916494.1788 +552 552 221377868.0526 +553 552 -44221604.19657 +554 552 -1.311302185059e-06 +636 552 -24181082.63358 +637 552 12258979.8306 +638 552 15950694.44968 +657 552 -14510689.24923 +658 552 -4944598.950664 +659 552 -7551944.445206 +660 552 -43850090.99987 +661 552 3741020.174657 +662 552 36263194.43892 +663 552 4221029.5472 +664 552 -11055401.05459 +665 552 -6380277.77673 +553 553 221364529.6578 +554 553 2.861022949219e-06 +636 553 12258979.8306 +637 553 -26023208.832 +638 553 -16666666.67214 +657 553 388734.38442 +658 553 -40028465.77003 +659 553 -33333333.32786 +660 553 -1592313.160427 +661 553 -16486853.68196 +662 553 3333333.334428 +663 553 -11055401.05459 +664 553 4217694.948508 +665 553 6666666.665572 +554 554 265339467.0094 +636 554 15950694.44968 +637 554 -16666666.67214 +638 554 -32922561.4056 +657 554 -1171666.664473 +658 554 -33333333.32786 +659 554 -51022200.11334 +660 554 36263194.43806 +661 554 -3333333.334428 +662 554 -54916494.1788 +663 554 6380277.77673 +664 554 -6666666.665571 +665 554 -69994299.86354 +555 555 583376284.5667 +556 555 43333333.32621 +557 555 -18054493.30016 +558 555 -212203317.245 +559 555 -43342510.83425 +560 555 16396980.83364 +561 555 11333216.7726 +562 555 34675844.16901 +563 555 12517770.08628 +666 555 -10929001.68405 +667 555 8333333.33607 +668 555 3726516.388097 +669 555 -69036918.95254 +670 555 -8338077.039497 +671 555 -55624567.39871 +672 555 7014515.850343 +673 555 6671410.372285 +674 555 -6514983.987003 +556 556 518362818.9365 +557 556 40035087.57113 +558 556 -43347099.58827 +559 556 -8506300.789178 +560 556 23165903.31214 +561 556 52013766.25352 +562 556 11333216.7726 +563 556 -14999325.89734 +666 556 8333333.336069 +667 556 -23434958.63979 +668 556 30221022.26397 +669 556 -8340448.891212 +670 556 -29855098.36736 +671 556 -1182917.166231 +672 556 10007115.55843 +673 556 7014515.850342 +674 556 7818288.469344 +557 557 777948189.0547 +558 557 15568224.60039 +559 557 18499461.34631 +560 557 73162839.64451 +561 557 18776655.12942 +562 557 -9999550.598229 +563 557 30221911.39361 +666 557 -21803668.18463 +667 557 9797097.079457 +668 557 -178746028.6722 +669 557 -56043408.3313 +670 557 -3514321.011405 +671 557 -61172289.98812 +672 557 -9772475.980504 +673 557 5212192.312896 +674 557 18705375.60092 +558 558 939476176.8883 +559 558 43356277.09631 +560 558 -18771852.99502 +561 558 49283631.66647 +562 558 -43342510.83425 +563 558 -16337221.96865 +564 558 -128333063.0188 +565 558 1.341104507446e-07 +566 558 3194474.194728 +567 558 -60367995.80692 +568 558 43333333.32622 +569 558 16319451.87991 +666 558 -99681629.70551 +667 558 -8340448.891213 +668 558 71607514.53236 +669 558 -8298175.66356 +670 558 8345192.594641 +671 558 -9379478.645899 +672 558 2423001.606932 +673 558 -8338077.0395 +674 558 7795396.873343 +675 558 -69751628.43939 +676 558 1.266598701477e-06 +677 558 -62205540.42245 +678 558 -11071939.81576 +679 558 8333333.336071 +680 558 -7790968.444033 +559 559 822460198.9193 +560 559 51648672.72297 +561 559 -43347099.58827 +562 559 -102400547.2501 +563 559 -28003452.87548 +564 559 -1.192092895508e-07 +565 559 62334645.32605 +566 559 16666488.1637 +567 559 43333333.32622 +568 559 -47367367.71582 +569 559 -9166577.415131 +666 559 -8338077.039499 +667 559 -60499809.12032 +668 559 22021029.70742 +669 559 8345192.594641 +670 559 -30804628.63791 +671 559 25829490.35962 +672 559 -8340448.891214 +673 559 -26752986.0284 +674 559 37056208.64825 +675 559 7.376074790955e-07 +676 559 -33084756.09483 +677 559 8333242.6046 +678 559 8333333.336071 +679 559 -8571815.80988 +680 559 8177128.701754 +560 560 1105469191.389 +561 560 -16346107.01282 +562 560 -32013997.77403 +563 560 114586890.8952 +564 560 2361140.861532 +565 560 16666488.1637 +566 560 141192013.134 +567 560 16319451.87971 +568 560 -9166577.414967 +569 560 -5461644.444274 +666 560 72026355.46494 +667 560 24359692.24116 +668 560 -142891518.6627 +669 560 -9370405.180087 +670 560 25836749.05321 +671 560 -291361037.6863 +672 560 7797611.087997 +673 560 35054390.19536 +674 560 3229564.966024 +675 560 -62622207.08884 +676 560 8333242.6046 +677 560 -93040173.76232 +678 560 -7790968.444033 +679 560 8177128.701754 +680 560 382463.4398733 +561 561 583376284.5667 +562 561 43333333.32621 +563 561 -18054493.30016 +564 561 -58492995.80723 +565 561 -43333333.32622 +566 561 -14930548.11496 +567 561 -212203317.245 +568 561 -43342510.83425 +569 561 16396980.83364 +570 561 11333216.7726 +571 561 34675844.16901 +572 561 12517770.08628 +666 561 -50448491.13742 +667 561 10007115.55843 +668 561 28536410.43085 +669 561 -85645347.16108 +670 561 -8340448.891212 +671 561 -24130997.54348 +672 561 -10929001.68405 +673 561 8333333.33607 +674 561 3726516.388097 +675 561 -38845377.32488 +676 561 -8333333.33607 +677 561 -23415968.44916 +678 561 -69036918.95254 +679 561 -8338077.039497 +680 561 -55624567.39871 +681 561 7014515.850343 +682 561 6671410.372285 +683 561 -6514983.987003 +562 562 518362818.9365 +563 562 40035087.57113 +564 562 -43333333.32622 +565 562 -45492367.71613 +566 562 -7499910.748575 +567 562 -43347099.58827 +568 562 -8506300.789178 +569 562 23165903.31214 +570 562 52013766.25352 +571 562 11333216.7726 +572 562 -14999325.89734 +666 562 6671410.372285 +667 562 -50448491.13742 +668 562 -15218991.7376 +669 562 -8338077.039498 +670 562 -114821334.7964 +671 562 -67065236.07198 +672 562 8333333.336069 +673 562 -23434958.63979 +674 562 30221022.26397 +675 562 -8333333.33607 +676 562 -36345253.319 +677 562 -16510371.30635 +678 562 -8340448.891212 +679 562 -29855098.36736 +680 562 -1182917.166231 +681 562 10007115.55843 +682 562 7014515.850342 +683 562 7818288.469344 +563 563 777948189.0547 +564 563 -14930548.11516 +565 563 -7499910.748739 +566 563 -461644.445098 +567 563 15568224.60039 +568 563 18499461.34631 +569 563 73162839.64451 +570 563 18776655.12942 +571 563 -9999550.598229 +572 563 30221911.39361 +666 563 19024273.62057 +667 563 -22828487.60639 +668 563 -134529309.6998 +669 563 -24124138.5141 +670 563 -65063417.79147 +671 563 -231619365.082 +672 563 -21803668.18463 +673 563 9797097.079457 +674 563 -178746028.6722 +675 563 -23415968.44916 +676 563 -16510371.30635 +677 563 -73680036.58444 +678 563 -56043408.3313 +679 563 -3514321.011405 +680 563 -61172289.98812 +681 563 -9772475.980504 +682 563 5212192.312896 +683 563 18705375.60092 +564 564 866359460.9496 +565 564 1.430511474609e-06 +566 564 -5555615.056281 +567 564 107138445.2518 +568 564 -2.831220626831e-07 +569 564 -1388903.764753 +573 564 -128333063.0188 +574 564 1.341104507446e-07 +575 564 3194474.194728 +576 564 -60367995.80692 +577 564 43333333.32622 +578 564 16319451.87991 +669 564 -77407961.77148 +670 564 -1.184642314911e-06 +671 564 64983348.44575 +672 564 -12048523.14942 +673 564 -8333333.336071 +674 564 8485420.4502 +675 564 -27191273.16515 +676 564 2.98023223877e-07 +677 564 -2777808.023288 +678 564 20509800.90325 +679 564 -2.242624759674e-06 +680 564 -694452.0061662 +684 564 -69751628.43939 +685 564 1.266598701477e-06 +686 564 -62205540.42245 +687 564 -11071939.81576 +688 564 8333333.336071 +689 564 -7790968.444033 +565 565 762354436.272 +566 565 66665952.62197 +567 565 -6.556510925293e-07 +568 565 -57528006.93644 +569 565 -33666309.64427 +573 565 -1.192092895508e-07 +574 565 62334645.32605 +575 565 16666488.1637 +576 565 43333333.32622 +577 565 -47367367.71582 +578 565 -9166577.415131 +669 565 -1.601874828339e-06 +670 565 -40741089.4269 +671 565 8333242.604601 +672 565 -8333333.336071 +673 565 -9548399.143536 +674 565 9010462.03536 +675 565 2.384185791016e-07 +676 565 -47192265.20236 +677 565 33332970.40198 +678 565 -1.728534698486e-06 +679 565 -11156823.43448 +680 565 34208514.79074 +684 565 7.376074790955e-07 +685 565 -33084756.09483 +686 565 8333242.6046 +687 565 8333333.336071 +688 565 -8571815.80988 +689 565 8177128.701754 +566 566 1066134474.818 +567 566 -1388903.764753 +568 566 -32999642.97771 +569 566 113328361.2626 +573 566 2361140.861532 +574 566 16666488.1637 +575 566 141192013.134 +576 566 16319451.87971 +577 566 -9166577.414967 +578 566 -5461644.444274 +669 566 65400015.11214 +670 566 8333242.604601 +671 566 -113457062.6479 +672 566 8485420.4502 +673 566 9010462.03536 +674 566 -2221758.783205 +675 566 -2777808.023289 +676 566 33332970.40198 +677 566 -311771151.9111 +678 566 -694452.006166 +679 566 34541848.12385 +680 566 21543906.17081 +684 566 -62622207.08884 +685 566 8333242.6046 +686 566 -93040173.76232 +687 566 -7790968.444033 +688 566 8177128.701754 +689 566 382463.4398733 +567 567 939476176.8883 +568 567 43356277.09631 +569 567 -18771852.99502 +570 567 49283631.66647 +571 567 -43342510.83425 +572 567 -16337221.96865 +573 567 -58492995.80723 +574 567 -43333333.32622 +575 567 -14930548.11496 +576 567 -128333063.0188 +577 567 1.341104507446e-07 +578 567 3194474.194728 +579 567 -60367995.80692 +580 567 43333333.32622 +581 567 16319451.87991 +669 567 -41696960.65915 +670 567 8333333.336071 +671 567 24110420.45533 +672 567 -99681629.70551 +673 567 -8340448.891213 +674 567 71607514.53236 +675 567 -94333949.07787 +676 567 1.773238182068e-06 +677 567 -694452.0061627 +678 567 -8298175.66356 +679 567 8345192.594641 +680 567 -9379478.645899 +681 567 2423001.606932 +682 567 -8338077.0395 +683 567 7795396.873343 +684 567 -38845377.32488 +685 567 -8333333.33607 +686 567 -23415968.44916 +687 567 -69751628.43939 +688 567 1.266598701477e-06 +689 567 -62205540.42245 +690 567 -11071939.81576 +691 567 8333333.336071 +692 567 -7790968.444033 +568 568 822460198.9193 +569 568 51648672.72297 +570 568 -43347099.58827 +571 568 -102400547.2501 +572 568 -28003452.87548 +573 568 -43333333.32622 +574 568 -45492367.71613 +575 568 -7499910.748575 +576 568 -1.192092895508e-07 +577 568 62334645.32605 +578 568 16666488.1637 +579 568 43333333.32622 +580 568 -47367367.71582 +581 568 -9166577.415131 +669 568 8333333.336071 +670 568 -39196836.65327 +671 568 -17343704.63996 +672 568 -8338077.039499 +673 568 -60499809.12032 +674 568 22021029.70742 +675 568 2.175569534302e-06 +676 568 -126000573.4156 +677 568 -67541485.19271 +678 568 8345192.594641 +679 568 -30804628.63791 +680 568 25829490.35962 +681 568 -8340448.891214 +682 568 -26752986.0284 +683 568 37056208.64825 +684 568 -8333333.33607 +685 568 -36345253.319 +686 568 -16510371.30635 +687 568 7.376074790955e-07 +688 568 -33084756.09483 +689 568 8333242.6046 +690 568 8333333.336071 +691 568 -8571815.80988 +692 568 8177128.701754 +569 569 1105469191.389 +570 569 -16346107.01282 +571 569 -32013997.77403 +572 569 114586890.8952 +573 569 -14930548.11516 +574 569 -7499910.748739 +575 569 -461644.445098 +576 569 2361140.861532 +577 569 16666488.1637 +578 569 141192013.134 +579 569 16319451.87971 +580 569 -9166577.414967 +581 569 -5461644.444274 +669 569 24110420.45533 +670 569 -17343704.63996 +671 569 -81284258.80916 +672 569 72026355.46494 +673 569 24359692.24116 +674 569 -142891518.6627 +675 569 -694452.0061623 +676 569 -67874818.52582 +677 569 -284706093.7789 +678 569 -9370405.180087 +679 569 25836749.05321 +680 569 -291361037.6863 +681 569 7797611.087997 +682 569 35054390.19536 +683 569 3229564.966024 +684 569 -23415968.44916 +685 569 -16510371.30635 +686 569 -73680036.58444 +687 569 -62622207.08884 +688 569 8333242.6046 +689 569 -93040173.76232 +690 569 -7790968.444033 +691 569 8177128.701754 +692 569 382463.4398733 +570 570 583376284.5667 +571 570 43333333.32621 +572 570 -18054493.30016 +576 570 -58492995.80723 +577 570 -43333333.32622 +578 570 -14930548.11496 +579 570 -212203317.245 +580 570 -43342510.83425 +581 570 16396980.83364 +582 570 11333216.7726 +583 570 34675844.16901 +584 570 12517770.08628 +672 570 -50448491.13742 +673 570 10007115.55843 +674 570 28536410.43085 +678 570 -85645347.16108 +679 570 -8340448.891212 +680 570 -24130997.54348 +681 570 -10929001.68405 +682 570 8333333.33607 +683 570 3726516.388097 +687 570 -38845377.32488 +688 570 -8333333.33607 +689 570 -23415968.44916 +690 570 -69036918.95254 +691 570 -8338077.039497 +692 570 -55624567.39871 +693 570 7014515.850343 +694 570 6671410.372285 +695 570 -6514983.987003 +571 571 518362818.9365 +572 571 40035087.57113 +576 571 -43333333.32622 +577 571 -45492367.71613 +578 571 -7499910.748575 +579 571 -43347099.58827 +580 571 -8506300.789178 +581 571 23165903.31214 +582 571 52013766.25352 +583 571 11333216.7726 +584 571 -14999325.89734 +672 571 6671410.372285 +673 571 -50448491.13742 +674 571 -15218991.7376 +678 571 -8338077.039498 +679 571 -114821334.7964 +680 571 -67065236.07198 +681 571 8333333.336069 +682 571 -23434958.63979 +683 571 30221022.26397 +687 571 -8333333.33607 +688 571 -36345253.319 +689 571 -16510371.30635 +690 571 -8340448.891212 +691 571 -29855098.36736 +692 571 -1182917.166231 +693 571 10007115.55843 +694 571 7014515.850342 +695 571 7818288.469344 +572 572 777948189.0547 +576 572 -14930548.11516 +577 572 -7499910.748739 +578 572 -461644.445098 +579 572 15568224.60039 +580 572 18499461.34631 +581 572 73162839.64451 +582 572 18776655.12942 +583 572 -9999550.598229 +584 572 30221911.39361 +672 572 19024273.62057 +673 572 -22828487.60639 +674 572 -134529309.6998 +678 572 -24124138.5141 +679 572 -65063417.79147 +680 572 -231619365.082 +681 572 -21803668.18463 +682 572 9797097.079457 +683 572 -178746028.6722 +687 572 -23415968.44916 +688 572 -16510371.30635 +689 572 -73680036.58444 +690 572 -56043408.3313 +691 572 -3514321.011405 +692 572 -61172289.98812 +693 572 -9772475.980504 +694 572 5212192.312896 +695 572 18705375.60092 +573 573 866359460.9496 +574 573 1.430511474609e-06 +575 573 -5555615.056281 +576 573 107138445.2518 +577 573 -2.831220626831e-07 +578 573 -1388903.764753 +585 573 -128333063.0188 +586 573 1.341104507446e-07 +587 573 3194474.194728 +588 573 -60367995.80692 +589 573 43333333.32622 +590 573 16319451.87991 +675 573 -77407961.77148 +676 573 -1.184642314911e-06 +677 573 64983348.44575 +678 573 -12048523.14942 +679 573 -8333333.336071 +680 573 8485420.4502 +684 573 -27191273.16515 +685 573 2.98023223877e-07 +686 573 -2777808.023288 +687 573 20509800.90325 +688 573 -2.242624759674e-06 +689 573 -694452.0061662 +696 573 -69751628.43939 +697 573 1.266598701477e-06 +698 573 -62205540.42245 +699 573 -11071939.81576 +700 573 8333333.336071 +701 573 -7790968.444033 +574 574 762354436.272 +575 574 66665952.62197 +576 574 -6.556510925293e-07 +577 574 -57528006.93644 +578 574 -33666309.64427 +585 574 -1.192092895508e-07 +586 574 62334645.32605 +587 574 16666488.1637 +588 574 43333333.32622 +589 574 -47367367.71582 +590 574 -9166577.415131 +675 574 -1.601874828339e-06 +676 574 -40741089.4269 +677 574 8333242.604601 +678 574 -8333333.336071 +679 574 -9548399.143536 +680 574 9010462.03536 +684 574 2.384185791016e-07 +685 574 -47192265.20236 +686 574 33332970.40198 +687 574 -1.728534698486e-06 +688 574 -11156823.43448 +689 574 34208514.79074 +696 574 7.376074790955e-07 +697 574 -33084756.09483 +698 574 8333242.6046 +699 574 8333333.336071 +700 574 -8571815.80988 +701 574 8177128.701754 +575 575 1066134474.818 +576 575 -1388903.764753 +577 575 -32999642.97771 +578 575 113328361.2626 +585 575 2361140.861532 +586 575 16666488.1637 +587 575 141192013.134 +588 575 16319451.87971 +589 575 -9166577.414967 +590 575 -5461644.444274 +675 575 65400015.11214 +676 575 8333242.604601 +677 575 -113457062.6479 +678 575 8485420.4502 +679 575 9010462.03536 +680 575 -2221758.783205 +684 575 -2777808.023289 +685 575 33332970.40198 +686 575 -311771151.9111 +687 575 -694452.006166 +688 575 34541848.12385 +689 575 21543906.17081 +696 575 -62622207.08884 +697 575 8333242.6046 +698 575 -93040173.76232 +699 575 -7790968.444033 +700 575 8177128.701754 +701 575 382463.4398733 +576 576 866359460.9496 +577 576 1.430511474609e-06 +578 576 -5555615.056281 +579 576 107138445.2518 +580 576 -2.831220626831e-07 +581 576 -1388903.764753 +585 576 -58492995.80723 +586 576 -43333333.32622 +587 576 -14930548.11496 +588 576 -128333063.0188 +589 576 1.341104507446e-07 +590 576 3194474.194728 +591 576 -60367995.80692 +592 576 43333333.32622 +593 576 16319451.87991 +675 576 -41696960.65915 +676 576 8333333.336071 +677 576 24110420.45533 +678 576 -77407961.77148 +679 576 -1.184642314911e-06 +680 576 64983348.44575 +681 576 -12048523.14942 +682 576 -8333333.336071 +683 576 8485420.4502 +684 576 -94333949.07787 +685 576 1.773238182068e-06 +686 576 -694452.0061627 +687 576 -27191273.16515 +688 576 2.98023223877e-07 +689 576 -2777808.023288 +690 576 20509800.90325 +691 576 -2.242624759674e-06 +692 576 -694452.0061662 +696 576 -38845377.32488 +697 576 -8333333.33607 +698 576 -23415968.44916 +699 576 -69751628.43939 +700 576 1.266598701477e-06 +701 576 -62205540.42245 +702 576 -11071939.81576 +703 576 8333333.336071 +704 576 -7790968.444033 +577 577 762354436.272 +578 577 66665952.62197 +579 577 -6.556510925293e-07 +580 577 -57528006.93644 +581 577 -33666309.64427 +585 577 -43333333.32622 +586 577 -45492367.71613 +587 577 -7499910.748575 +588 577 -1.192092895508e-07 +589 577 62334645.32605 +590 577 16666488.1637 +591 577 43333333.32622 +592 577 -47367367.71582 +593 577 -9166577.415131 +675 577 8333333.336071 +676 577 -39196836.65327 +677 577 -17343704.63996 +678 577 -1.601874828339e-06 +679 577 -40741089.4269 +680 577 8333242.604601 +681 577 -8333333.336071 +682 577 -9548399.143536 +683 577 9010462.03536 +684 577 2.175569534302e-06 +685 577 -126000573.4156 +686 577 -67541485.19271 +687 577 2.384185791016e-07 +688 577 -47192265.20236 +689 577 33332970.40198 +690 577 -1.728534698486e-06 +691 577 -11156823.43448 +692 577 34208514.79074 +696 577 -8333333.33607 +697 577 -36345253.319 +698 577 -16510371.30635 +699 577 7.376074790955e-07 +700 577 -33084756.09483 +701 577 8333242.6046 +702 577 8333333.336071 +703 577 -8571815.80988 +704 577 8177128.701754 +578 578 1066134474.818 +579 578 -1388903.764753 +580 578 -32999642.97771 +581 578 113328361.2626 +585 578 -14930548.11516 +586 578 -7499910.748739 +587 578 -461644.445098 +588 578 2361140.861532 +589 578 16666488.1637 +590 578 141192013.134 +591 578 16319451.87971 +592 578 -9166577.414967 +593 578 -5461644.444274 +675 578 24110420.45533 +676 578 -17343704.63996 +677 578 -81284258.80916 +678 578 65400015.11214 +679 578 8333242.604601 +680 578 -113457062.6479 +681 578 8485420.4502 +682 578 9010462.03536 +683 578 -2221758.783205 +684 578 -694452.0061623 +685 578 -67874818.52582 +686 578 -284706093.7789 +687 578 -2777808.023289 +688 578 33332970.40198 +689 578 -311771151.9111 +690 578 -694452.006166 +691 578 34541848.12385 +692 578 21543906.17081 +696 578 -23415968.44916 +697 578 -16510371.30635 +698 578 -73680036.58444 +699 578 -62622207.08884 +700 578 8333242.6046 +701 578 -93040173.76232 +702 578 -7790968.444033 +703 578 8177128.701754 +704 578 382463.4398733 +579 579 939476176.8883 +580 579 43356277.09631 +581 579 -18771852.99502 +582 579 49283631.66647 +583 579 -43342510.83425 +584 579 -16337221.96865 +588 579 -58492995.80723 +589 579 -43333333.32622 +590 579 -14930548.11496 +591 579 -128333063.0188 +592 579 1.341104507446e-07 +593 579 3194474.194728 +594 579 -60367995.80692 +595 579 43333333.32622 +596 579 16319451.87991 +678 579 -41696960.65915 +679 579 8333333.336071 +680 579 24110420.45533 +681 579 -99681629.70551 +682 579 -8340448.891213 +683 579 71607514.53236 +687 579 -94333949.07787 +688 579 1.773238182068e-06 +689 579 -694452.0061627 +690 579 -8298175.66356 +691 579 8345192.594641 +692 579 -9379478.645899 +693 579 2423001.606932 +694 579 -8338077.0395 +695 579 7795396.873343 +699 579 -38845377.32488 +700 579 -8333333.33607 +701 579 -23415968.44916 +702 579 -69751628.43939 +703 579 1.266598701477e-06 +704 579 -62205540.42245 +705 579 -11071939.81576 +706 579 8333333.336071 +707 579 -7790968.444033 +580 580 822460198.9193 +581 580 51648672.72297 +582 580 -43347099.58827 +583 580 -102400547.2501 +584 580 -28003452.87548 +588 580 -43333333.32622 +589 580 -45492367.71613 +590 580 -7499910.748575 +591 580 -1.192092895508e-07 +592 580 62334645.32605 +593 580 16666488.1637 +594 580 43333333.32622 +595 580 -47367367.71582 +596 580 -9166577.415131 +678 580 8333333.336071 +679 580 -39196836.65327 +680 580 -17343704.63996 +681 580 -8338077.039499 +682 580 -60499809.12032 +683 580 22021029.70742 +687 580 2.175569534302e-06 +688 580 -126000573.4156 +689 580 -67541485.19271 +690 580 8345192.594641 +691 580 -30804628.63791 +692 580 25829490.35962 +693 580 -8340448.891214 +694 580 -26752986.0284 +695 580 37056208.64825 +699 580 -8333333.33607 +700 580 -36345253.319 +701 580 -16510371.30635 +702 580 7.376074790955e-07 +703 580 -33084756.09483 +704 580 8333242.6046 +705 580 8333333.336071 +706 580 -8571815.80988 +707 580 8177128.701754 +581 581 1105469191.389 +582 581 -16346107.01282 +583 581 -32013997.77403 +584 581 114586890.8952 +588 581 -14930548.11516 +589 581 -7499910.748739 +590 581 -461644.445098 +591 581 2361140.861532 +592 581 16666488.1637 +593 581 141192013.134 +594 581 16319451.87971 +595 581 -9166577.414967 +596 581 -5461644.444274 +678 581 24110420.45533 +679 581 -17343704.63996 +680 581 -81284258.80916 +681 581 72026355.46494 +682 581 24359692.24116 +683 581 -142891518.6627 +687 581 -694452.0061623 +688 581 -67874818.52582 +689 581 -284706093.7789 +690 581 -9370405.180087 +691 581 25836749.05321 +692 581 -291361037.6863 +693 581 7797611.087997 +694 581 35054390.19536 +695 581 3229564.966024 +699 581 -23415968.44916 +700 581 -16510371.30635 +701 581 -73680036.58444 +702 581 -62622207.08884 +703 581 8333242.6046 +704 581 -93040173.76232 +705 581 -7790968.444033 +706 581 8177128.701754 +707 581 382463.4398733 +582 582 583376284.5667 +583 582 43333333.32621 +584 582 -18054493.30016 +591 582 -58492995.80723 +592 582 -43333333.32622 +593 582 -14930548.11496 +594 582 -212203317.245 +595 582 -43342510.83425 +596 582 16396980.83364 +597 582 11333216.7726 +598 582 34675844.16901 +599 582 12517770.08628 +681 582 -50448491.13742 +682 582 10007115.55843 +683 582 28536410.43085 +690 582 -85645347.16108 +691 582 -8340448.891212 +692 582 -24130997.54348 +693 582 -10929001.68405 +694 582 8333333.33607 +695 582 3726516.388097 +702 582 -38845377.32488 +703 582 -8333333.33607 +704 582 -23415968.44916 +705 582 -69036918.95254 +706 582 -8338077.039497 +707 582 -55624567.39871 +708 582 7014515.850343 +709 582 6671410.372285 +710 582 -6514983.987003 +583 583 518362818.9365 +584 583 40035087.57113 +591 583 -43333333.32622 +592 583 -45492367.71613 +593 583 -7499910.748575 +594 583 -43347099.58827 +595 583 -8506300.789178 +596 583 23165903.31214 +597 583 52013766.25352 +598 583 11333216.7726 +599 583 -14999325.89734 +681 583 6671410.372285 +682 583 -50448491.13742 +683 583 -15218991.7376 +690 583 -8338077.039498 +691 583 -114821334.7964 +692 583 -67065236.07198 +693 583 8333333.336069 +694 583 -23434958.63979 +695 583 30221022.26397 +702 583 -8333333.33607 +703 583 -36345253.319 +704 583 -16510371.30635 +705 583 -8340448.891212 +706 583 -29855098.36736 +707 583 -1182917.166231 +708 583 10007115.55843 +709 583 7014515.850342 +710 583 7818288.469344 +584 584 777948189.0547 +591 584 -14930548.11516 +592 584 -7499910.748739 +593 584 -461644.445098 +594 584 15568224.60039 +595 584 18499461.34631 +596 584 73162839.64451 +597 584 18776655.12942 +598 584 -9999550.598229 +599 584 30221911.39361 +681 584 19024273.62057 +682 584 -22828487.60639 +683 584 -134529309.6998 +690 584 -24124138.5141 +691 584 -65063417.79147 +692 584 -231619365.082 +693 584 -21803668.18463 +694 584 9797097.079457 +695 584 -178746028.6722 +702 584 -23415968.44916 +703 584 -16510371.30635 +704 584 -73680036.58444 +705 584 -56043408.3313 +706 584 -3514321.011405 +707 584 -61172289.98812 +708 584 -9772475.980504 +709 584 5212192.312896 +710 584 18705375.60092 +585 585 866359460.9496 +586 585 1.430511474609e-06 +587 585 -5555615.056281 +588 585 107138445.2518 +589 585 -2.831220626831e-07 +590 585 -1388903.764753 +600 585 -128333063.0188 +601 585 1.341104507446e-07 +602 585 3194474.194728 +603 585 -60367995.80692 +604 585 43333333.32622 +605 585 16319451.87991 +684 585 -77407961.77148 +685 585 -1.184642314911e-06 +686 585 64983348.44575 +687 585 -12048523.14942 +688 585 -8333333.336071 +689 585 8485420.4502 +696 585 -27191273.16515 +697 585 2.98023223877e-07 +698 585 -2777808.023288 +699 585 20509800.90325 +700 585 -2.242624759674e-06 +701 585 -694452.0061662 +711 585 -69751628.43939 +712 585 1.266598701477e-06 +713 585 -62205540.42245 +714 585 -11071939.81576 +715 585 8333333.336071 +716 585 -7790968.444033 +586 586 762354436.272 +587 586 66665952.62197 +588 586 -6.556510925293e-07 +589 586 -57528006.93644 +590 586 -33666309.64427 +600 586 -1.192092895508e-07 +601 586 62334645.32605 +602 586 16666488.1637 +603 586 43333333.32622 +604 586 -47367367.71582 +605 586 -9166577.415131 +684 586 -1.601874828339e-06 +685 586 -40741089.4269 +686 586 8333242.604601 +687 586 -8333333.336071 +688 586 -9548399.143536 +689 586 9010462.03536 +696 586 2.384185791016e-07 +697 586 -47192265.20236 +698 586 33332970.40198 +699 586 -1.728534698486e-06 +700 586 -11156823.43448 +701 586 34208514.79074 +711 586 7.376074790955e-07 +712 586 -33084756.09483 +713 586 8333242.6046 +714 586 8333333.336071 +715 586 -8571815.80988 +716 586 8177128.701754 +587 587 1066134474.818 +588 587 -1388903.764753 +589 587 -32999642.97771 +590 587 113328361.2626 +600 587 2361140.861532 +601 587 16666488.1637 +602 587 141192013.134 +603 587 16319451.87971 +604 587 -9166577.414967 +605 587 -5461644.444274 +684 587 65400015.11214 +685 587 8333242.604601 +686 587 -113457062.6479 +687 587 8485420.4502 +688 587 9010462.03536 +689 587 -2221758.783205 +696 587 -2777808.023289 +697 587 33332970.40198 +698 587 -311771151.9111 +699 587 -694452.006166 +700 587 34541848.12385 +701 587 21543906.17081 +711 587 -62622207.08884 +712 587 8333242.6046 +713 587 -93040173.76232 +714 587 -7790968.444033 +715 587 8177128.701754 +716 587 382463.4398733 +588 588 866359460.9496 +589 588 1.430511474609e-06 +590 588 -5555615.056281 +591 588 107138445.2518 +592 588 -2.831220626831e-07 +593 588 -1388903.764753 +600 588 -58492995.80723 +601 588 -43333333.32622 +602 588 -14930548.11496 +603 588 -128333063.0188 +604 588 1.341104507446e-07 +605 588 3194474.194728 +606 588 -60367995.80692 +607 588 43333333.32622 +608 588 16319451.87991 +684 588 -41696960.65915 +685 588 8333333.336071 +686 588 24110420.45533 +687 588 -77407961.77148 +688 588 -1.184642314911e-06 +689 588 64983348.44575 +690 588 -12048523.14942 +691 588 -8333333.336071 +692 588 8485420.4502 +696 588 -94333949.07787 +697 588 1.773238182068e-06 +698 588 -694452.0061627 +699 588 -27191273.16515 +700 588 2.98023223877e-07 +701 588 -2777808.023288 +702 588 20509800.90325 +703 588 -2.242624759674e-06 +704 588 -694452.0061662 +711 588 -38845377.32488 +712 588 -8333333.33607 +713 588 -23415968.44916 +714 588 -69751628.43939 +715 588 1.266598701477e-06 +716 588 -62205540.42245 +717 588 -11071939.81576 +718 588 8333333.336071 +719 588 -7790968.444033 +589 589 762354436.272 +590 589 66665952.62197 +591 589 -6.556510925293e-07 +592 589 -57528006.93644 +593 589 -33666309.64427 +600 589 -43333333.32622 +601 589 -45492367.71613 +602 589 -7499910.748575 +603 589 -1.192092895508e-07 +604 589 62334645.32605 +605 589 16666488.1637 +606 589 43333333.32622 +607 589 -47367367.71582 +608 589 -9166577.415131 +684 589 8333333.336071 +685 589 -39196836.65327 +686 589 -17343704.63996 +687 589 -1.601874828339e-06 +688 589 -40741089.4269 +689 589 8333242.604601 +690 589 -8333333.336071 +691 589 -9548399.143536 +692 589 9010462.03536 +696 589 2.175569534302e-06 +697 589 -126000573.4156 +698 589 -67541485.19271 +699 589 2.384185791016e-07 +700 589 -47192265.20236 +701 589 33332970.40198 +702 589 -1.728534698486e-06 +703 589 -11156823.43448 +704 589 34208514.79074 +711 589 -8333333.33607 +712 589 -36345253.319 +713 589 -16510371.30635 +714 589 7.376074790955e-07 +715 589 -33084756.09483 +716 589 8333242.6046 +717 589 8333333.336071 +718 589 -8571815.80988 +719 589 8177128.701754 +590 590 1066134474.818 +591 590 -1388903.764753 +592 590 -32999642.97771 +593 590 113328361.2626 +600 590 -14930548.11516 +601 590 -7499910.748739 +602 590 -461644.445098 +603 590 2361140.861532 +604 590 16666488.1637 +605 590 141192013.134 +606 590 16319451.87971 +607 590 -9166577.414967 +608 590 -5461644.444274 +684 590 24110420.45533 +685 590 -17343704.63996 +686 590 -81284258.80916 +687 590 65400015.11214 +688 590 8333242.604601 +689 590 -113457062.6479 +690 590 8485420.4502 +691 590 9010462.03536 +692 590 -2221758.783205 +696 590 -694452.0061623 +697 590 -67874818.52582 +698 590 -284706093.7789 +699 590 -2777808.023289 +700 590 33332970.40198 +701 590 -311771151.9111 +702 590 -694452.006166 +703 590 34541848.12385 +704 590 21543906.17081 +711 590 -23415968.44916 +712 590 -16510371.30635 +713 590 -73680036.58444 +714 590 -62622207.08884 +715 590 8333242.6046 +716 590 -93040173.76232 +717 590 -7790968.444033 +718 590 8177128.701754 +719 590 382463.4398733 +591 591 866359460.9496 +592 591 1.430511474609e-06 +593 591 -5555615.056281 +594 591 107138445.2518 +595 591 -2.831220626831e-07 +596 591 -1388903.764753 +603 591 -58492995.80723 +604 591 -43333333.32622 +605 591 -14930548.11496 +606 591 -128333063.0188 +607 591 1.341104507446e-07 +608 591 3194474.194728 +609 591 -60367995.80692 +610 591 43333333.32622 +611 591 16319451.87991 +687 591 -41696960.65915 +688 591 8333333.336071 +689 591 24110420.45533 +690 591 -77407961.77148 +691 591 -1.184642314911e-06 +692 591 64983348.44575 +693 591 -12048523.14942 +694 591 -8333333.336071 +695 591 8485420.4502 +699 591 -94333949.07787 +700 591 1.773238182068e-06 +701 591 -694452.0061627 +702 591 -27191273.16515 +703 591 2.98023223877e-07 +704 591 -2777808.023288 +705 591 20509800.90325 +706 591 -2.242624759674e-06 +707 591 -694452.0061662 +714 591 -38845377.32488 +715 591 -8333333.33607 +716 591 -23415968.44916 +717 591 -69751628.43939 +718 591 1.266598701477e-06 +719 591 -62205540.42245 +720 591 -11071939.81576 +721 591 8333333.336071 +722 591 -7790968.444033 +592 592 762354436.272 +593 592 66665952.62197 +594 592 -6.556510925293e-07 +595 592 -57528006.93644 +596 592 -33666309.64427 +603 592 -43333333.32622 +604 592 -45492367.71613 +605 592 -7499910.748575 +606 592 -1.192092895508e-07 +607 592 62334645.32605 +608 592 16666488.1637 +609 592 43333333.32622 +610 592 -47367367.71582 +611 592 -9166577.415131 +687 592 8333333.336071 +688 592 -39196836.65327 +689 592 -17343704.63996 +690 592 -1.601874828339e-06 +691 592 -40741089.4269 +692 592 8333242.604601 +693 592 -8333333.336071 +694 592 -9548399.143536 +695 592 9010462.03536 +699 592 2.175569534302e-06 +700 592 -126000573.4156 +701 592 -67541485.19271 +702 592 2.384185791016e-07 +703 592 -47192265.20236 +704 592 33332970.40198 +705 592 -1.728534698486e-06 +706 592 -11156823.43448 +707 592 34208514.79074 +714 592 -8333333.33607 +715 592 -36345253.319 +716 592 -16510371.30635 +717 592 7.376074790955e-07 +718 592 -33084756.09483 +719 592 8333242.6046 +720 592 8333333.336071 +721 592 -8571815.80988 +722 592 8177128.701754 +593 593 1066134474.818 +594 593 -1388903.764753 +595 593 -32999642.97771 +596 593 113328361.2626 +603 593 -14930548.11516 +604 593 -7499910.748739 +605 593 -461644.445098 +606 593 2361140.861532 +607 593 16666488.1637 +608 593 141192013.134 +609 593 16319451.87971 +610 593 -9166577.414967 +611 593 -5461644.444274 +687 593 24110420.45533 +688 593 -17343704.63996 +689 593 -81284258.80916 +690 593 65400015.11214 +691 593 8333242.604601 +692 593 -113457062.6479 +693 593 8485420.4502 +694 593 9010462.03536 +695 593 -2221758.783205 +699 593 -694452.0061623 +700 593 -67874818.52582 +701 593 -284706093.7789 +702 593 -2777808.023289 +703 593 33332970.40198 +704 593 -311771151.9111 +705 593 -694452.006166 +706 593 34541848.12385 +707 593 21543906.17081 +714 593 -23415968.44916 +715 593 -16510371.30635 +716 593 -73680036.58444 +717 593 -62622207.08884 +718 593 8333242.6046 +719 593 -93040173.76232 +720 593 -7790968.444033 +721 593 8177128.701754 +722 593 382463.4398733 +594 594 939476176.8883 +595 594 43356277.09631 +596 594 -18771852.99502 +597 594 49283631.66647 +598 594 -43342510.83425 +599 594 -16337221.96865 +606 594 -58492995.80723 +607 594 -43333333.32622 +608 594 -14930548.11496 +609 594 -128333063.0188 +610 594 1.341104507446e-07 +611 594 3194474.194728 +612 594 -60367995.80692 +613 594 43333333.32622 +614 594 16319451.87991 +690 594 -41696960.65915 +691 594 8333333.336071 +692 594 24110420.45533 +693 594 -99681629.70551 +694 594 -8340448.891213 +695 594 71607514.53236 +702 594 -94333949.07787 +703 594 1.773238182068e-06 +704 594 -694452.0061627 +705 594 -8298175.66356 +706 594 8345192.594641 +707 594 -9379478.645899 +708 594 2423001.606932 +709 594 -8338077.0395 +710 594 7795396.873343 +717 594 -38845377.32488 +718 594 -8333333.33607 +719 594 -23415968.44916 +720 594 -69751628.43939 +721 594 1.266598701477e-06 +722 594 -62205540.42245 +723 594 -11071939.81576 +724 594 8333333.336071 +725 594 -7790968.444033 +595 595 822460198.9193 +596 595 51648672.72297 +597 595 -43347099.58827 +598 595 -102400547.2501 +599 595 -28003452.87548 +606 595 -43333333.32622 +607 595 -45492367.71613 +608 595 -7499910.748575 +609 595 -1.192092895508e-07 +610 595 62334645.32605 +611 595 16666488.1637 +612 595 43333333.32622 +613 595 -47367367.71582 +614 595 -9166577.415131 +690 595 8333333.336071 +691 595 -39196836.65327 +692 595 -17343704.63996 +693 595 -8338077.039499 +694 595 -60499809.12032 +695 595 22021029.70742 +702 595 2.175569534302e-06 +703 595 -126000573.4156 +704 595 -67541485.19271 +705 595 8345192.594641 +706 595 -30804628.63791 +707 595 25829490.35962 +708 595 -8340448.891214 +709 595 -26752986.0284 +710 595 37056208.64825 +717 595 -8333333.33607 +718 595 -36345253.319 +719 595 -16510371.30635 +720 595 7.376074790955e-07 +721 595 -33084756.09483 +722 595 8333242.6046 +723 595 8333333.336071 +724 595 -8571815.80988 +725 595 8177128.701754 +596 596 1105469191.389 +597 596 -16346107.01282 +598 596 -32013997.77403 +599 596 114586890.8952 +606 596 -14930548.11516 +607 596 -7499910.748739 +608 596 -461644.445098 +609 596 2361140.861532 +610 596 16666488.1637 +611 596 141192013.134 +612 596 16319451.87971 +613 596 -9166577.414967 +614 596 -5461644.444274 +690 596 24110420.45533 +691 596 -17343704.63996 +692 596 -81284258.80916 +693 596 72026355.46494 +694 596 24359692.24116 +695 596 -142891518.6627 +702 596 -694452.0061623 +703 596 -67874818.52582 +704 596 -284706093.7789 +705 596 -9370405.180087 +706 596 25836749.05321 +707 596 -291361037.6863 +708 596 7797611.087997 +709 596 35054390.19536 +710 596 3229564.966024 +717 596 -23415968.44916 +718 596 -16510371.30635 +719 596 -73680036.58444 +720 596 -62622207.08884 +721 596 8333242.6046 +722 596 -93040173.76232 +723 596 -7790968.444033 +724 596 8177128.701754 +725 596 382463.4398733 +597 597 583376284.5667 +598 597 43333333.32621 +599 597 -18054493.30016 +609 597 -58492995.80723 +610 597 -43333333.32622 +611 597 -14930548.11496 +612 597 -212203317.245 +613 597 -43342510.83425 +614 597 16396980.83364 +615 597 11333216.7726 +616 597 34675844.16901 +617 597 12517770.08628 +693 597 -50448491.13742 +694 597 10007115.55843 +695 597 28536410.43085 +705 597 -85645347.16108 +706 597 -8340448.891212 +707 597 -24130997.54348 +708 597 -10929001.68405 +709 597 8333333.33607 +710 597 3726516.388097 +720 597 -38845377.32488 +721 597 -8333333.33607 +722 597 -23415968.44916 +723 597 -69036918.95254 +724 597 -8338077.039497 +725 597 -55624567.39871 +726 597 7014515.850343 +727 597 6671410.372285 +728 597 -6514983.987003 +598 598 518362818.9365 +599 598 40035087.57113 +609 598 -43333333.32622 +610 598 -45492367.71613 +611 598 -7499910.748575 +612 598 -43347099.58827 +613 598 -8506300.789178 +614 598 23165903.31214 +615 598 52013766.25352 +616 598 11333216.7726 +617 598 -14999325.89734 +693 598 6671410.372285 +694 598 -50448491.13742 +695 598 -15218991.7376 +705 598 -8338077.039498 +706 598 -114821334.7964 +707 598 -67065236.07198 +708 598 8333333.336069 +709 598 -23434958.63979 +710 598 30221022.26397 +720 598 -8333333.33607 +721 598 -36345253.319 +722 598 -16510371.30635 +723 598 -8340448.891212 +724 598 -29855098.36736 +725 598 -1182917.166231 +726 598 10007115.55843 +727 598 7014515.850342 +728 598 7818288.469344 +599 599 777948189.0547 +609 599 -14930548.11516 +610 599 -7499910.748739 +611 599 -461644.445098 +612 599 15568224.60039 +613 599 18499461.34631 +614 599 73162839.64451 +615 599 18776655.12942 +616 599 -9999550.598229 +617 599 30221911.39361 +693 599 19024273.62057 +694 599 -22828487.60639 +695 599 -134529309.6998 +705 599 -24124138.5141 +706 599 -65063417.79147 +707 599 -231619365.082 +708 599 -21803668.18463 +709 599 9797097.079457 +710 599 -178746028.6722 +720 599 -23415968.44916 +721 599 -16510371.30635 +722 599 -73680036.58444 +723 599 -56043408.3313 +724 599 -3514321.011405 +725 599 -61172289.98812 +726 599 -9772475.980504 +727 599 5212192.312896 +728 599 18705375.60092 +600 600 866359460.9496 +601 600 1.430511474609e-06 +602 600 -5555615.056281 +603 600 107138445.2518 +604 600 -2.831220626831e-07 +605 600 -1388903.764753 +618 600 -128333063.0188 +619 600 1.341104507446e-07 +620 600 3194474.194728 +621 600 -60367995.80692 +622 600 43333333.32622 +623 600 16319451.87991 +696 600 -77407961.77148 +697 600 -1.184642314911e-06 +698 600 64983348.44575 +699 600 -12048523.14942 +700 600 -8333333.336071 +701 600 8485420.4502 +711 600 -27191273.16515 +712 600 2.98023223877e-07 +713 600 -2777808.023288 +714 600 20509800.90325 +715 600 -2.242624759674e-06 +716 600 -694452.0061662 +729 600 -69751628.43939 +730 600 1.266598701477e-06 +731 600 -62205540.42245 +732 600 -11071939.81576 +733 600 8333333.336071 +734 600 -7790968.444033 +601 601 762354436.272 +602 601 66665952.62197 +603 601 -6.556510925293e-07 +604 601 -57528006.93644 +605 601 -33666309.64427 +618 601 -1.192092895508e-07 +619 601 62334645.32605 +620 601 16666488.1637 +621 601 43333333.32622 +622 601 -47367367.71582 +623 601 -9166577.415131 +696 601 -1.601874828339e-06 +697 601 -40741089.4269 +698 601 8333242.604601 +699 601 -8333333.336071 +700 601 -9548399.143536 +701 601 9010462.03536 +711 601 2.384185791016e-07 +712 601 -47192265.20236 +713 601 33332970.40198 +714 601 -1.728534698486e-06 +715 601 -11156823.43448 +716 601 34208514.79074 +729 601 7.376074790955e-07 +730 601 -33084756.09483 +731 601 8333242.6046 +732 601 8333333.336071 +733 601 -8571815.80988 +734 601 8177128.701754 +602 602 1066134474.818 +603 602 -1388903.764753 +604 602 -32999642.97771 +605 602 113328361.2626 +618 602 2361140.861532 +619 602 16666488.1637 +620 602 141192013.134 +621 602 16319451.87971 +622 602 -9166577.414967 +623 602 -5461644.444274 +696 602 65400015.11214 +697 602 8333242.604601 +698 602 -113457062.6479 +699 602 8485420.4502 +700 602 9010462.03536 +701 602 -2221758.783205 +711 602 -2777808.023289 +712 602 33332970.40198 +713 602 -311771151.9111 +714 602 -694452.006166 +715 602 34541848.12385 +716 602 21543906.17081 +729 602 -62622207.08884 +730 602 8333242.6046 +731 602 -93040173.76232 +732 602 -7790968.444033 +733 602 8177128.701754 +734 602 382463.4398733 +603 603 866359460.9496 +604 603 1.430511474609e-06 +605 603 -5555615.056281 +606 603 107138445.2518 +607 603 -2.831220626831e-07 +608 603 -1388903.764753 +618 603 -58492995.80723 +619 603 -43333333.32622 +620 603 -14930548.11496 +621 603 -128333063.0188 +622 603 1.341104507446e-07 +623 603 3194474.194728 +624 603 -60367995.80692 +625 603 43333333.32622 +626 603 16319451.87991 +696 603 -41696960.65915 +697 603 8333333.336071 +698 603 24110420.45533 +699 603 -77407961.77148 +700 603 -1.184642314911e-06 +701 603 64983348.44575 +702 603 -12048523.14942 +703 603 -8333333.336071 +704 603 8485420.4502 +711 603 -94333949.07787 +712 603 1.773238182068e-06 +713 603 -694452.0061627 +714 603 -27191273.16515 +715 603 2.98023223877e-07 +716 603 -2777808.023288 +717 603 20509800.90325 +718 603 -2.242624759674e-06 +719 603 -694452.0061662 +729 603 -38845377.32488 +730 603 -8333333.33607 +731 603 -23415968.44916 +732 603 -69751628.43939 +733 603 1.266598701477e-06 +734 603 -62205540.42245 +735 603 -11071939.81576 +736 603 8333333.336071 +737 603 -7790968.444033 +604 604 762354436.272 +605 604 66665952.62197 +606 604 -6.556510925293e-07 +607 604 -57528006.93644 +608 604 -33666309.64427 +618 604 -43333333.32622 +619 604 -45492367.71613 +620 604 -7499910.748575 +621 604 -1.192092895508e-07 +622 604 62334645.32605 +623 604 16666488.1637 +624 604 43333333.32622 +625 604 -47367367.71582 +626 604 -9166577.415131 +696 604 8333333.336071 +697 604 -39196836.65327 +698 604 -17343704.63996 +699 604 -1.601874828339e-06 +700 604 -40741089.4269 +701 604 8333242.604601 +702 604 -8333333.336071 +703 604 -9548399.143536 +704 604 9010462.03536 +711 604 2.175569534302e-06 +712 604 -126000573.4156 +713 604 -67541485.19271 +714 604 2.384185791016e-07 +715 604 -47192265.20236 +716 604 33332970.40198 +717 604 -1.728534698486e-06 +718 604 -11156823.43448 +719 604 34208514.79074 +729 604 -8333333.33607 +730 604 -36345253.319 +731 604 -16510371.30635 +732 604 7.376074790955e-07 +733 604 -33084756.09483 +734 604 8333242.6046 +735 604 8333333.336071 +736 604 -8571815.80988 +737 604 8177128.701754 +605 605 1066134474.818 +606 605 -1388903.764753 +607 605 -32999642.97771 +608 605 113328361.2626 +618 605 -14930548.11516 +619 605 -7499910.748739 +620 605 -461644.445098 +621 605 2361140.861532 +622 605 16666488.1637 +623 605 141192013.134 +624 605 16319451.87971 +625 605 -9166577.414967 +626 605 -5461644.444274 +696 605 24110420.45533 +697 605 -17343704.63996 +698 605 -81284258.80916 +699 605 65400015.11214 +700 605 8333242.604601 +701 605 -113457062.6479 +702 605 8485420.4502 +703 605 9010462.03536 +704 605 -2221758.783205 +711 605 -694452.0061623 +712 605 -67874818.52582 +713 605 -284706093.7789 +714 605 -2777808.023289 +715 605 33332970.40198 +716 605 -311771151.9111 +717 605 -694452.006166 +718 605 34541848.12385 +719 605 21543906.17081 +729 605 -23415968.44916 +730 605 -16510371.30635 +731 605 -73680036.58444 +732 605 -62622207.08884 +733 605 8333242.6046 +734 605 -93040173.76232 +735 605 -7790968.444033 +736 605 8177128.701754 +737 605 382463.4398733 +606 606 866359460.9496 +607 606 1.430511474609e-06 +608 606 -5555615.056281 +609 606 107138445.2518 +610 606 -2.831220626831e-07 +611 606 -1388903.764753 +621 606 -58492995.80723 +622 606 -43333333.32622 +623 606 -14930548.11496 +624 606 -128333063.0188 +625 606 1.341104507446e-07 +626 606 3194474.194728 +627 606 -60367995.80692 +628 606 43333333.32622 +629 606 16319451.87991 +699 606 -41696960.65915 +700 606 8333333.336071 +701 606 24110420.45533 +702 606 -77407961.77148 +703 606 -1.184642314911e-06 +704 606 64983348.44575 +705 606 -12048523.14942 +706 606 -8333333.336071 +707 606 8485420.4502 +714 606 -94333949.07787 +715 606 1.773238182068e-06 +716 606 -694452.0061627 +717 606 -27191273.16515 +718 606 2.98023223877e-07 +719 606 -2777808.023288 +720 606 20509800.90325 +721 606 -2.242624759674e-06 +722 606 -694452.0061662 +732 606 -38845377.32488 +733 606 -8333333.33607 +734 606 -23415968.44916 +735 606 -69751628.43939 +736 606 1.266598701477e-06 +737 606 -62205540.42245 +738 606 -11071939.81576 +739 606 8333333.336071 +740 606 -7790968.444033 +607 607 762354436.272 +608 607 66665952.62197 +609 607 -6.556510925293e-07 +610 607 -57528006.93644 +611 607 -33666309.64427 +621 607 -43333333.32622 +622 607 -45492367.71613 +623 607 -7499910.748575 +624 607 -1.192092895508e-07 +625 607 62334645.32605 +626 607 16666488.1637 +627 607 43333333.32622 +628 607 -47367367.71582 +629 607 -9166577.415131 +699 607 8333333.336071 +700 607 -39196836.65327 +701 607 -17343704.63996 +702 607 -1.601874828339e-06 +703 607 -40741089.4269 +704 607 8333242.604601 +705 607 -8333333.336071 +706 607 -9548399.143536 +707 607 9010462.03536 +714 607 2.175569534302e-06 +715 607 -126000573.4156 +716 607 -67541485.19271 +717 607 2.384185791016e-07 +718 607 -47192265.20236 +719 607 33332970.40198 +720 607 -1.728534698486e-06 +721 607 -11156823.43448 +722 607 34208514.79074 +732 607 -8333333.33607 +733 607 -36345253.319 +734 607 -16510371.30635 +735 607 7.376074790955e-07 +736 607 -33084756.09483 +737 607 8333242.6046 +738 607 8333333.336071 +739 607 -8571815.80988 +740 607 8177128.701754 +608 608 1066134474.818 +609 608 -1388903.764753 +610 608 -32999642.97771 +611 608 113328361.2626 +621 608 -14930548.11516 +622 608 -7499910.748739 +623 608 -461644.445098 +624 608 2361140.861532 +625 608 16666488.1637 +626 608 141192013.134 +627 608 16319451.87971 +628 608 -9166577.414967 +629 608 -5461644.444274 +699 608 24110420.45533 +700 608 -17343704.63996 +701 608 -81284258.80916 +702 608 65400015.11214 +703 608 8333242.604601 +704 608 -113457062.6479 +705 608 8485420.4502 +706 608 9010462.03536 +707 608 -2221758.783205 +714 608 -694452.0061623 +715 608 -67874818.52582 +716 608 -284706093.7789 +717 608 -2777808.023289 +718 608 33332970.40198 +719 608 -311771151.9111 +720 608 -694452.006166 +721 608 34541848.12385 +722 608 21543906.17081 +732 608 -23415968.44916 +733 608 -16510371.30635 +734 608 -73680036.58444 +735 608 -62622207.08884 +736 608 8333242.6046 +737 608 -93040173.76232 +738 608 -7790968.444033 +739 608 8177128.701754 +740 608 382463.4398733 +609 609 866359460.9496 +610 609 1.430511474609e-06 +611 609 -5555615.056281 +612 609 107138445.2518 +613 609 -2.831220626831e-07 +614 609 -1388903.764753 +624 609 -58492995.80723 +625 609 -43333333.32622 +626 609 -14930548.11496 +627 609 -128333063.0188 +628 609 1.341104507446e-07 +629 609 3194474.194728 +630 609 -60367995.80692 +631 609 43333333.32622 +632 609 16319451.87991 +702 609 -41696960.65915 +703 609 8333333.336071 +704 609 24110420.45533 +705 609 -77407961.77148 +706 609 -1.184642314911e-06 +707 609 64983348.44575 +708 609 -12048523.14942 +709 609 -8333333.336071 +710 609 8485420.4502 +717 609 -94333949.07787 +718 609 1.773238182068e-06 +719 609 -694452.0061627 +720 609 -27191273.16515 +721 609 2.98023223877e-07 +722 609 -2777808.023288 +723 609 20509800.90325 +724 609 -2.242624759674e-06 +725 609 -694452.0061662 +735 609 -38845377.32488 +736 609 -8333333.33607 +737 609 -23415968.44916 +738 609 -69751628.43939 +739 609 1.266598701477e-06 +740 609 -62205540.42245 +741 609 -11071939.81576 +742 609 8333333.336071 +743 609 -7790968.444033 +610 610 762354436.272 +611 610 66665952.62197 +612 610 -6.556510925293e-07 +613 610 -57528006.93644 +614 610 -33666309.64427 +624 610 -43333333.32622 +625 610 -45492367.71613 +626 610 -7499910.748575 +627 610 -1.192092895508e-07 +628 610 62334645.32605 +629 610 16666488.1637 +630 610 43333333.32622 +631 610 -47367367.71582 +632 610 -9166577.415131 +702 610 8333333.336071 +703 610 -39196836.65327 +704 610 -17343704.63996 +705 610 -1.601874828339e-06 +706 610 -40741089.4269 +707 610 8333242.604601 +708 610 -8333333.336071 +709 610 -9548399.143536 +710 610 9010462.03536 +717 610 2.175569534302e-06 +718 610 -126000573.4156 +719 610 -67541485.19271 +720 610 2.384185791016e-07 +721 610 -47192265.20236 +722 610 33332970.40198 +723 610 -1.728534698486e-06 +724 610 -11156823.43448 +725 610 34208514.79074 +735 610 -8333333.33607 +736 610 -36345253.319 +737 610 -16510371.30635 +738 610 7.376074790955e-07 +739 610 -33084756.09483 +740 610 8333242.6046 +741 610 8333333.336071 +742 610 -8571815.80988 +743 610 8177128.701754 +611 611 1066134474.818 +612 611 -1388903.764753 +613 611 -32999642.97771 +614 611 113328361.2626 +624 611 -14930548.11516 +625 611 -7499910.748739 +626 611 -461644.445098 +627 611 2361140.861532 +628 611 16666488.1637 +629 611 141192013.134 +630 611 16319451.87971 +631 611 -9166577.414967 +632 611 -5461644.444274 +702 611 24110420.45533 +703 611 -17343704.63996 +704 611 -81284258.80916 +705 611 65400015.11214 +706 611 8333242.604601 +707 611 -113457062.6479 +708 611 8485420.4502 +709 611 9010462.03536 +710 611 -2221758.783205 +717 611 -694452.0061623 +718 611 -67874818.52582 +719 611 -284706093.7789 +720 611 -2777808.023289 +721 611 33332970.40198 +722 611 -311771151.9111 +723 611 -694452.006166 +724 611 34541848.12385 +725 611 21543906.17081 +735 611 -23415968.44916 +736 611 -16510371.30635 +737 611 -73680036.58444 +738 611 -62622207.08884 +739 611 8333242.6046 +740 611 -93040173.76232 +741 611 -7790968.444033 +742 611 8177128.701754 +743 611 382463.4398733 +612 612 939476176.8883 +613 612 43356277.09631 +614 612 -18771852.99502 +615 612 49283631.66647 +616 612 -43342510.83425 +617 612 -16337221.96865 +627 612 -58492995.80723 +628 612 -43333333.32622 +629 612 -14930548.11496 +630 612 -128333063.0188 +631 612 1.341104507446e-07 +632 612 3194474.194728 +633 612 -60367995.80692 +634 612 43333333.32622 +635 612 16319451.87991 +705 612 -41696960.65915 +706 612 8333333.336071 +707 612 24110420.45533 +708 612 -99681629.70551 +709 612 -8340448.891213 +710 612 71607514.53236 +720 612 -94333949.07787 +721 612 1.773238182068e-06 +722 612 -694452.0061627 +723 612 -8298175.66356 +724 612 8345192.594641 +725 612 -9379478.645899 +726 612 2423001.606932 +727 612 -8338077.0395 +728 612 7795396.873343 +738 612 -38845377.32488 +739 612 -8333333.33607 +740 612 -23415968.44916 +741 612 -69751628.43939 +742 612 1.266598701477e-06 +743 612 -62205540.42245 +744 612 -11071939.81576 +745 612 8333333.336071 +746 612 -7790968.444033 +613 613 822460198.9193 +614 613 51648672.72297 +615 613 -43347099.58827 +616 613 -102400547.2501 +617 613 -28003452.87548 +627 613 -43333333.32622 +628 613 -45492367.71613 +629 613 -7499910.748575 +630 613 -1.192092895508e-07 +631 613 62334645.32605 +632 613 16666488.1637 +633 613 43333333.32622 +634 613 -47367367.71582 +635 613 -9166577.415131 +705 613 8333333.336071 +706 613 -39196836.65327 +707 613 -17343704.63996 +708 613 -8338077.039499 +709 613 -60499809.12032 +710 613 22021029.70742 +720 613 2.175569534302e-06 +721 613 -126000573.4156 +722 613 -67541485.19271 +723 613 8345192.594641 +724 613 -30804628.63791 +725 613 25829490.35962 +726 613 -8340448.891214 +727 613 -26752986.0284 +728 613 37056208.64825 +738 613 -8333333.33607 +739 613 -36345253.319 +740 613 -16510371.30635 +741 613 7.376074790955e-07 +742 613 -33084756.09483 +743 613 8333242.6046 +744 613 8333333.336071 +745 613 -8571815.80988 +746 613 8177128.701754 +614 614 1105469191.389 +615 614 -16346107.01282 +616 614 -32013997.77403 +617 614 114586890.8952 +627 614 -14930548.11516 +628 614 -7499910.748739 +629 614 -461644.445098 +630 614 2361140.861532 +631 614 16666488.1637 +632 614 141192013.134 +633 614 16319451.87971 +634 614 -9166577.414967 +635 614 -5461644.444274 +705 614 24110420.45533 +706 614 -17343704.63996 +707 614 -81284258.80916 +708 614 72026355.46494 +709 614 24359692.24116 +710 614 -142891518.6627 +720 614 -694452.0061623 +721 614 -67874818.52582 +722 614 -284706093.7789 +723 614 -9370405.180087 +724 614 25836749.05321 +725 614 -291361037.6863 +726 614 7797611.087997 +727 614 35054390.19536 +728 614 3229564.966024 +738 614 -23415968.44916 +739 614 -16510371.30635 +740 614 -73680036.58444 +741 614 -62622207.08884 +742 614 8333242.6046 +743 614 -93040173.76232 +744 614 -7790968.444033 +745 614 8177128.701754 +746 614 382463.4398733 +615 615 537237674.144 +616 615 19682635.03509 +617 615 7278853.935812 +630 615 -58492995.80723 +631 615 -43333333.32622 +632 615 -14930548.11496 +633 615 -149236272.2809 +634 615 -19708334.49086 +635 615 1086095.150343 +636 615 2489297.126623 +637 615 34692366.11674 +638 615 1688899.488625 +708 615 -50448491.13742 +709 615 10007115.55843 +710 615 28536410.43085 +723 615 -85645347.16108 +724 615 -8340448.891212 +725 615 -24130997.54348 +726 615 -17836755.62729 +727 615 3212976.44109 +728 615 14418636.61301 +741 615 -38845377.32488 +742 615 -8333333.33607 +743 615 -23415968.44916 +744 615 -63830259.57109 +745 615 -3226694.96361 +746 615 -53519044.21609 +747 615 -9616209.125473 +748 615 6680385.191377 +749 615 -8036218.454271 +616 616 508863262.8828 +617 616 40926260.08717 +630 616 -43333333.32622 +631 616 -45492367.71613 +632 616 -7499910.748575 +633 616 -19721184.21874 +634 616 43866664.97233 +635 616 10904977.14742 +636 616 52038549.1751 +637 616 -23555678.03985 +638 616 -4314117.219295 +708 616 6671410.372285 +709 616 -50448491.13742 +710 616 -15218991.7376 +723 616 -8338077.039498 +724 616 -114821334.7964 +725 616 -67065236.07198 +726 616 3212976.44109 +727 616 -22134058.05942 +728 616 29194228.99637 +741 616 -8333333.33607 +742 616 -36345253.319 +743 616 -16510371.30635 +744 616 -3233554.224871 +745 616 -26925105.42998 +746 616 514296.7345483 +747 616 10020577.78707 +748 616 -15548197.20502 +749 616 16207412.72304 +617 617 756010396.5891 +630 617 -14930548.11516 +631 617 -7499910.748739 +632 617 -461644.445098 +633 617 5268569.693425 +634 617 10241225.80364 +635 617 113931482.3872 +636 617 2533349.232938 +637 617 -3659305.027546 +638 617 32683100.83748 +708 617 19024273.62057 +709 617 -22828487.60639 +710 617 -134529309.6998 +723 617 -24124138.5141 +724 617 -65063417.79147 +725 617 -231619365.082 +726 617 -7213954.829688 +727 617 11901763.34317 +728 617 -175634313.754 +741 617 -23415968.44916 +742 617 -16510371.30635 +743 617 -73680036.58444 +744 617 -51436656.57492 +745 617 190595.229853 +746 617 -74752245.15073 +747 617 -12054327.68141 +748 617 12991927.13824 +749 617 -19711236.25505 +618 618 866359460.9496 +619 618 1.430511474609e-06 +620 618 -5555615.056281 +621 618 107138445.2518 +622 618 -2.831220626831e-07 +623 618 -1388903.764753 +639 618 -128333063.0188 +640 618 1.341104507446e-07 +641 618 3194474.194728 +642 618 -60367995.80692 +643 618 43333333.32622 +644 618 16319451.87991 +711 618 -77407961.77148 +712 618 -1.184642314911e-06 +713 618 64983348.44575 +714 618 -12048523.14942 +715 618 -8333333.336071 +716 618 8485420.4502 +729 618 -27191273.16515 +730 618 2.98023223877e-07 +731 618 -2777808.023288 +732 618 20509800.90325 +733 618 -2.242624759674e-06 +734 618 -694452.0061662 +750 618 -69751628.43939 +751 618 1.266598701477e-06 +752 618 -62205540.42245 +753 618 -11071939.81576 +754 618 8333333.336071 +755 618 -7790968.444033 +619 619 762354436.272 +620 619 66665952.62197 +621 619 -6.556510925293e-07 +622 619 -57528006.93644 +623 619 -33666309.64427 +639 619 -1.192092895508e-07 +640 619 62334645.32605 +641 619 16666488.1637 +642 619 43333333.32622 +643 619 -47367367.71582 +644 619 -9166577.415131 +711 619 -1.601874828339e-06 +712 619 -40741089.4269 +713 619 8333242.604601 +714 619 -8333333.336071 +715 619 -9548399.143536 +716 619 9010462.03536 +729 619 2.384185791016e-07 +730 619 -47192265.20236 +731 619 33332970.40198 +732 619 -1.728534698486e-06 +733 619 -11156823.43448 +734 619 34208514.79074 +750 619 7.376074790955e-07 +751 619 -33084756.09483 +752 619 8333242.6046 +753 619 8333333.336071 +754 619 -8571815.80988 +755 619 8177128.701754 +620 620 1066134474.818 +621 620 -1388903.764753 +622 620 -32999642.97771 +623 620 113328361.2626 +639 620 2361140.861532 +640 620 16666488.1637 +641 620 141192013.134 +642 620 16319451.87971 +643 620 -9166577.414967 +644 620 -5461644.444274 +711 620 65400015.11214 +712 620 8333242.604601 +713 620 -113457062.6479 +714 620 8485420.4502 +715 620 9010462.03536 +716 620 -2221758.783205 +729 620 -2777808.023289 +730 620 33332970.40198 +731 620 -311771151.9111 +732 620 -694452.006166 +733 620 34541848.12385 +734 620 21543906.17081 +750 620 -62622207.08884 +751 620 8333242.6046 +752 620 -93040173.76232 +753 620 -7790968.444033 +754 620 8177128.701754 +755 620 382463.4398733 +621 621 866359460.9496 +622 621 1.430511474609e-06 +623 621 -5555615.056281 +624 621 107138445.2518 +625 621 -2.831220626831e-07 +626 621 -1388903.764753 +639 621 -58492995.80723 +640 621 -43333333.32622 +641 621 -14930548.11496 +642 621 -128333063.0188 +643 621 1.341104507446e-07 +644 621 3194474.194728 +645 621 -60367995.80692 +646 621 43333333.32622 +647 621 16319451.87991 +711 621 -41696960.65915 +712 621 8333333.336071 +713 621 24110420.45533 +714 621 -77407961.77148 +715 621 -1.184642314911e-06 +716 621 64983348.44575 +717 621 -12048523.14942 +718 621 -8333333.336071 +719 621 8485420.4502 +729 621 -94333949.07787 +730 621 1.773238182068e-06 +731 621 -694452.0061627 +732 621 -27191273.16515 +733 621 2.98023223877e-07 +734 621 -2777808.023288 +735 621 20509800.90325 +736 621 -2.242624759674e-06 +737 621 -694452.0061662 +750 621 -38845377.32488 +751 621 -8333333.33607 +752 621 -23415968.44916 +753 621 -69751628.43939 +754 621 1.266598701477e-06 +755 621 -62205540.42245 +756 621 -11071939.81576 +757 621 8333333.336071 +758 621 -7790968.444033 +622 622 762354436.272 +623 622 66665952.62197 +624 622 -6.556510925293e-07 +625 622 -57528006.93644 +626 622 -33666309.64427 +639 622 -43333333.32622 +640 622 -45492367.71613 +641 622 -7499910.748575 +642 622 -1.192092895508e-07 +643 622 62334645.32605 +644 622 16666488.1637 +645 622 43333333.32622 +646 622 -47367367.71582 +647 622 -9166577.415131 +711 622 8333333.336071 +712 622 -39196836.65327 +713 622 -17343704.63996 +714 622 -1.601874828339e-06 +715 622 -40741089.4269 +716 622 8333242.604601 +717 622 -8333333.336071 +718 622 -9548399.143536 +719 622 9010462.03536 +729 622 2.175569534302e-06 +730 622 -126000573.4156 +731 622 -67541485.19271 +732 622 2.384185791016e-07 +733 622 -47192265.20236 +734 622 33332970.40198 +735 622 -1.728534698486e-06 +736 622 -11156823.43448 +737 622 34208514.79074 +750 622 -8333333.33607 +751 622 -36345253.319 +752 622 -16510371.30635 +753 622 7.376074790955e-07 +754 622 -33084756.09483 +755 622 8333242.6046 +756 622 8333333.336071 +757 622 -8571815.80988 +758 622 8177128.701754 +623 623 1066134474.818 +624 623 -1388903.764753 +625 623 -32999642.97771 +626 623 113328361.2626 +639 623 -14930548.11516 +640 623 -7499910.748739 +641 623 -461644.445098 +642 623 2361140.861532 +643 623 16666488.1637 +644 623 141192013.134 +645 623 16319451.87971 +646 623 -9166577.414967 +647 623 -5461644.444274 +711 623 24110420.45533 +712 623 -17343704.63996 +713 623 -81284258.80916 +714 623 65400015.11214 +715 623 8333242.604601 +716 623 -113457062.6479 +717 623 8485420.4502 +718 623 9010462.03536 +719 623 -2221758.783205 +729 623 -694452.0061623 +730 623 -67874818.52582 +731 623 -284706093.7789 +732 623 -2777808.023289 +733 623 33332970.40198 +734 623 -311771151.9111 +735 623 -694452.006166 +736 623 34541848.12385 +737 623 21543906.17081 +750 623 -23415968.44916 +751 623 -16510371.30635 +752 623 -73680036.58444 +753 623 -62622207.08884 +754 623 8333242.6046 +755 623 -93040173.76232 +756 623 -7790968.444033 +757 623 8177128.701754 +758 623 382463.4398733 +624 624 866359460.9496 +625 624 1.430511474609e-06 +626 624 -5555615.056281 +627 624 107138445.2518 +628 624 -2.831220626831e-07 +629 624 -1388903.764753 +642 624 -58492995.80723 +643 624 -43333333.32622 +644 624 -14930548.11496 +645 624 -128333063.0188 +646 624 1.341104507446e-07 +647 624 3194474.194728 +648 624 -60367995.80692 +649 624 43333333.32622 +650 624 16319451.87991 +714 624 -41696960.65915 +715 624 8333333.336071 +716 624 24110420.45533 +717 624 -77407961.77148 +718 624 -1.184642314911e-06 +719 624 64983348.44575 +720 624 -12048523.14942 +721 624 -8333333.336071 +722 624 8485420.4502 +732 624 -94333949.07787 +733 624 1.773238182068e-06 +734 624 -694452.0061627 +735 624 -27191273.16515 +736 624 2.98023223877e-07 +737 624 -2777808.023288 +738 624 20509800.90325 +739 624 -2.242624759674e-06 +740 624 -694452.0061662 +753 624 -38845377.32488 +754 624 -8333333.33607 +755 624 -23415968.44916 +756 624 -69751628.43939 +757 624 1.266598701477e-06 +758 624 -62205540.42245 +759 624 -11071939.81576 +760 624 8333333.336071 +761 624 -7790968.444033 +625 625 762354436.272 +626 625 66665952.62197 +627 625 -6.556510925293e-07 +628 625 -57528006.93644 +629 625 -33666309.64427 +642 625 -43333333.32622 +643 625 -45492367.71613 +644 625 -7499910.748575 +645 625 -1.192092895508e-07 +646 625 62334645.32605 +647 625 16666488.1637 +648 625 43333333.32622 +649 625 -47367367.71582 +650 625 -9166577.415131 +714 625 8333333.336071 +715 625 -39196836.65327 +716 625 -17343704.63996 +717 625 -1.601874828339e-06 +718 625 -40741089.4269 +719 625 8333242.604601 +720 625 -8333333.336071 +721 625 -9548399.143536 +722 625 9010462.03536 +732 625 2.175569534302e-06 +733 625 -126000573.4156 +734 625 -67541485.19271 +735 625 2.384185791016e-07 +736 625 -47192265.20236 +737 625 33332970.40198 +738 625 -1.728534698486e-06 +739 625 -11156823.43448 +740 625 34208514.79074 +753 625 -8333333.33607 +754 625 -36345253.319 +755 625 -16510371.30635 +756 625 7.376074790955e-07 +757 625 -33084756.09483 +758 625 8333242.6046 +759 625 8333333.336071 +760 625 -8571815.80988 +761 625 8177128.701754 +626 626 1066134474.818 +627 626 -1388903.764753 +628 626 -32999642.97771 +629 626 113328361.2626 +642 626 -14930548.11516 +643 626 -7499910.748739 +644 626 -461644.445098 +645 626 2361140.861532 +646 626 16666488.1637 +647 626 141192013.134 +648 626 16319451.87971 +649 626 -9166577.414967 +650 626 -5461644.444274 +714 626 24110420.45533 +715 626 -17343704.63996 +716 626 -81284258.80916 +717 626 65400015.11214 +718 626 8333242.604601 +719 626 -113457062.6479 +720 626 8485420.4502 +721 626 9010462.03536 +722 626 -2221758.783205 +732 626 -694452.0061623 +733 626 -67874818.52582 +734 626 -284706093.7789 +735 626 -2777808.023289 +736 626 33332970.40198 +737 626 -311771151.9111 +738 626 -694452.006166 +739 626 34541848.12385 +740 626 21543906.17081 +753 626 -23415968.44916 +754 626 -16510371.30635 +755 626 -73680036.58444 +756 626 -62622207.08884 +757 626 8333242.6046 +758 626 -93040173.76232 +759 626 -7790968.444033 +760 626 8177128.701754 +761 626 382463.4398733 +627 627 866359460.9496 +628 627 1.430511474609e-06 +629 627 -5555615.056281 +630 627 107138445.2518 +631 627 -2.831220626831e-07 +632 627 -1388903.764753 +645 627 -58492995.80723 +646 627 -43333333.32622 +647 627 -14930548.11496 +648 627 -128333063.0188 +649 627 1.341104507446e-07 +650 627 3194474.194728 +651 627 -60367995.80692 +652 627 43333333.32622 +653 627 16319451.87991 +717 627 -41696960.65915 +718 627 8333333.336071 +719 627 24110420.45533 +720 627 -77407961.77148 +721 627 -1.184642314911e-06 +722 627 64983348.44575 +723 627 -12048523.14942 +724 627 -8333333.336071 +725 627 8485420.4502 +735 627 -94333949.07787 +736 627 1.773238182068e-06 +737 627 -694452.0061627 +738 627 -27191273.16515 +739 627 2.98023223877e-07 +740 627 -2777808.023288 +741 627 20509800.90325 +742 627 -2.242624759674e-06 +743 627 -694452.0061662 +756 627 -38845377.32488 +757 627 -8333333.33607 +758 627 -23415968.44916 +759 627 -69751628.43939 +760 627 1.266598701477e-06 +761 627 -62205540.42245 +762 627 -11071939.81576 +763 627 8333333.336071 +764 627 -7790968.444033 +628 628 762354436.272 +629 628 66665952.62197 +630 628 -6.556510925293e-07 +631 628 -57528006.93644 +632 628 -33666309.64427 +645 628 -43333333.32622 +646 628 -45492367.71613 +647 628 -7499910.748575 +648 628 -1.192092895508e-07 +649 628 62334645.32605 +650 628 16666488.1637 +651 628 43333333.32622 +652 628 -47367367.71582 +653 628 -9166577.415131 +717 628 8333333.336071 +718 628 -39196836.65327 +719 628 -17343704.63996 +720 628 -1.601874828339e-06 +721 628 -40741089.4269 +722 628 8333242.604601 +723 628 -8333333.336071 +724 628 -9548399.143536 +725 628 9010462.03536 +735 628 2.175569534302e-06 +736 628 -126000573.4156 +737 628 -67541485.19271 +738 628 2.384185791016e-07 +739 628 -47192265.20236 +740 628 33332970.40198 +741 628 -1.728534698486e-06 +742 628 -11156823.43448 +743 628 34208514.79074 +756 628 -8333333.33607 +757 628 -36345253.319 +758 628 -16510371.30635 +759 628 7.376074790955e-07 +760 628 -33084756.09483 +761 628 8333242.6046 +762 628 8333333.336071 +763 628 -8571815.80988 +764 628 8177128.701754 +629 629 1066134474.818 +630 629 -1388903.764753 +631 629 -32999642.97771 +632 629 113328361.2626 +645 629 -14930548.11516 +646 629 -7499910.748739 +647 629 -461644.445098 +648 629 2361140.861532 +649 629 16666488.1637 +650 629 141192013.134 +651 629 16319451.87971 +652 629 -9166577.414967 +653 629 -5461644.444274 +717 629 24110420.45533 +718 629 -17343704.63996 +719 629 -81284258.80916 +720 629 65400015.11214 +721 629 8333242.604601 +722 629 -113457062.6479 +723 629 8485420.4502 +724 629 9010462.03536 +725 629 -2221758.783205 +735 629 -694452.0061623 +736 629 -67874818.52582 +737 629 -284706093.7789 +738 629 -2777808.023289 +739 629 33332970.40198 +740 629 -311771151.9111 +741 629 -694452.006166 +742 629 34541848.12385 +743 629 21543906.17081 +756 629 -23415968.44916 +757 629 -16510371.30635 +758 629 -73680036.58444 +759 629 -62622207.08884 +760 629 8333242.6046 +761 629 -93040173.76232 +762 629 -7790968.444033 +763 629 8177128.701754 +764 629 382463.4398733 +630 630 866359460.9496 +631 630 1.430511474609e-06 +632 630 -5555615.056281 +633 630 107138445.2518 +634 630 -2.831220626831e-07 +635 630 -1388903.764753 +648 630 -58492995.80723 +649 630 -43333333.32622 +650 630 -14930548.11496 +651 630 -128333063.0188 +652 630 1.341104507446e-07 +653 630 3194474.194728 +654 630 -60367995.80692 +655 630 43333333.32622 +656 630 16319451.87991 +720 630 -41696960.65915 +721 630 8333333.336071 +722 630 24110420.45533 +723 630 -77407961.77148 +724 630 -1.184642314911e-06 +725 630 64983348.44575 +726 630 -12048523.14942 +727 630 -8333333.336071 +728 630 8485420.4502 +738 630 -94333949.07787 +739 630 1.773238182068e-06 +740 630 -694452.0061627 +741 630 -27191273.16515 +742 630 2.98023223877e-07 +743 630 -2777808.023288 +744 630 20509800.90325 +745 630 -2.242624759674e-06 +746 630 -694452.0061662 +759 630 -38845377.32488 +760 630 -8333333.33607 +761 630 -23415968.44916 +762 630 -69751628.43939 +763 630 1.266598701477e-06 +764 630 -62205540.42245 +765 630 -11071939.81576 +766 630 8333333.336071 +767 630 -7790968.444033 +631 631 762354436.272 +632 631 66665952.62197 +633 631 -6.556510925293e-07 +634 631 -57528006.93644 +635 631 -33666309.64427 +648 631 -43333333.32622 +649 631 -45492367.71613 +650 631 -7499910.748575 +651 631 -1.192092895508e-07 +652 631 62334645.32605 +653 631 16666488.1637 +654 631 43333333.32622 +655 631 -47367367.71582 +656 631 -9166577.415131 +720 631 8333333.336071 +721 631 -39196836.65327 +722 631 -17343704.63996 +723 631 -1.601874828339e-06 +724 631 -40741089.4269 +725 631 8333242.604601 +726 631 -8333333.336071 +727 631 -9548399.143536 +728 631 9010462.03536 +738 631 2.175569534302e-06 +739 631 -126000573.4156 +740 631 -67541485.19271 +741 631 2.384185791016e-07 +742 631 -47192265.20236 +743 631 33332970.40198 +744 631 -1.728534698486e-06 +745 631 -11156823.43448 +746 631 34208514.79074 +759 631 -8333333.33607 +760 631 -36345253.319 +761 631 -16510371.30635 +762 631 7.376074790955e-07 +763 631 -33084756.09483 +764 631 8333242.6046 +765 631 8333333.336071 +766 631 -8571815.80988 +767 631 8177128.701754 +632 632 1066134474.818 +633 632 -1388903.764753 +634 632 -32999642.97771 +635 632 113328361.2626 +648 632 -14930548.11516 +649 632 -7499910.748739 +650 632 -461644.445098 +651 632 2361140.861532 +652 632 16666488.1637 +653 632 141192013.134 +654 632 16319451.87971 +655 632 -9166577.414967 +656 632 -5461644.444274 +720 632 24110420.45533 +721 632 -17343704.63996 +722 632 -81284258.80916 +723 632 65400015.11214 +724 632 8333242.604601 +725 632 -113457062.6479 +726 632 8485420.4502 +727 632 9010462.03536 +728 632 -2221758.783205 +738 632 -694452.0061623 +739 632 -67874818.52582 +740 632 -284706093.7789 +741 632 -2777808.023289 +742 632 33332970.40198 +743 632 -311771151.9111 +744 632 -694452.006166 +745 632 34541848.12385 +746 632 21543906.17081 +759 632 -23415968.44916 +760 632 -16510371.30635 +761 632 -73680036.58444 +762 632 -62622207.08884 +763 632 8333242.6046 +764 632 -93040173.76232 +765 632 -7790968.444033 +766 632 8177128.701754 +767 632 382463.4398733 +633 633 858993812.0537 +634 633 23572935.22651 +635 633 -5596605.68986 +636 633 4618634.835751 +637 633 -55643925.7906 +638 633 -3070485.761489 +651 633 -58492995.80723 +652 633 -43333333.32622 +653 633 -14930548.11496 +654 633 -98216097.07436 +655 633 11347340.27138 +656 633 719973.8304573 +657 633 -33795235.93693 +658 633 40444834.51144 +659 633 2624699.350195 +723 633 -41696960.65915 +724 633 8333333.336071 +725 633 24110420.45533 +726 633 -71415955.0593 +727 633 -3233554.224872 +728 633 56726300.63859 +741 633 -94333949.07787 +742 633 1.773238182068e-06 +743 633 -694452.0061627 +744 633 -13774447.66423 +745 633 4191171.176221 +746 633 -2780612.645988 +747 633 -30223428.17772 +748 633 -11020580.63135 +749 633 14420581.05462 +762 633 -38845377.32488 +763 633 -8333333.33607 +764 633 -23415968.44916 +765 633 -64986646.84972 +766 633 2436242.286385 +767 633 -58542682.88204 +768 633 -16011865.17978 +769 633 7626721.393617 +770 633 -9769737.878529 +634 634 808466815.7419 +635 634 38960608.67833 +636 634 -55656775.51848 +637 634 -150135338.7036 +638 634 -6430096.965576 +651 634 -43333333.32622 +652 634 -45492367.71613 +653 634 -7499910.748575 +654 634 11347340.27138 +655 634 78782999.63319 +656 634 9628847.797338 +657 634 40444834.51144 +658 634 -59951104.04053 +659 634 -2777534.348236 +723 634 8333333.336071 +724 634 -39196836.65327 +725 634 -17343704.63996 +726 634 -3226694.963612 +727 634 -34510800.91818 +728 634 10096086.08607 +741 634 2.175569534302e-06 +742 634 -126000573.4156 +743 634 -67541485.19271 +744 634 4191171.17622 +745 634 -21799184.55042 +746 634 19581709.58125 +747 634 -11027439.89261 +748 634 -60138740.99675 +749 634 47821580.90675 +762 634 -8333333.33607 +763 634 -36345253.319 +764 634 -16510371.30635 +765 634 2436242.286385 +766 634 -31339965.69435 +767 634 8706676.127155 +768 634 7626721.393617 +769 634 -21957274.44509 +770 634 15232588.38105 +635 635 1060138391.827 +636 635 -3081602.172603 +637 635 -6448721.730348 +638 635 65923719.58454 +651 635 -14930548.11516 +652 635 -7499910.748739 +653 635 -461644.445098 +654 635 4886640.496438 +655 635 9628847.797338 +656 635 164674627.3592 +657 635 2624699.349784 +658 635 -2777534.348236 +659 635 9639493.762348 +723 635 24110420.45533 +724 635 -17343704.63996 +725 635 -81284258.80916 +726 635 54643912.99742 +727 635 10440765.17629 +728 635 -94980766.45259 +741 635 -694452.0061623 +742 635 -67874818.52582 +743 635 -284706093.7789 +744 635 -2762465.644181 +745 635 19596227.63998 +746 635 -269985712.4852 +747 635 14428412.5018 +748 635 47817257.06168 +749 635 -68547849.10008 +762 635 -23415968.44916 +763 635 -16510371.30635 +764 635 -73680036.58444 +765 635 -56459349.54655 +766 635 8706676.128006 +767 635 -92583202.06042 +768 635 -9769737.878529 +769 635 15232588.38105 +770 635 -24335094.043 +636 636 509824422.991 +637 636 7091706.43505 +638 636 -233419.5339228 +654 636 -59049926.58522 +655 636 -42965317.60158 +656 636 -2258246.676834 +657 636 -59241455.91135 +658 636 15132295.57647 +659 636 798361.610166 +660 636 74246775.76258 +661 636 -15390441.52608 +662 636 58526.0984211 +663 636 -25108448.92089 +664 636 39749983.45952 +665 636 516364.7746233 +726 636 -18540701.9006 +727 636 10020577.78707 +728 636 14561779.53718 +744 636 -45939787.20181 +745 636 -11027439.89261 +746 636 -17526028.04609 +747 636 -61800142.29096 +748 636 1513948.569663 +749 636 12440251.97284 +765 636 -26368729.20533 +766 636 -8242806.906906 +767 636 -17075883.20919 +768 636 -74906791.02692 +769 636 3256684.855284 +770 636 -62343936.77239 +771 636 -25367014.53987 +772 636 -3090096.028045 +773 636 8972625.494148 +774 636 -22671270.46426 +775 636 7569131.615548 +776 636 -15173808.97594 +637 637 589020111.9775 +638 637 7899561.014866 +654 637 -42965317.60158 +655 637 -38102021.6452 +656 637 -637598.5609377 +657 637 15132295.57647 +658 637 112031420.9635 +659 637 2220214.855314 +660 637 1942891.804407 +661 637 -9986366.234935 +662 637 -309424.0944229 +663 637 39749983.45952 +664 637 -31492829.01886 +665 637 -337101.3112045 +726 637 6680385.191377 +727 637 -24472689.98014 +728 637 -16861073.14158 +744 637 -11020580.63135 +745 637 -75855100.02084 +746 637 -54351585.25286 +747 637 1513948.569662 +748 637 -45007225.02585 +749 637 7591760.11537 +765 637 -8242806.906906 +766 637 -22147088.59928 +767 637 -13065785.2468 +768 637 3256684.855284 +769 637 -42318700.05597 +770 637 5034943.242021 +771 637 243237.3063829 +772 637 -41573854.45411 +773 637 33177819.90803 +774 637 7569131.615548 +775 637 -24219778.49355 +776 637 16496295.54634 +638 638 736638462.5419 +654 638 -2258246.67704 +655 638 -637598.5611018 +656 638 9368572.827382 +657 638 798361.6101658 +658 638 2220214.855314 +659 638 191399411.2569 +660 638 58526.09842288 +661 638 -309424.0944231 +662 638 123526648.2913 +663 638 516364.7744184 +664 638 -337101.3112046 +665 638 34538216.12317 +726 638 9707853.024785 +727 638 -20743439.00053 +728 638 -43509883.65538 +744 638 -17515712.64747 +745 638 -54353721.05939 +746 638 -110458139.831 +747 638 -12663636.91192 +748 638 487449.3652666 +749 638 -284041735.68 +765 638 -17075883.20919 +766 638 -13065785.2468 +767 638 -38056298.36311 +768 638 -62343936.77198 +769 638 5034943.242873 +770 638 -135317416.4032 +771 638 847625.4925454 +772 638 33177819.90803 +773 638 -81733152.47406 +774 638 -15173808.97594 +775 638 16496295.54634 +776 638 -41801871.2726 +639 639 437007897.1408 +640 639 1.788139343262e-06 +641 639 -694474.1951501 +642 639 54557514.29287 +643 639 8666666.665243 +644 639 2430548.117623 +729 639 -77407961.77148 +730 639 -1.184642314911e-06 +731 639 64983348.44575 +732 639 -12048523.14942 +733 639 -8333333.336071 +734 639 8485420.4502 +750 639 -13658136.58254 +751 639 5.662441253662e-07 +752 639 -13107792.89912 +753 639 10254900.45163 +754 639 1666666.667213 +755 639 -1974864.892506 +640 640 385005384.802 +641 640 33332976.31099 +642 640 -8666666.665243 +643 640 -27775711.80126 +644 640 -16666488.15549 +729 640 -1.601874828339e-06 +730 640 -40741089.4269 +731 640 8333242.604601 +732 640 -8333333.336071 +733 640 -9548399.143536 +734 640 9010462.03536 +750 640 5.960464477539e-08 +751 640 -23658632.60114 +752 640 16666485.20099 +753 640 -1666666.667215 +754 640 -5578411.717238 +755 640 17187590.72873 +641 641 543275681.852 +642 641 -3819451.88135 +643 641 -16666488.15549 +644 641 59299625.07651 +729 641 65400015.11214 +730 641 8333242.604601 +731 641 -113457062.6479 +732 641 8485420.4502 +733 641 9010462.03536 +734 641 -2221758.783205 +750 641 12413318.2078 +751 641 16666485.20099 +752 641 -156052242.6221 +753 641 1280412.88634 +754 641 17187590.72856 +755 641 10771953.08541 +642 642 437007897.1408 +643 642 1.788139343262e-06 +644 642 -694474.1951501 +645 642 54557514.29287 +646 642 8666666.665243 +647 642 2430548.117623 +729 642 -41696960.65915 +730 642 8333333.336071 +731 642 24110420.45533 +732 642 -77407961.77148 +733 642 -1.184642314911e-06 +734 642 64983348.44575 +735 642 -12048523.14942 +736 642 -8333333.336071 +737 642 8485420.4502 +750 642 -47166974.53894 +751 642 -1666666.667213 +752 642 -5099864.893531 +753 642 -13658136.58254 +754 642 5.662441253662e-07 +755 642 -13107792.89912 +756 642 10254900.45163 +757 642 1666666.667213 +758 642 -1974864.892506 +643 643 385005384.802 +644 643 33332976.31099 +645 643 -8666666.665243 +646 643 -27775711.80126 +647 643 -16666488.15549 +729 643 8333333.336071 +730 643 -39196836.65327 +731 643 -17343704.63996 +732 643 -1.601874828339e-06 +733 643 -40741089.4269 +734 643 8333242.604601 +735 643 -8333333.336071 +736 643 -9548399.143536 +737 643 9010462.03536 +750 643 1666666.667215 +751 643 -63000286.7078 +752 643 -33854075.92972 +753 643 5.960464477539e-08 +754 643 -23658632.60114 +755 643 16666485.20099 +756 643 -1666666.667215 +757 643 -5578411.717238 +758 643 17187590.72873 +644 644 543275681.852 +645 644 -3819451.88135 +646 644 -16666488.15549 +647 644 59299625.07651 +729 644 24110420.45533 +730 644 -17343704.63996 +731 644 -81284258.80916 +732 644 65400015.11214 +733 644 8333242.604601 +734 644 -113457062.6479 +735 644 8485420.4502 +736 644 9010462.03536 +737 644 -2221758.783205 +750 644 4405412.887368 +751 644 -33854075.92955 +752 644 -142353046.8894 +753 644 12413318.2078 +754 644 16666485.20099 +755 644 -156052242.6221 +756 644 1280412.88634 +757 644 17187590.72856 +758 644 10771953.08541 +645 645 437007897.1408 +646 645 1.788139343262e-06 +647 645 -694474.1951501 +648 645 54557514.29287 +649 645 8666666.665243 +650 645 2430548.117623 +732 645 -41696960.65915 +733 645 8333333.336071 +734 645 24110420.45533 +735 645 -77407961.77148 +736 645 -1.184642314911e-06 +737 645 64983348.44575 +738 645 -12048523.14942 +739 645 -8333333.336071 +740 645 8485420.4502 +753 645 -47166974.53894 +754 645 -1666666.667213 +755 645 -5099864.893531 +756 645 -13658136.58254 +757 645 5.662441253662e-07 +758 645 -13107792.89912 +759 645 10254900.45163 +760 645 1666666.667213 +761 645 -1974864.892506 +646 646 385005384.802 +647 646 33332976.31099 +648 646 -8666666.665243 +649 646 -27775711.80126 +650 646 -16666488.15549 +732 646 8333333.336071 +733 646 -39196836.65327 +734 646 -17343704.63996 +735 646 -1.601874828339e-06 +736 646 -40741089.4269 +737 646 8333242.604601 +738 646 -8333333.336071 +739 646 -9548399.143536 +740 646 9010462.03536 +753 646 1666666.667215 +754 646 -63000286.7078 +755 646 -33854075.92972 +756 646 5.960464477539e-08 +757 646 -23658632.60114 +758 646 16666485.20099 +759 646 -1666666.667215 +760 646 -5578411.717238 +761 646 17187590.72873 +647 647 543275681.852 +648 647 -3819451.88135 +649 647 -16666488.15549 +650 647 59299625.07651 +732 647 24110420.45533 +733 647 -17343704.63996 +734 647 -81284258.80916 +735 647 65400015.11214 +736 647 8333242.604601 +737 647 -113457062.6479 +738 647 8485420.4502 +739 647 9010462.03536 +740 647 -2221758.783205 +753 647 4405412.887368 +754 647 -33854075.92955 +755 647 -142353046.8894 +756 647 12413318.2078 +757 647 16666485.20099 +758 647 -156052242.6221 +759 647 1280412.88634 +760 647 17187590.72856 +761 647 10771953.08541 +648 648 437007897.1408 +649 648 1.788139343262e-06 +650 648 -694474.1951501 +651 648 54557514.29287 +652 648 8666666.665243 +653 648 2430548.117623 +735 648 -41696960.65915 +736 648 8333333.336071 +737 648 24110420.45533 +738 648 -77407961.77148 +739 648 -1.184642314911e-06 +740 648 64983348.44575 +741 648 -12048523.14942 +742 648 -8333333.336071 +743 648 8485420.4502 +756 648 -47166974.53894 +757 648 -1666666.667213 +758 648 -5099864.893531 +759 648 -13658136.58254 +760 648 5.662441253662e-07 +761 648 -13107792.89912 +762 648 10254900.45163 +763 648 1666666.667213 +764 648 -1974864.892506 +649 649 385005384.802 +650 649 33332976.31099 +651 649 -8666666.665243 +652 649 -27775711.80126 +653 649 -16666488.15549 +735 649 8333333.336071 +736 649 -39196836.65327 +737 649 -17343704.63996 +738 649 -1.601874828339e-06 +739 649 -40741089.4269 +740 649 8333242.604601 +741 649 -8333333.336071 +742 649 -9548399.143536 +743 649 9010462.03536 +756 649 1666666.667215 +757 649 -63000286.7078 +758 649 -33854075.92972 +759 649 5.960464477539e-08 +760 649 -23658632.60114 +761 649 16666485.20099 +762 649 -1666666.667215 +763 649 -5578411.717238 +764 649 17187590.72873 +650 650 543275681.852 +651 650 -3819451.88135 +652 650 -16666488.15549 +653 650 59299625.07651 +735 650 24110420.45533 +736 650 -17343704.63996 +737 650 -81284258.80916 +738 650 65400015.11214 +739 650 8333242.604601 +740 650 -113457062.6479 +741 650 8485420.4502 +742 650 9010462.03536 +743 650 -2221758.783205 +756 650 4405412.887368 +757 650 -33854075.92955 +758 650 -142353046.8894 +759 650 12413318.2078 +760 650 16666485.20099 +761 650 -156052242.6221 +762 650 1280412.88634 +763 650 17187590.72856 +764 650 10771953.08541 +651 651 437007897.1408 +652 651 1.788139343262e-06 +653 651 -694474.1951501 +654 651 54557514.29287 +655 651 8666666.665243 +656 651 2430548.117623 +738 651 -41696960.65915 +739 651 8333333.336071 +740 651 24110420.45533 +741 651 -77407961.77148 +742 651 -1.184642314911e-06 +743 651 64983348.44575 +744 651 -12048523.14942 +745 651 -8333333.336071 +746 651 8485420.4502 +759 651 -47166974.53894 +760 651 -1666666.667213 +761 651 -5099864.893531 +762 651 -13658136.58254 +763 651 5.662441253662e-07 +764 651 -13107792.89912 +765 651 10254900.45163 +766 651 1666666.667213 +767 651 -1974864.892506 +652 652 385005384.802 +653 652 33332976.31099 +654 652 -8666666.665243 +655 652 -27775711.80126 +656 652 -16666488.15549 +738 652 8333333.336071 +739 652 -39196836.65327 +740 652 -17343704.63996 +741 652 -1.601874828339e-06 +742 652 -40741089.4269 +743 652 8333242.604601 +744 652 -8333333.336071 +745 652 -9548399.143536 +746 652 9010462.03536 +759 652 1666666.667215 +760 652 -63000286.7078 +761 652 -33854075.92972 +762 652 5.960464477539e-08 +763 652 -23658632.60114 +764 652 16666485.20099 +765 652 -1666666.667215 +766 652 -5578411.717238 +767 652 17187590.72873 +653 653 543275681.852 +654 653 -3819451.88135 +655 653 -16666488.15549 +656 653 59299625.07651 +738 653 24110420.45533 +739 653 -17343704.63996 +740 653 -81284258.80916 +741 653 65400015.11214 +742 653 8333242.604601 +743 653 -113457062.6479 +744 653 8485420.4502 +745 653 9010462.03536 +746 653 -2221758.783205 +759 653 4405412.887368 +760 653 -33854075.92955 +761 653 -142353046.8894 +762 653 12413318.2078 +763 653 16666485.20099 +764 653 -156052242.6221 +765 653 1280412.88634 +766 653 17187590.72856 +767 653 10771953.08541 +654 654 447412022.0987 +655 654 367932.9627128 +656 654 -13022116.19691 +657 654 49415165.36624 +658 654 -3416622.293492 +659 654 -439610.9536436 +741 654 -41696960.65915 +742 654 8333333.336071 +743 654 24110420.45533 +744 654 -72955365.59794 +745 654 2436242.286385 +746 654 61378150.43314 +747 654 -22540576.42629 +748 654 -8242806.906905 +749 654 14824116.80129 +762 654 -47166974.53894 +763 654 -1666666.667213 +764 654 -5099864.893531 +765 654 -19040600.32219 +766 654 90519.34075832 +767 654 -19268094.90535 +768 654 -13147418.28847 +769 654 -950621.3890942 +770 654 1450272.108583 +655 655 403364363.9692 +656 655 20195692.56007 +657 655 -20749955.62398 +658 655 -35151580.14884 +659 655 -3353876.225841 +741 655 8333333.336071 +742 655 -39196836.65327 +743 655 -17343704.63996 +744 655 2436242.286384 +745 655 -39308684.44256 +746 655 894176.12852 +747 655 -8242806.906905 +748 655 -18318935.82024 +749 655 12455048.09491 +762 655 1666666.667215 +763 655 -63000286.7078 +764 655 -33854075.92972 +765 655 90519.34075797 +766 655 -27318088.15734 +767 655 10111276.76934 +768 655 -4283954.723522 +769 655 -29405064.05177 +770 655 27737279.5769 +656 656 582349612.129 +657 656 -1689610.95344 +658 656 -3353876.225841 +659 656 79771026.4956 +741 656 24110420.45533 +742 656 -17343704.63996 +743 656 -81284258.80916 +744 656 59294817.09957 +745 656 894176.1292076 +746 656 -113833118.7223 +747 656 14824116.80129 +748 656 12455048.09491 +749 656 -27847890.95234 +762 656 4405412.887368 +763 656 -33854075.92955 +764 656 -142353046.8894 +765 656 6252460.646014 +766 656 10111276.76934 +767 656 -168050028.8542 +768 656 7205272.109613 +769 656 27737279.57605 +770 656 -44092711.32715 +657 657 423348866.0204 +658 657 11032466.66264 +659 657 326585.5522151 +660 657 -62232004.47076 +661 657 -46916683.19291 +662 657 -525301.8919845 +663 657 51948761.9348 +664 657 1057042.066345 +665 657 131933.0004746 +744 657 -22730594.34878 +745 657 7626721.393617 +746 657 12364984.35096 +747 657 -76547391.72184 +748 657 3256684.855286 +749 657 63175507.65185 +765 657 -24944296.75828 +766 657 -4283954.723523 +767 657 -8940005.667694 +768 657 -48889704.10442 +769 657 2464794.383752 +770 657 -12359093.76876 +771 657 -30483492.68905 +772 657 -9097535.056593 +773 657 20047718.8134 +774 657 -23754733.9178 +775 657 33289.14746143 +776 657 1855888.619689 +658 658 428928472.3575 +659 658 5287278.179705 +660 658 -46916683.19291 +661 658 -45414162.35006 +662 658 -337101.3112045 +663 658 -16276291.26414 +664 658 -30998949.77914 +665 658 -1038981.149731 +744 658 7626721.393617 +745 658 -28676003.61409 +746 658 -18100744.96323 +747 658 3256684.855286 +748 658 -43959300.75089 +749 658 -2777556.756613 +765 658 -950621.3890945 +766 658 -41201942.52158 +767 658 -31116887.08018 +768 658 2464794.383752 +769 658 -46644595.36138 +770 658 2691531.008842 +771 658 -9097535.056593 +772 658 -27149361.82785 +773 658 16496295.54634 +774 658 -3300044.186967 +775 658 -39719009.46437 +776 658 32807362.24483 +659 659 584145228.2337 +660 659 -525301.8919851 +661 659 -337101.3112046 +662 659 20616882.79198 +663 659 -284733.6661254 +664 659 -1038981.149731 +665 659 99612216.13263 +744 659 12364984.35096 +745 659 -18100744.96323 +746 659 -42251705.16035 +747 659 63175507.65144 +748 659 -2777556.755926 +749 659 -139692351.5897 +765 659 -1935005.666458 +766 659 -31116887.08087 +767 659 -75551053.91331 +768 659 12744795.11601 +769 659 2691531.008842 +770 659 -234152588.3109 +771 659 20047718.8134 +772 659 16496295.54634 +773 659 -44731454.6069 +774 659 7819499.733824 +775 659 32807362.24483 +776 659 -69888082.52598 +660 660 244685203.3475 +661 660 50057108.18705 +662 660 288696.1236947 +663 660 -36054766.3116 +664 660 -5083316.798544 +665 660 178079.6698694 +747 660 -26617014.5403 +748 660 243237.3063828 +749 660 -792652.2819211 +768 660 -31733492.68947 +769 660 -9097535.056593 +770 660 -20577281.19994 +771 660 -33148818.76463 +772 660 9756762.696902 +773 660 8271124.504546 +774 660 -44282340.66884 +775 660 -902464.9466921 +776 660 -35651191.02268 +661 661 223293345.3624 +662 661 309424.094425 +663 661 12250016.53194 +664 661 52752391.55036 +665 661 337101.3112057 +747 661 -3090096.028045 +748 661 -42823854.45454 +749 661 -33488846.74768 +768 661 -9097535.056593 +769 661 -28399361.82827 +770 661 -16837037.79794 +771 661 9756762.696902 +772 661 -37254478.85706 +773 661 6822180.085395 +774 661 2430868.387736 +775 661 -27303971.52336 +776 661 3503704.460225 +662 662 339666962.7326 +663 662 178079.6698721 +664 662 337101.3112057 +665 662 104576728.3915 +747 662 -8917652.283731 +748 662 -33488846.74768 +749 662 -85066485.80853 +768 662 -20577281.19995 +769 662 -16837037.79794 +770 662 -48064787.94135 +771 662 -7978875.492785 +772 662 -6511153.245748 +773 662 -148788236.3624 +774 662 -35651191.02354 +775 662 -3162962.208631 +776 662 -80164934.32299 +663 663 212848619.9699 +664 663 -35723708.72732 +665 663 423622.5554408 +747 663 -23921270.46468 +748 663 7569131.615548 +749 663 15685913.25641 +768 663 -27504733.91658 +769 663 -3300044.186967 +770 663 -8117722.489783 +771 663 -44282340.66884 +772 663 2430868.387737 +773 663 35833531.18791 +774 663 -29604988.28668 +775 663 -6699955.816318 +776 663 -5953388.621477 +664 664 213373553.9199 +665 664 1038981.149734 +747 664 7569131.615548 +748 664 -25469778.49398 +749 664 -16837037.79794 +768 664 33289.14746112 +769 664 -43469009.46316 +770 664 -33859304.41089 +771 664 -902464.9466912 +772 664 -27303971.52336 +773 664 3503704.460225 +774 664 -6699955.816318 +775 664 -29070573.85628 +776 664 7192637.7486 +665 665 304297283.8121 +747 665 15685913.25641 +748 665 -16837037.79794 +749 665 -45135204.60706 +768 665 -1737444.709049 +769 665 -33859304.41089 +770 665 -79888082.52274 +771 665 35833531.18684 +772 665 -3162962.208631 +773 665 -80164934.32299 +774 665 6390500.265385 +775 665 -6140695.582542 +776 665 -128980667.4453 +666 666 544597009.4256 +667 666 33333333.32786 +668 666 -31989118.31313 +669 666 -132114372.9571 +670 666 -33352308.14156 +671 666 31970539.06385 +672 666 1216456.507315 +673 666 26685641.47599 +674 666 25851320.01324 +777 666 -10929001.68405 +778 666 8333333.33607 +779 666 3726516.388097 +780 666 -69036918.95254 +781 666 -8338077.039497 +782 666 -55624567.39871 +783 666 7014515.850343 +784 666 6671410.372285 +785 666 -6514983.987003 +667 667 494573181.6273 +668 667 83368386.85484 +669 667 -33361795.54841 +670 667 24612909.30639 +671 667 46187594.51733 +672 667 40028462.21399 +673 667 1216456.507311 +674 667 -29021109.31684 +777 667 8333333.336069 +778 667 -23434958.63979 +779 667 30221022.26397 +780 667 -8340448.891212 +781 667 -29855098.36736 +782 667 -1182917.166231 +783 667 10007115.55843 +784 667 7014515.850342 +785 667 7818288.469344 +668 668 853850595.3707 +669 668 31961249.43922 +670 668 37180558.07827 +671 668 139399647.4134 +672 668 38776980.01986 +673 668 -19347406.21122 +674 668 3243884.01951 +777 668 -21803668.18463 +778 668 9797097.079457 +779 668 -178746028.6722 +780 668 -56043408.3313 +781 668 -3514321.011405 +782 668 -61172289.98812 +783 668 -9772475.980504 +784 668 5212192.312896 +785 668 18705375.60092 +669 669 847901916.7151 +670 669 33380770.36212 +671 669 -37498286.23383 +672 669 39751697.94156 +673 669 -33352308.14156 +674 669 -32448557.35788 +675 669 -59718971.98211 +676 669 -9.387731552124e-07 +677 669 5555616.043855 +678 669 -46856498.79532 +679 669 33333333.32786 +680 669 32430570.67332 +777 669 -99681629.70551 +778 669 -8340448.891213 +779 669 71607514.53236 +780 669 -8298175.66356 +781 669 8345192.594641 +782 669 -9379478.645899 +783 669 2423001.606932 +784 669 -8338077.0395 +785 669 7795396.873343 +786 669 -69751628.43939 +787 669 1.266598701477e-06 +788 669 -62205540.42245 +789 669 -11071939.81576 +790 669 8333333.336071 +791 669 -7790968.444033 +670 670 757876104.862 +671 670 103333663.8687 +672 670 -33361795.54842 +673 670 -76952252.54226 +674 670 -55347988.6005 +675 670 -8.344650268555e-07 +676 670 86948517.3239 +677 670 33332970.40197 +678 670 33333333.32786 +679 670 -36856002.77671 +680 670 -18166485.20082 +777 670 -8338077.039499 +778 670 -60499809.12032 +779 670 22021029.70742 +780 670 8345192.594641 +781 670 -30804628.63791 +782 670 25829490.35962 +783 670 -8340448.891214 +784 670 -26752986.0284 +785 670 37056208.64825 +786 670 7.376074790955e-07 +787 670 -33084756.09483 +788 670 8333242.6046 +789 670 8333333.336071 +790 670 -8571815.80988 +791 670 8177128.701754 +671 671 1184141501.437 +672 671 -32874217.36655 +673 671 -64688121.35194 +674 671 93077437.24068 +675 671 5555616.043855 +676 671 33332970.40197 +677 671 212606082.8355 +678 671 32847237.33971 +679 671 -18499818.53394 +680 671 -5320118.38549 +777 671 72026355.46494 +778 671 24359692.24116 +779 671 -142891518.6627 +780 671 -9370405.180087 +781 671 25836749.05321 +782 671 -291361037.6863 +783 671 7797611.087997 +784 671 35054390.19536 +785 671 3229564.966024 +786 671 -62622207.08884 +787 671 8333242.6046 +788 671 -93040173.76232 +789 671 -7790968.444033 +790 671 8177128.701754 +791 671 382463.4398733 +672 672 544597009.4256 +673 672 33333333.32786 +674 672 -31989118.31313 +675 672 -43106498.79594 +676 672 -33333333.32786 +677 672 -30069429.31642 +678 672 -132114372.9571 +679 672 -33352308.14156 +680 672 31970539.06385 +681 672 1216456.507315 +682 672 26685641.47599 +683 672 25851320.01324 +777 672 -50448491.13742 +778 672 10007115.55843 +779 672 28536410.43085 +780 672 -85645347.16108 +781 672 -8340448.891212 +782 672 -24130997.54348 +783 672 -10929001.68405 +784 672 8333333.33607 +785 672 3726516.388097 +786 672 -38845377.32488 +787 672 -8333333.33607 +788 672 -23415968.44916 +789 672 -69036918.95254 +790 672 -8338077.039497 +791 672 -55624567.39871 +792 672 7014515.850343 +793 672 6671410.372285 +794 672 -6514983.987003 +673 673 494573181.6273 +674 673 83368386.85484 +675 673 -33333333.32786 +676 673 -33106002.77733 +677 673 -15166485.20115 +678 673 -33361795.54841 +679 673 24612909.30639 +680 673 46187594.51733 +681 673 40028462.21399 +682 673 1216456.507311 +683 673 -29021109.31684 +777 673 6671410.372285 +778 673 -50448491.13742 +779 673 -15218991.7376 +780 673 -8338077.039498 +781 673 -114821334.7964 +782 673 -67065236.07198 +783 673 8333333.336069 +784 673 -23434958.63979 +785 673 30221022.26397 +786 673 -8333333.33607 +787 673 -36345253.319 +788 673 -16510371.30635 +789 673 -8340448.891212 +790 673 -29855098.36736 +791 673 -1182917.166231 +792 673 10007115.55843 +793 673 7014515.850342 +794 673 7818288.469344 +674 674 853850595.3707 +675 674 -29652762.65002 +676 674 -14833151.86804 +677 674 4679881.612865 +678 674 31961249.43922 +679 674 37180558.07827 +680 674 139399647.4134 +681 674 38776980.01986 +682 674 -19347406.21122 +683 674 3243884.01951 +777 674 19024273.62057 +778 674 -22828487.60639 +779 674 -134529309.6998 +780 674 -24124138.5141 +781 674 -65063417.79147 +782 674 -231619365.082 +783 674 -21803668.18463 +784 674 9797097.079457 +785 674 -178746028.6722 +786 674 -23415968.44916 +787 674 -16510371.30635 +788 674 -73680036.58444 +789 674 -56043408.3313 +790 674 -3514321.011405 +791 674 -61172289.98812 +792 674 -9772475.980504 +793 674 5212192.312896 +794 674 18705375.60092 +675 675 829135740.1102 +676 675 1.847743988037e-06 +677 675 -11111232.08774 +678 675 86951912.01811 +679 675 -3.8743019104e-07 +680 675 -2777808.023304 +684 675 -59718971.98211 +685 675 -9.387731552124e-07 +686 675 5555616.043855 +687 675 -46856498.79532 +688 675 33333333.32786 +689 675 32430570.67332 +780 675 -77407961.77148 +781 675 -1.184642314911e-06 +782 675 64983348.44575 +783 675 -12048523.14942 +784 675 -8333333.336071 +785 675 8485420.4502 +786 675 -27191273.16515 +787 675 2.98023223877e-07 +788 675 -2777808.023288 +789 675 20509800.90325 +790 675 -2.242624759674e-06 +791 675 -694452.0061662 +795 675 -69751628.43939 +796 675 1.266598701477e-06 +797 675 -62205540.42245 +798 675 -11071939.81576 +799 675 8333333.336071 +800 675 -7790968.444033 +676 676 749131772.0008 +677 676 133331881.5422 +678 676 -1.639127731323e-07 +679 676 -39714585.27039 +680 676 -66665940.77111 +684 676 -8.344650268555e-07 +685 676 86948517.3239 +686 676 33332970.40197 +687 676 33333333.32786 +688 676 -36856002.77671 +689 676 -18166485.20082 +780 676 -1.601874828339e-06 +781 676 -40741089.4269 +782 676 8333242.604601 +783 676 -8333333.336071 +784 676 -9548399.143536 +785 676 9010462.03536 +786 676 2.384185791016e-07 +787 676 -47192265.20236 +788 676 33332970.40198 +789 676 -1.728534698486e-06 +790 676 -11156823.43448 +791 676 34208514.79074 +795 676 7.376074790955e-07 +796 676 -33084756.09483 +797 676 8333242.6046 +798 676 8333333.336071 +799 676 -8571815.80988 +800 676 8177128.701754 +677 677 1253984280.216 +678 677 -2777808.023304 +679 677 -66665940.77111 +680 677 99276180.49554 +684 677 5555616.043855 +685 677 33332970.40197 +686 677 212606082.8355 +687 677 32847237.33971 +688 677 -18499818.53394 +689 677 -5320118.38549 +780 677 65400015.11214 +781 677 8333242.604601 +782 677 -113457062.6479 +783 677 8485420.4502 +784 677 9010462.03536 +785 677 -2221758.783205 +786 677 -2777808.023289 +787 677 33332970.40198 +788 677 -311771151.9111 +789 677 -694452.006166 +790 677 34541848.12385 +791 677 21543906.17081 +795 677 -62622207.08884 +796 677 8333242.6046 +797 677 -93040173.76232 +798 677 -7790968.444033 +799 677 8177128.701754 +800 677 382463.4398733 +678 678 847901916.7151 +679 678 33380770.36212 +680 678 -37498286.23383 +681 678 39751697.94156 +682 678 -33352308.14156 +683 678 -32448557.35788 +684 678 -43106498.79594 +685 678 -33333333.32786 +686 678 -30069429.31642 +687 678 -59718971.98211 +688 678 -9.387731552124e-07 +689 678 5555616.043855 +690 678 -46856498.79532 +691 678 33333333.32786 +692 678 32430570.67332 +780 678 -41696960.65915 +781 678 8333333.336071 +782 678 24110420.45533 +783 678 -99681629.70551 +784 678 -8340448.891213 +785 678 71607514.53236 +786 678 -94333949.07787 +787 678 1.773238182068e-06 +788 678 -694452.0061627 +789 678 -8298175.66356 +790 678 8345192.594641 +791 678 -9379478.645899 +792 678 2423001.606932 +793 678 -8338077.0395 +794 678 7795396.873343 +795 678 -38845377.32488 +796 678 -8333333.33607 +797 678 -23415968.44916 +798 678 -69751628.43939 +799 678 1.266598701477e-06 +800 678 -62205540.42245 +801 678 -11071939.81576 +802 678 8333333.336071 +803 678 -7790968.444033 +679 679 757876104.862 +680 679 103333663.8687 +681 679 -33361795.54842 +682 679 -76952252.54226 +683 679 -55347988.6005 +684 679 -33333333.32786 +685 679 -33106002.77733 +686 679 -15166485.20115 +687 679 -8.344650268555e-07 +688 679 86948517.3239 +689 679 33332970.40197 +690 679 33333333.32786 +691 679 -36856002.77671 +692 679 -18166485.20082 +780 679 8333333.336071 +781 679 -39196836.65327 +782 679 -17343704.63996 +783 679 -8338077.039499 +784 679 -60499809.12032 +785 679 22021029.70742 +786 679 2.175569534302e-06 +787 679 -126000573.4156 +788 679 -67541485.19271 +789 679 8345192.594641 +790 679 -30804628.63791 +791 679 25829490.35962 +792 679 -8340448.891214 +793 679 -26752986.0284 +794 679 37056208.64825 +795 679 -8333333.33607 +796 679 -36345253.319 +797 679 -16510371.30635 +798 679 7.376074790955e-07 +799 679 -33084756.09483 +800 679 8333242.6046 +801 679 8333333.336071 +802 679 -8571815.80988 +803 679 8177128.701754 +680 680 1184141501.437 +681 680 -32874217.36655 +682 680 -64688121.35194 +683 680 93077437.24068 +684 680 -29652762.65002 +685 680 -14833151.86804 +686 680 4679881.612865 +687 680 5555616.043855 +688 680 33332970.40197 +689 680 212606082.8355 +690 680 32847237.33971 +691 680 -18499818.53394 +692 680 -5320118.38549 +780 680 24110420.45533 +781 680 -17343704.63996 +782 680 -81284258.80916 +783 680 72026355.46494 +784 680 24359692.24116 +785 680 -142891518.6627 +786 680 -694452.0061623 +787 680 -67874818.52582 +788 680 -284706093.7789 +789 680 -9370405.180087 +790 680 25836749.05321 +791 680 -291361037.6863 +792 680 7797611.087997 +793 680 35054390.19536 +794 680 3229564.966024 +795 680 -23415968.44916 +796 680 -16510371.30635 +797 680 -73680036.58444 +798 680 -62622207.08884 +799 680 8333242.6046 +800 680 -93040173.76232 +801 680 -7790968.444033 +802 680 8177128.701754 +803 680 382463.4398733 +681 681 544597009.4256 +682 681 33333333.32786 +683 681 -31989118.31313 +687 681 -43106498.79594 +688 681 -33333333.32786 +689 681 -30069429.31642 +690 681 -132114372.9571 +691 681 -33352308.14156 +692 681 31970539.06385 +693 681 1216456.507315 +694 681 26685641.47599 +695 681 25851320.01324 +783 681 -50448491.13742 +784 681 10007115.55843 +785 681 28536410.43085 +789 681 -85645347.16108 +790 681 -8340448.891212 +791 681 -24130997.54348 +792 681 -10929001.68405 +793 681 8333333.33607 +794 681 3726516.388097 +798 681 -38845377.32488 +799 681 -8333333.33607 +800 681 -23415968.44916 +801 681 -69036918.95254 +802 681 -8338077.039497 +803 681 -55624567.39871 +804 681 7014515.850343 +805 681 6671410.372285 +806 681 -6514983.987003 +682 682 494573181.6273 +683 682 83368386.85484 +687 682 -33333333.32786 +688 682 -33106002.77733 +689 682 -15166485.20115 +690 682 -33361795.54841 +691 682 24612909.30639 +692 682 46187594.51733 +693 682 40028462.21399 +694 682 1216456.507311 +695 682 -29021109.31684 +783 682 6671410.372285 +784 682 -50448491.13742 +785 682 -15218991.7376 +789 682 -8338077.039498 +790 682 -114821334.7964 +791 682 -67065236.07198 +792 682 8333333.336069 +793 682 -23434958.63979 +794 682 30221022.26397 +798 682 -8333333.33607 +799 682 -36345253.319 +800 682 -16510371.30635 +801 682 -8340448.891212 +802 682 -29855098.36736 +803 682 -1182917.166231 +804 682 10007115.55843 +805 682 7014515.850342 +806 682 7818288.469344 +683 683 853850595.3707 +687 683 -29652762.65002 +688 683 -14833151.86804 +689 683 4679881.612865 +690 683 31961249.43922 +691 683 37180558.07827 +692 683 139399647.4134 +693 683 38776980.01986 +694 683 -19347406.21122 +695 683 3243884.01951 +783 683 19024273.62057 +784 683 -22828487.60639 +785 683 -134529309.6998 +789 683 -24124138.5141 +790 683 -65063417.79147 +791 683 -231619365.082 +792 683 -21803668.18463 +793 683 9797097.079457 +794 683 -178746028.6722 +798 683 -23415968.44916 +799 683 -16510371.30635 +800 683 -73680036.58444 +801 683 -56043408.3313 +802 683 -3514321.011405 +803 683 -61172289.98812 +804 683 -9772475.980504 +805 683 5212192.312896 +806 683 18705375.60092 +684 684 829135740.1102 +685 684 1.847743988037e-06 +686 684 -11111232.08774 +687 684 86951912.01811 +688 684 -3.8743019104e-07 +689 684 -2777808.023304 +696 684 -59718971.98211 +697 684 -9.387731552124e-07 +698 684 5555616.043855 +699 684 -46856498.79532 +700 684 33333333.32786 +701 684 32430570.67332 +786 684 -77407961.77148 +787 684 -1.184642314911e-06 +788 684 64983348.44575 +789 684 -12048523.14942 +790 684 -8333333.336071 +791 684 8485420.4502 +795 684 -27191273.16515 +796 684 2.98023223877e-07 +797 684 -2777808.023288 +798 684 20509800.90325 +799 684 -2.242624759674e-06 +800 684 -694452.0061662 +807 684 -69751628.43939 +808 684 1.266598701477e-06 +809 684 -62205540.42245 +810 684 -11071939.81576 +811 684 8333333.336071 +812 684 -7790968.444033 +685 685 749131772.0008 +686 685 133331881.5422 +687 685 -1.639127731323e-07 +688 685 -39714585.27039 +689 685 -66665940.77111 +696 685 -8.344650268555e-07 +697 685 86948517.3239 +698 685 33332970.40197 +699 685 33333333.32786 +700 685 -36856002.77671 +701 685 -18166485.20082 +786 685 -1.601874828339e-06 +787 685 -40741089.4269 +788 685 8333242.604601 +789 685 -8333333.336071 +790 685 -9548399.143536 +791 685 9010462.03536 +795 685 2.384185791016e-07 +796 685 -47192265.20236 +797 685 33332970.40198 +798 685 -1.728534698486e-06 +799 685 -11156823.43448 +800 685 34208514.79074 +807 685 7.376074790955e-07 +808 685 -33084756.09483 +809 685 8333242.6046 +810 685 8333333.336071 +811 685 -8571815.80988 +812 685 8177128.701754 +686 686 1253984280.216 +687 686 -2777808.023304 +688 686 -66665940.77111 +689 686 99276180.49554 +696 686 5555616.043855 +697 686 33332970.40197 +698 686 212606082.8355 +699 686 32847237.33971 +700 686 -18499818.53394 +701 686 -5320118.38549 +786 686 65400015.11214 +787 686 8333242.604601 +788 686 -113457062.6479 +789 686 8485420.4502 +790 686 9010462.03536 +791 686 -2221758.783205 +795 686 -2777808.023289 +796 686 33332970.40198 +797 686 -311771151.9111 +798 686 -694452.006166 +799 686 34541848.12385 +800 686 21543906.17081 +807 686 -62622207.08884 +808 686 8333242.6046 +809 686 -93040173.76232 +810 686 -7790968.444033 +811 686 8177128.701754 +812 686 382463.4398733 +687 687 829135740.1102 +688 687 1.847743988037e-06 +689 687 -11111232.08774 +690 687 86951912.01811 +691 687 -3.8743019104e-07 +692 687 -2777808.023304 +696 687 -43106498.79594 +697 687 -33333333.32786 +698 687 -30069429.31642 +699 687 -59718971.98211 +700 687 -9.387731552124e-07 +701 687 5555616.043855 +702 687 -46856498.79532 +703 687 33333333.32786 +704 687 32430570.67332 +786 687 -41696960.65915 +787 687 8333333.336071 +788 687 24110420.45533 +789 687 -77407961.77148 +790 687 -1.184642314911e-06 +791 687 64983348.44575 +792 687 -12048523.14942 +793 687 -8333333.336071 +794 687 8485420.4502 +795 687 -94333949.07787 +796 687 1.773238182068e-06 +797 687 -694452.0061627 +798 687 -27191273.16515 +799 687 2.98023223877e-07 +800 687 -2777808.023288 +801 687 20509800.90325 +802 687 -2.242624759674e-06 +803 687 -694452.0061662 +807 687 -38845377.32488 +808 687 -8333333.33607 +809 687 -23415968.44916 +810 687 -69751628.43939 +811 687 1.266598701477e-06 +812 687 -62205540.42245 +813 687 -11071939.81576 +814 687 8333333.336071 +815 687 -7790968.444033 +688 688 749131772.0008 +689 688 133331881.5422 +690 688 -1.639127731323e-07 +691 688 -39714585.27039 +692 688 -66665940.77111 +696 688 -33333333.32786 +697 688 -33106002.77733 +698 688 -15166485.20115 +699 688 -8.344650268555e-07 +700 688 86948517.3239 +701 688 33332970.40197 +702 688 33333333.32786 +703 688 -36856002.77671 +704 688 -18166485.20082 +786 688 8333333.336071 +787 688 -39196836.65327 +788 688 -17343704.63996 +789 688 -1.601874828339e-06 +790 688 -40741089.4269 +791 688 8333242.604601 +792 688 -8333333.336071 +793 688 -9548399.143536 +794 688 9010462.03536 +795 688 2.175569534302e-06 +796 688 -126000573.4156 +797 688 -67541485.19271 +798 688 2.384185791016e-07 +799 688 -47192265.20236 +800 688 33332970.40198 +801 688 -1.728534698486e-06 +802 688 -11156823.43448 +803 688 34208514.79074 +807 688 -8333333.33607 +808 688 -36345253.319 +809 688 -16510371.30635 +810 688 7.376074790955e-07 +811 688 -33084756.09483 +812 688 8333242.6046 +813 688 8333333.336071 +814 688 -8571815.80988 +815 688 8177128.701754 +689 689 1253984280.216 +690 689 -2777808.023304 +691 689 -66665940.77111 +692 689 99276180.49554 +696 689 -29652762.65002 +697 689 -14833151.86804 +698 689 4679881.612865 +699 689 5555616.043855 +700 689 33332970.40197 +701 689 212606082.8355 +702 689 32847237.33971 +703 689 -18499818.53394 +704 689 -5320118.38549 +786 689 24110420.45533 +787 689 -17343704.63996 +788 689 -81284258.80916 +789 689 65400015.11214 +790 689 8333242.604601 +791 689 -113457062.6479 +792 689 8485420.4502 +793 689 9010462.03536 +794 689 -2221758.783205 +795 689 -694452.0061623 +796 689 -67874818.52582 +797 689 -284706093.7789 +798 689 -2777808.023289 +799 689 33332970.40198 +800 689 -311771151.9111 +801 689 -694452.006166 +802 689 34541848.12385 +803 689 21543906.17081 +807 689 -23415968.44916 +808 689 -16510371.30635 +809 689 -73680036.58444 +810 689 -62622207.08884 +811 689 8333242.6046 +812 689 -93040173.76232 +813 689 -7790968.444033 +814 689 8177128.701754 +815 689 382463.4398733 +690 690 847901916.7151 +691 690 33380770.36212 +692 690 -37498286.23383 +693 690 39751697.94156 +694 690 -33352308.14156 +695 690 -32448557.35788 +699 690 -43106498.79594 +700 690 -33333333.32786 +701 690 -30069429.31642 +702 690 -59718971.98211 +703 690 -9.387731552124e-07 +704 690 5555616.043855 +705 690 -46856498.79532 +706 690 33333333.32786 +707 690 32430570.67332 +789 690 -41696960.65915 +790 690 8333333.336071 +791 690 24110420.45533 +792 690 -99681629.70551 +793 690 -8340448.891213 +794 690 71607514.53236 +798 690 -94333949.07787 +799 690 1.773238182068e-06 +800 690 -694452.0061627 +801 690 -8298175.66356 +802 690 8345192.594641 +803 690 -9379478.645899 +804 690 2423001.606932 +805 690 -8338077.0395 +806 690 7795396.873343 +810 690 -38845377.32488 +811 690 -8333333.33607 +812 690 -23415968.44916 +813 690 -69751628.43939 +814 690 1.266598701477e-06 +815 690 -62205540.42245 +816 690 -11071939.81576 +817 690 8333333.336071 +818 690 -7790968.444033 +691 691 757876104.862 +692 691 103333663.8687 +693 691 -33361795.54842 +694 691 -76952252.54226 +695 691 -55347988.6005 +699 691 -33333333.32786 +700 691 -33106002.77733 +701 691 -15166485.20115 +702 691 -8.344650268555e-07 +703 691 86948517.3239 +704 691 33332970.40197 +705 691 33333333.32786 +706 691 -36856002.77671 +707 691 -18166485.20082 +789 691 8333333.336071 +790 691 -39196836.65327 +791 691 -17343704.63996 +792 691 -8338077.039499 +793 691 -60499809.12032 +794 691 22021029.70742 +798 691 2.175569534302e-06 +799 691 -126000573.4156 +800 691 -67541485.19271 +801 691 8345192.594641 +802 691 -30804628.63791 +803 691 25829490.35962 +804 691 -8340448.891214 +805 691 -26752986.0284 +806 691 37056208.64825 +810 691 -8333333.33607 +811 691 -36345253.319 +812 691 -16510371.30635 +813 691 7.376074790955e-07 +814 691 -33084756.09483 +815 691 8333242.6046 +816 691 8333333.336071 +817 691 -8571815.80988 +818 691 8177128.701754 +692 692 1184141501.437 +693 692 -32874217.36655 +694 692 -64688121.35194 +695 692 93077437.24068 +699 692 -29652762.65002 +700 692 -14833151.86804 +701 692 4679881.612865 +702 692 5555616.043855 +703 692 33332970.40197 +704 692 212606082.8355 +705 692 32847237.33971 +706 692 -18499818.53394 +707 692 -5320118.38549 +789 692 24110420.45533 +790 692 -17343704.63996 +791 692 -81284258.80916 +792 692 72026355.46494 +793 692 24359692.24116 +794 692 -142891518.6627 +798 692 -694452.0061623 +799 692 -67874818.52582 +800 692 -284706093.7789 +801 692 -9370405.180087 +802 692 25836749.05321 +803 692 -291361037.6863 +804 692 7797611.087997 +805 692 35054390.19536 +806 692 3229564.966024 +810 692 -23415968.44916 +811 692 -16510371.30635 +812 692 -73680036.58444 +813 692 -62622207.08884 +814 692 8333242.6046 +815 692 -93040173.76232 +816 692 -7790968.444033 +817 692 8177128.701754 +818 692 382463.4398733 +693 693 544597009.4256 +694 693 33333333.32786 +695 693 -31989118.31313 +702 693 -43106498.79594 +703 693 -33333333.32786 +704 693 -30069429.31642 +705 693 -132114372.9571 +706 693 -33352308.14156 +707 693 31970539.06385 +708 693 1216456.507315 +709 693 26685641.47599 +710 693 25851320.01324 +792 693 -50448491.13742 +793 693 10007115.55843 +794 693 28536410.43085 +801 693 -85645347.16108 +802 693 -8340448.891212 +803 693 -24130997.54348 +804 693 -10929001.68405 +805 693 8333333.33607 +806 693 3726516.388097 +813 693 -38845377.32488 +814 693 -8333333.33607 +815 693 -23415968.44916 +816 693 -69036918.95254 +817 693 -8338077.039497 +818 693 -55624567.39871 +819 693 7014515.850343 +820 693 6671410.372285 +821 693 -6514983.987003 +694 694 494573181.6273 +695 694 83368386.85484 +702 694 -33333333.32786 +703 694 -33106002.77733 +704 694 -15166485.20115 +705 694 -33361795.54841 +706 694 24612909.30639 +707 694 46187594.51733 +708 694 40028462.21399 +709 694 1216456.507311 +710 694 -29021109.31684 +792 694 6671410.372285 +793 694 -50448491.13742 +794 694 -15218991.7376 +801 694 -8338077.039498 +802 694 -114821334.7964 +803 694 -67065236.07198 +804 694 8333333.336069 +805 694 -23434958.63979 +806 694 30221022.26397 +813 694 -8333333.33607 +814 694 -36345253.319 +815 694 -16510371.30635 +816 694 -8340448.891212 +817 694 -29855098.36736 +818 694 -1182917.166231 +819 694 10007115.55843 +820 694 7014515.850342 +821 694 7818288.469344 +695 695 853850595.3707 +702 695 -29652762.65002 +703 695 -14833151.86804 +704 695 4679881.612865 +705 695 31961249.43922 +706 695 37180558.07827 +707 695 139399647.4134 +708 695 38776980.01986 +709 695 -19347406.21122 +710 695 3243884.01951 +792 695 19024273.62057 +793 695 -22828487.60639 +794 695 -134529309.6998 +801 695 -24124138.5141 +802 695 -65063417.79147 +803 695 -231619365.082 +804 695 -21803668.18463 +805 695 9797097.079457 +806 695 -178746028.6722 +813 695 -23415968.44916 +814 695 -16510371.30635 +815 695 -73680036.58444 +816 695 -56043408.3313 +817 695 -3514321.011405 +818 695 -61172289.98812 +819 695 -9772475.980504 +820 695 5212192.312896 +821 695 18705375.60092 +696 696 829135740.1102 +697 696 1.847743988037e-06 +698 696 -11111232.08774 +699 696 86951912.01811 +700 696 -3.8743019104e-07 +701 696 -2777808.023304 +711 696 -59718971.98211 +712 696 -9.387731552124e-07 +713 696 5555616.043855 +714 696 -46856498.79532 +715 696 33333333.32786 +716 696 32430570.67332 +795 696 -77407961.77148 +796 696 -1.184642314911e-06 +797 696 64983348.44575 +798 696 -12048523.14942 +799 696 -8333333.336071 +800 696 8485420.4502 +807 696 -27191273.16515 +808 696 2.98023223877e-07 +809 696 -2777808.023288 +810 696 20509800.90325 +811 696 -2.242624759674e-06 +812 696 -694452.0061662 +822 696 -69751628.43939 +823 696 1.266598701477e-06 +824 696 -62205540.42245 +825 696 -11071939.81576 +826 696 8333333.336071 +827 696 -7790968.444033 +697 697 749131772.0008 +698 697 133331881.5422 +699 697 -1.639127731323e-07 +700 697 -39714585.27039 +701 697 -66665940.77111 +711 697 -8.344650268555e-07 +712 697 86948517.3239 +713 697 33332970.40197 +714 697 33333333.32786 +715 697 -36856002.77671 +716 697 -18166485.20082 +795 697 -1.601874828339e-06 +796 697 -40741089.4269 +797 697 8333242.604601 +798 697 -8333333.336071 +799 697 -9548399.143536 +800 697 9010462.03536 +807 697 2.384185791016e-07 +808 697 -47192265.20236 +809 697 33332970.40198 +810 697 -1.728534698486e-06 +811 697 -11156823.43448 +812 697 34208514.79074 +822 697 7.376074790955e-07 +823 697 -33084756.09483 +824 697 8333242.6046 +825 697 8333333.336071 +826 697 -8571815.80988 +827 697 8177128.701754 +698 698 1253984280.216 +699 698 -2777808.023304 +700 698 -66665940.77111 +701 698 99276180.49554 +711 698 5555616.043855 +712 698 33332970.40197 +713 698 212606082.8355 +714 698 32847237.33971 +715 698 -18499818.53394 +716 698 -5320118.38549 +795 698 65400015.11214 +796 698 8333242.604601 +797 698 -113457062.6479 +798 698 8485420.4502 +799 698 9010462.03536 +800 698 -2221758.783205 +807 698 -2777808.023289 +808 698 33332970.40198 +809 698 -311771151.9111 +810 698 -694452.006166 +811 698 34541848.12385 +812 698 21543906.17081 +822 698 -62622207.08884 +823 698 8333242.6046 +824 698 -93040173.76232 +825 698 -7790968.444033 +826 698 8177128.701754 +827 698 382463.4398733 +699 699 829135740.1102 +700 699 1.847743988037e-06 +701 699 -11111232.08774 +702 699 86951912.01811 +703 699 -3.8743019104e-07 +704 699 -2777808.023304 +711 699 -43106498.79594 +712 699 -33333333.32786 +713 699 -30069429.31642 +714 699 -59718971.98211 +715 699 -9.387731552124e-07 +716 699 5555616.043855 +717 699 -46856498.79532 +718 699 33333333.32786 +719 699 32430570.67332 +795 699 -41696960.65915 +796 699 8333333.336071 +797 699 24110420.45533 +798 699 -77407961.77148 +799 699 -1.184642314911e-06 +800 699 64983348.44575 +801 699 -12048523.14942 +802 699 -8333333.336071 +803 699 8485420.4502 +807 699 -94333949.07787 +808 699 1.773238182068e-06 +809 699 -694452.0061627 +810 699 -27191273.16515 +811 699 2.98023223877e-07 +812 699 -2777808.023288 +813 699 20509800.90325 +814 699 -2.242624759674e-06 +815 699 -694452.0061662 +822 699 -38845377.32488 +823 699 -8333333.33607 +824 699 -23415968.44916 +825 699 -69751628.43939 +826 699 1.266598701477e-06 +827 699 -62205540.42245 +828 699 -11071939.81576 +829 699 8333333.336071 +830 699 -7790968.444033 +700 700 749131772.0008 +701 700 133331881.5422 +702 700 -1.639127731323e-07 +703 700 -39714585.27039 +704 700 -66665940.77111 +711 700 -33333333.32786 +712 700 -33106002.77733 +713 700 -15166485.20115 +714 700 -8.344650268555e-07 +715 700 86948517.3239 +716 700 33332970.40197 +717 700 33333333.32786 +718 700 -36856002.77671 +719 700 -18166485.20082 +795 700 8333333.336071 +796 700 -39196836.65327 +797 700 -17343704.63996 +798 700 -1.601874828339e-06 +799 700 -40741089.4269 +800 700 8333242.604601 +801 700 -8333333.336071 +802 700 -9548399.143536 +803 700 9010462.03536 +807 700 2.175569534302e-06 +808 700 -126000573.4156 +809 700 -67541485.19271 +810 700 2.384185791016e-07 +811 700 -47192265.20236 +812 700 33332970.40198 +813 700 -1.728534698486e-06 +814 700 -11156823.43448 +815 700 34208514.79074 +822 700 -8333333.33607 +823 700 -36345253.319 +824 700 -16510371.30635 +825 700 7.376074790955e-07 +826 700 -33084756.09483 +827 700 8333242.6046 +828 700 8333333.336071 +829 700 -8571815.80988 +830 700 8177128.701754 +701 701 1253984280.216 +702 701 -2777808.023304 +703 701 -66665940.77111 +704 701 99276180.49554 +711 701 -29652762.65002 +712 701 -14833151.86804 +713 701 4679881.612865 +714 701 5555616.043855 +715 701 33332970.40197 +716 701 212606082.8355 +717 701 32847237.33971 +718 701 -18499818.53394 +719 701 -5320118.38549 +795 701 24110420.45533 +796 701 -17343704.63996 +797 701 -81284258.80916 +798 701 65400015.11214 +799 701 8333242.604601 +800 701 -113457062.6479 +801 701 8485420.4502 +802 701 9010462.03536 +803 701 -2221758.783205 +807 701 -694452.0061623 +808 701 -67874818.52582 +809 701 -284706093.7789 +810 701 -2777808.023289 +811 701 33332970.40198 +812 701 -311771151.9111 +813 701 -694452.006166 +814 701 34541848.12385 +815 701 21543906.17081 +822 701 -23415968.44916 +823 701 -16510371.30635 +824 701 -73680036.58444 +825 701 -62622207.08884 +826 701 8333242.6046 +827 701 -93040173.76232 +828 701 -7790968.444033 +829 701 8177128.701754 +830 701 382463.4398733 +702 702 829135740.1102 +703 702 1.847743988037e-06 +704 702 -11111232.08774 +705 702 86951912.01811 +706 702 -3.8743019104e-07 +707 702 -2777808.023304 +714 702 -43106498.79594 +715 702 -33333333.32786 +716 702 -30069429.31642 +717 702 -59718971.98211 +718 702 -9.387731552124e-07 +719 702 5555616.043855 +720 702 -46856498.79532 +721 702 33333333.32786 +722 702 32430570.67332 +798 702 -41696960.65915 +799 702 8333333.336071 +800 702 24110420.45533 +801 702 -77407961.77148 +802 702 -1.184642314911e-06 +803 702 64983348.44575 +804 702 -12048523.14942 +805 702 -8333333.336071 +806 702 8485420.4502 +810 702 -94333949.07787 +811 702 1.773238182068e-06 +812 702 -694452.0061627 +813 702 -27191273.16515 +814 702 2.98023223877e-07 +815 702 -2777808.023288 +816 702 20509800.90325 +817 702 -2.242624759674e-06 +818 702 -694452.0061662 +825 702 -38845377.32488 +826 702 -8333333.33607 +827 702 -23415968.44916 +828 702 -69751628.43939 +829 702 1.266598701477e-06 +830 702 -62205540.42245 +831 702 -11071939.81576 +832 702 8333333.336071 +833 702 -7790968.444033 +703 703 749131772.0008 +704 703 133331881.5422 +705 703 -1.639127731323e-07 +706 703 -39714585.27039 +707 703 -66665940.77111 +714 703 -33333333.32786 +715 703 -33106002.77733 +716 703 -15166485.20115 +717 703 -8.344650268555e-07 +718 703 86948517.3239 +719 703 33332970.40197 +720 703 33333333.32786 +721 703 -36856002.77671 +722 703 -18166485.20082 +798 703 8333333.336071 +799 703 -39196836.65327 +800 703 -17343704.63996 +801 703 -1.601874828339e-06 +802 703 -40741089.4269 +803 703 8333242.604601 +804 703 -8333333.336071 +805 703 -9548399.143536 +806 703 9010462.03536 +810 703 2.175569534302e-06 +811 703 -126000573.4156 +812 703 -67541485.19271 +813 703 2.384185791016e-07 +814 703 -47192265.20236 +815 703 33332970.40198 +816 703 -1.728534698486e-06 +817 703 -11156823.43448 +818 703 34208514.79074 +825 703 -8333333.33607 +826 703 -36345253.319 +827 703 -16510371.30635 +828 703 7.376074790955e-07 +829 703 -33084756.09483 +830 703 8333242.6046 +831 703 8333333.336071 +832 703 -8571815.80988 +833 703 8177128.701754 +704 704 1253984280.216 +705 704 -2777808.023304 +706 704 -66665940.77111 +707 704 99276180.49554 +714 704 -29652762.65002 +715 704 -14833151.86804 +716 704 4679881.612865 +717 704 5555616.043855 +718 704 33332970.40197 +719 704 212606082.8355 +720 704 32847237.33971 +721 704 -18499818.53394 +722 704 -5320118.38549 +798 704 24110420.45533 +799 704 -17343704.63996 +800 704 -81284258.80916 +801 704 65400015.11214 +802 704 8333242.604601 +803 704 -113457062.6479 +804 704 8485420.4502 +805 704 9010462.03536 +806 704 -2221758.783205 +810 704 -694452.0061623 +811 704 -67874818.52582 +812 704 -284706093.7789 +813 704 -2777808.023289 +814 704 33332970.40198 +815 704 -311771151.9111 +816 704 -694452.006166 +817 704 34541848.12385 +818 704 21543906.17081 +825 704 -23415968.44916 +826 704 -16510371.30635 +827 704 -73680036.58444 +828 704 -62622207.08884 +829 704 8333242.6046 +830 704 -93040173.76232 +831 704 -7790968.444033 +832 704 8177128.701754 +833 704 382463.4398733 +705 705 847901916.7151 +706 705 33380770.36212 +707 705 -37498286.23383 +708 705 39751697.94156 +709 705 -33352308.14156 +710 705 -32448557.35788 +717 705 -43106498.79594 +718 705 -33333333.32786 +719 705 -30069429.31642 +720 705 -59718971.98211 +721 705 -9.387731552124e-07 +722 705 5555616.043855 +723 705 -46856498.79532 +724 705 33333333.32786 +725 705 32430570.67332 +801 705 -41696960.65915 +802 705 8333333.336071 +803 705 24110420.45533 +804 705 -99681629.70551 +805 705 -8340448.891213 +806 705 71607514.53236 +813 705 -94333949.07787 +814 705 1.773238182068e-06 +815 705 -694452.0061627 +816 705 -8298175.66356 +817 705 8345192.594641 +818 705 -9379478.645899 +819 705 2423001.606932 +820 705 -8338077.0395 +821 705 7795396.873343 +828 705 -38845377.32488 +829 705 -8333333.33607 +830 705 -23415968.44916 +831 705 -69751628.43939 +832 705 1.266598701477e-06 +833 705 -62205540.42245 +834 705 -11071939.81576 +835 705 8333333.336071 +836 705 -7790968.444033 +706 706 757876104.862 +707 706 103333663.8687 +708 706 -33361795.54842 +709 706 -76952252.54226 +710 706 -55347988.6005 +717 706 -33333333.32786 +718 706 -33106002.77733 +719 706 -15166485.20115 +720 706 -8.344650268555e-07 +721 706 86948517.3239 +722 706 33332970.40197 +723 706 33333333.32786 +724 706 -36856002.77671 +725 706 -18166485.20082 +801 706 8333333.336071 +802 706 -39196836.65327 +803 706 -17343704.63996 +804 706 -8338077.039499 +805 706 -60499809.12032 +806 706 22021029.70742 +813 706 2.175569534302e-06 +814 706 -126000573.4156 +815 706 -67541485.19271 +816 706 8345192.594641 +817 706 -30804628.63791 +818 706 25829490.35962 +819 706 -8340448.891214 +820 706 -26752986.0284 +821 706 37056208.64825 +828 706 -8333333.33607 +829 706 -36345253.319 +830 706 -16510371.30635 +831 706 7.376074790955e-07 +832 706 -33084756.09483 +833 706 8333242.6046 +834 706 8333333.336071 +835 706 -8571815.80988 +836 706 8177128.701754 +707 707 1184141501.437 +708 707 -32874217.36655 +709 707 -64688121.35194 +710 707 93077437.24068 +717 707 -29652762.65002 +718 707 -14833151.86804 +719 707 4679881.612865 +720 707 5555616.043855 +721 707 33332970.40197 +722 707 212606082.8355 +723 707 32847237.33971 +724 707 -18499818.53394 +725 707 -5320118.38549 +801 707 24110420.45533 +802 707 -17343704.63996 +803 707 -81284258.80916 +804 707 72026355.46494 +805 707 24359692.24116 +806 707 -142891518.6627 +813 707 -694452.0061623 +814 707 -67874818.52582 +815 707 -284706093.7789 +816 707 -9370405.180087 +817 707 25836749.05321 +818 707 -291361037.6863 +819 707 7797611.087997 +820 707 35054390.19536 +821 707 3229564.966024 +828 707 -23415968.44916 +829 707 -16510371.30635 +830 707 -73680036.58444 +831 707 -62622207.08884 +832 707 8333242.6046 +833 707 -93040173.76232 +834 707 -7790968.444033 +835 707 8177128.701754 +836 707 382463.4398733 +708 708 544597009.4256 +709 708 33333333.32786 +710 708 -31989118.31313 +720 708 -43106498.79594 +721 708 -33333333.32786 +722 708 -30069429.31642 +723 708 -132114372.9571 +724 708 -33352308.14156 +725 708 31970539.06385 +726 708 1216456.507315 +727 708 26685641.47599 +728 708 25851320.01324 +804 708 -50448491.13742 +805 708 10007115.55843 +806 708 28536410.43085 +816 708 -85645347.16108 +817 708 -8340448.891212 +818 708 -24130997.54348 +819 708 -10929001.68405 +820 708 8333333.33607 +821 708 3726516.388097 +831 708 -38845377.32488 +832 708 -8333333.33607 +833 708 -23415968.44916 +834 708 -69036918.95254 +835 708 -8338077.039497 +836 708 -55624567.39871 +837 708 7014515.850343 +838 708 6671410.372285 +839 708 -6514983.987003 +709 709 494573181.6273 +710 709 83368386.85484 +720 709 -33333333.32786 +721 709 -33106002.77733 +722 709 -15166485.20115 +723 709 -33361795.54841 +724 709 24612909.30639 +725 709 46187594.51733 +726 709 40028462.21399 +727 709 1216456.507311 +728 709 -29021109.31684 +804 709 6671410.372285 +805 709 -50448491.13742 +806 709 -15218991.7376 +816 709 -8338077.039498 +817 709 -114821334.7964 +818 709 -67065236.07198 +819 709 8333333.336069 +820 709 -23434958.63979 +821 709 30221022.26397 +831 709 -8333333.33607 +832 709 -36345253.319 +833 709 -16510371.30635 +834 709 -8340448.891212 +835 709 -29855098.36736 +836 709 -1182917.166231 +837 709 10007115.55843 +838 709 7014515.850342 +839 709 7818288.469344 +710 710 853850595.3707 +720 710 -29652762.65002 +721 710 -14833151.86804 +722 710 4679881.612865 +723 710 31961249.43922 +724 710 37180558.07827 +725 710 139399647.4134 +726 710 38776980.01986 +727 710 -19347406.21122 +728 710 3243884.01951 +804 710 19024273.62057 +805 710 -22828487.60639 +806 710 -134529309.6998 +816 710 -24124138.5141 +817 710 -65063417.79147 +818 710 -231619365.082 +819 710 -21803668.18463 +820 710 9797097.079457 +821 710 -178746028.6722 +831 710 -23415968.44916 +832 710 -16510371.30635 +833 710 -73680036.58444 +834 710 -56043408.3313 +835 710 -3514321.011405 +836 710 -61172289.98812 +837 710 -9772475.980504 +838 710 5212192.312896 +839 710 18705375.60092 +711 711 829135740.1102 +712 711 1.847743988037e-06 +713 711 -11111232.08774 +714 711 86951912.01811 +715 711 -3.8743019104e-07 +716 711 -2777808.023304 +729 711 -59718971.98211 +730 711 -9.387731552124e-07 +731 711 5555616.043855 +732 711 -46856498.79532 +733 711 33333333.32786 +734 711 32430570.67332 +807 711 -77407961.77148 +808 711 -1.184642314911e-06 +809 711 64983348.44575 +810 711 -12048523.14942 +811 711 -8333333.336071 +812 711 8485420.4502 +822 711 -27191273.16515 +823 711 2.98023223877e-07 +824 711 -2777808.023288 +825 711 20509800.90325 +826 711 -2.242624759674e-06 +827 711 -694452.0061662 +840 711 -69751628.43939 +841 711 1.266598701477e-06 +842 711 -62205540.42245 +843 711 -11071939.81576 +844 711 8333333.336071 +845 711 -7790968.444033 +712 712 749131772.0008 +713 712 133331881.5422 +714 712 -1.639127731323e-07 +715 712 -39714585.27039 +716 712 -66665940.77111 +729 712 -8.344650268555e-07 +730 712 86948517.3239 +731 712 33332970.40197 +732 712 33333333.32786 +733 712 -36856002.77671 +734 712 -18166485.20082 +807 712 -1.601874828339e-06 +808 712 -40741089.4269 +809 712 8333242.604601 +810 712 -8333333.336071 +811 712 -9548399.143536 +812 712 9010462.03536 +822 712 2.384185791016e-07 +823 712 -47192265.20236 +824 712 33332970.40198 +825 712 -1.728534698486e-06 +826 712 -11156823.43448 +827 712 34208514.79074 +840 712 7.376074790955e-07 +841 712 -33084756.09483 +842 712 8333242.6046 +843 712 8333333.336071 +844 712 -8571815.80988 +845 712 8177128.701754 +713 713 1253984280.216 +714 713 -2777808.023304 +715 713 -66665940.77111 +716 713 99276180.49554 +729 713 5555616.043855 +730 713 33332970.40197 +731 713 212606082.8355 +732 713 32847237.33971 +733 713 -18499818.53394 +734 713 -5320118.38549 +807 713 65400015.11214 +808 713 8333242.604601 +809 713 -113457062.6479 +810 713 8485420.4502 +811 713 9010462.03536 +812 713 -2221758.783205 +822 713 -2777808.023289 +823 713 33332970.40198 +824 713 -311771151.9111 +825 713 -694452.006166 +826 713 34541848.12385 +827 713 21543906.17081 +840 713 -62622207.08884 +841 713 8333242.6046 +842 713 -93040173.76232 +843 713 -7790968.444033 +844 713 8177128.701754 +845 713 382463.4398733 +714 714 829135740.1102 +715 714 1.847743988037e-06 +716 714 -11111232.08774 +717 714 86951912.01811 +718 714 -3.8743019104e-07 +719 714 -2777808.023304 +729 714 -43106498.79594 +730 714 -33333333.32786 +731 714 -30069429.31642 +732 714 -59718971.98211 +733 714 -9.387731552124e-07 +734 714 5555616.043855 +735 714 -46856498.79532 +736 714 33333333.32786 +737 714 32430570.67332 +807 714 -41696960.65915 +808 714 8333333.336071 +809 714 24110420.45533 +810 714 -77407961.77148 +811 714 -1.184642314911e-06 +812 714 64983348.44575 +813 714 -12048523.14942 +814 714 -8333333.336071 +815 714 8485420.4502 +822 714 -94333949.07787 +823 714 1.773238182068e-06 +824 714 -694452.0061627 +825 714 -27191273.16515 +826 714 2.98023223877e-07 +827 714 -2777808.023288 +828 714 20509800.90325 +829 714 -2.242624759674e-06 +830 714 -694452.0061662 +840 714 -38845377.32488 +841 714 -8333333.33607 +842 714 -23415968.44916 +843 714 -69751628.43939 +844 714 1.266598701477e-06 +845 714 -62205540.42245 +846 714 -11071939.81576 +847 714 8333333.336071 +848 714 -7790968.444033 +715 715 749131772.0008 +716 715 133331881.5422 +717 715 -1.639127731323e-07 +718 715 -39714585.27039 +719 715 -66665940.77111 +729 715 -33333333.32786 +730 715 -33106002.77733 +731 715 -15166485.20115 +732 715 -8.344650268555e-07 +733 715 86948517.3239 +734 715 33332970.40197 +735 715 33333333.32786 +736 715 -36856002.77671 +737 715 -18166485.20082 +807 715 8333333.336071 +808 715 -39196836.65327 +809 715 -17343704.63996 +810 715 -1.601874828339e-06 +811 715 -40741089.4269 +812 715 8333242.604601 +813 715 -8333333.336071 +814 715 -9548399.143536 +815 715 9010462.03536 +822 715 2.175569534302e-06 +823 715 -126000573.4156 +824 715 -67541485.19271 +825 715 2.384185791016e-07 +826 715 -47192265.20236 +827 715 33332970.40198 +828 715 -1.728534698486e-06 +829 715 -11156823.43448 +830 715 34208514.79074 +840 715 -8333333.33607 +841 715 -36345253.319 +842 715 -16510371.30635 +843 715 7.376074790955e-07 +844 715 -33084756.09483 +845 715 8333242.6046 +846 715 8333333.336071 +847 715 -8571815.80988 +848 715 8177128.701754 +716 716 1253984280.216 +717 716 -2777808.023304 +718 716 -66665940.77111 +719 716 99276180.49554 +729 716 -29652762.65002 +730 716 -14833151.86804 +731 716 4679881.612865 +732 716 5555616.043855 +733 716 33332970.40197 +734 716 212606082.8355 +735 716 32847237.33971 +736 716 -18499818.53394 +737 716 -5320118.38549 +807 716 24110420.45533 +808 716 -17343704.63996 +809 716 -81284258.80916 +810 716 65400015.11214 +811 716 8333242.604601 +812 716 -113457062.6479 +813 716 8485420.4502 +814 716 9010462.03536 +815 716 -2221758.783205 +822 716 -694452.0061623 +823 716 -67874818.52582 +824 716 -284706093.7789 +825 716 -2777808.023289 +826 716 33332970.40198 +827 716 -311771151.9111 +828 716 -694452.006166 +829 716 34541848.12385 +830 716 21543906.17081 +840 716 -23415968.44916 +841 716 -16510371.30635 +842 716 -73680036.58444 +843 716 -62622207.08884 +844 716 8333242.6046 +845 716 -93040173.76232 +846 716 -7790968.444033 +847 716 8177128.701754 +848 716 382463.4398733 +717 717 829135740.1102 +718 717 1.847743988037e-06 +719 717 -11111232.08774 +720 717 86951912.01811 +721 717 -3.8743019104e-07 +722 717 -2777808.023304 +732 717 -43106498.79594 +733 717 -33333333.32786 +734 717 -30069429.31642 +735 717 -59718971.98211 +736 717 -9.387731552124e-07 +737 717 5555616.043855 +738 717 -46856498.79532 +739 717 33333333.32786 +740 717 32430570.67332 +810 717 -41696960.65915 +811 717 8333333.336071 +812 717 24110420.45533 +813 717 -77407961.77148 +814 717 -1.184642314911e-06 +815 717 64983348.44575 +816 717 -12048523.14942 +817 717 -8333333.336071 +818 717 8485420.4502 +825 717 -94333949.07787 +826 717 1.773238182068e-06 +827 717 -694452.0061627 +828 717 -27191273.16515 +829 717 2.98023223877e-07 +830 717 -2777808.023288 +831 717 20509800.90325 +832 717 -2.242624759674e-06 +833 717 -694452.0061662 +843 717 -38845377.32488 +844 717 -8333333.33607 +845 717 -23415968.44916 +846 717 -69751628.43939 +847 717 1.266598701477e-06 +848 717 -62205540.42245 +849 717 -11071939.81576 +850 717 8333333.336071 +851 717 -7790968.444033 +718 718 749131772.0008 +719 718 133331881.5422 +720 718 -1.639127731323e-07 +721 718 -39714585.27039 +722 718 -66665940.77111 +732 718 -33333333.32786 +733 718 -33106002.77733 +734 718 -15166485.20115 +735 718 -8.344650268555e-07 +736 718 86948517.3239 +737 718 33332970.40197 +738 718 33333333.32786 +739 718 -36856002.77671 +740 718 -18166485.20082 +810 718 8333333.336071 +811 718 -39196836.65327 +812 718 -17343704.63996 +813 718 -1.601874828339e-06 +814 718 -40741089.4269 +815 718 8333242.604601 +816 718 -8333333.336071 +817 718 -9548399.143536 +818 718 9010462.03536 +825 718 2.175569534302e-06 +826 718 -126000573.4156 +827 718 -67541485.19271 +828 718 2.384185791016e-07 +829 718 -47192265.20236 +830 718 33332970.40198 +831 718 -1.728534698486e-06 +832 718 -11156823.43448 +833 718 34208514.79074 +843 718 -8333333.33607 +844 718 -36345253.319 +845 718 -16510371.30635 +846 718 7.376074790955e-07 +847 718 -33084756.09483 +848 718 8333242.6046 +849 718 8333333.336071 +850 718 -8571815.80988 +851 718 8177128.701754 +719 719 1253984280.216 +720 719 -2777808.023304 +721 719 -66665940.77111 +722 719 99276180.49554 +732 719 -29652762.65002 +733 719 -14833151.86804 +734 719 4679881.612865 +735 719 5555616.043855 +736 719 33332970.40197 +737 719 212606082.8355 +738 719 32847237.33971 +739 719 -18499818.53394 +740 719 -5320118.38549 +810 719 24110420.45533 +811 719 -17343704.63996 +812 719 -81284258.80916 +813 719 65400015.11214 +814 719 8333242.604601 +815 719 -113457062.6479 +816 719 8485420.4502 +817 719 9010462.03536 +818 719 -2221758.783205 +825 719 -694452.0061623 +826 719 -67874818.52582 +827 719 -284706093.7789 +828 719 -2777808.023289 +829 719 33332970.40198 +830 719 -311771151.9111 +831 719 -694452.006166 +832 719 34541848.12385 +833 719 21543906.17081 +843 719 -23415968.44916 +844 719 -16510371.30635 +845 719 -73680036.58444 +846 719 -62622207.08884 +847 719 8333242.6046 +848 719 -93040173.76232 +849 719 -7790968.444033 +850 719 8177128.701754 +851 719 382463.4398733 +720 720 829135740.1102 +721 720 1.847743988037e-06 +722 720 -11111232.08774 +723 720 86951912.01811 +724 720 -3.8743019104e-07 +725 720 -2777808.023304 +735 720 -43106498.79594 +736 720 -33333333.32786 +737 720 -30069429.31642 +738 720 -59718971.98211 +739 720 -9.387731552124e-07 +740 720 5555616.043855 +741 720 -46856498.79532 +742 720 33333333.32786 +743 720 32430570.67332 +813 720 -41696960.65915 +814 720 8333333.336071 +815 720 24110420.45533 +816 720 -77407961.77148 +817 720 -1.184642314911e-06 +818 720 64983348.44575 +819 720 -12048523.14942 +820 720 -8333333.336071 +821 720 8485420.4502 +828 720 -94333949.07787 +829 720 1.773238182068e-06 +830 720 -694452.0061627 +831 720 -27191273.16515 +832 720 2.98023223877e-07 +833 720 -2777808.023288 +834 720 20509800.90325 +835 720 -2.242624759674e-06 +836 720 -694452.0061662 +846 720 -38845377.32488 +847 720 -8333333.33607 +848 720 -23415968.44916 +849 720 -69751628.43939 +850 720 1.266598701477e-06 +851 720 -62205540.42245 +852 720 -11071939.81576 +853 720 8333333.336071 +854 720 -7790968.444033 +721 721 749131772.0008 +722 721 133331881.5422 +723 721 -1.639127731323e-07 +724 721 -39714585.27039 +725 721 -66665940.77111 +735 721 -33333333.32786 +736 721 -33106002.77733 +737 721 -15166485.20115 +738 721 -8.344650268555e-07 +739 721 86948517.3239 +740 721 33332970.40197 +741 721 33333333.32786 +742 721 -36856002.77671 +743 721 -18166485.20082 +813 721 8333333.336071 +814 721 -39196836.65327 +815 721 -17343704.63996 +816 721 -1.601874828339e-06 +817 721 -40741089.4269 +818 721 8333242.604601 +819 721 -8333333.336071 +820 721 -9548399.143536 +821 721 9010462.03536 +828 721 2.175569534302e-06 +829 721 -126000573.4156 +830 721 -67541485.19271 +831 721 2.384185791016e-07 +832 721 -47192265.20236 +833 721 33332970.40198 +834 721 -1.728534698486e-06 +835 721 -11156823.43448 +836 721 34208514.79074 +846 721 -8333333.33607 +847 721 -36345253.319 +848 721 -16510371.30635 +849 721 7.376074790955e-07 +850 721 -33084756.09483 +851 721 8333242.6046 +852 721 8333333.336071 +853 721 -8571815.80988 +854 721 8177128.701754 +722 722 1253984280.216 +723 722 -2777808.023304 +724 722 -66665940.77111 +725 722 99276180.49554 +735 722 -29652762.65002 +736 722 -14833151.86804 +737 722 4679881.612865 +738 722 5555616.043855 +739 722 33332970.40197 +740 722 212606082.8355 +741 722 32847237.33971 +742 722 -18499818.53394 +743 722 -5320118.38549 +813 722 24110420.45533 +814 722 -17343704.63996 +815 722 -81284258.80916 +816 722 65400015.11214 +817 722 8333242.604601 +818 722 -113457062.6479 +819 722 8485420.4502 +820 722 9010462.03536 +821 722 -2221758.783205 +828 722 -694452.0061623 +829 722 -67874818.52582 +830 722 -284706093.7789 +831 722 -2777808.023289 +832 722 33332970.40198 +833 722 -311771151.9111 +834 722 -694452.006166 +835 722 34541848.12385 +836 722 21543906.17081 +846 722 -23415968.44916 +847 722 -16510371.30635 +848 722 -73680036.58444 +849 722 -62622207.08884 +850 722 8333242.6046 +851 722 -93040173.76232 +852 722 -7790968.444033 +853 722 8177128.701754 +854 722 382463.4398733 +723 723 847901916.7151 +724 723 33380770.36212 +725 723 -37498286.23383 +726 723 39751697.94156 +727 723 -33352308.14156 +728 723 -32448557.35788 +738 723 -43106498.79594 +739 723 -33333333.32786 +740 723 -30069429.31642 +741 723 -59718971.98211 +742 723 -9.387731552124e-07 +743 723 5555616.043855 +744 723 -46856498.79532 +745 723 33333333.32786 +746 723 32430570.67332 +816 723 -41696960.65915 +817 723 8333333.336071 +818 723 24110420.45533 +819 723 -99681629.70551 +820 723 -8340448.891213 +821 723 71607514.53236 +831 723 -94333949.07787 +832 723 1.773238182068e-06 +833 723 -694452.0061627 +834 723 -8298175.66356 +835 723 8345192.594641 +836 723 -9379478.645899 +837 723 2423001.606932 +838 723 -8338077.0395 +839 723 7795396.873343 +849 723 -38845377.32488 +850 723 -8333333.33607 +851 723 -23415968.44916 +852 723 -69751628.43939 +853 723 1.266598701477e-06 +854 723 -62205540.42245 +855 723 -11071939.81576 +856 723 8333333.336071 +857 723 -7790968.444033 +724 724 757876104.862 +725 724 103333663.8687 +726 724 -33361795.54842 +727 724 -76952252.54226 +728 724 -55347988.6005 +738 724 -33333333.32786 +739 724 -33106002.77733 +740 724 -15166485.20115 +741 724 -8.344650268555e-07 +742 724 86948517.3239 +743 724 33332970.40197 +744 724 33333333.32786 +745 724 -36856002.77671 +746 724 -18166485.20082 +816 724 8333333.336071 +817 724 -39196836.65327 +818 724 -17343704.63996 +819 724 -8338077.039499 +820 724 -60499809.12032 +821 724 22021029.70742 +831 724 2.175569534302e-06 +832 724 -126000573.4156 +833 724 -67541485.19271 +834 724 8345192.594641 +835 724 -30804628.63791 +836 724 25829490.35962 +837 724 -8340448.891214 +838 724 -26752986.0284 +839 724 37056208.64825 +849 724 -8333333.33607 +850 724 -36345253.319 +851 724 -16510371.30635 +852 724 7.376074790955e-07 +853 724 -33084756.09483 +854 724 8333242.6046 +855 724 8333333.336071 +856 724 -8571815.80988 +857 724 8177128.701754 +725 725 1184141501.437 +726 725 -32874217.36655 +727 725 -64688121.35194 +728 725 93077437.24068 +738 725 -29652762.65002 +739 725 -14833151.86804 +740 725 4679881.612865 +741 725 5555616.043855 +742 725 33332970.40197 +743 725 212606082.8355 +744 725 32847237.33971 +745 725 -18499818.53394 +746 725 -5320118.38549 +816 725 24110420.45533 +817 725 -17343704.63996 +818 725 -81284258.80916 +819 725 72026355.46494 +820 725 24359692.24116 +821 725 -142891518.6627 +831 725 -694452.0061623 +832 725 -67874818.52582 +833 725 -284706093.7789 +834 725 -9370405.180087 +835 725 25836749.05321 +836 725 -291361037.6863 +837 725 7797611.087997 +838 725 35054390.19536 +839 725 3229564.966024 +849 725 -23415968.44916 +850 725 -16510371.30635 +851 725 -73680036.58444 +852 725 -62622207.08884 +853 725 8333242.6046 +854 725 -93040173.76232 +855 725 -7790968.444033 +856 725 8177128.701754 +857 725 382463.4398733 +726 726 464940542.775 +727 726 12851905.75803 +728 726 20656400.75291 +741 726 -43106498.79594 +742 726 -33333333.32786 +743 726 -30069429.31642 +744 726 -91182430.47 +745 726 -12906779.84809 +746 726 1000330.122879 +747 726 5007090.268645 +748 726 26721540.75234 +749 726 5008750.65625 +819 726 -50448491.13742 +820 726 10007115.55843 +821 726 28536410.43085 +834 726 -85645347.16108 +835 726 -8340448.891212 +836 726 -24130997.54348 +837 726 -17836755.62729 +838 726 3212976.44109 +839 726 14418636.61301 +852 726 -38845377.32488 +853 726 -8333333.33607 +854 726 -23415968.44916 +855 726 -63830259.57109 +856 726 -3226694.96361 +857 726 -53519044.21609 +858 726 -9616209.125473 +859 726 6680385.191377 +860 726 -8036218.454271 +727 727 447751333.0549 +728 727 87198301.12591 +741 727 -33333333.32786 +742 727 -33106002.77733 +743 727 -15166485.20115 +744 727 -12934216.89311 +745 727 56438186.02174 +746 727 21414546.77539 +747 727 40082311.12852 +748 727 -18720862.03784 +749 727 -7408308.537561 +819 727 6671410.372285 +820 727 -50448491.13742 +821 727 -15218991.7376 +834 727 -8338077.039498 +835 727 -114821334.7964 +836 727 -67065236.07198 +837 727 3212976.44109 +838 727 -22134058.05942 +839 727 29194228.99637 +852 727 -8333333.33607 +853 727 -36345253.319 +854 727 -16510371.30635 +855 727 -3233554.224871 +856 727 -26925105.42998 +857 727 514296.7345483 +858 727 10020577.78707 +859 727 -15548197.20502 +860 727 16207412.72304 +728 728 727562919.3276 +741 728 -29652762.65002 +742 728 -14833151.86804 +743 728 4679881.612865 +744 728 11828695.56078 +745 728 21078811.80228 +746 728 138693973.3806 +747 728 7513125.984376 +748 728 -6071073.243682 +749 728 37080193.02289 +819 728 19024273.62057 +820 728 -22828487.60639 +821 728 -134529309.6998 +834 728 -24124138.5141 +835 728 -65063417.79147 +836 728 -231619365.082 +837 728 -7213954.829688 +838 728 11901763.34317 +839 728 -175634313.754 +852 728 -23415968.44916 +853 728 -16510371.30635 +854 728 -73680036.58444 +855 728 -51436656.57492 +856 728 190595.229853 +857 728 -74752245.15073 +858 728 -12054327.68141 +859 728 12991927.13824 +860 728 -19711236.25505 +729 729 829135740.1102 +730 729 1.847743988037e-06 +731 729 -11111232.08774 +732 729 86951912.01811 +733 729 -3.8743019104e-07 +734 729 -2777808.023304 +750 729 -59718971.98211 +751 729 -9.387731552124e-07 +752 729 5555616.043855 +753 729 -46856498.79532 +754 729 33333333.32786 +755 729 32430570.67332 +822 729 -77407961.77148 +823 729 -1.184642314911e-06 +824 729 64983348.44575 +825 729 -12048523.14942 +826 729 -8333333.336071 +827 729 8485420.4502 +840 729 -27191273.16515 +841 729 2.98023223877e-07 +842 729 -2777808.023288 +843 729 20509800.90325 +844 729 -2.242624759674e-06 +845 729 -694452.0061662 +861 729 -69751628.43939 +862 729 1.266598701477e-06 +863 729 -62205540.42245 +864 729 -11071939.81576 +865 729 8333333.336071 +866 729 -7790968.444033 +730 730 749131772.0008 +731 730 133331881.5422 +732 730 -1.639127731323e-07 +733 730 -39714585.27039 +734 730 -66665940.77111 +750 730 -8.344650268555e-07 +751 730 86948517.3239 +752 730 33332970.40197 +753 730 33333333.32786 +754 730 -36856002.77671 +755 730 -18166485.20082 +822 730 -1.601874828339e-06 +823 730 -40741089.4269 +824 730 8333242.604601 +825 730 -8333333.336071 +826 730 -9548399.143536 +827 730 9010462.03536 +840 730 2.384185791016e-07 +841 730 -47192265.20236 +842 730 33332970.40198 +843 730 -1.728534698486e-06 +844 730 -11156823.43448 +845 730 34208514.79074 +861 730 7.376074790955e-07 +862 730 -33084756.09483 +863 730 8333242.6046 +864 730 8333333.336071 +865 730 -8571815.80988 +866 730 8177128.701754 +731 731 1253984280.216 +732 731 -2777808.023304 +733 731 -66665940.77111 +734 731 99276180.49554 +750 731 5555616.043855 +751 731 33332970.40197 +752 731 212606082.8355 +753 731 32847237.33971 +754 731 -18499818.53394 +755 731 -5320118.38549 +822 731 65400015.11214 +823 731 8333242.604601 +824 731 -113457062.6479 +825 731 8485420.4502 +826 731 9010462.03536 +827 731 -2221758.783205 +840 731 -2777808.023289 +841 731 33332970.40198 +842 731 -311771151.9111 +843 731 -694452.006166 +844 731 34541848.12385 +845 731 21543906.17081 +861 731 -62622207.08884 +862 731 8333242.6046 +863 731 -93040173.76232 +864 731 -7790968.444033 +865 731 8177128.701754 +866 731 382463.4398733 +732 732 829135740.1102 +733 732 1.847743988037e-06 +734 732 -11111232.08774 +735 732 86951912.01811 +736 732 -3.8743019104e-07 +737 732 -2777808.023304 +750 732 -43106498.79594 +751 732 -33333333.32786 +752 732 -30069429.31642 +753 732 -59718971.98211 +754 732 -9.387731552124e-07 +755 732 5555616.043855 +756 732 -46856498.79532 +757 732 33333333.32786 +758 732 32430570.67332 +822 732 -41696960.65915 +823 732 8333333.336071 +824 732 24110420.45533 +825 732 -77407961.77148 +826 732 -1.184642314911e-06 +827 732 64983348.44575 +828 732 -12048523.14942 +829 732 -8333333.336071 +830 732 8485420.4502 +840 732 -94333949.07787 +841 732 1.773238182068e-06 +842 732 -694452.0061627 +843 732 -27191273.16515 +844 732 2.98023223877e-07 +845 732 -2777808.023288 +846 732 20509800.90325 +847 732 -2.242624759674e-06 +848 732 -694452.0061662 +861 732 -38845377.32488 +862 732 -8333333.33607 +863 732 -23415968.44916 +864 732 -69751628.43939 +865 732 1.266598701477e-06 +866 732 -62205540.42245 +867 732 -11071939.81576 +868 732 8333333.336071 +869 732 -7790968.444033 +733 733 749131772.0008 +734 733 133331881.5422 +735 733 -1.639127731323e-07 +736 733 -39714585.27039 +737 733 -66665940.77111 +750 733 -33333333.32786 +751 733 -33106002.77733 +752 733 -15166485.20115 +753 733 -8.344650268555e-07 +754 733 86948517.3239 +755 733 33332970.40197 +756 733 33333333.32786 +757 733 -36856002.77671 +758 733 -18166485.20082 +822 733 8333333.336071 +823 733 -39196836.65327 +824 733 -17343704.63996 +825 733 -1.601874828339e-06 +826 733 -40741089.4269 +827 733 8333242.604601 +828 733 -8333333.336071 +829 733 -9548399.143536 +830 733 9010462.03536 +840 733 2.175569534302e-06 +841 733 -126000573.4156 +842 733 -67541485.19271 +843 733 2.384185791016e-07 +844 733 -47192265.20236 +845 733 33332970.40198 +846 733 -1.728534698486e-06 +847 733 -11156823.43448 +848 733 34208514.79074 +861 733 -8333333.33607 +862 733 -36345253.319 +863 733 -16510371.30635 +864 733 7.376074790955e-07 +865 733 -33084756.09483 +866 733 8333242.6046 +867 733 8333333.336071 +868 733 -8571815.80988 +869 733 8177128.701754 +734 734 1253984280.216 +735 734 -2777808.023304 +736 734 -66665940.77111 +737 734 99276180.49554 +750 734 -29652762.65002 +751 734 -14833151.86804 +752 734 4679881.612865 +753 734 5555616.043855 +754 734 33332970.40197 +755 734 212606082.8355 +756 734 32847237.33971 +757 734 -18499818.53394 +758 734 -5320118.38549 +822 734 24110420.45533 +823 734 -17343704.63996 +824 734 -81284258.80916 +825 734 65400015.11214 +826 734 8333242.604601 +827 734 -113457062.6479 +828 734 8485420.4502 +829 734 9010462.03536 +830 734 -2221758.783205 +840 734 -694452.0061623 +841 734 -67874818.52582 +842 734 -284706093.7789 +843 734 -2777808.023289 +844 734 33332970.40198 +845 734 -311771151.9111 +846 734 -694452.006166 +847 734 34541848.12385 +848 734 21543906.17081 +861 734 -23415968.44916 +862 734 -16510371.30635 +863 734 -73680036.58444 +864 734 -62622207.08884 +865 734 8333242.6046 +866 734 -93040173.76232 +867 734 -7790968.444033 +868 734 8177128.701754 +869 734 382463.4398733 +735 735 829135740.1102 +736 735 1.847743988037e-06 +737 735 -11111232.08774 +738 735 86951912.01811 +739 735 -3.8743019104e-07 +740 735 -2777808.023304 +753 735 -43106498.79594 +754 735 -33333333.32786 +755 735 -30069429.31642 +756 735 -59718971.98211 +757 735 -9.387731552124e-07 +758 735 5555616.043855 +759 735 -46856498.79532 +760 735 33333333.32786 +761 735 32430570.67332 +825 735 -41696960.65915 +826 735 8333333.336071 +827 735 24110420.45533 +828 735 -77407961.77148 +829 735 -1.184642314911e-06 +830 735 64983348.44575 +831 735 -12048523.14942 +832 735 -8333333.336071 +833 735 8485420.4502 +843 735 -94333949.07787 +844 735 1.773238182068e-06 +845 735 -694452.0061627 +846 735 -27191273.16515 +847 735 2.98023223877e-07 +848 735 -2777808.023288 +849 735 20509800.90325 +850 735 -2.242624759674e-06 +851 735 -694452.0061662 +864 735 -38845377.32488 +865 735 -8333333.33607 +866 735 -23415968.44916 +867 735 -69751628.43939 +868 735 1.266598701477e-06 +869 735 -62205540.42245 +870 735 -11071939.81576 +871 735 8333333.336071 +872 735 -7790968.444033 +736 736 749131772.0008 +737 736 133331881.5422 +738 736 -1.639127731323e-07 +739 736 -39714585.27039 +740 736 -66665940.77111 +753 736 -33333333.32786 +754 736 -33106002.77733 +755 736 -15166485.20115 +756 736 -8.344650268555e-07 +757 736 86948517.3239 +758 736 33332970.40197 +759 736 33333333.32786 +760 736 -36856002.77671 +761 736 -18166485.20082 +825 736 8333333.336071 +826 736 -39196836.65327 +827 736 -17343704.63996 +828 736 -1.601874828339e-06 +829 736 -40741089.4269 +830 736 8333242.604601 +831 736 -8333333.336071 +832 736 -9548399.143536 +833 736 9010462.03536 +843 736 2.175569534302e-06 +844 736 -126000573.4156 +845 736 -67541485.19271 +846 736 2.384185791016e-07 +847 736 -47192265.20236 +848 736 33332970.40198 +849 736 -1.728534698486e-06 +850 736 -11156823.43448 +851 736 34208514.79074 +864 736 -8333333.33607 +865 736 -36345253.319 +866 736 -16510371.30635 +867 736 7.376074790955e-07 +868 736 -33084756.09483 +869 736 8333242.6046 +870 736 8333333.336071 +871 736 -8571815.80988 +872 736 8177128.701754 +737 737 1253984280.216 +738 737 -2777808.023304 +739 737 -66665940.77111 +740 737 99276180.49554 +753 737 -29652762.65002 +754 737 -14833151.86804 +755 737 4679881.612865 +756 737 5555616.043855 +757 737 33332970.40197 +758 737 212606082.8355 +759 737 32847237.33971 +760 737 -18499818.53394 +761 737 -5320118.38549 +825 737 24110420.45533 +826 737 -17343704.63996 +827 737 -81284258.80916 +828 737 65400015.11214 +829 737 8333242.604601 +830 737 -113457062.6479 +831 737 8485420.4502 +832 737 9010462.03536 +833 737 -2221758.783205 +843 737 -694452.0061623 +844 737 -67874818.52582 +845 737 -284706093.7789 +846 737 -2777808.023289 +847 737 33332970.40198 +848 737 -311771151.9111 +849 737 -694452.006166 +850 737 34541848.12385 +851 737 21543906.17081 +864 737 -23415968.44916 +865 737 -16510371.30635 +866 737 -73680036.58444 +867 737 -62622207.08884 +868 737 8333242.6046 +869 737 -93040173.76232 +870 737 -7790968.444033 +871 737 8177128.701754 +872 737 382463.4398733 +738 738 829135740.1102 +739 738 1.847743988037e-06 +740 738 -11111232.08774 +741 738 86951912.01811 +742 738 -3.8743019104e-07 +743 738 -2777808.023304 +756 738 -43106498.79594 +757 738 -33333333.32786 +758 738 -30069429.31642 +759 738 -59718971.98211 +760 738 -9.387731552124e-07 +761 738 5555616.043855 +762 738 -46856498.79532 +763 738 33333333.32786 +764 738 32430570.67332 +828 738 -41696960.65915 +829 738 8333333.336071 +830 738 24110420.45533 +831 738 -77407961.77148 +832 738 -1.184642314911e-06 +833 738 64983348.44575 +834 738 -12048523.14942 +835 738 -8333333.336071 +836 738 8485420.4502 +846 738 -94333949.07787 +847 738 1.773238182068e-06 +848 738 -694452.0061627 +849 738 -27191273.16515 +850 738 2.98023223877e-07 +851 738 -2777808.023288 +852 738 20509800.90325 +853 738 -2.242624759674e-06 +854 738 -694452.0061662 +867 738 -38845377.32488 +868 738 -8333333.33607 +869 738 -23415968.44916 +870 738 -69751628.43939 +871 738 1.266598701477e-06 +872 738 -62205540.42245 +873 738 -11071939.81576 +874 738 8333333.336071 +875 738 -7790968.444033 +739 739 749131772.0008 +740 739 133331881.5422 +741 739 -1.639127731323e-07 +742 739 -39714585.27039 +743 739 -66665940.77111 +756 739 -33333333.32786 +757 739 -33106002.77733 +758 739 -15166485.20115 +759 739 -8.344650268555e-07 +760 739 86948517.3239 +761 739 33332970.40197 +762 739 33333333.32786 +763 739 -36856002.77671 +764 739 -18166485.20082 +828 739 8333333.336071 +829 739 -39196836.65327 +830 739 -17343704.63996 +831 739 -1.601874828339e-06 +832 739 -40741089.4269 +833 739 8333242.604601 +834 739 -8333333.336071 +835 739 -9548399.143536 +836 739 9010462.03536 +846 739 2.175569534302e-06 +847 739 -126000573.4156 +848 739 -67541485.19271 +849 739 2.384185791016e-07 +850 739 -47192265.20236 +851 739 33332970.40198 +852 739 -1.728534698486e-06 +853 739 -11156823.43448 +854 739 34208514.79074 +867 739 -8333333.33607 +868 739 -36345253.319 +869 739 -16510371.30635 +870 739 7.376074790955e-07 +871 739 -33084756.09483 +872 739 8333242.6046 +873 739 8333333.336071 +874 739 -8571815.80988 +875 739 8177128.701754 +740 740 1253984280.216 +741 740 -2777808.023304 +742 740 -66665940.77111 +743 740 99276180.49554 +756 740 -29652762.65002 +757 740 -14833151.86804 +758 740 4679881.612865 +759 740 5555616.043855 +760 740 33332970.40197 +761 740 212606082.8355 +762 740 32847237.33971 +763 740 -18499818.53394 +764 740 -5320118.38549 +828 740 24110420.45533 +829 740 -17343704.63996 +830 740 -81284258.80916 +831 740 65400015.11214 +832 740 8333242.604601 +833 740 -113457062.6479 +834 740 8485420.4502 +835 740 9010462.03536 +836 740 -2221758.783205 +846 740 -694452.0061623 +847 740 -67874818.52582 +848 740 -284706093.7789 +849 740 -2777808.023289 +850 740 33332970.40198 +851 740 -311771151.9111 +852 740 -694452.006166 +853 740 34541848.12385 +854 740 21543906.17081 +867 740 -23415968.44916 +868 740 -16510371.30635 +869 740 -73680036.58444 +870 740 -62622207.08884 +871 740 8333242.6046 +872 740 -93040173.76232 +873 740 -7790968.444033 +874 740 8177128.701754 +875 740 382463.4398733 +741 741 829135740.1102 +742 741 1.847743988037e-06 +743 741 -11111232.08774 +744 741 86951912.01811 +745 741 -3.8743019104e-07 +746 741 -2777808.023304 +759 741 -43106498.79594 +760 741 -33333333.32786 +761 741 -30069429.31642 +762 741 -59718971.98211 +763 741 -9.387731552124e-07 +764 741 5555616.043855 +765 741 -46856498.79532 +766 741 33333333.32786 +767 741 32430570.67332 +831 741 -41696960.65915 +832 741 8333333.336071 +833 741 24110420.45533 +834 741 -77407961.77148 +835 741 -1.184642314911e-06 +836 741 64983348.44575 +837 741 -12048523.14942 +838 741 -8333333.336071 +839 741 8485420.4502 +849 741 -94333949.07787 +850 741 1.773238182068e-06 +851 741 -694452.0061627 +852 741 -27191273.16515 +853 741 2.98023223877e-07 +854 741 -2777808.023288 +855 741 20509800.90325 +856 741 -2.242624759674e-06 +857 741 -694452.0061662 +870 741 -38845377.32488 +871 741 -8333333.33607 +872 741 -23415968.44916 +873 741 -69751628.43939 +874 741 1.266598701477e-06 +875 741 -62205540.42245 +876 741 -11071939.81576 +877 741 8333333.336071 +878 741 -7790968.444033 +742 742 749131772.0008 +743 742 133331881.5422 +744 742 -1.639127731323e-07 +745 742 -39714585.27039 +746 742 -66665940.77111 +759 742 -33333333.32786 +760 742 -33106002.77733 +761 742 -15166485.20115 +762 742 -8.344650268555e-07 +763 742 86948517.3239 +764 742 33332970.40197 +765 742 33333333.32786 +766 742 -36856002.77671 +767 742 -18166485.20082 +831 742 8333333.336071 +832 742 -39196836.65327 +833 742 -17343704.63996 +834 742 -1.601874828339e-06 +835 742 -40741089.4269 +836 742 8333242.604601 +837 742 -8333333.336071 +838 742 -9548399.143536 +839 742 9010462.03536 +849 742 2.175569534302e-06 +850 742 -126000573.4156 +851 742 -67541485.19271 +852 742 2.384185791016e-07 +853 742 -47192265.20236 +854 742 33332970.40198 +855 742 -1.728534698486e-06 +856 742 -11156823.43448 +857 742 34208514.79074 +870 742 -8333333.33607 +871 742 -36345253.319 +872 742 -16510371.30635 +873 742 7.376074790955e-07 +874 742 -33084756.09483 +875 742 8333242.6046 +876 742 8333333.336071 +877 742 -8571815.80988 +878 742 8177128.701754 +743 743 1253984280.216 +744 743 -2777808.023304 +745 743 -66665940.77111 +746 743 99276180.49554 +759 743 -29652762.65002 +760 743 -14833151.86804 +761 743 4679881.612865 +762 743 5555616.043855 +763 743 33332970.40197 +764 743 212606082.8355 +765 743 32847237.33971 +766 743 -18499818.53394 +767 743 -5320118.38549 +831 743 24110420.45533 +832 743 -17343704.63996 +833 743 -81284258.80916 +834 743 65400015.11214 +835 743 8333242.604601 +836 743 -113457062.6479 +837 743 8485420.4502 +838 743 9010462.03536 +839 743 -2221758.783205 +849 743 -694452.0061623 +850 743 -67874818.52582 +851 743 -284706093.7789 +852 743 -2777808.023289 +853 743 33332970.40198 +854 743 -311771151.9111 +855 743 -694452.006166 +856 743 34541848.12385 +857 743 21543906.17081 +870 743 -23415968.44916 +871 743 -16510371.30635 +872 743 -73680036.58444 +873 743 -62622207.08884 +874 743 8333242.6046 +875 743 -93040173.76232 +876 743 -7790968.444033 +877 743 8177128.701754 +878 743 382463.4398733 +744 744 738198115.7453 +745 744 16764684.69662 +746 744 -11083193.77549 +747 744 17410783.23705 +748 744 -44082322.50369 +749 744 -5980744.701169 +762 744 -43106498.79594 +763 744 -33333333.32786 +764 744 -30069429.31642 +765 744 -49479493.54265 +766 744 9744969.140738 +767 744 462601.7693525 +768 744 -18806142.95809 +769 744 30506885.55944 +770 744 4773826.27592 +834 744 -41696960.65915 +835 744 8333333.336071 +836 744 24110420.45533 +837 744 -71415955.0593 +838 744 -3233554.224872 +839 744 56726300.63859 +852 744 -94333949.07787 +853 744 1.773238182068e-06 +854 744 -694452.0061627 +855 744 -13774447.66423 +856 744 4191171.176221 +857 744 -2780612.645988 +858 744 -30223428.17772 +859 744 -11020580.63135 +860 744 14420581.05462 +873 744 -38845377.32488 +874 744 -8333333.33607 +875 744 -23415968.44916 +876 744 -64986646.84972 +877 744 2436242.286385 +878 744 -58542682.88204 +879 744 -16011865.17978 +880 744 7626721.393617 +881 744 -9769737.878529 +745 745 706099168.2163 +746 745 78358244.93297 +747 745 -44109759.54871 +748 745 -102250467.9801 +749 745 -12402588.68539 +762 745 -33333333.32786 +763 745 -33106002.77733 +764 745 -15166485.20115 +765 745 9744969.140738 +766 745 85107231.01254 +767 745 19035037.8372 +768 745 30506885.55944 +769 745 -42587780.00762 +770 745 -5736313.161515 +834 745 8333333.336071 +835 745 -39196836.65327 +836 745 -17343704.63996 +837 745 -3226694.963612 +838 745 -34510800.91818 +839 745 10096086.08607 +852 745 2.175569534302e-06 +853 745 -126000573.4156 +854 745 -67541485.19271 +855 745 4191171.17622 +856 745 -21799184.55042 +857 745 19581709.58125 +858 745 -11027439.89261 +859 745 -60138740.99675 +860 745 47821580.90675 +873 745 -8333333.33607 +874 745 -36345253.319 +875 745 -16510371.30635 +876 745 2436242.286385 +877 745 -31339965.69435 +878 745 8706676.127155 +879 745 7626721.393617 +880 745 -21957274.44509 +881 745 15232588.38105 +746 746 1035512900.925 +747 746 -6401786.696301 +748 746 -13737849.54833 +749 746 94620592.77045 +762 746 -29652762.65002 +763 746 -14833151.86804 +764 746 4679881.612865 +765 746 10879268.43431 +766 746 19368371.17048 +767 746 190912775.2159 +768 746 5607159.608706 +769 746 -5736313.161515 +770 746 23303137.82117 +834 746 24110420.45533 +835 746 -17343704.63996 +836 746 -81284258.80916 +837 746 54643912.99742 +838 746 10440765.17629 +839 746 -94980766.45259 +852 746 -694452.0061623 +853 746 -67874818.52582 +854 746 -284706093.7789 +855 746 -2762465.644181 +856 746 19596227.63998 +857 746 -269985712.4852 +858 746 14428412.5018 +859 746 47817257.06168 +860 746 -68547849.10008 +873 746 -23415968.44916 +874 746 -16510371.30635 +875 746 -73680036.58444 +876 746 -56459349.54655 +877 746 8706676.128006 +878 746 -92583202.06042 +879 746 -9769737.878529 +880 746 15232588.38105 +881 746 -24335094.043 +747 747 476719092.606 +748 747 6055794.275668 +749 747 3719896.783943 +765 747 -39139835.15421 +766 747 -32971227.61138 +767 747 -4711866.146783 +768 747 -5046854.985 +769 747 13026739.41472 +770 747 829808.4249002 +771 747 79313608.52165 +772 747 -12360384.10609 +773 747 -98386.911798 +774 747 -7403415.117131 +775 747 30276526.44728 +776 747 815875.2272372 +837 747 -18540701.9006 +838 747 10020577.78707 +839 747 14561779.53718 +855 747 -45939787.20181 +856 747 -11027439.89261 +857 747 -17526028.04609 +858 747 -61800142.29096 +859 747 1513948.569663 +860 747 12440251.97284 +876 747 -26368729.20533 +877 747 -8242806.906906 +878 747 -17075883.20919 +879 747 -74906791.02692 +880 747 3256684.855284 +881 747 -62343936.77239 +882 747 -25367014.53987 +883 747 -3090096.028045 +884 747 8972625.494148 +885 747 -22671270.46426 +886 747 7569131.615548 +887 747 -15173808.97594 +748 748 543890761.6333 +749 748 19481880.11059 +765 748 -32971227.61138 +766 748 -22253272.73831 +767 748 -1388140.969734 +768 748 13026739.41472 +769 748 125305508.8346 +770 748 4348106.303911 +771 748 972949.2250522 +772 748 14486248.89663 +773 748 -622053.6789891 +774 748 30276526.44728 +775 748 -13597447.23127 +776 748 -681484.5028543 +837 748 6680385.191377 +838 748 -24472689.98014 +839 748 -16861073.14158 +855 748 -11020580.63135 +856 748 -75855100.02084 +857 748 -54351585.25286 +858 748 1513948.569662 +859 748 -45007225.02585 +860 748 7591760.11537 +876 748 -8242806.906906 +877 748 -22147088.59928 +878 748 -13065785.2468 +879 748 3256684.855284 +880 748 -42318700.05597 +881 748 5034943.242021 +882 748 243237.3063829 +883 748 -41573854.45411 +884 748 33177819.90803 +885 748 7569131.615548 +886 748 -24219778.49355 +887 748 16496295.54634 +749 749 794285488.9012 +765 749 -4295199.48039 +766 749 -1054807.636619 +767 749 24668357.59631 +768 749 2496475.091293 +769 749 4681439.637189 +770 749 244277825.254 +771 749 318279.7548032 +772 749 -622053.6789894 +773 749 155151834.6146 +774 749 1232541.89363 +775 749 -681484.5028543 +776 749 54876959.51256 +837 749 9707853.024785 +838 749 -20743439.00053 +839 749 -43509883.65538 +855 749 -17515712.64747 +856 749 -54353721.05939 +857 749 -110458139.831 +858 749 -12663636.91192 +859 749 487449.3652666 +860 749 -284041735.68 +876 749 -17075883.20919 +877 749 -13065785.2468 +878 749 -38056298.36311 +879 749 -62343936.77198 +880 749 5034943.242873 +881 749 -135317416.4032 +882 749 847625.4925454 +883 749 33177819.90803 +884 749 -81733152.47406 +885 749 -15173808.97594 +886 749 16496295.54634 +887 749 -41801871.2726 +750 750 414567870.0551 +751 750 7.152557373047e-07 +752 750 -5555616.043871 +753 750 43538456.00902 +754 750 6666666.665572 +755 750 3819429.321339 +840 750 -77407961.77148 +841 750 -1.184642314911e-06 +842 750 64983348.44575 +843 750 -12048523.14942 +844 750 -8333333.336071 +845 750 8485420.4502 +861 750 -13658136.58254 +862 750 5.662441253662e-07 +863 750 -13107792.89912 +864 750 10254900.45163 +865 750 1666666.667213 +866 750 -1974864.892506 +751 751 374565886.0004 +752 751 66665940.77111 +753 751 -6666666.665572 +754 751 -19794792.63523 +755 751 -32999637.05228 +840 751 -1.601874828339e-06 +841 751 -40741089.4269 +842 751 8333242.604601 +843 751 -8333333.336071 +844 751 -9548399.143536 +845 751 9010462.03536 +861 751 5.960464477539e-08 +862 751 -23658632.60114 +863 751 16666485.20099 +864 751 -1666666.667215 +865 751 -5578411.717238 +866 751 17187590.72873 +752 752 626992140.1079 +753 752 -8680570.676608 +754 752 -33666303.71883 +755 752 49804756.91433 +840 752 65400015.11214 +841 752 8333242.604601 +842 752 -113457062.6479 +843 752 8485420.4502 +844 752 9010462.03536 +845 752 -2221758.783205 +861 752 12413318.2078 +862 752 16666485.20099 +863 752 -156052242.6221 +864 752 1280412.88634 +865 752 17187590.72856 +866 752 10771953.08541 +753 753 414567870.0551 +754 753 7.152557373047e-07 +755 753 -5555616.043871 +756 753 43538456.00902 +757 753 6666666.665572 +758 753 3819429.321339 +840 753 -41696960.65915 +841 753 8333333.336071 +842 753 24110420.45533 +843 753 -77407961.77148 +844 753 -1.184642314911e-06 +845 753 64983348.44575 +846 753 -12048523.14942 +847 753 -8333333.336071 +848 753 8485420.4502 +861 753 -47166974.53894 +862 753 -1666666.667213 +863 753 -5099864.893531 +864 753 -13658136.58254 +865 753 5.662441253662e-07 +866 753 -13107792.89912 +867 753 10254900.45163 +868 753 1666666.667213 +869 753 -1974864.892506 +754 754 374565886.0004 +755 754 66665940.77111 +756 754 -6666666.665572 +757 754 -19794792.63523 +758 754 -32999637.05228 +840 754 8333333.336071 +841 754 -39196836.65327 +842 754 -17343704.63996 +843 754 -1.601874828339e-06 +844 754 -40741089.4269 +845 754 8333242.604601 +846 754 -8333333.336071 +847 754 -9548399.143536 +848 754 9010462.03536 +861 754 1666666.667215 +862 754 -63000286.7078 +863 754 -33854075.92972 +864 754 5.960464477539e-08 +865 754 -23658632.60114 +866 754 16666485.20099 +867 754 -1666666.667215 +868 754 -5578411.717238 +869 754 17187590.72873 +755 755 626992140.1079 +756 755 -8680570.676608 +757 755 -33666303.71883 +758 755 49804756.91433 +840 755 24110420.45533 +841 755 -17343704.63996 +842 755 -81284258.80916 +843 755 65400015.11214 +844 755 8333242.604601 +845 755 -113457062.6479 +846 755 8485420.4502 +847 755 9010462.03536 +848 755 -2221758.783205 +861 755 4405412.887368 +862 755 -33854075.92955 +863 755 -142353046.8894 +864 755 12413318.2078 +865 755 16666485.20099 +866 755 -156052242.6221 +867 755 1280412.88634 +868 755 17187590.72856 +869 755 10771953.08541 +756 756 414567870.0551 +757 756 7.152557373047e-07 +758 756 -5555616.043871 +759 756 43538456.00902 +760 756 6666666.665572 +761 756 3819429.321339 +843 756 -41696960.65915 +844 756 8333333.336071 +845 756 24110420.45533 +846 756 -77407961.77148 +847 756 -1.184642314911e-06 +848 756 64983348.44575 +849 756 -12048523.14942 +850 756 -8333333.336071 +851 756 8485420.4502 +864 756 -47166974.53894 +865 756 -1666666.667213 +866 756 -5099864.893531 +867 756 -13658136.58254 +868 756 5.662441253662e-07 +869 756 -13107792.89912 +870 756 10254900.45163 +871 756 1666666.667213 +872 756 -1974864.892506 +757 757 374565886.0004 +758 757 66665940.77111 +759 757 -6666666.665572 +760 757 -19794792.63523 +761 757 -32999637.05228 +843 757 8333333.336071 +844 757 -39196836.65327 +845 757 -17343704.63996 +846 757 -1.601874828339e-06 +847 757 -40741089.4269 +848 757 8333242.604601 +849 757 -8333333.336071 +850 757 -9548399.143536 +851 757 9010462.03536 +864 757 1666666.667215 +865 757 -63000286.7078 +866 757 -33854075.92972 +867 757 5.960464477539e-08 +868 757 -23658632.60114 +869 757 16666485.20099 +870 757 -1666666.667215 +871 757 -5578411.717238 +872 757 17187590.72873 +758 758 626992140.1079 +759 758 -8680570.676608 +760 758 -33666303.71883 +761 758 49804756.91433 +843 758 24110420.45533 +844 758 -17343704.63996 +845 758 -81284258.80916 +846 758 65400015.11214 +847 758 8333242.604601 +848 758 -113457062.6479 +849 758 8485420.4502 +850 758 9010462.03536 +851 758 -2221758.783205 +864 758 4405412.887368 +865 758 -33854075.92955 +866 758 -142353046.8894 +867 758 12413318.2078 +868 758 16666485.20099 +869 758 -156052242.6221 +870 758 1280412.88634 +871 758 17187590.72856 +872 758 10771953.08541 +759 759 414567870.0551 +760 759 7.152557373047e-07 +761 759 -5555616.043871 +762 759 43538456.00902 +763 759 6666666.665572 +764 759 3819429.321339 +846 759 -41696960.65915 +847 759 8333333.336071 +848 759 24110420.45533 +849 759 -77407961.77148 +850 759 -1.184642314911e-06 +851 759 64983348.44575 +852 759 -12048523.14942 +853 759 -8333333.336071 +854 759 8485420.4502 +867 759 -47166974.53894 +868 759 -1666666.667213 +869 759 -5099864.893531 +870 759 -13658136.58254 +871 759 5.662441253662e-07 +872 759 -13107792.89912 +873 759 10254900.45163 +874 759 1666666.667213 +875 759 -1974864.892506 +760 760 374565886.0004 +761 760 66665940.77111 +762 760 -6666666.665572 +763 760 -19794792.63523 +764 760 -32999637.05228 +846 760 8333333.336071 +847 760 -39196836.65327 +848 760 -17343704.63996 +849 760 -1.601874828339e-06 +850 760 -40741089.4269 +851 760 8333242.604601 +852 760 -8333333.336071 +853 760 -9548399.143536 +854 760 9010462.03536 +867 760 1666666.667215 +868 760 -63000286.7078 +869 760 -33854075.92972 +870 760 5.960464477539e-08 +871 760 -23658632.60114 +872 760 16666485.20099 +873 760 -1666666.667215 +874 760 -5578411.717238 +875 760 17187590.72873 +761 761 626992140.1079 +762 761 -8680570.676608 +763 761 -33666303.71883 +764 761 49804756.91433 +846 761 24110420.45533 +847 761 -17343704.63996 +848 761 -81284258.80916 +849 761 65400015.11214 +850 761 8333242.604601 +851 761 -113457062.6479 +852 761 8485420.4502 +853 761 9010462.03536 +854 761 -2221758.783205 +867 761 4405412.887368 +868 761 -33854075.92955 +869 761 -142353046.8894 +870 761 12413318.2078 +871 761 16666485.20099 +872 761 -156052242.6221 +873 761 1280412.88634 +874 761 17187590.72856 +875 761 10771953.08541 +762 762 414567870.0551 +763 762 7.152557373047e-07 +764 762 -5555616.043871 +765 762 43538456.00902 +766 762 6666666.665572 +767 762 3819429.321339 +849 762 -41696960.65915 +850 762 8333333.336071 +851 762 24110420.45533 +852 762 -77407961.77148 +853 762 -1.184642314911e-06 +854 762 64983348.44575 +855 762 -12048523.14942 +856 762 -8333333.336071 +857 762 8485420.4502 +870 762 -47166974.53894 +871 762 -1666666.667213 +872 762 -5099864.893531 +873 762 -13658136.58254 +874 762 5.662441253662e-07 +875 762 -13107792.89912 +876 762 10254900.45163 +877 762 1666666.667213 +878 762 -1974864.892506 +763 763 374565886.0004 +764 763 66665940.77111 +765 763 -6666666.665572 +766 763 -19794792.63523 +767 763 -32999637.05228 +849 763 8333333.336071 +850 763 -39196836.65327 +851 763 -17343704.63996 +852 763 -1.601874828339e-06 +853 763 -40741089.4269 +854 763 8333242.604601 +855 763 -8333333.336071 +856 763 -9548399.143536 +857 763 9010462.03536 +870 763 1666666.667215 +871 763 -63000286.7078 +872 763 -33854075.92972 +873 763 5.960464477539e-08 +874 763 -23658632.60114 +875 763 16666485.20099 +876 763 -1666666.667215 +877 763 -5578411.717238 +878 763 17187590.72873 +764 764 626992140.1079 +765 764 -8680570.676608 +766 764 -33666303.71883 +767 764 49804756.91433 +849 764 24110420.45533 +850 764 -17343704.63996 +851 764 -81284258.80916 +852 764 65400015.11214 +853 764 8333242.604601 +854 764 -113457062.6479 +855 764 8485420.4502 +856 764 9010462.03536 +857 764 -2221758.783205 +870 764 4405412.887368 +871 764 -33854075.92955 +872 764 -142353046.8894 +873 764 12413318.2078 +874 764 16666485.20099 +875 764 -156052242.6221 +876 764 1280412.88634 +877 764 17187590.72856 +878 764 10771953.08541 +765 765 394527858.8554 +766 765 362077.3628545 +767 765 -30197935.16775 +768 765 50114720.96038 +769 765 -3802485.554504 +770 765 -2219467.11486 +852 765 -41696960.65915 +853 765 8333333.336071 +854 765 24110420.45533 +855 765 -72955365.59794 +856 765 2436242.286385 +857 765 61378150.43314 +858 765 -22540576.42629 +859 765 -8242806.906905 +860 765 14824116.80129 +873 765 -47166974.53894 +874 765 -1666666.667213 +875 765 -5099864.893531 +876 765 -19040600.32219 +877 765 90519.34075832 +878 765 -19268094.90535 +879 765 -13147418.28847 +880 765 -950621.3890942 +881 765 1450272.108583 +766 766 361417907.5311 +767 766 40445107.05745 +768 766 -17135818.88565 +769 766 -14915862.06077 +770 766 -6592548.338528 +852 766 8333333.336071 +853 766 -39196836.65327 +854 766 -17343704.63996 +855 766 2436242.286384 +856 766 -39308684.44256 +857 766 894176.12852 +858 766 -8242806.906905 +859 766 -18318935.82024 +860 766 12455048.09491 +873 766 1666666.667215 +874 766 -63000286.7078 +875 766 -33854075.92972 +876 766 90519.34075797 +877 766 -27318088.15734 +878 766 10111276.76934 +879 766 -4283954.723522 +880 766 -29405064.05177 +881 766 27737279.5769 +767 767 582973911.8654 +768 767 -4302800.447853 +769 767 -6925881.671807 +770 767 97507539.01388 +852 767 24110420.45533 +853 767 -17343704.63996 +854 767 -81284258.80916 +855 767 59294817.09957 +856 767 894176.1292076 +857 767 -113833118.7223 +858 767 14824116.80129 +859 767 12455048.09491 +860 767 -27847890.95234 +873 767 4405412.887368 +874 767 -33854075.92955 +875 767 -142353046.8894 +876 767 6252460.646014 +877 767 10111276.76934 +878 767 -168050028.8542 +879 767 7205272.109613 +880 767 27737279.57605 +881 767 -44092711.32715 +768 768 394608735.3681 +769 768 9859177.530151 +770 768 -3395263.967743 +771 768 -38652304.00089 +772 768 -36390140.20844 +773 768 -1059124.772573 +774 768 57326064.36126 +775 768 133156.5897796 +776 768 -1013112.177398 +855 768 -22730594.34878 +856 768 7626721.393617 +857 768 12364984.35096 +858 768 -76547391.72184 +859 768 3256684.855286 +860 768 63175507.65185 +876 768 -24944296.75828 +877 768 -4283954.723523 +878 768 -8940005.667694 +879 768 -48889704.10442 +880 768 2464794.383752 +881 768 -12359093.76876 +882 768 -30483492.68905 +883 768 -9097535.056593 +884 768 20047718.8134 +885 768 -23754733.9178 +886 768 33289.14746143 +887 768 1855888.619689 +769 769 403589170.3359 +770 769 10766124.03009 +771 769 -36390140.20844 +772 769 -25315780.56268 +773 769 -681484.5028545 +774 769 -13200176.74136 +775 769 -6531037.793588 +776 769 -2103884.331085 +855 769 7626721.393617 +856 769 -28676003.61409 +857 769 -18100744.96323 +858 769 3256684.855286 +859 769 -43959300.75089 +860 769 -2777556.756613 +876 769 -950621.3890945 +877 769 -41201942.52158 +878 769 -31116887.08018 +879 769 2464794.383752 +880 769 -46644595.36138 +881 769 2691531.008842 +882 769 -9097535.056593 +883 769 -27149361.82785 +884 769 16496295.54634 +885 769 -3300044.186967 +886 769 -39719009.46437 +887 769 32807362.24483 +770 770 637169785.0564 +771 770 -1059124.772573 +772 770 -681484.5028545 +773 770 43158626.18115 +774 770 -1429778.844 +775 770 -2103884.331085 +776 770 126701003.3288 +855 770 12364984.35096 +856 770 -18100744.96323 +857 770 -42251705.16035 +858 770 63175507.65144 +859 770 -2777556.755926 +860 770 -139692351.5897 +876 770 -1935005.666458 +877 770 -31116887.08087 +878 770 -75551053.91331 +879 770 12744795.11601 +880 770 2691531.008842 +881 770 -234152588.3109 +882 770 20047718.8134 +883 770 16496295.54634 +884 770 -44731454.6069 +885 770 7819499.733824 +886 770 32807362.24483 +887 770 -69888082.52598 +771 771 233968058.0878 +772 771 39027050.76838 +773 771 584498.0232363 +774 771 -5566029.282941 +775 771 -3609859.784988 +776 771 156346.9945345 +858 771 -26617014.5403 +859 771 243237.3063828 +860 771 -792652.2819211 +879 771 -31733492.68947 +880 771 -9097535.056593 +881 771 -20577281.19994 +882 771 -33148818.76463 +883 771 9756762.696902 +884 771 8271124.504546 +885 771 -44282340.66884 +886 771 -902464.9466921 +887 771 -35651191.02268 +772 772 217545417.7261 +773 772 622053.6789918 +774 772 9723473.546155 +775 772 62347447.26551 +776 772 681484.5028564 +858 772 -3090096.028045 +859 772 -42823854.45454 +860 772 -33488846.74768 +879 772 -9097535.056593 +880 772 -28399361.82827 +881 772 -16837037.79794 +882 772 9756762.696902 +883 772 -37254478.85706 +884 772 6822180.085395 +885 772 2430868.387736 +886 772 -27303971.52336 +887 772 3503704.460225 +773 773 382349276.3928 +774 773 573013.6611362 +775 773 681484.5028564 +776 773 136842485.0131 +858 773 -8917652.283731 +859 773 -33488846.74768 +860 773 -85066485.80853 +879 773 -20577281.19995 +880 773 -16837037.79794 +881 773 -48064787.94135 +882 773 -7978875.492785 +883 773 -6511153.245748 +884 773 -148788236.3624 +885 773 -35651191.02354 +886 773 -3162962.208631 +887 773 -80164934.32299 +774 774 201270046.7132 +775 774 -26799823.25207 +776 774 -1209110.043552 +858 774 -23921270.46468 +859 774 7569131.615548 +860 774 15685913.25641 +879 774 -27504733.91658 +880 774 -3300044.186967 +881 774 -8117722.489783 +882 774 -44282340.66884 +883 774 2430868.387737 +884 774 35833531.18791 +885 774 -29604988.28668 +886 774 -6699955.816318 +887 774 -5953388.621477 +775 775 203407704.4337 +776 775 2103884.331091 +858 775 7569131.615548 +859 775 -25469778.49398 +860 775 -16837037.79794 +879 775 33289.14746112 +880 775 -43469009.46316 +881 775 -33859304.41089 +882 775 -902464.9466912 +883 775 -27303971.52336 +884 775 3503704.460225 +885 775 -6699955.816318 +886 775 -29070573.85628 +887 775 7192637.7486 +776 776 336583996.6104 +858 776 15685913.25641 +859 776 -16837037.79794 +860 776 -45135204.60706 +879 776 -1737444.709049 +880 776 -33859304.41089 +881 776 -79888082.52274 +882 776 35833531.18684 +883 776 -3162962.208631 +884 776 -80164934.32299 +885 776 6390500.265385 +886 776 -6140695.582542 +887 776 -128980667.4453 +777 777 511307203.7006 +778 777 31944444.4392 +779 777 -38471552.3926 +780 777 -129270221.6954 +781 777 -31963408.23791 +782 777 32202213.44983 +783 777 -74245.33507569 +784 777 25574519.35007 +785 777 23212035.46926 +888 777 -2535056.171221 +889 777 7638888.891397 +890 777 2916127.642058 +891 777 -61266506.56961 +892 777 -7643634.032713 +893 777 -48493965.33591 +894 777 6429332.410642 +895 777 6115856.254433 +896 777 -5472930.844082 +778 778 463366668.0891 +779 778 73645353.45811 +780 778 -31972890.13727 +781 778 20929276.84229 +782 778 44576929.53758 +783 778 38361779.02511 +784 778 -74245.33508131 +785 778 -29688226.0277 +888 778 7638888.891396 +889 778 -13999375.77193 +890 778 27304194.09764 +891 778 -7646006.603371 +892 778 -25348555.65241 +893 778 -585233.2815705 +894 778 9173784.381649 +895 778 6429332.410642 +896 778 6567824.782935 +779 779 790000669.0394 +780 779 29067543.97844 +781 779 35319743.0838 +782 779 126505653.3816 +783 779 34818053.20388 +784 779 -19792150.68513 +785 779 -197987.5602046 +888 779 -19488671.82916 +889 779 9380576.980452 +890 779 -143900824.6786 +891 779 -48878084.71163 +892 779 -2722347.244235 +893 779 -50690307.28013 +894 779 -8209396.266123 +895 779 4378549.855291 +896 779 17144886.42838 +780 780 798779840.2986 +781 780 31991853.93598 +782 780 -35934840.90099 +783 780 33796428.38625 +784 780 -31963408.23791 +785 780 -31487513.88132 +786 780 -60300895.02916 +787 780 -1.370906829834e-06 +788 780 6886635.866331 +789 780 -45730271.10628 +790 780 31944444.4392 +791 780 31469922.85153 +888 780 -88160408.62987 +889 780 -7646006.603366 +890 780 63145912.64445 +891 780 3615653.321898 +892 780 7650751.744684 +893 780 -8598044.452827 +894 780 3117023.124192 +895 780 -7643634.032712 +896 780 6521862.080229 +897 780 -61096866.41184 +898 780 -1.631677150726e-06 +899 780 -54526141.60101 +900 780 -10000259.54407 +901 780 7638888.891397 +902 780 -6517820.126831 +781 781 712503944.5236 +782 781 99028842.16786 +783 781 -31972890.13727 +784 781 -78046374.58557 +785 781 -54292558.27614 +787 781 80255500.90366 +788 781 31944073.6884 +789 781 31944444.4392 +790 781 -36146431.06068 +791 781 -17722036.84414 +888 781 -7643634.032709 +889 781 -52242457.71267 +890 781 19687387.29713 +891 781 7650751.744683 +892 781 -17015851.08971 +893 781 23676848.33746 +894 781 -7646006.603369 +895 781 -23628404.39615 +896 781 31972114.21773 +897 781 -1.691281795502e-06 +898 781 -27485540.44924 +899 781 7638794.112417 +900 781 7638888.891397 +901 781 -7708463.340222 +902 781 6996575.169565 +782 782 1098010379.249 +783 782 -31114364.95125 +784 782 -60743490.00346 +785 782 77736775.05345 +786 782 3761635.866845 +787 782 31944073.6884 +788 782 195560564.8714 +789 782 31087978.40657 +790 782 -17416481.28817 +791 782 -7301392.713971 +888 782 63530032.02016 +889 782 21831451.86013 +890 782 -122407379.4408 +891 782 -8589356.089042 +892 782 23683798.94222 +893 782 -237160382.7964 +894 782 6523883.056929 +895 782 30136961.89646 +896 782 5350330.44263 +897 782 -54908086.04521 +898 782 7638794.112417 +899 782 -77707668.15051 +900 782 -6517820.126831 +901 782 6996575.169565 +902 782 748003.7541653 +783 783 511307203.7006 +784 783 31944444.4392 +785 783 -38471552.3926 +786 783 -42136521.10687 +787 783 -31944444.4392 +788 783 -28425910.47196 +789 783 -129270221.6954 +790 783 -31963408.23791 +791 783 32202213.44983 +792 783 -74245.33507569 +793 783 25574519.35007 +794 783 23212035.46926 +888 783 -44000691.65356 +889 783 9173784.381649 +890 783 25410834.91903 +891 783 -74169151.35949 +892 783 -7646006.603371 +893 783 -21497320.34861 +894 783 -2535056.171221 +895 783 7638888.891397 +896 783 2916127.642058 +897 783 -34336197.05207 +898 783 -7638888.891398 +899 783 -20840736.7982 +900 783 -61266506.56961 +901 783 -7643634.032713 +902 783 -48493965.33591 +903 783 6429332.410642 +904 783 6115856.254433 +905 783 -5472930.844082 +784 784 463366668.0891 +785 784 73645353.45811 +786 784 -31944444.4392 +787 784 -32552681.06127 +788 784 -14222036.84425 +789 784 -31972890.13727 +790 784 20929276.84229 +791 784 44576929.53758 +792 784 38361779.02511 +793 784 -74245.33508131 +794 784 -29688226.0277 +888 784 6115856.254433 +889 784 -44000691.65356 +890 784 -13552018.01794 +891 784 -7643634.032713 +892 784 -100914578.8798 +893 784 -59481123.99205 +894 784 7638888.891396 +895 784 -13999375.77193 +896 784 27304194.09764 +897 784 -7638888.891398 +898 784 -32044400.84822 +899 784 -14635369.28198 +900 784 -7646006.603371 +901 784 -25348555.65241 +902 784 -585233.2815705 +903 784 9173784.381649 +904 784 6429332.410642 +905 784 6567824.782935 +785 785 790000669.0394 +786 785 -28807854.91693 +787 785 -14527592.40022 +788 785 2281940.617786 +789 785 29067543.97844 +790 785 35319743.0838 +791 785 126505653.3816 +792 785 34818053.20388 +793 785 -19792150.68513 +794 785 -197987.5602046 +888 785 16940556.61269 +889 785 -20328027.02691 +890 785 -117335177.7428 +891 785 -21490653.15616 +892 785 -57645971.82207 +893 785 -200746134.8472 +894 785 -19488671.82916 +895 785 9380576.980452 +896 785 -143900824.6786 +897 785 -20840736.7982 +898 785 -14635369.28198 +899 785 -64147829.60048 +900 785 -48878084.71163 +901 785 -2722347.244235 +902 785 -50690307.28013 +903 785 -8209396.266123 +904 785 4378549.855291 +905 785 17144886.42838 +786 786 783245798.6586 +787 786 2.861022949219e-06 +788 786 -10648271.7332 +789 786 80258968.78408 +790 786 -4.023313522339e-07 +791 786 -2662067.934612 +795 786 -60300895.02916 +796 786 -1.370906829834e-06 +797 786 6886635.866331 +798 786 -45730271.10628 +799 786 31944444.4392 +800 786 31469922.85153 +891 786 -67815699.74408 +892 786 2.041459083557e-06 +893 786 57072469.49195 +894 786 -10820592.87768 +895 786 -7638888.891398 +896 786 7154402.099879 +897 786 -12957512.05534 +898 786 5.960464477539e-08 +899 786 -2546327.890928 +900 786 19546554.40623 +901 786 -1.84029340744e-06 +902 786 -636581.9730468 +906 786 -61096866.41184 +907 786 -1.631677150726e-06 +908 786 -54526141.60101 +909 786 -10000259.54407 +910 786 7638888.891397 +911 786 -6517820.126831 +787 787 706575078.3316 +788 787 127776294.6906 +789 787 -1.341104507446e-07 +790 787 -41129747.07642 +791 787 -65138147.34512 +796 787 80255500.90366 +797 787 31944073.6884 +798 787 31944444.4392 +799 787 -36146431.06068 +800 787 -17722036.84414 +891 787 2.004206180573e-06 +892 787 -34204373.78147 +893 787 7638794.112417 +894 787 -7638888.891398 +895 787 -8528796.673826 +896 787 7760464.058704 +897 787 2.98023223877e-08 +898 787 -31291881.67713 +899 787 30555176.43461 +900 787 -1.668930053711e-06 +901 787 -9481179.15318 +902 787 29361300.66432 +906 787 -1.691281795502e-06 +907 787 -27485540.44924 +908 787 7638794.112417 +909 787 7638888.891397 +910 787 -7708463.340222 +911 787 6996575.169565 +788 788 1171487488.319 +789 788 -2662067.934612 +790 788 -62638147.34553 +791 788 86952958.72131 +795 788 3761635.866845 +796 788 31944073.6884 +797 788 195560564.8714 +798 788 31087978.40657 +799 788 -17416481.28817 +800 788 -7301392.713971 +891 788 57454413.93615 +892 788 7638794.112417 +893 788 -95624557.03646 +894 788 7154402.099879 +895 788 7760464.058704 +896 788 -1439551.802109 +897 788 -2546327.890927 +898 788 30555176.43461 +899 788 -253876265.6798 +900 788 -636581.9730468 +901 788 29666856.21968 +902 788 21737561.15826 +906 788 -54908086.04521 +907 788 7638794.112417 +908 788 -77707668.15051 +909 788 -6517820.126831 +910 788 6996575.169565 +911 788 748003.7541653 +789 789 798779840.2986 +790 789 31991853.93598 +791 789 -35934840.90099 +792 789 33796428.38625 +793 789 -31963408.23791 +794 789 -31487513.88132 +795 789 -42136521.10687 +796 789 -31944444.4392 +797 789 -28425910.47196 +798 789 -60300895.02916 +799 789 -1.370906829834e-06 +800 789 6886635.866331 +801 789 -45730271.10628 +802 789 31944444.4392 +803 789 31469922.85153 +891 789 -36875280.38624 +892 789 7638888.891399 +893 789 21477318.77125 +894 789 -88160408.62987 +895 789 -7646006.603366 +896 789 63145912.64445 +897 789 -81234695.57722 +898 789 1.624226570129e-06 +899 789 -636581.9730444 +900 789 3615653.321898 +901 789 7650751.744684 +902 789 -8598044.452827 +903 789 3117023.124192 +904 789 -7643634.032712 +905 789 6521862.080229 +906 789 -34336197.05207 +907 789 -7638888.891398 +908 789 -20840736.7982 +909 789 -61096866.41184 +910 789 -1.631677150726e-06 +911 789 -54526141.60101 +912 789 -10000259.54407 +913 789 7638888.891397 +914 789 -6517820.126831 +790 790 712503944.5236 +791 790 99028842.16786 +792 790 -31972890.13727 +793 790 -78046374.58557 +794 790 -54292558.27614 +795 790 -31944444.4392 +796 790 -32552681.06127 +797 790 -14222036.84425 +799 790 80255500.90366 +800 790 31944073.6884 +801 790 31944444.4392 +802 790 -36146431.06068 +803 790 -17722036.84414 +891 790 7638888.891399 +892 790 -34583484.18238 +893 790 -15399258.17112 +894 790 -7643634.032709 +895 790 -52242457.71267 +896 790 19687387.29713 +897 790 1.564621925354e-06 +898 790 -110262429.1366 +899 790 -59916477.09895 +900 790 7650751.744683 +901 790 -17015851.08971 +902 790 23676848.33746 +903 790 -7646006.603369 +904 790 -23628404.39615 +905 790 31972114.21773 +906 790 -7638888.891398 +907 790 -32044400.84822 +908 790 -14635369.28198 +909 790 -1.691281795502e-06 +910 790 -27485540.44924 +911 790 7638794.112417 +912 790 7638888.891397 +913 790 -7708463.340222 +914 790 6996575.169565 +791 791 1098010379.249 +792 791 -31114364.95125 +793 791 -60743490.00346 +794 791 77736775.05345 +795 791 -28807854.91693 +796 791 -14527592.40022 +797 791 2281940.617786 +798 791 3761635.866845 +799 791 31944073.6884 +800 791 195560564.8714 +801 791 31087978.40657 +802 791 -17416481.28817 +803 791 -7301392.713971 +891 791 21477318.77125 +892 791 -15399258.17112 +893 791 -70918718.4916 +894 791 63530032.02016 +895 791 21831451.86013 +896 791 -122407379.4408 +897 791 -636581.9730439 +898 791 -60222032.6543 +899 791 -247012438.7976 +900 791 -8589356.089042 +901 791 23683798.94222 +902 791 -237160382.7964 +903 791 6523883.056929 +904 791 30136961.89646 +905 791 5350330.44263 +906 791 -20840736.7982 +907 791 -14635369.28198 +908 791 -64147829.60048 +909 791 -54908086.04521 +910 791 7638794.112417 +911 791 -77707668.15051 +912 791 -6517820.126831 +913 791 6996575.169565 +914 791 748003.7541653 +792 792 511307203.7006 +793 792 31944444.4392 +794 792 -38471552.3926 +798 792 -42136521.10687 +799 792 -31944444.4392 +800 792 -28425910.47196 +801 792 -129270221.6954 +802 792 -31963408.23791 +803 792 32202213.44983 +804 792 -74245.33507569 +805 792 25574519.35007 +806 792 23212035.46926 +894 792 -44000691.65356 +895 792 9173784.381649 +896 792 25410834.91903 +900 792 -74169151.35949 +901 792 -7646006.603371 +902 792 -21497320.34861 +903 792 -2535056.171221 +904 792 7638888.891397 +905 792 2916127.642058 +909 792 -34336197.05207 +910 792 -7638888.891398 +911 792 -20840736.7982 +912 792 -61266506.56961 +913 792 -7643634.032713 +914 792 -48493965.33591 +915 792 6429332.410642 +916 792 6115856.254433 +917 792 -5472930.844082 +793 793 463366668.0891 +794 793 73645353.45811 +798 793 -31944444.4392 +799 793 -32552681.06127 +800 793 -14222036.84425 +801 793 -31972890.13727 +802 793 20929276.84229 +803 793 44576929.53758 +804 793 38361779.02511 +805 793 -74245.33508131 +806 793 -29688226.0277 +894 793 6115856.254433 +895 793 -44000691.65356 +896 793 -13552018.01794 +900 793 -7643634.032713 +901 793 -100914578.8798 +902 793 -59481123.99205 +903 793 7638888.891396 +904 793 -13999375.77193 +905 793 27304194.09764 +909 793 -7638888.891398 +910 793 -32044400.84822 +911 793 -14635369.28198 +912 793 -7646006.603371 +913 793 -25348555.65241 +914 793 -585233.2815705 +915 793 9173784.381649 +916 793 6429332.410642 +917 793 6567824.782935 +794 794 790000669.0394 +798 794 -28807854.91693 +799 794 -14527592.40022 +800 794 2281940.617786 +801 794 29067543.97844 +802 794 35319743.0838 +803 794 126505653.3816 +804 794 34818053.20388 +805 794 -19792150.68513 +806 794 -197987.5602046 +894 794 16940556.61269 +895 794 -20328027.02691 +896 794 -117335177.7428 +900 794 -21490653.15616 +901 794 -57645971.82207 +902 794 -200746134.8472 +903 794 -19488671.82916 +904 794 9380576.980452 +905 794 -143900824.6786 +909 794 -20840736.7982 +910 794 -14635369.28198 +911 794 -64147829.60048 +912 794 -48878084.71163 +913 794 -2722347.244235 +914 794 -50690307.28013 +915 794 -8209396.266123 +916 794 4378549.855291 +917 794 17144886.42838 +795 795 783245798.6586 +796 795 2.861022949219e-06 +797 795 -10648271.7332 +798 795 80258968.78408 +799 795 -4.023313522339e-07 +800 795 -2662067.934612 +807 795 -60300895.02916 +808 795 -1.370906829834e-06 +809 795 6886635.866331 +810 795 -45730271.10628 +811 795 31944444.4392 +812 795 31469922.85153 +897 795 -67815699.74408 +898 795 2.041459083557e-06 +899 795 57072469.49195 +900 795 -10820592.87768 +901 795 -7638888.891398 +902 795 7154402.099879 +906 795 -12957512.05534 +907 795 5.960464477539e-08 +908 795 -2546327.890928 +909 795 19546554.40623 +910 795 -1.84029340744e-06 +911 795 -636581.9730468 +918 795 -61096866.41184 +919 795 -1.631677150726e-06 +920 795 -54526141.60101 +921 795 -10000259.54407 +922 795 7638888.891397 +923 795 -6517820.126831 +796 796 706575078.3316 +797 796 127776294.6906 +798 796 -1.341104507446e-07 +799 796 -41129747.07642 +800 796 -65138147.34512 +808 796 80255500.90366 +809 796 31944073.6884 +810 796 31944444.4392 +811 796 -36146431.06068 +812 796 -17722036.84414 +897 796 2.004206180573e-06 +898 796 -34204373.78147 +899 796 7638794.112417 +900 796 -7638888.891398 +901 796 -8528796.673826 +902 796 7760464.058704 +906 796 2.98023223877e-08 +907 796 -31291881.67713 +908 796 30555176.43461 +909 796 -1.668930053711e-06 +910 796 -9481179.15318 +911 796 29361300.66432 +918 796 -1.691281795502e-06 +919 796 -27485540.44924 +920 796 7638794.112417 +921 796 7638888.891397 +922 796 -7708463.340222 +923 796 6996575.169565 +797 797 1171487488.319 +798 797 -2662067.934612 +799 797 -62638147.34553 +800 797 86952958.72131 +807 797 3761635.866845 +808 797 31944073.6884 +809 797 195560564.8714 +810 797 31087978.40657 +811 797 -17416481.28817 +812 797 -7301392.713971 +897 797 57454413.93615 +898 797 7638794.112417 +899 797 -95624557.03646 +900 797 7154402.099879 +901 797 7760464.058704 +902 797 -1439551.802109 +906 797 -2546327.890927 +907 797 30555176.43461 +908 797 -253876265.6798 +909 797 -636581.9730468 +910 797 29666856.21968 +911 797 21737561.15826 +918 797 -54908086.04521 +919 797 7638794.112417 +920 797 -77707668.15051 +921 797 -6517820.126831 +922 797 6996575.169565 +923 797 748003.7541653 +798 798 783245798.6586 +799 798 2.861022949219e-06 +800 798 -10648271.7332 +801 798 80258968.78408 +802 798 -4.023313522339e-07 +803 798 -2662067.934612 +807 798 -42136521.10687 +808 798 -31944444.4392 +809 798 -28425910.47196 +810 798 -60300895.02916 +811 798 -1.370906829834e-06 +812 798 6886635.866331 +813 798 -45730271.10628 +814 798 31944444.4392 +815 798 31469922.85153 +897 798 -36875280.38624 +898 798 7638888.891399 +899 798 21477318.77125 +900 798 -67815699.74408 +901 798 2.041459083557e-06 +902 798 57072469.49195 +903 798 -10820592.87768 +904 798 -7638888.891398 +905 798 7154402.099879 +906 798 -81234695.57722 +907 798 1.624226570129e-06 +908 798 -636581.9730444 +909 798 -12957512.05534 +910 798 5.960464477539e-08 +911 798 -2546327.890928 +912 798 19546554.40623 +913 798 -1.84029340744e-06 +914 798 -636581.9730468 +918 798 -34336197.05207 +919 798 -7638888.891398 +920 798 -20840736.7982 +921 798 -61096866.41184 +922 798 -1.631677150726e-06 +923 798 -54526141.60101 +924 798 -10000259.54407 +925 798 7638888.891397 +926 798 -6517820.126831 +799 799 706575078.3316 +800 799 127776294.6906 +801 799 -1.341104507446e-07 +802 799 -41129747.07642 +803 799 -65138147.34512 +807 799 -31944444.4392 +808 799 -32552681.06127 +809 799 -14222036.84425 +811 799 80255500.90366 +812 799 31944073.6884 +813 799 31944444.4392 +814 799 -36146431.06068 +815 799 -17722036.84414 +897 799 7638888.891399 +898 799 -34583484.18238 +899 799 -15399258.17112 +900 799 2.004206180573e-06 +901 799 -34204373.78147 +902 799 7638794.112417 +903 799 -7638888.891398 +904 799 -8528796.673826 +905 799 7760464.058704 +906 799 1.564621925354e-06 +907 799 -110262429.1366 +908 799 -59916477.09895 +909 799 2.98023223877e-08 +910 799 -31291881.67713 +911 799 30555176.43461 +912 799 -1.668930053711e-06 +913 799 -9481179.15318 +914 799 29361300.66432 +918 799 -7638888.891398 +919 799 -32044400.84822 +920 799 -14635369.28198 +921 799 -1.691281795502e-06 +922 799 -27485540.44924 +923 799 7638794.112417 +924 799 7638888.891397 +925 799 -7708463.340222 +926 799 6996575.169565 +800 800 1171487488.319 +801 800 -2662067.934612 +802 800 -62638147.34553 +803 800 86952958.72131 +807 800 -28807854.91693 +808 800 -14527592.40022 +809 800 2281940.617786 +810 800 3761635.866845 +811 800 31944073.6884 +812 800 195560564.8714 +813 800 31087978.40657 +814 800 -17416481.28817 +815 800 -7301392.713971 +897 800 21477318.77125 +898 800 -15399258.17112 +899 800 -70918718.4916 +900 800 57454413.93615 +901 800 7638794.112417 +902 800 -95624557.03646 +903 800 7154402.099879 +904 800 7760464.058704 +905 800 -1439551.802109 +906 800 -636581.9730439 +907 800 -60222032.6543 +908 800 -247012438.7976 +909 800 -2546327.890927 +910 800 30555176.43461 +911 800 -253876265.6798 +912 800 -636581.9730468 +913 800 29666856.21968 +914 800 21737561.15826 +918 800 -20840736.7982 +919 800 -14635369.28198 +920 800 -64147829.60048 +921 800 -54908086.04521 +922 800 7638794.112417 +923 800 -77707668.15051 +924 800 -6517820.126831 +925 800 6996575.169565 +926 800 748003.7541653 +801 801 798779840.2986 +802 801 31991853.93598 +803 801 -35934840.90099 +804 801 33796428.38625 +805 801 -31963408.23791 +806 801 -31487513.88132 +810 801 -42136521.10687 +811 801 -31944444.4392 +812 801 -28425910.47196 +813 801 -60300895.02916 +814 801 -1.370906829834e-06 +815 801 6886635.866331 +816 801 -45730271.10628 +817 801 31944444.4392 +818 801 31469922.85153 +900 801 -36875280.38624 +901 801 7638888.891399 +902 801 21477318.77125 +903 801 -88160408.62987 +904 801 -7646006.603366 +905 801 63145912.64445 +909 801 -81234695.57722 +910 801 1.624226570129e-06 +911 801 -636581.9730444 +912 801 3615653.321898 +913 801 7650751.744684 +914 801 -8598044.452827 +915 801 3117023.124192 +916 801 -7643634.032712 +917 801 6521862.080229 +921 801 -34336197.05207 +922 801 -7638888.891398 +923 801 -20840736.7982 +924 801 -61096866.41184 +925 801 -1.631677150726e-06 +926 801 -54526141.60101 +927 801 -10000259.54407 +928 801 7638888.891397 +929 801 -6517820.126831 +802 802 712503944.5236 +803 802 99028842.16786 +804 802 -31972890.13727 +805 802 -78046374.58557 +806 802 -54292558.27614 +810 802 -31944444.4392 +811 802 -32552681.06127 +812 802 -14222036.84425 +814 802 80255500.90366 +815 802 31944073.6884 +816 802 31944444.4392 +817 802 -36146431.06068 +818 802 -17722036.84414 +900 802 7638888.891399 +901 802 -34583484.18238 +902 802 -15399258.17112 +903 802 -7643634.032709 +904 802 -52242457.71267 +905 802 19687387.29713 +909 802 1.564621925354e-06 +910 802 -110262429.1366 +911 802 -59916477.09895 +912 802 7650751.744683 +913 802 -17015851.08971 +914 802 23676848.33746 +915 802 -7646006.603369 +916 802 -23628404.39615 +917 802 31972114.21773 +921 802 -7638888.891398 +922 802 -32044400.84822 +923 802 -14635369.28198 +924 802 -1.691281795502e-06 +925 802 -27485540.44924 +926 802 7638794.112417 +927 802 7638888.891397 +928 802 -7708463.340222 +929 802 6996575.169565 +803 803 1098010379.249 +804 803 -31114364.95125 +805 803 -60743490.00346 +806 803 77736775.05345 +810 803 -28807854.91693 +811 803 -14527592.40022 +812 803 2281940.617786 +813 803 3761635.866845 +814 803 31944073.6884 +815 803 195560564.8714 +816 803 31087978.40657 +817 803 -17416481.28817 +818 803 -7301392.713971 +900 803 21477318.77125 +901 803 -15399258.17112 +902 803 -70918718.4916 +903 803 63530032.02016 +904 803 21831451.86013 +905 803 -122407379.4408 +909 803 -636581.9730439 +910 803 -60222032.6543 +911 803 -247012438.7976 +912 803 -8589356.089042 +913 803 23683798.94222 +914 803 -237160382.7964 +915 803 6523883.056929 +916 803 30136961.89646 +917 803 5350330.44263 +921 803 -20840736.7982 +922 803 -14635369.28198 +923 803 -64147829.60048 +924 803 -54908086.04521 +925 803 7638794.112417 +926 803 -77707668.15051 +927 803 -6517820.126831 +928 803 6996575.169565 +929 803 748003.7541653 +804 804 511307203.7006 +805 804 31944444.4392 +806 804 -38471552.3926 +813 804 -42136521.10687 +814 804 -31944444.4392 +815 804 -28425910.47196 +816 804 -129270221.6954 +817 804 -31963408.23791 +818 804 32202213.44983 +819 804 -74245.33507569 +820 804 25574519.35007 +821 804 23212035.46926 +903 804 -44000691.65356 +904 804 9173784.381649 +905 804 25410834.91903 +912 804 -74169151.35949 +913 804 -7646006.603371 +914 804 -21497320.34861 +915 804 -2535056.171221 +916 804 7638888.891397 +917 804 2916127.642058 +924 804 -34336197.05207 +925 804 -7638888.891398 +926 804 -20840736.7982 +927 804 -61266506.56961 +928 804 -7643634.032713 +929 804 -48493965.33591 +930 804 6429332.410642 +931 804 6115856.254433 +932 804 -5472930.844082 +805 805 463366668.0891 +806 805 73645353.45811 +813 805 -31944444.4392 +814 805 -32552681.06127 +815 805 -14222036.84425 +816 805 -31972890.13727 +817 805 20929276.84229 +818 805 44576929.53758 +819 805 38361779.02511 +820 805 -74245.33508131 +821 805 -29688226.0277 +903 805 6115856.254433 +904 805 -44000691.65356 +905 805 -13552018.01794 +912 805 -7643634.032713 +913 805 -100914578.8798 +914 805 -59481123.99205 +915 805 7638888.891396 +916 805 -13999375.77193 +917 805 27304194.09764 +924 805 -7638888.891398 +925 805 -32044400.84822 +926 805 -14635369.28198 +927 805 -7646006.603371 +928 805 -25348555.65241 +929 805 -585233.2815705 +930 805 9173784.381649 +931 805 6429332.410642 +932 805 6567824.782935 +806 806 790000669.0394 +813 806 -28807854.91693 +814 806 -14527592.40022 +815 806 2281940.617786 +816 806 29067543.97844 +817 806 35319743.0838 +818 806 126505653.3816 +819 806 34818053.20388 +820 806 -19792150.68513 +821 806 -197987.5602046 +903 806 16940556.61269 +904 806 -20328027.02691 +905 806 -117335177.7428 +912 806 -21490653.15616 +913 806 -57645971.82207 +914 806 -200746134.8472 +915 806 -19488671.82916 +916 806 9380576.980452 +917 806 -143900824.6786 +924 806 -20840736.7982 +925 806 -14635369.28198 +926 806 -64147829.60048 +927 806 -48878084.71163 +928 806 -2722347.244235 +929 806 -50690307.28013 +930 806 -8209396.266123 +931 806 4378549.855291 +932 806 17144886.42838 +807 807 783245798.6586 +808 807 2.861022949219e-06 +809 807 -10648271.7332 +810 807 80258968.78408 +811 807 -4.023313522339e-07 +812 807 -2662067.934612 +822 807 -60300895.02916 +823 807 -1.370906829834e-06 +824 807 6886635.866331 +825 807 -45730271.10628 +826 807 31944444.4392 +827 807 31469922.85153 +906 807 -67815699.74408 +907 807 2.041459083557e-06 +908 807 57072469.49195 +909 807 -10820592.87768 +910 807 -7638888.891398 +911 807 7154402.099879 +918 807 -12957512.05534 +919 807 5.960464477539e-08 +920 807 -2546327.890928 +921 807 19546554.40623 +922 807 -1.84029340744e-06 +923 807 -636581.9730468 +933 807 -61096866.41184 +934 807 -1.631677150726e-06 +935 807 -54526141.60101 +936 807 -10000259.54407 +937 807 7638888.891397 +938 807 -6517820.126831 +808 808 706575078.3316 +809 808 127776294.6906 +810 808 -1.341104507446e-07 +811 808 -41129747.07642 +812 808 -65138147.34512 +823 808 80255500.90366 +824 808 31944073.6884 +825 808 31944444.4392 +826 808 -36146431.06068 +827 808 -17722036.84414 +906 808 2.004206180573e-06 +907 808 -34204373.78147 +908 808 7638794.112417 +909 808 -7638888.891398 +910 808 -8528796.673826 +911 808 7760464.058704 +918 808 2.98023223877e-08 +919 808 -31291881.67713 +920 808 30555176.43461 +921 808 -1.668930053711e-06 +922 808 -9481179.15318 +923 808 29361300.66432 +933 808 -1.691281795502e-06 +934 808 -27485540.44924 +935 808 7638794.112417 +936 808 7638888.891397 +937 808 -7708463.340222 +938 808 6996575.169565 +809 809 1171487488.319 +810 809 -2662067.934612 +811 809 -62638147.34553 +812 809 86952958.72131 +822 809 3761635.866845 +823 809 31944073.6884 +824 809 195560564.8714 +825 809 31087978.40657 +826 809 -17416481.28817 +827 809 -7301392.713971 +906 809 57454413.93615 +907 809 7638794.112417 +908 809 -95624557.03646 +909 809 7154402.099879 +910 809 7760464.058704 +911 809 -1439551.802109 +918 809 -2546327.890927 +919 809 30555176.43461 +920 809 -253876265.6798 +921 809 -636581.9730468 +922 809 29666856.21968 +923 809 21737561.15826 +933 809 -54908086.04521 +934 809 7638794.112417 +935 809 -77707668.15051 +936 809 -6517820.126831 +937 809 6996575.169565 +938 809 748003.7541653 +810 810 783245798.6586 +811 810 2.861022949219e-06 +812 810 -10648271.7332 +813 810 80258968.78408 +814 810 -4.023313522339e-07 +815 810 -2662067.934612 +822 810 -42136521.10687 +823 810 -31944444.4392 +824 810 -28425910.47196 +825 810 -60300895.02916 +826 810 -1.370906829834e-06 +827 810 6886635.866331 +828 810 -45730271.10628 +829 810 31944444.4392 +830 810 31469922.85153 +906 810 -36875280.38624 +907 810 7638888.891399 +908 810 21477318.77125 +909 810 -67815699.74408 +910 810 2.041459083557e-06 +911 810 57072469.49195 +912 810 -10820592.87768 +913 810 -7638888.891398 +914 810 7154402.099879 +918 810 -81234695.57722 +919 810 1.624226570129e-06 +920 810 -636581.9730444 +921 810 -12957512.05534 +922 810 5.960464477539e-08 +923 810 -2546327.890928 +924 810 19546554.40623 +925 810 -1.84029340744e-06 +926 810 -636581.9730468 +933 810 -34336197.05207 +934 810 -7638888.891398 +935 810 -20840736.7982 +936 810 -61096866.41184 +937 810 -1.631677150726e-06 +938 810 -54526141.60101 +939 810 -10000259.54407 +940 810 7638888.891397 +941 810 -6517820.126831 +811 811 706575078.3316 +812 811 127776294.6906 +813 811 -1.341104507446e-07 +814 811 -41129747.07642 +815 811 -65138147.34512 +822 811 -31944444.4392 +823 811 -32552681.06127 +824 811 -14222036.84425 +826 811 80255500.90366 +827 811 31944073.6884 +828 811 31944444.4392 +829 811 -36146431.06068 +830 811 -17722036.84414 +906 811 7638888.891399 +907 811 -34583484.18238 +908 811 -15399258.17112 +909 811 2.004206180573e-06 +910 811 -34204373.78147 +911 811 7638794.112417 +912 811 -7638888.891398 +913 811 -8528796.673826 +914 811 7760464.058704 +918 811 1.564621925354e-06 +919 811 -110262429.1366 +920 811 -59916477.09895 +921 811 2.98023223877e-08 +922 811 -31291881.67713 +923 811 30555176.43461 +924 811 -1.668930053711e-06 +925 811 -9481179.15318 +926 811 29361300.66432 +933 811 -7638888.891398 +934 811 -32044400.84822 +935 811 -14635369.28198 +936 811 -1.691281795502e-06 +937 811 -27485540.44924 +938 811 7638794.112417 +939 811 7638888.891397 +940 811 -7708463.340222 +941 811 6996575.169565 +812 812 1171487488.319 +813 812 -2662067.934612 +814 812 -62638147.34553 +815 812 86952958.72131 +822 812 -28807854.91693 +823 812 -14527592.40022 +824 812 2281940.617786 +825 812 3761635.866845 +826 812 31944073.6884 +827 812 195560564.8714 +828 812 31087978.40657 +829 812 -17416481.28817 +830 812 -7301392.713971 +906 812 21477318.77125 +907 812 -15399258.17112 +908 812 -70918718.4916 +909 812 57454413.93615 +910 812 7638794.112417 +911 812 -95624557.03646 +912 812 7154402.099879 +913 812 7760464.058704 +914 812 -1439551.802109 +918 812 -636581.9730439 +919 812 -60222032.6543 +920 812 -247012438.7976 +921 812 -2546327.890927 +922 812 30555176.43461 +923 812 -253876265.6798 +924 812 -636581.9730468 +925 812 29666856.21968 +926 812 21737561.15826 +933 812 -20840736.7982 +934 812 -14635369.28198 +935 812 -64147829.60048 +936 812 -54908086.04521 +937 812 7638794.112417 +938 812 -77707668.15051 +939 812 -6517820.126831 +940 812 6996575.169565 +941 812 748003.7541653 +813 813 783245798.6586 +814 813 2.861022949219e-06 +815 813 -10648271.7332 +816 813 80258968.78408 +817 813 -4.023313522339e-07 +818 813 -2662067.934612 +825 813 -42136521.10687 +826 813 -31944444.4392 +827 813 -28425910.47196 +828 813 -60300895.02916 +829 813 -1.370906829834e-06 +830 813 6886635.866331 +831 813 -45730271.10628 +832 813 31944444.4392 +833 813 31469922.85153 +909 813 -36875280.38624 +910 813 7638888.891399 +911 813 21477318.77125 +912 813 -67815699.74408 +913 813 2.041459083557e-06 +914 813 57072469.49195 +915 813 -10820592.87768 +916 813 -7638888.891398 +917 813 7154402.099879 +921 813 -81234695.57722 +922 813 1.624226570129e-06 +923 813 -636581.9730444 +924 813 -12957512.05534 +925 813 5.960464477539e-08 +926 813 -2546327.890928 +927 813 19546554.40623 +928 813 -1.84029340744e-06 +929 813 -636581.9730468 +936 813 -34336197.05207 +937 813 -7638888.891398 +938 813 -20840736.7982 +939 813 -61096866.41184 +940 813 -1.631677150726e-06 +941 813 -54526141.60101 +942 813 -10000259.54407 +943 813 7638888.891397 +944 813 -6517820.126831 +814 814 706575078.3316 +815 814 127776294.6906 +816 814 -1.341104507446e-07 +817 814 -41129747.07642 +818 814 -65138147.34512 +825 814 -31944444.4392 +826 814 -32552681.06127 +827 814 -14222036.84425 +829 814 80255500.90366 +830 814 31944073.6884 +831 814 31944444.4392 +832 814 -36146431.06068 +833 814 -17722036.84414 +909 814 7638888.891399 +910 814 -34583484.18238 +911 814 -15399258.17112 +912 814 2.004206180573e-06 +913 814 -34204373.78147 +914 814 7638794.112417 +915 814 -7638888.891398 +916 814 -8528796.673826 +917 814 7760464.058704 +921 814 1.564621925354e-06 +922 814 -110262429.1366 +923 814 -59916477.09895 +924 814 2.98023223877e-08 +925 814 -31291881.67713 +926 814 30555176.43461 +927 814 -1.668930053711e-06 +928 814 -9481179.15318 +929 814 29361300.66432 +936 814 -7638888.891398 +937 814 -32044400.84822 +938 814 -14635369.28198 +939 814 -1.691281795502e-06 +940 814 -27485540.44924 +941 814 7638794.112417 +942 814 7638888.891397 +943 814 -7708463.340222 +944 814 6996575.169565 +815 815 1171487488.319 +816 815 -2662067.934612 +817 815 -62638147.34553 +818 815 86952958.72131 +825 815 -28807854.91693 +826 815 -14527592.40022 +827 815 2281940.617786 +828 815 3761635.866845 +829 815 31944073.6884 +830 815 195560564.8714 +831 815 31087978.40657 +832 815 -17416481.28817 +833 815 -7301392.713971 +909 815 21477318.77125 +910 815 -15399258.17112 +911 815 -70918718.4916 +912 815 57454413.93615 +913 815 7638794.112417 +914 815 -95624557.03646 +915 815 7154402.099879 +916 815 7760464.058704 +917 815 -1439551.802109 +921 815 -636581.9730439 +922 815 -60222032.6543 +923 815 -247012438.7976 +924 815 -2546327.890927 +925 815 30555176.43461 +926 815 -253876265.6798 +927 815 -636581.9730468 +928 815 29666856.21968 +929 815 21737561.15826 +936 815 -20840736.7982 +937 815 -14635369.28198 +938 815 -64147829.60048 +939 815 -54908086.04521 +940 815 7638794.112417 +941 815 -77707668.15051 +942 815 -6517820.126831 +943 815 6996575.169565 +944 815 748003.7541653 +816 816 798779840.2986 +817 816 31991853.93598 +818 816 -35934840.90099 +819 816 33796428.38625 +820 816 -31963408.23791 +821 816 -31487513.88132 +828 816 -42136521.10687 +829 816 -31944444.4392 +830 816 -28425910.47196 +831 816 -60300895.02916 +832 816 -1.370906829834e-06 +833 816 6886635.866331 +834 816 -45730271.10628 +835 816 31944444.4392 +836 816 31469922.85153 +912 816 -36875280.38624 +913 816 7638888.891399 +914 816 21477318.77125 +915 816 -88160408.62987 +916 816 -7646006.603366 +917 816 63145912.64445 +924 816 -81234695.57722 +925 816 1.624226570129e-06 +926 816 -636581.9730444 +927 816 3615653.321898 +928 816 7650751.744684 +929 816 -8598044.452827 +930 816 3117023.124192 +931 816 -7643634.032712 +932 816 6521862.080229 +939 816 -34336197.05207 +940 816 -7638888.891398 +941 816 -20840736.7982 +942 816 -61096866.41184 +943 816 -1.631677150726e-06 +944 816 -54526141.60101 +945 816 -10000259.54407 +946 816 7638888.891397 +947 816 -6517820.126831 +817 817 712503944.5236 +818 817 99028842.16786 +819 817 -31972890.13727 +820 817 -78046374.58557 +821 817 -54292558.27614 +828 817 -31944444.4392 +829 817 -32552681.06127 +830 817 -14222036.84425 +832 817 80255500.90366 +833 817 31944073.6884 +834 817 31944444.4392 +835 817 -36146431.06068 +836 817 -17722036.84414 +912 817 7638888.891399 +913 817 -34583484.18238 +914 817 -15399258.17112 +915 817 -7643634.032709 +916 817 -52242457.71267 +917 817 19687387.29713 +924 817 1.564621925354e-06 +925 817 -110262429.1366 +926 817 -59916477.09895 +927 817 7650751.744683 +928 817 -17015851.08971 +929 817 23676848.33746 +930 817 -7646006.603369 +931 817 -23628404.39615 +932 817 31972114.21773 +939 817 -7638888.891398 +940 817 -32044400.84822 +941 817 -14635369.28198 +942 817 -1.691281795502e-06 +943 817 -27485540.44924 +944 817 7638794.112417 +945 817 7638888.891397 +946 817 -7708463.340222 +947 817 6996575.169565 +818 818 1098010379.249 +819 818 -31114364.95125 +820 818 -60743490.00346 +821 818 77736775.05345 +828 818 -28807854.91693 +829 818 -14527592.40022 +830 818 2281940.617786 +831 818 3761635.866845 +832 818 31944073.6884 +833 818 195560564.8714 +834 818 31087978.40657 +835 818 -17416481.28817 +836 818 -7301392.713971 +912 818 21477318.77125 +913 818 -15399258.17112 +914 818 -70918718.4916 +915 818 63530032.02016 +916 818 21831451.86013 +917 818 -122407379.4408 +924 818 -636581.9730439 +925 818 -60222032.6543 +926 818 -247012438.7976 +927 818 -8589356.089042 +928 818 23683798.94222 +929 818 -237160382.7964 +930 818 6523883.056929 +931 818 30136961.89646 +932 818 5350330.44263 +939 818 -20840736.7982 +940 818 -14635369.28198 +941 818 -64147829.60048 +942 818 -54908086.04521 +943 818 7638794.112417 +944 818 -77707668.15051 +945 818 -6517820.126831 +946 818 6996575.169565 +947 818 748003.7541653 +819 819 511307203.7006 +820 819 31944444.4392 +821 819 -38471552.3926 +831 819 -42136521.10687 +832 819 -31944444.4392 +833 819 -28425910.47196 +834 819 -129270221.6954 +835 819 -31963408.23791 +836 819 32202213.44983 +837 819 -74245.33507569 +838 819 25574519.35007 +839 819 23212035.46926 +915 819 -44000691.65356 +916 819 9173784.381649 +917 819 25410834.91903 +927 819 -74169151.35949 +928 819 -7646006.603371 +929 819 -21497320.34861 +930 819 -2535056.171221 +931 819 7638888.891397 +932 819 2916127.642058 +942 819 -34336197.05207 +943 819 -7638888.891398 +944 819 -20840736.7982 +945 819 -61266506.56961 +946 819 -7643634.032713 +947 819 -48493965.33591 +948 819 6429332.410642 +949 819 6115856.254433 +950 819 -5472930.844082 +820 820 463366668.0891 +821 820 73645353.45811 +831 820 -31944444.4392 +832 820 -32552681.06127 +833 820 -14222036.84425 +834 820 -31972890.13727 +835 820 20929276.84229 +836 820 44576929.53758 +837 820 38361779.02511 +838 820 -74245.33508131 +839 820 -29688226.0277 +915 820 6115856.254433 +916 820 -44000691.65356 +917 820 -13552018.01794 +927 820 -7643634.032713 +928 820 -100914578.8798 +929 820 -59481123.99205 +930 820 7638888.891396 +931 820 -13999375.77193 +932 820 27304194.09764 +942 820 -7638888.891398 +943 820 -32044400.84822 +944 820 -14635369.28198 +945 820 -7646006.603371 +946 820 -25348555.65241 +947 820 -585233.2815705 +948 820 9173784.381649 +949 820 6429332.410642 +950 820 6567824.782935 +821 821 790000669.0394 +831 821 -28807854.91693 +832 821 -14527592.40022 +833 821 2281940.617786 +834 821 29067543.97844 +835 821 35319743.0838 +836 821 126505653.3816 +837 821 34818053.20388 +838 821 -19792150.68513 +839 821 -197987.5602046 +915 821 16940556.61269 +916 821 -20328027.02691 +917 821 -117335177.7428 +927 821 -21490653.15616 +928 821 -57645971.82207 +929 821 -200746134.8472 +930 821 -19488671.82916 +931 821 9380576.980452 +932 821 -143900824.6786 +942 821 -20840736.7982 +943 821 -14635369.28198 +944 821 -64147829.60048 +945 821 -48878084.71163 +946 821 -2722347.244235 +947 821 -50690307.28013 +948 821 -8209396.266123 +949 821 4378549.855291 +950 821 17144886.42838 +822 822 783245798.6586 +823 822 2.861022949219e-06 +824 822 -10648271.7332 +825 822 80258968.78408 +826 822 -4.023313522339e-07 +827 822 -2662067.934612 +840 822 -60300895.02916 +841 822 -1.370906829834e-06 +842 822 6886635.866331 +843 822 -45730271.10628 +844 822 31944444.4392 +845 822 31469922.85153 +918 822 -67815699.74408 +919 822 2.041459083557e-06 +920 822 57072469.49195 +921 822 -10820592.87768 +922 822 -7638888.891398 +923 822 7154402.099879 +933 822 -12957512.05534 +934 822 5.960464477539e-08 +935 822 -2546327.890928 +936 822 19546554.40623 +937 822 -1.84029340744e-06 +938 822 -636581.9730468 +951 822 -61096866.41184 +952 822 -1.631677150726e-06 +953 822 -54526141.60101 +954 822 -10000259.54407 +955 822 7638888.891397 +956 822 -6517820.126831 +823 823 706575078.3316 +824 823 127776294.6906 +825 823 -1.341104507446e-07 +826 823 -41129747.07642 +827 823 -65138147.34512 +841 823 80255500.90366 +842 823 31944073.6884 +843 823 31944444.4392 +844 823 -36146431.06068 +845 823 -17722036.84414 +918 823 2.004206180573e-06 +919 823 -34204373.78147 +920 823 7638794.112417 +921 823 -7638888.891398 +922 823 -8528796.673826 +923 823 7760464.058704 +933 823 2.98023223877e-08 +934 823 -31291881.67713 +935 823 30555176.43461 +936 823 -1.668930053711e-06 +937 823 -9481179.15318 +938 823 29361300.66432 +951 823 -1.691281795502e-06 +952 823 -27485540.44924 +953 823 7638794.112417 +954 823 7638888.891397 +955 823 -7708463.340222 +956 823 6996575.169565 +824 824 1171487488.319 +825 824 -2662067.934612 +826 824 -62638147.34553 +827 824 86952958.72131 +840 824 3761635.866845 +841 824 31944073.6884 +842 824 195560564.8714 +843 824 31087978.40657 +844 824 -17416481.28817 +845 824 -7301392.713971 +918 824 57454413.93615 +919 824 7638794.112417 +920 824 -95624557.03646 +921 824 7154402.099879 +922 824 7760464.058704 +923 824 -1439551.802109 +933 824 -2546327.890927 +934 824 30555176.43461 +935 824 -253876265.6798 +936 824 -636581.9730468 +937 824 29666856.21968 +938 824 21737561.15826 +951 824 -54908086.04521 +952 824 7638794.112417 +953 824 -77707668.15051 +954 824 -6517820.126831 +955 824 6996575.169565 +956 824 748003.7541653 +825 825 783245798.6586 +826 825 2.861022949219e-06 +827 825 -10648271.7332 +828 825 80258968.78408 +829 825 -4.023313522339e-07 +830 825 -2662067.934612 +840 825 -42136521.10687 +841 825 -31944444.4392 +842 825 -28425910.47196 +843 825 -60300895.02916 +844 825 -1.370906829834e-06 +845 825 6886635.866331 +846 825 -45730271.10628 +847 825 31944444.4392 +848 825 31469922.85153 +918 825 -36875280.38624 +919 825 7638888.891399 +920 825 21477318.77125 +921 825 -67815699.74408 +922 825 2.041459083557e-06 +923 825 57072469.49195 +924 825 -10820592.87768 +925 825 -7638888.891398 +926 825 7154402.099879 +933 825 -81234695.57722 +934 825 1.624226570129e-06 +935 825 -636581.9730444 +936 825 -12957512.05534 +937 825 5.960464477539e-08 +938 825 -2546327.890928 +939 825 19546554.40623 +940 825 -1.84029340744e-06 +941 825 -636581.9730468 +951 825 -34336197.05207 +952 825 -7638888.891398 +953 825 -20840736.7982 +954 825 -61096866.41184 +955 825 -1.631677150726e-06 +956 825 -54526141.60101 +957 825 -10000259.54407 +958 825 7638888.891397 +959 825 -6517820.126831 +826 826 706575078.3316 +827 826 127776294.6906 +828 826 -1.341104507446e-07 +829 826 -41129747.07642 +830 826 -65138147.34512 +840 826 -31944444.4392 +841 826 -32552681.06127 +842 826 -14222036.84425 +844 826 80255500.90366 +845 826 31944073.6884 +846 826 31944444.4392 +847 826 -36146431.06068 +848 826 -17722036.84414 +918 826 7638888.891399 +919 826 -34583484.18238 +920 826 -15399258.17112 +921 826 2.004206180573e-06 +922 826 -34204373.78147 +923 826 7638794.112417 +924 826 -7638888.891398 +925 826 -8528796.673826 +926 826 7760464.058704 +933 826 1.564621925354e-06 +934 826 -110262429.1366 +935 826 -59916477.09895 +936 826 2.98023223877e-08 +937 826 -31291881.67713 +938 826 30555176.43461 +939 826 -1.668930053711e-06 +940 826 -9481179.15318 +941 826 29361300.66432 +951 826 -7638888.891398 +952 826 -32044400.84822 +953 826 -14635369.28198 +954 826 -1.691281795502e-06 +955 826 -27485540.44924 +956 826 7638794.112417 +957 826 7638888.891397 +958 826 -7708463.340222 +959 826 6996575.169565 +827 827 1171487488.319 +828 827 -2662067.934612 +829 827 -62638147.34553 +830 827 86952958.72131 +840 827 -28807854.91693 +841 827 -14527592.40022 +842 827 2281940.617786 +843 827 3761635.866845 +844 827 31944073.6884 +845 827 195560564.8714 +846 827 31087978.40657 +847 827 -17416481.28817 +848 827 -7301392.713971 +918 827 21477318.77125 +919 827 -15399258.17112 +920 827 -70918718.4916 +921 827 57454413.93615 +922 827 7638794.112417 +923 827 -95624557.03646 +924 827 7154402.099879 +925 827 7760464.058704 +926 827 -1439551.802109 +933 827 -636581.9730439 +934 827 -60222032.6543 +935 827 -247012438.7976 +936 827 -2546327.890927 +937 827 30555176.43461 +938 827 -253876265.6798 +939 827 -636581.9730468 +940 827 29666856.21968 +941 827 21737561.15826 +951 827 -20840736.7982 +952 827 -14635369.28198 +953 827 -64147829.60048 +954 827 -54908086.04521 +955 827 7638794.112417 +956 827 -77707668.15051 +957 827 -6517820.126831 +958 827 6996575.169565 +959 827 748003.7541653 +828 828 783245798.6586 +829 828 2.861022949219e-06 +830 828 -10648271.7332 +831 828 80258968.78408 +832 828 -4.023313522339e-07 +833 828 -2662067.934612 +843 828 -42136521.10687 +844 828 -31944444.4392 +845 828 -28425910.47196 +846 828 -60300895.02916 +847 828 -1.370906829834e-06 +848 828 6886635.866331 +849 828 -45730271.10628 +850 828 31944444.4392 +851 828 31469922.85153 +921 828 -36875280.38624 +922 828 7638888.891399 +923 828 21477318.77125 +924 828 -67815699.74408 +925 828 2.041459083557e-06 +926 828 57072469.49195 +927 828 -10820592.87768 +928 828 -7638888.891398 +929 828 7154402.099879 +936 828 -81234695.57722 +937 828 1.624226570129e-06 +938 828 -636581.9730444 +939 828 -12957512.05534 +940 828 5.960464477539e-08 +941 828 -2546327.890928 +942 828 19546554.40623 +943 828 -1.84029340744e-06 +944 828 -636581.9730468 +954 828 -34336197.05207 +955 828 -7638888.891398 +956 828 -20840736.7982 +957 828 -61096866.41184 +958 828 -1.631677150726e-06 +959 828 -54526141.60101 +960 828 -10000259.54407 +961 828 7638888.891397 +962 828 -6517820.126831 +829 829 706575078.3316 +830 829 127776294.6906 +831 829 -1.341104507446e-07 +832 829 -41129747.07642 +833 829 -65138147.34512 +843 829 -31944444.4392 +844 829 -32552681.06127 +845 829 -14222036.84425 +847 829 80255500.90366 +848 829 31944073.6884 +849 829 31944444.4392 +850 829 -36146431.06068 +851 829 -17722036.84414 +921 829 7638888.891399 +922 829 -34583484.18238 +923 829 -15399258.17112 +924 829 2.004206180573e-06 +925 829 -34204373.78147 +926 829 7638794.112417 +927 829 -7638888.891398 +928 829 -8528796.673826 +929 829 7760464.058704 +936 829 1.564621925354e-06 +937 829 -110262429.1366 +938 829 -59916477.09895 +939 829 2.98023223877e-08 +940 829 -31291881.67713 +941 829 30555176.43461 +942 829 -1.668930053711e-06 +943 829 -9481179.15318 +944 829 29361300.66432 +954 829 -7638888.891398 +955 829 -32044400.84822 +956 829 -14635369.28198 +957 829 -1.691281795502e-06 +958 829 -27485540.44924 +959 829 7638794.112417 +960 829 7638888.891397 +961 829 -7708463.340222 +962 829 6996575.169565 +830 830 1171487488.319 +831 830 -2662067.934612 +832 830 -62638147.34553 +833 830 86952958.72131 +843 830 -28807854.91693 +844 830 -14527592.40022 +845 830 2281940.617786 +846 830 3761635.866845 +847 830 31944073.6884 +848 830 195560564.8714 +849 830 31087978.40657 +850 830 -17416481.28817 +851 830 -7301392.713971 +921 830 21477318.77125 +922 830 -15399258.17112 +923 830 -70918718.4916 +924 830 57454413.93615 +925 830 7638794.112417 +926 830 -95624557.03646 +927 830 7154402.099879 +928 830 7760464.058704 +929 830 -1439551.802109 +936 830 -636581.9730439 +937 830 -60222032.6543 +938 830 -247012438.7976 +939 830 -2546327.890927 +940 830 30555176.43461 +941 830 -253876265.6798 +942 830 -636581.9730468 +943 830 29666856.21968 +944 830 21737561.15826 +954 830 -20840736.7982 +955 830 -14635369.28198 +956 830 -64147829.60048 +957 830 -54908086.04521 +958 830 7638794.112417 +959 830 -77707668.15051 +960 830 -6517820.126831 +961 830 6996575.169565 +962 830 748003.7541653 +831 831 783245798.6586 +832 831 2.861022949219e-06 +833 831 -10648271.7332 +834 831 80258968.78408 +835 831 -4.023313522339e-07 +836 831 -2662067.934612 +846 831 -42136521.10687 +847 831 -31944444.4392 +848 831 -28425910.47196 +849 831 -60300895.02916 +850 831 -1.370906829834e-06 +851 831 6886635.866331 +852 831 -45730271.10628 +853 831 31944444.4392 +854 831 31469922.85153 +924 831 -36875280.38624 +925 831 7638888.891399 +926 831 21477318.77125 +927 831 -67815699.74408 +928 831 2.041459083557e-06 +929 831 57072469.49195 +930 831 -10820592.87768 +931 831 -7638888.891398 +932 831 7154402.099879 +939 831 -81234695.57722 +940 831 1.624226570129e-06 +941 831 -636581.9730444 +942 831 -12957512.05534 +943 831 5.960464477539e-08 +944 831 -2546327.890928 +945 831 19546554.40623 +946 831 -1.84029340744e-06 +947 831 -636581.9730468 +957 831 -34336197.05207 +958 831 -7638888.891398 +959 831 -20840736.7982 +960 831 -61096866.41184 +961 831 -1.631677150726e-06 +962 831 -54526141.60101 +963 831 -10000259.54407 +964 831 7638888.891397 +965 831 -6517820.126831 +832 832 706575078.3316 +833 832 127776294.6906 +834 832 -1.341104507446e-07 +835 832 -41129747.07642 +836 832 -65138147.34512 +846 832 -31944444.4392 +847 832 -32552681.06127 +848 832 -14222036.84425 +850 832 80255500.90366 +851 832 31944073.6884 +852 832 31944444.4392 +853 832 -36146431.06068 +854 832 -17722036.84414 +924 832 7638888.891399 +925 832 -34583484.18238 +926 832 -15399258.17112 +927 832 2.004206180573e-06 +928 832 -34204373.78147 +929 832 7638794.112417 +930 832 -7638888.891398 +931 832 -8528796.673826 +932 832 7760464.058704 +939 832 1.564621925354e-06 +940 832 -110262429.1366 +941 832 -59916477.09895 +942 832 2.98023223877e-08 +943 832 -31291881.67713 +944 832 30555176.43461 +945 832 -1.668930053711e-06 +946 832 -9481179.15318 +947 832 29361300.66432 +957 832 -7638888.891398 +958 832 -32044400.84822 +959 832 -14635369.28198 +960 832 -1.691281795502e-06 +961 832 -27485540.44924 +962 832 7638794.112417 +963 832 7638888.891397 +964 832 -7708463.340222 +965 832 6996575.169565 +833 833 1171487488.319 +834 833 -2662067.934612 +835 833 -62638147.34553 +836 833 86952958.72131 +846 833 -28807854.91693 +847 833 -14527592.40022 +848 833 2281940.617786 +849 833 3761635.866845 +850 833 31944073.6884 +851 833 195560564.8714 +852 833 31087978.40657 +853 833 -17416481.28817 +854 833 -7301392.713971 +924 833 21477318.77125 +925 833 -15399258.17112 +926 833 -70918718.4916 +927 833 57454413.93615 +928 833 7638794.112417 +929 833 -95624557.03646 +930 833 7154402.099879 +931 833 7760464.058704 +932 833 -1439551.802109 +939 833 -636581.9730439 +940 833 -60222032.6543 +941 833 -247012438.7976 +942 833 -2546327.890927 +943 833 30555176.43461 +944 833 -253876265.6798 +945 833 -636581.9730468 +946 833 29666856.21968 +947 833 21737561.15826 +957 833 -20840736.7982 +958 833 -14635369.28198 +959 833 -64147829.60048 +960 833 -54908086.04521 +961 833 7638794.112417 +962 833 -77707668.15051 +963 833 -6517820.126831 +964 833 6996575.169565 +965 833 748003.7541653 +834 834 798779840.2986 +835 834 31991853.93598 +836 834 -35934840.90099 +837 834 33796428.38625 +838 834 -31963408.23791 +839 834 -31487513.88132 +849 834 -42136521.10687 +850 834 -31944444.4392 +851 834 -28425910.47196 +852 834 -60300895.02916 +853 834 -1.370906829834e-06 +854 834 6886635.866331 +855 834 -45730271.10628 +856 834 31944444.4392 +857 834 31469922.85153 +927 834 -36875280.38624 +928 834 7638888.891399 +929 834 21477318.77125 +930 834 -88160408.62987 +931 834 -7646006.603366 +932 834 63145912.64445 +942 834 -81234695.57722 +943 834 1.624226570129e-06 +944 834 -636581.9730444 +945 834 3615653.321898 +946 834 7650751.744684 +947 834 -8598044.452827 +948 834 3117023.124192 +949 834 -7643634.032712 +950 834 6521862.080229 +960 834 -34336197.05207 +961 834 -7638888.891398 +962 834 -20840736.7982 +963 834 -61096866.41184 +964 834 -1.631677150726e-06 +965 834 -54526141.60101 +966 834 -10000259.54407 +967 834 7638888.891397 +968 834 -6517820.126831 +835 835 712503944.5236 +836 835 99028842.16786 +837 835 -31972890.13727 +838 835 -78046374.58557 +839 835 -54292558.27614 +849 835 -31944444.4392 +850 835 -32552681.06127 +851 835 -14222036.84425 +853 835 80255500.90366 +854 835 31944073.6884 +855 835 31944444.4392 +856 835 -36146431.06068 +857 835 -17722036.84414 +927 835 7638888.891399 +928 835 -34583484.18238 +929 835 -15399258.17112 +930 835 -7643634.032709 +931 835 -52242457.71267 +932 835 19687387.29713 +942 835 1.564621925354e-06 +943 835 -110262429.1366 +944 835 -59916477.09895 +945 835 7650751.744683 +946 835 -17015851.08971 +947 835 23676848.33746 +948 835 -7646006.603369 +949 835 -23628404.39615 +950 835 31972114.21773 +960 835 -7638888.891398 +961 835 -32044400.84822 +962 835 -14635369.28198 +963 835 -1.691281795502e-06 +964 835 -27485540.44924 +965 835 7638794.112417 +966 835 7638888.891397 +967 835 -7708463.340222 +968 835 6996575.169565 +836 836 1098010379.249 +837 836 -31114364.95125 +838 836 -60743490.00346 +839 836 77736775.05345 +849 836 -28807854.91693 +850 836 -14527592.40022 +851 836 2281940.617786 +852 836 3761635.866845 +853 836 31944073.6884 +854 836 195560564.8714 +855 836 31087978.40657 +856 836 -17416481.28817 +857 836 -7301392.713971 +927 836 21477318.77125 +928 836 -15399258.17112 +929 836 -70918718.4916 +930 836 63530032.02016 +931 836 21831451.86013 +932 836 -122407379.4408 +942 836 -636581.9730439 +943 836 -60222032.6543 +944 836 -247012438.7976 +945 836 -8589356.089042 +946 836 23683798.94222 +947 836 -237160382.7964 +948 836 6523883.056929 +949 836 30136961.89646 +950 836 5350330.44263 +960 836 -20840736.7982 +961 836 -14635369.28198 +962 836 -64147829.60048 +963 836 -54908086.04521 +964 836 7638794.112417 +965 836 -77707668.15051 +966 836 -6517820.126831 +967 836 6996575.169565 +968 836 748003.7541653 +837 837 421581687.6543 +838 837 6785907.782109 +839 837 7841193.266554 +852 837 -42136521.10687 +853 837 -31944444.4392 +854 837 -28425910.47196 +855 837 -79796686.86909 +856 837 -6849309.631483 +857 837 3534798.038794 +858 837 -5594967.08466 +859 837 25618957.40074 +860 837 1676068.417707 +930 837 -44000691.65356 +931 837 9173784.381649 +932 837 25410834.91903 +945 837 -74169151.35949 +946 837 -7646006.603371 +947 837 -21497320.34861 +948 837 -8042181.826519 +949 837 145867.1889037 +950 837 11655806.43098 +963 837 -34336197.05207 +964 837 -7638888.891398 +965 837 -20840736.7982 +966 837 -46993816.04493 +967 837 -164542.081198 +968 837 -41727721.81694 +969 837 -9829239.428922 +970 837 6129786.005412 +971 837 -4979066.640203 +838 838 419099416.1247 +839 838 75912796.59245 +852 838 -31944444.4392 +853 838 -32552681.06127 +854 838 -14222036.84425 +855 838 -6881010.556171 +856 838 59218360.02186 +857 838 21640366.11732 +858 838 38428436.1011 +859 838 -39868779.51983 +860 838 -12146433.61666 +930 838 6115856.254433 +931 838 -44000691.65356 +932 838 -13552018.01794 +945 838 -7643634.032713 +946 838 -100914578.8798 +947 838 -59481123.99205 +948 838 145867.1889033 +949 838 -4368145.660696 +950 838 26571164.39647 +963 838 -7638888.891398 +964 838 -32044400.84822 +965 838 -14635369.28198 +966 838 -173879.5273452 +967 838 -14404613.18541 +968 838 4846854.379944 +969 838 9194679.008118 +970 838 -21638847.13778 +971 838 14725306.89276 +839 839 651397439.371 +852 839 -28807854.91693 +853 839 -14527592.40022 +854 839 2281940.617786 +855 839 9222793.691471 +856 839 19439582.74236 +857 839 123496454.0281 +858 839 2514102.62656 +859 839 -10870425.29035 +860 839 19353900.20941 +930 839 16940556.61269 +931 839 -20328027.02691 +932 839 -117335177.7428 +945 839 -21490653.15616 +946 839 -57645971.82207 +947 839 -200746134.8472 +948 839 -5288514.808431 +949 839 13035968.8684 +950 839 -130215372.7727 +963 839 -20840736.7982 +964 839 -14635369.28198 +965 839 -64147829.60048 +966 839 -39819358.2705 +967 839 4553577.796946 +968 839 -52810527.24323 +969 839 -7468599.960305 +970 839 12732043.03141 +971 839 -14401697.43494 +840 840 783245798.6586 +841 840 2.861022949219e-06 +842 840 -10648271.7332 +843 840 80258968.78408 +844 840 -4.023313522339e-07 +845 840 -2662067.934612 +861 840 -60300895.02916 +862 840 -1.370906829834e-06 +863 840 6886635.866331 +864 840 -45730271.10628 +865 840 31944444.4392 +866 840 31469922.85153 +933 840 -67815699.74408 +934 840 2.041459083557e-06 +935 840 57072469.49195 +936 840 -10820592.87768 +937 840 -7638888.891398 +938 840 7154402.099879 +951 840 -12957512.05534 +952 840 5.960464477539e-08 +953 840 -2546327.890928 +954 840 19546554.40623 +955 840 -1.84029340744e-06 +956 840 -636581.9730468 +972 840 -61096866.41184 +973 840 -1.631677150726e-06 +974 840 -54526141.60101 +975 840 -10000259.54407 +976 840 7638888.891397 +977 840 -6517820.126831 +841 841 706575078.3316 +842 841 127776294.6906 +843 841 -1.341104507446e-07 +844 841 -41129747.07642 +845 841 -65138147.34512 +862 841 80255500.90366 +863 841 31944073.6884 +864 841 31944444.4392 +865 841 -36146431.06068 +866 841 -17722036.84414 +933 841 2.004206180573e-06 +934 841 -34204373.78147 +935 841 7638794.112417 +936 841 -7638888.891398 +937 841 -8528796.673826 +938 841 7760464.058704 +951 841 2.98023223877e-08 +952 841 -31291881.67713 +953 841 30555176.43461 +954 841 -1.668930053711e-06 +955 841 -9481179.15318 +956 841 29361300.66432 +972 841 -1.691281795502e-06 +973 841 -27485540.44924 +974 841 7638794.112417 +975 841 7638888.891397 +976 841 -7708463.340222 +977 841 6996575.169565 +842 842 1171487488.319 +843 842 -2662067.934612 +844 842 -62638147.34553 +845 842 86952958.72131 +861 842 3761635.866845 +862 842 31944073.6884 +863 842 195560564.8714 +864 842 31087978.40657 +865 842 -17416481.28817 +866 842 -7301392.713971 +933 842 57454413.93615 +934 842 7638794.112417 +935 842 -95624557.03646 +936 842 7154402.099879 +937 842 7760464.058704 +938 842 -1439551.802109 +951 842 -2546327.890927 +952 842 30555176.43461 +953 842 -253876265.6798 +954 842 -636581.9730468 +955 842 29666856.21968 +956 842 21737561.15826 +972 842 -54908086.04521 +973 842 7638794.112417 +974 842 -77707668.15051 +975 842 -6517820.126831 +976 842 6996575.169565 +977 842 748003.7541653 +843 843 783245798.6586 +844 843 2.861022949219e-06 +845 843 -10648271.7332 +846 843 80258968.78408 +847 843 -4.023313522339e-07 +848 843 -2662067.934612 +861 843 -42136521.10687 +862 843 -31944444.4392 +863 843 -28425910.47196 +864 843 -60300895.02916 +865 843 -1.370906829834e-06 +866 843 6886635.866331 +867 843 -45730271.10628 +868 843 31944444.4392 +869 843 31469922.85153 +933 843 -36875280.38624 +934 843 7638888.891399 +935 843 21477318.77125 +936 843 -67815699.74408 +937 843 2.041459083557e-06 +938 843 57072469.49195 +939 843 -10820592.87768 +940 843 -7638888.891398 +941 843 7154402.099879 +951 843 -81234695.57722 +952 843 1.624226570129e-06 +953 843 -636581.9730444 +954 843 -12957512.05534 +955 843 5.960464477539e-08 +956 843 -2546327.890928 +957 843 19546554.40623 +958 843 -1.84029340744e-06 +959 843 -636581.9730468 +972 843 -34336197.05207 +973 843 -7638888.891398 +974 843 -20840736.7982 +975 843 -61096866.41184 +976 843 -1.631677150726e-06 +977 843 -54526141.60101 +978 843 -10000259.54407 +979 843 7638888.891397 +980 843 -6517820.126831 +844 844 706575078.3316 +845 844 127776294.6906 +846 844 -1.341104507446e-07 +847 844 -41129747.07642 +848 844 -65138147.34512 +861 844 -31944444.4392 +862 844 -32552681.06127 +863 844 -14222036.84425 +865 844 80255500.90366 +866 844 31944073.6884 +867 844 31944444.4392 +868 844 -36146431.06068 +869 844 -17722036.84414 +933 844 7638888.891399 +934 844 -34583484.18238 +935 844 -15399258.17112 +936 844 2.004206180573e-06 +937 844 -34204373.78147 +938 844 7638794.112417 +939 844 -7638888.891398 +940 844 -8528796.673826 +941 844 7760464.058704 +951 844 1.564621925354e-06 +952 844 -110262429.1366 +953 844 -59916477.09895 +954 844 2.98023223877e-08 +955 844 -31291881.67713 +956 844 30555176.43461 +957 844 -1.668930053711e-06 +958 844 -9481179.15318 +959 844 29361300.66432 +972 844 -7638888.891398 +973 844 -32044400.84822 +974 844 -14635369.28198 +975 844 -1.691281795502e-06 +976 844 -27485540.44924 +977 844 7638794.112417 +978 844 7638888.891397 +979 844 -7708463.340222 +980 844 6996575.169565 +845 845 1171487488.319 +846 845 -2662067.934612 +847 845 -62638147.34553 +848 845 86952958.72131 +861 845 -28807854.91693 +862 845 -14527592.40022 +863 845 2281940.617786 +864 845 3761635.866845 +865 845 31944073.6884 +866 845 195560564.8714 +867 845 31087978.40657 +868 845 -17416481.28817 +869 845 -7301392.713971 +933 845 21477318.77125 +934 845 -15399258.17112 +935 845 -70918718.4916 +936 845 57454413.93615 +937 845 7638794.112417 +938 845 -95624557.03646 +939 845 7154402.099879 +940 845 7760464.058704 +941 845 -1439551.802109 +951 845 -636581.9730439 +952 845 -60222032.6543 +953 845 -247012438.7976 +954 845 -2546327.890927 +955 845 30555176.43461 +956 845 -253876265.6798 +957 845 -636581.9730468 +958 845 29666856.21968 +959 845 21737561.15826 +972 845 -20840736.7982 +973 845 -14635369.28198 +974 845 -64147829.60048 +975 845 -54908086.04521 +976 845 7638794.112417 +977 845 -77707668.15051 +978 845 -6517820.126831 +979 845 6996575.169565 +980 845 748003.7541653 +846 846 783245798.6586 +847 846 2.861022949219e-06 +848 846 -10648271.7332 +849 846 80258968.78408 +850 846 -4.023313522339e-07 +851 846 -2662067.934612 +864 846 -42136521.10687 +865 846 -31944444.4392 +866 846 -28425910.47196 +867 846 -60300895.02916 +868 846 -1.370906829834e-06 +869 846 6886635.866331 +870 846 -45730271.10628 +871 846 31944444.4392 +872 846 31469922.85153 +936 846 -36875280.38624 +937 846 7638888.891399 +938 846 21477318.77125 +939 846 -67815699.74408 +940 846 2.041459083557e-06 +941 846 57072469.49195 +942 846 -10820592.87768 +943 846 -7638888.891398 +944 846 7154402.099879 +954 846 -81234695.57722 +955 846 1.624226570129e-06 +956 846 -636581.9730444 +957 846 -12957512.05534 +958 846 5.960464477539e-08 +959 846 -2546327.890928 +960 846 19546554.40623 +961 846 -1.84029340744e-06 +962 846 -636581.9730468 +975 846 -34336197.05207 +976 846 -7638888.891398 +977 846 -20840736.7982 +978 846 -61096866.41184 +979 846 -1.631677150726e-06 +980 846 -54526141.60101 +981 846 -10000259.54407 +982 846 7638888.891397 +983 846 -6517820.126831 +847 847 706575078.3316 +848 847 127776294.6906 +849 847 -1.341104507446e-07 +850 847 -41129747.07642 +851 847 -65138147.34512 +864 847 -31944444.4392 +865 847 -32552681.06127 +866 847 -14222036.84425 +868 847 80255500.90366 +869 847 31944073.6884 +870 847 31944444.4392 +871 847 -36146431.06068 +872 847 -17722036.84414 +936 847 7638888.891399 +937 847 -34583484.18238 +938 847 -15399258.17112 +939 847 2.004206180573e-06 +940 847 -34204373.78147 +941 847 7638794.112417 +942 847 -7638888.891398 +943 847 -8528796.673826 +944 847 7760464.058704 +954 847 1.564621925354e-06 +955 847 -110262429.1366 +956 847 -59916477.09895 +957 847 2.98023223877e-08 +958 847 -31291881.67713 +959 847 30555176.43461 +960 847 -1.668930053711e-06 +961 847 -9481179.15318 +962 847 29361300.66432 +975 847 -7638888.891398 +976 847 -32044400.84822 +977 847 -14635369.28198 +978 847 -1.691281795502e-06 +979 847 -27485540.44924 +980 847 7638794.112417 +981 847 7638888.891397 +982 847 -7708463.340222 +983 847 6996575.169565 +848 848 1171487488.319 +849 848 -2662067.934612 +850 848 -62638147.34553 +851 848 86952958.72131 +864 848 -28807854.91693 +865 848 -14527592.40022 +866 848 2281940.617786 +867 848 3761635.866845 +868 848 31944073.6884 +869 848 195560564.8714 +870 848 31087978.40657 +871 848 -17416481.28817 +872 848 -7301392.713971 +936 848 21477318.77125 +937 848 -15399258.17112 +938 848 -70918718.4916 +939 848 57454413.93615 +940 848 7638794.112417 +941 848 -95624557.03646 +942 848 7154402.099879 +943 848 7760464.058704 +944 848 -1439551.802109 +954 848 -636581.9730439 +955 848 -60222032.6543 +956 848 -247012438.7976 +957 848 -2546327.890927 +958 848 30555176.43461 +959 848 -253876265.6798 +960 848 -636581.9730468 +961 848 29666856.21968 +962 848 21737561.15826 +975 848 -20840736.7982 +976 848 -14635369.28198 +977 848 -64147829.60048 +978 848 -54908086.04521 +979 848 7638794.112417 +980 848 -77707668.15051 +981 848 -6517820.126831 +982 848 6996575.169565 +983 848 748003.7541653 +849 849 783245798.6586 +850 849 2.861022949219e-06 +851 849 -10648271.7332 +852 849 80258968.78408 +853 849 -4.023313522339e-07 +854 849 -2662067.934612 +867 849 -42136521.10687 +868 849 -31944444.4392 +869 849 -28425910.47196 +870 849 -60300895.02916 +871 849 -1.370906829834e-06 +872 849 6886635.866331 +873 849 -45730271.10628 +874 849 31944444.4392 +875 849 31469922.85153 +939 849 -36875280.38624 +940 849 7638888.891399 +941 849 21477318.77125 +942 849 -67815699.74408 +943 849 2.041459083557e-06 +944 849 57072469.49195 +945 849 -10820592.87768 +946 849 -7638888.891398 +947 849 7154402.099879 +957 849 -81234695.57722 +958 849 1.624226570129e-06 +959 849 -636581.9730444 +960 849 -12957512.05534 +961 849 5.960464477539e-08 +962 849 -2546327.890928 +963 849 19546554.40623 +964 849 -1.84029340744e-06 +965 849 -636581.9730468 +978 849 -34336197.05207 +979 849 -7638888.891398 +980 849 -20840736.7982 +981 849 -61096866.41184 +982 849 -1.631677150726e-06 +983 849 -54526141.60101 +984 849 -10000259.54407 +985 849 7638888.891397 +986 849 -6517820.126831 +850 850 706575078.3316 +851 850 127776294.6906 +852 850 -1.341104507446e-07 +853 850 -41129747.07642 +854 850 -65138147.34512 +867 850 -31944444.4392 +868 850 -32552681.06127 +869 850 -14222036.84425 +871 850 80255500.90366 +872 850 31944073.6884 +873 850 31944444.4392 +874 850 -36146431.06068 +875 850 -17722036.84414 +939 850 7638888.891399 +940 850 -34583484.18238 +941 850 -15399258.17112 +942 850 2.004206180573e-06 +943 850 -34204373.78147 +944 850 7638794.112417 +945 850 -7638888.891398 +946 850 -8528796.673826 +947 850 7760464.058704 +957 850 1.564621925354e-06 +958 850 -110262429.1366 +959 850 -59916477.09895 +960 850 2.98023223877e-08 +961 850 -31291881.67713 +962 850 30555176.43461 +963 850 -1.668930053711e-06 +964 850 -9481179.15318 +965 850 29361300.66432 +978 850 -7638888.891398 +979 850 -32044400.84822 +980 850 -14635369.28198 +981 850 -1.691281795502e-06 +982 850 -27485540.44924 +983 850 7638794.112417 +984 850 7638888.891397 +985 850 -7708463.340222 +986 850 6996575.169565 +851 851 1171487488.319 +852 851 -2662067.934612 +853 851 -62638147.34553 +854 851 86952958.72131 +867 851 -28807854.91693 +868 851 -14527592.40022 +869 851 2281940.617786 +870 851 3761635.866845 +871 851 31944073.6884 +872 851 195560564.8714 +873 851 31087978.40657 +874 851 -17416481.28817 +875 851 -7301392.713971 +939 851 21477318.77125 +940 851 -15399258.17112 +941 851 -70918718.4916 +942 851 57454413.93615 +943 851 7638794.112417 +944 851 -95624557.03646 +945 851 7154402.099879 +946 851 7760464.058704 +947 851 -1439551.802109 +957 851 -636581.9730439 +958 851 -60222032.6543 +959 851 -247012438.7976 +960 851 -2546327.890927 +961 851 30555176.43461 +962 851 -253876265.6798 +963 851 -636581.9730468 +964 851 29666856.21968 +965 851 21737561.15826 +978 851 -20840736.7982 +979 851 -14635369.28198 +980 851 -64147829.60048 +981 851 -54908086.04521 +982 851 7638794.112417 +983 851 -77707668.15051 +984 851 -6517820.126831 +985 851 6996575.169565 +986 851 748003.7541653 +852 852 783245798.6586 +853 852 2.861022949219e-06 +854 852 -10648271.7332 +855 852 80258968.78408 +856 852 -4.023313522339e-07 +857 852 -2662067.934612 +870 852 -42136521.10687 +871 852 -31944444.4392 +872 852 -28425910.47196 +873 852 -60300895.02916 +874 852 -1.370906829834e-06 +875 852 6886635.866331 +876 852 -45730271.10628 +877 852 31944444.4392 +878 852 31469922.85153 +942 852 -36875280.38624 +943 852 7638888.891399 +944 852 21477318.77125 +945 852 -67815699.74408 +946 852 2.041459083557e-06 +947 852 57072469.49195 +948 852 -10820592.87768 +949 852 -7638888.891398 +950 852 7154402.099879 +960 852 -81234695.57722 +961 852 1.624226570129e-06 +962 852 -636581.9730444 +963 852 -12957512.05534 +964 852 5.960464477539e-08 +965 852 -2546327.890928 +966 852 19546554.40623 +967 852 -1.84029340744e-06 +968 852 -636581.9730468 +981 852 -34336197.05207 +982 852 -7638888.891398 +983 852 -20840736.7982 +984 852 -61096866.41184 +985 852 -1.631677150726e-06 +986 852 -54526141.60101 +987 852 -10000259.54407 +988 852 7638888.891397 +989 852 -6517820.126831 +853 853 706575078.3316 +854 853 127776294.6906 +855 853 -1.341104507446e-07 +856 853 -41129747.07642 +857 853 -65138147.34512 +870 853 -31944444.4392 +871 853 -32552681.06127 +872 853 -14222036.84425 +874 853 80255500.90366 +875 853 31944073.6884 +876 853 31944444.4392 +877 853 -36146431.06068 +878 853 -17722036.84414 +942 853 7638888.891399 +943 853 -34583484.18238 +944 853 -15399258.17112 +945 853 2.004206180573e-06 +946 853 -34204373.78147 +947 853 7638794.112417 +948 853 -7638888.891398 +949 853 -8528796.673826 +950 853 7760464.058704 +960 853 1.564621925354e-06 +961 853 -110262429.1366 +962 853 -59916477.09895 +963 853 2.98023223877e-08 +964 853 -31291881.67713 +965 853 30555176.43461 +966 853 -1.668930053711e-06 +967 853 -9481179.15318 +968 853 29361300.66432 +981 853 -7638888.891398 +982 853 -32044400.84822 +983 853 -14635369.28198 +984 853 -1.691281795502e-06 +985 853 -27485540.44924 +986 853 7638794.112417 +987 853 7638888.891397 +988 853 -7708463.340222 +989 853 6996575.169565 +854 854 1171487488.319 +855 854 -2662067.934612 +856 854 -62638147.34553 +857 854 86952958.72131 +870 854 -28807854.91693 +871 854 -14527592.40022 +872 854 2281940.617786 +873 854 3761635.866845 +874 854 31944073.6884 +875 854 195560564.8714 +876 854 31087978.40657 +877 854 -17416481.28817 +878 854 -7301392.713971 +942 854 21477318.77125 +943 854 -15399258.17112 +944 854 -70918718.4916 +945 854 57454413.93615 +946 854 7638794.112417 +947 854 -95624557.03646 +948 854 7154402.099879 +949 854 7760464.058704 +950 854 -1439551.802109 +960 854 -636581.9730439 +961 854 -60222032.6543 +962 854 -247012438.7976 +963 854 -2546327.890927 +964 854 30555176.43461 +965 854 -253876265.6798 +966 854 -636581.9730468 +967 854 29666856.21968 +968 854 21737561.15826 +981 854 -20840736.7982 +982 854 -14635369.28198 +983 854 -64147829.60048 +984 854 -54908086.04521 +985 854 7638794.112417 +986 854 -77707668.15051 +987 854 -6517820.126831 +988 854 6996575.169565 +989 854 748003.7541653 +855 855 672093135.7221 +856 855 13234981.24506 +857 855 -10472451.03689 +858 855 2713245.605375 +859 855 -45406565.53451 +860 855 -6467542.23253 +873 855 -42136521.10687 +874 855 -31944444.4392 +875 855 -28425910.47196 +876 855 -47252648.26046 +877 855 11696243.19932 +878 855 2625796.579181 +879 855 -17427995.66092 +880 855 27356351.64631 +881 855 5094898.82678 +945 855 -36875280.38624 +946 855 7638888.891399 +947 855 21477318.77125 +948 855 -54114504.27018 +949 855 -173879.5273432 +950 855 44902247.92658 +963 855 -81234695.57722 +964 855 1.624226570129e-06 +965 855 -636581.9730444 +966 855 -876482.9019934 +967 855 2519526.915563 +968 855 -2460507.026248 +969 855 -27045633.06006 +970 855 -11723510.74027 +971 855 12416379.47746 +984 855 -34336197.05207 +985 855 -7638888.891398 +986 855 -20840736.7982 +987 855 -53125239.25827 +988 855 3404183.289858 +989 855 -48696407.07857 +990 855 -13272078.15617 +991 855 5973680.062196 +992 855 -6110175.711185 +856 856 658656781.071 +857 856 76687183.50347 +858 856 -45438266.4592 +859 856 -113708638.183 +860 856 -13866021.06147 +873 856 -31944444.4392 +874 856 -32552681.06127 +875 856 -14222036.84425 +876 856 11696243.19932 +877 856 77523891.37046 +878 856 18276020.97343 +879 856 27356351.64631 +880 856 -49140307.97396 +881 856 -6257304.511357 +945 856 7638888.891399 +946 856 -34583484.18238 +947 856 -15399258.17112 +948 856 -164542.0811964 +949 856 -21525301.41066 +950 856 5061950.597479 +963 856 1.564621925354e-06 +964 856 -110262429.1366 +965 856 -59916477.09895 +966 856 2519526.915562 +967 856 673695.8703558 +968 856 18791643.5427 +969 856 -11732848.18642 +970 856 -55420678.77829 +971 856 41466871.49251 +984 856 -7638888.891398 +985 856 -32044400.84822 +986 856 -14635369.28198 +987 856 3404183.289858 +988 856 -24476237.66492 +989 856 9715809.309978 +990 856 5973680.062196 +991 856 -23241274.51146 +992 856 14956061.60352 +857 857 928696529.4313 +858 857 -6090298.663802 +859 857 -12648739.68516 +860 857 70585514.17612 +873 857 -28807854.91693 +874 857 -14527592.40022 +875 857 2281940.617786 +876 857 8702185.467069 +877 857 17970465.41792 +878 857 170894335.6621 +879 857 4331009.936854 +880 857 -6257304.511357 +881 857 18316932.36521 +945 857 21477318.77125 +946 857 -15399258.17112 +947 857 -70918718.4916 +948 857 42993884.38014 +949 857 5382550.883186 +950 857 -71799029.17722 +963 857 -636581.9730439 +964 857 -60222032.6543 +965 857 -247012438.7976 +966 857 -2443130.228498 +967 857 18805545.65999 +968 857 -201210190.2793 +969 857 12423412.7955 +970 857 41458540.64078 +971 857 -52321022.26258 +984 857 -20840736.7982 +985 857 -14635369.28198 +986 857 -64147829.60048 +987 857 -46786684.85391 +988 857 9715809.311131 +989 857 -73933522.36379 +990 857 -6110175.711185 +991 857 14956061.60352 +992 857 -21004210.79327 +858 858 458048502.1176 +859 858 7221161.637984 +860 858 -4162749.187164 +876 858 -38665742.94727 +877 858 -31344098.53733 +878 858 -4065866.490514 +879 858 9293647.217087 +880 858 15820050.87655 +881 858 2615912.244499 +882 858 79369122.72938 +883 858 -13009632.81335 +884 858 270546.9858633 +885 858 -2386124.678085 +886 858 28322349.19425 +887 858 1140574.705732 +948 858 -17822239.3706 +949 858 9194679.008118 +950 858 9770196.805889 +966 858 -41046754.09296 +967 858 -11732848.18642 +968 858 -15622467.2995 +969 858 -55034990.49984 +970 858 2099749.686162 +971 858 10931445.7583 +987 858 -23479926.51996 +988 858 -7417253.056677 +989 858 -14997301.90306 +990 858 -65005495.31362 +991 858 4667669.592739 +992 858 -54435157.05621 +993 858 -28235802.42725 +994 858 -3405845.891125 +995 858 10910713.0034 +996 858 -20886441.98794 +997 858 6593848.847203 +998 858 -13257984.86388 +859 859 539593713.555 +860 859 14603363.45522 +876 859 -31344098.53733 +877 859 -20535883.40964 +878 859 -786872.1150392 +879 859 15820050.87655 +880 859 131165149.8624 +881 859 4782395.446402 +882 859 -231855.0376756 +883 859 17238152.64816 +884 859 -607975.0375446 +885 859 28322349.19425 +886 859 -11106031.9936 +887 859 -680548.4017037 +948 859 6129786.005412 +949 859 -29631847.07945 +950 859 -18404535.59174 +966 859 -11723510.74027 +967 859 -69421799.81119 +968 859 -48221146.21121 +969 859 2099749.686162 +970 859 -30476016.89128 +971 859 7201253.461998 +987 859 -7417253.056677 +988 859 -18611925.28141 +989 859 -11356377.95096 +990 859 4667669.592739 +991 859 -36620614.93688 +992 859 6659742.089658 +993 859 -350290.3345659 +994 859 -43084517.47741 +995 859 33184890.09814 +996 859 6593848.847203 +997 859 -23664928.73455 +998 859 16496735.37374 +860 860 765181880.4553 +876 860 -4447810.935477 +877 860 -1092427.67101 +878 860 21841944.23782 +879 860 1088134.466972 +880 860 4476839.890896 +881 860 245902987.7379 +882 860 -111397.4585147 +883 860 -607975.0375448 +884 860 160000503.5775 +885 860 758630.2607686 +886 860 -680548.4017037 +887 860 57873757.49777 +948 860 6513464.53726 +949 860 -21008507.25432 +950 860 -35716363.94607 +966 860 -15612123.92226 +967 860 -48226237.0269 +968 860 -89657345.01698 +969 860 -11047443.12698 +970 860 2590596.573928 +971 860 -256503983.8706 +987 860 -14997301.90306 +988 860 -11356377.95096 +989 860 -32461726.1069 +990 860 -54435157.05583 +991 860 6659742.090811 +992 860 -127235156.8213 +993 860 2785713.002169 +994 860 33184890.09814 +995 860 -87010159.53147 +996 860 -13257984.86388 +997 860 16496735.37374 +998 860 -42112998.60584 +861 861 391154149.3294 +862 861 -2.026557922363e-06 +863 861 2488364.132116 +864 861 40072192.7253 +865 861 6388888.887839 +866 861 5613410.477452 +951 861 -67815699.74408 +952 861 2.041459083557e-06 +953 861 57072469.49195 +954 861 -10820592.87768 +955 861 -7638888.891398 +956 861 7154402.099879 +972 861 -6536047.694301 +973 861 -2.086162567139e-07 +974 861 -11516358.3887 +975 861 9773277.203117 +976 861 1527777.778279 +977 861 -1685513.209194 +862 862 352818789.1659 +863 862 63888147.34533 +864 862 -6388888.887841 +865 862 -20622165.20495 +866 862 -32249629.22817 +951 862 2.004206180573e-06 +952 862 -34204373.78147 +953 862 7638794.112417 +954 862 -7638888.891398 +955 862 -8528796.673826 +956 862 7760464.058704 +972 862 4.768371582031e-07 +973 862 -15703232.5052 +974 862 15277588.21731 +975 862 -1527777.77828 +976 862 -4740589.576589 +977 862 14757039.22107 +863 863 584493744.1599 +864 863 -6365756.187247 +865 863 -31638518.11715 +866 863 43323701.58267 +951 863 57454413.93615 +952 863 7638794.112417 +953 863 -95624557.03646 +954 863 7154402.099879 +955 863 7760464.058704 +956 863 -1439551.802109 +972 863 10879752.71874 +973 863 15277588.21731 +974 863 -127090910.6176 +975 863 1048931.236148 +976 863 14757039.22092 +977 863 10868780.57913 +864 864 391154149.3294 +865 864 -2.026557922363e-06 +866 864 2488364.132116 +867 864 40072192.7253 +868 864 6388888.887839 +869 864 5613410.477452 +951 864 -36875280.38624 +952 864 7638888.891399 +953 864 21477318.77125 +954 864 -67815699.74408 +955 864 2.041459083557e-06 +956 864 57072469.49195 +957 864 -10820592.87768 +958 864 -7638888.891398 +959 864 7154402.099879 +972 864 -40617347.78861 +973 864 -1527777.778279 +974 864 -4550096.543467 +975 864 -6536047.694301 +976 864 -2.086162567139e-07 +977 864 -11516358.3887 +978 864 9773277.203117 +979 864 1527777.778279 +980 864 -1685513.209194 +865 865 352818789.1659 +866 865 63888147.34533 +867 865 -6388888.887841 +868 865 -20622165.20495 +869 865 -32249629.22817 +951 865 7638888.891399 +952 865 -34583484.18238 +953 865 -15399258.17112 +954 865 2.004206180573e-06 +955 865 -34204373.78147 +956 865 7638794.112417 +957 865 -7638888.891398 +958 865 -8528796.673826 +959 865 7760464.058704 +972 865 1527777.77828 +973 865 -55131214.56832 +974 865 -30034627.43839 +975 865 4.768371582031e-07 +976 865 -15703232.5052 +977 865 15277588.21731 +978 865 -1527777.77828 +979 865 -4740589.576589 +980 865 14757039.22107 +866 866 584493744.1599 +867 866 -6365756.187247 +868 866 -31638518.11715 +869 866 43323701.58267 +951 866 21477318.77125 +952 866 -15399258.17112 +953 866 -70918718.4916 +954 866 57454413.93615 +955 866 7638794.112417 +956 866 -95624557.03646 +957 866 7154402.099879 +958 866 7760464.058704 +959 866 -1439551.802109 +972 866 3913514.570423 +973 866 -30034627.43824 +974 866 -123506219.3988 +975 866 10879752.71874 +976 866 15277588.21731 +977 866 -127090910.6176 +978 866 1048931.236148 +979 866 14757039.22092 +980 866 10868780.57913 +867 867 391154149.3294 +868 867 -2.026557922363e-06 +869 867 2488364.132116 +870 867 40072192.7253 +871 867 6388888.887839 +872 867 5613410.477452 +954 867 -36875280.38624 +955 867 7638888.891399 +956 867 21477318.77125 +957 867 -67815699.74408 +958 867 2.041459083557e-06 +959 867 57072469.49195 +960 867 -10820592.87768 +961 867 -7638888.891398 +962 867 7154402.099879 +975 867 -40617347.78861 +976 867 -1527777.778279 +977 867 -4550096.543467 +978 867 -6536047.694301 +979 867 -2.086162567139e-07 +980 867 -11516358.3887 +981 867 9773277.203117 +982 867 1527777.778279 +983 867 -1685513.209194 +868 868 352818789.1659 +869 868 63888147.34533 +870 868 -6388888.887841 +871 868 -20622165.20495 +872 868 -32249629.22817 +954 868 7638888.891399 +955 868 -34583484.18238 +956 868 -15399258.17112 +957 868 2.004206180573e-06 +958 868 -34204373.78147 +959 868 7638794.112417 +960 868 -7638888.891398 +961 868 -8528796.673826 +962 868 7760464.058704 +975 868 1527777.77828 +976 868 -55131214.56832 +977 868 -30034627.43839 +978 868 4.768371582031e-07 +979 868 -15703232.5052 +980 868 15277588.21731 +981 868 -1527777.77828 +982 868 -4740589.576589 +983 868 14757039.22107 +869 869 584493744.1599 +870 869 -6365756.187247 +871 869 -31638518.11715 +872 869 43323701.58267 +954 869 21477318.77125 +955 869 -15399258.17112 +956 869 -70918718.4916 +957 869 57454413.93615 +958 869 7638794.112417 +959 869 -95624557.03646 +960 869 7154402.099879 +961 869 7760464.058704 +962 869 -1439551.802109 +975 869 3913514.570423 +976 869 -30034627.43824 +977 869 -123506219.3988 +978 869 10879752.71874 +979 869 15277588.21731 +980 869 -127090910.6176 +981 869 1048931.236148 +982 869 14757039.22092 +983 869 10868780.57913 +870 870 391154149.3294 +871 870 -2.026557922363e-06 +872 870 2488364.132116 +873 870 40072192.7253 +874 870 6388888.887839 +875 870 5613410.477452 +957 870 -36875280.38624 +958 870 7638888.891399 +959 870 21477318.77125 +960 870 -67815699.74408 +961 870 2.041459083557e-06 +962 870 57072469.49195 +963 870 -10820592.87768 +964 870 -7638888.891398 +965 870 7154402.099879 +978 870 -40617347.78861 +979 870 -1527777.778279 +980 870 -4550096.543467 +981 870 -6536047.694301 +982 870 -2.086162567139e-07 +983 870 -11516358.3887 +984 870 9773277.203117 +985 870 1527777.778279 +986 870 -1685513.209194 +871 871 352818789.1659 +872 871 63888147.34533 +873 871 -6388888.887841 +874 871 -20622165.20495 +875 871 -32249629.22817 +957 871 7638888.891399 +958 871 -34583484.18238 +959 871 -15399258.17112 +960 871 2.004206180573e-06 +961 871 -34204373.78147 +962 871 7638794.112417 +963 871 -7638888.891398 +964 871 -8528796.673826 +965 871 7760464.058704 +978 871 1527777.77828 +979 871 -55131214.56832 +980 871 -30034627.43839 +981 871 4.768371582031e-07 +982 871 -15703232.5052 +983 871 15277588.21731 +984 871 -1527777.77828 +985 871 -4740589.576589 +986 871 14757039.22107 +872 872 584493744.1599 +873 872 -6365756.187247 +874 872 -31638518.11715 +875 872 43323701.58267 +957 872 21477318.77125 +958 872 -15399258.17112 +959 872 -70918718.4916 +960 872 57454413.93615 +961 872 7638794.112417 +962 872 -95624557.03646 +963 872 7154402.099879 +964 872 7760464.058704 +965 872 -1439551.802109 +978 872 3913514.570423 +979 872 -30034627.43824 +980 872 -123506219.3988 +981 872 10879752.71874 +982 872 15277588.21731 +983 872 -127090910.6176 +984 872 1048931.236148 +985 872 14757039.22092 +986 872 10868780.57913 +873 873 391154149.3294 +874 873 -2.026557922363e-06 +875 873 2488364.132116 +876 873 40072192.7253 +877 873 6388888.887839 +878 873 5613410.477452 +960 873 -36875280.38624 +961 873 7638888.891399 +962 873 21477318.77125 +963 873 -67815699.74408 +964 873 2.041459083557e-06 +965 873 57072469.49195 +966 873 -10820592.87768 +967 873 -7638888.891398 +968 873 7154402.099879 +981 873 -40617347.78861 +982 873 -1527777.778279 +983 873 -4550096.543467 +984 873 -6536047.694301 +985 873 -2.086162567139e-07 +986 873 -11516358.3887 +987 873 9773277.203117 +988 873 1527777.778279 +989 873 -1685513.209194 +874 874 352818789.1659 +875 874 63888147.34533 +876 874 -6388888.887841 +877 874 -20622165.20495 +878 874 -32249629.22817 +960 874 7638888.891399 +961 874 -34583484.18238 +962 874 -15399258.17112 +963 874 2.004206180573e-06 +964 874 -34204373.78147 +965 874 7638794.112417 +966 874 -7638888.891398 +967 874 -8528796.673826 +968 874 7760464.058704 +981 874 1527777.77828 +982 874 -55131214.56832 +983 874 -30034627.43839 +984 874 4.768371582031e-07 +985 874 -15703232.5052 +986 874 15277588.21731 +987 874 -1527777.77828 +988 874 -4740589.576589 +989 874 14757039.22107 +875 875 584493744.1599 +876 875 -6365756.187247 +877 875 -31638518.11715 +878 875 43323701.58267 +960 875 21477318.77125 +961 875 -15399258.17112 +962 875 -70918718.4916 +963 875 57454413.93615 +964 875 7638794.112417 +965 875 -95624557.03646 +966 875 7154402.099879 +967 875 7760464.058704 +968 875 -1439551.802109 +981 875 3913514.570423 +982 875 -30034627.43824 +983 875 -123506219.3988 +984 875 10879752.71874 +985 875 15277588.21731 +986 875 -127090910.6176 +987 875 1048931.236148 +988 875 14757039.22092 +989 875 10868780.57913 +876 876 368805865.5583 +877 876 600413.9845734 +878 876 -21068127.21853 +879 876 42393842.6661 +880 876 -6508114.19792 +881 876 -130691.7535722 +963 876 -36875280.38624 +964 876 7638888.891399 +965 876 21477318.77125 +966 876 -60781458.00658 +967 876 3404183.289861 +968 876 51519565.1286 +969 876 -20120523.74107 +970 876 -7417253.056677 +971 876 12996448.10614 +984 876 -40617347.78861 +985 876 -1527777.778279 +986 876 -4550096.543467 +987 876 -11601369.55203 +988 876 221678.9263838 +989 876 -17131637.01904 +990 876 -13469946.66151 +991 876 -2319720.272684 +992 876 3638957.111577 +877 877 339022561.8246 +878 877 38990819.562 +879 877 -19285891.9736 +880 877 -19618734.88413 +881 877 -6813857.903571 +963 877 7638888.891399 +964 877 -34583484.18238 +965 877 -15399258.17112 +966 877 3404183.28986 +967 877 -32132456.41324 +968 877 -1221690.688151 +969 877 -7417253.056677 +970 877 -15252522.50252 +971 877 11039455.38973 +984 877 1527777.77828 +985 877 -55131214.56832 +986 877 -30034627.43839 +987 877 221678.9263841 +988 877 -18190823.38574 +989 877 9390127.87436 +990 877 -5375275.829243 +991 877 -28175425.08385 +992 877 26225993.03356 +878 878 535213861.8177 +879 878 -2908469.530896 +880 878 -6508302.348066 +881 878 88356185.77556 +963 878 21477318.77125 +964 878 -15399258.17112 +965 878 -70918718.4916 +966 878 49609842.90663 +967 878 -1221690.687148 +968 878 -94350105.69262 +969 878 12996448.10614 +970 878 11039455.38973 +971 878 -23503318.69652 +984 878 3913514.570423 +985 878 -30034627.43824 +986 878 -123506219.3988 +987 878 5263918.532836 +988 878 9390127.87436 +989 878 -137859693.4611 +990 878 8664790.445306 +991 878 26225993.03241 +992 878 -39104413.95542 +879 879 380111399.5452 +880 879 13154777.29419 +881 879 5043109.696474 +882 879 -38195245.0425 +883 879 -35566539.68415 +884 879 -1046925.294216 +885 879 52825684.13076 +886 879 -1478748.159299 +887 879 1270918.503642 +966 879 -19678307.32513 +967 879 5973680.062196 +968 879 8212046.515743 +969 879 -66802346.00857 +970 879 4667669.592741 +971 879 55459287.37057 +987 879 -24485575.13151 +988 879 -5375275.829244 +989 879 -10605487.33072 +990 879 -49124876.9151 +991 879 4192169.39349 +992 879 -10562709.25846 +993 879 -30912229.02827 +994 879 -8683928.935591 +995 879 20053820.70261 +996 879 -25803993.24156 +997 879 -774314.2835916 +998 879 4143597.555308 +880 880 399639718.9945 +881 880 11083533.93817 +882 880 -35566539.68415 +883 880 -24534452.13025 +884 880 -680548.401704 +885 880 -14256525.93498 +886 880 -8510041.012748 +887 880 -2114218.56793 +966 880 5973680.062196 +967 880 -29647503.68042 +968 880 -18377271.74076 +969 880 4667669.59274 +970 880 -38417465.63183 +971 880 -4277757.90847 +987 880 -2319720.272685 +988 880 -39191053.55385 +989 880 -29503173.62402 +990 880 4192169.39349 +991 880 -41616248.08588 +992 880 2859416.535212 +993 880 -8683928.935591 +994 880 -27424598.87467 +995 880 16496735.37374 +996 880 -3829869.84015 +997 880 -40510457.82348 +998 880 32802051.3643 +881 881 622335345.1548 +882 881 -1046925.294216 +883 881 -680548.4017041 +884 881 44445337.36111 +885 881 90362.94827753 +886 881 -2114218.56793 +887 881 124646765.8875 +966 881 8212046.515743 +967 881 -18377271.74076 +968 881 -38087488.57717 +969 881 55459287.37019 +970 881 -4277757.907468 +971 881 -132026758.6745 +987 881 -4433820.663462 +988 881 -29503173.62502 +989 881 -68479423.20874 +990 881 11416179.62681 +991 881 2859416.535213 +992 881 -223309439.3091 +993 881 20053820.70261 +994 881 16496735.37374 +995 881 -45872668.74596 +996 881 9343319.780678 +997 881 32802051.3643 +998 881 -70377095.21823 +882 882 234270043.8785 +883 882 38565188.36471 +884 882 585934.4949026 +885 882 735926.9097565 +886 882 -2766793.642892 +887 882 572388.2578264 +969 882 -29485802.42768 +970 882 -350290.3345662 +971 882 -2760814.77204 +990 882 -32162229.02869 +991 882 -8683928.935592 +992 882 -20571179.31073 +993 882 -38762530.87567 +994 882 9516957.004243 +995 882 8271694.402195 +996 882 -42487619.48068 +997 882 -482737.734086 +998 882 -33689700.31943 +883 883 218536430.6391 +884 883 607975.0375481 +885 883 10010984.13279 +886 883 64939717.31805 +887 883 680548.401706 +969 883 -3405845.891125 +970 883 -44334517.47785 +971 883 -33481776.55758 +990 883 -8683928.935592 +991 883 -28674598.8751 +992 883 -16836597.97054 +993 883 9516957.004243 +994 883 -42533607.49829 +995 883 6815109.89529 +996 883 2572817.822473 +997 883 -27355457.96149 +998 883 3503264.632831 +884 884 390867135.2015 +885 884 190443.8134477 +886 884 680548.401706 +887 884 141166619.7936 +969 884 -10885814.77346 +970 884 -33481776.55758 +971 884 -90343492.86596 +990 884 -20571179.31073 +991 884 -16836597.97054 +992 884 -49206002.08042 +993 884 -7978305.595135 +994 884 -6518223.435853 +995 884 -159924632.0765 +996 884 -33689700.32068 +997 884 -3163402.036025 +998 884 -81587691.14437 +885 885 195388756.0715 +886 885 -24076807.39206 +887 885 2849451.866921 +969 885 -22136441.98836 +970 885 6593848.847203 +971 885 13695487.3672 +990 885 -29553993.24035 +991 885 -3829869.840151 +992 885 -9718902.442414 +993 885 -42487619.48068 +994 885 2572817.822474 +995 885 33888771.89179 +996 885 -32072854.387 +997 885 -5336796.829526 +998 885 -5139245.705715 +886 886 201240598.1223 +887 886 2114218.567935 +969 886 6593848.847203 +970 886 -24914928.73497 +971 886 -16836597.97054 +990 886 -774314.283592 +991 886 -44260457.82227 +992 886 -33864615.29142 +993 886 -482737.7340849 +994 886 -27355457.96149 +995 886 3503264.632831 +996 886 -5336796.829526 +997 886 -29720064.57765 +998 886 7197948.62913 +887 887 333817503.3118 +969 887 13695487.3672 +970 887 -16836597.97054 +971 887 -45446331.9403 +990 887 -4137235.77266 +991 887 -33864615.29142 +992 887 -80377095.215 +993 887 33888771.89035 +994 887 -3163402.036025 +995 887 -81587691.14436 +996 887 5642143.181403 +997 887 -6135384.702013 +998 887 -129257972.624 +888 888 484267631.2317 +889 888 30555555.55053 +890 888 -29327125.67035 +891 888 -126348953.9595 +892 888 -30574536.11578 +893 888 29308540.81618 +894 888 -1130543.633331 +895 888 24463425.00568 +896 888 23698547.70003 +999 888 -2535056.171221 +1000 888 7638888.891397 +1001 888 2916127.642058 +1002 888 -61266506.56961 +1003 888 -7643634.032713 +1004 888 -48493965.33591 +1005 888 6429332.410642 +1006 888 6115856.254433 +1007 888 -5472930.844082 +889 889 438410352.8514 +890 889 76423912.27372 +891 889 -30584026.39841 +892 889 17322849.63857 +893 889 42340370.58254 +894 889 36695137.50852 +895 889 -1130543.633336 +896 889 -26604449.03234 +999 889 7638888.891396 +1000 889 -13999375.77193 +1001 889 27304194.09764 +1002 889 -7646006.603371 +1003 889 -25348555.65241 +1004 889 -585233.2815705 +1005 889 9173784.381649 +1006 889 6429332.410642 +1007 889 6567824.782935 +890 890 742817650.6667 +891 890 29299248.38909 +892 890 34083332.0161 +893 890 113817630.1747 +894 890 35547821.55005 +895 890 -17736299.3549 +896 890 -3014783.022215 +999 890 -19488671.82916 +1000 890 9380576.980452 +1001 890 -143900824.6786 +1002 890 -48878084.71163 +1003 890 -2722347.244235 +1004 890 -50690307.28013 +1005 890 -8209396.266123 +1006 890 4378549.855291 +1007 890 17144886.42838 +891 891 754814074.6264 +892 891 30603006.96366 +893 891 -34373319.31429 +894 891 31201368.0013 +895 891 -30574536.11579 +896 891 -29746017.20074 +897 891 -60726571.61129 +898 891 6.407499313354e-07 +899 891 5092655.779359 +900 891 -44447793.81348 +901 891 30555555.55054 +902 891 29728025.052 +999 891 -88160408.62987 +1000 891 -7646006.603366 +1001 891 63145912.64445 +1002 891 3615653.321898 +1003 891 7650751.744684 +1004 891 -8598044.452827 +1005 891 3117023.124192 +1006 891 -7643634.032712 +1007 891 6521862.080229 +1008 891 -61096866.41184 +1009 891 -1.631677150726e-06 +1010 891 -54526141.60101 +1011 891 -10000259.54407 +1012 891 7638888.891397 +1013 891 -6517820.126831 +892 892 672288057.0206 +893 892 94722479.88535 +894 892 -30584026.39841 +895 892 -75780342.02739 +896 892 -50736841.1372 +897 892 8.642673492432e-07 +898 892 73718732.1729 +899 892 30555176.43462 +900 892 30555555.55054 +901 892 -35280609.00258 +902 892 -16652588.21716 +999 892 -7643634.032709 +1000 892 -52242457.71267 +1001 892 19687387.29713 +1002 892 7650751.744683 +1003 892 -17015851.08971 +1004 892 23676848.33746 +1005 892 -7646006.603369 +1006 892 -23628404.39615 +1007 892 31972114.21773 +1008 892 -1.691281795502e-06 +1009 892 -27485540.44924 +1010 892 7638794.112417 +1011 892 7638888.891397 +1012 892 -7708463.340222 +1013 892 6996575.169565 +893 893 1025629032.871 +894 893 -30136957.7193 +895 893 -59299198.1827 +896 893 71356723.1218 +897 893 5092655.779359 +898 893 30555176.43462 +899 893 178931711.3263 +900 893 30109969.49619 +901 893 -16958143.77251 +902 893 -8866000.069825 +999 893 63530032.02016 +1000 893 21831451.86013 +1001 893 -122407379.4408 +1002 893 -8589356.089042 +1003 893 23683798.94222 +1004 893 -237160382.7964 +1005 893 6523883.056929 +1006 893 30136961.89646 +1007 893 5350330.44263 +1008 893 -54908086.04521 +1009 893 7638794.112417 +1010 893 -77707668.15051 +1011 893 -6517820.126831 +1012 893 6996575.169565 +1013 893 748003.7541653 +894 894 484267631.2317 +895 894 30555555.55053 +896 894 -29327125.67035 +897 894 -41010293.81404 +898 894 -30555555.55054 +899 894 -27563641.60526 +900 894 -126348953.9595 +901 894 -30574536.11578 +902 894 29308540.81618 +903 894 -1130543.633331 +904 894 24463425.00568 +905 894 23698547.70003 +999 894 -44000691.65356 +1000 894 9173784.381649 +1001 894 25410834.91903 +1002 894 -74169151.35949 +1003 894 -7646006.603371 +1004 894 -21497320.34861 +1005 894 -2535056.171221 +1006 894 7638888.891397 +1007 894 2916127.642058 +1008 894 -34336197.05207 +1009 894 -7638888.891398 +1010 894 -20840736.7982 +1011 894 -61266506.56961 +1012 894 -7643634.032713 +1013 894 -48493965.33591 +1014 894 6429332.410642 +1015 894 6115856.254433 +1016 894 -5472930.844082 +895 895 438410352.8514 +896 895 76423912.27372 +897 895 -30555555.55054 +898 895 -31843109.00315 +899 895 -13902588.21746 +900 895 -30584026.39841 +901 895 17322849.63857 +902 895 42340370.58254 +903 895 36695137.50852 +904 895 -1130543.633336 +905 895 -26604449.03234 +999 895 6115856.254433 +1000 895 -44000691.65356 +1001 895 -13552018.01794 +1002 895 -7643634.032713 +1003 895 -100914578.8798 +1004 895 -59481123.99205 +1005 895 7638888.891396 +1006 895 -13999375.77193 +1007 895 27304194.09764 +1008 895 -7638888.891398 +1009 895 -32044400.84822 +1010 895 -14635369.28198 +1011 895 -7646006.603371 +1012 895 -25348555.65241 +1013 895 -585233.2815705 +1014 895 9173784.381649 +1015 895 6429332.410642 +1016 895 6567824.782935 +896 896 742817650.6667 +897 896 -27181697.16107 +898 896 -13597032.66211 +899 896 300666.5953339 +900 896 29299248.38909 +901 896 34083332.0161 +902 896 113817630.1747 +903 896 35547821.55005 +904 896 -17736299.3549 +905 896 -3014783.022215 +999 896 16940556.61269 +1000 896 -20328027.02691 +1001 896 -117335177.7428 +1002 896 -21490653.15616 +1003 896 -57645971.82207 +1004 896 -200746134.8472 +1005 896 -19488671.82916 +1006 896 9380576.980452 +1007 896 -143900824.6786 +1008 896 -20840736.7982 +1009 896 -14635369.28198 +1010 896 -64147829.60048 +1011 896 -48878084.71163 +1012 896 -2722347.244235 +1013 896 -50690307.28013 +1014 896 -8209396.266123 +1015 896 4378549.855291 +1016 896 17144886.42838 +897 897 736105860.3775 +898 897 -2.98023223877e-07 +899 897 -10185311.55874 +900 897 73722278.29235 +901 897 -3.725290298462e-07 +902 897 -2546327.890939 +906 897 -60726571.61129 +907 897 6.407499313354e-07 +908 897 5092655.779359 +909 897 -44447793.81348 +910 897 30555555.55054 +911 897 29728025.052 +1002 897 -67815699.74408 +1003 897 2.041459083557e-06 +1004 897 57072469.49195 +1005 897 -10820592.87768 +1006 897 -7638888.891398 +1007 897 7154402.099879 +1008 897 -12957512.05534 +1009 897 5.960464477539e-08 +1010 897 -2546327.890928 +1011 897 19546554.40623 +1012 897 -1.84029340744e-06 +1013 897 -636581.9730468 +1017 897 -61096866.41184 +1018 897 -1.631677150726e-06 +1019 897 -54526141.60101 +1020 897 -10000259.54407 +1021 897 7638888.891397 +1022 897 -6517820.126831 +898 898 662768381.9265 +899 898 122220705.6783 +900 898 -2.682209014893e-07 +901 898 -42388655.88811 +902 898 -61110352.83913 +906 898 8.642673492432e-07 +907 898 73718732.1729 +908 898 30555176.43462 +909 898 30555555.55054 +910 898 -35280609.00258 +911 898 -16652588.21716 +1002 898 2.004206180573e-06 +1003 898 -34204373.78147 +1004 898 7638794.112417 +1005 898 -7638888.891398 +1006 898 -8528796.673826 +1007 898 7760464.058704 +1008 898 2.98023223877e-08 +1009 898 -31291881.67713 +1010 898 30555176.43461 +1011 898 -1.668930053711e-06 +1012 898 -9481179.15318 +1013 898 29361300.66432 +1017 898 -1.691281795502e-06 +1018 898 -27485540.44924 +1019 898 7638794.112417 +1020 898 7638888.891397 +1021 898 -7708463.340222 +1022 898 6996575.169565 +899 899 1085657360.643 +900 899 -2546327.890939 +901 899 -61110352.83913 +902 899 75046406.47269 +906 899 5092655.779359 +907 899 30555176.43462 +908 899 178931711.3263 +909 899 30109969.49619 +910 899 -16958143.77251 +911 899 -8866000.069825 +1002 899 57454413.93615 +1003 899 7638794.112417 +1004 899 -95624557.03646 +1005 899 7154402.099879 +1006 899 7760464.058704 +1007 899 -1439551.802109 +1008 899 -2546327.890927 +1009 899 30555176.43461 +1010 899 -253876265.6798 +1011 899 -636581.9730468 +1012 899 29666856.21968 +1013 899 21737561.15826 +1017 899 -54908086.04521 +1018 899 7638794.112417 +1019 899 -77707668.15051 +1020 899 -6517820.126831 +1021 899 6996575.169565 +1022 899 748003.7541653 +900 900 754814074.6264 +901 900 30603006.96366 +902 900 -34373319.31429 +903 900 31201368.0013 +904 900 -30574536.11579 +905 900 -29746017.20074 +906 900 -41010293.81404 +907 900 -30555555.55054 +908 900 -27563641.60526 +909 900 -60726571.61129 +910 900 6.407499313354e-07 +911 900 5092655.779359 +912 900 -44447793.81348 +913 900 30555555.55054 +914 900 29728025.052 +1002 900 -36875280.38624 +1003 900 7638888.891399 +1004 900 21477318.77125 +1005 900 -88160408.62987 +1006 900 -7646006.603366 +1007 900 63145912.64445 +1008 900 -81234695.57722 +1009 900 1.624226570129e-06 +1010 900 -636581.9730444 +1011 900 3615653.321898 +1012 900 7650751.744684 +1013 900 -8598044.452827 +1014 900 3117023.124192 +1015 900 -7643634.032712 +1016 900 6521862.080229 +1017 900 -34336197.05207 +1018 900 -7638888.891398 +1019 900 -20840736.7982 +1020 900 -61096866.41184 +1021 900 -1.631677150726e-06 +1022 900 -54526141.60101 +1023 900 -10000259.54407 +1024 900 7638888.891397 +1025 900 -6517820.126831 +901 901 672288057.0206 +902 901 94722479.88535 +903 901 -30584026.39841 +904 901 -75780342.02739 +905 901 -50736841.1372 +906 901 -30555555.55054 +907 901 -31843109.00315 +908 901 -13902588.21746 +909 901 8.642673492432e-07 +910 901 73718732.1729 +911 901 30555176.43462 +912 901 30555555.55054 +913 901 -35280609.00258 +914 901 -16652588.21716 +1002 901 7638888.891399 +1003 901 -34583484.18238 +1004 901 -15399258.17112 +1005 901 -7643634.032709 +1006 901 -52242457.71267 +1007 901 19687387.29713 +1008 901 1.564621925354e-06 +1009 901 -110262429.1366 +1010 901 -59916477.09895 +1011 901 7650751.744683 +1012 901 -17015851.08971 +1013 901 23676848.33746 +1014 901 -7646006.603369 +1015 901 -23628404.39615 +1016 901 31972114.21773 +1017 901 -7638888.891398 +1018 901 -32044400.84822 +1019 901 -14635369.28198 +1020 901 -1.691281795502e-06 +1021 901 -27485540.44924 +1022 901 7638794.112417 +1023 901 7638888.891397 +1024 901 -7708463.340222 +1025 901 6996575.169565 +902 902 1025629032.871 +903 902 -30136957.7193 +904 902 -59299198.1827 +905 902 71356723.1218 +906 902 -27181697.16107 +907 902 -13597032.66211 +908 902 300666.5953339 +909 902 5092655.779359 +910 902 30555176.43462 +911 902 178931711.3263 +912 902 30109969.49619 +913 902 -16958143.77251 +914 902 -8866000.069825 +1002 902 21477318.77125 +1003 902 -15399258.17112 +1004 902 -70918718.4916 +1005 902 63530032.02016 +1006 902 21831451.86013 +1007 902 -122407379.4408 +1008 902 -636581.9730439 +1009 902 -60222032.6543 +1010 902 -247012438.7976 +1011 902 -8589356.089042 +1012 902 23683798.94222 +1013 902 -237160382.7964 +1014 902 6523883.056929 +1015 902 30136961.89646 +1016 902 5350330.44263 +1017 902 -20840736.7982 +1018 902 -14635369.28198 +1019 902 -64147829.60048 +1020 902 -54908086.04521 +1021 902 7638794.112417 +1022 902 -77707668.15051 +1023 902 -6517820.126831 +1024 902 6996575.169565 +1025 902 748003.7541653 +903 903 484267631.2317 +904 903 30555555.55053 +905 903 -29327125.67035 +909 903 -41010293.81404 +910 903 -30555555.55054 +911 903 -27563641.60526 +912 903 -126348953.9595 +913 903 -30574536.11578 +914 903 29308540.81618 +915 903 -1130543.633331 +916 903 24463425.00568 +917 903 23698547.70003 +1005 903 -44000691.65356 +1006 903 9173784.381649 +1007 903 25410834.91903 +1011 903 -74169151.35949 +1012 903 -7646006.603371 +1013 903 -21497320.34861 +1014 903 -2535056.171221 +1015 903 7638888.891397 +1016 903 2916127.642058 +1020 903 -34336197.05207 +1021 903 -7638888.891398 +1022 903 -20840736.7982 +1023 903 -61266506.56961 +1024 903 -7643634.032713 +1025 903 -48493965.33591 +1026 903 6429332.410642 +1027 903 6115856.254433 +1028 903 -5472930.844082 +904 904 438410352.8514 +905 904 76423912.27372 +909 904 -30555555.55054 +910 904 -31843109.00315 +911 904 -13902588.21746 +912 904 -30584026.39841 +913 904 17322849.63857 +914 904 42340370.58254 +915 904 36695137.50852 +916 904 -1130543.633336 +917 904 -26604449.03234 +1005 904 6115856.254433 +1006 904 -44000691.65356 +1007 904 -13552018.01794 +1011 904 -7643634.032713 +1012 904 -100914578.8798 +1013 904 -59481123.99205 +1014 904 7638888.891396 +1015 904 -13999375.77193 +1016 904 27304194.09764 +1020 904 -7638888.891398 +1021 904 -32044400.84822 +1022 904 -14635369.28198 +1023 904 -7646006.603371 +1024 904 -25348555.65241 +1025 904 -585233.2815705 +1026 904 9173784.381649 +1027 904 6429332.410642 +1028 904 6567824.782935 +905 905 742817650.6667 +909 905 -27181697.16107 +910 905 -13597032.66211 +911 905 300666.5953339 +912 905 29299248.38909 +913 905 34083332.0161 +914 905 113817630.1747 +915 905 35547821.55005 +916 905 -17736299.3549 +917 905 -3014783.022215 +1005 905 16940556.61269 +1006 905 -20328027.02691 +1007 905 -117335177.7428 +1011 905 -21490653.15616 +1012 905 -57645971.82207 +1013 905 -200746134.8472 +1014 905 -19488671.82916 +1015 905 9380576.980452 +1016 905 -143900824.6786 +1020 905 -20840736.7982 +1021 905 -14635369.28198 +1022 905 -64147829.60048 +1023 905 -48878084.71163 +1024 905 -2722347.244235 +1025 905 -50690307.28013 +1026 905 -8209396.266123 +1027 905 4378549.855291 +1028 905 17144886.42838 +906 906 736105860.3775 +907 906 -2.98023223877e-07 +908 906 -10185311.55874 +909 906 73722278.29235 +910 906 -3.725290298462e-07 +911 906 -2546327.890939 +918 906 -60726571.61129 +919 906 6.407499313354e-07 +920 906 5092655.779359 +921 906 -44447793.81348 +922 906 30555555.55054 +923 906 29728025.052 +1008 906 -67815699.74408 +1009 906 2.041459083557e-06 +1010 906 57072469.49195 +1011 906 -10820592.87768 +1012 906 -7638888.891398 +1013 906 7154402.099879 +1017 906 -12957512.05534 +1018 906 5.960464477539e-08 +1019 906 -2546327.890928 +1020 906 19546554.40623 +1021 906 -1.84029340744e-06 +1022 906 -636581.9730468 +1029 906 -61096866.41184 +1030 906 -1.631677150726e-06 +1031 906 -54526141.60101 +1032 906 -10000259.54407 +1033 906 7638888.891397 +1034 906 -6517820.126831 +907 907 662768381.9265 +908 907 122220705.6783 +909 907 -2.682209014893e-07 +910 907 -42388655.88811 +911 907 -61110352.83913 +918 907 8.642673492432e-07 +919 907 73718732.1729 +920 907 30555176.43462 +921 907 30555555.55054 +922 907 -35280609.00258 +923 907 -16652588.21716 +1008 907 2.004206180573e-06 +1009 907 -34204373.78147 +1010 907 7638794.112417 +1011 907 -7638888.891398 +1012 907 -8528796.673826 +1013 907 7760464.058704 +1017 907 2.98023223877e-08 +1018 907 -31291881.67713 +1019 907 30555176.43461 +1020 907 -1.668930053711e-06 +1021 907 -9481179.15318 +1022 907 29361300.66432 +1029 907 -1.691281795502e-06 +1030 907 -27485540.44924 +1031 907 7638794.112417 +1032 907 7638888.891397 +1033 907 -7708463.340222 +1034 907 6996575.169565 +908 908 1085657360.643 +909 908 -2546327.890939 +910 908 -61110352.83913 +911 908 75046406.47269 +918 908 5092655.779359 +919 908 30555176.43462 +920 908 178931711.3263 +921 908 30109969.49619 +922 908 -16958143.77251 +923 908 -8866000.069825 +1008 908 57454413.93615 +1009 908 7638794.112417 +1010 908 -95624557.03646 +1011 908 7154402.099879 +1012 908 7760464.058704 +1013 908 -1439551.802109 +1017 908 -2546327.890927 +1018 908 30555176.43461 +1019 908 -253876265.6798 +1020 908 -636581.9730468 +1021 908 29666856.21968 +1022 908 21737561.15826 +1029 908 -54908086.04521 +1030 908 7638794.112417 +1031 908 -77707668.15051 +1032 908 -6517820.126831 +1033 908 6996575.169565 +1034 908 748003.7541653 +909 909 736105860.3775 +910 909 -2.98023223877e-07 +911 909 -10185311.55874 +912 909 73722278.29235 +913 909 -3.725290298462e-07 +914 909 -2546327.890939 +918 909 -41010293.81404 +919 909 -30555555.55054 +920 909 -27563641.60526 +921 909 -60726571.61129 +922 909 6.407499313354e-07 +923 909 5092655.779359 +924 909 -44447793.81348 +925 909 30555555.55054 +926 909 29728025.052 +1008 909 -36875280.38624 +1009 909 7638888.891399 +1010 909 21477318.77125 +1011 909 -67815699.74408 +1012 909 2.041459083557e-06 +1013 909 57072469.49195 +1014 909 -10820592.87768 +1015 909 -7638888.891398 +1016 909 7154402.099879 +1017 909 -81234695.57722 +1018 909 1.624226570129e-06 +1019 909 -636581.9730444 +1020 909 -12957512.05534 +1021 909 5.960464477539e-08 +1022 909 -2546327.890928 +1023 909 19546554.40623 +1024 909 -1.84029340744e-06 +1025 909 -636581.9730468 +1029 909 -34336197.05207 +1030 909 -7638888.891398 +1031 909 -20840736.7982 +1032 909 -61096866.41184 +1033 909 -1.631677150726e-06 +1034 909 -54526141.60101 +1035 909 -10000259.54407 +1036 909 7638888.891397 +1037 909 -6517820.126831 +910 910 662768381.9265 +911 910 122220705.6783 +912 910 -2.682209014893e-07 +913 910 -42388655.88811 +914 910 -61110352.83913 +918 910 -30555555.55054 +919 910 -31843109.00315 +920 910 -13902588.21746 +921 910 8.642673492432e-07 +922 910 73718732.1729 +923 910 30555176.43462 +924 910 30555555.55054 +925 910 -35280609.00258 +926 910 -16652588.21716 +1008 910 7638888.891399 +1009 910 -34583484.18238 +1010 910 -15399258.17112 +1011 910 2.004206180573e-06 +1012 910 -34204373.78147 +1013 910 7638794.112417 +1014 910 -7638888.891398 +1015 910 -8528796.673826 +1016 910 7760464.058704 +1017 910 1.564621925354e-06 +1018 910 -110262429.1366 +1019 910 -59916477.09895 +1020 910 2.98023223877e-08 +1021 910 -31291881.67713 +1022 910 30555176.43461 +1023 910 -1.668930053711e-06 +1024 910 -9481179.15318 +1025 910 29361300.66432 +1029 910 -7638888.891398 +1030 910 -32044400.84822 +1031 910 -14635369.28198 +1032 910 -1.691281795502e-06 +1033 910 -27485540.44924 +1034 910 7638794.112417 +1035 910 7638888.891397 +1036 910 -7708463.340222 +1037 910 6996575.169565 +911 911 1085657360.643 +912 911 -2546327.890939 +913 911 -61110352.83913 +914 911 75046406.47269 +918 911 -27181697.16107 +919 911 -13597032.66211 +920 911 300666.5953339 +921 911 5092655.779359 +922 911 30555176.43462 +923 911 178931711.3263 +924 911 30109969.49619 +925 911 -16958143.77251 +926 911 -8866000.069825 +1008 911 21477318.77125 +1009 911 -15399258.17112 +1010 911 -70918718.4916 +1011 911 57454413.93615 +1012 911 7638794.112417 +1013 911 -95624557.03646 +1014 911 7154402.099879 +1015 911 7760464.058704 +1016 911 -1439551.802109 +1017 911 -636581.9730439 +1018 911 -60222032.6543 +1019 911 -247012438.7976 +1020 911 -2546327.890927 +1021 911 30555176.43461 +1022 911 -253876265.6798 +1023 911 -636581.9730468 +1024 911 29666856.21968 +1025 911 21737561.15826 +1029 911 -20840736.7982 +1030 911 -14635369.28198 +1031 911 -64147829.60048 +1032 911 -54908086.04521 +1033 911 7638794.112417 +1034 911 -77707668.15051 +1035 911 -6517820.126831 +1036 911 6996575.169565 +1037 911 748003.7541653 +912 912 754814074.6264 +913 912 30603006.96366 +914 912 -34373319.31429 +915 912 31201368.0013 +916 912 -30574536.11579 +917 912 -29746017.20074 +921 912 -41010293.81404 +922 912 -30555555.55054 +923 912 -27563641.60526 +924 912 -60726571.61129 +925 912 6.407499313354e-07 +926 912 5092655.779359 +927 912 -44447793.81348 +928 912 30555555.55054 +929 912 29728025.052 +1011 912 -36875280.38624 +1012 912 7638888.891399 +1013 912 21477318.77125 +1014 912 -88160408.62987 +1015 912 -7646006.603366 +1016 912 63145912.64445 +1020 912 -81234695.57722 +1021 912 1.624226570129e-06 +1022 912 -636581.9730444 +1023 912 3615653.321898 +1024 912 7650751.744684 +1025 912 -8598044.452827 +1026 912 3117023.124192 +1027 912 -7643634.032712 +1028 912 6521862.080229 +1032 912 -34336197.05207 +1033 912 -7638888.891398 +1034 912 -20840736.7982 +1035 912 -61096866.41184 +1036 912 -1.631677150726e-06 +1037 912 -54526141.60101 +1038 912 -10000259.54407 +1039 912 7638888.891397 +1040 912 -6517820.126831 +913 913 672288057.0206 +914 913 94722479.88535 +915 913 -30584026.39841 +916 913 -75780342.02739 +917 913 -50736841.1372 +921 913 -30555555.55054 +922 913 -31843109.00315 +923 913 -13902588.21746 +924 913 8.642673492432e-07 +925 913 73718732.1729 +926 913 30555176.43462 +927 913 30555555.55054 +928 913 -35280609.00258 +929 913 -16652588.21716 +1011 913 7638888.891399 +1012 913 -34583484.18238 +1013 913 -15399258.17112 +1014 913 -7643634.032709 +1015 913 -52242457.71267 +1016 913 19687387.29713 +1020 913 1.564621925354e-06 +1021 913 -110262429.1366 +1022 913 -59916477.09895 +1023 913 7650751.744683 +1024 913 -17015851.08971 +1025 913 23676848.33746 +1026 913 -7646006.603369 +1027 913 -23628404.39615 +1028 913 31972114.21773 +1032 913 -7638888.891398 +1033 913 -32044400.84822 +1034 913 -14635369.28198 +1035 913 -1.691281795502e-06 +1036 913 -27485540.44924 +1037 913 7638794.112417 +1038 913 7638888.891397 +1039 913 -7708463.340222 +1040 913 6996575.169565 +914 914 1025629032.871 +915 914 -30136957.7193 +916 914 -59299198.1827 +917 914 71356723.1218 +921 914 -27181697.16107 +922 914 -13597032.66211 +923 914 300666.5953339 +924 914 5092655.779359 +925 914 30555176.43462 +926 914 178931711.3263 +927 914 30109969.49619 +928 914 -16958143.77251 +929 914 -8866000.069825 +1011 914 21477318.77125 +1012 914 -15399258.17112 +1013 914 -70918718.4916 +1014 914 63530032.02016 +1015 914 21831451.86013 +1016 914 -122407379.4408 +1020 914 -636581.9730439 +1021 914 -60222032.6543 +1022 914 -247012438.7976 +1023 914 -8589356.089042 +1024 914 23683798.94222 +1025 914 -237160382.7964 +1026 914 6523883.056929 +1027 914 30136961.89646 +1028 914 5350330.44263 +1032 914 -20840736.7982 +1033 914 -14635369.28198 +1034 914 -64147829.60048 +1035 914 -54908086.04521 +1036 914 7638794.112417 +1037 914 -77707668.15051 +1038 914 -6517820.126831 +1039 914 6996575.169565 +1040 914 748003.7541653 +915 915 484267631.2317 +916 915 30555555.55053 +917 915 -29327125.67035 +924 915 -41010293.81404 +925 915 -30555555.55054 +926 915 -27563641.60526 +927 915 -126348953.9595 +928 915 -30574536.11578 +929 915 29308540.81618 +930 915 -1130543.633331 +931 915 24463425.00568 +932 915 23698547.70003 +1014 915 -44000691.65356 +1015 915 9173784.381649 +1016 915 25410834.91903 +1023 915 -74169151.35949 +1024 915 -7646006.603371 +1025 915 -21497320.34861 +1026 915 -2535056.171221 +1027 915 7638888.891397 +1028 915 2916127.642058 +1035 915 -34336197.05207 +1036 915 -7638888.891398 +1037 915 -20840736.7982 +1038 915 -61266506.56961 +1039 915 -7643634.032713 +1040 915 -48493965.33591 +1041 915 6429332.410642 +1042 915 6115856.254433 +1043 915 -5472930.844082 +916 916 438410352.8514 +917 916 76423912.27372 +924 916 -30555555.55054 +925 916 -31843109.00315 +926 916 -13902588.21746 +927 916 -30584026.39841 +928 916 17322849.63857 +929 916 42340370.58254 +930 916 36695137.50852 +931 916 -1130543.633336 +932 916 -26604449.03234 +1014 916 6115856.254433 +1015 916 -44000691.65356 +1016 916 -13552018.01794 +1023 916 -7643634.032713 +1024 916 -100914578.8798 +1025 916 -59481123.99205 +1026 916 7638888.891396 +1027 916 -13999375.77193 +1028 916 27304194.09764 +1035 916 -7638888.891398 +1036 916 -32044400.84822 +1037 916 -14635369.28198 +1038 916 -7646006.603371 +1039 916 -25348555.65241 +1040 916 -585233.2815705 +1041 916 9173784.381649 +1042 916 6429332.410642 +1043 916 6567824.782935 +917 917 742817650.6667 +924 917 -27181697.16107 +925 917 -13597032.66211 +926 917 300666.5953339 +927 917 29299248.38909 +928 917 34083332.0161 +929 917 113817630.1747 +930 917 35547821.55005 +931 917 -17736299.3549 +932 917 -3014783.022215 +1014 917 16940556.61269 +1015 917 -20328027.02691 +1016 917 -117335177.7428 +1023 917 -21490653.15616 +1024 917 -57645971.82207 +1025 917 -200746134.8472 +1026 917 -19488671.82916 +1027 917 9380576.980452 +1028 917 -143900824.6786 +1035 917 -20840736.7982 +1036 917 -14635369.28198 +1037 917 -64147829.60048 +1038 917 -48878084.71163 +1039 917 -2722347.244235 +1040 917 -50690307.28013 +1041 917 -8209396.266123 +1042 917 4378549.855291 +1043 917 17144886.42838 +918 918 736105860.3775 +919 918 -2.98023223877e-07 +920 918 -10185311.55874 +921 918 73722278.29235 +922 918 -3.725290298462e-07 +923 918 -2546327.890939 +933 918 -60726571.61129 +934 918 6.407499313354e-07 +935 918 5092655.779359 +936 918 -44447793.81348 +937 918 30555555.55054 +938 918 29728025.052 +1017 918 -67815699.74408 +1018 918 2.041459083557e-06 +1019 918 57072469.49195 +1020 918 -10820592.87768 +1021 918 -7638888.891398 +1022 918 7154402.099879 +1029 918 -12957512.05534 +1030 918 5.960464477539e-08 +1031 918 -2546327.890928 +1032 918 19546554.40623 +1033 918 -1.84029340744e-06 +1034 918 -636581.9730468 +1044 918 -61096866.41184 +1045 918 -1.631677150726e-06 +1046 918 -54526141.60101 +1047 918 -10000259.54407 +1048 918 7638888.891397 +1049 918 -6517820.126831 +919 919 662768381.9265 +920 919 122220705.6783 +921 919 -2.682209014893e-07 +922 919 -42388655.88811 +923 919 -61110352.83913 +933 919 8.642673492432e-07 +934 919 73718732.1729 +935 919 30555176.43462 +936 919 30555555.55054 +937 919 -35280609.00258 +938 919 -16652588.21716 +1017 919 2.004206180573e-06 +1018 919 -34204373.78147 +1019 919 7638794.112417 +1020 919 -7638888.891398 +1021 919 -8528796.673826 +1022 919 7760464.058704 +1029 919 2.98023223877e-08 +1030 919 -31291881.67713 +1031 919 30555176.43461 +1032 919 -1.668930053711e-06 +1033 919 -9481179.15318 +1034 919 29361300.66432 +1044 919 -1.691281795502e-06 +1045 919 -27485540.44924 +1046 919 7638794.112417 +1047 919 7638888.891397 +1048 919 -7708463.340222 +1049 919 6996575.169565 +920 920 1085657360.643 +921 920 -2546327.890939 +922 920 -61110352.83913 +923 920 75046406.47269 +933 920 5092655.779359 +934 920 30555176.43462 +935 920 178931711.3263 +936 920 30109969.49619 +937 920 -16958143.77251 +938 920 -8866000.069825 +1017 920 57454413.93615 +1018 920 7638794.112417 +1019 920 -95624557.03646 +1020 920 7154402.099879 +1021 920 7760464.058704 +1022 920 -1439551.802109 +1029 920 -2546327.890927 +1030 920 30555176.43461 +1031 920 -253876265.6798 +1032 920 -636581.9730468 +1033 920 29666856.21968 +1034 920 21737561.15826 +1044 920 -54908086.04521 +1045 920 7638794.112417 +1046 920 -77707668.15051 +1047 920 -6517820.126831 +1048 920 6996575.169565 +1049 920 748003.7541653 +921 921 736105860.3775 +922 921 -2.98023223877e-07 +923 921 -10185311.55874 +924 921 73722278.29235 +925 921 -3.725290298462e-07 +926 921 -2546327.890939 +933 921 -41010293.81404 +934 921 -30555555.55054 +935 921 -27563641.60526 +936 921 -60726571.61129 +937 921 6.407499313354e-07 +938 921 5092655.779359 +939 921 -44447793.81348 +940 921 30555555.55054 +941 921 29728025.052 +1017 921 -36875280.38624 +1018 921 7638888.891399 +1019 921 21477318.77125 +1020 921 -67815699.74408 +1021 921 2.041459083557e-06 +1022 921 57072469.49195 +1023 921 -10820592.87768 +1024 921 -7638888.891398 +1025 921 7154402.099879 +1029 921 -81234695.57722 +1030 921 1.624226570129e-06 +1031 921 -636581.9730444 +1032 921 -12957512.05534 +1033 921 5.960464477539e-08 +1034 921 -2546327.890928 +1035 921 19546554.40623 +1036 921 -1.84029340744e-06 +1037 921 -636581.9730468 +1044 921 -34336197.05207 +1045 921 -7638888.891398 +1046 921 -20840736.7982 +1047 921 -61096866.41184 +1048 921 -1.631677150726e-06 +1049 921 -54526141.60101 +1050 921 -10000259.54407 +1051 921 7638888.891397 +1052 921 -6517820.126831 +922 922 662768381.9265 +923 922 122220705.6783 +924 922 -2.682209014893e-07 +925 922 -42388655.88811 +926 922 -61110352.83913 +933 922 -30555555.55054 +934 922 -31843109.00315 +935 922 -13902588.21746 +936 922 8.642673492432e-07 +937 922 73718732.1729 +938 922 30555176.43462 +939 922 30555555.55054 +940 922 -35280609.00258 +941 922 -16652588.21716 +1017 922 7638888.891399 +1018 922 -34583484.18238 +1019 922 -15399258.17112 +1020 922 2.004206180573e-06 +1021 922 -34204373.78147 +1022 922 7638794.112417 +1023 922 -7638888.891398 +1024 922 -8528796.673826 +1025 922 7760464.058704 +1029 922 1.564621925354e-06 +1030 922 -110262429.1366 +1031 922 -59916477.09895 +1032 922 2.98023223877e-08 +1033 922 -31291881.67713 +1034 922 30555176.43461 +1035 922 -1.668930053711e-06 +1036 922 -9481179.15318 +1037 922 29361300.66432 +1044 922 -7638888.891398 +1045 922 -32044400.84822 +1046 922 -14635369.28198 +1047 922 -1.691281795502e-06 +1048 922 -27485540.44924 +1049 922 7638794.112417 +1050 922 7638888.891397 +1051 922 -7708463.340222 +1052 922 6996575.169565 +923 923 1085657360.643 +924 923 -2546327.890939 +925 923 -61110352.83913 +926 923 75046406.47269 +933 923 -27181697.16107 +934 923 -13597032.66211 +935 923 300666.5953339 +936 923 5092655.779359 +937 923 30555176.43462 +938 923 178931711.3263 +939 923 30109969.49619 +940 923 -16958143.77251 +941 923 -8866000.069825 +1017 923 21477318.77125 +1018 923 -15399258.17112 +1019 923 -70918718.4916 +1020 923 57454413.93615 +1021 923 7638794.112417 +1022 923 -95624557.03646 +1023 923 7154402.099879 +1024 923 7760464.058704 +1025 923 -1439551.802109 +1029 923 -636581.9730439 +1030 923 -60222032.6543 +1031 923 -247012438.7976 +1032 923 -2546327.890927 +1033 923 30555176.43461 +1034 923 -253876265.6798 +1035 923 -636581.9730468 +1036 923 29666856.21968 +1037 923 21737561.15826 +1044 923 -20840736.7982 +1045 923 -14635369.28198 +1046 923 -64147829.60048 +1047 923 -54908086.04521 +1048 923 7638794.112417 +1049 923 -77707668.15051 +1050 923 -6517820.126831 +1051 923 6996575.169565 +1052 923 748003.7541653 +924 924 736105860.3775 +925 924 -2.98023223877e-07 +926 924 -10185311.55874 +927 924 73722278.29235 +928 924 -3.725290298462e-07 +929 924 -2546327.890939 +936 924 -41010293.81404 +937 924 -30555555.55054 +938 924 -27563641.60526 +939 924 -60726571.61129 +940 924 6.407499313354e-07 +941 924 5092655.779359 +942 924 -44447793.81348 +943 924 30555555.55054 +944 924 29728025.052 +1020 924 -36875280.38624 +1021 924 7638888.891399 +1022 924 21477318.77125 +1023 924 -67815699.74408 +1024 924 2.041459083557e-06 +1025 924 57072469.49195 +1026 924 -10820592.87768 +1027 924 -7638888.891398 +1028 924 7154402.099879 +1032 924 -81234695.57722 +1033 924 1.624226570129e-06 +1034 924 -636581.9730444 +1035 924 -12957512.05534 +1036 924 5.960464477539e-08 +1037 924 -2546327.890928 +1038 924 19546554.40623 +1039 924 -1.84029340744e-06 +1040 924 -636581.9730468 +1047 924 -34336197.05207 +1048 924 -7638888.891398 +1049 924 -20840736.7982 +1050 924 -61096866.41184 +1051 924 -1.631677150726e-06 +1052 924 -54526141.60101 +1053 924 -10000259.54407 +1054 924 7638888.891397 +1055 924 -6517820.126831 +925 925 662768381.9265 +926 925 122220705.6783 +927 925 -2.682209014893e-07 +928 925 -42388655.88811 +929 925 -61110352.83913 +936 925 -30555555.55054 +937 925 -31843109.00315 +938 925 -13902588.21746 +939 925 8.642673492432e-07 +940 925 73718732.1729 +941 925 30555176.43462 +942 925 30555555.55054 +943 925 -35280609.00258 +944 925 -16652588.21716 +1020 925 7638888.891399 +1021 925 -34583484.18238 +1022 925 -15399258.17112 +1023 925 2.004206180573e-06 +1024 925 -34204373.78147 +1025 925 7638794.112417 +1026 925 -7638888.891398 +1027 925 -8528796.673826 +1028 925 7760464.058704 +1032 925 1.564621925354e-06 +1033 925 -110262429.1366 +1034 925 -59916477.09895 +1035 925 2.98023223877e-08 +1036 925 -31291881.67713 +1037 925 30555176.43461 +1038 925 -1.668930053711e-06 +1039 925 -9481179.15318 +1040 925 29361300.66432 +1047 925 -7638888.891398 +1048 925 -32044400.84822 +1049 925 -14635369.28198 +1050 925 -1.691281795502e-06 +1051 925 -27485540.44924 +1052 925 7638794.112417 +1053 925 7638888.891397 +1054 925 -7708463.340222 +1055 925 6996575.169565 +926 926 1085657360.643 +927 926 -2546327.890939 +928 926 -61110352.83913 +929 926 75046406.47269 +936 926 -27181697.16107 +937 926 -13597032.66211 +938 926 300666.5953339 +939 926 5092655.779359 +940 926 30555176.43462 +941 926 178931711.3263 +942 926 30109969.49619 +943 926 -16958143.77251 +944 926 -8866000.069825 +1020 926 21477318.77125 +1021 926 -15399258.17112 +1022 926 -70918718.4916 +1023 926 57454413.93615 +1024 926 7638794.112417 +1025 926 -95624557.03646 +1026 926 7154402.099879 +1027 926 7760464.058704 +1028 926 -1439551.802109 +1032 926 -636581.9730439 +1033 926 -60222032.6543 +1034 926 -247012438.7976 +1035 926 -2546327.890927 +1036 926 30555176.43461 +1037 926 -253876265.6798 +1038 926 -636581.9730468 +1039 926 29666856.21968 +1040 926 21737561.15826 +1047 926 -20840736.7982 +1048 926 -14635369.28198 +1049 926 -64147829.60048 +1050 926 -54908086.04521 +1051 926 7638794.112417 +1052 926 -77707668.15051 +1053 926 -6517820.126831 +1054 926 6996575.169565 +1055 926 748003.7541653 +927 927 754814074.6264 +928 927 30603006.96366 +929 927 -34373319.31429 +930 927 31201368.0013 +931 927 -30574536.11579 +932 927 -29746017.20074 +939 927 -41010293.81404 +940 927 -30555555.55054 +941 927 -27563641.60526 +942 927 -60726571.61129 +943 927 6.407499313354e-07 +944 927 5092655.779359 +945 927 -44447793.81348 +946 927 30555555.55054 +947 927 29728025.052 +1023 927 -36875280.38624 +1024 927 7638888.891399 +1025 927 21477318.77125 +1026 927 -88160408.62987 +1027 927 -7646006.603366 +1028 927 63145912.64445 +1035 927 -81234695.57722 +1036 927 1.624226570129e-06 +1037 927 -636581.9730444 +1038 927 3615653.321898 +1039 927 7650751.744684 +1040 927 -8598044.452827 +1041 927 3117023.124192 +1042 927 -7643634.032712 +1043 927 6521862.080229 +1050 927 -34336197.05207 +1051 927 -7638888.891398 +1052 927 -20840736.7982 +1053 927 -61096866.41184 +1054 927 -1.631677150726e-06 +1055 927 -54526141.60101 +1056 927 -10000259.54407 +1057 927 7638888.891397 +1058 927 -6517820.126831 +928 928 672288057.0206 +929 928 94722479.88535 +930 928 -30584026.39841 +931 928 -75780342.02739 +932 928 -50736841.1372 +939 928 -30555555.55054 +940 928 -31843109.00315 +941 928 -13902588.21746 +942 928 8.642673492432e-07 +943 928 73718732.1729 +944 928 30555176.43462 +945 928 30555555.55054 +946 928 -35280609.00258 +947 928 -16652588.21716 +1023 928 7638888.891399 +1024 928 -34583484.18238 +1025 928 -15399258.17112 +1026 928 -7643634.032709 +1027 928 -52242457.71267 +1028 928 19687387.29713 +1035 928 1.564621925354e-06 +1036 928 -110262429.1366 +1037 928 -59916477.09895 +1038 928 7650751.744683 +1039 928 -17015851.08971 +1040 928 23676848.33746 +1041 928 -7646006.603369 +1042 928 -23628404.39615 +1043 928 31972114.21773 +1050 928 -7638888.891398 +1051 928 -32044400.84822 +1052 928 -14635369.28198 +1053 928 -1.691281795502e-06 +1054 928 -27485540.44924 +1055 928 7638794.112417 +1056 928 7638888.891397 +1057 928 -7708463.340222 +1058 928 6996575.169565 +929 929 1025629032.871 +930 929 -30136957.7193 +931 929 -59299198.1827 +932 929 71356723.1218 +939 929 -27181697.16107 +940 929 -13597032.66211 +941 929 300666.5953339 +942 929 5092655.779359 +943 929 30555176.43462 +944 929 178931711.3263 +945 929 30109969.49619 +946 929 -16958143.77251 +947 929 -8866000.069825 +1023 929 21477318.77125 +1024 929 -15399258.17112 +1025 929 -70918718.4916 +1026 929 63530032.02016 +1027 929 21831451.86013 +1028 929 -122407379.4408 +1035 929 -636581.9730439 +1036 929 -60222032.6543 +1037 929 -247012438.7976 +1038 929 -8589356.089042 +1039 929 23683798.94222 +1040 929 -237160382.7964 +1041 929 6523883.056929 +1042 929 30136961.89646 +1043 929 5350330.44263 +1050 929 -20840736.7982 +1051 929 -14635369.28198 +1052 929 -64147829.60048 +1053 929 -54908086.04521 +1054 929 7638794.112417 +1055 929 -77707668.15051 +1056 929 -6517820.126831 +1057 929 6996575.169565 +1058 929 748003.7541653 +930 930 484267631.2317 +931 930 30555555.55053 +932 930 -29327125.67035 +942 930 -41010293.81404 +943 930 -30555555.55054 +944 930 -27563641.60526 +945 930 -126348953.9595 +946 930 -30574536.11578 +947 930 29308540.81618 +948 930 -1130543.633331 +949 930 24463425.00568 +950 930 23698547.70003 +1026 930 -44000691.65356 +1027 930 9173784.381649 +1028 930 25410834.91903 +1038 930 -74169151.35949 +1039 930 -7646006.603371 +1040 930 -21497320.34861 +1041 930 -2535056.171221 +1042 930 7638888.891397 +1043 930 2916127.642058 +1053 930 -34336197.05207 +1054 930 -7638888.891398 +1055 930 -20840736.7982 +1056 930 -61266506.56961 +1057 930 -7643634.032713 +1058 930 -48493965.33591 +1059 930 6429332.410642 +1060 930 6115856.254433 +1061 930 -5472930.844082 +931 931 438410352.8514 +932 931 76423912.27372 +942 931 -30555555.55054 +943 931 -31843109.00315 +944 931 -13902588.21746 +945 931 -30584026.39841 +946 931 17322849.63857 +947 931 42340370.58254 +948 931 36695137.50852 +949 931 -1130543.633336 +950 931 -26604449.03234 +1026 931 6115856.254433 +1027 931 -44000691.65356 +1028 931 -13552018.01794 +1038 931 -7643634.032713 +1039 931 -100914578.8798 +1040 931 -59481123.99205 +1041 931 7638888.891396 +1042 931 -13999375.77193 +1043 931 27304194.09764 +1053 931 -7638888.891398 +1054 931 -32044400.84822 +1055 931 -14635369.28198 +1056 931 -7646006.603371 +1057 931 -25348555.65241 +1058 931 -585233.2815705 +1059 931 9173784.381649 +1060 931 6429332.410642 +1061 931 6567824.782935 +932 932 742817650.6667 +942 932 -27181697.16107 +943 932 -13597032.66211 +944 932 300666.5953339 +945 932 29299248.38909 +946 932 34083332.0161 +947 932 113817630.1747 +948 932 35547821.55005 +949 932 -17736299.3549 +950 932 -3014783.022215 +1026 932 16940556.61269 +1027 932 -20328027.02691 +1028 932 -117335177.7428 +1038 932 -21490653.15616 +1039 932 -57645971.82207 +1040 932 -200746134.8472 +1041 932 -19488671.82916 +1042 932 9380576.980452 +1043 932 -143900824.6786 +1053 932 -20840736.7982 +1054 932 -14635369.28198 +1055 932 -64147829.60048 +1056 932 -48878084.71163 +1057 932 -2722347.244235 +1058 932 -50690307.28013 +1059 932 -8209396.266123 +1060 932 4378549.855291 +1061 932 17144886.42838 +933 933 736105860.3775 +934 933 -2.98023223877e-07 +935 933 -10185311.55874 +936 933 73722278.29235 +937 933 -3.725290298462e-07 +938 933 -2546327.890939 +951 933 -60726571.61129 +952 933 6.407499313354e-07 +953 933 5092655.779359 +954 933 -44447793.81348 +955 933 30555555.55054 +956 933 29728025.052 +1029 933 -67815699.74408 +1030 933 2.041459083557e-06 +1031 933 57072469.49195 +1032 933 -10820592.87768 +1033 933 -7638888.891398 +1034 933 7154402.099879 +1044 933 -12957512.05534 +1045 933 5.960464477539e-08 +1046 933 -2546327.890928 +1047 933 19546554.40623 +1048 933 -1.84029340744e-06 +1049 933 -636581.9730468 +1062 933 -61096866.41184 +1063 933 -1.631677150726e-06 +1064 933 -54526141.60101 +1065 933 -10000259.54407 +1066 933 7638888.891397 +1067 933 -6517820.126831 +934 934 662768381.9265 +935 934 122220705.6783 +936 934 -2.682209014893e-07 +937 934 -42388655.88811 +938 934 -61110352.83913 +951 934 8.642673492432e-07 +952 934 73718732.1729 +953 934 30555176.43462 +954 934 30555555.55054 +955 934 -35280609.00258 +956 934 -16652588.21716 +1029 934 2.004206180573e-06 +1030 934 -34204373.78147 +1031 934 7638794.112417 +1032 934 -7638888.891398 +1033 934 -8528796.673826 +1034 934 7760464.058704 +1044 934 2.98023223877e-08 +1045 934 -31291881.67713 +1046 934 30555176.43461 +1047 934 -1.668930053711e-06 +1048 934 -9481179.15318 +1049 934 29361300.66432 +1062 934 -1.691281795502e-06 +1063 934 -27485540.44924 +1064 934 7638794.112417 +1065 934 7638888.891397 +1066 934 -7708463.340222 +1067 934 6996575.169565 +935 935 1085657360.643 +936 935 -2546327.890939 +937 935 -61110352.83913 +938 935 75046406.47269 +951 935 5092655.779359 +952 935 30555176.43462 +953 935 178931711.3263 +954 935 30109969.49619 +955 935 -16958143.77251 +956 935 -8866000.069825 +1029 935 57454413.93615 +1030 935 7638794.112417 +1031 935 -95624557.03646 +1032 935 7154402.099879 +1033 935 7760464.058704 +1034 935 -1439551.802109 +1044 935 -2546327.890927 +1045 935 30555176.43461 +1046 935 -253876265.6798 +1047 935 -636581.9730468 +1048 935 29666856.21968 +1049 935 21737561.15826 +1062 935 -54908086.04521 +1063 935 7638794.112417 +1064 935 -77707668.15051 +1065 935 -6517820.126831 +1066 935 6996575.169565 +1067 935 748003.7541653 +936 936 736105860.3775 +937 936 -2.98023223877e-07 +938 936 -10185311.55874 +939 936 73722278.29235 +940 936 -3.725290298462e-07 +941 936 -2546327.890939 +951 936 -41010293.81404 +952 936 -30555555.55054 +953 936 -27563641.60526 +954 936 -60726571.61129 +955 936 6.407499313354e-07 +956 936 5092655.779359 +957 936 -44447793.81348 +958 936 30555555.55054 +959 936 29728025.052 +1029 936 -36875280.38624 +1030 936 7638888.891399 +1031 936 21477318.77125 +1032 936 -67815699.74408 +1033 936 2.041459083557e-06 +1034 936 57072469.49195 +1035 936 -10820592.87768 +1036 936 -7638888.891398 +1037 936 7154402.099879 +1044 936 -81234695.57722 +1045 936 1.624226570129e-06 +1046 936 -636581.9730444 +1047 936 -12957512.05534 +1048 936 5.960464477539e-08 +1049 936 -2546327.890928 +1050 936 19546554.40623 +1051 936 -1.84029340744e-06 +1052 936 -636581.9730468 +1062 936 -34336197.05207 +1063 936 -7638888.891398 +1064 936 -20840736.7982 +1065 936 -61096866.41184 +1066 936 -1.631677150726e-06 +1067 936 -54526141.60101 +1068 936 -10000259.54407 +1069 936 7638888.891397 +1070 936 -6517820.126831 +937 937 662768381.9265 +938 937 122220705.6783 +939 937 -2.682209014893e-07 +940 937 -42388655.88811 +941 937 -61110352.83913 +951 937 -30555555.55054 +952 937 -31843109.00315 +953 937 -13902588.21746 +954 937 8.642673492432e-07 +955 937 73718732.1729 +956 937 30555176.43462 +957 937 30555555.55054 +958 937 -35280609.00258 +959 937 -16652588.21716 +1029 937 7638888.891399 +1030 937 -34583484.18238 +1031 937 -15399258.17112 +1032 937 2.004206180573e-06 +1033 937 -34204373.78147 +1034 937 7638794.112417 +1035 937 -7638888.891398 +1036 937 -8528796.673826 +1037 937 7760464.058704 +1044 937 1.564621925354e-06 +1045 937 -110262429.1366 +1046 937 -59916477.09895 +1047 937 2.98023223877e-08 +1048 937 -31291881.67713 +1049 937 30555176.43461 +1050 937 -1.668930053711e-06 +1051 937 -9481179.15318 +1052 937 29361300.66432 +1062 937 -7638888.891398 +1063 937 -32044400.84822 +1064 937 -14635369.28198 +1065 937 -1.691281795502e-06 +1066 937 -27485540.44924 +1067 937 7638794.112417 +1068 937 7638888.891397 +1069 937 -7708463.340222 +1070 937 6996575.169565 +938 938 1085657360.643 +939 938 -2546327.890939 +940 938 -61110352.83913 +941 938 75046406.47269 +951 938 -27181697.16107 +952 938 -13597032.66211 +953 938 300666.5953339 +954 938 5092655.779359 +955 938 30555176.43462 +956 938 178931711.3263 +957 938 30109969.49619 +958 938 -16958143.77251 +959 938 -8866000.069825 +1029 938 21477318.77125 +1030 938 -15399258.17112 +1031 938 -70918718.4916 +1032 938 57454413.93615 +1033 938 7638794.112417 +1034 938 -95624557.03646 +1035 938 7154402.099879 +1036 938 7760464.058704 +1037 938 -1439551.802109 +1044 938 -636581.9730439 +1045 938 -60222032.6543 +1046 938 -247012438.7976 +1047 938 -2546327.890927 +1048 938 30555176.43461 +1049 938 -253876265.6798 +1050 938 -636581.9730468 +1051 938 29666856.21968 +1052 938 21737561.15826 +1062 938 -20840736.7982 +1063 938 -14635369.28198 +1064 938 -64147829.60048 +1065 938 -54908086.04521 +1066 938 7638794.112417 +1067 938 -77707668.15051 +1068 938 -6517820.126831 +1069 938 6996575.169565 +1070 938 748003.7541653 +939 939 736105860.3775 +940 939 -2.98023223877e-07 +941 939 -10185311.55874 +942 939 73722278.29235 +943 939 -3.725290298462e-07 +944 939 -2546327.890939 +954 939 -41010293.81404 +955 939 -30555555.55054 +956 939 -27563641.60526 +957 939 -60726571.61129 +958 939 6.407499313354e-07 +959 939 5092655.779359 +960 939 -44447793.81348 +961 939 30555555.55054 +962 939 29728025.052 +1032 939 -36875280.38624 +1033 939 7638888.891399 +1034 939 21477318.77125 +1035 939 -67815699.74408 +1036 939 2.041459083557e-06 +1037 939 57072469.49195 +1038 939 -10820592.87768 +1039 939 -7638888.891398 +1040 939 7154402.099879 +1047 939 -81234695.57722 +1048 939 1.624226570129e-06 +1049 939 -636581.9730444 +1050 939 -12957512.05534 +1051 939 5.960464477539e-08 +1052 939 -2546327.890928 +1053 939 19546554.40623 +1054 939 -1.84029340744e-06 +1055 939 -636581.9730468 +1065 939 -34336197.05207 +1066 939 -7638888.891398 +1067 939 -20840736.7982 +1068 939 -61096866.41184 +1069 939 -1.631677150726e-06 +1070 939 -54526141.60101 +1071 939 -10000259.54407 +1072 939 7638888.891397 +1073 939 -6517820.126831 +940 940 662768381.9265 +941 940 122220705.6783 +942 940 -2.682209014893e-07 +943 940 -42388655.88811 +944 940 -61110352.83913 +954 940 -30555555.55054 +955 940 -31843109.00315 +956 940 -13902588.21746 +957 940 8.642673492432e-07 +958 940 73718732.1729 +959 940 30555176.43462 +960 940 30555555.55054 +961 940 -35280609.00258 +962 940 -16652588.21716 +1032 940 7638888.891399 +1033 940 -34583484.18238 +1034 940 -15399258.17112 +1035 940 2.004206180573e-06 +1036 940 -34204373.78147 +1037 940 7638794.112417 +1038 940 -7638888.891398 +1039 940 -8528796.673826 +1040 940 7760464.058704 +1047 940 1.564621925354e-06 +1048 940 -110262429.1366 +1049 940 -59916477.09895 +1050 940 2.98023223877e-08 +1051 940 -31291881.67713 +1052 940 30555176.43461 +1053 940 -1.668930053711e-06 +1054 940 -9481179.15318 +1055 940 29361300.66432 +1065 940 -7638888.891398 +1066 940 -32044400.84822 +1067 940 -14635369.28198 +1068 940 -1.691281795502e-06 +1069 940 -27485540.44924 +1070 940 7638794.112417 +1071 940 7638888.891397 +1072 940 -7708463.340222 +1073 940 6996575.169565 +941 941 1085657360.643 +942 941 -2546327.890939 +943 941 -61110352.83913 +944 941 75046406.47269 +954 941 -27181697.16107 +955 941 -13597032.66211 +956 941 300666.5953339 +957 941 5092655.779359 +958 941 30555176.43462 +959 941 178931711.3263 +960 941 30109969.49619 +961 941 -16958143.77251 +962 941 -8866000.069825 +1032 941 21477318.77125 +1033 941 -15399258.17112 +1034 941 -70918718.4916 +1035 941 57454413.93615 +1036 941 7638794.112417 +1037 941 -95624557.03646 +1038 941 7154402.099879 +1039 941 7760464.058704 +1040 941 -1439551.802109 +1047 941 -636581.9730439 +1048 941 -60222032.6543 +1049 941 -247012438.7976 +1050 941 -2546327.890927 +1051 941 30555176.43461 +1052 941 -253876265.6798 +1053 941 -636581.9730468 +1054 941 29666856.21968 +1055 941 21737561.15826 +1065 941 -20840736.7982 +1066 941 -14635369.28198 +1067 941 -64147829.60048 +1068 941 -54908086.04521 +1069 941 7638794.112417 +1070 941 -77707668.15051 +1071 941 -6517820.126831 +1072 941 6996575.169565 +1073 941 748003.7541653 +942 942 736105860.3775 +943 942 -2.98023223877e-07 +944 942 -10185311.55874 +945 942 73722278.29235 +946 942 -3.725290298462e-07 +947 942 -2546327.890939 +957 942 -41010293.81404 +958 942 -30555555.55054 +959 942 -27563641.60526 +960 942 -60726571.61129 +961 942 6.407499313354e-07 +962 942 5092655.779359 +963 942 -44447793.81348 +964 942 30555555.55054 +965 942 29728025.052 +1035 942 -36875280.38624 +1036 942 7638888.891399 +1037 942 21477318.77125 +1038 942 -67815699.74408 +1039 942 2.041459083557e-06 +1040 942 57072469.49195 +1041 942 -10820592.87768 +1042 942 -7638888.891398 +1043 942 7154402.099879 +1050 942 -81234695.57722 +1051 942 1.624226570129e-06 +1052 942 -636581.9730444 +1053 942 -12957512.05534 +1054 942 5.960464477539e-08 +1055 942 -2546327.890928 +1056 942 19546554.40623 +1057 942 -1.84029340744e-06 +1058 942 -636581.9730468 +1068 942 -34336197.05207 +1069 942 -7638888.891398 +1070 942 -20840736.7982 +1071 942 -61096866.41184 +1072 942 -1.631677150726e-06 +1073 942 -54526141.60101 +1074 942 -10000259.54407 +1075 942 7638888.891397 +1076 942 -6517820.126831 +943 943 662768381.9265 +944 943 122220705.6783 +945 943 -2.682209014893e-07 +946 943 -42388655.88811 +947 943 -61110352.83913 +957 943 -30555555.55054 +958 943 -31843109.00315 +959 943 -13902588.21746 +960 943 8.642673492432e-07 +961 943 73718732.1729 +962 943 30555176.43462 +963 943 30555555.55054 +964 943 -35280609.00258 +965 943 -16652588.21716 +1035 943 7638888.891399 +1036 943 -34583484.18238 +1037 943 -15399258.17112 +1038 943 2.004206180573e-06 +1039 943 -34204373.78147 +1040 943 7638794.112417 +1041 943 -7638888.891398 +1042 943 -8528796.673826 +1043 943 7760464.058704 +1050 943 1.564621925354e-06 +1051 943 -110262429.1366 +1052 943 -59916477.09895 +1053 943 2.98023223877e-08 +1054 943 -31291881.67713 +1055 943 30555176.43461 +1056 943 -1.668930053711e-06 +1057 943 -9481179.15318 +1058 943 29361300.66432 +1068 943 -7638888.891398 +1069 943 -32044400.84822 +1070 943 -14635369.28198 +1071 943 -1.691281795502e-06 +1072 943 -27485540.44924 +1073 943 7638794.112417 +1074 943 7638888.891397 +1075 943 -7708463.340222 +1076 943 6996575.169565 +944 944 1085657360.643 +945 944 -2546327.890939 +946 944 -61110352.83913 +947 944 75046406.47269 +957 944 -27181697.16107 +958 944 -13597032.66211 +959 944 300666.5953339 +960 944 5092655.779359 +961 944 30555176.43462 +962 944 178931711.3263 +963 944 30109969.49619 +964 944 -16958143.77251 +965 944 -8866000.069825 +1035 944 21477318.77125 +1036 944 -15399258.17112 +1037 944 -70918718.4916 +1038 944 57454413.93615 +1039 944 7638794.112417 +1040 944 -95624557.03646 +1041 944 7154402.099879 +1042 944 7760464.058704 +1043 944 -1439551.802109 +1050 944 -636581.9730439 +1051 944 -60222032.6543 +1052 944 -247012438.7976 +1053 944 -2546327.890927 +1054 944 30555176.43461 +1055 944 -253876265.6798 +1056 944 -636581.9730468 +1057 944 29666856.21968 +1058 944 21737561.15826 +1068 944 -20840736.7982 +1069 944 -14635369.28198 +1070 944 -64147829.60048 +1071 944 -54908086.04521 +1072 944 7638794.112417 +1073 944 -77707668.15051 +1074 944 -6517820.126831 +1075 944 6996575.169565 +1076 944 748003.7541653 +945 945 754814074.6264 +946 945 30603006.96366 +947 945 -34373319.31429 +948 945 31201368.0013 +949 945 -30574536.11579 +950 945 -29746017.20074 +960 945 -41010293.81404 +961 945 -30555555.55054 +962 945 -27563641.60526 +963 945 -60726571.61129 +964 945 6.407499313354e-07 +965 945 5092655.779359 +966 945 -44447793.81348 +967 945 30555555.55054 +968 945 29728025.052 +1038 945 -36875280.38624 +1039 945 7638888.891399 +1040 945 21477318.77125 +1041 945 -88160408.62987 +1042 945 -7646006.603366 +1043 945 63145912.64445 +1053 945 -81234695.57722 +1054 945 1.624226570129e-06 +1055 945 -636581.9730444 +1056 945 3615653.321898 +1057 945 7650751.744684 +1058 945 -8598044.452827 +1059 945 3117023.124192 +1060 945 -7643634.032712 +1061 945 6521862.080229 +1071 945 -34336197.05207 +1072 945 -7638888.891398 +1073 945 -20840736.7982 +1074 945 -61096866.41184 +1075 945 -1.631677150726e-06 +1076 945 -54526141.60101 +1077 945 -10000259.54407 +1078 945 7638888.891397 +1079 945 -6517820.126831 +946 946 672288057.0206 +947 946 94722479.88535 +948 946 -30584026.39841 +949 946 -75780342.02739 +950 946 -50736841.1372 +960 946 -30555555.55054 +961 946 -31843109.00315 +962 946 -13902588.21746 +963 946 8.642673492432e-07 +964 946 73718732.1729 +965 946 30555176.43462 +966 946 30555555.55054 +967 946 -35280609.00258 +968 946 -16652588.21716 +1038 946 7638888.891399 +1039 946 -34583484.18238 +1040 946 -15399258.17112 +1041 946 -7643634.032709 +1042 946 -52242457.71267 +1043 946 19687387.29713 +1053 946 1.564621925354e-06 +1054 946 -110262429.1366 +1055 946 -59916477.09895 +1056 946 7650751.744683 +1057 946 -17015851.08971 +1058 946 23676848.33746 +1059 946 -7646006.603369 +1060 946 -23628404.39615 +1061 946 31972114.21773 +1071 946 -7638888.891398 +1072 946 -32044400.84822 +1073 946 -14635369.28198 +1074 946 -1.691281795502e-06 +1075 946 -27485540.44924 +1076 946 7638794.112417 +1077 946 7638888.891397 +1078 946 -7708463.340222 +1079 946 6996575.169565 +947 947 1025629032.871 +948 947 -30136957.7193 +949 947 -59299198.1827 +950 947 71356723.1218 +960 947 -27181697.16107 +961 947 -13597032.66211 +962 947 300666.5953339 +963 947 5092655.779359 +964 947 30555176.43462 +965 947 178931711.3263 +966 947 30109969.49619 +967 947 -16958143.77251 +968 947 -8866000.069825 +1038 947 21477318.77125 +1039 947 -15399258.17112 +1040 947 -70918718.4916 +1041 947 63530032.02016 +1042 947 21831451.86013 +1043 947 -122407379.4408 +1053 947 -636581.9730439 +1054 947 -60222032.6543 +1055 947 -247012438.7976 +1056 947 -8589356.089042 +1057 947 23683798.94222 +1058 947 -237160382.7964 +1059 947 6523883.056929 +1060 947 30136961.89646 +1061 947 5350330.44263 +1071 947 -20840736.7982 +1072 947 -14635369.28198 +1073 947 -64147829.60048 +1074 947 -54908086.04521 +1075 947 7638794.112417 +1076 947 -77707668.15051 +1077 947 -6517820.126831 +1078 947 6996575.169565 +1079 947 748003.7541653 +948 948 391747552.9943 +949 948 583468.7553267 +950 948 18460786.39383 +963 948 -41010293.81404 +964 948 -30555555.55054 +965 948 -27563641.60526 +966 948 -64957552.15474 +967 948 -658168.3244648 +968 948 1387084.494149 +969 948 -17226091.21786 +970 948 24519144.00957 +971 948 4595388.140829 +1041 948 -44000691.65356 +1042 948 9173784.381649 +1043 948 25410834.91903 +1056 948 -74169151.35949 +1057 948 -7646006.603371 +1058 948 -21497320.34861 +1059 948 -8042181.826519 +1060 948 145867.1889037 +1061 948 11655806.43098 +1074 948 -34336197.05207 +1075 948 -7638888.891398 +1076 948 -20840736.7982 +1077 948 -46993816.04493 +1078 948 -164542.081198 +1079 948 -41727721.81694 +1080 948 -9829239.428922 +1081 948 6129786.005412 +1082 948 -4979066.640203 +949 949 406443697.6504 +950 949 83812259.76818 +963 949 -30555555.55054 +964 949 -31843109.00315 +965 949 -13902588.21746 +966 949 -695518.1090343 +967 949 65399259.21915 +968 949 20008238.14593 +969 949 36778716.01435 +970 949 -64464522.03 +971 949 -11043214.84394 +1041 949 6115856.254433 +1042 949 -44000691.65356 +1043 949 -13552018.01794 +1056 949 -7643634.032713 +1057 949 -100914578.8798 +1058 949 -59481123.99205 +1059 949 145867.1889033 +1060 949 -4368145.660696 +1061 949 26571164.39647 +1074 949 -7638888.891398 +1075 949 -32044400.84822 +1076 949 -14635369.28198 +1077 949 -173879.5273452 +1078 949 -14404613.18541 +1079 949 4846854.379944 +1080 949 9194679.008118 +1081 949 -21638847.13778 +1082 949 14725306.89276 +950 950 609581923.258 +963 950 -27181697.16107 +964 950 -13597032.66211 +965 950 300666.5953339 +966 950 11311019.93814 +967 950 19699845.86993 +968 950 116805122.9509 +969 950 6893082.211243 +970 950 -9814986.833818 +971 950 1302187.56453 +1041 950 16940556.61269 +1042 950 -20328027.02691 +1043 950 -117335177.7428 +1056 950 -21490653.15616 +1057 950 -57645971.82207 +1058 950 -200746134.8472 +1059 950 -5288514.808431 +1060 950 13035968.8684 +1061 950 -130215372.7727 +1074 950 -20840736.7982 +1075 950 -14635369.28198 +1076 950 -64147829.60048 +1077 950 -39819358.2705 +1078 950 4553577.796946 +1079 950 -52810527.24323 +1080 950 -7468599.960305 +1081 950 12732043.03141 +1082 950 -14401697.43494 +951 951 736105860.3775 +952 951 -2.98023223877e-07 +953 951 -10185311.55874 +954 951 73722278.29235 +955 951 -3.725290298462e-07 +956 951 -2546327.890939 +972 951 -60726571.61129 +973 951 6.407499313354e-07 +974 951 5092655.779359 +975 951 -44447793.81348 +976 951 30555555.55054 +977 951 29728025.052 +1044 951 -67815699.74408 +1045 951 2.041459083557e-06 +1046 951 57072469.49195 +1047 951 -10820592.87768 +1048 951 -7638888.891398 +1049 951 7154402.099879 +1062 951 -12957512.05534 +1063 951 5.960464477539e-08 +1064 951 -2546327.890928 +1065 951 19546554.40623 +1066 951 -1.84029340744e-06 +1067 951 -636581.9730468 +1083 951 -61096866.41184 +1084 951 -1.631677150726e-06 +1085 951 -54526141.60101 +1086 951 -10000259.54407 +1087 951 7638888.891397 +1088 951 -6517820.126831 +952 952 662768381.9265 +953 952 122220705.6783 +954 952 -2.682209014893e-07 +955 952 -42388655.88811 +956 952 -61110352.83913 +972 952 8.642673492432e-07 +973 952 73718732.1729 +974 952 30555176.43462 +975 952 30555555.55054 +976 952 -35280609.00258 +977 952 -16652588.21716 +1044 952 2.004206180573e-06 +1045 952 -34204373.78147 +1046 952 7638794.112417 +1047 952 -7638888.891398 +1048 952 -8528796.673826 +1049 952 7760464.058704 +1062 952 2.98023223877e-08 +1063 952 -31291881.67713 +1064 952 30555176.43461 +1065 952 -1.668930053711e-06 +1066 952 -9481179.15318 +1067 952 29361300.66432 +1083 952 -1.691281795502e-06 +1084 952 -27485540.44924 +1085 952 7638794.112417 +1086 952 7638888.891397 +1087 952 -7708463.340222 +1088 952 6996575.169565 +953 953 1085657360.643 +954 953 -2546327.890939 +955 953 -61110352.83913 +956 953 75046406.47269 +972 953 5092655.779359 +973 953 30555176.43462 +974 953 178931711.3263 +975 953 30109969.49619 +976 953 -16958143.77251 +977 953 -8866000.069825 +1044 953 57454413.93615 +1045 953 7638794.112417 +1046 953 -95624557.03646 +1047 953 7154402.099879 +1048 953 7760464.058704 +1049 953 -1439551.802109 +1062 953 -2546327.890927 +1063 953 30555176.43461 +1064 953 -253876265.6798 +1065 953 -636581.9730468 +1066 953 29666856.21968 +1067 953 21737561.15826 +1083 953 -54908086.04521 +1084 953 7638794.112417 +1085 953 -77707668.15051 +1086 953 -6517820.126831 +1087 953 6996575.169565 +1088 953 748003.7541653 +954 954 736105860.3775 +955 954 -2.98023223877e-07 +956 954 -10185311.55874 +957 954 73722278.29235 +958 954 -3.725290298462e-07 +959 954 -2546327.890939 +972 954 -41010293.81404 +973 954 -30555555.55054 +974 954 -27563641.60526 +975 954 -60726571.61129 +976 954 6.407499313354e-07 +977 954 5092655.779359 +978 954 -44447793.81348 +979 954 30555555.55054 +980 954 29728025.052 +1044 954 -36875280.38624 +1045 954 7638888.891399 +1046 954 21477318.77125 +1047 954 -67815699.74408 +1048 954 2.041459083557e-06 +1049 954 57072469.49195 +1050 954 -10820592.87768 +1051 954 -7638888.891398 +1052 954 7154402.099879 +1062 954 -81234695.57722 +1063 954 1.624226570129e-06 +1064 954 -636581.9730444 +1065 954 -12957512.05534 +1066 954 5.960464477539e-08 +1067 954 -2546327.890928 +1068 954 19546554.40623 +1069 954 -1.84029340744e-06 +1070 954 -636581.9730468 +1083 954 -34336197.05207 +1084 954 -7638888.891398 +1085 954 -20840736.7982 +1086 954 -61096866.41184 +1087 954 -1.631677150726e-06 +1088 954 -54526141.60101 +1089 954 -10000259.54407 +1090 954 7638888.891397 +1091 954 -6517820.126831 +955 955 662768381.9265 +956 955 122220705.6783 +957 955 -2.682209014893e-07 +958 955 -42388655.88811 +959 955 -61110352.83913 +972 955 -30555555.55054 +973 955 -31843109.00315 +974 955 -13902588.21746 +975 955 8.642673492432e-07 +976 955 73718732.1729 +977 955 30555176.43462 +978 955 30555555.55054 +979 955 -35280609.00258 +980 955 -16652588.21716 +1044 955 7638888.891399 +1045 955 -34583484.18238 +1046 955 -15399258.17112 +1047 955 2.004206180573e-06 +1048 955 -34204373.78147 +1049 955 7638794.112417 +1050 955 -7638888.891398 +1051 955 -8528796.673826 +1052 955 7760464.058704 +1062 955 1.564621925354e-06 +1063 955 -110262429.1366 +1064 955 -59916477.09895 +1065 955 2.98023223877e-08 +1066 955 -31291881.67713 +1067 955 30555176.43461 +1068 955 -1.668930053711e-06 +1069 955 -9481179.15318 +1070 955 29361300.66432 +1083 955 -7638888.891398 +1084 955 -32044400.84822 +1085 955 -14635369.28198 +1086 955 -1.691281795502e-06 +1087 955 -27485540.44924 +1088 955 7638794.112417 +1089 955 7638888.891397 +1090 955 -7708463.340222 +1091 955 6996575.169565 +956 956 1085657360.643 +957 956 -2546327.890939 +958 956 -61110352.83913 +959 956 75046406.47269 +972 956 -27181697.16107 +973 956 -13597032.66211 +974 956 300666.5953339 +975 956 5092655.779359 +976 956 30555176.43462 +977 956 178931711.3263 +978 956 30109969.49619 +979 956 -16958143.77251 +980 956 -8866000.069825 +1044 956 21477318.77125 +1045 956 -15399258.17112 +1046 956 -70918718.4916 +1047 956 57454413.93615 +1048 956 7638794.112417 +1049 956 -95624557.03646 +1050 956 7154402.099879 +1051 956 7760464.058704 +1052 956 -1439551.802109 +1062 956 -636581.9730439 +1063 956 -60222032.6543 +1064 956 -247012438.7976 +1065 956 -2546327.890927 +1066 956 30555176.43461 +1067 956 -253876265.6798 +1068 956 -636581.9730468 +1069 956 29666856.21968 +1070 956 21737561.15826 +1083 956 -20840736.7982 +1084 956 -14635369.28198 +1085 956 -64147829.60048 +1086 956 -54908086.04521 +1087 956 7638794.112417 +1088 956 -77707668.15051 +1089 956 -6517820.126831 +1090 956 6996575.169565 +1091 956 748003.7541653 +957 957 736105860.3775 +958 957 -2.98023223877e-07 +959 957 -10185311.55874 +960 957 73722278.29235 +961 957 -3.725290298462e-07 +962 957 -2546327.890939 +975 957 -41010293.81404 +976 957 -30555555.55054 +977 957 -27563641.60526 +978 957 -60726571.61129 +979 957 6.407499313354e-07 +980 957 5092655.779359 +981 957 -44447793.81348 +982 957 30555555.55054 +983 957 29728025.052 +1047 957 -36875280.38624 +1048 957 7638888.891399 +1049 957 21477318.77125 +1050 957 -67815699.74408 +1051 957 2.041459083557e-06 +1052 957 57072469.49195 +1053 957 -10820592.87768 +1054 957 -7638888.891398 +1055 957 7154402.099879 +1065 957 -81234695.57722 +1066 957 1.624226570129e-06 +1067 957 -636581.9730444 +1068 957 -12957512.05534 +1069 957 5.960464477539e-08 +1070 957 -2546327.890928 +1071 957 19546554.40623 +1072 957 -1.84029340744e-06 +1073 957 -636581.9730468 +1086 957 -34336197.05207 +1087 957 -7638888.891398 +1088 957 -20840736.7982 +1089 957 -61096866.41184 +1090 957 -1.631677150726e-06 +1091 957 -54526141.60101 +1092 957 -10000259.54407 +1093 957 7638888.891397 +1094 957 -6517820.126831 +958 958 662768381.9265 +959 958 122220705.6783 +960 958 -2.682209014893e-07 +961 958 -42388655.88811 +962 958 -61110352.83913 +975 958 -30555555.55054 +976 958 -31843109.00315 +977 958 -13902588.21746 +978 958 8.642673492432e-07 +979 958 73718732.1729 +980 958 30555176.43462 +981 958 30555555.55054 +982 958 -35280609.00258 +983 958 -16652588.21716 +1047 958 7638888.891399 +1048 958 -34583484.18238 +1049 958 -15399258.17112 +1050 958 2.004206180573e-06 +1051 958 -34204373.78147 +1052 958 7638794.112417 +1053 958 -7638888.891398 +1054 958 -8528796.673826 +1055 958 7760464.058704 +1065 958 1.564621925354e-06 +1066 958 -110262429.1366 +1067 958 -59916477.09895 +1068 958 2.98023223877e-08 +1069 958 -31291881.67713 +1070 958 30555176.43461 +1071 958 -1.668930053711e-06 +1072 958 -9481179.15318 +1073 958 29361300.66432 +1086 958 -7638888.891398 +1087 958 -32044400.84822 +1088 958 -14635369.28198 +1089 958 -1.691281795502e-06 +1090 958 -27485540.44924 +1091 958 7638794.112417 +1092 958 7638888.891397 +1093 958 -7708463.340222 +1094 958 6996575.169565 +959 959 1085657360.643 +960 959 -2546327.890939 +961 959 -61110352.83913 +962 959 75046406.47269 +975 959 -27181697.16107 +976 959 -13597032.66211 +977 959 300666.5953339 +978 959 5092655.779359 +979 959 30555176.43462 +980 959 178931711.3263 +981 959 30109969.49619 +982 959 -16958143.77251 +983 959 -8866000.069825 +1047 959 21477318.77125 +1048 959 -15399258.17112 +1049 959 -70918718.4916 +1050 959 57454413.93615 +1051 959 7638794.112417 +1052 959 -95624557.03646 +1053 959 7154402.099879 +1054 959 7760464.058704 +1055 959 -1439551.802109 +1065 959 -636581.9730439 +1066 959 -60222032.6543 +1067 959 -247012438.7976 +1068 959 -2546327.890927 +1069 959 30555176.43461 +1070 959 -253876265.6798 +1071 959 -636581.9730468 +1072 959 29666856.21968 +1073 959 21737561.15826 +1086 959 -20840736.7982 +1087 959 -14635369.28198 +1088 959 -64147829.60048 +1089 959 -54908086.04521 +1090 959 7638794.112417 +1091 959 -77707668.15051 +1092 959 -6517820.126831 +1093 959 6996575.169565 +1094 959 748003.7541653 +960 960 736105860.3775 +961 960 -2.98023223877e-07 +962 960 -10185311.55874 +963 960 73722278.29235 +964 960 -3.725290298462e-07 +965 960 -2546327.890939 +978 960 -41010293.81404 +979 960 -30555555.55054 +980 960 -27563641.60526 +981 960 -60726571.61129 +982 960 6.407499313354e-07 +983 960 5092655.779359 +984 960 -44447793.81348 +985 960 30555555.55054 +986 960 29728025.052 +1050 960 -36875280.38624 +1051 960 7638888.891399 +1052 960 21477318.77125 +1053 960 -67815699.74408 +1054 960 2.041459083557e-06 +1055 960 57072469.49195 +1056 960 -10820592.87768 +1057 960 -7638888.891398 +1058 960 7154402.099879 +1068 960 -81234695.57722 +1069 960 1.624226570129e-06 +1070 960 -636581.9730444 +1071 960 -12957512.05534 +1072 960 5.960464477539e-08 +1073 960 -2546327.890928 +1074 960 19546554.40623 +1075 960 -1.84029340744e-06 +1076 960 -636581.9730468 +1089 960 -34336197.05207 +1090 960 -7638888.891398 +1091 960 -20840736.7982 +1092 960 -61096866.41184 +1093 960 -1.631677150726e-06 +1094 960 -54526141.60101 +1095 960 -10000259.54407 +1096 960 7638888.891397 +1097 960 -6517820.126831 +961 961 662768381.9265 +962 961 122220705.6783 +963 961 -2.682209014893e-07 +964 961 -42388655.88811 +965 961 -61110352.83913 +978 961 -30555555.55054 +979 961 -31843109.00315 +980 961 -13902588.21746 +981 961 8.642673492432e-07 +982 961 73718732.1729 +983 961 30555176.43462 +984 961 30555555.55054 +985 961 -35280609.00258 +986 961 -16652588.21716 +1050 961 7638888.891399 +1051 961 -34583484.18238 +1052 961 -15399258.17112 +1053 961 2.004206180573e-06 +1054 961 -34204373.78147 +1055 961 7638794.112417 +1056 961 -7638888.891398 +1057 961 -8528796.673826 +1058 961 7760464.058704 +1068 961 1.564621925354e-06 +1069 961 -110262429.1366 +1070 961 -59916477.09895 +1071 961 2.98023223877e-08 +1072 961 -31291881.67713 +1073 961 30555176.43461 +1074 961 -1.668930053711e-06 +1075 961 -9481179.15318 +1076 961 29361300.66432 +1089 961 -7638888.891398 +1090 961 -32044400.84822 +1091 961 -14635369.28198 +1092 961 -1.691281795502e-06 +1093 961 -27485540.44924 +1094 961 7638794.112417 +1095 961 7638888.891397 +1096 961 -7708463.340222 +1097 961 6996575.169565 +962 962 1085657360.643 +963 962 -2546327.890939 +964 962 -61110352.83913 +965 962 75046406.47269 +978 962 -27181697.16107 +979 962 -13597032.66211 +980 962 300666.5953339 +981 962 5092655.779359 +982 962 30555176.43462 +983 962 178931711.3263 +984 962 30109969.49619 +985 962 -16958143.77251 +986 962 -8866000.069825 +1050 962 21477318.77125 +1051 962 -15399258.17112 +1052 962 -70918718.4916 +1053 962 57454413.93615 +1054 962 7638794.112417 +1055 962 -95624557.03646 +1056 962 7154402.099879 +1057 962 7760464.058704 +1058 962 -1439551.802109 +1068 962 -636581.9730439 +1069 962 -60222032.6543 +1070 962 -247012438.7976 +1071 962 -2546327.890927 +1072 962 30555176.43461 +1073 962 -253876265.6798 +1074 962 -636581.9730468 +1075 962 29666856.21968 +1076 962 21737561.15826 +1089 962 -20840736.7982 +1090 962 -14635369.28198 +1091 962 -64147829.60048 +1092 962 -54908086.04521 +1093 962 7638794.112417 +1094 962 -77707668.15051 +1095 962 -6517820.126831 +1096 962 6996575.169565 +1097 962 748003.7541653 +963 963 736105860.3775 +964 963 -2.98023223877e-07 +965 963 -10185311.55874 +966 963 73722278.29235 +967 963 -3.725290298462e-07 +968 963 -2546327.890939 +981 963 -41010293.81404 +982 963 -30555555.55054 +983 963 -27563641.60526 +984 963 -60726571.61129 +985 963 6.407499313354e-07 +986 963 5092655.779359 +987 963 -44447793.81348 +988 963 30555555.55054 +989 963 29728025.052 +1053 963 -36875280.38624 +1054 963 7638888.891399 +1055 963 21477318.77125 +1056 963 -67815699.74408 +1057 963 2.041459083557e-06 +1058 963 57072469.49195 +1059 963 -10820592.87768 +1060 963 -7638888.891398 +1061 963 7154402.099879 +1071 963 -81234695.57722 +1072 963 1.624226570129e-06 +1073 963 -636581.9730444 +1074 963 -12957512.05534 +1075 963 5.960464477539e-08 +1076 963 -2546327.890928 +1077 963 19546554.40623 +1078 963 -1.84029340744e-06 +1079 963 -636581.9730468 +1092 963 -34336197.05207 +1093 963 -7638888.891398 +1094 963 -20840736.7982 +1095 963 -61096866.41184 +1096 963 -1.631677150726e-06 +1097 963 -54526141.60101 +1098 963 -10000259.54407 +1099 963 7638888.891397 +1100 963 -6517820.126831 +964 964 662768381.9265 +965 964 122220705.6783 +966 964 -2.682209014893e-07 +967 964 -42388655.88811 +968 964 -61110352.83913 +981 964 -30555555.55054 +982 964 -31843109.00315 +983 964 -13902588.21746 +984 964 8.642673492432e-07 +985 964 73718732.1729 +986 964 30555176.43462 +987 964 30555555.55054 +988 964 -35280609.00258 +989 964 -16652588.21716 +1053 964 7638888.891399 +1054 964 -34583484.18238 +1055 964 -15399258.17112 +1056 964 2.004206180573e-06 +1057 964 -34204373.78147 +1058 964 7638794.112417 +1059 964 -7638888.891398 +1060 964 -8528796.673826 +1061 964 7760464.058704 +1071 964 1.564621925354e-06 +1072 964 -110262429.1366 +1073 964 -59916477.09895 +1074 964 2.98023223877e-08 +1075 964 -31291881.67713 +1076 964 30555176.43461 +1077 964 -1.668930053711e-06 +1078 964 -9481179.15318 +1079 964 29361300.66432 +1092 964 -7638888.891398 +1093 964 -32044400.84822 +1094 964 -14635369.28198 +1095 964 -1.691281795502e-06 +1096 964 -27485540.44924 +1097 964 7638794.112417 +1098 964 7638888.891397 +1099 964 -7708463.340222 +1100 964 6996575.169565 +965 965 1085657360.643 +966 965 -2546327.890939 +967 965 -61110352.83913 +968 965 75046406.47269 +981 965 -27181697.16107 +982 965 -13597032.66211 +983 965 300666.5953339 +984 965 5092655.779359 +985 965 30555176.43462 +986 965 178931711.3263 +987 965 30109969.49619 +988 965 -16958143.77251 +989 965 -8866000.069825 +1053 965 21477318.77125 +1054 965 -15399258.17112 +1055 965 -70918718.4916 +1056 965 57454413.93615 +1057 965 7638794.112417 +1058 965 -95624557.03646 +1059 965 7154402.099879 +1060 965 7760464.058704 +1061 965 -1439551.802109 +1071 965 -636581.9730439 +1072 965 -60222032.6543 +1073 965 -247012438.7976 +1074 965 -2546327.890927 +1075 965 30555176.43461 +1076 965 -253876265.6798 +1077 965 -636581.9730468 +1078 965 29666856.21968 +1079 965 21737561.15826 +1092 965 -20840736.7982 +1093 965 -14635369.28198 +1094 965 -64147829.60048 +1095 965 -54908086.04521 +1096 965 7638794.112417 +1097 965 -77707668.15051 +1098 965 -6517820.126831 +1099 965 6996575.169565 +1100 965 748003.7541653 +966 966 618356973.1438 +967 966 10078107.65728 +968 966 -9804310.999607 +969 966 -11503867.92228 +970 966 -46894042.93799 +971 966 -6199331.236185 +984 966 -41010293.81404 +985 966 -30555555.55054 +986 966 -27563641.60526 +987 966 -42028446.52583 +988 966 13616733.15273 +989 966 872010.5456597 +990 966 -16600070.15644 +991 966 23894720.23701 +992 966 3821797.162853 +1056 966 -36875280.38624 +1057 966 7638888.891399 +1058 966 21477318.77125 +1059 966 -54114504.27018 +1060 966 -173879.5273432 +1061 966 44902247.92658 +1074 966 -81234695.57722 +1075 966 1.624226570129e-06 +1076 966 -636581.9730444 +1077 966 -876482.9019934 +1078 966 2519526.915563 +1079 966 -2460507.026248 +1080 966 -27045633.06006 +1081 966 -11723510.74027 +1082 966 12416379.47746 +1095 966 -34336197.05207 +1096 966 -7638888.891398 +1097 966 -20840736.7982 +1098 966 -53125239.25827 +1099 966 3404183.289858 +1100 966 -48696407.07857 +1101 966 -13272078.15617 +1102 966 5973680.062196 +1103 966 -6110175.711185 +967 967 624557688.2301 +968 967 75196749.74012 +969 967 -46931392.72256 +970 967 -125004050.7393 +971 967 -12917601.41412 +984 967 -30555555.55054 +985 967 -31843109.00315 +986 967 -13902588.21746 +987 967 13616733.15273 +988 967 72567559.79109 +989 967 16835459.46007 +990 967 23894720.23701 +991 967 -56476855.55795 +992 967 -6842420.271103 +1056 967 7638888.891399 +1057 967 -34583484.18238 +1058 967 -15399258.17112 +1059 967 -164542.0811964 +1060 967 -21525301.41066 +1061 967 5061950.597479 +1074 967 1.564621925354e-06 +1075 967 -110262429.1366 +1076 967 -59916477.09895 +1077 967 2519526.915562 +1078 967 673695.8703558 +1079 967 18791643.5427 +1080 967 -11732848.18642 +1081 967 -55420678.77829 +1082 967 41466871.49251 +1095 967 -7638888.891398 +1096 967 -32044400.84822 +1097 967 -14635369.28198 +1098 967 3404183.289858 +1099 967 -24476237.66492 +1100 967 9715809.309978 +1101 967 5973680.062196 +1102 967 -23241274.51146 +1103 967 14956061.60352 +968 968 853460318.6126 +969 968 -6587303.084687 +970 968 -14142186.07844 +971 968 48525682.42527 +984 968 -27181697.16107 +985 968 -13597032.66211 +986 968 300666.5953339 +987 968 10420621.6552 +988 968 17141015.01558 +989 968 158859271.764 +990 968 4585686.05124 +991 968 -6842420.271103 +992 968 13285136.71385 +1056 968 21477318.77125 +1057 968 -15399258.17112 +1058 968 -70918718.4916 +1059 968 42993884.38014 +1060 968 5382550.883186 +1061 968 -71799029.17722 +1074 968 -636581.9730439 +1075 968 -60222032.6543 +1076 968 -247012438.7976 +1077 968 -2443130.228498 +1078 968 18805545.65999 +1079 968 -201210190.2793 +1080 968 12423412.7955 +1081 968 41458540.64078 +1082 968 -52321022.26258 +1095 968 -20840736.7982 +1096 968 -14635369.28198 +1097 968 -64147829.60048 +1098 968 -46786684.85391 +1099 968 9715809.311131 +1100 968 -73933522.36379 +1101 968 -6110175.711185 +1102 968 14956061.60352 +1103 968 -21004210.79327 +969 969 442875011.6958 +970 969 8398998.740506 +971 969 3587449.702806 +987 969 -37900199.70542 +988 969 -29669012.21209 +989 969 -4192679.813966 +990 969 23914388.45506 +991 969 18670678.36176 +992 969 1284371.73895 +993 969 79386790.30619 +994 969 -13623383.55779 +995 969 -141175.7616777 +996 969 2420595.755201 +997 969 26375395.37582 +998 969 684032.7841115 +1059 969 -17822239.3706 +1060 969 9194679.008118 +1061 969 9770196.805889 +1077 969 -41046754.09296 +1078 969 -11732848.18642 +1079 969 -15622467.2995 +1080 969 -55034990.49984 +1081 969 2099749.686162 +1082 969 10931445.7583 +1098 969 -23479926.51996 +1099 969 -7417253.056677 +1100 969 -14997301.90306 +1101 969 -65005495.31362 +1102 969 4667669.592739 +1103 969 -54435157.05621 +1104 969 -28235802.42725 +1105 969 -3405845.891125 +1106 969 10910713.0034 +1107 969 -20886441.98794 +1108 969 6593848.847203 +1109 969 -13257984.86388 +970 970 541110906.0816 +971 970 22621038.86925 +987 970 -29669012.21209 +988 970 -18428194.76081 +989 970 -786622.899826 +990 970 18670678.36176 +991 970 137453909.9061 +992 970 4611190.584816 +993 970 -1401161.337575 +994 970 19991930.1348 +995 970 -593772.9185854 +996 970 26375395.37582 +997 970 -8693351.225763 +998 970 -679725.193279 +1059 970 6129786.005412 +1060 970 -29631847.07945 +1061 970 -18404535.59174 +1077 970 -11723510.74027 +1078 970 -69421799.81119 +1079 970 -48221146.21121 +1080 970 2099749.686162 +1081 970 -30476016.89128 +1082 970 7201253.461998 +1098 970 -7417253.056677 +1099 970 -18611925.28141 +1100 970 -11356377.95096 +1101 970 4667669.592739 +1102 970 -36620614.93688 +1103 970 6659742.089658 +1104 970 -350290.3345659 +1105 970 -43084517.47741 +1106 970 33184890.09814 +1107 970 6593848.847203 +1108 970 -23664928.73455 +1109 970 16496735.37374 +971 971 742023994.5875 +987 971 -3810735.369772 +988 971 -481067.3444712 +989 971 19538445.84481 +990 971 2812149.516478 +991 971 4916746.140321 +992 971 248223025.1829 +993 971 240768.6827077 +994 971 -593772.9185855 +995 971 164839361.9377 +996 971 1065977.228305 +997 971 -679725.193279 +998 971 60791642.10178 +1059 971 6513464.53726 +1060 971 -21008507.25432 +1061 971 -35716363.94607 +1077 971 -15612123.92226 +1078 971 -48226237.0269 +1079 971 -89657345.01698 +1080 971 -11047443.12698 +1081 971 2590596.573928 +1082 971 -256503983.8706 +1098 971 -14997301.90306 +1099 971 -11356377.95096 +1100 971 -32461726.1069 +1101 971 -54435157.05583 +1102 971 6659742.090811 +1103 971 -127235156.8213 +1104 971 2785713.002169 +1105 971 33184890.09814 +1106 971 -87010159.53147 +1107 971 -13257984.86388 +1108 971 16496735.37374 +1109 971 -42112998.60584 +972 972 368052930.1888 +973 972 -5.960464477539e-07 +974 972 -5092655.779371 +975 972 36918430.8128 +976 972 6111111.110107 +977 972 3501141.609773 +1062 972 -67815699.74408 +1063 972 2.041459083557e-06 +1064 972 57072469.49195 +1065 972 -10820592.87768 +1066 972 -7638888.891398 +1067 972 7154402.099879 +1083 972 -6536047.694301 +1084 972 -2.086162567139e-07 +1085 972 -11516358.3887 +1086 972 9773277.203117 +1087 972 1527777.778279 +1088 972 -1685513.209194 +973 973 331384190.9633 +974 973 61110352.83914 +975 973 -6111111.110108 +976 973 -21137036.27743 +977 973 -30249620.86406 +1062 973 2.004206180573e-06 +1063 973 -34204373.78147 +1064 973 7638794.112417 +1065 973 -7638888.891398 +1066 973 -8528796.673826 +1067 973 7760464.058704 +1083 973 4.768371582031e-07 +1084 973 -15703232.5052 +1085 973 15277588.21731 +1086 973 -1527777.77828 +1087 973 -4740589.576589 +1088 973 14757039.22107 +974 974 542828680.3217 +975 974 -7957191.721679 +976 974 -30860731.97507 +977 974 37675981.01402 +1062 974 57454413.93615 +1063 974 7638794.112417 +1064 974 -95624557.03646 +1065 974 7154402.099879 +1066 974 7760464.058704 +1067 974 -1439551.802109 +1083 974 10879752.71874 +1084 974 15277588.21731 +1085 974 -127090910.6176 +1086 974 1048931.236148 +1087 974 14757039.22092 +1088 974 10868780.57913 +975 975 368052930.1888 +976 975 -5.960464477539e-07 +977 975 -5092655.779371 +978 975 36918430.8128 +979 975 6111111.110107 +980 975 3501141.609773 +1062 975 -36875280.38624 +1063 975 7638888.891399 +1064 975 21477318.77125 +1065 975 -67815699.74408 +1066 975 2.041459083557e-06 +1067 975 57072469.49195 +1068 975 -10820592.87768 +1069 975 -7638888.891398 +1070 975 7154402.099879 +1083 975 -40617347.78861 +1084 975 -1527777.778279 +1085 975 -4550096.543467 +1086 975 -6536047.694301 +1087 975 -2.086162567139e-07 +1088 975 -11516358.3887 +1089 975 9773277.203117 +1090 975 1527777.778279 +1091 975 -1685513.209194 +976 976 331384190.9633 +977 976 61110352.83914 +978 976 -6111111.110108 +979 976 -21137036.27743 +980 976 -30249620.86406 +1062 976 7638888.891399 +1063 976 -34583484.18238 +1064 976 -15399258.17112 +1065 976 2.004206180573e-06 +1066 976 -34204373.78147 +1067 976 7638794.112417 +1068 976 -7638888.891398 +1069 976 -8528796.673826 +1070 976 7760464.058704 +1083 976 1527777.77828 +1084 976 -55131214.56832 +1085 976 -30034627.43839 +1086 976 4.768371582031e-07 +1087 976 -15703232.5052 +1088 976 15277588.21731 +1089 976 -1527777.77828 +1090 976 -4740589.576589 +1091 976 14757039.22107 +977 977 542828680.3217 +978 977 -7957191.721679 +979 977 -30860731.97507 +980 977 37675981.01402 +1062 977 21477318.77125 +1063 977 -15399258.17112 +1064 977 -70918718.4916 +1065 977 57454413.93615 +1066 977 7638794.112417 +1067 977 -95624557.03646 +1068 977 7154402.099879 +1069 977 7760464.058704 +1070 977 -1439551.802109 +1083 977 3913514.570423 +1084 977 -30034627.43824 +1085 977 -123506219.3988 +1086 977 10879752.71874 +1087 977 15277588.21731 +1088 977 -127090910.6176 +1089 977 1048931.236148 +1090 977 14757039.22092 +1091 977 10868780.57913 +978 978 368052930.1888 +979 978 -5.960464477539e-07 +980 978 -5092655.779371 +981 978 36918430.8128 +982 978 6111111.110107 +983 978 3501141.609773 +1065 978 -36875280.38624 +1066 978 7638888.891399 +1067 978 21477318.77125 +1068 978 -67815699.74408 +1069 978 2.041459083557e-06 +1070 978 57072469.49195 +1071 978 -10820592.87768 +1072 978 -7638888.891398 +1073 978 7154402.099879 +1086 978 -40617347.78861 +1087 978 -1527777.778279 +1088 978 -4550096.543467 +1089 978 -6536047.694301 +1090 978 -2.086162567139e-07 +1091 978 -11516358.3887 +1092 978 9773277.203117 +1093 978 1527777.778279 +1094 978 -1685513.209194 +979 979 331384190.9633 +980 979 61110352.83914 +981 979 -6111111.110108 +982 979 -21137036.27743 +983 979 -30249620.86406 +1065 979 7638888.891399 +1066 979 -34583484.18238 +1067 979 -15399258.17112 +1068 979 2.004206180573e-06 +1069 979 -34204373.78147 +1070 979 7638794.112417 +1071 979 -7638888.891398 +1072 979 -8528796.673826 +1073 979 7760464.058704 +1086 979 1527777.77828 +1087 979 -55131214.56832 +1088 979 -30034627.43839 +1089 979 4.768371582031e-07 +1090 979 -15703232.5052 +1091 979 15277588.21731 +1092 979 -1527777.77828 +1093 979 -4740589.576589 +1094 979 14757039.22107 +980 980 542828680.3217 +981 980 -7957191.721679 +982 980 -30860731.97507 +983 980 37675981.01402 +1065 980 21477318.77125 +1066 980 -15399258.17112 +1067 980 -70918718.4916 +1068 980 57454413.93615 +1069 980 7638794.112417 +1070 980 -95624557.03646 +1071 980 7154402.099879 +1072 980 7760464.058704 +1073 980 -1439551.802109 +1086 980 3913514.570423 +1087 980 -30034627.43824 +1088 980 -123506219.3988 +1089 980 10879752.71874 +1090 980 15277588.21731 +1091 980 -127090910.6176 +1092 980 1048931.236148 +1093 980 14757039.22092 +1094 980 10868780.57913 +981 981 368052930.1888 +982 981 -5.960464477539e-07 +983 981 -5092655.779371 +984 981 36918430.8128 +985 981 6111111.110107 +986 981 3501141.609773 +1068 981 -36875280.38624 +1069 981 7638888.891399 +1070 981 21477318.77125 +1071 981 -67815699.74408 +1072 981 2.041459083557e-06 +1073 981 57072469.49195 +1074 981 -10820592.87768 +1075 981 -7638888.891398 +1076 981 7154402.099879 +1089 981 -40617347.78861 +1090 981 -1527777.778279 +1091 981 -4550096.543467 +1092 981 -6536047.694301 +1093 981 -2.086162567139e-07 +1094 981 -11516358.3887 +1095 981 9773277.203117 +1096 981 1527777.778279 +1097 981 -1685513.209194 +982 982 331384190.9633 +983 982 61110352.83914 +984 982 -6111111.110108 +985 982 -21137036.27743 +986 982 -30249620.86406 +1068 982 7638888.891399 +1069 982 -34583484.18238 +1070 982 -15399258.17112 +1071 982 2.004206180573e-06 +1072 982 -34204373.78147 +1073 982 7638794.112417 +1074 982 -7638888.891398 +1075 982 -8528796.673826 +1076 982 7760464.058704 +1089 982 1527777.77828 +1090 982 -55131214.56832 +1091 982 -30034627.43839 +1092 982 4.768371582031e-07 +1093 982 -15703232.5052 +1094 982 15277588.21731 +1095 982 -1527777.77828 +1096 982 -4740589.576589 +1097 982 14757039.22107 +983 983 542828680.3217 +984 983 -7957191.721679 +985 983 -30860731.97507 +986 983 37675981.01402 +1068 983 21477318.77125 +1069 983 -15399258.17112 +1070 983 -70918718.4916 +1071 983 57454413.93615 +1072 983 7638794.112417 +1073 983 -95624557.03646 +1074 983 7154402.099879 +1075 983 7760464.058704 +1076 983 -1439551.802109 +1089 983 3913514.570423 +1090 983 -30034627.43824 +1091 983 -123506219.3988 +1092 983 10879752.71874 +1093 983 15277588.21731 +1094 983 -127090910.6176 +1095 983 1048931.236148 +1096 983 14757039.22092 +1097 983 10868780.57913 +984 984 368052930.1888 +985 984 -5.960464477539e-07 +986 984 -5092655.779371 +987 984 36918430.8128 +988 984 6111111.110107 +989 984 3501141.609773 +1071 984 -36875280.38624 +1072 984 7638888.891399 +1073 984 21477318.77125 +1074 984 -67815699.74408 +1075 984 2.041459083557e-06 +1076 984 57072469.49195 +1077 984 -10820592.87768 +1078 984 -7638888.891398 +1079 984 7154402.099879 +1092 984 -40617347.78861 +1093 984 -1527777.778279 +1094 984 -4550096.543467 +1095 984 -6536047.694301 +1096 984 -2.086162567139e-07 +1097 984 -11516358.3887 +1098 984 9773277.203117 +1099 984 1527777.778279 +1100 984 -1685513.209194 +985 985 331384190.9633 +986 985 61110352.83914 +987 985 -6111111.110108 +988 985 -21137036.27743 +989 985 -30249620.86406 +1071 985 7638888.891399 +1072 985 -34583484.18238 +1073 985 -15399258.17112 +1074 985 2.004206180573e-06 +1075 985 -34204373.78147 +1076 985 7638794.112417 +1077 985 -7638888.891398 +1078 985 -8528796.673826 +1079 985 7760464.058704 +1092 985 1527777.77828 +1093 985 -55131214.56832 +1094 985 -30034627.43839 +1095 985 4.768371582031e-07 +1096 985 -15703232.5052 +1097 985 15277588.21731 +1098 985 -1527777.77828 +1099 985 -4740589.576589 +1100 985 14757039.22107 +986 986 542828680.3217 +987 986 -7957191.721679 +988 986 -30860731.97507 +989 986 37675981.01402 +1071 986 21477318.77125 +1072 986 -15399258.17112 +1073 986 -70918718.4916 +1074 986 57454413.93615 +1075 986 7638794.112417 +1076 986 -95624557.03646 +1077 986 7154402.099879 +1078 986 7760464.058704 +1079 986 -1439551.802109 +1092 986 3913514.570423 +1093 986 -30034627.43824 +1094 986 -123506219.3988 +1095 986 10879752.71874 +1096 986 15277588.21731 +1097 986 -127090910.6176 +1098 986 1048931.236148 +1099 986 14757039.22092 +1100 986 10868780.57913 +987 987 349156585.9481 +988 987 886715.7050995 +989 987 -27554881.40078 +990 987 34686442.2226 +991 987 -9278881.086166 +992 987 -2735560.435943 +1074 987 -36875280.38624 +1075 987 7638888.891399 +1076 987 21477318.77125 +1077 987 -60781458.00658 +1078 987 3404183.289861 +1079 987 51519565.1286 +1080 987 -20120523.74107 +1081 987 -7417253.056677 +1082 987 12996448.10614 +1095 987 -40617347.78861 +1096 987 -1527777.778279 +1097 987 -4550096.543467 +1098 987 -11601369.55203 +1099 987 221678.9263838 +1100 987 -17131637.01904 +1101 987 -13469946.66151 +1102 987 -2319720.272684 +1103 987 3638957.111577 +988 988 322798770.6263 +989 988 37560511.47895 +990 988 -21501103.30638 +991 988 -24135471.43778 +992 988 -6401583.40246 +1074 988 7638888.891399 +1075 988 -34583484.18238 +1076 988 -15399258.17112 +1077 988 3404183.28986 +1078 988 -32132456.41324 +1079 988 -1221690.688151 +1080 988 -7417253.056677 +1081 988 -15252522.50252 +1082 988 11039455.38973 +1095 988 1527777.77828 +1096 988 -55131214.56832 +1097 988 -30034627.43839 +1098 988 221678.9263841 +1099 988 -18190823.38574 +1100 988 9390127.87436 +1101 988 -5375275.829243 +1102 988 -28175425.08385 +1103 988 26225993.03356 +989 989 503393397.4494 +990 989 -4645282.657855 +991 989 -6707138.957965 +992 989 79758954.50096 +1074 989 21477318.77125 +1075 989 -15399258.17112 +1076 989 -70918718.4916 +1077 989 49609842.90663 +1078 989 -1221690.687148 +1079 989 -94350105.69262 +1080 989 12996448.10614 +1081 989 11039455.38973 +1082 989 -23503318.69652 +1095 989 3913514.570423 +1096 989 -30034627.43824 +1097 989 -123506219.3988 +1098 989 5263918.532836 +1099 989 9390127.87436 +1100 989 -137859693.4611 +1101 989 8664790.445306 +1102 989 26225993.03241 +1103 989 -39104413.95542 +990 990 366758257.2118 +991 990 16768677.5657 +992 990 -2112503.704189 +993 990 -37682552.38635 +994 990 -34735715.72525 +995 990 -1034717.215718 +996 990 48319481.61887 +997 990 -3097257.132841 +998 990 -1133109.766727 +1077 990 -19678307.32513 +1078 990 5973680.062196 +1079 990 8212046.515743 +1080 990 -66802346.00857 +1081 990 4667669.592741 +1082 990 55459287.37057 +1098 990 -24485575.13151 +1099 990 -5375275.829244 +1100 990 -10605487.33072 +1101 990 -49124876.9151 +1102 990 4192169.39349 +1103 990 -10562709.25846 +1104 990 -30912229.02827 +1105 990 -8683928.935591 +1106 990 20053820.70261 +1107 990 -25803993.24156 +1108 990 -774314.2835916 +1109 990 4143597.555308 +991 991 396792772.5139 +992 991 11437666.13523 +993 991 -34735715.72525 +994 991 -23732031.77885 +995 991 -679725.1932795 +996 991 -15319479.35305 +997 991 -10506376.67983 +998 991 -2125127.853192 +1077 991 5973680.062196 +1078 991 -29647503.68042 +1079 991 -18377271.74076 +1080 991 4667669.59274 +1081 991 -38417465.63183 +1082 991 -4277757.90847 +1098 991 -2319720.272685 +1099 991 -39191053.55385 +1100 991 -29503173.62402 +1101 991 4192169.39349 +1102 991 -41616248.08588 +1103 991 2859416.535212 +1104 991 -8683928.935591 +1105 991 -27424598.87467 +1106 991 16496735.37374 +1107 991 -3829869.84015 +1108 991 -40510457.82348 +1109 991 32802051.3643 +992 992 608782949.2713 +993 992 -1034717.215718 +994 992 -679725.1932796 +995 992 45752961.54869 +996 992 -1515054.211112 +997 992 -2125127.853192 +998 992 122586164.6905 +1077 992 8212046.515743 +1078 992 -18377271.74076 +1079 992 -38087488.57717 +1080 992 55459287.37019 +1081 992 -4277757.907468 +1082 992 -132026758.6745 +1098 992 -4433820.663462 +1099 992 -29503173.62502 +1100 992 -68479423.20874 +1101 992 11416179.62681 +1102 992 2859416.535213 +1103 992 -223309439.3091 +1104 992 20053820.70261 +1105 992 16496735.37374 +1106 992 -45872668.74596 +1107 992 9343319.780678 +1108 992 32802051.3643 +1109 992 -70377095.21823 +993 993 234609876.3001 +994 993 38067827.99822 +995 993 586777.6138301 +996 993 6982249.404681 +997 993 -1930950.93539 +998 993 207170.9191803 +1080 993 -29485802.42768 +1081 993 -350290.3345662 +1082 993 -2760814.77204 +1101 993 -32162229.02869 +1102 993 -8683928.935592 +1103 993 -20571179.31073 +1104 993 -38762530.87567 +1105 993 9516957.004243 +1106 993 8271694.402195 +1107 993 -42487619.48068 +1108 993 -482737.734086 +1109 993 -33689700.31943 +994 994 219525569.817 +995 994 593772.9185901 +996 994 10291271.28482 +997 994 67510895.4516 +998 994 679725.1932815 +1080 994 -3405845.891125 +1081 994 -44334517.47785 +1082 994 -33481776.55758 +1101 994 -8683928.935592 +1102 994 -28674598.8751 +1103 994 -16836597.97054 +1104 994 9516957.004243 +1105 994 -42533607.49829 +1106 994 6815109.89529 +1107 994 2572817.822473 +1108 994 -27355457.96149 +1109 994 3503264.632831 +995 995 399394804.6128 +996 995 589115.3635656 +997 995 679725.1932814 +998 995 145469841.5664 +1080 995 -10885814.77346 +1081 995 -33481776.55758 +1082 995 -90343492.86596 +1101 995 -20571179.31073 +1102 995 -16836597.97054 +1103 995 -49206002.08042 +1104 995 -7978305.595135 +1105 995 -6518223.435853 +1106 995 -159924632.0765 +1107 995 -33689700.32068 +1108 995 -3163402.036025 +1109 995 -81587691.14437 +996 996 189779491.4148 +997 996 -21347187.30759 +998 996 -903927.2691454 +1080 996 -22136441.98836 +1081 996 6593848.847203 +1082 996 13695487.3672 +1101 996 -29553993.24035 +1102 996 -3829869.840151 +1103 996 -9718902.442414 +1104 996 -42487619.48068 +1105 996 2572817.822474 +1106 996 33888771.89179 +1107 996 -32072854.387 +1108 996 -5336796.829526 +1109 996 -5139245.705715 +997 997 199190650.6476 +998 997 2125127.853197 +1080 997 6593848.847203 +1081 997 -24914928.73497 +1082 997 -16836597.97054 +1101 997 -774314.283592 +1102 997 -44260457.82227 +1103 997 -33864615.29142 +1104 997 -482737.7340849 +1105 997 -27355457.96149 +1106 997 3503264.632831 +1107 997 -5336796.829526 +1108 997 -29720064.57765 +1109 997 7197948.62913 +998 998 331157200.1575 +1080 998 13695487.3672 +1081 998 -16836597.97054 +1082 998 -45446331.9403 +1101 998 -4137235.77266 +1102 998 -33864615.29142 +1103 998 -80377095.215 +1104 998 33888771.89035 +1105 998 -3163402.036025 +1106 998 -81587691.14436 +1107 998 5642143.181403 +1108 998 -6135384.702013 +1109 998 -129257972.624 +999 999 460369459.7115 +1000 999 30555555.55053 +1001 999 -36969735.5824 +1002 999 -133707927.5673 +1003 999 -30577597.78773 +1004 999 30839786.14823 +1005 999 -4378484.728122 +1006 999 24466486.67763 +1007 999 22175044.36675 +1110 999 18346673.71113 +1111 999 7638888.891398 +1112 999 1385379.035684 +1113 999 -55802716.54489 +1114 999 -7645254.369757 +1115 999 -40856339.07483 +1116 999 6123446.608564 +1117 999 6117476.591476 +1118 999 -3944940.585509 +1000 1000 414508539.3263 +1001 1000 70321276.71584 +1002 1000 -30588618.90633 +1003 1000 9973548.859403 +1004 1000 42647671.20218 +1005 1000 36699730.01644 +1006 1000 -4378484.728126 +1007 1000 -28439541.86765 +1110 1000 7638888.891397 +1111 1000 6880428.6391 +1112 1000 26085656.47845 +1113 1000 -7648437.108936 +1114 1000 -19879647.51159 +1115 1000 942630.1669732 +1116 1000 9176214.887214 +1117 1000 6123446.608565 +1118 1000 4734398.284357 +1001 1001 679047623.5514 +1002 1001 27774811.43114 +1003 1001 33778935.02398 +1004 1001 94229239.45832 +1005 1001 33262566.55012 +1006 1001 -18959694.57843 +1007 1001 -11675959.27499 +1110 1001 -17965238.89317 +1111 1001 10605384.60401 +1112 1001 -88238208.0348 +1113 1001 -41241201.16555 +1114 1001 -1194514.850572 +1115 1001 -36101396.81649 +1116 1001 -5917410.878264 +1117 1001 3156265.522905 +1118 1001 16329190.95617 +1002 1002 721009953.5089 +1003 1002 30610661.14353 +1004 1002 -34376411.47656 +1005 1002 22252951.07536 +1006 1002 -30577597.78774 +1007 1002 -30132237.29345 +1008 1002 -69150427.22048 +1009 1002 7.599592208862e-07 +1010 1002 6620438.369471 +1011 1002 -46611023.324 +1012 1002 30555555.55054 +1013 1002 30109970.69972 +1110 1002 -79032837.45136 +1111 1002 -7648437.10893 +1112 1002 55511888.47871 +1113 1002 34928101.59242 +1114 1002 7654802.58729 +1115 1002 -8598678.217522 +1116 1002 5149787.278365 +1117 1002 -7645254.369755 +1118 1002 4611926.752539 +1119 1002 -53208020.04453 +1120 1002 -1.534819602966e-06 +1121 1002 -46887250.21518 +1122 1002 -9746784.424485 +1123 1002 7638888.891396 +1124 1002 -4608097.279433 +1003 1003 638480136.047 +1004 1003 94719923.44838 +1005 1003 -30588618.90634 +1006 1003 -84734829.23983 +1007 1003 -51960954.36765 +1008 1003 5.662441253662e-07 +1009 1003 65294942.0157 +1010 1003 30555147.55986 +1011 1003 30555555.55054 +1012 1003 -37443799.05029 +1013 1003 -16958129.33543 +1110 1003 -7645254.369751 +1111 1003 -43109768.41806 +1112 1003 18161862.49682 +1113 1003 7654802.587289 +1114 1003 14294589.76961 +1115 1003 23676298.37333 +1116 1003 -7648437.108933 +1117 1003 -21598853.37172 +1118 1003 25862479.31684 +1119 1003 -1.318752765656e-06 +1120 1003 -19596660.10607 +1121 1003 7638779.123661 +1122 1003 7638888.891396 +1123 1003 -7454967.735663 +1124 1003 5468804.885664 +1004 1004 935442848.8393 +1005 1004 -29761426.14538 +1006 1004 -58081061.81704 +1007 1004 47500235.97878 +1008 1004 3564882.814418 +1009 1004 30555147.55986 +1010 1004 156468480.0912 +1011 1004 29728026.25477 +1012 1004 -16652573.77948 +1013 1004 -14634539.26698 +1110 1004 55896750.56943 +1111 1004 20307057.29599 +1112 1004 -98048385.90041 +1113 1004 -8588615.841047 +1114 1004 23684348.15878 +1115 1004 -153682668.3423 +1116 1004 4613841.489092 +1117 1004 24026705.92618 +1118 1004 10774189.69233 +1119 1004 -47269194.65938 +1120 1004 7638779.123661 +1121 1004 -56670545.31551 +1122 1004 -4608097.279433 +1123 1004 5468804.885664 +1124 1004 1423975.212606 +1005 1005 460369459.7115 +1006 1005 30555555.55053 +1007 1005 -36969735.5824 +1008 1005 -43173523.32456 +1009 1005 -30555555.55054 +1010 1005 -27181695.95754 +1011 1005 -133707927.5673 +1012 1005 -30577597.78773 +1013 1005 30839786.14823 +1014 1005 -4378484.728122 +1015 1005 24466486.67763 +1016 1005 22175044.36675 +1110 1005 -37437760.48235 +1111 1005 9176214.887214 +1112 1005 23123609.08966 +1113 1005 -61598018.00238 +1114 1005 -7648437.108935 +1115 1005 -19592039.58835 +1116 1005 18346673.71113 +1117 1005 7638888.891398 +1118 1005 1385379.035684 +1119 1005 -30645221.93135 +1120 1005 -7638888.891397 +1121 1005 -18931013.9508 +1122 1005 -55802716.54489 +1123 1005 -7645254.369757 +1124 1005 -40856339.07483 +1125 1005 6123446.608564 +1126 1005 6117476.591476 +1127 1005 -3944940.585509 +1006 1006 414508539.3263 +1007 1006 70321276.71584 +1008 1006 -30555555.55054 +1009 1006 -34006299.05085 +1010 1006 -13597018.22442 +1011 1006 -30588618.90633 +1012 1006 9973548.859403 +1013 1006 42647671.20218 +1014 1006 36699730.01644 +1015 1006 -4378484.728126 +1016 1006 -28439541.86765 +1110 1006 6117476.591476 +1111 1006 -37437760.48236 +1112 1006 -12332056.26767 +1113 1006 -7645254.369756 +1114 1006 -88346658.65246 +1115 1006 -53374653.70739 +1116 1006 7638888.891397 +1117 1006 6880428.6391 +1118 1006 26085656.47845 +1119 1006 -7638888.891397 +1120 1006 -28353405.24253 +1121 1006 -13107584.00933 +1122 1006 -7648437.108936 +1123 1006 -19879647.51159 +1124 1006 942630.1669732 +1125 1006 9176214.887214 +1126 1006 6123446.608565 +1127 1006 4734398.284357 +1007 1007 679047623.5514 +1008 1007 -27563640.40249 +1009 1007 -13902573.78038 +1010 1007 -5467872.601825 +1011 1007 27774811.43114 +1012 1007 33778935.02398 +1013 1007 94229239.45832 +1014 1007 33262566.55012 +1015 1007 -18959694.57843 +1016 1007 -11675959.27499 +1110 1007 15415739.3931 +1111 1007 -18498084.4015 +1112 1007 -99834027.95294 +1113 1007 -19583892.11655 +1114 1007 -51538880.44741 +1115 1007 -167219957.723 +1116 1007 -17965238.89317 +1117 1007 10605384.60401 +1118 1007 -88238208.0348 +1119 1007 -18931013.9508 +1120 1007 -13107584.00933 +1121 1007 -54305191.47237 +1122 1007 -41241201.16555 +1123 1007 -1194514.850572 +1124 1007 -36101396.81649 +1125 1007 -5917410.878264 +1126 1007 3156265.522905 +1127 1007 16329190.95617 +1008 1008 703328029.7947 +1009 1008 3.576278686523e-07 +1010 1008 -10185321.18392 +1011 1008 65298758.21399 +1012 1008 -4.023313522339e-07 +1013 1008 -2546330.297233 +1017 1008 -69150427.22048 +1018 1008 7.599592208862e-07 +1019 1008 6620438.369471 +1020 1008 -46611023.324 +1021 1008 30555555.55054 +1022 1008 30109970.69972 +1113 1008 -59010186.71026 +1114 1008 1.542270183563e-06 +1115 1008 49433583.10251 +1116 1008 -10337951.09135 +1117 1008 -7638888.891398 +1118 1008 5244680.501577 +1119 1008 20431686.98312 +1120 1008 -9.238719940186e-07 +1121 1008 -2546332.887312 +1122 1008 21018908.28051 +1123 1008 -2.346932888031e-06 +1124 1008 -636583.222144 +1128 1008 -53208020.04453 +1129 1008 -1.534819602966e-06 +1130 1008 -46887250.21518 +1131 1008 -9746784.424485 +1132 1008 7638888.891396 +1133 1008 -4608097.279433 +1009 1009 629990235.6412 +1010 1009 122220590.1792 +1011 1009 -5.662441253662e-07 +1012 1009 -50812162.49284 +1013 1009 -62332517.31162 +1017 1009 5.662441253662e-07 +1018 1009 65294942.0157 +1019 1009 30555147.55986 +1020 1009 30555555.55054 +1021 1009 -37443799.05029 +1022 1009 -16958129.33543 +1113 1009 1.035630702972e-06 +1114 1009 -25398826.77179 +1115 1009 7638779.123661 +1116 1009 -7638888.891398 +1117 1009 -8046134.402525 +1118 1009 6232693.774803 +1119 1009 -9.536743164063e-07 +1120 1009 2097153.481574 +1121 1009 30555116.47959 +1122 1009 -2.235174179077e-06 +1123 1009 -8008818.28482 +1124 1009 23250219.53173 +1128 1009 -1.318752765656e-06 +1129 1009 -19596660.10607 +1130 1009 7638779.123661 +1131 1009 7638888.891396 +1132 1009 -7454967.735663 +1133 1009 5468804.885664 +1010 1010 998249229.7754 +1011 1010 -2546330.297234 +1012 1010 -59888072.86758 +1013 1010 52583448.20272 +1017 1010 3564882.814418 +1018 1010 30555147.55986 +1019 1010 156468480.0912 +1020 1010 29728026.25477 +1021 1010 -16652573.77948 +1022 1010 -14634539.26698 +1113 1010 49815527.5467 +1114 1010 7638779.12366 +1115 1010 -72142989.75742 +1116 1010 5244680.501577 +1117 1010 6232693.774804 +1118 1010 -152469.232357 +1119 1010 -2546332.887312 +1120 1010 30555116.47959 +1121 1010 -164838704.0269 +1122 1010 -636583.2221438 +1123 1010 23555775.08708 +1124 1010 25663714.57989 +1128 1010 -47269194.65938 +1129 1010 7638779.123661 +1130 1010 -56670545.31551 +1131 1010 -4608097.279433 +1132 1010 5468804.885664 +1133 1010 1423975.212606 +1011 1011 721009953.5089 +1012 1011 30610661.14353 +1013 1011 -34376411.47656 +1014 1011 22252951.07536 +1015 1011 -30577597.78774 +1016 1011 -30132237.29345 +1017 1011 -43173523.32456 +1018 1011 -30555555.55054 +1019 1011 -27181695.95754 +1020 1011 -69150427.22048 +1021 1011 7.599592208862e-07 +1022 1011 6620438.369471 +1023 1011 -46611023.324 +1024 1011 30555555.55054 +1025 1011 30109970.69972 +1113 1011 -32955138.59878 +1114 1011 7638888.891398 +1115 1011 19567597.17295 +1116 1011 -79032837.45136 +1117 1011 -7648437.10893 +1118 1011 55511888.47871 +1119 1011 -66012341.70521 +1120 1011 2.853572368622e-06 +1121 1011 -636583.2221378 +1122 1011 34928101.59242 +1123 1011 7654802.58729 +1124 1011 -8598678.217522 +1125 1011 5149787.278365 +1126 1011 -7645254.369755 +1127 1011 4611926.752539 +1128 1011 -30645221.93135 +1129 1011 -7638888.891397 +1130 1011 -18931013.9508 +1131 1011 -53208020.04453 +1132 1011 -1.534819602966e-06 +1133 1011 -46887250.21518 +1134 1011 -9746784.424485 +1135 1011 7638888.891396 +1136 1011 -4608097.279433 +1012 1012 638480136.047 +1013 1012 94719923.44838 +1014 1012 -30588618.90634 +1015 1012 -84734829.23983 +1016 1012 -51960954.36765 +1017 1012 -30555555.55054 +1018 1012 -34006299.05085 +1019 1012 -13597018.22442 +1020 1012 5.662441253662e-07 +1021 1012 65294942.0157 +1022 1012 30555147.55986 +1023 1012 30555555.55054 +1024 1012 -37443799.05029 +1025 1012 -16958129.33543 +1113 1012 7638888.891398 +1114 1012 -30663321.90996 +1115 1012 -13871472.89847 +1116 1012 -7645254.369751 +1117 1012 -43109768.41806 +1118 1012 18161862.49682 +1119 1012 2.995133399963e-06 +1120 1012 -95040068.27054 +1121 1012 -53805336.01132 +1122 1012 7654802.587289 +1123 1012 14294589.76961 +1124 1012 23676298.37333 +1125 1012 -7648437.108933 +1126 1012 -21598853.37172 +1127 1012 25862479.31684 +1128 1012 -7638888.891397 +1129 1012 -28353405.24253 +1130 1012 -13107584.00933 +1131 1012 -1.318752765656e-06 +1132 1012 -19596660.10607 +1133 1012 7638779.123661 +1134 1012 7638888.891396 +1135 1012 -7454967.735663 +1136 1012 5468804.885664 +1013 1013 935442848.8393 +1014 1013 -29761426.14538 +1015 1013 -58081061.81704 +1016 1013 47500235.97878 +1017 1013 -27563640.40249 +1018 1013 -13902573.78038 +1019 1013 -5467872.601825 +1020 1013 3564882.814418 +1021 1013 30555147.55986 +1022 1013 156468480.0912 +1023 1013 29728026.25477 +1024 1013 -16652573.77948 +1025 1013 -14634539.26698 +1113 1013 19567597.17295 +1114 1013 -13871472.89847 +1115 1013 -60464969.25217 +1116 1013 55896750.56943 +1117 1013 20307057.29599 +1118 1013 -98048385.90041 +1119 1013 -636583.2221379 +1120 1013 -54110891.56668 +1121 1013 -206419618.7154 +1122 1013 -8588615.841047 +1123 1013 23684348.15878 +1124 1013 -153682668.3423 +1125 1013 4613841.489092 +1126 1013 24026705.92618 +1127 1013 10774189.69233 +1128 1013 -18931013.9508 +1129 1013 -13107584.00933 +1130 1013 -54305191.47237 +1131 1013 -47269194.65938 +1132 1013 7638779.123661 +1133 1013 -56670545.31551 +1134 1013 -4608097.279433 +1135 1013 5468804.885664 +1136 1013 1423975.212606 +1014 1014 460369459.7115 +1015 1014 30555555.55053 +1016 1014 -36969735.5824 +1020 1014 -43173523.32456 +1021 1014 -30555555.55054 +1022 1014 -27181695.95754 +1023 1014 -133707927.5673 +1024 1014 -30577597.78773 +1025 1014 30839786.14823 +1026 1014 -4378484.728122 +1027 1014 24466486.67763 +1028 1014 22175044.36675 +1116 1014 -37437760.48235 +1117 1014 9176214.887214 +1118 1014 23123609.08966 +1122 1014 -61598018.00238 +1123 1014 -7648437.108935 +1124 1014 -19592039.58835 +1125 1014 18346673.71113 +1126 1014 7638888.891398 +1127 1014 1385379.035684 +1131 1014 -30645221.93135 +1132 1014 -7638888.891397 +1133 1014 -18931013.9508 +1134 1014 -55802716.54489 +1135 1014 -7645254.369757 +1136 1014 -40856339.07483 +1137 1014 6123446.608564 +1138 1014 6117476.591476 +1139 1014 -3944940.585509 +1015 1015 414508539.3263 +1016 1015 70321276.71584 +1020 1015 -30555555.55054 +1021 1015 -34006299.05085 +1022 1015 -13597018.22442 +1023 1015 -30588618.90633 +1024 1015 9973548.859403 +1025 1015 42647671.20218 +1026 1015 36699730.01644 +1027 1015 -4378484.728126 +1028 1015 -28439541.86765 +1116 1015 6117476.591476 +1117 1015 -37437760.48236 +1118 1015 -12332056.26767 +1122 1015 -7645254.369756 +1123 1015 -88346658.65246 +1124 1015 -53374653.70739 +1125 1015 7638888.891397 +1126 1015 6880428.6391 +1127 1015 26085656.47845 +1131 1015 -7638888.891397 +1132 1015 -28353405.24253 +1133 1015 -13107584.00933 +1134 1015 -7648437.108936 +1135 1015 -19879647.51159 +1136 1015 942630.1669732 +1137 1015 9176214.887214 +1138 1015 6123446.608565 +1139 1015 4734398.284357 +1016 1016 679047623.5514 +1020 1016 -27563640.40249 +1021 1016 -13902573.78038 +1022 1016 -5467872.601825 +1023 1016 27774811.43114 +1024 1016 33778935.02398 +1025 1016 94229239.45832 +1026 1016 33262566.55012 +1027 1016 -18959694.57843 +1028 1016 -11675959.27499 +1116 1016 15415739.3931 +1117 1016 -18498084.4015 +1118 1016 -99834027.95294 +1122 1016 -19583892.11655 +1123 1016 -51538880.44741 +1124 1016 -167219957.723 +1125 1016 -17965238.89317 +1126 1016 10605384.60401 +1127 1016 -88238208.0348 +1131 1016 -18931013.9508 +1132 1016 -13107584.00933 +1133 1016 -54305191.47237 +1134 1016 -41241201.16555 +1135 1016 -1194514.850572 +1136 1016 -36101396.81649 +1137 1016 -5917410.878264 +1138 1016 3156265.522905 +1139 1016 16329190.95617 +1017 1017 703328029.7947 +1018 1017 3.576278686523e-07 +1019 1017 -10185321.18392 +1020 1017 65298758.21399 +1021 1017 -4.023313522339e-07 +1022 1017 -2546330.297233 +1029 1017 -69150427.22048 +1030 1017 7.599592208862e-07 +1031 1017 6620438.369471 +1032 1017 -46611023.324 +1033 1017 30555555.55054 +1034 1017 30109970.69972 +1119 1017 -59010186.71026 +1120 1017 1.542270183563e-06 +1121 1017 49433583.10251 +1122 1017 -10337951.09135 +1123 1017 -7638888.891398 +1124 1017 5244680.501577 +1128 1017 20431686.98312 +1129 1017 -9.238719940186e-07 +1130 1017 -2546332.887312 +1131 1017 21018908.28051 +1132 1017 -2.346932888031e-06 +1133 1017 -636583.222144 +1140 1017 -53208020.04453 +1141 1017 -1.534819602966e-06 +1142 1017 -46887250.21518 +1143 1017 -9746784.424485 +1144 1017 7638888.891396 +1145 1017 -4608097.279433 +1018 1018 629990235.6412 +1019 1018 122220590.1792 +1020 1018 -5.662441253662e-07 +1021 1018 -50812162.49284 +1022 1018 -62332517.31162 +1029 1018 5.662441253662e-07 +1030 1018 65294942.0157 +1031 1018 30555147.55986 +1032 1018 30555555.55054 +1033 1018 -37443799.05029 +1034 1018 -16958129.33543 +1119 1018 1.035630702972e-06 +1120 1018 -25398826.77179 +1121 1018 7638779.123661 +1122 1018 -7638888.891398 +1123 1018 -8046134.402525 +1124 1018 6232693.774803 +1128 1018 -9.536743164063e-07 +1129 1018 2097153.481574 +1130 1018 30555116.47959 +1131 1018 -2.235174179077e-06 +1132 1018 -8008818.28482 +1133 1018 23250219.53173 +1140 1018 -1.318752765656e-06 +1141 1018 -19596660.10607 +1142 1018 7638779.123661 +1143 1018 7638888.891396 +1144 1018 -7454967.735663 +1145 1018 5468804.885664 +1019 1019 998249229.7754 +1020 1019 -2546330.297234 +1021 1019 -59888072.86758 +1022 1019 52583448.20272 +1029 1019 3564882.814418 +1030 1019 30555147.55986 +1031 1019 156468480.0912 +1032 1019 29728026.25477 +1033 1019 -16652573.77948 +1034 1019 -14634539.26698 +1119 1019 49815527.5467 +1120 1019 7638779.12366 +1121 1019 -72142989.75742 +1122 1019 5244680.501577 +1123 1019 6232693.774804 +1124 1019 -152469.232357 +1128 1019 -2546332.887312 +1129 1019 30555116.47959 +1130 1019 -164838704.0269 +1131 1019 -636583.2221438 +1132 1019 23555775.08708 +1133 1019 25663714.57989 +1140 1019 -47269194.65938 +1141 1019 7638779.123661 +1142 1019 -56670545.31551 +1143 1019 -4608097.279433 +1144 1019 5468804.885664 +1145 1019 1423975.212606 +1020 1020 703328029.7947 +1021 1020 3.576278686523e-07 +1022 1020 -10185321.18392 +1023 1020 65298758.21399 +1024 1020 -4.023313522339e-07 +1025 1020 -2546330.297233 +1029 1020 -43173523.32456 +1030 1020 -30555555.55054 +1031 1020 -27181695.95754 +1032 1020 -69150427.22048 +1033 1020 7.599592208862e-07 +1034 1020 6620438.369471 +1035 1020 -46611023.324 +1036 1020 30555555.55054 +1037 1020 30109970.69972 +1119 1020 -32955138.59878 +1120 1020 7638888.891398 +1121 1020 19567597.17295 +1122 1020 -59010186.71026 +1123 1020 1.542270183563e-06 +1124 1020 49433583.10251 +1125 1020 -10337951.09135 +1126 1020 -7638888.891398 +1127 1020 5244680.501577 +1128 1020 -66012341.70521 +1129 1020 2.853572368622e-06 +1130 1020 -636583.2221378 +1131 1020 20431686.98312 +1132 1020 -9.238719940186e-07 +1133 1020 -2546332.887312 +1134 1020 21018908.28051 +1135 1020 -2.346932888031e-06 +1136 1020 -636583.222144 +1140 1020 -30645221.93135 +1141 1020 -7638888.891397 +1142 1020 -18931013.9508 +1143 1020 -53208020.04453 +1144 1020 -1.534819602966e-06 +1145 1020 -46887250.21518 +1146 1020 -9746784.424485 +1147 1020 7638888.891396 +1148 1020 -4608097.279433 +1021 1021 629990235.6412 +1022 1021 122220590.1792 +1023 1021 -5.662441253662e-07 +1024 1021 -50812162.49284 +1025 1021 -62332517.31162 +1029 1021 -30555555.55054 +1030 1021 -34006299.05085 +1031 1021 -13597018.22442 +1032 1021 5.662441253662e-07 +1033 1021 65294942.0157 +1034 1021 30555147.55986 +1035 1021 30555555.55054 +1036 1021 -37443799.05029 +1037 1021 -16958129.33543 +1119 1021 7638888.891398 +1120 1021 -30663321.90996 +1121 1021 -13871472.89847 +1122 1021 1.035630702972e-06 +1123 1021 -25398826.77179 +1124 1021 7638779.123661 +1125 1021 -7638888.891398 +1126 1021 -8046134.402525 +1127 1021 6232693.774803 +1128 1021 2.995133399963e-06 +1129 1021 -95040068.27054 +1130 1021 -53805336.01132 +1131 1021 -9.536743164063e-07 +1132 1021 2097153.481574 +1133 1021 30555116.47959 +1134 1021 -2.235174179077e-06 +1135 1021 -8008818.28482 +1136 1021 23250219.53173 +1140 1021 -7638888.891397 +1141 1021 -28353405.24253 +1142 1021 -13107584.00933 +1143 1021 -1.318752765656e-06 +1144 1021 -19596660.10607 +1145 1021 7638779.123661 +1146 1021 7638888.891396 +1147 1021 -7454967.735663 +1148 1021 5468804.885664 +1022 1022 998249229.7754 +1023 1022 -2546330.297234 +1024 1022 -59888072.86758 +1025 1022 52583448.20272 +1029 1022 -27563640.40249 +1030 1022 -13902573.78038 +1031 1022 -5467872.601825 +1032 1022 3564882.814418 +1033 1022 30555147.55986 +1034 1022 156468480.0912 +1035 1022 29728026.25477 +1036 1022 -16652573.77948 +1037 1022 -14634539.26698 +1119 1022 19567597.17295 +1120 1022 -13871472.89847 +1121 1022 -60464969.25217 +1122 1022 49815527.5467 +1123 1022 7638779.12366 +1124 1022 -72142989.75742 +1125 1022 5244680.501577 +1126 1022 6232693.774804 +1127 1022 -152469.232357 +1128 1022 -636583.2221379 +1129 1022 -54110891.56668 +1130 1022 -206419618.7154 +1131 1022 -2546332.887312 +1132 1022 30555116.47959 +1133 1022 -164838704.0269 +1134 1022 -636583.2221438 +1135 1022 23555775.08708 +1136 1022 25663714.57989 +1140 1022 -18931013.9508 +1141 1022 -13107584.00933 +1142 1022 -54305191.47237 +1143 1022 -47269194.65938 +1144 1022 7638779.123661 +1145 1022 -56670545.31551 +1146 1022 -4608097.279433 +1147 1022 5468804.885664 +1148 1022 1423975.212606 +1023 1023 721009953.5089 +1024 1023 30610661.14353 +1025 1023 -34376411.47656 +1026 1023 22252951.07536 +1027 1023 -30577597.78774 +1028 1023 -30132237.29345 +1032 1023 -43173523.32456 +1033 1023 -30555555.55054 +1034 1023 -27181695.95754 +1035 1023 -69150427.22048 +1036 1023 7.599592208862e-07 +1037 1023 6620438.369471 +1038 1023 -46611023.324 +1039 1023 30555555.55054 +1040 1023 30109970.69972 +1122 1023 -32955138.59878 +1123 1023 7638888.891398 +1124 1023 19567597.17295 +1125 1023 -79032837.45136 +1126 1023 -7648437.10893 +1127 1023 55511888.47871 +1131 1023 -66012341.70521 +1132 1023 2.853572368622e-06 +1133 1023 -636583.2221378 +1134 1023 34928101.59242 +1135 1023 7654802.58729 +1136 1023 -8598678.217522 +1137 1023 5149787.278365 +1138 1023 -7645254.369755 +1139 1023 4611926.752539 +1143 1023 -30645221.93135 +1144 1023 -7638888.891397 +1145 1023 -18931013.9508 +1146 1023 -53208020.04453 +1147 1023 -1.534819602966e-06 +1148 1023 -46887250.21518 +1149 1023 -9746784.424485 +1150 1023 7638888.891396 +1151 1023 -4608097.279433 +1024 1024 638480136.047 +1025 1024 94719923.44838 +1026 1024 -30588618.90634 +1027 1024 -84734829.23983 +1028 1024 -51960954.36765 +1032 1024 -30555555.55054 +1033 1024 -34006299.05085 +1034 1024 -13597018.22442 +1035 1024 5.662441253662e-07 +1036 1024 65294942.0157 +1037 1024 30555147.55986 +1038 1024 30555555.55054 +1039 1024 -37443799.05029 +1040 1024 -16958129.33543 +1122 1024 7638888.891398 +1123 1024 -30663321.90996 +1124 1024 -13871472.89847 +1125 1024 -7645254.369751 +1126 1024 -43109768.41806 +1127 1024 18161862.49682 +1131 1024 2.995133399963e-06 +1132 1024 -95040068.27054 +1133 1024 -53805336.01132 +1134 1024 7654802.587289 +1135 1024 14294589.76961 +1136 1024 23676298.37333 +1137 1024 -7648437.108933 +1138 1024 -21598853.37172 +1139 1024 25862479.31684 +1143 1024 -7638888.891397 +1144 1024 -28353405.24253 +1145 1024 -13107584.00933 +1146 1024 -1.318752765656e-06 +1147 1024 -19596660.10607 +1148 1024 7638779.123661 +1149 1024 7638888.891396 +1150 1024 -7454967.735663 +1151 1024 5468804.885664 +1025 1025 935442848.8393 +1026 1025 -29761426.14538 +1027 1025 -58081061.81704 +1028 1025 47500235.97878 +1032 1025 -27563640.40249 +1033 1025 -13902573.78038 +1034 1025 -5467872.601825 +1035 1025 3564882.814418 +1036 1025 30555147.55986 +1037 1025 156468480.0912 +1038 1025 29728026.25477 +1039 1025 -16652573.77948 +1040 1025 -14634539.26698 +1122 1025 19567597.17295 +1123 1025 -13871472.89847 +1124 1025 -60464969.25217 +1125 1025 55896750.56943 +1126 1025 20307057.29599 +1127 1025 -98048385.90041 +1131 1025 -636583.2221379 +1132 1025 -54110891.56668 +1133 1025 -206419618.7154 +1134 1025 -8588615.841047 +1135 1025 23684348.15878 +1136 1025 -153682668.3423 +1137 1025 4613841.489092 +1138 1025 24026705.92618 +1139 1025 10774189.69233 +1143 1025 -18931013.9508 +1144 1025 -13107584.00933 +1145 1025 -54305191.47237 +1146 1025 -47269194.65938 +1147 1025 7638779.123661 +1148 1025 -56670545.31551 +1149 1025 -4608097.279433 +1150 1025 5468804.885664 +1151 1025 1423975.212606 +1026 1026 460369459.7115 +1027 1026 30555555.55053 +1028 1026 -36969735.5824 +1035 1026 -43173523.32456 +1036 1026 -30555555.55054 +1037 1026 -27181695.95754 +1038 1026 -133707927.5673 +1039 1026 -30577597.78773 +1040 1026 30839786.14823 +1041 1026 -4378484.728122 +1042 1026 24466486.67763 +1043 1026 22175044.36675 +1125 1026 -37437760.48235 +1126 1026 9176214.887214 +1127 1026 23123609.08966 +1134 1026 -61598018.00238 +1135 1026 -7648437.108935 +1136 1026 -19592039.58835 +1137 1026 18346673.71113 +1138 1026 7638888.891398 +1139 1026 1385379.035684 +1146 1026 -30645221.93135 +1147 1026 -7638888.891397 +1148 1026 -18931013.9508 +1149 1026 -55802716.54489 +1150 1026 -7645254.369757 +1151 1026 -40856339.07483 +1152 1026 6123446.608564 +1153 1026 6117476.591476 +1154 1026 -3944940.585509 +1027 1027 414508539.3263 +1028 1027 70321276.71584 +1035 1027 -30555555.55054 +1036 1027 -34006299.05085 +1037 1027 -13597018.22442 +1038 1027 -30588618.90633 +1039 1027 9973548.859403 +1040 1027 42647671.20218 +1041 1027 36699730.01644 +1042 1027 -4378484.728126 +1043 1027 -28439541.86765 +1125 1027 6117476.591476 +1126 1027 -37437760.48236 +1127 1027 -12332056.26767 +1134 1027 -7645254.369756 +1135 1027 -88346658.65246 +1136 1027 -53374653.70739 +1137 1027 7638888.891397 +1138 1027 6880428.6391 +1139 1027 26085656.47845 +1146 1027 -7638888.891397 +1147 1027 -28353405.24253 +1148 1027 -13107584.00933 +1149 1027 -7648437.108936 +1150 1027 -19879647.51159 +1151 1027 942630.1669732 +1152 1027 9176214.887214 +1153 1027 6123446.608565 +1154 1027 4734398.284357 +1028 1028 679047623.5514 +1035 1028 -27563640.40249 +1036 1028 -13902573.78038 +1037 1028 -5467872.601825 +1038 1028 27774811.43114 +1039 1028 33778935.02398 +1040 1028 94229239.45832 +1041 1028 33262566.55012 +1042 1028 -18959694.57843 +1043 1028 -11675959.27499 +1125 1028 15415739.3931 +1126 1028 -18498084.4015 +1127 1028 -99834027.95294 +1134 1028 -19583892.11655 +1135 1028 -51538880.44741 +1136 1028 -167219957.723 +1137 1028 -17965238.89317 +1138 1028 10605384.60401 +1139 1028 -88238208.0348 +1146 1028 -18931013.9508 +1147 1028 -13107584.00933 +1148 1028 -54305191.47237 +1149 1028 -41241201.16555 +1150 1028 -1194514.850572 +1151 1028 -36101396.81649 +1152 1028 -5917410.878264 +1153 1028 3156265.522905 +1154 1028 16329190.95617 +1029 1029 703328029.7947 +1030 1029 3.576278686523e-07 +1031 1029 -10185321.18392 +1032 1029 65298758.21399 +1033 1029 -4.023313522339e-07 +1034 1029 -2546330.297233 +1044 1029 -69150427.22048 +1045 1029 7.599592208862e-07 +1046 1029 6620438.369471 +1047 1029 -46611023.324 +1048 1029 30555555.55054 +1049 1029 30109970.69972 +1128 1029 -59010186.71026 +1129 1029 1.542270183563e-06 +1130 1029 49433583.10251 +1131 1029 -10337951.09135 +1132 1029 -7638888.891398 +1133 1029 5244680.501577 +1140 1029 20431686.98312 +1141 1029 -9.238719940186e-07 +1142 1029 -2546332.887312 +1143 1029 21018908.28051 +1144 1029 -2.346932888031e-06 +1145 1029 -636583.222144 +1155 1029 -53208020.04453 +1156 1029 -1.534819602966e-06 +1157 1029 -46887250.21518 +1158 1029 -9746784.424485 +1159 1029 7638888.891396 +1160 1029 -4608097.279433 +1030 1030 629990235.6412 +1031 1030 122220590.1792 +1032 1030 -5.662441253662e-07 +1033 1030 -50812162.49284 +1034 1030 -62332517.31162 +1044 1030 5.662441253662e-07 +1045 1030 65294942.0157 +1046 1030 30555147.55986 +1047 1030 30555555.55054 +1048 1030 -37443799.05029 +1049 1030 -16958129.33543 +1128 1030 1.035630702972e-06 +1129 1030 -25398826.77179 +1130 1030 7638779.123661 +1131 1030 -7638888.891398 +1132 1030 -8046134.402525 +1133 1030 6232693.774803 +1140 1030 -9.536743164063e-07 +1141 1030 2097153.481574 +1142 1030 30555116.47959 +1143 1030 -2.235174179077e-06 +1144 1030 -8008818.28482 +1145 1030 23250219.53173 +1155 1030 -1.318752765656e-06 +1156 1030 -19596660.10607 +1157 1030 7638779.123661 +1158 1030 7638888.891396 +1159 1030 -7454967.735663 +1160 1030 5468804.885664 +1031 1031 998249229.7754 +1032 1031 -2546330.297234 +1033 1031 -59888072.86758 +1034 1031 52583448.20272 +1044 1031 3564882.814418 +1045 1031 30555147.55986 +1046 1031 156468480.0912 +1047 1031 29728026.25477 +1048 1031 -16652573.77948 +1049 1031 -14634539.26698 +1128 1031 49815527.5467 +1129 1031 7638779.12366 +1130 1031 -72142989.75742 +1131 1031 5244680.501577 +1132 1031 6232693.774804 +1133 1031 -152469.232357 +1140 1031 -2546332.887312 +1141 1031 30555116.47959 +1142 1031 -164838704.0269 +1143 1031 -636583.2221438 +1144 1031 23555775.08708 +1145 1031 25663714.57989 +1155 1031 -47269194.65938 +1156 1031 7638779.123661 +1157 1031 -56670545.31551 +1158 1031 -4608097.279433 +1159 1031 5468804.885664 +1160 1031 1423975.212606 +1032 1032 703328029.7947 +1033 1032 3.576278686523e-07 +1034 1032 -10185321.18392 +1035 1032 65298758.21399 +1036 1032 -4.023313522339e-07 +1037 1032 -2546330.297233 +1044 1032 -43173523.32456 +1045 1032 -30555555.55054 +1046 1032 -27181695.95754 +1047 1032 -69150427.22048 +1048 1032 7.599592208862e-07 +1049 1032 6620438.369471 +1050 1032 -46611023.324 +1051 1032 30555555.55054 +1052 1032 30109970.69972 +1128 1032 -32955138.59878 +1129 1032 7638888.891398 +1130 1032 19567597.17295 +1131 1032 -59010186.71026 +1132 1032 1.542270183563e-06 +1133 1032 49433583.10251 +1134 1032 -10337951.09135 +1135 1032 -7638888.891398 +1136 1032 5244680.501577 +1140 1032 -66012341.70521 +1141 1032 2.853572368622e-06 +1142 1032 -636583.2221378 +1143 1032 20431686.98312 +1144 1032 -9.238719940186e-07 +1145 1032 -2546332.887312 +1146 1032 21018908.28051 +1147 1032 -2.346932888031e-06 +1148 1032 -636583.222144 +1155 1032 -30645221.93135 +1156 1032 -7638888.891397 +1157 1032 -18931013.9508 +1158 1032 -53208020.04453 +1159 1032 -1.534819602966e-06 +1160 1032 -46887250.21518 +1161 1032 -9746784.424485 +1162 1032 7638888.891396 +1163 1032 -4608097.279433 +1033 1033 629990235.6412 +1034 1033 122220590.1792 +1035 1033 -5.662441253662e-07 +1036 1033 -50812162.49284 +1037 1033 -62332517.31162 +1044 1033 -30555555.55054 +1045 1033 -34006299.05085 +1046 1033 -13597018.22442 +1047 1033 5.662441253662e-07 +1048 1033 65294942.0157 +1049 1033 30555147.55986 +1050 1033 30555555.55054 +1051 1033 -37443799.05029 +1052 1033 -16958129.33543 +1128 1033 7638888.891398 +1129 1033 -30663321.90996 +1130 1033 -13871472.89847 +1131 1033 1.035630702972e-06 +1132 1033 -25398826.77179 +1133 1033 7638779.123661 +1134 1033 -7638888.891398 +1135 1033 -8046134.402525 +1136 1033 6232693.774803 +1140 1033 2.995133399963e-06 +1141 1033 -95040068.27054 +1142 1033 -53805336.01132 +1143 1033 -9.536743164063e-07 +1144 1033 2097153.481574 +1145 1033 30555116.47959 +1146 1033 -2.235174179077e-06 +1147 1033 -8008818.28482 +1148 1033 23250219.53173 +1155 1033 -7638888.891397 +1156 1033 -28353405.24253 +1157 1033 -13107584.00933 +1158 1033 -1.318752765656e-06 +1159 1033 -19596660.10607 +1160 1033 7638779.123661 +1161 1033 7638888.891396 +1162 1033 -7454967.735663 +1163 1033 5468804.885664 +1034 1034 998249229.7754 +1035 1034 -2546330.297234 +1036 1034 -59888072.86758 +1037 1034 52583448.20272 +1044 1034 -27563640.40249 +1045 1034 -13902573.78038 +1046 1034 -5467872.601825 +1047 1034 3564882.814418 +1048 1034 30555147.55986 +1049 1034 156468480.0912 +1050 1034 29728026.25477 +1051 1034 -16652573.77948 +1052 1034 -14634539.26698 +1128 1034 19567597.17295 +1129 1034 -13871472.89847 +1130 1034 -60464969.25217 +1131 1034 49815527.5467 +1132 1034 7638779.12366 +1133 1034 -72142989.75742 +1134 1034 5244680.501577 +1135 1034 6232693.774804 +1136 1034 -152469.232357 +1140 1034 -636583.2221379 +1141 1034 -54110891.56668 +1142 1034 -206419618.7154 +1143 1034 -2546332.887312 +1144 1034 30555116.47959 +1145 1034 -164838704.0269 +1146 1034 -636583.2221438 +1147 1034 23555775.08708 +1148 1034 25663714.57989 +1155 1034 -18931013.9508 +1156 1034 -13107584.00933 +1157 1034 -54305191.47237 +1158 1034 -47269194.65938 +1159 1034 7638779.123661 +1160 1034 -56670545.31551 +1161 1034 -4608097.279433 +1162 1034 5468804.885664 +1163 1034 1423975.212606 +1035 1035 703328029.7947 +1036 1035 3.576278686523e-07 +1037 1035 -10185321.18392 +1038 1035 65298758.21399 +1039 1035 -4.023313522339e-07 +1040 1035 -2546330.297233 +1047 1035 -43173523.32456 +1048 1035 -30555555.55054 +1049 1035 -27181695.95754 +1050 1035 -69150427.22048 +1051 1035 7.599592208862e-07 +1052 1035 6620438.369471 +1053 1035 -46611023.324 +1054 1035 30555555.55054 +1055 1035 30109970.69972 +1131 1035 -32955138.59878 +1132 1035 7638888.891398 +1133 1035 19567597.17295 +1134 1035 -59010186.71026 +1135 1035 1.542270183563e-06 +1136 1035 49433583.10251 +1137 1035 -10337951.09135 +1138 1035 -7638888.891398 +1139 1035 5244680.501577 +1143 1035 -66012341.70521 +1144 1035 2.853572368622e-06 +1145 1035 -636583.2221378 +1146 1035 20431686.98312 +1147 1035 -9.238719940186e-07 +1148 1035 -2546332.887312 +1149 1035 21018908.28051 +1150 1035 -2.346932888031e-06 +1151 1035 -636583.222144 +1158 1035 -30645221.93135 +1159 1035 -7638888.891397 +1160 1035 -18931013.9508 +1161 1035 -53208020.04453 +1162 1035 -1.534819602966e-06 +1163 1035 -46887250.21518 +1164 1035 -9746784.424485 +1165 1035 7638888.891396 +1166 1035 -4608097.279433 +1036 1036 629990235.6412 +1037 1036 122220590.1792 +1038 1036 -5.662441253662e-07 +1039 1036 -50812162.49284 +1040 1036 -62332517.31162 +1047 1036 -30555555.55054 +1048 1036 -34006299.05085 +1049 1036 -13597018.22442 +1050 1036 5.662441253662e-07 +1051 1036 65294942.0157 +1052 1036 30555147.55986 +1053 1036 30555555.55054 +1054 1036 -37443799.05029 +1055 1036 -16958129.33543 +1131 1036 7638888.891398 +1132 1036 -30663321.90996 +1133 1036 -13871472.89847 +1134 1036 1.035630702972e-06 +1135 1036 -25398826.77179 +1136 1036 7638779.123661 +1137 1036 -7638888.891398 +1138 1036 -8046134.402525 +1139 1036 6232693.774803 +1143 1036 2.995133399963e-06 +1144 1036 -95040068.27054 +1145 1036 -53805336.01132 +1146 1036 -9.536743164063e-07 +1147 1036 2097153.481574 +1148 1036 30555116.47959 +1149 1036 -2.235174179077e-06 +1150 1036 -8008818.28482 +1151 1036 23250219.53173 +1158 1036 -7638888.891397 +1159 1036 -28353405.24253 +1160 1036 -13107584.00933 +1161 1036 -1.318752765656e-06 +1162 1036 -19596660.10607 +1163 1036 7638779.123661 +1164 1036 7638888.891396 +1165 1036 -7454967.735663 +1166 1036 5468804.885664 +1037 1037 998249229.7754 +1038 1037 -2546330.297234 +1039 1037 -59888072.86758 +1040 1037 52583448.20272 +1047 1037 -27563640.40249 +1048 1037 -13902573.78038 +1049 1037 -5467872.601825 +1050 1037 3564882.814418 +1051 1037 30555147.55986 +1052 1037 156468480.0912 +1053 1037 29728026.25477 +1054 1037 -16652573.77948 +1055 1037 -14634539.26698 +1131 1037 19567597.17295 +1132 1037 -13871472.89847 +1133 1037 -60464969.25217 +1134 1037 49815527.5467 +1135 1037 7638779.12366 +1136 1037 -72142989.75742 +1137 1037 5244680.501577 +1138 1037 6232693.774804 +1139 1037 -152469.232357 +1143 1037 -636583.2221379 +1144 1037 -54110891.56668 +1145 1037 -206419618.7154 +1146 1037 -2546332.887312 +1147 1037 30555116.47959 +1148 1037 -164838704.0269 +1149 1037 -636583.2221438 +1150 1037 23555775.08708 +1151 1037 25663714.57989 +1158 1037 -18931013.9508 +1159 1037 -13107584.00933 +1160 1037 -54305191.47237 +1161 1037 -47269194.65938 +1162 1037 7638779.123661 +1163 1037 -56670545.31551 +1164 1037 -4608097.279433 +1165 1037 5468804.885664 +1166 1037 1423975.212606 +1038 1038 721009953.5089 +1039 1038 30610661.14353 +1040 1038 -34376411.47656 +1041 1038 22252951.07536 +1042 1038 -30577597.78774 +1043 1038 -30132237.29345 +1050 1038 -43173523.32456 +1051 1038 -30555555.55054 +1052 1038 -27181695.95754 +1053 1038 -69150427.22048 +1054 1038 7.599592208862e-07 +1055 1038 6620438.369471 +1056 1038 -46611023.324 +1057 1038 30555555.55054 +1058 1038 30109970.69972 +1134 1038 -32955138.59878 +1135 1038 7638888.891398 +1136 1038 19567597.17295 +1137 1038 -79032837.45136 +1138 1038 -7648437.10893 +1139 1038 55511888.47871 +1146 1038 -66012341.70521 +1147 1038 2.853572368622e-06 +1148 1038 -636583.2221378 +1149 1038 34928101.59242 +1150 1038 7654802.58729 +1151 1038 -8598678.217522 +1152 1038 5149787.278365 +1153 1038 -7645254.369755 +1154 1038 4611926.752539 +1161 1038 -30645221.93135 +1162 1038 -7638888.891397 +1163 1038 -18931013.9508 +1164 1038 -53208020.04453 +1165 1038 -1.534819602966e-06 +1166 1038 -46887250.21518 +1167 1038 -9746784.424485 +1168 1038 7638888.891396 +1169 1038 -4608097.279433 +1039 1039 638480136.047 +1040 1039 94719923.44838 +1041 1039 -30588618.90634 +1042 1039 -84734829.23983 +1043 1039 -51960954.36765 +1050 1039 -30555555.55054 +1051 1039 -34006299.05085 +1052 1039 -13597018.22442 +1053 1039 5.662441253662e-07 +1054 1039 65294942.0157 +1055 1039 30555147.55986 +1056 1039 30555555.55054 +1057 1039 -37443799.05029 +1058 1039 -16958129.33543 +1134 1039 7638888.891398 +1135 1039 -30663321.90996 +1136 1039 -13871472.89847 +1137 1039 -7645254.369751 +1138 1039 -43109768.41806 +1139 1039 18161862.49682 +1146 1039 2.995133399963e-06 +1147 1039 -95040068.27054 +1148 1039 -53805336.01132 +1149 1039 7654802.587289 +1150 1039 14294589.76961 +1151 1039 23676298.37333 +1152 1039 -7648437.108933 +1153 1039 -21598853.37172 +1154 1039 25862479.31684 +1161 1039 -7638888.891397 +1162 1039 -28353405.24253 +1163 1039 -13107584.00933 +1164 1039 -1.318752765656e-06 +1165 1039 -19596660.10607 +1166 1039 7638779.123661 +1167 1039 7638888.891396 +1168 1039 -7454967.735663 +1169 1039 5468804.885664 +1040 1040 935442848.8393 +1041 1040 -29761426.14538 +1042 1040 -58081061.81704 +1043 1040 47500235.97878 +1050 1040 -27563640.40249 +1051 1040 -13902573.78038 +1052 1040 -5467872.601825 +1053 1040 3564882.814418 +1054 1040 30555147.55986 +1055 1040 156468480.0912 +1056 1040 29728026.25477 +1057 1040 -16652573.77948 +1058 1040 -14634539.26698 +1134 1040 19567597.17295 +1135 1040 -13871472.89847 +1136 1040 -60464969.25217 +1137 1040 55896750.56943 +1138 1040 20307057.29599 +1139 1040 -98048385.90041 +1146 1040 -636583.2221379 +1147 1040 -54110891.56668 +1148 1040 -206419618.7154 +1149 1040 -8588615.841047 +1150 1040 23684348.15878 +1151 1040 -153682668.3423 +1152 1040 4613841.489092 +1153 1040 24026705.92618 +1154 1040 10774189.69233 +1161 1040 -18931013.9508 +1162 1040 -13107584.00933 +1163 1040 -54305191.47237 +1164 1040 -47269194.65938 +1165 1040 7638779.123661 +1166 1040 -56670545.31551 +1167 1040 -4608097.279433 +1168 1040 5468804.885664 +1169 1040 1423975.212606 +1041 1041 460369459.7115 +1042 1041 30555555.55053 +1043 1041 -36969735.5824 +1053 1041 -43173523.32456 +1054 1041 -30555555.55054 +1055 1041 -27181695.95754 +1056 1041 -133707927.5673 +1057 1041 -30577597.78773 +1058 1041 30839786.14823 +1059 1041 -4378484.728122 +1060 1041 24466486.67763 +1061 1041 22175044.36675 +1137 1041 -37437760.48235 +1138 1041 9176214.887214 +1139 1041 23123609.08966 +1149 1041 -61598018.00238 +1150 1041 -7648437.108935 +1151 1041 -19592039.58835 +1152 1041 18346673.71113 +1153 1041 7638888.891398 +1154 1041 1385379.035684 +1164 1041 -30645221.93135 +1165 1041 -7638888.891397 +1166 1041 -18931013.9508 +1167 1041 -55802716.54489 +1168 1041 -7645254.369757 +1169 1041 -40856339.07483 +1170 1041 6123446.608564 +1171 1041 6117476.591476 +1172 1041 -3944940.585509 +1042 1042 414508539.3263 +1043 1042 70321276.71584 +1053 1042 -30555555.55054 +1054 1042 -34006299.05085 +1055 1042 -13597018.22442 +1056 1042 -30588618.90633 +1057 1042 9973548.859403 +1058 1042 42647671.20218 +1059 1042 36699730.01644 +1060 1042 -4378484.728126 +1061 1042 -28439541.86765 +1137 1042 6117476.591476 +1138 1042 -37437760.48236 +1139 1042 -12332056.26767 +1149 1042 -7645254.369756 +1150 1042 -88346658.65246 +1151 1042 -53374653.70739 +1152 1042 7638888.891397 +1153 1042 6880428.6391 +1154 1042 26085656.47845 +1164 1042 -7638888.891397 +1165 1042 -28353405.24253 +1166 1042 -13107584.00933 +1167 1042 -7648437.108936 +1168 1042 -19879647.51159 +1169 1042 942630.1669732 +1170 1042 9176214.887214 +1171 1042 6123446.608565 +1172 1042 4734398.284357 +1043 1043 679047623.5514 +1053 1043 -27563640.40249 +1054 1043 -13902573.78038 +1055 1043 -5467872.601825 +1056 1043 27774811.43114 +1057 1043 33778935.02398 +1058 1043 94229239.45832 +1059 1043 33262566.55012 +1060 1043 -18959694.57843 +1061 1043 -11675959.27499 +1137 1043 15415739.3931 +1138 1043 -18498084.4015 +1139 1043 -99834027.95294 +1149 1043 -19583892.11655 +1150 1043 -51538880.44741 +1151 1043 -167219957.723 +1152 1043 -17965238.89317 +1153 1043 10605384.60401 +1154 1043 -88238208.0348 +1164 1043 -18931013.9508 +1165 1043 -13107584.00933 +1166 1043 -54305191.47237 +1167 1043 -41241201.16555 +1168 1043 -1194514.850572 +1169 1043 -36101396.81649 +1170 1043 -5917410.878264 +1171 1043 3156265.522905 +1172 1043 16329190.95617 +1044 1044 703328029.7947 +1045 1044 3.576278686523e-07 +1046 1044 -10185321.18392 +1047 1044 65298758.21399 +1048 1044 -4.023313522339e-07 +1049 1044 -2546330.297233 +1062 1044 -69150427.22048 +1063 1044 7.599592208862e-07 +1064 1044 6620438.369471 +1065 1044 -46611023.324 +1066 1044 30555555.55054 +1067 1044 30109970.69972 +1140 1044 -59010186.71026 +1141 1044 1.542270183563e-06 +1142 1044 49433583.10251 +1143 1044 -10337951.09135 +1144 1044 -7638888.891398 +1145 1044 5244680.501577 +1155 1044 20431686.98312 +1156 1044 -9.238719940186e-07 +1157 1044 -2546332.887312 +1158 1044 21018908.28051 +1159 1044 -2.346932888031e-06 +1160 1044 -636583.222144 +1173 1044 -53208020.04453 +1174 1044 -1.534819602966e-06 +1175 1044 -46887250.21518 +1176 1044 -9746784.424485 +1177 1044 7638888.891396 +1178 1044 -4608097.279433 +1045 1045 629990235.6412 +1046 1045 122220590.1792 +1047 1045 -5.662441253662e-07 +1048 1045 -50812162.49284 +1049 1045 -62332517.31162 +1062 1045 5.662441253662e-07 +1063 1045 65294942.0157 +1064 1045 30555147.55986 +1065 1045 30555555.55054 +1066 1045 -37443799.05029 +1067 1045 -16958129.33543 +1140 1045 1.035630702972e-06 +1141 1045 -25398826.77179 +1142 1045 7638779.123661 +1143 1045 -7638888.891398 +1144 1045 -8046134.402525 +1145 1045 6232693.774803 +1155 1045 -9.536743164063e-07 +1156 1045 2097153.481574 +1157 1045 30555116.47959 +1158 1045 -2.235174179077e-06 +1159 1045 -8008818.28482 +1160 1045 23250219.53173 +1173 1045 -1.318752765656e-06 +1174 1045 -19596660.10607 +1175 1045 7638779.123661 +1176 1045 7638888.891396 +1177 1045 -7454967.735663 +1178 1045 5468804.885664 +1046 1046 998249229.7754 +1047 1046 -2546330.297234 +1048 1046 -59888072.86758 +1049 1046 52583448.20272 +1062 1046 3564882.814418 +1063 1046 30555147.55986 +1064 1046 156468480.0912 +1065 1046 29728026.25477 +1066 1046 -16652573.77948 +1067 1046 -14634539.26698 +1140 1046 49815527.5467 +1141 1046 7638779.12366 +1142 1046 -72142989.75742 +1143 1046 5244680.501577 +1144 1046 6232693.774804 +1145 1046 -152469.232357 +1155 1046 -2546332.887312 +1156 1046 30555116.47959 +1157 1046 -164838704.0269 +1158 1046 -636583.2221438 +1159 1046 23555775.08708 +1160 1046 25663714.57989 +1173 1046 -47269194.65938 +1174 1046 7638779.123661 +1175 1046 -56670545.31551 +1176 1046 -4608097.279433 +1177 1046 5468804.885664 +1178 1046 1423975.212606 +1047 1047 703328029.7947 +1048 1047 3.576278686523e-07 +1049 1047 -10185321.18392 +1050 1047 65298758.21399 +1051 1047 -4.023313522339e-07 +1052 1047 -2546330.297233 +1062 1047 -43173523.32456 +1063 1047 -30555555.55054 +1064 1047 -27181695.95754 +1065 1047 -69150427.22048 +1066 1047 7.599592208862e-07 +1067 1047 6620438.369471 +1068 1047 -46611023.324 +1069 1047 30555555.55054 +1070 1047 30109970.69972 +1140 1047 -32955138.59878 +1141 1047 7638888.891398 +1142 1047 19567597.17295 +1143 1047 -59010186.71026 +1144 1047 1.542270183563e-06 +1145 1047 49433583.10251 +1146 1047 -10337951.09135 +1147 1047 -7638888.891398 +1148 1047 5244680.501577 +1155 1047 -66012341.70521 +1156 1047 2.853572368622e-06 +1157 1047 -636583.2221378 +1158 1047 20431686.98312 +1159 1047 -9.238719940186e-07 +1160 1047 -2546332.887312 +1161 1047 21018908.28051 +1162 1047 -2.346932888031e-06 +1163 1047 -636583.222144 +1173 1047 -30645221.93135 +1174 1047 -7638888.891397 +1175 1047 -18931013.9508 +1176 1047 -53208020.04453 +1177 1047 -1.534819602966e-06 +1178 1047 -46887250.21518 +1179 1047 -9746784.424485 +1180 1047 7638888.891396 +1181 1047 -4608097.279433 +1048 1048 629990235.6412 +1049 1048 122220590.1792 +1050 1048 -5.662441253662e-07 +1051 1048 -50812162.49284 +1052 1048 -62332517.31162 +1062 1048 -30555555.55054 +1063 1048 -34006299.05085 +1064 1048 -13597018.22442 +1065 1048 5.662441253662e-07 +1066 1048 65294942.0157 +1067 1048 30555147.55986 +1068 1048 30555555.55054 +1069 1048 -37443799.05029 +1070 1048 -16958129.33543 +1140 1048 7638888.891398 +1141 1048 -30663321.90996 +1142 1048 -13871472.89847 +1143 1048 1.035630702972e-06 +1144 1048 -25398826.77179 +1145 1048 7638779.123661 +1146 1048 -7638888.891398 +1147 1048 -8046134.402525 +1148 1048 6232693.774803 +1155 1048 2.995133399963e-06 +1156 1048 -95040068.27054 +1157 1048 -53805336.01132 +1158 1048 -9.536743164063e-07 +1159 1048 2097153.481574 +1160 1048 30555116.47959 +1161 1048 -2.235174179077e-06 +1162 1048 -8008818.28482 +1163 1048 23250219.53173 +1173 1048 -7638888.891397 +1174 1048 -28353405.24253 +1175 1048 -13107584.00933 +1176 1048 -1.318752765656e-06 +1177 1048 -19596660.10607 +1178 1048 7638779.123661 +1179 1048 7638888.891396 +1180 1048 -7454967.735663 +1181 1048 5468804.885664 +1049 1049 998249229.7754 +1050 1049 -2546330.297234 +1051 1049 -59888072.86758 +1052 1049 52583448.20272 +1062 1049 -27563640.40249 +1063 1049 -13902573.78038 +1064 1049 -5467872.601825 +1065 1049 3564882.814418 +1066 1049 30555147.55986 +1067 1049 156468480.0912 +1068 1049 29728026.25477 +1069 1049 -16652573.77948 +1070 1049 -14634539.26698 +1140 1049 19567597.17295 +1141 1049 -13871472.89847 +1142 1049 -60464969.25217 +1143 1049 49815527.5467 +1144 1049 7638779.12366 +1145 1049 -72142989.75742 +1146 1049 5244680.501577 +1147 1049 6232693.774804 +1148 1049 -152469.232357 +1155 1049 -636583.2221379 +1156 1049 -54110891.56668 +1157 1049 -206419618.7154 +1158 1049 -2546332.887312 +1159 1049 30555116.47959 +1160 1049 -164838704.0269 +1161 1049 -636583.2221438 +1162 1049 23555775.08708 +1163 1049 25663714.57989 +1173 1049 -18931013.9508 +1174 1049 -13107584.00933 +1175 1049 -54305191.47237 +1176 1049 -47269194.65938 +1177 1049 7638779.123661 +1178 1049 -56670545.31551 +1179 1049 -4608097.279433 +1180 1049 5468804.885664 +1181 1049 1423975.212606 +1050 1050 703328029.7947 +1051 1050 3.576278686523e-07 +1052 1050 -10185321.18392 +1053 1050 65298758.21399 +1054 1050 -4.023313522339e-07 +1055 1050 -2546330.297233 +1065 1050 -43173523.32456 +1066 1050 -30555555.55054 +1067 1050 -27181695.95754 +1068 1050 -69150427.22048 +1069 1050 7.599592208862e-07 +1070 1050 6620438.369471 +1071 1050 -46611023.324 +1072 1050 30555555.55054 +1073 1050 30109970.69972 +1143 1050 -32955138.59878 +1144 1050 7638888.891398 +1145 1050 19567597.17295 +1146 1050 -59010186.71026 +1147 1050 1.542270183563e-06 +1148 1050 49433583.10251 +1149 1050 -10337951.09135 +1150 1050 -7638888.891398 +1151 1050 5244680.501577 +1158 1050 -66012341.70521 +1159 1050 2.853572368622e-06 +1160 1050 -636583.2221378 +1161 1050 20431686.98312 +1162 1050 -9.238719940186e-07 +1163 1050 -2546332.887312 +1164 1050 21018908.28051 +1165 1050 -2.346932888031e-06 +1166 1050 -636583.222144 +1176 1050 -30645221.93135 +1177 1050 -7638888.891397 +1178 1050 -18931013.9508 +1179 1050 -53208020.04453 +1180 1050 -1.534819602966e-06 +1181 1050 -46887250.21518 +1182 1050 -9746784.424485 +1183 1050 7638888.891396 +1184 1050 -4608097.279433 +1051 1051 629990235.6412 +1052 1051 122220590.1792 +1053 1051 -5.662441253662e-07 +1054 1051 -50812162.49284 +1055 1051 -62332517.31162 +1065 1051 -30555555.55054 +1066 1051 -34006299.05085 +1067 1051 -13597018.22442 +1068 1051 5.662441253662e-07 +1069 1051 65294942.0157 +1070 1051 30555147.55986 +1071 1051 30555555.55054 +1072 1051 -37443799.05029 +1073 1051 -16958129.33543 +1143 1051 7638888.891398 +1144 1051 -30663321.90996 +1145 1051 -13871472.89847 +1146 1051 1.035630702972e-06 +1147 1051 -25398826.77179 +1148 1051 7638779.123661 +1149 1051 -7638888.891398 +1150 1051 -8046134.402525 +1151 1051 6232693.774803 +1158 1051 2.995133399963e-06 +1159 1051 -95040068.27054 +1160 1051 -53805336.01132 +1161 1051 -9.536743164063e-07 +1162 1051 2097153.481574 +1163 1051 30555116.47959 +1164 1051 -2.235174179077e-06 +1165 1051 -8008818.28482 +1166 1051 23250219.53173 +1176 1051 -7638888.891397 +1177 1051 -28353405.24253 +1178 1051 -13107584.00933 +1179 1051 -1.318752765656e-06 +1180 1051 -19596660.10607 +1181 1051 7638779.123661 +1182 1051 7638888.891396 +1183 1051 -7454967.735663 +1184 1051 5468804.885664 +1052 1052 998249229.7754 +1053 1052 -2546330.297234 +1054 1052 -59888072.86758 +1055 1052 52583448.20272 +1065 1052 -27563640.40249 +1066 1052 -13902573.78038 +1067 1052 -5467872.601825 +1068 1052 3564882.814418 +1069 1052 30555147.55986 +1070 1052 156468480.0912 +1071 1052 29728026.25477 +1072 1052 -16652573.77948 +1073 1052 -14634539.26698 +1143 1052 19567597.17295 +1144 1052 -13871472.89847 +1145 1052 -60464969.25217 +1146 1052 49815527.5467 +1147 1052 7638779.12366 +1148 1052 -72142989.75742 +1149 1052 5244680.501577 +1150 1052 6232693.774804 +1151 1052 -152469.232357 +1158 1052 -636583.2221379 +1159 1052 -54110891.56668 +1160 1052 -206419618.7154 +1161 1052 -2546332.887312 +1162 1052 30555116.47959 +1163 1052 -164838704.0269 +1164 1052 -636583.2221438 +1165 1052 23555775.08708 +1166 1052 25663714.57989 +1176 1052 -18931013.9508 +1177 1052 -13107584.00933 +1178 1052 -54305191.47237 +1179 1052 -47269194.65938 +1180 1052 7638779.123661 +1181 1052 -56670545.31551 +1182 1052 -4608097.279433 +1183 1052 5468804.885664 +1184 1052 1423975.212606 +1053 1053 703328029.7947 +1054 1053 3.576278686523e-07 +1055 1053 -10185321.18392 +1056 1053 65298758.21399 +1057 1053 -4.023313522339e-07 +1058 1053 -2546330.297233 +1068 1053 -43173523.32456 +1069 1053 -30555555.55054 +1070 1053 -27181695.95754 +1071 1053 -69150427.22048 +1072 1053 7.599592208862e-07 +1073 1053 6620438.369471 +1074 1053 -46611023.324 +1075 1053 30555555.55054 +1076 1053 30109970.69972 +1146 1053 -32955138.59878 +1147 1053 7638888.891398 +1148 1053 19567597.17295 +1149 1053 -59010186.71026 +1150 1053 1.542270183563e-06 +1151 1053 49433583.10251 +1152 1053 -10337951.09135 +1153 1053 -7638888.891398 +1154 1053 5244680.501577 +1161 1053 -66012341.70521 +1162 1053 2.853572368622e-06 +1163 1053 -636583.2221378 +1164 1053 20431686.98312 +1165 1053 -9.238719940186e-07 +1166 1053 -2546332.887312 +1167 1053 21018908.28051 +1168 1053 -2.346932888031e-06 +1169 1053 -636583.222144 +1179 1053 -30645221.93135 +1180 1053 -7638888.891397 +1181 1053 -18931013.9508 +1182 1053 -53208020.04453 +1183 1053 -1.534819602966e-06 +1184 1053 -46887250.21518 +1185 1053 -9746784.424485 +1186 1053 7638888.891396 +1187 1053 -4608097.279433 +1054 1054 629990235.6412 +1055 1054 122220590.1792 +1056 1054 -5.662441253662e-07 +1057 1054 -50812162.49284 +1058 1054 -62332517.31162 +1068 1054 -30555555.55054 +1069 1054 -34006299.05085 +1070 1054 -13597018.22442 +1071 1054 5.662441253662e-07 +1072 1054 65294942.0157 +1073 1054 30555147.55986 +1074 1054 30555555.55054 +1075 1054 -37443799.05029 +1076 1054 -16958129.33543 +1146 1054 7638888.891398 +1147 1054 -30663321.90996 +1148 1054 -13871472.89847 +1149 1054 1.035630702972e-06 +1150 1054 -25398826.77179 +1151 1054 7638779.123661 +1152 1054 -7638888.891398 +1153 1054 -8046134.402525 +1154 1054 6232693.774803 +1161 1054 2.995133399963e-06 +1162 1054 -95040068.27054 +1163 1054 -53805336.01132 +1164 1054 -9.536743164063e-07 +1165 1054 2097153.481574 +1166 1054 30555116.47959 +1167 1054 -2.235174179077e-06 +1168 1054 -8008818.28482 +1169 1054 23250219.53173 +1179 1054 -7638888.891397 +1180 1054 -28353405.24253 +1181 1054 -13107584.00933 +1182 1054 -1.318752765656e-06 +1183 1054 -19596660.10607 +1184 1054 7638779.123661 +1185 1054 7638888.891396 +1186 1054 -7454967.735663 +1187 1054 5468804.885664 +1055 1055 998249229.7754 +1056 1055 -2546330.297234 +1057 1055 -59888072.86758 +1058 1055 52583448.20272 +1068 1055 -27563640.40249 +1069 1055 -13902573.78038 +1070 1055 -5467872.601825 +1071 1055 3564882.814418 +1072 1055 30555147.55986 +1073 1055 156468480.0912 +1074 1055 29728026.25477 +1075 1055 -16652573.77948 +1076 1055 -14634539.26698 +1146 1055 19567597.17295 +1147 1055 -13871472.89847 +1148 1055 -60464969.25217 +1149 1055 49815527.5467 +1150 1055 7638779.12366 +1151 1055 -72142989.75742 +1152 1055 5244680.501577 +1153 1055 6232693.774804 +1154 1055 -152469.232357 +1161 1055 -636583.2221379 +1162 1055 -54110891.56668 +1163 1055 -206419618.7154 +1164 1055 -2546332.887312 +1165 1055 30555116.47959 +1166 1055 -164838704.0269 +1167 1055 -636583.2221438 +1168 1055 23555775.08708 +1169 1055 25663714.57989 +1179 1055 -18931013.9508 +1180 1055 -13107584.00933 +1181 1055 -54305191.47237 +1182 1055 -47269194.65938 +1183 1055 7638779.123661 +1184 1055 -56670545.31551 +1185 1055 -4608097.279433 +1186 1055 5468804.885664 +1187 1055 1423975.212606 +1056 1056 721009953.5089 +1057 1056 30610661.14353 +1058 1056 -34376411.47656 +1059 1056 22252951.07536 +1060 1056 -30577597.78774 +1061 1056 -30132237.29345 +1071 1056 -43173523.32456 +1072 1056 -30555555.55054 +1073 1056 -27181695.95754 +1074 1056 -69150427.22048 +1075 1056 7.599592208862e-07 +1076 1056 6620438.369471 +1077 1056 -46611023.324 +1078 1056 30555555.55054 +1079 1056 30109970.69972 +1149 1056 -32955138.59878 +1150 1056 7638888.891398 +1151 1056 19567597.17295 +1152 1056 -79032837.45136 +1153 1056 -7648437.10893 +1154 1056 55511888.47871 +1164 1056 -66012341.70521 +1165 1056 2.853572368622e-06 +1166 1056 -636583.2221378 +1167 1056 34928101.59242 +1168 1056 7654802.58729 +1169 1056 -8598678.217522 +1170 1056 5149787.278365 +1171 1056 -7645254.369755 +1172 1056 4611926.752539 +1182 1056 -30645221.93135 +1183 1056 -7638888.891397 +1184 1056 -18931013.9508 +1185 1056 -53208020.04453 +1186 1056 -1.534819602966e-06 +1187 1056 -46887250.21518 +1188 1056 -9746784.424485 +1189 1056 7638888.891396 +1190 1056 -4608097.279433 +1057 1057 638480136.047 +1058 1057 94719923.44838 +1059 1057 -30588618.90634 +1060 1057 -84734829.23983 +1061 1057 -51960954.36765 +1071 1057 -30555555.55054 +1072 1057 -34006299.05085 +1073 1057 -13597018.22442 +1074 1057 5.662441253662e-07 +1075 1057 65294942.0157 +1076 1057 30555147.55986 +1077 1057 30555555.55054 +1078 1057 -37443799.05029 +1079 1057 -16958129.33543 +1149 1057 7638888.891398 +1150 1057 -30663321.90996 +1151 1057 -13871472.89847 +1152 1057 -7645254.369751 +1153 1057 -43109768.41806 +1154 1057 18161862.49682 +1164 1057 2.995133399963e-06 +1165 1057 -95040068.27054 +1166 1057 -53805336.01132 +1167 1057 7654802.587289 +1168 1057 14294589.76961 +1169 1057 23676298.37333 +1170 1057 -7648437.108933 +1171 1057 -21598853.37172 +1172 1057 25862479.31684 +1182 1057 -7638888.891397 +1183 1057 -28353405.24253 +1184 1057 -13107584.00933 +1185 1057 -1.318752765656e-06 +1186 1057 -19596660.10607 +1187 1057 7638779.123661 +1188 1057 7638888.891396 +1189 1057 -7454967.735663 +1190 1057 5468804.885664 +1058 1058 935442848.8393 +1059 1058 -29761426.14538 +1060 1058 -58081061.81704 +1061 1058 47500235.97878 +1071 1058 -27563640.40249 +1072 1058 -13902573.78038 +1073 1058 -5467872.601825 +1074 1058 3564882.814418 +1075 1058 30555147.55986 +1076 1058 156468480.0912 +1077 1058 29728026.25477 +1078 1058 -16652573.77948 +1079 1058 -14634539.26698 +1149 1058 19567597.17295 +1150 1058 -13871472.89847 +1151 1058 -60464969.25217 +1152 1058 55896750.56943 +1153 1058 20307057.29599 +1154 1058 -98048385.90041 +1164 1058 -636583.2221379 +1165 1058 -54110891.56668 +1166 1058 -206419618.7154 +1167 1058 -8588615.841047 +1168 1058 23684348.15878 +1169 1058 -153682668.3423 +1170 1058 4613841.489092 +1171 1058 24026705.92618 +1172 1058 10774189.69233 +1182 1058 -18931013.9508 +1183 1058 -13107584.00933 +1184 1058 -54305191.47237 +1185 1058 -47269194.65938 +1186 1058 7638779.123661 +1187 1058 -56670545.31551 +1188 1058 -4608097.279433 +1189 1058 5468804.885664 +1190 1058 1423975.212606 +1059 1059 367439587.8674 +1060 1059 -6444670.14594 +1061 1059 6702162.32163 +1074 1059 -43173523.32456 +1075 1059 -30555555.55054 +1076 1059 -27181695.95754 +1077 1059 -57214134.66201 +1078 1059 6324640.430005 +1079 1059 3976848.141463 +1080 1059 -42286740.95386 +1081 1059 24564474.15636 +1082 1059 1550068.294194 +1152 1059 -37437760.48235 +1153 1059 9176214.887214 +1154 1059 23123609.08966 +1167 1059 -61598018.00238 +1168 1059 -7648437.108935 +1169 1059 -19592039.58835 +1170 1059 18456352.87299 +1171 1059 -3515413.057224 +1172 1059 9204137.171611 +1185 1059 -30645221.93135 +1186 1059 -7638888.891397 +1187 1059 -18931013.9508 +1188 1059 -30340144.80161 +1189 1059 3467943.693614 +1190 1059 -30119546.23577 +1191 1059 -19821700.11939 +1192 1059 6158580.476729 +1193 1059 -1921392.690481 +1060 1060 419218508.677 +1061 1060 80031030.37421 +1074 1060 -30555555.55054 +1075 1060 -34006299.05085 +1076 1060 -13597018.22442 +1077 1060 6264625.572038 +1078 1060 70122596.35682 +1079 1060 21137034.96597 +1080 1060 36846711.23454 +1081 1060 -123581836.7408 +1082 1060 -19765521.80219 +1152 1060 6117476.591476 +1153 1060 -37437760.48236 +1154 1060 -12332056.26767 +1167 1060 -7645254.369756 +1168 1060 -88346658.65246 +1169 1060 -53374653.70739 +1170 1060 -3515413.057224 +1171 1060 45200470.13904 +1172 1060 28178112.40107 +1185 1060 -7638888.891397 +1186 1060 -28353405.24253 +1187 1060 -13107584.00933 +1188 1060 3444209.011808 +1189 1060 692072.0501018 +1190 1060 9579154.834703 +1191 1060 9237870.715094 +1192 1060 -53141210.27589 +1193 1060 10606269.5228 +1061 1061 548014788.7711 +1074 1061 -27563640.40249 +1075 1061 -13902573.78038 +1076 1061 -5467872.601825 +1077 1061 9316353.373012 +1078 1061 18981174.69952 +1079 1061 100137434.615 +1080 1061 2325102.441291 +1081 1061 -18561981.68092 +1082 1061 -31469546.75673 +1152 1061 15415739.3931 +1153 1061 -18498084.4015 +1154 1061 -99834027.95294 +1167 1061 -19583892.11655 +1168 1061 -51538880.44741 +1169 1061 -167219957.723 +1170 1061 -3159598.760604 +1171 1061 18338796.75477 +1172 1061 -61684899.57103 +1185 1061 -18931013.9508 +1186 1061 -13107584.00933 +1187 1061 -54305191.47237 +1188 1061 -28213514.83563 +1189 1061 9298506.145881 +1190 1061 -27781546.3564 +1191 1061 -2882089.035722 +1192 1061 9831110.118881 +1193 1061 -19538356.82854 +1062 1062 703328029.7947 +1063 1062 3.576278686523e-07 +1064 1062 -10185321.18392 +1065 1062 65298758.21399 +1066 1062 -4.023313522339e-07 +1067 1062 -2546330.297233 +1083 1062 -69150427.22048 +1084 1062 7.599592208862e-07 +1085 1062 6620438.369471 +1086 1062 -46611023.324 +1087 1062 30555555.55054 +1088 1062 30109970.69972 +1155 1062 -59010186.71026 +1156 1062 1.542270183563e-06 +1157 1062 49433583.10251 +1158 1062 -10337951.09135 +1159 1062 -7638888.891398 +1160 1062 5244680.501577 +1173 1062 20431686.98312 +1174 1062 -9.238719940186e-07 +1175 1062 -2546332.887312 +1176 1062 21018908.28051 +1177 1062 -2.346932888031e-06 +1178 1062 -636583.222144 +1194 1062 -53208020.04453 +1195 1062 -1.534819602966e-06 +1196 1062 -46887250.21518 +1197 1062 -9746784.424485 +1198 1062 7638888.891396 +1199 1062 -4608097.279433 +1063 1063 629990235.6412 +1064 1063 122220590.1792 +1065 1063 -5.662441253662e-07 +1066 1063 -50812162.49284 +1067 1063 -62332517.31162 +1083 1063 5.662441253662e-07 +1084 1063 65294942.0157 +1085 1063 30555147.55986 +1086 1063 30555555.55054 +1087 1063 -37443799.05029 +1088 1063 -16958129.33543 +1155 1063 1.035630702972e-06 +1156 1063 -25398826.77179 +1157 1063 7638779.123661 +1158 1063 -7638888.891398 +1159 1063 -8046134.402525 +1160 1063 6232693.774803 +1173 1063 -9.536743164063e-07 +1174 1063 2097153.481574 +1175 1063 30555116.47959 +1176 1063 -2.235174179077e-06 +1177 1063 -8008818.28482 +1178 1063 23250219.53173 +1194 1063 -1.318752765656e-06 +1195 1063 -19596660.10607 +1196 1063 7638779.123661 +1197 1063 7638888.891396 +1198 1063 -7454967.735663 +1199 1063 5468804.885664 +1064 1064 998249229.7754 +1065 1064 -2546330.297234 +1066 1064 -59888072.86758 +1067 1064 52583448.20272 +1083 1064 3564882.814418 +1084 1064 30555147.55986 +1085 1064 156468480.0912 +1086 1064 29728026.25477 +1087 1064 -16652573.77948 +1088 1064 -14634539.26698 +1155 1064 49815527.5467 +1156 1064 7638779.12366 +1157 1064 -72142989.75742 +1158 1064 5244680.501577 +1159 1064 6232693.774804 +1160 1064 -152469.232357 +1173 1064 -2546332.887312 +1174 1064 30555116.47959 +1175 1064 -164838704.0269 +1176 1064 -636583.2221438 +1177 1064 23555775.08708 +1178 1064 25663714.57989 +1194 1064 -47269194.65938 +1195 1064 7638779.123661 +1196 1064 -56670545.31551 +1197 1064 -4608097.279433 +1198 1064 5468804.885664 +1199 1064 1423975.212606 +1065 1065 703328029.7947 +1066 1065 3.576278686523e-07 +1067 1065 -10185321.18392 +1068 1065 65298758.21399 +1069 1065 -4.023313522339e-07 +1070 1065 -2546330.297233 +1083 1065 -43173523.32456 +1084 1065 -30555555.55054 +1085 1065 -27181695.95754 +1086 1065 -69150427.22048 +1087 1065 7.599592208862e-07 +1088 1065 6620438.369471 +1089 1065 -46611023.324 +1090 1065 30555555.55054 +1091 1065 30109970.69972 +1155 1065 -32955138.59878 +1156 1065 7638888.891398 +1157 1065 19567597.17295 +1158 1065 -59010186.71026 +1159 1065 1.542270183563e-06 +1160 1065 49433583.10251 +1161 1065 -10337951.09135 +1162 1065 -7638888.891398 +1163 1065 5244680.501577 +1173 1065 -66012341.70521 +1174 1065 2.853572368622e-06 +1175 1065 -636583.2221378 +1176 1065 20431686.98312 +1177 1065 -9.238719940186e-07 +1178 1065 -2546332.887312 +1179 1065 21018908.28051 +1180 1065 -2.346932888031e-06 +1181 1065 -636583.222144 +1194 1065 -30645221.93135 +1195 1065 -7638888.891397 +1196 1065 -18931013.9508 +1197 1065 -53208020.04453 +1198 1065 -1.534819602966e-06 +1199 1065 -46887250.21518 +1200 1065 -9746784.424485 +1201 1065 7638888.891396 +1202 1065 -4608097.279433 +1066 1066 629990235.6412 +1067 1066 122220590.1792 +1068 1066 -5.662441253662e-07 +1069 1066 -50812162.49284 +1070 1066 -62332517.31162 +1083 1066 -30555555.55054 +1084 1066 -34006299.05085 +1085 1066 -13597018.22442 +1086 1066 5.662441253662e-07 +1087 1066 65294942.0157 +1088 1066 30555147.55986 +1089 1066 30555555.55054 +1090 1066 -37443799.05029 +1091 1066 -16958129.33543 +1155 1066 7638888.891398 +1156 1066 -30663321.90996 +1157 1066 -13871472.89847 +1158 1066 1.035630702972e-06 +1159 1066 -25398826.77179 +1160 1066 7638779.123661 +1161 1066 -7638888.891398 +1162 1066 -8046134.402525 +1163 1066 6232693.774803 +1173 1066 2.995133399963e-06 +1174 1066 -95040068.27054 +1175 1066 -53805336.01132 +1176 1066 -9.536743164063e-07 +1177 1066 2097153.481574 +1178 1066 30555116.47959 +1179 1066 -2.235174179077e-06 +1180 1066 -8008818.28482 +1181 1066 23250219.53173 +1194 1066 -7638888.891397 +1195 1066 -28353405.24253 +1196 1066 -13107584.00933 +1197 1066 -1.318752765656e-06 +1198 1066 -19596660.10607 +1199 1066 7638779.123661 +1200 1066 7638888.891396 +1201 1066 -7454967.735663 +1202 1066 5468804.885664 +1067 1067 998249229.7754 +1068 1067 -2546330.297234 +1069 1067 -59888072.86758 +1070 1067 52583448.20272 +1083 1067 -27563640.40249 +1084 1067 -13902573.78038 +1085 1067 -5467872.601825 +1086 1067 3564882.814418 +1087 1067 30555147.55986 +1088 1067 156468480.0912 +1089 1067 29728026.25477 +1090 1067 -16652573.77948 +1091 1067 -14634539.26698 +1155 1067 19567597.17295 +1156 1067 -13871472.89847 +1157 1067 -60464969.25217 +1158 1067 49815527.5467 +1159 1067 7638779.12366 +1160 1067 -72142989.75742 +1161 1067 5244680.501577 +1162 1067 6232693.774804 +1163 1067 -152469.232357 +1173 1067 -636583.2221379 +1174 1067 -54110891.56668 +1175 1067 -206419618.7154 +1176 1067 -2546332.887312 +1177 1067 30555116.47959 +1178 1067 -164838704.0269 +1179 1067 -636583.2221438 +1180 1067 23555775.08708 +1181 1067 25663714.57989 +1194 1067 -18931013.9508 +1195 1067 -13107584.00933 +1196 1067 -54305191.47237 +1197 1067 -47269194.65938 +1198 1067 7638779.123661 +1199 1067 -56670545.31551 +1200 1067 -4608097.279433 +1201 1067 5468804.885664 +1202 1067 1423975.212606 +1068 1068 703328029.7947 +1069 1068 3.576278686523e-07 +1070 1068 -10185321.18392 +1071 1068 65298758.21399 +1072 1068 -4.023313522339e-07 +1073 1068 -2546330.297233 +1086 1068 -43173523.32456 +1087 1068 -30555555.55054 +1088 1068 -27181695.95754 +1089 1068 -69150427.22048 +1090 1068 7.599592208862e-07 +1091 1068 6620438.369471 +1092 1068 -46611023.324 +1093 1068 30555555.55054 +1094 1068 30109970.69972 +1158 1068 -32955138.59878 +1159 1068 7638888.891398 +1160 1068 19567597.17295 +1161 1068 -59010186.71026 +1162 1068 1.542270183563e-06 +1163 1068 49433583.10251 +1164 1068 -10337951.09135 +1165 1068 -7638888.891398 +1166 1068 5244680.501577 +1176 1068 -66012341.70521 +1177 1068 2.853572368622e-06 +1178 1068 -636583.2221378 +1179 1068 20431686.98312 +1180 1068 -9.238719940186e-07 +1181 1068 -2546332.887312 +1182 1068 21018908.28051 +1183 1068 -2.346932888031e-06 +1184 1068 -636583.222144 +1197 1068 -30645221.93135 +1198 1068 -7638888.891397 +1199 1068 -18931013.9508 +1200 1068 -53208020.04453 +1201 1068 -1.534819602966e-06 +1202 1068 -46887250.21518 +1203 1068 -9746784.424485 +1204 1068 7638888.891396 +1205 1068 -4608097.279433 +1069 1069 629990235.6412 +1070 1069 122220590.1792 +1071 1069 -5.662441253662e-07 +1072 1069 -50812162.49284 +1073 1069 -62332517.31162 +1086 1069 -30555555.55054 +1087 1069 -34006299.05085 +1088 1069 -13597018.22442 +1089 1069 5.662441253662e-07 +1090 1069 65294942.0157 +1091 1069 30555147.55986 +1092 1069 30555555.55054 +1093 1069 -37443799.05029 +1094 1069 -16958129.33543 +1158 1069 7638888.891398 +1159 1069 -30663321.90996 +1160 1069 -13871472.89847 +1161 1069 1.035630702972e-06 +1162 1069 -25398826.77179 +1163 1069 7638779.123661 +1164 1069 -7638888.891398 +1165 1069 -8046134.402525 +1166 1069 6232693.774803 +1176 1069 2.995133399963e-06 +1177 1069 -95040068.27054 +1178 1069 -53805336.01132 +1179 1069 -9.536743164063e-07 +1180 1069 2097153.481574 +1181 1069 30555116.47959 +1182 1069 -2.235174179077e-06 +1183 1069 -8008818.28482 +1184 1069 23250219.53173 +1197 1069 -7638888.891397 +1198 1069 -28353405.24253 +1199 1069 -13107584.00933 +1200 1069 -1.318752765656e-06 +1201 1069 -19596660.10607 +1202 1069 7638779.123661 +1203 1069 7638888.891396 +1204 1069 -7454967.735663 +1205 1069 5468804.885664 +1070 1070 998249229.7754 +1071 1070 -2546330.297234 +1072 1070 -59888072.86758 +1073 1070 52583448.20272 +1086 1070 -27563640.40249 +1087 1070 -13902573.78038 +1088 1070 -5467872.601825 +1089 1070 3564882.814418 +1090 1070 30555147.55986 +1091 1070 156468480.0912 +1092 1070 29728026.25477 +1093 1070 -16652573.77948 +1094 1070 -14634539.26698 +1158 1070 19567597.17295 +1159 1070 -13871472.89847 +1160 1070 -60464969.25217 +1161 1070 49815527.5467 +1162 1070 7638779.12366 +1163 1070 -72142989.75742 +1164 1070 5244680.501577 +1165 1070 6232693.774804 +1166 1070 -152469.232357 +1176 1070 -636583.2221379 +1177 1070 -54110891.56668 +1178 1070 -206419618.7154 +1179 1070 -2546332.887312 +1180 1070 30555116.47959 +1181 1070 -164838704.0269 +1182 1070 -636583.2221438 +1183 1070 23555775.08708 +1184 1070 25663714.57989 +1197 1070 -18931013.9508 +1198 1070 -13107584.00933 +1199 1070 -54305191.47237 +1200 1070 -47269194.65938 +1201 1070 7638779.123661 +1202 1070 -56670545.31551 +1203 1070 -4608097.279433 +1204 1070 5468804.885664 +1205 1070 1423975.212606 +1071 1071 703328029.7947 +1072 1071 3.576278686523e-07 +1073 1071 -10185321.18392 +1074 1071 65298758.21399 +1075 1071 -4.023313522339e-07 +1076 1071 -2546330.297233 +1089 1071 -43173523.32456 +1090 1071 -30555555.55054 +1091 1071 -27181695.95754 +1092 1071 -69150427.22048 +1093 1071 7.599592208862e-07 +1094 1071 6620438.369471 +1095 1071 -46611023.324 +1096 1071 30555555.55054 +1097 1071 30109970.69972 +1161 1071 -32955138.59878 +1162 1071 7638888.891398 +1163 1071 19567597.17295 +1164 1071 -59010186.71026 +1165 1071 1.542270183563e-06 +1166 1071 49433583.10251 +1167 1071 -10337951.09135 +1168 1071 -7638888.891398 +1169 1071 5244680.501577 +1179 1071 -66012341.70521 +1180 1071 2.853572368622e-06 +1181 1071 -636583.2221378 +1182 1071 20431686.98312 +1183 1071 -9.238719940186e-07 +1184 1071 -2546332.887312 +1185 1071 21018908.28051 +1186 1071 -2.346932888031e-06 +1187 1071 -636583.222144 +1200 1071 -30645221.93135 +1201 1071 -7638888.891397 +1202 1071 -18931013.9508 +1203 1071 -53208020.04453 +1204 1071 -1.534819602966e-06 +1205 1071 -46887250.21518 +1206 1071 -9746784.424485 +1207 1071 7638888.891396 +1208 1071 -4608097.279433 +1072 1072 629990235.6412 +1073 1072 122220590.1792 +1074 1072 -5.662441253662e-07 +1075 1072 -50812162.49284 +1076 1072 -62332517.31162 +1089 1072 -30555555.55054 +1090 1072 -34006299.05085 +1091 1072 -13597018.22442 +1092 1072 5.662441253662e-07 +1093 1072 65294942.0157 +1094 1072 30555147.55986 +1095 1072 30555555.55054 +1096 1072 -37443799.05029 +1097 1072 -16958129.33543 +1161 1072 7638888.891398 +1162 1072 -30663321.90996 +1163 1072 -13871472.89847 +1164 1072 1.035630702972e-06 +1165 1072 -25398826.77179 +1166 1072 7638779.123661 +1167 1072 -7638888.891398 +1168 1072 -8046134.402525 +1169 1072 6232693.774803 +1179 1072 2.995133399963e-06 +1180 1072 -95040068.27054 +1181 1072 -53805336.01132 +1182 1072 -9.536743164063e-07 +1183 1072 2097153.481574 +1184 1072 30555116.47959 +1185 1072 -2.235174179077e-06 +1186 1072 -8008818.28482 +1187 1072 23250219.53173 +1200 1072 -7638888.891397 +1201 1072 -28353405.24253 +1202 1072 -13107584.00933 +1203 1072 -1.318752765656e-06 +1204 1072 -19596660.10607 +1205 1072 7638779.123661 +1206 1072 7638888.891396 +1207 1072 -7454967.735663 +1208 1072 5468804.885664 +1073 1073 998249229.7754 +1074 1073 -2546330.297234 +1075 1073 -59888072.86758 +1076 1073 52583448.20272 +1089 1073 -27563640.40249 +1090 1073 -13902573.78038 +1091 1073 -5467872.601825 +1092 1073 3564882.814418 +1093 1073 30555147.55986 +1094 1073 156468480.0912 +1095 1073 29728026.25477 +1096 1073 -16652573.77948 +1097 1073 -14634539.26698 +1161 1073 19567597.17295 +1162 1073 -13871472.89847 +1163 1073 -60464969.25217 +1164 1073 49815527.5467 +1165 1073 7638779.12366 +1166 1073 -72142989.75742 +1167 1073 5244680.501577 +1168 1073 6232693.774804 +1169 1073 -152469.232357 +1179 1073 -636583.2221379 +1180 1073 -54110891.56668 +1181 1073 -206419618.7154 +1182 1073 -2546332.887312 +1183 1073 30555116.47959 +1184 1073 -164838704.0269 +1185 1073 -636583.2221438 +1186 1073 23555775.08708 +1187 1073 25663714.57989 +1200 1073 -18931013.9508 +1201 1073 -13107584.00933 +1202 1073 -54305191.47237 +1203 1073 -47269194.65938 +1204 1073 7638779.123661 +1205 1073 -56670545.31551 +1206 1073 -4608097.279433 +1207 1073 5468804.885664 +1208 1073 1423975.212606 +1074 1074 703328029.7947 +1075 1074 3.576278686523e-07 +1076 1074 -10185321.18392 +1077 1074 65298758.21399 +1078 1074 -4.023313522339e-07 +1079 1074 -2546330.297233 +1092 1074 -43173523.32456 +1093 1074 -30555555.55054 +1094 1074 -27181695.95754 +1095 1074 -69150427.22048 +1096 1074 7.599592208862e-07 +1097 1074 6620438.369471 +1098 1074 -46611023.324 +1099 1074 30555555.55054 +1100 1074 30109970.69972 +1164 1074 -32955138.59878 +1165 1074 7638888.891398 +1166 1074 19567597.17295 +1167 1074 -59010186.71026 +1168 1074 1.542270183563e-06 +1169 1074 49433583.10251 +1170 1074 -10337951.09135 +1171 1074 -7638888.891398 +1172 1074 5244680.501577 +1182 1074 -66012341.70521 +1183 1074 2.853572368622e-06 +1184 1074 -636583.2221378 +1185 1074 20431686.98312 +1186 1074 -9.238719940186e-07 +1187 1074 -2546332.887312 +1188 1074 21018908.28051 +1189 1074 -2.346932888031e-06 +1190 1074 -636583.222144 +1203 1074 -30645221.93135 +1204 1074 -7638888.891397 +1205 1074 -18931013.9508 +1206 1074 -53208020.04453 +1207 1074 -1.534819602966e-06 +1208 1074 -46887250.21518 +1209 1074 -9746784.424485 +1210 1074 7638888.891396 +1211 1074 -4608097.279433 +1075 1075 629990235.6412 +1076 1075 122220590.1792 +1077 1075 -5.662441253662e-07 +1078 1075 -50812162.49284 +1079 1075 -62332517.31162 +1092 1075 -30555555.55054 +1093 1075 -34006299.05085 +1094 1075 -13597018.22442 +1095 1075 5.662441253662e-07 +1096 1075 65294942.0157 +1097 1075 30555147.55986 +1098 1075 30555555.55054 +1099 1075 -37443799.05029 +1100 1075 -16958129.33543 +1164 1075 7638888.891398 +1165 1075 -30663321.90996 +1166 1075 -13871472.89847 +1167 1075 1.035630702972e-06 +1168 1075 -25398826.77179 +1169 1075 7638779.123661 +1170 1075 -7638888.891398 +1171 1075 -8046134.402525 +1172 1075 6232693.774803 +1182 1075 2.995133399963e-06 +1183 1075 -95040068.27054 +1184 1075 -53805336.01132 +1185 1075 -9.536743164063e-07 +1186 1075 2097153.481574 +1187 1075 30555116.47959 +1188 1075 -2.235174179077e-06 +1189 1075 -8008818.28482 +1190 1075 23250219.53173 +1203 1075 -7638888.891397 +1204 1075 -28353405.24253 +1205 1075 -13107584.00933 +1206 1075 -1.318752765656e-06 +1207 1075 -19596660.10607 +1208 1075 7638779.123661 +1209 1075 7638888.891396 +1210 1075 -7454967.735663 +1211 1075 5468804.885664 +1076 1076 998249229.7754 +1077 1076 -2546330.297234 +1078 1076 -59888072.86758 +1079 1076 52583448.20272 +1092 1076 -27563640.40249 +1093 1076 -13902573.78038 +1094 1076 -5467872.601825 +1095 1076 3564882.814418 +1096 1076 30555147.55986 +1097 1076 156468480.0912 +1098 1076 29728026.25477 +1099 1076 -16652573.77948 +1100 1076 -14634539.26698 +1164 1076 19567597.17295 +1165 1076 -13871472.89847 +1166 1076 -60464969.25217 +1167 1076 49815527.5467 +1168 1076 7638779.12366 +1169 1076 -72142989.75742 +1170 1076 5244680.501577 +1171 1076 6232693.774804 +1172 1076 -152469.232357 +1182 1076 -636583.2221379 +1183 1076 -54110891.56668 +1184 1076 -206419618.7154 +1185 1076 -2546332.887312 +1186 1076 30555116.47959 +1187 1076 -164838704.0269 +1188 1076 -636583.2221438 +1189 1076 23555775.08708 +1190 1076 25663714.57989 +1203 1076 -18931013.9508 +1204 1076 -13107584.00933 +1205 1076 -54305191.47237 +1206 1076 -47269194.65938 +1207 1076 7638779.123661 +1208 1076 -56670545.31551 +1209 1076 -4608097.279433 +1210 1076 5468804.885664 +1211 1076 1423975.212606 +1077 1077 570501723.1357 +1078 1077 9079022.427935 +1079 1077 -9274929.964965 +1080 1077 -31839728.53513 +1081 1077 -51458572.29585 +1082 1077 -7127824.323312 +1095 1077 -43173523.32456 +1096 1077 -30555555.55054 +1097 1077 -27181695.95754 +1098 1077 -46568529.59302 +1099 1077 16027965.13575 +1100 1077 2967342.757803 +1101 1077 -20904300.89722 +1102 1077 20086959.16013 +1103 1077 4112201.618113 +1167 1077 -32955138.59878 +1168 1077 7638888.891398 +1169 1077 19567597.17295 +1170 1077 -37020168.145 +1171 1077 3444209.011809 +1172 1077 33605164.82544 +1185 1077 -66012341.70521 +1186 1077 2.853572368622e-06 +1187 1077 -636583.2221378 +1188 1077 28568367.61238 +1189 1077 2250538.971708 +1190 1077 -2147300.291512 +1191 1077 -25990848.25866 +1192 1077 -14160162.85565 +1193 1077 10214737.96898 +1206 1077 -30645221.93135 +1207 1077 -7638888.891397 +1208 1077 -18931013.9508 +1209 1077 -42000541.15558 +1210 1077 4593894.893531 +1211 1077 -39062848.24116 +1212 1077 -12782232.44445 +1213 1077 3871519.978604 +1214 1077 -2550174.723511 +1078 1078 602206739.2136 +1079 1078 78107882.18832 +1080 1078 -51518587.15382 +1081 1078 -149270648.6277 +1082 1078 -15352296.85928 +1095 1078 -30555555.55054 +1096 1078 -34006299.05085 +1097 1078 -13597018.22442 +1098 1078 16027965.13575 +1099 1078 61070693.25451 +1100 1078 16474762.21805 +1101 1078 20086959.16013 +1102 1078 -72377878.58954 +1103 1078 -8079345.074944 +1167 1078 7638888.891398 +1168 1078 -30663321.90996 +1169 1078 -13871472.89847 +1170 1078 3467943.693615 +1171 1078 -5987951.293276 +1172 1078 553673.964687 +1185 1078 2.995133399963e-06 +1186 1078 -95040068.27054 +1187 1078 -53805336.01132 +1188 1078 2250538.971707 +1189 1078 43780387.67943 +1190 1078 20402730.74043 +1191 1078 -14183897.53746 +1192 1078 -56594197.06368 +1193 1078 34727712.16061 +1206 1078 -7638888.891397 +1207 1078 -28353405.24253 +1208 1078 -13107584.00933 +1209 1078 4593894.893531 +1210 1078 -17139975.40311 +1211 1078 10863138.72183 +1212 1078 3871519.978604 +1213 1078 -28839593.123 +1214 1078 14284805.5813 +1079 1079 752156033.5716 +1080 1079 -6757025.137261 +1081 1079 -14149789.86418 +1082 1079 17937302.5459 +1095 1079 -27563640.40249 +1096 1079 -13902573.78038 +1097 1079 -5467872.601825 +1098 1079 8696509.423527 +1099 1079 16169206.66254 +1100 1079 132992729.5666 +1101 1079 3348312.728221 +1102 1079 -8079345.074944 +1103 1079 2933439.403798 +1167 1079 19567597.17295 +1168 1079 -13871472.89847 +1169 1079 -60464969.25217 +1170 1079 31699133.42531 +1171 1079 894158.2412029 +1172 1079 -45594941.93873 +1185 1079 -636583.2221379 +1186 1079 -54110891.56668 +1187 1079 -206419618.7154 +1188 1079 -2127175.46838 +1189 1079 20418832.32509 +1190 1079 -110189348.5657 +1191 1079 10220712.09006 +1192 1079 34700515.9782 +1193 1079 -36988737.34261 +1206 1079 -18931013.9508 +1207 1079 -13107584.00933 +1208 1079 -54305191.47237 +1209 1079 -37153126.01612 +1210 1079 10863138.72329 +1211 1079 -51173139.66418 +1212 1079 -2550174.723511 +1213 1079 14284805.5813 +1214 1079 -18432385.38669 +1080 1080 441900073.546 +1081 1080 10150442.22681 +1082 1080 -3907142.848424 +1098 1080 -39682007.72661 +1099 1080 -29098948.8429 +1100 1080 -3693457.663771 +1101 1080 32090689.3218 +1102 1080 22812216.28582 +1103 1080 3150441.404939 +1104 1080 77149508.19 +1105 1080 -14804593.1609 +1106 1080 213770.8266398 +1107 1080 4228979.174319 +1108 1080 25612759.41044 +1109 1080 1029422.0867 +1170 1080 -26928306.79151 +1171 1080 9237870.715094 +1172 1080 5198285.296003 +1188 1080 -38329908.16593 +1189 1080 -14183897.53746 +1190 1080 -14013967.79219 +1191 1080 -25957044.68394 +1192 1080 3016827.972827 +1193 1080 9482743.61017 +1209 1080 -20891328.62495 +1210 1080 -7095495.010489 +1211 1080 -13022180.51333 +1212 1080 -52119203.19171 +1213 1080 6820581.445927 +1214 1080 -46618553.49094 +1215 1080 -28126911.39166 +1216 1080 -4001073.446638 +1217 1080 12806770.0787 +1218 1080 -18753093.0123 +1219 1080 6205185.860737 +1220 1080 -11366986.07681 +1081 1081 580486288.2643 +1082 1081 22691862.99995 +1098 1081 -29098948.8429 +1099 1081 -17363440.96438 +1100 1081 -73698.46132895 +1101 1081 22812216.28582 +1102 1081 142916154.0449 +1103 1081 5377779.606667 +1104 1081 -2582370.940681 +1105 1081 17900862.83321 +1106 1081 -606809.4308197 +1107 1081 25612759.41044 +1108 1081 -9526605.793109 +1109 1081 -711679.6250324 +1170 1081 6158580.476729 +1171 1081 -60247816.94801 +1172 1081 -22683651.68266 +1188 1081 -14160162.85565 +1189 1081 -68933256.97095 +1190 1081 -42828570.94811 +1191 1081 3016827.972827 +1192 1081 23366674.83819 +1193 1081 9832075.434784 +1209 1081 -7095495.010489 +1210 1081 -14494911.61067 +1211 1081 -9604397.379856 +1212 1081 6820581.445928 +1213 1081 -25052049.96819 +1214 1081 8435776.588031 +1215 1081 -945517.8900795 +1216 1081 -42892980.14588 +1217 1081 33178246.2864 +1218 1081 6205185.860737 +1219 1081 -22851455.05649 +1220 1081 16480334.95681 +1082 1082 715157788.3498 +1098 1082 -4075402.108717 +1099 1082 -379254.0172859 +1100 1082 14849046.76255 +1101 1082 1622663.627413 +1102 1082 5072224.051161 +1103 1082 239843057.1136 +1104 1082 -168173.6177378 +1105 1082 -606809.4308198 +1106 1082 161890430.9423 +1107 1082 647477.6417536 +1108 1082 -711679.6250324 +1109 1082 59287315.75331 +1170 1082 3465523.530669 +1171 1082 -24063482.84713 +1172 1082 -38489307.95421 +1188 1082 -13999817.14035 +1189 1082 -42845108.80891 +1190 1082 -69892897.09532 +1191 1082 -9440589.720055 +1192 1082 7633351.086299 +1193 1082 -195780653.0959 +1209 1082 -13022180.51333 +1210 1082 -9604397.379856 +1211 1082 -25668168.01612 +1212 1082 -46618553.49056 +1213 1082 8435776.589485 +1214 1082 -108413832.6808 +1215 1082 4681770.077847 +1216 1082 33178246.2864 +1217 1082 -85160955.10089 +1218 1082 -11366986.07681 +1219 1082 16480334.95681 +1220 1082 -39542975.02213 +1083 1083 351205681.5641 +1084 1083 7.748603820801e-07 +1085 1083 2546228.295676 +1086 1083 32592087.44026 +1087 1083 6111111.110108 +1088 1083 5410862.629475 +1173 1083 -59010186.71026 +1174 1083 1.542270183563e-06 +1175 1083 49433583.10251 +1176 1083 -10337951.09135 +1177 1083 -7638888.891398 +1178 1083 5244680.501577 +1194 1083 10158551.82493 +1195 1083 -1.639127731323e-06 +1196 1083 -9988583.109361 +1197 1083 10509454.14025 +1198 1083 1527777.778278 +1199 1083 -1303569.389173 +1084 1084 314536784.4873 +1085 1084 61110295.08961 +1086 1084 -6111111.110107 +1087 1084 -25463372.91316 +1088 1084 -30860703.10031 +1173 1084 1.035630702972e-06 +1174 1084 -25398826.77179 +1175 1084 7638779.123661 +1176 1084 -7638888.891398 +1177 1084 -8046134.402525 +1178 1084 6232693.774803 +1194 1084 -1.132488250732e-06 +1195 1084 991285.0741574 +1196 1084 15277558.23979 +1197 1084 -1527777.77828 +1198 1084 -4004409.142409 +1199 1084 11701498.65478 +1085 1085 497902392.6657 +1086 1085 -6047470.701977 +1087 1085 -30249591.9893 +1088 1085 26138946.32338 +1173 1085 49815527.5467 +1174 1085 7638779.12366 +1175 1085 -72142989.75742 +1176 1085 5244680.501577 +1177 1085 6232693.774804 +1178 1085 -152469.232357 +1194 1085 9351972.443016 +1195 1085 15277558.23979 +1196 1085 -82572129.79111 +1197 1085 666986.1670292 +1198 1085 11701498.65463 +1199 1085 12831857.28995 +1086 1086 351205681.5641 +1087 1086 7.748603820801e-07 +1088 1086 2546228.295676 +1089 1086 32592087.44026 +1090 1086 6111111.110108 +1091 1086 5410862.629475 +1173 1086 -32955138.59878 +1174 1086 7638888.891398 +1175 1086 19567597.17295 +1176 1086 -59010186.71026 +1177 1086 1.542270183563e-06 +1178 1086 49433583.10251 +1179 1086 -10337951.09135 +1180 1086 -7638888.891398 +1181 1086 5244680.501577 +1194 1086 -33006170.85261 +1195 1086 -1527777.778278 +1196 1086 -4168152.723444 +1197 1086 10158551.82493 +1198 1086 -1.639127731323e-06 +1199 1086 -9988583.109361 +1200 1086 10509454.14025 +1201 1086 1527777.778278 +1202 1086 -1303569.389173 +1087 1087 314536784.4873 +1088 1087 61110295.08961 +1089 1087 -6111111.110107 +1090 1087 -25463372.91316 +1091 1087 -30860703.10031 +1173 1087 7638888.891398 +1174 1087 -30663321.90996 +1175 1087 -13871472.89847 +1176 1087 1.035630702972e-06 +1177 1087 -25398826.77179 +1178 1087 7638779.123661 +1179 1087 -7638888.891398 +1180 1087 -8046134.402525 +1181 1087 6232693.774803 +1194 1087 1527777.778281 +1195 1087 -47520034.13527 +1196 1087 -26979056.89458 +1197 1087 -1.132488250732e-06 +1198 1087 991285.0741574 +1199 1087 15277558.23979 +1200 1087 -1527777.77828 +1201 1087 -4004409.142409 +1202 1087 11701498.65478 +1088 1088 497902392.6657 +1089 1088 -6047470.701977 +1090 1088 -30249591.9893 +1091 1088 26138946.32338 +1173 1088 19567597.17295 +1174 1088 -13871472.89847 +1175 1088 -60464969.25217 +1176 1088 49815527.5467 +1177 1088 7638779.12366 +1178 1088 -72142989.75742 +1179 1088 5244680.501577 +1180 1088 6232693.774804 +1181 1088 -152469.232357 +1194 1088 3531569.501306 +1195 1088 -26979056.89443 +1196 1088 -103209809.3577 +1197 1088 9351972.443016 +1198 1088 15277558.23979 +1199 1088 -82572129.79111 +1200 1088 666986.1670292 +1201 1088 11701498.65463 +1202 1088 12831857.28995 +1089 1089 351205681.5641 +1090 1089 7.748603820801e-07 +1091 1089 2546228.295676 +1092 1089 32592087.44026 +1093 1089 6111111.110108 +1094 1089 5410862.629475 +1176 1089 -32955138.59878 +1177 1089 7638888.891398 +1178 1089 19567597.17295 +1179 1089 -59010186.71026 +1180 1089 1.542270183563e-06 +1181 1089 49433583.10251 +1182 1089 -10337951.09135 +1183 1089 -7638888.891398 +1184 1089 5244680.501577 +1197 1089 -33006170.85261 +1198 1089 -1527777.778278 +1199 1089 -4168152.723444 +1200 1089 10158551.82493 +1201 1089 -1.639127731323e-06 +1202 1089 -9988583.109361 +1203 1089 10509454.14025 +1204 1089 1527777.778278 +1205 1089 -1303569.389173 +1090 1090 314536784.4873 +1091 1090 61110295.08961 +1092 1090 -6111111.110107 +1093 1090 -25463372.91316 +1094 1090 -30860703.10031 +1176 1090 7638888.891398 +1177 1090 -30663321.90996 +1178 1090 -13871472.89847 +1179 1090 1.035630702972e-06 +1180 1090 -25398826.77179 +1181 1090 7638779.123661 +1182 1090 -7638888.891398 +1183 1090 -8046134.402525 +1184 1090 6232693.774803 +1197 1090 1527777.778281 +1198 1090 -47520034.13527 +1199 1090 -26979056.89458 +1200 1090 -1.132488250732e-06 +1201 1090 991285.0741574 +1202 1090 15277558.23979 +1203 1090 -1527777.77828 +1204 1090 -4004409.142409 +1205 1090 11701498.65478 +1091 1091 497902392.6657 +1092 1091 -6047470.701977 +1093 1091 -30249591.9893 +1094 1091 26138946.32338 +1176 1091 19567597.17295 +1177 1091 -13871472.89847 +1178 1091 -60464969.25217 +1179 1091 49815527.5467 +1180 1091 7638779.12366 +1181 1091 -72142989.75742 +1182 1091 5244680.501577 +1183 1091 6232693.774804 +1184 1091 -152469.232357 +1197 1091 3531569.501306 +1198 1091 -26979056.89443 +1199 1091 -103209809.3577 +1200 1091 9351972.443016 +1201 1091 15277558.23979 +1202 1091 -82572129.79111 +1203 1091 666986.1670292 +1204 1091 11701498.65463 +1205 1091 12831857.28995 +1092 1092 351205681.5641 +1093 1092 7.748603820801e-07 +1094 1092 2546228.295676 +1095 1092 32592087.44026 +1096 1092 6111111.110108 +1097 1092 5410862.629475 +1179 1092 -32955138.59878 +1180 1092 7638888.891398 +1181 1092 19567597.17295 +1182 1092 -59010186.71026 +1183 1092 1.542270183563e-06 +1184 1092 49433583.10251 +1185 1092 -10337951.09135 +1186 1092 -7638888.891398 +1187 1092 5244680.501577 +1200 1092 -33006170.85261 +1201 1092 -1527777.778278 +1202 1092 -4168152.723444 +1203 1092 10158551.82493 +1204 1092 -1.639127731323e-06 +1205 1092 -9988583.109361 +1206 1092 10509454.14025 +1207 1092 1527777.778278 +1208 1092 -1303569.389173 +1093 1093 314536784.4873 +1094 1093 61110295.08961 +1095 1093 -6111111.110107 +1096 1093 -25463372.91316 +1097 1093 -30860703.10031 +1179 1093 7638888.891398 +1180 1093 -30663321.90996 +1181 1093 -13871472.89847 +1182 1093 1.035630702972e-06 +1183 1093 -25398826.77179 +1184 1093 7638779.123661 +1185 1093 -7638888.891398 +1186 1093 -8046134.402525 +1187 1093 6232693.774803 +1200 1093 1527777.778281 +1201 1093 -47520034.13527 +1202 1093 -26979056.89458 +1203 1093 -1.132488250732e-06 +1204 1093 991285.0741574 +1205 1093 15277558.23979 +1206 1093 -1527777.77828 +1207 1093 -4004409.142409 +1208 1093 11701498.65478 +1094 1094 497902392.6657 +1095 1094 -6047470.701977 +1096 1094 -30249591.9893 +1097 1094 26138946.32338 +1179 1094 19567597.17295 +1180 1094 -13871472.89847 +1181 1094 -60464969.25217 +1182 1094 49815527.5467 +1183 1094 7638779.12366 +1184 1094 -72142989.75742 +1185 1094 5244680.501577 +1186 1094 6232693.774804 +1187 1094 -152469.232357 +1200 1094 3531569.501306 +1201 1094 -26979056.89443 +1202 1094 -103209809.3577 +1203 1094 9351972.443016 +1204 1094 15277558.23979 +1205 1094 -82572129.79111 +1206 1094 666986.1670292 +1207 1094 11701498.65463 +1208 1094 12831857.28995 +1095 1095 351205681.5641 +1096 1095 7.748603820801e-07 +1097 1095 2546228.295676 +1098 1095 32592087.44026 +1099 1095 6111111.110108 +1100 1095 5410862.629475 +1182 1095 -32955138.59878 +1183 1095 7638888.891398 +1184 1095 19567597.17295 +1185 1095 -59010186.71026 +1186 1095 1.542270183563e-06 +1187 1095 49433583.10251 +1188 1095 -10337951.09135 +1189 1095 -7638888.891398 +1190 1095 5244680.501577 +1203 1095 -33006170.85261 +1204 1095 -1527777.778278 +1205 1095 -4168152.723444 +1206 1095 10158551.82493 +1207 1095 -1.639127731323e-06 +1208 1095 -9988583.109361 +1209 1095 10509454.14025 +1210 1095 1527777.778278 +1211 1095 -1303569.389173 +1096 1096 314536784.4873 +1097 1096 61110295.08961 +1098 1096 -6111111.110107 +1099 1096 -25463372.91316 +1100 1096 -30860703.10031 +1182 1096 7638888.891398 +1183 1096 -30663321.90996 +1184 1096 -13871472.89847 +1185 1096 1.035630702972e-06 +1186 1096 -25398826.77179 +1187 1096 7638779.123661 +1188 1096 -7638888.891398 +1189 1096 -8046134.402525 +1190 1096 6232693.774803 +1203 1096 1527777.778281 +1204 1096 -47520034.13527 +1205 1096 -26979056.89458 +1206 1096 -1.132488250732e-06 +1207 1096 991285.0741574 +1208 1096 15277558.23979 +1209 1096 -1527777.77828 +1210 1096 -4004409.142409 +1211 1096 11701498.65478 +1097 1097 497902392.6657 +1098 1097 -6047470.701977 +1099 1097 -30249591.9893 +1100 1097 26138946.32338 +1182 1097 19567597.17295 +1183 1097 -13871472.89847 +1184 1097 -60464969.25217 +1185 1097 49815527.5467 +1186 1097 7638779.12366 +1187 1097 -72142989.75742 +1188 1097 5244680.501577 +1189 1097 6232693.774804 +1190 1097 -152469.232357 +1203 1097 3531569.501306 +1204 1097 -26979056.89443 +1205 1097 -103209809.3577 +1206 1097 9351972.443016 +1207 1097 15277558.23979 +1208 1097 -82572129.79111 +1209 1097 666986.1670292 +1210 1097 11701498.65463 +1211 1097 12831857.28995 +1098 1098 329940847.3278 +1099 1098 1456924.130812 +1100 1098 -19798695.49209 +1101 1098 24338728.1477 +1102 1098 -12830384.86409 +1103 1098 -864078.4856287 +1185 1098 -32955138.59878 +1186 1098 7638888.891398 +1187 1098 19567597.17295 +1188 1098 -49351204.34845 +1189 1098 4593894.893533 +1190 1098 42055901.74692 +1191 1098 -17990259.17954 +1192 1098 -7095495.010488 +1193 1098 11152125.05017 +1206 1098 -33006170.85261 +1207 1098 -1527777.778278 +1208 1098 -4168152.723444 +1209 1098 5365690.855964 +1210 1098 543513.6403558 +1211 1098 -15538450.00238 +1212 1098 -13153927.34598 +1213 1098 -4153024.636518 +1214 1098 5714867.644173 +1099 1099 306429729.3792 +1100 1099 37967868.48639 +1101 1099 -25052607.08431 +1102 1099 -33219707.43372 +1103 1099 -6855655.362866 +1185 1099 7638888.891398 +1186 1099 -30663321.90996 +1187 1099 -13871472.89847 +1188 1099 4593894.893532 +1189 1099 -24490638.59597 +1190 1099 -3129916.831349 +1191 1099 -7095495.010488 +1192 1099 -11593842.16527 +1193 1099 9735880.404272 +1206 1099 1527777.778281 +1207 1099 -47520034.13527 +1208 1099 -26979056.89458 +1209 1099 543513.6403558 +1210 1099 304716.0104512 +1211 1099 9614323.658581 +1212 1099 -7208580.193077 +1213 1099 -27127888.67338 +1214 1099 24630242.56153 +1100 1100 452213403.8995 +1101 1100 -3537689.596304 +1102 1100 -6550099.807361 +1103 1100 65800685.44065 +1185 1100 19567597.17295 +1186 1100 -13871472.89847 +1187 1100 -60464969.25217 +1188 1100 40146179.52533 +1189 1100 -3129916.830046 +1190 1100 -70774908.17847 +1191 1100 11152125.05017 +1192 1100 9735880.404273 +1193 1100 -17931982.82838 +1206 1100 3531569.501306 +1207 1100 -26979056.89443 +1208 1100 -103209809.3577 +1209 1100 3801549.994444 +1210 1100 9614323.658581 +1211 1100 -92723636.11364 +1212 1100 9976812.088386 +1213 1100 24630242.56008 +1214 1100 -31137386.18803 +1101 1101 356383026.0183 +1102 1101 22618374.71874 +1103 1101 6237540.301439 +1104 1101 -41476020.81817 +1105 1101 -35498351.69063 +1106 1101 -1071272.357701 +1107 1101 40984741.8607 +1108 1101 -4966591.38975 +1109 1101 1039334.186828 +1188 1101 -18882906.05781 +1189 1101 3871519.978604 +1190 1101 4133158.612019 +1191 1101 -54068831.66446 +1192 1101 6820581.445929 +1193 1101 47998113.16057 +1209 1101 -23405666.92726 +1210 1101 -7208580.193078 +1211 1101 -12349021.24194 +1212 1101 -35108767.53211 +1213 1101 7322809.363781 +1214 1101 -8657494.534025 +1215 1101 -31579805.97947 +1216 1101 -9072591.922057 +1217 1101 20035097.26683 +1218 1101 -25782266.15658 +1219 1101 -1733738.673178 +1220 1101 6374035.624927 +1102 1102 398814687.378 +1103 1102 12508809.5241 +1104 1102 -35498351.69063 +1105 1102 -26665980.79029 +1106 1102 -711679.625033 +1107 1102 -17188813.60996 +1108 1102 -18050410.97621 +1109 1102 -2239909.067908 +1188 1102 3871519.978604 +1189 1102 -34940266.73636 +1190 1102 -19048527.76298 +1191 1102 6820581.445929 +1192 1102 -27001678.44094 +1193 1102 -5557278.965151 +1209 1102 -4153024.636519 +1210 1102 -37379628.25466 +1211 1102 -28043368.541 +1212 1102 7322809.363781 +1213 1102 -21246056.35551 +1214 1102 3425746.803933 +1215 1102 -9072591.922058 +1216 1102 -27661472.41918 +1217 1102 16480334.95681 +1218 1102 -4789294.229737 +1219 1102 -40599142.11104 +1220 1102 32743093.50838 +1103 1103 579837473.3427 +1104 1103 -1071272.357701 +1105 1103 -711679.6250329 +1106 1103 42147940.75612 +1107 1103 -106499.146321 +1108 1103 -2239909.067908 +1109 1103 113215706.9648 +1188 1103 4133158.612019 +1189 1103 -19048527.76298 +1190 1103 -34700848.35564 +1191 1103 47998113.16019 +1192 1103 -5557278.963848 +1193 1103 -113612841.9415 +1209 1103 -6941243.464199 +1210 1103 -28043368.5423 +1211 1103 -58475358.40478 +1212 1103 10265838.7962 +1213 1103 3425746.803932 +1214 1103 -187302696.7748 +1215 1103 20035097.26683 +1216 1103 16480334.95681 +1217 1103 -44352992.38482 +1218 1103 10809868.96153 +1219 1103 32743093.50838 +1220 1103 -65097246.98569 +1104 1104 234347158.4154 +1105 1104 39249037.60132 +1106 1104 613775.4689543 +1107 1104 8275717.835673 +1108 1104 -1168314.970011 +1109 1104 625670.506485 +1191 1104 -29376911.3921 +1192 1104 -945517.8900799 +1193 1104 -4684202.140556 +1212 1104 -32829805.9799 +1213 1104 -9072591.922058 +1214 1104 -20589902.74651 +1215 1104 -36371421.91044 +1216 1104 10112184.55976 +1217 1104 8285359.548615 +1218 1104 -39320042.52865 +1219 1104 -94074.74761934 +1220 1104 -31761254.66155 +1105 1105 219116637.1178 +1106 1105 606809.4308238 +1107 1105 11053907.2502 +1108 1105 67944844.46223 +1109 1105 711679.6250347 +1191 1105 -4001073.446639 +1192 1105 -44142980.14633 +1193 1105 -33488420.36932 +1212 1105 -9072591.922058 +1213 1105 -28911472.41961 +1214 1105 -16852998.38747 +1215 1105 10112184.55976 +1216 1105 -40225144.82899 +1217 1105 6821753.707027 +1218 1105 2961480.80894 +1219 1105 -24618584.41616 +1220 1105 3519665.049753 +1106 1106 395677068.9393 +1107 1106 243726.0621074 +1108 1106 711679.6250346 +1109 1106 142408195.6901 +1191 1106 -12809202.1416 +1192 1106 -33488420.36932 +1193 1106 -88494288.4354 +1212 1106 -20589902.74651 +1213 1106 -16852998.38747 +1214 1106 -47686325.71928 +1215 1106 -7964640.448716 +1216 1106 -6511579.624115 +1217 1106 -155107169.8382 +1218 1106 -31761254.66318 +1219 1106 -3147001.619103 +1220 1106 -76440700.83665 +1107 1107 184012379.3245 +1108 1107 -19477853.05068 +1109 1107 3034739.887406 +1191 1107 -20003093.01273 +1192 1107 6205185.860737 +1193 1107 11767041.70857 +1212 1107 -29532266.15537 +1213 1107 -4789294.229737 +1214 1107 -11307908.81661 +1215 1107 -39320042.52865 +1216 1107 2961480.80894 +1217 1107 31997773.10585 +1218 1107 -27395507.40129 +1219 1107 -4377372.43994 +1220 1107 -4314128.22028 +1108 1108 197133990.5023 +1109 1108 2239909.067913 +1191 1108 6205185.860737 +1192 1108 -24101455.05692 +1193 1108 -16852998.38747 +1212 1108 -1733738.673178 +1213 1108 -44349142.10983 +1214 1108 -33923573.14734 +1215 1108 -94074.74761849 +1216 1108 -24618584.41616 +1217 1108 3519665.049753 +1218 1108 -4377372.43994 +1219 1108 -23181727.51512 +1220 1108 7256906.485048 +1109 1109 318426963.4457 +1191 1109 11767041.70857 +1192 1109 -16852998.38747 +1193 1109 -42876308.35659 +1212 1109 -6490131.035622 +1213 1109 -33923573.14734 +1214 1109 -75097246.98247 +1215 1109 31997773.10404 +1216 1109 -3147001.619103 +1217 1109 -76440700.83665 +1218 1109 4939482.889311 +1219 1109 -6076426.846095 +1220 1109 -115588168.0857 +1110 1110 442585385.072 +1111 1110 30555555.55053 +1112 1110 -29342262.45851 +1113 1110 -140989212.5199 +1114 1110 -30581017.46395 +1115 1110 29317331.52637 +1116 1110 -7397842.697824 +1117 1110 24469906.35385 +1118 1110 23704691.59905 +1221 1110 18346673.71113 +1222 1110 7638888.891398 +1223 1110 1385379.035684 +1224 1110 -55802716.54489 +1225 1110 -7645254.369757 +1226 1110 -40856339.07483 +1227 1110 6123446.608564 +1228 1110 6117476.591476 +1229 1110 -3944940.585509 +1111 1111 396720404.8065 +1112 1111 76436047.94083 +1113 1111 -30593748.42066 +1114 1111 2703063.542514 +1115 1111 42347550.95634 +1116 1111 36704859.53077 +1117 1111 -7397842.697831 +1118 1111 -26611659.38366 +1221 1111 7638888.891397 +1222 1111 6880428.6391 +1223 1111 26085656.47845 +1224 1111 -7648437.108936 +1225 1111 -19879647.51159 +1226 1111 942630.1669732 +1227 1111 9176214.887214 +1228 1111 6123446.608565 +1229 1111 4734398.284357 +1112 1112 631577008.7377 +1113 1112 29304866.06029 +1114 1112 34088108.93947 +1115 1112 74852155.60434 +1116 1112 35557037.39857 +1117 1112 -17741106.25578 +1118 1112 -19727580.52753 +1221 1112 -17965238.89317 +1222 1112 10605384.60401 +1223 1112 -88238208.0348 +1224 1112 -41241201.16555 +1225 1112 -1194514.850572 +1226 1112 -36101396.81649 +1227 1112 -5917410.878264 +1228 1112 3156265.522905 +1229 1112 16329190.95617 +1113 1113 692250148.1146 +1114 1113 30619210.33408 +1115 1113 -34372600.90029 +1116 1113 16585727.58665 +1117 1113 -30581017.46396 +1118 1113 -29752163.59795 +1119 1113 -77421519.48389 +1120 1113 -5.513429641724e-07 +1121 1113 5092665.772129 +1122 1113 -48621476.67428 +1123 1113 30555555.55054 +1124 1113 29728027.55019 +1221 1113 -79032837.45136 +1222 1113 -7648437.10893 +1223 1113 55511888.47871 +1224 1113 34928101.59242 +1225 1113 7654802.58729 +1226 1113 -8598678.217522 +1227 1113 5149787.278365 +1228 1113 -7645254.369755 +1229 1113 4611926.752539 +1230 1113 -53208020.04453 +1231 1113 -1.534819602966e-06 +1232 1113 -46887250.21518 +1233 1113 -9746784.424485 +1234 1113 7638888.891396 +1235 1113 -4608097.279433 +1114 1114 609716100.864 +1115 1114 94722882.73185 +1116 1114 -30593748.42066 +1117 1114 -90408834.961 +1118 1114 -50742009.05798 +1119 1114 -7.450580596924e-07 +1120 1114 57023920.20371 +1121 1114 30555116.4796 +1122 1114 30555555.55054 +1123 1114 -39454209.9235 +1124 1114 -16652558.23965 +1221 1114 -7645254.369751 +1222 1114 -43109768.41806 +1223 1114 18161862.49682 +1224 1114 7654802.587289 +1225 1114 14294589.76961 +1226 1114 23676298.37333 +1227 1114 -7648437.108933 +1228 1114 -21598853.37172 +1229 1114 25862479.31684 +1230 1114 -1.318752765656e-06 +1231 1114 -19596660.10607 +1232 1114 7638779.123661 +1233 1114 7638888.891396 +1234 1114 -7454967.735663 +1235 1114 5468804.885664 +1115 1115 858703305.1038 +1116 1115 -30146176.06602 +1117 1115 -59306688.68559 +1118 1115 32394301.37033 +1119 1115 5092665.772129 +1120 1115 30555116.4796 +1121 1115 134412647.088 +1122 1115 30109971.99439 +1123 1115 -16958113.795 +1124 1115 -19995669.80713 +1221 1115 55896750.56943 +1222 1115 20307057.29599 +1223 1115 -98048385.90041 +1224 1115 -8588615.841047 +1225 1115 23684348.15878 +1226 1115 -153682668.3423 +1227 1115 4613841.489092 +1228 1115 24026705.92618 +1229 1115 10774189.69233 +1230 1115 -47269194.65938 +1231 1115 7638779.123661 +1232 1115 -56670545.31551 +1233 1115 -4608097.279433 +1234 1115 5468804.885664 +1235 1115 1423975.212606 +1116 1116 442585385.072 +1117 1116 30555555.55053 +1118 1116 -29342262.45851 +1119 1116 -45183976.67484 +1120 1116 -30555555.55054 +1121 1116 -27563639.10707 +1122 1116 -140989212.5199 +1123 1116 -30581017.46395 +1124 1116 29317331.52637 +1125 1116 -7397842.697824 +1126 1116 24469906.35385 +1127 1116 23704691.59905 +1221 1116 -37437760.48235 +1222 1116 9176214.887214 +1223 1116 23123609.08966 +1224 1116 -61598018.00238 +1225 1116 -7648437.108935 +1226 1116 -19592039.58835 +1227 1116 18346673.71113 +1228 1116 7638888.891398 +1229 1116 1385379.035684 +1230 1116 -30645221.93135 +1231 1116 -7638888.891397 +1232 1116 -18931013.9508 +1233 1116 -55802716.54489 +1234 1116 -7645254.369757 +1235 1116 -40856339.07483 +1236 1116 6123446.608564 +1237 1116 6117476.591476 +1238 1116 -3944940.585509 +1117 1117 396720404.8065 +1118 1117 76436047.94083 +1119 1117 -30555555.55054 +1120 1117 -36016709.92406 +1121 1117 -13902558.23995 +1122 1117 -30593748.42066 +1123 1117 2703063.542514 +1124 1117 42347550.95634 +1125 1117 36704859.53077 +1126 1117 -7397842.697831 +1127 1117 -26611659.38366 +1221 1117 6117476.591476 +1222 1117 -37437760.48236 +1223 1117 -12332056.26767 +1224 1117 -7645254.369756 +1225 1117 -88346658.65246 +1226 1117 -53374653.70739 +1227 1117 7638888.891397 +1228 1117 6880428.6391 +1229 1117 26085656.47845 +1230 1117 -7638888.891397 +1231 1117 -28353405.24253 +1232 1117 -13107584.00933 +1233 1117 -7648437.108936 +1234 1117 -19879647.51159 +1235 1117 942630.1669732 +1236 1117 9176214.887214 +1237 1117 6123446.608565 +1238 1117 4734398.284357 +1118 1118 631577008.7377 +1119 1118 -27181694.66288 +1120 1118 -13597002.68459 +1121 1118 -10829003.14197 +1122 1118 29304866.06029 +1123 1118 34088108.93947 +1124 1118 74852155.60434 +1125 1118 35557037.39857 +1126 1118 -17741106.25578 +1127 1118 -19727580.52753 +1221 1118 15415739.3931 +1222 1118 -18498084.4015 +1223 1118 -99834027.95294 +1224 1118 -19583892.11655 +1225 1118 -51538880.44741 +1226 1118 -167219957.723 +1227 1118 -17965238.89317 +1228 1118 10605384.60401 +1229 1118 -88238208.0348 +1230 1118 -18931013.9508 +1231 1118 -13107584.00933 +1232 1118 -54305191.47237 +1233 1118 -41241201.16555 +1234 1118 -1194514.850572 +1235 1118 -36101396.81649 +1236 1118 -5917410.878264 +1237 1118 3156265.522905 +1238 1118 16329190.95617 +1119 1119 669327989.9306 +1120 1119 -1.430511474609e-06 +1121 1119 -10185331.54429 +1122 1119 57028027.11004 +1123 1119 9.089708328247e-07 +1124 1119 -2546332.887327 +1128 1119 -77421519.48389 +1129 1119 -5.513429641724e-07 +1130 1119 5092665.772129 +1131 1119 -48621476.67428 +1132 1119 30555555.55054 +1133 1119 29728027.55019 +1224 1119 -59010186.71026 +1225 1119 1.542270183563e-06 +1226 1119 49433583.10251 +1227 1119 -10337951.09135 +1228 1119 -7638888.891398 +1229 1119 5244680.501577 +1230 1119 20431686.98312 +1231 1119 -9.238719940186e-07 +1232 1119 -2546332.887312 +1233 1119 21018908.28051 +1234 1119 -2.346932888031e-06 +1235 1119 -636583.222144 +1239 1119 -53208020.04453 +1240 1119 -1.534819602966e-06 +1241 1119 -46887250.21518 +1242 1119 -9746784.424485 +1243 1119 7638888.891396 +1244 1119 -4608097.279433 +1120 1120 595989855.9605 +1121 1120 122220465.8582 +1122 1120 1.132488250732e-06 +1123 1120 -59082879.09408 +1124 1120 -61110232.92908 +1128 1120 -7.450580596924e-07 +1129 1120 57023920.20371 +1130 1120 30555116.4796 +1131 1120 30555555.55054 +1132 1120 -39454209.9235 +1133 1120 -16652558.23965 +1224 1120 1.035630702972e-06 +1225 1120 -25398826.77179 +1226 1120 7638779.123661 +1227 1120 -7638888.891398 +1228 1120 -8046134.402525 +1229 1120 6232693.774803 +1230 1120 -9.536743164063e-07 +1231 1120 2097153.481574 +1232 1120 30555116.47959 +1233 1120 -2.235174179077e-06 +1234 1120 -8008818.28482 +1235 1120 23250219.53173 +1239 1120 -1.318752765656e-06 +1240 1120 -19596660.10607 +1241 1120 7638779.123661 +1242 1120 7638888.891396 +1243 1120 -7454967.735663 +1244 1120 5468804.885664 +1121 1121 907581829.653 +1122 1121 -2546332.887327 +1123 1121 -61110232.92908 +1124 1121 30527909.01414 +1128 1121 5092665.772129 +1129 1121 30555116.4796 +1130 1121 134412647.088 +1131 1121 30109971.99439 +1132 1121 -16958113.795 +1133 1121 -19995669.80713 +1224 1121 49815527.5467 +1225 1121 7638779.12366 +1226 1121 -72142989.75742 +1227 1121 5244680.501577 +1228 1121 6232693.774804 +1229 1121 -152469.232357 +1230 1121 -2546332.887312 +1231 1121 30555116.47959 +1232 1121 -164838704.0269 +1233 1121 -636583.2221438 +1234 1121 23555775.08708 +1235 1121 25663714.57989 +1239 1121 -47269194.65938 +1240 1121 7638779.123661 +1241 1121 -56670545.31551 +1242 1121 -4608097.279433 +1243 1121 5468804.885664 +1244 1121 1423975.212606 +1122 1122 692250148.1146 +1123 1122 30619210.33408 +1124 1122 -34372600.90029 +1125 1122 16585727.58665 +1126 1122 -30581017.46396 +1127 1122 -29752163.59795 +1128 1122 -45183976.67484 +1129 1122 -30555555.55054 +1130 1122 -27563639.10707 +1131 1122 -77421519.48389 +1132 1122 -5.513429641724e-07 +1133 1122 5092665.772129 +1134 1122 -48621476.67428 +1135 1122 30555555.55054 +1136 1122 29728027.55019 +1224 1122 -32955138.59878 +1225 1122 7638888.891398 +1226 1122 19567597.17295 +1227 1122 -79032837.45136 +1228 1122 -7648437.10893 +1229 1122 55511888.47871 +1230 1122 -66012341.70521 +1231 1122 2.853572368622e-06 +1232 1122 -636583.2221378 +1233 1122 34928101.59242 +1234 1122 7654802.58729 +1235 1122 -8598678.217522 +1236 1122 5149787.278365 +1237 1122 -7645254.369755 +1238 1122 4611926.752539 +1239 1122 -30645221.93135 +1240 1122 -7638888.891397 +1241 1122 -18931013.9508 +1242 1122 -53208020.04453 +1243 1122 -1.534819602966e-06 +1244 1122 -46887250.21518 +1245 1122 -9746784.424485 +1246 1122 7638888.891396 +1247 1122 -4608097.279433 +1123 1123 609716100.864 +1124 1123 94722882.73185 +1125 1123 -30593748.42066 +1126 1123 -90408834.961 +1127 1123 -50742009.05798 +1128 1123 -30555555.55054 +1129 1123 -36016709.92406 +1130 1123 -13902558.23995 +1131 1123 -7.450580596924e-07 +1132 1123 57023920.20371 +1133 1123 30555116.4796 +1134 1123 30555555.55054 +1135 1123 -39454209.9235 +1136 1123 -16652558.23965 +1224 1123 7638888.891398 +1225 1123 -30663321.90996 +1226 1123 -13871472.89847 +1227 1123 -7645254.369751 +1228 1123 -43109768.41806 +1229 1123 18161862.49682 +1230 1123 2.995133399963e-06 +1231 1123 -95040068.27054 +1232 1123 -53805336.01132 +1233 1123 7654802.587289 +1234 1123 14294589.76961 +1235 1123 23676298.37333 +1236 1123 -7648437.108933 +1237 1123 -21598853.37172 +1238 1123 25862479.31684 +1239 1123 -7638888.891397 +1240 1123 -28353405.24253 +1241 1123 -13107584.00933 +1242 1123 -1.318752765656e-06 +1243 1123 -19596660.10607 +1244 1123 7638779.123661 +1245 1123 7638888.891396 +1246 1123 -7454967.735663 +1247 1123 5468804.885664 +1124 1124 858703305.1038 +1125 1124 -30146176.06602 +1126 1124 -59306688.68559 +1127 1124 32394301.37033 +1128 1124 -27181694.66288 +1129 1124 -13597002.68459 +1130 1124 -10829003.14197 +1131 1124 5092665.772129 +1132 1124 30555116.4796 +1133 1124 134412647.088 +1134 1124 30109971.99439 +1135 1124 -16958113.795 +1136 1124 -19995669.80713 +1224 1124 19567597.17295 +1225 1124 -13871472.89847 +1226 1124 -60464969.25217 +1227 1124 55896750.56943 +1228 1124 20307057.29599 +1229 1124 -98048385.90041 +1230 1124 -636583.2221379 +1231 1124 -54110891.56668 +1232 1124 -206419618.7154 +1233 1124 -8588615.841047 +1234 1124 23684348.15878 +1235 1124 -153682668.3423 +1236 1124 4613841.489092 +1237 1124 24026705.92618 +1238 1124 10774189.69233 +1239 1124 -18931013.9508 +1240 1124 -13107584.00933 +1241 1124 -54305191.47237 +1242 1124 -47269194.65938 +1243 1124 7638779.123661 +1244 1124 -56670545.31551 +1245 1124 -4608097.279433 +1246 1124 5468804.885664 +1247 1124 1423975.212606 +1125 1125 442585385.072 +1126 1125 30555555.55053 +1127 1125 -29342262.45851 +1131 1125 -45183976.67484 +1132 1125 -30555555.55054 +1133 1125 -27563639.10707 +1134 1125 -140989212.5199 +1135 1125 -30581017.46395 +1136 1125 29317331.52637 +1137 1125 -7397842.697824 +1138 1125 24469906.35385 +1139 1125 23704691.59905 +1227 1125 -37437760.48235 +1228 1125 9176214.887214 +1229 1125 23123609.08966 +1233 1125 -61598018.00238 +1234 1125 -7648437.108935 +1235 1125 -19592039.58835 +1236 1125 18346673.71113 +1237 1125 7638888.891398 +1238 1125 1385379.035684 +1242 1125 -30645221.93135 +1243 1125 -7638888.891397 +1244 1125 -18931013.9508 +1245 1125 -55802716.54489 +1246 1125 -7645254.369757 +1247 1125 -40856339.07483 +1248 1125 6123446.608564 +1249 1125 6117476.591476 +1250 1125 -3944940.585509 +1126 1126 396720404.8065 +1127 1126 76436047.94083 +1131 1126 -30555555.55054 +1132 1126 -36016709.92406 +1133 1126 -13902558.23995 +1134 1126 -30593748.42066 +1135 1126 2703063.542514 +1136 1126 42347550.95634 +1137 1126 36704859.53077 +1138 1126 -7397842.697831 +1139 1126 -26611659.38366 +1227 1126 6117476.591476 +1228 1126 -37437760.48236 +1229 1126 -12332056.26767 +1233 1126 -7645254.369756 +1234 1126 -88346658.65246 +1235 1126 -53374653.70739 +1236 1126 7638888.891397 +1237 1126 6880428.6391 +1238 1126 26085656.47845 +1242 1126 -7638888.891397 +1243 1126 -28353405.24253 +1244 1126 -13107584.00933 +1245 1126 -7648437.108936 +1246 1126 -19879647.51159 +1247 1126 942630.1669732 +1248 1126 9176214.887214 +1249 1126 6123446.608565 +1250 1126 4734398.284357 +1127 1127 631577008.7377 +1131 1127 -27181694.66288 +1132 1127 -13597002.68459 +1133 1127 -10829003.14197 +1134 1127 29304866.06029 +1135 1127 34088108.93947 +1136 1127 74852155.60434 +1137 1127 35557037.39857 +1138 1127 -17741106.25578 +1139 1127 -19727580.52753 +1227 1127 15415739.3931 +1228 1127 -18498084.4015 +1229 1127 -99834027.95294 +1233 1127 -19583892.11655 +1234 1127 -51538880.44741 +1235 1127 -167219957.723 +1236 1127 -17965238.89317 +1237 1127 10605384.60401 +1238 1127 -88238208.0348 +1242 1127 -18931013.9508 +1243 1127 -13107584.00933 +1244 1127 -54305191.47237 +1245 1127 -41241201.16555 +1246 1127 -1194514.850572 +1247 1127 -36101396.81649 +1248 1127 -5917410.878264 +1249 1127 3156265.522905 +1250 1127 16329190.95617 +1128 1128 669327989.9306 +1129 1128 -1.430511474609e-06 +1130 1128 -10185331.54429 +1131 1128 57028027.11004 +1132 1128 9.089708328247e-07 +1133 1128 -2546332.887327 +1140 1128 -77421519.48389 +1141 1128 -5.513429641724e-07 +1142 1128 5092665.772129 +1143 1128 -48621476.67428 +1144 1128 30555555.55054 +1145 1128 29728027.55019 +1230 1128 -59010186.71026 +1231 1128 1.542270183563e-06 +1232 1128 49433583.10251 +1233 1128 -10337951.09135 +1234 1128 -7638888.891398 +1235 1128 5244680.501577 +1239 1128 20431686.98312 +1240 1128 -9.238719940186e-07 +1241 1128 -2546332.887312 +1242 1128 21018908.28051 +1243 1128 -2.346932888031e-06 +1244 1128 -636583.222144 +1251 1128 -53208020.04453 +1252 1128 -1.534819602966e-06 +1253 1128 -46887250.21518 +1254 1128 -9746784.424485 +1255 1128 7638888.891396 +1256 1128 -4608097.279433 +1129 1129 595989855.9605 +1130 1129 122220465.8582 +1131 1129 1.132488250732e-06 +1132 1129 -59082879.09408 +1133 1129 -61110232.92908 +1140 1129 -7.450580596924e-07 +1141 1129 57023920.20371 +1142 1129 30555116.4796 +1143 1129 30555555.55054 +1144 1129 -39454209.9235 +1145 1129 -16652558.23965 +1230 1129 1.035630702972e-06 +1231 1129 -25398826.77179 +1232 1129 7638779.123661 +1233 1129 -7638888.891398 +1234 1129 -8046134.402525 +1235 1129 6232693.774803 +1239 1129 -9.536743164063e-07 +1240 1129 2097153.481574 +1241 1129 30555116.47959 +1242 1129 -2.235174179077e-06 +1243 1129 -8008818.28482 +1244 1129 23250219.53173 +1251 1129 -1.318752765656e-06 +1252 1129 -19596660.10607 +1253 1129 7638779.123661 +1254 1129 7638888.891396 +1255 1129 -7454967.735663 +1256 1129 5468804.885664 +1130 1130 907581829.653 +1131 1130 -2546332.887327 +1132 1130 -61110232.92908 +1133 1130 30527909.01414 +1140 1130 5092665.772129 +1141 1130 30555116.4796 +1142 1130 134412647.088 +1143 1130 30109971.99439 +1144 1130 -16958113.795 +1145 1130 -19995669.80713 +1230 1130 49815527.5467 +1231 1130 7638779.12366 +1232 1130 -72142989.75742 +1233 1130 5244680.501577 +1234 1130 6232693.774804 +1235 1130 -152469.232357 +1239 1130 -2546332.887312 +1240 1130 30555116.47959 +1241 1130 -164838704.0269 +1242 1130 -636583.2221438 +1243 1130 23555775.08708 +1244 1130 25663714.57989 +1251 1130 -47269194.65938 +1252 1130 7638779.123661 +1253 1130 -56670545.31551 +1254 1130 -4608097.279433 +1255 1130 5468804.885664 +1256 1130 1423975.212606 +1131 1131 669327989.9306 +1132 1131 -1.430511474609e-06 +1133 1131 -10185331.54429 +1134 1131 57028027.11004 +1135 1131 9.089708328247e-07 +1136 1131 -2546332.887327 +1140 1131 -45183976.67484 +1141 1131 -30555555.55054 +1142 1131 -27563639.10707 +1143 1131 -77421519.48389 +1144 1131 -5.513429641724e-07 +1145 1131 5092665.772129 +1146 1131 -48621476.67428 +1147 1131 30555555.55054 +1148 1131 29728027.55019 +1230 1131 -32955138.59878 +1231 1131 7638888.891398 +1232 1131 19567597.17295 +1233 1131 -59010186.71026 +1234 1131 1.542270183563e-06 +1235 1131 49433583.10251 +1236 1131 -10337951.09135 +1237 1131 -7638888.891398 +1238 1131 5244680.501577 +1239 1131 -66012341.70521 +1240 1131 2.853572368622e-06 +1241 1131 -636583.2221378 +1242 1131 20431686.98312 +1243 1131 -9.238719940186e-07 +1244 1131 -2546332.887312 +1245 1131 21018908.28051 +1246 1131 -2.346932888031e-06 +1247 1131 -636583.222144 +1251 1131 -30645221.93135 +1252 1131 -7638888.891397 +1253 1131 -18931013.9508 +1254 1131 -53208020.04453 +1255 1131 -1.534819602966e-06 +1256 1131 -46887250.21518 +1257 1131 -9746784.424485 +1258 1131 7638888.891396 +1259 1131 -4608097.279433 +1132 1132 595989855.9605 +1133 1132 122220465.8582 +1134 1132 1.132488250732e-06 +1135 1132 -59082879.09408 +1136 1132 -61110232.92908 +1140 1132 -30555555.55054 +1141 1132 -36016709.92406 +1142 1132 -13902558.23995 +1143 1132 -7.450580596924e-07 +1144 1132 57023920.20371 +1145 1132 30555116.4796 +1146 1132 30555555.55054 +1147 1132 -39454209.9235 +1148 1132 -16652558.23965 +1230 1132 7638888.891398 +1231 1132 -30663321.90996 +1232 1132 -13871472.89847 +1233 1132 1.035630702972e-06 +1234 1132 -25398826.77179 +1235 1132 7638779.123661 +1236 1132 -7638888.891398 +1237 1132 -8046134.402525 +1238 1132 6232693.774803 +1239 1132 2.995133399963e-06 +1240 1132 -95040068.27054 +1241 1132 -53805336.01132 +1242 1132 -9.536743164063e-07 +1243 1132 2097153.481574 +1244 1132 30555116.47959 +1245 1132 -2.235174179077e-06 +1246 1132 -8008818.28482 +1247 1132 23250219.53173 +1251 1132 -7638888.891397 +1252 1132 -28353405.24253 +1253 1132 -13107584.00933 +1254 1132 -1.318752765656e-06 +1255 1132 -19596660.10607 +1256 1132 7638779.123661 +1257 1132 7638888.891396 +1258 1132 -7454967.735663 +1259 1132 5468804.885664 +1133 1133 907581829.653 +1134 1133 -2546332.887327 +1135 1133 -61110232.92908 +1136 1133 30527909.01414 +1140 1133 -27181694.66288 +1141 1133 -13597002.68459 +1142 1133 -10829003.14197 +1143 1133 5092665.772129 +1144 1133 30555116.4796 +1145 1133 134412647.088 +1146 1133 30109971.99439 +1147 1133 -16958113.795 +1148 1133 -19995669.80713 +1230 1133 19567597.17295 +1231 1133 -13871472.89847 +1232 1133 -60464969.25217 +1233 1133 49815527.5467 +1234 1133 7638779.12366 +1235 1133 -72142989.75742 +1236 1133 5244680.501577 +1237 1133 6232693.774804 +1238 1133 -152469.232357 +1239 1133 -636583.2221379 +1240 1133 -54110891.56668 +1241 1133 -206419618.7154 +1242 1133 -2546332.887312 +1243 1133 30555116.47959 +1244 1133 -164838704.0269 +1245 1133 -636583.2221438 +1246 1133 23555775.08708 +1247 1133 25663714.57989 +1251 1133 -18931013.9508 +1252 1133 -13107584.00933 +1253 1133 -54305191.47237 +1254 1133 -47269194.65938 +1255 1133 7638779.123661 +1256 1133 -56670545.31551 +1257 1133 -4608097.279433 +1258 1133 5468804.885664 +1259 1133 1423975.212606 +1134 1134 692250148.1146 +1135 1134 30619210.33408 +1136 1134 -34372600.90029 +1137 1134 16585727.58665 +1138 1134 -30581017.46396 +1139 1134 -29752163.59795 +1143 1134 -45183976.67484 +1144 1134 -30555555.55054 +1145 1134 -27563639.10707 +1146 1134 -77421519.48389 +1147 1134 -5.513429641724e-07 +1148 1134 5092665.772129 +1149 1134 -48621476.67428 +1150 1134 30555555.55054 +1151 1134 29728027.55019 +1233 1134 -32955138.59878 +1234 1134 7638888.891398 +1235 1134 19567597.17295 +1236 1134 -79032837.45136 +1237 1134 -7648437.10893 +1238 1134 55511888.47871 +1242 1134 -66012341.70521 +1243 1134 2.853572368622e-06 +1244 1134 -636583.2221378 +1245 1134 34928101.59242 +1246 1134 7654802.58729 +1247 1134 -8598678.217522 +1248 1134 5149787.278365 +1249 1134 -7645254.369755 +1250 1134 4611926.752539 +1254 1134 -30645221.93135 +1255 1134 -7638888.891397 +1256 1134 -18931013.9508 +1257 1134 -53208020.04453 +1258 1134 -1.534819602966e-06 +1259 1134 -46887250.21518 +1260 1134 -9746784.424485 +1261 1134 7638888.891396 +1262 1134 -4608097.279433 +1135 1135 609716100.864 +1136 1135 94722882.73185 +1137 1135 -30593748.42066 +1138 1135 -90408834.961 +1139 1135 -50742009.05798 +1143 1135 -30555555.55054 +1144 1135 -36016709.92406 +1145 1135 -13902558.23995 +1146 1135 -7.450580596924e-07 +1147 1135 57023920.20371 +1148 1135 30555116.4796 +1149 1135 30555555.55054 +1150 1135 -39454209.9235 +1151 1135 -16652558.23965 +1233 1135 7638888.891398 +1234 1135 -30663321.90996 +1235 1135 -13871472.89847 +1236 1135 -7645254.369751 +1237 1135 -43109768.41806 +1238 1135 18161862.49682 +1242 1135 2.995133399963e-06 +1243 1135 -95040068.27054 +1244 1135 -53805336.01132 +1245 1135 7654802.587289 +1246 1135 14294589.76961 +1247 1135 23676298.37333 +1248 1135 -7648437.108933 +1249 1135 -21598853.37172 +1250 1135 25862479.31684 +1254 1135 -7638888.891397 +1255 1135 -28353405.24253 +1256 1135 -13107584.00933 +1257 1135 -1.318752765656e-06 +1258 1135 -19596660.10607 +1259 1135 7638779.123661 +1260 1135 7638888.891396 +1261 1135 -7454967.735663 +1262 1135 5468804.885664 +1136 1136 858703305.1038 +1137 1136 -30146176.06602 +1138 1136 -59306688.68559 +1139 1136 32394301.37033 +1143 1136 -27181694.66288 +1144 1136 -13597002.68459 +1145 1136 -10829003.14197 +1146 1136 5092665.772129 +1147 1136 30555116.4796 +1148 1136 134412647.088 +1149 1136 30109971.99439 +1150 1136 -16958113.795 +1151 1136 -19995669.80713 +1233 1136 19567597.17295 +1234 1136 -13871472.89847 +1235 1136 -60464969.25217 +1236 1136 55896750.56943 +1237 1136 20307057.29599 +1238 1136 -98048385.90041 +1242 1136 -636583.2221379 +1243 1136 -54110891.56668 +1244 1136 -206419618.7154 +1245 1136 -8588615.841047 +1246 1136 23684348.15878 +1247 1136 -153682668.3423 +1248 1136 4613841.489092 +1249 1136 24026705.92618 +1250 1136 10774189.69233 +1254 1136 -18931013.9508 +1255 1136 -13107584.00933 +1256 1136 -54305191.47237 +1257 1136 -47269194.65938 +1258 1136 7638779.123661 +1259 1136 -56670545.31551 +1260 1136 -4608097.279433 +1261 1136 5468804.885664 +1262 1136 1423975.212606 +1137 1137 442585385.072 +1138 1137 30555555.55053 +1139 1137 -29342262.45851 +1146 1137 -45183976.67484 +1147 1137 -30555555.55054 +1148 1137 -27563639.10707 +1149 1137 -140989212.5199 +1150 1137 -30581017.46395 +1151 1137 29317331.52637 +1152 1137 -7397842.697824 +1153 1137 24469906.35385 +1154 1137 23704691.59905 +1236 1137 -37437760.48235 +1237 1137 9176214.887214 +1238 1137 23123609.08966 +1245 1137 -61598018.00238 +1246 1137 -7648437.108935 +1247 1137 -19592039.58835 +1248 1137 18346673.71113 +1249 1137 7638888.891398 +1250 1137 1385379.035684 +1257 1137 -30645221.93135 +1258 1137 -7638888.891397 +1259 1137 -18931013.9508 +1260 1137 -55802716.54489 +1261 1137 -7645254.369757 +1262 1137 -40856339.07483 +1263 1137 6123446.608564 +1264 1137 6117476.591476 +1265 1137 -3944940.585509 +1138 1138 396720404.8065 +1139 1138 76436047.94083 +1146 1138 -30555555.55054 +1147 1138 -36016709.92406 +1148 1138 -13902558.23995 +1149 1138 -30593748.42066 +1150 1138 2703063.542514 +1151 1138 42347550.95634 +1152 1138 36704859.53077 +1153 1138 -7397842.697831 +1154 1138 -26611659.38366 +1236 1138 6117476.591476 +1237 1138 -37437760.48236 +1238 1138 -12332056.26767 +1245 1138 -7645254.369756 +1246 1138 -88346658.65246 +1247 1138 -53374653.70739 +1248 1138 7638888.891397 +1249 1138 6880428.6391 +1250 1138 26085656.47845 +1257 1138 -7638888.891397 +1258 1138 -28353405.24253 +1259 1138 -13107584.00933 +1260 1138 -7648437.108936 +1261 1138 -19879647.51159 +1262 1138 942630.1669732 +1263 1138 9176214.887214 +1264 1138 6123446.608565 +1265 1138 4734398.284357 +1139 1139 631577008.7377 +1146 1139 -27181694.66288 +1147 1139 -13597002.68459 +1148 1139 -10829003.14197 +1149 1139 29304866.06029 +1150 1139 34088108.93947 +1151 1139 74852155.60434 +1152 1139 35557037.39857 +1153 1139 -17741106.25578 +1154 1139 -19727580.52753 +1236 1139 15415739.3931 +1237 1139 -18498084.4015 +1238 1139 -99834027.95294 +1245 1139 -19583892.11655 +1246 1139 -51538880.44741 +1247 1139 -167219957.723 +1248 1139 -17965238.89317 +1249 1139 10605384.60401 +1250 1139 -88238208.0348 +1257 1139 -18931013.9508 +1258 1139 -13107584.00933 +1259 1139 -54305191.47237 +1260 1139 -41241201.16555 +1261 1139 -1194514.850572 +1262 1139 -36101396.81649 +1263 1139 -5917410.878264 +1264 1139 3156265.522905 +1265 1139 16329190.95617 +1140 1140 669327989.9306 +1141 1140 -1.430511474609e-06 +1142 1140 -10185331.54429 +1143 1140 57028027.11004 +1144 1140 9.089708328247e-07 +1145 1140 -2546332.887327 +1155 1140 -77421519.48389 +1156 1140 -5.513429641724e-07 +1157 1140 5092665.772129 +1158 1140 -48621476.67428 +1159 1140 30555555.55054 +1160 1140 29728027.55019 +1239 1140 -59010186.71026 +1240 1140 1.542270183563e-06 +1241 1140 49433583.10251 +1242 1140 -10337951.09135 +1243 1140 -7638888.891398 +1244 1140 5244680.501577 +1251 1140 20431686.98312 +1252 1140 -9.238719940186e-07 +1253 1140 -2546332.887312 +1254 1140 21018908.28051 +1255 1140 -2.346932888031e-06 +1256 1140 -636583.222144 +1266 1140 -53208020.04453 +1267 1140 -1.534819602966e-06 +1268 1140 -46887250.21518 +1269 1140 -9746784.424485 +1270 1140 7638888.891396 +1271 1140 -4608097.279433 +1141 1141 595989855.9605 +1142 1141 122220465.8582 +1143 1141 1.132488250732e-06 +1144 1141 -59082879.09408 +1145 1141 -61110232.92908 +1155 1141 -7.450580596924e-07 +1156 1141 57023920.20371 +1157 1141 30555116.4796 +1158 1141 30555555.55054 +1159 1141 -39454209.9235 +1160 1141 -16652558.23965 +1239 1141 1.035630702972e-06 +1240 1141 -25398826.77179 +1241 1141 7638779.123661 +1242 1141 -7638888.891398 +1243 1141 -8046134.402525 +1244 1141 6232693.774803 +1251 1141 -9.536743164063e-07 +1252 1141 2097153.481574 +1253 1141 30555116.47959 +1254 1141 -2.235174179077e-06 +1255 1141 -8008818.28482 +1256 1141 23250219.53173 +1266 1141 -1.318752765656e-06 +1267 1141 -19596660.10607 +1268 1141 7638779.123661 +1269 1141 7638888.891396 +1270 1141 -7454967.735663 +1271 1141 5468804.885664 +1142 1142 907581829.653 +1143 1142 -2546332.887327 +1144 1142 -61110232.92908 +1145 1142 30527909.01414 +1155 1142 5092665.772129 +1156 1142 30555116.4796 +1157 1142 134412647.088 +1158 1142 30109971.99439 +1159 1142 -16958113.795 +1160 1142 -19995669.80713 +1239 1142 49815527.5467 +1240 1142 7638779.12366 +1241 1142 -72142989.75742 +1242 1142 5244680.501577 +1243 1142 6232693.774804 +1244 1142 -152469.232357 +1251 1142 -2546332.887312 +1252 1142 30555116.47959 +1253 1142 -164838704.0269 +1254 1142 -636583.2221438 +1255 1142 23555775.08708 +1256 1142 25663714.57989 +1266 1142 -47269194.65938 +1267 1142 7638779.123661 +1268 1142 -56670545.31551 +1269 1142 -4608097.279433 +1270 1142 5468804.885664 +1271 1142 1423975.212606 +1143 1143 669327989.9306 +1144 1143 -1.430511474609e-06 +1145 1143 -10185331.54429 +1146 1143 57028027.11004 +1147 1143 9.089708328247e-07 +1148 1143 -2546332.887327 +1155 1143 -45183976.67484 +1156 1143 -30555555.55054 +1157 1143 -27563639.10707 +1158 1143 -77421519.48389 +1159 1143 -5.513429641724e-07 +1160 1143 5092665.772129 +1161 1143 -48621476.67428 +1162 1143 30555555.55054 +1163 1143 29728027.55019 +1239 1143 -32955138.59878 +1240 1143 7638888.891398 +1241 1143 19567597.17295 +1242 1143 -59010186.71026 +1243 1143 1.542270183563e-06 +1244 1143 49433583.10251 +1245 1143 -10337951.09135 +1246 1143 -7638888.891398 +1247 1143 5244680.501577 +1251 1143 -66012341.70521 +1252 1143 2.853572368622e-06 +1253 1143 -636583.2221378 +1254 1143 20431686.98312 +1255 1143 -9.238719940186e-07 +1256 1143 -2546332.887312 +1257 1143 21018908.28051 +1258 1143 -2.346932888031e-06 +1259 1143 -636583.222144 +1266 1143 -30645221.93135 +1267 1143 -7638888.891397 +1268 1143 -18931013.9508 +1269 1143 -53208020.04453 +1270 1143 -1.534819602966e-06 +1271 1143 -46887250.21518 +1272 1143 -9746784.424485 +1273 1143 7638888.891396 +1274 1143 -4608097.279433 +1144 1144 595989855.9605 +1145 1144 122220465.8582 +1146 1144 1.132488250732e-06 +1147 1144 -59082879.09408 +1148 1144 -61110232.92908 +1155 1144 -30555555.55054 +1156 1144 -36016709.92406 +1157 1144 -13902558.23995 +1158 1144 -7.450580596924e-07 +1159 1144 57023920.20371 +1160 1144 30555116.4796 +1161 1144 30555555.55054 +1162 1144 -39454209.9235 +1163 1144 -16652558.23965 +1239 1144 7638888.891398 +1240 1144 -30663321.90996 +1241 1144 -13871472.89847 +1242 1144 1.035630702972e-06 +1243 1144 -25398826.77179 +1244 1144 7638779.123661 +1245 1144 -7638888.891398 +1246 1144 -8046134.402525 +1247 1144 6232693.774803 +1251 1144 2.995133399963e-06 +1252 1144 -95040068.27054 +1253 1144 -53805336.01132 +1254 1144 -9.536743164063e-07 +1255 1144 2097153.481574 +1256 1144 30555116.47959 +1257 1144 -2.235174179077e-06 +1258 1144 -8008818.28482 +1259 1144 23250219.53173 +1266 1144 -7638888.891397 +1267 1144 -28353405.24253 +1268 1144 -13107584.00933 +1269 1144 -1.318752765656e-06 +1270 1144 -19596660.10607 +1271 1144 7638779.123661 +1272 1144 7638888.891396 +1273 1144 -7454967.735663 +1274 1144 5468804.885664 +1145 1145 907581829.653 +1146 1145 -2546332.887327 +1147 1145 -61110232.92908 +1148 1145 30527909.01414 +1155 1145 -27181694.66288 +1156 1145 -13597002.68459 +1157 1145 -10829003.14197 +1158 1145 5092665.772129 +1159 1145 30555116.4796 +1160 1145 134412647.088 +1161 1145 30109971.99439 +1162 1145 -16958113.795 +1163 1145 -19995669.80713 +1239 1145 19567597.17295 +1240 1145 -13871472.89847 +1241 1145 -60464969.25217 +1242 1145 49815527.5467 +1243 1145 7638779.12366 +1244 1145 -72142989.75742 +1245 1145 5244680.501577 +1246 1145 6232693.774804 +1247 1145 -152469.232357 +1251 1145 -636583.2221379 +1252 1145 -54110891.56668 +1253 1145 -206419618.7154 +1254 1145 -2546332.887312 +1255 1145 30555116.47959 +1256 1145 -164838704.0269 +1257 1145 -636583.2221438 +1258 1145 23555775.08708 +1259 1145 25663714.57989 +1266 1145 -18931013.9508 +1267 1145 -13107584.00933 +1268 1145 -54305191.47237 +1269 1145 -47269194.65938 +1270 1145 7638779.123661 +1271 1145 -56670545.31551 +1272 1145 -4608097.279433 +1273 1145 5468804.885664 +1274 1145 1423975.212606 +1146 1146 669327989.9306 +1147 1146 -1.430511474609e-06 +1148 1146 -10185331.54429 +1149 1146 57028027.11004 +1150 1146 9.089708328247e-07 +1151 1146 -2546332.887327 +1158 1146 -45183976.67484 +1159 1146 -30555555.55054 +1160 1146 -27563639.10707 +1161 1146 -77421519.48389 +1162 1146 -5.513429641724e-07 +1163 1146 5092665.772129 +1164 1146 -48621476.67428 +1165 1146 30555555.55054 +1166 1146 29728027.55019 +1242 1146 -32955138.59878 +1243 1146 7638888.891398 +1244 1146 19567597.17295 +1245 1146 -59010186.71026 +1246 1146 1.542270183563e-06 +1247 1146 49433583.10251 +1248 1146 -10337951.09135 +1249 1146 -7638888.891398 +1250 1146 5244680.501577 +1254 1146 -66012341.70521 +1255 1146 2.853572368622e-06 +1256 1146 -636583.2221378 +1257 1146 20431686.98312 +1258 1146 -9.238719940186e-07 +1259 1146 -2546332.887312 +1260 1146 21018908.28051 +1261 1146 -2.346932888031e-06 +1262 1146 -636583.222144 +1269 1146 -30645221.93135 +1270 1146 -7638888.891397 +1271 1146 -18931013.9508 +1272 1146 -53208020.04453 +1273 1146 -1.534819602966e-06 +1274 1146 -46887250.21518 +1275 1146 -9746784.424485 +1276 1146 7638888.891396 +1277 1146 -4608097.279433 +1147 1147 595989855.9605 +1148 1147 122220465.8582 +1149 1147 1.132488250732e-06 +1150 1147 -59082879.09408 +1151 1147 -61110232.92908 +1158 1147 -30555555.55054 +1159 1147 -36016709.92406 +1160 1147 -13902558.23995 +1161 1147 -7.450580596924e-07 +1162 1147 57023920.20371 +1163 1147 30555116.4796 +1164 1147 30555555.55054 +1165 1147 -39454209.9235 +1166 1147 -16652558.23965 +1242 1147 7638888.891398 +1243 1147 -30663321.90996 +1244 1147 -13871472.89847 +1245 1147 1.035630702972e-06 +1246 1147 -25398826.77179 +1247 1147 7638779.123661 +1248 1147 -7638888.891398 +1249 1147 -8046134.402525 +1250 1147 6232693.774803 +1254 1147 2.995133399963e-06 +1255 1147 -95040068.27054 +1256 1147 -53805336.01132 +1257 1147 -9.536743164063e-07 +1258 1147 2097153.481574 +1259 1147 30555116.47959 +1260 1147 -2.235174179077e-06 +1261 1147 -8008818.28482 +1262 1147 23250219.53173 +1269 1147 -7638888.891397 +1270 1147 -28353405.24253 +1271 1147 -13107584.00933 +1272 1147 -1.318752765656e-06 +1273 1147 -19596660.10607 +1274 1147 7638779.123661 +1275 1147 7638888.891396 +1276 1147 -7454967.735663 +1277 1147 5468804.885664 +1148 1148 907581829.653 +1149 1148 -2546332.887327 +1150 1148 -61110232.92908 +1151 1148 30527909.01414 +1158 1148 -27181694.66288 +1159 1148 -13597002.68459 +1160 1148 -10829003.14197 +1161 1148 5092665.772129 +1162 1148 30555116.4796 +1163 1148 134412647.088 +1164 1148 30109971.99439 +1165 1148 -16958113.795 +1166 1148 -19995669.80713 +1242 1148 19567597.17295 +1243 1148 -13871472.89847 +1244 1148 -60464969.25217 +1245 1148 49815527.5467 +1246 1148 7638779.12366 +1247 1148 -72142989.75742 +1248 1148 5244680.501577 +1249 1148 6232693.774804 +1250 1148 -152469.232357 +1254 1148 -636583.2221379 +1255 1148 -54110891.56668 +1256 1148 -206419618.7154 +1257 1148 -2546332.887312 +1258 1148 30555116.47959 +1259 1148 -164838704.0269 +1260 1148 -636583.2221438 +1261 1148 23555775.08708 +1262 1148 25663714.57989 +1269 1148 -18931013.9508 +1270 1148 -13107584.00933 +1271 1148 -54305191.47237 +1272 1148 -47269194.65938 +1273 1148 7638779.123661 +1274 1148 -56670545.31551 +1275 1148 -4608097.279433 +1276 1148 5468804.885664 +1277 1148 1423975.212606 +1149 1149 692250148.1146 +1150 1149 30619210.33408 +1151 1149 -34372600.90029 +1152 1149 16585727.58665 +1153 1149 -30581017.46396 +1154 1149 -29752163.59795 +1161 1149 -45183976.67484 +1162 1149 -30555555.55054 +1163 1149 -27563639.10707 +1164 1149 -77421519.48389 +1165 1149 -5.513429641724e-07 +1166 1149 5092665.772129 +1167 1149 -48621476.67428 +1168 1149 30555555.55054 +1169 1149 29728027.55019 +1245 1149 -32955138.59878 +1246 1149 7638888.891398 +1247 1149 19567597.17295 +1248 1149 -79032837.45136 +1249 1149 -7648437.10893 +1250 1149 55511888.47871 +1257 1149 -66012341.70521 +1258 1149 2.853572368622e-06 +1259 1149 -636583.2221378 +1260 1149 34928101.59242 +1261 1149 7654802.58729 +1262 1149 -8598678.217522 +1263 1149 5149787.278365 +1264 1149 -7645254.369755 +1265 1149 4611926.752539 +1272 1149 -30645221.93135 +1273 1149 -7638888.891397 +1274 1149 -18931013.9508 +1275 1149 -53208020.04453 +1276 1149 -1.534819602966e-06 +1277 1149 -46887250.21518 +1278 1149 -9746784.424485 +1279 1149 7638888.891396 +1280 1149 -4608097.279433 +1150 1150 609716100.864 +1151 1150 94722882.73185 +1152 1150 -30593748.42066 +1153 1150 -90408834.961 +1154 1150 -50742009.05798 +1161 1150 -30555555.55054 +1162 1150 -36016709.92406 +1163 1150 -13902558.23995 +1164 1150 -7.450580596924e-07 +1165 1150 57023920.20371 +1166 1150 30555116.4796 +1167 1150 30555555.55054 +1168 1150 -39454209.9235 +1169 1150 -16652558.23965 +1245 1150 7638888.891398 +1246 1150 -30663321.90996 +1247 1150 -13871472.89847 +1248 1150 -7645254.369751 +1249 1150 -43109768.41806 +1250 1150 18161862.49682 +1257 1150 2.995133399963e-06 +1258 1150 -95040068.27054 +1259 1150 -53805336.01132 +1260 1150 7654802.587289 +1261 1150 14294589.76961 +1262 1150 23676298.37333 +1263 1150 -7648437.108933 +1264 1150 -21598853.37172 +1265 1150 25862479.31684 +1272 1150 -7638888.891397 +1273 1150 -28353405.24253 +1274 1150 -13107584.00933 +1275 1150 -1.318752765656e-06 +1276 1150 -19596660.10607 +1277 1150 7638779.123661 +1278 1150 7638888.891396 +1279 1150 -7454967.735663 +1280 1150 5468804.885664 +1151 1151 858703305.1038 +1152 1151 -30146176.06602 +1153 1151 -59306688.68559 +1154 1151 32394301.37033 +1161 1151 -27181694.66288 +1162 1151 -13597002.68459 +1163 1151 -10829003.14197 +1164 1151 5092665.772129 +1165 1151 30555116.4796 +1166 1151 134412647.088 +1167 1151 30109971.99439 +1168 1151 -16958113.795 +1169 1151 -19995669.80713 +1245 1151 19567597.17295 +1246 1151 -13871472.89847 +1247 1151 -60464969.25217 +1248 1151 55896750.56943 +1249 1151 20307057.29599 +1250 1151 -98048385.90041 +1257 1151 -636583.2221379 +1258 1151 -54110891.56668 +1259 1151 -206419618.7154 +1260 1151 -8588615.841047 +1261 1151 23684348.15878 +1262 1151 -153682668.3423 +1263 1151 4613841.489092 +1264 1151 24026705.92618 +1265 1151 10774189.69233 +1272 1151 -18931013.9508 +1273 1151 -13107584.00933 +1274 1151 -54305191.47237 +1275 1151 -47269194.65938 +1276 1151 7638779.123661 +1277 1151 -56670545.31551 +1278 1151 -4608097.279433 +1279 1151 5468804.885664 +1280 1151 1423975.212606 +1152 1152 442585385.072 +1153 1152 30555555.55053 +1154 1152 -29342262.45851 +1164 1152 -45183976.67484 +1165 1152 -30555555.55054 +1166 1152 -27563639.10707 +1167 1152 -140989212.5199 +1168 1152 -30581017.46395 +1169 1152 29317331.52637 +1170 1152 -7397842.697824 +1171 1152 24469906.35385 +1172 1152 23704691.59905 +1248 1152 -37437760.48235 +1249 1152 9176214.887214 +1250 1152 23123609.08966 +1260 1152 -61598018.00238 +1261 1152 -7648437.108935 +1262 1152 -19592039.58835 +1263 1152 18346673.71113 +1264 1152 7638888.891398 +1265 1152 1385379.035684 +1275 1152 -30645221.93135 +1276 1152 -7638888.891397 +1277 1152 -18931013.9508 +1278 1152 -55802716.54489 +1279 1152 -7645254.369757 +1280 1152 -40856339.07483 +1281 1152 6123446.608564 +1282 1152 6117476.591476 +1283 1152 -3944940.585509 +1153 1153 396720404.8065 +1154 1153 76436047.94083 +1164 1153 -30555555.55054 +1165 1153 -36016709.92406 +1166 1153 -13902558.23995 +1167 1153 -30593748.42066 +1168 1153 2703063.542514 +1169 1153 42347550.95634 +1170 1153 36704859.53077 +1171 1153 -7397842.697831 +1172 1153 -26611659.38366 +1248 1153 6117476.591476 +1249 1153 -37437760.48236 +1250 1153 -12332056.26767 +1260 1153 -7645254.369756 +1261 1153 -88346658.65246 +1262 1153 -53374653.70739 +1263 1153 7638888.891397 +1264 1153 6880428.6391 +1265 1153 26085656.47845 +1275 1153 -7638888.891397 +1276 1153 -28353405.24253 +1277 1153 -13107584.00933 +1278 1153 -7648437.108936 +1279 1153 -19879647.51159 +1280 1153 942630.1669732 +1281 1153 9176214.887214 +1282 1153 6123446.608565 +1283 1153 4734398.284357 +1154 1154 631577008.7377 +1164 1154 -27181694.66288 +1165 1154 -13597002.68459 +1166 1154 -10829003.14197 +1167 1154 29304866.06029 +1168 1154 34088108.93947 +1169 1154 74852155.60434 +1170 1154 35557037.39857 +1171 1154 -17741106.25578 +1172 1154 -19727580.52753 +1248 1154 15415739.3931 +1249 1154 -18498084.4015 +1250 1154 -99834027.95294 +1260 1154 -19583892.11655 +1261 1154 -51538880.44741 +1262 1154 -167219957.723 +1263 1154 -17965238.89317 +1264 1154 10605384.60401 +1265 1154 -88238208.0348 +1275 1154 -18931013.9508 +1276 1154 -13107584.00933 +1277 1154 -54305191.47237 +1278 1154 -41241201.16555 +1279 1154 -1194514.850572 +1280 1154 -36101396.81649 +1281 1154 -5917410.878264 +1282 1154 3156265.522905 +1283 1154 16329190.95617 +1155 1155 669327989.9306 +1156 1155 -1.430511474609e-06 +1157 1155 -10185331.54429 +1158 1155 57028027.11004 +1159 1155 9.089708328247e-07 +1160 1155 -2546332.887327 +1173 1155 -77421519.48389 +1174 1155 -5.513429641724e-07 +1175 1155 5092665.772129 +1176 1155 -48621476.67428 +1177 1155 30555555.55054 +1178 1155 29728027.55019 +1251 1155 -59010186.71026 +1252 1155 1.542270183563e-06 +1253 1155 49433583.10251 +1254 1155 -10337951.09135 +1255 1155 -7638888.891398 +1256 1155 5244680.501577 +1266 1155 20431686.98312 +1267 1155 -9.238719940186e-07 +1268 1155 -2546332.887312 +1269 1155 21018908.28051 +1270 1155 -2.346932888031e-06 +1271 1155 -636583.222144 +1284 1155 -53208020.04453 +1285 1155 -1.534819602966e-06 +1286 1155 -46887250.21518 +1287 1155 -9746784.424485 +1288 1155 7638888.891396 +1289 1155 -4608097.279433 +1156 1156 595989855.9605 +1157 1156 122220465.8582 +1158 1156 1.132488250732e-06 +1159 1156 -59082879.09408 +1160 1156 -61110232.92908 +1173 1156 -7.450580596924e-07 +1174 1156 57023920.20371 +1175 1156 30555116.4796 +1176 1156 30555555.55054 +1177 1156 -39454209.9235 +1178 1156 -16652558.23965 +1251 1156 1.035630702972e-06 +1252 1156 -25398826.77179 +1253 1156 7638779.123661 +1254 1156 -7638888.891398 +1255 1156 -8046134.402525 +1256 1156 6232693.774803 +1266 1156 -9.536743164063e-07 +1267 1156 2097153.481574 +1268 1156 30555116.47959 +1269 1156 -2.235174179077e-06 +1270 1156 -8008818.28482 +1271 1156 23250219.53173 +1284 1156 -1.318752765656e-06 +1285 1156 -19596660.10607 +1286 1156 7638779.123661 +1287 1156 7638888.891396 +1288 1156 -7454967.735663 +1289 1156 5468804.885664 +1157 1157 907581829.653 +1158 1157 -2546332.887327 +1159 1157 -61110232.92908 +1160 1157 30527909.01414 +1173 1157 5092665.772129 +1174 1157 30555116.4796 +1175 1157 134412647.088 +1176 1157 30109971.99439 +1177 1157 -16958113.795 +1178 1157 -19995669.80713 +1251 1157 49815527.5467 +1252 1157 7638779.12366 +1253 1157 -72142989.75742 +1254 1157 5244680.501577 +1255 1157 6232693.774804 +1256 1157 -152469.232357 +1266 1157 -2546332.887312 +1267 1157 30555116.47959 +1268 1157 -164838704.0269 +1269 1157 -636583.2221438 +1270 1157 23555775.08708 +1271 1157 25663714.57989 +1284 1157 -47269194.65938 +1285 1157 7638779.123661 +1286 1157 -56670545.31551 +1287 1157 -4608097.279433 +1288 1157 5468804.885664 +1289 1157 1423975.212606 +1158 1158 669327989.9306 +1159 1158 -1.430511474609e-06 +1160 1158 -10185331.54429 +1161 1158 57028027.11004 +1162 1158 9.089708328247e-07 +1163 1158 -2546332.887327 +1173 1158 -45183976.67484 +1174 1158 -30555555.55054 +1175 1158 -27563639.10707 +1176 1158 -77421519.48389 +1177 1158 -5.513429641724e-07 +1178 1158 5092665.772129 +1179 1158 -48621476.67428 +1180 1158 30555555.55054 +1181 1158 29728027.55019 +1251 1158 -32955138.59878 +1252 1158 7638888.891398 +1253 1158 19567597.17295 +1254 1158 -59010186.71026 +1255 1158 1.542270183563e-06 +1256 1158 49433583.10251 +1257 1158 -10337951.09135 +1258 1158 -7638888.891398 +1259 1158 5244680.501577 +1266 1158 -66012341.70521 +1267 1158 2.853572368622e-06 +1268 1158 -636583.2221378 +1269 1158 20431686.98312 +1270 1158 -9.238719940186e-07 +1271 1158 -2546332.887312 +1272 1158 21018908.28051 +1273 1158 -2.346932888031e-06 +1274 1158 -636583.222144 +1284 1158 -30645221.93135 +1285 1158 -7638888.891397 +1286 1158 -18931013.9508 +1287 1158 -53208020.04453 +1288 1158 -1.534819602966e-06 +1289 1158 -46887250.21518 +1290 1158 -9746784.424485 +1291 1158 7638888.891396 +1292 1158 -4608097.279433 +1159 1159 595989855.9605 +1160 1159 122220465.8582 +1161 1159 1.132488250732e-06 +1162 1159 -59082879.09408 +1163 1159 -61110232.92908 +1173 1159 -30555555.55054 +1174 1159 -36016709.92406 +1175 1159 -13902558.23995 +1176 1159 -7.450580596924e-07 +1177 1159 57023920.20371 +1178 1159 30555116.4796 +1179 1159 30555555.55054 +1180 1159 -39454209.9235 +1181 1159 -16652558.23965 +1251 1159 7638888.891398 +1252 1159 -30663321.90996 +1253 1159 -13871472.89847 +1254 1159 1.035630702972e-06 +1255 1159 -25398826.77179 +1256 1159 7638779.123661 +1257 1159 -7638888.891398 +1258 1159 -8046134.402525 +1259 1159 6232693.774803 +1266 1159 2.995133399963e-06 +1267 1159 -95040068.27054 +1268 1159 -53805336.01132 +1269 1159 -9.536743164063e-07 +1270 1159 2097153.481574 +1271 1159 30555116.47959 +1272 1159 -2.235174179077e-06 +1273 1159 -8008818.28482 +1274 1159 23250219.53173 +1284 1159 -7638888.891397 +1285 1159 -28353405.24253 +1286 1159 -13107584.00933 +1287 1159 -1.318752765656e-06 +1288 1159 -19596660.10607 +1289 1159 7638779.123661 +1290 1159 7638888.891396 +1291 1159 -7454967.735663 +1292 1159 5468804.885664 +1160 1160 907581829.653 +1161 1160 -2546332.887327 +1162 1160 -61110232.92908 +1163 1160 30527909.01414 +1173 1160 -27181694.66288 +1174 1160 -13597002.68459 +1175 1160 -10829003.14197 +1176 1160 5092665.772129 +1177 1160 30555116.4796 +1178 1160 134412647.088 +1179 1160 30109971.99439 +1180 1160 -16958113.795 +1181 1160 -19995669.80713 +1251 1160 19567597.17295 +1252 1160 -13871472.89847 +1253 1160 -60464969.25217 +1254 1160 49815527.5467 +1255 1160 7638779.12366 +1256 1160 -72142989.75742 +1257 1160 5244680.501577 +1258 1160 6232693.774804 +1259 1160 -152469.232357 +1266 1160 -636583.2221379 +1267 1160 -54110891.56668 +1268 1160 -206419618.7154 +1269 1160 -2546332.887312 +1270 1160 30555116.47959 +1271 1160 -164838704.0269 +1272 1160 -636583.2221438 +1273 1160 23555775.08708 +1274 1160 25663714.57989 +1284 1160 -18931013.9508 +1285 1160 -13107584.00933 +1286 1160 -54305191.47237 +1287 1160 -47269194.65938 +1288 1160 7638779.123661 +1289 1160 -56670545.31551 +1290 1160 -4608097.279433 +1291 1160 5468804.885664 +1292 1160 1423975.212606 +1161 1161 669327989.9306 +1162 1161 -1.430511474609e-06 +1163 1161 -10185331.54429 +1164 1161 57028027.11004 +1165 1161 9.089708328247e-07 +1166 1161 -2546332.887327 +1176 1161 -45183976.67484 +1177 1161 -30555555.55054 +1178 1161 -27563639.10707 +1179 1161 -77421519.48389 +1180 1161 -5.513429641724e-07 +1181 1161 5092665.772129 +1182 1161 -48621476.67428 +1183 1161 30555555.55054 +1184 1161 29728027.55019 +1254 1161 -32955138.59878 +1255 1161 7638888.891398 +1256 1161 19567597.17295 +1257 1161 -59010186.71026 +1258 1161 1.542270183563e-06 +1259 1161 49433583.10251 +1260 1161 -10337951.09135 +1261 1161 -7638888.891398 +1262 1161 5244680.501577 +1269 1161 -66012341.70521 +1270 1161 2.853572368622e-06 +1271 1161 -636583.2221378 +1272 1161 20431686.98312 +1273 1161 -9.238719940186e-07 +1274 1161 -2546332.887312 +1275 1161 21018908.28051 +1276 1161 -2.346932888031e-06 +1277 1161 -636583.222144 +1287 1161 -30645221.93135 +1288 1161 -7638888.891397 +1289 1161 -18931013.9508 +1290 1161 -53208020.04453 +1291 1161 -1.534819602966e-06 +1292 1161 -46887250.21518 +1293 1161 -9746784.424485 +1294 1161 7638888.891396 +1295 1161 -4608097.279433 +1162 1162 595989855.9605 +1163 1162 122220465.8582 +1164 1162 1.132488250732e-06 +1165 1162 -59082879.09408 +1166 1162 -61110232.92908 +1176 1162 -30555555.55054 +1177 1162 -36016709.92406 +1178 1162 -13902558.23995 +1179 1162 -7.450580596924e-07 +1180 1162 57023920.20371 +1181 1162 30555116.4796 +1182 1162 30555555.55054 +1183 1162 -39454209.9235 +1184 1162 -16652558.23965 +1254 1162 7638888.891398 +1255 1162 -30663321.90996 +1256 1162 -13871472.89847 +1257 1162 1.035630702972e-06 +1258 1162 -25398826.77179 +1259 1162 7638779.123661 +1260 1162 -7638888.891398 +1261 1162 -8046134.402525 +1262 1162 6232693.774803 +1269 1162 2.995133399963e-06 +1270 1162 -95040068.27054 +1271 1162 -53805336.01132 +1272 1162 -9.536743164063e-07 +1273 1162 2097153.481574 +1274 1162 30555116.47959 +1275 1162 -2.235174179077e-06 +1276 1162 -8008818.28482 +1277 1162 23250219.53173 +1287 1162 -7638888.891397 +1288 1162 -28353405.24253 +1289 1162 -13107584.00933 +1290 1162 -1.318752765656e-06 +1291 1162 -19596660.10607 +1292 1162 7638779.123661 +1293 1162 7638888.891396 +1294 1162 -7454967.735663 +1295 1162 5468804.885664 +1163 1163 907581829.653 +1164 1163 -2546332.887327 +1165 1163 -61110232.92908 +1166 1163 30527909.01414 +1176 1163 -27181694.66288 +1177 1163 -13597002.68459 +1178 1163 -10829003.14197 +1179 1163 5092665.772129 +1180 1163 30555116.4796 +1181 1163 134412647.088 +1182 1163 30109971.99439 +1183 1163 -16958113.795 +1184 1163 -19995669.80713 +1254 1163 19567597.17295 +1255 1163 -13871472.89847 +1256 1163 -60464969.25217 +1257 1163 49815527.5467 +1258 1163 7638779.12366 +1259 1163 -72142989.75742 +1260 1163 5244680.501577 +1261 1163 6232693.774804 +1262 1163 -152469.232357 +1269 1163 -636583.2221379 +1270 1163 -54110891.56668 +1271 1163 -206419618.7154 +1272 1163 -2546332.887312 +1273 1163 30555116.47959 +1274 1163 -164838704.0269 +1275 1163 -636583.2221438 +1276 1163 23555775.08708 +1277 1163 25663714.57989 +1287 1163 -18931013.9508 +1288 1163 -13107584.00933 +1289 1163 -54305191.47237 +1290 1163 -47269194.65938 +1291 1163 7638779.123661 +1292 1163 -56670545.31551 +1293 1163 -4608097.279433 +1294 1163 5468804.885664 +1295 1163 1423975.212606 +1164 1164 669327989.9306 +1165 1164 -1.430511474609e-06 +1166 1164 -10185331.54429 +1167 1164 57028027.11004 +1168 1164 9.089708328247e-07 +1169 1164 -2546332.887327 +1179 1164 -45183976.67484 +1180 1164 -30555555.55054 +1181 1164 -27563639.10707 +1182 1164 -77421519.48389 +1183 1164 -5.513429641724e-07 +1184 1164 5092665.772129 +1185 1164 -48621476.67428 +1186 1164 30555555.55054 +1187 1164 29728027.55019 +1257 1164 -32955138.59878 +1258 1164 7638888.891398 +1259 1164 19567597.17295 +1260 1164 -59010186.71026 +1261 1164 1.542270183563e-06 +1262 1164 49433583.10251 +1263 1164 -10337951.09135 +1264 1164 -7638888.891398 +1265 1164 5244680.501577 +1272 1164 -66012341.70521 +1273 1164 2.853572368622e-06 +1274 1164 -636583.2221378 +1275 1164 20431686.98312 +1276 1164 -9.238719940186e-07 +1277 1164 -2546332.887312 +1278 1164 21018908.28051 +1279 1164 -2.346932888031e-06 +1280 1164 -636583.222144 +1290 1164 -30645221.93135 +1291 1164 -7638888.891397 +1292 1164 -18931013.9508 +1293 1164 -53208020.04453 +1294 1164 -1.534819602966e-06 +1295 1164 -46887250.21518 +1296 1164 -9746784.424485 +1297 1164 7638888.891396 +1298 1164 -4608097.279433 +1165 1165 595989855.9605 +1166 1165 122220465.8582 +1167 1165 1.132488250732e-06 +1168 1165 -59082879.09408 +1169 1165 -61110232.92908 +1179 1165 -30555555.55054 +1180 1165 -36016709.92406 +1181 1165 -13902558.23995 +1182 1165 -7.450580596924e-07 +1183 1165 57023920.20371 +1184 1165 30555116.4796 +1185 1165 30555555.55054 +1186 1165 -39454209.9235 +1187 1165 -16652558.23965 +1257 1165 7638888.891398 +1258 1165 -30663321.90996 +1259 1165 -13871472.89847 +1260 1165 1.035630702972e-06 +1261 1165 -25398826.77179 +1262 1165 7638779.123661 +1263 1165 -7638888.891398 +1264 1165 -8046134.402525 +1265 1165 6232693.774803 +1272 1165 2.995133399963e-06 +1273 1165 -95040068.27054 +1274 1165 -53805336.01132 +1275 1165 -9.536743164063e-07 +1276 1165 2097153.481574 +1277 1165 30555116.47959 +1278 1165 -2.235174179077e-06 +1279 1165 -8008818.28482 +1280 1165 23250219.53173 +1290 1165 -7638888.891397 +1291 1165 -28353405.24253 +1292 1165 -13107584.00933 +1293 1165 -1.318752765656e-06 +1294 1165 -19596660.10607 +1295 1165 7638779.123661 +1296 1165 7638888.891396 +1297 1165 -7454967.735663 +1298 1165 5468804.885664 +1166 1166 907581829.653 +1167 1166 -2546332.887327 +1168 1166 -61110232.92908 +1169 1166 30527909.01414 +1179 1166 -27181694.66288 +1180 1166 -13597002.68459 +1181 1166 -10829003.14197 +1182 1166 5092665.772129 +1183 1166 30555116.4796 +1184 1166 134412647.088 +1185 1166 30109971.99439 +1186 1166 -16958113.795 +1187 1166 -19995669.80713 +1257 1166 19567597.17295 +1258 1166 -13871472.89847 +1259 1166 -60464969.25217 +1260 1166 49815527.5467 +1261 1166 7638779.12366 +1262 1166 -72142989.75742 +1263 1166 5244680.501577 +1264 1166 6232693.774804 +1265 1166 -152469.232357 +1272 1166 -636583.2221379 +1273 1166 -54110891.56668 +1274 1166 -206419618.7154 +1275 1166 -2546332.887312 +1276 1166 30555116.47959 +1277 1166 -164838704.0269 +1278 1166 -636583.2221438 +1279 1166 23555775.08708 +1280 1166 25663714.57989 +1290 1166 -18931013.9508 +1291 1166 -13107584.00933 +1292 1166 -54305191.47237 +1293 1166 -47269194.65938 +1294 1166 7638779.123661 +1295 1166 -56670545.31551 +1296 1166 -4608097.279433 +1297 1166 5468804.885664 +1298 1166 1423975.212606 +1167 1167 692250148.1146 +1168 1167 30619210.33408 +1169 1167 -34372600.90029 +1170 1167 16585727.58665 +1171 1167 -30581017.46396 +1172 1167 -29752163.59795 +1182 1167 -45183976.67484 +1183 1167 -30555555.55054 +1184 1167 -27563639.10707 +1185 1167 -77421519.48389 +1186 1167 -5.513429641724e-07 +1187 1167 5092665.772129 +1188 1167 -48621476.67428 +1189 1167 30555555.55054 +1190 1167 29728027.55019 +1260 1167 -32955138.59878 +1261 1167 7638888.891398 +1262 1167 19567597.17295 +1263 1167 -79032837.45136 +1264 1167 -7648437.10893 +1265 1167 55511888.47871 +1275 1167 -66012341.70521 +1276 1167 2.853572368622e-06 +1277 1167 -636583.2221378 +1278 1167 34928101.59242 +1279 1167 7654802.58729 +1280 1167 -8598678.217522 +1281 1167 5149787.278365 +1282 1167 -7645254.369755 +1283 1167 4611926.752539 +1293 1167 -30645221.93135 +1294 1167 -7638888.891397 +1295 1167 -18931013.9508 +1296 1167 -53208020.04453 +1297 1167 -1.534819602966e-06 +1298 1167 -46887250.21518 +1299 1167 -9746784.424485 +1300 1167 7638888.891396 +1301 1167 -4608097.279433 +1168 1168 609716100.864 +1169 1168 94722882.73185 +1170 1168 -30593748.42066 +1171 1168 -90408834.961 +1172 1168 -50742009.05798 +1182 1168 -30555555.55054 +1183 1168 -36016709.92406 +1184 1168 -13902558.23995 +1185 1168 -7.450580596924e-07 +1186 1168 57023920.20371 +1187 1168 30555116.4796 +1188 1168 30555555.55054 +1189 1168 -39454209.9235 +1190 1168 -16652558.23965 +1260 1168 7638888.891398 +1261 1168 -30663321.90996 +1262 1168 -13871472.89847 +1263 1168 -7645254.369751 +1264 1168 -43109768.41806 +1265 1168 18161862.49682 +1275 1168 2.995133399963e-06 +1276 1168 -95040068.27054 +1277 1168 -53805336.01132 +1278 1168 7654802.587289 +1279 1168 14294589.76961 +1280 1168 23676298.37333 +1281 1168 -7648437.108933 +1282 1168 -21598853.37172 +1283 1168 25862479.31684 +1293 1168 -7638888.891397 +1294 1168 -28353405.24253 +1295 1168 -13107584.00933 +1296 1168 -1.318752765656e-06 +1297 1168 -19596660.10607 +1298 1168 7638779.123661 +1299 1168 7638888.891396 +1300 1168 -7454967.735663 +1301 1168 5468804.885664 +1169 1169 858703305.1038 +1170 1169 -30146176.06602 +1171 1169 -59306688.68559 +1172 1169 32394301.37033 +1182 1169 -27181694.66288 +1183 1169 -13597002.68459 +1184 1169 -10829003.14197 +1185 1169 5092665.772129 +1186 1169 30555116.4796 +1187 1169 134412647.088 +1188 1169 30109971.99439 +1189 1169 -16958113.795 +1190 1169 -19995669.80713 +1260 1169 19567597.17295 +1261 1169 -13871472.89847 +1262 1169 -60464969.25217 +1263 1169 55896750.56943 +1264 1169 20307057.29599 +1265 1169 -98048385.90041 +1275 1169 -636583.2221379 +1276 1169 -54110891.56668 +1277 1169 -206419618.7154 +1278 1169 -8588615.841047 +1279 1169 23684348.15878 +1280 1169 -153682668.3423 +1281 1169 4613841.489092 +1282 1169 24026705.92618 +1283 1169 10774189.69233 +1293 1169 -18931013.9508 +1294 1169 -13107584.00933 +1295 1169 -54305191.47237 +1296 1169 -47269194.65938 +1297 1169 7638779.123661 +1298 1169 -56670545.31551 +1299 1169 -4608097.279433 +1300 1169 5468804.885664 +1301 1169 1423975.212606 +1170 1170 364985426.4907 +1171 1170 -14061652.22197 +1172 1170 17814269.07624 +1185 1170 -45183976.67484 +1186 1170 -30555555.55054 +1187 1170 -27563639.10707 +1188 1170 -45058067.96334 +1189 1170 13871774.76762 +1190 1170 2014135.925476 +1191 1170 -77987935.00936 +1192 1170 24634321.89478 +1193 1170 4614449.669165 +1263 1170 -37437760.48235 +1264 1170 9176214.887214 +1265 1170 23123609.08966 +1278 1170 -61598018.00238 +1279 1170 -7648437.108935 +1280 1170 -19592039.58835 +1281 1170 18456352.87299 +1282 1170 -3515413.057224 +1283 1170 9204137.171611 +1296 1170 -30645221.93135 +1297 1170 -7638888.891397 +1298 1170 -18931013.9508 +1299 1170 -30340144.80161 +1300 1170 3467943.693614 +1301 1170 -30119546.23577 +1302 1170 -19821700.11939 +1303 1170 6158580.476729 +1304 1170 -1921392.690481 +1171 1171 471961895.5022 +1172 1171 97697867.88863 +1185 1171 -30555555.55054 +1186 1171 -36016709.92406 +1187 1171 -13902558.23995 +1188 1171 13776836.04045 +1189 1171 79070799.38238 +1190 1171 20523124.61285 +1191 1171 36951482.84217 +1192 1171 -211265975.5697 +1193 1171 -25405019.46708 +1263 1171 6117476.591476 +1264 1171 -37437760.48236 +1265 1171 -12332056.26767 +1278 1171 -7645254.369756 +1279 1171 -88346658.65246 +1280 1171 -53374653.70739 +1281 1171 -3515413.057224 +1282 1171 45200470.13904 +1283 1171 28178112.40107 +1296 1171 -7638888.891397 +1297 1171 -28353405.24253 +1298 1171 -13107584.00933 +1299 1171 3444209.011808 +1300 1171 692072.0501018 +1301 1171 9579154.834703 +1302 1171 9237870.715094 +1303 1171 -53141210.27589 +1304 1171 10606269.5228 +1172 1172 529687108.5978 +1185 1172 -27181694.66288 +1186 1172 -13597002.68459 +1187 1172 -10829003.14197 +1188 1172 11928338.42634 +1189 1172 20213350.09205 +1190 1172 92347177.78475 +1191 1172 6921674.503748 +1192 1172 -24162117.07483 +1193 1172 -74689786.13132 +1263 1172 15415739.3931 +1264 1172 -18498084.4015 +1265 1172 -99834027.95294 +1278 1172 -19583892.11655 +1279 1172 -51538880.44741 +1280 1172 -167219957.723 +1281 1172 -3159598.760604 +1282 1172 18338796.75477 +1283 1172 -61684899.57103 +1296 1172 -18931013.9508 +1297 1172 -13107584.00933 +1298 1172 -54305191.47237 +1299 1172 -28213514.83563 +1300 1172 9298506.145881 +1301 1172 -27781546.3564 +1302 1172 -2882089.035722 +1303 1172 9831110.118881 +1304 1172 -19538356.82854 +1173 1173 669327989.9306 +1174 1173 -1.430511474609e-06 +1175 1173 -10185331.54429 +1176 1173 57028027.11004 +1177 1173 9.089708328247e-07 +1178 1173 -2546332.887327 +1194 1173 -77421519.48389 +1195 1173 -5.513429641724e-07 +1196 1173 5092665.772129 +1197 1173 -48621476.67428 +1198 1173 30555555.55054 +1199 1173 29728027.55019 +1266 1173 -59010186.71026 +1267 1173 1.542270183563e-06 +1268 1173 49433583.10251 +1269 1173 -10337951.09135 +1270 1173 -7638888.891398 +1271 1173 5244680.501577 +1284 1173 20431686.98312 +1285 1173 -9.238719940186e-07 +1286 1173 -2546332.887312 +1287 1173 21018908.28051 +1288 1173 -2.346932888031e-06 +1289 1173 -636583.222144 +1305 1173 -53208020.04453 +1306 1173 -1.534819602966e-06 +1307 1173 -46887250.21518 +1308 1173 -9746784.424485 +1309 1173 7638888.891396 +1310 1173 -4608097.279433 +1174 1174 595989855.9605 +1175 1174 122220465.8582 +1176 1174 1.132488250732e-06 +1177 1174 -59082879.09408 +1178 1174 -61110232.92908 +1194 1174 -7.450580596924e-07 +1195 1174 57023920.20371 +1196 1174 30555116.4796 +1197 1174 30555555.55054 +1198 1174 -39454209.9235 +1199 1174 -16652558.23965 +1266 1174 1.035630702972e-06 +1267 1174 -25398826.77179 +1268 1174 7638779.123661 +1269 1174 -7638888.891398 +1270 1174 -8046134.402525 +1271 1174 6232693.774803 +1284 1174 -9.536743164063e-07 +1285 1174 2097153.481574 +1286 1174 30555116.47959 +1287 1174 -2.235174179077e-06 +1288 1174 -8008818.28482 +1289 1174 23250219.53173 +1305 1174 -1.318752765656e-06 +1306 1174 -19596660.10607 +1307 1174 7638779.123661 +1308 1174 7638888.891396 +1309 1174 -7454967.735663 +1310 1174 5468804.885664 +1175 1175 907581829.653 +1176 1175 -2546332.887327 +1177 1175 -61110232.92908 +1178 1175 30527909.01414 +1194 1175 5092665.772129 +1195 1175 30555116.4796 +1196 1175 134412647.088 +1197 1175 30109971.99439 +1198 1175 -16958113.795 +1199 1175 -19995669.80713 +1266 1175 49815527.5467 +1267 1175 7638779.12366 +1268 1175 -72142989.75742 +1269 1175 5244680.501577 +1270 1175 6232693.774804 +1271 1175 -152469.232357 +1284 1175 -2546332.887312 +1285 1175 30555116.47959 +1286 1175 -164838704.0269 +1287 1175 -636583.2221438 +1288 1175 23555775.08708 +1289 1175 25663714.57989 +1305 1175 -47269194.65938 +1306 1175 7638779.123661 +1307 1175 -56670545.31551 +1308 1175 -4608097.279433 +1309 1175 5468804.885664 +1310 1175 1423975.212606 +1176 1176 669327989.9306 +1177 1176 -1.430511474609e-06 +1178 1176 -10185331.54429 +1179 1176 57028027.11004 +1180 1176 9.089708328247e-07 +1181 1176 -2546332.887327 +1194 1176 -45183976.67484 +1195 1176 -30555555.55054 +1196 1176 -27563639.10707 +1197 1176 -77421519.48389 +1198 1176 -5.513429641724e-07 +1199 1176 5092665.772129 +1200 1176 -48621476.67428 +1201 1176 30555555.55054 +1202 1176 29728027.55019 +1266 1176 -32955138.59878 +1267 1176 7638888.891398 +1268 1176 19567597.17295 +1269 1176 -59010186.71026 +1270 1176 1.542270183563e-06 +1271 1176 49433583.10251 +1272 1176 -10337951.09135 +1273 1176 -7638888.891398 +1274 1176 5244680.501577 +1284 1176 -66012341.70521 +1285 1176 2.853572368622e-06 +1286 1176 -636583.2221378 +1287 1176 20431686.98312 +1288 1176 -9.238719940186e-07 +1289 1176 -2546332.887312 +1290 1176 21018908.28051 +1291 1176 -2.346932888031e-06 +1292 1176 -636583.222144 +1305 1176 -30645221.93135 +1306 1176 -7638888.891397 +1307 1176 -18931013.9508 +1308 1176 -53208020.04453 +1309 1176 -1.534819602966e-06 +1310 1176 -46887250.21518 +1311 1176 -9746784.424485 +1312 1176 7638888.891396 +1313 1176 -4608097.279433 +1177 1177 595989855.9605 +1178 1177 122220465.8582 +1179 1177 1.132488250732e-06 +1180 1177 -59082879.09408 +1181 1177 -61110232.92908 +1194 1177 -30555555.55054 +1195 1177 -36016709.92406 +1196 1177 -13902558.23995 +1197 1177 -7.450580596924e-07 +1198 1177 57023920.20371 +1199 1177 30555116.4796 +1200 1177 30555555.55054 +1201 1177 -39454209.9235 +1202 1177 -16652558.23965 +1266 1177 7638888.891398 +1267 1177 -30663321.90996 +1268 1177 -13871472.89847 +1269 1177 1.035630702972e-06 +1270 1177 -25398826.77179 +1271 1177 7638779.123661 +1272 1177 -7638888.891398 +1273 1177 -8046134.402525 +1274 1177 6232693.774803 +1284 1177 2.995133399963e-06 +1285 1177 -95040068.27054 +1286 1177 -53805336.01132 +1287 1177 -9.536743164063e-07 +1288 1177 2097153.481574 +1289 1177 30555116.47959 +1290 1177 -2.235174179077e-06 +1291 1177 -8008818.28482 +1292 1177 23250219.53173 +1305 1177 -7638888.891397 +1306 1177 -28353405.24253 +1307 1177 -13107584.00933 +1308 1177 -1.318752765656e-06 +1309 1177 -19596660.10607 +1310 1177 7638779.123661 +1311 1177 7638888.891396 +1312 1177 -7454967.735663 +1313 1177 5468804.885664 +1178 1178 907581829.653 +1179 1178 -2546332.887327 +1180 1178 -61110232.92908 +1181 1178 30527909.01414 +1194 1178 -27181694.66288 +1195 1178 -13597002.68459 +1196 1178 -10829003.14197 +1197 1178 5092665.772129 +1198 1178 30555116.4796 +1199 1178 134412647.088 +1200 1178 30109971.99439 +1201 1178 -16958113.795 +1202 1178 -19995669.80713 +1266 1178 19567597.17295 +1267 1178 -13871472.89847 +1268 1178 -60464969.25217 +1269 1178 49815527.5467 +1270 1178 7638779.12366 +1271 1178 -72142989.75742 +1272 1178 5244680.501577 +1273 1178 6232693.774804 +1274 1178 -152469.232357 +1284 1178 -636583.2221379 +1285 1178 -54110891.56668 +1286 1178 -206419618.7154 +1287 1178 -2546332.887312 +1288 1178 30555116.47959 +1289 1178 -164838704.0269 +1290 1178 -636583.2221438 +1291 1178 23555775.08708 +1292 1178 25663714.57989 +1305 1178 -18931013.9508 +1306 1178 -13107584.00933 +1307 1178 -54305191.47237 +1308 1178 -47269194.65938 +1309 1178 7638779.123661 +1310 1178 -56670545.31551 +1311 1178 -4608097.279433 +1312 1178 5468804.885664 +1313 1178 1423975.212606 +1179 1179 669327989.9306 +1180 1179 -1.430511474609e-06 +1181 1179 -10185331.54429 +1182 1179 57028027.11004 +1183 1179 9.089708328247e-07 +1184 1179 -2546332.887327 +1197 1179 -45183976.67484 +1198 1179 -30555555.55054 +1199 1179 -27563639.10707 +1200 1179 -77421519.48389 +1201 1179 -5.513429641724e-07 +1202 1179 5092665.772129 +1203 1179 -48621476.67428 +1204 1179 30555555.55054 +1205 1179 29728027.55019 +1269 1179 -32955138.59878 +1270 1179 7638888.891398 +1271 1179 19567597.17295 +1272 1179 -59010186.71026 +1273 1179 1.542270183563e-06 +1274 1179 49433583.10251 +1275 1179 -10337951.09135 +1276 1179 -7638888.891398 +1277 1179 5244680.501577 +1287 1179 -66012341.70521 +1288 1179 2.853572368622e-06 +1289 1179 -636583.2221378 +1290 1179 20431686.98312 +1291 1179 -9.238719940186e-07 +1292 1179 -2546332.887312 +1293 1179 21018908.28051 +1294 1179 -2.346932888031e-06 +1295 1179 -636583.222144 +1308 1179 -30645221.93135 +1309 1179 -7638888.891397 +1310 1179 -18931013.9508 +1311 1179 -53208020.04453 +1312 1179 -1.534819602966e-06 +1313 1179 -46887250.21518 +1314 1179 -9746784.424485 +1315 1179 7638888.891396 +1316 1179 -4608097.279433 +1180 1180 595989855.9605 +1181 1180 122220465.8582 +1182 1180 1.132488250732e-06 +1183 1180 -59082879.09408 +1184 1180 -61110232.92908 +1197 1180 -30555555.55054 +1198 1180 -36016709.92406 +1199 1180 -13902558.23995 +1200 1180 -7.450580596924e-07 +1201 1180 57023920.20371 +1202 1180 30555116.4796 +1203 1180 30555555.55054 +1204 1180 -39454209.9235 +1205 1180 -16652558.23965 +1269 1180 7638888.891398 +1270 1180 -30663321.90996 +1271 1180 -13871472.89847 +1272 1180 1.035630702972e-06 +1273 1180 -25398826.77179 +1274 1180 7638779.123661 +1275 1180 -7638888.891398 +1276 1180 -8046134.402525 +1277 1180 6232693.774803 +1287 1180 2.995133399963e-06 +1288 1180 -95040068.27054 +1289 1180 -53805336.01132 +1290 1180 -9.536743164063e-07 +1291 1180 2097153.481574 +1292 1180 30555116.47959 +1293 1180 -2.235174179077e-06 +1294 1180 -8008818.28482 +1295 1180 23250219.53173 +1308 1180 -7638888.891397 +1309 1180 -28353405.24253 +1310 1180 -13107584.00933 +1311 1180 -1.318752765656e-06 +1312 1180 -19596660.10607 +1313 1180 7638779.123661 +1314 1180 7638888.891396 +1315 1180 -7454967.735663 +1316 1180 5468804.885664 +1181 1181 907581829.653 +1182 1181 -2546332.887327 +1183 1181 -61110232.92908 +1184 1181 30527909.01414 +1197 1181 -27181694.66288 +1198 1181 -13597002.68459 +1199 1181 -10829003.14197 +1200 1181 5092665.772129 +1201 1181 30555116.4796 +1202 1181 134412647.088 +1203 1181 30109971.99439 +1204 1181 -16958113.795 +1205 1181 -19995669.80713 +1269 1181 19567597.17295 +1270 1181 -13871472.89847 +1271 1181 -60464969.25217 +1272 1181 49815527.5467 +1273 1181 7638779.12366 +1274 1181 -72142989.75742 +1275 1181 5244680.501577 +1276 1181 6232693.774804 +1277 1181 -152469.232357 +1287 1181 -636583.2221379 +1288 1181 -54110891.56668 +1289 1181 -206419618.7154 +1290 1181 -2546332.887312 +1291 1181 30555116.47959 +1292 1181 -164838704.0269 +1293 1181 -636583.2221438 +1294 1181 23555775.08708 +1295 1181 25663714.57989 +1308 1181 -18931013.9508 +1309 1181 -13107584.00933 +1310 1181 -54305191.47237 +1311 1181 -47269194.65938 +1312 1181 7638779.123661 +1313 1181 -56670545.31551 +1314 1181 -4608097.279433 +1315 1181 5468804.885664 +1316 1181 1423975.212606 +1182 1182 669327989.9306 +1183 1182 -1.430511474609e-06 +1184 1182 -10185331.54429 +1185 1182 57028027.11004 +1186 1182 9.089708328247e-07 +1187 1182 -2546332.887327 +1200 1182 -45183976.67484 +1201 1182 -30555555.55054 +1202 1182 -27563639.10707 +1203 1182 -77421519.48389 +1204 1182 -5.513429641724e-07 +1205 1182 5092665.772129 +1206 1182 -48621476.67428 +1207 1182 30555555.55054 +1208 1182 29728027.55019 +1272 1182 -32955138.59878 +1273 1182 7638888.891398 +1274 1182 19567597.17295 +1275 1182 -59010186.71026 +1276 1182 1.542270183563e-06 +1277 1182 49433583.10251 +1278 1182 -10337951.09135 +1279 1182 -7638888.891398 +1280 1182 5244680.501577 +1290 1182 -66012341.70521 +1291 1182 2.853572368622e-06 +1292 1182 -636583.2221378 +1293 1182 20431686.98312 +1294 1182 -9.238719940186e-07 +1295 1182 -2546332.887312 +1296 1182 21018908.28051 +1297 1182 -2.346932888031e-06 +1298 1182 -636583.222144 +1311 1182 -30645221.93135 +1312 1182 -7638888.891397 +1313 1182 -18931013.9508 +1314 1182 -53208020.04453 +1315 1182 -1.534819602966e-06 +1316 1182 -46887250.21518 +1317 1182 -9746784.424485 +1318 1182 7638888.891396 +1319 1182 -4608097.279433 +1183 1183 595989855.9605 +1184 1183 122220465.8582 +1185 1183 1.132488250732e-06 +1186 1183 -59082879.09408 +1187 1183 -61110232.92908 +1200 1183 -30555555.55054 +1201 1183 -36016709.92406 +1202 1183 -13902558.23995 +1203 1183 -7.450580596924e-07 +1204 1183 57023920.20371 +1205 1183 30555116.4796 +1206 1183 30555555.55054 +1207 1183 -39454209.9235 +1208 1183 -16652558.23965 +1272 1183 7638888.891398 +1273 1183 -30663321.90996 +1274 1183 -13871472.89847 +1275 1183 1.035630702972e-06 +1276 1183 -25398826.77179 +1277 1183 7638779.123661 +1278 1183 -7638888.891398 +1279 1183 -8046134.402525 +1280 1183 6232693.774803 +1290 1183 2.995133399963e-06 +1291 1183 -95040068.27054 +1292 1183 -53805336.01132 +1293 1183 -9.536743164063e-07 +1294 1183 2097153.481574 +1295 1183 30555116.47959 +1296 1183 -2.235174179077e-06 +1297 1183 -8008818.28482 +1298 1183 23250219.53173 +1311 1183 -7638888.891397 +1312 1183 -28353405.24253 +1313 1183 -13107584.00933 +1314 1183 -1.318752765656e-06 +1315 1183 -19596660.10607 +1316 1183 7638779.123661 +1317 1183 7638888.891396 +1318 1183 -7454967.735663 +1319 1183 5468804.885664 +1184 1184 907581829.653 +1185 1184 -2546332.887327 +1186 1184 -61110232.92908 +1187 1184 30527909.01414 +1200 1184 -27181694.66288 +1201 1184 -13597002.68459 +1202 1184 -10829003.14197 +1203 1184 5092665.772129 +1204 1184 30555116.4796 +1205 1184 134412647.088 +1206 1184 30109971.99439 +1207 1184 -16958113.795 +1208 1184 -19995669.80713 +1272 1184 19567597.17295 +1273 1184 -13871472.89847 +1274 1184 -60464969.25217 +1275 1184 49815527.5467 +1276 1184 7638779.12366 +1277 1184 -72142989.75742 +1278 1184 5244680.501577 +1279 1184 6232693.774804 +1280 1184 -152469.232357 +1290 1184 -636583.2221379 +1291 1184 -54110891.56668 +1292 1184 -206419618.7154 +1293 1184 -2546332.887312 +1294 1184 30555116.47959 +1295 1184 -164838704.0269 +1296 1184 -636583.2221438 +1297 1184 23555775.08708 +1298 1184 25663714.57989 +1311 1184 -18931013.9508 +1312 1184 -13107584.00933 +1313 1184 -54305191.47237 +1314 1184 -47269194.65938 +1315 1184 7638779.123661 +1316 1184 -56670545.31551 +1317 1184 -4608097.279433 +1318 1184 5468804.885664 +1319 1184 1423975.212606 +1185 1185 669327989.9306 +1186 1185 -1.430511474609e-06 +1187 1185 -10185331.54429 +1188 1185 57028027.11004 +1189 1185 9.089708328247e-07 +1190 1185 -2546332.887327 +1203 1185 -45183976.67484 +1204 1185 -30555555.55054 +1205 1185 -27563639.10707 +1206 1185 -77421519.48389 +1207 1185 -5.513429641724e-07 +1208 1185 5092665.772129 +1209 1185 -48621476.67428 +1210 1185 30555555.55054 +1211 1185 29728027.55019 +1275 1185 -32955138.59878 +1276 1185 7638888.891398 +1277 1185 19567597.17295 +1278 1185 -59010186.71026 +1279 1185 1.542270183563e-06 +1280 1185 49433583.10251 +1281 1185 -10337951.09135 +1282 1185 -7638888.891398 +1283 1185 5244680.501577 +1293 1185 -66012341.70521 +1294 1185 2.853572368622e-06 +1295 1185 -636583.2221378 +1296 1185 20431686.98312 +1297 1185 -9.238719940186e-07 +1298 1185 -2546332.887312 +1299 1185 21018908.28051 +1300 1185 -2.346932888031e-06 +1301 1185 -636583.222144 +1314 1185 -30645221.93135 +1315 1185 -7638888.891397 +1316 1185 -18931013.9508 +1317 1185 -53208020.04453 +1318 1185 -1.534819602966e-06 +1319 1185 -46887250.21518 +1320 1185 -9746784.424485 +1321 1185 7638888.891396 +1322 1185 -4608097.279433 +1186 1186 595989855.9605 +1187 1186 122220465.8582 +1188 1186 1.132488250732e-06 +1189 1186 -59082879.09408 +1190 1186 -61110232.92908 +1203 1186 -30555555.55054 +1204 1186 -36016709.92406 +1205 1186 -13902558.23995 +1206 1186 -7.450580596924e-07 +1207 1186 57023920.20371 +1208 1186 30555116.4796 +1209 1186 30555555.55054 +1210 1186 -39454209.9235 +1211 1186 -16652558.23965 +1275 1186 7638888.891398 +1276 1186 -30663321.90996 +1277 1186 -13871472.89847 +1278 1186 1.035630702972e-06 +1279 1186 -25398826.77179 +1280 1186 7638779.123661 +1281 1186 -7638888.891398 +1282 1186 -8046134.402525 +1283 1186 6232693.774803 +1293 1186 2.995133399963e-06 +1294 1186 -95040068.27054 +1295 1186 -53805336.01132 +1296 1186 -9.536743164063e-07 +1297 1186 2097153.481574 +1298 1186 30555116.47959 +1299 1186 -2.235174179077e-06 +1300 1186 -8008818.28482 +1301 1186 23250219.53173 +1314 1186 -7638888.891397 +1315 1186 -28353405.24253 +1316 1186 -13107584.00933 +1317 1186 -1.318752765656e-06 +1318 1186 -19596660.10607 +1319 1186 7638779.123661 +1320 1186 7638888.891396 +1321 1186 -7454967.735663 +1322 1186 5468804.885664 +1187 1187 907581829.653 +1188 1187 -2546332.887327 +1189 1187 -61110232.92908 +1190 1187 30527909.01414 +1203 1187 -27181694.66288 +1204 1187 -13597002.68459 +1205 1187 -10829003.14197 +1206 1187 5092665.772129 +1207 1187 30555116.4796 +1208 1187 134412647.088 +1209 1187 30109971.99439 +1210 1187 -16958113.795 +1211 1187 -19995669.80713 +1275 1187 19567597.17295 +1276 1187 -13871472.89847 +1277 1187 -60464969.25217 +1278 1187 49815527.5467 +1279 1187 7638779.12366 +1280 1187 -72142989.75742 +1281 1187 5244680.501577 +1282 1187 6232693.774804 +1283 1187 -152469.232357 +1293 1187 -636583.2221379 +1294 1187 -54110891.56668 +1295 1187 -206419618.7154 +1296 1187 -2546332.887312 +1297 1187 30555116.47959 +1298 1187 -164838704.0269 +1299 1187 -636583.2221438 +1300 1187 23555775.08708 +1301 1187 25663714.57989 +1314 1187 -18931013.9508 +1315 1187 -13107584.00933 +1316 1187 -54305191.47237 +1317 1187 -47269194.65938 +1318 1187 7638779.123661 +1319 1187 -56670545.31551 +1320 1187 -4608097.279433 +1321 1187 5468804.885664 +1322 1187 1423975.212606 +1188 1188 535720103.1431 +1189 1188 9002155.882396 +1190 1188 -8544977.115715 +1191 1188 -52832367.09619 +1192 1188 -56640651.3947 +1193 1188 -7377596.330818 +1206 1188 -45183976.67484 +1207 1188 -30555555.55054 +1208 1188 -27563639.10707 +1209 1188 -48262168.01736 +1210 1188 18375579.56507 +1211 1188 1211801.457708 +1212 1188 -26550326.20373 +1213 1188 15486079.90679 +1214 1188 2784023.331262 +1278 1188 -32955138.59878 +1279 1188 7638888.891398 +1280 1188 19567597.17295 +1281 1188 -37020168.145 +1282 1188 3444209.011809 +1283 1188 33605164.82544 +1296 1188 -66012341.70521 +1297 1188 2.853572368622e-06 +1298 1188 -636583.2221378 +1299 1188 28568367.61238 +1300 1188 2250538.971708 +1301 1188 -2147300.291512 +1302 1188 -25990848.25866 +1303 1188 -14160162.85565 +1304 1188 10214737.96898 +1317 1188 -30645221.93135 +1318 1188 -7638888.891397 +1319 1188 -18931013.9508 +1320 1188 -42000541.15558 +1321 1188 4593894.893531 +1322 1188 -39062848.24116 +1323 1188 -12782232.44445 +1324 1188 3871519.978604 +1325 1188 -2550174.723511 +1189 1189 596568183.3813 +1190 1189 81646308.40731 +1191 1189 -56735590.12188 +1192 1189 -175245762.256 +1193 1189 -15673702.24174 +1206 1189 -30555555.55054 +1207 1189 -36016709.92406 +1208 1189 -13902558.23995 +1209 1189 18375579.56507 +1210 1189 51180094.94358 +1211 1189 15313665.99873 +1212 1189 15486079.90679 +1213 1189 -90779768.88629 +1214 1189 -9527444.358657 +1278 1189 7638888.891398 +1279 1189 -30663321.90996 +1280 1189 -13871472.89847 +1281 1189 3467943.693615 +1282 1189 -5987951.293276 +1283 1189 553673.964687 +1296 1189 2.995133399963e-06 +1297 1189 -95040068.27054 +1298 1189 -53805336.01132 +1299 1189 2250538.971707 +1300 1189 43780387.67943 +1301 1189 20402730.74043 +1302 1189 -14183897.53746 +1303 1189 -56594197.06368 +1304 1189 34727712.16061 +1317 1189 -7638888.891397 +1318 1189 -28353405.24253 +1319 1189 -13107584.00933 +1320 1189 4593894.893531 +1321 1189 -17139975.40311 +1322 1189 10863138.72183 +1323 1189 3871519.978604 +1324 1189 -28839593.123 +1325 1189 14284805.5813 +1190 1190 683100293.2876 +1191 1190 -7775098.943489 +1192 1190 -16899506.96192 +1193 1190 -11605546.9316 +1206 1190 -27181694.66288 +1207 1190 -13597002.68459 +1208 1190 -10829003.14197 +1209 1190 10760412.56725 +1210 1190 15619221.55424 +1211 1190 114614098.8367 +1212 1190 3547912.219649 +1213 1190 -9527444.358657 +1214 1190 -8186598.713413 +1278 1190 19567597.17295 +1279 1190 -13871472.89847 +1280 1190 -60464969.25217 +1281 1190 31699133.42531 +1282 1190 894158.2412029 +1283 1190 -45594941.93873 +1296 1190 -636583.2221379 +1297 1190 -54110891.56668 +1298 1190 -206419618.7154 +1299 1190 -2127175.46838 +1300 1190 20418832.32509 +1301 1190 -110189348.5657 +1302 1190 10220712.09006 +1303 1190 34700515.9782 +1304 1190 -36988737.34261 +1317 1190 -18931013.9508 +1318 1190 -13107584.00933 +1319 1190 -54305191.47237 +1320 1190 -37153126.01612 +1321 1190 10863138.72329 +1322 1190 -51173139.66418 +1323 1190 -2550174.723511 +1324 1190 14284805.5813 +1325 1190 -18432385.38669 +1191 1191 451174699.773 +1192 1191 12686634.78714 +1193 1191 2008579.463539 +1209 1191 -40983224.80108 +1210 1191 -28381980.02797 +1211 1191 -3931083.146571 +1212 1191 42151750.35842 +1213 1191 27710564.3627 +1214 1191 1252478.644547 +1215 1191 73565600.69527 +1216 1191 -16623616.68045 +1217 1191 -19413.59080505 +1218 1191 6725960.251957 +1219 1191 24392504.83829 +1220 1191 778974.1791444 +1281 1191 -26928306.79151 +1282 1191 9237870.715094 +1283 1191 5198285.296003 +1299 1191 -38329908.16593 +1300 1191 -14183897.53746 +1301 1191 -14013967.79219 +1302 1191 -26091846.39063 +1303 1191 3329117.509553 +1304 1191 9108174.376875 +1320 1191 -20891328.62495 +1321 1191 -7095495.010489 +1322 1191 -13022180.51333 +1323 1191 -50466960.84116 +1324 1191 7039307.107296 +1325 1191 -45843812.67481 +1326 1191 -28142572.64797 +1327 1191 -4313362.983367 +1328 1191 13754255.97847 +1329 1191 -17754872.39901 +1330 1191 5986460.19937 +1331 1191 -10422976.89274 +1192 1192 650089192.2842 +1193 1192 37908240.51927 +1209 1192 -28381980.02797 +1210 1192 -15397556.75659 +1211 1192 110188.2710273 +1212 1192 27710564.3627 +1213 1192 149985457.4504 +1214 1192 5622912.023309 +1215 1192 -4401394.460237 +1216 1192 14632289.89103 +1217 1192 -627668.483343 +1218 1192 24392504.83829 +1219 1192 -10983160.87137 +1220 1192 -764021.4159333 +1281 1192 6158580.476729 +1282 1192 -60247816.94801 +1283 1192 -22683651.68266 +1299 1192 -14160162.85565 +1300 1192 -68933256.97095 +1301 1192 -42828570.94811 +1302 1192 3329117.509553 +1303 1192 24036725.11853 +1304 1192 9835814.33498 +1320 1192 -7095495.010489 +1321 1192 -14494911.61067 +1322 1192 -9604397.379856 +1323 1192 7039307.107296 +1324 1192 -23617557.97339 +1325 1192 8445393.906125 +1326 1192 -1257807.426807 +1327 1192 -42838204.03708 +1328 1192 33174507.3862 +1329 1192 5986460.19937 +1330 1192 -22510773.43959 +1331 1192 16470717.63872 +1193 1193 701486591.9163 +1209 1193 -3549138.702378 +1210 1193 415743.8263821 +1211 1193 10879567.07286 +1212 1193 2398311.977692 +1213 1193 5928467.578815 +1214 1193 231150405.9677 +1215 1193 -19413.59080088 +1216 1193 -627668.4833433 +1217 1193 157368763.5337 +1218 1193 778974.1787681 +1219 1193 -764021.4159333 +1220 1193 56915295.69757 +1281 1193 3465523.530669 +1282 1193 -24063482.84713 +1283 1193 -38489307.95421 +1299 1193 -13999817.14035 +1300 1193 -42845108.80891 +1301 1193 -69892897.09532 +1302 1193 -9051270.064587 +1303 1193 7637089.986494 +1304 1193 -193866763.3494 +1320 1193 -13022180.51333 +1321 1193 -9604397.379856 +1322 1193 -25668168.01612 +1323 1193 -45461868.23006 +1324 1193 8445393.907579 +1325 1193 -105803535.3494 +1326 1193 5629255.977809 +1327 1193 33174507.3862 +1328 1193 -84266685.12418 +1329 1193 -10422976.89274 +1330 1193 16470717.63872 +1331 1193 -38294765.40783 +1194 1194 334663994.9653 +1195 1194 -1.788139343262e-07 +1196 1194 -5092665.772147 +1197 1194 28571305.22165 +1198 1194 6111111.110108 +1199 1194 3501139.111579 +1284 1194 -59010186.71026 +1285 1194 1.542270183563e-06 +1286 1194 49433583.10251 +1287 1194 -10337951.09135 +1288 1194 -7638888.891398 +1289 1194 5244680.501577 +1305 1194 10158551.82493 +1306 1194 -1.639127731323e-06 +1307 1194 -9988583.109361 +1308 1194 10509454.14025 +1309 1194 1527777.778278 +1310 1194 -1303569.389173 +1195 1195 297994927.9803 +1196 1195 61110232.92908 +1197 1195 -6111111.110106 +1198 1195 -29484147.88041 +1199 1195 -30249560.90903 +1284 1195 1.035630702972e-06 +1285 1195 -25398826.77179 +1286 1195 7638779.123661 +1287 1195 -7638888.891398 +1288 1195 -8046134.402525 +1289 1195 6232693.774803 +1305 1195 -1.132488250732e-06 +1306 1195 991285.0741574 +1307 1195 15277558.23979 +1308 1195 -1527777.77828 +1309 1195 -4004409.142409 +1310 1195 11701498.65478 +1196 1196 453790914.8265 +1197 1196 -7957194.219873 +1198 1196 -30860672.02004 +1199 1196 15416732.28475 +1284 1196 49815527.5467 +1285 1196 7638779.12366 +1286 1196 -72142989.75742 +1287 1196 5244680.501577 +1288 1196 6232693.774804 +1289 1196 -152469.232357 +1305 1196 9351972.443016 +1306 1196 15277558.23979 +1307 1196 -82572129.79111 +1308 1196 666986.1670292 +1309 1196 11701498.65463 +1310 1196 12831857.28995 +1197 1197 334663994.9653 +1198 1197 -1.788139343262e-07 +1199 1197 -5092665.772147 +1200 1197 28571305.22165 +1201 1197 6111111.110108 +1202 1197 3501139.111579 +1284 1197 -32955138.59878 +1285 1197 7638888.891398 +1286 1197 19567597.17295 +1287 1197 -59010186.71026 +1288 1197 1.542270183563e-06 +1289 1197 49433583.10251 +1290 1197 -10337951.09135 +1291 1197 -7638888.891398 +1292 1197 5244680.501577 +1305 1197 -33006170.85261 +1306 1197 -1527777.778278 +1307 1197 -4168152.723444 +1308 1197 10158551.82493 +1309 1197 -1.639127731323e-06 +1310 1197 -9988583.109361 +1311 1197 10509454.14025 +1312 1197 1527777.778278 +1313 1197 -1303569.389173 +1198 1198 297994927.9803 +1199 1198 61110232.92908 +1200 1198 -6111111.110106 +1201 1198 -29484147.88041 +1202 1198 -30249560.90903 +1284 1198 7638888.891398 +1285 1198 -30663321.90996 +1286 1198 -13871472.89847 +1287 1198 1.035630702972e-06 +1288 1198 -25398826.77179 +1289 1198 7638779.123661 +1290 1198 -7638888.891398 +1291 1198 -8046134.402525 +1292 1198 6232693.774803 +1305 1198 1527777.778281 +1306 1198 -47520034.13527 +1307 1198 -26979056.89458 +1308 1198 -1.132488250732e-06 +1309 1198 991285.0741574 +1310 1198 15277558.23979 +1311 1198 -1527777.77828 +1312 1198 -4004409.142409 +1313 1198 11701498.65478 +1199 1199 453790914.8265 +1200 1199 -7957194.219873 +1201 1199 -30860672.02004 +1202 1199 15416732.28475 +1284 1199 19567597.17295 +1285 1199 -13871472.89847 +1286 1199 -60464969.25217 +1287 1199 49815527.5467 +1288 1199 7638779.12366 +1289 1199 -72142989.75742 +1290 1199 5244680.501577 +1291 1199 6232693.774804 +1292 1199 -152469.232357 +1305 1199 3531569.501306 +1306 1199 -26979056.89443 +1307 1199 -103209809.3577 +1308 1199 9351972.443016 +1309 1199 15277558.23979 +1310 1199 -82572129.79111 +1311 1199 666986.1670292 +1312 1199 11701498.65463 +1313 1199 12831857.28995 +1200 1200 334663994.9653 +1201 1200 -1.788139343262e-07 +1202 1200 -5092665.772147 +1203 1200 28571305.22165 +1204 1200 6111111.110108 +1205 1200 3501139.111579 +1287 1200 -32955138.59878 +1288 1200 7638888.891398 +1289 1200 19567597.17295 +1290 1200 -59010186.71026 +1291 1200 1.542270183563e-06 +1292 1200 49433583.10251 +1293 1200 -10337951.09135 +1294 1200 -7638888.891398 +1295 1200 5244680.501577 +1308 1200 -33006170.85261 +1309 1200 -1527777.778278 +1310 1200 -4168152.723444 +1311 1200 10158551.82493 +1312 1200 -1.639127731323e-06 +1313 1200 -9988583.109361 +1314 1200 10509454.14025 +1315 1200 1527777.778278 +1316 1200 -1303569.389173 +1201 1201 297994927.9803 +1202 1201 61110232.92908 +1203 1201 -6111111.110106 +1204 1201 -29484147.88041 +1205 1201 -30249560.90903 +1287 1201 7638888.891398 +1288 1201 -30663321.90996 +1289 1201 -13871472.89847 +1290 1201 1.035630702972e-06 +1291 1201 -25398826.77179 +1292 1201 7638779.123661 +1293 1201 -7638888.891398 +1294 1201 -8046134.402525 +1295 1201 6232693.774803 +1308 1201 1527777.778281 +1309 1201 -47520034.13527 +1310 1201 -26979056.89458 +1311 1201 -1.132488250732e-06 +1312 1201 991285.0741574 +1313 1201 15277558.23979 +1314 1201 -1527777.77828 +1315 1201 -4004409.142409 +1316 1201 11701498.65478 +1202 1202 453790914.8265 +1203 1202 -7957194.219873 +1204 1202 -30860672.02004 +1205 1202 15416732.28475 +1287 1202 19567597.17295 +1288 1202 -13871472.89847 +1289 1202 -60464969.25217 +1290 1202 49815527.5467 +1291 1202 7638779.12366 +1292 1202 -72142989.75742 +1293 1202 5244680.501577 +1294 1202 6232693.774804 +1295 1202 -152469.232357 +1308 1202 3531569.501306 +1309 1202 -26979056.89443 +1310 1202 -103209809.3577 +1311 1202 9351972.443016 +1312 1202 15277558.23979 +1313 1202 -82572129.79111 +1314 1202 666986.1670292 +1315 1202 11701498.65463 +1316 1202 12831857.28995 +1203 1203 334663994.9653 +1204 1203 -1.788139343262e-07 +1205 1203 -5092665.772147 +1206 1203 28571305.22165 +1207 1203 6111111.110108 +1208 1203 3501139.111579 +1290 1203 -32955138.59878 +1291 1203 7638888.891398 +1292 1203 19567597.17295 +1293 1203 -59010186.71026 +1294 1203 1.542270183563e-06 +1295 1203 49433583.10251 +1296 1203 -10337951.09135 +1297 1203 -7638888.891398 +1298 1203 5244680.501577 +1311 1203 -33006170.85261 +1312 1203 -1527777.778278 +1313 1203 -4168152.723444 +1314 1203 10158551.82493 +1315 1203 -1.639127731323e-06 +1316 1203 -9988583.109361 +1317 1203 10509454.14025 +1318 1203 1527777.778278 +1319 1203 -1303569.389173 +1204 1204 297994927.9803 +1205 1204 61110232.92908 +1206 1204 -6111111.110106 +1207 1204 -29484147.88041 +1208 1204 -30249560.90903 +1290 1204 7638888.891398 +1291 1204 -30663321.90996 +1292 1204 -13871472.89847 +1293 1204 1.035630702972e-06 +1294 1204 -25398826.77179 +1295 1204 7638779.123661 +1296 1204 -7638888.891398 +1297 1204 -8046134.402525 +1298 1204 6232693.774803 +1311 1204 1527777.778281 +1312 1204 -47520034.13527 +1313 1204 -26979056.89458 +1314 1204 -1.132488250732e-06 +1315 1204 991285.0741574 +1316 1204 15277558.23979 +1317 1204 -1527777.77828 +1318 1204 -4004409.142409 +1319 1204 11701498.65478 +1205 1205 453790914.8265 +1206 1205 -7957194.219873 +1207 1205 -30860672.02004 +1208 1205 15416732.28475 +1290 1205 19567597.17295 +1291 1205 -13871472.89847 +1292 1205 -60464969.25217 +1293 1205 49815527.5467 +1294 1205 7638779.12366 +1295 1205 -72142989.75742 +1296 1205 5244680.501577 +1297 1205 6232693.774804 +1298 1205 -152469.232357 +1311 1205 3531569.501306 +1312 1205 -26979056.89443 +1313 1205 -103209809.3577 +1314 1205 9351972.443016 +1315 1205 15277558.23979 +1316 1205 -82572129.79111 +1317 1205 666986.1670292 +1318 1205 11701498.65463 +1319 1205 12831857.28995 +1206 1206 334663994.9653 +1207 1206 -1.788139343262e-07 +1208 1206 -5092665.772147 +1209 1206 28571305.22165 +1210 1206 6111111.110108 +1211 1206 3501139.111579 +1293 1206 -32955138.59878 +1294 1206 7638888.891398 +1295 1206 19567597.17295 +1296 1206 -59010186.71026 +1297 1206 1.542270183563e-06 +1298 1206 49433583.10251 +1299 1206 -10337951.09135 +1300 1206 -7638888.891398 +1301 1206 5244680.501577 +1314 1206 -33006170.85261 +1315 1206 -1527777.778278 +1316 1206 -4168152.723444 +1317 1206 10158551.82493 +1318 1206 -1.639127731323e-06 +1319 1206 -9988583.109361 +1320 1206 10509454.14025 +1321 1206 1527777.778278 +1322 1206 -1303569.389173 +1207 1207 297994927.9803 +1208 1207 61110232.92908 +1209 1207 -6111111.110106 +1210 1207 -29484147.88041 +1211 1207 -30249560.90903 +1293 1207 7638888.891398 +1294 1207 -30663321.90996 +1295 1207 -13871472.89847 +1296 1207 1.035630702972e-06 +1297 1207 -25398826.77179 +1298 1207 7638779.123661 +1299 1207 -7638888.891398 +1300 1207 -8046134.402525 +1301 1207 6232693.774803 +1314 1207 1527777.778281 +1315 1207 -47520034.13527 +1316 1207 -26979056.89458 +1317 1207 -1.132488250732e-06 +1318 1207 991285.0741574 +1319 1207 15277558.23979 +1320 1207 -1527777.77828 +1321 1207 -4004409.142409 +1322 1207 11701498.65478 +1208 1208 453790914.8265 +1209 1208 -7957194.219873 +1210 1208 -30860672.02004 +1211 1208 15416732.28475 +1293 1208 19567597.17295 +1294 1208 -13871472.89847 +1295 1208 -60464969.25217 +1296 1208 49815527.5467 +1297 1208 7638779.12366 +1298 1208 -72142989.75742 +1299 1208 5244680.501577 +1300 1208 6232693.774804 +1301 1208 -152469.232357 +1314 1208 3531569.501306 +1315 1208 -26979056.89443 +1316 1208 -103209809.3577 +1317 1208 9351972.443016 +1318 1208 15277558.23979 +1319 1208 -82572129.79111 +1320 1208 666986.1670292 +1321 1208 11701498.65463 +1322 1208 12831857.28995 +1209 1209 316858494.2791 +1210 1209 2174054.560357 +1211 1209 -27293244.44437 +1212 1209 13697255.5974 +1213 1209 -16612098.53789 +1214 1209 -3598584.9718 +1296 1209 -32955138.59878 +1297 1209 7638888.891398 +1298 1209 19567597.17295 +1299 1209 -49351204.34845 +1300 1209 4593894.893533 +1301 1209 42055901.74692 +1302 1209 -17990259.17954 +1303 1209 -7095495.010488 +1304 1209 11152125.05017 +1317 1209 -33006170.85261 +1318 1209 -1527777.778278 +1319 1209 -4168152.723444 +1320 1209 5365690.855964 +1321 1209 543513.6403558 +1322 1209 -15538450.00238 +1323 1209 -13153927.34598 +1324 1209 -4153024.636518 +1325 1209 5714867.644173 +1210 1210 296614594.907 +1211 1210 38457294.61539 +1212 1210 -28834320.7581 +1213 1210 -42198589.68467 +1214 1210 -6673474.180954 +1296 1210 7638888.891398 +1297 1210 -30663321.90996 +1298 1210 -13871472.89847 +1299 1210 4593894.893532 +1300 1210 -24490638.59597 +1301 1210 -3129916.831349 +1302 1210 -7095495.010488 +1303 1210 -11593842.16527 +1304 1210 9735880.404272 +1317 1210 1527777.778281 +1318 1210 -47520034.13527 +1319 1210 -26979056.89458 +1320 1210 543513.6403558 +1321 1210 304716.0104512 +1322 1210 9614323.658581 +1323 1210 -7208580.193077 +1324 1210 -27127888.67338 +1325 1210 24630242.56153 +1211 1211 416827404.7037 +1212 1211 -5508307.193711 +1213 1211 -6979029.73646 +1214 1211 52285028.52362 +1296 1211 19567597.17295 +1297 1211 -13871472.89847 +1298 1211 -60464969.25217 +1299 1211 40146179.52533 +1300 1211 -3129916.830046 +1301 1211 -70774908.17847 +1302 1211 11152125.05017 +1303 1211 9735880.404273 +1304 1211 -17931982.82838 +1317 1211 3531569.501306 +1318 1211 -26979056.89443 +1319 1211 -103209809.3577 +1320 1211 3801549.994444 +1321 1211 9614323.658581 +1322 1211 -92723636.11364 +1323 1211 9976812.088386 +1324 1211 24630242.56008 +1325 1211 -31137386.18803 +1212 1212 348089344.3927 +1213 1212 30384868.90779 +1214 1212 -532757.0458715 +1215 1212 -47381817.51693 +1216 1212 -36718606.26279 +1217 1212 -1130748.042973 +1218 1212 29348240.34016 +1219 1212 -8028586.156387 +1220 1212 -302189.6915584 +1299 1212 -18882906.05781 +1300 1212 3871519.978604 +1301 1212 4133158.612019 +1302 1212 -52416589.31391 +1303 1212 7039307.107297 +1304 1212 46863131.75478 +1320 1212 -23405666.92726 +1321 1212 -7208580.193078 +1322 1212 -12349021.24194 +1323 1212 -31165922.35193 +1324 1212 7885422.472098 +1325 1212 -8621462.035699 +1326 1212 -31982048.32961 +1327 1212 -9291317.583428 +1328 1212 20024245.33947 +1329 1212 -25975111.33797 +1330 1212 -2296351.781493 +1331 1212 7483836.459745 +1213 1213 403682108.9628 +1214 1213 13770445.11113 +1215 1213 -36718606.26279 +1216 1213 -31273577.53471 +1217 1213 -764021.4159336 +1218 1213 -20250808.3766 +1219 1213 -30061183.33955 +1220 1213 -2428417.178885 +1299 1213 3871519.978604 +1300 1213 -34940266.73636 +1301 1213 -19048527.76298 +1302 1213 7039307.107298 +1303 1213 -25567186.44614 +1304 1213 -5547661.647057 +1320 1213 -4153024.636519 +1321 1213 -37379628.25466 +1322 1213 -28043368.541 +1323 1213 7885422.472099 +1324 1213 -17228485.8815 +1325 1213 3460477.176094 +1326 1213 -9291317.583428 +1327 1213 -27845964.41357 +1328 1213 16470717.63872 +1329 1213 -5351907.338053 +1330 1213 -40866712.58626 +1331 1213 32708363.13622 +1214 1214 547608641.2762 +1215 1214 -1130748.042973 +1216 1214 -764021.4159337 +1217 1214 36624879.03423 +1218 1214 -1066078.580326 +1219 1214 -2428417.178885 +1220 1214 98796169.1597 +1299 1214 4133158.612019 +1300 1214 -19048527.76298 +1301 1214 -34700848.35564 +1302 1214 47245076.19879 +1303 1214 -5547661.645754 +1304 1214 -111002544.6101 +1320 1214 -6941243.464199 +1321 1214 -28043368.5423 +1322 1214 -58475358.40478 +1323 1214 10301871.29453 +1324 1214 3460477.176094 +1325 1214 -179825744.4227 +1326 1214 20024245.33947 +1327 1214 16470717.63872 +1328 1214 -43629956.38181 +1329 1214 11537725.35197 +1330 1214 32708363.13622 +1331 1214 -62574199.34102 +1215 1215 234181065.9089 +1216 1215 41068061.12088 +1217 1215 655987.6646829 +1218 1215 10431514.53318 +1219 1215 51939.60213825 +1220 1215 494173.9690943 +1302 1215 -29392572.6484 +1303 1215 -1257807.426808 +1304 1215 -5646438.46269 +1323 1215 -33232048.33004 +1324 1215 -9291317.583429 +1325 1215 -20600754.67387 +1326 1215 -35105760.6537 +1327 1215 10424474.09649 +1328 1215 8292734.7597 +1329 1215 -37667800.1781 +1330 1215 124650.9137491 +1331 1215 -30795541.62314 +1216 1216 218635210.0587 +1217 1216 627668.4833469 +1218 1216 12274161.82235 +1219 1216 68802441.20539 +1220 1216 764021.4159354 +1302 1216 -4313362.983367 +1303 1216 -44088204.03752 +1304 1216 -33492159.26951 +1323 1216 -9291317.583429 +1324 1216 -29095964.41399 +1325 1216 -16862615.70556 +1326 1216 10424474.09649 +1327 1216 -39029920.93737 +1328 1216 6825492.607223 +1329 1216 3180206.470309 +1330 1216 -23184092.42136 +1331 1216 3529282.367847 +1217 1217 390198736.3446 +1218 1217 494173.9690994 +1219 1217 764021.4159352 +1220 1217 137931257.4087 +1302 1217 -13771438.46354 +1303 1217 -33492159.26951 +1304 1217 -87600018.45868 +1323 1217 -20600754.67387 +1324 1217 -16862615.70556 +1325 1217 -46963289.71627 +1326 1217 -7957265.237631 +1327 1217 -6507840.72392 +1328 1217 -152668106.4805 +1329 1217 -30795541.62496 +1330 1217 -3137384.301009 +1331 1217 -73830403.50521 +1218 1218 175996103.0724 +1219 1218 -16415858.28404 +1220 1218 1320708.210737 +1302 1218 -19004872.39944 +1303 1218 5986460.19937 +1304 1218 10801328.66978 +1323 1218 -29725111.33676 +1324 1218 -5351907.338053 +1325 1218 -12107830.2037 +1326 1218 -37667800.1781 +1327 1218 3180206.47031 +1328 1218 31053763.92235 +1329 1218 -24853125.18453 +1330 1218 -3814759.331626 +1331 1218 -3896151.277573 +1219 1219 194743721.2032 +1220 1219 2428417.178889 +1302 1219 5986460.19937 +1303 1219 -23760773.44002 +1304 1219 -16862615.70556 +1323 1219 -2296351.781494 +1324 1219 -44616712.58506 +1325 1219 -33958303.5195 +1326 1219 124650.9137499 +1327 1219 -23184092.42136 +1328 1219 3529282.367847 +1329 1219 -3814759.331626 +1330 1219 -19689330.6524 +1331 1219 7291636.857209 +1220 1220 299695459.5944 +1302 1220 10801328.66978 +1303 1220 -16862615.70556 +1304 1220 -41628098.7423 +1323 1220 -7671996.867094 +1324 1220 -33958303.5195 +1325 1220 -72574199.3378 +1326 1220 31053763.92035 +1327 1220 -3137384.301009 +1328 1220 -73830403.50521 +1329 1220 4593570.943256 +1330 1220 -6041696.473933 +1331 1220 -108636389.3449 +1221 1221 392409175.4658 +1222 1221 33611111.10558 +1223 1221 -18921677.97532 +1224 1221 -173081388.0675 +1225 1221 -33624506.06547 +1226 1221 14444361.39273 +1227 1221 1431297.732108 +1228 1221 26902283.84436 +1229 1221 9655347.358825 +1332 1221 35932670.30059 +1333 1221 9166666.669679 +1334 1221 9311563.653784 +1335 1221 -72925641.46158 +1336 1221 -9166747.055676 +1337 1221 -43478968.03166 +1338 1221 -7497354.851903 +1339 1221 7333413.72174 +1340 1221 -9080099.689708 +1222 1222 341973871.613 +1223 1222 30282406.91647 +1224 1222 -33631203.54542 +1225 1222 -15065409.46899 +1226 1222 19484896.97789 +1227 1222 40353425.76654 +1228 1222 1431297.732101 +1229 1222 -13443330.95707 +1332 1222 9166666.669678 +1333 1222 22181563.40434 +1334 1222 5180609.664774 +1335 1222 -9166787.248676 +1336 1222 -29841516.44517 +1337 1222 -9524419.110191 +1338 1222 11000120.58261 +1339 1222 -7497354.8519 +1340 1222 10895952.52268 +1223 1223 443104893.4996 +1224 1223 12205703.10143 +1225 1223 15281564.4366 +1226 1223 34188531.48329 +1227 1223 14483021.03824 +1228 1223 -8962220.638046 +1229 1223 3816793.952288 +1332 1223 -7806863.548506 +1333 1223 -8513909.758068 +1334 1223 -68673244.4318 +1335 1223 -43444243.01831 +1336 1223 -9329934.937092 +1337 1223 -59307696.78438 +1338 1223 -13620149.53456 +1339 1223 7263968.348454 +1340 1223 -19992946.27174 +1224 1224 662031295.7794 +1225 1224 33644598.50531 +1226 1224 -15598790.43683 +1227 1224 6223512.930091 +1228 1224 -33624506.06548 +1229 1224 -13793087.22804 +1230 1224 -109230745.6082 +1231 1224 1.281499862671e-06 +1232 1224 3425959.474268 +1233 1224 -51177807.60464 +1234 1224 33611111.10559 +1235 1224 13790517.64469 +1332 1224 -71369389.94283 +1333 1224 -9166787.24867 +1334 1224 42147892.99313 +1335 1224 76553135.92261 +1336 1224 9166867.634673 +1337 1224 781226.2244361 +1338 1224 -18699525.19313 +1339 1224 -9166747.055676 +1340 1224 11379035.3452 +1341 1224 -59172122.54065 +1342 1224 4.395842552185e-07 +1343 1224 -42928937.05631 +1344 1224 -19947608.24497 +1345 1224 9166666.669675 +1346 1224 -11378935.65847 +1225 1225 571259805.1183 +1226 1225 43075945.84504 +1227 1225 -33631203.54543 +1228 1225 -111441208.5227 +1229 1225 -23958771.83004 +1230 1225 9.387731552124e-07 +1231 1225 38659326.41933 +1232 1225 13888687.59834 +1233 1225 33611111.10559 +1234 1225 -41093760.8976 +1235 1225 -7791566.021395 +1332 1225 -9166747.055672 +1333 1225 -28285264.92641 +1334 1225 7788270.809731 +1335 1225 9166867.634673 +1336 1225 51801215.86321 +1337 1225 -2152764.494718 +1338 1225 -9166787.248675 +1339 1225 -50782746.60544 +1340 1225 35402941.77273 +1341 1225 4.619359970093e-07 +1342 1225 -18838452.02672 +1343 1225 -694433.1761459 +1344 1225 9166666.669675 +1345 1225 -17197404.95283 +1346 1225 8940966.590895 +1226 1226 679585775.4118 +1227 1226 -13412427.57498 +1228 1226 -26066650.19218 +1229 1226 3548849.435559 +1230 1226 1203737.252411 +1231 1226 13888687.59834 +1232 1226 83675565.4165 +1233 1226 13408573.19995 +1234 1226 -7486010.465602 +1235 1226 -15846293.82194 +1332 1226 42113167.97979 +1333 1226 7593861.729456 +1334 1226 -55157692.73435 +1335 1226 781320.0962051 +1336 1226 -2152689.398522 +1337 1226 -91946096.11431 +1338 1226 11379085.18856 +1339 1226 35569610.71641 +1340 1226 -53430905.74636 +1341 1226 -42894214.83411 +1342 1226 -694433.1761459 +1343 1226 -55531090.78464 +1344 1226 -11378935.65847 +1345 1226 8940966.590895 +1346 1226 -20295098.63508 +1227 1227 392409175.4658 +1228 1227 33611111.10558 +1229 1227 -18921677.97532 +1230 1227 -49447220.48372 +1231 1227 -33611111.10559 +1232 1227 -12251149.01771 +1233 1227 -173081388.0675 +1234 1227 -33624506.06547 +1235 1227 14444361.39273 +1236 1227 1431297.732108 +1237 1227 26902283.84436 +1238 1227 9655347.358825 +1332 1227 -4579449.609996 +1333 1227 11000120.58261 +1334 1227 12057631.64322 +1335 1227 -14225493.76444 +1336 1227 -9166787.248675 +1337 1227 -10019112.65448 +1338 1227 35932670.30059 +1339 1227 9166666.669679 +1340 1227 9311563.653784 +1341 1227 -18482764.4945 +1342 1227 -9166666.669676 +1343 1227 -10076852.32471 +1344 1227 -72925641.46158 +1345 1227 -9166747.055676 +1346 1227 -43478968.03166 +1347 1227 -7497354.851903 +1348 1227 7333413.72174 +1349 1227 -9080099.689708 +1228 1228 341973871.613 +1229 1228 30282406.91647 +1230 1228 -33611111.10559 +1231 1228 -39363173.77667 +1232 1228 -6097121.576942 +1233 1228 -33631203.54542 +1234 1228 -15065409.46899 +1235 1228 19484896.97789 +1236 1228 40353425.76654 +1237 1228 1431297.732101 +1238 1228 -13443330.95707 +1332 1228 7333413.72174 +1333 1228 -4579449.61 +1334 1228 -6430626.286135 +1335 1228 -9166747.055675 +1336 1228 -46308715.17675 +1337 1228 -32902986.62891 +1338 1228 9166666.669678 +1339 1228 22181563.40434 +1340 1228 5180609.664774 +1341 1228 -9166666.669676 +1342 1228 -15732561.20235 +1343 1228 -8246533.414749 +1344 1228 -9166787.248676 +1345 1228 -29841516.44517 +1346 1228 -9524419.110191 +1347 1228 11000120.58261 +1348 1228 -7497354.8519 +1349 1228 10895952.52268 +1229 1229 443104893.4996 +1230 1229 -12633093.46245 +1231 1229 -6402677.132734 +1232 1229 -11231394.83281 +1233 1229 12205703.10143 +1234 1229 15281564.4366 +1235 1229 34188531.48329 +1236 1229 14483021.03824 +1237 1229 -8962220.638046 +1238 1229 3816793.952288 +1332 1229 8038421.095477 +1333 1229 -9645939.429201 +1334 1229 -12211865.62666 +1335 1229 -10019068.77473 +1336 1229 -33069655.68813 +1337 1229 -41500155.26984 +1338 1229 -7806863.548506 +1339 1229 -8513909.758068 +1340 1229 -68673244.4318 +1341 1229 -10076852.32471 +1342 1229 -8246533.414749 +1343 1229 -16388848.63381 +1344 1229 -43444243.01831 +1345 1229 -9329934.937092 +1346 1229 -59307696.78438 +1347 1229 -13620149.53456 +1348 1229 7263968.348454 +1349 1229 -19992946.27174 +1230 1230 645455824.6572 +1231 1230 3.814697265625e-06 +1232 1230 -4629696.72672 +1233 1230 69286959.53708 +1234 1230 -2.101063728333e-06 +1235 1230 -1157424.182251 +1239 1230 -109230745.6082 +1240 1230 1.281499862671e-06 +1241 1230 3425959.474268 +1242 1230 -51177807.60464 +1243 1230 33611111.10559 +1244 1230 13790517.64469 +1335 1230 -58783069.51046 +1336 1230 1.639127731323e-06 +1337 1230 42697451.81849 +1338 1230 -19844426.42677 +1339 1230 -9166666.669679 +1340 1230 11321064.34898 +1341 1230 57430602.85087 +1342 1230 3.8743019104e-06 +1343 1230 231485.2378496 +1344 1230 -6249019.844286 +1345 1230 -7.443130016327e-06 +1346 1230 57871.30949415 +1350 1230 -59172122.54065 +1351 1230 4.395842552185e-07 +1352 1230 -42928937.05631 +1353 1230 -19947608.24497 +1354 1230 9166666.669675 +1355 1230 -11378935.65847 +1231 1231 564783451.0405 +1232 1231 55554750.36598 +1233 1231 -3.129243850708e-06 +1234 1231 -58435019.09619 +1235 1231 -28666264.07173 +1239 1231 9.387731552124e-07 +1240 1231 38659326.41933 +1241 1231 13888687.59834 +1242 1231 33611111.10559 +1243 1231 -41093760.8976 +1244 1231 -7791566.021395 +1335 1231 6.034970283508e-07 +1336 1231 -18449398.9965 +1337 1231 -694433.1761458 +1338 1231 -9166666.669679 +1339 1231 -17094223.13462 +1340 1231 8871522.146427 +1341 1231 4.231929779053e-06 +1342 1231 35428976.52455 +1343 1231 -2777732.703215 +1344 1231 -7.599592208862e-06 +1345 1231 -41082283.77936 +1346 1231 35638866.34597 +1350 1231 4.619359970093e-07 +1351 1231 -18838452.02672 +1352 1231 -694433.1761459 +1353 1231 9166666.669675 +1354 1231 -17197404.95283 +1355 1231 8940966.590895 +1232 1232 756192654.5709 +1233 1232 -1157424.182251 +1234 1232 -26888486.29425 +1235 1232 51063391.07047 +1239 1232 1203737.252411 +1240 1232 13888687.59834 +1241 1232 83675565.4165 +1242 1232 13408573.19995 +1243 1232 -7486010.465602 +1244 1232 -15846293.82194 +1335 1232 42662729.59629 +1336 1232 -694433.1761458 +1337 1232 -54493616.03735 +1338 1232 11321064.34898 +1339 1232 8871522.146428 +1340 1232 -20019947.11985 +1341 1232 231485.2378493 +1342 1232 -2777732.703215 +1343 1232 -110039912.4136 +1344 1232 57871.30949473 +1345 1232 35611088.56821 +1346 1232 -53128242.27036 +1350 1232 -42894214.83411 +1351 1232 -694433.1761459 +1352 1232 -55531090.78464 +1353 1232 -11378935.65847 +1354 1232 8940966.590895 +1355 1232 -20295098.63508 +1233 1233 662031295.7794 +1234 1233 33644598.50531 +1235 1233 -15598790.43683 +1236 1233 6223512.930091 +1237 1233 -33624506.06548 +1238 1233 -13793087.22804 +1239 1233 -49447220.48372 +1240 1233 -33611111.10559 +1241 1233 -12251149.01771 +1242 1233 -109230745.6082 +1243 1233 1.281499862671e-06 +1244 1233 3425959.474268 +1245 1233 -51177807.60464 +1246 1233 33611111.10559 +1247 1233 13790517.64469 +1335 1233 -18391419.7975 +1336 1233 9166666.669678 +1337 1233 10018981.01522 +1338 1233 -71369389.94283 +1339 1233 -9166787.24867 +1340 1233 42147892.99313 +1341 1233 -413319.0876746 +1342 1233 3.017485141754e-06 +1343 1233 57871.30948708 +1344 1233 76553135.92261 +1345 1233 9166867.634673 +1346 1233 781226.2244361 +1347 1233 -18699525.19313 +1348 1233 -9166747.055676 +1349 1233 11379035.3452 +1350 1233 -18482764.4945 +1351 1233 -9166666.669676 +1352 1233 -10076852.32471 +1353 1233 -59172122.54065 +1354 1233 4.395842552185e-07 +1355 1233 -42928937.05631 +1356 1233 -19947608.24497 +1357 1233 9166666.669675 +1358 1233 -11378935.65847 +1234 1234 571259805.1183 +1235 1234 43075945.84504 +1236 1234 -33631203.54543 +1237 1234 -111441208.5227 +1238 1234 -23958771.83004 +1239 1234 -33611111.10559 +1240 1234 -39363173.77667 +1241 1234 -6097121.576942 +1242 1234 9.387731552124e-07 +1243 1234 38659326.41933 +1244 1234 13888687.59834 +1245 1234 33611111.10559 +1246 1234 -41093760.8976 +1247 1234 -7791566.021395 +1335 1234 9166666.669678 +1336 1234 -15641216.50536 +1337 1234 -8177088.970282 +1338 1234 -9166747.055672 +1339 1234 -28285264.92641 +1340 1234 7788270.809731 +1341 1234 4.06801700592e-06 +1342 1234 -35246583.02275 +1343 1234 -32861133.64276 +1344 1234 9166867.634673 +1345 1234 51801215.86321 +1346 1234 -2152764.494718 +1347 1234 -9166787.248675 +1348 1234 -50782746.60544 +1349 1234 35402941.77273 +1350 1234 -9166666.669676 +1351 1234 -15732561.20235 +1352 1234 -8246533.414749 +1353 1234 4.619359970093e-07 +1354 1234 -18838452.02672 +1355 1234 -694433.1761459 +1356 1234 9166666.669675 +1357 1234 -17197404.95283 +1358 1234 8940966.590895 +1235 1235 679585775.4118 +1236 1235 -13412427.57498 +1237 1235 -26066650.19218 +1238 1235 3548849.435559 +1239 1235 -12633093.46245 +1240 1235 -6402677.132734 +1241 1235 -11231394.83281 +1242 1235 1203737.252411 +1243 1235 13888687.59834 +1244 1235 83675565.4165 +1245 1235 13408573.19995 +1246 1235 -7486010.465602 +1247 1235 -15846293.82194 +1335 1235 10018981.01522 +1336 1235 -8177088.970282 +1337 1235 -16145262.77514 +1338 1235 42113167.97979 +1339 1235 7593861.729456 +1340 1235 -55157692.73435 +1341 1235 57871.30948763 +1342 1235 -32833355.865 +1343 1235 -37566373.58606 +1344 1235 781320.0962051 +1345 1235 -2152689.398522 +1346 1235 -91946096.11431 +1347 1235 11379085.18856 +1348 1235 35569610.71641 +1349 1235 -53430905.74636 +1350 1235 -10076852.32471 +1351 1235 -8246533.414749 +1352 1235 -16388848.63381 +1353 1235 -42894214.83411 +1354 1235 -694433.1761459 +1355 1235 -55531090.78464 +1356 1235 -11378935.65847 +1357 1235 8940966.590895 +1358 1235 -20295098.63508 +1236 1236 392409175.4658 +1237 1236 33611111.10558 +1238 1236 -18921677.97532 +1242 1236 -49447220.48372 +1243 1236 -33611111.10559 +1244 1236 -12251149.01771 +1245 1236 -173081388.0675 +1246 1236 -33624506.06547 +1247 1236 14444361.39273 +1248 1236 1431297.732108 +1249 1236 26902283.84436 +1250 1236 9655347.358825 +1338 1236 -4579449.609996 +1339 1236 11000120.58261 +1340 1236 12057631.64322 +1344 1236 -14225493.76444 +1345 1236 -9166787.248675 +1346 1236 -10019112.65448 +1347 1236 35932670.30059 +1348 1236 9166666.669679 +1349 1236 9311563.653784 +1353 1236 -18482764.4945 +1354 1236 -9166666.669676 +1355 1236 -10076852.32471 +1356 1236 -72925641.46158 +1357 1236 -9166747.055676 +1358 1236 -43478968.03166 +1359 1236 -7497354.851903 +1360 1236 7333413.72174 +1361 1236 -9080099.689708 +1237 1237 341973871.613 +1238 1237 30282406.91647 +1242 1237 -33611111.10559 +1243 1237 -39363173.77667 +1244 1237 -6097121.576942 +1245 1237 -33631203.54542 +1246 1237 -15065409.46899 +1247 1237 19484896.97789 +1248 1237 40353425.76654 +1249 1237 1431297.732101 +1250 1237 -13443330.95707 +1338 1237 7333413.72174 +1339 1237 -4579449.61 +1340 1237 -6430626.286135 +1344 1237 -9166747.055675 +1345 1237 -46308715.17675 +1346 1237 -32902986.62891 +1347 1237 9166666.669678 +1348 1237 22181563.40434 +1349 1237 5180609.664774 +1353 1237 -9166666.669676 +1354 1237 -15732561.20235 +1355 1237 -8246533.414749 +1356 1237 -9166787.248676 +1357 1237 -29841516.44517 +1358 1237 -9524419.110191 +1359 1237 11000120.58261 +1360 1237 -7497354.8519 +1361 1237 10895952.52268 +1238 1238 443104893.4996 +1242 1238 -12633093.46245 +1243 1238 -6402677.132734 +1244 1238 -11231394.83281 +1245 1238 12205703.10143 +1246 1238 15281564.4366 +1247 1238 34188531.48329 +1248 1238 14483021.03824 +1249 1238 -8962220.638046 +1250 1238 3816793.952288 +1338 1238 8038421.095477 +1339 1238 -9645939.429201 +1340 1238 -12211865.62666 +1344 1238 -10019068.77473 +1345 1238 -33069655.68813 +1346 1238 -41500155.26984 +1347 1238 -7806863.548506 +1348 1238 -8513909.758068 +1349 1238 -68673244.4318 +1353 1238 -10076852.32471 +1354 1238 -8246533.414749 +1355 1238 -16388848.63381 +1356 1238 -43444243.01831 +1357 1238 -9329934.937092 +1358 1238 -59307696.78438 +1359 1238 -13620149.53456 +1360 1238 7263968.348454 +1361 1238 -19992946.27174 +1239 1239 645455824.6572 +1240 1239 3.814697265625e-06 +1241 1239 -4629696.72672 +1242 1239 69286959.53708 +1243 1239 -2.101063728333e-06 +1244 1239 -1157424.182251 +1251 1239 -109230745.6082 +1252 1239 1.281499862671e-06 +1253 1239 3425959.474268 +1254 1239 -51177807.60464 +1255 1239 33611111.10559 +1256 1239 13790517.64469 +1341 1239 -58783069.51046 +1342 1239 1.639127731323e-06 +1343 1239 42697451.81849 +1344 1239 -19844426.42677 +1345 1239 -9166666.669679 +1346 1239 11321064.34898 +1350 1239 57430602.85087 +1351 1239 3.8743019104e-06 +1352 1239 231485.2378496 +1353 1239 -6249019.844286 +1354 1239 -7.443130016327e-06 +1355 1239 57871.30949415 +1362 1239 -59172122.54065 +1363 1239 4.395842552185e-07 +1364 1239 -42928937.05631 +1365 1239 -19947608.24497 +1366 1239 9166666.669675 +1367 1239 -11378935.65847 +1240 1240 564783451.0405 +1241 1240 55554750.36598 +1242 1240 -3.129243850708e-06 +1243 1240 -58435019.09619 +1244 1240 -28666264.07173 +1251 1240 9.387731552124e-07 +1252 1240 38659326.41933 +1253 1240 13888687.59834 +1254 1240 33611111.10559 +1255 1240 -41093760.8976 +1256 1240 -7791566.021395 +1341 1240 6.034970283508e-07 +1342 1240 -18449398.9965 +1343 1240 -694433.1761458 +1344 1240 -9166666.669679 +1345 1240 -17094223.13462 +1346 1240 8871522.146427 +1350 1240 4.231929779053e-06 +1351 1240 35428976.52455 +1352 1240 -2777732.703215 +1353 1240 -7.599592208862e-06 +1354 1240 -41082283.77936 +1355 1240 35638866.34597 +1362 1240 4.619359970093e-07 +1363 1240 -18838452.02672 +1364 1240 -694433.1761459 +1365 1240 9166666.669675 +1366 1240 -17197404.95283 +1367 1240 8940966.590895 +1241 1241 756192654.5709 +1242 1241 -1157424.182251 +1243 1241 -26888486.29425 +1244 1241 51063391.07047 +1251 1241 1203737.252411 +1252 1241 13888687.59834 +1253 1241 83675565.4165 +1254 1241 13408573.19995 +1255 1241 -7486010.465602 +1256 1241 -15846293.82194 +1341 1241 42662729.59629 +1342 1241 -694433.1761458 +1343 1241 -54493616.03735 +1344 1241 11321064.34898 +1345 1241 8871522.146428 +1346 1241 -20019947.11985 +1350 1241 231485.2378493 +1351 1241 -2777732.703215 +1352 1241 -110039912.4136 +1353 1241 57871.30949473 +1354 1241 35611088.56821 +1355 1241 -53128242.27036 +1362 1241 -42894214.83411 +1363 1241 -694433.1761459 +1364 1241 -55531090.78464 +1365 1241 -11378935.65847 +1366 1241 8940966.590895 +1367 1241 -20295098.63508 +1242 1242 645455824.6572 +1243 1242 3.814697265625e-06 +1244 1242 -4629696.72672 +1245 1242 69286959.53708 +1246 1242 -2.101063728333e-06 +1247 1242 -1157424.182251 +1251 1242 -49447220.48372 +1252 1242 -33611111.10559 +1253 1242 -12251149.01771 +1254 1242 -109230745.6082 +1255 1242 1.281499862671e-06 +1256 1242 3425959.474268 +1257 1242 -51177807.60464 +1258 1242 33611111.10559 +1259 1242 13790517.64469 +1341 1242 -18391419.7975 +1342 1242 9166666.669678 +1343 1242 10018981.01522 +1344 1242 -58783069.51046 +1345 1242 1.639127731323e-06 +1346 1242 42697451.81849 +1347 1242 -19844426.42677 +1348 1242 -9166666.669679 +1349 1242 11321064.34898 +1350 1242 -413319.0876746 +1351 1242 3.017485141754e-06 +1352 1242 57871.30948708 +1353 1242 57430602.85087 +1354 1242 3.8743019104e-06 +1355 1242 231485.2378496 +1356 1242 -6249019.844286 +1357 1242 -7.443130016327e-06 +1358 1242 57871.30949415 +1362 1242 -18482764.4945 +1363 1242 -9166666.669676 +1364 1242 -10076852.32471 +1365 1242 -59172122.54065 +1366 1242 4.395842552185e-07 +1367 1242 -42928937.05631 +1368 1242 -19947608.24497 +1369 1242 9166666.669675 +1370 1242 -11378935.65847 +1243 1243 564783451.0405 +1244 1243 55554750.36598 +1245 1243 -3.129243850708e-06 +1246 1243 -58435019.09619 +1247 1243 -28666264.07173 +1251 1243 -33611111.10559 +1252 1243 -39363173.77667 +1253 1243 -6097121.576942 +1254 1243 9.387731552124e-07 +1255 1243 38659326.41933 +1256 1243 13888687.59834 +1257 1243 33611111.10559 +1258 1243 -41093760.8976 +1259 1243 -7791566.021395 +1341 1243 9166666.669678 +1342 1243 -15641216.50536 +1343 1243 -8177088.970282 +1344 1243 6.034970283508e-07 +1345 1243 -18449398.9965 +1346 1243 -694433.1761458 +1347 1243 -9166666.669679 +1348 1243 -17094223.13462 +1349 1243 8871522.146427 +1350 1243 4.06801700592e-06 +1351 1243 -35246583.02275 +1352 1243 -32861133.64276 +1353 1243 4.231929779053e-06 +1354 1243 35428976.52455 +1355 1243 -2777732.703215 +1356 1243 -7.599592208862e-06 +1357 1243 -41082283.77936 +1358 1243 35638866.34597 +1362 1243 -9166666.669676 +1363 1243 -15732561.20235 +1364 1243 -8246533.414749 +1365 1243 4.619359970093e-07 +1366 1243 -18838452.02672 +1367 1243 -694433.1761459 +1368 1243 9166666.669675 +1369 1243 -17197404.95283 +1370 1243 8940966.590895 +1244 1244 756192654.5709 +1245 1244 -1157424.182251 +1246 1244 -26888486.29425 +1247 1244 51063391.07047 +1251 1244 -12633093.46245 +1252 1244 -6402677.132734 +1253 1244 -11231394.83281 +1254 1244 1203737.252411 +1255 1244 13888687.59834 +1256 1244 83675565.4165 +1257 1244 13408573.19995 +1258 1244 -7486010.465602 +1259 1244 -15846293.82194 +1341 1244 10018981.01522 +1342 1244 -8177088.970282 +1343 1244 -16145262.77514 +1344 1244 42662729.59629 +1345 1244 -694433.1761458 +1346 1244 -54493616.03735 +1347 1244 11321064.34898 +1348 1244 8871522.146428 +1349 1244 -20019947.11985 +1350 1244 57871.30948763 +1351 1244 -32833355.865 +1352 1244 -37566373.58606 +1353 1244 231485.2378493 +1354 1244 -2777732.703215 +1355 1244 -110039912.4136 +1356 1244 57871.30949473 +1357 1244 35611088.56821 +1358 1244 -53128242.27036 +1362 1244 -10076852.32471 +1363 1244 -8246533.414749 +1364 1244 -16388848.63381 +1365 1244 -42894214.83411 +1366 1244 -694433.1761459 +1367 1244 -55531090.78464 +1368 1244 -11378935.65847 +1369 1244 8940966.590895 +1370 1244 -20295098.63508 +1245 1245 662031295.7794 +1246 1245 33644598.50531 +1247 1245 -15598790.43683 +1248 1245 6223512.930091 +1249 1245 -33624506.06548 +1250 1245 -13793087.22804 +1254 1245 -49447220.48372 +1255 1245 -33611111.10559 +1256 1245 -12251149.01771 +1257 1245 -109230745.6082 +1258 1245 1.281499862671e-06 +1259 1245 3425959.474268 +1260 1245 -51177807.60464 +1261 1245 33611111.10559 +1262 1245 13790517.64469 +1344 1245 -18391419.7975 +1345 1245 9166666.669678 +1346 1245 10018981.01522 +1347 1245 -71369389.94283 +1348 1245 -9166787.24867 +1349 1245 42147892.99313 +1353 1245 -413319.0876746 +1354 1245 3.017485141754e-06 +1355 1245 57871.30948708 +1356 1245 76553135.92261 +1357 1245 9166867.634673 +1358 1245 781226.2244361 +1359 1245 -18699525.19313 +1360 1245 -9166747.055676 +1361 1245 11379035.3452 +1365 1245 -18482764.4945 +1366 1245 -9166666.669676 +1367 1245 -10076852.32471 +1368 1245 -59172122.54065 +1369 1245 4.395842552185e-07 +1370 1245 -42928937.05631 +1371 1245 -19947608.24497 +1372 1245 9166666.669675 +1373 1245 -11378935.65847 +1246 1246 571259805.1183 +1247 1246 43075945.84504 +1248 1246 -33631203.54543 +1249 1246 -111441208.5227 +1250 1246 -23958771.83004 +1254 1246 -33611111.10559 +1255 1246 -39363173.77667 +1256 1246 -6097121.576942 +1257 1246 9.387731552124e-07 +1258 1246 38659326.41933 +1259 1246 13888687.59834 +1260 1246 33611111.10559 +1261 1246 -41093760.8976 +1262 1246 -7791566.021395 +1344 1246 9166666.669678 +1345 1246 -15641216.50536 +1346 1246 -8177088.970282 +1347 1246 -9166747.055672 +1348 1246 -28285264.92641 +1349 1246 7788270.809731 +1353 1246 4.06801700592e-06 +1354 1246 -35246583.02275 +1355 1246 -32861133.64276 +1356 1246 9166867.634673 +1357 1246 51801215.86321 +1358 1246 -2152764.494718 +1359 1246 -9166787.248675 +1360 1246 -50782746.60544 +1361 1246 35402941.77273 +1365 1246 -9166666.669676 +1366 1246 -15732561.20235 +1367 1246 -8246533.414749 +1368 1246 4.619359970093e-07 +1369 1246 -18838452.02672 +1370 1246 -694433.1761459 +1371 1246 9166666.669675 +1372 1246 -17197404.95283 +1373 1246 8940966.590895 +1247 1247 679585775.4118 +1248 1247 -13412427.57498 +1249 1247 -26066650.19218 +1250 1247 3548849.435559 +1254 1247 -12633093.46245 +1255 1247 -6402677.132734 +1256 1247 -11231394.83281 +1257 1247 1203737.252411 +1258 1247 13888687.59834 +1259 1247 83675565.4165 +1260 1247 13408573.19995 +1261 1247 -7486010.465602 +1262 1247 -15846293.82194 +1344 1247 10018981.01522 +1345 1247 -8177088.970282 +1346 1247 -16145262.77514 +1347 1247 42113167.97979 +1348 1247 7593861.729456 +1349 1247 -55157692.73435 +1353 1247 57871.30948763 +1354 1247 -32833355.865 +1355 1247 -37566373.58606 +1356 1247 781320.0962051 +1357 1247 -2152689.398522 +1358 1247 -91946096.11431 +1359 1247 11379085.18856 +1360 1247 35569610.71641 +1361 1247 -53430905.74636 +1365 1247 -10076852.32471 +1366 1247 -8246533.414749 +1367 1247 -16388848.63381 +1368 1247 -42894214.83411 +1369 1247 -694433.1761459 +1370 1247 -55531090.78464 +1371 1247 -11378935.65847 +1372 1247 8940966.590895 +1373 1247 -20295098.63508 +1248 1248 392409175.4658 +1249 1248 33611111.10558 +1250 1248 -18921677.97532 +1257 1248 -49447220.48372 +1258 1248 -33611111.10559 +1259 1248 -12251149.01771 +1260 1248 -173081388.0675 +1261 1248 -33624506.06547 +1262 1248 14444361.39273 +1263 1248 1431297.732108 +1264 1248 26902283.84436 +1265 1248 9655347.358825 +1347 1248 -4579449.609996 +1348 1248 11000120.58261 +1349 1248 12057631.64322 +1356 1248 -14225493.76444 +1357 1248 -9166787.248675 +1358 1248 -10019112.65448 +1359 1248 35932670.30059 +1360 1248 9166666.669679 +1361 1248 9311563.653784 +1368 1248 -18482764.4945 +1369 1248 -9166666.669676 +1370 1248 -10076852.32471 +1371 1248 -72925641.46158 +1372 1248 -9166747.055676 +1373 1248 -43478968.03166 +1374 1248 -7497354.851903 +1375 1248 7333413.72174 +1376 1248 -9080099.689708 +1249 1249 341973871.613 +1250 1249 30282406.91647 +1257 1249 -33611111.10559 +1258 1249 -39363173.77667 +1259 1249 -6097121.576942 +1260 1249 -33631203.54542 +1261 1249 -15065409.46899 +1262 1249 19484896.97789 +1263 1249 40353425.76654 +1264 1249 1431297.732101 +1265 1249 -13443330.95707 +1347 1249 7333413.72174 +1348 1249 -4579449.61 +1349 1249 -6430626.286135 +1356 1249 -9166747.055675 +1357 1249 -46308715.17675 +1358 1249 -32902986.62891 +1359 1249 9166666.669678 +1360 1249 22181563.40434 +1361 1249 5180609.664774 +1368 1249 -9166666.669676 +1369 1249 -15732561.20235 +1370 1249 -8246533.414749 +1371 1249 -9166787.248676 +1372 1249 -29841516.44517 +1373 1249 -9524419.110191 +1374 1249 11000120.58261 +1375 1249 -7497354.8519 +1376 1249 10895952.52268 +1250 1250 443104893.4996 +1257 1250 -12633093.46245 +1258 1250 -6402677.132734 +1259 1250 -11231394.83281 +1260 1250 12205703.10143 +1261 1250 15281564.4366 +1262 1250 34188531.48329 +1263 1250 14483021.03824 +1264 1250 -8962220.638046 +1265 1250 3816793.952288 +1347 1250 8038421.095477 +1348 1250 -9645939.429201 +1349 1250 -12211865.62666 +1356 1250 -10019068.77473 +1357 1250 -33069655.68813 +1358 1250 -41500155.26984 +1359 1250 -7806863.548506 +1360 1250 -8513909.758068 +1361 1250 -68673244.4318 +1368 1250 -10076852.32471 +1369 1250 -8246533.414749 +1370 1250 -16388848.63381 +1371 1250 -43444243.01831 +1372 1250 -9329934.937092 +1373 1250 -59307696.78438 +1374 1250 -13620149.53456 +1375 1250 7263968.348454 +1376 1250 -19992946.27174 +1251 1251 645455824.6572 +1252 1251 3.814697265625e-06 +1253 1251 -4629696.72672 +1254 1251 69286959.53708 +1255 1251 -2.101063728333e-06 +1256 1251 -1157424.182251 +1266 1251 -109230745.6082 +1267 1251 1.281499862671e-06 +1268 1251 3425959.474268 +1269 1251 -51177807.60464 +1270 1251 33611111.10559 +1271 1251 13790517.64469 +1350 1251 -58783069.51046 +1351 1251 1.639127731323e-06 +1352 1251 42697451.81849 +1353 1251 -19844426.42677 +1354 1251 -9166666.669679 +1355 1251 11321064.34898 +1362 1251 57430602.85087 +1363 1251 3.8743019104e-06 +1364 1251 231485.2378496 +1365 1251 -6249019.844286 +1366 1251 -7.443130016327e-06 +1367 1251 57871.30949415 +1377 1251 -59172122.54065 +1378 1251 4.395842552185e-07 +1379 1251 -42928937.05631 +1380 1251 -19947608.24497 +1381 1251 9166666.669675 +1382 1251 -11378935.65847 +1252 1252 564783451.0405 +1253 1252 55554750.36598 +1254 1252 -3.129243850708e-06 +1255 1252 -58435019.09619 +1256 1252 -28666264.07173 +1266 1252 9.387731552124e-07 +1267 1252 38659326.41933 +1268 1252 13888687.59834 +1269 1252 33611111.10559 +1270 1252 -41093760.8976 +1271 1252 -7791566.021395 +1350 1252 6.034970283508e-07 +1351 1252 -18449398.9965 +1352 1252 -694433.1761458 +1353 1252 -9166666.669679 +1354 1252 -17094223.13462 +1355 1252 8871522.146427 +1362 1252 4.231929779053e-06 +1363 1252 35428976.52455 +1364 1252 -2777732.703215 +1365 1252 -7.599592208862e-06 +1366 1252 -41082283.77936 +1367 1252 35638866.34597 +1377 1252 4.619359970093e-07 +1378 1252 -18838452.02672 +1379 1252 -694433.1761459 +1380 1252 9166666.669675 +1381 1252 -17197404.95283 +1382 1252 8940966.590895 +1253 1253 756192654.5709 +1254 1253 -1157424.182251 +1255 1253 -26888486.29425 +1256 1253 51063391.07047 +1266 1253 1203737.252411 +1267 1253 13888687.59834 +1268 1253 83675565.4165 +1269 1253 13408573.19995 +1270 1253 -7486010.465602 +1271 1253 -15846293.82194 +1350 1253 42662729.59629 +1351 1253 -694433.1761458 +1352 1253 -54493616.03735 +1353 1253 11321064.34898 +1354 1253 8871522.146428 +1355 1253 -20019947.11985 +1362 1253 231485.2378493 +1363 1253 -2777732.703215 +1364 1253 -110039912.4136 +1365 1253 57871.30949473 +1366 1253 35611088.56821 +1367 1253 -53128242.27036 +1377 1253 -42894214.83411 +1378 1253 -694433.1761459 +1379 1253 -55531090.78464 +1380 1253 -11378935.65847 +1381 1253 8940966.590895 +1382 1253 -20295098.63508 +1254 1254 645455824.6572 +1255 1254 3.814697265625e-06 +1256 1254 -4629696.72672 +1257 1254 69286959.53708 +1258 1254 -2.101063728333e-06 +1259 1254 -1157424.182251 +1266 1254 -49447220.48372 +1267 1254 -33611111.10559 +1268 1254 -12251149.01771 +1269 1254 -109230745.6082 +1270 1254 1.281499862671e-06 +1271 1254 3425959.474268 +1272 1254 -51177807.60464 +1273 1254 33611111.10559 +1274 1254 13790517.64469 +1350 1254 -18391419.7975 +1351 1254 9166666.669678 +1352 1254 10018981.01522 +1353 1254 -58783069.51046 +1354 1254 1.639127731323e-06 +1355 1254 42697451.81849 +1356 1254 -19844426.42677 +1357 1254 -9166666.669679 +1358 1254 11321064.34898 +1362 1254 -413319.0876746 +1363 1254 3.017485141754e-06 +1364 1254 57871.30948708 +1365 1254 57430602.85087 +1366 1254 3.8743019104e-06 +1367 1254 231485.2378496 +1368 1254 -6249019.844286 +1369 1254 -7.443130016327e-06 +1370 1254 57871.30949415 +1377 1254 -18482764.4945 +1378 1254 -9166666.669676 +1379 1254 -10076852.32471 +1380 1254 -59172122.54065 +1381 1254 4.395842552185e-07 +1382 1254 -42928937.05631 +1383 1254 -19947608.24497 +1384 1254 9166666.669675 +1385 1254 -11378935.65847 +1255 1255 564783451.0405 +1256 1255 55554750.36598 +1257 1255 -3.129243850708e-06 +1258 1255 -58435019.09619 +1259 1255 -28666264.07173 +1266 1255 -33611111.10559 +1267 1255 -39363173.77667 +1268 1255 -6097121.576942 +1269 1255 9.387731552124e-07 +1270 1255 38659326.41933 +1271 1255 13888687.59834 +1272 1255 33611111.10559 +1273 1255 -41093760.8976 +1274 1255 -7791566.021395 +1350 1255 9166666.669678 +1351 1255 -15641216.50536 +1352 1255 -8177088.970282 +1353 1255 6.034970283508e-07 +1354 1255 -18449398.9965 +1355 1255 -694433.1761458 +1356 1255 -9166666.669679 +1357 1255 -17094223.13462 +1358 1255 8871522.146427 +1362 1255 4.06801700592e-06 +1363 1255 -35246583.02275 +1364 1255 -32861133.64276 +1365 1255 4.231929779053e-06 +1366 1255 35428976.52455 +1367 1255 -2777732.703215 +1368 1255 -7.599592208862e-06 +1369 1255 -41082283.77936 +1370 1255 35638866.34597 +1377 1255 -9166666.669676 +1378 1255 -15732561.20235 +1379 1255 -8246533.414749 +1380 1255 4.619359970093e-07 +1381 1255 -18838452.02672 +1382 1255 -694433.1761459 +1383 1255 9166666.669675 +1384 1255 -17197404.95283 +1385 1255 8940966.590895 +1256 1256 756192654.5709 +1257 1256 -1157424.182251 +1258 1256 -26888486.29425 +1259 1256 51063391.07047 +1266 1256 -12633093.46245 +1267 1256 -6402677.132734 +1268 1256 -11231394.83281 +1269 1256 1203737.252411 +1270 1256 13888687.59834 +1271 1256 83675565.4165 +1272 1256 13408573.19995 +1273 1256 -7486010.465602 +1274 1256 -15846293.82194 +1350 1256 10018981.01522 +1351 1256 -8177088.970282 +1352 1256 -16145262.77514 +1353 1256 42662729.59629 +1354 1256 -694433.1761458 +1355 1256 -54493616.03735 +1356 1256 11321064.34898 +1357 1256 8871522.146428 +1358 1256 -20019947.11985 +1362 1256 57871.30948763 +1363 1256 -32833355.865 +1364 1256 -37566373.58606 +1365 1256 231485.2378493 +1366 1256 -2777732.703215 +1367 1256 -110039912.4136 +1368 1256 57871.30949473 +1369 1256 35611088.56821 +1370 1256 -53128242.27036 +1377 1256 -10076852.32471 +1378 1256 -8246533.414749 +1379 1256 -16388848.63381 +1380 1256 -42894214.83411 +1381 1256 -694433.1761459 +1382 1256 -55531090.78464 +1383 1256 -11378935.65847 +1384 1256 8940966.590895 +1385 1256 -20295098.63508 +1257 1257 645455824.6572 +1258 1257 3.814697265625e-06 +1259 1257 -4629696.72672 +1260 1257 69286959.53708 +1261 1257 -2.101063728333e-06 +1262 1257 -1157424.182251 +1269 1257 -49447220.48372 +1270 1257 -33611111.10559 +1271 1257 -12251149.01771 +1272 1257 -109230745.6082 +1273 1257 1.281499862671e-06 +1274 1257 3425959.474268 +1275 1257 -51177807.60464 +1276 1257 33611111.10559 +1277 1257 13790517.64469 +1353 1257 -18391419.7975 +1354 1257 9166666.669678 +1355 1257 10018981.01522 +1356 1257 -58783069.51046 +1357 1257 1.639127731323e-06 +1358 1257 42697451.81849 +1359 1257 -19844426.42677 +1360 1257 -9166666.669679 +1361 1257 11321064.34898 +1365 1257 -413319.0876746 +1366 1257 3.017485141754e-06 +1367 1257 57871.30948708 +1368 1257 57430602.85087 +1369 1257 3.8743019104e-06 +1370 1257 231485.2378496 +1371 1257 -6249019.844286 +1372 1257 -7.443130016327e-06 +1373 1257 57871.30949415 +1380 1257 -18482764.4945 +1381 1257 -9166666.669676 +1382 1257 -10076852.32471 +1383 1257 -59172122.54065 +1384 1257 4.395842552185e-07 +1385 1257 -42928937.05631 +1386 1257 -19947608.24497 +1387 1257 9166666.669675 +1388 1257 -11378935.65847 +1258 1258 564783451.0405 +1259 1258 55554750.36598 +1260 1258 -3.129243850708e-06 +1261 1258 -58435019.09619 +1262 1258 -28666264.07173 +1269 1258 -33611111.10559 +1270 1258 -39363173.77667 +1271 1258 -6097121.576942 +1272 1258 9.387731552124e-07 +1273 1258 38659326.41933 +1274 1258 13888687.59834 +1275 1258 33611111.10559 +1276 1258 -41093760.8976 +1277 1258 -7791566.021395 +1353 1258 9166666.669678 +1354 1258 -15641216.50536 +1355 1258 -8177088.970282 +1356 1258 6.034970283508e-07 +1357 1258 -18449398.9965 +1358 1258 -694433.1761458 +1359 1258 -9166666.669679 +1360 1258 -17094223.13462 +1361 1258 8871522.146427 +1365 1258 4.06801700592e-06 +1366 1258 -35246583.02275 +1367 1258 -32861133.64276 +1368 1258 4.231929779053e-06 +1369 1258 35428976.52455 +1370 1258 -2777732.703215 +1371 1258 -7.599592208862e-06 +1372 1258 -41082283.77936 +1373 1258 35638866.34597 +1380 1258 -9166666.669676 +1381 1258 -15732561.20235 +1382 1258 -8246533.414749 +1383 1258 4.619359970093e-07 +1384 1258 -18838452.02672 +1385 1258 -694433.1761459 +1386 1258 9166666.669675 +1387 1258 -17197404.95283 +1388 1258 8940966.590895 +1259 1259 756192654.5709 +1260 1259 -1157424.182251 +1261 1259 -26888486.29425 +1262 1259 51063391.07047 +1269 1259 -12633093.46245 +1270 1259 -6402677.132734 +1271 1259 -11231394.83281 +1272 1259 1203737.252411 +1273 1259 13888687.59834 +1274 1259 83675565.4165 +1275 1259 13408573.19995 +1276 1259 -7486010.465602 +1277 1259 -15846293.82194 +1353 1259 10018981.01522 +1354 1259 -8177088.970282 +1355 1259 -16145262.77514 +1356 1259 42662729.59629 +1357 1259 -694433.1761458 +1358 1259 -54493616.03735 +1359 1259 11321064.34898 +1360 1259 8871522.146428 +1361 1259 -20019947.11985 +1365 1259 57871.30948763 +1366 1259 -32833355.865 +1367 1259 -37566373.58606 +1368 1259 231485.2378493 +1369 1259 -2777732.703215 +1370 1259 -110039912.4136 +1371 1259 57871.30949473 +1372 1259 35611088.56821 +1373 1259 -53128242.27036 +1380 1259 -10076852.32471 +1381 1259 -8246533.414749 +1382 1259 -16388848.63381 +1383 1259 -42894214.83411 +1384 1259 -694433.1761459 +1385 1259 -55531090.78464 +1386 1259 -11378935.65847 +1387 1259 8940966.590895 +1388 1259 -20295098.63508 +1260 1260 662031295.7794 +1261 1260 33644598.50531 +1262 1260 -15598790.43683 +1263 1260 6223512.930091 +1264 1260 -33624506.06548 +1265 1260 -13793087.22804 +1272 1260 -49447220.48372 +1273 1260 -33611111.10559 +1274 1260 -12251149.01771 +1275 1260 -109230745.6082 +1276 1260 1.281499862671e-06 +1277 1260 3425959.474268 +1278 1260 -51177807.60464 +1279 1260 33611111.10559 +1280 1260 13790517.64469 +1356 1260 -18391419.7975 +1357 1260 9166666.669678 +1358 1260 10018981.01522 +1359 1260 -71369389.94283 +1360 1260 -9166787.24867 +1361 1260 42147892.99313 +1368 1260 -413319.0876746 +1369 1260 3.017485141754e-06 +1370 1260 57871.30948708 +1371 1260 76553135.92261 +1372 1260 9166867.634673 +1373 1260 781226.2244361 +1374 1260 -18699525.19313 +1375 1260 -9166747.055676 +1376 1260 11379035.3452 +1383 1260 -18482764.4945 +1384 1260 -9166666.669676 +1385 1260 -10076852.32471 +1386 1260 -59172122.54065 +1387 1260 4.395842552185e-07 +1388 1260 -42928937.05631 +1389 1260 -19947608.24497 +1390 1260 9166666.669675 +1391 1260 -11378935.65847 +1261 1261 571259805.1183 +1262 1261 43075945.84504 +1263 1261 -33631203.54543 +1264 1261 -111441208.5227 +1265 1261 -23958771.83004 +1272 1261 -33611111.10559 +1273 1261 -39363173.77667 +1274 1261 -6097121.576942 +1275 1261 9.387731552124e-07 +1276 1261 38659326.41933 +1277 1261 13888687.59834 +1278 1261 33611111.10559 +1279 1261 -41093760.8976 +1280 1261 -7791566.021395 +1356 1261 9166666.669678 +1357 1261 -15641216.50536 +1358 1261 -8177088.970282 +1359 1261 -9166747.055672 +1360 1261 -28285264.92641 +1361 1261 7788270.809731 +1368 1261 4.06801700592e-06 +1369 1261 -35246583.02275 +1370 1261 -32861133.64276 +1371 1261 9166867.634673 +1372 1261 51801215.86321 +1373 1261 -2152764.494718 +1374 1261 -9166787.248675 +1375 1261 -50782746.60544 +1376 1261 35402941.77273 +1383 1261 -9166666.669676 +1384 1261 -15732561.20235 +1385 1261 -8246533.414749 +1386 1261 4.619359970093e-07 +1387 1261 -18838452.02672 +1388 1261 -694433.1761459 +1389 1261 9166666.669675 +1390 1261 -17197404.95283 +1391 1261 8940966.590895 +1262 1262 679585775.4118 +1263 1262 -13412427.57498 +1264 1262 -26066650.19218 +1265 1262 3548849.435559 +1272 1262 -12633093.46245 +1273 1262 -6402677.132734 +1274 1262 -11231394.83281 +1275 1262 1203737.252411 +1276 1262 13888687.59834 +1277 1262 83675565.4165 +1278 1262 13408573.19995 +1279 1262 -7486010.465602 +1280 1262 -15846293.82194 +1356 1262 10018981.01522 +1357 1262 -8177088.970282 +1358 1262 -16145262.77514 +1359 1262 42113167.97979 +1360 1262 7593861.729456 +1361 1262 -55157692.73435 +1368 1262 57871.30948763 +1369 1262 -32833355.865 +1370 1262 -37566373.58606 +1371 1262 781320.0962051 +1372 1262 -2152689.398522 +1373 1262 -91946096.11431 +1374 1262 11379085.18856 +1375 1262 35569610.71641 +1376 1262 -53430905.74636 +1383 1262 -10076852.32471 +1384 1262 -8246533.414749 +1385 1262 -16388848.63381 +1386 1262 -42894214.83411 +1387 1262 -694433.1761459 +1388 1262 -55531090.78464 +1389 1262 -11378935.65847 +1390 1262 8940966.590895 +1391 1262 -20295098.63508 +1263 1263 392409175.4658 +1264 1263 33611111.10558 +1265 1263 -18921677.97532 +1275 1263 -49447220.48372 +1276 1263 -33611111.10559 +1277 1263 -12251149.01771 +1278 1263 -173081388.0675 +1279 1263 -33624506.06547 +1280 1263 14444361.39273 +1281 1263 1431297.732108 +1282 1263 26902283.84436 +1283 1263 9655347.358825 +1359 1263 -4579449.609996 +1360 1263 11000120.58261 +1361 1263 12057631.64322 +1371 1263 -14225493.76444 +1372 1263 -9166787.248675 +1373 1263 -10019112.65448 +1374 1263 35932670.30059 +1375 1263 9166666.669679 +1376 1263 9311563.653784 +1386 1263 -18482764.4945 +1387 1263 -9166666.669676 +1388 1263 -10076852.32471 +1389 1263 -72925641.46158 +1390 1263 -9166747.055676 +1391 1263 -43478968.03166 +1392 1263 -7497354.851903 +1393 1263 7333413.72174 +1394 1263 -9080099.689708 +1264 1264 341973871.613 +1265 1264 30282406.91647 +1275 1264 -33611111.10559 +1276 1264 -39363173.77667 +1277 1264 -6097121.576942 +1278 1264 -33631203.54542 +1279 1264 -15065409.46899 +1280 1264 19484896.97789 +1281 1264 40353425.76654 +1282 1264 1431297.732101 +1283 1264 -13443330.95707 +1359 1264 7333413.72174 +1360 1264 -4579449.61 +1361 1264 -6430626.286135 +1371 1264 -9166747.055675 +1372 1264 -46308715.17675 +1373 1264 -32902986.62891 +1374 1264 9166666.669678 +1375 1264 22181563.40434 +1376 1264 5180609.664774 +1386 1264 -9166666.669676 +1387 1264 -15732561.20235 +1388 1264 -8246533.414749 +1389 1264 -9166787.248676 +1390 1264 -29841516.44517 +1391 1264 -9524419.110191 +1392 1264 11000120.58261 +1393 1264 -7497354.8519 +1394 1264 10895952.52268 +1265 1265 443104893.4996 +1275 1265 -12633093.46245 +1276 1265 -6402677.132734 +1277 1265 -11231394.83281 +1278 1265 12205703.10143 +1279 1265 15281564.4366 +1280 1265 34188531.48329 +1281 1265 14483021.03824 +1282 1265 -8962220.638046 +1283 1265 3816793.952288 +1359 1265 8038421.095477 +1360 1265 -9645939.429201 +1361 1265 -12211865.62666 +1371 1265 -10019068.77473 +1372 1265 -33069655.68813 +1373 1265 -41500155.26984 +1374 1265 -7806863.548506 +1375 1265 -8513909.758068 +1376 1265 -68673244.4318 +1386 1265 -10076852.32471 +1387 1265 -8246533.414749 +1388 1265 -16388848.63381 +1389 1265 -43444243.01831 +1390 1265 -9329934.937092 +1391 1265 -59307696.78438 +1392 1265 -13620149.53456 +1393 1265 7263968.348454 +1394 1265 -19992946.27174 +1266 1266 645455824.6572 +1267 1266 3.814697265625e-06 +1268 1266 -4629696.72672 +1269 1266 69286959.53708 +1270 1266 -2.101063728333e-06 +1271 1266 -1157424.182251 +1284 1266 -109230745.6082 +1285 1266 1.281499862671e-06 +1286 1266 3425959.474268 +1287 1266 -51177807.60464 +1288 1266 33611111.10559 +1289 1266 13790517.64469 +1362 1266 -58783069.51046 +1363 1266 1.639127731323e-06 +1364 1266 42697451.81849 +1365 1266 -19844426.42677 +1366 1266 -9166666.669679 +1367 1266 11321064.34898 +1377 1266 57430602.85087 +1378 1266 3.8743019104e-06 +1379 1266 231485.2378496 +1380 1266 -6249019.844286 +1381 1266 -7.443130016327e-06 +1382 1266 57871.30949415 +1395 1266 -59172122.54065 +1396 1266 4.395842552185e-07 +1397 1266 -42928937.05631 +1398 1266 -19947608.24497 +1399 1266 9166666.669675 +1400 1266 -11378935.65847 +1267 1267 564783451.0405 +1268 1267 55554750.36598 +1269 1267 -3.129243850708e-06 +1270 1267 -58435019.09619 +1271 1267 -28666264.07173 +1284 1267 9.387731552124e-07 +1285 1267 38659326.41933 +1286 1267 13888687.59834 +1287 1267 33611111.10559 +1288 1267 -41093760.8976 +1289 1267 -7791566.021395 +1362 1267 6.034970283508e-07 +1363 1267 -18449398.9965 +1364 1267 -694433.1761458 +1365 1267 -9166666.669679 +1366 1267 -17094223.13462 +1367 1267 8871522.146427 +1377 1267 4.231929779053e-06 +1378 1267 35428976.52455 +1379 1267 -2777732.703215 +1380 1267 -7.599592208862e-06 +1381 1267 -41082283.77936 +1382 1267 35638866.34597 +1395 1267 4.619359970093e-07 +1396 1267 -18838452.02672 +1397 1267 -694433.1761459 +1398 1267 9166666.669675 +1399 1267 -17197404.95283 +1400 1267 8940966.590895 +1268 1268 756192654.5709 +1269 1268 -1157424.182251 +1270 1268 -26888486.29425 +1271 1268 51063391.07047 +1284 1268 1203737.252411 +1285 1268 13888687.59834 +1286 1268 83675565.4165 +1287 1268 13408573.19995 +1288 1268 -7486010.465602 +1289 1268 -15846293.82194 +1362 1268 42662729.59629 +1363 1268 -694433.1761458 +1364 1268 -54493616.03735 +1365 1268 11321064.34898 +1366 1268 8871522.146428 +1367 1268 -20019947.11985 +1377 1268 231485.2378493 +1378 1268 -2777732.703215 +1379 1268 -110039912.4136 +1380 1268 57871.30949473 +1381 1268 35611088.56821 +1382 1268 -53128242.27036 +1395 1268 -42894214.83411 +1396 1268 -694433.1761459 +1397 1268 -55531090.78464 +1398 1268 -11378935.65847 +1399 1268 8940966.590895 +1400 1268 -20295098.63508 +1269 1269 645455824.6572 +1270 1269 3.814697265625e-06 +1271 1269 -4629696.72672 +1272 1269 69286959.53708 +1273 1269 -2.101063728333e-06 +1274 1269 -1157424.182251 +1284 1269 -49447220.48372 +1285 1269 -33611111.10559 +1286 1269 -12251149.01771 +1287 1269 -109230745.6082 +1288 1269 1.281499862671e-06 +1289 1269 3425959.474268 +1290 1269 -51177807.60464 +1291 1269 33611111.10559 +1292 1269 13790517.64469 +1362 1269 -18391419.7975 +1363 1269 9166666.669678 +1364 1269 10018981.01522 +1365 1269 -58783069.51046 +1366 1269 1.639127731323e-06 +1367 1269 42697451.81849 +1368 1269 -19844426.42677 +1369 1269 -9166666.669679 +1370 1269 11321064.34898 +1377 1269 -413319.0876746 +1378 1269 3.017485141754e-06 +1379 1269 57871.30948708 +1380 1269 57430602.85087 +1381 1269 3.8743019104e-06 +1382 1269 231485.2378496 +1383 1269 -6249019.844286 +1384 1269 -7.443130016327e-06 +1385 1269 57871.30949415 +1395 1269 -18482764.4945 +1396 1269 -9166666.669676 +1397 1269 -10076852.32471 +1398 1269 -59172122.54065 +1399 1269 4.395842552185e-07 +1400 1269 -42928937.05631 +1401 1269 -19947608.24497 +1402 1269 9166666.669675 +1403 1269 -11378935.65847 +1270 1270 564783451.0405 +1271 1270 55554750.36598 +1272 1270 -3.129243850708e-06 +1273 1270 -58435019.09619 +1274 1270 -28666264.07173 +1284 1270 -33611111.10559 +1285 1270 -39363173.77667 +1286 1270 -6097121.576942 +1287 1270 9.387731552124e-07 +1288 1270 38659326.41933 +1289 1270 13888687.59834 +1290 1270 33611111.10559 +1291 1270 -41093760.8976 +1292 1270 -7791566.021395 +1362 1270 9166666.669678 +1363 1270 -15641216.50536 +1364 1270 -8177088.970282 +1365 1270 6.034970283508e-07 +1366 1270 -18449398.9965 +1367 1270 -694433.1761458 +1368 1270 -9166666.669679 +1369 1270 -17094223.13462 +1370 1270 8871522.146427 +1377 1270 4.06801700592e-06 +1378 1270 -35246583.02275 +1379 1270 -32861133.64276 +1380 1270 4.231929779053e-06 +1381 1270 35428976.52455 +1382 1270 -2777732.703215 +1383 1270 -7.599592208862e-06 +1384 1270 -41082283.77936 +1385 1270 35638866.34597 +1395 1270 -9166666.669676 +1396 1270 -15732561.20235 +1397 1270 -8246533.414749 +1398 1270 4.619359970093e-07 +1399 1270 -18838452.02672 +1400 1270 -694433.1761459 +1401 1270 9166666.669675 +1402 1270 -17197404.95283 +1403 1270 8940966.590895 +1271 1271 756192654.5709 +1272 1271 -1157424.182251 +1273 1271 -26888486.29425 +1274 1271 51063391.07047 +1284 1271 -12633093.46245 +1285 1271 -6402677.132734 +1286 1271 -11231394.83281 +1287 1271 1203737.252411 +1288 1271 13888687.59834 +1289 1271 83675565.4165 +1290 1271 13408573.19995 +1291 1271 -7486010.465602 +1292 1271 -15846293.82194 +1362 1271 10018981.01522 +1363 1271 -8177088.970282 +1364 1271 -16145262.77514 +1365 1271 42662729.59629 +1366 1271 -694433.1761458 +1367 1271 -54493616.03735 +1368 1271 11321064.34898 +1369 1271 8871522.146428 +1370 1271 -20019947.11985 +1377 1271 57871.30948763 +1378 1271 -32833355.865 +1379 1271 -37566373.58606 +1380 1271 231485.2378493 +1381 1271 -2777732.703215 +1382 1271 -110039912.4136 +1383 1271 57871.30949473 +1384 1271 35611088.56821 +1385 1271 -53128242.27036 +1395 1271 -10076852.32471 +1396 1271 -8246533.414749 +1397 1271 -16388848.63381 +1398 1271 -42894214.83411 +1399 1271 -694433.1761459 +1400 1271 -55531090.78464 +1401 1271 -11378935.65847 +1402 1271 8940966.590895 +1403 1271 -20295098.63508 +1272 1272 645455824.6572 +1273 1272 3.814697265625e-06 +1274 1272 -4629696.72672 +1275 1272 69286959.53708 +1276 1272 -2.101063728333e-06 +1277 1272 -1157424.182251 +1287 1272 -49447220.48372 +1288 1272 -33611111.10559 +1289 1272 -12251149.01771 +1290 1272 -109230745.6082 +1291 1272 1.281499862671e-06 +1292 1272 3425959.474268 +1293 1272 -51177807.60464 +1294 1272 33611111.10559 +1295 1272 13790517.64469 +1365 1272 -18391419.7975 +1366 1272 9166666.669678 +1367 1272 10018981.01522 +1368 1272 -58783069.51046 +1369 1272 1.639127731323e-06 +1370 1272 42697451.81849 +1371 1272 -19844426.42677 +1372 1272 -9166666.669679 +1373 1272 11321064.34898 +1380 1272 -413319.0876746 +1381 1272 3.017485141754e-06 +1382 1272 57871.30948708 +1383 1272 57430602.85087 +1384 1272 3.8743019104e-06 +1385 1272 231485.2378496 +1386 1272 -6249019.844286 +1387 1272 -7.443130016327e-06 +1388 1272 57871.30949415 +1398 1272 -18482764.4945 +1399 1272 -9166666.669676 +1400 1272 -10076852.32471 +1401 1272 -59172122.54065 +1402 1272 4.395842552185e-07 +1403 1272 -42928937.05631 +1404 1272 -19947608.24497 +1405 1272 9166666.669675 +1406 1272 -11378935.65847 +1273 1273 564783451.0405 +1274 1273 55554750.36598 +1275 1273 -3.129243850708e-06 +1276 1273 -58435019.09619 +1277 1273 -28666264.07173 +1287 1273 -33611111.10559 +1288 1273 -39363173.77667 +1289 1273 -6097121.576942 +1290 1273 9.387731552124e-07 +1291 1273 38659326.41933 +1292 1273 13888687.59834 +1293 1273 33611111.10559 +1294 1273 -41093760.8976 +1295 1273 -7791566.021395 +1365 1273 9166666.669678 +1366 1273 -15641216.50536 +1367 1273 -8177088.970282 +1368 1273 6.034970283508e-07 +1369 1273 -18449398.9965 +1370 1273 -694433.1761458 +1371 1273 -9166666.669679 +1372 1273 -17094223.13462 +1373 1273 8871522.146427 +1380 1273 4.06801700592e-06 +1381 1273 -35246583.02275 +1382 1273 -32861133.64276 +1383 1273 4.231929779053e-06 +1384 1273 35428976.52455 +1385 1273 -2777732.703215 +1386 1273 -7.599592208862e-06 +1387 1273 -41082283.77936 +1388 1273 35638866.34597 +1398 1273 -9166666.669676 +1399 1273 -15732561.20235 +1400 1273 -8246533.414749 +1401 1273 4.619359970093e-07 +1402 1273 -18838452.02672 +1403 1273 -694433.1761459 +1404 1273 9166666.669675 +1405 1273 -17197404.95283 +1406 1273 8940966.590895 +1274 1274 756192654.5709 +1275 1274 -1157424.182251 +1276 1274 -26888486.29425 +1277 1274 51063391.07047 +1287 1274 -12633093.46245 +1288 1274 -6402677.132734 +1289 1274 -11231394.83281 +1290 1274 1203737.252411 +1291 1274 13888687.59834 +1292 1274 83675565.4165 +1293 1274 13408573.19995 +1294 1274 -7486010.465602 +1295 1274 -15846293.82194 +1365 1274 10018981.01522 +1366 1274 -8177088.970282 +1367 1274 -16145262.77514 +1368 1274 42662729.59629 +1369 1274 -694433.1761458 +1370 1274 -54493616.03735 +1371 1274 11321064.34898 +1372 1274 8871522.146428 +1373 1274 -20019947.11985 +1380 1274 57871.30948763 +1381 1274 -32833355.865 +1382 1274 -37566373.58606 +1383 1274 231485.2378493 +1384 1274 -2777732.703215 +1385 1274 -110039912.4136 +1386 1274 57871.30949473 +1387 1274 35611088.56821 +1388 1274 -53128242.27036 +1398 1274 -10076852.32471 +1399 1274 -8246533.414749 +1400 1274 -16388848.63381 +1401 1274 -42894214.83411 +1402 1274 -694433.1761459 +1403 1274 -55531090.78464 +1404 1274 -11378935.65847 +1405 1274 8940966.590895 +1406 1274 -20295098.63508 +1275 1275 645455824.6572 +1276 1275 3.814697265625e-06 +1277 1275 -4629696.72672 +1278 1275 69286959.53708 +1279 1275 -2.101063728333e-06 +1280 1275 -1157424.182251 +1290 1275 -49447220.48372 +1291 1275 -33611111.10559 +1292 1275 -12251149.01771 +1293 1275 -109230745.6082 +1294 1275 1.281499862671e-06 +1295 1275 3425959.474268 +1296 1275 -51177807.60464 +1297 1275 33611111.10559 +1298 1275 13790517.64469 +1368 1275 -18391419.7975 +1369 1275 9166666.669678 +1370 1275 10018981.01522 +1371 1275 -58783069.51046 +1372 1275 1.639127731323e-06 +1373 1275 42697451.81849 +1374 1275 -19844426.42677 +1375 1275 -9166666.669679 +1376 1275 11321064.34898 +1383 1275 -413319.0876746 +1384 1275 3.017485141754e-06 +1385 1275 57871.30948708 +1386 1275 57430602.85087 +1387 1275 3.8743019104e-06 +1388 1275 231485.2378496 +1389 1275 -6249019.844286 +1390 1275 -7.443130016327e-06 +1391 1275 57871.30949415 +1401 1275 -18482764.4945 +1402 1275 -9166666.669676 +1403 1275 -10076852.32471 +1404 1275 -59172122.54065 +1405 1275 4.395842552185e-07 +1406 1275 -42928937.05631 +1407 1275 -19947608.24497 +1408 1275 9166666.669675 +1409 1275 -11378935.65847 +1276 1276 564783451.0405 +1277 1276 55554750.36598 +1278 1276 -3.129243850708e-06 +1279 1276 -58435019.09619 +1280 1276 -28666264.07173 +1290 1276 -33611111.10559 +1291 1276 -39363173.77667 +1292 1276 -6097121.576942 +1293 1276 9.387731552124e-07 +1294 1276 38659326.41933 +1295 1276 13888687.59834 +1296 1276 33611111.10559 +1297 1276 -41093760.8976 +1298 1276 -7791566.021395 +1368 1276 9166666.669678 +1369 1276 -15641216.50536 +1370 1276 -8177088.970282 +1371 1276 6.034970283508e-07 +1372 1276 -18449398.9965 +1373 1276 -694433.1761458 +1374 1276 -9166666.669679 +1375 1276 -17094223.13462 +1376 1276 8871522.146427 +1383 1276 4.06801700592e-06 +1384 1276 -35246583.02275 +1385 1276 -32861133.64276 +1386 1276 4.231929779053e-06 +1387 1276 35428976.52455 +1388 1276 -2777732.703215 +1389 1276 -7.599592208862e-06 +1390 1276 -41082283.77936 +1391 1276 35638866.34597 +1401 1276 -9166666.669676 +1402 1276 -15732561.20235 +1403 1276 -8246533.414749 +1404 1276 4.619359970093e-07 +1405 1276 -18838452.02672 +1406 1276 -694433.1761459 +1407 1276 9166666.669675 +1408 1276 -17197404.95283 +1409 1276 8940966.590895 +1277 1277 756192654.5709 +1278 1277 -1157424.182251 +1279 1277 -26888486.29425 +1280 1277 51063391.07047 +1290 1277 -12633093.46245 +1291 1277 -6402677.132734 +1292 1277 -11231394.83281 +1293 1277 1203737.252411 +1294 1277 13888687.59834 +1295 1277 83675565.4165 +1296 1277 13408573.19995 +1297 1277 -7486010.465602 +1298 1277 -15846293.82194 +1368 1277 10018981.01522 +1369 1277 -8177088.970282 +1370 1277 -16145262.77514 +1371 1277 42662729.59629 +1372 1277 -694433.1761458 +1373 1277 -54493616.03735 +1374 1277 11321064.34898 +1375 1277 8871522.146428 +1376 1277 -20019947.11985 +1383 1277 57871.30948763 +1384 1277 -32833355.865 +1385 1277 -37566373.58606 +1386 1277 231485.2378493 +1387 1277 -2777732.703215 +1388 1277 -110039912.4136 +1389 1277 57871.30949473 +1390 1277 35611088.56821 +1391 1277 -53128242.27036 +1401 1277 -10076852.32471 +1402 1277 -8246533.414749 +1403 1277 -16388848.63381 +1404 1277 -42894214.83411 +1405 1277 -694433.1761459 +1406 1277 -55531090.78464 +1407 1277 -11378935.65847 +1408 1277 8940966.590895 +1409 1277 -20295098.63508 +1278 1278 662031295.7794 +1279 1278 33644598.50531 +1280 1278 -15598790.43683 +1281 1278 6223512.930091 +1282 1278 -33624506.06548 +1283 1278 -13793087.22804 +1293 1278 -49447220.48372 +1294 1278 -33611111.10559 +1295 1278 -12251149.01771 +1296 1278 -109230745.6082 +1297 1278 1.281499862671e-06 +1298 1278 3425959.474268 +1299 1278 -51177807.60464 +1300 1278 33611111.10559 +1301 1278 13790517.64469 +1371 1278 -18391419.7975 +1372 1278 9166666.669678 +1373 1278 10018981.01522 +1374 1278 -71369389.94283 +1375 1278 -9166787.24867 +1376 1278 42147892.99313 +1386 1278 -413319.0876746 +1387 1278 3.017485141754e-06 +1388 1278 57871.30948708 +1389 1278 76553135.92261 +1390 1278 9166867.634673 +1391 1278 781226.2244361 +1392 1278 -18699525.19313 +1393 1278 -9166747.055676 +1394 1278 11379035.3452 +1404 1278 -18482764.4945 +1405 1278 -9166666.669676 +1406 1278 -10076852.32471 +1407 1278 -59172122.54065 +1408 1278 4.395842552185e-07 +1409 1278 -42928937.05631 +1410 1278 -19947608.24497 +1411 1278 9166666.669675 +1412 1278 -11378935.65847 +1279 1279 571259805.1183 +1280 1279 43075945.84504 +1281 1279 -33631203.54543 +1282 1279 -111441208.5227 +1283 1279 -23958771.83004 +1293 1279 -33611111.10559 +1294 1279 -39363173.77667 +1295 1279 -6097121.576942 +1296 1279 9.387731552124e-07 +1297 1279 38659326.41933 +1298 1279 13888687.59834 +1299 1279 33611111.10559 +1300 1279 -41093760.8976 +1301 1279 -7791566.021395 +1371 1279 9166666.669678 +1372 1279 -15641216.50536 +1373 1279 -8177088.970282 +1374 1279 -9166747.055672 +1375 1279 -28285264.92641 +1376 1279 7788270.809731 +1386 1279 4.06801700592e-06 +1387 1279 -35246583.02275 +1388 1279 -32861133.64276 +1389 1279 9166867.634673 +1390 1279 51801215.86321 +1391 1279 -2152764.494718 +1392 1279 -9166787.248675 +1393 1279 -50782746.60544 +1394 1279 35402941.77273 +1404 1279 -9166666.669676 +1405 1279 -15732561.20235 +1406 1279 -8246533.414749 +1407 1279 4.619359970093e-07 +1408 1279 -18838452.02672 +1409 1279 -694433.1761459 +1410 1279 9166666.669675 +1411 1279 -17197404.95283 +1412 1279 8940966.590895 +1280 1280 679585775.4118 +1281 1280 -13412427.57498 +1282 1280 -26066650.19218 +1283 1280 3548849.435559 +1293 1280 -12633093.46245 +1294 1280 -6402677.132734 +1295 1280 -11231394.83281 +1296 1280 1203737.252411 +1297 1280 13888687.59834 +1298 1280 83675565.4165 +1299 1280 13408573.19995 +1300 1280 -7486010.465602 +1301 1280 -15846293.82194 +1371 1280 10018981.01522 +1372 1280 -8177088.970282 +1373 1280 -16145262.77514 +1374 1280 42113167.97979 +1375 1280 7593861.729456 +1376 1280 -55157692.73435 +1386 1280 57871.30948763 +1387 1280 -32833355.865 +1388 1280 -37566373.58606 +1389 1280 781320.0962051 +1390 1280 -2152689.398522 +1391 1280 -91946096.11431 +1392 1280 11379085.18856 +1393 1280 35569610.71641 +1394 1280 -53430905.74636 +1404 1280 -10076852.32471 +1405 1280 -8246533.414749 +1406 1280 -16388848.63381 +1407 1280 -42894214.83411 +1408 1280 -694433.1761459 +1409 1280 -55531090.78464 +1410 1280 -11378935.65847 +1411 1280 8940966.590895 +1412 1280 -20295098.63508 +1281 1281 585665704.3843 +1282 1281 -24667941.68432 +1283 1281 -312397.5657639 +1296 1281 -49447220.48372 +1297 1281 -33611111.10559 +1298 1281 -12251149.01771 +1299 1281 -51062855.9649 +1300 1281 24550979.49731 +1301 1281 2614802.455998 +1302 1281 -390940047.3902 +1303 1281 27005851.07148 +1304 1281 -140787.7808927 +1374 1281 -4579449.609996 +1375 1281 11000120.58261 +1376 1281 12057631.64322 +1389 1281 -14225493.76444 +1390 1281 -9166787.248675 +1391 1281 -10019112.65448 +1392 1281 163714858.8002 +1393 1281 -8207285.558244 +1394 1281 4241855.317219 +1407 1281 -18482764.4945 +1408 1281 -9166666.669676 +1409 1281 -10076852.32471 +1410 1281 -23632031.88637 +1411 1281 8204207.520878 +1412 1281 -22609970.36319 +1413 1281 -160108670.9846 +1414 1281 7336411.37311 +1415 1281 -520782.4807296 +1282 1282 1212925807.182 +1283 1282 33470955.69176 +1296 1282 -33611111.10559 +1297 1282 -39363173.77667 +1298 1282 -6097121.576942 +1299 1282 24492498.40383 +1300 1282 81068219.8035 +1301 1282 10079426.66136 +1302 1282 40508776.6072 +1303 1282 -1042750551.21 +1304 1282 -9476246.029013 +1374 1282 7333413.72174 +1375 1282 -4579449.61 +1376 1282 -6430626.286135 +1389 1282 -9166747.055675 +1390 1282 -46308715.17675 +1391 1282 -32902986.62891 +1392 1282 -8207285.558244 +1393 1282 423632934.9284 +1394 1282 -1353225.115187 +1407 1282 -9166666.669676 +1408 1282 -15732561.20235 +1409 1282 -8246533.414749 +1410 1282 8202668.502206 +1411 1282 11650696.80984 +1412 1282 7172753.555873 +1413 1282 11004617.05965 +1414 1282 -425976457.6889 +1415 1282 20227336.59943 +1283 1283 619229339.1181 +1296 1283 -12633093.46245 +1297 1283 -6402677.132734 +1298 1283 -11231394.83281 +1299 1283 3766004.901116 +1300 1283 8616807.386232 +1301 1283 46987078.10111 +1302 1283 -211181.6713378 +1303 1283 -8860767.282742 +1304 1283 -390696289.2204 +1374 1283 8038421.095477 +1375 1283 -9645939.429201 +1376 1283 -12211865.62666 +1389 1283 -10019068.77473 +1390 1283 -33069655.68813 +1391 1283 -41500155.26984 +1392 1283 -4768610.272799 +1393 1283 -8558910.345734 +1394 1283 99719621.84851 +1407 1283 -10076852.32471 +1408 1283 -8246533.414749 +1409 1283 -16388848.63381 +1410 1283 -22783562.29616 +1411 1283 7202053.220155 +1412 1283 -21366221.56937 +1413 1283 -781173.7210934 +1414 1283 20019063.72315 +1415 1283 -161088669.2548 +1284 1284 645455824.6572 +1285 1284 3.814697265625e-06 +1286 1284 -4629696.72672 +1287 1284 69286959.53708 +1288 1284 -2.101063728333e-06 +1289 1284 -1157424.182251 +1305 1284 -109230745.6082 +1306 1284 1.281499862671e-06 +1307 1284 3425959.474268 +1308 1284 -51177807.60464 +1309 1284 33611111.10559 +1310 1284 13790517.64469 +1377 1284 -58783069.51046 +1378 1284 1.639127731323e-06 +1379 1284 42697451.81849 +1380 1284 -19844426.42677 +1381 1284 -9166666.669679 +1382 1284 11321064.34898 +1395 1284 57430602.85087 +1396 1284 3.8743019104e-06 +1397 1284 231485.2378496 +1398 1284 -6249019.844286 +1399 1284 -7.443130016327e-06 +1400 1284 57871.30949415 +1416 1284 -59172122.54065 +1417 1284 4.395842552185e-07 +1418 1284 -42928937.05631 +1419 1284 -19947608.24497 +1420 1284 9166666.669675 +1421 1284 -11378935.65847 +1285 1285 564783451.0405 +1286 1285 55554750.36598 +1287 1285 -3.129243850708e-06 +1288 1285 -58435019.09619 +1289 1285 -28666264.07173 +1305 1285 9.387731552124e-07 +1306 1285 38659326.41933 +1307 1285 13888687.59834 +1308 1285 33611111.10559 +1309 1285 -41093760.8976 +1310 1285 -7791566.021395 +1377 1285 6.034970283508e-07 +1378 1285 -18449398.9965 +1379 1285 -694433.1761458 +1380 1285 -9166666.669679 +1381 1285 -17094223.13462 +1382 1285 8871522.146427 +1395 1285 4.231929779053e-06 +1396 1285 35428976.52455 +1397 1285 -2777732.703215 +1398 1285 -7.599592208862e-06 +1399 1285 -41082283.77936 +1400 1285 35638866.34597 +1416 1285 4.619359970093e-07 +1417 1285 -18838452.02672 +1418 1285 -694433.1761459 +1419 1285 9166666.669675 +1420 1285 -17197404.95283 +1421 1285 8940966.590895 +1286 1286 756192654.5709 +1287 1286 -1157424.182251 +1288 1286 -26888486.29425 +1289 1286 51063391.07047 +1305 1286 1203737.252411 +1306 1286 13888687.59834 +1307 1286 83675565.4165 +1308 1286 13408573.19995 +1309 1286 -7486010.465602 +1310 1286 -15846293.82194 +1377 1286 42662729.59629 +1378 1286 -694433.1761458 +1379 1286 -54493616.03735 +1380 1286 11321064.34898 +1381 1286 8871522.146428 +1382 1286 -20019947.11985 +1395 1286 231485.2378493 +1396 1286 -2777732.703215 +1397 1286 -110039912.4136 +1398 1286 57871.30949473 +1399 1286 35611088.56821 +1400 1286 -53128242.27036 +1416 1286 -42894214.83411 +1417 1286 -694433.1761459 +1418 1286 -55531090.78464 +1419 1286 -11378935.65847 +1420 1286 8940966.590895 +1421 1286 -20295098.63508 +1287 1287 645455824.6572 +1288 1287 3.814697265625e-06 +1289 1287 -4629696.72672 +1290 1287 69286959.53708 +1291 1287 -2.101063728333e-06 +1292 1287 -1157424.182251 +1305 1287 -49447220.48372 +1306 1287 -33611111.10559 +1307 1287 -12251149.01771 +1308 1287 -109230745.6082 +1309 1287 1.281499862671e-06 +1310 1287 3425959.474268 +1311 1287 -51177807.60464 +1312 1287 33611111.10559 +1313 1287 13790517.64469 +1377 1287 -18391419.7975 +1378 1287 9166666.669678 +1379 1287 10018981.01522 +1380 1287 -58783069.51046 +1381 1287 1.639127731323e-06 +1382 1287 42697451.81849 +1383 1287 -19844426.42677 +1384 1287 -9166666.669679 +1385 1287 11321064.34898 +1395 1287 -413319.0876746 +1396 1287 3.017485141754e-06 +1397 1287 57871.30948708 +1398 1287 57430602.85087 +1399 1287 3.8743019104e-06 +1400 1287 231485.2378496 +1401 1287 -6249019.844286 +1402 1287 -7.443130016327e-06 +1403 1287 57871.30949415 +1416 1287 -18482764.4945 +1417 1287 -9166666.669676 +1418 1287 -10076852.32471 +1419 1287 -59172122.54065 +1420 1287 4.395842552185e-07 +1421 1287 -42928937.05631 +1422 1287 -19947608.24497 +1423 1287 9166666.669675 +1424 1287 -11378935.65847 +1288 1288 564783451.0405 +1289 1288 55554750.36598 +1290 1288 -3.129243850708e-06 +1291 1288 -58435019.09619 +1292 1288 -28666264.07173 +1305 1288 -33611111.10559 +1306 1288 -39363173.77667 +1307 1288 -6097121.576942 +1308 1288 9.387731552124e-07 +1309 1288 38659326.41933 +1310 1288 13888687.59834 +1311 1288 33611111.10559 +1312 1288 -41093760.8976 +1313 1288 -7791566.021395 +1377 1288 9166666.669678 +1378 1288 -15641216.50536 +1379 1288 -8177088.970282 +1380 1288 6.034970283508e-07 +1381 1288 -18449398.9965 +1382 1288 -694433.1761458 +1383 1288 -9166666.669679 +1384 1288 -17094223.13462 +1385 1288 8871522.146427 +1395 1288 4.06801700592e-06 +1396 1288 -35246583.02275 +1397 1288 -32861133.64276 +1398 1288 4.231929779053e-06 +1399 1288 35428976.52455 +1400 1288 -2777732.703215 +1401 1288 -7.599592208862e-06 +1402 1288 -41082283.77936 +1403 1288 35638866.34597 +1416 1288 -9166666.669676 +1417 1288 -15732561.20235 +1418 1288 -8246533.414749 +1419 1288 4.619359970093e-07 +1420 1288 -18838452.02672 +1421 1288 -694433.1761459 +1422 1288 9166666.669675 +1423 1288 -17197404.95283 +1424 1288 8940966.590895 +1289 1289 756192654.5709 +1290 1289 -1157424.182251 +1291 1289 -26888486.29425 +1292 1289 51063391.07047 +1305 1289 -12633093.46245 +1306 1289 -6402677.132734 +1307 1289 -11231394.83281 +1308 1289 1203737.252411 +1309 1289 13888687.59834 +1310 1289 83675565.4165 +1311 1289 13408573.19995 +1312 1289 -7486010.465602 +1313 1289 -15846293.82194 +1377 1289 10018981.01522 +1378 1289 -8177088.970282 +1379 1289 -16145262.77514 +1380 1289 42662729.59629 +1381 1289 -694433.1761458 +1382 1289 -54493616.03735 +1383 1289 11321064.34898 +1384 1289 8871522.146428 +1385 1289 -20019947.11985 +1395 1289 57871.30948763 +1396 1289 -32833355.865 +1397 1289 -37566373.58606 +1398 1289 231485.2378493 +1399 1289 -2777732.703215 +1400 1289 -110039912.4136 +1401 1289 57871.30949473 +1402 1289 35611088.56821 +1403 1289 -53128242.27036 +1416 1289 -10076852.32471 +1417 1289 -8246533.414749 +1418 1289 -16388848.63381 +1419 1289 -42894214.83411 +1420 1289 -694433.1761459 +1421 1289 -55531090.78464 +1422 1289 -11378935.65847 +1423 1289 8940966.590895 +1424 1289 -20295098.63508 +1290 1290 645455824.6572 +1291 1290 3.814697265625e-06 +1292 1290 -4629696.72672 +1293 1290 69286959.53708 +1294 1290 -2.101063728333e-06 +1295 1290 -1157424.182251 +1308 1290 -49447220.48372 +1309 1290 -33611111.10559 +1310 1290 -12251149.01771 +1311 1290 -109230745.6082 +1312 1290 1.281499862671e-06 +1313 1290 3425959.474268 +1314 1290 -51177807.60464 +1315 1290 33611111.10559 +1316 1290 13790517.64469 +1380 1290 -18391419.7975 +1381 1290 9166666.669678 +1382 1290 10018981.01522 +1383 1290 -58783069.51046 +1384 1290 1.639127731323e-06 +1385 1290 42697451.81849 +1386 1290 -19844426.42677 +1387 1290 -9166666.669679 +1388 1290 11321064.34898 +1398 1290 -413319.0876746 +1399 1290 3.017485141754e-06 +1400 1290 57871.30948708 +1401 1290 57430602.85087 +1402 1290 3.8743019104e-06 +1403 1290 231485.2378496 +1404 1290 -6249019.844286 +1405 1290 -7.443130016327e-06 +1406 1290 57871.30949415 +1419 1290 -18482764.4945 +1420 1290 -9166666.669676 +1421 1290 -10076852.32471 +1422 1290 -59172122.54065 +1423 1290 4.395842552185e-07 +1424 1290 -42928937.05631 +1425 1290 -19947608.24497 +1426 1290 9166666.669675 +1427 1290 -11378935.65847 +1291 1291 564783451.0405 +1292 1291 55554750.36598 +1293 1291 -3.129243850708e-06 +1294 1291 -58435019.09619 +1295 1291 -28666264.07173 +1308 1291 -33611111.10559 +1309 1291 -39363173.77667 +1310 1291 -6097121.576942 +1311 1291 9.387731552124e-07 +1312 1291 38659326.41933 +1313 1291 13888687.59834 +1314 1291 33611111.10559 +1315 1291 -41093760.8976 +1316 1291 -7791566.021395 +1380 1291 9166666.669678 +1381 1291 -15641216.50536 +1382 1291 -8177088.970282 +1383 1291 6.034970283508e-07 +1384 1291 -18449398.9965 +1385 1291 -694433.1761458 +1386 1291 -9166666.669679 +1387 1291 -17094223.13462 +1388 1291 8871522.146427 +1398 1291 4.06801700592e-06 +1399 1291 -35246583.02275 +1400 1291 -32861133.64276 +1401 1291 4.231929779053e-06 +1402 1291 35428976.52455 +1403 1291 -2777732.703215 +1404 1291 -7.599592208862e-06 +1405 1291 -41082283.77936 +1406 1291 35638866.34597 +1419 1291 -9166666.669676 +1420 1291 -15732561.20235 +1421 1291 -8246533.414749 +1422 1291 4.619359970093e-07 +1423 1291 -18838452.02672 +1424 1291 -694433.1761459 +1425 1291 9166666.669675 +1426 1291 -17197404.95283 +1427 1291 8940966.590895 +1292 1292 756192654.5709 +1293 1292 -1157424.182251 +1294 1292 -26888486.29425 +1295 1292 51063391.07047 +1308 1292 -12633093.46245 +1309 1292 -6402677.132734 +1310 1292 -11231394.83281 +1311 1292 1203737.252411 +1312 1292 13888687.59834 +1313 1292 83675565.4165 +1314 1292 13408573.19995 +1315 1292 -7486010.465602 +1316 1292 -15846293.82194 +1380 1292 10018981.01522 +1381 1292 -8177088.970282 +1382 1292 -16145262.77514 +1383 1292 42662729.59629 +1384 1292 -694433.1761458 +1385 1292 -54493616.03735 +1386 1292 11321064.34898 +1387 1292 8871522.146428 +1388 1292 -20019947.11985 +1398 1292 57871.30948763 +1399 1292 -32833355.865 +1400 1292 -37566373.58606 +1401 1292 231485.2378493 +1402 1292 -2777732.703215 +1403 1292 -110039912.4136 +1404 1292 57871.30949473 +1405 1292 35611088.56821 +1406 1292 -53128242.27036 +1419 1292 -10076852.32471 +1420 1292 -8246533.414749 +1421 1292 -16388848.63381 +1422 1292 -42894214.83411 +1423 1292 -694433.1761459 +1424 1292 -55531090.78464 +1425 1292 -11378935.65847 +1426 1292 8940966.590895 +1427 1292 -20295098.63508 +1293 1293 645455824.6572 +1294 1293 3.814697265625e-06 +1295 1293 -4629696.72672 +1296 1293 69286959.53708 +1297 1293 -2.101063728333e-06 +1298 1293 -1157424.182251 +1311 1293 -49447220.48372 +1312 1293 -33611111.10559 +1313 1293 -12251149.01771 +1314 1293 -109230745.6082 +1315 1293 1.281499862671e-06 +1316 1293 3425959.474268 +1317 1293 -51177807.60464 +1318 1293 33611111.10559 +1319 1293 13790517.64469 +1383 1293 -18391419.7975 +1384 1293 9166666.669678 +1385 1293 10018981.01522 +1386 1293 -58783069.51046 +1387 1293 1.639127731323e-06 +1388 1293 42697451.81849 +1389 1293 -19844426.42677 +1390 1293 -9166666.669679 +1391 1293 11321064.34898 +1401 1293 -413319.0876746 +1402 1293 3.017485141754e-06 +1403 1293 57871.30948708 +1404 1293 57430602.85087 +1405 1293 3.8743019104e-06 +1406 1293 231485.2378496 +1407 1293 -6249019.844286 +1408 1293 -7.443130016327e-06 +1409 1293 57871.30949415 +1422 1293 -18482764.4945 +1423 1293 -9166666.669676 +1424 1293 -10076852.32471 +1425 1293 -59172122.54065 +1426 1293 4.395842552185e-07 +1427 1293 -42928937.05631 +1428 1293 -19947608.24497 +1429 1293 9166666.669675 +1430 1293 -11378935.65847 +1294 1294 564783451.0405 +1295 1294 55554750.36598 +1296 1294 -3.129243850708e-06 +1297 1294 -58435019.09619 +1298 1294 -28666264.07173 +1311 1294 -33611111.10559 +1312 1294 -39363173.77667 +1313 1294 -6097121.576942 +1314 1294 9.387731552124e-07 +1315 1294 38659326.41933 +1316 1294 13888687.59834 +1317 1294 33611111.10559 +1318 1294 -41093760.8976 +1319 1294 -7791566.021395 +1383 1294 9166666.669678 +1384 1294 -15641216.50536 +1385 1294 -8177088.970282 +1386 1294 6.034970283508e-07 +1387 1294 -18449398.9965 +1388 1294 -694433.1761458 +1389 1294 -9166666.669679 +1390 1294 -17094223.13462 +1391 1294 8871522.146427 +1401 1294 4.06801700592e-06 +1402 1294 -35246583.02275 +1403 1294 -32861133.64276 +1404 1294 4.231929779053e-06 +1405 1294 35428976.52455 +1406 1294 -2777732.703215 +1407 1294 -7.599592208862e-06 +1408 1294 -41082283.77936 +1409 1294 35638866.34597 +1422 1294 -9166666.669676 +1423 1294 -15732561.20235 +1424 1294 -8246533.414749 +1425 1294 4.619359970093e-07 +1426 1294 -18838452.02672 +1427 1294 -694433.1761459 +1428 1294 9166666.669675 +1429 1294 -17197404.95283 +1430 1294 8940966.590895 +1295 1295 756192654.5709 +1296 1295 -1157424.182251 +1297 1295 -26888486.29425 +1298 1295 51063391.07047 +1311 1295 -12633093.46245 +1312 1295 -6402677.132734 +1313 1295 -11231394.83281 +1314 1295 1203737.252411 +1315 1295 13888687.59834 +1316 1295 83675565.4165 +1317 1295 13408573.19995 +1318 1295 -7486010.465602 +1319 1295 -15846293.82194 +1383 1295 10018981.01522 +1384 1295 -8177088.970282 +1385 1295 -16145262.77514 +1386 1295 42662729.59629 +1387 1295 -694433.1761458 +1388 1295 -54493616.03735 +1389 1295 11321064.34898 +1390 1295 8871522.146428 +1391 1295 -20019947.11985 +1401 1295 57871.30948763 +1402 1295 -32833355.865 +1403 1295 -37566373.58606 +1404 1295 231485.2378493 +1405 1295 -2777732.703215 +1406 1295 -110039912.4136 +1407 1295 57871.30949473 +1408 1295 35611088.56821 +1409 1295 -53128242.27036 +1422 1295 -10076852.32471 +1423 1295 -8246533.414749 +1424 1295 -16388848.63381 +1425 1295 -42894214.83411 +1426 1295 -694433.1761459 +1427 1295 -55531090.78464 +1428 1295 -11378935.65847 +1429 1295 8940966.590895 +1430 1295 -20295098.63508 +1296 1296 645455824.6572 +1297 1296 3.814697265625e-06 +1298 1296 -4629696.72672 +1299 1296 69286959.53708 +1300 1296 -2.101063728333e-06 +1301 1296 -1157424.182251 +1314 1296 -49447220.48372 +1315 1296 -33611111.10559 +1316 1296 -12251149.01771 +1317 1296 -109230745.6082 +1318 1296 1.281499862671e-06 +1319 1296 3425959.474268 +1320 1296 -51177807.60464 +1321 1296 33611111.10559 +1322 1296 13790517.64469 +1386 1296 -18391419.7975 +1387 1296 9166666.669678 +1388 1296 10018981.01522 +1389 1296 -58783069.51046 +1390 1296 1.639127731323e-06 +1391 1296 42697451.81849 +1392 1296 -19844426.42677 +1393 1296 -9166666.669679 +1394 1296 11321064.34898 +1404 1296 -413319.0876746 +1405 1296 3.017485141754e-06 +1406 1296 57871.30948708 +1407 1296 57430602.85087 +1408 1296 3.8743019104e-06 +1409 1296 231485.2378496 +1410 1296 -6249019.844286 +1411 1296 -7.443130016327e-06 +1412 1296 57871.30949415 +1425 1296 -18482764.4945 +1426 1296 -9166666.669676 +1427 1296 -10076852.32471 +1428 1296 -59172122.54065 +1429 1296 4.395842552185e-07 +1430 1296 -42928937.05631 +1431 1296 -19947608.24497 +1432 1296 9166666.669675 +1433 1296 -11378935.65847 +1297 1297 564783451.0405 +1298 1297 55554750.36598 +1299 1297 -3.129243850708e-06 +1300 1297 -58435019.09619 +1301 1297 -28666264.07173 +1314 1297 -33611111.10559 +1315 1297 -39363173.77667 +1316 1297 -6097121.576942 +1317 1297 9.387731552124e-07 +1318 1297 38659326.41933 +1319 1297 13888687.59834 +1320 1297 33611111.10559 +1321 1297 -41093760.8976 +1322 1297 -7791566.021395 +1386 1297 9166666.669678 +1387 1297 -15641216.50536 +1388 1297 -8177088.970282 +1389 1297 6.034970283508e-07 +1390 1297 -18449398.9965 +1391 1297 -694433.1761458 +1392 1297 -9166666.669679 +1393 1297 -17094223.13462 +1394 1297 8871522.146427 +1404 1297 4.06801700592e-06 +1405 1297 -35246583.02275 +1406 1297 -32861133.64276 +1407 1297 4.231929779053e-06 +1408 1297 35428976.52455 +1409 1297 -2777732.703215 +1410 1297 -7.599592208862e-06 +1411 1297 -41082283.77936 +1412 1297 35638866.34597 +1425 1297 -9166666.669676 +1426 1297 -15732561.20235 +1427 1297 -8246533.414749 +1428 1297 4.619359970093e-07 +1429 1297 -18838452.02672 +1430 1297 -694433.1761459 +1431 1297 9166666.669675 +1432 1297 -17197404.95283 +1433 1297 8940966.590895 +1298 1298 756192654.5709 +1299 1298 -1157424.182251 +1300 1298 -26888486.29425 +1301 1298 51063391.07047 +1314 1298 -12633093.46245 +1315 1298 -6402677.132734 +1316 1298 -11231394.83281 +1317 1298 1203737.252411 +1318 1298 13888687.59834 +1319 1298 83675565.4165 +1320 1298 13408573.19995 +1321 1298 -7486010.465602 +1322 1298 -15846293.82194 +1386 1298 10018981.01522 +1387 1298 -8177088.970282 +1388 1298 -16145262.77514 +1389 1298 42662729.59629 +1390 1298 -694433.1761458 +1391 1298 -54493616.03735 +1392 1298 11321064.34898 +1393 1298 8871522.146428 +1394 1298 -20019947.11985 +1404 1298 57871.30948763 +1405 1298 -32833355.865 +1406 1298 -37566373.58606 +1407 1298 231485.2378493 +1408 1298 -2777732.703215 +1409 1298 -110039912.4136 +1410 1298 57871.30949473 +1411 1298 35611088.56821 +1412 1298 -53128242.27036 +1425 1298 -10076852.32471 +1426 1298 -8246533.414749 +1427 1298 -16388848.63381 +1428 1298 -42894214.83411 +1429 1298 -694433.1761459 +1430 1298 -55531090.78464 +1431 1298 -11378935.65847 +1432 1298 8940966.590895 +1433 1298 -20295098.63508 +1299 1299 491276950.9903 +1300 1299 14806601.51898 +1301 1299 -3818422.289607 +1302 1299 -87383385.7527 +1303 1299 -70035624.56997 +1304 1299 -3641118.236221 +1317 1299 -49447220.48372 +1318 1299 -33611111.10559 +1319 1299 -12251149.01771 +1320 1299 -77292831.94718 +1321 1299 21747857.93987 +1322 1299 1956544.273544 +1323 1299 -42699882.91731 +1324 1299 8988666.707287 +1325 1299 1797596.462234 +1389 1299 -18391419.7975 +1390 1299 9166666.669678 +1391 1299 10018981.01522 +1392 1299 -23153309.42759 +1393 1299 8202668.502207 +1394 1299 22268765.65392 +1407 1299 -413319.0876746 +1408 1299 3.017485141754e-06 +1409 1299 57871.30948708 +1410 1299 68265937.74305 +1411 1299 4972552.434569 +1412 1299 136620.1412261 +1413 1299 -38378504.19399 +1414 1299 -20393185.43893 +1415 1299 10904728.81155 +1428 1299 -18482764.4945 +1429 1299 -9166666.669676 +1430 1299 -10076852.32471 +1431 1299 -43384348.52402 +1432 1299 6143828.422977 +1433 1299 -32706624.47957 +1434 1299 -20160575.07792 +1435 1299 1074136.079187 +1436 1299 -602925.9311655 +1300 1300 604598995.5615 +1301 1300 37277012.53792 +1302 1300 -70094105.66344 +1303 1300 -231857593.3807 +1304 1300 -8143757.767629 +1317 1300 -33611111.10559 +1318 1300 -39363173.77667 +1319 1300 -6097121.576942 +1320 1300 21747857.93987 +1321 1300 17898117.69298 +1322 1300 7160931.803441 +1323 1300 8988666.707287 +1324 1300 -131315860.0499 +1325 1300 -4390886.091072 +1389 1300 9166666.669678 +1390 1300 -15641216.50536 +1391 1300 -8177088.970282 +1392 1300 8204207.520877 +1393 1300 12129419.26863 +1394 1300 -8118315.333891 +1407 1300 4.06801700592e-06 +1408 1300 -35246583.02275 +1409 1300 -32861133.64276 +1410 1300 4972552.434566 +1411 1300 107051190.7071 +1412 1300 -2079037.895958 +1413 1300 -20394724.45761 +1414 1300 -79470228.63097 +1415 1300 34698117.36652 +1428 1300 -9166666.669676 +1429 1300 -15732561.20235 +1430 1300 -8246533.414749 +1431 1300 6143828.422977 +1432 1300 -19857535.41586 +1433 1300 7819016.563107 +1434 1300 1074136.079187 +1435 1300 -47330788.05857 +1436 1300 16965426.97932 +1301 1301 497207159.3263 +1302 1301 -3258224.345824 +1303 1301 -6887687.832126 +1304 1301 -52377574.72795 +1317 1301 -12633093.46245 +1318 1301 -6402677.132734 +1319 1301 -11231394.83281 +1320 1301 3519044.273286 +1321 1301 6855376.247936 +1322 1301 49759463.96313 +1323 1301 1033707.572752 +1324 1301 -4390886.091072 +1325 1301 -28228693.45994 +1389 1301 10018981.01522 +1390 1301 -8177088.970282 +1391 1301 -16145262.77514 +1392 1301 22442357.5869 +1393 1301 -8144741.575046 +1394 1301 -20089628.3459 +1407 1301 57871.30948763 +1408 1301 -32833355.865 +1409 1301 -37566373.58606 +1410 1301 136807.9549443 +1411 1301 -2078887.551707 +1412 1301 -39053108.69402 +1413 1301 10904842.27205 +1414 1301 34696841.30973 +1415 1301 -46645425.83998 +1428 1301 -10076852.32471 +1429 1301 -8246533.414749 +1430 1301 -16388848.63381 +1431 1301 -32880235.58879 +1432 1301 7819016.564698 +1433 1301 -47680406.12059 +1434 1301 -602925.9311654 +1435 1301 16965426.97932 +1436 1301 -27359753.63154 +1302 1302 748427414.7551 +1303 1302 16631311.86316 +1304 1302 -1850042.970848 +1320 1302 -46717612.54642 +1321 1302 -29761853.78616 +1322 1302 -1504257.272989 +1323 1302 44119848.09802 +1324 1302 36257674.87884 +1325 1302 2822647.309645 +1326 1302 66901986.07731 +1327 1302 -19503336.17053 +1328 1302 -18746.55804789 +1329 1302 3782927.556693 +1330 1302 25961532.27095 +1331 1302 339249.9533962 +1392 1302 -159624729.0253 +1393 1302 11004617.05965 +1394 1302 572723.0303333 +1410 1302 -37538860.21074 +1411 1302 -20394724.45761 +1412 1302 -10492248.91842 +1413 1302 145746193.545 +1414 1302 4821174.303457 +1415 1302 8338174.490712 +1431 1302 -18861959.6269 +1432 1302 -7862576.000248 +1433 1302 -10622738.80081 +1434 1302 -37300727.61412 +1435 1302 10723804.48332 +1436 1302 -41832926.99883 +1437 1302 -23212197.68204 +1438 1302 -5350103.986268 +1439 1302 14197971.68996 +1440 1302 -16690161.87378 +1441 1302 7057808.597695 +1442 1302 -10194843.38188 +1303 1303 1480675841.238 +1304 1303 8331896.126548 +1320 1303 -29761853.78616 +1321 1303 -13233472.25669 +1322 1303 290066.0256773 +1323 1303 36257674.87883 +1324 1303 161203877.6836 +1325 1303 2812011.040772 +1326 1303 -6058891.728297 +1327 1303 2376956.410093 +1328 1303 -290381.0699252 +1329 1303 25961532.27095 +1330 1303 -18223927.68573 +1331 1303 -360456.5943326 +1392 1303 7336411.373109 +1393 1303 -425492515.7295 +1394 1303 -13147629.82044 +1410 1303 -20393185.43894 +1411 1303 -78630584.64773 +1412 1303 -33781578.76871 +1413 1303 4821174.303456 +1414 1303 434483682.2102 +1415 1303 -3492649.630975 +1431 1303 -7862576.000248 +1432 1303 -8819552.279667 +1433 1303 -8595373.465755 +1434 1303 10723804.48332 +1435 1303 -5466319.193666 +1436 1303 7947549.067445 +1437 1303 -1683437.318397 +1438 1303 -40801616.79024 +1439 1303 33347935.147 +1440 1303 7057808.597695 +1441 1303 -22755536.05731 +1442 1303 16684907.19053 +1304 1304 944103154.1131 +1320 1304 -1886201.717729 +1321 1304 -15489.53011546 +1322 1304 4179508.007112 +1323 1304 1676813.9765 +1324 1304 2506455.485267 +1325 1304 209445391.5281 +1326 1304 -18746.55804396 +1327 1304 -290381.0699252 +1328 1304 139488909.5392 +1329 1304 339249.9532249 +1330 1304 -360456.5943326 +1331 1304 47699916.22173 +1392 1304 381815.353556 +1393 1304 -13300618.50896 +1394 1304 -159798157.3631 +1410 1304 -10492174.57703 +1411 1304 -33783025.80027 +1412 1304 -44406375.21794 +1413 1304 -8362936.617657 +1414 1304 -3856634.052932 +1415 1304 13357391.99385 +1431 1304 -10622738.80081 +1432 1304 -8595373.465755 +1433 1304 -15817835.62473 +1434 1304 -41832926.99887 +1435 1304 7947549.069036 +1436 1304 -79830320.55011 +1437 1304 6072971.68928 +1438 1304 33347935.147 +1439 1304 -72413820.75204 +1440 1304 -10194843.38188 +1441 1304 16684907.19053 +1442 1304 -34377395.78682 +1305 1305 319632302.4806 +1306 1305 2.861022949219e-06 +1307 1305 3240707.191283 +1308 1305 33898420.42483 +1309 1305 6722222.221118 +1310 1305 2980315.686967 +1395 1305 -58783069.51046 +1396 1305 1.639127731323e-06 +1397 1305 42697451.81849 +1398 1305 -19844426.42677 +1399 1305 -9166666.669679 +1400 1305 11321064.34898 +1416 1305 28714906.85473 +1417 1305 5.364418029785e-07 +1418 1305 -8530229.601834 +1419 1305 -3124509.92214 +1420 1305 1833333.333932 +1421 1305 -2241064.345998 +1306 1306 279296115.6723 +1307 1306 27777375.18299 +1308 1306 -6722222.221118 +1309 1306 -29962568.8918 +1310 1306 -14194243.147 +1395 1306 6.034970283508e-07 +1396 1306 -18449398.9965 +1397 1306 -694433.1761458 +1398 1306 -9166666.669679 +1399 1306 -17094223.13462 +1400 1306 8871522.146427 +1416 1306 8.940696716309e-07 +1417 1306 17714093.69157 +1418 1306 -1388866.351609 +1419 1306 -1833333.333939 +1420 1306 -20541141.88968 +1421 1306 17812488.72854 +1307 1307 369841367.6909 +1308 1307 -2228017.645512 +1309 1307 -13583132.03599 +1310 1307 23544870.61869 +1395 1307 42662729.59629 +1396 1307 -694433.1761458 +1397 1307 -54493616.03735 +1398 1307 11321064.34898 +1399 1307 8871522.146428 +1400 1307 -20019947.11985 +1416 1307 8588103.728686 +1417 1307 -1388866.351609 +1418 1307 -55021008.39532 +1419 1307 2298935.655493 +1420 1307 17812488.72855 +1421 1307 -26564121.13518 +1308 1308 319632302.4806 +1309 1308 2.861022949219e-06 +1310 1308 3240707.191283 +1311 1308 33898420.42483 +1312 1308 6722222.221118 +1313 1308 2980315.686967 +1395 1308 -18391419.7975 +1396 1308 9166666.669678 +1397 1308 10018981.01522 +1398 1308 -58783069.51046 +1399 1308 1.639127731323e-06 +1400 1308 42697451.81849 +1401 1308 -19844426.42677 +1402 1308 -9166666.669679 +1403 1308 11321064.34898 +1416 1308 -206659.5438359 +1417 1308 -1833333.333934 +1418 1308 -1980647.67925 +1419 1308 28714906.85473 +1420 1308 5.364418029785e-07 +1421 1308 -8530229.601834 +1422 1308 -3124509.92214 +1423 1308 1833333.333932 +1424 1308 -2241064.345998 +1309 1309 279296115.6723 +1310 1309 27777375.18299 +1311 1309 -6722222.221118 +1312 1309 -29962568.8918 +1313 1309 -14194243.147 +1395 1309 9166666.669678 +1396 1309 -15641216.50536 +1397 1309 -8177088.970282 +1398 1309 6.034970283508e-07 +1399 1309 -18449398.9965 +1400 1309 -694433.1761458 +1401 1309 -9166666.669679 +1402 1309 -17094223.13462 +1403 1309 8871522.146427 +1416 1309 1833333.333937 +1417 1309 -17623291.51138 +1418 1309 -16423622.37693 +1419 1309 8.940696716309e-07 +1420 1309 17714093.69157 +1421 1309 -1388866.351609 +1422 1309 -1833333.333939 +1423 1309 -20541141.88968 +1424 1309 17812488.72854 +1310 1310 369841367.6909 +1311 1310 -2228017.645512 +1312 1310 -13583132.03599 +1313 1310 23544870.61869 +1395 1310 10018981.01522 +1396 1310 -8177088.970282 +1397 1310 -16145262.77514 +1398 1310 42662729.59629 +1399 1310 -694433.1761458 +1400 1310 -54493616.03735 +1401 1310 11321064.34898 +1402 1310 8871522.146428 +1403 1310 -20019947.11985 +1416 1310 2038518.988737 +1417 1310 -16423622.37695 +1418 1310 -18783186.79303 +1419 1310 8588103.728686 +1420 1310 -1388866.351609 +1421 1310 -55021008.39532 +1422 1310 2298935.655493 +1423 1310 17812488.72855 +1424 1310 -26564121.13518 +1311 1311 319632302.4806 +1312 1311 2.861022949219e-06 +1313 1311 3240707.191283 +1314 1311 33898420.42483 +1315 1311 6722222.221118 +1316 1311 2980315.686967 +1398 1311 -18391419.7975 +1399 1311 9166666.669678 +1400 1311 10018981.01522 +1401 1311 -58783069.51046 +1402 1311 1.639127731323e-06 +1403 1311 42697451.81849 +1404 1311 -19844426.42677 +1405 1311 -9166666.669679 +1406 1311 11321064.34898 +1419 1311 -206659.5438359 +1420 1311 -1833333.333934 +1421 1311 -1980647.67925 +1422 1311 28714906.85473 +1423 1311 5.364418029785e-07 +1424 1311 -8530229.601834 +1425 1311 -3124509.92214 +1426 1311 1833333.333932 +1427 1311 -2241064.345998 +1312 1312 279296115.6723 +1313 1312 27777375.18299 +1314 1312 -6722222.221118 +1315 1312 -29962568.8918 +1316 1312 -14194243.147 +1398 1312 9166666.669678 +1399 1312 -15641216.50536 +1400 1312 -8177088.970282 +1401 1312 6.034970283508e-07 +1402 1312 -18449398.9965 +1403 1312 -694433.1761458 +1404 1312 -9166666.669679 +1405 1312 -17094223.13462 +1406 1312 8871522.146427 +1419 1312 1833333.333937 +1420 1312 -17623291.51138 +1421 1312 -16423622.37693 +1422 1312 8.940696716309e-07 +1423 1312 17714093.69157 +1424 1312 -1388866.351609 +1425 1312 -1833333.333939 +1426 1312 -20541141.88968 +1427 1312 17812488.72854 +1313 1313 369841367.6909 +1314 1313 -2228017.645512 +1315 1313 -13583132.03599 +1316 1313 23544870.61869 +1398 1313 10018981.01522 +1399 1313 -8177088.970282 +1400 1313 -16145262.77514 +1401 1313 42662729.59629 +1402 1313 -694433.1761458 +1403 1313 -54493616.03735 +1404 1313 11321064.34898 +1405 1313 8871522.146428 +1406 1313 -20019947.11985 +1419 1313 2038518.988737 +1420 1313 -16423622.37695 +1421 1313 -18783186.79303 +1422 1313 8588103.728686 +1423 1313 -1388866.351609 +1424 1313 -55021008.39532 +1425 1313 2298935.655493 +1426 1313 17812488.72855 +1427 1313 -26564121.13518 +1314 1314 319632302.4806 +1315 1314 2.861022949219e-06 +1316 1314 3240707.191283 +1317 1314 33898420.42483 +1318 1314 6722222.221118 +1319 1314 2980315.686967 +1401 1314 -18391419.7975 +1402 1314 9166666.669678 +1403 1314 10018981.01522 +1404 1314 -58783069.51046 +1405 1314 1.639127731323e-06 +1406 1314 42697451.81849 +1407 1314 -19844426.42677 +1408 1314 -9166666.669679 +1409 1314 11321064.34898 +1422 1314 -206659.5438359 +1423 1314 -1833333.333934 +1424 1314 -1980647.67925 +1425 1314 28714906.85473 +1426 1314 5.364418029785e-07 +1427 1314 -8530229.601834 +1428 1314 -3124509.92214 +1429 1314 1833333.333932 +1430 1314 -2241064.345998 +1315 1315 279296115.6723 +1316 1315 27777375.18299 +1317 1315 -6722222.221118 +1318 1315 -29962568.8918 +1319 1315 -14194243.147 +1401 1315 9166666.669678 +1402 1315 -15641216.50536 +1403 1315 -8177088.970282 +1404 1315 6.034970283508e-07 +1405 1315 -18449398.9965 +1406 1315 -694433.1761458 +1407 1315 -9166666.669679 +1408 1315 -17094223.13462 +1409 1315 8871522.146427 +1422 1315 1833333.333937 +1423 1315 -17623291.51138 +1424 1315 -16423622.37693 +1425 1315 8.940696716309e-07 +1426 1315 17714093.69157 +1427 1315 -1388866.351609 +1428 1315 -1833333.333939 +1429 1315 -20541141.88968 +1430 1315 17812488.72854 +1316 1316 369841367.6909 +1317 1316 -2228017.645512 +1318 1316 -13583132.03599 +1319 1316 23544870.61869 +1401 1316 10018981.01522 +1402 1316 -8177088.970282 +1403 1316 -16145262.77514 +1404 1316 42662729.59629 +1405 1316 -694433.1761458 +1406 1316 -54493616.03735 +1407 1316 11321064.34898 +1408 1316 8871522.146428 +1409 1316 -20019947.11985 +1422 1316 2038518.988737 +1423 1316 -16423622.37695 +1424 1316 -18783186.79303 +1425 1316 8588103.728686 +1426 1316 -1388866.351609 +1427 1316 -55021008.39532 +1428 1316 2298935.655493 +1429 1316 17812488.72855 +1430 1316 -26564121.13518 +1317 1317 319632302.4806 +1318 1317 2.861022949219e-06 +1319 1317 3240707.191283 +1320 1317 33898420.42483 +1321 1317 6722222.221118 +1322 1317 2980315.686967 +1404 1317 -18391419.7975 +1405 1317 9166666.669678 +1406 1317 10018981.01522 +1407 1317 -58783069.51046 +1408 1317 1.639127731323e-06 +1409 1317 42697451.81849 +1410 1317 -19844426.42677 +1411 1317 -9166666.669679 +1412 1317 11321064.34898 +1425 1317 -206659.5438359 +1426 1317 -1833333.333934 +1427 1317 -1980647.67925 +1428 1317 28714906.85473 +1429 1317 5.364418029785e-07 +1430 1317 -8530229.601834 +1431 1317 -3124509.92214 +1432 1317 1833333.333932 +1433 1317 -2241064.345998 +1318 1318 279296115.6723 +1319 1318 27777375.18299 +1320 1318 -6722222.221118 +1321 1318 -29962568.8918 +1322 1318 -14194243.147 +1404 1318 9166666.669678 +1405 1318 -15641216.50536 +1406 1318 -8177088.970282 +1407 1318 6.034970283508e-07 +1408 1318 -18449398.9965 +1409 1318 -694433.1761458 +1410 1318 -9166666.669679 +1411 1318 -17094223.13462 +1412 1318 8871522.146427 +1425 1318 1833333.333937 +1426 1318 -17623291.51138 +1427 1318 -16423622.37693 +1428 1318 8.940696716309e-07 +1429 1318 17714093.69157 +1430 1318 -1388866.351609 +1431 1318 -1833333.333939 +1432 1318 -20541141.88968 +1433 1318 17812488.72854 +1319 1319 369841367.6909 +1320 1319 -2228017.645512 +1321 1319 -13583132.03599 +1322 1319 23544870.61869 +1404 1319 10018981.01522 +1405 1319 -8177088.970282 +1406 1319 -16145262.77514 +1407 1319 42662729.59629 +1408 1319 -694433.1761458 +1409 1319 -54493616.03735 +1410 1319 11321064.34898 +1411 1319 8871522.146428 +1412 1319 -20019947.11985 +1425 1319 2038518.988737 +1426 1319 -16423622.37695 +1427 1319 -18783186.79303 +1428 1319 8588103.728686 +1429 1319 -1388866.351609 +1430 1319 -55021008.39532 +1431 1319 2298935.655493 +1432 1319 17812488.72855 +1433 1319 -26564121.13518 +1320 1320 292706109.3267 +1321 1320 3849993.374101 +1322 1320 -6845642.411734 +1323 1320 -1362952.211621 +1324 1320 -22724886.41228 +1325 1320 4466.524408698 +1407 1320 -18391419.7975 +1408 1320 9166666.669678 +1409 1320 10018981.01522 +1410 1320 -42844315.11718 +1411 1320 6143828.42298 +1412 1320 32439903.28737 +1413 1320 -19056485.08992 +1414 1320 -7862576.000246 +1415 1320 10773788.984 +1428 1320 -206659.5438359 +1429 1320 -1833333.333934 +1430 1320 -1980647.67925 +1431 1320 28878510.79233 +1432 1320 1304325.673737 +1433 1320 -8034871.658814 +1434 1320 -18263780.54944 +1435 1320 -6918911.432209 +1436 1320 8066734.94041 +1321 1321 275777719.2542 +1322 1321 17498346.56299 +1323 1321 -36169330.85452 +1324 1321 -59332709.45945 +1325 1321 -3269090.779215 +1407 1321 9166666.669678 +1408 1321 -15641216.50536 +1409 1321 -8177088.970282 +1410 1321 6143828.422979 +1411 1321 -19317502.00901 +1412 1321 -8396261.212014 +1413 1321 -7862576.000246 +1414 1321 -9014077.742685 +1415 1321 8522682.095422 +1428 1321 1833333.333937 +1429 1321 -17623291.51138 +1430 1321 -16423622.37693 +1431 1321 1304325.673737 +1432 1321 25172041.03341 +1433 1321 -904397.1795395 +1434 1321 -10585578.10008 +1435 1321 -33460102.57053 +1436 1321 25378687.64334 +1322 1322 306182737.1243 +1323 1322 -1419144.586472 +1324 1322 -2963535.22371 +1325 1322 32321915.28632 +1407 1322 10018981.01522 +1408 1322 -8177088.970282 +1409 1322 -16145262.77514 +1410 1322 32613514.40058 +1411 1322 -8396261.210409 +1412 1322 -46240317.03562 +1413 1322 10773788.984 +1414 1322 8522682.095422 +1415 1322 -16336570.1928 +1428 1322 2038518.988737 +1429 1322 -16423622.37695 +1430 1322 -18783186.79303 +1431 1322 9082906.116151 +1432 1322 -904397.1795395 +1433 1322 -52999059.66538 +1434 1322 12398123.82872 +1435 1322 25378687.64175 +1436 1322 -35853335.01949 +1323 1323 351474505.4045 +1324 1323 43278658.3616 +1325 1323 5396404.4899 +1326 1323 -61121044.65449 +1327 1323 -41260689.94024 +1328 1323 -528805.6021204 +1329 1323 15684474.19606 +1330 1323 -11094979.15296 +1331 1323 -186753.6278738 +1410 1323 -19715237.85133 +1411 1323 1074136.079186 +1412 1323 524851.8469836 +1413 1323 -37144610.97898 +1414 1323 10723804.48332 +1415 1323 41672628.54298 +1431 1323 -17529221.15356 +1432 1323 -10585578.10008 +1433 1323 -12149931.72292 +1434 1323 -1095063.644689 +1435 1323 13148490.57674 +1436 1323 -8461748.97526 +1437 1323 -34526661.87963 +1438 1323 -11275524.74166 +1439 1323 20339184.40592 +1440 1323 -25557949.75669 +1441 1323 -3085328.297506 +1442 1323 8108904.791231 +1324 1324 428079692.8527 +1325 1324 6359867.73056 +1326 1324 -41260689.94024 +1327 1324 -42562917.26492 +1328 1324 -360456.5943327 +1329 1324 -24539423.5952 +1330 1324 -49977135.84681 +1331 1324 -1151445.306695 +1410 1324 1074136.079186 +1411 1324 -46885450.83199 +1412 1324 -16367906.36496 +1413 1324 10723804.48332 +1414 1324 -5310202.55853 +1415 1324 -8267728.707675 +1431 1324 -6918911.432211 +1432 1324 -32725543.17465 +1433 1324 -25072701.23725 +1434 1324 13148490.57674 +1435 1324 22270764.74516 +1436 1324 -368264.4629124 +1437 1324 -11275524.74166 +1438 1324 -29444223.55951 +1439 1324 16684907.19053 +1440 1324 -6751994.965377 +1441 1324 -43474089.88536 +1442 1324 33391693.58226 +1325 1325 502747367.9195 +1326 1325 -528805.6021202 +1327 1325 -360456.5943328 +1328 1325 23360926.64254 +1329 1325 -533975.8500424 +1330 1325 -1151445.306695 +1331 1325 76606286.52403 +1410 1325 524851.8469835 +1411 1325 -16367906.36496 +1412 1325 -26172187.69396 +1413 1325 41672628.54301 +1414 1325 -8267728.706071 +1415 1325 -79414009.52307 +1431 1325 -7922709.501298 +1432 1325 -25072701.23886 +1433 1325 -33894509.96379 +1434 1325 8239362.133108 +1435 1325 -368264.4629123 +1436 1325 -122620538.7512 +1437 1325 20339184.40592 +1438 1325 16684907.19053 +1439 1325 -41066083.28901 +1440 1325 12197515.90567 +1441 1325 33391693.58226 +1442 1325 -58349324.81867 +1326 1326 234754680.5278 +1327 1326 46392225.05501 +1328 1326 308098.4098136 +1329 1326 3111044.699987 +1330 1326 927356.613524 +1331 1326 239453.7503519 +1413 1326 -23117500.71233 +1414 1326 -1683437.318397 +1415 1326 -6070778.306718 +1434 1326 -34431964.90992 +1435 1326 -11275524.74166 +1436 1326 -20285815.60742 +1437 1326 -18665832.59106 +1438 1326 12683437.32201 +1439 1326 8109435.714787 +1440 1326 -34533186.62789 +1441 1326 275524.7380462 +1442 1326 -30502841.80065 +1327 1327 217352626.8751 +1328 1327 290381.0699289 +1329 1327 14371801.05576 +1330 1327 66480000.63031 +1331 1327 360456.594335 +1413 1327 -5350103.986268 +1414 1327 -40706919.82054 +1415 1327 -33318731.50871 +1434 1327 -11275524.74166 +1435 1327 -29349526.58979 +1436 1327 -16648426.15375 +1437 1327 12683437.32201 +1438 1327 -23420163.4902 +1439 1327 6652064.846425 +1440 1327 3942191.405917 +1441 1327 -17271874.94068 +1442 1327 3315092.816032 +1328 1328 364529562.5681 +1329 1328 239453.750356 +1330 1328 360456.5943349 +1331 1328 122345045.6517 +1413 1328 -14195778.30738 +1414 1328 -33318731.50871 +1415 1328 -72161295.49948 +1434 1328 -20285815.60742 +1435 1328 -16648426.15375 +1436 1328 -40813558.03643 +1437 1328 -8140564.282544 +1438 1328 -6681268.484718 +1439 1328 -121188010.0031 +1440 1328 -30502841.80265 +1441 1328 -3351573.852824 +1442 1328 -61166429.37081 +1329 1329 172214886.8966 +1330 1329 -15793909.73151 +1331 1329 649716.5911349 +1413 1329 -16595464.90406 +1414 1329 7057808.597695 +1415 1329 10161406.6248 +1434 1329 -25273858.84771 +1435 1329 -6751994.965378 +1436 1329 -12142484.09433 +1437 1329 -34533186.62789 +1438 1329 3942191.405919 +1439 1329 30478408.18933 +1440 1329 -12139913.87007 +1441 1329 -4248005.038235 +1442 1329 -4104552.942003 +1330 1330 196514396.2516 +1331 1330 1151445.306701 +1413 1330 7057808.597695 +1414 1330 -22660839.0876 +1415 1330 -16648426.15375 +1434 1330 -3085328.297507 +1435 1330 -43189998.97639 +1436 1330 -33274973.07346 +1437 1330 275524.7380478 +1438 1330 -17271874.94068 +1439 1330 3315092.816032 +1440 1330 -4248005.038235 +1441 1330 -5419711.245076 +1442 1330 6608306.41117 +1331 1331 272797640.5341 +1413 1331 10161406.6248 +1414 1331 -16648426.15375 +1415 1331 -34124870.53423 +1434 1331 -8088595.202104 +1435 1331 -33274973.07346 +1436 1331 -57591749.06139 +1437 1331 30478408.18734 +1438 1331 -3351573.852824 +1439 1331 -61166429.37081 +1440 1331 4037947.05666 +1441 1331 -6725026.919973 +1442 1331 -83230082.36618 +1332 1332 383498024.544 +1333 1332 36666666.66064 +1334 1332 2662179.892796 +1335 1332 -204675200.5845 +1336 1332 -36666988.20463 +1337 1332 -2662156.039165 +1338 1332 11810466.31493 +1339 1332 29333654.8725 +1340 1332 -2152800.8684 +1443 1332 35932670.30059 +1444 1332 9166666.669679 +1445 1332 9311563.653784 +1446 1332 -72925641.46158 +1447 1332 -9166747.055676 +1448 1332 -43478968.03166 +1449 1332 -7497354.851903 +1450 1332 7333413.72174 +1451 1332 -9080099.689708 +1333 1333 328493596.9861 +1334 1333 -6944376.434009 +1335 1333 -36667148.97662 +1336 1333 -32338700.60373 +1337 1333 -3847226.785359 +1338 1333 44000482.30876 +1339 1333 11810466.31493 +1340 1333 2416693.76713 +1443 1333 9166666.669678 +1444 1333 22181563.40434 +1445 1333 5180609.664774 +1446 1333 -9166787.248676 +1447 1333 -29841516.44517 +1448 1333 -9524419.110191 +1449 1333 11000120.58261 +1450 1333 -7497354.8519 +1451 1333 10895952.52268 +1334 1334 364686604.8413 +1335 1334 -2662144.112346 +1336 1334 -3097217.751863 +1337 1334 -5157813.372203 +1338 1334 -3229201.302601 +1339 1334 1611129.178087 +1340 1334 31494576.83983 +1443 1334 -7806863.548506 +1444 1334 -8513909.758068 +1445 1334 -68673244.4318 +1446 1334 -43444243.01831 +1447 1334 -9329934.937092 +1448 1334 -59307696.78438 +1449 1334 -13620149.53456 +1450 1334 7263968.348454 +1451 1334 -19992946.27174 +1335 1335 665854880.679 +1336 1335 36667470.52063 +1337 1335 3125090.734117 +1338 1335 18070347.2503 +1339 1335 -36666988.20464 +1340 1335 2702571.265064 +1341 1335 -140008022.8906 +1342 1335 2.577900886536e-06 +1343 1335 -462970.4754454 +1344 1335 -52702268.47617 +1345 1335 36666666.66064 +1346 1335 -2702548.174055 +1443 1335 -71369389.94283 +1444 1335 -9166787.24867 +1445 1335 42147892.99313 +1446 1335 76553135.92261 +1447 1335 9166867.634673 +1448 1335 781226.2244361 +1449 1335 -18699525.19313 +1450 1335 -9166747.055676 +1451 1335 11379035.3452 +1452 1335 -59172122.54065 +1453 1335 4.395842552185e-07 +1454 1335 -42928937.05631 +1455 1335 -19947608.24497 +1456 1335 9166666.669675 +1457 1335 -11378935.65847 +1336 1336 566847200.4901 +1337 1336 -8610909.306622 +1338 1336 -36667148.97663 +1339 1336 -110262538.3357 +1340 1336 4611016.915367 +1341 1336 2.831220626831e-06 +1342 1336 21326659.08566 +1343 1336 -2777732.703214 +1344 1336 36666666.66064 +1345 1336 -41701455.31301 +1346 1336 1513866.351594 +1443 1336 -9166747.055672 +1444 1336 -28285264.92641 +1445 1336 7788270.809731 +1446 1336 9166867.634673 +1447 1336 51801215.86321 +1448 1336 -2152764.494718 +1449 1336 -9166787.248675 +1450 1336 -50782746.60544 +1451 1336 35402941.77273 +1452 1336 4.619359970093e-07 +1453 1336 -18838452.02672 +1454 1336 -694433.1761459 +1455 1336 9166666.669675 +1456 1336 -17197404.95283 +1457 1336 8940966.590895 +1337 1337 591261848.0956 +1338 1337 2737305.032771 +1339 1337 5388803.421584 +1340 1337 33925571.74906 +1341 1337 -462970.4754449 +1342 1337 -2777732.703214 +1343 1337 35690216.05203 +1344 1337 -2737270.396254 +1345 1337 1541644.129353 +1346 1337 -8945289.261872 +1443 1337 42113167.97979 +1444 1337 7593861.729456 +1445 1337 -55157692.73435 +1446 1337 781320.0962051 +1447 1337 -2152689.398522 +1448 1337 -91946096.11431 +1449 1337 11379085.18856 +1450 1337 35569610.71641 +1451 1337 -53430905.74636 +1452 1337 -42894214.83411 +1453 1337 -694433.1761459 +1454 1337 -55531090.78464 +1455 1337 -11378935.65847 +1456 1337 8940966.590895 +1457 1337 -20295098.63508 +1338 1338 383498024.544 +1339 1338 36666666.66064 +1340 1338 2662179.892796 +1341 1338 -52678594.23377 +1342 1338 -36666666.66064 +1343 1338 2505785.158418 +1344 1338 -204675200.5845 +1345 1338 -36666988.20463 +1346 1338 -2662156.039165 +1347 1338 11810466.31493 +1348 1338 29333654.8725 +1349 1338 -2152800.8684 +1443 1338 -4579449.609996 +1444 1338 11000120.58261 +1445 1338 12057631.64322 +1446 1338 -14225493.76444 +1447 1338 -9166787.248675 +1448 1338 -10019112.65448 +1449 1338 35932670.30059 +1450 1338 9166666.669679 +1451 1338 9311563.653784 +1452 1338 -18482764.4945 +1453 1338 -9166666.669676 +1454 1338 -10076852.32471 +1455 1338 -72925641.46158 +1456 1338 -9166747.055676 +1457 1338 -43478968.03166 +1458 1338 -7497354.851903 +1459 1338 7333413.72174 +1460 1338 -9080099.689708 +1339 1339 328493596.9861 +1340 1339 -6944376.43401 +1341 1339 -36666666.66065 +1342 1339 -41677781.0706 +1343 1339 1263866.351621 +1344 1339 -36667148.97662 +1345 1339 -32338700.60373 +1346 1339 -3847226.785359 +1347 1339 44000482.30876 +1348 1339 11810466.31493 +1349 1339 2416693.76713 +1443 1339 7333413.72174 +1444 1339 -4579449.61 +1445 1339 -6430626.286135 +1446 1339 -9166747.055675 +1447 1339 -46308715.17675 +1448 1339 -32902986.62891 +1449 1339 9166666.669678 +1450 1339 22181563.40434 +1451 1339 5180609.664774 +1452 1339 -9166666.669676 +1453 1339 -15732561.20235 +1454 1339 -8246533.414749 +1455 1339 -9166787.248676 +1456 1339 -29841516.44517 +1457 1339 -9524419.110191 +1458 1339 11000120.58261 +1459 1339 -7497354.8519 +1460 1339 10895952.52268 +1340 1340 364686604.8413 +1341 1340 2471062.936219 +1342 1340 1236088.573861 +1343 1340 -8882157.948759 +1344 1340 -2662144.112346 +1345 1340 -3097217.751863 +1346 1340 -5157813.372203 +1347 1340 -3229201.302601 +1348 1340 1611129.178087 +1349 1340 31494576.83983 +1443 1340 8038421.095477 +1444 1340 -9645939.429201 +1445 1340 -12211865.62666 +1446 1340 -10019068.77473 +1447 1340 -33069655.68813 +1448 1340 -41500155.26984 +1449 1340 -7806863.548506 +1450 1340 -8513909.758068 +1451 1340 -68673244.4318 +1452 1340 -10076852.32471 +1453 1340 -8246533.414749 +1454 1340 -16388848.63381 +1455 1340 -43444243.01831 +1456 1340 -9329934.937092 +1457 1340 -59307696.78438 +1458 1340 -13620149.53456 +1459 1340 7263968.348454 +1460 1340 -19992946.27174 +1341 1341 613328698.917 +1342 1341 1.621246337891e-05 +1343 1341 925940.9508365 +1344 1341 82577683.23799 +1345 1341 -7.659196853638e-06 +1346 1341 231485.2378237 +1350 1341 -140008022.8906 +1351 1341 2.577900886536e-06 +1352 1341 -462970.4754454 +1353 1341 -52702268.47617 +1354 1341 36666666.66064 +1355 1341 -2702548.174055 +1446 1341 -58783069.51046 +1447 1341 1.639127731323e-06 +1448 1341 42697451.81849 +1449 1341 -19844426.42677 +1450 1341 -9166666.669679 +1451 1341 11321064.34898 +1452 1341 57430602.85087 +1453 1341 3.8743019104e-06 +1454 1341 231485.2378496 +1455 1341 -6249019.844286 +1456 1341 -7.443130016327e-06 +1457 1341 57871.30949415 +1461 1341 -59172122.54065 +1462 1341 4.395842552185e-07 +1463 1341 -42928937.05631 +1464 1341 -19947608.24497 +1465 1341 9166666.669675 +1466 1341 -11378935.65847 +1342 1342 525322193.6551 +1343 1342 -11110930.80738 +1344 1342 -7.525086402893e-06 +1345 1342 -56755372.43366 +1346 1342 5555465.403692 +1350 1342 2.831220626831e-06 +1351 1342 21326659.08566 +1352 1342 -2777732.703214 +1353 1342 36666666.66064 +1354 1342 -41701455.31301 +1355 1342 1513866.351594 +1446 1342 6.034970283508e-07 +1447 1342 -18449398.9965 +1448 1342 -694433.1761458 +1449 1342 -9166666.669679 +1450 1342 -17094223.13462 +1451 1342 8871522.146427 +1452 1342 4.231929779053e-06 +1453 1342 35428976.52455 +1454 1342 -2777732.703215 +1455 1342 -7.599592208862e-06 +1456 1342 -41082283.77936 +1457 1342 35638866.34597 +1461 1342 4.619359970093e-07 +1462 1342 -18838452.02672 +1463 1342 -694433.1761459 +1464 1342 9166666.669675 +1465 1342 -17197404.95283 +1466 1342 8940966.590895 +1343 1343 582790450.9006 +1344 1343 231485.2378239 +1345 1343 5555465.403692 +1346 1343 74350397.96411 +1350 1343 -462970.4754449 +1351 1343 -2777732.703214 +1352 1343 35690216.05203 +1353 1343 -2737270.396254 +1354 1343 1541644.129353 +1355 1343 -8945289.261872 +1446 1343 42662729.59629 +1447 1343 -694433.1761458 +1448 1343 -54493616.03735 +1449 1343 11321064.34898 +1450 1343 8871522.146428 +1451 1343 -20019947.11985 +1452 1343 231485.2378493 +1453 1343 -2777732.703215 +1454 1343 -110039912.4136 +1455 1343 57871.30949473 +1456 1343 35611088.56821 +1457 1343 -53128242.27036 +1461 1343 -42894214.83411 +1462 1343 -694433.1761459 +1463 1343 -55531090.78464 +1464 1343 -11378935.65847 +1465 1343 8940966.590895 +1466 1343 -20295098.63508 +1344 1344 665854880.679 +1345 1344 36667470.52063 +1346 1344 3125090.734117 +1347 1344 18070347.2503 +1348 1344 -36666988.20464 +1349 1344 2702571.265064 +1350 1344 -52678594.23377 +1351 1344 -36666666.66064 +1352 1344 2505785.158418 +1353 1344 -140008022.8906 +1354 1344 2.577900886536e-06 +1355 1344 -462970.4754454 +1356 1344 -52702268.47617 +1357 1344 36666666.66064 +1358 1344 -2702548.174055 +1446 1344 -18391419.7975 +1447 1344 9166666.669678 +1448 1344 10018981.01522 +1449 1344 -71369389.94283 +1450 1344 -9166787.24867 +1451 1344 42147892.99313 +1452 1344 -413319.0876746 +1453 1344 3.017485141754e-06 +1454 1344 57871.30948708 +1455 1344 76553135.92261 +1456 1344 9166867.634673 +1457 1344 781226.2244361 +1458 1344 -18699525.19313 +1459 1344 -9166747.055676 +1460 1344 11379035.3452 +1461 1344 -18482764.4945 +1462 1344 -9166666.669676 +1463 1344 -10076852.32471 +1464 1344 -59172122.54065 +1465 1344 4.395842552185e-07 +1466 1344 -42928937.05631 +1467 1344 -19947608.24497 +1468 1344 9166666.669675 +1469 1344 -11378935.65847 +1345 1345 566847200.4901 +1346 1345 -8610909.306622 +1347 1345 -36667148.97663 +1348 1345 -110262538.3357 +1349 1345 4611016.915367 +1350 1345 -36666666.66065 +1351 1345 -41677781.0706 +1352 1345 1263866.351621 +1353 1345 2.831220626831e-06 +1354 1345 21326659.08566 +1355 1345 -2777732.703214 +1356 1345 36666666.66064 +1357 1345 -41701455.31301 +1358 1345 1513866.351594 +1446 1345 9166666.669678 +1447 1345 -15641216.50536 +1448 1345 -8177088.970282 +1449 1345 -9166747.055672 +1450 1345 -28285264.92641 +1451 1345 7788270.809731 +1452 1345 4.06801700592e-06 +1453 1345 -35246583.02275 +1454 1345 -32861133.64276 +1455 1345 9166867.634673 +1456 1345 51801215.86321 +1457 1345 -2152764.494718 +1458 1345 -9166787.248675 +1459 1345 -50782746.60544 +1460 1345 35402941.77273 +1461 1345 -9166666.669676 +1462 1345 -15732561.20235 +1463 1345 -8246533.414749 +1464 1345 4.619359970093e-07 +1465 1345 -18838452.02672 +1466 1345 -694433.1761459 +1467 1345 9166666.669675 +1468 1345 -17197404.95283 +1469 1345 8940966.590895 +1346 1346 591261848.0956 +1347 1346 2737305.032771 +1348 1346 5388803.421584 +1349 1346 33925571.74906 +1350 1346 2471062.936219 +1351 1346 1236088.573861 +1352 1346 -8882157.948759 +1353 1346 -462970.4754449 +1354 1346 -2777732.703214 +1355 1346 35690216.05203 +1356 1346 -2737270.396254 +1357 1346 1541644.129353 +1358 1346 -8945289.261872 +1446 1346 10018981.01522 +1447 1346 -8177088.970282 +1448 1346 -16145262.77514 +1449 1346 42113167.97979 +1450 1346 7593861.729456 +1451 1346 -55157692.73435 +1452 1346 57871.30948763 +1453 1346 -32833355.865 +1454 1346 -37566373.58606 +1455 1346 781320.0962051 +1456 1346 -2152689.398522 +1457 1346 -91946096.11431 +1458 1346 11379085.18856 +1459 1346 35569610.71641 +1460 1346 -53430905.74636 +1461 1346 -10076852.32471 +1462 1346 -8246533.414749 +1463 1346 -16388848.63381 +1464 1346 -42894214.83411 +1465 1346 -694433.1761459 +1466 1346 -55531090.78464 +1467 1346 -11378935.65847 +1468 1346 8940966.590895 +1469 1346 -20295098.63508 +1347 1347 383498024.544 +1348 1347 36666666.66064 +1349 1347 2662179.892796 +1353 1347 -52678594.23377 +1354 1347 -36666666.66064 +1355 1347 2505785.158418 +1356 1347 -204675200.5845 +1357 1347 -36666988.20463 +1358 1347 -2662156.039165 +1359 1347 11810466.31493 +1360 1347 29333654.8725 +1361 1347 -2152800.8684 +1449 1347 -4579449.609996 +1450 1347 11000120.58261 +1451 1347 12057631.64322 +1455 1347 -14225493.76444 +1456 1347 -9166787.248675 +1457 1347 -10019112.65448 +1458 1347 35932670.30059 +1459 1347 9166666.669679 +1460 1347 9311563.653784 +1464 1347 -18482764.4945 +1465 1347 -9166666.669676 +1466 1347 -10076852.32471 +1467 1347 -72925641.46158 +1468 1347 -9166747.055676 +1469 1347 -43478968.03166 +1470 1347 -7497354.851903 +1471 1347 7333413.72174 +1472 1347 -9080099.689708 +1348 1348 328493596.9861 +1349 1348 -6944376.43401 +1353 1348 -36666666.66065 +1354 1348 -41677781.0706 +1355 1348 1263866.351621 +1356 1348 -36667148.97662 +1357 1348 -32338700.60373 +1358 1348 -3847226.785359 +1359 1348 44000482.30876 +1360 1348 11810466.31493 +1361 1348 2416693.76713 +1449 1348 7333413.72174 +1450 1348 -4579449.61 +1451 1348 -6430626.286135 +1455 1348 -9166747.055675 +1456 1348 -46308715.17675 +1457 1348 -32902986.62891 +1458 1348 9166666.669678 +1459 1348 22181563.40434 +1460 1348 5180609.664774 +1464 1348 -9166666.669676 +1465 1348 -15732561.20235 +1466 1348 -8246533.414749 +1467 1348 -9166787.248676 +1468 1348 -29841516.44517 +1469 1348 -9524419.110191 +1470 1348 11000120.58261 +1471 1348 -7497354.8519 +1472 1348 10895952.52268 +1349 1349 364686604.8413 +1353 1349 2471062.936219 +1354 1349 1236088.573861 +1355 1349 -8882157.948759 +1356 1349 -2662144.112346 +1357 1349 -3097217.751863 +1358 1349 -5157813.372203 +1359 1349 -3229201.302601 +1360 1349 1611129.178087 +1361 1349 31494576.83983 +1449 1349 8038421.095477 +1450 1349 -9645939.429201 +1451 1349 -12211865.62666 +1455 1349 -10019068.77473 +1456 1349 -33069655.68813 +1457 1349 -41500155.26984 +1458 1349 -7806863.548506 +1459 1349 -8513909.758068 +1460 1349 -68673244.4318 +1464 1349 -10076852.32471 +1465 1349 -8246533.414749 +1466 1349 -16388848.63381 +1467 1349 -43444243.01831 +1468 1349 -9329934.937092 +1469 1349 -59307696.78438 +1470 1349 -13620149.53456 +1471 1349 7263968.348454 +1472 1349 -19992946.27174 +1350 1350 613328698.917 +1351 1350 1.621246337891e-05 +1352 1350 925940.9508365 +1353 1350 82577683.23799 +1354 1350 -7.659196853638e-06 +1355 1350 231485.2378237 +1362 1350 -140008022.8906 +1363 1350 2.577900886536e-06 +1364 1350 -462970.4754454 +1365 1350 -52702268.47617 +1366 1350 36666666.66064 +1367 1350 -2702548.174055 +1452 1350 -58783069.51046 +1453 1350 1.639127731323e-06 +1454 1350 42697451.81849 +1455 1350 -19844426.42677 +1456 1350 -9166666.669679 +1457 1350 11321064.34898 +1461 1350 57430602.85087 +1462 1350 3.8743019104e-06 +1463 1350 231485.2378496 +1464 1350 -6249019.844286 +1465 1350 -7.443130016327e-06 +1466 1350 57871.30949415 +1473 1350 -59172122.54065 +1474 1350 4.395842552185e-07 +1475 1350 -42928937.05631 +1476 1350 -19947608.24497 +1477 1350 9166666.669675 +1478 1350 -11378935.65847 +1351 1351 525322193.6551 +1352 1351 -11110930.80738 +1353 1351 -7.525086402893e-06 +1354 1351 -56755372.43366 +1355 1351 5555465.403692 +1362 1351 2.831220626831e-06 +1363 1351 21326659.08566 +1364 1351 -2777732.703214 +1365 1351 36666666.66064 +1366 1351 -41701455.31301 +1367 1351 1513866.351594 +1452 1351 6.034970283508e-07 +1453 1351 -18449398.9965 +1454 1351 -694433.1761458 +1455 1351 -9166666.669679 +1456 1351 -17094223.13462 +1457 1351 8871522.146427 +1461 1351 4.231929779053e-06 +1462 1351 35428976.52455 +1463 1351 -2777732.703215 +1464 1351 -7.599592208862e-06 +1465 1351 -41082283.77936 +1466 1351 35638866.34597 +1473 1351 4.619359970093e-07 +1474 1351 -18838452.02672 +1475 1351 -694433.1761459 +1476 1351 9166666.669675 +1477 1351 -17197404.95283 +1478 1351 8940966.590895 +1352 1352 582790450.9006 +1353 1352 231485.2378239 +1354 1352 5555465.403692 +1355 1352 74350397.96411 +1362 1352 -462970.4754449 +1363 1352 -2777732.703214 +1364 1352 35690216.05203 +1365 1352 -2737270.396254 +1366 1352 1541644.129353 +1367 1352 -8945289.261872 +1452 1352 42662729.59629 +1453 1352 -694433.1761458 +1454 1352 -54493616.03735 +1455 1352 11321064.34898 +1456 1352 8871522.146428 +1457 1352 -20019947.11985 +1461 1352 231485.2378493 +1462 1352 -2777732.703215 +1463 1352 -110039912.4136 +1464 1352 57871.30949473 +1465 1352 35611088.56821 +1466 1352 -53128242.27036 +1473 1352 -42894214.83411 +1474 1352 -694433.1761459 +1475 1352 -55531090.78464 +1476 1352 -11378935.65847 +1477 1352 8940966.590895 +1478 1352 -20295098.63508 +1353 1353 613328698.917 +1354 1353 1.621246337891e-05 +1355 1353 925940.9508365 +1356 1353 82577683.23799 +1357 1353 -7.659196853638e-06 +1358 1353 231485.2378237 +1362 1353 -52678594.23377 +1363 1353 -36666666.66064 +1364 1353 2505785.158418 +1365 1353 -140008022.8906 +1366 1353 2.577900886536e-06 +1367 1353 -462970.4754454 +1368 1353 -52702268.47617 +1369 1353 36666666.66064 +1370 1353 -2702548.174055 +1452 1353 -18391419.7975 +1453 1353 9166666.669678 +1454 1353 10018981.01522 +1455 1353 -58783069.51046 +1456 1353 1.639127731323e-06 +1457 1353 42697451.81849 +1458 1353 -19844426.42677 +1459 1353 -9166666.669679 +1460 1353 11321064.34898 +1461 1353 -413319.0876746 +1462 1353 3.017485141754e-06 +1463 1353 57871.30948708 +1464 1353 57430602.85087 +1465 1353 3.8743019104e-06 +1466 1353 231485.2378496 +1467 1353 -6249019.844286 +1468 1353 -7.443130016327e-06 +1469 1353 57871.30949415 +1473 1353 -18482764.4945 +1474 1353 -9166666.669676 +1475 1353 -10076852.32471 +1476 1353 -59172122.54065 +1477 1353 4.395842552185e-07 +1478 1353 -42928937.05631 +1479 1353 -19947608.24497 +1480 1353 9166666.669675 +1481 1353 -11378935.65847 +1354 1354 525322193.6551 +1355 1354 -11110930.80738 +1356 1354 -7.525086402893e-06 +1357 1354 -56755372.43366 +1358 1354 5555465.403692 +1362 1354 -36666666.66065 +1363 1354 -41677781.0706 +1364 1354 1263866.351621 +1365 1354 2.831220626831e-06 +1366 1354 21326659.08566 +1367 1354 -2777732.703214 +1368 1354 36666666.66064 +1369 1354 -41701455.31301 +1370 1354 1513866.351594 +1452 1354 9166666.669678 +1453 1354 -15641216.50536 +1454 1354 -8177088.970282 +1455 1354 6.034970283508e-07 +1456 1354 -18449398.9965 +1457 1354 -694433.1761458 +1458 1354 -9166666.669679 +1459 1354 -17094223.13462 +1460 1354 8871522.146427 +1461 1354 4.06801700592e-06 +1462 1354 -35246583.02275 +1463 1354 -32861133.64276 +1464 1354 4.231929779053e-06 +1465 1354 35428976.52455 +1466 1354 -2777732.703215 +1467 1354 -7.599592208862e-06 +1468 1354 -41082283.77936 +1469 1354 35638866.34597 +1473 1354 -9166666.669676 +1474 1354 -15732561.20235 +1475 1354 -8246533.414749 +1476 1354 4.619359970093e-07 +1477 1354 -18838452.02672 +1478 1354 -694433.1761459 +1479 1354 9166666.669675 +1480 1354 -17197404.95283 +1481 1354 8940966.590895 +1355 1355 582790450.9006 +1356 1355 231485.2378239 +1357 1355 5555465.403692 +1358 1355 74350397.96411 +1362 1355 2471062.936219 +1363 1355 1236088.573861 +1364 1355 -8882157.948759 +1365 1355 -462970.4754449 +1366 1355 -2777732.703214 +1367 1355 35690216.05203 +1368 1355 -2737270.396254 +1369 1355 1541644.129353 +1370 1355 -8945289.261872 +1452 1355 10018981.01522 +1453 1355 -8177088.970282 +1454 1355 -16145262.77514 +1455 1355 42662729.59629 +1456 1355 -694433.1761458 +1457 1355 -54493616.03735 +1458 1355 11321064.34898 +1459 1355 8871522.146428 +1460 1355 -20019947.11985 +1461 1355 57871.30948763 +1462 1355 -32833355.865 +1463 1355 -37566373.58606 +1464 1355 231485.2378493 +1465 1355 -2777732.703215 +1466 1355 -110039912.4136 +1467 1355 57871.30949473 +1468 1355 35611088.56821 +1469 1355 -53128242.27036 +1473 1355 -10076852.32471 +1474 1355 -8246533.414749 +1475 1355 -16388848.63381 +1476 1355 -42894214.83411 +1477 1355 -694433.1761459 +1478 1355 -55531090.78464 +1479 1355 -11378935.65847 +1480 1355 8940966.590895 +1481 1355 -20295098.63508 +1356 1356 665854880.679 +1357 1356 36667470.52063 +1358 1356 3125090.734117 +1359 1356 18070347.2503 +1360 1356 -36666988.20464 +1361 1356 2702571.265064 +1365 1356 -52678594.23377 +1366 1356 -36666666.66064 +1367 1356 2505785.158418 +1368 1356 -140008022.8906 +1369 1356 2.577900886536e-06 +1370 1356 -462970.4754454 +1371 1356 -52702268.47617 +1372 1356 36666666.66064 +1373 1356 -2702548.174055 +1455 1356 -18391419.7975 +1456 1356 9166666.669678 +1457 1356 10018981.01522 +1458 1356 -71369389.94283 +1459 1356 -9166787.24867 +1460 1356 42147892.99313 +1464 1356 -413319.0876746 +1465 1356 3.017485141754e-06 +1466 1356 57871.30948708 +1467 1356 76553135.92261 +1468 1356 9166867.634673 +1469 1356 781226.2244361 +1470 1356 -18699525.19313 +1471 1356 -9166747.055676 +1472 1356 11379035.3452 +1476 1356 -18482764.4945 +1477 1356 -9166666.669676 +1478 1356 -10076852.32471 +1479 1356 -59172122.54065 +1480 1356 4.395842552185e-07 +1481 1356 -42928937.05631 +1482 1356 -19947608.24497 +1483 1356 9166666.669675 +1484 1356 -11378935.65847 +1357 1357 566847200.4901 +1358 1357 -8610909.306622 +1359 1357 -36667148.97663 +1360 1357 -110262538.3357 +1361 1357 4611016.915367 +1365 1357 -36666666.66065 +1366 1357 -41677781.0706 +1367 1357 1263866.351621 +1368 1357 2.831220626831e-06 +1369 1357 21326659.08566 +1370 1357 -2777732.703214 +1371 1357 36666666.66064 +1372 1357 -41701455.31301 +1373 1357 1513866.351594 +1455 1357 9166666.669678 +1456 1357 -15641216.50536 +1457 1357 -8177088.970282 +1458 1357 -9166747.055672 +1459 1357 -28285264.92641 +1460 1357 7788270.809731 +1464 1357 4.06801700592e-06 +1465 1357 -35246583.02275 +1466 1357 -32861133.64276 +1467 1357 9166867.634673 +1468 1357 51801215.86321 +1469 1357 -2152764.494718 +1470 1357 -9166787.248675 +1471 1357 -50782746.60544 +1472 1357 35402941.77273 +1476 1357 -9166666.669676 +1477 1357 -15732561.20235 +1478 1357 -8246533.414749 +1479 1357 4.619359970093e-07 +1480 1357 -18838452.02672 +1481 1357 -694433.1761459 +1482 1357 9166666.669675 +1483 1357 -17197404.95283 +1484 1357 8940966.590895 +1358 1358 591261848.0956 +1359 1358 2737305.032771 +1360 1358 5388803.421584 +1361 1358 33925571.74906 +1365 1358 2471062.936219 +1366 1358 1236088.573861 +1367 1358 -8882157.948759 +1368 1358 -462970.4754449 +1369 1358 -2777732.703214 +1370 1358 35690216.05203 +1371 1358 -2737270.396254 +1372 1358 1541644.129353 +1373 1358 -8945289.261872 +1455 1358 10018981.01522 +1456 1358 -8177088.970282 +1457 1358 -16145262.77514 +1458 1358 42113167.97979 +1459 1358 7593861.729456 +1460 1358 -55157692.73435 +1464 1358 57871.30948763 +1465 1358 -32833355.865 +1466 1358 -37566373.58606 +1467 1358 781320.0962051 +1468 1358 -2152689.398522 +1469 1358 -91946096.11431 +1470 1358 11379085.18856 +1471 1358 35569610.71641 +1472 1358 -53430905.74636 +1476 1358 -10076852.32471 +1477 1358 -8246533.414749 +1478 1358 -16388848.63381 +1479 1358 -42894214.83411 +1480 1358 -694433.1761459 +1481 1358 -55531090.78464 +1482 1358 -11378935.65847 +1483 1358 8940966.590895 +1484 1358 -20295098.63508 +1359 1359 383498024.544 +1360 1359 36666666.66064 +1361 1359 2662179.892796 +1368 1359 -52678594.23377 +1369 1359 -36666666.66064 +1370 1359 2505785.158418 +1371 1359 -204675200.5845 +1372 1359 -36666988.20463 +1373 1359 -2662156.039165 +1374 1359 11810466.31493 +1375 1359 29333654.8725 +1376 1359 -2152800.8684 +1458 1359 -4579449.609996 +1459 1359 11000120.58261 +1460 1359 12057631.64322 +1467 1359 -14225493.76444 +1468 1359 -9166787.248675 +1469 1359 -10019112.65448 +1470 1359 35932670.30059 +1471 1359 9166666.669679 +1472 1359 9311563.653784 +1479 1359 -18482764.4945 +1480 1359 -9166666.669676 +1481 1359 -10076852.32471 +1482 1359 -72925641.46158 +1483 1359 -9166747.055676 +1484 1359 -43478968.03166 +1485 1359 -7497354.851903 +1486 1359 7333413.72174 +1487 1359 -9080099.689708 +1360 1360 328493596.9861 +1361 1360 -6944376.43401 +1368 1360 -36666666.66065 +1369 1360 -41677781.0706 +1370 1360 1263866.351621 +1371 1360 -36667148.97662 +1372 1360 -32338700.60373 +1373 1360 -3847226.785359 +1374 1360 44000482.30876 +1375 1360 11810466.31493 +1376 1360 2416693.76713 +1458 1360 7333413.72174 +1459 1360 -4579449.61 +1460 1360 -6430626.286135 +1467 1360 -9166747.055675 +1468 1360 -46308715.17675 +1469 1360 -32902986.62891 +1470 1360 9166666.669678 +1471 1360 22181563.40434 +1472 1360 5180609.664774 +1479 1360 -9166666.669676 +1480 1360 -15732561.20235 +1481 1360 -8246533.414749 +1482 1360 -9166787.248676 +1483 1360 -29841516.44517 +1484 1360 -9524419.110191 +1485 1360 11000120.58261 +1486 1360 -7497354.8519 +1487 1360 10895952.52268 +1361 1361 364686604.8413 +1368 1361 2471062.936219 +1369 1361 1236088.573861 +1370 1361 -8882157.948759 +1371 1361 -2662144.112346 +1372 1361 -3097217.751863 +1373 1361 -5157813.372203 +1374 1361 -3229201.302601 +1375 1361 1611129.178087 +1376 1361 31494576.83983 +1458 1361 8038421.095477 +1459 1361 -9645939.429201 +1460 1361 -12211865.62666 +1467 1361 -10019068.77473 +1468 1361 -33069655.68813 +1469 1361 -41500155.26984 +1470 1361 -7806863.548506 +1471 1361 -8513909.758068 +1472 1361 -68673244.4318 +1479 1361 -10076852.32471 +1480 1361 -8246533.414749 +1481 1361 -16388848.63381 +1482 1361 -43444243.01831 +1483 1361 -9329934.937092 +1484 1361 -59307696.78438 +1485 1361 -13620149.53456 +1486 1361 7263968.348454 +1487 1361 -19992946.27174 +1362 1362 613328698.917 +1363 1362 1.621246337891e-05 +1364 1362 925940.9508365 +1365 1362 82577683.23799 +1366 1362 -7.659196853638e-06 +1367 1362 231485.2378237 +1377 1362 -140008022.8906 +1378 1362 2.577900886536e-06 +1379 1362 -462970.4754454 +1380 1362 -52702268.47617 +1381 1362 36666666.66064 +1382 1362 -2702548.174055 +1461 1362 -58783069.51046 +1462 1362 1.639127731323e-06 +1463 1362 42697451.81849 +1464 1362 -19844426.42677 +1465 1362 -9166666.669679 +1466 1362 11321064.34898 +1473 1362 57430602.85087 +1474 1362 3.8743019104e-06 +1475 1362 231485.2378496 +1476 1362 -6249019.844286 +1477 1362 -7.443130016327e-06 +1478 1362 57871.30949415 +1488 1362 -59172122.54065 +1489 1362 4.395842552185e-07 +1490 1362 -42928937.05631 +1491 1362 -19947608.24497 +1492 1362 9166666.669675 +1493 1362 -11378935.65847 +1363 1363 525322193.6551 +1364 1363 -11110930.80738 +1365 1363 -7.525086402893e-06 +1366 1363 -56755372.43366 +1367 1363 5555465.403692 +1377 1363 2.831220626831e-06 +1378 1363 21326659.08566 +1379 1363 -2777732.703214 +1380 1363 36666666.66064 +1381 1363 -41701455.31301 +1382 1363 1513866.351594 +1461 1363 6.034970283508e-07 +1462 1363 -18449398.9965 +1463 1363 -694433.1761458 +1464 1363 -9166666.669679 +1465 1363 -17094223.13462 +1466 1363 8871522.146427 +1473 1363 4.231929779053e-06 +1474 1363 35428976.52455 +1475 1363 -2777732.703215 +1476 1363 -7.599592208862e-06 +1477 1363 -41082283.77936 +1478 1363 35638866.34597 +1488 1363 4.619359970093e-07 +1489 1363 -18838452.02672 +1490 1363 -694433.1761459 +1491 1363 9166666.669675 +1492 1363 -17197404.95283 +1493 1363 8940966.590895 +1364 1364 582790450.9006 +1365 1364 231485.2378239 +1366 1364 5555465.403692 +1367 1364 74350397.96411 +1377 1364 -462970.4754449 +1378 1364 -2777732.703214 +1379 1364 35690216.05203 +1380 1364 -2737270.396254 +1381 1364 1541644.129353 +1382 1364 -8945289.261872 +1461 1364 42662729.59629 +1462 1364 -694433.1761458 +1463 1364 -54493616.03735 +1464 1364 11321064.34898 +1465 1364 8871522.146428 +1466 1364 -20019947.11985 +1473 1364 231485.2378493 +1474 1364 -2777732.703215 +1475 1364 -110039912.4136 +1476 1364 57871.30949473 +1477 1364 35611088.56821 +1478 1364 -53128242.27036 +1488 1364 -42894214.83411 +1489 1364 -694433.1761459 +1490 1364 -55531090.78464 +1491 1364 -11378935.65847 +1492 1364 8940966.590895 +1493 1364 -20295098.63508 +1365 1365 613328698.917 +1366 1365 1.621246337891e-05 +1367 1365 925940.9508365 +1368 1365 82577683.23799 +1369 1365 -7.659196853638e-06 +1370 1365 231485.2378237 +1377 1365 -52678594.23377 +1378 1365 -36666666.66064 +1379 1365 2505785.158418 +1380 1365 -140008022.8906 +1381 1365 2.577900886536e-06 +1382 1365 -462970.4754454 +1383 1365 -52702268.47617 +1384 1365 36666666.66064 +1385 1365 -2702548.174055 +1461 1365 -18391419.7975 +1462 1365 9166666.669678 +1463 1365 10018981.01522 +1464 1365 -58783069.51046 +1465 1365 1.639127731323e-06 +1466 1365 42697451.81849 +1467 1365 -19844426.42677 +1468 1365 -9166666.669679 +1469 1365 11321064.34898 +1473 1365 -413319.0876746 +1474 1365 3.017485141754e-06 +1475 1365 57871.30948708 +1476 1365 57430602.85087 +1477 1365 3.8743019104e-06 +1478 1365 231485.2378496 +1479 1365 -6249019.844286 +1480 1365 -7.443130016327e-06 +1481 1365 57871.30949415 +1488 1365 -18482764.4945 +1489 1365 -9166666.669676 +1490 1365 -10076852.32471 +1491 1365 -59172122.54065 +1492 1365 4.395842552185e-07 +1493 1365 -42928937.05631 +1494 1365 -19947608.24497 +1495 1365 9166666.669675 +1496 1365 -11378935.65847 +1366 1366 525322193.6551 +1367 1366 -11110930.80738 +1368 1366 -7.525086402893e-06 +1369 1366 -56755372.43366 +1370 1366 5555465.403692 +1377 1366 -36666666.66065 +1378 1366 -41677781.0706 +1379 1366 1263866.351621 +1380 1366 2.831220626831e-06 +1381 1366 21326659.08566 +1382 1366 -2777732.703214 +1383 1366 36666666.66064 +1384 1366 -41701455.31301 +1385 1366 1513866.351594 +1461 1366 9166666.669678 +1462 1366 -15641216.50536 +1463 1366 -8177088.970282 +1464 1366 6.034970283508e-07 +1465 1366 -18449398.9965 +1466 1366 -694433.1761458 +1467 1366 -9166666.669679 +1468 1366 -17094223.13462 +1469 1366 8871522.146427 +1473 1366 4.06801700592e-06 +1474 1366 -35246583.02275 +1475 1366 -32861133.64276 +1476 1366 4.231929779053e-06 +1477 1366 35428976.52455 +1478 1366 -2777732.703215 +1479 1366 -7.599592208862e-06 +1480 1366 -41082283.77936 +1481 1366 35638866.34597 +1488 1366 -9166666.669676 +1489 1366 -15732561.20235 +1490 1366 -8246533.414749 +1491 1366 4.619359970093e-07 +1492 1366 -18838452.02672 +1493 1366 -694433.1761459 +1494 1366 9166666.669675 +1495 1366 -17197404.95283 +1496 1366 8940966.590895 +1367 1367 582790450.9006 +1368 1367 231485.2378239 +1369 1367 5555465.403692 +1370 1367 74350397.96411 +1377 1367 2471062.936219 +1378 1367 1236088.573861 +1379 1367 -8882157.948759 +1380 1367 -462970.4754449 +1381 1367 -2777732.703214 +1382 1367 35690216.05203 +1383 1367 -2737270.396254 +1384 1367 1541644.129353 +1385 1367 -8945289.261872 +1461 1367 10018981.01522 +1462 1367 -8177088.970282 +1463 1367 -16145262.77514 +1464 1367 42662729.59629 +1465 1367 -694433.1761458 +1466 1367 -54493616.03735 +1467 1367 11321064.34898 +1468 1367 8871522.146428 +1469 1367 -20019947.11985 +1473 1367 57871.30948763 +1474 1367 -32833355.865 +1475 1367 -37566373.58606 +1476 1367 231485.2378493 +1477 1367 -2777732.703215 +1478 1367 -110039912.4136 +1479 1367 57871.30949473 +1480 1367 35611088.56821 +1481 1367 -53128242.27036 +1488 1367 -10076852.32471 +1489 1367 -8246533.414749 +1490 1367 -16388848.63381 +1491 1367 -42894214.83411 +1492 1367 -694433.1761459 +1493 1367 -55531090.78464 +1494 1367 -11378935.65847 +1495 1367 8940966.590895 +1496 1367 -20295098.63508 +1368 1368 613328698.917 +1369 1368 1.621246337891e-05 +1370 1368 925940.9508365 +1371 1368 82577683.23799 +1372 1368 -7.659196853638e-06 +1373 1368 231485.2378237 +1380 1368 -52678594.23377 +1381 1368 -36666666.66064 +1382 1368 2505785.158418 +1383 1368 -140008022.8906 +1384 1368 2.577900886536e-06 +1385 1368 -462970.4754454 +1386 1368 -52702268.47617 +1387 1368 36666666.66064 +1388 1368 -2702548.174055 +1464 1368 -18391419.7975 +1465 1368 9166666.669678 +1466 1368 10018981.01522 +1467 1368 -58783069.51046 +1468 1368 1.639127731323e-06 +1469 1368 42697451.81849 +1470 1368 -19844426.42677 +1471 1368 -9166666.669679 +1472 1368 11321064.34898 +1476 1368 -413319.0876746 +1477 1368 3.017485141754e-06 +1478 1368 57871.30948708 +1479 1368 57430602.85087 +1480 1368 3.8743019104e-06 +1481 1368 231485.2378496 +1482 1368 -6249019.844286 +1483 1368 -7.443130016327e-06 +1484 1368 57871.30949415 +1491 1368 -18482764.4945 +1492 1368 -9166666.669676 +1493 1368 -10076852.32471 +1494 1368 -59172122.54065 +1495 1368 4.395842552185e-07 +1496 1368 -42928937.05631 +1497 1368 -19947608.24497 +1498 1368 9166666.669675 +1499 1368 -11378935.65847 +1369 1369 525322193.6551 +1370 1369 -11110930.80738 +1371 1369 -7.525086402893e-06 +1372 1369 -56755372.43366 +1373 1369 5555465.403692 +1380 1369 -36666666.66065 +1381 1369 -41677781.0706 +1382 1369 1263866.351621 +1383 1369 2.831220626831e-06 +1384 1369 21326659.08566 +1385 1369 -2777732.703214 +1386 1369 36666666.66064 +1387 1369 -41701455.31301 +1388 1369 1513866.351594 +1464 1369 9166666.669678 +1465 1369 -15641216.50536 +1466 1369 -8177088.970282 +1467 1369 6.034970283508e-07 +1468 1369 -18449398.9965 +1469 1369 -694433.1761458 +1470 1369 -9166666.669679 +1471 1369 -17094223.13462 +1472 1369 8871522.146427 +1476 1369 4.06801700592e-06 +1477 1369 -35246583.02275 +1478 1369 -32861133.64276 +1479 1369 4.231929779053e-06 +1480 1369 35428976.52455 +1481 1369 -2777732.703215 +1482 1369 -7.599592208862e-06 +1483 1369 -41082283.77936 +1484 1369 35638866.34597 +1491 1369 -9166666.669676 +1492 1369 -15732561.20235 +1493 1369 -8246533.414749 +1494 1369 4.619359970093e-07 +1495 1369 -18838452.02672 +1496 1369 -694433.1761459 +1497 1369 9166666.669675 +1498 1369 -17197404.95283 +1499 1369 8940966.590895 +1370 1370 582790450.9006 +1371 1370 231485.2378239 +1372 1370 5555465.403692 +1373 1370 74350397.96411 +1380 1370 2471062.936219 +1381 1370 1236088.573861 +1382 1370 -8882157.948759 +1383 1370 -462970.4754449 +1384 1370 -2777732.703214 +1385 1370 35690216.05203 +1386 1370 -2737270.396254 +1387 1370 1541644.129353 +1388 1370 -8945289.261872 +1464 1370 10018981.01522 +1465 1370 -8177088.970282 +1466 1370 -16145262.77514 +1467 1370 42662729.59629 +1468 1370 -694433.1761458 +1469 1370 -54493616.03735 +1470 1370 11321064.34898 +1471 1370 8871522.146428 +1472 1370 -20019947.11985 +1476 1370 57871.30948763 +1477 1370 -32833355.865 +1478 1370 -37566373.58606 +1479 1370 231485.2378493 +1480 1370 -2777732.703215 +1481 1370 -110039912.4136 +1482 1370 57871.30949473 +1483 1370 35611088.56821 +1484 1370 -53128242.27036 +1491 1370 -10076852.32471 +1492 1370 -8246533.414749 +1493 1370 -16388848.63381 +1494 1370 -42894214.83411 +1495 1370 -694433.1761459 +1496 1370 -55531090.78464 +1497 1370 -11378935.65847 +1498 1370 8940966.590895 +1499 1370 -20295098.63508 +1371 1371 665854880.679 +1372 1371 36667470.52063 +1373 1371 3125090.734117 +1374 1371 18070347.2503 +1375 1371 -36666988.20464 +1376 1371 2702571.265064 +1383 1371 -52678594.23377 +1384 1371 -36666666.66064 +1385 1371 2505785.158418 +1386 1371 -140008022.8906 +1387 1371 2.577900886536e-06 +1388 1371 -462970.4754454 +1389 1371 -52702268.47617 +1390 1371 36666666.66064 +1391 1371 -2702548.174055 +1467 1371 -18391419.7975 +1468 1371 9166666.669678 +1469 1371 10018981.01522 +1470 1371 -71369389.94283 +1471 1371 -9166787.24867 +1472 1371 42147892.99313 +1479 1371 -413319.0876746 +1480 1371 3.017485141754e-06 +1481 1371 57871.30948708 +1482 1371 76553135.92261 +1483 1371 9166867.634673 +1484 1371 781226.2244361 +1485 1371 -18699525.19313 +1486 1371 -9166747.055676 +1487 1371 11379035.3452 +1494 1371 -18482764.4945 +1495 1371 -9166666.669676 +1496 1371 -10076852.32471 +1497 1371 -59172122.54065 +1498 1371 4.395842552185e-07 +1499 1371 -42928937.05631 +1500 1371 -19947608.24497 +1501 1371 9166666.669675 +1502 1371 -11378935.65847 +1372 1372 566847200.4901 +1373 1372 -8610909.306622 +1374 1372 -36667148.97663 +1375 1372 -110262538.3357 +1376 1372 4611016.915367 +1383 1372 -36666666.66065 +1384 1372 -41677781.0706 +1385 1372 1263866.351621 +1386 1372 2.831220626831e-06 +1387 1372 21326659.08566 +1388 1372 -2777732.703214 +1389 1372 36666666.66064 +1390 1372 -41701455.31301 +1391 1372 1513866.351594 +1467 1372 9166666.669678 +1468 1372 -15641216.50536 +1469 1372 -8177088.970282 +1470 1372 -9166747.055672 +1471 1372 -28285264.92641 +1472 1372 7788270.809731 +1479 1372 4.06801700592e-06 +1480 1372 -35246583.02275 +1481 1372 -32861133.64276 +1482 1372 9166867.634673 +1483 1372 51801215.86321 +1484 1372 -2152764.494718 +1485 1372 -9166787.248675 +1486 1372 -50782746.60544 +1487 1372 35402941.77273 +1494 1372 -9166666.669676 +1495 1372 -15732561.20235 +1496 1372 -8246533.414749 +1497 1372 4.619359970093e-07 +1498 1372 -18838452.02672 +1499 1372 -694433.1761459 +1500 1372 9166666.669675 +1501 1372 -17197404.95283 +1502 1372 8940966.590895 +1373 1373 591261848.0956 +1374 1373 2737305.032771 +1375 1373 5388803.421584 +1376 1373 33925571.74906 +1383 1373 2471062.936219 +1384 1373 1236088.573861 +1385 1373 -8882157.948759 +1386 1373 -462970.4754449 +1387 1373 -2777732.703214 +1388 1373 35690216.05203 +1389 1373 -2737270.396254 +1390 1373 1541644.129353 +1391 1373 -8945289.261872 +1467 1373 10018981.01522 +1468 1373 -8177088.970282 +1469 1373 -16145262.77514 +1470 1373 42113167.97979 +1471 1373 7593861.729456 +1472 1373 -55157692.73435 +1479 1373 57871.30948763 +1480 1373 -32833355.865 +1481 1373 -37566373.58606 +1482 1373 781320.0962051 +1483 1373 -2152689.398522 +1484 1373 -91946096.11431 +1485 1373 11379085.18856 +1486 1373 35569610.71641 +1487 1373 -53430905.74636 +1494 1373 -10076852.32471 +1495 1373 -8246533.414749 +1496 1373 -16388848.63381 +1497 1373 -42894214.83411 +1498 1373 -694433.1761459 +1499 1373 -55531090.78464 +1500 1373 -11378935.65847 +1501 1373 8940966.590895 +1502 1373 -20295098.63508 +1374 1374 383498024.544 +1375 1374 36666666.66064 +1376 1374 2662179.892796 +1386 1374 -52678594.23377 +1387 1374 -36666666.66064 +1388 1374 2505785.158418 +1389 1374 -204675200.5845 +1390 1374 -36666988.20463 +1391 1374 -2662156.039165 +1392 1374 11810466.31493 +1393 1374 29333654.8725 +1394 1374 -2152800.8684 +1470 1374 -4579449.609996 +1471 1374 11000120.58261 +1472 1374 12057631.64322 +1482 1374 -14225493.76444 +1483 1374 -9166787.248675 +1484 1374 -10019112.65448 +1485 1374 35932670.30059 +1486 1374 9166666.669679 +1487 1374 9311563.653784 +1497 1374 -18482764.4945 +1498 1374 -9166666.669676 +1499 1374 -10076852.32471 +1500 1374 -72925641.46158 +1501 1374 -9166747.055676 +1502 1374 -43478968.03166 +1503 1374 -7497354.851903 +1504 1374 7333413.72174 +1505 1374 -9080099.689708 +1375 1375 328493596.9861 +1376 1375 -6944376.43401 +1386 1375 -36666666.66065 +1387 1375 -41677781.0706 +1388 1375 1263866.351621 +1389 1375 -36667148.97662 +1390 1375 -32338700.60373 +1391 1375 -3847226.785359 +1392 1375 44000482.30876 +1393 1375 11810466.31493 +1394 1375 2416693.76713 +1470 1375 7333413.72174 +1471 1375 -4579449.61 +1472 1375 -6430626.286135 +1482 1375 -9166747.055675 +1483 1375 -46308715.17675 +1484 1375 -32902986.62891 +1485 1375 9166666.669678 +1486 1375 22181563.40434 +1487 1375 5180609.664774 +1497 1375 -9166666.669676 +1498 1375 -15732561.20235 +1499 1375 -8246533.414749 +1500 1375 -9166787.248676 +1501 1375 -29841516.44517 +1502 1375 -9524419.110191 +1503 1375 11000120.58261 +1504 1375 -7497354.8519 +1505 1375 10895952.52268 +1376 1376 364686604.8413 +1386 1376 2471062.936219 +1387 1376 1236088.573861 +1388 1376 -8882157.948759 +1389 1376 -2662144.112346 +1390 1376 -3097217.751863 +1391 1376 -5157813.372203 +1392 1376 -3229201.302601 +1393 1376 1611129.178087 +1394 1376 31494576.83983 +1470 1376 8038421.095477 +1471 1376 -9645939.429201 +1472 1376 -12211865.62666 +1482 1376 -10019068.77473 +1483 1376 -33069655.68813 +1484 1376 -41500155.26984 +1485 1376 -7806863.548506 +1486 1376 -8513909.758068 +1487 1376 -68673244.4318 +1497 1376 -10076852.32471 +1498 1376 -8246533.414749 +1499 1376 -16388848.63381 +1500 1376 -43444243.01831 +1501 1376 -9329934.937092 +1502 1376 -59307696.78438 +1503 1376 -13620149.53456 +1504 1376 7263968.348454 +1505 1376 -19992946.27174 +1377 1377 613328698.917 +1378 1377 1.621246337891e-05 +1379 1377 925940.9508365 +1380 1377 82577683.23799 +1381 1377 -7.659196853638e-06 +1382 1377 231485.2378237 +1395 1377 -140008022.8906 +1396 1377 2.577900886536e-06 +1397 1377 -462970.4754454 +1398 1377 -52702268.47617 +1399 1377 36666666.66064 +1400 1377 -2702548.174055 +1473 1377 -58783069.51046 +1474 1377 1.639127731323e-06 +1475 1377 42697451.81849 +1476 1377 -19844426.42677 +1477 1377 -9166666.669679 +1478 1377 11321064.34898 +1488 1377 57430602.85087 +1489 1377 3.8743019104e-06 +1490 1377 231485.2378496 +1491 1377 -6249019.844286 +1492 1377 -7.443130016327e-06 +1493 1377 57871.30949415 +1506 1377 -59172122.54065 +1507 1377 4.395842552185e-07 +1508 1377 -42928937.05631 +1509 1377 -19947608.24497 +1510 1377 9166666.669675 +1511 1377 -11378935.65847 +1378 1378 525322193.6551 +1379 1378 -11110930.80738 +1380 1378 -7.525086402893e-06 +1381 1378 -56755372.43366 +1382 1378 5555465.403692 +1395 1378 2.831220626831e-06 +1396 1378 21326659.08566 +1397 1378 -2777732.703214 +1398 1378 36666666.66064 +1399 1378 -41701455.31301 +1400 1378 1513866.351594 +1473 1378 6.034970283508e-07 +1474 1378 -18449398.9965 +1475 1378 -694433.1761458 +1476 1378 -9166666.669679 +1477 1378 -17094223.13462 +1478 1378 8871522.146427 +1488 1378 4.231929779053e-06 +1489 1378 35428976.52455 +1490 1378 -2777732.703215 +1491 1378 -7.599592208862e-06 +1492 1378 -41082283.77936 +1493 1378 35638866.34597 +1506 1378 4.619359970093e-07 +1507 1378 -18838452.02672 +1508 1378 -694433.1761459 +1509 1378 9166666.669675 +1510 1378 -17197404.95283 +1511 1378 8940966.590895 +1379 1379 582790450.9006 +1380 1379 231485.2378239 +1381 1379 5555465.403692 +1382 1379 74350397.96411 +1395 1379 -462970.4754449 +1396 1379 -2777732.703214 +1397 1379 35690216.05203 +1398 1379 -2737270.396254 +1399 1379 1541644.129353 +1400 1379 -8945289.261872 +1473 1379 42662729.59629 +1474 1379 -694433.1761458 +1475 1379 -54493616.03735 +1476 1379 11321064.34898 +1477 1379 8871522.146428 +1478 1379 -20019947.11985 +1488 1379 231485.2378493 +1489 1379 -2777732.703215 +1490 1379 -110039912.4136 +1491 1379 57871.30949473 +1492 1379 35611088.56821 +1493 1379 -53128242.27036 +1506 1379 -42894214.83411 +1507 1379 -694433.1761459 +1508 1379 -55531090.78464 +1509 1379 -11378935.65847 +1510 1379 8940966.590895 +1511 1379 -20295098.63508 +1380 1380 613328698.917 +1381 1380 1.621246337891e-05 +1382 1380 925940.9508365 +1383 1380 82577683.23799 +1384 1380 -7.659196853638e-06 +1385 1380 231485.2378237 +1395 1380 -52678594.23377 +1396 1380 -36666666.66064 +1397 1380 2505785.158418 +1398 1380 -140008022.8906 +1399 1380 2.577900886536e-06 +1400 1380 -462970.4754454 +1401 1380 -52702268.47617 +1402 1380 36666666.66064 +1403 1380 -2702548.174055 +1473 1380 -18391419.7975 +1474 1380 9166666.669678 +1475 1380 10018981.01522 +1476 1380 -58783069.51046 +1477 1380 1.639127731323e-06 +1478 1380 42697451.81849 +1479 1380 -19844426.42677 +1480 1380 -9166666.669679 +1481 1380 11321064.34898 +1488 1380 -413319.0876746 +1489 1380 3.017485141754e-06 +1490 1380 57871.30948708 +1491 1380 57430602.85087 +1492 1380 3.8743019104e-06 +1493 1380 231485.2378496 +1494 1380 -6249019.844286 +1495 1380 -7.443130016327e-06 +1496 1380 57871.30949415 +1506 1380 -18482764.4945 +1507 1380 -9166666.669676 +1508 1380 -10076852.32471 +1509 1380 -59172122.54065 +1510 1380 4.395842552185e-07 +1511 1380 -42928937.05631 +1512 1380 -19947608.24497 +1513 1380 9166666.669675 +1514 1380 -11378935.65847 +1381 1381 525322193.6551 +1382 1381 -11110930.80738 +1383 1381 -7.525086402893e-06 +1384 1381 -56755372.43366 +1385 1381 5555465.403692 +1395 1381 -36666666.66065 +1396 1381 -41677781.0706 +1397 1381 1263866.351621 +1398 1381 2.831220626831e-06 +1399 1381 21326659.08566 +1400 1381 -2777732.703214 +1401 1381 36666666.66064 +1402 1381 -41701455.31301 +1403 1381 1513866.351594 +1473 1381 9166666.669678 +1474 1381 -15641216.50536 +1475 1381 -8177088.970282 +1476 1381 6.034970283508e-07 +1477 1381 -18449398.9965 +1478 1381 -694433.1761458 +1479 1381 -9166666.669679 +1480 1381 -17094223.13462 +1481 1381 8871522.146427 +1488 1381 4.06801700592e-06 +1489 1381 -35246583.02275 +1490 1381 -32861133.64276 +1491 1381 4.231929779053e-06 +1492 1381 35428976.52455 +1493 1381 -2777732.703215 +1494 1381 -7.599592208862e-06 +1495 1381 -41082283.77936 +1496 1381 35638866.34597 +1506 1381 -9166666.669676 +1507 1381 -15732561.20235 +1508 1381 -8246533.414749 +1509 1381 4.619359970093e-07 +1510 1381 -18838452.02672 +1511 1381 -694433.1761459 +1512 1381 9166666.669675 +1513 1381 -17197404.95283 +1514 1381 8940966.590895 +1382 1382 582790450.9006 +1383 1382 231485.2378239 +1384 1382 5555465.403692 +1385 1382 74350397.96411 +1395 1382 2471062.936219 +1396 1382 1236088.573861 +1397 1382 -8882157.948759 +1398 1382 -462970.4754449 +1399 1382 -2777732.703214 +1400 1382 35690216.05203 +1401 1382 -2737270.396254 +1402 1382 1541644.129353 +1403 1382 -8945289.261872 +1473 1382 10018981.01522 +1474 1382 -8177088.970282 +1475 1382 -16145262.77514 +1476 1382 42662729.59629 +1477 1382 -694433.1761458 +1478 1382 -54493616.03735 +1479 1382 11321064.34898 +1480 1382 8871522.146428 +1481 1382 -20019947.11985 +1488 1382 57871.30948763 +1489 1382 -32833355.865 +1490 1382 -37566373.58606 +1491 1382 231485.2378493 +1492 1382 -2777732.703215 +1493 1382 -110039912.4136 +1494 1382 57871.30949473 +1495 1382 35611088.56821 +1496 1382 -53128242.27036 +1506 1382 -10076852.32471 +1507 1382 -8246533.414749 +1508 1382 -16388848.63381 +1509 1382 -42894214.83411 +1510 1382 -694433.1761459 +1511 1382 -55531090.78464 +1512 1382 -11378935.65847 +1513 1382 8940966.590895 +1514 1382 -20295098.63508 +1383 1383 613328698.917 +1384 1383 1.621246337891e-05 +1385 1383 925940.9508365 +1386 1383 82577683.23799 +1387 1383 -7.659196853638e-06 +1388 1383 231485.2378237 +1398 1383 -52678594.23377 +1399 1383 -36666666.66064 +1400 1383 2505785.158418 +1401 1383 -140008022.8906 +1402 1383 2.577900886536e-06 +1403 1383 -462970.4754454 +1404 1383 -52702268.47617 +1405 1383 36666666.66064 +1406 1383 -2702548.174055 +1476 1383 -18391419.7975 +1477 1383 9166666.669678 +1478 1383 10018981.01522 +1479 1383 -58783069.51046 +1480 1383 1.639127731323e-06 +1481 1383 42697451.81849 +1482 1383 -19844426.42677 +1483 1383 -9166666.669679 +1484 1383 11321064.34898 +1491 1383 -413319.0876746 +1492 1383 3.017485141754e-06 +1493 1383 57871.30948708 +1494 1383 57430602.85087 +1495 1383 3.8743019104e-06 +1496 1383 231485.2378496 +1497 1383 -6249019.844286 +1498 1383 -7.443130016327e-06 +1499 1383 57871.30949415 +1509 1383 -18482764.4945 +1510 1383 -9166666.669676 +1511 1383 -10076852.32471 +1512 1383 -59172122.54065 +1513 1383 4.395842552185e-07 +1514 1383 -42928937.05631 +1515 1383 -19947608.24497 +1516 1383 9166666.669675 +1517 1383 -11378935.65847 +1384 1384 525322193.6551 +1385 1384 -11110930.80738 +1386 1384 -7.525086402893e-06 +1387 1384 -56755372.43366 +1388 1384 5555465.403692 +1398 1384 -36666666.66065 +1399 1384 -41677781.0706 +1400 1384 1263866.351621 +1401 1384 2.831220626831e-06 +1402 1384 21326659.08566 +1403 1384 -2777732.703214 +1404 1384 36666666.66064 +1405 1384 -41701455.31301 +1406 1384 1513866.351594 +1476 1384 9166666.669678 +1477 1384 -15641216.50536 +1478 1384 -8177088.970282 +1479 1384 6.034970283508e-07 +1480 1384 -18449398.9965 +1481 1384 -694433.1761458 +1482 1384 -9166666.669679 +1483 1384 -17094223.13462 +1484 1384 8871522.146427 +1491 1384 4.06801700592e-06 +1492 1384 -35246583.02275 +1493 1384 -32861133.64276 +1494 1384 4.231929779053e-06 +1495 1384 35428976.52455 +1496 1384 -2777732.703215 +1497 1384 -7.599592208862e-06 +1498 1384 -41082283.77936 +1499 1384 35638866.34597 +1509 1384 -9166666.669676 +1510 1384 -15732561.20235 +1511 1384 -8246533.414749 +1512 1384 4.619359970093e-07 +1513 1384 -18838452.02672 +1514 1384 -694433.1761459 +1515 1384 9166666.669675 +1516 1384 -17197404.95283 +1517 1384 8940966.590895 +1385 1385 582790450.9006 +1386 1385 231485.2378239 +1387 1385 5555465.403692 +1388 1385 74350397.96411 +1398 1385 2471062.936219 +1399 1385 1236088.573861 +1400 1385 -8882157.948759 +1401 1385 -462970.4754449 +1402 1385 -2777732.703214 +1403 1385 35690216.05203 +1404 1385 -2737270.396254 +1405 1385 1541644.129353 +1406 1385 -8945289.261872 +1476 1385 10018981.01522 +1477 1385 -8177088.970282 +1478 1385 -16145262.77514 +1479 1385 42662729.59629 +1480 1385 -694433.1761458 +1481 1385 -54493616.03735 +1482 1385 11321064.34898 +1483 1385 8871522.146428 +1484 1385 -20019947.11985 +1491 1385 57871.30948763 +1492 1385 -32833355.865 +1493 1385 -37566373.58606 +1494 1385 231485.2378493 +1495 1385 -2777732.703215 +1496 1385 -110039912.4136 +1497 1385 57871.30949473 +1498 1385 35611088.56821 +1499 1385 -53128242.27036 +1509 1385 -10076852.32471 +1510 1385 -8246533.414749 +1511 1385 -16388848.63381 +1512 1385 -42894214.83411 +1513 1385 -694433.1761459 +1514 1385 -55531090.78464 +1515 1385 -11378935.65847 +1516 1385 8940966.590895 +1517 1385 -20295098.63508 +1386 1386 613328698.917 +1387 1386 1.621246337891e-05 +1388 1386 925940.9508365 +1389 1386 82577683.23799 +1390 1386 -7.659196853638e-06 +1391 1386 231485.2378237 +1401 1386 -52678594.23377 +1402 1386 -36666666.66064 +1403 1386 2505785.158418 +1404 1386 -140008022.8906 +1405 1386 2.577900886536e-06 +1406 1386 -462970.4754454 +1407 1386 -52702268.47617 +1408 1386 36666666.66064 +1409 1386 -2702548.174055 +1479 1386 -18391419.7975 +1480 1386 9166666.669678 +1481 1386 10018981.01522 +1482 1386 -58783069.51046 +1483 1386 1.639127731323e-06 +1484 1386 42697451.81849 +1485 1386 -19844426.42677 +1486 1386 -9166666.669679 +1487 1386 11321064.34898 +1494 1386 -413319.0876746 +1495 1386 3.017485141754e-06 +1496 1386 57871.30948708 +1497 1386 57430602.85087 +1498 1386 3.8743019104e-06 +1499 1386 231485.2378496 +1500 1386 -6249019.844286 +1501 1386 -7.443130016327e-06 +1502 1386 57871.30949415 +1512 1386 -18482764.4945 +1513 1386 -9166666.669676 +1514 1386 -10076852.32471 +1515 1386 -59172122.54065 +1516 1386 4.395842552185e-07 +1517 1386 -42928937.05631 +1518 1386 -19947608.24497 +1519 1386 9166666.669675 +1520 1386 -11378935.65847 +1387 1387 525322193.6551 +1388 1387 -11110930.80738 +1389 1387 -7.525086402893e-06 +1390 1387 -56755372.43366 +1391 1387 5555465.403692 +1401 1387 -36666666.66065 +1402 1387 -41677781.0706 +1403 1387 1263866.351621 +1404 1387 2.831220626831e-06 +1405 1387 21326659.08566 +1406 1387 -2777732.703214 +1407 1387 36666666.66064 +1408 1387 -41701455.31301 +1409 1387 1513866.351594 +1479 1387 9166666.669678 +1480 1387 -15641216.50536 +1481 1387 -8177088.970282 +1482 1387 6.034970283508e-07 +1483 1387 -18449398.9965 +1484 1387 -694433.1761458 +1485 1387 -9166666.669679 +1486 1387 -17094223.13462 +1487 1387 8871522.146427 +1494 1387 4.06801700592e-06 +1495 1387 -35246583.02275 +1496 1387 -32861133.64276 +1497 1387 4.231929779053e-06 +1498 1387 35428976.52455 +1499 1387 -2777732.703215 +1500 1387 -7.599592208862e-06 +1501 1387 -41082283.77936 +1502 1387 35638866.34597 +1512 1387 -9166666.669676 +1513 1387 -15732561.20235 +1514 1387 -8246533.414749 +1515 1387 4.619359970093e-07 +1516 1387 -18838452.02672 +1517 1387 -694433.1761459 +1518 1387 9166666.669675 +1519 1387 -17197404.95283 +1520 1387 8940966.590895 +1388 1388 582790450.9006 +1389 1388 231485.2378239 +1390 1388 5555465.403692 +1391 1388 74350397.96411 +1401 1388 2471062.936219 +1402 1388 1236088.573861 +1403 1388 -8882157.948759 +1404 1388 -462970.4754449 +1405 1388 -2777732.703214 +1406 1388 35690216.05203 +1407 1388 -2737270.396254 +1408 1388 1541644.129353 +1409 1388 -8945289.261872 +1479 1388 10018981.01522 +1480 1388 -8177088.970282 +1481 1388 -16145262.77514 +1482 1388 42662729.59629 +1483 1388 -694433.1761458 +1484 1388 -54493616.03735 +1485 1388 11321064.34898 +1486 1388 8871522.146428 +1487 1388 -20019947.11985 +1494 1388 57871.30948763 +1495 1388 -32833355.865 +1496 1388 -37566373.58606 +1497 1388 231485.2378493 +1498 1388 -2777732.703215 +1499 1388 -110039912.4136 +1500 1388 57871.30949473 +1501 1388 35611088.56821 +1502 1388 -53128242.27036 +1512 1388 -10076852.32471 +1513 1388 -8246533.414749 +1514 1388 -16388848.63381 +1515 1388 -42894214.83411 +1516 1388 -694433.1761459 +1517 1388 -55531090.78464 +1518 1388 -11378935.65847 +1519 1388 8940966.590895 +1520 1388 -20295098.63508 +1389 1389 665854880.679 +1390 1389 36667470.52063 +1391 1389 3125090.734117 +1392 1389 18070347.2503 +1393 1389 -36666988.20464 +1394 1389 2702571.265064 +1404 1389 -52678594.23377 +1405 1389 -36666666.66064 +1406 1389 2505785.158418 +1407 1389 -140008022.8906 +1408 1389 2.577900886536e-06 +1409 1389 -462970.4754454 +1410 1389 -52702268.47617 +1411 1389 36666666.66064 +1412 1389 -2702548.174055 +1482 1389 -18391419.7975 +1483 1389 9166666.669678 +1484 1389 10018981.01522 +1485 1389 -71369389.94283 +1486 1389 -9166787.24867 +1487 1389 42147892.99313 +1497 1389 -413319.0876746 +1498 1389 3.017485141754e-06 +1499 1389 57871.30948708 +1500 1389 76553135.92261 +1501 1389 9166867.634673 +1502 1389 781226.2244361 +1503 1389 -18699525.19313 +1504 1389 -9166747.055676 +1505 1389 11379035.3452 +1515 1389 -18482764.4945 +1516 1389 -9166666.669676 +1517 1389 -10076852.32471 +1518 1389 -59172122.54065 +1519 1389 4.395842552185e-07 +1520 1389 -42928937.05631 +1521 1389 -19947608.24497 +1522 1389 9166666.669675 +1523 1389 -11378935.65847 +1390 1390 566847200.4901 +1391 1390 -8610909.306622 +1392 1390 -36667148.97663 +1393 1390 -110262538.3357 +1394 1390 4611016.915367 +1404 1390 -36666666.66065 +1405 1390 -41677781.0706 +1406 1390 1263866.351621 +1407 1390 2.831220626831e-06 +1408 1390 21326659.08566 +1409 1390 -2777732.703214 +1410 1390 36666666.66064 +1411 1390 -41701455.31301 +1412 1390 1513866.351594 +1482 1390 9166666.669678 +1483 1390 -15641216.50536 +1484 1390 -8177088.970282 +1485 1390 -9166747.055672 +1486 1390 -28285264.92641 +1487 1390 7788270.809731 +1497 1390 4.06801700592e-06 +1498 1390 -35246583.02275 +1499 1390 -32861133.64276 +1500 1390 9166867.634673 +1501 1390 51801215.86321 +1502 1390 -2152764.494718 +1503 1390 -9166787.248675 +1504 1390 -50782746.60544 +1505 1390 35402941.77273 +1515 1390 -9166666.669676 +1516 1390 -15732561.20235 +1517 1390 -8246533.414749 +1518 1390 4.619359970093e-07 +1519 1390 -18838452.02672 +1520 1390 -694433.1761459 +1521 1390 9166666.669675 +1522 1390 -17197404.95283 +1523 1390 8940966.590895 +1391 1391 591261848.0956 +1392 1391 2737305.032771 +1393 1391 5388803.421584 +1394 1391 33925571.74906 +1404 1391 2471062.936219 +1405 1391 1236088.573861 +1406 1391 -8882157.948759 +1407 1391 -462970.4754449 +1408 1391 -2777732.703214 +1409 1391 35690216.05203 +1410 1391 -2737270.396254 +1411 1391 1541644.129353 +1412 1391 -8945289.261872 +1482 1391 10018981.01522 +1483 1391 -8177088.970282 +1484 1391 -16145262.77514 +1485 1391 42113167.97979 +1486 1391 7593861.729456 +1487 1391 -55157692.73435 +1497 1391 57871.30948763 +1498 1391 -32833355.865 +1499 1391 -37566373.58606 +1500 1391 781320.0962051 +1501 1391 -2152689.398522 +1502 1391 -91946096.11431 +1503 1391 11379085.18856 +1504 1391 35569610.71641 +1505 1391 -53430905.74636 +1515 1391 -10076852.32471 +1516 1391 -8246533.414749 +1517 1391 -16388848.63381 +1518 1391 -42894214.83411 +1519 1391 -694433.1761459 +1520 1391 -55531090.78464 +1521 1391 -11378935.65847 +1522 1391 8940966.590895 +1523 1391 -20295098.63508 +1392 1392 826502950.7467 +1393 1392 -32829142.2168 +1394 1392 -1574339.432285 +1407 1392 -52678594.23377 +1408 1392 -36666666.66064 +1409 1392 2505785.158418 +1410 1392 -43717734.4447 +1411 1392 32816830.06734 +1412 1392 -231059.6481135 +1413 1392 -637569397.5693 +1414 1392 29345645.47798 +1415 1392 -416821.6161519 +1485 1392 -4579449.609996 +1486 1392 11000120.58261 +1487 1392 12057631.64322 +1500 1392 -14225493.76444 +1501 1392 -9166787.248675 +1502 1392 -10019112.65448 +1503 1392 163714858.8002 +1504 1392 -8207285.558244 +1505 1392 4241855.317219 +1518 1392 -18482764.4945 +1519 1392 -9166666.669676 +1520 1392 -10076852.32471 +1521 1392 -23632031.88637 +1522 1392 8204207.520878 +1523 1392 -22609970.36319 +1524 1392 -160108670.9846 +1525 1392 7336411.37311 +1526 1392 -520782.4807296 +1393 1393 1866175254.747 +1394 1393 -20243144.64085 +1407 1393 -36666666.66065 +1408 1393 -41677781.0706 +1409 1393 1263866.351621 +1410 1393 32810673.99266 +1411 1393 97413180.27061 +1412 1393 -1903194.680072 +1413 1393 44018468.21692 +1414 1393 -1701040543.862 +1415 1393 13714990.87775 +1485 1393 7333413.72174 +1486 1393 -4579449.61 +1487 1393 -6430626.286135 +1500 1393 -9166747.055675 +1501 1393 -46308715.17675 +1502 1393 -32902986.62891 +1503 1393 -8207285.558244 +1504 1393 423632934.9284 +1505 1393 -1353225.115187 +1518 1393 -9166666.669676 +1519 1393 -15732561.20235 +1520 1393 -8246533.414749 +1521 1393 8202668.502206 +1522 1393 11650696.80984 +1523 1393 7172753.555873 +1524 1393 11004617.05965 +1525 1393 -425976457.6889 +1526 1393 20227336.59943 +1394 1394 856594529.5136 +1407 1394 2471062.936219 +1408 1394 1236088.573861 +1409 1394 -8882157.948759 +1410 1394 -1133759.188307 +1411 1394 -1875517.295844 +1412 1394 50029495.24259 +1413 1394 -625232.4242272 +1414 1394 13603538.44251 +1415 1394 -636713913.8918 +1485 1394 8038421.095477 +1486 1394 -9645939.429201 +1487 1394 -12211865.62666 +1500 1394 -10019068.77473 +1501 1394 -33069655.68813 +1502 1394 -41500155.26984 +1503 1394 -4768610.272799 +1504 1394 -8558910.345734 +1505 1394 99719621.84851 +1518 1394 -10076852.32471 +1519 1394 -8246533.414749 +1520 1394 -16388848.63381 +1521 1394 -22783562.29616 +1522 1394 7202053.220155 +1523 1394 -21366221.56937 +1524 1394 -781173.7210934 +1525 1394 20019063.72315 +1526 1394 -161088669.2548 +1395 1395 613328698.917 +1396 1395 1.621246337891e-05 +1397 1395 925940.9508365 +1398 1395 82577683.23799 +1399 1395 -7.659196853638e-06 +1400 1395 231485.2378237 +1416 1395 -140008022.8906 +1417 1395 2.577900886536e-06 +1418 1395 -462970.4754454 +1419 1395 -52702268.47617 +1420 1395 36666666.66064 +1421 1395 -2702548.174055 +1488 1395 -58783069.51046 +1489 1395 1.639127731323e-06 +1490 1395 42697451.81849 +1491 1395 -19844426.42677 +1492 1395 -9166666.669679 +1493 1395 11321064.34898 +1506 1395 57430602.85087 +1507 1395 3.8743019104e-06 +1508 1395 231485.2378496 +1509 1395 -6249019.844286 +1510 1395 -7.443130016327e-06 +1511 1395 57871.30949415 +1527 1395 -59172122.54065 +1528 1395 4.395842552185e-07 +1529 1395 -42928937.05631 +1530 1395 -19947608.24497 +1531 1395 9166666.669675 +1532 1395 -11378935.65847 +1396 1396 525322193.6551 +1397 1396 -11110930.80738 +1398 1396 -7.525086402893e-06 +1399 1396 -56755372.43366 +1400 1396 5555465.403692 +1416 1396 2.831220626831e-06 +1417 1396 21326659.08566 +1418 1396 -2777732.703214 +1419 1396 36666666.66064 +1420 1396 -41701455.31301 +1421 1396 1513866.351594 +1488 1396 6.034970283508e-07 +1489 1396 -18449398.9965 +1490 1396 -694433.1761458 +1491 1396 -9166666.669679 +1492 1396 -17094223.13462 +1493 1396 8871522.146427 +1506 1396 4.231929779053e-06 +1507 1396 35428976.52455 +1508 1396 -2777732.703215 +1509 1396 -7.599592208862e-06 +1510 1396 -41082283.77936 +1511 1396 35638866.34597 +1527 1396 4.619359970093e-07 +1528 1396 -18838452.02672 +1529 1396 -694433.1761459 +1530 1396 9166666.669675 +1531 1396 -17197404.95283 +1532 1396 8940966.590895 +1397 1397 582790450.9006 +1398 1397 231485.2378239 +1399 1397 5555465.403692 +1400 1397 74350397.96411 +1416 1397 -462970.4754449 +1417 1397 -2777732.703214 +1418 1397 35690216.05203 +1419 1397 -2737270.396254 +1420 1397 1541644.129353 +1421 1397 -8945289.261872 +1488 1397 42662729.59629 +1489 1397 -694433.1761458 +1490 1397 -54493616.03735 +1491 1397 11321064.34898 +1492 1397 8871522.146428 +1493 1397 -20019947.11985 +1506 1397 231485.2378493 +1507 1397 -2777732.703215 +1508 1397 -110039912.4136 +1509 1397 57871.30949473 +1510 1397 35611088.56821 +1511 1397 -53128242.27036 +1527 1397 -42894214.83411 +1528 1397 -694433.1761459 +1529 1397 -55531090.78464 +1530 1397 -11378935.65847 +1531 1397 8940966.590895 +1532 1397 -20295098.63508 +1398 1398 613328698.917 +1399 1398 1.621246337891e-05 +1400 1398 925940.9508365 +1401 1398 82577683.23799 +1402 1398 -7.659196853638e-06 +1403 1398 231485.2378237 +1416 1398 -52678594.23377 +1417 1398 -36666666.66064 +1418 1398 2505785.158418 +1419 1398 -140008022.8906 +1420 1398 2.577900886536e-06 +1421 1398 -462970.4754454 +1422 1398 -52702268.47617 +1423 1398 36666666.66064 +1424 1398 -2702548.174055 +1488 1398 -18391419.7975 +1489 1398 9166666.669678 +1490 1398 10018981.01522 +1491 1398 -58783069.51046 +1492 1398 1.639127731323e-06 +1493 1398 42697451.81849 +1494 1398 -19844426.42677 +1495 1398 -9166666.669679 +1496 1398 11321064.34898 +1506 1398 -413319.0876746 +1507 1398 3.017485141754e-06 +1508 1398 57871.30948708 +1509 1398 57430602.85087 +1510 1398 3.8743019104e-06 +1511 1398 231485.2378496 +1512 1398 -6249019.844286 +1513 1398 -7.443130016327e-06 +1514 1398 57871.30949415 +1527 1398 -18482764.4945 +1528 1398 -9166666.669676 +1529 1398 -10076852.32471 +1530 1398 -59172122.54065 +1531 1398 4.395842552185e-07 +1532 1398 -42928937.05631 +1533 1398 -19947608.24497 +1534 1398 9166666.669675 +1535 1398 -11378935.65847 +1399 1399 525322193.6551 +1400 1399 -11110930.80738 +1401 1399 -7.525086402893e-06 +1402 1399 -56755372.43366 +1403 1399 5555465.403692 +1416 1399 -36666666.66065 +1417 1399 -41677781.0706 +1418 1399 1263866.351621 +1419 1399 2.831220626831e-06 +1420 1399 21326659.08566 +1421 1399 -2777732.703214 +1422 1399 36666666.66064 +1423 1399 -41701455.31301 +1424 1399 1513866.351594 +1488 1399 9166666.669678 +1489 1399 -15641216.50536 +1490 1399 -8177088.970282 +1491 1399 6.034970283508e-07 +1492 1399 -18449398.9965 +1493 1399 -694433.1761458 +1494 1399 -9166666.669679 +1495 1399 -17094223.13462 +1496 1399 8871522.146427 +1506 1399 4.06801700592e-06 +1507 1399 -35246583.02275 +1508 1399 -32861133.64276 +1509 1399 4.231929779053e-06 +1510 1399 35428976.52455 +1511 1399 -2777732.703215 +1512 1399 -7.599592208862e-06 +1513 1399 -41082283.77936 +1514 1399 35638866.34597 +1527 1399 -9166666.669676 +1528 1399 -15732561.20235 +1529 1399 -8246533.414749 +1530 1399 4.619359970093e-07 +1531 1399 -18838452.02672 +1532 1399 -694433.1761459 +1533 1399 9166666.669675 +1534 1399 -17197404.95283 +1535 1399 8940966.590895 +1400 1400 582790450.9006 +1401 1400 231485.2378239 +1402 1400 5555465.403692 +1403 1400 74350397.96411 +1416 1400 2471062.936219 +1417 1400 1236088.573861 +1418 1400 -8882157.948759 +1419 1400 -462970.4754449 +1420 1400 -2777732.703214 +1421 1400 35690216.05203 +1422 1400 -2737270.396254 +1423 1400 1541644.129353 +1424 1400 -8945289.261872 +1488 1400 10018981.01522 +1489 1400 -8177088.970282 +1490 1400 -16145262.77514 +1491 1400 42662729.59629 +1492 1400 -694433.1761458 +1493 1400 -54493616.03735 +1494 1400 11321064.34898 +1495 1400 8871522.146428 +1496 1400 -20019947.11985 +1506 1400 57871.30948763 +1507 1400 -32833355.865 +1508 1400 -37566373.58606 +1509 1400 231485.2378493 +1510 1400 -2777732.703215 +1511 1400 -110039912.4136 +1512 1400 57871.30949473 +1513 1400 35611088.56821 +1514 1400 -53128242.27036 +1527 1400 -10076852.32471 +1528 1400 -8246533.414749 +1529 1400 -16388848.63381 +1530 1400 -42894214.83411 +1531 1400 -694433.1761459 +1532 1400 -55531090.78464 +1533 1400 -11378935.65847 +1534 1400 8940966.590895 +1535 1400 -20295098.63508 +1401 1401 613328698.917 +1402 1401 1.621246337891e-05 +1403 1401 925940.9508365 +1404 1401 82577683.23799 +1405 1401 -7.659196853638e-06 +1406 1401 231485.2378237 +1419 1401 -52678594.23377 +1420 1401 -36666666.66064 +1421 1401 2505785.158418 +1422 1401 -140008022.8906 +1423 1401 2.577900886536e-06 +1424 1401 -462970.4754454 +1425 1401 -52702268.47617 +1426 1401 36666666.66064 +1427 1401 -2702548.174055 +1491 1401 -18391419.7975 +1492 1401 9166666.669678 +1493 1401 10018981.01522 +1494 1401 -58783069.51046 +1495 1401 1.639127731323e-06 +1496 1401 42697451.81849 +1497 1401 -19844426.42677 +1498 1401 -9166666.669679 +1499 1401 11321064.34898 +1509 1401 -413319.0876746 +1510 1401 3.017485141754e-06 +1511 1401 57871.30948708 +1512 1401 57430602.85087 +1513 1401 3.8743019104e-06 +1514 1401 231485.2378496 +1515 1401 -6249019.844286 +1516 1401 -7.443130016327e-06 +1517 1401 57871.30949415 +1530 1401 -18482764.4945 +1531 1401 -9166666.669676 +1532 1401 -10076852.32471 +1533 1401 -59172122.54065 +1534 1401 4.395842552185e-07 +1535 1401 -42928937.05631 +1536 1401 -19947608.24497 +1537 1401 9166666.669675 +1538 1401 -11378935.65847 +1402 1402 525322193.6551 +1403 1402 -11110930.80738 +1404 1402 -7.525086402893e-06 +1405 1402 -56755372.43366 +1406 1402 5555465.403692 +1419 1402 -36666666.66065 +1420 1402 -41677781.0706 +1421 1402 1263866.351621 +1422 1402 2.831220626831e-06 +1423 1402 21326659.08566 +1424 1402 -2777732.703214 +1425 1402 36666666.66064 +1426 1402 -41701455.31301 +1427 1402 1513866.351594 +1491 1402 9166666.669678 +1492 1402 -15641216.50536 +1493 1402 -8177088.970282 +1494 1402 6.034970283508e-07 +1495 1402 -18449398.9965 +1496 1402 -694433.1761458 +1497 1402 -9166666.669679 +1498 1402 -17094223.13462 +1499 1402 8871522.146427 +1509 1402 4.06801700592e-06 +1510 1402 -35246583.02275 +1511 1402 -32861133.64276 +1512 1402 4.231929779053e-06 +1513 1402 35428976.52455 +1514 1402 -2777732.703215 +1515 1402 -7.599592208862e-06 +1516 1402 -41082283.77936 +1517 1402 35638866.34597 +1530 1402 -9166666.669676 +1531 1402 -15732561.20235 +1532 1402 -8246533.414749 +1533 1402 4.619359970093e-07 +1534 1402 -18838452.02672 +1535 1402 -694433.1761459 +1536 1402 9166666.669675 +1537 1402 -17197404.95283 +1538 1402 8940966.590895 +1403 1403 582790450.9006 +1404 1403 231485.2378239 +1405 1403 5555465.403692 +1406 1403 74350397.96411 +1419 1403 2471062.936219 +1420 1403 1236088.573861 +1421 1403 -8882157.948759 +1422 1403 -462970.4754449 +1423 1403 -2777732.703214 +1424 1403 35690216.05203 +1425 1403 -2737270.396254 +1426 1403 1541644.129353 +1427 1403 -8945289.261872 +1491 1403 10018981.01522 +1492 1403 -8177088.970282 +1493 1403 -16145262.77514 +1494 1403 42662729.59629 +1495 1403 -694433.1761458 +1496 1403 -54493616.03735 +1497 1403 11321064.34898 +1498 1403 8871522.146428 +1499 1403 -20019947.11985 +1509 1403 57871.30948763 +1510 1403 -32833355.865 +1511 1403 -37566373.58606 +1512 1403 231485.2378493 +1513 1403 -2777732.703215 +1514 1403 -110039912.4136 +1515 1403 57871.30949473 +1516 1403 35611088.56821 +1517 1403 -53128242.27036 +1530 1403 -10076852.32471 +1531 1403 -8246533.414749 +1532 1403 -16388848.63381 +1533 1403 -42894214.83411 +1534 1403 -694433.1761459 +1535 1403 -55531090.78464 +1536 1403 -11378935.65847 +1537 1403 8940966.590895 +1538 1403 -20295098.63508 +1404 1404 613328698.917 +1405 1404 1.621246337891e-05 +1406 1404 925940.9508365 +1407 1404 82577683.23799 +1408 1404 -7.659196853638e-06 +1409 1404 231485.2378237 +1422 1404 -52678594.23377 +1423 1404 -36666666.66064 +1424 1404 2505785.158418 +1425 1404 -140008022.8906 +1426 1404 2.577900886536e-06 +1427 1404 -462970.4754454 +1428 1404 -52702268.47617 +1429 1404 36666666.66064 +1430 1404 -2702548.174055 +1494 1404 -18391419.7975 +1495 1404 9166666.669678 +1496 1404 10018981.01522 +1497 1404 -58783069.51046 +1498 1404 1.639127731323e-06 +1499 1404 42697451.81849 +1500 1404 -19844426.42677 +1501 1404 -9166666.669679 +1502 1404 11321064.34898 +1512 1404 -413319.0876746 +1513 1404 3.017485141754e-06 +1514 1404 57871.30948708 +1515 1404 57430602.85087 +1516 1404 3.8743019104e-06 +1517 1404 231485.2378496 +1518 1404 -6249019.844286 +1519 1404 -7.443130016327e-06 +1520 1404 57871.30949415 +1533 1404 -18482764.4945 +1534 1404 -9166666.669676 +1535 1404 -10076852.32471 +1536 1404 -59172122.54065 +1537 1404 4.395842552185e-07 +1538 1404 -42928937.05631 +1539 1404 -19947608.24497 +1540 1404 9166666.669675 +1541 1404 -11378935.65847 +1405 1405 525322193.6551 +1406 1405 -11110930.80738 +1407 1405 -7.525086402893e-06 +1408 1405 -56755372.43366 +1409 1405 5555465.403692 +1422 1405 -36666666.66065 +1423 1405 -41677781.0706 +1424 1405 1263866.351621 +1425 1405 2.831220626831e-06 +1426 1405 21326659.08566 +1427 1405 -2777732.703214 +1428 1405 36666666.66064 +1429 1405 -41701455.31301 +1430 1405 1513866.351594 +1494 1405 9166666.669678 +1495 1405 -15641216.50536 +1496 1405 -8177088.970282 +1497 1405 6.034970283508e-07 +1498 1405 -18449398.9965 +1499 1405 -694433.1761458 +1500 1405 -9166666.669679 +1501 1405 -17094223.13462 +1502 1405 8871522.146427 +1512 1405 4.06801700592e-06 +1513 1405 -35246583.02275 +1514 1405 -32861133.64276 +1515 1405 4.231929779053e-06 +1516 1405 35428976.52455 +1517 1405 -2777732.703215 +1518 1405 -7.599592208862e-06 +1519 1405 -41082283.77936 +1520 1405 35638866.34597 +1533 1405 -9166666.669676 +1534 1405 -15732561.20235 +1535 1405 -8246533.414749 +1536 1405 4.619359970093e-07 +1537 1405 -18838452.02672 +1538 1405 -694433.1761459 +1539 1405 9166666.669675 +1540 1405 -17197404.95283 +1541 1405 8940966.590895 +1406 1406 582790450.9006 +1407 1406 231485.2378239 +1408 1406 5555465.403692 +1409 1406 74350397.96411 +1422 1406 2471062.936219 +1423 1406 1236088.573861 +1424 1406 -8882157.948759 +1425 1406 -462970.4754449 +1426 1406 -2777732.703214 +1427 1406 35690216.05203 +1428 1406 -2737270.396254 +1429 1406 1541644.129353 +1430 1406 -8945289.261872 +1494 1406 10018981.01522 +1495 1406 -8177088.970282 +1496 1406 -16145262.77514 +1497 1406 42662729.59629 +1498 1406 -694433.1761458 +1499 1406 -54493616.03735 +1500 1406 11321064.34898 +1501 1406 8871522.146428 +1502 1406 -20019947.11985 +1512 1406 57871.30948763 +1513 1406 -32833355.865 +1514 1406 -37566373.58606 +1515 1406 231485.2378493 +1516 1406 -2777732.703215 +1517 1406 -110039912.4136 +1518 1406 57871.30949473 +1519 1406 35611088.56821 +1520 1406 -53128242.27036 +1533 1406 -10076852.32471 +1534 1406 -8246533.414749 +1535 1406 -16388848.63381 +1536 1406 -42894214.83411 +1537 1406 -694433.1761459 +1538 1406 -55531090.78464 +1539 1406 -11378935.65847 +1540 1406 8940966.590895 +1541 1406 -20295098.63508 +1407 1407 613328698.917 +1408 1407 1.621246337891e-05 +1409 1407 925940.9508365 +1410 1407 82577683.23799 +1411 1407 -7.659196853638e-06 +1412 1407 231485.2378237 +1425 1407 -52678594.23377 +1426 1407 -36666666.66064 +1427 1407 2505785.158418 +1428 1407 -140008022.8906 +1429 1407 2.577900886536e-06 +1430 1407 -462970.4754454 +1431 1407 -52702268.47617 +1432 1407 36666666.66064 +1433 1407 -2702548.174055 +1497 1407 -18391419.7975 +1498 1407 9166666.669678 +1499 1407 10018981.01522 +1500 1407 -58783069.51046 +1501 1407 1.639127731323e-06 +1502 1407 42697451.81849 +1503 1407 -19844426.42677 +1504 1407 -9166666.669679 +1505 1407 11321064.34898 +1515 1407 -413319.0876746 +1516 1407 3.017485141754e-06 +1517 1407 57871.30948708 +1518 1407 57430602.85087 +1519 1407 3.8743019104e-06 +1520 1407 231485.2378496 +1521 1407 -6249019.844286 +1522 1407 -7.443130016327e-06 +1523 1407 57871.30949415 +1536 1407 -18482764.4945 +1537 1407 -9166666.669676 +1538 1407 -10076852.32471 +1539 1407 -59172122.54065 +1540 1407 4.395842552185e-07 +1541 1407 -42928937.05631 +1542 1407 -19947608.24497 +1543 1407 9166666.669675 +1544 1407 -11378935.65847 +1408 1408 525322193.6551 +1409 1408 -11110930.80738 +1410 1408 -7.525086402893e-06 +1411 1408 -56755372.43366 +1412 1408 5555465.403692 +1425 1408 -36666666.66065 +1426 1408 -41677781.0706 +1427 1408 1263866.351621 +1428 1408 2.831220626831e-06 +1429 1408 21326659.08566 +1430 1408 -2777732.703214 +1431 1408 36666666.66064 +1432 1408 -41701455.31301 +1433 1408 1513866.351594 +1497 1408 9166666.669678 +1498 1408 -15641216.50536 +1499 1408 -8177088.970282 +1500 1408 6.034970283508e-07 +1501 1408 -18449398.9965 +1502 1408 -694433.1761458 +1503 1408 -9166666.669679 +1504 1408 -17094223.13462 +1505 1408 8871522.146427 +1515 1408 4.06801700592e-06 +1516 1408 -35246583.02275 +1517 1408 -32861133.64276 +1518 1408 4.231929779053e-06 +1519 1408 35428976.52455 +1520 1408 -2777732.703215 +1521 1408 -7.599592208862e-06 +1522 1408 -41082283.77936 +1523 1408 35638866.34597 +1536 1408 -9166666.669676 +1537 1408 -15732561.20235 +1538 1408 -8246533.414749 +1539 1408 4.619359970093e-07 +1540 1408 -18838452.02672 +1541 1408 -694433.1761459 +1542 1408 9166666.669675 +1543 1408 -17197404.95283 +1544 1408 8940966.590895 +1409 1409 582790450.9006 +1410 1409 231485.2378239 +1411 1409 5555465.403692 +1412 1409 74350397.96411 +1425 1409 2471062.936219 +1426 1409 1236088.573861 +1427 1409 -8882157.948759 +1428 1409 -462970.4754449 +1429 1409 -2777732.703214 +1430 1409 35690216.05203 +1431 1409 -2737270.396254 +1432 1409 1541644.129353 +1433 1409 -8945289.261872 +1497 1409 10018981.01522 +1498 1409 -8177088.970282 +1499 1409 -16145262.77514 +1500 1409 42662729.59629 +1501 1409 -694433.1761458 +1502 1409 -54493616.03735 +1503 1409 11321064.34898 +1504 1409 8871522.146428 +1505 1409 -20019947.11985 +1515 1409 57871.30948763 +1516 1409 -32833355.865 +1517 1409 -37566373.58606 +1518 1409 231485.2378493 +1519 1409 -2777732.703215 +1520 1409 -110039912.4136 +1521 1409 57871.30949473 +1522 1409 35611088.56821 +1523 1409 -53128242.27036 +1536 1409 -10076852.32471 +1537 1409 -8246533.414749 +1538 1409 -16388848.63381 +1539 1409 -42894214.83411 +1540 1409 -694433.1761459 +1541 1409 -55531090.78464 +1542 1409 -11378935.65847 +1543 1409 8940966.590895 +1544 1409 -20295098.63508 +1410 1410 519155644.6527 +1411 1410 19890209.72848 +1412 1410 546852.3808991 +1413 1410 -113344502.1932 +1414 1410 -81572741.71556 +1415 1410 807745.8307167 +1428 1410 -52678594.23377 +1429 1410 -36666666.66064 +1430 1410 2505785.158418 +1431 1410 -87908611.13882 +1432 1410 24575313.67981 +1433 1410 -99414.6025005 +1434 1410 -55777752.70527 +1435 1410 4296544.314628 +1436 1410 -121425.9460867 +1500 1410 -18391419.7975 +1501 1410 9166666.669678 +1502 1410 10018981.01522 +1503 1410 -23153309.42759 +1504 1410 8202668.502207 +1505 1410 22268765.65392 +1518 1410 -413319.0876746 +1519 1410 3.017485141754e-06 +1520 1410 57871.30948708 +1521 1410 68265937.74305 +1522 1410 4972552.434569 +1523 1410 136620.1412261 +1524 1410 -38378504.19399 +1525 1410 -20393185.43893 +1526 1410 10904728.81155 +1539 1410 -18482764.4945 +1540 1410 -9166666.669676 +1541 1410 -10076852.32471 +1542 1410 -43384348.52402 +1543 1410 6143828.422977 +1544 1410 -32706624.47957 +1545 1410 -20160575.07792 +1546 1410 1074136.079187 +1547 1410 -602925.9311655 +1411 1411 674296656.4325 +1412 1411 -8315854.013774 +1413 1411 -81578897.79024 +1414 1411 -277711399.8602 +1415 1411 1775953.352355 +1428 1411 -36666666.66065 +1429 1411 -41677781.0706 +1430 1411 1263866.351621 +1431 1411 24575313.67981 +1432 1411 6198641.247472 +1433 1411 -1140600.40519 +1434 1411 4296544.314628 +1435 1411 -164458604.5744 +1436 1411 1195041.228134 +1500 1411 9166666.669678 +1501 1411 -15641216.50536 +1502 1411 -8177088.970282 +1503 1411 8204207.520877 +1504 1411 12129419.26863 +1505 1411 -8118315.333891 +1518 1411 4.06801700592e-06 +1519 1411 -35246583.02275 +1520 1411 -32861133.64276 +1521 1411 4972552.434566 +1522 1411 107051190.7071 +1523 1411 -2079037.895958 +1524 1411 -20394724.45761 +1525 1411 -79470228.63097 +1526 1411 34698117.36652 +1539 1411 -9166666.669676 +1540 1411 -15732561.20235 +1541 1411 -8246533.414749 +1542 1411 6143828.422977 +1543 1411 -19857535.41586 +1544 1411 7819016.563107 +1545 1411 1074136.079187 +1546 1411 -47330788.05857 +1547 1411 16965426.97932 +1412 1412 500032615.4741 +1413 1412 842545.5277112 +1414 1412 1886963.445041 +1415 1412 -79462997.91567 +1428 1412 2471062.936219 +1429 1412 1236088.573861 +1430 1412 -8882157.948759 +1431 1412 -967470.1579145 +1432 1412 -1168378.182963 +1433 1412 37621796.60312 +1434 1412 -190870.3904854 +1435 1412 1195041.228134 +1436 1412 -43133554.29443 +1500 1412 10018981.01522 +1501 1412 -8177088.970282 +1502 1412 -16145262.77514 +1503 1412 22442357.5869 +1504 1412 -8144741.575046 +1505 1412 -20089628.3459 +1518 1412 57871.30948763 +1519 1412 -32833355.865 +1520 1412 -37566373.58606 +1521 1412 136807.9549443 +1522 1412 -2078887.551707 +1523 1412 -39053108.69402 +1524 1412 10904842.27205 +1525 1412 34696841.30973 +1526 1412 -46645425.83998 +1539 1412 -10076852.32471 +1540 1412 -8246533.414749 +1541 1412 -16388848.63381 +1542 1412 -32880235.58879 +1543 1412 7819016.564698 +1544 1412 -47680406.12059 +1545 1412 -602925.9311654 +1546 1412 16965426.97932 +1547 1412 -27359753.63154 +1413 1413 992997068.4552 +1414 1413 19284697.20432 +1415 1413 -396746.4756725 +1431 1413 -51863016.28236 +1432 1413 -31450303.98549 +1433 1413 319461.4773361 +1434 1413 43461620.04061 +1435 1413 42895217.91215 +1436 1413 -251152.4671109 +1437 1413 62501966.85689 +1438 1413 -21400415.93453 +1439 1413 21747.87620521 +1440 1413 -46253.50102974 +1441 1413 28231234.37687 +1442 1413 -49512.40302987 +1503 1413 -159624729.0253 +1504 1413 11004617.05965 +1505 1413 572723.0303333 +1521 1413 -37538860.21074 +1522 1413 -20394724.45761 +1523 1413 -10492248.91842 +1524 1413 145746193.545 +1525 1413 4821174.303457 +1526 1413 8338174.490712 +1542 1413 -18861959.6269 +1543 1413 -7862576.000248 +1544 1413 -10622738.80081 +1545 1413 -37300727.61412 +1546 1413 10723804.48332 +1547 1413 -41832926.99883 +1548 1413 -23212197.68204 +1549 1413 -5350103.986268 +1550 1413 14197971.68996 +1551 1413 -16690161.87378 +1552 1413 7057808.597695 +1553 1413 -10194843.38188 +1414 1414 2147947022.547 +1415 1414 -14974133.4238 +1431 1414 -31450303.98549 +1432 1414 -11693386.9132 +1433 1414 -131493.8517104 +1434 1414 42895217.91215 +1435 1414 170799253.6597 +1436 1414 -626470.3880802 +1437 1414 -6733749.270272 +1438 1414 -7855709.541271 +1439 1414 58407.27655116 +1440 1414 28231234.37687 +1441 1414 -24307750.22323 +1442 1414 72962.07354513 +1503 1414 7336411.373109 +1504 1414 -425492515.7295 +1505 1414 -13147629.82044 +1521 1414 -20393185.43894 +1522 1414 -78630584.64773 +1523 1414 -33781578.76871 +1524 1414 4821174.303456 +1525 1414 434483682.2102 +1526 1414 -3492649.630975 +1542 1414 -7862576.000248 +1543 1414 -8819552.279667 +1544 1414 -8595373.465755 +1545 1414 10723804.48332 +1546 1414 -5466319.193666 +1547 1414 7947549.067445 +1548 1414 -1683437.318397 +1549 1414 -40801616.79024 +1550 1414 33347935.147 +1551 1414 7057808.597695 +1552 1414 -22755536.05731 +1553 1414 16684907.19053 +1415 1415 1146795686.782 +1431 1415 284739.2551368 +1432 1415 -159271.6294699 +1433 1415 -378483.2995525 +1434 1415 -390041.3559778 +1435 1415 -654248.1658537 +1436 1415 194450799.0864 +1437 1415 -12974.3460083 +1438 1415 58407.27655098 +1439 1415 124613403.906 +1440 1415 -84234.62522937 +1441 1415 72962.07354511 +1442 1415 40395467.48366 +1503 1415 381815.353556 +1504 1415 -13300618.50896 +1505 1415 -159798157.3631 +1521 1415 -10492174.57703 +1522 1415 -33783025.80027 +1523 1415 -44406375.21794 +1524 1415 -8362936.617657 +1525 1415 -3856634.052932 +1526 1415 13357391.99385 +1542 1415 -10622738.80081 +1543 1415 -8595373.465755 +1544 1415 -15817835.62473 +1545 1415 -41832926.99887 +1546 1415 7947549.069036 +1547 1415 -79830320.55011 +1548 1415 6072971.68928 +1549 1415 33347935.147 +1550 1415 -72413820.75204 +1551 1415 -10194843.38188 +1552 1415 16684907.19053 +1553 1415 -34377395.78682 +1416 1416 306664349.4585 +1417 1416 7.62939453125e-06 +1418 1416 462970.475417 +1419 1416 41289236.1897 +1420 1416 7333333.332126 +1421 1416 -318285.1588368 +1506 1416 -58783069.51046 +1507 1416 1.639127731323e-06 +1508 1416 42697451.81849 +1509 1416 -19844426.42677 +1510 1416 -9166666.669679 +1511 1416 11321064.34898 +1527 1416 28714906.85473 +1528 1416 5.364418029785e-07 +1529 1416 -8530229.601834 +1530 1416 -3124509.92214 +1531 1416 1833333.333932 +1532 1416 -2241064.345998 +1417 1417 262661096.8276 +1418 1417 -5555465.403687 +1419 1417 -7333333.332131 +1420 1417 -28377291.64613 +1421 1417 2749954.924074 +1506 1417 6.034970283508e-07 +1507 1417 -18449398.9965 +1508 1417 -694433.1761458 +1509 1417 -9166666.669679 +1510 1417 -17094223.13462 +1511 1417 8871522.146427 +1527 1417 8.940696716309e-07 +1528 1417 17714093.69157 +1529 1417 -1388866.351609 +1530 1417 -1833333.333939 +1531 1417 -20541141.88968 +1532 1417 17812488.72854 +1418 1418 291395225.4503 +1419 1418 723381.5076579 +1420 1418 2805510.47962 +1421 1418 37176251.17061 +1506 1418 42662729.59629 +1507 1418 -694433.1761458 +1508 1418 -54493616.03735 +1509 1418 11321064.34898 +1510 1418 8871522.146428 +1511 1418 -20019947.11985 +1527 1418 8588103.728686 +1528 1418 -1388866.351609 +1529 1418 -55021008.39532 +1530 1418 2298935.655493 +1531 1418 17812488.72855 +1532 1418 -26564121.13518 +1419 1419 306664349.4585 +1420 1419 7.62939453125e-06 +1421 1419 462970.475417 +1422 1419 41289236.1897 +1423 1419 7333333.332126 +1424 1419 -318285.1588368 +1506 1419 -18391419.7975 +1507 1419 9166666.669678 +1508 1419 10018981.01522 +1509 1419 -58783069.51046 +1510 1419 1.639127731323e-06 +1511 1419 42697451.81849 +1512 1419 -19844426.42677 +1513 1419 -9166666.669679 +1514 1419 11321064.34898 +1527 1419 -206659.5438359 +1528 1419 -1833333.333934 +1529 1419 -1980647.67925 +1530 1419 28714906.85473 +1531 1419 5.364418029785e-07 +1532 1419 -8530229.601834 +1533 1419 -3124509.92214 +1534 1419 1833333.333932 +1535 1419 -2241064.345998 +1420 1420 262661096.8276 +1421 1420 -5555465.403687 +1422 1420 -7333333.332131 +1423 1420 -28377291.64613 +1424 1420 2749954.924074 +1506 1420 9166666.669678 +1507 1420 -15641216.50536 +1508 1420 -8177088.970282 +1509 1420 6.034970283508e-07 +1510 1420 -18449398.9965 +1511 1420 -694433.1761458 +1512 1420 -9166666.669679 +1513 1420 -17094223.13462 +1514 1420 8871522.146427 +1527 1420 1833333.333937 +1528 1420 -17623291.51138 +1529 1420 -16423622.37693 +1530 1420 8.940696716309e-07 +1531 1420 17714093.69157 +1532 1420 -1388866.351609 +1533 1420 -1833333.333939 +1534 1420 -20541141.88968 +1535 1420 17812488.72854 +1421 1421 291395225.4503 +1422 1421 723381.5076579 +1423 1421 2805510.47962 +1424 1421 37176251.17061 +1506 1421 10018981.01522 +1507 1421 -8177088.970282 +1508 1421 -16145262.77514 +1509 1421 42662729.59629 +1510 1421 -694433.1761458 +1511 1421 -54493616.03735 +1512 1421 11321064.34898 +1513 1421 8871522.146428 +1514 1421 -20019947.11985 +1527 1421 2038518.988737 +1528 1421 -16423622.37695 +1529 1421 -18783186.79303 +1530 1421 8588103.728686 +1531 1421 -1388866.351609 +1532 1421 -55021008.39532 +1533 1421 2298935.655493 +1534 1421 17812488.72855 +1535 1421 -26564121.13518 +1422 1422 306664349.4585 +1423 1422 7.62939453125e-06 +1424 1422 462970.475417 +1425 1422 41289236.1897 +1426 1422 7333333.332126 +1427 1422 -318285.1588368 +1509 1422 -18391419.7975 +1510 1422 9166666.669678 +1511 1422 10018981.01522 +1512 1422 -58783069.51046 +1513 1422 1.639127731323e-06 +1514 1422 42697451.81849 +1515 1422 -19844426.42677 +1516 1422 -9166666.669679 +1517 1422 11321064.34898 +1530 1422 -206659.5438359 +1531 1422 -1833333.333934 +1532 1422 -1980647.67925 +1533 1422 28714906.85473 +1534 1422 5.364418029785e-07 +1535 1422 -8530229.601834 +1536 1422 -3124509.92214 +1537 1422 1833333.333932 +1538 1422 -2241064.345998 +1423 1423 262661096.8276 +1424 1423 -5555465.403687 +1425 1423 -7333333.332131 +1426 1423 -28377291.64613 +1427 1423 2749954.924074 +1509 1423 9166666.669678 +1510 1423 -15641216.50536 +1511 1423 -8177088.970282 +1512 1423 6.034970283508e-07 +1513 1423 -18449398.9965 +1514 1423 -694433.1761458 +1515 1423 -9166666.669679 +1516 1423 -17094223.13462 +1517 1423 8871522.146427 +1530 1423 1833333.333937 +1531 1423 -17623291.51138 +1532 1423 -16423622.37693 +1533 1423 8.940696716309e-07 +1534 1423 17714093.69157 +1535 1423 -1388866.351609 +1536 1423 -1833333.333939 +1537 1423 -20541141.88968 +1538 1423 17812488.72854 +1424 1424 291395225.4503 +1425 1424 723381.5076579 +1426 1424 2805510.47962 +1427 1424 37176251.17061 +1509 1424 10018981.01522 +1510 1424 -8177088.970282 +1511 1424 -16145262.77514 +1512 1424 42662729.59629 +1513 1424 -694433.1761458 +1514 1424 -54493616.03735 +1515 1424 11321064.34898 +1516 1424 8871522.146428 +1517 1424 -20019947.11985 +1530 1424 2038518.988737 +1531 1424 -16423622.37695 +1532 1424 -18783186.79303 +1533 1424 8588103.728686 +1534 1424 -1388866.351609 +1535 1424 -55021008.39532 +1536 1424 2298935.655493 +1537 1424 17812488.72855 +1538 1424 -26564121.13518 +1425 1425 306664349.4585 +1426 1425 7.62939453125e-06 +1427 1425 462970.475417 +1428 1425 41289236.1897 +1429 1425 7333333.332126 +1430 1425 -318285.1588368 +1512 1425 -18391419.7975 +1513 1425 9166666.669678 +1514 1425 10018981.01522 +1515 1425 -58783069.51046 +1516 1425 1.639127731323e-06 +1517 1425 42697451.81849 +1518 1425 -19844426.42677 +1519 1425 -9166666.669679 +1520 1425 11321064.34898 +1533 1425 -206659.5438359 +1534 1425 -1833333.333934 +1535 1425 -1980647.67925 +1536 1425 28714906.85473 +1537 1425 5.364418029785e-07 +1538 1425 -8530229.601834 +1539 1425 -3124509.92214 +1540 1425 1833333.333932 +1541 1425 -2241064.345998 +1426 1426 262661096.8276 +1427 1426 -5555465.403687 +1428 1426 -7333333.332131 +1429 1426 -28377291.64613 +1430 1426 2749954.924074 +1512 1426 9166666.669678 +1513 1426 -15641216.50536 +1514 1426 -8177088.970282 +1515 1426 6.034970283508e-07 +1516 1426 -18449398.9965 +1517 1426 -694433.1761458 +1518 1426 -9166666.669679 +1519 1426 -17094223.13462 +1520 1426 8871522.146427 +1533 1426 1833333.333937 +1534 1426 -17623291.51138 +1535 1426 -16423622.37693 +1536 1426 8.940696716309e-07 +1537 1426 17714093.69157 +1538 1426 -1388866.351609 +1539 1426 -1833333.333939 +1540 1426 -20541141.88968 +1541 1426 17812488.72854 +1427 1427 291395225.4503 +1428 1427 723381.5076579 +1429 1427 2805510.47962 +1430 1427 37176251.17061 +1512 1427 10018981.01522 +1513 1427 -8177088.970282 +1514 1427 -16145262.77514 +1515 1427 42662729.59629 +1516 1427 -694433.1761458 +1517 1427 -54493616.03735 +1518 1427 11321064.34898 +1519 1427 8871522.146428 +1520 1427 -20019947.11985 +1533 1427 2038518.988737 +1534 1427 -16423622.37695 +1535 1427 -18783186.79303 +1536 1427 8588103.728686 +1537 1427 -1388866.351609 +1538 1427 -55021008.39532 +1539 1427 2298935.655493 +1540 1427 17812488.72855 +1541 1427 -26564121.13518 +1428 1428 306664349.4585 +1429 1428 7.62939453125e-06 +1430 1428 462970.475417 +1431 1428 41289236.1897 +1432 1428 7333333.332126 +1433 1428 -318285.1588368 +1515 1428 -18391419.7975 +1516 1428 9166666.669678 +1517 1428 10018981.01522 +1518 1428 -58783069.51046 +1519 1428 1.639127731323e-06 +1520 1428 42697451.81849 +1521 1428 -19844426.42677 +1522 1428 -9166666.669679 +1523 1428 11321064.34898 +1536 1428 -206659.5438359 +1537 1428 -1833333.333934 +1538 1428 -1980647.67925 +1539 1428 28714906.85473 +1540 1428 5.364418029785e-07 +1541 1428 -8530229.601834 +1542 1428 -3124509.92214 +1543 1428 1833333.333932 +1544 1428 -2241064.345998 +1429 1429 262661096.8276 +1430 1429 -5555465.403687 +1431 1429 -7333333.332131 +1432 1429 -28377291.64613 +1433 1429 2749954.924074 +1515 1429 9166666.669678 +1516 1429 -15641216.50536 +1517 1429 -8177088.970282 +1518 1429 6.034970283508e-07 +1519 1429 -18449398.9965 +1520 1429 -694433.1761458 +1521 1429 -9166666.669679 +1522 1429 -17094223.13462 +1523 1429 8871522.146427 +1536 1429 1833333.333937 +1537 1429 -17623291.51138 +1538 1429 -16423622.37693 +1539 1429 8.940696716309e-07 +1540 1429 17714093.69157 +1541 1429 -1388866.351609 +1542 1429 -1833333.333939 +1543 1429 -20541141.88968 +1544 1429 17812488.72854 +1430 1430 291395225.4503 +1431 1430 723381.5076579 +1432 1430 2805510.47962 +1433 1430 37176251.17061 +1515 1430 10018981.01522 +1516 1430 -8177088.970282 +1517 1430 -16145262.77514 +1518 1430 42662729.59629 +1519 1430 -694433.1761458 +1520 1430 -54493616.03735 +1521 1430 11321064.34898 +1522 1430 8871522.146428 +1523 1430 -20019947.11985 +1536 1430 2038518.988737 +1537 1430 -16423622.37695 +1538 1430 -18783186.79303 +1539 1430 8588103.728686 +1540 1430 -1388866.351609 +1541 1430 -55021008.39532 +1542 1430 2298935.655493 +1543 1430 17812488.72855 +1544 1430 -26564121.13518 +1431 1431 307321293.6177 +1432 1431 5217302.692383 +1433 1431 2443291.135431 +1434 1431 -12283347.92522 +1435 1431 -27675645.7152 +1436 1431 392217.5447181 +1518 1431 -18391419.7975 +1519 1431 9166666.669678 +1520 1431 10018981.01522 +1521 1431 -42844315.11718 +1522 1431 6143828.42298 +1523 1431 32439903.28737 +1524 1431 -19056485.08992 +1525 1431 -7862576.000246 +1526 1431 10773788.984 +1539 1431 -206659.5438359 +1540 1431 -1833333.333934 +1541 1431 -1980647.67925 +1542 1431 28878510.79233 +1543 1431 1304325.673737 +1544 1431 -8034871.658814 +1545 1431 -18263780.54944 +1546 1431 -6918911.432209 +1547 1431 8066734.94041 +1432 1432 292495414.5893 +1433 1432 -3617588.716354 +1434 1432 -42342312.37946 +1435 1432 -73068635.97963 +1436 1432 598083.9198294 +1518 1432 9166666.669678 +1519 1432 -15641216.50536 +1520 1432 -8177088.970282 +1521 1432 6143828.422979 +1522 1432 -19317502.00901 +1523 1432 -8396261.212014 +1524 1432 -7862576.000246 +1525 1432 -9014077.742685 +1526 1432 8522682.095422 +1539 1432 1833333.333937 +1540 1432 -17623291.51138 +1541 1432 -16423622.37693 +1542 1432 1304325.673737 +1543 1432 25172041.03341 +1544 1432 -904397.1795395 +1545 1432 -10585578.10008 +1546 1432 -33460102.57053 +1547 1432 25378687.64334 +1433 1433 299489762.7903 +1434 1433 565828.6557986 +1435 1433 625861.6976026 +1436 1433 18644724.62356 +1518 1433 10018981.01522 +1519 1433 -8177088.970282 +1520 1433 -16145262.77514 +1521 1433 32613514.40058 +1522 1433 -8396261.210409 +1523 1433 -46240317.03562 +1524 1433 10773788.984 +1525 1433 8522682.095422 +1526 1433 -16336570.1928 +1539 1433 2038518.988737 +1540 1433 -16423622.37695 +1541 1433 -18783186.79303 +1542 1433 9082906.116151 +1543 1433 -904397.1795395 +1544 1433 -52999059.66538 +1545 1433 12398123.82872 +1546 1433 25378687.64175 +1547 1433 -35853335.01949 +1434 1434 358811430.7903 +1435 1434 52593962.28105 +1436 1434 -97551.46225023 +1437 1434 -71392253.48931 +1438 1434 -45102098.94442 +1439 1434 106737.5969375 +1440 1434 9275019.197588 +1441 1434 -12341313.18395 +1442 1434 144785.8447827 +1521 1434 -19715237.85133 +1522 1434 1074136.079186 +1523 1434 524851.8469836 +1524 1434 -37144610.97898 +1525 1434 10723804.48332 +1526 1434 41672628.54298 +1542 1434 -17529221.15356 +1543 1434 -10585578.10008 +1544 1434 -12149931.72292 +1545 1434 -1095063.644689 +1546 1434 13148490.57674 +1547 1434 -8461748.97526 +1548 1434 -34526661.87963 +1549 1434 -11275524.74166 +1550 1434 20339184.40592 +1551 1434 -25557949.75669 +1552 1434 -3085328.297506 +1553 1434 8108904.791231 +1435 1435 452274744.3036 +1436 1435 -1473057.85089 +1437 1435 -45102098.94442 +1438 1435 -51062500.21883 +1439 1435 72962.07354495 +1440 1435 -27007979.8482 +1441 1435 -62389541.28179 +1442 1435 233441.0174853 +1521 1435 1074136.079186 +1522 1435 -46885450.83199 +1523 1435 -16367906.36496 +1524 1435 10723804.48332 +1525 1435 -5310202.55853 +1526 1435 -8267728.707675 +1542 1435 -6918911.432211 +1543 1435 -32725543.17465 +1544 1435 -25072701.23725 +1545 1435 13148490.57674 +1546 1435 22270764.74516 +1547 1435 -368264.4629124 +1548 1435 -11275524.74166 +1549 1435 -29444223.55951 +1550 1435 16684907.19053 +1551 1435 -6751994.965377 +1552 1435 -43474089.88536 +1553 1435 33391693.58226 +1436 1436 478029006.2153 +1437 1436 106737.5969376 +1438 1436 72962.07354495 +1439 1436 13640717.48805 +1440 1436 179508.0669963 +1441 1436 233441.0174853 +1442 1436 63954215.97093 +1521 1436 524851.8469835 +1522 1436 -16367906.36496 +1523 1436 -26172187.69396 +1524 1436 41672628.54301 +1525 1436 -8267728.706071 +1526 1436 -79414009.52307 +1542 1436 -7922709.501298 +1543 1436 -25072701.23886 +1544 1436 -33894509.96379 +1545 1436 8239362.133108 +1546 1436 -368264.4629123 +1547 1436 -122620538.7512 +1548 1436 20339184.40592 +1549 1436 16684907.19053 +1550 1436 -41066083.28901 +1551 1436 12197515.90567 +1552 1436 33391693.58226 +1553 1436 -58349324.81867 +1437 1437 235659396.7196 +1438 1437 50733749.26305 +1439 1437 -62257.13548279 +1440 1437 -5082746.465364 +1441 1437 1102098.951645 +1442 1437 -31506.11544451 +1524 1437 -23117500.71233 +1525 1437 -1683437.318397 +1526 1437 -6070778.306718 +1545 1437 -34431964.90992 +1546 1437 -11275524.74166 +1547 1437 -20285815.60742 +1548 1437 -18665832.59106 +1549 1437 12683437.32201 +1550 1437 8109435.714787 +1551 1437 -34533186.62789 +1552 1437 275524.7380462 +1553 1437 -30502841.80065 +1438 1438 216642073.1324 +1439 1438 -58407.27654648 +1440 1438 15768765.6159 +1441 1438 63962500.24948 +1442 1438 -72962.07354212 +1524 1438 -5350103.986268 +1525 1438 -40706919.82054 +1526 1438 -33318731.50871 +1545 1438 -11275524.74166 +1546 1438 -29349526.58979 +1547 1438 -16648426.15375 +1548 1438 12683437.32201 +1549 1438 -23420163.4902 +1550 1438 6652064.846425 +1551 1438 3942191.405917 +1552 1438 -17271874.94068 +1553 1438 3315092.816032 +1439 1439 342775232.3518 +1440 1439 -66228.3376576 +1441 1439 -72962.0735423 +1442 1439 110134282.579 +1524 1439 -14195778.30738 +1525 1439 -33318731.50871 +1526 1439 -72161295.49948 +1545 1439 -20285815.60742 +1546 1439 -16648426.15375 +1547 1439 -40813558.03643 +1548 1439 -8140564.282544 +1549 1439 -6681268.484718 +1550 1439 -121188010.0031 +1551 1439 -30502841.80265 +1552 1439 -3351573.852824 +1553 1439 -61166429.37081 +1440 1440 173317617.147 +1441 1440 -16992020.14457 +1442 1440 40399.34029067 +1524 1440 -16595464.90406 +1525 1440 7057808.597695 +1526 1440 10161406.6248 +1545 1440 -25273858.84771 +1546 1440 -6751994.965378 +1547 1440 -12142484.09433 +1548 1440 -34533186.62789 +1549 1440 3942191.405919 +1550 1440 30478408.18933 +1551 1440 -12139913.87007 +1552 1440 -4248005.038235 +1553 1440 -4104552.942003 +1441 1441 200198427.6337 +1442 1441 -233441.0174782 +1524 1441 7057808.597695 +1525 1441 -22660839.0876 +1526 1441 -16648426.15375 +1545 1441 -3085328.297507 +1546 1441 -43189998.97639 +1547 1441 -33274973.07346 +1548 1441 275524.7380478 +1549 1441 -17271874.94068 +1550 1441 3315092.816032 +1551 1441 -4248005.038235 +1552 1441 -5419711.245076 +1553 1441 6608306.41117 +1442 1442 258752397.6415 +1524 1442 10161406.6248 +1525 1442 -16648426.15375 +1526 1442 -34124870.53423 +1545 1442 -8088595.202104 +1546 1442 -33274973.07346 +1547 1442 -57591749.06139 +1548 1442 30478408.18734 +1549 1442 -3351573.852824 +1550 1442 -61166429.37081 +1551 1442 4037947.05666 +1552 1442 -6725026.919973 +1553 1442 -83230082.36618 +1443 1443 383498024.544 +1444 1443 36666666.66064 +1445 1443 2662179.892796 +1446 1443 -204675200.5845 +1447 1443 -36666988.20463 +1448 1443 -2662156.039165 +1449 1443 11810466.31493 +1450 1443 29333654.8725 +1451 1443 -2152800.8684 +1554 1443 35932670.30059 +1555 1443 9166666.669679 +1556 1443 9311563.653784 +1557 1443 -72925641.46158 +1558 1443 -9166747.055676 +1559 1443 -43478968.03166 +1560 1443 -7497354.851903 +1561 1443 7333413.72174 +1562 1443 -9080099.689708 +1444 1444 328493596.9861 +1445 1444 -6944376.434009 +1446 1444 -36667148.97662 +1447 1444 -32338700.60373 +1448 1444 -3847226.785359 +1449 1444 44000482.30876 +1450 1444 11810466.31493 +1451 1444 2416693.76713 +1554 1444 9166666.669678 +1555 1444 22181563.40434 +1556 1444 5180609.664774 +1557 1444 -9166787.248676 +1558 1444 -29841516.44517 +1559 1444 -9524419.110191 +1560 1444 11000120.58261 +1561 1444 -7497354.8519 +1562 1444 10895952.52268 +1445 1445 364686604.8413 +1446 1445 -2662144.112346 +1447 1445 -3097217.751863 +1448 1445 -5157813.372203 +1449 1445 -3229201.302601 +1450 1445 1611129.178087 +1451 1445 31494576.83983 +1554 1445 -7806863.548506 +1555 1445 -8513909.758068 +1556 1445 -68673244.4318 +1557 1445 -43444243.01831 +1558 1445 -9329934.937092 +1559 1445 -59307696.78438 +1560 1445 -13620149.53456 +1561 1445 7263968.348454 +1562 1445 -19992946.27174 +1446 1446 665854880.679 +1447 1446 36667470.52063 +1448 1446 3125090.734117 +1449 1446 18070347.2503 +1450 1446 -36666988.20464 +1451 1446 2702571.265064 +1452 1446 -140008022.8906 +1453 1446 2.577900886536e-06 +1454 1446 -462970.4754454 +1455 1446 -52702268.47617 +1456 1446 36666666.66064 +1457 1446 -2702548.174055 +1554 1446 -71369389.94283 +1555 1446 -9166787.24867 +1556 1446 42147892.99313 +1557 1446 76553135.92261 +1558 1446 9166867.634673 +1559 1446 781226.2244361 +1560 1446 -18699525.19313 +1561 1446 -9166747.055676 +1562 1446 11379035.3452 +1563 1446 -59172122.54065 +1564 1446 4.395842552185e-07 +1565 1446 -42928937.05631 +1566 1446 -19947608.24497 +1567 1446 9166666.669675 +1568 1446 -11378935.65847 +1447 1447 566847200.4901 +1448 1447 -8610909.306622 +1449 1447 -36667148.97663 +1450 1447 -110262538.3357 +1451 1447 4611016.915367 +1452 1447 2.831220626831e-06 +1453 1447 21326659.08566 +1454 1447 -2777732.703214 +1455 1447 36666666.66064 +1456 1447 -41701455.31301 +1457 1447 1513866.351594 +1554 1447 -9166747.055672 +1555 1447 -28285264.92641 +1556 1447 7788270.809731 +1557 1447 9166867.634673 +1558 1447 51801215.86321 +1559 1447 -2152764.494718 +1560 1447 -9166787.248675 +1561 1447 -50782746.60544 +1562 1447 35402941.77273 +1563 1447 4.619359970093e-07 +1564 1447 -18838452.02672 +1565 1447 -694433.1761459 +1566 1447 9166666.669675 +1567 1447 -17197404.95283 +1568 1447 8940966.590895 +1448 1448 591261848.0956 +1449 1448 2737305.032771 +1450 1448 5388803.421584 +1451 1448 33925571.74906 +1452 1448 -462970.4754449 +1453 1448 -2777732.703214 +1454 1448 35690216.05203 +1455 1448 -2737270.396254 +1456 1448 1541644.129353 +1457 1448 -8945289.261872 +1554 1448 42113167.97979 +1555 1448 7593861.729456 +1556 1448 -55157692.73435 +1557 1448 781320.0962051 +1558 1448 -2152689.398522 +1559 1448 -91946096.11431 +1560 1448 11379085.18856 +1561 1448 35569610.71641 +1562 1448 -53430905.74636 +1563 1448 -42894214.83411 +1564 1448 -694433.1761459 +1565 1448 -55531090.78464 +1566 1448 -11378935.65847 +1567 1448 8940966.590895 +1568 1448 -20295098.63508 +1449 1449 383498024.544 +1450 1449 36666666.66064 +1451 1449 2662179.892796 +1452 1449 -52678594.23377 +1453 1449 -36666666.66064 +1454 1449 2505785.158418 +1455 1449 -204675200.5845 +1456 1449 -36666988.20463 +1457 1449 -2662156.039165 +1458 1449 11810466.31493 +1459 1449 29333654.8725 +1460 1449 -2152800.8684 +1554 1449 -4579449.609996 +1555 1449 11000120.58261 +1556 1449 12057631.64322 +1557 1449 -14225493.76444 +1558 1449 -9166787.248675 +1559 1449 -10019112.65448 +1560 1449 35932670.30059 +1561 1449 9166666.669679 +1562 1449 9311563.653784 +1563 1449 -18482764.4945 +1564 1449 -9166666.669676 +1565 1449 -10076852.32471 +1566 1449 -72925641.46158 +1567 1449 -9166747.055676 +1568 1449 -43478968.03166 +1569 1449 -7497354.851903 +1570 1449 7333413.72174 +1571 1449 -9080099.689708 +1450 1450 328493596.9861 +1451 1450 -6944376.43401 +1452 1450 -36666666.66065 +1453 1450 -41677781.0706 +1454 1450 1263866.351621 +1455 1450 -36667148.97662 +1456 1450 -32338700.60373 +1457 1450 -3847226.785359 +1458 1450 44000482.30876 +1459 1450 11810466.31493 +1460 1450 2416693.76713 +1554 1450 7333413.72174 +1555 1450 -4579449.61 +1556 1450 -6430626.286135 +1557 1450 -9166747.055675 +1558 1450 -46308715.17675 +1559 1450 -32902986.62891 +1560 1450 9166666.669678 +1561 1450 22181563.40434 +1562 1450 5180609.664774 +1563 1450 -9166666.669676 +1564 1450 -15732561.20235 +1565 1450 -8246533.414749 +1566 1450 -9166787.248676 +1567 1450 -29841516.44517 +1568 1450 -9524419.110191 +1569 1450 11000120.58261 +1570 1450 -7497354.8519 +1571 1450 10895952.52268 +1451 1451 364686604.8413 +1452 1451 2471062.936219 +1453 1451 1236088.573861 +1454 1451 -8882157.948759 +1455 1451 -2662144.112346 +1456 1451 -3097217.751863 +1457 1451 -5157813.372203 +1458 1451 -3229201.302601 +1459 1451 1611129.178087 +1460 1451 31494576.83983 +1554 1451 8038421.095477 +1555 1451 -9645939.429201 +1556 1451 -12211865.62666 +1557 1451 -10019068.77473 +1558 1451 -33069655.68813 +1559 1451 -41500155.26984 +1560 1451 -7806863.548506 +1561 1451 -8513909.758068 +1562 1451 -68673244.4318 +1563 1451 -10076852.32471 +1564 1451 -8246533.414749 +1565 1451 -16388848.63381 +1566 1451 -43444243.01831 +1567 1451 -9329934.937092 +1568 1451 -59307696.78438 +1569 1451 -13620149.53456 +1570 1451 7263968.348454 +1571 1451 -19992946.27174 +1452 1452 613328698.917 +1453 1452 1.621246337891e-05 +1454 1452 925940.9508365 +1455 1452 82577683.23799 +1456 1452 -7.659196853638e-06 +1457 1452 231485.2378237 +1461 1452 -140008022.8906 +1462 1452 2.577900886536e-06 +1463 1452 -462970.4754454 +1464 1452 -52702268.47617 +1465 1452 36666666.66064 +1466 1452 -2702548.174055 +1557 1452 -58783069.51046 +1558 1452 1.639127731323e-06 +1559 1452 42697451.81849 +1560 1452 -19844426.42677 +1561 1452 -9166666.669679 +1562 1452 11321064.34898 +1563 1452 57430602.85087 +1564 1452 3.8743019104e-06 +1565 1452 231485.2378496 +1566 1452 -6249019.844286 +1567 1452 -7.443130016327e-06 +1568 1452 57871.30949415 +1572 1452 -59172122.54065 +1573 1452 4.395842552185e-07 +1574 1452 -42928937.05631 +1575 1452 -19947608.24497 +1576 1452 9166666.669675 +1577 1452 -11378935.65847 +1453 1453 525322193.6551 +1454 1453 -11110930.80738 +1455 1453 -7.525086402893e-06 +1456 1453 -56755372.43366 +1457 1453 5555465.403692 +1461 1453 2.831220626831e-06 +1462 1453 21326659.08566 +1463 1453 -2777732.703214 +1464 1453 36666666.66064 +1465 1453 -41701455.31301 +1466 1453 1513866.351594 +1557 1453 6.034970283508e-07 +1558 1453 -18449398.9965 +1559 1453 -694433.1761458 +1560 1453 -9166666.669679 +1561 1453 -17094223.13462 +1562 1453 8871522.146427 +1563 1453 4.231929779053e-06 +1564 1453 35428976.52455 +1565 1453 -2777732.703215 +1566 1453 -7.599592208862e-06 +1567 1453 -41082283.77936 +1568 1453 35638866.34597 +1572 1453 4.619359970093e-07 +1573 1453 -18838452.02672 +1574 1453 -694433.1761459 +1575 1453 9166666.669675 +1576 1453 -17197404.95283 +1577 1453 8940966.590895 +1454 1454 582790450.9006 +1455 1454 231485.2378239 +1456 1454 5555465.403692 +1457 1454 74350397.96411 +1461 1454 -462970.4754449 +1462 1454 -2777732.703214 +1463 1454 35690216.05203 +1464 1454 -2737270.396254 +1465 1454 1541644.129353 +1466 1454 -8945289.261872 +1557 1454 42662729.59629 +1558 1454 -694433.1761458 +1559 1454 -54493616.03735 +1560 1454 11321064.34898 +1561 1454 8871522.146428 +1562 1454 -20019947.11985 +1563 1454 231485.2378493 +1564 1454 -2777732.703215 +1565 1454 -110039912.4136 +1566 1454 57871.30949473 +1567 1454 35611088.56821 +1568 1454 -53128242.27036 +1572 1454 -42894214.83411 +1573 1454 -694433.1761459 +1574 1454 -55531090.78464 +1575 1454 -11378935.65847 +1576 1454 8940966.590895 +1577 1454 -20295098.63508 +1455 1455 665854880.679 +1456 1455 36667470.52063 +1457 1455 3125090.734117 +1458 1455 18070347.2503 +1459 1455 -36666988.20464 +1460 1455 2702571.265064 +1461 1455 -52678594.23377 +1462 1455 -36666666.66064 +1463 1455 2505785.158418 +1464 1455 -140008022.8906 +1465 1455 2.577900886536e-06 +1466 1455 -462970.4754454 +1467 1455 -52702268.47617 +1468 1455 36666666.66064 +1469 1455 -2702548.174055 +1557 1455 -18391419.7975 +1558 1455 9166666.669678 +1559 1455 10018981.01522 +1560 1455 -71369389.94283 +1561 1455 -9166787.24867 +1562 1455 42147892.99313 +1563 1455 -413319.0876746 +1564 1455 3.017485141754e-06 +1565 1455 57871.30948708 +1566 1455 76553135.92261 +1567 1455 9166867.634673 +1568 1455 781226.2244361 +1569 1455 -18699525.19313 +1570 1455 -9166747.055676 +1571 1455 11379035.3452 +1572 1455 -18482764.4945 +1573 1455 -9166666.669676 +1574 1455 -10076852.32471 +1575 1455 -59172122.54065 +1576 1455 4.395842552185e-07 +1577 1455 -42928937.05631 +1578 1455 -19947608.24497 +1579 1455 9166666.669675 +1580 1455 -11378935.65847 +1456 1456 566847200.4901 +1457 1456 -8610909.306622 +1458 1456 -36667148.97663 +1459 1456 -110262538.3357 +1460 1456 4611016.915367 +1461 1456 -36666666.66065 +1462 1456 -41677781.0706 +1463 1456 1263866.351621 +1464 1456 2.831220626831e-06 +1465 1456 21326659.08566 +1466 1456 -2777732.703214 +1467 1456 36666666.66064 +1468 1456 -41701455.31301 +1469 1456 1513866.351594 +1557 1456 9166666.669678 +1558 1456 -15641216.50536 +1559 1456 -8177088.970282 +1560 1456 -9166747.055672 +1561 1456 -28285264.92641 +1562 1456 7788270.809731 +1563 1456 4.06801700592e-06 +1564 1456 -35246583.02275 +1565 1456 -32861133.64276 +1566 1456 9166867.634673 +1567 1456 51801215.86321 +1568 1456 -2152764.494718 +1569 1456 -9166787.248675 +1570 1456 -50782746.60544 +1571 1456 35402941.77273 +1572 1456 -9166666.669676 +1573 1456 -15732561.20235 +1574 1456 -8246533.414749 +1575 1456 4.619359970093e-07 +1576 1456 -18838452.02672 +1577 1456 -694433.1761459 +1578 1456 9166666.669675 +1579 1456 -17197404.95283 +1580 1456 8940966.590895 +1457 1457 591261848.0956 +1458 1457 2737305.032771 +1459 1457 5388803.421584 +1460 1457 33925571.74906 +1461 1457 2471062.936219 +1462 1457 1236088.573861 +1463 1457 -8882157.948759 +1464 1457 -462970.4754449 +1465 1457 -2777732.703214 +1466 1457 35690216.05203 +1467 1457 -2737270.396254 +1468 1457 1541644.129353 +1469 1457 -8945289.261872 +1557 1457 10018981.01522 +1558 1457 -8177088.970282 +1559 1457 -16145262.77514 +1560 1457 42113167.97979 +1561 1457 7593861.729456 +1562 1457 -55157692.73435 +1563 1457 57871.30948763 +1564 1457 -32833355.865 +1565 1457 -37566373.58606 +1566 1457 781320.0962051 +1567 1457 -2152689.398522 +1568 1457 -91946096.11431 +1569 1457 11379085.18856 +1570 1457 35569610.71641 +1571 1457 -53430905.74636 +1572 1457 -10076852.32471 +1573 1457 -8246533.414749 +1574 1457 -16388848.63381 +1575 1457 -42894214.83411 +1576 1457 -694433.1761459 +1577 1457 -55531090.78464 +1578 1457 -11378935.65847 +1579 1457 8940966.590895 +1580 1457 -20295098.63508 +1458 1458 383498024.544 +1459 1458 36666666.66064 +1460 1458 2662179.892796 +1464 1458 -52678594.23377 +1465 1458 -36666666.66064 +1466 1458 2505785.158418 +1467 1458 -204675200.5845 +1468 1458 -36666988.20463 +1469 1458 -2662156.039165 +1470 1458 11810466.31493 +1471 1458 29333654.8725 +1472 1458 -2152800.8684 +1560 1458 -4579449.609996 +1561 1458 11000120.58261 +1562 1458 12057631.64322 +1566 1458 -14225493.76444 +1567 1458 -9166787.248675 +1568 1458 -10019112.65448 +1569 1458 35932670.30059 +1570 1458 9166666.669679 +1571 1458 9311563.653784 +1575 1458 -18482764.4945 +1576 1458 -9166666.669676 +1577 1458 -10076852.32471 +1578 1458 -72925641.46158 +1579 1458 -9166747.055676 +1580 1458 -43478968.03166 +1581 1458 -7497354.851903 +1582 1458 7333413.72174 +1583 1458 -9080099.689708 +1459 1459 328493596.9861 +1460 1459 -6944376.43401 +1464 1459 -36666666.66065 +1465 1459 -41677781.0706 +1466 1459 1263866.351621 +1467 1459 -36667148.97662 +1468 1459 -32338700.60373 +1469 1459 -3847226.785359 +1470 1459 44000482.30876 +1471 1459 11810466.31493 +1472 1459 2416693.76713 +1560 1459 7333413.72174 +1561 1459 -4579449.61 +1562 1459 -6430626.286135 +1566 1459 -9166747.055675 +1567 1459 -46308715.17675 +1568 1459 -32902986.62891 +1569 1459 9166666.669678 +1570 1459 22181563.40434 +1571 1459 5180609.664774 +1575 1459 -9166666.669676 +1576 1459 -15732561.20235 +1577 1459 -8246533.414749 +1578 1459 -9166787.248676 +1579 1459 -29841516.44517 +1580 1459 -9524419.110191 +1581 1459 11000120.58261 +1582 1459 -7497354.8519 +1583 1459 10895952.52268 +1460 1460 364686604.8413 +1464 1460 2471062.936219 +1465 1460 1236088.573861 +1466 1460 -8882157.948759 +1467 1460 -2662144.112346 +1468 1460 -3097217.751863 +1469 1460 -5157813.372203 +1470 1460 -3229201.302601 +1471 1460 1611129.178087 +1472 1460 31494576.83983 +1560 1460 8038421.095477 +1561 1460 -9645939.429201 +1562 1460 -12211865.62666 +1566 1460 -10019068.77473 +1567 1460 -33069655.68813 +1568 1460 -41500155.26984 +1569 1460 -7806863.548506 +1570 1460 -8513909.758068 +1571 1460 -68673244.4318 +1575 1460 -10076852.32471 +1576 1460 -8246533.414749 +1577 1460 -16388848.63381 +1578 1460 -43444243.01831 +1579 1460 -9329934.937092 +1580 1460 -59307696.78438 +1581 1460 -13620149.53456 +1582 1460 7263968.348454 +1583 1460 -19992946.27174 +1461 1461 613328698.917 +1462 1461 1.621246337891e-05 +1463 1461 925940.9508365 +1464 1461 82577683.23799 +1465 1461 -7.659196853638e-06 +1466 1461 231485.2378237 +1473 1461 -140008022.8906 +1474 1461 2.577900886536e-06 +1475 1461 -462970.4754454 +1476 1461 -52702268.47617 +1477 1461 36666666.66064 +1478 1461 -2702548.174055 +1563 1461 -58783069.51046 +1564 1461 1.639127731323e-06 +1565 1461 42697451.81849 +1566 1461 -19844426.42677 +1567 1461 -9166666.669679 +1568 1461 11321064.34898 +1572 1461 57430602.85087 +1573 1461 3.8743019104e-06 +1574 1461 231485.2378496 +1575 1461 -6249019.844286 +1576 1461 -7.443130016327e-06 +1577 1461 57871.30949415 +1584 1461 -59172122.54065 +1585 1461 4.395842552185e-07 +1586 1461 -42928937.05631 +1587 1461 -19947608.24497 +1588 1461 9166666.669675 +1589 1461 -11378935.65847 +1462 1462 525322193.6551 +1463 1462 -11110930.80738 +1464 1462 -7.525086402893e-06 +1465 1462 -56755372.43366 +1466 1462 5555465.403692 +1473 1462 2.831220626831e-06 +1474 1462 21326659.08566 +1475 1462 -2777732.703214 +1476 1462 36666666.66064 +1477 1462 -41701455.31301 +1478 1462 1513866.351594 +1563 1462 6.034970283508e-07 +1564 1462 -18449398.9965 +1565 1462 -694433.1761458 +1566 1462 -9166666.669679 +1567 1462 -17094223.13462 +1568 1462 8871522.146427 +1572 1462 4.231929779053e-06 +1573 1462 35428976.52455 +1574 1462 -2777732.703215 +1575 1462 -7.599592208862e-06 +1576 1462 -41082283.77936 +1577 1462 35638866.34597 +1584 1462 4.619359970093e-07 +1585 1462 -18838452.02672 +1586 1462 -694433.1761459 +1587 1462 9166666.669675 +1588 1462 -17197404.95283 +1589 1462 8940966.590895 +1463 1463 582790450.9006 +1464 1463 231485.2378239 +1465 1463 5555465.403692 +1466 1463 74350397.96411 +1473 1463 -462970.4754449 +1474 1463 -2777732.703214 +1475 1463 35690216.05203 +1476 1463 -2737270.396254 +1477 1463 1541644.129353 +1478 1463 -8945289.261872 +1563 1463 42662729.59629 +1564 1463 -694433.1761458 +1565 1463 -54493616.03735 +1566 1463 11321064.34898 +1567 1463 8871522.146428 +1568 1463 -20019947.11985 +1572 1463 231485.2378493 +1573 1463 -2777732.703215 +1574 1463 -110039912.4136 +1575 1463 57871.30949473 +1576 1463 35611088.56821 +1577 1463 -53128242.27036 +1584 1463 -42894214.83411 +1585 1463 -694433.1761459 +1586 1463 -55531090.78464 +1587 1463 -11378935.65847 +1588 1463 8940966.590895 +1589 1463 -20295098.63508 +1464 1464 613328698.917 +1465 1464 1.621246337891e-05 +1466 1464 925940.9508365 +1467 1464 82577683.23799 +1468 1464 -7.659196853638e-06 +1469 1464 231485.2378237 +1473 1464 -52678594.23377 +1474 1464 -36666666.66064 +1475 1464 2505785.158418 +1476 1464 -140008022.8906 +1477 1464 2.577900886536e-06 +1478 1464 -462970.4754454 +1479 1464 -52702268.47617 +1480 1464 36666666.66064 +1481 1464 -2702548.174055 +1563 1464 -18391419.7975 +1564 1464 9166666.669678 +1565 1464 10018981.01522 +1566 1464 -58783069.51046 +1567 1464 1.639127731323e-06 +1568 1464 42697451.81849 +1569 1464 -19844426.42677 +1570 1464 -9166666.669679 +1571 1464 11321064.34898 +1572 1464 -413319.0876746 +1573 1464 3.017485141754e-06 +1574 1464 57871.30948708 +1575 1464 57430602.85087 +1576 1464 3.8743019104e-06 +1577 1464 231485.2378496 +1578 1464 -6249019.844286 +1579 1464 -7.443130016327e-06 +1580 1464 57871.30949415 +1584 1464 -18482764.4945 +1585 1464 -9166666.669676 +1586 1464 -10076852.32471 +1587 1464 -59172122.54065 +1588 1464 4.395842552185e-07 +1589 1464 -42928937.05631 +1590 1464 -19947608.24497 +1591 1464 9166666.669675 +1592 1464 -11378935.65847 +1465 1465 525322193.6551 +1466 1465 -11110930.80738 +1467 1465 -7.525086402893e-06 +1468 1465 -56755372.43366 +1469 1465 5555465.403692 +1473 1465 -36666666.66065 +1474 1465 -41677781.0706 +1475 1465 1263866.351621 +1476 1465 2.831220626831e-06 +1477 1465 21326659.08566 +1478 1465 -2777732.703214 +1479 1465 36666666.66064 +1480 1465 -41701455.31301 +1481 1465 1513866.351594 +1563 1465 9166666.669678 +1564 1465 -15641216.50536 +1565 1465 -8177088.970282 +1566 1465 6.034970283508e-07 +1567 1465 -18449398.9965 +1568 1465 -694433.1761458 +1569 1465 -9166666.669679 +1570 1465 -17094223.13462 +1571 1465 8871522.146427 +1572 1465 4.06801700592e-06 +1573 1465 -35246583.02275 +1574 1465 -32861133.64276 +1575 1465 4.231929779053e-06 +1576 1465 35428976.52455 +1577 1465 -2777732.703215 +1578 1465 -7.599592208862e-06 +1579 1465 -41082283.77936 +1580 1465 35638866.34597 +1584 1465 -9166666.669676 +1585 1465 -15732561.20235 +1586 1465 -8246533.414749 +1587 1465 4.619359970093e-07 +1588 1465 -18838452.02672 +1589 1465 -694433.1761459 +1590 1465 9166666.669675 +1591 1465 -17197404.95283 +1592 1465 8940966.590895 +1466 1466 582790450.9006 +1467 1466 231485.2378239 +1468 1466 5555465.403692 +1469 1466 74350397.96411 +1473 1466 2471062.936219 +1474 1466 1236088.573861 +1475 1466 -8882157.948759 +1476 1466 -462970.4754449 +1477 1466 -2777732.703214 +1478 1466 35690216.05203 +1479 1466 -2737270.396254 +1480 1466 1541644.129353 +1481 1466 -8945289.261872 +1563 1466 10018981.01522 +1564 1466 -8177088.970282 +1565 1466 -16145262.77514 +1566 1466 42662729.59629 +1567 1466 -694433.1761458 +1568 1466 -54493616.03735 +1569 1466 11321064.34898 +1570 1466 8871522.146428 +1571 1466 -20019947.11985 +1572 1466 57871.30948763 +1573 1466 -32833355.865 +1574 1466 -37566373.58606 +1575 1466 231485.2378493 +1576 1466 -2777732.703215 +1577 1466 -110039912.4136 +1578 1466 57871.30949473 +1579 1466 35611088.56821 +1580 1466 -53128242.27036 +1584 1466 -10076852.32471 +1585 1466 -8246533.414749 +1586 1466 -16388848.63381 +1587 1466 -42894214.83411 +1588 1466 -694433.1761459 +1589 1466 -55531090.78464 +1590 1466 -11378935.65847 +1591 1466 8940966.590895 +1592 1466 -20295098.63508 +1467 1467 665854880.679 +1468 1467 36667470.52063 +1469 1467 3125090.734117 +1470 1467 18070347.2503 +1471 1467 -36666988.20464 +1472 1467 2702571.265064 +1476 1467 -52678594.23377 +1477 1467 -36666666.66064 +1478 1467 2505785.158418 +1479 1467 -140008022.8906 +1480 1467 2.577900886536e-06 +1481 1467 -462970.4754454 +1482 1467 -52702268.47617 +1483 1467 36666666.66064 +1484 1467 -2702548.174055 +1566 1467 -18391419.7975 +1567 1467 9166666.669678 +1568 1467 10018981.01522 +1569 1467 -71369389.94283 +1570 1467 -9166787.24867 +1571 1467 42147892.99313 +1575 1467 -413319.0876746 +1576 1467 3.017485141754e-06 +1577 1467 57871.30948708 +1578 1467 76553135.92261 +1579 1467 9166867.634673 +1580 1467 781226.2244361 +1581 1467 -18699525.19313 +1582 1467 -9166747.055676 +1583 1467 11379035.3452 +1587 1467 -18482764.4945 +1588 1467 -9166666.669676 +1589 1467 -10076852.32471 +1590 1467 -59172122.54065 +1591 1467 4.395842552185e-07 +1592 1467 -42928937.05631 +1593 1467 -19947608.24497 +1594 1467 9166666.669675 +1595 1467 -11378935.65847 +1468 1468 566847200.4901 +1469 1468 -8610909.306622 +1470 1468 -36667148.97663 +1471 1468 -110262538.3357 +1472 1468 4611016.915367 +1476 1468 -36666666.66065 +1477 1468 -41677781.0706 +1478 1468 1263866.351621 +1479 1468 2.831220626831e-06 +1480 1468 21326659.08566 +1481 1468 -2777732.703214 +1482 1468 36666666.66064 +1483 1468 -41701455.31301 +1484 1468 1513866.351594 +1566 1468 9166666.669678 +1567 1468 -15641216.50536 +1568 1468 -8177088.970282 +1569 1468 -9166747.055672 +1570 1468 -28285264.92641 +1571 1468 7788270.809731 +1575 1468 4.06801700592e-06 +1576 1468 -35246583.02275 +1577 1468 -32861133.64276 +1578 1468 9166867.634673 +1579 1468 51801215.86321 +1580 1468 -2152764.494718 +1581 1468 -9166787.248675 +1582 1468 -50782746.60544 +1583 1468 35402941.77273 +1587 1468 -9166666.669676 +1588 1468 -15732561.20235 +1589 1468 -8246533.414749 +1590 1468 4.619359970093e-07 +1591 1468 -18838452.02672 +1592 1468 -694433.1761459 +1593 1468 9166666.669675 +1594 1468 -17197404.95283 +1595 1468 8940966.590895 +1469 1469 591261848.0956 +1470 1469 2737305.032771 +1471 1469 5388803.421584 +1472 1469 33925571.74906 +1476 1469 2471062.936219 +1477 1469 1236088.573861 +1478 1469 -8882157.948759 +1479 1469 -462970.4754449 +1480 1469 -2777732.703214 +1481 1469 35690216.05203 +1482 1469 -2737270.396254 +1483 1469 1541644.129353 +1484 1469 -8945289.261872 +1566 1469 10018981.01522 +1567 1469 -8177088.970282 +1568 1469 -16145262.77514 +1569 1469 42113167.97979 +1570 1469 7593861.729456 +1571 1469 -55157692.73435 +1575 1469 57871.30948763 +1576 1469 -32833355.865 +1577 1469 -37566373.58606 +1578 1469 781320.0962051 +1579 1469 -2152689.398522 +1580 1469 -91946096.11431 +1581 1469 11379085.18856 +1582 1469 35569610.71641 +1583 1469 -53430905.74636 +1587 1469 -10076852.32471 +1588 1469 -8246533.414749 +1589 1469 -16388848.63381 +1590 1469 -42894214.83411 +1591 1469 -694433.1761459 +1592 1469 -55531090.78464 +1593 1469 -11378935.65847 +1594 1469 8940966.590895 +1595 1469 -20295098.63508 +1470 1470 383498024.544 +1471 1470 36666666.66064 +1472 1470 2662179.892796 +1479 1470 -52678594.23377 +1480 1470 -36666666.66064 +1481 1470 2505785.158418 +1482 1470 -204675200.5845 +1483 1470 -36666988.20463 +1484 1470 -2662156.039165 +1485 1470 11810466.31493 +1486 1470 29333654.8725 +1487 1470 -2152800.8684 +1569 1470 -4579449.609996 +1570 1470 11000120.58261 +1571 1470 12057631.64322 +1578 1470 -14225493.76444 +1579 1470 -9166787.248675 +1580 1470 -10019112.65448 +1581 1470 35932670.30059 +1582 1470 9166666.669679 +1583 1470 9311563.653784 +1590 1470 -18482764.4945 +1591 1470 -9166666.669676 +1592 1470 -10076852.32471 +1593 1470 -72925641.46158 +1594 1470 -9166747.055676 +1595 1470 -43478968.03166 +1596 1470 -7497354.851903 +1597 1470 7333413.72174 +1598 1470 -9080099.689708 +1471 1471 328493596.9861 +1472 1471 -6944376.43401 +1479 1471 -36666666.66065 +1480 1471 -41677781.0706 +1481 1471 1263866.351621 +1482 1471 -36667148.97662 +1483 1471 -32338700.60373 +1484 1471 -3847226.785359 +1485 1471 44000482.30876 +1486 1471 11810466.31493 +1487 1471 2416693.76713 +1569 1471 7333413.72174 +1570 1471 -4579449.61 +1571 1471 -6430626.286135 +1578 1471 -9166747.055675 +1579 1471 -46308715.17675 +1580 1471 -32902986.62891 +1581 1471 9166666.669678 +1582 1471 22181563.40434 +1583 1471 5180609.664774 +1590 1471 -9166666.669676 +1591 1471 -15732561.20235 +1592 1471 -8246533.414749 +1593 1471 -9166787.248676 +1594 1471 -29841516.44517 +1595 1471 -9524419.110191 +1596 1471 11000120.58261 +1597 1471 -7497354.8519 +1598 1471 10895952.52268 +1472 1472 364686604.8413 +1479 1472 2471062.936219 +1480 1472 1236088.573861 +1481 1472 -8882157.948759 +1482 1472 -2662144.112346 +1483 1472 -3097217.751863 +1484 1472 -5157813.372203 +1485 1472 -3229201.302601 +1486 1472 1611129.178087 +1487 1472 31494576.83983 +1569 1472 8038421.095477 +1570 1472 -9645939.429201 +1571 1472 -12211865.62666 +1578 1472 -10019068.77473 +1579 1472 -33069655.68813 +1580 1472 -41500155.26984 +1581 1472 -7806863.548506 +1582 1472 -8513909.758068 +1583 1472 -68673244.4318 +1590 1472 -10076852.32471 +1591 1472 -8246533.414749 +1592 1472 -16388848.63381 +1593 1472 -43444243.01831 +1594 1472 -9329934.937092 +1595 1472 -59307696.78438 +1596 1472 -13620149.53456 +1597 1472 7263968.348454 +1598 1472 -19992946.27174 +1473 1473 613328698.917 +1474 1473 1.621246337891e-05 +1475 1473 925940.9508365 +1476 1473 82577683.23799 +1477 1473 -7.659196853638e-06 +1478 1473 231485.2378237 +1488 1473 -140008022.8906 +1489 1473 2.577900886536e-06 +1490 1473 -462970.4754454 +1491 1473 -52702268.47617 +1492 1473 36666666.66064 +1493 1473 -2702548.174055 +1572 1473 -58783069.51046 +1573 1473 1.639127731323e-06 +1574 1473 42697451.81849 +1575 1473 -19844426.42677 +1576 1473 -9166666.669679 +1577 1473 11321064.34898 +1584 1473 57430602.85087 +1585 1473 3.8743019104e-06 +1586 1473 231485.2378496 +1587 1473 -6249019.844286 +1588 1473 -7.443130016327e-06 +1589 1473 57871.30949415 +1599 1473 -59172122.54065 +1600 1473 4.395842552185e-07 +1601 1473 -42928937.05631 +1602 1473 -19947608.24497 +1603 1473 9166666.669675 +1604 1473 -11378935.65847 +1474 1474 525322193.6551 +1475 1474 -11110930.80738 +1476 1474 -7.525086402893e-06 +1477 1474 -56755372.43366 +1478 1474 5555465.403692 +1488 1474 2.831220626831e-06 +1489 1474 21326659.08566 +1490 1474 -2777732.703214 +1491 1474 36666666.66064 +1492 1474 -41701455.31301 +1493 1474 1513866.351594 +1572 1474 6.034970283508e-07 +1573 1474 -18449398.9965 +1574 1474 -694433.1761458 +1575 1474 -9166666.669679 +1576 1474 -17094223.13462 +1577 1474 8871522.146427 +1584 1474 4.231929779053e-06 +1585 1474 35428976.52455 +1586 1474 -2777732.703215 +1587 1474 -7.599592208862e-06 +1588 1474 -41082283.77936 +1589 1474 35638866.34597 +1599 1474 4.619359970093e-07 +1600 1474 -18838452.02672 +1601 1474 -694433.1761459 +1602 1474 9166666.669675 +1603 1474 -17197404.95283 +1604 1474 8940966.590895 +1475 1475 582790450.9006 +1476 1475 231485.2378239 +1477 1475 5555465.403692 +1478 1475 74350397.96411 +1488 1475 -462970.4754449 +1489 1475 -2777732.703214 +1490 1475 35690216.05203 +1491 1475 -2737270.396254 +1492 1475 1541644.129353 +1493 1475 -8945289.261872 +1572 1475 42662729.59629 +1573 1475 -694433.1761458 +1574 1475 -54493616.03735 +1575 1475 11321064.34898 +1576 1475 8871522.146428 +1577 1475 -20019947.11985 +1584 1475 231485.2378493 +1585 1475 -2777732.703215 +1586 1475 -110039912.4136 +1587 1475 57871.30949473 +1588 1475 35611088.56821 +1589 1475 -53128242.27036 +1599 1475 -42894214.83411 +1600 1475 -694433.1761459 +1601 1475 -55531090.78464 +1602 1475 -11378935.65847 +1603 1475 8940966.590895 +1604 1475 -20295098.63508 +1476 1476 613328698.917 +1477 1476 1.621246337891e-05 +1478 1476 925940.9508365 +1479 1476 82577683.23799 +1480 1476 -7.659196853638e-06 +1481 1476 231485.2378237 +1488 1476 -52678594.23377 +1489 1476 -36666666.66064 +1490 1476 2505785.158418 +1491 1476 -140008022.8906 +1492 1476 2.577900886536e-06 +1493 1476 -462970.4754454 +1494 1476 -52702268.47617 +1495 1476 36666666.66064 +1496 1476 -2702548.174055 +1572 1476 -18391419.7975 +1573 1476 9166666.669678 +1574 1476 10018981.01522 +1575 1476 -58783069.51046 +1576 1476 1.639127731323e-06 +1577 1476 42697451.81849 +1578 1476 -19844426.42677 +1579 1476 -9166666.669679 +1580 1476 11321064.34898 +1584 1476 -413319.0876746 +1585 1476 3.017485141754e-06 +1586 1476 57871.30948708 +1587 1476 57430602.85087 +1588 1476 3.8743019104e-06 +1589 1476 231485.2378496 +1590 1476 -6249019.844286 +1591 1476 -7.443130016327e-06 +1592 1476 57871.30949415 +1599 1476 -18482764.4945 +1600 1476 -9166666.669676 +1601 1476 -10076852.32471 +1602 1476 -59172122.54065 +1603 1476 4.395842552185e-07 +1604 1476 -42928937.05631 +1605 1476 -19947608.24497 +1606 1476 9166666.669675 +1607 1476 -11378935.65847 +1477 1477 525322193.6551 +1478 1477 -11110930.80738 +1479 1477 -7.525086402893e-06 +1480 1477 -56755372.43366 +1481 1477 5555465.403692 +1488 1477 -36666666.66065 +1489 1477 -41677781.0706 +1490 1477 1263866.351621 +1491 1477 2.831220626831e-06 +1492 1477 21326659.08566 +1493 1477 -2777732.703214 +1494 1477 36666666.66064 +1495 1477 -41701455.31301 +1496 1477 1513866.351594 +1572 1477 9166666.669678 +1573 1477 -15641216.50536 +1574 1477 -8177088.970282 +1575 1477 6.034970283508e-07 +1576 1477 -18449398.9965 +1577 1477 -694433.1761458 +1578 1477 -9166666.669679 +1579 1477 -17094223.13462 +1580 1477 8871522.146427 +1584 1477 4.06801700592e-06 +1585 1477 -35246583.02275 +1586 1477 -32861133.64276 +1587 1477 4.231929779053e-06 +1588 1477 35428976.52455 +1589 1477 -2777732.703215 +1590 1477 -7.599592208862e-06 +1591 1477 -41082283.77936 +1592 1477 35638866.34597 +1599 1477 -9166666.669676 +1600 1477 -15732561.20235 +1601 1477 -8246533.414749 +1602 1477 4.619359970093e-07 +1603 1477 -18838452.02672 +1604 1477 -694433.1761459 +1605 1477 9166666.669675 +1606 1477 -17197404.95283 +1607 1477 8940966.590895 +1478 1478 582790450.9006 +1479 1478 231485.2378239 +1480 1478 5555465.403692 +1481 1478 74350397.96411 +1488 1478 2471062.936219 +1489 1478 1236088.573861 +1490 1478 -8882157.948759 +1491 1478 -462970.4754449 +1492 1478 -2777732.703214 +1493 1478 35690216.05203 +1494 1478 -2737270.396254 +1495 1478 1541644.129353 +1496 1478 -8945289.261872 +1572 1478 10018981.01522 +1573 1478 -8177088.970282 +1574 1478 -16145262.77514 +1575 1478 42662729.59629 +1576 1478 -694433.1761458 +1577 1478 -54493616.03735 +1578 1478 11321064.34898 +1579 1478 8871522.146428 +1580 1478 -20019947.11985 +1584 1478 57871.30948763 +1585 1478 -32833355.865 +1586 1478 -37566373.58606 +1587 1478 231485.2378493 +1588 1478 -2777732.703215 +1589 1478 -110039912.4136 +1590 1478 57871.30949473 +1591 1478 35611088.56821 +1592 1478 -53128242.27036 +1599 1478 -10076852.32471 +1600 1478 -8246533.414749 +1601 1478 -16388848.63381 +1602 1478 -42894214.83411 +1603 1478 -694433.1761459 +1604 1478 -55531090.78464 +1605 1478 -11378935.65847 +1606 1478 8940966.590895 +1607 1478 -20295098.63508 +1479 1479 613328698.917 +1480 1479 1.621246337891e-05 +1481 1479 925940.9508365 +1482 1479 82577683.23799 +1483 1479 -7.659196853638e-06 +1484 1479 231485.2378237 +1491 1479 -52678594.23377 +1492 1479 -36666666.66064 +1493 1479 2505785.158418 +1494 1479 -140008022.8906 +1495 1479 2.577900886536e-06 +1496 1479 -462970.4754454 +1497 1479 -52702268.47617 +1498 1479 36666666.66064 +1499 1479 -2702548.174055 +1575 1479 -18391419.7975 +1576 1479 9166666.669678 +1577 1479 10018981.01522 +1578 1479 -58783069.51046 +1579 1479 1.639127731323e-06 +1580 1479 42697451.81849 +1581 1479 -19844426.42677 +1582 1479 -9166666.669679 +1583 1479 11321064.34898 +1587 1479 -413319.0876746 +1588 1479 3.017485141754e-06 +1589 1479 57871.30948708 +1590 1479 57430602.85087 +1591 1479 3.8743019104e-06 +1592 1479 231485.2378496 +1593 1479 -6249019.844286 +1594 1479 -7.443130016327e-06 +1595 1479 57871.30949415 +1602 1479 -18482764.4945 +1603 1479 -9166666.669676 +1604 1479 -10076852.32471 +1605 1479 -59172122.54065 +1606 1479 4.395842552185e-07 +1607 1479 -42928937.05631 +1608 1479 -19947608.24497 +1609 1479 9166666.669675 +1610 1479 -11378935.65847 +1480 1480 525322193.6551 +1481 1480 -11110930.80738 +1482 1480 -7.525086402893e-06 +1483 1480 -56755372.43366 +1484 1480 5555465.403692 +1491 1480 -36666666.66065 +1492 1480 -41677781.0706 +1493 1480 1263866.351621 +1494 1480 2.831220626831e-06 +1495 1480 21326659.08566 +1496 1480 -2777732.703214 +1497 1480 36666666.66064 +1498 1480 -41701455.31301 +1499 1480 1513866.351594 +1575 1480 9166666.669678 +1576 1480 -15641216.50536 +1577 1480 -8177088.970282 +1578 1480 6.034970283508e-07 +1579 1480 -18449398.9965 +1580 1480 -694433.1761458 +1581 1480 -9166666.669679 +1582 1480 -17094223.13462 +1583 1480 8871522.146427 +1587 1480 4.06801700592e-06 +1588 1480 -35246583.02275 +1589 1480 -32861133.64276 +1590 1480 4.231929779053e-06 +1591 1480 35428976.52455 +1592 1480 -2777732.703215 +1593 1480 -7.599592208862e-06 +1594 1480 -41082283.77936 +1595 1480 35638866.34597 +1602 1480 -9166666.669676 +1603 1480 -15732561.20235 +1604 1480 -8246533.414749 +1605 1480 4.619359970093e-07 +1606 1480 -18838452.02672 +1607 1480 -694433.1761459 +1608 1480 9166666.669675 +1609 1480 -17197404.95283 +1610 1480 8940966.590895 +1481 1481 582790450.9006 +1482 1481 231485.2378239 +1483 1481 5555465.403692 +1484 1481 74350397.96411 +1491 1481 2471062.936219 +1492 1481 1236088.573861 +1493 1481 -8882157.948759 +1494 1481 -462970.4754449 +1495 1481 -2777732.703214 +1496 1481 35690216.05203 +1497 1481 -2737270.396254 +1498 1481 1541644.129353 +1499 1481 -8945289.261872 +1575 1481 10018981.01522 +1576 1481 -8177088.970282 +1577 1481 -16145262.77514 +1578 1481 42662729.59629 +1579 1481 -694433.1761458 +1580 1481 -54493616.03735 +1581 1481 11321064.34898 +1582 1481 8871522.146428 +1583 1481 -20019947.11985 +1587 1481 57871.30948763 +1588 1481 -32833355.865 +1589 1481 -37566373.58606 +1590 1481 231485.2378493 +1591 1481 -2777732.703215 +1592 1481 -110039912.4136 +1593 1481 57871.30949473 +1594 1481 35611088.56821 +1595 1481 -53128242.27036 +1602 1481 -10076852.32471 +1603 1481 -8246533.414749 +1604 1481 -16388848.63381 +1605 1481 -42894214.83411 +1606 1481 -694433.1761459 +1607 1481 -55531090.78464 +1608 1481 -11378935.65847 +1609 1481 8940966.590895 +1610 1481 -20295098.63508 +1482 1482 665854880.679 +1483 1482 36667470.52063 +1484 1482 3125090.734117 +1485 1482 18070347.2503 +1486 1482 -36666988.20464 +1487 1482 2702571.265064 +1494 1482 -52678594.23377 +1495 1482 -36666666.66064 +1496 1482 2505785.158418 +1497 1482 -140008022.8906 +1498 1482 2.577900886536e-06 +1499 1482 -462970.4754454 +1500 1482 -52702268.47617 +1501 1482 36666666.66064 +1502 1482 -2702548.174055 +1578 1482 -18391419.7975 +1579 1482 9166666.669678 +1580 1482 10018981.01522 +1581 1482 -71369389.94283 +1582 1482 -9166787.24867 +1583 1482 42147892.99313 +1590 1482 -413319.0876746 +1591 1482 3.017485141754e-06 +1592 1482 57871.30948708 +1593 1482 76553135.92261 +1594 1482 9166867.634673 +1595 1482 781226.2244361 +1596 1482 -18699525.19313 +1597 1482 -9166747.055676 +1598 1482 11379035.3452 +1605 1482 -18482764.4945 +1606 1482 -9166666.669676 +1607 1482 -10076852.32471 +1608 1482 -59172122.54065 +1609 1482 4.395842552185e-07 +1610 1482 -42928937.05631 +1611 1482 -19947608.24497 +1612 1482 9166666.669675 +1613 1482 -11378935.65847 +1483 1483 566847200.4901 +1484 1483 -8610909.306622 +1485 1483 -36667148.97663 +1486 1483 -110262538.3357 +1487 1483 4611016.915367 +1494 1483 -36666666.66065 +1495 1483 -41677781.0706 +1496 1483 1263866.351621 +1497 1483 2.831220626831e-06 +1498 1483 21326659.08566 +1499 1483 -2777732.703214 +1500 1483 36666666.66064 +1501 1483 -41701455.31301 +1502 1483 1513866.351594 +1578 1483 9166666.669678 +1579 1483 -15641216.50536 +1580 1483 -8177088.970282 +1581 1483 -9166747.055672 +1582 1483 -28285264.92641 +1583 1483 7788270.809731 +1590 1483 4.06801700592e-06 +1591 1483 -35246583.02275 +1592 1483 -32861133.64276 +1593 1483 9166867.634673 +1594 1483 51801215.86321 +1595 1483 -2152764.494718 +1596 1483 -9166787.248675 +1597 1483 -50782746.60544 +1598 1483 35402941.77273 +1605 1483 -9166666.669676 +1606 1483 -15732561.20235 +1607 1483 -8246533.414749 +1608 1483 4.619359970093e-07 +1609 1483 -18838452.02672 +1610 1483 -694433.1761459 +1611 1483 9166666.669675 +1612 1483 -17197404.95283 +1613 1483 8940966.590895 +1484 1484 591261848.0956 +1485 1484 2737305.032771 +1486 1484 5388803.421584 +1487 1484 33925571.74906 +1494 1484 2471062.936219 +1495 1484 1236088.573861 +1496 1484 -8882157.948759 +1497 1484 -462970.4754449 +1498 1484 -2777732.703214 +1499 1484 35690216.05203 +1500 1484 -2737270.396254 +1501 1484 1541644.129353 +1502 1484 -8945289.261872 +1578 1484 10018981.01522 +1579 1484 -8177088.970282 +1580 1484 -16145262.77514 +1581 1484 42113167.97979 +1582 1484 7593861.729456 +1583 1484 -55157692.73435 +1590 1484 57871.30948763 +1591 1484 -32833355.865 +1592 1484 -37566373.58606 +1593 1484 781320.0962051 +1594 1484 -2152689.398522 +1595 1484 -91946096.11431 +1596 1484 11379085.18856 +1597 1484 35569610.71641 +1598 1484 -53430905.74636 +1605 1484 -10076852.32471 +1606 1484 -8246533.414749 +1607 1484 -16388848.63381 +1608 1484 -42894214.83411 +1609 1484 -694433.1761459 +1610 1484 -55531090.78464 +1611 1484 -11378935.65847 +1612 1484 8940966.590895 +1613 1484 -20295098.63508 +1485 1485 383498024.544 +1486 1485 36666666.66064 +1487 1485 2662179.892796 +1497 1485 -52678594.23377 +1498 1485 -36666666.66064 +1499 1485 2505785.158418 +1500 1485 -204675200.5845 +1501 1485 -36666988.20463 +1502 1485 -2662156.039165 +1503 1485 11810466.31493 +1504 1485 29333654.8725 +1505 1485 -2152800.8684 +1581 1485 -4579449.609996 +1582 1485 11000120.58261 +1583 1485 12057631.64322 +1593 1485 -14225493.76444 +1594 1485 -9166787.248675 +1595 1485 -10019112.65448 +1596 1485 35932670.30059 +1597 1485 9166666.669679 +1598 1485 9311563.653784 +1608 1485 -18482764.4945 +1609 1485 -9166666.669676 +1610 1485 -10076852.32471 +1611 1485 -72925641.46158 +1612 1485 -9166747.055676 +1613 1485 -43478968.03166 +1614 1485 -7497354.851903 +1615 1485 7333413.72174 +1616 1485 -9080099.689708 +1486 1486 328493596.9861 +1487 1486 -6944376.43401 +1497 1486 -36666666.66065 +1498 1486 -41677781.0706 +1499 1486 1263866.351621 +1500 1486 -36667148.97662 +1501 1486 -32338700.60373 +1502 1486 -3847226.785359 +1503 1486 44000482.30876 +1504 1486 11810466.31493 +1505 1486 2416693.76713 +1581 1486 7333413.72174 +1582 1486 -4579449.61 +1583 1486 -6430626.286135 +1593 1486 -9166747.055675 +1594 1486 -46308715.17675 +1595 1486 -32902986.62891 +1596 1486 9166666.669678 +1597 1486 22181563.40434 +1598 1486 5180609.664774 +1608 1486 -9166666.669676 +1609 1486 -15732561.20235 +1610 1486 -8246533.414749 +1611 1486 -9166787.248676 +1612 1486 -29841516.44517 +1613 1486 -9524419.110191 +1614 1486 11000120.58261 +1615 1486 -7497354.8519 +1616 1486 10895952.52268 +1487 1487 364686604.8413 +1497 1487 2471062.936219 +1498 1487 1236088.573861 +1499 1487 -8882157.948759 +1500 1487 -2662144.112346 +1501 1487 -3097217.751863 +1502 1487 -5157813.372203 +1503 1487 -3229201.302601 +1504 1487 1611129.178087 +1505 1487 31494576.83983 +1581 1487 8038421.095477 +1582 1487 -9645939.429201 +1583 1487 -12211865.62666 +1593 1487 -10019068.77473 +1594 1487 -33069655.68813 +1595 1487 -41500155.26984 +1596 1487 -7806863.548506 +1597 1487 -8513909.758068 +1598 1487 -68673244.4318 +1608 1487 -10076852.32471 +1609 1487 -8246533.414749 +1610 1487 -16388848.63381 +1611 1487 -43444243.01831 +1612 1487 -9329934.937092 +1613 1487 -59307696.78438 +1614 1487 -13620149.53456 +1615 1487 7263968.348454 +1616 1487 -19992946.27174 +1488 1488 613328698.917 +1489 1488 1.621246337891e-05 +1490 1488 925940.9508365 +1491 1488 82577683.23799 +1492 1488 -7.659196853638e-06 +1493 1488 231485.2378237 +1506 1488 -140008022.8906 +1507 1488 2.577900886536e-06 +1508 1488 -462970.4754454 +1509 1488 -52702268.47617 +1510 1488 36666666.66064 +1511 1488 -2702548.174055 +1584 1488 -58783069.51046 +1585 1488 1.639127731323e-06 +1586 1488 42697451.81849 +1587 1488 -19844426.42677 +1588 1488 -9166666.669679 +1589 1488 11321064.34898 +1599 1488 57430602.85087 +1600 1488 3.8743019104e-06 +1601 1488 231485.2378496 +1602 1488 -6249019.844286 +1603 1488 -7.443130016327e-06 +1604 1488 57871.30949415 +1617 1488 -59172122.54065 +1618 1488 4.395842552185e-07 +1619 1488 -42928937.05631 +1620 1488 -19947608.24497 +1621 1488 9166666.669675 +1622 1488 -11378935.65847 +1489 1489 525322193.6551 +1490 1489 -11110930.80738 +1491 1489 -7.525086402893e-06 +1492 1489 -56755372.43366 +1493 1489 5555465.403692 +1506 1489 2.831220626831e-06 +1507 1489 21326659.08566 +1508 1489 -2777732.703214 +1509 1489 36666666.66064 +1510 1489 -41701455.31301 +1511 1489 1513866.351594 +1584 1489 6.034970283508e-07 +1585 1489 -18449398.9965 +1586 1489 -694433.1761458 +1587 1489 -9166666.669679 +1588 1489 -17094223.13462 +1589 1489 8871522.146427 +1599 1489 4.231929779053e-06 +1600 1489 35428976.52455 +1601 1489 -2777732.703215 +1602 1489 -7.599592208862e-06 +1603 1489 -41082283.77936 +1604 1489 35638866.34597 +1617 1489 4.619359970093e-07 +1618 1489 -18838452.02672 +1619 1489 -694433.1761459 +1620 1489 9166666.669675 +1621 1489 -17197404.95283 +1622 1489 8940966.590895 +1490 1490 582790450.9006 +1491 1490 231485.2378239 +1492 1490 5555465.403692 +1493 1490 74350397.96411 +1506 1490 -462970.4754449 +1507 1490 -2777732.703214 +1508 1490 35690216.05203 +1509 1490 -2737270.396254 +1510 1490 1541644.129353 +1511 1490 -8945289.261872 +1584 1490 42662729.59629 +1585 1490 -694433.1761458 +1586 1490 -54493616.03735 +1587 1490 11321064.34898 +1588 1490 8871522.146428 +1589 1490 -20019947.11985 +1599 1490 231485.2378493 +1600 1490 -2777732.703215 +1601 1490 -110039912.4136 +1602 1490 57871.30949473 +1603 1490 35611088.56821 +1604 1490 -53128242.27036 +1617 1490 -42894214.83411 +1618 1490 -694433.1761459 +1619 1490 -55531090.78464 +1620 1490 -11378935.65847 +1621 1490 8940966.590895 +1622 1490 -20295098.63508 +1491 1491 613328698.917 +1492 1491 1.621246337891e-05 +1493 1491 925940.9508365 +1494 1491 82577683.23799 +1495 1491 -7.659196853638e-06 +1496 1491 231485.2378237 +1506 1491 -52678594.23377 +1507 1491 -36666666.66064 +1508 1491 2505785.158418 +1509 1491 -140008022.8906 +1510 1491 2.577900886536e-06 +1511 1491 -462970.4754454 +1512 1491 -52702268.47617 +1513 1491 36666666.66064 +1514 1491 -2702548.174055 +1584 1491 -18391419.7975 +1585 1491 9166666.669678 +1586 1491 10018981.01522 +1587 1491 -58783069.51046 +1588 1491 1.639127731323e-06 +1589 1491 42697451.81849 +1590 1491 -19844426.42677 +1591 1491 -9166666.669679 +1592 1491 11321064.34898 +1599 1491 -413319.0876746 +1600 1491 3.017485141754e-06 +1601 1491 57871.30948708 +1602 1491 57430602.85087 +1603 1491 3.8743019104e-06 +1604 1491 231485.2378496 +1605 1491 -6249019.844286 +1606 1491 -7.443130016327e-06 +1607 1491 57871.30949415 +1617 1491 -18482764.4945 +1618 1491 -9166666.669676 +1619 1491 -10076852.32471 +1620 1491 -59172122.54065 +1621 1491 4.395842552185e-07 +1622 1491 -42928937.05631 +1623 1491 -19947608.24497 +1624 1491 9166666.669675 +1625 1491 -11378935.65847 +1492 1492 525322193.6551 +1493 1492 -11110930.80738 +1494 1492 -7.525086402893e-06 +1495 1492 -56755372.43366 +1496 1492 5555465.403692 +1506 1492 -36666666.66065 +1507 1492 -41677781.0706 +1508 1492 1263866.351621 +1509 1492 2.831220626831e-06 +1510 1492 21326659.08566 +1511 1492 -2777732.703214 +1512 1492 36666666.66064 +1513 1492 -41701455.31301 +1514 1492 1513866.351594 +1584 1492 9166666.669678 +1585 1492 -15641216.50536 +1586 1492 -8177088.970282 +1587 1492 6.034970283508e-07 +1588 1492 -18449398.9965 +1589 1492 -694433.1761458 +1590 1492 -9166666.669679 +1591 1492 -17094223.13462 +1592 1492 8871522.146427 +1599 1492 4.06801700592e-06 +1600 1492 -35246583.02275 +1601 1492 -32861133.64276 +1602 1492 4.231929779053e-06 +1603 1492 35428976.52455 +1604 1492 -2777732.703215 +1605 1492 -7.599592208862e-06 +1606 1492 -41082283.77936 +1607 1492 35638866.34597 +1617 1492 -9166666.669676 +1618 1492 -15732561.20235 +1619 1492 -8246533.414749 +1620 1492 4.619359970093e-07 +1621 1492 -18838452.02672 +1622 1492 -694433.1761459 +1623 1492 9166666.669675 +1624 1492 -17197404.95283 +1625 1492 8940966.590895 +1493 1493 582790450.9006 +1494 1493 231485.2378239 +1495 1493 5555465.403692 +1496 1493 74350397.96411 +1506 1493 2471062.936219 +1507 1493 1236088.573861 +1508 1493 -8882157.948759 +1509 1493 -462970.4754449 +1510 1493 -2777732.703214 +1511 1493 35690216.05203 +1512 1493 -2737270.396254 +1513 1493 1541644.129353 +1514 1493 -8945289.261872 +1584 1493 10018981.01522 +1585 1493 -8177088.970282 +1586 1493 -16145262.77514 +1587 1493 42662729.59629 +1588 1493 -694433.1761458 +1589 1493 -54493616.03735 +1590 1493 11321064.34898 +1591 1493 8871522.146428 +1592 1493 -20019947.11985 +1599 1493 57871.30948763 +1600 1493 -32833355.865 +1601 1493 -37566373.58606 +1602 1493 231485.2378493 +1603 1493 -2777732.703215 +1604 1493 -110039912.4136 +1605 1493 57871.30949473 +1606 1493 35611088.56821 +1607 1493 -53128242.27036 +1617 1493 -10076852.32471 +1618 1493 -8246533.414749 +1619 1493 -16388848.63381 +1620 1493 -42894214.83411 +1621 1493 -694433.1761459 +1622 1493 -55531090.78464 +1623 1493 -11378935.65847 +1624 1493 8940966.590895 +1625 1493 -20295098.63508 +1494 1494 613328698.917 +1495 1494 1.621246337891e-05 +1496 1494 925940.9508365 +1497 1494 82577683.23799 +1498 1494 -7.659196853638e-06 +1499 1494 231485.2378237 +1509 1494 -52678594.23377 +1510 1494 -36666666.66064 +1511 1494 2505785.158418 +1512 1494 -140008022.8906 +1513 1494 2.577900886536e-06 +1514 1494 -462970.4754454 +1515 1494 -52702268.47617 +1516 1494 36666666.66064 +1517 1494 -2702548.174055 +1587 1494 -18391419.7975 +1588 1494 9166666.669678 +1589 1494 10018981.01522 +1590 1494 -58783069.51046 +1591 1494 1.639127731323e-06 +1592 1494 42697451.81849 +1593 1494 -19844426.42677 +1594 1494 -9166666.669679 +1595 1494 11321064.34898 +1602 1494 -413319.0876746 +1603 1494 3.017485141754e-06 +1604 1494 57871.30948708 +1605 1494 57430602.85087 +1606 1494 3.8743019104e-06 +1607 1494 231485.2378496 +1608 1494 -6249019.844286 +1609 1494 -7.443130016327e-06 +1610 1494 57871.30949415 +1620 1494 -18482764.4945 +1621 1494 -9166666.669676 +1622 1494 -10076852.32471 +1623 1494 -59172122.54065 +1624 1494 4.395842552185e-07 +1625 1494 -42928937.05631 +1626 1494 -19947608.24497 +1627 1494 9166666.669675 +1628 1494 -11378935.65847 +1495 1495 525322193.6551 +1496 1495 -11110930.80738 +1497 1495 -7.525086402893e-06 +1498 1495 -56755372.43366 +1499 1495 5555465.403692 +1509 1495 -36666666.66065 +1510 1495 -41677781.0706 +1511 1495 1263866.351621 +1512 1495 2.831220626831e-06 +1513 1495 21326659.08566 +1514 1495 -2777732.703214 +1515 1495 36666666.66064 +1516 1495 -41701455.31301 +1517 1495 1513866.351594 +1587 1495 9166666.669678 +1588 1495 -15641216.50536 +1589 1495 -8177088.970282 +1590 1495 6.034970283508e-07 +1591 1495 -18449398.9965 +1592 1495 -694433.1761458 +1593 1495 -9166666.669679 +1594 1495 -17094223.13462 +1595 1495 8871522.146427 +1602 1495 4.06801700592e-06 +1603 1495 -35246583.02275 +1604 1495 -32861133.64276 +1605 1495 4.231929779053e-06 +1606 1495 35428976.52455 +1607 1495 -2777732.703215 +1608 1495 -7.599592208862e-06 +1609 1495 -41082283.77936 +1610 1495 35638866.34597 +1620 1495 -9166666.669676 +1621 1495 -15732561.20235 +1622 1495 -8246533.414749 +1623 1495 4.619359970093e-07 +1624 1495 -18838452.02672 +1625 1495 -694433.1761459 +1626 1495 9166666.669675 +1627 1495 -17197404.95283 +1628 1495 8940966.590895 +1496 1496 582790450.9006 +1497 1496 231485.2378239 +1498 1496 5555465.403692 +1499 1496 74350397.96411 +1509 1496 2471062.936219 +1510 1496 1236088.573861 +1511 1496 -8882157.948759 +1512 1496 -462970.4754449 +1513 1496 -2777732.703214 +1514 1496 35690216.05203 +1515 1496 -2737270.396254 +1516 1496 1541644.129353 +1517 1496 -8945289.261872 +1587 1496 10018981.01522 +1588 1496 -8177088.970282 +1589 1496 -16145262.77514 +1590 1496 42662729.59629 +1591 1496 -694433.1761458 +1592 1496 -54493616.03735 +1593 1496 11321064.34898 +1594 1496 8871522.146428 +1595 1496 -20019947.11985 +1602 1496 57871.30948763 +1603 1496 -32833355.865 +1604 1496 -37566373.58606 +1605 1496 231485.2378493 +1606 1496 -2777732.703215 +1607 1496 -110039912.4136 +1608 1496 57871.30949473 +1609 1496 35611088.56821 +1610 1496 -53128242.27036 +1620 1496 -10076852.32471 +1621 1496 -8246533.414749 +1622 1496 -16388848.63381 +1623 1496 -42894214.83411 +1624 1496 -694433.1761459 +1625 1496 -55531090.78464 +1626 1496 -11378935.65847 +1627 1496 8940966.590895 +1628 1496 -20295098.63508 +1497 1497 613328698.917 +1498 1497 1.621246337891e-05 +1499 1497 925940.9508365 +1500 1497 82577683.23799 +1501 1497 -7.659196853638e-06 +1502 1497 231485.2378237 +1512 1497 -52678594.23377 +1513 1497 -36666666.66064 +1514 1497 2505785.158418 +1515 1497 -140008022.8906 +1516 1497 2.577900886536e-06 +1517 1497 -462970.4754454 +1518 1497 -52702268.47617 +1519 1497 36666666.66064 +1520 1497 -2702548.174055 +1590 1497 -18391419.7975 +1591 1497 9166666.669678 +1592 1497 10018981.01522 +1593 1497 -58783069.51046 +1594 1497 1.639127731323e-06 +1595 1497 42697451.81849 +1596 1497 -19844426.42677 +1597 1497 -9166666.669679 +1598 1497 11321064.34898 +1605 1497 -413319.0876746 +1606 1497 3.017485141754e-06 +1607 1497 57871.30948708 +1608 1497 57430602.85087 +1609 1497 3.8743019104e-06 +1610 1497 231485.2378496 +1611 1497 -6249019.844286 +1612 1497 -7.443130016327e-06 +1613 1497 57871.30949415 +1623 1497 -18482764.4945 +1624 1497 -9166666.669676 +1625 1497 -10076852.32471 +1626 1497 -59172122.54065 +1627 1497 4.395842552185e-07 +1628 1497 -42928937.05631 +1629 1497 -19947608.24497 +1630 1497 9166666.669675 +1631 1497 -11378935.65847 +1498 1498 525322193.6551 +1499 1498 -11110930.80738 +1500 1498 -7.525086402893e-06 +1501 1498 -56755372.43366 +1502 1498 5555465.403692 +1512 1498 -36666666.66065 +1513 1498 -41677781.0706 +1514 1498 1263866.351621 +1515 1498 2.831220626831e-06 +1516 1498 21326659.08566 +1517 1498 -2777732.703214 +1518 1498 36666666.66064 +1519 1498 -41701455.31301 +1520 1498 1513866.351594 +1590 1498 9166666.669678 +1591 1498 -15641216.50536 +1592 1498 -8177088.970282 +1593 1498 6.034970283508e-07 +1594 1498 -18449398.9965 +1595 1498 -694433.1761458 +1596 1498 -9166666.669679 +1597 1498 -17094223.13462 +1598 1498 8871522.146427 +1605 1498 4.06801700592e-06 +1606 1498 -35246583.02275 +1607 1498 -32861133.64276 +1608 1498 4.231929779053e-06 +1609 1498 35428976.52455 +1610 1498 -2777732.703215 +1611 1498 -7.599592208862e-06 +1612 1498 -41082283.77936 +1613 1498 35638866.34597 +1623 1498 -9166666.669676 +1624 1498 -15732561.20235 +1625 1498 -8246533.414749 +1626 1498 4.619359970093e-07 +1627 1498 -18838452.02672 +1628 1498 -694433.1761459 +1629 1498 9166666.669675 +1630 1498 -17197404.95283 +1631 1498 8940966.590895 +1499 1499 582790450.9006 +1500 1499 231485.2378239 +1501 1499 5555465.403692 +1502 1499 74350397.96411 +1512 1499 2471062.936219 +1513 1499 1236088.573861 +1514 1499 -8882157.948759 +1515 1499 -462970.4754449 +1516 1499 -2777732.703214 +1517 1499 35690216.05203 +1518 1499 -2737270.396254 +1519 1499 1541644.129353 +1520 1499 -8945289.261872 +1590 1499 10018981.01522 +1591 1499 -8177088.970282 +1592 1499 -16145262.77514 +1593 1499 42662729.59629 +1594 1499 -694433.1761458 +1595 1499 -54493616.03735 +1596 1499 11321064.34898 +1597 1499 8871522.146428 +1598 1499 -20019947.11985 +1605 1499 57871.30948763 +1606 1499 -32833355.865 +1607 1499 -37566373.58606 +1608 1499 231485.2378493 +1609 1499 -2777732.703215 +1610 1499 -110039912.4136 +1611 1499 57871.30949473 +1612 1499 35611088.56821 +1613 1499 -53128242.27036 +1623 1499 -10076852.32471 +1624 1499 -8246533.414749 +1625 1499 -16388848.63381 +1626 1499 -42894214.83411 +1627 1499 -694433.1761459 +1628 1499 -55531090.78464 +1629 1499 -11378935.65847 +1630 1499 8940966.590895 +1631 1499 -20295098.63508 +1500 1500 665854880.679 +1501 1500 36667470.52063 +1502 1500 3125090.734117 +1503 1500 18070347.2503 +1504 1500 -36666988.20464 +1505 1500 2702571.265064 +1515 1500 -52678594.23377 +1516 1500 -36666666.66064 +1517 1500 2505785.158418 +1518 1500 -140008022.8906 +1519 1500 2.577900886536e-06 +1520 1500 -462970.4754454 +1521 1500 -52702268.47617 +1522 1500 36666666.66064 +1523 1500 -2702548.174055 +1593 1500 -18391419.7975 +1594 1500 9166666.669678 +1595 1500 10018981.01522 +1596 1500 -71369389.94283 +1597 1500 -9166787.24867 +1598 1500 42147892.99313 +1608 1500 -413319.0876746 +1609 1500 3.017485141754e-06 +1610 1500 57871.30948708 +1611 1500 76553135.92261 +1612 1500 9166867.634673 +1613 1500 781226.2244361 +1614 1500 -18699525.19313 +1615 1500 -9166747.055676 +1616 1500 11379035.3452 +1626 1500 -18482764.4945 +1627 1500 -9166666.669676 +1628 1500 -10076852.32471 +1629 1500 -59172122.54065 +1630 1500 4.395842552185e-07 +1631 1500 -42928937.05631 +1632 1500 -19947608.24497 +1633 1500 9166666.669675 +1634 1500 -11378935.65847 +1501 1501 566847200.4901 +1502 1501 -8610909.306622 +1503 1501 -36667148.97663 +1504 1501 -110262538.3357 +1505 1501 4611016.915367 +1515 1501 -36666666.66065 +1516 1501 -41677781.0706 +1517 1501 1263866.351621 +1518 1501 2.831220626831e-06 +1519 1501 21326659.08566 +1520 1501 -2777732.703214 +1521 1501 36666666.66064 +1522 1501 -41701455.31301 +1523 1501 1513866.351594 +1593 1501 9166666.669678 +1594 1501 -15641216.50536 +1595 1501 -8177088.970282 +1596 1501 -9166747.055672 +1597 1501 -28285264.92641 +1598 1501 7788270.809731 +1608 1501 4.06801700592e-06 +1609 1501 -35246583.02275 +1610 1501 -32861133.64276 +1611 1501 9166867.634673 +1612 1501 51801215.86321 +1613 1501 -2152764.494718 +1614 1501 -9166787.248675 +1615 1501 -50782746.60544 +1616 1501 35402941.77273 +1626 1501 -9166666.669676 +1627 1501 -15732561.20235 +1628 1501 -8246533.414749 +1629 1501 4.619359970093e-07 +1630 1501 -18838452.02672 +1631 1501 -694433.1761459 +1632 1501 9166666.669675 +1633 1501 -17197404.95283 +1634 1501 8940966.590895 +1502 1502 591261848.0956 +1503 1502 2737305.032771 +1504 1502 5388803.421584 +1505 1502 33925571.74906 +1515 1502 2471062.936219 +1516 1502 1236088.573861 +1517 1502 -8882157.948759 +1518 1502 -462970.4754449 +1519 1502 -2777732.703214 +1520 1502 35690216.05203 +1521 1502 -2737270.396254 +1522 1502 1541644.129353 +1523 1502 -8945289.261872 +1593 1502 10018981.01522 +1594 1502 -8177088.970282 +1595 1502 -16145262.77514 +1596 1502 42113167.97979 +1597 1502 7593861.729456 +1598 1502 -55157692.73435 +1608 1502 57871.30948763 +1609 1502 -32833355.865 +1610 1502 -37566373.58606 +1611 1502 781320.0962051 +1612 1502 -2152689.398522 +1613 1502 -91946096.11431 +1614 1502 11379085.18856 +1615 1502 35569610.71641 +1616 1502 -53430905.74636 +1626 1502 -10076852.32471 +1627 1502 -8246533.414749 +1628 1502 -16388848.63381 +1629 1502 -42894214.83411 +1630 1502 -694433.1761459 +1631 1502 -55531090.78464 +1632 1502 -11378935.65847 +1633 1502 8940966.590895 +1634 1502 -20295098.63508 +1503 1503 826502950.7467 +1504 1503 -32829142.2168 +1505 1503 -1574339.432285 +1518 1503 -52678594.23377 +1519 1503 -36666666.66064 +1520 1503 2505785.158418 +1521 1503 -43717734.4447 +1522 1503 32816830.06734 +1523 1503 -231059.6481135 +1524 1503 -637569397.5693 +1525 1503 29345645.47798 +1526 1503 -416821.6161519 +1596 1503 -4579449.609996 +1597 1503 11000120.58261 +1598 1503 12057631.64322 +1611 1503 -14225493.76444 +1612 1503 -9166787.248675 +1613 1503 -10019112.65448 +1614 1503 163714858.8002 +1615 1503 -8207285.558244 +1616 1503 4241855.317219 +1629 1503 -18482764.4945 +1630 1503 -9166666.669676 +1631 1503 -10076852.32471 +1632 1503 -23632031.88637 +1633 1503 8204207.520878 +1634 1503 -22609970.36319 +1635 1503 -160108670.9846 +1636 1503 7336411.37311 +1637 1503 -520782.4807296 +1504 1504 1866175254.747 +1505 1504 -20243144.64085 +1518 1504 -36666666.66065 +1519 1504 -41677781.0706 +1520 1504 1263866.351621 +1521 1504 32810673.99266 +1522 1504 97413180.27061 +1523 1504 -1903194.680072 +1524 1504 44018468.21692 +1525 1504 -1701040543.862 +1526 1504 13714990.87775 +1596 1504 7333413.72174 +1597 1504 -4579449.61 +1598 1504 -6430626.286135 +1611 1504 -9166747.055675 +1612 1504 -46308715.17675 +1613 1504 -32902986.62891 +1614 1504 -8207285.558244 +1615 1504 423632934.9284 +1616 1504 -1353225.115187 +1629 1504 -9166666.669676 +1630 1504 -15732561.20235 +1631 1504 -8246533.414749 +1632 1504 8202668.502206 +1633 1504 11650696.80984 +1634 1504 7172753.555873 +1635 1504 11004617.05965 +1636 1504 -425976457.6889 +1637 1504 20227336.59943 +1505 1505 856594529.5136 +1518 1505 2471062.936219 +1519 1505 1236088.573861 +1520 1505 -8882157.948759 +1521 1505 -1133759.188307 +1522 1505 -1875517.295844 +1523 1505 50029495.24259 +1524 1505 -625232.4242272 +1525 1505 13603538.44251 +1526 1505 -636713913.8918 +1596 1505 8038421.095477 +1597 1505 -9645939.429201 +1598 1505 -12211865.62666 +1611 1505 -10019068.77473 +1612 1505 -33069655.68813 +1613 1505 -41500155.26984 +1614 1505 -4768610.272799 +1615 1505 -8558910.345734 +1616 1505 99719621.84851 +1629 1505 -10076852.32471 +1630 1505 -8246533.414749 +1631 1505 -16388848.63381 +1632 1505 -22783562.29616 +1633 1505 7202053.220155 +1634 1505 -21366221.56937 +1635 1505 -781173.7210934 +1636 1505 20019063.72315 +1637 1505 -161088669.2548 +1506 1506 613328698.917 +1507 1506 1.621246337891e-05 +1508 1506 925940.9508365 +1509 1506 82577683.23799 +1510 1506 -7.659196853638e-06 +1511 1506 231485.2378237 +1527 1506 -140008022.8906 +1528 1506 2.577900886536e-06 +1529 1506 -462970.4754454 +1530 1506 -52702268.47617 +1531 1506 36666666.66064 +1532 1506 -2702548.174055 +1599 1506 -58783069.51046 +1600 1506 1.639127731323e-06 +1601 1506 42697451.81849 +1602 1506 -19844426.42677 +1603 1506 -9166666.669679 +1604 1506 11321064.34898 +1617 1506 57430602.85087 +1618 1506 3.8743019104e-06 +1619 1506 231485.2378496 +1620 1506 -6249019.844286 +1621 1506 -7.443130016327e-06 +1622 1506 57871.30949415 +1638 1506 -59172122.54065 +1639 1506 4.395842552185e-07 +1640 1506 -42928937.05631 +1641 1506 -19947608.24497 +1642 1506 9166666.669675 +1643 1506 -11378935.65847 +1507 1507 525322193.6551 +1508 1507 -11110930.80738 +1509 1507 -7.525086402893e-06 +1510 1507 -56755372.43366 +1511 1507 5555465.403692 +1527 1507 2.831220626831e-06 +1528 1507 21326659.08566 +1529 1507 -2777732.703214 +1530 1507 36666666.66064 +1531 1507 -41701455.31301 +1532 1507 1513866.351594 +1599 1507 6.034970283508e-07 +1600 1507 -18449398.9965 +1601 1507 -694433.1761458 +1602 1507 -9166666.669679 +1603 1507 -17094223.13462 +1604 1507 8871522.146427 +1617 1507 4.231929779053e-06 +1618 1507 35428976.52455 +1619 1507 -2777732.703215 +1620 1507 -7.599592208862e-06 +1621 1507 -41082283.77936 +1622 1507 35638866.34597 +1638 1507 4.619359970093e-07 +1639 1507 -18838452.02672 +1640 1507 -694433.1761459 +1641 1507 9166666.669675 +1642 1507 -17197404.95283 +1643 1507 8940966.590895 +1508 1508 582790450.9006 +1509 1508 231485.2378239 +1510 1508 5555465.403692 +1511 1508 74350397.96411 +1527 1508 -462970.4754449 +1528 1508 -2777732.703214 +1529 1508 35690216.05203 +1530 1508 -2737270.396254 +1531 1508 1541644.129353 +1532 1508 -8945289.261872 +1599 1508 42662729.59629 +1600 1508 -694433.1761458 +1601 1508 -54493616.03735 +1602 1508 11321064.34898 +1603 1508 8871522.146428 +1604 1508 -20019947.11985 +1617 1508 231485.2378493 +1618 1508 -2777732.703215 +1619 1508 -110039912.4136 +1620 1508 57871.30949473 +1621 1508 35611088.56821 +1622 1508 -53128242.27036 +1638 1508 -42894214.83411 +1639 1508 -694433.1761459 +1640 1508 -55531090.78464 +1641 1508 -11378935.65847 +1642 1508 8940966.590895 +1643 1508 -20295098.63508 +1509 1509 613328698.917 +1510 1509 1.621246337891e-05 +1511 1509 925940.9508365 +1512 1509 82577683.23799 +1513 1509 -7.659196853638e-06 +1514 1509 231485.2378237 +1527 1509 -52678594.23377 +1528 1509 -36666666.66064 +1529 1509 2505785.158418 +1530 1509 -140008022.8906 +1531 1509 2.577900886536e-06 +1532 1509 -462970.4754454 +1533 1509 -52702268.47617 +1534 1509 36666666.66064 +1535 1509 -2702548.174055 +1599 1509 -18391419.7975 +1600 1509 9166666.669678 +1601 1509 10018981.01522 +1602 1509 -58783069.51046 +1603 1509 1.639127731323e-06 +1604 1509 42697451.81849 +1605 1509 -19844426.42677 +1606 1509 -9166666.669679 +1607 1509 11321064.34898 +1617 1509 -413319.0876746 +1618 1509 3.017485141754e-06 +1619 1509 57871.30948708 +1620 1509 57430602.85087 +1621 1509 3.8743019104e-06 +1622 1509 231485.2378496 +1623 1509 -6249019.844286 +1624 1509 -7.443130016327e-06 +1625 1509 57871.30949415 +1638 1509 -18482764.4945 +1639 1509 -9166666.669676 +1640 1509 -10076852.32471 +1641 1509 -59172122.54065 +1642 1509 4.395842552185e-07 +1643 1509 -42928937.05631 +1644 1509 -19947608.24497 +1645 1509 9166666.669675 +1646 1509 -11378935.65847 +1510 1510 525322193.6551 +1511 1510 -11110930.80738 +1512 1510 -7.525086402893e-06 +1513 1510 -56755372.43366 +1514 1510 5555465.403692 +1527 1510 -36666666.66065 +1528 1510 -41677781.0706 +1529 1510 1263866.351621 +1530 1510 2.831220626831e-06 +1531 1510 21326659.08566 +1532 1510 -2777732.703214 +1533 1510 36666666.66064 +1534 1510 -41701455.31301 +1535 1510 1513866.351594 +1599 1510 9166666.669678 +1600 1510 -15641216.50536 +1601 1510 -8177088.970282 +1602 1510 6.034970283508e-07 +1603 1510 -18449398.9965 +1604 1510 -694433.1761458 +1605 1510 -9166666.669679 +1606 1510 -17094223.13462 +1607 1510 8871522.146427 +1617 1510 4.06801700592e-06 +1618 1510 -35246583.02275 +1619 1510 -32861133.64276 +1620 1510 4.231929779053e-06 +1621 1510 35428976.52455 +1622 1510 -2777732.703215 +1623 1510 -7.599592208862e-06 +1624 1510 -41082283.77936 +1625 1510 35638866.34597 +1638 1510 -9166666.669676 +1639 1510 -15732561.20235 +1640 1510 -8246533.414749 +1641 1510 4.619359970093e-07 +1642 1510 -18838452.02672 +1643 1510 -694433.1761459 +1644 1510 9166666.669675 +1645 1510 -17197404.95283 +1646 1510 8940966.590895 +1511 1511 582790450.9006 +1512 1511 231485.2378239 +1513 1511 5555465.403692 +1514 1511 74350397.96411 +1527 1511 2471062.936219 +1528 1511 1236088.573861 +1529 1511 -8882157.948759 +1530 1511 -462970.4754449 +1531 1511 -2777732.703214 +1532 1511 35690216.05203 +1533 1511 -2737270.396254 +1534 1511 1541644.129353 +1535 1511 -8945289.261872 +1599 1511 10018981.01522 +1600 1511 -8177088.970282 +1601 1511 -16145262.77514 +1602 1511 42662729.59629 +1603 1511 -694433.1761458 +1604 1511 -54493616.03735 +1605 1511 11321064.34898 +1606 1511 8871522.146428 +1607 1511 -20019947.11985 +1617 1511 57871.30948763 +1618 1511 -32833355.865 +1619 1511 -37566373.58606 +1620 1511 231485.2378493 +1621 1511 -2777732.703215 +1622 1511 -110039912.4136 +1623 1511 57871.30949473 +1624 1511 35611088.56821 +1625 1511 -53128242.27036 +1638 1511 -10076852.32471 +1639 1511 -8246533.414749 +1640 1511 -16388848.63381 +1641 1511 -42894214.83411 +1642 1511 -694433.1761459 +1643 1511 -55531090.78464 +1644 1511 -11378935.65847 +1645 1511 8940966.590895 +1646 1511 -20295098.63508 +1512 1512 613328698.917 +1513 1512 1.621246337891e-05 +1514 1512 925940.9508365 +1515 1512 82577683.23799 +1516 1512 -7.659196853638e-06 +1517 1512 231485.2378237 +1530 1512 -52678594.23377 +1531 1512 -36666666.66064 +1532 1512 2505785.158418 +1533 1512 -140008022.8906 +1534 1512 2.577900886536e-06 +1535 1512 -462970.4754454 +1536 1512 -52702268.47617 +1537 1512 36666666.66064 +1538 1512 -2702548.174055 +1602 1512 -18391419.7975 +1603 1512 9166666.669678 +1604 1512 10018981.01522 +1605 1512 -58783069.51046 +1606 1512 1.639127731323e-06 +1607 1512 42697451.81849 +1608 1512 -19844426.42677 +1609 1512 -9166666.669679 +1610 1512 11321064.34898 +1620 1512 -413319.0876746 +1621 1512 3.017485141754e-06 +1622 1512 57871.30948708 +1623 1512 57430602.85087 +1624 1512 3.8743019104e-06 +1625 1512 231485.2378496 +1626 1512 -6249019.844286 +1627 1512 -7.443130016327e-06 +1628 1512 57871.30949415 +1641 1512 -18482764.4945 +1642 1512 -9166666.669676 +1643 1512 -10076852.32471 +1644 1512 -59172122.54065 +1645 1512 4.395842552185e-07 +1646 1512 -42928937.05631 +1647 1512 -19947608.24497 +1648 1512 9166666.669675 +1649 1512 -11378935.65847 +1513 1513 525322193.6551 +1514 1513 -11110930.80738 +1515 1513 -7.525086402893e-06 +1516 1513 -56755372.43366 +1517 1513 5555465.403692 +1530 1513 -36666666.66065 +1531 1513 -41677781.0706 +1532 1513 1263866.351621 +1533 1513 2.831220626831e-06 +1534 1513 21326659.08566 +1535 1513 -2777732.703214 +1536 1513 36666666.66064 +1537 1513 -41701455.31301 +1538 1513 1513866.351594 +1602 1513 9166666.669678 +1603 1513 -15641216.50536 +1604 1513 -8177088.970282 +1605 1513 6.034970283508e-07 +1606 1513 -18449398.9965 +1607 1513 -694433.1761458 +1608 1513 -9166666.669679 +1609 1513 -17094223.13462 +1610 1513 8871522.146427 +1620 1513 4.06801700592e-06 +1621 1513 -35246583.02275 +1622 1513 -32861133.64276 +1623 1513 4.231929779053e-06 +1624 1513 35428976.52455 +1625 1513 -2777732.703215 +1626 1513 -7.599592208862e-06 +1627 1513 -41082283.77936 +1628 1513 35638866.34597 +1641 1513 -9166666.669676 +1642 1513 -15732561.20235 +1643 1513 -8246533.414749 +1644 1513 4.619359970093e-07 +1645 1513 -18838452.02672 +1646 1513 -694433.1761459 +1647 1513 9166666.669675 +1648 1513 -17197404.95283 +1649 1513 8940966.590895 +1514 1514 582790450.9006 +1515 1514 231485.2378239 +1516 1514 5555465.403692 +1517 1514 74350397.96411 +1530 1514 2471062.936219 +1531 1514 1236088.573861 +1532 1514 -8882157.948759 +1533 1514 -462970.4754449 +1534 1514 -2777732.703214 +1535 1514 35690216.05203 +1536 1514 -2737270.396254 +1537 1514 1541644.129353 +1538 1514 -8945289.261872 +1602 1514 10018981.01522 +1603 1514 -8177088.970282 +1604 1514 -16145262.77514 +1605 1514 42662729.59629 +1606 1514 -694433.1761458 +1607 1514 -54493616.03735 +1608 1514 11321064.34898 +1609 1514 8871522.146428 +1610 1514 -20019947.11985 +1620 1514 57871.30948763 +1621 1514 -32833355.865 +1622 1514 -37566373.58606 +1623 1514 231485.2378493 +1624 1514 -2777732.703215 +1625 1514 -110039912.4136 +1626 1514 57871.30949473 +1627 1514 35611088.56821 +1628 1514 -53128242.27036 +1641 1514 -10076852.32471 +1642 1514 -8246533.414749 +1643 1514 -16388848.63381 +1644 1514 -42894214.83411 +1645 1514 -694433.1761459 +1646 1514 -55531090.78464 +1647 1514 -11378935.65847 +1648 1514 8940966.590895 +1649 1514 -20295098.63508 +1515 1515 613328698.917 +1516 1515 1.621246337891e-05 +1517 1515 925940.9508365 +1518 1515 82577683.23799 +1519 1515 -7.659196853638e-06 +1520 1515 231485.2378237 +1533 1515 -52678594.23377 +1534 1515 -36666666.66064 +1535 1515 2505785.158418 +1536 1515 -140008022.8906 +1537 1515 2.577900886536e-06 +1538 1515 -462970.4754454 +1539 1515 -52702268.47617 +1540 1515 36666666.66064 +1541 1515 -2702548.174055 +1605 1515 -18391419.7975 +1606 1515 9166666.669678 +1607 1515 10018981.01522 +1608 1515 -58783069.51046 +1609 1515 1.639127731323e-06 +1610 1515 42697451.81849 +1611 1515 -19844426.42677 +1612 1515 -9166666.669679 +1613 1515 11321064.34898 +1623 1515 -413319.0876746 +1624 1515 3.017485141754e-06 +1625 1515 57871.30948708 +1626 1515 57430602.85087 +1627 1515 3.8743019104e-06 +1628 1515 231485.2378496 +1629 1515 -6249019.844286 +1630 1515 -7.443130016327e-06 +1631 1515 57871.30949415 +1644 1515 -18482764.4945 +1645 1515 -9166666.669676 +1646 1515 -10076852.32471 +1647 1515 -59172122.54065 +1648 1515 4.395842552185e-07 +1649 1515 -42928937.05631 +1650 1515 -19947608.24497 +1651 1515 9166666.669675 +1652 1515 -11378935.65847 +1516 1516 525322193.6551 +1517 1516 -11110930.80738 +1518 1516 -7.525086402893e-06 +1519 1516 -56755372.43366 +1520 1516 5555465.403692 +1533 1516 -36666666.66065 +1534 1516 -41677781.0706 +1535 1516 1263866.351621 +1536 1516 2.831220626831e-06 +1537 1516 21326659.08566 +1538 1516 -2777732.703214 +1539 1516 36666666.66064 +1540 1516 -41701455.31301 +1541 1516 1513866.351594 +1605 1516 9166666.669678 +1606 1516 -15641216.50536 +1607 1516 -8177088.970282 +1608 1516 6.034970283508e-07 +1609 1516 -18449398.9965 +1610 1516 -694433.1761458 +1611 1516 -9166666.669679 +1612 1516 -17094223.13462 +1613 1516 8871522.146427 +1623 1516 4.06801700592e-06 +1624 1516 -35246583.02275 +1625 1516 -32861133.64276 +1626 1516 4.231929779053e-06 +1627 1516 35428976.52455 +1628 1516 -2777732.703215 +1629 1516 -7.599592208862e-06 +1630 1516 -41082283.77936 +1631 1516 35638866.34597 +1644 1516 -9166666.669676 +1645 1516 -15732561.20235 +1646 1516 -8246533.414749 +1647 1516 4.619359970093e-07 +1648 1516 -18838452.02672 +1649 1516 -694433.1761459 +1650 1516 9166666.669675 +1651 1516 -17197404.95283 +1652 1516 8940966.590895 +1517 1517 582790450.9006 +1518 1517 231485.2378239 +1519 1517 5555465.403692 +1520 1517 74350397.96411 +1533 1517 2471062.936219 +1534 1517 1236088.573861 +1535 1517 -8882157.948759 +1536 1517 -462970.4754449 +1537 1517 -2777732.703214 +1538 1517 35690216.05203 +1539 1517 -2737270.396254 +1540 1517 1541644.129353 +1541 1517 -8945289.261872 +1605 1517 10018981.01522 +1606 1517 -8177088.970282 +1607 1517 -16145262.77514 +1608 1517 42662729.59629 +1609 1517 -694433.1761458 +1610 1517 -54493616.03735 +1611 1517 11321064.34898 +1612 1517 8871522.146428 +1613 1517 -20019947.11985 +1623 1517 57871.30948763 +1624 1517 -32833355.865 +1625 1517 -37566373.58606 +1626 1517 231485.2378493 +1627 1517 -2777732.703215 +1628 1517 -110039912.4136 +1629 1517 57871.30949473 +1630 1517 35611088.56821 +1631 1517 -53128242.27036 +1644 1517 -10076852.32471 +1645 1517 -8246533.414749 +1646 1517 -16388848.63381 +1647 1517 -42894214.83411 +1648 1517 -694433.1761459 +1649 1517 -55531090.78464 +1650 1517 -11378935.65847 +1651 1517 8940966.590895 +1652 1517 -20295098.63508 +1518 1518 613328698.917 +1519 1518 1.621246337891e-05 +1520 1518 925940.9508365 +1521 1518 82577683.23799 +1522 1518 -7.659196853638e-06 +1523 1518 231485.2378237 +1536 1518 -52678594.23377 +1537 1518 -36666666.66064 +1538 1518 2505785.158418 +1539 1518 -140008022.8906 +1540 1518 2.577900886536e-06 +1541 1518 -462970.4754454 +1542 1518 -52702268.47617 +1543 1518 36666666.66064 +1544 1518 -2702548.174055 +1608 1518 -18391419.7975 +1609 1518 9166666.669678 +1610 1518 10018981.01522 +1611 1518 -58783069.51046 +1612 1518 1.639127731323e-06 +1613 1518 42697451.81849 +1614 1518 -19844426.42677 +1615 1518 -9166666.669679 +1616 1518 11321064.34898 +1626 1518 -413319.0876746 +1627 1518 3.017485141754e-06 +1628 1518 57871.30948708 +1629 1518 57430602.85087 +1630 1518 3.8743019104e-06 +1631 1518 231485.2378496 +1632 1518 -6249019.844286 +1633 1518 -7.443130016327e-06 +1634 1518 57871.30949415 +1647 1518 -18482764.4945 +1648 1518 -9166666.669676 +1649 1518 -10076852.32471 +1650 1518 -59172122.54065 +1651 1518 4.395842552185e-07 +1652 1518 -42928937.05631 +1653 1518 -19947608.24497 +1654 1518 9166666.669675 +1655 1518 -11378935.65847 +1519 1519 525322193.6551 +1520 1519 -11110930.80738 +1521 1519 -7.525086402893e-06 +1522 1519 -56755372.43366 +1523 1519 5555465.403692 +1536 1519 -36666666.66065 +1537 1519 -41677781.0706 +1538 1519 1263866.351621 +1539 1519 2.831220626831e-06 +1540 1519 21326659.08566 +1541 1519 -2777732.703214 +1542 1519 36666666.66064 +1543 1519 -41701455.31301 +1544 1519 1513866.351594 +1608 1519 9166666.669678 +1609 1519 -15641216.50536 +1610 1519 -8177088.970282 +1611 1519 6.034970283508e-07 +1612 1519 -18449398.9965 +1613 1519 -694433.1761458 +1614 1519 -9166666.669679 +1615 1519 -17094223.13462 +1616 1519 8871522.146427 +1626 1519 4.06801700592e-06 +1627 1519 -35246583.02275 +1628 1519 -32861133.64276 +1629 1519 4.231929779053e-06 +1630 1519 35428976.52455 +1631 1519 -2777732.703215 +1632 1519 -7.599592208862e-06 +1633 1519 -41082283.77936 +1634 1519 35638866.34597 +1647 1519 -9166666.669676 +1648 1519 -15732561.20235 +1649 1519 -8246533.414749 +1650 1519 4.619359970093e-07 +1651 1519 -18838452.02672 +1652 1519 -694433.1761459 +1653 1519 9166666.669675 +1654 1519 -17197404.95283 +1655 1519 8940966.590895 +1520 1520 582790450.9006 +1521 1520 231485.2378239 +1522 1520 5555465.403692 +1523 1520 74350397.96411 +1536 1520 2471062.936219 +1537 1520 1236088.573861 +1538 1520 -8882157.948759 +1539 1520 -462970.4754449 +1540 1520 -2777732.703214 +1541 1520 35690216.05203 +1542 1520 -2737270.396254 +1543 1520 1541644.129353 +1544 1520 -8945289.261872 +1608 1520 10018981.01522 +1609 1520 -8177088.970282 +1610 1520 -16145262.77514 +1611 1520 42662729.59629 +1612 1520 -694433.1761458 +1613 1520 -54493616.03735 +1614 1520 11321064.34898 +1615 1520 8871522.146428 +1616 1520 -20019947.11985 +1626 1520 57871.30948763 +1627 1520 -32833355.865 +1628 1520 -37566373.58606 +1629 1520 231485.2378493 +1630 1520 -2777732.703215 +1631 1520 -110039912.4136 +1632 1520 57871.30949473 +1633 1520 35611088.56821 +1634 1520 -53128242.27036 +1647 1520 -10076852.32471 +1648 1520 -8246533.414749 +1649 1520 -16388848.63381 +1650 1520 -42894214.83411 +1651 1520 -694433.1761459 +1652 1520 -55531090.78464 +1653 1520 -11378935.65847 +1654 1520 8940966.590895 +1655 1520 -20295098.63508 +1521 1521 519155644.6527 +1522 1521 19890209.72848 +1523 1521 546852.3808991 +1524 1521 -113344502.1932 +1525 1521 -81572741.71556 +1526 1521 807745.8307167 +1539 1521 -52678594.23377 +1540 1521 -36666666.66064 +1541 1521 2505785.158418 +1542 1521 -87908611.13882 +1543 1521 24575313.67981 +1544 1521 -99414.6025005 +1545 1521 -55777752.70527 +1546 1521 4296544.314628 +1547 1521 -121425.9460867 +1611 1521 -18391419.7975 +1612 1521 9166666.669678 +1613 1521 10018981.01522 +1614 1521 -23153309.42759 +1615 1521 8202668.502207 +1616 1521 22268765.65392 +1629 1521 -413319.0876746 +1630 1521 3.017485141754e-06 +1631 1521 57871.30948708 +1632 1521 68265937.74305 +1633 1521 4972552.434569 +1634 1521 136620.1412261 +1635 1521 -38378504.19399 +1636 1521 -20393185.43893 +1637 1521 10904728.81155 +1650 1521 -18482764.4945 +1651 1521 -9166666.669676 +1652 1521 -10076852.32471 +1653 1521 -43384348.52402 +1654 1521 6143828.422977 +1655 1521 -32706624.47957 +1656 1521 -20160575.07792 +1657 1521 1074136.079187 +1658 1521 -602925.9311655 +1522 1522 674296656.4325 +1523 1522 -8315854.013774 +1524 1522 -81578897.79024 +1525 1522 -277711399.8602 +1526 1522 1775953.352355 +1539 1522 -36666666.66065 +1540 1522 -41677781.0706 +1541 1522 1263866.351621 +1542 1522 24575313.67981 +1543 1522 6198641.247472 +1544 1522 -1140600.40519 +1545 1522 4296544.314628 +1546 1522 -164458604.5744 +1547 1522 1195041.228134 +1611 1522 9166666.669678 +1612 1522 -15641216.50536 +1613 1522 -8177088.970282 +1614 1522 8204207.520877 +1615 1522 12129419.26863 +1616 1522 -8118315.333891 +1629 1522 4.06801700592e-06 +1630 1522 -35246583.02275 +1631 1522 -32861133.64276 +1632 1522 4972552.434566 +1633 1522 107051190.7071 +1634 1522 -2079037.895958 +1635 1522 -20394724.45761 +1636 1522 -79470228.63097 +1637 1522 34698117.36652 +1650 1522 -9166666.669676 +1651 1522 -15732561.20235 +1652 1522 -8246533.414749 +1653 1522 6143828.422977 +1654 1522 -19857535.41586 +1655 1522 7819016.563107 +1656 1522 1074136.079187 +1657 1522 -47330788.05857 +1658 1522 16965426.97932 +1523 1523 500032615.4741 +1524 1523 842545.5277112 +1525 1523 1886963.445041 +1526 1523 -79462997.91567 +1539 1523 2471062.936219 +1540 1523 1236088.573861 +1541 1523 -8882157.948759 +1542 1523 -967470.1579145 +1543 1523 -1168378.182963 +1544 1523 37621796.60312 +1545 1523 -190870.3904854 +1546 1523 1195041.228134 +1547 1523 -43133554.29443 +1611 1523 10018981.01522 +1612 1523 -8177088.970282 +1613 1523 -16145262.77514 +1614 1523 22442357.5869 +1615 1523 -8144741.575046 +1616 1523 -20089628.3459 +1629 1523 57871.30948763 +1630 1523 -32833355.865 +1631 1523 -37566373.58606 +1632 1523 136807.9549443 +1633 1523 -2078887.551707 +1634 1523 -39053108.69402 +1635 1523 10904842.27205 +1636 1523 34696841.30973 +1637 1523 -46645425.83998 +1650 1523 -10076852.32471 +1651 1523 -8246533.414749 +1652 1523 -16388848.63381 +1653 1523 -32880235.58879 +1654 1523 7819016.564698 +1655 1523 -47680406.12059 +1656 1523 -602925.9311654 +1657 1523 16965426.97932 +1658 1523 -27359753.63154 +1524 1524 992997068.4552 +1525 1524 19284697.20432 +1526 1524 -396746.4756725 +1542 1524 -51863016.28236 +1543 1524 -31450303.98549 +1544 1524 319461.4773361 +1545 1524 43461620.04061 +1546 1524 42895217.91215 +1547 1524 -251152.4671109 +1548 1524 62501966.85689 +1549 1524 -21400415.93453 +1550 1524 21747.87620521 +1551 1524 -46253.50102974 +1552 1524 28231234.37687 +1553 1524 -49512.40302987 +1614 1524 -159624729.0253 +1615 1524 11004617.05965 +1616 1524 572723.0303333 +1632 1524 -37538860.21074 +1633 1524 -20394724.45761 +1634 1524 -10492248.91842 +1635 1524 145746193.545 +1636 1524 4821174.303457 +1637 1524 8338174.490712 +1653 1524 -18861959.6269 +1654 1524 -7862576.000248 +1655 1524 -10622738.80081 +1656 1524 -37300727.61412 +1657 1524 10723804.48332 +1658 1524 -41832926.99883 +1659 1524 -23212197.68204 +1660 1524 -5350103.986268 +1661 1524 14197971.68996 +1662 1524 -16690161.87378 +1663 1524 7057808.597695 +1664 1524 -10194843.38188 +1525 1525 2147947022.547 +1526 1525 -14974133.4238 +1542 1525 -31450303.98549 +1543 1525 -11693386.9132 +1544 1525 -131493.8517104 +1545 1525 42895217.91215 +1546 1525 170799253.6597 +1547 1525 -626470.3880802 +1548 1525 -6733749.270272 +1549 1525 -7855709.541271 +1550 1525 58407.27655116 +1551 1525 28231234.37687 +1552 1525 -24307750.22323 +1553 1525 72962.07354513 +1614 1525 7336411.373109 +1615 1525 -425492515.7295 +1616 1525 -13147629.82044 +1632 1525 -20393185.43894 +1633 1525 -78630584.64773 +1634 1525 -33781578.76871 +1635 1525 4821174.303456 +1636 1525 434483682.2102 +1637 1525 -3492649.630975 +1653 1525 -7862576.000248 +1654 1525 -8819552.279667 +1655 1525 -8595373.465755 +1656 1525 10723804.48332 +1657 1525 -5466319.193666 +1658 1525 7947549.067445 +1659 1525 -1683437.318397 +1660 1525 -40801616.79024 +1661 1525 33347935.147 +1662 1525 7057808.597695 +1663 1525 -22755536.05731 +1664 1525 16684907.19053 +1526 1526 1146795686.782 +1542 1526 284739.2551368 +1543 1526 -159271.6294699 +1544 1526 -378483.2995525 +1545 1526 -390041.3559778 +1546 1526 -654248.1658537 +1547 1526 194450799.0864 +1548 1526 -12974.3460083 +1549 1526 58407.27655098 +1550 1526 124613403.906 +1551 1526 -84234.62522937 +1552 1526 72962.07354511 +1553 1526 40395467.48366 +1614 1526 381815.353556 +1615 1526 -13300618.50896 +1616 1526 -159798157.3631 +1632 1526 -10492174.57703 +1633 1526 -33783025.80027 +1634 1526 -44406375.21794 +1635 1526 -8362936.617657 +1636 1526 -3856634.052932 +1637 1526 13357391.99385 +1653 1526 -10622738.80081 +1654 1526 -8595373.465755 +1655 1526 -15817835.62473 +1656 1526 -41832926.99887 +1657 1526 7947549.069036 +1658 1526 -79830320.55011 +1659 1526 6072971.68928 +1660 1526 33347935.147 +1661 1526 -72413820.75204 +1662 1526 -10194843.38188 +1663 1526 16684907.19053 +1664 1526 -34377395.78682 +1527 1527 306664349.4585 +1528 1527 7.62939453125e-06 +1529 1527 462970.475417 +1530 1527 41289236.1897 +1531 1527 7333333.332126 +1532 1527 -318285.1588368 +1617 1527 -58783069.51046 +1618 1527 1.639127731323e-06 +1619 1527 42697451.81849 +1620 1527 -19844426.42677 +1621 1527 -9166666.669679 +1622 1527 11321064.34898 +1638 1527 28714906.85473 +1639 1527 5.364418029785e-07 +1640 1527 -8530229.601834 +1641 1527 -3124509.92214 +1642 1527 1833333.333932 +1643 1527 -2241064.345998 +1528 1528 262661096.8276 +1529 1528 -5555465.403687 +1530 1528 -7333333.332131 +1531 1528 -28377291.64613 +1532 1528 2749954.924074 +1617 1528 6.034970283508e-07 +1618 1528 -18449398.9965 +1619 1528 -694433.1761458 +1620 1528 -9166666.669679 +1621 1528 -17094223.13462 +1622 1528 8871522.146427 +1638 1528 8.940696716309e-07 +1639 1528 17714093.69157 +1640 1528 -1388866.351609 +1641 1528 -1833333.333939 +1642 1528 -20541141.88968 +1643 1528 17812488.72854 +1529 1529 291395225.4503 +1530 1529 723381.5076579 +1531 1529 2805510.47962 +1532 1529 37176251.17061 +1617 1529 42662729.59629 +1618 1529 -694433.1761458 +1619 1529 -54493616.03735 +1620 1529 11321064.34898 +1621 1529 8871522.146428 +1622 1529 -20019947.11985 +1638 1529 8588103.728686 +1639 1529 -1388866.351609 +1640 1529 -55021008.39532 +1641 1529 2298935.655493 +1642 1529 17812488.72855 +1643 1529 -26564121.13518 +1530 1530 306664349.4585 +1531 1530 7.62939453125e-06 +1532 1530 462970.475417 +1533 1530 41289236.1897 +1534 1530 7333333.332126 +1535 1530 -318285.1588368 +1617 1530 -18391419.7975 +1618 1530 9166666.669678 +1619 1530 10018981.01522 +1620 1530 -58783069.51046 +1621 1530 1.639127731323e-06 +1622 1530 42697451.81849 +1623 1530 -19844426.42677 +1624 1530 -9166666.669679 +1625 1530 11321064.34898 +1638 1530 -206659.5438359 +1639 1530 -1833333.333934 +1640 1530 -1980647.67925 +1641 1530 28714906.85473 +1642 1530 5.364418029785e-07 +1643 1530 -8530229.601834 +1644 1530 -3124509.92214 +1645 1530 1833333.333932 +1646 1530 -2241064.345998 +1531 1531 262661096.8276 +1532 1531 -5555465.403687 +1533 1531 -7333333.332131 +1534 1531 -28377291.64613 +1535 1531 2749954.924074 +1617 1531 9166666.669678 +1618 1531 -15641216.50536 +1619 1531 -8177088.970282 +1620 1531 6.034970283508e-07 +1621 1531 -18449398.9965 +1622 1531 -694433.1761458 +1623 1531 -9166666.669679 +1624 1531 -17094223.13462 +1625 1531 8871522.146427 +1638 1531 1833333.333937 +1639 1531 -17623291.51138 +1640 1531 -16423622.37693 +1641 1531 8.940696716309e-07 +1642 1531 17714093.69157 +1643 1531 -1388866.351609 +1644 1531 -1833333.333939 +1645 1531 -20541141.88968 +1646 1531 17812488.72854 +1532 1532 291395225.4503 +1533 1532 723381.5076579 +1534 1532 2805510.47962 +1535 1532 37176251.17061 +1617 1532 10018981.01522 +1618 1532 -8177088.970282 +1619 1532 -16145262.77514 +1620 1532 42662729.59629 +1621 1532 -694433.1761458 +1622 1532 -54493616.03735 +1623 1532 11321064.34898 +1624 1532 8871522.146428 +1625 1532 -20019947.11985 +1638 1532 2038518.988737 +1639 1532 -16423622.37695 +1640 1532 -18783186.79303 +1641 1532 8588103.728686 +1642 1532 -1388866.351609 +1643 1532 -55021008.39532 +1644 1532 2298935.655493 +1645 1532 17812488.72855 +1646 1532 -26564121.13518 +1533 1533 306664349.4585 +1534 1533 7.62939453125e-06 +1535 1533 462970.475417 +1536 1533 41289236.1897 +1537 1533 7333333.332126 +1538 1533 -318285.1588368 +1620 1533 -18391419.7975 +1621 1533 9166666.669678 +1622 1533 10018981.01522 +1623 1533 -58783069.51046 +1624 1533 1.639127731323e-06 +1625 1533 42697451.81849 +1626 1533 -19844426.42677 +1627 1533 -9166666.669679 +1628 1533 11321064.34898 +1641 1533 -206659.5438359 +1642 1533 -1833333.333934 +1643 1533 -1980647.67925 +1644 1533 28714906.85473 +1645 1533 5.364418029785e-07 +1646 1533 -8530229.601834 +1647 1533 -3124509.92214 +1648 1533 1833333.333932 +1649 1533 -2241064.345998 +1534 1534 262661096.8276 +1535 1534 -5555465.403687 +1536 1534 -7333333.332131 +1537 1534 -28377291.64613 +1538 1534 2749954.924074 +1620 1534 9166666.669678 +1621 1534 -15641216.50536 +1622 1534 -8177088.970282 +1623 1534 6.034970283508e-07 +1624 1534 -18449398.9965 +1625 1534 -694433.1761458 +1626 1534 -9166666.669679 +1627 1534 -17094223.13462 +1628 1534 8871522.146427 +1641 1534 1833333.333937 +1642 1534 -17623291.51138 +1643 1534 -16423622.37693 +1644 1534 8.940696716309e-07 +1645 1534 17714093.69157 +1646 1534 -1388866.351609 +1647 1534 -1833333.333939 +1648 1534 -20541141.88968 +1649 1534 17812488.72854 +1535 1535 291395225.4503 +1536 1535 723381.5076579 +1537 1535 2805510.47962 +1538 1535 37176251.17061 +1620 1535 10018981.01522 +1621 1535 -8177088.970282 +1622 1535 -16145262.77514 +1623 1535 42662729.59629 +1624 1535 -694433.1761458 +1625 1535 -54493616.03735 +1626 1535 11321064.34898 +1627 1535 8871522.146428 +1628 1535 -20019947.11985 +1641 1535 2038518.988737 +1642 1535 -16423622.37695 +1643 1535 -18783186.79303 +1644 1535 8588103.728686 +1645 1535 -1388866.351609 +1646 1535 -55021008.39532 +1647 1535 2298935.655493 +1648 1535 17812488.72855 +1649 1535 -26564121.13518 +1536 1536 306664349.4585 +1537 1536 7.62939453125e-06 +1538 1536 462970.475417 +1539 1536 41289236.1897 +1540 1536 7333333.332126 +1541 1536 -318285.1588368 +1623 1536 -18391419.7975 +1624 1536 9166666.669678 +1625 1536 10018981.01522 +1626 1536 -58783069.51046 +1627 1536 1.639127731323e-06 +1628 1536 42697451.81849 +1629 1536 -19844426.42677 +1630 1536 -9166666.669679 +1631 1536 11321064.34898 +1644 1536 -206659.5438359 +1645 1536 -1833333.333934 +1646 1536 -1980647.67925 +1647 1536 28714906.85473 +1648 1536 5.364418029785e-07 +1649 1536 -8530229.601834 +1650 1536 -3124509.92214 +1651 1536 1833333.333932 +1652 1536 -2241064.345998 +1537 1537 262661096.8276 +1538 1537 -5555465.403687 +1539 1537 -7333333.332131 +1540 1537 -28377291.64613 +1541 1537 2749954.924074 +1623 1537 9166666.669678 +1624 1537 -15641216.50536 +1625 1537 -8177088.970282 +1626 1537 6.034970283508e-07 +1627 1537 -18449398.9965 +1628 1537 -694433.1761458 +1629 1537 -9166666.669679 +1630 1537 -17094223.13462 +1631 1537 8871522.146427 +1644 1537 1833333.333937 +1645 1537 -17623291.51138 +1646 1537 -16423622.37693 +1647 1537 8.940696716309e-07 +1648 1537 17714093.69157 +1649 1537 -1388866.351609 +1650 1537 -1833333.333939 +1651 1537 -20541141.88968 +1652 1537 17812488.72854 +1538 1538 291395225.4503 +1539 1538 723381.5076579 +1540 1538 2805510.47962 +1541 1538 37176251.17061 +1623 1538 10018981.01522 +1624 1538 -8177088.970282 +1625 1538 -16145262.77514 +1626 1538 42662729.59629 +1627 1538 -694433.1761458 +1628 1538 -54493616.03735 +1629 1538 11321064.34898 +1630 1538 8871522.146428 +1631 1538 -20019947.11985 +1644 1538 2038518.988737 +1645 1538 -16423622.37695 +1646 1538 -18783186.79303 +1647 1538 8588103.728686 +1648 1538 -1388866.351609 +1649 1538 -55021008.39532 +1650 1538 2298935.655493 +1651 1538 17812488.72855 +1652 1538 -26564121.13518 +1539 1539 306664349.4585 +1540 1539 7.62939453125e-06 +1541 1539 462970.475417 +1542 1539 41289236.1897 +1543 1539 7333333.332126 +1544 1539 -318285.1588368 +1626 1539 -18391419.7975 +1627 1539 9166666.669678 +1628 1539 10018981.01522 +1629 1539 -58783069.51046 +1630 1539 1.639127731323e-06 +1631 1539 42697451.81849 +1632 1539 -19844426.42677 +1633 1539 -9166666.669679 +1634 1539 11321064.34898 +1647 1539 -206659.5438359 +1648 1539 -1833333.333934 +1649 1539 -1980647.67925 +1650 1539 28714906.85473 +1651 1539 5.364418029785e-07 +1652 1539 -8530229.601834 +1653 1539 -3124509.92214 +1654 1539 1833333.333932 +1655 1539 -2241064.345998 +1540 1540 262661096.8276 +1541 1540 -5555465.403687 +1542 1540 -7333333.332131 +1543 1540 -28377291.64613 +1544 1540 2749954.924074 +1626 1540 9166666.669678 +1627 1540 -15641216.50536 +1628 1540 -8177088.970282 +1629 1540 6.034970283508e-07 +1630 1540 -18449398.9965 +1631 1540 -694433.1761458 +1632 1540 -9166666.669679 +1633 1540 -17094223.13462 +1634 1540 8871522.146427 +1647 1540 1833333.333937 +1648 1540 -17623291.51138 +1649 1540 -16423622.37693 +1650 1540 8.940696716309e-07 +1651 1540 17714093.69157 +1652 1540 -1388866.351609 +1653 1540 -1833333.333939 +1654 1540 -20541141.88968 +1655 1540 17812488.72854 +1541 1541 291395225.4503 +1542 1541 723381.5076579 +1543 1541 2805510.47962 +1544 1541 37176251.17061 +1626 1541 10018981.01522 +1627 1541 -8177088.970282 +1628 1541 -16145262.77514 +1629 1541 42662729.59629 +1630 1541 -694433.1761458 +1631 1541 -54493616.03735 +1632 1541 11321064.34898 +1633 1541 8871522.146428 +1634 1541 -20019947.11985 +1647 1541 2038518.988737 +1648 1541 -16423622.37695 +1649 1541 -18783186.79303 +1650 1541 8588103.728686 +1651 1541 -1388866.351609 +1652 1541 -55021008.39532 +1653 1541 2298935.655493 +1654 1541 17812488.72855 +1655 1541 -26564121.13518 +1542 1542 307321293.6177 +1543 1542 5217302.692383 +1544 1542 2443291.135431 +1545 1542 -12283347.92522 +1546 1542 -27675645.7152 +1547 1542 392217.5447181 +1629 1542 -18391419.7975 +1630 1542 9166666.669678 +1631 1542 10018981.01522 +1632 1542 -42844315.11718 +1633 1542 6143828.42298 +1634 1542 32439903.28737 +1635 1542 -19056485.08992 +1636 1542 -7862576.000246 +1637 1542 10773788.984 +1650 1542 -206659.5438359 +1651 1542 -1833333.333934 +1652 1542 -1980647.67925 +1653 1542 28878510.79233 +1654 1542 1304325.673737 +1655 1542 -8034871.658814 +1656 1542 -18263780.54944 +1657 1542 -6918911.432209 +1658 1542 8066734.94041 +1543 1543 292495414.5893 +1544 1543 -3617588.716354 +1545 1543 -42342312.37946 +1546 1543 -73068635.97963 +1547 1543 598083.9198294 +1629 1543 9166666.669678 +1630 1543 -15641216.50536 +1631 1543 -8177088.970282 +1632 1543 6143828.422979 +1633 1543 -19317502.00901 +1634 1543 -8396261.212014 +1635 1543 -7862576.000246 +1636 1543 -9014077.742685 +1637 1543 8522682.095422 +1650 1543 1833333.333937 +1651 1543 -17623291.51138 +1652 1543 -16423622.37693 +1653 1543 1304325.673737 +1654 1543 25172041.03341 +1655 1543 -904397.1795395 +1656 1543 -10585578.10008 +1657 1543 -33460102.57053 +1658 1543 25378687.64334 +1544 1544 299489762.7903 +1545 1544 565828.6557986 +1546 1544 625861.6976026 +1547 1544 18644724.62356 +1629 1544 10018981.01522 +1630 1544 -8177088.970282 +1631 1544 -16145262.77514 +1632 1544 32613514.40058 +1633 1544 -8396261.210409 +1634 1544 -46240317.03562 +1635 1544 10773788.984 +1636 1544 8522682.095422 +1637 1544 -16336570.1928 +1650 1544 2038518.988737 +1651 1544 -16423622.37695 +1652 1544 -18783186.79303 +1653 1544 9082906.116151 +1654 1544 -904397.1795395 +1655 1544 -52999059.66538 +1656 1544 12398123.82872 +1657 1544 25378687.64175 +1658 1544 -35853335.01949 +1545 1545 358811430.7903 +1546 1545 52593962.28105 +1547 1545 -97551.46225023 +1548 1545 -71392253.48931 +1549 1545 -45102098.94442 +1550 1545 106737.5969375 +1551 1545 9275019.197588 +1552 1545 -12341313.18395 +1553 1545 144785.8447827 +1632 1545 -19715237.85133 +1633 1545 1074136.079186 +1634 1545 524851.8469836 +1635 1545 -37144610.97898 +1636 1545 10723804.48332 +1637 1545 41672628.54298 +1653 1545 -17529221.15356 +1654 1545 -10585578.10008 +1655 1545 -12149931.72292 +1656 1545 -1095063.644689 +1657 1545 13148490.57674 +1658 1545 -8461748.97526 +1659 1545 -34526661.87963 +1660 1545 -11275524.74166 +1661 1545 20339184.40592 +1662 1545 -25557949.75669 +1663 1545 -3085328.297506 +1664 1545 8108904.791231 +1546 1546 452274744.3036 +1547 1546 -1473057.85089 +1548 1546 -45102098.94442 +1549 1546 -51062500.21883 +1550 1546 72962.07354495 +1551 1546 -27007979.8482 +1552 1546 -62389541.28179 +1553 1546 233441.0174853 +1632 1546 1074136.079186 +1633 1546 -46885450.83199 +1634 1546 -16367906.36496 +1635 1546 10723804.48332 +1636 1546 -5310202.55853 +1637 1546 -8267728.707675 +1653 1546 -6918911.432211 +1654 1546 -32725543.17465 +1655 1546 -25072701.23725 +1656 1546 13148490.57674 +1657 1546 22270764.74516 +1658 1546 -368264.4629124 +1659 1546 -11275524.74166 +1660 1546 -29444223.55951 +1661 1546 16684907.19053 +1662 1546 -6751994.965377 +1663 1546 -43474089.88536 +1664 1546 33391693.58226 +1547 1547 478029006.2153 +1548 1547 106737.5969376 +1549 1547 72962.07354495 +1550 1547 13640717.48805 +1551 1547 179508.0669963 +1552 1547 233441.0174853 +1553 1547 63954215.97093 +1632 1547 524851.8469835 +1633 1547 -16367906.36496 +1634 1547 -26172187.69396 +1635 1547 41672628.54301 +1636 1547 -8267728.706071 +1637 1547 -79414009.52307 +1653 1547 -7922709.501298 +1654 1547 -25072701.23886 +1655 1547 -33894509.96379 +1656 1547 8239362.133108 +1657 1547 -368264.4629123 +1658 1547 -122620538.7512 +1659 1547 20339184.40592 +1660 1547 16684907.19053 +1661 1547 -41066083.28901 +1662 1547 12197515.90567 +1663 1547 33391693.58226 +1664 1547 -58349324.81867 +1548 1548 235659396.7196 +1549 1548 50733749.26305 +1550 1548 -62257.13548279 +1551 1548 -5082746.465364 +1552 1548 1102098.951645 +1553 1548 -31506.11544451 +1635 1548 -23117500.71233 +1636 1548 -1683437.318397 +1637 1548 -6070778.306718 +1656 1548 -34431964.90992 +1657 1548 -11275524.74166 +1658 1548 -20285815.60742 +1659 1548 -18665832.59106 +1660 1548 12683437.32201 +1661 1548 8109435.714787 +1662 1548 -34533186.62789 +1663 1548 275524.7380462 +1664 1548 -30502841.80065 +1549 1549 216642073.1324 +1550 1549 -58407.27654648 +1551 1549 15768765.6159 +1552 1549 63962500.24948 +1553 1549 -72962.07354212 +1635 1549 -5350103.986268 +1636 1549 -40706919.82054 +1637 1549 -33318731.50871 +1656 1549 -11275524.74166 +1657 1549 -29349526.58979 +1658 1549 -16648426.15375 +1659 1549 12683437.32201 +1660 1549 -23420163.4902 +1661 1549 6652064.846425 +1662 1549 3942191.405917 +1663 1549 -17271874.94068 +1664 1549 3315092.816032 +1550 1550 342775232.3518 +1551 1550 -66228.3376576 +1552 1550 -72962.0735423 +1553 1550 110134282.579 +1635 1550 -14195778.30738 +1636 1550 -33318731.50871 +1637 1550 -72161295.49948 +1656 1550 -20285815.60742 +1657 1550 -16648426.15375 +1658 1550 -40813558.03643 +1659 1550 -8140564.282544 +1660 1550 -6681268.484718 +1661 1550 -121188010.0031 +1662 1550 -30502841.80265 +1663 1550 -3351573.852824 +1664 1550 -61166429.37081 +1551 1551 173317617.147 +1552 1551 -16992020.14457 +1553 1551 40399.34029067 +1635 1551 -16595464.90406 +1636 1551 7057808.597695 +1637 1551 10161406.6248 +1656 1551 -25273858.84771 +1657 1551 -6751994.965378 +1658 1551 -12142484.09433 +1659 1551 -34533186.62789 +1660 1551 3942191.405919 +1661 1551 30478408.18933 +1662 1551 -12139913.87007 +1663 1551 -4248005.038235 +1664 1551 -4104552.942003 +1552 1552 200198427.6337 +1553 1552 -233441.0174782 +1635 1552 7057808.597695 +1636 1552 -22660839.0876 +1637 1552 -16648426.15375 +1656 1552 -3085328.297507 +1657 1552 -43189998.97639 +1658 1552 -33274973.07346 +1659 1552 275524.7380478 +1660 1552 -17271874.94068 +1661 1552 3315092.816032 +1662 1552 -4248005.038235 +1663 1552 -5419711.245076 +1664 1552 6608306.41117 +1553 1553 258752397.6415 +1635 1553 10161406.6248 +1636 1553 -16648426.15375 +1637 1553 -34124870.53423 +1656 1553 -8088595.202104 +1657 1553 -33274973.07346 +1658 1553 -57591749.06139 +1659 1553 30478408.18734 +1660 1553 -3351573.852824 +1661 1553 -61166429.37081 +1662 1553 4037947.05666 +1663 1553 -6725026.919973 +1664 1553 -83230082.36618 +1554 1554 385435299.3209 +1555 1554 36666666.66064 +1556 1554 3703838.61297 +1557 1554 -203986384.4368 +1558 1554 -36666980.60238 +1559 1554 -2870486.454752 +1560 1554 12104621.19738 +1561 1554 29333647.27025 +1562 1554 -1944469.225024 +1665 1554 33963705.33589 +1666 1554 9166666.669679 +1667 1554 9519894.71657 +1668 1554 -73633660.33315 +1669 1554 -9166743.277268 +1670 1554 -44520628.22528 +1671 1554 -7828204.348046 +1672 1554 7333409.943332 +1673 1554 -9288430.506837 +1555 1555 330430928.8169 +1556 1555 -6111047.842687 +1557 1555 -36667137.57325 +1558 1555 -31649934.0022 +1559 1555 -3888890.401321 +1560 1555 44000470.90538 +1561 1555 12104621.19738 +1562 1555 2666690.447648 +1665 1555 9166666.669679 +1666 1555 20212626.84424 +1667 1555 5347275.319281 +1668 1555 -9166781.581064 +1669 1555 -30549559.96733 +1670 1555 -9732749.59088 +1671 1555 11000114.915 +1672 1555 -7828204.348045 +1673 1555 11145949.53617 +1556 1556 369852862.7392 +1557 1556 -2453810.375638 +1558 1556 -3055549.140985 +1559 1556 -3321169.645782 +1560 1556 -2916703.837537 +1561 1556 1777793.631766 +1562 1556 32278989.8597 +1665 1556 -8015196.919944 +1666 1556 -8680575.648187 +1667 1556 -73923722.2424 +1668 1556 -44485903.34313 +1669 1556 -9538266.413314 +1670 1556 -61195846.2912 +1671 1556 -13932645.76025 +1672 1556 7430633.02411 +1673 1556 -20875211.59479 +1557 1557 668782112.6068 +1558 1557 36667451.515 +1559 1557 3125095.269694 +1560 1557 18742492.4051 +1561 1557 -36666980.60238 +1562 1557 2754656.266036 +1563 1557 -139221200.1674 +1564 1557 1.877546310425e-06 +1565 1557 -671303.7191255 +1566 1557 -52506158.07532 +1567 1557 36666666.66064 +1568 1557 -2754631.485001 +1665 1557 -72039530.38171 +1666 1557 -9166781.581061 +1667 1557 43189554.83944 +1668 1557 73599694.87993 +1669 1557 9166858.188655 +1670 1557 781226.7976368 +1671 1557 -19443104.86928 +1672 1557 -9166743.27727 +1673 1557 11639449.48452 +1674 1557 -59964405.70834 +1675 1557 7.525086402893e-07 +1676 1557 -43970603.67818 +1677 1557 -20163436.42398 +1678 1557 9166666.669676 +1679 1557 -11639352.31406 +1558 1558 569774528.2723 +1559 1558 -8610907.219653 +1560 1558 -36667137.57325 +1561 1558 -109590390.9887 +1562 1558 4777683.581345 +1563 1558 1.594424247742e-06 +1564 1558 22113465.72052 +1565 1558 -2777733.240903 +1566 1558 36666666.66064 +1567 1558 -41505354.61226 +1568 1558 1555533.287118 +1665 1558 -9166743.277267 +1666 1558 -28955430.01587 +1667 1558 7996602.428466 +1668 1558 9166858.188655 +1669 1558 48847822.54786 +1670 1558 -2152764.803778 +1671 1558 -9166781.581064 +1672 1558 -51526325.20493 +1673 1558 36236271.0855 +1674 1558 3.725290298462e-07 +1675 1558 -19630743.20649 +1676 1558 -694433.4439167 +1677 1558 9166666.669676 +1678 1558 -17413237.96253 +1679 1558 9149300.058182 +1559 1559 599068063.3379 +1560 1559 2685224.212055 +1561 1559 5222138.335127 +1562 1559 35717984.23851 +1563 1559 -254637.0525279 +1564 1559 -2777733.240903 +1565 1559 37788315.6602 +1566 1559 -2685187.040499 +1567 1559 1499977.731517 +1568 1559 -8422346.095089 +1665 1559 43154829.95728 +1666 1559 7802192.5578 +1667 1559 -56944833.0873 +1668 1559 781318.4370322 +1669 1559 -2152691.493423 +1670 1559 -99821807.80486 +1671 1559 11639498.06975 +1672 1559 36402939.91804 +1673 1559 -55413772.21342 +1674 1559 -43935881.45598 +1675 1559 -694433.4439167 +1676 1559 -57643892.87044 +1677 1559 -11639352.31406 +1678 1559 9149300.058182 +1679 1559 -20870649.36111 +1560 1560 385435299.3209 +1561 1560 36666666.66064 +1562 1560 3703838.61297 +1563 1560 -52482483.83292 +1564 1560 -36666666.66064 +1565 1560 2453701.847473 +1566 1560 -203986384.4368 +1567 1560 -36666980.60238 +1568 1560 -2870486.454752 +1569 1560 12104621.19738 +1570 1560 29333647.27025 +1571 1560 -1944469.225024 +1665 1560 -4839277.140465 +1666 1560 11000114.915 +1667 1560 12370128.70975 +1668 1560 -14860172.33131 +1669 1560 -9166781.581062 +1670 1560 -10279526.39882 +1671 1560 33963705.33589 +1672 1560 9166666.669679 +1673 1560 9519894.71657 +1674 1560 -18663081.30986 +1675 1560 -9166666.669677 +1676 1560 -10337268.9803 +1677 1560 -73633660.33315 +1678 1560 -9166743.277268 +1679 1560 -44520628.22528 +1680 1560 -7828204.348046 +1681 1560 7333409.943332 +1682 1560 -9288430.506837 +1561 1561 330430928.8169 +1562 1561 -6111047.842687 +1563 1561 -36666666.66065 +1564 1561 -41481680.36985 +1565 1561 1222199.953785 +1566 1561 -36667137.57325 +1567 1561 -31649934.0022 +1568 1561 -3888890.401321 +1569 1561 44000470.90538 +1570 1561 12104621.19738 +1571 1561 2666690.447648 +1665 1561 7333409.943332 +1666 1561 -4839277.140466 +1667 1561 -6597291.372073 +1668 1561 -9166743.277267 +1669 1561 -46943392.66696 +1670 1561 -33736315.15602 +1671 1561 9166666.669679 +1672 1561 20212626.84424 +1673 1561 5347275.319281 +1674 1561 -9166666.669677 +1675 1561 -15912882.8484 +1676 1561 -8454866.614265 +1677 1561 -9166781.581064 +1678 1561 -30549559.96733 +1679 1561 -9732749.59088 +1680 1561 11000114.915 +1681 1561 -7828204.348045 +1682 1561 11145949.53617 +1562 1562 369852862.7392 +1563 1562 2523146.291974 +1564 1562 1277755.509386 +1565 1562 -8359214.781975 +1566 1562 -2453810.375638 +1567 1562 -3055549.140985 +1568 1562 -3321169.645782 +1569 1562 -2916703.837537 +1570 1562 1777793.631766 +1571 1562 32278989.8597 +1665 1562 8246752.473166 +1666 1562 -9895937.05811 +1667 1562 -12904739.04124 +1668 1562 -10279483.49692 +1669 1562 -33902984.10692 +1670 1562 -43192618.77883 +1671 1562 -8015196.919944 +1672 1562 -8680575.648187 +1673 1562 -73923722.2424 +1674 1562 -10337268.9803 +1675 1562 -8454866.614265 +1676 1562 -16869702.39011 +1677 1562 -44485903.34313 +1678 1562 -9538266.413314 +1679 1562 -61195846.2912 +1680 1562 -13932645.76025 +1681 1562 7430633.02411 +1682 1562 -20875211.59479 +1563 1563 616485232.3769 +1564 1563 1.227855682373e-05 +1565 1563 925940.7716047 +1566 1563 83364435.48308 +1567 1563 -6.437301635742e-06 +1568 1563 231485.1930161 +1572 1563 -139221200.1674 +1573 1563 1.877546310425e-06 +1574 1563 -671303.7191255 +1575 1563 -52506158.07532 +1576 1563 36666666.66064 +1577 1563 -2754631.485001 +1668 1563 -59565882.98117 +1669 1563 4.91738319397e-07 +1670 1563 43739118.52961 +1671 1563 -20057887.18154 +1672 1563 -9166666.669679 +1673 1563 11581481.02689 +1674 1563 54280296.46473 +1675 1563 3.09944152832e-06 +1676 1563 231485.1485852 +1677 1563 -7107625.989141 +1678 1563 -6.146728992462e-06 +1679 1563 57871.2871768 +1683 1563 -59964405.70834 +1684 1563 7.525086402893e-07 +1685 1563 -43970603.67818 +1686 1563 -20163436.42398 +1687 1563 9166666.669676 +1688 1563 -11639352.31406 +1564 1564 528478804.7157 +1565 1564 -11110932.95814 +1566 1564 -5.766749382019e-06 +1567 1564 -55968623.50036 +1568 1564 5722133.145708 +1572 1564 1.594424247742e-06 +1573 1564 22113465.72052 +1574 1564 -2777733.240903 +1575 1564 36666666.66064 +1576 1564 -41505354.61226 +1577 1564 1555533.287118 +1668 1564 -5.811452865601e-07 +1669 1564 -19232220.47929 +1670 1564 -694433.4439163 +1671 1564 -9166666.669679 +1672 1564 -17307688.72007 +1673 1564 9079855.613715 +1674 1564 3.635883331299e-06 +1675 1564 32278708.78388 +1676 1564 -2777733.774297 +1677 1564 -5.349516868591e-06 +1678 1564 -41940891.5735 +1679 1564 36472200.21471 +1683 1564 3.725290298462e-07 +1684 1564 -19630743.20649 +1685 1564 -694433.4439167 +1686 1564 9166666.669676 +1687 1564 -17413237.96253 +1688 1564 9149300.058182 +1565 1565 591208016.6774 +1566 1565 231485.1930168 +1567 1565 5388799.81243 +1568 1565 76448462.46728 +1572 1565 -254637.0525279 +1573 1565 -2777733.240903 +1574 1565 37788315.6602 +1575 1565 -2685187.040499 +1576 1565 1499977.731517 +1577 1565 -8422346.095089 +1668 1565 43704396.30741 +1669 1565 -694433.4439163 +1670 1565 -56581165.5979 +1671 1565 11581481.02689 +1672 1565 9079855.613715 +1673 1565 -20589184.71456 +1674 1565 231485.148585 +1675 1565 -2777733.774298 +1676 1565 -118440658.1206 +1677 1565 57871.28717716 +1678 1565 36444422.43695 +1679 1565 -55417829.51533 +1683 1565 -43935881.45598 +1684 1565 -694433.4439167 +1685 1565 -57643892.87044 +1686 1565 -11639352.31406 +1687 1565 9149300.058182 +1688 1565 -20870649.36111 +1566 1566 668782112.6068 +1567 1566 36667451.515 +1568 1566 3125095.269694 +1569 1566 18742492.4051 +1570 1566 -36666980.60238 +1571 1566 2754656.266036 +1572 1566 -52482483.83292 +1573 1566 -36666666.66064 +1574 1566 2453701.847473 +1575 1566 -139221200.1674 +1576 1566 1.877546310425e-06 +1577 1566 -671303.7191255 +1578 1566 -52506158.07532 +1579 1566 36666666.66064 +1580 1566 -2754631.485001 +1668 1566 -18569369.18862 +1669 1566 9166666.669678 +1670 1566 10279397.69313 +1671 1566 -72039530.38171 +1672 1566 -9166781.581061 +1673 1566 43189554.83944 +1674 1566 -1129879.778007 +1675 1566 2.369284629822e-06 +1676 1566 57871.28717239 +1677 1566 73599694.87993 +1678 1566 9166858.188655 +1679 1566 781226.7976368 +1680 1566 -19443104.86928 +1681 1566 -9166743.27727 +1682 1566 11639449.48452 +1683 1566 -18663081.30986 +1684 1566 -9166666.669677 +1685 1566 -10337268.9803 +1686 1566 -59964405.70834 +1687 1566 7.525086402893e-07 +1688 1566 -43970603.67818 +1689 1566 -20163436.42398 +1690 1566 9166666.669676 +1691 1566 -11639352.31406 +1567 1567 569774528.2723 +1568 1567 -8610907.219653 +1569 1567 -36667137.57325 +1570 1567 -109590390.9887 +1571 1567 4777683.581345 +1572 1567 -36666666.66065 +1573 1567 -41481680.36985 +1574 1567 1222199.953785 +1575 1567 1.594424247742e-06 +1576 1567 22113465.72052 +1577 1567 -2777733.240903 +1578 1567 36666666.66064 +1579 1567 -41505354.61226 +1580 1567 1555533.287118 +1668 1567 9166666.669678 +1669 1567 -15819170.72716 +1670 1567 -8385422.169798 +1671 1567 -9166743.277267 +1672 1567 -28955430.01587 +1673 1567 7996602.428466 +1674 1567 2.913177013397e-06 +1675 1567 -35963145.36236 +1676 1567 -33694466.44041 +1677 1567 9166858.188655 +1678 1567 48847822.54786 +1679 1567 -2152764.803778 +1680 1567 -9166781.581064 +1681 1567 -51526325.20493 +1682 1567 36236271.0855 +1683 1567 -9166666.669677 +1684 1567 -15912882.8484 +1685 1567 -8454866.614265 +1686 1567 3.725290298462e-07 +1687 1567 -19630743.20649 +1688 1567 -694433.4439167 +1689 1567 9166666.669676 +1690 1567 -17413237.96253 +1691 1567 9149300.058182 +1568 1568 599068063.3379 +1569 1568 2685224.212055 +1570 1568 5222138.335127 +1571 1568 35717984.23851 +1572 1568 2523146.291974 +1573 1568 1277755.509386 +1574 1568 -8359214.781975 +1575 1568 -254637.0525279 +1576 1568 -2777733.240903 +1577 1568 37788315.6602 +1578 1568 -2685187.040499 +1579 1568 1499977.731517 +1580 1568 -8422346.095089 +1668 1568 10279397.69313 +1669 1568 -8385422.169798 +1670 1568 -16619803.40013 +1671 1568 43154829.95728 +1672 1568 7802192.5578 +1673 1568 -56944833.0873 +1674 1568 57871.28717278 +1675 1568 -33666688.66265 +1676 1568 -39477172.9523 +1677 1568 781318.4370322 +1678 1568 -2152691.493423 +1679 1568 -99821807.80486 +1680 1568 11639498.06975 +1681 1568 36402939.91804 +1682 1568 -55413772.21342 +1683 1568 -10337268.9803 +1684 1568 -8454866.614265 +1685 1568 -16869702.39011 +1686 1568 -43935881.45598 +1687 1568 -694433.4439167 +1688 1568 -57643892.87044 +1689 1568 -11639352.31406 +1690 1568 9149300.058182 +1691 1568 -20870649.36111 +1569 1569 385435299.3209 +1570 1569 36666666.66064 +1571 1569 3703838.61297 +1575 1569 -52482483.83292 +1576 1569 -36666666.66064 +1577 1569 2453701.847473 +1578 1569 -203986384.4368 +1579 1569 -36666980.60238 +1580 1569 -2870486.454752 +1581 1569 12104621.19738 +1582 1569 29333647.27025 +1583 1569 -1944469.225024 +1671 1569 -4839277.140465 +1672 1569 11000114.915 +1673 1569 12370128.70975 +1677 1569 -14860172.33131 +1678 1569 -9166781.581062 +1679 1569 -10279526.39882 +1680 1569 33963705.33589 +1681 1569 9166666.669679 +1682 1569 9519894.71657 +1686 1569 -18663081.30986 +1687 1569 -9166666.669677 +1688 1569 -10337268.9803 +1689 1569 -73633660.33315 +1690 1569 -9166743.277268 +1691 1569 -44520628.22528 +1692 1569 -7828204.348046 +1693 1569 7333409.943332 +1694 1569 -9288430.506837 +1570 1570 330430928.8169 +1571 1570 -6111047.842687 +1575 1570 -36666666.66065 +1576 1570 -41481680.36985 +1577 1570 1222199.953785 +1578 1570 -36667137.57325 +1579 1570 -31649934.0022 +1580 1570 -3888890.401321 +1581 1570 44000470.90538 +1582 1570 12104621.19738 +1583 1570 2666690.447648 +1671 1570 7333409.943332 +1672 1570 -4839277.140466 +1673 1570 -6597291.372073 +1677 1570 -9166743.277267 +1678 1570 -46943392.66696 +1679 1570 -33736315.15602 +1680 1570 9166666.669679 +1681 1570 20212626.84424 +1682 1570 5347275.319281 +1686 1570 -9166666.669677 +1687 1570 -15912882.8484 +1688 1570 -8454866.614265 +1689 1570 -9166781.581064 +1690 1570 -30549559.96733 +1691 1570 -9732749.59088 +1692 1570 11000114.915 +1693 1570 -7828204.348045 +1694 1570 11145949.53617 +1571 1571 369852862.7392 +1575 1571 2523146.291974 +1576 1571 1277755.509386 +1577 1571 -8359214.781975 +1578 1571 -2453810.375638 +1579 1571 -3055549.140985 +1580 1571 -3321169.645782 +1581 1571 -2916703.837537 +1582 1571 1777793.631766 +1583 1571 32278989.8597 +1671 1571 8246752.473166 +1672 1571 -9895937.05811 +1673 1571 -12904739.04124 +1677 1571 -10279483.49692 +1678 1571 -33902984.10692 +1679 1571 -43192618.77883 +1680 1571 -8015196.919944 +1681 1571 -8680575.648187 +1682 1571 -73923722.2424 +1686 1571 -10337268.9803 +1687 1571 -8454866.614265 +1688 1571 -16869702.39011 +1689 1571 -44485903.34313 +1690 1571 -9538266.413314 +1691 1571 -61195846.2912 +1692 1571 -13932645.76025 +1693 1571 7430633.02411 +1694 1571 -20875211.59479 +1572 1572 616485232.3769 +1573 1572 1.227855682373e-05 +1574 1572 925940.7716047 +1575 1572 83364435.48308 +1576 1572 -6.437301635742e-06 +1577 1572 231485.1930161 +1584 1572 -139221200.1674 +1585 1572 1.877546310425e-06 +1586 1572 -671303.7191255 +1587 1572 -52506158.07532 +1588 1572 36666666.66064 +1589 1572 -2754631.485001 +1674 1572 -59565882.98117 +1675 1572 4.91738319397e-07 +1676 1572 43739118.52961 +1677 1572 -20057887.18154 +1678 1572 -9166666.669679 +1679 1572 11581481.02689 +1683 1572 54280296.46473 +1684 1572 3.09944152832e-06 +1685 1572 231485.1485852 +1686 1572 -7107625.989141 +1687 1572 -6.146728992462e-06 +1688 1572 57871.2871768 +1695 1572 -59964405.70834 +1696 1572 7.525086402893e-07 +1697 1572 -43970603.67818 +1698 1572 -20163436.42398 +1699 1572 9166666.669676 +1700 1572 -11639352.31406 +1573 1573 528478804.7157 +1574 1573 -11110932.95814 +1575 1573 -5.766749382019e-06 +1576 1573 -55968623.50036 +1577 1573 5722133.145708 +1584 1573 1.594424247742e-06 +1585 1573 22113465.72052 +1586 1573 -2777733.240903 +1587 1573 36666666.66064 +1588 1573 -41505354.61226 +1589 1573 1555533.287118 +1674 1573 -5.811452865601e-07 +1675 1573 -19232220.47929 +1676 1573 -694433.4439163 +1677 1573 -9166666.669679 +1678 1573 -17307688.72007 +1679 1573 9079855.613715 +1683 1573 3.635883331299e-06 +1684 1573 32278708.78388 +1685 1573 -2777733.774297 +1686 1573 -5.349516868591e-06 +1687 1573 -41940891.5735 +1688 1573 36472200.21471 +1695 1573 3.725290298462e-07 +1696 1573 -19630743.20649 +1697 1573 -694433.4439167 +1698 1573 9166666.669676 +1699 1573 -17413237.96253 +1700 1573 9149300.058182 +1574 1574 591208016.6774 +1575 1574 231485.1930168 +1576 1574 5388799.81243 +1577 1574 76448462.46728 +1584 1574 -254637.0525279 +1585 1574 -2777733.240903 +1586 1574 37788315.6602 +1587 1574 -2685187.040499 +1588 1574 1499977.731517 +1589 1574 -8422346.095089 +1674 1574 43704396.30741 +1675 1574 -694433.4439163 +1676 1574 -56581165.5979 +1677 1574 11581481.02689 +1678 1574 9079855.613715 +1679 1574 -20589184.71456 +1683 1574 231485.148585 +1684 1574 -2777733.774298 +1685 1574 -118440658.1206 +1686 1574 57871.28717716 +1687 1574 36444422.43695 +1688 1574 -55417829.51533 +1695 1574 -43935881.45598 +1696 1574 -694433.4439167 +1697 1574 -57643892.87044 +1698 1574 -11639352.31406 +1699 1574 9149300.058182 +1700 1574 -20870649.36111 +1575 1575 616485232.3769 +1576 1575 1.227855682373e-05 +1577 1575 925940.7716047 +1578 1575 83364435.48308 +1579 1575 -6.437301635742e-06 +1580 1575 231485.1930161 +1584 1575 -52482483.83292 +1585 1575 -36666666.66064 +1586 1575 2453701.847473 +1587 1575 -139221200.1674 +1588 1575 1.877546310425e-06 +1589 1575 -671303.7191255 +1590 1575 -52506158.07532 +1591 1575 36666666.66064 +1592 1575 -2754631.485001 +1674 1575 -18569369.18862 +1675 1575 9166666.669678 +1676 1575 10279397.69313 +1677 1575 -59565882.98117 +1678 1575 4.91738319397e-07 +1679 1575 43739118.52961 +1680 1575 -20057887.18154 +1681 1575 -9166666.669679 +1682 1575 11581481.02689 +1683 1575 -1129879.778007 +1684 1575 2.369284629822e-06 +1685 1575 57871.28717239 +1686 1575 54280296.46473 +1687 1575 3.09944152832e-06 +1688 1575 231485.1485852 +1689 1575 -7107625.989141 +1690 1575 -6.146728992462e-06 +1691 1575 57871.2871768 +1695 1575 -18663081.30986 +1696 1575 -9166666.669677 +1697 1575 -10337268.9803 +1698 1575 -59964405.70834 +1699 1575 7.525086402893e-07 +1700 1575 -43970603.67818 +1701 1575 -20163436.42398 +1702 1575 9166666.669676 +1703 1575 -11639352.31406 +1576 1576 528478804.7157 +1577 1576 -11110932.95814 +1578 1576 -5.766749382019e-06 +1579 1576 -55968623.50036 +1580 1576 5722133.145708 +1584 1576 -36666666.66065 +1585 1576 -41481680.36985 +1586 1576 1222199.953785 +1587 1576 1.594424247742e-06 +1588 1576 22113465.72052 +1589 1576 -2777733.240903 +1590 1576 36666666.66064 +1591 1576 -41505354.61226 +1592 1576 1555533.287118 +1674 1576 9166666.669678 +1675 1576 -15819170.72716 +1676 1576 -8385422.169798 +1677 1576 -5.811452865601e-07 +1678 1576 -19232220.47929 +1679 1576 -694433.4439163 +1680 1576 -9166666.669679 +1681 1576 -17307688.72007 +1682 1576 9079855.613715 +1683 1576 2.913177013397e-06 +1684 1576 -35963145.36236 +1685 1576 -33694466.44041 +1686 1576 3.635883331299e-06 +1687 1576 32278708.78388 +1688 1576 -2777733.774297 +1689 1576 -5.349516868591e-06 +1690 1576 -41940891.5735 +1691 1576 36472200.21471 +1695 1576 -9166666.669677 +1696 1576 -15912882.8484 +1697 1576 -8454866.614265 +1698 1576 3.725290298462e-07 +1699 1576 -19630743.20649 +1700 1576 -694433.4439167 +1701 1576 9166666.669676 +1702 1576 -17413237.96253 +1703 1576 9149300.058182 +1577 1577 591208016.6774 +1578 1577 231485.1930168 +1579 1577 5388799.81243 +1580 1577 76448462.46728 +1584 1577 2523146.291974 +1585 1577 1277755.509386 +1586 1577 -8359214.781975 +1587 1577 -254637.0525279 +1588 1577 -2777733.240903 +1589 1577 37788315.6602 +1590 1577 -2685187.040499 +1591 1577 1499977.731517 +1592 1577 -8422346.095089 +1674 1577 10279397.69313 +1675 1577 -8385422.169798 +1676 1577 -16619803.40013 +1677 1577 43704396.30741 +1678 1577 -694433.4439163 +1679 1577 -56581165.5979 +1680 1577 11581481.02689 +1681 1577 9079855.613715 +1682 1577 -20589184.71456 +1683 1577 57871.28717278 +1684 1577 -33666688.66265 +1685 1577 -39477172.9523 +1686 1577 231485.148585 +1687 1577 -2777733.774298 +1688 1577 -118440658.1206 +1689 1577 57871.28717716 +1690 1577 36444422.43695 +1691 1577 -55417829.51533 +1695 1577 -10337268.9803 +1696 1577 -8454866.614265 +1697 1577 -16869702.39011 +1698 1577 -43935881.45598 +1699 1577 -694433.4439167 +1700 1577 -57643892.87044 +1701 1577 -11639352.31406 +1702 1577 9149300.058182 +1703 1577 -20870649.36111 +1578 1578 668782112.6068 +1579 1578 36667451.515 +1580 1578 3125095.269694 +1581 1578 18742492.4051 +1582 1578 -36666980.60238 +1583 1578 2754656.266036 +1587 1578 -52482483.83292 +1588 1578 -36666666.66064 +1589 1578 2453701.847473 +1590 1578 -139221200.1674 +1591 1578 1.877546310425e-06 +1592 1578 -671303.7191255 +1593 1578 -52506158.07532 +1594 1578 36666666.66064 +1595 1578 -2754631.485001 +1677 1578 -18569369.18862 +1678 1578 9166666.669678 +1679 1578 10279397.69313 +1680 1578 -72039530.38171 +1681 1578 -9166781.581061 +1682 1578 43189554.83944 +1686 1578 -1129879.778007 +1687 1578 2.369284629822e-06 +1688 1578 57871.28717239 +1689 1578 73599694.87993 +1690 1578 9166858.188655 +1691 1578 781226.7976368 +1692 1578 -19443104.86928 +1693 1578 -9166743.27727 +1694 1578 11639449.48452 +1698 1578 -18663081.30986 +1699 1578 -9166666.669677 +1700 1578 -10337268.9803 +1701 1578 -59964405.70834 +1702 1578 7.525086402893e-07 +1703 1578 -43970603.67818 +1704 1578 -20163436.42398 +1705 1578 9166666.669676 +1706 1578 -11639352.31406 +1579 1579 569774528.2723 +1580 1579 -8610907.219653 +1581 1579 -36667137.57325 +1582 1579 -109590390.9887 +1583 1579 4777683.581345 +1587 1579 -36666666.66065 +1588 1579 -41481680.36985 +1589 1579 1222199.953785 +1590 1579 1.594424247742e-06 +1591 1579 22113465.72052 +1592 1579 -2777733.240903 +1593 1579 36666666.66064 +1594 1579 -41505354.61226 +1595 1579 1555533.287118 +1677 1579 9166666.669678 +1678 1579 -15819170.72716 +1679 1579 -8385422.169798 +1680 1579 -9166743.277267 +1681 1579 -28955430.01587 +1682 1579 7996602.428466 +1686 1579 2.913177013397e-06 +1687 1579 -35963145.36236 +1688 1579 -33694466.44041 +1689 1579 9166858.188655 +1690 1579 48847822.54786 +1691 1579 -2152764.803778 +1692 1579 -9166781.581064 +1693 1579 -51526325.20493 +1694 1579 36236271.0855 +1698 1579 -9166666.669677 +1699 1579 -15912882.8484 +1700 1579 -8454866.614265 +1701 1579 3.725290298462e-07 +1702 1579 -19630743.20649 +1703 1579 -694433.4439167 +1704 1579 9166666.669676 +1705 1579 -17413237.96253 +1706 1579 9149300.058182 +1580 1580 599068063.3379 +1581 1580 2685224.212055 +1582 1580 5222138.335127 +1583 1580 35717984.23851 +1587 1580 2523146.291974 +1588 1580 1277755.509386 +1589 1580 -8359214.781975 +1590 1580 -254637.0525279 +1591 1580 -2777733.240903 +1592 1580 37788315.6602 +1593 1580 -2685187.040499 +1594 1580 1499977.731517 +1595 1580 -8422346.095089 +1677 1580 10279397.69313 +1678 1580 -8385422.169798 +1679 1580 -16619803.40013 +1680 1580 43154829.95728 +1681 1580 7802192.5578 +1682 1580 -56944833.0873 +1686 1580 57871.28717278 +1687 1580 -33666688.66265 +1688 1580 -39477172.9523 +1689 1580 781318.4370322 +1690 1580 -2152691.493423 +1691 1580 -99821807.80486 +1692 1580 11639498.06975 +1693 1580 36402939.91804 +1694 1580 -55413772.21342 +1698 1580 -10337268.9803 +1699 1580 -8454866.614265 +1700 1580 -16869702.39011 +1701 1580 -43935881.45598 +1702 1580 -694433.4439167 +1703 1580 -57643892.87044 +1704 1580 -11639352.31406 +1705 1580 9149300.058182 +1706 1580 -20870649.36111 +1581 1581 385435299.3209 +1582 1581 36666666.66064 +1583 1581 3703838.61297 +1590 1581 -52482483.83292 +1591 1581 -36666666.66064 +1592 1581 2453701.847473 +1593 1581 -203986384.4368 +1594 1581 -36666980.60238 +1595 1581 -2870486.454752 +1596 1581 12104621.19738 +1597 1581 29333647.27025 +1598 1581 -1944469.225024 +1680 1581 -4839277.140465 +1681 1581 11000114.915 +1682 1581 12370128.70975 +1689 1581 -14860172.33131 +1690 1581 -9166781.581062 +1691 1581 -10279526.39882 +1692 1581 33963705.33589 +1693 1581 9166666.669679 +1694 1581 9519894.71657 +1701 1581 -18663081.30986 +1702 1581 -9166666.669677 +1703 1581 -10337268.9803 +1704 1581 -73633660.33315 +1705 1581 -9166743.277268 +1706 1581 -44520628.22528 +1707 1581 -7828204.348046 +1708 1581 7333409.943332 +1709 1581 -9288430.506837 +1582 1582 330430928.8169 +1583 1582 -6111047.842687 +1590 1582 -36666666.66065 +1591 1582 -41481680.36985 +1592 1582 1222199.953785 +1593 1582 -36667137.57325 +1594 1582 -31649934.0022 +1595 1582 -3888890.401321 +1596 1582 44000470.90538 +1597 1582 12104621.19738 +1598 1582 2666690.447648 +1680 1582 7333409.943332 +1681 1582 -4839277.140466 +1682 1582 -6597291.372073 +1689 1582 -9166743.277267 +1690 1582 -46943392.66696 +1691 1582 -33736315.15602 +1692 1582 9166666.669679 +1693 1582 20212626.84424 +1694 1582 5347275.319281 +1701 1582 -9166666.669677 +1702 1582 -15912882.8484 +1703 1582 -8454866.614265 +1704 1582 -9166781.581064 +1705 1582 -30549559.96733 +1706 1582 -9732749.59088 +1707 1582 11000114.915 +1708 1582 -7828204.348045 +1709 1582 11145949.53617 +1583 1583 369852862.7392 +1590 1583 2523146.291974 +1591 1583 1277755.509386 +1592 1583 -8359214.781975 +1593 1583 -2453810.375638 +1594 1583 -3055549.140985 +1595 1583 -3321169.645782 +1596 1583 -2916703.837537 +1597 1583 1777793.631766 +1598 1583 32278989.8597 +1680 1583 8246752.473166 +1681 1583 -9895937.05811 +1682 1583 -12904739.04124 +1689 1583 -10279483.49692 +1690 1583 -33902984.10692 +1691 1583 -43192618.77883 +1692 1583 -8015196.919944 +1693 1583 -8680575.648187 +1694 1583 -73923722.2424 +1701 1583 -10337268.9803 +1702 1583 -8454866.614265 +1703 1583 -16869702.39011 +1704 1583 -44485903.34313 +1705 1583 -9538266.413314 +1706 1583 -61195846.2912 +1707 1583 -13932645.76025 +1708 1583 7430633.02411 +1709 1583 -20875211.59479 +1584 1584 616485232.3769 +1585 1584 1.227855682373e-05 +1586 1584 925940.7716047 +1587 1584 83364435.48308 +1588 1584 -6.437301635742e-06 +1589 1584 231485.1930161 +1599 1584 -139221200.1674 +1600 1584 1.877546310425e-06 +1601 1584 -671303.7191255 +1602 1584 -52506158.07532 +1603 1584 36666666.66064 +1604 1584 -2754631.485001 +1683 1584 -59565882.98117 +1684 1584 4.91738319397e-07 +1685 1584 43739118.52961 +1686 1584 -20057887.18154 +1687 1584 -9166666.669679 +1688 1584 11581481.02689 +1695 1584 54280296.46473 +1696 1584 3.09944152832e-06 +1697 1584 231485.1485852 +1698 1584 -7107625.989141 +1699 1584 -6.146728992462e-06 +1700 1584 57871.2871768 +1710 1584 -59964405.70834 +1711 1584 7.525086402893e-07 +1712 1584 -43970603.67818 +1713 1584 -20163436.42398 +1714 1584 9166666.669676 +1715 1584 -11639352.31406 +1585 1585 528478804.7157 +1586 1585 -11110932.95814 +1587 1585 -5.766749382019e-06 +1588 1585 -55968623.50036 +1589 1585 5722133.145708 +1599 1585 1.594424247742e-06 +1600 1585 22113465.72052 +1601 1585 -2777733.240903 +1602 1585 36666666.66064 +1603 1585 -41505354.61226 +1604 1585 1555533.287118 +1683 1585 -5.811452865601e-07 +1684 1585 -19232220.47929 +1685 1585 -694433.4439163 +1686 1585 -9166666.669679 +1687 1585 -17307688.72007 +1688 1585 9079855.613715 +1695 1585 3.635883331299e-06 +1696 1585 32278708.78388 +1697 1585 -2777733.774297 +1698 1585 -5.349516868591e-06 +1699 1585 -41940891.5735 +1700 1585 36472200.21471 +1710 1585 3.725290298462e-07 +1711 1585 -19630743.20649 +1712 1585 -694433.4439167 +1713 1585 9166666.669676 +1714 1585 -17413237.96253 +1715 1585 9149300.058182 +1586 1586 591208016.6774 +1587 1586 231485.1930168 +1588 1586 5388799.81243 +1589 1586 76448462.46728 +1599 1586 -254637.0525279 +1600 1586 -2777733.240903 +1601 1586 37788315.6602 +1602 1586 -2685187.040499 +1603 1586 1499977.731517 +1604 1586 -8422346.095089 +1683 1586 43704396.30741 +1684 1586 -694433.4439163 +1685 1586 -56581165.5979 +1686 1586 11581481.02689 +1687 1586 9079855.613715 +1688 1586 -20589184.71456 +1695 1586 231485.148585 +1696 1586 -2777733.774298 +1697 1586 -118440658.1206 +1698 1586 57871.28717716 +1699 1586 36444422.43695 +1700 1586 -55417829.51533 +1710 1586 -43935881.45598 +1711 1586 -694433.4439167 +1712 1586 -57643892.87044 +1713 1586 -11639352.31406 +1714 1586 9149300.058182 +1715 1586 -20870649.36111 +1587 1587 616485232.3769 +1588 1587 1.227855682373e-05 +1589 1587 925940.7716047 +1590 1587 83364435.48308 +1591 1587 -6.437301635742e-06 +1592 1587 231485.1930161 +1599 1587 -52482483.83292 +1600 1587 -36666666.66064 +1601 1587 2453701.847473 +1602 1587 -139221200.1674 +1603 1587 1.877546310425e-06 +1604 1587 -671303.7191255 +1605 1587 -52506158.07532 +1606 1587 36666666.66064 +1607 1587 -2754631.485001 +1683 1587 -18569369.18862 +1684 1587 9166666.669678 +1685 1587 10279397.69313 +1686 1587 -59565882.98117 +1687 1587 4.91738319397e-07 +1688 1587 43739118.52961 +1689 1587 -20057887.18154 +1690 1587 -9166666.669679 +1691 1587 11581481.02689 +1695 1587 -1129879.778007 +1696 1587 2.369284629822e-06 +1697 1587 57871.28717239 +1698 1587 54280296.46473 +1699 1587 3.09944152832e-06 +1700 1587 231485.1485852 +1701 1587 -7107625.989141 +1702 1587 -6.146728992462e-06 +1703 1587 57871.2871768 +1710 1587 -18663081.30986 +1711 1587 -9166666.669677 +1712 1587 -10337268.9803 +1713 1587 -59964405.70834 +1714 1587 7.525086402893e-07 +1715 1587 -43970603.67818 +1716 1587 -20163436.42398 +1717 1587 9166666.669676 +1718 1587 -11639352.31406 +1588 1588 528478804.7157 +1589 1588 -11110932.95814 +1590 1588 -5.766749382019e-06 +1591 1588 -55968623.50036 +1592 1588 5722133.145708 +1599 1588 -36666666.66065 +1600 1588 -41481680.36985 +1601 1588 1222199.953785 +1602 1588 1.594424247742e-06 +1603 1588 22113465.72052 +1604 1588 -2777733.240903 +1605 1588 36666666.66064 +1606 1588 -41505354.61226 +1607 1588 1555533.287118 +1683 1588 9166666.669678 +1684 1588 -15819170.72716 +1685 1588 -8385422.169798 +1686 1588 -5.811452865601e-07 +1687 1588 -19232220.47929 +1688 1588 -694433.4439163 +1689 1588 -9166666.669679 +1690 1588 -17307688.72007 +1691 1588 9079855.613715 +1695 1588 2.913177013397e-06 +1696 1588 -35963145.36236 +1697 1588 -33694466.44041 +1698 1588 3.635883331299e-06 +1699 1588 32278708.78388 +1700 1588 -2777733.774297 +1701 1588 -5.349516868591e-06 +1702 1588 -41940891.5735 +1703 1588 36472200.21471 +1710 1588 -9166666.669677 +1711 1588 -15912882.8484 +1712 1588 -8454866.614265 +1713 1588 3.725290298462e-07 +1714 1588 -19630743.20649 +1715 1588 -694433.4439167 +1716 1588 9166666.669676 +1717 1588 -17413237.96253 +1718 1588 9149300.058182 +1589 1589 591208016.6774 +1590 1589 231485.1930168 +1591 1589 5388799.81243 +1592 1589 76448462.46728 +1599 1589 2523146.291974 +1600 1589 1277755.509386 +1601 1589 -8359214.781975 +1602 1589 -254637.0525279 +1603 1589 -2777733.240903 +1604 1589 37788315.6602 +1605 1589 -2685187.040499 +1606 1589 1499977.731517 +1607 1589 -8422346.095089 +1683 1589 10279397.69313 +1684 1589 -8385422.169798 +1685 1589 -16619803.40013 +1686 1589 43704396.30741 +1687 1589 -694433.4439163 +1688 1589 -56581165.5979 +1689 1589 11581481.02689 +1690 1589 9079855.613715 +1691 1589 -20589184.71456 +1695 1589 57871.28717278 +1696 1589 -33666688.66265 +1697 1589 -39477172.9523 +1698 1589 231485.148585 +1699 1589 -2777733.774298 +1700 1589 -118440658.1206 +1701 1589 57871.28717716 +1702 1589 36444422.43695 +1703 1589 -55417829.51533 +1710 1589 -10337268.9803 +1711 1589 -8454866.614265 +1712 1589 -16869702.39011 +1713 1589 -43935881.45598 +1714 1589 -694433.4439167 +1715 1589 -57643892.87044 +1716 1589 -11639352.31406 +1717 1589 9149300.058182 +1718 1589 -20870649.36111 +1590 1590 616485232.3769 +1591 1590 1.227855682373e-05 +1592 1590 925940.7716047 +1593 1590 83364435.48308 +1594 1590 -6.437301635742e-06 +1595 1590 231485.1930161 +1602 1590 -52482483.83292 +1603 1590 -36666666.66064 +1604 1590 2453701.847473 +1605 1590 -139221200.1674 +1606 1590 1.877546310425e-06 +1607 1590 -671303.7191255 +1608 1590 -52506158.07532 +1609 1590 36666666.66064 +1610 1590 -2754631.485001 +1686 1590 -18569369.18862 +1687 1590 9166666.669678 +1688 1590 10279397.69313 +1689 1590 -59565882.98117 +1690 1590 4.91738319397e-07 +1691 1590 43739118.52961 +1692 1590 -20057887.18154 +1693 1590 -9166666.669679 +1694 1590 11581481.02689 +1698 1590 -1129879.778007 +1699 1590 2.369284629822e-06 +1700 1590 57871.28717239 +1701 1590 54280296.46473 +1702 1590 3.09944152832e-06 +1703 1590 231485.1485852 +1704 1590 -7107625.989141 +1705 1590 -6.146728992462e-06 +1706 1590 57871.2871768 +1713 1590 -18663081.30986 +1714 1590 -9166666.669677 +1715 1590 -10337268.9803 +1716 1590 -59964405.70834 +1717 1590 7.525086402893e-07 +1718 1590 -43970603.67818 +1719 1590 -20163436.42398 +1720 1590 9166666.669676 +1721 1590 -11639352.31406 +1591 1591 528478804.7157 +1592 1591 -11110932.95814 +1593 1591 -5.766749382019e-06 +1594 1591 -55968623.50036 +1595 1591 5722133.145708 +1602 1591 -36666666.66065 +1603 1591 -41481680.36985 +1604 1591 1222199.953785 +1605 1591 1.594424247742e-06 +1606 1591 22113465.72052 +1607 1591 -2777733.240903 +1608 1591 36666666.66064 +1609 1591 -41505354.61226 +1610 1591 1555533.287118 +1686 1591 9166666.669678 +1687 1591 -15819170.72716 +1688 1591 -8385422.169798 +1689 1591 -5.811452865601e-07 +1690 1591 -19232220.47929 +1691 1591 -694433.4439163 +1692 1591 -9166666.669679 +1693 1591 -17307688.72007 +1694 1591 9079855.613715 +1698 1591 2.913177013397e-06 +1699 1591 -35963145.36236 +1700 1591 -33694466.44041 +1701 1591 3.635883331299e-06 +1702 1591 32278708.78388 +1703 1591 -2777733.774297 +1704 1591 -5.349516868591e-06 +1705 1591 -41940891.5735 +1706 1591 36472200.21471 +1713 1591 -9166666.669677 +1714 1591 -15912882.8484 +1715 1591 -8454866.614265 +1716 1591 3.725290298462e-07 +1717 1591 -19630743.20649 +1718 1591 -694433.4439167 +1719 1591 9166666.669676 +1720 1591 -17413237.96253 +1721 1591 9149300.058182 +1592 1592 591208016.6774 +1593 1592 231485.1930168 +1594 1592 5388799.81243 +1595 1592 76448462.46728 +1602 1592 2523146.291974 +1603 1592 1277755.509386 +1604 1592 -8359214.781975 +1605 1592 -254637.0525279 +1606 1592 -2777733.240903 +1607 1592 37788315.6602 +1608 1592 -2685187.040499 +1609 1592 1499977.731517 +1610 1592 -8422346.095089 +1686 1592 10279397.69313 +1687 1592 -8385422.169798 +1688 1592 -16619803.40013 +1689 1592 43704396.30741 +1690 1592 -694433.4439163 +1691 1592 -56581165.5979 +1692 1592 11581481.02689 +1693 1592 9079855.613715 +1694 1592 -20589184.71456 +1698 1592 57871.28717278 +1699 1592 -33666688.66265 +1700 1592 -39477172.9523 +1701 1592 231485.148585 +1702 1592 -2777733.774298 +1703 1592 -118440658.1206 +1704 1592 57871.28717716 +1705 1592 36444422.43695 +1706 1592 -55417829.51533 +1713 1592 -10337268.9803 +1714 1592 -8454866.614265 +1715 1592 -16869702.39011 +1716 1592 -43935881.45598 +1717 1592 -694433.4439167 +1718 1592 -57643892.87044 +1719 1592 -11639352.31406 +1720 1592 9149300.058182 +1721 1592 -20870649.36111 +1593 1593 668782112.6068 +1594 1593 36667451.515 +1595 1593 3125095.269694 +1596 1593 18742492.4051 +1597 1593 -36666980.60238 +1598 1593 2754656.266036 +1605 1593 -52482483.83292 +1606 1593 -36666666.66064 +1607 1593 2453701.847473 +1608 1593 -139221200.1674 +1609 1593 1.877546310425e-06 +1610 1593 -671303.7191255 +1611 1593 -52506158.07532 +1612 1593 36666666.66064 +1613 1593 -2754631.485001 +1689 1593 -18569369.18862 +1690 1593 9166666.669678 +1691 1593 10279397.69313 +1692 1593 -72039530.38171 +1693 1593 -9166781.581061 +1694 1593 43189554.83944 +1701 1593 -1129879.778007 +1702 1593 2.369284629822e-06 +1703 1593 57871.28717239 +1704 1593 73599694.87993 +1705 1593 9166858.188655 +1706 1593 781226.7976368 +1707 1593 -19443104.86928 +1708 1593 -9166743.27727 +1709 1593 11639449.48452 +1716 1593 -18663081.30986 +1717 1593 -9166666.669677 +1718 1593 -10337268.9803 +1719 1593 -59964405.70834 +1720 1593 7.525086402893e-07 +1721 1593 -43970603.67818 +1722 1593 -20163436.42398 +1723 1593 9166666.669676 +1724 1593 -11639352.31406 +1594 1594 569774528.2723 +1595 1594 -8610907.219653 +1596 1594 -36667137.57325 +1597 1594 -109590390.9887 +1598 1594 4777683.581345 +1605 1594 -36666666.66065 +1606 1594 -41481680.36985 +1607 1594 1222199.953785 +1608 1594 1.594424247742e-06 +1609 1594 22113465.72052 +1610 1594 -2777733.240903 +1611 1594 36666666.66064 +1612 1594 -41505354.61226 +1613 1594 1555533.287118 +1689 1594 9166666.669678 +1690 1594 -15819170.72716 +1691 1594 -8385422.169798 +1692 1594 -9166743.277267 +1693 1594 -28955430.01587 +1694 1594 7996602.428466 +1701 1594 2.913177013397e-06 +1702 1594 -35963145.36236 +1703 1594 -33694466.44041 +1704 1594 9166858.188655 +1705 1594 48847822.54786 +1706 1594 -2152764.803778 +1707 1594 -9166781.581064 +1708 1594 -51526325.20493 +1709 1594 36236271.0855 +1716 1594 -9166666.669677 +1717 1594 -15912882.8484 +1718 1594 -8454866.614265 +1719 1594 3.725290298462e-07 +1720 1594 -19630743.20649 +1721 1594 -694433.4439167 +1722 1594 9166666.669676 +1723 1594 -17413237.96253 +1724 1594 9149300.058182 +1595 1595 599068063.3379 +1596 1595 2685224.212055 +1597 1595 5222138.335127 +1598 1595 35717984.23851 +1605 1595 2523146.291974 +1606 1595 1277755.509386 +1607 1595 -8359214.781975 +1608 1595 -254637.0525279 +1609 1595 -2777733.240903 +1610 1595 37788315.6602 +1611 1595 -2685187.040499 +1612 1595 1499977.731517 +1613 1595 -8422346.095089 +1689 1595 10279397.69313 +1690 1595 -8385422.169798 +1691 1595 -16619803.40013 +1692 1595 43154829.95728 +1693 1595 7802192.5578 +1694 1595 -56944833.0873 +1701 1595 57871.28717278 +1702 1595 -33666688.66265 +1703 1595 -39477172.9523 +1704 1595 781318.4370322 +1705 1595 -2152691.493423 +1706 1595 -99821807.80486 +1707 1595 11639498.06975 +1708 1595 36402939.91804 +1709 1595 -55413772.21342 +1716 1595 -10337268.9803 +1717 1595 -8454866.614265 +1718 1595 -16869702.39011 +1719 1595 -43935881.45598 +1720 1595 -694433.4439167 +1721 1595 -57643892.87044 +1722 1595 -11639352.31406 +1723 1595 9149300.058182 +1724 1595 -20870649.36111 +1596 1596 385435299.3209 +1597 1596 36666666.66064 +1598 1596 3703838.61297 +1608 1596 -52482483.83292 +1609 1596 -36666666.66064 +1610 1596 2453701.847473 +1611 1596 -203986384.4368 +1612 1596 -36666980.60238 +1613 1596 -2870486.454752 +1614 1596 12104621.19738 +1615 1596 29333647.27025 +1616 1596 -1944469.225024 +1692 1596 -4839277.140465 +1693 1596 11000114.915 +1694 1596 12370128.70975 +1704 1596 -14860172.33131 +1705 1596 -9166781.581062 +1706 1596 -10279526.39882 +1707 1596 33963705.33589 +1708 1596 9166666.669679 +1709 1596 9519894.71657 +1719 1596 -18663081.30986 +1720 1596 -9166666.669677 +1721 1596 -10337268.9803 +1722 1596 -73633660.33315 +1723 1596 -9166743.277268 +1724 1596 -44520628.22528 +1725 1596 -7828204.348046 +1726 1596 7333409.943332 +1727 1596 -9288430.506837 +1597 1597 330430928.8169 +1598 1597 -6111047.842687 +1608 1597 -36666666.66065 +1609 1597 -41481680.36985 +1610 1597 1222199.953785 +1611 1597 -36667137.57325 +1612 1597 -31649934.0022 +1613 1597 -3888890.401321 +1614 1597 44000470.90538 +1615 1597 12104621.19738 +1616 1597 2666690.447648 +1692 1597 7333409.943332 +1693 1597 -4839277.140466 +1694 1597 -6597291.372073 +1704 1597 -9166743.277267 +1705 1597 -46943392.66696 +1706 1597 -33736315.15602 +1707 1597 9166666.669679 +1708 1597 20212626.84424 +1709 1597 5347275.319281 +1719 1597 -9166666.669677 +1720 1597 -15912882.8484 +1721 1597 -8454866.614265 +1722 1597 -9166781.581064 +1723 1597 -30549559.96733 +1724 1597 -9732749.59088 +1725 1597 11000114.915 +1726 1597 -7828204.348045 +1727 1597 11145949.53617 +1598 1598 369852862.7392 +1608 1598 2523146.291974 +1609 1598 1277755.509386 +1610 1598 -8359214.781975 +1611 1598 -2453810.375638 +1612 1598 -3055549.140985 +1613 1598 -3321169.645782 +1614 1598 -2916703.837537 +1615 1598 1777793.631766 +1616 1598 32278989.8597 +1692 1598 8246752.473166 +1693 1598 -9895937.05811 +1694 1598 -12904739.04124 +1704 1598 -10279483.49692 +1705 1598 -33902984.10692 +1706 1598 -43192618.77883 +1707 1598 -8015196.919944 +1708 1598 -8680575.648187 +1709 1598 -73923722.2424 +1719 1598 -10337268.9803 +1720 1598 -8454866.614265 +1721 1598 -16869702.39011 +1722 1598 -44485903.34313 +1723 1598 -9538266.413314 +1724 1598 -61195846.2912 +1725 1598 -13932645.76025 +1726 1598 7430633.02411 +1727 1598 -20875211.59479 +1599 1599 616485232.3769 +1600 1599 1.227855682373e-05 +1601 1599 925940.7716047 +1602 1599 83364435.48308 +1603 1599 -6.437301635742e-06 +1604 1599 231485.1930161 +1617 1599 -139221200.1674 +1618 1599 1.877546310425e-06 +1619 1599 -671303.7191255 +1620 1599 -52506158.07532 +1621 1599 36666666.66064 +1622 1599 -2754631.485001 +1695 1599 -59565882.98117 +1696 1599 4.91738319397e-07 +1697 1599 43739118.52961 +1698 1599 -20057887.18154 +1699 1599 -9166666.669679 +1700 1599 11581481.02689 +1710 1599 54280296.46473 +1711 1599 3.09944152832e-06 +1712 1599 231485.1485852 +1713 1599 -7107625.989141 +1714 1599 -6.146728992462e-06 +1715 1599 57871.2871768 +1728 1599 -59964405.70834 +1729 1599 7.525086402893e-07 +1730 1599 -43970603.67818 +1731 1599 -20163436.42398 +1732 1599 9166666.669676 +1733 1599 -11639352.31406 +1600 1600 528478804.7157 +1601 1600 -11110932.95814 +1602 1600 -5.766749382019e-06 +1603 1600 -55968623.50036 +1604 1600 5722133.145708 +1617 1600 1.594424247742e-06 +1618 1600 22113465.72052 +1619 1600 -2777733.240903 +1620 1600 36666666.66064 +1621 1600 -41505354.61226 +1622 1600 1555533.287118 +1695 1600 -5.811452865601e-07 +1696 1600 -19232220.47929 +1697 1600 -694433.4439163 +1698 1600 -9166666.669679 +1699 1600 -17307688.72007 +1700 1600 9079855.613715 +1710 1600 3.635883331299e-06 +1711 1600 32278708.78388 +1712 1600 -2777733.774297 +1713 1600 -5.349516868591e-06 +1714 1600 -41940891.5735 +1715 1600 36472200.21471 +1728 1600 3.725290298462e-07 +1729 1600 -19630743.20649 +1730 1600 -694433.4439167 +1731 1600 9166666.669676 +1732 1600 -17413237.96253 +1733 1600 9149300.058182 +1601 1601 591208016.6774 +1602 1601 231485.1930168 +1603 1601 5388799.81243 +1604 1601 76448462.46728 +1617 1601 -254637.0525279 +1618 1601 -2777733.240903 +1619 1601 37788315.6602 +1620 1601 -2685187.040499 +1621 1601 1499977.731517 +1622 1601 -8422346.095089 +1695 1601 43704396.30741 +1696 1601 -694433.4439163 +1697 1601 -56581165.5979 +1698 1601 11581481.02689 +1699 1601 9079855.613715 +1700 1601 -20589184.71456 +1710 1601 231485.148585 +1711 1601 -2777733.774298 +1712 1601 -118440658.1206 +1713 1601 57871.28717716 +1714 1601 36444422.43695 +1715 1601 -55417829.51533 +1728 1601 -43935881.45598 +1729 1601 -694433.4439167 +1730 1601 -57643892.87044 +1731 1601 -11639352.31406 +1732 1601 9149300.058182 +1733 1601 -20870649.36111 +1602 1602 616485232.3769 +1603 1602 1.227855682373e-05 +1604 1602 925940.7716047 +1605 1602 83364435.48308 +1606 1602 -6.437301635742e-06 +1607 1602 231485.1930161 +1617 1602 -52482483.83292 +1618 1602 -36666666.66064 +1619 1602 2453701.847473 +1620 1602 -139221200.1674 +1621 1602 1.877546310425e-06 +1622 1602 -671303.7191255 +1623 1602 -52506158.07532 +1624 1602 36666666.66064 +1625 1602 -2754631.485001 +1695 1602 -18569369.18862 +1696 1602 9166666.669678 +1697 1602 10279397.69313 +1698 1602 -59565882.98117 +1699 1602 4.91738319397e-07 +1700 1602 43739118.52961 +1701 1602 -20057887.18154 +1702 1602 -9166666.669679 +1703 1602 11581481.02689 +1710 1602 -1129879.778007 +1711 1602 2.369284629822e-06 +1712 1602 57871.28717239 +1713 1602 54280296.46473 +1714 1602 3.09944152832e-06 +1715 1602 231485.1485852 +1716 1602 -7107625.989141 +1717 1602 -6.146728992462e-06 +1718 1602 57871.2871768 +1728 1602 -18663081.30986 +1729 1602 -9166666.669677 +1730 1602 -10337268.9803 +1731 1602 -59964405.70834 +1732 1602 7.525086402893e-07 +1733 1602 -43970603.67818 +1734 1602 -20163436.42398 +1735 1602 9166666.669676 +1736 1602 -11639352.31406 +1603 1603 528478804.7157 +1604 1603 -11110932.95814 +1605 1603 -5.766749382019e-06 +1606 1603 -55968623.50036 +1607 1603 5722133.145708 +1617 1603 -36666666.66065 +1618 1603 -41481680.36985 +1619 1603 1222199.953785 +1620 1603 1.594424247742e-06 +1621 1603 22113465.72052 +1622 1603 -2777733.240903 +1623 1603 36666666.66064 +1624 1603 -41505354.61226 +1625 1603 1555533.287118 +1695 1603 9166666.669678 +1696 1603 -15819170.72716 +1697 1603 -8385422.169798 +1698 1603 -5.811452865601e-07 +1699 1603 -19232220.47929 +1700 1603 -694433.4439163 +1701 1603 -9166666.669679 +1702 1603 -17307688.72007 +1703 1603 9079855.613715 +1710 1603 2.913177013397e-06 +1711 1603 -35963145.36236 +1712 1603 -33694466.44041 +1713 1603 3.635883331299e-06 +1714 1603 32278708.78388 +1715 1603 -2777733.774297 +1716 1603 -5.349516868591e-06 +1717 1603 -41940891.5735 +1718 1603 36472200.21471 +1728 1603 -9166666.669677 +1729 1603 -15912882.8484 +1730 1603 -8454866.614265 +1731 1603 3.725290298462e-07 +1732 1603 -19630743.20649 +1733 1603 -694433.4439167 +1734 1603 9166666.669676 +1735 1603 -17413237.96253 +1736 1603 9149300.058182 +1604 1604 591208016.6774 +1605 1604 231485.1930168 +1606 1604 5388799.81243 +1607 1604 76448462.46728 +1617 1604 2523146.291974 +1618 1604 1277755.509386 +1619 1604 -8359214.781975 +1620 1604 -254637.0525279 +1621 1604 -2777733.240903 +1622 1604 37788315.6602 +1623 1604 -2685187.040499 +1624 1604 1499977.731517 +1625 1604 -8422346.095089 +1695 1604 10279397.69313 +1696 1604 -8385422.169798 +1697 1604 -16619803.40013 +1698 1604 43704396.30741 +1699 1604 -694433.4439163 +1700 1604 -56581165.5979 +1701 1604 11581481.02689 +1702 1604 9079855.613715 +1703 1604 -20589184.71456 +1710 1604 57871.28717278 +1711 1604 -33666688.66265 +1712 1604 -39477172.9523 +1713 1604 231485.148585 +1714 1604 -2777733.774298 +1715 1604 -118440658.1206 +1716 1604 57871.28717716 +1717 1604 36444422.43695 +1718 1604 -55417829.51533 +1728 1604 -10337268.9803 +1729 1604 -8454866.614265 +1730 1604 -16869702.39011 +1731 1604 -43935881.45598 +1732 1604 -694433.4439167 +1733 1604 -57643892.87044 +1734 1604 -11639352.31406 +1735 1604 9149300.058182 +1736 1604 -20870649.36111 +1605 1605 616485232.3769 +1606 1605 1.227855682373e-05 +1607 1605 925940.7716047 +1608 1605 83364435.48308 +1609 1605 -6.437301635742e-06 +1610 1605 231485.1930161 +1620 1605 -52482483.83292 +1621 1605 -36666666.66064 +1622 1605 2453701.847473 +1623 1605 -139221200.1674 +1624 1605 1.877546310425e-06 +1625 1605 -671303.7191255 +1626 1605 -52506158.07532 +1627 1605 36666666.66064 +1628 1605 -2754631.485001 +1698 1605 -18569369.18862 +1699 1605 9166666.669678 +1700 1605 10279397.69313 +1701 1605 -59565882.98117 +1702 1605 4.91738319397e-07 +1703 1605 43739118.52961 +1704 1605 -20057887.18154 +1705 1605 -9166666.669679 +1706 1605 11581481.02689 +1713 1605 -1129879.778007 +1714 1605 2.369284629822e-06 +1715 1605 57871.28717239 +1716 1605 54280296.46473 +1717 1605 3.09944152832e-06 +1718 1605 231485.1485852 +1719 1605 -7107625.989141 +1720 1605 -6.146728992462e-06 +1721 1605 57871.2871768 +1731 1605 -18663081.30986 +1732 1605 -9166666.669677 +1733 1605 -10337268.9803 +1734 1605 -59964405.70834 +1735 1605 7.525086402893e-07 +1736 1605 -43970603.67818 +1737 1605 -20163436.42398 +1738 1605 9166666.669676 +1739 1605 -11639352.31406 +1606 1606 528478804.7157 +1607 1606 -11110932.95814 +1608 1606 -5.766749382019e-06 +1609 1606 -55968623.50036 +1610 1606 5722133.145708 +1620 1606 -36666666.66065 +1621 1606 -41481680.36985 +1622 1606 1222199.953785 +1623 1606 1.594424247742e-06 +1624 1606 22113465.72052 +1625 1606 -2777733.240903 +1626 1606 36666666.66064 +1627 1606 -41505354.61226 +1628 1606 1555533.287118 +1698 1606 9166666.669678 +1699 1606 -15819170.72716 +1700 1606 -8385422.169798 +1701 1606 -5.811452865601e-07 +1702 1606 -19232220.47929 +1703 1606 -694433.4439163 +1704 1606 -9166666.669679 +1705 1606 -17307688.72007 +1706 1606 9079855.613715 +1713 1606 2.913177013397e-06 +1714 1606 -35963145.36236 +1715 1606 -33694466.44041 +1716 1606 3.635883331299e-06 +1717 1606 32278708.78388 +1718 1606 -2777733.774297 +1719 1606 -5.349516868591e-06 +1720 1606 -41940891.5735 +1721 1606 36472200.21471 +1731 1606 -9166666.669677 +1732 1606 -15912882.8484 +1733 1606 -8454866.614265 +1734 1606 3.725290298462e-07 +1735 1606 -19630743.20649 +1736 1606 -694433.4439167 +1737 1606 9166666.669676 +1738 1606 -17413237.96253 +1739 1606 9149300.058182 +1607 1607 591208016.6774 +1608 1607 231485.1930168 +1609 1607 5388799.81243 +1610 1607 76448462.46728 +1620 1607 2523146.291974 +1621 1607 1277755.509386 +1622 1607 -8359214.781975 +1623 1607 -254637.0525279 +1624 1607 -2777733.240903 +1625 1607 37788315.6602 +1626 1607 -2685187.040499 +1627 1607 1499977.731517 +1628 1607 -8422346.095089 +1698 1607 10279397.69313 +1699 1607 -8385422.169798 +1700 1607 -16619803.40013 +1701 1607 43704396.30741 +1702 1607 -694433.4439163 +1703 1607 -56581165.5979 +1704 1607 11581481.02689 +1705 1607 9079855.613715 +1706 1607 -20589184.71456 +1713 1607 57871.28717278 +1714 1607 -33666688.66265 +1715 1607 -39477172.9523 +1716 1607 231485.148585 +1717 1607 -2777733.774298 +1718 1607 -118440658.1206 +1719 1607 57871.28717716 +1720 1607 36444422.43695 +1721 1607 -55417829.51533 +1731 1607 -10337268.9803 +1732 1607 -8454866.614265 +1733 1607 -16869702.39011 +1734 1607 -43935881.45598 +1735 1607 -694433.4439167 +1736 1607 -57643892.87044 +1737 1607 -11639352.31406 +1738 1607 9149300.058182 +1739 1607 -20870649.36111 +1608 1608 616485232.3769 +1609 1608 1.227855682373e-05 +1610 1608 925940.7716047 +1611 1608 83364435.48308 +1612 1608 -6.437301635742e-06 +1613 1608 231485.1930161 +1623 1608 -52482483.83292 +1624 1608 -36666666.66064 +1625 1608 2453701.847473 +1626 1608 -139221200.1674 +1627 1608 1.877546310425e-06 +1628 1608 -671303.7191255 +1629 1608 -52506158.07532 +1630 1608 36666666.66064 +1631 1608 -2754631.485001 +1701 1608 -18569369.18862 +1702 1608 9166666.669678 +1703 1608 10279397.69313 +1704 1608 -59565882.98117 +1705 1608 4.91738319397e-07 +1706 1608 43739118.52961 +1707 1608 -20057887.18154 +1708 1608 -9166666.669679 +1709 1608 11581481.02689 +1716 1608 -1129879.778007 +1717 1608 2.369284629822e-06 +1718 1608 57871.28717239 +1719 1608 54280296.46473 +1720 1608 3.09944152832e-06 +1721 1608 231485.1485852 +1722 1608 -7107625.989141 +1723 1608 -6.146728992462e-06 +1724 1608 57871.2871768 +1734 1608 -18663081.30986 +1735 1608 -9166666.669677 +1736 1608 -10337268.9803 +1737 1608 -59964405.70834 +1738 1608 7.525086402893e-07 +1739 1608 -43970603.67818 +1740 1608 -20163436.42398 +1741 1608 9166666.669676 +1742 1608 -11639352.31406 +1609 1609 528478804.7157 +1610 1609 -11110932.95814 +1611 1609 -5.766749382019e-06 +1612 1609 -55968623.50036 +1613 1609 5722133.145708 +1623 1609 -36666666.66065 +1624 1609 -41481680.36985 +1625 1609 1222199.953785 +1626 1609 1.594424247742e-06 +1627 1609 22113465.72052 +1628 1609 -2777733.240903 +1629 1609 36666666.66064 +1630 1609 -41505354.61226 +1631 1609 1555533.287118 +1701 1609 9166666.669678 +1702 1609 -15819170.72716 +1703 1609 -8385422.169798 +1704 1609 -5.811452865601e-07 +1705 1609 -19232220.47929 +1706 1609 -694433.4439163 +1707 1609 -9166666.669679 +1708 1609 -17307688.72007 +1709 1609 9079855.613715 +1716 1609 2.913177013397e-06 +1717 1609 -35963145.36236 +1718 1609 -33694466.44041 +1719 1609 3.635883331299e-06 +1720 1609 32278708.78388 +1721 1609 -2777733.774297 +1722 1609 -5.349516868591e-06 +1723 1609 -41940891.5735 +1724 1609 36472200.21471 +1734 1609 -9166666.669677 +1735 1609 -15912882.8484 +1736 1609 -8454866.614265 +1737 1609 3.725290298462e-07 +1738 1609 -19630743.20649 +1739 1609 -694433.4439167 +1740 1609 9166666.669676 +1741 1609 -17413237.96253 +1742 1609 9149300.058182 +1610 1610 591208016.6774 +1611 1610 231485.1930168 +1612 1610 5388799.81243 +1613 1610 76448462.46728 +1623 1610 2523146.291974 +1624 1610 1277755.509386 +1625 1610 -8359214.781975 +1626 1610 -254637.0525279 +1627 1610 -2777733.240903 +1628 1610 37788315.6602 +1629 1610 -2685187.040499 +1630 1610 1499977.731517 +1631 1610 -8422346.095089 +1701 1610 10279397.69313 +1702 1610 -8385422.169798 +1703 1610 -16619803.40013 +1704 1610 43704396.30741 +1705 1610 -694433.4439163 +1706 1610 -56581165.5979 +1707 1610 11581481.02689 +1708 1610 9079855.613715 +1709 1610 -20589184.71456 +1716 1610 57871.28717278 +1717 1610 -33666688.66265 +1718 1610 -39477172.9523 +1719 1610 231485.148585 +1720 1610 -2777733.774298 +1721 1610 -118440658.1206 +1722 1610 57871.28717716 +1723 1610 36444422.43695 +1724 1610 -55417829.51533 +1734 1610 -10337268.9803 +1735 1610 -8454866.614265 +1736 1610 -16869702.39011 +1737 1610 -43935881.45598 +1738 1610 -694433.4439167 +1739 1610 -57643892.87044 +1740 1610 -11639352.31406 +1741 1610 9149300.058182 +1742 1610 -20870649.36111 +1611 1611 668782112.6068 +1612 1611 36667451.515 +1613 1611 3125095.269694 +1614 1611 18742492.4051 +1615 1611 -36666980.60238 +1616 1611 2754656.266036 +1626 1611 -52482483.83292 +1627 1611 -36666666.66064 +1628 1611 2453701.847473 +1629 1611 -139221200.1674 +1630 1611 1.877546310425e-06 +1631 1611 -671303.7191255 +1632 1611 -52506158.07532 +1633 1611 36666666.66064 +1634 1611 -2754631.485001 +1704 1611 -18569369.18862 +1705 1611 9166666.669678 +1706 1611 10279397.69313 +1707 1611 -72039530.38171 +1708 1611 -9166781.581061 +1709 1611 43189554.83944 +1719 1611 -1129879.778007 +1720 1611 2.369284629822e-06 +1721 1611 57871.28717239 +1722 1611 73599694.87993 +1723 1611 9166858.188655 +1724 1611 781226.7976368 +1725 1611 -19443104.86928 +1726 1611 -9166743.27727 +1727 1611 11639449.48452 +1737 1611 -18663081.30986 +1738 1611 -9166666.669677 +1739 1611 -10337268.9803 +1740 1611 -59964405.70834 +1741 1611 7.525086402893e-07 +1742 1611 -43970603.67818 +1743 1611 -20163436.42398 +1744 1611 9166666.669676 +1745 1611 -11639352.31406 +1612 1612 569774528.2723 +1613 1612 -8610907.219653 +1614 1612 -36667137.57325 +1615 1612 -109590390.9887 +1616 1612 4777683.581345 +1626 1612 -36666666.66065 +1627 1612 -41481680.36985 +1628 1612 1222199.953785 +1629 1612 1.594424247742e-06 +1630 1612 22113465.72052 +1631 1612 -2777733.240903 +1632 1612 36666666.66064 +1633 1612 -41505354.61226 +1634 1612 1555533.287118 +1704 1612 9166666.669678 +1705 1612 -15819170.72716 +1706 1612 -8385422.169798 +1707 1612 -9166743.277267 +1708 1612 -28955430.01587 +1709 1612 7996602.428466 +1719 1612 2.913177013397e-06 +1720 1612 -35963145.36236 +1721 1612 -33694466.44041 +1722 1612 9166858.188655 +1723 1612 48847822.54786 +1724 1612 -2152764.803778 +1725 1612 -9166781.581064 +1726 1612 -51526325.20493 +1727 1612 36236271.0855 +1737 1612 -9166666.669677 +1738 1612 -15912882.8484 +1739 1612 -8454866.614265 +1740 1612 3.725290298462e-07 +1741 1612 -19630743.20649 +1742 1612 -694433.4439167 +1743 1612 9166666.669676 +1744 1612 -17413237.96253 +1745 1612 9149300.058182 +1613 1613 599068063.3379 +1614 1613 2685224.212055 +1615 1613 5222138.335127 +1616 1613 35717984.23851 +1626 1613 2523146.291974 +1627 1613 1277755.509386 +1628 1613 -8359214.781975 +1629 1613 -254637.0525279 +1630 1613 -2777733.240903 +1631 1613 37788315.6602 +1632 1613 -2685187.040499 +1633 1613 1499977.731517 +1634 1613 -8422346.095089 +1704 1613 10279397.69313 +1705 1613 -8385422.169798 +1706 1613 -16619803.40013 +1707 1613 43154829.95728 +1708 1613 7802192.5578 +1709 1613 -56944833.0873 +1719 1613 57871.28717278 +1720 1613 -33666688.66265 +1721 1613 -39477172.9523 +1722 1613 781318.4370322 +1723 1613 -2152691.493423 +1724 1613 -99821807.80486 +1725 1613 11639498.06975 +1726 1613 36402939.91804 +1727 1613 -55413772.21342 +1737 1613 -10337268.9803 +1738 1613 -8454866.614265 +1739 1613 -16869702.39011 +1740 1613 -43935881.45598 +1741 1613 -694433.4439167 +1742 1613 -57643892.87044 +1743 1613 -11639352.31406 +1744 1613 9149300.058182 +1745 1613 -20870649.36111 +1614 1614 655735355.2101 +1615 1614 -31117212.66892 +1616 1614 -17334.85400189 +1629 1614 -52482483.83292 +1630 1614 -36666666.66064 +1631 1614 2453701.847473 +1632 1614 -47267674.59853 +1633 1614 31108306.68764 +1634 1614 -538116.1871277 +1635 1614 -460334096.3009 +1636 1614 29342239.3098 +1637 1614 -116.4260834567 +1707 1614 -4839277.140465 +1708 1614 11000114.915 +1709 1614 12370128.70975 +1722 1614 -14860172.33131 +1723 1614 -9166781.581062 +1724 1614 -10279526.39882 +1725 1614 84600329.791 +1726 1614 -7355166.008999 +1727 1614 4551627.348748 +1740 1614 -18663081.30986 +1741 1614 -9166666.669677 +1742 1614 -10337268.9803 +1743 1614 -26443017.83902 +1744 1614 7353613.14478 +1745 1614 -24169752.6984 +1746 1614 -81188509.12609 +1747 1614 7334886.199962 +1748 1614 -937425.4063848 +1615 1615 1399825463.238 +1616 1615 -15271235.38801 +1629 1615 -36666666.66065 +1630 1615 -41481680.36985 +1631 1615 1222199.953785 +1632 1615 31103853.69702 +1633 1615 94613187.18359 +1634 1615 -2022211.413523 +1635 1615 44013358.96467 +1636 1615 -1228972986.18 +1637 1615 10408237.60212 +1707 1615 7333409.943332 +1708 1615 -4839277.140466 +1709 1615 -6597291.372073 +1722 1615 -9166743.277267 +1723 1615 -46943392.66696 +1724 1615 -33736315.15602 +1725 1615 -7355166.008999 +1726 1615 212115402.7313 +1727 1615 562018.4294399 +1740 1615 -9166666.669677 +1741 1615 -15912882.8484 +1742 1615 -8454866.614265 +1743 1615 7352836.71267 +1744 1615 9214022.79247 +1745 1615 6548490.870986 +1746 1615 11002329.29994 +1747 1615 -215027600.8237 +1748 1615 18640210.33911 +1616 1616 686859776.2503 +1629 1616 2523146.291974 +1630 1616 1277755.509386 +1631 1616 -8359214.781975 +1632 1616 -815841.7076854 +1633 1616 -1743802.481929 +1634 1616 49749735.57039 +1635 1616 -174.6391257197 +1636 1616 10298292.41346 +1637 1616 -458918700.2564 +1707 1616 8246752.473166 +1708 1616 -9895937.05811 +1709 1616 -12904739.04124 +1722 1616 -10279483.49692 +1723 1616 -33902984.10692 +1724 1616 -43192618.77883 +1725 1616 -5083833.776419 +1726 1616 -7145049.724392 +1727 1616 16202036.69247 +1740 1616 -10337268.9803 +1741 1616 -8454866.614265 +1742 1616 -16869702.39011 +1743 1616 -24343354.24807 +1744 1616 6577036.690483 +1745 1616 -24287985.05901 +1746 1616 -1406138.109577 +1747 1616 18265170.55897 +1748 1616 -82663599.30531 +1617 1617 616485232.3769 +1618 1617 1.227855682373e-05 +1619 1617 925940.7716047 +1620 1617 83364435.48308 +1621 1617 -6.437301635742e-06 +1622 1617 231485.1930161 +1638 1617 -139221200.1674 +1639 1617 1.877546310425e-06 +1640 1617 -671303.7191255 +1641 1617 -52506158.07532 +1642 1617 36666666.66064 +1643 1617 -2754631.485001 +1710 1617 -59565882.98117 +1711 1617 4.91738319397e-07 +1712 1617 43739118.52961 +1713 1617 -20057887.18154 +1714 1617 -9166666.669679 +1715 1617 11581481.02689 +1728 1617 54280296.46473 +1729 1617 3.09944152832e-06 +1730 1617 231485.1485852 +1731 1617 -7107625.989141 +1732 1617 -6.146728992462e-06 +1733 1617 57871.2871768 +1749 1617 -59964405.70834 +1750 1617 7.525086402893e-07 +1751 1617 -43970603.67818 +1752 1617 -20163436.42398 +1753 1617 9166666.669676 +1754 1617 -11639352.31406 +1618 1618 528478804.7157 +1619 1618 -11110932.95814 +1620 1618 -5.766749382019e-06 +1621 1618 -55968623.50036 +1622 1618 5722133.145708 +1638 1618 1.594424247742e-06 +1639 1618 22113465.72052 +1640 1618 -2777733.240903 +1641 1618 36666666.66064 +1642 1618 -41505354.61226 +1643 1618 1555533.287118 +1710 1618 -5.811452865601e-07 +1711 1618 -19232220.47929 +1712 1618 -694433.4439163 +1713 1618 -9166666.669679 +1714 1618 -17307688.72007 +1715 1618 9079855.613715 +1728 1618 3.635883331299e-06 +1729 1618 32278708.78388 +1730 1618 -2777733.774297 +1731 1618 -5.349516868591e-06 +1732 1618 -41940891.5735 +1733 1618 36472200.21471 +1749 1618 3.725290298462e-07 +1750 1618 -19630743.20649 +1751 1618 -694433.4439167 +1752 1618 9166666.669676 +1753 1618 -17413237.96253 +1754 1618 9149300.058182 +1619 1619 591208016.6774 +1620 1619 231485.1930168 +1621 1619 5388799.81243 +1622 1619 76448462.46728 +1638 1619 -254637.0525279 +1639 1619 -2777733.240903 +1640 1619 37788315.6602 +1641 1619 -2685187.040499 +1642 1619 1499977.731517 +1643 1619 -8422346.095089 +1710 1619 43704396.30741 +1711 1619 -694433.4439163 +1712 1619 -56581165.5979 +1713 1619 11581481.02689 +1714 1619 9079855.613715 +1715 1619 -20589184.71456 +1728 1619 231485.148585 +1729 1619 -2777733.774298 +1730 1619 -118440658.1206 +1731 1619 57871.28717716 +1732 1619 36444422.43695 +1733 1619 -55417829.51533 +1749 1619 -43935881.45598 +1750 1619 -694433.4439167 +1751 1619 -57643892.87044 +1752 1619 -11639352.31406 +1753 1619 9149300.058182 +1754 1619 -20870649.36111 +1620 1620 616485232.3769 +1621 1620 1.227855682373e-05 +1622 1620 925940.7716047 +1623 1620 83364435.48308 +1624 1620 -6.437301635742e-06 +1625 1620 231485.1930161 +1638 1620 -52482483.83292 +1639 1620 -36666666.66064 +1640 1620 2453701.847473 +1641 1620 -139221200.1674 +1642 1620 1.877546310425e-06 +1643 1620 -671303.7191255 +1644 1620 -52506158.07532 +1645 1620 36666666.66064 +1646 1620 -2754631.485001 +1710 1620 -18569369.18862 +1711 1620 9166666.669678 +1712 1620 10279397.69313 +1713 1620 -59565882.98117 +1714 1620 4.91738319397e-07 +1715 1620 43739118.52961 +1716 1620 -20057887.18154 +1717 1620 -9166666.669679 +1718 1620 11581481.02689 +1728 1620 -1129879.778007 +1729 1620 2.369284629822e-06 +1730 1620 57871.28717239 +1731 1620 54280296.46473 +1732 1620 3.09944152832e-06 +1733 1620 231485.1485852 +1734 1620 -7107625.989141 +1735 1620 -6.146728992462e-06 +1736 1620 57871.2871768 +1749 1620 -18663081.30986 +1750 1620 -9166666.669677 +1751 1620 -10337268.9803 +1752 1620 -59964405.70834 +1753 1620 7.525086402893e-07 +1754 1620 -43970603.67818 +1755 1620 -20163436.42398 +1756 1620 9166666.669676 +1757 1620 -11639352.31406 +1621 1621 528478804.7157 +1622 1621 -11110932.95814 +1623 1621 -5.766749382019e-06 +1624 1621 -55968623.50036 +1625 1621 5722133.145708 +1638 1621 -36666666.66065 +1639 1621 -41481680.36985 +1640 1621 1222199.953785 +1641 1621 1.594424247742e-06 +1642 1621 22113465.72052 +1643 1621 -2777733.240903 +1644 1621 36666666.66064 +1645 1621 -41505354.61226 +1646 1621 1555533.287118 +1710 1621 9166666.669678 +1711 1621 -15819170.72716 +1712 1621 -8385422.169798 +1713 1621 -5.811452865601e-07 +1714 1621 -19232220.47929 +1715 1621 -694433.4439163 +1716 1621 -9166666.669679 +1717 1621 -17307688.72007 +1718 1621 9079855.613715 +1728 1621 2.913177013397e-06 +1729 1621 -35963145.36236 +1730 1621 -33694466.44041 +1731 1621 3.635883331299e-06 +1732 1621 32278708.78388 +1733 1621 -2777733.774297 +1734 1621 -5.349516868591e-06 +1735 1621 -41940891.5735 +1736 1621 36472200.21471 +1749 1621 -9166666.669677 +1750 1621 -15912882.8484 +1751 1621 -8454866.614265 +1752 1621 3.725290298462e-07 +1753 1621 -19630743.20649 +1754 1621 -694433.4439167 +1755 1621 9166666.669676 +1756 1621 -17413237.96253 +1757 1621 9149300.058182 +1622 1622 591208016.6774 +1623 1622 231485.1930168 +1624 1622 5388799.81243 +1625 1622 76448462.46728 +1638 1622 2523146.291974 +1639 1622 1277755.509386 +1640 1622 -8359214.781975 +1641 1622 -254637.0525279 +1642 1622 -2777733.240903 +1643 1622 37788315.6602 +1644 1622 -2685187.040499 +1645 1622 1499977.731517 +1646 1622 -8422346.095089 +1710 1622 10279397.69313 +1711 1622 -8385422.169798 +1712 1622 -16619803.40013 +1713 1622 43704396.30741 +1714 1622 -694433.4439163 +1715 1622 -56581165.5979 +1716 1622 11581481.02689 +1717 1622 9079855.613715 +1718 1622 -20589184.71456 +1728 1622 57871.28717278 +1729 1622 -33666688.66265 +1730 1622 -39477172.9523 +1731 1622 231485.148585 +1732 1622 -2777733.774298 +1733 1622 -118440658.1206 +1734 1622 57871.28717716 +1735 1622 36444422.43695 +1736 1622 -55417829.51533 +1749 1622 -10337268.9803 +1750 1622 -8454866.614265 +1751 1622 -16869702.39011 +1752 1622 -43935881.45598 +1753 1622 -694433.4439167 +1754 1622 -57643892.87044 +1755 1622 -11639352.31406 +1756 1622 9149300.058182 +1757 1622 -20870649.36111 +1623 1623 616485232.3769 +1624 1623 1.227855682373e-05 +1625 1623 925940.7716047 +1626 1623 83364435.48308 +1627 1623 -6.437301635742e-06 +1628 1623 231485.1930161 +1641 1623 -52482483.83292 +1642 1623 -36666666.66064 +1643 1623 2453701.847473 +1644 1623 -139221200.1674 +1645 1623 1.877546310425e-06 +1646 1623 -671303.7191255 +1647 1623 -52506158.07532 +1648 1623 36666666.66064 +1649 1623 -2754631.485001 +1713 1623 -18569369.18862 +1714 1623 9166666.669678 +1715 1623 10279397.69313 +1716 1623 -59565882.98117 +1717 1623 4.91738319397e-07 +1718 1623 43739118.52961 +1719 1623 -20057887.18154 +1720 1623 -9166666.669679 +1721 1623 11581481.02689 +1731 1623 -1129879.778007 +1732 1623 2.369284629822e-06 +1733 1623 57871.28717239 +1734 1623 54280296.46473 +1735 1623 3.09944152832e-06 +1736 1623 231485.1485852 +1737 1623 -7107625.989141 +1738 1623 -6.146728992462e-06 +1739 1623 57871.2871768 +1752 1623 -18663081.30986 +1753 1623 -9166666.669677 +1754 1623 -10337268.9803 +1755 1623 -59964405.70834 +1756 1623 7.525086402893e-07 +1757 1623 -43970603.67818 +1758 1623 -20163436.42398 +1759 1623 9166666.669676 +1760 1623 -11639352.31406 +1624 1624 528478804.7157 +1625 1624 -11110932.95814 +1626 1624 -5.766749382019e-06 +1627 1624 -55968623.50036 +1628 1624 5722133.145708 +1641 1624 -36666666.66065 +1642 1624 -41481680.36985 +1643 1624 1222199.953785 +1644 1624 1.594424247742e-06 +1645 1624 22113465.72052 +1646 1624 -2777733.240903 +1647 1624 36666666.66064 +1648 1624 -41505354.61226 +1649 1624 1555533.287118 +1713 1624 9166666.669678 +1714 1624 -15819170.72716 +1715 1624 -8385422.169798 +1716 1624 -5.811452865601e-07 +1717 1624 -19232220.47929 +1718 1624 -694433.4439163 +1719 1624 -9166666.669679 +1720 1624 -17307688.72007 +1721 1624 9079855.613715 +1731 1624 2.913177013397e-06 +1732 1624 -35963145.36236 +1733 1624 -33694466.44041 +1734 1624 3.635883331299e-06 +1735 1624 32278708.78388 +1736 1624 -2777733.774297 +1737 1624 -5.349516868591e-06 +1738 1624 -41940891.5735 +1739 1624 36472200.21471 +1752 1624 -9166666.669677 +1753 1624 -15912882.8484 +1754 1624 -8454866.614265 +1755 1624 3.725290298462e-07 +1756 1624 -19630743.20649 +1757 1624 -694433.4439167 +1758 1624 9166666.669676 +1759 1624 -17413237.96253 +1760 1624 9149300.058182 +1625 1625 591208016.6774 +1626 1625 231485.1930168 +1627 1625 5388799.81243 +1628 1625 76448462.46728 +1641 1625 2523146.291974 +1642 1625 1277755.509386 +1643 1625 -8359214.781975 +1644 1625 -254637.0525279 +1645 1625 -2777733.240903 +1646 1625 37788315.6602 +1647 1625 -2685187.040499 +1648 1625 1499977.731517 +1649 1625 -8422346.095089 +1713 1625 10279397.69313 +1714 1625 -8385422.169798 +1715 1625 -16619803.40013 +1716 1625 43704396.30741 +1717 1625 -694433.4439163 +1718 1625 -56581165.5979 +1719 1625 11581481.02689 +1720 1625 9079855.613715 +1721 1625 -20589184.71456 +1731 1625 57871.28717278 +1732 1625 -33666688.66265 +1733 1625 -39477172.9523 +1734 1625 231485.148585 +1735 1625 -2777733.774298 +1736 1625 -118440658.1206 +1737 1625 57871.28717716 +1738 1625 36444422.43695 +1739 1625 -55417829.51533 +1752 1625 -10337268.9803 +1753 1625 -8454866.614265 +1754 1625 -16869702.39011 +1755 1625 -43935881.45598 +1756 1625 -694433.4439167 +1757 1625 -57643892.87044 +1758 1625 -11639352.31406 +1759 1625 9149300.058182 +1760 1625 -20870649.36111 +1626 1626 616485232.3769 +1627 1626 1.227855682373e-05 +1628 1626 925940.7716047 +1629 1626 83364435.48308 +1630 1626 -6.437301635742e-06 +1631 1626 231485.1930161 +1644 1626 -52482483.83292 +1645 1626 -36666666.66064 +1646 1626 2453701.847473 +1647 1626 -139221200.1674 +1648 1626 1.877546310425e-06 +1649 1626 -671303.7191255 +1650 1626 -52506158.07532 +1651 1626 36666666.66064 +1652 1626 -2754631.485001 +1716 1626 -18569369.18862 +1717 1626 9166666.669678 +1718 1626 10279397.69313 +1719 1626 -59565882.98117 +1720 1626 4.91738319397e-07 +1721 1626 43739118.52961 +1722 1626 -20057887.18154 +1723 1626 -9166666.669679 +1724 1626 11581481.02689 +1734 1626 -1129879.778007 +1735 1626 2.369284629822e-06 +1736 1626 57871.28717239 +1737 1626 54280296.46473 +1738 1626 3.09944152832e-06 +1739 1626 231485.1485852 +1740 1626 -7107625.989141 +1741 1626 -6.146728992462e-06 +1742 1626 57871.2871768 +1755 1626 -18663081.30986 +1756 1626 -9166666.669677 +1757 1626 -10337268.9803 +1758 1626 -59964405.70834 +1759 1626 7.525086402893e-07 +1760 1626 -43970603.67818 +1761 1626 -20163436.42398 +1762 1626 9166666.669676 +1763 1626 -11639352.31406 +1627 1627 528478804.7157 +1628 1627 -11110932.95814 +1629 1627 -5.766749382019e-06 +1630 1627 -55968623.50036 +1631 1627 5722133.145708 +1644 1627 -36666666.66065 +1645 1627 -41481680.36985 +1646 1627 1222199.953785 +1647 1627 1.594424247742e-06 +1648 1627 22113465.72052 +1649 1627 -2777733.240903 +1650 1627 36666666.66064 +1651 1627 -41505354.61226 +1652 1627 1555533.287118 +1716 1627 9166666.669678 +1717 1627 -15819170.72716 +1718 1627 -8385422.169798 +1719 1627 -5.811452865601e-07 +1720 1627 -19232220.47929 +1721 1627 -694433.4439163 +1722 1627 -9166666.669679 +1723 1627 -17307688.72007 +1724 1627 9079855.613715 +1734 1627 2.913177013397e-06 +1735 1627 -35963145.36236 +1736 1627 -33694466.44041 +1737 1627 3.635883331299e-06 +1738 1627 32278708.78388 +1739 1627 -2777733.774297 +1740 1627 -5.349516868591e-06 +1741 1627 -41940891.5735 +1742 1627 36472200.21471 +1755 1627 -9166666.669677 +1756 1627 -15912882.8484 +1757 1627 -8454866.614265 +1758 1627 3.725290298462e-07 +1759 1627 -19630743.20649 +1760 1627 -694433.4439167 +1761 1627 9166666.669676 +1762 1627 -17413237.96253 +1763 1627 9149300.058182 +1628 1628 591208016.6774 +1629 1628 231485.1930168 +1630 1628 5388799.81243 +1631 1628 76448462.46728 +1644 1628 2523146.291974 +1645 1628 1277755.509386 +1646 1628 -8359214.781975 +1647 1628 -254637.0525279 +1648 1628 -2777733.240903 +1649 1628 37788315.6602 +1650 1628 -2685187.040499 +1651 1628 1499977.731517 +1652 1628 -8422346.095089 +1716 1628 10279397.69313 +1717 1628 -8385422.169798 +1718 1628 -16619803.40013 +1719 1628 43704396.30741 +1720 1628 -694433.4439163 +1721 1628 -56581165.5979 +1722 1628 11581481.02689 +1723 1628 9079855.613715 +1724 1628 -20589184.71456 +1734 1628 57871.28717278 +1735 1628 -33666688.66265 +1736 1628 -39477172.9523 +1737 1628 231485.148585 +1738 1628 -2777733.774298 +1739 1628 -118440658.1206 +1740 1628 57871.28717716 +1741 1628 36444422.43695 +1742 1628 -55417829.51533 +1755 1628 -10337268.9803 +1756 1628 -8454866.614265 +1757 1628 -16869702.39011 +1758 1628 -43935881.45598 +1759 1628 -694433.4439167 +1760 1628 -57643892.87044 +1761 1628 -11639352.31406 +1762 1628 9149300.058182 +1763 1628 -20870649.36111 +1629 1629 616485232.3769 +1630 1629 1.227855682373e-05 +1631 1629 925940.7716047 +1632 1629 83364435.48308 +1633 1629 -6.437301635742e-06 +1634 1629 231485.1930161 +1647 1629 -52482483.83292 +1648 1629 -36666666.66064 +1649 1629 2453701.847473 +1650 1629 -139221200.1674 +1651 1629 1.877546310425e-06 +1652 1629 -671303.7191255 +1653 1629 -52506158.07532 +1654 1629 36666666.66064 +1655 1629 -2754631.485001 +1719 1629 -18569369.18862 +1720 1629 9166666.669678 +1721 1629 10279397.69313 +1722 1629 -59565882.98117 +1723 1629 4.91738319397e-07 +1724 1629 43739118.52961 +1725 1629 -20057887.18154 +1726 1629 -9166666.669679 +1727 1629 11581481.02689 +1737 1629 -1129879.778007 +1738 1629 2.369284629822e-06 +1739 1629 57871.28717239 +1740 1629 54280296.46473 +1741 1629 3.09944152832e-06 +1742 1629 231485.1485852 +1743 1629 -7107625.989141 +1744 1629 -6.146728992462e-06 +1745 1629 57871.2871768 +1758 1629 -18663081.30986 +1759 1629 -9166666.669677 +1760 1629 -10337268.9803 +1761 1629 -59964405.70834 +1762 1629 7.525086402893e-07 +1763 1629 -43970603.67818 +1764 1629 -20163436.42398 +1765 1629 9166666.669676 +1766 1629 -11639352.31406 +1630 1630 528478804.7157 +1631 1630 -11110932.95814 +1632 1630 -5.766749382019e-06 +1633 1630 -55968623.50036 +1634 1630 5722133.145708 +1647 1630 -36666666.66065 +1648 1630 -41481680.36985 +1649 1630 1222199.953785 +1650 1630 1.594424247742e-06 +1651 1630 22113465.72052 +1652 1630 -2777733.240903 +1653 1630 36666666.66064 +1654 1630 -41505354.61226 +1655 1630 1555533.287118 +1719 1630 9166666.669678 +1720 1630 -15819170.72716 +1721 1630 -8385422.169798 +1722 1630 -5.811452865601e-07 +1723 1630 -19232220.47929 +1724 1630 -694433.4439163 +1725 1630 -9166666.669679 +1726 1630 -17307688.72007 +1727 1630 9079855.613715 +1737 1630 2.913177013397e-06 +1738 1630 -35963145.36236 +1739 1630 -33694466.44041 +1740 1630 3.635883331299e-06 +1741 1630 32278708.78388 +1742 1630 -2777733.774297 +1743 1630 -5.349516868591e-06 +1744 1630 -41940891.5735 +1745 1630 36472200.21471 +1758 1630 -9166666.669677 +1759 1630 -15912882.8484 +1760 1630 -8454866.614265 +1761 1630 3.725290298462e-07 +1762 1630 -19630743.20649 +1763 1630 -694433.4439167 +1764 1630 9166666.669676 +1765 1630 -17413237.96253 +1766 1630 9149300.058182 +1631 1631 591208016.6774 +1632 1631 231485.1930168 +1633 1631 5388799.81243 +1634 1631 76448462.46728 +1647 1631 2523146.291974 +1648 1631 1277755.509386 +1649 1631 -8359214.781975 +1650 1631 -254637.0525279 +1651 1631 -2777733.240903 +1652 1631 37788315.6602 +1653 1631 -2685187.040499 +1654 1631 1499977.731517 +1655 1631 -8422346.095089 +1719 1631 10279397.69313 +1720 1631 -8385422.169798 +1721 1631 -16619803.40013 +1722 1631 43704396.30741 +1723 1631 -694433.4439163 +1724 1631 -56581165.5979 +1725 1631 11581481.02689 +1726 1631 9079855.613715 +1727 1631 -20589184.71456 +1737 1631 57871.28717278 +1738 1631 -33666688.66265 +1739 1631 -39477172.9523 +1740 1631 231485.148585 +1741 1631 -2777733.774298 +1742 1631 -118440658.1206 +1743 1631 57871.28717716 +1744 1631 36444422.43695 +1745 1631 -55417829.51533 +1758 1631 -10337268.9803 +1759 1631 -8454866.614265 +1760 1631 -16869702.39011 +1761 1631 -43935881.45598 +1762 1631 -694433.4439167 +1763 1631 -57643892.87044 +1764 1631 -11639352.31406 +1765 1631 9149300.058182 +1766 1631 -20870649.36111 +1632 1632 519928912.9843 +1633 1632 18284601.12091 +1634 1632 578761.350884 +1635 1632 -108612258.8245 +1636 1632 -79935938.68238 +1637 1632 842556.2480698 +1650 1632 -52482483.83292 +1651 1632 -36666666.66064 +1652 1632 2453701.847473 +1653 1632 -87335209.48903 +1654 1632 24505093.74398 +1655 1632 -363621.4604582 +1656 1632 -53017905.4468 +1657 1632 6042390.120481 +1658 1632 -241842.5188305 +1722 1632 -18569369.18862 +1723 1632 9166666.669678 +1724 1632 10279397.69313 +1725 1632 -25959619.6135 +1726 1632 7352836.71267 +1727 1632 23833951.37777 +1740 1632 -1129879.778007 +1741 1632 2.369284629822e-06 +1742 1632 57871.28717239 +1743 1632 64236492.00143 +1744 1632 4188504.580192 +1745 1632 152313.04164 +1746 1632 -37094686.27921 +1747 1632 -19583073.02575 +1748 1632 11156605.99291 +1761 1632 -18663081.30986 +1762 1632 -9166666.669677 +1763 1632 -10337268.9803 +1764 1632 -44289186.74016 +1765 1632 6104008.873161 +1766 1632 -34010528.30258 +1767 1632 -19096765.45373 +1768 1632 1937722.859732 +1769 1632 -1131791.351039 +1633 1633 665160657.0974 +1634 1633 -8200338.494416 +1635 1633 -79940391.673 +1636 1633 -270574059.2863 +1637 1633 1895212.372046 +1650 1633 -36666666.66065 +1651 1633 -41481680.36985 +1652 1633 1222199.953785 +1653 1633 24505093.74398 +1654 1633 9926729.013553 +1655 1633 -1216504.30871 +1656 1633 6042390.120481 +1657 1633 -158099197.3255 +1658 1633 1154465.064861 +1722 1633 9166666.669678 +1723 1633 -15819170.72716 +1724 1633 -8385422.169798 +1725 1633 7353613.144779 +1726 1633 9697421.018002 +1727 1633 -7489184.963696 +1740 1633 2.913177013397e-06 +1741 1633 -35963145.36236 +1742 1633 -33694466.44041 +1743 1633 4188504.58019 +1744 1633 98121188.26052 +1745 1633 -2022071.160098 +1746 1633 -19583849.45786 +1747 1633 -77002617.67255 +1748 1633 35507242.60329 +1761 1633 -9166666.669677 +1762 1633 -15912882.8484 +1763 1633 -8454866.614265 +1764 1633 6104008.87316 +1765 1633 -19204445.69136 +1766 1633 7593833.975638 +1767 1633 1937722.859732 +1768 1633 -44482443.33833 +1769 1633 16945375.52141 +1634 1634 503970173.8716 +1635 1634 773170.0166806 +1636 1634 1673626.128399 +1637 1634 -74740651.99144 +1650 1634 2523146.291974 +1651 1634 1277755.509386 +1652 1634 -8359214.781975 +1653 1634 -710843.6826246 +1654 1634 -1160948.753164 +1655 1634 40441461.7719 +1656 1634 -102953.6298271 +1657 1634 1154465.064861 +1658 1634 -40229865.61205 +1722 1634 10279397.69313 +1723 1634 -8385422.169798 +1724 1634 -16619803.40013 +1725 1634 24007552.92743 +1726 1634 -7516245.690184 +1727 1634 -22998923.12425 +1740 1634 57871.28717278 +1741 1634 -33666688.66265 +1742 1634 -39477172.9523 +1743 1634 152496.3906114 +1744 1634 -2021924.433862 +1745 1634 -48932710.54889 +1746 1634 11156707.58288 +1747 1634 35506599.20027 +1748 1634 -47133838.53141 +1761 1634 -10337268.9803 +1762 1634 -8454866.614265 +1763 1634 -16869702.39011 +1764 1634 -34184139.41185 +1765 1634 7593833.977188 +1766 1634 -49430632.70391 +1767 1634 -1131791.351039 +1768 1634 16945375.52141 +1769 1634 -26713473.31342 +1635 1635 817622030.6816 +1636 1635 18728335.5089 +1637 1635 650261.4885132 +1653 1635 -52289155.99191 +1654 1635 -31796218.63405 +1655 1635 272335.4986461 +1656 1635 40696773.02407 +1657 1635 41799857.02722 +1658 1635 -451578.6953159 +1659 1635 62907192.10629 +1660 1635 -21190039.75704 +1661 1635 -30718.70653248 +1662 1635 -302984.9272958 +1663 1635 28385098.56329 +1664 1635 -102183.8516526 +1725 1635 -80695196.04604 +1726 1635 11002329.29994 +1727 1635 1197745.226308 +1743 1635 -36237740.37331 +1744 1635 -19583849.45786 +1745 1635 -10761203.52545 +1746 1635 64918240.7767 +1747 1635 4545607.815533 +1748 1635 8549143.250188 +1764 1635 -19361814.47454 +1765 1635 -8033003.905469 +1766 1635 -10880711.7551 +1767 1635 -39542928.89608 +1768 1635 10179332.65207 +1769 1635 -42870672.366 +1770 1635 -23152016.19972 +1771 1635 -5245000.469661 +1772 1635 13937363.65238 +1773 1635 -16961001.23544 +1774 1635 7134584.065443 +1775 1635 -10455553.37126 +1636 1636 1676043355.975 +1637 1636 -10405897.15394 +1653 1636 -31796218.63405 +1654 1636 -13283312.79656 +1655 1636 -157557.8164433 +1656 1636 41799857.02722 +1657 1636 168116723.4543 +1658 1636 -653824.0004528 +1659 1636 -6523373.092781 +1660 1636 -7507584.898842 +1661 1636 58208.02223074 +1662 1636 28385098.56329 +1663 1636 -24134636.49954 +1664 1636 72437.49368545 +1725 1636 7334886.199962 +1726 1636 -214534287.7436 +1727 1636 -14727925.53035 +1743 1636 -19583073.02575 +1744 1636 -76145671.76667 +1745 1636 -34635700.01357 +1746 1636 4545607.815532 +1747 1636 220786408.8697 +1748 1636 -1651487.677043 +1764 1636 -8033003.905469 +1765 1636 -9894458.669336 +1766 1636 -8796010.290028 +1767 1636 10179332.65207 +1768 1636 -7663163.946107 +1769 1636 7746290.39215 +1770 1636 -1578333.801791 +1771 1636 -40769835.26372 +1772 1636 33347835.72267 +1773 1636 7134584.065443 +1774 1636 -22811447.92863 +1775 1636 16684645.6024 +1637 1637 973553864.9319 +1653 1637 341779.9431477 +1654 1637 -102002.2608421 +1655 1637 -512623.6482486 +1656 1637 -173800.9175837 +1657 1637 -598268.4449064 +1658 1637 194191502.4522 +1659 1637 38725.73790348 +1660 1637 58208.02223065 +1661 1637 125019736.2969 +1662 1637 -32739.40715139 +1663 1637 72437.49368545 +1664 1637 40573538.2614 +1725 1637 798496.8175386 +1726 1637 -15047477.02744 +1727 1637 -81348097.7585 +1743 1637 -10761121.78541 +1744 1637 -34636394.9925 +1745 1637 -44848649.44901 +1746 1637 -8568634.524779 +1747 1637 -2347417.099454 +1748 1637 -70370912.58102 +1764 1637 -10880711.7551 +1765 1637 -8796010.290028 +1766 1637 -16660073.13599 +1767 1637 -42870672.36604 +1768 1637 7746290.393699 +1769 1637 -82268491.96201 +1770 1637 5812363.651645 +1771 1637 33347835.72267 +1772 1637 -72589611.80809 +1773 1637 -10455553.37126 +1774 1637 16684645.6024 +1775 1637 -34667380.50116 +1638 1638 308237881.34 +1639 1638 6.914138793945e-06 +1640 1638 -578696.2806914 +1641 1638 41681428.60013 +1642 1638 7333333.332127 +1643 1638 -578701.847993 +1728 1638 -59565882.98117 +1729 1638 4.91738319397e-07 +1730 1638 43739118.52961 +1731 1638 -20057887.18154 +1732 1638 -9166666.669679 +1733 1638 11581481.02689 +1749 1638 27139753.66166 +1750 1638 8.344650268555e-07 +1751 1638 -8738562.979764 +1752 1638 -3553812.994569 +1753 1638 1833333.333932 +1754 1638 -2293147.690507 +1639 1639 264234667.5094 +1640 1639 -5555466.479065 +1641 1639 -7333333.33213 +1642 1639 -27985100.89159 +1643 1639 2833288.795082 +1728 1639 -5.811452865601e-07 +1729 1639 -19232220.47929 +1730 1639 -694433.4439163 +1731 1639 -9166666.669679 +1732 1639 -17307688.72007 +1733 1639 9079855.613715 +1749 1639 8.940696716309e-07 +1750 1639 16138959.82123 +1751 1639 -1388866.887151 +1752 1639 -1833333.333938 +1753 1639 -20970445.78675 +1754 1639 18229155.66291 +1640 1640 295591382.0761 +1641 1640 462964.8185019 +1642 1640 2722177.683989 +1643 1640 38222126.85654 +1728 1640 43704396.30741 +1729 1640 -694433.4439163 +1730 1640 -56581165.5979 +1731 1640 11581481.02689 +1732 1640 9079855.613715 +1733 1640 -20589184.71456 +1749 1640 8796437.017353 +1750 1640 -1388866.887151 +1751 1640 -59221381.24884 +1752 1640 2351018.977684 +1753 1640 18229155.66292 +1754 1640 -27708914.75766 +1641 1641 308237881.34 +1642 1641 6.914138793945e-06 +1643 1641 -578696.2806914 +1644 1641 41681428.60013 +1645 1641 7333333.332127 +1646 1641 -578701.847993 +1728 1641 -18569369.18862 +1729 1641 9166666.669678 +1730 1641 10279397.69313 +1731 1641 -59565882.98117 +1732 1641 4.91738319397e-07 +1733 1641 43739118.52961 +1734 1641 -20057887.18154 +1735 1641 -9166666.669679 +1736 1641 11581481.02689 +1749 1641 -564939.8890041 +1750 1641 -1833333.333934 +1751 1641 -2032731.023757 +1752 1641 27139753.66166 +1753 1641 8.344650268555e-07 +1754 1641 -8738562.979764 +1755 1641 -3553812.994569 +1756 1641 1833333.333932 +1757 1641 -2293147.690507 +1642 1642 264234667.5094 +1643 1642 -5555466.479065 +1644 1642 -7333333.33213 +1645 1642 -27985100.89159 +1646 1642 2833288.795082 +1728 1642 9166666.669678 +1729 1642 -15819170.72716 +1730 1642 -8385422.169798 +1731 1642 -5.811452865601e-07 +1732 1642 -19232220.47929 +1733 1642 -694433.4439163 +1734 1642 -9166666.669679 +1735 1642 -17307688.72007 +1736 1642 9079855.613715 +1749 1642 1833333.333937 +1750 1642 -17981572.68118 +1751 1642 -16840288.77576 +1752 1642 8.940696716309e-07 +1753 1642 16138959.82123 +1754 1642 -1388866.887151 +1755 1642 -1833333.333938 +1756 1642 -20970445.78675 +1757 1642 18229155.66291 +1643 1643 295591382.0761 +1644 1643 462964.8185019 +1645 1643 2722177.683989 +1646 1643 38222126.85654 +1728 1643 10279397.69313 +1729 1643 -8385422.169798 +1730 1643 -16619803.40013 +1731 1643 43704396.30741 +1732 1643 -694433.4439163 +1733 1643 -56581165.5979 +1734 1643 11581481.02689 +1735 1643 9079855.613715 +1736 1643 -20589184.71456 +1749 1643 2090602.31093 +1750 1643 -16840288.77577 +1751 1643 -19738586.47615 +1752 1643 8796437.017353 +1753 1643 -1388866.887151 +1754 1643 -59221381.24884 +1755 1643 2351018.977684 +1756 1643 18229155.66292 +1757 1643 -27708914.75766 +1644 1644 308237881.34 +1645 1644 6.914138793945e-06 +1646 1644 -578696.2806914 +1647 1644 41681428.60013 +1648 1644 7333333.332127 +1649 1644 -578701.847993 +1731 1644 -18569369.18862 +1732 1644 9166666.669678 +1733 1644 10279397.69313 +1734 1644 -59565882.98117 +1735 1644 4.91738319397e-07 +1736 1644 43739118.52961 +1737 1644 -20057887.18154 +1738 1644 -9166666.669679 +1739 1644 11581481.02689 +1752 1644 -564939.8890041 +1753 1644 -1833333.333934 +1754 1644 -2032731.023757 +1755 1644 27139753.66166 +1756 1644 8.344650268555e-07 +1757 1644 -8738562.979764 +1758 1644 -3553812.994569 +1759 1644 1833333.333932 +1760 1644 -2293147.690507 +1645 1645 264234667.5094 +1646 1645 -5555466.479065 +1647 1645 -7333333.33213 +1648 1645 -27985100.89159 +1649 1645 2833288.795082 +1731 1645 9166666.669678 +1732 1645 -15819170.72716 +1733 1645 -8385422.169798 +1734 1645 -5.811452865601e-07 +1735 1645 -19232220.47929 +1736 1645 -694433.4439163 +1737 1645 -9166666.669679 +1738 1645 -17307688.72007 +1739 1645 9079855.613715 +1752 1645 1833333.333937 +1753 1645 -17981572.68118 +1754 1645 -16840288.77576 +1755 1645 8.940696716309e-07 +1756 1645 16138959.82123 +1757 1645 -1388866.887151 +1758 1645 -1833333.333938 +1759 1645 -20970445.78675 +1760 1645 18229155.66291 +1646 1646 295591382.0761 +1647 1646 462964.8185019 +1648 1646 2722177.683989 +1649 1646 38222126.85654 +1731 1646 10279397.69313 +1732 1646 -8385422.169798 +1733 1646 -16619803.40013 +1734 1646 43704396.30741 +1735 1646 -694433.4439163 +1736 1646 -56581165.5979 +1737 1646 11581481.02689 +1738 1646 9079855.613715 +1739 1646 -20589184.71456 +1752 1646 2090602.31093 +1753 1646 -16840288.77577 +1754 1646 -19738586.47615 +1755 1646 8796437.017353 +1756 1646 -1388866.887151 +1757 1646 -59221381.24884 +1758 1646 2351018.977684 +1759 1646 18229155.66292 +1760 1646 -27708914.75766 +1647 1647 308237881.34 +1648 1647 6.914138793945e-06 +1649 1647 -578696.2806914 +1650 1647 41681428.60013 +1651 1647 7333333.332127 +1652 1647 -578701.847993 +1734 1647 -18569369.18862 +1735 1647 9166666.669678 +1736 1647 10279397.69313 +1737 1647 -59565882.98117 +1738 1647 4.91738319397e-07 +1739 1647 43739118.52961 +1740 1647 -20057887.18154 +1741 1647 -9166666.669679 +1742 1647 11581481.02689 +1755 1647 -564939.8890041 +1756 1647 -1833333.333934 +1757 1647 -2032731.023757 +1758 1647 27139753.66166 +1759 1647 8.344650268555e-07 +1760 1647 -8738562.979764 +1761 1647 -3553812.994569 +1762 1647 1833333.333932 +1763 1647 -2293147.690507 +1648 1648 264234667.5094 +1649 1648 -5555466.479065 +1650 1648 -7333333.33213 +1651 1648 -27985100.89159 +1652 1648 2833288.795082 +1734 1648 9166666.669678 +1735 1648 -15819170.72716 +1736 1648 -8385422.169798 +1737 1648 -5.811452865601e-07 +1738 1648 -19232220.47929 +1739 1648 -694433.4439163 +1740 1648 -9166666.669679 +1741 1648 -17307688.72007 +1742 1648 9079855.613715 +1755 1648 1833333.333937 +1756 1648 -17981572.68118 +1757 1648 -16840288.77576 +1758 1648 8.940696716309e-07 +1759 1648 16138959.82123 +1760 1648 -1388866.887151 +1761 1648 -1833333.333938 +1762 1648 -20970445.78675 +1763 1648 18229155.66291 +1649 1649 295591382.0761 +1650 1649 462964.8185019 +1651 1649 2722177.683989 +1652 1649 38222126.85654 +1734 1649 10279397.69313 +1735 1649 -8385422.169798 +1736 1649 -16619803.40013 +1737 1649 43704396.30741 +1738 1649 -694433.4439163 +1739 1649 -56581165.5979 +1740 1649 11581481.02689 +1741 1649 9079855.613715 +1742 1649 -20589184.71456 +1755 1649 2090602.31093 +1756 1649 -16840288.77577 +1757 1649 -19738586.47615 +1758 1649 8796437.017353 +1759 1649 -1388866.887151 +1760 1649 -59221381.24884 +1761 1649 2351018.977684 +1762 1649 18229155.66292 +1763 1649 -27708914.75766 +1650 1650 308237881.34 +1651 1650 6.914138793945e-06 +1652 1650 -578696.2806914 +1653 1650 41681428.60013 +1654 1650 7333333.332127 +1655 1650 -578701.847993 +1737 1650 -18569369.18862 +1738 1650 9166666.669678 +1739 1650 10279397.69313 +1740 1650 -59565882.98117 +1741 1650 4.91738319397e-07 +1742 1650 43739118.52961 +1743 1650 -20057887.18154 +1744 1650 -9166666.669679 +1745 1650 11581481.02689 +1758 1650 -564939.8890041 +1759 1650 -1833333.333934 +1760 1650 -2032731.023757 +1761 1650 27139753.66166 +1762 1650 8.344650268555e-07 +1763 1650 -8738562.979764 +1764 1650 -3553812.994569 +1765 1650 1833333.333932 +1766 1650 -2293147.690507 +1651 1651 264234667.5094 +1652 1651 -5555466.479065 +1653 1651 -7333333.33213 +1654 1651 -27985100.89159 +1655 1651 2833288.795082 +1737 1651 9166666.669678 +1738 1651 -15819170.72716 +1739 1651 -8385422.169798 +1740 1651 -5.811452865601e-07 +1741 1651 -19232220.47929 +1742 1651 -694433.4439163 +1743 1651 -9166666.669679 +1744 1651 -17307688.72007 +1745 1651 9079855.613715 +1758 1651 1833333.333937 +1759 1651 -17981572.68118 +1760 1651 -16840288.77576 +1761 1651 8.940696716309e-07 +1762 1651 16138959.82123 +1763 1651 -1388866.887151 +1764 1651 -1833333.333938 +1765 1651 -20970445.78675 +1766 1651 18229155.66291 +1652 1652 295591382.0761 +1653 1652 462964.8185019 +1654 1652 2722177.683989 +1655 1652 38222126.85654 +1737 1652 10279397.69313 +1738 1652 -8385422.169798 +1739 1652 -16619803.40013 +1740 1652 43704396.30741 +1741 1652 -694433.4439163 +1742 1652 -56581165.5979 +1743 1652 11581481.02689 +1744 1652 9079855.613715 +1745 1652 -20589184.71456 +1758 1652 2090602.31093 +1759 1652 -16840288.77577 +1760 1652 -19738586.47615 +1761 1652 8796437.017353 +1762 1652 -1388866.887151 +1763 1652 -59221381.24884 +1764 1652 2351018.977684 +1765 1652 18229155.66292 +1766 1652 -27708914.75766 +1653 1653 308244166.1959 +1654 1653 4871351.472134 +1655 1653 1406582.11241 +1656 1653 -10447476.5428 +1657 1653 -26913559.91057 +1658 1653 73592.73784202 +1740 1653 -18569369.18862 +1741 1653 9166666.669678 +1742 1653 10279397.69313 +1743 1653 -43745996.76765 +1744 1653 6104008.873162 +1745 1653 33740166.13061 +1746 1653 -19561074.78605 +1747 1653 -8033003.905467 +1748 1653 11036649.36321 +1761 1653 -564939.8890041 +1762 1653 -1833333.333934 +1763 1653 -2032731.023757 +1764 1653 26998047.5617 +1765 1653 1133879.491557 +1766 1653 -8240761.134482 +1767 1653 -17935124.94805 +1768 1653 -6538217.79499 +1769 1653 7751167.860229 +1654 1654 292254523.9123 +1655 1654 -3601986.849327 +1656 1654 -41580226.57483 +1657 1654 -72059889.92846 +1658 1654 642782.4478399 +1740 1654 9166666.669678 +1741 1654 -15819170.72716 +1742 1654 -8385422.169798 +1743 1654 6104008.873161 +1744 1654 -18661255.71884 +1745 1654 -8204777.132884 +1746 1654 -8033003.905467 +1747 1654 -10093718.98084 +1748 1654 8738711.937952 +1761 1654 1833333.333937 +1762 1654 -17981572.68118 +1763 1654 -16840288.77576 +1764 1654 1133879.491557 +1765 1654 22716537.18088 +1766 1654 -896701.0799925 +1767 1654 -10204884.46286 +1768 1654 -33539277.09052 +1769 1654 25588477.22048 +1655 1655 302953037.7494 +1656 1655 351370.5155727 +1657 1655 587226.8922934 +1658 1655 20245262.55732 +1740 1655 10279397.69313 +1741 1655 -8385422.169798 +1742 1655 -16619803.40013 +1743 1655 33913777.24376 +1744 1655 -8204777.131321 +1745 1655 -47982126.11052 +1746 1655 11036649.36321 +1747 1655 8738711.937952 +1748 1655 -17191433.96669 +1761 1655 2090602.31093 +1762 1655 -16840288.77577 +1763 1655 -19738586.47615 +1764 1655 9293683.307081 +1765 1655 -896701.0799924 +1766 1655 -57522894.85793 +1767 1655 12186723.41529 +1768 1655 25588477.21893 +1769 1655 -36621043.23569 +1656 1656 357883920.7142 +1657 1656 50622446.80118 +1658 1656 -1122193.194315 +1659 1656 -70732318.24906 +1660 1656 -44948234.758 +1661 1656 106149.4816659 +1662 1656 10592868.24227 +1663 1656 -11936232.61605 +1664 1656 -169683.3667107 +1743 1656 -18648271.66148 +1744 1656 1937722.859731 +1745 1656 1037653.094121 +1746 1656 -39388390.54376 +1747 1656 10179332.65207 +1748 1656 42718216.5088 +1764 1656 -17192674.13802 +1765 1656 -10204884.46286 +1766 1656 -11944665.46985 +1767 1656 -3554898.16184 +1768 1656 12169908.16824 +1769 1656 -8661629.199202 +1770 1656 -34339167.90781 +1771 1656 -11198749.27391 +1772 1656 20338891.08329 +1773 1656 -25326488.68513 +1774 1656 -2883329.94327 +1775 1656 7795422.871771 +1657 1657 448577823.0671 +1658 1657 -1447402.958279 +1659 1657 -44948234.758 +1660 1657 -50545636.4952 +1661 1657 72437.4936852 +1662 1657 -26602899.28031 +1663 1657 -61013961.03033 +1664 1657 231541.9523678 +1743 1657 1937722.859731 +1744 1657 -44033949.54609 +1745 1657 -16387957.82287 +1746 1657 10179332.65207 +1747 1657 -7508625.593797 +1748 1657 -8052320.716373 +1764 1657 -6538217.794992 +1765 1657 -32796826.2805 +1766 1657 -25279578.32671 +1767 1657 12169908.16824 +1768 1657 18431664.65015 +1769 1657 -355535.3905276 +1770 1657 -11198749.27391 +1771 1657 -29328260.43077 +1772 1657 16684645.6024 +1773 1657 -6549996.611141 +1774 1657 -43213893.89705 +1775 1657 33390746.65407 +1658 1658 479608110.2915 +1659 1658 106149.481666 +1660 1658 72437.49368523 +1661 1658 14162538.26573 +1662 1658 -30794.47784716 +1663 1658 231541.9523679 +1664 1658 65291416.69021 +1743 1658 1037653.094121 +1744 1658 -16387957.82287 +1745 1658 -25517489.86743 +1746 1658 42718216.50883 +1747 1658 -8052320.714809 +1748 1658 -81856389.68918 +1764 1658 -7613276.581476 +1765 1658 -25279578.32828 +1766 1658 -34641174.40895 +1767 1658 8456148.575766 +1768 1658 -355535.3905277 +1769 1658 -127182615.0065 +1770 1658 20338891.08329 +1771 1658 16684645.6024 +1772 1658 -41184193.0033 +1773 1658 11988200.65286 +1774 1658 33390746.65407 +1775 1658 -58817847.61943 +1659 1659 235538262.3794 +1660 1659 50523373.08556 +1661 1659 -61873.88594103 +1662 1659 -5458590.79643 +1663 1659 948234.7652241 +1664 1659 -83001.33362576 +1746 1659 -23057319.23001 +1747 1659 -1578333.801791 +1748 1659 -5810553.011053 +1767 1659 -34244470.9381 +1768 1659 -11198749.27391 +1769 1659 -20286108.93005 +1770 1659 -19010104.98257 +1771 1659 12578333.8054 +1772 1659 8109627.085772 +1773 1659 -35004771.5089 +1774 1659 198749.2702979 +1775 1659 -30762965.14467 +1660 1660 216578039.3992 +1661 1660 -58208.02222538 +1662 1660 15614901.42948 +1663 1660 63729727.43504 +1664 1660 -72437.49368215 +1746 1660 -5245000.469662 +1747 1660 -40675138.29401 +1748 1660 -33318830.93304 +1767 1660 -11198749.27391 +1768 1660 -29233563.46106 +1769 1660 -16648687.74188 +1770 1660 12578333.8054 +1771 1660 -23736035.9259 +1772 1660 6652164.270755 +1773 1660 3865415.938169 +1774 1660 -17671928.9786 +1775 1660 3315354.404162 +1661 1661 343126475.7188 +1662 1661 -13556.88918927 +1663 1661 -72437.49368227 +1664 1661 110370037.5592 +1746 1661 -13935553.01177 +1747 1661 -33318830.93304 +1748 1661 -72337086.55553 +1767 1661 -20286108.93005 +1768 1661 -16648687.74188 +1769 1661 -40931667.75071 +1770 1661 -8140372.91156 +1771 1661 -6681169.060388 +1772 1661 -121769794.7049 +1773 1661 -30762965.14663 +1774 1661 -3351312.264694 +1775 1661 -61805895.41435 +1662 1662 173768707.4958 +1663 1662 -17397100.71246 +1664 1662 -478464.7814124 +1746 1662 -16866304.26572 +1747 1662 7134584.065443 +1748 1662 10421529.96893 +1767 1662 -25042397.77615 +1768 1662 -6549996.611143 +1769 1662 -11935132.68054 +1770 1662 -35004771.5089 +1771 1662 3865415.938171 +1772 1662 30739118.17856 +1773 1662 -12765314.33514 +1774 1662 -4450003.392471 +1775 1662 -4207737.689143 +1663 1663 200018870.1092 +1664 1663 -231541.9523607 +1746 1663 7134584.065443 +1747 1663 -22716750.95892 +1748 1663 -16648687.74188 +1767 1663 -2883329.943272 +1768 1663 -42929802.98808 +1769 1663 -33275920.00165 +1770 1663 198749.2702997 +1771 1663 -17671928.9786 +1772 1663 3315354.404162 +1773 1663 -4450003.392471 +1774 1663 -6360304.960321 +1775 1663 6609253.339359 +1664 1664 260031674.1941 +1746 1664 10421529.96893 +1747 1664 -16648687.74188 +1748 1664 -34414855.24857 +1767 1664 -7777077.121665 +1768 1664 -33275920.00165 +1769 1664 -58060271.86214 +1770 1664 30739118.17662 +1771 1664 -3351312.264694 +1772 1664 -61805895.41435 +1773 1664 4143095.64282 +1774 1664 -6724079.991783 +1775 1664 -84862411.83735 +1665 1665 387435706.2613 +1666 1665 36666666.66065 +1667 1665 2662175.186034 +1668 1665 -203296779.618 +1669 1665 -36666973.09101 +1670 1665 -2662152.453524 +1671 1665 12401143.47877 +1672 1665 29333639.75888 +1673 1665 -2152799.783064 +1776 1665 33963705.33589 +1777 1665 9166666.669679 +1778 1665 9519894.71657 +1779 1665 -73633660.33315 +1780 1665 -9166743.277268 +1781 1665 -44520628.22528 +1782 1665 -7828204.348046 +1783 1665 7333409.943332 +1784 1665 -9288430.506837 +1666 1666 332431392.3218 +1667 1666 -6944376.976808 +1668 1666 -36667126.30619 +1669 1666 -30960378.23954 +1670 1666 -3847226.047119 +1671 1666 44000459.63831 +1672 1666 12401143.47877 +1673 1666 2416692.493345 +1776 1666 9166666.669679 +1777 1666 20212626.84424 +1778 1666 5347275.319281 +1779 1666 -9166781.581064 +1780 1666 -30549559.96733 +1781 1666 -9732749.59088 +1782 1666 11000114.915 +1783 1666 -7828204.348045 +1784 1666 11145949.53617 +1667 1667 375187471.1352 +1668 1667 -2662141.087263 +1669 1667 -3097217.438217 +1670 1667 -1482420.858694 +1671 1667 -3229199.674597 +1672 1667 1611128.328897 +1673 1667 33069715.94339 +1776 1667 -8015196.919944 +1777 1667 -8680575.648187 +1778 1667 -73923722.2424 +1779 1667 -44485903.34313 +1780 1667 -9538266.413314 +1781 1667 -61195846.2912 +1782 1667 -13932645.76025 +1783 1667 7430633.02411 +1784 1667 -20875211.59479 +1668 1668 671761428.9985 +1669 1668 36667432.73655 +1670 1668 3125088.651632 +1671 1668 19448570.31785 +1672 1668 -36666973.09101 +1673 1668 2702570.135099 +1674 1668 -138432799.5 +1675 1668 1.490116119385e-07 +1676 1668 -462970.296923 +1677 1668 -52308469.44899 +1678 1668 36666666.66065 +1679 1668 -2702548.129425 +1776 1668 -72039530.38171 +1777 1668 -9166781.581061 +1778 1668 43189554.83944 +1779 1668 73599694.87993 +1780 1668 9166858.188655 +1781 1668 781226.7976368 +1782 1668 -19443104.86928 +1783 1668 -9166743.27727 +1784 1668 11639449.48452 +1785 1668 -59964405.70834 +1786 1668 7.525086402893e-07 +1787 1668 -43970603.67818 +1788 1668 -20163436.42398 +1789 1668 9166666.669676 +1790 1668 -11639352.31406 +1669 1669 572753939.719 +1670 1669 -8610914.043003 +1671 1669 -36667126.30619 +1672 1669 -108884310.9615 +1673 1669 4611018.689007 +1674 1669 -5.960464477539e-08 +1675 1669 22901850.42796 +1676 1669 -2777733.774299 +1677 1669 36666666.66064 +1678 1669 -41307675.60857 +1679 1669 1513866.887135 +1776 1669 -9166743.277267 +1777 1669 -28955430.01587 +1778 1669 7996602.428466 +1779 1669 9166858.188655 +1780 1669 48847822.54786 +1781 1669 -2152764.803778 +1782 1669 -9166781.581064 +1783 1669 -51526325.20493 +1784 1669 36236271.0855 +1785 1669 3.725290298462e-07 +1786 1669 -19630743.20649 +1787 1669 -694433.4439167 +1788 1669 9166666.669676 +1789 1669 -17413237.96253 +1790 1669 9149300.058182 +1670 1670 607013167.9741 +1671 1670 2737303.360137 +1672 1670 5388804.78494 +1673 1670 37600883.93994 +1674 1670 -462970.2969232 +1675 1670 -2777733.774298 +1676 1670 39890623.87246 +1677 1670 -2737270.351624 +1678 1670 1541644.664895 +1679 1670 -7895194.184061 +1776 1670 43154829.95728 +1777 1670 7802192.5578 +1778 1670 -56944833.0873 +1779 1670 781318.4370322 +1780 1670 -2152691.493423 +1781 1670 -99821807.80486 +1782 1670 11639498.06975 +1783 1670 36402939.91804 +1784 1670 -55413772.21342 +1785 1670 -43935881.45598 +1786 1670 -694433.4439167 +1787 1670 -57643892.87044 +1788 1670 -11639352.31406 +1789 1670 9149300.058182 +1790 1670 -20870649.36111 +1671 1671 387435706.2613 +1672 1671 36666666.66065 +1673 1671 2662175.186035 +1674 1671 -52284795.20658 +1675 1671 -36666666.66065 +1676 1671 2505785.203048 +1677 1671 -203296779.618 +1678 1671 -36666973.09101 +1679 1671 -2662152.453524 +1680 1671 12401143.47877 +1681 1671 29333639.75888 +1682 1671 -2152799.783064 +1776 1671 -4839277.140465 +1777 1671 11000114.915 +1778 1671 12370128.70975 +1779 1671 -14860172.33131 +1780 1671 -9166781.581062 +1781 1671 -10279526.39882 +1782 1671 33963705.33589 +1783 1671 9166666.669679 +1784 1671 9519894.71657 +1785 1671 -18663081.30986 +1786 1671 -9166666.669677 +1787 1671 -10337268.9803 +1788 1671 -73633660.33315 +1789 1671 -9166743.277268 +1790 1671 -44520628.22528 +1791 1671 -7828204.348046 +1792 1671 7333409.943332 +1793 1671 -9288430.506837 +1672 1672 332431392.3218 +1673 1672 -6944376.976808 +1674 1672 -36666666.66065 +1675 1672 -41284001.36615 +1676 1672 1263866.887163 +1677 1672 -36667126.30619 +1678 1672 -30960378.23954 +1679 1672 -3847226.047119 +1680 1672 44000459.63831 +1681 1672 12401143.47877 +1682 1672 2416692.493345 +1776 1672 7333409.943332 +1777 1672 -4839277.140466 +1778 1672 -6597291.372073 +1779 1672 -9166743.277267 +1780 1672 -46943392.66696 +1781 1672 -33736315.15602 +1782 1672 9166666.669679 +1783 1672 20212626.84424 +1784 1672 5347275.319281 +1785 1672 -9166666.669677 +1786 1672 -15912882.8484 +1787 1672 -8454866.614265 +1788 1672 -9166781.581064 +1789 1672 -30549559.96733 +1790 1672 -9732749.59088 +1791 1672 11000114.915 +1792 1672 -7828204.348045 +1793 1672 11145949.53617 +1673 1673 375187471.1352 +1674 1673 2471062.980849 +1675 1673 1236089.109403 +1676 1673 -7832062.870945 +1677 1673 -2662141.087263 +1678 1673 -3097217.438217 +1679 1673 -1482420.858694 +1680 1673 -3229199.674597 +1681 1673 1611128.328897 +1682 1673 33069715.94339 +1776 1673 8246752.473166 +1777 1673 -9895937.05811 +1778 1673 -12904739.04124 +1779 1673 -10279483.49692 +1780 1673 -33902984.10692 +1781 1673 -43192618.77883 +1782 1673 -8015196.919944 +1783 1673 -8680575.648187 +1784 1673 -73923722.2424 +1785 1673 -10337268.9803 +1786 1673 -8454866.614265 +1787 1673 -16869702.39011 +1788 1673 -44485903.34313 +1789 1673 -9538266.413314 +1790 1673 -61195846.2912 +1791 1673 -13932645.76025 +1792 1673 7430633.02411 +1793 1673 -20875211.59479 +1674 1674 619629140.0329 +1675 1674 1.168251037598e-05 +1676 1674 925940.5938052 +1677 1674 84152766.23505 +1678 1674 -4.991888999939e-06 +1679 1674 231485.148566 +1683 1674 -138432799.5 +1684 1674 1.490116119385e-07 +1685 1674 -462970.296923 +1686 1674 -52308469.44899 +1687 1674 36666666.66065 +1688 1674 -2702548.129425 +1779 1674 -59565882.98117 +1780 1674 4.91738319397e-07 +1781 1674 43739118.52961 +1782 1674 -20057887.18154 +1783 1674 -9166666.669679 +1784 1674 11581481.02689 +1785 1674 54280296.46473 +1786 1674 3.09944152832e-06 +1787 1674 231485.1485852 +1788 1674 -7107625.989141 +1789 1674 -6.146728992462e-06 +1790 1674 57871.2871768 +1794 1674 -59964405.70834 +1795 1674 7.525086402893e-07 +1796 1674 -43970603.67818 +1797 1674 -20163436.42398 +1798 1674 9166666.669676 +1799 1674 -11639352.31406 +1675 1675 531622789.3528 +1676 1675 -11110935.09172 +1677 1675 -4.798173904419e-06 +1678 1675 -55180296.03374 +1679 1675 5555467.545859 +1683 1675 -5.960464477539e-08 +1684 1675 22901850.42796 +1685 1675 -2777733.774299 +1686 1675 36666666.66064 +1687 1675 -41307675.60857 +1688 1675 1513866.887135 +1779 1675 -5.811452865601e-07 +1780 1675 -19232220.47929 +1781 1675 -694433.4439163 +1782 1675 -9166666.669679 +1783 1675 -17307688.72007 +1784 1675 9079855.613715 +1785 1675 3.635883331299e-06 +1786 1675 32278708.78388 +1787 1675 -2777733.774297 +1788 1675 -5.349516868591e-06 +1789 1675 -41940891.5735 +1790 1675 36472200.21471 +1794 1675 3.725290298462e-07 +1795 1675 -19630743.20649 +1796 1675 -694433.4439167 +1797 1675 9166666.669676 +1798 1675 -17413237.96253 +1799 1675 9149300.058182 +1676 1676 599591912.5003 +1677 1676 231485.1485663 +1678 1676 5555467.545859 +1679 1676 78550735.85485 +1683 1676 -462970.2969232 +1684 1676 -2777733.774298 +1685 1676 39890623.87246 +1686 1676 -2737270.351624 +1687 1676 1541644.664895 +1688 1676 -7895194.184061 +1779 1676 43704396.30741 +1780 1676 -694433.4439163 +1781 1676 -56581165.5979 +1782 1676 11581481.02689 +1783 1676 9079855.613715 +1784 1676 -20589184.71456 +1785 1676 231485.148585 +1786 1676 -2777733.774298 +1787 1676 -118440658.1206 +1788 1676 57871.28717716 +1789 1676 36444422.43695 +1790 1676 -55417829.51533 +1794 1676 -43935881.45598 +1795 1676 -694433.4439167 +1796 1676 -57643892.87044 +1797 1676 -11639352.31406 +1798 1676 9149300.058182 +1799 1676 -20870649.36111 +1677 1677 671761428.9985 +1678 1677 36667432.73655 +1679 1677 3125088.651632 +1680 1677 19448570.31785 +1681 1677 -36666973.09101 +1682 1677 2702570.135099 +1683 1677 -52284795.20658 +1684 1677 -36666666.66065 +1685 1677 2505785.203048 +1686 1677 -138432799.5 +1687 1677 1.490116119385e-07 +1688 1677 -462970.296923 +1689 1677 -52308469.44899 +1690 1677 36666666.66065 +1691 1677 -2702548.129425 +1779 1677 -18569369.18862 +1780 1677 9166666.669678 +1781 1677 10279397.69313 +1782 1677 -72039530.38171 +1783 1677 -9166781.581061 +1784 1677 43189554.83944 +1785 1677 -1129879.778007 +1786 1677 2.369284629822e-06 +1787 1677 57871.28717239 +1788 1677 73599694.87993 +1789 1677 9166858.188655 +1790 1677 781226.7976368 +1791 1677 -19443104.86928 +1792 1677 -9166743.27727 +1793 1677 11639449.48452 +1794 1677 -18663081.30986 +1795 1677 -9166666.669677 +1796 1677 -10337268.9803 +1797 1677 -59964405.70834 +1798 1677 7.525086402893e-07 +1799 1677 -43970603.67818 +1800 1677 -20163436.42398 +1801 1677 9166666.669676 +1802 1677 -11639352.31406 +1678 1678 572753939.719 +1679 1678 -8610914.043003 +1680 1678 -36667126.30619 +1681 1678 -108884310.9615 +1682 1678 4611018.689007 +1683 1678 -36666666.66065 +1684 1678 -41284001.36615 +1685 1678 1263866.887163 +1686 1678 -5.960464477539e-08 +1687 1678 22901850.42796 +1688 1678 -2777733.774299 +1689 1678 36666666.66064 +1690 1678 -41307675.60857 +1691 1678 1513866.887135 +1779 1678 9166666.669678 +1780 1678 -15819170.72716 +1781 1678 -8385422.169798 +1782 1678 -9166743.277267 +1783 1678 -28955430.01587 +1784 1678 7996602.428466 +1785 1678 2.913177013397e-06 +1786 1678 -35963145.36236 +1787 1678 -33694466.44041 +1788 1678 9166858.188655 +1789 1678 48847822.54786 +1790 1678 -2152764.803778 +1791 1678 -9166781.581064 +1792 1678 -51526325.20493 +1793 1678 36236271.0855 +1794 1678 -9166666.669677 +1795 1678 -15912882.8484 +1796 1678 -8454866.614265 +1797 1678 3.725290298462e-07 +1798 1678 -19630743.20649 +1799 1678 -694433.4439167 +1800 1678 9166666.669676 +1801 1678 -17413237.96253 +1802 1678 9149300.058182 +1679 1679 607013167.9741 +1680 1679 2737303.360137 +1681 1679 5388804.78494 +1682 1679 37600883.93994 +1683 1679 2471062.980849 +1684 1679 1236089.109403 +1685 1679 -7832062.870945 +1686 1679 -462970.2969232 +1687 1679 -2777733.774298 +1688 1679 39890623.87246 +1689 1679 -2737270.351624 +1690 1679 1541644.664895 +1691 1679 -7895194.184061 +1779 1679 10279397.69313 +1780 1679 -8385422.169798 +1781 1679 -16619803.40013 +1782 1679 43154829.95728 +1783 1679 7802192.5578 +1784 1679 -56944833.0873 +1785 1679 57871.28717278 +1786 1679 -33666688.66265 +1787 1679 -39477172.9523 +1788 1679 781318.4370322 +1789 1679 -2152691.493423 +1790 1679 -99821807.80486 +1791 1679 11639498.06975 +1792 1679 36402939.91804 +1793 1679 -55413772.21342 +1794 1679 -10337268.9803 +1795 1679 -8454866.614265 +1796 1679 -16869702.39011 +1797 1679 -43935881.45598 +1798 1679 -694433.4439167 +1799 1679 -57643892.87044 +1800 1679 -11639352.31406 +1801 1679 9149300.058182 +1802 1679 -20870649.36111 +1680 1680 387435706.2613 +1681 1680 36666666.66065 +1682 1680 2662175.186035 +1686 1680 -52284795.20658 +1687 1680 -36666666.66065 +1688 1680 2505785.203048 +1689 1680 -203296779.618 +1690 1680 -36666973.09101 +1691 1680 -2662152.453524 +1692 1680 12401143.47877 +1693 1680 29333639.75888 +1694 1680 -2152799.783064 +1782 1680 -4839277.140465 +1783 1680 11000114.915 +1784 1680 12370128.70975 +1788 1680 -14860172.33131 +1789 1680 -9166781.581062 +1790 1680 -10279526.39882 +1791 1680 33963705.33589 +1792 1680 9166666.669679 +1793 1680 9519894.71657 +1797 1680 -18663081.30986 +1798 1680 -9166666.669677 +1799 1680 -10337268.9803 +1800 1680 -73633660.33315 +1801 1680 -9166743.277268 +1802 1680 -44520628.22528 +1803 1680 -7828204.348046 +1804 1680 7333409.943332 +1805 1680 -9288430.506837 +1681 1681 332431392.3218 +1682 1681 -6944376.976808 +1686 1681 -36666666.66065 +1687 1681 -41284001.36615 +1688 1681 1263866.887163 +1689 1681 -36667126.30619 +1690 1681 -30960378.23954 +1691 1681 -3847226.047119 +1692 1681 44000459.63831 +1693 1681 12401143.47877 +1694 1681 2416692.493345 +1782 1681 7333409.943332 +1783 1681 -4839277.140466 +1784 1681 -6597291.372073 +1788 1681 -9166743.277267 +1789 1681 -46943392.66696 +1790 1681 -33736315.15602 +1791 1681 9166666.669679 +1792 1681 20212626.84424 +1793 1681 5347275.319281 +1797 1681 -9166666.669677 +1798 1681 -15912882.8484 +1799 1681 -8454866.614265 +1800 1681 -9166781.581064 +1801 1681 -30549559.96733 +1802 1681 -9732749.59088 +1803 1681 11000114.915 +1804 1681 -7828204.348045 +1805 1681 11145949.53617 +1682 1682 375187471.1352 +1686 1682 2471062.980849 +1687 1682 1236089.109403 +1688 1682 -7832062.870945 +1689 1682 -2662141.087263 +1690 1682 -3097217.438217 +1691 1682 -1482420.858694 +1692 1682 -3229199.674597 +1693 1682 1611128.328897 +1694 1682 33069715.94339 +1782 1682 8246752.473166 +1783 1682 -9895937.05811 +1784 1682 -12904739.04124 +1788 1682 -10279483.49692 +1789 1682 -33902984.10692 +1790 1682 -43192618.77883 +1791 1682 -8015196.919944 +1792 1682 -8680575.648187 +1793 1682 -73923722.2424 +1797 1682 -10337268.9803 +1798 1682 -8454866.614265 +1799 1682 -16869702.39011 +1800 1682 -44485903.34313 +1801 1682 -9538266.413314 +1802 1682 -61195846.2912 +1803 1682 -13932645.76025 +1804 1682 7430633.02411 +1805 1682 -20875211.59479 +1683 1683 619629140.0329 +1684 1683 1.168251037598e-05 +1685 1683 925940.5938052 +1686 1683 84152766.23505 +1687 1683 -4.991888999939e-06 +1688 1683 231485.148566 +1695 1683 -138432799.5 +1696 1683 1.490116119385e-07 +1697 1683 -462970.296923 +1698 1683 -52308469.44899 +1699 1683 36666666.66065 +1700 1683 -2702548.129425 +1785 1683 -59565882.98117 +1786 1683 4.91738319397e-07 +1787 1683 43739118.52961 +1788 1683 -20057887.18154 +1789 1683 -9166666.669679 +1790 1683 11581481.02689 +1794 1683 54280296.46473 +1795 1683 3.09944152832e-06 +1796 1683 231485.1485852 +1797 1683 -7107625.989141 +1798 1683 -6.146728992462e-06 +1799 1683 57871.2871768 +1806 1683 -59964405.70834 +1807 1683 7.525086402893e-07 +1808 1683 -43970603.67818 +1809 1683 -20163436.42398 +1810 1683 9166666.669676 +1811 1683 -11639352.31406 +1684 1684 531622789.3528 +1685 1684 -11110935.09172 +1686 1684 -4.798173904419e-06 +1687 1684 -55180296.03374 +1688 1684 5555467.545859 +1695 1684 -5.960464477539e-08 +1696 1684 22901850.42796 +1697 1684 -2777733.774299 +1698 1684 36666666.66064 +1699 1684 -41307675.60857 +1700 1684 1513866.887135 +1785 1684 -5.811452865601e-07 +1786 1684 -19232220.47929 +1787 1684 -694433.4439163 +1788 1684 -9166666.669679 +1789 1684 -17307688.72007 +1790 1684 9079855.613715 +1794 1684 3.635883331299e-06 +1795 1684 32278708.78388 +1796 1684 -2777733.774297 +1797 1684 -5.349516868591e-06 +1798 1684 -41940891.5735 +1799 1684 36472200.21471 +1806 1684 3.725290298462e-07 +1807 1684 -19630743.20649 +1808 1684 -694433.4439167 +1809 1684 9166666.669676 +1810 1684 -17413237.96253 +1811 1684 9149300.058182 +1685 1685 599591912.5003 +1686 1685 231485.1485663 +1687 1685 5555467.545859 +1688 1685 78550735.85485 +1695 1685 -462970.2969232 +1696 1685 -2777733.774298 +1697 1685 39890623.87246 +1698 1685 -2737270.351624 +1699 1685 1541644.664895 +1700 1685 -7895194.184061 +1785 1685 43704396.30741 +1786 1685 -694433.4439163 +1787 1685 -56581165.5979 +1788 1685 11581481.02689 +1789 1685 9079855.613715 +1790 1685 -20589184.71456 +1794 1685 231485.148585 +1795 1685 -2777733.774298 +1796 1685 -118440658.1206 +1797 1685 57871.28717716 +1798 1685 36444422.43695 +1799 1685 -55417829.51533 +1806 1685 -43935881.45598 +1807 1685 -694433.4439167 +1808 1685 -57643892.87044 +1809 1685 -11639352.31406 +1810 1685 9149300.058182 +1811 1685 -20870649.36111 +1686 1686 619629140.0329 +1687 1686 1.168251037598e-05 +1688 1686 925940.5938052 +1689 1686 84152766.23505 +1690 1686 -4.991888999939e-06 +1691 1686 231485.148566 +1695 1686 -52284795.20658 +1696 1686 -36666666.66065 +1697 1686 2505785.203048 +1698 1686 -138432799.5 +1699 1686 1.490116119385e-07 +1700 1686 -462970.296923 +1701 1686 -52308469.44899 +1702 1686 36666666.66065 +1703 1686 -2702548.129425 +1785 1686 -18569369.18862 +1786 1686 9166666.669678 +1787 1686 10279397.69313 +1788 1686 -59565882.98117 +1789 1686 4.91738319397e-07 +1790 1686 43739118.52961 +1791 1686 -20057887.18154 +1792 1686 -9166666.669679 +1793 1686 11581481.02689 +1794 1686 -1129879.778007 +1795 1686 2.369284629822e-06 +1796 1686 57871.28717239 +1797 1686 54280296.46473 +1798 1686 3.09944152832e-06 +1799 1686 231485.1485852 +1800 1686 -7107625.989141 +1801 1686 -6.146728992462e-06 +1802 1686 57871.2871768 +1806 1686 -18663081.30986 +1807 1686 -9166666.669677 +1808 1686 -10337268.9803 +1809 1686 -59964405.70834 +1810 1686 7.525086402893e-07 +1811 1686 -43970603.67818 +1812 1686 -20163436.42398 +1813 1686 9166666.669676 +1814 1686 -11639352.31406 +1687 1687 531622789.3528 +1688 1687 -11110935.09172 +1689 1687 -4.798173904419e-06 +1690 1687 -55180296.03374 +1691 1687 5555467.545859 +1695 1687 -36666666.66065 +1696 1687 -41284001.36615 +1697 1687 1263866.887163 +1698 1687 -5.960464477539e-08 +1699 1687 22901850.42796 +1700 1687 -2777733.774299 +1701 1687 36666666.66064 +1702 1687 -41307675.60857 +1703 1687 1513866.887135 +1785 1687 9166666.669678 +1786 1687 -15819170.72716 +1787 1687 -8385422.169798 +1788 1687 -5.811452865601e-07 +1789 1687 -19232220.47929 +1790 1687 -694433.4439163 +1791 1687 -9166666.669679 +1792 1687 -17307688.72007 +1793 1687 9079855.613715 +1794 1687 2.913177013397e-06 +1795 1687 -35963145.36236 +1796 1687 -33694466.44041 +1797 1687 3.635883331299e-06 +1798 1687 32278708.78388 +1799 1687 -2777733.774297 +1800 1687 -5.349516868591e-06 +1801 1687 -41940891.5735 +1802 1687 36472200.21471 +1806 1687 -9166666.669677 +1807 1687 -15912882.8484 +1808 1687 -8454866.614265 +1809 1687 3.725290298462e-07 +1810 1687 -19630743.20649 +1811 1687 -694433.4439167 +1812 1687 9166666.669676 +1813 1687 -17413237.96253 +1814 1687 9149300.058182 +1688 1688 599591912.5003 +1689 1688 231485.1485663 +1690 1688 5555467.545859 +1691 1688 78550735.85485 +1695 1688 2471062.980849 +1696 1688 1236089.109403 +1697 1688 -7832062.870945 +1698 1688 -462970.2969232 +1699 1688 -2777733.774298 +1700 1688 39890623.87246 +1701 1688 -2737270.351624 +1702 1688 1541644.664895 +1703 1688 -7895194.184061 +1785 1688 10279397.69313 +1786 1688 -8385422.169798 +1787 1688 -16619803.40013 +1788 1688 43704396.30741 +1789 1688 -694433.4439163 +1790 1688 -56581165.5979 +1791 1688 11581481.02689 +1792 1688 9079855.613715 +1793 1688 -20589184.71456 +1794 1688 57871.28717278 +1795 1688 -33666688.66265 +1796 1688 -39477172.9523 +1797 1688 231485.148585 +1798 1688 -2777733.774298 +1799 1688 -118440658.1206 +1800 1688 57871.28717716 +1801 1688 36444422.43695 +1802 1688 -55417829.51533 +1806 1688 -10337268.9803 +1807 1688 -8454866.614265 +1808 1688 -16869702.39011 +1809 1688 -43935881.45598 +1810 1688 -694433.4439167 +1811 1688 -57643892.87044 +1812 1688 -11639352.31406 +1813 1688 9149300.058182 +1814 1688 -20870649.36111 +1689 1689 671761428.9985 +1690 1689 36667432.73655 +1691 1689 3125088.651632 +1692 1689 19448570.31785 +1693 1689 -36666973.09101 +1694 1689 2702570.135099 +1698 1689 -52284795.20658 +1699 1689 -36666666.66065 +1700 1689 2505785.203048 +1701 1689 -138432799.5 +1702 1689 1.490116119385e-07 +1703 1689 -462970.296923 +1704 1689 -52308469.44899 +1705 1689 36666666.66065 +1706 1689 -2702548.129425 +1788 1689 -18569369.18862 +1789 1689 9166666.669678 +1790 1689 10279397.69313 +1791 1689 -72039530.38171 +1792 1689 -9166781.581061 +1793 1689 43189554.83944 +1797 1689 -1129879.778007 +1798 1689 2.369284629822e-06 +1799 1689 57871.28717239 +1800 1689 73599694.87993 +1801 1689 9166858.188655 +1802 1689 781226.7976368 +1803 1689 -19443104.86928 +1804 1689 -9166743.27727 +1805 1689 11639449.48452 +1809 1689 -18663081.30986 +1810 1689 -9166666.669677 +1811 1689 -10337268.9803 +1812 1689 -59964405.70834 +1813 1689 7.525086402893e-07 +1814 1689 -43970603.67818 +1815 1689 -20163436.42398 +1816 1689 9166666.669676 +1817 1689 -11639352.31406 +1690 1690 572753939.719 +1691 1690 -8610914.043003 +1692 1690 -36667126.30619 +1693 1690 -108884310.9615 +1694 1690 4611018.689007 +1698 1690 -36666666.66065 +1699 1690 -41284001.36615 +1700 1690 1263866.887163 +1701 1690 -5.960464477539e-08 +1702 1690 22901850.42796 +1703 1690 -2777733.774299 +1704 1690 36666666.66064 +1705 1690 -41307675.60857 +1706 1690 1513866.887135 +1788 1690 9166666.669678 +1789 1690 -15819170.72716 +1790 1690 -8385422.169798 +1791 1690 -9166743.277267 +1792 1690 -28955430.01587 +1793 1690 7996602.428466 +1797 1690 2.913177013397e-06 +1798 1690 -35963145.36236 +1799 1690 -33694466.44041 +1800 1690 9166858.188655 +1801 1690 48847822.54786 +1802 1690 -2152764.803778 +1803 1690 -9166781.581064 +1804 1690 -51526325.20493 +1805 1690 36236271.0855 +1809 1690 -9166666.669677 +1810 1690 -15912882.8484 +1811 1690 -8454866.614265 +1812 1690 3.725290298462e-07 +1813 1690 -19630743.20649 +1814 1690 -694433.4439167 +1815 1690 9166666.669676 +1816 1690 -17413237.96253 +1817 1690 9149300.058182 +1691 1691 607013167.9741 +1692 1691 2737303.360137 +1693 1691 5388804.78494 +1694 1691 37600883.93994 +1698 1691 2471062.980849 +1699 1691 1236089.109403 +1700 1691 -7832062.870945 +1701 1691 -462970.2969232 +1702 1691 -2777733.774298 +1703 1691 39890623.87246 +1704 1691 -2737270.351624 +1705 1691 1541644.664895 +1706 1691 -7895194.184061 +1788 1691 10279397.69313 +1789 1691 -8385422.169798 +1790 1691 -16619803.40013 +1791 1691 43154829.95728 +1792 1691 7802192.5578 +1793 1691 -56944833.0873 +1797 1691 57871.28717278 +1798 1691 -33666688.66265 +1799 1691 -39477172.9523 +1800 1691 781318.4370322 +1801 1691 -2152691.493423 +1802 1691 -99821807.80486 +1803 1691 11639498.06975 +1804 1691 36402939.91804 +1805 1691 -55413772.21342 +1809 1691 -10337268.9803 +1810 1691 -8454866.614265 +1811 1691 -16869702.39011 +1812 1691 -43935881.45598 +1813 1691 -694433.4439167 +1814 1691 -57643892.87044 +1815 1691 -11639352.31406 +1816 1691 9149300.058182 +1817 1691 -20870649.36111 +1692 1692 387435706.2613 +1693 1692 36666666.66065 +1694 1692 2662175.186035 +1701 1692 -52284795.20658 +1702 1692 -36666666.66065 +1703 1692 2505785.203048 +1704 1692 -203296779.618 +1705 1692 -36666973.09101 +1706 1692 -2662152.453524 +1707 1692 12401143.47877 +1708 1692 29333639.75888 +1709 1692 -2152799.783064 +1791 1692 -4839277.140465 +1792 1692 11000114.915 +1793 1692 12370128.70975 +1800 1692 -14860172.33131 +1801 1692 -9166781.581062 +1802 1692 -10279526.39882 +1803 1692 33963705.33589 +1804 1692 9166666.669679 +1805 1692 9519894.71657 +1812 1692 -18663081.30986 +1813 1692 -9166666.669677 +1814 1692 -10337268.9803 +1815 1692 -73633660.33315 +1816 1692 -9166743.277268 +1817 1692 -44520628.22528 +1818 1692 -7828204.348046 +1819 1692 7333409.943332 +1820 1692 -9288430.506837 +1693 1693 332431392.3218 +1694 1693 -6944376.976808 +1701 1693 -36666666.66065 +1702 1693 -41284001.36615 +1703 1693 1263866.887163 +1704 1693 -36667126.30619 +1705 1693 -30960378.23954 +1706 1693 -3847226.047119 +1707 1693 44000459.63831 +1708 1693 12401143.47877 +1709 1693 2416692.493345 +1791 1693 7333409.943332 +1792 1693 -4839277.140466 +1793 1693 -6597291.372073 +1800 1693 -9166743.277267 +1801 1693 -46943392.66696 +1802 1693 -33736315.15602 +1803 1693 9166666.669679 +1804 1693 20212626.84424 +1805 1693 5347275.319281 +1812 1693 -9166666.669677 +1813 1693 -15912882.8484 +1814 1693 -8454866.614265 +1815 1693 -9166781.581064 +1816 1693 -30549559.96733 +1817 1693 -9732749.59088 +1818 1693 11000114.915 +1819 1693 -7828204.348045 +1820 1693 11145949.53617 +1694 1694 375187471.1352 +1701 1694 2471062.980849 +1702 1694 1236089.109403 +1703 1694 -7832062.870945 +1704 1694 -2662141.087263 +1705 1694 -3097217.438217 +1706 1694 -1482420.858694 +1707 1694 -3229199.674597 +1708 1694 1611128.328897 +1709 1694 33069715.94339 +1791 1694 8246752.473166 +1792 1694 -9895937.05811 +1793 1694 -12904739.04124 +1800 1694 -10279483.49692 +1801 1694 -33902984.10692 +1802 1694 -43192618.77883 +1803 1694 -8015196.919944 +1804 1694 -8680575.648187 +1805 1694 -73923722.2424 +1812 1694 -10337268.9803 +1813 1694 -8454866.614265 +1814 1694 -16869702.39011 +1815 1694 -44485903.34313 +1816 1694 -9538266.413314 +1817 1694 -61195846.2912 +1818 1694 -13932645.76025 +1819 1694 7430633.02411 +1820 1694 -20875211.59479 +1695 1695 619629140.0329 +1696 1695 1.168251037598e-05 +1697 1695 925940.5938052 +1698 1695 84152766.23505 +1699 1695 -4.991888999939e-06 +1700 1695 231485.148566 +1710 1695 -138432799.5 +1711 1695 1.490116119385e-07 +1712 1695 -462970.296923 +1713 1695 -52308469.44899 +1714 1695 36666666.66065 +1715 1695 -2702548.129425 +1794 1695 -59565882.98117 +1795 1695 4.91738319397e-07 +1796 1695 43739118.52961 +1797 1695 -20057887.18154 +1798 1695 -9166666.669679 +1799 1695 11581481.02689 +1806 1695 54280296.46473 +1807 1695 3.09944152832e-06 +1808 1695 231485.1485852 +1809 1695 -7107625.989141 +1810 1695 -6.146728992462e-06 +1811 1695 57871.2871768 +1821 1695 -59964405.70834 +1822 1695 7.525086402893e-07 +1823 1695 -43970603.67818 +1824 1695 -20163436.42398 +1825 1695 9166666.669676 +1826 1695 -11639352.31406 +1696 1696 531622789.3528 +1697 1696 -11110935.09172 +1698 1696 -4.798173904419e-06 +1699 1696 -55180296.03374 +1700 1696 5555467.545859 +1710 1696 -5.960464477539e-08 +1711 1696 22901850.42796 +1712 1696 -2777733.774299 +1713 1696 36666666.66064 +1714 1696 -41307675.60857 +1715 1696 1513866.887135 +1794 1696 -5.811452865601e-07 +1795 1696 -19232220.47929 +1796 1696 -694433.4439163 +1797 1696 -9166666.669679 +1798 1696 -17307688.72007 +1799 1696 9079855.613715 +1806 1696 3.635883331299e-06 +1807 1696 32278708.78388 +1808 1696 -2777733.774297 +1809 1696 -5.349516868591e-06 +1810 1696 -41940891.5735 +1811 1696 36472200.21471 +1821 1696 3.725290298462e-07 +1822 1696 -19630743.20649 +1823 1696 -694433.4439167 +1824 1696 9166666.669676 +1825 1696 -17413237.96253 +1826 1696 9149300.058182 +1697 1697 599591912.5003 +1698 1697 231485.1485663 +1699 1697 5555467.545859 +1700 1697 78550735.85485 +1710 1697 -462970.2969232 +1711 1697 -2777733.774298 +1712 1697 39890623.87246 +1713 1697 -2737270.351624 +1714 1697 1541644.664895 +1715 1697 -7895194.184061 +1794 1697 43704396.30741 +1795 1697 -694433.4439163 +1796 1697 -56581165.5979 +1797 1697 11581481.02689 +1798 1697 9079855.613715 +1799 1697 -20589184.71456 +1806 1697 231485.148585 +1807 1697 -2777733.774298 +1808 1697 -118440658.1206 +1809 1697 57871.28717716 +1810 1697 36444422.43695 +1811 1697 -55417829.51533 +1821 1697 -43935881.45598 +1822 1697 -694433.4439167 +1823 1697 -57643892.87044 +1824 1697 -11639352.31406 +1825 1697 9149300.058182 +1826 1697 -20870649.36111 +1698 1698 619629140.0329 +1699 1698 1.168251037598e-05 +1700 1698 925940.5938052 +1701 1698 84152766.23505 +1702 1698 -4.991888999939e-06 +1703 1698 231485.148566 +1710 1698 -52284795.20658 +1711 1698 -36666666.66065 +1712 1698 2505785.203048 +1713 1698 -138432799.5 +1714 1698 1.490116119385e-07 +1715 1698 -462970.296923 +1716 1698 -52308469.44899 +1717 1698 36666666.66065 +1718 1698 -2702548.129425 +1794 1698 -18569369.18862 +1795 1698 9166666.669678 +1796 1698 10279397.69313 +1797 1698 -59565882.98117 +1798 1698 4.91738319397e-07 +1799 1698 43739118.52961 +1800 1698 -20057887.18154 +1801 1698 -9166666.669679 +1802 1698 11581481.02689 +1806 1698 -1129879.778007 +1807 1698 2.369284629822e-06 +1808 1698 57871.28717239 +1809 1698 54280296.46473 +1810 1698 3.09944152832e-06 +1811 1698 231485.1485852 +1812 1698 -7107625.989141 +1813 1698 -6.146728992462e-06 +1814 1698 57871.2871768 +1821 1698 -18663081.30986 +1822 1698 -9166666.669677 +1823 1698 -10337268.9803 +1824 1698 -59964405.70834 +1825 1698 7.525086402893e-07 +1826 1698 -43970603.67818 +1827 1698 -20163436.42398 +1828 1698 9166666.669676 +1829 1698 -11639352.31406 +1699 1699 531622789.3528 +1700 1699 -11110935.09172 +1701 1699 -4.798173904419e-06 +1702 1699 -55180296.03374 +1703 1699 5555467.545859 +1710 1699 -36666666.66065 +1711 1699 -41284001.36615 +1712 1699 1263866.887163 +1713 1699 -5.960464477539e-08 +1714 1699 22901850.42796 +1715 1699 -2777733.774299 +1716 1699 36666666.66064 +1717 1699 -41307675.60857 +1718 1699 1513866.887135 +1794 1699 9166666.669678 +1795 1699 -15819170.72716 +1796 1699 -8385422.169798 +1797 1699 -5.811452865601e-07 +1798 1699 -19232220.47929 +1799 1699 -694433.4439163 +1800 1699 -9166666.669679 +1801 1699 -17307688.72007 +1802 1699 9079855.613715 +1806 1699 2.913177013397e-06 +1807 1699 -35963145.36236 +1808 1699 -33694466.44041 +1809 1699 3.635883331299e-06 +1810 1699 32278708.78388 +1811 1699 -2777733.774297 +1812 1699 -5.349516868591e-06 +1813 1699 -41940891.5735 +1814 1699 36472200.21471 +1821 1699 -9166666.669677 +1822 1699 -15912882.8484 +1823 1699 -8454866.614265 +1824 1699 3.725290298462e-07 +1825 1699 -19630743.20649 +1826 1699 -694433.4439167 +1827 1699 9166666.669676 +1828 1699 -17413237.96253 +1829 1699 9149300.058182 +1700 1700 599591912.5003 +1701 1700 231485.1485663 +1702 1700 5555467.545859 +1703 1700 78550735.85485 +1710 1700 2471062.980849 +1711 1700 1236089.109403 +1712 1700 -7832062.870945 +1713 1700 -462970.2969232 +1714 1700 -2777733.774298 +1715 1700 39890623.87246 +1716 1700 -2737270.351624 +1717 1700 1541644.664895 +1718 1700 -7895194.184061 +1794 1700 10279397.69313 +1795 1700 -8385422.169798 +1796 1700 -16619803.40013 +1797 1700 43704396.30741 +1798 1700 -694433.4439163 +1799 1700 -56581165.5979 +1800 1700 11581481.02689 +1801 1700 9079855.613715 +1802 1700 -20589184.71456 +1806 1700 57871.28717278 +1807 1700 -33666688.66265 +1808 1700 -39477172.9523 +1809 1700 231485.148585 +1810 1700 -2777733.774298 +1811 1700 -118440658.1206 +1812 1700 57871.28717716 +1813 1700 36444422.43695 +1814 1700 -55417829.51533 +1821 1700 -10337268.9803 +1822 1700 -8454866.614265 +1823 1700 -16869702.39011 +1824 1700 -43935881.45598 +1825 1700 -694433.4439167 +1826 1700 -57643892.87044 +1827 1700 -11639352.31406 +1828 1700 9149300.058182 +1829 1700 -20870649.36111 +1701 1701 619629140.0329 +1702 1701 1.168251037598e-05 +1703 1701 925940.5938052 +1704 1701 84152766.23505 +1705 1701 -4.991888999939e-06 +1706 1701 231485.148566 +1713 1701 -52284795.20658 +1714 1701 -36666666.66065 +1715 1701 2505785.203048 +1716 1701 -138432799.5 +1717 1701 1.490116119385e-07 +1718 1701 -462970.296923 +1719 1701 -52308469.44899 +1720 1701 36666666.66065 +1721 1701 -2702548.129425 +1797 1701 -18569369.18862 +1798 1701 9166666.669678 +1799 1701 10279397.69313 +1800 1701 -59565882.98117 +1801 1701 4.91738319397e-07 +1802 1701 43739118.52961 +1803 1701 -20057887.18154 +1804 1701 -9166666.669679 +1805 1701 11581481.02689 +1809 1701 -1129879.778007 +1810 1701 2.369284629822e-06 +1811 1701 57871.28717239 +1812 1701 54280296.46473 +1813 1701 3.09944152832e-06 +1814 1701 231485.1485852 +1815 1701 -7107625.989141 +1816 1701 -6.146728992462e-06 +1817 1701 57871.2871768 +1824 1701 -18663081.30986 +1825 1701 -9166666.669677 +1826 1701 -10337268.9803 +1827 1701 -59964405.70834 +1828 1701 7.525086402893e-07 +1829 1701 -43970603.67818 +1830 1701 -20163436.42398 +1831 1701 9166666.669676 +1832 1701 -11639352.31406 +1702 1702 531622789.3528 +1703 1702 -11110935.09172 +1704 1702 -4.798173904419e-06 +1705 1702 -55180296.03374 +1706 1702 5555467.545859 +1713 1702 -36666666.66065 +1714 1702 -41284001.36615 +1715 1702 1263866.887163 +1716 1702 -5.960464477539e-08 +1717 1702 22901850.42796 +1718 1702 -2777733.774299 +1719 1702 36666666.66064 +1720 1702 -41307675.60857 +1721 1702 1513866.887135 +1797 1702 9166666.669678 +1798 1702 -15819170.72716 +1799 1702 -8385422.169798 +1800 1702 -5.811452865601e-07 +1801 1702 -19232220.47929 +1802 1702 -694433.4439163 +1803 1702 -9166666.669679 +1804 1702 -17307688.72007 +1805 1702 9079855.613715 +1809 1702 2.913177013397e-06 +1810 1702 -35963145.36236 +1811 1702 -33694466.44041 +1812 1702 3.635883331299e-06 +1813 1702 32278708.78388 +1814 1702 -2777733.774297 +1815 1702 -5.349516868591e-06 +1816 1702 -41940891.5735 +1817 1702 36472200.21471 +1824 1702 -9166666.669677 +1825 1702 -15912882.8484 +1826 1702 -8454866.614265 +1827 1702 3.725290298462e-07 +1828 1702 -19630743.20649 +1829 1702 -694433.4439167 +1830 1702 9166666.669676 +1831 1702 -17413237.96253 +1832 1702 9149300.058182 +1703 1703 599591912.5003 +1704 1703 231485.1485663 +1705 1703 5555467.545859 +1706 1703 78550735.85485 +1713 1703 2471062.980849 +1714 1703 1236089.109403 +1715 1703 -7832062.870945 +1716 1703 -462970.2969232 +1717 1703 -2777733.774298 +1718 1703 39890623.87246 +1719 1703 -2737270.351624 +1720 1703 1541644.664895 +1721 1703 -7895194.184061 +1797 1703 10279397.69313 +1798 1703 -8385422.169798 +1799 1703 -16619803.40013 +1800 1703 43704396.30741 +1801 1703 -694433.4439163 +1802 1703 -56581165.5979 +1803 1703 11581481.02689 +1804 1703 9079855.613715 +1805 1703 -20589184.71456 +1809 1703 57871.28717278 +1810 1703 -33666688.66265 +1811 1703 -39477172.9523 +1812 1703 231485.148585 +1813 1703 -2777733.774298 +1814 1703 -118440658.1206 +1815 1703 57871.28717716 +1816 1703 36444422.43695 +1817 1703 -55417829.51533 +1824 1703 -10337268.9803 +1825 1703 -8454866.614265 +1826 1703 -16869702.39011 +1827 1703 -43935881.45598 +1828 1703 -694433.4439167 +1829 1703 -57643892.87044 +1830 1703 -11639352.31406 +1831 1703 9149300.058182 +1832 1703 -20870649.36111 +1704 1704 671761428.9985 +1705 1704 36667432.73655 +1706 1704 3125088.651632 +1707 1704 19448570.31785 +1708 1704 -36666973.09101 +1709 1704 2702570.135099 +1716 1704 -52284795.20658 +1717 1704 -36666666.66065 +1718 1704 2505785.203048 +1719 1704 -138432799.5 +1720 1704 1.490116119385e-07 +1721 1704 -462970.296923 +1722 1704 -52308469.44899 +1723 1704 36666666.66065 +1724 1704 -2702548.129425 +1800 1704 -18569369.18862 +1801 1704 9166666.669678 +1802 1704 10279397.69313 +1803 1704 -72039530.38171 +1804 1704 -9166781.581061 +1805 1704 43189554.83944 +1812 1704 -1129879.778007 +1813 1704 2.369284629822e-06 +1814 1704 57871.28717239 +1815 1704 73599694.87993 +1816 1704 9166858.188655 +1817 1704 781226.7976368 +1818 1704 -19443104.86928 +1819 1704 -9166743.27727 +1820 1704 11639449.48452 +1827 1704 -18663081.30986 +1828 1704 -9166666.669677 +1829 1704 -10337268.9803 +1830 1704 -59964405.70834 +1831 1704 7.525086402893e-07 +1832 1704 -43970603.67818 +1833 1704 -20163436.42398 +1834 1704 9166666.669676 +1835 1704 -11639352.31406 +1705 1705 572753939.719 +1706 1705 -8610914.043003 +1707 1705 -36667126.30619 +1708 1705 -108884310.9615 +1709 1705 4611018.689007 +1716 1705 -36666666.66065 +1717 1705 -41284001.36615 +1718 1705 1263866.887163 +1719 1705 -5.960464477539e-08 +1720 1705 22901850.42796 +1721 1705 -2777733.774299 +1722 1705 36666666.66064 +1723 1705 -41307675.60857 +1724 1705 1513866.887135 +1800 1705 9166666.669678 +1801 1705 -15819170.72716 +1802 1705 -8385422.169798 +1803 1705 -9166743.277267 +1804 1705 -28955430.01587 +1805 1705 7996602.428466 +1812 1705 2.913177013397e-06 +1813 1705 -35963145.36236 +1814 1705 -33694466.44041 +1815 1705 9166858.188655 +1816 1705 48847822.54786 +1817 1705 -2152764.803778 +1818 1705 -9166781.581064 +1819 1705 -51526325.20493 +1820 1705 36236271.0855 +1827 1705 -9166666.669677 +1828 1705 -15912882.8484 +1829 1705 -8454866.614265 +1830 1705 3.725290298462e-07 +1831 1705 -19630743.20649 +1832 1705 -694433.4439167 +1833 1705 9166666.669676 +1834 1705 -17413237.96253 +1835 1705 9149300.058182 +1706 1706 607013167.9741 +1707 1706 2737303.360137 +1708 1706 5388804.78494 +1709 1706 37600883.93994 +1716 1706 2471062.980849 +1717 1706 1236089.109403 +1718 1706 -7832062.870945 +1719 1706 -462970.2969232 +1720 1706 -2777733.774298 +1721 1706 39890623.87246 +1722 1706 -2737270.351624 +1723 1706 1541644.664895 +1724 1706 -7895194.184061 +1800 1706 10279397.69313 +1801 1706 -8385422.169798 +1802 1706 -16619803.40013 +1803 1706 43154829.95728 +1804 1706 7802192.5578 +1805 1706 -56944833.0873 +1812 1706 57871.28717278 +1813 1706 -33666688.66265 +1814 1706 -39477172.9523 +1815 1706 781318.4370322 +1816 1706 -2152691.493423 +1817 1706 -99821807.80486 +1818 1706 11639498.06975 +1819 1706 36402939.91804 +1820 1706 -55413772.21342 +1827 1706 -10337268.9803 +1828 1706 -8454866.614265 +1829 1706 -16869702.39011 +1830 1706 -43935881.45598 +1831 1706 -694433.4439167 +1832 1706 -57643892.87044 +1833 1706 -11639352.31406 +1834 1706 9149300.058182 +1835 1706 -20870649.36111 +1707 1707 387435706.2613 +1708 1707 36666666.66065 +1709 1707 2662175.186035 +1719 1707 -52284795.20658 +1720 1707 -36666666.66065 +1721 1707 2505785.203048 +1722 1707 -203296779.618 +1723 1707 -36666973.09101 +1724 1707 -2662152.453524 +1725 1707 12401143.47877 +1726 1707 29333639.75888 +1727 1707 -2152799.783064 +1803 1707 -4839277.140465 +1804 1707 11000114.915 +1805 1707 12370128.70975 +1815 1707 -14860172.33131 +1816 1707 -9166781.581062 +1817 1707 -10279526.39882 +1818 1707 33963705.33589 +1819 1707 9166666.669679 +1820 1707 9519894.71657 +1830 1707 -18663081.30986 +1831 1707 -9166666.669677 +1832 1707 -10337268.9803 +1833 1707 -73633660.33315 +1834 1707 -9166743.277268 +1835 1707 -44520628.22528 +1836 1707 -7828204.348046 +1837 1707 7333409.943332 +1838 1707 -9288430.506837 +1708 1708 332431392.3218 +1709 1708 -6944376.976808 +1719 1708 -36666666.66065 +1720 1708 -41284001.36615 +1721 1708 1263866.887163 +1722 1708 -36667126.30619 +1723 1708 -30960378.23954 +1724 1708 -3847226.047119 +1725 1708 44000459.63831 +1726 1708 12401143.47877 +1727 1708 2416692.493345 +1803 1708 7333409.943332 +1804 1708 -4839277.140466 +1805 1708 -6597291.372073 +1815 1708 -9166743.277267 +1816 1708 -46943392.66696 +1817 1708 -33736315.15602 +1818 1708 9166666.669679 +1819 1708 20212626.84424 +1820 1708 5347275.319281 +1830 1708 -9166666.669677 +1831 1708 -15912882.8484 +1832 1708 -8454866.614265 +1833 1708 -9166781.581064 +1834 1708 -30549559.96733 +1835 1708 -9732749.59088 +1836 1708 11000114.915 +1837 1708 -7828204.348045 +1838 1708 11145949.53617 +1709 1709 375187471.1352 +1719 1709 2471062.980849 +1720 1709 1236089.109403 +1721 1709 -7832062.870945 +1722 1709 -2662141.087263 +1723 1709 -3097217.438217 +1724 1709 -1482420.858694 +1725 1709 -3229199.674597 +1726 1709 1611128.328897 +1727 1709 33069715.94339 +1803 1709 8246752.473166 +1804 1709 -9895937.05811 +1805 1709 -12904739.04124 +1815 1709 -10279483.49692 +1816 1709 -33902984.10692 +1817 1709 -43192618.77883 +1818 1709 -8015196.919944 +1819 1709 -8680575.648187 +1820 1709 -73923722.2424 +1830 1709 -10337268.9803 +1831 1709 -8454866.614265 +1832 1709 -16869702.39011 +1833 1709 -44485903.34313 +1834 1709 -9538266.413314 +1835 1709 -61195846.2912 +1836 1709 -13932645.76025 +1837 1709 7430633.02411 +1838 1709 -20875211.59479 +1710 1710 619629140.0329 +1711 1710 1.168251037598e-05 +1712 1710 925940.5938052 +1713 1710 84152766.23505 +1714 1710 -4.991888999939e-06 +1715 1710 231485.148566 +1728 1710 -138432799.5 +1729 1710 1.490116119385e-07 +1730 1710 -462970.296923 +1731 1710 -52308469.44899 +1732 1710 36666666.66065 +1733 1710 -2702548.129425 +1806 1710 -59565882.98117 +1807 1710 4.91738319397e-07 +1808 1710 43739118.52961 +1809 1710 -20057887.18154 +1810 1710 -9166666.669679 +1811 1710 11581481.02689 +1821 1710 54280296.46473 +1822 1710 3.09944152832e-06 +1823 1710 231485.1485852 +1824 1710 -7107625.989141 +1825 1710 -6.146728992462e-06 +1826 1710 57871.2871768 +1839 1710 -59964405.70834 +1840 1710 7.525086402893e-07 +1841 1710 -43970603.67818 +1842 1710 -20163436.42398 +1843 1710 9166666.669676 +1844 1710 -11639352.31406 +1711 1711 531622789.3528 +1712 1711 -11110935.09172 +1713 1711 -4.798173904419e-06 +1714 1711 -55180296.03374 +1715 1711 5555467.545859 +1728 1711 -5.960464477539e-08 +1729 1711 22901850.42796 +1730 1711 -2777733.774299 +1731 1711 36666666.66064 +1732 1711 -41307675.60857 +1733 1711 1513866.887135 +1806 1711 -5.811452865601e-07 +1807 1711 -19232220.47929 +1808 1711 -694433.4439163 +1809 1711 -9166666.669679 +1810 1711 -17307688.72007 +1811 1711 9079855.613715 +1821 1711 3.635883331299e-06 +1822 1711 32278708.78388 +1823 1711 -2777733.774297 +1824 1711 -5.349516868591e-06 +1825 1711 -41940891.5735 +1826 1711 36472200.21471 +1839 1711 3.725290298462e-07 +1840 1711 -19630743.20649 +1841 1711 -694433.4439167 +1842 1711 9166666.669676 +1843 1711 -17413237.96253 +1844 1711 9149300.058182 +1712 1712 599591912.5003 +1713 1712 231485.1485663 +1714 1712 5555467.545859 +1715 1712 78550735.85485 +1728 1712 -462970.2969232 +1729 1712 -2777733.774298 +1730 1712 39890623.87246 +1731 1712 -2737270.351624 +1732 1712 1541644.664895 +1733 1712 -7895194.184061 +1806 1712 43704396.30741 +1807 1712 -694433.4439163 +1808 1712 -56581165.5979 +1809 1712 11581481.02689 +1810 1712 9079855.613715 +1811 1712 -20589184.71456 +1821 1712 231485.148585 +1822 1712 -2777733.774298 +1823 1712 -118440658.1206 +1824 1712 57871.28717716 +1825 1712 36444422.43695 +1826 1712 -55417829.51533 +1839 1712 -43935881.45598 +1840 1712 -694433.4439167 +1841 1712 -57643892.87044 +1842 1712 -11639352.31406 +1843 1712 9149300.058182 +1844 1712 -20870649.36111 +1713 1713 619629140.0329 +1714 1713 1.168251037598e-05 +1715 1713 925940.5938052 +1716 1713 84152766.23505 +1717 1713 -4.991888999939e-06 +1718 1713 231485.148566 +1728 1713 -52284795.20658 +1729 1713 -36666666.66065 +1730 1713 2505785.203048 +1731 1713 -138432799.5 +1732 1713 1.490116119385e-07 +1733 1713 -462970.296923 +1734 1713 -52308469.44899 +1735 1713 36666666.66065 +1736 1713 -2702548.129425 +1806 1713 -18569369.18862 +1807 1713 9166666.669678 +1808 1713 10279397.69313 +1809 1713 -59565882.98117 +1810 1713 4.91738319397e-07 +1811 1713 43739118.52961 +1812 1713 -20057887.18154 +1813 1713 -9166666.669679 +1814 1713 11581481.02689 +1821 1713 -1129879.778007 +1822 1713 2.369284629822e-06 +1823 1713 57871.28717239 +1824 1713 54280296.46473 +1825 1713 3.09944152832e-06 +1826 1713 231485.1485852 +1827 1713 -7107625.989141 +1828 1713 -6.146728992462e-06 +1829 1713 57871.2871768 +1839 1713 -18663081.30986 +1840 1713 -9166666.669677 +1841 1713 -10337268.9803 +1842 1713 -59964405.70834 +1843 1713 7.525086402893e-07 +1844 1713 -43970603.67818 +1845 1713 -20163436.42398 +1846 1713 9166666.669676 +1847 1713 -11639352.31406 +1714 1714 531622789.3528 +1715 1714 -11110935.09172 +1716 1714 -4.798173904419e-06 +1717 1714 -55180296.03374 +1718 1714 5555467.545859 +1728 1714 -36666666.66065 +1729 1714 -41284001.36615 +1730 1714 1263866.887163 +1731 1714 -5.960464477539e-08 +1732 1714 22901850.42796 +1733 1714 -2777733.774299 +1734 1714 36666666.66064 +1735 1714 -41307675.60857 +1736 1714 1513866.887135 +1806 1714 9166666.669678 +1807 1714 -15819170.72716 +1808 1714 -8385422.169798 +1809 1714 -5.811452865601e-07 +1810 1714 -19232220.47929 +1811 1714 -694433.4439163 +1812 1714 -9166666.669679 +1813 1714 -17307688.72007 +1814 1714 9079855.613715 +1821 1714 2.913177013397e-06 +1822 1714 -35963145.36236 +1823 1714 -33694466.44041 +1824 1714 3.635883331299e-06 +1825 1714 32278708.78388 +1826 1714 -2777733.774297 +1827 1714 -5.349516868591e-06 +1828 1714 -41940891.5735 +1829 1714 36472200.21471 +1839 1714 -9166666.669677 +1840 1714 -15912882.8484 +1841 1714 -8454866.614265 +1842 1714 3.725290298462e-07 +1843 1714 -19630743.20649 +1844 1714 -694433.4439167 +1845 1714 9166666.669676 +1846 1714 -17413237.96253 +1847 1714 9149300.058182 +1715 1715 599591912.5003 +1716 1715 231485.1485663 +1717 1715 5555467.545859 +1718 1715 78550735.85485 +1728 1715 2471062.980849 +1729 1715 1236089.109403 +1730 1715 -7832062.870945 +1731 1715 -462970.2969232 +1732 1715 -2777733.774298 +1733 1715 39890623.87246 +1734 1715 -2737270.351624 +1735 1715 1541644.664895 +1736 1715 -7895194.184061 +1806 1715 10279397.69313 +1807 1715 -8385422.169798 +1808 1715 -16619803.40013 +1809 1715 43704396.30741 +1810 1715 -694433.4439163 +1811 1715 -56581165.5979 +1812 1715 11581481.02689 +1813 1715 9079855.613715 +1814 1715 -20589184.71456 +1821 1715 57871.28717278 +1822 1715 -33666688.66265 +1823 1715 -39477172.9523 +1824 1715 231485.148585 +1825 1715 -2777733.774298 +1826 1715 -118440658.1206 +1827 1715 57871.28717716 +1828 1715 36444422.43695 +1829 1715 -55417829.51533 +1839 1715 -10337268.9803 +1840 1715 -8454866.614265 +1841 1715 -16869702.39011 +1842 1715 -43935881.45598 +1843 1715 -694433.4439167 +1844 1715 -57643892.87044 +1845 1715 -11639352.31406 +1846 1715 9149300.058182 +1847 1715 -20870649.36111 +1716 1716 619629140.0329 +1717 1716 1.168251037598e-05 +1718 1716 925940.5938052 +1719 1716 84152766.23505 +1720 1716 -4.991888999939e-06 +1721 1716 231485.148566 +1731 1716 -52284795.20658 +1732 1716 -36666666.66065 +1733 1716 2505785.203048 +1734 1716 -138432799.5 +1735 1716 1.490116119385e-07 +1736 1716 -462970.296923 +1737 1716 -52308469.44899 +1738 1716 36666666.66065 +1739 1716 -2702548.129425 +1809 1716 -18569369.18862 +1810 1716 9166666.669678 +1811 1716 10279397.69313 +1812 1716 -59565882.98117 +1813 1716 4.91738319397e-07 +1814 1716 43739118.52961 +1815 1716 -20057887.18154 +1816 1716 -9166666.669679 +1817 1716 11581481.02689 +1824 1716 -1129879.778007 +1825 1716 2.369284629822e-06 +1826 1716 57871.28717239 +1827 1716 54280296.46473 +1828 1716 3.09944152832e-06 +1829 1716 231485.1485852 +1830 1716 -7107625.989141 +1831 1716 -6.146728992462e-06 +1832 1716 57871.2871768 +1842 1716 -18663081.30986 +1843 1716 -9166666.669677 +1844 1716 -10337268.9803 +1845 1716 -59964405.70834 +1846 1716 7.525086402893e-07 +1847 1716 -43970603.67818 +1848 1716 -20163436.42398 +1849 1716 9166666.669676 +1850 1716 -11639352.31406 +1717 1717 531622789.3528 +1718 1717 -11110935.09172 +1719 1717 -4.798173904419e-06 +1720 1717 -55180296.03374 +1721 1717 5555467.545859 +1731 1717 -36666666.66065 +1732 1717 -41284001.36615 +1733 1717 1263866.887163 +1734 1717 -5.960464477539e-08 +1735 1717 22901850.42796 +1736 1717 -2777733.774299 +1737 1717 36666666.66064 +1738 1717 -41307675.60857 +1739 1717 1513866.887135 +1809 1717 9166666.669678 +1810 1717 -15819170.72716 +1811 1717 -8385422.169798 +1812 1717 -5.811452865601e-07 +1813 1717 -19232220.47929 +1814 1717 -694433.4439163 +1815 1717 -9166666.669679 +1816 1717 -17307688.72007 +1817 1717 9079855.613715 +1824 1717 2.913177013397e-06 +1825 1717 -35963145.36236 +1826 1717 -33694466.44041 +1827 1717 3.635883331299e-06 +1828 1717 32278708.78388 +1829 1717 -2777733.774297 +1830 1717 -5.349516868591e-06 +1831 1717 -41940891.5735 +1832 1717 36472200.21471 +1842 1717 -9166666.669677 +1843 1717 -15912882.8484 +1844 1717 -8454866.614265 +1845 1717 3.725290298462e-07 +1846 1717 -19630743.20649 +1847 1717 -694433.4439167 +1848 1717 9166666.669676 +1849 1717 -17413237.96253 +1850 1717 9149300.058182 +1718 1718 599591912.5003 +1719 1718 231485.1485663 +1720 1718 5555467.545859 +1721 1718 78550735.85485 +1731 1718 2471062.980849 +1732 1718 1236089.109403 +1733 1718 -7832062.870945 +1734 1718 -462970.2969232 +1735 1718 -2777733.774298 +1736 1718 39890623.87246 +1737 1718 -2737270.351624 +1738 1718 1541644.664895 +1739 1718 -7895194.184061 +1809 1718 10279397.69313 +1810 1718 -8385422.169798 +1811 1718 -16619803.40013 +1812 1718 43704396.30741 +1813 1718 -694433.4439163 +1814 1718 -56581165.5979 +1815 1718 11581481.02689 +1816 1718 9079855.613715 +1817 1718 -20589184.71456 +1824 1718 57871.28717278 +1825 1718 -33666688.66265 +1826 1718 -39477172.9523 +1827 1718 231485.148585 +1828 1718 -2777733.774298 +1829 1718 -118440658.1206 +1830 1718 57871.28717716 +1831 1718 36444422.43695 +1832 1718 -55417829.51533 +1842 1718 -10337268.9803 +1843 1718 -8454866.614265 +1844 1718 -16869702.39011 +1845 1718 -43935881.45598 +1846 1718 -694433.4439167 +1847 1718 -57643892.87044 +1848 1718 -11639352.31406 +1849 1718 9149300.058182 +1850 1718 -20870649.36111 +1719 1719 619629140.0329 +1720 1719 1.168251037598e-05 +1721 1719 925940.5938052 +1722 1719 84152766.23505 +1723 1719 -4.991888999939e-06 +1724 1719 231485.148566 +1734 1719 -52284795.20658 +1735 1719 -36666666.66065 +1736 1719 2505785.203048 +1737 1719 -138432799.5 +1738 1719 1.490116119385e-07 +1739 1719 -462970.296923 +1740 1719 -52308469.44899 +1741 1719 36666666.66065 +1742 1719 -2702548.129425 +1812 1719 -18569369.18862 +1813 1719 9166666.669678 +1814 1719 10279397.69313 +1815 1719 -59565882.98117 +1816 1719 4.91738319397e-07 +1817 1719 43739118.52961 +1818 1719 -20057887.18154 +1819 1719 -9166666.669679 +1820 1719 11581481.02689 +1827 1719 -1129879.778007 +1828 1719 2.369284629822e-06 +1829 1719 57871.28717239 +1830 1719 54280296.46473 +1831 1719 3.09944152832e-06 +1832 1719 231485.1485852 +1833 1719 -7107625.989141 +1834 1719 -6.146728992462e-06 +1835 1719 57871.2871768 +1845 1719 -18663081.30986 +1846 1719 -9166666.669677 +1847 1719 -10337268.9803 +1848 1719 -59964405.70834 +1849 1719 7.525086402893e-07 +1850 1719 -43970603.67818 +1851 1719 -20163436.42398 +1852 1719 9166666.669676 +1853 1719 -11639352.31406 +1720 1720 531622789.3528 +1721 1720 -11110935.09172 +1722 1720 -4.798173904419e-06 +1723 1720 -55180296.03374 +1724 1720 5555467.545859 +1734 1720 -36666666.66065 +1735 1720 -41284001.36615 +1736 1720 1263866.887163 +1737 1720 -5.960464477539e-08 +1738 1720 22901850.42796 +1739 1720 -2777733.774299 +1740 1720 36666666.66064 +1741 1720 -41307675.60857 +1742 1720 1513866.887135 +1812 1720 9166666.669678 +1813 1720 -15819170.72716 +1814 1720 -8385422.169798 +1815 1720 -5.811452865601e-07 +1816 1720 -19232220.47929 +1817 1720 -694433.4439163 +1818 1720 -9166666.669679 +1819 1720 -17307688.72007 +1820 1720 9079855.613715 +1827 1720 2.913177013397e-06 +1828 1720 -35963145.36236 +1829 1720 -33694466.44041 +1830 1720 3.635883331299e-06 +1831 1720 32278708.78388 +1832 1720 -2777733.774297 +1833 1720 -5.349516868591e-06 +1834 1720 -41940891.5735 +1835 1720 36472200.21471 +1845 1720 -9166666.669677 +1846 1720 -15912882.8484 +1847 1720 -8454866.614265 +1848 1720 3.725290298462e-07 +1849 1720 -19630743.20649 +1850 1720 -694433.4439167 +1851 1720 9166666.669676 +1852 1720 -17413237.96253 +1853 1720 9149300.058182 +1721 1721 599591912.5003 +1722 1721 231485.1485663 +1723 1721 5555467.545859 +1724 1721 78550735.85485 +1734 1721 2471062.980849 +1735 1721 1236089.109403 +1736 1721 -7832062.870945 +1737 1721 -462970.2969232 +1738 1721 -2777733.774298 +1739 1721 39890623.87246 +1740 1721 -2737270.351624 +1741 1721 1541644.664895 +1742 1721 -7895194.184061 +1812 1721 10279397.69313 +1813 1721 -8385422.169798 +1814 1721 -16619803.40013 +1815 1721 43704396.30741 +1816 1721 -694433.4439163 +1817 1721 -56581165.5979 +1818 1721 11581481.02689 +1819 1721 9079855.613715 +1820 1721 -20589184.71456 +1827 1721 57871.28717278 +1828 1721 -33666688.66265 +1829 1721 -39477172.9523 +1830 1721 231485.148585 +1831 1721 -2777733.774298 +1832 1721 -118440658.1206 +1833 1721 57871.28717716 +1834 1721 36444422.43695 +1835 1721 -55417829.51533 +1845 1721 -10337268.9803 +1846 1721 -8454866.614265 +1847 1721 -16869702.39011 +1848 1721 -43935881.45598 +1849 1721 -694433.4439167 +1850 1721 -57643892.87044 +1851 1721 -11639352.31406 +1852 1721 9149300.058182 +1853 1721 -20870649.36111 +1722 1722 671761428.9985 +1723 1722 36667432.73655 +1724 1722 3125088.651632 +1725 1722 19448570.31785 +1726 1722 -36666973.09101 +1727 1722 2702570.135099 +1737 1722 -52284795.20658 +1738 1722 -36666666.66065 +1739 1722 2505785.203048 +1740 1722 -138432799.5 +1741 1722 1.490116119385e-07 +1742 1722 -462970.296923 +1743 1722 -52308469.44899 +1744 1722 36666666.66065 +1745 1722 -2702548.129425 +1815 1722 -18569369.18862 +1816 1722 9166666.669678 +1817 1722 10279397.69313 +1818 1722 -72039530.38171 +1819 1722 -9166781.581061 +1820 1722 43189554.83944 +1830 1722 -1129879.778007 +1831 1722 2.369284629822e-06 +1832 1722 57871.28717239 +1833 1722 73599694.87993 +1834 1722 9166858.188655 +1835 1722 781226.7976368 +1836 1722 -19443104.86928 +1837 1722 -9166743.27727 +1838 1722 11639449.48452 +1848 1722 -18663081.30986 +1849 1722 -9166666.669677 +1850 1722 -10337268.9803 +1851 1722 -59964405.70834 +1852 1722 7.525086402893e-07 +1853 1722 -43970603.67818 +1854 1722 -20163436.42398 +1855 1722 9166666.669676 +1856 1722 -11639352.31406 +1723 1723 572753939.719 +1724 1723 -8610914.043003 +1725 1723 -36667126.30619 +1726 1723 -108884310.9615 +1727 1723 4611018.689007 +1737 1723 -36666666.66065 +1738 1723 -41284001.36615 +1739 1723 1263866.887163 +1740 1723 -5.960464477539e-08 +1741 1723 22901850.42796 +1742 1723 -2777733.774299 +1743 1723 36666666.66064 +1744 1723 -41307675.60857 +1745 1723 1513866.887135 +1815 1723 9166666.669678 +1816 1723 -15819170.72716 +1817 1723 -8385422.169798 +1818 1723 -9166743.277267 +1819 1723 -28955430.01587 +1820 1723 7996602.428466 +1830 1723 2.913177013397e-06 +1831 1723 -35963145.36236 +1832 1723 -33694466.44041 +1833 1723 9166858.188655 +1834 1723 48847822.54786 +1835 1723 -2152764.803778 +1836 1723 -9166781.581064 +1837 1723 -51526325.20493 +1838 1723 36236271.0855 +1848 1723 -9166666.669677 +1849 1723 -15912882.8484 +1850 1723 -8454866.614265 +1851 1723 3.725290298462e-07 +1852 1723 -19630743.20649 +1853 1723 -694433.4439167 +1854 1723 9166666.669676 +1855 1723 -17413237.96253 +1856 1723 9149300.058182 +1724 1724 607013167.9741 +1725 1724 2737303.360137 +1726 1724 5388804.78494 +1727 1724 37600883.93994 +1737 1724 2471062.980849 +1738 1724 1236089.109403 +1739 1724 -7832062.870945 +1740 1724 -462970.2969232 +1741 1724 -2777733.774298 +1742 1724 39890623.87246 +1743 1724 -2737270.351624 +1744 1724 1541644.664895 +1745 1724 -7895194.184061 +1815 1724 10279397.69313 +1816 1724 -8385422.169798 +1817 1724 -16619803.40013 +1818 1724 43154829.95728 +1819 1724 7802192.5578 +1820 1724 -56944833.0873 +1830 1724 57871.28717278 +1831 1724 -33666688.66265 +1832 1724 -39477172.9523 +1833 1724 781318.4370322 +1834 1724 -2152691.493423 +1835 1724 -99821807.80486 +1836 1724 11639498.06975 +1837 1724 36402939.91804 +1838 1724 -55413772.21342 +1848 1724 -10337268.9803 +1849 1724 -8454866.614265 +1850 1724 -16869702.39011 +1851 1724 -43935881.45598 +1852 1724 -694433.4439167 +1853 1724 -57643892.87044 +1854 1724 -11639352.31406 +1855 1724 9149300.058182 +1856 1724 -20870649.36111 +1725 1725 498363702.219 +1726 1725 -28869531.02742 +1727 1725 -1239775.021335 +1740 1725 -52284795.20658 +1741 1725 -36666666.66065 +1742 1725 2505785.203048 +1743 1725 -52009283.16359 +1744 1725 28863804.2588 +1745 1725 -287932.3683392 +1746 1725 -294718966.1837 +1747 1725 29339060.09713 +1748 1725 -277851.0500069 +1818 1725 -4839277.140465 +1819 1725 11000114.915 +1820 1725 12370128.70975 +1833 1725 -14860172.33131 +1834 1725 -9166781.581062 +1835 1725 -10279526.39882 +1836 1725 73338606.72416 +1837 1725 -7080721.947104 +1838 1725 4620199.485418 +1851 1725 -18663081.30986 +1852 1725 -9166666.669677 +1853 1725 -10337268.9803 +1854 1725 -27228255.66332 +1855 1725 7079394.610295 +1856 1725 -24516102.56983 +1857 1725 -69564509.4735 +1858 1725 7334660.672553 +1859 1725 -1076310.000064 +1726 1726 966174720.2427 +1727 1726 -12914947.41583 +1740 1726 -36666666.66065 +1741 1726 -41284001.36615 +1742 1726 1263866.887163 +1743 1726 28860940.8745 +1744 1726 90863993.22883 +1745 1726 -2003561.139996 +1746 1726 44008590.1457 +1747 1726 -788071173.1609 +1748 1726 6655116.515009 +1818 1726 7333409.943332 +1819 1726 -4839277.140466 +1820 1726 -6597291.372073 +1833 1726 -9166743.277267 +1834 1726 -46943392.66696 +1835 1726 -33736315.15602 +1836 1726 -7080721.947105 +1837 1726 181183500.3014 +1838 1726 835990.2504258 +1851 1726 -9166666.669677 +1852 1726 -15912882.8484 +1853 1726 -8454866.614265 +1854 1726 7078730.941889 +1855 1726 8550937.821368 +1856 1726 6326759.532925 +1857 1726 11001991.00883 +1858 1726 -183855574.6612 +1859 1726 18420659.28497 +1727 1727 530415847.6868 +1740 1727 2471062.980849 +1741 1727 1236089.109403 +1742 1727 -7832062.870945 +1743 1727 -1051786.06317 +1744 1727 -1892360.826072 +1745 1727 49178308.71143 +1746 1727 -416776.5750104 +1747 1727 6544119.890423 +1748 1727 -292565036.1794 +1818 1727 8246752.473166 +1819 1727 -9895937.05811 +1820 1727 -12904739.04124 +1833 1727 -10279483.49692 +1834 1727 -33902984.10692 +1835 1727 -43192618.77883 +1836 1727 -5154149.08713 +1837 1727 -6926837.903859 +1838 1727 4243293.054075 +1851 1727 -10337268.9803 +1852 1727 -8454866.614265 +1853 1727 -16869702.39011 +1854 1727 -24689705.53948 +1855 1727 6382974.380012 +1856 1727 -24906443.9538 +1857 1727 -1614465.000096 +1858 1727 17990055.19208 +1859 1727 -71214293.40827 +1728 1728 619629140.0329 +1729 1728 1.168251037598e-05 +1730 1728 925940.5938052 +1731 1728 84152766.23505 +1732 1728 -4.991888999939e-06 +1733 1728 231485.148566 +1749 1728 -138432799.5 +1750 1728 1.490116119385e-07 +1751 1728 -462970.296923 +1752 1728 -52308469.44899 +1753 1728 36666666.66065 +1754 1728 -2702548.129425 +1821 1728 -59565882.98117 +1822 1728 4.91738319397e-07 +1823 1728 43739118.52961 +1824 1728 -20057887.18154 +1825 1728 -9166666.669679 +1826 1728 11581481.02689 +1839 1728 54280296.46473 +1840 1728 3.09944152832e-06 +1841 1728 231485.1485852 +1842 1728 -7107625.989141 +1843 1728 -6.146728992462e-06 +1844 1728 57871.2871768 +1860 1728 -59964405.70834 +1861 1728 7.525086402893e-07 +1862 1728 -43970603.67818 +1863 1728 -20163436.42398 +1864 1728 9166666.669676 +1865 1728 -11639352.31406 +1729 1729 531622789.3528 +1730 1729 -11110935.09172 +1731 1729 -4.798173904419e-06 +1732 1729 -55180296.03374 +1733 1729 5555467.545859 +1749 1729 -5.960464477539e-08 +1750 1729 22901850.42796 +1751 1729 -2777733.774299 +1752 1729 36666666.66064 +1753 1729 -41307675.60857 +1754 1729 1513866.887135 +1821 1729 -5.811452865601e-07 +1822 1729 -19232220.47929 +1823 1729 -694433.4439163 +1824 1729 -9166666.669679 +1825 1729 -17307688.72007 +1826 1729 9079855.613715 +1839 1729 3.635883331299e-06 +1840 1729 32278708.78388 +1841 1729 -2777733.774297 +1842 1729 -5.349516868591e-06 +1843 1729 -41940891.5735 +1844 1729 36472200.21471 +1860 1729 3.725290298462e-07 +1861 1729 -19630743.20649 +1862 1729 -694433.4439167 +1863 1729 9166666.669676 +1864 1729 -17413237.96253 +1865 1729 9149300.058182 +1730 1730 599591912.5003 +1731 1730 231485.1485663 +1732 1730 5555467.545859 +1733 1730 78550735.85485 +1749 1730 -462970.2969232 +1750 1730 -2777733.774298 +1751 1730 39890623.87246 +1752 1730 -2737270.351624 +1753 1730 1541644.664895 +1754 1730 -7895194.184061 +1821 1730 43704396.30741 +1822 1730 -694433.4439163 +1823 1730 -56581165.5979 +1824 1730 11581481.02689 +1825 1730 9079855.613715 +1826 1730 -20589184.71456 +1839 1730 231485.148585 +1840 1730 -2777733.774298 +1841 1730 -118440658.1206 +1842 1730 57871.28717716 +1843 1730 36444422.43695 +1844 1730 -55417829.51533 +1860 1730 -43935881.45598 +1861 1730 -694433.4439167 +1862 1730 -57643892.87044 +1863 1730 -11639352.31406 +1864 1730 9149300.058182 +1865 1730 -20870649.36111 +1731 1731 619629140.0329 +1732 1731 1.168251037598e-05 +1733 1731 925940.5938052 +1734 1731 84152766.23505 +1735 1731 -4.991888999939e-06 +1736 1731 231485.148566 +1749 1731 -52284795.20658 +1750 1731 -36666666.66065 +1751 1731 2505785.203048 +1752 1731 -138432799.5 +1753 1731 1.490116119385e-07 +1754 1731 -462970.296923 +1755 1731 -52308469.44899 +1756 1731 36666666.66065 +1757 1731 -2702548.129425 +1821 1731 -18569369.18862 +1822 1731 9166666.669678 +1823 1731 10279397.69313 +1824 1731 -59565882.98117 +1825 1731 4.91738319397e-07 +1826 1731 43739118.52961 +1827 1731 -20057887.18154 +1828 1731 -9166666.669679 +1829 1731 11581481.02689 +1839 1731 -1129879.778007 +1840 1731 2.369284629822e-06 +1841 1731 57871.28717239 +1842 1731 54280296.46473 +1843 1731 3.09944152832e-06 +1844 1731 231485.1485852 +1845 1731 -7107625.989141 +1846 1731 -6.146728992462e-06 +1847 1731 57871.2871768 +1860 1731 -18663081.30986 +1861 1731 -9166666.669677 +1862 1731 -10337268.9803 +1863 1731 -59964405.70834 +1864 1731 7.525086402893e-07 +1865 1731 -43970603.67818 +1866 1731 -20163436.42398 +1867 1731 9166666.669676 +1868 1731 -11639352.31406 +1732 1732 531622789.3528 +1733 1732 -11110935.09172 +1734 1732 -4.798173904419e-06 +1735 1732 -55180296.03374 +1736 1732 5555467.545859 +1749 1732 -36666666.66065 +1750 1732 -41284001.36615 +1751 1732 1263866.887163 +1752 1732 -5.960464477539e-08 +1753 1732 22901850.42796 +1754 1732 -2777733.774299 +1755 1732 36666666.66064 +1756 1732 -41307675.60857 +1757 1732 1513866.887135 +1821 1732 9166666.669678 +1822 1732 -15819170.72716 +1823 1732 -8385422.169798 +1824 1732 -5.811452865601e-07 +1825 1732 -19232220.47929 +1826 1732 -694433.4439163 +1827 1732 -9166666.669679 +1828 1732 -17307688.72007 +1829 1732 9079855.613715 +1839 1732 2.913177013397e-06 +1840 1732 -35963145.36236 +1841 1732 -33694466.44041 +1842 1732 3.635883331299e-06 +1843 1732 32278708.78388 +1844 1732 -2777733.774297 +1845 1732 -5.349516868591e-06 +1846 1732 -41940891.5735 +1847 1732 36472200.21471 +1860 1732 -9166666.669677 +1861 1732 -15912882.8484 +1862 1732 -8454866.614265 +1863 1732 3.725290298462e-07 +1864 1732 -19630743.20649 +1865 1732 -694433.4439167 +1866 1732 9166666.669676 +1867 1732 -17413237.96253 +1868 1732 9149300.058182 +1733 1733 599591912.5003 +1734 1733 231485.1485663 +1735 1733 5555467.545859 +1736 1733 78550735.85485 +1749 1733 2471062.980849 +1750 1733 1236089.109403 +1751 1733 -7832062.870945 +1752 1733 -462970.2969232 +1753 1733 -2777733.774298 +1754 1733 39890623.87246 +1755 1733 -2737270.351624 +1756 1733 1541644.664895 +1757 1733 -7895194.184061 +1821 1733 10279397.69313 +1822 1733 -8385422.169798 +1823 1733 -16619803.40013 +1824 1733 43704396.30741 +1825 1733 -694433.4439163 +1826 1733 -56581165.5979 +1827 1733 11581481.02689 +1828 1733 9079855.613715 +1829 1733 -20589184.71456 +1839 1733 57871.28717278 +1840 1733 -33666688.66265 +1841 1733 -39477172.9523 +1842 1733 231485.148585 +1843 1733 -2777733.774298 +1844 1733 -118440658.1206 +1845 1733 57871.28717716 +1846 1733 36444422.43695 +1847 1733 -55417829.51533 +1860 1733 -10337268.9803 +1861 1733 -8454866.614265 +1862 1733 -16869702.39011 +1863 1733 -43935881.45598 +1864 1733 -694433.4439167 +1865 1733 -57643892.87044 +1866 1733 -11639352.31406 +1867 1733 9149300.058182 +1868 1733 -20870649.36111 +1734 1734 619629140.0329 +1735 1734 1.168251037598e-05 +1736 1734 925940.5938052 +1737 1734 84152766.23505 +1738 1734 -4.991888999939e-06 +1739 1734 231485.148566 +1752 1734 -52284795.20658 +1753 1734 -36666666.66065 +1754 1734 2505785.203048 +1755 1734 -138432799.5 +1756 1734 1.490116119385e-07 +1757 1734 -462970.296923 +1758 1734 -52308469.44899 +1759 1734 36666666.66065 +1760 1734 -2702548.129425 +1824 1734 -18569369.18862 +1825 1734 9166666.669678 +1826 1734 10279397.69313 +1827 1734 -59565882.98117 +1828 1734 4.91738319397e-07 +1829 1734 43739118.52961 +1830 1734 -20057887.18154 +1831 1734 -9166666.669679 +1832 1734 11581481.02689 +1842 1734 -1129879.778007 +1843 1734 2.369284629822e-06 +1844 1734 57871.28717239 +1845 1734 54280296.46473 +1846 1734 3.09944152832e-06 +1847 1734 231485.1485852 +1848 1734 -7107625.989141 +1849 1734 -6.146728992462e-06 +1850 1734 57871.2871768 +1863 1734 -18663081.30986 +1864 1734 -9166666.669677 +1865 1734 -10337268.9803 +1866 1734 -59964405.70834 +1867 1734 7.525086402893e-07 +1868 1734 -43970603.67818 +1869 1734 -20163436.42398 +1870 1734 9166666.669676 +1871 1734 -11639352.31406 +1735 1735 531622789.3528 +1736 1735 -11110935.09172 +1737 1735 -4.798173904419e-06 +1738 1735 -55180296.03374 +1739 1735 5555467.545859 +1752 1735 -36666666.66065 +1753 1735 -41284001.36615 +1754 1735 1263866.887163 +1755 1735 -5.960464477539e-08 +1756 1735 22901850.42796 +1757 1735 -2777733.774299 +1758 1735 36666666.66064 +1759 1735 -41307675.60857 +1760 1735 1513866.887135 +1824 1735 9166666.669678 +1825 1735 -15819170.72716 +1826 1735 -8385422.169798 +1827 1735 -5.811452865601e-07 +1828 1735 -19232220.47929 +1829 1735 -694433.4439163 +1830 1735 -9166666.669679 +1831 1735 -17307688.72007 +1832 1735 9079855.613715 +1842 1735 2.913177013397e-06 +1843 1735 -35963145.36236 +1844 1735 -33694466.44041 +1845 1735 3.635883331299e-06 +1846 1735 32278708.78388 +1847 1735 -2777733.774297 +1848 1735 -5.349516868591e-06 +1849 1735 -41940891.5735 +1850 1735 36472200.21471 +1863 1735 -9166666.669677 +1864 1735 -15912882.8484 +1865 1735 -8454866.614265 +1866 1735 3.725290298462e-07 +1867 1735 -19630743.20649 +1868 1735 -694433.4439167 +1869 1735 9166666.669676 +1870 1735 -17413237.96253 +1871 1735 9149300.058182 +1736 1736 599591912.5003 +1737 1736 231485.1485663 +1738 1736 5555467.545859 +1739 1736 78550735.85485 +1752 1736 2471062.980849 +1753 1736 1236089.109403 +1754 1736 -7832062.870945 +1755 1736 -462970.2969232 +1756 1736 -2777733.774298 +1757 1736 39890623.87246 +1758 1736 -2737270.351624 +1759 1736 1541644.664895 +1760 1736 -7895194.184061 +1824 1736 10279397.69313 +1825 1736 -8385422.169798 +1826 1736 -16619803.40013 +1827 1736 43704396.30741 +1828 1736 -694433.4439163 +1829 1736 -56581165.5979 +1830 1736 11581481.02689 +1831 1736 9079855.613715 +1832 1736 -20589184.71456 +1842 1736 57871.28717278 +1843 1736 -33666688.66265 +1844 1736 -39477172.9523 +1845 1736 231485.148585 +1846 1736 -2777733.774298 +1847 1736 -118440658.1206 +1848 1736 57871.28717716 +1849 1736 36444422.43695 +1850 1736 -55417829.51533 +1863 1736 -10337268.9803 +1864 1736 -8454866.614265 +1865 1736 -16869702.39011 +1866 1736 -43935881.45598 +1867 1736 -694433.4439167 +1868 1736 -57643892.87044 +1869 1736 -11639352.31406 +1870 1736 9149300.058182 +1871 1736 -20870649.36111 +1737 1737 619629140.0329 +1738 1737 1.168251037598e-05 +1739 1737 925940.5938052 +1740 1737 84152766.23505 +1741 1737 -4.991888999939e-06 +1742 1737 231485.148566 +1755 1737 -52284795.20658 +1756 1737 -36666666.66065 +1757 1737 2505785.203048 +1758 1737 -138432799.5 +1759 1737 1.490116119385e-07 +1760 1737 -462970.296923 +1761 1737 -52308469.44899 +1762 1737 36666666.66065 +1763 1737 -2702548.129425 +1827 1737 -18569369.18862 +1828 1737 9166666.669678 +1829 1737 10279397.69313 +1830 1737 -59565882.98117 +1831 1737 4.91738319397e-07 +1832 1737 43739118.52961 +1833 1737 -20057887.18154 +1834 1737 -9166666.669679 +1835 1737 11581481.02689 +1845 1737 -1129879.778007 +1846 1737 2.369284629822e-06 +1847 1737 57871.28717239 +1848 1737 54280296.46473 +1849 1737 3.09944152832e-06 +1850 1737 231485.1485852 +1851 1737 -7107625.989141 +1852 1737 -6.146728992462e-06 +1853 1737 57871.2871768 +1866 1737 -18663081.30986 +1867 1737 -9166666.669677 +1868 1737 -10337268.9803 +1869 1737 -59964405.70834 +1870 1737 7.525086402893e-07 +1871 1737 -43970603.67818 +1872 1737 -20163436.42398 +1873 1737 9166666.669676 +1874 1737 -11639352.31406 +1738 1738 531622789.3528 +1739 1738 -11110935.09172 +1740 1738 -4.798173904419e-06 +1741 1738 -55180296.03374 +1742 1738 5555467.545859 +1755 1738 -36666666.66065 +1756 1738 -41284001.36615 +1757 1738 1263866.887163 +1758 1738 -5.960464477539e-08 +1759 1738 22901850.42796 +1760 1738 -2777733.774299 +1761 1738 36666666.66064 +1762 1738 -41307675.60857 +1763 1738 1513866.887135 +1827 1738 9166666.669678 +1828 1738 -15819170.72716 +1829 1738 -8385422.169798 +1830 1738 -5.811452865601e-07 +1831 1738 -19232220.47929 +1832 1738 -694433.4439163 +1833 1738 -9166666.669679 +1834 1738 -17307688.72007 +1835 1738 9079855.613715 +1845 1738 2.913177013397e-06 +1846 1738 -35963145.36236 +1847 1738 -33694466.44041 +1848 1738 3.635883331299e-06 +1849 1738 32278708.78388 +1850 1738 -2777733.774297 +1851 1738 -5.349516868591e-06 +1852 1738 -41940891.5735 +1853 1738 36472200.21471 +1866 1738 -9166666.669677 +1867 1738 -15912882.8484 +1868 1738 -8454866.614265 +1869 1738 3.725290298462e-07 +1870 1738 -19630743.20649 +1871 1738 -694433.4439167 +1872 1738 9166666.669676 +1873 1738 -17413237.96253 +1874 1738 9149300.058182 +1739 1739 599591912.5003 +1740 1739 231485.1485663 +1741 1739 5555467.545859 +1742 1739 78550735.85485 +1755 1739 2471062.980849 +1756 1739 1236089.109403 +1757 1739 -7832062.870945 +1758 1739 -462970.2969232 +1759 1739 -2777733.774298 +1760 1739 39890623.87246 +1761 1739 -2737270.351624 +1762 1739 1541644.664895 +1763 1739 -7895194.184061 +1827 1739 10279397.69313 +1828 1739 -8385422.169798 +1829 1739 -16619803.40013 +1830 1739 43704396.30741 +1831 1739 -694433.4439163 +1832 1739 -56581165.5979 +1833 1739 11581481.02689 +1834 1739 9079855.613715 +1835 1739 -20589184.71456 +1845 1739 57871.28717278 +1846 1739 -33666688.66265 +1847 1739 -39477172.9523 +1848 1739 231485.148585 +1849 1739 -2777733.774298 +1850 1739 -118440658.1206 +1851 1739 57871.28717716 +1852 1739 36444422.43695 +1853 1739 -55417829.51533 +1866 1739 -10337268.9803 +1867 1739 -8454866.614265 +1868 1739 -16869702.39011 +1869 1739 -43935881.45598 +1870 1739 -694433.4439167 +1871 1739 -57643892.87044 +1872 1739 -11639352.31406 +1873 1739 9149300.058182 +1874 1739 -20870649.36111 +1740 1740 619629140.0329 +1741 1740 1.168251037598e-05 +1742 1740 925940.5938052 +1743 1740 84152766.23505 +1744 1740 -4.991888999939e-06 +1745 1740 231485.148566 +1758 1740 -52284795.20658 +1759 1740 -36666666.66065 +1760 1740 2505785.203048 +1761 1740 -138432799.5 +1762 1740 1.490116119385e-07 +1763 1740 -462970.296923 +1764 1740 -52308469.44899 +1765 1740 36666666.66065 +1766 1740 -2702548.129425 +1830 1740 -18569369.18862 +1831 1740 9166666.669678 +1832 1740 10279397.69313 +1833 1740 -59565882.98117 +1834 1740 4.91738319397e-07 +1835 1740 43739118.52961 +1836 1740 -20057887.18154 +1837 1740 -9166666.669679 +1838 1740 11581481.02689 +1848 1740 -1129879.778007 +1849 1740 2.369284629822e-06 +1850 1740 57871.28717239 +1851 1740 54280296.46473 +1852 1740 3.09944152832e-06 +1853 1740 231485.1485852 +1854 1740 -7107625.989141 +1855 1740 -6.146728992462e-06 +1856 1740 57871.2871768 +1869 1740 -18663081.30986 +1870 1740 -9166666.669677 +1871 1740 -10337268.9803 +1872 1740 -59964405.70834 +1873 1740 7.525086402893e-07 +1874 1740 -43970603.67818 +1875 1740 -20163436.42398 +1876 1740 9166666.669676 +1877 1740 -11639352.31406 +1741 1741 531622789.3528 +1742 1741 -11110935.09172 +1743 1741 -4.798173904419e-06 +1744 1741 -55180296.03374 +1745 1741 5555467.545859 +1758 1741 -36666666.66065 +1759 1741 -41284001.36615 +1760 1741 1263866.887163 +1761 1741 -5.960464477539e-08 +1762 1741 22901850.42796 +1763 1741 -2777733.774299 +1764 1741 36666666.66064 +1765 1741 -41307675.60857 +1766 1741 1513866.887135 +1830 1741 9166666.669678 +1831 1741 -15819170.72716 +1832 1741 -8385422.169798 +1833 1741 -5.811452865601e-07 +1834 1741 -19232220.47929 +1835 1741 -694433.4439163 +1836 1741 -9166666.669679 +1837 1741 -17307688.72007 +1838 1741 9079855.613715 +1848 1741 2.913177013397e-06 +1849 1741 -35963145.36236 +1850 1741 -33694466.44041 +1851 1741 3.635883331299e-06 +1852 1741 32278708.78388 +1853 1741 -2777733.774297 +1854 1741 -5.349516868591e-06 +1855 1741 -41940891.5735 +1856 1741 36472200.21471 +1869 1741 -9166666.669677 +1870 1741 -15912882.8484 +1871 1741 -8454866.614265 +1872 1741 3.725290298462e-07 +1873 1741 -19630743.20649 +1874 1741 -694433.4439167 +1875 1741 9166666.669676 +1876 1741 -17413237.96253 +1877 1741 9149300.058182 +1742 1742 599591912.5003 +1743 1742 231485.1485663 +1744 1742 5555467.545859 +1745 1742 78550735.85485 +1758 1742 2471062.980849 +1759 1742 1236089.109403 +1760 1742 -7832062.870945 +1761 1742 -462970.2969232 +1762 1742 -2777733.774298 +1763 1742 39890623.87246 +1764 1742 -2737270.351624 +1765 1742 1541644.664895 +1766 1742 -7895194.184061 +1830 1742 10279397.69313 +1831 1742 -8385422.169798 +1832 1742 -16619803.40013 +1833 1742 43704396.30741 +1834 1742 -694433.4439163 +1835 1742 -56581165.5979 +1836 1742 11581481.02689 +1837 1742 9079855.613715 +1838 1742 -20589184.71456 +1848 1742 57871.28717278 +1849 1742 -33666688.66265 +1850 1742 -39477172.9523 +1851 1742 231485.148585 +1852 1742 -2777733.774298 +1853 1742 -118440658.1206 +1854 1742 57871.28717716 +1855 1742 36444422.43695 +1856 1742 -55417829.51533 +1869 1742 -10337268.9803 +1870 1742 -8454866.614265 +1871 1742 -16869702.39011 +1872 1742 -43935881.45598 +1873 1742 -694433.4439167 +1874 1742 -57643892.87044 +1875 1742 -11639352.31406 +1876 1742 9149300.058182 +1877 1742 -20870649.36111 +1743 1743 522558998.0903 +1744 1743 17303939.58594 +1745 1743 260660.847523 +1746 1743 -103844000.8346 +1747 1743 -78331807.37615 +1748 1743 634712.287186 +1761 1743 -52284795.20658 +1762 1743 -36666666.66065 +1763 1743 2505785.203048 +1764 1743 -86773795.75742 +1765 1743 24416035.48061 +1766 1743 -106696.56214 +1767 1743 -50334865.85163 +1768 1743 7750891.435108 +1769 1743 -153554.2915443 +1833 1743 -18569369.18862 +1834 1743 9166666.669678 +1835 1743 10279397.69313 +1836 1743 -26744866.17423 +1837 1743 7078730.941889 +1838 1743 24182037.32326 +1851 1743 -1129879.778007 +1852 1743 2.369284629822e-06 +1853 1743 57871.28717239 +1854 1743 64705026.32284 +1855 1743 4462384.823563 +1856 1743 82004.83090511 +1857 1743 -37200947.50606 +1858 1743 -19582847.49834 +1859 1743 11295490.58659 +1872 1743 -18663081.30986 +1873 1743 -9166666.669677 +1874 1743 -10337268.9803 +1875 1743 -44289186.74016 +1876 1743 6104008.873161 +1877 1743 -34010528.30258 +1878 1743 -19096765.45373 +1879 1743 1937722.859732 +1880 1743 -1131791.351039 +1744 1744 657850299.5685 +1745 1744 -8367157.575223 +1746 1744 -78334670.76046 +1747 1744 -263473356.7747 +1748 1744 1658370.316677 +1761 1744 -36666666.66065 +1762 1744 -41284001.36615 +1763 1744 1263866.887163 +1764 1744 24416035.48061 +1765 1744 13565168.38836 +1766 1744 -1207997.421921 +1767 1744 7750891.435108 +1768 1744 -151877577.34 +1769 1744 1114835.39655 +1833 1744 9166666.669678 +1834 1744 -15819170.72716 +1835 1744 -8385422.169798 +1836 1744 7079394.610294 +1837 1744 9034327.310477 +1838 1744 -7293747.370667 +1851 1744 2.913177013397e-06 +1852 1744 -35963145.36236 +1853 1744 -33694466.44041 +1854 1744 4462384.823561 +1855 1744 98466467.05465 +1856 1744 -2078317.714271 +1857 1744 -19583511.16675 +1858 1744 -77107776.22533 +1859 1744 35701381.40565 +1872 1744 -9166666.669677 +1873 1744 -15912882.8484 +1874 1744 -8454866.614265 +1875 1744 6104008.87316 +1876 1744 -19204445.69136 +1877 1744 7593833.975638 +1878 1744 1937722.859732 +1879 1744 -44482443.33833 +1880 1744 16945375.52141 +1745 1745 509610127.4935 +1746 1745 600026.7011092 +1747 1745 1686238.457855 +1748 1745 -69778405.6964 +1761 1745 2471062.980849 +1762 1745 1236089.109403 +1763 1745 -7832062.870945 +1764 1745 -974752.1175541 +1765 1745 -1235775.199694 +1766 1745 43298672.25768 +1767 1745 -222998.7359433 +1768 1745 1114835.39655 +1769 1745 -37381370.73265 +1833 1745 10279397.69313 +1834 1745 -8385422.169798 +1835 1745 -16619803.40013 +1836 1745 24355640.29292 +1837 1745 -7293127.174127 +1838 1745 -23617405.31616 +1851 1745 57871.28717278 +1852 1745 -33666688.66265 +1853 1745 -39477172.9523 +1854 1745 221075.6272578 +1855 1745 -1967061.036964 +1856 1745 -49157691.6544 +1857 1745 11365034.4734 +1858 1745 35728612.04915 +1859 1745 -47418304.47711 +1872 1745 -10337268.9803 +1873 1745 -8454866.614265 +1874 1745 -16869702.39011 +1875 1745 -34184139.41185 +1876 1745 7593833.977188 +1877 1745 -49430632.70391 +1878 1745 -1131791.351039 +1879 1745 16945375.52141 +1880 1745 -26713473.31342 +1746 1746 654493853.2633 +1747 1746 18112754.50314 +1748 1746 -212467.253144 +1764 1746 -52690570.14122 +1765 1746 -32132015.60604 +1766 1746 329236.32717 +1767 1746 37843199.73853 +1768 1746 40666870.3651 +1769 1746 -165830.6701221 +1770 1746 63443900.22534 +1771 1746 -20910325.11828 +1772 1746 3494.874451399 +1773 1746 -649271.3369567 +1774 1746 28588796.47085 +1775 1746 -68238.95990977 +1836 1746 -69068054.42203 +1837 1746 11001991.00883 +1838 1746 1406080.670902 +1854 1746 -36340853.80447 +1855 1746 -19583511.16675 +1856 1746 -10969538.97004 +1857 1746 53015005.13881 +1858 1746 4510797.120458 +1859 1746 8583928.59339 +1875 1746 -19361814.47454 +1876 1746 -8033003.905469 +1877 1746 -10880711.7551 +1878 1746 -39698995.2683 +1879 1746 10154153.16224 +1880 1746 -42940020.97 +1881 1746 -23132978.83525 +1882 1746 -5210189.774588 +1883 1746 13850494.97586 +1884 1746 -17052409.61077 +1885 1746 7159763.555271 +1886 1746 -10542454.76729 +1747 1747 1235787256.67 +1748 1747 -7606192.875332 +1764 1747 -32132015.60604 +1765 1747 -14821146.93907 +1766 1747 -100707.8152143 +1767 1747 40666870.3651 +1768 1747 165409922.2218 +1769 1747 -598000.6034298 +1770 1747 -6243658.454024 +1771 1747 -7045608.663929 +1772 1747 57944.23317599 +1773 1747 28588796.47085 +1774 1747 -23907748.62226 +1775 1747 71744.56828891 +1836 1747 7334660.672553 +1837 1747 -183359119.6098 +1838 1747 -14946460.79994 +1854 1747 -19582847.49834 +1855 1747 -76247682.52375 +1856 1747 -34857716.91352 +1857 1747 4510797.120457 +1858 1747 189247624.3669 +1859 1747 -1376922.17004 +1875 1747 -8033003.905469 +1876 1747 -9894458.669336 +1877 1747 -8796010.290028 +1878 1747 10154153.16224 +1879 1747 -7795400.909588 +1880 1747 7746375.742142 +1881 1747 -1543523.106716 +1882 1747 -40759864.32944 +1883 1747 33347803.1152 +1884 1747 7159763.555271 +1885 1747 -22831199.60156 +1886 1747 16684560.25241 +1748 1748 812898545.1978 +1764 1748 294514.104971 +1765 1748 -128485.5929738 +1766 1748 -622458.5944218 +1767 1748 -269997.3367721 +1768 1748 -625778.3812032 +1769 1748 194040329.5774 +1770 1748 3494.874454618 +1771 1748 57944.23317578 +1772 1748 125559935.8517 +1773 1748 -68238.95987599 +1774 1748 71744.56828886 +1775 1748 40808809.12515 +1836 1748 937387.1139347 +1837 1748 -15321557.93441 +1838 1748 -69890413.27102 +1854 1748 -10900012.08181 +1855 1748 -34830525.94038 +1856 1748 -45124721.27286 +1857 1748 -8603293.626011 +1858 1748 -2128201.542135 +1859 1748 -82804048.59254 +1875 1748 -10880711.7551 +1876 1748 -8796010.290028 +1877 1748 -16660073.13599 +1878 1748 -42974743.19225 +1879 1748 7746375.743692 +1880 1748 -82481035.57895 +1881 1748 5725494.97511 +1882 1748 33347803.1152 +1883 1748 -72648657.74928 +1884 1748 -10542454.76729 +1885 1748 16684560.25241 +1886 1748 -34764653.8035 +1749 1749 309814570.0165 +1750 1749 6.437301635742e-06 +1751 1749 462970.2969034 +1752 1749 42076777.68823 +1753 1749 7333333.332127 +1754 1749 -318285.203467 +1839 1749 -59565882.98117 +1840 1749 4.91738319397e-07 +1841 1749 43739118.52961 +1842 1749 -20057887.18154 +1843 1749 -9166666.669679 +1844 1749 11581481.02689 +1860 1749 27139753.66166 +1861 1749 8.344650268555e-07 +1862 1749 -8738562.979764 +1863 1749 -3553812.994569 +1864 1749 1833333.333932 +1865 1749 -2293147.690507 +1750 1750 265811394.6764 +1751 1750 -5555467.545855 +1752 1750 -7333333.332131 +1753 1750 -27589753.44616 +1754 1750 2749955.995158 +1839 1750 -5.811452865601e-07 +1840 1750 -19232220.47929 +1841 1750 -694433.4439163 +1842 1750 -9166666.669679 +1843 1750 -17307688.72007 +1844 1750 9079855.613715 +1860 1750 8.940696716309e-07 +1861 1750 16138959.82123 +1862 1750 -1388866.887151 +1863 1750 -1833333.333938 +1864 1750 -20970445.78675 +1865 1750 18229155.66291 +1751 1751 299795956.2502 +1752 1751 723381.4630278 +1753 1751 2805511.550704 +1754 1751 39276420.11598 +1839 1751 43704396.30741 +1840 1751 -694433.4439163 +1841 1751 -56581165.5979 +1842 1751 11581481.02689 +1843 1751 9079855.613715 +1844 1751 -20589184.71456 +1860 1751 8796437.017353 +1861 1751 -1388866.887151 +1862 1751 -59221381.24884 +1863 1751 2351018.977684 +1864 1751 18229155.66292 +1865 1751 -27708914.75766 +1752 1752 309814570.0165 +1753 1752 6.437301635742e-06 +1754 1752 462970.2969034 +1755 1752 42076777.68823 +1756 1752 7333333.332127 +1757 1752 -318285.203467 +1839 1752 -18569369.18862 +1840 1752 9166666.669678 +1841 1752 10279397.69313 +1842 1752 -59565882.98117 +1843 1752 4.91738319397e-07 +1844 1752 43739118.52961 +1845 1752 -20057887.18154 +1846 1752 -9166666.669679 +1847 1752 11581481.02689 +1860 1752 -564939.8890041 +1861 1752 -1833333.333934 +1862 1752 -2032731.023757 +1863 1752 27139753.66166 +1864 1752 8.344650268555e-07 +1865 1752 -8738562.979764 +1866 1752 -3553812.994569 +1867 1752 1833333.333932 +1868 1752 -2293147.690507 +1753 1753 265811394.6764 +1754 1753 -5555467.545855 +1755 1753 -7333333.332131 +1756 1753 -27589753.44616 +1757 1753 2749955.995158 +1839 1753 9166666.669678 +1840 1753 -15819170.72716 +1841 1753 -8385422.169798 +1842 1753 -5.811452865601e-07 +1843 1753 -19232220.47929 +1844 1753 -694433.4439163 +1845 1753 -9166666.669679 +1846 1753 -17307688.72007 +1847 1753 9079855.613715 +1860 1753 1833333.333937 +1861 1753 -17981572.68118 +1862 1753 -16840288.77576 +1863 1753 8.940696716309e-07 +1864 1753 16138959.82123 +1865 1753 -1388866.887151 +1866 1753 -1833333.333938 +1867 1753 -20970445.78675 +1868 1753 18229155.66291 +1754 1754 299795956.2502 +1755 1754 723381.4630278 +1756 1754 2805511.550704 +1757 1754 39276420.11598 +1839 1754 10279397.69313 +1840 1754 -8385422.169798 +1841 1754 -16619803.40013 +1842 1754 43704396.30741 +1843 1754 -694433.4439163 +1844 1754 -56581165.5979 +1845 1754 11581481.02689 +1846 1754 9079855.613715 +1847 1754 -20589184.71456 +1860 1754 2090602.31093 +1861 1754 -16840288.77577 +1862 1754 -19738586.47615 +1863 1754 8796437.017353 +1864 1754 -1388866.887151 +1865 1754 -59221381.24884 +1866 1754 2351018.977684 +1867 1754 18229155.66292 +1868 1754 -27708914.75766 +1755 1755 309814570.0165 +1756 1755 6.437301635742e-06 +1757 1755 462970.2969034 +1758 1755 42076777.68823 +1759 1755 7333333.332127 +1760 1755 -318285.203467 +1842 1755 -18569369.18862 +1843 1755 9166666.669678 +1844 1755 10279397.69313 +1845 1755 -59565882.98117 +1846 1755 4.91738319397e-07 +1847 1755 43739118.52961 +1848 1755 -20057887.18154 +1849 1755 -9166666.669679 +1850 1755 11581481.02689 +1863 1755 -564939.8890041 +1864 1755 -1833333.333934 +1865 1755 -2032731.023757 +1866 1755 27139753.66166 +1867 1755 8.344650268555e-07 +1868 1755 -8738562.979764 +1869 1755 -3553812.994569 +1870 1755 1833333.333932 +1871 1755 -2293147.690507 +1756 1756 265811394.6764 +1757 1756 -5555467.545855 +1758 1756 -7333333.332131 +1759 1756 -27589753.44616 +1760 1756 2749955.995158 +1842 1756 9166666.669678 +1843 1756 -15819170.72716 +1844 1756 -8385422.169798 +1845 1756 -5.811452865601e-07 +1846 1756 -19232220.47929 +1847 1756 -694433.4439163 +1848 1756 -9166666.669679 +1849 1756 -17307688.72007 +1850 1756 9079855.613715 +1863 1756 1833333.333937 +1864 1756 -17981572.68118 +1865 1756 -16840288.77576 +1866 1756 8.940696716309e-07 +1867 1756 16138959.82123 +1868 1756 -1388866.887151 +1869 1756 -1833333.333938 +1870 1756 -20970445.78675 +1871 1756 18229155.66291 +1757 1757 299795956.2502 +1758 1757 723381.4630278 +1759 1757 2805511.550704 +1760 1757 39276420.11598 +1842 1757 10279397.69313 +1843 1757 -8385422.169798 +1844 1757 -16619803.40013 +1845 1757 43704396.30741 +1846 1757 -694433.4439163 +1847 1757 -56581165.5979 +1848 1757 11581481.02689 +1849 1757 9079855.613715 +1850 1757 -20589184.71456 +1863 1757 2090602.31093 +1864 1757 -16840288.77577 +1865 1757 -19738586.47615 +1866 1757 8796437.017353 +1867 1757 -1388866.887151 +1868 1757 -59221381.24884 +1869 1757 2351018.977684 +1870 1757 18229155.66292 +1871 1757 -27708914.75766 +1758 1758 309814570.0165 +1759 1758 6.437301635742e-06 +1760 1758 462970.2969034 +1761 1758 42076777.68823 +1762 1758 7333333.332127 +1763 1758 -318285.203467 +1845 1758 -18569369.18862 +1846 1758 9166666.669678 +1847 1758 10279397.69313 +1848 1758 -59565882.98117 +1849 1758 4.91738319397e-07 +1850 1758 43739118.52961 +1851 1758 -20057887.18154 +1852 1758 -9166666.669679 +1853 1758 11581481.02689 +1866 1758 -564939.8890041 +1867 1758 -1833333.333934 +1868 1758 -2032731.023757 +1869 1758 27139753.66166 +1870 1758 8.344650268555e-07 +1871 1758 -8738562.979764 +1872 1758 -3553812.994569 +1873 1758 1833333.333932 +1874 1758 -2293147.690507 +1759 1759 265811394.6764 +1760 1759 -5555467.545855 +1761 1759 -7333333.332131 +1762 1759 -27589753.44616 +1763 1759 2749955.995158 +1845 1759 9166666.669678 +1846 1759 -15819170.72716 +1847 1759 -8385422.169798 +1848 1759 -5.811452865601e-07 +1849 1759 -19232220.47929 +1850 1759 -694433.4439163 +1851 1759 -9166666.669679 +1852 1759 -17307688.72007 +1853 1759 9079855.613715 +1866 1759 1833333.333937 +1867 1759 -17981572.68118 +1868 1759 -16840288.77576 +1869 1759 8.940696716309e-07 +1870 1759 16138959.82123 +1871 1759 -1388866.887151 +1872 1759 -1833333.333938 +1873 1759 -20970445.78675 +1874 1759 18229155.66291 +1760 1760 299795956.2502 +1761 1760 723381.4630278 +1762 1760 2805511.550704 +1763 1760 39276420.11598 +1845 1760 10279397.69313 +1846 1760 -8385422.169798 +1847 1760 -16619803.40013 +1848 1760 43704396.30741 +1849 1760 -694433.4439163 +1850 1760 -56581165.5979 +1851 1760 11581481.02689 +1852 1760 9079855.613715 +1853 1760 -20589184.71456 +1866 1760 2090602.31093 +1867 1760 -16840288.77577 +1868 1760 -19738586.47615 +1869 1760 8796437.017353 +1870 1760 -1388866.887151 +1871 1760 -59221381.24884 +1872 1760 2351018.977684 +1873 1760 18229155.66292 +1874 1760 -27708914.75766 +1761 1761 309814570.0165 +1762 1761 6.437301635742e-06 +1763 1761 462970.2969034 +1764 1761 42076777.68823 +1765 1761 7333333.332127 +1766 1761 -318285.203467 +1848 1761 -18569369.18862 +1849 1761 9166666.669678 +1850 1761 10279397.69313 +1851 1761 -59565882.98117 +1852 1761 4.91738319397e-07 +1853 1761 43739118.52961 +1854 1761 -20057887.18154 +1855 1761 -9166666.669679 +1856 1761 11581481.02689 +1869 1761 -564939.8890041 +1870 1761 -1833333.333934 +1871 1761 -2032731.023757 +1872 1761 27139753.66166 +1873 1761 8.344650268555e-07 +1874 1761 -8738562.979764 +1875 1761 -3553812.994569 +1876 1761 1833333.333932 +1877 1761 -2293147.690507 +1762 1762 265811394.6764 +1763 1762 -5555467.545855 +1764 1762 -7333333.332131 +1765 1762 -27589753.44616 +1766 1762 2749955.995158 +1848 1762 9166666.669678 +1849 1762 -15819170.72716 +1850 1762 -8385422.169798 +1851 1762 -5.811452865601e-07 +1852 1762 -19232220.47929 +1853 1762 -694433.4439163 +1854 1762 -9166666.669679 +1855 1762 -17307688.72007 +1856 1762 9079855.613715 +1869 1762 1833333.333937 +1870 1762 -17981572.68118 +1871 1762 -16840288.77576 +1872 1762 8.940696716309e-07 +1873 1762 16138959.82123 +1874 1762 -1388866.887151 +1875 1762 -1833333.333938 +1876 1762 -20970445.78675 +1877 1762 18229155.66291 +1763 1763 299795956.2502 +1764 1763 723381.4630278 +1765 1763 2805511.550704 +1766 1763 39276420.11598 +1848 1763 10279397.69313 +1849 1763 -8385422.169798 +1850 1763 -16619803.40013 +1851 1763 43704396.30741 +1852 1763 -694433.4439163 +1853 1763 -56581165.5979 +1854 1763 11581481.02689 +1855 1763 9079855.613715 +1856 1763 -20589184.71456 +1869 1763 2090602.31093 +1870 1763 -16840288.77577 +1871 1763 -19738586.47615 +1872 1763 8796437.017353 +1873 1763 -1388866.887151 +1874 1763 -59221381.24884 +1875 1763 2351018.977684 +1876 1763 18229155.66292 +1877 1763 -27708914.75766 +1764 1764 309250160.3896 +1765 1764 4535517.963994 +1766 1764 2453066.565954 +1767 1764 -8612767.502989 +1768 1764 -26152871.16708 +1769 1764 379949.2240047 +1851 1764 -18569369.18862 +1852 1764 9166666.669678 +1853 1764 10279397.69313 +1854 1764 -43745996.76765 +1855 1764 6104008.873162 +1856 1764 33740166.13061 +1857 1764 -19561074.78605 +1858 1764 -8033003.905467 +1859 1764 11036649.36321 +1872 1764 -564939.8890041 +1873 1764 -1833333.333934 +1874 1764 -2032731.023757 +1875 1764 26998047.5617 +1876 1764 1133879.491557 +1877 1764 -8240761.134482 +1878 1764 -17935124.94805 +1879 1764 -6538217.79499 +1880 1764 7751167.860229 +1765 1765 292124118.8748 +1766 1765 -3586804.318186 +1767 1765 -40819537.83134 +1768 1765 -71029376.04212 +1769 1765 603908.8952657 +1851 1765 9166666.669678 +1852 1765 -15819170.72716 +1853 1765 -8385422.169798 +1854 1765 6104008.873161 +1855 1765 -18661255.71884 +1856 1765 -8204777.132884 +1857 1765 -8033003.905467 +1858 1765 -10093718.98084 +1859 1765 8738711.937952 +1872 1765 1833333.333937 +1873 1765 -17981572.68118 +1874 1765 -16840288.77576 +1875 1765 1133879.491557 +1876 1765 22716537.18088 +1877 1765 -896701.0799925 +1878 1765 -10204884.46286 +1879 1765 -33539277.09052 +1880 1765 25588477.22048 +1766 1766 306596341.2044 +1767 1766 553560.3350853 +1768 1766 631686.6730388 +1769 1766 21856446.47305 +1851 1766 10279397.69313 +1852 1766 -8385422.169798 +1853 1766 -16619803.40013 +1854 1766 33913777.24376 +1855 1766 -8204777.131321 +1856 1766 -47982126.11052 +1857 1766 11036649.36321 +1858 1766 8738711.937952 +1859 1766 -17191433.96669 +1872 1766 2090602.31093 +1873 1766 -16840288.77577 +1874 1766 -19738586.47615 +1875 1766 9293683.307081 +1876 1766 -896701.0799924 +1877 1766 -57522894.85793 +1878 1766 12186723.41529 +1879 1766 25588477.21893 +1880 1766 -36621043.23569 +1767 1767 356868400.0533 +1768 1767 48547468.5066 +1769 1767 -63096.8105123 +1770 1767 -69856382.4367 +1771 1767 -44744536.85045 +1772 1767 105372.1511744 +1773 1767 12337681.15014 +1774 1767 -11401155.62501 +1775 1767 36049.28577423 +1854 1767 -18648271.66148 +1855 1767 1937722.859731 +1856 1767 1037653.094121 +1857 1767 -39544456.91598 +1858 1767 10154153.16225 +1859 1767 42822479.01589 +1875 1767 -17192674.13802 +1876 1767 -10204884.46286 +1877 1767 -11944665.46985 +1878 1767 -3912651.53854 +1879 1767 12104000.90406 +1880 1767 -8661308.958427 +1881 1767 -34277798.50532 +1882 1767 -11173569.78409 +1883 1767 20338795.24285 +1884 1767 -25252826.21741 +1885 1767 -2817422.679089 +1886 1767 7690935.964348 +1768 1768 444796097.3529 +1769 1768 -1421522.296491 +1770 1768 -44744536.85045 +1771 1768 -49860415.28467 +1772 1768 71744.56828867 +1773 1768 -26067822.28927 +1774 1768 -59193385.75724 +1775 1768 229034.039838 +1854 1768 1937722.859731 +1855 1768 -44033949.54609 +1856 1768 -16387957.82287 +1857 1768 10154153.16225 +1858 1768 -7640862.557279 +1859 1768 -8052235.36638 +1875 1768 -6538217.794992 +1876 1768 -32796826.2805 +1877 1768 -25279578.32671 +1878 1768 12104000.90406 +1879 1768 18064676.36711 +1880 1768 -355226.5980296 +1881 1768 -11173569.78409 +1882 1768 -29290720.43702 +1883 1768 16684560.25241 +1884 1768 -6484089.34696 +1885 1768 -43130996.523 +1886 1768 33390437.86157 +1769 1769 481548525.3653 +1770 1769 105372.1511744 +1771 1769 71744.56828868 +1772 1769 14856142.46274 +1773 1769 105493.7302044 +1774 1769 229034.0398379 +1775 1769 67067300.58928 +1854 1769 1037653.094121 +1855 1769 -16387957.82287 +1856 1769 -25517489.86743 +1857 1769 42787756.79371 +1858 1769 -8052235.364817 +1859 1769 -82068933.30612 +1875 1769 -7613276.581476 +1876 1769 -25279578.32828 +1877 1769 -34641174.40895 +1878 1769 8456468.81654 +1879 1769 -355226.5980297 +1880 1769 -127782018.4958 +1881 1769 20338795.24285 +1882 1769 16684560.25241 +1883 1769 -41224174.63896 +1884 1769 11918435.96766 +1885 1769 33390437.86157 +1886 1769 -58976019.88741 +1770 1770 235380342.1393 +1771 1770 50243658.4468 +1772 1770 -61365.24479413 +1773 1770 -5955738.729899 +1774 1770 744536.8576738 +1775 1770 -47501.78083324 +1857 1770 -23038281.86555 +1858 1770 -1543523.106717 +1859 1770 -5723810.576489 +1878 1770 -34183101.53561 +1879 1770 -11173569.78409 +1880 1770 -20286204.77049 +1881 1770 -19123839.31674 +1882 1770 12543523.11033 +1883 1770 8109690.206757 +1884 1770 -35160837.88112 +1885 1770 173569.7804715 +1886 1770 -30849674.85978 +1771 1771 216494851.0432 +1772 1771 -57944.23316944 +1773 1771 15411203.52193 +1774 1771 63423294.1034 +1775 1771 -71744.56828511 +1857 1771 -5210189.774589 +1858 1771 -40665167.35974 +1859 1771 -33318863.54052 +1878 1771 -11173569.78409 +1879 1771 -29196023.4673 +1880 1771 -16648773.09187 +1881 1771 12543523.11033 +1882 1771 -23840703.82989 +1883 1771 6652196.878227 +1884 1771 3840236.448343 +1885 1771 -17804165.94208 +1886 1771 3315439.754154 +1772 1772 343596377.1744 +1773 1772 -47501.78082988 +1774 1772 -71744.56828505 +1775 1772 110686534.3726 +1857 1772 -13848810.57722 +1858 1772 -33318863.54052 +1859 1772 -72396132.49673 +1878 1772 -20286204.77049 +1879 1772 -16648773.09187 +1880 1772 -40971649.38638 +1881 1772 -8140309.790574 +1882 1772 -6681136.452916 +1883 1772 -121963274.0163 +1884 1772 -30849674.86172 +1885 1772 -3351226.914701 +1886 1772 -62018439.03128 +1773 1773 174382480.4459 +1774 1773 -17932177.70351 +1775 1773 -128641.8784312 +1857 1773 -16957712.64106 +1858 1773 7159763.555271 +1859 1773 10508239.68408 +1878 1773 -24968735.30843 +1879 1773 -6484089.346963 +1880 1773 -11866008.47688 +1881 1773 -35160837.88111 +1882 1773 3840236.448346 +1883 1773 30826019.57453 +1884 1773 -12970289.93401 +1885 1773 -4515910.656654 +1886 1773 -4242139.670585 +1774 1774 199792991.8053 +1775 1774 -229034.0398293 +1857 1774 7159763.555271 +1858 1774 -22736502.63185 +1859 1774 -16648773.09187 +1878 1774 -2817422.679091 +1879 1774 -42846905.61403 +1880 1774 -33276228.79415 +1881 1774 173569.7804737 +1882 1774 -17804165.94208 +1883 1774 3315439.754155 +1884 1774 -4515910.656654 +1885 1774 -6670001.576668 +1886 1774 6609562.131857 +1775 1775 261744426.6576 +1857 1775 10508239.68408 +1858 1775 -16648773.09187 +1859 1775 -34512128.55092 +1878 1775 -7673230.695789 +1879 1775 -33276228.79415 +1880 1775 -58218444.13013 +1881 1775 30826019.57261 +1882 1775 -3351226.914701 +1883 1775 -62018439.03128 +1884 1775 4178138.10581 +1885 1775 -6723771.199285 +1886 1775 -85404523.65996 +1776 1776 387435706.2613 +1777 1776 36666666.66065 +1778 1776 2662175.186034 +1779 1776 -203296779.618 +1780 1776 -36666973.09101 +1781 1776 -2662152.453524 +1782 1776 12401143.47877 +1783 1776 29333639.75888 +1784 1776 -2152799.783064 +1887 1776 33963705.33589 +1888 1776 9166666.669679 +1889 1776 9519894.71657 +1890 1776 -73633660.33315 +1891 1776 -9166743.277268 +1892 1776 -44520628.22528 +1893 1776 -7828204.348046 +1894 1776 7333409.943332 +1895 1776 -9288430.506837 +1777 1777 332431392.3218 +1778 1777 -6944376.976808 +1779 1777 -36667126.30619 +1780 1777 -30960378.23954 +1781 1777 -3847226.047119 +1782 1777 44000459.63831 +1783 1777 12401143.47877 +1784 1777 2416692.493345 +1887 1777 9166666.669679 +1888 1777 20212626.84424 +1889 1777 5347275.319281 +1890 1777 -9166781.581064 +1891 1777 -30549559.96733 +1892 1777 -9732749.59088 +1893 1777 11000114.915 +1894 1777 -7828204.348045 +1895 1777 11145949.53617 +1778 1778 375187471.1352 +1779 1778 -2662141.087263 +1780 1778 -3097217.438217 +1781 1778 -1482420.858694 +1782 1778 -3229199.674597 +1783 1778 1611128.328897 +1784 1778 33069715.94339 +1887 1778 -8015196.919944 +1888 1778 -8680575.648187 +1889 1778 -73923722.2424 +1890 1778 -44485903.34313 +1891 1778 -9538266.413314 +1892 1778 -61195846.2912 +1893 1778 -13932645.76025 +1894 1778 7430633.02411 +1895 1778 -20875211.59479 +1779 1779 671761428.9985 +1780 1779 36667432.73655 +1781 1779 3125088.651632 +1782 1779 19448570.31785 +1783 1779 -36666973.09101 +1784 1779 2702570.135099 +1785 1779 -138432799.5 +1786 1779 1.490116119385e-07 +1787 1779 -462970.296923 +1788 1779 -52308469.44899 +1789 1779 36666666.66065 +1790 1779 -2702548.129425 +1887 1779 -72039530.38171 +1888 1779 -9166781.581061 +1889 1779 43189554.83944 +1890 1779 73599694.87993 +1891 1779 9166858.188655 +1892 1779 781226.7976368 +1893 1779 -19443104.86928 +1894 1779 -9166743.27727 +1895 1779 11639449.48452 +1896 1779 -59964405.70834 +1897 1779 7.525086402893e-07 +1898 1779 -43970603.67818 +1899 1779 -20163436.42398 +1900 1779 9166666.669676 +1901 1779 -11639352.31406 +1780 1780 572753939.719 +1781 1780 -8610914.043003 +1782 1780 -36667126.30619 +1783 1780 -108884310.9615 +1784 1780 4611018.689007 +1785 1780 -5.960464477539e-08 +1786 1780 22901850.42796 +1787 1780 -2777733.774299 +1788 1780 36666666.66064 +1789 1780 -41307675.60857 +1790 1780 1513866.887135 +1887 1780 -9166743.277267 +1888 1780 -28955430.01587 +1889 1780 7996602.428466 +1890 1780 9166858.188655 +1891 1780 48847822.54786 +1892 1780 -2152764.803778 +1893 1780 -9166781.581064 +1894 1780 -51526325.20493 +1895 1780 36236271.0855 +1896 1780 3.725290298462e-07 +1897 1780 -19630743.20649 +1898 1780 -694433.4439167 +1899 1780 9166666.669676 +1900 1780 -17413237.96253 +1901 1780 9149300.058182 +1781 1781 607013167.9741 +1782 1781 2737303.360137 +1783 1781 5388804.78494 +1784 1781 37600883.93994 +1785 1781 -462970.2969232 +1786 1781 -2777733.774298 +1787 1781 39890623.87246 +1788 1781 -2737270.351624 +1789 1781 1541644.664895 +1790 1781 -7895194.184061 +1887 1781 43154829.95728 +1888 1781 7802192.5578 +1889 1781 -56944833.0873 +1890 1781 781318.4370322 +1891 1781 -2152691.493423 +1892 1781 -99821807.80486 +1893 1781 11639498.06975 +1894 1781 36402939.91804 +1895 1781 -55413772.21342 +1896 1781 -43935881.45598 +1897 1781 -694433.4439167 +1898 1781 -57643892.87044 +1899 1781 -11639352.31406 +1900 1781 9149300.058182 +1901 1781 -20870649.36111 +1782 1782 387435706.2613 +1783 1782 36666666.66065 +1784 1782 2662175.186035 +1785 1782 -52284795.20658 +1786 1782 -36666666.66065 +1787 1782 2505785.203048 +1788 1782 -203296779.618 +1789 1782 -36666973.09101 +1790 1782 -2662152.453524 +1791 1782 12401143.47877 +1792 1782 29333639.75888 +1793 1782 -2152799.783064 +1887 1782 -4839277.140465 +1888 1782 11000114.915 +1889 1782 12370128.70975 +1890 1782 -14860172.33131 +1891 1782 -9166781.581062 +1892 1782 -10279526.39882 +1893 1782 33963705.33589 +1894 1782 9166666.669679 +1895 1782 9519894.71657 +1896 1782 -18663081.30986 +1897 1782 -9166666.669677 +1898 1782 -10337268.9803 +1899 1782 -73633660.33315 +1900 1782 -9166743.277268 +1901 1782 -44520628.22528 +1902 1782 -7828204.348046 +1903 1782 7333409.943332 +1904 1782 -9288430.506837 +1783 1783 332431392.3218 +1784 1783 -6944376.976808 +1785 1783 -36666666.66065 +1786 1783 -41284001.36615 +1787 1783 1263866.887163 +1788 1783 -36667126.30619 +1789 1783 -30960378.23954 +1790 1783 -3847226.047119 +1791 1783 44000459.63831 +1792 1783 12401143.47877 +1793 1783 2416692.493345 +1887 1783 7333409.943332 +1888 1783 -4839277.140466 +1889 1783 -6597291.372073 +1890 1783 -9166743.277267 +1891 1783 -46943392.66696 +1892 1783 -33736315.15602 +1893 1783 9166666.669679 +1894 1783 20212626.84424 +1895 1783 5347275.319281 +1896 1783 -9166666.669677 +1897 1783 -15912882.8484 +1898 1783 -8454866.614265 +1899 1783 -9166781.581064 +1900 1783 -30549559.96733 +1901 1783 -9732749.59088 +1902 1783 11000114.915 +1903 1783 -7828204.348045 +1904 1783 11145949.53617 +1784 1784 375187471.1352 +1785 1784 2471062.980849 +1786 1784 1236089.109403 +1787 1784 -7832062.870945 +1788 1784 -2662141.087263 +1789 1784 -3097217.438217 +1790 1784 -1482420.858694 +1791 1784 -3229199.674597 +1792 1784 1611128.328897 +1793 1784 33069715.94339 +1887 1784 8246752.473166 +1888 1784 -9895937.05811 +1889 1784 -12904739.04124 +1890 1784 -10279483.49692 +1891 1784 -33902984.10692 +1892 1784 -43192618.77883 +1893 1784 -8015196.919944 +1894 1784 -8680575.648187 +1895 1784 -73923722.2424 +1896 1784 -10337268.9803 +1897 1784 -8454866.614265 +1898 1784 -16869702.39011 +1899 1784 -44485903.34313 +1900 1784 -9538266.413314 +1901 1784 -61195846.2912 +1902 1784 -13932645.76025 +1903 1784 7430633.02411 +1904 1784 -20875211.59479 +1785 1785 619629140.0329 +1786 1785 1.168251037598e-05 +1787 1785 925940.5938052 +1788 1785 84152766.23505 +1789 1785 -4.991888999939e-06 +1790 1785 231485.148566 +1794 1785 -138432799.5 +1795 1785 1.490116119385e-07 +1796 1785 -462970.296923 +1797 1785 -52308469.44899 +1798 1785 36666666.66065 +1799 1785 -2702548.129425 +1890 1785 -59565882.98117 +1891 1785 4.91738319397e-07 +1892 1785 43739118.52961 +1893 1785 -20057887.18154 +1894 1785 -9166666.669679 +1895 1785 11581481.02689 +1896 1785 54280296.46473 +1897 1785 3.09944152832e-06 +1898 1785 231485.1485852 +1899 1785 -7107625.989141 +1900 1785 -6.146728992462e-06 +1901 1785 57871.2871768 +1905 1785 -59964405.70834 +1906 1785 7.525086402893e-07 +1907 1785 -43970603.67818 +1908 1785 -20163436.42398 +1909 1785 9166666.669676 +1910 1785 -11639352.31406 +1786 1786 531622789.3528 +1787 1786 -11110935.09172 +1788 1786 -4.798173904419e-06 +1789 1786 -55180296.03374 +1790 1786 5555467.545859 +1794 1786 -5.960464477539e-08 +1795 1786 22901850.42796 +1796 1786 -2777733.774299 +1797 1786 36666666.66064 +1798 1786 -41307675.60857 +1799 1786 1513866.887135 +1890 1786 -5.811452865601e-07 +1891 1786 -19232220.47929 +1892 1786 -694433.4439163 +1893 1786 -9166666.669679 +1894 1786 -17307688.72007 +1895 1786 9079855.613715 +1896 1786 3.635883331299e-06 +1897 1786 32278708.78388 +1898 1786 -2777733.774297 +1899 1786 -5.349516868591e-06 +1900 1786 -41940891.5735 +1901 1786 36472200.21471 +1905 1786 3.725290298462e-07 +1906 1786 -19630743.20649 +1907 1786 -694433.4439167 +1908 1786 9166666.669676 +1909 1786 -17413237.96253 +1910 1786 9149300.058182 +1787 1787 599591912.5003 +1788 1787 231485.1485663 +1789 1787 5555467.545859 +1790 1787 78550735.85485 +1794 1787 -462970.2969232 +1795 1787 -2777733.774298 +1796 1787 39890623.87246 +1797 1787 -2737270.351624 +1798 1787 1541644.664895 +1799 1787 -7895194.184061 +1890 1787 43704396.30741 +1891 1787 -694433.4439163 +1892 1787 -56581165.5979 +1893 1787 11581481.02689 +1894 1787 9079855.613715 +1895 1787 -20589184.71456 +1896 1787 231485.148585 +1897 1787 -2777733.774298 +1898 1787 -118440658.1206 +1899 1787 57871.28717716 +1900 1787 36444422.43695 +1901 1787 -55417829.51533 +1905 1787 -43935881.45598 +1906 1787 -694433.4439167 +1907 1787 -57643892.87044 +1908 1787 -11639352.31406 +1909 1787 9149300.058182 +1910 1787 -20870649.36111 +1788 1788 671761428.9985 +1789 1788 36667432.73655 +1790 1788 3125088.651632 +1791 1788 19448570.31785 +1792 1788 -36666973.09101 +1793 1788 2702570.135099 +1794 1788 -52284795.20658 +1795 1788 -36666666.66065 +1796 1788 2505785.203048 +1797 1788 -138432799.5 +1798 1788 1.490116119385e-07 +1799 1788 -462970.296923 +1800 1788 -52308469.44899 +1801 1788 36666666.66065 +1802 1788 -2702548.129425 +1890 1788 -18569369.18862 +1891 1788 9166666.669678 +1892 1788 10279397.69313 +1893 1788 -72039530.38171 +1894 1788 -9166781.581061 +1895 1788 43189554.83944 +1896 1788 -1129879.778007 +1897 1788 2.369284629822e-06 +1898 1788 57871.28717239 +1899 1788 73599694.87993 +1900 1788 9166858.188655 +1901 1788 781226.7976368 +1902 1788 -19443104.86928 +1903 1788 -9166743.27727 +1904 1788 11639449.48452 +1905 1788 -18663081.30986 +1906 1788 -9166666.669677 +1907 1788 -10337268.9803 +1908 1788 -59964405.70834 +1909 1788 7.525086402893e-07 +1910 1788 -43970603.67818 +1911 1788 -20163436.42398 +1912 1788 9166666.669676 +1913 1788 -11639352.31406 +1789 1789 572753939.719 +1790 1789 -8610914.043003 +1791 1789 -36667126.30619 +1792 1789 -108884310.9615 +1793 1789 4611018.689007 +1794 1789 -36666666.66065 +1795 1789 -41284001.36615 +1796 1789 1263866.887163 +1797 1789 -5.960464477539e-08 +1798 1789 22901850.42796 +1799 1789 -2777733.774299 +1800 1789 36666666.66064 +1801 1789 -41307675.60857 +1802 1789 1513866.887135 +1890 1789 9166666.669678 +1891 1789 -15819170.72716 +1892 1789 -8385422.169798 +1893 1789 -9166743.277267 +1894 1789 -28955430.01587 +1895 1789 7996602.428466 +1896 1789 2.913177013397e-06 +1897 1789 -35963145.36236 +1898 1789 -33694466.44041 +1899 1789 9166858.188655 +1900 1789 48847822.54786 +1901 1789 -2152764.803778 +1902 1789 -9166781.581064 +1903 1789 -51526325.20493 +1904 1789 36236271.0855 +1905 1789 -9166666.669677 +1906 1789 -15912882.8484 +1907 1789 -8454866.614265 +1908 1789 3.725290298462e-07 +1909 1789 -19630743.20649 +1910 1789 -694433.4439167 +1911 1789 9166666.669676 +1912 1789 -17413237.96253 +1913 1789 9149300.058182 +1790 1790 607013167.9741 +1791 1790 2737303.360137 +1792 1790 5388804.78494 +1793 1790 37600883.93994 +1794 1790 2471062.980849 +1795 1790 1236089.109403 +1796 1790 -7832062.870945 +1797 1790 -462970.2969232 +1798 1790 -2777733.774298 +1799 1790 39890623.87246 +1800 1790 -2737270.351624 +1801 1790 1541644.664895 +1802 1790 -7895194.184061 +1890 1790 10279397.69313 +1891 1790 -8385422.169798 +1892 1790 -16619803.40013 +1893 1790 43154829.95728 +1894 1790 7802192.5578 +1895 1790 -56944833.0873 +1896 1790 57871.28717278 +1897 1790 -33666688.66265 +1898 1790 -39477172.9523 +1899 1790 781318.4370322 +1900 1790 -2152691.493423 +1901 1790 -99821807.80486 +1902 1790 11639498.06975 +1903 1790 36402939.91804 +1904 1790 -55413772.21342 +1905 1790 -10337268.9803 +1906 1790 -8454866.614265 +1907 1790 -16869702.39011 +1908 1790 -43935881.45598 +1909 1790 -694433.4439167 +1910 1790 -57643892.87044 +1911 1790 -11639352.31406 +1912 1790 9149300.058182 +1913 1790 -20870649.36111 +1791 1791 387435706.2613 +1792 1791 36666666.66065 +1793 1791 2662175.186035 +1797 1791 -52284795.20658 +1798 1791 -36666666.66065 +1799 1791 2505785.203048 +1800 1791 -203296779.618 +1801 1791 -36666973.09101 +1802 1791 -2662152.453524 +1803 1791 12401143.47877 +1804 1791 29333639.75888 +1805 1791 -2152799.783064 +1893 1791 -4839277.140465 +1894 1791 11000114.915 +1895 1791 12370128.70975 +1899 1791 -14860172.33131 +1900 1791 -9166781.581062 +1901 1791 -10279526.39882 +1902 1791 33963705.33589 +1903 1791 9166666.669679 +1904 1791 9519894.71657 +1908 1791 -18663081.30986 +1909 1791 -9166666.669677 +1910 1791 -10337268.9803 +1911 1791 -73633660.33315 +1912 1791 -9166743.277268 +1913 1791 -44520628.22528 +1914 1791 -7828204.348046 +1915 1791 7333409.943332 +1916 1791 -9288430.506837 +1792 1792 332431392.3218 +1793 1792 -6944376.976808 +1797 1792 -36666666.66065 +1798 1792 -41284001.36615 +1799 1792 1263866.887163 +1800 1792 -36667126.30619 +1801 1792 -30960378.23954 +1802 1792 -3847226.047119 +1803 1792 44000459.63831 +1804 1792 12401143.47877 +1805 1792 2416692.493345 +1893 1792 7333409.943332 +1894 1792 -4839277.140466 +1895 1792 -6597291.372073 +1899 1792 -9166743.277267 +1900 1792 -46943392.66696 +1901 1792 -33736315.15602 +1902 1792 9166666.669679 +1903 1792 20212626.84424 +1904 1792 5347275.319281 +1908 1792 -9166666.669677 +1909 1792 -15912882.8484 +1910 1792 -8454866.614265 +1911 1792 -9166781.581064 +1912 1792 -30549559.96733 +1913 1792 -9732749.59088 +1914 1792 11000114.915 +1915 1792 -7828204.348045 +1916 1792 11145949.53617 +1793 1793 375187471.1352 +1797 1793 2471062.980849 +1798 1793 1236089.109403 +1799 1793 -7832062.870945 +1800 1793 -2662141.087263 +1801 1793 -3097217.438217 +1802 1793 -1482420.858694 +1803 1793 -3229199.674597 +1804 1793 1611128.328897 +1805 1793 33069715.94339 +1893 1793 8246752.473166 +1894 1793 -9895937.05811 +1895 1793 -12904739.04124 +1899 1793 -10279483.49692 +1900 1793 -33902984.10692 +1901 1793 -43192618.77883 +1902 1793 -8015196.919944 +1903 1793 -8680575.648187 +1904 1793 -73923722.2424 +1908 1793 -10337268.9803 +1909 1793 -8454866.614265 +1910 1793 -16869702.39011 +1911 1793 -44485903.34313 +1912 1793 -9538266.413314 +1913 1793 -61195846.2912 +1914 1793 -13932645.76025 +1915 1793 7430633.02411 +1916 1793 -20875211.59479 +1794 1794 619629140.0329 +1795 1794 1.168251037598e-05 +1796 1794 925940.5938052 +1797 1794 84152766.23505 +1798 1794 -4.991888999939e-06 +1799 1794 231485.148566 +1806 1794 -138432799.5 +1807 1794 1.490116119385e-07 +1808 1794 -462970.296923 +1809 1794 -52308469.44899 +1810 1794 36666666.66065 +1811 1794 -2702548.129425 +1896 1794 -59565882.98117 +1897 1794 4.91738319397e-07 +1898 1794 43739118.52961 +1899 1794 -20057887.18154 +1900 1794 -9166666.669679 +1901 1794 11581481.02689 +1905 1794 54280296.46473 +1906 1794 3.09944152832e-06 +1907 1794 231485.1485852 +1908 1794 -7107625.989141 +1909 1794 -6.146728992462e-06 +1910 1794 57871.2871768 +1917 1794 -59964405.70834 +1918 1794 7.525086402893e-07 +1919 1794 -43970603.67818 +1920 1794 -20163436.42398 +1921 1794 9166666.669676 +1922 1794 -11639352.31406 +1795 1795 531622789.3528 +1796 1795 -11110935.09172 +1797 1795 -4.798173904419e-06 +1798 1795 -55180296.03374 +1799 1795 5555467.545859 +1806 1795 -5.960464477539e-08 +1807 1795 22901850.42796 +1808 1795 -2777733.774299 +1809 1795 36666666.66064 +1810 1795 -41307675.60857 +1811 1795 1513866.887135 +1896 1795 -5.811452865601e-07 +1897 1795 -19232220.47929 +1898 1795 -694433.4439163 +1899 1795 -9166666.669679 +1900 1795 -17307688.72007 +1901 1795 9079855.613715 +1905 1795 3.635883331299e-06 +1906 1795 32278708.78388 +1907 1795 -2777733.774297 +1908 1795 -5.349516868591e-06 +1909 1795 -41940891.5735 +1910 1795 36472200.21471 +1917 1795 3.725290298462e-07 +1918 1795 -19630743.20649 +1919 1795 -694433.4439167 +1920 1795 9166666.669676 +1921 1795 -17413237.96253 +1922 1795 9149300.058182 +1796 1796 599591912.5003 +1797 1796 231485.1485663 +1798 1796 5555467.545859 +1799 1796 78550735.85485 +1806 1796 -462970.2969232 +1807 1796 -2777733.774298 +1808 1796 39890623.87246 +1809 1796 -2737270.351624 +1810 1796 1541644.664895 +1811 1796 -7895194.184061 +1896 1796 43704396.30741 +1897 1796 -694433.4439163 +1898 1796 -56581165.5979 +1899 1796 11581481.02689 +1900 1796 9079855.613715 +1901 1796 -20589184.71456 +1905 1796 231485.148585 +1906 1796 -2777733.774298 +1907 1796 -118440658.1206 +1908 1796 57871.28717716 +1909 1796 36444422.43695 +1910 1796 -55417829.51533 +1917 1796 -43935881.45598 +1918 1796 -694433.4439167 +1919 1796 -57643892.87044 +1920 1796 -11639352.31406 +1921 1796 9149300.058182 +1922 1796 -20870649.36111 +1797 1797 619629140.0329 +1798 1797 1.168251037598e-05 +1799 1797 925940.5938052 +1800 1797 84152766.23505 +1801 1797 -4.991888999939e-06 +1802 1797 231485.148566 +1806 1797 -52284795.20658 +1807 1797 -36666666.66065 +1808 1797 2505785.203048 +1809 1797 -138432799.5 +1810 1797 1.490116119385e-07 +1811 1797 -462970.296923 +1812 1797 -52308469.44899 +1813 1797 36666666.66065 +1814 1797 -2702548.129425 +1896 1797 -18569369.18862 +1897 1797 9166666.669678 +1898 1797 10279397.69313 +1899 1797 -59565882.98117 +1900 1797 4.91738319397e-07 +1901 1797 43739118.52961 +1902 1797 -20057887.18154 +1903 1797 -9166666.669679 +1904 1797 11581481.02689 +1905 1797 -1129879.778007 +1906 1797 2.369284629822e-06 +1907 1797 57871.28717239 +1908 1797 54280296.46473 +1909 1797 3.09944152832e-06 +1910 1797 231485.1485852 +1911 1797 -7107625.989141 +1912 1797 -6.146728992462e-06 +1913 1797 57871.2871768 +1917 1797 -18663081.30986 +1918 1797 -9166666.669677 +1919 1797 -10337268.9803 +1920 1797 -59964405.70834 +1921 1797 7.525086402893e-07 +1922 1797 -43970603.67818 +1923 1797 -20163436.42398 +1924 1797 9166666.669676 +1925 1797 -11639352.31406 +1798 1798 531622789.3528 +1799 1798 -11110935.09172 +1800 1798 -4.798173904419e-06 +1801 1798 -55180296.03374 +1802 1798 5555467.545859 +1806 1798 -36666666.66065 +1807 1798 -41284001.36615 +1808 1798 1263866.887163 +1809 1798 -5.960464477539e-08 +1810 1798 22901850.42796 +1811 1798 -2777733.774299 +1812 1798 36666666.66064 +1813 1798 -41307675.60857 +1814 1798 1513866.887135 +1896 1798 9166666.669678 +1897 1798 -15819170.72716 +1898 1798 -8385422.169798 +1899 1798 -5.811452865601e-07 +1900 1798 -19232220.47929 +1901 1798 -694433.4439163 +1902 1798 -9166666.669679 +1903 1798 -17307688.72007 +1904 1798 9079855.613715 +1905 1798 2.913177013397e-06 +1906 1798 -35963145.36236 +1907 1798 -33694466.44041 +1908 1798 3.635883331299e-06 +1909 1798 32278708.78388 +1910 1798 -2777733.774297 +1911 1798 -5.349516868591e-06 +1912 1798 -41940891.5735 +1913 1798 36472200.21471 +1917 1798 -9166666.669677 +1918 1798 -15912882.8484 +1919 1798 -8454866.614265 +1920 1798 3.725290298462e-07 +1921 1798 -19630743.20649 +1922 1798 -694433.4439167 +1923 1798 9166666.669676 +1924 1798 -17413237.96253 +1925 1798 9149300.058182 +1799 1799 599591912.5003 +1800 1799 231485.1485663 +1801 1799 5555467.545859 +1802 1799 78550735.85485 +1806 1799 2471062.980849 +1807 1799 1236089.109403 +1808 1799 -7832062.870945 +1809 1799 -462970.2969232 +1810 1799 -2777733.774298 +1811 1799 39890623.87246 +1812 1799 -2737270.351624 +1813 1799 1541644.664895 +1814 1799 -7895194.184061 +1896 1799 10279397.69313 +1897 1799 -8385422.169798 +1898 1799 -16619803.40013 +1899 1799 43704396.30741 +1900 1799 -694433.4439163 +1901 1799 -56581165.5979 +1902 1799 11581481.02689 +1903 1799 9079855.613715 +1904 1799 -20589184.71456 +1905 1799 57871.28717278 +1906 1799 -33666688.66265 +1907 1799 -39477172.9523 +1908 1799 231485.148585 +1909 1799 -2777733.774298 +1910 1799 -118440658.1206 +1911 1799 57871.28717716 +1912 1799 36444422.43695 +1913 1799 -55417829.51533 +1917 1799 -10337268.9803 +1918 1799 -8454866.614265 +1919 1799 -16869702.39011 +1920 1799 -43935881.45598 +1921 1799 -694433.4439167 +1922 1799 -57643892.87044 +1923 1799 -11639352.31406 +1924 1799 9149300.058182 +1925 1799 -20870649.36111 +1800 1800 671761428.9985 +1801 1800 36667432.73655 +1802 1800 3125088.651632 +1803 1800 19448570.31785 +1804 1800 -36666973.09101 +1805 1800 2702570.135099 +1809 1800 -52284795.20658 +1810 1800 -36666666.66065 +1811 1800 2505785.203048 +1812 1800 -138432799.5 +1813 1800 1.490116119385e-07 +1814 1800 -462970.296923 +1815 1800 -52308469.44899 +1816 1800 36666666.66065 +1817 1800 -2702548.129425 +1899 1800 -18569369.18862 +1900 1800 9166666.669678 +1901 1800 10279397.69313 +1902 1800 -72039530.38171 +1903 1800 -9166781.581061 +1904 1800 43189554.83944 +1908 1800 -1129879.778007 +1909 1800 2.369284629822e-06 +1910 1800 57871.28717239 +1911 1800 73599694.87993 +1912 1800 9166858.188655 +1913 1800 781226.7976368 +1914 1800 -19443104.86928 +1915 1800 -9166743.27727 +1916 1800 11639449.48452 +1920 1800 -18663081.30986 +1921 1800 -9166666.669677 +1922 1800 -10337268.9803 +1923 1800 -59964405.70834 +1924 1800 7.525086402893e-07 +1925 1800 -43970603.67818 +1926 1800 -20163436.42398 +1927 1800 9166666.669676 +1928 1800 -11639352.31406 +1801 1801 572753939.719 +1802 1801 -8610914.043003 +1803 1801 -36667126.30619 +1804 1801 -108884310.9615 +1805 1801 4611018.689007 +1809 1801 -36666666.66065 +1810 1801 -41284001.36615 +1811 1801 1263866.887163 +1812 1801 -5.960464477539e-08 +1813 1801 22901850.42796 +1814 1801 -2777733.774299 +1815 1801 36666666.66064 +1816 1801 -41307675.60857 +1817 1801 1513866.887135 +1899 1801 9166666.669678 +1900 1801 -15819170.72716 +1901 1801 -8385422.169798 +1902 1801 -9166743.277267 +1903 1801 -28955430.01587 +1904 1801 7996602.428466 +1908 1801 2.913177013397e-06 +1909 1801 -35963145.36236 +1910 1801 -33694466.44041 +1911 1801 9166858.188655 +1912 1801 48847822.54786 +1913 1801 -2152764.803778 +1914 1801 -9166781.581064 +1915 1801 -51526325.20493 +1916 1801 36236271.0855 +1920 1801 -9166666.669677 +1921 1801 -15912882.8484 +1922 1801 -8454866.614265 +1923 1801 3.725290298462e-07 +1924 1801 -19630743.20649 +1925 1801 -694433.4439167 +1926 1801 9166666.669676 +1927 1801 -17413237.96253 +1928 1801 9149300.058182 +1802 1802 607013167.9741 +1803 1802 2737303.360137 +1804 1802 5388804.78494 +1805 1802 37600883.93994 +1809 1802 2471062.980849 +1810 1802 1236089.109403 +1811 1802 -7832062.870945 +1812 1802 -462970.2969232 +1813 1802 -2777733.774298 +1814 1802 39890623.87246 +1815 1802 -2737270.351624 +1816 1802 1541644.664895 +1817 1802 -7895194.184061 +1899 1802 10279397.69313 +1900 1802 -8385422.169798 +1901 1802 -16619803.40013 +1902 1802 43154829.95728 +1903 1802 7802192.5578 +1904 1802 -56944833.0873 +1908 1802 57871.28717278 +1909 1802 -33666688.66265 +1910 1802 -39477172.9523 +1911 1802 781318.4370322 +1912 1802 -2152691.493423 +1913 1802 -99821807.80486 +1914 1802 11639498.06975 +1915 1802 36402939.91804 +1916 1802 -55413772.21342 +1920 1802 -10337268.9803 +1921 1802 -8454866.614265 +1922 1802 -16869702.39011 +1923 1802 -43935881.45598 +1924 1802 -694433.4439167 +1925 1802 -57643892.87044 +1926 1802 -11639352.31406 +1927 1802 9149300.058182 +1928 1802 -20870649.36111 +1803 1803 387435706.2613 +1804 1803 36666666.66065 +1805 1803 2662175.186035 +1812 1803 -52284795.20658 +1813 1803 -36666666.66065 +1814 1803 2505785.203048 +1815 1803 -203296779.618 +1816 1803 -36666973.09101 +1817 1803 -2662152.453524 +1818 1803 12401143.47877 +1819 1803 29333639.75888 +1820 1803 -2152799.783064 +1902 1803 -4839277.140465 +1903 1803 11000114.915 +1904 1803 12370128.70975 +1911 1803 -14860172.33131 +1912 1803 -9166781.581062 +1913 1803 -10279526.39882 +1914 1803 33963705.33589 +1915 1803 9166666.669679 +1916 1803 9519894.71657 +1923 1803 -18663081.30986 +1924 1803 -9166666.669677 +1925 1803 -10337268.9803 +1926 1803 -73633660.33315 +1927 1803 -9166743.277268 +1928 1803 -44520628.22528 +1929 1803 -7828204.348046 +1930 1803 7333409.943332 +1931 1803 -9288430.506837 +1804 1804 332431392.3218 +1805 1804 -6944376.976808 +1812 1804 -36666666.66065 +1813 1804 -41284001.36615 +1814 1804 1263866.887163 +1815 1804 -36667126.30619 +1816 1804 -30960378.23954 +1817 1804 -3847226.047119 +1818 1804 44000459.63831 +1819 1804 12401143.47877 +1820 1804 2416692.493345 +1902 1804 7333409.943332 +1903 1804 -4839277.140466 +1904 1804 -6597291.372073 +1911 1804 -9166743.277267 +1912 1804 -46943392.66696 +1913 1804 -33736315.15602 +1914 1804 9166666.669679 +1915 1804 20212626.84424 +1916 1804 5347275.319281 +1923 1804 -9166666.669677 +1924 1804 -15912882.8484 +1925 1804 -8454866.614265 +1926 1804 -9166781.581064 +1927 1804 -30549559.96733 +1928 1804 -9732749.59088 +1929 1804 11000114.915 +1930 1804 -7828204.348045 +1931 1804 11145949.53617 +1805 1805 375187471.1352 +1812 1805 2471062.980849 +1813 1805 1236089.109403 +1814 1805 -7832062.870945 +1815 1805 -2662141.087263 +1816 1805 -3097217.438217 +1817 1805 -1482420.858694 +1818 1805 -3229199.674597 +1819 1805 1611128.328897 +1820 1805 33069715.94339 +1902 1805 8246752.473166 +1903 1805 -9895937.05811 +1904 1805 -12904739.04124 +1911 1805 -10279483.49692 +1912 1805 -33902984.10692 +1913 1805 -43192618.77883 +1914 1805 -8015196.919944 +1915 1805 -8680575.648187 +1916 1805 -73923722.2424 +1923 1805 -10337268.9803 +1924 1805 -8454866.614265 +1925 1805 -16869702.39011 +1926 1805 -44485903.34313 +1927 1805 -9538266.413314 +1928 1805 -61195846.2912 +1929 1805 -13932645.76025 +1930 1805 7430633.02411 +1931 1805 -20875211.59479 +1806 1806 619629140.0329 +1807 1806 1.168251037598e-05 +1808 1806 925940.5938052 +1809 1806 84152766.23505 +1810 1806 -4.991888999939e-06 +1811 1806 231485.148566 +1821 1806 -138432799.5 +1822 1806 1.490116119385e-07 +1823 1806 -462970.296923 +1824 1806 -52308469.44899 +1825 1806 36666666.66065 +1826 1806 -2702548.129425 +1905 1806 -59565882.98117 +1906 1806 4.91738319397e-07 +1907 1806 43739118.52961 +1908 1806 -20057887.18154 +1909 1806 -9166666.669679 +1910 1806 11581481.02689 +1917 1806 54280296.46473 +1918 1806 3.09944152832e-06 +1919 1806 231485.1485852 +1920 1806 -7107625.989141 +1921 1806 -6.146728992462e-06 +1922 1806 57871.2871768 +1932 1806 -59964405.70834 +1933 1806 7.525086402893e-07 +1934 1806 -43970603.67818 +1935 1806 -20163436.42398 +1936 1806 9166666.669676 +1937 1806 -11639352.31406 +1807 1807 531622789.3528 +1808 1807 -11110935.09172 +1809 1807 -4.798173904419e-06 +1810 1807 -55180296.03374 +1811 1807 5555467.545859 +1821 1807 -5.960464477539e-08 +1822 1807 22901850.42796 +1823 1807 -2777733.774299 +1824 1807 36666666.66064 +1825 1807 -41307675.60857 +1826 1807 1513866.887135 +1905 1807 -5.811452865601e-07 +1906 1807 -19232220.47929 +1907 1807 -694433.4439163 +1908 1807 -9166666.669679 +1909 1807 -17307688.72007 +1910 1807 9079855.613715 +1917 1807 3.635883331299e-06 +1918 1807 32278708.78388 +1919 1807 -2777733.774297 +1920 1807 -5.349516868591e-06 +1921 1807 -41940891.5735 +1922 1807 36472200.21471 +1932 1807 3.725290298462e-07 +1933 1807 -19630743.20649 +1934 1807 -694433.4439167 +1935 1807 9166666.669676 +1936 1807 -17413237.96253 +1937 1807 9149300.058182 +1808 1808 599591912.5003 +1809 1808 231485.1485663 +1810 1808 5555467.545859 +1811 1808 78550735.85485 +1821 1808 -462970.2969232 +1822 1808 -2777733.774298 +1823 1808 39890623.87246 +1824 1808 -2737270.351624 +1825 1808 1541644.664895 +1826 1808 -7895194.184061 +1905 1808 43704396.30741 +1906 1808 -694433.4439163 +1907 1808 -56581165.5979 +1908 1808 11581481.02689 +1909 1808 9079855.613715 +1910 1808 -20589184.71456 +1917 1808 231485.148585 +1918 1808 -2777733.774298 +1919 1808 -118440658.1206 +1920 1808 57871.28717716 +1921 1808 36444422.43695 +1922 1808 -55417829.51533 +1932 1808 -43935881.45598 +1933 1808 -694433.4439167 +1934 1808 -57643892.87044 +1935 1808 -11639352.31406 +1936 1808 9149300.058182 +1937 1808 -20870649.36111 +1809 1809 619629140.0329 +1810 1809 1.168251037598e-05 +1811 1809 925940.5938052 +1812 1809 84152766.23505 +1813 1809 -4.991888999939e-06 +1814 1809 231485.148566 +1821 1809 -52284795.20658 +1822 1809 -36666666.66065 +1823 1809 2505785.203048 +1824 1809 -138432799.5 +1825 1809 1.490116119385e-07 +1826 1809 -462970.296923 +1827 1809 -52308469.44899 +1828 1809 36666666.66065 +1829 1809 -2702548.129425 +1905 1809 -18569369.18862 +1906 1809 9166666.669678 +1907 1809 10279397.69313 +1908 1809 -59565882.98117 +1909 1809 4.91738319397e-07 +1910 1809 43739118.52961 +1911 1809 -20057887.18154 +1912 1809 -9166666.669679 +1913 1809 11581481.02689 +1917 1809 -1129879.778007 +1918 1809 2.369284629822e-06 +1919 1809 57871.28717239 +1920 1809 54280296.46473 +1921 1809 3.09944152832e-06 +1922 1809 231485.1485852 +1923 1809 -7107625.989141 +1924 1809 -6.146728992462e-06 +1925 1809 57871.2871768 +1932 1809 -18663081.30986 +1933 1809 -9166666.669677 +1934 1809 -10337268.9803 +1935 1809 -59964405.70834 +1936 1809 7.525086402893e-07 +1937 1809 -43970603.67818 +1938 1809 -20163436.42398 +1939 1809 9166666.669676 +1940 1809 -11639352.31406 +1810 1810 531622789.3528 +1811 1810 -11110935.09172 +1812 1810 -4.798173904419e-06 +1813 1810 -55180296.03374 +1814 1810 5555467.545859 +1821 1810 -36666666.66065 +1822 1810 -41284001.36615 +1823 1810 1263866.887163 +1824 1810 -5.960464477539e-08 +1825 1810 22901850.42796 +1826 1810 -2777733.774299 +1827 1810 36666666.66064 +1828 1810 -41307675.60857 +1829 1810 1513866.887135 +1905 1810 9166666.669678 +1906 1810 -15819170.72716 +1907 1810 -8385422.169798 +1908 1810 -5.811452865601e-07 +1909 1810 -19232220.47929 +1910 1810 -694433.4439163 +1911 1810 -9166666.669679 +1912 1810 -17307688.72007 +1913 1810 9079855.613715 +1917 1810 2.913177013397e-06 +1918 1810 -35963145.36236 +1919 1810 -33694466.44041 +1920 1810 3.635883331299e-06 +1921 1810 32278708.78388 +1922 1810 -2777733.774297 +1923 1810 -5.349516868591e-06 +1924 1810 -41940891.5735 +1925 1810 36472200.21471 +1932 1810 -9166666.669677 +1933 1810 -15912882.8484 +1934 1810 -8454866.614265 +1935 1810 3.725290298462e-07 +1936 1810 -19630743.20649 +1937 1810 -694433.4439167 +1938 1810 9166666.669676 +1939 1810 -17413237.96253 +1940 1810 9149300.058182 +1811 1811 599591912.5003 +1812 1811 231485.1485663 +1813 1811 5555467.545859 +1814 1811 78550735.85485 +1821 1811 2471062.980849 +1822 1811 1236089.109403 +1823 1811 -7832062.870945 +1824 1811 -462970.2969232 +1825 1811 -2777733.774298 +1826 1811 39890623.87246 +1827 1811 -2737270.351624 +1828 1811 1541644.664895 +1829 1811 -7895194.184061 +1905 1811 10279397.69313 +1906 1811 -8385422.169798 +1907 1811 -16619803.40013 +1908 1811 43704396.30741 +1909 1811 -694433.4439163 +1910 1811 -56581165.5979 +1911 1811 11581481.02689 +1912 1811 9079855.613715 +1913 1811 -20589184.71456 +1917 1811 57871.28717278 +1918 1811 -33666688.66265 +1919 1811 -39477172.9523 +1920 1811 231485.148585 +1921 1811 -2777733.774298 +1922 1811 -118440658.1206 +1923 1811 57871.28717716 +1924 1811 36444422.43695 +1925 1811 -55417829.51533 +1932 1811 -10337268.9803 +1933 1811 -8454866.614265 +1934 1811 -16869702.39011 +1935 1811 -43935881.45598 +1936 1811 -694433.4439167 +1937 1811 -57643892.87044 +1938 1811 -11639352.31406 +1939 1811 9149300.058182 +1940 1811 -20870649.36111 +1812 1812 619629140.0329 +1813 1812 1.168251037598e-05 +1814 1812 925940.5938052 +1815 1812 84152766.23505 +1816 1812 -4.991888999939e-06 +1817 1812 231485.148566 +1824 1812 -52284795.20658 +1825 1812 -36666666.66065 +1826 1812 2505785.203048 +1827 1812 -138432799.5 +1828 1812 1.490116119385e-07 +1829 1812 -462970.296923 +1830 1812 -52308469.44899 +1831 1812 36666666.66065 +1832 1812 -2702548.129425 +1908 1812 -18569369.18862 +1909 1812 9166666.669678 +1910 1812 10279397.69313 +1911 1812 -59565882.98117 +1912 1812 4.91738319397e-07 +1913 1812 43739118.52961 +1914 1812 -20057887.18154 +1915 1812 -9166666.669679 +1916 1812 11581481.02689 +1920 1812 -1129879.778007 +1921 1812 2.369284629822e-06 +1922 1812 57871.28717239 +1923 1812 54280296.46473 +1924 1812 3.09944152832e-06 +1925 1812 231485.1485852 +1926 1812 -7107625.989141 +1927 1812 -6.146728992462e-06 +1928 1812 57871.2871768 +1935 1812 -18663081.30986 +1936 1812 -9166666.669677 +1937 1812 -10337268.9803 +1938 1812 -59964405.70834 +1939 1812 7.525086402893e-07 +1940 1812 -43970603.67818 +1941 1812 -20163436.42398 +1942 1812 9166666.669676 +1943 1812 -11639352.31406 +1813 1813 531622789.3528 +1814 1813 -11110935.09172 +1815 1813 -4.798173904419e-06 +1816 1813 -55180296.03374 +1817 1813 5555467.545859 +1824 1813 -36666666.66065 +1825 1813 -41284001.36615 +1826 1813 1263866.887163 +1827 1813 -5.960464477539e-08 +1828 1813 22901850.42796 +1829 1813 -2777733.774299 +1830 1813 36666666.66064 +1831 1813 -41307675.60857 +1832 1813 1513866.887135 +1908 1813 9166666.669678 +1909 1813 -15819170.72716 +1910 1813 -8385422.169798 +1911 1813 -5.811452865601e-07 +1912 1813 -19232220.47929 +1913 1813 -694433.4439163 +1914 1813 -9166666.669679 +1915 1813 -17307688.72007 +1916 1813 9079855.613715 +1920 1813 2.913177013397e-06 +1921 1813 -35963145.36236 +1922 1813 -33694466.44041 +1923 1813 3.635883331299e-06 +1924 1813 32278708.78388 +1925 1813 -2777733.774297 +1926 1813 -5.349516868591e-06 +1927 1813 -41940891.5735 +1928 1813 36472200.21471 +1935 1813 -9166666.669677 +1936 1813 -15912882.8484 +1937 1813 -8454866.614265 +1938 1813 3.725290298462e-07 +1939 1813 -19630743.20649 +1940 1813 -694433.4439167 +1941 1813 9166666.669676 +1942 1813 -17413237.96253 +1943 1813 9149300.058182 +1814 1814 599591912.5003 +1815 1814 231485.1485663 +1816 1814 5555467.545859 +1817 1814 78550735.85485 +1824 1814 2471062.980849 +1825 1814 1236089.109403 +1826 1814 -7832062.870945 +1827 1814 -462970.2969232 +1828 1814 -2777733.774298 +1829 1814 39890623.87246 +1830 1814 -2737270.351624 +1831 1814 1541644.664895 +1832 1814 -7895194.184061 +1908 1814 10279397.69313 +1909 1814 -8385422.169798 +1910 1814 -16619803.40013 +1911 1814 43704396.30741 +1912 1814 -694433.4439163 +1913 1814 -56581165.5979 +1914 1814 11581481.02689 +1915 1814 9079855.613715 +1916 1814 -20589184.71456 +1920 1814 57871.28717278 +1921 1814 -33666688.66265 +1922 1814 -39477172.9523 +1923 1814 231485.148585 +1924 1814 -2777733.774298 +1925 1814 -118440658.1206 +1926 1814 57871.28717716 +1927 1814 36444422.43695 +1928 1814 -55417829.51533 +1935 1814 -10337268.9803 +1936 1814 -8454866.614265 +1937 1814 -16869702.39011 +1938 1814 -43935881.45598 +1939 1814 -694433.4439167 +1940 1814 -57643892.87044 +1941 1814 -11639352.31406 +1942 1814 9149300.058182 +1943 1814 -20870649.36111 +1815 1815 671761428.9985 +1816 1815 36667432.73655 +1817 1815 3125088.651632 +1818 1815 19448570.31785 +1819 1815 -36666973.09101 +1820 1815 2702570.135099 +1827 1815 -52284795.20658 +1828 1815 -36666666.66065 +1829 1815 2505785.203048 +1830 1815 -138432799.5 +1831 1815 1.490116119385e-07 +1832 1815 -462970.296923 +1833 1815 -52308469.44899 +1834 1815 36666666.66065 +1835 1815 -2702548.129425 +1911 1815 -18569369.18862 +1912 1815 9166666.669678 +1913 1815 10279397.69313 +1914 1815 -72039530.38171 +1915 1815 -9166781.581061 +1916 1815 43189554.83944 +1923 1815 -1129879.778007 +1924 1815 2.369284629822e-06 +1925 1815 57871.28717239 +1926 1815 73599694.87993 +1927 1815 9166858.188655 +1928 1815 781226.7976368 +1929 1815 -19443104.86928 +1930 1815 -9166743.27727 +1931 1815 11639449.48452 +1938 1815 -18663081.30986 +1939 1815 -9166666.669677 +1940 1815 -10337268.9803 +1941 1815 -59964405.70834 +1942 1815 7.525086402893e-07 +1943 1815 -43970603.67818 +1944 1815 -20163436.42398 +1945 1815 9166666.669676 +1946 1815 -11639352.31406 +1816 1816 572753939.719 +1817 1816 -8610914.043003 +1818 1816 -36667126.30619 +1819 1816 -108884310.9615 +1820 1816 4611018.689007 +1827 1816 -36666666.66065 +1828 1816 -41284001.36615 +1829 1816 1263866.887163 +1830 1816 -5.960464477539e-08 +1831 1816 22901850.42796 +1832 1816 -2777733.774299 +1833 1816 36666666.66064 +1834 1816 -41307675.60857 +1835 1816 1513866.887135 +1911 1816 9166666.669678 +1912 1816 -15819170.72716 +1913 1816 -8385422.169798 +1914 1816 -9166743.277267 +1915 1816 -28955430.01587 +1916 1816 7996602.428466 +1923 1816 2.913177013397e-06 +1924 1816 -35963145.36236 +1925 1816 -33694466.44041 +1926 1816 9166858.188655 +1927 1816 48847822.54786 +1928 1816 -2152764.803778 +1929 1816 -9166781.581064 +1930 1816 -51526325.20493 +1931 1816 36236271.0855 +1938 1816 -9166666.669677 +1939 1816 -15912882.8484 +1940 1816 -8454866.614265 +1941 1816 3.725290298462e-07 +1942 1816 -19630743.20649 +1943 1816 -694433.4439167 +1944 1816 9166666.669676 +1945 1816 -17413237.96253 +1946 1816 9149300.058182 +1817 1817 607013167.9741 +1818 1817 2737303.360137 +1819 1817 5388804.78494 +1820 1817 37600883.93994 +1827 1817 2471062.980849 +1828 1817 1236089.109403 +1829 1817 -7832062.870945 +1830 1817 -462970.2969232 +1831 1817 -2777733.774298 +1832 1817 39890623.87246 +1833 1817 -2737270.351624 +1834 1817 1541644.664895 +1835 1817 -7895194.184061 +1911 1817 10279397.69313 +1912 1817 -8385422.169798 +1913 1817 -16619803.40013 +1914 1817 43154829.95728 +1915 1817 7802192.5578 +1916 1817 -56944833.0873 +1923 1817 57871.28717278 +1924 1817 -33666688.66265 +1925 1817 -39477172.9523 +1926 1817 781318.4370322 +1927 1817 -2152691.493423 +1928 1817 -99821807.80486 +1929 1817 11639498.06975 +1930 1817 36402939.91804 +1931 1817 -55413772.21342 +1938 1817 -10337268.9803 +1939 1817 -8454866.614265 +1940 1817 -16869702.39011 +1941 1817 -43935881.45598 +1942 1817 -694433.4439167 +1943 1817 -57643892.87044 +1944 1817 -11639352.31406 +1945 1817 9149300.058182 +1946 1817 -20870649.36111 +1818 1818 387435706.2613 +1819 1818 36666666.66065 +1820 1818 2662175.186035 +1830 1818 -52284795.20658 +1831 1818 -36666666.66065 +1832 1818 2505785.203048 +1833 1818 -203296779.618 +1834 1818 -36666973.09101 +1835 1818 -2662152.453524 +1836 1818 12401143.47877 +1837 1818 29333639.75888 +1838 1818 -2152799.783064 +1914 1818 -4839277.140465 +1915 1818 11000114.915 +1916 1818 12370128.70975 +1926 1818 -14860172.33131 +1927 1818 -9166781.581062 +1928 1818 -10279526.39882 +1929 1818 33963705.33589 +1930 1818 9166666.669679 +1931 1818 9519894.71657 +1941 1818 -18663081.30986 +1942 1818 -9166666.669677 +1943 1818 -10337268.9803 +1944 1818 -73633660.33315 +1945 1818 -9166743.277268 +1946 1818 -44520628.22528 +1947 1818 -7828204.348046 +1948 1818 7333409.943332 +1949 1818 -9288430.506837 +1819 1819 332431392.3218 +1820 1819 -6944376.976808 +1830 1819 -36666666.66065 +1831 1819 -41284001.36615 +1832 1819 1263866.887163 +1833 1819 -36667126.30619 +1834 1819 -30960378.23954 +1835 1819 -3847226.047119 +1836 1819 44000459.63831 +1837 1819 12401143.47877 +1838 1819 2416692.493345 +1914 1819 7333409.943332 +1915 1819 -4839277.140466 +1916 1819 -6597291.372073 +1926 1819 -9166743.277267 +1927 1819 -46943392.66696 +1928 1819 -33736315.15602 +1929 1819 9166666.669679 +1930 1819 20212626.84424 +1931 1819 5347275.319281 +1941 1819 -9166666.669677 +1942 1819 -15912882.8484 +1943 1819 -8454866.614265 +1944 1819 -9166781.581064 +1945 1819 -30549559.96733 +1946 1819 -9732749.59088 +1947 1819 11000114.915 +1948 1819 -7828204.348045 +1949 1819 11145949.53617 +1820 1820 375187471.1352 +1830 1820 2471062.980849 +1831 1820 1236089.109403 +1832 1820 -7832062.870945 +1833 1820 -2662141.087263 +1834 1820 -3097217.438217 +1835 1820 -1482420.858694 +1836 1820 -3229199.674597 +1837 1820 1611128.328897 +1838 1820 33069715.94339 +1914 1820 8246752.473166 +1915 1820 -9895937.05811 +1916 1820 -12904739.04124 +1926 1820 -10279483.49692 +1927 1820 -33902984.10692 +1928 1820 -43192618.77883 +1929 1820 -8015196.919944 +1930 1820 -8680575.648187 +1931 1820 -73923722.2424 +1941 1820 -10337268.9803 +1942 1820 -8454866.614265 +1943 1820 -16869702.39011 +1944 1820 -44485903.34313 +1945 1820 -9538266.413314 +1946 1820 -61195846.2912 +1947 1820 -13932645.76025 +1948 1820 7430633.02411 +1949 1820 -20875211.59479 +1821 1821 619629140.0329 +1822 1821 1.168251037598e-05 +1823 1821 925940.5938052 +1824 1821 84152766.23505 +1825 1821 -4.991888999939e-06 +1826 1821 231485.148566 +1839 1821 -138432799.5 +1840 1821 1.490116119385e-07 +1841 1821 -462970.296923 +1842 1821 -52308469.44899 +1843 1821 36666666.66065 +1844 1821 -2702548.129425 +1917 1821 -59565882.98117 +1918 1821 4.91738319397e-07 +1919 1821 43739118.52961 +1920 1821 -20057887.18154 +1921 1821 -9166666.669679 +1922 1821 11581481.02689 +1932 1821 54280296.46473 +1933 1821 3.09944152832e-06 +1934 1821 231485.1485852 +1935 1821 -7107625.989141 +1936 1821 -6.146728992462e-06 +1937 1821 57871.2871768 +1950 1821 -59964405.70834 +1951 1821 7.525086402893e-07 +1952 1821 -43970603.67818 +1953 1821 -20163436.42398 +1954 1821 9166666.669676 +1955 1821 -11639352.31406 +1822 1822 531622789.3528 +1823 1822 -11110935.09172 +1824 1822 -4.798173904419e-06 +1825 1822 -55180296.03374 +1826 1822 5555467.545859 +1839 1822 -5.960464477539e-08 +1840 1822 22901850.42796 +1841 1822 -2777733.774299 +1842 1822 36666666.66064 +1843 1822 -41307675.60857 +1844 1822 1513866.887135 +1917 1822 -5.811452865601e-07 +1918 1822 -19232220.47929 +1919 1822 -694433.4439163 +1920 1822 -9166666.669679 +1921 1822 -17307688.72007 +1922 1822 9079855.613715 +1932 1822 3.635883331299e-06 +1933 1822 32278708.78388 +1934 1822 -2777733.774297 +1935 1822 -5.349516868591e-06 +1936 1822 -41940891.5735 +1937 1822 36472200.21471 +1950 1822 3.725290298462e-07 +1951 1822 -19630743.20649 +1952 1822 -694433.4439167 +1953 1822 9166666.669676 +1954 1822 -17413237.96253 +1955 1822 9149300.058182 +1823 1823 599591912.5003 +1824 1823 231485.1485663 +1825 1823 5555467.545859 +1826 1823 78550735.85485 +1839 1823 -462970.2969232 +1840 1823 -2777733.774298 +1841 1823 39890623.87246 +1842 1823 -2737270.351624 +1843 1823 1541644.664895 +1844 1823 -7895194.184061 +1917 1823 43704396.30741 +1918 1823 -694433.4439163 +1919 1823 -56581165.5979 +1920 1823 11581481.02689 +1921 1823 9079855.613715 +1922 1823 -20589184.71456 +1932 1823 231485.148585 +1933 1823 -2777733.774298 +1934 1823 -118440658.1206 +1935 1823 57871.28717716 +1936 1823 36444422.43695 +1937 1823 -55417829.51533 +1950 1823 -43935881.45598 +1951 1823 -694433.4439167 +1952 1823 -57643892.87044 +1953 1823 -11639352.31406 +1954 1823 9149300.058182 +1955 1823 -20870649.36111 +1824 1824 619629140.0329 +1825 1824 1.168251037598e-05 +1826 1824 925940.5938052 +1827 1824 84152766.23505 +1828 1824 -4.991888999939e-06 +1829 1824 231485.148566 +1839 1824 -52284795.20658 +1840 1824 -36666666.66065 +1841 1824 2505785.203048 +1842 1824 -138432799.5 +1843 1824 1.490116119385e-07 +1844 1824 -462970.296923 +1845 1824 -52308469.44899 +1846 1824 36666666.66065 +1847 1824 -2702548.129425 +1917 1824 -18569369.18862 +1918 1824 9166666.669678 +1919 1824 10279397.69313 +1920 1824 -59565882.98117 +1921 1824 4.91738319397e-07 +1922 1824 43739118.52961 +1923 1824 -20057887.18154 +1924 1824 -9166666.669679 +1925 1824 11581481.02689 +1932 1824 -1129879.778007 +1933 1824 2.369284629822e-06 +1934 1824 57871.28717239 +1935 1824 54280296.46473 +1936 1824 3.09944152832e-06 +1937 1824 231485.1485852 +1938 1824 -7107625.989141 +1939 1824 -6.146728992462e-06 +1940 1824 57871.2871768 +1950 1824 -18663081.30986 +1951 1824 -9166666.669677 +1952 1824 -10337268.9803 +1953 1824 -59964405.70834 +1954 1824 7.525086402893e-07 +1955 1824 -43970603.67818 +1956 1824 -20163436.42398 +1957 1824 9166666.669676 +1958 1824 -11639352.31406 +1825 1825 531622789.3528 +1826 1825 -11110935.09172 +1827 1825 -4.798173904419e-06 +1828 1825 -55180296.03374 +1829 1825 5555467.545859 +1839 1825 -36666666.66065 +1840 1825 -41284001.36615 +1841 1825 1263866.887163 +1842 1825 -5.960464477539e-08 +1843 1825 22901850.42796 +1844 1825 -2777733.774299 +1845 1825 36666666.66064 +1846 1825 -41307675.60857 +1847 1825 1513866.887135 +1917 1825 9166666.669678 +1918 1825 -15819170.72716 +1919 1825 -8385422.169798 +1920 1825 -5.811452865601e-07 +1921 1825 -19232220.47929 +1922 1825 -694433.4439163 +1923 1825 -9166666.669679 +1924 1825 -17307688.72007 +1925 1825 9079855.613715 +1932 1825 2.913177013397e-06 +1933 1825 -35963145.36236 +1934 1825 -33694466.44041 +1935 1825 3.635883331299e-06 +1936 1825 32278708.78388 +1937 1825 -2777733.774297 +1938 1825 -5.349516868591e-06 +1939 1825 -41940891.5735 +1940 1825 36472200.21471 +1950 1825 -9166666.669677 +1951 1825 -15912882.8484 +1952 1825 -8454866.614265 +1953 1825 3.725290298462e-07 +1954 1825 -19630743.20649 +1955 1825 -694433.4439167 +1956 1825 9166666.669676 +1957 1825 -17413237.96253 +1958 1825 9149300.058182 +1826 1826 599591912.5003 +1827 1826 231485.1485663 +1828 1826 5555467.545859 +1829 1826 78550735.85485 +1839 1826 2471062.980849 +1840 1826 1236089.109403 +1841 1826 -7832062.870945 +1842 1826 -462970.2969232 +1843 1826 -2777733.774298 +1844 1826 39890623.87246 +1845 1826 -2737270.351624 +1846 1826 1541644.664895 +1847 1826 -7895194.184061 +1917 1826 10279397.69313 +1918 1826 -8385422.169798 +1919 1826 -16619803.40013 +1920 1826 43704396.30741 +1921 1826 -694433.4439163 +1922 1826 -56581165.5979 +1923 1826 11581481.02689 +1924 1826 9079855.613715 +1925 1826 -20589184.71456 +1932 1826 57871.28717278 +1933 1826 -33666688.66265 +1934 1826 -39477172.9523 +1935 1826 231485.148585 +1936 1826 -2777733.774298 +1937 1826 -118440658.1206 +1938 1826 57871.28717716 +1939 1826 36444422.43695 +1940 1826 -55417829.51533 +1950 1826 -10337268.9803 +1951 1826 -8454866.614265 +1952 1826 -16869702.39011 +1953 1826 -43935881.45598 +1954 1826 -694433.4439167 +1955 1826 -57643892.87044 +1956 1826 -11639352.31406 +1957 1826 9149300.058182 +1958 1826 -20870649.36111 +1827 1827 619629140.0329 +1828 1827 1.168251037598e-05 +1829 1827 925940.5938052 +1830 1827 84152766.23505 +1831 1827 -4.991888999939e-06 +1832 1827 231485.148566 +1842 1827 -52284795.20658 +1843 1827 -36666666.66065 +1844 1827 2505785.203048 +1845 1827 -138432799.5 +1846 1827 1.490116119385e-07 +1847 1827 -462970.296923 +1848 1827 -52308469.44899 +1849 1827 36666666.66065 +1850 1827 -2702548.129425 +1920 1827 -18569369.18862 +1921 1827 9166666.669678 +1922 1827 10279397.69313 +1923 1827 -59565882.98117 +1924 1827 4.91738319397e-07 +1925 1827 43739118.52961 +1926 1827 -20057887.18154 +1927 1827 -9166666.669679 +1928 1827 11581481.02689 +1935 1827 -1129879.778007 +1936 1827 2.369284629822e-06 +1937 1827 57871.28717239 +1938 1827 54280296.46473 +1939 1827 3.09944152832e-06 +1940 1827 231485.1485852 +1941 1827 -7107625.989141 +1942 1827 -6.146728992462e-06 +1943 1827 57871.2871768 +1953 1827 -18663081.30986 +1954 1827 -9166666.669677 +1955 1827 -10337268.9803 +1956 1827 -59964405.70834 +1957 1827 7.525086402893e-07 +1958 1827 -43970603.67818 +1959 1827 -20163436.42398 +1960 1827 9166666.669676 +1961 1827 -11639352.31406 +1828 1828 531622789.3528 +1829 1828 -11110935.09172 +1830 1828 -4.798173904419e-06 +1831 1828 -55180296.03374 +1832 1828 5555467.545859 +1842 1828 -36666666.66065 +1843 1828 -41284001.36615 +1844 1828 1263866.887163 +1845 1828 -5.960464477539e-08 +1846 1828 22901850.42796 +1847 1828 -2777733.774299 +1848 1828 36666666.66064 +1849 1828 -41307675.60857 +1850 1828 1513866.887135 +1920 1828 9166666.669678 +1921 1828 -15819170.72716 +1922 1828 -8385422.169798 +1923 1828 -5.811452865601e-07 +1924 1828 -19232220.47929 +1925 1828 -694433.4439163 +1926 1828 -9166666.669679 +1927 1828 -17307688.72007 +1928 1828 9079855.613715 +1935 1828 2.913177013397e-06 +1936 1828 -35963145.36236 +1937 1828 -33694466.44041 +1938 1828 3.635883331299e-06 +1939 1828 32278708.78388 +1940 1828 -2777733.774297 +1941 1828 -5.349516868591e-06 +1942 1828 -41940891.5735 +1943 1828 36472200.21471 +1953 1828 -9166666.669677 +1954 1828 -15912882.8484 +1955 1828 -8454866.614265 +1956 1828 3.725290298462e-07 +1957 1828 -19630743.20649 +1958 1828 -694433.4439167 +1959 1828 9166666.669676 +1960 1828 -17413237.96253 +1961 1828 9149300.058182 +1829 1829 599591912.5003 +1830 1829 231485.1485663 +1831 1829 5555467.545859 +1832 1829 78550735.85485 +1842 1829 2471062.980849 +1843 1829 1236089.109403 +1844 1829 -7832062.870945 +1845 1829 -462970.2969232 +1846 1829 -2777733.774298 +1847 1829 39890623.87246 +1848 1829 -2737270.351624 +1849 1829 1541644.664895 +1850 1829 -7895194.184061 +1920 1829 10279397.69313 +1921 1829 -8385422.169798 +1922 1829 -16619803.40013 +1923 1829 43704396.30741 +1924 1829 -694433.4439163 +1925 1829 -56581165.5979 +1926 1829 11581481.02689 +1927 1829 9079855.613715 +1928 1829 -20589184.71456 +1935 1829 57871.28717278 +1936 1829 -33666688.66265 +1937 1829 -39477172.9523 +1938 1829 231485.148585 +1939 1829 -2777733.774298 +1940 1829 -118440658.1206 +1941 1829 57871.28717716 +1942 1829 36444422.43695 +1943 1829 -55417829.51533 +1953 1829 -10337268.9803 +1954 1829 -8454866.614265 +1955 1829 -16869702.39011 +1956 1829 -43935881.45598 +1957 1829 -694433.4439167 +1958 1829 -57643892.87044 +1959 1829 -11639352.31406 +1960 1829 9149300.058182 +1961 1829 -20870649.36111 +1830 1830 619629140.0329 +1831 1830 1.168251037598e-05 +1832 1830 925940.5938052 +1833 1830 84152766.23505 +1834 1830 -4.991888999939e-06 +1835 1830 231485.148566 +1845 1830 -52284795.20658 +1846 1830 -36666666.66065 +1847 1830 2505785.203048 +1848 1830 -138432799.5 +1849 1830 1.490116119385e-07 +1850 1830 -462970.296923 +1851 1830 -52308469.44899 +1852 1830 36666666.66065 +1853 1830 -2702548.129425 +1923 1830 -18569369.18862 +1924 1830 9166666.669678 +1925 1830 10279397.69313 +1926 1830 -59565882.98117 +1927 1830 4.91738319397e-07 +1928 1830 43739118.52961 +1929 1830 -20057887.18154 +1930 1830 -9166666.669679 +1931 1830 11581481.02689 +1938 1830 -1129879.778007 +1939 1830 2.369284629822e-06 +1940 1830 57871.28717239 +1941 1830 54280296.46473 +1942 1830 3.09944152832e-06 +1943 1830 231485.1485852 +1944 1830 -7107625.989141 +1945 1830 -6.146728992462e-06 +1946 1830 57871.2871768 +1956 1830 -18663081.30986 +1957 1830 -9166666.669677 +1958 1830 -10337268.9803 +1959 1830 -59964405.70834 +1960 1830 7.525086402893e-07 +1961 1830 -43970603.67818 +1962 1830 -20163436.42398 +1963 1830 9166666.669676 +1964 1830 -11639352.31406 +1831 1831 531622789.3528 +1832 1831 -11110935.09172 +1833 1831 -4.798173904419e-06 +1834 1831 -55180296.03374 +1835 1831 5555467.545859 +1845 1831 -36666666.66065 +1846 1831 -41284001.36615 +1847 1831 1263866.887163 +1848 1831 -5.960464477539e-08 +1849 1831 22901850.42796 +1850 1831 -2777733.774299 +1851 1831 36666666.66064 +1852 1831 -41307675.60857 +1853 1831 1513866.887135 +1923 1831 9166666.669678 +1924 1831 -15819170.72716 +1925 1831 -8385422.169798 +1926 1831 -5.811452865601e-07 +1927 1831 -19232220.47929 +1928 1831 -694433.4439163 +1929 1831 -9166666.669679 +1930 1831 -17307688.72007 +1931 1831 9079855.613715 +1938 1831 2.913177013397e-06 +1939 1831 -35963145.36236 +1940 1831 -33694466.44041 +1941 1831 3.635883331299e-06 +1942 1831 32278708.78388 +1943 1831 -2777733.774297 +1944 1831 -5.349516868591e-06 +1945 1831 -41940891.5735 +1946 1831 36472200.21471 +1956 1831 -9166666.669677 +1957 1831 -15912882.8484 +1958 1831 -8454866.614265 +1959 1831 3.725290298462e-07 +1960 1831 -19630743.20649 +1961 1831 -694433.4439167 +1962 1831 9166666.669676 +1963 1831 -17413237.96253 +1964 1831 9149300.058182 +1832 1832 599591912.5003 +1833 1832 231485.1485663 +1834 1832 5555467.545859 +1835 1832 78550735.85485 +1845 1832 2471062.980849 +1846 1832 1236089.109403 +1847 1832 -7832062.870945 +1848 1832 -462970.2969232 +1849 1832 -2777733.774298 +1850 1832 39890623.87246 +1851 1832 -2737270.351624 +1852 1832 1541644.664895 +1853 1832 -7895194.184061 +1923 1832 10279397.69313 +1924 1832 -8385422.169798 +1925 1832 -16619803.40013 +1926 1832 43704396.30741 +1927 1832 -694433.4439163 +1928 1832 -56581165.5979 +1929 1832 11581481.02689 +1930 1832 9079855.613715 +1931 1832 -20589184.71456 +1938 1832 57871.28717278 +1939 1832 -33666688.66265 +1940 1832 -39477172.9523 +1941 1832 231485.148585 +1942 1832 -2777733.774298 +1943 1832 -118440658.1206 +1944 1832 57871.28717716 +1945 1832 36444422.43695 +1946 1832 -55417829.51533 +1956 1832 -10337268.9803 +1957 1832 -8454866.614265 +1958 1832 -16869702.39011 +1959 1832 -43935881.45598 +1960 1832 -694433.4439167 +1961 1832 -57643892.87044 +1962 1832 -11639352.31406 +1963 1832 9149300.058182 +1964 1832 -20870649.36111 +1833 1833 671761428.9985 +1834 1833 36667432.73655 +1835 1833 3125088.651632 +1836 1833 19448570.31785 +1837 1833 -36666973.09101 +1838 1833 2702570.135099 +1848 1833 -52284795.20658 +1849 1833 -36666666.66065 +1850 1833 2505785.203048 +1851 1833 -138432799.5 +1852 1833 1.490116119385e-07 +1853 1833 -462970.296923 +1854 1833 -52308469.44899 +1855 1833 36666666.66065 +1856 1833 -2702548.129425 +1926 1833 -18569369.18862 +1927 1833 9166666.669678 +1928 1833 10279397.69313 +1929 1833 -72039530.38171 +1930 1833 -9166781.581061 +1931 1833 43189554.83944 +1941 1833 -1129879.778007 +1942 1833 2.369284629822e-06 +1943 1833 57871.28717239 +1944 1833 73599694.87993 +1945 1833 9166858.188655 +1946 1833 781226.7976368 +1947 1833 -19443104.86928 +1948 1833 -9166743.27727 +1949 1833 11639449.48452 +1959 1833 -18663081.30986 +1960 1833 -9166666.669677 +1961 1833 -10337268.9803 +1962 1833 -59964405.70834 +1963 1833 7.525086402893e-07 +1964 1833 -43970603.67818 +1965 1833 -20163436.42398 +1966 1833 9166666.669676 +1967 1833 -11639352.31406 +1834 1834 572753939.719 +1835 1834 -8610914.043003 +1836 1834 -36667126.30619 +1837 1834 -108884310.9615 +1838 1834 4611018.689007 +1848 1834 -36666666.66065 +1849 1834 -41284001.36615 +1850 1834 1263866.887163 +1851 1834 -5.960464477539e-08 +1852 1834 22901850.42796 +1853 1834 -2777733.774299 +1854 1834 36666666.66064 +1855 1834 -41307675.60857 +1856 1834 1513866.887135 +1926 1834 9166666.669678 +1927 1834 -15819170.72716 +1928 1834 -8385422.169798 +1929 1834 -9166743.277267 +1930 1834 -28955430.01587 +1931 1834 7996602.428466 +1941 1834 2.913177013397e-06 +1942 1834 -35963145.36236 +1943 1834 -33694466.44041 +1944 1834 9166858.188655 +1945 1834 48847822.54786 +1946 1834 -2152764.803778 +1947 1834 -9166781.581064 +1948 1834 -51526325.20493 +1949 1834 36236271.0855 +1959 1834 -9166666.669677 +1960 1834 -15912882.8484 +1961 1834 -8454866.614265 +1962 1834 3.725290298462e-07 +1963 1834 -19630743.20649 +1964 1834 -694433.4439167 +1965 1834 9166666.669676 +1966 1834 -17413237.96253 +1967 1834 9149300.058182 +1835 1835 607013167.9741 +1836 1835 2737303.360137 +1837 1835 5388804.78494 +1838 1835 37600883.93994 +1848 1835 2471062.980849 +1849 1835 1236089.109403 +1850 1835 -7832062.870945 +1851 1835 -462970.2969232 +1852 1835 -2777733.774298 +1853 1835 39890623.87246 +1854 1835 -2737270.351624 +1855 1835 1541644.664895 +1856 1835 -7895194.184061 +1926 1835 10279397.69313 +1927 1835 -8385422.169798 +1928 1835 -16619803.40013 +1929 1835 43154829.95728 +1930 1835 7802192.5578 +1931 1835 -56944833.0873 +1941 1835 57871.28717278 +1942 1835 -33666688.66265 +1943 1835 -39477172.9523 +1944 1835 781318.4370322 +1945 1835 -2152691.493423 +1946 1835 -99821807.80486 +1947 1835 11639498.06975 +1948 1835 36402939.91804 +1949 1835 -55413772.21342 +1959 1835 -10337268.9803 +1960 1835 -8454866.614265 +1961 1835 -16869702.39011 +1962 1835 -43935881.45598 +1963 1835 -694433.4439167 +1964 1835 -57643892.87044 +1965 1835 -11639352.31406 +1966 1835 9149300.058182 +1967 1835 -20870649.36111 +1836 1836 460873125.4361 +1837 1836 -27780651.28176 +1838 1836 -1243230.409633 +1851 1836 -52284795.20658 +1852 1836 -36666666.66065 +1853 1836 2505785.203048 +1854 1836 -54494915.13083 +1855 1836 27775705.0022 +1856 1836 -284486.8047392 +1857 1836 -253893652.0179 +1858 1836 29338279.60807 +1859 1836 -277841.1803685 +1929 1836 -4839277.140465 +1930 1836 11000114.915 +1931 1836 12370128.70975 +1944 1836 -14860172.33131 +1945 1836 -9166781.581062 +1946 1836 -10279526.39882 +1947 1836 64920055.70775 +1948 1836 -6810686.593768 +1949 1836 4688786.852337 +1962 1836 -18663081.30986 +1963 1836 -9166666.669677 +1964 1836 -10337268.9803 +1965 1836 -28004319.24308 +1966 1836 6809529.72167 +1967 1836 -24862467.02138 +1968 1836 -60799172.28945 +1969 1836 7334490.207843 +1970 1836 -1215195.31154 +1837 1837 860522545.6296 +1838 1837 -12063310.05486 +1851 1837 -36666666.66065 +1852 1837 -41284001.36615 +1853 1837 1263866.887163 +1854 1837 27773231.86242 +1855 1837 88863699.5249 +1856 1837 -2000807.444541 +1857 1837 44007419.41211 +1858 1837 -679569599.4282 +1859 1837 5800626.008788 +1929 1837 7333409.943332 +1930 1837 -4839277.140466 +1931 1837 -6597291.372073 +1944 1837 -9166743.277267 +1945 1837 -46943392.66696 +1946 1837 -33736315.15602 +1947 1837 -6810686.593769 +1948 1837 157857373.3892 +1949 1837 1049845.884691 +1962 1837 -9166666.669677 +1963 1837 -15912882.8484 +1964 1837 -8454866.614265 +1965 1837 6808951.285619 +1966 1837 7895373.789088 +1967 1837 6105067.934335 +1968 1837 11001735.31176 +1969 1837 -160303161.1289 +1970 1837 18261345.26948 +1838 1838 492262051.6588 +1851 1838 2471062.980849 +1852 1838 1236089.109403 +1853 1838 -7832062.870945 +1854 1838 -1048345.411919 +1855 1838 -1889626.655437 +1856 1838 48405140.97272 +1857 1838 -416761.7705528 +1858 1838 5689599.184121 +1859 1838 -251373791.3042 +1929 1838 8246752.473166 +1930 1838 -9895937.05811 +1931 1838 -12904739.04124 +1944 1838 -10279483.49692 +1945 1838 -33902984.10692 +1946 1838 -43192618.77883 +1947 1838 -5224449.190063 +1948 1838 -6768692.222871 +1949 1838 -4871347.006253 +1962 1838 -10337268.9803 +1963 1838 -8454866.614265 +1964 1838 -16869702.39011 +1965 1838 -25036071.0635 +1966 1838 6188978.792547 +1967 1838 -25523699.80167 +1968 1838 -1822792.96731 +1969 1838 17775180.12884 +1970 1838 -62627137.26573 +1839 1839 619629140.0329 +1840 1839 1.168251037598e-05 +1841 1839 925940.5938052 +1842 1839 84152766.23505 +1843 1839 -4.991888999939e-06 +1844 1839 231485.148566 +1860 1839 -138432799.5 +1861 1839 1.490116119385e-07 +1862 1839 -462970.296923 +1863 1839 -52308469.44899 +1864 1839 36666666.66065 +1865 1839 -2702548.129425 +1932 1839 -59565882.98117 +1933 1839 4.91738319397e-07 +1934 1839 43739118.52961 +1935 1839 -20057887.18154 +1936 1839 -9166666.669679 +1937 1839 11581481.02689 +1950 1839 54280296.46473 +1951 1839 3.09944152832e-06 +1952 1839 231485.1485852 +1953 1839 -7107625.989141 +1954 1839 -6.146728992462e-06 +1955 1839 57871.2871768 +1971 1839 -59964405.70834 +1972 1839 7.525086402893e-07 +1973 1839 -43970603.67818 +1974 1839 -20163436.42398 +1975 1839 9166666.669676 +1976 1839 -11639352.31406 +1840 1840 531622789.3528 +1841 1840 -11110935.09172 +1842 1840 -4.798173904419e-06 +1843 1840 -55180296.03374 +1844 1840 5555467.545859 +1860 1840 -5.960464477539e-08 +1861 1840 22901850.42796 +1862 1840 -2777733.774299 +1863 1840 36666666.66064 +1864 1840 -41307675.60857 +1865 1840 1513866.887135 +1932 1840 -5.811452865601e-07 +1933 1840 -19232220.47929 +1934 1840 -694433.4439163 +1935 1840 -9166666.669679 +1936 1840 -17307688.72007 +1937 1840 9079855.613715 +1950 1840 3.635883331299e-06 +1951 1840 32278708.78388 +1952 1840 -2777733.774297 +1953 1840 -5.349516868591e-06 +1954 1840 -41940891.5735 +1955 1840 36472200.21471 +1971 1840 3.725290298462e-07 +1972 1840 -19630743.20649 +1973 1840 -694433.4439167 +1974 1840 9166666.669676 +1975 1840 -17413237.96253 +1976 1840 9149300.058182 +1841 1841 599591912.5003 +1842 1841 231485.1485663 +1843 1841 5555467.545859 +1844 1841 78550735.85485 +1860 1841 -462970.2969232 +1861 1841 -2777733.774298 +1862 1841 39890623.87246 +1863 1841 -2737270.351624 +1864 1841 1541644.664895 +1865 1841 -7895194.184061 +1932 1841 43704396.30741 +1933 1841 -694433.4439163 +1934 1841 -56581165.5979 +1935 1841 11581481.02689 +1936 1841 9079855.613715 +1937 1841 -20589184.71456 +1950 1841 231485.148585 +1951 1841 -2777733.774298 +1952 1841 -118440658.1206 +1953 1841 57871.28717716 +1954 1841 36444422.43695 +1955 1841 -55417829.51533 +1971 1841 -43935881.45598 +1972 1841 -694433.4439167 +1973 1841 -57643892.87044 +1974 1841 -11639352.31406 +1975 1841 9149300.058182 +1976 1841 -20870649.36111 +1842 1842 619629140.0329 +1843 1842 1.168251037598e-05 +1844 1842 925940.5938052 +1845 1842 84152766.23505 +1846 1842 -4.991888999939e-06 +1847 1842 231485.148566 +1860 1842 -52284795.20658 +1861 1842 -36666666.66065 +1862 1842 2505785.203048 +1863 1842 -138432799.5 +1864 1842 1.490116119385e-07 +1865 1842 -462970.296923 +1866 1842 -52308469.44899 +1867 1842 36666666.66065 +1868 1842 -2702548.129425 +1932 1842 -18569369.18862 +1933 1842 9166666.669678 +1934 1842 10279397.69313 +1935 1842 -59565882.98117 +1936 1842 4.91738319397e-07 +1937 1842 43739118.52961 +1938 1842 -20057887.18154 +1939 1842 -9166666.669679 +1940 1842 11581481.02689 +1950 1842 -1129879.778007 +1951 1842 2.369284629822e-06 +1952 1842 57871.28717239 +1953 1842 54280296.46473 +1954 1842 3.09944152832e-06 +1955 1842 231485.1485852 +1956 1842 -7107625.989141 +1957 1842 -6.146728992462e-06 +1958 1842 57871.2871768 +1971 1842 -18663081.30986 +1972 1842 -9166666.669677 +1973 1842 -10337268.9803 +1974 1842 -59964405.70834 +1975 1842 7.525086402893e-07 +1976 1842 -43970603.67818 +1977 1842 -20163436.42398 +1978 1842 9166666.669676 +1979 1842 -11639352.31406 +1843 1843 531622789.3528 +1844 1843 -11110935.09172 +1845 1843 -4.798173904419e-06 +1846 1843 -55180296.03374 +1847 1843 5555467.545859 +1860 1843 -36666666.66065 +1861 1843 -41284001.36615 +1862 1843 1263866.887163 +1863 1843 -5.960464477539e-08 +1864 1843 22901850.42796 +1865 1843 -2777733.774299 +1866 1843 36666666.66064 +1867 1843 -41307675.60857 +1868 1843 1513866.887135 +1932 1843 9166666.669678 +1933 1843 -15819170.72716 +1934 1843 -8385422.169798 +1935 1843 -5.811452865601e-07 +1936 1843 -19232220.47929 +1937 1843 -694433.4439163 +1938 1843 -9166666.669679 +1939 1843 -17307688.72007 +1940 1843 9079855.613715 +1950 1843 2.913177013397e-06 +1951 1843 -35963145.36236 +1952 1843 -33694466.44041 +1953 1843 3.635883331299e-06 +1954 1843 32278708.78388 +1955 1843 -2777733.774297 +1956 1843 -5.349516868591e-06 +1957 1843 -41940891.5735 +1958 1843 36472200.21471 +1971 1843 -9166666.669677 +1972 1843 -15912882.8484 +1973 1843 -8454866.614265 +1974 1843 3.725290298462e-07 +1975 1843 -19630743.20649 +1976 1843 -694433.4439167 +1977 1843 9166666.669676 +1978 1843 -17413237.96253 +1979 1843 9149300.058182 +1844 1844 599591912.5003 +1845 1844 231485.1485663 +1846 1844 5555467.545859 +1847 1844 78550735.85485 +1860 1844 2471062.980849 +1861 1844 1236089.109403 +1862 1844 -7832062.870945 +1863 1844 -462970.2969232 +1864 1844 -2777733.774298 +1865 1844 39890623.87246 +1866 1844 -2737270.351624 +1867 1844 1541644.664895 +1868 1844 -7895194.184061 +1932 1844 10279397.69313 +1933 1844 -8385422.169798 +1934 1844 -16619803.40013 +1935 1844 43704396.30741 +1936 1844 -694433.4439163 +1937 1844 -56581165.5979 +1938 1844 11581481.02689 +1939 1844 9079855.613715 +1940 1844 -20589184.71456 +1950 1844 57871.28717278 +1951 1844 -33666688.66265 +1952 1844 -39477172.9523 +1953 1844 231485.148585 +1954 1844 -2777733.774298 +1955 1844 -118440658.1206 +1956 1844 57871.28717716 +1957 1844 36444422.43695 +1958 1844 -55417829.51533 +1971 1844 -10337268.9803 +1972 1844 -8454866.614265 +1973 1844 -16869702.39011 +1974 1844 -43935881.45598 +1975 1844 -694433.4439167 +1976 1844 -57643892.87044 +1977 1844 -11639352.31406 +1978 1844 9149300.058182 +1979 1844 -20870649.36111 +1845 1845 619629140.0329 +1846 1845 1.168251037598e-05 +1847 1845 925940.5938052 +1848 1845 84152766.23505 +1849 1845 -4.991888999939e-06 +1850 1845 231485.148566 +1863 1845 -52284795.20658 +1864 1845 -36666666.66065 +1865 1845 2505785.203048 +1866 1845 -138432799.5 +1867 1845 1.490116119385e-07 +1868 1845 -462970.296923 +1869 1845 -52308469.44899 +1870 1845 36666666.66065 +1871 1845 -2702548.129425 +1935 1845 -18569369.18862 +1936 1845 9166666.669678 +1937 1845 10279397.69313 +1938 1845 -59565882.98117 +1939 1845 4.91738319397e-07 +1940 1845 43739118.52961 +1941 1845 -20057887.18154 +1942 1845 -9166666.669679 +1943 1845 11581481.02689 +1953 1845 -1129879.778007 +1954 1845 2.369284629822e-06 +1955 1845 57871.28717239 +1956 1845 54280296.46473 +1957 1845 3.09944152832e-06 +1958 1845 231485.1485852 +1959 1845 -7107625.989141 +1960 1845 -6.146728992462e-06 +1961 1845 57871.2871768 +1974 1845 -18663081.30986 +1975 1845 -9166666.669677 +1976 1845 -10337268.9803 +1977 1845 -59964405.70834 +1978 1845 7.525086402893e-07 +1979 1845 -43970603.67818 +1980 1845 -20163436.42398 +1981 1845 9166666.669676 +1982 1845 -11639352.31406 +1846 1846 531622789.3528 +1847 1846 -11110935.09172 +1848 1846 -4.798173904419e-06 +1849 1846 -55180296.03374 +1850 1846 5555467.545859 +1863 1846 -36666666.66065 +1864 1846 -41284001.36615 +1865 1846 1263866.887163 +1866 1846 -5.960464477539e-08 +1867 1846 22901850.42796 +1868 1846 -2777733.774299 +1869 1846 36666666.66064 +1870 1846 -41307675.60857 +1871 1846 1513866.887135 +1935 1846 9166666.669678 +1936 1846 -15819170.72716 +1937 1846 -8385422.169798 +1938 1846 -5.811452865601e-07 +1939 1846 -19232220.47929 +1940 1846 -694433.4439163 +1941 1846 -9166666.669679 +1942 1846 -17307688.72007 +1943 1846 9079855.613715 +1953 1846 2.913177013397e-06 +1954 1846 -35963145.36236 +1955 1846 -33694466.44041 +1956 1846 3.635883331299e-06 +1957 1846 32278708.78388 +1958 1846 -2777733.774297 +1959 1846 -5.349516868591e-06 +1960 1846 -41940891.5735 +1961 1846 36472200.21471 +1974 1846 -9166666.669677 +1975 1846 -15912882.8484 +1976 1846 -8454866.614265 +1977 1846 3.725290298462e-07 +1978 1846 -19630743.20649 +1979 1846 -694433.4439167 +1980 1846 9166666.669676 +1981 1846 -17413237.96253 +1982 1846 9149300.058182 +1847 1847 599591912.5003 +1848 1847 231485.1485663 +1849 1847 5555467.545859 +1850 1847 78550735.85485 +1863 1847 2471062.980849 +1864 1847 1236089.109403 +1865 1847 -7832062.870945 +1866 1847 -462970.2969232 +1867 1847 -2777733.774298 +1868 1847 39890623.87246 +1869 1847 -2737270.351624 +1870 1847 1541644.664895 +1871 1847 -7895194.184061 +1935 1847 10279397.69313 +1936 1847 -8385422.169798 +1937 1847 -16619803.40013 +1938 1847 43704396.30741 +1939 1847 -694433.4439163 +1940 1847 -56581165.5979 +1941 1847 11581481.02689 +1942 1847 9079855.613715 +1943 1847 -20589184.71456 +1953 1847 57871.28717278 +1954 1847 -33666688.66265 +1955 1847 -39477172.9523 +1956 1847 231485.148585 +1957 1847 -2777733.774298 +1958 1847 -118440658.1206 +1959 1847 57871.28717716 +1960 1847 36444422.43695 +1961 1847 -55417829.51533 +1974 1847 -10337268.9803 +1975 1847 -8454866.614265 +1976 1847 -16869702.39011 +1977 1847 -43935881.45598 +1978 1847 -694433.4439167 +1979 1847 -57643892.87044 +1980 1847 -11639352.31406 +1981 1847 9149300.058182 +1982 1847 -20870649.36111 +1848 1848 619629140.0329 +1849 1848 1.168251037598e-05 +1850 1848 925940.5938052 +1851 1848 84152766.23505 +1852 1848 -4.991888999939e-06 +1853 1848 231485.148566 +1866 1848 -52284795.20658 +1867 1848 -36666666.66065 +1868 1848 2505785.203048 +1869 1848 -138432799.5 +1870 1848 1.490116119385e-07 +1871 1848 -462970.296923 +1872 1848 -52308469.44899 +1873 1848 36666666.66065 +1874 1848 -2702548.129425 +1938 1848 -18569369.18862 +1939 1848 9166666.669678 +1940 1848 10279397.69313 +1941 1848 -59565882.98117 +1942 1848 4.91738319397e-07 +1943 1848 43739118.52961 +1944 1848 -20057887.18154 +1945 1848 -9166666.669679 +1946 1848 11581481.02689 +1956 1848 -1129879.778007 +1957 1848 2.369284629822e-06 +1958 1848 57871.28717239 +1959 1848 54280296.46473 +1960 1848 3.09944152832e-06 +1961 1848 231485.1485852 +1962 1848 -7107625.989141 +1963 1848 -6.146728992462e-06 +1964 1848 57871.2871768 +1977 1848 -18663081.30986 +1978 1848 -9166666.669677 +1979 1848 -10337268.9803 +1980 1848 -59964405.70834 +1981 1848 7.525086402893e-07 +1982 1848 -43970603.67818 +1983 1848 -20163436.42398 +1984 1848 9166666.669676 +1985 1848 -11639352.31406 +1849 1849 531622789.3528 +1850 1849 -11110935.09172 +1851 1849 -4.798173904419e-06 +1852 1849 -55180296.03374 +1853 1849 5555467.545859 +1866 1849 -36666666.66065 +1867 1849 -41284001.36615 +1868 1849 1263866.887163 +1869 1849 -5.960464477539e-08 +1870 1849 22901850.42796 +1871 1849 -2777733.774299 +1872 1849 36666666.66064 +1873 1849 -41307675.60857 +1874 1849 1513866.887135 +1938 1849 9166666.669678 +1939 1849 -15819170.72716 +1940 1849 -8385422.169798 +1941 1849 -5.811452865601e-07 +1942 1849 -19232220.47929 +1943 1849 -694433.4439163 +1944 1849 -9166666.669679 +1945 1849 -17307688.72007 +1946 1849 9079855.613715 +1956 1849 2.913177013397e-06 +1957 1849 -35963145.36236 +1958 1849 -33694466.44041 +1959 1849 3.635883331299e-06 +1960 1849 32278708.78388 +1961 1849 -2777733.774297 +1962 1849 -5.349516868591e-06 +1963 1849 -41940891.5735 +1964 1849 36472200.21471 +1977 1849 -9166666.669677 +1978 1849 -15912882.8484 +1979 1849 -8454866.614265 +1980 1849 3.725290298462e-07 +1981 1849 -19630743.20649 +1982 1849 -694433.4439167 +1983 1849 9166666.669676 +1984 1849 -17413237.96253 +1985 1849 9149300.058182 +1850 1850 599591912.5003 +1851 1850 231485.1485663 +1852 1850 5555467.545859 +1853 1850 78550735.85485 +1866 1850 2471062.980849 +1867 1850 1236089.109403 +1868 1850 -7832062.870945 +1869 1850 -462970.2969232 +1870 1850 -2777733.774298 +1871 1850 39890623.87246 +1872 1850 -2737270.351624 +1873 1850 1541644.664895 +1874 1850 -7895194.184061 +1938 1850 10279397.69313 +1939 1850 -8385422.169798 +1940 1850 -16619803.40013 +1941 1850 43704396.30741 +1942 1850 -694433.4439163 +1943 1850 -56581165.5979 +1944 1850 11581481.02689 +1945 1850 9079855.613715 +1946 1850 -20589184.71456 +1956 1850 57871.28717278 +1957 1850 -33666688.66265 +1958 1850 -39477172.9523 +1959 1850 231485.148585 +1960 1850 -2777733.774298 +1961 1850 -118440658.1206 +1962 1850 57871.28717716 +1963 1850 36444422.43695 +1964 1850 -55417829.51533 +1977 1850 -10337268.9803 +1978 1850 -8454866.614265 +1979 1850 -16869702.39011 +1980 1850 -43935881.45598 +1981 1850 -694433.4439167 +1982 1850 -57643892.87044 +1983 1850 -11639352.31406 +1984 1850 9149300.058182 +1985 1850 -20870649.36111 +1851 1851 619629140.0329 +1852 1851 1.168251037598e-05 +1853 1851 925940.5938052 +1854 1851 84152766.23505 +1855 1851 -4.991888999939e-06 +1856 1851 231485.148566 +1869 1851 -52284795.20658 +1870 1851 -36666666.66065 +1871 1851 2505785.203048 +1872 1851 -138432799.5 +1873 1851 1.490116119385e-07 +1874 1851 -462970.296923 +1875 1851 -52308469.44899 +1876 1851 36666666.66065 +1877 1851 -2702548.129425 +1941 1851 -18569369.18862 +1942 1851 9166666.669678 +1943 1851 10279397.69313 +1944 1851 -59565882.98117 +1945 1851 4.91738319397e-07 +1946 1851 43739118.52961 +1947 1851 -20057887.18154 +1948 1851 -9166666.669679 +1949 1851 11581481.02689 +1959 1851 -1129879.778007 +1960 1851 2.369284629822e-06 +1961 1851 57871.28717239 +1962 1851 54280296.46473 +1963 1851 3.09944152832e-06 +1964 1851 231485.1485852 +1965 1851 -7107625.989141 +1966 1851 -6.146728992462e-06 +1967 1851 57871.2871768 +1980 1851 -18663081.30986 +1981 1851 -9166666.669677 +1982 1851 -10337268.9803 +1983 1851 -59964405.70834 +1984 1851 7.525086402893e-07 +1985 1851 -43970603.67818 +1986 1851 -20163436.42398 +1987 1851 9166666.669676 +1988 1851 -11639352.31406 +1852 1852 531622789.3528 +1853 1852 -11110935.09172 +1854 1852 -4.798173904419e-06 +1855 1852 -55180296.03374 +1856 1852 5555467.545859 +1869 1852 -36666666.66065 +1870 1852 -41284001.36615 +1871 1852 1263866.887163 +1872 1852 -5.960464477539e-08 +1873 1852 22901850.42796 +1874 1852 -2777733.774299 +1875 1852 36666666.66064 +1876 1852 -41307675.60857 +1877 1852 1513866.887135 +1941 1852 9166666.669678 +1942 1852 -15819170.72716 +1943 1852 -8385422.169798 +1944 1852 -5.811452865601e-07 +1945 1852 -19232220.47929 +1946 1852 -694433.4439163 +1947 1852 -9166666.669679 +1948 1852 -17307688.72007 +1949 1852 9079855.613715 +1959 1852 2.913177013397e-06 +1960 1852 -35963145.36236 +1961 1852 -33694466.44041 +1962 1852 3.635883331299e-06 +1963 1852 32278708.78388 +1964 1852 -2777733.774297 +1965 1852 -5.349516868591e-06 +1966 1852 -41940891.5735 +1967 1852 36472200.21471 +1980 1852 -9166666.669677 +1981 1852 -15912882.8484 +1982 1852 -8454866.614265 +1983 1852 3.725290298462e-07 +1984 1852 -19630743.20649 +1985 1852 -694433.4439167 +1986 1852 9166666.669676 +1987 1852 -17413237.96253 +1988 1852 9149300.058182 +1853 1853 599591912.5003 +1854 1853 231485.1485663 +1855 1853 5555467.545859 +1856 1853 78550735.85485 +1869 1853 2471062.980849 +1870 1853 1236089.109403 +1871 1853 -7832062.870945 +1872 1853 -462970.2969232 +1873 1853 -2777733.774298 +1874 1853 39890623.87246 +1875 1853 -2737270.351624 +1876 1853 1541644.664895 +1877 1853 -7895194.184061 +1941 1853 10279397.69313 +1942 1853 -8385422.169798 +1943 1853 -16619803.40013 +1944 1853 43704396.30741 +1945 1853 -694433.4439163 +1946 1853 -56581165.5979 +1947 1853 11581481.02689 +1948 1853 9079855.613715 +1949 1853 -20589184.71456 +1959 1853 57871.28717278 +1960 1853 -33666688.66265 +1961 1853 -39477172.9523 +1962 1853 231485.148585 +1963 1853 -2777733.774298 +1964 1853 -118440658.1206 +1965 1853 57871.28717716 +1966 1853 36444422.43695 +1967 1853 -55417829.51533 +1980 1853 -10337268.9803 +1981 1853 -8454866.614265 +1982 1853 -16869702.39011 +1983 1853 -43935881.45598 +1984 1853 -694433.4439167 +1985 1853 -57643892.87044 +1986 1853 -11639352.31406 +1987 1853 9149300.058182 +1988 1853 -20870649.36111 +1854 1854 525679167.9811 +1855 1854 18390868.10895 +1856 1854 257230.0209704 +1857 1854 -103629435.2263 +1858 1854 -78331026.88709 +1859 1854 634702.4175476 +1872 1854 -52284795.20658 +1873 1854 -36666666.66065 +1874 1854 2505785.203048 +1875 1854 -86773795.75742 +1876 1854 24416035.48061 +1877 1854 -106696.56214 +1878 1854 -50334865.85163 +1879 1854 7750891.435108 +1880 1854 -153554.2915443 +1944 1854 -18569369.18862 +1945 1854 9166666.669678 +1946 1854 10279397.69313 +1947 1854 -27520936.3574 +1948 1854 6808951.285619 +1949 1854 24530109.1485 +1962 1854 -1129879.778007 +1963 1854 2.369284629822e-06 +1964 1854 57871.28717239 +1965 1854 65159811.72745 +1966 1854 4731994.015123 +1967 1854 11710.09029299 +1968 1854 -37308949.32533 +1969 1854 -19582677.03363 +1970 1854 11434375.89806 +1983 1854 -18663081.30986 +1984 1854 -9166666.669677 +1985 1854 -10337268.9803 +1986 1854 -44289186.74016 +1987 1854 6104008.873161 +1988 1854 -34010528.30258 +1989 1854 -19096765.45373 +1990 1854 1937722.859732 +1991 1854 -1131791.351039 +1855 1855 660481314.2789 +1856 1855 -8369902.192371 +1857 1855 -78333500.02687 +1858 1855 -263254974.2493 +1859 1855 1658380.723923 +1872 1855 -36666666.66065 +1873 1855 -41284001.36615 +1874 1855 1263866.887163 +1875 1855 24416035.48061 +1876 1855 13565168.38836 +1877 1855 -1207997.421921 +1878 1855 7750891.435108 +1879 1855 -151877577.34 +1880 1855 1114835.39655 +1944 1855 9166666.669678 +1945 1855 -15819170.72716 +1946 1855 -8385422.169798 +1947 1855 6809529.721669 +1948 1855 8378756.674785 +1949 1855 -7098393.156867 +1962 1855 2.913177013397e-06 +1963 1855 -35963145.36236 +1964 1855 -33694466.44041 +1965 1855 4731994.015121 +1966 1855 98799919.06592 +1967 1855 -2134553.493147 +1968 1855 -19583255.46968 +1969 1855 -77214944.19873 +1970 1855 35895592.87145 +1983 1855 -9166666.669677 +1984 1855 -15912882.8484 +1985 1855 -8454866.614265 +1986 1855 6104008.87316 +1987 1855 -19204445.69136 +1988 1855 7593833.975638 +1989 1855 1937722.859732 +1990 1855 -44482443.33833 +1991 1855 16945375.52141 +1856 1856 512079213.2787 +1857 1856 600011.8966515 +1858 1856 1686229.320647 +1859 1856 -69210047.65795 +1872 1856 2471062.980849 +1873 1856 1236089.109403 +1874 1856 -7832062.870945 +1875 1856 -974752.1175541 +1876 1856 -1235775.199694 +1877 1856 43298672.25768 +1878 1856 -222998.7359433 +1879 1856 1114835.39655 +1880 1856 -37381370.73265 +1944 1856 10279397.69313 +1945 1856 -8385422.169798 +1946 1856 -16619803.40013 +1947 1856 24703713.19063 +1948 1856 -7070068.954014 +1949 1856 -24234678.77313 +1962 1856 57871.28717278 +1963 1856 -33666688.66265 +1964 1856 -39477172.9523 +1965 1856 289668.3564975 +1966 1856 -1912186.845125 +1967 1856 -49396343.76105 +1968 1856 11573362.44061 +1969 1856 35950674.48827 +1970 1856 -47707143.17434 +1983 1856 -10337268.9803 +1984 1856 -8454866.614265 +1985 1856 -16869702.39011 +1986 1856 -34184139.41185 +1987 1856 7593833.977188 +1988 1856 -49430632.70391 +1989 1856 -1131791.351039 +1990 1856 16945375.52141 +1991 1856 -26713473.31342 +1857 1857 614839050.8983 +1858 1857 17973732.66542 +1859 1857 -212215.4261644 +1875 1857 -52690570.14122 +1876 1857 -32132015.60604 +1877 1857 329236.32717 +1878 1857 37598828.59377 +1879 1857 40566555.84207 +1880 1857 -165449.1983437 +1881 1857 63708429.49975 +1882 1857 -20771303.28056 +1883 1857 3243.047472715 +1884 1857 -826617.3637437 +1885 1857 28689110.99388 +1886 1857 -68620.43168689 +1947 1857 -60299571.71085 +1948 1857 11001735.31176 +1949 1857 1614415.106212 +1965 1857 -36445705.69433 +1966 1857 -19583255.46968 +1967 1857 -11177873.40535 +1968 1857 43966363.06476 +1969 1857 4476096.649079 +1970 1857 8618713.609176 +1986 1857 -19361814.47454 +1987 1857 -8033003.905469 +1988 1857 -10880711.7551 +1989 1857 -39854510.3119 +1990 1857 10129174.62529 +1991 1857 -43009370.51522 +1992 1857 -23114447.75168 +1993 1857 -5175489.303206 +1994 1857 13763626.62675 +1995 1857 -17144369.31473 +1996 1857 7184742.092224 +1997 1857 -10629355.22208 +1858 1858 1128106300.08 +1859 1858 -6751433.635311 +1875 1858 -32132015.60604 +1876 1858 -14821146.93907 +1877 1858 -100707.8152143 +1878 1858 40566555.84207 +1879 1858 165260852.6832 +1880 1858 -597661.00714 +1881 1858 -6104636.616306 +1882 1858 -6816946.093491 +1883 1858 57814.32573971 +1884 1858 28689110.99387 +1885 1858 -23798451.81077 +1886 1858 71404.97200041 +1947 1858 7334490.207843 +1948 1858 -159803560.5503 +1949 1858 -15105006.04105 +1965 1858 -19582677.03363 +1966 1858 -76351700.56774 +1967 1858 -35079784.41579 +1968 1858 4476096.649078 +1969 1858 165324453.0163 +1970 1858 -1162457.000333 +1986 1858 -8033003.905469 +1987 1858 -9894458.669336 +1988 1858 -8796010.290028 +1989 1858 10129174.62529 +1990 1858 -7927094.714724 +1991 1858 7746460.193937 +1992 1858 -1508822.635335 +1993 1858 -40750200.27463 +1994 1858 33347770.76796 +1995 1858 7184742.092224 +1996 1858 -22851494.43284 +1997 1858 16684475.80062 +1859 1859 773869008.0752 +1875 1859 294514.104971 +1876 1859 -128485.5929738 +1877 1859 -622458.5944218 +1878 1859 -269615.8649938 +1879 1859 -625438.7849135 +1880 1859 194200855.2863 +1881 1859 3243.047475696 +1882 1859 57814.32573968 +1883 1859 125828358.2539 +1884 1859 -68620.4316531 +1885 1859 71404.97200043 +1886 1859 40924167.25486 +1947 1859 1076276.737474 +1948 1859 -15535652.09754 +1949 1859 -61294869.05612 +1965 1859 -11038901.70535 +1966 1859 -35024734.46458 +1967 1859 -45405160.15834 +1968 1859 -8637953.054657 +1969 1859 -1969136.388931 +1970 1859 -92387282.40012 +1986 1859 -10880711.7551 +1987 1859 -8796010.290028 +1988 1859 -16660073.13599 +1989 1859 -43078814.95968 +1990 1859 7746460.195486 +1991 1859 -82693280.69379 +1992 1859 5638626.62599 +1993 1859 33347770.76796 +1994 1859 -72707925.46305 +1995 1859 -10629355.22208 +1996 1859 16684475.80062 +1997 1859 -34862225.60797 +1860 1860 309814570.0165 +1861 1860 6.437301635742e-06 +1862 1860 462970.2969034 +1863 1860 42076777.68823 +1864 1860 7333333.332127 +1865 1860 -318285.203467 +1950 1860 -59565882.98117 +1951 1860 4.91738319397e-07 +1952 1860 43739118.52961 +1953 1860 -20057887.18154 +1954 1860 -9166666.669679 +1955 1860 11581481.02689 +1971 1860 27139753.66166 +1972 1860 8.344650268555e-07 +1973 1860 -8738562.979764 +1974 1860 -3553812.994569 +1975 1860 1833333.333932 +1976 1860 -2293147.690507 +1861 1861 265811394.6764 +1862 1861 -5555467.545855 +1863 1861 -7333333.332131 +1864 1861 -27589753.44616 +1865 1861 2749955.995158 +1950 1861 -5.811452865601e-07 +1951 1861 -19232220.47929 +1952 1861 -694433.4439163 +1953 1861 -9166666.669679 +1954 1861 -17307688.72007 +1955 1861 9079855.613715 +1971 1861 8.940696716309e-07 +1972 1861 16138959.82123 +1973 1861 -1388866.887151 +1974 1861 -1833333.333938 +1975 1861 -20970445.78675 +1976 1861 18229155.66291 +1862 1862 299795956.2502 +1863 1862 723381.4630278 +1864 1862 2805511.550704 +1865 1862 39276420.11598 +1950 1862 43704396.30741 +1951 1862 -694433.4439163 +1952 1862 -56581165.5979 +1953 1862 11581481.02689 +1954 1862 9079855.613715 +1955 1862 -20589184.71456 +1971 1862 8796437.017353 +1972 1862 -1388866.887151 +1973 1862 -59221381.24884 +1974 1862 2351018.977684 +1975 1862 18229155.66292 +1976 1862 -27708914.75766 +1863 1863 309814570.0165 +1864 1863 6.437301635742e-06 +1865 1863 462970.2969034 +1866 1863 42076777.68823 +1867 1863 7333333.332127 +1868 1863 -318285.203467 +1950 1863 -18569369.18862 +1951 1863 9166666.669678 +1952 1863 10279397.69313 +1953 1863 -59565882.98117 +1954 1863 4.91738319397e-07 +1955 1863 43739118.52961 +1956 1863 -20057887.18154 +1957 1863 -9166666.669679 +1958 1863 11581481.02689 +1971 1863 -564939.8890041 +1972 1863 -1833333.333934 +1973 1863 -2032731.023757 +1974 1863 27139753.66166 +1975 1863 8.344650268555e-07 +1976 1863 -8738562.979764 +1977 1863 -3553812.994569 +1978 1863 1833333.333932 +1979 1863 -2293147.690507 +1864 1864 265811394.6764 +1865 1864 -5555467.545855 +1866 1864 -7333333.332131 +1867 1864 -27589753.44616 +1868 1864 2749955.995158 +1950 1864 9166666.669678 +1951 1864 -15819170.72716 +1952 1864 -8385422.169798 +1953 1864 -5.811452865601e-07 +1954 1864 -19232220.47929 +1955 1864 -694433.4439163 +1956 1864 -9166666.669679 +1957 1864 -17307688.72007 +1958 1864 9079855.613715 +1971 1864 1833333.333937 +1972 1864 -17981572.68118 +1973 1864 -16840288.77576 +1974 1864 8.940696716309e-07 +1975 1864 16138959.82123 +1976 1864 -1388866.887151 +1977 1864 -1833333.333938 +1978 1864 -20970445.78675 +1979 1864 18229155.66291 +1865 1865 299795956.2502 +1866 1865 723381.4630278 +1867 1865 2805511.550704 +1868 1865 39276420.11598 +1950 1865 10279397.69313 +1951 1865 -8385422.169798 +1952 1865 -16619803.40013 +1953 1865 43704396.30741 +1954 1865 -694433.4439163 +1955 1865 -56581165.5979 +1956 1865 11581481.02689 +1957 1865 9079855.613715 +1958 1865 -20589184.71456 +1971 1865 2090602.31093 +1972 1865 -16840288.77577 +1973 1865 -19738586.47615 +1974 1865 8796437.017353 +1975 1865 -1388866.887151 +1976 1865 -59221381.24884 +1977 1865 2351018.977684 +1978 1865 18229155.66292 +1979 1865 -27708914.75766 +1866 1866 309814570.0165 +1867 1866 6.437301635742e-06 +1868 1866 462970.2969034 +1869 1866 42076777.68823 +1870 1866 7333333.332127 +1871 1866 -318285.203467 +1953 1866 -18569369.18862 +1954 1866 9166666.669678 +1955 1866 10279397.69313 +1956 1866 -59565882.98117 +1957 1866 4.91738319397e-07 +1958 1866 43739118.52961 +1959 1866 -20057887.18154 +1960 1866 -9166666.669679 +1961 1866 11581481.02689 +1974 1866 -564939.8890041 +1975 1866 -1833333.333934 +1976 1866 -2032731.023757 +1977 1866 27139753.66166 +1978 1866 8.344650268555e-07 +1979 1866 -8738562.979764 +1980 1866 -3553812.994569 +1981 1866 1833333.333932 +1982 1866 -2293147.690507 +1867 1867 265811394.6764 +1868 1867 -5555467.545855 +1869 1867 -7333333.332131 +1870 1867 -27589753.44616 +1871 1867 2749955.995158 +1953 1867 9166666.669678 +1954 1867 -15819170.72716 +1955 1867 -8385422.169798 +1956 1867 -5.811452865601e-07 +1957 1867 -19232220.47929 +1958 1867 -694433.4439163 +1959 1867 -9166666.669679 +1960 1867 -17307688.72007 +1961 1867 9079855.613715 +1974 1867 1833333.333937 +1975 1867 -17981572.68118 +1976 1867 -16840288.77576 +1977 1867 8.940696716309e-07 +1978 1867 16138959.82123 +1979 1867 -1388866.887151 +1980 1867 -1833333.333938 +1981 1867 -20970445.78675 +1982 1867 18229155.66291 +1868 1868 299795956.2502 +1869 1868 723381.4630278 +1870 1868 2805511.550704 +1871 1868 39276420.11598 +1953 1868 10279397.69313 +1954 1868 -8385422.169798 +1955 1868 -16619803.40013 +1956 1868 43704396.30741 +1957 1868 -694433.4439163 +1958 1868 -56581165.5979 +1959 1868 11581481.02689 +1960 1868 9079855.613715 +1961 1868 -20589184.71456 +1974 1868 2090602.31093 +1975 1868 -16840288.77577 +1976 1868 -19738586.47615 +1977 1868 8796437.017353 +1978 1868 -1388866.887151 +1979 1868 -59221381.24884 +1980 1868 2351018.977684 +1981 1868 18229155.66292 +1982 1868 -27708914.75766 +1869 1869 309814570.0165 +1870 1869 6.437301635742e-06 +1871 1869 462970.2969034 +1872 1869 42076777.68823 +1873 1869 7333333.332127 +1874 1869 -318285.203467 +1956 1869 -18569369.18862 +1957 1869 9166666.669678 +1958 1869 10279397.69313 +1959 1869 -59565882.98117 +1960 1869 4.91738319397e-07 +1961 1869 43739118.52961 +1962 1869 -20057887.18154 +1963 1869 -9166666.669679 +1964 1869 11581481.02689 +1977 1869 -564939.8890041 +1978 1869 -1833333.333934 +1979 1869 -2032731.023757 +1980 1869 27139753.66166 +1981 1869 8.344650268555e-07 +1982 1869 -8738562.979764 +1983 1869 -3553812.994569 +1984 1869 1833333.333932 +1985 1869 -2293147.690507 +1870 1870 265811394.6764 +1871 1870 -5555467.545855 +1872 1870 -7333333.332131 +1873 1870 -27589753.44616 +1874 1870 2749955.995158 +1956 1870 9166666.669678 +1957 1870 -15819170.72716 +1958 1870 -8385422.169798 +1959 1870 -5.811452865601e-07 +1960 1870 -19232220.47929 +1961 1870 -694433.4439163 +1962 1870 -9166666.669679 +1963 1870 -17307688.72007 +1964 1870 9079855.613715 +1977 1870 1833333.333937 +1978 1870 -17981572.68118 +1979 1870 -16840288.77576 +1980 1870 8.940696716309e-07 +1981 1870 16138959.82123 +1982 1870 -1388866.887151 +1983 1870 -1833333.333938 +1984 1870 -20970445.78675 +1985 1870 18229155.66291 +1871 1871 299795956.2502 +1872 1871 723381.4630278 +1873 1871 2805511.550704 +1874 1871 39276420.11598 +1956 1871 10279397.69313 +1957 1871 -8385422.169798 +1958 1871 -16619803.40013 +1959 1871 43704396.30741 +1960 1871 -694433.4439163 +1961 1871 -56581165.5979 +1962 1871 11581481.02689 +1963 1871 9079855.613715 +1964 1871 -20589184.71456 +1977 1871 2090602.31093 +1978 1871 -16840288.77577 +1979 1871 -19738586.47615 +1980 1871 8796437.017353 +1981 1871 -1388866.887151 +1982 1871 -59221381.24884 +1983 1871 2351018.977684 +1984 1871 18229155.66292 +1985 1871 -27708914.75766 +1872 1872 309814570.0165 +1873 1872 6.437301635742e-06 +1874 1872 462970.2969034 +1875 1872 42076777.68823 +1876 1872 7333333.332127 +1877 1872 -318285.203467 +1959 1872 -18569369.18862 +1960 1872 9166666.669678 +1961 1872 10279397.69313 +1962 1872 -59565882.98117 +1963 1872 4.91738319397e-07 +1964 1872 43739118.52961 +1965 1872 -20057887.18154 +1966 1872 -9166666.669679 +1967 1872 11581481.02689 +1980 1872 -564939.8890041 +1981 1872 -1833333.333934 +1982 1872 -2032731.023757 +1983 1872 27139753.66166 +1984 1872 8.344650268555e-07 +1985 1872 -8738562.979764 +1986 1872 -3553812.994569 +1987 1872 1833333.333932 +1988 1872 -2293147.690507 +1873 1873 265811394.6764 +1874 1873 -5555467.545855 +1875 1873 -7333333.332131 +1876 1873 -27589753.44616 +1877 1873 2749955.995158 +1959 1873 9166666.669678 +1960 1873 -15819170.72716 +1961 1873 -8385422.169798 +1962 1873 -5.811452865601e-07 +1963 1873 -19232220.47929 +1964 1873 -694433.4439163 +1965 1873 -9166666.669679 +1966 1873 -17307688.72007 +1967 1873 9079855.613715 +1980 1873 1833333.333937 +1981 1873 -17981572.68118 +1982 1873 -16840288.77576 +1983 1873 8.940696716309e-07 +1984 1873 16138959.82123 +1985 1873 -1388866.887151 +1986 1873 -1833333.333938 +1987 1873 -20970445.78675 +1988 1873 18229155.66291 +1874 1874 299795956.2502 +1875 1874 723381.4630278 +1876 1874 2805511.550704 +1877 1874 39276420.11598 +1959 1874 10279397.69313 +1960 1874 -8385422.169798 +1961 1874 -16619803.40013 +1962 1874 43704396.30741 +1963 1874 -694433.4439163 +1964 1874 -56581165.5979 +1965 1874 11581481.02689 +1966 1874 9079855.613715 +1967 1874 -20589184.71456 +1980 1874 2090602.31093 +1981 1874 -16840288.77577 +1982 1874 -19738586.47615 +1983 1874 8796437.017353 +1984 1874 -1388866.887151 +1985 1874 -59221381.24884 +1986 1874 2351018.977684 +1987 1874 18229155.66292 +1988 1874 -27708914.75766 +1875 1875 309250160.3896 +1876 1875 4535517.963994 +1877 1875 2453066.565954 +1878 1875 -8612767.502989 +1879 1875 -26152871.16708 +1880 1875 379949.2240047 +1962 1875 -18569369.18862 +1963 1875 9166666.669678 +1964 1875 10279397.69313 +1965 1875 -43745996.76765 +1966 1875 6104008.873162 +1967 1875 33740166.13061 +1968 1875 -19561074.78605 +1969 1875 -8033003.905467 +1970 1875 11036649.36321 +1983 1875 -564939.8890041 +1984 1875 -1833333.333934 +1985 1875 -2032731.023757 +1986 1875 26998047.5617 +1987 1875 1133879.491557 +1988 1875 -8240761.134482 +1989 1875 -17935124.94805 +1990 1875 -6538217.79499 +1991 1875 7751167.860229 +1876 1876 292124118.8748 +1877 1876 -3586804.318186 +1878 1876 -40819537.83134 +1879 1876 -71029376.04212 +1880 1876 603908.8952657 +1962 1876 9166666.669678 +1963 1876 -15819170.72716 +1964 1876 -8385422.169798 +1965 1876 6104008.873161 +1966 1876 -18661255.71884 +1967 1876 -8204777.132884 +1968 1876 -8033003.905467 +1969 1876 -10093718.98084 +1970 1876 8738711.937952 +1983 1876 1833333.333937 +1984 1876 -17981572.68118 +1985 1876 -16840288.77576 +1986 1876 1133879.491557 +1987 1876 22716537.18088 +1988 1876 -896701.0799925 +1989 1876 -10204884.46286 +1990 1876 -33539277.09052 +1991 1876 25588477.22048 +1877 1877 306596341.2044 +1878 1877 553560.3350853 +1879 1877 631686.6730388 +1880 1877 21856446.47305 +1962 1877 10279397.69313 +1963 1877 -8385422.169798 +1964 1877 -16619803.40013 +1965 1877 33913777.24376 +1966 1877 -8204777.131321 +1967 1877 -47982126.11052 +1968 1877 11036649.36321 +1969 1877 8738711.937952 +1970 1877 -17191433.96669 +1983 1877 2090602.31093 +1984 1877 -16840288.77577 +1985 1877 -19738586.47615 +1986 1877 9293683.307081 +1987 1877 -896701.0799924 +1988 1877 -57522894.85793 +1989 1877 12186723.41529 +1990 1877 25588477.21893 +1991 1877 -36621043.23569 +1878 1878 356577161.9201 +1879 1878 48285232.25239 +1880 1878 -61822.7503829 +1881 1878 -69422617.35248 +1882 1878 -44644222.32742 +1883 1878 104990.6793973 +1884 1878 13197101.10136 +1885 1878 -11138919.37081 +1886 1878 34775.22564381 +1965 1878 -18648271.66148 +1966 1878 1937722.859731 +1967 1878 1037653.094121 +1968 1878 -39699971.95958 +1969 1878 10129174.62529 +1970 1878 42926740.58175 +1986 1878 -17192674.13802 +1987 1878 -10204884.46286 +1988 1878 -11944665.46985 +1989 1878 -4268705.881667 +1990 1878 12038787.22767 +1991 1878 -8660992.155141 +1992 1878 -34216980.43145 +1993 1878 -11148591.24713 +1994 1878 20338700.34364 +1995 1878 -25180862.7833 +1996 1878 -2752209.002696 +1997 1878 7586452.49441 +1879 1879 444468254.4959 +1880 1879 -1420293.818771 +1881 1879 -44644222.32742 +1882 1879 -49521951.80655 +1883 1879 71404.97200023 +1884 1879 -25805586.03507 +1885 1879 -58297361.08229 +1886 1879 227805.5621212 +1965 1879 1937722.859731 +1966 1879 -44033949.54609 +1967 1879 -16387957.82287 +1968 1879 10129174.62529 +1969 1879 -7772556.362414 +1970 1879 -8052150.914586 +1986 1879 -6538217.794992 +1987 1879 -32796826.2805 +1988 1879 -25279578.32671 +1989 1879 12038787.22767 +1990 1879 17699553.83801 +1991 1879 -354921.1380877 +1992 1879 -11148591.24713 +1993 1879 -29253723.60161 +1994 1879 16684475.80062 +1995 1879 -6418875.670566 +1996 1879 -43049964.90291 +1997 1879 33390132.40162 +1880 1880 482183166.7639 +1881 1880 104990.6793971 +1882 1880 71404.97200023 +1883 1880 15200667.25909 +1884 1880 104219.6700739 +1885 1880 227805.5621212 +1886 1880 67947810.70532 +1965 1880 1037653.094121 +1966 1880 -16387957.82287 +1967 1880 -25517489.86743 +1968 1880 42857296.13735 +1969 1880 -8052150.913023 +1970 1880 -82281178.42096 +1986 1880 -7613276.581476 +1987 1880 -25279578.32828 +1988 1880 -34641174.40895 +1989 1880 8456785.619827 +1990 1880 -354921.1380879 +1991 1880 -128380449.7493 +1992 1880 20338700.34364 +1993 1880 16684475.80062 +1994 1880 -41264454.77674 +1995 1880 11848674.71994 +1996 1880 33390132.40162 +1997 1880 -59135164.39133 +1881 1881 235305206.8043 +1882 1881 50104636.60908 +1883 1881 -61113.41781354 +1884 1881 -6200109.874661 +1885 1881 644222.3346426 +1886 1881 -47120.30905524 +1968 1881 -23019750.78198 +1969 1881 -1508822.635337 +1970 1881 -5637067.814509 +1989 1881 -34122283.46173 +1990 1881 -11148591.24713 +1991 1881 -20286299.6697 +1992 1881 -19237067.37006 +1993 1881 12508822.63895 +1994 1881 8109753.000327 +1995 1881 -35316352.92472 +1996 1881 148591.2435152 +1997 1881 -30936385.51612 +1882 1882 216455582.4122 +1883 1882 -57814.32572985 +1884 1882 15310888.9989 +1885 1882 63274224.56474 +1886 1882 -71404.97199523 +1968 1882 -5175489.303208 +1969 1882 -40655503.30493 +1970 1882 -33318895.88775 +1989 1882 -11148591.24713 +1990 1882 -29159026.6319 +1991 1882 -16648857.54366 +1992 1882 12508822.63895 +1993 1882 -23945064.85445 +1994 1882 6652229.225463 +1995 1882 3815257.911386 +1996 1882 -17935859.74721 +1997 1882 3315524.205949 +1883 1883 343833005.2774 +1884 1883 -47120.30905163 +1885 1883 -71404.97199523 +1886 1883 110847060.0814 +1968 1883 -13762067.81526 +1969 1883 -33318895.88775 +1970 1883 -72455400.21049 +1989 1883 -20286299.6697 +1990 1883 -16648857.54366 +1991 1883 -41011929.52416 +1992 1883 -8140246.997005 +1993 1883 -6681104.10568 +1994 1883 -122156531.5552 +1995 1883 -30936385.51804 +1996 1883 -3351142.462907 +1997 1883 -62230684.14613 +1884 1884 174702353.4237 +1885 1884 -18194413.95771 +1886 1884 -127367.818301 +1968 1884 -17049672.34501 +1969 1884 7184742.092225 +1970 1884 10594950.34044 +1989 1884 -24896771.87432 +1990 1884 -6418875.670569 +1991 1884 -11796880.83574 +1992 1884 -35316352.92472 +1993 1884 3815257.911389 +1994 1884 30912920.02928 +1995 1884 -13173566.49931 +1996 1884 -4581124.333045 +1997 1884 -4276545.089515 +1885 1885 199694315.615 +1886 1885 -227805.5621098 +1968 1885 7184742.092225 +1969 1885 -22756797.46313 +1970 1885 -16648857.54366 +1989 1885 -2752209.002698 +1990 1885 -42765873.99394 +1991 1885 -33276534.25409 +1992 1885 148591.2435185 +1993 1885 -17935859.74721 +1994 1885 3315524.205949 +1995 1885 -4581124.333044 +1996 1885 -6977832.439091 +1997 1885 6609867.591799 +1886 1886 262608234.7228 +1968 1886 10594950.34044 +1969 1886 -16648857.54366 +1970 1886 -34609700.35539 +1989 1886 -7569380.832428 +1990 1886 -33276534.25409 +1991 1886 -58377588.63405 +1992 1886 30912920.02737 +1993 1886 -3351142.462907 +1994 1886 -62230684.14613 +1995 1886 4213177.131314 +1996 1886 -6723465.739343 +1997 1886 -85945663.24674 +1887 1887 389420334.4506 +1888 1887 36666666.66065 +1889 1887 3703834.305166 +1890 1887 -202591396.4212 +1891 1887 -36666966.01295 +1892 1887 -2870483.022002 +1893 1887 12702400.63006 +1894 1887 29333632.68082 +1895 1887 -1944468.073742 +1998 1887 31947394.33292 +1999 1887 9166666.669681 +2000 1887 9728225.899101 +2001 1887 -74358253.63036 +2002 1887 -9166739.758898 +2003 1887 -45562288.72778 +2004 1887 -8166156.136015 +2005 1887 7333406.424962 +2006 1887 -9496761.446847 +1888 1888 334416074.7194 +1889 1888 -6111048.190243 +1890 1888 -36667115.68909 +1891 1888 -30255041.75127 +1892 1888 -3888889.819054 +1893 1888 44000449.02122 +1894 1888 12702400.63006 +1895 1888 2666689.342343 +1998 1888 9166666.66968 +1999 1888 18196342.83202 +2000 1888 5513941.008134 +2001 1888 -9166776.303507 +2002 1888 -31274176.50627 +2003 1888 -9941080.210835 +2004 1888 11000109.63744 +2005 1888 -8166156.136015 +2006 1888 11395946.69513 +1889 1889 380479993.5812 +1890 1889 -2453807.380415 +1891 1889 -3055548.927153 +1892 1889 398412.8916247 +1893 1889 -2916702.110613 +1894 1889 1777792.894895 +1895 1889 33873068.34682 +1998 1889 -8223530.275229 +1999 1889 -8847241.586827 +2000 1889 -79300461.72417 +2001 1889 -45527563.96779 +2002 1889 -9746597.980308 +2003 1889 -63128188.69225 +2004 1889 -14245142.17027 +2005 1889 7597297.796754 +2006 1889 -21776416.36271 +1890 1890 674759689.9124 +1891 1890 36667415.0414 +1892 1890 3125092.975185 +1893 1890 20137287.77529 +1894 1890 -36666966.01295 +1895 1890 2754655.071165 +1896 1890 -137627039.3558 +1897 1890 -2.235174179077e-07 +1898 1890 -671303.5447711 +1899 1890 -52107624.53367 +1900 1890 36666666.66065 +1901 1890 -2754631.441411 +1998 1890 -72726245.22972 +1999 1890 -9166776.303506 +2000 1890 44231216.90386 +2001 1890 70575234.21716 +2002 1890 9166849.392726 +2003 1890 781227.3439141 +2004 1890 -20203256.3538 +2005 1890 -9166739.758899 +2006 1890 11899863.74724 +2007 1890 -60775629.25067 +2008 1890 -1.214444637299e-06 +2009 1890 -45012270.30212 +2010 1890 -20383999.6175 +2011 1890 9166666.669679 +2012 1890 -11899768.97017 +1891 1891 575752291.8369 +1892 1891 -8610912.053949 +1893 1891 -36667115.6891 +1894 1891 -108195591.755 +1895 1891 4777685.365654 +1896 1891 4.470348358154e-07 +1897 1891 23707595.23204 +1898 1891 -2777734.286976 +1899 1891 36666666.66065 +1900 1891 -41106839.94217 +1901 1891 1555533.810155 +1998 1891 -9166739.758897 +1999 1891 -29642168.10562 +2000 1891 8204934.122165 +2001 1891 9166849.392726 +2002 1891 45823407.30156 +2003 1891 -2152765.098743 +2004 1891 -9166776.303508 +2005 1891 -52286475.83204 +2006 1891 37069600.58987 +2007 1891 -1.445412635803e-06 +2008 1891 -20441974.38895 +2009 1891 -694433.6992576 +2010 1891 9166666.669678 +2011 1891 -17633805.76247 +2012 1891 9357633.519253 +1892 1892 615008779.2968 +1893 1892 2685222.441543 +1894 1892 5222139.640517 +1895 1892 39437488.39575 +1896 1892 -254636.8781728 +1897 1892 -2777734.286976 +1898 1892 42039227.65673 +1899 1892 -2685186.996909 +1900 1892 1499978.254554 +1901 1892 -7359624.812662 +1998 1892 44196492.14387 +1999 1892 8010523.495484 +2000 1892 -58776166.2905 +2001 1892 781316.8545274 +2002 1892 -2152693.49136 +2003 1892 -107886912.3736 +2004 1892 11899911.13577 +2005 1892 37236269.31883 +2006 1892 -57440830.58835 +2007 1892 -44977548.07992 +2008 1892 -694433.6992576 +2009 1892 -59807200.44138 +2010 1892 -11899768.97017 +2011 1892 9357633.519253 +2012 1892 -21458826.37861 +1893 1893 389420334.4506 +1894 1893 36666666.66065 +1895 1893 3703834.305166 +1896 1893 -52083950.29126 +1897 1893 -36666666.66065 +1898 1893 2453701.89106 +1899 1893 -202591396.4212 +1900 1893 -36666966.01295 +1901 1893 -2870483.022002 +1902 1893 12702400.63006 +1903 1893 29333632.68082 +1904 1893 -1944468.073742 +1998 1893 -5106206.927443 +1999 1893 11000109.63744 +2000 1893 12682625.90274 +2001 1893 -15511422.68773 +2002 1893 -9166776.303506 +2003 1893 -10539940.2691 +2004 1893 31947394.33292 +2005 1893 9166666.669681 +2006 1893 9728225.899101 +2007 1893 -18848133.13973 +2008 1893 -9166666.66968 +2009 1893 -10597685.63642 +2010 1893 -74358253.63036 +2011 1893 -9166739.758898 +2012 1893 -45562288.72778 +2013 1893 -8166156.136015 +2014 1893 7333406.424962 +2015 1893 -9496761.446847 +1894 1894 334416074.7194 +1895 1894 -6111048.190243 +1896 1894 -36666666.66065 +1897 1894 -41083165.69975 +1898 1894 1222200.476822 +1899 1894 -36667115.68909 +1900 1894 -30255041.75127 +1901 1894 -3888889.819054 +1902 1894 44000449.02122 +1903 1894 12702400.63006 +1904 1894 2666689.342343 +1998 1894 7333406.424962 +1999 1894 -5106206.927443 +2000 1894 -6763956.526763 +2001 1894 -9166739.758897 +2002 1894 -47594642.16596 +2003 1894 -34569643.89832 +2004 1894 9166666.66968 +2005 1894 18196342.83202 +2006 1894 5513941.008134 +2007 1894 -9166666.669679 +2008 1894 -16097939.2847 +2009 1894 -8663199.819997 +2010 1894 -9166776.303507 +2011 1894 -31274176.50627 +2012 1894 -9941080.210835 +2013 1894 11000109.63744 +2014 1894 -8166156.136015 +2015 1894 11395946.69513 +1895 1895 380479993.5812 +1896 1895 2523146.335561 +1897 1895 1277756.032423 +1898 1895 -7296493.499545 +1899 1895 -2453807.380415 +1900 1895 -3055548.927153 +1901 1895 398412.8916247 +1902 1895 -2916702.110613 +1903 1895 1777792.894895 +1904 1895 33873068.34682 +1998 1895 8455083.935158 +1999 1895 -10145934.79014 +2000 1895 -13616551.80652 +2001 1895 -10539898.30291 +2002 1895 -34736312.74845 +2003 1895 -44929274.14549 +2004 1895 -8223530.275229 +2005 1895 -8847241.586827 +2006 1895 -79300461.72417 +2007 1895 -10597685.63642 +2008 1895 -8663199.819997 +2009 1895 -17363182.43788 +2010 1895 -45527563.96779 +2011 1895 -9746597.980308 +2012 1895 -63128188.69225 +2013 1895 -14245142.17027 +2014 1895 7597297.796754 +2015 1895 -21776416.36271 +1896 1896 622861433.7406 +1897 1896 1.120567321777e-05 +1898 1896 925940.4229136 +1899 1896 84958459.17911 +1900 1896 -5.066394805908e-06 +1901 1896 231485.1058435 +1905 1896 -137627039.3558 +1906 1896 -2.235174179077e-07 +1907 1896 -671303.5447711 +1908 1896 -52107624.53367 +1909 1896 36666666.66065 +1910 1896 -2754631.441411 +2001 1896 -60367636.82651 +2002 1896 1.877546310425e-06 +2003 1896 44780785.23866 +2004 1896 -20276082.95081 +2005 1896 -9166666.66968 +2006 1896 11841897.70428 +2007 1896 51054233.83102 +2008 1896 1.788139343262e-06 +2009 1896 231485.0634618 +2010 1896 -7985170.87927 +2011 1896 -2.771615982056e-06 +2012 1896 57871.2658952 +2016 1896 -60775629.25067 +2017 1896 -1.214444637299e-06 +2018 1896 -45012270.30212 +2019 1896 -20383999.6175 +2020 1896 9166666.669679 +2021 1896 -11899768.97017 +1897 1897 534855157.0519 +1898 1897 -11110937.14243 +1899 1897 -3.457069396973e-06 +1900 1897 -54374606.24745 +1901 1897 5722135.237857 +1905 1897 4.470348358154e-07 +1906 1897 23707595.23204 +1907 1897 -2777734.286976 +1908 1897 36666666.66065 +1909 1897 -41106839.94217 +1910 1897 1555533.810155 +2001 1897 1.169741153717e-06 +2002 1897 -20033981.96478 +2003 1897 -694433.6992575 +2004 1897 -9166666.66968 +2005 1897 -17525889.09577 +2006 1897 9288189.074786 +2007 1897 1.966953277588e-06 +2008 1897 29052683.00161 +2009 1897 -2777734.795662 +2010 1897 -2.190470695496e-06 +2011 1897 -42818438.03636 +2012 1897 37305534.05859 +2016 1897 -1.445412635803e-06 +2017 1897 -20441974.38895 +2018 1897 -694433.6992576 +2019 1897 9166666.669678 +2020 1897 -17633805.76247 +2021 1897 9357633.519253 +1898 1898 608211498.9432 +1899 1898 231485.105844 +1900 1898 5388801.904579 +1901 1898 80699306.16691 +1905 1898 -254636.8781728 +1906 1898 -2777734.286976 +1907 1898 42039227.65673 +1908 1898 -2685186.996909 +1909 1898 1499978.254554 +1910 1898 -7359624.812662 +2001 1898 44746063.01646 +2002 1898 -694433.6992574 +2003 1898 -58719220.64359 +2004 1898 11841897.70428 +2005 1898 9288189.074786 +2006 1898 -21171048.60074 +2007 1898 231485.0634617 +2008 1898 -2777734.795662 +2009 1898 -127043423.7988 +2010 1898 57871.26589543 +2011 1898 37277756.28083 +2012 1898 -57757921.43384 +2016 1898 -44977548.07992 +2017 1898 -694433.6992576 +2018 1898 -59807200.44138 +2019 1898 -11899768.97017 +2020 1898 9357633.519253 +2021 1898 -21458826.37861 +1899 1899 674759689.9124 +1900 1899 36667415.0414 +1901 1899 3125092.975185 +1902 1899 20137287.77529 +1903 1899 -36666966.01295 +1904 1899 2754655.071165 +1905 1899 -52083950.29126 +1906 1899 -36666666.66065 +1907 1899 2453701.89106 +1908 1899 -137627039.3558 +1909 1899 -2.235174179077e-07 +1910 1899 -671303.5447711 +1911 1899 -52107624.53367 +1912 1899 36666666.66065 +1913 1899 -2754631.441411 +2001 1899 -18752053.59425 +2002 1899 9166666.66968 +2003 1899 10539814.37052 +2004 1899 -72726245.22972 +2005 1899 -9166776.303506 +2006 1899 44231216.90386 +2007 1899 -1865379.213624 +2008 1899 8.79168510437e-07 +2009 1899 57871.26589221 +2010 1899 70575234.21716 +2011 1899 9166849.392726 +2012 1899 781227.3439141 +2013 1899 -20203256.3538 +2014 1899 -9166739.758899 +2015 1899 11899863.74724 +2016 1899 -18848133.13973 +2017 1899 -9166666.66968 +2018 1899 -10597685.63642 +2019 1899 -60775629.25067 +2020 1899 -1.214444637299e-06 +2021 1899 -45012270.30212 +2022 1899 -20383999.6175 +2023 1899 9166666.669679 +2024 1899 -11899768.97017 +1900 1900 575752291.8369 +1901 1900 -8610912.053949 +1902 1900 -36667115.6891 +1903 1900 -108195591.755 +1904 1900 4777685.365654 +1905 1900 -36666666.66065 +1906 1900 -41083165.69975 +1907 1900 1222200.476822 +1908 1900 4.470348358154e-07 +1909 1900 23707595.23204 +1910 1900 -2777734.286976 +1911 1900 36666666.66065 +1912 1900 -41106839.94217 +1913 1900 1555533.810155 +2001 1900 9166666.66968 +2002 1900 -16001859.73922 +2003 1900 -8593755.37553 +2004 1900 -9166739.758897 +2005 1900 -29642168.10562 +2006 1900 8204934.122165 +2007 1900 1.229345798492e-06 +2008 1900 -36698646.37071 +2009 1900 -34527799.26293 +2010 1900 9166849.392726 +2011 1900 45823407.30156 +2012 1900 -2152765.098743 +2013 1900 -9166776.303508 +2014 1900 -52286475.83204 +2015 1900 37069600.58987 +2016 1900 -9166666.669679 +2017 1900 -16097939.2847 +2018 1900 -8663199.819997 +2019 1900 -1.445412635803e-06 +2020 1900 -20441974.38895 +2021 1900 -694433.6992576 +2022 1900 9166666.669678 +2023 1900 -17633805.76247 +2024 1900 9357633.519253 +1901 1901 615008779.2968 +1902 1901 2685222.441543 +1903 1901 5222139.640517 +1904 1901 39437488.39575 +1905 1901 2523146.335561 +1906 1901 1277756.032423 +1907 1901 -7296493.499545 +1908 1901 -254636.8781728 +1909 1901 -2777734.286976 +1910 1901 42039227.65673 +1911 1901 -2685186.996909 +1912 1901 1499978.254554 +1913 1901 -7359624.812662 +2001 1901 10539814.37052 +2002 1901 -8593755.37553 +2003 1901 -17106970.31658 +2004 1901 44196492.14387 +2005 1901 8010523.495484 +2006 1901 -58776166.2905 +2007 1901 57871.26589252 +2008 1901 -34500021.48517 +2009 1901 -41438476.99211 +2010 1901 781316.8545274 +2011 1901 -2152693.49136 +2012 1901 -107886912.3736 +2013 1901 11899911.13577 +2014 1901 37236269.31883 +2015 1901 -57440830.58835 +2016 1901 -10597685.63642 +2017 1901 -8663199.819997 +2018 1901 -17363182.43788 +2019 1901 -44977548.07992 +2020 1901 -694433.6992576 +2021 1901 -59807200.44138 +2022 1901 -11899768.97017 +2023 1901 9357633.519253 +2024 1901 -21458826.37861 +1902 1902 389420334.4506 +1903 1902 36666666.66065 +1904 1902 3703834.305166 +1908 1902 -52083950.29126 +1909 1902 -36666666.66065 +1910 1902 2453701.89106 +1911 1902 -202591396.4212 +1912 1902 -36666966.01295 +1913 1902 -2870483.022002 +1914 1902 12702400.63006 +1915 1902 29333632.68082 +1916 1902 -1944468.073742 +2004 1902 -5106206.927443 +2005 1902 11000109.63744 +2006 1902 12682625.90274 +2010 1902 -15511422.68773 +2011 1902 -9166776.303506 +2012 1902 -10539940.2691 +2013 1902 31947394.33292 +2014 1902 9166666.669681 +2015 1902 9728225.899101 +2019 1902 -18848133.13973 +2020 1902 -9166666.66968 +2021 1902 -10597685.63642 +2022 1902 -74358253.63036 +2023 1902 -9166739.758898 +2024 1902 -45562288.72778 +2025 1902 -8166156.136015 +2026 1902 7333406.424962 +2027 1902 -9496761.446847 +1903 1903 334416074.7194 +1904 1903 -6111048.190243 +1908 1903 -36666666.66065 +1909 1903 -41083165.69975 +1910 1903 1222200.476822 +1911 1903 -36667115.68909 +1912 1903 -30255041.75127 +1913 1903 -3888889.819054 +1914 1903 44000449.02122 +1915 1903 12702400.63006 +1916 1903 2666689.342343 +2004 1903 7333406.424962 +2005 1903 -5106206.927443 +2006 1903 -6763956.526763 +2010 1903 -9166739.758897 +2011 1903 -47594642.16596 +2012 1903 -34569643.89832 +2013 1903 9166666.66968 +2014 1903 18196342.83202 +2015 1903 5513941.008134 +2019 1903 -9166666.669679 +2020 1903 -16097939.2847 +2021 1903 -8663199.819997 +2022 1903 -9166776.303507 +2023 1903 -31274176.50627 +2024 1903 -9941080.210835 +2025 1903 11000109.63744 +2026 1903 -8166156.136015 +2027 1903 11395946.69513 +1904 1904 380479993.5812 +1908 1904 2523146.335561 +1909 1904 1277756.032423 +1910 1904 -7296493.499545 +1911 1904 -2453807.380415 +1912 1904 -3055548.927153 +1913 1904 398412.8916247 +1914 1904 -2916702.110613 +1915 1904 1777792.894895 +1916 1904 33873068.34682 +2004 1904 8455083.935158 +2005 1904 -10145934.79014 +2006 1904 -13616551.80652 +2010 1904 -10539898.30291 +2011 1904 -34736312.74845 +2012 1904 -44929274.14549 +2013 1904 -8223530.275229 +2014 1904 -8847241.586827 +2015 1904 -79300461.72417 +2019 1904 -10597685.63642 +2020 1904 -8663199.819997 +2021 1904 -17363182.43788 +2022 1904 -45527563.96779 +2023 1904 -9746597.980308 +2024 1904 -63128188.69225 +2025 1904 -14245142.17027 +2026 1904 7597297.796754 +2027 1904 -21776416.36271 +1905 1905 622861433.7406 +1906 1905 1.120567321777e-05 +1907 1905 925940.4229136 +1908 1905 84958459.17911 +1909 1905 -5.066394805908e-06 +1910 1905 231485.1058435 +1917 1905 -137627039.3558 +1918 1905 -2.235174179077e-07 +1919 1905 -671303.5447711 +1920 1905 -52107624.53367 +1921 1905 36666666.66065 +1922 1905 -2754631.441411 +2007 1905 -60367636.82651 +2008 1905 1.877546310425e-06 +2009 1905 44780785.23866 +2010 1905 -20276082.95081 +2011 1905 -9166666.66968 +2012 1905 11841897.70428 +2016 1905 51054233.83102 +2017 1905 1.788139343262e-06 +2018 1905 231485.0634618 +2019 1905 -7985170.87927 +2020 1905 -2.771615982056e-06 +2021 1905 57871.2658952 +2028 1905 -60775629.25067 +2029 1905 -1.214444637299e-06 +2030 1905 -45012270.30212 +2031 1905 -20383999.6175 +2032 1905 9166666.669679 +2033 1905 -11899768.97017 +1906 1906 534855157.0519 +1907 1906 -11110937.14243 +1908 1906 -3.457069396973e-06 +1909 1906 -54374606.24745 +1910 1906 5722135.237857 +1917 1906 4.470348358154e-07 +1918 1906 23707595.23204 +1919 1906 -2777734.286976 +1920 1906 36666666.66065 +1921 1906 -41106839.94217 +1922 1906 1555533.810155 +2007 1906 1.169741153717e-06 +2008 1906 -20033981.96478 +2009 1906 -694433.6992575 +2010 1906 -9166666.66968 +2011 1906 -17525889.09577 +2012 1906 9288189.074786 +2016 1906 1.966953277588e-06 +2017 1906 29052683.00161 +2018 1906 -2777734.795662 +2019 1906 -2.190470695496e-06 +2020 1906 -42818438.03636 +2021 1906 37305534.05859 +2028 1906 -1.445412635803e-06 +2029 1906 -20441974.38895 +2030 1906 -694433.6992576 +2031 1906 9166666.669678 +2032 1906 -17633805.76247 +2033 1906 9357633.519253 +1907 1907 608211498.9432 +1908 1907 231485.105844 +1909 1907 5388801.904579 +1910 1907 80699306.16691 +1917 1907 -254636.8781728 +1918 1907 -2777734.286976 +1919 1907 42039227.65673 +1920 1907 -2685186.996909 +1921 1907 1499978.254554 +1922 1907 -7359624.812662 +2007 1907 44746063.01646 +2008 1907 -694433.6992574 +2009 1907 -58719220.64359 +2010 1907 11841897.70428 +2011 1907 9288189.074786 +2012 1907 -21171048.60074 +2016 1907 231485.0634617 +2017 1907 -2777734.795662 +2018 1907 -127043423.7988 +2019 1907 57871.26589543 +2020 1907 37277756.28083 +2021 1907 -57757921.43384 +2028 1907 -44977548.07992 +2029 1907 -694433.6992576 +2030 1907 -59807200.44138 +2031 1907 -11899768.97017 +2032 1907 9357633.519253 +2033 1907 -21458826.37861 +1908 1908 622861433.7406 +1909 1908 1.120567321777e-05 +1910 1908 925940.4229136 +1911 1908 84958459.17911 +1912 1908 -5.066394805908e-06 +1913 1908 231485.1058435 +1917 1908 -52083950.29126 +1918 1908 -36666666.66065 +1919 1908 2453701.89106 +1920 1908 -137627039.3558 +1921 1908 -2.235174179077e-07 +1922 1908 -671303.5447711 +1923 1908 -52107624.53367 +1924 1908 36666666.66065 +1925 1908 -2754631.441411 +2007 1908 -18752053.59425 +2008 1908 9166666.66968 +2009 1908 10539814.37052 +2010 1908 -60367636.82651 +2011 1908 1.877546310425e-06 +2012 1908 44780785.23866 +2013 1908 -20276082.95081 +2014 1908 -9166666.66968 +2015 1908 11841897.70428 +2016 1908 -1865379.213624 +2017 1908 8.79168510437e-07 +2018 1908 57871.26589221 +2019 1908 51054233.83102 +2020 1908 1.788139343262e-06 +2021 1908 231485.0634618 +2022 1908 -7985170.87927 +2023 1908 -2.771615982056e-06 +2024 1908 57871.2658952 +2028 1908 -18848133.13973 +2029 1908 -9166666.66968 +2030 1908 -10597685.63642 +2031 1908 -60775629.25067 +2032 1908 -1.214444637299e-06 +2033 1908 -45012270.30212 +2034 1908 -20383999.6175 +2035 1908 9166666.669679 +2036 1908 -11899768.97017 +1909 1909 534855157.0519 +1910 1909 -11110937.14243 +1911 1909 -3.457069396973e-06 +1912 1909 -54374606.24745 +1913 1909 5722135.237857 +1917 1909 -36666666.66065 +1918 1909 -41083165.69975 +1919 1909 1222200.476822 +1920 1909 4.470348358154e-07 +1921 1909 23707595.23204 +1922 1909 -2777734.286976 +1923 1909 36666666.66065 +1924 1909 -41106839.94217 +1925 1909 1555533.810155 +2007 1909 9166666.66968 +2008 1909 -16001859.73922 +2009 1909 -8593755.37553 +2010 1909 1.169741153717e-06 +2011 1909 -20033981.96478 +2012 1909 -694433.6992575 +2013 1909 -9166666.66968 +2014 1909 -17525889.09577 +2015 1909 9288189.074786 +2016 1909 1.229345798492e-06 +2017 1909 -36698646.37071 +2018 1909 -34527799.26293 +2019 1909 1.966953277588e-06 +2020 1909 29052683.00161 +2021 1909 -2777734.795662 +2022 1909 -2.190470695496e-06 +2023 1909 -42818438.03636 +2024 1909 37305534.05859 +2028 1909 -9166666.669679 +2029 1909 -16097939.2847 +2030 1909 -8663199.819997 +2031 1909 -1.445412635803e-06 +2032 1909 -20441974.38895 +2033 1909 -694433.6992576 +2034 1909 9166666.669678 +2035 1909 -17633805.76247 +2036 1909 9357633.519253 +1910 1910 608211498.9432 +1911 1910 231485.105844 +1912 1910 5388801.904579 +1913 1910 80699306.16691 +1917 1910 2523146.335561 +1918 1910 1277756.032423 +1919 1910 -7296493.499545 +1920 1910 -254636.8781728 +1921 1910 -2777734.286976 +1922 1910 42039227.65673 +1923 1910 -2685186.996909 +1924 1910 1499978.254554 +1925 1910 -7359624.812662 +2007 1910 10539814.37052 +2008 1910 -8593755.37553 +2009 1910 -17106970.31658 +2010 1910 44746063.01646 +2011 1910 -694433.6992574 +2012 1910 -58719220.64359 +2013 1910 11841897.70428 +2014 1910 9288189.074786 +2015 1910 -21171048.60074 +2016 1910 57871.26589252 +2017 1910 -34500021.48517 +2018 1910 -41438476.99211 +2019 1910 231485.0634617 +2020 1910 -2777734.795662 +2021 1910 -127043423.7988 +2022 1910 57871.26589543 +2023 1910 37277756.28083 +2024 1910 -57757921.43384 +2028 1910 -10597685.63642 +2029 1910 -8663199.819997 +2030 1910 -17363182.43788 +2031 1910 -44977548.07992 +2032 1910 -694433.6992576 +2033 1910 -59807200.44138 +2034 1910 -11899768.97017 +2035 1910 9357633.519253 +2036 1910 -21458826.37861 +1911 1911 674759689.9124 +1912 1911 36667415.0414 +1913 1911 3125092.975185 +1914 1911 20137287.77529 +1915 1911 -36666966.01295 +1916 1911 2754655.071165 +1920 1911 -52083950.29126 +1921 1911 -36666666.66065 +1922 1911 2453701.89106 +1923 1911 -137627039.3558 +1924 1911 -2.235174179077e-07 +1925 1911 -671303.5447711 +1926 1911 -52107624.53367 +1927 1911 36666666.66065 +1928 1911 -2754631.441411 +2010 1911 -18752053.59425 +2011 1911 9166666.66968 +2012 1911 10539814.37052 +2013 1911 -72726245.22972 +2014 1911 -9166776.303506 +2015 1911 44231216.90386 +2019 1911 -1865379.213624 +2020 1911 8.79168510437e-07 +2021 1911 57871.26589221 +2022 1911 70575234.21716 +2023 1911 9166849.392726 +2024 1911 781227.3439141 +2025 1911 -20203256.3538 +2026 1911 -9166739.758899 +2027 1911 11899863.74724 +2031 1911 -18848133.13973 +2032 1911 -9166666.66968 +2033 1911 -10597685.63642 +2034 1911 -60775629.25067 +2035 1911 -1.214444637299e-06 +2036 1911 -45012270.30212 +2037 1911 -20383999.6175 +2038 1911 9166666.669679 +2039 1911 -11899768.97017 +1912 1912 575752291.8369 +1913 1912 -8610912.053949 +1914 1912 -36667115.6891 +1915 1912 -108195591.755 +1916 1912 4777685.365654 +1920 1912 -36666666.66065 +1921 1912 -41083165.69975 +1922 1912 1222200.476822 +1923 1912 4.470348358154e-07 +1924 1912 23707595.23204 +1925 1912 -2777734.286976 +1926 1912 36666666.66065 +1927 1912 -41106839.94217 +1928 1912 1555533.810155 +2010 1912 9166666.66968 +2011 1912 -16001859.73922 +2012 1912 -8593755.37553 +2013 1912 -9166739.758897 +2014 1912 -29642168.10562 +2015 1912 8204934.122165 +2019 1912 1.229345798492e-06 +2020 1912 -36698646.37071 +2021 1912 -34527799.26293 +2022 1912 9166849.392726 +2023 1912 45823407.30156 +2024 1912 -2152765.098743 +2025 1912 -9166776.303508 +2026 1912 -52286475.83204 +2027 1912 37069600.58987 +2031 1912 -9166666.669679 +2032 1912 -16097939.2847 +2033 1912 -8663199.819997 +2034 1912 -1.445412635803e-06 +2035 1912 -20441974.38895 +2036 1912 -694433.6992576 +2037 1912 9166666.669678 +2038 1912 -17633805.76247 +2039 1912 9357633.519253 +1913 1913 615008779.2968 +1914 1913 2685222.441543 +1915 1913 5222139.640517 +1916 1913 39437488.39575 +1920 1913 2523146.335561 +1921 1913 1277756.032423 +1922 1913 -7296493.499545 +1923 1913 -254636.8781728 +1924 1913 -2777734.286976 +1925 1913 42039227.65673 +1926 1913 -2685186.996909 +1927 1913 1499978.254554 +1928 1913 -7359624.812662 +2010 1913 10539814.37052 +2011 1913 -8593755.37553 +2012 1913 -17106970.31658 +2013 1913 44196492.14387 +2014 1913 8010523.495484 +2015 1913 -58776166.2905 +2019 1913 57871.26589252 +2020 1913 -34500021.48517 +2021 1913 -41438476.99211 +2022 1913 781316.8545274 +2023 1913 -2152693.49136 +2024 1913 -107886912.3736 +2025 1913 11899911.13577 +2026 1913 37236269.31883 +2027 1913 -57440830.58835 +2031 1913 -10597685.63642 +2032 1913 -8663199.819997 +2033 1913 -17363182.43788 +2034 1913 -44977548.07992 +2035 1913 -694433.6992576 +2036 1913 -59807200.44138 +2037 1913 -11899768.97017 +2038 1913 9357633.519253 +2039 1913 -21458826.37861 +1914 1914 389420334.4506 +1915 1914 36666666.66065 +1916 1914 3703834.305166 +1923 1914 -52083950.29126 +1924 1914 -36666666.66065 +1925 1914 2453701.89106 +1926 1914 -202591396.4212 +1927 1914 -36666966.01295 +1928 1914 -2870483.022002 +1929 1914 12702400.63006 +1930 1914 29333632.68082 +1931 1914 -1944468.073742 +2013 1914 -5106206.927443 +2014 1914 11000109.63744 +2015 1914 12682625.90274 +2022 1914 -15511422.68773 +2023 1914 -9166776.303506 +2024 1914 -10539940.2691 +2025 1914 31947394.33292 +2026 1914 9166666.669681 +2027 1914 9728225.899101 +2034 1914 -18848133.13973 +2035 1914 -9166666.66968 +2036 1914 -10597685.63642 +2037 1914 -74358253.63036 +2038 1914 -9166739.758898 +2039 1914 -45562288.72778 +2040 1914 -8166156.136015 +2041 1914 7333406.424962 +2042 1914 -9496761.446847 +1915 1915 334416074.7194 +1916 1915 -6111048.190243 +1923 1915 -36666666.66065 +1924 1915 -41083165.69975 +1925 1915 1222200.476822 +1926 1915 -36667115.68909 +1927 1915 -30255041.75127 +1928 1915 -3888889.819054 +1929 1915 44000449.02122 +1930 1915 12702400.63006 +1931 1915 2666689.342343 +2013 1915 7333406.424962 +2014 1915 -5106206.927443 +2015 1915 -6763956.526763 +2022 1915 -9166739.758897 +2023 1915 -47594642.16596 +2024 1915 -34569643.89832 +2025 1915 9166666.66968 +2026 1915 18196342.83202 +2027 1915 5513941.008134 +2034 1915 -9166666.669679 +2035 1915 -16097939.2847 +2036 1915 -8663199.819997 +2037 1915 -9166776.303507 +2038 1915 -31274176.50627 +2039 1915 -9941080.210835 +2040 1915 11000109.63744 +2041 1915 -8166156.136015 +2042 1915 11395946.69513 +1916 1916 380479993.5812 +1923 1916 2523146.335561 +1924 1916 1277756.032423 +1925 1916 -7296493.499545 +1926 1916 -2453807.380415 +1927 1916 -3055548.927153 +1928 1916 398412.8916247 +1929 1916 -2916702.110613 +1930 1916 1777792.894895 +1931 1916 33873068.34682 +2013 1916 8455083.935158 +2014 1916 -10145934.79014 +2015 1916 -13616551.80652 +2022 1916 -10539898.30291 +2023 1916 -34736312.74845 +2024 1916 -44929274.14549 +2025 1916 -8223530.275229 +2026 1916 -8847241.586827 +2027 1916 -79300461.72417 +2034 1916 -10597685.63642 +2035 1916 -8663199.819997 +2036 1916 -17363182.43788 +2037 1916 -45527563.96779 +2038 1916 -9746597.980308 +2039 1916 -63128188.69225 +2040 1916 -14245142.17027 +2041 1916 7597297.796754 +2042 1916 -21776416.36271 +1917 1917 622861433.7406 +1918 1917 1.120567321777e-05 +1919 1917 925940.4229136 +1920 1917 84958459.17911 +1921 1917 -5.066394805908e-06 +1922 1917 231485.1058435 +1932 1917 -137627039.3558 +1933 1917 -2.235174179077e-07 +1934 1917 -671303.5447711 +1935 1917 -52107624.53367 +1936 1917 36666666.66065 +1937 1917 -2754631.441411 +2016 1917 -60367636.82651 +2017 1917 1.877546310425e-06 +2018 1917 44780785.23866 +2019 1917 -20276082.95081 +2020 1917 -9166666.66968 +2021 1917 11841897.70428 +2028 1917 51054233.83102 +2029 1917 1.788139343262e-06 +2030 1917 231485.0634618 +2031 1917 -7985170.87927 +2032 1917 -2.771615982056e-06 +2033 1917 57871.2658952 +2043 1917 -60775629.25067 +2044 1917 -1.214444637299e-06 +2045 1917 -45012270.30212 +2046 1917 -20383999.6175 +2047 1917 9166666.669679 +2048 1917 -11899768.97017 +1918 1918 534855157.0519 +1919 1918 -11110937.14243 +1920 1918 -3.457069396973e-06 +1921 1918 -54374606.24745 +1922 1918 5722135.237857 +1932 1918 4.470348358154e-07 +1933 1918 23707595.23204 +1934 1918 -2777734.286976 +1935 1918 36666666.66065 +1936 1918 -41106839.94217 +1937 1918 1555533.810155 +2016 1918 1.169741153717e-06 +2017 1918 -20033981.96478 +2018 1918 -694433.6992575 +2019 1918 -9166666.66968 +2020 1918 -17525889.09577 +2021 1918 9288189.074786 +2028 1918 1.966953277588e-06 +2029 1918 29052683.00161 +2030 1918 -2777734.795662 +2031 1918 -2.190470695496e-06 +2032 1918 -42818438.03636 +2033 1918 37305534.05859 +2043 1918 -1.445412635803e-06 +2044 1918 -20441974.38895 +2045 1918 -694433.6992576 +2046 1918 9166666.669678 +2047 1918 -17633805.76247 +2048 1918 9357633.519253 +1919 1919 608211498.9432 +1920 1919 231485.105844 +1921 1919 5388801.904579 +1922 1919 80699306.16691 +1932 1919 -254636.8781728 +1933 1919 -2777734.286976 +1934 1919 42039227.65673 +1935 1919 -2685186.996909 +1936 1919 1499978.254554 +1937 1919 -7359624.812662 +2016 1919 44746063.01646 +2017 1919 -694433.6992574 +2018 1919 -58719220.64359 +2019 1919 11841897.70428 +2020 1919 9288189.074786 +2021 1919 -21171048.60074 +2028 1919 231485.0634617 +2029 1919 -2777734.795662 +2030 1919 -127043423.7988 +2031 1919 57871.26589543 +2032 1919 37277756.28083 +2033 1919 -57757921.43384 +2043 1919 -44977548.07992 +2044 1919 -694433.6992576 +2045 1919 -59807200.44138 +2046 1919 -11899768.97017 +2047 1919 9357633.519253 +2048 1919 -21458826.37861 +1920 1920 622861433.7406 +1921 1920 1.120567321777e-05 +1922 1920 925940.4229136 +1923 1920 84958459.17911 +1924 1920 -5.066394805908e-06 +1925 1920 231485.1058435 +1932 1920 -52083950.29126 +1933 1920 -36666666.66065 +1934 1920 2453701.89106 +1935 1920 -137627039.3558 +1936 1920 -2.235174179077e-07 +1937 1920 -671303.5447711 +1938 1920 -52107624.53367 +1939 1920 36666666.66065 +1940 1920 -2754631.441411 +2016 1920 -18752053.59425 +2017 1920 9166666.66968 +2018 1920 10539814.37052 +2019 1920 -60367636.82651 +2020 1920 1.877546310425e-06 +2021 1920 44780785.23866 +2022 1920 -20276082.95081 +2023 1920 -9166666.66968 +2024 1920 11841897.70428 +2028 1920 -1865379.213624 +2029 1920 8.79168510437e-07 +2030 1920 57871.26589221 +2031 1920 51054233.83102 +2032 1920 1.788139343262e-06 +2033 1920 231485.0634618 +2034 1920 -7985170.87927 +2035 1920 -2.771615982056e-06 +2036 1920 57871.2658952 +2043 1920 -18848133.13973 +2044 1920 -9166666.66968 +2045 1920 -10597685.63642 +2046 1920 -60775629.25067 +2047 1920 -1.214444637299e-06 +2048 1920 -45012270.30212 +2049 1920 -20383999.6175 +2050 1920 9166666.669679 +2051 1920 -11899768.97017 +1921 1921 534855157.0519 +1922 1921 -11110937.14243 +1923 1921 -3.457069396973e-06 +1924 1921 -54374606.24745 +1925 1921 5722135.237857 +1932 1921 -36666666.66065 +1933 1921 -41083165.69975 +1934 1921 1222200.476822 +1935 1921 4.470348358154e-07 +1936 1921 23707595.23204 +1937 1921 -2777734.286976 +1938 1921 36666666.66065 +1939 1921 -41106839.94217 +1940 1921 1555533.810155 +2016 1921 9166666.66968 +2017 1921 -16001859.73922 +2018 1921 -8593755.37553 +2019 1921 1.169741153717e-06 +2020 1921 -20033981.96478 +2021 1921 -694433.6992575 +2022 1921 -9166666.66968 +2023 1921 -17525889.09577 +2024 1921 9288189.074786 +2028 1921 1.229345798492e-06 +2029 1921 -36698646.37071 +2030 1921 -34527799.26293 +2031 1921 1.966953277588e-06 +2032 1921 29052683.00161 +2033 1921 -2777734.795662 +2034 1921 -2.190470695496e-06 +2035 1921 -42818438.03636 +2036 1921 37305534.05859 +2043 1921 -9166666.669679 +2044 1921 -16097939.2847 +2045 1921 -8663199.819997 +2046 1921 -1.445412635803e-06 +2047 1921 -20441974.38895 +2048 1921 -694433.6992576 +2049 1921 9166666.669678 +2050 1921 -17633805.76247 +2051 1921 9357633.519253 +1922 1922 608211498.9432 +1923 1922 231485.105844 +1924 1922 5388801.904579 +1925 1922 80699306.16691 +1932 1922 2523146.335561 +1933 1922 1277756.032423 +1934 1922 -7296493.499545 +1935 1922 -254636.8781728 +1936 1922 -2777734.286976 +1937 1922 42039227.65673 +1938 1922 -2685186.996909 +1939 1922 1499978.254554 +1940 1922 -7359624.812662 +2016 1922 10539814.37052 +2017 1922 -8593755.37553 +2018 1922 -17106970.31658 +2019 1922 44746063.01646 +2020 1922 -694433.6992574 +2021 1922 -58719220.64359 +2022 1922 11841897.70428 +2023 1922 9288189.074786 +2024 1922 -21171048.60074 +2028 1922 57871.26589252 +2029 1922 -34500021.48517 +2030 1922 -41438476.99211 +2031 1922 231485.0634617 +2032 1922 -2777734.795662 +2033 1922 -127043423.7988 +2034 1922 57871.26589543 +2035 1922 37277756.28083 +2036 1922 -57757921.43384 +2043 1922 -10597685.63642 +2044 1922 -8663199.819997 +2045 1922 -17363182.43788 +2046 1922 -44977548.07992 +2047 1922 -694433.6992576 +2048 1922 -59807200.44138 +2049 1922 -11899768.97017 +2050 1922 9357633.519253 +2051 1922 -21458826.37861 +1923 1923 622861433.7406 +1924 1923 1.120567321777e-05 +1925 1923 925940.4229136 +1926 1923 84958459.17911 +1927 1923 -5.066394805908e-06 +1928 1923 231485.1058435 +1935 1923 -52083950.29126 +1936 1923 -36666666.66065 +1937 1923 2453701.89106 +1938 1923 -137627039.3558 +1939 1923 -2.235174179077e-07 +1940 1923 -671303.5447711 +1941 1923 -52107624.53367 +1942 1923 36666666.66065 +1943 1923 -2754631.441411 +2019 1923 -18752053.59425 +2020 1923 9166666.66968 +2021 1923 10539814.37052 +2022 1923 -60367636.82651 +2023 1923 1.877546310425e-06 +2024 1923 44780785.23866 +2025 1923 -20276082.95081 +2026 1923 -9166666.66968 +2027 1923 11841897.70428 +2031 1923 -1865379.213624 +2032 1923 8.79168510437e-07 +2033 1923 57871.26589221 +2034 1923 51054233.83102 +2035 1923 1.788139343262e-06 +2036 1923 231485.0634618 +2037 1923 -7985170.87927 +2038 1923 -2.771615982056e-06 +2039 1923 57871.2658952 +2046 1923 -18848133.13973 +2047 1923 -9166666.66968 +2048 1923 -10597685.63642 +2049 1923 -60775629.25067 +2050 1923 -1.214444637299e-06 +2051 1923 -45012270.30212 +2052 1923 -20383999.6175 +2053 1923 9166666.669679 +2054 1923 -11899768.97017 +1924 1924 534855157.0519 +1925 1924 -11110937.14243 +1926 1924 -3.457069396973e-06 +1927 1924 -54374606.24745 +1928 1924 5722135.237857 +1935 1924 -36666666.66065 +1936 1924 -41083165.69975 +1937 1924 1222200.476822 +1938 1924 4.470348358154e-07 +1939 1924 23707595.23204 +1940 1924 -2777734.286976 +1941 1924 36666666.66065 +1942 1924 -41106839.94217 +1943 1924 1555533.810155 +2019 1924 9166666.66968 +2020 1924 -16001859.73922 +2021 1924 -8593755.37553 +2022 1924 1.169741153717e-06 +2023 1924 -20033981.96478 +2024 1924 -694433.6992575 +2025 1924 -9166666.66968 +2026 1924 -17525889.09577 +2027 1924 9288189.074786 +2031 1924 1.229345798492e-06 +2032 1924 -36698646.37071 +2033 1924 -34527799.26293 +2034 1924 1.966953277588e-06 +2035 1924 29052683.00161 +2036 1924 -2777734.795662 +2037 1924 -2.190470695496e-06 +2038 1924 -42818438.03636 +2039 1924 37305534.05859 +2046 1924 -9166666.669679 +2047 1924 -16097939.2847 +2048 1924 -8663199.819997 +2049 1924 -1.445412635803e-06 +2050 1924 -20441974.38895 +2051 1924 -694433.6992576 +2052 1924 9166666.669678 +2053 1924 -17633805.76247 +2054 1924 9357633.519253 +1925 1925 608211498.9432 +1926 1925 231485.105844 +1927 1925 5388801.904579 +1928 1925 80699306.16691 +1935 1925 2523146.335561 +1936 1925 1277756.032423 +1937 1925 -7296493.499545 +1938 1925 -254636.8781728 +1939 1925 -2777734.286976 +1940 1925 42039227.65673 +1941 1925 -2685186.996909 +1942 1925 1499978.254554 +1943 1925 -7359624.812662 +2019 1925 10539814.37052 +2020 1925 -8593755.37553 +2021 1925 -17106970.31658 +2022 1925 44746063.01646 +2023 1925 -694433.6992574 +2024 1925 -58719220.64359 +2025 1925 11841897.70428 +2026 1925 9288189.074786 +2027 1925 -21171048.60074 +2031 1925 57871.26589252 +2032 1925 -34500021.48517 +2033 1925 -41438476.99211 +2034 1925 231485.0634617 +2035 1925 -2777734.795662 +2036 1925 -127043423.7988 +2037 1925 57871.26589543 +2038 1925 37277756.28083 +2039 1925 -57757921.43384 +2046 1925 -10597685.63642 +2047 1925 -8663199.819997 +2048 1925 -17363182.43788 +2049 1925 -44977548.07992 +2050 1925 -694433.6992576 +2051 1925 -59807200.44138 +2052 1925 -11899768.97017 +2053 1925 9357633.519253 +2054 1925 -21458826.37861 +1926 1926 674759689.9124 +1927 1926 36667415.0414 +1928 1926 3125092.975185 +1929 1926 20137287.77529 +1930 1926 -36666966.01295 +1931 1926 2754655.071165 +1938 1926 -52083950.29126 +1939 1926 -36666666.66065 +1940 1926 2453701.89106 +1941 1926 -137627039.3558 +1942 1926 -2.235174179077e-07 +1943 1926 -671303.5447711 +1944 1926 -52107624.53367 +1945 1926 36666666.66065 +1946 1926 -2754631.441411 +2022 1926 -18752053.59425 +2023 1926 9166666.66968 +2024 1926 10539814.37052 +2025 1926 -72726245.22972 +2026 1926 -9166776.303506 +2027 1926 44231216.90386 +2034 1926 -1865379.213624 +2035 1926 8.79168510437e-07 +2036 1926 57871.26589221 +2037 1926 70575234.21716 +2038 1926 9166849.392726 +2039 1926 781227.3439141 +2040 1926 -20203256.3538 +2041 1926 -9166739.758899 +2042 1926 11899863.74724 +2049 1926 -18848133.13973 +2050 1926 -9166666.66968 +2051 1926 -10597685.63642 +2052 1926 -60775629.25067 +2053 1926 -1.214444637299e-06 +2054 1926 -45012270.30212 +2055 1926 -20383999.6175 +2056 1926 9166666.669679 +2057 1926 -11899768.97017 +1927 1927 575752291.8369 +1928 1927 -8610912.053949 +1929 1927 -36667115.6891 +1930 1927 -108195591.755 +1931 1927 4777685.365654 +1938 1927 -36666666.66065 +1939 1927 -41083165.69975 +1940 1927 1222200.476822 +1941 1927 4.470348358154e-07 +1942 1927 23707595.23204 +1943 1927 -2777734.286976 +1944 1927 36666666.66065 +1945 1927 -41106839.94217 +1946 1927 1555533.810155 +2022 1927 9166666.66968 +2023 1927 -16001859.73922 +2024 1927 -8593755.37553 +2025 1927 -9166739.758897 +2026 1927 -29642168.10562 +2027 1927 8204934.122165 +2034 1927 1.229345798492e-06 +2035 1927 -36698646.37071 +2036 1927 -34527799.26293 +2037 1927 9166849.392726 +2038 1927 45823407.30156 +2039 1927 -2152765.098743 +2040 1927 -9166776.303508 +2041 1927 -52286475.83204 +2042 1927 37069600.58987 +2049 1927 -9166666.669679 +2050 1927 -16097939.2847 +2051 1927 -8663199.819997 +2052 1927 -1.445412635803e-06 +2053 1927 -20441974.38895 +2054 1927 -694433.6992576 +2055 1927 9166666.669678 +2056 1927 -17633805.76247 +2057 1927 9357633.519253 +1928 1928 615008779.2968 +1929 1928 2685222.441543 +1930 1928 5222139.640517 +1931 1928 39437488.39575 +1938 1928 2523146.335561 +1939 1928 1277756.032423 +1940 1928 -7296493.499545 +1941 1928 -254636.8781728 +1942 1928 -2777734.286976 +1943 1928 42039227.65673 +1944 1928 -2685186.996909 +1945 1928 1499978.254554 +1946 1928 -7359624.812662 +2022 1928 10539814.37052 +2023 1928 -8593755.37553 +2024 1928 -17106970.31658 +2025 1928 44196492.14387 +2026 1928 8010523.495484 +2027 1928 -58776166.2905 +2034 1928 57871.26589252 +2035 1928 -34500021.48517 +2036 1928 -41438476.99211 +2037 1928 781316.8545274 +2038 1928 -2152693.49136 +2039 1928 -107886912.3736 +2040 1928 11899911.13577 +2041 1928 37236269.31883 +2042 1928 -57440830.58835 +2049 1928 -10597685.63642 +2050 1928 -8663199.819997 +2051 1928 -17363182.43788 +2052 1928 -44977548.07992 +2053 1928 -694433.6992576 +2054 1928 -59807200.44138 +2055 1928 -11899768.97017 +2056 1928 9357633.519253 +2057 1928 -21458826.37861 +1929 1929 389420334.4506 +1930 1929 36666666.66065 +1931 1929 3703834.305166 +1941 1929 -52083950.29126 +1942 1929 -36666666.66065 +1943 1929 2453701.89106 +1944 1929 -202591396.4212 +1945 1929 -36666966.01295 +1946 1929 -2870483.022002 +1947 1929 12702400.63006 +1948 1929 29333632.68082 +1949 1929 -1944468.073742 +2025 1929 -5106206.927443 +2026 1929 11000109.63744 +2027 1929 12682625.90274 +2037 1929 -15511422.68773 +2038 1929 -9166776.303506 +2039 1929 -10539940.2691 +2040 1929 31947394.33292 +2041 1929 9166666.669681 +2042 1929 9728225.899101 +2052 1929 -18848133.13973 +2053 1929 -9166666.66968 +2054 1929 -10597685.63642 +2055 1929 -74358253.63036 +2056 1929 -9166739.758898 +2057 1929 -45562288.72778 +2058 1929 -8166156.136015 +2059 1929 7333406.424962 +2060 1929 -9496761.446847 +1930 1930 334416074.7194 +1931 1930 -6111048.190243 +1941 1930 -36666666.66065 +1942 1930 -41083165.69975 +1943 1930 1222200.476822 +1944 1930 -36667115.68909 +1945 1930 -30255041.75127 +1946 1930 -3888889.819054 +1947 1930 44000449.02122 +1948 1930 12702400.63006 +1949 1930 2666689.342343 +2025 1930 7333406.424962 +2026 1930 -5106206.927443 +2027 1930 -6763956.526763 +2037 1930 -9166739.758897 +2038 1930 -47594642.16596 +2039 1930 -34569643.89832 +2040 1930 9166666.66968 +2041 1930 18196342.83202 +2042 1930 5513941.008134 +2052 1930 -9166666.669679 +2053 1930 -16097939.2847 +2054 1930 -8663199.819997 +2055 1930 -9166776.303507 +2056 1930 -31274176.50627 +2057 1930 -9941080.210835 +2058 1930 11000109.63744 +2059 1930 -8166156.136015 +2060 1930 11395946.69513 +1931 1931 380479993.5812 +1941 1931 2523146.335561 +1942 1931 1277756.032423 +1943 1931 -7296493.499545 +1944 1931 -2453807.380415 +1945 1931 -3055548.927153 +1946 1931 398412.8916247 +1947 1931 -2916702.110613 +1948 1931 1777792.894895 +1949 1931 33873068.34682 +2025 1931 8455083.935158 +2026 1931 -10145934.79014 +2027 1931 -13616551.80652 +2037 1931 -10539898.30291 +2038 1931 -34736312.74845 +2039 1931 -44929274.14549 +2040 1931 -8223530.275229 +2041 1931 -8847241.586827 +2042 1931 -79300461.72417 +2052 1931 -10597685.63642 +2053 1931 -8663199.819997 +2054 1931 -17363182.43788 +2055 1931 -45527563.96779 +2056 1931 -9746597.980308 +2057 1931 -63128188.69225 +2058 1931 -14245142.17027 +2059 1931 7597297.796754 +2060 1931 -21776416.36271 +1932 1932 622861433.7406 +1933 1932 1.120567321777e-05 +1934 1932 925940.4229136 +1935 1932 84958459.17911 +1936 1932 -5.066394805908e-06 +1937 1932 231485.1058435 +1950 1932 -137627039.3558 +1951 1932 -2.235174179077e-07 +1952 1932 -671303.5447711 +1953 1932 -52107624.53367 +1954 1932 36666666.66065 +1955 1932 -2754631.441411 +2028 1932 -60367636.82651 +2029 1932 1.877546310425e-06 +2030 1932 44780785.23866 +2031 1932 -20276082.95081 +2032 1932 -9166666.66968 +2033 1932 11841897.70428 +2043 1932 51054233.83102 +2044 1932 1.788139343262e-06 +2045 1932 231485.0634618 +2046 1932 -7985170.87927 +2047 1932 -2.771615982056e-06 +2048 1932 57871.2658952 +2061 1932 -60775629.25067 +2062 1932 -1.214444637299e-06 +2063 1932 -45012270.30212 +2064 1932 -20383999.6175 +2065 1932 9166666.669679 +2066 1932 -11899768.97017 +1933 1933 534855157.0519 +1934 1933 -11110937.14243 +1935 1933 -3.457069396973e-06 +1936 1933 -54374606.24745 +1937 1933 5722135.237857 +1950 1933 4.470348358154e-07 +1951 1933 23707595.23204 +1952 1933 -2777734.286976 +1953 1933 36666666.66065 +1954 1933 -41106839.94217 +1955 1933 1555533.810155 +2028 1933 1.169741153717e-06 +2029 1933 -20033981.96478 +2030 1933 -694433.6992575 +2031 1933 -9166666.66968 +2032 1933 -17525889.09577 +2033 1933 9288189.074786 +2043 1933 1.966953277588e-06 +2044 1933 29052683.00161 +2045 1933 -2777734.795662 +2046 1933 -2.190470695496e-06 +2047 1933 -42818438.03636 +2048 1933 37305534.05859 +2061 1933 -1.445412635803e-06 +2062 1933 -20441974.38895 +2063 1933 -694433.6992576 +2064 1933 9166666.669678 +2065 1933 -17633805.76247 +2066 1933 9357633.519253 +1934 1934 608211498.9432 +1935 1934 231485.105844 +1936 1934 5388801.904579 +1937 1934 80699306.16691 +1950 1934 -254636.8781728 +1951 1934 -2777734.286976 +1952 1934 42039227.65673 +1953 1934 -2685186.996909 +1954 1934 1499978.254554 +1955 1934 -7359624.812662 +2028 1934 44746063.01646 +2029 1934 -694433.6992574 +2030 1934 -58719220.64359 +2031 1934 11841897.70428 +2032 1934 9288189.074786 +2033 1934 -21171048.60074 +2043 1934 231485.0634617 +2044 1934 -2777734.795662 +2045 1934 -127043423.7988 +2046 1934 57871.26589543 +2047 1934 37277756.28083 +2048 1934 -57757921.43384 +2061 1934 -44977548.07992 +2062 1934 -694433.6992576 +2063 1934 -59807200.44138 +2064 1934 -11899768.97017 +2065 1934 9357633.519253 +2066 1934 -21458826.37861 +1935 1935 622861433.7406 +1936 1935 1.120567321777e-05 +1937 1935 925940.4229136 +1938 1935 84958459.17911 +1939 1935 -5.066394805908e-06 +1940 1935 231485.1058435 +1950 1935 -52083950.29126 +1951 1935 -36666666.66065 +1952 1935 2453701.89106 +1953 1935 -137627039.3558 +1954 1935 -2.235174179077e-07 +1955 1935 -671303.5447711 +1956 1935 -52107624.53367 +1957 1935 36666666.66065 +1958 1935 -2754631.441411 +2028 1935 -18752053.59425 +2029 1935 9166666.66968 +2030 1935 10539814.37052 +2031 1935 -60367636.82651 +2032 1935 1.877546310425e-06 +2033 1935 44780785.23866 +2034 1935 -20276082.95081 +2035 1935 -9166666.66968 +2036 1935 11841897.70428 +2043 1935 -1865379.213624 +2044 1935 8.79168510437e-07 +2045 1935 57871.26589221 +2046 1935 51054233.83102 +2047 1935 1.788139343262e-06 +2048 1935 231485.0634618 +2049 1935 -7985170.87927 +2050 1935 -2.771615982056e-06 +2051 1935 57871.2658952 +2061 1935 -18848133.13973 +2062 1935 -9166666.66968 +2063 1935 -10597685.63642 +2064 1935 -60775629.25067 +2065 1935 -1.214444637299e-06 +2066 1935 -45012270.30212 +2067 1935 -20383999.6175 +2068 1935 9166666.669679 +2069 1935 -11899768.97017 +1936 1936 534855157.0519 +1937 1936 -11110937.14243 +1938 1936 -3.457069396973e-06 +1939 1936 -54374606.24745 +1940 1936 5722135.237857 +1950 1936 -36666666.66065 +1951 1936 -41083165.69975 +1952 1936 1222200.476822 +1953 1936 4.470348358154e-07 +1954 1936 23707595.23204 +1955 1936 -2777734.286976 +1956 1936 36666666.66065 +1957 1936 -41106839.94217 +1958 1936 1555533.810155 +2028 1936 9166666.66968 +2029 1936 -16001859.73922 +2030 1936 -8593755.37553 +2031 1936 1.169741153717e-06 +2032 1936 -20033981.96478 +2033 1936 -694433.6992575 +2034 1936 -9166666.66968 +2035 1936 -17525889.09577 +2036 1936 9288189.074786 +2043 1936 1.229345798492e-06 +2044 1936 -36698646.37071 +2045 1936 -34527799.26293 +2046 1936 1.966953277588e-06 +2047 1936 29052683.00161 +2048 1936 -2777734.795662 +2049 1936 -2.190470695496e-06 +2050 1936 -42818438.03636 +2051 1936 37305534.05859 +2061 1936 -9166666.669679 +2062 1936 -16097939.2847 +2063 1936 -8663199.819997 +2064 1936 -1.445412635803e-06 +2065 1936 -20441974.38895 +2066 1936 -694433.6992576 +2067 1936 9166666.669678 +2068 1936 -17633805.76247 +2069 1936 9357633.519253 +1937 1937 608211498.9432 +1938 1937 231485.105844 +1939 1937 5388801.904579 +1940 1937 80699306.16691 +1950 1937 2523146.335561 +1951 1937 1277756.032423 +1952 1937 -7296493.499545 +1953 1937 -254636.8781728 +1954 1937 -2777734.286976 +1955 1937 42039227.65673 +1956 1937 -2685186.996909 +1957 1937 1499978.254554 +1958 1937 -7359624.812662 +2028 1937 10539814.37052 +2029 1937 -8593755.37553 +2030 1937 -17106970.31658 +2031 1937 44746063.01646 +2032 1937 -694433.6992574 +2033 1937 -58719220.64359 +2034 1937 11841897.70428 +2035 1937 9288189.074786 +2036 1937 -21171048.60074 +2043 1937 57871.26589252 +2044 1937 -34500021.48517 +2045 1937 -41438476.99211 +2046 1937 231485.0634617 +2047 1937 -2777734.795662 +2048 1937 -127043423.7988 +2049 1937 57871.26589543 +2050 1937 37277756.28083 +2051 1937 -57757921.43384 +2061 1937 -10597685.63642 +2062 1937 -8663199.819997 +2063 1937 -17363182.43788 +2064 1937 -44977548.07992 +2065 1937 -694433.6992576 +2066 1937 -59807200.44138 +2067 1937 -11899768.97017 +2068 1937 9357633.519253 +2069 1937 -21458826.37861 +1938 1938 622861433.7406 +1939 1938 1.120567321777e-05 +1940 1938 925940.4229136 +1941 1938 84958459.17911 +1942 1938 -5.066394805908e-06 +1943 1938 231485.1058435 +1953 1938 -52083950.29126 +1954 1938 -36666666.66065 +1955 1938 2453701.89106 +1956 1938 -137627039.3558 +1957 1938 -2.235174179077e-07 +1958 1938 -671303.5447711 +1959 1938 -52107624.53367 +1960 1938 36666666.66065 +1961 1938 -2754631.441411 +2031 1938 -18752053.59425 +2032 1938 9166666.66968 +2033 1938 10539814.37052 +2034 1938 -60367636.82651 +2035 1938 1.877546310425e-06 +2036 1938 44780785.23866 +2037 1938 -20276082.95081 +2038 1938 -9166666.66968 +2039 1938 11841897.70428 +2046 1938 -1865379.213624 +2047 1938 8.79168510437e-07 +2048 1938 57871.26589221 +2049 1938 51054233.83102 +2050 1938 1.788139343262e-06 +2051 1938 231485.0634618 +2052 1938 -7985170.87927 +2053 1938 -2.771615982056e-06 +2054 1938 57871.2658952 +2064 1938 -18848133.13973 +2065 1938 -9166666.66968 +2066 1938 -10597685.63642 +2067 1938 -60775629.25067 +2068 1938 -1.214444637299e-06 +2069 1938 -45012270.30212 +2070 1938 -20383999.6175 +2071 1938 9166666.669679 +2072 1938 -11899768.97017 +1939 1939 534855157.0519 +1940 1939 -11110937.14243 +1941 1939 -3.457069396973e-06 +1942 1939 -54374606.24745 +1943 1939 5722135.237857 +1953 1939 -36666666.66065 +1954 1939 -41083165.69975 +1955 1939 1222200.476822 +1956 1939 4.470348358154e-07 +1957 1939 23707595.23204 +1958 1939 -2777734.286976 +1959 1939 36666666.66065 +1960 1939 -41106839.94217 +1961 1939 1555533.810155 +2031 1939 9166666.66968 +2032 1939 -16001859.73922 +2033 1939 -8593755.37553 +2034 1939 1.169741153717e-06 +2035 1939 -20033981.96478 +2036 1939 -694433.6992575 +2037 1939 -9166666.66968 +2038 1939 -17525889.09577 +2039 1939 9288189.074786 +2046 1939 1.229345798492e-06 +2047 1939 -36698646.37071 +2048 1939 -34527799.26293 +2049 1939 1.966953277588e-06 +2050 1939 29052683.00161 +2051 1939 -2777734.795662 +2052 1939 -2.190470695496e-06 +2053 1939 -42818438.03636 +2054 1939 37305534.05859 +2064 1939 -9166666.669679 +2065 1939 -16097939.2847 +2066 1939 -8663199.819997 +2067 1939 -1.445412635803e-06 +2068 1939 -20441974.38895 +2069 1939 -694433.6992576 +2070 1939 9166666.669678 +2071 1939 -17633805.76247 +2072 1939 9357633.519253 +1940 1940 608211498.9432 +1941 1940 231485.105844 +1942 1940 5388801.904579 +1943 1940 80699306.16691 +1953 1940 2523146.335561 +1954 1940 1277756.032423 +1955 1940 -7296493.499545 +1956 1940 -254636.8781728 +1957 1940 -2777734.286976 +1958 1940 42039227.65673 +1959 1940 -2685186.996909 +1960 1940 1499978.254554 +1961 1940 -7359624.812662 +2031 1940 10539814.37052 +2032 1940 -8593755.37553 +2033 1940 -17106970.31658 +2034 1940 44746063.01646 +2035 1940 -694433.6992574 +2036 1940 -58719220.64359 +2037 1940 11841897.70428 +2038 1940 9288189.074786 +2039 1940 -21171048.60074 +2046 1940 57871.26589252 +2047 1940 -34500021.48517 +2048 1940 -41438476.99211 +2049 1940 231485.0634617 +2050 1940 -2777734.795662 +2051 1940 -127043423.7988 +2052 1940 57871.26589543 +2053 1940 37277756.28083 +2054 1940 -57757921.43384 +2064 1940 -10597685.63642 +2065 1940 -8663199.819997 +2066 1940 -17363182.43788 +2067 1940 -44977548.07992 +2068 1940 -694433.6992576 +2069 1940 -59807200.44138 +2070 1940 -11899768.97017 +2071 1940 9357633.519253 +2072 1940 -21458826.37861 +1941 1941 622861433.7406 +1942 1941 1.120567321777e-05 +1943 1941 925940.4229136 +1944 1941 84958459.17911 +1945 1941 -5.066394805908e-06 +1946 1941 231485.1058435 +1956 1941 -52083950.29126 +1957 1941 -36666666.66065 +1958 1941 2453701.89106 +1959 1941 -137627039.3558 +1960 1941 -2.235174179077e-07 +1961 1941 -671303.5447711 +1962 1941 -52107624.53367 +1963 1941 36666666.66065 +1964 1941 -2754631.441411 +2034 1941 -18752053.59425 +2035 1941 9166666.66968 +2036 1941 10539814.37052 +2037 1941 -60367636.82651 +2038 1941 1.877546310425e-06 +2039 1941 44780785.23866 +2040 1941 -20276082.95081 +2041 1941 -9166666.66968 +2042 1941 11841897.70428 +2049 1941 -1865379.213624 +2050 1941 8.79168510437e-07 +2051 1941 57871.26589221 +2052 1941 51054233.83102 +2053 1941 1.788139343262e-06 +2054 1941 231485.0634618 +2055 1941 -7985170.87927 +2056 1941 -2.771615982056e-06 +2057 1941 57871.2658952 +2067 1941 -18848133.13973 +2068 1941 -9166666.66968 +2069 1941 -10597685.63642 +2070 1941 -60775629.25067 +2071 1941 -1.214444637299e-06 +2072 1941 -45012270.30212 +2073 1941 -20383999.6175 +2074 1941 9166666.669679 +2075 1941 -11899768.97017 +1942 1942 534855157.0519 +1943 1942 -11110937.14243 +1944 1942 -3.457069396973e-06 +1945 1942 -54374606.24745 +1946 1942 5722135.237857 +1956 1942 -36666666.66065 +1957 1942 -41083165.69975 +1958 1942 1222200.476822 +1959 1942 4.470348358154e-07 +1960 1942 23707595.23204 +1961 1942 -2777734.286976 +1962 1942 36666666.66065 +1963 1942 -41106839.94217 +1964 1942 1555533.810155 +2034 1942 9166666.66968 +2035 1942 -16001859.73922 +2036 1942 -8593755.37553 +2037 1942 1.169741153717e-06 +2038 1942 -20033981.96478 +2039 1942 -694433.6992575 +2040 1942 -9166666.66968 +2041 1942 -17525889.09577 +2042 1942 9288189.074786 +2049 1942 1.229345798492e-06 +2050 1942 -36698646.37071 +2051 1942 -34527799.26293 +2052 1942 1.966953277588e-06 +2053 1942 29052683.00161 +2054 1942 -2777734.795662 +2055 1942 -2.190470695496e-06 +2056 1942 -42818438.03636 +2057 1942 37305534.05859 +2067 1942 -9166666.669679 +2068 1942 -16097939.2847 +2069 1942 -8663199.819997 +2070 1942 -1.445412635803e-06 +2071 1942 -20441974.38895 +2072 1942 -694433.6992576 +2073 1942 9166666.669678 +2074 1942 -17633805.76247 +2075 1942 9357633.519253 +1943 1943 608211498.9432 +1944 1943 231485.105844 +1945 1943 5388801.904579 +1946 1943 80699306.16691 +1956 1943 2523146.335561 +1957 1943 1277756.032423 +1958 1943 -7296493.499545 +1959 1943 -254636.8781728 +1960 1943 -2777734.286976 +1961 1943 42039227.65673 +1962 1943 -2685186.996909 +1963 1943 1499978.254554 +1964 1943 -7359624.812662 +2034 1943 10539814.37052 +2035 1943 -8593755.37553 +2036 1943 -17106970.31658 +2037 1943 44746063.01646 +2038 1943 -694433.6992574 +2039 1943 -58719220.64359 +2040 1943 11841897.70428 +2041 1943 9288189.074786 +2042 1943 -21171048.60074 +2049 1943 57871.26589252 +2050 1943 -34500021.48517 +2051 1943 -41438476.99211 +2052 1943 231485.0634617 +2053 1943 -2777734.795662 +2054 1943 -127043423.7988 +2055 1943 57871.26589543 +2056 1943 37277756.28083 +2057 1943 -57757921.43384 +2067 1943 -10597685.63642 +2068 1943 -8663199.819997 +2069 1943 -17363182.43788 +2070 1943 -44977548.07992 +2071 1943 -694433.6992576 +2072 1943 -59807200.44138 +2073 1943 -11899768.97017 +2074 1943 9357633.519253 +2075 1943 -21458826.37861 +1944 1944 674759689.9124 +1945 1944 36667415.0414 +1946 1944 3125092.975185 +1947 1944 20137287.77529 +1948 1944 -36666966.01295 +1949 1944 2754655.071165 +1959 1944 -52083950.29126 +1960 1944 -36666666.66065 +1961 1944 2453701.89106 +1962 1944 -137627039.3558 +1963 1944 -2.235174179077e-07 +1964 1944 -671303.5447711 +1965 1944 -52107624.53367 +1966 1944 36666666.66065 +1967 1944 -2754631.441411 +2037 1944 -18752053.59425 +2038 1944 9166666.66968 +2039 1944 10539814.37052 +2040 1944 -72726245.22972 +2041 1944 -9166776.303506 +2042 1944 44231216.90386 +2052 1944 -1865379.213624 +2053 1944 8.79168510437e-07 +2054 1944 57871.26589221 +2055 1944 70575234.21716 +2056 1944 9166849.392726 +2057 1944 781227.3439141 +2058 1944 -20203256.3538 +2059 1944 -9166739.758899 +2060 1944 11899863.74724 +2070 1944 -18848133.13973 +2071 1944 -9166666.66968 +2072 1944 -10597685.63642 +2073 1944 -60775629.25067 +2074 1944 -1.214444637299e-06 +2075 1944 -45012270.30212 +2076 1944 -20383999.6175 +2077 1944 9166666.669679 +2078 1944 -11899768.97017 +1945 1945 575752291.8369 +1946 1945 -8610912.053949 +1947 1945 -36667115.6891 +1948 1945 -108195591.755 +1949 1945 4777685.365654 +1959 1945 -36666666.66065 +1960 1945 -41083165.69975 +1961 1945 1222200.476822 +1962 1945 4.470348358154e-07 +1963 1945 23707595.23204 +1964 1945 -2777734.286976 +1965 1945 36666666.66065 +1966 1945 -41106839.94217 +1967 1945 1555533.810155 +2037 1945 9166666.66968 +2038 1945 -16001859.73922 +2039 1945 -8593755.37553 +2040 1945 -9166739.758897 +2041 1945 -29642168.10562 +2042 1945 8204934.122165 +2052 1945 1.229345798492e-06 +2053 1945 -36698646.37071 +2054 1945 -34527799.26293 +2055 1945 9166849.392726 +2056 1945 45823407.30156 +2057 1945 -2152765.098743 +2058 1945 -9166776.303508 +2059 1945 -52286475.83204 +2060 1945 37069600.58987 +2070 1945 -9166666.669679 +2071 1945 -16097939.2847 +2072 1945 -8663199.819997 +2073 1945 -1.445412635803e-06 +2074 1945 -20441974.38895 +2075 1945 -694433.6992576 +2076 1945 9166666.669678 +2077 1945 -17633805.76247 +2078 1945 9357633.519253 +1946 1946 615008779.2968 +1947 1946 2685222.441543 +1948 1946 5222139.640517 +1949 1946 39437488.39575 +1959 1946 2523146.335561 +1960 1946 1277756.032423 +1961 1946 -7296493.499545 +1962 1946 -254636.8781728 +1963 1946 -2777734.286976 +1964 1946 42039227.65673 +1965 1946 -2685186.996909 +1966 1946 1499978.254554 +1967 1946 -7359624.812662 +2037 1946 10539814.37052 +2038 1946 -8593755.37553 +2039 1946 -17106970.31658 +2040 1946 44196492.14387 +2041 1946 8010523.495484 +2042 1946 -58776166.2905 +2052 1946 57871.26589252 +2053 1946 -34500021.48517 +2054 1946 -41438476.99211 +2055 1946 781316.8545274 +2056 1946 -2152693.49136 +2057 1946 -107886912.3736 +2058 1946 11899911.13577 +2059 1946 37236269.31883 +2060 1946 -57440830.58835 +2070 1946 -10597685.63642 +2071 1946 -8663199.819997 +2072 1946 -17363182.43788 +2073 1946 -44977548.07992 +2074 1946 -694433.6992576 +2075 1946 -59807200.44138 +2076 1946 -11899768.97017 +2077 1946 9357633.519253 +2078 1946 -21458826.37861 +1947 1947 434012491.322 +1948 1947 -26709105.05296 +1949 1947 -725793.543576 +1962 1947 -52083950.29126 +1963 1947 -36666666.66065 +1964 1947 2453701.89106 +1965 1947 -56549866.20531 +1966 1947 26704759.61057 +1967 1947 -385264.5612573 +1968 1947 -222386913.2778 +1969 1947 29337678.77091 +1970 1947 -277833.5794091 +2040 1947 -5106206.927443 +2041 1947 11000109.63744 +2042 1947 12682625.90274 +2055 1947 -15511422.68773 +2056 1947 -9166776.303506 +2057 1947 -10539940.2691 +2058 1947 57002220.2306 +2059 1947 -6544915.940513 +2060 1947 4861555.215121 +2073 1947 -18848133.13973 +2074 1947 -9166666.66968 +2075 1947 -10597685.63642 +2076 1947 -29177118.41547 +2077 1947 6543892.420132 +2078 1947 -25729678.71087 +2079 1947 -53961140.25394 +2080 1947 7334356.856125 +2081 1947 -1354081.113647 +1948 1948 781040484.4929 +1949 1948 -10574395.88396 +1962 1948 -36666666.66065 +1963 1948 -41083165.69975 +1964 1948 1222200.476822 +1965 1948 26702586.88937 +1966 1948 87287357.54424 +1967 1948 -1789762.243781 +1968 1948 44006518.15637 +1969 1948 -595920035.2594 +1970 1948 5142261.375664 +2040 1948 7333406.424962 +2041 1948 -5106206.927443 +2042 1948 -6763956.526763 +2055 1948 -9166739.758897 +2056 1948 -47594642.16596 +2057 1948 -34569643.89832 +2058 1948 -6544915.940513 +2059 1948 138242633.1703 +2060 1948 1389850.346674 +2073 1948 -9166666.669679 +2074 1948 -16097939.2847 +2075 1948 -8663199.819997 +2076 1948 6543380.659941 +2077 1948 6841374.023334 +2078 1948 5925066.094897 +2079 1948 11001535.28419 +2080 1948 -141887020.0092 +2081 1948 18142632.26191 +1949 1949 467013145.2305 +1962 1949 2523146.335561 +1963 1949 1277756.032423 +1964 1949 -7296493.499545 +1965 1949 -940793.6136686 +1966 1949 -1678594.911864 +1967 1949 48688638.16036 +1968 1949 -416750.3691136 +1969 1949 5031214.44564 +1970 1949 -219498646.7591 +2040 1949 8455083.935158 +2041 1949 -10145934.79014 +2042 1949 -13616551.80652 +2055 1949 -10539898.30291 +2056 1949 -34736312.74845 +2057 1949 -44929274.14549 +2058 1949 -5398901.65238 +2059 1949 -6817695.611917 +2060 1949 -15837053.95701 +2073 1949 -10597685.63642 +2074 1949 -8663199.819997 +2075 1949 -17363182.43788 +2076 1949 -25903283.59124 +2077 1949 5953357.675215 +2078 1949 -27221579.91443 +2079 1949 -2031121.67047 +2080 1949 17600907.9829 +2081 1949 -55970494.25524 +1950 1950 622861433.7406 +1951 1950 1.120567321777e-05 +1952 1950 925940.4229136 +1953 1950 84958459.17911 +1954 1950 -5.066394805908e-06 +1955 1950 231485.1058435 +1971 1950 -137627039.3558 +1972 1950 -2.235174179077e-07 +1973 1950 -671303.5447711 +1974 1950 -52107624.53367 +1975 1950 36666666.66065 +1976 1950 -2754631.441411 +2043 1950 -60367636.82651 +2044 1950 1.877546310425e-06 +2045 1950 44780785.23866 +2046 1950 -20276082.95081 +2047 1950 -9166666.66968 +2048 1950 11841897.70428 +2061 1950 51054233.83102 +2062 1950 1.788139343262e-06 +2063 1950 231485.0634618 +2064 1950 -7985170.87927 +2065 1950 -2.771615982056e-06 +2066 1950 57871.2658952 +2082 1950 -60775629.25067 +2083 1950 -1.214444637299e-06 +2084 1950 -45012270.30212 +2085 1950 -20383999.6175 +2086 1950 9166666.669679 +2087 1950 -11899768.97017 +1951 1951 534855157.0519 +1952 1951 -11110937.14243 +1953 1951 -3.457069396973e-06 +1954 1951 -54374606.24745 +1955 1951 5722135.237857 +1971 1951 4.470348358154e-07 +1972 1951 23707595.23204 +1973 1951 -2777734.286976 +1974 1951 36666666.66065 +1975 1951 -41106839.94217 +1976 1951 1555533.810155 +2043 1951 1.169741153717e-06 +2044 1951 -20033981.96478 +2045 1951 -694433.6992575 +2046 1951 -9166666.66968 +2047 1951 -17525889.09577 +2048 1951 9288189.074786 +2061 1951 1.966953277588e-06 +2062 1951 29052683.00161 +2063 1951 -2777734.795662 +2064 1951 -2.190470695496e-06 +2065 1951 -42818438.03636 +2066 1951 37305534.05859 +2082 1951 -1.445412635803e-06 +2083 1951 -20441974.38895 +2084 1951 -694433.6992576 +2085 1951 9166666.669678 +2086 1951 -17633805.76247 +2087 1951 9357633.519253 +1952 1952 608211498.9432 +1953 1952 231485.105844 +1954 1952 5388801.904579 +1955 1952 80699306.16691 +1971 1952 -254636.8781728 +1972 1952 -2777734.286976 +1973 1952 42039227.65673 +1974 1952 -2685186.996909 +1975 1952 1499978.254554 +1976 1952 -7359624.812662 +2043 1952 44746063.01646 +2044 1952 -694433.6992574 +2045 1952 -58719220.64359 +2046 1952 11841897.70428 +2047 1952 9288189.074786 +2048 1952 -21171048.60074 +2061 1952 231485.0634617 +2062 1952 -2777734.795662 +2063 1952 -127043423.7988 +2064 1952 57871.26589543 +2065 1952 37277756.28083 +2066 1952 -57757921.43384 +2082 1952 -44977548.07992 +2083 1952 -694433.6992576 +2084 1952 -59807200.44138 +2085 1952 -11899768.97017 +2086 1952 9357633.519253 +2087 1952 -21458826.37861 +1953 1953 622861433.7406 +1954 1953 1.120567321777e-05 +1955 1953 925940.4229136 +1956 1953 84958459.17911 +1957 1953 -5.066394805908e-06 +1958 1953 231485.1058435 +1971 1953 -52083950.29126 +1972 1953 -36666666.66065 +1973 1953 2453701.89106 +1974 1953 -137627039.3558 +1975 1953 -2.235174179077e-07 +1976 1953 -671303.5447711 +1977 1953 -52107624.53367 +1978 1953 36666666.66065 +1979 1953 -2754631.441411 +2043 1953 -18752053.59425 +2044 1953 9166666.66968 +2045 1953 10539814.37052 +2046 1953 -60367636.82651 +2047 1953 1.877546310425e-06 +2048 1953 44780785.23866 +2049 1953 -20276082.95081 +2050 1953 -9166666.66968 +2051 1953 11841897.70428 +2061 1953 -1865379.213624 +2062 1953 8.79168510437e-07 +2063 1953 57871.26589221 +2064 1953 51054233.83102 +2065 1953 1.788139343262e-06 +2066 1953 231485.0634618 +2067 1953 -7985170.87927 +2068 1953 -2.771615982056e-06 +2069 1953 57871.2658952 +2082 1953 -18848133.13973 +2083 1953 -9166666.66968 +2084 1953 -10597685.63642 +2085 1953 -60775629.25067 +2086 1953 -1.214444637299e-06 +2087 1953 -45012270.30212 +2088 1953 -20383999.6175 +2089 1953 9166666.669679 +2090 1953 -11899768.97017 +1954 1954 534855157.0519 +1955 1954 -11110937.14243 +1956 1954 -3.457069396973e-06 +1957 1954 -54374606.24745 +1958 1954 5722135.237857 +1971 1954 -36666666.66065 +1972 1954 -41083165.69975 +1973 1954 1222200.476822 +1974 1954 4.470348358154e-07 +1975 1954 23707595.23204 +1976 1954 -2777734.286976 +1977 1954 36666666.66065 +1978 1954 -41106839.94217 +1979 1954 1555533.810155 +2043 1954 9166666.66968 +2044 1954 -16001859.73922 +2045 1954 -8593755.37553 +2046 1954 1.169741153717e-06 +2047 1954 -20033981.96478 +2048 1954 -694433.6992575 +2049 1954 -9166666.66968 +2050 1954 -17525889.09577 +2051 1954 9288189.074786 +2061 1954 1.229345798492e-06 +2062 1954 -36698646.37071 +2063 1954 -34527799.26293 +2064 1954 1.966953277588e-06 +2065 1954 29052683.00161 +2066 1954 -2777734.795662 +2067 1954 -2.190470695496e-06 +2068 1954 -42818438.03636 +2069 1954 37305534.05859 +2082 1954 -9166666.669679 +2083 1954 -16097939.2847 +2084 1954 -8663199.819997 +2085 1954 -1.445412635803e-06 +2086 1954 -20441974.38895 +2087 1954 -694433.6992576 +2088 1954 9166666.669678 +2089 1954 -17633805.76247 +2090 1954 9357633.519253 +1955 1955 608211498.9432 +1956 1955 231485.105844 +1957 1955 5388801.904579 +1958 1955 80699306.16691 +1971 1955 2523146.335561 +1972 1955 1277756.032423 +1973 1955 -7296493.499545 +1974 1955 -254636.8781728 +1975 1955 -2777734.286976 +1976 1955 42039227.65673 +1977 1955 -2685186.996909 +1978 1955 1499978.254554 +1979 1955 -7359624.812662 +2043 1955 10539814.37052 +2044 1955 -8593755.37553 +2045 1955 -17106970.31658 +2046 1955 44746063.01646 +2047 1955 -694433.6992574 +2048 1955 -58719220.64359 +2049 1955 11841897.70428 +2050 1955 9288189.074786 +2051 1955 -21171048.60074 +2061 1955 57871.26589252 +2062 1955 -34500021.48517 +2063 1955 -41438476.99211 +2064 1955 231485.0634617 +2065 1955 -2777734.795662 +2066 1955 -127043423.7988 +2067 1955 57871.26589543 +2068 1955 37277756.28083 +2069 1955 -57757921.43384 +2082 1955 -10597685.63642 +2083 1955 -8663199.819997 +2084 1955 -17363182.43788 +2085 1955 -44977548.07992 +2086 1955 -694433.6992576 +2087 1955 -59807200.44138 +2088 1955 -11899768.97017 +2089 1955 9357633.519253 +2090 1955 -21458826.37861 +1956 1956 622861433.7406 +1957 1956 1.120567321777e-05 +1958 1956 925940.4229136 +1959 1956 84958459.17911 +1960 1956 -5.066394805908e-06 +1961 1956 231485.1058435 +1974 1956 -52083950.29126 +1975 1956 -36666666.66065 +1976 1956 2453701.89106 +1977 1956 -137627039.3558 +1978 1956 -2.235174179077e-07 +1979 1956 -671303.5447711 +1980 1956 -52107624.53367 +1981 1956 36666666.66065 +1982 1956 -2754631.441411 +2046 1956 -18752053.59425 +2047 1956 9166666.66968 +2048 1956 10539814.37052 +2049 1956 -60367636.82651 +2050 1956 1.877546310425e-06 +2051 1956 44780785.23866 +2052 1956 -20276082.95081 +2053 1956 -9166666.66968 +2054 1956 11841897.70428 +2064 1956 -1865379.213624 +2065 1956 8.79168510437e-07 +2066 1956 57871.26589221 +2067 1956 51054233.83102 +2068 1956 1.788139343262e-06 +2069 1956 231485.0634618 +2070 1956 -7985170.87927 +2071 1956 -2.771615982056e-06 +2072 1956 57871.2658952 +2085 1956 -18848133.13973 +2086 1956 -9166666.66968 +2087 1956 -10597685.63642 +2088 1956 -60775629.25067 +2089 1956 -1.214444637299e-06 +2090 1956 -45012270.30212 +2091 1956 -20383999.6175 +2092 1956 9166666.669679 +2093 1956 -11899768.97017 +1957 1957 534855157.0519 +1958 1957 -11110937.14243 +1959 1957 -3.457069396973e-06 +1960 1957 -54374606.24745 +1961 1957 5722135.237857 +1974 1957 -36666666.66065 +1975 1957 -41083165.69975 +1976 1957 1222200.476822 +1977 1957 4.470348358154e-07 +1978 1957 23707595.23204 +1979 1957 -2777734.286976 +1980 1957 36666666.66065 +1981 1957 -41106839.94217 +1982 1957 1555533.810155 +2046 1957 9166666.66968 +2047 1957 -16001859.73922 +2048 1957 -8593755.37553 +2049 1957 1.169741153717e-06 +2050 1957 -20033981.96478 +2051 1957 -694433.6992575 +2052 1957 -9166666.66968 +2053 1957 -17525889.09577 +2054 1957 9288189.074786 +2064 1957 1.229345798492e-06 +2065 1957 -36698646.37071 +2066 1957 -34527799.26293 +2067 1957 1.966953277588e-06 +2068 1957 29052683.00161 +2069 1957 -2777734.795662 +2070 1957 -2.190470695496e-06 +2071 1957 -42818438.03636 +2072 1957 37305534.05859 +2085 1957 -9166666.669679 +2086 1957 -16097939.2847 +2087 1957 -8663199.819997 +2088 1957 -1.445412635803e-06 +2089 1957 -20441974.38895 +2090 1957 -694433.6992576 +2091 1957 9166666.669678 +2092 1957 -17633805.76247 +2093 1957 9357633.519253 +1958 1958 608211498.9432 +1959 1958 231485.105844 +1960 1958 5388801.904579 +1961 1958 80699306.16691 +1974 1958 2523146.335561 +1975 1958 1277756.032423 +1976 1958 -7296493.499545 +1977 1958 -254636.8781728 +1978 1958 -2777734.286976 +1979 1958 42039227.65673 +1980 1958 -2685186.996909 +1981 1958 1499978.254554 +1982 1958 -7359624.812662 +2046 1958 10539814.37052 +2047 1958 -8593755.37553 +2048 1958 -17106970.31658 +2049 1958 44746063.01646 +2050 1958 -694433.6992574 +2051 1958 -58719220.64359 +2052 1958 11841897.70428 +2053 1958 9288189.074786 +2054 1958 -21171048.60074 +2064 1958 57871.26589252 +2065 1958 -34500021.48517 +2066 1958 -41438476.99211 +2067 1958 231485.0634617 +2068 1958 -2777734.795662 +2069 1958 -127043423.7988 +2070 1958 57871.26589543 +2071 1958 37277756.28083 +2072 1958 -57757921.43384 +2085 1958 -10597685.63642 +2086 1958 -8663199.819997 +2087 1958 -17363182.43788 +2088 1958 -44977548.07992 +2089 1958 -694433.6992576 +2090 1958 -59807200.44138 +2091 1958 -11899768.97017 +2092 1958 9357633.519253 +2093 1958 -21458826.37861 +1959 1959 622861433.7406 +1960 1959 1.120567321777e-05 +1961 1959 925940.4229136 +1962 1959 84958459.17911 +1963 1959 -5.066394805908e-06 +1964 1959 231485.1058435 +1977 1959 -52083950.29126 +1978 1959 -36666666.66065 +1979 1959 2453701.89106 +1980 1959 -137627039.3558 +1981 1959 -2.235174179077e-07 +1982 1959 -671303.5447711 +1983 1959 -52107624.53367 +1984 1959 36666666.66065 +1985 1959 -2754631.441411 +2049 1959 -18752053.59425 +2050 1959 9166666.66968 +2051 1959 10539814.37052 +2052 1959 -60367636.82651 +2053 1959 1.877546310425e-06 +2054 1959 44780785.23866 +2055 1959 -20276082.95081 +2056 1959 -9166666.66968 +2057 1959 11841897.70428 +2067 1959 -1865379.213624 +2068 1959 8.79168510437e-07 +2069 1959 57871.26589221 +2070 1959 51054233.83102 +2071 1959 1.788139343262e-06 +2072 1959 231485.0634618 +2073 1959 -7985170.87927 +2074 1959 -2.771615982056e-06 +2075 1959 57871.2658952 +2088 1959 -18848133.13973 +2089 1959 -9166666.66968 +2090 1959 -10597685.63642 +2091 1959 -60775629.25067 +2092 1959 -1.214444637299e-06 +2093 1959 -45012270.30212 +2094 1959 -20383999.6175 +2095 1959 9166666.669679 +2096 1959 -11899768.97017 +1960 1960 534855157.0519 +1961 1960 -11110937.14243 +1962 1960 -3.457069396973e-06 +1963 1960 -54374606.24745 +1964 1960 5722135.237857 +1977 1960 -36666666.66065 +1978 1960 -41083165.69975 +1979 1960 1222200.476822 +1980 1960 4.470348358154e-07 +1981 1960 23707595.23204 +1982 1960 -2777734.286976 +1983 1960 36666666.66065 +1984 1960 -41106839.94217 +1985 1960 1555533.810155 +2049 1960 9166666.66968 +2050 1960 -16001859.73922 +2051 1960 -8593755.37553 +2052 1960 1.169741153717e-06 +2053 1960 -20033981.96478 +2054 1960 -694433.6992575 +2055 1960 -9166666.66968 +2056 1960 -17525889.09577 +2057 1960 9288189.074786 +2067 1960 1.229345798492e-06 +2068 1960 -36698646.37071 +2069 1960 -34527799.26293 +2070 1960 1.966953277588e-06 +2071 1960 29052683.00161 +2072 1960 -2777734.795662 +2073 1960 -2.190470695496e-06 +2074 1960 -42818438.03636 +2075 1960 37305534.05859 +2088 1960 -9166666.669679 +2089 1960 -16097939.2847 +2090 1960 -8663199.819997 +2091 1960 -1.445412635803e-06 +2092 1960 -20441974.38895 +2093 1960 -694433.6992576 +2094 1960 9166666.669678 +2095 1960 -17633805.76247 +2096 1960 9357633.519253 +1961 1961 608211498.9432 +1962 1961 231485.105844 +1963 1961 5388801.904579 +1964 1961 80699306.16691 +1977 1961 2523146.335561 +1978 1961 1277756.032423 +1979 1961 -7296493.499545 +1980 1961 -254636.8781728 +1981 1961 -2777734.286976 +1982 1961 42039227.65673 +1983 1961 -2685186.996909 +1984 1961 1499978.254554 +1985 1961 -7359624.812662 +2049 1961 10539814.37052 +2050 1961 -8593755.37553 +2051 1961 -17106970.31658 +2052 1961 44746063.01646 +2053 1961 -694433.6992574 +2054 1961 -58719220.64359 +2055 1961 11841897.70428 +2056 1961 9288189.074786 +2057 1961 -21171048.60074 +2067 1961 57871.26589252 +2068 1961 -34500021.48517 +2069 1961 -41438476.99211 +2070 1961 231485.0634617 +2071 1961 -2777734.795662 +2072 1961 -127043423.7988 +2073 1961 57871.26589543 +2074 1961 37277756.28083 +2075 1961 -57757921.43384 +2088 1961 -10597685.63642 +2089 1961 -8663199.819997 +2090 1961 -17363182.43788 +2091 1961 -44977548.07992 +2092 1961 -694433.6992576 +2093 1961 -59807200.44138 +2094 1961 -11899768.97017 +2095 1961 9357633.519253 +2096 1961 -21458826.37861 +1962 1962 622861433.7406 +1963 1962 1.120567321777e-05 +1964 1962 925940.4229136 +1965 1962 84958459.17911 +1966 1962 -5.066394805908e-06 +1967 1962 231485.1058435 +1980 1962 -52083950.29126 +1981 1962 -36666666.66065 +1982 1962 2453701.89106 +1983 1962 -137627039.3558 +1984 1962 -2.235174179077e-07 +1985 1962 -671303.5447711 +1986 1962 -52107624.53367 +1987 1962 36666666.66065 +1988 1962 -2754631.441411 +2052 1962 -18752053.59425 +2053 1962 9166666.66968 +2054 1962 10539814.37052 +2055 1962 -60367636.82651 +2056 1962 1.877546310425e-06 +2057 1962 44780785.23866 +2058 1962 -20276082.95081 +2059 1962 -9166666.66968 +2060 1962 11841897.70428 +2070 1962 -1865379.213624 +2071 1962 8.79168510437e-07 +2072 1962 57871.26589221 +2073 1962 51054233.83102 +2074 1962 1.788139343262e-06 +2075 1962 231485.0634618 +2076 1962 -7985170.87927 +2077 1962 -2.771615982056e-06 +2078 1962 57871.2658952 +2091 1962 -18848133.13973 +2092 1962 -9166666.66968 +2093 1962 -10597685.63642 +2094 1962 -60775629.25067 +2095 1962 -1.214444637299e-06 +2096 1962 -45012270.30212 +2097 1962 -20383999.6175 +2098 1962 9166666.669679 +2099 1962 -11899768.97017 +1963 1963 534855157.0519 +1964 1963 -11110937.14243 +1965 1963 -3.457069396973e-06 +1966 1963 -54374606.24745 +1967 1963 5722135.237857 +1980 1963 -36666666.66065 +1981 1963 -41083165.69975 +1982 1963 1222200.476822 +1983 1963 4.470348358154e-07 +1984 1963 23707595.23204 +1985 1963 -2777734.286976 +1986 1963 36666666.66065 +1987 1963 -41106839.94217 +1988 1963 1555533.810155 +2052 1963 9166666.66968 +2053 1963 -16001859.73922 +2054 1963 -8593755.37553 +2055 1963 1.169741153717e-06 +2056 1963 -20033981.96478 +2057 1963 -694433.6992575 +2058 1963 -9166666.66968 +2059 1963 -17525889.09577 +2060 1963 9288189.074786 +2070 1963 1.229345798492e-06 +2071 1963 -36698646.37071 +2072 1963 -34527799.26293 +2073 1963 1.966953277588e-06 +2074 1963 29052683.00161 +2075 1963 -2777734.795662 +2076 1963 -2.190470695496e-06 +2077 1963 -42818438.03636 +2078 1963 37305534.05859 +2091 1963 -9166666.669679 +2092 1963 -16097939.2847 +2093 1963 -8663199.819997 +2094 1963 -1.445412635803e-06 +2095 1963 -20441974.38895 +2096 1963 -694433.6992576 +2097 1963 9166666.669678 +2098 1963 -17633805.76247 +2099 1963 9357633.519253 +1964 1964 608211498.9432 +1965 1964 231485.105844 +1966 1964 5388801.904579 +1967 1964 80699306.16691 +1980 1964 2523146.335561 +1981 1964 1277756.032423 +1982 1964 -7296493.499545 +1983 1964 -254636.8781728 +1984 1964 -2777734.286976 +1985 1964 42039227.65673 +1986 1964 -2685186.996909 +1987 1964 1499978.254554 +1988 1964 -7359624.812662 +2052 1964 10539814.37052 +2053 1964 -8593755.37553 +2054 1964 -17106970.31658 +2055 1964 44746063.01646 +2056 1964 -694433.6992574 +2057 1964 -58719220.64359 +2058 1964 11841897.70428 +2059 1964 9288189.074786 +2060 1964 -21171048.60074 +2070 1964 57871.26589252 +2071 1964 -34500021.48517 +2072 1964 -41438476.99211 +2073 1964 231485.0634617 +2074 1964 -2777734.795662 +2075 1964 -127043423.7988 +2076 1964 57871.26589543 +2077 1964 37277756.28083 +2078 1964 -57757921.43384 +2091 1964 -10597685.63642 +2092 1964 -8663199.819997 +2093 1964 -17363182.43788 +2094 1964 -44977548.07992 +2095 1964 -694433.6992576 +2096 1964 -59807200.44138 +2097 1964 -11899768.97017 +2098 1964 9357633.519253 +2099 1964 -21458826.37861 +1965 1965 525841223.8952 +1966 1965 16637726.52648 +1967 1965 1326933.388722 +1968 1965 -99403447.86785 +1969 1965 -76875437.99681 +1970 1965 1088428.388042 +1983 1965 -52083950.29126 +1984 1965 -36666666.66065 +1985 1965 2453701.89106 +1986 1965 -86403605.12191 +1987 1965 24246660.24538 +1988 1965 -369310.9342484 +1989 1965 -48005004.3171 +1990 1965 9288464.335591 +1991 1965 -271921.0998234 +2055 1965 -18752053.59425 +2056 1965 9166666.66968 +2057 1965 10539814.37052 +2058 1965 -28689005.84703 +2059 1965 6543380.659943 +2060 1965 25399000.74626 +2073 1965 -1865379.213624 +2074 1965 8.79168510437e-07 +2075 1965 57871.26589221 +2076 1965 60544850.76444 +2077 1965 3603652.033654 +2078 1965 165256.0848025 +2079 1965 -36046786.41637 +2080 1965 -18861624.24183 +2081 1965 11409584.46838 +2094 1965 -18848133.13973 +2095 1965 -9166666.66968 +2096 1965 -10597685.63642 +2097 1965 -45324581.42976 +2098 1965 6015914.059347 +2099 1965 -35313654.50317 +2100 1965 -18251664.62718 +2101 1965 2698677.488894 +2102 1965 -1659648.850827 +1966 1966 652167491.1058 +1967 1966 -7436833.74596 +1968 1966 -76877610.71801 +1969 1966 -257026253.9904 +1970 1966 1869729.751142 +1983 1966 -36666666.66065 +1984 1966 -41083165.69975 +1985 1966 1222200.476822 +1986 1966 24246660.24538 +1987 1966 16665770.31957 +1988 1966 -1278060.764028 +1989 1966 9288464.335591 +1990 1966 -146283568.3526 +1991 1966 1079447.946065 +2055 1966 9166666.66968 +2056 1966 -16001859.73922 +2057 1966 -8593755.37553 +2058 1966 6543892.420133 +2059 1966 7329486.591774 +2060 1966 -6861432.291434 +2073 1966 1.229345798492e-06 +2074 1966 -36698646.37071 +2075 1966 -34527799.26293 +2076 1966 3603652.033653 +2077 1966 90110247.58946 +2078 1966 -1973524.931692 +2079 1966 -18862136.00203 +2080 1966 -74966289.42761 +2081 1966 36320757.18761 +2094 1966 -9166666.669679 +2095 1966 -16097939.2847 +2096 1966 -8663199.819997 +2097 1966 6015914.059347 +2098 1966 -18890115.44135 +2099 1966 7371512.847656 +2100 1966 2698677.488894 +2101 1966 -42017637.42113 +2102 1966 16927872.0975 +1967 1967 515818492.9784 +1968 1967 1157900.733316 +1969 1967 1814231.538681 +1970 1967 -65036963.58215 +1983 1967 2523146.335561 +1984 1967 1277756.032423 +1985 1967 -7296493.499545 +1986 1967 -716533.1564142 +1987 1967 -1222505.208481 +1988 1967 45936875.78449 +1989 1967 -133032.2108206 +1990 1967 1079447.946065 +1991 1967 -34793738.56316 +2055 1967 10539814.37052 +2056 1967 -8593755.37553 +2057 1967 -17106970.31658 +2058 1967 25572605.62664 +2059 1967 -6888721.711543 +2060 1967 -25919946.39859 +2073 1967 57871.26589252 +2074 1967 -34500021.48517 +2075 1967 -41438476.99211 +2076 1967 165435.1762095 +2077 1967 -1973381.627549 +2078 1967 -58670256.12405 +2079 1967 11409680.57863 +2080 1967 36320340.74991 +2081 1967 -47859546.84135 +2094 1967 -10597685.63642 +2095 1967 -8663199.819997 +2096 1967 -17363182.43788 +2097 1967 -35487265.61249 +2098 1967 7371512.849165 +2099 1967 -51354101.90813 +2100 1967 -1659648.850827 +2101 1967 16927872.0975 +2102 1967 -26241528.32399 +1968 1968 584821571.4308 +1969 1968 17544222.98078 +1970 1968 313065.1993893 +1986 1968 -52986235.77516 +1987 1968 -32422879.68721 +1988 1968 281349.1550519 +1989 1968 35144313.475 +1990 1968 39593841.83951 +1991 1968 -575114.6272513 +1992 1968 63970939.87151 +1993 1968 -20632720.36621 +1994 1968 2992.521678209 +1995 1968 -1006153.553093 +1996 1968 28788627.79476 +1997 1968 -68998.16852388 +2058 1968 -53458391.75147 +2059 1968 11001535.28419 +2060 1968 1822748.871423 +2076 1968 -35172500.00353 +2077 1968 -18862136.00203 +2078 1968 -11029051.06911 +2079 1968 35790640.60615 +2080 1968 4298038.396794 +2081 1968 8759735.736302 +2097 1968 -19804774.09007 +2098 1968 -8176439.889684 +2099 1968 -11139057.95335 +2100 1968 -41703527.98086 +2101 1968 9670377.580278 +2102 1968 -43908768.3245 +2103 1968 -23096419.85021 +2104 1968 -5140898.074326 +2105 1968 13676758.60085 +2106 1968 -17236872.81083 +2107 1968 7209522.704775 +2108 1968 -10716254.75056 +1969 1969 1044581457.601 +1970 1969 -5662855.094209 +1986 1969 -32422879.68721 +1987 1969 -16131420.91587 +1988 1969 -129055.109933 +1989 1969 39593841.83951 +1990 1969 162931143.787 +1991 1969 -626977.6637532 +1992 1969 -5966053.701947 +1993 1969 -6589505.676626 +1994 1969 57685.45135477 +1995 1969 28788627.79476 +1996 1969 -23691311.24204 +1997 1969 71068.93951069 +2058 1969 7334356.856125 +2059 1969 -141384271.5067 +2060 1969 -15223117.05093 +2076 1969 -18861624.24184 +2077 1969 -74092003.01479 +2078 1969 -35487648.98173 +2079 1969 4298038.396793 +2080 1969 144981214.6301 +2081 1969 -898589.0163781 +2097 1969 -8176439.889684 +2098 1969 -10839297.49869 +2099 1969 -8997766.816414 +2100 1969 9670377.580277 +2101 1969 -9734323.79071 +2102 1969 7544152.626836 +2103 1969 -1474231.406454 +2104 1969 -40740840.42931 +2105 1969 33347738.67704 +2106 1969 7209522.704775 +2107 1969 -22872324.27073 +2108 1969 16684392.2326 +1970 1970 745776634.0428 +1986 1970 350793.5995534 +1987 1970 -73499.55433191 +1988 1970 -634662.7282902 +1989 1970 -366781.293952 +1990 1970 -571422.1082071 +1991 1970 194003600.4649 +1992 1970 2992.521681309 +1993 1970 57685.45135468 +1994 1970 126095896.7256 +1995 1970 -68998.16849005 +1996 1970 71068.9395107 +1997 1970 41038339.97883 +2058 1970 1215165.914282 +2059 1970 -15709313.95751 +2060 1970 -54629831.58199 +2076 1970 -11028968.11405 +2077 1970 -35488091.42098 +2078 1970 -45528116.40711 +2079 1970 -8774708.705263 +2080 1970 -1927368.836544 +2081 1970 -102472943.4706 +2097 1970 -11139057.95335 +2098 1970 -8997766.816414 +2099 1970 -17461344.76991 +2100 1970 -43908768.32454 +2101 1970 7544152.628345 +2102 1970 -84665181.10733 +2103 1970 5551758.600068 +2104 1970 33347738.67704 +2105 1970 -72767413.37603 +2106 1970 -10716254.75056 +2107 1970 16684392.2326 +2108 1970 -34960091.63584 +1971 1971 311425982.0218 +1972 1971 4.053115844727e-06 +1973 1971 -578696.4550389 +1974 1971 42478440.44814 +1975 1971 7333333.332128 +1976 1971 -578701.8915792 +2061 1971 -60367636.82651 +2062 1971 1.877546310425e-06 +2063 1971 44780785.23866 +2064 1971 -20276082.95081 +2065 1971 -9166666.66968 +2066 1971 11841897.70428 +2082 1971 25526722.3448 +2083 1971 -5.960464477539e-08 +2084 1971 -8946896.355626 +2085 1971 -3992585.439634 +2086 1971 1833333.333934 +2087 1971 -2345231.034498 +1972 1972 267422843.6775 +1973 1972 -5555468.571212 +1974 1972 -7333333.332131 +1975 1972 -27188092.26514 +1976 1972 2833289.841157 +2061 1972 1.169741153717e-06 +2062 1972 -20033981.96478 +2063 1972 -694433.6992575 +2064 1972 -9166666.66968 +2065 1972 -17525889.09577 +2066 1972 9288189.074786 +2082 1972 6.556510925293e-07 +2083 1972 14525946.9301 +2084 1972 -1388867.397833 +2085 1972 -1833333.333937 +2086 1972 -21409219.01818 +2087 1972 18645822.58485 +1973 1973 304093123.209 +1974 1973 462964.7749153 +1975 1973 2722178.730064 +1976 1973 40347548.70635 +2061 1973 44746063.01646 +2062 1973 -694433.6992574 +2063 1973 -58719220.64359 +2064 1973 11841897.70428 +2065 1973 9288189.074786 +2066 1973 -21171048.60074 +2082 1973 9004770.308089 +2083 1973 -1388867.397833 +2084 1973 -63522764.08798 +2085 1973 2403102.300394 +2086 1973 18645822.58486 +2087 1973 -28878960.71692 +1974 1974 311425982.0218 +1975 1974 4.053115844727e-06 +1976 1974 -578696.4550389 +1977 1974 42478440.44814 +1978 1974 7333333.332128 +1979 1974 -578701.8915792 +2061 1974 -18752053.59425 +2062 1974 9166666.66968 +2063 1974 10539814.37052 +2064 1974 -60367636.82651 +2065 1974 1.877546310425e-06 +2066 1974 44780785.23866 +2067 1974 -20276082.95081 +2068 1974 -9166666.66968 +2069 1974 11841897.70428 +2082 1974 -932689.6068121 +2083 1974 -1833333.333935 +2084 1974 -2084814.367748 +2085 1974 25526722.3448 +2086 1974 -5.960464477539e-08 +2087 1974 -8946896.355626 +2088 1974 -3992585.439634 +2089 1974 1833333.333934 +2090 1974 -2345231.034498 +1975 1975 267422843.6775 +1976 1975 -5555468.571212 +1977 1975 -7333333.332131 +1978 1975 -27188092.26514 +1979 1975 2833289.841157 +2061 1975 9166666.66968 +2062 1975 -16001859.73922 +2063 1975 -8593755.37553 +2064 1975 1.169741153717e-06 +2065 1975 -20033981.96478 +2066 1975 -694433.6992575 +2067 1975 -9166666.66968 +2068 1975 -17525889.09577 +2069 1975 9288189.074786 +2082 1975 1833333.333937 +2083 1975 -18349323.18536 +2084 1975 -17256955.18702 +2085 1975 6.556510925293e-07 +2086 1975 14525946.9301 +2087 1975 -1388867.397833 +2088 1975 -1833333.333937 +2089 1975 -21409219.01818 +2090 1975 18645822.58485 +1976 1976 304093123.209 +1977 1976 462964.7749153 +1978 1976 2722178.730064 +1979 1976 40347548.70635 +2061 1976 10539814.37052 +2062 1976 -8593755.37553 +2063 1976 -17106970.31658 +2064 1976 44746063.01646 +2065 1976 -694433.6992574 +2066 1976 -58719220.64359 +2067 1976 11841897.70428 +2068 1976 9288189.074786 +2069 1976 -21171048.60074 +2082 1976 2142685.63364 +2083 1976 -17256955.18703 +2084 1976 -20719238.49606 +2085 1976 9004770.308089 +2086 1976 -1388867.397833 +2087 1976 -63522764.08798 +2088 1976 2403102.300394 +2089 1976 18645822.58486 +2090 1976 -28878960.71692 +1977 1977 311425982.0218 +1978 1977 4.053115844727e-06 +1979 1977 -578696.4550389 +1980 1977 42478440.44814 +1981 1977 7333333.332128 +1982 1977 -578701.8915792 +2064 1977 -18752053.59425 +2065 1977 9166666.66968 +2066 1977 10539814.37052 +2067 1977 -60367636.82651 +2068 1977 1.877546310425e-06 +2069 1977 44780785.23866 +2070 1977 -20276082.95081 +2071 1977 -9166666.66968 +2072 1977 11841897.70428 +2085 1977 -932689.6068121 +2086 1977 -1833333.333935 +2087 1977 -2084814.367748 +2088 1977 25526722.3448 +2089 1977 -5.960464477539e-08 +2090 1977 -8946896.355626 +2091 1977 -3992585.439634 +2092 1977 1833333.333934 +2093 1977 -2345231.034498 +1978 1978 267422843.6775 +1979 1978 -5555468.571212 +1980 1978 -7333333.332131 +1981 1978 -27188092.26514 +1982 1978 2833289.841157 +2064 1978 9166666.66968 +2065 1978 -16001859.73922 +2066 1978 -8593755.37553 +2067 1978 1.169741153717e-06 +2068 1978 -20033981.96478 +2069 1978 -694433.6992575 +2070 1978 -9166666.66968 +2071 1978 -17525889.09577 +2072 1978 9288189.074786 +2085 1978 1833333.333937 +2086 1978 -18349323.18536 +2087 1978 -17256955.18702 +2088 1978 6.556510925293e-07 +2089 1978 14525946.9301 +2090 1978 -1388867.397833 +2091 1978 -1833333.333937 +2092 1978 -21409219.01818 +2093 1978 18645822.58485 +1979 1979 304093123.209 +1980 1979 462964.7749153 +1981 1979 2722178.730064 +1982 1979 40347548.70635 +2064 1979 10539814.37052 +2065 1979 -8593755.37553 +2066 1979 -17106970.31658 +2067 1979 44746063.01646 +2068 1979 -694433.6992574 +2069 1979 -58719220.64359 +2070 1979 11841897.70428 +2071 1979 9288189.074786 +2072 1979 -21171048.60074 +2085 1979 2142685.63364 +2086 1979 -17256955.18703 +2087 1979 -20719238.49606 +2088 1979 9004770.308089 +2089 1979 -1388867.397833 +2090 1979 -63522764.08798 +2091 1979 2403102.300394 +2092 1979 18645822.58486 +2093 1979 -28878960.71692 +1980 1980 311425982.0218 +1981 1980 4.053115844727e-06 +1982 1980 -578696.4550389 +1983 1980 42478440.44814 +1984 1980 7333333.332128 +1985 1980 -578701.8915792 +2067 1980 -18752053.59425 +2068 1980 9166666.66968 +2069 1980 10539814.37052 +2070 1980 -60367636.82651 +2071 1980 1.877546310425e-06 +2072 1980 44780785.23866 +2073 1980 -20276082.95081 +2074 1980 -9166666.66968 +2075 1980 11841897.70428 +2088 1980 -932689.6068121 +2089 1980 -1833333.333935 +2090 1980 -2084814.367748 +2091 1980 25526722.3448 +2092 1980 -5.960464477539e-08 +2093 1980 -8946896.355626 +2094 1980 -3992585.439634 +2095 1980 1833333.333934 +2096 1980 -2345231.034498 +1981 1981 267422843.6775 +1982 1981 -5555468.571212 +1983 1981 -7333333.332131 +1984 1981 -27188092.26514 +1985 1981 2833289.841157 +2067 1981 9166666.66968 +2068 1981 -16001859.73922 +2069 1981 -8593755.37553 +2070 1981 1.169741153717e-06 +2071 1981 -20033981.96478 +2072 1981 -694433.6992575 +2073 1981 -9166666.66968 +2074 1981 -17525889.09577 +2075 1981 9288189.074786 +2088 1981 1833333.333937 +2089 1981 -18349323.18536 +2090 1981 -17256955.18702 +2091 1981 6.556510925293e-07 +2092 1981 14525946.9301 +2093 1981 -1388867.397833 +2094 1981 -1833333.333937 +2095 1981 -21409219.01818 +2096 1981 18645822.58485 +1982 1982 304093123.209 +1983 1982 462964.7749153 +1984 1982 2722178.730064 +1985 1982 40347548.70635 +2067 1982 10539814.37052 +2068 1982 -8593755.37553 +2069 1982 -17106970.31658 +2070 1982 44746063.01646 +2071 1982 -694433.6992574 +2072 1982 -58719220.64359 +2073 1982 11841897.70428 +2074 1982 9288189.074786 +2075 1982 -21171048.60074 +2088 1982 2142685.63364 +2089 1982 -17256955.18703 +2090 1982 -20719238.49606 +2091 1982 9004770.308089 +2092 1982 -1388867.397833 +2093 1982 -63522764.08798 +2094 1982 2403102.300394 +2095 1982 18645822.58486 +2096 1982 -28878960.71692 +1983 1983 311425982.0218 +1984 1983 4.053115844727e-06 +1985 1983 -578696.4550389 +1986 1983 42478440.44814 +1987 1983 7333333.332128 +1988 1983 -578701.8915792 +2070 1983 -18752053.59425 +2071 1983 9166666.66968 +2072 1983 10539814.37052 +2073 1983 -60367636.82651 +2074 1983 1.877546310425e-06 +2075 1983 44780785.23866 +2076 1983 -20276082.95081 +2077 1983 -9166666.66968 +2078 1983 11841897.70428 +2091 1983 -932689.6068121 +2092 1983 -1833333.333935 +2093 1983 -2084814.367748 +2094 1983 25526722.3448 +2095 1983 -5.960464477539e-08 +2096 1983 -8946896.355626 +2097 1983 -3992585.439634 +2098 1983 1833333.333934 +2099 1983 -2345231.034498 +1984 1984 267422843.6775 +1985 1984 -5555468.571212 +1986 1984 -7333333.332131 +1987 1984 -27188092.26514 +1988 1984 2833289.841157 +2070 1984 9166666.66968 +2071 1984 -16001859.73922 +2072 1984 -8593755.37553 +2073 1984 1.169741153717e-06 +2074 1984 -20033981.96478 +2075 1984 -694433.6992575 +2076 1984 -9166666.66968 +2077 1984 -17525889.09577 +2078 1984 9288189.074786 +2091 1984 1833333.333937 +2092 1984 -18349323.18536 +2093 1984 -17256955.18702 +2094 1984 6.556510925293e-07 +2095 1984 14525946.9301 +2096 1984 -1388867.397833 +2097 1984 -1833333.333937 +2098 1984 -21409219.01818 +2099 1984 18645822.58485 +1985 1985 304093123.209 +1986 1985 462964.7749153 +1987 1985 2722178.730064 +1988 1985 40347548.70635 +2070 1985 10539814.37052 +2071 1985 -8593755.37553 +2072 1985 -17106970.31658 +2073 1985 44746063.01646 +2074 1985 -694433.6992574 +2075 1985 -58719220.64359 +2076 1985 11841897.70428 +2077 1985 9288189.074786 +2078 1985 -21171048.60074 +2091 1985 2142685.63364 +2092 1985 -17256955.18703 +2093 1985 -20719238.49606 +2094 1985 9004770.308089 +2095 1985 -1388867.397833 +2096 1985 -63522764.08798 +2097 1985 2403102.300394 +2098 1985 18645822.58486 +2099 1985 -28878960.71692 +1986 1986 310336649.2785 +1987 1986 4244617.814256 +1988 1986 1415596.36294 +1989 1986 -6796753.083789 +1990 1986 -25401731.70095 +1991 1986 61254.30470198 +2073 1986 -18752053.59425 +2074 1986 9166666.66968 +2075 1986 10539814.37052 +2076 1986 -44778234.89159 +2077 1986 6015914.059352 +2078 1986 35041206.59625 +2079 1986 -20008769.25006 +2080 1986 -8176439.889681 +2081 1986 11299136.49846 +2094 1986 -932689.6068121 +2095 1986 -1833333.333935 +2096 1986 -2084814.367748 +2097 1986 25141334.84086 +2098 1986 990425.5084367 +2099 1986 -8447023.847856 +2100 1986 -17627581.50065 +2101 1986 -6163233.013846 +2102 1986 7435569.639298 +1987 1987 292196010.7903 +1988 1987 -3573485.612244 +1989 1987 -40068398.3652 +1990 1987 -69914556.7746 +1991 1987 647333.3904552 +2073 1987 9166666.66968 +2074 1987 -16001859.73922 +2075 1987 -8593755.37553 +2076 1987 6015914.059351 +2077 1987 -18343768.90317 +2078 1987 -8010431.594268 +2079 1987 -8176439.889681 +2080 1987 -11043292.65868 +2081 1987 8953622.07837 +2094 1987 1833333.333937 +2095 1987 -18349323.18536 +2096 1987 -17256955.18702 +2097 1987 990425.5084375 +2098 1987 20357950.52274 +2099 1987 -890124.6000073 +2100 1987 -9829899.681717 +2101 1987 -33577700.03881 +2102 1987 25797644.67844 +1988 1988 310269932.1323 +1989 1988 339032.0824319 +1990 1988 591777.8349088 +1991 1988 23495587.48335 +2073 1988 10539814.37052 +2074 1988 -8593755.37553 +2075 1988 -17106970.31658 +2076 1988 35214817.70936 +2077 1988 -8010431.592745 +2078 1988 -49897177.80632 +2079 1988 11299136.49846 +2080 1988 8953622.07837 +2081 1988 -18005331.86323 +2094 1988 2142685.63364 +2095 1988 -17256955.18703 +2096 1988 -20719238.49606 +2097 1988 9504087.260305 +2098 1988 -890124.6000072 +2099 1988 -62094149.98014 +2100 1988 11975291.86111 +2101 1988 25797644.67693 +2102 1988 -37398448.87766 +1989 1989 356132315.0052 +1990 1989 46610232.79847 +1991 1989 -1088457.435502 +1992 1989 -68991042.43081 +1993 1989 -44544705.52654 +1994 1989 104612.942561 +1995 1989 14049779.30499 +1996 1989 -10879435.08183 +1997 1989 33514.80409205 +2076 1989 -17800014.26928 +2077 1989 2698677.488893 +2078 1989 1551462.261342 +2079 1989 -41550567.91137 +2080 1989 9670377.580283 +2081 1989 43763453.88329 +2097 1989 -16877239.2765 +2098 1989 -9829899.681722 +2099 1989 -11739430.35753 +2100 1989 -5864347.079577 +2101 1989 11272333.02856 +2102 1989 -8862175.675498 +2103 1989 -34156706.14972 +2104 1989 -11123810.63458 +2105 1989 20338606.37075 +2106 1989 -25110571.33565 +2107 1989 -2687677.781431 +2108 1989 7481972.406576 +1990 1990 441394973.0897 +1991 1990 -1397462.91879 +1992 1990 -44544705.52654 +1993 1990 -49185644.57119 +1994 1990 71068.93951051 +1995 1990 -25546101.74609 +1996 1990 -57408739.22477 +1997 1990 226590.3065475 +2076 1990 2698677.488893 +2077 1990 -41565987.06324 +2078 1990 -16405461.24678 +2079 1990 9670377.580283 +2080 1990 -9581363.721229 +2081 1990 -7837791.815088 +2097 1990 -6163233.01385 +2098 1990 -32827357.81467 +2099 1990 -25487077.53535 +2100 1990 11272333.02856 +2101 1990 14803293.44955 +2102 1990 -343891.8558928 +2103 1990 -11123810.63458 +2104 1990 -29217261.77281 +2105 1990 16684392.2326 +2106 1990 -6354344.449302 +2107 1990 -42970769.09971 +2108 1990 33389830.22049 +1991 1991 483682368.7122 +1992 1991 104612.942561 +1993 1991 71068.93951043 +1994 1991 15544006.64969 +1995 1991 102959.2485223 +1996 1991 226590.3065475 +1997 1991 68824463.12898 +2076 1991 1551462.261342 +2077 1991 -16405461.24678 +2078 1991 -25037127.36958 +2079 1991 43763453.88333 +2080 1991 -7837791.813566 +2081 1991 -84257287.58871 +2097 1991 -7303874.802406 +2098 1991 -25487077.53687 +2099 1991 -35397536.2799 +2100 1991 8672268.766067 +2101 1991 -343891.8558926 +2102 1991 -131666276.7598 +2103 1991 20338606.37075 +2104 1991 16684392.2326 +2105 1991 -41305029.13792 +2106 1991 11778916.85432 +2107 1991 33389830.22049 +2108 1991 -59295265.58963 +1992 1992 235232090.372 +1993 1992 49966053.69473 +1994 1992 -60862.89202046 +1995 1992 -6442290.85687 +1996 1992 544705.5337606 +1997 1992 -46742.57221824 +2079 1992 -23001722.8805 +2080 1992 -1474231.406455 +2081 1992 -5550324.72933 +2100 1992 -34062009.18001 +2101 1992 -11123810.63458 +2102 1992 -20286393.64259 +2103 1992 -19349792.24124 +2104 1992 12474231.41007 +2105 1992 8109815.470699 +2106 1992 -35471324.17617 +2107 1992 123810.6309668 +2108 1992 -31023097.09878 +1993 1993 216417535.9348 +1994 1993 -57685.45134497 +1995 1993 15211372.19802 +1996 1993 63127311.26884 +1997 1993 -71068.9395045 +2079 1993 -5140898.074327 +2080 1993 -40646143.4596 +2081 1993 -33318927.97868 +2100 1993 -11123810.63458 +2101 1993 -29122564.8031 +2102 1993 -16648941.11168 +2103 1993 12474231.41007 +2104 1993 -24049121.66948 +2105 1993 6652261.316389 +2106 1993 3790477.298838 +2107 1993 -18067018.54574 +2108 1993 3315607.773964 +1994 1994 344070517.3109 +1995 1994 -46742.57221502 +1996 1994 -71068.9395045 +1997 1994 111008771.196 +2079 1994 -13675324.7301 +2080 1994 -33318927.97868 +2081 1994 -72514888.12347 +2100 1994 -20286393.64259 +2101 1994 -16648941.11168 +2102 1994 -41052503.88534 +2103 1994 -8140184.526632 +2104 1994 -6681072.014753 +2105 1994 -122349568.8948 +2106 1994 -31023097.10068 +2107 1994 -3351058.894892 +2108 1994 -62442635.03753 +1995 1995 175028968.1491 +1996 1995 -18453898.24669 +1997 1995 -126107.3967482 +2079 1995 -17142175.84111 +2080 1995 7209522.704776 +2081 1995 10681661.92314 +2100 1995 -24826480.42668 +2101 1995 -6354344.449306 +2102 1995 -11727749.81249 +2103 1995 -35471324.17617 +2104 1995 3790477.298842 +2105 1995 30999819.5577 +2106 1995 -13375171.0781 +2107 1995 -4645655.554312 +2108 1995 -4310953.890546 +1996 1996 199603042.2421 +1997 1996 -226590.3065325 +2079 1996 7209522.704776 +2080 1996 -22777627.30101 +2081 1996 -16648941.11168 +2100 1996 -2687677.781434 +2101 1996 -42686678.19075 +2102 1996 -33276836.43523 +2103 1996 123810.63097 +2104 1996 -18067018.54574 +2105 1996 3315607.773964 +2106 1996 -4645655.554311 +2107 1996 -7283827.484575 +2108 1996 6610169.772934 +1997 1997 263475900.4805 +2079 1997 10681661.92314 +2080 1997 -16648941.11168 +2081 1997 -34707566.38326 +2100 1997 -7465527.586963 +2101 1997 -33276836.43523 +2102 1997 -58537689.83235 +2103 1997 30999819.55581 +2104 1997 -3351058.894892 +2105 1997 -62442635.03753 +2106 1997 4248212.774715 +2107 1997 -6723163.558209 +2108 1997 -86485846.13902 +1998 1998 391468094.7324 +1999 1998 36666666.66066 +2000 1998 2662170.757228 +2001 1998 -201885224.5025 +2002 1998 -36666959.01753 +2003 1998 -2662149.068675 +2004 1998 13006025.1815 +2005 1998 29333625.68539 +2006 1998 -2152798.772422 +2109 1998 31947394.33292 +2110 1998 9166666.669681 +2111 1998 9728225.899101 +2112 1998 -74358253.63036 +2113 1998 -9166739.758898 +2114 1998 -45562288.72778 +2115 1998 -8166156.136015 +2116 1998 7333406.424962 +2117 1998 -9496761.446847 +1999 1999 336463888.7559 +2000 1999 -6944377.543016 +2001 1999 -36667105.19596 +2002 1999 -29548916.09098 +2003 1999 -3847225.37168 +2004 1999 44000438.52809 +2005 1999 13006025.1815 +2006 1999 2416691.307227 +2109 1999 9166666.66968 +2110 1999 18196342.83202 +2111 1999 5513941.008134 +2112 1999 -9166776.303507 +2113 1999 -31274176.50627 +2114 1999 -9941080.210835 +2115 1999 11000109.63744 +2116 1999 -8166156.136015 +2117 1999 11395946.69513 +2000 2000 385940866.4962 +2001 2000 -2662138.224395 +2002 2000 -3097217.158151 +2003 2000 2281351.682023 +2004 2000 -3229198.158633 +2005 2000 1611127.538151 +2006 2000 34682733.81733 +2109 2000 -8223530.275229 +2110 2000 -8847241.586827 +2111 2000 -79300461.72417 +2112 2000 -45527563.96779 +2113 2000 -9746597.980308 +2114 2000 -63128188.69225 +2115 2000 -14245142.17027 +2116 2000 7597297.796754 +2117 2000 -21776416.36271 +2001 2001 677810035.2011 +2002 2001 36667397.55284 +2003 2001 3125086.662505 +2004 2001 20859938.00677 +2005 2001 -36666959.01753 +2006 2001 2702569.081896 +2007 2001 -136819701.2443 +2008 2001 9.089708328247e-07 +2009 2001 -462970.1266867 +2010 2001 -51905201.38891 +2011 2001 36666666.66065 +2012 2001 -2702548.086863 +2109 2001 -72726245.22972 +2110 2001 -9166776.303506 +2111 2001 44231216.90386 +2112 2001 70575234.21716 +2113 2001 9166849.392726 +2114 2001 781227.3439141 +2115 2001 -20203256.3538 +2116 2001 -9166739.758899 +2117 2001 11899863.74724 +2118 2001 -60775629.25067 +2119 2001 -1.214444637299e-06 +2120 2001 -45012270.30212 +2121 2001 -20383999.6175 +2122 2001 9166666.669679 +2123 2001 -11899768.97017 +2002 2002 578802727.5875 +2003 2002 -8610918.562153 +2004 2002 -36667105.19596 +2005 2002 -107472939.8429 +2006 2002 4611020.401354 +2007 2002 9.685754776001e-07 +2008 2002 24514918.12315 +2009 2002 -2777734.795656 +2010 2002 36666666.66065 +2011 2002 -40904425.97421 +2012 2002 1513867.397816 +2109 2002 -9166739.758897 +2110 2002 -29642168.10562 +2111 2002 8204934.122165 +2112 2002 9166849.392726 +2113 2002 45823407.30156 +2114 2002 -2152765.098743 +2115 2002 -9166776.303508 +2116 2002 -52286475.83204 +2117 2002 37069600.58987 +2118 2002 -1.445412635803e-06 +2119 2002 -20441974.38895 +2120 2002 -694433.6992576 +2121 2002 9166666.669678 +2122 2002 -17633805.76247 +2123 2002 9357633.519253 +2003 2003 623143279.9755 +2004 2003 2737301.801614 +2005 2003 5388806.115241 +2006 2003 41364580.11227 +2007 2003 -462970.1266864 +2008 2003 -2777734.795656 +2009 2003 44192040.0554 +2010 2003 -2737270.309063 +2011 2003 1541645.175575 +2012 2003 -6819846.696327 +2109 2003 44196492.14387 +2110 2003 8010523.495484 +2111 2003 -58776166.2905 +2112 2003 781316.8545274 +2113 2003 -2152693.49136 +2114 2003 -107886912.3736 +2115 2003 11899911.13577 +2116 2003 37236269.31883 +2117 2003 -57440830.58835 +2118 2003 -44977548.07992 +2119 2003 -694433.6992576 +2120 2003 -59807200.44138 +2121 2003 -11899768.97017 +2122 2003 9357633.519253 +2123 2003 -21458826.37861 +2004 2004 391468094.7324 +2005 2004 36666666.66066 +2006 2004 2662170.757228 +2007 2004 -51881527.1465 +2008 2004 -36666666.66065 +2009 2004 2505785.245605 +2010 2004 -201885224.5025 +2011 2004 -36666959.01753 +2012 2004 -2662149.068675 +2013 2004 13006025.1815 +2014 2004 29333625.68539 +2015 2004 -2152798.772422 +2109 2004 -5106206.927443 +2110 2004 11000109.63744 +2111 2004 12682625.90274 +2112 2004 -15511422.68773 +2113 2004 -9166776.303506 +2114 2004 -10539940.2691 +2115 2004 31947394.33292 +2116 2004 9166666.669681 +2117 2004 9728225.899101 +2118 2004 -18848133.13973 +2119 2004 -9166666.66968 +2120 2004 -10597685.63642 +2121 2004 -74358253.63036 +2122 2004 -9166739.758898 +2123 2004 -45562288.72778 +2124 2004 -8166156.136015 +2125 2004 7333406.424962 +2126 2004 -9496761.446847 +2005 2005 336463888.7559 +2006 2005 -6944377.543016 +2007 2005 -36666666.66065 +2008 2005 -40880751.7318 +2009 2005 1263867.397843 +2010 2005 -36667105.19596 +2011 2005 -29548916.09098 +2012 2005 -3847225.37168 +2013 2005 44000438.52809 +2014 2005 13006025.1815 +2015 2005 2416691.307227 +2109 2005 7333406.424962 +2110 2005 -5106206.927443 +2111 2005 -6763956.526763 +2112 2005 -9166739.758897 +2113 2005 -47594642.16596 +2114 2005 -34569643.89832 +2115 2005 9166666.66968 +2116 2005 18196342.83202 +2117 2005 5513941.008134 +2118 2005 -9166666.669679 +2119 2005 -16097939.2847 +2120 2005 -8663199.819997 +2121 2005 -9166776.303507 +2122 2005 -31274176.50627 +2123 2005 -9941080.210835 +2124 2005 11000109.63744 +2125 2005 -8166156.136015 +2126 2005 11395946.69513 +2006 2006 385940866.4962 +2007 2006 2471063.023406 +2008 2006 1236089.620084 +2009 2006 -6756715.38321 +2010 2006 -2662138.224395 +2011 2006 -3097217.158151 +2012 2006 2281351.682023 +2013 2006 -3229198.158633 +2014 2006 1611127.538151 +2015 2006 34682733.81733 +2109 2006 8455083.935158 +2110 2006 -10145934.79014 +2111 2006 -13616551.80652 +2112 2006 -10539898.30291 +2113 2006 -34736312.74845 +2114 2006 -44929274.14549 +2115 2006 -8223530.275229 +2116 2006 -8847241.586827 +2117 2006 -79300461.72417 +2118 2006 -10597685.63642 +2119 2006 -8663199.819997 +2120 2006 -17363182.43788 +2121 2006 -45527563.96779 +2122 2006 -9746597.980308 +2123 2006 -63128188.69225 +2124 2006 -14245142.17027 +2125 2006 7597297.796754 +2126 2006 -21776416.36271 +2007 2007 626081101.6128 +2008 2007 7.033348083496e-06 +2009 2007 925940.2533548 +2010 2007 85765730.61463 +2011 2007 -3.814697265625e-06 +2012 2007 231485.0634534 +2016 2007 -136819701.2443 +2017 2007 9.089708328247e-07 +2018 2007 -462970.1266867 +2019 2007 -51905201.38891 +2020 2007 36666666.66065 +2021 2007 -2702548.086863 +2112 2007 -60367636.82651 +2113 2007 1.877546310425e-06 +2114 2007 44780785.23866 +2115 2007 -20276082.95081 +2116 2007 -9166666.66968 +2117 2007 11841897.70428 +2118 2007 51054233.83102 +2119 2007 1.788139343262e-06 +2120 2007 231485.0634618 +2121 2007 -7985170.87927 +2122 2007 -2.771615982056e-06 +2123 2007 57871.2658952 +2127 2007 -60775629.25067 +2128 2007 -1.214444637299e-06 +2129 2007 -45012270.30212 +2130 2007 -20383999.6175 +2131 2007 9166666.669679 +2132 2007 -11899768.97017 +2008 2008 538074898.3386 +2009 2008 -11110939.17715 +2010 2008 -2.861022949219e-06 +2011 2008 -53567337.94508 +2012 2008 5555469.588581 +2016 2008 9.685754776001e-07 +2017 2008 24514918.12315 +2018 2008 -2777734.795656 +2019 2008 36666666.66065 +2020 2008 -40904425.97421 +2021 2008 1513867.397816 +2112 2008 1.169741153717e-06 +2113 2008 -20033981.96478 +2114 2008 -694433.6992575 +2115 2008 -9166666.66968 +2116 2008 -17525889.09577 +2117 2008 9288189.074786 +2118 2008 1.966953277588e-06 +2119 2008 29052683.00161 +2120 2008 -2777734.795662 +2121 2008 -2.190470695496e-06 +2122 2008 -42818438.03636 +2123 2008 37305534.05859 +2127 2008 -1.445412635803e-06 +2128 2008 -20441974.38895 +2129 2008 -694433.6992576 +2130 2008 9166666.669678 +2131 2008 -17633805.76247 +2132 2008 9357633.519253 +2009 2009 616797415.4266 +2010 2009 231485.0634536 +2011 2009 5555469.588581 +2012 2009 82852085.35441 +2016 2009 -462970.1266864 +2017 2009 -2777734.795656 +2018 2009 44192040.0554 +2019 2009 -2737270.309063 +2020 2009 1541645.175575 +2021 2009 -6819846.696327 +2112 2009 44746063.01646 +2113 2009 -694433.6992574 +2114 2009 -58719220.64359 +2115 2009 11841897.70428 +2116 2009 9288189.074786 +2117 2009 -21171048.60074 +2118 2009 231485.0634617 +2119 2009 -2777734.795662 +2120 2009 -127043423.7988 +2121 2009 57871.26589543 +2122 2009 37277756.28083 +2123 2009 -57757921.43384 +2127 2009 -44977548.07992 +2128 2009 -694433.6992576 +2129 2009 -59807200.44138 +2130 2009 -11899768.97017 +2131 2009 9357633.519253 +2132 2009 -21458826.37861 +2010 2010 677810035.2011 +2011 2010 36667397.55284 +2012 2010 3125086.662505 +2013 2010 20859938.00677 +2014 2010 -36666959.01753 +2015 2010 2702569.081896 +2016 2010 -51881527.1465 +2017 2010 -36666666.66065 +2018 2010 2505785.245605 +2019 2010 -136819701.2443 +2020 2010 9.089708328247e-07 +2021 2010 -462970.1266867 +2022 2010 -51905201.38891 +2023 2010 36666666.66065 +2024 2010 -2702548.086863 +2112 2010 -18752053.59425 +2113 2010 9166666.66968 +2114 2010 10539814.37052 +2115 2010 -72726245.22972 +2116 2010 -9166776.303506 +2117 2010 44231216.90386 +2118 2010 -1865379.213624 +2119 2010 8.79168510437e-07 +2120 2010 57871.26589221 +2121 2010 70575234.21716 +2122 2010 9166849.392726 +2123 2010 781227.3439141 +2124 2010 -20203256.3538 +2125 2010 -9166739.758899 +2126 2010 11899863.74724 +2127 2010 -18848133.13973 +2128 2010 -9166666.66968 +2129 2010 -10597685.63642 +2130 2010 -60775629.25067 +2131 2010 -1.214444637299e-06 +2132 2010 -45012270.30212 +2133 2010 -20383999.6175 +2134 2010 9166666.669679 +2135 2010 -11899768.97017 +2011 2011 578802727.5875 +2012 2011 -8610918.562153 +2013 2011 -36667105.19596 +2014 2011 -107472939.8429 +2015 2011 4611020.401354 +2016 2011 -36666666.66065 +2017 2011 -40880751.7318 +2018 2011 1263867.397843 +2019 2011 9.685754776001e-07 +2020 2011 24514918.12315 +2021 2011 -2777734.795656 +2022 2011 36666666.66065 +2023 2011 -40904425.97421 +2024 2011 1513867.397816 +2112 2011 9166666.66968 +2113 2011 -16001859.73922 +2114 2011 -8593755.37553 +2115 2011 -9166739.758897 +2116 2011 -29642168.10562 +2117 2011 8204934.122165 +2118 2011 1.229345798492e-06 +2119 2011 -36698646.37071 +2120 2011 -34527799.26293 +2121 2011 9166849.392726 +2122 2011 45823407.30156 +2123 2011 -2152765.098743 +2124 2011 -9166776.303508 +2125 2011 -52286475.83204 +2126 2011 37069600.58987 +2127 2011 -9166666.669679 +2128 2011 -16097939.2847 +2129 2011 -8663199.819997 +2130 2011 -1.445412635803e-06 +2131 2011 -20441974.38895 +2132 2011 -694433.6992576 +2133 2011 9166666.669678 +2134 2011 -17633805.76247 +2135 2011 9357633.519253 +2012 2012 623143279.9755 +2013 2012 2737301.801614 +2014 2012 5388806.115241 +2015 2012 41364580.11227 +2016 2012 2471063.023406 +2017 2012 1236089.620084 +2018 2012 -6756715.38321 +2019 2012 -462970.1266864 +2020 2012 -2777734.795656 +2021 2012 44192040.0554 +2022 2012 -2737270.309063 +2023 2012 1541645.175575 +2024 2012 -6819846.696327 +2112 2012 10539814.37052 +2113 2012 -8593755.37553 +2114 2012 -17106970.31658 +2115 2012 44196492.14387 +2116 2012 8010523.495484 +2117 2012 -58776166.2905 +2118 2012 57871.26589252 +2119 2012 -34500021.48517 +2120 2012 -41438476.99211 +2121 2012 781316.8545274 +2122 2012 -2152693.49136 +2123 2012 -107886912.3736 +2124 2012 11899911.13577 +2125 2012 37236269.31883 +2126 2012 -57440830.58835 +2127 2012 -10597685.63642 +2128 2012 -8663199.819997 +2129 2012 -17363182.43788 +2130 2012 -44977548.07992 +2131 2012 -694433.6992576 +2132 2012 -59807200.44138 +2133 2012 -11899768.97017 +2134 2012 9357633.519253 +2135 2012 -21458826.37861 +2013 2013 391468094.7324 +2014 2013 36666666.66066 +2015 2013 2662170.757228 +2019 2013 -51881527.1465 +2020 2013 -36666666.66065 +2021 2013 2505785.245605 +2022 2013 -201885224.5025 +2023 2013 -36666959.01753 +2024 2013 -2662149.068675 +2025 2013 13006025.1815 +2026 2013 29333625.68539 +2027 2013 -2152798.772422 +2115 2013 -5106206.927443 +2116 2013 11000109.63744 +2117 2013 12682625.90274 +2121 2013 -15511422.68773 +2122 2013 -9166776.303506 +2123 2013 -10539940.2691 +2124 2013 31947394.33292 +2125 2013 9166666.669681 +2126 2013 9728225.899101 +2130 2013 -18848133.13973 +2131 2013 -9166666.66968 +2132 2013 -10597685.63642 +2133 2013 -74358253.63036 +2134 2013 -9166739.758898 +2135 2013 -45562288.72778 +2136 2013 -8166156.136015 +2137 2013 7333406.424962 +2138 2013 -9496761.446847 +2014 2014 336463888.7559 +2015 2014 -6944377.543016 +2019 2014 -36666666.66065 +2020 2014 -40880751.7318 +2021 2014 1263867.397843 +2022 2014 -36667105.19596 +2023 2014 -29548916.09098 +2024 2014 -3847225.37168 +2025 2014 44000438.52809 +2026 2014 13006025.1815 +2027 2014 2416691.307227 +2115 2014 7333406.424962 +2116 2014 -5106206.927443 +2117 2014 -6763956.526763 +2121 2014 -9166739.758897 +2122 2014 -47594642.16596 +2123 2014 -34569643.89832 +2124 2014 9166666.66968 +2125 2014 18196342.83202 +2126 2014 5513941.008134 +2130 2014 -9166666.669679 +2131 2014 -16097939.2847 +2132 2014 -8663199.819997 +2133 2014 -9166776.303507 +2134 2014 -31274176.50627 +2135 2014 -9941080.210835 +2136 2014 11000109.63744 +2137 2014 -8166156.136015 +2138 2014 11395946.69513 +2015 2015 385940866.4962 +2019 2015 2471063.023406 +2020 2015 1236089.620084 +2021 2015 -6756715.38321 +2022 2015 -2662138.224395 +2023 2015 -3097217.158151 +2024 2015 2281351.682023 +2025 2015 -3229198.158633 +2026 2015 1611127.538151 +2027 2015 34682733.81733 +2115 2015 8455083.935158 +2116 2015 -10145934.79014 +2117 2015 -13616551.80652 +2121 2015 -10539898.30291 +2122 2015 -34736312.74845 +2123 2015 -44929274.14549 +2124 2015 -8223530.275229 +2125 2015 -8847241.586827 +2126 2015 -79300461.72417 +2130 2015 -10597685.63642 +2131 2015 -8663199.819997 +2132 2015 -17363182.43788 +2133 2015 -45527563.96779 +2134 2015 -9746597.980308 +2135 2015 -63128188.69225 +2136 2015 -14245142.17027 +2137 2015 7597297.796754 +2138 2015 -21776416.36271 +2016 2016 626081101.6128 +2017 2016 7.033348083496e-06 +2018 2016 925940.2533548 +2019 2016 85765730.61463 +2020 2016 -3.814697265625e-06 +2021 2016 231485.0634534 +2028 2016 -136819701.2443 +2029 2016 9.089708328247e-07 +2030 2016 -462970.1266867 +2031 2016 -51905201.38891 +2032 2016 36666666.66065 +2033 2016 -2702548.086863 +2118 2016 -60367636.82651 +2119 2016 1.877546310425e-06 +2120 2016 44780785.23866 +2121 2016 -20276082.95081 +2122 2016 -9166666.66968 +2123 2016 11841897.70428 +2127 2016 51054233.83102 +2128 2016 1.788139343262e-06 +2129 2016 231485.0634618 +2130 2016 -7985170.87927 +2131 2016 -2.771615982056e-06 +2132 2016 57871.2658952 +2139 2016 -60775629.25067 +2140 2016 -1.214444637299e-06 +2141 2016 -45012270.30212 +2142 2016 -20383999.6175 +2143 2016 9166666.669679 +2144 2016 -11899768.97017 +2017 2017 538074898.3386 +2018 2017 -11110939.17715 +2019 2017 -2.861022949219e-06 +2020 2017 -53567337.94508 +2021 2017 5555469.588581 +2028 2017 9.685754776001e-07 +2029 2017 24514918.12315 +2030 2017 -2777734.795656 +2031 2017 36666666.66065 +2032 2017 -40904425.97421 +2033 2017 1513867.397816 +2118 2017 1.169741153717e-06 +2119 2017 -20033981.96478 +2120 2017 -694433.6992575 +2121 2017 -9166666.66968 +2122 2017 -17525889.09577 +2123 2017 9288189.074786 +2127 2017 1.966953277588e-06 +2128 2017 29052683.00161 +2129 2017 -2777734.795662 +2130 2017 -2.190470695496e-06 +2131 2017 -42818438.03636 +2132 2017 37305534.05859 +2139 2017 -1.445412635803e-06 +2140 2017 -20441974.38895 +2141 2017 -694433.6992576 +2142 2017 9166666.669678 +2143 2017 -17633805.76247 +2144 2017 9357633.519253 +2018 2018 616797415.4266 +2019 2018 231485.0634536 +2020 2018 5555469.588581 +2021 2018 82852085.35441 +2028 2018 -462970.1266864 +2029 2018 -2777734.795656 +2030 2018 44192040.0554 +2031 2018 -2737270.309063 +2032 2018 1541645.175575 +2033 2018 -6819846.696327 +2118 2018 44746063.01646 +2119 2018 -694433.6992574 +2120 2018 -58719220.64359 +2121 2018 11841897.70428 +2122 2018 9288189.074786 +2123 2018 -21171048.60074 +2127 2018 231485.0634617 +2128 2018 -2777734.795662 +2129 2018 -127043423.7988 +2130 2018 57871.26589543 +2131 2018 37277756.28083 +2132 2018 -57757921.43384 +2139 2018 -44977548.07992 +2140 2018 -694433.6992576 +2141 2018 -59807200.44138 +2142 2018 -11899768.97017 +2143 2018 9357633.519253 +2144 2018 -21458826.37861 +2019 2019 626081101.6128 +2020 2019 7.033348083496e-06 +2021 2019 925940.2533548 +2022 2019 85765730.61463 +2023 2019 -3.814697265625e-06 +2024 2019 231485.0634534 +2028 2019 -51881527.1465 +2029 2019 -36666666.66065 +2030 2019 2505785.245605 +2031 2019 -136819701.2443 +2032 2019 9.089708328247e-07 +2033 2019 -462970.1266867 +2034 2019 -51905201.38891 +2035 2019 36666666.66065 +2036 2019 -2702548.086863 +2118 2019 -18752053.59425 +2119 2019 9166666.66968 +2120 2019 10539814.37052 +2121 2019 -60367636.82651 +2122 2019 1.877546310425e-06 +2123 2019 44780785.23866 +2124 2019 -20276082.95081 +2125 2019 -9166666.66968 +2126 2019 11841897.70428 +2127 2019 -1865379.213624 +2128 2019 8.79168510437e-07 +2129 2019 57871.26589221 +2130 2019 51054233.83102 +2131 2019 1.788139343262e-06 +2132 2019 231485.0634618 +2133 2019 -7985170.87927 +2134 2019 -2.771615982056e-06 +2135 2019 57871.2658952 +2139 2019 -18848133.13973 +2140 2019 -9166666.66968 +2141 2019 -10597685.63642 +2142 2019 -60775629.25067 +2143 2019 -1.214444637299e-06 +2144 2019 -45012270.30212 +2145 2019 -20383999.6175 +2146 2019 9166666.669679 +2147 2019 -11899768.97017 +2020 2020 538074898.3386 +2021 2020 -11110939.17715 +2022 2020 -2.861022949219e-06 +2023 2020 -53567337.94508 +2024 2020 5555469.588581 +2028 2020 -36666666.66065 +2029 2020 -40880751.7318 +2030 2020 1263867.397843 +2031 2020 9.685754776001e-07 +2032 2020 24514918.12315 +2033 2020 -2777734.795656 +2034 2020 36666666.66065 +2035 2020 -40904425.97421 +2036 2020 1513867.397816 +2118 2020 9166666.66968 +2119 2020 -16001859.73922 +2120 2020 -8593755.37553 +2121 2020 1.169741153717e-06 +2122 2020 -20033981.96478 +2123 2020 -694433.6992575 +2124 2020 -9166666.66968 +2125 2020 -17525889.09577 +2126 2020 9288189.074786 +2127 2020 1.229345798492e-06 +2128 2020 -36698646.37071 +2129 2020 -34527799.26293 +2130 2020 1.966953277588e-06 +2131 2020 29052683.00161 +2132 2020 -2777734.795662 +2133 2020 -2.190470695496e-06 +2134 2020 -42818438.03636 +2135 2020 37305534.05859 +2139 2020 -9166666.669679 +2140 2020 -16097939.2847 +2141 2020 -8663199.819997 +2142 2020 -1.445412635803e-06 +2143 2020 -20441974.38895 +2144 2020 -694433.6992576 +2145 2020 9166666.669678 +2146 2020 -17633805.76247 +2147 2020 9357633.519253 +2021 2021 616797415.4266 +2022 2021 231485.0634536 +2023 2021 5555469.588581 +2024 2021 82852085.35441 +2028 2021 2471063.023406 +2029 2021 1236089.620084 +2030 2021 -6756715.38321 +2031 2021 -462970.1266864 +2032 2021 -2777734.795656 +2033 2021 44192040.0554 +2034 2021 -2737270.309063 +2035 2021 1541645.175575 +2036 2021 -6819846.696327 +2118 2021 10539814.37052 +2119 2021 -8593755.37553 +2120 2021 -17106970.31658 +2121 2021 44746063.01646 +2122 2021 -694433.6992574 +2123 2021 -58719220.64359 +2124 2021 11841897.70428 +2125 2021 9288189.074786 +2126 2021 -21171048.60074 +2127 2021 57871.26589252 +2128 2021 -34500021.48517 +2129 2021 -41438476.99211 +2130 2021 231485.0634617 +2131 2021 -2777734.795662 +2132 2021 -127043423.7988 +2133 2021 57871.26589543 +2134 2021 37277756.28083 +2135 2021 -57757921.43384 +2139 2021 -10597685.63642 +2140 2021 -8663199.819997 +2141 2021 -17363182.43788 +2142 2021 -44977548.07992 +2143 2021 -694433.6992576 +2144 2021 -59807200.44138 +2145 2021 -11899768.97017 +2146 2021 9357633.519253 +2147 2021 -21458826.37861 +2022 2022 677810035.2011 +2023 2022 36667397.55284 +2024 2022 3125086.662505 +2025 2022 20859938.00677 +2026 2022 -36666959.01753 +2027 2022 2702569.081896 +2031 2022 -51881527.1465 +2032 2022 -36666666.66065 +2033 2022 2505785.245605 +2034 2022 -136819701.2443 +2035 2022 9.089708328247e-07 +2036 2022 -462970.1266867 +2037 2022 -51905201.38891 +2038 2022 36666666.66065 +2039 2022 -2702548.086863 +2121 2022 -18752053.59425 +2122 2022 9166666.66968 +2123 2022 10539814.37052 +2124 2022 -72726245.22972 +2125 2022 -9166776.303506 +2126 2022 44231216.90386 +2130 2022 -1865379.213624 +2131 2022 8.79168510437e-07 +2132 2022 57871.26589221 +2133 2022 70575234.21716 +2134 2022 9166849.392726 +2135 2022 781227.3439141 +2136 2022 -20203256.3538 +2137 2022 -9166739.758899 +2138 2022 11899863.74724 +2142 2022 -18848133.13973 +2143 2022 -9166666.66968 +2144 2022 -10597685.63642 +2145 2022 -60775629.25067 +2146 2022 -1.214444637299e-06 +2147 2022 -45012270.30212 +2148 2022 -20383999.6175 +2149 2022 9166666.669679 +2150 2022 -11899768.97017 +2023 2023 578802727.5875 +2024 2023 -8610918.562153 +2025 2023 -36667105.19596 +2026 2023 -107472939.8429 +2027 2023 4611020.401354 +2031 2023 -36666666.66065 +2032 2023 -40880751.7318 +2033 2023 1263867.397843 +2034 2023 9.685754776001e-07 +2035 2023 24514918.12315 +2036 2023 -2777734.795656 +2037 2023 36666666.66065 +2038 2023 -40904425.97421 +2039 2023 1513867.397816 +2121 2023 9166666.66968 +2122 2023 -16001859.73922 +2123 2023 -8593755.37553 +2124 2023 -9166739.758897 +2125 2023 -29642168.10562 +2126 2023 8204934.122165 +2130 2023 1.229345798492e-06 +2131 2023 -36698646.37071 +2132 2023 -34527799.26293 +2133 2023 9166849.392726 +2134 2023 45823407.30156 +2135 2023 -2152765.098743 +2136 2023 -9166776.303508 +2137 2023 -52286475.83204 +2138 2023 37069600.58987 +2142 2023 -9166666.669679 +2143 2023 -16097939.2847 +2144 2023 -8663199.819997 +2145 2023 -1.445412635803e-06 +2146 2023 -20441974.38895 +2147 2023 -694433.6992576 +2148 2023 9166666.669678 +2149 2023 -17633805.76247 +2150 2023 9357633.519253 +2024 2024 623143279.9755 +2025 2024 2737301.801614 +2026 2024 5388806.115241 +2027 2024 41364580.11227 +2031 2024 2471063.023406 +2032 2024 1236089.620084 +2033 2024 -6756715.38321 +2034 2024 -462970.1266864 +2035 2024 -2777734.795656 +2036 2024 44192040.0554 +2037 2024 -2737270.309063 +2038 2024 1541645.175575 +2039 2024 -6819846.696327 +2121 2024 10539814.37052 +2122 2024 -8593755.37553 +2123 2024 -17106970.31658 +2124 2024 44196492.14387 +2125 2024 8010523.495484 +2126 2024 -58776166.2905 +2130 2024 57871.26589252 +2131 2024 -34500021.48517 +2132 2024 -41438476.99211 +2133 2024 781316.8545274 +2134 2024 -2152693.49136 +2135 2024 -107886912.3736 +2136 2024 11899911.13577 +2137 2024 37236269.31883 +2138 2024 -57440830.58835 +2142 2024 -10597685.63642 +2143 2024 -8663199.819997 +2144 2024 -17363182.43788 +2145 2024 -44977548.07992 +2146 2024 -694433.6992576 +2147 2024 -59807200.44138 +2148 2024 -11899768.97017 +2149 2024 9357633.519253 +2150 2024 -21458826.37861 +2025 2025 391468094.7324 +2026 2025 36666666.66066 +2027 2025 2662170.757228 +2034 2025 -51881527.1465 +2035 2025 -36666666.66065 +2036 2025 2505785.245605 +2037 2025 -201885224.5025 +2038 2025 -36666959.01753 +2039 2025 -2662149.068675 +2040 2025 13006025.1815 +2041 2025 29333625.68539 +2042 2025 -2152798.772422 +2124 2025 -5106206.927443 +2125 2025 11000109.63744 +2126 2025 12682625.90274 +2133 2025 -15511422.68773 +2134 2025 -9166776.303506 +2135 2025 -10539940.2691 +2136 2025 31947394.33292 +2137 2025 9166666.669681 +2138 2025 9728225.899101 +2145 2025 -18848133.13973 +2146 2025 -9166666.66968 +2147 2025 -10597685.63642 +2148 2025 -74358253.63036 +2149 2025 -9166739.758898 +2150 2025 -45562288.72778 +2151 2025 -8166156.136015 +2152 2025 7333406.424962 +2153 2025 -9496761.446847 +2026 2026 336463888.7559 +2027 2026 -6944377.543016 +2034 2026 -36666666.66065 +2035 2026 -40880751.7318 +2036 2026 1263867.397843 +2037 2026 -36667105.19596 +2038 2026 -29548916.09098 +2039 2026 -3847225.37168 +2040 2026 44000438.52809 +2041 2026 13006025.1815 +2042 2026 2416691.307227 +2124 2026 7333406.424962 +2125 2026 -5106206.927443 +2126 2026 -6763956.526763 +2133 2026 -9166739.758897 +2134 2026 -47594642.16596 +2135 2026 -34569643.89832 +2136 2026 9166666.66968 +2137 2026 18196342.83202 +2138 2026 5513941.008134 +2145 2026 -9166666.669679 +2146 2026 -16097939.2847 +2147 2026 -8663199.819997 +2148 2026 -9166776.303507 +2149 2026 -31274176.50627 +2150 2026 -9941080.210835 +2151 2026 11000109.63744 +2152 2026 -8166156.136015 +2153 2026 11395946.69513 +2027 2027 385940866.4962 +2034 2027 2471063.023406 +2035 2027 1236089.620084 +2036 2027 -6756715.38321 +2037 2027 -2662138.224395 +2038 2027 -3097217.158151 +2039 2027 2281351.682023 +2040 2027 -3229198.158633 +2041 2027 1611127.538151 +2042 2027 34682733.81733 +2124 2027 8455083.935158 +2125 2027 -10145934.79014 +2126 2027 -13616551.80652 +2133 2027 -10539898.30291 +2134 2027 -34736312.74845 +2135 2027 -44929274.14549 +2136 2027 -8223530.275229 +2137 2027 -8847241.586827 +2138 2027 -79300461.72417 +2145 2027 -10597685.63642 +2146 2027 -8663199.819997 +2147 2027 -17363182.43788 +2148 2027 -45527563.96779 +2149 2027 -9746597.980308 +2150 2027 -63128188.69225 +2151 2027 -14245142.17027 +2152 2027 7597297.796754 +2153 2027 -21776416.36271 +2028 2028 626081101.6128 +2029 2028 7.033348083496e-06 +2030 2028 925940.2533548 +2031 2028 85765730.61463 +2032 2028 -3.814697265625e-06 +2033 2028 231485.0634534 +2043 2028 -136819701.2443 +2044 2028 9.089708328247e-07 +2045 2028 -462970.1266867 +2046 2028 -51905201.38891 +2047 2028 36666666.66065 +2048 2028 -2702548.086863 +2127 2028 -60367636.82651 +2128 2028 1.877546310425e-06 +2129 2028 44780785.23866 +2130 2028 -20276082.95081 +2131 2028 -9166666.66968 +2132 2028 11841897.70428 +2139 2028 51054233.83102 +2140 2028 1.788139343262e-06 +2141 2028 231485.0634618 +2142 2028 -7985170.87927 +2143 2028 -2.771615982056e-06 +2144 2028 57871.2658952 +2154 2028 -60775629.25067 +2155 2028 -1.214444637299e-06 +2156 2028 -45012270.30212 +2157 2028 -20383999.6175 +2158 2028 9166666.669679 +2159 2028 -11899768.97017 +2029 2029 538074898.3386 +2030 2029 -11110939.17715 +2031 2029 -2.861022949219e-06 +2032 2029 -53567337.94508 +2033 2029 5555469.588581 +2043 2029 9.685754776001e-07 +2044 2029 24514918.12315 +2045 2029 -2777734.795656 +2046 2029 36666666.66065 +2047 2029 -40904425.97421 +2048 2029 1513867.397816 +2127 2029 1.169741153717e-06 +2128 2029 -20033981.96478 +2129 2029 -694433.6992575 +2130 2029 -9166666.66968 +2131 2029 -17525889.09577 +2132 2029 9288189.074786 +2139 2029 1.966953277588e-06 +2140 2029 29052683.00161 +2141 2029 -2777734.795662 +2142 2029 -2.190470695496e-06 +2143 2029 -42818438.03636 +2144 2029 37305534.05859 +2154 2029 -1.445412635803e-06 +2155 2029 -20441974.38895 +2156 2029 -694433.6992576 +2157 2029 9166666.669678 +2158 2029 -17633805.76247 +2159 2029 9357633.519253 +2030 2030 616797415.4266 +2031 2030 231485.0634536 +2032 2030 5555469.588581 +2033 2030 82852085.35441 +2043 2030 -462970.1266864 +2044 2030 -2777734.795656 +2045 2030 44192040.0554 +2046 2030 -2737270.309063 +2047 2030 1541645.175575 +2048 2030 -6819846.696327 +2127 2030 44746063.01646 +2128 2030 -694433.6992574 +2129 2030 -58719220.64359 +2130 2030 11841897.70428 +2131 2030 9288189.074786 +2132 2030 -21171048.60074 +2139 2030 231485.0634617 +2140 2030 -2777734.795662 +2141 2030 -127043423.7988 +2142 2030 57871.26589543 +2143 2030 37277756.28083 +2144 2030 -57757921.43384 +2154 2030 -44977548.07992 +2155 2030 -694433.6992576 +2156 2030 -59807200.44138 +2157 2030 -11899768.97017 +2158 2030 9357633.519253 +2159 2030 -21458826.37861 +2031 2031 626081101.6128 +2032 2031 7.033348083496e-06 +2033 2031 925940.2533548 +2034 2031 85765730.61463 +2035 2031 -3.814697265625e-06 +2036 2031 231485.0634534 +2043 2031 -51881527.1465 +2044 2031 -36666666.66065 +2045 2031 2505785.245605 +2046 2031 -136819701.2443 +2047 2031 9.089708328247e-07 +2048 2031 -462970.1266867 +2049 2031 -51905201.38891 +2050 2031 36666666.66065 +2051 2031 -2702548.086863 +2127 2031 -18752053.59425 +2128 2031 9166666.66968 +2129 2031 10539814.37052 +2130 2031 -60367636.82651 +2131 2031 1.877546310425e-06 +2132 2031 44780785.23866 +2133 2031 -20276082.95081 +2134 2031 -9166666.66968 +2135 2031 11841897.70428 +2139 2031 -1865379.213624 +2140 2031 8.79168510437e-07 +2141 2031 57871.26589221 +2142 2031 51054233.83102 +2143 2031 1.788139343262e-06 +2144 2031 231485.0634618 +2145 2031 -7985170.87927 +2146 2031 -2.771615982056e-06 +2147 2031 57871.2658952 +2154 2031 -18848133.13973 +2155 2031 -9166666.66968 +2156 2031 -10597685.63642 +2157 2031 -60775629.25067 +2158 2031 -1.214444637299e-06 +2159 2031 -45012270.30212 +2160 2031 -20383999.6175 +2161 2031 9166666.669679 +2162 2031 -11899768.97017 +2032 2032 538074898.3386 +2033 2032 -11110939.17715 +2034 2032 -2.861022949219e-06 +2035 2032 -53567337.94508 +2036 2032 5555469.588581 +2043 2032 -36666666.66065 +2044 2032 -40880751.7318 +2045 2032 1263867.397843 +2046 2032 9.685754776001e-07 +2047 2032 24514918.12315 +2048 2032 -2777734.795656 +2049 2032 36666666.66065 +2050 2032 -40904425.97421 +2051 2032 1513867.397816 +2127 2032 9166666.66968 +2128 2032 -16001859.73922 +2129 2032 -8593755.37553 +2130 2032 1.169741153717e-06 +2131 2032 -20033981.96478 +2132 2032 -694433.6992575 +2133 2032 -9166666.66968 +2134 2032 -17525889.09577 +2135 2032 9288189.074786 +2139 2032 1.229345798492e-06 +2140 2032 -36698646.37071 +2141 2032 -34527799.26293 +2142 2032 1.966953277588e-06 +2143 2032 29052683.00161 +2144 2032 -2777734.795662 +2145 2032 -2.190470695496e-06 +2146 2032 -42818438.03636 +2147 2032 37305534.05859 +2154 2032 -9166666.669679 +2155 2032 -16097939.2847 +2156 2032 -8663199.819997 +2157 2032 -1.445412635803e-06 +2158 2032 -20441974.38895 +2159 2032 -694433.6992576 +2160 2032 9166666.669678 +2161 2032 -17633805.76247 +2162 2032 9357633.519253 +2033 2033 616797415.4266 +2034 2033 231485.0634536 +2035 2033 5555469.588581 +2036 2033 82852085.35441 +2043 2033 2471063.023406 +2044 2033 1236089.620084 +2045 2033 -6756715.38321 +2046 2033 -462970.1266864 +2047 2033 -2777734.795656 +2048 2033 44192040.0554 +2049 2033 -2737270.309063 +2050 2033 1541645.175575 +2051 2033 -6819846.696327 +2127 2033 10539814.37052 +2128 2033 -8593755.37553 +2129 2033 -17106970.31658 +2130 2033 44746063.01646 +2131 2033 -694433.6992574 +2132 2033 -58719220.64359 +2133 2033 11841897.70428 +2134 2033 9288189.074786 +2135 2033 -21171048.60074 +2139 2033 57871.26589252 +2140 2033 -34500021.48517 +2141 2033 -41438476.99211 +2142 2033 231485.0634617 +2143 2033 -2777734.795662 +2144 2033 -127043423.7988 +2145 2033 57871.26589543 +2146 2033 37277756.28083 +2147 2033 -57757921.43384 +2154 2033 -10597685.63642 +2155 2033 -8663199.819997 +2156 2033 -17363182.43788 +2157 2033 -44977548.07992 +2158 2033 -694433.6992576 +2159 2033 -59807200.44138 +2160 2033 -11899768.97017 +2161 2033 9357633.519253 +2162 2033 -21458826.37861 +2034 2034 626081101.6128 +2035 2034 7.033348083496e-06 +2036 2034 925940.2533548 +2037 2034 85765730.61463 +2038 2034 -3.814697265625e-06 +2039 2034 231485.0634534 +2046 2034 -51881527.1465 +2047 2034 -36666666.66065 +2048 2034 2505785.245605 +2049 2034 -136819701.2443 +2050 2034 9.089708328247e-07 +2051 2034 -462970.1266867 +2052 2034 -51905201.38891 +2053 2034 36666666.66065 +2054 2034 -2702548.086863 +2130 2034 -18752053.59425 +2131 2034 9166666.66968 +2132 2034 10539814.37052 +2133 2034 -60367636.82651 +2134 2034 1.877546310425e-06 +2135 2034 44780785.23866 +2136 2034 -20276082.95081 +2137 2034 -9166666.66968 +2138 2034 11841897.70428 +2142 2034 -1865379.213624 +2143 2034 8.79168510437e-07 +2144 2034 57871.26589221 +2145 2034 51054233.83102 +2146 2034 1.788139343262e-06 +2147 2034 231485.0634618 +2148 2034 -7985170.87927 +2149 2034 -2.771615982056e-06 +2150 2034 57871.2658952 +2157 2034 -18848133.13973 +2158 2034 -9166666.66968 +2159 2034 -10597685.63642 +2160 2034 -60775629.25067 +2161 2034 -1.214444637299e-06 +2162 2034 -45012270.30212 +2163 2034 -20383999.6175 +2164 2034 9166666.669679 +2165 2034 -11899768.97017 +2035 2035 538074898.3386 +2036 2035 -11110939.17715 +2037 2035 -2.861022949219e-06 +2038 2035 -53567337.94508 +2039 2035 5555469.588581 +2046 2035 -36666666.66065 +2047 2035 -40880751.7318 +2048 2035 1263867.397843 +2049 2035 9.685754776001e-07 +2050 2035 24514918.12315 +2051 2035 -2777734.795656 +2052 2035 36666666.66065 +2053 2035 -40904425.97421 +2054 2035 1513867.397816 +2130 2035 9166666.66968 +2131 2035 -16001859.73922 +2132 2035 -8593755.37553 +2133 2035 1.169741153717e-06 +2134 2035 -20033981.96478 +2135 2035 -694433.6992575 +2136 2035 -9166666.66968 +2137 2035 -17525889.09577 +2138 2035 9288189.074786 +2142 2035 1.229345798492e-06 +2143 2035 -36698646.37071 +2144 2035 -34527799.26293 +2145 2035 1.966953277588e-06 +2146 2035 29052683.00161 +2147 2035 -2777734.795662 +2148 2035 -2.190470695496e-06 +2149 2035 -42818438.03636 +2150 2035 37305534.05859 +2157 2035 -9166666.669679 +2158 2035 -16097939.2847 +2159 2035 -8663199.819997 +2160 2035 -1.445412635803e-06 +2161 2035 -20441974.38895 +2162 2035 -694433.6992576 +2163 2035 9166666.669678 +2164 2035 -17633805.76247 +2165 2035 9357633.519253 +2036 2036 616797415.4266 +2037 2036 231485.0634536 +2038 2036 5555469.588581 +2039 2036 82852085.35441 +2046 2036 2471063.023406 +2047 2036 1236089.620084 +2048 2036 -6756715.38321 +2049 2036 -462970.1266864 +2050 2036 -2777734.795656 +2051 2036 44192040.0554 +2052 2036 -2737270.309063 +2053 2036 1541645.175575 +2054 2036 -6819846.696327 +2130 2036 10539814.37052 +2131 2036 -8593755.37553 +2132 2036 -17106970.31658 +2133 2036 44746063.01646 +2134 2036 -694433.6992574 +2135 2036 -58719220.64359 +2136 2036 11841897.70428 +2137 2036 9288189.074786 +2138 2036 -21171048.60074 +2142 2036 57871.26589252 +2143 2036 -34500021.48517 +2144 2036 -41438476.99211 +2145 2036 231485.0634617 +2146 2036 -2777734.795662 +2147 2036 -127043423.7988 +2148 2036 57871.26589543 +2149 2036 37277756.28083 +2150 2036 -57757921.43384 +2157 2036 -10597685.63642 +2158 2036 -8663199.819997 +2159 2036 -17363182.43788 +2160 2036 -44977548.07992 +2161 2036 -694433.6992576 +2162 2036 -59807200.44138 +2163 2036 -11899768.97017 +2164 2036 9357633.519253 +2165 2036 -21458826.37861 +2037 2037 677810035.2011 +2038 2037 36667397.55284 +2039 2037 3125086.662505 +2040 2037 20859938.00677 +2041 2037 -36666959.01753 +2042 2037 2702569.081896 +2049 2037 -51881527.1465 +2050 2037 -36666666.66065 +2051 2037 2505785.245605 +2052 2037 -136819701.2443 +2053 2037 9.089708328247e-07 +2054 2037 -462970.1266867 +2055 2037 -51905201.38891 +2056 2037 36666666.66065 +2057 2037 -2702548.086863 +2133 2037 -18752053.59425 +2134 2037 9166666.66968 +2135 2037 10539814.37052 +2136 2037 -72726245.22972 +2137 2037 -9166776.303506 +2138 2037 44231216.90386 +2145 2037 -1865379.213624 +2146 2037 8.79168510437e-07 +2147 2037 57871.26589221 +2148 2037 70575234.21716 +2149 2037 9166849.392726 +2150 2037 781227.3439141 +2151 2037 -20203256.3538 +2152 2037 -9166739.758899 +2153 2037 11899863.74724 +2160 2037 -18848133.13973 +2161 2037 -9166666.66968 +2162 2037 -10597685.63642 +2163 2037 -60775629.25067 +2164 2037 -1.214444637299e-06 +2165 2037 -45012270.30212 +2166 2037 -20383999.6175 +2167 2037 9166666.669679 +2168 2037 -11899768.97017 +2038 2038 578802727.5875 +2039 2038 -8610918.562153 +2040 2038 -36667105.19596 +2041 2038 -107472939.8429 +2042 2038 4611020.401354 +2049 2038 -36666666.66065 +2050 2038 -40880751.7318 +2051 2038 1263867.397843 +2052 2038 9.685754776001e-07 +2053 2038 24514918.12315 +2054 2038 -2777734.795656 +2055 2038 36666666.66065 +2056 2038 -40904425.97421 +2057 2038 1513867.397816 +2133 2038 9166666.66968 +2134 2038 -16001859.73922 +2135 2038 -8593755.37553 +2136 2038 -9166739.758897 +2137 2038 -29642168.10562 +2138 2038 8204934.122165 +2145 2038 1.229345798492e-06 +2146 2038 -36698646.37071 +2147 2038 -34527799.26293 +2148 2038 9166849.392726 +2149 2038 45823407.30156 +2150 2038 -2152765.098743 +2151 2038 -9166776.303508 +2152 2038 -52286475.83204 +2153 2038 37069600.58987 +2160 2038 -9166666.669679 +2161 2038 -16097939.2847 +2162 2038 -8663199.819997 +2163 2038 -1.445412635803e-06 +2164 2038 -20441974.38895 +2165 2038 -694433.6992576 +2166 2038 9166666.669678 +2167 2038 -17633805.76247 +2168 2038 9357633.519253 +2039 2039 623143279.9755 +2040 2039 2737301.801614 +2041 2039 5388806.115241 +2042 2039 41364580.11227 +2049 2039 2471063.023406 +2050 2039 1236089.620084 +2051 2039 -6756715.38321 +2052 2039 -462970.1266864 +2053 2039 -2777734.795656 +2054 2039 44192040.0554 +2055 2039 -2737270.309063 +2056 2039 1541645.175575 +2057 2039 -6819846.696327 +2133 2039 10539814.37052 +2134 2039 -8593755.37553 +2135 2039 -17106970.31658 +2136 2039 44196492.14387 +2137 2039 8010523.495484 +2138 2039 -58776166.2905 +2145 2039 57871.26589252 +2146 2039 -34500021.48517 +2147 2039 -41438476.99211 +2148 2039 781316.8545274 +2149 2039 -2152693.49136 +2150 2039 -107886912.3736 +2151 2039 11899911.13577 +2152 2039 37236269.31883 +2153 2039 -57440830.58835 +2160 2039 -10597685.63642 +2161 2039 -8663199.819997 +2162 2039 -17363182.43788 +2163 2039 -44977548.07992 +2164 2039 -694433.6992576 +2165 2039 -59807200.44138 +2166 2039 -11899768.97017 +2167 2039 9357633.519253 +2168 2039 -21458826.37861 +2040 2040 391468094.7324 +2041 2040 36666666.66066 +2042 2040 2662170.757228 +2052 2040 -51881527.1465 +2053 2040 -36666666.66065 +2054 2040 2505785.245605 +2055 2040 -201885224.5025 +2056 2040 -36666959.01753 +2057 2040 -2662149.068675 +2058 2040 13006025.1815 +2059 2040 29333625.68539 +2060 2040 -2152798.772422 +2136 2040 -5106206.927443 +2137 2040 11000109.63744 +2138 2040 12682625.90274 +2148 2040 -15511422.68773 +2149 2040 -9166776.303506 +2150 2040 -10539940.2691 +2151 2040 31947394.33292 +2152 2040 9166666.669681 +2153 2040 9728225.899101 +2163 2040 -18848133.13973 +2164 2040 -9166666.66968 +2165 2040 -10597685.63642 +2166 2040 -74358253.63036 +2167 2040 -9166739.758898 +2168 2040 -45562288.72778 +2169 2040 -8166156.136015 +2170 2040 7333406.424962 +2171 2040 -9496761.446847 +2041 2041 336463888.7559 +2042 2041 -6944377.543016 +2052 2041 -36666666.66065 +2053 2041 -40880751.7318 +2054 2041 1263867.397843 +2055 2041 -36667105.19596 +2056 2041 -29548916.09098 +2057 2041 -3847225.37168 +2058 2041 44000438.52809 +2059 2041 13006025.1815 +2060 2041 2416691.307227 +2136 2041 7333406.424962 +2137 2041 -5106206.927443 +2138 2041 -6763956.526763 +2148 2041 -9166739.758897 +2149 2041 -47594642.16596 +2150 2041 -34569643.89832 +2151 2041 9166666.66968 +2152 2041 18196342.83202 +2153 2041 5513941.008134 +2163 2041 -9166666.669679 +2164 2041 -16097939.2847 +2165 2041 -8663199.819997 +2166 2041 -9166776.303507 +2167 2041 -31274176.50627 +2168 2041 -9941080.210835 +2169 2041 11000109.63744 +2170 2041 -8166156.136015 +2171 2041 11395946.69513 +2042 2042 385940866.4962 +2052 2042 2471063.023406 +2053 2042 1236089.620084 +2054 2042 -6756715.38321 +2055 2042 -2662138.224395 +2056 2042 -3097217.158151 +2057 2042 2281351.682023 +2058 2042 -3229198.158633 +2059 2042 1611127.538151 +2060 2042 34682733.81733 +2136 2042 8455083.935158 +2137 2042 -10145934.79014 +2138 2042 -13616551.80652 +2148 2042 -10539898.30291 +2149 2042 -34736312.74845 +2150 2042 -44929274.14549 +2151 2042 -8223530.275229 +2152 2042 -8847241.586827 +2153 2042 -79300461.72417 +2163 2042 -10597685.63642 +2164 2042 -8663199.819997 +2165 2042 -17363182.43788 +2166 2042 -45527563.96779 +2167 2042 -9746597.980308 +2168 2042 -63128188.69225 +2169 2042 -14245142.17027 +2170 2042 7597297.796754 +2171 2042 -21776416.36271 +2043 2043 626081101.6128 +2044 2043 7.033348083496e-06 +2045 2043 925940.2533548 +2046 2043 85765730.61463 +2047 2043 -3.814697265625e-06 +2048 2043 231485.0634534 +2061 2043 -136819701.2443 +2062 2043 9.089708328247e-07 +2063 2043 -462970.1266867 +2064 2043 -51905201.38891 +2065 2043 36666666.66065 +2066 2043 -2702548.086863 +2139 2043 -60367636.82651 +2140 2043 1.877546310425e-06 +2141 2043 44780785.23866 +2142 2043 -20276082.95081 +2143 2043 -9166666.66968 +2144 2043 11841897.70428 +2154 2043 51054233.83102 +2155 2043 1.788139343262e-06 +2156 2043 231485.0634618 +2157 2043 -7985170.87927 +2158 2043 -2.771615982056e-06 +2159 2043 57871.2658952 +2172 2043 -60775629.25067 +2173 2043 -1.214444637299e-06 +2174 2043 -45012270.30212 +2175 2043 -20383999.6175 +2176 2043 9166666.669679 +2177 2043 -11899768.97017 +2044 2044 538074898.3386 +2045 2044 -11110939.17715 +2046 2044 -2.861022949219e-06 +2047 2044 -53567337.94508 +2048 2044 5555469.588581 +2061 2044 9.685754776001e-07 +2062 2044 24514918.12315 +2063 2044 -2777734.795656 +2064 2044 36666666.66065 +2065 2044 -40904425.97421 +2066 2044 1513867.397816 +2139 2044 1.169741153717e-06 +2140 2044 -20033981.96478 +2141 2044 -694433.6992575 +2142 2044 -9166666.66968 +2143 2044 -17525889.09577 +2144 2044 9288189.074786 +2154 2044 1.966953277588e-06 +2155 2044 29052683.00161 +2156 2044 -2777734.795662 +2157 2044 -2.190470695496e-06 +2158 2044 -42818438.03636 +2159 2044 37305534.05859 +2172 2044 -1.445412635803e-06 +2173 2044 -20441974.38895 +2174 2044 -694433.6992576 +2175 2044 9166666.669678 +2176 2044 -17633805.76247 +2177 2044 9357633.519253 +2045 2045 616797415.4266 +2046 2045 231485.0634536 +2047 2045 5555469.588581 +2048 2045 82852085.35441 +2061 2045 -462970.1266864 +2062 2045 -2777734.795656 +2063 2045 44192040.0554 +2064 2045 -2737270.309063 +2065 2045 1541645.175575 +2066 2045 -6819846.696327 +2139 2045 44746063.01646 +2140 2045 -694433.6992574 +2141 2045 -58719220.64359 +2142 2045 11841897.70428 +2143 2045 9288189.074786 +2144 2045 -21171048.60074 +2154 2045 231485.0634617 +2155 2045 -2777734.795662 +2156 2045 -127043423.7988 +2157 2045 57871.26589543 +2158 2045 37277756.28083 +2159 2045 -57757921.43384 +2172 2045 -44977548.07992 +2173 2045 -694433.6992576 +2174 2045 -59807200.44138 +2175 2045 -11899768.97017 +2176 2045 9357633.519253 +2177 2045 -21458826.37861 +2046 2046 626081101.6128 +2047 2046 7.033348083496e-06 +2048 2046 925940.2533548 +2049 2046 85765730.61463 +2050 2046 -3.814697265625e-06 +2051 2046 231485.0634534 +2061 2046 -51881527.1465 +2062 2046 -36666666.66065 +2063 2046 2505785.245605 +2064 2046 -136819701.2443 +2065 2046 9.089708328247e-07 +2066 2046 -462970.1266867 +2067 2046 -51905201.38891 +2068 2046 36666666.66065 +2069 2046 -2702548.086863 +2139 2046 -18752053.59425 +2140 2046 9166666.66968 +2141 2046 10539814.37052 +2142 2046 -60367636.82651 +2143 2046 1.877546310425e-06 +2144 2046 44780785.23866 +2145 2046 -20276082.95081 +2146 2046 -9166666.66968 +2147 2046 11841897.70428 +2154 2046 -1865379.213624 +2155 2046 8.79168510437e-07 +2156 2046 57871.26589221 +2157 2046 51054233.83102 +2158 2046 1.788139343262e-06 +2159 2046 231485.0634618 +2160 2046 -7985170.87927 +2161 2046 -2.771615982056e-06 +2162 2046 57871.2658952 +2172 2046 -18848133.13973 +2173 2046 -9166666.66968 +2174 2046 -10597685.63642 +2175 2046 -60775629.25067 +2176 2046 -1.214444637299e-06 +2177 2046 -45012270.30212 +2178 2046 -20383999.6175 +2179 2046 9166666.669679 +2180 2046 -11899768.97017 +2047 2047 538074898.3386 +2048 2047 -11110939.17715 +2049 2047 -2.861022949219e-06 +2050 2047 -53567337.94508 +2051 2047 5555469.588581 +2061 2047 -36666666.66065 +2062 2047 -40880751.7318 +2063 2047 1263867.397843 +2064 2047 9.685754776001e-07 +2065 2047 24514918.12315 +2066 2047 -2777734.795656 +2067 2047 36666666.66065 +2068 2047 -40904425.97421 +2069 2047 1513867.397816 +2139 2047 9166666.66968 +2140 2047 -16001859.73922 +2141 2047 -8593755.37553 +2142 2047 1.169741153717e-06 +2143 2047 -20033981.96478 +2144 2047 -694433.6992575 +2145 2047 -9166666.66968 +2146 2047 -17525889.09577 +2147 2047 9288189.074786 +2154 2047 1.229345798492e-06 +2155 2047 -36698646.37071 +2156 2047 -34527799.26293 +2157 2047 1.966953277588e-06 +2158 2047 29052683.00161 +2159 2047 -2777734.795662 +2160 2047 -2.190470695496e-06 +2161 2047 -42818438.03636 +2162 2047 37305534.05859 +2172 2047 -9166666.669679 +2173 2047 -16097939.2847 +2174 2047 -8663199.819997 +2175 2047 -1.445412635803e-06 +2176 2047 -20441974.38895 +2177 2047 -694433.6992576 +2178 2047 9166666.669678 +2179 2047 -17633805.76247 +2180 2047 9357633.519253 +2048 2048 616797415.4266 +2049 2048 231485.0634536 +2050 2048 5555469.588581 +2051 2048 82852085.35441 +2061 2048 2471063.023406 +2062 2048 1236089.620084 +2063 2048 -6756715.38321 +2064 2048 -462970.1266864 +2065 2048 -2777734.795656 +2066 2048 44192040.0554 +2067 2048 -2737270.309063 +2068 2048 1541645.175575 +2069 2048 -6819846.696327 +2139 2048 10539814.37052 +2140 2048 -8593755.37553 +2141 2048 -17106970.31658 +2142 2048 44746063.01646 +2143 2048 -694433.6992574 +2144 2048 -58719220.64359 +2145 2048 11841897.70428 +2146 2048 9288189.074786 +2147 2048 -21171048.60074 +2154 2048 57871.26589252 +2155 2048 -34500021.48517 +2156 2048 -41438476.99211 +2157 2048 231485.0634617 +2158 2048 -2777734.795662 +2159 2048 -127043423.7988 +2160 2048 57871.26589543 +2161 2048 37277756.28083 +2162 2048 -57757921.43384 +2172 2048 -10597685.63642 +2173 2048 -8663199.819997 +2174 2048 -17363182.43788 +2175 2048 -44977548.07992 +2176 2048 -694433.6992576 +2177 2048 -59807200.44138 +2178 2048 -11899768.97017 +2179 2048 9357633.519253 +2180 2048 -21458826.37861 +2049 2049 626081101.6128 +2050 2049 7.033348083496e-06 +2051 2049 925940.2533548 +2052 2049 85765730.61463 +2053 2049 -3.814697265625e-06 +2054 2049 231485.0634534 +2064 2049 -51881527.1465 +2065 2049 -36666666.66065 +2066 2049 2505785.245605 +2067 2049 -136819701.2443 +2068 2049 9.089708328247e-07 +2069 2049 -462970.1266867 +2070 2049 -51905201.38891 +2071 2049 36666666.66065 +2072 2049 -2702548.086863 +2142 2049 -18752053.59425 +2143 2049 9166666.66968 +2144 2049 10539814.37052 +2145 2049 -60367636.82651 +2146 2049 1.877546310425e-06 +2147 2049 44780785.23866 +2148 2049 -20276082.95081 +2149 2049 -9166666.66968 +2150 2049 11841897.70428 +2157 2049 -1865379.213624 +2158 2049 8.79168510437e-07 +2159 2049 57871.26589221 +2160 2049 51054233.83102 +2161 2049 1.788139343262e-06 +2162 2049 231485.0634618 +2163 2049 -7985170.87927 +2164 2049 -2.771615982056e-06 +2165 2049 57871.2658952 +2175 2049 -18848133.13973 +2176 2049 -9166666.66968 +2177 2049 -10597685.63642 +2178 2049 -60775629.25067 +2179 2049 -1.214444637299e-06 +2180 2049 -45012270.30212 +2181 2049 -20383999.6175 +2182 2049 9166666.669679 +2183 2049 -11899768.97017 +2050 2050 538074898.3386 +2051 2050 -11110939.17715 +2052 2050 -2.861022949219e-06 +2053 2050 -53567337.94508 +2054 2050 5555469.588581 +2064 2050 -36666666.66065 +2065 2050 -40880751.7318 +2066 2050 1263867.397843 +2067 2050 9.685754776001e-07 +2068 2050 24514918.12315 +2069 2050 -2777734.795656 +2070 2050 36666666.66065 +2071 2050 -40904425.97421 +2072 2050 1513867.397816 +2142 2050 9166666.66968 +2143 2050 -16001859.73922 +2144 2050 -8593755.37553 +2145 2050 1.169741153717e-06 +2146 2050 -20033981.96478 +2147 2050 -694433.6992575 +2148 2050 -9166666.66968 +2149 2050 -17525889.09577 +2150 2050 9288189.074786 +2157 2050 1.229345798492e-06 +2158 2050 -36698646.37071 +2159 2050 -34527799.26293 +2160 2050 1.966953277588e-06 +2161 2050 29052683.00161 +2162 2050 -2777734.795662 +2163 2050 -2.190470695496e-06 +2164 2050 -42818438.03636 +2165 2050 37305534.05859 +2175 2050 -9166666.669679 +2176 2050 -16097939.2847 +2177 2050 -8663199.819997 +2178 2050 -1.445412635803e-06 +2179 2050 -20441974.38895 +2180 2050 -694433.6992576 +2181 2050 9166666.669678 +2182 2050 -17633805.76247 +2183 2050 9357633.519253 +2051 2051 616797415.4266 +2052 2051 231485.0634536 +2053 2051 5555469.588581 +2054 2051 82852085.35441 +2064 2051 2471063.023406 +2065 2051 1236089.620084 +2066 2051 -6756715.38321 +2067 2051 -462970.1266864 +2068 2051 -2777734.795656 +2069 2051 44192040.0554 +2070 2051 -2737270.309063 +2071 2051 1541645.175575 +2072 2051 -6819846.696327 +2142 2051 10539814.37052 +2143 2051 -8593755.37553 +2144 2051 -17106970.31658 +2145 2051 44746063.01646 +2146 2051 -694433.6992574 +2147 2051 -58719220.64359 +2148 2051 11841897.70428 +2149 2051 9288189.074786 +2150 2051 -21171048.60074 +2157 2051 57871.26589252 +2158 2051 -34500021.48517 +2159 2051 -41438476.99211 +2160 2051 231485.0634617 +2161 2051 -2777734.795662 +2162 2051 -127043423.7988 +2163 2051 57871.26589543 +2164 2051 37277756.28083 +2165 2051 -57757921.43384 +2175 2051 -10597685.63642 +2176 2051 -8663199.819997 +2177 2051 -17363182.43788 +2178 2051 -44977548.07992 +2179 2051 -694433.6992576 +2180 2051 -59807200.44138 +2181 2051 -11899768.97017 +2182 2051 9357633.519253 +2183 2051 -21458826.37861 +2052 2052 626081101.6128 +2053 2052 7.033348083496e-06 +2054 2052 925940.2533548 +2055 2052 85765730.61463 +2056 2052 -3.814697265625e-06 +2057 2052 231485.0634534 +2067 2052 -51881527.1465 +2068 2052 -36666666.66065 +2069 2052 2505785.245605 +2070 2052 -136819701.2443 +2071 2052 9.089708328247e-07 +2072 2052 -462970.1266867 +2073 2052 -51905201.38891 +2074 2052 36666666.66065 +2075 2052 -2702548.086863 +2145 2052 -18752053.59425 +2146 2052 9166666.66968 +2147 2052 10539814.37052 +2148 2052 -60367636.82651 +2149 2052 1.877546310425e-06 +2150 2052 44780785.23866 +2151 2052 -20276082.95081 +2152 2052 -9166666.66968 +2153 2052 11841897.70428 +2160 2052 -1865379.213624 +2161 2052 8.79168510437e-07 +2162 2052 57871.26589221 +2163 2052 51054233.83102 +2164 2052 1.788139343262e-06 +2165 2052 231485.0634618 +2166 2052 -7985170.87927 +2167 2052 -2.771615982056e-06 +2168 2052 57871.2658952 +2178 2052 -18848133.13973 +2179 2052 -9166666.66968 +2180 2052 -10597685.63642 +2181 2052 -60775629.25067 +2182 2052 -1.214444637299e-06 +2183 2052 -45012270.30212 +2184 2052 -20383999.6175 +2185 2052 9166666.669679 +2186 2052 -11899768.97017 +2053 2053 538074898.3386 +2054 2053 -11110939.17715 +2055 2053 -2.861022949219e-06 +2056 2053 -53567337.94508 +2057 2053 5555469.588581 +2067 2053 -36666666.66065 +2068 2053 -40880751.7318 +2069 2053 1263867.397843 +2070 2053 9.685754776001e-07 +2071 2053 24514918.12315 +2072 2053 -2777734.795656 +2073 2053 36666666.66065 +2074 2053 -40904425.97421 +2075 2053 1513867.397816 +2145 2053 9166666.66968 +2146 2053 -16001859.73922 +2147 2053 -8593755.37553 +2148 2053 1.169741153717e-06 +2149 2053 -20033981.96478 +2150 2053 -694433.6992575 +2151 2053 -9166666.66968 +2152 2053 -17525889.09577 +2153 2053 9288189.074786 +2160 2053 1.229345798492e-06 +2161 2053 -36698646.37071 +2162 2053 -34527799.26293 +2163 2053 1.966953277588e-06 +2164 2053 29052683.00161 +2165 2053 -2777734.795662 +2166 2053 -2.190470695496e-06 +2167 2053 -42818438.03636 +2168 2053 37305534.05859 +2178 2053 -9166666.669679 +2179 2053 -16097939.2847 +2180 2053 -8663199.819997 +2181 2053 -1.445412635803e-06 +2182 2053 -20441974.38895 +2183 2053 -694433.6992576 +2184 2053 9166666.669678 +2185 2053 -17633805.76247 +2186 2053 9357633.519253 +2054 2054 616797415.4266 +2055 2054 231485.0634536 +2056 2054 5555469.588581 +2057 2054 82852085.35441 +2067 2054 2471063.023406 +2068 2054 1236089.620084 +2069 2054 -6756715.38321 +2070 2054 -462970.1266864 +2071 2054 -2777734.795656 +2072 2054 44192040.0554 +2073 2054 -2737270.309063 +2074 2054 1541645.175575 +2075 2054 -6819846.696327 +2145 2054 10539814.37052 +2146 2054 -8593755.37553 +2147 2054 -17106970.31658 +2148 2054 44746063.01646 +2149 2054 -694433.6992574 +2150 2054 -58719220.64359 +2151 2054 11841897.70428 +2152 2054 9288189.074786 +2153 2054 -21171048.60074 +2160 2054 57871.26589252 +2161 2054 -34500021.48517 +2162 2054 -41438476.99211 +2163 2054 231485.0634617 +2164 2054 -2777734.795662 +2165 2054 -127043423.7988 +2166 2054 57871.26589543 +2167 2054 37277756.28083 +2168 2054 -57757921.43384 +2178 2054 -10597685.63642 +2179 2054 -8663199.819997 +2180 2054 -17363182.43788 +2181 2054 -44977548.07992 +2182 2054 -694433.6992576 +2183 2054 -59807200.44138 +2184 2054 -11899768.97017 +2185 2054 9357633.519253 +2186 2054 -21458826.37861 +2055 2055 677810035.2011 +2056 2055 36667397.55284 +2057 2055 3125086.662505 +2058 2055 20859938.00677 +2059 2055 -36666959.01753 +2060 2055 2702569.081896 +2070 2055 -51881527.1465 +2071 2055 -36666666.66065 +2072 2055 2505785.245605 +2073 2055 -136819701.2443 +2074 2055 9.089708328247e-07 +2075 2055 -462970.1266867 +2076 2055 -51905201.38891 +2077 2055 36666666.66065 +2078 2055 -2702548.086863 +2148 2055 -18752053.59425 +2149 2055 9166666.66968 +2150 2055 10539814.37052 +2151 2055 -72726245.22972 +2152 2055 -9166776.303506 +2153 2055 44231216.90386 +2163 2055 -1865379.213624 +2164 2055 8.79168510437e-07 +2165 2055 57871.26589221 +2166 2055 70575234.21716 +2167 2055 9166849.392726 +2168 2055 781227.3439141 +2169 2055 -20203256.3538 +2170 2055 -9166739.758899 +2171 2055 11899863.74724 +2181 2055 -18848133.13973 +2182 2055 -9166666.66968 +2183 2055 -10597685.63642 +2184 2055 -60775629.25067 +2185 2055 -1.214444637299e-06 +2186 2055 -45012270.30212 +2187 2055 -20383999.6175 +2188 2055 9166666.669679 +2189 2055 -11899768.97017 +2056 2056 578802727.5875 +2057 2056 -8610918.562153 +2058 2056 -36667105.19596 +2059 2056 -107472939.8429 +2060 2056 4611020.401354 +2070 2056 -36666666.66065 +2071 2056 -40880751.7318 +2072 2056 1263867.397843 +2073 2056 9.685754776001e-07 +2074 2056 24514918.12315 +2075 2056 -2777734.795656 +2076 2056 36666666.66065 +2077 2056 -40904425.97421 +2078 2056 1513867.397816 +2148 2056 9166666.66968 +2149 2056 -16001859.73922 +2150 2056 -8593755.37553 +2151 2056 -9166739.758897 +2152 2056 -29642168.10562 +2153 2056 8204934.122165 +2163 2056 1.229345798492e-06 +2164 2056 -36698646.37071 +2165 2056 -34527799.26293 +2166 2056 9166849.392726 +2167 2056 45823407.30156 +2168 2056 -2152765.098743 +2169 2056 -9166776.303508 +2170 2056 -52286475.83204 +2171 2056 37069600.58987 +2181 2056 -9166666.669679 +2182 2056 -16097939.2847 +2183 2056 -8663199.819997 +2184 2056 -1.445412635803e-06 +2185 2056 -20441974.38895 +2186 2056 -694433.6992576 +2187 2056 9166666.669678 +2188 2056 -17633805.76247 +2189 2056 9357633.519253 +2057 2057 623143279.9755 +2058 2057 2737301.801614 +2059 2057 5388806.115241 +2060 2057 41364580.11227 +2070 2057 2471063.023406 +2071 2057 1236089.620084 +2072 2057 -6756715.38321 +2073 2057 -462970.1266864 +2074 2057 -2777734.795656 +2075 2057 44192040.0554 +2076 2057 -2737270.309063 +2077 2057 1541645.175575 +2078 2057 -6819846.696327 +2148 2057 10539814.37052 +2149 2057 -8593755.37553 +2150 2057 -17106970.31658 +2151 2057 44196492.14387 +2152 2057 8010523.495484 +2153 2057 -58776166.2905 +2163 2057 57871.26589252 +2164 2057 -34500021.48517 +2165 2057 -41438476.99211 +2166 2057 781316.8545274 +2167 2057 -2152693.49136 +2168 2057 -107886912.3736 +2169 2057 11899911.13577 +2170 2057 37236269.31883 +2171 2057 -57440830.58835 +2181 2057 -10597685.63642 +2182 2057 -8663199.819997 +2183 2057 -17363182.43788 +2184 2057 -44977548.07992 +2185 2057 -694433.6992576 +2186 2057 -59807200.44138 +2187 2057 -11899768.97017 +2188 2057 9357633.519253 +2189 2057 -21458826.37861 +2058 2058 413691226.2239 +2059 2058 -25654363.10696 +2060 2058 -1249967.365095 +2073 2058 -51881527.1465 +2074 2058 -36666666.66065 +2075 2058 2505785.245605 +2076 2058 -58524091.22636 +2077 2058 25650494.38754 +2078 2058 -277763.3969709 +2079 2058 -197317189.9008 +2080 2058 29337202.04795 +2081 2058 -277827.545884 +2151 2058 -5106206.927443 +2152 2058 11000109.63744 +2153 2058 12682625.90274 +2166 2058 -15511422.68773 +2167 2058 -9166776.303506 +2168 2058 -10539940.2691 +2169 2058 51842225.42953 +2170 2058 -6283286.62687 +2171 2058 4930170.635181 +2184 2058 -18848133.13973 +2185 2058 -9166666.66968 +2186 2058 -10597685.63642 +2187 2058 -29935699.6739 +2188 2058 6282370.253291 +2189 2058 -26076070.50321 +2190 2058 -48484471.3307 +2191 2058 7334249.709323 +2192 2058 -1492967.268152 +2059 2059 718836304.435 +2060 2059 -10887577.70192 +2073 2059 -36666666.66065 +2074 2059 -40880751.7318 +2075 2059 1263867.397843 +2076 2059 25648560.02782 +2077 2059 85784924.743 +2078 2059 -1995425.504626 +2079 2059 44005803.07192 +2080 2059 -529439181.6462 +2081 2059 4619396.074007 +2151 2059 7333406.424962 +2152 2059 -5106206.927443 +2153 2059 -6763956.526763 +2166 2059 -9166739.758897 +2167 2059 -47594642.16596 +2168 2059 -34569643.89832 +2169 2059 -6283286.626871 +2170 2059 123653332.6419 +2171 2059 1534582.009726 +2184 2059 -9166666.669679 +2185 2059 -16097939.2847 +2186 2059 -8663199.819997 +2187 2059 6281912.066501 +2188 2059 6199889.665017 +2189 2059 5703411.089823 +2190 2059 11001374.56398 +2191 2059 -127098142.2588 +2192 2059 18052588.31743 +2060 2060 448560260.3527 +2073 2060 2471063.023406 +2074 2060 1236089.620084 +2075 2060 -6756715.38321 +2076 2060 -1041628.778 +2077 2060 -1884267.879154 +2078 2060 49098005.46007 +2079 2060 -416741.3188259 +2080 2060 4508335.130453 +2081 2060 -194057181.3232 +2151 2060 8455083.935158 +2152 2060 -10145934.79014 +2153 2060 -13616551.80652 +2166 2060 -10539898.30291 +2167 2060 -34736312.74845 +2168 2060 -44929274.14549 +2169 2060 -5469173.745564 +2170 2060 -6728616.358724 +2171 2060 -21692368.26691 +2184 2060 -10597685.63642 +2185 2060 -8663199.819997 +2186 2060 -17363182.43788 +2187 2060 -26249676.05648 +2188 2060 5759429.388185 +2189 2060 -27836926.26943 +2190 2060 -2239450.902228 +2191 2060 17455306.08699 +2192 2060 -50678252.62041 +2061 2061 626081101.6128 +2062 2061 7.033348083496e-06 +2063 2061 925940.2533548 +2064 2061 85765730.61463 +2065 2061 -3.814697265625e-06 +2066 2061 231485.0634534 +2082 2061 -136819701.2443 +2083 2061 9.089708328247e-07 +2084 2061 -462970.1266867 +2085 2061 -51905201.38891 +2086 2061 36666666.66065 +2087 2061 -2702548.086863 +2154 2061 -60367636.82651 +2155 2061 1.877546310425e-06 +2156 2061 44780785.23866 +2157 2061 -20276082.95081 +2158 2061 -9166666.66968 +2159 2061 11841897.70428 +2172 2061 51054233.83102 +2173 2061 1.788139343262e-06 +2174 2061 231485.0634618 +2175 2061 -7985170.87927 +2176 2061 -2.771615982056e-06 +2177 2061 57871.2658952 +2193 2061 -60775629.25067 +2194 2061 -1.214444637299e-06 +2195 2061 -45012270.30212 +2196 2061 -20383999.6175 +2197 2061 9166666.669679 +2198 2061 -11899768.97017 +2062 2062 538074898.3386 +2063 2062 -11110939.17715 +2064 2062 -2.861022949219e-06 +2065 2062 -53567337.94508 +2066 2062 5555469.588581 +2082 2062 9.685754776001e-07 +2083 2062 24514918.12315 +2084 2062 -2777734.795656 +2085 2062 36666666.66065 +2086 2062 -40904425.97421 +2087 2062 1513867.397816 +2154 2062 1.169741153717e-06 +2155 2062 -20033981.96478 +2156 2062 -694433.6992575 +2157 2062 -9166666.66968 +2158 2062 -17525889.09577 +2159 2062 9288189.074786 +2172 2062 1.966953277588e-06 +2173 2062 29052683.00161 +2174 2062 -2777734.795662 +2175 2062 -2.190470695496e-06 +2176 2062 -42818438.03636 +2177 2062 37305534.05859 +2193 2062 -1.445412635803e-06 +2194 2062 -20441974.38895 +2195 2062 -694433.6992576 +2196 2062 9166666.669678 +2197 2062 -17633805.76247 +2198 2062 9357633.519253 +2063 2063 616797415.4266 +2064 2063 231485.0634536 +2065 2063 5555469.588581 +2066 2063 82852085.35441 +2082 2063 -462970.1266864 +2083 2063 -2777734.795656 +2084 2063 44192040.0554 +2085 2063 -2737270.309063 +2086 2063 1541645.175575 +2087 2063 -6819846.696327 +2154 2063 44746063.01646 +2155 2063 -694433.6992574 +2156 2063 -58719220.64359 +2157 2063 11841897.70428 +2158 2063 9288189.074786 +2159 2063 -21171048.60074 +2172 2063 231485.0634617 +2173 2063 -2777734.795662 +2174 2063 -127043423.7988 +2175 2063 57871.26589543 +2176 2063 37277756.28083 +2177 2063 -57757921.43384 +2193 2063 -44977548.07992 +2194 2063 -694433.6992576 +2195 2063 -59807200.44138 +2196 2063 -11899768.97017 +2197 2063 9357633.519253 +2198 2063 -21458826.37861 +2064 2064 626081101.6128 +2065 2064 7.033348083496e-06 +2066 2064 925940.2533548 +2067 2064 85765730.61463 +2068 2064 -3.814697265625e-06 +2069 2064 231485.0634534 +2082 2064 -51881527.1465 +2083 2064 -36666666.66065 +2084 2064 2505785.245605 +2085 2064 -136819701.2443 +2086 2064 9.089708328247e-07 +2087 2064 -462970.1266867 +2088 2064 -51905201.38891 +2089 2064 36666666.66065 +2090 2064 -2702548.086863 +2154 2064 -18752053.59425 +2155 2064 9166666.66968 +2156 2064 10539814.37052 +2157 2064 -60367636.82651 +2158 2064 1.877546310425e-06 +2159 2064 44780785.23866 +2160 2064 -20276082.95081 +2161 2064 -9166666.66968 +2162 2064 11841897.70428 +2172 2064 -1865379.213624 +2173 2064 8.79168510437e-07 +2174 2064 57871.26589221 +2175 2064 51054233.83102 +2176 2064 1.788139343262e-06 +2177 2064 231485.0634618 +2178 2064 -7985170.87927 +2179 2064 -2.771615982056e-06 +2180 2064 57871.2658952 +2193 2064 -18848133.13973 +2194 2064 -9166666.66968 +2195 2064 -10597685.63642 +2196 2064 -60775629.25067 +2197 2064 -1.214444637299e-06 +2198 2064 -45012270.30212 +2199 2064 -20383999.6175 +2200 2064 9166666.669679 +2201 2064 -11899768.97017 +2065 2065 538074898.3386 +2066 2065 -11110939.17715 +2067 2065 -2.861022949219e-06 +2068 2065 -53567337.94508 +2069 2065 5555469.588581 +2082 2065 -36666666.66065 +2083 2065 -40880751.7318 +2084 2065 1263867.397843 +2085 2065 9.685754776001e-07 +2086 2065 24514918.12315 +2087 2065 -2777734.795656 +2088 2065 36666666.66065 +2089 2065 -40904425.97421 +2090 2065 1513867.397816 +2154 2065 9166666.66968 +2155 2065 -16001859.73922 +2156 2065 -8593755.37553 +2157 2065 1.169741153717e-06 +2158 2065 -20033981.96478 +2159 2065 -694433.6992575 +2160 2065 -9166666.66968 +2161 2065 -17525889.09577 +2162 2065 9288189.074786 +2172 2065 1.229345798492e-06 +2173 2065 -36698646.37071 +2174 2065 -34527799.26293 +2175 2065 1.966953277588e-06 +2176 2065 29052683.00161 +2177 2065 -2777734.795662 +2178 2065 -2.190470695496e-06 +2179 2065 -42818438.03636 +2180 2065 37305534.05859 +2193 2065 -9166666.669679 +2194 2065 -16097939.2847 +2195 2065 -8663199.819997 +2196 2065 -1.445412635803e-06 +2197 2065 -20441974.38895 +2198 2065 -694433.6992576 +2199 2065 9166666.669678 +2200 2065 -17633805.76247 +2201 2065 9357633.519253 +2066 2066 616797415.4266 +2067 2066 231485.0634536 +2068 2066 5555469.588581 +2069 2066 82852085.35441 +2082 2066 2471063.023406 +2083 2066 1236089.620084 +2084 2066 -6756715.38321 +2085 2066 -462970.1266864 +2086 2066 -2777734.795656 +2087 2066 44192040.0554 +2088 2066 -2737270.309063 +2089 2066 1541645.175575 +2090 2066 -6819846.696327 +2154 2066 10539814.37052 +2155 2066 -8593755.37553 +2156 2066 -17106970.31658 +2157 2066 44746063.01646 +2158 2066 -694433.6992574 +2159 2066 -58719220.64359 +2160 2066 11841897.70428 +2161 2066 9288189.074786 +2162 2066 -21171048.60074 +2172 2066 57871.26589252 +2173 2066 -34500021.48517 +2174 2066 -41438476.99211 +2175 2066 231485.0634617 +2176 2066 -2777734.795662 +2177 2066 -127043423.7988 +2178 2066 57871.26589543 +2179 2066 37277756.28083 +2180 2066 -57757921.43384 +2193 2066 -10597685.63642 +2194 2066 -8663199.819997 +2195 2066 -17363182.43788 +2196 2066 -44977548.07992 +2197 2066 -694433.6992576 +2198 2066 -59807200.44138 +2199 2066 -11899768.97017 +2200 2066 9357633.519253 +2201 2066 -21458826.37861 +2067 2067 626081101.6128 +2068 2067 7.033348083496e-06 +2069 2067 925940.2533548 +2070 2067 85765730.61463 +2071 2067 -3.814697265625e-06 +2072 2067 231485.0634534 +2085 2067 -51881527.1465 +2086 2067 -36666666.66065 +2087 2067 2505785.245605 +2088 2067 -136819701.2443 +2089 2067 9.089708328247e-07 +2090 2067 -462970.1266867 +2091 2067 -51905201.38891 +2092 2067 36666666.66065 +2093 2067 -2702548.086863 +2157 2067 -18752053.59425 +2158 2067 9166666.66968 +2159 2067 10539814.37052 +2160 2067 -60367636.82651 +2161 2067 1.877546310425e-06 +2162 2067 44780785.23866 +2163 2067 -20276082.95081 +2164 2067 -9166666.66968 +2165 2067 11841897.70428 +2175 2067 -1865379.213624 +2176 2067 8.79168510437e-07 +2177 2067 57871.26589221 +2178 2067 51054233.83102 +2179 2067 1.788139343262e-06 +2180 2067 231485.0634618 +2181 2067 -7985170.87927 +2182 2067 -2.771615982056e-06 +2183 2067 57871.2658952 +2196 2067 -18848133.13973 +2197 2067 -9166666.66968 +2198 2067 -10597685.63642 +2199 2067 -60775629.25067 +2200 2067 -1.214444637299e-06 +2201 2067 -45012270.30212 +2202 2067 -20383999.6175 +2203 2067 9166666.669679 +2204 2067 -11899768.97017 +2068 2068 538074898.3386 +2069 2068 -11110939.17715 +2070 2068 -2.861022949219e-06 +2071 2068 -53567337.94508 +2072 2068 5555469.588581 +2085 2068 -36666666.66065 +2086 2068 -40880751.7318 +2087 2068 1263867.397843 +2088 2068 9.685754776001e-07 +2089 2068 24514918.12315 +2090 2068 -2777734.795656 +2091 2068 36666666.66065 +2092 2068 -40904425.97421 +2093 2068 1513867.397816 +2157 2068 9166666.66968 +2158 2068 -16001859.73922 +2159 2068 -8593755.37553 +2160 2068 1.169741153717e-06 +2161 2068 -20033981.96478 +2162 2068 -694433.6992575 +2163 2068 -9166666.66968 +2164 2068 -17525889.09577 +2165 2068 9288189.074786 +2175 2068 1.229345798492e-06 +2176 2068 -36698646.37071 +2177 2068 -34527799.26293 +2178 2068 1.966953277588e-06 +2179 2068 29052683.00161 +2180 2068 -2777734.795662 +2181 2068 -2.190470695496e-06 +2182 2068 -42818438.03636 +2183 2068 37305534.05859 +2196 2068 -9166666.669679 +2197 2068 -16097939.2847 +2198 2068 -8663199.819997 +2199 2068 -1.445412635803e-06 +2200 2068 -20441974.38895 +2201 2068 -694433.6992576 +2202 2068 9166666.669678 +2203 2068 -17633805.76247 +2204 2068 9357633.519253 +2069 2069 616797415.4266 +2070 2069 231485.0634536 +2071 2069 5555469.588581 +2072 2069 82852085.35441 +2085 2069 2471063.023406 +2086 2069 1236089.620084 +2087 2069 -6756715.38321 +2088 2069 -462970.1266864 +2089 2069 -2777734.795656 +2090 2069 44192040.0554 +2091 2069 -2737270.309063 +2092 2069 1541645.175575 +2093 2069 -6819846.696327 +2157 2069 10539814.37052 +2158 2069 -8593755.37553 +2159 2069 -17106970.31658 +2160 2069 44746063.01646 +2161 2069 -694433.6992574 +2162 2069 -58719220.64359 +2163 2069 11841897.70428 +2164 2069 9288189.074786 +2165 2069 -21171048.60074 +2175 2069 57871.26589252 +2176 2069 -34500021.48517 +2177 2069 -41438476.99211 +2178 2069 231485.0634617 +2179 2069 -2777734.795662 +2180 2069 -127043423.7988 +2181 2069 57871.26589543 +2182 2069 37277756.28083 +2183 2069 -57757921.43384 +2196 2069 -10597685.63642 +2197 2069 -8663199.819997 +2198 2069 -17363182.43788 +2199 2069 -44977548.07992 +2200 2069 -694433.6992576 +2201 2069 -59807200.44138 +2202 2069 -11899768.97017 +2203 2069 9357633.519253 +2204 2069 -21458826.37861 +2070 2070 626081101.6128 +2071 2070 7.033348083496e-06 +2072 2070 925940.2533548 +2073 2070 85765730.61463 +2074 2070 -3.814697265625e-06 +2075 2070 231485.0634534 +2088 2070 -51881527.1465 +2089 2070 -36666666.66065 +2090 2070 2505785.245605 +2091 2070 -136819701.2443 +2092 2070 9.089708328247e-07 +2093 2070 -462970.1266867 +2094 2070 -51905201.38891 +2095 2070 36666666.66065 +2096 2070 -2702548.086863 +2160 2070 -18752053.59425 +2161 2070 9166666.66968 +2162 2070 10539814.37052 +2163 2070 -60367636.82651 +2164 2070 1.877546310425e-06 +2165 2070 44780785.23866 +2166 2070 -20276082.95081 +2167 2070 -9166666.66968 +2168 2070 11841897.70428 +2178 2070 -1865379.213624 +2179 2070 8.79168510437e-07 +2180 2070 57871.26589221 +2181 2070 51054233.83102 +2182 2070 1.788139343262e-06 +2183 2070 231485.0634618 +2184 2070 -7985170.87927 +2185 2070 -2.771615982056e-06 +2186 2070 57871.2658952 +2199 2070 -18848133.13973 +2200 2070 -9166666.66968 +2201 2070 -10597685.63642 +2202 2070 -60775629.25067 +2203 2070 -1.214444637299e-06 +2204 2070 -45012270.30212 +2205 2070 -20383999.6175 +2206 2070 9166666.669679 +2207 2070 -11899768.97017 +2071 2071 538074898.3386 +2072 2071 -11110939.17715 +2073 2071 -2.861022949219e-06 +2074 2071 -53567337.94508 +2075 2071 5555469.588581 +2088 2071 -36666666.66065 +2089 2071 -40880751.7318 +2090 2071 1263867.397843 +2091 2071 9.685754776001e-07 +2092 2071 24514918.12315 +2093 2071 -2777734.795656 +2094 2071 36666666.66065 +2095 2071 -40904425.97421 +2096 2071 1513867.397816 +2160 2071 9166666.66968 +2161 2071 -16001859.73922 +2162 2071 -8593755.37553 +2163 2071 1.169741153717e-06 +2164 2071 -20033981.96478 +2165 2071 -694433.6992575 +2166 2071 -9166666.66968 +2167 2071 -17525889.09577 +2168 2071 9288189.074786 +2178 2071 1.229345798492e-06 +2179 2071 -36698646.37071 +2180 2071 -34527799.26293 +2181 2071 1.966953277588e-06 +2182 2071 29052683.00161 +2183 2071 -2777734.795662 +2184 2071 -2.190470695496e-06 +2185 2071 -42818438.03636 +2186 2071 37305534.05859 +2199 2071 -9166666.669679 +2200 2071 -16097939.2847 +2201 2071 -8663199.819997 +2202 2071 -1.445412635803e-06 +2203 2071 -20441974.38895 +2204 2071 -694433.6992576 +2205 2071 9166666.669678 +2206 2071 -17633805.76247 +2207 2071 9357633.519253 +2072 2072 616797415.4266 +2073 2072 231485.0634536 +2074 2072 5555469.588581 +2075 2072 82852085.35441 +2088 2072 2471063.023406 +2089 2072 1236089.620084 +2090 2072 -6756715.38321 +2091 2072 -462970.1266864 +2092 2072 -2777734.795656 +2093 2072 44192040.0554 +2094 2072 -2737270.309063 +2095 2072 1541645.175575 +2096 2072 -6819846.696327 +2160 2072 10539814.37052 +2161 2072 -8593755.37553 +2162 2072 -17106970.31658 +2163 2072 44746063.01646 +2164 2072 -694433.6992574 +2165 2072 -58719220.64359 +2166 2072 11841897.70428 +2167 2072 9288189.074786 +2168 2072 -21171048.60074 +2178 2072 57871.26589252 +2179 2072 -34500021.48517 +2180 2072 -41438476.99211 +2181 2072 231485.0634617 +2182 2072 -2777734.795662 +2183 2072 -127043423.7988 +2184 2072 57871.26589543 +2185 2072 37277756.28083 +2186 2072 -57757921.43384 +2199 2072 -10597685.63642 +2200 2072 -8663199.819997 +2201 2072 -17363182.43788 +2202 2072 -44977548.07992 +2203 2072 -694433.6992576 +2204 2072 -59807200.44138 +2205 2072 -11899768.97017 +2206 2072 9357633.519253 +2207 2072 -21458826.37861 +2073 2073 626081101.6128 +2074 2073 7.033348083496e-06 +2075 2073 925940.2533548 +2076 2073 85765730.61463 +2077 2073 -3.814697265625e-06 +2078 2073 231485.0634534 +2091 2073 -51881527.1465 +2092 2073 -36666666.66065 +2093 2073 2505785.245605 +2094 2073 -136819701.2443 +2095 2073 9.089708328247e-07 +2096 2073 -462970.1266867 +2097 2073 -51905201.38891 +2098 2073 36666666.66065 +2099 2073 -2702548.086863 +2163 2073 -18752053.59425 +2164 2073 9166666.66968 +2165 2073 10539814.37052 +2166 2073 -60367636.82651 +2167 2073 1.877546310425e-06 +2168 2073 44780785.23866 +2169 2073 -20276082.95081 +2170 2073 -9166666.66968 +2171 2073 11841897.70428 +2181 2073 -1865379.213624 +2182 2073 8.79168510437e-07 +2183 2073 57871.26589221 +2184 2073 51054233.83102 +2185 2073 1.788139343262e-06 +2186 2073 231485.0634618 +2187 2073 -7985170.87927 +2188 2073 -2.771615982056e-06 +2189 2073 57871.2658952 +2202 2073 -18848133.13973 +2203 2073 -9166666.66968 +2204 2073 -10597685.63642 +2205 2073 -60775629.25067 +2206 2073 -1.214444637299e-06 +2207 2073 -45012270.30212 +2208 2073 -20383999.6175 +2209 2073 9166666.669679 +2210 2073 -11899768.97017 +2074 2074 538074898.3386 +2075 2074 -11110939.17715 +2076 2074 -2.861022949219e-06 +2077 2074 -53567337.94508 +2078 2074 5555469.588581 +2091 2074 -36666666.66065 +2092 2074 -40880751.7318 +2093 2074 1263867.397843 +2094 2074 9.685754776001e-07 +2095 2074 24514918.12315 +2096 2074 -2777734.795656 +2097 2074 36666666.66065 +2098 2074 -40904425.97421 +2099 2074 1513867.397816 +2163 2074 9166666.66968 +2164 2074 -16001859.73922 +2165 2074 -8593755.37553 +2166 2074 1.169741153717e-06 +2167 2074 -20033981.96478 +2168 2074 -694433.6992575 +2169 2074 -9166666.66968 +2170 2074 -17525889.09577 +2171 2074 9288189.074786 +2181 2074 1.229345798492e-06 +2182 2074 -36698646.37071 +2183 2074 -34527799.26293 +2184 2074 1.966953277588e-06 +2185 2074 29052683.00161 +2186 2074 -2777734.795662 +2187 2074 -2.190470695496e-06 +2188 2074 -42818438.03636 +2189 2074 37305534.05859 +2202 2074 -9166666.669679 +2203 2074 -16097939.2847 +2204 2074 -8663199.819997 +2205 2074 -1.445412635803e-06 +2206 2074 -20441974.38895 +2207 2074 -694433.6992576 +2208 2074 9166666.669678 +2209 2074 -17633805.76247 +2210 2074 9357633.519253 +2075 2075 616797415.4266 +2076 2075 231485.0634536 +2077 2075 5555469.588581 +2078 2075 82852085.35441 +2091 2075 2471063.023406 +2092 2075 1236089.620084 +2093 2075 -6756715.38321 +2094 2075 -462970.1266864 +2095 2075 -2777734.795656 +2096 2075 44192040.0554 +2097 2075 -2737270.309063 +2098 2075 1541645.175575 +2099 2075 -6819846.696327 +2163 2075 10539814.37052 +2164 2075 -8593755.37553 +2165 2075 -17106970.31658 +2166 2075 44746063.01646 +2167 2075 -694433.6992574 +2168 2075 -58719220.64359 +2169 2075 11841897.70428 +2170 2075 9288189.074786 +2171 2075 -21171048.60074 +2181 2075 57871.26589252 +2182 2075 -34500021.48517 +2183 2075 -41438476.99211 +2184 2075 231485.0634617 +2185 2075 -2777734.795662 +2186 2075 -127043423.7988 +2187 2075 57871.26589543 +2188 2075 37277756.28083 +2189 2075 -57757921.43384 +2202 2075 -10597685.63642 +2203 2075 -8663199.819997 +2204 2075 -17363182.43788 +2205 2075 -44977548.07992 +2206 2075 -694433.6992576 +2207 2075 -59807200.44138 +2208 2075 -11899768.97017 +2209 2075 9357633.519253 +2210 2075 -21458826.37861 +2076 2076 526252665.2804 +2077 2076 14939345.36446 +2078 2076 312503.9972225 +2079 2076 -95232869.048 +2080 2076 -75446271.56808 +2081 2076 604979.855709 +2094 2076 -51881527.1465 +2095 2076 -36666666.66065 +2096 2076 2505785.245605 +2097 2076 -86033365.36057 +2098 2076 24063656.22554 +2099 2076 -110868.0321211 +2100 2076 -45738405.09723 +2101 2076 10794709.95026 +2102 2076 -181650.9566633 +2166 2076 -18752053.59425 +2167 2076 9166666.66968 +2168 2076 10539814.37052 +2169 2076 -29447591.25609 +2170 2076 6281912.066503 +2171 2076 25747045.84724 +2184 2076 -1865379.213624 +2185 2076 8.79168510437e-07 +2186 2076 57871.26589221 +2187 2076 60972868.35786 +2188 2076 3865013.480293 +2189 2076 94987.35611238 +2190 2076 -36158131.46173 +2191 2076 -18861517.09503 +2192 2076 11548470.62288 +2205 2076 -18848133.13973 +2206 2076 -9166666.66968 +2207 2076 -10597685.63642 +2208 2076 -45324581.42976 +2209 2076 6015914.059347 +2210 2076 -35313654.50317 +2211 2076 -18251664.62718 +2212 2076 2698677.488894 +2213 2076 -1659648.850827 +2077 2077 644278102.7769 +2078 2077 -8172915.912315 +2079 2077 -75448205.92779 +2080 2077 -250909777.5561 +2081 2077 1581997.404667 +2094 2077 -36666666.66065 +2095 2077 -40880751.7318 +2096 2077 1263867.397843 +2097 2077 24063656.22554 +2098 2077 19704498.54099 +2099 2077 -1263948.6007 +2100 2077 10794709.95026 +2101 2077 -140802296.2262 +2102 2077 1044821.700929 +2166 2077 9166666.66968 +2167 2077 -16001859.73922 +2168 2077 -8593755.37553 +2169 2077 6282370.253292 +2170 2077 6687998.082834 +2171 2077 -6666183.334191 +2184 2077 1.229345798492e-06 +2185 2077 -36698646.37071 +2186 2077 -34527799.26293 +2187 2077 3865013.480291 +2188 2077 90420643.57345 +2189 2077 -2029739.902148 +2190 2077 -18861975.28182 +2191 2077 -75077109.76366 +2192 2077 36515053.21218 +2205 2077 -9166666.669679 +2206 2077 -16097939.2847 +2207 2077 -8663199.819997 +2208 2077 6015914.059347 +2209 2077 -18890115.44135 +2210 2077 7371512.847656 +2211 2077 2698677.488894 +2212 2077 -42017637.42113 +2213 2077 16927872.0975 +2078 2078 520022806.6022 +2079 2078 570282.5175709 +2080 2078 1609822.801136 +2081 2078 -60894553.27404 +2094 2078 2471063.023406 +2095 2078 1236089.620084 +2096 2078 -6756715.38321 +2097 2078 -978923.5875342 +2098 2078 -1291726.378473 +2099 2078 48623486.51979 +2100 2078 -251095.4010623 +2101 2078 1044821.700929 +2102 2078 -32250770.90951 +2166 2078 10539814.37052 +2167 2078 -8593755.37553 +2168 2078 -17106970.31658 +2169 2078 25920651.40051 +2170 2078 -6665741.874855 +2171 2078 -26535303.82191 +2184 2078 57871.26589252 +2185 2078 -34500021.48517 +2186 2078 -41438476.99211 +2187 2078 234053.9607636 +2188 2078 -1918486.590656 +2189 2078 -58935888.16644 +2190 2078 11618009.81039 +2191 2078 36542460.89336 +2192 2078 -48156991.67162 +2205 2078 -10597685.63642 +2206 2078 -8663199.819997 +2207 2078 -17363182.43788 +2208 2078 -35487265.61249 +2209 2078 7371512.849165 +2210 2078 -51354101.90813 +2211 2078 -1659648.850827 +2212 2078 16927872.0975 +2213 2078 -26241528.32399 +2079 2079 561277452.4122 +2080 2079 17123133.77783 +2081 2079 -203432.5875025 +2097 2079 -53262133.98087 +2098 2079 -32705759.54262 +2099 2079 337518.2011556 +2100 2079 32720092.49217 +2101 2079 38632242.24836 +2102 2079 -151553.4188327 +2103 2079 64231443.64297 +2104 2079 -20494572.48629 +2105 2079 2743.280364752 +2106 2079 -1187850.072857 +2107 2079 28887358.8586 +2108 2079 -69372.22938187 +2169 2079 -47978573.2119 +2170 2079 11001374.56398 +2171 2079 2031082.172367 +2187 2079 -35280692.66549 +2188 2079 -18861975.28183 +2189 2079 -11237384.37005 +2190 2079 30022383.98719 +2191 2079 4263555.44703 +2192 2079 8794520.109826 +2208 2079 -19804774.09007 +2209 2079 -8176439.889684 +2210 2079 -11139057.95335 +2211 2079 -41857962.82082 +2212 2079 9645791.927615 +2213 2079 -43978119.70779 +2214 2079 -23078892.07815 +2215 2079 -5106415.12456 +2216 2079 13589890.89401 +2217 2079 -17329912.71843 +2218 2079 7234108.357436 +2219 2079 -10803153.36729 +2080 2080 978283183.6999 +2081 2080 -5543467.713303 +2097 2080 -32705759.54262 +2098 2080 -17400227.63301 +2099 2080 -74400.58715915 +2100 2080 38632242.24836 +2101 2080 160644520.1659 +2102 2080 -573223.656266 +2103 2080 -5827905.822031 +2104 2080 -6363276.830221 +2105 2080 57557.59449947 +2106 2080 28887358.8586 +2107 2080 -23586294.65532 +2108 2080 70736.41377275 +2169 2080 7334249.709323 +2170 2080 -126592244.14 +2171 2080 -15312676.91506 +2187 2080 -18861517.09504 +2188 2080 -74199670.96744 +2189 2080 -35709774.04968 +2190 2080 4263555.447029 +2191 2080 129813207.8779 +2192 2080 -753234.9707085 +2208 2080 -8176439.889684 +2209 2080 -10839297.49869 +2210 2080 -8997766.816414 +2211 2080 9645791.927616 +2212 2080 -9864955.562426 +2213 2080 7544235.325179 +2214 2080 -1439748.456689 +2215 2080 -40731782.17156 +2216 2080 33347706.83858 +2217 2080 7234108.357436 +2218 2080 -22893681.13543 +2219 2080 16684309.53426 +2081 2081 724177116.0154 +2097 2081 302795.9789559 +2098 2081 -102178.3649187 +2099 2081 -626812.8042064 +2100 2081 -255720.0854817 +2101 2081 -601001.4340393 +2102 2081 193831384.4324 +2103 2081 2743.280367732 +2104 2081 57557.5944995 +2105 2081 126362557.5082 +2106 2081 -69372.22934835 +2107 2081 70736.41377272 +2108 2081 41151344.23183 +2169 2081 1354054.781578 +2170 2081 -15854425.87662 +2171 2081 -49329190.9703 +2187 2081 -11167856.98135 +2188 2081 -35682388.19982 +2189 2081 -45817154.88165 +2190 2081 -8809368.776172 +2191 2081 -1837472.387429 +2192 2081 -108785896.0355 +2208 2081 -11139057.95335 +2209 2081 -8997766.816414 +2210 2081 -17461344.76991 +2211 2081 -44012841.93004 +2212 2081 7544235.326688 +2213 2081 -84876841.96464 +2214 2081 5464890.893211 +2215 2081 33347706.83858 +2216 2081 -72827119.94061 +2217 2081 -10803153.36729 +2218 2081 16684309.53426 +2219 2081 -35058247.69784 +2082 2082 313040550.8064 +2083 2082 3.218650817871e-06 +2084 2082 462970.1266764 +2085 2082 42883259.87802 +2086 2082 7333333.332129 +2087 2082 -318285.2460207 +2172 2082 -60367636.82651 +2173 2082 1.877546310425e-06 +2174 2082 44780785.23866 +2175 2082 -20276082.95081 +2176 2082 -9166666.66968 +2177 2082 11841897.70428 +2193 2082 25526722.3448 +2194 2082 -5.960464477539e-08 +2195 2082 -8946896.355626 +2196 2082 -3992585.439634 +2197 2082 1833333.333934 +2198 2082 -2345231.034498 +2083 2083 269037449.1693 +2084 2083 -5555469.588573 +2085 2083 -7333333.332131 +2086 2083 -26783274.40183 +2087 2083 2749957.016519 +2172 2083 1.169741153717e-06 +2173 2083 -20033981.96478 +2174 2083 -694433.6992575 +2175 2083 -9166666.66968 +2176 2083 -17525889.09577 +2177 2083 9288189.074786 +2193 2083 6.556510925293e-07 +2194 2083 14525946.9301 +2195 2083 -1388867.397833 +2196 2083 -1833333.333937 +2197 2083 -21409219.01818 +2198 2083 18645822.58485 +2084 2084 308398707.7133 +2085 2084 723381.420473 +2086 2084 2805512.572065 +2087 2084 41427094.86576 +2172 2084 44746063.01646 +2173 2084 -694433.6992574 +2174 2084 -58719220.64359 +2175 2084 11841897.70428 +2176 2084 9288189.074786 +2177 2084 -21171048.60074 +2193 2084 9004770.308089 +2194 2084 -1388867.397833 +2195 2084 -63522764.08798 +2196 2084 2403102.300394 +2197 2084 18645822.58486 +2198 2084 -28878960.71692 +2085 2085 313040550.8064 +2086 2085 3.218650817871e-06 +2087 2085 462970.1266764 +2088 2085 42883259.87802 +2089 2085 7333333.332129 +2090 2085 -318285.2460207 +2172 2085 -18752053.59425 +2173 2085 9166666.66968 +2174 2085 10539814.37052 +2175 2085 -60367636.82651 +2176 2085 1.877546310425e-06 +2177 2085 44780785.23866 +2178 2085 -20276082.95081 +2179 2085 -9166666.66968 +2180 2085 11841897.70428 +2193 2085 -932689.6068121 +2194 2085 -1833333.333935 +2195 2085 -2084814.367748 +2196 2085 25526722.3448 +2197 2085 -5.960464477539e-08 +2198 2085 -8946896.355626 +2199 2085 -3992585.439634 +2200 2085 1833333.333934 +2201 2085 -2345231.034498 +2086 2086 269037449.1693 +2087 2086 -5555469.588573 +2088 2086 -7333333.332131 +2089 2086 -26783274.40183 +2090 2086 2749957.016519 +2172 2086 9166666.66968 +2173 2086 -16001859.73922 +2174 2086 -8593755.37553 +2175 2086 1.169741153717e-06 +2176 2086 -20033981.96478 +2177 2086 -694433.6992575 +2178 2086 -9166666.66968 +2179 2086 -17525889.09577 +2180 2086 9288189.074786 +2193 2086 1833333.333937 +2194 2086 -18349323.18536 +2195 2086 -17256955.18702 +2196 2086 6.556510925293e-07 +2197 2086 14525946.9301 +2198 2086 -1388867.397833 +2199 2086 -1833333.333937 +2200 2086 -21409219.01818 +2201 2086 18645822.58485 +2087 2087 308398707.7133 +2088 2087 723381.420473 +2089 2087 2805512.572065 +2090 2087 41427094.86576 +2172 2087 10539814.37052 +2173 2087 -8593755.37553 +2174 2087 -17106970.31658 +2175 2087 44746063.01646 +2176 2087 -694433.6992574 +2177 2087 -58719220.64359 +2178 2087 11841897.70428 +2179 2087 9288189.074786 +2180 2087 -21171048.60074 +2193 2087 2142685.63364 +2194 2087 -17256955.18703 +2195 2087 -20719238.49606 +2196 2087 9004770.308089 +2197 2087 -1388867.397833 +2198 2087 -63522764.08798 +2199 2087 2403102.300394 +2200 2087 18645822.58486 +2201 2087 -28878960.71692 +2088 2088 313040550.8064 +2089 2088 3.218650817871e-06 +2090 2088 462970.1266764 +2091 2088 42883259.87802 +2092 2088 7333333.332129 +2093 2088 -318285.2460207 +2175 2088 -18752053.59425 +2176 2088 9166666.66968 +2177 2088 10539814.37052 +2178 2088 -60367636.82651 +2179 2088 1.877546310425e-06 +2180 2088 44780785.23866 +2181 2088 -20276082.95081 +2182 2088 -9166666.66968 +2183 2088 11841897.70428 +2196 2088 -932689.6068121 +2197 2088 -1833333.333935 +2198 2088 -2084814.367748 +2199 2088 25526722.3448 +2200 2088 -5.960464477539e-08 +2201 2088 -8946896.355626 +2202 2088 -3992585.439634 +2203 2088 1833333.333934 +2204 2088 -2345231.034498 +2089 2089 269037449.1693 +2090 2089 -5555469.588573 +2091 2089 -7333333.332131 +2092 2089 -26783274.40183 +2093 2089 2749957.016519 +2175 2089 9166666.66968 +2176 2089 -16001859.73922 +2177 2089 -8593755.37553 +2178 2089 1.169741153717e-06 +2179 2089 -20033981.96478 +2180 2089 -694433.6992575 +2181 2089 -9166666.66968 +2182 2089 -17525889.09577 +2183 2089 9288189.074786 +2196 2089 1833333.333937 +2197 2089 -18349323.18536 +2198 2089 -17256955.18702 +2199 2089 6.556510925293e-07 +2200 2089 14525946.9301 +2201 2089 -1388867.397833 +2202 2089 -1833333.333937 +2203 2089 -21409219.01818 +2204 2089 18645822.58485 +2090 2090 308398707.7133 +2091 2090 723381.420473 +2092 2090 2805512.572065 +2093 2090 41427094.86576 +2175 2090 10539814.37052 +2176 2090 -8593755.37553 +2177 2090 -17106970.31658 +2178 2090 44746063.01646 +2179 2090 -694433.6992574 +2180 2090 -58719220.64359 +2181 2090 11841897.70428 +2182 2090 9288189.074786 +2183 2090 -21171048.60074 +2196 2090 2142685.63364 +2197 2090 -17256955.18703 +2198 2090 -20719238.49606 +2199 2090 9004770.308089 +2200 2090 -1388867.397833 +2201 2090 -63522764.08798 +2202 2090 2403102.300394 +2203 2090 18645822.58486 +2204 2090 -28878960.71692 +2091 2091 313040550.8064 +2092 2091 3.218650817871e-06 +2093 2091 462970.1266764 +2094 2091 42883259.87802 +2095 2091 7333333.332129 +2096 2091 -318285.2460207 +2178 2091 -18752053.59425 +2179 2091 9166666.66968 +2180 2091 10539814.37052 +2181 2091 -60367636.82651 +2182 2091 1.877546310425e-06 +2183 2091 44780785.23866 +2184 2091 -20276082.95081 +2185 2091 -9166666.66968 +2186 2091 11841897.70428 +2199 2091 -932689.6068121 +2200 2091 -1833333.333935 +2201 2091 -2084814.367748 +2202 2091 25526722.3448 +2203 2091 -5.960464477539e-08 +2204 2091 -8946896.355626 +2205 2091 -3992585.439634 +2206 2091 1833333.333934 +2207 2091 -2345231.034498 +2092 2092 269037449.1693 +2093 2092 -5555469.588573 +2094 2092 -7333333.332131 +2095 2092 -26783274.40183 +2096 2092 2749957.016519 +2178 2092 9166666.66968 +2179 2092 -16001859.73922 +2180 2092 -8593755.37553 +2181 2092 1.169741153717e-06 +2182 2092 -20033981.96478 +2183 2092 -694433.6992575 +2184 2092 -9166666.66968 +2185 2092 -17525889.09577 +2186 2092 9288189.074786 +2199 2092 1833333.333937 +2200 2092 -18349323.18536 +2201 2092 -17256955.18702 +2202 2092 6.556510925293e-07 +2203 2092 14525946.9301 +2204 2092 -1388867.397833 +2205 2092 -1833333.333937 +2206 2092 -21409219.01818 +2207 2092 18645822.58485 +2093 2093 308398707.7133 +2094 2093 723381.420473 +2095 2093 2805512.572065 +2096 2093 41427094.86576 +2178 2093 10539814.37052 +2179 2093 -8593755.37553 +2180 2093 -17106970.31658 +2181 2093 44746063.01646 +2182 2093 -694433.6992574 +2183 2093 -58719220.64359 +2184 2093 11841897.70428 +2185 2093 9288189.074786 +2186 2093 -21171048.60074 +2199 2093 2142685.63364 +2200 2093 -17256955.18703 +2201 2093 -20719238.49606 +2202 2093 9004770.308089 +2203 2093 -1388867.397833 +2204 2093 -63522764.08798 +2205 2093 2403102.300394 +2206 2093 18645822.58486 +2207 2093 -28878960.71692 +2094 2094 313040550.8064 +2095 2094 3.218650817871e-06 +2096 2094 462970.1266764 +2097 2094 42883259.87802 +2098 2094 7333333.332129 +2099 2094 -318285.2460207 +2181 2094 -18752053.59425 +2182 2094 9166666.66968 +2183 2094 10539814.37052 +2184 2094 -60367636.82651 +2185 2094 1.877546310425e-06 +2186 2094 44780785.23866 +2187 2094 -20276082.95081 +2188 2094 -9166666.66968 +2189 2094 11841897.70428 +2202 2094 -932689.6068121 +2203 2094 -1833333.333935 +2204 2094 -2084814.367748 +2205 2094 25526722.3448 +2206 2094 -5.960464477539e-08 +2207 2094 -8946896.355626 +2208 2094 -3992585.439634 +2209 2094 1833333.333934 +2210 2094 -2345231.034498 +2095 2095 269037449.1693 +2096 2095 -5555469.588573 +2097 2095 -7333333.332131 +2098 2095 -26783274.40183 +2099 2095 2749957.016519 +2181 2095 9166666.66968 +2182 2095 -16001859.73922 +2183 2095 -8593755.37553 +2184 2095 1.169741153717e-06 +2185 2095 -20033981.96478 +2186 2095 -694433.6992575 +2187 2095 -9166666.66968 +2188 2095 -17525889.09577 +2189 2095 9288189.074786 +2202 2095 1833333.333937 +2203 2095 -18349323.18536 +2204 2095 -17256955.18702 +2205 2095 6.556510925293e-07 +2206 2095 14525946.9301 +2207 2095 -1388867.397833 +2208 2095 -1833333.333937 +2209 2095 -21409219.01818 +2210 2095 18645822.58485 +2096 2096 308398707.7133 +2097 2096 723381.420473 +2098 2096 2805512.572065 +2099 2096 41427094.86576 +2181 2096 10539814.37052 +2182 2096 -8593755.37553 +2183 2096 -17106970.31658 +2184 2096 44746063.01646 +2185 2096 -694433.6992574 +2186 2096 -58719220.64359 +2187 2096 11841897.70428 +2188 2096 9288189.074786 +2189 2096 -21171048.60074 +2202 2096 2142685.63364 +2203 2096 -17256955.18703 +2204 2096 -20719238.49606 +2205 2096 9004770.308089 +2206 2096 -1388867.397833 +2207 2096 -63522764.08798 +2208 2096 2403102.300394 +2209 2096 18645822.58486 +2210 2096 -28878960.71692 +2097 2097 311501301.9278 +2098 2097 3961702.031803 +2099 2097 2461349.04567 +2100 2097 -4984022.060376 +2101 2097 -24652932.04324 +2102 2097 367556.3402904 +2184 2097 -18752053.59425 +2185 2097 9166666.66968 +2186 2097 10539814.37052 +2187 2097 -44778234.89159 +2188 2097 6015914.059352 +2189 2097 35041206.59625 +2190 2097 -20008769.25006 +2191 2097 -8176439.889681 +2192 2097 11299136.49846 +2205 2097 -932689.6068121 +2206 2097 -1833333.333935 +2207 2097 -2084814.367748 +2208 2097 25141334.84086 +2209 2097 990425.5084367 +2210 2097 -8447023.847856 +2211 2097 -17627581.50065 +2212 2097 -6163233.013846 +2213 2097 7435569.639298 +2098 2098 292367764.6648 +2099 2098 -3560498.398243 +2100 2098 -39319598.70751 +2101 2098 -68784496.1816 +2102 2098 607245.3940165 +2184 2098 9166666.66968 +2185 2098 -16001859.73922 +2186 2098 -8593755.37553 +2187 2098 6015914.059351 +2188 2098 -18343768.90317 +2189 2098 -8010431.594268 +2190 2098 -8176439.889681 +2191 2098 -11043292.65868 +2192 2098 8953622.07837 +2205 2098 1833333.333937 +2206 2098 -18349323.18536 +2207 2098 -17256955.18702 +2208 2098 990425.5084375 +2209 2098 20357950.52274 +2210 2098 -890124.6000073 +2211 2098 -9829899.681717 +2212 2098 -33577700.03881 +2213 2098 25797644.67844 +2099 2099 314119300.5055 +2100 2099 541167.4513703 +2101 2099 635023.1717897 +2102 2099 25143014.98303 +2184 2099 10539814.37052 +2185 2099 -8593755.37553 +2186 2099 -17106970.31658 +2187 2099 35214817.70936 +2188 2099 -8010431.592745 +2189 2099 -49897177.80632 +2190 2099 11299136.49846 +2191 2099 8953622.07837 +2192 2099 -18005331.86323 +2205 2099 2142685.63364 +2206 2099 -17256955.18703 +2207 2099 -20719238.49606 +2208 2099 9504087.260305 +2209 2099 -890124.6000072 +2210 2099 -62094149.98014 +2211 2099 11975291.86111 +2212 2099 25797644.67693 +2213 2099 -37398448.87766 +2100 2100 355741984.4135 +2101 2100 44961279.6782 +2102 2100 -31969.75969148 +2103 2100 -68561627.83958 +2104 2100 -44445974.46271 +2105 2100 104238.8817037 +2106 2100 14895822.78727 +2107 2100 -10622658.7066 +2108 2100 32267.80197597 +2187 2100 -17800014.26928 +2188 2100 2698677.488893 +2189 2100 1551462.261342 +2190 2100 -41705002.75133 +2191 2100 9645791.927622 +2192 2100 43867713.61109 +2208 2100 -16877239.2765 +2209 2100 -9829899.681722 +2210 2100 -11739430.35753 +2211 2100 -6217083.919647 +2212 2100 11208473.36773 +2213 2100 -8861865.582222 +2214 2100 -34096968.27949 +2215 2100 -11099224.98192 +2216 2100 20338513.3096 +2217 2100 -25041925.40459 +2218 2100 -2623818.120598 +2219 2100 7377495.646649 +2101 2101 438394979.9803 +2102 2101 -1374967.912862 +2103 2101 -44445974.46271 +2104 2101 -48851461.31784 +2105 2101 70736.41377251 +2106 2101 -25289325.37086 +2107 2101 -56527401.72481 +2108 2101 225388.0604518 +2187 2101 2698677.488893 +2188 2101 -41565987.06324 +2189 2101 -16405461.24678 +2190 2101 9645791.927621 +2191 2101 -9711995.492945 +2192 2101 -7837709.116745 +2208 2101 -6163233.01385 +2209 2101 -32827357.81467 +2210 2101 -25487077.53535 +2211 2101 11208473.36773 +2212 2101 14441813.25705 +2213 2101 -343592.9009723 +2214 2101 -11099224.98192 +2215 2101 -29181326.97082 +2216 2101 16684309.53426 +2217 2101 -6290484.78847 +2218 2101 -42893379.81621 +2219 2101 33389531.26557 +2102 2102 485223127.0891 +2103 2102 104238.8817039 +2104 2102 70736.41377254 +2105 2102 15886177.56931 +2106 2102 101712.2464065 +2107 2102 225388.0604519 +2108 2102 69697319.35776 +2187 2102 1551462.261342 +2188 2102 -16405461.24678 +2189 2102 -25037127.36958 +2190 2102 43832991.38891 +2191 2102 -7837709.115223 +2192 2102 -84468948.44602 +2208 2102 -7303874.802406 +2209 2102 -25487077.53687 +2210 2102 -35397536.2799 +2211 2102 8672578.859343 +2212 2102 -343592.9009723 +2213 2102 -132262809.834 +2214 2102 20338513.3096 +2215 2102 16684309.53426 +2216 2102 -41345893.53323 +2217 2102 11709162.31661 +2218 2102 33389531.26557 +2219 2102 -59456308.27283 +2103 2103 235160980.54 +2104 2103 49827905.81482 +2105 2103 -60613.6507082 +2106 2103 -6682311.508679 +2107 2103 445974.4699243 +2108 2103 -46368.51136041 +2190 2103 -22984195.10845 +2191 2103 -1439748.456691 +2192 2103 -5463581.325088 +2211 2103 -34002271.30978 +2212 2103 -11099224.98192 +2213 2103 -20286486.70374 +2214 2103 -19462016.98302 +2215 2103 12439748.46031 +2216 2103 8109877.622006 +2217 2103 -35625759.01613 +2218 2103 99224.97830465 +2219 2103 -31109809.59318 +2104 2104 216380701.0278 +2105 2104 -57557.59448934 +2106 2104 15112641.13419 +2107 2104 62982521.95492 +2108 2104 -70736.41376597 +2190 2104 -5106415.124563 +2191 2104 -40637085.20186 +2192 2104 -33318959.81713 +2211 2104 -11099224.98192 +2212 2104 -29086630.00111 +2213 2104 -16649023.81002 +2214 2104 12439748.46031 +2215 2104 -24152876.89695 +2216 2104 6652293.15484 +2217 2104 3765891.646176 +2218 2104 -18197650.31745 +2219 2104 3315690.472307 +2105 2105 344308907.0334 +2106 2105 -46368.51135737 +2107 2105 -70736.41376615 +2108 2105 111171650.7816 +2190 2105 -13588581.32587 +2191 2105 -33318959.81713 +2192 2105 -72574594.68805 +2211 2105 -20286486.70374 +2212 2105 -16649023.81002 +2213 2105 -41093368.28065 +2214 2105 -8140122.375325 +2215 2105 -6681040.176303 +2216 2105 -122542387.5828 +2217 2105 -31109809.59507 +2218 2105 -3350976.196549 +2219 2105 -62654295.89483 +2106 2106 175362217.5958 +2107 2106 -18710674.62192 +2108 2106 -124860.3946307 +2190 2106 -17235215.74871 +2191 2106 7234108.357437 +2192 2106 10768374.41758 +2211 2106 -24757834.49561 +2212 2106 -6290484.788473 +2213 2106 -11658615.46133 +2214 2106 -35625759.01613 +2215 2106 3765891.64618 +2216 2106 31086718.17438 +2217 2106 -13575130.14034 +2218 2106 -4709515.215144 +2219 2106 -4345366.019486 +2107 2107 199519053.2267 +2108 2107 -225388.0604351 +2190 2107 7234108.357437 +2191 2107 -22798984.16571 +2192 2107 -16649023.81002 +2211 2107 -2623818.120601 +2212 2107 -42609288.90724 +2213 2107 -33277135.39015 +2214 2107 99224.97830848 +2215 2107 -18197650.31745 +2216 2107 3315690.472307 +2217 2107 -4709515.215143 +2218 2107 -7588016.01039 +2219 2107 6610468.727854 +2108 2108 264347362.4329 +2190 2108 10768374.41758 +2191 2108 -16649023.81002 +2192 2108 -34805722.44525 +2211 2108 -7361671.013591 +2212 2108 -33277135.39015 +2213 2108 -58698732.51554 +2214 2108 31086718.17251 +2215 2108 -3350976.196549 +2216 2108 -62654295.89483 +2217 2108 4283245.090209 +2218 2108 -6722864.603289 +2219 2108 -87025087.54648 +2109 2109 391468094.7324 +2110 2109 36666666.66066 +2111 2109 2662170.757228 +2112 2109 -201885224.5025 +2113 2109 -36666959.01753 +2114 2109 -2662149.068675 +2115 2109 13006025.1815 +2116 2109 29333625.68539 +2117 2109 -2152798.772422 +2220 2109 31947394.33292 +2221 2109 9166666.669681 +2222 2109 9728225.899101 +2223 2109 -74358253.63036 +2224 2109 -9166739.758898 +2225 2109 -45562288.72778 +2226 2109 -8166156.136015 +2227 2109 7333406.424962 +2228 2109 -9496761.446847 +2110 2110 336463888.7559 +2111 2110 -6944377.543016 +2112 2110 -36667105.19596 +2113 2110 -29548916.09098 +2114 2110 -3847225.37168 +2115 2110 44000438.52809 +2116 2110 13006025.1815 +2117 2110 2416691.307227 +2220 2110 9166666.66968 +2221 2110 18196342.83202 +2222 2110 5513941.008134 +2223 2110 -9166776.303507 +2224 2110 -31274176.50627 +2225 2110 -9941080.210835 +2226 2110 11000109.63744 +2227 2110 -8166156.136015 +2228 2110 11395946.69513 +2111 2111 385940866.4962 +2112 2111 -2662138.224395 +2113 2111 -3097217.158151 +2114 2111 2281351.682023 +2115 2111 -3229198.158633 +2116 2111 1611127.538151 +2117 2111 34682733.81733 +2220 2111 -8223530.275229 +2221 2111 -8847241.586827 +2222 2111 -79300461.72417 +2223 2111 -45527563.96779 +2224 2111 -9746597.980308 +2225 2111 -63128188.69225 +2226 2111 -14245142.17027 +2227 2111 7597297.796754 +2228 2111 -21776416.36271 +2112 2112 677810035.2011 +2113 2112 36667397.55284 +2114 2112 3125086.662505 +2115 2112 20859938.00677 +2116 2112 -36666959.01753 +2117 2112 2702569.081896 +2118 2112 -136819701.2443 +2119 2112 9.089708328247e-07 +2120 2112 -462970.1266867 +2121 2112 -51905201.38891 +2122 2112 36666666.66065 +2123 2112 -2702548.086863 +2220 2112 -72726245.22972 +2221 2112 -9166776.303506 +2222 2112 44231216.90386 +2223 2112 70575234.21716 +2224 2112 9166849.392726 +2225 2112 781227.3439141 +2226 2112 -20203256.3538 +2227 2112 -9166739.758899 +2228 2112 11899863.74724 +2229 2112 -60775629.25067 +2230 2112 -1.214444637299e-06 +2231 2112 -45012270.30212 +2232 2112 -20383999.6175 +2233 2112 9166666.669679 +2234 2112 -11899768.97017 +2113 2113 578802727.5875 +2114 2113 -8610918.562153 +2115 2113 -36667105.19596 +2116 2113 -107472939.8429 +2117 2113 4611020.401354 +2118 2113 9.685754776001e-07 +2119 2113 24514918.12315 +2120 2113 -2777734.795656 +2121 2113 36666666.66065 +2122 2113 -40904425.97421 +2123 2113 1513867.397816 +2220 2113 -9166739.758897 +2221 2113 -29642168.10562 +2222 2113 8204934.122165 +2223 2113 9166849.392726 +2224 2113 45823407.30156 +2225 2113 -2152765.098743 +2226 2113 -9166776.303508 +2227 2113 -52286475.83204 +2228 2113 37069600.58987 +2229 2113 -1.445412635803e-06 +2230 2113 -20441974.38895 +2231 2113 -694433.6992576 +2232 2113 9166666.669678 +2233 2113 -17633805.76247 +2234 2113 9357633.519253 +2114 2114 623143279.9755 +2115 2114 2737301.801614 +2116 2114 5388806.115241 +2117 2114 41364580.11227 +2118 2114 -462970.1266864 +2119 2114 -2777734.795656 +2120 2114 44192040.0554 +2121 2114 -2737270.309063 +2122 2114 1541645.175575 +2123 2114 -6819846.696327 +2220 2114 44196492.14387 +2221 2114 8010523.495484 +2222 2114 -58776166.2905 +2223 2114 781316.8545274 +2224 2114 -2152693.49136 +2225 2114 -107886912.3736 +2226 2114 11899911.13577 +2227 2114 37236269.31883 +2228 2114 -57440830.58835 +2229 2114 -44977548.07992 +2230 2114 -694433.6992576 +2231 2114 -59807200.44138 +2232 2114 -11899768.97017 +2233 2114 9357633.519253 +2234 2114 -21458826.37861 +2115 2115 391468094.7324 +2116 2115 36666666.66066 +2117 2115 2662170.757228 +2118 2115 -51881527.1465 +2119 2115 -36666666.66065 +2120 2115 2505785.245605 +2121 2115 -201885224.5025 +2122 2115 -36666959.01753 +2123 2115 -2662149.068675 +2124 2115 13006025.1815 +2125 2115 29333625.68539 +2126 2115 -2152798.772422 +2220 2115 -5106206.927443 +2221 2115 11000109.63744 +2222 2115 12682625.90274 +2223 2115 -15511422.68773 +2224 2115 -9166776.303506 +2225 2115 -10539940.2691 +2226 2115 31947394.33292 +2227 2115 9166666.669681 +2228 2115 9728225.899101 +2229 2115 -18848133.13973 +2230 2115 -9166666.66968 +2231 2115 -10597685.63642 +2232 2115 -74358253.63036 +2233 2115 -9166739.758898 +2234 2115 -45562288.72778 +2235 2115 -8166156.136015 +2236 2115 7333406.424962 +2237 2115 -9496761.446847 +2116 2116 336463888.7559 +2117 2116 -6944377.543016 +2118 2116 -36666666.66065 +2119 2116 -40880751.7318 +2120 2116 1263867.397843 +2121 2116 -36667105.19596 +2122 2116 -29548916.09098 +2123 2116 -3847225.37168 +2124 2116 44000438.52809 +2125 2116 13006025.1815 +2126 2116 2416691.307227 +2220 2116 7333406.424962 +2221 2116 -5106206.927443 +2222 2116 -6763956.526763 +2223 2116 -9166739.758897 +2224 2116 -47594642.16596 +2225 2116 -34569643.89832 +2226 2116 9166666.66968 +2227 2116 18196342.83202 +2228 2116 5513941.008134 +2229 2116 -9166666.669679 +2230 2116 -16097939.2847 +2231 2116 -8663199.819997 +2232 2116 -9166776.303507 +2233 2116 -31274176.50627 +2234 2116 -9941080.210835 +2235 2116 11000109.63744 +2236 2116 -8166156.136015 +2237 2116 11395946.69513 +2117 2117 385940866.4962 +2118 2117 2471063.023406 +2119 2117 1236089.620084 +2120 2117 -6756715.38321 +2121 2117 -2662138.224395 +2122 2117 -3097217.158151 +2123 2117 2281351.682023 +2124 2117 -3229198.158633 +2125 2117 1611127.538151 +2126 2117 34682733.81733 +2220 2117 8455083.935158 +2221 2117 -10145934.79014 +2222 2117 -13616551.80652 +2223 2117 -10539898.30291 +2224 2117 -34736312.74845 +2225 2117 -44929274.14549 +2226 2117 -8223530.275229 +2227 2117 -8847241.586827 +2228 2117 -79300461.72417 +2229 2117 -10597685.63642 +2230 2117 -8663199.819997 +2231 2117 -17363182.43788 +2232 2117 -45527563.96779 +2233 2117 -9746597.980308 +2234 2117 -63128188.69225 +2235 2117 -14245142.17027 +2236 2117 7597297.796754 +2237 2117 -21776416.36271 +2118 2118 626081101.6128 +2119 2118 7.033348083496e-06 +2120 2118 925940.2533548 +2121 2118 85765730.61463 +2122 2118 -3.814697265625e-06 +2123 2118 231485.0634534 +2127 2118 -136819701.2443 +2128 2118 9.089708328247e-07 +2129 2118 -462970.1266867 +2130 2118 -51905201.38891 +2131 2118 36666666.66065 +2132 2118 -2702548.086863 +2223 2118 -60367636.82651 +2224 2118 1.877546310425e-06 +2225 2118 44780785.23866 +2226 2118 -20276082.95081 +2227 2118 -9166666.66968 +2228 2118 11841897.70428 +2229 2118 51054233.83102 +2230 2118 1.788139343262e-06 +2231 2118 231485.0634618 +2232 2118 -7985170.87927 +2233 2118 -2.771615982056e-06 +2234 2118 57871.2658952 +2238 2118 -60775629.25067 +2239 2118 -1.214444637299e-06 +2240 2118 -45012270.30212 +2241 2118 -20383999.6175 +2242 2118 9166666.669679 +2243 2118 -11899768.97017 +2119 2119 538074898.3386 +2120 2119 -11110939.17715 +2121 2119 -2.861022949219e-06 +2122 2119 -53567337.94508 +2123 2119 5555469.588581 +2127 2119 9.685754776001e-07 +2128 2119 24514918.12315 +2129 2119 -2777734.795656 +2130 2119 36666666.66065 +2131 2119 -40904425.97421 +2132 2119 1513867.397816 +2223 2119 1.169741153717e-06 +2224 2119 -20033981.96478 +2225 2119 -694433.6992575 +2226 2119 -9166666.66968 +2227 2119 -17525889.09577 +2228 2119 9288189.074786 +2229 2119 1.966953277588e-06 +2230 2119 29052683.00161 +2231 2119 -2777734.795662 +2232 2119 -2.190470695496e-06 +2233 2119 -42818438.03636 +2234 2119 37305534.05859 +2238 2119 -1.445412635803e-06 +2239 2119 -20441974.38895 +2240 2119 -694433.6992576 +2241 2119 9166666.669678 +2242 2119 -17633805.76247 +2243 2119 9357633.519253 +2120 2120 616797415.4266 +2121 2120 231485.0634536 +2122 2120 5555469.588581 +2123 2120 82852085.35441 +2127 2120 -462970.1266864 +2128 2120 -2777734.795656 +2129 2120 44192040.0554 +2130 2120 -2737270.309063 +2131 2120 1541645.175575 +2132 2120 -6819846.696327 +2223 2120 44746063.01646 +2224 2120 -694433.6992574 +2225 2120 -58719220.64359 +2226 2120 11841897.70428 +2227 2120 9288189.074786 +2228 2120 -21171048.60074 +2229 2120 231485.0634617 +2230 2120 -2777734.795662 +2231 2120 -127043423.7988 +2232 2120 57871.26589543 +2233 2120 37277756.28083 +2234 2120 -57757921.43384 +2238 2120 -44977548.07992 +2239 2120 -694433.6992576 +2240 2120 -59807200.44138 +2241 2120 -11899768.97017 +2242 2120 9357633.519253 +2243 2120 -21458826.37861 +2121 2121 677810035.2011 +2122 2121 36667397.55284 +2123 2121 3125086.662505 +2124 2121 20859938.00677 +2125 2121 -36666959.01753 +2126 2121 2702569.081896 +2127 2121 -51881527.1465 +2128 2121 -36666666.66065 +2129 2121 2505785.245605 +2130 2121 -136819701.2443 +2131 2121 9.089708328247e-07 +2132 2121 -462970.1266867 +2133 2121 -51905201.38891 +2134 2121 36666666.66065 +2135 2121 -2702548.086863 +2223 2121 -18752053.59425 +2224 2121 9166666.66968 +2225 2121 10539814.37052 +2226 2121 -72726245.22972 +2227 2121 -9166776.303506 +2228 2121 44231216.90386 +2229 2121 -1865379.213624 +2230 2121 8.79168510437e-07 +2231 2121 57871.26589221 +2232 2121 70575234.21716 +2233 2121 9166849.392726 +2234 2121 781227.3439141 +2235 2121 -20203256.3538 +2236 2121 -9166739.758899 +2237 2121 11899863.74724 +2238 2121 -18848133.13973 +2239 2121 -9166666.66968 +2240 2121 -10597685.63642 +2241 2121 -60775629.25067 +2242 2121 -1.214444637299e-06 +2243 2121 -45012270.30212 +2244 2121 -20383999.6175 +2245 2121 9166666.669679 +2246 2121 -11899768.97017 +2122 2122 578802727.5875 +2123 2122 -8610918.562153 +2124 2122 -36667105.19596 +2125 2122 -107472939.8429 +2126 2122 4611020.401354 +2127 2122 -36666666.66065 +2128 2122 -40880751.7318 +2129 2122 1263867.397843 +2130 2122 9.685754776001e-07 +2131 2122 24514918.12315 +2132 2122 -2777734.795656 +2133 2122 36666666.66065 +2134 2122 -40904425.97421 +2135 2122 1513867.397816 +2223 2122 9166666.66968 +2224 2122 -16001859.73922 +2225 2122 -8593755.37553 +2226 2122 -9166739.758897 +2227 2122 -29642168.10562 +2228 2122 8204934.122165 +2229 2122 1.229345798492e-06 +2230 2122 -36698646.37071 +2231 2122 -34527799.26293 +2232 2122 9166849.392726 +2233 2122 45823407.30156 +2234 2122 -2152765.098743 +2235 2122 -9166776.303508 +2236 2122 -52286475.83204 +2237 2122 37069600.58987 +2238 2122 -9166666.669679 +2239 2122 -16097939.2847 +2240 2122 -8663199.819997 +2241 2122 -1.445412635803e-06 +2242 2122 -20441974.38895 +2243 2122 -694433.6992576 +2244 2122 9166666.669678 +2245 2122 -17633805.76247 +2246 2122 9357633.519253 +2123 2123 623143279.9755 +2124 2123 2737301.801614 +2125 2123 5388806.115241 +2126 2123 41364580.11227 +2127 2123 2471063.023406 +2128 2123 1236089.620084 +2129 2123 -6756715.38321 +2130 2123 -462970.1266864 +2131 2123 -2777734.795656 +2132 2123 44192040.0554 +2133 2123 -2737270.309063 +2134 2123 1541645.175575 +2135 2123 -6819846.696327 +2223 2123 10539814.37052 +2224 2123 -8593755.37553 +2225 2123 -17106970.31658 +2226 2123 44196492.14387 +2227 2123 8010523.495484 +2228 2123 -58776166.2905 +2229 2123 57871.26589252 +2230 2123 -34500021.48517 +2231 2123 -41438476.99211 +2232 2123 781316.8545274 +2233 2123 -2152693.49136 +2234 2123 -107886912.3736 +2235 2123 11899911.13577 +2236 2123 37236269.31883 +2237 2123 -57440830.58835 +2238 2123 -10597685.63642 +2239 2123 -8663199.819997 +2240 2123 -17363182.43788 +2241 2123 -44977548.07992 +2242 2123 -694433.6992576 +2243 2123 -59807200.44138 +2244 2123 -11899768.97017 +2245 2123 9357633.519253 +2246 2123 -21458826.37861 +2124 2124 391468094.7324 +2125 2124 36666666.66066 +2126 2124 2662170.757228 +2130 2124 -51881527.1465 +2131 2124 -36666666.66065 +2132 2124 2505785.245605 +2133 2124 -201885224.5025 +2134 2124 -36666959.01753 +2135 2124 -2662149.068675 +2136 2124 13006025.1815 +2137 2124 29333625.68539 +2138 2124 -2152798.772422 +2226 2124 -5106206.927443 +2227 2124 11000109.63744 +2228 2124 12682625.90274 +2232 2124 -15511422.68773 +2233 2124 -9166776.303506 +2234 2124 -10539940.2691 +2235 2124 31947394.33292 +2236 2124 9166666.669681 +2237 2124 9728225.899101 +2241 2124 -18848133.13973 +2242 2124 -9166666.66968 +2243 2124 -10597685.63642 +2244 2124 -74358253.63036 +2245 2124 -9166739.758898 +2246 2124 -45562288.72778 +2247 2124 -8166156.136015 +2248 2124 7333406.424962 +2249 2124 -9496761.446847 +2125 2125 336463888.7559 +2126 2125 -6944377.543016 +2130 2125 -36666666.66065 +2131 2125 -40880751.7318 +2132 2125 1263867.397843 +2133 2125 -36667105.19596 +2134 2125 -29548916.09098 +2135 2125 -3847225.37168 +2136 2125 44000438.52809 +2137 2125 13006025.1815 +2138 2125 2416691.307227 +2226 2125 7333406.424962 +2227 2125 -5106206.927443 +2228 2125 -6763956.526763 +2232 2125 -9166739.758897 +2233 2125 -47594642.16596 +2234 2125 -34569643.89832 +2235 2125 9166666.66968 +2236 2125 18196342.83202 +2237 2125 5513941.008134 +2241 2125 -9166666.669679 +2242 2125 -16097939.2847 +2243 2125 -8663199.819997 +2244 2125 -9166776.303507 +2245 2125 -31274176.50627 +2246 2125 -9941080.210835 +2247 2125 11000109.63744 +2248 2125 -8166156.136015 +2249 2125 11395946.69513 +2126 2126 385940866.4962 +2130 2126 2471063.023406 +2131 2126 1236089.620084 +2132 2126 -6756715.38321 +2133 2126 -2662138.224395 +2134 2126 -3097217.158151 +2135 2126 2281351.682023 +2136 2126 -3229198.158633 +2137 2126 1611127.538151 +2138 2126 34682733.81733 +2226 2126 8455083.935158 +2227 2126 -10145934.79014 +2228 2126 -13616551.80652 +2232 2126 -10539898.30291 +2233 2126 -34736312.74845 +2234 2126 -44929274.14549 +2235 2126 -8223530.275229 +2236 2126 -8847241.586827 +2237 2126 -79300461.72417 +2241 2126 -10597685.63642 +2242 2126 -8663199.819997 +2243 2126 -17363182.43788 +2244 2126 -45527563.96779 +2245 2126 -9746597.980308 +2246 2126 -63128188.69225 +2247 2126 -14245142.17027 +2248 2126 7597297.796754 +2249 2126 -21776416.36271 +2127 2127 626081101.6128 +2128 2127 7.033348083496e-06 +2129 2127 925940.2533548 +2130 2127 85765730.61463 +2131 2127 -3.814697265625e-06 +2132 2127 231485.0634534 +2139 2127 -136819701.2443 +2140 2127 9.089708328247e-07 +2141 2127 -462970.1266867 +2142 2127 -51905201.38891 +2143 2127 36666666.66065 +2144 2127 -2702548.086863 +2229 2127 -60367636.82651 +2230 2127 1.877546310425e-06 +2231 2127 44780785.23866 +2232 2127 -20276082.95081 +2233 2127 -9166666.66968 +2234 2127 11841897.70428 +2238 2127 51054233.83102 +2239 2127 1.788139343262e-06 +2240 2127 231485.0634618 +2241 2127 -7985170.87927 +2242 2127 -2.771615982056e-06 +2243 2127 57871.2658952 +2250 2127 -60775629.25067 +2251 2127 -1.214444637299e-06 +2252 2127 -45012270.30212 +2253 2127 -20383999.6175 +2254 2127 9166666.669679 +2255 2127 -11899768.97017 +2128 2128 538074898.3386 +2129 2128 -11110939.17715 +2130 2128 -2.861022949219e-06 +2131 2128 -53567337.94508 +2132 2128 5555469.588581 +2139 2128 9.685754776001e-07 +2140 2128 24514918.12315 +2141 2128 -2777734.795656 +2142 2128 36666666.66065 +2143 2128 -40904425.97421 +2144 2128 1513867.397816 +2229 2128 1.169741153717e-06 +2230 2128 -20033981.96478 +2231 2128 -694433.6992575 +2232 2128 -9166666.66968 +2233 2128 -17525889.09577 +2234 2128 9288189.074786 +2238 2128 1.966953277588e-06 +2239 2128 29052683.00161 +2240 2128 -2777734.795662 +2241 2128 -2.190470695496e-06 +2242 2128 -42818438.03636 +2243 2128 37305534.05859 +2250 2128 -1.445412635803e-06 +2251 2128 -20441974.38895 +2252 2128 -694433.6992576 +2253 2128 9166666.669678 +2254 2128 -17633805.76247 +2255 2128 9357633.519253 +2129 2129 616797415.4266 +2130 2129 231485.0634536 +2131 2129 5555469.588581 +2132 2129 82852085.35441 +2139 2129 -462970.1266864 +2140 2129 -2777734.795656 +2141 2129 44192040.0554 +2142 2129 -2737270.309063 +2143 2129 1541645.175575 +2144 2129 -6819846.696327 +2229 2129 44746063.01646 +2230 2129 -694433.6992574 +2231 2129 -58719220.64359 +2232 2129 11841897.70428 +2233 2129 9288189.074786 +2234 2129 -21171048.60074 +2238 2129 231485.0634617 +2239 2129 -2777734.795662 +2240 2129 -127043423.7988 +2241 2129 57871.26589543 +2242 2129 37277756.28083 +2243 2129 -57757921.43384 +2250 2129 -44977548.07992 +2251 2129 -694433.6992576 +2252 2129 -59807200.44138 +2253 2129 -11899768.97017 +2254 2129 9357633.519253 +2255 2129 -21458826.37861 +2130 2130 626081101.6128 +2131 2130 7.033348083496e-06 +2132 2130 925940.2533548 +2133 2130 85765730.61463 +2134 2130 -3.814697265625e-06 +2135 2130 231485.0634534 +2139 2130 -51881527.1465 +2140 2130 -36666666.66065 +2141 2130 2505785.245605 +2142 2130 -136819701.2443 +2143 2130 9.089708328247e-07 +2144 2130 -462970.1266867 +2145 2130 -51905201.38891 +2146 2130 36666666.66065 +2147 2130 -2702548.086863 +2229 2130 -18752053.59425 +2230 2130 9166666.66968 +2231 2130 10539814.37052 +2232 2130 -60367636.82651 +2233 2130 1.877546310425e-06 +2234 2130 44780785.23866 +2235 2130 -20276082.95081 +2236 2130 -9166666.66968 +2237 2130 11841897.70428 +2238 2130 -1865379.213624 +2239 2130 8.79168510437e-07 +2240 2130 57871.26589221 +2241 2130 51054233.83102 +2242 2130 1.788139343262e-06 +2243 2130 231485.0634618 +2244 2130 -7985170.87927 +2245 2130 -2.771615982056e-06 +2246 2130 57871.2658952 +2250 2130 -18848133.13973 +2251 2130 -9166666.66968 +2252 2130 -10597685.63642 +2253 2130 -60775629.25067 +2254 2130 -1.214444637299e-06 +2255 2130 -45012270.30212 +2256 2130 -20383999.6175 +2257 2130 9166666.669679 +2258 2130 -11899768.97017 +2131 2131 538074898.3386 +2132 2131 -11110939.17715 +2133 2131 -2.861022949219e-06 +2134 2131 -53567337.94508 +2135 2131 5555469.588581 +2139 2131 -36666666.66065 +2140 2131 -40880751.7318 +2141 2131 1263867.397843 +2142 2131 9.685754776001e-07 +2143 2131 24514918.12315 +2144 2131 -2777734.795656 +2145 2131 36666666.66065 +2146 2131 -40904425.97421 +2147 2131 1513867.397816 +2229 2131 9166666.66968 +2230 2131 -16001859.73922 +2231 2131 -8593755.37553 +2232 2131 1.169741153717e-06 +2233 2131 -20033981.96478 +2234 2131 -694433.6992575 +2235 2131 -9166666.66968 +2236 2131 -17525889.09577 +2237 2131 9288189.074786 +2238 2131 1.229345798492e-06 +2239 2131 -36698646.37071 +2240 2131 -34527799.26293 +2241 2131 1.966953277588e-06 +2242 2131 29052683.00161 +2243 2131 -2777734.795662 +2244 2131 -2.190470695496e-06 +2245 2131 -42818438.03636 +2246 2131 37305534.05859 +2250 2131 -9166666.669679 +2251 2131 -16097939.2847 +2252 2131 -8663199.819997 +2253 2131 -1.445412635803e-06 +2254 2131 -20441974.38895 +2255 2131 -694433.6992576 +2256 2131 9166666.669678 +2257 2131 -17633805.76247 +2258 2131 9357633.519253 +2132 2132 616797415.4266 +2133 2132 231485.0634536 +2134 2132 5555469.588581 +2135 2132 82852085.35441 +2139 2132 2471063.023406 +2140 2132 1236089.620084 +2141 2132 -6756715.38321 +2142 2132 -462970.1266864 +2143 2132 -2777734.795656 +2144 2132 44192040.0554 +2145 2132 -2737270.309063 +2146 2132 1541645.175575 +2147 2132 -6819846.696327 +2229 2132 10539814.37052 +2230 2132 -8593755.37553 +2231 2132 -17106970.31658 +2232 2132 44746063.01646 +2233 2132 -694433.6992574 +2234 2132 -58719220.64359 +2235 2132 11841897.70428 +2236 2132 9288189.074786 +2237 2132 -21171048.60074 +2238 2132 57871.26589252 +2239 2132 -34500021.48517 +2240 2132 -41438476.99211 +2241 2132 231485.0634617 +2242 2132 -2777734.795662 +2243 2132 -127043423.7988 +2244 2132 57871.26589543 +2245 2132 37277756.28083 +2246 2132 -57757921.43384 +2250 2132 -10597685.63642 +2251 2132 -8663199.819997 +2252 2132 -17363182.43788 +2253 2132 -44977548.07992 +2254 2132 -694433.6992576 +2255 2132 -59807200.44138 +2256 2132 -11899768.97017 +2257 2132 9357633.519253 +2258 2132 -21458826.37861 +2133 2133 677810035.2011 +2134 2133 36667397.55284 +2135 2133 3125086.662505 +2136 2133 20859938.00677 +2137 2133 -36666959.01753 +2138 2133 2702569.081896 +2142 2133 -51881527.1465 +2143 2133 -36666666.66065 +2144 2133 2505785.245605 +2145 2133 -136819701.2443 +2146 2133 9.089708328247e-07 +2147 2133 -462970.1266867 +2148 2133 -51905201.38891 +2149 2133 36666666.66065 +2150 2133 -2702548.086863 +2232 2133 -18752053.59425 +2233 2133 9166666.66968 +2234 2133 10539814.37052 +2235 2133 -72726245.22972 +2236 2133 -9166776.303506 +2237 2133 44231216.90386 +2241 2133 -1865379.213624 +2242 2133 8.79168510437e-07 +2243 2133 57871.26589221 +2244 2133 70575234.21716 +2245 2133 9166849.392726 +2246 2133 781227.3439141 +2247 2133 -20203256.3538 +2248 2133 -9166739.758899 +2249 2133 11899863.74724 +2253 2133 -18848133.13973 +2254 2133 -9166666.66968 +2255 2133 -10597685.63642 +2256 2133 -60775629.25067 +2257 2133 -1.214444637299e-06 +2258 2133 -45012270.30212 +2259 2133 -20383999.6175 +2260 2133 9166666.669679 +2261 2133 -11899768.97017 +2134 2134 578802727.5875 +2135 2134 -8610918.562153 +2136 2134 -36667105.19596 +2137 2134 -107472939.8429 +2138 2134 4611020.401354 +2142 2134 -36666666.66065 +2143 2134 -40880751.7318 +2144 2134 1263867.397843 +2145 2134 9.685754776001e-07 +2146 2134 24514918.12315 +2147 2134 -2777734.795656 +2148 2134 36666666.66065 +2149 2134 -40904425.97421 +2150 2134 1513867.397816 +2232 2134 9166666.66968 +2233 2134 -16001859.73922 +2234 2134 -8593755.37553 +2235 2134 -9166739.758897 +2236 2134 -29642168.10562 +2237 2134 8204934.122165 +2241 2134 1.229345798492e-06 +2242 2134 -36698646.37071 +2243 2134 -34527799.26293 +2244 2134 9166849.392726 +2245 2134 45823407.30156 +2246 2134 -2152765.098743 +2247 2134 -9166776.303508 +2248 2134 -52286475.83204 +2249 2134 37069600.58987 +2253 2134 -9166666.669679 +2254 2134 -16097939.2847 +2255 2134 -8663199.819997 +2256 2134 -1.445412635803e-06 +2257 2134 -20441974.38895 +2258 2134 -694433.6992576 +2259 2134 9166666.669678 +2260 2134 -17633805.76247 +2261 2134 9357633.519253 +2135 2135 623143279.9755 +2136 2135 2737301.801614 +2137 2135 5388806.115241 +2138 2135 41364580.11227 +2142 2135 2471063.023406 +2143 2135 1236089.620084 +2144 2135 -6756715.38321 +2145 2135 -462970.1266864 +2146 2135 -2777734.795656 +2147 2135 44192040.0554 +2148 2135 -2737270.309063 +2149 2135 1541645.175575 +2150 2135 -6819846.696327 +2232 2135 10539814.37052 +2233 2135 -8593755.37553 +2234 2135 -17106970.31658 +2235 2135 44196492.14387 +2236 2135 8010523.495484 +2237 2135 -58776166.2905 +2241 2135 57871.26589252 +2242 2135 -34500021.48517 +2243 2135 -41438476.99211 +2244 2135 781316.8545274 +2245 2135 -2152693.49136 +2246 2135 -107886912.3736 +2247 2135 11899911.13577 +2248 2135 37236269.31883 +2249 2135 -57440830.58835 +2253 2135 -10597685.63642 +2254 2135 -8663199.819997 +2255 2135 -17363182.43788 +2256 2135 -44977548.07992 +2257 2135 -694433.6992576 +2258 2135 -59807200.44138 +2259 2135 -11899768.97017 +2260 2135 9357633.519253 +2261 2135 -21458826.37861 +2136 2136 391468094.7324 +2137 2136 36666666.66066 +2138 2136 2662170.757228 +2145 2136 -51881527.1465 +2146 2136 -36666666.66065 +2147 2136 2505785.245605 +2148 2136 -201885224.5025 +2149 2136 -36666959.01753 +2150 2136 -2662149.068675 +2151 2136 13006025.1815 +2152 2136 29333625.68539 +2153 2136 -2152798.772422 +2235 2136 -5106206.927443 +2236 2136 11000109.63744 +2237 2136 12682625.90274 +2244 2136 -15511422.68773 +2245 2136 -9166776.303506 +2246 2136 -10539940.2691 +2247 2136 31947394.33292 +2248 2136 9166666.669681 +2249 2136 9728225.899101 +2256 2136 -18848133.13973 +2257 2136 -9166666.66968 +2258 2136 -10597685.63642 +2259 2136 -74358253.63036 +2260 2136 -9166739.758898 +2261 2136 -45562288.72778 +2262 2136 -8166156.136015 +2263 2136 7333406.424962 +2264 2136 -9496761.446847 +2137 2137 336463888.7559 +2138 2137 -6944377.543016 +2145 2137 -36666666.66065 +2146 2137 -40880751.7318 +2147 2137 1263867.397843 +2148 2137 -36667105.19596 +2149 2137 -29548916.09098 +2150 2137 -3847225.37168 +2151 2137 44000438.52809 +2152 2137 13006025.1815 +2153 2137 2416691.307227 +2235 2137 7333406.424962 +2236 2137 -5106206.927443 +2237 2137 -6763956.526763 +2244 2137 -9166739.758897 +2245 2137 -47594642.16596 +2246 2137 -34569643.89832 +2247 2137 9166666.66968 +2248 2137 18196342.83202 +2249 2137 5513941.008134 +2256 2137 -9166666.669679 +2257 2137 -16097939.2847 +2258 2137 -8663199.819997 +2259 2137 -9166776.303507 +2260 2137 -31274176.50627 +2261 2137 -9941080.210835 +2262 2137 11000109.63744 +2263 2137 -8166156.136015 +2264 2137 11395946.69513 +2138 2138 385940866.4962 +2145 2138 2471063.023406 +2146 2138 1236089.620084 +2147 2138 -6756715.38321 +2148 2138 -2662138.224395 +2149 2138 -3097217.158151 +2150 2138 2281351.682023 +2151 2138 -3229198.158633 +2152 2138 1611127.538151 +2153 2138 34682733.81733 +2235 2138 8455083.935158 +2236 2138 -10145934.79014 +2237 2138 -13616551.80652 +2244 2138 -10539898.30291 +2245 2138 -34736312.74845 +2246 2138 -44929274.14549 +2247 2138 -8223530.275229 +2248 2138 -8847241.586827 +2249 2138 -79300461.72417 +2256 2138 -10597685.63642 +2257 2138 -8663199.819997 +2258 2138 -17363182.43788 +2259 2138 -45527563.96779 +2260 2138 -9746597.980308 +2261 2138 -63128188.69225 +2262 2138 -14245142.17027 +2263 2138 7597297.796754 +2264 2138 -21776416.36271 +2139 2139 626081101.6128 +2140 2139 7.033348083496e-06 +2141 2139 925940.2533548 +2142 2139 85765730.61463 +2143 2139 -3.814697265625e-06 +2144 2139 231485.0634534 +2154 2139 -136819701.2443 +2155 2139 9.089708328247e-07 +2156 2139 -462970.1266867 +2157 2139 -51905201.38891 +2158 2139 36666666.66065 +2159 2139 -2702548.086863 +2238 2139 -60367636.82651 +2239 2139 1.877546310425e-06 +2240 2139 44780785.23866 +2241 2139 -20276082.95081 +2242 2139 -9166666.66968 +2243 2139 11841897.70428 +2250 2139 51054233.83102 +2251 2139 1.788139343262e-06 +2252 2139 231485.0634618 +2253 2139 -7985170.87927 +2254 2139 -2.771615982056e-06 +2255 2139 57871.2658952 +2265 2139 -60775629.25067 +2266 2139 -1.214444637299e-06 +2267 2139 -45012270.30212 +2268 2139 -20383999.6175 +2269 2139 9166666.669679 +2270 2139 -11899768.97017 +2140 2140 538074898.3386 +2141 2140 -11110939.17715 +2142 2140 -2.861022949219e-06 +2143 2140 -53567337.94508 +2144 2140 5555469.588581 +2154 2140 9.685754776001e-07 +2155 2140 24514918.12315 +2156 2140 -2777734.795656 +2157 2140 36666666.66065 +2158 2140 -40904425.97421 +2159 2140 1513867.397816 +2238 2140 1.169741153717e-06 +2239 2140 -20033981.96478 +2240 2140 -694433.6992575 +2241 2140 -9166666.66968 +2242 2140 -17525889.09577 +2243 2140 9288189.074786 +2250 2140 1.966953277588e-06 +2251 2140 29052683.00161 +2252 2140 -2777734.795662 +2253 2140 -2.190470695496e-06 +2254 2140 -42818438.03636 +2255 2140 37305534.05859 +2265 2140 -1.445412635803e-06 +2266 2140 -20441974.38895 +2267 2140 -694433.6992576 +2268 2140 9166666.669678 +2269 2140 -17633805.76247 +2270 2140 9357633.519253 +2141 2141 616797415.4266 +2142 2141 231485.0634536 +2143 2141 5555469.588581 +2144 2141 82852085.35441 +2154 2141 -462970.1266864 +2155 2141 -2777734.795656 +2156 2141 44192040.0554 +2157 2141 -2737270.309063 +2158 2141 1541645.175575 +2159 2141 -6819846.696327 +2238 2141 44746063.01646 +2239 2141 -694433.6992574 +2240 2141 -58719220.64359 +2241 2141 11841897.70428 +2242 2141 9288189.074786 +2243 2141 -21171048.60074 +2250 2141 231485.0634617 +2251 2141 -2777734.795662 +2252 2141 -127043423.7988 +2253 2141 57871.26589543 +2254 2141 37277756.28083 +2255 2141 -57757921.43384 +2265 2141 -44977548.07992 +2266 2141 -694433.6992576 +2267 2141 -59807200.44138 +2268 2141 -11899768.97017 +2269 2141 9357633.519253 +2270 2141 -21458826.37861 +2142 2142 626081101.6128 +2143 2142 7.033348083496e-06 +2144 2142 925940.2533548 +2145 2142 85765730.61463 +2146 2142 -3.814697265625e-06 +2147 2142 231485.0634534 +2154 2142 -51881527.1465 +2155 2142 -36666666.66065 +2156 2142 2505785.245605 +2157 2142 -136819701.2443 +2158 2142 9.089708328247e-07 +2159 2142 -462970.1266867 +2160 2142 -51905201.38891 +2161 2142 36666666.66065 +2162 2142 -2702548.086863 +2238 2142 -18752053.59425 +2239 2142 9166666.66968 +2240 2142 10539814.37052 +2241 2142 -60367636.82651 +2242 2142 1.877546310425e-06 +2243 2142 44780785.23866 +2244 2142 -20276082.95081 +2245 2142 -9166666.66968 +2246 2142 11841897.70428 +2250 2142 -1865379.213624 +2251 2142 8.79168510437e-07 +2252 2142 57871.26589221 +2253 2142 51054233.83102 +2254 2142 1.788139343262e-06 +2255 2142 231485.0634618 +2256 2142 -7985170.87927 +2257 2142 -2.771615982056e-06 +2258 2142 57871.2658952 +2265 2142 -18848133.13973 +2266 2142 -9166666.66968 +2267 2142 -10597685.63642 +2268 2142 -60775629.25067 +2269 2142 -1.214444637299e-06 +2270 2142 -45012270.30212 +2271 2142 -20383999.6175 +2272 2142 9166666.669679 +2273 2142 -11899768.97017 +2143 2143 538074898.3386 +2144 2143 -11110939.17715 +2145 2143 -2.861022949219e-06 +2146 2143 -53567337.94508 +2147 2143 5555469.588581 +2154 2143 -36666666.66065 +2155 2143 -40880751.7318 +2156 2143 1263867.397843 +2157 2143 9.685754776001e-07 +2158 2143 24514918.12315 +2159 2143 -2777734.795656 +2160 2143 36666666.66065 +2161 2143 -40904425.97421 +2162 2143 1513867.397816 +2238 2143 9166666.66968 +2239 2143 -16001859.73922 +2240 2143 -8593755.37553 +2241 2143 1.169741153717e-06 +2242 2143 -20033981.96478 +2243 2143 -694433.6992575 +2244 2143 -9166666.66968 +2245 2143 -17525889.09577 +2246 2143 9288189.074786 +2250 2143 1.229345798492e-06 +2251 2143 -36698646.37071 +2252 2143 -34527799.26293 +2253 2143 1.966953277588e-06 +2254 2143 29052683.00161 +2255 2143 -2777734.795662 +2256 2143 -2.190470695496e-06 +2257 2143 -42818438.03636 +2258 2143 37305534.05859 +2265 2143 -9166666.669679 +2266 2143 -16097939.2847 +2267 2143 -8663199.819997 +2268 2143 -1.445412635803e-06 +2269 2143 -20441974.38895 +2270 2143 -694433.6992576 +2271 2143 9166666.669678 +2272 2143 -17633805.76247 +2273 2143 9357633.519253 +2144 2144 616797415.4266 +2145 2144 231485.0634536 +2146 2144 5555469.588581 +2147 2144 82852085.35441 +2154 2144 2471063.023406 +2155 2144 1236089.620084 +2156 2144 -6756715.38321 +2157 2144 -462970.1266864 +2158 2144 -2777734.795656 +2159 2144 44192040.0554 +2160 2144 -2737270.309063 +2161 2144 1541645.175575 +2162 2144 -6819846.696327 +2238 2144 10539814.37052 +2239 2144 -8593755.37553 +2240 2144 -17106970.31658 +2241 2144 44746063.01646 +2242 2144 -694433.6992574 +2243 2144 -58719220.64359 +2244 2144 11841897.70428 +2245 2144 9288189.074786 +2246 2144 -21171048.60074 +2250 2144 57871.26589252 +2251 2144 -34500021.48517 +2252 2144 -41438476.99211 +2253 2144 231485.0634617 +2254 2144 -2777734.795662 +2255 2144 -127043423.7988 +2256 2144 57871.26589543 +2257 2144 37277756.28083 +2258 2144 -57757921.43384 +2265 2144 -10597685.63642 +2266 2144 -8663199.819997 +2267 2144 -17363182.43788 +2268 2144 -44977548.07992 +2269 2144 -694433.6992576 +2270 2144 -59807200.44138 +2271 2144 -11899768.97017 +2272 2144 9357633.519253 +2273 2144 -21458826.37861 +2145 2145 626081101.6128 +2146 2145 7.033348083496e-06 +2147 2145 925940.2533548 +2148 2145 85765730.61463 +2149 2145 -3.814697265625e-06 +2150 2145 231485.0634534 +2157 2145 -51881527.1465 +2158 2145 -36666666.66065 +2159 2145 2505785.245605 +2160 2145 -136819701.2443 +2161 2145 9.089708328247e-07 +2162 2145 -462970.1266867 +2163 2145 -51905201.38891 +2164 2145 36666666.66065 +2165 2145 -2702548.086863 +2241 2145 -18752053.59425 +2242 2145 9166666.66968 +2243 2145 10539814.37052 +2244 2145 -60367636.82651 +2245 2145 1.877546310425e-06 +2246 2145 44780785.23866 +2247 2145 -20276082.95081 +2248 2145 -9166666.66968 +2249 2145 11841897.70428 +2253 2145 -1865379.213624 +2254 2145 8.79168510437e-07 +2255 2145 57871.26589221 +2256 2145 51054233.83102 +2257 2145 1.788139343262e-06 +2258 2145 231485.0634618 +2259 2145 -7985170.87927 +2260 2145 -2.771615982056e-06 +2261 2145 57871.2658952 +2268 2145 -18848133.13973 +2269 2145 -9166666.66968 +2270 2145 -10597685.63642 +2271 2145 -60775629.25067 +2272 2145 -1.214444637299e-06 +2273 2145 -45012270.30212 +2274 2145 -20383999.6175 +2275 2145 9166666.669679 +2276 2145 -11899768.97017 +2146 2146 538074898.3386 +2147 2146 -11110939.17715 +2148 2146 -2.861022949219e-06 +2149 2146 -53567337.94508 +2150 2146 5555469.588581 +2157 2146 -36666666.66065 +2158 2146 -40880751.7318 +2159 2146 1263867.397843 +2160 2146 9.685754776001e-07 +2161 2146 24514918.12315 +2162 2146 -2777734.795656 +2163 2146 36666666.66065 +2164 2146 -40904425.97421 +2165 2146 1513867.397816 +2241 2146 9166666.66968 +2242 2146 -16001859.73922 +2243 2146 -8593755.37553 +2244 2146 1.169741153717e-06 +2245 2146 -20033981.96478 +2246 2146 -694433.6992575 +2247 2146 -9166666.66968 +2248 2146 -17525889.09577 +2249 2146 9288189.074786 +2253 2146 1.229345798492e-06 +2254 2146 -36698646.37071 +2255 2146 -34527799.26293 +2256 2146 1.966953277588e-06 +2257 2146 29052683.00161 +2258 2146 -2777734.795662 +2259 2146 -2.190470695496e-06 +2260 2146 -42818438.03636 +2261 2146 37305534.05859 +2268 2146 -9166666.669679 +2269 2146 -16097939.2847 +2270 2146 -8663199.819997 +2271 2146 -1.445412635803e-06 +2272 2146 -20441974.38895 +2273 2146 -694433.6992576 +2274 2146 9166666.669678 +2275 2146 -17633805.76247 +2276 2146 9357633.519253 +2147 2147 616797415.4266 +2148 2147 231485.0634536 +2149 2147 5555469.588581 +2150 2147 82852085.35441 +2157 2147 2471063.023406 +2158 2147 1236089.620084 +2159 2147 -6756715.38321 +2160 2147 -462970.1266864 +2161 2147 -2777734.795656 +2162 2147 44192040.0554 +2163 2147 -2737270.309063 +2164 2147 1541645.175575 +2165 2147 -6819846.696327 +2241 2147 10539814.37052 +2242 2147 -8593755.37553 +2243 2147 -17106970.31658 +2244 2147 44746063.01646 +2245 2147 -694433.6992574 +2246 2147 -58719220.64359 +2247 2147 11841897.70428 +2248 2147 9288189.074786 +2249 2147 -21171048.60074 +2253 2147 57871.26589252 +2254 2147 -34500021.48517 +2255 2147 -41438476.99211 +2256 2147 231485.0634617 +2257 2147 -2777734.795662 +2258 2147 -127043423.7988 +2259 2147 57871.26589543 +2260 2147 37277756.28083 +2261 2147 -57757921.43384 +2268 2147 -10597685.63642 +2269 2147 -8663199.819997 +2270 2147 -17363182.43788 +2271 2147 -44977548.07992 +2272 2147 -694433.6992576 +2273 2147 -59807200.44138 +2274 2147 -11899768.97017 +2275 2147 9357633.519253 +2276 2147 -21458826.37861 +2148 2148 677810035.2011 +2149 2148 36667397.55284 +2150 2148 3125086.662505 +2151 2148 20859938.00677 +2152 2148 -36666959.01753 +2153 2148 2702569.081896 +2160 2148 -51881527.1465 +2161 2148 -36666666.66065 +2162 2148 2505785.245605 +2163 2148 -136819701.2443 +2164 2148 9.089708328247e-07 +2165 2148 -462970.1266867 +2166 2148 -51905201.38891 +2167 2148 36666666.66065 +2168 2148 -2702548.086863 +2244 2148 -18752053.59425 +2245 2148 9166666.66968 +2246 2148 10539814.37052 +2247 2148 -72726245.22972 +2248 2148 -9166776.303506 +2249 2148 44231216.90386 +2256 2148 -1865379.213624 +2257 2148 8.79168510437e-07 +2258 2148 57871.26589221 +2259 2148 70575234.21716 +2260 2148 9166849.392726 +2261 2148 781227.3439141 +2262 2148 -20203256.3538 +2263 2148 -9166739.758899 +2264 2148 11899863.74724 +2271 2148 -18848133.13973 +2272 2148 -9166666.66968 +2273 2148 -10597685.63642 +2274 2148 -60775629.25067 +2275 2148 -1.214444637299e-06 +2276 2148 -45012270.30212 +2277 2148 -20383999.6175 +2278 2148 9166666.669679 +2279 2148 -11899768.97017 +2149 2149 578802727.5875 +2150 2149 -8610918.562153 +2151 2149 -36667105.19596 +2152 2149 -107472939.8429 +2153 2149 4611020.401354 +2160 2149 -36666666.66065 +2161 2149 -40880751.7318 +2162 2149 1263867.397843 +2163 2149 9.685754776001e-07 +2164 2149 24514918.12315 +2165 2149 -2777734.795656 +2166 2149 36666666.66065 +2167 2149 -40904425.97421 +2168 2149 1513867.397816 +2244 2149 9166666.66968 +2245 2149 -16001859.73922 +2246 2149 -8593755.37553 +2247 2149 -9166739.758897 +2248 2149 -29642168.10562 +2249 2149 8204934.122165 +2256 2149 1.229345798492e-06 +2257 2149 -36698646.37071 +2258 2149 -34527799.26293 +2259 2149 9166849.392726 +2260 2149 45823407.30156 +2261 2149 -2152765.098743 +2262 2149 -9166776.303508 +2263 2149 -52286475.83204 +2264 2149 37069600.58987 +2271 2149 -9166666.669679 +2272 2149 -16097939.2847 +2273 2149 -8663199.819997 +2274 2149 -1.445412635803e-06 +2275 2149 -20441974.38895 +2276 2149 -694433.6992576 +2277 2149 9166666.669678 +2278 2149 -17633805.76247 +2279 2149 9357633.519253 +2150 2150 623143279.9755 +2151 2150 2737301.801614 +2152 2150 5388806.115241 +2153 2150 41364580.11227 +2160 2150 2471063.023406 +2161 2150 1236089.620084 +2162 2150 -6756715.38321 +2163 2150 -462970.1266864 +2164 2150 -2777734.795656 +2165 2150 44192040.0554 +2166 2150 -2737270.309063 +2167 2150 1541645.175575 +2168 2150 -6819846.696327 +2244 2150 10539814.37052 +2245 2150 -8593755.37553 +2246 2150 -17106970.31658 +2247 2150 44196492.14387 +2248 2150 8010523.495484 +2249 2150 -58776166.2905 +2256 2150 57871.26589252 +2257 2150 -34500021.48517 +2258 2150 -41438476.99211 +2259 2150 781316.8545274 +2260 2150 -2152693.49136 +2261 2150 -107886912.3736 +2262 2150 11899911.13577 +2263 2150 37236269.31883 +2264 2150 -57440830.58835 +2271 2150 -10597685.63642 +2272 2150 -8663199.819997 +2273 2150 -17363182.43788 +2274 2150 -44977548.07992 +2275 2150 -694433.6992576 +2276 2150 -59807200.44138 +2277 2150 -11899768.97017 +2278 2150 9357633.519253 +2279 2150 -21458826.37861 +2151 2151 391468094.7324 +2152 2151 36666666.66066 +2153 2151 2662170.757228 +2163 2151 -51881527.1465 +2164 2151 -36666666.66065 +2165 2151 2505785.245605 +2166 2151 -201885224.5025 +2167 2151 -36666959.01753 +2168 2151 -2662149.068675 +2169 2151 13006025.1815 +2170 2151 29333625.68539 +2171 2151 -2152798.772422 +2247 2151 -5106206.927443 +2248 2151 11000109.63744 +2249 2151 12682625.90274 +2259 2151 -15511422.68773 +2260 2151 -9166776.303506 +2261 2151 -10539940.2691 +2262 2151 31947394.33292 +2263 2151 9166666.669681 +2264 2151 9728225.899101 +2274 2151 -18848133.13973 +2275 2151 -9166666.66968 +2276 2151 -10597685.63642 +2277 2151 -74358253.63036 +2278 2151 -9166739.758898 +2279 2151 -45562288.72778 +2280 2151 -8166156.136015 +2281 2151 7333406.424962 +2282 2151 -9496761.446847 +2152 2152 336463888.7559 +2153 2152 -6944377.543016 +2163 2152 -36666666.66065 +2164 2152 -40880751.7318 +2165 2152 1263867.397843 +2166 2152 -36667105.19596 +2167 2152 -29548916.09098 +2168 2152 -3847225.37168 +2169 2152 44000438.52809 +2170 2152 13006025.1815 +2171 2152 2416691.307227 +2247 2152 7333406.424962 +2248 2152 -5106206.927443 +2249 2152 -6763956.526763 +2259 2152 -9166739.758897 +2260 2152 -47594642.16596 +2261 2152 -34569643.89832 +2262 2152 9166666.66968 +2263 2152 18196342.83202 +2264 2152 5513941.008134 +2274 2152 -9166666.669679 +2275 2152 -16097939.2847 +2276 2152 -8663199.819997 +2277 2152 -9166776.303507 +2278 2152 -31274176.50627 +2279 2152 -9941080.210835 +2280 2152 11000109.63744 +2281 2152 -8166156.136015 +2282 2152 11395946.69513 +2153 2153 385940866.4962 +2163 2153 2471063.023406 +2164 2153 1236089.620084 +2165 2153 -6756715.38321 +2166 2153 -2662138.224395 +2167 2153 -3097217.158151 +2168 2153 2281351.682023 +2169 2153 -3229198.158633 +2170 2153 1611127.538151 +2171 2153 34682733.81733 +2247 2153 8455083.935158 +2248 2153 -10145934.79014 +2249 2153 -13616551.80652 +2259 2153 -10539898.30291 +2260 2153 -34736312.74845 +2261 2153 -44929274.14549 +2262 2153 -8223530.275229 +2263 2153 -8847241.586827 +2264 2153 -79300461.72417 +2274 2153 -10597685.63642 +2275 2153 -8663199.819997 +2276 2153 -17363182.43788 +2277 2153 -45527563.96779 +2278 2153 -9746597.980308 +2279 2153 -63128188.69225 +2280 2153 -14245142.17027 +2281 2153 7597297.796754 +2282 2153 -21776416.36271 +2154 2154 626081101.6128 +2155 2154 7.033348083496e-06 +2156 2154 925940.2533548 +2157 2154 85765730.61463 +2158 2154 -3.814697265625e-06 +2159 2154 231485.0634534 +2172 2154 -136819701.2443 +2173 2154 9.089708328247e-07 +2174 2154 -462970.1266867 +2175 2154 -51905201.38891 +2176 2154 36666666.66065 +2177 2154 -2702548.086863 +2250 2154 -60367636.82651 +2251 2154 1.877546310425e-06 +2252 2154 44780785.23866 +2253 2154 -20276082.95081 +2254 2154 -9166666.66968 +2255 2154 11841897.70428 +2265 2154 51054233.83102 +2266 2154 1.788139343262e-06 +2267 2154 231485.0634618 +2268 2154 -7985170.87927 +2269 2154 -2.771615982056e-06 +2270 2154 57871.2658952 +2283 2154 -60775629.25067 +2284 2154 -1.214444637299e-06 +2285 2154 -45012270.30212 +2286 2154 -20383999.6175 +2287 2154 9166666.669679 +2288 2154 -11899768.97017 +2155 2155 538074898.3386 +2156 2155 -11110939.17715 +2157 2155 -2.861022949219e-06 +2158 2155 -53567337.94508 +2159 2155 5555469.588581 +2172 2155 9.685754776001e-07 +2173 2155 24514918.12315 +2174 2155 -2777734.795656 +2175 2155 36666666.66065 +2176 2155 -40904425.97421 +2177 2155 1513867.397816 +2250 2155 1.169741153717e-06 +2251 2155 -20033981.96478 +2252 2155 -694433.6992575 +2253 2155 -9166666.66968 +2254 2155 -17525889.09577 +2255 2155 9288189.074786 +2265 2155 1.966953277588e-06 +2266 2155 29052683.00161 +2267 2155 -2777734.795662 +2268 2155 -2.190470695496e-06 +2269 2155 -42818438.03636 +2270 2155 37305534.05859 +2283 2155 -1.445412635803e-06 +2284 2155 -20441974.38895 +2285 2155 -694433.6992576 +2286 2155 9166666.669678 +2287 2155 -17633805.76247 +2288 2155 9357633.519253 +2156 2156 616797415.4266 +2157 2156 231485.0634536 +2158 2156 5555469.588581 +2159 2156 82852085.35441 +2172 2156 -462970.1266864 +2173 2156 -2777734.795656 +2174 2156 44192040.0554 +2175 2156 -2737270.309063 +2176 2156 1541645.175575 +2177 2156 -6819846.696327 +2250 2156 44746063.01646 +2251 2156 -694433.6992574 +2252 2156 -58719220.64359 +2253 2156 11841897.70428 +2254 2156 9288189.074786 +2255 2156 -21171048.60074 +2265 2156 231485.0634617 +2266 2156 -2777734.795662 +2267 2156 -127043423.7988 +2268 2156 57871.26589543 +2269 2156 37277756.28083 +2270 2156 -57757921.43384 +2283 2156 -44977548.07992 +2284 2156 -694433.6992576 +2285 2156 -59807200.44138 +2286 2156 -11899768.97017 +2287 2156 9357633.519253 +2288 2156 -21458826.37861 +2157 2157 626081101.6128 +2158 2157 7.033348083496e-06 +2159 2157 925940.2533548 +2160 2157 85765730.61463 +2161 2157 -3.814697265625e-06 +2162 2157 231485.0634534 +2172 2157 -51881527.1465 +2173 2157 -36666666.66065 +2174 2157 2505785.245605 +2175 2157 -136819701.2443 +2176 2157 9.089708328247e-07 +2177 2157 -462970.1266867 +2178 2157 -51905201.38891 +2179 2157 36666666.66065 +2180 2157 -2702548.086863 +2250 2157 -18752053.59425 +2251 2157 9166666.66968 +2252 2157 10539814.37052 +2253 2157 -60367636.82651 +2254 2157 1.877546310425e-06 +2255 2157 44780785.23866 +2256 2157 -20276082.95081 +2257 2157 -9166666.66968 +2258 2157 11841897.70428 +2265 2157 -1865379.213624 +2266 2157 8.79168510437e-07 +2267 2157 57871.26589221 +2268 2157 51054233.83102 +2269 2157 1.788139343262e-06 +2270 2157 231485.0634618 +2271 2157 -7985170.87927 +2272 2157 -2.771615982056e-06 +2273 2157 57871.2658952 +2283 2157 -18848133.13973 +2284 2157 -9166666.66968 +2285 2157 -10597685.63642 +2286 2157 -60775629.25067 +2287 2157 -1.214444637299e-06 +2288 2157 -45012270.30212 +2289 2157 -20383999.6175 +2290 2157 9166666.669679 +2291 2157 -11899768.97017 +2158 2158 538074898.3386 +2159 2158 -11110939.17715 +2160 2158 -2.861022949219e-06 +2161 2158 -53567337.94508 +2162 2158 5555469.588581 +2172 2158 -36666666.66065 +2173 2158 -40880751.7318 +2174 2158 1263867.397843 +2175 2158 9.685754776001e-07 +2176 2158 24514918.12315 +2177 2158 -2777734.795656 +2178 2158 36666666.66065 +2179 2158 -40904425.97421 +2180 2158 1513867.397816 +2250 2158 9166666.66968 +2251 2158 -16001859.73922 +2252 2158 -8593755.37553 +2253 2158 1.169741153717e-06 +2254 2158 -20033981.96478 +2255 2158 -694433.6992575 +2256 2158 -9166666.66968 +2257 2158 -17525889.09577 +2258 2158 9288189.074786 +2265 2158 1.229345798492e-06 +2266 2158 -36698646.37071 +2267 2158 -34527799.26293 +2268 2158 1.966953277588e-06 +2269 2158 29052683.00161 +2270 2158 -2777734.795662 +2271 2158 -2.190470695496e-06 +2272 2158 -42818438.03636 +2273 2158 37305534.05859 +2283 2158 -9166666.669679 +2284 2158 -16097939.2847 +2285 2158 -8663199.819997 +2286 2158 -1.445412635803e-06 +2287 2158 -20441974.38895 +2288 2158 -694433.6992576 +2289 2158 9166666.669678 +2290 2158 -17633805.76247 +2291 2158 9357633.519253 +2159 2159 616797415.4266 +2160 2159 231485.0634536 +2161 2159 5555469.588581 +2162 2159 82852085.35441 +2172 2159 2471063.023406 +2173 2159 1236089.620084 +2174 2159 -6756715.38321 +2175 2159 -462970.1266864 +2176 2159 -2777734.795656 +2177 2159 44192040.0554 +2178 2159 -2737270.309063 +2179 2159 1541645.175575 +2180 2159 -6819846.696327 +2250 2159 10539814.37052 +2251 2159 -8593755.37553 +2252 2159 -17106970.31658 +2253 2159 44746063.01646 +2254 2159 -694433.6992574 +2255 2159 -58719220.64359 +2256 2159 11841897.70428 +2257 2159 9288189.074786 +2258 2159 -21171048.60074 +2265 2159 57871.26589252 +2266 2159 -34500021.48517 +2267 2159 -41438476.99211 +2268 2159 231485.0634617 +2269 2159 -2777734.795662 +2270 2159 -127043423.7988 +2271 2159 57871.26589543 +2272 2159 37277756.28083 +2273 2159 -57757921.43384 +2283 2159 -10597685.63642 +2284 2159 -8663199.819997 +2285 2159 -17363182.43788 +2286 2159 -44977548.07992 +2287 2159 -694433.6992576 +2288 2159 -59807200.44138 +2289 2159 -11899768.97017 +2290 2159 9357633.519253 +2291 2159 -21458826.37861 +2160 2160 626081101.6128 +2161 2160 7.033348083496e-06 +2162 2160 925940.2533548 +2163 2160 85765730.61463 +2164 2160 -3.814697265625e-06 +2165 2160 231485.0634534 +2175 2160 -51881527.1465 +2176 2160 -36666666.66065 +2177 2160 2505785.245605 +2178 2160 -136819701.2443 +2179 2160 9.089708328247e-07 +2180 2160 -462970.1266867 +2181 2160 -51905201.38891 +2182 2160 36666666.66065 +2183 2160 -2702548.086863 +2253 2160 -18752053.59425 +2254 2160 9166666.66968 +2255 2160 10539814.37052 +2256 2160 -60367636.82651 +2257 2160 1.877546310425e-06 +2258 2160 44780785.23866 +2259 2160 -20276082.95081 +2260 2160 -9166666.66968 +2261 2160 11841897.70428 +2268 2160 -1865379.213624 +2269 2160 8.79168510437e-07 +2270 2160 57871.26589221 +2271 2160 51054233.83102 +2272 2160 1.788139343262e-06 +2273 2160 231485.0634618 +2274 2160 -7985170.87927 +2275 2160 -2.771615982056e-06 +2276 2160 57871.2658952 +2286 2160 -18848133.13973 +2287 2160 -9166666.66968 +2288 2160 -10597685.63642 +2289 2160 -60775629.25067 +2290 2160 -1.214444637299e-06 +2291 2160 -45012270.30212 +2292 2160 -20383999.6175 +2293 2160 9166666.669679 +2294 2160 -11899768.97017 +2161 2161 538074898.3386 +2162 2161 -11110939.17715 +2163 2161 -2.861022949219e-06 +2164 2161 -53567337.94508 +2165 2161 5555469.588581 +2175 2161 -36666666.66065 +2176 2161 -40880751.7318 +2177 2161 1263867.397843 +2178 2161 9.685754776001e-07 +2179 2161 24514918.12315 +2180 2161 -2777734.795656 +2181 2161 36666666.66065 +2182 2161 -40904425.97421 +2183 2161 1513867.397816 +2253 2161 9166666.66968 +2254 2161 -16001859.73922 +2255 2161 -8593755.37553 +2256 2161 1.169741153717e-06 +2257 2161 -20033981.96478 +2258 2161 -694433.6992575 +2259 2161 -9166666.66968 +2260 2161 -17525889.09577 +2261 2161 9288189.074786 +2268 2161 1.229345798492e-06 +2269 2161 -36698646.37071 +2270 2161 -34527799.26293 +2271 2161 1.966953277588e-06 +2272 2161 29052683.00161 +2273 2161 -2777734.795662 +2274 2161 -2.190470695496e-06 +2275 2161 -42818438.03636 +2276 2161 37305534.05859 +2286 2161 -9166666.669679 +2287 2161 -16097939.2847 +2288 2161 -8663199.819997 +2289 2161 -1.445412635803e-06 +2290 2161 -20441974.38895 +2291 2161 -694433.6992576 +2292 2161 9166666.669678 +2293 2161 -17633805.76247 +2294 2161 9357633.519253 +2162 2162 616797415.4266 +2163 2162 231485.0634536 +2164 2162 5555469.588581 +2165 2162 82852085.35441 +2175 2162 2471063.023406 +2176 2162 1236089.620084 +2177 2162 -6756715.38321 +2178 2162 -462970.1266864 +2179 2162 -2777734.795656 +2180 2162 44192040.0554 +2181 2162 -2737270.309063 +2182 2162 1541645.175575 +2183 2162 -6819846.696327 +2253 2162 10539814.37052 +2254 2162 -8593755.37553 +2255 2162 -17106970.31658 +2256 2162 44746063.01646 +2257 2162 -694433.6992574 +2258 2162 -58719220.64359 +2259 2162 11841897.70428 +2260 2162 9288189.074786 +2261 2162 -21171048.60074 +2268 2162 57871.26589252 +2269 2162 -34500021.48517 +2270 2162 -41438476.99211 +2271 2162 231485.0634617 +2272 2162 -2777734.795662 +2273 2162 -127043423.7988 +2274 2162 57871.26589543 +2275 2162 37277756.28083 +2276 2162 -57757921.43384 +2286 2162 -10597685.63642 +2287 2162 -8663199.819997 +2288 2162 -17363182.43788 +2289 2162 -44977548.07992 +2290 2162 -694433.6992576 +2291 2162 -59807200.44138 +2292 2162 -11899768.97017 +2293 2162 9357633.519253 +2294 2162 -21458826.37861 +2163 2163 626081101.6128 +2164 2163 7.033348083496e-06 +2165 2163 925940.2533548 +2166 2163 85765730.61463 +2167 2163 -3.814697265625e-06 +2168 2163 231485.0634534 +2178 2163 -51881527.1465 +2179 2163 -36666666.66065 +2180 2163 2505785.245605 +2181 2163 -136819701.2443 +2182 2163 9.089708328247e-07 +2183 2163 -462970.1266867 +2184 2163 -51905201.38891 +2185 2163 36666666.66065 +2186 2163 -2702548.086863 +2256 2163 -18752053.59425 +2257 2163 9166666.66968 +2258 2163 10539814.37052 +2259 2163 -60367636.82651 +2260 2163 1.877546310425e-06 +2261 2163 44780785.23866 +2262 2163 -20276082.95081 +2263 2163 -9166666.66968 +2264 2163 11841897.70428 +2271 2163 -1865379.213624 +2272 2163 8.79168510437e-07 +2273 2163 57871.26589221 +2274 2163 51054233.83102 +2275 2163 1.788139343262e-06 +2276 2163 231485.0634618 +2277 2163 -7985170.87927 +2278 2163 -2.771615982056e-06 +2279 2163 57871.2658952 +2289 2163 -18848133.13973 +2290 2163 -9166666.66968 +2291 2163 -10597685.63642 +2292 2163 -60775629.25067 +2293 2163 -1.214444637299e-06 +2294 2163 -45012270.30212 +2295 2163 -20383999.6175 +2296 2163 9166666.669679 +2297 2163 -11899768.97017 +2164 2164 538074898.3386 +2165 2164 -11110939.17715 +2166 2164 -2.861022949219e-06 +2167 2164 -53567337.94508 +2168 2164 5555469.588581 +2178 2164 -36666666.66065 +2179 2164 -40880751.7318 +2180 2164 1263867.397843 +2181 2164 9.685754776001e-07 +2182 2164 24514918.12315 +2183 2164 -2777734.795656 +2184 2164 36666666.66065 +2185 2164 -40904425.97421 +2186 2164 1513867.397816 +2256 2164 9166666.66968 +2257 2164 -16001859.73922 +2258 2164 -8593755.37553 +2259 2164 1.169741153717e-06 +2260 2164 -20033981.96478 +2261 2164 -694433.6992575 +2262 2164 -9166666.66968 +2263 2164 -17525889.09577 +2264 2164 9288189.074786 +2271 2164 1.229345798492e-06 +2272 2164 -36698646.37071 +2273 2164 -34527799.26293 +2274 2164 1.966953277588e-06 +2275 2164 29052683.00161 +2276 2164 -2777734.795662 +2277 2164 -2.190470695496e-06 +2278 2164 -42818438.03636 +2279 2164 37305534.05859 +2289 2164 -9166666.669679 +2290 2164 -16097939.2847 +2291 2164 -8663199.819997 +2292 2164 -1.445412635803e-06 +2293 2164 -20441974.38895 +2294 2164 -694433.6992576 +2295 2164 9166666.669678 +2296 2164 -17633805.76247 +2297 2164 9357633.519253 +2165 2165 616797415.4266 +2166 2165 231485.0634536 +2167 2165 5555469.588581 +2168 2165 82852085.35441 +2178 2165 2471063.023406 +2179 2165 1236089.620084 +2180 2165 -6756715.38321 +2181 2165 -462970.1266864 +2182 2165 -2777734.795656 +2183 2165 44192040.0554 +2184 2165 -2737270.309063 +2185 2165 1541645.175575 +2186 2165 -6819846.696327 +2256 2165 10539814.37052 +2257 2165 -8593755.37553 +2258 2165 -17106970.31658 +2259 2165 44746063.01646 +2260 2165 -694433.6992574 +2261 2165 -58719220.64359 +2262 2165 11841897.70428 +2263 2165 9288189.074786 +2264 2165 -21171048.60074 +2271 2165 57871.26589252 +2272 2165 -34500021.48517 +2273 2165 -41438476.99211 +2274 2165 231485.0634617 +2275 2165 -2777734.795662 +2276 2165 -127043423.7988 +2277 2165 57871.26589543 +2278 2165 37277756.28083 +2279 2165 -57757921.43384 +2289 2165 -10597685.63642 +2290 2165 -8663199.819997 +2291 2165 -17363182.43788 +2292 2165 -44977548.07992 +2293 2165 -694433.6992576 +2294 2165 -59807200.44138 +2295 2165 -11899768.97017 +2296 2165 9357633.519253 +2297 2165 -21458826.37861 +2166 2166 677810035.2011 +2167 2166 36667397.55284 +2168 2166 3125086.662505 +2169 2166 20859938.00677 +2170 2166 -36666959.01753 +2171 2166 2702569.081896 +2181 2166 -51881527.1465 +2182 2166 -36666666.66065 +2183 2166 2505785.245605 +2184 2166 -136819701.2443 +2185 2166 9.089708328247e-07 +2186 2166 -462970.1266867 +2187 2166 -51905201.38891 +2188 2166 36666666.66065 +2189 2166 -2702548.086863 +2259 2166 -18752053.59425 +2260 2166 9166666.66968 +2261 2166 10539814.37052 +2262 2166 -72726245.22972 +2263 2166 -9166776.303506 +2264 2166 44231216.90386 +2274 2166 -1865379.213624 +2275 2166 8.79168510437e-07 +2276 2166 57871.26589221 +2277 2166 70575234.21716 +2278 2166 9166849.392726 +2279 2166 781227.3439141 +2280 2166 -20203256.3538 +2281 2166 -9166739.758899 +2282 2166 11899863.74724 +2292 2166 -18848133.13973 +2293 2166 -9166666.66968 +2294 2166 -10597685.63642 +2295 2166 -60775629.25067 +2296 2166 -1.214444637299e-06 +2297 2166 -45012270.30212 +2298 2166 -20383999.6175 +2299 2166 9166666.669679 +2300 2166 -11899768.97017 +2167 2167 578802727.5875 +2168 2167 -8610918.562153 +2169 2167 -36667105.19596 +2170 2167 -107472939.8429 +2171 2167 4611020.401354 +2181 2167 -36666666.66065 +2182 2167 -40880751.7318 +2183 2167 1263867.397843 +2184 2167 9.685754776001e-07 +2185 2167 24514918.12315 +2186 2167 -2777734.795656 +2187 2167 36666666.66065 +2188 2167 -40904425.97421 +2189 2167 1513867.397816 +2259 2167 9166666.66968 +2260 2167 -16001859.73922 +2261 2167 -8593755.37553 +2262 2167 -9166739.758897 +2263 2167 -29642168.10562 +2264 2167 8204934.122165 +2274 2167 1.229345798492e-06 +2275 2167 -36698646.37071 +2276 2167 -34527799.26293 +2277 2167 9166849.392726 +2278 2167 45823407.30156 +2279 2167 -2152765.098743 +2280 2167 -9166776.303508 +2281 2167 -52286475.83204 +2282 2167 37069600.58987 +2292 2167 -9166666.669679 +2293 2167 -16097939.2847 +2294 2167 -8663199.819997 +2295 2167 -1.445412635803e-06 +2296 2167 -20441974.38895 +2297 2167 -694433.6992576 +2298 2167 9166666.669678 +2299 2167 -17633805.76247 +2300 2167 9357633.519253 +2168 2168 623143279.9755 +2169 2168 2737301.801614 +2170 2168 5388806.115241 +2171 2168 41364580.11227 +2181 2168 2471063.023406 +2182 2168 1236089.620084 +2183 2168 -6756715.38321 +2184 2168 -462970.1266864 +2185 2168 -2777734.795656 +2186 2168 44192040.0554 +2187 2168 -2737270.309063 +2188 2168 1541645.175575 +2189 2168 -6819846.696327 +2259 2168 10539814.37052 +2260 2168 -8593755.37553 +2261 2168 -17106970.31658 +2262 2168 44196492.14387 +2263 2168 8010523.495484 +2264 2168 -58776166.2905 +2274 2168 57871.26589252 +2275 2168 -34500021.48517 +2276 2168 -41438476.99211 +2277 2168 781316.8545274 +2278 2168 -2152693.49136 +2279 2168 -107886912.3736 +2280 2168 11899911.13577 +2281 2168 37236269.31883 +2282 2168 -57440830.58835 +2292 2168 -10597685.63642 +2293 2168 -8663199.819997 +2294 2168 -17363182.43788 +2295 2168 -44977548.07992 +2296 2168 -694433.6992576 +2297 2168 -59807200.44138 +2298 2168 -11899768.97017 +2299 2168 9357633.519253 +2300 2168 -21458826.37861 +2169 2169 396493735.9168 +2170 2169 -24615960.06481 +2171 2169 -1253254.124483 +2184 2169 -51881527.1465 +2185 2169 -36666666.66065 +2186 2169 2505785.245605 +2187 2169 -60876355.65992 +2188 2169 24612478.72648 +2189 2169 -274481.5008204 +2190 2169 -176880452.1819 +2191 2169 29336814.66686 +2192 2169 -277822.6407411 +2262 2169 -5106206.927443 +2263 2169 11000109.63744 +2264 2169 12682625.90274 +2277 2169 -15511422.68773 +2278 2169 -9166776.303506 +2279 2169 -10539940.2691 +2280 2169 47665090.09198 +2281 2169 -6025687.958198 +2282 2169 4998799.242218 +2295 2169 -18848133.13973 +2296 2169 -9166666.66968 +2297 2169 -10597685.63642 +2298 2169 -30685926.23396 +2299 2169 6024859.53953 +2300 2169 -26422475.28228 +2301 2169 -44005330.74077 +2302 2169 7334161.754413 +2303 2169 -1631853.686012 +2170 2170 667488218.5831 +2171 2170 -10464919.5182 +2184 2170 -36666666.66065 +2185 2170 -40880751.7318 +2186 2170 1263867.397843 +2187 2170 24610738.05731 +2188 2170 83897643.7762 +2189 2170 -1992796.476061 +2190 2170 44005222.00029 +2191 2170 -475316831.8494 +2192 2170 4194074.09632 +2262 2170 7333406.424962 +2263 2170 -5106206.927443 +2264 2170 -6763956.526763 +2277 2170 -9166739.758897 +2278 2170 -47594642.16596 +2279 2170 -34569643.89832 +2280 2170 -6025687.958199 +2281 2170 111708208.2815 +2282 2170 1658363.194039 +2295 2170 -9166666.669679 +2296 2170 -16097939.2847 +2297 2170 -8663199.819997 +2298 2170 6024445.330197 +2299 2170 5565061.370466 +2300 2170 5481763.258292 +2301 2170 11001242.63162 +2302 2170 -114966410.9115 +2303 2170 17983542.55927 +2171 2171 430799078.9239 +2184 2171 2471063.023406 +2185 2171 1236089.620084 +2186 2171 -6756715.38321 +2187 2171 -1038349.313469 +2188 2171 -1881646.106394 +2189 2171 48412119.65877 +2190 2171 -416733.9611113 +2191 2171 4083003.025873 +2192 2171 -173244826.151 +2262 2171 8455083.935158 +2263 2171 -10145934.79014 +2264 2171 -13616551.80652 +2277 2171 -10539898.30291 +2278 2171 -34736312.74845 +2279 2171 -44929274.14549 +2280 2171 -5539432.672724 +2281 2171 -6660470.145771 +2282 2171 -26564808.1013 +2295 2171 -10597685.63642 +2296 2171 -8663199.819997 +2297 2171 -17363182.43788 +2298 2171 -26596081.38737 +2299 2171 5565517.502875 +2300 2171 -28451527.40463 +2301 2171 -2447780.529017 +2302 2171 17330703.15128 +2303 2171 -46386468.4713 +2172 2172 626081101.6128 +2173 2172 7.033348083496e-06 +2174 2172 925940.2533548 +2175 2172 85765730.61463 +2176 2172 -3.814697265625e-06 +2177 2172 231485.0634534 +2193 2172 -136819701.2443 +2194 2172 9.089708328247e-07 +2195 2172 -462970.1266867 +2196 2172 -51905201.38891 +2197 2172 36666666.66065 +2198 2172 -2702548.086863 +2265 2172 -60367636.82651 +2266 2172 1.877546310425e-06 +2267 2172 44780785.23866 +2268 2172 -20276082.95081 +2269 2172 -9166666.66968 +2270 2172 11841897.70428 +2283 2172 51054233.83102 +2284 2172 1.788139343262e-06 +2285 2172 231485.0634618 +2286 2172 -7985170.87927 +2287 2172 -2.771615982056e-06 +2288 2172 57871.2658952 +2304 2172 -60775629.25067 +2305 2172 -1.214444637299e-06 +2306 2172 -45012270.30212 +2307 2172 -20383999.6175 +2308 2172 9166666.669679 +2309 2172 -11899768.97017 +2173 2173 538074898.3386 +2174 2173 -11110939.17715 +2175 2173 -2.861022949219e-06 +2176 2173 -53567337.94508 +2177 2173 5555469.588581 +2193 2173 9.685754776001e-07 +2194 2173 24514918.12315 +2195 2173 -2777734.795656 +2196 2173 36666666.66065 +2197 2173 -40904425.97421 +2198 2173 1513867.397816 +2265 2173 1.169741153717e-06 +2266 2173 -20033981.96478 +2267 2173 -694433.6992575 +2268 2173 -9166666.66968 +2269 2173 -17525889.09577 +2270 2173 9288189.074786 +2283 2173 1.966953277588e-06 +2284 2173 29052683.00161 +2285 2173 -2777734.795662 +2286 2173 -2.190470695496e-06 +2287 2173 -42818438.03636 +2288 2173 37305534.05859 +2304 2173 -1.445412635803e-06 +2305 2173 -20441974.38895 +2306 2173 -694433.6992576 +2307 2173 9166666.669678 +2308 2173 -17633805.76247 +2309 2173 9357633.519253 +2174 2174 616797415.4266 +2175 2174 231485.0634536 +2176 2174 5555469.588581 +2177 2174 82852085.35441 +2193 2174 -462970.1266864 +2194 2174 -2777734.795656 +2195 2174 44192040.0554 +2196 2174 -2737270.309063 +2197 2174 1541645.175575 +2198 2174 -6819846.696327 +2265 2174 44746063.01646 +2266 2174 -694433.6992574 +2267 2174 -58719220.64359 +2268 2174 11841897.70428 +2269 2174 9288189.074786 +2270 2174 -21171048.60074 +2283 2174 231485.0634617 +2284 2174 -2777734.795662 +2285 2174 -127043423.7988 +2286 2174 57871.26589543 +2287 2174 37277756.28083 +2288 2174 -57757921.43384 +2304 2174 -44977548.07992 +2305 2174 -694433.6992576 +2306 2174 -59807200.44138 +2307 2174 -11899768.97017 +2308 2174 9357633.519253 +2309 2174 -21458826.37861 +2175 2175 626081101.6128 +2176 2175 7.033348083496e-06 +2177 2175 925940.2533548 +2178 2175 85765730.61463 +2179 2175 -3.814697265625e-06 +2180 2175 231485.0634534 +2193 2175 -51881527.1465 +2194 2175 -36666666.66065 +2195 2175 2505785.245605 +2196 2175 -136819701.2443 +2197 2175 9.089708328247e-07 +2198 2175 -462970.1266867 +2199 2175 -51905201.38891 +2200 2175 36666666.66065 +2201 2175 -2702548.086863 +2265 2175 -18752053.59425 +2266 2175 9166666.66968 +2267 2175 10539814.37052 +2268 2175 -60367636.82651 +2269 2175 1.877546310425e-06 +2270 2175 44780785.23866 +2271 2175 -20276082.95081 +2272 2175 -9166666.66968 +2273 2175 11841897.70428 +2283 2175 -1865379.213624 +2284 2175 8.79168510437e-07 +2285 2175 57871.26589221 +2286 2175 51054233.83102 +2287 2175 1.788139343262e-06 +2288 2175 231485.0634618 +2289 2175 -7985170.87927 +2290 2175 -2.771615982056e-06 +2291 2175 57871.2658952 +2304 2175 -18848133.13973 +2305 2175 -9166666.66968 +2306 2175 -10597685.63642 +2307 2175 -60775629.25067 +2308 2175 -1.214444637299e-06 +2309 2175 -45012270.30212 +2310 2175 -20383999.6175 +2311 2175 9166666.669679 +2312 2175 -11899768.97017 +2176 2176 538074898.3386 +2177 2176 -11110939.17715 +2178 2176 -2.861022949219e-06 +2179 2176 -53567337.94508 +2180 2176 5555469.588581 +2193 2176 -36666666.66065 +2194 2176 -40880751.7318 +2195 2176 1263867.397843 +2196 2176 9.685754776001e-07 +2197 2176 24514918.12315 +2198 2176 -2777734.795656 +2199 2176 36666666.66065 +2200 2176 -40904425.97421 +2201 2176 1513867.397816 +2265 2176 9166666.66968 +2266 2176 -16001859.73922 +2267 2176 -8593755.37553 +2268 2176 1.169741153717e-06 +2269 2176 -20033981.96478 +2270 2176 -694433.6992575 +2271 2176 -9166666.66968 +2272 2176 -17525889.09577 +2273 2176 9288189.074786 +2283 2176 1.229345798492e-06 +2284 2176 -36698646.37071 +2285 2176 -34527799.26293 +2286 2176 1.966953277588e-06 +2287 2176 29052683.00161 +2288 2176 -2777734.795662 +2289 2176 -2.190470695496e-06 +2290 2176 -42818438.03636 +2291 2176 37305534.05859 +2304 2176 -9166666.669679 +2305 2176 -16097939.2847 +2306 2176 -8663199.819997 +2307 2176 -1.445412635803e-06 +2308 2176 -20441974.38895 +2309 2176 -694433.6992576 +2310 2176 9166666.669678 +2311 2176 -17633805.76247 +2312 2176 9357633.519253 +2177 2177 616797415.4266 +2178 2177 231485.0634536 +2179 2177 5555469.588581 +2180 2177 82852085.35441 +2193 2177 2471063.023406 +2194 2177 1236089.620084 +2195 2177 -6756715.38321 +2196 2177 -462970.1266864 +2197 2177 -2777734.795656 +2198 2177 44192040.0554 +2199 2177 -2737270.309063 +2200 2177 1541645.175575 +2201 2177 -6819846.696327 +2265 2177 10539814.37052 +2266 2177 -8593755.37553 +2267 2177 -17106970.31658 +2268 2177 44746063.01646 +2269 2177 -694433.6992574 +2270 2177 -58719220.64359 +2271 2177 11841897.70428 +2272 2177 9288189.074786 +2273 2177 -21171048.60074 +2283 2177 57871.26589252 +2284 2177 -34500021.48517 +2285 2177 -41438476.99211 +2286 2177 231485.0634617 +2287 2177 -2777734.795662 +2288 2177 -127043423.7988 +2289 2177 57871.26589543 +2290 2177 37277756.28083 +2291 2177 -57757921.43384 +2304 2177 -10597685.63642 +2305 2177 -8663199.819997 +2306 2177 -17363182.43788 +2307 2177 -44977548.07992 +2308 2177 -694433.6992576 +2309 2177 -59807200.44138 +2310 2177 -11899768.97017 +2311 2177 9357633.519253 +2312 2177 -21458826.37861 +2178 2178 626081101.6128 +2179 2178 7.033348083496e-06 +2180 2178 925940.2533548 +2181 2178 85765730.61463 +2182 2178 -3.814697265625e-06 +2183 2178 231485.0634534 +2196 2178 -51881527.1465 +2197 2178 -36666666.66065 +2198 2178 2505785.245605 +2199 2178 -136819701.2443 +2200 2178 9.089708328247e-07 +2201 2178 -462970.1266867 +2202 2178 -51905201.38891 +2203 2178 36666666.66065 +2204 2178 -2702548.086863 +2268 2178 -18752053.59425 +2269 2178 9166666.66968 +2270 2178 10539814.37052 +2271 2178 -60367636.82651 +2272 2178 1.877546310425e-06 +2273 2178 44780785.23866 +2274 2178 -20276082.95081 +2275 2178 -9166666.66968 +2276 2178 11841897.70428 +2286 2178 -1865379.213624 +2287 2178 8.79168510437e-07 +2288 2178 57871.26589221 +2289 2178 51054233.83102 +2290 2178 1.788139343262e-06 +2291 2178 231485.0634618 +2292 2178 -7985170.87927 +2293 2178 -2.771615982056e-06 +2294 2178 57871.2658952 +2307 2178 -18848133.13973 +2308 2178 -9166666.66968 +2309 2178 -10597685.63642 +2310 2178 -60775629.25067 +2311 2178 -1.214444637299e-06 +2312 2178 -45012270.30212 +2313 2178 -20383999.6175 +2314 2178 9166666.669679 +2315 2178 -11899768.97017 +2179 2179 538074898.3386 +2180 2179 -11110939.17715 +2181 2179 -2.861022949219e-06 +2182 2179 -53567337.94508 +2183 2179 5555469.588581 +2196 2179 -36666666.66065 +2197 2179 -40880751.7318 +2198 2179 1263867.397843 +2199 2179 9.685754776001e-07 +2200 2179 24514918.12315 +2201 2179 -2777734.795656 +2202 2179 36666666.66065 +2203 2179 -40904425.97421 +2204 2179 1513867.397816 +2268 2179 9166666.66968 +2269 2179 -16001859.73922 +2270 2179 -8593755.37553 +2271 2179 1.169741153717e-06 +2272 2179 -20033981.96478 +2273 2179 -694433.6992575 +2274 2179 -9166666.66968 +2275 2179 -17525889.09577 +2276 2179 9288189.074786 +2286 2179 1.229345798492e-06 +2287 2179 -36698646.37071 +2288 2179 -34527799.26293 +2289 2179 1.966953277588e-06 +2290 2179 29052683.00161 +2291 2179 -2777734.795662 +2292 2179 -2.190470695496e-06 +2293 2179 -42818438.03636 +2294 2179 37305534.05859 +2307 2179 -9166666.669679 +2308 2179 -16097939.2847 +2309 2179 -8663199.819997 +2310 2179 -1.445412635803e-06 +2311 2179 -20441974.38895 +2312 2179 -694433.6992576 +2313 2179 9166666.669678 +2314 2179 -17633805.76247 +2315 2179 9357633.519253 +2180 2180 616797415.4266 +2181 2180 231485.0634536 +2182 2180 5555469.588581 +2183 2180 82852085.35441 +2196 2180 2471063.023406 +2197 2180 1236089.620084 +2198 2180 -6756715.38321 +2199 2180 -462970.1266864 +2200 2180 -2777734.795656 +2201 2180 44192040.0554 +2202 2180 -2737270.309063 +2203 2180 1541645.175575 +2204 2180 -6819846.696327 +2268 2180 10539814.37052 +2269 2180 -8593755.37553 +2270 2180 -17106970.31658 +2271 2180 44746063.01646 +2272 2180 -694433.6992574 +2273 2180 -58719220.64359 +2274 2180 11841897.70428 +2275 2180 9288189.074786 +2276 2180 -21171048.60074 +2286 2180 57871.26589252 +2287 2180 -34500021.48517 +2288 2180 -41438476.99211 +2289 2180 231485.0634617 +2290 2180 -2777734.795662 +2291 2180 -127043423.7988 +2292 2180 57871.26589543 +2293 2180 37277756.28083 +2294 2180 -57757921.43384 +2307 2180 -10597685.63642 +2308 2180 -8663199.819997 +2309 2180 -17363182.43788 +2310 2180 -44977548.07992 +2311 2180 -694433.6992576 +2312 2180 -59807200.44138 +2313 2180 -11899768.97017 +2314 2180 9357633.519253 +2315 2180 -21458826.37861 +2181 2181 626081101.6128 +2182 2181 7.033348083496e-06 +2183 2181 925940.2533548 +2184 2181 85765730.61463 +2185 2181 -3.814697265625e-06 +2186 2181 231485.0634534 +2199 2181 -51881527.1465 +2200 2181 -36666666.66065 +2201 2181 2505785.245605 +2202 2181 -136819701.2443 +2203 2181 9.089708328247e-07 +2204 2181 -462970.1266867 +2205 2181 -51905201.38891 +2206 2181 36666666.66065 +2207 2181 -2702548.086863 +2271 2181 -18752053.59425 +2272 2181 9166666.66968 +2273 2181 10539814.37052 +2274 2181 -60367636.82651 +2275 2181 1.877546310425e-06 +2276 2181 44780785.23866 +2277 2181 -20276082.95081 +2278 2181 -9166666.66968 +2279 2181 11841897.70428 +2289 2181 -1865379.213624 +2290 2181 8.79168510437e-07 +2291 2181 57871.26589221 +2292 2181 51054233.83102 +2293 2181 1.788139343262e-06 +2294 2181 231485.0634618 +2295 2181 -7985170.87927 +2296 2181 -2.771615982056e-06 +2297 2181 57871.2658952 +2310 2181 -18848133.13973 +2311 2181 -9166666.66968 +2312 2181 -10597685.63642 +2313 2181 -60775629.25067 +2314 2181 -1.214444637299e-06 +2315 2181 -45012270.30212 +2316 2181 -20383999.6175 +2317 2181 9166666.669679 +2318 2181 -11899768.97017 +2182 2182 538074898.3386 +2183 2182 -11110939.17715 +2184 2182 -2.861022949219e-06 +2185 2182 -53567337.94508 +2186 2182 5555469.588581 +2199 2182 -36666666.66065 +2200 2182 -40880751.7318 +2201 2182 1263867.397843 +2202 2182 9.685754776001e-07 +2203 2182 24514918.12315 +2204 2182 -2777734.795656 +2205 2182 36666666.66065 +2206 2182 -40904425.97421 +2207 2182 1513867.397816 +2271 2182 9166666.66968 +2272 2182 -16001859.73922 +2273 2182 -8593755.37553 +2274 2182 1.169741153717e-06 +2275 2182 -20033981.96478 +2276 2182 -694433.6992575 +2277 2182 -9166666.66968 +2278 2182 -17525889.09577 +2279 2182 9288189.074786 +2289 2182 1.229345798492e-06 +2290 2182 -36698646.37071 +2291 2182 -34527799.26293 +2292 2182 1.966953277588e-06 +2293 2182 29052683.00161 +2294 2182 -2777734.795662 +2295 2182 -2.190470695496e-06 +2296 2182 -42818438.03636 +2297 2182 37305534.05859 +2310 2182 -9166666.669679 +2311 2182 -16097939.2847 +2312 2182 -8663199.819997 +2313 2182 -1.445412635803e-06 +2314 2182 -20441974.38895 +2315 2182 -694433.6992576 +2316 2182 9166666.669678 +2317 2182 -17633805.76247 +2318 2182 9357633.519253 +2183 2183 616797415.4266 +2184 2183 231485.0634536 +2185 2183 5555469.588581 +2186 2183 82852085.35441 +2199 2183 2471063.023406 +2200 2183 1236089.620084 +2201 2183 -6756715.38321 +2202 2183 -462970.1266864 +2203 2183 -2777734.795656 +2204 2183 44192040.0554 +2205 2183 -2737270.309063 +2206 2183 1541645.175575 +2207 2183 -6819846.696327 +2271 2183 10539814.37052 +2272 2183 -8593755.37553 +2273 2183 -17106970.31658 +2274 2183 44746063.01646 +2275 2183 -694433.6992574 +2276 2183 -58719220.64359 +2277 2183 11841897.70428 +2278 2183 9288189.074786 +2279 2183 -21171048.60074 +2289 2183 57871.26589252 +2290 2183 -34500021.48517 +2291 2183 -41438476.99211 +2292 2183 231485.0634617 +2293 2183 -2777734.795662 +2294 2183 -127043423.7988 +2295 2183 57871.26589543 +2296 2183 37277756.28083 +2297 2183 -57757921.43384 +2310 2183 -10597685.63642 +2311 2183 -8663199.819997 +2312 2183 -17363182.43788 +2313 2183 -44977548.07992 +2314 2183 -694433.6992576 +2315 2183 -59807200.44138 +2316 2183 -11899768.97017 +2317 2183 9357633.519253 +2318 2183 -21458826.37861 +2184 2184 626081101.6128 +2185 2184 7.033348083496e-06 +2186 2184 925940.2533548 +2187 2184 85765730.61463 +2188 2184 -3.814697265625e-06 +2189 2184 231485.0634534 +2202 2184 -51881527.1465 +2203 2184 -36666666.66065 +2204 2184 2505785.245605 +2205 2184 -136819701.2443 +2206 2184 9.089708328247e-07 +2207 2184 -462970.1266867 +2208 2184 -51905201.38891 +2209 2184 36666666.66065 +2210 2184 -2702548.086863 +2274 2184 -18752053.59425 +2275 2184 9166666.66968 +2276 2184 10539814.37052 +2277 2184 -60367636.82651 +2278 2184 1.877546310425e-06 +2279 2184 44780785.23866 +2280 2184 -20276082.95081 +2281 2184 -9166666.66968 +2282 2184 11841897.70428 +2292 2184 -1865379.213624 +2293 2184 8.79168510437e-07 +2294 2184 57871.26589221 +2295 2184 51054233.83102 +2296 2184 1.788139343262e-06 +2297 2184 231485.0634618 +2298 2184 -7985170.87927 +2299 2184 -2.771615982056e-06 +2300 2184 57871.2658952 +2313 2184 -18848133.13973 +2314 2184 -9166666.66968 +2315 2184 -10597685.63642 +2316 2184 -60775629.25067 +2317 2184 -1.214444637299e-06 +2318 2184 -45012270.30212 +2319 2184 -20383999.6175 +2320 2184 9166666.669679 +2321 2184 -11899768.97017 +2185 2185 538074898.3386 +2186 2185 -11110939.17715 +2187 2185 -2.861022949219e-06 +2188 2185 -53567337.94508 +2189 2185 5555469.588581 +2202 2185 -36666666.66065 +2203 2185 -40880751.7318 +2204 2185 1263867.397843 +2205 2185 9.685754776001e-07 +2206 2185 24514918.12315 +2207 2185 -2777734.795656 +2208 2185 36666666.66065 +2209 2185 -40904425.97421 +2210 2185 1513867.397816 +2274 2185 9166666.66968 +2275 2185 -16001859.73922 +2276 2185 -8593755.37553 +2277 2185 1.169741153717e-06 +2278 2185 -20033981.96478 +2279 2185 -694433.6992575 +2280 2185 -9166666.66968 +2281 2185 -17525889.09577 +2282 2185 9288189.074786 +2292 2185 1.229345798492e-06 +2293 2185 -36698646.37071 +2294 2185 -34527799.26293 +2295 2185 1.966953277588e-06 +2296 2185 29052683.00161 +2297 2185 -2777734.795662 +2298 2185 -2.190470695496e-06 +2299 2185 -42818438.03636 +2300 2185 37305534.05859 +2313 2185 -9166666.669679 +2314 2185 -16097939.2847 +2315 2185 -8663199.819997 +2316 2185 -1.445412635803e-06 +2317 2185 -20441974.38895 +2318 2185 -694433.6992576 +2319 2185 9166666.669678 +2320 2185 -17633805.76247 +2321 2185 9357633.519253 +2186 2186 616797415.4266 +2187 2186 231485.0634536 +2188 2186 5555469.588581 +2189 2186 82852085.35441 +2202 2186 2471063.023406 +2203 2186 1236089.620084 +2204 2186 -6756715.38321 +2205 2186 -462970.1266864 +2206 2186 -2777734.795656 +2207 2186 44192040.0554 +2208 2186 -2737270.309063 +2209 2186 1541645.175575 +2210 2186 -6819846.696327 +2274 2186 10539814.37052 +2275 2186 -8593755.37553 +2276 2186 -17106970.31658 +2277 2186 44746063.01646 +2278 2186 -694433.6992574 +2279 2186 -58719220.64359 +2280 2186 11841897.70428 +2281 2186 9288189.074786 +2282 2186 -21171048.60074 +2292 2186 57871.26589252 +2293 2186 -34500021.48517 +2294 2186 -41438476.99211 +2295 2186 231485.0634617 +2296 2186 -2777734.795662 +2297 2186 -127043423.7988 +2298 2186 57871.26589543 +2299 2186 37277756.28083 +2300 2186 -57757921.43384 +2313 2186 -10597685.63642 +2314 2186 -8663199.819997 +2315 2186 -17363182.43788 +2316 2186 -44977548.07992 +2317 2186 -694433.6992576 +2318 2186 -59807200.44138 +2319 2186 -11899768.97017 +2320 2186 9357633.519253 +2321 2186 -21458826.37861 +2187 2187 529269027.9738 +2188 2187 15976779.95389 +2189 2187 309229.3959292 +2190 2187 -95009984.98826 +2191 2187 -75445884.18699 +2192 2187 604974.9505656 +2205 2187 -51881527.1465 +2206 2187 -36666666.66065 +2207 2187 2505785.245605 +2208 2187 -86033365.36057 +2209 2187 24063656.22554 +2210 2187 -110868.0321211 +2211 2187 -45738405.09723 +2212 2187 10794709.95026 +2213 2187 -181650.9566633 +2277 2187 -18752053.59425 +2278 2187 9166666.66968 +2279 2187 10539814.37052 +2280 2187 -30197821.22333 +2281 2187 6024445.330198 +2282 2187 26095078.18734 +2295 2187 -1865379.213624 +2296 2187 8.79168510437e-07 +2297 2187 57871.26589221 +2298 2187 61387852.24502 +2299 2187 4122392.261682 +2300 2187 24731.18804856 +2301 2187 -36271111.37421 +2302 2187 -18861429.14012 +2303 2187 11687357.04074 +2316 2187 -18848133.13973 +2317 2187 -9166666.66968 +2318 2187 -10597685.63642 +2319 2187 -45324581.42976 +2320 2187 6015914.059347 +2321 2187 -35313654.50317 +2322 2187 -18251664.62718 +2323 2187 2698677.488894 +2324 2187 -1659648.850827 +2188 2188 646827584.356 +2189 2188 -8175535.550103 +2190 2188 -75447624.85616 +2191 2188 -250684995.8489 +2192 2188 1581995.23501 +2205 2188 -36666666.66065 +2206 2188 -40880751.7318 +2207 2188 1263867.397843 +2208 2188 24063656.22554 +2209 2188 19704498.54099 +2210 2188 -1263948.6007 +2211 2188 10794709.95026 +2212 2188 -140802296.2262 +2213 2188 1044821.700929 +2277 2188 9166666.66968 +2278 2188 -16001859.73922 +2279 2188 -8593755.37553 +2280 2188 6024859.539531 +2281 2188 6053166.381108 +2282 2188 -6470970.256034 +2295 2188 1.229345798492e-06 +2296 2188 -36698646.37071 +2297 2188 -34527799.26293 +2298 2188 4122392.261681 +2299 2188 90719798.19174 +2300 2188 -2085944.824517 +2301 2188 -18861843.34945 +2302 2188 -75189658.67279 +2303 2188 36709375.12006 +2316 2188 -9166666.669679 +2317 2188 -16097939.2847 +2318 2188 -8663199.819997 +2319 2188 6015914.059347 +2320 2188 -18890115.44135 +2321 2188 7371512.847656 +2322 2188 2698677.488894 +2323 2188 -42017637.42113 +2324 2188 16927872.0975 +2189 2189 522481518.7437 +2190 2189 570275.1598561 +2191 2189 1609813.358331 +2192 2189 -60302093.42892 +2205 2189 2471063.023406 +2206 2189 1236089.620084 +2207 2189 -6756715.38321 +2208 2189 -978923.5875342 +2209 2189 -1291726.378473 +2210 2189 48623486.51979 +2211 2189 -251095.4010623 +2212 2189 1044821.700929 +2213 2189 -32250770.90951 +2277 2189 10539814.37052 +2278 2189 -8593755.37553 +2279 2189 -17106970.31658 +2280 2189 26268684.29243 +2281 2189 -6442789.689586 +2282 2189 -27149914.04291 +2295 2189 57871.26589252 +2296 2189 -34500021.48517 +2297 2189 -41438476.99211 +2298 2189 302685.3268968 +2299 2189 -1863581.488333 +2300 2189 -59214836.48893 +2301 2189 11826339.43718 +2302 2189 36764598.70127 +2303 2189 -48458702.44161 +2316 2189 -10597685.63642 +2317 2189 -8663199.819997 +2318 2189 -17363182.43788 +2319 2189 -35487265.61249 +2320 2189 7371512.849165 +2321 2189 -51354101.90813 +2322 2189 -1659648.850827 +2323 2189 16927872.0975 +2324 2189 -26241528.32399 +2190 2190 542046808.038 +2191 2190 16985417.11376 +2192 2190 -203184.6143076 +2208 2190 -53262133.98087 +2209 2190 -32705759.54262 +2210 2190 337518.2011556 +2211 2190 32482202.95367 +2212 2190 38534285.18882 +2213 2190 -151182.9762473 +2214 2190 64489952.93444 +2215 2190 -20356855.82223 +2216 2190 2495.307171345 +2217 2190 -1371677.705903 +2218 2190 28985315.91813 +2219 2190 -69742.67196767 +2280 2190 -43496281.76604 +2281 2190 11001242.63162 +2282 2190 2239415.141139 +2298 2190 -35390519.45059 +2299 2190 -18861843.34945 +2300 2190 -11445717.33882 +2301 2190 25247473.61597 +2302 2190 4229179.830355 +2303 2190 8829304.168334 +2319 2190 -19804774.09007 +2320 2190 -8176439.889684 +2321 2190 -11139057.95335 +2322 2190 -42011868.47821 +2323 2190 9621398.332572 +2324 2190 -44047471.98855 +2325 2190 -23061861.42779 +2326 2190 -5072039.507889 +2327 2190 13503023.50219 +2328 2190 -17423481.8086 +2329 2190 7258501.952479 +2330 2190 -10890051.08655 +2191 2191 925016566.7777 +2192 2191 -5117964.511316 +2208 2191 -32705759.54262 +2209 2191 -17400227.63301 +2210 2191 -74400.58715915 +2211 2191 38534285.18882 +2212 2191 160501823.252 +2213 2191 -572894.5814486 +2214 2191 -5690189.15797 +2215 2191 -6138249.160739 +2216 2191 57430.73998052 +2217 2191 28985315.91813 +2218 2191 -23483370.46853 +2219 2191 70407.33895533 +2280 2191 7334161.754413 +2281 2191 -114457361.9368 +2282 2191 -15381325.04617 +2298 2191 -18861429.14012 +2299 2191 -74309066.74917 +2300 2191 -35931916.41689 +2301 2191 4229179.830354 +2302 2191 117298061.0399 +2303 2191 -628830.5409434 +2319 2191 -8176439.889684 +2320 2191 -10839297.49869 +2321 2191 -8997766.816414 +2322 2191 9621398.332572 +2323 2191 -9995068.119689 +2324 2191 7544317.16766 +2325 2191 -1405372.840019 +2326 2191 -40723022.92627 +2327 2191 33347675.24885 +2328 2191 7258501.952479 +2329 2191 -22915557.21458 +2330 2191 16684227.69178 +2192 2192 705606013.3235 +2208 2192 302795.9789559 +2209 2192 -102178.3649187 +2210 2192 -626812.8042064 +2211 2192 -255349.6428957 +2212 2192 -600672.359222 +2213 2192 193995415.907 +2214 2192 2495.307174325 +2215 2192 57430.73998049 +2216 2192 126628346.7421 +2217 2192 -69742.6719339 +2218 2192 70407.33895537 +2219 2192 41263196.59584 +2280 2192 1492943.427426 +2281 2192 -15978626.85393 +2282 2192 -45029004.53869 +2298 2192 -11306745.62719 +2299 2192 -35876711.49758 +2300 2192 -46110457.31193 +2301 2192 -8844029.162097 +2302 2192 -1768543.01006 +2303 2192 -114110745.5777 +2319 2192 -11139057.95335 +2320 2192 -8997766.816414 +2321 2192 -17461344.76991 +2322 2192 -44116916.43301 +2323 2192 7544317.169169 +2324 2192 -85088216.89009 +2325 2192 5378023.50137 +2326 2192 33347675.24885 +2327 2192 -72887043.63418 +2328 2192 -10890051.08655 +2329 2192 16684227.69178 +2330 2192 -35156689.69169 +2193 2193 313040550.8064 +2194 2193 3.218650817871e-06 +2195 2193 462970.1266764 +2196 2193 42883259.87802 +2197 2193 7333333.332129 +2198 2193 -318285.2460207 +2283 2193 -60367636.82651 +2284 2193 1.877546310425e-06 +2285 2193 44780785.23866 +2286 2193 -20276082.95081 +2287 2193 -9166666.66968 +2288 2193 11841897.70428 +2304 2193 25526722.3448 +2305 2193 -5.960464477539e-08 +2306 2193 -8946896.355626 +2307 2193 -3992585.439634 +2308 2193 1833333.333934 +2309 2193 -2345231.034498 +2194 2194 269037449.1693 +2195 2194 -5555469.588573 +2196 2194 -7333333.332131 +2197 2194 -26783274.40183 +2198 2194 2749957.016519 +2283 2194 1.169741153717e-06 +2284 2194 -20033981.96478 +2285 2194 -694433.6992575 +2286 2194 -9166666.66968 +2287 2194 -17525889.09577 +2288 2194 9288189.074786 +2304 2194 6.556510925293e-07 +2305 2194 14525946.9301 +2306 2194 -1388867.397833 +2307 2194 -1833333.333937 +2308 2194 -21409219.01818 +2309 2194 18645822.58485 +2195 2195 308398707.7133 +2196 2195 723381.420473 +2197 2195 2805512.572065 +2198 2195 41427094.86576 +2283 2195 44746063.01646 +2284 2195 -694433.6992574 +2285 2195 -58719220.64359 +2286 2195 11841897.70428 +2287 2195 9288189.074786 +2288 2195 -21171048.60074 +2304 2195 9004770.308089 +2305 2195 -1388867.397833 +2306 2195 -63522764.08798 +2307 2195 2403102.300394 +2308 2195 18645822.58486 +2309 2195 -28878960.71692 +2196 2196 313040550.8064 +2197 2196 3.218650817871e-06 +2198 2196 462970.1266764 +2199 2196 42883259.87802 +2200 2196 7333333.332129 +2201 2196 -318285.2460207 +2283 2196 -18752053.59425 +2284 2196 9166666.66968 +2285 2196 10539814.37052 +2286 2196 -60367636.82651 +2287 2196 1.877546310425e-06 +2288 2196 44780785.23866 +2289 2196 -20276082.95081 +2290 2196 -9166666.66968 +2291 2196 11841897.70428 +2304 2196 -932689.6068121 +2305 2196 -1833333.333935 +2306 2196 -2084814.367748 +2307 2196 25526722.3448 +2308 2196 -5.960464477539e-08 +2309 2196 -8946896.355626 +2310 2196 -3992585.439634 +2311 2196 1833333.333934 +2312 2196 -2345231.034498 +2197 2197 269037449.1693 +2198 2197 -5555469.588573 +2199 2197 -7333333.332131 +2200 2197 -26783274.40183 +2201 2197 2749957.016519 +2283 2197 9166666.66968 +2284 2197 -16001859.73922 +2285 2197 -8593755.37553 +2286 2197 1.169741153717e-06 +2287 2197 -20033981.96478 +2288 2197 -694433.6992575 +2289 2197 -9166666.66968 +2290 2197 -17525889.09577 +2291 2197 9288189.074786 +2304 2197 1833333.333937 +2305 2197 -18349323.18536 +2306 2197 -17256955.18702 +2307 2197 6.556510925293e-07 +2308 2197 14525946.9301 +2309 2197 -1388867.397833 +2310 2197 -1833333.333937 +2311 2197 -21409219.01818 +2312 2197 18645822.58485 +2198 2198 308398707.7133 +2199 2198 723381.420473 +2200 2198 2805512.572065 +2201 2198 41427094.86576 +2283 2198 10539814.37052 +2284 2198 -8593755.37553 +2285 2198 -17106970.31658 +2286 2198 44746063.01646 +2287 2198 -694433.6992574 +2288 2198 -58719220.64359 +2289 2198 11841897.70428 +2290 2198 9288189.074786 +2291 2198 -21171048.60074 +2304 2198 2142685.63364 +2305 2198 -17256955.18703 +2306 2198 -20719238.49606 +2307 2198 9004770.308089 +2308 2198 -1388867.397833 +2309 2198 -63522764.08798 +2310 2198 2403102.300394 +2311 2198 18645822.58486 +2312 2198 -28878960.71692 +2199 2199 313040550.8064 +2200 2199 3.218650817871e-06 +2201 2199 462970.1266764 +2202 2199 42883259.87802 +2203 2199 7333333.332129 +2204 2199 -318285.2460207 +2286 2199 -18752053.59425 +2287 2199 9166666.66968 +2288 2199 10539814.37052 +2289 2199 -60367636.82651 +2290 2199 1.877546310425e-06 +2291 2199 44780785.23866 +2292 2199 -20276082.95081 +2293 2199 -9166666.66968 +2294 2199 11841897.70428 +2307 2199 -932689.6068121 +2308 2199 -1833333.333935 +2309 2199 -2084814.367748 +2310 2199 25526722.3448 +2311 2199 -5.960464477539e-08 +2312 2199 -8946896.355626 +2313 2199 -3992585.439634 +2314 2199 1833333.333934 +2315 2199 -2345231.034498 +2200 2200 269037449.1693 +2201 2200 -5555469.588573 +2202 2200 -7333333.332131 +2203 2200 -26783274.40183 +2204 2200 2749957.016519 +2286 2200 9166666.66968 +2287 2200 -16001859.73922 +2288 2200 -8593755.37553 +2289 2200 1.169741153717e-06 +2290 2200 -20033981.96478 +2291 2200 -694433.6992575 +2292 2200 -9166666.66968 +2293 2200 -17525889.09577 +2294 2200 9288189.074786 +2307 2200 1833333.333937 +2308 2200 -18349323.18536 +2309 2200 -17256955.18702 +2310 2200 6.556510925293e-07 +2311 2200 14525946.9301 +2312 2200 -1388867.397833 +2313 2200 -1833333.333937 +2314 2200 -21409219.01818 +2315 2200 18645822.58485 +2201 2201 308398707.7133 +2202 2201 723381.420473 +2203 2201 2805512.572065 +2204 2201 41427094.86576 +2286 2201 10539814.37052 +2287 2201 -8593755.37553 +2288 2201 -17106970.31658 +2289 2201 44746063.01646 +2290 2201 -694433.6992574 +2291 2201 -58719220.64359 +2292 2201 11841897.70428 +2293 2201 9288189.074786 +2294 2201 -21171048.60074 +2307 2201 2142685.63364 +2308 2201 -17256955.18703 +2309 2201 -20719238.49606 +2310 2201 9004770.308089 +2311 2201 -1388867.397833 +2312 2201 -63522764.08798 +2313 2201 2403102.300394 +2314 2201 18645822.58486 +2315 2201 -28878960.71692 +2202 2202 313040550.8064 +2203 2202 3.218650817871e-06 +2204 2202 462970.1266764 +2205 2202 42883259.87802 +2206 2202 7333333.332129 +2207 2202 -318285.2460207 +2289 2202 -18752053.59425 +2290 2202 9166666.66968 +2291 2202 10539814.37052 +2292 2202 -60367636.82651 +2293 2202 1.877546310425e-06 +2294 2202 44780785.23866 +2295 2202 -20276082.95081 +2296 2202 -9166666.66968 +2297 2202 11841897.70428 +2310 2202 -932689.6068121 +2311 2202 -1833333.333935 +2312 2202 -2084814.367748 +2313 2202 25526722.3448 +2314 2202 -5.960464477539e-08 +2315 2202 -8946896.355626 +2316 2202 -3992585.439634 +2317 2202 1833333.333934 +2318 2202 -2345231.034498 +2203 2203 269037449.1693 +2204 2203 -5555469.588573 +2205 2203 -7333333.332131 +2206 2203 -26783274.40183 +2207 2203 2749957.016519 +2289 2203 9166666.66968 +2290 2203 -16001859.73922 +2291 2203 -8593755.37553 +2292 2203 1.169741153717e-06 +2293 2203 -20033981.96478 +2294 2203 -694433.6992575 +2295 2203 -9166666.66968 +2296 2203 -17525889.09577 +2297 2203 9288189.074786 +2310 2203 1833333.333937 +2311 2203 -18349323.18536 +2312 2203 -17256955.18702 +2313 2203 6.556510925293e-07 +2314 2203 14525946.9301 +2315 2203 -1388867.397833 +2316 2203 -1833333.333937 +2317 2203 -21409219.01818 +2318 2203 18645822.58485 +2204 2204 308398707.7133 +2205 2204 723381.420473 +2206 2204 2805512.572065 +2207 2204 41427094.86576 +2289 2204 10539814.37052 +2290 2204 -8593755.37553 +2291 2204 -17106970.31658 +2292 2204 44746063.01646 +2293 2204 -694433.6992574 +2294 2204 -58719220.64359 +2295 2204 11841897.70428 +2296 2204 9288189.074786 +2297 2204 -21171048.60074 +2310 2204 2142685.63364 +2311 2204 -17256955.18703 +2312 2204 -20719238.49606 +2313 2204 9004770.308089 +2314 2204 -1388867.397833 +2315 2204 -63522764.08798 +2316 2204 2403102.300394 +2317 2204 18645822.58486 +2318 2204 -28878960.71692 +2205 2205 313040550.8064 +2206 2205 3.218650817871e-06 +2207 2205 462970.1266764 +2208 2205 42883259.87802 +2209 2205 7333333.332129 +2210 2205 -318285.2460207 +2292 2205 -18752053.59425 +2293 2205 9166666.66968 +2294 2205 10539814.37052 +2295 2205 -60367636.82651 +2296 2205 1.877546310425e-06 +2297 2205 44780785.23866 +2298 2205 -20276082.95081 +2299 2205 -9166666.66968 +2300 2205 11841897.70428 +2313 2205 -932689.6068121 +2314 2205 -1833333.333935 +2315 2205 -2084814.367748 +2316 2205 25526722.3448 +2317 2205 -5.960464477539e-08 +2318 2205 -8946896.355626 +2319 2205 -3992585.439634 +2320 2205 1833333.333934 +2321 2205 -2345231.034498 +2206 2206 269037449.1693 +2207 2206 -5555469.588573 +2208 2206 -7333333.332131 +2209 2206 -26783274.40183 +2210 2206 2749957.016519 +2292 2206 9166666.66968 +2293 2206 -16001859.73922 +2294 2206 -8593755.37553 +2295 2206 1.169741153717e-06 +2296 2206 -20033981.96478 +2297 2206 -694433.6992575 +2298 2206 -9166666.66968 +2299 2206 -17525889.09577 +2300 2206 9288189.074786 +2313 2206 1833333.333937 +2314 2206 -18349323.18536 +2315 2206 -17256955.18702 +2316 2206 6.556510925293e-07 +2317 2206 14525946.9301 +2318 2206 -1388867.397833 +2319 2206 -1833333.333937 +2320 2206 -21409219.01818 +2321 2206 18645822.58485 +2207 2207 308398707.7133 +2208 2207 723381.420473 +2209 2207 2805512.572065 +2210 2207 41427094.86576 +2292 2207 10539814.37052 +2293 2207 -8593755.37553 +2294 2207 -17106970.31658 +2295 2207 44746063.01646 +2296 2207 -694433.6992574 +2297 2207 -58719220.64359 +2298 2207 11841897.70428 +2299 2207 9288189.074786 +2300 2207 -21171048.60074 +2313 2207 2142685.63364 +2314 2207 -17256955.18703 +2315 2207 -20719238.49606 +2316 2207 9004770.308089 +2317 2207 -1388867.397833 +2318 2207 -63522764.08798 +2319 2207 2403102.300394 +2320 2207 18645822.58486 +2321 2207 -28878960.71692 +2208 2208 311501301.9278 +2209 2208 3961702.031803 +2210 2208 2461349.04567 +2211 2208 -4984022.060376 +2212 2208 -24652932.04324 +2213 2208 367556.3402904 +2295 2208 -18752053.59425 +2296 2208 9166666.66968 +2297 2208 10539814.37052 +2298 2208 -44778234.89159 +2299 2208 6015914.059352 +2300 2208 35041206.59625 +2301 2208 -20008769.25006 +2302 2208 -8176439.889681 +2303 2208 11299136.49846 +2316 2208 -932689.6068121 +2317 2208 -1833333.333935 +2318 2208 -2084814.367748 +2319 2208 25141334.84086 +2320 2208 990425.5084367 +2321 2208 -8447023.847856 +2322 2208 -17627581.50065 +2323 2208 -6163233.013846 +2324 2208 7435569.639298 +2209 2209 292367764.6648 +2210 2209 -3560498.398243 +2211 2209 -39319598.70751 +2212 2209 -68784496.1816 +2213 2209 607245.3940165 +2295 2209 9166666.66968 +2296 2209 -16001859.73922 +2297 2209 -8593755.37553 +2298 2209 6015914.059351 +2299 2209 -18343768.90317 +2300 2209 -8010431.594268 +2301 2209 -8176439.889681 +2302 2209 -11043292.65868 +2303 2209 8953622.07837 +2316 2209 1833333.333937 +2317 2209 -18349323.18536 +2318 2209 -17256955.18702 +2319 2209 990425.5084375 +2320 2209 20357950.52274 +2321 2209 -890124.6000073 +2322 2209 -9829899.681717 +2323 2209 -33577700.03881 +2324 2209 25797644.67844 +2210 2210 314119300.5055 +2211 2210 541167.4513703 +2212 2210 635023.1717897 +2213 2210 25143014.98303 +2295 2210 10539814.37052 +2296 2210 -8593755.37553 +2297 2210 -17106970.31658 +2298 2210 35214817.70936 +2299 2210 -8010431.592745 +2300 2210 -49897177.80632 +2301 2210 11299136.49846 +2302 2210 8953622.07837 +2303 2210 -18005331.86323 +2316 2210 2142685.63364 +2317 2210 -17256955.18703 +2318 2210 -20719238.49606 +2319 2210 9504087.260305 +2320 2210 -890124.6000072 +2321 2210 -62094149.98014 +2322 2210 11975291.86111 +2323 2210 25797644.67693 +2324 2210 -37398448.87766 +2211 2211 355470652.7224 +2212 2211 44707168.10431 +2213 2211 -30735.96254444 +2214 2211 -68134344.3616 +2215 2211 -44348017.40317 +2216 2211 103868.4391181 +2217 2211 15735336.29641 +2218 2211 -10368547.13271 +2219 2211 31034.00482726 +2298 2211 -17800014.26928 +2299 2211 2698677.488893 +2300 2211 1551462.261342 +2301 2211 -41858908.40872 +2302 2211 9621398.332578 +2303 2211 43971972.44142 +2319 2211 -16877239.2765 +2320 2211 -9829899.681722 +2321 2211 -11739430.35753 +2322 2211 -6568201.151123 +2323 2211 11145274.60427 +2324 2211 -8861558.763805 +2325 2211 -34037759.59183 +2326 2211 -11074831.38688 +2327 2211 20338421.14593 +2328 2211 -24974899.08211 +2329 2211 -2560619.357143 +2330 2211 7273022.161583 +2212 2212 438088992.7212 +2213 2212 -1373778.468112 +2214 2212 -44348017.40317 +2215 2212 -48519370.46442 +2216 2212 70407.33895519 +2217 2212 -25035213.79697 +2218 2212 -55653232.64768 +2219 2212 224198.6157019 +2298 2212 2698677.488893 +2299 2212 -41565987.06324 +2300 2212 -16405461.24678 +2301 2212 9621398.332577 +2302 2212 -9842108.050208 +2303 2212 -7837627.274264 +2319 2212 -6163233.01385 +2320 2212 -32827357.81467 +2321 2212 -25487077.53535 +2322 2212 11145274.60427 +2323 2212 14082110.90991 +2324 2212 -343297.1207862 +2325 2212 -11074831.38688 +2326 2212 -29145911.38329 +2327 2212 16684227.69178 +2328 2212 -6227286.025014 +2329 2212 -42817768.37808 +2330 2212 33389235.48538 +2213 2213 485869158.3822 +2214 2213 103868.4391181 +2215 2213 70407.33895515 +2216 2213 16227196.59995 +2217 2213 100478.4492579 +2218 2213 224198.6157018 +2219 2213 70566439.57932 +2298 2213 1551462.261342 +2299 2213 -16405461.24678 +2300 2213 -25037127.36958 +2301 2213 43902527.99702 +2302 2213 -7837627.272742 +2303 2213 -84680323.37147 +2319 2213 -7303874.802406 +2320 2213 -25487077.53687 +2321 2213 -35397536.2799 +2322 2213 8672885.677761 +2323 2213 -343297.120786 +2324 2213 -132858416.3097 +2325 2213 20338421.14593 +2326 2213 16684227.69178 +2327 2213 -41387043.8604 +2328 2213 11639411.05376 +2329 2213 33389235.48538 +2330 2213 -59618277.55449 +2214 2214 235091865.188 +2215 2214 49690189.15075 +2216 2214 -60365.67751312 +2217 2214 -6920201.047179 +2218 2214 348017.4103893 +2219 2214 -45998.06877485 +2301 2214 -22967164.45808 +2302 2214 -1405372.84002 +2303 2214 -5376837.60583 +2322 2214 -33943062.62212 +2323 2214 -11074831.38688 +2324 2214 -20286578.86741 +2325 2214 -19573744.60313 +2326 2214 12405372.84363 +2327 2214 8109939.458298 +2328 2214 -35779664.67352 +2329 2214 74831.38326172 +2330 2214 -31196522.98505 +2215 2215 216345067.2978 +2216 2215 -57430.73996973 +2217 2215 15014684.07465 +2218 2215 62839825.04097 +2219 2215 -70407.33894855 +2301 2215 -5072039.507891 +2302 2215 -40628325.95656 +2303 2215 -33318991.40687 +2322 2215 -11074831.38688 +2323 2215 -29051214.41358 +2324 2215 -16649105.6525 +2325 2215 12405372.84363 +2326 2215 -24256333.11199 +2327 2215 6652324.744578 +2328 2215 3741498.051133 +2329 2215 -18327762.87472 +2330 2215 3315772.314788 +2216 2216 344548168.3047 +2217 2216 -45998.06877142 +2218 2216 -70407.33894849 +2219 2216 111335682.2562 +2301 2216 -13501837.60663 +2302 2216 -33318991.40687 +2303 2216 -72634518.38162 +2322 2216 -20286578.86741 +2323 2216 -16649105.6525 +2324 2216 -41134518.60782 +2325 2216 -8140060.539033 +2326 2216 -6681008.586565 +2327 2216 -122734989.1419 +2328 2216 -31196522.98692 +2329 2216 -3350894.354068 +2330 2216 -62865670.82029 +2217 2217 175701997.0157 +2218 2217 -18964786.19581 +2219 2217 -123626.5974838 +2301 2217 -17328784.83888 +2302 2217 7258501.95248 +2303 2217 10855087.80949 +2322 2217 -24690808.17314 +2323 2217 -6227286.025018 +2324 2217 -11589477.83532 +2325 2217 -35779664.67352 +2326 2217 3741498.051137 +2327 2217 31173615.89359 +2328 2217 -13773469.59399 +2329 2217 -4772713.978599 +2330 2217 -4379781.423286 +2218 2218 199442232.6343 +2219 2218 -224198.6156853 +2301 2218 7258501.95248 +2302 2218 -22820860.24487 +2303 2218 -16649105.6525 +2322 2218 -2560619.357146 +2323 2218 -42533677.46912 +2324 2218 -33277431.17033 +2325 2218 74831.38326509 +2326 2218 -18327762.87471 +2327 2218 3315772.314788 +2328 2218 -4772713.978598 +2329 2218 -7890426.690841 +2330 2218 6610764.50804 +2219 2219 265222560.3927 +2301 2219 10855087.80949 +2302 2219 -16649105.6525 +2303 2219 -34904164.4391 +2322 2219 -7257811.165357 +2323 2219 -33277431.17033 +2324 2219 -58860701.79721 +2325 2219 31173615.89173 +2326 2219 -3350894.354067 +2327 2219 -62865670.82028 +2328 2219 4318274.130842 +2329 2219 -6722568.823102 +2330 2219 -87563402.35548 +2220 2220 391468094.7324 +2221 2220 36666666.66066 +2222 2220 2662170.757228 +2223 2220 -201885224.5025 +2224 2220 -36666959.01753 +2225 2220 -2662149.068675 +2226 2220 13006025.1815 +2227 2220 29333625.68539 +2228 2220 -2152798.772422 +2331 2220 31947394.33292 +2332 2220 9166666.669681 +2333 2220 9728225.899101 +2334 2220 -74358253.63036 +2335 2220 -9166739.758898 +2336 2220 -45562288.72778 +2337 2220 -8166156.136015 +2338 2220 7333406.424962 +2339 2220 -9496761.446847 +2221 2221 336463888.7559 +2222 2221 -6944377.543016 +2223 2221 -36667105.19596 +2224 2221 -29548916.09098 +2225 2221 -3847225.37168 +2226 2221 44000438.52809 +2227 2221 13006025.1815 +2228 2221 2416691.307227 +2331 2221 9166666.66968 +2332 2221 18196342.83202 +2333 2221 5513941.008134 +2334 2221 -9166776.303507 +2335 2221 -31274176.50627 +2336 2221 -9941080.210835 +2337 2221 11000109.63744 +2338 2221 -8166156.136015 +2339 2221 11395946.69513 +2222 2222 385940866.4962 +2223 2222 -2662138.224395 +2224 2222 -3097217.158151 +2225 2222 2281351.682023 +2226 2222 -3229198.158633 +2227 2222 1611127.538151 +2228 2222 34682733.81733 +2331 2222 -8223530.275229 +2332 2222 -8847241.586827 +2333 2222 -79300461.72417 +2334 2222 -45527563.96779 +2335 2222 -9746597.980308 +2336 2222 -63128188.69225 +2337 2222 -14245142.17027 +2338 2222 7597297.796754 +2339 2222 -21776416.36271 +2223 2223 677810035.2011 +2224 2223 36667397.55284 +2225 2223 3125086.662505 +2226 2223 20859938.00677 +2227 2223 -36666959.01753 +2228 2223 2702569.081896 +2229 2223 -136819701.2443 +2230 2223 9.089708328247e-07 +2231 2223 -462970.1266867 +2232 2223 -51905201.38891 +2233 2223 36666666.66065 +2234 2223 -2702548.086863 +2331 2223 -72726245.22972 +2332 2223 -9166776.303506 +2333 2223 44231216.90386 +2334 2223 70575234.21716 +2335 2223 9166849.392726 +2336 2223 781227.3439141 +2337 2223 -20203256.3538 +2338 2223 -9166739.758899 +2339 2223 11899863.74724 +2340 2223 -60775629.25067 +2341 2223 -1.214444637299e-06 +2342 2223 -45012270.30212 +2343 2223 -20383999.6175 +2344 2223 9166666.669679 +2345 2223 -11899768.97017 +2224 2224 578802727.5875 +2225 2224 -8610918.562153 +2226 2224 -36667105.19596 +2227 2224 -107472939.8429 +2228 2224 4611020.401354 +2229 2224 9.685754776001e-07 +2230 2224 24514918.12315 +2231 2224 -2777734.795656 +2232 2224 36666666.66065 +2233 2224 -40904425.97421 +2234 2224 1513867.397816 +2331 2224 -9166739.758897 +2332 2224 -29642168.10562 +2333 2224 8204934.122165 +2334 2224 9166849.392726 +2335 2224 45823407.30156 +2336 2224 -2152765.098743 +2337 2224 -9166776.303508 +2338 2224 -52286475.83204 +2339 2224 37069600.58987 +2340 2224 -1.445412635803e-06 +2341 2224 -20441974.38895 +2342 2224 -694433.6992576 +2343 2224 9166666.669678 +2344 2224 -17633805.76247 +2345 2224 9357633.519253 +2225 2225 623143279.9755 +2226 2225 2737301.801614 +2227 2225 5388806.115241 +2228 2225 41364580.11227 +2229 2225 -462970.1266864 +2230 2225 -2777734.795656 +2231 2225 44192040.0554 +2232 2225 -2737270.309063 +2233 2225 1541645.175575 +2234 2225 -6819846.696327 +2331 2225 44196492.14387 +2332 2225 8010523.495484 +2333 2225 -58776166.2905 +2334 2225 781316.8545274 +2335 2225 -2152693.49136 +2336 2225 -107886912.3736 +2337 2225 11899911.13577 +2338 2225 37236269.31883 +2339 2225 -57440830.58835 +2340 2225 -44977548.07992 +2341 2225 -694433.6992576 +2342 2225 -59807200.44138 +2343 2225 -11899768.97017 +2344 2225 9357633.519253 +2345 2225 -21458826.37861 +2226 2226 391468094.7324 +2227 2226 36666666.66066 +2228 2226 2662170.757228 +2229 2226 -51881527.1465 +2230 2226 -36666666.66065 +2231 2226 2505785.245605 +2232 2226 -201885224.5025 +2233 2226 -36666959.01753 +2234 2226 -2662149.068675 +2235 2226 13006025.1815 +2236 2226 29333625.68539 +2237 2226 -2152798.772422 +2331 2226 -5106206.927443 +2332 2226 11000109.63744 +2333 2226 12682625.90274 +2334 2226 -15511422.68773 +2335 2226 -9166776.303506 +2336 2226 -10539940.2691 +2337 2226 31947394.33292 +2338 2226 9166666.669681 +2339 2226 9728225.899101 +2340 2226 -18848133.13973 +2341 2226 -9166666.66968 +2342 2226 -10597685.63642 +2343 2226 -74358253.63036 +2344 2226 -9166739.758898 +2345 2226 -45562288.72778 +2346 2226 -8166156.136015 +2347 2226 7333406.424962 +2348 2226 -9496761.446847 +2227 2227 336463888.7559 +2228 2227 -6944377.543016 +2229 2227 -36666666.66065 +2230 2227 -40880751.7318 +2231 2227 1263867.397843 +2232 2227 -36667105.19596 +2233 2227 -29548916.09098 +2234 2227 -3847225.37168 +2235 2227 44000438.52809 +2236 2227 13006025.1815 +2237 2227 2416691.307227 +2331 2227 7333406.424962 +2332 2227 -5106206.927443 +2333 2227 -6763956.526763 +2334 2227 -9166739.758897 +2335 2227 -47594642.16596 +2336 2227 -34569643.89832 +2337 2227 9166666.66968 +2338 2227 18196342.83202 +2339 2227 5513941.008134 +2340 2227 -9166666.669679 +2341 2227 -16097939.2847 +2342 2227 -8663199.819997 +2343 2227 -9166776.303507 +2344 2227 -31274176.50627 +2345 2227 -9941080.210835 +2346 2227 11000109.63744 +2347 2227 -8166156.136015 +2348 2227 11395946.69513 +2228 2228 385940866.4962 +2229 2228 2471063.023406 +2230 2228 1236089.620084 +2231 2228 -6756715.38321 +2232 2228 -2662138.224395 +2233 2228 -3097217.158151 +2234 2228 2281351.682023 +2235 2228 -3229198.158633 +2236 2228 1611127.538151 +2237 2228 34682733.81733 +2331 2228 8455083.935158 +2332 2228 -10145934.79014 +2333 2228 -13616551.80652 +2334 2228 -10539898.30291 +2335 2228 -34736312.74845 +2336 2228 -44929274.14549 +2337 2228 -8223530.275229 +2338 2228 -8847241.586827 +2339 2228 -79300461.72417 +2340 2228 -10597685.63642 +2341 2228 -8663199.819997 +2342 2228 -17363182.43788 +2343 2228 -45527563.96779 +2344 2228 -9746597.980308 +2345 2228 -63128188.69225 +2346 2228 -14245142.17027 +2347 2228 7597297.796754 +2348 2228 -21776416.36271 +2229 2229 626081101.6128 +2230 2229 7.033348083496e-06 +2231 2229 925940.2533548 +2232 2229 85765730.61463 +2233 2229 -3.814697265625e-06 +2234 2229 231485.0634534 +2238 2229 -136819701.2443 +2239 2229 9.089708328247e-07 +2240 2229 -462970.1266867 +2241 2229 -51905201.38891 +2242 2229 36666666.66065 +2243 2229 -2702548.086863 +2334 2229 -60367636.82651 +2335 2229 1.877546310425e-06 +2336 2229 44780785.23866 +2337 2229 -20276082.95081 +2338 2229 -9166666.66968 +2339 2229 11841897.70428 +2340 2229 51054233.83102 +2341 2229 1.788139343262e-06 +2342 2229 231485.0634618 +2343 2229 -7985170.87927 +2344 2229 -2.771615982056e-06 +2345 2229 57871.2658952 +2349 2229 -60775629.25067 +2350 2229 -1.214444637299e-06 +2351 2229 -45012270.30212 +2352 2229 -20383999.6175 +2353 2229 9166666.669679 +2354 2229 -11899768.97017 +2230 2230 538074898.3386 +2231 2230 -11110939.17715 +2232 2230 -2.861022949219e-06 +2233 2230 -53567337.94508 +2234 2230 5555469.588581 +2238 2230 9.685754776001e-07 +2239 2230 24514918.12315 +2240 2230 -2777734.795656 +2241 2230 36666666.66065 +2242 2230 -40904425.97421 +2243 2230 1513867.397816 +2334 2230 1.169741153717e-06 +2335 2230 -20033981.96478 +2336 2230 -694433.6992575 +2337 2230 -9166666.66968 +2338 2230 -17525889.09577 +2339 2230 9288189.074786 +2340 2230 1.966953277588e-06 +2341 2230 29052683.00161 +2342 2230 -2777734.795662 +2343 2230 -2.190470695496e-06 +2344 2230 -42818438.03636 +2345 2230 37305534.05859 +2349 2230 -1.445412635803e-06 +2350 2230 -20441974.38895 +2351 2230 -694433.6992576 +2352 2230 9166666.669678 +2353 2230 -17633805.76247 +2354 2230 9357633.519253 +2231 2231 616797415.4266 +2232 2231 231485.0634536 +2233 2231 5555469.588581 +2234 2231 82852085.35441 +2238 2231 -462970.1266864 +2239 2231 -2777734.795656 +2240 2231 44192040.0554 +2241 2231 -2737270.309063 +2242 2231 1541645.175575 +2243 2231 -6819846.696327 +2334 2231 44746063.01646 +2335 2231 -694433.6992574 +2336 2231 -58719220.64359 +2337 2231 11841897.70428 +2338 2231 9288189.074786 +2339 2231 -21171048.60074 +2340 2231 231485.0634617 +2341 2231 -2777734.795662 +2342 2231 -127043423.7988 +2343 2231 57871.26589543 +2344 2231 37277756.28083 +2345 2231 -57757921.43384 +2349 2231 -44977548.07992 +2350 2231 -694433.6992576 +2351 2231 -59807200.44138 +2352 2231 -11899768.97017 +2353 2231 9357633.519253 +2354 2231 -21458826.37861 +2232 2232 677810035.2011 +2233 2232 36667397.55284 +2234 2232 3125086.662505 +2235 2232 20859938.00677 +2236 2232 -36666959.01753 +2237 2232 2702569.081896 +2238 2232 -51881527.1465 +2239 2232 -36666666.66065 +2240 2232 2505785.245605 +2241 2232 -136819701.2443 +2242 2232 9.089708328247e-07 +2243 2232 -462970.1266867 +2244 2232 -51905201.38891 +2245 2232 36666666.66065 +2246 2232 -2702548.086863 +2334 2232 -18752053.59425 +2335 2232 9166666.66968 +2336 2232 10539814.37052 +2337 2232 -72726245.22972 +2338 2232 -9166776.303506 +2339 2232 44231216.90386 +2340 2232 -1865379.213624 +2341 2232 8.79168510437e-07 +2342 2232 57871.26589221 +2343 2232 70575234.21716 +2344 2232 9166849.392726 +2345 2232 781227.3439141 +2346 2232 -20203256.3538 +2347 2232 -9166739.758899 +2348 2232 11899863.74724 +2349 2232 -18848133.13973 +2350 2232 -9166666.66968 +2351 2232 -10597685.63642 +2352 2232 -60775629.25067 +2353 2232 -1.214444637299e-06 +2354 2232 -45012270.30212 +2355 2232 -20383999.6175 +2356 2232 9166666.669679 +2357 2232 -11899768.97017 +2233 2233 578802727.5875 +2234 2233 -8610918.562153 +2235 2233 -36667105.19596 +2236 2233 -107472939.8429 +2237 2233 4611020.401354 +2238 2233 -36666666.66065 +2239 2233 -40880751.7318 +2240 2233 1263867.397843 +2241 2233 9.685754776001e-07 +2242 2233 24514918.12315 +2243 2233 -2777734.795656 +2244 2233 36666666.66065 +2245 2233 -40904425.97421 +2246 2233 1513867.397816 +2334 2233 9166666.66968 +2335 2233 -16001859.73922 +2336 2233 -8593755.37553 +2337 2233 -9166739.758897 +2338 2233 -29642168.10562 +2339 2233 8204934.122165 +2340 2233 1.229345798492e-06 +2341 2233 -36698646.37071 +2342 2233 -34527799.26293 +2343 2233 9166849.392726 +2344 2233 45823407.30156 +2345 2233 -2152765.098743 +2346 2233 -9166776.303508 +2347 2233 -52286475.83204 +2348 2233 37069600.58987 +2349 2233 -9166666.669679 +2350 2233 -16097939.2847 +2351 2233 -8663199.819997 +2352 2233 -1.445412635803e-06 +2353 2233 -20441974.38895 +2354 2233 -694433.6992576 +2355 2233 9166666.669678 +2356 2233 -17633805.76247 +2357 2233 9357633.519253 +2234 2234 623143279.9755 +2235 2234 2737301.801614 +2236 2234 5388806.115241 +2237 2234 41364580.11227 +2238 2234 2471063.023406 +2239 2234 1236089.620084 +2240 2234 -6756715.38321 +2241 2234 -462970.1266864 +2242 2234 -2777734.795656 +2243 2234 44192040.0554 +2244 2234 -2737270.309063 +2245 2234 1541645.175575 +2246 2234 -6819846.696327 +2334 2234 10539814.37052 +2335 2234 -8593755.37553 +2336 2234 -17106970.31658 +2337 2234 44196492.14387 +2338 2234 8010523.495484 +2339 2234 -58776166.2905 +2340 2234 57871.26589252 +2341 2234 -34500021.48517 +2342 2234 -41438476.99211 +2343 2234 781316.8545274 +2344 2234 -2152693.49136 +2345 2234 -107886912.3736 +2346 2234 11899911.13577 +2347 2234 37236269.31883 +2348 2234 -57440830.58835 +2349 2234 -10597685.63642 +2350 2234 -8663199.819997 +2351 2234 -17363182.43788 +2352 2234 -44977548.07992 +2353 2234 -694433.6992576 +2354 2234 -59807200.44138 +2355 2234 -11899768.97017 +2356 2234 9357633.519253 +2357 2234 -21458826.37861 +2235 2235 391468094.7324 +2236 2235 36666666.66066 +2237 2235 2662170.757228 +2241 2235 -51881527.1465 +2242 2235 -36666666.66065 +2243 2235 2505785.245605 +2244 2235 -201885224.5025 +2245 2235 -36666959.01753 +2246 2235 -2662149.068675 +2247 2235 13006025.1815 +2248 2235 29333625.68539 +2249 2235 -2152798.772422 +2337 2235 -5106206.927443 +2338 2235 11000109.63744 +2339 2235 12682625.90274 +2343 2235 -15511422.68773 +2344 2235 -9166776.303506 +2345 2235 -10539940.2691 +2346 2235 31947394.33292 +2347 2235 9166666.669681 +2348 2235 9728225.899101 +2352 2235 -18848133.13973 +2353 2235 -9166666.66968 +2354 2235 -10597685.63642 +2355 2235 -74358253.63036 +2356 2235 -9166739.758898 +2357 2235 -45562288.72778 +2358 2235 -8166156.136015 +2359 2235 7333406.424962 +2360 2235 -9496761.446847 +2236 2236 336463888.7559 +2237 2236 -6944377.543016 +2241 2236 -36666666.66065 +2242 2236 -40880751.7318 +2243 2236 1263867.397843 +2244 2236 -36667105.19596 +2245 2236 -29548916.09098 +2246 2236 -3847225.37168 +2247 2236 44000438.52809 +2248 2236 13006025.1815 +2249 2236 2416691.307227 +2337 2236 7333406.424962 +2338 2236 -5106206.927443 +2339 2236 -6763956.526763 +2343 2236 -9166739.758897 +2344 2236 -47594642.16596 +2345 2236 -34569643.89832 +2346 2236 9166666.66968 +2347 2236 18196342.83202 +2348 2236 5513941.008134 +2352 2236 -9166666.669679 +2353 2236 -16097939.2847 +2354 2236 -8663199.819997 +2355 2236 -9166776.303507 +2356 2236 -31274176.50627 +2357 2236 -9941080.210835 +2358 2236 11000109.63744 +2359 2236 -8166156.136015 +2360 2236 11395946.69513 +2237 2237 385940866.4962 +2241 2237 2471063.023406 +2242 2237 1236089.620084 +2243 2237 -6756715.38321 +2244 2237 -2662138.224395 +2245 2237 -3097217.158151 +2246 2237 2281351.682023 +2247 2237 -3229198.158633 +2248 2237 1611127.538151 +2249 2237 34682733.81733 +2337 2237 8455083.935158 +2338 2237 -10145934.79014 +2339 2237 -13616551.80652 +2343 2237 -10539898.30291 +2344 2237 -34736312.74845 +2345 2237 -44929274.14549 +2346 2237 -8223530.275229 +2347 2237 -8847241.586827 +2348 2237 -79300461.72417 +2352 2237 -10597685.63642 +2353 2237 -8663199.819997 +2354 2237 -17363182.43788 +2355 2237 -45527563.96779 +2356 2237 -9746597.980308 +2357 2237 -63128188.69225 +2358 2237 -14245142.17027 +2359 2237 7597297.796754 +2360 2237 -21776416.36271 +2238 2238 626081101.6128 +2239 2238 7.033348083496e-06 +2240 2238 925940.2533548 +2241 2238 85765730.61463 +2242 2238 -3.814697265625e-06 +2243 2238 231485.0634534 +2250 2238 -136819701.2443 +2251 2238 9.089708328247e-07 +2252 2238 -462970.1266867 +2253 2238 -51905201.38891 +2254 2238 36666666.66065 +2255 2238 -2702548.086863 +2340 2238 -60367636.82651 +2341 2238 1.877546310425e-06 +2342 2238 44780785.23866 +2343 2238 -20276082.95081 +2344 2238 -9166666.66968 +2345 2238 11841897.70428 +2349 2238 51054233.83102 +2350 2238 1.788139343262e-06 +2351 2238 231485.0634618 +2352 2238 -7985170.87927 +2353 2238 -2.771615982056e-06 +2354 2238 57871.2658952 +2361 2238 -60775629.25067 +2362 2238 -1.214444637299e-06 +2363 2238 -45012270.30212 +2364 2238 -20383999.6175 +2365 2238 9166666.669679 +2366 2238 -11899768.97017 +2239 2239 538074898.3386 +2240 2239 -11110939.17715 +2241 2239 -2.861022949219e-06 +2242 2239 -53567337.94508 +2243 2239 5555469.588581 +2250 2239 9.685754776001e-07 +2251 2239 24514918.12315 +2252 2239 -2777734.795656 +2253 2239 36666666.66065 +2254 2239 -40904425.97421 +2255 2239 1513867.397816 +2340 2239 1.169741153717e-06 +2341 2239 -20033981.96478 +2342 2239 -694433.6992575 +2343 2239 -9166666.66968 +2344 2239 -17525889.09577 +2345 2239 9288189.074786 +2349 2239 1.966953277588e-06 +2350 2239 29052683.00161 +2351 2239 -2777734.795662 +2352 2239 -2.190470695496e-06 +2353 2239 -42818438.03636 +2354 2239 37305534.05859 +2361 2239 -1.445412635803e-06 +2362 2239 -20441974.38895 +2363 2239 -694433.6992576 +2364 2239 9166666.669678 +2365 2239 -17633805.76247 +2366 2239 9357633.519253 +2240 2240 616797415.4266 +2241 2240 231485.0634536 +2242 2240 5555469.588581 +2243 2240 82852085.35441 +2250 2240 -462970.1266864 +2251 2240 -2777734.795656 +2252 2240 44192040.0554 +2253 2240 -2737270.309063 +2254 2240 1541645.175575 +2255 2240 -6819846.696327 +2340 2240 44746063.01646 +2341 2240 -694433.6992574 +2342 2240 -58719220.64359 +2343 2240 11841897.70428 +2344 2240 9288189.074786 +2345 2240 -21171048.60074 +2349 2240 231485.0634617 +2350 2240 -2777734.795662 +2351 2240 -127043423.7988 +2352 2240 57871.26589543 +2353 2240 37277756.28083 +2354 2240 -57757921.43384 +2361 2240 -44977548.07992 +2362 2240 -694433.6992576 +2363 2240 -59807200.44138 +2364 2240 -11899768.97017 +2365 2240 9357633.519253 +2366 2240 -21458826.37861 +2241 2241 626081101.6128 +2242 2241 7.033348083496e-06 +2243 2241 925940.2533548 +2244 2241 85765730.61463 +2245 2241 -3.814697265625e-06 +2246 2241 231485.0634534 +2250 2241 -51881527.1465 +2251 2241 -36666666.66065 +2252 2241 2505785.245605 +2253 2241 -136819701.2443 +2254 2241 9.089708328247e-07 +2255 2241 -462970.1266867 +2256 2241 -51905201.38891 +2257 2241 36666666.66065 +2258 2241 -2702548.086863 +2340 2241 -18752053.59425 +2341 2241 9166666.66968 +2342 2241 10539814.37052 +2343 2241 -60367636.82651 +2344 2241 1.877546310425e-06 +2345 2241 44780785.23866 +2346 2241 -20276082.95081 +2347 2241 -9166666.66968 +2348 2241 11841897.70428 +2349 2241 -1865379.213624 +2350 2241 8.79168510437e-07 +2351 2241 57871.26589221 +2352 2241 51054233.83102 +2353 2241 1.788139343262e-06 +2354 2241 231485.0634618 +2355 2241 -7985170.87927 +2356 2241 -2.771615982056e-06 +2357 2241 57871.2658952 +2361 2241 -18848133.13973 +2362 2241 -9166666.66968 +2363 2241 -10597685.63642 +2364 2241 -60775629.25067 +2365 2241 -1.214444637299e-06 +2366 2241 -45012270.30212 +2367 2241 -20383999.6175 +2368 2241 9166666.669679 +2369 2241 -11899768.97017 +2242 2242 538074898.3386 +2243 2242 -11110939.17715 +2244 2242 -2.861022949219e-06 +2245 2242 -53567337.94508 +2246 2242 5555469.588581 +2250 2242 -36666666.66065 +2251 2242 -40880751.7318 +2252 2242 1263867.397843 +2253 2242 9.685754776001e-07 +2254 2242 24514918.12315 +2255 2242 -2777734.795656 +2256 2242 36666666.66065 +2257 2242 -40904425.97421 +2258 2242 1513867.397816 +2340 2242 9166666.66968 +2341 2242 -16001859.73922 +2342 2242 -8593755.37553 +2343 2242 1.169741153717e-06 +2344 2242 -20033981.96478 +2345 2242 -694433.6992575 +2346 2242 -9166666.66968 +2347 2242 -17525889.09577 +2348 2242 9288189.074786 +2349 2242 1.229345798492e-06 +2350 2242 -36698646.37071 +2351 2242 -34527799.26293 +2352 2242 1.966953277588e-06 +2353 2242 29052683.00161 +2354 2242 -2777734.795662 +2355 2242 -2.190470695496e-06 +2356 2242 -42818438.03636 +2357 2242 37305534.05859 +2361 2242 -9166666.669679 +2362 2242 -16097939.2847 +2363 2242 -8663199.819997 +2364 2242 -1.445412635803e-06 +2365 2242 -20441974.38895 +2366 2242 -694433.6992576 +2367 2242 9166666.669678 +2368 2242 -17633805.76247 +2369 2242 9357633.519253 +2243 2243 616797415.4266 +2244 2243 231485.0634536 +2245 2243 5555469.588581 +2246 2243 82852085.35441 +2250 2243 2471063.023406 +2251 2243 1236089.620084 +2252 2243 -6756715.38321 +2253 2243 -462970.1266864 +2254 2243 -2777734.795656 +2255 2243 44192040.0554 +2256 2243 -2737270.309063 +2257 2243 1541645.175575 +2258 2243 -6819846.696327 +2340 2243 10539814.37052 +2341 2243 -8593755.37553 +2342 2243 -17106970.31658 +2343 2243 44746063.01646 +2344 2243 -694433.6992574 +2345 2243 -58719220.64359 +2346 2243 11841897.70428 +2347 2243 9288189.074786 +2348 2243 -21171048.60074 +2349 2243 57871.26589252 +2350 2243 -34500021.48517 +2351 2243 -41438476.99211 +2352 2243 231485.0634617 +2353 2243 -2777734.795662 +2354 2243 -127043423.7988 +2355 2243 57871.26589543 +2356 2243 37277756.28083 +2357 2243 -57757921.43384 +2361 2243 -10597685.63642 +2362 2243 -8663199.819997 +2363 2243 -17363182.43788 +2364 2243 -44977548.07992 +2365 2243 -694433.6992576 +2366 2243 -59807200.44138 +2367 2243 -11899768.97017 +2368 2243 9357633.519253 +2369 2243 -21458826.37861 +2244 2244 677810035.2011 +2245 2244 36667397.55284 +2246 2244 3125086.662505 +2247 2244 20859938.00677 +2248 2244 -36666959.01753 +2249 2244 2702569.081896 +2253 2244 -51881527.1465 +2254 2244 -36666666.66065 +2255 2244 2505785.245605 +2256 2244 -136819701.2443 +2257 2244 9.089708328247e-07 +2258 2244 -462970.1266867 +2259 2244 -51905201.38891 +2260 2244 36666666.66065 +2261 2244 -2702548.086863 +2343 2244 -18752053.59425 +2344 2244 9166666.66968 +2345 2244 10539814.37052 +2346 2244 -72726245.22972 +2347 2244 -9166776.303506 +2348 2244 44231216.90386 +2352 2244 -1865379.213624 +2353 2244 8.79168510437e-07 +2354 2244 57871.26589221 +2355 2244 70575234.21716 +2356 2244 9166849.392726 +2357 2244 781227.3439141 +2358 2244 -20203256.3538 +2359 2244 -9166739.758899 +2360 2244 11899863.74724 +2364 2244 -18848133.13973 +2365 2244 -9166666.66968 +2366 2244 -10597685.63642 +2367 2244 -60775629.25067 +2368 2244 -1.214444637299e-06 +2369 2244 -45012270.30212 +2370 2244 -20383999.6175 +2371 2244 9166666.669679 +2372 2244 -11899768.97017 +2245 2245 578802727.5875 +2246 2245 -8610918.562153 +2247 2245 -36667105.19596 +2248 2245 -107472939.8429 +2249 2245 4611020.401354 +2253 2245 -36666666.66065 +2254 2245 -40880751.7318 +2255 2245 1263867.397843 +2256 2245 9.685754776001e-07 +2257 2245 24514918.12315 +2258 2245 -2777734.795656 +2259 2245 36666666.66065 +2260 2245 -40904425.97421 +2261 2245 1513867.397816 +2343 2245 9166666.66968 +2344 2245 -16001859.73922 +2345 2245 -8593755.37553 +2346 2245 -9166739.758897 +2347 2245 -29642168.10562 +2348 2245 8204934.122165 +2352 2245 1.229345798492e-06 +2353 2245 -36698646.37071 +2354 2245 -34527799.26293 +2355 2245 9166849.392726 +2356 2245 45823407.30156 +2357 2245 -2152765.098743 +2358 2245 -9166776.303508 +2359 2245 -52286475.83204 +2360 2245 37069600.58987 +2364 2245 -9166666.669679 +2365 2245 -16097939.2847 +2366 2245 -8663199.819997 +2367 2245 -1.445412635803e-06 +2368 2245 -20441974.38895 +2369 2245 -694433.6992576 +2370 2245 9166666.669678 +2371 2245 -17633805.76247 +2372 2245 9357633.519253 +2246 2246 623143279.9755 +2247 2246 2737301.801614 +2248 2246 5388806.115241 +2249 2246 41364580.11227 +2253 2246 2471063.023406 +2254 2246 1236089.620084 +2255 2246 -6756715.38321 +2256 2246 -462970.1266864 +2257 2246 -2777734.795656 +2258 2246 44192040.0554 +2259 2246 -2737270.309063 +2260 2246 1541645.175575 +2261 2246 -6819846.696327 +2343 2246 10539814.37052 +2344 2246 -8593755.37553 +2345 2246 -17106970.31658 +2346 2246 44196492.14387 +2347 2246 8010523.495484 +2348 2246 -58776166.2905 +2352 2246 57871.26589252 +2353 2246 -34500021.48517 +2354 2246 -41438476.99211 +2355 2246 781316.8545274 +2356 2246 -2152693.49136 +2357 2246 -107886912.3736 +2358 2246 11899911.13577 +2359 2246 37236269.31883 +2360 2246 -57440830.58835 +2364 2246 -10597685.63642 +2365 2246 -8663199.819997 +2366 2246 -17363182.43788 +2367 2246 -44977548.07992 +2368 2246 -694433.6992576 +2369 2246 -59807200.44138 +2370 2246 -11899768.97017 +2371 2246 9357633.519253 +2372 2246 -21458826.37861 +2247 2247 391468094.7324 +2248 2247 36666666.66066 +2249 2247 2662170.757228 +2256 2247 -51881527.1465 +2257 2247 -36666666.66065 +2258 2247 2505785.245605 +2259 2247 -201885224.5025 +2260 2247 -36666959.01753 +2261 2247 -2662149.068675 +2262 2247 13006025.1815 +2263 2247 29333625.68539 +2264 2247 -2152798.772422 +2346 2247 -5106206.927443 +2347 2247 11000109.63744 +2348 2247 12682625.90274 +2355 2247 -15511422.68773 +2356 2247 -9166776.303506 +2357 2247 -10539940.2691 +2358 2247 31947394.33292 +2359 2247 9166666.669681 +2360 2247 9728225.899101 +2367 2247 -18848133.13973 +2368 2247 -9166666.66968 +2369 2247 -10597685.63642 +2370 2247 -74358253.63036 +2371 2247 -9166739.758898 +2372 2247 -45562288.72778 +2373 2247 -8166156.136015 +2374 2247 7333406.424962 +2375 2247 -9496761.446847 +2248 2248 336463888.7559 +2249 2248 -6944377.543016 +2256 2248 -36666666.66065 +2257 2248 -40880751.7318 +2258 2248 1263867.397843 +2259 2248 -36667105.19596 +2260 2248 -29548916.09098 +2261 2248 -3847225.37168 +2262 2248 44000438.52809 +2263 2248 13006025.1815 +2264 2248 2416691.307227 +2346 2248 7333406.424962 +2347 2248 -5106206.927443 +2348 2248 -6763956.526763 +2355 2248 -9166739.758897 +2356 2248 -47594642.16596 +2357 2248 -34569643.89832 +2358 2248 9166666.66968 +2359 2248 18196342.83202 +2360 2248 5513941.008134 +2367 2248 -9166666.669679 +2368 2248 -16097939.2847 +2369 2248 -8663199.819997 +2370 2248 -9166776.303507 +2371 2248 -31274176.50627 +2372 2248 -9941080.210835 +2373 2248 11000109.63744 +2374 2248 -8166156.136015 +2375 2248 11395946.69513 +2249 2249 385940866.4962 +2256 2249 2471063.023406 +2257 2249 1236089.620084 +2258 2249 -6756715.38321 +2259 2249 -2662138.224395 +2260 2249 -3097217.158151 +2261 2249 2281351.682023 +2262 2249 -3229198.158633 +2263 2249 1611127.538151 +2264 2249 34682733.81733 +2346 2249 8455083.935158 +2347 2249 -10145934.79014 +2348 2249 -13616551.80652 +2355 2249 -10539898.30291 +2356 2249 -34736312.74845 +2357 2249 -44929274.14549 +2358 2249 -8223530.275229 +2359 2249 -8847241.586827 +2360 2249 -79300461.72417 +2367 2249 -10597685.63642 +2368 2249 -8663199.819997 +2369 2249 -17363182.43788 +2370 2249 -45527563.96779 +2371 2249 -9746597.980308 +2372 2249 -63128188.69225 +2373 2249 -14245142.17027 +2374 2249 7597297.796754 +2375 2249 -21776416.36271 +2250 2250 626081101.6128 +2251 2250 7.033348083496e-06 +2252 2250 925940.2533548 +2253 2250 85765730.61463 +2254 2250 -3.814697265625e-06 +2255 2250 231485.0634534 +2265 2250 -136819701.2443 +2266 2250 9.089708328247e-07 +2267 2250 -462970.1266867 +2268 2250 -51905201.38891 +2269 2250 36666666.66065 +2270 2250 -2702548.086863 +2349 2250 -60367636.82651 +2350 2250 1.877546310425e-06 +2351 2250 44780785.23866 +2352 2250 -20276082.95081 +2353 2250 -9166666.66968 +2354 2250 11841897.70428 +2361 2250 51054233.83102 +2362 2250 1.788139343262e-06 +2363 2250 231485.0634618 +2364 2250 -7985170.87927 +2365 2250 -2.771615982056e-06 +2366 2250 57871.2658952 +2376 2250 -60775629.25067 +2377 2250 -1.214444637299e-06 +2378 2250 -45012270.30212 +2379 2250 -20383999.6175 +2380 2250 9166666.669679 +2381 2250 -11899768.97017 +2251 2251 538074898.3386 +2252 2251 -11110939.17715 +2253 2251 -2.861022949219e-06 +2254 2251 -53567337.94508 +2255 2251 5555469.588581 +2265 2251 9.685754776001e-07 +2266 2251 24514918.12315 +2267 2251 -2777734.795656 +2268 2251 36666666.66065 +2269 2251 -40904425.97421 +2270 2251 1513867.397816 +2349 2251 1.169741153717e-06 +2350 2251 -20033981.96478 +2351 2251 -694433.6992575 +2352 2251 -9166666.66968 +2353 2251 -17525889.09577 +2354 2251 9288189.074786 +2361 2251 1.966953277588e-06 +2362 2251 29052683.00161 +2363 2251 -2777734.795662 +2364 2251 -2.190470695496e-06 +2365 2251 -42818438.03636 +2366 2251 37305534.05859 +2376 2251 -1.445412635803e-06 +2377 2251 -20441974.38895 +2378 2251 -694433.6992576 +2379 2251 9166666.669678 +2380 2251 -17633805.76247 +2381 2251 9357633.519253 +2252 2252 616797415.4266 +2253 2252 231485.0634536 +2254 2252 5555469.588581 +2255 2252 82852085.35441 +2265 2252 -462970.1266864 +2266 2252 -2777734.795656 +2267 2252 44192040.0554 +2268 2252 -2737270.309063 +2269 2252 1541645.175575 +2270 2252 -6819846.696327 +2349 2252 44746063.01646 +2350 2252 -694433.6992574 +2351 2252 -58719220.64359 +2352 2252 11841897.70428 +2353 2252 9288189.074786 +2354 2252 -21171048.60074 +2361 2252 231485.0634617 +2362 2252 -2777734.795662 +2363 2252 -127043423.7988 +2364 2252 57871.26589543 +2365 2252 37277756.28083 +2366 2252 -57757921.43384 +2376 2252 -44977548.07992 +2377 2252 -694433.6992576 +2378 2252 -59807200.44138 +2379 2252 -11899768.97017 +2380 2252 9357633.519253 +2381 2252 -21458826.37861 +2253 2253 626081101.6128 +2254 2253 7.033348083496e-06 +2255 2253 925940.2533548 +2256 2253 85765730.61463 +2257 2253 -3.814697265625e-06 +2258 2253 231485.0634534 +2265 2253 -51881527.1465 +2266 2253 -36666666.66065 +2267 2253 2505785.245605 +2268 2253 -136819701.2443 +2269 2253 9.089708328247e-07 +2270 2253 -462970.1266867 +2271 2253 -51905201.38891 +2272 2253 36666666.66065 +2273 2253 -2702548.086863 +2349 2253 -18752053.59425 +2350 2253 9166666.66968 +2351 2253 10539814.37052 +2352 2253 -60367636.82651 +2353 2253 1.877546310425e-06 +2354 2253 44780785.23866 +2355 2253 -20276082.95081 +2356 2253 -9166666.66968 +2357 2253 11841897.70428 +2361 2253 -1865379.213624 +2362 2253 8.79168510437e-07 +2363 2253 57871.26589221 +2364 2253 51054233.83102 +2365 2253 1.788139343262e-06 +2366 2253 231485.0634618 +2367 2253 -7985170.87927 +2368 2253 -2.771615982056e-06 +2369 2253 57871.2658952 +2376 2253 -18848133.13973 +2377 2253 -9166666.66968 +2378 2253 -10597685.63642 +2379 2253 -60775629.25067 +2380 2253 -1.214444637299e-06 +2381 2253 -45012270.30212 +2382 2253 -20383999.6175 +2383 2253 9166666.669679 +2384 2253 -11899768.97017 +2254 2254 538074898.3386 +2255 2254 -11110939.17715 +2256 2254 -2.861022949219e-06 +2257 2254 -53567337.94508 +2258 2254 5555469.588581 +2265 2254 -36666666.66065 +2266 2254 -40880751.7318 +2267 2254 1263867.397843 +2268 2254 9.685754776001e-07 +2269 2254 24514918.12315 +2270 2254 -2777734.795656 +2271 2254 36666666.66065 +2272 2254 -40904425.97421 +2273 2254 1513867.397816 +2349 2254 9166666.66968 +2350 2254 -16001859.73922 +2351 2254 -8593755.37553 +2352 2254 1.169741153717e-06 +2353 2254 -20033981.96478 +2354 2254 -694433.6992575 +2355 2254 -9166666.66968 +2356 2254 -17525889.09577 +2357 2254 9288189.074786 +2361 2254 1.229345798492e-06 +2362 2254 -36698646.37071 +2363 2254 -34527799.26293 +2364 2254 1.966953277588e-06 +2365 2254 29052683.00161 +2366 2254 -2777734.795662 +2367 2254 -2.190470695496e-06 +2368 2254 -42818438.03636 +2369 2254 37305534.05859 +2376 2254 -9166666.669679 +2377 2254 -16097939.2847 +2378 2254 -8663199.819997 +2379 2254 -1.445412635803e-06 +2380 2254 -20441974.38895 +2381 2254 -694433.6992576 +2382 2254 9166666.669678 +2383 2254 -17633805.76247 +2384 2254 9357633.519253 +2255 2255 616797415.4266 +2256 2255 231485.0634536 +2257 2255 5555469.588581 +2258 2255 82852085.35441 +2265 2255 2471063.023406 +2266 2255 1236089.620084 +2267 2255 -6756715.38321 +2268 2255 -462970.1266864 +2269 2255 -2777734.795656 +2270 2255 44192040.0554 +2271 2255 -2737270.309063 +2272 2255 1541645.175575 +2273 2255 -6819846.696327 +2349 2255 10539814.37052 +2350 2255 -8593755.37553 +2351 2255 -17106970.31658 +2352 2255 44746063.01646 +2353 2255 -694433.6992574 +2354 2255 -58719220.64359 +2355 2255 11841897.70428 +2356 2255 9288189.074786 +2357 2255 -21171048.60074 +2361 2255 57871.26589252 +2362 2255 -34500021.48517 +2363 2255 -41438476.99211 +2364 2255 231485.0634617 +2365 2255 -2777734.795662 +2366 2255 -127043423.7988 +2367 2255 57871.26589543 +2368 2255 37277756.28083 +2369 2255 -57757921.43384 +2376 2255 -10597685.63642 +2377 2255 -8663199.819997 +2378 2255 -17363182.43788 +2379 2255 -44977548.07992 +2380 2255 -694433.6992576 +2381 2255 -59807200.44138 +2382 2255 -11899768.97017 +2383 2255 9357633.519253 +2384 2255 -21458826.37861 +2256 2256 626081101.6128 +2257 2256 7.033348083496e-06 +2258 2256 925940.2533548 +2259 2256 85765730.61463 +2260 2256 -3.814697265625e-06 +2261 2256 231485.0634534 +2268 2256 -51881527.1465 +2269 2256 -36666666.66065 +2270 2256 2505785.245605 +2271 2256 -136819701.2443 +2272 2256 9.089708328247e-07 +2273 2256 -462970.1266867 +2274 2256 -51905201.38891 +2275 2256 36666666.66065 +2276 2256 -2702548.086863 +2352 2256 -18752053.59425 +2353 2256 9166666.66968 +2354 2256 10539814.37052 +2355 2256 -60367636.82651 +2356 2256 1.877546310425e-06 +2357 2256 44780785.23866 +2358 2256 -20276082.95081 +2359 2256 -9166666.66968 +2360 2256 11841897.70428 +2364 2256 -1865379.213624 +2365 2256 8.79168510437e-07 +2366 2256 57871.26589221 +2367 2256 51054233.83102 +2368 2256 1.788139343262e-06 +2369 2256 231485.0634618 +2370 2256 -7985170.87927 +2371 2256 -2.771615982056e-06 +2372 2256 57871.2658952 +2379 2256 -18848133.13973 +2380 2256 -9166666.66968 +2381 2256 -10597685.63642 +2382 2256 -60775629.25067 +2383 2256 -1.214444637299e-06 +2384 2256 -45012270.30212 +2385 2256 -20383999.6175 +2386 2256 9166666.669679 +2387 2256 -11899768.97017 +2257 2257 538074898.3386 +2258 2257 -11110939.17715 +2259 2257 -2.861022949219e-06 +2260 2257 -53567337.94508 +2261 2257 5555469.588581 +2268 2257 -36666666.66065 +2269 2257 -40880751.7318 +2270 2257 1263867.397843 +2271 2257 9.685754776001e-07 +2272 2257 24514918.12315 +2273 2257 -2777734.795656 +2274 2257 36666666.66065 +2275 2257 -40904425.97421 +2276 2257 1513867.397816 +2352 2257 9166666.66968 +2353 2257 -16001859.73922 +2354 2257 -8593755.37553 +2355 2257 1.169741153717e-06 +2356 2257 -20033981.96478 +2357 2257 -694433.6992575 +2358 2257 -9166666.66968 +2359 2257 -17525889.09577 +2360 2257 9288189.074786 +2364 2257 1.229345798492e-06 +2365 2257 -36698646.37071 +2366 2257 -34527799.26293 +2367 2257 1.966953277588e-06 +2368 2257 29052683.00161 +2369 2257 -2777734.795662 +2370 2257 -2.190470695496e-06 +2371 2257 -42818438.03636 +2372 2257 37305534.05859 +2379 2257 -9166666.669679 +2380 2257 -16097939.2847 +2381 2257 -8663199.819997 +2382 2257 -1.445412635803e-06 +2383 2257 -20441974.38895 +2384 2257 -694433.6992576 +2385 2257 9166666.669678 +2386 2257 -17633805.76247 +2387 2257 9357633.519253 +2258 2258 616797415.4266 +2259 2258 231485.0634536 +2260 2258 5555469.588581 +2261 2258 82852085.35441 +2268 2258 2471063.023406 +2269 2258 1236089.620084 +2270 2258 -6756715.38321 +2271 2258 -462970.1266864 +2272 2258 -2777734.795656 +2273 2258 44192040.0554 +2274 2258 -2737270.309063 +2275 2258 1541645.175575 +2276 2258 -6819846.696327 +2352 2258 10539814.37052 +2353 2258 -8593755.37553 +2354 2258 -17106970.31658 +2355 2258 44746063.01646 +2356 2258 -694433.6992574 +2357 2258 -58719220.64359 +2358 2258 11841897.70428 +2359 2258 9288189.074786 +2360 2258 -21171048.60074 +2364 2258 57871.26589252 +2365 2258 -34500021.48517 +2366 2258 -41438476.99211 +2367 2258 231485.0634617 +2368 2258 -2777734.795662 +2369 2258 -127043423.7988 +2370 2258 57871.26589543 +2371 2258 37277756.28083 +2372 2258 -57757921.43384 +2379 2258 -10597685.63642 +2380 2258 -8663199.819997 +2381 2258 -17363182.43788 +2382 2258 -44977548.07992 +2383 2258 -694433.6992576 +2384 2258 -59807200.44138 +2385 2258 -11899768.97017 +2386 2258 9357633.519253 +2387 2258 -21458826.37861 +2259 2259 677810035.2011 +2260 2259 36667397.55284 +2261 2259 3125086.662505 +2262 2259 20859938.00677 +2263 2259 -36666959.01753 +2264 2259 2702569.081896 +2271 2259 -51881527.1465 +2272 2259 -36666666.66065 +2273 2259 2505785.245605 +2274 2259 -136819701.2443 +2275 2259 9.089708328247e-07 +2276 2259 -462970.1266867 +2277 2259 -51905201.38891 +2278 2259 36666666.66065 +2279 2259 -2702548.086863 +2355 2259 -18752053.59425 +2356 2259 9166666.66968 +2357 2259 10539814.37052 +2358 2259 -72726245.22972 +2359 2259 -9166776.303506 +2360 2259 44231216.90386 +2367 2259 -1865379.213624 +2368 2259 8.79168510437e-07 +2369 2259 57871.26589221 +2370 2259 70575234.21716 +2371 2259 9166849.392726 +2372 2259 781227.3439141 +2373 2259 -20203256.3538 +2374 2259 -9166739.758899 +2375 2259 11899863.74724 +2382 2259 -18848133.13973 +2383 2259 -9166666.66968 +2384 2259 -10597685.63642 +2385 2259 -60775629.25067 +2386 2259 -1.214444637299e-06 +2387 2259 -45012270.30212 +2388 2259 -20383999.6175 +2389 2259 9166666.669679 +2390 2259 -11899768.97017 +2260 2260 578802727.5875 +2261 2260 -8610918.562153 +2262 2260 -36667105.19596 +2263 2260 -107472939.8429 +2264 2260 4611020.401354 +2271 2260 -36666666.66065 +2272 2260 -40880751.7318 +2273 2260 1263867.397843 +2274 2260 9.685754776001e-07 +2275 2260 24514918.12315 +2276 2260 -2777734.795656 +2277 2260 36666666.66065 +2278 2260 -40904425.97421 +2279 2260 1513867.397816 +2355 2260 9166666.66968 +2356 2260 -16001859.73922 +2357 2260 -8593755.37553 +2358 2260 -9166739.758897 +2359 2260 -29642168.10562 +2360 2260 8204934.122165 +2367 2260 1.229345798492e-06 +2368 2260 -36698646.37071 +2369 2260 -34527799.26293 +2370 2260 9166849.392726 +2371 2260 45823407.30156 +2372 2260 -2152765.098743 +2373 2260 -9166776.303508 +2374 2260 -52286475.83204 +2375 2260 37069600.58987 +2382 2260 -9166666.669679 +2383 2260 -16097939.2847 +2384 2260 -8663199.819997 +2385 2260 -1.445412635803e-06 +2386 2260 -20441974.38895 +2387 2260 -694433.6992576 +2388 2260 9166666.669678 +2389 2260 -17633805.76247 +2390 2260 9357633.519253 +2261 2261 623143279.9755 +2262 2261 2737301.801614 +2263 2261 5388806.115241 +2264 2261 41364580.11227 +2271 2261 2471063.023406 +2272 2261 1236089.620084 +2273 2261 -6756715.38321 +2274 2261 -462970.1266864 +2275 2261 -2777734.795656 +2276 2261 44192040.0554 +2277 2261 -2737270.309063 +2278 2261 1541645.175575 +2279 2261 -6819846.696327 +2355 2261 10539814.37052 +2356 2261 -8593755.37553 +2357 2261 -17106970.31658 +2358 2261 44196492.14387 +2359 2261 8010523.495484 +2360 2261 -58776166.2905 +2367 2261 57871.26589252 +2368 2261 -34500021.48517 +2369 2261 -41438476.99211 +2370 2261 781316.8545274 +2371 2261 -2152693.49136 +2372 2261 -107886912.3736 +2373 2261 11899911.13577 +2374 2261 37236269.31883 +2375 2261 -57440830.58835 +2382 2261 -10597685.63642 +2383 2261 -8663199.819997 +2384 2261 -17363182.43788 +2385 2261 -44977548.07992 +2386 2261 -694433.6992576 +2387 2261 -59807200.44138 +2388 2261 -11899768.97017 +2389 2261 9357633.519253 +2390 2261 -21458826.37861 +2262 2262 391468094.7324 +2263 2262 36666666.66066 +2264 2262 2662170.757228 +2274 2262 -51881527.1465 +2275 2262 -36666666.66065 +2276 2262 2505785.245605 +2277 2262 -201885224.5025 +2278 2262 -36666959.01753 +2279 2262 -2662149.068675 +2280 2262 13006025.1815 +2281 2262 29333625.68539 +2282 2262 -2152798.772422 +2358 2262 -5106206.927443 +2359 2262 11000109.63744 +2360 2262 12682625.90274 +2370 2262 -15511422.68773 +2371 2262 -9166776.303506 +2372 2262 -10539940.2691 +2373 2262 31947394.33292 +2374 2262 9166666.669681 +2375 2262 9728225.899101 +2385 2262 -18848133.13973 +2386 2262 -9166666.66968 +2387 2262 -10597685.63642 +2388 2262 -74358253.63036 +2389 2262 -9166739.758898 +2390 2262 -45562288.72778 +2391 2262 -8166156.136015 +2392 2262 7333406.424962 +2393 2262 -9496761.446847 +2263 2263 336463888.7559 +2264 2263 -6944377.543016 +2274 2263 -36666666.66065 +2275 2263 -40880751.7318 +2276 2263 1263867.397843 +2277 2263 -36667105.19596 +2278 2263 -29548916.09098 +2279 2263 -3847225.37168 +2280 2263 44000438.52809 +2281 2263 13006025.1815 +2282 2263 2416691.307227 +2358 2263 7333406.424962 +2359 2263 -5106206.927443 +2360 2263 -6763956.526763 +2370 2263 -9166739.758897 +2371 2263 -47594642.16596 +2372 2263 -34569643.89832 +2373 2263 9166666.66968 +2374 2263 18196342.83202 +2375 2263 5513941.008134 +2385 2263 -9166666.669679 +2386 2263 -16097939.2847 +2387 2263 -8663199.819997 +2388 2263 -9166776.303507 +2389 2263 -31274176.50627 +2390 2263 -9941080.210835 +2391 2263 11000109.63744 +2392 2263 -8166156.136015 +2393 2263 11395946.69513 +2264 2264 385940866.4962 +2274 2264 2471063.023406 +2275 2264 1236089.620084 +2276 2264 -6756715.38321 +2277 2264 -2662138.224395 +2278 2264 -3097217.158151 +2279 2264 2281351.682023 +2280 2264 -3229198.158633 +2281 2264 1611127.538151 +2282 2264 34682733.81733 +2358 2264 8455083.935158 +2359 2264 -10145934.79014 +2360 2264 -13616551.80652 +2370 2264 -10539898.30291 +2371 2264 -34736312.74845 +2372 2264 -44929274.14549 +2373 2264 -8223530.275229 +2374 2264 -8847241.586827 +2375 2264 -79300461.72417 +2385 2264 -10597685.63642 +2386 2264 -8663199.819997 +2387 2264 -17363182.43788 +2388 2264 -45527563.96779 +2389 2264 -9746597.980308 +2390 2264 -63128188.69225 +2391 2264 -14245142.17027 +2392 2264 7597297.796754 +2393 2264 -21776416.36271 +2265 2265 626081101.6128 +2266 2265 7.033348083496e-06 +2267 2265 925940.2533548 +2268 2265 85765730.61463 +2269 2265 -3.814697265625e-06 +2270 2265 231485.0634534 +2283 2265 -136819701.2443 +2284 2265 9.089708328247e-07 +2285 2265 -462970.1266867 +2286 2265 -51905201.38891 +2287 2265 36666666.66065 +2288 2265 -2702548.086863 +2361 2265 -60367636.82651 +2362 2265 1.877546310425e-06 +2363 2265 44780785.23866 +2364 2265 -20276082.95081 +2365 2265 -9166666.66968 +2366 2265 11841897.70428 +2376 2265 51054233.83102 +2377 2265 1.788139343262e-06 +2378 2265 231485.0634618 +2379 2265 -7985170.87927 +2380 2265 -2.771615982056e-06 +2381 2265 57871.2658952 +2394 2265 -60775629.25067 +2395 2265 -1.214444637299e-06 +2396 2265 -45012270.30212 +2397 2265 -20383999.6175 +2398 2265 9166666.669679 +2399 2265 -11899768.97017 +2266 2266 538074898.3386 +2267 2266 -11110939.17715 +2268 2266 -2.861022949219e-06 +2269 2266 -53567337.94508 +2270 2266 5555469.588581 +2283 2266 9.685754776001e-07 +2284 2266 24514918.12315 +2285 2266 -2777734.795656 +2286 2266 36666666.66065 +2287 2266 -40904425.97421 +2288 2266 1513867.397816 +2361 2266 1.169741153717e-06 +2362 2266 -20033981.96478 +2363 2266 -694433.6992575 +2364 2266 -9166666.66968 +2365 2266 -17525889.09577 +2366 2266 9288189.074786 +2376 2266 1.966953277588e-06 +2377 2266 29052683.00161 +2378 2266 -2777734.795662 +2379 2266 -2.190470695496e-06 +2380 2266 -42818438.03636 +2381 2266 37305534.05859 +2394 2266 -1.445412635803e-06 +2395 2266 -20441974.38895 +2396 2266 -694433.6992576 +2397 2266 9166666.669678 +2398 2266 -17633805.76247 +2399 2266 9357633.519253 +2267 2267 616797415.4266 +2268 2267 231485.0634536 +2269 2267 5555469.588581 +2270 2267 82852085.35441 +2283 2267 -462970.1266864 +2284 2267 -2777734.795656 +2285 2267 44192040.0554 +2286 2267 -2737270.309063 +2287 2267 1541645.175575 +2288 2267 -6819846.696327 +2361 2267 44746063.01646 +2362 2267 -694433.6992574 +2363 2267 -58719220.64359 +2364 2267 11841897.70428 +2365 2267 9288189.074786 +2366 2267 -21171048.60074 +2376 2267 231485.0634617 +2377 2267 -2777734.795662 +2378 2267 -127043423.7988 +2379 2267 57871.26589543 +2380 2267 37277756.28083 +2381 2267 -57757921.43384 +2394 2267 -44977548.07992 +2395 2267 -694433.6992576 +2396 2267 -59807200.44138 +2397 2267 -11899768.97017 +2398 2267 9357633.519253 +2399 2267 -21458826.37861 +2268 2268 626081101.6128 +2269 2268 7.033348083496e-06 +2270 2268 925940.2533548 +2271 2268 85765730.61463 +2272 2268 -3.814697265625e-06 +2273 2268 231485.0634534 +2283 2268 -51881527.1465 +2284 2268 -36666666.66065 +2285 2268 2505785.245605 +2286 2268 -136819701.2443 +2287 2268 9.089708328247e-07 +2288 2268 -462970.1266867 +2289 2268 -51905201.38891 +2290 2268 36666666.66065 +2291 2268 -2702548.086863 +2361 2268 -18752053.59425 +2362 2268 9166666.66968 +2363 2268 10539814.37052 +2364 2268 -60367636.82651 +2365 2268 1.877546310425e-06 +2366 2268 44780785.23866 +2367 2268 -20276082.95081 +2368 2268 -9166666.66968 +2369 2268 11841897.70428 +2376 2268 -1865379.213624 +2377 2268 8.79168510437e-07 +2378 2268 57871.26589221 +2379 2268 51054233.83102 +2380 2268 1.788139343262e-06 +2381 2268 231485.0634618 +2382 2268 -7985170.87927 +2383 2268 -2.771615982056e-06 +2384 2268 57871.2658952 +2394 2268 -18848133.13973 +2395 2268 -9166666.66968 +2396 2268 -10597685.63642 +2397 2268 -60775629.25067 +2398 2268 -1.214444637299e-06 +2399 2268 -45012270.30212 +2400 2268 -20383999.6175 +2401 2268 9166666.669679 +2402 2268 -11899768.97017 +2269 2269 538074898.3386 +2270 2269 -11110939.17715 +2271 2269 -2.861022949219e-06 +2272 2269 -53567337.94508 +2273 2269 5555469.588581 +2283 2269 -36666666.66065 +2284 2269 -40880751.7318 +2285 2269 1263867.397843 +2286 2269 9.685754776001e-07 +2287 2269 24514918.12315 +2288 2269 -2777734.795656 +2289 2269 36666666.66065 +2290 2269 -40904425.97421 +2291 2269 1513867.397816 +2361 2269 9166666.66968 +2362 2269 -16001859.73922 +2363 2269 -8593755.37553 +2364 2269 1.169741153717e-06 +2365 2269 -20033981.96478 +2366 2269 -694433.6992575 +2367 2269 -9166666.66968 +2368 2269 -17525889.09577 +2369 2269 9288189.074786 +2376 2269 1.229345798492e-06 +2377 2269 -36698646.37071 +2378 2269 -34527799.26293 +2379 2269 1.966953277588e-06 +2380 2269 29052683.00161 +2381 2269 -2777734.795662 +2382 2269 -2.190470695496e-06 +2383 2269 -42818438.03636 +2384 2269 37305534.05859 +2394 2269 -9166666.669679 +2395 2269 -16097939.2847 +2396 2269 -8663199.819997 +2397 2269 -1.445412635803e-06 +2398 2269 -20441974.38895 +2399 2269 -694433.6992576 +2400 2269 9166666.669678 +2401 2269 -17633805.76247 +2402 2269 9357633.519253 +2270 2270 616797415.4266 +2271 2270 231485.0634536 +2272 2270 5555469.588581 +2273 2270 82852085.35441 +2283 2270 2471063.023406 +2284 2270 1236089.620084 +2285 2270 -6756715.38321 +2286 2270 -462970.1266864 +2287 2270 -2777734.795656 +2288 2270 44192040.0554 +2289 2270 -2737270.309063 +2290 2270 1541645.175575 +2291 2270 -6819846.696327 +2361 2270 10539814.37052 +2362 2270 -8593755.37553 +2363 2270 -17106970.31658 +2364 2270 44746063.01646 +2365 2270 -694433.6992574 +2366 2270 -58719220.64359 +2367 2270 11841897.70428 +2368 2270 9288189.074786 +2369 2270 -21171048.60074 +2376 2270 57871.26589252 +2377 2270 -34500021.48517 +2378 2270 -41438476.99211 +2379 2270 231485.0634617 +2380 2270 -2777734.795662 +2381 2270 -127043423.7988 +2382 2270 57871.26589543 +2383 2270 37277756.28083 +2384 2270 -57757921.43384 +2394 2270 -10597685.63642 +2395 2270 -8663199.819997 +2396 2270 -17363182.43788 +2397 2270 -44977548.07992 +2398 2270 -694433.6992576 +2399 2270 -59807200.44138 +2400 2270 -11899768.97017 +2401 2270 9357633.519253 +2402 2270 -21458826.37861 +2271 2271 626081101.6128 +2272 2271 7.033348083496e-06 +2273 2271 925940.2533548 +2274 2271 85765730.61463 +2275 2271 -3.814697265625e-06 +2276 2271 231485.0634534 +2286 2271 -51881527.1465 +2287 2271 -36666666.66065 +2288 2271 2505785.245605 +2289 2271 -136819701.2443 +2290 2271 9.089708328247e-07 +2291 2271 -462970.1266867 +2292 2271 -51905201.38891 +2293 2271 36666666.66065 +2294 2271 -2702548.086863 +2364 2271 -18752053.59425 +2365 2271 9166666.66968 +2366 2271 10539814.37052 +2367 2271 -60367636.82651 +2368 2271 1.877546310425e-06 +2369 2271 44780785.23866 +2370 2271 -20276082.95081 +2371 2271 -9166666.66968 +2372 2271 11841897.70428 +2379 2271 -1865379.213624 +2380 2271 8.79168510437e-07 +2381 2271 57871.26589221 +2382 2271 51054233.83102 +2383 2271 1.788139343262e-06 +2384 2271 231485.0634618 +2385 2271 -7985170.87927 +2386 2271 -2.771615982056e-06 +2387 2271 57871.2658952 +2397 2271 -18848133.13973 +2398 2271 -9166666.66968 +2399 2271 -10597685.63642 +2400 2271 -60775629.25067 +2401 2271 -1.214444637299e-06 +2402 2271 -45012270.30212 +2403 2271 -20383999.6175 +2404 2271 9166666.669679 +2405 2271 -11899768.97017 +2272 2272 538074898.3386 +2273 2272 -11110939.17715 +2274 2272 -2.861022949219e-06 +2275 2272 -53567337.94508 +2276 2272 5555469.588581 +2286 2272 -36666666.66065 +2287 2272 -40880751.7318 +2288 2272 1263867.397843 +2289 2272 9.685754776001e-07 +2290 2272 24514918.12315 +2291 2272 -2777734.795656 +2292 2272 36666666.66065 +2293 2272 -40904425.97421 +2294 2272 1513867.397816 +2364 2272 9166666.66968 +2365 2272 -16001859.73922 +2366 2272 -8593755.37553 +2367 2272 1.169741153717e-06 +2368 2272 -20033981.96478 +2369 2272 -694433.6992575 +2370 2272 -9166666.66968 +2371 2272 -17525889.09577 +2372 2272 9288189.074786 +2379 2272 1.229345798492e-06 +2380 2272 -36698646.37071 +2381 2272 -34527799.26293 +2382 2272 1.966953277588e-06 +2383 2272 29052683.00161 +2384 2272 -2777734.795662 +2385 2272 -2.190470695496e-06 +2386 2272 -42818438.03636 +2387 2272 37305534.05859 +2397 2272 -9166666.669679 +2398 2272 -16097939.2847 +2399 2272 -8663199.819997 +2400 2272 -1.445412635803e-06 +2401 2272 -20441974.38895 +2402 2272 -694433.6992576 +2403 2272 9166666.669678 +2404 2272 -17633805.76247 +2405 2272 9357633.519253 +2273 2273 616797415.4266 +2274 2273 231485.0634536 +2275 2273 5555469.588581 +2276 2273 82852085.35441 +2286 2273 2471063.023406 +2287 2273 1236089.620084 +2288 2273 -6756715.38321 +2289 2273 -462970.1266864 +2290 2273 -2777734.795656 +2291 2273 44192040.0554 +2292 2273 -2737270.309063 +2293 2273 1541645.175575 +2294 2273 -6819846.696327 +2364 2273 10539814.37052 +2365 2273 -8593755.37553 +2366 2273 -17106970.31658 +2367 2273 44746063.01646 +2368 2273 -694433.6992574 +2369 2273 -58719220.64359 +2370 2273 11841897.70428 +2371 2273 9288189.074786 +2372 2273 -21171048.60074 +2379 2273 57871.26589252 +2380 2273 -34500021.48517 +2381 2273 -41438476.99211 +2382 2273 231485.0634617 +2383 2273 -2777734.795662 +2384 2273 -127043423.7988 +2385 2273 57871.26589543 +2386 2273 37277756.28083 +2387 2273 -57757921.43384 +2397 2273 -10597685.63642 +2398 2273 -8663199.819997 +2399 2273 -17363182.43788 +2400 2273 -44977548.07992 +2401 2273 -694433.6992576 +2402 2273 -59807200.44138 +2403 2273 -11899768.97017 +2404 2273 9357633.519253 +2405 2273 -21458826.37861 +2274 2274 626081101.6128 +2275 2274 7.033348083496e-06 +2276 2274 925940.2533548 +2277 2274 85765730.61463 +2278 2274 -3.814697265625e-06 +2279 2274 231485.0634534 +2289 2274 -51881527.1465 +2290 2274 -36666666.66065 +2291 2274 2505785.245605 +2292 2274 -136819701.2443 +2293 2274 9.089708328247e-07 +2294 2274 -462970.1266867 +2295 2274 -51905201.38891 +2296 2274 36666666.66065 +2297 2274 -2702548.086863 +2367 2274 -18752053.59425 +2368 2274 9166666.66968 +2369 2274 10539814.37052 +2370 2274 -60367636.82651 +2371 2274 1.877546310425e-06 +2372 2274 44780785.23866 +2373 2274 -20276082.95081 +2374 2274 -9166666.66968 +2375 2274 11841897.70428 +2382 2274 -1865379.213624 +2383 2274 8.79168510437e-07 +2384 2274 57871.26589221 +2385 2274 51054233.83102 +2386 2274 1.788139343262e-06 +2387 2274 231485.0634618 +2388 2274 -7985170.87927 +2389 2274 -2.771615982056e-06 +2390 2274 57871.2658952 +2400 2274 -18848133.13973 +2401 2274 -9166666.66968 +2402 2274 -10597685.63642 +2403 2274 -60775629.25067 +2404 2274 -1.214444637299e-06 +2405 2274 -45012270.30212 +2406 2274 -20383999.6175 +2407 2274 9166666.669679 +2408 2274 -11899768.97017 +2275 2275 538074898.3386 +2276 2275 -11110939.17715 +2277 2275 -2.861022949219e-06 +2278 2275 -53567337.94508 +2279 2275 5555469.588581 +2289 2275 -36666666.66065 +2290 2275 -40880751.7318 +2291 2275 1263867.397843 +2292 2275 9.685754776001e-07 +2293 2275 24514918.12315 +2294 2275 -2777734.795656 +2295 2275 36666666.66065 +2296 2275 -40904425.97421 +2297 2275 1513867.397816 +2367 2275 9166666.66968 +2368 2275 -16001859.73922 +2369 2275 -8593755.37553 +2370 2275 1.169741153717e-06 +2371 2275 -20033981.96478 +2372 2275 -694433.6992575 +2373 2275 -9166666.66968 +2374 2275 -17525889.09577 +2375 2275 9288189.074786 +2382 2275 1.229345798492e-06 +2383 2275 -36698646.37071 +2384 2275 -34527799.26293 +2385 2275 1.966953277588e-06 +2386 2275 29052683.00161 +2387 2275 -2777734.795662 +2388 2275 -2.190470695496e-06 +2389 2275 -42818438.03636 +2390 2275 37305534.05859 +2400 2275 -9166666.669679 +2401 2275 -16097939.2847 +2402 2275 -8663199.819997 +2403 2275 -1.445412635803e-06 +2404 2275 -20441974.38895 +2405 2275 -694433.6992576 +2406 2275 9166666.669678 +2407 2275 -17633805.76247 +2408 2275 9357633.519253 +2276 2276 616797415.4266 +2277 2276 231485.0634536 +2278 2276 5555469.588581 +2279 2276 82852085.35441 +2289 2276 2471063.023406 +2290 2276 1236089.620084 +2291 2276 -6756715.38321 +2292 2276 -462970.1266864 +2293 2276 -2777734.795656 +2294 2276 44192040.0554 +2295 2276 -2737270.309063 +2296 2276 1541645.175575 +2297 2276 -6819846.696327 +2367 2276 10539814.37052 +2368 2276 -8593755.37553 +2369 2276 -17106970.31658 +2370 2276 44746063.01646 +2371 2276 -694433.6992574 +2372 2276 -58719220.64359 +2373 2276 11841897.70428 +2374 2276 9288189.074786 +2375 2276 -21171048.60074 +2382 2276 57871.26589252 +2383 2276 -34500021.48517 +2384 2276 -41438476.99211 +2385 2276 231485.0634617 +2386 2276 -2777734.795662 +2387 2276 -127043423.7988 +2388 2276 57871.26589543 +2389 2276 37277756.28083 +2390 2276 -57757921.43384 +2400 2276 -10597685.63642 +2401 2276 -8663199.819997 +2402 2276 -17363182.43788 +2403 2276 -44977548.07992 +2404 2276 -694433.6992576 +2405 2276 -59807200.44138 +2406 2276 -11899768.97017 +2407 2276 9357633.519253 +2408 2276 -21458826.37861 +2277 2277 677810035.2011 +2278 2277 36667397.55284 +2279 2277 3125086.662505 +2280 2277 20859938.00677 +2281 2277 -36666959.01753 +2282 2277 2702569.081896 +2292 2277 -51881527.1465 +2293 2277 -36666666.66065 +2294 2277 2505785.245605 +2295 2277 -136819701.2443 +2296 2277 9.089708328247e-07 +2297 2277 -462970.1266867 +2298 2277 -51905201.38891 +2299 2277 36666666.66065 +2300 2277 -2702548.086863 +2370 2277 -18752053.59425 +2371 2277 9166666.66968 +2372 2277 10539814.37052 +2373 2277 -72726245.22972 +2374 2277 -9166776.303506 +2375 2277 44231216.90386 +2385 2277 -1865379.213624 +2386 2277 8.79168510437e-07 +2387 2277 57871.26589221 +2388 2277 70575234.21716 +2389 2277 9166849.392726 +2390 2277 781227.3439141 +2391 2277 -20203256.3538 +2392 2277 -9166739.758899 +2393 2277 11899863.74724 +2403 2277 -18848133.13973 +2404 2277 -9166666.66968 +2405 2277 -10597685.63642 +2406 2277 -60775629.25067 +2407 2277 -1.214444637299e-06 +2408 2277 -45012270.30212 +2409 2277 -20383999.6175 +2410 2277 9166666.669679 +2411 2277 -11899768.97017 +2278 2278 578802727.5875 +2279 2278 -8610918.562153 +2280 2278 -36667105.19596 +2281 2278 -107472939.8429 +2282 2278 4611020.401354 +2292 2278 -36666666.66065 +2293 2278 -40880751.7318 +2294 2278 1263867.397843 +2295 2278 9.685754776001e-07 +2296 2278 24514918.12315 +2297 2278 -2777734.795656 +2298 2278 36666666.66065 +2299 2278 -40904425.97421 +2300 2278 1513867.397816 +2370 2278 9166666.66968 +2371 2278 -16001859.73922 +2372 2278 -8593755.37553 +2373 2278 -9166739.758897 +2374 2278 -29642168.10562 +2375 2278 8204934.122165 +2385 2278 1.229345798492e-06 +2386 2278 -36698646.37071 +2387 2278 -34527799.26293 +2388 2278 9166849.392726 +2389 2278 45823407.30156 +2390 2278 -2152765.098743 +2391 2278 -9166776.303508 +2392 2278 -52286475.83204 +2393 2278 37069600.58987 +2403 2278 -9166666.669679 +2404 2278 -16097939.2847 +2405 2278 -8663199.819997 +2406 2278 -1.445412635803e-06 +2407 2278 -20441974.38895 +2408 2278 -694433.6992576 +2409 2278 9166666.669678 +2410 2278 -17633805.76247 +2411 2278 9357633.519253 +2279 2279 623143279.9755 +2280 2279 2737301.801614 +2281 2279 5388806.115241 +2282 2279 41364580.11227 +2292 2279 2471063.023406 +2293 2279 1236089.620084 +2294 2279 -6756715.38321 +2295 2279 -462970.1266864 +2296 2279 -2777734.795656 +2297 2279 44192040.0554 +2298 2279 -2737270.309063 +2299 2279 1541645.175575 +2300 2279 -6819846.696327 +2370 2279 10539814.37052 +2371 2279 -8593755.37553 +2372 2279 -17106970.31658 +2373 2279 44196492.14387 +2374 2279 8010523.495484 +2375 2279 -58776166.2905 +2385 2279 57871.26589252 +2386 2279 -34500021.48517 +2387 2279 -41438476.99211 +2388 2279 781316.8545274 +2389 2279 -2152693.49136 +2390 2279 -107886912.3736 +2391 2279 11899911.13577 +2392 2279 37236269.31883 +2393 2279 -57440830.58835 +2403 2279 -10597685.63642 +2404 2279 -8663199.819997 +2405 2279 -17363182.43788 +2406 2279 -44977548.07992 +2407 2279 -694433.6992576 +2408 2279 -59807200.44138 +2409 2279 -11899768.97017 +2410 2279 9357633.519253 +2411 2279 -21458826.37861 +2280 2280 407563929.055 +2281 2280 -25145238.89341 +2282 2280 -2293234.224282 +2295 2280 -51881527.1465 +2296 2280 -36666666.66065 +2297 2280 2505785.245605 +2298 2280 -59676961.47535 +2299 2280 25141515.70066 +2300 2280 -67823.50352038 +2301 2280 -189595094.0897 +2302 2280 29337056.52127 +2303 2280 -694488.2655304 +2373 2280 -5106206.927443 +2374 2280 11000109.63744 +2375 2280 12682625.90274 +2388 2280 -15511422.68773 +2389 2280 -9166776.303506 +2390 2280 -10539940.2691 +2391 2280 57002220.2306 +2392 2280 -6544915.940513 +2393 2280 4861555.215121 +2406 2280 -18848133.13973 +2407 2280 -9166666.66968 +2408 2280 -10597685.63642 +2409 2280 -29177118.41547 +2410 2280 6543892.420132 +2411 2280 -25729678.71087 +2412 2280 -53961140.25394 +2413 2280 7334356.856125 +2414 2280 -1354081.113647 +2281 2281 699802921.116 +2282 2281 -11146138.11235 +2295 2281 -36666666.66065 +2296 2281 -40880751.7318 +2297 2281 1263867.397843 +2298 2281 25139654.10429 +2299 2281 84860300.43415 +2300 2281 -1661075.16402 +2301 2281 44005584.78191 +2302 2281 -509039245.6252 +2303 2281 4042794.265653 +2373 2281 7333406.424962 +2374 2281 -5106206.927443 +2375 2281 -6763956.526763 +2388 2281 -9166739.758897 +2389 2281 -47594642.16596 +2390 2281 -34569643.89832 +2391 2281 -6544915.940513 +2392 2281 138242633.1703 +2393 2281 1389850.346674 +2406 2281 -9166666.669679 +2407 2281 -16097939.2847 +2408 2281 -8663199.819997 +2409 2281 6543380.659941 +2410 2281 6841374.023334 +2411 2281 5925066.094897 +2412 2281 11001535.28419 +2413 2281 -141887020.0092 +2414 2281 18142632.26191 +2282 2282 442159068.8707 +2295 2282 2471063.023406 +2296 2282 1236089.620084 +2297 2282 -6756715.38321 +2298 2282 -1248352.367417 +2299 2282 -1800051.757736 +2300 2282 48763257.37113 +2301 2282 -1041732.398296 +2302 2282 3931461.602197 +2303 2282 -186142766.0369 +2373 2282 8455083.935158 +2374 2282 -10145934.79014 +2375 2282 -13616551.80652 +2388 2282 -10539898.30291 +2389 2282 -34736312.74845 +2390 2282 -44929274.14549 +2391 2282 -5398901.65238 +2392 2282 -6817695.611917 +2393 2282 -15837053.95701 +2406 2282 -10597685.63642 +2407 2282 -8663199.819997 +2408 2282 -17363182.43788 +2409 2282 -25903283.59124 +2410 2282 5953357.675215 +2411 2282 -27221579.91443 +2412 2282 -2031121.67047 +2413 2282 17600907.9829 +2414 2282 -55970494.25524 +2283 2283 626081101.6128 +2284 2283 7.033348083496e-06 +2285 2283 925940.2533548 +2286 2283 85765730.61463 +2287 2283 -3.814697265625e-06 +2288 2283 231485.0634534 +2304 2283 -136819701.2443 +2305 2283 9.089708328247e-07 +2306 2283 -462970.1266867 +2307 2283 -51905201.38891 +2308 2283 36666666.66065 +2309 2283 -2702548.086863 +2376 2283 -60367636.82651 +2377 2283 1.877546310425e-06 +2378 2283 44780785.23866 +2379 2283 -20276082.95081 +2380 2283 -9166666.66968 +2381 2283 11841897.70428 +2394 2283 51054233.83102 +2395 2283 1.788139343262e-06 +2396 2283 231485.0634618 +2397 2283 -7985170.87927 +2398 2283 -2.771615982056e-06 +2399 2283 57871.2658952 +2415 2283 -60775629.25067 +2416 2283 -1.214444637299e-06 +2417 2283 -45012270.30212 +2418 2283 -20383999.6175 +2419 2283 9166666.669679 +2420 2283 -11899768.97017 +2284 2284 538074898.3386 +2285 2284 -11110939.17715 +2286 2284 -2.861022949219e-06 +2287 2284 -53567337.94508 +2288 2284 5555469.588581 +2304 2284 9.685754776001e-07 +2305 2284 24514918.12315 +2306 2284 -2777734.795656 +2307 2284 36666666.66065 +2308 2284 -40904425.97421 +2309 2284 1513867.397816 +2376 2284 1.169741153717e-06 +2377 2284 -20033981.96478 +2378 2284 -694433.6992575 +2379 2284 -9166666.66968 +2380 2284 -17525889.09577 +2381 2284 9288189.074786 +2394 2284 1.966953277588e-06 +2395 2284 29052683.00161 +2396 2284 -2777734.795662 +2397 2284 -2.190470695496e-06 +2398 2284 -42818438.03636 +2399 2284 37305534.05859 +2415 2284 -1.445412635803e-06 +2416 2284 -20441974.38895 +2417 2284 -694433.6992576 +2418 2284 9166666.669678 +2419 2284 -17633805.76247 +2420 2284 9357633.519253 +2285 2285 616797415.4266 +2286 2285 231485.0634536 +2287 2285 5555469.588581 +2288 2285 82852085.35441 +2304 2285 -462970.1266864 +2305 2285 -2777734.795656 +2306 2285 44192040.0554 +2307 2285 -2737270.309063 +2308 2285 1541645.175575 +2309 2285 -6819846.696327 +2376 2285 44746063.01646 +2377 2285 -694433.6992574 +2378 2285 -58719220.64359 +2379 2285 11841897.70428 +2380 2285 9288189.074786 +2381 2285 -21171048.60074 +2394 2285 231485.0634617 +2395 2285 -2777734.795662 +2396 2285 -127043423.7988 +2397 2285 57871.26589543 +2398 2285 37277756.28083 +2399 2285 -57757921.43384 +2415 2285 -44977548.07992 +2416 2285 -694433.6992576 +2417 2285 -59807200.44138 +2418 2285 -11899768.97017 +2419 2285 9357633.519253 +2420 2285 -21458826.37861 +2286 2286 626081101.6128 +2287 2286 7.033348083496e-06 +2288 2286 925940.2533548 +2289 2286 85765730.61463 +2290 2286 -3.814697265625e-06 +2291 2286 231485.0634534 +2304 2286 -51881527.1465 +2305 2286 -36666666.66065 +2306 2286 2505785.245605 +2307 2286 -136819701.2443 +2308 2286 9.089708328247e-07 +2309 2286 -462970.1266867 +2310 2286 -51905201.38891 +2311 2286 36666666.66065 +2312 2286 -2702548.086863 +2376 2286 -18752053.59425 +2377 2286 9166666.66968 +2378 2286 10539814.37052 +2379 2286 -60367636.82651 +2380 2286 1.877546310425e-06 +2381 2286 44780785.23866 +2382 2286 -20276082.95081 +2383 2286 -9166666.66968 +2384 2286 11841897.70428 +2394 2286 -1865379.213624 +2395 2286 8.79168510437e-07 +2396 2286 57871.26589221 +2397 2286 51054233.83102 +2398 2286 1.788139343262e-06 +2399 2286 231485.0634618 +2400 2286 -7985170.87927 +2401 2286 -2.771615982056e-06 +2402 2286 57871.2658952 +2415 2286 -18848133.13973 +2416 2286 -9166666.66968 +2417 2286 -10597685.63642 +2418 2286 -60775629.25067 +2419 2286 -1.214444637299e-06 +2420 2286 -45012270.30212 +2421 2286 -20383999.6175 +2422 2286 9166666.669679 +2423 2286 -11899768.97017 +2287 2287 538074898.3386 +2288 2287 -11110939.17715 +2289 2287 -2.861022949219e-06 +2290 2287 -53567337.94508 +2291 2287 5555469.588581 +2304 2287 -36666666.66065 +2305 2287 -40880751.7318 +2306 2287 1263867.397843 +2307 2287 9.685754776001e-07 +2308 2287 24514918.12315 +2309 2287 -2777734.795656 +2310 2287 36666666.66065 +2311 2287 -40904425.97421 +2312 2287 1513867.397816 +2376 2287 9166666.66968 +2377 2287 -16001859.73922 +2378 2287 -8593755.37553 +2379 2287 1.169741153717e-06 +2380 2287 -20033981.96478 +2381 2287 -694433.6992575 +2382 2287 -9166666.66968 +2383 2287 -17525889.09577 +2384 2287 9288189.074786 +2394 2287 1.229345798492e-06 +2395 2287 -36698646.37071 +2396 2287 -34527799.26293 +2397 2287 1.966953277588e-06 +2398 2287 29052683.00161 +2399 2287 -2777734.795662 +2400 2287 -2.190470695496e-06 +2401 2287 -42818438.03636 +2402 2287 37305534.05859 +2415 2287 -9166666.669679 +2416 2287 -16097939.2847 +2417 2287 -8663199.819997 +2418 2287 -1.445412635803e-06 +2419 2287 -20441974.38895 +2420 2287 -694433.6992576 +2421 2287 9166666.669678 +2422 2287 -17633805.76247 +2423 2287 9357633.519253 +2288 2288 616797415.4266 +2289 2288 231485.0634536 +2290 2288 5555469.588581 +2291 2288 82852085.35441 +2304 2288 2471063.023406 +2305 2288 1236089.620084 +2306 2288 -6756715.38321 +2307 2288 -462970.1266864 +2308 2288 -2777734.795656 +2309 2288 44192040.0554 +2310 2288 -2737270.309063 +2311 2288 1541645.175575 +2312 2288 -6819846.696327 +2376 2288 10539814.37052 +2377 2288 -8593755.37553 +2378 2288 -17106970.31658 +2379 2288 44746063.01646 +2380 2288 -694433.6992574 +2381 2288 -58719220.64359 +2382 2288 11841897.70428 +2383 2288 9288189.074786 +2384 2288 -21171048.60074 +2394 2288 57871.26589252 +2395 2288 -34500021.48517 +2396 2288 -41438476.99211 +2397 2288 231485.0634617 +2398 2288 -2777734.795662 +2399 2288 -127043423.7988 +2400 2288 57871.26589543 +2401 2288 37277756.28083 +2402 2288 -57757921.43384 +2415 2288 -10597685.63642 +2416 2288 -8663199.819997 +2417 2288 -17363182.43788 +2418 2288 -44977548.07992 +2419 2288 -694433.6992576 +2420 2288 -59807200.44138 +2421 2288 -11899768.97017 +2422 2288 9357633.519253 +2423 2288 -21458826.37861 +2289 2289 626081101.6128 +2290 2289 7.033348083496e-06 +2291 2289 925940.2533548 +2292 2289 85765730.61463 +2293 2289 -3.814697265625e-06 +2294 2289 231485.0634534 +2307 2289 -51881527.1465 +2308 2289 -36666666.66065 +2309 2289 2505785.245605 +2310 2289 -136819701.2443 +2311 2289 9.089708328247e-07 +2312 2289 -462970.1266867 +2313 2289 -51905201.38891 +2314 2289 36666666.66065 +2315 2289 -2702548.086863 +2379 2289 -18752053.59425 +2380 2289 9166666.66968 +2381 2289 10539814.37052 +2382 2289 -60367636.82651 +2383 2289 1.877546310425e-06 +2384 2289 44780785.23866 +2385 2289 -20276082.95081 +2386 2289 -9166666.66968 +2387 2289 11841897.70428 +2397 2289 -1865379.213624 +2398 2289 8.79168510437e-07 +2399 2289 57871.26589221 +2400 2289 51054233.83102 +2401 2289 1.788139343262e-06 +2402 2289 231485.0634618 +2403 2289 -7985170.87927 +2404 2289 -2.771615982056e-06 +2405 2289 57871.2658952 +2418 2289 -18848133.13973 +2419 2289 -9166666.66968 +2420 2289 -10597685.63642 +2421 2289 -60775629.25067 +2422 2289 -1.214444637299e-06 +2423 2289 -45012270.30212 +2424 2289 -20383999.6175 +2425 2289 9166666.669679 +2426 2289 -11899768.97017 +2290 2290 538074898.3386 +2291 2290 -11110939.17715 +2292 2290 -2.861022949219e-06 +2293 2290 -53567337.94508 +2294 2290 5555469.588581 +2307 2290 -36666666.66065 +2308 2290 -40880751.7318 +2309 2290 1263867.397843 +2310 2290 9.685754776001e-07 +2311 2290 24514918.12315 +2312 2290 -2777734.795656 +2313 2290 36666666.66065 +2314 2290 -40904425.97421 +2315 2290 1513867.397816 +2379 2290 9166666.66968 +2380 2290 -16001859.73922 +2381 2290 -8593755.37553 +2382 2290 1.169741153717e-06 +2383 2290 -20033981.96478 +2384 2290 -694433.6992575 +2385 2290 -9166666.66968 +2386 2290 -17525889.09577 +2387 2290 9288189.074786 +2397 2290 1.229345798492e-06 +2398 2290 -36698646.37071 +2399 2290 -34527799.26293 +2400 2290 1.966953277588e-06 +2401 2290 29052683.00161 +2402 2290 -2777734.795662 +2403 2290 -2.190470695496e-06 +2404 2290 -42818438.03636 +2405 2290 37305534.05859 +2418 2290 -9166666.669679 +2419 2290 -16097939.2847 +2420 2290 -8663199.819997 +2421 2290 -1.445412635803e-06 +2422 2290 -20441974.38895 +2423 2290 -694433.6992576 +2424 2290 9166666.669678 +2425 2290 -17633805.76247 +2426 2290 9357633.519253 +2291 2291 616797415.4266 +2292 2291 231485.0634536 +2293 2291 5555469.588581 +2294 2291 82852085.35441 +2307 2291 2471063.023406 +2308 2291 1236089.620084 +2309 2291 -6756715.38321 +2310 2291 -462970.1266864 +2311 2291 -2777734.795656 +2312 2291 44192040.0554 +2313 2291 -2737270.309063 +2314 2291 1541645.175575 +2315 2291 -6819846.696327 +2379 2291 10539814.37052 +2380 2291 -8593755.37553 +2381 2291 -17106970.31658 +2382 2291 44746063.01646 +2383 2291 -694433.6992574 +2384 2291 -58719220.64359 +2385 2291 11841897.70428 +2386 2291 9288189.074786 +2387 2291 -21171048.60074 +2397 2291 57871.26589252 +2398 2291 -34500021.48517 +2399 2291 -41438476.99211 +2400 2291 231485.0634617 +2401 2291 -2777734.795662 +2402 2291 -127043423.7988 +2403 2291 57871.26589543 +2404 2291 37277756.28083 +2405 2291 -57757921.43384 +2418 2291 -10597685.63642 +2419 2291 -8663199.819997 +2420 2291 -17363182.43788 +2421 2291 -44977548.07992 +2422 2291 -694433.6992576 +2423 2291 -59807200.44138 +2424 2291 -11899768.97017 +2425 2291 9357633.519253 +2426 2291 -21458826.37861 +2292 2292 626081101.6128 +2293 2292 7.033348083496e-06 +2294 2292 925940.2533548 +2295 2292 85765730.61463 +2296 2292 -3.814697265625e-06 +2297 2292 231485.0634534 +2310 2292 -51881527.1465 +2311 2292 -36666666.66065 +2312 2292 2505785.245605 +2313 2292 -136819701.2443 +2314 2292 9.089708328247e-07 +2315 2292 -462970.1266867 +2316 2292 -51905201.38891 +2317 2292 36666666.66065 +2318 2292 -2702548.086863 +2382 2292 -18752053.59425 +2383 2292 9166666.66968 +2384 2292 10539814.37052 +2385 2292 -60367636.82651 +2386 2292 1.877546310425e-06 +2387 2292 44780785.23866 +2388 2292 -20276082.95081 +2389 2292 -9166666.66968 +2390 2292 11841897.70428 +2400 2292 -1865379.213624 +2401 2292 8.79168510437e-07 +2402 2292 57871.26589221 +2403 2292 51054233.83102 +2404 2292 1.788139343262e-06 +2405 2292 231485.0634618 +2406 2292 -7985170.87927 +2407 2292 -2.771615982056e-06 +2408 2292 57871.2658952 +2421 2292 -18848133.13973 +2422 2292 -9166666.66968 +2423 2292 -10597685.63642 +2424 2292 -60775629.25067 +2425 2292 -1.214444637299e-06 +2426 2292 -45012270.30212 +2427 2292 -20383999.6175 +2428 2292 9166666.669679 +2429 2292 -11899768.97017 +2293 2293 538074898.3386 +2294 2293 -11110939.17715 +2295 2293 -2.861022949219e-06 +2296 2293 -53567337.94508 +2297 2293 5555469.588581 +2310 2293 -36666666.66065 +2311 2293 -40880751.7318 +2312 2293 1263867.397843 +2313 2293 9.685754776001e-07 +2314 2293 24514918.12315 +2315 2293 -2777734.795656 +2316 2293 36666666.66065 +2317 2293 -40904425.97421 +2318 2293 1513867.397816 +2382 2293 9166666.66968 +2383 2293 -16001859.73922 +2384 2293 -8593755.37553 +2385 2293 1.169741153717e-06 +2386 2293 -20033981.96478 +2387 2293 -694433.6992575 +2388 2293 -9166666.66968 +2389 2293 -17525889.09577 +2390 2293 9288189.074786 +2400 2293 1.229345798492e-06 +2401 2293 -36698646.37071 +2402 2293 -34527799.26293 +2403 2293 1.966953277588e-06 +2404 2293 29052683.00161 +2405 2293 -2777734.795662 +2406 2293 -2.190470695496e-06 +2407 2293 -42818438.03636 +2408 2293 37305534.05859 +2421 2293 -9166666.669679 +2422 2293 -16097939.2847 +2423 2293 -8663199.819997 +2424 2293 -1.445412635803e-06 +2425 2293 -20441974.38895 +2426 2293 -694433.6992576 +2427 2293 9166666.669678 +2428 2293 -17633805.76247 +2429 2293 9357633.519253 +2294 2294 616797415.4266 +2295 2294 231485.0634536 +2296 2294 5555469.588581 +2297 2294 82852085.35441 +2310 2294 2471063.023406 +2311 2294 1236089.620084 +2312 2294 -6756715.38321 +2313 2294 -462970.1266864 +2314 2294 -2777734.795656 +2315 2294 44192040.0554 +2316 2294 -2737270.309063 +2317 2294 1541645.175575 +2318 2294 -6819846.696327 +2382 2294 10539814.37052 +2383 2294 -8593755.37553 +2384 2294 -17106970.31658 +2385 2294 44746063.01646 +2386 2294 -694433.6992574 +2387 2294 -58719220.64359 +2388 2294 11841897.70428 +2389 2294 9288189.074786 +2390 2294 -21171048.60074 +2400 2294 57871.26589252 +2401 2294 -34500021.48517 +2402 2294 -41438476.99211 +2403 2294 231485.0634617 +2404 2294 -2777734.795662 +2405 2294 -127043423.7988 +2406 2294 57871.26589543 +2407 2294 37277756.28083 +2408 2294 -57757921.43384 +2421 2294 -10597685.63642 +2422 2294 -8663199.819997 +2423 2294 -17363182.43788 +2424 2294 -44977548.07992 +2425 2294 -694433.6992576 +2426 2294 -59807200.44138 +2427 2294 -11899768.97017 +2428 2294 9357633.519253 +2429 2294 -21458826.37861 +2295 2295 626081101.6128 +2296 2295 7.033348083496e-06 +2297 2295 925940.2533548 +2298 2295 85765730.61463 +2299 2295 -3.814697265625e-06 +2300 2295 231485.0634534 +2313 2295 -51881527.1465 +2314 2295 -36666666.66065 +2315 2295 2505785.245605 +2316 2295 -136819701.2443 +2317 2295 9.089708328247e-07 +2318 2295 -462970.1266867 +2319 2295 -51905201.38891 +2320 2295 36666666.66065 +2321 2295 -2702548.086863 +2385 2295 -18752053.59425 +2386 2295 9166666.66968 +2387 2295 10539814.37052 +2388 2295 -60367636.82651 +2389 2295 1.877546310425e-06 +2390 2295 44780785.23866 +2391 2295 -20276082.95081 +2392 2295 -9166666.66968 +2393 2295 11841897.70428 +2403 2295 -1865379.213624 +2404 2295 8.79168510437e-07 +2405 2295 57871.26589221 +2406 2295 51054233.83102 +2407 2295 1.788139343262e-06 +2408 2295 231485.0634618 +2409 2295 -7985170.87927 +2410 2295 -2.771615982056e-06 +2411 2295 57871.2658952 +2424 2295 -18848133.13973 +2425 2295 -9166666.66968 +2426 2295 -10597685.63642 +2427 2295 -60775629.25067 +2428 2295 -1.214444637299e-06 +2429 2295 -45012270.30212 +2430 2295 -20383999.6175 +2431 2295 9166666.669679 +2432 2295 -11899768.97017 +2296 2296 538074898.3386 +2297 2296 -11110939.17715 +2298 2296 -2.861022949219e-06 +2299 2296 -53567337.94508 +2300 2296 5555469.588581 +2313 2296 -36666666.66065 +2314 2296 -40880751.7318 +2315 2296 1263867.397843 +2316 2296 9.685754776001e-07 +2317 2296 24514918.12315 +2318 2296 -2777734.795656 +2319 2296 36666666.66065 +2320 2296 -40904425.97421 +2321 2296 1513867.397816 +2385 2296 9166666.66968 +2386 2296 -16001859.73922 +2387 2296 -8593755.37553 +2388 2296 1.169741153717e-06 +2389 2296 -20033981.96478 +2390 2296 -694433.6992575 +2391 2296 -9166666.66968 +2392 2296 -17525889.09577 +2393 2296 9288189.074786 +2403 2296 1.229345798492e-06 +2404 2296 -36698646.37071 +2405 2296 -34527799.26293 +2406 2296 1.966953277588e-06 +2407 2296 29052683.00161 +2408 2296 -2777734.795662 +2409 2296 -2.190470695496e-06 +2410 2296 -42818438.03636 +2411 2296 37305534.05859 +2424 2296 -9166666.669679 +2425 2296 -16097939.2847 +2426 2296 -8663199.819997 +2427 2296 -1.445412635803e-06 +2428 2296 -20441974.38895 +2429 2296 -694433.6992576 +2430 2296 9166666.669678 +2431 2296 -17633805.76247 +2432 2296 9357633.519253 +2297 2297 616797415.4266 +2298 2297 231485.0634536 +2299 2297 5555469.588581 +2300 2297 82852085.35441 +2313 2297 2471063.023406 +2314 2297 1236089.620084 +2315 2297 -6756715.38321 +2316 2297 -462970.1266864 +2317 2297 -2777734.795656 +2318 2297 44192040.0554 +2319 2297 -2737270.309063 +2320 2297 1541645.175575 +2321 2297 -6819846.696327 +2385 2297 10539814.37052 +2386 2297 -8593755.37553 +2387 2297 -17106970.31658 +2388 2297 44746063.01646 +2389 2297 -694433.6992574 +2390 2297 -58719220.64359 +2391 2297 11841897.70428 +2392 2297 9288189.074786 +2393 2297 -21171048.60074 +2403 2297 57871.26589252 +2404 2297 -34500021.48517 +2405 2297 -41438476.99211 +2406 2297 231485.0634617 +2407 2297 -2777734.795662 +2408 2297 -127043423.7988 +2409 2297 57871.26589543 +2410 2297 37277756.28083 +2411 2297 -57757921.43384 +2424 2297 -10597685.63642 +2425 2297 -8663199.819997 +2426 2297 -17363182.43788 +2427 2297 -44977548.07992 +2428 2297 -694433.6992576 +2429 2297 -59807200.44138 +2430 2297 -11899768.97017 +2431 2297 9357633.519253 +2432 2297 -21458826.37861 +2298 2298 527732996.6747 +2299 2298 15448105.76131 +2300 2298 1352554.552373 +2301 2298 -95118417.26927 +2302 2298 -75446126.04139 +2303 2298 1021640.575356 +2316 2298 -51881527.1465 +2317 2298 -36666666.66065 +2318 2298 2505785.245605 +2319 2298 -86033365.36057 +2320 2298 24063656.22554 +2321 2298 -110868.0321211 +2322 2298 -45738405.09723 +2323 2298 10794709.95026 +2324 2298 -181650.9566633 +2388 2298 -18752053.59425 +2389 2298 9166666.66968 +2390 2298 10539814.37052 +2391 2298 -28689005.84703 +2392 2298 6543380.659943 +2393 2298 25399000.74626 +2406 2298 -1865379.213624 +2407 2298 8.79168510437e-07 +2408 2298 57871.26589221 +2409 2298 60544850.76444 +2410 2298 3603652.033654 +2411 2298 165256.0848025 +2412 2298 -36046786.41637 +2413 2298 -18861624.24183 +2414 2298 11409584.46838 +2427 2298 -18848133.13973 +2428 2298 -9166666.66968 +2429 2298 -10597685.63642 +2430 2298 -45324581.42976 +2431 2298 6015914.059347 +2432 2298 -35313654.50317 +2433 2298 -18251664.62718 +2434 2298 2698677.488894 +2435 2298 -1659648.850827 +2299 2299 645529474.5711 +2300 2299 -7340875.469264 +2301 2299 -75447987.63776 +2302 2299 -250794612.1175 +2303 2299 1665730.961277 +2316 2299 -36666666.66065 +2317 2299 -40880751.7318 +2318 2299 1263867.397843 +2319 2299 24063656.22554 +2320 2299 19704498.54099 +2321 2299 -1263948.6007 +2322 2299 10794709.95026 +2323 2299 -140802296.2262 +2324 2299 1044821.700929 +2388 2299 9166666.66968 +2389 2299 -16001859.73922 +2390 2299 -8593755.37553 +2391 2299 6543892.420133 +2392 2299 7329486.591774 +2393 2299 -6861432.291434 +2406 2299 1.229345798492e-06 +2407 2299 -36698646.37071 +2408 2299 -34527799.26293 +2409 2299 3603652.033653 +2410 2299 90110247.58946 +2411 2299 -1973524.931692 +2412 2299 -18862136.00203 +2413 2299 -74966289.42761 +2414 2299 36320757.18761 +2427 2299 -9166666.669679 +2428 2299 -16097939.2847 +2429 2299 -8663199.819997 +2430 2299 6015914.059347 +2431 2299 -18890115.44135 +2432 2299 7371512.847656 +2433 2299 2698677.488894 +2434 2299 -42017637.42113 +2435 2299 16927872.0975 +2300 2300 521231498.0717 +2301 2300 1195273.597041 +2302 2300 1943417.199096 +2303 2300 -60590062.19069 +2316 2300 2471063.023406 +2317 2300 1236089.620084 +2318 2300 -6756715.38321 +2319 2300 -978923.5875342 +2320 2300 -1291726.378473 +2321 2300 48623486.51979 +2322 2300 -251095.4010623 +2323 2300 1044821.700929 +2324 2300 -32250770.90951 +2388 2300 10539814.37052 +2389 2300 -8593755.37553 +2390 2300 -17106970.31658 +2391 2300 25572605.62664 +2392 2300 -6888721.711543 +2393 2300 -25919946.39859 +2406 2300 57871.26589252 +2407 2300 -34500021.48517 +2408 2300 -41438476.99211 +2409 2300 165435.1762095 +2410 2300 -1973381.627549 +2411 2300 -58670256.12405 +2412 2300 11409680.57863 +2413 2300 36320340.74991 +2414 2300 -47859546.84135 +2427 2300 -10597685.63642 +2428 2300 -8663199.819997 +2429 2300 -17363182.43788 +2430 2300 -35487265.61249 +2431 2300 7371512.849165 +2432 2300 -51354101.90813 +2433 2300 -1659648.850827 +2434 2300 16927872.0975 +2435 2300 -26241528.32399 +2301 2301 554169247.361 +2302 2301 17054543.77992 +2303 2301 -724142.721697 +2319 2301 -53262133.98087 +2320 2301 -32705759.54262 +2321 2301 337518.2011556 +2322 2301 32602470.69165 +2323 2301 38583743.86768 +2324 2301 -359703.7745384 +2325 2301 64359455.48084 +2326 2301 -20425982.4884 +2327 2301 54703.41451001 +2328 2301 -1281086.858114 +2329 2301 28935857.23927 +2330 2301 -17471.873625 +2391 2301 -53458391.75147 +2392 2301 11001535.28419 +2393 2301 1822748.871423 +2409 2301 -35172500.00353 +2410 2301 -18862136.00203 +2411 2301 -11029051.06911 +2412 2301 35790640.60615 +2413 2301 4298038.396794 +2414 2301 8759735.736302 +2430 2301 -19804774.09007 +2431 2301 -8176439.889684 +2432 2301 -11139057.95335 +2433 2301 -41703527.98086 +2434 2301 9670377.580278 +2435 2301 -43908768.3245 +2436 2301 -23096419.85021 +2437 2301 -5140898.074326 +2438 2301 13676758.60085 +2439 2301 -17236872.81083 +2440 2301 7209522.704775 +2441 2301 -10716254.75056 +2302 2302 958321698.0947 +2303 2302 -5799304.02044 +2319 2302 -32705759.54262 +2320 2302 -17400227.63301 +2321 2302 -74400.58715915 +2322 2302 38583743.86768 +2323 2302 160574469.7587 +2324 2302 -573061.2585385 +2325 2302 -5759315.824143 +2326 2302 -6251510.530391 +2327 2302 57494.78903285 +2328 2302 28935857.23927 +2329 2302 -23536130.61164 +2330 2302 70574.01604483 +2391 2302 7334356.856125 +2392 2302 -141384271.5067 +2393 2302 -15223117.05093 +2409 2302 -18861624.24184 +2410 2302 -74092003.01479 +2411 2302 -35487648.98173 +2412 2302 4298038.396793 +2413 2302 144981214.6301 +2414 2302 -898589.0163781 +2430 2302 -8176439.889684 +2431 2302 -10839297.49869 +2432 2302 -8997766.816414 +2433 2302 9670377.580277 +2434 2302 -9734323.79071 +2435 2302 7544152.626836 +2436 2302 -1474231.406454 +2437 2302 -40740840.42931 +2438 2302 33347738.67704 +2439 2302 7209522.704775 +2440 2302 -22872324.27073 +2441 2302 16684392.2326 +2303 2303 717409238.0425 +2319 2303 302795.9789559 +2320 2303 -102178.3649187 +2321 2303 -626812.8042064 +2322 2303 -568037.1078372 +2323 2303 -600839.0363119 +2324 2303 193914115.0064 +2325 2303 -49463.25213635 +2326 2303 57494.78903276 +2327 2303 126494909.3007 +2328 2303 -121638.5402918 +2329 2303 70574.01604487 +2330 2303 41206555.57713 +2391 2303 1215165.914282 +2392 2303 -15709313.95751 +2393 2303 -54629831.58199 +2409 2303 -11028968.11405 +2410 2303 -35488091.42098 +2411 2303 -45528116.40711 +2412 2303 -8774708.705263 +2413 2303 -1927368.836544 +2414 2303 -102472943.4706 +2430 2303 -11139057.95335 +2431 2303 -8997766.816414 +2432 2303 -17461344.76991 +2433 2303 -43908768.32454 +2434 2303 7544152.628345 +2435 2303 -84665181.10733 +2436 2303 5551758.600068 +2437 2303 33347738.67704 +2438 2303 -72767413.37603 +2439 2303 -10716254.75056 +2440 2303 16684392.2326 +2441 2303 -34960091.63584 +2304 2304 313040550.8064 +2305 2304 3.218650817871e-06 +2306 2304 462970.1266764 +2307 2304 42883259.87802 +2308 2304 7333333.332129 +2309 2304 -318285.2460207 +2394 2304 -60367636.82651 +2395 2304 1.877546310425e-06 +2396 2304 44780785.23866 +2397 2304 -20276082.95081 +2398 2304 -9166666.66968 +2399 2304 11841897.70428 +2415 2304 25526722.3448 +2416 2304 -5.960464477539e-08 +2417 2304 -8946896.355626 +2418 2304 -3992585.439634 +2419 2304 1833333.333934 +2420 2304 -2345231.034498 +2305 2305 269037449.1693 +2306 2305 -5555469.588573 +2307 2305 -7333333.332131 +2308 2305 -26783274.40183 +2309 2305 2749957.016519 +2394 2305 1.169741153717e-06 +2395 2305 -20033981.96478 +2396 2305 -694433.6992575 +2397 2305 -9166666.66968 +2398 2305 -17525889.09577 +2399 2305 9288189.074786 +2415 2305 6.556510925293e-07 +2416 2305 14525946.9301 +2417 2305 -1388867.397833 +2418 2305 -1833333.333937 +2419 2305 -21409219.01818 +2420 2305 18645822.58485 +2306 2306 308398707.7133 +2307 2306 723381.420473 +2308 2306 2805512.572065 +2309 2306 41427094.86576 +2394 2306 44746063.01646 +2395 2306 -694433.6992574 +2396 2306 -58719220.64359 +2397 2306 11841897.70428 +2398 2306 9288189.074786 +2399 2306 -21171048.60074 +2415 2306 9004770.308089 +2416 2306 -1388867.397833 +2417 2306 -63522764.08798 +2418 2306 2403102.300394 +2419 2306 18645822.58486 +2420 2306 -28878960.71692 +2307 2307 313040550.8064 +2308 2307 3.218650817871e-06 +2309 2307 462970.1266764 +2310 2307 42883259.87802 +2311 2307 7333333.332129 +2312 2307 -318285.2460207 +2394 2307 -18752053.59425 +2395 2307 9166666.66968 +2396 2307 10539814.37052 +2397 2307 -60367636.82651 +2398 2307 1.877546310425e-06 +2399 2307 44780785.23866 +2400 2307 -20276082.95081 +2401 2307 -9166666.66968 +2402 2307 11841897.70428 +2415 2307 -932689.6068121 +2416 2307 -1833333.333935 +2417 2307 -2084814.367748 +2418 2307 25526722.3448 +2419 2307 -5.960464477539e-08 +2420 2307 -8946896.355626 +2421 2307 -3992585.439634 +2422 2307 1833333.333934 +2423 2307 -2345231.034498 +2308 2308 269037449.1693 +2309 2308 -5555469.588573 +2310 2308 -7333333.332131 +2311 2308 -26783274.40183 +2312 2308 2749957.016519 +2394 2308 9166666.66968 +2395 2308 -16001859.73922 +2396 2308 -8593755.37553 +2397 2308 1.169741153717e-06 +2398 2308 -20033981.96478 +2399 2308 -694433.6992575 +2400 2308 -9166666.66968 +2401 2308 -17525889.09577 +2402 2308 9288189.074786 +2415 2308 1833333.333937 +2416 2308 -18349323.18536 +2417 2308 -17256955.18702 +2418 2308 6.556510925293e-07 +2419 2308 14525946.9301 +2420 2308 -1388867.397833 +2421 2308 -1833333.333937 +2422 2308 -21409219.01818 +2423 2308 18645822.58485 +2309 2309 308398707.7133 +2310 2309 723381.420473 +2311 2309 2805512.572065 +2312 2309 41427094.86576 +2394 2309 10539814.37052 +2395 2309 -8593755.37553 +2396 2309 -17106970.31658 +2397 2309 44746063.01646 +2398 2309 -694433.6992574 +2399 2309 -58719220.64359 +2400 2309 11841897.70428 +2401 2309 9288189.074786 +2402 2309 -21171048.60074 +2415 2309 2142685.63364 +2416 2309 -17256955.18703 +2417 2309 -20719238.49606 +2418 2309 9004770.308089 +2419 2309 -1388867.397833 +2420 2309 -63522764.08798 +2421 2309 2403102.300394 +2422 2309 18645822.58486 +2423 2309 -28878960.71692 +2310 2310 313040550.8064 +2311 2310 3.218650817871e-06 +2312 2310 462970.1266764 +2313 2310 42883259.87802 +2314 2310 7333333.332129 +2315 2310 -318285.2460207 +2397 2310 -18752053.59425 +2398 2310 9166666.66968 +2399 2310 10539814.37052 +2400 2310 -60367636.82651 +2401 2310 1.877546310425e-06 +2402 2310 44780785.23866 +2403 2310 -20276082.95081 +2404 2310 -9166666.66968 +2405 2310 11841897.70428 +2418 2310 -932689.6068121 +2419 2310 -1833333.333935 +2420 2310 -2084814.367748 +2421 2310 25526722.3448 +2422 2310 -5.960464477539e-08 +2423 2310 -8946896.355626 +2424 2310 -3992585.439634 +2425 2310 1833333.333934 +2426 2310 -2345231.034498 +2311 2311 269037449.1693 +2312 2311 -5555469.588573 +2313 2311 -7333333.332131 +2314 2311 -26783274.40183 +2315 2311 2749957.016519 +2397 2311 9166666.66968 +2398 2311 -16001859.73922 +2399 2311 -8593755.37553 +2400 2311 1.169741153717e-06 +2401 2311 -20033981.96478 +2402 2311 -694433.6992575 +2403 2311 -9166666.66968 +2404 2311 -17525889.09577 +2405 2311 9288189.074786 +2418 2311 1833333.333937 +2419 2311 -18349323.18536 +2420 2311 -17256955.18702 +2421 2311 6.556510925293e-07 +2422 2311 14525946.9301 +2423 2311 -1388867.397833 +2424 2311 -1833333.333937 +2425 2311 -21409219.01818 +2426 2311 18645822.58485 +2312 2312 308398707.7133 +2313 2312 723381.420473 +2314 2312 2805512.572065 +2315 2312 41427094.86576 +2397 2312 10539814.37052 +2398 2312 -8593755.37553 +2399 2312 -17106970.31658 +2400 2312 44746063.01646 +2401 2312 -694433.6992574 +2402 2312 -58719220.64359 +2403 2312 11841897.70428 +2404 2312 9288189.074786 +2405 2312 -21171048.60074 +2418 2312 2142685.63364 +2419 2312 -17256955.18703 +2420 2312 -20719238.49606 +2421 2312 9004770.308089 +2422 2312 -1388867.397833 +2423 2312 -63522764.08798 +2424 2312 2403102.300394 +2425 2312 18645822.58486 +2426 2312 -28878960.71692 +2313 2313 313040550.8064 +2314 2313 3.218650817871e-06 +2315 2313 462970.1266764 +2316 2313 42883259.87802 +2317 2313 7333333.332129 +2318 2313 -318285.2460207 +2400 2313 -18752053.59425 +2401 2313 9166666.66968 +2402 2313 10539814.37052 +2403 2313 -60367636.82651 +2404 2313 1.877546310425e-06 +2405 2313 44780785.23866 +2406 2313 -20276082.95081 +2407 2313 -9166666.66968 +2408 2313 11841897.70428 +2421 2313 -932689.6068121 +2422 2313 -1833333.333935 +2423 2313 -2084814.367748 +2424 2313 25526722.3448 +2425 2313 -5.960464477539e-08 +2426 2313 -8946896.355626 +2427 2313 -3992585.439634 +2428 2313 1833333.333934 +2429 2313 -2345231.034498 +2314 2314 269037449.1693 +2315 2314 -5555469.588573 +2316 2314 -7333333.332131 +2317 2314 -26783274.40183 +2318 2314 2749957.016519 +2400 2314 9166666.66968 +2401 2314 -16001859.73922 +2402 2314 -8593755.37553 +2403 2314 1.169741153717e-06 +2404 2314 -20033981.96478 +2405 2314 -694433.6992575 +2406 2314 -9166666.66968 +2407 2314 -17525889.09577 +2408 2314 9288189.074786 +2421 2314 1833333.333937 +2422 2314 -18349323.18536 +2423 2314 -17256955.18702 +2424 2314 6.556510925293e-07 +2425 2314 14525946.9301 +2426 2314 -1388867.397833 +2427 2314 -1833333.333937 +2428 2314 -21409219.01818 +2429 2314 18645822.58485 +2315 2315 308398707.7133 +2316 2315 723381.420473 +2317 2315 2805512.572065 +2318 2315 41427094.86576 +2400 2315 10539814.37052 +2401 2315 -8593755.37553 +2402 2315 -17106970.31658 +2403 2315 44746063.01646 +2404 2315 -694433.6992574 +2405 2315 -58719220.64359 +2406 2315 11841897.70428 +2407 2315 9288189.074786 +2408 2315 -21171048.60074 +2421 2315 2142685.63364 +2422 2315 -17256955.18703 +2423 2315 -20719238.49606 +2424 2315 9004770.308089 +2425 2315 -1388867.397833 +2426 2315 -63522764.08798 +2427 2315 2403102.300394 +2428 2315 18645822.58486 +2429 2315 -28878960.71692 +2316 2316 313040550.8064 +2317 2316 3.218650817871e-06 +2318 2316 462970.1266764 +2319 2316 42883259.87802 +2320 2316 7333333.332129 +2321 2316 -318285.2460207 +2403 2316 -18752053.59425 +2404 2316 9166666.66968 +2405 2316 10539814.37052 +2406 2316 -60367636.82651 +2407 2316 1.877546310425e-06 +2408 2316 44780785.23866 +2409 2316 -20276082.95081 +2410 2316 -9166666.66968 +2411 2316 11841897.70428 +2424 2316 -932689.6068121 +2425 2316 -1833333.333935 +2426 2316 -2084814.367748 +2427 2316 25526722.3448 +2428 2316 -5.960464477539e-08 +2429 2316 -8946896.355626 +2430 2316 -3992585.439634 +2431 2316 1833333.333934 +2432 2316 -2345231.034498 +2317 2317 269037449.1693 +2318 2317 -5555469.588573 +2319 2317 -7333333.332131 +2320 2317 -26783274.40183 +2321 2317 2749957.016519 +2403 2317 9166666.66968 +2404 2317 -16001859.73922 +2405 2317 -8593755.37553 +2406 2317 1.169741153717e-06 +2407 2317 -20033981.96478 +2408 2317 -694433.6992575 +2409 2317 -9166666.66968 +2410 2317 -17525889.09577 +2411 2317 9288189.074786 +2424 2317 1833333.333937 +2425 2317 -18349323.18536 +2426 2317 -17256955.18702 +2427 2317 6.556510925293e-07 +2428 2317 14525946.9301 +2429 2317 -1388867.397833 +2430 2317 -1833333.333937 +2431 2317 -21409219.01818 +2432 2317 18645822.58485 +2318 2318 308398707.7133 +2319 2318 723381.420473 +2320 2318 2805512.572065 +2321 2318 41427094.86576 +2403 2318 10539814.37052 +2404 2318 -8593755.37553 +2405 2318 -17106970.31658 +2406 2318 44746063.01646 +2407 2318 -694433.6992574 +2408 2318 -58719220.64359 +2409 2318 11841897.70428 +2410 2318 9288189.074786 +2411 2318 -21171048.60074 +2424 2318 2142685.63364 +2425 2318 -17256955.18703 +2426 2318 -20719238.49606 +2427 2318 9004770.308089 +2428 2318 -1388867.397833 +2429 2318 -63522764.08798 +2430 2318 2403102.300394 +2431 2318 18645822.58486 +2432 2318 -28878960.71692 +2319 2319 311501301.9278 +2320 2319 3961702.031803 +2321 2319 2461349.04567 +2322 2319 -4984022.060376 +2323 2319 -24652932.04324 +2324 2319 367556.3402904 +2406 2319 -18752053.59425 +2407 2319 9166666.66968 +2408 2319 10539814.37052 +2409 2319 -44778234.89159 +2410 2319 6015914.059352 +2411 2319 35041206.59625 +2412 2319 -20008769.25006 +2413 2319 -8176439.889681 +2414 2319 11299136.49846 +2427 2319 -932689.6068121 +2428 2319 -1833333.333935 +2429 2319 -2084814.367748 +2430 2319 25141334.84086 +2431 2319 990425.5084367 +2432 2319 -8447023.847856 +2433 2319 -17627581.50065 +2434 2319 -6163233.013846 +2435 2319 7435569.639298 +2320 2320 292367764.6648 +2321 2320 -3560498.398243 +2322 2320 -39319598.70751 +2323 2320 -68784496.1816 +2324 2320 607245.3940165 +2406 2320 9166666.66968 +2407 2320 -16001859.73922 +2408 2320 -8593755.37553 +2409 2320 6015914.059351 +2410 2320 -18343768.90317 +2411 2320 -8010431.594268 +2412 2320 -8176439.889681 +2413 2320 -11043292.65868 +2414 2320 8953622.07837 +2427 2320 1833333.333937 +2428 2320 -18349323.18536 +2429 2320 -17256955.18702 +2430 2320 990425.5084375 +2431 2320 20357950.52274 +2432 2320 -890124.6000073 +2433 2320 -9829899.681717 +2434 2320 -33577700.03881 +2435 2320 25797644.67844 +2321 2321 314119300.5055 +2322 2321 541167.4513703 +2323 2321 635023.1717897 +2324 2321 25143014.98303 +2406 2321 10539814.37052 +2407 2321 -8593755.37553 +2408 2321 -17106970.31658 +2409 2321 35214817.70936 +2410 2321 -8010431.592745 +2411 2321 -49897177.80632 +2412 2321 11299136.49846 +2413 2321 8953622.07837 +2414 2321 -18005331.86323 +2427 2321 2142685.63364 +2428 2321 -17256955.18703 +2429 2321 -20719238.49606 +2430 2321 9504087.260305 +2431 2321 -890124.6000072 +2432 2321 -62094149.98014 +2433 2321 11975291.86111 +2434 2321 25797644.67693 +2435 2321 -37398448.87766 +2322 2322 355610367.635 +2323 2322 44835876.15348 +2324 2322 -31361.04836392 +2325 2322 -68349309.06932 +2326 2322 -44397476.08203 +2327 2322 104055.9041087 +2328 2322 15311530.47477 +2329 2322 -10497255.18188 +2330 2322 344159.0905987 +2409 2322 -17800014.26928 +2410 2322 2698677.488893 +2411 2322 1551462.261342 +2412 2322 -41550567.91137 +2413 2322 9670377.580283 +2414 2322 43763453.88329 +2430 2322 -16877239.2765 +2431 2322 -9829899.681722 +2432 2322 -11739430.35753 +2433 2322 -5864347.079577 +2434 2322 11272333.02856 +2435 2322 -8862175.675498 +2436 2322 -34156706.14972 +2437 2322 -11123810.63458 +2438 2322 20338606.37075 +2439 2322 -25110571.33565 +2440 2322 -2687677.781431 +2441 2322 7481972.406576 +2323 2323 438246431.0147 +2324 2323 -1374381.127417 +2325 2323 -44397476.08203 +2326 2323 -48686713.94084 +2327 2323 70574.01604466 +2328 2323 -25163921.84615 +2329 2323 -56094761.85019 +2330 2323 224801.2750072 +2409 2323 2698677.488893 +2410 2323 -41565987.06324 +2411 2323 -16405461.24678 +2412 2323 9670377.580283 +2413 2323 -9581363.721229 +2414 2323 -7837791.815088 +2430 2323 -6163233.01385 +2431 2323 -32827357.81467 +2432 2323 -25487077.53535 +2433 2323 11272333.02856 +2434 2323 14803293.44955 +2435 2323 -343891.8558928 +2436 2323 -11123810.63458 +2437 2323 -29217261.77281 +2438 2323 16684392.2326 +2439 2323 -6354344.449302 +2440 2323 -42970769.09971 +2441 2323 33389830.22049 +2324 2324 485548459.258 +2325 2324 104055.9041089 +2326 2324 70574.01604465 +2327 2324 16055972.24793 +2328 2324 309436.8683792 +2329 2324 224801.2750072 +2330 2324 70129562.94617 +2409 2324 1551462.261342 +2410 2324 -16405461.24678 +2411 2324 -25037127.36958 +2412 2324 43763453.88333 +2413 2324 -7837791.813566 +2414 2324 -84257287.58871 +2430 2324 -7303874.802406 +2431 2324 -25487077.53687 +2432 2324 -35397536.2799 +2433 2324 8672268.766067 +2434 2324 -343891.8558926 +2435 2324 -131666276.7598 +2436 2324 20338606.37075 +2437 2324 16684392.2326 +2438 2324 -41305029.13792 +2439 2324 11778916.85432 +2440 2324 33389830.22049 +2441 2324 -59295265.58963 +2325 2325 235127665.6719 +2326 2325 49759315.81692 +2327 2325 -60490.45165706 +2328 2325 -6799933.309191 +2329 2325 397476.0892505 +2330 2325 5897.799686611 +2412 2325 -23001722.8805 +2413 2325 -1474231.406455 +2414 2325 -5550324.72933 +2433 2325 -34062009.18001 +2434 2325 -11123810.63458 +2435 2325 -20286393.64259 +2436 2325 -19349792.24124 +2437 2325 12474231.41007 +2438 2325 8109815.470699 +2439 2325 -35471324.17617 +2440 2325 123810.6309668 +2441 2325 -31023097.09878 +2326 2326 216363631.6977 +2327 2326 -57494.78902459 +2328 2326 15064142.75351 +2329 2326 62912471.54766 +2330 2326 -70574.01603854 +2412 2326 -5140898.074327 +2413 2326 -40646143.4596 +2414 2326 -33318927.97868 +2433 2326 -11123810.63458 +2434 2326 -29122564.8031 +2435 2326 -16648941.11168 +2436 2326 12474231.41007 +2437 2326 -24049121.66948 +2438 2326 6652261.316389 +2439 2326 3790477.298838 +2440 2326 -18067018.54574 +2441 2326 3315607.773964 +2327 2327 344429080.4936 +2328 2327 -98268.86695981 +2329 2327 -70574.0160386 +2330 2327 111254381.3556 +2412 2327 -13675324.7301 +2413 2327 -33318927.97868 +2414 2327 -72514888.12347 +2433 2327 -20286393.64259 +2434 2327 -16648941.11168 +2435 2327 -41052503.88534 +2436 2327 -8140184.526632 +2437 2327 -6681072.014753 +2438 2327 -122349568.8948 +2439 2327 -31023097.10068 +2440 2327 -3351058.894892 +2441 2327 -62442635.03753 +2328 2328 175536156.3728 +2329 2328 -18836078.14664 +2330 2328 396581.649942 +2412 2328 -17142175.84111 +2413 2328 7209522.704776 +2414 2328 10681661.92314 +2433 2328 -24826480.42668 +2434 2328 -6354344.449306 +2435 2328 -11727749.81249 +2436 2328 -35471324.17617 +2437 2328 3790477.298842 +2438 2328 30999819.5577 +2439 2328 -13375171.0781 +2440 2328 -4645655.554312 +2441 2328 -4310953.890546 +2329 2329 199485087.5944 +2330 2329 -224801.2749909 +2412 2329 7209522.704776 +2413 2329 -22777627.30101 +2414 2329 -16648941.11168 +2433 2329 -2687677.781434 +2434 2329 -42686678.19075 +2435 2329 -33276836.43523 +2436 2329 123810.63097 +2437 2329 -18067018.54574 +2438 2329 3315607.773964 +2439 2329 -4645655.554311 +2440 2329 -7283827.484575 +2441 2329 6610169.772934 +2330 2330 264787277.9352 +2412 2330 10681661.92314 +2413 2330 -16648941.11168 +2414 2330 -34707566.38326 +2433 2330 -7465527.586963 +2434 2330 -33276836.43523 +2435 2330 -58537689.83235 +2436 2330 30999819.55581 +2437 2330 -3351058.894892 +2438 2330 -62442635.03753 +2439 2330 4248212.774715 +2440 2330 -6723163.558209 +2441 2330 -86485846.13902 +2331 2331 434188482.4496 +2332 2331 42222222.21529 +2333 2331 14004257.85694 +2334 2331 -237961315.0134 +2335 2331 -42232516.70149 +2336 2331 -11962465.89917 +2337 2331 7955780.401528 +2338 2331 33788072.25843 +2339 2331 -8749455.084514 +2442 2331 66125098.41489 +2443 2331 11944444.44837 +2444 2331 15207852.8515 +2445 2331 -93269248.17781 +2446 2331 -11949381.52693 +2447 2331 -52618980.4305 +2448 2331 -17054654.84265 +2449 2331 9560492.637254 +2450 2331 -13448143.98712 +2332 2332 370839207.457 +2333 2332 -27831791.96622 +2334 2332 -42237663.94459 +2335 2332 -39482381.812 +2336 2332 -16655123.83823 +2337 2332 50682108.38765 +2338 2332 7955780.401527 +2339 2332 11010768.51444 +2442 2332 11944444.44837 +2443 2332 48201681.39244 +2444 2332 -5082672.97723 +2445 2332 -11951850.06621 +2446 2332 -37114294.87206 +2447 2332 -16826932.79813 +2448 2332 14340738.95588 +2449 2332 -17054654.84265 +2450 2332 16137388.124 +2333 2333 400035038.4858 +2334 2333 -10941569.92029 +2335 2333 -13223756.5556 +2336 2333 -11892250.19807 +2337 2333 -13124182.62677 +2338 2333 7340512.342961 +2339 2333 21215414.40408 +2442 2333 -3762599.703372 +2443 2333 -20258812.61341 +2444 2333 -38071476.41094 +2445 2333 -52354091.66514 +2446 2333 -15346414.53585 +2447 2333 -72544459.24024 +2448 2333 -20172215.98068 +2449 2333 10758258.74933 +2450 2333 -45479079.58041 +2334 2334 753320607.0872 +2335 2334 42247958.4308 +2336 2334 13425270.63193 +2337 2334 10687201.53391 +2338 2334 -42232516.7015 +2339 2334 11747147.69675 +2340 2334 -163051082.2809 +2341 2334 4.857778549194e-06 +2342 2334 -2497714.891996 +2343 2334 -63439558.95712 +2344 2334 42222222.21529 +2345 2334 -11747692.6104 +2442 2334 -83208406.42019 +2443 2334 -11951850.06621 +2444 2334 42498171.10922 +2445 2334 125282026.2887 +2446 2334 11956787.14478 +2447 2334 5935098.98454 +2448 2334 -32275376.32772 +2449 2334 -11949381.52693 +2450 2334 17028332.3953 +2451 2334 -71083613.53293 +2452 2334 2.801418304443e-06 +2453 2334 -48425475.84218 +2454 2334 -29334356.73017 +2455 2334 11944444.44836 +2456 2334 -17021299.52369 +2335 2335 639301177.7705 +2336 2335 -37037050.15144 +2337 2335 -42237663.9446 +2338 2335 -137109995.2621 +2339 2335 20238494.1063 +2340 2335 3.516674041748e-06 +2341 2335 22728141.58569 +2342 2335 -11944266.20381 +2343 2335 42222222.21529 +2344 2335 -50772020.36985 +2345 2335 6611021.990771 +2442 2335 -11949381.52693 +2443 2335 -27053453.11441 +2444 2335 3626698.329752 +2445 2335 11956787.14477 +2446 2335 93024319.31714 +2447 2335 -16362810.24847 +2448 2335 -11951850.06621 +2449 2335 -74090485.10009 +2450 2335 46808583.40323 +2451 2335 2.488493919373e-06 +2452 2335 -18527661.31289 +2453 2335 -5277700.460655 +2454 2335 11944444.44836 +2455 2335 -25750784.24113 +2456 2335 12385378.01131 +2336 2336 644924144.2682 +2337 2336 11642708.57308 +2338 2336 22769593.39294 +2339 2336 12096388.9117 +2340 2336 -1483826.003273 +2341 2336 -11944266.20381 +2342 2336 36217937.62672 +2343 2336 -11643525.94355 +2344 2336 6527688.657292 +2345 2336 -17639683.8315 +2442 2336 42233282.34386 +2443 2336 2150097.608279 +2444 2336 -45715547.88649 +2445 2336 5939995.986973 +2446 2336 -16358892.70393 +2447 2336 -51790570.05088 +2448 2336 17031848.8311 +2449 2336 48076086.23075 +2450 2336 -90703859.27092 +2451 2336 -48161586.95346 +2452 2336 -5277700.460655 +2453 2336 -56307063.72196 +2454 2336 -17021299.52369 +2455 2336 12385378.01131 +2456 2336 -35357225.93349 +2337 2337 434188482.4496 +2338 2337 42222222.21529 +2339 2337 14004257.85694 +2340 2337 -62903012.53369 +2341 2337 -42222222.21529 +2342 2337 10648140.71925 +2343 2337 -237961315.0134 +2344 2337 -42232516.70149 +2345 2337 -11962465.89917 +2346 2337 7955780.401528 +2347 2337 33788072.25843 +2348 2337 -8749455.084514 +2442 2337 1810230.00851 +2443 2337 14340738.95588 +2444 2337 8290807.874965 +2445 2337 -3359294.569133 +2446 2337 -11951850.06621 +2447 2337 -6689786.134111 +2448 2337 66125098.41489 +2449 2337 11944444.44837 +2450 2337 15207852.8515 +2451 2337 -19644494.8084 +2452 2337 -11944444.44837 +2453 2337 -7125466.187114 +2454 2337 -93269248.17781 +2455 2337 -11949381.52693 +2456 2337 -52618980.4305 +2457 2337 -17054654.84265 +2458 2337 9560492.637254 +2459 2337 -13448143.98712 +2338 2338 370839207.457 +2339 2338 -27831791.96622 +2340 2338 -42222222.21529 +2341 2338 -50235473.94641 +2342 2338 5333244.213044 +2343 2338 -42237663.94459 +2344 2338 -39482381.812 +2345 2338 -16655123.83823 +2346 2338 50682108.38765 +2347 2338 7955780.401527 +2348 2338 11010768.51444 +2442 2338 9560492.637254 +2443 2338 1810230.008509 +2444 2338 -4421798.559475 +2445 2338 -11949381.52693 +2446 2338 -45174403.34149 +2447 2338 -27804612.20634 +2448 2338 11944444.44837 +2449 2338 48201681.39244 +2450 2338 -5082672.97723 +2451 2338 -11944444.44836 +2452 2338 -16060922.31935 +2453 2338 -7107677.550651 +2454 2338 -11951850.06621 +2455 2338 -37114294.87206 +2456 2338 -16826932.79813 +2457 2338 14340738.95588 +2458 2338 -17054654.84265 +2459 2338 16137388.124 +2339 2339 400035038.4858 +2340 2339 10752307.38609 +2341 2339 5416577.546522 +2342 2339 -16208893.36898 +2343 2339 -10941569.92029 +2344 2339 -13223756.5556 +2345 2339 -11892250.19807 +2346 2339 -13124182.62677 +2347 2339 7340512.342961 +2348 2339 21215414.40408 +2442 2339 5527205.249977 +2443 2339 -6632697.839212 +2444 2339 4827280.022694 +2445 2339 -6688405.732252 +2446 2339 -29072115.16194 +2447 2339 -13594307.9147 +2448 2339 -3762599.703372 +2449 2339 -20258812.61341 +2450 2339 -38071476.41094 +2451 2339 -7125466.187114 +2452 2339 -7107677.550651 +2453 2339 -9517594.142065 +2454 2339 -52354091.66514 +2455 2339 -15346414.53585 +2456 2339 -72544459.24024 +2457 2339 -20172215.98068 +2458 2339 10758258.74933 +2459 2339 -45479079.58041 +2340 2340 701224018.4261 +2341 2340 1.215934753418e-05 +2342 2340 3981540.895231 +2343 2340 85654059.23587 +2344 2340 -7.361173629761e-06 +2345 2340 995385.2243004 +2349 2340 -163051082.2809 +2350 2340 4.857778549194e-06 +2351 2340 -2497714.891996 +2352 2340 -63439558.95712 +2353 2340 42222222.21529 +2354 2340 -11747692.6104 +2445 2340 -68569574.7737 +2446 2340 9.983777999878e-07 +2447 2340 46666190.80873 +2448 2340 -28443492.38882 +2449 2340 -11944444.44837 +2450 2340 16581478.26512 +2451 2340 103049709.0446 +2452 2340 8.106231689453e-06 +2453 2340 1759285.033469 +2454 2340 -19975421.90891 +2455 2340 -1.013278961182e-05 +2456 2340 439821.2585936 +2460 2340 -71083613.53293 +2461 2340 2.801418304443e-06 +2462 2340 -48425475.84218 +2463 2340 -29334356.73017 +2464 2340 11944444.44836 +2465 2340 -17021299.52369 +2341 2341 599883709.7778 +2342 2341 -47777064.79172 +2343 2341 -8.612871170044e-06 +2344 2341 -74790087.48109 +2345 2341 24294087.95135 +2349 2341 3.516674041748e-06 +2350 2341 22728141.58569 +2351 2341 -11944266.20381 +2352 2341 42222222.21529 +2353 2341 -50772020.36985 +2354 2341 6611021.990771 +2445 2341 -8.195638656616e-07 +2446 2341 -16013622.55363 +2447 2341 -5277700.460655 +2448 2341 -11944444.44837 +2449 2341 -24859919.89976 +2450 2341 11857600.23336 +2451 2341 7.987022399902e-06 +2452 2341 74381129.14638 +2453 2341 -21110801.83222 +2454 2341 -9.581446647644e-06 +2455 2341 -65364229.15794 +2456 2341 48591512.02092 +2460 2341 2.488493919373e-06 +2461 2341 -18527661.31289 +2462 2341 -5277700.460655 +2463 2341 11944444.44836 +2464 2341 -25750784.24113 +2465 2341 12385378.01131 +2342 2342 657670929.3001 +2343 2342 995385.2243 +2344 2342 23482976.84037 +2345 2342 60454947.39636 +2349 2342 -1483826.003273 +2350 2342 -11944266.20381 +2351 2342 36217937.62672 +2352 2342 -11643525.94355 +2353 2342 6527688.657292 +2354 2342 -17639683.8315 +2445 2342 46402301.92001 +2446 2342 -5277700.460655 +2447 2342 -49602960.36391 +2448 2342 16581478.26512 +2449 2342 11857600.23336 +2450 2342 -32981587.68983 +2451 2342 1759285.033468 +2452 2342 -21110801.83222 +2453 2342 -68142578.48796 +2454 2342 439821.258594 +2455 2342 48380400.90995 +2456 2342 -100781580.1802 +2460 2342 -48161586.95346 +2461 2342 -5277700.460655 +2462 2342 -56307063.72196 +2463 2342 -17021299.52369 +2464 2342 12385378.01131 +2465 2342 -35357225.93349 +2343 2343 753320607.0872 +2344 2343 42247958.4308 +2345 2343 13425270.63193 +2346 2343 10687201.53391 +2347 2343 -42232516.7015 +2348 2343 11747147.69675 +2349 2343 -62903012.53369 +2350 2343 -42222222.21529 +2351 2343 10648140.71925 +2352 2343 -163051082.2809 +2353 2343 4.857778549194e-06 +2354 2343 -2497714.891996 +2355 2343 -63439558.95712 +2356 2343 42222222.21529 +2357 2343 -11747692.6104 +2445 2343 -19278339.76952 +2446 2343 11944444.44837 +2447 2343 6685644.928532 +2448 2343 -83208406.42019 +2449 2343 -11951850.06621 +2450 2343 42498171.10922 +2451 2343 17734607.15466 +2452 2343 1.817941665649e-06 +2453 2343 439821.2585785 +2454 2343 125282026.2887 +2455 2343 11956787.14478 +2456 2343 5935098.98454 +2457 2343 -32275376.32772 +2458 2343 -11949381.52693 +2459 2343 17028332.3953 +2460 2343 -19644494.8084 +2461 2343 -11944444.44837 +2462 2343 -7125466.187114 +2463 2343 -71083613.53293 +2464 2343 2.801418304443e-06 +2465 2343 -48425475.84218 +2466 2343 -29334356.73017 +2467 2343 11944444.44836 +2468 2343 -17021299.52369 +2344 2344 639301177.7705 +2345 2344 -37037050.15144 +2346 2344 -42237663.9446 +2347 2344 -137109995.2621 +2348 2344 20238494.1063 +2349 2344 -42222222.21529 +2350 2344 -50235473.94641 +2351 2344 5333244.213044 +2352 2344 3.516674041748e-06 +2353 2344 22728141.58569 +2354 2344 -11944266.20381 +2355 2344 42222222.21529 +2356 2344 -50772020.36985 +2357 2344 6611021.990771 +2445 2344 11944444.44837 +2446 2344 -15694767.28047 +2447 2344 -6579899.772699 +2448 2344 -11949381.52693 +2449 2344 -27053453.11441 +2450 2344 3626698.329752 +2451 2344 3.322958946228e-06 +2452 2344 -27654200.09436 +2453 2344 -27480710.1887 +2454 2344 11956787.14477 +2455 2344 93024319.31714 +2456 2344 -16362810.24847 +2457 2344 -11951850.06621 +2458 2344 -74090485.10009 +2459 2344 46808583.40323 +2460 2344 -11944444.44836 +2461 2344 -16060922.31935 +2462 2344 -7107677.550651 +2463 2344 2.488493919373e-06 +2464 2344 -18527661.31289 +2465 2344 -5277700.460655 +2466 2344 11944444.44836 +2467 2344 -25750784.24113 +2468 2344 12385378.01131 +2345 2345 644924144.2682 +2346 2345 11642708.57308 +2347 2345 22769593.39294 +2348 2345 12096388.9117 +2349 2345 10752307.38609 +2350 2345 5416577.546522 +2351 2345 -16208893.36898 +2352 2345 -1483826.003273 +2353 2345 -11944266.20381 +2354 2345 36217937.62672 +2355 2345 -11643525.94355 +2356 2345 6527688.657292 +2357 2345 -17639683.8315 +2445 2345 6685644.928532 +2446 2345 -6579899.772699 +2447 2345 -8541180.705052 +2448 2345 42233282.34386 +2449 2345 2150097.608279 +2450 2345 -45715547.88649 +2451 2345 439821.2585788 +2452 2345 -27269599.07773 +2453 2345 -221502.6772963 +2454 2345 5939995.986973 +2455 2345 -16358892.70393 +2456 2345 -51790570.05088 +2457 2345 17031848.8311 +2458 2345 48076086.23075 +2459 2345 -90703859.27092 +2460 2345 -7125466.187114 +2461 2345 -7107677.550651 +2462 2345 -9517594.142065 +2463 2345 -48161586.95346 +2464 2345 -5277700.460655 +2465 2345 -56307063.72196 +2466 2345 -17021299.52369 +2467 2345 12385378.01131 +2468 2345 -35357225.93349 +2346 2346 434188482.4496 +2347 2346 42222222.21529 +2348 2346 14004257.85694 +2352 2346 -62903012.53369 +2353 2346 -42222222.21529 +2354 2346 10648140.71925 +2355 2346 -237961315.0134 +2356 2346 -42232516.70149 +2357 2346 -11962465.89917 +2358 2346 7955780.401528 +2359 2346 33788072.25843 +2360 2346 -8749455.084514 +2448 2346 1810230.00851 +2449 2346 14340738.95588 +2450 2346 8290807.874965 +2454 2346 -3359294.569133 +2455 2346 -11951850.06621 +2456 2346 -6689786.134111 +2457 2346 66125098.41489 +2458 2346 11944444.44837 +2459 2346 15207852.8515 +2463 2346 -19644494.8084 +2464 2346 -11944444.44837 +2465 2346 -7125466.187114 +2466 2346 -93269248.17781 +2467 2346 -11949381.52693 +2468 2346 -52618980.4305 +2469 2346 -17054654.84265 +2470 2346 9560492.637254 +2471 2346 -13448143.98712 +2347 2347 370839207.457 +2348 2347 -27831791.96622 +2352 2347 -42222222.21529 +2353 2347 -50235473.94641 +2354 2347 5333244.213044 +2355 2347 -42237663.94459 +2356 2347 -39482381.812 +2357 2347 -16655123.83823 +2358 2347 50682108.38765 +2359 2347 7955780.401527 +2360 2347 11010768.51444 +2448 2347 9560492.637254 +2449 2347 1810230.008509 +2450 2347 -4421798.559475 +2454 2347 -11949381.52693 +2455 2347 -45174403.34149 +2456 2347 -27804612.20634 +2457 2347 11944444.44837 +2458 2347 48201681.39244 +2459 2347 -5082672.97723 +2463 2347 -11944444.44836 +2464 2347 -16060922.31935 +2465 2347 -7107677.550651 +2466 2347 -11951850.06621 +2467 2347 -37114294.87206 +2468 2347 -16826932.79813 +2469 2347 14340738.95588 +2470 2347 -17054654.84265 +2471 2347 16137388.124 +2348 2348 400035038.4858 +2352 2348 10752307.38609 +2353 2348 5416577.546522 +2354 2348 -16208893.36898 +2355 2348 -10941569.92029 +2356 2348 -13223756.5556 +2357 2348 -11892250.19807 +2358 2348 -13124182.62677 +2359 2348 7340512.342961 +2360 2348 21215414.40408 +2448 2348 5527205.249977 +2449 2348 -6632697.839212 +2450 2348 4827280.022694 +2454 2348 -6688405.732252 +2455 2348 -29072115.16194 +2456 2348 -13594307.9147 +2457 2348 -3762599.703372 +2458 2348 -20258812.61341 +2459 2348 -38071476.41094 +2463 2348 -7125466.187114 +2464 2348 -7107677.550651 +2465 2348 -9517594.142065 +2466 2348 -52354091.66514 +2467 2348 -15346414.53585 +2468 2348 -72544459.24024 +2469 2348 -20172215.98068 +2470 2348 10758258.74933 +2471 2348 -45479079.58041 +2349 2349 701224018.4261 +2350 2349 1.215934753418e-05 +2351 2349 3981540.895231 +2352 2349 85654059.23587 +2353 2349 -7.361173629761e-06 +2354 2349 995385.2243004 +2361 2349 -163051082.2809 +2362 2349 4.857778549194e-06 +2363 2349 -2497714.891996 +2364 2349 -63439558.95712 +2365 2349 42222222.21529 +2366 2349 -11747692.6104 +2451 2349 -68569574.7737 +2452 2349 9.983777999878e-07 +2453 2349 46666190.80873 +2454 2349 -28443492.38882 +2455 2349 -11944444.44837 +2456 2349 16581478.26512 +2460 2349 103049709.0446 +2461 2349 8.106231689453e-06 +2462 2349 1759285.033469 +2463 2349 -19975421.90891 +2464 2349 -1.013278961182e-05 +2465 2349 439821.2585936 +2472 2349 -71083613.53293 +2473 2349 2.801418304443e-06 +2474 2349 -48425475.84218 +2475 2349 -29334356.73017 +2476 2349 11944444.44836 +2477 2349 -17021299.52369 +2350 2350 599883709.7778 +2351 2350 -47777064.79172 +2352 2350 -8.612871170044e-06 +2353 2350 -74790087.48109 +2354 2350 24294087.95135 +2361 2350 3.516674041748e-06 +2362 2350 22728141.58569 +2363 2350 -11944266.20381 +2364 2350 42222222.21529 +2365 2350 -50772020.36985 +2366 2350 6611021.990771 +2451 2350 -8.195638656616e-07 +2452 2350 -16013622.55363 +2453 2350 -5277700.460655 +2454 2350 -11944444.44837 +2455 2350 -24859919.89976 +2456 2350 11857600.23336 +2460 2350 7.987022399902e-06 +2461 2350 74381129.14638 +2462 2350 -21110801.83222 +2463 2350 -9.581446647644e-06 +2464 2350 -65364229.15794 +2465 2350 48591512.02092 +2472 2350 2.488493919373e-06 +2473 2350 -18527661.31289 +2474 2350 -5277700.460655 +2475 2350 11944444.44836 +2476 2350 -25750784.24113 +2477 2350 12385378.01131 +2351 2351 657670929.3001 +2352 2351 995385.2243 +2353 2351 23482976.84037 +2354 2351 60454947.39636 +2361 2351 -1483826.003273 +2362 2351 -11944266.20381 +2363 2351 36217937.62672 +2364 2351 -11643525.94355 +2365 2351 6527688.657292 +2366 2351 -17639683.8315 +2451 2351 46402301.92001 +2452 2351 -5277700.460655 +2453 2351 -49602960.36391 +2454 2351 16581478.26512 +2455 2351 11857600.23336 +2456 2351 -32981587.68983 +2460 2351 1759285.033468 +2461 2351 -21110801.83222 +2462 2351 -68142578.48796 +2463 2351 439821.258594 +2464 2351 48380400.90995 +2465 2351 -100781580.1802 +2472 2351 -48161586.95346 +2473 2351 -5277700.460655 +2474 2351 -56307063.72196 +2475 2351 -17021299.52369 +2476 2351 12385378.01131 +2477 2351 -35357225.93349 +2352 2352 701224018.4261 +2353 2352 1.215934753418e-05 +2354 2352 3981540.895231 +2355 2352 85654059.23587 +2356 2352 -7.361173629761e-06 +2357 2352 995385.2243004 +2361 2352 -62903012.53369 +2362 2352 -42222222.21529 +2363 2352 10648140.71925 +2364 2352 -163051082.2809 +2365 2352 4.857778549194e-06 +2366 2352 -2497714.891996 +2367 2352 -63439558.95712 +2368 2352 42222222.21529 +2369 2352 -11747692.6104 +2451 2352 -19278339.76952 +2452 2352 11944444.44837 +2453 2352 6685644.928532 +2454 2352 -68569574.7737 +2455 2352 9.983777999878e-07 +2456 2352 46666190.80873 +2457 2352 -28443492.38882 +2458 2352 -11944444.44837 +2459 2352 16581478.26512 +2460 2352 17734607.15466 +2461 2352 1.817941665649e-06 +2462 2352 439821.2585785 +2463 2352 103049709.0446 +2464 2352 8.106231689453e-06 +2465 2352 1759285.033469 +2466 2352 -19975421.90891 +2467 2352 -1.013278961182e-05 +2468 2352 439821.2585936 +2472 2352 -19644494.8084 +2473 2352 -11944444.44837 +2474 2352 -7125466.187114 +2475 2352 -71083613.53293 +2476 2352 2.801418304443e-06 +2477 2352 -48425475.84218 +2478 2352 -29334356.73017 +2479 2352 11944444.44836 +2480 2352 -17021299.52369 +2353 2353 599883709.7778 +2354 2353 -47777064.79172 +2355 2353 -8.612871170044e-06 +2356 2353 -74790087.48109 +2357 2353 24294087.95135 +2361 2353 -42222222.21529 +2362 2353 -50235473.94641 +2363 2353 5333244.213044 +2364 2353 3.516674041748e-06 +2365 2353 22728141.58569 +2366 2353 -11944266.20381 +2367 2353 42222222.21529 +2368 2353 -50772020.36985 +2369 2353 6611021.990771 +2451 2353 11944444.44837 +2452 2353 -15694767.28047 +2453 2353 -6579899.772699 +2454 2353 -8.195638656616e-07 +2455 2353 -16013622.55363 +2456 2353 -5277700.460655 +2457 2353 -11944444.44837 +2458 2353 -24859919.89976 +2459 2353 11857600.23336 +2460 2353 3.322958946228e-06 +2461 2353 -27654200.09436 +2462 2353 -27480710.1887 +2463 2353 7.987022399902e-06 +2464 2353 74381129.14638 +2465 2353 -21110801.83222 +2466 2353 -9.581446647644e-06 +2467 2353 -65364229.15794 +2468 2353 48591512.02092 +2472 2353 -11944444.44836 +2473 2353 -16060922.31935 +2474 2353 -7107677.550651 +2475 2353 2.488493919373e-06 +2476 2353 -18527661.31289 +2477 2353 -5277700.460655 +2478 2353 11944444.44836 +2479 2353 -25750784.24113 +2480 2353 12385378.01131 +2354 2354 657670929.3001 +2355 2354 995385.2243 +2356 2354 23482976.84037 +2357 2354 60454947.39636 +2361 2354 10752307.38609 +2362 2354 5416577.546522 +2363 2354 -16208893.36898 +2364 2354 -1483826.003273 +2365 2354 -11944266.20381 +2366 2354 36217937.62672 +2367 2354 -11643525.94355 +2368 2354 6527688.657292 +2369 2354 -17639683.8315 +2451 2354 6685644.928532 +2452 2354 -6579899.772699 +2453 2354 -8541180.705052 +2454 2354 46402301.92001 +2455 2354 -5277700.460655 +2456 2354 -49602960.36391 +2457 2354 16581478.26512 +2458 2354 11857600.23336 +2459 2354 -32981587.68983 +2460 2354 439821.2585788 +2461 2354 -27269599.07773 +2462 2354 -221502.6772963 +2463 2354 1759285.033468 +2464 2354 -21110801.83222 +2465 2354 -68142578.48796 +2466 2354 439821.258594 +2467 2354 48380400.90995 +2468 2354 -100781580.1802 +2472 2354 -7125466.187114 +2473 2354 -7107677.550651 +2474 2354 -9517594.142065 +2475 2354 -48161586.95346 +2476 2354 -5277700.460655 +2477 2354 -56307063.72196 +2478 2354 -17021299.52369 +2479 2354 12385378.01131 +2480 2354 -35357225.93349 +2355 2355 753320607.0872 +2356 2355 42247958.4308 +2357 2355 13425270.63193 +2358 2355 10687201.53391 +2359 2355 -42232516.7015 +2360 2355 11747147.69675 +2364 2355 -62903012.53369 +2365 2355 -42222222.21529 +2366 2355 10648140.71925 +2367 2355 -163051082.2809 +2368 2355 4.857778549194e-06 +2369 2355 -2497714.891996 +2370 2355 -63439558.95712 +2371 2355 42222222.21529 +2372 2355 -11747692.6104 +2454 2355 -19278339.76952 +2455 2355 11944444.44837 +2456 2355 6685644.928532 +2457 2355 -83208406.42019 +2458 2355 -11951850.06621 +2459 2355 42498171.10922 +2463 2355 17734607.15466 +2464 2355 1.817941665649e-06 +2465 2355 439821.2585785 +2466 2355 125282026.2887 +2467 2355 11956787.14478 +2468 2355 5935098.98454 +2469 2355 -32275376.32772 +2470 2355 -11949381.52693 +2471 2355 17028332.3953 +2475 2355 -19644494.8084 +2476 2355 -11944444.44837 +2477 2355 -7125466.187114 +2478 2355 -71083613.53293 +2479 2355 2.801418304443e-06 +2480 2355 -48425475.84218 +2481 2355 -29334356.73017 +2482 2355 11944444.44836 +2483 2355 -17021299.52369 +2356 2356 639301177.7705 +2357 2356 -37037050.15144 +2358 2356 -42237663.9446 +2359 2356 -137109995.2621 +2360 2356 20238494.1063 +2364 2356 -42222222.21529 +2365 2356 -50235473.94641 +2366 2356 5333244.213044 +2367 2356 3.516674041748e-06 +2368 2356 22728141.58569 +2369 2356 -11944266.20381 +2370 2356 42222222.21529 +2371 2356 -50772020.36985 +2372 2356 6611021.990771 +2454 2356 11944444.44837 +2455 2356 -15694767.28047 +2456 2356 -6579899.772699 +2457 2356 -11949381.52693 +2458 2356 -27053453.11441 +2459 2356 3626698.329752 +2463 2356 3.322958946228e-06 +2464 2356 -27654200.09436 +2465 2356 -27480710.1887 +2466 2356 11956787.14477 +2467 2356 93024319.31714 +2468 2356 -16362810.24847 +2469 2356 -11951850.06621 +2470 2356 -74090485.10009 +2471 2356 46808583.40323 +2475 2356 -11944444.44836 +2476 2356 -16060922.31935 +2477 2356 -7107677.550651 +2478 2356 2.488493919373e-06 +2479 2356 -18527661.31289 +2480 2356 -5277700.460655 +2481 2356 11944444.44836 +2482 2356 -25750784.24113 +2483 2356 12385378.01131 +2357 2357 644924144.2682 +2358 2357 11642708.57308 +2359 2357 22769593.39294 +2360 2357 12096388.9117 +2364 2357 10752307.38609 +2365 2357 5416577.546522 +2366 2357 -16208893.36898 +2367 2357 -1483826.003273 +2368 2357 -11944266.20381 +2369 2357 36217937.62672 +2370 2357 -11643525.94355 +2371 2357 6527688.657292 +2372 2357 -17639683.8315 +2454 2357 6685644.928532 +2455 2357 -6579899.772699 +2456 2357 -8541180.705052 +2457 2357 42233282.34386 +2458 2357 2150097.608279 +2459 2357 -45715547.88649 +2463 2357 439821.2585788 +2464 2357 -27269599.07773 +2465 2357 -221502.6772963 +2466 2357 5939995.986973 +2467 2357 -16358892.70393 +2468 2357 -51790570.05088 +2469 2357 17031848.8311 +2470 2357 48076086.23075 +2471 2357 -90703859.27092 +2475 2357 -7125466.187114 +2476 2357 -7107677.550651 +2477 2357 -9517594.142065 +2478 2357 -48161586.95346 +2479 2357 -5277700.460655 +2480 2357 -56307063.72196 +2481 2357 -17021299.52369 +2482 2357 12385378.01131 +2483 2357 -35357225.93349 +2358 2358 434188482.4496 +2359 2358 42222222.21529 +2360 2358 14004257.85694 +2367 2358 -62903012.53369 +2368 2358 -42222222.21529 +2369 2358 10648140.71925 +2370 2358 -237961315.0134 +2371 2358 -42232516.70149 +2372 2358 -11962465.89917 +2373 2358 7955780.401528 +2374 2358 33788072.25843 +2375 2358 -8749455.084514 +2457 2358 1810230.00851 +2458 2358 14340738.95588 +2459 2358 8290807.874965 +2466 2358 -3359294.569133 +2467 2358 -11951850.06621 +2468 2358 -6689786.134111 +2469 2358 66125098.41489 +2470 2358 11944444.44837 +2471 2358 15207852.8515 +2478 2358 -19644494.8084 +2479 2358 -11944444.44837 +2480 2358 -7125466.187114 +2481 2358 -93269248.17781 +2482 2358 -11949381.52693 +2483 2358 -52618980.4305 +2484 2358 -17054654.84265 +2485 2358 9560492.637254 +2486 2358 -13448143.98712 +2359 2359 370839207.457 +2360 2359 -27831791.96622 +2367 2359 -42222222.21529 +2368 2359 -50235473.94641 +2369 2359 5333244.213044 +2370 2359 -42237663.94459 +2371 2359 -39482381.812 +2372 2359 -16655123.83823 +2373 2359 50682108.38765 +2374 2359 7955780.401527 +2375 2359 11010768.51444 +2457 2359 9560492.637254 +2458 2359 1810230.008509 +2459 2359 -4421798.559475 +2466 2359 -11949381.52693 +2467 2359 -45174403.34149 +2468 2359 -27804612.20634 +2469 2359 11944444.44837 +2470 2359 48201681.39244 +2471 2359 -5082672.97723 +2478 2359 -11944444.44836 +2479 2359 -16060922.31935 +2480 2359 -7107677.550651 +2481 2359 -11951850.06621 +2482 2359 -37114294.87206 +2483 2359 -16826932.79813 +2484 2359 14340738.95588 +2485 2359 -17054654.84265 +2486 2359 16137388.124 +2360 2360 400035038.4858 +2367 2360 10752307.38609 +2368 2360 5416577.546522 +2369 2360 -16208893.36898 +2370 2360 -10941569.92029 +2371 2360 -13223756.5556 +2372 2360 -11892250.19807 +2373 2360 -13124182.62677 +2374 2360 7340512.342961 +2375 2360 21215414.40408 +2457 2360 5527205.249977 +2458 2360 -6632697.839212 +2459 2360 4827280.022694 +2466 2360 -6688405.732252 +2467 2360 -29072115.16194 +2468 2360 -13594307.9147 +2469 2360 -3762599.703372 +2470 2360 -20258812.61341 +2471 2360 -38071476.41094 +2478 2360 -7125466.187114 +2479 2360 -7107677.550651 +2480 2360 -9517594.142065 +2481 2360 -52354091.66514 +2482 2360 -15346414.53585 +2483 2360 -72544459.24024 +2484 2360 -20172215.98068 +2485 2360 10758258.74933 +2486 2360 -45479079.58041 +2361 2361 701224018.4261 +2362 2361 1.215934753418e-05 +2363 2361 3981540.895231 +2364 2361 85654059.23587 +2365 2361 -7.361173629761e-06 +2366 2361 995385.2243004 +2376 2361 -163051082.2809 +2377 2361 4.857778549194e-06 +2378 2361 -2497714.891996 +2379 2361 -63439558.95712 +2380 2361 42222222.21529 +2381 2361 -11747692.6104 +2460 2361 -68569574.7737 +2461 2361 9.983777999878e-07 +2462 2361 46666190.80873 +2463 2361 -28443492.38882 +2464 2361 -11944444.44837 +2465 2361 16581478.26512 +2472 2361 103049709.0446 +2473 2361 8.106231689453e-06 +2474 2361 1759285.033469 +2475 2361 -19975421.90891 +2476 2361 -1.013278961182e-05 +2477 2361 439821.2585936 +2487 2361 -71083613.53293 +2488 2361 2.801418304443e-06 +2489 2361 -48425475.84218 +2490 2361 -29334356.73017 +2491 2361 11944444.44836 +2492 2361 -17021299.52369 +2362 2362 599883709.7778 +2363 2362 -47777064.79172 +2364 2362 -8.612871170044e-06 +2365 2362 -74790087.48109 +2366 2362 24294087.95135 +2376 2362 3.516674041748e-06 +2377 2362 22728141.58569 +2378 2362 -11944266.20381 +2379 2362 42222222.21529 +2380 2362 -50772020.36985 +2381 2362 6611021.990771 +2460 2362 -8.195638656616e-07 +2461 2362 -16013622.55363 +2462 2362 -5277700.460655 +2463 2362 -11944444.44837 +2464 2362 -24859919.89976 +2465 2362 11857600.23336 +2472 2362 7.987022399902e-06 +2473 2362 74381129.14638 +2474 2362 -21110801.83222 +2475 2362 -9.581446647644e-06 +2476 2362 -65364229.15794 +2477 2362 48591512.02092 +2487 2362 2.488493919373e-06 +2488 2362 -18527661.31289 +2489 2362 -5277700.460655 +2490 2362 11944444.44836 +2491 2362 -25750784.24113 +2492 2362 12385378.01131 +2363 2363 657670929.3001 +2364 2363 995385.2243 +2365 2363 23482976.84037 +2366 2363 60454947.39636 +2376 2363 -1483826.003273 +2377 2363 -11944266.20381 +2378 2363 36217937.62672 +2379 2363 -11643525.94355 +2380 2363 6527688.657292 +2381 2363 -17639683.8315 +2460 2363 46402301.92001 +2461 2363 -5277700.460655 +2462 2363 -49602960.36391 +2463 2363 16581478.26512 +2464 2363 11857600.23336 +2465 2363 -32981587.68983 +2472 2363 1759285.033468 +2473 2363 -21110801.83222 +2474 2363 -68142578.48796 +2475 2363 439821.258594 +2476 2363 48380400.90995 +2477 2363 -100781580.1802 +2487 2363 -48161586.95346 +2488 2363 -5277700.460655 +2489 2363 -56307063.72196 +2490 2363 -17021299.52369 +2491 2363 12385378.01131 +2492 2363 -35357225.93349 +2364 2364 701224018.4261 +2365 2364 1.215934753418e-05 +2366 2364 3981540.895231 +2367 2364 85654059.23587 +2368 2364 -7.361173629761e-06 +2369 2364 995385.2243004 +2376 2364 -62903012.53369 +2377 2364 -42222222.21529 +2378 2364 10648140.71925 +2379 2364 -163051082.2809 +2380 2364 4.857778549194e-06 +2381 2364 -2497714.891996 +2382 2364 -63439558.95712 +2383 2364 42222222.21529 +2384 2364 -11747692.6104 +2460 2364 -19278339.76952 +2461 2364 11944444.44837 +2462 2364 6685644.928532 +2463 2364 -68569574.7737 +2464 2364 9.983777999878e-07 +2465 2364 46666190.80873 +2466 2364 -28443492.38882 +2467 2364 -11944444.44837 +2468 2364 16581478.26512 +2472 2364 17734607.15466 +2473 2364 1.817941665649e-06 +2474 2364 439821.2585785 +2475 2364 103049709.0446 +2476 2364 8.106231689453e-06 +2477 2364 1759285.033469 +2478 2364 -19975421.90891 +2479 2364 -1.013278961182e-05 +2480 2364 439821.2585936 +2487 2364 -19644494.8084 +2488 2364 -11944444.44837 +2489 2364 -7125466.187114 +2490 2364 -71083613.53293 +2491 2364 2.801418304443e-06 +2492 2364 -48425475.84218 +2493 2364 -29334356.73017 +2494 2364 11944444.44836 +2495 2364 -17021299.52369 +2365 2365 599883709.7778 +2366 2365 -47777064.79172 +2367 2365 -8.612871170044e-06 +2368 2365 -74790087.48109 +2369 2365 24294087.95135 +2376 2365 -42222222.21529 +2377 2365 -50235473.94641 +2378 2365 5333244.213044 +2379 2365 3.516674041748e-06 +2380 2365 22728141.58569 +2381 2365 -11944266.20381 +2382 2365 42222222.21529 +2383 2365 -50772020.36985 +2384 2365 6611021.990771 +2460 2365 11944444.44837 +2461 2365 -15694767.28047 +2462 2365 -6579899.772699 +2463 2365 -8.195638656616e-07 +2464 2365 -16013622.55363 +2465 2365 -5277700.460655 +2466 2365 -11944444.44837 +2467 2365 -24859919.89976 +2468 2365 11857600.23336 +2472 2365 3.322958946228e-06 +2473 2365 -27654200.09436 +2474 2365 -27480710.1887 +2475 2365 7.987022399902e-06 +2476 2365 74381129.14638 +2477 2365 -21110801.83222 +2478 2365 -9.581446647644e-06 +2479 2365 -65364229.15794 +2480 2365 48591512.02092 +2487 2365 -11944444.44836 +2488 2365 -16060922.31935 +2489 2365 -7107677.550651 +2490 2365 2.488493919373e-06 +2491 2365 -18527661.31289 +2492 2365 -5277700.460655 +2493 2365 11944444.44836 +2494 2365 -25750784.24113 +2495 2365 12385378.01131 +2366 2366 657670929.3001 +2367 2366 995385.2243 +2368 2366 23482976.84037 +2369 2366 60454947.39636 +2376 2366 10752307.38609 +2377 2366 5416577.546522 +2378 2366 -16208893.36898 +2379 2366 -1483826.003273 +2380 2366 -11944266.20381 +2381 2366 36217937.62672 +2382 2366 -11643525.94355 +2383 2366 6527688.657292 +2384 2366 -17639683.8315 +2460 2366 6685644.928532 +2461 2366 -6579899.772699 +2462 2366 -8541180.705052 +2463 2366 46402301.92001 +2464 2366 -5277700.460655 +2465 2366 -49602960.36391 +2466 2366 16581478.26512 +2467 2366 11857600.23336 +2468 2366 -32981587.68983 +2472 2366 439821.2585788 +2473 2366 -27269599.07773 +2474 2366 -221502.6772963 +2475 2366 1759285.033468 +2476 2366 -21110801.83222 +2477 2366 -68142578.48796 +2478 2366 439821.258594 +2479 2366 48380400.90995 +2480 2366 -100781580.1802 +2487 2366 -7125466.187114 +2488 2366 -7107677.550651 +2489 2366 -9517594.142065 +2490 2366 -48161586.95346 +2491 2366 -5277700.460655 +2492 2366 -56307063.72196 +2493 2366 -17021299.52369 +2494 2366 12385378.01131 +2495 2366 -35357225.93349 +2367 2367 701224018.4261 +2368 2367 1.215934753418e-05 +2369 2367 3981540.895231 +2370 2367 85654059.23587 +2371 2367 -7.361173629761e-06 +2372 2367 995385.2243004 +2379 2367 -62903012.53369 +2380 2367 -42222222.21529 +2381 2367 10648140.71925 +2382 2367 -163051082.2809 +2383 2367 4.857778549194e-06 +2384 2367 -2497714.891996 +2385 2367 -63439558.95712 +2386 2367 42222222.21529 +2387 2367 -11747692.6104 +2463 2367 -19278339.76952 +2464 2367 11944444.44837 +2465 2367 6685644.928532 +2466 2367 -68569574.7737 +2467 2367 9.983777999878e-07 +2468 2367 46666190.80873 +2469 2367 -28443492.38882 +2470 2367 -11944444.44837 +2471 2367 16581478.26512 +2475 2367 17734607.15466 +2476 2367 1.817941665649e-06 +2477 2367 439821.2585785 +2478 2367 103049709.0446 +2479 2367 8.106231689453e-06 +2480 2367 1759285.033469 +2481 2367 -19975421.90891 +2482 2367 -1.013278961182e-05 +2483 2367 439821.2585936 +2490 2367 -19644494.8084 +2491 2367 -11944444.44837 +2492 2367 -7125466.187114 +2493 2367 -71083613.53293 +2494 2367 2.801418304443e-06 +2495 2367 -48425475.84218 +2496 2367 -29334356.73017 +2497 2367 11944444.44836 +2498 2367 -17021299.52369 +2368 2368 599883709.7778 +2369 2368 -47777064.79172 +2370 2368 -8.612871170044e-06 +2371 2368 -74790087.48109 +2372 2368 24294087.95135 +2379 2368 -42222222.21529 +2380 2368 -50235473.94641 +2381 2368 5333244.213044 +2382 2368 3.516674041748e-06 +2383 2368 22728141.58569 +2384 2368 -11944266.20381 +2385 2368 42222222.21529 +2386 2368 -50772020.36985 +2387 2368 6611021.990771 +2463 2368 11944444.44837 +2464 2368 -15694767.28047 +2465 2368 -6579899.772699 +2466 2368 -8.195638656616e-07 +2467 2368 -16013622.55363 +2468 2368 -5277700.460655 +2469 2368 -11944444.44837 +2470 2368 -24859919.89976 +2471 2368 11857600.23336 +2475 2368 3.322958946228e-06 +2476 2368 -27654200.09436 +2477 2368 -27480710.1887 +2478 2368 7.987022399902e-06 +2479 2368 74381129.14638 +2480 2368 -21110801.83222 +2481 2368 -9.581446647644e-06 +2482 2368 -65364229.15794 +2483 2368 48591512.02092 +2490 2368 -11944444.44836 +2491 2368 -16060922.31935 +2492 2368 -7107677.550651 +2493 2368 2.488493919373e-06 +2494 2368 -18527661.31289 +2495 2368 -5277700.460655 +2496 2368 11944444.44836 +2497 2368 -25750784.24113 +2498 2368 12385378.01131 +2369 2369 657670929.3001 +2370 2369 995385.2243 +2371 2369 23482976.84037 +2372 2369 60454947.39636 +2379 2369 10752307.38609 +2380 2369 5416577.546522 +2381 2369 -16208893.36898 +2382 2369 -1483826.003273 +2383 2369 -11944266.20381 +2384 2369 36217937.62672 +2385 2369 -11643525.94355 +2386 2369 6527688.657292 +2387 2369 -17639683.8315 +2463 2369 6685644.928532 +2464 2369 -6579899.772699 +2465 2369 -8541180.705052 +2466 2369 46402301.92001 +2467 2369 -5277700.460655 +2468 2369 -49602960.36391 +2469 2369 16581478.26512 +2470 2369 11857600.23336 +2471 2369 -32981587.68983 +2475 2369 439821.2585788 +2476 2369 -27269599.07773 +2477 2369 -221502.6772963 +2478 2369 1759285.033468 +2479 2369 -21110801.83222 +2480 2369 -68142578.48796 +2481 2369 439821.258594 +2482 2369 48380400.90995 +2483 2369 -100781580.1802 +2490 2369 -7125466.187114 +2491 2369 -7107677.550651 +2492 2369 -9517594.142065 +2493 2369 -48161586.95346 +2494 2369 -5277700.460655 +2495 2369 -56307063.72196 +2496 2369 -17021299.52369 +2497 2369 12385378.01131 +2498 2369 -35357225.93349 +2370 2370 753320607.0872 +2371 2370 42247958.4308 +2372 2370 13425270.63193 +2373 2370 10687201.53391 +2374 2370 -42232516.7015 +2375 2370 11747147.69675 +2382 2370 -62903012.53369 +2383 2370 -42222222.21529 +2384 2370 10648140.71925 +2385 2370 -163051082.2809 +2386 2370 4.857778549194e-06 +2387 2370 -2497714.891996 +2388 2370 -63439558.95712 +2389 2370 42222222.21529 +2390 2370 -11747692.6104 +2466 2370 -19278339.76952 +2467 2370 11944444.44837 +2468 2370 6685644.928532 +2469 2370 -83208406.42019 +2470 2370 -11951850.06621 +2471 2370 42498171.10922 +2478 2370 17734607.15466 +2479 2370 1.817941665649e-06 +2480 2370 439821.2585785 +2481 2370 125282026.2887 +2482 2370 11956787.14478 +2483 2370 5935098.98454 +2484 2370 -32275376.32772 +2485 2370 -11949381.52693 +2486 2370 17028332.3953 +2493 2370 -19644494.8084 +2494 2370 -11944444.44837 +2495 2370 -7125466.187114 +2496 2370 -71083613.53293 +2497 2370 2.801418304443e-06 +2498 2370 -48425475.84218 +2499 2370 -29334356.73017 +2500 2370 11944444.44836 +2501 2370 -17021299.52369 +2371 2371 639301177.7705 +2372 2371 -37037050.15144 +2373 2371 -42237663.9446 +2374 2371 -137109995.2621 +2375 2371 20238494.1063 +2382 2371 -42222222.21529 +2383 2371 -50235473.94641 +2384 2371 5333244.213044 +2385 2371 3.516674041748e-06 +2386 2371 22728141.58569 +2387 2371 -11944266.20381 +2388 2371 42222222.21529 +2389 2371 -50772020.36985 +2390 2371 6611021.990771 +2466 2371 11944444.44837 +2467 2371 -15694767.28047 +2468 2371 -6579899.772699 +2469 2371 -11949381.52693 +2470 2371 -27053453.11441 +2471 2371 3626698.329752 +2478 2371 3.322958946228e-06 +2479 2371 -27654200.09436 +2480 2371 -27480710.1887 +2481 2371 11956787.14477 +2482 2371 93024319.31714 +2483 2371 -16362810.24847 +2484 2371 -11951850.06621 +2485 2371 -74090485.10009 +2486 2371 46808583.40323 +2493 2371 -11944444.44836 +2494 2371 -16060922.31935 +2495 2371 -7107677.550651 +2496 2371 2.488493919373e-06 +2497 2371 -18527661.31289 +2498 2371 -5277700.460655 +2499 2371 11944444.44836 +2500 2371 -25750784.24113 +2501 2371 12385378.01131 +2372 2372 644924144.2682 +2373 2372 11642708.57308 +2374 2372 22769593.39294 +2375 2372 12096388.9117 +2382 2372 10752307.38609 +2383 2372 5416577.546522 +2384 2372 -16208893.36898 +2385 2372 -1483826.003273 +2386 2372 -11944266.20381 +2387 2372 36217937.62672 +2388 2372 -11643525.94355 +2389 2372 6527688.657292 +2390 2372 -17639683.8315 +2466 2372 6685644.928532 +2467 2372 -6579899.772699 +2468 2372 -8541180.705052 +2469 2372 42233282.34386 +2470 2372 2150097.608279 +2471 2372 -45715547.88649 +2478 2372 439821.2585788 +2479 2372 -27269599.07773 +2480 2372 -221502.6772963 +2481 2372 5939995.986973 +2482 2372 -16358892.70393 +2483 2372 -51790570.05088 +2484 2372 17031848.8311 +2485 2372 48076086.23075 +2486 2372 -90703859.27092 +2493 2372 -7125466.187114 +2494 2372 -7107677.550651 +2495 2372 -9517594.142065 +2496 2372 -48161586.95346 +2497 2372 -5277700.460655 +2498 2372 -56307063.72196 +2499 2372 -17021299.52369 +2500 2372 12385378.01131 +2501 2372 -35357225.93349 +2373 2373 434188482.4496 +2374 2373 42222222.21529 +2375 2373 14004257.85694 +2385 2373 -62903012.53369 +2386 2373 -42222222.21529 +2387 2373 10648140.71925 +2388 2373 -237961315.0134 +2389 2373 -42232516.70149 +2390 2373 -11962465.89917 +2391 2373 7955780.401528 +2392 2373 33788072.25843 +2393 2373 -8749455.084514 +2469 2373 1810230.00851 +2470 2373 14340738.95588 +2471 2373 8290807.874965 +2481 2373 -3359294.569133 +2482 2373 -11951850.06621 +2483 2373 -6689786.134111 +2484 2373 66125098.41489 +2485 2373 11944444.44837 +2486 2373 15207852.8515 +2496 2373 -19644494.8084 +2497 2373 -11944444.44837 +2498 2373 -7125466.187114 +2499 2373 -93269248.17781 +2500 2373 -11949381.52693 +2501 2373 -52618980.4305 +2502 2373 -17054654.84265 +2503 2373 9560492.637254 +2504 2373 -13448143.98712 +2374 2374 370839207.457 +2375 2374 -27831791.96622 +2385 2374 -42222222.21529 +2386 2374 -50235473.94641 +2387 2374 5333244.213044 +2388 2374 -42237663.94459 +2389 2374 -39482381.812 +2390 2374 -16655123.83823 +2391 2374 50682108.38765 +2392 2374 7955780.401527 +2393 2374 11010768.51444 +2469 2374 9560492.637254 +2470 2374 1810230.008509 +2471 2374 -4421798.559475 +2481 2374 -11949381.52693 +2482 2374 -45174403.34149 +2483 2374 -27804612.20634 +2484 2374 11944444.44837 +2485 2374 48201681.39244 +2486 2374 -5082672.97723 +2496 2374 -11944444.44836 +2497 2374 -16060922.31935 +2498 2374 -7107677.550651 +2499 2374 -11951850.06621 +2500 2374 -37114294.87206 +2501 2374 -16826932.79813 +2502 2374 14340738.95588 +2503 2374 -17054654.84265 +2504 2374 16137388.124 +2375 2375 400035038.4858 +2385 2375 10752307.38609 +2386 2375 5416577.546522 +2387 2375 -16208893.36898 +2388 2375 -10941569.92029 +2389 2375 -13223756.5556 +2390 2375 -11892250.19807 +2391 2375 -13124182.62677 +2392 2375 7340512.342961 +2393 2375 21215414.40408 +2469 2375 5527205.249977 +2470 2375 -6632697.839212 +2471 2375 4827280.022694 +2481 2375 -6688405.732252 +2482 2375 -29072115.16194 +2483 2375 -13594307.9147 +2484 2375 -3762599.703372 +2485 2375 -20258812.61341 +2486 2375 -38071476.41094 +2496 2375 -7125466.187114 +2497 2375 -7107677.550651 +2498 2375 -9517594.142065 +2499 2375 -52354091.66514 +2500 2375 -15346414.53585 +2501 2375 -72544459.24024 +2502 2375 -20172215.98068 +2503 2375 10758258.74933 +2504 2375 -45479079.58041 +2376 2376 701224018.4261 +2377 2376 1.215934753418e-05 +2378 2376 3981540.895231 +2379 2376 85654059.23587 +2380 2376 -7.361173629761e-06 +2381 2376 995385.2243004 +2394 2376 -163051082.2809 +2395 2376 4.857778549194e-06 +2396 2376 -2497714.891996 +2397 2376 -63439558.95712 +2398 2376 42222222.21529 +2399 2376 -11747692.6104 +2472 2376 -68569574.7737 +2473 2376 9.983777999878e-07 +2474 2376 46666190.80873 +2475 2376 -28443492.38882 +2476 2376 -11944444.44837 +2477 2376 16581478.26512 +2487 2376 103049709.0446 +2488 2376 8.106231689453e-06 +2489 2376 1759285.033469 +2490 2376 -19975421.90891 +2491 2376 -1.013278961182e-05 +2492 2376 439821.2585936 +2505 2376 -71083613.53293 +2506 2376 2.801418304443e-06 +2507 2376 -48425475.84218 +2508 2376 -29334356.73017 +2509 2376 11944444.44836 +2510 2376 -17021299.52369 +2377 2377 599883709.7778 +2378 2377 -47777064.79172 +2379 2377 -8.612871170044e-06 +2380 2377 -74790087.48109 +2381 2377 24294087.95135 +2394 2377 3.516674041748e-06 +2395 2377 22728141.58569 +2396 2377 -11944266.20381 +2397 2377 42222222.21529 +2398 2377 -50772020.36985 +2399 2377 6611021.990771 +2472 2377 -8.195638656616e-07 +2473 2377 -16013622.55363 +2474 2377 -5277700.460655 +2475 2377 -11944444.44837 +2476 2377 -24859919.89976 +2477 2377 11857600.23336 +2487 2377 7.987022399902e-06 +2488 2377 74381129.14638 +2489 2377 -21110801.83222 +2490 2377 -9.581446647644e-06 +2491 2377 -65364229.15794 +2492 2377 48591512.02092 +2505 2377 2.488493919373e-06 +2506 2377 -18527661.31289 +2507 2377 -5277700.460655 +2508 2377 11944444.44836 +2509 2377 -25750784.24113 +2510 2377 12385378.01131 +2378 2378 657670929.3001 +2379 2378 995385.2243 +2380 2378 23482976.84037 +2381 2378 60454947.39636 +2394 2378 -1483826.003273 +2395 2378 -11944266.20381 +2396 2378 36217937.62672 +2397 2378 -11643525.94355 +2398 2378 6527688.657292 +2399 2378 -17639683.8315 +2472 2378 46402301.92001 +2473 2378 -5277700.460655 +2474 2378 -49602960.36391 +2475 2378 16581478.26512 +2476 2378 11857600.23336 +2477 2378 -32981587.68983 +2487 2378 1759285.033468 +2488 2378 -21110801.83222 +2489 2378 -68142578.48796 +2490 2378 439821.258594 +2491 2378 48380400.90995 +2492 2378 -100781580.1802 +2505 2378 -48161586.95346 +2506 2378 -5277700.460655 +2507 2378 -56307063.72196 +2508 2378 -17021299.52369 +2509 2378 12385378.01131 +2510 2378 -35357225.93349 +2379 2379 701224018.4261 +2380 2379 1.215934753418e-05 +2381 2379 3981540.895231 +2382 2379 85654059.23587 +2383 2379 -7.361173629761e-06 +2384 2379 995385.2243004 +2394 2379 -62903012.53369 +2395 2379 -42222222.21529 +2396 2379 10648140.71925 +2397 2379 -163051082.2809 +2398 2379 4.857778549194e-06 +2399 2379 -2497714.891996 +2400 2379 -63439558.95712 +2401 2379 42222222.21529 +2402 2379 -11747692.6104 +2472 2379 -19278339.76952 +2473 2379 11944444.44837 +2474 2379 6685644.928532 +2475 2379 -68569574.7737 +2476 2379 9.983777999878e-07 +2477 2379 46666190.80873 +2478 2379 -28443492.38882 +2479 2379 -11944444.44837 +2480 2379 16581478.26512 +2487 2379 17734607.15466 +2488 2379 1.817941665649e-06 +2489 2379 439821.2585785 +2490 2379 103049709.0446 +2491 2379 8.106231689453e-06 +2492 2379 1759285.033469 +2493 2379 -19975421.90891 +2494 2379 -1.013278961182e-05 +2495 2379 439821.2585936 +2505 2379 -19644494.8084 +2506 2379 -11944444.44837 +2507 2379 -7125466.187114 +2508 2379 -71083613.53293 +2509 2379 2.801418304443e-06 +2510 2379 -48425475.84218 +2511 2379 -29334356.73017 +2512 2379 11944444.44836 +2513 2379 -17021299.52369 +2380 2380 599883709.7778 +2381 2380 -47777064.79172 +2382 2380 -8.612871170044e-06 +2383 2380 -74790087.48109 +2384 2380 24294087.95135 +2394 2380 -42222222.21529 +2395 2380 -50235473.94641 +2396 2380 5333244.213044 +2397 2380 3.516674041748e-06 +2398 2380 22728141.58569 +2399 2380 -11944266.20381 +2400 2380 42222222.21529 +2401 2380 -50772020.36985 +2402 2380 6611021.990771 +2472 2380 11944444.44837 +2473 2380 -15694767.28047 +2474 2380 -6579899.772699 +2475 2380 -8.195638656616e-07 +2476 2380 -16013622.55363 +2477 2380 -5277700.460655 +2478 2380 -11944444.44837 +2479 2380 -24859919.89976 +2480 2380 11857600.23336 +2487 2380 3.322958946228e-06 +2488 2380 -27654200.09436 +2489 2380 -27480710.1887 +2490 2380 7.987022399902e-06 +2491 2380 74381129.14638 +2492 2380 -21110801.83222 +2493 2380 -9.581446647644e-06 +2494 2380 -65364229.15794 +2495 2380 48591512.02092 +2505 2380 -11944444.44836 +2506 2380 -16060922.31935 +2507 2380 -7107677.550651 +2508 2380 2.488493919373e-06 +2509 2380 -18527661.31289 +2510 2380 -5277700.460655 +2511 2380 11944444.44836 +2512 2380 -25750784.24113 +2513 2380 12385378.01131 +2381 2381 657670929.3001 +2382 2381 995385.2243 +2383 2381 23482976.84037 +2384 2381 60454947.39636 +2394 2381 10752307.38609 +2395 2381 5416577.546522 +2396 2381 -16208893.36898 +2397 2381 -1483826.003273 +2398 2381 -11944266.20381 +2399 2381 36217937.62672 +2400 2381 -11643525.94355 +2401 2381 6527688.657292 +2402 2381 -17639683.8315 +2472 2381 6685644.928532 +2473 2381 -6579899.772699 +2474 2381 -8541180.705052 +2475 2381 46402301.92001 +2476 2381 -5277700.460655 +2477 2381 -49602960.36391 +2478 2381 16581478.26512 +2479 2381 11857600.23336 +2480 2381 -32981587.68983 +2487 2381 439821.2585788 +2488 2381 -27269599.07773 +2489 2381 -221502.6772963 +2490 2381 1759285.033468 +2491 2381 -21110801.83222 +2492 2381 -68142578.48796 +2493 2381 439821.258594 +2494 2381 48380400.90995 +2495 2381 -100781580.1802 +2505 2381 -7125466.187114 +2506 2381 -7107677.550651 +2507 2381 -9517594.142065 +2508 2381 -48161586.95346 +2509 2381 -5277700.460655 +2510 2381 -56307063.72196 +2511 2381 -17021299.52369 +2512 2381 12385378.01131 +2513 2381 -35357225.93349 +2382 2382 701224018.4261 +2383 2382 1.215934753418e-05 +2384 2382 3981540.895231 +2385 2382 85654059.23587 +2386 2382 -7.361173629761e-06 +2387 2382 995385.2243004 +2397 2382 -62903012.53369 +2398 2382 -42222222.21529 +2399 2382 10648140.71925 +2400 2382 -163051082.2809 +2401 2382 4.857778549194e-06 +2402 2382 -2497714.891996 +2403 2382 -63439558.95712 +2404 2382 42222222.21529 +2405 2382 -11747692.6104 +2475 2382 -19278339.76952 +2476 2382 11944444.44837 +2477 2382 6685644.928532 +2478 2382 -68569574.7737 +2479 2382 9.983777999878e-07 +2480 2382 46666190.80873 +2481 2382 -28443492.38882 +2482 2382 -11944444.44837 +2483 2382 16581478.26512 +2490 2382 17734607.15466 +2491 2382 1.817941665649e-06 +2492 2382 439821.2585785 +2493 2382 103049709.0446 +2494 2382 8.106231689453e-06 +2495 2382 1759285.033469 +2496 2382 -19975421.90891 +2497 2382 -1.013278961182e-05 +2498 2382 439821.2585936 +2508 2382 -19644494.8084 +2509 2382 -11944444.44837 +2510 2382 -7125466.187114 +2511 2382 -71083613.53293 +2512 2382 2.801418304443e-06 +2513 2382 -48425475.84218 +2514 2382 -29334356.73017 +2515 2382 11944444.44836 +2516 2382 -17021299.52369 +2383 2383 599883709.7778 +2384 2383 -47777064.79172 +2385 2383 -8.612871170044e-06 +2386 2383 -74790087.48109 +2387 2383 24294087.95135 +2397 2383 -42222222.21529 +2398 2383 -50235473.94641 +2399 2383 5333244.213044 +2400 2383 3.516674041748e-06 +2401 2383 22728141.58569 +2402 2383 -11944266.20381 +2403 2383 42222222.21529 +2404 2383 -50772020.36985 +2405 2383 6611021.990771 +2475 2383 11944444.44837 +2476 2383 -15694767.28047 +2477 2383 -6579899.772699 +2478 2383 -8.195638656616e-07 +2479 2383 -16013622.55363 +2480 2383 -5277700.460655 +2481 2383 -11944444.44837 +2482 2383 -24859919.89976 +2483 2383 11857600.23336 +2490 2383 3.322958946228e-06 +2491 2383 -27654200.09436 +2492 2383 -27480710.1887 +2493 2383 7.987022399902e-06 +2494 2383 74381129.14638 +2495 2383 -21110801.83222 +2496 2383 -9.581446647644e-06 +2497 2383 -65364229.15794 +2498 2383 48591512.02092 +2508 2383 -11944444.44836 +2509 2383 -16060922.31935 +2510 2383 -7107677.550651 +2511 2383 2.488493919373e-06 +2512 2383 -18527661.31289 +2513 2383 -5277700.460655 +2514 2383 11944444.44836 +2515 2383 -25750784.24113 +2516 2383 12385378.01131 +2384 2384 657670929.3001 +2385 2384 995385.2243 +2386 2384 23482976.84037 +2387 2384 60454947.39636 +2397 2384 10752307.38609 +2398 2384 5416577.546522 +2399 2384 -16208893.36898 +2400 2384 -1483826.003273 +2401 2384 -11944266.20381 +2402 2384 36217937.62672 +2403 2384 -11643525.94355 +2404 2384 6527688.657292 +2405 2384 -17639683.8315 +2475 2384 6685644.928532 +2476 2384 -6579899.772699 +2477 2384 -8541180.705052 +2478 2384 46402301.92001 +2479 2384 -5277700.460655 +2480 2384 -49602960.36391 +2481 2384 16581478.26512 +2482 2384 11857600.23336 +2483 2384 -32981587.68983 +2490 2384 439821.2585788 +2491 2384 -27269599.07773 +2492 2384 -221502.6772963 +2493 2384 1759285.033468 +2494 2384 -21110801.83222 +2495 2384 -68142578.48796 +2496 2384 439821.258594 +2497 2384 48380400.90995 +2498 2384 -100781580.1802 +2508 2384 -7125466.187114 +2509 2384 -7107677.550651 +2510 2384 -9517594.142065 +2511 2384 -48161586.95346 +2512 2384 -5277700.460655 +2513 2384 -56307063.72196 +2514 2384 -17021299.52369 +2515 2384 12385378.01131 +2516 2384 -35357225.93349 +2385 2385 701224018.4261 +2386 2385 1.215934753418e-05 +2387 2385 3981540.895231 +2388 2385 85654059.23587 +2389 2385 -7.361173629761e-06 +2390 2385 995385.2243004 +2400 2385 -62903012.53369 +2401 2385 -42222222.21529 +2402 2385 10648140.71925 +2403 2385 -163051082.2809 +2404 2385 4.857778549194e-06 +2405 2385 -2497714.891996 +2406 2385 -63439558.95712 +2407 2385 42222222.21529 +2408 2385 -11747692.6104 +2478 2385 -19278339.76952 +2479 2385 11944444.44837 +2480 2385 6685644.928532 +2481 2385 -68569574.7737 +2482 2385 9.983777999878e-07 +2483 2385 46666190.80873 +2484 2385 -28443492.38882 +2485 2385 -11944444.44837 +2486 2385 16581478.26512 +2493 2385 17734607.15466 +2494 2385 1.817941665649e-06 +2495 2385 439821.2585785 +2496 2385 103049709.0446 +2497 2385 8.106231689453e-06 +2498 2385 1759285.033469 +2499 2385 -19975421.90891 +2500 2385 -1.013278961182e-05 +2501 2385 439821.2585936 +2511 2385 -19644494.8084 +2512 2385 -11944444.44837 +2513 2385 -7125466.187114 +2514 2385 -71083613.53293 +2515 2385 2.801418304443e-06 +2516 2385 -48425475.84218 +2517 2385 -29334356.73017 +2518 2385 11944444.44836 +2519 2385 -17021299.52369 +2386 2386 599883709.7778 +2387 2386 -47777064.79172 +2388 2386 -8.612871170044e-06 +2389 2386 -74790087.48109 +2390 2386 24294087.95135 +2400 2386 -42222222.21529 +2401 2386 -50235473.94641 +2402 2386 5333244.213044 +2403 2386 3.516674041748e-06 +2404 2386 22728141.58569 +2405 2386 -11944266.20381 +2406 2386 42222222.21529 +2407 2386 -50772020.36985 +2408 2386 6611021.990771 +2478 2386 11944444.44837 +2479 2386 -15694767.28047 +2480 2386 -6579899.772699 +2481 2386 -8.195638656616e-07 +2482 2386 -16013622.55363 +2483 2386 -5277700.460655 +2484 2386 -11944444.44837 +2485 2386 -24859919.89976 +2486 2386 11857600.23336 +2493 2386 3.322958946228e-06 +2494 2386 -27654200.09436 +2495 2386 -27480710.1887 +2496 2386 7.987022399902e-06 +2497 2386 74381129.14638 +2498 2386 -21110801.83222 +2499 2386 -9.581446647644e-06 +2500 2386 -65364229.15794 +2501 2386 48591512.02092 +2511 2386 -11944444.44836 +2512 2386 -16060922.31935 +2513 2386 -7107677.550651 +2514 2386 2.488493919373e-06 +2515 2386 -18527661.31289 +2516 2386 -5277700.460655 +2517 2386 11944444.44836 +2518 2386 -25750784.24113 +2519 2386 12385378.01131 +2387 2387 657670929.3001 +2388 2387 995385.2243 +2389 2387 23482976.84037 +2390 2387 60454947.39636 +2400 2387 10752307.38609 +2401 2387 5416577.546522 +2402 2387 -16208893.36898 +2403 2387 -1483826.003273 +2404 2387 -11944266.20381 +2405 2387 36217937.62672 +2406 2387 -11643525.94355 +2407 2387 6527688.657292 +2408 2387 -17639683.8315 +2478 2387 6685644.928532 +2479 2387 -6579899.772699 +2480 2387 -8541180.705052 +2481 2387 46402301.92001 +2482 2387 -5277700.460655 +2483 2387 -49602960.36391 +2484 2387 16581478.26512 +2485 2387 11857600.23336 +2486 2387 -32981587.68983 +2493 2387 439821.2585788 +2494 2387 -27269599.07773 +2495 2387 -221502.6772963 +2496 2387 1759285.033468 +2497 2387 -21110801.83222 +2498 2387 -68142578.48796 +2499 2387 439821.258594 +2500 2387 48380400.90995 +2501 2387 -100781580.1802 +2511 2387 -7125466.187114 +2512 2387 -7107677.550651 +2513 2387 -9517594.142065 +2514 2387 -48161586.95346 +2515 2387 -5277700.460655 +2516 2387 -56307063.72196 +2517 2387 -17021299.52369 +2518 2387 12385378.01131 +2519 2387 -35357225.93349 +2388 2388 753320607.0872 +2389 2388 42247958.4308 +2390 2388 13425270.63193 +2391 2388 10687201.53391 +2392 2388 -42232516.7015 +2393 2388 11747147.69675 +2403 2388 -62903012.53369 +2404 2388 -42222222.21529 +2405 2388 10648140.71925 +2406 2388 -163051082.2809 +2407 2388 4.857778549194e-06 +2408 2388 -2497714.891996 +2409 2388 -63439558.95712 +2410 2388 42222222.21529 +2411 2388 -11747692.6104 +2481 2388 -19278339.76952 +2482 2388 11944444.44837 +2483 2388 6685644.928532 +2484 2388 -83208406.42019 +2485 2388 -11951850.06621 +2486 2388 42498171.10922 +2496 2388 17734607.15466 +2497 2388 1.817941665649e-06 +2498 2388 439821.2585785 +2499 2388 125282026.2887 +2500 2388 11956787.14478 +2501 2388 5935098.98454 +2502 2388 -32275376.32772 +2503 2388 -11949381.52693 +2504 2388 17028332.3953 +2514 2388 -19644494.8084 +2515 2388 -11944444.44837 +2516 2388 -7125466.187114 +2517 2388 -71083613.53293 +2518 2388 2.801418304443e-06 +2519 2388 -48425475.84218 +2520 2388 -29334356.73017 +2521 2388 11944444.44836 +2522 2388 -17021299.52369 +2389 2389 639301177.7705 +2390 2389 -37037050.15144 +2391 2389 -42237663.9446 +2392 2389 -137109995.2621 +2393 2389 20238494.1063 +2403 2389 -42222222.21529 +2404 2389 -50235473.94641 +2405 2389 5333244.213044 +2406 2389 3.516674041748e-06 +2407 2389 22728141.58569 +2408 2389 -11944266.20381 +2409 2389 42222222.21529 +2410 2389 -50772020.36985 +2411 2389 6611021.990771 +2481 2389 11944444.44837 +2482 2389 -15694767.28047 +2483 2389 -6579899.772699 +2484 2389 -11949381.52693 +2485 2389 -27053453.11441 +2486 2389 3626698.329752 +2496 2389 3.322958946228e-06 +2497 2389 -27654200.09436 +2498 2389 -27480710.1887 +2499 2389 11956787.14477 +2500 2389 93024319.31714 +2501 2389 -16362810.24847 +2502 2389 -11951850.06621 +2503 2389 -74090485.10009 +2504 2389 46808583.40323 +2514 2389 -11944444.44836 +2515 2389 -16060922.31935 +2516 2389 -7107677.550651 +2517 2389 2.488493919373e-06 +2518 2389 -18527661.31289 +2519 2389 -5277700.460655 +2520 2389 11944444.44836 +2521 2389 -25750784.24113 +2522 2389 12385378.01131 +2390 2390 644924144.2682 +2391 2390 11642708.57308 +2392 2390 22769593.39294 +2393 2390 12096388.9117 +2403 2390 10752307.38609 +2404 2390 5416577.546522 +2405 2390 -16208893.36898 +2406 2390 -1483826.003273 +2407 2390 -11944266.20381 +2408 2390 36217937.62672 +2409 2390 -11643525.94355 +2410 2390 6527688.657292 +2411 2390 -17639683.8315 +2481 2390 6685644.928532 +2482 2390 -6579899.772699 +2483 2390 -8541180.705052 +2484 2390 42233282.34386 +2485 2390 2150097.608279 +2486 2390 -45715547.88649 +2496 2390 439821.2585788 +2497 2390 -27269599.07773 +2498 2390 -221502.6772963 +2499 2390 5939995.986973 +2500 2390 -16358892.70393 +2501 2390 -51790570.05088 +2502 2390 17031848.8311 +2503 2390 48076086.23075 +2504 2390 -90703859.27092 +2514 2390 -7125466.187114 +2515 2390 -7107677.550651 +2516 2390 -9517594.142065 +2517 2390 -48161586.95346 +2518 2390 -5277700.460655 +2519 2390 -56307063.72196 +2520 2390 -17021299.52369 +2521 2390 12385378.01131 +2522 2390 -35357225.93349 +2391 2391 420142253.8812 +2392 2391 -26639487.106 +2393 2391 -3084379.120139 +2406 2391 -62903012.53369 +2407 2391 -42222222.21529 +2408 2391 10648140.71925 +2409 2391 -80812305.28421 +2410 2391 26543754.57092 +2411 2391 -1611502.173259 +2412 2391 -184325621.8369 +2413 2391 33873510.30732 +2414 2391 -775000.5169595 +2484 2391 1810230.00851 +2485 2391 14340738.95588 +2486 2391 8290807.874965 +2499 2391 -3359294.569133 +2500 2391 -11951850.06621 +2501 2391 -6689786.134111 +2502 2391 64793825.45948 +2503 2391 -6243722.738426 +2504 2391 3816806.707693 +2517 2391 -19644494.8084 +2518 2391 -11944444.44837 +2519 2391 -7125466.187114 +2520 2391 -40605721.95413 +2521 2391 6202186.078868 +2522 2391 -30034628.76677 +2523 2391 -39948167.4897 +2524 2391 9597092.218255 +2525 2391 -2839054.908176 +2392 2392 697040023.4809 +2393 2392 -38830126.79588 +2406 2392 -42222222.21529 +2407 2392 -50235473.94641 +2408 2392 5333244.213044 +2409 2392 26495888.30338 +2410 2392 86950457.68356 +2411 2392 -8406841.802013 +2412 2392 50810265.46097 +2413 2392 -493856496.1955 +2414 2392 14658602.99375 +2484 2392 9560492.637254 +2485 2392 1810230.008509 +2486 2392 -4421798.559475 +2499 2392 -11949381.52693 +2500 2392 -45174403.34149 +2501 2392 -27804612.20634 +2502 2392 -6243722.738427 +2503 2392 116187740.7912 +2504 2392 -12029230.86321 +2517 2392 -11944444.44836 +2518 2392 -16060922.31935 +2519 2392 -7107677.550651 +2520 2392 6181417.749088 +2521 2392 7479412.380062 +2522 2392 1270358.056493 +2523 2392 14395638.32738 +2524 2392 -101195680.8723 +2525 2392 22521951.86899 +2393 2393 422801090.7216 +2406 2393 10752307.38609 +2407 2393 5416577.546522 +2408 2393 -16208893.36898 +2409 2393 -3959442.819955 +2410 2393 -7686435.131428 +2411 2393 37418239.63636 +2412 2393 -1162500.775438 +2413 2393 14148198.27724 +2414 2393 -182004117.2064 +2484 2393 5527205.249977 +2485 2393 -6632697.839212 +2486 2393 4827280.022694 +2499 2393 -6688405.732252 +2500 2393 -29072115.16194 +2501 2393 -13594307.9147 +2502 2393 -7974098.476532 +2503 2393 -21433087.28757 +2504 2393 -5368828.40544 +2517 2393 -7125466.187114 +2518 2393 -7107677.550651 +2519 2393 -9517594.142065 +2520 2393 -31352634.6121 +2521 2393 1500021.740722 +2522 2393 -29608611.91299 +2523 2393 -4258582.362264 +2524 2393 21389042.21735 +2525 2393 -45280933.25655 +2394 2394 701224018.4261 +2395 2394 1.215934753418e-05 +2396 2394 3981540.895231 +2397 2394 85654059.23587 +2398 2394 -7.361173629761e-06 +2399 2394 995385.2243004 +2415 2394 -163051082.2809 +2416 2394 4.857778549194e-06 +2417 2394 -2497714.891996 +2418 2394 -63439558.95712 +2419 2394 42222222.21529 +2420 2394 -11747692.6104 +2487 2394 -68569574.7737 +2488 2394 9.983777999878e-07 +2489 2394 46666190.80873 +2490 2394 -28443492.38882 +2491 2394 -11944444.44837 +2492 2394 16581478.26512 +2505 2394 103049709.0446 +2506 2394 8.106231689453e-06 +2507 2394 1759285.033469 +2508 2394 -19975421.90891 +2509 2394 -1.013278961182e-05 +2510 2394 439821.2585936 +2526 2394 -71083613.53293 +2527 2394 2.801418304443e-06 +2528 2394 -48425475.84218 +2529 2394 -29334356.73017 +2530 2394 11944444.44836 +2531 2394 -17021299.52369 +2395 2395 599883709.7778 +2396 2395 -47777064.79172 +2397 2395 -8.612871170044e-06 +2398 2395 -74790087.48109 +2399 2395 24294087.95135 +2415 2395 3.516674041748e-06 +2416 2395 22728141.58569 +2417 2395 -11944266.20381 +2418 2395 42222222.21529 +2419 2395 -50772020.36985 +2420 2395 6611021.990771 +2487 2395 -8.195638656616e-07 +2488 2395 -16013622.55363 +2489 2395 -5277700.460655 +2490 2395 -11944444.44837 +2491 2395 -24859919.89976 +2492 2395 11857600.23336 +2505 2395 7.987022399902e-06 +2506 2395 74381129.14638 +2507 2395 -21110801.83222 +2508 2395 -9.581446647644e-06 +2509 2395 -65364229.15794 +2510 2395 48591512.02092 +2526 2395 2.488493919373e-06 +2527 2395 -18527661.31289 +2528 2395 -5277700.460655 +2529 2395 11944444.44836 +2530 2395 -25750784.24113 +2531 2395 12385378.01131 +2396 2396 657670929.3001 +2397 2396 995385.2243 +2398 2396 23482976.84037 +2399 2396 60454947.39636 +2415 2396 -1483826.003273 +2416 2396 -11944266.20381 +2417 2396 36217937.62672 +2418 2396 -11643525.94355 +2419 2396 6527688.657292 +2420 2396 -17639683.8315 +2487 2396 46402301.92001 +2488 2396 -5277700.460655 +2489 2396 -49602960.36391 +2490 2396 16581478.26512 +2491 2396 11857600.23336 +2492 2396 -32981587.68983 +2505 2396 1759285.033468 +2506 2396 -21110801.83222 +2507 2396 -68142578.48796 +2508 2396 439821.258594 +2509 2396 48380400.90995 +2510 2396 -100781580.1802 +2526 2396 -48161586.95346 +2527 2396 -5277700.460655 +2528 2396 -56307063.72196 +2529 2396 -17021299.52369 +2530 2396 12385378.01131 +2531 2396 -35357225.93349 +2397 2397 701224018.4261 +2398 2397 1.215934753418e-05 +2399 2397 3981540.895231 +2400 2397 85654059.23587 +2401 2397 -7.361173629761e-06 +2402 2397 995385.2243004 +2415 2397 -62903012.53369 +2416 2397 -42222222.21529 +2417 2397 10648140.71925 +2418 2397 -163051082.2809 +2419 2397 4.857778549194e-06 +2420 2397 -2497714.891996 +2421 2397 -63439558.95712 +2422 2397 42222222.21529 +2423 2397 -11747692.6104 +2487 2397 -19278339.76952 +2488 2397 11944444.44837 +2489 2397 6685644.928532 +2490 2397 -68569574.7737 +2491 2397 9.983777999878e-07 +2492 2397 46666190.80873 +2493 2397 -28443492.38882 +2494 2397 -11944444.44837 +2495 2397 16581478.26512 +2505 2397 17734607.15466 +2506 2397 1.817941665649e-06 +2507 2397 439821.2585785 +2508 2397 103049709.0446 +2509 2397 8.106231689453e-06 +2510 2397 1759285.033469 +2511 2397 -19975421.90891 +2512 2397 -1.013278961182e-05 +2513 2397 439821.2585936 +2526 2397 -19644494.8084 +2527 2397 -11944444.44837 +2528 2397 -7125466.187114 +2529 2397 -71083613.53293 +2530 2397 2.801418304443e-06 +2531 2397 -48425475.84218 +2532 2397 -29334356.73017 +2533 2397 11944444.44836 +2534 2397 -17021299.52369 +2398 2398 599883709.7778 +2399 2398 -47777064.79172 +2400 2398 -8.612871170044e-06 +2401 2398 -74790087.48109 +2402 2398 24294087.95135 +2415 2398 -42222222.21529 +2416 2398 -50235473.94641 +2417 2398 5333244.213044 +2418 2398 3.516674041748e-06 +2419 2398 22728141.58569 +2420 2398 -11944266.20381 +2421 2398 42222222.21529 +2422 2398 -50772020.36985 +2423 2398 6611021.990771 +2487 2398 11944444.44837 +2488 2398 -15694767.28047 +2489 2398 -6579899.772699 +2490 2398 -8.195638656616e-07 +2491 2398 -16013622.55363 +2492 2398 -5277700.460655 +2493 2398 -11944444.44837 +2494 2398 -24859919.89976 +2495 2398 11857600.23336 +2505 2398 3.322958946228e-06 +2506 2398 -27654200.09436 +2507 2398 -27480710.1887 +2508 2398 7.987022399902e-06 +2509 2398 74381129.14638 +2510 2398 -21110801.83222 +2511 2398 -9.581446647644e-06 +2512 2398 -65364229.15794 +2513 2398 48591512.02092 +2526 2398 -11944444.44836 +2527 2398 -16060922.31935 +2528 2398 -7107677.550651 +2529 2398 2.488493919373e-06 +2530 2398 -18527661.31289 +2531 2398 -5277700.460655 +2532 2398 11944444.44836 +2533 2398 -25750784.24113 +2534 2398 12385378.01131 +2399 2399 657670929.3001 +2400 2399 995385.2243 +2401 2399 23482976.84037 +2402 2399 60454947.39636 +2415 2399 10752307.38609 +2416 2399 5416577.546522 +2417 2399 -16208893.36898 +2418 2399 -1483826.003273 +2419 2399 -11944266.20381 +2420 2399 36217937.62672 +2421 2399 -11643525.94355 +2422 2399 6527688.657292 +2423 2399 -17639683.8315 +2487 2399 6685644.928532 +2488 2399 -6579899.772699 +2489 2399 -8541180.705052 +2490 2399 46402301.92001 +2491 2399 -5277700.460655 +2492 2399 -49602960.36391 +2493 2399 16581478.26512 +2494 2399 11857600.23336 +2495 2399 -32981587.68983 +2505 2399 439821.2585788 +2506 2399 -27269599.07773 +2507 2399 -221502.6772963 +2508 2399 1759285.033468 +2509 2399 -21110801.83222 +2510 2399 -68142578.48796 +2511 2399 439821.258594 +2512 2399 48380400.90995 +2513 2399 -100781580.1802 +2526 2399 -7125466.187114 +2527 2399 -7107677.550651 +2528 2399 -9517594.142065 +2529 2399 -48161586.95346 +2530 2399 -5277700.460655 +2531 2399 -56307063.72196 +2532 2399 -17021299.52369 +2533 2399 12385378.01131 +2534 2399 -35357225.93349 +2400 2400 701224018.4261 +2401 2400 1.215934753418e-05 +2402 2400 3981540.895231 +2403 2400 85654059.23587 +2404 2400 -7.361173629761e-06 +2405 2400 995385.2243004 +2418 2400 -62903012.53369 +2419 2400 -42222222.21529 +2420 2400 10648140.71925 +2421 2400 -163051082.2809 +2422 2400 4.857778549194e-06 +2423 2400 -2497714.891996 +2424 2400 -63439558.95712 +2425 2400 42222222.21529 +2426 2400 -11747692.6104 +2490 2400 -19278339.76952 +2491 2400 11944444.44837 +2492 2400 6685644.928532 +2493 2400 -68569574.7737 +2494 2400 9.983777999878e-07 +2495 2400 46666190.80873 +2496 2400 -28443492.38882 +2497 2400 -11944444.44837 +2498 2400 16581478.26512 +2508 2400 17734607.15466 +2509 2400 1.817941665649e-06 +2510 2400 439821.2585785 +2511 2400 103049709.0446 +2512 2400 8.106231689453e-06 +2513 2400 1759285.033469 +2514 2400 -19975421.90891 +2515 2400 -1.013278961182e-05 +2516 2400 439821.2585936 +2529 2400 -19644494.8084 +2530 2400 -11944444.44837 +2531 2400 -7125466.187114 +2532 2400 -71083613.53293 +2533 2400 2.801418304443e-06 +2534 2400 -48425475.84218 +2535 2400 -29334356.73017 +2536 2400 11944444.44836 +2537 2400 -17021299.52369 +2401 2401 599883709.7778 +2402 2401 -47777064.79172 +2403 2401 -8.612871170044e-06 +2404 2401 -74790087.48109 +2405 2401 24294087.95135 +2418 2401 -42222222.21529 +2419 2401 -50235473.94641 +2420 2401 5333244.213044 +2421 2401 3.516674041748e-06 +2422 2401 22728141.58569 +2423 2401 -11944266.20381 +2424 2401 42222222.21529 +2425 2401 -50772020.36985 +2426 2401 6611021.990771 +2490 2401 11944444.44837 +2491 2401 -15694767.28047 +2492 2401 -6579899.772699 +2493 2401 -8.195638656616e-07 +2494 2401 -16013622.55363 +2495 2401 -5277700.460655 +2496 2401 -11944444.44837 +2497 2401 -24859919.89976 +2498 2401 11857600.23336 +2508 2401 3.322958946228e-06 +2509 2401 -27654200.09436 +2510 2401 -27480710.1887 +2511 2401 7.987022399902e-06 +2512 2401 74381129.14638 +2513 2401 -21110801.83222 +2514 2401 -9.581446647644e-06 +2515 2401 -65364229.15794 +2516 2401 48591512.02092 +2529 2401 -11944444.44836 +2530 2401 -16060922.31935 +2531 2401 -7107677.550651 +2532 2401 2.488493919373e-06 +2533 2401 -18527661.31289 +2534 2401 -5277700.460655 +2535 2401 11944444.44836 +2536 2401 -25750784.24113 +2537 2401 12385378.01131 +2402 2402 657670929.3001 +2403 2402 995385.2243 +2404 2402 23482976.84037 +2405 2402 60454947.39636 +2418 2402 10752307.38609 +2419 2402 5416577.546522 +2420 2402 -16208893.36898 +2421 2402 -1483826.003273 +2422 2402 -11944266.20381 +2423 2402 36217937.62672 +2424 2402 -11643525.94355 +2425 2402 6527688.657292 +2426 2402 -17639683.8315 +2490 2402 6685644.928532 +2491 2402 -6579899.772699 +2492 2402 -8541180.705052 +2493 2402 46402301.92001 +2494 2402 -5277700.460655 +2495 2402 -49602960.36391 +2496 2402 16581478.26512 +2497 2402 11857600.23336 +2498 2402 -32981587.68983 +2508 2402 439821.2585788 +2509 2402 -27269599.07773 +2510 2402 -221502.6772963 +2511 2402 1759285.033468 +2512 2402 -21110801.83222 +2513 2402 -68142578.48796 +2514 2402 439821.258594 +2515 2402 48380400.90995 +2516 2402 -100781580.1802 +2529 2402 -7125466.187114 +2530 2402 -7107677.550651 +2531 2402 -9517594.142065 +2532 2402 -48161586.95346 +2533 2402 -5277700.460655 +2534 2402 -56307063.72196 +2535 2402 -17021299.52369 +2536 2402 12385378.01131 +2537 2402 -35357225.93349 +2403 2403 701224018.4261 +2404 2403 1.215934753418e-05 +2405 2403 3981540.895231 +2406 2403 85654059.23587 +2407 2403 -7.361173629761e-06 +2408 2403 995385.2243004 +2421 2403 -62903012.53369 +2422 2403 -42222222.21529 +2423 2403 10648140.71925 +2424 2403 -163051082.2809 +2425 2403 4.857778549194e-06 +2426 2403 -2497714.891996 +2427 2403 -63439558.95712 +2428 2403 42222222.21529 +2429 2403 -11747692.6104 +2493 2403 -19278339.76952 +2494 2403 11944444.44837 +2495 2403 6685644.928532 +2496 2403 -68569574.7737 +2497 2403 9.983777999878e-07 +2498 2403 46666190.80873 +2499 2403 -28443492.38882 +2500 2403 -11944444.44837 +2501 2403 16581478.26512 +2511 2403 17734607.15466 +2512 2403 1.817941665649e-06 +2513 2403 439821.2585785 +2514 2403 103049709.0446 +2515 2403 8.106231689453e-06 +2516 2403 1759285.033469 +2517 2403 -19975421.90891 +2518 2403 -1.013278961182e-05 +2519 2403 439821.2585936 +2532 2403 -19644494.8084 +2533 2403 -11944444.44837 +2534 2403 -7125466.187114 +2535 2403 -71083613.53293 +2536 2403 2.801418304443e-06 +2537 2403 -48425475.84218 +2538 2403 -29334356.73017 +2539 2403 11944444.44836 +2540 2403 -17021299.52369 +2404 2404 599883709.7778 +2405 2404 -47777064.79172 +2406 2404 -8.612871170044e-06 +2407 2404 -74790087.48109 +2408 2404 24294087.95135 +2421 2404 -42222222.21529 +2422 2404 -50235473.94641 +2423 2404 5333244.213044 +2424 2404 3.516674041748e-06 +2425 2404 22728141.58569 +2426 2404 -11944266.20381 +2427 2404 42222222.21529 +2428 2404 -50772020.36985 +2429 2404 6611021.990771 +2493 2404 11944444.44837 +2494 2404 -15694767.28047 +2495 2404 -6579899.772699 +2496 2404 -8.195638656616e-07 +2497 2404 -16013622.55363 +2498 2404 -5277700.460655 +2499 2404 -11944444.44837 +2500 2404 -24859919.89976 +2501 2404 11857600.23336 +2511 2404 3.322958946228e-06 +2512 2404 -27654200.09436 +2513 2404 -27480710.1887 +2514 2404 7.987022399902e-06 +2515 2404 74381129.14638 +2516 2404 -21110801.83222 +2517 2404 -9.581446647644e-06 +2518 2404 -65364229.15794 +2519 2404 48591512.02092 +2532 2404 -11944444.44836 +2533 2404 -16060922.31935 +2534 2404 -7107677.550651 +2535 2404 2.488493919373e-06 +2536 2404 -18527661.31289 +2537 2404 -5277700.460655 +2538 2404 11944444.44836 +2539 2404 -25750784.24113 +2540 2404 12385378.01131 +2405 2405 657670929.3001 +2406 2405 995385.2243 +2407 2405 23482976.84037 +2408 2405 60454947.39636 +2421 2405 10752307.38609 +2422 2405 5416577.546522 +2423 2405 -16208893.36898 +2424 2405 -1483826.003273 +2425 2405 -11944266.20381 +2426 2405 36217937.62672 +2427 2405 -11643525.94355 +2428 2405 6527688.657292 +2429 2405 -17639683.8315 +2493 2405 6685644.928532 +2494 2405 -6579899.772699 +2495 2405 -8541180.705052 +2496 2405 46402301.92001 +2497 2405 -5277700.460655 +2498 2405 -49602960.36391 +2499 2405 16581478.26512 +2500 2405 11857600.23336 +2501 2405 -32981587.68983 +2511 2405 439821.2585788 +2512 2405 -27269599.07773 +2513 2405 -221502.6772963 +2514 2405 1759285.033468 +2515 2405 -21110801.83222 +2516 2405 -68142578.48796 +2517 2405 439821.258594 +2518 2405 48380400.90995 +2519 2405 -100781580.1802 +2532 2405 -7125466.187114 +2533 2405 -7107677.550651 +2534 2405 -9517594.142065 +2535 2405 -48161586.95346 +2536 2405 -5277700.460655 +2537 2405 -56307063.72196 +2538 2405 -17021299.52369 +2539 2405 12385378.01131 +2540 2405 -35357225.93349 +2406 2406 701224018.4261 +2407 2406 1.215934753418e-05 +2408 2406 3981540.895231 +2409 2406 85654059.23587 +2410 2406 -7.361173629761e-06 +2411 2406 995385.2243004 +2424 2406 -62903012.53369 +2425 2406 -42222222.21529 +2426 2406 10648140.71925 +2427 2406 -163051082.2809 +2428 2406 4.857778549194e-06 +2429 2406 -2497714.891996 +2430 2406 -63439558.95712 +2431 2406 42222222.21529 +2432 2406 -11747692.6104 +2496 2406 -19278339.76952 +2497 2406 11944444.44837 +2498 2406 6685644.928532 +2499 2406 -68569574.7737 +2500 2406 9.983777999878e-07 +2501 2406 46666190.80873 +2502 2406 -28443492.38882 +2503 2406 -11944444.44837 +2504 2406 16581478.26512 +2514 2406 17734607.15466 +2515 2406 1.817941665649e-06 +2516 2406 439821.2585785 +2517 2406 103049709.0446 +2518 2406 8.106231689453e-06 +2519 2406 1759285.033469 +2520 2406 -19975421.90891 +2521 2406 -1.013278961182e-05 +2522 2406 439821.2585936 +2535 2406 -19644494.8084 +2536 2406 -11944444.44837 +2537 2406 -7125466.187114 +2538 2406 -71083613.53293 +2539 2406 2.801418304443e-06 +2540 2406 -48425475.84218 +2541 2406 -29334356.73017 +2542 2406 11944444.44836 +2543 2406 -17021299.52369 +2407 2407 599883709.7778 +2408 2407 -47777064.79172 +2409 2407 -8.612871170044e-06 +2410 2407 -74790087.48109 +2411 2407 24294087.95135 +2424 2407 -42222222.21529 +2425 2407 -50235473.94641 +2426 2407 5333244.213044 +2427 2407 3.516674041748e-06 +2428 2407 22728141.58569 +2429 2407 -11944266.20381 +2430 2407 42222222.21529 +2431 2407 -50772020.36985 +2432 2407 6611021.990771 +2496 2407 11944444.44837 +2497 2407 -15694767.28047 +2498 2407 -6579899.772699 +2499 2407 -8.195638656616e-07 +2500 2407 -16013622.55363 +2501 2407 -5277700.460655 +2502 2407 -11944444.44837 +2503 2407 -24859919.89976 +2504 2407 11857600.23336 +2514 2407 3.322958946228e-06 +2515 2407 -27654200.09436 +2516 2407 -27480710.1887 +2517 2407 7.987022399902e-06 +2518 2407 74381129.14638 +2519 2407 -21110801.83222 +2520 2407 -9.581446647644e-06 +2521 2407 -65364229.15794 +2522 2407 48591512.02092 +2535 2407 -11944444.44836 +2536 2407 -16060922.31935 +2537 2407 -7107677.550651 +2538 2407 2.488493919373e-06 +2539 2407 -18527661.31289 +2540 2407 -5277700.460655 +2541 2407 11944444.44836 +2542 2407 -25750784.24113 +2543 2407 12385378.01131 +2408 2408 657670929.3001 +2409 2408 995385.2243 +2410 2408 23482976.84037 +2411 2408 60454947.39636 +2424 2408 10752307.38609 +2425 2408 5416577.546522 +2426 2408 -16208893.36898 +2427 2408 -1483826.003273 +2428 2408 -11944266.20381 +2429 2408 36217937.62672 +2430 2408 -11643525.94355 +2431 2408 6527688.657292 +2432 2408 -17639683.8315 +2496 2408 6685644.928532 +2497 2408 -6579899.772699 +2498 2408 -8541180.705052 +2499 2408 46402301.92001 +2500 2408 -5277700.460655 +2501 2408 -49602960.36391 +2502 2408 16581478.26512 +2503 2408 11857600.23336 +2504 2408 -32981587.68983 +2514 2408 439821.2585788 +2515 2408 -27269599.07773 +2516 2408 -221502.6772963 +2517 2408 1759285.033468 +2518 2408 -21110801.83222 +2519 2408 -68142578.48796 +2520 2408 439821.258594 +2521 2408 48380400.90995 +2522 2408 -100781580.1802 +2535 2408 -7125466.187114 +2536 2408 -7107677.550651 +2537 2408 -9517594.142065 +2538 2408 -48161586.95346 +2539 2408 -5277700.460655 +2540 2408 -56307063.72196 +2541 2408 -17021299.52369 +2542 2408 12385378.01131 +2543 2408 -35357225.93349 +2409 2409 577704024.4718 +2410 2409 14809283.69956 +2411 2409 3094500.267067 +2412 2409 -105944549.6383 +2413 2409 -83930476.14658 +2414 2409 3150475.677939 +2427 2409 -62903012.53369 +2428 2409 -42222222.21529 +2429 2409 10648140.71925 +2430 2409 -109457388.1912 +2431 2409 27063170.45869 +2432 2409 -1117736.826287 +2433 2409 -51031357.23621 +2434 2409 15562133.68496 +2435 2409 -1196914.486729 +2499 2409 -19278339.76952 +2500 2409 11944444.44837 +2501 2409 6685644.928532 +2502 2409 -37684606.37654 +2503 2409 6181417.749088 +2504 2409 27601891.30902 +2517 2409 17734607.15466 +2518 2409 1.817941665649e-06 +2519 2409 439821.2585785 +2520 2409 100394552.2472 +2521 2409 3668856.730091 +2522 2409 1425389.136151 +2523 2409 -41726819.0919 +2524 2409 -22707301.49767 +2525 2409 13201184.57836 +2538 2409 -19644494.8084 +2539 2409 -11944444.44837 +2540 2409 -7125466.187114 +2541 2409 -53972480.23384 +2542 2409 7388118.740806 +2543 2409 -38810328.02163 +2544 2409 -20564060.7256 +2545 2409 5468908.277692 +2546 2409 -3388482.255547 +2410 2410 695909943.6538 +2411 2410 -32875937.83832 +2412 2410 -83978342.41412 +2413 2410 -281568044.39 +2414 2410 6945565.151227 +2427 2410 -42222222.21529 +2428 2410 -50235473.94641 +2429 2410 5333244.213044 +2430 2410 27063170.45869 +2431 2410 17779793.06391 +2432 2410 -5838198.671549 +2433 2410 15562133.68496 +2434 2410 -153504656.347 +2435 2410 4087799.174187 +2499 2410 11944444.44837 +2500 2410 -15694767.28047 +2501 2410 -6579899.772699 +2502 2410 6202186.078866 +2503 2410 10400527.95768 +2504 2410 -8330322.108782 +2517 2410 3.322958946228e-06 +2518 2410 -27654200.09436 +2519 2410 -27480710.1887 +2520 2410 3668856.730088 +2521 2410 127661417.7545 +2522 2410 -14307167.86992 +2523 2410 -22728069.82745 +2524 2410 -90171091.60634 +2525 2410 40873449.4208 +2538 2410 -11944444.44836 +2539 2410 -16060922.31935 +2540 2410 -7107677.550651 +2541 2410 7388118.740805 +2542 2410 -16117915.41583 +2543 2410 4565046.721977 +2544 2410 5468908.277692 +2545 2410 -47104690.59973 +2546 2410 18391008.29112 +2411 2411 523190943.6465 +2412 2411 3044920.380945 +2413 2411 6593211.907962 +2414 2411 -75050515.58456 +2427 2411 10752307.38609 +2428 2411 5416577.546522 +2429 2411 -16208893.36898 +2430 2411 -3583014.60366 +2431 2411 -5754865.33823 +2432 2411 33100739.46664 +2433 2411 -988581.1530332 +2434 2411 4087799.174186 +2435 2411 -39212679.04904 +2499 2411 6685644.928532 +2500 2411 -6579899.772699 +2501 2411 -8541180.705052 +2502 2411 28919897.15434 +2503 2411 -8527088.580187 +2504 2411 -21818970.37266 +2517 2411 439821.2585788 +2518 2411 -27269599.07773 +2519 2411 -221502.6772963 +2520 2411 1435183.211197 +2521 2411 -14299331.64391 +2522 2411 -21850651.32956 +2523 2411 13207656.47459 +2524 2411 40863132.02543 +2525 2411 -57780083.98817 +2538 2411 -7125466.187114 +2539 2411 -7107677.550651 +2540 2411 -9517594.142065 +2541 2411 -40129772.46506 +2542 2411 4565046.723341 +2543 2411 -50119670.15696 +2544 2411 -3388482.255547 +2545 2411 18391008.29112 +2546 2411 -29461390.90537 +2412 2412 566952139.5686 +2413 2412 18738912.23931 +2414 2412 963971.4140308 +2430 2412 -64315355.09417 +2431 2412 -38220064.14765 +2432 2412 1370583.552858 +2433 2412 13585633.50306 +2434 2412 42269697.51059 +2435 2412 -1370603.487074 +2436 2412 60660323.14971 +2437 2412 -23180190.42236 +2438 2412 -44826.00110793 +2439 2412 -8118600.276353 +2440 2412 33559721.77326 +2441 2412 -357100.6393677 +2502 2412 -36868564.84551 +2503 2412 14395638.32738 +2504 2412 2665799.7449 +2520 2412 -36372847.98441 +2521 2412 -22728069.82745 +2522 2412 -10527281.18303 +2523 2412 50575003.33921 +2524 2412 4932035.917719 +2525 2412 9249992.645587 +2541 2412 -23862844.19582 +2542 2412 -10997981.99709 +2543 2412 -11215149.57021 +2544 2412 -42543957.73714 +2545 2412 11150657.82588 +2546 2412 -46865917.20518 +2547 2412 -16084851.82021 +2548 2412 -6374221.316074 +2549 2412 13044420.75426 +2550 2412 -17415384.18459 +2551 2412 9621941.06963 +2552 2412 -11469087.40889 +2413 2413 971271979.9936 +2414 2413 -16529874.51391 +2430 2413 -38220064.14765 +2431 2413 -25081526.54831 +2432 2413 -273324.5491264 +2433 2413 42269697.51059 +2434 2413 161486942.6946 +2435 2413 -2422759.372724 +2436 2413 -6291301.536248 +2437 2413 -20728017.24709 +2438 2413 245188.837259 +2439 2413 33559721.77326 +2440 2413 -33030868.93149 +2441 2413 298208.6664563 +2502 2413 9597092.218255 +2503 2413 -98116078.22816 +2504 2413 -11165823.77878 +2520 2413 -22707301.49767 +2521 2413 -84817120.49885 +2522 2413 -35087282.09087 +2523 2413 4932035.917718 +2524 2413 137487222.3673 +2525 2413 -5791200.564033 +2541 2413 -10997981.99709 +2542 2413 -13468644.62109 +2543 2413 -9555687.152061 +2544 2413 11150657.82588 +2545 2413 -432390.2942711 +2546 2413 6161256.991149 +2547 2413 -1596443.536727 +2548 2413 -39150114.66293 +2549 2413 33441094.01512 +2550 2413 9621941.06963 +2551 2413 -24076321.49047 +2552 2413 16796952.25561 +2414 2414 693246339.4045 +2430 2414 1474750.219706 +2431 2414 -189991.215648 +2432 2414 -7392450.986293 +2433 2414 -953936.8204754 +2434 2414 -2339426.039404 +2435 2414 173827673.356 +2436 2414 59340.66554439 +2437 2414 245188.8372588 +2438 2414 108763262.0371 +2439 2414 -252933.9725203 +2440 2414 298208.6664563 +2441 2414 31260393.98142 +2502 2414 1777199.829934 +2503 2414 -11879639.33914 +2504 2414 -37068659.53871 +2520 2414 -10523959.04784 +2521 2414 -35102025.71722 +2522 2414 -43502827.70152 +2523 2414 -9298340.6847 +2524 2414 -7662986.54061 +2525 2414 -71378006.24346 +2541 2414 -11215149.57021 +2542 2414 -9555687.152061 +2543 2414 -16816432.49076 +2544 2414 -46865917.20544 +2545 2414 6161256.992512 +2546 2414 -69024564.22655 +2547 2414 4919420.753295 +2548 2414 33441094.01512 +2549 2414 -58433218.49776 +2550 2414 -11469087.40889 +2551 2414 16796952.25561 +2552 2414 -30638817.77715 +2415 2415 349558986.0455 +2416 2415 9.059906005859e-06 +2417 2415 -543951.774193 +2418 2415 42572716.26631 +2419 2415 8444444.443056 +2420 2415 -2002307.387935 +2505 2415 -68569574.7737 +2506 2415 9.983777999878e-07 +2507 2415 46666190.80873 +2508 2415 -28443492.38882 +2509 2415 -11944444.44837 +2510 2415 16581478.26512 +2526 2415 51507364.21225 +2527 2415 2.384185791016e-06 +2528 2415 -9262857.481274 +2529 2415 -9987710.954453 +2530 2415 2388888.889668 +2531 2415 -3140367.149584 +2416 2416 298888831.7214 +2417 2416 -23888532.39585 +2418 2416 -8444444.44306 +2419 2416 -37649357.09217 +2420 2416 12027599.53125 +2505 2416 -8.195638656616e-07 +2506 2416 -16013622.55363 +2507 2416 -5277700.460655 +2508 2416 -11944444.44837 +2509 2416 -24859919.89976 +2510 2416 11857600.23336 +2526 2416 1.788139343262e-06 +2527 2416 37173074.26313 +2528 2416 -10555400.91611 +2529 2416 -2388888.889678 +2530 2416 -32682114.57897 +2531 2416 24242978.23266 +2417 2417 326027402.8699 +2418 2417 2476859.277995 +2419 2417 11860932.86461 +2420 2417 29549304.7605 +2505 2417 46402301.92001 +2506 2417 -5277700.460655 +2507 2417 -49602960.36391 +2508 2417 16581478.26512 +2509 2417 11857600.23336 +2510 2417 -32981587.68983 +2526 2417 9702698.071164 +2527 2417 -10555400.91611 +2528 2417 -34117930.07082 +2529 2417 3580188.408178 +2530 2417 24242978.23277 +2531 2417 -50390790.09008 +2418 2418 349558986.0455 +2419 2418 9.059906005859e-06 +2420 2418 -543951.774193 +2421 2418 42572716.26631 +2422 2418 8444444.443056 +2423 2418 -2002307.387935 +2505 2418 -19278339.76952 +2506 2418 11944444.44837 +2507 2418 6685644.928532 +2508 2418 -68569574.7737 +2509 2418 9.983777999878e-07 +2510 2418 46666190.80873 +2511 2418 -28443492.38882 +2512 2418 -11944444.44837 +2513 2418 16581478.26512 +2526 2418 8867303.577332 +2527 2418 -2388888.889672 +2528 2418 -1161200.482275 +2529 2418 51507364.21225 +2530 2418 2.384185791016e-06 +2531 2418 -9262857.481274 +2532 2418 -9987710.954453 +2533 2418 2388888.889668 +2534 2418 -3140367.149584 +2419 2419 298888831.7214 +2420 2419 -23888532.39585 +2421 2419 -8444444.44306 +2422 2419 -37649357.09217 +2423 2419 12027599.53125 +2505 2419 11944444.44837 +2506 2419 -15694767.28047 +2507 2419 -6579899.772699 +2508 2419 -8.195638656616e-07 +2509 2419 -16013622.55363 +2510 2419 -5277700.460655 +2511 2419 -11944444.44837 +2512 2419 -24859919.89976 +2513 2419 11857600.23336 +2526 2419 2388888.889675 +2527 2419 -13827100.04718 +2528 2419 -13687577.31655 +2529 2419 1.788139343262e-06 +2530 2419 37173074.26313 +2531 2419 -10555400.91611 +2532 2419 -2388888.889678 +2533 2419 -32682114.57897 +2534 2419 24242978.23266 +2420 2420 326027402.8699 +2421 2420 2476859.277995 +2422 2420 11860932.86461 +2423 2420 29549304.7605 +2505 2420 6685644.928532 +2506 2420 -6579899.772699 +2507 2420 -8541180.705052 +2508 2420 46402301.92001 +2509 2420 -5277700.460655 +2510 2420 -49602960.36391 +2511 2420 16581478.26512 +2512 2420 11857600.23336 +2513 2420 -32981587.68983 +2526 2420 1601021.740854 +2527 2420 -13687577.31666 +2528 2420 -110751.3386485 +2529 2420 9702698.071164 +2530 2420 -10555400.91611 +2531 2420 -34117930.07082 +2532 2420 3580188.408178 +2533 2420 24242978.23277 +2534 2420 -50390790.09008 +2421 2421 349558986.0455 +2422 2421 9.059906005859e-06 +2423 2421 -543951.774193 +2424 2421 42572716.26631 +2425 2421 8444444.443056 +2426 2421 -2002307.387935 +2508 2421 -19278339.76952 +2509 2421 11944444.44837 +2510 2421 6685644.928532 +2511 2421 -68569574.7737 +2512 2421 9.983777999878e-07 +2513 2421 46666190.80873 +2514 2421 -28443492.38882 +2515 2421 -11944444.44837 +2516 2421 16581478.26512 +2529 2421 8867303.577332 +2530 2421 -2388888.889672 +2531 2421 -1161200.482275 +2532 2421 51507364.21225 +2533 2421 2.384185791016e-06 +2534 2421 -9262857.481274 +2535 2421 -9987710.954453 +2536 2421 2388888.889668 +2537 2421 -3140367.149584 +2422 2422 298888831.7214 +2423 2422 -23888532.39585 +2424 2422 -8444444.44306 +2425 2422 -37649357.09217 +2426 2422 12027599.53125 +2508 2422 11944444.44837 +2509 2422 -15694767.28047 +2510 2422 -6579899.772699 +2511 2422 -8.195638656616e-07 +2512 2422 -16013622.55363 +2513 2422 -5277700.460655 +2514 2422 -11944444.44837 +2515 2422 -24859919.89976 +2516 2422 11857600.23336 +2529 2422 2388888.889675 +2530 2422 -13827100.04718 +2531 2422 -13687577.31655 +2532 2422 1.788139343262e-06 +2533 2422 37173074.26313 +2534 2422 -10555400.91611 +2535 2422 -2388888.889678 +2536 2422 -32682114.57897 +2537 2422 24242978.23266 +2423 2423 326027402.8699 +2424 2423 2476859.277995 +2425 2423 11860932.86461 +2426 2423 29549304.7605 +2508 2423 6685644.928532 +2509 2423 -6579899.772699 +2510 2423 -8541180.705052 +2511 2423 46402301.92001 +2512 2423 -5277700.460655 +2513 2423 -49602960.36391 +2514 2423 16581478.26512 +2515 2423 11857600.23336 +2516 2423 -32981587.68983 +2529 2423 1601021.740854 +2530 2423 -13687577.31666 +2531 2423 -110751.3386485 +2532 2423 9702698.071164 +2533 2423 -10555400.91611 +2534 2423 -34117930.07082 +2535 2423 3580188.408178 +2536 2423 24242978.23277 +2537 2423 -50390790.09008 +2424 2424 349558986.0455 +2425 2424 9.059906005859e-06 +2426 2424 -543951.774193 +2427 2424 42572716.26631 +2428 2424 8444444.443056 +2429 2424 -2002307.387935 +2511 2424 -19278339.76952 +2512 2424 11944444.44837 +2513 2424 6685644.928532 +2514 2424 -68569574.7737 +2515 2424 9.983777999878e-07 +2516 2424 46666190.80873 +2517 2424 -28443492.38882 +2518 2424 -11944444.44837 +2519 2424 16581478.26512 +2532 2424 8867303.577332 +2533 2424 -2388888.889672 +2534 2424 -1161200.482275 +2535 2424 51507364.21225 +2536 2424 2.384185791016e-06 +2537 2424 -9262857.481274 +2538 2424 -9987710.954453 +2539 2424 2388888.889668 +2540 2424 -3140367.149584 +2425 2425 298888831.7214 +2426 2425 -23888532.39585 +2427 2425 -8444444.44306 +2428 2425 -37649357.09217 +2429 2425 12027599.53125 +2511 2425 11944444.44837 +2512 2425 -15694767.28047 +2513 2425 -6579899.772699 +2514 2425 -8.195638656616e-07 +2515 2425 -16013622.55363 +2516 2425 -5277700.460655 +2517 2425 -11944444.44837 +2518 2425 -24859919.89976 +2519 2425 11857600.23336 +2532 2425 2388888.889675 +2533 2425 -13827100.04718 +2534 2425 -13687577.31655 +2535 2425 1.788139343262e-06 +2536 2425 37173074.26313 +2537 2425 -10555400.91611 +2538 2425 -2388888.889678 +2539 2425 -32682114.57897 +2540 2425 24242978.23266 +2426 2426 326027402.8699 +2427 2426 2476859.277995 +2428 2426 11860932.86461 +2429 2426 29549304.7605 +2511 2426 6685644.928532 +2512 2426 -6579899.772699 +2513 2426 -8541180.705052 +2514 2426 46402301.92001 +2515 2426 -5277700.460655 +2516 2426 -49602960.36391 +2517 2426 16581478.26512 +2518 2426 11857600.23336 +2519 2426 -32981587.68983 +2532 2426 1601021.740854 +2533 2426 -13687577.31666 +2534 2426 -110751.3386485 +2535 2426 9702698.071164 +2536 2426 -10555400.91611 +2537 2426 -34117930.07082 +2538 2426 3580188.408178 +2539 2426 24242978.23277 +2540 2426 -50390790.09008 +2427 2427 349558986.0455 +2428 2427 9.059906005859e-06 +2429 2427 -543951.774193 +2430 2427 42572716.26631 +2431 2427 8444444.443056 +2432 2427 -2002307.387935 +2514 2427 -19278339.76952 +2515 2427 11944444.44837 +2516 2427 6685644.928532 +2517 2427 -68569574.7737 +2518 2427 9.983777999878e-07 +2519 2427 46666190.80873 +2520 2427 -28443492.38882 +2521 2427 -11944444.44837 +2522 2427 16581478.26512 +2535 2427 8867303.577332 +2536 2427 -2388888.889672 +2537 2427 -1161200.482275 +2538 2427 51507364.21225 +2539 2427 2.384185791016e-06 +2540 2427 -9262857.481274 +2541 2427 -9987710.954453 +2542 2427 2388888.889668 +2543 2427 -3140367.149584 +2428 2428 298888831.7214 +2429 2428 -23888532.39585 +2430 2428 -8444444.44306 +2431 2428 -37649357.09217 +2432 2428 12027599.53125 +2514 2428 11944444.44837 +2515 2428 -15694767.28047 +2516 2428 -6579899.772699 +2517 2428 -8.195638656616e-07 +2518 2428 -16013622.55363 +2519 2428 -5277700.460655 +2520 2428 -11944444.44837 +2521 2428 -24859919.89976 +2522 2428 11857600.23336 +2535 2428 2388888.889675 +2536 2428 -13827100.04718 +2537 2428 -13687577.31655 +2538 2428 1.788139343262e-06 +2539 2428 37173074.26313 +2540 2428 -10555400.91611 +2541 2428 -2388888.889678 +2542 2428 -32682114.57897 +2543 2428 24242978.23266 +2429 2429 326027402.8699 +2430 2429 2476859.277995 +2431 2429 11860932.86461 +2432 2429 29549304.7605 +2514 2429 6685644.928532 +2515 2429 -6579899.772699 +2516 2429 -8541180.705052 +2517 2429 46402301.92001 +2518 2429 -5277700.460655 +2519 2429 -49602960.36391 +2520 2429 16581478.26512 +2521 2429 11857600.23336 +2522 2429 -32981587.68983 +2535 2429 1601021.740854 +2536 2429 -13687577.31666 +2537 2429 -110751.3386485 +2538 2429 9702698.071164 +2539 2429 -10555400.91611 +2540 2429 -34117930.07082 +2541 2429 3580188.408178 +2542 2429 24242978.23277 +2543 2429 -50390790.09008 +2430 2430 338387026.2375 +2431 2430 4002989.89494 +2432 2430 8095074.275888 +2433 2430 -7811370.442606 +2434 2430 -26623873.97821 +2435 2430 735412.3287755 +2517 2430 -19278339.76952 +2518 2430 11944444.44837 +2519 2430 6685644.928532 +2520 2430 -50741082.54401 +2521 2430 7388118.740808 +2522 2430 36735505.29832 +2523 2430 -25119857.43912 +2524 2430 -10997981.99708 +2525 2430 12490405.99313 +2538 2430 8867303.577332 +2539 2430 -2388888.889672 +2540 2430 -1161200.482275 +2541 2430 49274982.41504 +2542 2430 946667.844034 +2543 2430 -5436326.485142 +2544 2430 -17697231.04585 +2545 2430 -6892360.146446 +2546 2430 7053192.97001 +2431 2431 314292766.6033 +2432 2431 -15162162.93871 +2433 2431 -43512762.86433 +2434 2431 -82633585.83811 +2435 2431 2718397.970699 +2517 2431 11944444.44837 +2518 2431 -15694767.28047 +2519 2431 -6579899.772699 +2520 2431 7388118.740806 +2521 2431 -12886517.72598 +2522 2431 -9803008.83127 +2523 2431 -10997981.99708 +2524 2431 -14725657.86439 +2525 2431 9409590.631944 +2538 2431 2388888.889675 +2539 2431 -13827100.04718 +2540 2431 -13687577.31655 +2541 2431 946667.8440332 +2542 2431 41753994.66988 +2543 2431 -6670249.398894 +2544 2431 -11670137.92579 +2545 2431 -39314176.55796 +2546 2431 27331144.68747 +2432 2432 308833935.2489 +2433 2432 1735412.328609 +2434 2432 2635064.637379 +2435 2432 16044341.52492 +2517 2432 6685644.928532 +2518 2432 -6579899.772699 +2519 2432 -8541180.705052 +2520 2432 38054949.74529 +2521 2432 -9803008.829802 +2522 2432 -41502609.65066 +2523 2432 12490405.99313 +2524 2432 9409590.631944 +2525 2432 -20168467.80624 +2538 2432 1601021.740854 +2539 2432 -13687577.31666 +2540 2432 -110751.3386485 +2541 2432 13528673.51174 +2542 2432 -6670249.398894 +2543 2432 -36116433.14522 +2544 2432 12190137.41431 +2545 2432 27331144.6861 +2546 2432 -39411823.5038 +2433 2433 373838541.6067 +2434 2433 48035465.6548 +2435 2433 -2482772.715053 +2436 2433 -83825989.15247 +2437 2433 -50884722.65732 +2438 2433 441510.4716972 +2439 2433 9076442.48639 +2440 2433 -11469811.3287 +2441 2433 -196076.5565655 +2520 2433 -17884984.01273 +2521 2433 5468908.277692 +2522 2433 2357351.079676 +2523 2433 -41674209.10964 +2524 2433 11150657.82588 +2525 2433 45875749.446 +2541 2433 -13208817.04483 +2542 2433 -11670137.9258 +2543 2433 -10510695.91586 +2544 2433 21472381.83449 +2545 2433 12233311.84361 +2546 2433 -9870324.609983 +2547 2433 -38009199.00617 +2548 2433 -14266947.8271 +2549 2433 20505912.60161 +2550 2433 -22191462.63102 +2551 2433 -2915792.194291 +2552 2433 6759229.62113 +2434 2434 462970610.9071 +2435 2434 -5629292.266559 +2436 2434 -50884722.65732 +2437 2434 -61421139.76003 +2438 2434 298208.6664561 +2439 2434 -28358700.21481 +2440 2434 -73066270.8917 +2441 2434 947645.8279781 +2520 2434 5468908.277692 +2521 2434 -44425613.88687 +2522 2434 -14942325.05316 +2523 2434 11150657.82588 +2524 2434 437358.3332224 +2525 2434 -8206798.562099 +2541 2434 -6892360.14645 +2542 2434 -34825762.55696 +2543 2434 -24967466.415 +2544 2434 12233311.84362 +2545 2434 44502443.09594 +2546 2434 -2427077.199588 +2547 2434 -14266947.8271 +2548 2434 -31799002.04856 +2549 2434 16796952.25561 +2550 2434 -7693569.973637 +2551 2434 -45385712.90668 +2552 2434 33746714.97422 +2435 2435 468748108.3725 +2436 2435 441510.4716972 +2437 2435 298208.666456 +2438 2435 2870123.152872 +2439 2435 206701.2211432 +2440 2435 947645.8279782 +2441 2435 54607501.34905 +2520 2435 2357351.079676 +2521 2435 -14942325.05316 +2522 2435 -22317186.33773 +2523 2435 45875749.44626 +2524 2435 -8206798.560631 +2525 2435 -66705234.55323 +2541 2435 -6165418.138362 +2542 2435 -24967466.41647 +2543 2435 -27442719.50107 +2544 2435 8678008.720305 +2545 2435 -2427077.199588 +2546 2435 -90144206.98683 +2547 2435 20505912.60161 +2548 2435 16796952.25561 +2549 2435 -38361498.33524 +2550 2435 11424229.62437 +2551 2435 33746714.97422 +2552 2435 -52352594.20565 +2436 2436 242431625.3468 +2437 2436 56957968.1946 +2438 2436 -256099.9245906 +2439 2436 -20745205.30394 +2440 2436 218055.9989742 +2441 2436 -244751.2126476 +2523 2436 -15532526.23864 +2524 2436 -1596443.536728 +2525 2436 -4915301.465078 +2544 2436 -37456873.4246 +2545 2436 -14266947.8271 +2546 2436 -20119087.41174 +2547 2436 1886789.833553 +2548 2436 15929776.87477 +2549 2436 8012986.650805 +2550 2436 -35343901.79311 +2551 2436 -66385.51093899 +2552 2436 -31728597.77399 +2437 2437 220903299.0939 +2438 2437 -245188.8372518 +2439 2437 17106944.88509 +2440 2437 59766611.95339 +2441 2437 -298208.6664508 +2523 2437 -6374221.316075 +2524 2437 -38597789.08137 +2525 2437 -33225572.6406 +2544 2437 -14266947.8271 +2545 2437 -31246676.46699 +2546 2437 -16536381.08867 +2547 2437 15929776.87477 +2548 2437 -4162530.666617 +2549 2437 6558905.978311 +2550 2437 4711392.268407 +2551 2437 -12439515.40783 +2552 2437 3203047.750956 +2438 2438 322120822.9046 +2439 2438 -140584.5459949 +2440 2438 -298208.666451 +2441 2438 95634469.34586 +2523 2438 -13040301.46591 +2524 2438 -33225572.6406 +2525 2438 -56960350.28025 +2544 2438 -20119087.41174 +2545 2438 -16536381.08867 +2546 2438 -36888630.11772 +2547 2438 -8237013.346527 +2548 2438 -6774427.352831 +2549 2438 -86181752.3906 +2550 2438 -31728597.77583 +2551 2438 -3463618.9179 +2552 2438 -50493298.20557 +2439 2439 181839442.0347 +2440 2439 -22307966.44354 +2441 2439 -1035404.925042 +2523 2439 -16863058.60302 +2524 2439 9621941.069631 +2525 2439 11196190.37633 +2544 2439 -20534485.88739 +2545 2439 -7693569.973641 +2546 2439 -11068548.15372 +2547 2439 -35343901.79311 +2548 2439 4711392.268411 +2549 2439 31561679.99333 +2550 2439 1883306.743505 +2551 2439 -6639763.364401 +2552 2439 -4754877.771325 +2440 2440 208382606.8106 +2441 2440 -947645.8279632 +2523 2440 9621941.069631 +2524 2440 -23523995.9089 +2525 2440 -16536381.08867 +2544 2440 -2915792.194294 +2545 2440 -43728736.16307 +2546 2440 -32919951.68149 +2547 2440 -66385.51093579 +2548 2440 -12439515.40783 +2549 2440 3203047.750956 +2550 2440 -6639763.3644 +2551 2440 8834107.939769 +2552 2440 6253285.019201 +2441 2441 250636512.4991 +2523 2441 11196190.37633 +2524 2441 -16536381.08867 +2525 2441 -29165949.55963 +2544 2441 -6667437.039326 +2545 2441 -32919951.68149 +2546 2441 -47933989.55597 +2547 2441 31561679.99162 +2548 2441 -3463618.9179 +2549 2441 -50493298.20557 +2550 2441 4311233.338298 +2551 2441 -7080048.311942 +2552 2441 -61361801.45222 +2442 2442 490945057.4196 +2443 2442 47777777.76993 +2444 2442 20252298.79464 +2445 2442 -273863949.3497 +2446 2442 -47797526.08415 +2447 2442 -20243754.66502 +2448 2442 3432365.726058 +2449 2442 38241970.53018 +2450 2442 -16369382.67653 +2553 2442 66125098.41489 +2554 2442 11944444.44837 +2555 2442 15207852.8515 +2556 2442 -93269248.17781 +2557 2442 -11949381.52693 +2558 2442 -52618980.4305 +2559 2442 -17054654.84265 +2560 2442 9560492.637254 +2561 2442 -13448143.98712 +2443 2443 419251389.3651 +2444 2443 -52793537.14673 +2445 2443 -47807400.24127 +2446 2443 -49244136.23734 +2447 2443 -29248441.87035 +2448 2443 57362955.79526 +2449 2443 3432365.726057 +2450 2443 18376374.28788 +2553 2443 11944444.44837 +2554 2443 48201681.39244 +2555 2443 -5082672.97723 +2556 2443 -11951850.06621 +2557 2443 -37114294.87206 +2558 2443 -16826932.79813 +2559 2443 14340738.95588 +2560 2443 -17054654.84265 +2561 2443 16137388.124 +2444 2444 451566531.4722 +2445 2444 -20239482.6002 +2446 2444 -23545205.99654 +2447 2444 -25609721.67724 +2448 2444 -24554074.0148 +2449 2444 12250916.19192 +2450 2444 9152975.269492 +2553 2444 -3762599.703372 +2554 2444 -20258812.61341 +2555 2444 -38071476.41094 +2556 2444 -52354091.66514 +2557 2444 -15346414.53585 +2558 2444 -72544459.24024 +2559 2444 -20172215.98068 +2560 2444 10758258.74933 +2561 2444 -45479079.58041 +2445 2445 840410334.4004 +2446 2445 47827148.55553 +2447 2445 23749508.53569 +2448 2445 8066610.522678 +2449 2445 -47797526.08417 +2450 2445 20547636.30415 +2451 2445 -188931397.8084 +2452 2445 6.824731826782e-06 +2453 2445 -3518570.065188 +2454 2445 -74622903.1185 +2455 2445 47777777.76992 +2456 2445 -20539364.73579 +2553 2445 -83208406.42019 +2554 2445 -11951850.06621 +2555 2445 42498171.10922 +2556 2445 125282026.2887 +2557 2445 11956787.14478 +2558 2445 5935098.98454 +2559 2445 -32275376.32772 +2560 2445 -11949381.52693 +2561 2445 17028332.3953 +2562 2445 -71083613.53293 +2563 2445 2.801418304443e-06 +2564 2445 -48425475.84218 +2565 2445 -29334356.73017 +2566 2445 11944444.44836 +2567 2445 -17021299.52369 +2446 2446 711379506.5777 +2447 2446 -65443950.97306 +2448 2446 -47807400.24129 +2449 2446 -159193824.4844 +2450 2446 35050823.25634 +2451 2446 6.347894668579e-06 +2452 2446 21292410.96829 +2453 2446 -21110801.83222 +2454 2446 47777777.76992 +2455 2446 -60288613.16939 +2456 2446 11505400.91601 +2553 2446 -11949381.52693 +2554 2446 -27053453.11441 +2555 2446 3626698.329752 +2556 2446 11956787.14477 +2557 2446 93024319.31714 +2558 2446 -16362810.24847 +2559 2446 -11951850.06621 +2560 2446 -74090485.10009 +2561 2446 46808583.40323 +2562 2446 2.488493919373e-06 +2563 2446 -18527661.31289 +2564 2446 -5277700.460655 +2565 2446 11944444.44836 +2566 2446 -25750784.24113 +2567 2446 12385378.01131 +2447 2447 697590331.8784 +2448 2447 20815660.97705 +2449 2447 40965061.2198 +2450 2447 2966205.148247 +2451 2447 -3518570.065188 +2452 2447 -21110801.83222 +2453 2447 29179895.04537 +2454 2447 -20803253.6245 +2455 2447 11716512.02698 +2456 2447 -27523507.01255 +2553 2447 42233282.34386 +2554 2447 2150097.608279 +2555 2447 -45715547.88649 +2556 2447 5939995.986973 +2557 2447 -16358892.70393 +2558 2447 -51790570.05088 +2559 2447 17031848.8311 +2560 2447 48076086.23075 +2561 2447 -90703859.27092 +2562 2447 -48161586.95346 +2563 2447 -5277700.460655 +2564 2447 -56307063.72196 +2565 2447 -17021299.52369 +2566 2447 12385378.01131 +2567 2447 -35357225.93349 +2448 2448 490945057.4196 +2449 2448 47777777.76993 +2450 2448 20252298.79464 +2451 2448 -73573484.51406 +2452 2448 -47777777.76993 +2453 2448 19043968.59104 +2454 2448 -273863949.3497 +2455 2448 -47797526.08415 +2456 2448 -20243754.66502 +2457 2448 3432365.726058 +2458 2448 38241970.53018 +2459 2448 -16369382.67653 +2553 2448 1810230.00851 +2554 2448 14340738.95588 +2555 2448 8290807.874965 +2556 2448 -3359294.569133 +2557 2448 -11951850.06621 +2558 2448 -6689786.134111 +2559 2448 66125098.41489 +2560 2448 11944444.44837 +2561 2448 15207852.8515 +2562 2448 -19644494.8084 +2563 2448 -11944444.44837 +2564 2448 -7125466.187114 +2565 2448 -93269248.17781 +2566 2448 -11949381.52693 +2567 2448 -52618980.4305 +2568 2448 -17054654.84265 +2569 2448 9560492.637254 +2570 2448 -13448143.98712 +2449 2449 419251389.3651 +2450 2449 -52793537.14673 +2451 2449 -47777777.76993 +2452 2449 -59239194.56492 +2453 2449 9605400.916215 +2454 2449 -47807400.24127 +2455 2449 -49244136.23734 +2456 2449 -29248441.87035 +2457 2449 57362955.79526 +2458 2449 3432365.726057 +2459 2449 18376374.28788 +2553 2449 9560492.637254 +2554 2449 1810230.008509 +2555 2449 -4421798.559475 +2556 2449 -11949381.52693 +2557 2449 -45174403.34149 +2558 2449 -27804612.20634 +2559 2449 11944444.44837 +2560 2449 48201681.39244 +2561 2449 -5082672.97723 +2562 2449 -11944444.44836 +2563 2449 -16060922.31935 +2564 2449 -7107677.550651 +2565 2449 -11951850.06621 +2566 2449 -37114294.87206 +2567 2449 -16826932.79813 +2568 2449 14340738.95588 +2569 2449 -17054654.84265 +2570 2449 16137388.124 +2450 2450 451566531.4722 +2451 2450 18780079.70233 +2452 2450 9394289.805242 +2453 2450 -24725057.40063 +2454 2450 -20239482.6002 +2455 2450 -23545205.99654 +2456 2450 -25609721.67724 +2457 2450 -24554074.0148 +2458 2450 12250916.19192 +2459 2450 9152975.269492 +2553 2450 5527205.249977 +2554 2450 -6632697.839212 +2555 2450 4827280.022694 +2556 2450 -6688405.732252 +2557 2450 -29072115.16194 +2558 2450 -13594307.9147 +2559 2450 -3762599.703372 +2560 2450 -20258812.61341 +2561 2450 -38071476.41094 +2562 2450 -7125466.187114 +2563 2450 -7107677.550651 +2564 2450 -9517594.142065 +2565 2450 -52354091.66514 +2566 2450 -15346414.53585 +2567 2450 -72544459.24024 +2568 2450 -20172215.98068 +2569 2450 10758258.74933 +2570 2450 -45479079.58041 +2451 2451 773558827.9862 +2452 2451 2.658367156982e-05 +2453 2451 7037140.130311 +2454 2451 85893349.16099 +2455 2451 -1.427531242371e-05 +2456 2451 1759285.033452 +2460 2451 -188931397.8084 +2461 2451 6.824731826782e-06 +2462 2451 -3518570.065188 +2463 2451 -74622903.1185 +2464 2451 47777777.76992 +2465 2451 -20539364.73579 +2556 2451 -68569574.7737 +2557 2451 9.983777999878e-07 +2558 2451 46666190.80873 +2559 2451 -28443492.38882 +2560 2451 -11944444.44837 +2561 2451 16581478.26512 +2562 2451 103049709.0446 +2563 2451 8.106231689453e-06 +2564 2451 1759285.033469 +2565 2451 -19975421.90891 +2566 2451 -1.013278961182e-05 +2567 2451 439821.2585936 +2571 2451 -71083613.53293 +2572 2451 2.801418304443e-06 +2573 2451 -48425475.84218 +2574 2451 -29334356.73017 +2575 2451 11944444.44836 +2576 2451 -17021299.52369 +2452 2452 658884508.4497 +2453 2452 -84443207.28729 +2454 2452 -1.427531242371e-05 +2455 2452 -95661879.74567 +2456 2452 42221603.64364 +2460 2452 6.347894668579e-06 +2461 2452 21292410.96829 +2462 2452 -21110801.83222 +2463 2452 47777777.76992 +2464 2452 -60288613.16939 +2465 2452 11505400.91601 +2556 2452 -8.195638656616e-07 +2557 2452 -16013622.55363 +2558 2452 -5277700.460655 +2559 2452 -11944444.44837 +2560 2452 -24859919.89976 +2561 2452 11857600.23336 +2562 2452 7.987022399902e-06 +2563 2452 74381129.14638 +2564 2452 -21110801.83222 +2565 2452 -9.581446647644e-06 +2566 2452 -65364229.15794 +2567 2452 48591512.02092 +2571 2452 2.488493919373e-06 +2572 2452 -18527661.31289 +2573 2452 -5277700.460655 +2574 2452 11944444.44836 +2575 2452 -25750784.24113 +2576 2452 12385378.01131 +2453 2453 691056331.5443 +2454 2453 1759285.033452 +2455 2453 42221603.64364 +2456 2453 38993777.49737 +2460 2453 -3518570.065188 +2461 2453 -21110801.83222 +2462 2453 29179895.04537 +2463 2453 -20803253.6245 +2464 2453 11716512.02698 +2465 2453 -27523507.01255 +2556 2453 46402301.92001 +2557 2453 -5277700.460655 +2558 2453 -49602960.36391 +2559 2453 16581478.26512 +2560 2453 11857600.23336 +2561 2453 -32981587.68983 +2562 2453 1759285.033468 +2563 2453 -21110801.83222 +2564 2453 -68142578.48796 +2565 2453 439821.258594 +2566 2453 48380400.90995 +2567 2453 -100781580.1802 +2571 2453 -48161586.95346 +2572 2453 -5277700.460655 +2573 2453 -56307063.72196 +2574 2453 -17021299.52369 +2575 2453 12385378.01131 +2576 2453 -35357225.93349 +2454 2454 840410334.4004 +2455 2454 47827148.55553 +2456 2454 23749508.53569 +2457 2454 8066610.522678 +2458 2454 -47797526.08417 +2459 2454 20547636.30415 +2460 2454 -73573484.51406 +2461 2454 -47777777.76993 +2462 2454 19043968.59104 +2463 2454 -188931397.8084 +2464 2454 6.824731826782e-06 +2465 2454 -3518570.065188 +2466 2454 -74622903.1185 +2467 2454 47777777.76992 +2468 2454 -20539364.73579 +2556 2454 -19278339.76952 +2557 2454 11944444.44837 +2558 2454 6685644.928532 +2559 2454 -83208406.42019 +2560 2454 -11951850.06621 +2561 2454 42498171.10922 +2562 2454 17734607.15466 +2563 2454 1.817941665649e-06 +2564 2454 439821.2585785 +2565 2454 125282026.2887 +2566 2454 11956787.14478 +2567 2454 5935098.98454 +2568 2454 -32275376.32772 +2569 2454 -11949381.52693 +2570 2454 17028332.3953 +2571 2454 -19644494.8084 +2572 2454 -11944444.44837 +2573 2454 -7125466.187114 +2574 2454 -71083613.53293 +2575 2454 2.801418304443e-06 +2576 2454 -48425475.84218 +2577 2454 -29334356.73017 +2578 2454 11944444.44836 +2579 2454 -17021299.52369 +2455 2455 711379506.5777 +2456 2455 -65443950.97306 +2457 2455 -47807400.24129 +2458 2455 -159193824.4844 +2459 2455 35050823.25634 +2460 2455 -47777777.76993 +2461 2455 -59239194.56492 +2462 2455 9605400.916215 +2463 2455 6.347894668579e-06 +2464 2455 21292410.96829 +2465 2455 -21110801.83222 +2466 2455 47777777.76992 +2467 2455 -60288613.16939 +2468 2455 11505400.91601 +2556 2455 11944444.44837 +2557 2455 -15694767.28047 +2558 2455 -6579899.772699 +2559 2455 -11949381.52693 +2560 2455 -27053453.11441 +2561 2455 3626698.329752 +2562 2455 3.322958946228e-06 +2563 2455 -27654200.09436 +2564 2455 -27480710.1887 +2565 2455 11956787.14477 +2566 2455 93024319.31714 +2567 2455 -16362810.24847 +2568 2455 -11951850.06621 +2569 2455 -74090485.10009 +2570 2455 46808583.40323 +2571 2455 -11944444.44836 +2572 2455 -16060922.31935 +2573 2455 -7107677.550651 +2574 2455 2.488493919373e-06 +2575 2455 -18527661.31289 +2576 2455 -5277700.460655 +2577 2455 11944444.44836 +2578 2455 -25750784.24113 +2579 2455 12385378.01131 +2456 2456 697590331.8784 +2457 2456 20815660.97705 +2458 2456 40965061.2198 +2459 2456 2966205.148247 +2460 2456 18780079.70233 +2461 2456 9394289.805242 +2462 2456 -24725057.40063 +2463 2456 -3518570.065188 +2464 2456 -21110801.83222 +2465 2456 29179895.04537 +2466 2456 -20803253.6245 +2467 2456 11716512.02698 +2468 2456 -27523507.01255 +2556 2456 6685644.928532 +2557 2456 -6579899.772699 +2558 2456 -8541180.705052 +2559 2456 42233282.34386 +2560 2456 2150097.608279 +2561 2456 -45715547.88649 +2562 2456 439821.2585788 +2563 2456 -27269599.07773 +2564 2456 -221502.6772963 +2565 2456 5939995.986973 +2566 2456 -16358892.70393 +2567 2456 -51790570.05088 +2568 2456 17031848.8311 +2569 2456 48076086.23075 +2570 2456 -90703859.27092 +2571 2456 -7125466.187114 +2572 2456 -7107677.550651 +2573 2456 -9517594.142065 +2574 2456 -48161586.95346 +2575 2456 -5277700.460655 +2576 2456 -56307063.72196 +2577 2456 -17021299.52369 +2578 2456 12385378.01131 +2579 2456 -35357225.93349 +2457 2457 490945057.4196 +2458 2457 47777777.76993 +2459 2457 20252298.79464 +2463 2457 -73573484.51406 +2464 2457 -47777777.76993 +2465 2457 19043968.59104 +2466 2457 -273863949.3497 +2467 2457 -47797526.08415 +2468 2457 -20243754.66502 +2469 2457 3432365.726058 +2470 2457 38241970.53018 +2471 2457 -16369382.67653 +2559 2457 1810230.00851 +2560 2457 14340738.95588 +2561 2457 8290807.874965 +2565 2457 -3359294.569133 +2566 2457 -11951850.06621 +2567 2457 -6689786.134111 +2568 2457 66125098.41489 +2569 2457 11944444.44837 +2570 2457 15207852.8515 +2574 2457 -19644494.8084 +2575 2457 -11944444.44837 +2576 2457 -7125466.187114 +2577 2457 -93269248.17781 +2578 2457 -11949381.52693 +2579 2457 -52618980.4305 +2580 2457 -17054654.84265 +2581 2457 9560492.637254 +2582 2457 -13448143.98712 +2458 2458 419251389.3651 +2459 2458 -52793537.14673 +2463 2458 -47777777.76993 +2464 2458 -59239194.56492 +2465 2458 9605400.916215 +2466 2458 -47807400.24127 +2467 2458 -49244136.23734 +2468 2458 -29248441.87035 +2469 2458 57362955.79526 +2470 2458 3432365.726057 +2471 2458 18376374.28788 +2559 2458 9560492.637254 +2560 2458 1810230.008509 +2561 2458 -4421798.559475 +2565 2458 -11949381.52693 +2566 2458 -45174403.34149 +2567 2458 -27804612.20634 +2568 2458 11944444.44837 +2569 2458 48201681.39244 +2570 2458 -5082672.97723 +2574 2458 -11944444.44836 +2575 2458 -16060922.31935 +2576 2458 -7107677.550651 +2577 2458 -11951850.06621 +2578 2458 -37114294.87206 +2579 2458 -16826932.79813 +2580 2458 14340738.95588 +2581 2458 -17054654.84265 +2582 2458 16137388.124 +2459 2459 451566531.4722 +2463 2459 18780079.70233 +2464 2459 9394289.805242 +2465 2459 -24725057.40063 +2466 2459 -20239482.6002 +2467 2459 -23545205.99654 +2468 2459 -25609721.67724 +2469 2459 -24554074.0148 +2470 2459 12250916.19192 +2471 2459 9152975.269492 +2559 2459 5527205.249977 +2560 2459 -6632697.839212 +2561 2459 4827280.022694 +2565 2459 -6688405.732252 +2566 2459 -29072115.16194 +2567 2459 -13594307.9147 +2568 2459 -3762599.703372 +2569 2459 -20258812.61341 +2570 2459 -38071476.41094 +2574 2459 -7125466.187114 +2575 2459 -7107677.550651 +2576 2459 -9517594.142065 +2577 2459 -52354091.66514 +2578 2459 -15346414.53585 +2579 2459 -72544459.24024 +2580 2459 -20172215.98068 +2581 2459 10758258.74933 +2582 2459 -45479079.58041 +2460 2460 773558827.9862 +2461 2460 2.658367156982e-05 +2462 2460 7037140.130311 +2463 2460 85893349.16099 +2464 2460 -1.427531242371e-05 +2465 2460 1759285.033452 +2472 2460 -188931397.8084 +2473 2460 6.824731826782e-06 +2474 2460 -3518570.065188 +2475 2460 -74622903.1185 +2476 2460 47777777.76992 +2477 2460 -20539364.73579 +2562 2460 -68569574.7737 +2563 2460 9.983777999878e-07 +2564 2460 46666190.80873 +2565 2460 -28443492.38882 +2566 2460 -11944444.44837 +2567 2460 16581478.26512 +2571 2460 103049709.0446 +2572 2460 8.106231689453e-06 +2573 2460 1759285.033469 +2574 2460 -19975421.90891 +2575 2460 -1.013278961182e-05 +2576 2460 439821.2585936 +2583 2460 -71083613.53293 +2584 2460 2.801418304443e-06 +2585 2460 -48425475.84218 +2586 2460 -29334356.73017 +2587 2460 11944444.44836 +2588 2460 -17021299.52369 +2461 2461 658884508.4497 +2462 2461 -84443207.28729 +2463 2461 -1.427531242371e-05 +2464 2461 -95661879.74567 +2465 2461 42221603.64364 +2472 2461 6.347894668579e-06 +2473 2461 21292410.96829 +2474 2461 -21110801.83222 +2475 2461 47777777.76992 +2476 2461 -60288613.16939 +2477 2461 11505400.91601 +2562 2461 -8.195638656616e-07 +2563 2461 -16013622.55363 +2564 2461 -5277700.460655 +2565 2461 -11944444.44837 +2566 2461 -24859919.89976 +2567 2461 11857600.23336 +2571 2461 7.987022399902e-06 +2572 2461 74381129.14638 +2573 2461 -21110801.83222 +2574 2461 -9.581446647644e-06 +2575 2461 -65364229.15794 +2576 2461 48591512.02092 +2583 2461 2.488493919373e-06 +2584 2461 -18527661.31289 +2585 2461 -5277700.460655 +2586 2461 11944444.44836 +2587 2461 -25750784.24113 +2588 2461 12385378.01131 +2462 2462 691056331.5443 +2463 2462 1759285.033452 +2464 2462 42221603.64364 +2465 2462 38993777.49737 +2472 2462 -3518570.065188 +2473 2462 -21110801.83222 +2474 2462 29179895.04537 +2475 2462 -20803253.6245 +2476 2462 11716512.02698 +2477 2462 -27523507.01255 +2562 2462 46402301.92001 +2563 2462 -5277700.460655 +2564 2462 -49602960.36391 +2565 2462 16581478.26512 +2566 2462 11857600.23336 +2567 2462 -32981587.68983 +2571 2462 1759285.033468 +2572 2462 -21110801.83222 +2573 2462 -68142578.48796 +2574 2462 439821.258594 +2575 2462 48380400.90995 +2576 2462 -100781580.1802 +2583 2462 -48161586.95346 +2584 2462 -5277700.460655 +2585 2462 -56307063.72196 +2586 2462 -17021299.52369 +2587 2462 12385378.01131 +2588 2462 -35357225.93349 +2463 2463 773558827.9862 +2464 2463 2.658367156982e-05 +2465 2463 7037140.130311 +2466 2463 85893349.16099 +2467 2463 -1.427531242371e-05 +2468 2463 1759285.033452 +2472 2463 -73573484.51406 +2473 2463 -47777777.76993 +2474 2463 19043968.59104 +2475 2463 -188931397.8084 +2476 2463 6.824731826782e-06 +2477 2463 -3518570.065188 +2478 2463 -74622903.1185 +2479 2463 47777777.76992 +2480 2463 -20539364.73579 +2562 2463 -19278339.76952 +2563 2463 11944444.44837 +2564 2463 6685644.928532 +2565 2463 -68569574.7737 +2566 2463 9.983777999878e-07 +2567 2463 46666190.80873 +2568 2463 -28443492.38882 +2569 2463 -11944444.44837 +2570 2463 16581478.26512 +2571 2463 17734607.15466 +2572 2463 1.817941665649e-06 +2573 2463 439821.2585785 +2574 2463 103049709.0446 +2575 2463 8.106231689453e-06 +2576 2463 1759285.033469 +2577 2463 -19975421.90891 +2578 2463 -1.013278961182e-05 +2579 2463 439821.2585936 +2583 2463 -19644494.8084 +2584 2463 -11944444.44837 +2585 2463 -7125466.187114 +2586 2463 -71083613.53293 +2587 2463 2.801418304443e-06 +2588 2463 -48425475.84218 +2589 2463 -29334356.73017 +2590 2463 11944444.44836 +2591 2463 -17021299.52369 +2464 2464 658884508.4497 +2465 2464 -84443207.28729 +2466 2464 -1.427531242371e-05 +2467 2464 -95661879.74567 +2468 2464 42221603.64364 +2472 2464 -47777777.76993 +2473 2464 -59239194.56492 +2474 2464 9605400.916215 +2475 2464 6.347894668579e-06 +2476 2464 21292410.96829 +2477 2464 -21110801.83222 +2478 2464 47777777.76992 +2479 2464 -60288613.16939 +2480 2464 11505400.91601 +2562 2464 11944444.44837 +2563 2464 -15694767.28047 +2564 2464 -6579899.772699 +2565 2464 -8.195638656616e-07 +2566 2464 -16013622.55363 +2567 2464 -5277700.460655 +2568 2464 -11944444.44837 +2569 2464 -24859919.89976 +2570 2464 11857600.23336 +2571 2464 3.322958946228e-06 +2572 2464 -27654200.09436 +2573 2464 -27480710.1887 +2574 2464 7.987022399902e-06 +2575 2464 74381129.14638 +2576 2464 -21110801.83222 +2577 2464 -9.581446647644e-06 +2578 2464 -65364229.15794 +2579 2464 48591512.02092 +2583 2464 -11944444.44836 +2584 2464 -16060922.31935 +2585 2464 -7107677.550651 +2586 2464 2.488493919373e-06 +2587 2464 -18527661.31289 +2588 2464 -5277700.460655 +2589 2464 11944444.44836 +2590 2464 -25750784.24113 +2591 2464 12385378.01131 +2465 2465 691056331.5443 +2466 2465 1759285.033452 +2467 2465 42221603.64364 +2468 2465 38993777.49737 +2472 2465 18780079.70233 +2473 2465 9394289.805242 +2474 2465 -24725057.40063 +2475 2465 -3518570.065188 +2476 2465 -21110801.83222 +2477 2465 29179895.04537 +2478 2465 -20803253.6245 +2479 2465 11716512.02698 +2480 2465 -27523507.01255 +2562 2465 6685644.928532 +2563 2465 -6579899.772699 +2564 2465 -8541180.705052 +2565 2465 46402301.92001 +2566 2465 -5277700.460655 +2567 2465 -49602960.36391 +2568 2465 16581478.26512 +2569 2465 11857600.23336 +2570 2465 -32981587.68983 +2571 2465 439821.2585788 +2572 2465 -27269599.07773 +2573 2465 -221502.6772963 +2574 2465 1759285.033468 +2575 2465 -21110801.83222 +2576 2465 -68142578.48796 +2577 2465 439821.258594 +2578 2465 48380400.90995 +2579 2465 -100781580.1802 +2583 2465 -7125466.187114 +2584 2465 -7107677.550651 +2585 2465 -9517594.142065 +2586 2465 -48161586.95346 +2587 2465 -5277700.460655 +2588 2465 -56307063.72196 +2589 2465 -17021299.52369 +2590 2465 12385378.01131 +2591 2465 -35357225.93349 +2466 2466 840410334.4004 +2467 2466 47827148.55553 +2468 2466 23749508.53569 +2469 2466 8066610.522678 +2470 2466 -47797526.08417 +2471 2466 20547636.30415 +2475 2466 -73573484.51406 +2476 2466 -47777777.76993 +2477 2466 19043968.59104 +2478 2466 -188931397.8084 +2479 2466 6.824731826782e-06 +2480 2466 -3518570.065188 +2481 2466 -74622903.1185 +2482 2466 47777777.76992 +2483 2466 -20539364.73579 +2565 2466 -19278339.76952 +2566 2466 11944444.44837 +2567 2466 6685644.928532 +2568 2466 -83208406.42019 +2569 2466 -11951850.06621 +2570 2466 42498171.10922 +2574 2466 17734607.15466 +2575 2466 1.817941665649e-06 +2576 2466 439821.2585785 +2577 2466 125282026.2887 +2578 2466 11956787.14478 +2579 2466 5935098.98454 +2580 2466 -32275376.32772 +2581 2466 -11949381.52693 +2582 2466 17028332.3953 +2586 2466 -19644494.8084 +2587 2466 -11944444.44837 +2588 2466 -7125466.187114 +2589 2466 -71083613.53293 +2590 2466 2.801418304443e-06 +2591 2466 -48425475.84218 +2592 2466 -29334356.73017 +2593 2466 11944444.44836 +2594 2466 -17021299.52369 +2467 2467 711379506.5777 +2468 2467 -65443950.97306 +2469 2467 -47807400.24129 +2470 2467 -159193824.4844 +2471 2467 35050823.25634 +2475 2467 -47777777.76993 +2476 2467 -59239194.56492 +2477 2467 9605400.916215 +2478 2467 6.347894668579e-06 +2479 2467 21292410.96829 +2480 2467 -21110801.83222 +2481 2467 47777777.76992 +2482 2467 -60288613.16939 +2483 2467 11505400.91601 +2565 2467 11944444.44837 +2566 2467 -15694767.28047 +2567 2467 -6579899.772699 +2568 2467 -11949381.52693 +2569 2467 -27053453.11441 +2570 2467 3626698.329752 +2574 2467 3.322958946228e-06 +2575 2467 -27654200.09436 +2576 2467 -27480710.1887 +2577 2467 11956787.14477 +2578 2467 93024319.31714 +2579 2467 -16362810.24847 +2580 2467 -11951850.06621 +2581 2467 -74090485.10009 +2582 2467 46808583.40323 +2586 2467 -11944444.44836 +2587 2467 -16060922.31935 +2588 2467 -7107677.550651 +2589 2467 2.488493919373e-06 +2590 2467 -18527661.31289 +2591 2467 -5277700.460655 +2592 2467 11944444.44836 +2593 2467 -25750784.24113 +2594 2467 12385378.01131 +2468 2468 697590331.8784 +2469 2468 20815660.97705 +2470 2468 40965061.2198 +2471 2468 2966205.148247 +2475 2468 18780079.70233 +2476 2468 9394289.805242 +2477 2468 -24725057.40063 +2478 2468 -3518570.065188 +2479 2468 -21110801.83222 +2480 2468 29179895.04537 +2481 2468 -20803253.6245 +2482 2468 11716512.02698 +2483 2468 -27523507.01255 +2565 2468 6685644.928532 +2566 2468 -6579899.772699 +2567 2468 -8541180.705052 +2568 2468 42233282.34386 +2569 2468 2150097.608279 +2570 2468 -45715547.88649 +2574 2468 439821.2585788 +2575 2468 -27269599.07773 +2576 2468 -221502.6772963 +2577 2468 5939995.986973 +2578 2468 -16358892.70393 +2579 2468 -51790570.05088 +2580 2468 17031848.8311 +2581 2468 48076086.23075 +2582 2468 -90703859.27092 +2586 2468 -7125466.187114 +2587 2468 -7107677.550651 +2588 2468 -9517594.142065 +2589 2468 -48161586.95346 +2590 2468 -5277700.460655 +2591 2468 -56307063.72196 +2592 2468 -17021299.52369 +2593 2468 12385378.01131 +2594 2468 -35357225.93349 +2469 2469 490945057.4196 +2470 2469 47777777.76993 +2471 2469 20252298.79464 +2478 2469 -73573484.51406 +2479 2469 -47777777.76993 +2480 2469 19043968.59104 +2481 2469 -273863949.3497 +2482 2469 -47797526.08415 +2483 2469 -20243754.66502 +2484 2469 3432365.726058 +2485 2469 38241970.53018 +2486 2469 -16369382.67653 +2568 2469 1810230.00851 +2569 2469 14340738.95588 +2570 2469 8290807.874965 +2577 2469 -3359294.569133 +2578 2469 -11951850.06621 +2579 2469 -6689786.134111 +2580 2469 66125098.41489 +2581 2469 11944444.44837 +2582 2469 15207852.8515 +2589 2469 -19644494.8084 +2590 2469 -11944444.44837 +2591 2469 -7125466.187114 +2592 2469 -93269248.17781 +2593 2469 -11949381.52693 +2594 2469 -52618980.4305 +2595 2469 -17054654.84265 +2596 2469 9560492.637254 +2597 2469 -13448143.98712 +2470 2470 419251389.3651 +2471 2470 -52793537.14673 +2478 2470 -47777777.76993 +2479 2470 -59239194.56492 +2480 2470 9605400.916215 +2481 2470 -47807400.24127 +2482 2470 -49244136.23734 +2483 2470 -29248441.87035 +2484 2470 57362955.79526 +2485 2470 3432365.726057 +2486 2470 18376374.28788 +2568 2470 9560492.637254 +2569 2470 1810230.008509 +2570 2470 -4421798.559475 +2577 2470 -11949381.52693 +2578 2470 -45174403.34149 +2579 2470 -27804612.20634 +2580 2470 11944444.44837 +2581 2470 48201681.39244 +2582 2470 -5082672.97723 +2589 2470 -11944444.44836 +2590 2470 -16060922.31935 +2591 2470 -7107677.550651 +2592 2470 -11951850.06621 +2593 2470 -37114294.87206 +2594 2470 -16826932.79813 +2595 2470 14340738.95588 +2596 2470 -17054654.84265 +2597 2470 16137388.124 +2471 2471 451566531.4722 +2478 2471 18780079.70233 +2479 2471 9394289.805242 +2480 2471 -24725057.40063 +2481 2471 -20239482.6002 +2482 2471 -23545205.99654 +2483 2471 -25609721.67724 +2484 2471 -24554074.0148 +2485 2471 12250916.19192 +2486 2471 9152975.269492 +2568 2471 5527205.249977 +2569 2471 -6632697.839212 +2570 2471 4827280.022694 +2577 2471 -6688405.732252 +2578 2471 -29072115.16194 +2579 2471 -13594307.9147 +2580 2471 -3762599.703372 +2581 2471 -20258812.61341 +2582 2471 -38071476.41094 +2589 2471 -7125466.187114 +2590 2471 -7107677.550651 +2591 2471 -9517594.142065 +2592 2471 -52354091.66514 +2593 2471 -15346414.53585 +2594 2471 -72544459.24024 +2595 2471 -20172215.98068 +2596 2471 10758258.74933 +2597 2471 -45479079.58041 +2472 2472 773558827.9862 +2473 2472 2.658367156982e-05 +2474 2472 7037140.130311 +2475 2472 85893349.16099 +2476 2472 -1.427531242371e-05 +2477 2472 1759285.033452 +2487 2472 -188931397.8084 +2488 2472 6.824731826782e-06 +2489 2472 -3518570.065188 +2490 2472 -74622903.1185 +2491 2472 47777777.76992 +2492 2472 -20539364.73579 +2571 2472 -68569574.7737 +2572 2472 9.983777999878e-07 +2573 2472 46666190.80873 +2574 2472 -28443492.38882 +2575 2472 -11944444.44837 +2576 2472 16581478.26512 +2583 2472 103049709.0446 +2584 2472 8.106231689453e-06 +2585 2472 1759285.033469 +2586 2472 -19975421.90891 +2587 2472 -1.013278961182e-05 +2588 2472 439821.2585936 +2598 2472 -71083613.53293 +2599 2472 2.801418304443e-06 +2600 2472 -48425475.84218 +2601 2472 -29334356.73017 +2602 2472 11944444.44836 +2603 2472 -17021299.52369 +2473 2473 658884508.4497 +2474 2473 -84443207.28729 +2475 2473 -1.427531242371e-05 +2476 2473 -95661879.74567 +2477 2473 42221603.64364 +2487 2473 6.347894668579e-06 +2488 2473 21292410.96829 +2489 2473 -21110801.83222 +2490 2473 47777777.76992 +2491 2473 -60288613.16939 +2492 2473 11505400.91601 +2571 2473 -8.195638656616e-07 +2572 2473 -16013622.55363 +2573 2473 -5277700.460655 +2574 2473 -11944444.44837 +2575 2473 -24859919.89976 +2576 2473 11857600.23336 +2583 2473 7.987022399902e-06 +2584 2473 74381129.14638 +2585 2473 -21110801.83222 +2586 2473 -9.581446647644e-06 +2587 2473 -65364229.15794 +2588 2473 48591512.02092 +2598 2473 2.488493919373e-06 +2599 2473 -18527661.31289 +2600 2473 -5277700.460655 +2601 2473 11944444.44836 +2602 2473 -25750784.24113 +2603 2473 12385378.01131 +2474 2474 691056331.5443 +2475 2474 1759285.033452 +2476 2474 42221603.64364 +2477 2474 38993777.49737 +2487 2474 -3518570.065188 +2488 2474 -21110801.83222 +2489 2474 29179895.04537 +2490 2474 -20803253.6245 +2491 2474 11716512.02698 +2492 2474 -27523507.01255 +2571 2474 46402301.92001 +2572 2474 -5277700.460655 +2573 2474 -49602960.36391 +2574 2474 16581478.26512 +2575 2474 11857600.23336 +2576 2474 -32981587.68983 +2583 2474 1759285.033468 +2584 2474 -21110801.83222 +2585 2474 -68142578.48796 +2586 2474 439821.258594 +2587 2474 48380400.90995 +2588 2474 -100781580.1802 +2598 2474 -48161586.95346 +2599 2474 -5277700.460655 +2600 2474 -56307063.72196 +2601 2474 -17021299.52369 +2602 2474 12385378.01131 +2603 2474 -35357225.93349 +2475 2475 773558827.9862 +2476 2475 2.658367156982e-05 +2477 2475 7037140.130311 +2478 2475 85893349.16099 +2479 2475 -1.427531242371e-05 +2480 2475 1759285.033452 +2487 2475 -73573484.51406 +2488 2475 -47777777.76993 +2489 2475 19043968.59104 +2490 2475 -188931397.8084 +2491 2475 6.824731826782e-06 +2492 2475 -3518570.065188 +2493 2475 -74622903.1185 +2494 2475 47777777.76992 +2495 2475 -20539364.73579 +2571 2475 -19278339.76952 +2572 2475 11944444.44837 +2573 2475 6685644.928532 +2574 2475 -68569574.7737 +2575 2475 9.983777999878e-07 +2576 2475 46666190.80873 +2577 2475 -28443492.38882 +2578 2475 -11944444.44837 +2579 2475 16581478.26512 +2583 2475 17734607.15466 +2584 2475 1.817941665649e-06 +2585 2475 439821.2585785 +2586 2475 103049709.0446 +2587 2475 8.106231689453e-06 +2588 2475 1759285.033469 +2589 2475 -19975421.90891 +2590 2475 -1.013278961182e-05 +2591 2475 439821.2585936 +2598 2475 -19644494.8084 +2599 2475 -11944444.44837 +2600 2475 -7125466.187114 +2601 2475 -71083613.53293 +2602 2475 2.801418304443e-06 +2603 2475 -48425475.84218 +2604 2475 -29334356.73017 +2605 2475 11944444.44836 +2606 2475 -17021299.52369 +2476 2476 658884508.4497 +2477 2476 -84443207.28729 +2478 2476 -1.427531242371e-05 +2479 2476 -95661879.74567 +2480 2476 42221603.64364 +2487 2476 -47777777.76993 +2488 2476 -59239194.56492 +2489 2476 9605400.916215 +2490 2476 6.347894668579e-06 +2491 2476 21292410.96829 +2492 2476 -21110801.83222 +2493 2476 47777777.76992 +2494 2476 -60288613.16939 +2495 2476 11505400.91601 +2571 2476 11944444.44837 +2572 2476 -15694767.28047 +2573 2476 -6579899.772699 +2574 2476 -8.195638656616e-07 +2575 2476 -16013622.55363 +2576 2476 -5277700.460655 +2577 2476 -11944444.44837 +2578 2476 -24859919.89976 +2579 2476 11857600.23336 +2583 2476 3.322958946228e-06 +2584 2476 -27654200.09436 +2585 2476 -27480710.1887 +2586 2476 7.987022399902e-06 +2587 2476 74381129.14638 +2588 2476 -21110801.83222 +2589 2476 -9.581446647644e-06 +2590 2476 -65364229.15794 +2591 2476 48591512.02092 +2598 2476 -11944444.44836 +2599 2476 -16060922.31935 +2600 2476 -7107677.550651 +2601 2476 2.488493919373e-06 +2602 2476 -18527661.31289 +2603 2476 -5277700.460655 +2604 2476 11944444.44836 +2605 2476 -25750784.24113 +2606 2476 12385378.01131 +2477 2477 691056331.5443 +2478 2477 1759285.033452 +2479 2477 42221603.64364 +2480 2477 38993777.49737 +2487 2477 18780079.70233 +2488 2477 9394289.805242 +2489 2477 -24725057.40063 +2490 2477 -3518570.065188 +2491 2477 -21110801.83222 +2492 2477 29179895.04537 +2493 2477 -20803253.6245 +2494 2477 11716512.02698 +2495 2477 -27523507.01255 +2571 2477 6685644.928532 +2572 2477 -6579899.772699 +2573 2477 -8541180.705052 +2574 2477 46402301.92001 +2575 2477 -5277700.460655 +2576 2477 -49602960.36391 +2577 2477 16581478.26512 +2578 2477 11857600.23336 +2579 2477 -32981587.68983 +2583 2477 439821.2585788 +2584 2477 -27269599.07773 +2585 2477 -221502.6772963 +2586 2477 1759285.033468 +2587 2477 -21110801.83222 +2588 2477 -68142578.48796 +2589 2477 439821.258594 +2590 2477 48380400.90995 +2591 2477 -100781580.1802 +2598 2477 -7125466.187114 +2599 2477 -7107677.550651 +2600 2477 -9517594.142065 +2601 2477 -48161586.95346 +2602 2477 -5277700.460655 +2603 2477 -56307063.72196 +2604 2477 -17021299.52369 +2605 2477 12385378.01131 +2606 2477 -35357225.93349 +2478 2478 773558827.9862 +2479 2478 2.658367156982e-05 +2480 2478 7037140.130311 +2481 2478 85893349.16099 +2482 2478 -1.427531242371e-05 +2483 2478 1759285.033452 +2490 2478 -73573484.51406 +2491 2478 -47777777.76993 +2492 2478 19043968.59104 +2493 2478 -188931397.8084 +2494 2478 6.824731826782e-06 +2495 2478 -3518570.065188 +2496 2478 -74622903.1185 +2497 2478 47777777.76992 +2498 2478 -20539364.73579 +2574 2478 -19278339.76952 +2575 2478 11944444.44837 +2576 2478 6685644.928532 +2577 2478 -68569574.7737 +2578 2478 9.983777999878e-07 +2579 2478 46666190.80873 +2580 2478 -28443492.38882 +2581 2478 -11944444.44837 +2582 2478 16581478.26512 +2586 2478 17734607.15466 +2587 2478 1.817941665649e-06 +2588 2478 439821.2585785 +2589 2478 103049709.0446 +2590 2478 8.106231689453e-06 +2591 2478 1759285.033469 +2592 2478 -19975421.90891 +2593 2478 -1.013278961182e-05 +2594 2478 439821.2585936 +2601 2478 -19644494.8084 +2602 2478 -11944444.44837 +2603 2478 -7125466.187114 +2604 2478 -71083613.53293 +2605 2478 2.801418304443e-06 +2606 2478 -48425475.84218 +2607 2478 -29334356.73017 +2608 2478 11944444.44836 +2609 2478 -17021299.52369 +2479 2479 658884508.4497 +2480 2479 -84443207.28729 +2481 2479 -1.427531242371e-05 +2482 2479 -95661879.74567 +2483 2479 42221603.64364 +2490 2479 -47777777.76993 +2491 2479 -59239194.56492 +2492 2479 9605400.916215 +2493 2479 6.347894668579e-06 +2494 2479 21292410.96829 +2495 2479 -21110801.83222 +2496 2479 47777777.76992 +2497 2479 -60288613.16939 +2498 2479 11505400.91601 +2574 2479 11944444.44837 +2575 2479 -15694767.28047 +2576 2479 -6579899.772699 +2577 2479 -8.195638656616e-07 +2578 2479 -16013622.55363 +2579 2479 -5277700.460655 +2580 2479 -11944444.44837 +2581 2479 -24859919.89976 +2582 2479 11857600.23336 +2586 2479 3.322958946228e-06 +2587 2479 -27654200.09436 +2588 2479 -27480710.1887 +2589 2479 7.987022399902e-06 +2590 2479 74381129.14638 +2591 2479 -21110801.83222 +2592 2479 -9.581446647644e-06 +2593 2479 -65364229.15794 +2594 2479 48591512.02092 +2601 2479 -11944444.44836 +2602 2479 -16060922.31935 +2603 2479 -7107677.550651 +2604 2479 2.488493919373e-06 +2605 2479 -18527661.31289 +2606 2479 -5277700.460655 +2607 2479 11944444.44836 +2608 2479 -25750784.24113 +2609 2479 12385378.01131 +2480 2480 691056331.5443 +2481 2480 1759285.033452 +2482 2480 42221603.64364 +2483 2480 38993777.49737 +2490 2480 18780079.70233 +2491 2480 9394289.805242 +2492 2480 -24725057.40063 +2493 2480 -3518570.065188 +2494 2480 -21110801.83222 +2495 2480 29179895.04537 +2496 2480 -20803253.6245 +2497 2480 11716512.02698 +2498 2480 -27523507.01255 +2574 2480 6685644.928532 +2575 2480 -6579899.772699 +2576 2480 -8541180.705052 +2577 2480 46402301.92001 +2578 2480 -5277700.460655 +2579 2480 -49602960.36391 +2580 2480 16581478.26512 +2581 2480 11857600.23336 +2582 2480 -32981587.68983 +2586 2480 439821.2585788 +2587 2480 -27269599.07773 +2588 2480 -221502.6772963 +2589 2480 1759285.033468 +2590 2480 -21110801.83222 +2591 2480 -68142578.48796 +2592 2480 439821.258594 +2593 2480 48380400.90995 +2594 2480 -100781580.1802 +2601 2480 -7125466.187114 +2602 2480 -7107677.550651 +2603 2480 -9517594.142065 +2604 2480 -48161586.95346 +2605 2480 -5277700.460655 +2606 2480 -56307063.72196 +2607 2480 -17021299.52369 +2608 2480 12385378.01131 +2609 2480 -35357225.93349 +2481 2481 840410334.4004 +2482 2481 47827148.55553 +2483 2481 23749508.53569 +2484 2481 8066610.522678 +2485 2481 -47797526.08417 +2486 2481 20547636.30415 +2493 2481 -73573484.51406 +2494 2481 -47777777.76993 +2495 2481 19043968.59104 +2496 2481 -188931397.8084 +2497 2481 6.824731826782e-06 +2498 2481 -3518570.065188 +2499 2481 -74622903.1185 +2500 2481 47777777.76992 +2501 2481 -20539364.73579 +2577 2481 -19278339.76952 +2578 2481 11944444.44837 +2579 2481 6685644.928532 +2580 2481 -83208406.42019 +2581 2481 -11951850.06621 +2582 2481 42498171.10922 +2589 2481 17734607.15466 +2590 2481 1.817941665649e-06 +2591 2481 439821.2585785 +2592 2481 125282026.2887 +2593 2481 11956787.14478 +2594 2481 5935098.98454 +2595 2481 -32275376.32772 +2596 2481 -11949381.52693 +2597 2481 17028332.3953 +2604 2481 -19644494.8084 +2605 2481 -11944444.44837 +2606 2481 -7125466.187114 +2607 2481 -71083613.53293 +2608 2481 2.801418304443e-06 +2609 2481 -48425475.84218 +2610 2481 -29334356.73017 +2611 2481 11944444.44836 +2612 2481 -17021299.52369 +2482 2482 711379506.5777 +2483 2482 -65443950.97306 +2484 2482 -47807400.24129 +2485 2482 -159193824.4844 +2486 2482 35050823.25634 +2493 2482 -47777777.76993 +2494 2482 -59239194.56492 +2495 2482 9605400.916215 +2496 2482 6.347894668579e-06 +2497 2482 21292410.96829 +2498 2482 -21110801.83222 +2499 2482 47777777.76992 +2500 2482 -60288613.16939 +2501 2482 11505400.91601 +2577 2482 11944444.44837 +2578 2482 -15694767.28047 +2579 2482 -6579899.772699 +2580 2482 -11949381.52693 +2581 2482 -27053453.11441 +2582 2482 3626698.329752 +2589 2482 3.322958946228e-06 +2590 2482 -27654200.09436 +2591 2482 -27480710.1887 +2592 2482 11956787.14477 +2593 2482 93024319.31714 +2594 2482 -16362810.24847 +2595 2482 -11951850.06621 +2596 2482 -74090485.10009 +2597 2482 46808583.40323 +2604 2482 -11944444.44836 +2605 2482 -16060922.31935 +2606 2482 -7107677.550651 +2607 2482 2.488493919373e-06 +2608 2482 -18527661.31289 +2609 2482 -5277700.460655 +2610 2482 11944444.44836 +2611 2482 -25750784.24113 +2612 2482 12385378.01131 +2483 2483 697590331.8784 +2484 2483 20815660.97705 +2485 2483 40965061.2198 +2486 2483 2966205.148247 +2493 2483 18780079.70233 +2494 2483 9394289.805242 +2495 2483 -24725057.40063 +2496 2483 -3518570.065188 +2497 2483 -21110801.83222 +2498 2483 29179895.04537 +2499 2483 -20803253.6245 +2500 2483 11716512.02698 +2501 2483 -27523507.01255 +2577 2483 6685644.928532 +2578 2483 -6579899.772699 +2579 2483 -8541180.705052 +2580 2483 42233282.34386 +2581 2483 2150097.608279 +2582 2483 -45715547.88649 +2589 2483 439821.2585788 +2590 2483 -27269599.07773 +2591 2483 -221502.6772963 +2592 2483 5939995.986973 +2593 2483 -16358892.70393 +2594 2483 -51790570.05088 +2595 2483 17031848.8311 +2596 2483 48076086.23075 +2597 2483 -90703859.27092 +2604 2483 -7125466.187114 +2605 2483 -7107677.550651 +2606 2483 -9517594.142065 +2607 2483 -48161586.95346 +2608 2483 -5277700.460655 +2609 2483 -56307063.72196 +2610 2483 -17021299.52369 +2611 2483 12385378.01131 +2612 2483 -35357225.93349 +2484 2484 490945057.4196 +2485 2484 47777777.76993 +2486 2484 20252298.79464 +2496 2484 -73573484.51406 +2497 2484 -47777777.76993 +2498 2484 19043968.59104 +2499 2484 -273863949.3497 +2500 2484 -47797526.08415 +2501 2484 -20243754.66502 +2502 2484 3432365.726058 +2503 2484 38241970.53018 +2504 2484 -16369382.67653 +2580 2484 1810230.00851 +2581 2484 14340738.95588 +2582 2484 8290807.874965 +2592 2484 -3359294.569133 +2593 2484 -11951850.06621 +2594 2484 -6689786.134111 +2595 2484 66125098.41489 +2596 2484 11944444.44837 +2597 2484 15207852.8515 +2607 2484 -19644494.8084 +2608 2484 -11944444.44837 +2609 2484 -7125466.187114 +2610 2484 -93269248.17781 +2611 2484 -11949381.52693 +2612 2484 -52618980.4305 +2613 2484 -17054654.84265 +2614 2484 9560492.637254 +2615 2484 -13448143.98712 +2485 2485 419251389.3651 +2486 2485 -52793537.14673 +2496 2485 -47777777.76993 +2497 2485 -59239194.56492 +2498 2485 9605400.916215 +2499 2485 -47807400.24127 +2500 2485 -49244136.23734 +2501 2485 -29248441.87035 +2502 2485 57362955.79526 +2503 2485 3432365.726057 +2504 2485 18376374.28788 +2580 2485 9560492.637254 +2581 2485 1810230.008509 +2582 2485 -4421798.559475 +2592 2485 -11949381.52693 +2593 2485 -45174403.34149 +2594 2485 -27804612.20634 +2595 2485 11944444.44837 +2596 2485 48201681.39244 +2597 2485 -5082672.97723 +2607 2485 -11944444.44836 +2608 2485 -16060922.31935 +2609 2485 -7107677.550651 +2610 2485 -11951850.06621 +2611 2485 -37114294.87206 +2612 2485 -16826932.79813 +2613 2485 14340738.95588 +2614 2485 -17054654.84265 +2615 2485 16137388.124 +2486 2486 451566531.4722 +2496 2486 18780079.70233 +2497 2486 9394289.805242 +2498 2486 -24725057.40063 +2499 2486 -20239482.6002 +2500 2486 -23545205.99654 +2501 2486 -25609721.67724 +2502 2486 -24554074.0148 +2503 2486 12250916.19192 +2504 2486 9152975.269492 +2580 2486 5527205.249977 +2581 2486 -6632697.839212 +2582 2486 4827280.022694 +2592 2486 -6688405.732252 +2593 2486 -29072115.16194 +2594 2486 -13594307.9147 +2595 2486 -3762599.703372 +2596 2486 -20258812.61341 +2597 2486 -38071476.41094 +2607 2486 -7125466.187114 +2608 2486 -7107677.550651 +2609 2486 -9517594.142065 +2610 2486 -52354091.66514 +2611 2486 -15346414.53585 +2612 2486 -72544459.24024 +2613 2486 -20172215.98068 +2614 2486 10758258.74933 +2615 2486 -45479079.58041 +2487 2487 773558827.9862 +2488 2487 2.658367156982e-05 +2489 2487 7037140.130311 +2490 2487 85893349.16099 +2491 2487 -1.427531242371e-05 +2492 2487 1759285.033452 +2505 2487 -188931397.8084 +2506 2487 6.824731826782e-06 +2507 2487 -3518570.065188 +2508 2487 -74622903.1185 +2509 2487 47777777.76992 +2510 2487 -20539364.73579 +2583 2487 -68569574.7737 +2584 2487 9.983777999878e-07 +2585 2487 46666190.80873 +2586 2487 -28443492.38882 +2587 2487 -11944444.44837 +2588 2487 16581478.26512 +2598 2487 103049709.0446 +2599 2487 8.106231689453e-06 +2600 2487 1759285.033469 +2601 2487 -19975421.90891 +2602 2487 -1.013278961182e-05 +2603 2487 439821.2585936 +2616 2487 -71083613.53293 +2617 2487 2.801418304443e-06 +2618 2487 -48425475.84218 +2619 2487 -29334356.73017 +2620 2487 11944444.44836 +2621 2487 -17021299.52369 +2488 2488 658884508.4497 +2489 2488 -84443207.28729 +2490 2488 -1.427531242371e-05 +2491 2488 -95661879.74567 +2492 2488 42221603.64364 +2505 2488 6.347894668579e-06 +2506 2488 21292410.96829 +2507 2488 -21110801.83222 +2508 2488 47777777.76992 +2509 2488 -60288613.16939 +2510 2488 11505400.91601 +2583 2488 -8.195638656616e-07 +2584 2488 -16013622.55363 +2585 2488 -5277700.460655 +2586 2488 -11944444.44837 +2587 2488 -24859919.89976 +2588 2488 11857600.23336 +2598 2488 7.987022399902e-06 +2599 2488 74381129.14638 +2600 2488 -21110801.83222 +2601 2488 -9.581446647644e-06 +2602 2488 -65364229.15794 +2603 2488 48591512.02092 +2616 2488 2.488493919373e-06 +2617 2488 -18527661.31289 +2618 2488 -5277700.460655 +2619 2488 11944444.44836 +2620 2488 -25750784.24113 +2621 2488 12385378.01131 +2489 2489 691056331.5443 +2490 2489 1759285.033452 +2491 2489 42221603.64364 +2492 2489 38993777.49737 +2505 2489 -3518570.065188 +2506 2489 -21110801.83222 +2507 2489 29179895.04537 +2508 2489 -20803253.6245 +2509 2489 11716512.02698 +2510 2489 -27523507.01255 +2583 2489 46402301.92001 +2584 2489 -5277700.460655 +2585 2489 -49602960.36391 +2586 2489 16581478.26512 +2587 2489 11857600.23336 +2588 2489 -32981587.68983 +2598 2489 1759285.033468 +2599 2489 -21110801.83222 +2600 2489 -68142578.48796 +2601 2489 439821.258594 +2602 2489 48380400.90995 +2603 2489 -100781580.1802 +2616 2489 -48161586.95346 +2617 2489 -5277700.460655 +2618 2489 -56307063.72196 +2619 2489 -17021299.52369 +2620 2489 12385378.01131 +2621 2489 -35357225.93349 +2490 2490 773558827.9862 +2491 2490 2.658367156982e-05 +2492 2490 7037140.130311 +2493 2490 85893349.16099 +2494 2490 -1.427531242371e-05 +2495 2490 1759285.033452 +2505 2490 -73573484.51406 +2506 2490 -47777777.76993 +2507 2490 19043968.59104 +2508 2490 -188931397.8084 +2509 2490 6.824731826782e-06 +2510 2490 -3518570.065188 +2511 2490 -74622903.1185 +2512 2490 47777777.76992 +2513 2490 -20539364.73579 +2583 2490 -19278339.76952 +2584 2490 11944444.44837 +2585 2490 6685644.928532 +2586 2490 -68569574.7737 +2587 2490 9.983777999878e-07 +2588 2490 46666190.80873 +2589 2490 -28443492.38882 +2590 2490 -11944444.44837 +2591 2490 16581478.26512 +2598 2490 17734607.15466 +2599 2490 1.817941665649e-06 +2600 2490 439821.2585785 +2601 2490 103049709.0446 +2602 2490 8.106231689453e-06 +2603 2490 1759285.033469 +2604 2490 -19975421.90891 +2605 2490 -1.013278961182e-05 +2606 2490 439821.2585936 +2616 2490 -19644494.8084 +2617 2490 -11944444.44837 +2618 2490 -7125466.187114 +2619 2490 -71083613.53293 +2620 2490 2.801418304443e-06 +2621 2490 -48425475.84218 +2622 2490 -29334356.73017 +2623 2490 11944444.44836 +2624 2490 -17021299.52369 +2491 2491 658884508.4497 +2492 2491 -84443207.28729 +2493 2491 -1.427531242371e-05 +2494 2491 -95661879.74567 +2495 2491 42221603.64364 +2505 2491 -47777777.76993 +2506 2491 -59239194.56492 +2507 2491 9605400.916215 +2508 2491 6.347894668579e-06 +2509 2491 21292410.96829 +2510 2491 -21110801.83222 +2511 2491 47777777.76992 +2512 2491 -60288613.16939 +2513 2491 11505400.91601 +2583 2491 11944444.44837 +2584 2491 -15694767.28047 +2585 2491 -6579899.772699 +2586 2491 -8.195638656616e-07 +2587 2491 -16013622.55363 +2588 2491 -5277700.460655 +2589 2491 -11944444.44837 +2590 2491 -24859919.89976 +2591 2491 11857600.23336 +2598 2491 3.322958946228e-06 +2599 2491 -27654200.09436 +2600 2491 -27480710.1887 +2601 2491 7.987022399902e-06 +2602 2491 74381129.14638 +2603 2491 -21110801.83222 +2604 2491 -9.581446647644e-06 +2605 2491 -65364229.15794 +2606 2491 48591512.02092 +2616 2491 -11944444.44836 +2617 2491 -16060922.31935 +2618 2491 -7107677.550651 +2619 2491 2.488493919373e-06 +2620 2491 -18527661.31289 +2621 2491 -5277700.460655 +2622 2491 11944444.44836 +2623 2491 -25750784.24113 +2624 2491 12385378.01131 +2492 2492 691056331.5443 +2493 2492 1759285.033452 +2494 2492 42221603.64364 +2495 2492 38993777.49737 +2505 2492 18780079.70233 +2506 2492 9394289.805242 +2507 2492 -24725057.40063 +2508 2492 -3518570.065188 +2509 2492 -21110801.83222 +2510 2492 29179895.04537 +2511 2492 -20803253.6245 +2512 2492 11716512.02698 +2513 2492 -27523507.01255 +2583 2492 6685644.928532 +2584 2492 -6579899.772699 +2585 2492 -8541180.705052 +2586 2492 46402301.92001 +2587 2492 -5277700.460655 +2588 2492 -49602960.36391 +2589 2492 16581478.26512 +2590 2492 11857600.23336 +2591 2492 -32981587.68983 +2598 2492 439821.2585788 +2599 2492 -27269599.07773 +2600 2492 -221502.6772963 +2601 2492 1759285.033468 +2602 2492 -21110801.83222 +2603 2492 -68142578.48796 +2604 2492 439821.258594 +2605 2492 48380400.90995 +2606 2492 -100781580.1802 +2616 2492 -7125466.187114 +2617 2492 -7107677.550651 +2618 2492 -9517594.142065 +2619 2492 -48161586.95346 +2620 2492 -5277700.460655 +2621 2492 -56307063.72196 +2622 2492 -17021299.52369 +2623 2492 12385378.01131 +2624 2492 -35357225.93349 +2493 2493 773558827.9862 +2494 2493 2.658367156982e-05 +2495 2493 7037140.130311 +2496 2493 85893349.16099 +2497 2493 -1.427531242371e-05 +2498 2493 1759285.033452 +2508 2493 -73573484.51406 +2509 2493 -47777777.76993 +2510 2493 19043968.59104 +2511 2493 -188931397.8084 +2512 2493 6.824731826782e-06 +2513 2493 -3518570.065188 +2514 2493 -74622903.1185 +2515 2493 47777777.76992 +2516 2493 -20539364.73579 +2586 2493 -19278339.76952 +2587 2493 11944444.44837 +2588 2493 6685644.928532 +2589 2493 -68569574.7737 +2590 2493 9.983777999878e-07 +2591 2493 46666190.80873 +2592 2493 -28443492.38882 +2593 2493 -11944444.44837 +2594 2493 16581478.26512 +2601 2493 17734607.15466 +2602 2493 1.817941665649e-06 +2603 2493 439821.2585785 +2604 2493 103049709.0446 +2605 2493 8.106231689453e-06 +2606 2493 1759285.033469 +2607 2493 -19975421.90891 +2608 2493 -1.013278961182e-05 +2609 2493 439821.2585936 +2619 2493 -19644494.8084 +2620 2493 -11944444.44837 +2621 2493 -7125466.187114 +2622 2493 -71083613.53293 +2623 2493 2.801418304443e-06 +2624 2493 -48425475.84218 +2625 2493 -29334356.73017 +2626 2493 11944444.44836 +2627 2493 -17021299.52369 +2494 2494 658884508.4497 +2495 2494 -84443207.28729 +2496 2494 -1.427531242371e-05 +2497 2494 -95661879.74567 +2498 2494 42221603.64364 +2508 2494 -47777777.76993 +2509 2494 -59239194.56492 +2510 2494 9605400.916215 +2511 2494 6.347894668579e-06 +2512 2494 21292410.96829 +2513 2494 -21110801.83222 +2514 2494 47777777.76992 +2515 2494 -60288613.16939 +2516 2494 11505400.91601 +2586 2494 11944444.44837 +2587 2494 -15694767.28047 +2588 2494 -6579899.772699 +2589 2494 -8.195638656616e-07 +2590 2494 -16013622.55363 +2591 2494 -5277700.460655 +2592 2494 -11944444.44837 +2593 2494 -24859919.89976 +2594 2494 11857600.23336 +2601 2494 3.322958946228e-06 +2602 2494 -27654200.09436 +2603 2494 -27480710.1887 +2604 2494 7.987022399902e-06 +2605 2494 74381129.14638 +2606 2494 -21110801.83222 +2607 2494 -9.581446647644e-06 +2608 2494 -65364229.15794 +2609 2494 48591512.02092 +2619 2494 -11944444.44836 +2620 2494 -16060922.31935 +2621 2494 -7107677.550651 +2622 2494 2.488493919373e-06 +2623 2494 -18527661.31289 +2624 2494 -5277700.460655 +2625 2494 11944444.44836 +2626 2494 -25750784.24113 +2627 2494 12385378.01131 +2495 2495 691056331.5443 +2496 2495 1759285.033452 +2497 2495 42221603.64364 +2498 2495 38993777.49737 +2508 2495 18780079.70233 +2509 2495 9394289.805242 +2510 2495 -24725057.40063 +2511 2495 -3518570.065188 +2512 2495 -21110801.83222 +2513 2495 29179895.04537 +2514 2495 -20803253.6245 +2515 2495 11716512.02698 +2516 2495 -27523507.01255 +2586 2495 6685644.928532 +2587 2495 -6579899.772699 +2588 2495 -8541180.705052 +2589 2495 46402301.92001 +2590 2495 -5277700.460655 +2591 2495 -49602960.36391 +2592 2495 16581478.26512 +2593 2495 11857600.23336 +2594 2495 -32981587.68983 +2601 2495 439821.2585788 +2602 2495 -27269599.07773 +2603 2495 -221502.6772963 +2604 2495 1759285.033468 +2605 2495 -21110801.83222 +2606 2495 -68142578.48796 +2607 2495 439821.258594 +2608 2495 48380400.90995 +2609 2495 -100781580.1802 +2619 2495 -7125466.187114 +2620 2495 -7107677.550651 +2621 2495 -9517594.142065 +2622 2495 -48161586.95346 +2623 2495 -5277700.460655 +2624 2495 -56307063.72196 +2625 2495 -17021299.52369 +2626 2495 12385378.01131 +2627 2495 -35357225.93349 +2496 2496 773558827.9862 +2497 2496 2.658367156982e-05 +2498 2496 7037140.130311 +2499 2496 85893349.16099 +2500 2496 -1.427531242371e-05 +2501 2496 1759285.033452 +2511 2496 -73573484.51406 +2512 2496 -47777777.76993 +2513 2496 19043968.59104 +2514 2496 -188931397.8084 +2515 2496 6.824731826782e-06 +2516 2496 -3518570.065188 +2517 2496 -74622903.1185 +2518 2496 47777777.76992 +2519 2496 -20539364.73579 +2589 2496 -19278339.76952 +2590 2496 11944444.44837 +2591 2496 6685644.928532 +2592 2496 -68569574.7737 +2593 2496 9.983777999878e-07 +2594 2496 46666190.80873 +2595 2496 -28443492.38882 +2596 2496 -11944444.44837 +2597 2496 16581478.26512 +2604 2496 17734607.15466 +2605 2496 1.817941665649e-06 +2606 2496 439821.2585785 +2607 2496 103049709.0446 +2608 2496 8.106231689453e-06 +2609 2496 1759285.033469 +2610 2496 -19975421.90891 +2611 2496 -1.013278961182e-05 +2612 2496 439821.2585936 +2622 2496 -19644494.8084 +2623 2496 -11944444.44837 +2624 2496 -7125466.187114 +2625 2496 -71083613.53293 +2626 2496 2.801418304443e-06 +2627 2496 -48425475.84218 +2628 2496 -29334356.73017 +2629 2496 11944444.44836 +2630 2496 -17021299.52369 +2497 2497 658884508.4497 +2498 2497 -84443207.28729 +2499 2497 -1.427531242371e-05 +2500 2497 -95661879.74567 +2501 2497 42221603.64364 +2511 2497 -47777777.76993 +2512 2497 -59239194.56492 +2513 2497 9605400.916215 +2514 2497 6.347894668579e-06 +2515 2497 21292410.96829 +2516 2497 -21110801.83222 +2517 2497 47777777.76992 +2518 2497 -60288613.16939 +2519 2497 11505400.91601 +2589 2497 11944444.44837 +2590 2497 -15694767.28047 +2591 2497 -6579899.772699 +2592 2497 -8.195638656616e-07 +2593 2497 -16013622.55363 +2594 2497 -5277700.460655 +2595 2497 -11944444.44837 +2596 2497 -24859919.89976 +2597 2497 11857600.23336 +2604 2497 3.322958946228e-06 +2605 2497 -27654200.09436 +2606 2497 -27480710.1887 +2607 2497 7.987022399902e-06 +2608 2497 74381129.14638 +2609 2497 -21110801.83222 +2610 2497 -9.581446647644e-06 +2611 2497 -65364229.15794 +2612 2497 48591512.02092 +2622 2497 -11944444.44836 +2623 2497 -16060922.31935 +2624 2497 -7107677.550651 +2625 2497 2.488493919373e-06 +2626 2497 -18527661.31289 +2627 2497 -5277700.460655 +2628 2497 11944444.44836 +2629 2497 -25750784.24113 +2630 2497 12385378.01131 +2498 2498 691056331.5443 +2499 2498 1759285.033452 +2500 2498 42221603.64364 +2501 2498 38993777.49737 +2511 2498 18780079.70233 +2512 2498 9394289.805242 +2513 2498 -24725057.40063 +2514 2498 -3518570.065188 +2515 2498 -21110801.83222 +2516 2498 29179895.04537 +2517 2498 -20803253.6245 +2518 2498 11716512.02698 +2519 2498 -27523507.01255 +2589 2498 6685644.928532 +2590 2498 -6579899.772699 +2591 2498 -8541180.705052 +2592 2498 46402301.92001 +2593 2498 -5277700.460655 +2594 2498 -49602960.36391 +2595 2498 16581478.26512 +2596 2498 11857600.23336 +2597 2498 -32981587.68983 +2604 2498 439821.2585788 +2605 2498 -27269599.07773 +2606 2498 -221502.6772963 +2607 2498 1759285.033468 +2608 2498 -21110801.83222 +2609 2498 -68142578.48796 +2610 2498 439821.258594 +2611 2498 48380400.90995 +2612 2498 -100781580.1802 +2622 2498 -7125466.187114 +2623 2498 -7107677.550651 +2624 2498 -9517594.142065 +2625 2498 -48161586.95346 +2626 2498 -5277700.460655 +2627 2498 -56307063.72196 +2628 2498 -17021299.52369 +2629 2498 12385378.01131 +2630 2498 -35357225.93349 +2499 2499 840410334.4004 +2500 2499 47827148.55553 +2501 2499 23749508.53569 +2502 2499 8066610.522678 +2503 2499 -47797526.08417 +2504 2499 20547636.30415 +2514 2499 -73573484.51406 +2515 2499 -47777777.76993 +2516 2499 19043968.59104 +2517 2499 -188931397.8084 +2518 2499 6.824731826782e-06 +2519 2499 -3518570.065188 +2520 2499 -74622903.1185 +2521 2499 47777777.76992 +2522 2499 -20539364.73579 +2592 2499 -19278339.76952 +2593 2499 11944444.44837 +2594 2499 6685644.928532 +2595 2499 -83208406.42019 +2596 2499 -11951850.06621 +2597 2499 42498171.10922 +2607 2499 17734607.15466 +2608 2499 1.817941665649e-06 +2609 2499 439821.2585785 +2610 2499 125282026.2887 +2611 2499 11956787.14478 +2612 2499 5935098.98454 +2613 2499 -32275376.32772 +2614 2499 -11949381.52693 +2615 2499 17028332.3953 +2625 2499 -19644494.8084 +2626 2499 -11944444.44837 +2627 2499 -7125466.187114 +2628 2499 -71083613.53293 +2629 2499 2.801418304443e-06 +2630 2499 -48425475.84218 +2631 2499 -29334356.73017 +2632 2499 11944444.44836 +2633 2499 -17021299.52369 +2500 2500 711379506.5777 +2501 2500 -65443950.97306 +2502 2500 -47807400.24129 +2503 2500 -159193824.4844 +2504 2500 35050823.25634 +2514 2500 -47777777.76993 +2515 2500 -59239194.56492 +2516 2500 9605400.916215 +2517 2500 6.347894668579e-06 +2518 2500 21292410.96829 +2519 2500 -21110801.83222 +2520 2500 47777777.76992 +2521 2500 -60288613.16939 +2522 2500 11505400.91601 +2592 2500 11944444.44837 +2593 2500 -15694767.28047 +2594 2500 -6579899.772699 +2595 2500 -11949381.52693 +2596 2500 -27053453.11441 +2597 2500 3626698.329752 +2607 2500 3.322958946228e-06 +2608 2500 -27654200.09436 +2609 2500 -27480710.1887 +2610 2500 11956787.14477 +2611 2500 93024319.31714 +2612 2500 -16362810.24847 +2613 2500 -11951850.06621 +2614 2500 -74090485.10009 +2615 2500 46808583.40323 +2625 2500 -11944444.44836 +2626 2500 -16060922.31935 +2627 2500 -7107677.550651 +2628 2500 2.488493919373e-06 +2629 2500 -18527661.31289 +2630 2500 -5277700.460655 +2631 2500 11944444.44836 +2632 2500 -25750784.24113 +2633 2500 12385378.01131 +2501 2501 697590331.8784 +2502 2501 20815660.97705 +2503 2501 40965061.2198 +2504 2501 2966205.148247 +2514 2501 18780079.70233 +2515 2501 9394289.805242 +2516 2501 -24725057.40063 +2517 2501 -3518570.065188 +2518 2501 -21110801.83222 +2519 2501 29179895.04537 +2520 2501 -20803253.6245 +2521 2501 11716512.02698 +2522 2501 -27523507.01255 +2592 2501 6685644.928532 +2593 2501 -6579899.772699 +2594 2501 -8541180.705052 +2595 2501 42233282.34386 +2596 2501 2150097.608279 +2597 2501 -45715547.88649 +2607 2501 439821.2585788 +2608 2501 -27269599.07773 +2609 2501 -221502.6772963 +2610 2501 5939995.986973 +2611 2501 -16358892.70393 +2612 2501 -51790570.05088 +2613 2501 17031848.8311 +2614 2501 48076086.23075 +2615 2501 -90703859.27092 +2625 2501 -7125466.187114 +2626 2501 -7107677.550651 +2627 2501 -9517594.142065 +2628 2501 -48161586.95346 +2629 2501 -5277700.460655 +2630 2501 -56307063.72196 +2631 2501 -17021299.52369 +2632 2501 12385378.01131 +2633 2501 -35357225.93349 +2502 2502 414827357.504 +2503 2502 -20340871.50549 +2504 2502 -9724189.681112 +2517 2502 -73573484.51406 +2518 2502 -47777777.76993 +2519 2502 19043968.59104 +2520 2502 -113444843.5246 +2521 2502 20210194.63973 +2522 2502 -1877986.414888 +2523 2502 -111796877.2832 +2524 2502 38352899.08171 +2525 2502 -2121078.875016 +2595 2502 1810230.00851 +2596 2502 14340738.95588 +2597 2502 8290807.874965 +2610 2502 -3359294.569133 +2611 2502 -11951850.06621 +2612 2502 -6689786.134111 +2613 2502 55048606.88105 +2614 2502 -3993837.276312 +2615 2502 4300879.130003 +2628 2502 -19644494.8084 +2629 2502 -11944444.44837 +2630 2502 -7125466.187114 +2631 2502 -46850477.23879 +2632 2502 3967148.114668 +2633 2502 -32629853.81604 +2634 2502 -26982829.38238 +2635 2502 9582244.720342 +2636 2502 -3892991.07326 +2503 2503 564039483.2591 +2504 2503 -65106018.41226 +2517 2503 -47777777.76993 +2518 2503 -59239194.56492 +2519 2503 9605400.916215 +2520 2503 20144856.20685 +2521 2503 80868506.6064 +2522 2503 -14973710.12356 +2523 2503 57529348.62257 +2524 2503 -302396208.1114 +2525 2503 17278369.45958 +2595 2503 9560492.637254 +2596 2503 1810230.008509 +2597 2503 -4421798.559475 +2610 2503 -11949381.52693 +2611 2503 -45174403.34149 +2612 2503 -27804612.20634 +2613 2503 -3993837.276313 +2614 2503 82661789.79505 +2615 2503 -10169382.16459 +2628 2503 -11944444.44836 +2629 2503 -16060922.31935 +2630 2503 -7107677.550651 +2631 2503 3953803.533843 +2632 2503 2200024.266784 +2633 2503 -395237.0216989 +2634 2503 14373367.08051 +2635 2503 -65414977.51864 +2636 2503 21026558.24452 +2504 2504 423445398.9633 +2517 2504 18780079.70233 +2518 2504 9394289.805242 +2519 2504 -24725057.40063 +2520 2504 -7679074.462877 +2521 2504 -14123216.23606 +2522 2504 36715829.09565 +2523 2504 -3181618.312524 +2524 2504 16437776.1764 +2525 2504 -107525675.2604 +2595 2504 5527205.249977 +2596 2504 -6632697.839212 +2597 2504 4827280.022694 +2610 2504 -6688405.732252 +2611 2504 -29072115.16194 +2612 2504 -13594307.9147 +2613 2504 -8545064.987078 +2614 2504 -20005612.70897 +2615 2504 -20483373.72889 +2628 2504 -7125466.187114 +2629 2504 -7107677.550651 +2630 2504 -9517594.142065 +2631 2504 -33948397.04199 +2632 2504 39261.12256241 +2633 2504 -34318631.6447 +2634 2504 -5839486.60989 +2635 2504 19470618.25085 +2636 2504 -33522063.55007 +2505 2505 773558827.9862 +2506 2505 2.658367156982e-05 +2507 2505 7037140.130311 +2508 2505 85893349.16099 +2509 2505 -1.427531242371e-05 +2510 2505 1759285.033452 +2526 2505 -188931397.8084 +2527 2505 6.824731826782e-06 +2528 2505 -3518570.065188 +2529 2505 -74622903.1185 +2530 2505 47777777.76992 +2531 2505 -20539364.73579 +2598 2505 -68569574.7737 +2599 2505 9.983777999878e-07 +2600 2505 46666190.80873 +2601 2505 -28443492.38882 +2602 2505 -11944444.44837 +2603 2505 16581478.26512 +2616 2505 103049709.0446 +2617 2505 8.106231689453e-06 +2618 2505 1759285.033469 +2619 2505 -19975421.90891 +2620 2505 -1.013278961182e-05 +2621 2505 439821.2585936 +2637 2505 -71083613.53293 +2638 2505 2.801418304443e-06 +2639 2505 -48425475.84218 +2640 2505 -29334356.73017 +2641 2505 11944444.44836 +2642 2505 -17021299.52369 +2506 2506 658884508.4497 +2507 2506 -84443207.28729 +2508 2506 -1.427531242371e-05 +2509 2506 -95661879.74567 +2510 2506 42221603.64364 +2526 2506 6.347894668579e-06 +2527 2506 21292410.96829 +2528 2506 -21110801.83222 +2529 2506 47777777.76992 +2530 2506 -60288613.16939 +2531 2506 11505400.91601 +2598 2506 -8.195638656616e-07 +2599 2506 -16013622.55363 +2600 2506 -5277700.460655 +2601 2506 -11944444.44837 +2602 2506 -24859919.89976 +2603 2506 11857600.23336 +2616 2506 7.987022399902e-06 +2617 2506 74381129.14638 +2618 2506 -21110801.83222 +2619 2506 -9.581446647644e-06 +2620 2506 -65364229.15794 +2621 2506 48591512.02092 +2637 2506 2.488493919373e-06 +2638 2506 -18527661.31289 +2639 2506 -5277700.460655 +2640 2506 11944444.44836 +2641 2506 -25750784.24113 +2642 2506 12385378.01131 +2507 2507 691056331.5443 +2508 2507 1759285.033452 +2509 2507 42221603.64364 +2510 2507 38993777.49737 +2526 2507 -3518570.065188 +2527 2507 -21110801.83222 +2528 2507 29179895.04537 +2529 2507 -20803253.6245 +2530 2507 11716512.02698 +2531 2507 -27523507.01255 +2598 2507 46402301.92001 +2599 2507 -5277700.460655 +2600 2507 -49602960.36391 +2601 2507 16581478.26512 +2602 2507 11857600.23336 +2603 2507 -32981587.68983 +2616 2507 1759285.033468 +2617 2507 -21110801.83222 +2618 2507 -68142578.48796 +2619 2507 439821.258594 +2620 2507 48380400.90995 +2621 2507 -100781580.1802 +2637 2507 -48161586.95346 +2638 2507 -5277700.460655 +2639 2507 -56307063.72196 +2640 2507 -17021299.52369 +2641 2507 12385378.01131 +2642 2507 -35357225.93349 +2508 2508 773558827.9862 +2509 2508 2.658367156982e-05 +2510 2508 7037140.130311 +2511 2508 85893349.16099 +2512 2508 -1.427531242371e-05 +2513 2508 1759285.033452 +2526 2508 -73573484.51406 +2527 2508 -47777777.76993 +2528 2508 19043968.59104 +2529 2508 -188931397.8084 +2530 2508 6.824731826782e-06 +2531 2508 -3518570.065188 +2532 2508 -74622903.1185 +2533 2508 47777777.76992 +2534 2508 -20539364.73579 +2598 2508 -19278339.76952 +2599 2508 11944444.44837 +2600 2508 6685644.928532 +2601 2508 -68569574.7737 +2602 2508 9.983777999878e-07 +2603 2508 46666190.80873 +2604 2508 -28443492.38882 +2605 2508 -11944444.44837 +2606 2508 16581478.26512 +2616 2508 17734607.15466 +2617 2508 1.817941665649e-06 +2618 2508 439821.2585785 +2619 2508 103049709.0446 +2620 2508 8.106231689453e-06 +2621 2508 1759285.033469 +2622 2508 -19975421.90891 +2623 2508 -1.013278961182e-05 +2624 2508 439821.2585936 +2637 2508 -19644494.8084 +2638 2508 -11944444.44837 +2639 2508 -7125466.187114 +2640 2508 -71083613.53293 +2641 2508 2.801418304443e-06 +2642 2508 -48425475.84218 +2643 2508 -29334356.73017 +2644 2508 11944444.44836 +2645 2508 -17021299.52369 +2509 2509 658884508.4497 +2510 2509 -84443207.28729 +2511 2509 -1.427531242371e-05 +2512 2509 -95661879.74567 +2513 2509 42221603.64364 +2526 2509 -47777777.76993 +2527 2509 -59239194.56492 +2528 2509 9605400.916215 +2529 2509 6.347894668579e-06 +2530 2509 21292410.96829 +2531 2509 -21110801.83222 +2532 2509 47777777.76992 +2533 2509 -60288613.16939 +2534 2509 11505400.91601 +2598 2509 11944444.44837 +2599 2509 -15694767.28047 +2600 2509 -6579899.772699 +2601 2509 -8.195638656616e-07 +2602 2509 -16013622.55363 +2603 2509 -5277700.460655 +2604 2509 -11944444.44837 +2605 2509 -24859919.89976 +2606 2509 11857600.23336 +2616 2509 3.322958946228e-06 +2617 2509 -27654200.09436 +2618 2509 -27480710.1887 +2619 2509 7.987022399902e-06 +2620 2509 74381129.14638 +2621 2509 -21110801.83222 +2622 2509 -9.581446647644e-06 +2623 2509 -65364229.15794 +2624 2509 48591512.02092 +2637 2509 -11944444.44836 +2638 2509 -16060922.31935 +2639 2509 -7107677.550651 +2640 2509 2.488493919373e-06 +2641 2509 -18527661.31289 +2642 2509 -5277700.460655 +2643 2509 11944444.44836 +2644 2509 -25750784.24113 +2645 2509 12385378.01131 +2510 2510 691056331.5443 +2511 2510 1759285.033452 +2512 2510 42221603.64364 +2513 2510 38993777.49737 +2526 2510 18780079.70233 +2527 2510 9394289.805242 +2528 2510 -24725057.40063 +2529 2510 -3518570.065188 +2530 2510 -21110801.83222 +2531 2510 29179895.04537 +2532 2510 -20803253.6245 +2533 2510 11716512.02698 +2534 2510 -27523507.01255 +2598 2510 6685644.928532 +2599 2510 -6579899.772699 +2600 2510 -8541180.705052 +2601 2510 46402301.92001 +2602 2510 -5277700.460655 +2603 2510 -49602960.36391 +2604 2510 16581478.26512 +2605 2510 11857600.23336 +2606 2510 -32981587.68983 +2616 2510 439821.2585788 +2617 2510 -27269599.07773 +2618 2510 -221502.6772963 +2619 2510 1759285.033468 +2620 2510 -21110801.83222 +2621 2510 -68142578.48796 +2622 2510 439821.258594 +2623 2510 48380400.90995 +2624 2510 -100781580.1802 +2637 2510 -7125466.187114 +2638 2510 -7107677.550651 +2639 2510 -9517594.142065 +2640 2510 -48161586.95346 +2641 2510 -5277700.460655 +2642 2510 -56307063.72196 +2643 2510 -17021299.52369 +2644 2510 12385378.01131 +2645 2510 -35357225.93349 +2511 2511 773558827.9862 +2512 2511 2.658367156982e-05 +2513 2511 7037140.130311 +2514 2511 85893349.16099 +2515 2511 -1.427531242371e-05 +2516 2511 1759285.033452 +2529 2511 -73573484.51406 +2530 2511 -47777777.76993 +2531 2511 19043968.59104 +2532 2511 -188931397.8084 +2533 2511 6.824731826782e-06 +2534 2511 -3518570.065188 +2535 2511 -74622903.1185 +2536 2511 47777777.76992 +2537 2511 -20539364.73579 +2601 2511 -19278339.76952 +2602 2511 11944444.44837 +2603 2511 6685644.928532 +2604 2511 -68569574.7737 +2605 2511 9.983777999878e-07 +2606 2511 46666190.80873 +2607 2511 -28443492.38882 +2608 2511 -11944444.44837 +2609 2511 16581478.26512 +2619 2511 17734607.15466 +2620 2511 1.817941665649e-06 +2621 2511 439821.2585785 +2622 2511 103049709.0446 +2623 2511 8.106231689453e-06 +2624 2511 1759285.033469 +2625 2511 -19975421.90891 +2626 2511 -1.013278961182e-05 +2627 2511 439821.2585936 +2640 2511 -19644494.8084 +2641 2511 -11944444.44837 +2642 2511 -7125466.187114 +2643 2511 -71083613.53293 +2644 2511 2.801418304443e-06 +2645 2511 -48425475.84218 +2646 2511 -29334356.73017 +2647 2511 11944444.44836 +2648 2511 -17021299.52369 +2512 2512 658884508.4497 +2513 2512 -84443207.28729 +2514 2512 -1.427531242371e-05 +2515 2512 -95661879.74567 +2516 2512 42221603.64364 +2529 2512 -47777777.76993 +2530 2512 -59239194.56492 +2531 2512 9605400.916215 +2532 2512 6.347894668579e-06 +2533 2512 21292410.96829 +2534 2512 -21110801.83222 +2535 2512 47777777.76992 +2536 2512 -60288613.16939 +2537 2512 11505400.91601 +2601 2512 11944444.44837 +2602 2512 -15694767.28047 +2603 2512 -6579899.772699 +2604 2512 -8.195638656616e-07 +2605 2512 -16013622.55363 +2606 2512 -5277700.460655 +2607 2512 -11944444.44837 +2608 2512 -24859919.89976 +2609 2512 11857600.23336 +2619 2512 3.322958946228e-06 +2620 2512 -27654200.09436 +2621 2512 -27480710.1887 +2622 2512 7.987022399902e-06 +2623 2512 74381129.14638 +2624 2512 -21110801.83222 +2625 2512 -9.581446647644e-06 +2626 2512 -65364229.15794 +2627 2512 48591512.02092 +2640 2512 -11944444.44836 +2641 2512 -16060922.31935 +2642 2512 -7107677.550651 +2643 2512 2.488493919373e-06 +2644 2512 -18527661.31289 +2645 2512 -5277700.460655 +2646 2512 11944444.44836 +2647 2512 -25750784.24113 +2648 2512 12385378.01131 +2513 2513 691056331.5443 +2514 2513 1759285.033452 +2515 2513 42221603.64364 +2516 2513 38993777.49737 +2529 2513 18780079.70233 +2530 2513 9394289.805242 +2531 2513 -24725057.40063 +2532 2513 -3518570.065188 +2533 2513 -21110801.83222 +2534 2513 29179895.04537 +2535 2513 -20803253.6245 +2536 2513 11716512.02698 +2537 2513 -27523507.01255 +2601 2513 6685644.928532 +2602 2513 -6579899.772699 +2603 2513 -8541180.705052 +2604 2513 46402301.92001 +2605 2513 -5277700.460655 +2606 2513 -49602960.36391 +2607 2513 16581478.26512 +2608 2513 11857600.23336 +2609 2513 -32981587.68983 +2619 2513 439821.2585788 +2620 2513 -27269599.07773 +2621 2513 -221502.6772963 +2622 2513 1759285.033468 +2623 2513 -21110801.83222 +2624 2513 -68142578.48796 +2625 2513 439821.258594 +2626 2513 48380400.90995 +2627 2513 -100781580.1802 +2640 2513 -7125466.187114 +2641 2513 -7107677.550651 +2642 2513 -9517594.142065 +2643 2513 -48161586.95346 +2644 2513 -5277700.460655 +2645 2513 -56307063.72196 +2646 2513 -17021299.52369 +2647 2513 12385378.01131 +2648 2513 -35357225.93349 +2514 2514 773558827.9862 +2515 2514 2.658367156982e-05 +2516 2514 7037140.130311 +2517 2514 85893349.16099 +2518 2514 -1.427531242371e-05 +2519 2514 1759285.033452 +2532 2514 -73573484.51406 +2533 2514 -47777777.76993 +2534 2514 19043968.59104 +2535 2514 -188931397.8084 +2536 2514 6.824731826782e-06 +2537 2514 -3518570.065188 +2538 2514 -74622903.1185 +2539 2514 47777777.76992 +2540 2514 -20539364.73579 +2604 2514 -19278339.76952 +2605 2514 11944444.44837 +2606 2514 6685644.928532 +2607 2514 -68569574.7737 +2608 2514 9.983777999878e-07 +2609 2514 46666190.80873 +2610 2514 -28443492.38882 +2611 2514 -11944444.44837 +2612 2514 16581478.26512 +2622 2514 17734607.15466 +2623 2514 1.817941665649e-06 +2624 2514 439821.2585785 +2625 2514 103049709.0446 +2626 2514 8.106231689453e-06 +2627 2514 1759285.033469 +2628 2514 -19975421.90891 +2629 2514 -1.013278961182e-05 +2630 2514 439821.2585936 +2643 2514 -19644494.8084 +2644 2514 -11944444.44837 +2645 2514 -7125466.187114 +2646 2514 -71083613.53293 +2647 2514 2.801418304443e-06 +2648 2514 -48425475.84218 +2649 2514 -29334356.73017 +2650 2514 11944444.44836 +2651 2514 -17021299.52369 +2515 2515 658884508.4497 +2516 2515 -84443207.28729 +2517 2515 -1.427531242371e-05 +2518 2515 -95661879.74567 +2519 2515 42221603.64364 +2532 2515 -47777777.76993 +2533 2515 -59239194.56492 +2534 2515 9605400.916215 +2535 2515 6.347894668579e-06 +2536 2515 21292410.96829 +2537 2515 -21110801.83222 +2538 2515 47777777.76992 +2539 2515 -60288613.16939 +2540 2515 11505400.91601 +2604 2515 11944444.44837 +2605 2515 -15694767.28047 +2606 2515 -6579899.772699 +2607 2515 -8.195638656616e-07 +2608 2515 -16013622.55363 +2609 2515 -5277700.460655 +2610 2515 -11944444.44837 +2611 2515 -24859919.89976 +2612 2515 11857600.23336 +2622 2515 3.322958946228e-06 +2623 2515 -27654200.09436 +2624 2515 -27480710.1887 +2625 2515 7.987022399902e-06 +2626 2515 74381129.14638 +2627 2515 -21110801.83222 +2628 2515 -9.581446647644e-06 +2629 2515 -65364229.15794 +2630 2515 48591512.02092 +2643 2515 -11944444.44836 +2644 2515 -16060922.31935 +2645 2515 -7107677.550651 +2646 2515 2.488493919373e-06 +2647 2515 -18527661.31289 +2648 2515 -5277700.460655 +2649 2515 11944444.44836 +2650 2515 -25750784.24113 +2651 2515 12385378.01131 +2516 2516 691056331.5443 +2517 2516 1759285.033452 +2518 2516 42221603.64364 +2519 2516 38993777.49737 +2532 2516 18780079.70233 +2533 2516 9394289.805242 +2534 2516 -24725057.40063 +2535 2516 -3518570.065188 +2536 2516 -21110801.83222 +2537 2516 29179895.04537 +2538 2516 -20803253.6245 +2539 2516 11716512.02698 +2540 2516 -27523507.01255 +2604 2516 6685644.928532 +2605 2516 -6579899.772699 +2606 2516 -8541180.705052 +2607 2516 46402301.92001 +2608 2516 -5277700.460655 +2609 2516 -49602960.36391 +2610 2516 16581478.26512 +2611 2516 11857600.23336 +2612 2516 -32981587.68983 +2622 2516 439821.2585788 +2623 2516 -27269599.07773 +2624 2516 -221502.6772963 +2625 2516 1759285.033468 +2626 2516 -21110801.83222 +2627 2516 -68142578.48796 +2628 2516 439821.258594 +2629 2516 48380400.90995 +2630 2516 -100781580.1802 +2643 2516 -7125466.187114 +2644 2516 -7107677.550651 +2645 2516 -9517594.142065 +2646 2516 -48161586.95346 +2647 2516 -5277700.460655 +2648 2516 -56307063.72196 +2649 2516 -17021299.52369 +2650 2516 12385378.01131 +2651 2516 -35357225.93349 +2517 2517 773558827.9862 +2518 2517 2.658367156982e-05 +2519 2517 7037140.130311 +2520 2517 85893349.16099 +2521 2517 -1.427531242371e-05 +2522 2517 1759285.033452 +2535 2517 -73573484.51406 +2536 2517 -47777777.76993 +2537 2517 19043968.59104 +2538 2517 -188931397.8084 +2539 2517 6.824731826782e-06 +2540 2517 -3518570.065188 +2541 2517 -74622903.1185 +2542 2517 47777777.76992 +2543 2517 -20539364.73579 +2607 2517 -19278339.76952 +2608 2517 11944444.44837 +2609 2517 6685644.928532 +2610 2517 -68569574.7737 +2611 2517 9.983777999878e-07 +2612 2517 46666190.80873 +2613 2517 -28443492.38882 +2614 2517 -11944444.44837 +2615 2517 16581478.26512 +2625 2517 17734607.15466 +2626 2517 1.817941665649e-06 +2627 2517 439821.2585785 +2628 2517 103049709.0446 +2629 2517 8.106231689453e-06 +2630 2517 1759285.033469 +2631 2517 -19975421.90891 +2632 2517 -1.013278961182e-05 +2633 2517 439821.2585936 +2646 2517 -19644494.8084 +2647 2517 -11944444.44837 +2648 2517 -7125466.187114 +2649 2517 -71083613.53293 +2650 2517 2.801418304443e-06 +2651 2517 -48425475.84218 +2652 2517 -29334356.73017 +2653 2517 11944444.44836 +2654 2517 -17021299.52369 +2518 2518 658884508.4497 +2519 2518 -84443207.28729 +2520 2518 -1.427531242371e-05 +2521 2518 -95661879.74567 +2522 2518 42221603.64364 +2535 2518 -47777777.76993 +2536 2518 -59239194.56492 +2537 2518 9605400.916215 +2538 2518 6.347894668579e-06 +2539 2518 21292410.96829 +2540 2518 -21110801.83222 +2541 2518 47777777.76992 +2542 2518 -60288613.16939 +2543 2518 11505400.91601 +2607 2518 11944444.44837 +2608 2518 -15694767.28047 +2609 2518 -6579899.772699 +2610 2518 -8.195638656616e-07 +2611 2518 -16013622.55363 +2612 2518 -5277700.460655 +2613 2518 -11944444.44837 +2614 2518 -24859919.89976 +2615 2518 11857600.23336 +2625 2518 3.322958946228e-06 +2626 2518 -27654200.09436 +2627 2518 -27480710.1887 +2628 2518 7.987022399902e-06 +2629 2518 74381129.14638 +2630 2518 -21110801.83222 +2631 2518 -9.581446647644e-06 +2632 2518 -65364229.15794 +2633 2518 48591512.02092 +2646 2518 -11944444.44836 +2647 2518 -16060922.31935 +2648 2518 -7107677.550651 +2649 2518 2.488493919373e-06 +2650 2518 -18527661.31289 +2651 2518 -5277700.460655 +2652 2518 11944444.44836 +2653 2518 -25750784.24113 +2654 2518 12385378.01131 +2519 2519 691056331.5443 +2520 2519 1759285.033452 +2521 2519 42221603.64364 +2522 2519 38993777.49737 +2535 2519 18780079.70233 +2536 2519 9394289.805242 +2537 2519 -24725057.40063 +2538 2519 -3518570.065188 +2539 2519 -21110801.83222 +2540 2519 29179895.04537 +2541 2519 -20803253.6245 +2542 2519 11716512.02698 +2543 2519 -27523507.01255 +2607 2519 6685644.928532 +2608 2519 -6579899.772699 +2609 2519 -8541180.705052 +2610 2519 46402301.92001 +2611 2519 -5277700.460655 +2612 2519 -49602960.36391 +2613 2519 16581478.26512 +2614 2519 11857600.23336 +2615 2519 -32981587.68983 +2625 2519 439821.2585788 +2626 2519 -27269599.07773 +2627 2519 -221502.6772963 +2628 2519 1759285.033468 +2629 2519 -21110801.83222 +2630 2519 -68142578.48796 +2631 2519 439821.258594 +2632 2519 48380400.90995 +2633 2519 -100781580.1802 +2646 2519 -7125466.187114 +2647 2519 -7107677.550651 +2648 2519 -9517594.142065 +2649 2519 -48161586.95346 +2650 2519 -5277700.460655 +2651 2519 -56307063.72196 +2652 2519 -17021299.52369 +2653 2519 12385378.01131 +2654 2519 -35357225.93349 +2520 2520 661143350.3463 +2521 2520 13618540.72033 +2522 2520 5989102.104141 +2523 2520 -101035987.8533 +2524 2520 -87387069.812 +2525 2520 5160549.700649 +2538 2520 -73573484.51406 +2539 2520 -47777777.76993 +2540 2520 19043968.59104 +2541 2520 -129151830.3037 +2542 2520 28408228.69302 +2543 2520 -1228671.263296 +2544 2520 -50340940.25329 +2545 2520 25215444.19182 +2546 2520 -2240873.326595 +2610 2520 -19278339.76952 +2611 2520 11944444.44837 +2612 2520 6685644.928532 +2613 2520 -43931936.15608 +2614 2520 3953803.533843 +2615 2520 30281323.54341 +2628 2520 17734607.15466 +2629 2520 1.817941665649e-06 +2630 2520 439821.2585785 +2631 2520 98285811.20611 +2632 2520 3290506.566172 +2633 2520 1546926.362953 +2634 2520 -39364297.46372 +2635 2520 -21070750.36619 +2636 2520 13769148.13469 +2649 2520 -19644494.8084 +2650 2520 -11944444.44837 +2651 2520 -7125466.187114 +2652 2520 -56246818.4596 +2653 2520 6794385.619339 +2654 2520 -40777663.34128 +2655 2520 -19457886.36742 +2656 2520 7032054.646846 +2657 2520 -4791657.828043 +2521 2521 750451146.4559 +2522 2521 -58171951.50429 +2523 2521 -87452408.24488 +2524 2521 -290974733.7609 +2525 2521 11075712.80635 +2538 2521 -47777777.76993 +2539 2521 -59239194.56492 +2540 2521 9605400.916215 +2541 2521 28408228.69302 +2542 2521 28079220.69954 +2543 2521 -11305000.42828 +2544 2521 25215444.19182 +2545 2521 -148367742.5811 +2546 2521 6448432.317586 +2610 2521 11944444.44837 +2611 2521 -15694767.28047 +2612 2521 -6579899.772699 +2613 2521 3967148.114666 +2614 2521 5118565.349512 +2615 2521 -6805898.764872 +2628 2521 3.322958946228e-06 +2629 2521 -27654200.09436 +2630 2521 -27480710.1887 +2631 2521 3290506.566169 +2632 2521 116187098.4075 +2633 2521 -14193581.10448 +2634 2521 -21084094.94702 +2635 2521 -86047416.47364 +2636 2521 42749757.90501 +2649 2521 -11944444.44836 +2650 2521 -16060922.31935 +2651 2521 -7107677.550651 +2652 2521 6794385.619338 +2653 2521 -15664941.07429 +2654 2521 3794011.966557 +2655 2521 7032054.646846 +2656 2521 -42086771.17886 +2657 2521 18179794.31644 +2522 2522 595375909.2707 +2523 2522 5165533.582777 +2524 2522 11082175.68687 +2525 2522 -72701184.11614 +2538 2522 18780079.70233 +2539 2522 9394289.805242 +2540 2522 -24725057.40063 +2541 2522 -7034226.817899 +2542 2522 -11305000.42828 +2543 2522 38156861.57885 +2544 2522 -2240873.326075 +2545 2522 6448432.317585 +2546 2522 -37981402.40673 +2610 2522 6685644.928532 +2611 2522 -6579899.772699 +2612 2522 -8541180.705052 +2613 2522 31599866.76936 +2614 2522 -6795843.015341 +2615 2522 -26535855.42407 +2628 2522 439821.2585788 +2629 2522 -27269599.07773 +2630 2522 -221502.6772963 +2631 2522 1556203.815474 +2632 2522 -13341714.07747 +2633 2522 -32667374.4372 +2634 2522 13774810.33564 +2635 2522 42743511.30837 +2636 2522 -59721377.20001 +2649 2522 -7125466.187114 +2650 2522 -7107677.550651 +2651 2522 -9517594.142065 +2652 2522 -42097107.78484 +2653 2522 4005123.078997 +2654 2522 -52469144.20003 +2655 2522 -4791657.828043 +2656 2522 18179794.31644 +2657 2522 -28734916.98485 +2523 2523 523303156.7564 +2524 2523 18508164.24143 +2525 2523 -41775.96088886 +2541 2523 -75675730.3705 +2542 2523 -44546650.89538 +2543 2523 2598546.349347 +2544 2523 -16392499.20861 +2545 2523 41849759.38176 +2546 2523 -1875236.03192 +2547 2523 58848606.59511 +2548 2523 -24831769.03377 +2549 2523 1359.619889617 +2550 2523 -16689329.37432 +2551 2523 38943555.92827 +2552 2523 -555698.1348699 +2613 2523 -23767663.79374 +2614 2523 14373367.08051 +2615 2523 4250012.242433 +2631 2523 -33756445.01475 +2632 2523 -21084094.94702 +2633 2523 -11278021.84509 +2634 2523 33974829.94332 +2635 2523 4345910.00941 +2636 2523 9803417.164491 +2652 2523 -24574481.29388 +2653 2523 -11253340.76984 +2654 2523 -11852637.55666 +2655 2523 -48054442.14957 +2656 2523 9814966.021255 +2657 2523 -49454271.31342 +2658 2523 -15833393.4173 +2659 2523 -6043520.287572 +2660 2523 12381289.62259 +2661 2523 -18260108.90285 +2662 2523 9846712.893254 +2663 2523 -12133677.20358 +2524 2524 812493800.1257 +2525 2524 -22728114.4994 +2541 2524 -44546650.89538 +2542 2524 -36336145.54889 +2543 2524 -134262.3811041 +2544 2524 41849759.38176 +2545 2524 153232218.2128 +2546 2524 -3929309.634979 +2547 2524 -5720657.925795 +2548 2524 -33546371.83474 +2549 2524 427600.0767067 +2550 2524 38943555.92827 +2551 2524 -41911219.82108 +2552 2524 512395.3812619 +2613 2524 9582244.720342 +2614 2524 -62199811.93 +2615 2524 -12610438.76902 +2631 2524 -21070750.3662 +2632 2524 -80439564.02468 +2633 2524 -37406752.97443 +2634 2524 4345910.009409 +2635 2524 96101627.0792 +2636 2524 -3613158.842714 +2652 2524 -11253340.76984 +2653 2524 -15237473.62937 +2654 2524 -10009880.35657 +2655 2524 9814966.021255 +2656 2524 -5324672.171355 +2657 2524 5709888.680204 +2658 2524 -1265742.508225 +2659 2524 -38961976.03075 +2660 2524 33439396.27524 +2661 2524 9846712.893254 +2662 2524 -24209833.92182 +2663 2524 16792659.13732 +2525 2525 620870306.405 +2541 2525 2598546.349607 +2542 2525 -134262.380896 +2543 2525 -13607944.83238 +2544 2525 -1875236.03192 +2545 2525 -3929309.634979 +2546 2525 153090382.0159 +2547 2525 1359.619892359 +2548 2525 427600.0767067 +2549 2525 92846755.87184 +2550 2525 -555698.1346104 +2551 2525 512395.381262 +2552 2525 21857597.94702 +2613 2525 2833341.494955 +2614 2525 -13745254.78106 +2615 2525 -24948288.64704 +2631 2525 -11274406.6552 +2632 2525 -37415415.51588 +2633 2525 -44767104.00273 +2634 2525 -9800471.721178 +2635 2525 -6318823.715466 +2636 2525 -94950833.35383 +2652 2525 -11852637.55666 +2653 2525 -10009880.35657 +2654 2525 -18339788.46327 +2655 2525 -49454271.31368 +2656 2525 5709888.681464 +2657 2525 -74385394.46558 +2658 2525 4256289.621493 +2659 2525 33439396.27524 +2660 2525 -58703814.84431 +2661 2525 -12133677.20358 +2662 2525 16792659.13732 +2663 2525 -31295988.5666 +2526 2526 386779413.9931 +2527 2526 1.430511474609e-05 +2528 2526 3518570.065155 +2529 2526 42964164.89056 +2530 2526 9555555.55398 +2531 2526 -2418968.594168 +2616 2526 -68569574.7737 +2617 2526 9.983777999878e-07 +2618 2526 46666190.80873 +2619 2526 -28443492.38882 +2620 2526 -11944444.44837 +2621 2526 16581478.26512 +2637 2526 51507364.21225 +2638 2526 2.384185791016e-06 +2639 2526 -9262857.481274 +2640 2526 -9987710.954453 +2641 2526 2388888.889668 +2642 2526 -3140367.149584 +2527 2527 329442254.2248 +2528 2527 -42221603.64364 +2529 2527 -9555555.55399 +2530 2527 -47813449.56276 +2531 2527 20899690.71075 +2616 2527 -8.195638656616e-07 +2617 2527 -16013622.55363 +2618 2527 -5277700.460655 +2619 2527 -11944444.44837 +2620 2527 -24859919.89976 +2621 2527 11857600.23336 +2637 2527 1.788139343262e-06 +2638 2527 37173074.26313 +2639 2527 -10555400.91611 +2640 2527 -2388888.889678 +2641 2527 -32682114.57897 +2642 2527 24242978.23266 +2528 2528 345528165.7722 +2529 2528 5497698.071198 +2530 2528 21321912.9329 +2531 2528 19543529.57553 +2616 2528 46402301.92001 +2617 2528 -5277700.460655 +2618 2528 -49602960.36391 +2619 2528 16581478.26512 +2620 2528 11857600.23336 +2621 2528 -32981587.68983 +2637 2528 9702698.071164 +2638 2528 -10555400.91611 +2639 2528 -34117930.07082 +2640 2528 3580188.408178 +2641 2528 24242978.23277 +2642 2528 -50390790.09008 +2529 2529 386779413.9931 +2530 2529 1.430511474609e-05 +2531 2529 3518570.065155 +2532 2529 42964164.89056 +2533 2529 9555555.55398 +2534 2529 -2418968.594168 +2616 2529 -19278339.76952 +2617 2529 11944444.44837 +2618 2529 6685644.928532 +2619 2529 -68569574.7737 +2620 2529 9.983777999878e-07 +2621 2529 46666190.80873 +2622 2529 -28443492.38882 +2623 2529 -11944444.44837 +2624 2529 16581478.26512 +2637 2529 8867303.577332 +2638 2529 -2388888.889672 +2639 2529 -1161200.482275 +2640 2529 51507364.21225 +2641 2529 2.384185791016e-06 +2642 2529 -9262857.481274 +2643 2529 -9987710.954453 +2644 2529 2388888.889668 +2645 2529 -3140367.149584 +2530 2530 329442254.2248 +2531 2530 -42221603.64364 +2532 2530 -9555555.55399 +2533 2530 -47813449.56276 +2534 2530 20899690.71075 +2616 2530 11944444.44837 +2617 2530 -15694767.28047 +2618 2530 -6579899.772699 +2619 2530 -8.195638656616e-07 +2620 2530 -16013622.55363 +2621 2530 -5277700.460655 +2622 2530 -11944444.44837 +2623 2530 -24859919.89976 +2624 2530 11857600.23336 +2637 2530 2388888.889675 +2638 2530 -13827100.04718 +2639 2530 -13687577.31655 +2640 2530 1.788139343262e-06 +2641 2530 37173074.26313 +2642 2530 -10555400.91611 +2643 2530 -2388888.889678 +2644 2530 -32682114.57897 +2645 2530 24242978.23266 +2531 2531 345528165.7722 +2532 2531 5497698.071198 +2533 2531 21321912.9329 +2534 2531 19543529.57553 +2616 2531 6685644.928532 +2617 2531 -6579899.772699 +2618 2531 -8541180.705052 +2619 2531 46402301.92001 +2620 2531 -5277700.460655 +2621 2531 -49602960.36391 +2622 2531 16581478.26512 +2623 2531 11857600.23336 +2624 2531 -32981587.68983 +2637 2531 1601021.740854 +2638 2531 -13687577.31666 +2639 2531 -110751.3386485 +2640 2531 9702698.071164 +2641 2531 -10555400.91611 +2642 2531 -34117930.07082 +2643 2531 3580188.408178 +2644 2531 24242978.23277 +2645 2531 -50390790.09008 +2532 2532 386779413.9931 +2533 2532 1.430511474609e-05 +2534 2532 3518570.065155 +2535 2532 42964164.89056 +2536 2532 9555555.55398 +2537 2532 -2418968.594168 +2619 2532 -19278339.76952 +2620 2532 11944444.44837 +2621 2532 6685644.928532 +2622 2532 -68569574.7737 +2623 2532 9.983777999878e-07 +2624 2532 46666190.80873 +2625 2532 -28443492.38882 +2626 2532 -11944444.44837 +2627 2532 16581478.26512 +2640 2532 8867303.577332 +2641 2532 -2388888.889672 +2642 2532 -1161200.482275 +2643 2532 51507364.21225 +2644 2532 2.384185791016e-06 +2645 2532 -9262857.481274 +2646 2532 -9987710.954453 +2647 2532 2388888.889668 +2648 2532 -3140367.149584 +2533 2533 329442254.2248 +2534 2533 -42221603.64364 +2535 2533 -9555555.55399 +2536 2533 -47813449.56276 +2537 2533 20899690.71075 +2619 2533 11944444.44837 +2620 2533 -15694767.28047 +2621 2533 -6579899.772699 +2622 2533 -8.195638656616e-07 +2623 2533 -16013622.55363 +2624 2533 -5277700.460655 +2625 2533 -11944444.44837 +2626 2533 -24859919.89976 +2627 2533 11857600.23336 +2640 2533 2388888.889675 +2641 2533 -13827100.04718 +2642 2533 -13687577.31655 +2643 2533 1.788139343262e-06 +2644 2533 37173074.26313 +2645 2533 -10555400.91611 +2646 2533 -2388888.889678 +2647 2533 -32682114.57897 +2648 2533 24242978.23266 +2534 2534 345528165.7722 +2535 2534 5497698.071198 +2536 2534 21321912.9329 +2537 2534 19543529.57553 +2619 2534 6685644.928532 +2620 2534 -6579899.772699 +2621 2534 -8541180.705052 +2622 2534 46402301.92001 +2623 2534 -5277700.460655 +2624 2534 -49602960.36391 +2625 2534 16581478.26512 +2626 2534 11857600.23336 +2627 2534 -32981587.68983 +2640 2534 1601021.740854 +2641 2534 -13687577.31666 +2642 2534 -110751.3386485 +2643 2534 9702698.071164 +2644 2534 -10555400.91611 +2645 2534 -34117930.07082 +2646 2534 3580188.408178 +2647 2534 24242978.23277 +2648 2534 -50390790.09008 +2535 2535 386779413.9931 +2536 2535 1.430511474609e-05 +2537 2535 3518570.065155 +2538 2535 42964164.89056 +2539 2535 9555555.55398 +2540 2535 -2418968.594168 +2622 2535 -19278339.76952 +2623 2535 11944444.44837 +2624 2535 6685644.928532 +2625 2535 -68569574.7737 +2626 2535 9.983777999878e-07 +2627 2535 46666190.80873 +2628 2535 -28443492.38882 +2629 2535 -11944444.44837 +2630 2535 16581478.26512 +2643 2535 8867303.577332 +2644 2535 -2388888.889672 +2645 2535 -1161200.482275 +2646 2535 51507364.21225 +2647 2535 2.384185791016e-06 +2648 2535 -9262857.481274 +2649 2535 -9987710.954453 +2650 2535 2388888.889668 +2651 2535 -3140367.149584 +2536 2536 329442254.2248 +2537 2536 -42221603.64364 +2538 2536 -9555555.55399 +2539 2536 -47813449.56276 +2540 2536 20899690.71075 +2622 2536 11944444.44837 +2623 2536 -15694767.28047 +2624 2536 -6579899.772699 +2625 2536 -8.195638656616e-07 +2626 2536 -16013622.55363 +2627 2536 -5277700.460655 +2628 2536 -11944444.44837 +2629 2536 -24859919.89976 +2630 2536 11857600.23336 +2643 2536 2388888.889675 +2644 2536 -13827100.04718 +2645 2536 -13687577.31655 +2646 2536 1.788139343262e-06 +2647 2536 37173074.26313 +2648 2536 -10555400.91611 +2649 2536 -2388888.889678 +2650 2536 -32682114.57897 +2651 2536 24242978.23266 +2537 2537 345528165.7722 +2538 2537 5497698.071198 +2539 2537 21321912.9329 +2540 2537 19543529.57553 +2622 2537 6685644.928532 +2623 2537 -6579899.772699 +2624 2537 -8541180.705052 +2625 2537 46402301.92001 +2626 2537 -5277700.460655 +2627 2537 -49602960.36391 +2628 2537 16581478.26512 +2629 2537 11857600.23336 +2630 2537 -32981587.68983 +2643 2537 1601021.740854 +2644 2537 -13687577.31666 +2645 2537 -110751.3386485 +2646 2537 9702698.071164 +2647 2537 -10555400.91611 +2648 2537 -34117930.07082 +2649 2537 3580188.408178 +2650 2537 24242978.23277 +2651 2537 -50390790.09008 +2538 2538 386779413.9931 +2539 2538 1.430511474609e-05 +2540 2538 3518570.065155 +2541 2538 42964164.89056 +2542 2538 9555555.55398 +2543 2538 -2418968.594168 +2625 2538 -19278339.76952 +2626 2538 11944444.44837 +2627 2538 6685644.928532 +2628 2538 -68569574.7737 +2629 2538 9.983777999878e-07 +2630 2538 46666190.80873 +2631 2538 -28443492.38882 +2632 2538 -11944444.44837 +2633 2538 16581478.26512 +2646 2538 8867303.577332 +2647 2538 -2388888.889672 +2648 2538 -1161200.482275 +2649 2538 51507364.21225 +2650 2538 2.384185791016e-06 +2651 2538 -9262857.481274 +2652 2538 -9987710.954453 +2653 2538 2388888.889668 +2654 2538 -3140367.149584 +2539 2539 329442254.2248 +2540 2539 -42221603.64364 +2541 2539 -9555555.55399 +2542 2539 -47813449.56276 +2543 2539 20899690.71075 +2625 2539 11944444.44837 +2626 2539 -15694767.28047 +2627 2539 -6579899.772699 +2628 2539 -8.195638656616e-07 +2629 2539 -16013622.55363 +2630 2539 -5277700.460655 +2631 2539 -11944444.44837 +2632 2539 -24859919.89976 +2633 2539 11857600.23336 +2646 2539 2388888.889675 +2647 2539 -13827100.04718 +2648 2539 -13687577.31655 +2649 2539 1.788139343262e-06 +2650 2539 37173074.26313 +2651 2539 -10555400.91611 +2652 2539 -2388888.889678 +2653 2539 -32682114.57897 +2654 2539 24242978.23266 +2540 2540 345528165.7722 +2541 2540 5497698.071198 +2542 2540 21321912.9329 +2543 2540 19543529.57553 +2625 2540 6685644.928532 +2626 2540 -6579899.772699 +2627 2540 -8541180.705052 +2628 2540 46402301.92001 +2629 2540 -5277700.460655 +2630 2540 -49602960.36391 +2631 2540 16581478.26512 +2632 2540 11857600.23336 +2633 2540 -32981587.68983 +2646 2540 1601021.740854 +2647 2540 -13687577.31666 +2648 2540 -110751.3386485 +2649 2540 9702698.071164 +2650 2540 -10555400.91611 +2651 2540 -34117930.07082 +2652 2540 3580188.408178 +2653 2540 24242978.23277 +2654 2540 -50390790.09008 +2541 2541 379349533.0635 +2542 2541 3231845.600422 +2543 2541 17552178.32146 +2544 2541 -3096942.010396 +2545 2541 -25315645.61399 +2546 2541 1661279.921644 +2628 2541 -19278339.76952 +2629 2541 11944444.44837 +2630 2541 6685644.928532 +2631 2541 -53038741.18321 +2632 2541 6794385.61934 +2633 2541 38726503.31135 +2634 2541 -25901455.77751 +2635 2541 -11253340.76984 +2636 2541 13172362.45156 +2649 2541 8867303.577332 +2650 2541 -2388888.889672 +2651 2541 -1161200.482275 +2652 2541 47236392.63317 +2653 2541 691259.3258688 +2654 2541 -5677978.041664 +2655 2541 -16560224.88716 +2656 2541 -5787859.734054 +2657 2541 6205223.388404 +2542 2542 347028277.7135 +2543 2542 -27578620.27532 +2544 2542 -44426756.72196 +2545 2542 -90902997.98104 +2546 2542 4712791.457968 +2628 2542 11944444.44837 +2629 2542 -15694767.28047 +2630 2542 -6579899.772699 +2631 2542 6794385.619339 +2632 2542 -12456863.79788 +2633 2542 -9518488.031308 +2634 2542 -11253340.76984 +2635 2542 -16564448.113 +2636 2542 10010952.98333 +2649 2542 2388888.889675 +2650 2542 -13827100.04718 +2651 2542 -13687577.31655 +2652 2542 691259.3258679 +2653 2542 38658164.66062 +2654 2542 -6807774.623089 +2655 2542 -10565637.5134 +2656 2542 -38790050.82896 +2657 2542 27849453.42698 +2543 2543 342455969.0481 +2544 2543 3244613.254716 +2545 2543 4712791.457968 +2546 2543 13685204.04501 +2628 2543 6685644.928532 +2629 2543 -6579899.772699 +2630 2543 -8541180.705052 +2631 2543 40045947.75819 +2632 2543 -9307376.918764 +2633 2543 -43914271.4629 +2634 2543 13172362.45156 +2635 2543 10010952.98333 +2636 2543 -21878387.08629 +2649 2543 1601021.740854 +2650 2543 -13687577.31666 +2651 2543 -110751.3386485 +2652 2543 13814799.73291 +2653 2543 -6385552.400936 +2654 2543 -41178317.44134 +2655 2543 11606056.72181 +2656 2543 27849453.42572 +2657 2543 -40843933.05076 +2544 2544 391504755.4749 +2545 2544 44478671.07544 +2546 2544 -2154209.15787 +2547 2544 -96038662.69461 +2548 2544 -56611999.61159 +2549 2544 763746.3094749 +2550 2544 9012742.663298 +2551 2544 -10505118.31547 +2552 2544 150847.8398809 +2631 2544 -16732168.82767 +2632 2544 7032054.646846 +2633 2544 3593064.396935 +2634 2544 -47208013.93552 +2635 2544 9814966.02126 +2636 2544 48565173.11467 +2652 2544 -11955208.81899 +2653 2544 -10565637.5134 +2654 2544 -10039221.05324 +2655 2544 17195056.37436 +2656 2544 10108198.77753 +2657 2544 -10287674.1737 +2658 2544 -37340960.76096 +2659 2544 -14042176.00348 +2660 2544 20501045.02935 +2661 2544 -21282931.01638 +2662 2544 -2347405.92875 +2663 2544 5951501.575213 +2545 2545 475970703.4827 +2546 2545 -9366290.969137 +2547 2545 -56611999.61159 +2548 2545 -71667219.81619 +2549 2545 512395.3812617 +2550 2545 -29616229.42344 +2551 2545 -83616507.34594 +2552 2545 1621981.447331 +2631 2545 7032054.646846 +2632 2545 -39361053.63912 +2633 2545 -15153539.02783 +2634 2545 9814966.02126 +2635 2545 -4478243.957304 +2636 2545 -7602611.317661 +2652 2545 -5787859.734057 +2653 2545 -34185034.7608 +2654 2545 -25504713.23087 +2655 2545 10108198.77753 +2656 2545 36471076.67132 +2657 2545 -2263035.801925 +2658 2545 -14042176.00348 +2659 2545 -31365153.36861 +2660 2545 16792659.13732 +2661 2545 -7125183.708097 +2662 2545 -44405817.93066 +2663 2545 33731240.24096 +2546 2546 459767793.0897 +2547 2546 763746.3094749 +2548 2546 512395.3812617 +2549 2546 -7898402.048094 +2550 2546 678625.6175699 +2551 2546 1621981.447331 +2552 2546 45065635.89419 +2631 2546 3593064.396935 +2632 2546 -15153539.02783 +2633 2546 -21466336.87887 +2634 2546 48565173.11493 +2635 2546 -7602611.316297 +2636 2546 -72128252.56145 +2652 2546 -5430054.386635 +2653 2546 -25504713.23224 +2654 2546 -28563890.20229 +2655 2546 9316214.711972 +2656 2546 -2263035.801925 +2657 2546 -99246219.9555 +2658 2546 20501045.02935 +2659 2546 16792659.13732 +2660 2546 -38451308.0134 +2661 2546 10880390.46729 +2662 2546 33731240.24096 +2663 2546 -53008597.68228 +2547 2547 249047517.3782 +2548 2547 63053991.24971 +2549 2547 -441174.4345524 +2550 2547 -36755135.70683 +2551 2547 -721333.7123261 +2552 2547 -323931.4948134 +2634 2547 -15281067.83574 +2635 2547 -1265742.508225 +2636 2547 -4258988.152521 +2655 2547 -36788635.1794 +2656 2547 -14042176.00348 +2657 2547 -20123954.98399 +2658 2547 1083005.849087 +2659 2547 15599075.84627 +2660 2547 8016395.560427 +2661 2547 -36564465.6199 +2662 2547 -291157.3345608 +2663 2547 -32383452.42392 +2548 2548 224984162.4938 +2549 2548 -427600.076701 +2550 2548 18389777.39565 +2551 2548 55331754.72896 +2552 2548 -512395.3812575 +2634 2548 -6043520.287573 +2635 2548 -38409650.44919 +2636 2548 -33227270.38047 +2655 2548 -14042176.00348 +2656 2548 -30812827.78704 +2657 2548 -16540674.20696 +2658 2548 15599075.84627 +2659 2548 -4902994.880355 +2660 2548 6560603.718184 +2661 2548 4486620.444786 +2662 2548 -13425689.66935 +2663 2548 3207340.869242 +2549 2549 301195685.9049 +2550 2549 -323931.4948108 +2551 2549 -512395.3812577 +2552 2549 80795495.12971 +2634 2549 -12383988.15349 +2635 2549 -33227270.38047 +2636 2549 -57230946.62681 +2655 2549 -20123954.98399 +2656 2549 -16540674.20696 +2657 2549 -36978439.79588 +2658 2549 -8233604.436904 +2659 2549 -6772729.612959 +2660 2549 -87384024.26155 +2661 2549 -32383452.42562 +2662 2549 -3459325.799613 +2663 2549 -51876356.74494 +2550 2550 190566606.1483 +2551 2550 -27717103.90048 +2552 2550 -854551.5440485 +2634 2550 -17707783.32128 +2635 2550 9846712.893254 +2636 2550 11851045.02652 +2655 2550 -19625954.27276 +2656 2550 -7125183.708099 +2657 2550 -10556831.75541 +2658 2550 -36564465.6199 +2659 2550 4486620.444789 +2660 2550 32226269.78763 +2661 2550 830761.3487039 +2662 2550 -7208149.629944 +2663 2550 -5002705.280788 +2551 2551 216330856.1685 +2552 2551 -1621981.44732 +2634 2551 9846712.893254 +2635 2551 -23657508.34025 +2636 2551 -16540674.20696 +2655 2551 -2347405.928752 +2656 2551 -42748841.18704 +2657 2551 -32935426.41476 +2658 2551 -291157.3345582 +2659 2551 -13425689.66935 +2660 2551 3207340.869243 +2661 2551 -7208149.629943 +2662 2551 6764597.331406 +2663 2551 6268759.752466 +2552 2552 241974294.3103 +2634 2552 11851045.02652 +2635 2552 -16540674.20696 +2636 2552 -29823120.34908 +2655 2552 -5891831.75217 +2656 2552 -32935426.41476 +2657 2552 -48589993.03259 +2658 2552 32226269.78606 +2659 2552 -3459325.799613 +2660 2552 -51876356.74494 +2661 2552 4591183.606526 +2662 2552 -7064573.578677 +2663 2552 -64557041.51398 +2553 2553 498845612.8338 +2554 2553 47777777.76994 +2555 2553 25526818.17494 +2556 2553 -270769575.0497 +2557 2553 -47795571.28618 +2558 2553 -21297878.33857 +2559 2553 4724775.55691 +2560 2553 38240015.7322 +2561 2553 -15313498.75867 +2664 2553 57272319.20769 +2665 2553 11944444.44837 +2666 2553 16262217.83282 +2667 2553 -96920154.16551 +2668 2553 -11948441.41665 +2669 2553 -57894966.96635 +2670 2553 -19430363.65776 +2671 2553 9559552.526969 +2672 2553 -14502802.0572 +2554 2554 427154390.1247 +2555 2554 -48570698.50186 +2556 2554 -47804468.04431 +2557 2554 -46156001.60459 +2558 2554 -29458011.57407 +2559 2554 57360023.5983 +2560 2554 4724775.556911 +2561 2554 19641491.59463 +2664 2554 11944444.44837 +2665 2554 39350079.73598 +2666 2554 -4237631.002181 +2667 2554 -11950439.90079 +2668 2554 -40768202.4791 +2669 2554 -17881456.80322 +2670 2554 14339328.79045 +2671 2554 -19430363.65775 +2672 2554 17403019.36621 +2555 2555 472661441.9387 +2556 2555 -19183408.42037 +2557 2555 -23333069.93135 +2558 2555 -17381025.25039 +2559 2555 -22970248.13801 +2560 2555 13094327.72975 +2561 2555 12599401.48509 +2664 2555 -4818855.100867 +2665 2555 -21102266.9381 +2666 2555 -61666013.98076 +2667 2555 -57630268.59944 +2668 2555 -16401283.68257 +2669 2555 -82291258.12151 +2670 2555 -21754203.08579 +2671 2555 11602012.9108 +2672 2555 -51814303.08735 +2556 2556 852898004.744 +2557 2556 47822261.56058 +2558 2556 23750813.775 +2559 2556 10663984.89933 +2560 2556 -47795571.28619 +2561 2556 20811196.16841 +2562 2556 -185415908.7468 +2563 2556 4.678964614868e-06 +2564 2556 -4574122.969536 +2565 2556 -73761541.41083 +2566 2556 47777777.76992 +2567 2556 -20803252.962 +2664 2556 -85740387.93072 +2665 2556 -11950439.90077 +2666 2556 47775096.06898 +2667 2556 112006329.4708 +2668 2556 11954436.86906 +2669 2556 5935349.843305 +2670 2556 -36979414.9719 +2671 2556 -11948441.41664 +2672 2556 18346879.03149 +2673 2556 -74762019.75572 +2674 2556 2.533197402954e-07 +2675 2556 -53703252.3277 +2676 2556 -30778677.45218 +2677 2556 11944444.44836 +2678 2556 -18340743.64572 +2557 2557 723869819.0551 +2558 2557 -65442952.40696 +2559 2557 -47804468.04432 +2560 2557 -156592606.5887 +2561 2557 35894402.90473 +2562 2557 5.662441253662e-06 +2563 2557 24807818.43265 +2564 2557 -21110817.73799 +2565 2557 47777777.76992 +2566 2557 -59427300.65882 +2567 2557 11716519.98007 +2664 2557 -11948441.41664 +2665 2557 -29588436.2443 +2666 2557 4682155.144749 +2667 2557 11954436.86906 +2668 2557 79749895.91067 +2669 2557 -16362631.77783 +2670 2557 -11950439.90078 +2671 2557 -78792675.71048 +2672 2557 51029508.03613 +2673 2557 -8.195638656616e-07 +2674 2557 -22206107.28377 +2675 2557 -5277708.20877 +2676 2557 11944444.44836 +2677 2557 -27195128.92833 +2678 2557 13440937.44126 +2558 2558 730917912.008 +2559 2558 20551278.88239 +2560 2558 40119834.77044 +2561 2558 9888833.293587 +2562 2558 -2463011.858771 +2563 2558 -21110817.73799 +2564 2558 38554054.16679 +2565 2558 -20539364.07277 +2566 2558 11505408.86868 +2567 2558 -25226633.25495 +2664 2558 47510397.70207 +2665 2558 3205506.989851 +2666 2558 -52478548.16204 +2667 2558 5939756.113784 +2668 2558 -16359106.80793 +2669 2558 -87179377.66603 +2670 2558 18349946.72438 +2671 2558 52296851.6274 +2672 2558 -103249742.1615 +2673 2558 -53439363.43899 +2674 2558 -5277708.20877 +2675 2558 -66116380.01208 +2676 2558 -18340743.64572 +2677 2558 13440937.44126 +2678 2558 -39208792.08802 +2559 2559 498845612.8338 +2560 2559 47777777.76994 +2561 2559 25526818.17494 +2562 2559 -72712122.80639 +2563 2559 -47777777.76993 +2564 2559 18780080.36483 +2565 2559 -270769575.0497 +2566 2559 -47795571.28618 +2567 2559 -21297878.33857 +2568 2559 4724775.55691 +2569 2559 38240015.7322 +2570 2559 -15313498.75867 +2664 2559 1532382.642161 +2665 2559 14339328.79045 +2666 2559 9874015.186731 +2667 2559 -4845636.536104 +2668 2559 -11950439.90078 +2669 2559 -8009104.879749 +2670 2559 57272319.20769 +2671 2559 11944444.44837 +2672 2559 16262217.83282 +2673 2559 -20039396.92541 +2674 2559 -11944444.44837 +2675 2559 -8444910.309145 +2676 2559 -96920154.16551 +2677 2559 -11948441.41665 +2678 2559 -57894966.96635 +2679 2559 -19430363.65776 +2680 2559 9559552.526969 +2681 2559 -14502802.0572 +2560 2560 427154390.1247 +2561 2560 -48570698.50186 +2562 2560 -47777777.76993 +2563 2560 -58377882.05435 +2564 2560 9394297.757917 +2565 2560 -47804468.04431 +2566 2560 -46156001.60459 +2567 2560 -29458011.57407 +2568 2560 57360023.5983 +2569 2560 4724775.556911 +2570 2560 19641491.59463 +2664 2560 9559552.526969 +2665 2560 1532382.642157 +2666 2560 -5266148.137347 +2667 2560 -11948441.41664 +2668 2560 -46658897.27468 +2669 2560 -32026328.33686 +2670 2560 11944444.44837 +2671 2560 39350079.73598 +2672 2560 -4237631.002181 +2673 2560 -11944444.44837 +2674 2560 -16455848.40155 +2675 2560 -8163229.232496 +2676 2560 -11950439.90079 +2677 2560 -40768202.4791 +2678 2560 -17881456.80322 +2679 2560 14339328.79045 +2680 2560 -19430363.65775 +2681 2560 17403019.36621 +2561 2561 472661441.9387 +2562 2561 19043969.25406 +2563 2561 9605408.869306 +2564 2561 -22428183.64302 +2565 2561 -19183408.42037 +2566 2561 -23333069.93135 +2567 2561 -17381025.25039 +2568 2561 -22970248.13801 +2569 2561 13094327.72975 +2570 2561 12599401.48509 +2664 2561 6582676.791154 +2665 2561 -7899222.206021 +2666 2561 4086353.712421 +2667 2561 -8007766.485252 +2668 2561 -33293672.07046 +2669 2561 -17559666.33271 +2670 2561 -4818855.100867 +2671 2561 -21102266.9381 +2672 2561 -61666013.98076 +2673 2561 -8444910.309145 +2674 2561 -8163229.232496 +2675 2561 -10570710.68328 +2676 2561 -57630268.59944 +2677 2561 -16401283.68257 +2678 2561 -82291258.12151 +2679 2561 -21754203.08579 +2680 2561 11602012.9108 +2681 2561 -51814303.08735 +2562 2562 787899476.9604 +2563 2562 2.861022949219e-05 +2564 2562 7037134.828232 +2565 2562 89408469.17376 +2566 2562 -1.275539398193e-05 +2567 2562 1759283.707933 +2571 2562 -185415908.7468 +2572 2562 4.678964614868e-06 +2573 2562 -4574122.969536 +2574 2562 -73761541.41083 +2575 2562 47777777.76992 +2576 2562 -20803252.962 +2667 2562 -71968136.03531 +2668 2562 4.157423973083e-06 +2669 2562 51943969.87703 +2670 2562 -29817851.87049 +2671 2562 -11944444.44837 +2672 2562 17900923.03284 +2673 2562 88895212.80375 +2674 2562 4.112720489502e-06 +2675 2562 1759282.450699 +2676 2562 -25612922.63328 +2677 2562 -1.080334186554e-05 +2678 2562 439820.6129002 +2682 2562 -74762019.75572 +2683 2562 2.533197402954e-07 +2684 2562 -53703252.3277 +2685 2562 -30778677.45218 +2686 2562 11944444.44836 +2687 2562 -18340743.64572 +2563 2563 673225551.0007 +2564 2563 -84443270.91034 +2565 2563 -1.353025436401e-05 +2566 2563 -92146776.52992 +2567 2563 43066079.89948 +2571 2563 5.662441253662e-06 +2572 2563 24807818.43265 +2573 2563 -21110817.73799 +2574 2563 47777777.76992 +2575 2563 -59427300.65882 +2576 2563 11716519.98007 +2667 2563 3.337860107422e-06 +2668 2563 -19412223.56332 +2669 2563 -5277708.208769 +2670 2563 -11944444.44837 +2671 2563 -26234303.34662 +2672 2563 12913159.66331 +2673 2563 4.351139068604e-06 +2674 2563 60226824.62697 +2675 2563 -21110832.82468 +2676 2563 -9.95397567749e-06 +2677 2563 -71001738.06458 +2678 2563 52813749.73867 +2682 2563 -8.195638656616e-07 +2683 2563 -22206107.28377 +2684 2563 -5277708.20877 +2685 2563 11944444.44836 +2686 2563 -27195128.92833 +2687 2563 13440937.44126 +2564 2564 729298788.5117 +2565 2564 1759283.707934 +2566 2564 41377191.01087 +2567 2564 48367727.64837 +2571 2564 -2463011.858771 +2572 2564 -21110817.73799 +2573 2564 38554054.16679 +2574 2564 -20539364.07277 +2575 2564 11505408.86868 +2576 2564 -25226633.25495 +2667 2564 51680080.98832 +2668 2564 -5277708.208769 +2669 2564 -58666023.42418 +2670 2564 17900923.03284 +2671 2564 12913159.66331 +2672 2564 -36646590.5368 +2673 2564 1759282.450699 +2674 2564 -21110832.82468 +2675 2564 -105887547.9636 +2676 2564 439820.6129005 +2677 2564 52602638.6277 +2678 2564 -115814770.8741 +2682 2564 -53439363.43899 +2683 2564 -5277708.20877 +2684 2564 -66116380.01208 +2685 2564 -18340743.64572 +2686 2564 13440937.44126 +2687 2564 -39208792.08802 +2565 2565 852898004.744 +2566 2565 47822261.56058 +2567 2565 23750813.775 +2568 2565 10663984.89933 +2569 2565 -47795571.28619 +2570 2565 20811196.16841 +2571 2565 -72712122.80639 +2572 2565 -47777777.76993 +2573 2565 18780080.36483 +2574 2565 -185415908.7468 +2575 2565 4.678964614868e-06 +2576 2565 -4574122.969536 +2577 2565 -73761541.41083 +2578 2565 47777777.76992 +2579 2565 -20803252.962 +2667 2565 -19603280.6462 +2668 2565 11944444.44837 +2669 2565 8005089.696258 +2670 2565 -85740387.93072 +2671 2565 -11950439.90077 +2672 2565 47775096.06898 +2673 2565 16294780.8482 +2674 2565 4.217028617859e-06 +2675 2565 439820.6128852 +2676 2565 112006329.4708 +2677 2565 11954436.86906 +2678 2565 5935349.843305 +2679 2565 -36979414.9719 +2680 2565 -11948441.41664 +2681 2565 18346879.03149 +2682 2565 -20039396.92541 +2683 2565 -11944444.44837 +2684 2565 -8444910.309145 +2685 2565 -74762019.75572 +2686 2565 2.533197402954e-07 +2687 2565 -53703252.3277 +2688 2565 -30778677.45218 +2689 2565 11944444.44836 +2690 2565 -18340743.64572 +2566 2566 723869819.0551 +2567 2566 -65442952.40696 +2568 2566 -47804468.04432 +2569 2566 -156592606.5887 +2570 2566 35894402.90473 +2571 2566 -47777777.76993 +2572 2566 -58377882.05435 +2573 2566 9394297.757917 +2574 2566 5.662441253662e-06 +2575 2566 24807818.43265 +2576 2566 -21110817.73799 +2577 2566 47777777.76992 +2578 2566 -59427300.65882 +2579 2566 11716519.98007 +2667 2566 11944444.44837 +2668 2566 -16019732.12234 +2669 2566 -7635451.454545 +2670 2566 -11948441.41664 +2671 2566 -29588436.2443 +2672 2566 4682155.144749 +2673 2566 5.125999450684e-06 +2674 2566 -29094034.58311 +2675 2566 -31702916.914 +2676 2566 11954436.86906 +2677 2566 79749895.91067 +2678 2566 -16362631.77783 +2679 2566 -11950439.90078 +2680 2566 -78792675.71048 +2681 2566 51029508.03613 +2682 2566 -11944444.44837 +2683 2566 -16455848.40155 +2684 2566 -8163229.232496 +2685 2566 -8.195638656616e-07 +2686 2566 -22206107.28377 +2687 2566 -5277708.20877 +2688 2566 11944444.44836 +2689 2566 -27195128.92833 +2690 2566 13440937.44126 +2567 2567 730917912.008 +2568 2567 20551278.88239 +2569 2567 40119834.77044 +2570 2567 9888833.293587 +2571 2567 19043969.25406 +2572 2567 9605408.869306 +2573 2567 -22428183.64302 +2574 2567 -2463011.858771 +2575 2567 -21110817.73799 +2576 2567 38554054.16679 +2577 2567 -20539364.07277 +2578 2567 11505408.86868 +2579 2567 -25226633.25495 +2667 2567 8005089.696258 +2668 2567 -7635451.454545 +2669 2567 -9407733.938713 +2670 2567 47510397.70207 +2671 2567 3205506.989851 +2672 2567 -52478548.16204 +2673 2567 439820.6128855 +2674 2567 -31491805.80303 +2675 2567 -4060894.923526 +2676 2567 5939756.113784 +2677 2567 -16359106.80793 +2678 2567 -87179377.66603 +2679 2567 18349946.72438 +2680 2567 52296851.6274 +2681 2567 -103249742.1615 +2682 2567 -8444910.309145 +2683 2567 -8163229.232496 +2684 2567 -10570710.68328 +2685 2567 -53439363.43899 +2686 2567 -5277708.20877 +2687 2567 -66116380.01208 +2688 2567 -18340743.64572 +2689 2567 13440937.44126 +2690 2567 -39208792.08802 +2568 2568 498845612.8338 +2569 2568 47777777.76994 +2570 2568 25526818.17494 +2574 2568 -72712122.80639 +2575 2568 -47777777.76993 +2576 2568 18780080.36483 +2577 2568 -270769575.0497 +2578 2568 -47795571.28618 +2579 2568 -21297878.33857 +2580 2568 4724775.55691 +2581 2568 38240015.7322 +2582 2568 -15313498.75867 +2670 2568 1532382.642161 +2671 2568 14339328.79045 +2672 2568 9874015.186731 +2676 2568 -4845636.536104 +2677 2568 -11950439.90078 +2678 2568 -8009104.879749 +2679 2568 57272319.20769 +2680 2568 11944444.44837 +2681 2568 16262217.83282 +2685 2568 -20039396.92541 +2686 2568 -11944444.44837 +2687 2568 -8444910.309145 +2688 2568 -96920154.16551 +2689 2568 -11948441.41665 +2690 2568 -57894966.96635 +2691 2568 -19430363.65776 +2692 2568 9559552.526969 +2693 2568 -14502802.0572 +2569 2569 427154390.1247 +2570 2569 -48570698.50186 +2574 2569 -47777777.76993 +2575 2569 -58377882.05435 +2576 2569 9394297.757917 +2577 2569 -47804468.04431 +2578 2569 -46156001.60459 +2579 2569 -29458011.57407 +2580 2569 57360023.5983 +2581 2569 4724775.556911 +2582 2569 19641491.59463 +2670 2569 9559552.526969 +2671 2569 1532382.642157 +2672 2569 -5266148.137347 +2676 2569 -11948441.41664 +2677 2569 -46658897.27468 +2678 2569 -32026328.33686 +2679 2569 11944444.44837 +2680 2569 39350079.73598 +2681 2569 -4237631.002181 +2685 2569 -11944444.44837 +2686 2569 -16455848.40155 +2687 2569 -8163229.232496 +2688 2569 -11950439.90079 +2689 2569 -40768202.4791 +2690 2569 -17881456.80322 +2691 2569 14339328.79045 +2692 2569 -19430363.65775 +2693 2569 17403019.36621 +2570 2570 472661441.9387 +2574 2570 19043969.25406 +2575 2570 9605408.869306 +2576 2570 -22428183.64302 +2577 2570 -19183408.42037 +2578 2570 -23333069.93135 +2579 2570 -17381025.25039 +2580 2570 -22970248.13801 +2581 2570 13094327.72975 +2582 2570 12599401.48509 +2670 2570 6582676.791154 +2671 2570 -7899222.206021 +2672 2570 4086353.712421 +2676 2570 -8007766.485252 +2677 2570 -33293672.07046 +2678 2570 -17559666.33271 +2679 2570 -4818855.100867 +2680 2570 -21102266.9381 +2681 2570 -61666013.98076 +2685 2570 -8444910.309145 +2686 2570 -8163229.232496 +2687 2570 -10570710.68328 +2688 2570 -57630268.59944 +2689 2570 -16401283.68257 +2690 2570 -82291258.12151 +2691 2570 -21754203.08579 +2692 2570 11602012.9108 +2693 2570 -51814303.08735 +2571 2571 787899476.9604 +2572 2571 2.861022949219e-05 +2573 2571 7037134.828232 +2574 2571 89408469.17376 +2575 2571 -1.275539398193e-05 +2576 2571 1759283.707933 +2583 2571 -185415908.7468 +2584 2571 4.678964614868e-06 +2585 2571 -4574122.969536 +2586 2571 -73761541.41083 +2587 2571 47777777.76992 +2588 2571 -20803252.962 +2673 2571 -71968136.03531 +2674 2571 4.157423973083e-06 +2675 2571 51943969.87703 +2676 2571 -29817851.87049 +2677 2571 -11944444.44837 +2678 2571 17900923.03284 +2682 2571 88895212.80375 +2683 2571 4.112720489502e-06 +2684 2571 1759282.450699 +2685 2571 -25612922.63328 +2686 2571 -1.080334186554e-05 +2687 2571 439820.6129002 +2694 2571 -74762019.75572 +2695 2571 2.533197402954e-07 +2696 2571 -53703252.3277 +2697 2571 -30778677.45218 +2698 2571 11944444.44836 +2699 2571 -18340743.64572 +2572 2572 673225551.0007 +2573 2572 -84443270.91034 +2574 2572 -1.353025436401e-05 +2575 2572 -92146776.52992 +2576 2572 43066079.89948 +2583 2572 5.662441253662e-06 +2584 2572 24807818.43265 +2585 2572 -21110817.73799 +2586 2572 47777777.76992 +2587 2572 -59427300.65882 +2588 2572 11716519.98007 +2673 2572 3.337860107422e-06 +2674 2572 -19412223.56332 +2675 2572 -5277708.208769 +2676 2572 -11944444.44837 +2677 2572 -26234303.34662 +2678 2572 12913159.66331 +2682 2572 4.351139068604e-06 +2683 2572 60226824.62697 +2684 2572 -21110832.82468 +2685 2572 -9.95397567749e-06 +2686 2572 -71001738.06458 +2687 2572 52813749.73867 +2694 2572 -8.195638656616e-07 +2695 2572 -22206107.28377 +2696 2572 -5277708.20877 +2697 2572 11944444.44836 +2698 2572 -27195128.92833 +2699 2572 13440937.44126 +2573 2573 729298788.5117 +2574 2573 1759283.707934 +2575 2573 41377191.01087 +2576 2573 48367727.64837 +2583 2573 -2463011.858771 +2584 2573 -21110817.73799 +2585 2573 38554054.16679 +2586 2573 -20539364.07277 +2587 2573 11505408.86868 +2588 2573 -25226633.25495 +2673 2573 51680080.98832 +2674 2573 -5277708.208769 +2675 2573 -58666023.42418 +2676 2573 17900923.03284 +2677 2573 12913159.66331 +2678 2573 -36646590.5368 +2682 2573 1759282.450699 +2683 2573 -21110832.82468 +2684 2573 -105887547.9636 +2685 2573 439820.6129005 +2686 2573 52602638.6277 +2687 2573 -115814770.8741 +2694 2573 -53439363.43899 +2695 2573 -5277708.20877 +2696 2573 -66116380.01208 +2697 2573 -18340743.64572 +2698 2573 13440937.44126 +2699 2573 -39208792.08802 +2574 2574 787899476.9604 +2575 2574 2.861022949219e-05 +2576 2574 7037134.828232 +2577 2574 89408469.17376 +2578 2574 -1.275539398193e-05 +2579 2574 1759283.707933 +2583 2574 -72712122.80639 +2584 2574 -47777777.76993 +2585 2574 18780080.36483 +2586 2574 -185415908.7468 +2587 2574 4.678964614868e-06 +2588 2574 -4574122.969536 +2589 2574 -73761541.41083 +2590 2574 47777777.76992 +2591 2574 -20803252.962 +2673 2574 -19603280.6462 +2674 2574 11944444.44837 +2675 2574 8005089.696258 +2676 2574 -71968136.03531 +2677 2574 4.157423973083e-06 +2678 2574 51943969.87703 +2679 2574 -29817851.87049 +2680 2574 -11944444.44837 +2681 2574 17900923.03284 +2682 2574 16294780.8482 +2683 2574 4.217028617859e-06 +2684 2574 439820.6128852 +2685 2574 88895212.80375 +2686 2574 4.112720489502e-06 +2687 2574 1759282.450699 +2688 2574 -25612922.63328 +2689 2574 -1.080334186554e-05 +2690 2574 439820.6129002 +2694 2574 -20039396.92541 +2695 2574 -11944444.44837 +2696 2574 -8444910.309145 +2697 2574 -74762019.75572 +2698 2574 2.533197402954e-07 +2699 2574 -53703252.3277 +2700 2574 -30778677.45218 +2701 2574 11944444.44836 +2702 2574 -18340743.64572 +2575 2575 673225551.0007 +2576 2575 -84443270.91034 +2577 2575 -1.353025436401e-05 +2578 2575 -92146776.52992 +2579 2575 43066079.89948 +2583 2575 -47777777.76993 +2584 2575 -58377882.05435 +2585 2575 9394297.757917 +2586 2575 5.662441253662e-06 +2587 2575 24807818.43265 +2588 2575 -21110817.73799 +2589 2575 47777777.76992 +2590 2575 -59427300.65882 +2591 2575 11716519.98007 +2673 2575 11944444.44837 +2674 2575 -16019732.12234 +2675 2575 -7635451.454545 +2676 2575 3.337860107422e-06 +2677 2575 -19412223.56332 +2678 2575 -5277708.208769 +2679 2575 -11944444.44837 +2680 2575 -26234303.34662 +2681 2575 12913159.66331 +2682 2575 5.125999450684e-06 +2683 2575 -29094034.58311 +2684 2575 -31702916.914 +2685 2575 4.351139068604e-06 +2686 2575 60226824.62697 +2687 2575 -21110832.82468 +2688 2575 -9.95397567749e-06 +2689 2575 -71001738.06458 +2690 2575 52813749.73867 +2694 2575 -11944444.44837 +2695 2575 -16455848.40155 +2696 2575 -8163229.232496 +2697 2575 -8.195638656616e-07 +2698 2575 -22206107.28377 +2699 2575 -5277708.20877 +2700 2575 11944444.44836 +2701 2575 -27195128.92833 +2702 2575 13440937.44126 +2576 2576 729298788.5117 +2577 2576 1759283.707934 +2578 2576 41377191.01087 +2579 2576 48367727.64837 +2583 2576 19043969.25406 +2584 2576 9605408.869306 +2585 2576 -22428183.64302 +2586 2576 -2463011.858771 +2587 2576 -21110817.73799 +2588 2576 38554054.16679 +2589 2576 -20539364.07277 +2590 2576 11505408.86868 +2591 2576 -25226633.25495 +2673 2576 8005089.696258 +2674 2576 -7635451.454545 +2675 2576 -9407733.938713 +2676 2576 51680080.98832 +2677 2576 -5277708.208769 +2678 2576 -58666023.42418 +2679 2576 17900923.03284 +2680 2576 12913159.66331 +2681 2576 -36646590.5368 +2682 2576 439820.6128855 +2683 2576 -31491805.80303 +2684 2576 -4060894.923526 +2685 2576 1759282.450699 +2686 2576 -21110832.82468 +2687 2576 -105887547.9636 +2688 2576 439820.6129005 +2689 2576 52602638.6277 +2690 2576 -115814770.8741 +2694 2576 -8444910.309145 +2695 2576 -8163229.232496 +2696 2576 -10570710.68328 +2697 2576 -53439363.43899 +2698 2576 -5277708.20877 +2699 2576 -66116380.01208 +2700 2576 -18340743.64572 +2701 2576 13440937.44126 +2702 2576 -39208792.08802 +2577 2577 852898004.744 +2578 2577 47822261.56058 +2579 2577 23750813.775 +2580 2577 10663984.89933 +2581 2577 -47795571.28619 +2582 2577 20811196.16841 +2586 2577 -72712122.80639 +2587 2577 -47777777.76993 +2588 2577 18780080.36483 +2589 2577 -185415908.7468 +2590 2577 4.678964614868e-06 +2591 2577 -4574122.969536 +2592 2577 -73761541.41083 +2593 2577 47777777.76992 +2594 2577 -20803252.962 +2676 2577 -19603280.6462 +2677 2577 11944444.44837 +2678 2577 8005089.696258 +2679 2577 -85740387.93072 +2680 2577 -11950439.90077 +2681 2577 47775096.06898 +2685 2577 16294780.8482 +2686 2577 4.217028617859e-06 +2687 2577 439820.6128852 +2688 2577 112006329.4708 +2689 2577 11954436.86906 +2690 2577 5935349.843305 +2691 2577 -36979414.9719 +2692 2577 -11948441.41664 +2693 2577 18346879.03149 +2697 2577 -20039396.92541 +2698 2577 -11944444.44837 +2699 2577 -8444910.309145 +2700 2577 -74762019.75572 +2701 2577 2.533197402954e-07 +2702 2577 -53703252.3277 +2703 2577 -30778677.45218 +2704 2577 11944444.44836 +2705 2577 -18340743.64572 +2578 2578 723869819.0551 +2579 2578 -65442952.40696 +2580 2578 -47804468.04432 +2581 2578 -156592606.5887 +2582 2578 35894402.90473 +2586 2578 -47777777.76993 +2587 2578 -58377882.05435 +2588 2578 9394297.757917 +2589 2578 5.662441253662e-06 +2590 2578 24807818.43265 +2591 2578 -21110817.73799 +2592 2578 47777777.76992 +2593 2578 -59427300.65882 +2594 2578 11716519.98007 +2676 2578 11944444.44837 +2677 2578 -16019732.12234 +2678 2578 -7635451.454545 +2679 2578 -11948441.41664 +2680 2578 -29588436.2443 +2681 2578 4682155.144749 +2685 2578 5.125999450684e-06 +2686 2578 -29094034.58311 +2687 2578 -31702916.914 +2688 2578 11954436.86906 +2689 2578 79749895.91067 +2690 2578 -16362631.77783 +2691 2578 -11950439.90078 +2692 2578 -78792675.71048 +2693 2578 51029508.03613 +2697 2578 -11944444.44837 +2698 2578 -16455848.40155 +2699 2578 -8163229.232496 +2700 2578 -8.195638656616e-07 +2701 2578 -22206107.28377 +2702 2578 -5277708.20877 +2703 2578 11944444.44836 +2704 2578 -27195128.92833 +2705 2578 13440937.44126 +2579 2579 730917912.008 +2580 2579 20551278.88239 +2581 2579 40119834.77044 +2582 2579 9888833.293587 +2586 2579 19043969.25406 +2587 2579 9605408.869306 +2588 2579 -22428183.64302 +2589 2579 -2463011.858771 +2590 2579 -21110817.73799 +2591 2579 38554054.16679 +2592 2579 -20539364.07277 +2593 2579 11505408.86868 +2594 2579 -25226633.25495 +2676 2579 8005089.696258 +2677 2579 -7635451.454545 +2678 2579 -9407733.938713 +2679 2579 47510397.70207 +2680 2579 3205506.989851 +2681 2579 -52478548.16204 +2685 2579 439820.6128855 +2686 2579 -31491805.80303 +2687 2579 -4060894.923526 +2688 2579 5939756.113784 +2689 2579 -16359106.80793 +2690 2579 -87179377.66603 +2691 2579 18349946.72438 +2692 2579 52296851.6274 +2693 2579 -103249742.1615 +2697 2579 -8444910.309145 +2698 2579 -8163229.232496 +2699 2579 -10570710.68328 +2700 2579 -53439363.43899 +2701 2579 -5277708.20877 +2702 2579 -66116380.01208 +2703 2579 -18340743.64572 +2704 2579 13440937.44126 +2705 2579 -39208792.08802 +2580 2580 498845612.8338 +2581 2580 47777777.76994 +2582 2580 25526818.17494 +2589 2580 -72712122.80639 +2590 2580 -47777777.76993 +2591 2580 18780080.36483 +2592 2580 -270769575.0497 +2593 2580 -47795571.28618 +2594 2580 -21297878.33857 +2595 2580 4724775.55691 +2596 2580 38240015.7322 +2597 2580 -15313498.75867 +2679 2580 1532382.642161 +2680 2580 14339328.79045 +2681 2580 9874015.186731 +2688 2580 -4845636.536104 +2689 2580 -11950439.90078 +2690 2580 -8009104.879749 +2691 2580 57272319.20769 +2692 2580 11944444.44837 +2693 2580 16262217.83282 +2700 2580 -20039396.92541 +2701 2580 -11944444.44837 +2702 2580 -8444910.309145 +2703 2580 -96920154.16551 +2704 2580 -11948441.41665 +2705 2580 -57894966.96635 +2706 2580 -19430363.65776 +2707 2580 9559552.526969 +2708 2580 -14502802.0572 +2581 2581 427154390.1247 +2582 2581 -48570698.50186 +2589 2581 -47777777.76993 +2590 2581 -58377882.05435 +2591 2581 9394297.757917 +2592 2581 -47804468.04431 +2593 2581 -46156001.60459 +2594 2581 -29458011.57407 +2595 2581 57360023.5983 +2596 2581 4724775.556911 +2597 2581 19641491.59463 +2679 2581 9559552.526969 +2680 2581 1532382.642157 +2681 2581 -5266148.137347 +2688 2581 -11948441.41664 +2689 2581 -46658897.27468 +2690 2581 -32026328.33686 +2691 2581 11944444.44837 +2692 2581 39350079.73598 +2693 2581 -4237631.002181 +2700 2581 -11944444.44837 +2701 2581 -16455848.40155 +2702 2581 -8163229.232496 +2703 2581 -11950439.90079 +2704 2581 -40768202.4791 +2705 2581 -17881456.80322 +2706 2581 14339328.79045 +2707 2581 -19430363.65775 +2708 2581 17403019.36621 +2582 2582 472661441.9387 +2589 2582 19043969.25406 +2590 2582 9605408.869306 +2591 2582 -22428183.64302 +2592 2582 -19183408.42037 +2593 2582 -23333069.93135 +2594 2582 -17381025.25039 +2595 2582 -22970248.13801 +2596 2582 13094327.72975 +2597 2582 12599401.48509 +2679 2582 6582676.791154 +2680 2582 -7899222.206021 +2681 2582 4086353.712421 +2688 2582 -8007766.485252 +2689 2582 -33293672.07046 +2690 2582 -17559666.33271 +2691 2582 -4818855.100867 +2692 2582 -21102266.9381 +2693 2582 -61666013.98076 +2700 2582 -8444910.309145 +2701 2582 -8163229.232496 +2702 2582 -10570710.68328 +2703 2582 -57630268.59944 +2704 2582 -16401283.68257 +2705 2582 -82291258.12151 +2706 2582 -21754203.08579 +2707 2582 11602012.9108 +2708 2582 -51814303.08735 +2583 2583 787899476.9604 +2584 2583 2.861022949219e-05 +2585 2583 7037134.828232 +2586 2583 89408469.17376 +2587 2583 -1.275539398193e-05 +2588 2583 1759283.707933 +2598 2583 -185415908.7468 +2599 2583 4.678964614868e-06 +2600 2583 -4574122.969536 +2601 2583 -73761541.41083 +2602 2583 47777777.76992 +2603 2583 -20803252.962 +2682 2583 -71968136.03531 +2683 2583 4.157423973083e-06 +2684 2583 51943969.87703 +2685 2583 -29817851.87049 +2686 2583 -11944444.44837 +2687 2583 17900923.03284 +2694 2583 88895212.80375 +2695 2583 4.112720489502e-06 +2696 2583 1759282.450699 +2697 2583 -25612922.63328 +2698 2583 -1.080334186554e-05 +2699 2583 439820.6129002 +2709 2583 -74762019.75572 +2710 2583 2.533197402954e-07 +2711 2583 -53703252.3277 +2712 2583 -30778677.45218 +2713 2583 11944444.44836 +2714 2583 -18340743.64572 +2584 2584 673225551.0007 +2585 2584 -84443270.91034 +2586 2584 -1.353025436401e-05 +2587 2584 -92146776.52992 +2588 2584 43066079.89948 +2598 2584 5.662441253662e-06 +2599 2584 24807818.43265 +2600 2584 -21110817.73799 +2601 2584 47777777.76992 +2602 2584 -59427300.65882 +2603 2584 11716519.98007 +2682 2584 3.337860107422e-06 +2683 2584 -19412223.56332 +2684 2584 -5277708.208769 +2685 2584 -11944444.44837 +2686 2584 -26234303.34662 +2687 2584 12913159.66331 +2694 2584 4.351139068604e-06 +2695 2584 60226824.62697 +2696 2584 -21110832.82468 +2697 2584 -9.95397567749e-06 +2698 2584 -71001738.06458 +2699 2584 52813749.73867 +2709 2584 -8.195638656616e-07 +2710 2584 -22206107.28377 +2711 2584 -5277708.20877 +2712 2584 11944444.44836 +2713 2584 -27195128.92833 +2714 2584 13440937.44126 +2585 2585 729298788.5117 +2586 2585 1759283.707934 +2587 2585 41377191.01087 +2588 2585 48367727.64837 +2598 2585 -2463011.858771 +2599 2585 -21110817.73799 +2600 2585 38554054.16679 +2601 2585 -20539364.07277 +2602 2585 11505408.86868 +2603 2585 -25226633.25495 +2682 2585 51680080.98832 +2683 2585 -5277708.208769 +2684 2585 -58666023.42418 +2685 2585 17900923.03284 +2686 2585 12913159.66331 +2687 2585 -36646590.5368 +2694 2585 1759282.450699 +2695 2585 -21110832.82468 +2696 2585 -105887547.9636 +2697 2585 439820.6129005 +2698 2585 52602638.6277 +2699 2585 -115814770.8741 +2709 2585 -53439363.43899 +2710 2585 -5277708.20877 +2711 2585 -66116380.01208 +2712 2585 -18340743.64572 +2713 2585 13440937.44126 +2714 2585 -39208792.08802 +2586 2586 787899476.9604 +2587 2586 2.861022949219e-05 +2588 2586 7037134.828232 +2589 2586 89408469.17376 +2590 2586 -1.275539398193e-05 +2591 2586 1759283.707933 +2598 2586 -72712122.80639 +2599 2586 -47777777.76993 +2600 2586 18780080.36483 +2601 2586 -185415908.7468 +2602 2586 4.678964614868e-06 +2603 2586 -4574122.969536 +2604 2586 -73761541.41083 +2605 2586 47777777.76992 +2606 2586 -20803252.962 +2682 2586 -19603280.6462 +2683 2586 11944444.44837 +2684 2586 8005089.696258 +2685 2586 -71968136.03531 +2686 2586 4.157423973083e-06 +2687 2586 51943969.87703 +2688 2586 -29817851.87049 +2689 2586 -11944444.44837 +2690 2586 17900923.03284 +2694 2586 16294780.8482 +2695 2586 4.217028617859e-06 +2696 2586 439820.6128852 +2697 2586 88895212.80375 +2698 2586 4.112720489502e-06 +2699 2586 1759282.450699 +2700 2586 -25612922.63328 +2701 2586 -1.080334186554e-05 +2702 2586 439820.6129002 +2709 2586 -20039396.92541 +2710 2586 -11944444.44837 +2711 2586 -8444910.309145 +2712 2586 -74762019.75572 +2713 2586 2.533197402954e-07 +2714 2586 -53703252.3277 +2715 2586 -30778677.45218 +2716 2586 11944444.44836 +2717 2586 -18340743.64572 +2587 2587 673225551.0007 +2588 2587 -84443270.91034 +2589 2587 -1.353025436401e-05 +2590 2587 -92146776.52992 +2591 2587 43066079.89948 +2598 2587 -47777777.76993 +2599 2587 -58377882.05435 +2600 2587 9394297.757917 +2601 2587 5.662441253662e-06 +2602 2587 24807818.43265 +2603 2587 -21110817.73799 +2604 2587 47777777.76992 +2605 2587 -59427300.65882 +2606 2587 11716519.98007 +2682 2587 11944444.44837 +2683 2587 -16019732.12234 +2684 2587 -7635451.454545 +2685 2587 3.337860107422e-06 +2686 2587 -19412223.56332 +2687 2587 -5277708.208769 +2688 2587 -11944444.44837 +2689 2587 -26234303.34662 +2690 2587 12913159.66331 +2694 2587 5.125999450684e-06 +2695 2587 -29094034.58311 +2696 2587 -31702916.914 +2697 2587 4.351139068604e-06 +2698 2587 60226824.62697 +2699 2587 -21110832.82468 +2700 2587 -9.95397567749e-06 +2701 2587 -71001738.06458 +2702 2587 52813749.73867 +2709 2587 -11944444.44837 +2710 2587 -16455848.40155 +2711 2587 -8163229.232496 +2712 2587 -8.195638656616e-07 +2713 2587 -22206107.28377 +2714 2587 -5277708.20877 +2715 2587 11944444.44836 +2716 2587 -27195128.92833 +2717 2587 13440937.44126 +2588 2588 729298788.5117 +2589 2588 1759283.707934 +2590 2588 41377191.01087 +2591 2588 48367727.64837 +2598 2588 19043969.25406 +2599 2588 9605408.869306 +2600 2588 -22428183.64302 +2601 2588 -2463011.858771 +2602 2588 -21110817.73799 +2603 2588 38554054.16679 +2604 2588 -20539364.07277 +2605 2588 11505408.86868 +2606 2588 -25226633.25495 +2682 2588 8005089.696258 +2683 2588 -7635451.454545 +2684 2588 -9407733.938713 +2685 2588 51680080.98832 +2686 2588 -5277708.208769 +2687 2588 -58666023.42418 +2688 2588 17900923.03284 +2689 2588 12913159.66331 +2690 2588 -36646590.5368 +2694 2588 439820.6128855 +2695 2588 -31491805.80303 +2696 2588 -4060894.923526 +2697 2588 1759282.450699 +2698 2588 -21110832.82468 +2699 2588 -105887547.9636 +2700 2588 439820.6129005 +2701 2588 52602638.6277 +2702 2588 -115814770.8741 +2709 2588 -8444910.309145 +2710 2588 -8163229.232496 +2711 2588 -10570710.68328 +2712 2588 -53439363.43899 +2713 2588 -5277708.20877 +2714 2588 -66116380.01208 +2715 2588 -18340743.64572 +2716 2588 13440937.44126 +2717 2588 -39208792.08802 +2589 2589 787899476.9604 +2590 2589 2.861022949219e-05 +2591 2589 7037134.828232 +2592 2589 89408469.17376 +2593 2589 -1.275539398193e-05 +2594 2589 1759283.707933 +2601 2589 -72712122.80639 +2602 2589 -47777777.76993 +2603 2589 18780080.36483 +2604 2589 -185415908.7468 +2605 2589 4.678964614868e-06 +2606 2589 -4574122.969536 +2607 2589 -73761541.41083 +2608 2589 47777777.76992 +2609 2589 -20803252.962 +2685 2589 -19603280.6462 +2686 2589 11944444.44837 +2687 2589 8005089.696258 +2688 2589 -71968136.03531 +2689 2589 4.157423973083e-06 +2690 2589 51943969.87703 +2691 2589 -29817851.87049 +2692 2589 -11944444.44837 +2693 2589 17900923.03284 +2697 2589 16294780.8482 +2698 2589 4.217028617859e-06 +2699 2589 439820.6128852 +2700 2589 88895212.80375 +2701 2589 4.112720489502e-06 +2702 2589 1759282.450699 +2703 2589 -25612922.63328 +2704 2589 -1.080334186554e-05 +2705 2589 439820.6129002 +2712 2589 -20039396.92541 +2713 2589 -11944444.44837 +2714 2589 -8444910.309145 +2715 2589 -74762019.75572 +2716 2589 2.533197402954e-07 +2717 2589 -53703252.3277 +2718 2589 -30778677.45218 +2719 2589 11944444.44836 +2720 2589 -18340743.64572 +2590 2590 673225551.0007 +2591 2590 -84443270.91034 +2592 2590 -1.353025436401e-05 +2593 2590 -92146776.52992 +2594 2590 43066079.89948 +2601 2590 -47777777.76993 +2602 2590 -58377882.05435 +2603 2590 9394297.757917 +2604 2590 5.662441253662e-06 +2605 2590 24807818.43265 +2606 2590 -21110817.73799 +2607 2590 47777777.76992 +2608 2590 -59427300.65882 +2609 2590 11716519.98007 +2685 2590 11944444.44837 +2686 2590 -16019732.12234 +2687 2590 -7635451.454545 +2688 2590 3.337860107422e-06 +2689 2590 -19412223.56332 +2690 2590 -5277708.208769 +2691 2590 -11944444.44837 +2692 2590 -26234303.34662 +2693 2590 12913159.66331 +2697 2590 5.125999450684e-06 +2698 2590 -29094034.58311 +2699 2590 -31702916.914 +2700 2590 4.351139068604e-06 +2701 2590 60226824.62697 +2702 2590 -21110832.82468 +2703 2590 -9.95397567749e-06 +2704 2590 -71001738.06458 +2705 2590 52813749.73867 +2712 2590 -11944444.44837 +2713 2590 -16455848.40155 +2714 2590 -8163229.232496 +2715 2590 -8.195638656616e-07 +2716 2590 -22206107.28377 +2717 2590 -5277708.20877 +2718 2590 11944444.44836 +2719 2590 -27195128.92833 +2720 2590 13440937.44126 +2591 2591 729298788.5117 +2592 2591 1759283.707934 +2593 2591 41377191.01087 +2594 2591 48367727.64837 +2601 2591 19043969.25406 +2602 2591 9605408.869306 +2603 2591 -22428183.64302 +2604 2591 -2463011.858771 +2605 2591 -21110817.73799 +2606 2591 38554054.16679 +2607 2591 -20539364.07277 +2608 2591 11505408.86868 +2609 2591 -25226633.25495 +2685 2591 8005089.696258 +2686 2591 -7635451.454545 +2687 2591 -9407733.938713 +2688 2591 51680080.98832 +2689 2591 -5277708.208769 +2690 2591 -58666023.42418 +2691 2591 17900923.03284 +2692 2591 12913159.66331 +2693 2591 -36646590.5368 +2697 2591 439820.6128855 +2698 2591 -31491805.80303 +2699 2591 -4060894.923526 +2700 2591 1759282.450699 +2701 2591 -21110832.82468 +2702 2591 -105887547.9636 +2703 2591 439820.6129005 +2704 2591 52602638.6277 +2705 2591 -115814770.8741 +2712 2591 -8444910.309145 +2713 2591 -8163229.232496 +2714 2591 -10570710.68328 +2715 2591 -53439363.43899 +2716 2591 -5277708.20877 +2717 2591 -66116380.01208 +2718 2591 -18340743.64572 +2719 2591 13440937.44126 +2720 2591 -39208792.08802 +2592 2592 852898004.744 +2593 2592 47822261.56058 +2594 2592 23750813.775 +2595 2592 10663984.89933 +2596 2592 -47795571.28619 +2597 2592 20811196.16841 +2604 2592 -72712122.80639 +2605 2592 -47777777.76993 +2606 2592 18780080.36483 +2607 2592 -185415908.7468 +2608 2592 4.678964614868e-06 +2609 2592 -4574122.969536 +2610 2592 -73761541.41083 +2611 2592 47777777.76992 +2612 2592 -20803252.962 +2688 2592 -19603280.6462 +2689 2592 11944444.44837 +2690 2592 8005089.696258 +2691 2592 -85740387.93072 +2692 2592 -11950439.90077 +2693 2592 47775096.06898 +2700 2592 16294780.8482 +2701 2592 4.217028617859e-06 +2702 2592 439820.6128852 +2703 2592 112006329.4708 +2704 2592 11954436.86906 +2705 2592 5935349.843305 +2706 2592 -36979414.9719 +2707 2592 -11948441.41664 +2708 2592 18346879.03149 +2715 2592 -20039396.92541 +2716 2592 -11944444.44837 +2717 2592 -8444910.309145 +2718 2592 -74762019.75572 +2719 2592 2.533197402954e-07 +2720 2592 -53703252.3277 +2721 2592 -30778677.45218 +2722 2592 11944444.44836 +2723 2592 -18340743.64572 +2593 2593 723869819.0551 +2594 2593 -65442952.40696 +2595 2593 -47804468.04432 +2596 2593 -156592606.5887 +2597 2593 35894402.90473 +2604 2593 -47777777.76993 +2605 2593 -58377882.05435 +2606 2593 9394297.757917 +2607 2593 5.662441253662e-06 +2608 2593 24807818.43265 +2609 2593 -21110817.73799 +2610 2593 47777777.76992 +2611 2593 -59427300.65882 +2612 2593 11716519.98007 +2688 2593 11944444.44837 +2689 2593 -16019732.12234 +2690 2593 -7635451.454545 +2691 2593 -11948441.41664 +2692 2593 -29588436.2443 +2693 2593 4682155.144749 +2700 2593 5.125999450684e-06 +2701 2593 -29094034.58311 +2702 2593 -31702916.914 +2703 2593 11954436.86906 +2704 2593 79749895.91067 +2705 2593 -16362631.77783 +2706 2593 -11950439.90078 +2707 2593 -78792675.71048 +2708 2593 51029508.03613 +2715 2593 -11944444.44837 +2716 2593 -16455848.40155 +2717 2593 -8163229.232496 +2718 2593 -8.195638656616e-07 +2719 2593 -22206107.28377 +2720 2593 -5277708.20877 +2721 2593 11944444.44836 +2722 2593 -27195128.92833 +2723 2593 13440937.44126 +2594 2594 730917912.008 +2595 2594 20551278.88239 +2596 2594 40119834.77044 +2597 2594 9888833.293587 +2604 2594 19043969.25406 +2605 2594 9605408.869306 +2606 2594 -22428183.64302 +2607 2594 -2463011.858771 +2608 2594 -21110817.73799 +2609 2594 38554054.16679 +2610 2594 -20539364.07277 +2611 2594 11505408.86868 +2612 2594 -25226633.25495 +2688 2594 8005089.696258 +2689 2594 -7635451.454545 +2690 2594 -9407733.938713 +2691 2594 47510397.70207 +2692 2594 3205506.989851 +2693 2594 -52478548.16204 +2700 2594 439820.6128855 +2701 2594 -31491805.80303 +2702 2594 -4060894.923526 +2703 2594 5939756.113784 +2704 2594 -16359106.80793 +2705 2594 -87179377.66603 +2706 2594 18349946.72438 +2707 2594 52296851.6274 +2708 2594 -103249742.1615 +2715 2594 -8444910.309145 +2716 2594 -8163229.232496 +2717 2594 -10570710.68328 +2718 2594 -53439363.43899 +2719 2594 -5277708.20877 +2720 2594 -66116380.01208 +2721 2594 -18340743.64572 +2722 2594 13440937.44126 +2723 2594 -39208792.08802 +2595 2595 498845612.8338 +2596 2595 47777777.76994 +2597 2595 25526818.17494 +2607 2595 -72712122.80639 +2608 2595 -47777777.76993 +2609 2595 18780080.36483 +2610 2595 -270769575.0497 +2611 2595 -47795571.28618 +2612 2595 -21297878.33857 +2613 2595 4724775.55691 +2614 2595 38240015.7322 +2615 2595 -15313498.75867 +2691 2595 1532382.642161 +2692 2595 14339328.79045 +2693 2595 9874015.186731 +2703 2595 -4845636.536104 +2704 2595 -11950439.90078 +2705 2595 -8009104.879749 +2706 2595 57272319.20769 +2707 2595 11944444.44837 +2708 2595 16262217.83282 +2718 2595 -20039396.92541 +2719 2595 -11944444.44837 +2720 2595 -8444910.309145 +2721 2595 -96920154.16551 +2722 2595 -11948441.41665 +2723 2595 -57894966.96635 +2724 2595 -19430363.65776 +2725 2595 9559552.526969 +2726 2595 -14502802.0572 +2596 2596 427154390.1247 +2597 2596 -48570698.50186 +2607 2596 -47777777.76993 +2608 2596 -58377882.05435 +2609 2596 9394297.757917 +2610 2596 -47804468.04431 +2611 2596 -46156001.60459 +2612 2596 -29458011.57407 +2613 2596 57360023.5983 +2614 2596 4724775.556911 +2615 2596 19641491.59463 +2691 2596 9559552.526969 +2692 2596 1532382.642157 +2693 2596 -5266148.137347 +2703 2596 -11948441.41664 +2704 2596 -46658897.27468 +2705 2596 -32026328.33686 +2706 2596 11944444.44837 +2707 2596 39350079.73598 +2708 2596 -4237631.002181 +2718 2596 -11944444.44837 +2719 2596 -16455848.40155 +2720 2596 -8163229.232496 +2721 2596 -11950439.90079 +2722 2596 -40768202.4791 +2723 2596 -17881456.80322 +2724 2596 14339328.79045 +2725 2596 -19430363.65775 +2726 2596 17403019.36621 +2597 2597 472661441.9387 +2607 2597 19043969.25406 +2608 2597 9605408.869306 +2609 2597 -22428183.64302 +2610 2597 -19183408.42037 +2611 2597 -23333069.93135 +2612 2597 -17381025.25039 +2613 2597 -22970248.13801 +2614 2597 13094327.72975 +2615 2597 12599401.48509 +2691 2597 6582676.791154 +2692 2597 -7899222.206021 +2693 2597 4086353.712421 +2703 2597 -8007766.485252 +2704 2597 -33293672.07046 +2705 2597 -17559666.33271 +2706 2597 -4818855.100867 +2707 2597 -21102266.9381 +2708 2597 -61666013.98076 +2718 2597 -8444910.309145 +2719 2597 -8163229.232496 +2720 2597 -10570710.68328 +2721 2597 -57630268.59944 +2722 2597 -16401283.68257 +2723 2597 -82291258.12151 +2724 2597 -21754203.08579 +2725 2597 11602012.9108 +2726 2597 -51814303.08735 +2598 2598 787899476.9604 +2599 2598 2.861022949219e-05 +2600 2598 7037134.828232 +2601 2598 89408469.17376 +2602 2598 -1.275539398193e-05 +2603 2598 1759283.707933 +2616 2598 -185415908.7468 +2617 2598 4.678964614868e-06 +2618 2598 -4574122.969536 +2619 2598 -73761541.41083 +2620 2598 47777777.76992 +2621 2598 -20803252.962 +2694 2598 -71968136.03531 +2695 2598 4.157423973083e-06 +2696 2598 51943969.87703 +2697 2598 -29817851.87049 +2698 2598 -11944444.44837 +2699 2598 17900923.03284 +2709 2598 88895212.80375 +2710 2598 4.112720489502e-06 +2711 2598 1759282.450699 +2712 2598 -25612922.63328 +2713 2598 -1.080334186554e-05 +2714 2598 439820.6129002 +2727 2598 -74762019.75572 +2728 2598 2.533197402954e-07 +2729 2598 -53703252.3277 +2730 2598 -30778677.45218 +2731 2598 11944444.44836 +2732 2598 -18340743.64572 +2599 2599 673225551.0007 +2600 2599 -84443270.91034 +2601 2599 -1.353025436401e-05 +2602 2599 -92146776.52992 +2603 2599 43066079.89948 +2616 2599 5.662441253662e-06 +2617 2599 24807818.43265 +2618 2599 -21110817.73799 +2619 2599 47777777.76992 +2620 2599 -59427300.65882 +2621 2599 11716519.98007 +2694 2599 3.337860107422e-06 +2695 2599 -19412223.56332 +2696 2599 -5277708.208769 +2697 2599 -11944444.44837 +2698 2599 -26234303.34662 +2699 2599 12913159.66331 +2709 2599 4.351139068604e-06 +2710 2599 60226824.62697 +2711 2599 -21110832.82468 +2712 2599 -9.95397567749e-06 +2713 2599 -71001738.06458 +2714 2599 52813749.73867 +2727 2599 -8.195638656616e-07 +2728 2599 -22206107.28377 +2729 2599 -5277708.20877 +2730 2599 11944444.44836 +2731 2599 -27195128.92833 +2732 2599 13440937.44126 +2600 2600 729298788.5117 +2601 2600 1759283.707934 +2602 2600 41377191.01087 +2603 2600 48367727.64837 +2616 2600 -2463011.858771 +2617 2600 -21110817.73799 +2618 2600 38554054.16679 +2619 2600 -20539364.07277 +2620 2600 11505408.86868 +2621 2600 -25226633.25495 +2694 2600 51680080.98832 +2695 2600 -5277708.208769 +2696 2600 -58666023.42418 +2697 2600 17900923.03284 +2698 2600 12913159.66331 +2699 2600 -36646590.5368 +2709 2600 1759282.450699 +2710 2600 -21110832.82468 +2711 2600 -105887547.9636 +2712 2600 439820.6129005 +2713 2600 52602638.6277 +2714 2600 -115814770.8741 +2727 2600 -53439363.43899 +2728 2600 -5277708.20877 +2729 2600 -66116380.01208 +2730 2600 -18340743.64572 +2731 2600 13440937.44126 +2732 2600 -39208792.08802 +2601 2601 787899476.9604 +2602 2601 2.861022949219e-05 +2603 2601 7037134.828232 +2604 2601 89408469.17376 +2605 2601 -1.275539398193e-05 +2606 2601 1759283.707933 +2616 2601 -72712122.80639 +2617 2601 -47777777.76993 +2618 2601 18780080.36483 +2619 2601 -185415908.7468 +2620 2601 4.678964614868e-06 +2621 2601 -4574122.969536 +2622 2601 -73761541.41083 +2623 2601 47777777.76992 +2624 2601 -20803252.962 +2694 2601 -19603280.6462 +2695 2601 11944444.44837 +2696 2601 8005089.696258 +2697 2601 -71968136.03531 +2698 2601 4.157423973083e-06 +2699 2601 51943969.87703 +2700 2601 -29817851.87049 +2701 2601 -11944444.44837 +2702 2601 17900923.03284 +2709 2601 16294780.8482 +2710 2601 4.217028617859e-06 +2711 2601 439820.6128852 +2712 2601 88895212.80375 +2713 2601 4.112720489502e-06 +2714 2601 1759282.450699 +2715 2601 -25612922.63328 +2716 2601 -1.080334186554e-05 +2717 2601 439820.6129002 +2727 2601 -20039396.92541 +2728 2601 -11944444.44837 +2729 2601 -8444910.309145 +2730 2601 -74762019.75572 +2731 2601 2.533197402954e-07 +2732 2601 -53703252.3277 +2733 2601 -30778677.45218 +2734 2601 11944444.44836 +2735 2601 -18340743.64572 +2602 2602 673225551.0007 +2603 2602 -84443270.91034 +2604 2602 -1.353025436401e-05 +2605 2602 -92146776.52992 +2606 2602 43066079.89948 +2616 2602 -47777777.76993 +2617 2602 -58377882.05435 +2618 2602 9394297.757917 +2619 2602 5.662441253662e-06 +2620 2602 24807818.43265 +2621 2602 -21110817.73799 +2622 2602 47777777.76992 +2623 2602 -59427300.65882 +2624 2602 11716519.98007 +2694 2602 11944444.44837 +2695 2602 -16019732.12234 +2696 2602 -7635451.454545 +2697 2602 3.337860107422e-06 +2698 2602 -19412223.56332 +2699 2602 -5277708.208769 +2700 2602 -11944444.44837 +2701 2602 -26234303.34662 +2702 2602 12913159.66331 +2709 2602 5.125999450684e-06 +2710 2602 -29094034.58311 +2711 2602 -31702916.914 +2712 2602 4.351139068604e-06 +2713 2602 60226824.62697 +2714 2602 -21110832.82468 +2715 2602 -9.95397567749e-06 +2716 2602 -71001738.06458 +2717 2602 52813749.73867 +2727 2602 -11944444.44837 +2728 2602 -16455848.40155 +2729 2602 -8163229.232496 +2730 2602 -8.195638656616e-07 +2731 2602 -22206107.28377 +2732 2602 -5277708.20877 +2733 2602 11944444.44836 +2734 2602 -27195128.92833 +2735 2602 13440937.44126 +2603 2603 729298788.5117 +2604 2603 1759283.707934 +2605 2603 41377191.01087 +2606 2603 48367727.64837 +2616 2603 19043969.25406 +2617 2603 9605408.869306 +2618 2603 -22428183.64302 +2619 2603 -2463011.858771 +2620 2603 -21110817.73799 +2621 2603 38554054.16679 +2622 2603 -20539364.07277 +2623 2603 11505408.86868 +2624 2603 -25226633.25495 +2694 2603 8005089.696258 +2695 2603 -7635451.454545 +2696 2603 -9407733.938713 +2697 2603 51680080.98832 +2698 2603 -5277708.208769 +2699 2603 -58666023.42418 +2700 2603 17900923.03284 +2701 2603 12913159.66331 +2702 2603 -36646590.5368 +2709 2603 439820.6128855 +2710 2603 -31491805.80303 +2711 2603 -4060894.923526 +2712 2603 1759282.450699 +2713 2603 -21110832.82468 +2714 2603 -105887547.9636 +2715 2603 439820.6129005 +2716 2603 52602638.6277 +2717 2603 -115814770.8741 +2727 2603 -8444910.309145 +2728 2603 -8163229.232496 +2729 2603 -10570710.68328 +2730 2603 -53439363.43899 +2731 2603 -5277708.20877 +2732 2603 -66116380.01208 +2733 2603 -18340743.64572 +2734 2603 13440937.44126 +2735 2603 -39208792.08802 +2604 2604 787899476.9604 +2605 2604 2.861022949219e-05 +2606 2604 7037134.828232 +2607 2604 89408469.17376 +2608 2604 -1.275539398193e-05 +2609 2604 1759283.707933 +2619 2604 -72712122.80639 +2620 2604 -47777777.76993 +2621 2604 18780080.36483 +2622 2604 -185415908.7468 +2623 2604 4.678964614868e-06 +2624 2604 -4574122.969536 +2625 2604 -73761541.41083 +2626 2604 47777777.76992 +2627 2604 -20803252.962 +2697 2604 -19603280.6462 +2698 2604 11944444.44837 +2699 2604 8005089.696258 +2700 2604 -71968136.03531 +2701 2604 4.157423973083e-06 +2702 2604 51943969.87703 +2703 2604 -29817851.87049 +2704 2604 -11944444.44837 +2705 2604 17900923.03284 +2712 2604 16294780.8482 +2713 2604 4.217028617859e-06 +2714 2604 439820.6128852 +2715 2604 88895212.80375 +2716 2604 4.112720489502e-06 +2717 2604 1759282.450699 +2718 2604 -25612922.63328 +2719 2604 -1.080334186554e-05 +2720 2604 439820.6129002 +2730 2604 -20039396.92541 +2731 2604 -11944444.44837 +2732 2604 -8444910.309145 +2733 2604 -74762019.75572 +2734 2604 2.533197402954e-07 +2735 2604 -53703252.3277 +2736 2604 -30778677.45218 +2737 2604 11944444.44836 +2738 2604 -18340743.64572 +2605 2605 673225551.0007 +2606 2605 -84443270.91034 +2607 2605 -1.353025436401e-05 +2608 2605 -92146776.52992 +2609 2605 43066079.89948 +2619 2605 -47777777.76993 +2620 2605 -58377882.05435 +2621 2605 9394297.757917 +2622 2605 5.662441253662e-06 +2623 2605 24807818.43265 +2624 2605 -21110817.73799 +2625 2605 47777777.76992 +2626 2605 -59427300.65882 +2627 2605 11716519.98007 +2697 2605 11944444.44837 +2698 2605 -16019732.12234 +2699 2605 -7635451.454545 +2700 2605 3.337860107422e-06 +2701 2605 -19412223.56332 +2702 2605 -5277708.208769 +2703 2605 -11944444.44837 +2704 2605 -26234303.34662 +2705 2605 12913159.66331 +2712 2605 5.125999450684e-06 +2713 2605 -29094034.58311 +2714 2605 -31702916.914 +2715 2605 4.351139068604e-06 +2716 2605 60226824.62697 +2717 2605 -21110832.82468 +2718 2605 -9.95397567749e-06 +2719 2605 -71001738.06458 +2720 2605 52813749.73867 +2730 2605 -11944444.44837 +2731 2605 -16455848.40155 +2732 2605 -8163229.232496 +2733 2605 -8.195638656616e-07 +2734 2605 -22206107.28377 +2735 2605 -5277708.20877 +2736 2605 11944444.44836 +2737 2605 -27195128.92833 +2738 2605 13440937.44126 +2606 2606 729298788.5117 +2607 2606 1759283.707934 +2608 2606 41377191.01087 +2609 2606 48367727.64837 +2619 2606 19043969.25406 +2620 2606 9605408.869306 +2621 2606 -22428183.64302 +2622 2606 -2463011.858771 +2623 2606 -21110817.73799 +2624 2606 38554054.16679 +2625 2606 -20539364.07277 +2626 2606 11505408.86868 +2627 2606 -25226633.25495 +2697 2606 8005089.696258 +2698 2606 -7635451.454545 +2699 2606 -9407733.938713 +2700 2606 51680080.98832 +2701 2606 -5277708.208769 +2702 2606 -58666023.42418 +2703 2606 17900923.03284 +2704 2606 12913159.66331 +2705 2606 -36646590.5368 +2712 2606 439820.6128855 +2713 2606 -31491805.80303 +2714 2606 -4060894.923526 +2715 2606 1759282.450699 +2716 2606 -21110832.82468 +2717 2606 -105887547.9636 +2718 2606 439820.6129005 +2719 2606 52602638.6277 +2720 2606 -115814770.8741 +2730 2606 -8444910.309145 +2731 2606 -8163229.232496 +2732 2606 -10570710.68328 +2733 2606 -53439363.43899 +2734 2606 -5277708.20877 +2735 2606 -66116380.01208 +2736 2606 -18340743.64572 +2737 2606 13440937.44126 +2738 2606 -39208792.08802 +2607 2607 787899476.9604 +2608 2607 2.861022949219e-05 +2609 2607 7037134.828232 +2610 2607 89408469.17376 +2611 2607 -1.275539398193e-05 +2612 2607 1759283.707933 +2622 2607 -72712122.80639 +2623 2607 -47777777.76993 +2624 2607 18780080.36483 +2625 2607 -185415908.7468 +2626 2607 4.678964614868e-06 +2627 2607 -4574122.969536 +2628 2607 -73761541.41083 +2629 2607 47777777.76992 +2630 2607 -20803252.962 +2700 2607 -19603280.6462 +2701 2607 11944444.44837 +2702 2607 8005089.696258 +2703 2607 -71968136.03531 +2704 2607 4.157423973083e-06 +2705 2607 51943969.87703 +2706 2607 -29817851.87049 +2707 2607 -11944444.44837 +2708 2607 17900923.03284 +2715 2607 16294780.8482 +2716 2607 4.217028617859e-06 +2717 2607 439820.6128852 +2718 2607 88895212.80375 +2719 2607 4.112720489502e-06 +2720 2607 1759282.450699 +2721 2607 -25612922.63328 +2722 2607 -1.080334186554e-05 +2723 2607 439820.6129002 +2733 2607 -20039396.92541 +2734 2607 -11944444.44837 +2735 2607 -8444910.309145 +2736 2607 -74762019.75572 +2737 2607 2.533197402954e-07 +2738 2607 -53703252.3277 +2739 2607 -30778677.45218 +2740 2607 11944444.44836 +2741 2607 -18340743.64572 +2608 2608 673225551.0007 +2609 2608 -84443270.91034 +2610 2608 -1.353025436401e-05 +2611 2608 -92146776.52992 +2612 2608 43066079.89948 +2622 2608 -47777777.76993 +2623 2608 -58377882.05435 +2624 2608 9394297.757917 +2625 2608 5.662441253662e-06 +2626 2608 24807818.43265 +2627 2608 -21110817.73799 +2628 2608 47777777.76992 +2629 2608 -59427300.65882 +2630 2608 11716519.98007 +2700 2608 11944444.44837 +2701 2608 -16019732.12234 +2702 2608 -7635451.454545 +2703 2608 3.337860107422e-06 +2704 2608 -19412223.56332 +2705 2608 -5277708.208769 +2706 2608 -11944444.44837 +2707 2608 -26234303.34662 +2708 2608 12913159.66331 +2715 2608 5.125999450684e-06 +2716 2608 -29094034.58311 +2717 2608 -31702916.914 +2718 2608 4.351139068604e-06 +2719 2608 60226824.62697 +2720 2608 -21110832.82468 +2721 2608 -9.95397567749e-06 +2722 2608 -71001738.06458 +2723 2608 52813749.73867 +2733 2608 -11944444.44837 +2734 2608 -16455848.40155 +2735 2608 -8163229.232496 +2736 2608 -8.195638656616e-07 +2737 2608 -22206107.28377 +2738 2608 -5277708.20877 +2739 2608 11944444.44836 +2740 2608 -27195128.92833 +2741 2608 13440937.44126 +2609 2609 729298788.5117 +2610 2609 1759283.707934 +2611 2609 41377191.01087 +2612 2609 48367727.64837 +2622 2609 19043969.25406 +2623 2609 9605408.869306 +2624 2609 -22428183.64302 +2625 2609 -2463011.858771 +2626 2609 -21110817.73799 +2627 2609 38554054.16679 +2628 2609 -20539364.07277 +2629 2609 11505408.86868 +2630 2609 -25226633.25495 +2700 2609 8005089.696258 +2701 2609 -7635451.454545 +2702 2609 -9407733.938713 +2703 2609 51680080.98832 +2704 2609 -5277708.208769 +2705 2609 -58666023.42418 +2706 2609 17900923.03284 +2707 2609 12913159.66331 +2708 2609 -36646590.5368 +2715 2609 439820.6128855 +2716 2609 -31491805.80303 +2717 2609 -4060894.923526 +2718 2609 1759282.450699 +2719 2609 -21110832.82468 +2720 2609 -105887547.9636 +2721 2609 439820.6129005 +2722 2609 52602638.6277 +2723 2609 -115814770.8741 +2733 2609 -8444910.309145 +2734 2609 -8163229.232496 +2735 2609 -10570710.68328 +2736 2609 -53439363.43899 +2737 2609 -5277708.20877 +2738 2609 -66116380.01208 +2739 2609 -18340743.64572 +2740 2609 13440937.44126 +2741 2609 -39208792.08802 +2610 2610 852898004.744 +2611 2610 47822261.56058 +2612 2610 23750813.775 +2613 2610 10663984.89933 +2614 2610 -47795571.28619 +2615 2610 20811196.16841 +2625 2610 -72712122.80639 +2626 2610 -47777777.76993 +2627 2610 18780080.36483 +2628 2610 -185415908.7468 +2629 2610 4.678964614868e-06 +2630 2610 -4574122.969536 +2631 2610 -73761541.41083 +2632 2610 47777777.76992 +2633 2610 -20803252.962 +2703 2610 -19603280.6462 +2704 2610 11944444.44837 +2705 2610 8005089.696258 +2706 2610 -85740387.93072 +2707 2610 -11950439.90077 +2708 2610 47775096.06898 +2718 2610 16294780.8482 +2719 2610 4.217028617859e-06 +2720 2610 439820.6128852 +2721 2610 112006329.4708 +2722 2610 11954436.86906 +2723 2610 5935349.843305 +2724 2610 -36979414.9719 +2725 2610 -11948441.41664 +2726 2610 18346879.03149 +2736 2610 -20039396.92541 +2737 2610 -11944444.44837 +2738 2610 -8444910.309145 +2739 2610 -74762019.75572 +2740 2610 2.533197402954e-07 +2741 2610 -53703252.3277 +2742 2610 -30778677.45218 +2743 2610 11944444.44836 +2744 2610 -18340743.64572 +2611 2611 723869819.0551 +2612 2611 -65442952.40696 +2613 2611 -47804468.04432 +2614 2611 -156592606.5887 +2615 2611 35894402.90473 +2625 2611 -47777777.76993 +2626 2611 -58377882.05435 +2627 2611 9394297.757917 +2628 2611 5.662441253662e-06 +2629 2611 24807818.43265 +2630 2611 -21110817.73799 +2631 2611 47777777.76992 +2632 2611 -59427300.65882 +2633 2611 11716519.98007 +2703 2611 11944444.44837 +2704 2611 -16019732.12234 +2705 2611 -7635451.454545 +2706 2611 -11948441.41664 +2707 2611 -29588436.2443 +2708 2611 4682155.144749 +2718 2611 5.125999450684e-06 +2719 2611 -29094034.58311 +2720 2611 -31702916.914 +2721 2611 11954436.86906 +2722 2611 79749895.91067 +2723 2611 -16362631.77783 +2724 2611 -11950439.90078 +2725 2611 -78792675.71048 +2726 2611 51029508.03613 +2736 2611 -11944444.44837 +2737 2611 -16455848.40155 +2738 2611 -8163229.232496 +2739 2611 -8.195638656616e-07 +2740 2611 -22206107.28377 +2741 2611 -5277708.20877 +2742 2611 11944444.44836 +2743 2611 -27195128.92833 +2744 2611 13440937.44126 +2612 2612 730917912.008 +2613 2612 20551278.88239 +2614 2612 40119834.77044 +2615 2612 9888833.293587 +2625 2612 19043969.25406 +2626 2612 9605408.869306 +2627 2612 -22428183.64302 +2628 2612 -2463011.858771 +2629 2612 -21110817.73799 +2630 2612 38554054.16679 +2631 2612 -20539364.07277 +2632 2612 11505408.86868 +2633 2612 -25226633.25495 +2703 2612 8005089.696258 +2704 2612 -7635451.454545 +2705 2612 -9407733.938713 +2706 2612 47510397.70207 +2707 2612 3205506.989851 +2708 2612 -52478548.16204 +2718 2612 439820.6128855 +2719 2612 -31491805.80303 +2720 2612 -4060894.923526 +2721 2612 5939756.113784 +2722 2612 -16359106.80793 +2723 2612 -87179377.66603 +2724 2612 18349946.72438 +2725 2612 52296851.6274 +2726 2612 -103249742.1615 +2736 2612 -8444910.309145 +2737 2612 -8163229.232496 +2738 2612 -10570710.68328 +2739 2612 -53439363.43899 +2740 2612 -5277708.20877 +2741 2612 -66116380.01208 +2742 2612 -18340743.64572 +2743 2612 13440937.44126 +2744 2612 -39208792.08802 +2613 2613 404739861.6568 +2614 2613 -11848182.92845 +2615 2613 -7247227.153557 +2628 2613 -72712122.80639 +2629 2613 -47777777.76993 +2630 2613 18780080.36483 +2631 2613 -131522618.6576 +2632 2613 11758507.45862 +2633 2613 -2246788.336919 +2634 2613 -71992455.07851 +2635 2613 38311897.68579 +2636 2613 -2118024.903648 +2706 2613 1532382.642161 +2707 2613 14339328.79045 +2708 2613 9874015.186731 +2721 2613 -4845636.536104 +2722 2613 -11950439.90078 +2723 2613 -8009104.879749 +2724 2613 45154799.16275 +2725 2613 -1984038.076042 +2726 2613 5318188.302819 +2739 2613 -20039396.92541 +2740 2613 -11944444.44837 +2741 2613 -8444910.309145 +2742 2613 -54446261.20618 +2743 2613 1964829.816336 +2744 2613 -37868990.52104 +2745 2613 -20832796.07979 +2746 2613 9574763.8184 +2747 2613 -4947522.887458 +2614 2614 486884655.0059 +2615 2614 -56349720.67878 +2628 2614 -47777777.76993 +2629 2614 -58377882.05435 +2630 2614 9394297.757917 +2631 2614 11713669.72369 +2632 2614 66482451.11392 +2633 2614 -13793542.99022 +2634 2614 57467846.52868 +2635 2614 -199219967.4632 +2636 2614 12610421.48169 +2706 2614 9559552.526969 +2707 2614 1532382.642157 +2708 2614 -5266148.137347 +2721 2614 -11948441.41664 +2722 2614 -46658897.27468 +2723 2614 -32026328.33686 +2724 2614 -1984038.076043 +2725 2614 60242385.44579 +2726 2614 -8284128.881153 +2739 2614 -11944444.44837 +2740 2614 -16455848.40155 +2741 2614 -8163229.232496 +2742 2614 1955225.686481 +2743 2614 -4515066.791966 +2744 2614 -1847868.948734 +2745 2614 14362145.7276 +2746 2614 -47621864.56235 +2747 2614 20366850.75772 +2615 2615 414669440.4442 +2628 2615 19043969.25406 +2629 2615 9605408.869306 +2630 2615 -22428183.64302 +2631 2615 -6993796.082146 +2632 2615 -12945585.99015 +2633 2615 33760011.09959 +2634 2615 -3177037.355472 +2635 2615 11767430.40646 +2636 2615 -64752367.82467 +2706 2615 6582676.791154 +2707 2615 -7899222.206021 +2708 2615 4086353.712421 +2721 2615 -8007766.485252 +2722 2615 -33293672.07046 +2723 2615 -17559666.33271 +2724 2615 -9638402.083643 +2725 2615 -20236111.15782 +2726 2615 -45956057.35504 +2739 2615 -8444910.309145 +2740 2615 -8163229.232496 +2741 2615 -10570710.68328 +2742 2615 -39187801.2437 +2743 2615 -1627591.468903 +2744 2615 -43839955.45809 +2745 2615 -7421284.331187 +2746 2615 18388546.96739 +2747 2615 -28765054.39688 +2616 2616 787899476.9604 +2617 2616 2.861022949219e-05 +2618 2616 7037134.828232 +2619 2616 89408469.17376 +2620 2616 -1.275539398193e-05 +2621 2616 1759283.707933 +2637 2616 -185415908.7468 +2638 2616 4.678964614868e-06 +2639 2616 -4574122.969536 +2640 2616 -73761541.41083 +2641 2616 47777777.76992 +2642 2616 -20803252.962 +2709 2616 -71968136.03531 +2710 2616 4.157423973083e-06 +2711 2616 51943969.87703 +2712 2616 -29817851.87049 +2713 2616 -11944444.44837 +2714 2616 17900923.03284 +2727 2616 88895212.80375 +2728 2616 4.112720489502e-06 +2729 2616 1759282.450699 +2730 2616 -25612922.63328 +2731 2616 -1.080334186554e-05 +2732 2616 439820.6129002 +2748 2616 -74762019.75572 +2749 2616 2.533197402954e-07 +2750 2616 -53703252.3277 +2751 2616 -30778677.45218 +2752 2616 11944444.44836 +2753 2616 -18340743.64572 +2617 2617 673225551.0007 +2618 2617 -84443270.91034 +2619 2617 -1.353025436401e-05 +2620 2617 -92146776.52992 +2621 2617 43066079.89948 +2637 2617 5.662441253662e-06 +2638 2617 24807818.43265 +2639 2617 -21110817.73799 +2640 2617 47777777.76992 +2641 2617 -59427300.65882 +2642 2617 11716519.98007 +2709 2617 3.337860107422e-06 +2710 2617 -19412223.56332 +2711 2617 -5277708.208769 +2712 2617 -11944444.44837 +2713 2617 -26234303.34662 +2714 2617 12913159.66331 +2727 2617 4.351139068604e-06 +2728 2617 60226824.62697 +2729 2617 -21110832.82468 +2730 2617 -9.95397567749e-06 +2731 2617 -71001738.06458 +2732 2617 52813749.73867 +2748 2617 -8.195638656616e-07 +2749 2617 -22206107.28377 +2750 2617 -5277708.20877 +2751 2617 11944444.44836 +2752 2617 -27195128.92833 +2753 2617 13440937.44126 +2618 2618 729298788.5117 +2619 2618 1759283.707934 +2620 2618 41377191.01087 +2621 2618 48367727.64837 +2637 2618 -2463011.858771 +2638 2618 -21110817.73799 +2639 2618 38554054.16679 +2640 2618 -20539364.07277 +2641 2618 11505408.86868 +2642 2618 -25226633.25495 +2709 2618 51680080.98832 +2710 2618 -5277708.208769 +2711 2618 -58666023.42418 +2712 2618 17900923.03284 +2713 2618 12913159.66331 +2714 2618 -36646590.5368 +2727 2618 1759282.450699 +2728 2618 -21110832.82468 +2729 2618 -105887547.9636 +2730 2618 439820.6129005 +2731 2618 52602638.6277 +2732 2618 -115814770.8741 +2748 2618 -53439363.43899 +2749 2618 -5277708.20877 +2750 2618 -66116380.01208 +2751 2618 -18340743.64572 +2752 2618 13440937.44126 +2753 2618 -39208792.08802 +2619 2619 787899476.9604 +2620 2619 2.861022949219e-05 +2621 2619 7037134.828232 +2622 2619 89408469.17376 +2623 2619 -1.275539398193e-05 +2624 2619 1759283.707933 +2637 2619 -72712122.80639 +2638 2619 -47777777.76993 +2639 2619 18780080.36483 +2640 2619 -185415908.7468 +2641 2619 4.678964614868e-06 +2642 2619 -4574122.969536 +2643 2619 -73761541.41083 +2644 2619 47777777.76992 +2645 2619 -20803252.962 +2709 2619 -19603280.6462 +2710 2619 11944444.44837 +2711 2619 8005089.696258 +2712 2619 -71968136.03531 +2713 2619 4.157423973083e-06 +2714 2619 51943969.87703 +2715 2619 -29817851.87049 +2716 2619 -11944444.44837 +2717 2619 17900923.03284 +2727 2619 16294780.8482 +2728 2619 4.217028617859e-06 +2729 2619 439820.6128852 +2730 2619 88895212.80375 +2731 2619 4.112720489502e-06 +2732 2619 1759282.450699 +2733 2619 -25612922.63328 +2734 2619 -1.080334186554e-05 +2735 2619 439820.6129002 +2748 2619 -20039396.92541 +2749 2619 -11944444.44837 +2750 2619 -8444910.309145 +2751 2619 -74762019.75572 +2752 2619 2.533197402954e-07 +2753 2619 -53703252.3277 +2754 2619 -30778677.45218 +2755 2619 11944444.44836 +2756 2619 -18340743.64572 +2620 2620 673225551.0007 +2621 2620 -84443270.91034 +2622 2620 -1.353025436401e-05 +2623 2620 -92146776.52992 +2624 2620 43066079.89948 +2637 2620 -47777777.76993 +2638 2620 -58377882.05435 +2639 2620 9394297.757917 +2640 2620 5.662441253662e-06 +2641 2620 24807818.43265 +2642 2620 -21110817.73799 +2643 2620 47777777.76992 +2644 2620 -59427300.65882 +2645 2620 11716519.98007 +2709 2620 11944444.44837 +2710 2620 -16019732.12234 +2711 2620 -7635451.454545 +2712 2620 3.337860107422e-06 +2713 2620 -19412223.56332 +2714 2620 -5277708.208769 +2715 2620 -11944444.44837 +2716 2620 -26234303.34662 +2717 2620 12913159.66331 +2727 2620 5.125999450684e-06 +2728 2620 -29094034.58311 +2729 2620 -31702916.914 +2730 2620 4.351139068604e-06 +2731 2620 60226824.62697 +2732 2620 -21110832.82468 +2733 2620 -9.95397567749e-06 +2734 2620 -71001738.06458 +2735 2620 52813749.73867 +2748 2620 -11944444.44837 +2749 2620 -16455848.40155 +2750 2620 -8163229.232496 +2751 2620 -8.195638656616e-07 +2752 2620 -22206107.28377 +2753 2620 -5277708.20877 +2754 2620 11944444.44836 +2755 2620 -27195128.92833 +2756 2620 13440937.44126 +2621 2621 729298788.5117 +2622 2621 1759283.707934 +2623 2621 41377191.01087 +2624 2621 48367727.64837 +2637 2621 19043969.25406 +2638 2621 9605408.869306 +2639 2621 -22428183.64302 +2640 2621 -2463011.858771 +2641 2621 -21110817.73799 +2642 2621 38554054.16679 +2643 2621 -20539364.07277 +2644 2621 11505408.86868 +2645 2621 -25226633.25495 +2709 2621 8005089.696258 +2710 2621 -7635451.454545 +2711 2621 -9407733.938713 +2712 2621 51680080.98832 +2713 2621 -5277708.208769 +2714 2621 -58666023.42418 +2715 2621 17900923.03284 +2716 2621 12913159.66331 +2717 2621 -36646590.5368 +2727 2621 439820.6128855 +2728 2621 -31491805.80303 +2729 2621 -4060894.923526 +2730 2621 1759282.450699 +2731 2621 -21110832.82468 +2732 2621 -105887547.9636 +2733 2621 439820.6129005 +2734 2621 52602638.6277 +2735 2621 -115814770.8741 +2748 2621 -8444910.309145 +2749 2621 -8163229.232496 +2750 2621 -10570710.68328 +2751 2621 -53439363.43899 +2752 2621 -5277708.20877 +2753 2621 -66116380.01208 +2754 2621 -18340743.64572 +2755 2621 13440937.44126 +2756 2621 -39208792.08802 +2622 2622 787899476.9604 +2623 2622 2.861022949219e-05 +2624 2622 7037134.828232 +2625 2622 89408469.17376 +2626 2622 -1.275539398193e-05 +2627 2622 1759283.707933 +2640 2622 -72712122.80639 +2641 2622 -47777777.76993 +2642 2622 18780080.36483 +2643 2622 -185415908.7468 +2644 2622 4.678964614868e-06 +2645 2622 -4574122.969536 +2646 2622 -73761541.41083 +2647 2622 47777777.76992 +2648 2622 -20803252.962 +2712 2622 -19603280.6462 +2713 2622 11944444.44837 +2714 2622 8005089.696258 +2715 2622 -71968136.03531 +2716 2622 4.157423973083e-06 +2717 2622 51943969.87703 +2718 2622 -29817851.87049 +2719 2622 -11944444.44837 +2720 2622 17900923.03284 +2730 2622 16294780.8482 +2731 2622 4.217028617859e-06 +2732 2622 439820.6128852 +2733 2622 88895212.80375 +2734 2622 4.112720489502e-06 +2735 2622 1759282.450699 +2736 2622 -25612922.63328 +2737 2622 -1.080334186554e-05 +2738 2622 439820.6129002 +2751 2622 -20039396.92541 +2752 2622 -11944444.44837 +2753 2622 -8444910.309145 +2754 2622 -74762019.75572 +2755 2622 2.533197402954e-07 +2756 2622 -53703252.3277 +2757 2622 -30778677.45218 +2758 2622 11944444.44836 +2759 2622 -18340743.64572 +2623 2623 673225551.0007 +2624 2623 -84443270.91034 +2625 2623 -1.353025436401e-05 +2626 2623 -92146776.52992 +2627 2623 43066079.89948 +2640 2623 -47777777.76993 +2641 2623 -58377882.05435 +2642 2623 9394297.757917 +2643 2623 5.662441253662e-06 +2644 2623 24807818.43265 +2645 2623 -21110817.73799 +2646 2623 47777777.76992 +2647 2623 -59427300.65882 +2648 2623 11716519.98007 +2712 2623 11944444.44837 +2713 2623 -16019732.12234 +2714 2623 -7635451.454545 +2715 2623 3.337860107422e-06 +2716 2623 -19412223.56332 +2717 2623 -5277708.208769 +2718 2623 -11944444.44837 +2719 2623 -26234303.34662 +2720 2623 12913159.66331 +2730 2623 5.125999450684e-06 +2731 2623 -29094034.58311 +2732 2623 -31702916.914 +2733 2623 4.351139068604e-06 +2734 2623 60226824.62697 +2735 2623 -21110832.82468 +2736 2623 -9.95397567749e-06 +2737 2623 -71001738.06458 +2738 2623 52813749.73867 +2751 2623 -11944444.44837 +2752 2623 -16455848.40155 +2753 2623 -8163229.232496 +2754 2623 -8.195638656616e-07 +2755 2623 -22206107.28377 +2756 2623 -5277708.20877 +2757 2623 11944444.44836 +2758 2623 -27195128.92833 +2759 2623 13440937.44126 +2624 2624 729298788.5117 +2625 2624 1759283.707934 +2626 2624 41377191.01087 +2627 2624 48367727.64837 +2640 2624 19043969.25406 +2641 2624 9605408.869306 +2642 2624 -22428183.64302 +2643 2624 -2463011.858771 +2644 2624 -21110817.73799 +2645 2624 38554054.16679 +2646 2624 -20539364.07277 +2647 2624 11505408.86868 +2648 2624 -25226633.25495 +2712 2624 8005089.696258 +2713 2624 -7635451.454545 +2714 2624 -9407733.938713 +2715 2624 51680080.98832 +2716 2624 -5277708.208769 +2717 2624 -58666023.42418 +2718 2624 17900923.03284 +2719 2624 12913159.66331 +2720 2624 -36646590.5368 +2730 2624 439820.6128855 +2731 2624 -31491805.80303 +2732 2624 -4060894.923526 +2733 2624 1759282.450699 +2734 2624 -21110832.82468 +2735 2624 -105887547.9636 +2736 2624 439820.6129005 +2737 2624 52602638.6277 +2738 2624 -115814770.8741 +2751 2624 -8444910.309145 +2752 2624 -8163229.232496 +2753 2624 -10570710.68328 +2754 2624 -53439363.43899 +2755 2624 -5277708.20877 +2756 2624 -66116380.01208 +2757 2624 -18340743.64572 +2758 2624 13440937.44126 +2759 2624 -39208792.08802 +2625 2625 787899476.9604 +2626 2625 2.861022949219e-05 +2627 2625 7037134.828232 +2628 2625 89408469.17376 +2629 2625 -1.275539398193e-05 +2630 2625 1759283.707933 +2643 2625 -72712122.80639 +2644 2625 -47777777.76993 +2645 2625 18780080.36483 +2646 2625 -185415908.7468 +2647 2625 4.678964614868e-06 +2648 2625 -4574122.969536 +2649 2625 -73761541.41083 +2650 2625 47777777.76992 +2651 2625 -20803252.962 +2715 2625 -19603280.6462 +2716 2625 11944444.44837 +2717 2625 8005089.696258 +2718 2625 -71968136.03531 +2719 2625 4.157423973083e-06 +2720 2625 51943969.87703 +2721 2625 -29817851.87049 +2722 2625 -11944444.44837 +2723 2625 17900923.03284 +2733 2625 16294780.8482 +2734 2625 4.217028617859e-06 +2735 2625 439820.6128852 +2736 2625 88895212.80375 +2737 2625 4.112720489502e-06 +2738 2625 1759282.450699 +2739 2625 -25612922.63328 +2740 2625 -1.080334186554e-05 +2741 2625 439820.6129002 +2754 2625 -20039396.92541 +2755 2625 -11944444.44837 +2756 2625 -8444910.309145 +2757 2625 -74762019.75572 +2758 2625 2.533197402954e-07 +2759 2625 -53703252.3277 +2760 2625 -30778677.45218 +2761 2625 11944444.44836 +2762 2625 -18340743.64572 +2626 2626 673225551.0007 +2627 2626 -84443270.91034 +2628 2626 -1.353025436401e-05 +2629 2626 -92146776.52992 +2630 2626 43066079.89948 +2643 2626 -47777777.76993 +2644 2626 -58377882.05435 +2645 2626 9394297.757917 +2646 2626 5.662441253662e-06 +2647 2626 24807818.43265 +2648 2626 -21110817.73799 +2649 2626 47777777.76992 +2650 2626 -59427300.65882 +2651 2626 11716519.98007 +2715 2626 11944444.44837 +2716 2626 -16019732.12234 +2717 2626 -7635451.454545 +2718 2626 3.337860107422e-06 +2719 2626 -19412223.56332 +2720 2626 -5277708.208769 +2721 2626 -11944444.44837 +2722 2626 -26234303.34662 +2723 2626 12913159.66331 +2733 2626 5.125999450684e-06 +2734 2626 -29094034.58311 +2735 2626 -31702916.914 +2736 2626 4.351139068604e-06 +2737 2626 60226824.62697 +2738 2626 -21110832.82468 +2739 2626 -9.95397567749e-06 +2740 2626 -71001738.06458 +2741 2626 52813749.73867 +2754 2626 -11944444.44837 +2755 2626 -16455848.40155 +2756 2626 -8163229.232496 +2757 2626 -8.195638656616e-07 +2758 2626 -22206107.28377 +2759 2626 -5277708.20877 +2760 2626 11944444.44836 +2761 2626 -27195128.92833 +2762 2626 13440937.44126 +2627 2627 729298788.5117 +2628 2627 1759283.707934 +2629 2627 41377191.01087 +2630 2627 48367727.64837 +2643 2627 19043969.25406 +2644 2627 9605408.869306 +2645 2627 -22428183.64302 +2646 2627 -2463011.858771 +2647 2627 -21110817.73799 +2648 2627 38554054.16679 +2649 2627 -20539364.07277 +2650 2627 11505408.86868 +2651 2627 -25226633.25495 +2715 2627 8005089.696258 +2716 2627 -7635451.454545 +2717 2627 -9407733.938713 +2718 2627 51680080.98832 +2719 2627 -5277708.208769 +2720 2627 -58666023.42418 +2721 2627 17900923.03284 +2722 2627 12913159.66331 +2723 2627 -36646590.5368 +2733 2627 439820.6128855 +2734 2627 -31491805.80303 +2735 2627 -4060894.923526 +2736 2627 1759282.450699 +2737 2627 -21110832.82468 +2738 2627 -105887547.9636 +2739 2627 439820.6129005 +2740 2627 52602638.6277 +2741 2627 -115814770.8741 +2754 2627 -8444910.309145 +2755 2627 -8163229.232496 +2756 2627 -10570710.68328 +2757 2627 -53439363.43899 +2758 2627 -5277708.20877 +2759 2627 -66116380.01208 +2760 2627 -18340743.64572 +2761 2627 13440937.44126 +2762 2627 -39208792.08802 +2628 2628 787899476.9604 +2629 2628 2.861022949219e-05 +2630 2628 7037134.828232 +2631 2628 89408469.17376 +2632 2628 -1.275539398193e-05 +2633 2628 1759283.707933 +2646 2628 -72712122.80639 +2647 2628 -47777777.76993 +2648 2628 18780080.36483 +2649 2628 -185415908.7468 +2650 2628 4.678964614868e-06 +2651 2628 -4574122.969536 +2652 2628 -73761541.41083 +2653 2628 47777777.76992 +2654 2628 -20803252.962 +2718 2628 -19603280.6462 +2719 2628 11944444.44837 +2720 2628 8005089.696258 +2721 2628 -71968136.03531 +2722 2628 4.157423973083e-06 +2723 2628 51943969.87703 +2724 2628 -29817851.87049 +2725 2628 -11944444.44837 +2726 2628 17900923.03284 +2736 2628 16294780.8482 +2737 2628 4.217028617859e-06 +2738 2628 439820.6128852 +2739 2628 88895212.80375 +2740 2628 4.112720489502e-06 +2741 2628 1759282.450699 +2742 2628 -25612922.63328 +2743 2628 -1.080334186554e-05 +2744 2628 439820.6129002 +2757 2628 -20039396.92541 +2758 2628 -11944444.44837 +2759 2628 -8444910.309145 +2760 2628 -74762019.75572 +2761 2628 2.533197402954e-07 +2762 2628 -53703252.3277 +2763 2628 -30778677.45218 +2764 2628 11944444.44836 +2765 2628 -18340743.64572 +2629 2629 673225551.0007 +2630 2629 -84443270.91034 +2631 2629 -1.353025436401e-05 +2632 2629 -92146776.52992 +2633 2629 43066079.89948 +2646 2629 -47777777.76993 +2647 2629 -58377882.05435 +2648 2629 9394297.757917 +2649 2629 5.662441253662e-06 +2650 2629 24807818.43265 +2651 2629 -21110817.73799 +2652 2629 47777777.76992 +2653 2629 -59427300.65882 +2654 2629 11716519.98007 +2718 2629 11944444.44837 +2719 2629 -16019732.12234 +2720 2629 -7635451.454545 +2721 2629 3.337860107422e-06 +2722 2629 -19412223.56332 +2723 2629 -5277708.208769 +2724 2629 -11944444.44837 +2725 2629 -26234303.34662 +2726 2629 12913159.66331 +2736 2629 5.125999450684e-06 +2737 2629 -29094034.58311 +2738 2629 -31702916.914 +2739 2629 4.351139068604e-06 +2740 2629 60226824.62697 +2741 2629 -21110832.82468 +2742 2629 -9.95397567749e-06 +2743 2629 -71001738.06458 +2744 2629 52813749.73867 +2757 2629 -11944444.44837 +2758 2629 -16455848.40155 +2759 2629 -8163229.232496 +2760 2629 -8.195638656616e-07 +2761 2629 -22206107.28377 +2762 2629 -5277708.20877 +2763 2629 11944444.44836 +2764 2629 -27195128.92833 +2765 2629 13440937.44126 +2630 2630 729298788.5117 +2631 2630 1759283.707934 +2632 2630 41377191.01087 +2633 2630 48367727.64837 +2646 2630 19043969.25406 +2647 2630 9605408.869306 +2648 2630 -22428183.64302 +2649 2630 -2463011.858771 +2650 2630 -21110817.73799 +2651 2630 38554054.16679 +2652 2630 -20539364.07277 +2653 2630 11505408.86868 +2654 2630 -25226633.25495 +2718 2630 8005089.696258 +2719 2630 -7635451.454545 +2720 2630 -9407733.938713 +2721 2630 51680080.98832 +2722 2630 -5277708.208769 +2723 2630 -58666023.42418 +2724 2630 17900923.03284 +2725 2630 12913159.66331 +2726 2630 -36646590.5368 +2736 2630 439820.6128855 +2737 2630 -31491805.80303 +2738 2630 -4060894.923526 +2739 2630 1759282.450699 +2740 2630 -21110832.82468 +2741 2630 -105887547.9636 +2742 2630 439820.6129005 +2743 2630 52602638.6277 +2744 2630 -115814770.8741 +2757 2630 -8444910.309145 +2758 2630 -8163229.232496 +2759 2630 -10570710.68328 +2760 2630 -53439363.43899 +2761 2630 -5277708.20877 +2762 2630 -66116380.01208 +2763 2630 -18340743.64572 +2764 2630 13440937.44126 +2765 2630 -39208792.08802 +2631 2631 680142840.8764 +2632 2631 13175247.2066 +2633 2631 6382789.174558 +2634 2631 -82619272.09145 +2635 2631 -81460003.59595 +2636 2631 4837026.623929 +2649 2631 -72712122.80639 +2650 2631 -47777777.76993 +2651 2631 18780080.36483 +2652 2631 -131943732.0842 +2653 2631 25894289.31629 +2654 2631 -1690287.649399 +2655 2631 -44746568.51674 +2656 2631 30676797.34938 +2657 2631 -2534802.781049 +2721 2631 -19603280.6462 +2722 2631 11944444.44837 +2723 2631 8005089.696258 +2724 2631 -51389094.80041 +2725 2631 1955225.686484 +2726 2631 35595150.68861 +2739 2631 16294780.8482 +2740 2631 4.217028617859e-06 +2741 2631 439820.6128852 +2742 2631 89751427.48146 +2743 2631 3388998.455101 +2744 2631 1627256.23664 +2745 2631 -37804191.87041 +2746 2631 -19718417.92848 +2747 2631 14356015.6679 +2760 2631 -20039396.92541 +2761 2631 -11944444.44837 +2762 2631 -8444910.309145 +2763 2631 -60532186.86274 +2764 2631 6145877.671103 +2765 2631 -45375800.4239 +2766 2631 -19078219.62127 +2767 2631 8228316.115794 +2768 2631 -6175963.728574 +2632 2632 735751686.9788 +2633 2632 -52100622.42778 +2634 2632 -81504841.33087 +2635 2632 -266648531.6403 +2636 2632 10310073.83947 +2649 2632 -47777777.76993 +2650 2632 -58377882.05435 +2651 2632 9394297.757917 +2652 2632 25894289.31629 +2653 2632 34891492.87158 +2654 2632 -10707202.07691 +2655 2632 30676797.34938 +2656 2632 -128279685.5979 +2657 2632 5700516.123451 +2721 2632 11944444.44837 +2722 2632 -16019732.12234 +2723 2632 -7635451.454545 +2724 2632 1964829.816337 +2725 2632 -1457900.386174 +2726 2632 -5080618.041869 +2739 2632 5.125999450684e-06 +2740 2632 -29094034.58311 +2741 2632 -31702916.914 +2742 2632 3388998.455098 +2743 2632 100011639.1232 +2744 2632 -13368588.23948 +2745 2632 -19728022.05833 +2746 2632 -83236811.85808 +2747 2632 44683227.92718 +2760 2632 -11944444.44837 +2761 2632 -16455848.40155 +2762 2632 -8163229.232496 +2763 2632 6145877.671102 +2764 2632 -17818422.88929 +2765 2632 3275933.400212 +2766 2632 8228316.115794 +2767 2632 -38329051.2794 +2768 2632 18012970.71223 +2633 2633 621822217.5976 +2634 2633 4840483.520374 +2635 2633 10313958.28093 +2636 2633 -53773245.36454 +2649 2633 19043969.25406 +2650 2633 9605408.869306 +2651 2633 -22428183.64302 +2652 2633 -6440287.64862 +2653 2633 -10707202.07691 +2654 2633 45832031.608 +2655 2633 -2534802.780529 +2656 2633 5700516.123451 +2657 2633 -29032713.73637 +2721 2633 8005089.696258 +2722 2633 -7635451.454545 +2723 2633 -9407733.938713 +2724 2633 36913961.41127 +2725 2633 -5283969.107957 +2726 2633 -35687511.70929 +2739 2633 439820.6128855 +2740 2633 -31491805.80303 +2741 2633 -4060894.923526 +2742 2633 1636068.847779 +2743 2633 -13361537.70386 +2744 2633 -62110956.49564 +2745 2633 14361165.99813 +2746 2633 44679081.42414 +2747 2633 -62517889.38316 +2760 2633 -8444910.309145 +2761 2633 -8163229.232496 +2762 2633 -10570710.68328 +2763 2633 -46695244.86759 +2764 2633 3275933.401367 +2765 2633 -60107504.48815 +2766 2633 -6175963.728574 +2767 2633 18012970.71223 +2768 2633 -28603898.10301 +2634 2634 495839808.9306 +2635 2634 16337513.03765 +2636 2634 47664.71513438 +2652 2634 -75700660.41266 +2653 2634 -45408902.36255 +2654 2634 2674577.975484 +2655 2634 -30456445.17167 +2656 2634 36813695.54339 +2657 2634 -1688029.935787 +2658 2634 60889192.4204 +2659 2634 -23523603.93206 +2660 2634 -12036.74060798 +2661 2634 -19031852.31565 +2662 2634 39818292.51576 +2663 2634 -574511.0673158 +2724 2634 -17479931.67357 +2725 2634 14362145.7276 +2726 2634 5833486.609719 +2742 2634 -31941173.76503 +2743 2634 -19728022.05833 +2744 2634 -12009716.04913 +2745 2634 24089286.29196 +2746 2634 3839092.775206 +2747 2634 10350875.53811 +2763 2634 -25149760.01167 +2764 2634 -11436618.24716 +2765 2634 -12495973.82755 +2766 2634 -53221395.58403 +2767 2634 8623814.868827 +2768 2634 -52049556.20671 +2769 2634 -15616531.23755 +2770 2634 -5720032.851413 +2771 2634 11718275.57488 +2772 2634 -19138192.52839 +2773 2634 10059619.78527 +2774 2634 -12797947.19522 +2635 2635 714233526.3379 +2636 2635 -17784727.63113 +2652 2635 -45408902.36255 +2653 2635 -40143456.5852 +2654 2635 121080.7303977 +2655 2635 36813695.54338 +2656 2635 141843299.2925 +2657 2635 -3656369.598247 +2658 2635 -4412492.824084 +2659 2635 -31730042.91106 +2660 2635 420993.0422516 +2661 2635 39818292.51576 +2662 2635 -41406510.74943 +2663 2635 495848.037314 +2724 2635 9574763.8184 +2725 2635 -44269000.15613 +2726 2635 -13244377.7058 +2742 2635 -19718417.92848 +2743 2635 -77373793.75269 +2744 2635 -39681478.38126 +2745 2635 3839092.775206 +2746 2635 72806765.35626 +2747 2635 -2276323.108396 +2763 2635 -11436618.24716 +2764 2635 -16666806.57997 +2765 2635 -10481763.82233 +2766 2635 8623814.868826 +2767 2635 -9785420.099232 +2768 2635 5243568.66829 +2769 2635 -942255.0720671 +2770 2635 -38793986.71761 +2771 2635 33437788.15322 +2772 2635 10059619.78527 +2773 2635 -24375456.5589 +2774 2635 16788670.00494 +2636 2636 601702510.7098 +2652 2636 2674577.975744 +2653 2636 121080.7306057 +2654 2636 -12802814.23482 +2655 2636 -1688029.935786 +2656 2636 -3656369.598247 +2657 2636 151283500.6691 +2658 2636 -12036.74060512 +2659 2636 420993.0422515 +2660 2636 94679889.0428 +2661 2636 -574511.067056 +2662 2636 495848.037314 +2663 2636 22138037.08526 +2724 2636 3888991.073146 +2725 2636 -14800902.31119 +2726 2636 -19824082.64697 +2742 2636 -12006053.84798 +2743 2636 -39687207.82015 +2744 2636 -46883174.43545 +2745 2636 -10308568.90294 +2746 2636 -5821027.16094 +2747 2636 -112164251.0942 +2763 2636 -12495973.82755 +2764 2636 -10481763.82233 +2765 2636 -19781022.96801 +2766 2636 -52049556.20697 +2767 2636 5243568.669446 +2768 2636 -79607627.60272 +2769 2636 3593275.573656 +2770 2636 33437788.15322 +2771 2636 -58989344.86761 +2772 2636 -12797947.19522 +2773 2636 16788670.00494 +2774 2636 -31971025.74039 +2637 2637 393809815.9996 +2638 2637 1.168251037598e-05 +2639 2637 -1759210.362797 +2640 2637 44686744.27678 +2641 2637 9555555.553978 +2642 2637 -3738413.701805 +2727 2637 -71968136.03531 +2728 2637 4.157423973083e-06 +2729 2637 51943969.87703 +2730 2637 -29817851.87049 +2731 2637 -11944444.44837 +2732 2637 17900923.03284 +2748 2637 44430116.09181 +2749 2637 1.907348632813e-06 +2750 2637 -10318414.32804 +2751 2637 -12806461.31664 +2752 2637 2388888.889668 +2753 2637 -3404256.361406 +2638 2638 336472853.0197 +2639 2638 -42221635.45517 +2640 2638 -9555555.553992 +2641 2638 -46090878.57506 +2642 2638 21321928.83866 +2727 2638 3.337860107422e-06 +2728 2638 -19412223.56332 +2729 2638 -5277708.208769 +2730 2638 -11944444.44837 +2731 2638 -26234303.34662 +2732 2638 12913159.66331 +2748 2638 2.861022949219e-06 +2749 2638 30095922.00342 +2750 2638 -10555416.41234 +2751 2638 -2388888.889678 +2752 2638 -35500869.03229 +2753 2638 26354097.09154 +2639 2639 364276267.6409 +2640 2639 4178252.963561 +2641 2639 20899706.61651 +2642 2639 24137222.99725 +2727 2639 51680080.98832 +2728 2639 -5277708.208769 +2729 2639 -58666023.42418 +2730 2639 17900923.03284 +2731 2639 12913159.66331 +2732 2639 -36646590.5368 +2748 2639 10758252.33516 +2749 2639 -10555416.41234 +2750 2639 -52990414.80866 +2751 2639 3844076.974307 +2752 2639 26354097.09164 +2753 2639 -57907385.43707 +2640 2640 393809815.9996 +2641 2640 1.168251037598e-05 +2642 2640 -1759210.362797 +2643 2640 44686744.27678 +2644 2640 9555555.553978 +2645 2640 -3738413.701805 +2727 2640 -19603280.6462 +2728 2640 11944444.44837 +2729 2640 8005089.696258 +2730 2640 -71968136.03531 +2731 2640 4.157423973083e-06 +2732 2640 51943969.87703 +2733 2640 -29817851.87049 +2734 2640 -11944444.44837 +2735 2640 17900923.03284 +2748 2640 8147390.424101 +2749 2640 -2388888.889671 +2750 2640 -1425089.694098 +2751 2640 44430116.09181 +2752 2640 1.907348632813e-06 +2753 2640 -10318414.32804 +2754 2640 -12806461.31664 +2755 2640 2388888.889668 +2756 2640 -3404256.361406 +2641 2641 336472853.0197 +2642 2641 -42221635.45517 +2643 2641 -9555555.553992 +2644 2641 -46090878.57506 +2645 2641 21321928.83866 +2727 2641 11944444.44837 +2728 2641 -16019732.12234 +2729 2641 -7635451.454545 +2730 2641 3.337860107422e-06 +2731 2641 -19412223.56332 +2732 2641 -5277708.208769 +2733 2641 -11944444.44837 +2734 2641 -26234303.34662 +2735 2641 12913159.66331 +2748 2641 2388888.889676 +2749 2641 -14547017.29156 +2750 2641 -15798680.67921 +2751 2641 2.861022949219e-06 +2752 2641 30095922.00342 +2753 2641 -10555416.41234 +2754 2641 -2388888.889678 +2755 2641 -35500869.03229 +2756 2641 26354097.09154 +2642 2642 364276267.6409 +2643 2642 4178252.963561 +2644 2642 20899706.61651 +2645 2642 24137222.99725 +2727 2642 8005089.696258 +2728 2642 -7635451.454545 +2729 2642 -9407733.938713 +2730 2642 51680080.98832 +2731 2642 -5277708.208769 +2732 2642 -58666023.42418 +2733 2642 17900923.03284 +2734 2642 12913159.66331 +2735 2642 -36646590.5368 +2748 2642 1864910.306983 +2749 2642 -15798680.67931 +2750 2642 -2030447.461764 +2751 2642 10758252.33516 +2752 2642 -10555416.41234 +2753 2642 -52990414.80866 +2754 2642 3844076.974307 +2755 2642 26354097.09164 +2756 2642 -57907385.43707 +2643 2643 393809815.9996 +2644 2643 1.168251037598e-05 +2645 2643 -1759210.362797 +2646 2643 44686744.27678 +2647 2643 9555555.553978 +2648 2643 -3738413.701805 +2730 2643 -19603280.6462 +2731 2643 11944444.44837 +2732 2643 8005089.696258 +2733 2643 -71968136.03531 +2734 2643 4.157423973083e-06 +2735 2643 51943969.87703 +2736 2643 -29817851.87049 +2737 2643 -11944444.44837 +2738 2643 17900923.03284 +2751 2643 8147390.424101 +2752 2643 -2388888.889671 +2753 2643 -1425089.694098 +2754 2643 44430116.09181 +2755 2643 1.907348632813e-06 +2756 2643 -10318414.32804 +2757 2643 -12806461.31664 +2758 2643 2388888.889668 +2759 2643 -3404256.361406 +2644 2644 336472853.0197 +2645 2644 -42221635.45517 +2646 2644 -9555555.553992 +2647 2644 -46090878.57506 +2648 2644 21321928.83866 +2730 2644 11944444.44837 +2731 2644 -16019732.12234 +2732 2644 -7635451.454545 +2733 2644 3.337860107422e-06 +2734 2644 -19412223.56332 +2735 2644 -5277708.208769 +2736 2644 -11944444.44837 +2737 2644 -26234303.34662 +2738 2644 12913159.66331 +2751 2644 2388888.889676 +2752 2644 -14547017.29156 +2753 2644 -15798680.67921 +2754 2644 2.861022949219e-06 +2755 2644 30095922.00342 +2756 2644 -10555416.41234 +2757 2644 -2388888.889678 +2758 2644 -35500869.03229 +2759 2644 26354097.09154 +2645 2645 364276267.6409 +2646 2645 4178252.963561 +2647 2645 20899706.61651 +2648 2645 24137222.99725 +2730 2645 8005089.696258 +2731 2645 -7635451.454545 +2732 2645 -9407733.938713 +2733 2645 51680080.98832 +2734 2645 -5277708.208769 +2735 2645 -58666023.42418 +2736 2645 17900923.03284 +2737 2645 12913159.66331 +2738 2645 -36646590.5368 +2751 2645 1864910.306983 +2752 2645 -15798680.67931 +2753 2645 -2030447.461764 +2754 2645 10758252.33516 +2755 2645 -10555416.41234 +2756 2645 -52990414.80866 +2757 2645 3844076.974307 +2758 2645 26354097.09164 +2759 2645 -57907385.43707 +2646 2646 393809815.9996 +2647 2646 1.168251037598e-05 +2648 2646 -1759210.362797 +2649 2646 44686744.27678 +2650 2646 9555555.553978 +2651 2646 -3738413.701805 +2733 2646 -19603280.6462 +2734 2646 11944444.44837 +2735 2646 8005089.696258 +2736 2646 -71968136.03531 +2737 2646 4.157423973083e-06 +2738 2646 51943969.87703 +2739 2646 -29817851.87049 +2740 2646 -11944444.44837 +2741 2646 17900923.03284 +2754 2646 8147390.424101 +2755 2646 -2388888.889671 +2756 2646 -1425089.694098 +2757 2646 44430116.09181 +2758 2646 1.907348632813e-06 +2759 2646 -10318414.32804 +2760 2646 -12806461.31664 +2761 2646 2388888.889668 +2762 2646 -3404256.361406 +2647 2647 336472853.0197 +2648 2647 -42221635.45517 +2649 2647 -9555555.553992 +2650 2647 -46090878.57506 +2651 2647 21321928.83866 +2733 2647 11944444.44837 +2734 2647 -16019732.12234 +2735 2647 -7635451.454545 +2736 2647 3.337860107422e-06 +2737 2647 -19412223.56332 +2738 2647 -5277708.208769 +2739 2647 -11944444.44837 +2740 2647 -26234303.34662 +2741 2647 12913159.66331 +2754 2647 2388888.889676 +2755 2647 -14547017.29156 +2756 2647 -15798680.67921 +2757 2647 2.861022949219e-06 +2758 2647 30095922.00342 +2759 2647 -10555416.41234 +2760 2647 -2388888.889678 +2761 2647 -35500869.03229 +2762 2647 26354097.09154 +2648 2648 364276267.6409 +2649 2648 4178252.963561 +2650 2648 20899706.61651 +2651 2648 24137222.99725 +2733 2648 8005089.696258 +2734 2648 -7635451.454545 +2735 2648 -9407733.938713 +2736 2648 51680080.98832 +2737 2648 -5277708.208769 +2738 2648 -58666023.42418 +2739 2648 17900923.03284 +2740 2648 12913159.66331 +2741 2648 -36646590.5368 +2754 2648 1864910.306983 +2755 2648 -15798680.67931 +2756 2648 -2030447.461764 +2757 2648 10758252.33516 +2758 2648 -10555416.41234 +2759 2648 -52990414.80866 +2760 2648 3844076.974307 +2761 2648 26354097.09164 +2762 2648 -57907385.43707 +2649 2649 393809815.9996 +2650 2649 1.168251037598e-05 +2651 2649 -1759210.362797 +2652 2649 44686744.27678 +2653 2649 9555555.553978 +2654 2649 -3738413.701805 +2736 2649 -19603280.6462 +2737 2649 11944444.44837 +2738 2649 8005089.696258 +2739 2649 -71968136.03531 +2740 2649 4.157423973083e-06 +2741 2649 51943969.87703 +2742 2649 -29817851.87049 +2743 2649 -11944444.44837 +2744 2649 17900923.03284 +2757 2649 8147390.424101 +2758 2649 -2388888.889671 +2759 2649 -1425089.694098 +2760 2649 44430116.09181 +2761 2649 1.907348632813e-06 +2762 2649 -10318414.32804 +2763 2649 -12806461.31664 +2764 2649 2388888.889668 +2765 2649 -3404256.361406 +2650 2650 336472853.0197 +2651 2650 -42221635.45517 +2652 2650 -9555555.553992 +2653 2650 -46090878.57506 +2654 2650 21321928.83866 +2736 2650 11944444.44837 +2737 2650 -16019732.12234 +2738 2650 -7635451.454545 +2739 2650 3.337860107422e-06 +2740 2650 -19412223.56332 +2741 2650 -5277708.208769 +2742 2650 -11944444.44837 +2743 2650 -26234303.34662 +2744 2650 12913159.66331 +2757 2650 2388888.889676 +2758 2650 -14547017.29156 +2759 2650 -15798680.67921 +2760 2650 2.861022949219e-06 +2761 2650 30095922.00342 +2762 2650 -10555416.41234 +2763 2650 -2388888.889678 +2764 2650 -35500869.03229 +2765 2650 26354097.09154 +2651 2651 364276267.6409 +2652 2651 4178252.963561 +2653 2651 20899706.61651 +2654 2651 24137222.99725 +2736 2651 8005089.696258 +2737 2651 -7635451.454545 +2738 2651 -9407733.938713 +2739 2651 51680080.98832 +2740 2651 -5277708.208769 +2741 2651 -58666023.42418 +2742 2651 17900923.03284 +2743 2651 12913159.66331 +2744 2651 -36646590.5368 +2757 2651 1864910.306983 +2758 2651 -15798680.67931 +2759 2651 -2030447.461764 +2760 2651 10758252.33516 +2761 2651 -10555416.41234 +2762 2651 -52990414.80866 +2763 2651 3844076.974307 +2764 2651 26354097.09164 +2765 2651 -57907385.43707 +2652 2652 384444228.8383 +2653 2652 2369408.517209 +2654 2652 14989331.54212 +2655 2652 6285692.86603 +2656 2652 -21077017.68688 +2657 2652 1443044.794795 +2739 2652 -19603280.6462 +2740 2652 11944444.44837 +2741 2652 8005089.696258 +2742 2652 -57207507.5192 +2743 2652 6145877.671107 +2744 2652 43364477.33833 +2745 2652 -26546695.73564 +2746 2652 -11436618.24716 +2747 2652 13848470.62555 +2760 2652 8147390.424101 +2761 2652 -2388888.889671 +2762 2652 -1425089.694098 +2763 2652 41725581.05413 +2764 2652 507938.7214912 +2765 2652 -6453256.604583 +2766 2652 -15664036.02673 +2767 2652 -4772753.704127 +2768 2652 5360864.194452 +2653 2653 348340478.4061 +2654 2653 -25212175.28334 +2655 2653 -40188128.79485 +2656 2653 -83559603.38511 +2657 2653 4659847.811131 +2739 2653 11944444.44837 +2740 2653 -16019732.12234 +2741 2653 -7635451.454545 +2742 2653 6145877.671106 +2743 2653 -14493743.54572 +2744 2653 -8981011.042271 +2745 2653 -11436618.24716 +2746 2653 -18063742.30393 +2747 2653 10594625.07348 +2760 2653 2388888.889676 +2761 2653 -14547017.29156 +2762 2653 -15798680.67921 +2763 2653 507938.7214905 +2764 2653 32293290.44228 +2765 2653 -6540775.042003 +2766 2653 -9550531.483474 +2767 2653 -38317603.62825 +2768 2653 28361293.14454 +2654 2654 356913639.2484 +2655 2654 3026378.127865 +2656 2654 4659847.811131 +2657 2654 21841839.16531 +2739 2654 8005089.696258 +2740 2654 -7635451.454545 +2741 2654 -9407733.938713 +2742 2654 44683921.78504 +2743 2654 -8981011.041011 +2744 2654 -51241692.90527 +2745 2654 13848470.62555 +2746 2654 10594625.07348 +2747 2654 -23506184.8986 +2760 2654 1864910.306983 +2761 2654 -15798680.67931 +2762 2654 -2030447.461764 +2763 2654 14622854.50307 +2764 2654 -6540775.042003 +2765 2654 -55780885.41815 +2766 2654 11025586.41696 +2767 2654 28361293.14339 +2768 2654 -42429184.57622 +2655 2655 392073206.9466 +2656 2655 36749235.99511 +2657 2655 -1748582.371002 +2658 2655 -92329333.78509 +2659 2655 -55737263.0241 +2660 2655 744933.3770267 +2661 2655 15757620.62389 +2662 2655 -8314337.068925 +2663 2655 88992.47062683 +2742 2655 -16305861.25464 +2743 2655 8228316.115794 +2744 2655 4847647.38616 +2745 2655 -52398287.78342 +2746 2655 8623814.868829 +2747 2655 51247665.9983 +2763 2655 -10942417.8914 +2764 2655 -9550531.483475 +2765 2655 -9564135.802965 +2766 2655 13533800.67906 +2767 2655 8346935.407593 +2768 2655 -10722054.94328 +2769 2655 -36706081.42304 +2770 2655 -13829269.11147 +2771 2655 20496497.26015 +2772 2655 -20473238.80768 +2773 2655 -1819265.797273 +2774 2655 5144935.657537 +2656 2656 462078895.6081 +2657 2656 -8762241.479656 +2658 2656 -55737263.0241 +2659 2656 -68893066.30047 +2660 2656 495848.0373137 +2661 2656 -27425448.1769 +2662 2656 -76605666.65403 +2663 2656 1562399.106027 +2742 2656 8228316.115794 +2743 2656 -35556692.91277 +2744 2656 -15320362.63205 +2745 2656 8623814.868829 +2746 2656 -8962312.29862 +2747 2656 -7013375.774193 +2763 2656 -4772753.704129 +2764 2656 -33595985.49293 +2765 2656 -26048429.06869 +2766 2656 8346935.407594 +2767 2656 29320533.57608 +2768 2656 -2123394.363487 +2769 2656 -13829269.11147 +2770 2656 -30963414.8944 +2771 2656 16788670.00494 +2772 2656 -6597043.576619 +2773 2656 -43534214.45849 +2774 2656 33716891.83347 +2657 2657 467651094.3303 +2658 2657 744933.3770265 +2659 2657 495848.0373138 +2660 2657 -5348518.465777 +2661 2657 616770.2483149 +2662 2657 1562399.106027 +2663 2657 51162592.60563 +2742 2657 4847647.38616 +2743 2657 -15320362.63205 +2744 2657 -21210942.45867 +2745 2657 51247665.99856 +2746 2657 -7013375.772933 +2747 2657 -77412673.46776 +2763 2657 -4691080.247253 +2764 2657 -26048429.06995 +2765 2657 -29838202.88199 +2766 2657 9937389.497775 +2767 2657 -2123394.363487 +2768 2657 -108036961.3792 +2769 2657 20496497.26015 +2770 2657 16788670.00494 +2771 2657 -38558984.07588 +2772 2657 10337713.43846 +2773 2657 33716891.83347 +2774 2657 -53721133.01946 +2658 2658 248111582.7161 +2659 2658 61745826.148 +2660 2658 -427778.0740535 +2661 2658 -39359813.45319 +2662 2658 -1596070.29982 +2663 2658 -305118.5623656 +2745 2658 -15064205.65599 +2746 2658 -942255.0720674 +2747 2658 -3602557.756001 +2766 2658 -36153755.84147 +2767 2658 -13829269.11147 +2768 2658 -20128502.75319 +2769 2658 313818.0877385 +2770 2658 15275588.41011 +2771 2658 8019687.386086 +2772 2658 -37751670.53939 +2773 2658 -504064.2265737 +2774 2658 -33038626.87689 +2659 2659 224272484.7333 +2660 2659 -420993.0422466 +2661 2659 17515040.80815 +2662 2659 53662252.3764 +2663 2659 -495848.0373107 +2745 2659 -5720032.851414 +2746 2659 -38241661.13605 +2747 2659 -33228878.5025 +2766 2659 -13829269.11147 +2767 2659 -30411089.31283 +2768 2659 -16544663.33934 +2769 2659 15275588.41011 +2770 2659 -5623309.775096 +2771 2659 6562211.840209 +2772 2659 4273713.552772 +2773 2659 -14379753.72514 +2774 2659 3211330.001623 +2660 2660 302308289.169 +2661 2660 -305118.5623623 +2662 2660 -495848.0373107 +2663 2660 81191347.98248 +2745 2660 -11727557.7571 +2746 2660 -33228878.5025 +2747 2660 -57516476.65011 +2766 2660 -20128502.75319 +2767 2660 -16544663.33934 +2768 2660 -37086115.85837 +2769 2660 -8230312.611246 +2770 2660 -6771121.490934 +2771 2660 -88571362.45583 +2772 2660 -33038626.87847 +2773 2660 -3455336.667233 +2774 2660 -53241548.9 +2661 2661 193187533.5258 +2662 2661 -29907885.14702 +2663 2661 -792696.1747975 +2745 2661 -18585866.94682 +2746 2661 10059619.78527 +2747 2661 12506219.47975 +2766 2661 -18816262.06405 +2767 2661 -6597043.57662 +2768 2661 -10043953.22886 +2769 2661 -37751670.53939 +2770 2661 4273713.552774 +2771 2661 32890539.77888 +2772 2661 -122944.6401992 +2773 2661 -7736289.761419 +2774 2661 -5251694.918494 +2662 2662 214903413.4079 +2663 2662 -1562399.106019 +2745 2662 10059619.78527 +2746 2662 -23823130.97733 +2747 2662 -16544663.33934 +2766 2662 -1819265.797274 +2767 2662 -41877237.71487 +2768 2662 -32949774.82225 +2769 2662 -504064.2265722 +2770 2662 -14379753.72514 +2771 2662 3211330.001623 +2772 2662 -7736289.761419 +2773 2662 4803378.226877 +2774 2662 6283108.159956 +2663 2663 246983991.3423 +2745 2663 12506219.47975 +2746 2663 -16544663.33934 +2747 2663 -30498157.52287 +2766 2663 -5115064.336773 +2767 2663 -32949774.82225 +2768 2663 -49302528.36979 +2769 2663 32890539.77744 +2770 2663 -3455336.667232 +2771 2663 -53241548.9 +2772 2663 4869971.746511 +2773 2663 -7050225.171186 +2774 2663 -67695749.71523 +2664 2664 508612796.7711 +2665 2664 47777777.76993 +2666 2664 20248388.26907 +2667 2664 -267652150.2947 +2668 2664 -47793765.64302 +2669 2664 -20241471.08164 +2670 2664 6087083.420696 +2671 2664 38238210.08904 +2672 2664 -16367807.61161 +2775 2664 57272319.20769 +2776 2664 11944444.44837 +2777 2664 16262217.83282 +2778 2664 -96920154.16551 +2779 2664 -11948441.41665 +2780 2664 -57894966.96635 +2781 2664 -19430363.65776 +2782 2664 9559552.526969 +2783 2664 -14502802.0572 +2665 2665 436923838.9196 +2666 2665 -52790465.59624 +2667 2665 -47801759.57957 +2668 2665 -43044343.65972 +2669 2665 -29246608.86722 +2670 2665 57357315.13355 +2671 2665 6087083.420705 +2672 2665 18374525.78853 +2775 2665 11944444.44837 +2776 2665 39350079.73598 +2777 2665 -4237631.002181 +2778 2665 -11950439.90079 +2779 2665 -40768202.4791 +2780 2665 -17881456.80322 +2781 2665 14339328.79045 +2782 2665 -19430363.65775 +2783 2665 17403019.36621 +2666 2666 498731997.6738 +2667 2666 -20238012.48793 +2668 2666 -23543989.15986 +2669 2666 -9089122.520285 +2670 2666 -24551711.41742 +2671 2666 12249683.85902 +2672 2666 16232222.45521 +2775 2666 -4818855.100867 +2776 2666 -21102266.9381 +2777 2666 -61666013.98076 +2778 2666 -57630268.59944 +2779 2666 -16401283.68257 +2780 2666 -82291258.12151 +2781 2666 -21754203.08579 +2782 2666 11602012.9108 +2783 2666 -51814303.08735 +2667 2667 866925828.5346 +2668 2667 47817747.45269 +2669 2667 23749660.20008 +2670 2667 14263474.74723 +2671 2667 -47793765.64302 +2672 2667 20546059.94785 +2673 2667 -181853790.138 +2674 2667 3.248453140259e-06 +2675 2667 -3518564.899638 +2676 2667 -72853540.65349 +2677 2667 47777777.76992 +2678 2667 -20539363.4444 +2775 2667 -85740387.93072 +2776 2667 -11950439.90077 +2777 2667 47775096.06898 +2778 2667 112006329.4708 +2779 2667 11954436.86906 +2780 2667 5935349.843305 +2781 2667 -36979414.9719 +2782 2667 -11948441.41664 +2783 2667 18346879.03149 +2784 2667 -74762019.75572 +2785 2667 2.533197402954e-07 +2786 2667 -53703252.3277 +2787 2667 -30778677.45218 +2788 2667 11944444.44836 +2789 2667 -18340743.64572 +2668 2668 737900094.3577 +2669 2668 -65443918.48946 +2670 2668 -47801759.57957 +2671 2668 -152989568.1247 +2672 2668 35049537.95506 +2673 2668 3.069639205933e-06 +2674 2668 28369859.6463 +2675 2668 -21110832.82467 +2676 2668 47777777.76992 +2677 2668 -58519346.56511 +2678 2668 11505416.41223 +2775 2668 -11948441.41664 +2776 2668 -29588436.2443 +2777 2668 4682155.144749 +2778 2668 11954436.86906 +2779 2668 79749895.91067 +2780 2668 -16362631.77783 +2781 2668 -11950439.90078 +2782 2668 -78792675.71048 +2783 2668 51029508.03613 +2784 2668 -8.195638656616e-07 +2785 2668 -22206107.28377 +2786 2668 -5277708.20877 +2787 2668 11944444.44836 +2788 2668 -27195128.92833 +2789 2668 13440937.44126 +2669 2669 768350518.5004 +2670 2669 20813297.08829 +2671 2669 40963180.50213 +2672 2669 19484057.05595 +2673 2669 -3518564.899638 +2674 2669 -21110832.82467 +2675 2669 48052583.38233 +2676 2669 -20803252.33311 +2677 2669 11716527.5232 +2678 2669 -22805384.02253 +2775 2669 47510397.70207 +2776 2669 3205506.989851 +2777 2669 -52478548.16204 +2778 2669 5939756.113784 +2779 2669 -16359106.80793 +2780 2669 -87179377.66603 +2781 2669 18349946.72438 +2782 2669 52296851.6274 +2783 2669 -103249742.1615 +2784 2669 -53439363.43899 +2785 2669 -5277708.20877 +2786 2669 -66116380.01208 +2787 2669 -18340743.64572 +2788 2669 13440937.44126 +2789 2669 -39208792.08802 +2670 2670 508612796.7711 +2671 2670 47777777.76993 +2672 2670 20248388.26907 +2673 2670 -71804122.04904 +2674 2670 -47777777.76993 +2675 2670 19043969.88243 +2676 2670 -267652150.2947 +2677 2670 -47793765.64302 +2678 2670 -20241471.08164 +2679 2670 6087083.420696 +2680 2670 38238210.08904 +2681 2670 -16367807.61161 +2775 2670 1532382.642161 +2776 2670 14339328.79045 +2777 2670 9874015.186731 +2778 2670 -4845636.536104 +2779 2670 -11950439.90078 +2780 2670 -8009104.879749 +2781 2670 57272319.20769 +2782 2670 11944444.44837 +2783 2670 16262217.83282 +2784 2670 -20039396.92541 +2785 2670 -11944444.44837 +2786 2670 -8444910.309145 +2787 2670 -96920154.16551 +2788 2670 -11948441.41665 +2789 2670 -57894966.96635 +2790 2670 -19430363.65776 +2791 2670 9559552.526969 +2792 2670 -14502802.0572 +2671 2671 436923838.9196 +2672 2671 -52790465.59624 +2673 2671 -47777777.76993 +2674 2671 -57469927.96065 +2675 2671 9605416.412441 +2676 2671 -47801759.57957 +2677 2671 -43044343.65972 +2678 2671 -29246608.86722 +2679 2671 57357315.13355 +2680 2671 6087083.420705 +2681 2671 18374525.78853 +2775 2671 9559552.526969 +2776 2671 1532382.642157 +2777 2671 -5266148.137347 +2778 2671 -11948441.41664 +2779 2671 -46658897.27468 +2780 2671 -32026328.33686 +2781 2671 11944444.44837 +2782 2671 39350079.73598 +2783 2671 -4237631.002181 +2784 2671 -11944444.44837 +2785 2671 -16455848.40155 +2786 2671 -8163229.232496 +2787 2671 -11950439.90079 +2788 2671 -40768202.4791 +2789 2671 -17881456.80322 +2790 2671 14339328.79045 +2791 2671 -19430363.65775 +2792 2671 17403019.36621 +2672 2672 498731997.6738 +2673 2672 18780080.99371 +2674 2672 9394305.301468 +2675 2672 -20006934.4106 +2676 2672 -20238012.48793 +2677 2672 -23543989.15986 +2678 2672 -9089122.520285 +2679 2672 -24551711.41742 +2680 2672 12249683.85902 +2681 2672 16232222.45521 +2775 2672 6582676.791154 +2776 2672 -7899222.206021 +2777 2672 4086353.712421 +2778 2672 -8007766.485252 +2779 2672 -33293672.07046 +2780 2672 -17559666.33271 +2781 2672 -4818855.100867 +2782 2672 -21102266.9381 +2783 2672 -61666013.98076 +2784 2672 -8444910.309145 +2785 2672 -8163229.232496 +2786 2672 -10570710.68328 +2787 2672 -57630268.59944 +2788 2672 -16401283.68257 +2789 2672 -82291258.12151 +2790 2672 -21754203.08579 +2791 2672 11602012.9108 +2792 2672 -51814303.08735 +2673 2673 801867013.5374 +2674 2673 2.598762512207e-05 +2675 2673 7037129.799195 +2676 2673 92970237.73849 +2677 2673 -1.010298728943e-05 +2678 2673 1759282.450673 +2682 2673 -181853790.138 +2683 2673 3.248453140259e-06 +2684 2673 -3518564.899638 +2685 2673 -72853540.65349 +2686 2673 47777777.76992 +2687 2673 -20539363.4444 +2778 2673 -71968136.03531 +2779 2673 4.157423973083e-06 +2780 2673 51943969.87703 +2781 2673 -29817851.87049 +2782 2673 -11944444.44837 +2783 2673 17900923.03284 +2784 2673 88895212.80375 +2785 2673 4.112720489502e-06 +2786 2673 1759282.450699 +2787 2673 -25612922.63328 +2788 2673 -1.080334186554e-05 +2789 2673 439820.6129002 +2793 2673 -74762019.75572 +2794 2673 2.533197402954e-07 +2795 2673 -53703252.3277 +2796 2673 -30778677.45218 +2797 2673 11944444.44836 +2798 2673 -18340743.64572 +2674 2674 687193460.8868 +2675 2674 -84443331.25708 +2676 2674 -1.019239425659e-05 +2677 2674 -88585023.89729 +2678 2674 42221665.62855 +2682 2674 3.069639205933e-06 +2683 2674 28369859.6463 +2684 2674 -21110832.82467 +2685 2674 47777777.76992 +2686 2674 -58519346.56511 +2687 2674 11505416.41223 +2778 2674 3.337860107422e-06 +2779 2674 -19412223.56332 +2780 2674 -5277708.208769 +2781 2674 -11944444.44837 +2782 2674 -26234303.34662 +2783 2674 12913159.66331 +2784 2674 4.351139068604e-06 +2785 2674 60226824.62697 +2786 2674 -21110832.82468 +2787 2674 -9.95397567749e-06 +2788 2674 -71001738.06458 +2789 2674 52813749.73867 +2793 2674 -8.195638656616e-07 +2794 2674 -22206107.28377 +2795 2674 -5277708.20877 +2796 2674 11944444.44836 +2797 2674 -27195128.92833 +2798 2674 13440937.44126 +2675 2675 766546241.681 +2676 2675 1759282.450673 +2677 2675 42221665.62855 +2678 2675 57866058.65466 +2682 2675 -3518564.899638 +2683 2675 -21110832.82467 +2684 2675 48052583.38233 +2685 2675 -20803252.33311 +2686 2675 11716527.5232 +2687 2675 -22805384.02253 +2778 2675 51680080.98832 +2779 2675 -5277708.208769 +2780 2675 -58666023.42418 +2781 2675 17900923.03284 +2782 2675 12913159.66331 +2783 2675 -36646590.5368 +2784 2675 1759282.450699 +2785 2675 -21110832.82468 +2786 2675 -105887547.9636 +2787 2675 439820.6129005 +2788 2675 52602638.6277 +2789 2675 -115814770.8741 +2793 2675 -53439363.43899 +2794 2675 -5277708.20877 +2795 2675 -66116380.01208 +2796 2675 -18340743.64572 +2797 2675 13440937.44126 +2798 2675 -39208792.08802 +2676 2676 866925828.5346 +2677 2676 47817747.45269 +2678 2676 23749660.20008 +2679 2676 14263474.74723 +2680 2676 -47793765.64302 +2681 2676 20546059.94785 +2682 2676 -71804122.04904 +2683 2676 -47777777.76993 +2684 2676 19043969.88243 +2685 2676 -181853790.138 +2686 2676 3.248453140259e-06 +2687 2676 -3518564.899638 +2688 2676 -72853540.65349 +2689 2676 47777777.76992 +2690 2676 -20539363.4444 +2778 2676 -19603280.6462 +2779 2676 11944444.44837 +2780 2676 8005089.696258 +2781 2676 -85740387.93072 +2782 2676 -11950439.90077 +2783 2676 47775096.06898 +2784 2676 16294780.8482 +2785 2676 4.217028617859e-06 +2786 2676 439820.6128852 +2787 2676 112006329.4708 +2788 2676 11954436.86906 +2789 2676 5935349.843305 +2790 2676 -36979414.9719 +2791 2676 -11948441.41664 +2792 2676 18346879.03149 +2793 2676 -20039396.92541 +2794 2676 -11944444.44837 +2795 2676 -8444910.309145 +2796 2676 -74762019.75572 +2797 2676 2.533197402954e-07 +2798 2676 -53703252.3277 +2799 2676 -30778677.45218 +2800 2676 11944444.44836 +2801 2676 -18340743.64572 +2677 2677 737900094.3577 +2678 2677 -65443918.48946 +2679 2677 -47801759.57957 +2680 2677 -152989568.1247 +2681 2677 35049537.95506 +2682 2677 -47777777.76993 +2683 2677 -57469927.96065 +2684 2677 9605416.412441 +2685 2677 3.069639205933e-06 +2686 2677 28369859.6463 +2687 2677 -21110832.82467 +2688 2677 47777777.76992 +2689 2677 -58519346.56511 +2690 2677 11505416.41223 +2778 2677 11944444.44837 +2779 2677 -16019732.12234 +2780 2677 -7635451.454545 +2781 2677 -11948441.41664 +2782 2677 -29588436.2443 +2783 2677 4682155.144749 +2784 2677 5.125999450684e-06 +2785 2677 -29094034.58311 +2786 2677 -31702916.914 +2787 2677 11954436.86906 +2788 2677 79749895.91067 +2789 2677 -16362631.77783 +2790 2677 -11950439.90078 +2791 2677 -78792675.71048 +2792 2677 51029508.03613 +2793 2677 -11944444.44837 +2794 2677 -16455848.40155 +2795 2677 -8163229.232496 +2796 2677 -8.195638656616e-07 +2797 2677 -22206107.28377 +2798 2677 -5277708.20877 +2799 2677 11944444.44836 +2800 2677 -27195128.92833 +2801 2677 13440937.44126 +2678 2678 768350518.5004 +2679 2678 20813297.08829 +2680 2678 40963180.50213 +2681 2678 19484057.05595 +2682 2678 18780080.99371 +2683 2678 9394305.301468 +2684 2678 -20006934.4106 +2685 2678 -3518564.899638 +2686 2678 -21110832.82467 +2687 2678 48052583.38233 +2688 2678 -20803252.33311 +2689 2678 11716527.5232 +2690 2678 -22805384.02253 +2778 2678 8005089.696258 +2779 2678 -7635451.454545 +2780 2678 -9407733.938713 +2781 2678 47510397.70207 +2782 2678 3205506.989851 +2783 2678 -52478548.16204 +2784 2678 439820.6128855 +2785 2678 -31491805.80303 +2786 2678 -4060894.923526 +2787 2678 5939756.113784 +2788 2678 -16359106.80793 +2789 2678 -87179377.66603 +2790 2678 18349946.72438 +2791 2678 52296851.6274 +2792 2678 -103249742.1615 +2793 2678 -8444910.309145 +2794 2678 -8163229.232496 +2795 2678 -10570710.68328 +2796 2678 -53439363.43899 +2797 2678 -5277708.20877 +2798 2678 -66116380.01208 +2799 2678 -18340743.64572 +2800 2678 13440937.44126 +2801 2678 -39208792.08802 +2679 2679 508612796.7711 +2680 2679 47777777.76993 +2681 2679 20248388.26907 +2685 2679 -71804122.04904 +2686 2679 -47777777.76993 +2687 2679 19043969.88243 +2688 2679 -267652150.2947 +2689 2679 -47793765.64302 +2690 2679 -20241471.08164 +2691 2679 6087083.420696 +2692 2679 38238210.08904 +2693 2679 -16367807.61161 +2781 2679 1532382.642161 +2782 2679 14339328.79045 +2783 2679 9874015.186731 +2787 2679 -4845636.536104 +2788 2679 -11950439.90078 +2789 2679 -8009104.879749 +2790 2679 57272319.20769 +2791 2679 11944444.44837 +2792 2679 16262217.83282 +2796 2679 -20039396.92541 +2797 2679 -11944444.44837 +2798 2679 -8444910.309145 +2799 2679 -96920154.16551 +2800 2679 -11948441.41665 +2801 2679 -57894966.96635 +2802 2679 -19430363.65776 +2803 2679 9559552.526969 +2804 2679 -14502802.0572 +2680 2680 436923838.9196 +2681 2680 -52790465.59624 +2685 2680 -47777777.76993 +2686 2680 -57469927.96065 +2687 2680 9605416.412441 +2688 2680 -47801759.57957 +2689 2680 -43044343.65972 +2690 2680 -29246608.86722 +2691 2680 57357315.13355 +2692 2680 6087083.420705 +2693 2680 18374525.78853 +2781 2680 9559552.526969 +2782 2680 1532382.642157 +2783 2680 -5266148.137347 +2787 2680 -11948441.41664 +2788 2680 -46658897.27468 +2789 2680 -32026328.33686 +2790 2680 11944444.44837 +2791 2680 39350079.73598 +2792 2680 -4237631.002181 +2796 2680 -11944444.44837 +2797 2680 -16455848.40155 +2798 2680 -8163229.232496 +2799 2680 -11950439.90079 +2800 2680 -40768202.4791 +2801 2680 -17881456.80322 +2802 2680 14339328.79045 +2803 2680 -19430363.65775 +2804 2680 17403019.36621 +2681 2681 498731997.6738 +2685 2681 18780080.99371 +2686 2681 9394305.301468 +2687 2681 -20006934.4106 +2688 2681 -20238012.48793 +2689 2681 -23543989.15986 +2690 2681 -9089122.520285 +2691 2681 -24551711.41742 +2692 2681 12249683.85902 +2693 2681 16232222.45521 +2781 2681 6582676.791154 +2782 2681 -7899222.206021 +2783 2681 4086353.712421 +2787 2681 -8007766.485252 +2788 2681 -33293672.07046 +2789 2681 -17559666.33271 +2790 2681 -4818855.100867 +2791 2681 -21102266.9381 +2792 2681 -61666013.98076 +2796 2681 -8444910.309145 +2797 2681 -8163229.232496 +2798 2681 -10570710.68328 +2799 2681 -57630268.59944 +2800 2681 -16401283.68257 +2801 2681 -82291258.12151 +2802 2681 -21754203.08579 +2803 2681 11602012.9108 +2804 2681 -51814303.08735 +2682 2682 801867013.5374 +2683 2682 2.598762512207e-05 +2684 2682 7037129.799195 +2685 2682 92970237.73849 +2686 2682 -1.010298728943e-05 +2687 2682 1759282.450673 +2694 2682 -181853790.138 +2695 2682 3.248453140259e-06 +2696 2682 -3518564.899638 +2697 2682 -72853540.65349 +2698 2682 47777777.76992 +2699 2682 -20539363.4444 +2784 2682 -71968136.03531 +2785 2682 4.157423973083e-06 +2786 2682 51943969.87703 +2787 2682 -29817851.87049 +2788 2682 -11944444.44837 +2789 2682 17900923.03284 +2793 2682 88895212.80375 +2794 2682 4.112720489502e-06 +2795 2682 1759282.450699 +2796 2682 -25612922.63328 +2797 2682 -1.080334186554e-05 +2798 2682 439820.6129002 +2805 2682 -74762019.75572 +2806 2682 2.533197402954e-07 +2807 2682 -53703252.3277 +2808 2682 -30778677.45218 +2809 2682 11944444.44836 +2810 2682 -18340743.64572 +2683 2683 687193460.8868 +2684 2683 -84443331.25708 +2685 2683 -1.019239425659e-05 +2686 2683 -88585023.89729 +2687 2683 42221665.62855 +2694 2683 3.069639205933e-06 +2695 2683 28369859.6463 +2696 2683 -21110832.82467 +2697 2683 47777777.76992 +2698 2683 -58519346.56511 +2699 2683 11505416.41223 +2784 2683 3.337860107422e-06 +2785 2683 -19412223.56332 +2786 2683 -5277708.208769 +2787 2683 -11944444.44837 +2788 2683 -26234303.34662 +2789 2683 12913159.66331 +2793 2683 4.351139068604e-06 +2794 2683 60226824.62697 +2795 2683 -21110832.82468 +2796 2683 -9.95397567749e-06 +2797 2683 -71001738.06458 +2798 2683 52813749.73867 +2805 2683 -8.195638656616e-07 +2806 2683 -22206107.28377 +2807 2683 -5277708.20877 +2808 2683 11944444.44836 +2809 2683 -27195128.92833 +2810 2683 13440937.44126 +2684 2684 766546241.681 +2685 2684 1759282.450673 +2686 2684 42221665.62855 +2687 2684 57866058.65466 +2694 2684 -3518564.899638 +2695 2684 -21110832.82467 +2696 2684 48052583.38233 +2697 2684 -20803252.33311 +2698 2684 11716527.5232 +2699 2684 -22805384.02253 +2784 2684 51680080.98832 +2785 2684 -5277708.208769 +2786 2684 -58666023.42418 +2787 2684 17900923.03284 +2788 2684 12913159.66331 +2789 2684 -36646590.5368 +2793 2684 1759282.450699 +2794 2684 -21110832.82468 +2795 2684 -105887547.9636 +2796 2684 439820.6129005 +2797 2684 52602638.6277 +2798 2684 -115814770.8741 +2805 2684 -53439363.43899 +2806 2684 -5277708.20877 +2807 2684 -66116380.01208 +2808 2684 -18340743.64572 +2809 2684 13440937.44126 +2810 2684 -39208792.08802 +2685 2685 801867013.5374 +2686 2685 2.598762512207e-05 +2687 2685 7037129.799195 +2688 2685 92970237.73849 +2689 2685 -1.010298728943e-05 +2690 2685 1759282.450673 +2694 2685 -71804122.04904 +2695 2685 -47777777.76993 +2696 2685 19043969.88243 +2697 2685 -181853790.138 +2698 2685 3.248453140259e-06 +2699 2685 -3518564.899638 +2700 2685 -72853540.65349 +2701 2685 47777777.76992 +2702 2685 -20539363.4444 +2784 2685 -19603280.6462 +2785 2685 11944444.44837 +2786 2685 8005089.696258 +2787 2685 -71968136.03531 +2788 2685 4.157423973083e-06 +2789 2685 51943969.87703 +2790 2685 -29817851.87049 +2791 2685 -11944444.44837 +2792 2685 17900923.03284 +2793 2685 16294780.8482 +2794 2685 4.217028617859e-06 +2795 2685 439820.6128852 +2796 2685 88895212.80375 +2797 2685 4.112720489502e-06 +2798 2685 1759282.450699 +2799 2685 -25612922.63328 +2800 2685 -1.080334186554e-05 +2801 2685 439820.6129002 +2805 2685 -20039396.92541 +2806 2685 -11944444.44837 +2807 2685 -8444910.309145 +2808 2685 -74762019.75572 +2809 2685 2.533197402954e-07 +2810 2685 -53703252.3277 +2811 2685 -30778677.45218 +2812 2685 11944444.44836 +2813 2685 -18340743.64572 +2686 2686 687193460.8868 +2687 2686 -84443331.25708 +2688 2686 -1.019239425659e-05 +2689 2686 -88585023.89729 +2690 2686 42221665.62855 +2694 2686 -47777777.76993 +2695 2686 -57469927.96065 +2696 2686 9605416.412441 +2697 2686 3.069639205933e-06 +2698 2686 28369859.6463 +2699 2686 -21110832.82467 +2700 2686 47777777.76992 +2701 2686 -58519346.56511 +2702 2686 11505416.41223 +2784 2686 11944444.44837 +2785 2686 -16019732.12234 +2786 2686 -7635451.454545 +2787 2686 3.337860107422e-06 +2788 2686 -19412223.56332 +2789 2686 -5277708.208769 +2790 2686 -11944444.44837 +2791 2686 -26234303.34662 +2792 2686 12913159.66331 +2793 2686 5.125999450684e-06 +2794 2686 -29094034.58311 +2795 2686 -31702916.914 +2796 2686 4.351139068604e-06 +2797 2686 60226824.62697 +2798 2686 -21110832.82468 +2799 2686 -9.95397567749e-06 +2800 2686 -71001738.06458 +2801 2686 52813749.73867 +2805 2686 -11944444.44837 +2806 2686 -16455848.40155 +2807 2686 -8163229.232496 +2808 2686 -8.195638656616e-07 +2809 2686 -22206107.28377 +2810 2686 -5277708.20877 +2811 2686 11944444.44836 +2812 2686 -27195128.92833 +2813 2686 13440937.44126 +2687 2687 766546241.681 +2688 2687 1759282.450673 +2689 2687 42221665.62855 +2690 2687 57866058.65466 +2694 2687 18780080.99371 +2695 2687 9394305.301468 +2696 2687 -20006934.4106 +2697 2687 -3518564.899638 +2698 2687 -21110832.82467 +2699 2687 48052583.38233 +2700 2687 -20803252.33311 +2701 2687 11716527.5232 +2702 2687 -22805384.02253 +2784 2687 8005089.696258 +2785 2687 -7635451.454545 +2786 2687 -9407733.938713 +2787 2687 51680080.98832 +2788 2687 -5277708.208769 +2789 2687 -58666023.42418 +2790 2687 17900923.03284 +2791 2687 12913159.66331 +2792 2687 -36646590.5368 +2793 2687 439820.6128855 +2794 2687 -31491805.80303 +2795 2687 -4060894.923526 +2796 2687 1759282.450699 +2797 2687 -21110832.82468 +2798 2687 -105887547.9636 +2799 2687 439820.6129005 +2800 2687 52602638.6277 +2801 2687 -115814770.8741 +2805 2687 -8444910.309145 +2806 2687 -8163229.232496 +2807 2687 -10570710.68328 +2808 2687 -53439363.43899 +2809 2687 -5277708.20877 +2810 2687 -66116380.01208 +2811 2687 -18340743.64572 +2812 2687 13440937.44126 +2813 2687 -39208792.08802 +2688 2688 866925828.5346 +2689 2688 47817747.45269 +2690 2688 23749660.20008 +2691 2688 14263474.74723 +2692 2688 -47793765.64302 +2693 2688 20546059.94785 +2697 2688 -71804122.04904 +2698 2688 -47777777.76993 +2699 2688 19043969.88243 +2700 2688 -181853790.138 +2701 2688 3.248453140259e-06 +2702 2688 -3518564.899638 +2703 2688 -72853540.65349 +2704 2688 47777777.76992 +2705 2688 -20539363.4444 +2787 2688 -19603280.6462 +2788 2688 11944444.44837 +2789 2688 8005089.696258 +2790 2688 -85740387.93072 +2791 2688 -11950439.90077 +2792 2688 47775096.06898 +2796 2688 16294780.8482 +2797 2688 4.217028617859e-06 +2798 2688 439820.6128852 +2799 2688 112006329.4708 +2800 2688 11954436.86906 +2801 2688 5935349.843305 +2802 2688 -36979414.9719 +2803 2688 -11948441.41664 +2804 2688 18346879.03149 +2808 2688 -20039396.92541 +2809 2688 -11944444.44837 +2810 2688 -8444910.309145 +2811 2688 -74762019.75572 +2812 2688 2.533197402954e-07 +2813 2688 -53703252.3277 +2814 2688 -30778677.45218 +2815 2688 11944444.44836 +2816 2688 -18340743.64572 +2689 2689 737900094.3577 +2690 2689 -65443918.48946 +2691 2689 -47801759.57957 +2692 2689 -152989568.1247 +2693 2689 35049537.95506 +2697 2689 -47777777.76993 +2698 2689 -57469927.96065 +2699 2689 9605416.412441 +2700 2689 3.069639205933e-06 +2701 2689 28369859.6463 +2702 2689 -21110832.82467 +2703 2689 47777777.76992 +2704 2689 -58519346.56511 +2705 2689 11505416.41223 +2787 2689 11944444.44837 +2788 2689 -16019732.12234 +2789 2689 -7635451.454545 +2790 2689 -11948441.41664 +2791 2689 -29588436.2443 +2792 2689 4682155.144749 +2796 2689 5.125999450684e-06 +2797 2689 -29094034.58311 +2798 2689 -31702916.914 +2799 2689 11954436.86906 +2800 2689 79749895.91067 +2801 2689 -16362631.77783 +2802 2689 -11950439.90078 +2803 2689 -78792675.71048 +2804 2689 51029508.03613 +2808 2689 -11944444.44837 +2809 2689 -16455848.40155 +2810 2689 -8163229.232496 +2811 2689 -8.195638656616e-07 +2812 2689 -22206107.28377 +2813 2689 -5277708.20877 +2814 2689 11944444.44836 +2815 2689 -27195128.92833 +2816 2689 13440937.44126 +2690 2690 768350518.5004 +2691 2690 20813297.08829 +2692 2690 40963180.50213 +2693 2690 19484057.05595 +2697 2690 18780080.99371 +2698 2690 9394305.301468 +2699 2690 -20006934.4106 +2700 2690 -3518564.899638 +2701 2690 -21110832.82467 +2702 2690 48052583.38233 +2703 2690 -20803252.33311 +2704 2690 11716527.5232 +2705 2690 -22805384.02253 +2787 2690 8005089.696258 +2788 2690 -7635451.454545 +2789 2690 -9407733.938713 +2790 2690 47510397.70207 +2791 2690 3205506.989851 +2792 2690 -52478548.16204 +2796 2690 439820.6128855 +2797 2690 -31491805.80303 +2798 2690 -4060894.923526 +2799 2690 5939756.113784 +2800 2690 -16359106.80793 +2801 2690 -87179377.66603 +2802 2690 18349946.72438 +2803 2690 52296851.6274 +2804 2690 -103249742.1615 +2808 2690 -8444910.309145 +2809 2690 -8163229.232496 +2810 2690 -10570710.68328 +2811 2690 -53439363.43899 +2812 2690 -5277708.20877 +2813 2690 -66116380.01208 +2814 2690 -18340743.64572 +2815 2690 13440937.44126 +2816 2690 -39208792.08802 +2691 2691 508612796.7711 +2692 2691 47777777.76993 +2693 2691 20248388.26907 +2700 2691 -71804122.04904 +2701 2691 -47777777.76993 +2702 2691 19043969.88243 +2703 2691 -267652150.2947 +2704 2691 -47793765.64302 +2705 2691 -20241471.08164 +2706 2691 6087083.420696 +2707 2691 38238210.08904 +2708 2691 -16367807.61161 +2790 2691 1532382.642161 +2791 2691 14339328.79045 +2792 2691 9874015.186731 +2799 2691 -4845636.536104 +2800 2691 -11950439.90078 +2801 2691 -8009104.879749 +2802 2691 57272319.20769 +2803 2691 11944444.44837 +2804 2691 16262217.83282 +2811 2691 -20039396.92541 +2812 2691 -11944444.44837 +2813 2691 -8444910.309145 +2814 2691 -96920154.16551 +2815 2691 -11948441.41665 +2816 2691 -57894966.96635 +2817 2691 -19430363.65776 +2818 2691 9559552.526969 +2819 2691 -14502802.0572 +2692 2692 436923838.9196 +2693 2692 -52790465.59624 +2700 2692 -47777777.76993 +2701 2692 -57469927.96065 +2702 2692 9605416.412441 +2703 2692 -47801759.57957 +2704 2692 -43044343.65972 +2705 2692 -29246608.86722 +2706 2692 57357315.13355 +2707 2692 6087083.420705 +2708 2692 18374525.78853 +2790 2692 9559552.526969 +2791 2692 1532382.642157 +2792 2692 -5266148.137347 +2799 2692 -11948441.41664 +2800 2692 -46658897.27468 +2801 2692 -32026328.33686 +2802 2692 11944444.44837 +2803 2692 39350079.73598 +2804 2692 -4237631.002181 +2811 2692 -11944444.44837 +2812 2692 -16455848.40155 +2813 2692 -8163229.232496 +2814 2692 -11950439.90079 +2815 2692 -40768202.4791 +2816 2692 -17881456.80322 +2817 2692 14339328.79045 +2818 2692 -19430363.65775 +2819 2692 17403019.36621 +2693 2693 498731997.6738 +2700 2693 18780080.99371 +2701 2693 9394305.301468 +2702 2693 -20006934.4106 +2703 2693 -20238012.48793 +2704 2693 -23543989.15986 +2705 2693 -9089122.520285 +2706 2693 -24551711.41742 +2707 2693 12249683.85902 +2708 2693 16232222.45521 +2790 2693 6582676.791154 +2791 2693 -7899222.206021 +2792 2693 4086353.712421 +2799 2693 -8007766.485252 +2800 2693 -33293672.07046 +2801 2693 -17559666.33271 +2802 2693 -4818855.100867 +2803 2693 -21102266.9381 +2804 2693 -61666013.98076 +2811 2693 -8444910.309145 +2812 2693 -8163229.232496 +2813 2693 -10570710.68328 +2814 2693 -57630268.59944 +2815 2693 -16401283.68257 +2816 2693 -82291258.12151 +2817 2693 -21754203.08579 +2818 2693 11602012.9108 +2819 2693 -51814303.08735 +2694 2694 801867013.5374 +2695 2694 2.598762512207e-05 +2696 2694 7037129.799195 +2697 2694 92970237.73849 +2698 2694 -1.010298728943e-05 +2699 2694 1759282.450673 +2709 2694 -181853790.138 +2710 2694 3.248453140259e-06 +2711 2694 -3518564.899638 +2712 2694 -72853540.65349 +2713 2694 47777777.76992 +2714 2694 -20539363.4444 +2793 2694 -71968136.03531 +2794 2694 4.157423973083e-06 +2795 2694 51943969.87703 +2796 2694 -29817851.87049 +2797 2694 -11944444.44837 +2798 2694 17900923.03284 +2805 2694 88895212.80375 +2806 2694 4.112720489502e-06 +2807 2694 1759282.450699 +2808 2694 -25612922.63328 +2809 2694 -1.080334186554e-05 +2810 2694 439820.6129002 +2820 2694 -74762019.75572 +2821 2694 2.533197402954e-07 +2822 2694 -53703252.3277 +2823 2694 -30778677.45218 +2824 2694 11944444.44836 +2825 2694 -18340743.64572 +2695 2695 687193460.8868 +2696 2695 -84443331.25708 +2697 2695 -1.019239425659e-05 +2698 2695 -88585023.89729 +2699 2695 42221665.62855 +2709 2695 3.069639205933e-06 +2710 2695 28369859.6463 +2711 2695 -21110832.82467 +2712 2695 47777777.76992 +2713 2695 -58519346.56511 +2714 2695 11505416.41223 +2793 2695 3.337860107422e-06 +2794 2695 -19412223.56332 +2795 2695 -5277708.208769 +2796 2695 -11944444.44837 +2797 2695 -26234303.34662 +2798 2695 12913159.66331 +2805 2695 4.351139068604e-06 +2806 2695 60226824.62697 +2807 2695 -21110832.82468 +2808 2695 -9.95397567749e-06 +2809 2695 -71001738.06458 +2810 2695 52813749.73867 +2820 2695 -8.195638656616e-07 +2821 2695 -22206107.28377 +2822 2695 -5277708.20877 +2823 2695 11944444.44836 +2824 2695 -27195128.92833 +2825 2695 13440937.44126 +2696 2696 766546241.681 +2697 2696 1759282.450673 +2698 2696 42221665.62855 +2699 2696 57866058.65466 +2709 2696 -3518564.899638 +2710 2696 -21110832.82467 +2711 2696 48052583.38233 +2712 2696 -20803252.33311 +2713 2696 11716527.5232 +2714 2696 -22805384.02253 +2793 2696 51680080.98832 +2794 2696 -5277708.208769 +2795 2696 -58666023.42418 +2796 2696 17900923.03284 +2797 2696 12913159.66331 +2798 2696 -36646590.5368 +2805 2696 1759282.450699 +2806 2696 -21110832.82468 +2807 2696 -105887547.9636 +2808 2696 439820.6129005 +2809 2696 52602638.6277 +2810 2696 -115814770.8741 +2820 2696 -53439363.43899 +2821 2696 -5277708.20877 +2822 2696 -66116380.01208 +2823 2696 -18340743.64572 +2824 2696 13440937.44126 +2825 2696 -39208792.08802 +2697 2697 801867013.5374 +2698 2697 2.598762512207e-05 +2699 2697 7037129.799195 +2700 2697 92970237.73849 +2701 2697 -1.010298728943e-05 +2702 2697 1759282.450673 +2709 2697 -71804122.04904 +2710 2697 -47777777.76993 +2711 2697 19043969.88243 +2712 2697 -181853790.138 +2713 2697 3.248453140259e-06 +2714 2697 -3518564.899638 +2715 2697 -72853540.65349 +2716 2697 47777777.76992 +2717 2697 -20539363.4444 +2793 2697 -19603280.6462 +2794 2697 11944444.44837 +2795 2697 8005089.696258 +2796 2697 -71968136.03531 +2797 2697 4.157423973083e-06 +2798 2697 51943969.87703 +2799 2697 -29817851.87049 +2800 2697 -11944444.44837 +2801 2697 17900923.03284 +2805 2697 16294780.8482 +2806 2697 4.217028617859e-06 +2807 2697 439820.6128852 +2808 2697 88895212.80375 +2809 2697 4.112720489502e-06 +2810 2697 1759282.450699 +2811 2697 -25612922.63328 +2812 2697 -1.080334186554e-05 +2813 2697 439820.6129002 +2820 2697 -20039396.92541 +2821 2697 -11944444.44837 +2822 2697 -8444910.309145 +2823 2697 -74762019.75572 +2824 2697 2.533197402954e-07 +2825 2697 -53703252.3277 +2826 2697 -30778677.45218 +2827 2697 11944444.44836 +2828 2697 -18340743.64572 +2698 2698 687193460.8868 +2699 2698 -84443331.25708 +2700 2698 -1.019239425659e-05 +2701 2698 -88585023.89729 +2702 2698 42221665.62855 +2709 2698 -47777777.76993 +2710 2698 -57469927.96065 +2711 2698 9605416.412441 +2712 2698 3.069639205933e-06 +2713 2698 28369859.6463 +2714 2698 -21110832.82467 +2715 2698 47777777.76992 +2716 2698 -58519346.56511 +2717 2698 11505416.41223 +2793 2698 11944444.44837 +2794 2698 -16019732.12234 +2795 2698 -7635451.454545 +2796 2698 3.337860107422e-06 +2797 2698 -19412223.56332 +2798 2698 -5277708.208769 +2799 2698 -11944444.44837 +2800 2698 -26234303.34662 +2801 2698 12913159.66331 +2805 2698 5.125999450684e-06 +2806 2698 -29094034.58311 +2807 2698 -31702916.914 +2808 2698 4.351139068604e-06 +2809 2698 60226824.62697 +2810 2698 -21110832.82468 +2811 2698 -9.95397567749e-06 +2812 2698 -71001738.06458 +2813 2698 52813749.73867 +2820 2698 -11944444.44837 +2821 2698 -16455848.40155 +2822 2698 -8163229.232496 +2823 2698 -8.195638656616e-07 +2824 2698 -22206107.28377 +2825 2698 -5277708.20877 +2826 2698 11944444.44836 +2827 2698 -27195128.92833 +2828 2698 13440937.44126 +2699 2699 766546241.681 +2700 2699 1759282.450673 +2701 2699 42221665.62855 +2702 2699 57866058.65466 +2709 2699 18780080.99371 +2710 2699 9394305.301468 +2711 2699 -20006934.4106 +2712 2699 -3518564.899638 +2713 2699 -21110832.82467 +2714 2699 48052583.38233 +2715 2699 -20803252.33311 +2716 2699 11716527.5232 +2717 2699 -22805384.02253 +2793 2699 8005089.696258 +2794 2699 -7635451.454545 +2795 2699 -9407733.938713 +2796 2699 51680080.98832 +2797 2699 -5277708.208769 +2798 2699 -58666023.42418 +2799 2699 17900923.03284 +2800 2699 12913159.66331 +2801 2699 -36646590.5368 +2805 2699 439820.6128855 +2806 2699 -31491805.80303 +2807 2699 -4060894.923526 +2808 2699 1759282.450699 +2809 2699 -21110832.82468 +2810 2699 -105887547.9636 +2811 2699 439820.6129005 +2812 2699 52602638.6277 +2813 2699 -115814770.8741 +2820 2699 -8444910.309145 +2821 2699 -8163229.232496 +2822 2699 -10570710.68328 +2823 2699 -53439363.43899 +2824 2699 -5277708.20877 +2825 2699 -66116380.01208 +2826 2699 -18340743.64572 +2827 2699 13440937.44126 +2828 2699 -39208792.08802 +2700 2700 801867013.5374 +2701 2700 2.598762512207e-05 +2702 2700 7037129.799195 +2703 2700 92970237.73849 +2704 2700 -1.010298728943e-05 +2705 2700 1759282.450673 +2712 2700 -71804122.04904 +2713 2700 -47777777.76993 +2714 2700 19043969.88243 +2715 2700 -181853790.138 +2716 2700 3.248453140259e-06 +2717 2700 -3518564.899638 +2718 2700 -72853540.65349 +2719 2700 47777777.76992 +2720 2700 -20539363.4444 +2796 2700 -19603280.6462 +2797 2700 11944444.44837 +2798 2700 8005089.696258 +2799 2700 -71968136.03531 +2800 2700 4.157423973083e-06 +2801 2700 51943969.87703 +2802 2700 -29817851.87049 +2803 2700 -11944444.44837 +2804 2700 17900923.03284 +2808 2700 16294780.8482 +2809 2700 4.217028617859e-06 +2810 2700 439820.6128852 +2811 2700 88895212.80375 +2812 2700 4.112720489502e-06 +2813 2700 1759282.450699 +2814 2700 -25612922.63328 +2815 2700 -1.080334186554e-05 +2816 2700 439820.6129002 +2823 2700 -20039396.92541 +2824 2700 -11944444.44837 +2825 2700 -8444910.309145 +2826 2700 -74762019.75572 +2827 2700 2.533197402954e-07 +2828 2700 -53703252.3277 +2829 2700 -30778677.45218 +2830 2700 11944444.44836 +2831 2700 -18340743.64572 +2701 2701 687193460.8868 +2702 2701 -84443331.25708 +2703 2701 -1.019239425659e-05 +2704 2701 -88585023.89729 +2705 2701 42221665.62855 +2712 2701 -47777777.76993 +2713 2701 -57469927.96065 +2714 2701 9605416.412441 +2715 2701 3.069639205933e-06 +2716 2701 28369859.6463 +2717 2701 -21110832.82467 +2718 2701 47777777.76992 +2719 2701 -58519346.56511 +2720 2701 11505416.41223 +2796 2701 11944444.44837 +2797 2701 -16019732.12234 +2798 2701 -7635451.454545 +2799 2701 3.337860107422e-06 +2800 2701 -19412223.56332 +2801 2701 -5277708.208769 +2802 2701 -11944444.44837 +2803 2701 -26234303.34662 +2804 2701 12913159.66331 +2808 2701 5.125999450684e-06 +2809 2701 -29094034.58311 +2810 2701 -31702916.914 +2811 2701 4.351139068604e-06 +2812 2701 60226824.62697 +2813 2701 -21110832.82468 +2814 2701 -9.95397567749e-06 +2815 2701 -71001738.06458 +2816 2701 52813749.73867 +2823 2701 -11944444.44837 +2824 2701 -16455848.40155 +2825 2701 -8163229.232496 +2826 2701 -8.195638656616e-07 +2827 2701 -22206107.28377 +2828 2701 -5277708.20877 +2829 2701 11944444.44836 +2830 2701 -27195128.92833 +2831 2701 13440937.44126 +2702 2702 766546241.681 +2703 2702 1759282.450673 +2704 2702 42221665.62855 +2705 2702 57866058.65466 +2712 2702 18780080.99371 +2713 2702 9394305.301468 +2714 2702 -20006934.4106 +2715 2702 -3518564.899638 +2716 2702 -21110832.82467 +2717 2702 48052583.38233 +2718 2702 -20803252.33311 +2719 2702 11716527.5232 +2720 2702 -22805384.02253 +2796 2702 8005089.696258 +2797 2702 -7635451.454545 +2798 2702 -9407733.938713 +2799 2702 51680080.98832 +2800 2702 -5277708.208769 +2801 2702 -58666023.42418 +2802 2702 17900923.03284 +2803 2702 12913159.66331 +2804 2702 -36646590.5368 +2808 2702 439820.6128855 +2809 2702 -31491805.80303 +2810 2702 -4060894.923526 +2811 2702 1759282.450699 +2812 2702 -21110832.82468 +2813 2702 -105887547.9636 +2814 2702 439820.6129005 +2815 2702 52602638.6277 +2816 2702 -115814770.8741 +2823 2702 -8444910.309145 +2824 2702 -8163229.232496 +2825 2702 -10570710.68328 +2826 2702 -53439363.43899 +2827 2702 -5277708.20877 +2828 2702 -66116380.01208 +2829 2702 -18340743.64572 +2830 2702 13440937.44126 +2831 2702 -39208792.08802 +2703 2703 866925828.5346 +2704 2703 47817747.45269 +2705 2703 23749660.20008 +2706 2703 14263474.74723 +2707 2703 -47793765.64302 +2708 2703 20546059.94785 +2715 2703 -71804122.04904 +2716 2703 -47777777.76993 +2717 2703 19043969.88243 +2718 2703 -181853790.138 +2719 2703 3.248453140259e-06 +2720 2703 -3518564.899638 +2721 2703 -72853540.65349 +2722 2703 47777777.76992 +2723 2703 -20539363.4444 +2799 2703 -19603280.6462 +2800 2703 11944444.44837 +2801 2703 8005089.696258 +2802 2703 -85740387.93072 +2803 2703 -11950439.90077 +2804 2703 47775096.06898 +2811 2703 16294780.8482 +2812 2703 4.217028617859e-06 +2813 2703 439820.6128852 +2814 2703 112006329.4708 +2815 2703 11954436.86906 +2816 2703 5935349.843305 +2817 2703 -36979414.9719 +2818 2703 -11948441.41664 +2819 2703 18346879.03149 +2826 2703 -20039396.92541 +2827 2703 -11944444.44837 +2828 2703 -8444910.309145 +2829 2703 -74762019.75572 +2830 2703 2.533197402954e-07 +2831 2703 -53703252.3277 +2832 2703 -30778677.45218 +2833 2703 11944444.44836 +2834 2703 -18340743.64572 +2704 2704 737900094.3577 +2705 2704 -65443918.48946 +2706 2704 -47801759.57957 +2707 2704 -152989568.1247 +2708 2704 35049537.95506 +2715 2704 -47777777.76993 +2716 2704 -57469927.96065 +2717 2704 9605416.412441 +2718 2704 3.069639205933e-06 +2719 2704 28369859.6463 +2720 2704 -21110832.82467 +2721 2704 47777777.76992 +2722 2704 -58519346.56511 +2723 2704 11505416.41223 +2799 2704 11944444.44837 +2800 2704 -16019732.12234 +2801 2704 -7635451.454545 +2802 2704 -11948441.41664 +2803 2704 -29588436.2443 +2804 2704 4682155.144749 +2811 2704 5.125999450684e-06 +2812 2704 -29094034.58311 +2813 2704 -31702916.914 +2814 2704 11954436.86906 +2815 2704 79749895.91067 +2816 2704 -16362631.77783 +2817 2704 -11950439.90078 +2818 2704 -78792675.71048 +2819 2704 51029508.03613 +2826 2704 -11944444.44837 +2827 2704 -16455848.40155 +2828 2704 -8163229.232496 +2829 2704 -8.195638656616e-07 +2830 2704 -22206107.28377 +2831 2704 -5277708.20877 +2832 2704 11944444.44836 +2833 2704 -27195128.92833 +2834 2704 13440937.44126 +2705 2705 768350518.5004 +2706 2705 20813297.08829 +2707 2705 40963180.50213 +2708 2705 19484057.05595 +2715 2705 18780080.99371 +2716 2705 9394305.301468 +2717 2705 -20006934.4106 +2718 2705 -3518564.899638 +2719 2705 -21110832.82467 +2720 2705 48052583.38233 +2721 2705 -20803252.33311 +2722 2705 11716527.5232 +2723 2705 -22805384.02253 +2799 2705 8005089.696258 +2800 2705 -7635451.454545 +2801 2705 -9407733.938713 +2802 2705 47510397.70207 +2803 2705 3205506.989851 +2804 2705 -52478548.16204 +2811 2705 439820.6128855 +2812 2705 -31491805.80303 +2813 2705 -4060894.923526 +2814 2705 5939756.113784 +2815 2705 -16359106.80793 +2816 2705 -87179377.66603 +2817 2705 18349946.72438 +2818 2705 52296851.6274 +2819 2705 -103249742.1615 +2826 2705 -8444910.309145 +2827 2705 -8163229.232496 +2828 2705 -10570710.68328 +2829 2705 -53439363.43899 +2830 2705 -5277708.20877 +2831 2705 -66116380.01208 +2832 2705 -18340743.64572 +2833 2705 13440937.44126 +2834 2705 -39208792.08802 +2706 2706 508612796.7711 +2707 2706 47777777.76993 +2708 2706 20248388.26907 +2718 2706 -71804122.04904 +2719 2706 -47777777.76993 +2720 2706 19043969.88243 +2721 2706 -267652150.2947 +2722 2706 -47793765.64302 +2723 2706 -20241471.08164 +2724 2706 6087083.420696 +2725 2706 38238210.08904 +2726 2706 -16367807.61161 +2802 2706 1532382.642161 +2803 2706 14339328.79045 +2804 2706 9874015.186731 +2814 2706 -4845636.536104 +2815 2706 -11950439.90078 +2816 2706 -8009104.879749 +2817 2706 57272319.20769 +2818 2706 11944444.44837 +2819 2706 16262217.83282 +2829 2706 -20039396.92541 +2830 2706 -11944444.44837 +2831 2706 -8444910.309145 +2832 2706 -96920154.16551 +2833 2706 -11948441.41665 +2834 2706 -57894966.96635 +2835 2706 -19430363.65776 +2836 2706 9559552.526969 +2837 2706 -14502802.0572 +2707 2707 436923838.9196 +2708 2707 -52790465.59624 +2718 2707 -47777777.76993 +2719 2707 -57469927.96065 +2720 2707 9605416.412441 +2721 2707 -47801759.57957 +2722 2707 -43044343.65972 +2723 2707 -29246608.86722 +2724 2707 57357315.13355 +2725 2707 6087083.420705 +2726 2707 18374525.78853 +2802 2707 9559552.526969 +2803 2707 1532382.642157 +2804 2707 -5266148.137347 +2814 2707 -11948441.41664 +2815 2707 -46658897.27468 +2816 2707 -32026328.33686 +2817 2707 11944444.44837 +2818 2707 39350079.73598 +2819 2707 -4237631.002181 +2829 2707 -11944444.44837 +2830 2707 -16455848.40155 +2831 2707 -8163229.232496 +2832 2707 -11950439.90079 +2833 2707 -40768202.4791 +2834 2707 -17881456.80322 +2835 2707 14339328.79045 +2836 2707 -19430363.65775 +2837 2707 17403019.36621 +2708 2708 498731997.6738 +2718 2708 18780080.99371 +2719 2708 9394305.301468 +2720 2708 -20006934.4106 +2721 2708 -20238012.48793 +2722 2708 -23543989.15986 +2723 2708 -9089122.520285 +2724 2708 -24551711.41742 +2725 2708 12249683.85902 +2726 2708 16232222.45521 +2802 2708 6582676.791154 +2803 2708 -7899222.206021 +2804 2708 4086353.712421 +2814 2708 -8007766.485252 +2815 2708 -33293672.07046 +2816 2708 -17559666.33271 +2817 2708 -4818855.100867 +2818 2708 -21102266.9381 +2819 2708 -61666013.98076 +2829 2708 -8444910.309145 +2830 2708 -8163229.232496 +2831 2708 -10570710.68328 +2832 2708 -57630268.59944 +2833 2708 -16401283.68257 +2834 2708 -82291258.12151 +2835 2708 -21754203.08579 +2836 2708 11602012.9108 +2837 2708 -51814303.08735 +2709 2709 801867013.5374 +2710 2709 2.598762512207e-05 +2711 2709 7037129.799195 +2712 2709 92970237.73849 +2713 2709 -1.010298728943e-05 +2714 2709 1759282.450673 +2727 2709 -181853790.138 +2728 2709 3.248453140259e-06 +2729 2709 -3518564.899638 +2730 2709 -72853540.65349 +2731 2709 47777777.76992 +2732 2709 -20539363.4444 +2805 2709 -71968136.03531 +2806 2709 4.157423973083e-06 +2807 2709 51943969.87703 +2808 2709 -29817851.87049 +2809 2709 -11944444.44837 +2810 2709 17900923.03284 +2820 2709 88895212.80375 +2821 2709 4.112720489502e-06 +2822 2709 1759282.450699 +2823 2709 -25612922.63328 +2824 2709 -1.080334186554e-05 +2825 2709 439820.6129002 +2838 2709 -74762019.75572 +2839 2709 2.533197402954e-07 +2840 2709 -53703252.3277 +2841 2709 -30778677.45218 +2842 2709 11944444.44836 +2843 2709 -18340743.64572 +2710 2710 687193460.8868 +2711 2710 -84443331.25708 +2712 2710 -1.019239425659e-05 +2713 2710 -88585023.89729 +2714 2710 42221665.62855 +2727 2710 3.069639205933e-06 +2728 2710 28369859.6463 +2729 2710 -21110832.82467 +2730 2710 47777777.76992 +2731 2710 -58519346.56511 +2732 2710 11505416.41223 +2805 2710 3.337860107422e-06 +2806 2710 -19412223.56332 +2807 2710 -5277708.208769 +2808 2710 -11944444.44837 +2809 2710 -26234303.34662 +2810 2710 12913159.66331 +2820 2710 4.351139068604e-06 +2821 2710 60226824.62697 +2822 2710 -21110832.82468 +2823 2710 -9.95397567749e-06 +2824 2710 -71001738.06458 +2825 2710 52813749.73867 +2838 2710 -8.195638656616e-07 +2839 2710 -22206107.28377 +2840 2710 -5277708.20877 +2841 2710 11944444.44836 +2842 2710 -27195128.92833 +2843 2710 13440937.44126 +2711 2711 766546241.681 +2712 2711 1759282.450673 +2713 2711 42221665.62855 +2714 2711 57866058.65466 +2727 2711 -3518564.899638 +2728 2711 -21110832.82467 +2729 2711 48052583.38233 +2730 2711 -20803252.33311 +2731 2711 11716527.5232 +2732 2711 -22805384.02253 +2805 2711 51680080.98832 +2806 2711 -5277708.208769 +2807 2711 -58666023.42418 +2808 2711 17900923.03284 +2809 2711 12913159.66331 +2810 2711 -36646590.5368 +2820 2711 1759282.450699 +2821 2711 -21110832.82468 +2822 2711 -105887547.9636 +2823 2711 439820.6129005 +2824 2711 52602638.6277 +2825 2711 -115814770.8741 +2838 2711 -53439363.43899 +2839 2711 -5277708.20877 +2840 2711 -66116380.01208 +2841 2711 -18340743.64572 +2842 2711 13440937.44126 +2843 2711 -39208792.08802 +2712 2712 801867013.5374 +2713 2712 2.598762512207e-05 +2714 2712 7037129.799195 +2715 2712 92970237.73849 +2716 2712 -1.010298728943e-05 +2717 2712 1759282.450673 +2727 2712 -71804122.04904 +2728 2712 -47777777.76993 +2729 2712 19043969.88243 +2730 2712 -181853790.138 +2731 2712 3.248453140259e-06 +2732 2712 -3518564.899638 +2733 2712 -72853540.65349 +2734 2712 47777777.76992 +2735 2712 -20539363.4444 +2805 2712 -19603280.6462 +2806 2712 11944444.44837 +2807 2712 8005089.696258 +2808 2712 -71968136.03531 +2809 2712 4.157423973083e-06 +2810 2712 51943969.87703 +2811 2712 -29817851.87049 +2812 2712 -11944444.44837 +2813 2712 17900923.03284 +2820 2712 16294780.8482 +2821 2712 4.217028617859e-06 +2822 2712 439820.6128852 +2823 2712 88895212.80375 +2824 2712 4.112720489502e-06 +2825 2712 1759282.450699 +2826 2712 -25612922.63328 +2827 2712 -1.080334186554e-05 +2828 2712 439820.6129002 +2838 2712 -20039396.92541 +2839 2712 -11944444.44837 +2840 2712 -8444910.309145 +2841 2712 -74762019.75572 +2842 2712 2.533197402954e-07 +2843 2712 -53703252.3277 +2844 2712 -30778677.45218 +2845 2712 11944444.44836 +2846 2712 -18340743.64572 +2713 2713 687193460.8868 +2714 2713 -84443331.25708 +2715 2713 -1.019239425659e-05 +2716 2713 -88585023.89729 +2717 2713 42221665.62855 +2727 2713 -47777777.76993 +2728 2713 -57469927.96065 +2729 2713 9605416.412441 +2730 2713 3.069639205933e-06 +2731 2713 28369859.6463 +2732 2713 -21110832.82467 +2733 2713 47777777.76992 +2734 2713 -58519346.56511 +2735 2713 11505416.41223 +2805 2713 11944444.44837 +2806 2713 -16019732.12234 +2807 2713 -7635451.454545 +2808 2713 3.337860107422e-06 +2809 2713 -19412223.56332 +2810 2713 -5277708.208769 +2811 2713 -11944444.44837 +2812 2713 -26234303.34662 +2813 2713 12913159.66331 +2820 2713 5.125999450684e-06 +2821 2713 -29094034.58311 +2822 2713 -31702916.914 +2823 2713 4.351139068604e-06 +2824 2713 60226824.62697 +2825 2713 -21110832.82468 +2826 2713 -9.95397567749e-06 +2827 2713 -71001738.06458 +2828 2713 52813749.73867 +2838 2713 -11944444.44837 +2839 2713 -16455848.40155 +2840 2713 -8163229.232496 +2841 2713 -8.195638656616e-07 +2842 2713 -22206107.28377 +2843 2713 -5277708.20877 +2844 2713 11944444.44836 +2845 2713 -27195128.92833 +2846 2713 13440937.44126 +2714 2714 766546241.681 +2715 2714 1759282.450673 +2716 2714 42221665.62855 +2717 2714 57866058.65466 +2727 2714 18780080.99371 +2728 2714 9394305.301468 +2729 2714 -20006934.4106 +2730 2714 -3518564.899638 +2731 2714 -21110832.82467 +2732 2714 48052583.38233 +2733 2714 -20803252.33311 +2734 2714 11716527.5232 +2735 2714 -22805384.02253 +2805 2714 8005089.696258 +2806 2714 -7635451.454545 +2807 2714 -9407733.938713 +2808 2714 51680080.98832 +2809 2714 -5277708.208769 +2810 2714 -58666023.42418 +2811 2714 17900923.03284 +2812 2714 12913159.66331 +2813 2714 -36646590.5368 +2820 2714 439820.6128855 +2821 2714 -31491805.80303 +2822 2714 -4060894.923526 +2823 2714 1759282.450699 +2824 2714 -21110832.82468 +2825 2714 -105887547.9636 +2826 2714 439820.6129005 +2827 2714 52602638.6277 +2828 2714 -115814770.8741 +2838 2714 -8444910.309145 +2839 2714 -8163229.232496 +2840 2714 -10570710.68328 +2841 2714 -53439363.43899 +2842 2714 -5277708.20877 +2843 2714 -66116380.01208 +2844 2714 -18340743.64572 +2845 2714 13440937.44126 +2846 2714 -39208792.08802 +2715 2715 801867013.5374 +2716 2715 2.598762512207e-05 +2717 2715 7037129.799195 +2718 2715 92970237.73849 +2719 2715 -1.010298728943e-05 +2720 2715 1759282.450673 +2730 2715 -71804122.04904 +2731 2715 -47777777.76993 +2732 2715 19043969.88243 +2733 2715 -181853790.138 +2734 2715 3.248453140259e-06 +2735 2715 -3518564.899638 +2736 2715 -72853540.65349 +2737 2715 47777777.76992 +2738 2715 -20539363.4444 +2808 2715 -19603280.6462 +2809 2715 11944444.44837 +2810 2715 8005089.696258 +2811 2715 -71968136.03531 +2812 2715 4.157423973083e-06 +2813 2715 51943969.87703 +2814 2715 -29817851.87049 +2815 2715 -11944444.44837 +2816 2715 17900923.03284 +2823 2715 16294780.8482 +2824 2715 4.217028617859e-06 +2825 2715 439820.6128852 +2826 2715 88895212.80375 +2827 2715 4.112720489502e-06 +2828 2715 1759282.450699 +2829 2715 -25612922.63328 +2830 2715 -1.080334186554e-05 +2831 2715 439820.6129002 +2841 2715 -20039396.92541 +2842 2715 -11944444.44837 +2843 2715 -8444910.309145 +2844 2715 -74762019.75572 +2845 2715 2.533197402954e-07 +2846 2715 -53703252.3277 +2847 2715 -30778677.45218 +2848 2715 11944444.44836 +2849 2715 -18340743.64572 +2716 2716 687193460.8868 +2717 2716 -84443331.25708 +2718 2716 -1.019239425659e-05 +2719 2716 -88585023.89729 +2720 2716 42221665.62855 +2730 2716 -47777777.76993 +2731 2716 -57469927.96065 +2732 2716 9605416.412441 +2733 2716 3.069639205933e-06 +2734 2716 28369859.6463 +2735 2716 -21110832.82467 +2736 2716 47777777.76992 +2737 2716 -58519346.56511 +2738 2716 11505416.41223 +2808 2716 11944444.44837 +2809 2716 -16019732.12234 +2810 2716 -7635451.454545 +2811 2716 3.337860107422e-06 +2812 2716 -19412223.56332 +2813 2716 -5277708.208769 +2814 2716 -11944444.44837 +2815 2716 -26234303.34662 +2816 2716 12913159.66331 +2823 2716 5.125999450684e-06 +2824 2716 -29094034.58311 +2825 2716 -31702916.914 +2826 2716 4.351139068604e-06 +2827 2716 60226824.62697 +2828 2716 -21110832.82468 +2829 2716 -9.95397567749e-06 +2830 2716 -71001738.06458 +2831 2716 52813749.73867 +2841 2716 -11944444.44837 +2842 2716 -16455848.40155 +2843 2716 -8163229.232496 +2844 2716 -8.195638656616e-07 +2845 2716 -22206107.28377 +2846 2716 -5277708.20877 +2847 2716 11944444.44836 +2848 2716 -27195128.92833 +2849 2716 13440937.44126 +2717 2717 766546241.681 +2718 2717 1759282.450673 +2719 2717 42221665.62855 +2720 2717 57866058.65466 +2730 2717 18780080.99371 +2731 2717 9394305.301468 +2732 2717 -20006934.4106 +2733 2717 -3518564.899638 +2734 2717 -21110832.82467 +2735 2717 48052583.38233 +2736 2717 -20803252.33311 +2737 2717 11716527.5232 +2738 2717 -22805384.02253 +2808 2717 8005089.696258 +2809 2717 -7635451.454545 +2810 2717 -9407733.938713 +2811 2717 51680080.98832 +2812 2717 -5277708.208769 +2813 2717 -58666023.42418 +2814 2717 17900923.03284 +2815 2717 12913159.66331 +2816 2717 -36646590.5368 +2823 2717 439820.6128855 +2824 2717 -31491805.80303 +2825 2717 -4060894.923526 +2826 2717 1759282.450699 +2827 2717 -21110832.82468 +2828 2717 -105887547.9636 +2829 2717 439820.6129005 +2830 2717 52602638.6277 +2831 2717 -115814770.8741 +2841 2717 -8444910.309145 +2842 2717 -8163229.232496 +2843 2717 -10570710.68328 +2844 2717 -53439363.43899 +2845 2717 -5277708.20877 +2846 2717 -66116380.01208 +2847 2717 -18340743.64572 +2848 2717 13440937.44126 +2849 2717 -39208792.08802 +2718 2718 801867013.5374 +2719 2718 2.598762512207e-05 +2720 2718 7037129.799195 +2721 2718 92970237.73849 +2722 2718 -1.010298728943e-05 +2723 2718 1759282.450673 +2733 2718 -71804122.04904 +2734 2718 -47777777.76993 +2735 2718 19043969.88243 +2736 2718 -181853790.138 +2737 2718 3.248453140259e-06 +2738 2718 -3518564.899638 +2739 2718 -72853540.65349 +2740 2718 47777777.76992 +2741 2718 -20539363.4444 +2811 2718 -19603280.6462 +2812 2718 11944444.44837 +2813 2718 8005089.696258 +2814 2718 -71968136.03531 +2815 2718 4.157423973083e-06 +2816 2718 51943969.87703 +2817 2718 -29817851.87049 +2818 2718 -11944444.44837 +2819 2718 17900923.03284 +2826 2718 16294780.8482 +2827 2718 4.217028617859e-06 +2828 2718 439820.6128852 +2829 2718 88895212.80375 +2830 2718 4.112720489502e-06 +2831 2718 1759282.450699 +2832 2718 -25612922.63328 +2833 2718 -1.080334186554e-05 +2834 2718 439820.6129002 +2844 2718 -20039396.92541 +2845 2718 -11944444.44837 +2846 2718 -8444910.309145 +2847 2718 -74762019.75572 +2848 2718 2.533197402954e-07 +2849 2718 -53703252.3277 +2850 2718 -30778677.45218 +2851 2718 11944444.44836 +2852 2718 -18340743.64572 +2719 2719 687193460.8868 +2720 2719 -84443331.25708 +2721 2719 -1.019239425659e-05 +2722 2719 -88585023.89729 +2723 2719 42221665.62855 +2733 2719 -47777777.76993 +2734 2719 -57469927.96065 +2735 2719 9605416.412441 +2736 2719 3.069639205933e-06 +2737 2719 28369859.6463 +2738 2719 -21110832.82467 +2739 2719 47777777.76992 +2740 2719 -58519346.56511 +2741 2719 11505416.41223 +2811 2719 11944444.44837 +2812 2719 -16019732.12234 +2813 2719 -7635451.454545 +2814 2719 3.337860107422e-06 +2815 2719 -19412223.56332 +2816 2719 -5277708.208769 +2817 2719 -11944444.44837 +2818 2719 -26234303.34662 +2819 2719 12913159.66331 +2826 2719 5.125999450684e-06 +2827 2719 -29094034.58311 +2828 2719 -31702916.914 +2829 2719 4.351139068604e-06 +2830 2719 60226824.62697 +2831 2719 -21110832.82468 +2832 2719 -9.95397567749e-06 +2833 2719 -71001738.06458 +2834 2719 52813749.73867 +2844 2719 -11944444.44837 +2845 2719 -16455848.40155 +2846 2719 -8163229.232496 +2847 2719 -8.195638656616e-07 +2848 2719 -22206107.28377 +2849 2719 -5277708.20877 +2850 2719 11944444.44836 +2851 2719 -27195128.92833 +2852 2719 13440937.44126 +2720 2720 766546241.681 +2721 2720 1759282.450673 +2722 2720 42221665.62855 +2723 2720 57866058.65466 +2733 2720 18780080.99371 +2734 2720 9394305.301468 +2735 2720 -20006934.4106 +2736 2720 -3518564.899638 +2737 2720 -21110832.82467 +2738 2720 48052583.38233 +2739 2720 -20803252.33311 +2740 2720 11716527.5232 +2741 2720 -22805384.02253 +2811 2720 8005089.696258 +2812 2720 -7635451.454545 +2813 2720 -9407733.938713 +2814 2720 51680080.98832 +2815 2720 -5277708.208769 +2816 2720 -58666023.42418 +2817 2720 17900923.03284 +2818 2720 12913159.66331 +2819 2720 -36646590.5368 +2826 2720 439820.6128855 +2827 2720 -31491805.80303 +2828 2720 -4060894.923526 +2829 2720 1759282.450699 +2830 2720 -21110832.82468 +2831 2720 -105887547.9636 +2832 2720 439820.6129005 +2833 2720 52602638.6277 +2834 2720 -115814770.8741 +2844 2720 -8444910.309145 +2845 2720 -8163229.232496 +2846 2720 -10570710.68328 +2847 2720 -53439363.43899 +2848 2720 -5277708.20877 +2849 2720 -66116380.01208 +2850 2720 -18340743.64572 +2851 2720 13440937.44126 +2852 2720 -39208792.08802 +2721 2721 866925828.5346 +2722 2721 47817747.45269 +2723 2721 23749660.20008 +2724 2721 14263474.74723 +2725 2721 -47793765.64302 +2726 2721 20546059.94785 +2736 2721 -71804122.04904 +2737 2721 -47777777.76993 +2738 2721 19043969.88243 +2739 2721 -181853790.138 +2740 2721 3.248453140259e-06 +2741 2721 -3518564.899638 +2742 2721 -72853540.65349 +2743 2721 47777777.76992 +2744 2721 -20539363.4444 +2814 2721 -19603280.6462 +2815 2721 11944444.44837 +2816 2721 8005089.696258 +2817 2721 -85740387.93072 +2818 2721 -11950439.90077 +2819 2721 47775096.06898 +2829 2721 16294780.8482 +2830 2721 4.217028617859e-06 +2831 2721 439820.6128852 +2832 2721 112006329.4708 +2833 2721 11954436.86906 +2834 2721 5935349.843305 +2835 2721 -36979414.9719 +2836 2721 -11948441.41664 +2837 2721 18346879.03149 +2847 2721 -20039396.92541 +2848 2721 -11944444.44837 +2849 2721 -8444910.309145 +2850 2721 -74762019.75572 +2851 2721 2.533197402954e-07 +2852 2721 -53703252.3277 +2853 2721 -30778677.45218 +2854 2721 11944444.44836 +2855 2721 -18340743.64572 +2722 2722 737900094.3577 +2723 2722 -65443918.48946 +2724 2722 -47801759.57957 +2725 2722 -152989568.1247 +2726 2722 35049537.95506 +2736 2722 -47777777.76993 +2737 2722 -57469927.96065 +2738 2722 9605416.412441 +2739 2722 3.069639205933e-06 +2740 2722 28369859.6463 +2741 2722 -21110832.82467 +2742 2722 47777777.76992 +2743 2722 -58519346.56511 +2744 2722 11505416.41223 +2814 2722 11944444.44837 +2815 2722 -16019732.12234 +2816 2722 -7635451.454545 +2817 2722 -11948441.41664 +2818 2722 -29588436.2443 +2819 2722 4682155.144749 +2829 2722 5.125999450684e-06 +2830 2722 -29094034.58311 +2831 2722 -31702916.914 +2832 2722 11954436.86906 +2833 2722 79749895.91067 +2834 2722 -16362631.77783 +2835 2722 -11950439.90078 +2836 2722 -78792675.71048 +2837 2722 51029508.03613 +2847 2722 -11944444.44837 +2848 2722 -16455848.40155 +2849 2722 -8163229.232496 +2850 2722 -8.195638656616e-07 +2851 2722 -22206107.28377 +2852 2722 -5277708.20877 +2853 2722 11944444.44836 +2854 2722 -27195128.92833 +2855 2722 13440937.44126 +2723 2723 768350518.5004 +2724 2723 20813297.08829 +2725 2723 40963180.50213 +2726 2723 19484057.05595 +2736 2723 18780080.99371 +2737 2723 9394305.301468 +2738 2723 -20006934.4106 +2739 2723 -3518564.899638 +2740 2723 -21110832.82467 +2741 2723 48052583.38233 +2742 2723 -20803252.33311 +2743 2723 11716527.5232 +2744 2723 -22805384.02253 +2814 2723 8005089.696258 +2815 2723 -7635451.454545 +2816 2723 -9407733.938713 +2817 2723 47510397.70207 +2818 2723 3205506.989851 +2819 2723 -52478548.16204 +2829 2723 439820.6128855 +2830 2723 -31491805.80303 +2831 2723 -4060894.923526 +2832 2723 5939756.113784 +2833 2723 -16359106.80793 +2834 2723 -87179377.66603 +2835 2723 18349946.72438 +2836 2723 52296851.6274 +2837 2723 -103249742.1615 +2847 2723 -8444910.309145 +2848 2723 -8163229.232496 +2849 2723 -10570710.68328 +2850 2723 -53439363.43899 +2851 2723 -5277708.20877 +2852 2723 -66116380.01208 +2853 2723 -18340743.64572 +2854 2723 13440937.44126 +2855 2723 -39208792.08802 +2724 2724 411984836.6329 +2725 2724 -7936152.30026 +2726 2724 -12597657.48158 +2739 2724 -71804122.04904 +2740 2724 -47777777.76993 +2741 2724 19043969.88243 +2742 2724 -138080718.2873 +2743 2724 7859319.261471 +2744 2724 -1118612.233799 +2745 2724 -59031787.7105 +2746 2724 38299055.25473 +2747 2724 -3172177.802272 +2817 2724 1532382.642161 +2818 2724 14339328.79045 +2819 2724 9874015.186731 +2832 2724 -4845636.536104 +2833 2724 -11950439.90078 +2834 2724 -8009104.879749 +2835 2724 45154799.16275 +2836 2724 -1984038.076042 +2837 2724 5318188.302819 +2850 2724 -20039396.92541 +2851 2724 -11944444.44837 +2852 2724 -8444910.309145 +2853 2724 -54446261.20618 +2854 2724 1964829.816336 +2855 2724 -37868990.52104 +2856 2724 -20832796.07979 +2857 2724 9574763.8184 +2858 2724 -4947522.887458 +2725 2725 472335181.7353 +2726 2725 -60215952.15695 +2739 2725 -47777777.76993 +2740 2725 -57469927.96065 +2741 2725 9605416.412441 +2742 2725 7820902.742076 +2743 2725 61644059.27118 +2744 2725 -13951237.99313 +2745 2725 57448582.8821 +2746 2725 -166188061.588 +2747 2725 10078720.53082 +2817 2725 9559552.526969 +2818 2725 1532382.642157 +2819 2725 -5266148.137347 +2832 2725 -11948441.41664 +2833 2725 -46658897.27468 +2834 2725 -32026328.33686 +2835 2725 -1984038.076043 +2836 2725 60242385.44579 +2837 2725 -8284128.881153 +2850 2725 -11944444.44837 +2851 2725 -16455848.40155 +2852 2725 -8163229.232496 +2853 2725 1955225.686481 +2854 2725 -4515066.791966 +2855 2725 -1847868.948734 +2856 2725 14362145.7276 +2857 2725 -47621864.56235 +2858 2725 20366850.75772 +2726 2726 433150810.8594 +2739 2726 18780080.99371 +2740 2726 9394305.301468 +2741 2726 -20006934.4106 +2742 2726 -7976747.091482 +2743 2726 -13738986.98741 +2744 2726 37185048.73447 +2745 2726 -4758266.703408 +2746 2726 9231286.830788 +2747 2726 -50261826.68389 +2817 2726 6582676.791154 +2818 2726 -7899222.206021 +2819 2726 4086353.712421 +2832 2726 -8007766.485252 +2833 2726 -33293672.07046 +2834 2726 -17559666.33271 +2835 2726 -9638402.083643 +2836 2726 -20236111.15782 +2837 2726 -45956057.35504 +2850 2726 -8444910.309145 +2851 2726 -8163229.232496 +2852 2726 -10570710.68328 +2853 2726 -39187801.2437 +2854 2726 -1627591.468903 +2855 2726 -43839955.45809 +2856 2726 -7421284.331187 +2857 2726 18388546.96739 +2858 2726 -28765054.39688 +2727 2727 801867013.5374 +2728 2727 2.598762512207e-05 +2729 2727 7037129.799195 +2730 2727 92970237.73849 +2731 2727 -1.010298728943e-05 +2732 2727 1759282.450673 +2748 2727 -181853790.138 +2749 2727 3.248453140259e-06 +2750 2727 -3518564.899638 +2751 2727 -72853540.65349 +2752 2727 47777777.76992 +2753 2727 -20539363.4444 +2820 2727 -71968136.03531 +2821 2727 4.157423973083e-06 +2822 2727 51943969.87703 +2823 2727 -29817851.87049 +2824 2727 -11944444.44837 +2825 2727 17900923.03284 +2838 2727 88895212.80375 +2839 2727 4.112720489502e-06 +2840 2727 1759282.450699 +2841 2727 -25612922.63328 +2842 2727 -1.080334186554e-05 +2843 2727 439820.6129002 +2859 2727 -74762019.75572 +2860 2727 2.533197402954e-07 +2861 2727 -53703252.3277 +2862 2727 -30778677.45218 +2863 2727 11944444.44836 +2864 2727 -18340743.64572 +2728 2728 687193460.8868 +2729 2728 -84443331.25708 +2730 2728 -1.019239425659e-05 +2731 2728 -88585023.89729 +2732 2728 42221665.62855 +2748 2728 3.069639205933e-06 +2749 2728 28369859.6463 +2750 2728 -21110832.82467 +2751 2728 47777777.76992 +2752 2728 -58519346.56511 +2753 2728 11505416.41223 +2820 2728 3.337860107422e-06 +2821 2728 -19412223.56332 +2822 2728 -5277708.208769 +2823 2728 -11944444.44837 +2824 2728 -26234303.34662 +2825 2728 12913159.66331 +2838 2728 4.351139068604e-06 +2839 2728 60226824.62697 +2840 2728 -21110832.82468 +2841 2728 -9.95397567749e-06 +2842 2728 -71001738.06458 +2843 2728 52813749.73867 +2859 2728 -8.195638656616e-07 +2860 2728 -22206107.28377 +2861 2728 -5277708.20877 +2862 2728 11944444.44836 +2863 2728 -27195128.92833 +2864 2728 13440937.44126 +2729 2729 766546241.681 +2730 2729 1759282.450673 +2731 2729 42221665.62855 +2732 2729 57866058.65466 +2748 2729 -3518564.899638 +2749 2729 -21110832.82467 +2750 2729 48052583.38233 +2751 2729 -20803252.33311 +2752 2729 11716527.5232 +2753 2729 -22805384.02253 +2820 2729 51680080.98832 +2821 2729 -5277708.208769 +2822 2729 -58666023.42418 +2823 2729 17900923.03284 +2824 2729 12913159.66331 +2825 2729 -36646590.5368 +2838 2729 1759282.450699 +2839 2729 -21110832.82468 +2840 2729 -105887547.9636 +2841 2729 439820.6129005 +2842 2729 52602638.6277 +2843 2729 -115814770.8741 +2859 2729 -53439363.43899 +2860 2729 -5277708.20877 +2861 2729 -66116380.01208 +2862 2729 -18340743.64572 +2863 2729 13440937.44126 +2864 2729 -39208792.08802 +2730 2730 801867013.5374 +2731 2730 2.598762512207e-05 +2732 2730 7037129.799195 +2733 2730 92970237.73849 +2734 2730 -1.010298728943e-05 +2735 2730 1759282.450673 +2748 2730 -71804122.04904 +2749 2730 -47777777.76993 +2750 2730 19043969.88243 +2751 2730 -181853790.138 +2752 2730 3.248453140259e-06 +2753 2730 -3518564.899638 +2754 2730 -72853540.65349 +2755 2730 47777777.76992 +2756 2730 -20539363.4444 +2820 2730 -19603280.6462 +2821 2730 11944444.44837 +2822 2730 8005089.696258 +2823 2730 -71968136.03531 +2824 2730 4.157423973083e-06 +2825 2730 51943969.87703 +2826 2730 -29817851.87049 +2827 2730 -11944444.44837 +2828 2730 17900923.03284 +2838 2730 16294780.8482 +2839 2730 4.217028617859e-06 +2840 2730 439820.6128852 +2841 2730 88895212.80375 +2842 2730 4.112720489502e-06 +2843 2730 1759282.450699 +2844 2730 -25612922.63328 +2845 2730 -1.080334186554e-05 +2846 2730 439820.6129002 +2859 2730 -20039396.92541 +2860 2730 -11944444.44837 +2861 2730 -8444910.309145 +2862 2730 -74762019.75572 +2863 2730 2.533197402954e-07 +2864 2730 -53703252.3277 +2865 2730 -30778677.45218 +2866 2730 11944444.44836 +2867 2730 -18340743.64572 +2731 2731 687193460.8868 +2732 2731 -84443331.25708 +2733 2731 -1.019239425659e-05 +2734 2731 -88585023.89729 +2735 2731 42221665.62855 +2748 2731 -47777777.76993 +2749 2731 -57469927.96065 +2750 2731 9605416.412441 +2751 2731 3.069639205933e-06 +2752 2731 28369859.6463 +2753 2731 -21110832.82467 +2754 2731 47777777.76992 +2755 2731 -58519346.56511 +2756 2731 11505416.41223 +2820 2731 11944444.44837 +2821 2731 -16019732.12234 +2822 2731 -7635451.454545 +2823 2731 3.337860107422e-06 +2824 2731 -19412223.56332 +2825 2731 -5277708.208769 +2826 2731 -11944444.44837 +2827 2731 -26234303.34662 +2828 2731 12913159.66331 +2838 2731 5.125999450684e-06 +2839 2731 -29094034.58311 +2840 2731 -31702916.914 +2841 2731 4.351139068604e-06 +2842 2731 60226824.62697 +2843 2731 -21110832.82468 +2844 2731 -9.95397567749e-06 +2845 2731 -71001738.06458 +2846 2731 52813749.73867 +2859 2731 -11944444.44837 +2860 2731 -16455848.40155 +2861 2731 -8163229.232496 +2862 2731 -8.195638656616e-07 +2863 2731 -22206107.28377 +2864 2731 -5277708.20877 +2865 2731 11944444.44836 +2866 2731 -27195128.92833 +2867 2731 13440937.44126 +2732 2732 766546241.681 +2733 2732 1759282.450673 +2734 2732 42221665.62855 +2735 2732 57866058.65466 +2748 2732 18780080.99371 +2749 2732 9394305.301468 +2750 2732 -20006934.4106 +2751 2732 -3518564.899638 +2752 2732 -21110832.82467 +2753 2732 48052583.38233 +2754 2732 -20803252.33311 +2755 2732 11716527.5232 +2756 2732 -22805384.02253 +2820 2732 8005089.696258 +2821 2732 -7635451.454545 +2822 2732 -9407733.938713 +2823 2732 51680080.98832 +2824 2732 -5277708.208769 +2825 2732 -58666023.42418 +2826 2732 17900923.03284 +2827 2732 12913159.66331 +2828 2732 -36646590.5368 +2838 2732 439820.6128855 +2839 2732 -31491805.80303 +2840 2732 -4060894.923526 +2841 2732 1759282.450699 +2842 2732 -21110832.82468 +2843 2732 -105887547.9636 +2844 2732 439820.6129005 +2845 2732 52602638.6277 +2846 2732 -115814770.8741 +2859 2732 -8444910.309145 +2860 2732 -8163229.232496 +2861 2732 -10570710.68328 +2862 2732 -53439363.43899 +2863 2732 -5277708.20877 +2864 2732 -66116380.01208 +2865 2732 -18340743.64572 +2866 2732 13440937.44126 +2867 2732 -39208792.08802 +2733 2733 801867013.5374 +2734 2733 2.598762512207e-05 +2735 2733 7037129.799195 +2736 2733 92970237.73849 +2737 2733 -1.010298728943e-05 +2738 2733 1759282.450673 +2751 2733 -71804122.04904 +2752 2733 -47777777.76993 +2753 2733 19043969.88243 +2754 2733 -181853790.138 +2755 2733 3.248453140259e-06 +2756 2733 -3518564.899638 +2757 2733 -72853540.65349 +2758 2733 47777777.76992 +2759 2733 -20539363.4444 +2823 2733 -19603280.6462 +2824 2733 11944444.44837 +2825 2733 8005089.696258 +2826 2733 -71968136.03531 +2827 2733 4.157423973083e-06 +2828 2733 51943969.87703 +2829 2733 -29817851.87049 +2830 2733 -11944444.44837 +2831 2733 17900923.03284 +2841 2733 16294780.8482 +2842 2733 4.217028617859e-06 +2843 2733 439820.6128852 +2844 2733 88895212.80375 +2845 2733 4.112720489502e-06 +2846 2733 1759282.450699 +2847 2733 -25612922.63328 +2848 2733 -1.080334186554e-05 +2849 2733 439820.6129002 +2862 2733 -20039396.92541 +2863 2733 -11944444.44837 +2864 2733 -8444910.309145 +2865 2733 -74762019.75572 +2866 2733 2.533197402954e-07 +2867 2733 -53703252.3277 +2868 2733 -30778677.45218 +2869 2733 11944444.44836 +2870 2733 -18340743.64572 +2734 2734 687193460.8868 +2735 2734 -84443331.25708 +2736 2734 -1.019239425659e-05 +2737 2734 -88585023.89729 +2738 2734 42221665.62855 +2751 2734 -47777777.76993 +2752 2734 -57469927.96065 +2753 2734 9605416.412441 +2754 2734 3.069639205933e-06 +2755 2734 28369859.6463 +2756 2734 -21110832.82467 +2757 2734 47777777.76992 +2758 2734 -58519346.56511 +2759 2734 11505416.41223 +2823 2734 11944444.44837 +2824 2734 -16019732.12234 +2825 2734 -7635451.454545 +2826 2734 3.337860107422e-06 +2827 2734 -19412223.56332 +2828 2734 -5277708.208769 +2829 2734 -11944444.44837 +2830 2734 -26234303.34662 +2831 2734 12913159.66331 +2841 2734 5.125999450684e-06 +2842 2734 -29094034.58311 +2843 2734 -31702916.914 +2844 2734 4.351139068604e-06 +2845 2734 60226824.62697 +2846 2734 -21110832.82468 +2847 2734 -9.95397567749e-06 +2848 2734 -71001738.06458 +2849 2734 52813749.73867 +2862 2734 -11944444.44837 +2863 2734 -16455848.40155 +2864 2734 -8163229.232496 +2865 2734 -8.195638656616e-07 +2866 2734 -22206107.28377 +2867 2734 -5277708.20877 +2868 2734 11944444.44836 +2869 2734 -27195128.92833 +2870 2734 13440937.44126 +2735 2735 766546241.681 +2736 2735 1759282.450673 +2737 2735 42221665.62855 +2738 2735 57866058.65466 +2751 2735 18780080.99371 +2752 2735 9394305.301468 +2753 2735 -20006934.4106 +2754 2735 -3518564.899638 +2755 2735 -21110832.82467 +2756 2735 48052583.38233 +2757 2735 -20803252.33311 +2758 2735 11716527.5232 +2759 2735 -22805384.02253 +2823 2735 8005089.696258 +2824 2735 -7635451.454545 +2825 2735 -9407733.938713 +2826 2735 51680080.98832 +2827 2735 -5277708.208769 +2828 2735 -58666023.42418 +2829 2735 17900923.03284 +2830 2735 12913159.66331 +2831 2735 -36646590.5368 +2841 2735 439820.6128855 +2842 2735 -31491805.80303 +2843 2735 -4060894.923526 +2844 2735 1759282.450699 +2845 2735 -21110832.82468 +2846 2735 -105887547.9636 +2847 2735 439820.6129005 +2848 2735 52602638.6277 +2849 2735 -115814770.8741 +2862 2735 -8444910.309145 +2863 2735 -8163229.232496 +2864 2735 -10570710.68328 +2865 2735 -53439363.43899 +2866 2735 -5277708.20877 +2867 2735 -66116380.01208 +2868 2735 -18340743.64572 +2869 2735 13440937.44126 +2870 2735 -39208792.08802 +2736 2736 801867013.5374 +2737 2736 2.598762512207e-05 +2738 2736 7037129.799195 +2739 2736 92970237.73849 +2740 2736 -1.010298728943e-05 +2741 2736 1759282.450673 +2754 2736 -71804122.04904 +2755 2736 -47777777.76993 +2756 2736 19043969.88243 +2757 2736 -181853790.138 +2758 2736 3.248453140259e-06 +2759 2736 -3518564.899638 +2760 2736 -72853540.65349 +2761 2736 47777777.76992 +2762 2736 -20539363.4444 +2826 2736 -19603280.6462 +2827 2736 11944444.44837 +2828 2736 8005089.696258 +2829 2736 -71968136.03531 +2830 2736 4.157423973083e-06 +2831 2736 51943969.87703 +2832 2736 -29817851.87049 +2833 2736 -11944444.44837 +2834 2736 17900923.03284 +2844 2736 16294780.8482 +2845 2736 4.217028617859e-06 +2846 2736 439820.6128852 +2847 2736 88895212.80375 +2848 2736 4.112720489502e-06 +2849 2736 1759282.450699 +2850 2736 -25612922.63328 +2851 2736 -1.080334186554e-05 +2852 2736 439820.6129002 +2865 2736 -20039396.92541 +2866 2736 -11944444.44837 +2867 2736 -8444910.309145 +2868 2736 -74762019.75572 +2869 2736 2.533197402954e-07 +2870 2736 -53703252.3277 +2871 2736 -30778677.45218 +2872 2736 11944444.44836 +2873 2736 -18340743.64572 +2737 2737 687193460.8868 +2738 2737 -84443331.25708 +2739 2737 -1.019239425659e-05 +2740 2737 -88585023.89729 +2741 2737 42221665.62855 +2754 2737 -47777777.76993 +2755 2737 -57469927.96065 +2756 2737 9605416.412441 +2757 2737 3.069639205933e-06 +2758 2737 28369859.6463 +2759 2737 -21110832.82467 +2760 2737 47777777.76992 +2761 2737 -58519346.56511 +2762 2737 11505416.41223 +2826 2737 11944444.44837 +2827 2737 -16019732.12234 +2828 2737 -7635451.454545 +2829 2737 3.337860107422e-06 +2830 2737 -19412223.56332 +2831 2737 -5277708.208769 +2832 2737 -11944444.44837 +2833 2737 -26234303.34662 +2834 2737 12913159.66331 +2844 2737 5.125999450684e-06 +2845 2737 -29094034.58311 +2846 2737 -31702916.914 +2847 2737 4.351139068604e-06 +2848 2737 60226824.62697 +2849 2737 -21110832.82468 +2850 2737 -9.95397567749e-06 +2851 2737 -71001738.06458 +2852 2737 52813749.73867 +2865 2737 -11944444.44837 +2866 2737 -16455848.40155 +2867 2737 -8163229.232496 +2868 2737 -8.195638656616e-07 +2869 2737 -22206107.28377 +2870 2737 -5277708.20877 +2871 2737 11944444.44836 +2872 2737 -27195128.92833 +2873 2737 13440937.44126 +2738 2738 766546241.681 +2739 2738 1759282.450673 +2740 2738 42221665.62855 +2741 2738 57866058.65466 +2754 2738 18780080.99371 +2755 2738 9394305.301468 +2756 2738 -20006934.4106 +2757 2738 -3518564.899638 +2758 2738 -21110832.82467 +2759 2738 48052583.38233 +2760 2738 -20803252.33311 +2761 2738 11716527.5232 +2762 2738 -22805384.02253 +2826 2738 8005089.696258 +2827 2738 -7635451.454545 +2828 2738 -9407733.938713 +2829 2738 51680080.98832 +2830 2738 -5277708.208769 +2831 2738 -58666023.42418 +2832 2738 17900923.03284 +2833 2738 12913159.66331 +2834 2738 -36646590.5368 +2844 2738 439820.6128855 +2845 2738 -31491805.80303 +2846 2738 -4060894.923526 +2847 2738 1759282.450699 +2848 2738 -21110832.82468 +2849 2738 -105887547.9636 +2850 2738 439820.6129005 +2851 2738 52602638.6277 +2852 2738 -115814770.8741 +2865 2738 -8444910.309145 +2866 2738 -8163229.232496 +2867 2738 -10570710.68328 +2868 2738 -53439363.43899 +2869 2738 -5277708.20877 +2870 2738 -66116380.01208 +2871 2738 -18340743.64572 +2872 2738 13440937.44126 +2873 2738 -39208792.08802 +2739 2739 801867013.5374 +2740 2739 2.598762512207e-05 +2741 2739 7037129.799195 +2742 2739 92970237.73849 +2743 2739 -1.010298728943e-05 +2744 2739 1759282.450673 +2757 2739 -71804122.04904 +2758 2739 -47777777.76993 +2759 2739 19043969.88243 +2760 2739 -181853790.138 +2761 2739 3.248453140259e-06 +2762 2739 -3518564.899638 +2763 2739 -72853540.65349 +2764 2739 47777777.76992 +2765 2739 -20539363.4444 +2829 2739 -19603280.6462 +2830 2739 11944444.44837 +2831 2739 8005089.696258 +2832 2739 -71968136.03531 +2833 2739 4.157423973083e-06 +2834 2739 51943969.87703 +2835 2739 -29817851.87049 +2836 2739 -11944444.44837 +2837 2739 17900923.03284 +2847 2739 16294780.8482 +2848 2739 4.217028617859e-06 +2849 2739 439820.6128852 +2850 2739 88895212.80375 +2851 2739 4.112720489502e-06 +2852 2739 1759282.450699 +2853 2739 -25612922.63328 +2854 2739 -1.080334186554e-05 +2855 2739 439820.6129002 +2868 2739 -20039396.92541 +2869 2739 -11944444.44837 +2870 2739 -8444910.309145 +2871 2739 -74762019.75572 +2872 2739 2.533197402954e-07 +2873 2739 -53703252.3277 +2874 2739 -30778677.45218 +2875 2739 11944444.44836 +2876 2739 -18340743.64572 +2740 2740 687193460.8868 +2741 2740 -84443331.25708 +2742 2740 -1.019239425659e-05 +2743 2740 -88585023.89729 +2744 2740 42221665.62855 +2757 2740 -47777777.76993 +2758 2740 -57469927.96065 +2759 2740 9605416.412441 +2760 2740 3.069639205933e-06 +2761 2740 28369859.6463 +2762 2740 -21110832.82467 +2763 2740 47777777.76992 +2764 2740 -58519346.56511 +2765 2740 11505416.41223 +2829 2740 11944444.44837 +2830 2740 -16019732.12234 +2831 2740 -7635451.454545 +2832 2740 3.337860107422e-06 +2833 2740 -19412223.56332 +2834 2740 -5277708.208769 +2835 2740 -11944444.44837 +2836 2740 -26234303.34662 +2837 2740 12913159.66331 +2847 2740 5.125999450684e-06 +2848 2740 -29094034.58311 +2849 2740 -31702916.914 +2850 2740 4.351139068604e-06 +2851 2740 60226824.62697 +2852 2740 -21110832.82468 +2853 2740 -9.95397567749e-06 +2854 2740 -71001738.06458 +2855 2740 52813749.73867 +2868 2740 -11944444.44837 +2869 2740 -16455848.40155 +2870 2740 -8163229.232496 +2871 2740 -8.195638656616e-07 +2872 2740 -22206107.28377 +2873 2740 -5277708.20877 +2874 2740 11944444.44836 +2875 2740 -27195128.92833 +2876 2740 13440937.44126 +2741 2741 766546241.681 +2742 2741 1759282.450673 +2743 2741 42221665.62855 +2744 2741 57866058.65466 +2757 2741 18780080.99371 +2758 2741 9394305.301468 +2759 2741 -20006934.4106 +2760 2741 -3518564.899638 +2761 2741 -21110832.82467 +2762 2741 48052583.38233 +2763 2741 -20803252.33311 +2764 2741 11716527.5232 +2765 2741 -22805384.02253 +2829 2741 8005089.696258 +2830 2741 -7635451.454545 +2831 2741 -9407733.938713 +2832 2741 51680080.98832 +2833 2741 -5277708.208769 +2834 2741 -58666023.42418 +2835 2741 17900923.03284 +2836 2741 12913159.66331 +2837 2741 -36646590.5368 +2847 2741 439820.6128855 +2848 2741 -31491805.80303 +2849 2741 -4060894.923526 +2850 2741 1759282.450699 +2851 2741 -21110832.82468 +2852 2741 -105887547.9636 +2853 2741 439820.6129005 +2854 2741 52602638.6277 +2855 2741 -115814770.8741 +2868 2741 -8444910.309145 +2869 2741 -8163229.232496 +2870 2741 -10570710.68328 +2871 2741 -53439363.43899 +2872 2741 -5277708.20877 +2873 2741 -66116380.01208 +2874 2741 -18340743.64572 +2875 2741 13440937.44126 +2876 2741 -39208792.08802 +2742 2742 697335433.5606 +2743 2742 13555993.81372 +2744 2742 6525546.760922 +2745 2742 -74181346.4655 +2746 2742 -78873671.67505 +2747 2742 4567537.813263 +2760 2742 -71804122.04904 +2761 2742 -47777777.76993 +2762 2742 19043969.88243 +2763 2742 -131767559.6882 +2764 2742 24583510.6723 +2765 2742 -724035.0559039 +2766 2742 -42859393.5392 +2767 2742 32913264.44696 +2768 2742 -2392743.794803 +2832 2742 -19603280.6462 +2833 2742 11944444.44837 +2834 2742 8005089.696258 +2835 2742 -51389094.80041 +2836 2742 1955225.686484 +2837 2742 35595150.68861 +2850 2742 16294780.8482 +2851 2742 4.217028617859e-06 +2852 2742 439820.6128852 +2853 2742 89751427.48146 +2854 2742 3388998.455101 +2855 2742 1627256.23664 +2856 2742 -37804191.87041 +2857 2742 -19718417.92848 +2858 2742 14356015.6679 +2871 2742 -20039396.92541 +2872 2742 -11944444.44837 +2873 2742 -8444910.309145 +2874 2742 -60532186.86274 +2875 2742 6145877.671103 +2876 2742 -45375800.4239 +2877 2742 -19078219.62127 +2878 2742 8228316.115794 +2879 2742 -6175963.728574 +2743 2743 738376280.1071 +2744 2743 -53461134.90695 +2745 2743 -78912088.19445 +2746 2743 -255911826.3266 +2747 2743 9575542.669736 +2760 2743 -47777777.76993 +2761 2743 -57469927.96065 +2762 2743 9605416.412441 +2763 2743 24583510.6723 +2764 2743 39087496.12151 +2765 2743 -11304599.7208 +2766 2743 32913264.44696 +2767 2743 -119862720.1338 +2768 2743 5385216.157707 +2832 2743 11944444.44837 +2833 2743 -16019732.12234 +2834 2743 -7635451.454545 +2835 2743 1964829.816337 +2836 2743 -1457900.386174 +2837 2743 -5080618.041869 +2850 2743 5.125999450684e-06 +2851 2743 -29094034.58311 +2852 2743 -31702916.914 +2853 2743 3388998.455098 +2854 2743 100011639.1232 +2855 2743 -13368588.23948 +2856 2743 -19728022.05833 +2857 2743 -83236811.85808 +2858 2743 44683227.92718 +2871 2743 -11944444.44837 +2872 2743 -16455848.40155 +2873 2743 -8163229.232496 +2874 2743 6145877.671102 +2875 2743 -17818422.88929 +2876 2743 3275933.400212 +2877 2743 8228316.115794 +2878 2743 -38329051.2794 +2879 2743 18012970.71223 +2744 2744 653768770.9707 +2745 2744 4834182.270174 +2746 2744 10420950.39671 +2747 2744 -44643768.23168 +2760 2744 18780080.99371 +2761 2744 9394305.301468 +2762 2744 -20006934.4106 +2763 2744 -7321257.277044 +2764 2744 -11515710.83187 +2765 2744 53866482.54874 +2766 2744 -2920521.572234 +2767 2744 5385216.157707 +2768 2744 -25206299.26693 +2832 2744 8005089.696258 +2833 2744 -7635451.454545 +2834 2744 -9407733.938713 +2835 2744 36913961.41127 +2836 2744 -5283969.107957 +2837 2744 -35687511.70929 +2850 2744 439820.6128855 +2851 2744 -31491805.80303 +2852 2744 -4060894.923526 +2853 2744 1636068.847779 +2854 2744 -13361537.70386 +2855 2744 -62110956.49564 +2856 2744 14361165.99813 +2857 2744 44679081.42414 +2858 2744 -62517889.38316 +2871 2744 -8444910.309145 +2872 2744 -8163229.232496 +2873 2744 -10570710.68328 +2874 2744 -46695244.86759 +2875 2744 3275933.401367 +2876 2744 -60107504.48815 +2877 2744 -6175963.728574 +2878 2744 18012970.71223 +2879 2744 -28603898.10301 +2745 2745 489618492.9753 +2746 2745 15356371.09326 +2747 2745 -2554275.615559 +2763 2745 -75484143.26592 +2764 2745 -45746472.96609 +2765 2745 2836938.039019 +2766 2745 -36927445.63632 +2767 2745 34495259.45832 +2768 2745 -1076002.638337 +2769 2745 61858293.65847 +2770 2745 -22880131.39438 +2771 2745 113380.0795472 +2772 2745 -20251607.2672 +2773 2745 40238479.12124 +2774 2745 -451510.9862942 +2835 2745 -17479931.67357 +2836 2745 14362145.7276 +2837 2745 5833486.609719 +2853 2745 -31941173.76503 +2854 2745 -19728022.05833 +2855 2745 -12009716.04913 +2856 2745 24089286.29196 +2857 2745 3839092.775206 +2858 2745 10350875.53811 +2874 2745 -25149760.01167 +2875 2745 -11436618.24716 +2876 2745 -12495973.82755 +2877 2745 -53221395.58403 +2878 2745 8623814.868827 +2879 2745 -52049556.20671 +2880 2745 -15616531.23755 +2881 2745 -5720032.851413 +2882 2745 11718275.57488 +2883 2745 -19138192.52839 +2884 2745 10059619.78527 +2885 2745 -12797947.19522 +2746 2746 684488409.1365 +2747 2746 -18295681.76298 +2763 2746 -45746472.96609 +2764 2746 -41552329.55583 +2765 2746 331278.0576664 +2766 2746 34495259.45832 +2767 2746 136816456.2173 +2768 2746 -3434058.65236 +2769 2746 -3769020.286411 +2770 2746 -30851528.21609 +2771 2746 417819.3012418 +2772 2746 40238479.12124 +2773 2746 -41200663.37894 +2774 2746 488013.3309756 +2835 2746 9574763.8184 +2836 2746 -44269000.15613 +2837 2746 -13244377.7058 +2853 2746 -19718417.92848 +2854 2746 -77373793.75269 +2855 2746 -39681478.38126 +2856 2746 3839092.775206 +2857 2746 72806765.35626 +2858 2746 -2276323.108396 +2874 2746 -11436618.24716 +2875 2746 -16666806.57997 +2876 2746 -10481763.82233 +2877 2746 8623814.868826 +2878 2746 -9785420.099232 +2879 2746 5243568.66829 +2880 2746 -942255.0720671 +2881 2746 -38793986.71761 +2882 2746 33437788.15322 +2883 2746 10059619.78527 +2884 2746 -24375456.5589 +2885 2746 16788670.00494 +2747 2747 600039923.4573 +2763 2747 2573049.150303 +2764 2747 120166.946694 +2765 2747 -12151033.88324 +2766 2747 -2131558.193719 +2767 2747 -3645169.763436 +2768 2747 150791187.3325 +2769 2747 -150508.8092947 +2770 2747 417819.3012417 +2771 2747 95574403.5202 +2772 2747 -715399.8750098 +2773 2747 488013.3309756 +2774 2747 22252331.25781 +2835 2747 3888991.073146 +2836 2747 -14800902.31119 +2837 2747 -19824082.64697 +2853 2747 -12006053.84798 +2854 2747 -39687207.82015 +2855 2747 -46883174.43545 +2856 2747 -10308568.90294 +2857 2747 -5821027.16094 +2858 2747 -112164251.0942 +2874 2747 -12495973.82755 +2875 2747 -10481763.82233 +2876 2747 -19781022.96801 +2877 2747 -52049556.20697 +2878 2747 5243568.669446 +2879 2747 -79607627.60272 +2880 2747 3593275.573656 +2881 2747 33437788.15322 +2882 2747 -58989344.86761 +2883 2747 -12797947.19522 +2884 2747 16788670.00494 +2885 2747 -31971025.74039 +2748 2748 400933506.7687 +2749 2748 1.347064971924e-05 +2750 2748 3518564.899597 +2751 2748 46502609.17931 +2752 2748 9555555.553979 +2753 2748 -2418969.885557 +2838 2748 -71968136.03531 +2839 2748 4.157423973083e-06 +2840 2748 51943969.87703 +2841 2748 -29817851.87049 +2842 2748 -11944444.44837 +2843 2748 17900923.03284 +2859 2748 44430116.09181 +2860 2748 1.907348632813e-06 +2861 2748 -10318414.32804 +2862 2748 -12806461.31664 +2863 2748 2388888.889668 +2864 2748 -3404256.361406 +2749 2749 343596730.4434 +2750 2749 -42221665.62853 +2751 2749 -9555555.55399 +2752 2749 -44275021.63857 +2753 2749 20899721.7032 +2838 2749 3.337860107422e-06 +2839 2749 -19412223.56332 +2840 2749 -5277708.208769 +2841 2749 -11944444.44837 +2842 2749 -26234303.34662 +2843 2749 12913159.66331 +2859 2749 2.861022949219e-06 +2860 2749 30095922.00342 +2861 2749 -10555416.41234 +2862 2749 -2388888.889678 +2863 2749 -35500869.03229 +2864 2749 26354097.09154 +2750 2750 383273120.8405 +2751 2750 5497696.779808 +2752 2750 21321943.92535 +2753 2750 28979670.15418 +2838 2750 51680080.98832 +2839 2750 -5277708.208769 +2840 2750 -58666023.42418 +2841 2750 17900923.03284 +2842 2750 12913159.66331 +2843 2750 -36646590.5368 +2859 2750 10758252.33516 +2860 2750 -10555416.41234 +2861 2750 -52990414.80866 +2862 2750 3844076.974307 +2863 2750 26354097.09164 +2864 2750 -57907385.43707 +2751 2751 400933506.7687 +2752 2751 1.347064971924e-05 +2753 2751 3518564.899597 +2754 2751 46502609.17931 +2755 2751 9555555.553979 +2756 2751 -2418969.885557 +2838 2751 -19603280.6462 +2839 2751 11944444.44837 +2840 2751 8005089.696258 +2841 2751 -71968136.03531 +2842 2751 4.157423973083e-06 +2843 2751 51943969.87703 +2844 2751 -29817851.87049 +2845 2751 -11944444.44837 +2846 2751 17900923.03284 +2859 2751 8147390.424101 +2860 2751 -2388888.889671 +2861 2751 -1425089.694098 +2862 2751 44430116.09181 +2863 2751 1.907348632813e-06 +2864 2751 -10318414.32804 +2865 2751 -12806461.31664 +2866 2751 2388888.889668 +2867 2751 -3404256.361406 +2752 2752 343596730.4434 +2753 2752 -42221665.62853 +2754 2752 -9555555.55399 +2755 2752 -44275021.63857 +2756 2752 20899721.7032 +2838 2752 11944444.44837 +2839 2752 -16019732.12234 +2840 2752 -7635451.454545 +2841 2752 3.337860107422e-06 +2842 2752 -19412223.56332 +2843 2752 -5277708.208769 +2844 2752 -11944444.44837 +2845 2752 -26234303.34662 +2846 2752 12913159.66331 +2859 2752 2388888.889676 +2860 2752 -14547017.29156 +2861 2752 -15798680.67921 +2862 2752 2.861022949219e-06 +2863 2752 30095922.00342 +2864 2752 -10555416.41234 +2865 2752 -2388888.889678 +2866 2752 -35500869.03229 +2867 2752 26354097.09154 +2753 2753 383273120.8405 +2754 2753 5497696.779808 +2755 2753 21321943.92535 +2756 2753 28979670.15418 +2838 2753 8005089.696258 +2839 2753 -7635451.454545 +2840 2753 -9407733.938713 +2841 2753 51680080.98832 +2842 2753 -5277708.208769 +2843 2753 -58666023.42418 +2844 2753 17900923.03284 +2845 2753 12913159.66331 +2846 2753 -36646590.5368 +2859 2753 1864910.306983 +2860 2753 -15798680.67931 +2861 2753 -2030447.461764 +2862 2753 10758252.33516 +2863 2753 -10555416.41234 +2864 2753 -52990414.80866 +2865 2753 3844076.974307 +2866 2753 26354097.09164 +2867 2753 -57907385.43707 +2754 2754 400933506.7687 +2755 2754 1.347064971924e-05 +2756 2754 3518564.899597 +2757 2754 46502609.17931 +2758 2754 9555555.553979 +2759 2754 -2418969.885557 +2841 2754 -19603280.6462 +2842 2754 11944444.44837 +2843 2754 8005089.696258 +2844 2754 -71968136.03531 +2845 2754 4.157423973083e-06 +2846 2754 51943969.87703 +2847 2754 -29817851.87049 +2848 2754 -11944444.44837 +2849 2754 17900923.03284 +2862 2754 8147390.424101 +2863 2754 -2388888.889671 +2864 2754 -1425089.694098 +2865 2754 44430116.09181 +2866 2754 1.907348632813e-06 +2867 2754 -10318414.32804 +2868 2754 -12806461.31664 +2869 2754 2388888.889668 +2870 2754 -3404256.361406 +2755 2755 343596730.4434 +2756 2755 -42221665.62853 +2757 2755 -9555555.55399 +2758 2755 -44275021.63857 +2759 2755 20899721.7032 +2841 2755 11944444.44837 +2842 2755 -16019732.12234 +2843 2755 -7635451.454545 +2844 2755 3.337860107422e-06 +2845 2755 -19412223.56332 +2846 2755 -5277708.208769 +2847 2755 -11944444.44837 +2848 2755 -26234303.34662 +2849 2755 12913159.66331 +2862 2755 2388888.889676 +2863 2755 -14547017.29156 +2864 2755 -15798680.67921 +2865 2755 2.861022949219e-06 +2866 2755 30095922.00342 +2867 2755 -10555416.41234 +2868 2755 -2388888.889678 +2869 2755 -35500869.03229 +2870 2755 26354097.09154 +2756 2756 383273120.8405 +2757 2756 5497696.779808 +2758 2756 21321943.92535 +2759 2756 28979670.15418 +2841 2756 8005089.696258 +2842 2756 -7635451.454545 +2843 2756 -9407733.938713 +2844 2756 51680080.98832 +2845 2756 -5277708.208769 +2846 2756 -58666023.42418 +2847 2756 17900923.03284 +2848 2756 12913159.66331 +2849 2756 -36646590.5368 +2862 2756 1864910.306983 +2863 2756 -15798680.67931 +2864 2756 -2030447.461764 +2865 2756 10758252.33516 +2866 2756 -10555416.41234 +2867 2756 -52990414.80866 +2868 2756 3844076.974307 +2869 2756 26354097.09164 +2870 2756 -57907385.43707 +2757 2757 400933506.7687 +2758 2757 1.347064971924e-05 +2759 2757 3518564.899597 +2760 2757 46502609.17931 +2761 2757 9555555.553979 +2762 2757 -2418969.885557 +2844 2757 -19603280.6462 +2845 2757 11944444.44837 +2846 2757 8005089.696258 +2847 2757 -71968136.03531 +2848 2757 4.157423973083e-06 +2849 2757 51943969.87703 +2850 2757 -29817851.87049 +2851 2757 -11944444.44837 +2852 2757 17900923.03284 +2865 2757 8147390.424101 +2866 2757 -2388888.889671 +2867 2757 -1425089.694098 +2868 2757 44430116.09181 +2869 2757 1.907348632813e-06 +2870 2757 -10318414.32804 +2871 2757 -12806461.31664 +2872 2757 2388888.889668 +2873 2757 -3404256.361406 +2758 2758 343596730.4434 +2759 2758 -42221665.62853 +2760 2758 -9555555.55399 +2761 2758 -44275021.63857 +2762 2758 20899721.7032 +2844 2758 11944444.44837 +2845 2758 -16019732.12234 +2846 2758 -7635451.454545 +2847 2758 3.337860107422e-06 +2848 2758 -19412223.56332 +2849 2758 -5277708.208769 +2850 2758 -11944444.44837 +2851 2758 -26234303.34662 +2852 2758 12913159.66331 +2865 2758 2388888.889676 +2866 2758 -14547017.29156 +2867 2758 -15798680.67921 +2868 2758 2.861022949219e-06 +2869 2758 30095922.00342 +2870 2758 -10555416.41234 +2871 2758 -2388888.889678 +2872 2758 -35500869.03229 +2873 2758 26354097.09154 +2759 2759 383273120.8405 +2760 2759 5497696.779808 +2761 2759 21321943.92535 +2762 2759 28979670.15418 +2844 2759 8005089.696258 +2845 2759 -7635451.454545 +2846 2759 -9407733.938713 +2847 2759 51680080.98832 +2848 2759 -5277708.208769 +2849 2759 -58666023.42418 +2850 2759 17900923.03284 +2851 2759 12913159.66331 +2852 2759 -36646590.5368 +2865 2759 1864910.306983 +2866 2759 -15798680.67931 +2867 2759 -2030447.461764 +2868 2759 10758252.33516 +2869 2759 -10555416.41234 +2870 2759 -52990414.80866 +2871 2759 3844076.974307 +2872 2759 26354097.09164 +2873 2759 -57907385.43707 +2760 2760 400933506.7687 +2761 2760 1.347064971924e-05 +2762 2760 3518564.899597 +2763 2760 46502609.17931 +2764 2760 9555555.553979 +2765 2760 -2418969.885557 +2847 2760 -19603280.6462 +2848 2760 11944444.44837 +2849 2760 8005089.696258 +2850 2760 -71968136.03531 +2851 2760 4.157423973083e-06 +2852 2760 51943969.87703 +2853 2760 -29817851.87049 +2854 2760 -11944444.44837 +2855 2760 17900923.03284 +2868 2760 8147390.424101 +2869 2760 -2388888.889671 +2870 2760 -1425089.694098 +2871 2760 44430116.09181 +2872 2760 1.907348632813e-06 +2873 2760 -10318414.32804 +2874 2760 -12806461.31664 +2875 2760 2388888.889668 +2876 2760 -3404256.361406 +2761 2761 343596730.4434 +2762 2761 -42221665.62853 +2763 2761 -9555555.55399 +2764 2761 -44275021.63857 +2765 2761 20899721.7032 +2847 2761 11944444.44837 +2848 2761 -16019732.12234 +2849 2761 -7635451.454545 +2850 2761 3.337860107422e-06 +2851 2761 -19412223.56332 +2852 2761 -5277708.208769 +2853 2761 -11944444.44837 +2854 2761 -26234303.34662 +2855 2761 12913159.66331 +2868 2761 2388888.889676 +2869 2761 -14547017.29156 +2870 2761 -15798680.67921 +2871 2761 2.861022949219e-06 +2872 2761 30095922.00342 +2873 2761 -10555416.41234 +2874 2761 -2388888.889678 +2875 2761 -35500869.03229 +2876 2761 26354097.09154 +2762 2762 383273120.8405 +2763 2762 5497696.779808 +2764 2762 21321943.92535 +2765 2762 28979670.15418 +2847 2762 8005089.696258 +2848 2762 -7635451.454545 +2849 2762 -9407733.938713 +2850 2762 51680080.98832 +2851 2762 -5277708.208769 +2852 2762 -58666023.42418 +2853 2762 17900923.03284 +2854 2762 12913159.66331 +2855 2762 -36646590.5368 +2868 2762 1864910.306983 +2869 2762 -15798680.67931 +2870 2762 -2030447.461764 +2871 2762 10758252.33516 +2872 2762 -10555416.41234 +2873 2762 -52990414.80866 +2874 2762 3844076.974307 +2875 2762 26354097.09164 +2876 2762 -57907385.43707 +2763 2763 390528978.5414 +2764 2763 2031754.88496 +2765 2763 18978084.67473 +2766 2763 10706126.81689 +2767 2763 -19091014.80711 +2768 2763 2131234.560147 +2850 2763 -19603280.6462 +2851 2763 11944444.44837 +2852 2763 8005089.696258 +2853 2763 -57207507.5192 +2854 2763 6145877.671107 +2855 2763 43364477.33833 +2856 2763 -26546695.73564 +2857 2763 -11436618.24716 +2858 2763 13848470.62555 +2871 2763 8147390.424101 +2872 2763 -2388888.889671 +2873 2763 -1425089.694098 +2874 2763 41725581.05413 +2875 2763 507938.7214912 +2876 2763 -6453256.604583 +2877 2763 -15664036.02673 +2878 2763 -4772753.704127 +2879 2763 5360864.194452 +2764 2764 352799816.1126 +2765 2764 -26163100.1551 +2766 2764 -38202125.91508 +2767 2764 -79908143.54456 +2768 2764 4520172.591737 +2850 2764 11944444.44837 +2851 2764 -16019732.12234 +2852 2764 -7635451.454545 +2853 2764 6145877.671106 +2854 2764 -14493743.54572 +2855 2764 -8981011.042271 +2856 2764 -11436618.24716 +2857 2764 -18063742.30393 +2858 2764 10594625.07348 +2871 2764 2388888.889676 +2872 2764 -14547017.29156 +2873 2764 -15798680.67921 +2874 2764 507938.7214905 +2875 2764 32293290.44228 +2876 2764 -6540775.042003 +2877 2764 -9550531.483474 +2878 2764 -38317603.62825 +2879 2764 28361293.14454 +2765 2765 373214203.523 +2766 2765 3450679.004372 +2767 2765 4731283.702813 +2768 2765 25915984.15995 +2850 2765 8005089.696258 +2851 2765 -7635451.454545 +2852 2765 -9407733.938713 +2853 2765 44683921.78504 +2854 2765 -8981011.041011 +2855 2765 -51241692.90527 +2856 2765 13848470.62555 +2857 2765 10594625.07348 +2858 2765 -23506184.8986 +2871 2765 1864910.306983 +2872 2765 -15798680.67931 +2873 2765 -2030447.461764 +2874 2765 14622854.50307 +2875 2765 -6540775.042003 +2876 2765 -55780885.41815 +2877 2765 11025586.41696 +2878 2765 28361293.14339 +2879 2765 -42429184.57622 +2766 2766 393308552.7541 +2767 2766 33387741.61392 +2768 2766 1069557.995636 +2769 2766 -90523162.8112 +2770 2766 -55317076.41861 +2771 2766 735989.013558 +2772 2766 18987277.35532 +2773 2766 -7277063.18551 +2774 2766 851409.3072543 +2853 2766 -16305861.25464 +2854 2766 8228316.115794 +2855 2766 4847647.38616 +2856 2766 -52398287.78342 +2857 2766 8623814.868829 +2858 2766 51247665.9983 +2874 2766 -10942417.8914 +2875 2766 -9550531.483475 +2876 2766 -9564135.802965 +2877 2766 13533800.67906 +2878 2766 8346935.407593 +2879 2766 -10722054.94328 +2880 2766 -36706081.42304 +2881 2766 -13829269.11147 +2882 2766 20496497.26015 +2883 2766 -20473238.80768 +2884 2766 -1819265.797273 +2885 2766 5144935.657537 +2767 2767 456455484.3111 +2768 2767 -8493577.449744 +2769 2767 -55317076.41861 +2770 2767 -67552496.70794 +2771 2767 488013.3309754 +2772 2767 -26388174.29348 +2773 2767 -73256625.20248 +2774 2767 1534234.021698 +2853 2767 8228316.115794 +2854 2767 -35556692.91277 +2855 2767 -15320362.63205 +2856 2767 8623814.868829 +2857 2767 -8962312.29862 +2858 2767 -7013375.774193 +2874 2767 -4772753.704129 +2875 2767 -33595985.49293 +2876 2767 -26048429.06869 +2877 2767 8346935.407594 +2878 2767 29320533.57608 +2879 2767 -2123394.363487 +2880 2767 -13829269.11147 +2881 2767 -30963414.8944 +2882 2767 16788670.00494 +2883 2767 -6597043.576619 +2884 2767 -43534214.45849 +2885 2767 33716891.83347 +2768 2768 472314421.5349 +2769 2768 735989.0135581 +2770 2768 488013.3309754 +2771 2768 -4099502.071191 +2772 2768 1115298.196096 +2773 2768 1534234.021698 +2774 2768 54129421.48319 +2853 2768 4847647.38616 +2854 2768 -15320362.63205 +2855 2768 -21210942.45867 +2856 2768 51247665.99856 +2857 2768 -7013375.772933 +2858 2768 -77412673.46776 +2874 2768 -4691080.247253 +2875 2768 -26048429.06995 +2876 2768 -29838202.88199 +2877 2768 9937389.497775 +2878 2768 -2123394.363487 +2879 2768 -108036961.3792 +2880 2768 20496497.26015 +2881 2768 16788670.00494 +2882 2768 -38558984.07588 +2883 2768 10337713.43846 +2884 2768 33716891.83347 +2885 2768 -53721133.01946 +2769 2769 247694807.0596 +2770 2769 61102353.61032 +2771 2769 -421250.4501109 +2772 2769 -40613658.84548 +2773 2769 -2016256.905298 +2774 2769 -164229.7541515 +2856 2769 -15064205.65599 +2857 2769 -942255.0720674 +2858 2769 -3602557.756001 +2877 2769 -36153755.84147 +2878 2769 -13829269.11147 +2879 2769 -20128502.75319 +2880 2769 313818.0877385 +2881 2769 15275588.41011 +2882 2769 8019687.386086 +2883 2769 -37751670.53939 +2884 2769 -504064.2265737 +2885 2769 -33038626.87689 +2770 2770 223946295.6199 +2771 2770 -417819.3012383 +2772 2770 17094854.20267 +2773 2770 52874008.36546 +2774 2770 -488013.3309731 +2856 2770 -5720032.851414 +2857 2770 -38241661.13605 +2858 2770 -33228878.5025 +2877 2770 -13829269.11147 +2878 2770 -30411089.31283 +2879 2770 -16544663.33934 +2880 2770 15275588.41011 +2881 2770 -5623309.775096 +2882 2770 6562211.840209 +2883 2770 4273713.552772 +2884 2770 -14379753.72514 +2885 2770 3211330.001623 +2771 2771 302886642.9092 +2772 2771 -428118.6429929 +2773 2771 -488013.3309731 +2774 2771 81415199.80545 +2856 2771 -11727557.7571 +2857 2771 -33228878.5025 +2858 2771 -57516476.65011 +2877 2771 -20128502.75319 +2878 2771 -16544663.33934 +2879 2771 -37086115.85837 +2880 2771 -8230312.611246 +2881 2771 -6771121.490934 +2882 2771 -88571362.45583 +2883 2771 -33038626.87847 +2884 2771 -3455336.667233 +2885 2771 -53241548.9 +2772 2772 194640779.4635 +2773 2772 -30945159.03043 +2774 2772 555998.0993371 +2856 2772 -18585866.94682 +2857 2772 10059619.78527 +2858 2772 12506219.47975 +2877 2772 -18816262.06405 +2878 2772 -6597043.57662 +2879 2772 -10043953.22886 +2880 2772 -37751670.53939 +2881 2772 4273713.552774 +2882 2772 32890539.77888 +2883 2772 -122944.6401992 +2884 2772 -7736289.761419 +2885 2772 -5251694.918494 +2773 2773 214346070.9221 +2774 2773 -1534234.021693 +2856 2773 10059619.78527 +2857 2773 -23823130.97733 +2858 2773 -16544663.33934 +2877 2773 -1819265.797274 +2878 2773 -41877237.71487 +2879 2773 -32949774.82225 +2880 2773 -504064.2265722 +2881 2773 -14379753.72514 +2882 2773 3211330.001623 +2883 2773 -7736289.761419 +2884 2773 4803378.226877 +2885 2773 6283108.159956 +2774 2774 249570489.3365 +2856 2774 12506219.47975 +2857 2774 -16544663.33934 +2858 2774 -30498157.52287 +2877 2774 -5115064.336773 +2878 2774 -32949774.82225 +2879 2774 -49302528.36979 +2880 2774 32890539.77744 +2881 2774 -3455336.667232 +2882 2774 -53241548.9 +2883 2774 4869971.746511 +2884 2774 -7050225.171186 +2885 2774 -67695749.71523 +2775 2775 508612796.7711 +2776 2775 47777777.76993 +2777 2775 20248388.26907 +2778 2775 -267652150.2947 +2779 2775 -47793765.64302 +2780 2775 -20241471.08164 +2781 2775 6087083.420696 +2782 2775 38238210.08904 +2783 2775 -16367807.61161 +2886 2775 57272319.20769 +2887 2775 11944444.44837 +2888 2775 16262217.83282 +2889 2775 -96920154.16551 +2890 2775 -11948441.41665 +2891 2775 -57894966.96635 +2892 2775 -19430363.65776 +2893 2775 9559552.526969 +2894 2775 -14502802.0572 +2776 2776 436923838.9196 +2777 2776 -52790465.59624 +2778 2776 -47801759.57957 +2779 2776 -43044343.65972 +2780 2776 -29246608.86722 +2781 2776 57357315.13355 +2782 2776 6087083.420705 +2783 2776 18374525.78853 +2886 2776 11944444.44837 +2887 2776 39350079.73598 +2888 2776 -4237631.002181 +2889 2776 -11950439.90079 +2890 2776 -40768202.4791 +2891 2776 -17881456.80322 +2892 2776 14339328.79045 +2893 2776 -19430363.65775 +2894 2776 17403019.36621 +2777 2777 498731997.6738 +2778 2777 -20238012.48793 +2779 2777 -23543989.15986 +2780 2777 -9089122.520285 +2781 2777 -24551711.41742 +2782 2777 12249683.85902 +2783 2777 16232222.45521 +2886 2777 -4818855.100867 +2887 2777 -21102266.9381 +2888 2777 -61666013.98076 +2889 2777 -57630268.59944 +2890 2777 -16401283.68257 +2891 2777 -82291258.12151 +2892 2777 -21754203.08579 +2893 2777 11602012.9108 +2894 2777 -51814303.08735 +2778 2778 866925828.5346 +2779 2778 47817747.45269 +2780 2778 23749660.20008 +2781 2778 14263474.74723 +2782 2778 -47793765.64302 +2783 2778 20546059.94785 +2784 2778 -181853790.138 +2785 2778 3.248453140259e-06 +2786 2778 -3518564.899638 +2787 2778 -72853540.65349 +2788 2778 47777777.76992 +2789 2778 -20539363.4444 +2886 2778 -85740387.93072 +2887 2778 -11950439.90077 +2888 2778 47775096.06898 +2889 2778 112006329.4708 +2890 2778 11954436.86906 +2891 2778 5935349.843305 +2892 2778 -36979414.9719 +2893 2778 -11948441.41664 +2894 2778 18346879.03149 +2895 2778 -74762019.75572 +2896 2778 2.533197402954e-07 +2897 2778 -53703252.3277 +2898 2778 -30778677.45218 +2899 2778 11944444.44836 +2900 2778 -18340743.64572 +2779 2779 737900094.3577 +2780 2779 -65443918.48946 +2781 2779 -47801759.57957 +2782 2779 -152989568.1247 +2783 2779 35049537.95506 +2784 2779 3.069639205933e-06 +2785 2779 28369859.6463 +2786 2779 -21110832.82467 +2787 2779 47777777.76992 +2788 2779 -58519346.56511 +2789 2779 11505416.41223 +2886 2779 -11948441.41664 +2887 2779 -29588436.2443 +2888 2779 4682155.144749 +2889 2779 11954436.86906 +2890 2779 79749895.91067 +2891 2779 -16362631.77783 +2892 2779 -11950439.90078 +2893 2779 -78792675.71048 +2894 2779 51029508.03613 +2895 2779 -8.195638656616e-07 +2896 2779 -22206107.28377 +2897 2779 -5277708.20877 +2898 2779 11944444.44836 +2899 2779 -27195128.92833 +2900 2779 13440937.44126 +2780 2780 768350518.5004 +2781 2780 20813297.08829 +2782 2780 40963180.50213 +2783 2780 19484057.05595 +2784 2780 -3518564.899638 +2785 2780 -21110832.82467 +2786 2780 48052583.38233 +2787 2780 -20803252.33311 +2788 2780 11716527.5232 +2789 2780 -22805384.02253 +2886 2780 47510397.70207 +2887 2780 3205506.989851 +2888 2780 -52478548.16204 +2889 2780 5939756.113784 +2890 2780 -16359106.80793 +2891 2780 -87179377.66603 +2892 2780 18349946.72438 +2893 2780 52296851.6274 +2894 2780 -103249742.1615 +2895 2780 -53439363.43899 +2896 2780 -5277708.20877 +2897 2780 -66116380.01208 +2898 2780 -18340743.64572 +2899 2780 13440937.44126 +2900 2780 -39208792.08802 +2781 2781 508612796.7711 +2782 2781 47777777.76993 +2783 2781 20248388.26907 +2784 2781 -71804122.04904 +2785 2781 -47777777.76993 +2786 2781 19043969.88243 +2787 2781 -267652150.2947 +2788 2781 -47793765.64302 +2789 2781 -20241471.08164 +2790 2781 6087083.420696 +2791 2781 38238210.08904 +2792 2781 -16367807.61161 +2886 2781 1532382.642161 +2887 2781 14339328.79045 +2888 2781 9874015.186731 +2889 2781 -4845636.536104 +2890 2781 -11950439.90078 +2891 2781 -8009104.879749 +2892 2781 57272319.20769 +2893 2781 11944444.44837 +2894 2781 16262217.83282 +2895 2781 -20039396.92541 +2896 2781 -11944444.44837 +2897 2781 -8444910.309145 +2898 2781 -96920154.16551 +2899 2781 -11948441.41665 +2900 2781 -57894966.96635 +2901 2781 -19430363.65776 +2902 2781 9559552.526969 +2903 2781 -14502802.0572 +2782 2782 436923838.9196 +2783 2782 -52790465.59624 +2784 2782 -47777777.76993 +2785 2782 -57469927.96065 +2786 2782 9605416.412441 +2787 2782 -47801759.57957 +2788 2782 -43044343.65972 +2789 2782 -29246608.86722 +2790 2782 57357315.13355 +2791 2782 6087083.420705 +2792 2782 18374525.78853 +2886 2782 9559552.526969 +2887 2782 1532382.642157 +2888 2782 -5266148.137347 +2889 2782 -11948441.41664 +2890 2782 -46658897.27468 +2891 2782 -32026328.33686 +2892 2782 11944444.44837 +2893 2782 39350079.73598 +2894 2782 -4237631.002181 +2895 2782 -11944444.44837 +2896 2782 -16455848.40155 +2897 2782 -8163229.232496 +2898 2782 -11950439.90079 +2899 2782 -40768202.4791 +2900 2782 -17881456.80322 +2901 2782 14339328.79045 +2902 2782 -19430363.65775 +2903 2782 17403019.36621 +2783 2783 498731997.6738 +2784 2783 18780080.99371 +2785 2783 9394305.301468 +2786 2783 -20006934.4106 +2787 2783 -20238012.48793 +2788 2783 -23543989.15986 +2789 2783 -9089122.520285 +2790 2783 -24551711.41742 +2791 2783 12249683.85902 +2792 2783 16232222.45521 +2886 2783 6582676.791154 +2887 2783 -7899222.206021 +2888 2783 4086353.712421 +2889 2783 -8007766.485252 +2890 2783 -33293672.07046 +2891 2783 -17559666.33271 +2892 2783 -4818855.100867 +2893 2783 -21102266.9381 +2894 2783 -61666013.98076 +2895 2783 -8444910.309145 +2896 2783 -8163229.232496 +2897 2783 -10570710.68328 +2898 2783 -57630268.59944 +2899 2783 -16401283.68257 +2900 2783 -82291258.12151 +2901 2783 -21754203.08579 +2902 2783 11602012.9108 +2903 2783 -51814303.08735 +2784 2784 801867013.5374 +2785 2784 2.598762512207e-05 +2786 2784 7037129.799195 +2787 2784 92970237.73849 +2788 2784 -1.010298728943e-05 +2789 2784 1759282.450673 +2793 2784 -181853790.138 +2794 2784 3.248453140259e-06 +2795 2784 -3518564.899638 +2796 2784 -72853540.65349 +2797 2784 47777777.76992 +2798 2784 -20539363.4444 +2889 2784 -71968136.03531 +2890 2784 4.157423973083e-06 +2891 2784 51943969.87703 +2892 2784 -29817851.87049 +2893 2784 -11944444.44837 +2894 2784 17900923.03284 +2895 2784 88895212.80375 +2896 2784 4.112720489502e-06 +2897 2784 1759282.450699 +2898 2784 -25612922.63328 +2899 2784 -1.080334186554e-05 +2900 2784 439820.6129002 +2904 2784 -74762019.75572 +2905 2784 2.533197402954e-07 +2906 2784 -53703252.3277 +2907 2784 -30778677.45218 +2908 2784 11944444.44836 +2909 2784 -18340743.64572 +2785 2785 687193460.8868 +2786 2785 -84443331.25708 +2787 2785 -1.019239425659e-05 +2788 2785 -88585023.89729 +2789 2785 42221665.62855 +2793 2785 3.069639205933e-06 +2794 2785 28369859.6463 +2795 2785 -21110832.82467 +2796 2785 47777777.76992 +2797 2785 -58519346.56511 +2798 2785 11505416.41223 +2889 2785 3.337860107422e-06 +2890 2785 -19412223.56332 +2891 2785 -5277708.208769 +2892 2785 -11944444.44837 +2893 2785 -26234303.34662 +2894 2785 12913159.66331 +2895 2785 4.351139068604e-06 +2896 2785 60226824.62697 +2897 2785 -21110832.82468 +2898 2785 -9.95397567749e-06 +2899 2785 -71001738.06458 +2900 2785 52813749.73867 +2904 2785 -8.195638656616e-07 +2905 2785 -22206107.28377 +2906 2785 -5277708.20877 +2907 2785 11944444.44836 +2908 2785 -27195128.92833 +2909 2785 13440937.44126 +2786 2786 766546241.681 +2787 2786 1759282.450673 +2788 2786 42221665.62855 +2789 2786 57866058.65466 +2793 2786 -3518564.899638 +2794 2786 -21110832.82467 +2795 2786 48052583.38233 +2796 2786 -20803252.33311 +2797 2786 11716527.5232 +2798 2786 -22805384.02253 +2889 2786 51680080.98832 +2890 2786 -5277708.208769 +2891 2786 -58666023.42418 +2892 2786 17900923.03284 +2893 2786 12913159.66331 +2894 2786 -36646590.5368 +2895 2786 1759282.450699 +2896 2786 -21110832.82468 +2897 2786 -105887547.9636 +2898 2786 439820.6129005 +2899 2786 52602638.6277 +2900 2786 -115814770.8741 +2904 2786 -53439363.43899 +2905 2786 -5277708.20877 +2906 2786 -66116380.01208 +2907 2786 -18340743.64572 +2908 2786 13440937.44126 +2909 2786 -39208792.08802 +2787 2787 866925828.5346 +2788 2787 47817747.45269 +2789 2787 23749660.20008 +2790 2787 14263474.74723 +2791 2787 -47793765.64302 +2792 2787 20546059.94785 +2793 2787 -71804122.04904 +2794 2787 -47777777.76993 +2795 2787 19043969.88243 +2796 2787 -181853790.138 +2797 2787 3.248453140259e-06 +2798 2787 -3518564.899638 +2799 2787 -72853540.65349 +2800 2787 47777777.76992 +2801 2787 -20539363.4444 +2889 2787 -19603280.6462 +2890 2787 11944444.44837 +2891 2787 8005089.696258 +2892 2787 -85740387.93072 +2893 2787 -11950439.90077 +2894 2787 47775096.06898 +2895 2787 16294780.8482 +2896 2787 4.217028617859e-06 +2897 2787 439820.6128852 +2898 2787 112006329.4708 +2899 2787 11954436.86906 +2900 2787 5935349.843305 +2901 2787 -36979414.9719 +2902 2787 -11948441.41664 +2903 2787 18346879.03149 +2904 2787 -20039396.92541 +2905 2787 -11944444.44837 +2906 2787 -8444910.309145 +2907 2787 -74762019.75572 +2908 2787 2.533197402954e-07 +2909 2787 -53703252.3277 +2910 2787 -30778677.45218 +2911 2787 11944444.44836 +2912 2787 -18340743.64572 +2788 2788 737900094.3577 +2789 2788 -65443918.48946 +2790 2788 -47801759.57957 +2791 2788 -152989568.1247 +2792 2788 35049537.95506 +2793 2788 -47777777.76993 +2794 2788 -57469927.96065 +2795 2788 9605416.412441 +2796 2788 3.069639205933e-06 +2797 2788 28369859.6463 +2798 2788 -21110832.82467 +2799 2788 47777777.76992 +2800 2788 -58519346.56511 +2801 2788 11505416.41223 +2889 2788 11944444.44837 +2890 2788 -16019732.12234 +2891 2788 -7635451.454545 +2892 2788 -11948441.41664 +2893 2788 -29588436.2443 +2894 2788 4682155.144749 +2895 2788 5.125999450684e-06 +2896 2788 -29094034.58311 +2897 2788 -31702916.914 +2898 2788 11954436.86906 +2899 2788 79749895.91067 +2900 2788 -16362631.77783 +2901 2788 -11950439.90078 +2902 2788 -78792675.71048 +2903 2788 51029508.03613 +2904 2788 -11944444.44837 +2905 2788 -16455848.40155 +2906 2788 -8163229.232496 +2907 2788 -8.195638656616e-07 +2908 2788 -22206107.28377 +2909 2788 -5277708.20877 +2910 2788 11944444.44836 +2911 2788 -27195128.92833 +2912 2788 13440937.44126 +2789 2789 768350518.5004 +2790 2789 20813297.08829 +2791 2789 40963180.50213 +2792 2789 19484057.05595 +2793 2789 18780080.99371 +2794 2789 9394305.301468 +2795 2789 -20006934.4106 +2796 2789 -3518564.899638 +2797 2789 -21110832.82467 +2798 2789 48052583.38233 +2799 2789 -20803252.33311 +2800 2789 11716527.5232 +2801 2789 -22805384.02253 +2889 2789 8005089.696258 +2890 2789 -7635451.454545 +2891 2789 -9407733.938713 +2892 2789 47510397.70207 +2893 2789 3205506.989851 +2894 2789 -52478548.16204 +2895 2789 439820.6128855 +2896 2789 -31491805.80303 +2897 2789 -4060894.923526 +2898 2789 5939756.113784 +2899 2789 -16359106.80793 +2900 2789 -87179377.66603 +2901 2789 18349946.72438 +2902 2789 52296851.6274 +2903 2789 -103249742.1615 +2904 2789 -8444910.309145 +2905 2789 -8163229.232496 +2906 2789 -10570710.68328 +2907 2789 -53439363.43899 +2908 2789 -5277708.20877 +2909 2789 -66116380.01208 +2910 2789 -18340743.64572 +2911 2789 13440937.44126 +2912 2789 -39208792.08802 +2790 2790 508612796.7711 +2791 2790 47777777.76993 +2792 2790 20248388.26907 +2796 2790 -71804122.04904 +2797 2790 -47777777.76993 +2798 2790 19043969.88243 +2799 2790 -267652150.2947 +2800 2790 -47793765.64302 +2801 2790 -20241471.08164 +2802 2790 6087083.420696 +2803 2790 38238210.08904 +2804 2790 -16367807.61161 +2892 2790 1532382.642161 +2893 2790 14339328.79045 +2894 2790 9874015.186731 +2898 2790 -4845636.536104 +2899 2790 -11950439.90078 +2900 2790 -8009104.879749 +2901 2790 57272319.20769 +2902 2790 11944444.44837 +2903 2790 16262217.83282 +2907 2790 -20039396.92541 +2908 2790 -11944444.44837 +2909 2790 -8444910.309145 +2910 2790 -96920154.16551 +2911 2790 -11948441.41665 +2912 2790 -57894966.96635 +2913 2790 -19430363.65776 +2914 2790 9559552.526969 +2915 2790 -14502802.0572 +2791 2791 436923838.9196 +2792 2791 -52790465.59624 +2796 2791 -47777777.76993 +2797 2791 -57469927.96065 +2798 2791 9605416.412441 +2799 2791 -47801759.57957 +2800 2791 -43044343.65972 +2801 2791 -29246608.86722 +2802 2791 57357315.13355 +2803 2791 6087083.420705 +2804 2791 18374525.78853 +2892 2791 9559552.526969 +2893 2791 1532382.642157 +2894 2791 -5266148.137347 +2898 2791 -11948441.41664 +2899 2791 -46658897.27468 +2900 2791 -32026328.33686 +2901 2791 11944444.44837 +2902 2791 39350079.73598 +2903 2791 -4237631.002181 +2907 2791 -11944444.44837 +2908 2791 -16455848.40155 +2909 2791 -8163229.232496 +2910 2791 -11950439.90079 +2911 2791 -40768202.4791 +2912 2791 -17881456.80322 +2913 2791 14339328.79045 +2914 2791 -19430363.65775 +2915 2791 17403019.36621 +2792 2792 498731997.6738 +2796 2792 18780080.99371 +2797 2792 9394305.301468 +2798 2792 -20006934.4106 +2799 2792 -20238012.48793 +2800 2792 -23543989.15986 +2801 2792 -9089122.520285 +2802 2792 -24551711.41742 +2803 2792 12249683.85902 +2804 2792 16232222.45521 +2892 2792 6582676.791154 +2893 2792 -7899222.206021 +2894 2792 4086353.712421 +2898 2792 -8007766.485252 +2899 2792 -33293672.07046 +2900 2792 -17559666.33271 +2901 2792 -4818855.100867 +2902 2792 -21102266.9381 +2903 2792 -61666013.98076 +2907 2792 -8444910.309145 +2908 2792 -8163229.232496 +2909 2792 -10570710.68328 +2910 2792 -57630268.59944 +2911 2792 -16401283.68257 +2912 2792 -82291258.12151 +2913 2792 -21754203.08579 +2914 2792 11602012.9108 +2915 2792 -51814303.08735 +2793 2793 801867013.5374 +2794 2793 2.598762512207e-05 +2795 2793 7037129.799195 +2796 2793 92970237.73849 +2797 2793 -1.010298728943e-05 +2798 2793 1759282.450673 +2805 2793 -181853790.138 +2806 2793 3.248453140259e-06 +2807 2793 -3518564.899638 +2808 2793 -72853540.65349 +2809 2793 47777777.76992 +2810 2793 -20539363.4444 +2895 2793 -71968136.03531 +2896 2793 4.157423973083e-06 +2897 2793 51943969.87703 +2898 2793 -29817851.87049 +2899 2793 -11944444.44837 +2900 2793 17900923.03284 +2904 2793 88895212.80375 +2905 2793 4.112720489502e-06 +2906 2793 1759282.450699 +2907 2793 -25612922.63328 +2908 2793 -1.080334186554e-05 +2909 2793 439820.6129002 +2916 2793 -74762019.75572 +2917 2793 2.533197402954e-07 +2918 2793 -53703252.3277 +2919 2793 -30778677.45218 +2920 2793 11944444.44836 +2921 2793 -18340743.64572 +2794 2794 687193460.8868 +2795 2794 -84443331.25708 +2796 2794 -1.019239425659e-05 +2797 2794 -88585023.89729 +2798 2794 42221665.62855 +2805 2794 3.069639205933e-06 +2806 2794 28369859.6463 +2807 2794 -21110832.82467 +2808 2794 47777777.76992 +2809 2794 -58519346.56511 +2810 2794 11505416.41223 +2895 2794 3.337860107422e-06 +2896 2794 -19412223.56332 +2897 2794 -5277708.208769 +2898 2794 -11944444.44837 +2899 2794 -26234303.34662 +2900 2794 12913159.66331 +2904 2794 4.351139068604e-06 +2905 2794 60226824.62697 +2906 2794 -21110832.82468 +2907 2794 -9.95397567749e-06 +2908 2794 -71001738.06458 +2909 2794 52813749.73867 +2916 2794 -8.195638656616e-07 +2917 2794 -22206107.28377 +2918 2794 -5277708.20877 +2919 2794 11944444.44836 +2920 2794 -27195128.92833 +2921 2794 13440937.44126 +2795 2795 766546241.681 +2796 2795 1759282.450673 +2797 2795 42221665.62855 +2798 2795 57866058.65466 +2805 2795 -3518564.899638 +2806 2795 -21110832.82467 +2807 2795 48052583.38233 +2808 2795 -20803252.33311 +2809 2795 11716527.5232 +2810 2795 -22805384.02253 +2895 2795 51680080.98832 +2896 2795 -5277708.208769 +2897 2795 -58666023.42418 +2898 2795 17900923.03284 +2899 2795 12913159.66331 +2900 2795 -36646590.5368 +2904 2795 1759282.450699 +2905 2795 -21110832.82468 +2906 2795 -105887547.9636 +2907 2795 439820.6129005 +2908 2795 52602638.6277 +2909 2795 -115814770.8741 +2916 2795 -53439363.43899 +2917 2795 -5277708.20877 +2918 2795 -66116380.01208 +2919 2795 -18340743.64572 +2920 2795 13440937.44126 +2921 2795 -39208792.08802 +2796 2796 801867013.5374 +2797 2796 2.598762512207e-05 +2798 2796 7037129.799195 +2799 2796 92970237.73849 +2800 2796 -1.010298728943e-05 +2801 2796 1759282.450673 +2805 2796 -71804122.04904 +2806 2796 -47777777.76993 +2807 2796 19043969.88243 +2808 2796 -181853790.138 +2809 2796 3.248453140259e-06 +2810 2796 -3518564.899638 +2811 2796 -72853540.65349 +2812 2796 47777777.76992 +2813 2796 -20539363.4444 +2895 2796 -19603280.6462 +2896 2796 11944444.44837 +2897 2796 8005089.696258 +2898 2796 -71968136.03531 +2899 2796 4.157423973083e-06 +2900 2796 51943969.87703 +2901 2796 -29817851.87049 +2902 2796 -11944444.44837 +2903 2796 17900923.03284 +2904 2796 16294780.8482 +2905 2796 4.217028617859e-06 +2906 2796 439820.6128852 +2907 2796 88895212.80375 +2908 2796 4.112720489502e-06 +2909 2796 1759282.450699 +2910 2796 -25612922.63328 +2911 2796 -1.080334186554e-05 +2912 2796 439820.6129002 +2916 2796 -20039396.92541 +2917 2796 -11944444.44837 +2918 2796 -8444910.309145 +2919 2796 -74762019.75572 +2920 2796 2.533197402954e-07 +2921 2796 -53703252.3277 +2922 2796 -30778677.45218 +2923 2796 11944444.44836 +2924 2796 -18340743.64572 +2797 2797 687193460.8868 +2798 2797 -84443331.25708 +2799 2797 -1.019239425659e-05 +2800 2797 -88585023.89729 +2801 2797 42221665.62855 +2805 2797 -47777777.76993 +2806 2797 -57469927.96065 +2807 2797 9605416.412441 +2808 2797 3.069639205933e-06 +2809 2797 28369859.6463 +2810 2797 -21110832.82467 +2811 2797 47777777.76992 +2812 2797 -58519346.56511 +2813 2797 11505416.41223 +2895 2797 11944444.44837 +2896 2797 -16019732.12234 +2897 2797 -7635451.454545 +2898 2797 3.337860107422e-06 +2899 2797 -19412223.56332 +2900 2797 -5277708.208769 +2901 2797 -11944444.44837 +2902 2797 -26234303.34662 +2903 2797 12913159.66331 +2904 2797 5.125999450684e-06 +2905 2797 -29094034.58311 +2906 2797 -31702916.914 +2907 2797 4.351139068604e-06 +2908 2797 60226824.62697 +2909 2797 -21110832.82468 +2910 2797 -9.95397567749e-06 +2911 2797 -71001738.06458 +2912 2797 52813749.73867 +2916 2797 -11944444.44837 +2917 2797 -16455848.40155 +2918 2797 -8163229.232496 +2919 2797 -8.195638656616e-07 +2920 2797 -22206107.28377 +2921 2797 -5277708.20877 +2922 2797 11944444.44836 +2923 2797 -27195128.92833 +2924 2797 13440937.44126 +2798 2798 766546241.681 +2799 2798 1759282.450673 +2800 2798 42221665.62855 +2801 2798 57866058.65466 +2805 2798 18780080.99371 +2806 2798 9394305.301468 +2807 2798 -20006934.4106 +2808 2798 -3518564.899638 +2809 2798 -21110832.82467 +2810 2798 48052583.38233 +2811 2798 -20803252.33311 +2812 2798 11716527.5232 +2813 2798 -22805384.02253 +2895 2798 8005089.696258 +2896 2798 -7635451.454545 +2897 2798 -9407733.938713 +2898 2798 51680080.98832 +2899 2798 -5277708.208769 +2900 2798 -58666023.42418 +2901 2798 17900923.03284 +2902 2798 12913159.66331 +2903 2798 -36646590.5368 +2904 2798 439820.6128855 +2905 2798 -31491805.80303 +2906 2798 -4060894.923526 +2907 2798 1759282.450699 +2908 2798 -21110832.82468 +2909 2798 -105887547.9636 +2910 2798 439820.6129005 +2911 2798 52602638.6277 +2912 2798 -115814770.8741 +2916 2798 -8444910.309145 +2917 2798 -8163229.232496 +2918 2798 -10570710.68328 +2919 2798 -53439363.43899 +2920 2798 -5277708.20877 +2921 2798 -66116380.01208 +2922 2798 -18340743.64572 +2923 2798 13440937.44126 +2924 2798 -39208792.08802 +2799 2799 866925828.5346 +2800 2799 47817747.45269 +2801 2799 23749660.20008 +2802 2799 14263474.74723 +2803 2799 -47793765.64302 +2804 2799 20546059.94785 +2808 2799 -71804122.04904 +2809 2799 -47777777.76993 +2810 2799 19043969.88243 +2811 2799 -181853790.138 +2812 2799 3.248453140259e-06 +2813 2799 -3518564.899638 +2814 2799 -72853540.65349 +2815 2799 47777777.76992 +2816 2799 -20539363.4444 +2898 2799 -19603280.6462 +2899 2799 11944444.44837 +2900 2799 8005089.696258 +2901 2799 -85740387.93072 +2902 2799 -11950439.90077 +2903 2799 47775096.06898 +2907 2799 16294780.8482 +2908 2799 4.217028617859e-06 +2909 2799 439820.6128852 +2910 2799 112006329.4708 +2911 2799 11954436.86906 +2912 2799 5935349.843305 +2913 2799 -36979414.9719 +2914 2799 -11948441.41664 +2915 2799 18346879.03149 +2919 2799 -20039396.92541 +2920 2799 -11944444.44837 +2921 2799 -8444910.309145 +2922 2799 -74762019.75572 +2923 2799 2.533197402954e-07 +2924 2799 -53703252.3277 +2925 2799 -30778677.45218 +2926 2799 11944444.44836 +2927 2799 -18340743.64572 +2800 2800 737900094.3577 +2801 2800 -65443918.48946 +2802 2800 -47801759.57957 +2803 2800 -152989568.1247 +2804 2800 35049537.95506 +2808 2800 -47777777.76993 +2809 2800 -57469927.96065 +2810 2800 9605416.412441 +2811 2800 3.069639205933e-06 +2812 2800 28369859.6463 +2813 2800 -21110832.82467 +2814 2800 47777777.76992 +2815 2800 -58519346.56511 +2816 2800 11505416.41223 +2898 2800 11944444.44837 +2899 2800 -16019732.12234 +2900 2800 -7635451.454545 +2901 2800 -11948441.41664 +2902 2800 -29588436.2443 +2903 2800 4682155.144749 +2907 2800 5.125999450684e-06 +2908 2800 -29094034.58311 +2909 2800 -31702916.914 +2910 2800 11954436.86906 +2911 2800 79749895.91067 +2912 2800 -16362631.77783 +2913 2800 -11950439.90078 +2914 2800 -78792675.71048 +2915 2800 51029508.03613 +2919 2800 -11944444.44837 +2920 2800 -16455848.40155 +2921 2800 -8163229.232496 +2922 2800 -8.195638656616e-07 +2923 2800 -22206107.28377 +2924 2800 -5277708.20877 +2925 2800 11944444.44836 +2926 2800 -27195128.92833 +2927 2800 13440937.44126 +2801 2801 768350518.5004 +2802 2801 20813297.08829 +2803 2801 40963180.50213 +2804 2801 19484057.05595 +2808 2801 18780080.99371 +2809 2801 9394305.301468 +2810 2801 -20006934.4106 +2811 2801 -3518564.899638 +2812 2801 -21110832.82467 +2813 2801 48052583.38233 +2814 2801 -20803252.33311 +2815 2801 11716527.5232 +2816 2801 -22805384.02253 +2898 2801 8005089.696258 +2899 2801 -7635451.454545 +2900 2801 -9407733.938713 +2901 2801 47510397.70207 +2902 2801 3205506.989851 +2903 2801 -52478548.16204 +2907 2801 439820.6128855 +2908 2801 -31491805.80303 +2909 2801 -4060894.923526 +2910 2801 5939756.113784 +2911 2801 -16359106.80793 +2912 2801 -87179377.66603 +2913 2801 18349946.72438 +2914 2801 52296851.6274 +2915 2801 -103249742.1615 +2919 2801 -8444910.309145 +2920 2801 -8163229.232496 +2921 2801 -10570710.68328 +2922 2801 -53439363.43899 +2923 2801 -5277708.20877 +2924 2801 -66116380.01208 +2925 2801 -18340743.64572 +2926 2801 13440937.44126 +2927 2801 -39208792.08802 +2802 2802 508612796.7711 +2803 2802 47777777.76993 +2804 2802 20248388.26907 +2811 2802 -71804122.04904 +2812 2802 -47777777.76993 +2813 2802 19043969.88243 +2814 2802 -267652150.2947 +2815 2802 -47793765.64302 +2816 2802 -20241471.08164 +2817 2802 6087083.420696 +2818 2802 38238210.08904 +2819 2802 -16367807.61161 +2901 2802 1532382.642161 +2902 2802 14339328.79045 +2903 2802 9874015.186731 +2910 2802 -4845636.536104 +2911 2802 -11950439.90078 +2912 2802 -8009104.879749 +2913 2802 57272319.20769 +2914 2802 11944444.44837 +2915 2802 16262217.83282 +2922 2802 -20039396.92541 +2923 2802 -11944444.44837 +2924 2802 -8444910.309145 +2925 2802 -96920154.16551 +2926 2802 -11948441.41665 +2927 2802 -57894966.96635 +2928 2802 -19430363.65776 +2929 2802 9559552.526969 +2930 2802 -14502802.0572 +2803 2803 436923838.9196 +2804 2803 -52790465.59624 +2811 2803 -47777777.76993 +2812 2803 -57469927.96065 +2813 2803 9605416.412441 +2814 2803 -47801759.57957 +2815 2803 -43044343.65972 +2816 2803 -29246608.86722 +2817 2803 57357315.13355 +2818 2803 6087083.420705 +2819 2803 18374525.78853 +2901 2803 9559552.526969 +2902 2803 1532382.642157 +2903 2803 -5266148.137347 +2910 2803 -11948441.41664 +2911 2803 -46658897.27468 +2912 2803 -32026328.33686 +2913 2803 11944444.44837 +2914 2803 39350079.73598 +2915 2803 -4237631.002181 +2922 2803 -11944444.44837 +2923 2803 -16455848.40155 +2924 2803 -8163229.232496 +2925 2803 -11950439.90079 +2926 2803 -40768202.4791 +2927 2803 -17881456.80322 +2928 2803 14339328.79045 +2929 2803 -19430363.65775 +2930 2803 17403019.36621 +2804 2804 498731997.6738 +2811 2804 18780080.99371 +2812 2804 9394305.301468 +2813 2804 -20006934.4106 +2814 2804 -20238012.48793 +2815 2804 -23543989.15986 +2816 2804 -9089122.520285 +2817 2804 -24551711.41742 +2818 2804 12249683.85902 +2819 2804 16232222.45521 +2901 2804 6582676.791154 +2902 2804 -7899222.206021 +2903 2804 4086353.712421 +2910 2804 -8007766.485252 +2911 2804 -33293672.07046 +2912 2804 -17559666.33271 +2913 2804 -4818855.100867 +2914 2804 -21102266.9381 +2915 2804 -61666013.98076 +2922 2804 -8444910.309145 +2923 2804 -8163229.232496 +2924 2804 -10570710.68328 +2925 2804 -57630268.59944 +2926 2804 -16401283.68257 +2927 2804 -82291258.12151 +2928 2804 -21754203.08579 +2929 2804 11602012.9108 +2930 2804 -51814303.08735 +2805 2805 801867013.5374 +2806 2805 2.598762512207e-05 +2807 2805 7037129.799195 +2808 2805 92970237.73849 +2809 2805 -1.010298728943e-05 +2810 2805 1759282.450673 +2820 2805 -181853790.138 +2821 2805 3.248453140259e-06 +2822 2805 -3518564.899638 +2823 2805 -72853540.65349 +2824 2805 47777777.76992 +2825 2805 -20539363.4444 +2904 2805 -71968136.03531 +2905 2805 4.157423973083e-06 +2906 2805 51943969.87703 +2907 2805 -29817851.87049 +2908 2805 -11944444.44837 +2909 2805 17900923.03284 +2916 2805 88895212.80375 +2917 2805 4.112720489502e-06 +2918 2805 1759282.450699 +2919 2805 -25612922.63328 +2920 2805 -1.080334186554e-05 +2921 2805 439820.6129002 +2931 2805 -74762019.75572 +2932 2805 2.533197402954e-07 +2933 2805 -53703252.3277 +2934 2805 -30778677.45218 +2935 2805 11944444.44836 +2936 2805 -18340743.64572 +2806 2806 687193460.8868 +2807 2806 -84443331.25708 +2808 2806 -1.019239425659e-05 +2809 2806 -88585023.89729 +2810 2806 42221665.62855 +2820 2806 3.069639205933e-06 +2821 2806 28369859.6463 +2822 2806 -21110832.82467 +2823 2806 47777777.76992 +2824 2806 -58519346.56511 +2825 2806 11505416.41223 +2904 2806 3.337860107422e-06 +2905 2806 -19412223.56332 +2906 2806 -5277708.208769 +2907 2806 -11944444.44837 +2908 2806 -26234303.34662 +2909 2806 12913159.66331 +2916 2806 4.351139068604e-06 +2917 2806 60226824.62697 +2918 2806 -21110832.82468 +2919 2806 -9.95397567749e-06 +2920 2806 -71001738.06458 +2921 2806 52813749.73867 +2931 2806 -8.195638656616e-07 +2932 2806 -22206107.28377 +2933 2806 -5277708.20877 +2934 2806 11944444.44836 +2935 2806 -27195128.92833 +2936 2806 13440937.44126 +2807 2807 766546241.681 +2808 2807 1759282.450673 +2809 2807 42221665.62855 +2810 2807 57866058.65466 +2820 2807 -3518564.899638 +2821 2807 -21110832.82467 +2822 2807 48052583.38233 +2823 2807 -20803252.33311 +2824 2807 11716527.5232 +2825 2807 -22805384.02253 +2904 2807 51680080.98832 +2905 2807 -5277708.208769 +2906 2807 -58666023.42418 +2907 2807 17900923.03284 +2908 2807 12913159.66331 +2909 2807 -36646590.5368 +2916 2807 1759282.450699 +2917 2807 -21110832.82468 +2918 2807 -105887547.9636 +2919 2807 439820.6129005 +2920 2807 52602638.6277 +2921 2807 -115814770.8741 +2931 2807 -53439363.43899 +2932 2807 -5277708.20877 +2933 2807 -66116380.01208 +2934 2807 -18340743.64572 +2935 2807 13440937.44126 +2936 2807 -39208792.08802 +2808 2808 801867013.5374 +2809 2808 2.598762512207e-05 +2810 2808 7037129.799195 +2811 2808 92970237.73849 +2812 2808 -1.010298728943e-05 +2813 2808 1759282.450673 +2820 2808 -71804122.04904 +2821 2808 -47777777.76993 +2822 2808 19043969.88243 +2823 2808 -181853790.138 +2824 2808 3.248453140259e-06 +2825 2808 -3518564.899638 +2826 2808 -72853540.65349 +2827 2808 47777777.76992 +2828 2808 -20539363.4444 +2904 2808 -19603280.6462 +2905 2808 11944444.44837 +2906 2808 8005089.696258 +2907 2808 -71968136.03531 +2908 2808 4.157423973083e-06 +2909 2808 51943969.87703 +2910 2808 -29817851.87049 +2911 2808 -11944444.44837 +2912 2808 17900923.03284 +2916 2808 16294780.8482 +2917 2808 4.217028617859e-06 +2918 2808 439820.6128852 +2919 2808 88895212.80375 +2920 2808 4.112720489502e-06 +2921 2808 1759282.450699 +2922 2808 -25612922.63328 +2923 2808 -1.080334186554e-05 +2924 2808 439820.6129002 +2931 2808 -20039396.92541 +2932 2808 -11944444.44837 +2933 2808 -8444910.309145 +2934 2808 -74762019.75572 +2935 2808 2.533197402954e-07 +2936 2808 -53703252.3277 +2937 2808 -30778677.45218 +2938 2808 11944444.44836 +2939 2808 -18340743.64572 +2809 2809 687193460.8868 +2810 2809 -84443331.25708 +2811 2809 -1.019239425659e-05 +2812 2809 -88585023.89729 +2813 2809 42221665.62855 +2820 2809 -47777777.76993 +2821 2809 -57469927.96065 +2822 2809 9605416.412441 +2823 2809 3.069639205933e-06 +2824 2809 28369859.6463 +2825 2809 -21110832.82467 +2826 2809 47777777.76992 +2827 2809 -58519346.56511 +2828 2809 11505416.41223 +2904 2809 11944444.44837 +2905 2809 -16019732.12234 +2906 2809 -7635451.454545 +2907 2809 3.337860107422e-06 +2908 2809 -19412223.56332 +2909 2809 -5277708.208769 +2910 2809 -11944444.44837 +2911 2809 -26234303.34662 +2912 2809 12913159.66331 +2916 2809 5.125999450684e-06 +2917 2809 -29094034.58311 +2918 2809 -31702916.914 +2919 2809 4.351139068604e-06 +2920 2809 60226824.62697 +2921 2809 -21110832.82468 +2922 2809 -9.95397567749e-06 +2923 2809 -71001738.06458 +2924 2809 52813749.73867 +2931 2809 -11944444.44837 +2932 2809 -16455848.40155 +2933 2809 -8163229.232496 +2934 2809 -8.195638656616e-07 +2935 2809 -22206107.28377 +2936 2809 -5277708.20877 +2937 2809 11944444.44836 +2938 2809 -27195128.92833 +2939 2809 13440937.44126 +2810 2810 766546241.681 +2811 2810 1759282.450673 +2812 2810 42221665.62855 +2813 2810 57866058.65466 +2820 2810 18780080.99371 +2821 2810 9394305.301468 +2822 2810 -20006934.4106 +2823 2810 -3518564.899638 +2824 2810 -21110832.82467 +2825 2810 48052583.38233 +2826 2810 -20803252.33311 +2827 2810 11716527.5232 +2828 2810 -22805384.02253 +2904 2810 8005089.696258 +2905 2810 -7635451.454545 +2906 2810 -9407733.938713 +2907 2810 51680080.98832 +2908 2810 -5277708.208769 +2909 2810 -58666023.42418 +2910 2810 17900923.03284 +2911 2810 12913159.66331 +2912 2810 -36646590.5368 +2916 2810 439820.6128855 +2917 2810 -31491805.80303 +2918 2810 -4060894.923526 +2919 2810 1759282.450699 +2920 2810 -21110832.82468 +2921 2810 -105887547.9636 +2922 2810 439820.6129005 +2923 2810 52602638.6277 +2924 2810 -115814770.8741 +2931 2810 -8444910.309145 +2932 2810 -8163229.232496 +2933 2810 -10570710.68328 +2934 2810 -53439363.43899 +2935 2810 -5277708.20877 +2936 2810 -66116380.01208 +2937 2810 -18340743.64572 +2938 2810 13440937.44126 +2939 2810 -39208792.08802 +2811 2811 801867013.5374 +2812 2811 2.598762512207e-05 +2813 2811 7037129.799195 +2814 2811 92970237.73849 +2815 2811 -1.010298728943e-05 +2816 2811 1759282.450673 +2823 2811 -71804122.04904 +2824 2811 -47777777.76993 +2825 2811 19043969.88243 +2826 2811 -181853790.138 +2827 2811 3.248453140259e-06 +2828 2811 -3518564.899638 +2829 2811 -72853540.65349 +2830 2811 47777777.76992 +2831 2811 -20539363.4444 +2907 2811 -19603280.6462 +2908 2811 11944444.44837 +2909 2811 8005089.696258 +2910 2811 -71968136.03531 +2911 2811 4.157423973083e-06 +2912 2811 51943969.87703 +2913 2811 -29817851.87049 +2914 2811 -11944444.44837 +2915 2811 17900923.03284 +2919 2811 16294780.8482 +2920 2811 4.217028617859e-06 +2921 2811 439820.6128852 +2922 2811 88895212.80375 +2923 2811 4.112720489502e-06 +2924 2811 1759282.450699 +2925 2811 -25612922.63328 +2926 2811 -1.080334186554e-05 +2927 2811 439820.6129002 +2934 2811 -20039396.92541 +2935 2811 -11944444.44837 +2936 2811 -8444910.309145 +2937 2811 -74762019.75572 +2938 2811 2.533197402954e-07 +2939 2811 -53703252.3277 +2940 2811 -30778677.45218 +2941 2811 11944444.44836 +2942 2811 -18340743.64572 +2812 2812 687193460.8868 +2813 2812 -84443331.25708 +2814 2812 -1.019239425659e-05 +2815 2812 -88585023.89729 +2816 2812 42221665.62855 +2823 2812 -47777777.76993 +2824 2812 -57469927.96065 +2825 2812 9605416.412441 +2826 2812 3.069639205933e-06 +2827 2812 28369859.6463 +2828 2812 -21110832.82467 +2829 2812 47777777.76992 +2830 2812 -58519346.56511 +2831 2812 11505416.41223 +2907 2812 11944444.44837 +2908 2812 -16019732.12234 +2909 2812 -7635451.454545 +2910 2812 3.337860107422e-06 +2911 2812 -19412223.56332 +2912 2812 -5277708.208769 +2913 2812 -11944444.44837 +2914 2812 -26234303.34662 +2915 2812 12913159.66331 +2919 2812 5.125999450684e-06 +2920 2812 -29094034.58311 +2921 2812 -31702916.914 +2922 2812 4.351139068604e-06 +2923 2812 60226824.62697 +2924 2812 -21110832.82468 +2925 2812 -9.95397567749e-06 +2926 2812 -71001738.06458 +2927 2812 52813749.73867 +2934 2812 -11944444.44837 +2935 2812 -16455848.40155 +2936 2812 -8163229.232496 +2937 2812 -8.195638656616e-07 +2938 2812 -22206107.28377 +2939 2812 -5277708.20877 +2940 2812 11944444.44836 +2941 2812 -27195128.92833 +2942 2812 13440937.44126 +2813 2813 766546241.681 +2814 2813 1759282.450673 +2815 2813 42221665.62855 +2816 2813 57866058.65466 +2823 2813 18780080.99371 +2824 2813 9394305.301468 +2825 2813 -20006934.4106 +2826 2813 -3518564.899638 +2827 2813 -21110832.82467 +2828 2813 48052583.38233 +2829 2813 -20803252.33311 +2830 2813 11716527.5232 +2831 2813 -22805384.02253 +2907 2813 8005089.696258 +2908 2813 -7635451.454545 +2909 2813 -9407733.938713 +2910 2813 51680080.98832 +2911 2813 -5277708.208769 +2912 2813 -58666023.42418 +2913 2813 17900923.03284 +2914 2813 12913159.66331 +2915 2813 -36646590.5368 +2919 2813 439820.6128855 +2920 2813 -31491805.80303 +2921 2813 -4060894.923526 +2922 2813 1759282.450699 +2923 2813 -21110832.82468 +2924 2813 -105887547.9636 +2925 2813 439820.6129005 +2926 2813 52602638.6277 +2927 2813 -115814770.8741 +2934 2813 -8444910.309145 +2935 2813 -8163229.232496 +2936 2813 -10570710.68328 +2937 2813 -53439363.43899 +2938 2813 -5277708.20877 +2939 2813 -66116380.01208 +2940 2813 -18340743.64572 +2941 2813 13440937.44126 +2942 2813 -39208792.08802 +2814 2814 866925828.5346 +2815 2814 47817747.45269 +2816 2814 23749660.20008 +2817 2814 14263474.74723 +2818 2814 -47793765.64302 +2819 2814 20546059.94785 +2826 2814 -71804122.04904 +2827 2814 -47777777.76993 +2828 2814 19043969.88243 +2829 2814 -181853790.138 +2830 2814 3.248453140259e-06 +2831 2814 -3518564.899638 +2832 2814 -72853540.65349 +2833 2814 47777777.76992 +2834 2814 -20539363.4444 +2910 2814 -19603280.6462 +2911 2814 11944444.44837 +2912 2814 8005089.696258 +2913 2814 -85740387.93072 +2914 2814 -11950439.90077 +2915 2814 47775096.06898 +2922 2814 16294780.8482 +2923 2814 4.217028617859e-06 +2924 2814 439820.6128852 +2925 2814 112006329.4708 +2926 2814 11954436.86906 +2927 2814 5935349.843305 +2928 2814 -36979414.9719 +2929 2814 -11948441.41664 +2930 2814 18346879.03149 +2937 2814 -20039396.92541 +2938 2814 -11944444.44837 +2939 2814 -8444910.309145 +2940 2814 -74762019.75572 +2941 2814 2.533197402954e-07 +2942 2814 -53703252.3277 +2943 2814 -30778677.45218 +2944 2814 11944444.44836 +2945 2814 -18340743.64572 +2815 2815 737900094.3577 +2816 2815 -65443918.48946 +2817 2815 -47801759.57957 +2818 2815 -152989568.1247 +2819 2815 35049537.95506 +2826 2815 -47777777.76993 +2827 2815 -57469927.96065 +2828 2815 9605416.412441 +2829 2815 3.069639205933e-06 +2830 2815 28369859.6463 +2831 2815 -21110832.82467 +2832 2815 47777777.76992 +2833 2815 -58519346.56511 +2834 2815 11505416.41223 +2910 2815 11944444.44837 +2911 2815 -16019732.12234 +2912 2815 -7635451.454545 +2913 2815 -11948441.41664 +2914 2815 -29588436.2443 +2915 2815 4682155.144749 +2922 2815 5.125999450684e-06 +2923 2815 -29094034.58311 +2924 2815 -31702916.914 +2925 2815 11954436.86906 +2926 2815 79749895.91067 +2927 2815 -16362631.77783 +2928 2815 -11950439.90078 +2929 2815 -78792675.71048 +2930 2815 51029508.03613 +2937 2815 -11944444.44837 +2938 2815 -16455848.40155 +2939 2815 -8163229.232496 +2940 2815 -8.195638656616e-07 +2941 2815 -22206107.28377 +2942 2815 -5277708.20877 +2943 2815 11944444.44836 +2944 2815 -27195128.92833 +2945 2815 13440937.44126 +2816 2816 768350518.5004 +2817 2816 20813297.08829 +2818 2816 40963180.50213 +2819 2816 19484057.05595 +2826 2816 18780080.99371 +2827 2816 9394305.301468 +2828 2816 -20006934.4106 +2829 2816 -3518564.899638 +2830 2816 -21110832.82467 +2831 2816 48052583.38233 +2832 2816 -20803252.33311 +2833 2816 11716527.5232 +2834 2816 -22805384.02253 +2910 2816 8005089.696258 +2911 2816 -7635451.454545 +2912 2816 -9407733.938713 +2913 2816 47510397.70207 +2914 2816 3205506.989851 +2915 2816 -52478548.16204 +2922 2816 439820.6128855 +2923 2816 -31491805.80303 +2924 2816 -4060894.923526 +2925 2816 5939756.113784 +2926 2816 -16359106.80793 +2927 2816 -87179377.66603 +2928 2816 18349946.72438 +2929 2816 52296851.6274 +2930 2816 -103249742.1615 +2937 2816 -8444910.309145 +2938 2816 -8163229.232496 +2939 2816 -10570710.68328 +2940 2816 -53439363.43899 +2941 2816 -5277708.20877 +2942 2816 -66116380.01208 +2943 2816 -18340743.64572 +2944 2816 13440937.44126 +2945 2816 -39208792.08802 +2817 2817 508612796.7711 +2818 2817 47777777.76993 +2819 2817 20248388.26907 +2829 2817 -71804122.04904 +2830 2817 -47777777.76993 +2831 2817 19043969.88243 +2832 2817 -267652150.2947 +2833 2817 -47793765.64302 +2834 2817 -20241471.08164 +2835 2817 6087083.420696 +2836 2817 38238210.08904 +2837 2817 -16367807.61161 +2913 2817 1532382.642161 +2914 2817 14339328.79045 +2915 2817 9874015.186731 +2925 2817 -4845636.536104 +2926 2817 -11950439.90078 +2927 2817 -8009104.879749 +2928 2817 57272319.20769 +2929 2817 11944444.44837 +2930 2817 16262217.83282 +2940 2817 -20039396.92541 +2941 2817 -11944444.44837 +2942 2817 -8444910.309145 +2943 2817 -96920154.16551 +2944 2817 -11948441.41665 +2945 2817 -57894966.96635 +2946 2817 -19430363.65776 +2947 2817 9559552.526969 +2948 2817 -14502802.0572 +2818 2818 436923838.9196 +2819 2818 -52790465.59624 +2829 2818 -47777777.76993 +2830 2818 -57469927.96065 +2831 2818 9605416.412441 +2832 2818 -47801759.57957 +2833 2818 -43044343.65972 +2834 2818 -29246608.86722 +2835 2818 57357315.13355 +2836 2818 6087083.420705 +2837 2818 18374525.78853 +2913 2818 9559552.526969 +2914 2818 1532382.642157 +2915 2818 -5266148.137347 +2925 2818 -11948441.41664 +2926 2818 -46658897.27468 +2927 2818 -32026328.33686 +2928 2818 11944444.44837 +2929 2818 39350079.73598 +2930 2818 -4237631.002181 +2940 2818 -11944444.44837 +2941 2818 -16455848.40155 +2942 2818 -8163229.232496 +2943 2818 -11950439.90079 +2944 2818 -40768202.4791 +2945 2818 -17881456.80322 +2946 2818 14339328.79045 +2947 2818 -19430363.65775 +2948 2818 17403019.36621 +2819 2819 498731997.6738 +2829 2819 18780080.99371 +2830 2819 9394305.301468 +2831 2819 -20006934.4106 +2832 2819 -20238012.48793 +2833 2819 -23543989.15986 +2834 2819 -9089122.520285 +2835 2819 -24551711.41742 +2836 2819 12249683.85902 +2837 2819 16232222.45521 +2913 2819 6582676.791154 +2914 2819 -7899222.206021 +2915 2819 4086353.712421 +2925 2819 -8007766.485252 +2926 2819 -33293672.07046 +2927 2819 -17559666.33271 +2928 2819 -4818855.100867 +2929 2819 -21102266.9381 +2930 2819 -61666013.98076 +2940 2819 -8444910.309145 +2941 2819 -8163229.232496 +2942 2819 -10570710.68328 +2943 2819 -57630268.59944 +2944 2819 -16401283.68257 +2945 2819 -82291258.12151 +2946 2819 -21754203.08579 +2947 2819 11602012.9108 +2948 2819 -51814303.08735 +2820 2820 801867013.5374 +2821 2820 2.598762512207e-05 +2822 2820 7037129.799195 +2823 2820 92970237.73849 +2824 2820 -1.010298728943e-05 +2825 2820 1759282.450673 +2838 2820 -181853790.138 +2839 2820 3.248453140259e-06 +2840 2820 -3518564.899638 +2841 2820 -72853540.65349 +2842 2820 47777777.76992 +2843 2820 -20539363.4444 +2916 2820 -71968136.03531 +2917 2820 4.157423973083e-06 +2918 2820 51943969.87703 +2919 2820 -29817851.87049 +2920 2820 -11944444.44837 +2921 2820 17900923.03284 +2931 2820 88895212.80375 +2932 2820 4.112720489502e-06 +2933 2820 1759282.450699 +2934 2820 -25612922.63328 +2935 2820 -1.080334186554e-05 +2936 2820 439820.6129002 +2949 2820 -74762019.75572 +2950 2820 2.533197402954e-07 +2951 2820 -53703252.3277 +2952 2820 -30778677.45218 +2953 2820 11944444.44836 +2954 2820 -18340743.64572 +2821 2821 687193460.8868 +2822 2821 -84443331.25708 +2823 2821 -1.019239425659e-05 +2824 2821 -88585023.89729 +2825 2821 42221665.62855 +2838 2821 3.069639205933e-06 +2839 2821 28369859.6463 +2840 2821 -21110832.82467 +2841 2821 47777777.76992 +2842 2821 -58519346.56511 +2843 2821 11505416.41223 +2916 2821 3.337860107422e-06 +2917 2821 -19412223.56332 +2918 2821 -5277708.208769 +2919 2821 -11944444.44837 +2920 2821 -26234303.34662 +2921 2821 12913159.66331 +2931 2821 4.351139068604e-06 +2932 2821 60226824.62697 +2933 2821 -21110832.82468 +2934 2821 -9.95397567749e-06 +2935 2821 -71001738.06458 +2936 2821 52813749.73867 +2949 2821 -8.195638656616e-07 +2950 2821 -22206107.28377 +2951 2821 -5277708.20877 +2952 2821 11944444.44836 +2953 2821 -27195128.92833 +2954 2821 13440937.44126 +2822 2822 766546241.681 +2823 2822 1759282.450673 +2824 2822 42221665.62855 +2825 2822 57866058.65466 +2838 2822 -3518564.899638 +2839 2822 -21110832.82467 +2840 2822 48052583.38233 +2841 2822 -20803252.33311 +2842 2822 11716527.5232 +2843 2822 -22805384.02253 +2916 2822 51680080.98832 +2917 2822 -5277708.208769 +2918 2822 -58666023.42418 +2919 2822 17900923.03284 +2920 2822 12913159.66331 +2921 2822 -36646590.5368 +2931 2822 1759282.450699 +2932 2822 -21110832.82468 +2933 2822 -105887547.9636 +2934 2822 439820.6129005 +2935 2822 52602638.6277 +2936 2822 -115814770.8741 +2949 2822 -53439363.43899 +2950 2822 -5277708.20877 +2951 2822 -66116380.01208 +2952 2822 -18340743.64572 +2953 2822 13440937.44126 +2954 2822 -39208792.08802 +2823 2823 801867013.5374 +2824 2823 2.598762512207e-05 +2825 2823 7037129.799195 +2826 2823 92970237.73849 +2827 2823 -1.010298728943e-05 +2828 2823 1759282.450673 +2838 2823 -71804122.04904 +2839 2823 -47777777.76993 +2840 2823 19043969.88243 +2841 2823 -181853790.138 +2842 2823 3.248453140259e-06 +2843 2823 -3518564.899638 +2844 2823 -72853540.65349 +2845 2823 47777777.76992 +2846 2823 -20539363.4444 +2916 2823 -19603280.6462 +2917 2823 11944444.44837 +2918 2823 8005089.696258 +2919 2823 -71968136.03531 +2920 2823 4.157423973083e-06 +2921 2823 51943969.87703 +2922 2823 -29817851.87049 +2923 2823 -11944444.44837 +2924 2823 17900923.03284 +2931 2823 16294780.8482 +2932 2823 4.217028617859e-06 +2933 2823 439820.6128852 +2934 2823 88895212.80375 +2935 2823 4.112720489502e-06 +2936 2823 1759282.450699 +2937 2823 -25612922.63328 +2938 2823 -1.080334186554e-05 +2939 2823 439820.6129002 +2949 2823 -20039396.92541 +2950 2823 -11944444.44837 +2951 2823 -8444910.309145 +2952 2823 -74762019.75572 +2953 2823 2.533197402954e-07 +2954 2823 -53703252.3277 +2955 2823 -30778677.45218 +2956 2823 11944444.44836 +2957 2823 -18340743.64572 +2824 2824 687193460.8868 +2825 2824 -84443331.25708 +2826 2824 -1.019239425659e-05 +2827 2824 -88585023.89729 +2828 2824 42221665.62855 +2838 2824 -47777777.76993 +2839 2824 -57469927.96065 +2840 2824 9605416.412441 +2841 2824 3.069639205933e-06 +2842 2824 28369859.6463 +2843 2824 -21110832.82467 +2844 2824 47777777.76992 +2845 2824 -58519346.56511 +2846 2824 11505416.41223 +2916 2824 11944444.44837 +2917 2824 -16019732.12234 +2918 2824 -7635451.454545 +2919 2824 3.337860107422e-06 +2920 2824 -19412223.56332 +2921 2824 -5277708.208769 +2922 2824 -11944444.44837 +2923 2824 -26234303.34662 +2924 2824 12913159.66331 +2931 2824 5.125999450684e-06 +2932 2824 -29094034.58311 +2933 2824 -31702916.914 +2934 2824 4.351139068604e-06 +2935 2824 60226824.62697 +2936 2824 -21110832.82468 +2937 2824 -9.95397567749e-06 +2938 2824 -71001738.06458 +2939 2824 52813749.73867 +2949 2824 -11944444.44837 +2950 2824 -16455848.40155 +2951 2824 -8163229.232496 +2952 2824 -8.195638656616e-07 +2953 2824 -22206107.28377 +2954 2824 -5277708.20877 +2955 2824 11944444.44836 +2956 2824 -27195128.92833 +2957 2824 13440937.44126 +2825 2825 766546241.681 +2826 2825 1759282.450673 +2827 2825 42221665.62855 +2828 2825 57866058.65466 +2838 2825 18780080.99371 +2839 2825 9394305.301468 +2840 2825 -20006934.4106 +2841 2825 -3518564.899638 +2842 2825 -21110832.82467 +2843 2825 48052583.38233 +2844 2825 -20803252.33311 +2845 2825 11716527.5232 +2846 2825 -22805384.02253 +2916 2825 8005089.696258 +2917 2825 -7635451.454545 +2918 2825 -9407733.938713 +2919 2825 51680080.98832 +2920 2825 -5277708.208769 +2921 2825 -58666023.42418 +2922 2825 17900923.03284 +2923 2825 12913159.66331 +2924 2825 -36646590.5368 +2931 2825 439820.6128855 +2932 2825 -31491805.80303 +2933 2825 -4060894.923526 +2934 2825 1759282.450699 +2935 2825 -21110832.82468 +2936 2825 -105887547.9636 +2937 2825 439820.6129005 +2938 2825 52602638.6277 +2939 2825 -115814770.8741 +2949 2825 -8444910.309145 +2950 2825 -8163229.232496 +2951 2825 -10570710.68328 +2952 2825 -53439363.43899 +2953 2825 -5277708.20877 +2954 2825 -66116380.01208 +2955 2825 -18340743.64572 +2956 2825 13440937.44126 +2957 2825 -39208792.08802 +2826 2826 801867013.5374 +2827 2826 2.598762512207e-05 +2828 2826 7037129.799195 +2829 2826 92970237.73849 +2830 2826 -1.010298728943e-05 +2831 2826 1759282.450673 +2841 2826 -71804122.04904 +2842 2826 -47777777.76993 +2843 2826 19043969.88243 +2844 2826 -181853790.138 +2845 2826 3.248453140259e-06 +2846 2826 -3518564.899638 +2847 2826 -72853540.65349 +2848 2826 47777777.76992 +2849 2826 -20539363.4444 +2919 2826 -19603280.6462 +2920 2826 11944444.44837 +2921 2826 8005089.696258 +2922 2826 -71968136.03531 +2923 2826 4.157423973083e-06 +2924 2826 51943969.87703 +2925 2826 -29817851.87049 +2926 2826 -11944444.44837 +2927 2826 17900923.03284 +2934 2826 16294780.8482 +2935 2826 4.217028617859e-06 +2936 2826 439820.6128852 +2937 2826 88895212.80375 +2938 2826 4.112720489502e-06 +2939 2826 1759282.450699 +2940 2826 -25612922.63328 +2941 2826 -1.080334186554e-05 +2942 2826 439820.6129002 +2952 2826 -20039396.92541 +2953 2826 -11944444.44837 +2954 2826 -8444910.309145 +2955 2826 -74762019.75572 +2956 2826 2.533197402954e-07 +2957 2826 -53703252.3277 +2958 2826 -30778677.45218 +2959 2826 11944444.44836 +2960 2826 -18340743.64572 +2827 2827 687193460.8868 +2828 2827 -84443331.25708 +2829 2827 -1.019239425659e-05 +2830 2827 -88585023.89729 +2831 2827 42221665.62855 +2841 2827 -47777777.76993 +2842 2827 -57469927.96065 +2843 2827 9605416.412441 +2844 2827 3.069639205933e-06 +2845 2827 28369859.6463 +2846 2827 -21110832.82467 +2847 2827 47777777.76992 +2848 2827 -58519346.56511 +2849 2827 11505416.41223 +2919 2827 11944444.44837 +2920 2827 -16019732.12234 +2921 2827 -7635451.454545 +2922 2827 3.337860107422e-06 +2923 2827 -19412223.56332 +2924 2827 -5277708.208769 +2925 2827 -11944444.44837 +2926 2827 -26234303.34662 +2927 2827 12913159.66331 +2934 2827 5.125999450684e-06 +2935 2827 -29094034.58311 +2936 2827 -31702916.914 +2937 2827 4.351139068604e-06 +2938 2827 60226824.62697 +2939 2827 -21110832.82468 +2940 2827 -9.95397567749e-06 +2941 2827 -71001738.06458 +2942 2827 52813749.73867 +2952 2827 -11944444.44837 +2953 2827 -16455848.40155 +2954 2827 -8163229.232496 +2955 2827 -8.195638656616e-07 +2956 2827 -22206107.28377 +2957 2827 -5277708.20877 +2958 2827 11944444.44836 +2959 2827 -27195128.92833 +2960 2827 13440937.44126 +2828 2828 766546241.681 +2829 2828 1759282.450673 +2830 2828 42221665.62855 +2831 2828 57866058.65466 +2841 2828 18780080.99371 +2842 2828 9394305.301468 +2843 2828 -20006934.4106 +2844 2828 -3518564.899638 +2845 2828 -21110832.82467 +2846 2828 48052583.38233 +2847 2828 -20803252.33311 +2848 2828 11716527.5232 +2849 2828 -22805384.02253 +2919 2828 8005089.696258 +2920 2828 -7635451.454545 +2921 2828 -9407733.938713 +2922 2828 51680080.98832 +2923 2828 -5277708.208769 +2924 2828 -58666023.42418 +2925 2828 17900923.03284 +2926 2828 12913159.66331 +2927 2828 -36646590.5368 +2934 2828 439820.6128855 +2935 2828 -31491805.80303 +2936 2828 -4060894.923526 +2937 2828 1759282.450699 +2938 2828 -21110832.82468 +2939 2828 -105887547.9636 +2940 2828 439820.6129005 +2941 2828 52602638.6277 +2942 2828 -115814770.8741 +2952 2828 -8444910.309145 +2953 2828 -8163229.232496 +2954 2828 -10570710.68328 +2955 2828 -53439363.43899 +2956 2828 -5277708.20877 +2957 2828 -66116380.01208 +2958 2828 -18340743.64572 +2959 2828 13440937.44126 +2960 2828 -39208792.08802 +2829 2829 801867013.5374 +2830 2829 2.598762512207e-05 +2831 2829 7037129.799195 +2832 2829 92970237.73849 +2833 2829 -1.010298728943e-05 +2834 2829 1759282.450673 +2844 2829 -71804122.04904 +2845 2829 -47777777.76993 +2846 2829 19043969.88243 +2847 2829 -181853790.138 +2848 2829 3.248453140259e-06 +2849 2829 -3518564.899638 +2850 2829 -72853540.65349 +2851 2829 47777777.76992 +2852 2829 -20539363.4444 +2922 2829 -19603280.6462 +2923 2829 11944444.44837 +2924 2829 8005089.696258 +2925 2829 -71968136.03531 +2926 2829 4.157423973083e-06 +2927 2829 51943969.87703 +2928 2829 -29817851.87049 +2929 2829 -11944444.44837 +2930 2829 17900923.03284 +2937 2829 16294780.8482 +2938 2829 4.217028617859e-06 +2939 2829 439820.6128852 +2940 2829 88895212.80375 +2941 2829 4.112720489502e-06 +2942 2829 1759282.450699 +2943 2829 -25612922.63328 +2944 2829 -1.080334186554e-05 +2945 2829 439820.6129002 +2955 2829 -20039396.92541 +2956 2829 -11944444.44837 +2957 2829 -8444910.309145 +2958 2829 -74762019.75572 +2959 2829 2.533197402954e-07 +2960 2829 -53703252.3277 +2961 2829 -30778677.45218 +2962 2829 11944444.44836 +2963 2829 -18340743.64572 +2830 2830 687193460.8868 +2831 2830 -84443331.25708 +2832 2830 -1.019239425659e-05 +2833 2830 -88585023.89729 +2834 2830 42221665.62855 +2844 2830 -47777777.76993 +2845 2830 -57469927.96065 +2846 2830 9605416.412441 +2847 2830 3.069639205933e-06 +2848 2830 28369859.6463 +2849 2830 -21110832.82467 +2850 2830 47777777.76992 +2851 2830 -58519346.56511 +2852 2830 11505416.41223 +2922 2830 11944444.44837 +2923 2830 -16019732.12234 +2924 2830 -7635451.454545 +2925 2830 3.337860107422e-06 +2926 2830 -19412223.56332 +2927 2830 -5277708.208769 +2928 2830 -11944444.44837 +2929 2830 -26234303.34662 +2930 2830 12913159.66331 +2937 2830 5.125999450684e-06 +2938 2830 -29094034.58311 +2939 2830 -31702916.914 +2940 2830 4.351139068604e-06 +2941 2830 60226824.62697 +2942 2830 -21110832.82468 +2943 2830 -9.95397567749e-06 +2944 2830 -71001738.06458 +2945 2830 52813749.73867 +2955 2830 -11944444.44837 +2956 2830 -16455848.40155 +2957 2830 -8163229.232496 +2958 2830 -8.195638656616e-07 +2959 2830 -22206107.28377 +2960 2830 -5277708.20877 +2961 2830 11944444.44836 +2962 2830 -27195128.92833 +2963 2830 13440937.44126 +2831 2831 766546241.681 +2832 2831 1759282.450673 +2833 2831 42221665.62855 +2834 2831 57866058.65466 +2844 2831 18780080.99371 +2845 2831 9394305.301468 +2846 2831 -20006934.4106 +2847 2831 -3518564.899638 +2848 2831 -21110832.82467 +2849 2831 48052583.38233 +2850 2831 -20803252.33311 +2851 2831 11716527.5232 +2852 2831 -22805384.02253 +2922 2831 8005089.696258 +2923 2831 -7635451.454545 +2924 2831 -9407733.938713 +2925 2831 51680080.98832 +2926 2831 -5277708.208769 +2927 2831 -58666023.42418 +2928 2831 17900923.03284 +2929 2831 12913159.66331 +2930 2831 -36646590.5368 +2937 2831 439820.6128855 +2938 2831 -31491805.80303 +2939 2831 -4060894.923526 +2940 2831 1759282.450699 +2941 2831 -21110832.82468 +2942 2831 -105887547.9636 +2943 2831 439820.6129005 +2944 2831 52602638.6277 +2945 2831 -115814770.8741 +2955 2831 -8444910.309145 +2956 2831 -8163229.232496 +2957 2831 -10570710.68328 +2958 2831 -53439363.43899 +2959 2831 -5277708.20877 +2960 2831 -66116380.01208 +2961 2831 -18340743.64572 +2962 2831 13440937.44126 +2963 2831 -39208792.08802 +2832 2832 866925828.5346 +2833 2832 47817747.45269 +2834 2832 23749660.20008 +2835 2832 14263474.74723 +2836 2832 -47793765.64302 +2837 2832 20546059.94785 +2847 2832 -71804122.04904 +2848 2832 -47777777.76993 +2849 2832 19043969.88243 +2850 2832 -181853790.138 +2851 2832 3.248453140259e-06 +2852 2832 -3518564.899638 +2853 2832 -72853540.65349 +2854 2832 47777777.76992 +2855 2832 -20539363.4444 +2925 2832 -19603280.6462 +2926 2832 11944444.44837 +2927 2832 8005089.696258 +2928 2832 -85740387.93072 +2929 2832 -11950439.90077 +2930 2832 47775096.06898 +2940 2832 16294780.8482 +2941 2832 4.217028617859e-06 +2942 2832 439820.6128852 +2943 2832 112006329.4708 +2944 2832 11954436.86906 +2945 2832 5935349.843305 +2946 2832 -36979414.9719 +2947 2832 -11948441.41664 +2948 2832 18346879.03149 +2958 2832 -20039396.92541 +2959 2832 -11944444.44837 +2960 2832 -8444910.309145 +2961 2832 -74762019.75572 +2962 2832 2.533197402954e-07 +2963 2832 -53703252.3277 +2964 2832 -30778677.45218 +2965 2832 11944444.44836 +2966 2832 -18340743.64572 +2833 2833 737900094.3577 +2834 2833 -65443918.48946 +2835 2833 -47801759.57957 +2836 2833 -152989568.1247 +2837 2833 35049537.95506 +2847 2833 -47777777.76993 +2848 2833 -57469927.96065 +2849 2833 9605416.412441 +2850 2833 3.069639205933e-06 +2851 2833 28369859.6463 +2852 2833 -21110832.82467 +2853 2833 47777777.76992 +2854 2833 -58519346.56511 +2855 2833 11505416.41223 +2925 2833 11944444.44837 +2926 2833 -16019732.12234 +2927 2833 -7635451.454545 +2928 2833 -11948441.41664 +2929 2833 -29588436.2443 +2930 2833 4682155.144749 +2940 2833 5.125999450684e-06 +2941 2833 -29094034.58311 +2942 2833 -31702916.914 +2943 2833 11954436.86906 +2944 2833 79749895.91067 +2945 2833 -16362631.77783 +2946 2833 -11950439.90078 +2947 2833 -78792675.71048 +2948 2833 51029508.03613 +2958 2833 -11944444.44837 +2959 2833 -16455848.40155 +2960 2833 -8163229.232496 +2961 2833 -8.195638656616e-07 +2962 2833 -22206107.28377 +2963 2833 -5277708.20877 +2964 2833 11944444.44836 +2965 2833 -27195128.92833 +2966 2833 13440937.44126 +2834 2834 768350518.5004 +2835 2834 20813297.08829 +2836 2834 40963180.50213 +2837 2834 19484057.05595 +2847 2834 18780080.99371 +2848 2834 9394305.301468 +2849 2834 -20006934.4106 +2850 2834 -3518564.899638 +2851 2834 -21110832.82467 +2852 2834 48052583.38233 +2853 2834 -20803252.33311 +2854 2834 11716527.5232 +2855 2834 -22805384.02253 +2925 2834 8005089.696258 +2926 2834 -7635451.454545 +2927 2834 -9407733.938713 +2928 2834 47510397.70207 +2929 2834 3205506.989851 +2930 2834 -52478548.16204 +2940 2834 439820.6128855 +2941 2834 -31491805.80303 +2942 2834 -4060894.923526 +2943 2834 5939756.113784 +2944 2834 -16359106.80793 +2945 2834 -87179377.66603 +2946 2834 18349946.72438 +2947 2834 52296851.6274 +2948 2834 -103249742.1615 +2958 2834 -8444910.309145 +2959 2834 -8163229.232496 +2960 2834 -10570710.68328 +2961 2834 -53439363.43899 +2962 2834 -5277708.20877 +2963 2834 -66116380.01208 +2964 2834 -18340743.64572 +2965 2834 13440937.44126 +2966 2834 -39208792.08802 +2835 2835 411984836.6329 +2836 2835 -7936152.30026 +2837 2835 -12597657.48158 +2850 2835 -71804122.04904 +2851 2835 -47777777.76993 +2852 2835 19043969.88243 +2853 2835 -138080718.2873 +2854 2835 7859319.261471 +2855 2835 -1118612.233799 +2856 2835 -59031787.7105 +2857 2835 38299055.25473 +2858 2835 -3172177.802272 +2928 2835 1532382.642161 +2929 2835 14339328.79045 +2930 2835 9874015.186731 +2943 2835 -4845636.536104 +2944 2835 -11950439.90078 +2945 2835 -8009104.879749 +2946 2835 45154799.16275 +2947 2835 -1984038.076042 +2948 2835 5318188.302819 +2961 2835 -20039396.92541 +2962 2835 -11944444.44837 +2963 2835 -8444910.309145 +2964 2835 -54446261.20618 +2965 2835 1964829.816336 +2966 2835 -37868990.52104 +2967 2835 -20832796.07979 +2968 2835 9574763.8184 +2969 2835 -4947522.887458 +2836 2836 472335181.7353 +2837 2836 -60215952.15695 +2850 2836 -47777777.76993 +2851 2836 -57469927.96065 +2852 2836 9605416.412441 +2853 2836 7820902.742076 +2854 2836 61644059.27118 +2855 2836 -13951237.99313 +2856 2836 57448582.8821 +2857 2836 -166188061.588 +2858 2836 10078720.53082 +2928 2836 9559552.526969 +2929 2836 1532382.642157 +2930 2836 -5266148.137347 +2943 2836 -11948441.41664 +2944 2836 -46658897.27468 +2945 2836 -32026328.33686 +2946 2836 -1984038.076043 +2947 2836 60242385.44579 +2948 2836 -8284128.881153 +2961 2836 -11944444.44837 +2962 2836 -16455848.40155 +2963 2836 -8163229.232496 +2964 2836 1955225.686481 +2965 2836 -4515066.791966 +2966 2836 -1847868.948734 +2967 2836 14362145.7276 +2968 2836 -47621864.56235 +2969 2836 20366850.75772 +2837 2837 433150810.8594 +2850 2837 18780080.99371 +2851 2837 9394305.301468 +2852 2837 -20006934.4106 +2853 2837 -7976747.091482 +2854 2837 -13738986.98741 +2855 2837 37185048.73447 +2856 2837 -4758266.703408 +2857 2837 9231286.830788 +2858 2837 -50261826.68389 +2928 2837 6582676.791154 +2929 2837 -7899222.206021 +2930 2837 4086353.712421 +2943 2837 -8007766.485252 +2944 2837 -33293672.07046 +2945 2837 -17559666.33271 +2946 2837 -9638402.083643 +2947 2837 -20236111.15782 +2948 2837 -45956057.35504 +2961 2837 -8444910.309145 +2962 2837 -8163229.232496 +2963 2837 -10570710.68328 +2964 2837 -39187801.2437 +2965 2837 -1627591.468903 +2966 2837 -43839955.45809 +2967 2837 -7421284.331187 +2968 2837 18388546.96739 +2969 2837 -28765054.39688 +2838 2838 801867013.5374 +2839 2838 2.598762512207e-05 +2840 2838 7037129.799195 +2841 2838 92970237.73849 +2842 2838 -1.010298728943e-05 +2843 2838 1759282.450673 +2859 2838 -181853790.138 +2860 2838 3.248453140259e-06 +2861 2838 -3518564.899638 +2862 2838 -72853540.65349 +2863 2838 47777777.76992 +2864 2838 -20539363.4444 +2931 2838 -71968136.03531 +2932 2838 4.157423973083e-06 +2933 2838 51943969.87703 +2934 2838 -29817851.87049 +2935 2838 -11944444.44837 +2936 2838 17900923.03284 +2949 2838 88895212.80375 +2950 2838 4.112720489502e-06 +2951 2838 1759282.450699 +2952 2838 -25612922.63328 +2953 2838 -1.080334186554e-05 +2954 2838 439820.6129002 +2970 2838 -74762019.75572 +2971 2838 2.533197402954e-07 +2972 2838 -53703252.3277 +2973 2838 -30778677.45218 +2974 2838 11944444.44836 +2975 2838 -18340743.64572 +2839 2839 687193460.8868 +2840 2839 -84443331.25708 +2841 2839 -1.019239425659e-05 +2842 2839 -88585023.89729 +2843 2839 42221665.62855 +2859 2839 3.069639205933e-06 +2860 2839 28369859.6463 +2861 2839 -21110832.82467 +2862 2839 47777777.76992 +2863 2839 -58519346.56511 +2864 2839 11505416.41223 +2931 2839 3.337860107422e-06 +2932 2839 -19412223.56332 +2933 2839 -5277708.208769 +2934 2839 -11944444.44837 +2935 2839 -26234303.34662 +2936 2839 12913159.66331 +2949 2839 4.351139068604e-06 +2950 2839 60226824.62697 +2951 2839 -21110832.82468 +2952 2839 -9.95397567749e-06 +2953 2839 -71001738.06458 +2954 2839 52813749.73867 +2970 2839 -8.195638656616e-07 +2971 2839 -22206107.28377 +2972 2839 -5277708.20877 +2973 2839 11944444.44836 +2974 2839 -27195128.92833 +2975 2839 13440937.44126 +2840 2840 766546241.681 +2841 2840 1759282.450673 +2842 2840 42221665.62855 +2843 2840 57866058.65466 +2859 2840 -3518564.899638 +2860 2840 -21110832.82467 +2861 2840 48052583.38233 +2862 2840 -20803252.33311 +2863 2840 11716527.5232 +2864 2840 -22805384.02253 +2931 2840 51680080.98832 +2932 2840 -5277708.208769 +2933 2840 -58666023.42418 +2934 2840 17900923.03284 +2935 2840 12913159.66331 +2936 2840 -36646590.5368 +2949 2840 1759282.450699 +2950 2840 -21110832.82468 +2951 2840 -105887547.9636 +2952 2840 439820.6129005 +2953 2840 52602638.6277 +2954 2840 -115814770.8741 +2970 2840 -53439363.43899 +2971 2840 -5277708.20877 +2972 2840 -66116380.01208 +2973 2840 -18340743.64572 +2974 2840 13440937.44126 +2975 2840 -39208792.08802 +2841 2841 801867013.5374 +2842 2841 2.598762512207e-05 +2843 2841 7037129.799195 +2844 2841 92970237.73849 +2845 2841 -1.010298728943e-05 +2846 2841 1759282.450673 +2859 2841 -71804122.04904 +2860 2841 -47777777.76993 +2861 2841 19043969.88243 +2862 2841 -181853790.138 +2863 2841 3.248453140259e-06 +2864 2841 -3518564.899638 +2865 2841 -72853540.65349 +2866 2841 47777777.76992 +2867 2841 -20539363.4444 +2931 2841 -19603280.6462 +2932 2841 11944444.44837 +2933 2841 8005089.696258 +2934 2841 -71968136.03531 +2935 2841 4.157423973083e-06 +2936 2841 51943969.87703 +2937 2841 -29817851.87049 +2938 2841 -11944444.44837 +2939 2841 17900923.03284 +2949 2841 16294780.8482 +2950 2841 4.217028617859e-06 +2951 2841 439820.6128852 +2952 2841 88895212.80375 +2953 2841 4.112720489502e-06 +2954 2841 1759282.450699 +2955 2841 -25612922.63328 +2956 2841 -1.080334186554e-05 +2957 2841 439820.6129002 +2970 2841 -20039396.92541 +2971 2841 -11944444.44837 +2972 2841 -8444910.309145 +2973 2841 -74762019.75572 +2974 2841 2.533197402954e-07 +2975 2841 -53703252.3277 +2976 2841 -30778677.45218 +2977 2841 11944444.44836 +2978 2841 -18340743.64572 +2842 2842 687193460.8868 +2843 2842 -84443331.25708 +2844 2842 -1.019239425659e-05 +2845 2842 -88585023.89729 +2846 2842 42221665.62855 +2859 2842 -47777777.76993 +2860 2842 -57469927.96065 +2861 2842 9605416.412441 +2862 2842 3.069639205933e-06 +2863 2842 28369859.6463 +2864 2842 -21110832.82467 +2865 2842 47777777.76992 +2866 2842 -58519346.56511 +2867 2842 11505416.41223 +2931 2842 11944444.44837 +2932 2842 -16019732.12234 +2933 2842 -7635451.454545 +2934 2842 3.337860107422e-06 +2935 2842 -19412223.56332 +2936 2842 -5277708.208769 +2937 2842 -11944444.44837 +2938 2842 -26234303.34662 +2939 2842 12913159.66331 +2949 2842 5.125999450684e-06 +2950 2842 -29094034.58311 +2951 2842 -31702916.914 +2952 2842 4.351139068604e-06 +2953 2842 60226824.62697 +2954 2842 -21110832.82468 +2955 2842 -9.95397567749e-06 +2956 2842 -71001738.06458 +2957 2842 52813749.73867 +2970 2842 -11944444.44837 +2971 2842 -16455848.40155 +2972 2842 -8163229.232496 +2973 2842 -8.195638656616e-07 +2974 2842 -22206107.28377 +2975 2842 -5277708.20877 +2976 2842 11944444.44836 +2977 2842 -27195128.92833 +2978 2842 13440937.44126 +2843 2843 766546241.681 +2844 2843 1759282.450673 +2845 2843 42221665.62855 +2846 2843 57866058.65466 +2859 2843 18780080.99371 +2860 2843 9394305.301468 +2861 2843 -20006934.4106 +2862 2843 -3518564.899638 +2863 2843 -21110832.82467 +2864 2843 48052583.38233 +2865 2843 -20803252.33311 +2866 2843 11716527.5232 +2867 2843 -22805384.02253 +2931 2843 8005089.696258 +2932 2843 -7635451.454545 +2933 2843 -9407733.938713 +2934 2843 51680080.98832 +2935 2843 -5277708.208769 +2936 2843 -58666023.42418 +2937 2843 17900923.03284 +2938 2843 12913159.66331 +2939 2843 -36646590.5368 +2949 2843 439820.6128855 +2950 2843 -31491805.80303 +2951 2843 -4060894.923526 +2952 2843 1759282.450699 +2953 2843 -21110832.82468 +2954 2843 -105887547.9636 +2955 2843 439820.6129005 +2956 2843 52602638.6277 +2957 2843 -115814770.8741 +2970 2843 -8444910.309145 +2971 2843 -8163229.232496 +2972 2843 -10570710.68328 +2973 2843 -53439363.43899 +2974 2843 -5277708.20877 +2975 2843 -66116380.01208 +2976 2843 -18340743.64572 +2977 2843 13440937.44126 +2978 2843 -39208792.08802 +2844 2844 801867013.5374 +2845 2844 2.598762512207e-05 +2846 2844 7037129.799195 +2847 2844 92970237.73849 +2848 2844 -1.010298728943e-05 +2849 2844 1759282.450673 +2862 2844 -71804122.04904 +2863 2844 -47777777.76993 +2864 2844 19043969.88243 +2865 2844 -181853790.138 +2866 2844 3.248453140259e-06 +2867 2844 -3518564.899638 +2868 2844 -72853540.65349 +2869 2844 47777777.76992 +2870 2844 -20539363.4444 +2934 2844 -19603280.6462 +2935 2844 11944444.44837 +2936 2844 8005089.696258 +2937 2844 -71968136.03531 +2938 2844 4.157423973083e-06 +2939 2844 51943969.87703 +2940 2844 -29817851.87049 +2941 2844 -11944444.44837 +2942 2844 17900923.03284 +2952 2844 16294780.8482 +2953 2844 4.217028617859e-06 +2954 2844 439820.6128852 +2955 2844 88895212.80375 +2956 2844 4.112720489502e-06 +2957 2844 1759282.450699 +2958 2844 -25612922.63328 +2959 2844 -1.080334186554e-05 +2960 2844 439820.6129002 +2973 2844 -20039396.92541 +2974 2844 -11944444.44837 +2975 2844 -8444910.309145 +2976 2844 -74762019.75572 +2977 2844 2.533197402954e-07 +2978 2844 -53703252.3277 +2979 2844 -30778677.45218 +2980 2844 11944444.44836 +2981 2844 -18340743.64572 +2845 2845 687193460.8868 +2846 2845 -84443331.25708 +2847 2845 -1.019239425659e-05 +2848 2845 -88585023.89729 +2849 2845 42221665.62855 +2862 2845 -47777777.76993 +2863 2845 -57469927.96065 +2864 2845 9605416.412441 +2865 2845 3.069639205933e-06 +2866 2845 28369859.6463 +2867 2845 -21110832.82467 +2868 2845 47777777.76992 +2869 2845 -58519346.56511 +2870 2845 11505416.41223 +2934 2845 11944444.44837 +2935 2845 -16019732.12234 +2936 2845 -7635451.454545 +2937 2845 3.337860107422e-06 +2938 2845 -19412223.56332 +2939 2845 -5277708.208769 +2940 2845 -11944444.44837 +2941 2845 -26234303.34662 +2942 2845 12913159.66331 +2952 2845 5.125999450684e-06 +2953 2845 -29094034.58311 +2954 2845 -31702916.914 +2955 2845 4.351139068604e-06 +2956 2845 60226824.62697 +2957 2845 -21110832.82468 +2958 2845 -9.95397567749e-06 +2959 2845 -71001738.06458 +2960 2845 52813749.73867 +2973 2845 -11944444.44837 +2974 2845 -16455848.40155 +2975 2845 -8163229.232496 +2976 2845 -8.195638656616e-07 +2977 2845 -22206107.28377 +2978 2845 -5277708.20877 +2979 2845 11944444.44836 +2980 2845 -27195128.92833 +2981 2845 13440937.44126 +2846 2846 766546241.681 +2847 2846 1759282.450673 +2848 2846 42221665.62855 +2849 2846 57866058.65466 +2862 2846 18780080.99371 +2863 2846 9394305.301468 +2864 2846 -20006934.4106 +2865 2846 -3518564.899638 +2866 2846 -21110832.82467 +2867 2846 48052583.38233 +2868 2846 -20803252.33311 +2869 2846 11716527.5232 +2870 2846 -22805384.02253 +2934 2846 8005089.696258 +2935 2846 -7635451.454545 +2936 2846 -9407733.938713 +2937 2846 51680080.98832 +2938 2846 -5277708.208769 +2939 2846 -58666023.42418 +2940 2846 17900923.03284 +2941 2846 12913159.66331 +2942 2846 -36646590.5368 +2952 2846 439820.6128855 +2953 2846 -31491805.80303 +2954 2846 -4060894.923526 +2955 2846 1759282.450699 +2956 2846 -21110832.82468 +2957 2846 -105887547.9636 +2958 2846 439820.6129005 +2959 2846 52602638.6277 +2960 2846 -115814770.8741 +2973 2846 -8444910.309145 +2974 2846 -8163229.232496 +2975 2846 -10570710.68328 +2976 2846 -53439363.43899 +2977 2846 -5277708.20877 +2978 2846 -66116380.01208 +2979 2846 -18340743.64572 +2980 2846 13440937.44126 +2981 2846 -39208792.08802 +2847 2847 801867013.5374 +2848 2847 2.598762512207e-05 +2849 2847 7037129.799195 +2850 2847 92970237.73849 +2851 2847 -1.010298728943e-05 +2852 2847 1759282.450673 +2865 2847 -71804122.04904 +2866 2847 -47777777.76993 +2867 2847 19043969.88243 +2868 2847 -181853790.138 +2869 2847 3.248453140259e-06 +2870 2847 -3518564.899638 +2871 2847 -72853540.65349 +2872 2847 47777777.76992 +2873 2847 -20539363.4444 +2937 2847 -19603280.6462 +2938 2847 11944444.44837 +2939 2847 8005089.696258 +2940 2847 -71968136.03531 +2941 2847 4.157423973083e-06 +2942 2847 51943969.87703 +2943 2847 -29817851.87049 +2944 2847 -11944444.44837 +2945 2847 17900923.03284 +2955 2847 16294780.8482 +2956 2847 4.217028617859e-06 +2957 2847 439820.6128852 +2958 2847 88895212.80375 +2959 2847 4.112720489502e-06 +2960 2847 1759282.450699 +2961 2847 -25612922.63328 +2962 2847 -1.080334186554e-05 +2963 2847 439820.6129002 +2976 2847 -20039396.92541 +2977 2847 -11944444.44837 +2978 2847 -8444910.309145 +2979 2847 -74762019.75572 +2980 2847 2.533197402954e-07 +2981 2847 -53703252.3277 +2982 2847 -30778677.45218 +2983 2847 11944444.44836 +2984 2847 -18340743.64572 +2848 2848 687193460.8868 +2849 2848 -84443331.25708 +2850 2848 -1.019239425659e-05 +2851 2848 -88585023.89729 +2852 2848 42221665.62855 +2865 2848 -47777777.76993 +2866 2848 -57469927.96065 +2867 2848 9605416.412441 +2868 2848 3.069639205933e-06 +2869 2848 28369859.6463 +2870 2848 -21110832.82467 +2871 2848 47777777.76992 +2872 2848 -58519346.56511 +2873 2848 11505416.41223 +2937 2848 11944444.44837 +2938 2848 -16019732.12234 +2939 2848 -7635451.454545 +2940 2848 3.337860107422e-06 +2941 2848 -19412223.56332 +2942 2848 -5277708.208769 +2943 2848 -11944444.44837 +2944 2848 -26234303.34662 +2945 2848 12913159.66331 +2955 2848 5.125999450684e-06 +2956 2848 -29094034.58311 +2957 2848 -31702916.914 +2958 2848 4.351139068604e-06 +2959 2848 60226824.62697 +2960 2848 -21110832.82468 +2961 2848 -9.95397567749e-06 +2962 2848 -71001738.06458 +2963 2848 52813749.73867 +2976 2848 -11944444.44837 +2977 2848 -16455848.40155 +2978 2848 -8163229.232496 +2979 2848 -8.195638656616e-07 +2980 2848 -22206107.28377 +2981 2848 -5277708.20877 +2982 2848 11944444.44836 +2983 2848 -27195128.92833 +2984 2848 13440937.44126 +2849 2849 766546241.681 +2850 2849 1759282.450673 +2851 2849 42221665.62855 +2852 2849 57866058.65466 +2865 2849 18780080.99371 +2866 2849 9394305.301468 +2867 2849 -20006934.4106 +2868 2849 -3518564.899638 +2869 2849 -21110832.82467 +2870 2849 48052583.38233 +2871 2849 -20803252.33311 +2872 2849 11716527.5232 +2873 2849 -22805384.02253 +2937 2849 8005089.696258 +2938 2849 -7635451.454545 +2939 2849 -9407733.938713 +2940 2849 51680080.98832 +2941 2849 -5277708.208769 +2942 2849 -58666023.42418 +2943 2849 17900923.03284 +2944 2849 12913159.66331 +2945 2849 -36646590.5368 +2955 2849 439820.6128855 +2956 2849 -31491805.80303 +2957 2849 -4060894.923526 +2958 2849 1759282.450699 +2959 2849 -21110832.82468 +2960 2849 -105887547.9636 +2961 2849 439820.6129005 +2962 2849 52602638.6277 +2963 2849 -115814770.8741 +2976 2849 -8444910.309145 +2977 2849 -8163229.232496 +2978 2849 -10570710.68328 +2979 2849 -53439363.43899 +2980 2849 -5277708.20877 +2981 2849 -66116380.01208 +2982 2849 -18340743.64572 +2983 2849 13440937.44126 +2984 2849 -39208792.08802 +2850 2850 801867013.5374 +2851 2850 2.598762512207e-05 +2852 2850 7037129.799195 +2853 2850 92970237.73849 +2854 2850 -1.010298728943e-05 +2855 2850 1759282.450673 +2868 2850 -71804122.04904 +2869 2850 -47777777.76993 +2870 2850 19043969.88243 +2871 2850 -181853790.138 +2872 2850 3.248453140259e-06 +2873 2850 -3518564.899638 +2874 2850 -72853540.65349 +2875 2850 47777777.76992 +2876 2850 -20539363.4444 +2940 2850 -19603280.6462 +2941 2850 11944444.44837 +2942 2850 8005089.696258 +2943 2850 -71968136.03531 +2944 2850 4.157423973083e-06 +2945 2850 51943969.87703 +2946 2850 -29817851.87049 +2947 2850 -11944444.44837 +2948 2850 17900923.03284 +2958 2850 16294780.8482 +2959 2850 4.217028617859e-06 +2960 2850 439820.6128852 +2961 2850 88895212.80375 +2962 2850 4.112720489502e-06 +2963 2850 1759282.450699 +2964 2850 -25612922.63328 +2965 2850 -1.080334186554e-05 +2966 2850 439820.6129002 +2979 2850 -20039396.92541 +2980 2850 -11944444.44837 +2981 2850 -8444910.309145 +2982 2850 -74762019.75572 +2983 2850 2.533197402954e-07 +2984 2850 -53703252.3277 +2985 2850 -30778677.45218 +2986 2850 11944444.44836 +2987 2850 -18340743.64572 +2851 2851 687193460.8868 +2852 2851 -84443331.25708 +2853 2851 -1.019239425659e-05 +2854 2851 -88585023.89729 +2855 2851 42221665.62855 +2868 2851 -47777777.76993 +2869 2851 -57469927.96065 +2870 2851 9605416.412441 +2871 2851 3.069639205933e-06 +2872 2851 28369859.6463 +2873 2851 -21110832.82467 +2874 2851 47777777.76992 +2875 2851 -58519346.56511 +2876 2851 11505416.41223 +2940 2851 11944444.44837 +2941 2851 -16019732.12234 +2942 2851 -7635451.454545 +2943 2851 3.337860107422e-06 +2944 2851 -19412223.56332 +2945 2851 -5277708.208769 +2946 2851 -11944444.44837 +2947 2851 -26234303.34662 +2948 2851 12913159.66331 +2958 2851 5.125999450684e-06 +2959 2851 -29094034.58311 +2960 2851 -31702916.914 +2961 2851 4.351139068604e-06 +2962 2851 60226824.62697 +2963 2851 -21110832.82468 +2964 2851 -9.95397567749e-06 +2965 2851 -71001738.06458 +2966 2851 52813749.73867 +2979 2851 -11944444.44837 +2980 2851 -16455848.40155 +2981 2851 -8163229.232496 +2982 2851 -8.195638656616e-07 +2983 2851 -22206107.28377 +2984 2851 -5277708.20877 +2985 2851 11944444.44836 +2986 2851 -27195128.92833 +2987 2851 13440937.44126 +2852 2852 766546241.681 +2853 2852 1759282.450673 +2854 2852 42221665.62855 +2855 2852 57866058.65466 +2868 2852 18780080.99371 +2869 2852 9394305.301468 +2870 2852 -20006934.4106 +2871 2852 -3518564.899638 +2872 2852 -21110832.82467 +2873 2852 48052583.38233 +2874 2852 -20803252.33311 +2875 2852 11716527.5232 +2876 2852 -22805384.02253 +2940 2852 8005089.696258 +2941 2852 -7635451.454545 +2942 2852 -9407733.938713 +2943 2852 51680080.98832 +2944 2852 -5277708.208769 +2945 2852 -58666023.42418 +2946 2852 17900923.03284 +2947 2852 12913159.66331 +2948 2852 -36646590.5368 +2958 2852 439820.6128855 +2959 2852 -31491805.80303 +2960 2852 -4060894.923526 +2961 2852 1759282.450699 +2962 2852 -21110832.82468 +2963 2852 -105887547.9636 +2964 2852 439820.6129005 +2965 2852 52602638.6277 +2966 2852 -115814770.8741 +2979 2852 -8444910.309145 +2980 2852 -8163229.232496 +2981 2852 -10570710.68328 +2982 2852 -53439363.43899 +2983 2852 -5277708.20877 +2984 2852 -66116380.01208 +2985 2852 -18340743.64572 +2986 2852 13440937.44126 +2987 2852 -39208792.08802 +2853 2853 697335433.5606 +2854 2853 13555993.81372 +2855 2853 6525546.760922 +2856 2853 -74181346.4655 +2857 2853 -78873671.67505 +2858 2853 4567537.813263 +2871 2853 -71804122.04904 +2872 2853 -47777777.76993 +2873 2853 19043969.88243 +2874 2853 -131767559.6882 +2875 2853 24583510.6723 +2876 2853 -724035.0559039 +2877 2853 -42859393.5392 +2878 2853 32913264.44696 +2879 2853 -2392743.794803 +2943 2853 -19603280.6462 +2944 2853 11944444.44837 +2945 2853 8005089.696258 +2946 2853 -51389094.80041 +2947 2853 1955225.686484 +2948 2853 35595150.68861 +2961 2853 16294780.8482 +2962 2853 4.217028617859e-06 +2963 2853 439820.6128852 +2964 2853 89751427.48146 +2965 2853 3388998.455101 +2966 2853 1627256.23664 +2967 2853 -37804191.87041 +2968 2853 -19718417.92848 +2969 2853 14356015.6679 +2982 2853 -20039396.92541 +2983 2853 -11944444.44837 +2984 2853 -8444910.309145 +2985 2853 -60532186.86274 +2986 2853 6145877.671103 +2987 2853 -45375800.4239 +2988 2853 -19078219.62127 +2989 2853 8228316.115794 +2990 2853 -6175963.728574 +2854 2854 738376280.1071 +2855 2854 -53461134.90695 +2856 2854 -78912088.19445 +2857 2854 -255911826.3266 +2858 2854 9575542.669736 +2871 2854 -47777777.76993 +2872 2854 -57469927.96065 +2873 2854 9605416.412441 +2874 2854 24583510.6723 +2875 2854 39087496.12151 +2876 2854 -11304599.7208 +2877 2854 32913264.44696 +2878 2854 -119862720.1338 +2879 2854 5385216.157707 +2943 2854 11944444.44837 +2944 2854 -16019732.12234 +2945 2854 -7635451.454545 +2946 2854 1964829.816337 +2947 2854 -1457900.386174 +2948 2854 -5080618.041869 +2961 2854 5.125999450684e-06 +2962 2854 -29094034.58311 +2963 2854 -31702916.914 +2964 2854 3388998.455098 +2965 2854 100011639.1232 +2966 2854 -13368588.23948 +2967 2854 -19728022.05833 +2968 2854 -83236811.85808 +2969 2854 44683227.92718 +2982 2854 -11944444.44837 +2983 2854 -16455848.40155 +2984 2854 -8163229.232496 +2985 2854 6145877.671102 +2986 2854 -17818422.88929 +2987 2854 3275933.400212 +2988 2854 8228316.115794 +2989 2854 -38329051.2794 +2990 2854 18012970.71223 +2855 2855 653768770.9707 +2856 2855 4834182.270174 +2857 2855 10420950.39671 +2858 2855 -44643768.23168 +2871 2855 18780080.99371 +2872 2855 9394305.301468 +2873 2855 -20006934.4106 +2874 2855 -7321257.277044 +2875 2855 -11515710.83187 +2876 2855 53866482.54874 +2877 2855 -2920521.572234 +2878 2855 5385216.157707 +2879 2855 -25206299.26693 +2943 2855 8005089.696258 +2944 2855 -7635451.454545 +2945 2855 -9407733.938713 +2946 2855 36913961.41127 +2947 2855 -5283969.107957 +2948 2855 -35687511.70929 +2961 2855 439820.6128855 +2962 2855 -31491805.80303 +2963 2855 -4060894.923526 +2964 2855 1636068.847779 +2965 2855 -13361537.70386 +2966 2855 -62110956.49564 +2967 2855 14361165.99813 +2968 2855 44679081.42414 +2969 2855 -62517889.38316 +2982 2855 -8444910.309145 +2983 2855 -8163229.232496 +2984 2855 -10570710.68328 +2985 2855 -46695244.86759 +2986 2855 3275933.401367 +2987 2855 -60107504.48815 +2988 2855 -6175963.728574 +2989 2855 18012970.71223 +2990 2855 -28603898.10301 +2856 2856 489618492.9753 +2857 2856 15356371.09326 +2858 2856 -2554275.615559 +2874 2856 -75484143.26592 +2875 2856 -45746472.96609 +2876 2856 2836938.039019 +2877 2856 -36927445.63632 +2878 2856 34495259.45832 +2879 2856 -1076002.638337 +2880 2856 61858293.65847 +2881 2856 -22880131.39438 +2882 2856 113380.0795472 +2883 2856 -20251607.2672 +2884 2856 40238479.12124 +2885 2856 -451510.9862942 +2946 2856 -17479931.67357 +2947 2856 14362145.7276 +2948 2856 5833486.609719 +2964 2856 -31941173.76503 +2965 2856 -19728022.05833 +2966 2856 -12009716.04913 +2967 2856 24089286.29196 +2968 2856 3839092.775206 +2969 2856 10350875.53811 +2985 2856 -25149760.01167 +2986 2856 -11436618.24716 +2987 2856 -12495973.82755 +2988 2856 -53221395.58403 +2989 2856 8623814.868827 +2990 2856 -52049556.20671 +2991 2856 -15616531.23755 +2992 2856 -5720032.851413 +2993 2856 11718275.57488 +2994 2856 -19138192.52839 +2995 2856 10059619.78527 +2996 2856 -12797947.19522 +2857 2857 684488409.1365 +2858 2857 -18295681.76298 +2874 2857 -45746472.96609 +2875 2857 -41552329.55583 +2876 2857 331278.0576664 +2877 2857 34495259.45832 +2878 2857 136816456.2173 +2879 2857 -3434058.65236 +2880 2857 -3769020.286411 +2881 2857 -30851528.21609 +2882 2857 417819.3012418 +2883 2857 40238479.12124 +2884 2857 -41200663.37894 +2885 2857 488013.3309756 +2946 2857 9574763.8184 +2947 2857 -44269000.15613 +2948 2857 -13244377.7058 +2964 2857 -19718417.92848 +2965 2857 -77373793.75269 +2966 2857 -39681478.38126 +2967 2857 3839092.775206 +2968 2857 72806765.35626 +2969 2857 -2276323.108396 +2985 2857 -11436618.24716 +2986 2857 -16666806.57997 +2987 2857 -10481763.82233 +2988 2857 8623814.868826 +2989 2857 -9785420.099232 +2990 2857 5243568.66829 +2991 2857 -942255.0720671 +2992 2857 -38793986.71761 +2993 2857 33437788.15322 +2994 2857 10059619.78527 +2995 2857 -24375456.5589 +2996 2857 16788670.00494 +2858 2858 600039923.4573 +2874 2858 2573049.150303 +2875 2858 120166.946694 +2876 2858 -12151033.88324 +2877 2858 -2131558.193719 +2878 2858 -3645169.763436 +2879 2858 150791187.3325 +2880 2858 -150508.8092947 +2881 2858 417819.3012417 +2882 2858 95574403.5202 +2883 2858 -715399.8750098 +2884 2858 488013.3309756 +2885 2858 22252331.25781 +2946 2858 3888991.073146 +2947 2858 -14800902.31119 +2948 2858 -19824082.64697 +2964 2858 -12006053.84798 +2965 2858 -39687207.82015 +2966 2858 -46883174.43545 +2967 2858 -10308568.90294 +2968 2858 -5821027.16094 +2969 2858 -112164251.0942 +2985 2858 -12495973.82755 +2986 2858 -10481763.82233 +2987 2858 -19781022.96801 +2988 2858 -52049556.20697 +2989 2858 5243568.669446 +2990 2858 -79607627.60272 +2991 2858 3593275.573656 +2992 2858 33437788.15322 +2993 2858 -58989344.86761 +2994 2858 -12797947.19522 +2995 2858 16788670.00494 +2996 2858 -31971025.74039 +2859 2859 400933506.7687 +2860 2859 1.347064971924e-05 +2861 2859 3518564.899597 +2862 2859 46502609.17931 +2863 2859 9555555.553979 +2864 2859 -2418969.885557 +2949 2859 -71968136.03531 +2950 2859 4.157423973083e-06 +2951 2859 51943969.87703 +2952 2859 -29817851.87049 +2953 2859 -11944444.44837 +2954 2859 17900923.03284 +2970 2859 44430116.09181 +2971 2859 1.907348632813e-06 +2972 2859 -10318414.32804 +2973 2859 -12806461.31664 +2974 2859 2388888.889668 +2975 2859 -3404256.361406 +2860 2860 343596730.4434 +2861 2860 -42221665.62853 +2862 2860 -9555555.55399 +2863 2860 -44275021.63857 +2864 2860 20899721.7032 +2949 2860 3.337860107422e-06 +2950 2860 -19412223.56332 +2951 2860 -5277708.208769 +2952 2860 -11944444.44837 +2953 2860 -26234303.34662 +2954 2860 12913159.66331 +2970 2860 2.861022949219e-06 +2971 2860 30095922.00342 +2972 2860 -10555416.41234 +2973 2860 -2388888.889678 +2974 2860 -35500869.03229 +2975 2860 26354097.09154 +2861 2861 383273120.8405 +2862 2861 5497696.779808 +2863 2861 21321943.92535 +2864 2861 28979670.15418 +2949 2861 51680080.98832 +2950 2861 -5277708.208769 +2951 2861 -58666023.42418 +2952 2861 17900923.03284 +2953 2861 12913159.66331 +2954 2861 -36646590.5368 +2970 2861 10758252.33516 +2971 2861 -10555416.41234 +2972 2861 -52990414.80866 +2973 2861 3844076.974307 +2974 2861 26354097.09164 +2975 2861 -57907385.43707 +2862 2862 400933506.7687 +2863 2862 1.347064971924e-05 +2864 2862 3518564.899597 +2865 2862 46502609.17931 +2866 2862 9555555.553979 +2867 2862 -2418969.885557 +2949 2862 -19603280.6462 +2950 2862 11944444.44837 +2951 2862 8005089.696258 +2952 2862 -71968136.03531 +2953 2862 4.157423973083e-06 +2954 2862 51943969.87703 +2955 2862 -29817851.87049 +2956 2862 -11944444.44837 +2957 2862 17900923.03284 +2970 2862 8147390.424101 +2971 2862 -2388888.889671 +2972 2862 -1425089.694098 +2973 2862 44430116.09181 +2974 2862 1.907348632813e-06 +2975 2862 -10318414.32804 +2976 2862 -12806461.31664 +2977 2862 2388888.889668 +2978 2862 -3404256.361406 +2863 2863 343596730.4434 +2864 2863 -42221665.62853 +2865 2863 -9555555.55399 +2866 2863 -44275021.63857 +2867 2863 20899721.7032 +2949 2863 11944444.44837 +2950 2863 -16019732.12234 +2951 2863 -7635451.454545 +2952 2863 3.337860107422e-06 +2953 2863 -19412223.56332 +2954 2863 -5277708.208769 +2955 2863 -11944444.44837 +2956 2863 -26234303.34662 +2957 2863 12913159.66331 +2970 2863 2388888.889676 +2971 2863 -14547017.29156 +2972 2863 -15798680.67921 +2973 2863 2.861022949219e-06 +2974 2863 30095922.00342 +2975 2863 -10555416.41234 +2976 2863 -2388888.889678 +2977 2863 -35500869.03229 +2978 2863 26354097.09154 +2864 2864 383273120.8405 +2865 2864 5497696.779808 +2866 2864 21321943.92535 +2867 2864 28979670.15418 +2949 2864 8005089.696258 +2950 2864 -7635451.454545 +2951 2864 -9407733.938713 +2952 2864 51680080.98832 +2953 2864 -5277708.208769 +2954 2864 -58666023.42418 +2955 2864 17900923.03284 +2956 2864 12913159.66331 +2957 2864 -36646590.5368 +2970 2864 1864910.306983 +2971 2864 -15798680.67931 +2972 2864 -2030447.461764 +2973 2864 10758252.33516 +2974 2864 -10555416.41234 +2975 2864 -52990414.80866 +2976 2864 3844076.974307 +2977 2864 26354097.09164 +2978 2864 -57907385.43707 +2865 2865 400933506.7687 +2866 2865 1.347064971924e-05 +2867 2865 3518564.899597 +2868 2865 46502609.17931 +2869 2865 9555555.553979 +2870 2865 -2418969.885557 +2952 2865 -19603280.6462 +2953 2865 11944444.44837 +2954 2865 8005089.696258 +2955 2865 -71968136.03531 +2956 2865 4.157423973083e-06 +2957 2865 51943969.87703 +2958 2865 -29817851.87049 +2959 2865 -11944444.44837 +2960 2865 17900923.03284 +2973 2865 8147390.424101 +2974 2865 -2388888.889671 +2975 2865 -1425089.694098 +2976 2865 44430116.09181 +2977 2865 1.907348632813e-06 +2978 2865 -10318414.32804 +2979 2865 -12806461.31664 +2980 2865 2388888.889668 +2981 2865 -3404256.361406 +2866 2866 343596730.4434 +2867 2866 -42221665.62853 +2868 2866 -9555555.55399 +2869 2866 -44275021.63857 +2870 2866 20899721.7032 +2952 2866 11944444.44837 +2953 2866 -16019732.12234 +2954 2866 -7635451.454545 +2955 2866 3.337860107422e-06 +2956 2866 -19412223.56332 +2957 2866 -5277708.208769 +2958 2866 -11944444.44837 +2959 2866 -26234303.34662 +2960 2866 12913159.66331 +2973 2866 2388888.889676 +2974 2866 -14547017.29156 +2975 2866 -15798680.67921 +2976 2866 2.861022949219e-06 +2977 2866 30095922.00342 +2978 2866 -10555416.41234 +2979 2866 -2388888.889678 +2980 2866 -35500869.03229 +2981 2866 26354097.09154 +2867 2867 383273120.8405 +2868 2867 5497696.779808 +2869 2867 21321943.92535 +2870 2867 28979670.15418 +2952 2867 8005089.696258 +2953 2867 -7635451.454545 +2954 2867 -9407733.938713 +2955 2867 51680080.98832 +2956 2867 -5277708.208769 +2957 2867 -58666023.42418 +2958 2867 17900923.03284 +2959 2867 12913159.66331 +2960 2867 -36646590.5368 +2973 2867 1864910.306983 +2974 2867 -15798680.67931 +2975 2867 -2030447.461764 +2976 2867 10758252.33516 +2977 2867 -10555416.41234 +2978 2867 -52990414.80866 +2979 2867 3844076.974307 +2980 2867 26354097.09164 +2981 2867 -57907385.43707 +2868 2868 400933506.7687 +2869 2868 1.347064971924e-05 +2870 2868 3518564.899597 +2871 2868 46502609.17931 +2872 2868 9555555.553979 +2873 2868 -2418969.885557 +2955 2868 -19603280.6462 +2956 2868 11944444.44837 +2957 2868 8005089.696258 +2958 2868 -71968136.03531 +2959 2868 4.157423973083e-06 +2960 2868 51943969.87703 +2961 2868 -29817851.87049 +2962 2868 -11944444.44837 +2963 2868 17900923.03284 +2976 2868 8147390.424101 +2977 2868 -2388888.889671 +2978 2868 -1425089.694098 +2979 2868 44430116.09181 +2980 2868 1.907348632813e-06 +2981 2868 -10318414.32804 +2982 2868 -12806461.31664 +2983 2868 2388888.889668 +2984 2868 -3404256.361406 +2869 2869 343596730.4434 +2870 2869 -42221665.62853 +2871 2869 -9555555.55399 +2872 2869 -44275021.63857 +2873 2869 20899721.7032 +2955 2869 11944444.44837 +2956 2869 -16019732.12234 +2957 2869 -7635451.454545 +2958 2869 3.337860107422e-06 +2959 2869 -19412223.56332 +2960 2869 -5277708.208769 +2961 2869 -11944444.44837 +2962 2869 -26234303.34662 +2963 2869 12913159.66331 +2976 2869 2388888.889676 +2977 2869 -14547017.29156 +2978 2869 -15798680.67921 +2979 2869 2.861022949219e-06 +2980 2869 30095922.00342 +2981 2869 -10555416.41234 +2982 2869 -2388888.889678 +2983 2869 -35500869.03229 +2984 2869 26354097.09154 +2870 2870 383273120.8405 +2871 2870 5497696.779808 +2872 2870 21321943.92535 +2873 2870 28979670.15418 +2955 2870 8005089.696258 +2956 2870 -7635451.454545 +2957 2870 -9407733.938713 +2958 2870 51680080.98832 +2959 2870 -5277708.208769 +2960 2870 -58666023.42418 +2961 2870 17900923.03284 +2962 2870 12913159.66331 +2963 2870 -36646590.5368 +2976 2870 1864910.306983 +2977 2870 -15798680.67931 +2978 2870 -2030447.461764 +2979 2870 10758252.33516 +2980 2870 -10555416.41234 +2981 2870 -52990414.80866 +2982 2870 3844076.974307 +2983 2870 26354097.09164 +2984 2870 -57907385.43707 +2871 2871 400933506.7687 +2872 2871 1.347064971924e-05 +2873 2871 3518564.899597 +2874 2871 46502609.17931 +2875 2871 9555555.553979 +2876 2871 -2418969.885557 +2958 2871 -19603280.6462 +2959 2871 11944444.44837 +2960 2871 8005089.696258 +2961 2871 -71968136.03531 +2962 2871 4.157423973083e-06 +2963 2871 51943969.87703 +2964 2871 -29817851.87049 +2965 2871 -11944444.44837 +2966 2871 17900923.03284 +2979 2871 8147390.424101 +2980 2871 -2388888.889671 +2981 2871 -1425089.694098 +2982 2871 44430116.09181 +2983 2871 1.907348632813e-06 +2984 2871 -10318414.32804 +2985 2871 -12806461.31664 +2986 2871 2388888.889668 +2987 2871 -3404256.361406 +2872 2872 343596730.4434 +2873 2872 -42221665.62853 +2874 2872 -9555555.55399 +2875 2872 -44275021.63857 +2876 2872 20899721.7032 +2958 2872 11944444.44837 +2959 2872 -16019732.12234 +2960 2872 -7635451.454545 +2961 2872 3.337860107422e-06 +2962 2872 -19412223.56332 +2963 2872 -5277708.208769 +2964 2872 -11944444.44837 +2965 2872 -26234303.34662 +2966 2872 12913159.66331 +2979 2872 2388888.889676 +2980 2872 -14547017.29156 +2981 2872 -15798680.67921 +2982 2872 2.861022949219e-06 +2983 2872 30095922.00342 +2984 2872 -10555416.41234 +2985 2872 -2388888.889678 +2986 2872 -35500869.03229 +2987 2872 26354097.09154 +2873 2873 383273120.8405 +2874 2873 5497696.779808 +2875 2873 21321943.92535 +2876 2873 28979670.15418 +2958 2873 8005089.696258 +2959 2873 -7635451.454545 +2960 2873 -9407733.938713 +2961 2873 51680080.98832 +2962 2873 -5277708.208769 +2963 2873 -58666023.42418 +2964 2873 17900923.03284 +2965 2873 12913159.66331 +2966 2873 -36646590.5368 +2979 2873 1864910.306983 +2980 2873 -15798680.67931 +2981 2873 -2030447.461764 +2982 2873 10758252.33516 +2983 2873 -10555416.41234 +2984 2873 -52990414.80866 +2985 2873 3844076.974307 +2986 2873 26354097.09164 +2987 2873 -57907385.43707 +2874 2874 390528978.5414 +2875 2874 2031754.88496 +2876 2874 18978084.67473 +2877 2874 10706126.81689 +2878 2874 -19091014.80711 +2879 2874 2131234.560147 +2961 2874 -19603280.6462 +2962 2874 11944444.44837 +2963 2874 8005089.696258 +2964 2874 -57207507.5192 +2965 2874 6145877.671107 +2966 2874 43364477.33833 +2967 2874 -26546695.73564 +2968 2874 -11436618.24716 +2969 2874 13848470.62555 +2982 2874 8147390.424101 +2983 2874 -2388888.889671 +2984 2874 -1425089.694098 +2985 2874 41725581.05413 +2986 2874 507938.7214912 +2987 2874 -6453256.604583 +2988 2874 -15664036.02673 +2989 2874 -4772753.704127 +2990 2874 5360864.194452 +2875 2875 352799816.1126 +2876 2875 -26163100.1551 +2877 2875 -38202125.91508 +2878 2875 -79908143.54456 +2879 2875 4520172.591737 +2961 2875 11944444.44837 +2962 2875 -16019732.12234 +2963 2875 -7635451.454545 +2964 2875 6145877.671106 +2965 2875 -14493743.54572 +2966 2875 -8981011.042271 +2967 2875 -11436618.24716 +2968 2875 -18063742.30393 +2969 2875 10594625.07348 +2982 2875 2388888.889676 +2983 2875 -14547017.29156 +2984 2875 -15798680.67921 +2985 2875 507938.7214905 +2986 2875 32293290.44228 +2987 2875 -6540775.042003 +2988 2875 -9550531.483474 +2989 2875 -38317603.62825 +2990 2875 28361293.14454 +2876 2876 373214203.523 +2877 2876 3450679.004372 +2878 2876 4731283.702813 +2879 2876 25915984.15995 +2961 2876 8005089.696258 +2962 2876 -7635451.454545 +2963 2876 -9407733.938713 +2964 2876 44683921.78504 +2965 2876 -8981011.041011 +2966 2876 -51241692.90527 +2967 2876 13848470.62555 +2968 2876 10594625.07348 +2969 2876 -23506184.8986 +2982 2876 1864910.306983 +2983 2876 -15798680.67931 +2984 2876 -2030447.461764 +2985 2876 14622854.50307 +2986 2876 -6540775.042003 +2987 2876 -55780885.41815 +2988 2876 11025586.41696 +2989 2876 28361293.14339 +2990 2876 -42429184.57622 +2877 2877 393308552.7541 +2878 2877 33387741.61392 +2879 2877 1069557.995636 +2880 2877 -90523162.8112 +2881 2877 -55317076.41861 +2882 2877 735989.013558 +2883 2877 18987277.35532 +2884 2877 -7277063.18551 +2885 2877 851409.3072543 +2964 2877 -16305861.25464 +2965 2877 8228316.115794 +2966 2877 4847647.38616 +2967 2877 -52398287.78342 +2968 2877 8623814.868829 +2969 2877 51247665.9983 +2985 2877 -10942417.8914 +2986 2877 -9550531.483475 +2987 2877 -9564135.802965 +2988 2877 13533800.67906 +2989 2877 8346935.407593 +2990 2877 -10722054.94328 +2991 2877 -36706081.42304 +2992 2877 -13829269.11147 +2993 2877 20496497.26015 +2994 2877 -20473238.80768 +2995 2877 -1819265.797273 +2996 2877 5144935.657537 +2878 2878 456455484.3111 +2879 2878 -8493577.449744 +2880 2878 -55317076.41861 +2881 2878 -67552496.70794 +2882 2878 488013.3309754 +2883 2878 -26388174.29348 +2884 2878 -73256625.20248 +2885 2878 1534234.021698 +2964 2878 8228316.115794 +2965 2878 -35556692.91277 +2966 2878 -15320362.63205 +2967 2878 8623814.868829 +2968 2878 -8962312.29862 +2969 2878 -7013375.774193 +2985 2878 -4772753.704129 +2986 2878 -33595985.49293 +2987 2878 -26048429.06869 +2988 2878 8346935.407594 +2989 2878 29320533.57608 +2990 2878 -2123394.363487 +2991 2878 -13829269.11147 +2992 2878 -30963414.8944 +2993 2878 16788670.00494 +2994 2878 -6597043.576619 +2995 2878 -43534214.45849 +2996 2878 33716891.83347 +2879 2879 472314421.5349 +2880 2879 735989.0135581 +2881 2879 488013.3309754 +2882 2879 -4099502.071191 +2883 2879 1115298.196096 +2884 2879 1534234.021698 +2885 2879 54129421.48319 +2964 2879 4847647.38616 +2965 2879 -15320362.63205 +2966 2879 -21210942.45867 +2967 2879 51247665.99856 +2968 2879 -7013375.772933 +2969 2879 -77412673.46776 +2985 2879 -4691080.247253 +2986 2879 -26048429.06995 +2987 2879 -29838202.88199 +2988 2879 9937389.497775 +2989 2879 -2123394.363487 +2990 2879 -108036961.3792 +2991 2879 20496497.26015 +2992 2879 16788670.00494 +2993 2879 -38558984.07588 +2994 2879 10337713.43846 +2995 2879 33716891.83347 +2996 2879 -53721133.01946 +2880 2880 247694807.0596 +2881 2880 61102353.61032 +2882 2880 -421250.4501109 +2883 2880 -40613658.84548 +2884 2880 -2016256.905298 +2885 2880 -164229.7541515 +2967 2880 -15064205.65599 +2968 2880 -942255.0720674 +2969 2880 -3602557.756001 +2988 2880 -36153755.84147 +2989 2880 -13829269.11147 +2990 2880 -20128502.75319 +2991 2880 313818.0877385 +2992 2880 15275588.41011 +2993 2880 8019687.386086 +2994 2880 -37751670.53939 +2995 2880 -504064.2265737 +2996 2880 -33038626.87689 +2881 2881 223946295.6199 +2882 2881 -417819.3012383 +2883 2881 17094854.20267 +2884 2881 52874008.36546 +2885 2881 -488013.3309731 +2967 2881 -5720032.851414 +2968 2881 -38241661.13605 +2969 2881 -33228878.5025 +2988 2881 -13829269.11147 +2989 2881 -30411089.31283 +2990 2881 -16544663.33934 +2991 2881 15275588.41011 +2992 2881 -5623309.775096 +2993 2881 6562211.840209 +2994 2881 4273713.552772 +2995 2881 -14379753.72514 +2996 2881 3211330.001623 +2882 2882 302886642.9092 +2883 2882 -428118.6429929 +2884 2882 -488013.3309731 +2885 2882 81415199.80545 +2967 2882 -11727557.7571 +2968 2882 -33228878.5025 +2969 2882 -57516476.65011 +2988 2882 -20128502.75319 +2989 2882 -16544663.33934 +2990 2882 -37086115.85837 +2991 2882 -8230312.611246 +2992 2882 -6771121.490934 +2993 2882 -88571362.45583 +2994 2882 -33038626.87847 +2995 2882 -3455336.667233 +2996 2882 -53241548.9 +2883 2883 194640779.4635 +2884 2883 -30945159.03043 +2885 2883 555998.0993371 +2967 2883 -18585866.94682 +2968 2883 10059619.78527 +2969 2883 12506219.47975 +2988 2883 -18816262.06405 +2989 2883 -6597043.57662 +2990 2883 -10043953.22886 +2991 2883 -37751670.53939 +2992 2883 4273713.552774 +2993 2883 32890539.77888 +2994 2883 -122944.6401992 +2995 2883 -7736289.761419 +2996 2883 -5251694.918494 +2884 2884 214346070.9221 +2885 2884 -1534234.021693 +2967 2884 10059619.78527 +2968 2884 -23823130.97733 +2969 2884 -16544663.33934 +2988 2884 -1819265.797274 +2989 2884 -41877237.71487 +2990 2884 -32949774.82225 +2991 2884 -504064.2265722 +2992 2884 -14379753.72514 +2993 2884 3211330.001623 +2994 2884 -7736289.761419 +2995 2884 4803378.226877 +2996 2884 6283108.159956 +2885 2885 249570489.3365 +2967 2885 12506219.47975 +2968 2885 -16544663.33934 +2969 2885 -30498157.52287 +2988 2885 -5115064.336773 +2989 2885 -32949774.82225 +2990 2885 -49302528.36979 +2991 2885 32890539.77744 +2992 2885 -3455336.667232 +2993 2885 -53241548.9 +2994 2885 4869971.746511 +2995 2885 -7050225.171186 +2996 2885 -67695749.71523 +2886 2886 572236993.7195 +2887 2886 55138888.87983 +2888 2886 31598553.4075 +2889 2886 -313559939.9103 +2890 2886 -55160226.61988 +2891 2886 -24936017.84334 +2892 2886 5063871.676501 +2893 2886 44132448.84391 +2894 2886 -17154449.80687 +2997 2886 88021012.11513 +2998 2886 15625000.00514 +2999 2886 19639605.71133 +3000 2886 -121308672.7549 +3001 2886 -15631586.90535 +3002 2886 -67766682.33182 +3003 2886 -21749648.26534 +3004 2886 12506586.90433 +3005 2886 -17353145.19621 +2887 2887 489500063.4635 +2888 2887 -54040789.03059 +2889 2887 -55170895.4899 +2890 2887 -54338040.03216 +2891 2887 -33960288.27187 +2892 2887 66198673.26587 +2893 2887 5063871.676508 +2894 2887 23123283.37764 +2997 2887 15625000.00514 +2998 2887 64574885.68388 +2999 2887 -6700809.891648 +3000 2887 -15634880.35547 +3001 2887 -47849941.99273 +3002 2887 -21743418.55177 +3003 2887 18759880.3565 +3004 2887 -21749648.26534 +3005 2887 20823318.70445 +2888 2888 536232943.3 +2889 2888 -21604750.06126 +2890 2888 -26737943.81257 +2891 2888 -22912436.09768 +2892 2888 -25731674.71031 +2893 2888 15415522.25176 +2894 2888 13503657.80403 +2997 2888 -4768139.577623 +2998 2888 -26226783.67725 +2999 2888 -45750138.7209 +3000 2888 -67422475.35311 +3001 2888 -19819673.42971 +3002 2888 -93029560.64943 +3003 2888 -26029717.79432 +3004 2888 13882212.46963 +3005 2888 -57999062.0409 +2889 2889 979444958.5446 +2890 2889 55192233.22997 +2891 2889 27299034.62316 +2892 2889 11141309.24956 +2893 2889 -55160226.61988 +2894 2889 24035972.54801 +2895 2889 -215223928.4788 +2896 2889 5.930662155151e-06 +2897 2889 -5707514.57167 +2898 2889 -85403197.39141 +2899 2889 55138888.87983 +2900 2889 -24029092.18165 +2997 2889 -108451246.8934 +2998 2889 -15634880.35547 +2999 2889 54616251.09168 +3000 2889 166227659.6012 +3001 2889 15641467.2557 +3002 2889 7711642.939084 +3003 2889 -41196855.08124 +3004 2889 -15631586.90536 +3005 2889 21974855.62738 +3006 2889 -92328809.14057 +3007 2889 5.915760993958e-06 +3008 2889 -62317692.40268 +3009 2889 -38047023.33633 +3010 2889 15625000.00513 +3011 2889 -21965599.32574 +2890 2890 830537689.1138 +2891 2890 -75243257.69584 +2892 2890 -55170895.48991 +2893 2890 -181886245.1745 +2894 2890 41627208.49512 +2895 2890 2.861022949219e-06 +2896 2890 27388705.35396 +2897 2890 -24270537.56804 +2898 2890 55138888.87983 +2899 2890 -68860612.58955 +2900 2890 13559921.56178 +2997 2890 -15631586.90536 +2998 2890 -34992516.13117 +2999 2890 4591649.47589 +3000 2890 15641467.2557 +3001 2890 124030560.5447 +3002 2890 -21261017.33538 +3003 2890 -15634880.35547 +3004 2890 -95897202.5708 +3005 2890 60337907.00837 +3006 2890 4.619359970093e-06 +3007 2890 -23578405.83475 +3008 2890 -6857560.807395 +3009 2890 15625000.00513 +3010 2890 -33359280.17771 +3011 2890 15972183.1856 +2891 2891 830564689.2359 +2892 2891 23511634.95294 +2893 2891 45765068.67361 +2894 2891 8306087.457417 +2895 2891 -2382861.794439 +2896 2891 -24270537.56804 +2897 2891 41183389.66318 +2898 2891 -23501314.4034 +2899 2891 13137699.33918 +2900 2891 -29852819.54686 +2997 2891 54272044.11297 +2998 2891 2673044.969291 +2999 2891 -58743091.68526 +3000 2891 7718068.787606 +3001 2891 -21255876.71511 +3002 2891 -61506429.36468 +3003 2891 21979483.77819 +3004 2891 61984848.42173 +3005 2891 -115922513.565 +3006 2891 -61974810.45846 +3007 2891 -6857560.807395 +3008 2891 -71902237.78217 +3009 2891 -21965599.32574 +3010 2891 15972183.1856 +3011 2891 -45381891.21762 +2892 2892 572236993.7195 +2893 2892 55138888.87983 +2894 2892 31598553.4075 +2895 2892 -84201296.24904 +2896 2892 -55138888.87984 +2897 2892 21478720.31087 +2898 2892 -313559939.9103 +2899 2892 -55160226.61988 +2900 2892 -24936017.84334 +2901 2892 5063871.676501 +2902 2892 44132448.84391 +2903 2892 -17154449.80687 +2997 2892 2359203.743841 +2998 2892 18759880.3565 +2999 2892 10591538.29392 +3000 2892 -4242975.331225 +3001 2892 -15634880.35547 +3002 2892 -8541442.446936 +3003 2892 88021012.11513 +3004 2892 15625000.00514 +3005 2892 19639605.71133 +3006 2892 -25660413.08922 +3007 2892 -15625000.00513 +3008 2892 -9107526.404853 +3009 2892 -121308672.7549 +3010 2892 -15631586.90535 +3011 2892 -67766682.33182 +3012 2892 -21749648.26534 +3013 2892 12506586.90433 +3014 2892 -17353145.19621 +2893 2893 489500063.4635 +2894 2893 -54040789.03059 +2895 2893 -55138888.87984 +2896 2893 -67658711.44716 +2897 2893 10710616.00625 +2898 2893 -55170895.4899 +2899 2893 -54338040.03216 +2900 2893 -33960288.27187 +2901 2893 66198673.26587 +2902 2893 5063871.676508 +2903 2893 23123283.37764 +2997 2893 12506586.90433 +2998 2893 2359203.743842 +2999 2893 -5648902.101029 +3000 2893 -15631586.90535 +3001 2893 -58943322.82077 +3002 2893 -35645020.83586 +3003 2893 15625000.00514 +3004 2893 64574885.68388 +3005 2893 -6700809.891648 +3006 2893 -15625000.00513 +3007 2893 -20972669.93059 +3008 2893 -9114622.378198 +3009 2893 -15634880.35547 +3010 2893 -47849941.99273 +3011 2893 -21743418.55177 +3012 2893 18759880.3565 +3013 2893 -21749648.26534 +3014 2893 20823318.70445 +2894 2894 536232943.3 +2895 2894 22006498.08912 +2896 2894 11132838.22885 +2897 2894 -26647749.83379 +2898 2894 -21604750.06126 +2899 2894 -26737943.81257 +2900 2894 -22912436.09768 +2901 2894 -25731674.71031 +2902 2894 15415522.25176 +2903 2894 13503657.80403 +2997 2894 7061025.529277 +2998 2894 -8473353.151544 +2999 2894 6291209.983575 +3000 2894 -8539644.961234 +3001 2894 -37291962.41402 +3002 2894 -17378834.23163 +3003 2894 -4768139.577623 +3004 2894 -26226783.67725 +3005 2894 -45750138.7209 +3006 2894 -9107526.404853 +3007 2894 -9114622.378198 +3008 2894 -12350930.55863 +3009 2894 -67422475.35311 +3010 2894 -19819673.42971 +3011 2894 -93029560.64943 +3012 2894 -26029717.79432 +3013 2894 13882212.46963 +3014 2894 -57999062.0409 +2895 2895 904416532.1423 +2896 2895 2.086162567139e-05 +2897 2895 8090376.36604 +2898 2895 102079011.1406 +2899 2895 -1.040101051331e-05 +2900 2895 2022594.092512 +2904 2895 -215223928.4788 +2905 2895 5.930662155151e-06 +2906 2895 -5707514.57167 +2907 2895 -85403197.39141 +2908 2895 55138888.87983 +2909 2895 -24029092.18165 +3000 2895 -89115968.74764 +3001 2895 -2.875924110413e-06 +3002 2895 60031786.74372 +3003 2895 -36905217.31746 +3004 2895 -15625000.00514 +3005 2895 21394122.91072 +3006 2895 137281674.8977 +3007 2895 7.092952728271e-06 +3008 2895 2285905.658981 +3009 2895 -24872960.07894 +3010 2895 -1.01625919342e-05 +3011 2895 571476.4150351 +3015 2895 -92328809.14057 +3016 2895 5.915760993958e-06 +3017 2895 -62317692.40268 +3018 2895 -38047023.33633 +3019 2895 15625000.00513 +3020 2895 -21965599.32574 +2896 2896 772075853.7925 +2897 2896 -97082150.22431 +2898 2896 -1.037120819092e-05 +2899 2896 -107448453.121 +2900 2896 49870936.22305 +2904 2896 2.861022949219e-06 +2905 2896 27388705.35396 +2906 2896 -24270537.56804 +2907 2896 55138888.87983 +2908 2896 -68860612.58955 +2909 2896 13559921.56178 +3000 2896 -4.589557647705e-06 +3001 2896 -20365565.44178 +3002 2896 -6857560.807395 +3003 2896 -15625000.00514 +3004 2896 -32217474.15883 +3005 2896 15286419.29648 +3006 2896 6.973743438721e-06 +3007 2896 99779729.64718 +3008 2896 -27430243.21607 +3009 2896 -8.568167686462e-06 +3010 2896 -84247877.07676 +3011 2896 62654357.71105 +3015 2896 4.619359970093e-06 +3016 2896 -23578405.83475 +3017 2896 -6857560.807395 +3018 2896 15625000.00513 +3019 2896 -33359280.17771 +3020 2896 15972183.1856 +2897 2897 828665098.5173 +2898 2897 2022594.092512 +2899 2897 47211214.00126 +2900 2897 52874910.70561 +2904 2897 -2382861.794439 +2905 2897 -24270537.56804 +2906 2897 41183389.66318 +2907 2897 -23501314.4034 +2908 2897 13137699.33918 +2909 2897 -29852819.54686 +3000 2897 59688904.7995 +3001 2897 -6857560.807395 +3002 2897 -63334663.40088 +3003 2897 21394122.91072 +3004 2897 15286419.29648 +3005 2897 -42337075.16724 +3006 2897 2285905.658981 +3007 2897 -27430243.21607 +3008 2897 -82530234.81935 +3009 2897 571476.4150354 +3010 2897 62380052.15567 +3011 2897 -128482138.2218 +3015 2897 -61974810.45846 +3016 2897 -6857560.807395 +3017 2897 -71902237.78217 +3018 2897 -21965599.32574 +3019 2897 15972183.1856 +3020 2897 -45381891.21762 +2898 2898 979444958.5446 +2899 2898 55192233.22997 +2900 2898 27299034.62316 +2901 2898 11141309.24956 +2902 2898 -55160226.61988 +2903 2898 24035972.54801 +2904 2898 -84201296.24904 +2905 2898 -55138888.87984 +2906 2898 21478720.31087 +2907 2898 -215223928.4788 +2908 2898 5.930662155151e-06 +2909 2898 -5707514.57167 +2910 2898 -85403197.39141 +2911 2898 55138888.87983 +2912 2898 -24029092.18165 +3000 2898 -25195798.91083 +3001 2898 15625000.00513 +3002 2898 8536049.989829 +3003 2898 -108451246.8934 +3004 2898 -15634880.35547 +3005 2898 54616251.09168 +3006 2898 23319097.20481 +3007 2898 3.09944152832e-06 +3008 2898 571476.4150216 +3009 2898 166227659.6012 +3010 2898 15641467.2557 +3011 2898 7711642.939084 +3012 2898 -41196855.08124 +3013 2898 -15631586.90536 +3014 2898 21974855.62738 +3015 2898 -25660413.08922 +3016 2898 -15625000.00513 +3017 2898 -9107526.404853 +3018 2898 -92328809.14057 +3019 2898 5.915760993958e-06 +3020 2898 -62317692.40268 +3021 2898 -38047023.33633 +3022 2898 15625000.00513 +3023 2898 -21965599.32574 +2899 2899 830537689.1138 +2900 2899 -75243257.69584 +2901 2899 -55170895.48991 +2902 2899 -181886245.1745 +2903 2899 41627208.49512 +2904 2899 -55138888.87984 +2905 2899 -67658711.44716 +2906 2899 10710616.00625 +2907 2899 2.861022949219e-06 +2908 2899 27388705.35396 +2909 2899 -24270537.56804 +2910 2899 55138888.87983 +2911 2899 -68860612.58955 +2912 2899 13559921.56178 +3000 2899 15625000.00513 +3001 2899 -20508055.7522 +3002 2899 -8428858.489084 +3003 2899 -15631586.90536 +3004 2899 -34992516.13117 +3005 2899 4591649.47589 +3006 2899 4.559755325317e-06 +3007 2899 -36055819.793 +3008 2899 -35224114.49497 +3009 2899 15641467.2557 +3010 2899 124030560.5447 +3011 2899 -21261017.33538 +3012 2899 -15634880.35547 +3013 2899 -95897202.5708 +3014 2899 60337907.00837 +3015 2899 -15625000.00513 +3016 2899 -20972669.93059 +3017 2899 -9114622.378198 +3018 2899 4.619359970093e-06 +3019 2899 -23578405.83475 +3020 2899 -6857560.807395 +3021 2899 15625000.00513 +3022 2899 -33359280.17771 +3023 2899 15972183.1856 +2900 2900 830564689.2359 +2901 2900 23511634.95294 +2902 2900 45765068.67361 +2903 2900 8306087.457417 +2904 2900 22006498.08912 +2905 2900 11132838.22885 +2906 2900 -26647749.83379 +2907 2900 -2382861.794439 +2908 2900 -24270537.56804 +2909 2900 41183389.66318 +2910 2900 -23501314.4034 +2911 2900 13137699.33918 +2912 2900 -29852819.54686 +3000 2900 8536049.989829 +3001 2900 -8428858.489084 +3002 2900 -11111959.41625 +3003 2900 54272044.11297 +3004 2900 2673044.969291 +3005 2900 -58743091.68526 +3006 2900 571476.4150219 +3007 2900 -34949808.93959 +3008 2900 30014.53480115 +3009 2900 7718068.787606 +3010 2900 -21255876.71511 +3011 2900 -61506429.36468 +3012 2900 21979483.77819 +3013 2900 61984848.42173 +3014 2900 -115922513.565 +3015 2900 -9107526.404853 +3016 2900 -9114622.378198 +3017 2900 -12350930.55863 +3018 2900 -61974810.45846 +3019 2900 -6857560.807395 +3020 2900 -71902237.78217 +3021 2900 -21965599.32574 +3022 2900 15972183.1856 +3023 2900 -45381891.21762 +2901 2901 572236993.7195 +2902 2901 55138888.87983 +2903 2901 31598553.4075 +2907 2901 -84201296.24904 +2908 2901 -55138888.87984 +2909 2901 21478720.31087 +2910 2901 -313559939.9103 +2911 2901 -55160226.61988 +2912 2901 -24936017.84334 +2913 2901 5063871.676501 +2914 2901 44132448.84391 +2915 2901 -17154449.80687 +3003 2901 2359203.743841 +3004 2901 18759880.3565 +3005 2901 10591538.29392 +3009 2901 -4242975.331225 +3010 2901 -15634880.35547 +3011 2901 -8541442.446936 +3012 2901 88021012.11513 +3013 2901 15625000.00514 +3014 2901 19639605.71133 +3018 2901 -25660413.08922 +3019 2901 -15625000.00513 +3020 2901 -9107526.404853 +3021 2901 -121308672.7549 +3022 2901 -15631586.90535 +3023 2901 -67766682.33182 +3024 2901 -21749648.26534 +3025 2901 12506586.90433 +3026 2901 -17353145.19621 +2902 2902 489500063.4635 +2903 2902 -54040789.03059 +2907 2902 -55138888.87984 +2908 2902 -67658711.44716 +2909 2902 10710616.00625 +2910 2902 -55170895.4899 +2911 2902 -54338040.03216 +2912 2902 -33960288.27187 +2913 2902 66198673.26587 +2914 2902 5063871.676508 +2915 2902 23123283.37764 +3003 2902 12506586.90433 +3004 2902 2359203.743842 +3005 2902 -5648902.101029 +3009 2902 -15631586.90535 +3010 2902 -58943322.82077 +3011 2902 -35645020.83586 +3012 2902 15625000.00514 +3013 2902 64574885.68388 +3014 2902 -6700809.891648 +3018 2902 -15625000.00513 +3019 2902 -20972669.93059 +3020 2902 -9114622.378198 +3021 2902 -15634880.35547 +3022 2902 -47849941.99273 +3023 2902 -21743418.55177 +3024 2902 18759880.3565 +3025 2902 -21749648.26534 +3026 2902 20823318.70445 +2903 2903 536232943.3 +2907 2903 22006498.08912 +2908 2903 11132838.22885 +2909 2903 -26647749.83379 +2910 2903 -21604750.06126 +2911 2903 -26737943.81257 +2912 2903 -22912436.09768 +2913 2903 -25731674.71031 +2914 2903 15415522.25176 +2915 2903 13503657.80403 +3003 2903 7061025.529277 +3004 2903 -8473353.151544 +3005 2903 6291209.983575 +3009 2903 -8539644.961234 +3010 2903 -37291962.41402 +3011 2903 -17378834.23163 +3012 2903 -4768139.577623 +3013 2903 -26226783.67725 +3014 2903 -45750138.7209 +3018 2903 -9107526.404853 +3019 2903 -9114622.378198 +3020 2903 -12350930.55863 +3021 2903 -67422475.35311 +3022 2903 -19819673.42971 +3023 2903 -93029560.64943 +3024 2903 -26029717.79432 +3025 2903 13882212.46963 +3026 2903 -57999062.0409 +2904 2904 904416532.1423 +2905 2904 2.086162567139e-05 +2906 2904 8090376.36604 +2907 2904 102079011.1406 +2908 2904 -1.040101051331e-05 +2909 2904 2022594.092512 +2916 2904 -215223928.4788 +2917 2904 5.930662155151e-06 +2918 2904 -5707514.57167 +2919 2904 -85403197.39141 +2920 2904 55138888.87983 +2921 2904 -24029092.18165 +3006 2904 -89115968.74764 +3007 2904 -2.875924110413e-06 +3008 2904 60031786.74372 +3009 2904 -36905217.31746 +3010 2904 -15625000.00514 +3011 2904 21394122.91072 +3015 2904 137281674.8977 +3016 2904 7.092952728271e-06 +3017 2904 2285905.658981 +3018 2904 -24872960.07894 +3019 2904 -1.01625919342e-05 +3020 2904 571476.4150351 +3027 2904 -92328809.14057 +3028 2904 5.915760993958e-06 +3029 2904 -62317692.40268 +3030 2904 -38047023.33633 +3031 2904 15625000.00513 +3032 2904 -21965599.32574 +2905 2905 772075853.7925 +2906 2905 -97082150.22431 +2907 2905 -1.037120819092e-05 +2908 2905 -107448453.121 +2909 2905 49870936.22305 +2916 2905 2.861022949219e-06 +2917 2905 27388705.35396 +2918 2905 -24270537.56804 +2919 2905 55138888.87983 +2920 2905 -68860612.58955 +2921 2905 13559921.56178 +3006 2905 -4.589557647705e-06 +3007 2905 -20365565.44178 +3008 2905 -6857560.807395 +3009 2905 -15625000.00514 +3010 2905 -32217474.15883 +3011 2905 15286419.29648 +3015 2905 6.973743438721e-06 +3016 2905 99779729.64718 +3017 2905 -27430243.21607 +3018 2905 -8.568167686462e-06 +3019 2905 -84247877.07676 +3020 2905 62654357.71105 +3027 2905 4.619359970093e-06 +3028 2905 -23578405.83475 +3029 2905 -6857560.807395 +3030 2905 15625000.00513 +3031 2905 -33359280.17771 +3032 2905 15972183.1856 +2906 2906 828665098.5173 +2907 2906 2022594.092512 +2908 2906 47211214.00126 +2909 2906 52874910.70561 +2916 2906 -2382861.794439 +2917 2906 -24270537.56804 +2918 2906 41183389.66318 +2919 2906 -23501314.4034 +2920 2906 13137699.33918 +2921 2906 -29852819.54686 +3006 2906 59688904.7995 +3007 2906 -6857560.807395 +3008 2906 -63334663.40088 +3009 2906 21394122.91072 +3010 2906 15286419.29648 +3011 2906 -42337075.16724 +3015 2906 2285905.658981 +3016 2906 -27430243.21607 +3017 2906 -82530234.81935 +3018 2906 571476.4150354 +3019 2906 62380052.15567 +3020 2906 -128482138.2218 +3027 2906 -61974810.45846 +3028 2906 -6857560.807395 +3029 2906 -71902237.78217 +3030 2906 -21965599.32574 +3031 2906 15972183.1856 +3032 2906 -45381891.21762 +2907 2907 904416532.1423 +2908 2907 2.086162567139e-05 +2909 2907 8090376.36604 +2910 2907 102079011.1406 +2911 2907 -1.040101051331e-05 +2912 2907 2022594.092512 +2916 2907 -84201296.24904 +2917 2907 -55138888.87984 +2918 2907 21478720.31087 +2919 2907 -215223928.4788 +2920 2907 5.930662155151e-06 +2921 2907 -5707514.57167 +2922 2907 -85403197.39141 +2923 2907 55138888.87983 +2924 2907 -24029092.18165 +3006 2907 -25195798.91083 +3007 2907 15625000.00513 +3008 2907 8536049.989829 +3009 2907 -89115968.74764 +3010 2907 -2.875924110413e-06 +3011 2907 60031786.74372 +3012 2907 -36905217.31746 +3013 2907 -15625000.00514 +3014 2907 21394122.91072 +3015 2907 23319097.20481 +3016 2907 3.09944152832e-06 +3017 2907 571476.4150216 +3018 2907 137281674.8977 +3019 2907 7.092952728271e-06 +3020 2907 2285905.658981 +3021 2907 -24872960.07894 +3022 2907 -1.01625919342e-05 +3023 2907 571476.4150351 +3027 2907 -25660413.08922 +3028 2907 -15625000.00513 +3029 2907 -9107526.404853 +3030 2907 -92328809.14057 +3031 2907 5.915760993958e-06 +3032 2907 -62317692.40268 +3033 2907 -38047023.33633 +3034 2907 15625000.00513 +3035 2907 -21965599.32574 +2908 2908 772075853.7925 +2909 2908 -97082150.22431 +2910 2908 -1.037120819092e-05 +2911 2908 -107448453.121 +2912 2908 49870936.22305 +2916 2908 -55138888.87984 +2917 2908 -67658711.44716 +2918 2908 10710616.00625 +2919 2908 2.861022949219e-06 +2920 2908 27388705.35396 +2921 2908 -24270537.56804 +2922 2908 55138888.87983 +2923 2908 -68860612.58955 +2924 2908 13559921.56178 +3006 2908 15625000.00513 +3007 2908 -20508055.7522 +3008 2908 -8428858.489084 +3009 2908 -4.589557647705e-06 +3010 2908 -20365565.44178 +3011 2908 -6857560.807395 +3012 2908 -15625000.00514 +3013 2908 -32217474.15883 +3014 2908 15286419.29648 +3015 2908 4.559755325317e-06 +3016 2908 -36055819.793 +3017 2908 -35224114.49497 +3018 2908 6.973743438721e-06 +3019 2908 99779729.64718 +3020 2908 -27430243.21607 +3021 2908 -8.568167686462e-06 +3022 2908 -84247877.07676 +3023 2908 62654357.71105 +3027 2908 -15625000.00513 +3028 2908 -20972669.93059 +3029 2908 -9114622.378198 +3030 2908 4.619359970093e-06 +3031 2908 -23578405.83475 +3032 2908 -6857560.807395 +3033 2908 15625000.00513 +3034 2908 -33359280.17771 +3035 2908 15972183.1856 +2909 2909 828665098.5173 +2910 2909 2022594.092512 +2911 2909 47211214.00126 +2912 2909 52874910.70561 +2916 2909 22006498.08912 +2917 2909 11132838.22885 +2918 2909 -26647749.83379 +2919 2909 -2382861.794439 +2920 2909 -24270537.56804 +2921 2909 41183389.66318 +2922 2909 -23501314.4034 +2923 2909 13137699.33918 +2924 2909 -29852819.54686 +3006 2909 8536049.989829 +3007 2909 -8428858.489084 +3008 2909 -11111959.41625 +3009 2909 59688904.7995 +3010 2909 -6857560.807395 +3011 2909 -63334663.40088 +3012 2909 21394122.91072 +3013 2909 15286419.29648 +3014 2909 -42337075.16724 +3015 2909 571476.4150219 +3016 2909 -34949808.93959 +3017 2909 30014.53480115 +3018 2909 2285905.658981 +3019 2909 -27430243.21607 +3020 2909 -82530234.81935 +3021 2909 571476.4150354 +3022 2909 62380052.15567 +3023 2909 -128482138.2218 +3027 2909 -9107526.404853 +3028 2909 -9114622.378198 +3029 2909 -12350930.55863 +3030 2909 -61974810.45846 +3031 2909 -6857560.807395 +3032 2909 -71902237.78217 +3033 2909 -21965599.32574 +3034 2909 15972183.1856 +3035 2909 -45381891.21762 +2910 2910 979444958.5446 +2911 2910 55192233.22997 +2912 2910 27299034.62316 +2913 2910 11141309.24956 +2914 2910 -55160226.61988 +2915 2910 24035972.54801 +2919 2910 -84201296.24904 +2920 2910 -55138888.87984 +2921 2910 21478720.31087 +2922 2910 -215223928.4788 +2923 2910 5.930662155151e-06 +2924 2910 -5707514.57167 +2925 2910 -85403197.39141 +2926 2910 55138888.87983 +2927 2910 -24029092.18165 +3009 2910 -25195798.91083 +3010 2910 15625000.00513 +3011 2910 8536049.989829 +3012 2910 -108451246.8934 +3013 2910 -15634880.35547 +3014 2910 54616251.09168 +3018 2910 23319097.20481 +3019 2910 3.09944152832e-06 +3020 2910 571476.4150216 +3021 2910 166227659.6012 +3022 2910 15641467.2557 +3023 2910 7711642.939084 +3024 2910 -41196855.08124 +3025 2910 -15631586.90536 +3026 2910 21974855.62738 +3030 2910 -25660413.08922 +3031 2910 -15625000.00513 +3032 2910 -9107526.404853 +3033 2910 -92328809.14057 +3034 2910 5.915760993958e-06 +3035 2910 -62317692.40268 +3036 2910 -38047023.33633 +3037 2910 15625000.00513 +3038 2910 -21965599.32574 +2911 2911 830537689.1138 +2912 2911 -75243257.69584 +2913 2911 -55170895.48991 +2914 2911 -181886245.1745 +2915 2911 41627208.49512 +2919 2911 -55138888.87984 +2920 2911 -67658711.44716 +2921 2911 10710616.00625 +2922 2911 2.861022949219e-06 +2923 2911 27388705.35396 +2924 2911 -24270537.56804 +2925 2911 55138888.87983 +2926 2911 -68860612.58955 +2927 2911 13559921.56178 +3009 2911 15625000.00513 +3010 2911 -20508055.7522 +3011 2911 -8428858.489084 +3012 2911 -15631586.90536 +3013 2911 -34992516.13117 +3014 2911 4591649.47589 +3018 2911 4.559755325317e-06 +3019 2911 -36055819.793 +3020 2911 -35224114.49497 +3021 2911 15641467.2557 +3022 2911 124030560.5447 +3023 2911 -21261017.33538 +3024 2911 -15634880.35547 +3025 2911 -95897202.5708 +3026 2911 60337907.00837 +3030 2911 -15625000.00513 +3031 2911 -20972669.93059 +3032 2911 -9114622.378198 +3033 2911 4.619359970093e-06 +3034 2911 -23578405.83475 +3035 2911 -6857560.807395 +3036 2911 15625000.00513 +3037 2911 -33359280.17771 +3038 2911 15972183.1856 +2912 2912 830564689.2359 +2913 2912 23511634.95294 +2914 2912 45765068.67361 +2915 2912 8306087.457417 +2919 2912 22006498.08912 +2920 2912 11132838.22885 +2921 2912 -26647749.83379 +2922 2912 -2382861.794439 +2923 2912 -24270537.56804 +2924 2912 41183389.66318 +2925 2912 -23501314.4034 +2926 2912 13137699.33918 +2927 2912 -29852819.54686 +3009 2912 8536049.989829 +3010 2912 -8428858.489084 +3011 2912 -11111959.41625 +3012 2912 54272044.11297 +3013 2912 2673044.969291 +3014 2912 -58743091.68526 +3018 2912 571476.4150219 +3019 2912 -34949808.93959 +3020 2912 30014.53480115 +3021 2912 7718068.787606 +3022 2912 -21255876.71511 +3023 2912 -61506429.36468 +3024 2912 21979483.77819 +3025 2912 61984848.42173 +3026 2912 -115922513.565 +3030 2912 -9107526.404853 +3031 2912 -9114622.378198 +3032 2912 -12350930.55863 +3033 2912 -61974810.45846 +3034 2912 -6857560.807395 +3035 2912 -71902237.78217 +3036 2912 -21965599.32574 +3037 2912 15972183.1856 +3038 2912 -45381891.21762 +2913 2913 572236993.7195 +2914 2913 55138888.87983 +2915 2913 31598553.4075 +2922 2913 -84201296.24904 +2923 2913 -55138888.87984 +2924 2913 21478720.31087 +2925 2913 -313559939.9103 +2926 2913 -55160226.61988 +2927 2913 -24936017.84334 +2928 2913 5063871.676501 +2929 2913 44132448.84391 +2930 2913 -17154449.80687 +3012 2913 2359203.743841 +3013 2913 18759880.3565 +3014 2913 10591538.29392 +3021 2913 -4242975.331225 +3022 2913 -15634880.35547 +3023 2913 -8541442.446936 +3024 2913 88021012.11513 +3025 2913 15625000.00514 +3026 2913 19639605.71133 +3033 2913 -25660413.08922 +3034 2913 -15625000.00513 +3035 2913 -9107526.404853 +3036 2913 -121308672.7549 +3037 2913 -15631586.90535 +3038 2913 -67766682.33182 +3039 2913 -21749648.26534 +3040 2913 12506586.90433 +3041 2913 -17353145.19621 +2914 2914 489500063.4635 +2915 2914 -54040789.03059 +2922 2914 -55138888.87984 +2923 2914 -67658711.44716 +2924 2914 10710616.00625 +2925 2914 -55170895.4899 +2926 2914 -54338040.03216 +2927 2914 -33960288.27187 +2928 2914 66198673.26587 +2929 2914 5063871.676508 +2930 2914 23123283.37764 +3012 2914 12506586.90433 +3013 2914 2359203.743842 +3014 2914 -5648902.101029 +3021 2914 -15631586.90535 +3022 2914 -58943322.82077 +3023 2914 -35645020.83586 +3024 2914 15625000.00514 +3025 2914 64574885.68388 +3026 2914 -6700809.891648 +3033 2914 -15625000.00513 +3034 2914 -20972669.93059 +3035 2914 -9114622.378198 +3036 2914 -15634880.35547 +3037 2914 -47849941.99273 +3038 2914 -21743418.55177 +3039 2914 18759880.3565 +3040 2914 -21749648.26534 +3041 2914 20823318.70445 +2915 2915 536232943.3 +2922 2915 22006498.08912 +2923 2915 11132838.22885 +2924 2915 -26647749.83379 +2925 2915 -21604750.06126 +2926 2915 -26737943.81257 +2927 2915 -22912436.09768 +2928 2915 -25731674.71031 +2929 2915 15415522.25176 +2930 2915 13503657.80403 +3012 2915 7061025.529277 +3013 2915 -8473353.151544 +3014 2915 6291209.983575 +3021 2915 -8539644.961234 +3022 2915 -37291962.41402 +3023 2915 -17378834.23163 +3024 2915 -4768139.577623 +3025 2915 -26226783.67725 +3026 2915 -45750138.7209 +3033 2915 -9107526.404853 +3034 2915 -9114622.378198 +3035 2915 -12350930.55863 +3036 2915 -67422475.35311 +3037 2915 -19819673.42971 +3038 2915 -93029560.64943 +3039 2915 -26029717.79432 +3040 2915 13882212.46963 +3041 2915 -57999062.0409 +2916 2916 904416532.1423 +2917 2916 2.086162567139e-05 +2918 2916 8090376.36604 +2919 2916 102079011.1406 +2920 2916 -1.040101051331e-05 +2921 2916 2022594.092512 +2931 2916 -215223928.4788 +2932 2916 5.930662155151e-06 +2933 2916 -5707514.57167 +2934 2916 -85403197.39141 +2935 2916 55138888.87983 +2936 2916 -24029092.18165 +3015 2916 -89115968.74764 +3016 2916 -2.875924110413e-06 +3017 2916 60031786.74372 +3018 2916 -36905217.31746 +3019 2916 -15625000.00514 +3020 2916 21394122.91072 +3027 2916 137281674.8977 +3028 2916 7.092952728271e-06 +3029 2916 2285905.658981 +3030 2916 -24872960.07894 +3031 2916 -1.01625919342e-05 +3032 2916 571476.4150351 +3042 2916 -92328809.14057 +3043 2916 5.915760993958e-06 +3044 2916 -62317692.40268 +3045 2916 -38047023.33633 +3046 2916 15625000.00513 +3047 2916 -21965599.32574 +2917 2917 772075853.7925 +2918 2917 -97082150.22431 +2919 2917 -1.037120819092e-05 +2920 2917 -107448453.121 +2921 2917 49870936.22305 +2931 2917 2.861022949219e-06 +2932 2917 27388705.35396 +2933 2917 -24270537.56804 +2934 2917 55138888.87983 +2935 2917 -68860612.58955 +2936 2917 13559921.56178 +3015 2917 -4.589557647705e-06 +3016 2917 -20365565.44178 +3017 2917 -6857560.807395 +3018 2917 -15625000.00514 +3019 2917 -32217474.15883 +3020 2917 15286419.29648 +3027 2917 6.973743438721e-06 +3028 2917 99779729.64718 +3029 2917 -27430243.21607 +3030 2917 -8.568167686462e-06 +3031 2917 -84247877.07676 +3032 2917 62654357.71105 +3042 2917 4.619359970093e-06 +3043 2917 -23578405.83475 +3044 2917 -6857560.807395 +3045 2917 15625000.00513 +3046 2917 -33359280.17771 +3047 2917 15972183.1856 +2918 2918 828665098.5173 +2919 2918 2022594.092512 +2920 2918 47211214.00126 +2921 2918 52874910.70561 +2931 2918 -2382861.794439 +2932 2918 -24270537.56804 +2933 2918 41183389.66318 +2934 2918 -23501314.4034 +2935 2918 13137699.33918 +2936 2918 -29852819.54686 +3015 2918 59688904.7995 +3016 2918 -6857560.807395 +3017 2918 -63334663.40088 +3018 2918 21394122.91072 +3019 2918 15286419.29648 +3020 2918 -42337075.16724 +3027 2918 2285905.658981 +3028 2918 -27430243.21607 +3029 2918 -82530234.81935 +3030 2918 571476.4150354 +3031 2918 62380052.15567 +3032 2918 -128482138.2218 +3042 2918 -61974810.45846 +3043 2918 -6857560.807395 +3044 2918 -71902237.78217 +3045 2918 -21965599.32574 +3046 2918 15972183.1856 +3047 2918 -45381891.21762 +2919 2919 904416532.1423 +2920 2919 2.086162567139e-05 +2921 2919 8090376.36604 +2922 2919 102079011.1406 +2923 2919 -1.040101051331e-05 +2924 2919 2022594.092512 +2931 2919 -84201296.24904 +2932 2919 -55138888.87984 +2933 2919 21478720.31087 +2934 2919 -215223928.4788 +2935 2919 5.930662155151e-06 +2936 2919 -5707514.57167 +2937 2919 -85403197.39141 +2938 2919 55138888.87983 +2939 2919 -24029092.18165 +3015 2919 -25195798.91083 +3016 2919 15625000.00513 +3017 2919 8536049.989829 +3018 2919 -89115968.74764 +3019 2919 -2.875924110413e-06 +3020 2919 60031786.74372 +3021 2919 -36905217.31746 +3022 2919 -15625000.00514 +3023 2919 21394122.91072 +3027 2919 23319097.20481 +3028 2919 3.09944152832e-06 +3029 2919 571476.4150216 +3030 2919 137281674.8977 +3031 2919 7.092952728271e-06 +3032 2919 2285905.658981 +3033 2919 -24872960.07894 +3034 2919 -1.01625919342e-05 +3035 2919 571476.4150351 +3042 2919 -25660413.08922 +3043 2919 -15625000.00513 +3044 2919 -9107526.404853 +3045 2919 -92328809.14057 +3046 2919 5.915760993958e-06 +3047 2919 -62317692.40268 +3048 2919 -38047023.33633 +3049 2919 15625000.00513 +3050 2919 -21965599.32574 +2920 2920 772075853.7925 +2921 2920 -97082150.22431 +2922 2920 -1.037120819092e-05 +2923 2920 -107448453.121 +2924 2920 49870936.22305 +2931 2920 -55138888.87984 +2932 2920 -67658711.44716 +2933 2920 10710616.00625 +2934 2920 2.861022949219e-06 +2935 2920 27388705.35396 +2936 2920 -24270537.56804 +2937 2920 55138888.87983 +2938 2920 -68860612.58955 +2939 2920 13559921.56178 +3015 2920 15625000.00513 +3016 2920 -20508055.7522 +3017 2920 -8428858.489084 +3018 2920 -4.589557647705e-06 +3019 2920 -20365565.44178 +3020 2920 -6857560.807395 +3021 2920 -15625000.00514 +3022 2920 -32217474.15883 +3023 2920 15286419.29648 +3027 2920 4.559755325317e-06 +3028 2920 -36055819.793 +3029 2920 -35224114.49497 +3030 2920 6.973743438721e-06 +3031 2920 99779729.64718 +3032 2920 -27430243.21607 +3033 2920 -8.568167686462e-06 +3034 2920 -84247877.07676 +3035 2920 62654357.71105 +3042 2920 -15625000.00513 +3043 2920 -20972669.93059 +3044 2920 -9114622.378198 +3045 2920 4.619359970093e-06 +3046 2920 -23578405.83475 +3047 2920 -6857560.807395 +3048 2920 15625000.00513 +3049 2920 -33359280.17771 +3050 2920 15972183.1856 +2921 2921 828665098.5173 +2922 2921 2022594.092512 +2923 2921 47211214.00126 +2924 2921 52874910.70561 +2931 2921 22006498.08912 +2932 2921 11132838.22885 +2933 2921 -26647749.83379 +2934 2921 -2382861.794439 +2935 2921 -24270537.56804 +2936 2921 41183389.66318 +2937 2921 -23501314.4034 +2938 2921 13137699.33918 +2939 2921 -29852819.54686 +3015 2921 8536049.989829 +3016 2921 -8428858.489084 +3017 2921 -11111959.41625 +3018 2921 59688904.7995 +3019 2921 -6857560.807395 +3020 2921 -63334663.40088 +3021 2921 21394122.91072 +3022 2921 15286419.29648 +3023 2921 -42337075.16724 +3027 2921 571476.4150219 +3028 2921 -34949808.93959 +3029 2921 30014.53480115 +3030 2921 2285905.658981 +3031 2921 -27430243.21607 +3032 2921 -82530234.81935 +3033 2921 571476.4150354 +3034 2921 62380052.15567 +3035 2921 -128482138.2218 +3042 2921 -9107526.404853 +3043 2921 -9114622.378198 +3044 2921 -12350930.55863 +3045 2921 -61974810.45846 +3046 2921 -6857560.807395 +3047 2921 -71902237.78217 +3048 2921 -21965599.32574 +3049 2921 15972183.1856 +3050 2921 -45381891.21762 +2922 2922 904416532.1423 +2923 2922 2.086162567139e-05 +2924 2922 8090376.36604 +2925 2922 102079011.1406 +2926 2922 -1.040101051331e-05 +2927 2922 2022594.092512 +2934 2922 -84201296.24904 +2935 2922 -55138888.87984 +2936 2922 21478720.31087 +2937 2922 -215223928.4788 +2938 2922 5.930662155151e-06 +2939 2922 -5707514.57167 +2940 2922 -85403197.39141 +2941 2922 55138888.87983 +2942 2922 -24029092.18165 +3018 2922 -25195798.91083 +3019 2922 15625000.00513 +3020 2922 8536049.989829 +3021 2922 -89115968.74764 +3022 2922 -2.875924110413e-06 +3023 2922 60031786.74372 +3024 2922 -36905217.31746 +3025 2922 -15625000.00514 +3026 2922 21394122.91072 +3030 2922 23319097.20481 +3031 2922 3.09944152832e-06 +3032 2922 571476.4150216 +3033 2922 137281674.8977 +3034 2922 7.092952728271e-06 +3035 2922 2285905.658981 +3036 2922 -24872960.07894 +3037 2922 -1.01625919342e-05 +3038 2922 571476.4150351 +3045 2922 -25660413.08922 +3046 2922 -15625000.00513 +3047 2922 -9107526.404853 +3048 2922 -92328809.14057 +3049 2922 5.915760993958e-06 +3050 2922 -62317692.40268 +3051 2922 -38047023.33633 +3052 2922 15625000.00513 +3053 2922 -21965599.32574 +2923 2923 772075853.7925 +2924 2923 -97082150.22431 +2925 2923 -1.037120819092e-05 +2926 2923 -107448453.121 +2927 2923 49870936.22305 +2934 2923 -55138888.87984 +2935 2923 -67658711.44716 +2936 2923 10710616.00625 +2937 2923 2.861022949219e-06 +2938 2923 27388705.35396 +2939 2923 -24270537.56804 +2940 2923 55138888.87983 +2941 2923 -68860612.58955 +2942 2923 13559921.56178 +3018 2923 15625000.00513 +3019 2923 -20508055.7522 +3020 2923 -8428858.489084 +3021 2923 -4.589557647705e-06 +3022 2923 -20365565.44178 +3023 2923 -6857560.807395 +3024 2923 -15625000.00514 +3025 2923 -32217474.15883 +3026 2923 15286419.29648 +3030 2923 4.559755325317e-06 +3031 2923 -36055819.793 +3032 2923 -35224114.49497 +3033 2923 6.973743438721e-06 +3034 2923 99779729.64718 +3035 2923 -27430243.21607 +3036 2923 -8.568167686462e-06 +3037 2923 -84247877.07676 +3038 2923 62654357.71105 +3045 2923 -15625000.00513 +3046 2923 -20972669.93059 +3047 2923 -9114622.378198 +3048 2923 4.619359970093e-06 +3049 2923 -23578405.83475 +3050 2923 -6857560.807395 +3051 2923 15625000.00513 +3052 2923 -33359280.17771 +3053 2923 15972183.1856 +2924 2924 828665098.5173 +2925 2924 2022594.092512 +2926 2924 47211214.00126 +2927 2924 52874910.70561 +2934 2924 22006498.08912 +2935 2924 11132838.22885 +2936 2924 -26647749.83379 +2937 2924 -2382861.794439 +2938 2924 -24270537.56804 +2939 2924 41183389.66318 +2940 2924 -23501314.4034 +2941 2924 13137699.33918 +2942 2924 -29852819.54686 +3018 2924 8536049.989829 +3019 2924 -8428858.489084 +3020 2924 -11111959.41625 +3021 2924 59688904.7995 +3022 2924 -6857560.807395 +3023 2924 -63334663.40088 +3024 2924 21394122.91072 +3025 2924 15286419.29648 +3026 2924 -42337075.16724 +3030 2924 571476.4150219 +3031 2924 -34949808.93959 +3032 2924 30014.53480115 +3033 2924 2285905.658981 +3034 2924 -27430243.21607 +3035 2924 -82530234.81935 +3036 2924 571476.4150354 +3037 2924 62380052.15567 +3038 2924 -128482138.2218 +3045 2924 -9107526.404853 +3046 2924 -9114622.378198 +3047 2924 -12350930.55863 +3048 2924 -61974810.45846 +3049 2924 -6857560.807395 +3050 2924 -71902237.78217 +3051 2924 -21965599.32574 +3052 2924 15972183.1856 +3053 2924 -45381891.21762 +2925 2925 979444958.5446 +2926 2925 55192233.22997 +2927 2925 27299034.62316 +2928 2925 11141309.24956 +2929 2925 -55160226.61988 +2930 2925 24035972.54801 +2937 2925 -84201296.24904 +2938 2925 -55138888.87984 +2939 2925 21478720.31087 +2940 2925 -215223928.4788 +2941 2925 5.930662155151e-06 +2942 2925 -5707514.57167 +2943 2925 -85403197.39141 +2944 2925 55138888.87983 +2945 2925 -24029092.18165 +3021 2925 -25195798.91083 +3022 2925 15625000.00513 +3023 2925 8536049.989829 +3024 2925 -108451246.8934 +3025 2925 -15634880.35547 +3026 2925 54616251.09168 +3033 2925 23319097.20481 +3034 2925 3.09944152832e-06 +3035 2925 571476.4150216 +3036 2925 166227659.6012 +3037 2925 15641467.2557 +3038 2925 7711642.939084 +3039 2925 -41196855.08124 +3040 2925 -15631586.90536 +3041 2925 21974855.62738 +3048 2925 -25660413.08922 +3049 2925 -15625000.00513 +3050 2925 -9107526.404853 +3051 2925 -92328809.14057 +3052 2925 5.915760993958e-06 +3053 2925 -62317692.40268 +3054 2925 -38047023.33633 +3055 2925 15625000.00513 +3056 2925 -21965599.32574 +2926 2926 830537689.1138 +2927 2926 -75243257.69584 +2928 2926 -55170895.48991 +2929 2926 -181886245.1745 +2930 2926 41627208.49512 +2937 2926 -55138888.87984 +2938 2926 -67658711.44716 +2939 2926 10710616.00625 +2940 2926 2.861022949219e-06 +2941 2926 27388705.35396 +2942 2926 -24270537.56804 +2943 2926 55138888.87983 +2944 2926 -68860612.58955 +2945 2926 13559921.56178 +3021 2926 15625000.00513 +3022 2926 -20508055.7522 +3023 2926 -8428858.489084 +3024 2926 -15631586.90536 +3025 2926 -34992516.13117 +3026 2926 4591649.47589 +3033 2926 4.559755325317e-06 +3034 2926 -36055819.793 +3035 2926 -35224114.49497 +3036 2926 15641467.2557 +3037 2926 124030560.5447 +3038 2926 -21261017.33538 +3039 2926 -15634880.35547 +3040 2926 -95897202.5708 +3041 2926 60337907.00837 +3048 2926 -15625000.00513 +3049 2926 -20972669.93059 +3050 2926 -9114622.378198 +3051 2926 4.619359970093e-06 +3052 2926 -23578405.83475 +3053 2926 -6857560.807395 +3054 2926 15625000.00513 +3055 2926 -33359280.17771 +3056 2926 15972183.1856 +2927 2927 830564689.2359 +2928 2927 23511634.95294 +2929 2927 45765068.67361 +2930 2927 8306087.457417 +2937 2927 22006498.08912 +2938 2927 11132838.22885 +2939 2927 -26647749.83379 +2940 2927 -2382861.794439 +2941 2927 -24270537.56804 +2942 2927 41183389.66318 +2943 2927 -23501314.4034 +2944 2927 13137699.33918 +2945 2927 -29852819.54686 +3021 2927 8536049.989829 +3022 2927 -8428858.489084 +3023 2927 -11111959.41625 +3024 2927 54272044.11297 +3025 2927 2673044.969291 +3026 2927 -58743091.68526 +3033 2927 571476.4150219 +3034 2927 -34949808.93959 +3035 2927 30014.53480115 +3036 2927 7718068.787606 +3037 2927 -21255876.71511 +3038 2927 -61506429.36468 +3039 2927 21979483.77819 +3040 2927 61984848.42173 +3041 2927 -115922513.565 +3048 2927 -9107526.404853 +3049 2927 -9114622.378198 +3050 2927 -12350930.55863 +3051 2927 -61974810.45846 +3052 2927 -6857560.807395 +3053 2927 -71902237.78217 +3054 2927 -21965599.32574 +3055 2927 15972183.1856 +3056 2927 -45381891.21762 +2928 2928 572236993.7195 +2929 2928 55138888.87983 +2930 2928 31598553.4075 +2940 2928 -84201296.24904 +2941 2928 -55138888.87984 +2942 2928 21478720.31087 +2943 2928 -313559939.9103 +2944 2928 -55160226.61988 +2945 2928 -24936017.84334 +2946 2928 5063871.676501 +2947 2928 44132448.84391 +2948 2928 -17154449.80687 +3024 2928 2359203.743841 +3025 2928 18759880.3565 +3026 2928 10591538.29392 +3036 2928 -4242975.331225 +3037 2928 -15634880.35547 +3038 2928 -8541442.446936 +3039 2928 88021012.11513 +3040 2928 15625000.00514 +3041 2928 19639605.71133 +3051 2928 -25660413.08922 +3052 2928 -15625000.00513 +3053 2928 -9107526.404853 +3054 2928 -121308672.7549 +3055 2928 -15631586.90535 +3056 2928 -67766682.33182 +3057 2928 -21749648.26534 +3058 2928 12506586.90433 +3059 2928 -17353145.19621 +2929 2929 489500063.4635 +2930 2929 -54040789.03059 +2940 2929 -55138888.87984 +2941 2929 -67658711.44716 +2942 2929 10710616.00625 +2943 2929 -55170895.4899 +2944 2929 -54338040.03216 +2945 2929 -33960288.27187 +2946 2929 66198673.26587 +2947 2929 5063871.676508 +2948 2929 23123283.37764 +3024 2929 12506586.90433 +3025 2929 2359203.743842 +3026 2929 -5648902.101029 +3036 2929 -15631586.90535 +3037 2929 -58943322.82077 +3038 2929 -35645020.83586 +3039 2929 15625000.00514 +3040 2929 64574885.68388 +3041 2929 -6700809.891648 +3051 2929 -15625000.00513 +3052 2929 -20972669.93059 +3053 2929 -9114622.378198 +3054 2929 -15634880.35547 +3055 2929 -47849941.99273 +3056 2929 -21743418.55177 +3057 2929 18759880.3565 +3058 2929 -21749648.26534 +3059 2929 20823318.70445 +2930 2930 536232943.3 +2940 2930 22006498.08912 +2941 2930 11132838.22885 +2942 2930 -26647749.83379 +2943 2930 -21604750.06126 +2944 2930 -26737943.81257 +2945 2930 -22912436.09768 +2946 2930 -25731674.71031 +2947 2930 15415522.25176 +2948 2930 13503657.80403 +3024 2930 7061025.529277 +3025 2930 -8473353.151544 +3026 2930 6291209.983575 +3036 2930 -8539644.961234 +3037 2930 -37291962.41402 +3038 2930 -17378834.23163 +3039 2930 -4768139.577623 +3040 2930 -26226783.67725 +3041 2930 -45750138.7209 +3051 2930 -9107526.404853 +3052 2930 -9114622.378198 +3053 2930 -12350930.55863 +3054 2930 -67422475.35311 +3055 2930 -19819673.42971 +3056 2930 -93029560.64943 +3057 2930 -26029717.79432 +3058 2930 13882212.46963 +3059 2930 -57999062.0409 +2931 2931 904416532.1423 +2932 2931 2.086162567139e-05 +2933 2931 8090376.36604 +2934 2931 102079011.1406 +2935 2931 -1.040101051331e-05 +2936 2931 2022594.092512 +2949 2931 -215223928.4788 +2950 2931 5.930662155151e-06 +2951 2931 -5707514.57167 +2952 2931 -85403197.39141 +2953 2931 55138888.87983 +2954 2931 -24029092.18165 +3027 2931 -89115968.74764 +3028 2931 -2.875924110413e-06 +3029 2931 60031786.74372 +3030 2931 -36905217.31746 +3031 2931 -15625000.00514 +3032 2931 21394122.91072 +3042 2931 137281674.8977 +3043 2931 7.092952728271e-06 +3044 2931 2285905.658981 +3045 2931 -24872960.07894 +3046 2931 -1.01625919342e-05 +3047 2931 571476.4150351 +3060 2931 -92328809.14057 +3061 2931 5.915760993958e-06 +3062 2931 -62317692.40268 +3063 2931 -38047023.33633 +3064 2931 15625000.00513 +3065 2931 -21965599.32574 +2932 2932 772075853.7925 +2933 2932 -97082150.22431 +2934 2932 -1.037120819092e-05 +2935 2932 -107448453.121 +2936 2932 49870936.22305 +2949 2932 2.861022949219e-06 +2950 2932 27388705.35396 +2951 2932 -24270537.56804 +2952 2932 55138888.87983 +2953 2932 -68860612.58955 +2954 2932 13559921.56178 +3027 2932 -4.589557647705e-06 +3028 2932 -20365565.44178 +3029 2932 -6857560.807395 +3030 2932 -15625000.00514 +3031 2932 -32217474.15883 +3032 2932 15286419.29648 +3042 2932 6.973743438721e-06 +3043 2932 99779729.64718 +3044 2932 -27430243.21607 +3045 2932 -8.568167686462e-06 +3046 2932 -84247877.07676 +3047 2932 62654357.71105 +3060 2932 4.619359970093e-06 +3061 2932 -23578405.83475 +3062 2932 -6857560.807395 +3063 2932 15625000.00513 +3064 2932 -33359280.17771 +3065 2932 15972183.1856 +2933 2933 828665098.5173 +2934 2933 2022594.092512 +2935 2933 47211214.00126 +2936 2933 52874910.70561 +2949 2933 -2382861.794439 +2950 2933 -24270537.56804 +2951 2933 41183389.66318 +2952 2933 -23501314.4034 +2953 2933 13137699.33918 +2954 2933 -29852819.54686 +3027 2933 59688904.7995 +3028 2933 -6857560.807395 +3029 2933 -63334663.40088 +3030 2933 21394122.91072 +3031 2933 15286419.29648 +3032 2933 -42337075.16724 +3042 2933 2285905.658981 +3043 2933 -27430243.21607 +3044 2933 -82530234.81935 +3045 2933 571476.4150354 +3046 2933 62380052.15567 +3047 2933 -128482138.2218 +3060 2933 -61974810.45846 +3061 2933 -6857560.807395 +3062 2933 -71902237.78217 +3063 2933 -21965599.32574 +3064 2933 15972183.1856 +3065 2933 -45381891.21762 +2934 2934 904416532.1423 +2935 2934 2.086162567139e-05 +2936 2934 8090376.36604 +2937 2934 102079011.1406 +2938 2934 -1.040101051331e-05 +2939 2934 2022594.092512 +2949 2934 -84201296.24904 +2950 2934 -55138888.87984 +2951 2934 21478720.31087 +2952 2934 -215223928.4788 +2953 2934 5.930662155151e-06 +2954 2934 -5707514.57167 +2955 2934 -85403197.39141 +2956 2934 55138888.87983 +2957 2934 -24029092.18165 +3027 2934 -25195798.91083 +3028 2934 15625000.00513 +3029 2934 8536049.989829 +3030 2934 -89115968.74764 +3031 2934 -2.875924110413e-06 +3032 2934 60031786.74372 +3033 2934 -36905217.31746 +3034 2934 -15625000.00514 +3035 2934 21394122.91072 +3042 2934 23319097.20481 +3043 2934 3.09944152832e-06 +3044 2934 571476.4150216 +3045 2934 137281674.8977 +3046 2934 7.092952728271e-06 +3047 2934 2285905.658981 +3048 2934 -24872960.07894 +3049 2934 -1.01625919342e-05 +3050 2934 571476.4150351 +3060 2934 -25660413.08922 +3061 2934 -15625000.00513 +3062 2934 -9107526.404853 +3063 2934 -92328809.14057 +3064 2934 5.915760993958e-06 +3065 2934 -62317692.40268 +3066 2934 -38047023.33633 +3067 2934 15625000.00513 +3068 2934 -21965599.32574 +2935 2935 772075853.7925 +2936 2935 -97082150.22431 +2937 2935 -1.037120819092e-05 +2938 2935 -107448453.121 +2939 2935 49870936.22305 +2949 2935 -55138888.87984 +2950 2935 -67658711.44716 +2951 2935 10710616.00625 +2952 2935 2.861022949219e-06 +2953 2935 27388705.35396 +2954 2935 -24270537.56804 +2955 2935 55138888.87983 +2956 2935 -68860612.58955 +2957 2935 13559921.56178 +3027 2935 15625000.00513 +3028 2935 -20508055.7522 +3029 2935 -8428858.489084 +3030 2935 -4.589557647705e-06 +3031 2935 -20365565.44178 +3032 2935 -6857560.807395 +3033 2935 -15625000.00514 +3034 2935 -32217474.15883 +3035 2935 15286419.29648 +3042 2935 4.559755325317e-06 +3043 2935 -36055819.793 +3044 2935 -35224114.49497 +3045 2935 6.973743438721e-06 +3046 2935 99779729.64718 +3047 2935 -27430243.21607 +3048 2935 -8.568167686462e-06 +3049 2935 -84247877.07676 +3050 2935 62654357.71105 +3060 2935 -15625000.00513 +3061 2935 -20972669.93059 +3062 2935 -9114622.378198 +3063 2935 4.619359970093e-06 +3064 2935 -23578405.83475 +3065 2935 -6857560.807395 +3066 2935 15625000.00513 +3067 2935 -33359280.17771 +3068 2935 15972183.1856 +2936 2936 828665098.5173 +2937 2936 2022594.092512 +2938 2936 47211214.00126 +2939 2936 52874910.70561 +2949 2936 22006498.08912 +2950 2936 11132838.22885 +2951 2936 -26647749.83379 +2952 2936 -2382861.794439 +2953 2936 -24270537.56804 +2954 2936 41183389.66318 +2955 2936 -23501314.4034 +2956 2936 13137699.33918 +2957 2936 -29852819.54686 +3027 2936 8536049.989829 +3028 2936 -8428858.489084 +3029 2936 -11111959.41625 +3030 2936 59688904.7995 +3031 2936 -6857560.807395 +3032 2936 -63334663.40088 +3033 2936 21394122.91072 +3034 2936 15286419.29648 +3035 2936 -42337075.16724 +3042 2936 571476.4150219 +3043 2936 -34949808.93959 +3044 2936 30014.53480115 +3045 2936 2285905.658981 +3046 2936 -27430243.21607 +3047 2936 -82530234.81935 +3048 2936 571476.4150354 +3049 2936 62380052.15567 +3050 2936 -128482138.2218 +3060 2936 -9107526.404853 +3061 2936 -9114622.378198 +3062 2936 -12350930.55863 +3063 2936 -61974810.45846 +3064 2936 -6857560.807395 +3065 2936 -71902237.78217 +3066 2936 -21965599.32574 +3067 2936 15972183.1856 +3068 2936 -45381891.21762 +2937 2937 904416532.1423 +2938 2937 2.086162567139e-05 +2939 2937 8090376.36604 +2940 2937 102079011.1406 +2941 2937 -1.040101051331e-05 +2942 2937 2022594.092512 +2952 2937 -84201296.24904 +2953 2937 -55138888.87984 +2954 2937 21478720.31087 +2955 2937 -215223928.4788 +2956 2937 5.930662155151e-06 +2957 2937 -5707514.57167 +2958 2937 -85403197.39141 +2959 2937 55138888.87983 +2960 2937 -24029092.18165 +3030 2937 -25195798.91083 +3031 2937 15625000.00513 +3032 2937 8536049.989829 +3033 2937 -89115968.74764 +3034 2937 -2.875924110413e-06 +3035 2937 60031786.74372 +3036 2937 -36905217.31746 +3037 2937 -15625000.00514 +3038 2937 21394122.91072 +3045 2937 23319097.20481 +3046 2937 3.09944152832e-06 +3047 2937 571476.4150216 +3048 2937 137281674.8977 +3049 2937 7.092952728271e-06 +3050 2937 2285905.658981 +3051 2937 -24872960.07894 +3052 2937 -1.01625919342e-05 +3053 2937 571476.4150351 +3063 2937 -25660413.08922 +3064 2937 -15625000.00513 +3065 2937 -9107526.404853 +3066 2937 -92328809.14057 +3067 2937 5.915760993958e-06 +3068 2937 -62317692.40268 +3069 2937 -38047023.33633 +3070 2937 15625000.00513 +3071 2937 -21965599.32574 +2938 2938 772075853.7925 +2939 2938 -97082150.22431 +2940 2938 -1.037120819092e-05 +2941 2938 -107448453.121 +2942 2938 49870936.22305 +2952 2938 -55138888.87984 +2953 2938 -67658711.44716 +2954 2938 10710616.00625 +2955 2938 2.861022949219e-06 +2956 2938 27388705.35396 +2957 2938 -24270537.56804 +2958 2938 55138888.87983 +2959 2938 -68860612.58955 +2960 2938 13559921.56178 +3030 2938 15625000.00513 +3031 2938 -20508055.7522 +3032 2938 -8428858.489084 +3033 2938 -4.589557647705e-06 +3034 2938 -20365565.44178 +3035 2938 -6857560.807395 +3036 2938 -15625000.00514 +3037 2938 -32217474.15883 +3038 2938 15286419.29648 +3045 2938 4.559755325317e-06 +3046 2938 -36055819.793 +3047 2938 -35224114.49497 +3048 2938 6.973743438721e-06 +3049 2938 99779729.64718 +3050 2938 -27430243.21607 +3051 2938 -8.568167686462e-06 +3052 2938 -84247877.07676 +3053 2938 62654357.71105 +3063 2938 -15625000.00513 +3064 2938 -20972669.93059 +3065 2938 -9114622.378198 +3066 2938 4.619359970093e-06 +3067 2938 -23578405.83475 +3068 2938 -6857560.807395 +3069 2938 15625000.00513 +3070 2938 -33359280.17771 +3071 2938 15972183.1856 +2939 2939 828665098.5173 +2940 2939 2022594.092512 +2941 2939 47211214.00126 +2942 2939 52874910.70561 +2952 2939 22006498.08912 +2953 2939 11132838.22885 +2954 2939 -26647749.83379 +2955 2939 -2382861.794439 +2956 2939 -24270537.56804 +2957 2939 41183389.66318 +2958 2939 -23501314.4034 +2959 2939 13137699.33918 +2960 2939 -29852819.54686 +3030 2939 8536049.989829 +3031 2939 -8428858.489084 +3032 2939 -11111959.41625 +3033 2939 59688904.7995 +3034 2939 -6857560.807395 +3035 2939 -63334663.40088 +3036 2939 21394122.91072 +3037 2939 15286419.29648 +3038 2939 -42337075.16724 +3045 2939 571476.4150219 +3046 2939 -34949808.93959 +3047 2939 30014.53480115 +3048 2939 2285905.658981 +3049 2939 -27430243.21607 +3050 2939 -82530234.81935 +3051 2939 571476.4150354 +3052 2939 62380052.15567 +3053 2939 -128482138.2218 +3063 2939 -9107526.404853 +3064 2939 -9114622.378198 +3065 2939 -12350930.55863 +3066 2939 -61974810.45846 +3067 2939 -6857560.807395 +3068 2939 -71902237.78217 +3069 2939 -21965599.32574 +3070 2939 15972183.1856 +3071 2939 -45381891.21762 +2940 2940 904416532.1423 +2941 2940 2.086162567139e-05 +2942 2940 8090376.36604 +2943 2940 102079011.1406 +2944 2940 -1.040101051331e-05 +2945 2940 2022594.092512 +2955 2940 -84201296.24904 +2956 2940 -55138888.87984 +2957 2940 21478720.31087 +2958 2940 -215223928.4788 +2959 2940 5.930662155151e-06 +2960 2940 -5707514.57167 +2961 2940 -85403197.39141 +2962 2940 55138888.87983 +2963 2940 -24029092.18165 +3033 2940 -25195798.91083 +3034 2940 15625000.00513 +3035 2940 8536049.989829 +3036 2940 -89115968.74764 +3037 2940 -2.875924110413e-06 +3038 2940 60031786.74372 +3039 2940 -36905217.31746 +3040 2940 -15625000.00514 +3041 2940 21394122.91072 +3048 2940 23319097.20481 +3049 2940 3.09944152832e-06 +3050 2940 571476.4150216 +3051 2940 137281674.8977 +3052 2940 7.092952728271e-06 +3053 2940 2285905.658981 +3054 2940 -24872960.07894 +3055 2940 -1.01625919342e-05 +3056 2940 571476.4150351 +3066 2940 -25660413.08922 +3067 2940 -15625000.00513 +3068 2940 -9107526.404853 +3069 2940 -92328809.14057 +3070 2940 5.915760993958e-06 +3071 2940 -62317692.40268 +3072 2940 -38047023.33633 +3073 2940 15625000.00513 +3074 2940 -21965599.32574 +2941 2941 772075853.7925 +2942 2941 -97082150.22431 +2943 2941 -1.037120819092e-05 +2944 2941 -107448453.121 +2945 2941 49870936.22305 +2955 2941 -55138888.87984 +2956 2941 -67658711.44716 +2957 2941 10710616.00625 +2958 2941 2.861022949219e-06 +2959 2941 27388705.35396 +2960 2941 -24270537.56804 +2961 2941 55138888.87983 +2962 2941 -68860612.58955 +2963 2941 13559921.56178 +3033 2941 15625000.00513 +3034 2941 -20508055.7522 +3035 2941 -8428858.489084 +3036 2941 -4.589557647705e-06 +3037 2941 -20365565.44178 +3038 2941 -6857560.807395 +3039 2941 -15625000.00514 +3040 2941 -32217474.15883 +3041 2941 15286419.29648 +3048 2941 4.559755325317e-06 +3049 2941 -36055819.793 +3050 2941 -35224114.49497 +3051 2941 6.973743438721e-06 +3052 2941 99779729.64718 +3053 2941 -27430243.21607 +3054 2941 -8.568167686462e-06 +3055 2941 -84247877.07676 +3056 2941 62654357.71105 +3066 2941 -15625000.00513 +3067 2941 -20972669.93059 +3068 2941 -9114622.378198 +3069 2941 4.619359970093e-06 +3070 2941 -23578405.83475 +3071 2941 -6857560.807395 +3072 2941 15625000.00513 +3073 2941 -33359280.17771 +3074 2941 15972183.1856 +2942 2942 828665098.5173 +2943 2942 2022594.092512 +2944 2942 47211214.00126 +2945 2942 52874910.70561 +2955 2942 22006498.08912 +2956 2942 11132838.22885 +2957 2942 -26647749.83379 +2958 2942 -2382861.794439 +2959 2942 -24270537.56804 +2960 2942 41183389.66318 +2961 2942 -23501314.4034 +2962 2942 13137699.33918 +2963 2942 -29852819.54686 +3033 2942 8536049.989829 +3034 2942 -8428858.489084 +3035 2942 -11111959.41625 +3036 2942 59688904.7995 +3037 2942 -6857560.807395 +3038 2942 -63334663.40088 +3039 2942 21394122.91072 +3040 2942 15286419.29648 +3041 2942 -42337075.16724 +3048 2942 571476.4150219 +3049 2942 -34949808.93959 +3050 2942 30014.53480115 +3051 2942 2285905.658981 +3052 2942 -27430243.21607 +3053 2942 -82530234.81935 +3054 2942 571476.4150354 +3055 2942 62380052.15567 +3056 2942 -128482138.2218 +3066 2942 -9107526.404853 +3067 2942 -9114622.378198 +3068 2942 -12350930.55863 +3069 2942 -61974810.45846 +3070 2942 -6857560.807395 +3071 2942 -71902237.78217 +3072 2942 -21965599.32574 +3073 2942 15972183.1856 +3074 2942 -45381891.21762 +2943 2943 979444958.5446 +2944 2943 55192233.22997 +2945 2943 27299034.62316 +2946 2943 11141309.24956 +2947 2943 -55160226.61988 +2948 2943 24035972.54801 +2958 2943 -84201296.24904 +2959 2943 -55138888.87984 +2960 2943 21478720.31087 +2961 2943 -215223928.4788 +2962 2943 5.930662155151e-06 +2963 2943 -5707514.57167 +2964 2943 -85403197.39141 +2965 2943 55138888.87983 +2966 2943 -24029092.18165 +3036 2943 -25195798.91083 +3037 2943 15625000.00513 +3038 2943 8536049.989829 +3039 2943 -108451246.8934 +3040 2943 -15634880.35547 +3041 2943 54616251.09168 +3051 2943 23319097.20481 +3052 2943 3.09944152832e-06 +3053 2943 571476.4150216 +3054 2943 166227659.6012 +3055 2943 15641467.2557 +3056 2943 7711642.939084 +3057 2943 -41196855.08124 +3058 2943 -15631586.90536 +3059 2943 21974855.62738 +3069 2943 -25660413.08922 +3070 2943 -15625000.00513 +3071 2943 -9107526.404853 +3072 2943 -92328809.14057 +3073 2943 5.915760993958e-06 +3074 2943 -62317692.40268 +3075 2943 -38047023.33633 +3076 2943 15625000.00513 +3077 2943 -21965599.32574 +2944 2944 830537689.1138 +2945 2944 -75243257.69584 +2946 2944 -55170895.48991 +2947 2944 -181886245.1745 +2948 2944 41627208.49512 +2958 2944 -55138888.87984 +2959 2944 -67658711.44716 +2960 2944 10710616.00625 +2961 2944 2.861022949219e-06 +2962 2944 27388705.35396 +2963 2944 -24270537.56804 +2964 2944 55138888.87983 +2965 2944 -68860612.58955 +2966 2944 13559921.56178 +3036 2944 15625000.00513 +3037 2944 -20508055.7522 +3038 2944 -8428858.489084 +3039 2944 -15631586.90536 +3040 2944 -34992516.13117 +3041 2944 4591649.47589 +3051 2944 4.559755325317e-06 +3052 2944 -36055819.793 +3053 2944 -35224114.49497 +3054 2944 15641467.2557 +3055 2944 124030560.5447 +3056 2944 -21261017.33538 +3057 2944 -15634880.35547 +3058 2944 -95897202.5708 +3059 2944 60337907.00837 +3069 2944 -15625000.00513 +3070 2944 -20972669.93059 +3071 2944 -9114622.378198 +3072 2944 4.619359970093e-06 +3073 2944 -23578405.83475 +3074 2944 -6857560.807395 +3075 2944 15625000.00513 +3076 2944 -33359280.17771 +3077 2944 15972183.1856 +2945 2945 830564689.2359 +2946 2945 23511634.95294 +2947 2945 45765068.67361 +2948 2945 8306087.457417 +2958 2945 22006498.08912 +2959 2945 11132838.22885 +2960 2945 -26647749.83379 +2961 2945 -2382861.794439 +2962 2945 -24270537.56804 +2963 2945 41183389.66318 +2964 2945 -23501314.4034 +2965 2945 13137699.33918 +2966 2945 -29852819.54686 +3036 2945 8536049.989829 +3037 2945 -8428858.489084 +3038 2945 -11111959.41625 +3039 2945 54272044.11297 +3040 2945 2673044.969291 +3041 2945 -58743091.68526 +3051 2945 571476.4150219 +3052 2945 -34949808.93959 +3053 2945 30014.53480115 +3054 2945 7718068.787606 +3055 2945 -21255876.71511 +3056 2945 -61506429.36468 +3057 2945 21979483.77819 +3058 2945 61984848.42173 +3059 2945 -115922513.565 +3069 2945 -9107526.404853 +3070 2945 -9114622.378198 +3071 2945 -12350930.55863 +3072 2945 -61974810.45846 +3073 2945 -6857560.807395 +3074 2945 -71902237.78217 +3075 2945 -21965599.32574 +3076 2945 15972183.1856 +3077 2945 -45381891.21762 +2946 2946 471649908.3269 +2947 2946 4090177.427809 +2948 2946 -2249173.036816 +2961 2946 -84201296.24904 +2962 2946 -55138888.87984 +2963 2946 21478720.31087 +2964 2946 -194821525.5646 +2965 2946 -4169934.661672 +2966 2946 -3538592.307103 +2967 2946 -41570569.89579 +2968 2946 44190868.33773 +2969 2946 -317590.9217181 +3039 2946 2359203.743841 +3040 2946 18759880.3565 +3041 2946 10591538.29392 +3054 2946 -4242975.331225 +3055 2946 -15634880.35547 +3056 2946 -8541442.446936 +3057 2946 71156841.17391 +3058 2946 4155152.359052 +3059 2946 7042994.495851 +3072 2946 -25660413.08922 +3073 2946 -15625000.00513 +3074 2946 -9107526.404853 +3075 2946 -85661283.17682 +3076 2946 -4175995.441555 +3077 2946 -50365747.51323 +3078 2946 -15271213.05259 +3079 2946 12520843.08662 +3080 2946 -8434357.784819 +2947 2947 492388135.1167 +2948 2947 -56289934.73763 +2961 2947 -55138888.87984 +2962 2947 -67658711.44716 +2963 2947 10710616.00625 +2964 2947 -4209813.278604 +2965 2947 41607978.37358 +2966 2947 -16842698.76085 +2967 2947 66286302.50659 +2968 2947 -122253331.0016 +2969 2947 11767705.63164 +3039 2947 12506586.90433 +3040 2947 2359203.743842 +3041 2947 -5648902.101029 +3054 2947 -15631586.90535 +3055 2947 -58943322.82077 +3056 2947 -35645020.83586 +3057 2947 4155152.359051 +3058 2947 67360267.87028 +3059 2947 -9155848.283368 +3072 2947 -15625000.00513 +3073 2947 -20972669.93059 +3074 2947 -9114622.378198 +3075 2947 -4186416.982811 +3076 2947 -17320437.94929 +3077 2947 -7812334.815313 +3078 2947 18781264.62992 +3079 2947 -29802880.64558 +3080 2947 20359407.72444 +2948 2948 461481303.1457 +2961 2948 22006498.08912 +2962 2948 11132838.22885 +2963 2948 -26647749.83379 +2964 2948 -6432474.979055 +2965 2948 -14600300.1054 +2966 2948 19559986.82562 +2967 2948 -476386.3825763 +2968 2948 10796323.33859 +2969 2948 -30172091.94962 +3039 2948 7061025.529277 +3040 2948 -8473353.151544 +3041 2948 6291209.983575 +3054 2948 -8539644.961234 +3055 2948 -37291962.41402 +3056 2948 -17378834.23163 +3057 2948 -12904614.21255 +3058 2948 -25102929.94573 +3059 2948 -43665037.20838 +3072 2948 -9107526.404853 +3073 2948 -9114622.378198 +3074 2948 -12350930.55863 +3075 2948 -52079515.31352 +3076 2948 -7529299.332116 +3077 2948 -59557746.72338 +3078 2948 -12651536.67723 +3079 2948 16986186.18761 +3080 2948 -26191567.2139 +2949 2949 904416532.1423 +2950 2949 2.086162567139e-05 +2951 2949 8090376.36604 +2952 2949 102079011.1406 +2953 2949 -1.040101051331e-05 +2954 2949 2022594.092512 +2970 2949 -215223928.4788 +2971 2949 5.930662155151e-06 +2972 2949 -5707514.57167 +2973 2949 -85403197.39141 +2974 2949 55138888.87983 +2975 2949 -24029092.18165 +3042 2949 -89115968.74764 +3043 2949 -2.875924110413e-06 +3044 2949 60031786.74372 +3045 2949 -36905217.31746 +3046 2949 -15625000.00514 +3047 2949 21394122.91072 +3060 2949 137281674.8977 +3061 2949 7.092952728271e-06 +3062 2949 2285905.658981 +3063 2949 -24872960.07894 +3064 2949 -1.01625919342e-05 +3065 2949 571476.4150351 +3081 2949 -92328809.14057 +3082 2949 5.915760993958e-06 +3083 2949 -62317692.40268 +3084 2949 -38047023.33633 +3085 2949 15625000.00513 +3086 2949 -21965599.32574 +2950 2950 772075853.7925 +2951 2950 -97082150.22431 +2952 2950 -1.037120819092e-05 +2953 2950 -107448453.121 +2954 2950 49870936.22305 +2970 2950 2.861022949219e-06 +2971 2950 27388705.35396 +2972 2950 -24270537.56804 +2973 2950 55138888.87983 +2974 2950 -68860612.58955 +2975 2950 13559921.56178 +3042 2950 -4.589557647705e-06 +3043 2950 -20365565.44178 +3044 2950 -6857560.807395 +3045 2950 -15625000.00514 +3046 2950 -32217474.15883 +3047 2950 15286419.29648 +3060 2950 6.973743438721e-06 +3061 2950 99779729.64718 +3062 2950 -27430243.21607 +3063 2950 -8.568167686462e-06 +3064 2950 -84247877.07676 +3065 2950 62654357.71105 +3081 2950 4.619359970093e-06 +3082 2950 -23578405.83475 +3083 2950 -6857560.807395 +3084 2950 15625000.00513 +3085 2950 -33359280.17771 +3086 2950 15972183.1856 +2951 2951 828665098.5173 +2952 2951 2022594.092512 +2953 2951 47211214.00126 +2954 2951 52874910.70561 +2970 2951 -2382861.794439 +2971 2951 -24270537.56804 +2972 2951 41183389.66318 +2973 2951 -23501314.4034 +2974 2951 13137699.33918 +2975 2951 -29852819.54686 +3042 2951 59688904.7995 +3043 2951 -6857560.807395 +3044 2951 -63334663.40088 +3045 2951 21394122.91072 +3046 2951 15286419.29648 +3047 2951 -42337075.16724 +3060 2951 2285905.658981 +3061 2951 -27430243.21607 +3062 2951 -82530234.81935 +3063 2951 571476.4150354 +3064 2951 62380052.15567 +3065 2951 -128482138.2218 +3081 2951 -61974810.45846 +3082 2951 -6857560.807395 +3083 2951 -71902237.78217 +3084 2951 -21965599.32574 +3085 2951 15972183.1856 +3086 2951 -45381891.21762 +2952 2952 904416532.1423 +2953 2952 2.086162567139e-05 +2954 2952 8090376.36604 +2955 2952 102079011.1406 +2956 2952 -1.040101051331e-05 +2957 2952 2022594.092512 +2970 2952 -84201296.24904 +2971 2952 -55138888.87984 +2972 2952 21478720.31087 +2973 2952 -215223928.4788 +2974 2952 5.930662155151e-06 +2975 2952 -5707514.57167 +2976 2952 -85403197.39141 +2977 2952 55138888.87983 +2978 2952 -24029092.18165 +3042 2952 -25195798.91083 +3043 2952 15625000.00513 +3044 2952 8536049.989829 +3045 2952 -89115968.74764 +3046 2952 -2.875924110413e-06 +3047 2952 60031786.74372 +3048 2952 -36905217.31746 +3049 2952 -15625000.00514 +3050 2952 21394122.91072 +3060 2952 23319097.20481 +3061 2952 3.09944152832e-06 +3062 2952 571476.4150216 +3063 2952 137281674.8977 +3064 2952 7.092952728271e-06 +3065 2952 2285905.658981 +3066 2952 -24872960.07894 +3067 2952 -1.01625919342e-05 +3068 2952 571476.4150351 +3081 2952 -25660413.08922 +3082 2952 -15625000.00513 +3083 2952 -9107526.404853 +3084 2952 -92328809.14057 +3085 2952 5.915760993958e-06 +3086 2952 -62317692.40268 +3087 2952 -38047023.33633 +3088 2952 15625000.00513 +3089 2952 -21965599.32574 +2953 2953 772075853.7925 +2954 2953 -97082150.22431 +2955 2953 -1.037120819092e-05 +2956 2953 -107448453.121 +2957 2953 49870936.22305 +2970 2953 -55138888.87984 +2971 2953 -67658711.44716 +2972 2953 10710616.00625 +2973 2953 2.861022949219e-06 +2974 2953 27388705.35396 +2975 2953 -24270537.56804 +2976 2953 55138888.87983 +2977 2953 -68860612.58955 +2978 2953 13559921.56178 +3042 2953 15625000.00513 +3043 2953 -20508055.7522 +3044 2953 -8428858.489084 +3045 2953 -4.589557647705e-06 +3046 2953 -20365565.44178 +3047 2953 -6857560.807395 +3048 2953 -15625000.00514 +3049 2953 -32217474.15883 +3050 2953 15286419.29648 +3060 2953 4.559755325317e-06 +3061 2953 -36055819.793 +3062 2953 -35224114.49497 +3063 2953 6.973743438721e-06 +3064 2953 99779729.64718 +3065 2953 -27430243.21607 +3066 2953 -8.568167686462e-06 +3067 2953 -84247877.07676 +3068 2953 62654357.71105 +3081 2953 -15625000.00513 +3082 2953 -20972669.93059 +3083 2953 -9114622.378198 +3084 2953 4.619359970093e-06 +3085 2953 -23578405.83475 +3086 2953 -6857560.807395 +3087 2953 15625000.00513 +3088 2953 -33359280.17771 +3089 2953 15972183.1856 +2954 2954 828665098.5173 +2955 2954 2022594.092512 +2956 2954 47211214.00126 +2957 2954 52874910.70561 +2970 2954 22006498.08912 +2971 2954 11132838.22885 +2972 2954 -26647749.83379 +2973 2954 -2382861.794439 +2974 2954 -24270537.56804 +2975 2954 41183389.66318 +2976 2954 -23501314.4034 +2977 2954 13137699.33918 +2978 2954 -29852819.54686 +3042 2954 8536049.989829 +3043 2954 -8428858.489084 +3044 2954 -11111959.41625 +3045 2954 59688904.7995 +3046 2954 -6857560.807395 +3047 2954 -63334663.40088 +3048 2954 21394122.91072 +3049 2954 15286419.29648 +3050 2954 -42337075.16724 +3060 2954 571476.4150219 +3061 2954 -34949808.93959 +3062 2954 30014.53480115 +3063 2954 2285905.658981 +3064 2954 -27430243.21607 +3065 2954 -82530234.81935 +3066 2954 571476.4150354 +3067 2954 62380052.15567 +3068 2954 -128482138.2218 +3081 2954 -9107526.404853 +3082 2954 -9114622.378198 +3083 2954 -12350930.55863 +3084 2954 -61974810.45846 +3085 2954 -6857560.807395 +3086 2954 -71902237.78217 +3087 2954 -21965599.32574 +3088 2954 15972183.1856 +3089 2954 -45381891.21762 +2955 2955 904416532.1423 +2956 2955 2.086162567139e-05 +2957 2955 8090376.36604 +2958 2955 102079011.1406 +2959 2955 -1.040101051331e-05 +2960 2955 2022594.092512 +2973 2955 -84201296.24904 +2974 2955 -55138888.87984 +2975 2955 21478720.31087 +2976 2955 -215223928.4788 +2977 2955 5.930662155151e-06 +2978 2955 -5707514.57167 +2979 2955 -85403197.39141 +2980 2955 55138888.87983 +2981 2955 -24029092.18165 +3045 2955 -25195798.91083 +3046 2955 15625000.00513 +3047 2955 8536049.989829 +3048 2955 -89115968.74764 +3049 2955 -2.875924110413e-06 +3050 2955 60031786.74372 +3051 2955 -36905217.31746 +3052 2955 -15625000.00514 +3053 2955 21394122.91072 +3063 2955 23319097.20481 +3064 2955 3.09944152832e-06 +3065 2955 571476.4150216 +3066 2955 137281674.8977 +3067 2955 7.092952728271e-06 +3068 2955 2285905.658981 +3069 2955 -24872960.07894 +3070 2955 -1.01625919342e-05 +3071 2955 571476.4150351 +3084 2955 -25660413.08922 +3085 2955 -15625000.00513 +3086 2955 -9107526.404853 +3087 2955 -92328809.14057 +3088 2955 5.915760993958e-06 +3089 2955 -62317692.40268 +3090 2955 -38047023.33633 +3091 2955 15625000.00513 +3092 2955 -21965599.32574 +2956 2956 772075853.7925 +2957 2956 -97082150.22431 +2958 2956 -1.037120819092e-05 +2959 2956 -107448453.121 +2960 2956 49870936.22305 +2973 2956 -55138888.87984 +2974 2956 -67658711.44716 +2975 2956 10710616.00625 +2976 2956 2.861022949219e-06 +2977 2956 27388705.35396 +2978 2956 -24270537.56804 +2979 2956 55138888.87983 +2980 2956 -68860612.58955 +2981 2956 13559921.56178 +3045 2956 15625000.00513 +3046 2956 -20508055.7522 +3047 2956 -8428858.489084 +3048 2956 -4.589557647705e-06 +3049 2956 -20365565.44178 +3050 2956 -6857560.807395 +3051 2956 -15625000.00514 +3052 2956 -32217474.15883 +3053 2956 15286419.29648 +3063 2956 4.559755325317e-06 +3064 2956 -36055819.793 +3065 2956 -35224114.49497 +3066 2956 6.973743438721e-06 +3067 2956 99779729.64718 +3068 2956 -27430243.21607 +3069 2956 -8.568167686462e-06 +3070 2956 -84247877.07676 +3071 2956 62654357.71105 +3084 2956 -15625000.00513 +3085 2956 -20972669.93059 +3086 2956 -9114622.378198 +3087 2956 4.619359970093e-06 +3088 2956 -23578405.83475 +3089 2956 -6857560.807395 +3090 2956 15625000.00513 +3091 2956 -33359280.17771 +3092 2956 15972183.1856 +2957 2957 828665098.5173 +2958 2957 2022594.092512 +2959 2957 47211214.00126 +2960 2957 52874910.70561 +2973 2957 22006498.08912 +2974 2957 11132838.22885 +2975 2957 -26647749.83379 +2976 2957 -2382861.794439 +2977 2957 -24270537.56804 +2978 2957 41183389.66318 +2979 2957 -23501314.4034 +2980 2957 13137699.33918 +2981 2957 -29852819.54686 +3045 2957 8536049.989829 +3046 2957 -8428858.489084 +3047 2957 -11111959.41625 +3048 2957 59688904.7995 +3049 2957 -6857560.807395 +3050 2957 -63334663.40088 +3051 2957 21394122.91072 +3052 2957 15286419.29648 +3053 2957 -42337075.16724 +3063 2957 571476.4150219 +3064 2957 -34949808.93959 +3065 2957 30014.53480115 +3066 2957 2285905.658981 +3067 2957 -27430243.21607 +3068 2957 -82530234.81935 +3069 2957 571476.4150354 +3070 2957 62380052.15567 +3071 2957 -128482138.2218 +3084 2957 -9107526.404853 +3085 2957 -9114622.378198 +3086 2957 -12350930.55863 +3087 2957 -61974810.45846 +3088 2957 -6857560.807395 +3089 2957 -71902237.78217 +3090 2957 -21965599.32574 +3091 2957 15972183.1856 +3092 2957 -45381891.21762 +2958 2958 904416532.1423 +2959 2958 2.086162567139e-05 +2960 2958 8090376.36604 +2961 2958 102079011.1406 +2962 2958 -1.040101051331e-05 +2963 2958 2022594.092512 +2976 2958 -84201296.24904 +2977 2958 -55138888.87984 +2978 2958 21478720.31087 +2979 2958 -215223928.4788 +2980 2958 5.930662155151e-06 +2981 2958 -5707514.57167 +2982 2958 -85403197.39141 +2983 2958 55138888.87983 +2984 2958 -24029092.18165 +3048 2958 -25195798.91083 +3049 2958 15625000.00513 +3050 2958 8536049.989829 +3051 2958 -89115968.74764 +3052 2958 -2.875924110413e-06 +3053 2958 60031786.74372 +3054 2958 -36905217.31746 +3055 2958 -15625000.00514 +3056 2958 21394122.91072 +3066 2958 23319097.20481 +3067 2958 3.09944152832e-06 +3068 2958 571476.4150216 +3069 2958 137281674.8977 +3070 2958 7.092952728271e-06 +3071 2958 2285905.658981 +3072 2958 -24872960.07894 +3073 2958 -1.01625919342e-05 +3074 2958 571476.4150351 +3087 2958 -25660413.08922 +3088 2958 -15625000.00513 +3089 2958 -9107526.404853 +3090 2958 -92328809.14057 +3091 2958 5.915760993958e-06 +3092 2958 -62317692.40268 +3093 2958 -38047023.33633 +3094 2958 15625000.00513 +3095 2958 -21965599.32574 +2959 2959 772075853.7925 +2960 2959 -97082150.22431 +2961 2959 -1.037120819092e-05 +2962 2959 -107448453.121 +2963 2959 49870936.22305 +2976 2959 -55138888.87984 +2977 2959 -67658711.44716 +2978 2959 10710616.00625 +2979 2959 2.861022949219e-06 +2980 2959 27388705.35396 +2981 2959 -24270537.56804 +2982 2959 55138888.87983 +2983 2959 -68860612.58955 +2984 2959 13559921.56178 +3048 2959 15625000.00513 +3049 2959 -20508055.7522 +3050 2959 -8428858.489084 +3051 2959 -4.589557647705e-06 +3052 2959 -20365565.44178 +3053 2959 -6857560.807395 +3054 2959 -15625000.00514 +3055 2959 -32217474.15883 +3056 2959 15286419.29648 +3066 2959 4.559755325317e-06 +3067 2959 -36055819.793 +3068 2959 -35224114.49497 +3069 2959 6.973743438721e-06 +3070 2959 99779729.64718 +3071 2959 -27430243.21607 +3072 2959 -8.568167686462e-06 +3073 2959 -84247877.07676 +3074 2959 62654357.71105 +3087 2959 -15625000.00513 +3088 2959 -20972669.93059 +3089 2959 -9114622.378198 +3090 2959 4.619359970093e-06 +3091 2959 -23578405.83475 +3092 2959 -6857560.807395 +3093 2959 15625000.00513 +3094 2959 -33359280.17771 +3095 2959 15972183.1856 +2960 2960 828665098.5173 +2961 2960 2022594.092512 +2962 2960 47211214.00126 +2963 2960 52874910.70561 +2976 2960 22006498.08912 +2977 2960 11132838.22885 +2978 2960 -26647749.83379 +2979 2960 -2382861.794439 +2980 2960 -24270537.56804 +2981 2960 41183389.66318 +2982 2960 -23501314.4034 +2983 2960 13137699.33918 +2984 2960 -29852819.54686 +3048 2960 8536049.989829 +3049 2960 -8428858.489084 +3050 2960 -11111959.41625 +3051 2960 59688904.7995 +3052 2960 -6857560.807395 +3053 2960 -63334663.40088 +3054 2960 21394122.91072 +3055 2960 15286419.29648 +3056 2960 -42337075.16724 +3066 2960 571476.4150219 +3067 2960 -34949808.93959 +3068 2960 30014.53480115 +3069 2960 2285905.658981 +3070 2960 -27430243.21607 +3071 2960 -82530234.81935 +3072 2960 571476.4150354 +3073 2960 62380052.15567 +3074 2960 -128482138.2218 +3087 2960 -9107526.404853 +3088 2960 -9114622.378198 +3089 2960 -12350930.55863 +3090 2960 -61974810.45846 +3091 2960 -6857560.807395 +3092 2960 -71902237.78217 +3093 2960 -21965599.32574 +3094 2960 15972183.1856 +3095 2960 -45381891.21762 +2961 2961 904416532.1423 +2962 2961 2.086162567139e-05 +2963 2961 8090376.36604 +2964 2961 102079011.1406 +2965 2961 -1.040101051331e-05 +2966 2961 2022594.092512 +2979 2961 -84201296.24904 +2980 2961 -55138888.87984 +2981 2961 21478720.31087 +2982 2961 -215223928.4788 +2983 2961 5.930662155151e-06 +2984 2961 -5707514.57167 +2985 2961 -85403197.39141 +2986 2961 55138888.87983 +2987 2961 -24029092.18165 +3051 2961 -25195798.91083 +3052 2961 15625000.00513 +3053 2961 8536049.989829 +3054 2961 -89115968.74764 +3055 2961 -2.875924110413e-06 +3056 2961 60031786.74372 +3057 2961 -36905217.31746 +3058 2961 -15625000.00514 +3059 2961 21394122.91072 +3069 2961 23319097.20481 +3070 2961 3.09944152832e-06 +3071 2961 571476.4150216 +3072 2961 137281674.8977 +3073 2961 7.092952728271e-06 +3074 2961 2285905.658981 +3075 2961 -24872960.07894 +3076 2961 -1.01625919342e-05 +3077 2961 571476.4150351 +3090 2961 -25660413.08922 +3091 2961 -15625000.00513 +3092 2961 -9107526.404853 +3093 2961 -92328809.14057 +3094 2961 5.915760993958e-06 +3095 2961 -62317692.40268 +3096 2961 -38047023.33633 +3097 2961 15625000.00513 +3098 2961 -21965599.32574 +2962 2962 772075853.7925 +2963 2962 -97082150.22431 +2964 2962 -1.037120819092e-05 +2965 2962 -107448453.121 +2966 2962 49870936.22305 +2979 2962 -55138888.87984 +2980 2962 -67658711.44716 +2981 2962 10710616.00625 +2982 2962 2.861022949219e-06 +2983 2962 27388705.35396 +2984 2962 -24270537.56804 +2985 2962 55138888.87983 +2986 2962 -68860612.58955 +2987 2962 13559921.56178 +3051 2962 15625000.00513 +3052 2962 -20508055.7522 +3053 2962 -8428858.489084 +3054 2962 -4.589557647705e-06 +3055 2962 -20365565.44178 +3056 2962 -6857560.807395 +3057 2962 -15625000.00514 +3058 2962 -32217474.15883 +3059 2962 15286419.29648 +3069 2962 4.559755325317e-06 +3070 2962 -36055819.793 +3071 2962 -35224114.49497 +3072 2962 6.973743438721e-06 +3073 2962 99779729.64718 +3074 2962 -27430243.21607 +3075 2962 -8.568167686462e-06 +3076 2962 -84247877.07676 +3077 2962 62654357.71105 +3090 2962 -15625000.00513 +3091 2962 -20972669.93059 +3092 2962 -9114622.378198 +3093 2962 4.619359970093e-06 +3094 2962 -23578405.83475 +3095 2962 -6857560.807395 +3096 2962 15625000.00513 +3097 2962 -33359280.17771 +3098 2962 15972183.1856 +2963 2963 828665098.5173 +2964 2963 2022594.092512 +2965 2963 47211214.00126 +2966 2963 52874910.70561 +2979 2963 22006498.08912 +2980 2963 11132838.22885 +2981 2963 -26647749.83379 +2982 2963 -2382861.794439 +2983 2963 -24270537.56804 +2984 2963 41183389.66318 +2985 2963 -23501314.4034 +2986 2963 13137699.33918 +2987 2963 -29852819.54686 +3051 2963 8536049.989829 +3052 2963 -8428858.489084 +3053 2963 -11111959.41625 +3054 2963 59688904.7995 +3055 2963 -6857560.807395 +3056 2963 -63334663.40088 +3057 2963 21394122.91072 +3058 2963 15286419.29648 +3059 2963 -42337075.16724 +3069 2963 571476.4150219 +3070 2963 -34949808.93959 +3071 2963 30014.53480115 +3072 2963 2285905.658981 +3073 2963 -27430243.21607 +3074 2963 -82530234.81935 +3075 2963 571476.4150354 +3076 2963 62380052.15567 +3077 2963 -128482138.2218 +3090 2963 -9107526.404853 +3091 2963 -9114622.378198 +3092 2963 -12350930.55863 +3093 2963 -61974810.45846 +3094 2963 -6857560.807395 +3095 2963 -71902237.78217 +3096 2963 -21965599.32574 +3097 2963 15972183.1856 +3098 2963 -45381891.21762 +2964 2964 814075637.7522 +2965 2964 19826669.68419 +2966 2964 7801715.663611 +2967 2964 -65761289.34655 +2968 2964 -82916487.90402 +2969 2964 5254868.213648 +2982 2964 -84201296.24904 +2983 2964 -55138888.87984 +2984 2964 21478720.31087 +2985 2964 -168878204.1951 +2986 2964 23258599.89119 +2987 2964 -2713120.011329 +2988 2964 -50129008.36995 +2989 2964 44041031.60725 +2990 2964 -3923688.173615 +3054 2964 -25195798.91083 +3055 2964 15625000.00513 +3056 2964 8536049.989829 +3057 2964 -82406367.71958 +3058 2964 -4186416.982814 +3059 2964 47658528.22846 +3072 2964 23319097.20481 +3073 2964 3.09944152832e-06 +3074 2964 571476.4150216 +3075 2964 140289807.8107 +3076 2964 6772533.290107 +3077 2964 2258936.462364 +3078 2964 -37259112.25684 +3079 2964 -21706836.85395 +3080 2964 16585652.20803 +3093 2964 -25660413.08922 +3094 2964 -15625000.00513 +3095 2964 -9107526.404853 +3096 2964 -80438815.71638 +3097 2964 5389707.749941 +3098 2964 -55764807.73549 +3099 2964 -23249696.87928 +3100 2964 13731012.79672 +3101 2964 -10699392.80394 +2965 2965 816271924.2702 +2966 2965 -59395775.03478 +2967 2965 -82956366.52095 +2968 2965 -269665196.5266 +2969 2965 11419191.28908 +2982 2965 -55138888.87984 +2983 2965 -67658711.44716 +2984 2965 10710616.00625 +2985 2965 23258599.89119 +2986 2965 40051295.91808 +2987 2965 -13759219.77655 +2988 2965 44041031.60725 +2989 2965 -117338097.1014 +2990 2965 5266414.972266 +3054 2965 15625000.00513 +3055 2965 -20508055.7522 +3056 2965 -8428858.489084 +3057 2965 -4175995.441561 +3058 2965 -14065522.49202 +3059 2965 -990203.8002845 +3072 2965 4.559755325317e-06 +3073 2965 -36055819.793 +3074 2965 -35224114.49497 +3075 2965 6772533.290104 +3076 2965 130991394.7564 +3077 2965 -16346341.23076 +3078 2965 -21717258.3952 +3079 2965 -93858000.46159 +3080 2965 51628535.64867 +3093 2965 -15625000.00513 +3094 2965 -20972669.93059 +3095 2965 -9114622.378198 +3096 2965 5389707.74994 +3097 2965 -18709904.78939 +3098 2965 551807.7684063 +3099 2965 13731012.79672 +3100 2965 -37422721.09417 +3101 2965 17954931.21862 +2966 2966 718413885.6964 +2967 2966 4727899.785733 +2968 2966 9730121.401043 +2969 2966 -41602774.38176 +2982 2966 22006498.08912 +2983 2966 11132838.22885 +2984 2966 -26647749.83379 +2985 2966 -6141939.455212 +2986 2966 -13336997.5544 +2987 2966 45476816.52765 +2988 2966 -2868132.617115 +2989 2966 5266414.972266 +2990 2966 -26328581.92312 +3054 2966 8536049.989829 +3055 2966 -8428858.489084 +3056 2966 -11111959.41625 +3057 2966 49372296.02875 +3058 2966 -1256982.046803 +3059 2966 -50877972.17063 +3072 2966 571476.4150219 +3073 2966 -34949808.93959 +3074 2966 30014.53480115 +3075 2966 2271788.22959 +3076 2966 -16336059.44644 +3077 2966 -52248020.85153 +3078 2966 16592900.54232 +3079 2966 51626293.67586 +3080 2966 -71025741.42099 +3093 2966 -9107526.404853 +3094 2966 -9114622.378198 +3095 2966 -12350930.55863 +3096 2966 -57479217.4576 +3097 2966 551807.7692189 +3098 2966 -67478321.27656 +3099 2966 -10699392.80394 +3100 2966 17954931.21862 +3101 2966 -29873867.65783 +2967 2967 522699975.3476 +2968 2967 14401653.43661 +2969 2967 5480581.188058 +2985 2967 -88453382.41505 +2986 2967 -53657199.77512 +2987 2967 2927126.633331 +2988 2967 -82446521.24533 +2989 2967 31900352.3773 +2990 2967 -2622745.842299 +2991 2967 63364875.38512 +2992 2967 -23947462.52149 +2993 2967 -309579.7647879 +2994 2967 -33820950.3989 +2995 2967 47972720.49706 +2996 2967 -966478.9499935 +3057 2967 -11503559.48192 +3058 2967 18781264.62992 +3059 2967 10589309.89512 +3075 2967 -30633021.82547 +3076 2967 -21717258.3952 +3077 2967 -13945914.77582 +3078 2967 49344074.06461 +3079 2967 3326270.339925 +3080 2967 12071955.85504 +3096 2967 -31620669.8148 +3097 2967 -15379874.43217 +3098 2967 -14331642.3119 +3099 2967 -70715365.81126 +3100 2967 7245060.881563 +3101 2967 -60340756.14738 +3102 2967 -8245159.844818 +3103 2967 -6206126.610077 +3104 2967 9626373.964429 +3105 2967 -23495676.93737 +3106 2967 13950663.58603 +3107 2967 -14935854.25772 +2968 2968 692282026.6453 +2969 2968 -10934150.66836 +2985 2968 -53657199.77512 +2986 2968 -54325438.18194 +2987 2968 342360.8843877 +2988 2968 31900352.3773 +2989 2968 124141079.4718 +2990 2968 -3927122.654523 +2991 2968 -1891906.969555 +2992 2968 -43813315.28894 +2993 2968 468835.5341619 +2994 2968 47972720.49706 +2995 2968 -52353687.68695 +2996 2968 533425.4164016 +3057 2968 12520843.08662 +3058 2968 -26035227.07491 +3059 2968 -13303837.81403 +3075 2968 -21706836.85395 +3076 2968 -87231910.03023 +3077 2968 -46041232.49696 +3078 2968 3326270.339925 +3079 2968 86203793.01102 +3080 2968 -505092.831848 +3096 2968 -15379874.43217 +3097 2968 -23056649.34309 +3098 2968 -11981607.60917 +3099 2968 7245060.881562 +3100 2968 -10705979.44983 +3101 2968 3493527.891282 +3102 2968 43873.39197527 +3103 2968 -38645654.17828 +3104 2968 33463119.42263 +3105 2968 13950663.58603 +3106 2968 -27397752.58572 +3107 2968 16811021.49711 +2969 2969 599530521.1754 +2985 2969 3454904.411581 +2986 2969 764583.1069877 +2987 2969 -19025929.82132 +2988 2969 -511634.7315344 +2989 2969 -3504900.43237 +2990 2969 126985993.5352 +2991 2969 218198.0129062 +2992 2969 468835.534162 +2993 2969 83129752.20461 +2994 2969 -438701.1717439 +2995 2969 533425.4164016 +2996 2969 11853562.38723 +3057 2969 7059539.930081 +3058 2969 -16128398.1209 +3059 2969 -16144491.02544 +3075 2969 -13940311.47962 +3076 2969 -46044966.08591 +3077 2969 -53356166.93734 +3078 2969 -11912141.36324 +3079 2969 -6708849.907338 +3080 2969 -90858994.86437 +3096 2969 -14331642.3119 +3097 2969 -11981607.60917 +3098 2969 -23323530.90453 +3099 2969 -60340756.14772 +3100 2969 3493527.892095 +3101 2969 -76697228.99476 +3102 2969 1501373.962777 +3103 2969 33463119.42263 +3104 2969 -47613841.53847 +3105 2969 -14935854.25772 +3106 2969 16811021.49711 +3107 2969 -30324091.47117 +2970 2970 451998787.7349 +2971 2970 1.800060272217e-05 +2972 2970 -4266443.760058 +2973 2970 51007167.67192 +2974 2970 11027777.77596 +2975 2970 -4858928.64862 +3060 2970 -89115968.74764 +3061 2970 -2.875924110413e-06 +3062 2970 60031786.74372 +3063 2970 -36905217.31746 +3064 2970 -15625000.00514 +3065 2970 21394122.91072 +3081 2970 68618264.38753 +3082 2970 3.814697265625e-06 +3083 2970 -11914911.75127 +3084 2970 -12436480.03947 +3085 2970 3125000.001022 +3086 2970 -4050234.016128 +2971 2971 385828448.56 +2972 2971 -48541075.11215 +2973 2971 -11027777.77597 +2974 2971 -53756564.45888 +2975 2971 24692759.77823 +3060 2971 -4.589557647705e-06 +3061 2971 -20365565.44178 +3062 2971 -6857560.807395 +3063 2971 -15625000.00514 +3064 2971 -32217474.15883 +3065 2971 15286419.29648 +3081 2971 2.026557922363e-06 +3082 2971 49867291.76226 +3083 2971 -13715121.60804 +3084 2971 -3125000.001031 +3085 2971 -42123938.53837 +3086 2971 31258602.46661 +2972 2972 413773940.3619 +2973 2972 4242633.849883 +2974 2972 23848315.33392 +2975 2972 26351220.95709 +3060 2972 59688904.7995 +3061 2972 -6857560.807395 +3062 2972 -63334663.40088 +3063 2972 21394122.91072 +3064 2972 15286419.29648 +3065 2972 -42337075.16724 +3081 2972 12486407.68916 +3082 2972 -13715121.60804 +3083 2972 -41325312.23988 +3084 2972 4621710.431164 +3085 2972 31258602.46674 +3086 2972 -64241069.11092 +2973 2973 451998787.7349 +2974 2973 1.800060272217e-05 +2975 2973 -4266443.760058 +2976 2973 51007167.67192 +2977 2973 11027777.77596 +2978 2973 -4858928.64862 +3060 2973 -25195798.91083 +3061 2973 15625000.00513 +3062 2973 8536049.989829 +3063 2973 -89115968.74764 +3064 2973 -2.875924110413e-06 +3065 2973 60031786.74372 +3066 2973 -36905217.31746 +3067 2973 -15625000.00514 +3068 2973 21394122.91072 +3081 2973 11659548.6024 +3082 2973 -3125000.001025 +3083 2973 -1478619.431957 +3084 2973 68618264.38753 +3085 2973 3.814697265625e-06 +3086 2973 -11914911.75127 +3087 2973 -12436480.03947 +3088 2973 3125000.001022 +3089 2973 -4050234.016128 +2974 2974 385828448.56 +2975 2974 -48541075.11215 +2976 2974 -11027777.77597 +2977 2974 -53756564.45888 +2978 2974 24692759.77823 +3060 2974 15625000.00513 +3061 2974 -20508055.7522 +3062 2974 -8428858.489084 +3063 2974 -4.589557647705e-06 +3064 2974 -20365565.44178 +3065 2974 -6857560.807395 +3066 2974 -15625000.00514 +3067 2974 -32217474.15883 +3068 2974 15286419.29648 +3081 2974 3125000.001029 +3082 2974 -18027909.8965 +3083 2974 -17543480.85857 +3084 2974 2.026557922363e-06 +3085 2974 49867291.76226 +3086 2974 -13715121.60804 +3087 2974 -3125000.001031 +3088 2974 -42123938.53837 +3089 2974 31258602.46661 +2975 2975 413773940.3619 +2976 2975 4242633.849883 +2977 2975 23848315.33392 +2978 2975 26351220.95709 +3060 2975 8536049.989829 +3061 2975 -8428858.489084 +3062 2975 -11111959.41625 +3063 2975 59688904.7995 +3064 2975 -6857560.807395 +3065 2975 -63334663.40088 +3066 2975 21394122.91072 +3067 2975 15286419.29648 +3068 2975 -42337075.16724 +3081 2975 2050095.846979 +3082 2975 -17543480.85871 +3083 2975 15007.26739907 +3084 2975 12486407.68916 +3085 2975 -13715121.60804 +3086 2975 -41325312.23988 +3087 2975 4621710.431164 +3088 2975 31258602.46674 +3089 2975 -64241069.11092 +2976 2976 451998787.7349 +2977 2976 1.800060272217e-05 +2978 2976 -4266443.760058 +2979 2976 51007167.67192 +2980 2976 11027777.77596 +2981 2976 -4858928.64862 +3063 2976 -25195798.91083 +3064 2976 15625000.00513 +3065 2976 8536049.989829 +3066 2976 -89115968.74764 +3067 2976 -2.875924110413e-06 +3068 2976 60031786.74372 +3069 2976 -36905217.31746 +3070 2976 -15625000.00514 +3071 2976 21394122.91072 +3084 2976 11659548.6024 +3085 2976 -3125000.001025 +3086 2976 -1478619.431957 +3087 2976 68618264.38753 +3088 2976 3.814697265625e-06 +3089 2976 -11914911.75127 +3090 2976 -12436480.03947 +3091 2976 3125000.001022 +3092 2976 -4050234.016128 +2977 2977 385828448.56 +2978 2977 -48541075.11215 +2979 2977 -11027777.77597 +2980 2977 -53756564.45888 +2981 2977 24692759.77823 +3063 2977 15625000.00513 +3064 2977 -20508055.7522 +3065 2977 -8428858.489084 +3066 2977 -4.589557647705e-06 +3067 2977 -20365565.44178 +3068 2977 -6857560.807395 +3069 2977 -15625000.00514 +3070 2977 -32217474.15883 +3071 2977 15286419.29648 +3084 2977 3125000.001029 +3085 2977 -18027909.8965 +3086 2977 -17543480.85857 +3087 2977 2.026557922363e-06 +3088 2977 49867291.76226 +3089 2977 -13715121.60804 +3090 2977 -3125000.001031 +3091 2977 -42123938.53837 +3092 2977 31258602.46661 +2978 2978 413773940.3619 +2979 2978 4242633.849883 +2980 2978 23848315.33392 +2981 2978 26351220.95709 +3063 2978 8536049.989829 +3064 2978 -8428858.489084 +3065 2978 -11111959.41625 +3066 2978 59688904.7995 +3067 2978 -6857560.807395 +3068 2978 -63334663.40088 +3069 2978 21394122.91072 +3070 2978 15286419.29648 +3071 2978 -42337075.16724 +3084 2978 2050095.846979 +3085 2978 -17543480.85871 +3086 2978 15007.26739907 +3087 2978 12486407.68916 +3088 2978 -13715121.60804 +3089 2978 -41325312.23988 +3090 2978 4621710.431164 +3091 2978 31258602.46674 +3092 2978 -64241069.11092 +2979 2979 451998787.7349 +2980 2979 1.800060272217e-05 +2981 2979 -4266443.760058 +2982 2979 51007167.67192 +2983 2979 11027777.77596 +2984 2979 -4858928.64862 +3066 2979 -25195798.91083 +3067 2979 15625000.00513 +3068 2979 8536049.989829 +3069 2979 -89115968.74764 +3070 2979 -2.875924110413e-06 +3071 2979 60031786.74372 +3072 2979 -36905217.31746 +3073 2979 -15625000.00514 +3074 2979 21394122.91072 +3087 2979 11659548.6024 +3088 2979 -3125000.001025 +3089 2979 -1478619.431957 +3090 2979 68618264.38753 +3091 2979 3.814697265625e-06 +3092 2979 -11914911.75127 +3093 2979 -12436480.03947 +3094 2979 3125000.001022 +3095 2979 -4050234.016128 +2980 2980 385828448.56 +2981 2980 -48541075.11215 +2982 2980 -11027777.77597 +2983 2980 -53756564.45888 +2984 2980 24692759.77823 +3066 2980 15625000.00513 +3067 2980 -20508055.7522 +3068 2980 -8428858.489084 +3069 2980 -4.589557647705e-06 +3070 2980 -20365565.44178 +3071 2980 -6857560.807395 +3072 2980 -15625000.00514 +3073 2980 -32217474.15883 +3074 2980 15286419.29648 +3087 2980 3125000.001029 +3088 2980 -18027909.8965 +3089 2980 -17543480.85857 +3090 2980 2.026557922363e-06 +3091 2980 49867291.76226 +3092 2980 -13715121.60804 +3093 2980 -3125000.001031 +3094 2980 -42123938.53837 +3095 2980 31258602.46661 +2981 2981 413773940.3619 +2982 2981 4242633.849883 +2983 2981 23848315.33392 +2984 2981 26351220.95709 +3066 2981 8536049.989829 +3067 2981 -8428858.489084 +3068 2981 -11111959.41625 +3069 2981 59688904.7995 +3070 2981 -6857560.807395 +3071 2981 -63334663.40088 +3072 2981 21394122.91072 +3073 2981 15286419.29648 +3074 2981 -42337075.16724 +3087 2981 2050095.846979 +3088 2981 -17543480.85871 +3089 2981 15007.26739907 +3090 2981 12486407.68916 +3091 2981 -13715121.60804 +3092 2981 -41325312.23988 +3093 2981 4621710.431164 +3094 2981 31258602.46674 +3095 2981 -64241069.11092 +2982 2982 451998787.7349 +2983 2982 1.800060272217e-05 +2984 2982 -4266443.760058 +2985 2982 51007167.67192 +2986 2982 11027777.77596 +2987 2982 -4858928.64862 +3069 2982 -25195798.91083 +3070 2982 15625000.00513 +3071 2982 8536049.989829 +3072 2982 -89115968.74764 +3073 2982 -2.875924110413e-06 +3074 2982 60031786.74372 +3075 2982 -36905217.31746 +3076 2982 -15625000.00514 +3077 2982 21394122.91072 +3090 2982 11659548.6024 +3091 2982 -3125000.001025 +3092 2982 -1478619.431957 +3093 2982 68618264.38753 +3094 2982 3.814697265625e-06 +3095 2982 -11914911.75127 +3096 2982 -12436480.03947 +3097 2982 3125000.001022 +3098 2982 -4050234.016128 +2983 2983 385828448.56 +2984 2983 -48541075.11215 +2985 2983 -11027777.77597 +2986 2983 -53756564.45888 +2987 2983 24692759.77823 +3069 2983 15625000.00513 +3070 2983 -20508055.7522 +3071 2983 -8428858.489084 +3072 2983 -4.589557647705e-06 +3073 2983 -20365565.44178 +3074 2983 -6857560.807395 +3075 2983 -15625000.00514 +3076 2983 -32217474.15883 +3077 2983 15286419.29648 +3090 2983 3125000.001029 +3091 2983 -18027909.8965 +3092 2983 -17543480.85857 +3093 2983 2.026557922363e-06 +3094 2983 49867291.76226 +3095 2983 -13715121.60804 +3096 2983 -3125000.001031 +3097 2983 -42123938.53837 +3098 2983 31258602.46661 +2984 2984 413773940.3619 +2985 2984 4242633.849883 +2986 2984 23848315.33392 +2987 2984 26351220.95709 +3069 2984 8536049.989829 +3070 2984 -8428858.489084 +3071 2984 -11111959.41625 +3072 2984 59688904.7995 +3073 2984 -6857560.807395 +3074 2984 -63334663.40088 +3075 2984 21394122.91072 +3076 2984 15286419.29648 +3077 2984 -42337075.16724 +3090 2984 2050095.846979 +3091 2984 -17543480.85871 +3092 2984 15007.26739907 +3093 2984 12486407.68916 +3094 2984 -13715121.60804 +3095 2984 -41325312.23988 +3096 2984 4621710.431164 +3097 2984 31258602.46674 +3098 2984 -64241069.11092 +2985 2985 438788681.6926 +2986 2985 1481949.882174 +2987 2985 13588100.97986 +2988 2985 20474398.84195 +2989 2985 -15194461.1021 +2990 2985 -402802.0502076 +3072 2985 -25195798.91083 +3073 2985 15625000.00513 +3074 2985 8536049.989829 +3075 2985 -76990580.01118 +3076 2985 5389707.749938 +3077 2985 53359584.60642 +3078 2985 -33227083.91641 +3079 2985 -15379874.43216 +3080 2985 16168618.11479 +3093 2985 11659548.6024 +3094 2985 -3125000.001025 +3095 2985 -1478619.431957 +3096 2985 65173303.32689 +3097 2985 245143.1226898 +3098 2985 -6853012.901018 +3099 2985 -10470930.81531 +3100 2985 -2754976.444567 +3101 2985 2783907.400167 +2986 2986 390214539.491 +2987 2986 -29785000.64378 +2988 2986 -37250016.65403 +2989 2986 -85787755.97384 +2990 2986 5371400.418087 +3072 2986 15625000.00513 +3073 2986 -20508055.7522 +3074 2986 -8428858.489084 +3075 2986 5389707.749936 +3076 2986 -15261669.08416 +3077 2986 -8380483.89686 +3078 2986 -15379874.43216 +3079 2986 -24663063.44469 +3080 2986 12419434.06551 +3093 2986 3125000.001029 +3094 2986 -18027909.8965 +3095 2986 -17543480.85857 +3096 2986 245143.1226879 +3097 2986 50301515.94588 +3098 2986 -8353117.277099 +3099 2986 -9004976.44662 +3100 2986 -40892359.49273 +3101 2986 30286506.45611 +2987 2987 397526973.6383 +2988 2987 1945288.227182 +2989 2987 4949178.195934 +2990 2987 26284976.12498 +3072 2987 8536049.989829 +3073 2987 -8428858.489084 +3074 2987 -11111959.41625 +3075 2987 55073994.33073 +3076 2987 -8380483.895913 +3077 2987 -58283026.06258 +3078 2987 16168618.11479 +3079 2987 12419434.06551 +3080 2987 -27607301.84214 +3093 2987 2050095.846979 +3094 2987 -17543480.85871 +3095 2987 15007.26739907 +3096 2987 17547750.98386 +3097 2987 -8353117.277099 +3098 2987 -45585142.3045 +3099 2987 9398282.401154 +3100 2987 30286506.4553 +3101 2987 -41565022.24035 +2988 2988 429105935.2957 +2989 2988 28330900.92755 +2990 2988 -6522740.616906 +2991 2988 -102981106.0586 +2992 2988 -62305057.2626 +2993 2988 814337.0222015 +2994 2988 23954189.43775 +2995 2988 -4717210.995471 +2996 2988 -1617533.951288 +3075 2988 -20350067.7116 +3076 2988 13731012.79672 +3077 2988 8635850.257965 +3078 2988 -69970751.18914 +3079 2988 7245060.881565 +3080 2988 59579729.9437 +3096 2988 -5416277.961415 +3097 2988 -9004976.44662 +3098 2988 -7866787.042358 +3099 2988 41507406.34697 +3100 2988 5819458.255594 +3101 2988 -12220682.65679 +3102 2988 -40243202.98454 +3103 2988 -17299336.42423 +3104 2988 20535239.50393 +3105 2988 -14105125.94333 +3106 2988 -491219.0630247 +3107 2988 2603177.771788 +2989 2989 477376768.0381 +2990 2989 -8908984.282613 +2991 2989 -62305057.2626 +2992 2989 -78288746.05932 +2993 2989 533425.4164013 +2994 2989 -26772766.5474 +2995 2989 -82125360.47375 +2996 2989 1664866.130393 +3075 2989 13731012.79672 +3076 2989 -34523091.92649 +3077 2989 -15378402.12566 +3078 2989 7245060.881565 +3079 2989 -9961364.827704 +3080 2989 -5438763.773985 +3096 2989 -2754976.444568 +3097 2989 -35837706.63884 +3098 2989 -27447868.53434 +3099 2989 5819458.255594 +3100 2989 49505416.69587 +3101 2989 -2326953.595817 +3102 2989 -17299336.42423 +3103 2989 -33678074.85341 +3104 2989 16811021.49711 +3105 2989 -6741219.065077 +3106 2989 -44083197.89248 +3107 2989 33780966.53269 +2990 2990 473986237.116 +2991 2990 814337.0222015 +2992 2990 533425.4164014 +2993 2990 -14081495.98514 +2994 2990 -482985.3403653 +2995 2990 1664866.130393 +2996 2990 47760572.2029 +3075 2990 8635850.257965 +3076 2990 -15378402.12566 +3077 2990 -22141523.21068 +3078 2990 59579729.94404 +3079 2990 -5438763.773037 +3080 2990 -74711590.00242 +3096 2990 -2281057.874872 +3097 2990 -27447868.53529 +3098 2990 -28085947.96329 +3099 2990 11763414.56149 +3100 2990 -2326953.595817 +3101 2990 -81177544.1979 +3102 2990 20535239.50393 +3103 2990 16811021.49711 +3104 2990 -36604413.73886 +3105 2990 8666615.274795 +3106 2990 33780966.53269 +3107 2990 -46820366.06832 +2991 2991 261715726.6238 +2992 2991 68058573.62535 +2993 2991 -459951.4843445 +2994 2991 -62033253.06281 +2995 2991 -3861609.393196 +2996 2991 -572583.5507624 +3078 2991 -7696548.733537 +3079 2991 43873.39197519 +3080 2991 -1538643.39493 +3099 2991 -39694591.87325 +3100 2991 -17299336.42423 +3101 2991 -20089760.50942 +3102 2991 20481159.87447 +3103 2991 18706126.61418 +3104 2991 8000767.237826 +3105 2991 -43395797.04293 +3106 2991 -1450663.581926 +3107 2991 -35122363.33348 +2992 2992 234492875.6532 +2993 2992 -468835.5341598 +2994 2992 18193946.15874 +2995 2992 47675428.58254 +2996 2992 -533425.4163997 +3078 2992 -6206126.610078 +3079 2992 -38097043.067 +3080 2992 -33203547.23309 +3099 2992 -17299336.42423 +3100 2992 -33129463.74212 +3101 2992 -16522311.84717 +3102 2992 18706126.61418 +3103 2992 12795716.69541 +3104 2992 6536880.5708 +3105 2992 4799336.420126 +3106 2992 -11874987.66155 +3107 2992 3188978.509455 +2993 2993 290948033.7889 +2994 2993 -44805.77306801 +2995 2993 -533425.4163998 +2996 2993 66847024.35831 +3078 2993 -9663643.396415 +3079 2993 -33203547.23309 +3080 2993 -46150878.57506 +3099 2993 -20089760.50942 +3100 2993 -16522311.84717 +3101 2993 -35141450.77543 +3102 2993 -8249232.759505 +3103 2993 -6796452.760343 +3104 2993 -59405262.59501 +3105 2993 -35122363.33466 +3106 2993 -3477688.1594 +3107 2993 -46784482.12185 +2994 2994 211997616.0977 +2995 2994 -39393900.1084 +2996 2994 -3413716.048555 +3078 2994 -22947065.82609 +3079 2994 13950663.58603 +3080 2994 14524128.39085 +3099 2994 -12459292.61054 +3100 2994 -6741219.065078 +3101 2994 -8390398.615294 +3102 2994 -43395797.04293 +3103 2994 4799336.420127 +3104 2994 34962619.29382 +3105 2994 16190599.92148 +3106 2994 -12008780.94108 +3107 2994 -6087251.846918 +2995 2995 226901221.6519 +2996 2995 -1664866.130388 +3078 2995 13950663.58603 +3079 2995 -26849141.47444 +3080 2995 -16522311.84717 +3099 2995 -491219.0630252 +3100 2995 -42437364.5597 +3101 2995 -32885700.12302 +3102 2995 -1450663.581925 +3103 2995 -11874987.66155 +3104 2995 3188978.509455 +3105 2995 -12008780.94108 +3106 2995 18549938.1376 +3107 2995 6219033.460737 +2996 2996 247132446.5815 +3078 2996 14524128.39085 +3079 2996 -16522311.84717 +3080 2996 -28861128.50774 +3099 2996 -2669843.056674 +3100 2996 -32885700.12303 +3101 2996 -42431477.18089 +3102 2996 34962619.2928 +3103 2996 -3477688.1594 +3104 2996 -46784482.12185 +3105 2996 5696741.206702 +3106 2996 -7114299.870405 +3107 2996 -48887060.34441 +2997 2997 638651984.0764 +2998 2997 62499999.98975 +2999 2997 26315015.78297 +3000 2997 -359433069.0472 +3001 2997 -62526347.59063 +3002 2997 -26303693.13048 +3003 2997 4145599.03273 +3004 2997 50026347.59267 +3005 2997 -21269642.01197 +3108 2997 88021012.11513 +3109 2997 15625000.00514 +3110 2997 19639605.71133 +3111 2997 -121308672.7549 +3112 2997 -15631586.90535 +3113 2997 -67766682.33182 +3114 2997 -21749648.26534 +3115 2997 12506586.90433 +3116 2997 -17353145.19621 +2998 2998 544867478.3976 +2999 2998 -68597520.2745 +3000 2998 -62539521.39107 +3001 2998 -65598146.14324 +3002 2998 -38004027.78497 +3003 2998 75039521.38901 +3004 2998 4145599.032734 +3005 2998 23877447.844 +3108 2998 15625000.00514 +3109 2998 64574885.68388 +3110 2998 -6700809.891648 +3111 2998 -15634880.35547 +3112 2998 -47849941.99273 +3113 2998 -21743418.55177 +3114 2998 18759880.3565 +3115 2998 -21749648.26534 +3116 2998 20823318.70445 +2999 2999 581180607.3115 +3000 2999 -26298031.80422 +3001 2999 -30593489.61466 +3002 2999 -36647251.12535 +3003 2999 -31904463.01796 +3004 2999 15918298.56266 +3005 2999 11054930.75394 +3108 2999 -4768139.577623 +3109 2999 -26226783.67725 +3110 2999 -45750138.7209 +3111 2999 -67422475.35311 +3112 2999 -19819673.42971 +3113 2999 -93029560.64943 +3114 2999 -26029717.79432 +3115 2999 13882212.46963 +3116 2999 -57999062.0409 +3000 3000 1094265961.25 +3001 3000 62565868.99196 +3002 3000 30858520.46735 +3003 3000 9522774.467089 +3004 3000 -62526347.59063 +3005 3000 26698619.14673 +3006 3000 -248524227.8966 +3007 3000 5.185604095459e-06 +3008 3000 -4571811.315691 +3009 3000 -97883025.962 +3010 3000 62499999.98974 +3011 3000 -26687657.68648 +3108 3000 -108451246.8934 +3109 3000 -15634880.35547 +3110 3000 54616251.09168 +3111 3000 166227659.6012 +3112 3000 15641467.2557 +3113 3000 7711642.939084 +3114 3000 -41196855.08124 +3115 3000 -15631586.90536 +3116 3000 21974855.62738 +3117 3000 -92328809.14057 +3118 3000 5.915760993958e-06 +3119 3000 -62317692.40268 +3120 3000 -38047023.33633 +3121 3000 15625000.00513 +3122 3000 -21965599.32574 +3001 3001 925477565.1068 +3002 3001 -85034510.41928 +3003 3001 -62539521.39107 +3004 3001 -209278615.3833 +3005 3001 45543422.51828 +3006 3001 4.678964614868e-06 +3007 3001 26477385.19127 +3008 3001 -27430243.21608 +3009 3001 62499999.98974 +3010 3001 -79132053.33673 +3011 3001 14949496.6079 +3108 3001 -15631586.90536 +3109 3001 -34992516.13117 +3110 3001 4591649.47589 +3111 3001 15641467.2557 +3112 3001 124030560.5447 +3113 3001 -21261017.33538 +3114 3001 -15634880.35547 +3115 3001 -95897202.5708 +3116 3001 60337907.00837 +3117 3001 4.619359970093e-06 +3118 3001 -23578405.83475 +3119 3001 -6857560.807395 +3120 3001 15625000.00513 +3121 3001 -33359280.17771 +3122 3001 15972183.1856 +3002 3002 898921811.1224 +3003 3002 27046981.82107 +3004 3002 53228121.77035 +3005 3002 1137131.864082 +3006 3002 -4571811.315691 +3007 3002 -27430243.21608 +3008 3002 34500404.96993 +3009 3002 -27030539.6307 +3010 3002 15223802.16328 +3011 3002 -36714051.95871 +3108 3002 54272044.11297 +3109 3002 2673044.969291 +3110 3002 -58743091.68526 +3111 3002 7718068.787606 +3112 3002 -21255876.71511 +3113 3002 -61506429.36468 +3114 3002 21979483.77819 +3115 3002 61984848.42173 +3116 3002 -115922513.565 +3117 3002 -61974810.45846 +3118 3002 -6857560.807395 +3119 3002 -71902237.78217 +3120 3002 -21965599.32574 +3121 3002 15972183.1856 +3122 3002 -45381891.21762 +3003 3003 638651984.0764 +3004 3003 62499999.98975 +3005 3003 26315015.78297 +3006 3003 -96528642.2817 +3007 3003 -62499999.98975 +3008 3003 24744633.97173 +3009 3003 -359433069.0472 +3010 3003 -62526347.59063 +3011 3003 -26303693.13048 +3012 3003 4145599.03273 +3013 3003 50026347.59267 +3014 3003 -21269642.01197 +3108 3003 2359203.743841 +3109 3003 18759880.3565 +3110 3003 10591538.29392 +3111 3003 -4242975.331225 +3112 3003 -15634880.35547 +3113 3003 -8541442.446936 +3114 3003 88021012.11513 +3115 3003 15625000.00514 +3116 3003 19639605.71133 +3117 3003 -25660413.08922 +3118 3003 -15625000.00513 +3119 3003 -9107526.404853 +3120 3003 -121308672.7549 +3121 3003 -15631586.90535 +3122 3003 -67766682.33182 +3123 3003 -21749648.26534 +3124 3003 12506586.90433 +3125 3003 -17353145.19621 +3004 3004 544867478.3976 +3005 3004 -68597520.2745 +3006 3004 -62499999.98975 +3007 3004 -77777669.65641 +3008 3004 12480746.60817 +3009 3004 -62539521.39107 +3010 3004 -65598146.14324 +3011 3004 -38004027.78497 +3012 3004 75039521.38901 +3013 3004 4145599.032734 +3014 3004 23877447.844 +3108 3004 12506586.90433 +3109 3004 2359203.743842 +3110 3004 -5648902.101029 +3111 3004 -15631586.90535 +3112 3004 -58943322.82077 +3113 3004 -35645020.83586 +3114 3004 15625000.00514 +3115 3004 64574885.68388 +3116 3004 -6700809.891648 +3117 3004 -15625000.00513 +3118 3004 -20972669.93059 +3119 3004 -9114622.378198 +3120 3004 -15634880.35547 +3121 3004 -47849941.99273 +3122 3004 -21743418.55177 +3123 3004 18759880.3565 +3124 3004 -21749648.26534 +3125 3004 20823318.70445 +3005 3005 581180607.3115 +3006 3005 24401752.02751 +3007 3005 12206441.0528 +3008 3005 -33102362.14451 +3009 3005 -26298031.80422 +3010 3005 -30593489.61466 +3011 3005 -36647251.12535 +3012 3005 -31904463.01796 +3013 3005 15918298.56266 +3014 3005 11054930.75394 +3108 3005 7061025.529277 +3109 3005 -8473353.151544 +3110 3005 6291209.983575 +3111 3005 -8539644.961234 +3112 3005 -37291962.41402 +3113 3005 -17378834.23163 +3114 3005 -4768139.577623 +3115 3005 -26226783.67725 +3116 3005 -45750138.7209 +3117 3005 -9107526.404853 +3118 3005 -9114622.378198 +3119 3005 -12350930.55863 +3120 3005 -67422475.35311 +3121 3005 -19819673.42971 +3122 3005 -93029560.64943 +3123 3005 -26029717.79432 +3124 3005 13882212.46963 +3125 3005 -57999062.0409 +3006 3006 1006407425.409 +3007 3006 2.30073928833e-05 +3008 3006 9143622.631317 +3009 3006 111257601.9543 +3010 3006 -1.153349876404e-05 +3011 3006 2285905.658962 +3015 3006 -248524227.8966 +3016 3006 5.185604095459e-06 +3017 3006 -4571811.315691 +3018 3006 -97883025.962 +3019 3006 62499999.98974 +3020 3006 -26687657.68648 +3111 3006 -89115968.74764 +3112 3006 -2.875924110413e-06 +3113 3006 60031786.74372 +3114 3006 -36905217.31746 +3115 3006 -15625000.00514 +3116 3006 21394122.91072 +3117 3006 137281674.8977 +3118 3006 7.092952728271e-06 +3119 3006 2285905.658981 +3120 3006 -24872960.07894 +3121 3006 -1.01625919342e-05 +3122 3006 571476.4150351 +3126 3006 -92328809.14057 +3127 3006 5.915760993958e-06 +3128 3006 -62317692.40268 +3129 3006 -38047023.33633 +3130 3006 15625000.00513 +3131 3006 -21965599.32574 +3007 3007 856399644.4805 +3008 3007 -109720972.8103 +3009 3007 -1.239776611328e-05 +3010 3007 -126242065.9199 +3011 3007 54860486.40512 +3015 3007 4.678964614868e-06 +3016 3007 26477385.19127 +3017 3007 -27430243.21608 +3018 3007 62499999.98974 +3019 3007 -79132053.33673 +3020 3007 14949496.6079 +3111 3007 -4.589557647705e-06 +3112 3007 -20365565.44178 +3113 3007 -6857560.807395 +3114 3007 -15625000.00514 +3115 3007 -32217474.15883 +3116 3007 15286419.29648 +3117 3007 6.973743438721e-06 +3118 3007 99779729.64718 +3119 3007 -27430243.21607 +3120 3007 -8.568167686462e-06 +3121 3007 -84247877.07676 +3122 3007 62654357.71105 +3126 3007 4.619359970093e-06 +3127 3007 -23578405.83475 +3128 3007 -6857560.807395 +3129 3007 15625000.00513 +3130 3007 -33359280.17771 +3131 3007 15972183.1856 +3008 3008 889294330.4544 +3009 3008 2285905.658962 +3010 3008 54860486.40512 +3011 3008 48069959.95526 +3015 3008 -4571811.315691 +3016 3008 -27430243.21608 +3017 3008 34500404.96993 +3018 3008 -27030539.6307 +3019 3008 15223802.16328 +3020 3008 -36714051.95871 +3111 3008 59688904.7995 +3112 3008 -6857560.807395 +3113 3008 -63334663.40088 +3114 3008 21394122.91072 +3115 3008 15286419.29648 +3116 3008 -42337075.16724 +3117 3008 2285905.658981 +3118 3008 -27430243.21607 +3119 3008 -82530234.81935 +3120 3008 571476.4150354 +3121 3008 62380052.15567 +3122 3008 -128482138.2218 +3126 3008 -61974810.45846 +3127 3008 -6857560.807395 +3128 3008 -71902237.78217 +3129 3008 -21965599.32574 +3130 3008 15972183.1856 +3131 3008 -45381891.21762 +3009 3009 1094265961.25 +3010 3009 62565868.99196 +3011 3009 30858520.46735 +3012 3009 9522774.467089 +3013 3009 -62526347.59063 +3014 3009 26698619.14673 +3015 3009 -96528642.2817 +3016 3009 -62499999.98975 +3017 3009 24744633.97173 +3018 3009 -248524227.8966 +3019 3009 5.185604095459e-06 +3020 3009 -4571811.315691 +3021 3009 -97883025.962 +3022 3009 62499999.98974 +3023 3009 -26687657.68648 +3111 3009 -25195798.91083 +3112 3009 15625000.00513 +3113 3009 8536049.989829 +3114 3009 -108451246.8934 +3115 3009 -15634880.35547 +3116 3009 54616251.09168 +3117 3009 23319097.20481 +3118 3009 3.09944152832e-06 +3119 3009 571476.4150216 +3120 3009 166227659.6012 +3121 3009 15641467.2557 +3122 3009 7711642.939084 +3123 3009 -41196855.08124 +3124 3009 -15631586.90536 +3125 3009 21974855.62738 +3126 3009 -25660413.08922 +3127 3009 -15625000.00513 +3128 3009 -9107526.404853 +3129 3009 -92328809.14057 +3130 3009 5.915760993958e-06 +3131 3009 -62317692.40268 +3132 3009 -38047023.33633 +3133 3009 15625000.00513 +3134 3009 -21965599.32574 +3010 3010 925477565.1068 +3011 3010 -85034510.41928 +3012 3010 -62539521.39107 +3013 3010 -209278615.3833 +3014 3010 45543422.51828 +3015 3010 -62499999.98975 +3016 3010 -77777669.65641 +3017 3010 12480746.60817 +3018 3010 4.678964614868e-06 +3019 3010 26477385.19127 +3020 3010 -27430243.21608 +3021 3010 62499999.98974 +3022 3010 -79132053.33673 +3023 3010 14949496.6079 +3111 3010 15625000.00513 +3112 3010 -20508055.7522 +3113 3010 -8428858.489084 +3114 3010 -15631586.90536 +3115 3010 -34992516.13117 +3116 3010 4591649.47589 +3117 3010 4.559755325317e-06 +3118 3010 -36055819.793 +3119 3010 -35224114.49497 +3120 3010 15641467.2557 +3121 3010 124030560.5447 +3122 3010 -21261017.33538 +3123 3010 -15634880.35547 +3124 3010 -95897202.5708 +3125 3010 60337907.00837 +3126 3010 -15625000.00513 +3127 3010 -20972669.93059 +3128 3010 -9114622.378198 +3129 3010 4.619359970093e-06 +3130 3010 -23578405.83475 +3131 3010 -6857560.807395 +3132 3010 15625000.00513 +3133 3010 -33359280.17771 +3134 3010 15972183.1856 +3011 3011 898921811.1224 +3012 3011 27046981.82107 +3013 3011 53228121.77035 +3014 3011 1137131.864082 +3015 3011 24401752.02751 +3016 3011 12206441.0528 +3017 3011 -33102362.14451 +3018 3011 -4571811.315691 +3019 3011 -27430243.21608 +3020 3011 34500404.96993 +3021 3011 -27030539.6307 +3022 3011 15223802.16328 +3023 3011 -36714051.95871 +3111 3011 8536049.989829 +3112 3011 -8428858.489084 +3113 3011 -11111959.41625 +3114 3011 54272044.11297 +3115 3011 2673044.969291 +3116 3011 -58743091.68526 +3117 3011 571476.4150219 +3118 3011 -34949808.93959 +3119 3011 30014.53480115 +3120 3011 7718068.787606 +3121 3011 -21255876.71511 +3122 3011 -61506429.36468 +3123 3011 21979483.77819 +3124 3011 61984848.42173 +3125 3011 -115922513.565 +3126 3011 -9107526.404853 +3127 3011 -9114622.378198 +3128 3011 -12350930.55863 +3129 3011 -61974810.45846 +3130 3011 -6857560.807395 +3131 3011 -71902237.78217 +3132 3011 -21965599.32574 +3133 3011 15972183.1856 +3134 3011 -45381891.21762 +3012 3012 638651984.0764 +3013 3012 62499999.98975 +3014 3012 26315015.78297 +3018 3012 -96528642.2817 +3019 3012 -62499999.98975 +3020 3012 24744633.97173 +3021 3012 -359433069.0472 +3022 3012 -62526347.59063 +3023 3012 -26303693.13048 +3024 3012 4145599.03273 +3025 3012 50026347.59267 +3026 3012 -21269642.01197 +3114 3012 2359203.743841 +3115 3012 18759880.3565 +3116 3012 10591538.29392 +3120 3012 -4242975.331225 +3121 3012 -15634880.35547 +3122 3012 -8541442.446936 +3123 3012 88021012.11513 +3124 3012 15625000.00514 +3125 3012 19639605.71133 +3129 3012 -25660413.08922 +3130 3012 -15625000.00513 +3131 3012 -9107526.404853 +3132 3012 -121308672.7549 +3133 3012 -15631586.90535 +3134 3012 -67766682.33182 +3135 3012 -21749648.26534 +3136 3012 12506586.90433 +3137 3012 -17353145.19621 +3013 3013 544867478.3976 +3014 3013 -68597520.2745 +3018 3013 -62499999.98975 +3019 3013 -77777669.65641 +3020 3013 12480746.60817 +3021 3013 -62539521.39107 +3022 3013 -65598146.14324 +3023 3013 -38004027.78497 +3024 3013 75039521.38901 +3025 3013 4145599.032734 +3026 3013 23877447.844 +3114 3013 12506586.90433 +3115 3013 2359203.743842 +3116 3013 -5648902.101029 +3120 3013 -15631586.90535 +3121 3013 -58943322.82077 +3122 3013 -35645020.83586 +3123 3013 15625000.00514 +3124 3013 64574885.68388 +3125 3013 -6700809.891648 +3129 3013 -15625000.00513 +3130 3013 -20972669.93059 +3131 3013 -9114622.378198 +3132 3013 -15634880.35547 +3133 3013 -47849941.99273 +3134 3013 -21743418.55177 +3135 3013 18759880.3565 +3136 3013 -21749648.26534 +3137 3013 20823318.70445 +3014 3014 581180607.3115 +3018 3014 24401752.02751 +3019 3014 12206441.0528 +3020 3014 -33102362.14451 +3021 3014 -26298031.80422 +3022 3014 -30593489.61466 +3023 3014 -36647251.12535 +3024 3014 -31904463.01796 +3025 3014 15918298.56266 +3026 3014 11054930.75394 +3114 3014 7061025.529277 +3115 3014 -8473353.151544 +3116 3014 6291209.983575 +3120 3014 -8539644.961234 +3121 3014 -37291962.41402 +3122 3014 -17378834.23163 +3123 3014 -4768139.577623 +3124 3014 -26226783.67725 +3125 3014 -45750138.7209 +3129 3014 -9107526.404853 +3130 3014 -9114622.378198 +3131 3014 -12350930.55863 +3132 3014 -67422475.35311 +3133 3014 -19819673.42971 +3134 3014 -93029560.64943 +3135 3014 -26029717.79432 +3136 3014 13882212.46963 +3137 3014 -57999062.0409 +3015 3015 1006407425.409 +3016 3015 2.30073928833e-05 +3017 3015 9143622.631317 +3018 3015 111257601.9543 +3019 3015 -1.153349876404e-05 +3020 3015 2285905.658962 +3027 3015 -248524227.8966 +3028 3015 5.185604095459e-06 +3029 3015 -4571811.315691 +3030 3015 -97883025.962 +3031 3015 62499999.98974 +3032 3015 -26687657.68648 +3117 3015 -89115968.74764 +3118 3015 -2.875924110413e-06 +3119 3015 60031786.74372 +3120 3015 -36905217.31746 +3121 3015 -15625000.00514 +3122 3015 21394122.91072 +3126 3015 137281674.8977 +3127 3015 7.092952728271e-06 +3128 3015 2285905.658981 +3129 3015 -24872960.07894 +3130 3015 -1.01625919342e-05 +3131 3015 571476.4150351 +3138 3015 -92328809.14057 +3139 3015 5.915760993958e-06 +3140 3015 -62317692.40268 +3141 3015 -38047023.33633 +3142 3015 15625000.00513 +3143 3015 -21965599.32574 +3016 3016 856399644.4805 +3017 3016 -109720972.8103 +3018 3016 -1.239776611328e-05 +3019 3016 -126242065.9199 +3020 3016 54860486.40512 +3027 3016 4.678964614868e-06 +3028 3016 26477385.19127 +3029 3016 -27430243.21608 +3030 3016 62499999.98974 +3031 3016 -79132053.33673 +3032 3016 14949496.6079 +3117 3016 -4.589557647705e-06 +3118 3016 -20365565.44178 +3119 3016 -6857560.807395 +3120 3016 -15625000.00514 +3121 3016 -32217474.15883 +3122 3016 15286419.29648 +3126 3016 6.973743438721e-06 +3127 3016 99779729.64718 +3128 3016 -27430243.21607 +3129 3016 -8.568167686462e-06 +3130 3016 -84247877.07676 +3131 3016 62654357.71105 +3138 3016 4.619359970093e-06 +3139 3016 -23578405.83475 +3140 3016 -6857560.807395 +3141 3016 15625000.00513 +3142 3016 -33359280.17771 +3143 3016 15972183.1856 +3017 3017 889294330.4544 +3018 3017 2285905.658962 +3019 3017 54860486.40512 +3020 3017 48069959.95526 +3027 3017 -4571811.315691 +3028 3017 -27430243.21608 +3029 3017 34500404.96993 +3030 3017 -27030539.6307 +3031 3017 15223802.16328 +3032 3017 -36714051.95871 +3117 3017 59688904.7995 +3118 3017 -6857560.807395 +3119 3017 -63334663.40088 +3120 3017 21394122.91072 +3121 3017 15286419.29648 +3122 3017 -42337075.16724 +3126 3017 2285905.658981 +3127 3017 -27430243.21607 +3128 3017 -82530234.81935 +3129 3017 571476.4150354 +3130 3017 62380052.15567 +3131 3017 -128482138.2218 +3138 3017 -61974810.45846 +3139 3017 -6857560.807395 +3140 3017 -71902237.78217 +3141 3017 -21965599.32574 +3142 3017 15972183.1856 +3143 3017 -45381891.21762 +3018 3018 1006407425.409 +3019 3018 2.30073928833e-05 +3020 3018 9143622.631317 +3021 3018 111257601.9543 +3022 3018 -1.153349876404e-05 +3023 3018 2285905.658962 +3027 3018 -96528642.2817 +3028 3018 -62499999.98975 +3029 3018 24744633.97173 +3030 3018 -248524227.8966 +3031 3018 5.185604095459e-06 +3032 3018 -4571811.315691 +3033 3018 -97883025.962 +3034 3018 62499999.98974 +3035 3018 -26687657.68648 +3117 3018 -25195798.91083 +3118 3018 15625000.00513 +3119 3018 8536049.989829 +3120 3018 -89115968.74764 +3121 3018 -2.875924110413e-06 +3122 3018 60031786.74372 +3123 3018 -36905217.31746 +3124 3018 -15625000.00514 +3125 3018 21394122.91072 +3126 3018 23319097.20481 +3127 3018 3.09944152832e-06 +3128 3018 571476.4150216 +3129 3018 137281674.8977 +3130 3018 7.092952728271e-06 +3131 3018 2285905.658981 +3132 3018 -24872960.07894 +3133 3018 -1.01625919342e-05 +3134 3018 571476.4150351 +3138 3018 -25660413.08922 +3139 3018 -15625000.00513 +3140 3018 -9107526.404853 +3141 3018 -92328809.14057 +3142 3018 5.915760993958e-06 +3143 3018 -62317692.40268 +3144 3018 -38047023.33633 +3145 3018 15625000.00513 +3146 3018 -21965599.32574 +3019 3019 856399644.4805 +3020 3019 -109720972.8103 +3021 3019 -1.239776611328e-05 +3022 3019 -126242065.9199 +3023 3019 54860486.40512 +3027 3019 -62499999.98975 +3028 3019 -77777669.65641 +3029 3019 12480746.60817 +3030 3019 4.678964614868e-06 +3031 3019 26477385.19127 +3032 3019 -27430243.21608 +3033 3019 62499999.98974 +3034 3019 -79132053.33673 +3035 3019 14949496.6079 +3117 3019 15625000.00513 +3118 3019 -20508055.7522 +3119 3019 -8428858.489084 +3120 3019 -4.589557647705e-06 +3121 3019 -20365565.44178 +3122 3019 -6857560.807395 +3123 3019 -15625000.00514 +3124 3019 -32217474.15883 +3125 3019 15286419.29648 +3126 3019 4.559755325317e-06 +3127 3019 -36055819.793 +3128 3019 -35224114.49497 +3129 3019 6.973743438721e-06 +3130 3019 99779729.64718 +3131 3019 -27430243.21607 +3132 3019 -8.568167686462e-06 +3133 3019 -84247877.07676 +3134 3019 62654357.71105 +3138 3019 -15625000.00513 +3139 3019 -20972669.93059 +3140 3019 -9114622.378198 +3141 3019 4.619359970093e-06 +3142 3019 -23578405.83475 +3143 3019 -6857560.807395 +3144 3019 15625000.00513 +3145 3019 -33359280.17771 +3146 3019 15972183.1856 +3020 3020 889294330.4544 +3021 3020 2285905.658962 +3022 3020 54860486.40512 +3023 3020 48069959.95526 +3027 3020 24401752.02751 +3028 3020 12206441.0528 +3029 3020 -33102362.14451 +3030 3020 -4571811.315691 +3031 3020 -27430243.21608 +3032 3020 34500404.96993 +3033 3020 -27030539.6307 +3034 3020 15223802.16328 +3035 3020 -36714051.95871 +3117 3020 8536049.989829 +3118 3020 -8428858.489084 +3119 3020 -11111959.41625 +3120 3020 59688904.7995 +3121 3020 -6857560.807395 +3122 3020 -63334663.40088 +3123 3020 21394122.91072 +3124 3020 15286419.29648 +3125 3020 -42337075.16724 +3126 3020 571476.4150219 +3127 3020 -34949808.93959 +3128 3020 30014.53480115 +3129 3020 2285905.658981 +3130 3020 -27430243.21607 +3131 3020 -82530234.81935 +3132 3020 571476.4150354 +3133 3020 62380052.15567 +3134 3020 -128482138.2218 +3138 3020 -9107526.404853 +3139 3020 -9114622.378198 +3140 3020 -12350930.55863 +3141 3020 -61974810.45846 +3142 3020 -6857560.807395 +3143 3020 -71902237.78217 +3144 3020 -21965599.32574 +3145 3020 15972183.1856 +3146 3020 -45381891.21762 +3021 3021 1094265961.25 +3022 3021 62565868.99196 +3023 3021 30858520.46735 +3024 3021 9522774.467089 +3025 3021 -62526347.59063 +3026 3021 26698619.14673 +3030 3021 -96528642.2817 +3031 3021 -62499999.98975 +3032 3021 24744633.97173 +3033 3021 -248524227.8966 +3034 3021 5.185604095459e-06 +3035 3021 -4571811.315691 +3036 3021 -97883025.962 +3037 3021 62499999.98974 +3038 3021 -26687657.68648 +3120 3021 -25195798.91083 +3121 3021 15625000.00513 +3122 3021 8536049.989829 +3123 3021 -108451246.8934 +3124 3021 -15634880.35547 +3125 3021 54616251.09168 +3129 3021 23319097.20481 +3130 3021 3.09944152832e-06 +3131 3021 571476.4150216 +3132 3021 166227659.6012 +3133 3021 15641467.2557 +3134 3021 7711642.939084 +3135 3021 -41196855.08124 +3136 3021 -15631586.90536 +3137 3021 21974855.62738 +3141 3021 -25660413.08922 +3142 3021 -15625000.00513 +3143 3021 -9107526.404853 +3144 3021 -92328809.14057 +3145 3021 5.915760993958e-06 +3146 3021 -62317692.40268 +3147 3021 -38047023.33633 +3148 3021 15625000.00513 +3149 3021 -21965599.32574 +3022 3022 925477565.1068 +3023 3022 -85034510.41928 +3024 3022 -62539521.39107 +3025 3022 -209278615.3833 +3026 3022 45543422.51828 +3030 3022 -62499999.98975 +3031 3022 -77777669.65641 +3032 3022 12480746.60817 +3033 3022 4.678964614868e-06 +3034 3022 26477385.19127 +3035 3022 -27430243.21608 +3036 3022 62499999.98974 +3037 3022 -79132053.33673 +3038 3022 14949496.6079 +3120 3022 15625000.00513 +3121 3022 -20508055.7522 +3122 3022 -8428858.489084 +3123 3022 -15631586.90536 +3124 3022 -34992516.13117 +3125 3022 4591649.47589 +3129 3022 4.559755325317e-06 +3130 3022 -36055819.793 +3131 3022 -35224114.49497 +3132 3022 15641467.2557 +3133 3022 124030560.5447 +3134 3022 -21261017.33538 +3135 3022 -15634880.35547 +3136 3022 -95897202.5708 +3137 3022 60337907.00837 +3141 3022 -15625000.00513 +3142 3022 -20972669.93059 +3143 3022 -9114622.378198 +3144 3022 4.619359970093e-06 +3145 3022 -23578405.83475 +3146 3022 -6857560.807395 +3147 3022 15625000.00513 +3148 3022 -33359280.17771 +3149 3022 15972183.1856 +3023 3023 898921811.1224 +3024 3023 27046981.82107 +3025 3023 53228121.77035 +3026 3023 1137131.864082 +3030 3023 24401752.02751 +3031 3023 12206441.0528 +3032 3023 -33102362.14451 +3033 3023 -4571811.315691 +3034 3023 -27430243.21608 +3035 3023 34500404.96993 +3036 3023 -27030539.6307 +3037 3023 15223802.16328 +3038 3023 -36714051.95871 +3120 3023 8536049.989829 +3121 3023 -8428858.489084 +3122 3023 -11111959.41625 +3123 3023 54272044.11297 +3124 3023 2673044.969291 +3125 3023 -58743091.68526 +3129 3023 571476.4150219 +3130 3023 -34949808.93959 +3131 3023 30014.53480115 +3132 3023 7718068.787606 +3133 3023 -21255876.71511 +3134 3023 -61506429.36468 +3135 3023 21979483.77819 +3136 3023 61984848.42173 +3137 3023 -115922513.565 +3141 3023 -9107526.404853 +3142 3023 -9114622.378198 +3143 3023 -12350930.55863 +3144 3023 -61974810.45846 +3145 3023 -6857560.807395 +3146 3023 -71902237.78217 +3147 3023 -21965599.32574 +3148 3023 15972183.1856 +3149 3023 -45381891.21762 +3024 3024 638651984.0764 +3025 3024 62499999.98975 +3026 3024 26315015.78297 +3033 3024 -96528642.2817 +3034 3024 -62499999.98975 +3035 3024 24744633.97173 +3036 3024 -359433069.0472 +3037 3024 -62526347.59063 +3038 3024 -26303693.13048 +3039 3024 4145599.03273 +3040 3024 50026347.59267 +3041 3024 -21269642.01197 +3123 3024 2359203.743841 +3124 3024 18759880.3565 +3125 3024 10591538.29392 +3132 3024 -4242975.331225 +3133 3024 -15634880.35547 +3134 3024 -8541442.446936 +3135 3024 88021012.11513 +3136 3024 15625000.00514 +3137 3024 19639605.71133 +3144 3024 -25660413.08922 +3145 3024 -15625000.00513 +3146 3024 -9107526.404853 +3147 3024 -121308672.7549 +3148 3024 -15631586.90535 +3149 3024 -67766682.33182 +3150 3024 -21749648.26534 +3151 3024 12506586.90433 +3152 3024 -17353145.19621 +3025 3025 544867478.3976 +3026 3025 -68597520.2745 +3033 3025 -62499999.98975 +3034 3025 -77777669.65641 +3035 3025 12480746.60817 +3036 3025 -62539521.39107 +3037 3025 -65598146.14324 +3038 3025 -38004027.78497 +3039 3025 75039521.38901 +3040 3025 4145599.032734 +3041 3025 23877447.844 +3123 3025 12506586.90433 +3124 3025 2359203.743842 +3125 3025 -5648902.101029 +3132 3025 -15631586.90535 +3133 3025 -58943322.82077 +3134 3025 -35645020.83586 +3135 3025 15625000.00514 +3136 3025 64574885.68388 +3137 3025 -6700809.891648 +3144 3025 -15625000.00513 +3145 3025 -20972669.93059 +3146 3025 -9114622.378198 +3147 3025 -15634880.35547 +3148 3025 -47849941.99273 +3149 3025 -21743418.55177 +3150 3025 18759880.3565 +3151 3025 -21749648.26534 +3152 3025 20823318.70445 +3026 3026 581180607.3115 +3033 3026 24401752.02751 +3034 3026 12206441.0528 +3035 3026 -33102362.14451 +3036 3026 -26298031.80422 +3037 3026 -30593489.61466 +3038 3026 -36647251.12535 +3039 3026 -31904463.01796 +3040 3026 15918298.56266 +3041 3026 11054930.75394 +3123 3026 7061025.529277 +3124 3026 -8473353.151544 +3125 3026 6291209.983575 +3132 3026 -8539644.961234 +3133 3026 -37291962.41402 +3134 3026 -17378834.23163 +3135 3026 -4768139.577623 +3136 3026 -26226783.67725 +3137 3026 -45750138.7209 +3144 3026 -9107526.404853 +3145 3026 -9114622.378198 +3146 3026 -12350930.55863 +3147 3026 -67422475.35311 +3148 3026 -19819673.42971 +3149 3026 -93029560.64943 +3150 3026 -26029717.79432 +3151 3026 13882212.46963 +3152 3026 -57999062.0409 +3027 3027 1006407425.409 +3028 3027 2.30073928833e-05 +3029 3027 9143622.631317 +3030 3027 111257601.9543 +3031 3027 -1.153349876404e-05 +3032 3027 2285905.658962 +3042 3027 -248524227.8966 +3043 3027 5.185604095459e-06 +3044 3027 -4571811.315691 +3045 3027 -97883025.962 +3046 3027 62499999.98974 +3047 3027 -26687657.68648 +3126 3027 -89115968.74764 +3127 3027 -2.875924110413e-06 +3128 3027 60031786.74372 +3129 3027 -36905217.31746 +3130 3027 -15625000.00514 +3131 3027 21394122.91072 +3138 3027 137281674.8977 +3139 3027 7.092952728271e-06 +3140 3027 2285905.658981 +3141 3027 -24872960.07894 +3142 3027 -1.01625919342e-05 +3143 3027 571476.4150351 +3153 3027 -92328809.14057 +3154 3027 5.915760993958e-06 +3155 3027 -62317692.40268 +3156 3027 -38047023.33633 +3157 3027 15625000.00513 +3158 3027 -21965599.32574 +3028 3028 856399644.4805 +3029 3028 -109720972.8103 +3030 3028 -1.239776611328e-05 +3031 3028 -126242065.9199 +3032 3028 54860486.40512 +3042 3028 4.678964614868e-06 +3043 3028 26477385.19127 +3044 3028 -27430243.21608 +3045 3028 62499999.98974 +3046 3028 -79132053.33673 +3047 3028 14949496.6079 +3126 3028 -4.589557647705e-06 +3127 3028 -20365565.44178 +3128 3028 -6857560.807395 +3129 3028 -15625000.00514 +3130 3028 -32217474.15883 +3131 3028 15286419.29648 +3138 3028 6.973743438721e-06 +3139 3028 99779729.64718 +3140 3028 -27430243.21607 +3141 3028 -8.568167686462e-06 +3142 3028 -84247877.07676 +3143 3028 62654357.71105 +3153 3028 4.619359970093e-06 +3154 3028 -23578405.83475 +3155 3028 -6857560.807395 +3156 3028 15625000.00513 +3157 3028 -33359280.17771 +3158 3028 15972183.1856 +3029 3029 889294330.4544 +3030 3029 2285905.658962 +3031 3029 54860486.40512 +3032 3029 48069959.95526 +3042 3029 -4571811.315691 +3043 3029 -27430243.21608 +3044 3029 34500404.96993 +3045 3029 -27030539.6307 +3046 3029 15223802.16328 +3047 3029 -36714051.95871 +3126 3029 59688904.7995 +3127 3029 -6857560.807395 +3128 3029 -63334663.40088 +3129 3029 21394122.91072 +3130 3029 15286419.29648 +3131 3029 -42337075.16724 +3138 3029 2285905.658981 +3139 3029 -27430243.21607 +3140 3029 -82530234.81935 +3141 3029 571476.4150354 +3142 3029 62380052.15567 +3143 3029 -128482138.2218 +3153 3029 -61974810.45846 +3154 3029 -6857560.807395 +3155 3029 -71902237.78217 +3156 3029 -21965599.32574 +3157 3029 15972183.1856 +3158 3029 -45381891.21762 +3030 3030 1006407425.409 +3031 3030 2.30073928833e-05 +3032 3030 9143622.631317 +3033 3030 111257601.9543 +3034 3030 -1.153349876404e-05 +3035 3030 2285905.658962 +3042 3030 -96528642.2817 +3043 3030 -62499999.98975 +3044 3030 24744633.97173 +3045 3030 -248524227.8966 +3046 3030 5.185604095459e-06 +3047 3030 -4571811.315691 +3048 3030 -97883025.962 +3049 3030 62499999.98974 +3050 3030 -26687657.68648 +3126 3030 -25195798.91083 +3127 3030 15625000.00513 +3128 3030 8536049.989829 +3129 3030 -89115968.74764 +3130 3030 -2.875924110413e-06 +3131 3030 60031786.74372 +3132 3030 -36905217.31746 +3133 3030 -15625000.00514 +3134 3030 21394122.91072 +3138 3030 23319097.20481 +3139 3030 3.09944152832e-06 +3140 3030 571476.4150216 +3141 3030 137281674.8977 +3142 3030 7.092952728271e-06 +3143 3030 2285905.658981 +3144 3030 -24872960.07894 +3145 3030 -1.01625919342e-05 +3146 3030 571476.4150351 +3153 3030 -25660413.08922 +3154 3030 -15625000.00513 +3155 3030 -9107526.404853 +3156 3030 -92328809.14057 +3157 3030 5.915760993958e-06 +3158 3030 -62317692.40268 +3159 3030 -38047023.33633 +3160 3030 15625000.00513 +3161 3030 -21965599.32574 +3031 3031 856399644.4805 +3032 3031 -109720972.8103 +3033 3031 -1.239776611328e-05 +3034 3031 -126242065.9199 +3035 3031 54860486.40512 +3042 3031 -62499999.98975 +3043 3031 -77777669.65641 +3044 3031 12480746.60817 +3045 3031 4.678964614868e-06 +3046 3031 26477385.19127 +3047 3031 -27430243.21608 +3048 3031 62499999.98974 +3049 3031 -79132053.33673 +3050 3031 14949496.6079 +3126 3031 15625000.00513 +3127 3031 -20508055.7522 +3128 3031 -8428858.489084 +3129 3031 -4.589557647705e-06 +3130 3031 -20365565.44178 +3131 3031 -6857560.807395 +3132 3031 -15625000.00514 +3133 3031 -32217474.15883 +3134 3031 15286419.29648 +3138 3031 4.559755325317e-06 +3139 3031 -36055819.793 +3140 3031 -35224114.49497 +3141 3031 6.973743438721e-06 +3142 3031 99779729.64718 +3143 3031 -27430243.21607 +3144 3031 -8.568167686462e-06 +3145 3031 -84247877.07676 +3146 3031 62654357.71105 +3153 3031 -15625000.00513 +3154 3031 -20972669.93059 +3155 3031 -9114622.378198 +3156 3031 4.619359970093e-06 +3157 3031 -23578405.83475 +3158 3031 -6857560.807395 +3159 3031 15625000.00513 +3160 3031 -33359280.17771 +3161 3031 15972183.1856 +3032 3032 889294330.4544 +3033 3032 2285905.658962 +3034 3032 54860486.40512 +3035 3032 48069959.95526 +3042 3032 24401752.02751 +3043 3032 12206441.0528 +3044 3032 -33102362.14451 +3045 3032 -4571811.315691 +3046 3032 -27430243.21608 +3047 3032 34500404.96993 +3048 3032 -27030539.6307 +3049 3032 15223802.16328 +3050 3032 -36714051.95871 +3126 3032 8536049.989829 +3127 3032 -8428858.489084 +3128 3032 -11111959.41625 +3129 3032 59688904.7995 +3130 3032 -6857560.807395 +3131 3032 -63334663.40088 +3132 3032 21394122.91072 +3133 3032 15286419.29648 +3134 3032 -42337075.16724 +3138 3032 571476.4150219 +3139 3032 -34949808.93959 +3140 3032 30014.53480115 +3141 3032 2285905.658981 +3142 3032 -27430243.21607 +3143 3032 -82530234.81935 +3144 3032 571476.4150354 +3145 3032 62380052.15567 +3146 3032 -128482138.2218 +3153 3032 -9107526.404853 +3154 3032 -9114622.378198 +3155 3032 -12350930.55863 +3156 3032 -61974810.45846 +3157 3032 -6857560.807395 +3158 3032 -71902237.78217 +3159 3032 -21965599.32574 +3160 3032 15972183.1856 +3161 3032 -45381891.21762 +3033 3033 1006407425.409 +3034 3033 2.30073928833e-05 +3035 3033 9143622.631317 +3036 3033 111257601.9543 +3037 3033 -1.153349876404e-05 +3038 3033 2285905.658962 +3045 3033 -96528642.2817 +3046 3033 -62499999.98975 +3047 3033 24744633.97173 +3048 3033 -248524227.8966 +3049 3033 5.185604095459e-06 +3050 3033 -4571811.315691 +3051 3033 -97883025.962 +3052 3033 62499999.98974 +3053 3033 -26687657.68648 +3129 3033 -25195798.91083 +3130 3033 15625000.00513 +3131 3033 8536049.989829 +3132 3033 -89115968.74764 +3133 3033 -2.875924110413e-06 +3134 3033 60031786.74372 +3135 3033 -36905217.31746 +3136 3033 -15625000.00514 +3137 3033 21394122.91072 +3141 3033 23319097.20481 +3142 3033 3.09944152832e-06 +3143 3033 571476.4150216 +3144 3033 137281674.8977 +3145 3033 7.092952728271e-06 +3146 3033 2285905.658981 +3147 3033 -24872960.07894 +3148 3033 -1.01625919342e-05 +3149 3033 571476.4150351 +3156 3033 -25660413.08922 +3157 3033 -15625000.00513 +3158 3033 -9107526.404853 +3159 3033 -92328809.14057 +3160 3033 5.915760993958e-06 +3161 3033 -62317692.40268 +3162 3033 -38047023.33633 +3163 3033 15625000.00513 +3164 3033 -21965599.32574 +3034 3034 856399644.4805 +3035 3034 -109720972.8103 +3036 3034 -1.239776611328e-05 +3037 3034 -126242065.9199 +3038 3034 54860486.40512 +3045 3034 -62499999.98975 +3046 3034 -77777669.65641 +3047 3034 12480746.60817 +3048 3034 4.678964614868e-06 +3049 3034 26477385.19127 +3050 3034 -27430243.21608 +3051 3034 62499999.98974 +3052 3034 -79132053.33673 +3053 3034 14949496.6079 +3129 3034 15625000.00513 +3130 3034 -20508055.7522 +3131 3034 -8428858.489084 +3132 3034 -4.589557647705e-06 +3133 3034 -20365565.44178 +3134 3034 -6857560.807395 +3135 3034 -15625000.00514 +3136 3034 -32217474.15883 +3137 3034 15286419.29648 +3141 3034 4.559755325317e-06 +3142 3034 -36055819.793 +3143 3034 -35224114.49497 +3144 3034 6.973743438721e-06 +3145 3034 99779729.64718 +3146 3034 -27430243.21607 +3147 3034 -8.568167686462e-06 +3148 3034 -84247877.07676 +3149 3034 62654357.71105 +3156 3034 -15625000.00513 +3157 3034 -20972669.93059 +3158 3034 -9114622.378198 +3159 3034 4.619359970093e-06 +3160 3034 -23578405.83475 +3161 3034 -6857560.807395 +3162 3034 15625000.00513 +3163 3034 -33359280.17771 +3164 3034 15972183.1856 +3035 3035 889294330.4544 +3036 3035 2285905.658962 +3037 3035 54860486.40512 +3038 3035 48069959.95526 +3045 3035 24401752.02751 +3046 3035 12206441.0528 +3047 3035 -33102362.14451 +3048 3035 -4571811.315691 +3049 3035 -27430243.21608 +3050 3035 34500404.96993 +3051 3035 -27030539.6307 +3052 3035 15223802.16328 +3053 3035 -36714051.95871 +3129 3035 8536049.989829 +3130 3035 -8428858.489084 +3131 3035 -11111959.41625 +3132 3035 59688904.7995 +3133 3035 -6857560.807395 +3134 3035 -63334663.40088 +3135 3035 21394122.91072 +3136 3035 15286419.29648 +3137 3035 -42337075.16724 +3141 3035 571476.4150219 +3142 3035 -34949808.93959 +3143 3035 30014.53480115 +3144 3035 2285905.658981 +3145 3035 -27430243.21607 +3146 3035 -82530234.81935 +3147 3035 571476.4150354 +3148 3035 62380052.15567 +3149 3035 -128482138.2218 +3156 3035 -9107526.404853 +3157 3035 -9114622.378198 +3158 3035 -12350930.55863 +3159 3035 -61974810.45846 +3160 3035 -6857560.807395 +3161 3035 -71902237.78217 +3162 3035 -21965599.32574 +3163 3035 15972183.1856 +3164 3035 -45381891.21762 +3036 3036 1094265961.25 +3037 3036 62565868.99196 +3038 3036 30858520.46735 +3039 3036 9522774.467089 +3040 3036 -62526347.59063 +3041 3036 26698619.14673 +3048 3036 -96528642.2817 +3049 3036 -62499999.98975 +3050 3036 24744633.97173 +3051 3036 -248524227.8966 +3052 3036 5.185604095459e-06 +3053 3036 -4571811.315691 +3054 3036 -97883025.962 +3055 3036 62499999.98974 +3056 3036 -26687657.68648 +3132 3036 -25195798.91083 +3133 3036 15625000.00513 +3134 3036 8536049.989829 +3135 3036 -108451246.8934 +3136 3036 -15634880.35547 +3137 3036 54616251.09168 +3144 3036 23319097.20481 +3145 3036 3.09944152832e-06 +3146 3036 571476.4150216 +3147 3036 166227659.6012 +3148 3036 15641467.2557 +3149 3036 7711642.939084 +3150 3036 -41196855.08124 +3151 3036 -15631586.90536 +3152 3036 21974855.62738 +3159 3036 -25660413.08922 +3160 3036 -15625000.00513 +3161 3036 -9107526.404853 +3162 3036 -92328809.14057 +3163 3036 5.915760993958e-06 +3164 3036 -62317692.40268 +3165 3036 -38047023.33633 +3166 3036 15625000.00513 +3167 3036 -21965599.32574 +3037 3037 925477565.1068 +3038 3037 -85034510.41928 +3039 3037 -62539521.39107 +3040 3037 -209278615.3833 +3041 3037 45543422.51828 +3048 3037 -62499999.98975 +3049 3037 -77777669.65641 +3050 3037 12480746.60817 +3051 3037 4.678964614868e-06 +3052 3037 26477385.19127 +3053 3037 -27430243.21608 +3054 3037 62499999.98974 +3055 3037 -79132053.33673 +3056 3037 14949496.6079 +3132 3037 15625000.00513 +3133 3037 -20508055.7522 +3134 3037 -8428858.489084 +3135 3037 -15631586.90536 +3136 3037 -34992516.13117 +3137 3037 4591649.47589 +3144 3037 4.559755325317e-06 +3145 3037 -36055819.793 +3146 3037 -35224114.49497 +3147 3037 15641467.2557 +3148 3037 124030560.5447 +3149 3037 -21261017.33538 +3150 3037 -15634880.35547 +3151 3037 -95897202.5708 +3152 3037 60337907.00837 +3159 3037 -15625000.00513 +3160 3037 -20972669.93059 +3161 3037 -9114622.378198 +3162 3037 4.619359970093e-06 +3163 3037 -23578405.83475 +3164 3037 -6857560.807395 +3165 3037 15625000.00513 +3166 3037 -33359280.17771 +3167 3037 15972183.1856 +3038 3038 898921811.1224 +3039 3038 27046981.82107 +3040 3038 53228121.77035 +3041 3038 1137131.864082 +3048 3038 24401752.02751 +3049 3038 12206441.0528 +3050 3038 -33102362.14451 +3051 3038 -4571811.315691 +3052 3038 -27430243.21608 +3053 3038 34500404.96993 +3054 3038 -27030539.6307 +3055 3038 15223802.16328 +3056 3038 -36714051.95871 +3132 3038 8536049.989829 +3133 3038 -8428858.489084 +3134 3038 -11111959.41625 +3135 3038 54272044.11297 +3136 3038 2673044.969291 +3137 3038 -58743091.68526 +3144 3038 571476.4150219 +3145 3038 -34949808.93959 +3146 3038 30014.53480115 +3147 3038 7718068.787606 +3148 3038 -21255876.71511 +3149 3038 -61506429.36468 +3150 3038 21979483.77819 +3151 3038 61984848.42173 +3152 3038 -115922513.565 +3159 3038 -9107526.404853 +3160 3038 -9114622.378198 +3161 3038 -12350930.55863 +3162 3038 -61974810.45846 +3163 3038 -6857560.807395 +3164 3038 -71902237.78217 +3165 3038 -21965599.32574 +3166 3038 15972183.1856 +3167 3038 -45381891.21762 +3039 3039 638651984.0764 +3040 3039 62499999.98975 +3041 3039 26315015.78297 +3051 3039 -96528642.2817 +3052 3039 -62499999.98975 +3053 3039 24744633.97173 +3054 3039 -359433069.0472 +3055 3039 -62526347.59063 +3056 3039 -26303693.13048 +3057 3039 4145599.03273 +3058 3039 50026347.59267 +3059 3039 -21269642.01197 +3135 3039 2359203.743841 +3136 3039 18759880.3565 +3137 3039 10591538.29392 +3147 3039 -4242975.331225 +3148 3039 -15634880.35547 +3149 3039 -8541442.446936 +3150 3039 88021012.11513 +3151 3039 15625000.00514 +3152 3039 19639605.71133 +3162 3039 -25660413.08922 +3163 3039 -15625000.00513 +3164 3039 -9107526.404853 +3165 3039 -121308672.7549 +3166 3039 -15631586.90535 +3167 3039 -67766682.33182 +3168 3039 -21749648.26534 +3169 3039 12506586.90433 +3170 3039 -17353145.19621 +3040 3040 544867478.3976 +3041 3040 -68597520.2745 +3051 3040 -62499999.98975 +3052 3040 -77777669.65641 +3053 3040 12480746.60817 +3054 3040 -62539521.39107 +3055 3040 -65598146.14324 +3056 3040 -38004027.78497 +3057 3040 75039521.38901 +3058 3040 4145599.032734 +3059 3040 23877447.844 +3135 3040 12506586.90433 +3136 3040 2359203.743842 +3137 3040 -5648902.101029 +3147 3040 -15631586.90535 +3148 3040 -58943322.82077 +3149 3040 -35645020.83586 +3150 3040 15625000.00514 +3151 3040 64574885.68388 +3152 3040 -6700809.891648 +3162 3040 -15625000.00513 +3163 3040 -20972669.93059 +3164 3040 -9114622.378198 +3165 3040 -15634880.35547 +3166 3040 -47849941.99273 +3167 3040 -21743418.55177 +3168 3040 18759880.3565 +3169 3040 -21749648.26534 +3170 3040 20823318.70445 +3041 3041 581180607.3115 +3051 3041 24401752.02751 +3052 3041 12206441.0528 +3053 3041 -33102362.14451 +3054 3041 -26298031.80422 +3055 3041 -30593489.61466 +3056 3041 -36647251.12535 +3057 3041 -31904463.01796 +3058 3041 15918298.56266 +3059 3041 11054930.75394 +3135 3041 7061025.529277 +3136 3041 -8473353.151544 +3137 3041 6291209.983575 +3147 3041 -8539644.961234 +3148 3041 -37291962.41402 +3149 3041 -17378834.23163 +3150 3041 -4768139.577623 +3151 3041 -26226783.67725 +3152 3041 -45750138.7209 +3162 3041 -9107526.404853 +3163 3041 -9114622.378198 +3164 3041 -12350930.55863 +3165 3041 -67422475.35311 +3166 3041 -19819673.42971 +3167 3041 -93029560.64943 +3168 3041 -26029717.79432 +3169 3041 13882212.46963 +3170 3041 -57999062.0409 +3042 3042 1006407425.409 +3043 3042 2.30073928833e-05 +3044 3042 9143622.631317 +3045 3042 111257601.9543 +3046 3042 -1.153349876404e-05 +3047 3042 2285905.658962 +3060 3042 -248524227.8966 +3061 3042 5.185604095459e-06 +3062 3042 -4571811.315691 +3063 3042 -97883025.962 +3064 3042 62499999.98974 +3065 3042 -26687657.68648 +3138 3042 -89115968.74764 +3139 3042 -2.875924110413e-06 +3140 3042 60031786.74372 +3141 3042 -36905217.31746 +3142 3042 -15625000.00514 +3143 3042 21394122.91072 +3153 3042 137281674.8977 +3154 3042 7.092952728271e-06 +3155 3042 2285905.658981 +3156 3042 -24872960.07894 +3157 3042 -1.01625919342e-05 +3158 3042 571476.4150351 +3171 3042 -92328809.14057 +3172 3042 5.915760993958e-06 +3173 3042 -62317692.40268 +3174 3042 -38047023.33633 +3175 3042 15625000.00513 +3176 3042 -21965599.32574 +3043 3043 856399644.4805 +3044 3043 -109720972.8103 +3045 3043 -1.239776611328e-05 +3046 3043 -126242065.9199 +3047 3043 54860486.40512 +3060 3043 4.678964614868e-06 +3061 3043 26477385.19127 +3062 3043 -27430243.21608 +3063 3043 62499999.98974 +3064 3043 -79132053.33673 +3065 3043 14949496.6079 +3138 3043 -4.589557647705e-06 +3139 3043 -20365565.44178 +3140 3043 -6857560.807395 +3141 3043 -15625000.00514 +3142 3043 -32217474.15883 +3143 3043 15286419.29648 +3153 3043 6.973743438721e-06 +3154 3043 99779729.64718 +3155 3043 -27430243.21607 +3156 3043 -8.568167686462e-06 +3157 3043 -84247877.07676 +3158 3043 62654357.71105 +3171 3043 4.619359970093e-06 +3172 3043 -23578405.83475 +3173 3043 -6857560.807395 +3174 3043 15625000.00513 +3175 3043 -33359280.17771 +3176 3043 15972183.1856 +3044 3044 889294330.4544 +3045 3044 2285905.658962 +3046 3044 54860486.40512 +3047 3044 48069959.95526 +3060 3044 -4571811.315691 +3061 3044 -27430243.21608 +3062 3044 34500404.96993 +3063 3044 -27030539.6307 +3064 3044 15223802.16328 +3065 3044 -36714051.95871 +3138 3044 59688904.7995 +3139 3044 -6857560.807395 +3140 3044 -63334663.40088 +3141 3044 21394122.91072 +3142 3044 15286419.29648 +3143 3044 -42337075.16724 +3153 3044 2285905.658981 +3154 3044 -27430243.21607 +3155 3044 -82530234.81935 +3156 3044 571476.4150354 +3157 3044 62380052.15567 +3158 3044 -128482138.2218 +3171 3044 -61974810.45846 +3172 3044 -6857560.807395 +3173 3044 -71902237.78217 +3174 3044 -21965599.32574 +3175 3044 15972183.1856 +3176 3044 -45381891.21762 +3045 3045 1006407425.409 +3046 3045 2.30073928833e-05 +3047 3045 9143622.631317 +3048 3045 111257601.9543 +3049 3045 -1.153349876404e-05 +3050 3045 2285905.658962 +3060 3045 -96528642.2817 +3061 3045 -62499999.98975 +3062 3045 24744633.97173 +3063 3045 -248524227.8966 +3064 3045 5.185604095459e-06 +3065 3045 -4571811.315691 +3066 3045 -97883025.962 +3067 3045 62499999.98974 +3068 3045 -26687657.68648 +3138 3045 -25195798.91083 +3139 3045 15625000.00513 +3140 3045 8536049.989829 +3141 3045 -89115968.74764 +3142 3045 -2.875924110413e-06 +3143 3045 60031786.74372 +3144 3045 -36905217.31746 +3145 3045 -15625000.00514 +3146 3045 21394122.91072 +3153 3045 23319097.20481 +3154 3045 3.09944152832e-06 +3155 3045 571476.4150216 +3156 3045 137281674.8977 +3157 3045 7.092952728271e-06 +3158 3045 2285905.658981 +3159 3045 -24872960.07894 +3160 3045 -1.01625919342e-05 +3161 3045 571476.4150351 +3171 3045 -25660413.08922 +3172 3045 -15625000.00513 +3173 3045 -9107526.404853 +3174 3045 -92328809.14057 +3175 3045 5.915760993958e-06 +3176 3045 -62317692.40268 +3177 3045 -38047023.33633 +3178 3045 15625000.00513 +3179 3045 -21965599.32574 +3046 3046 856399644.4805 +3047 3046 -109720972.8103 +3048 3046 -1.239776611328e-05 +3049 3046 -126242065.9199 +3050 3046 54860486.40512 +3060 3046 -62499999.98975 +3061 3046 -77777669.65641 +3062 3046 12480746.60817 +3063 3046 4.678964614868e-06 +3064 3046 26477385.19127 +3065 3046 -27430243.21608 +3066 3046 62499999.98974 +3067 3046 -79132053.33673 +3068 3046 14949496.6079 +3138 3046 15625000.00513 +3139 3046 -20508055.7522 +3140 3046 -8428858.489084 +3141 3046 -4.589557647705e-06 +3142 3046 -20365565.44178 +3143 3046 -6857560.807395 +3144 3046 -15625000.00514 +3145 3046 -32217474.15883 +3146 3046 15286419.29648 +3153 3046 4.559755325317e-06 +3154 3046 -36055819.793 +3155 3046 -35224114.49497 +3156 3046 6.973743438721e-06 +3157 3046 99779729.64718 +3158 3046 -27430243.21607 +3159 3046 -8.568167686462e-06 +3160 3046 -84247877.07676 +3161 3046 62654357.71105 +3171 3046 -15625000.00513 +3172 3046 -20972669.93059 +3173 3046 -9114622.378198 +3174 3046 4.619359970093e-06 +3175 3046 -23578405.83475 +3176 3046 -6857560.807395 +3177 3046 15625000.00513 +3178 3046 -33359280.17771 +3179 3046 15972183.1856 +3047 3047 889294330.4544 +3048 3047 2285905.658962 +3049 3047 54860486.40512 +3050 3047 48069959.95526 +3060 3047 24401752.02751 +3061 3047 12206441.0528 +3062 3047 -33102362.14451 +3063 3047 -4571811.315691 +3064 3047 -27430243.21608 +3065 3047 34500404.96993 +3066 3047 -27030539.6307 +3067 3047 15223802.16328 +3068 3047 -36714051.95871 +3138 3047 8536049.989829 +3139 3047 -8428858.489084 +3140 3047 -11111959.41625 +3141 3047 59688904.7995 +3142 3047 -6857560.807395 +3143 3047 -63334663.40088 +3144 3047 21394122.91072 +3145 3047 15286419.29648 +3146 3047 -42337075.16724 +3153 3047 571476.4150219 +3154 3047 -34949808.93959 +3155 3047 30014.53480115 +3156 3047 2285905.658981 +3157 3047 -27430243.21607 +3158 3047 -82530234.81935 +3159 3047 571476.4150354 +3160 3047 62380052.15567 +3161 3047 -128482138.2218 +3171 3047 -9107526.404853 +3172 3047 -9114622.378198 +3173 3047 -12350930.55863 +3174 3047 -61974810.45846 +3175 3047 -6857560.807395 +3176 3047 -71902237.78217 +3177 3047 -21965599.32574 +3178 3047 15972183.1856 +3179 3047 -45381891.21762 +3048 3048 1006407425.409 +3049 3048 2.30073928833e-05 +3050 3048 9143622.631317 +3051 3048 111257601.9543 +3052 3048 -1.153349876404e-05 +3053 3048 2285905.658962 +3063 3048 -96528642.2817 +3064 3048 -62499999.98975 +3065 3048 24744633.97173 +3066 3048 -248524227.8966 +3067 3048 5.185604095459e-06 +3068 3048 -4571811.315691 +3069 3048 -97883025.962 +3070 3048 62499999.98974 +3071 3048 -26687657.68648 +3141 3048 -25195798.91083 +3142 3048 15625000.00513 +3143 3048 8536049.989829 +3144 3048 -89115968.74764 +3145 3048 -2.875924110413e-06 +3146 3048 60031786.74372 +3147 3048 -36905217.31746 +3148 3048 -15625000.00514 +3149 3048 21394122.91072 +3156 3048 23319097.20481 +3157 3048 3.09944152832e-06 +3158 3048 571476.4150216 +3159 3048 137281674.8977 +3160 3048 7.092952728271e-06 +3161 3048 2285905.658981 +3162 3048 -24872960.07894 +3163 3048 -1.01625919342e-05 +3164 3048 571476.4150351 +3174 3048 -25660413.08922 +3175 3048 -15625000.00513 +3176 3048 -9107526.404853 +3177 3048 -92328809.14057 +3178 3048 5.915760993958e-06 +3179 3048 -62317692.40268 +3180 3048 -38047023.33633 +3181 3048 15625000.00513 +3182 3048 -21965599.32574 +3049 3049 856399644.4805 +3050 3049 -109720972.8103 +3051 3049 -1.239776611328e-05 +3052 3049 -126242065.9199 +3053 3049 54860486.40512 +3063 3049 -62499999.98975 +3064 3049 -77777669.65641 +3065 3049 12480746.60817 +3066 3049 4.678964614868e-06 +3067 3049 26477385.19127 +3068 3049 -27430243.21608 +3069 3049 62499999.98974 +3070 3049 -79132053.33673 +3071 3049 14949496.6079 +3141 3049 15625000.00513 +3142 3049 -20508055.7522 +3143 3049 -8428858.489084 +3144 3049 -4.589557647705e-06 +3145 3049 -20365565.44178 +3146 3049 -6857560.807395 +3147 3049 -15625000.00514 +3148 3049 -32217474.15883 +3149 3049 15286419.29648 +3156 3049 4.559755325317e-06 +3157 3049 -36055819.793 +3158 3049 -35224114.49497 +3159 3049 6.973743438721e-06 +3160 3049 99779729.64718 +3161 3049 -27430243.21607 +3162 3049 -8.568167686462e-06 +3163 3049 -84247877.07676 +3164 3049 62654357.71105 +3174 3049 -15625000.00513 +3175 3049 -20972669.93059 +3176 3049 -9114622.378198 +3177 3049 4.619359970093e-06 +3178 3049 -23578405.83475 +3179 3049 -6857560.807395 +3180 3049 15625000.00513 +3181 3049 -33359280.17771 +3182 3049 15972183.1856 +3050 3050 889294330.4544 +3051 3050 2285905.658962 +3052 3050 54860486.40512 +3053 3050 48069959.95526 +3063 3050 24401752.02751 +3064 3050 12206441.0528 +3065 3050 -33102362.14451 +3066 3050 -4571811.315691 +3067 3050 -27430243.21608 +3068 3050 34500404.96993 +3069 3050 -27030539.6307 +3070 3050 15223802.16328 +3071 3050 -36714051.95871 +3141 3050 8536049.989829 +3142 3050 -8428858.489084 +3143 3050 -11111959.41625 +3144 3050 59688904.7995 +3145 3050 -6857560.807395 +3146 3050 -63334663.40088 +3147 3050 21394122.91072 +3148 3050 15286419.29648 +3149 3050 -42337075.16724 +3156 3050 571476.4150219 +3157 3050 -34949808.93959 +3158 3050 30014.53480115 +3159 3050 2285905.658981 +3160 3050 -27430243.21607 +3161 3050 -82530234.81935 +3162 3050 571476.4150354 +3163 3050 62380052.15567 +3164 3050 -128482138.2218 +3174 3050 -9107526.404853 +3175 3050 -9114622.378198 +3176 3050 -12350930.55863 +3177 3050 -61974810.45846 +3178 3050 -6857560.807395 +3179 3050 -71902237.78217 +3180 3050 -21965599.32574 +3181 3050 15972183.1856 +3182 3050 -45381891.21762 +3051 3051 1006407425.409 +3052 3051 2.30073928833e-05 +3053 3051 9143622.631317 +3054 3051 111257601.9543 +3055 3051 -1.153349876404e-05 +3056 3051 2285905.658962 +3066 3051 -96528642.2817 +3067 3051 -62499999.98975 +3068 3051 24744633.97173 +3069 3051 -248524227.8966 +3070 3051 5.185604095459e-06 +3071 3051 -4571811.315691 +3072 3051 -97883025.962 +3073 3051 62499999.98974 +3074 3051 -26687657.68648 +3144 3051 -25195798.91083 +3145 3051 15625000.00513 +3146 3051 8536049.989829 +3147 3051 -89115968.74764 +3148 3051 -2.875924110413e-06 +3149 3051 60031786.74372 +3150 3051 -36905217.31746 +3151 3051 -15625000.00514 +3152 3051 21394122.91072 +3159 3051 23319097.20481 +3160 3051 3.09944152832e-06 +3161 3051 571476.4150216 +3162 3051 137281674.8977 +3163 3051 7.092952728271e-06 +3164 3051 2285905.658981 +3165 3051 -24872960.07894 +3166 3051 -1.01625919342e-05 +3167 3051 571476.4150351 +3177 3051 -25660413.08922 +3178 3051 -15625000.00513 +3179 3051 -9107526.404853 +3180 3051 -92328809.14057 +3181 3051 5.915760993958e-06 +3182 3051 -62317692.40268 +3183 3051 -38047023.33633 +3184 3051 15625000.00513 +3185 3051 -21965599.32574 +3052 3052 856399644.4805 +3053 3052 -109720972.8103 +3054 3052 -1.239776611328e-05 +3055 3052 -126242065.9199 +3056 3052 54860486.40512 +3066 3052 -62499999.98975 +3067 3052 -77777669.65641 +3068 3052 12480746.60817 +3069 3052 4.678964614868e-06 +3070 3052 26477385.19127 +3071 3052 -27430243.21608 +3072 3052 62499999.98974 +3073 3052 -79132053.33673 +3074 3052 14949496.6079 +3144 3052 15625000.00513 +3145 3052 -20508055.7522 +3146 3052 -8428858.489084 +3147 3052 -4.589557647705e-06 +3148 3052 -20365565.44178 +3149 3052 -6857560.807395 +3150 3052 -15625000.00514 +3151 3052 -32217474.15883 +3152 3052 15286419.29648 +3159 3052 4.559755325317e-06 +3160 3052 -36055819.793 +3161 3052 -35224114.49497 +3162 3052 6.973743438721e-06 +3163 3052 99779729.64718 +3164 3052 -27430243.21607 +3165 3052 -8.568167686462e-06 +3166 3052 -84247877.07676 +3167 3052 62654357.71105 +3177 3052 -15625000.00513 +3178 3052 -20972669.93059 +3179 3052 -9114622.378198 +3180 3052 4.619359970093e-06 +3181 3052 -23578405.83475 +3182 3052 -6857560.807395 +3183 3052 15625000.00513 +3184 3052 -33359280.17771 +3185 3052 15972183.1856 +3053 3053 889294330.4544 +3054 3053 2285905.658962 +3055 3053 54860486.40512 +3056 3053 48069959.95526 +3066 3053 24401752.02751 +3067 3053 12206441.0528 +3068 3053 -33102362.14451 +3069 3053 -4571811.315691 +3070 3053 -27430243.21608 +3071 3053 34500404.96993 +3072 3053 -27030539.6307 +3073 3053 15223802.16328 +3074 3053 -36714051.95871 +3144 3053 8536049.989829 +3145 3053 -8428858.489084 +3146 3053 -11111959.41625 +3147 3053 59688904.7995 +3148 3053 -6857560.807395 +3149 3053 -63334663.40088 +3150 3053 21394122.91072 +3151 3053 15286419.29648 +3152 3053 -42337075.16724 +3159 3053 571476.4150219 +3160 3053 -34949808.93959 +3161 3053 30014.53480115 +3162 3053 2285905.658981 +3163 3053 -27430243.21607 +3164 3053 -82530234.81935 +3165 3053 571476.4150354 +3166 3053 62380052.15567 +3167 3053 -128482138.2218 +3177 3053 -9107526.404853 +3178 3053 -9114622.378198 +3179 3053 -12350930.55863 +3180 3053 -61974810.45846 +3181 3053 -6857560.807395 +3182 3053 -71902237.78217 +3183 3053 -21965599.32574 +3184 3053 15972183.1856 +3185 3053 -45381891.21762 +3054 3054 1094265961.25 +3055 3054 62565868.99196 +3056 3054 30858520.46735 +3057 3054 9522774.467089 +3058 3054 -62526347.59063 +3059 3054 26698619.14673 +3069 3054 -96528642.2817 +3070 3054 -62499999.98975 +3071 3054 24744633.97173 +3072 3054 -248524227.8966 +3073 3054 5.185604095459e-06 +3074 3054 -4571811.315691 +3075 3054 -97883025.962 +3076 3054 62499999.98974 +3077 3054 -26687657.68648 +3147 3054 -25195798.91083 +3148 3054 15625000.00513 +3149 3054 8536049.989829 +3150 3054 -108451246.8934 +3151 3054 -15634880.35547 +3152 3054 54616251.09168 +3162 3054 23319097.20481 +3163 3054 3.09944152832e-06 +3164 3054 571476.4150216 +3165 3054 166227659.6012 +3166 3054 15641467.2557 +3167 3054 7711642.939084 +3168 3054 -41196855.08124 +3169 3054 -15631586.90536 +3170 3054 21974855.62738 +3180 3054 -25660413.08922 +3181 3054 -15625000.00513 +3182 3054 -9107526.404853 +3183 3054 -92328809.14057 +3184 3054 5.915760993958e-06 +3185 3054 -62317692.40268 +3186 3054 -38047023.33633 +3187 3054 15625000.00513 +3188 3054 -21965599.32574 +3055 3055 925477565.1068 +3056 3055 -85034510.41928 +3057 3055 -62539521.39107 +3058 3055 -209278615.3833 +3059 3055 45543422.51828 +3069 3055 -62499999.98975 +3070 3055 -77777669.65641 +3071 3055 12480746.60817 +3072 3055 4.678964614868e-06 +3073 3055 26477385.19127 +3074 3055 -27430243.21608 +3075 3055 62499999.98974 +3076 3055 -79132053.33673 +3077 3055 14949496.6079 +3147 3055 15625000.00513 +3148 3055 -20508055.7522 +3149 3055 -8428858.489084 +3150 3055 -15631586.90536 +3151 3055 -34992516.13117 +3152 3055 4591649.47589 +3162 3055 4.559755325317e-06 +3163 3055 -36055819.793 +3164 3055 -35224114.49497 +3165 3055 15641467.2557 +3166 3055 124030560.5447 +3167 3055 -21261017.33538 +3168 3055 -15634880.35547 +3169 3055 -95897202.5708 +3170 3055 60337907.00837 +3180 3055 -15625000.00513 +3181 3055 -20972669.93059 +3182 3055 -9114622.378198 +3183 3055 4.619359970093e-06 +3184 3055 -23578405.83475 +3185 3055 -6857560.807395 +3186 3055 15625000.00513 +3187 3055 -33359280.17771 +3188 3055 15972183.1856 +3056 3056 898921811.1224 +3057 3056 27046981.82107 +3058 3056 53228121.77035 +3059 3056 1137131.864082 +3069 3056 24401752.02751 +3070 3056 12206441.0528 +3071 3056 -33102362.14451 +3072 3056 -4571811.315691 +3073 3056 -27430243.21608 +3074 3056 34500404.96993 +3075 3056 -27030539.6307 +3076 3056 15223802.16328 +3077 3056 -36714051.95871 +3147 3056 8536049.989829 +3148 3056 -8428858.489084 +3149 3056 -11111959.41625 +3150 3056 54272044.11297 +3151 3056 2673044.969291 +3152 3056 -58743091.68526 +3162 3056 571476.4150219 +3163 3056 -34949808.93959 +3164 3056 30014.53480115 +3165 3056 7718068.787606 +3166 3056 -21255876.71511 +3167 3056 -61506429.36468 +3168 3056 21979483.77819 +3169 3056 61984848.42173 +3170 3056 -115922513.565 +3180 3056 -9107526.404853 +3181 3056 -9114622.378198 +3182 3056 -12350930.55863 +3183 3056 -61974810.45846 +3184 3056 -6857560.807395 +3185 3056 -71902237.78217 +3186 3056 -21965599.32574 +3187 3056 15972183.1856 +3188 3056 -45381891.21762 +3057 3057 548987475.0633 +3058 3057 21307129.89102 +3059 3057 -13524506.77974 +3072 3057 -96528642.2817 +3073 3057 -62499999.98975 +3074 3057 24744633.97173 +3075 3057 -261847081.0713 +3076 3057 -21381581.86031 +3077 3057 -1557764.62904 +3078 3057 -19854283.06572 +3079 3057 50074451.96109 +3080 3057 -2748957.564787 +3150 3057 2359203.743841 +3151 3057 18759880.3565 +3152 3057 10591538.29392 +3165 3057 -4242975.331225 +3166 3057 -15634880.35547 +3167 3057 -8541442.446936 +3168 3057 72114571.47739 +3169 3057 6435466.693849 +3170 3057 7686187.419515 +3183 3057 -25660413.08922 +3184 3057 -15625000.00513 +3185 3057 -9107526.404853 +3186 3057 -92399313.58557 +3187 3057 -6452212.714836 +3188 3057 -53750902.19951 +3189 3057 -13992108.66804 +3190 3057 12516746.0251 +3191 3057 -9804889.104296 +3058 3058 522858774.3376 +3059 3058 -70680941.34799 +3072 3058 -62499999.98975 +3073 3058 -77777669.65641 +3074 3058 12480746.60817 +3075 3058 -21418807.84496 +3076 3058 13597222.99385 +3077 3058 -18755531.55843 +3078 3058 75111677.94164 +3079 3058 -69119469.18 +3080 3058 7813396.322461 +3150 3058 12506586.90433 +3151 3058 2359203.743842 +3152 3058 -5648902.101029 +3165 3058 -15631586.90535 +3166 3058 -58943322.82077 +3167 3058 -35645020.83586 +3168 3058 6435466.693849 +3169 3058 63209679.55498 +3170 3058 -8614720.744595 +3183 3058 -15625000.00513 +3184 3058 -20972669.93059 +3185 3058 -9114622.378198 +3186 3058 -6460585.725333 +3187 3058 -23045188.60001 +3188 3058 -9974370.842673 +3189 3058 18775119.03765 +3190 3058 -24428737.40027 +3191 3058 20328376.47072 +3059 3059 514034148.2162 +3072 3059 24401752.02751 +3073 3059 12206441.0528 +3074 3059 -33102362.14451 +3075 3059 -9098900.333417 +3076 3059 -17656224.35797 +3077 3059 2357965.756388 +3078 3059 -4123436.347181 +3079 3059 6715989.826741 +3080 3059 -3679568.727652 +3150 3059 7061025.529277 +3151 3059 -8473353.151544 +3152 3059 6291209.983575 +3165 3059 -8539644.961234 +3166 3059 -37291962.41402 +3167 3059 -17378834.23163 +3168 3059 -13632264.79997 +3169 3059 -25112324.87446 +3170 3059 -49245078.61255 +3183 3059 -9107526.404853 +3184 3059 -9114622.378198 +3185 3059 -12350930.55863 +3186 3059 -55464807.37002 +3187 3059 -9418406.19857 +3188 3059 -65296800.07247 +3189 3059 -14707333.65644 +3190 3059 16406778.36934 +3191 3059 -26875661.04919 +3060 3060 1006407425.409 +3061 3060 2.30073928833e-05 +3062 3060 9143622.631317 +3063 3060 111257601.9543 +3064 3060 -1.153349876404e-05 +3065 3060 2285905.658962 +3081 3060 -248524227.8966 +3082 3060 5.185604095459e-06 +3083 3060 -4571811.315691 +3084 3060 -97883025.962 +3085 3060 62499999.98974 +3086 3060 -26687657.68648 +3153 3060 -89115968.74764 +3154 3060 -2.875924110413e-06 +3155 3060 60031786.74372 +3156 3060 -36905217.31746 +3157 3060 -15625000.00514 +3158 3060 21394122.91072 +3171 3060 137281674.8977 +3172 3060 7.092952728271e-06 +3173 3060 2285905.658981 +3174 3060 -24872960.07894 +3175 3060 -1.01625919342e-05 +3176 3060 571476.4150351 +3192 3060 -92328809.14057 +3193 3060 5.915760993958e-06 +3194 3060 -62317692.40268 +3195 3060 -38047023.33633 +3196 3060 15625000.00513 +3197 3060 -21965599.32574 +3061 3061 856399644.4805 +3062 3061 -109720972.8103 +3063 3061 -1.239776611328e-05 +3064 3061 -126242065.9199 +3065 3061 54860486.40512 +3081 3061 4.678964614868e-06 +3082 3061 26477385.19127 +3083 3061 -27430243.21608 +3084 3061 62499999.98974 +3085 3061 -79132053.33673 +3086 3061 14949496.6079 +3153 3061 -4.589557647705e-06 +3154 3061 -20365565.44178 +3155 3061 -6857560.807395 +3156 3061 -15625000.00514 +3157 3061 -32217474.15883 +3158 3061 15286419.29648 +3171 3061 6.973743438721e-06 +3172 3061 99779729.64718 +3173 3061 -27430243.21607 +3174 3061 -8.568167686462e-06 +3175 3061 -84247877.07676 +3176 3061 62654357.71105 +3192 3061 4.619359970093e-06 +3193 3061 -23578405.83475 +3194 3061 -6857560.807395 +3195 3061 15625000.00513 +3196 3061 -33359280.17771 +3197 3061 15972183.1856 +3062 3062 889294330.4544 +3063 3062 2285905.658962 +3064 3062 54860486.40512 +3065 3062 48069959.95526 +3081 3062 -4571811.315691 +3082 3062 -27430243.21608 +3083 3062 34500404.96993 +3084 3062 -27030539.6307 +3085 3062 15223802.16328 +3086 3062 -36714051.95871 +3153 3062 59688904.7995 +3154 3062 -6857560.807395 +3155 3062 -63334663.40088 +3156 3062 21394122.91072 +3157 3062 15286419.29648 +3158 3062 -42337075.16724 +3171 3062 2285905.658981 +3172 3062 -27430243.21607 +3173 3062 -82530234.81935 +3174 3062 571476.4150354 +3175 3062 62380052.15567 +3176 3062 -128482138.2218 +3192 3062 -61974810.45846 +3193 3062 -6857560.807395 +3194 3062 -71902237.78217 +3195 3062 -21965599.32574 +3196 3062 15972183.1856 +3197 3062 -45381891.21762 +3063 3063 1006407425.409 +3064 3063 2.30073928833e-05 +3065 3063 9143622.631317 +3066 3063 111257601.9543 +3067 3063 -1.153349876404e-05 +3068 3063 2285905.658962 +3081 3063 -96528642.2817 +3082 3063 -62499999.98975 +3083 3063 24744633.97173 +3084 3063 -248524227.8966 +3085 3063 5.185604095459e-06 +3086 3063 -4571811.315691 +3087 3063 -97883025.962 +3088 3063 62499999.98974 +3089 3063 -26687657.68648 +3153 3063 -25195798.91083 +3154 3063 15625000.00513 +3155 3063 8536049.989829 +3156 3063 -89115968.74764 +3157 3063 -2.875924110413e-06 +3158 3063 60031786.74372 +3159 3063 -36905217.31746 +3160 3063 -15625000.00514 +3161 3063 21394122.91072 +3171 3063 23319097.20481 +3172 3063 3.09944152832e-06 +3173 3063 571476.4150216 +3174 3063 137281674.8977 +3175 3063 7.092952728271e-06 +3176 3063 2285905.658981 +3177 3063 -24872960.07894 +3178 3063 -1.01625919342e-05 +3179 3063 571476.4150351 +3192 3063 -25660413.08922 +3193 3063 -15625000.00513 +3194 3063 -9107526.404853 +3195 3063 -92328809.14057 +3196 3063 5.915760993958e-06 +3197 3063 -62317692.40268 +3198 3063 -38047023.33633 +3199 3063 15625000.00513 +3200 3063 -21965599.32574 +3064 3064 856399644.4805 +3065 3064 -109720972.8103 +3066 3064 -1.239776611328e-05 +3067 3064 -126242065.9199 +3068 3064 54860486.40512 +3081 3064 -62499999.98975 +3082 3064 -77777669.65641 +3083 3064 12480746.60817 +3084 3064 4.678964614868e-06 +3085 3064 26477385.19127 +3086 3064 -27430243.21608 +3087 3064 62499999.98974 +3088 3064 -79132053.33673 +3089 3064 14949496.6079 +3153 3064 15625000.00513 +3154 3064 -20508055.7522 +3155 3064 -8428858.489084 +3156 3064 -4.589557647705e-06 +3157 3064 -20365565.44178 +3158 3064 -6857560.807395 +3159 3064 -15625000.00514 +3160 3064 -32217474.15883 +3161 3064 15286419.29648 +3171 3064 4.559755325317e-06 +3172 3064 -36055819.793 +3173 3064 -35224114.49497 +3174 3064 6.973743438721e-06 +3175 3064 99779729.64718 +3176 3064 -27430243.21607 +3177 3064 -8.568167686462e-06 +3178 3064 -84247877.07676 +3179 3064 62654357.71105 +3192 3064 -15625000.00513 +3193 3064 -20972669.93059 +3194 3064 -9114622.378198 +3195 3064 4.619359970093e-06 +3196 3064 -23578405.83475 +3197 3064 -6857560.807395 +3198 3064 15625000.00513 +3199 3064 -33359280.17771 +3200 3064 15972183.1856 +3065 3065 889294330.4544 +3066 3065 2285905.658962 +3067 3065 54860486.40512 +3068 3065 48069959.95526 +3081 3065 24401752.02751 +3082 3065 12206441.0528 +3083 3065 -33102362.14451 +3084 3065 -4571811.315691 +3085 3065 -27430243.21608 +3086 3065 34500404.96993 +3087 3065 -27030539.6307 +3088 3065 15223802.16328 +3089 3065 -36714051.95871 +3153 3065 8536049.989829 +3154 3065 -8428858.489084 +3155 3065 -11111959.41625 +3156 3065 59688904.7995 +3157 3065 -6857560.807395 +3158 3065 -63334663.40088 +3159 3065 21394122.91072 +3160 3065 15286419.29648 +3161 3065 -42337075.16724 +3171 3065 571476.4150219 +3172 3065 -34949808.93959 +3173 3065 30014.53480115 +3174 3065 2285905.658981 +3175 3065 -27430243.21607 +3176 3065 -82530234.81935 +3177 3065 571476.4150354 +3178 3065 62380052.15567 +3179 3065 -128482138.2218 +3192 3065 -9107526.404853 +3193 3065 -9114622.378198 +3194 3065 -12350930.55863 +3195 3065 -61974810.45846 +3196 3065 -6857560.807395 +3197 3065 -71902237.78217 +3198 3065 -21965599.32574 +3199 3065 15972183.1856 +3200 3065 -45381891.21762 +3066 3066 1006407425.409 +3067 3066 2.30073928833e-05 +3068 3066 9143622.631317 +3069 3066 111257601.9543 +3070 3066 -1.153349876404e-05 +3071 3066 2285905.658962 +3084 3066 -96528642.2817 +3085 3066 -62499999.98975 +3086 3066 24744633.97173 +3087 3066 -248524227.8966 +3088 3066 5.185604095459e-06 +3089 3066 -4571811.315691 +3090 3066 -97883025.962 +3091 3066 62499999.98974 +3092 3066 -26687657.68648 +3156 3066 -25195798.91083 +3157 3066 15625000.00513 +3158 3066 8536049.989829 +3159 3066 -89115968.74764 +3160 3066 -2.875924110413e-06 +3161 3066 60031786.74372 +3162 3066 -36905217.31746 +3163 3066 -15625000.00514 +3164 3066 21394122.91072 +3174 3066 23319097.20481 +3175 3066 3.09944152832e-06 +3176 3066 571476.4150216 +3177 3066 137281674.8977 +3178 3066 7.092952728271e-06 +3179 3066 2285905.658981 +3180 3066 -24872960.07894 +3181 3066 -1.01625919342e-05 +3182 3066 571476.4150351 +3195 3066 -25660413.08922 +3196 3066 -15625000.00513 +3197 3066 -9107526.404853 +3198 3066 -92328809.14057 +3199 3066 5.915760993958e-06 +3200 3066 -62317692.40268 +3201 3066 -38047023.33633 +3202 3066 15625000.00513 +3203 3066 -21965599.32574 +3067 3067 856399644.4805 +3068 3067 -109720972.8103 +3069 3067 -1.239776611328e-05 +3070 3067 -126242065.9199 +3071 3067 54860486.40512 +3084 3067 -62499999.98975 +3085 3067 -77777669.65641 +3086 3067 12480746.60817 +3087 3067 4.678964614868e-06 +3088 3067 26477385.19127 +3089 3067 -27430243.21608 +3090 3067 62499999.98974 +3091 3067 -79132053.33673 +3092 3067 14949496.6079 +3156 3067 15625000.00513 +3157 3067 -20508055.7522 +3158 3067 -8428858.489084 +3159 3067 -4.589557647705e-06 +3160 3067 -20365565.44178 +3161 3067 -6857560.807395 +3162 3067 -15625000.00514 +3163 3067 -32217474.15883 +3164 3067 15286419.29648 +3174 3067 4.559755325317e-06 +3175 3067 -36055819.793 +3176 3067 -35224114.49497 +3177 3067 6.973743438721e-06 +3178 3067 99779729.64718 +3179 3067 -27430243.21607 +3180 3067 -8.568167686462e-06 +3181 3067 -84247877.07676 +3182 3067 62654357.71105 +3195 3067 -15625000.00513 +3196 3067 -20972669.93059 +3197 3067 -9114622.378198 +3198 3067 4.619359970093e-06 +3199 3067 -23578405.83475 +3200 3067 -6857560.807395 +3201 3067 15625000.00513 +3202 3067 -33359280.17771 +3203 3067 15972183.1856 +3068 3068 889294330.4544 +3069 3068 2285905.658962 +3070 3068 54860486.40512 +3071 3068 48069959.95526 +3084 3068 24401752.02751 +3085 3068 12206441.0528 +3086 3068 -33102362.14451 +3087 3068 -4571811.315691 +3088 3068 -27430243.21608 +3089 3068 34500404.96993 +3090 3068 -27030539.6307 +3091 3068 15223802.16328 +3092 3068 -36714051.95871 +3156 3068 8536049.989829 +3157 3068 -8428858.489084 +3158 3068 -11111959.41625 +3159 3068 59688904.7995 +3160 3068 -6857560.807395 +3161 3068 -63334663.40088 +3162 3068 21394122.91072 +3163 3068 15286419.29648 +3164 3068 -42337075.16724 +3174 3068 571476.4150219 +3175 3068 -34949808.93959 +3176 3068 30014.53480115 +3177 3068 2285905.658981 +3178 3068 -27430243.21607 +3179 3068 -82530234.81935 +3180 3068 571476.4150354 +3181 3068 62380052.15567 +3182 3068 -128482138.2218 +3195 3068 -9107526.404853 +3196 3068 -9114622.378198 +3197 3068 -12350930.55863 +3198 3068 -61974810.45846 +3199 3068 -6857560.807395 +3200 3068 -71902237.78217 +3201 3068 -21965599.32574 +3202 3068 15972183.1856 +3203 3068 -45381891.21762 +3069 3069 1006407425.409 +3070 3069 2.30073928833e-05 +3071 3069 9143622.631317 +3072 3069 111257601.9543 +3073 3069 -1.153349876404e-05 +3074 3069 2285905.658962 +3087 3069 -96528642.2817 +3088 3069 -62499999.98975 +3089 3069 24744633.97173 +3090 3069 -248524227.8966 +3091 3069 5.185604095459e-06 +3092 3069 -4571811.315691 +3093 3069 -97883025.962 +3094 3069 62499999.98974 +3095 3069 -26687657.68648 +3159 3069 -25195798.91083 +3160 3069 15625000.00513 +3161 3069 8536049.989829 +3162 3069 -89115968.74764 +3163 3069 -2.875924110413e-06 +3164 3069 60031786.74372 +3165 3069 -36905217.31746 +3166 3069 -15625000.00514 +3167 3069 21394122.91072 +3177 3069 23319097.20481 +3178 3069 3.09944152832e-06 +3179 3069 571476.4150216 +3180 3069 137281674.8977 +3181 3069 7.092952728271e-06 +3182 3069 2285905.658981 +3183 3069 -24872960.07894 +3184 3069 -1.01625919342e-05 +3185 3069 571476.4150351 +3198 3069 -25660413.08922 +3199 3069 -15625000.00513 +3200 3069 -9107526.404853 +3201 3069 -92328809.14057 +3202 3069 5.915760993958e-06 +3203 3069 -62317692.40268 +3204 3069 -38047023.33633 +3205 3069 15625000.00513 +3206 3069 -21965599.32574 +3070 3070 856399644.4805 +3071 3070 -109720972.8103 +3072 3070 -1.239776611328e-05 +3073 3070 -126242065.9199 +3074 3070 54860486.40512 +3087 3070 -62499999.98975 +3088 3070 -77777669.65641 +3089 3070 12480746.60817 +3090 3070 4.678964614868e-06 +3091 3070 26477385.19127 +3092 3070 -27430243.21608 +3093 3070 62499999.98974 +3094 3070 -79132053.33673 +3095 3070 14949496.6079 +3159 3070 15625000.00513 +3160 3070 -20508055.7522 +3161 3070 -8428858.489084 +3162 3070 -4.589557647705e-06 +3163 3070 -20365565.44178 +3164 3070 -6857560.807395 +3165 3070 -15625000.00514 +3166 3070 -32217474.15883 +3167 3070 15286419.29648 +3177 3070 4.559755325317e-06 +3178 3070 -36055819.793 +3179 3070 -35224114.49497 +3180 3070 6.973743438721e-06 +3181 3070 99779729.64718 +3182 3070 -27430243.21607 +3183 3070 -8.568167686462e-06 +3184 3070 -84247877.07676 +3185 3070 62654357.71105 +3198 3070 -15625000.00513 +3199 3070 -20972669.93059 +3200 3070 -9114622.378198 +3201 3070 4.619359970093e-06 +3202 3070 -23578405.83475 +3203 3070 -6857560.807395 +3204 3070 15625000.00513 +3205 3070 -33359280.17771 +3206 3070 15972183.1856 +3071 3071 889294330.4544 +3072 3071 2285905.658962 +3073 3071 54860486.40512 +3074 3071 48069959.95526 +3087 3071 24401752.02751 +3088 3071 12206441.0528 +3089 3071 -33102362.14451 +3090 3071 -4571811.315691 +3091 3071 -27430243.21608 +3092 3071 34500404.96993 +3093 3071 -27030539.6307 +3094 3071 15223802.16328 +3095 3071 -36714051.95871 +3159 3071 8536049.989829 +3160 3071 -8428858.489084 +3161 3071 -11111959.41625 +3162 3071 59688904.7995 +3163 3071 -6857560.807395 +3164 3071 -63334663.40088 +3165 3071 21394122.91072 +3166 3071 15286419.29648 +3167 3071 -42337075.16724 +3177 3071 571476.4150219 +3178 3071 -34949808.93959 +3179 3071 30014.53480115 +3180 3071 2285905.658981 +3181 3071 -27430243.21607 +3182 3071 -82530234.81935 +3183 3071 571476.4150354 +3184 3071 62380052.15567 +3185 3071 -128482138.2218 +3198 3071 -9107526.404853 +3199 3071 -9114622.378198 +3200 3071 -12350930.55863 +3201 3071 -61974810.45846 +3202 3071 -6857560.807395 +3203 3071 -71902237.78217 +3204 3071 -21965599.32574 +3205 3071 15972183.1856 +3206 3071 -45381891.21762 +3072 3072 1006407425.409 +3073 3072 2.30073928833e-05 +3074 3072 9143622.631317 +3075 3072 111257601.9543 +3076 3072 -1.153349876404e-05 +3077 3072 2285905.658962 +3090 3072 -96528642.2817 +3091 3072 -62499999.98975 +3092 3072 24744633.97173 +3093 3072 -248524227.8966 +3094 3072 5.185604095459e-06 +3095 3072 -4571811.315691 +3096 3072 -97883025.962 +3097 3072 62499999.98974 +3098 3072 -26687657.68648 +3162 3072 -25195798.91083 +3163 3072 15625000.00513 +3164 3072 8536049.989829 +3165 3072 -89115968.74764 +3166 3072 -2.875924110413e-06 +3167 3072 60031786.74372 +3168 3072 -36905217.31746 +3169 3072 -15625000.00514 +3170 3072 21394122.91072 +3180 3072 23319097.20481 +3181 3072 3.09944152832e-06 +3182 3072 571476.4150216 +3183 3072 137281674.8977 +3184 3072 7.092952728271e-06 +3185 3072 2285905.658981 +3186 3072 -24872960.07894 +3187 3072 -1.01625919342e-05 +3188 3072 571476.4150351 +3201 3072 -25660413.08922 +3202 3072 -15625000.00513 +3203 3072 -9107526.404853 +3204 3072 -92328809.14057 +3205 3072 5.915760993958e-06 +3206 3072 -62317692.40268 +3207 3072 -38047023.33633 +3208 3072 15625000.00513 +3209 3072 -21965599.32574 +3073 3073 856399644.4805 +3074 3073 -109720972.8103 +3075 3073 -1.239776611328e-05 +3076 3073 -126242065.9199 +3077 3073 54860486.40512 +3090 3073 -62499999.98975 +3091 3073 -77777669.65641 +3092 3073 12480746.60817 +3093 3073 4.678964614868e-06 +3094 3073 26477385.19127 +3095 3073 -27430243.21608 +3096 3073 62499999.98974 +3097 3073 -79132053.33673 +3098 3073 14949496.6079 +3162 3073 15625000.00513 +3163 3073 -20508055.7522 +3164 3073 -8428858.489084 +3165 3073 -4.589557647705e-06 +3166 3073 -20365565.44178 +3167 3073 -6857560.807395 +3168 3073 -15625000.00514 +3169 3073 -32217474.15883 +3170 3073 15286419.29648 +3180 3073 4.559755325317e-06 +3181 3073 -36055819.793 +3182 3073 -35224114.49497 +3183 3073 6.973743438721e-06 +3184 3073 99779729.64718 +3185 3073 -27430243.21607 +3186 3073 -8.568167686462e-06 +3187 3073 -84247877.07676 +3188 3073 62654357.71105 +3201 3073 -15625000.00513 +3202 3073 -20972669.93059 +3203 3073 -9114622.378198 +3204 3073 4.619359970093e-06 +3205 3073 -23578405.83475 +3206 3073 -6857560.807395 +3207 3073 15625000.00513 +3208 3073 -33359280.17771 +3209 3073 15972183.1856 +3074 3074 889294330.4544 +3075 3074 2285905.658962 +3076 3074 54860486.40512 +3077 3074 48069959.95526 +3090 3074 24401752.02751 +3091 3074 12206441.0528 +3092 3074 -33102362.14451 +3093 3074 -4571811.315691 +3094 3074 -27430243.21608 +3095 3074 34500404.96993 +3096 3074 -27030539.6307 +3097 3074 15223802.16328 +3098 3074 -36714051.95871 +3162 3074 8536049.989829 +3163 3074 -8428858.489084 +3164 3074 -11111959.41625 +3165 3074 59688904.7995 +3166 3074 -6857560.807395 +3167 3074 -63334663.40088 +3168 3074 21394122.91072 +3169 3074 15286419.29648 +3170 3074 -42337075.16724 +3180 3074 571476.4150219 +3181 3074 -34949808.93959 +3182 3074 30014.53480115 +3183 3074 2285905.658981 +3184 3074 -27430243.21607 +3185 3074 -82530234.81935 +3186 3074 571476.4150354 +3187 3074 62380052.15567 +3188 3074 -128482138.2218 +3201 3074 -9107526.404853 +3202 3074 -9114622.378198 +3203 3074 -12350930.55863 +3204 3074 -61974810.45846 +3205 3074 -6857560.807395 +3206 3074 -71902237.78217 +3207 3074 -21965599.32574 +3208 3074 15972183.1856 +3209 3074 -45381891.21762 +3075 3075 954625585.2576 +3076 3075 29678719.75277 +3077 3075 9105132.755896 +3078 3075 -47307070.82524 +3079 3075 -84184102.99752 +3080 3075 5164900.375931 +3093 3075 -96528642.2817 +3094 3075 -62499999.98975 +3095 3075 24744633.97173 +3096 3075 -208808375.5906 +3097 3075 19521715.15921 +3098 3075 -950281.2899645 +3099 3075 -59636163.25621 +3100 3075 56402475.93051 +3101 3075 -4219483.641776 +3165 3075 -25195798.91083 +3166 3075 15625000.00513 +3167 3075 8536049.989829 +3168 3075 -89144937.54779 +3169 3075 -6460585.725337 +3170 3075 51127453.72743 +3183 3075 23319097.20481 +3184 3075 3.09944152832e-06 +3185 3075 571476.4150216 +3186 3075 140900154.1745 +3187 3075 8091534.898148 +3188 3075 2277246.826934 +3189 3075 -36337710.48924 +3190 3075 -20431230.61693 +3191 3075 17381850.39246 +3204 3075 -25660413.08922 +3205 3075 -15625000.00513 +3206 3075 -9107526.404853 +3207 3075 -83880342.47951 +3208 3075 4387679.506918 +3209 3075 -58292492.12322 +3210 3075 -24702531.44058 +3211 3075 14412601.93721 +3212 3075 -12457232.71543 +3076 3076 902985704.5719 +3077 3076 -67543036.76971 +3078 3076 -84221328.98217 +3079 3076 -272339828.8601 +3080 3076 10901872.41377 +3093 3076 -62499999.98975 +3094 3076 -77777669.65641 +3095 3076 12480746.60817 +3096 3076 19521715.15921 +3097 3076 41553709.10479 +3098 3076 -16437185.11221 +3099 3076 56402475.93051 +3100 3076 -108772190.6724 +3101 3076 4878966.421197 +3165 3076 15625000.00513 +3166 3076 -20508055.7522 +3167 3076 -8428858.489084 +3168 3076 -6452212.714842 +3169 3076 -19790812.56221 +3170 3076 965606.207854 +3183 3076 4.559755325317e-06 +3184 3076 -36055819.793 +3185 3076 -35224114.49497 +3186 3076 8091534.898145 +3187 3076 124639359.3474 +3188 3076 -16627910.42329 +3189 3076 -20439603.62743 +3190 3076 -92308791.06968 +3191 3076 54241007.71012 +3204 3076 -15625000.00513 +3205 3076 -20972669.93059 +3206 3076 -9114622.378198 +3207 3076 4387679.506917 +3208 3076 -20509034.904 +3209 3076 -314146.4441922 +3210 3076 14412601.93721 +3211 3076 -35196657.91355 +3212 3076 17824166.7884 +3077 3077 813405107.3031 +3078 3077 5167851.380775 +3079 3077 10904504.6108 +3080 3077 -27259503.15959 +3093 3077 24401752.02751 +3094 3077 12206441.0528 +3095 3077 -33102362.14451 +3096 3077 -8493684.066505 +3097 3077 -16437185.1122 +3098 3077 42009619.57762 +3099 3077 -4219483.641101 +3100 3077 4878966.421197 +3101 3077 -25105860.06319 +3165 3077 8536049.989829 +3166 3077 -8428858.489084 +3167 3077 -11111959.41625 +3168 3077 52841358.89794 +3169 3077 972051.0689625 +3170 3077 -56618463.97163 +3183 3077 571476.4150219 +3184 3077 -34949808.93959 +3185 3077 30014.53480115 +3186 3077 2289414.3277 +3187 3077 -15520953.90292 +3188 3077 -63976344.06463 +3189 3077 17388600.49754 +3190 3077 54239559.45527 +3191 3077 -75561570.76464 +3204 3077 -9107526.404853 +3205 3077 -9114622.378198 +3206 3077 -12350930.55863 +3207 3077 -60006901.8455 +3208 3077 -39840.88786912 +3209 3077 -71401065.72684 +3210 3077 -12457232.71543 +3211 3077 17824166.7884 +3212 3077 -30882966.90637 +3078 3078 563895329.5604 +3079 3078 12094082.46684 +3080 3078 350095.2308891 +3096 3078 -100199889.2755 +3097 3078 -61716139.93398 +3098 3078 3694588.2501 +3099 3078 -138007703.9904 +3100 3078 26141729.8893 +3101 3078 -1426197.341684 +3102 3078 66091143.81331 +3103 3078 -23810230.64342 +3104 3078 -84364.06685483 +3105 3078 -50572046.81022 +3106 3078 56400209.26179 +3107 3078 -835481.5495841 +3168 3078 -10044859.78212 +3169 3078 18775119.03765 +3170 3078 12646043.37978 +3186 3078 -29381178.05408 +3187 3078 -20439603.62743 +3188 3078 -14862571.67359 +3189 3078 44407129.00917 +3190 3078 2732061.517723 +3191 3078 12772232.20442 +3207 3078 -31931434.66587 +3208 3078 -15470023.5297 +3209 3078 -15179205.07113 +3210 3078 -77039196.05297 +3211 3078 5859266.438322 +3212 3078 -63722944.41981 +3213 3078 -7975427.310119 +3214 3078 -5702105.11695 +3215 3078 8764300.831026 +3216 3078 -25052811.64063 +3217 3078 14245285.28038 +3218 3078 -15798966.36227 +3079 3079 697591530.9292 +3080 3079 -13690717.22567 +3096 3079 -61716139.93398 +3097 3079 -67571752.73443 +3098 3079 958073.8792971 +3099 3079 26141729.8893 +3100 3079 104711137.1152 +3101 3079 -3780060.244209 +3102 3079 1189769.352479 +3103 3079 -55490454.62227 +3104 3079 514661.2980421 +3105 3079 56400209.26179 +3106 3079 -63735683.24105 +3107 3079 567096.4529157 +3168 3079 12516746.0251 +3169 3079 -20481488.51436 +3170 3079 -13323982.79472 +3186 3079 -20431230.61693 +3187 3079 -85352258.63453 +3188 3079 -48907517.62925 +3189 3079 2732061.517722 +3190 3079 74751645.69339 +3191 3079 384085.0688729 +3207 3079 -15470023.5297 +3208 3079 -24154401.16993 +3209 3079 -12628280.16189 +3210 3079 5859266.438323 +3211 3079 -15691362.14432 +3212 3079 2860835.284096 +3213 3079 547894.8851028 +3214 3079 -38358437.39327 +3215 3079 33460909.06044 +3216 3079 14245285.28038 +3217 3079 -27731476.33361 +3218 3079 16805961.40619 +3080 3080 611810183.1273 +3096 3080 3694588.250438 +3097 3080 958073.8795674 +3098 3080 -24420311.97772 +3099 3080 -1426197.341683 +3100 3080 -3780060.244208 +3101 3080 101673342.4859 +3102 3080 -84364.06685185 +3103 3080 514661.2980419 +3104 3080 71753512.71717 +3105 3080 -835481.5492466 +3106 3080 567096.4529157 +3107 3080 910290.6188606 +3168 3080 8430695.586522 +3169 3080 -16696841.26379 +3170 3080 -16349664.0201 +3186 3080 -14857154.43812 +3187 3080 -48910133.59817 +3188 3080 -57010817.60422 +3189 3080 -12583392.79142 +3190 3080 -6914435.376953 +3191 3080 -105490238.163 +3207 3080 -15179205.07113 +3208 3080 -12628280.16189 +3209 3080 -24783666.57282 +3210 3080 -63722944.42014 +3211 3080 2860835.284773 +3212 3080 -82669051.73675 +3213 3080 639300.8292051 +3214 3080 33460909.06044 +3215 3080 -47849796.71078 +3216 3080 -15798966.36227 +3217 3080 16805961.40619 +3218 3080 -31227507.85006 +3081 3081 503203712.7044 +3082 3081 1.287460327148e-05 +3083 3081 4571811.315658 +3084 3081 55651374.03849 +3085 3081 12499999.99794 +3086 3081 -3143071.475793 +3171 3081 -89115968.74764 +3172 3081 -2.875924110413e-06 +3173 3081 60031786.74372 +3174 3081 -36905217.31746 +3175 3081 -15625000.00514 +3176 3081 21394122.91072 +3192 3081 68618264.38753 +3193 3081 3.814697265625e-06 +3194 3081 -11914911.75127 +3195 3081 -12436480.03947 +3196 3081 3125000.001022 +3197 3081 -4050234.016128 +3082 3082 428199822.2403 +3083 3082 -54860486.40512 +3084 3082 -12499999.99795 +3085 3082 -63098459.89864 +3086 3082 27155937.64705 +3171 3082 -4.589557647705e-06 +3172 3082 -20365565.44178 +3173 3082 -6857560.807395 +3174 3082 -15625000.00514 +3175 3082 -32217474.15883 +3176 3082 15286419.29648 +3192 3082 2.026557922363e-06 +3193 3082 49867291.76226 +3194 3082 -13715121.60804 +3195 3082 -3125000.001031 +3196 3082 -42123938.53837 +3197 3082 31258602.46661 +3083 3083 444647165.2272 +3084 3083 7143386.85585 +3085 3083 27704548.75807 +3086 3083 24095174.80784 +3171 3083 59688904.7995 +3172 3083 -6857560.807395 +3173 3083 -63334663.40088 +3174 3083 21394122.91072 +3175 3083 15286419.29648 +3176 3083 -42337075.16724 +3192 3083 12486407.68916 +3193 3083 -13715121.60804 +3194 3083 -41325312.23988 +3195 3083 4621710.431164 +3196 3083 31258602.46674 +3197 3083 -64241069.11092 +3084 3084 503203712.7044 +3085 3084 1.287460327148e-05 +3086 3084 4571811.315658 +3087 3084 55651374.03849 +3088 3084 12499999.99794 +3089 3084 -3143071.475793 +3171 3084 -25195798.91083 +3172 3084 15625000.00513 +3173 3084 8536049.989829 +3174 3084 -89115968.74764 +3175 3084 -2.875924110413e-06 +3176 3084 60031786.74372 +3177 3084 -36905217.31746 +3178 3084 -15625000.00514 +3179 3084 21394122.91072 +3192 3084 11659548.6024 +3193 3084 -3125000.001025 +3194 3084 -1478619.431957 +3195 3084 68618264.38753 +3196 3084 3.814697265625e-06 +3197 3084 -11914911.75127 +3198 3084 -12436480.03947 +3199 3084 3125000.001022 +3200 3084 -4050234.016128 +3085 3085 428199822.2403 +3086 3085 -54860486.40512 +3087 3085 -12499999.99795 +3088 3085 -63098459.89864 +3089 3085 27155937.64705 +3171 3085 15625000.00513 +3172 3085 -20508055.7522 +3173 3085 -8428858.489084 +3174 3085 -4.589557647705e-06 +3175 3085 -20365565.44178 +3176 3085 -6857560.807395 +3177 3085 -15625000.00514 +3178 3085 -32217474.15883 +3179 3085 15286419.29648 +3192 3085 3125000.001029 +3193 3085 -18027909.8965 +3194 3085 -17543480.85857 +3195 3085 2.026557922363e-06 +3196 3085 49867291.76226 +3197 3085 -13715121.60804 +3198 3085 -3125000.001031 +3199 3085 -42123938.53837 +3200 3085 31258602.46661 +3086 3086 444647165.2272 +3087 3086 7143386.85585 +3088 3086 27704548.75807 +3089 3086 24095174.80784 +3171 3086 8536049.989829 +3172 3086 -8428858.489084 +3173 3086 -11111959.41625 +3174 3086 59688904.7995 +3175 3086 -6857560.807395 +3176 3086 -63334663.40088 +3177 3086 21394122.91072 +3178 3086 15286419.29648 +3179 3086 -42337075.16724 +3192 3086 2050095.846979 +3193 3086 -17543480.85871 +3194 3086 15007.26739907 +3195 3086 12486407.68916 +3196 3086 -13715121.60804 +3197 3086 -41325312.23988 +3198 3086 4621710.431164 +3199 3086 31258602.46674 +3200 3086 -64241069.11092 +3087 3087 503203712.7044 +3088 3087 1.287460327148e-05 +3089 3087 4571811.315658 +3090 3087 55651374.03849 +3091 3087 12499999.99794 +3092 3087 -3143071.475793 +3174 3087 -25195798.91083 +3175 3087 15625000.00513 +3176 3087 8536049.989829 +3177 3087 -89115968.74764 +3178 3087 -2.875924110413e-06 +3179 3087 60031786.74372 +3180 3087 -36905217.31746 +3181 3087 -15625000.00514 +3182 3087 21394122.91072 +3195 3087 11659548.6024 +3196 3087 -3125000.001025 +3197 3087 -1478619.431957 +3198 3087 68618264.38753 +3199 3087 3.814697265625e-06 +3200 3087 -11914911.75127 +3201 3087 -12436480.03947 +3202 3087 3125000.001022 +3203 3087 -4050234.016128 +3088 3088 428199822.2403 +3089 3088 -54860486.40512 +3090 3088 -12499999.99795 +3091 3088 -63098459.89864 +3092 3088 27155937.64705 +3174 3088 15625000.00513 +3175 3088 -20508055.7522 +3176 3088 -8428858.489084 +3177 3088 -4.589557647705e-06 +3178 3088 -20365565.44178 +3179 3088 -6857560.807395 +3180 3088 -15625000.00514 +3181 3088 -32217474.15883 +3182 3088 15286419.29648 +3195 3088 3125000.001029 +3196 3088 -18027909.8965 +3197 3088 -17543480.85857 +3198 3088 2.026557922363e-06 +3199 3088 49867291.76226 +3200 3088 -13715121.60804 +3201 3088 -3125000.001031 +3202 3088 -42123938.53837 +3203 3088 31258602.46661 +3089 3089 444647165.2272 +3090 3089 7143386.85585 +3091 3089 27704548.75807 +3092 3089 24095174.80784 +3174 3089 8536049.989829 +3175 3089 -8428858.489084 +3176 3089 -11111959.41625 +3177 3089 59688904.7995 +3178 3089 -6857560.807395 +3179 3089 -63334663.40088 +3180 3089 21394122.91072 +3181 3089 15286419.29648 +3182 3089 -42337075.16724 +3195 3089 2050095.846979 +3196 3089 -17543480.85871 +3197 3089 15007.26739907 +3198 3089 12486407.68916 +3199 3089 -13715121.60804 +3200 3089 -41325312.23988 +3201 3089 4621710.431164 +3202 3089 31258602.46674 +3203 3089 -64241069.11092 +3090 3090 503203712.7044 +3091 3090 1.287460327148e-05 +3092 3090 4571811.315658 +3093 3090 55651374.03849 +3094 3090 12499999.99794 +3095 3090 -3143071.475793 +3177 3090 -25195798.91083 +3178 3090 15625000.00513 +3179 3090 8536049.989829 +3180 3090 -89115968.74764 +3181 3090 -2.875924110413e-06 +3182 3090 60031786.74372 +3183 3090 -36905217.31746 +3184 3090 -15625000.00514 +3185 3090 21394122.91072 +3198 3090 11659548.6024 +3199 3090 -3125000.001025 +3200 3090 -1478619.431957 +3201 3090 68618264.38753 +3202 3090 3.814697265625e-06 +3203 3090 -11914911.75127 +3204 3090 -12436480.03947 +3205 3090 3125000.001022 +3206 3090 -4050234.016128 +3091 3091 428199822.2403 +3092 3091 -54860486.40512 +3093 3091 -12499999.99795 +3094 3091 -63098459.89864 +3095 3091 27155937.64705 +3177 3091 15625000.00513 +3178 3091 -20508055.7522 +3179 3091 -8428858.489084 +3180 3091 -4.589557647705e-06 +3181 3091 -20365565.44178 +3182 3091 -6857560.807395 +3183 3091 -15625000.00514 +3184 3091 -32217474.15883 +3185 3091 15286419.29648 +3198 3091 3125000.001029 +3199 3091 -18027909.8965 +3200 3091 -17543480.85857 +3201 3091 2.026557922363e-06 +3202 3091 49867291.76226 +3203 3091 -13715121.60804 +3204 3091 -3125000.001031 +3205 3091 -42123938.53837 +3206 3091 31258602.46661 +3092 3092 444647165.2272 +3093 3092 7143386.85585 +3094 3092 27704548.75807 +3095 3092 24095174.80784 +3177 3092 8536049.989829 +3178 3092 -8428858.489084 +3179 3092 -11111959.41625 +3180 3092 59688904.7995 +3181 3092 -6857560.807395 +3182 3092 -63334663.40088 +3183 3092 21394122.91072 +3184 3092 15286419.29648 +3185 3092 -42337075.16724 +3198 3092 2050095.846979 +3199 3092 -17543480.85871 +3200 3092 15007.26739907 +3201 3092 12486407.68916 +3202 3092 -13715121.60804 +3203 3092 -41325312.23988 +3204 3092 4621710.431164 +3205 3092 31258602.46674 +3206 3092 -64241069.11092 +3093 3093 503203712.7044 +3094 3093 1.287460327148e-05 +3095 3093 4571811.315658 +3096 3093 55651374.03849 +3097 3093 12499999.99794 +3098 3093 -3143071.475793 +3180 3093 -25195798.91083 +3181 3093 15625000.00513 +3182 3093 8536049.989829 +3183 3093 -89115968.74764 +3184 3093 -2.875924110413e-06 +3185 3093 60031786.74372 +3186 3093 -36905217.31746 +3187 3093 -15625000.00514 +3188 3093 21394122.91072 +3201 3093 11659548.6024 +3202 3093 -3125000.001025 +3203 3093 -1478619.431957 +3204 3093 68618264.38753 +3205 3093 3.814697265625e-06 +3206 3093 -11914911.75127 +3207 3093 -12436480.03947 +3208 3093 3125000.001022 +3209 3093 -4050234.016128 +3094 3094 428199822.2403 +3095 3094 -54860486.40512 +3096 3094 -12499999.99795 +3097 3094 -63098459.89864 +3098 3094 27155937.64705 +3180 3094 15625000.00513 +3181 3094 -20508055.7522 +3182 3094 -8428858.489084 +3183 3094 -4.589557647705e-06 +3184 3094 -20365565.44178 +3185 3094 -6857560.807395 +3186 3094 -15625000.00514 +3187 3094 -32217474.15883 +3188 3094 15286419.29648 +3201 3094 3125000.001029 +3202 3094 -18027909.8965 +3203 3094 -17543480.85857 +3204 3094 2.026557922363e-06 +3205 3094 49867291.76226 +3206 3094 -13715121.60804 +3207 3094 -3125000.001031 +3208 3094 -42123938.53837 +3209 3094 31258602.46661 +3095 3095 444647165.2272 +3096 3095 7143386.85585 +3097 3095 27704548.75807 +3098 3095 24095174.80784 +3180 3095 8536049.989829 +3181 3095 -8428858.489084 +3182 3095 -11111959.41625 +3183 3095 59688904.7995 +3184 3095 -6857560.807395 +3185 3095 -63334663.40088 +3186 3095 21394122.91072 +3187 3095 15286419.29648 +3188 3095 -42337075.16724 +3201 3095 2050095.846979 +3202 3095 -17543480.85871 +3203 3095 15007.26739907 +3204 3095 12486407.68916 +3205 3095 -13715121.60804 +3206 3095 -41325312.23988 +3207 3095 4621710.431164 +3208 3095 31258602.46674 +3209 3095 -64241069.11092 +3096 3096 492641702.9103 +3097 3096 783851.8819454 +3098 3096 23124528.25251 +3099 3096 35525755.89285 +3100 3096 -8589427.098965 +3101 3096 875956.4485927 +3183 3096 -25195798.91083 +3184 3096 15625000.00513 +3185 3096 8536049.989829 +3186 3096 -80462204.18944 +3187 3096 4387679.506916 +3188 3096 55975129.38452 +3189 3096 -33628141.01288 +3190 3096 -15470023.52969 +3191 3096 17035465.07834 +3204 3096 11659548.6024 +3205 3096 -3125000.001025 +3206 3096 -1478619.431957 +3207 3096 63165885.37219 +3208 3096 154956.7695463 +3209 3096 -7186249.992212 +3210 3096 -9680868.333559 +3211 3096 -1572612.750872 +3212 3096 1692044.416381 +3097 3097 431526412.2217 +3098 3097 -34701568.81617 +3099 3097 -33589427.09486 +3100 3097 -86350313.34311 +3101 3097 5606495.794132 +3183 3097 15625000.00513 +3184 3097 -20508055.7522 +3185 3097 -8428858.489084 +3186 3097 4387679.506913 +3187 3097 -17090896.6139 +3188 3097 -7874910.331907 +3189 3097 -15470023.52969 +3190 3097 -25851107.51693 +3191 3097 13144289.29101 +3204 3097 3125000.001029 +3205 3097 -18027909.8965 +3206 3097 -17543480.85857 +3207 3097 154956.7695445 +3208 3097 47507014.2381 +3209 3097 -8588328.009523 +3210 3097 -7822612.752924 +3211 3097 -40170622.93066 +3212 3097 30937121.7314 +3098 3098 434974977.4793 +3099 3098 2933248.114919 +3100 3098 5606495.794132 +3101 3098 31861370.7746 +3183 3098 8536049.989829 +3184 3098 -8428858.489084 +3185 3098 -11111959.41625 +3186 3098 57689539.10866 +3187 3098 -7600604.775448 +3188 3098 -62286030.28655 +3189 3098 17035465.07834 +3190 3098 13144289.29101 +3191 3098 -29308216.83149 +3204 3098 2050095.846979 +3205 3098 -17543480.85871 +3206 3098 15007.26739907 +3207 3098 17900277.78144 +3208 3098 -8039716.898502 +3209 3098 -51569754.72927 +3210 3098 8649301.362094 +3211 3098 30937121.73073 +3212 3098 -43449921.92941 +3099 3099 471121932.3818 +3100 3099 20233944.24908 +3101 3099 -737926.2288754 +3102 3099 -112418921.8 +3103 3099 -68599790.71768 +3104 3099 878928.1725117 +3105 3099 33580044.0569 +3106 3099 -588932.2563479 +3107 3099 -171624.632228 +3186 3099 -21742707.44264 +3187 3099 14412601.93721 +3188 3099 10306829.79205 +3189 3099 -76324678.84597 +3190 3099 5859266.438326 +3191 3099 63055180.55904 +3207 3099 -4475728.404087 +3208 3099 -7822612.752925 +3209 3099 -7244240.304203 +3210 3099 39577919.69218 +3211 3099 4372212.886619 +3212 3099 -12821762.43463 +3213 3099 -39228723.10362 +3214 3099 -17004714.72989 +3215 3099 20529332.26077 +3216 3099 -12888553.538 +3217 3099 183246.2206558 +3218 3099 1555771.238536 +3100 3100 493722084.1344 +3101 3100 -9026222.936527 +3102 3100 -68599790.71768 +3103 3100 -86928261.36223 +3104 3100 567096.4529154 +3105 3100 -25588932.25224 +3106 3100 -86217512.58703 +3107 3100 1753724.512503 +3186 3100 14412601.93721 +3187 3100 -32236833.91562 +3188 3100 -15509166.55588 +3189 3100 5859266.438325 +3190 3100 -14976844.93733 +3191 3100 -4699928.603619 +3207 3100 -1572612.750872 +3208 3100 -34965483.00119 +3209 3100 -28168781.0366 +3210 3100 4372212.88662 +3211 3100 42956376.60637 +3212 3100 -2191021.741286 +3213 3100 -17004714.72988 +3214 3100 -33047443.13223 +3215 3100 16805961.40619 +3216 3100 -6066753.781397 +3217 3100 -42812243.26214 +3218 3100 33762936.53119 +3101 3101 482504201.0121 +3102 3101 878928.1725112 +3103 3101 567096.4529154 +3104 3101 -22282287.50233 +3105 3101 514139.256546 +3106 3101 1753724.512503 +3107 3101 45122415.38576 +3186 3101 10306829.79205 +3187 3101 -15509166.55588 +3188 3101 -22990102.91187 +3189 3101 63055180.55938 +3190 3101 -4699928.602806 +3191 3101 -80763672.5181 +3207 3101 -1315629.191991 +3208 3101 -28168781.03741 +3209 3101 -29569548.78415 +3210 3101 12533862.5612 +3211 3101 -2191021.741286 +3212 3101 -89714782.17938 +3213 3101 20529332.26077 +3214 3101 16805961.40619 +3215 3101 -36543474.64868 +3216 3101 7962090.685931 +3217 3101 33762936.53119 +3218 3101 -47305010.00354 +3102 3102 275061856.1274 +3103 3102 73810230.63521 +3104 3102 -487105.8403563 +3105 3102 -85928078.14503 +3106 3102 -6400209.270002 +3107 3102 -307458.2653014 +3189 3102 -7426816.19884 +3190 3102 547894.8851027 +3191 3102 -686306.8063924 +3210 3102 -38680111.99234 +3211 3102 -17004714.72989 +3212 3102 -20095667.75257 +3213 3102 19662816.22848 +3214 3102 18202105.12106 +3215 3102 8005635.510344 +3216 3102 -44958888.03514 +3217 3102 -1745285.276274 +3218 3102 -35973660.95138 +3103 3103 244299704.588 +3104 3103 -514661.2980397 +3105 3103 18599790.72589 +3106 3103 40925011.39215 +3107 3103 -567096.4529139 +3189 3103 -5702105.11695 +3190 3103 -37809826.28199 +3191 3103 -33205757.59528 +3210 3103 -17004714.72989 +3211 3103 -32498832.02095 +3212 3103 -16527371.93809 +3213 3103 18202105.12106 +3214 3103 11959888.79912 +3215 3103 6539090.93299 +3216 3103 4504714.725779 +3217 3103 -13054230.49401 +3218 3103 3194038.600379 +3104 3104 279394070.5498 +3105 3104 -307458.2652981 +3106 3104 -567096.4529139 +3107 3104 51950704.22376 +3189 3104 -8811306.808046 +3190 3104 -33205757.59528 +3191 3104 -46386833.74737 +3210 3104 -20095667.75257 +3211 3104 -16527371.93809 +3212 3104 -35080511.68526 +3213 3104 -8244364.486988 +3214 3104 -6794242.398153 +3215 3104 -60632270.38613 +3216 3104 -35973660.9524 +3217 3104 -3472628.068476 +3218 3104 -48308384.17547 +3105 3105 232532080.9027 +3106 3105 -49411067.73544 +3107 3105 -742727.2202297 +3189 3105 -24504200.52935 +3190 3105 14245285.28038 +3191 3105 15375426.00908 +3210 3105 -11242720.20522 +3211 3105 -6066753.781398 +3212 3105 -7723395.426606 +3213 3105 -44958888.03514 +3214 3105 4504714.725781 +3215 3105 35825731.39786 +3216 3105 15899808.76754 +3217 3105 -12683246.22476 +3218 3105 -6411373.091219 +3106 3106 238640184.4403 +3107 3106 -1753724.512498 +3189 3106 14245285.28038 +3190 3106 -27182865.22233 +3191 3106 -16527371.93809 +3210 3106 183246.2206552 +3211 3106 -41166409.92937 +3212 3106 -32903730.12452 +3213 3106 -1745285.276272 +3214 3106 -13054230.49401 +3215 3106 3194038.60038 +3216 3106 -12683246.22476 +3217 3106 16597505.64354 +3218 3106 6237063.462234 +3107 3107 247648589.7832 +3189 3107 15375426.00909 +3190 3107 -16527371.93809 +3191 3107 -29764544.88664 +3210 3107 -1659957.923597 +3211 3107 -32903730.12452 +3212 3107 -42916121.11612 +3213 3107 35825731.39701 +3214 3107 -3472628.068476 +3215 3107 -48308384.17547 +3216 3107 6058383.851178 +3217 3107 -7096269.868909 +3218 3107 -51826949.82756 +3108 3108 648741877.3649 +3109 3108 62499999.98976 +3110 3108 33168324.30835 +3111 3108 -355476071.9436 +3112 3108 -62523716.6258 +3113 3108 -27673319.58105 +3114 3108 5797712.423909 +3115 3108 50023716.62785 +3116 3108 -19897668.89224 +3219 3108 76701211.16396 +3220 3108 15625000.00514 +3221 3108 21009550.22758 +3222 3108 -125983237.2565 +3223 3108 -15630322.06463 +3224 3108 -74621947.50591 +3225 3108 -24799837.07904 +3226 3108 12505322.06361 +3227 3108 -18723479.73292 +3109 3109 554960584.1326 +3110 3109 -63110559.55319 +3111 3109 -62535574.94383 +3112 3109 -61649505.13883 +3113 3109 -38276277.82281 +3114 3109 75035574.94178 +3115 3109 5797712.423912 +3116 3109 25521217.55499 +3219 3109 15625000.00514 +3220 3109 53256630.69937 +3221 3109 -5602780.460976 +3222 3109 -15632983.09438 +3223 3109 -52528524.54163 +3224 3109 -23113573.91808 +3225 3109 18757983.09541 +3226 3109 -24799837.07904 +3227 3109 22467775.67917 +3110 3110 608122864.0228 +3111 3110 -24925817.21738 +3112 3110 -30317816.4155 +3113 3110 -26125989.8053 +3114 3110 -29846503.33835 +3115 3110 17014145.03666 +3116 3110 15460566.46375 +3219 3110 -6140600.947398 +3220 3110 -27322678.94813 +3221 3110 -75919024.90121 +3222 3110 -74277994.97009 +3223 3110 -21190287.58241 +3224 3110 -105509843.5958 +3225 3110 -28085219.59939 +3226 3110 14978517.11945 +3227 3110 -66132898.87745 +3111 3111 1110223097.916 +3112 3111 62559291.5799 +3113 3111 30860259.9917 +3114 3111 12838043.85587 +3115 3111 -62523716.6258 +3116 3111 27041055.07434 +3117 3111 -244029558.4996 +3118 3111 2.473592758179e-06 +3119 3111 -5943336.391493 +3120 3111 -96781952.40796 +3121 3111 62499999.98974 +3122 3111 -27030538.9556 +3219 3111 -111681734.2619 +3220 3111 -15632983.09438 +3221 3111 61472760.90482 +3222 3111 149252626.5636 +3223 3111 15638305.15389 +3224 3111 7711980.245565 +3225 3111 -47230742.81426 +3226 3111 -15630322.06464 +3227 3111 23688071.7797 +3228 3111 -97033826.33989 +3229 3111 1.400709152222e-06 +3230 3111 -69175329.97466 +3231 3111 -39900479.57507 +3232 3111 15625000.00513 +3233 3111 -23680008.71958 +3112 3112 941438116.1313 +3113 3112 -85033165.29872 +3114 3112 -62535574.94383 +3115 3112 -205958151.8641 +3116 3112 46639478.37137 +3117 3112 4.053115844727e-06 +3118 3112 30971970.86735 +3119 3112 -27430259.42623 +3120 3112 62499999.98974 +3121 3112 -78031030.26054 +3122 3112 15223810.26862 +3219 3112 -15630322.06464 +3220 3112 -38227021.54706 +3221 3112 5963051.430523 +3222 3112 15638305.15389 +3223 3112 107057171.8061 +3224 3112 -21260770.12636 +3225 3112 -15632983.09439 +3226 3112 -101928593.64 +3227 3112 65822290.07648 +3228 3112 7.450580596924e-07 +3229 3112 -28283463.80681 +3230 3112 -6857568.701869 +3231 3112 15625000.00513 +3232 3112 -35212760.99956 +3233 3112 17343714.91106 +3113 3113 941510422.8134 +3114 3113 26703431.18881 +3115 3113 52129838.76531 +3116 3113 9972799.741074 +3117 3113 -3200280.836388 +3118 3113 -27430259.42623 +3119 3113 46485699.20007 +3120 3113 -26687657.01071 +3121 3113 14949504.71271 +3122 3113 -33777948.97413 +3219 3113 61128808.369 +3220 3113 4044385.985747 +3221 3113 -67372502.27695 +3222 3113 7717756.425008 +3223 3113 -21256149.23011 +3224 3113 -106755752.9646 +3225 3113 23692103.30976 +3226 3113 67469018.6918 +3227 3113 -132015307.5643 +3228 3113 -68832448.03044 +3229 3113 -6857568.701869 +3230 3113 -84449189.35104 +3231 3113 -23680008.71958 +3232 3113 17343714.91106 +3233 3113 -50324486.557 +3114 3114 648741877.3649 +3115 3114 62499999.98976 +3116 3114 33168324.30835 +3117 3114 -95427568.72765 +3118 3114 -62499999.98975 +3119 3114 24401752.70261 +3120 3114 -355476071.9436 +3121 3114 -62523716.6258 +3122 3114 -27673319.58105 +3123 3114 5797712.423909 +3124 3114 50023716.62785 +3125 3114 -19897668.89224 +3219 3114 2016499.187392 +3220 3114 18757983.09541 +3221 3114 12648670.74487 +3222 3114 -6124104.06778 +3223 3114 -15632983.09438 +3224 3114 -10255693.28227 +3225 3114 76701211.16396 +3226 3114 15625000.00514 +3227 3114 21009550.22758 +3228 3114 -26159485.64696 +3229 3114 -15625000.00513 +3230 3114 -10821935.79869 +3231 3114 -125983237.2565 +3232 3114 -15630322.06463 +3233 3114 -74621947.50591 +3234 3114 -24799837.07904 +3235 3114 12505322.06361 +3236 3114 -18723479.73292 +3115 3115 554960584.1326 +3116 3115 -63110559.55319 +3117 3115 -62499999.98975 +3118 3115 -76676646.58022 +3119 3115 12206449.1576 +3120 3115 -62535574.94383 +3121 3115 -61649505.13883 +3122 3115 -38276277.82281 +3123 3115 75035574.94178 +3124 3115 5797712.423912 +3125 3115 25521217.55499 +3219 3115 12505322.06361 +3220 3115 2016499.187392 +3221 3115 -6746002.447256 +3222 3115 -15630322.06463 +3223 3115 -60821954.89356 +3224 3115 -41130474.11058 +3225 3115 15625000.00514 +3226 3115 53256630.69937 +3227 3115 -5602780.460976 +3228 3115 -15625000.00513 +3229 3115 -21471767.07144 +3230 3115 -10486146.20919 +3231 3115 -15632983.09438 +3232 3115 -52528524.54163 +3233 3115 -23113573.91808 +3234 3115 18757983.09541 +3235 3115 -24799837.07904 +3236 3115 22467775.67917 +3116 3116 608122864.0228 +3117 3116 24744634.64751 +3118 3116 12480754.71352 +3119 3116 -30166259.15992 +3120 3116 -24925817.21738 +3121 3116 -30317816.4155 +3122 3116 -26125989.8053 +3123 3116 -29846503.33835 +3124 3116 17014145.03666 +3125 3116 15460566.46375 +3219 3116 8432447.163244 +3220 3116 -10119003.67088 +3221 3116 5377331.166378 +3222 3116 -10253948.8687 +3223 3116 -42777202.9092 +3224 3116 -22397604.24035 +3225 3116 -6140600.947398 +3226 3116 -27322678.94813 +3227 3116 -75919024.90121 +3228 3116 -10821935.79869 +3229 3116 -10486146.20919 +3230 3116 -13681836.08202 +3231 3116 -74277994.97009 +3232 3116 -21190287.58241 +3233 3116 -105509843.5958 +3234 3116 -28085219.59939 +3235 3116 14978517.11945 +3236 3116 -66132898.87745 +3117 3117 1024746089.754 +3118 3117 2.086162567139e-05 +3119 3117 9143617.227815 +3120 3117 115751892.8599 +3121 3117 -9.417533874512e-06 +3122 3117 2285904.308086 +3126 3117 -244029558.4996 +3127 3117 2.473592758179e-06 +3128 3117 -5943336.391493 +3129 3117 -96781952.40796 +3130 3117 62499999.98974 +3131 3117 -27030538.9556 +3222 3117 -93459816.96553 +3223 3117 1.579523086548e-06 +3224 3117 66889426.94725 +3225 3117 -38668381.31079 +3226 3117 -15625000.00514 +3227 3117 23108532.96245 +3228 3117 119183368.3243 +3229 3117 4.112720489502e-06 +3230 3117 2285903.027438 +3231 3117 -32106344.47651 +3232 3117 -9.387731552124e-06 +3233 3117 571475.757148 +3237 3117 -97033826.33989 +3238 3117 1.400709152222e-06 +3239 3117 -69175329.97466 +3240 3117 -39900479.57507 +3241 3117 15625000.00513 +3242 3117 -23680008.71958 +3118 3118 874738712.6486 +3119 3118 -109721037.6509 +3120 3118 -1.046061515808e-05 +3121 3118 -121747792.2491 +3122 3118 55957741.04746 +3126 3118 4.053115844727e-06 +3127 3118 30971970.86735 +3128 3118 -27430259.42623 +3129 3118 62499999.98974 +3130 3118 -78031030.26054 +3131 3118 15223810.26862 +3222 3118 -6.705522537231e-07 +3223 3118 -24709454.43242 +3224 3118 -6857568.701869 +3225 3118 -15625000.00514 +3226 3118 -33980662.73527 +3227 3118 16657951.02195 +3228 3118 4.053115844727e-06 +3229 3118 81681619.73861 +3230 3118 -27430274.79396 +3231 3118 -8.40425491333e-06 +3232 3118 -91481269.86781 +3233 3118 68140484.61019 +3237 3118 7.450580596924e-07 +3238 3118 -28283463.80681 +3239 3118 -6857568.701869 +3240 3118 15625000.00513 +3241 3118 -35212760.99956 +3242 3118 17343714.91106 +3119 3119 938198180.6514 +3120 3119 2285904.308086 +3121 3119 53763296.60338 +3122 3119 60055040.21296 +3126 3119 -3200280.836388 +3127 3119 -27430259.42623 +3128 3119 46485699.20007 +3129 3119 -26687657.01071 +3130 3119 14949504.71271 +3131 3119 -33777948.97413 +3222 3119 66546545.00303 +3223 3119 -6857568.701869 +3224 3119 -74918497.68596 +3225 3119 23108532.96245 +3226 3119 16657951.02195 +3227 3119 -47038891.18556 +3228 3119 2285903.027438 +3229 3119 -27430274.79396 +3230 3119 -130792022.7266 +3231 3119 571475.7571481 +3232 3119 67866179.05482 +3233 3119 -147771014.9835 +3237 3119 -68832448.03044 +3238 3119 -6857568.701869 +3239 3119 -84449189.35104 +3240 3119 -23680008.71958 +3241 3119 17343714.91106 +3242 3119 -50324486.557 +3120 3120 1110223097.916 +3121 3120 62559291.5799 +3122 3120 30860259.9917 +3123 3120 12838043.85587 +3124 3120 -62523716.6258 +3125 3120 27041055.07434 +3126 3120 -95427568.72765 +3127 3120 -62499999.98975 +3128 3120 24401752.70261 +3129 3120 -244029558.4996 +3130 3120 2.473592758179e-06 +3131 3120 -5943336.391493 +3132 3120 -96781952.40796 +3133 3120 62499999.98974 +3134 3120 -27030538.9556 +3222 3120 -25604579.22317 +3223 3120 15625000.00514 +3224 3120 10250460.04156 +3225 3120 -111681734.2619 +3226 3120 -15632983.09438 +3227 3120 61472760.90482 +3228 3120 21503247.52855 +3229 3120 3.844499588013e-06 +3230 3120 571475.7571353 +3231 3120 149252626.5636 +3232 3120 15638305.15389 +3233 3120 7711980.245565 +3234 3120 -47230742.81426 +3235 3120 -15630322.06464 +3236 3120 23688071.7797 +3237 3120 -26159485.64696 +3238 3120 -15625000.00513 +3239 3120 -10821935.79869 +3240 3120 -97033826.33989 +3241 3120 1.400709152222e-06 +3242 3120 -69175329.97466 +3243 3120 -39900479.57507 +3244 3120 15625000.00513 +3245 3120 -23680008.71958 +3121 3121 941438116.1313 +3122 3121 -85033165.29872 +3123 3121 -62535574.94383 +3124 3121 -205958151.8641 +3125 3121 46639478.37137 +3126 3121 -62499999.98975 +3127 3121 -76676646.58022 +3128 3121 12206449.1576 +3129 3121 4.053115844727e-06 +3130 3121 30971970.86735 +3131 3121 -27430259.42623 +3132 3121 62499999.98974 +3133 3121 -78031030.26054 +3134 3121 15223810.26862 +3222 3121 15625000.00514 +3223 3121 -20916860.64765 +3224 3121 -9800382.320076 +3225 3121 -15630322.06464 +3226 3121 -38227021.54706 +3227 3121 5963051.430523 +3228 3121 5.88595867157e-06 +3229 3121 -37871677.86274 +3230 3121 -40710209.81623 +3231 3121 15638305.15389 +3232 3121 107057171.8061 +3233 3121 -21260770.12636 +3234 3121 -15632983.09439 +3235 3121 -101928593.64 +3236 3121 65822290.07648 +3237 3121 -15625000.00513 +3238 3121 -21471767.07144 +3239 3121 -10486146.20919 +3240 3121 7.450580596924e-07 +3241 3121 -28283463.80681 +3242 3121 -6857568.701869 +3243 3121 15625000.00513 +3244 3121 -35212760.99956 +3245 3121 17343714.91106 +3122 3122 941510422.8134 +3123 3122 26703431.18881 +3124 3122 52129838.76531 +3125 3122 9972799.741074 +3126 3122 24744634.64751 +3127 3122 12480754.71352 +3128 3122 -30166259.15992 +3129 3122 -3200280.836388 +3130 3122 -27430259.42623 +3131 3122 46485699.20007 +3132 3122 -26687657.01071 +3133 3122 14949504.71271 +3134 3122 -33777948.97413 +3222 3122 10250460.04156 +3223 3122 -9800382.320076 +3224 3122 -12202085.61857 +3225 3122 61128808.369 +3226 3122 4044385.985747 +3227 3122 -67372502.27695 +3228 3122 571475.7571355 +3229 3122 -40435904.26086 +3230 3122 -4812102.970013 +3231 3122 7717756.425008 +3232 3122 -21256149.23011 +3233 3122 -106755752.9646 +3234 3122 23692103.30976 +3235 3122 67469018.6918 +3236 3122 -132015307.5643 +3237 3122 -10821935.79869 +3238 3122 -10486146.20919 +3239 3122 -13681836.08202 +3240 3122 -68832448.03044 +3241 3122 -6857568.701869 +3242 3122 -84449189.35104 +3243 3122 -23680008.71958 +3244 3122 17343714.91106 +3245 3122 -50324486.557 +3123 3123 648741877.3649 +3124 3123 62499999.98976 +3125 3123 33168324.30835 +3129 3123 -95427568.72765 +3130 3123 -62499999.98975 +3131 3123 24401752.70261 +3132 3123 -355476071.9436 +3133 3123 -62523716.6258 +3134 3123 -27673319.58105 +3135 3123 5797712.423909 +3136 3123 50023716.62785 +3137 3123 -19897668.89224 +3225 3123 2016499.187392 +3226 3123 18757983.09541 +3227 3123 12648670.74487 +3231 3123 -6124104.06778 +3232 3123 -15632983.09438 +3233 3123 -10255693.28227 +3234 3123 76701211.16396 +3235 3123 15625000.00514 +3236 3123 21009550.22758 +3240 3123 -26159485.64696 +3241 3123 -15625000.00513 +3242 3123 -10821935.79869 +3243 3123 -125983237.2565 +3244 3123 -15630322.06463 +3245 3123 -74621947.50591 +3246 3123 -24799837.07904 +3247 3123 12505322.06361 +3248 3123 -18723479.73292 +3124 3124 554960584.1326 +3125 3124 -63110559.55319 +3129 3124 -62499999.98975 +3130 3124 -76676646.58022 +3131 3124 12206449.1576 +3132 3124 -62535574.94383 +3133 3124 -61649505.13883 +3134 3124 -38276277.82281 +3135 3124 75035574.94178 +3136 3124 5797712.423912 +3137 3124 25521217.55499 +3225 3124 12505322.06361 +3226 3124 2016499.187392 +3227 3124 -6746002.447256 +3231 3124 -15630322.06463 +3232 3124 -60821954.89356 +3233 3124 -41130474.11058 +3234 3124 15625000.00514 +3235 3124 53256630.69937 +3236 3124 -5602780.460976 +3240 3124 -15625000.00513 +3241 3124 -21471767.07144 +3242 3124 -10486146.20919 +3243 3124 -15632983.09438 +3244 3124 -52528524.54163 +3245 3124 -23113573.91808 +3246 3124 18757983.09541 +3247 3124 -24799837.07904 +3248 3124 22467775.67917 +3125 3125 608122864.0228 +3129 3125 24744634.64751 +3130 3125 12480754.71352 +3131 3125 -30166259.15992 +3132 3125 -24925817.21738 +3133 3125 -30317816.4155 +3134 3125 -26125989.8053 +3135 3125 -29846503.33835 +3136 3125 17014145.03666 +3137 3125 15460566.46375 +3225 3125 8432447.163244 +3226 3125 -10119003.67088 +3227 3125 5377331.166378 +3231 3125 -10253948.8687 +3232 3125 -42777202.9092 +3233 3125 -22397604.24035 +3234 3125 -6140600.947398 +3235 3125 -27322678.94813 +3236 3125 -75919024.90121 +3240 3125 -10821935.79869 +3241 3125 -10486146.20919 +3242 3125 -13681836.08202 +3243 3125 -74277994.97009 +3244 3125 -21190287.58241 +3245 3125 -105509843.5958 +3246 3125 -28085219.59939 +3247 3125 14978517.11945 +3248 3125 -66132898.87745 +3126 3126 1024746089.754 +3127 3126 2.086162567139e-05 +3128 3126 9143617.227815 +3129 3126 115751892.8599 +3130 3126 -9.417533874512e-06 +3131 3126 2285904.308086 +3138 3126 -244029558.4996 +3139 3126 2.473592758179e-06 +3140 3126 -5943336.391493 +3141 3126 -96781952.40796 +3142 3126 62499999.98974 +3143 3126 -27030538.9556 +3228 3126 -93459816.96553 +3229 3126 1.579523086548e-06 +3230 3126 66889426.94725 +3231 3126 -38668381.31079 +3232 3126 -15625000.00514 +3233 3126 23108532.96245 +3237 3126 119183368.3243 +3238 3126 4.112720489502e-06 +3239 3126 2285903.027438 +3240 3126 -32106344.47651 +3241 3126 -9.387731552124e-06 +3242 3126 571475.757148 +3249 3126 -97033826.33989 +3250 3126 1.400709152222e-06 +3251 3126 -69175329.97466 +3252 3126 -39900479.57507 +3253 3126 15625000.00513 +3254 3126 -23680008.71958 +3127 3127 874738712.6486 +3128 3127 -109721037.6509 +3129 3127 -1.046061515808e-05 +3130 3127 -121747792.2491 +3131 3127 55957741.04746 +3138 3127 4.053115844727e-06 +3139 3127 30971970.86735 +3140 3127 -27430259.42623 +3141 3127 62499999.98974 +3142 3127 -78031030.26054 +3143 3127 15223810.26862 +3228 3127 -6.705522537231e-07 +3229 3127 -24709454.43242 +3230 3127 -6857568.701869 +3231 3127 -15625000.00514 +3232 3127 -33980662.73527 +3233 3127 16657951.02195 +3237 3127 4.053115844727e-06 +3238 3127 81681619.73861 +3239 3127 -27430274.79396 +3240 3127 -8.40425491333e-06 +3241 3127 -91481269.86781 +3242 3127 68140484.61019 +3249 3127 7.450580596924e-07 +3250 3127 -28283463.80681 +3251 3127 -6857568.701869 +3252 3127 15625000.00513 +3253 3127 -35212760.99956 +3254 3127 17343714.91106 +3128 3128 938198180.6514 +3129 3128 2285904.308086 +3130 3128 53763296.60338 +3131 3128 60055040.21296 +3138 3128 -3200280.836388 +3139 3128 -27430259.42623 +3140 3128 46485699.20007 +3141 3128 -26687657.01071 +3142 3128 14949504.71271 +3143 3128 -33777948.97413 +3228 3128 66546545.00303 +3229 3128 -6857568.701869 +3230 3128 -74918497.68596 +3231 3128 23108532.96245 +3232 3128 16657951.02195 +3233 3128 -47038891.18556 +3237 3128 2285903.027438 +3238 3128 -27430274.79396 +3239 3128 -130792022.7266 +3240 3128 571475.7571481 +3241 3128 67866179.05482 +3242 3128 -147771014.9835 +3249 3128 -68832448.03044 +3250 3128 -6857568.701869 +3251 3128 -84449189.35104 +3252 3128 -23680008.71958 +3253 3128 17343714.91106 +3254 3128 -50324486.557 +3129 3129 1024746089.754 +3130 3129 2.086162567139e-05 +3131 3129 9143617.227815 +3132 3129 115751892.8599 +3133 3129 -9.417533874512e-06 +3134 3129 2285904.308086 +3138 3129 -95427568.72765 +3139 3129 -62499999.98975 +3140 3129 24401752.70261 +3141 3129 -244029558.4996 +3142 3129 2.473592758179e-06 +3143 3129 -5943336.391493 +3144 3129 -96781952.40796 +3145 3129 62499999.98974 +3146 3129 -27030538.9556 +3228 3129 -25604579.22317 +3229 3129 15625000.00514 +3230 3129 10250460.04156 +3231 3129 -93459816.96553 +3232 3129 1.579523086548e-06 +3233 3129 66889426.94725 +3234 3129 -38668381.31079 +3235 3129 -15625000.00514 +3236 3129 23108532.96245 +3237 3129 21503247.52855 +3238 3129 3.844499588013e-06 +3239 3129 571475.7571353 +3240 3129 119183368.3243 +3241 3129 4.112720489502e-06 +3242 3129 2285903.027438 +3243 3129 -32106344.47651 +3244 3129 -9.387731552124e-06 +3245 3129 571475.757148 +3249 3129 -26159485.64696 +3250 3129 -15625000.00513 +3251 3129 -10821935.79869 +3252 3129 -97033826.33989 +3253 3129 1.400709152222e-06 +3254 3129 -69175329.97466 +3255 3129 -39900479.57507 +3256 3129 15625000.00513 +3257 3129 -23680008.71958 +3130 3130 874738712.6486 +3131 3130 -109721037.6509 +3132 3130 -1.046061515808e-05 +3133 3130 -121747792.2491 +3134 3130 55957741.04746 +3138 3130 -62499999.98975 +3139 3130 -76676646.58022 +3140 3130 12206449.1576 +3141 3130 4.053115844727e-06 +3142 3130 30971970.86735 +3143 3130 -27430259.42623 +3144 3130 62499999.98974 +3145 3130 -78031030.26054 +3146 3130 15223810.26862 +3228 3130 15625000.00514 +3229 3130 -20916860.64765 +3230 3130 -9800382.320076 +3231 3130 -6.705522537231e-07 +3232 3130 -24709454.43242 +3233 3130 -6857568.701869 +3234 3130 -15625000.00514 +3235 3130 -33980662.73527 +3236 3130 16657951.02195 +3237 3130 5.88595867157e-06 +3238 3130 -37871677.86274 +3239 3130 -40710209.81623 +3240 3130 4.053115844727e-06 +3241 3130 81681619.73861 +3242 3130 -27430274.79396 +3243 3130 -8.40425491333e-06 +3244 3130 -91481269.86781 +3245 3130 68140484.61019 +3249 3130 -15625000.00513 +3250 3130 -21471767.07144 +3251 3130 -10486146.20919 +3252 3130 7.450580596924e-07 +3253 3130 -28283463.80681 +3254 3130 -6857568.701869 +3255 3130 15625000.00513 +3256 3130 -35212760.99956 +3257 3130 17343714.91106 +3131 3131 938198180.6514 +3132 3131 2285904.308086 +3133 3131 53763296.60338 +3134 3131 60055040.21296 +3138 3131 24744634.64751 +3139 3131 12480754.71352 +3140 3131 -30166259.15992 +3141 3131 -3200280.836388 +3142 3131 -27430259.42623 +3143 3131 46485699.20007 +3144 3131 -26687657.01071 +3145 3131 14949504.71271 +3146 3131 -33777948.97413 +3228 3131 10250460.04156 +3229 3131 -9800382.320076 +3230 3131 -12202085.61857 +3231 3131 66546545.00303 +3232 3131 -6857568.701869 +3233 3131 -74918497.68596 +3234 3131 23108532.96245 +3235 3131 16657951.02195 +3236 3131 -47038891.18556 +3237 3131 571475.7571355 +3238 3131 -40435904.26086 +3239 3131 -4812102.970013 +3240 3131 2285903.027438 +3241 3131 -27430274.79396 +3242 3131 -130792022.7266 +3243 3131 571475.7571481 +3244 3131 67866179.05482 +3245 3131 -147771014.9835 +3249 3131 -10821935.79869 +3250 3131 -10486146.20919 +3251 3131 -13681836.08202 +3252 3131 -68832448.03044 +3253 3131 -6857568.701869 +3254 3131 -84449189.35104 +3255 3131 -23680008.71958 +3256 3131 17343714.91106 +3257 3131 -50324486.557 +3132 3132 1110223097.916 +3133 3132 62559291.5799 +3134 3132 30860259.9917 +3135 3132 12838043.85587 +3136 3132 -62523716.6258 +3137 3132 27041055.07434 +3141 3132 -95427568.72765 +3142 3132 -62499999.98975 +3143 3132 24401752.70261 +3144 3132 -244029558.4996 +3145 3132 2.473592758179e-06 +3146 3132 -5943336.391493 +3147 3132 -96781952.40796 +3148 3132 62499999.98974 +3149 3132 -27030538.9556 +3231 3132 -25604579.22317 +3232 3132 15625000.00514 +3233 3132 10250460.04156 +3234 3132 -111681734.2619 +3235 3132 -15632983.09438 +3236 3132 61472760.90482 +3240 3132 21503247.52855 +3241 3132 3.844499588013e-06 +3242 3132 571475.7571353 +3243 3132 149252626.5636 +3244 3132 15638305.15389 +3245 3132 7711980.245565 +3246 3132 -47230742.81426 +3247 3132 -15630322.06464 +3248 3132 23688071.7797 +3252 3132 -26159485.64696 +3253 3132 -15625000.00513 +3254 3132 -10821935.79869 +3255 3132 -97033826.33989 +3256 3132 1.400709152222e-06 +3257 3132 -69175329.97466 +3258 3132 -39900479.57507 +3259 3132 15625000.00513 +3260 3132 -23680008.71958 +3133 3133 941438116.1313 +3134 3133 -85033165.29872 +3135 3133 -62535574.94383 +3136 3133 -205958151.8641 +3137 3133 46639478.37137 +3141 3133 -62499999.98975 +3142 3133 -76676646.58022 +3143 3133 12206449.1576 +3144 3133 4.053115844727e-06 +3145 3133 30971970.86735 +3146 3133 -27430259.42623 +3147 3133 62499999.98974 +3148 3133 -78031030.26054 +3149 3133 15223810.26862 +3231 3133 15625000.00514 +3232 3133 -20916860.64765 +3233 3133 -9800382.320076 +3234 3133 -15630322.06464 +3235 3133 -38227021.54706 +3236 3133 5963051.430523 +3240 3133 5.88595867157e-06 +3241 3133 -37871677.86274 +3242 3133 -40710209.81623 +3243 3133 15638305.15389 +3244 3133 107057171.8061 +3245 3133 -21260770.12636 +3246 3133 -15632983.09439 +3247 3133 -101928593.64 +3248 3133 65822290.07648 +3252 3133 -15625000.00513 +3253 3133 -21471767.07144 +3254 3133 -10486146.20919 +3255 3133 7.450580596924e-07 +3256 3133 -28283463.80681 +3257 3133 -6857568.701869 +3258 3133 15625000.00513 +3259 3133 -35212760.99956 +3260 3133 17343714.91106 +3134 3134 941510422.8134 +3135 3134 26703431.18881 +3136 3134 52129838.76531 +3137 3134 9972799.741074 +3141 3134 24744634.64751 +3142 3134 12480754.71352 +3143 3134 -30166259.15992 +3144 3134 -3200280.836388 +3145 3134 -27430259.42623 +3146 3134 46485699.20007 +3147 3134 -26687657.01071 +3148 3134 14949504.71271 +3149 3134 -33777948.97413 +3231 3134 10250460.04156 +3232 3134 -9800382.320076 +3233 3134 -12202085.61857 +3234 3134 61128808.369 +3235 3134 4044385.985747 +3236 3134 -67372502.27695 +3240 3134 571475.7571355 +3241 3134 -40435904.26086 +3242 3134 -4812102.970013 +3243 3134 7717756.425008 +3244 3134 -21256149.23011 +3245 3134 -106755752.9646 +3246 3134 23692103.30976 +3247 3134 67469018.6918 +3248 3134 -132015307.5643 +3252 3134 -10821935.79869 +3253 3134 -10486146.20919 +3254 3134 -13681836.08202 +3255 3134 -68832448.03044 +3256 3134 -6857568.701869 +3257 3134 -84449189.35104 +3258 3134 -23680008.71958 +3259 3134 17343714.91106 +3260 3134 -50324486.557 +3135 3135 648741877.3649 +3136 3135 62499999.98976 +3137 3135 33168324.30835 +3144 3135 -95427568.72765 +3145 3135 -62499999.98975 +3146 3135 24401752.70261 +3147 3135 -355476071.9436 +3148 3135 -62523716.6258 +3149 3135 -27673319.58105 +3150 3135 5797712.423909 +3151 3135 50023716.62785 +3152 3135 -19897668.89224 +3234 3135 2016499.187392 +3235 3135 18757983.09541 +3236 3135 12648670.74487 +3243 3135 -6124104.06778 +3244 3135 -15632983.09438 +3245 3135 -10255693.28227 +3246 3135 76701211.16396 +3247 3135 15625000.00514 +3248 3135 21009550.22758 +3255 3135 -26159485.64696 +3256 3135 -15625000.00513 +3257 3135 -10821935.79869 +3258 3135 -125983237.2565 +3259 3135 -15630322.06463 +3260 3135 -74621947.50591 +3261 3135 -24799837.07904 +3262 3135 12505322.06361 +3263 3135 -18723479.73292 +3136 3136 554960584.1326 +3137 3136 -63110559.55319 +3144 3136 -62499999.98975 +3145 3136 -76676646.58022 +3146 3136 12206449.1576 +3147 3136 -62535574.94383 +3148 3136 -61649505.13883 +3149 3136 -38276277.82281 +3150 3136 75035574.94178 +3151 3136 5797712.423912 +3152 3136 25521217.55499 +3234 3136 12505322.06361 +3235 3136 2016499.187392 +3236 3136 -6746002.447256 +3243 3136 -15630322.06463 +3244 3136 -60821954.89356 +3245 3136 -41130474.11058 +3246 3136 15625000.00514 +3247 3136 53256630.69937 +3248 3136 -5602780.460976 +3255 3136 -15625000.00513 +3256 3136 -21471767.07144 +3257 3136 -10486146.20919 +3258 3136 -15632983.09438 +3259 3136 -52528524.54163 +3260 3136 -23113573.91808 +3261 3136 18757983.09541 +3262 3136 -24799837.07904 +3263 3136 22467775.67917 +3137 3137 608122864.0228 +3144 3137 24744634.64751 +3145 3137 12480754.71352 +3146 3137 -30166259.15992 +3147 3137 -24925817.21738 +3148 3137 -30317816.4155 +3149 3137 -26125989.8053 +3150 3137 -29846503.33835 +3151 3137 17014145.03666 +3152 3137 15460566.46375 +3234 3137 8432447.163244 +3235 3137 -10119003.67088 +3236 3137 5377331.166378 +3243 3137 -10253948.8687 +3244 3137 -42777202.9092 +3245 3137 -22397604.24035 +3246 3137 -6140600.947398 +3247 3137 -27322678.94813 +3248 3137 -75919024.90121 +3255 3137 -10821935.79869 +3256 3137 -10486146.20919 +3257 3137 -13681836.08202 +3258 3137 -74277994.97009 +3259 3137 -21190287.58241 +3260 3137 -105509843.5958 +3261 3137 -28085219.59939 +3262 3137 14978517.11945 +3263 3137 -66132898.87745 +3138 3138 1024746089.754 +3139 3138 2.086162567139e-05 +3140 3138 9143617.227815 +3141 3138 115751892.8599 +3142 3138 -9.417533874512e-06 +3143 3138 2285904.308086 +3153 3138 -244029558.4996 +3154 3138 2.473592758179e-06 +3155 3138 -5943336.391493 +3156 3138 -96781952.40796 +3157 3138 62499999.98974 +3158 3138 -27030538.9556 +3237 3138 -93459816.96553 +3238 3138 1.579523086548e-06 +3239 3138 66889426.94725 +3240 3138 -38668381.31079 +3241 3138 -15625000.00514 +3242 3138 23108532.96245 +3249 3138 119183368.3243 +3250 3138 4.112720489502e-06 +3251 3138 2285903.027438 +3252 3138 -32106344.47651 +3253 3138 -9.387731552124e-06 +3254 3138 571475.757148 +3264 3138 -97033826.33989 +3265 3138 1.400709152222e-06 +3266 3138 -69175329.97466 +3267 3138 -39900479.57507 +3268 3138 15625000.00513 +3269 3138 -23680008.71958 +3139 3139 874738712.6486 +3140 3139 -109721037.6509 +3141 3139 -1.046061515808e-05 +3142 3139 -121747792.2491 +3143 3139 55957741.04746 +3153 3139 4.053115844727e-06 +3154 3139 30971970.86735 +3155 3139 -27430259.42623 +3156 3139 62499999.98974 +3157 3139 -78031030.26054 +3158 3139 15223810.26862 +3237 3139 -6.705522537231e-07 +3238 3139 -24709454.43242 +3239 3139 -6857568.701869 +3240 3139 -15625000.00514 +3241 3139 -33980662.73527 +3242 3139 16657951.02195 +3249 3139 4.053115844727e-06 +3250 3139 81681619.73861 +3251 3139 -27430274.79396 +3252 3139 -8.40425491333e-06 +3253 3139 -91481269.86781 +3254 3139 68140484.61019 +3264 3139 7.450580596924e-07 +3265 3139 -28283463.80681 +3266 3139 -6857568.701869 +3267 3139 15625000.00513 +3268 3139 -35212760.99956 +3269 3139 17343714.91106 +3140 3140 938198180.6514 +3141 3140 2285904.308086 +3142 3140 53763296.60338 +3143 3140 60055040.21296 +3153 3140 -3200280.836388 +3154 3140 -27430259.42623 +3155 3140 46485699.20007 +3156 3140 -26687657.01071 +3157 3140 14949504.71271 +3158 3140 -33777948.97413 +3237 3140 66546545.00303 +3238 3140 -6857568.701869 +3239 3140 -74918497.68596 +3240 3140 23108532.96245 +3241 3140 16657951.02195 +3242 3140 -47038891.18556 +3249 3140 2285903.027438 +3250 3140 -27430274.79396 +3251 3140 -130792022.7266 +3252 3140 571475.7571481 +3253 3140 67866179.05482 +3254 3140 -147771014.9835 +3264 3140 -68832448.03044 +3265 3140 -6857568.701869 +3266 3140 -84449189.35104 +3267 3140 -23680008.71958 +3268 3140 17343714.91106 +3269 3140 -50324486.557 +3141 3141 1024746089.754 +3142 3141 2.086162567139e-05 +3143 3141 9143617.227815 +3144 3141 115751892.8599 +3145 3141 -9.417533874512e-06 +3146 3141 2285904.308086 +3153 3141 -95427568.72765 +3154 3141 -62499999.98975 +3155 3141 24401752.70261 +3156 3141 -244029558.4996 +3157 3141 2.473592758179e-06 +3158 3141 -5943336.391493 +3159 3141 -96781952.40796 +3160 3141 62499999.98974 +3161 3141 -27030538.9556 +3237 3141 -25604579.22317 +3238 3141 15625000.00514 +3239 3141 10250460.04156 +3240 3141 -93459816.96553 +3241 3141 1.579523086548e-06 +3242 3141 66889426.94725 +3243 3141 -38668381.31079 +3244 3141 -15625000.00514 +3245 3141 23108532.96245 +3249 3141 21503247.52855 +3250 3141 3.844499588013e-06 +3251 3141 571475.7571353 +3252 3141 119183368.3243 +3253 3141 4.112720489502e-06 +3254 3141 2285903.027438 +3255 3141 -32106344.47651 +3256 3141 -9.387731552124e-06 +3257 3141 571475.757148 +3264 3141 -26159485.64696 +3265 3141 -15625000.00513 +3266 3141 -10821935.79869 +3267 3141 -97033826.33989 +3268 3141 1.400709152222e-06 +3269 3141 -69175329.97466 +3270 3141 -39900479.57507 +3271 3141 15625000.00513 +3272 3141 -23680008.71958 +3142 3142 874738712.6486 +3143 3142 -109721037.6509 +3144 3142 -1.046061515808e-05 +3145 3142 -121747792.2491 +3146 3142 55957741.04746 +3153 3142 -62499999.98975 +3154 3142 -76676646.58022 +3155 3142 12206449.1576 +3156 3142 4.053115844727e-06 +3157 3142 30971970.86735 +3158 3142 -27430259.42623 +3159 3142 62499999.98974 +3160 3142 -78031030.26054 +3161 3142 15223810.26862 +3237 3142 15625000.00514 +3238 3142 -20916860.64765 +3239 3142 -9800382.320076 +3240 3142 -6.705522537231e-07 +3241 3142 -24709454.43242 +3242 3142 -6857568.701869 +3243 3142 -15625000.00514 +3244 3142 -33980662.73527 +3245 3142 16657951.02195 +3249 3142 5.88595867157e-06 +3250 3142 -37871677.86274 +3251 3142 -40710209.81623 +3252 3142 4.053115844727e-06 +3253 3142 81681619.73861 +3254 3142 -27430274.79396 +3255 3142 -8.40425491333e-06 +3256 3142 -91481269.86781 +3257 3142 68140484.61019 +3264 3142 -15625000.00513 +3265 3142 -21471767.07144 +3266 3142 -10486146.20919 +3267 3142 7.450580596924e-07 +3268 3142 -28283463.80681 +3269 3142 -6857568.701869 +3270 3142 15625000.00513 +3271 3142 -35212760.99956 +3272 3142 17343714.91106 +3143 3143 938198180.6514 +3144 3143 2285904.308086 +3145 3143 53763296.60338 +3146 3143 60055040.21296 +3153 3143 24744634.64751 +3154 3143 12480754.71352 +3155 3143 -30166259.15992 +3156 3143 -3200280.836388 +3157 3143 -27430259.42623 +3158 3143 46485699.20007 +3159 3143 -26687657.01071 +3160 3143 14949504.71271 +3161 3143 -33777948.97413 +3237 3143 10250460.04156 +3238 3143 -9800382.320076 +3239 3143 -12202085.61857 +3240 3143 66546545.00303 +3241 3143 -6857568.701869 +3242 3143 -74918497.68596 +3243 3143 23108532.96245 +3244 3143 16657951.02195 +3245 3143 -47038891.18556 +3249 3143 571475.7571355 +3250 3143 -40435904.26086 +3251 3143 -4812102.970013 +3252 3143 2285903.027438 +3253 3143 -27430274.79396 +3254 3143 -130792022.7266 +3255 3143 571475.7571481 +3256 3143 67866179.05482 +3257 3143 -147771014.9835 +3264 3143 -10821935.79869 +3265 3143 -10486146.20919 +3266 3143 -13681836.08202 +3267 3143 -68832448.03044 +3268 3143 -6857568.701869 +3269 3143 -84449189.35104 +3270 3143 -23680008.71958 +3271 3143 17343714.91106 +3272 3143 -50324486.557 +3144 3144 1024746089.754 +3145 3144 2.086162567139e-05 +3146 3144 9143617.227815 +3147 3144 115751892.8599 +3148 3144 -9.417533874512e-06 +3149 3144 2285904.308086 +3156 3144 -95427568.72765 +3157 3144 -62499999.98975 +3158 3144 24401752.70261 +3159 3144 -244029558.4996 +3160 3144 2.473592758179e-06 +3161 3144 -5943336.391493 +3162 3144 -96781952.40796 +3163 3144 62499999.98974 +3164 3144 -27030538.9556 +3240 3144 -25604579.22317 +3241 3144 15625000.00514 +3242 3144 10250460.04156 +3243 3144 -93459816.96553 +3244 3144 1.579523086548e-06 +3245 3144 66889426.94725 +3246 3144 -38668381.31079 +3247 3144 -15625000.00514 +3248 3144 23108532.96245 +3252 3144 21503247.52855 +3253 3144 3.844499588013e-06 +3254 3144 571475.7571353 +3255 3144 119183368.3243 +3256 3144 4.112720489502e-06 +3257 3144 2285903.027438 +3258 3144 -32106344.47651 +3259 3144 -9.387731552124e-06 +3260 3144 571475.757148 +3267 3144 -26159485.64696 +3268 3144 -15625000.00513 +3269 3144 -10821935.79869 +3270 3144 -97033826.33989 +3271 3144 1.400709152222e-06 +3272 3144 -69175329.97466 +3273 3144 -39900479.57507 +3274 3144 15625000.00513 +3275 3144 -23680008.71958 +3145 3145 874738712.6486 +3146 3145 -109721037.6509 +3147 3145 -1.046061515808e-05 +3148 3145 -121747792.2491 +3149 3145 55957741.04746 +3156 3145 -62499999.98975 +3157 3145 -76676646.58022 +3158 3145 12206449.1576 +3159 3145 4.053115844727e-06 +3160 3145 30971970.86735 +3161 3145 -27430259.42623 +3162 3145 62499999.98974 +3163 3145 -78031030.26054 +3164 3145 15223810.26862 +3240 3145 15625000.00514 +3241 3145 -20916860.64765 +3242 3145 -9800382.320076 +3243 3145 -6.705522537231e-07 +3244 3145 -24709454.43242 +3245 3145 -6857568.701869 +3246 3145 -15625000.00514 +3247 3145 -33980662.73527 +3248 3145 16657951.02195 +3252 3145 5.88595867157e-06 +3253 3145 -37871677.86274 +3254 3145 -40710209.81623 +3255 3145 4.053115844727e-06 +3256 3145 81681619.73861 +3257 3145 -27430274.79396 +3258 3145 -8.40425491333e-06 +3259 3145 -91481269.86781 +3260 3145 68140484.61019 +3267 3145 -15625000.00513 +3268 3145 -21471767.07144 +3269 3145 -10486146.20919 +3270 3145 7.450580596924e-07 +3271 3145 -28283463.80681 +3272 3145 -6857568.701869 +3273 3145 15625000.00513 +3274 3145 -35212760.99956 +3275 3145 17343714.91106 +3146 3146 938198180.6514 +3147 3146 2285904.308086 +3148 3146 53763296.60338 +3149 3146 60055040.21296 +3156 3146 24744634.64751 +3157 3146 12480754.71352 +3158 3146 -30166259.15992 +3159 3146 -3200280.836388 +3160 3146 -27430259.42623 +3161 3146 46485699.20007 +3162 3146 -26687657.01071 +3163 3146 14949504.71271 +3164 3146 -33777948.97413 +3240 3146 10250460.04156 +3241 3146 -9800382.320076 +3242 3146 -12202085.61857 +3243 3146 66546545.00303 +3244 3146 -6857568.701869 +3245 3146 -74918497.68596 +3246 3146 23108532.96245 +3247 3146 16657951.02195 +3248 3146 -47038891.18556 +3252 3146 571475.7571355 +3253 3146 -40435904.26086 +3254 3146 -4812102.970013 +3255 3146 2285903.027438 +3256 3146 -27430274.79396 +3257 3146 -130792022.7266 +3258 3146 571475.7571481 +3259 3146 67866179.05482 +3260 3146 -147771014.9835 +3267 3146 -10821935.79869 +3268 3146 -10486146.20919 +3269 3146 -13681836.08202 +3270 3146 -68832448.03044 +3271 3146 -6857568.701869 +3272 3146 -84449189.35104 +3273 3146 -23680008.71958 +3274 3146 17343714.91106 +3275 3146 -50324486.557 +3147 3147 1110223097.916 +3148 3147 62559291.5799 +3149 3147 30860259.9917 +3150 3147 12838043.85587 +3151 3147 -62523716.6258 +3152 3147 27041055.07434 +3159 3147 -95427568.72765 +3160 3147 -62499999.98975 +3161 3147 24401752.70261 +3162 3147 -244029558.4996 +3163 3147 2.473592758179e-06 +3164 3147 -5943336.391493 +3165 3147 -96781952.40796 +3166 3147 62499999.98974 +3167 3147 -27030538.9556 +3243 3147 -25604579.22317 +3244 3147 15625000.00514 +3245 3147 10250460.04156 +3246 3147 -111681734.2619 +3247 3147 -15632983.09438 +3248 3147 61472760.90482 +3255 3147 21503247.52855 +3256 3147 3.844499588013e-06 +3257 3147 571475.7571353 +3258 3147 149252626.5636 +3259 3147 15638305.15389 +3260 3147 7711980.245565 +3261 3147 -47230742.81426 +3262 3147 -15630322.06464 +3263 3147 23688071.7797 +3270 3147 -26159485.64696 +3271 3147 -15625000.00513 +3272 3147 -10821935.79869 +3273 3147 -97033826.33989 +3274 3147 1.400709152222e-06 +3275 3147 -69175329.97466 +3276 3147 -39900479.57507 +3277 3147 15625000.00513 +3278 3147 -23680008.71958 +3148 3148 941438116.1313 +3149 3148 -85033165.29872 +3150 3148 -62535574.94383 +3151 3148 -205958151.8641 +3152 3148 46639478.37137 +3159 3148 -62499999.98975 +3160 3148 -76676646.58022 +3161 3148 12206449.1576 +3162 3148 4.053115844727e-06 +3163 3148 30971970.86735 +3164 3148 -27430259.42623 +3165 3148 62499999.98974 +3166 3148 -78031030.26054 +3167 3148 15223810.26862 +3243 3148 15625000.00514 +3244 3148 -20916860.64765 +3245 3148 -9800382.320076 +3246 3148 -15630322.06464 +3247 3148 -38227021.54706 +3248 3148 5963051.430523 +3255 3148 5.88595867157e-06 +3256 3148 -37871677.86274 +3257 3148 -40710209.81623 +3258 3148 15638305.15389 +3259 3148 107057171.8061 +3260 3148 -21260770.12636 +3261 3148 -15632983.09439 +3262 3148 -101928593.64 +3263 3148 65822290.07648 +3270 3148 -15625000.00513 +3271 3148 -21471767.07144 +3272 3148 -10486146.20919 +3273 3148 7.450580596924e-07 +3274 3148 -28283463.80681 +3275 3148 -6857568.701869 +3276 3148 15625000.00513 +3277 3148 -35212760.99956 +3278 3148 17343714.91106 +3149 3149 941510422.8134 +3150 3149 26703431.18881 +3151 3149 52129838.76531 +3152 3149 9972799.741074 +3159 3149 24744634.64751 +3160 3149 12480754.71352 +3161 3149 -30166259.15992 +3162 3149 -3200280.836388 +3163 3149 -27430259.42623 +3164 3149 46485699.20007 +3165 3149 -26687657.01071 +3166 3149 14949504.71271 +3167 3149 -33777948.97413 +3243 3149 10250460.04156 +3244 3149 -9800382.320076 +3245 3149 -12202085.61857 +3246 3149 61128808.369 +3247 3149 4044385.985747 +3248 3149 -67372502.27695 +3255 3149 571475.7571355 +3256 3149 -40435904.26086 +3257 3149 -4812102.970013 +3258 3149 7717756.425008 +3259 3149 -21256149.23011 +3260 3149 -106755752.9646 +3261 3149 23692103.30976 +3262 3149 67469018.6918 +3263 3149 -132015307.5643 +3270 3149 -10821935.79869 +3271 3149 -10486146.20919 +3272 3149 -13681836.08202 +3273 3149 -68832448.03044 +3274 3149 -6857568.701869 +3275 3149 -84449189.35104 +3276 3149 -23680008.71958 +3277 3149 17343714.91106 +3278 3149 -50324486.557 +3150 3150 648741877.3649 +3151 3150 62499999.98976 +3152 3150 33168324.30835 +3162 3150 -95427568.72765 +3163 3150 -62499999.98975 +3164 3150 24401752.70261 +3165 3150 -355476071.9436 +3166 3150 -62523716.6258 +3167 3150 -27673319.58105 +3168 3150 5797712.423909 +3169 3150 50023716.62785 +3170 3150 -19897668.89224 +3246 3150 2016499.187392 +3247 3150 18757983.09541 +3248 3150 12648670.74487 +3258 3150 -6124104.06778 +3259 3150 -15632983.09438 +3260 3150 -10255693.28227 +3261 3150 76701211.16396 +3262 3150 15625000.00514 +3263 3150 21009550.22758 +3273 3150 -26159485.64696 +3274 3150 -15625000.00513 +3275 3150 -10821935.79869 +3276 3150 -125983237.2565 +3277 3150 -15630322.06463 +3278 3150 -74621947.50591 +3279 3150 -24799837.07904 +3280 3150 12505322.06361 +3281 3150 -18723479.73292 +3151 3151 554960584.1326 +3152 3151 -63110559.55319 +3162 3151 -62499999.98975 +3163 3151 -76676646.58022 +3164 3151 12206449.1576 +3165 3151 -62535574.94383 +3166 3151 -61649505.13883 +3167 3151 -38276277.82281 +3168 3151 75035574.94178 +3169 3151 5797712.423912 +3170 3151 25521217.55499 +3246 3151 12505322.06361 +3247 3151 2016499.187392 +3248 3151 -6746002.447256 +3258 3151 -15630322.06463 +3259 3151 -60821954.89356 +3260 3151 -41130474.11058 +3261 3151 15625000.00514 +3262 3151 53256630.69937 +3263 3151 -5602780.460976 +3273 3151 -15625000.00513 +3274 3151 -21471767.07144 +3275 3151 -10486146.20919 +3276 3151 -15632983.09438 +3277 3151 -52528524.54163 +3278 3151 -23113573.91808 +3279 3151 18757983.09541 +3280 3151 -24799837.07904 +3281 3151 22467775.67917 +3152 3152 608122864.0228 +3162 3152 24744634.64751 +3163 3152 12480754.71352 +3164 3152 -30166259.15992 +3165 3152 -24925817.21738 +3166 3152 -30317816.4155 +3167 3152 -26125989.8053 +3168 3152 -29846503.33835 +3169 3152 17014145.03666 +3170 3152 15460566.46375 +3246 3152 8432447.163244 +3247 3152 -10119003.67088 +3248 3152 5377331.166378 +3258 3152 -10253948.8687 +3259 3152 -42777202.9092 +3260 3152 -22397604.24035 +3261 3152 -6140600.947398 +3262 3152 -27322678.94813 +3263 3152 -75919024.90121 +3273 3152 -10821935.79869 +3274 3152 -10486146.20919 +3275 3152 -13681836.08202 +3276 3152 -74277994.97009 +3277 3152 -21190287.58241 +3278 3152 -105509843.5958 +3279 3152 -28085219.59939 +3280 3152 14978517.11945 +3281 3152 -66132898.87745 +3153 3153 1024746089.754 +3154 3153 2.086162567139e-05 +3155 3153 9143617.227815 +3156 3153 115751892.8599 +3157 3153 -9.417533874512e-06 +3158 3153 2285904.308086 +3171 3153 -244029558.4996 +3172 3153 2.473592758179e-06 +3173 3153 -5943336.391493 +3174 3153 -96781952.40796 +3175 3153 62499999.98974 +3176 3153 -27030538.9556 +3249 3153 -93459816.96553 +3250 3153 1.579523086548e-06 +3251 3153 66889426.94725 +3252 3153 -38668381.31079 +3253 3153 -15625000.00514 +3254 3153 23108532.96245 +3264 3153 119183368.3243 +3265 3153 4.112720489502e-06 +3266 3153 2285903.027438 +3267 3153 -32106344.47651 +3268 3153 -9.387731552124e-06 +3269 3153 571475.757148 +3282 3153 -97033826.33989 +3283 3153 1.400709152222e-06 +3284 3153 -69175329.97466 +3285 3153 -39900479.57507 +3286 3153 15625000.00513 +3287 3153 -23680008.71958 +3154 3154 874738712.6486 +3155 3154 -109721037.6509 +3156 3154 -1.046061515808e-05 +3157 3154 -121747792.2491 +3158 3154 55957741.04746 +3171 3154 4.053115844727e-06 +3172 3154 30971970.86735 +3173 3154 -27430259.42623 +3174 3154 62499999.98974 +3175 3154 -78031030.26054 +3176 3154 15223810.26862 +3249 3154 -6.705522537231e-07 +3250 3154 -24709454.43242 +3251 3154 -6857568.701869 +3252 3154 -15625000.00514 +3253 3154 -33980662.73527 +3254 3154 16657951.02195 +3264 3154 4.053115844727e-06 +3265 3154 81681619.73861 +3266 3154 -27430274.79396 +3267 3154 -8.40425491333e-06 +3268 3154 -91481269.86781 +3269 3154 68140484.61019 +3282 3154 7.450580596924e-07 +3283 3154 -28283463.80681 +3284 3154 -6857568.701869 +3285 3154 15625000.00513 +3286 3154 -35212760.99956 +3287 3154 17343714.91106 +3155 3155 938198180.6514 +3156 3155 2285904.308086 +3157 3155 53763296.60338 +3158 3155 60055040.21296 +3171 3155 -3200280.836388 +3172 3155 -27430259.42623 +3173 3155 46485699.20007 +3174 3155 -26687657.01071 +3175 3155 14949504.71271 +3176 3155 -33777948.97413 +3249 3155 66546545.00303 +3250 3155 -6857568.701869 +3251 3155 -74918497.68596 +3252 3155 23108532.96245 +3253 3155 16657951.02195 +3254 3155 -47038891.18556 +3264 3155 2285903.027438 +3265 3155 -27430274.79396 +3266 3155 -130792022.7266 +3267 3155 571475.7571481 +3268 3155 67866179.05482 +3269 3155 -147771014.9835 +3282 3155 -68832448.03044 +3283 3155 -6857568.701869 +3284 3155 -84449189.35104 +3285 3155 -23680008.71958 +3286 3155 17343714.91106 +3287 3155 -50324486.557 +3156 3156 1024746089.754 +3157 3156 2.086162567139e-05 +3158 3156 9143617.227815 +3159 3156 115751892.8599 +3160 3156 -9.417533874512e-06 +3161 3156 2285904.308086 +3171 3156 -95427568.72765 +3172 3156 -62499999.98975 +3173 3156 24401752.70261 +3174 3156 -244029558.4996 +3175 3156 2.473592758179e-06 +3176 3156 -5943336.391493 +3177 3156 -96781952.40796 +3178 3156 62499999.98974 +3179 3156 -27030538.9556 +3249 3156 -25604579.22317 +3250 3156 15625000.00514 +3251 3156 10250460.04156 +3252 3156 -93459816.96553 +3253 3156 1.579523086548e-06 +3254 3156 66889426.94725 +3255 3156 -38668381.31079 +3256 3156 -15625000.00514 +3257 3156 23108532.96245 +3264 3156 21503247.52855 +3265 3156 3.844499588013e-06 +3266 3156 571475.7571353 +3267 3156 119183368.3243 +3268 3156 4.112720489502e-06 +3269 3156 2285903.027438 +3270 3156 -32106344.47651 +3271 3156 -9.387731552124e-06 +3272 3156 571475.757148 +3282 3156 -26159485.64696 +3283 3156 -15625000.00513 +3284 3156 -10821935.79869 +3285 3156 -97033826.33989 +3286 3156 1.400709152222e-06 +3287 3156 -69175329.97466 +3288 3156 -39900479.57507 +3289 3156 15625000.00513 +3290 3156 -23680008.71958 +3157 3157 874738712.6486 +3158 3157 -109721037.6509 +3159 3157 -1.046061515808e-05 +3160 3157 -121747792.2491 +3161 3157 55957741.04746 +3171 3157 -62499999.98975 +3172 3157 -76676646.58022 +3173 3157 12206449.1576 +3174 3157 4.053115844727e-06 +3175 3157 30971970.86735 +3176 3157 -27430259.42623 +3177 3157 62499999.98974 +3178 3157 -78031030.26054 +3179 3157 15223810.26862 +3249 3157 15625000.00514 +3250 3157 -20916860.64765 +3251 3157 -9800382.320076 +3252 3157 -6.705522537231e-07 +3253 3157 -24709454.43242 +3254 3157 -6857568.701869 +3255 3157 -15625000.00514 +3256 3157 -33980662.73527 +3257 3157 16657951.02195 +3264 3157 5.88595867157e-06 +3265 3157 -37871677.86274 +3266 3157 -40710209.81623 +3267 3157 4.053115844727e-06 +3268 3157 81681619.73861 +3269 3157 -27430274.79396 +3270 3157 -8.40425491333e-06 +3271 3157 -91481269.86781 +3272 3157 68140484.61019 +3282 3157 -15625000.00513 +3283 3157 -21471767.07144 +3284 3157 -10486146.20919 +3285 3157 7.450580596924e-07 +3286 3157 -28283463.80681 +3287 3157 -6857568.701869 +3288 3157 15625000.00513 +3289 3157 -35212760.99956 +3290 3157 17343714.91106 +3158 3158 938198180.6514 +3159 3158 2285904.308086 +3160 3158 53763296.60338 +3161 3158 60055040.21296 +3171 3158 24744634.64751 +3172 3158 12480754.71352 +3173 3158 -30166259.15992 +3174 3158 -3200280.836388 +3175 3158 -27430259.42623 +3176 3158 46485699.20007 +3177 3158 -26687657.01071 +3178 3158 14949504.71271 +3179 3158 -33777948.97413 +3249 3158 10250460.04156 +3250 3158 -9800382.320076 +3251 3158 -12202085.61857 +3252 3158 66546545.00303 +3253 3158 -6857568.701869 +3254 3158 -74918497.68596 +3255 3158 23108532.96245 +3256 3158 16657951.02195 +3257 3158 -47038891.18556 +3264 3158 571475.7571355 +3265 3158 -40435904.26086 +3266 3158 -4812102.970013 +3267 3158 2285903.027438 +3268 3158 -27430274.79396 +3269 3158 -130792022.7266 +3270 3158 571475.7571481 +3271 3158 67866179.05482 +3272 3158 -147771014.9835 +3282 3158 -10821935.79869 +3283 3158 -10486146.20919 +3284 3158 -13681836.08202 +3285 3158 -68832448.03044 +3286 3158 -6857568.701869 +3287 3158 -84449189.35104 +3288 3158 -23680008.71958 +3289 3158 17343714.91106 +3290 3158 -50324486.557 +3159 3159 1024746089.754 +3160 3159 2.086162567139e-05 +3161 3159 9143617.227815 +3162 3159 115751892.8599 +3163 3159 -9.417533874512e-06 +3164 3159 2285904.308086 +3174 3159 -95427568.72765 +3175 3159 -62499999.98975 +3176 3159 24401752.70261 +3177 3159 -244029558.4996 +3178 3159 2.473592758179e-06 +3179 3159 -5943336.391493 +3180 3159 -96781952.40796 +3181 3159 62499999.98974 +3182 3159 -27030538.9556 +3252 3159 -25604579.22317 +3253 3159 15625000.00514 +3254 3159 10250460.04156 +3255 3159 -93459816.96553 +3256 3159 1.579523086548e-06 +3257 3159 66889426.94725 +3258 3159 -38668381.31079 +3259 3159 -15625000.00514 +3260 3159 23108532.96245 +3267 3159 21503247.52855 +3268 3159 3.844499588013e-06 +3269 3159 571475.7571353 +3270 3159 119183368.3243 +3271 3159 4.112720489502e-06 +3272 3159 2285903.027438 +3273 3159 -32106344.47651 +3274 3159 -9.387731552124e-06 +3275 3159 571475.757148 +3285 3159 -26159485.64696 +3286 3159 -15625000.00513 +3287 3159 -10821935.79869 +3288 3159 -97033826.33989 +3289 3159 1.400709152222e-06 +3290 3159 -69175329.97466 +3291 3159 -39900479.57507 +3292 3159 15625000.00513 +3293 3159 -23680008.71958 +3160 3160 874738712.6486 +3161 3160 -109721037.6509 +3162 3160 -1.046061515808e-05 +3163 3160 -121747792.2491 +3164 3160 55957741.04746 +3174 3160 -62499999.98975 +3175 3160 -76676646.58022 +3176 3160 12206449.1576 +3177 3160 4.053115844727e-06 +3178 3160 30971970.86735 +3179 3160 -27430259.42623 +3180 3160 62499999.98974 +3181 3160 -78031030.26054 +3182 3160 15223810.26862 +3252 3160 15625000.00514 +3253 3160 -20916860.64765 +3254 3160 -9800382.320076 +3255 3160 -6.705522537231e-07 +3256 3160 -24709454.43242 +3257 3160 -6857568.701869 +3258 3160 -15625000.00514 +3259 3160 -33980662.73527 +3260 3160 16657951.02195 +3267 3160 5.88595867157e-06 +3268 3160 -37871677.86274 +3269 3160 -40710209.81623 +3270 3160 4.053115844727e-06 +3271 3160 81681619.73861 +3272 3160 -27430274.79396 +3273 3160 -8.40425491333e-06 +3274 3160 -91481269.86781 +3275 3160 68140484.61019 +3285 3160 -15625000.00513 +3286 3160 -21471767.07144 +3287 3160 -10486146.20919 +3288 3160 7.450580596924e-07 +3289 3160 -28283463.80681 +3290 3160 -6857568.701869 +3291 3160 15625000.00513 +3292 3160 -35212760.99956 +3293 3160 17343714.91106 +3161 3161 938198180.6514 +3162 3161 2285904.308086 +3163 3161 53763296.60338 +3164 3161 60055040.21296 +3174 3161 24744634.64751 +3175 3161 12480754.71352 +3176 3161 -30166259.15992 +3177 3161 -3200280.836388 +3178 3161 -27430259.42623 +3179 3161 46485699.20007 +3180 3161 -26687657.01071 +3181 3161 14949504.71271 +3182 3161 -33777948.97413 +3252 3161 10250460.04156 +3253 3161 -9800382.320076 +3254 3161 -12202085.61857 +3255 3161 66546545.00303 +3256 3161 -6857568.701869 +3257 3161 -74918497.68596 +3258 3161 23108532.96245 +3259 3161 16657951.02195 +3260 3161 -47038891.18556 +3267 3161 571475.7571355 +3268 3161 -40435904.26086 +3269 3161 -4812102.970013 +3270 3161 2285903.027438 +3271 3161 -27430274.79396 +3272 3161 -130792022.7266 +3273 3161 571475.7571481 +3274 3161 67866179.05482 +3275 3161 -147771014.9835 +3285 3161 -10821935.79869 +3286 3161 -10486146.20919 +3287 3161 -13681836.08202 +3288 3161 -68832448.03044 +3289 3161 -6857568.701869 +3290 3161 -84449189.35104 +3291 3161 -23680008.71958 +3292 3161 17343714.91106 +3293 3161 -50324486.557 +3162 3162 1024746089.754 +3163 3162 2.086162567139e-05 +3164 3162 9143617.227815 +3165 3162 115751892.8599 +3166 3162 -9.417533874512e-06 +3167 3162 2285904.308086 +3177 3162 -95427568.72765 +3178 3162 -62499999.98975 +3179 3162 24401752.70261 +3180 3162 -244029558.4996 +3181 3162 2.473592758179e-06 +3182 3162 -5943336.391493 +3183 3162 -96781952.40796 +3184 3162 62499999.98974 +3185 3162 -27030538.9556 +3255 3162 -25604579.22317 +3256 3162 15625000.00514 +3257 3162 10250460.04156 +3258 3162 -93459816.96553 +3259 3162 1.579523086548e-06 +3260 3162 66889426.94725 +3261 3162 -38668381.31079 +3262 3162 -15625000.00514 +3263 3162 23108532.96245 +3270 3162 21503247.52855 +3271 3162 3.844499588013e-06 +3272 3162 571475.7571353 +3273 3162 119183368.3243 +3274 3162 4.112720489502e-06 +3275 3162 2285903.027438 +3276 3162 -32106344.47651 +3277 3162 -9.387731552124e-06 +3278 3162 571475.757148 +3288 3162 -26159485.64696 +3289 3162 -15625000.00513 +3290 3162 -10821935.79869 +3291 3162 -97033826.33989 +3292 3162 1.400709152222e-06 +3293 3162 -69175329.97466 +3294 3162 -39900479.57507 +3295 3162 15625000.00513 +3296 3162 -23680008.71958 +3163 3163 874738712.6486 +3164 3163 -109721037.6509 +3165 3163 -1.046061515808e-05 +3166 3163 -121747792.2491 +3167 3163 55957741.04746 +3177 3163 -62499999.98975 +3178 3163 -76676646.58022 +3179 3163 12206449.1576 +3180 3163 4.053115844727e-06 +3181 3163 30971970.86735 +3182 3163 -27430259.42623 +3183 3163 62499999.98974 +3184 3163 -78031030.26054 +3185 3163 15223810.26862 +3255 3163 15625000.00514 +3256 3163 -20916860.64765 +3257 3163 -9800382.320076 +3258 3163 -6.705522537231e-07 +3259 3163 -24709454.43242 +3260 3163 -6857568.701869 +3261 3163 -15625000.00514 +3262 3163 -33980662.73527 +3263 3163 16657951.02195 +3270 3163 5.88595867157e-06 +3271 3163 -37871677.86274 +3272 3163 -40710209.81623 +3273 3163 4.053115844727e-06 +3274 3163 81681619.73861 +3275 3163 -27430274.79396 +3276 3163 -8.40425491333e-06 +3277 3163 -91481269.86781 +3278 3163 68140484.61019 +3288 3163 -15625000.00513 +3289 3163 -21471767.07144 +3290 3163 -10486146.20919 +3291 3163 7.450580596924e-07 +3292 3163 -28283463.80681 +3293 3163 -6857568.701869 +3294 3163 15625000.00513 +3295 3163 -35212760.99956 +3296 3163 17343714.91106 +3164 3164 938198180.6514 +3165 3164 2285904.308086 +3166 3164 53763296.60338 +3167 3164 60055040.21296 +3177 3164 24744634.64751 +3178 3164 12480754.71352 +3179 3164 -30166259.15992 +3180 3164 -3200280.836388 +3181 3164 -27430259.42623 +3182 3164 46485699.20007 +3183 3164 -26687657.01071 +3184 3164 14949504.71271 +3185 3164 -33777948.97413 +3255 3164 10250460.04156 +3256 3164 -9800382.320076 +3257 3164 -12202085.61857 +3258 3164 66546545.00303 +3259 3164 -6857568.701869 +3260 3164 -74918497.68596 +3261 3164 23108532.96245 +3262 3164 16657951.02195 +3263 3164 -47038891.18556 +3270 3164 571475.7571355 +3271 3164 -40435904.26086 +3272 3164 -4812102.970013 +3273 3164 2285903.027438 +3274 3164 -27430274.79396 +3275 3164 -130792022.7266 +3276 3164 571475.7571481 +3277 3164 67866179.05482 +3278 3164 -147771014.9835 +3288 3164 -10821935.79869 +3289 3164 -10486146.20919 +3290 3164 -13681836.08202 +3291 3164 -68832448.03044 +3292 3164 -6857568.701869 +3293 3164 -84449189.35104 +3294 3164 -23680008.71958 +3295 3164 17343714.91106 +3296 3164 -50324486.557 +3165 3165 1110223097.916 +3166 3165 62559291.5799 +3167 3165 30860259.9917 +3168 3165 12838043.85587 +3169 3165 -62523716.6258 +3170 3165 27041055.07434 +3180 3165 -95427568.72765 +3181 3165 -62499999.98975 +3182 3165 24401752.70261 +3183 3165 -244029558.4996 +3184 3165 2.473592758179e-06 +3185 3165 -5943336.391493 +3186 3165 -96781952.40796 +3187 3165 62499999.98974 +3188 3165 -27030538.9556 +3258 3165 -25604579.22317 +3259 3165 15625000.00514 +3260 3165 10250460.04156 +3261 3165 -111681734.2619 +3262 3165 -15632983.09438 +3263 3165 61472760.90482 +3273 3165 21503247.52855 +3274 3165 3.844499588013e-06 +3275 3165 571475.7571353 +3276 3165 149252626.5636 +3277 3165 15638305.15389 +3278 3165 7711980.245565 +3279 3165 -47230742.81426 +3280 3165 -15630322.06464 +3281 3165 23688071.7797 +3291 3165 -26159485.64696 +3292 3165 -15625000.00513 +3293 3165 -10821935.79869 +3294 3165 -97033826.33989 +3295 3165 1.400709152222e-06 +3296 3165 -69175329.97466 +3297 3165 -39900479.57507 +3298 3165 15625000.00513 +3299 3165 -23680008.71958 +3166 3166 941438116.1313 +3167 3166 -85033165.29872 +3168 3166 -62535574.94383 +3169 3166 -205958151.8641 +3170 3166 46639478.37137 +3180 3166 -62499999.98975 +3181 3166 -76676646.58022 +3182 3166 12206449.1576 +3183 3166 4.053115844727e-06 +3184 3166 30971970.86735 +3185 3166 -27430259.42623 +3186 3166 62499999.98974 +3187 3166 -78031030.26054 +3188 3166 15223810.26862 +3258 3166 15625000.00514 +3259 3166 -20916860.64765 +3260 3166 -9800382.320076 +3261 3166 -15630322.06464 +3262 3166 -38227021.54706 +3263 3166 5963051.430523 +3273 3166 5.88595867157e-06 +3274 3166 -37871677.86274 +3275 3166 -40710209.81623 +3276 3166 15638305.15389 +3277 3166 107057171.8061 +3278 3166 -21260770.12636 +3279 3166 -15632983.09439 +3280 3166 -101928593.64 +3281 3166 65822290.07648 +3291 3166 -15625000.00513 +3292 3166 -21471767.07144 +3293 3166 -10486146.20919 +3294 3166 7.450580596924e-07 +3295 3166 -28283463.80681 +3296 3166 -6857568.701869 +3297 3166 15625000.00513 +3298 3166 -35212760.99956 +3299 3166 17343714.91106 +3167 3167 941510422.8134 +3168 3167 26703431.18881 +3169 3167 52129838.76531 +3170 3167 9972799.741074 +3180 3167 24744634.64751 +3181 3167 12480754.71352 +3182 3167 -30166259.15992 +3183 3167 -3200280.836388 +3184 3167 -27430259.42623 +3185 3167 46485699.20007 +3186 3167 -26687657.01071 +3187 3167 14949504.71271 +3188 3167 -33777948.97413 +3258 3167 10250460.04156 +3259 3167 -9800382.320076 +3260 3167 -12202085.61857 +3261 3167 61128808.369 +3262 3167 4044385.985747 +3263 3167 -67372502.27695 +3273 3167 571475.7571355 +3274 3167 -40435904.26086 +3275 3167 -4812102.970013 +3276 3167 7717756.425008 +3277 3167 -21256149.23011 +3278 3167 -106755752.9646 +3279 3167 23692103.30976 +3280 3167 67469018.6918 +3281 3167 -132015307.5643 +3291 3167 -10821935.79869 +3292 3167 -10486146.20919 +3293 3167 -13681836.08202 +3294 3167 -68832448.03044 +3295 3167 -6857568.701869 +3296 3167 -84449189.35104 +3297 3167 -23680008.71958 +3298 3167 17343714.91106 +3299 3167 -50324486.557 +3168 3168 571856074.9736 +3169 3168 29944782.78006 +3170 3168 -10255414.39245 +3183 3168 -95427568.72765 +3184 3168 -62499999.98975 +3185 3168 24401752.70261 +3186 3168 -279335748.997 +3187 3168 -30005441.58063 +3188 3168 -2084718.233583 +3189 3168 -9122767.138634 +3190 3168 50060658.79238 +3191 3168 -2747902.533834 +3261 3168 2016499.187392 +3262 3168 18757983.09541 +3263 3168 12648670.74487 +3276 3168 -6124104.06778 +3277 3168 -15632983.09438 +3278 3168 -10255693.28227 +3279 3168 65053034.9571 +3280 3168 8483480.368784 +3281 3168 9019580.696071 +3294 3168 -26159485.64696 +3295 3168 -15625000.00513 +3296 3168 -10821935.79869 +3297 3168 -101009842.5111 +3298 3168 -8497290.497413 +3299 3168 -60569369.93287 +3300 3168 -13454901.79217 +3301 3168 12513810.13274 +3302 3168 -11175576.39938 +3169 3169 527903869.9296 +3170 3169 -64299123.93581 +3183 3169 -62499999.98975 +3184 3169 -76676646.58022 +3185 3169 12206449.1576 +3186 3169 -30035770.98092 +3187 3169 -47816.62481159 +3188 3169 -17257158.96419 +3189 3169 75090988.18857 +3190 3169 -44413220.89433 +3191 3169 6790513.35647 +3261 3169 12505322.06361 +3262 3169 2016499.187392 +3263 3169 -6746002.447256 +3276 3169 -15630322.06463 +3277 3169 -60821954.89356 +3278 3169 -41130474.11058 +3279 3169 8483480.368782 +3280 3169 52217536.42934 +3281 3169 -7051287.02931 +3294 3169 -15625000.00513 +3295 3169 -21471767.07144 +3296 3169 -10486146.20919 +3297 3169 -8504195.561731 +3298 3169 -30743336.81906 +3299 3169 -11865024.08222 +3300 3169 18770715.19911 +3301 3169 -20875776.70625 +3302 3169 20377905.34396 +3170 3170 542654871.6366 +3183 3170 24744634.64751 +3184 3170 12480754.71352 +3185 3170 -30166259.15992 +3186 3170 -8254784.546585 +3187 3170 -16158331.56487 +3188 3170 2063603.639451 +3189 3170 -4121853.80075 +3190 3170 5692999.984857 +3191 3170 10963074.71934 +3261 3170 8432447.163244 +3262 3170 -10119003.67088 +3263 3170 5377331.166378 +3276 3170 -10253948.8687 +3277 3170 -42777202.9092 +3278 3170 -22397604.24035 +3279 3170 -15041312.00682 +3280 3170 -26292746.72624 +3281 3170 -76049227.32249 +3294 3170 -10821935.79869 +3295 3170 -10486146.20919 +3296 3170 -13681836.08202 +3297 3170 -62283371.84839 +3298 3170 -11584369.2819 +3299 3170 -77266599.98603 +3300 3170 -16763364.59907 +3301 3170 15907925.99552 +3302 3170 -28458863.19837 +3171 3171 1024746089.754 +3172 3171 2.086162567139e-05 +3173 3171 9143617.227815 +3174 3171 115751892.8599 +3175 3171 -9.417533874512e-06 +3176 3171 2285904.308086 +3192 3171 -244029558.4996 +3193 3171 2.473592758179e-06 +3194 3171 -5943336.391493 +3195 3171 -96781952.40796 +3196 3171 62499999.98974 +3197 3171 -27030538.9556 +3264 3171 -93459816.96553 +3265 3171 1.579523086548e-06 +3266 3171 66889426.94725 +3267 3171 -38668381.31079 +3268 3171 -15625000.00514 +3269 3171 23108532.96245 +3282 3171 119183368.3243 +3283 3171 4.112720489502e-06 +3284 3171 2285903.027438 +3285 3171 -32106344.47651 +3286 3171 -9.387731552124e-06 +3287 3171 571475.757148 +3303 3171 -97033826.33989 +3304 3171 1.400709152222e-06 +3305 3171 -69175329.97466 +3306 3171 -39900479.57507 +3307 3171 15625000.00513 +3308 3171 -23680008.71958 +3172 3172 874738712.6486 +3173 3172 -109721037.6509 +3174 3172 -1.046061515808e-05 +3175 3172 -121747792.2491 +3176 3172 55957741.04746 +3192 3172 4.053115844727e-06 +3193 3172 30971970.86735 +3194 3172 -27430259.42623 +3195 3172 62499999.98974 +3196 3172 -78031030.26054 +3197 3172 15223810.26862 +3264 3172 -6.705522537231e-07 +3265 3172 -24709454.43242 +3266 3172 -6857568.701869 +3267 3172 -15625000.00514 +3268 3172 -33980662.73527 +3269 3172 16657951.02195 +3282 3172 4.053115844727e-06 +3283 3172 81681619.73861 +3284 3172 -27430274.79396 +3285 3172 -8.40425491333e-06 +3286 3172 -91481269.86781 +3287 3172 68140484.61019 +3303 3172 7.450580596924e-07 +3304 3172 -28283463.80681 +3305 3172 -6857568.701869 +3306 3172 15625000.00513 +3307 3172 -35212760.99956 +3308 3172 17343714.91106 +3173 3173 938198180.6514 +3174 3173 2285904.308086 +3175 3173 53763296.60338 +3176 3173 60055040.21296 +3192 3173 -3200280.836388 +3193 3173 -27430259.42623 +3194 3173 46485699.20007 +3195 3173 -26687657.01071 +3196 3173 14949504.71271 +3197 3173 -33777948.97413 +3264 3173 66546545.00303 +3265 3173 -6857568.701869 +3266 3173 -74918497.68596 +3267 3173 23108532.96245 +3268 3173 16657951.02195 +3269 3173 -47038891.18556 +3282 3173 2285903.027438 +3283 3173 -27430274.79396 +3284 3173 -130792022.7266 +3285 3173 571475.7571481 +3286 3173 67866179.05482 +3287 3173 -147771014.9835 +3303 3173 -68832448.03044 +3304 3173 -6857568.701869 +3305 3173 -84449189.35104 +3306 3173 -23680008.71958 +3307 3173 17343714.91106 +3308 3173 -50324486.557 +3174 3174 1024746089.754 +3175 3174 2.086162567139e-05 +3176 3174 9143617.227815 +3177 3174 115751892.8599 +3178 3174 -9.417533874512e-06 +3179 3174 2285904.308086 +3192 3174 -95427568.72765 +3193 3174 -62499999.98975 +3194 3174 24401752.70261 +3195 3174 -244029558.4996 +3196 3174 2.473592758179e-06 +3197 3174 -5943336.391493 +3198 3174 -96781952.40796 +3199 3174 62499999.98974 +3200 3174 -27030538.9556 +3264 3174 -25604579.22317 +3265 3174 15625000.00514 +3266 3174 10250460.04156 +3267 3174 -93459816.96553 +3268 3174 1.579523086548e-06 +3269 3174 66889426.94725 +3270 3174 -38668381.31079 +3271 3174 -15625000.00514 +3272 3174 23108532.96245 +3282 3174 21503247.52855 +3283 3174 3.844499588013e-06 +3284 3174 571475.7571353 +3285 3174 119183368.3243 +3286 3174 4.112720489502e-06 +3287 3174 2285903.027438 +3288 3174 -32106344.47651 +3289 3174 -9.387731552124e-06 +3290 3174 571475.757148 +3303 3174 -26159485.64696 +3304 3174 -15625000.00513 +3305 3174 -10821935.79869 +3306 3174 -97033826.33989 +3307 3174 1.400709152222e-06 +3308 3174 -69175329.97466 +3309 3174 -39900479.57507 +3310 3174 15625000.00513 +3311 3174 -23680008.71958 +3175 3175 874738712.6486 +3176 3175 -109721037.6509 +3177 3175 -1.046061515808e-05 +3178 3175 -121747792.2491 +3179 3175 55957741.04746 +3192 3175 -62499999.98975 +3193 3175 -76676646.58022 +3194 3175 12206449.1576 +3195 3175 4.053115844727e-06 +3196 3175 30971970.86735 +3197 3175 -27430259.42623 +3198 3175 62499999.98974 +3199 3175 -78031030.26054 +3200 3175 15223810.26862 +3264 3175 15625000.00514 +3265 3175 -20916860.64765 +3266 3175 -9800382.320076 +3267 3175 -6.705522537231e-07 +3268 3175 -24709454.43242 +3269 3175 -6857568.701869 +3270 3175 -15625000.00514 +3271 3175 -33980662.73527 +3272 3175 16657951.02195 +3282 3175 5.88595867157e-06 +3283 3175 -37871677.86274 +3284 3175 -40710209.81623 +3285 3175 4.053115844727e-06 +3286 3175 81681619.73861 +3287 3175 -27430274.79396 +3288 3175 -8.40425491333e-06 +3289 3175 -91481269.86781 +3290 3175 68140484.61019 +3303 3175 -15625000.00513 +3304 3175 -21471767.07144 +3305 3175 -10486146.20919 +3306 3175 7.450580596924e-07 +3307 3175 -28283463.80681 +3308 3175 -6857568.701869 +3309 3175 15625000.00513 +3310 3175 -35212760.99956 +3311 3175 17343714.91106 +3176 3176 938198180.6514 +3177 3176 2285904.308086 +3178 3176 53763296.60338 +3179 3176 60055040.21296 +3192 3176 24744634.64751 +3193 3176 12480754.71352 +3194 3176 -30166259.15992 +3195 3176 -3200280.836388 +3196 3176 -27430259.42623 +3197 3176 46485699.20007 +3198 3176 -26687657.01071 +3199 3176 14949504.71271 +3200 3176 -33777948.97413 +3264 3176 10250460.04156 +3265 3176 -9800382.320076 +3266 3176 -12202085.61857 +3267 3176 66546545.00303 +3268 3176 -6857568.701869 +3269 3176 -74918497.68596 +3270 3176 23108532.96245 +3271 3176 16657951.02195 +3272 3176 -47038891.18556 +3282 3176 571475.7571355 +3283 3176 -40435904.26086 +3284 3176 -4812102.970013 +3285 3176 2285903.027438 +3286 3176 -27430274.79396 +3287 3176 -130792022.7266 +3288 3176 571475.7571481 +3289 3176 67866179.05482 +3290 3176 -147771014.9835 +3303 3176 -10821935.79869 +3304 3176 -10486146.20919 +3305 3176 -13681836.08202 +3306 3176 -68832448.03044 +3307 3176 -6857568.701869 +3308 3176 -84449189.35104 +3309 3176 -23680008.71958 +3310 3176 17343714.91106 +3311 3176 -50324486.557 +3177 3177 1024746089.754 +3178 3177 2.086162567139e-05 +3179 3177 9143617.227815 +3180 3177 115751892.8599 +3181 3177 -9.417533874512e-06 +3182 3177 2285904.308086 +3195 3177 -95427568.72765 +3196 3177 -62499999.98975 +3197 3177 24401752.70261 +3198 3177 -244029558.4996 +3199 3177 2.473592758179e-06 +3200 3177 -5943336.391493 +3201 3177 -96781952.40796 +3202 3177 62499999.98974 +3203 3177 -27030538.9556 +3267 3177 -25604579.22317 +3268 3177 15625000.00514 +3269 3177 10250460.04156 +3270 3177 -93459816.96553 +3271 3177 1.579523086548e-06 +3272 3177 66889426.94725 +3273 3177 -38668381.31079 +3274 3177 -15625000.00514 +3275 3177 23108532.96245 +3285 3177 21503247.52855 +3286 3177 3.844499588013e-06 +3287 3177 571475.7571353 +3288 3177 119183368.3243 +3289 3177 4.112720489502e-06 +3290 3177 2285903.027438 +3291 3177 -32106344.47651 +3292 3177 -9.387731552124e-06 +3293 3177 571475.757148 +3306 3177 -26159485.64696 +3307 3177 -15625000.00513 +3308 3177 -10821935.79869 +3309 3177 -97033826.33989 +3310 3177 1.400709152222e-06 +3311 3177 -69175329.97466 +3312 3177 -39900479.57507 +3313 3177 15625000.00513 +3314 3177 -23680008.71958 +3178 3178 874738712.6486 +3179 3178 -109721037.6509 +3180 3178 -1.046061515808e-05 +3181 3178 -121747792.2491 +3182 3178 55957741.04746 +3195 3178 -62499999.98975 +3196 3178 -76676646.58022 +3197 3178 12206449.1576 +3198 3178 4.053115844727e-06 +3199 3178 30971970.86735 +3200 3178 -27430259.42623 +3201 3178 62499999.98974 +3202 3178 -78031030.26054 +3203 3178 15223810.26862 +3267 3178 15625000.00514 +3268 3178 -20916860.64765 +3269 3178 -9800382.320076 +3270 3178 -6.705522537231e-07 +3271 3178 -24709454.43242 +3272 3178 -6857568.701869 +3273 3178 -15625000.00514 +3274 3178 -33980662.73527 +3275 3178 16657951.02195 +3285 3178 5.88595867157e-06 +3286 3178 -37871677.86274 +3287 3178 -40710209.81623 +3288 3178 4.053115844727e-06 +3289 3178 81681619.73861 +3290 3178 -27430274.79396 +3291 3178 -8.40425491333e-06 +3292 3178 -91481269.86781 +3293 3178 68140484.61019 +3306 3178 -15625000.00513 +3307 3178 -21471767.07144 +3308 3178 -10486146.20919 +3309 3178 7.450580596924e-07 +3310 3178 -28283463.80681 +3311 3178 -6857568.701869 +3312 3178 15625000.00513 +3313 3178 -35212760.99956 +3314 3178 17343714.91106 +3179 3179 938198180.6514 +3180 3179 2285904.308086 +3181 3179 53763296.60338 +3182 3179 60055040.21296 +3195 3179 24744634.64751 +3196 3179 12480754.71352 +3197 3179 -30166259.15992 +3198 3179 -3200280.836388 +3199 3179 -27430259.42623 +3200 3179 46485699.20007 +3201 3179 -26687657.01071 +3202 3179 14949504.71271 +3203 3179 -33777948.97413 +3267 3179 10250460.04156 +3268 3179 -9800382.320076 +3269 3179 -12202085.61857 +3270 3179 66546545.00303 +3271 3179 -6857568.701869 +3272 3179 -74918497.68596 +3273 3179 23108532.96245 +3274 3179 16657951.02195 +3275 3179 -47038891.18556 +3285 3179 571475.7571355 +3286 3179 -40435904.26086 +3287 3179 -4812102.970013 +3288 3179 2285903.027438 +3289 3179 -27430274.79396 +3290 3179 -130792022.7266 +3291 3179 571475.7571481 +3292 3179 67866179.05482 +3293 3179 -147771014.9835 +3306 3179 -10821935.79869 +3307 3179 -10486146.20919 +3308 3179 -13681836.08202 +3309 3179 -68832448.03044 +3310 3179 -6857568.701869 +3311 3179 -84449189.35104 +3312 3179 -23680008.71958 +3313 3179 17343714.91106 +3314 3179 -50324486.557 +3180 3180 1024746089.754 +3181 3180 2.086162567139e-05 +3182 3180 9143617.227815 +3183 3180 115751892.8599 +3184 3180 -9.417533874512e-06 +3185 3180 2285904.308086 +3198 3180 -95427568.72765 +3199 3180 -62499999.98975 +3200 3180 24401752.70261 +3201 3180 -244029558.4996 +3202 3180 2.473592758179e-06 +3203 3180 -5943336.391493 +3204 3180 -96781952.40796 +3205 3180 62499999.98974 +3206 3180 -27030538.9556 +3270 3180 -25604579.22317 +3271 3180 15625000.00514 +3272 3180 10250460.04156 +3273 3180 -93459816.96553 +3274 3180 1.579523086548e-06 +3275 3180 66889426.94725 +3276 3180 -38668381.31079 +3277 3180 -15625000.00514 +3278 3180 23108532.96245 +3288 3180 21503247.52855 +3289 3180 3.844499588013e-06 +3290 3180 571475.7571353 +3291 3180 119183368.3243 +3292 3180 4.112720489502e-06 +3293 3180 2285903.027438 +3294 3180 -32106344.47651 +3295 3180 -9.387731552124e-06 +3296 3180 571475.757148 +3309 3180 -26159485.64696 +3310 3180 -15625000.00513 +3311 3180 -10821935.79869 +3312 3180 -97033826.33989 +3313 3180 1.400709152222e-06 +3314 3180 -69175329.97466 +3315 3180 -39900479.57507 +3316 3180 15625000.00513 +3317 3180 -23680008.71958 +3181 3181 874738712.6486 +3182 3181 -109721037.6509 +3183 3181 -1.046061515808e-05 +3184 3181 -121747792.2491 +3185 3181 55957741.04746 +3198 3181 -62499999.98975 +3199 3181 -76676646.58022 +3200 3181 12206449.1576 +3201 3181 4.053115844727e-06 +3202 3181 30971970.86735 +3203 3181 -27430259.42623 +3204 3181 62499999.98974 +3205 3181 -78031030.26054 +3206 3181 15223810.26862 +3270 3181 15625000.00514 +3271 3181 -20916860.64765 +3272 3181 -9800382.320076 +3273 3181 -6.705522537231e-07 +3274 3181 -24709454.43242 +3275 3181 -6857568.701869 +3276 3181 -15625000.00514 +3277 3181 -33980662.73527 +3278 3181 16657951.02195 +3288 3181 5.88595867157e-06 +3289 3181 -37871677.86274 +3290 3181 -40710209.81623 +3291 3181 4.053115844727e-06 +3292 3181 81681619.73861 +3293 3181 -27430274.79396 +3294 3181 -8.40425491333e-06 +3295 3181 -91481269.86781 +3296 3181 68140484.61019 +3309 3181 -15625000.00513 +3310 3181 -21471767.07144 +3311 3181 -10486146.20919 +3312 3181 7.450580596924e-07 +3313 3181 -28283463.80681 +3314 3181 -6857568.701869 +3315 3181 15625000.00513 +3316 3181 -35212760.99956 +3317 3181 17343714.91106 +3182 3182 938198180.6514 +3183 3182 2285904.308086 +3184 3182 53763296.60338 +3185 3182 60055040.21296 +3198 3182 24744634.64751 +3199 3182 12480754.71352 +3200 3182 -30166259.15992 +3201 3182 -3200280.836388 +3202 3182 -27430259.42623 +3203 3182 46485699.20007 +3204 3182 -26687657.01071 +3205 3182 14949504.71271 +3206 3182 -33777948.97413 +3270 3182 10250460.04156 +3271 3182 -9800382.320076 +3272 3182 -12202085.61857 +3273 3182 66546545.00303 +3274 3182 -6857568.701869 +3275 3182 -74918497.68596 +3276 3182 23108532.96245 +3277 3182 16657951.02195 +3278 3182 -47038891.18556 +3288 3182 571475.7571355 +3289 3182 -40435904.26086 +3290 3182 -4812102.970013 +3291 3182 2285903.027438 +3292 3182 -27430274.79396 +3293 3182 -130792022.7266 +3294 3182 571475.7571481 +3295 3182 67866179.05482 +3296 3182 -147771014.9835 +3309 3182 -10821935.79869 +3310 3182 -10486146.20919 +3311 3182 -13681836.08202 +3312 3182 -68832448.03044 +3313 3182 -6857568.701869 +3314 3182 -84449189.35104 +3315 3182 -23680008.71958 +3316 3182 17343714.91106 +3317 3182 -50324486.557 +3183 3183 1024746089.754 +3184 3183 2.086162567139e-05 +3185 3183 9143617.227815 +3186 3183 115751892.8599 +3187 3183 -9.417533874512e-06 +3188 3183 2285904.308086 +3201 3183 -95427568.72765 +3202 3183 -62499999.98975 +3203 3183 24401752.70261 +3204 3183 -244029558.4996 +3205 3183 2.473592758179e-06 +3206 3183 -5943336.391493 +3207 3183 -96781952.40796 +3208 3183 62499999.98974 +3209 3183 -27030538.9556 +3273 3183 -25604579.22317 +3274 3183 15625000.00514 +3275 3183 10250460.04156 +3276 3183 -93459816.96553 +3277 3183 1.579523086548e-06 +3278 3183 66889426.94725 +3279 3183 -38668381.31079 +3280 3183 -15625000.00514 +3281 3183 23108532.96245 +3291 3183 21503247.52855 +3292 3183 3.844499588013e-06 +3293 3183 571475.7571353 +3294 3183 119183368.3243 +3295 3183 4.112720489502e-06 +3296 3183 2285903.027438 +3297 3183 -32106344.47651 +3298 3183 -9.387731552124e-06 +3299 3183 571475.757148 +3312 3183 -26159485.64696 +3313 3183 -15625000.00513 +3314 3183 -10821935.79869 +3315 3183 -97033826.33989 +3316 3183 1.400709152222e-06 +3317 3183 -69175329.97466 +3318 3183 -39900479.57507 +3319 3183 15625000.00513 +3320 3183 -23680008.71958 +3184 3184 874738712.6486 +3185 3184 -109721037.6509 +3186 3184 -1.046061515808e-05 +3187 3184 -121747792.2491 +3188 3184 55957741.04746 +3201 3184 -62499999.98975 +3202 3184 -76676646.58022 +3203 3184 12206449.1576 +3204 3184 4.053115844727e-06 +3205 3184 30971970.86735 +3206 3184 -27430259.42623 +3207 3184 62499999.98974 +3208 3184 -78031030.26054 +3209 3184 15223810.26862 +3273 3184 15625000.00514 +3274 3184 -20916860.64765 +3275 3184 -9800382.320076 +3276 3184 -6.705522537231e-07 +3277 3184 -24709454.43242 +3278 3184 -6857568.701869 +3279 3184 -15625000.00514 +3280 3184 -33980662.73527 +3281 3184 16657951.02195 +3291 3184 5.88595867157e-06 +3292 3184 -37871677.86274 +3293 3184 -40710209.81623 +3294 3184 4.053115844727e-06 +3295 3184 81681619.73861 +3296 3184 -27430274.79396 +3297 3184 -8.40425491333e-06 +3298 3184 -91481269.86781 +3299 3184 68140484.61019 +3312 3184 -15625000.00513 +3313 3184 -21471767.07144 +3314 3184 -10486146.20919 +3315 3184 7.450580596924e-07 +3316 3184 -28283463.80681 +3317 3184 -6857568.701869 +3318 3184 15625000.00513 +3319 3184 -35212760.99956 +3320 3184 17343714.91106 +3185 3185 938198180.6514 +3186 3185 2285904.308086 +3187 3185 53763296.60338 +3188 3185 60055040.21296 +3201 3185 24744634.64751 +3202 3185 12480754.71352 +3203 3185 -30166259.15992 +3204 3185 -3200280.836388 +3205 3185 -27430259.42623 +3206 3185 46485699.20007 +3207 3185 -26687657.01071 +3208 3185 14949504.71271 +3209 3185 -33777948.97413 +3273 3185 10250460.04156 +3274 3185 -9800382.320076 +3275 3185 -12202085.61857 +3276 3185 66546545.00303 +3277 3185 -6857568.701869 +3278 3185 -74918497.68596 +3279 3185 23108532.96245 +3280 3185 16657951.02195 +3281 3185 -47038891.18556 +3291 3185 571475.7571355 +3292 3185 -40435904.26086 +3293 3185 -4812102.970013 +3294 3185 2285903.027438 +3295 3185 -27430274.79396 +3296 3185 -130792022.7266 +3297 3185 571475.7571481 +3298 3185 67866179.05482 +3299 3185 -147771014.9835 +3312 3185 -10821935.79869 +3313 3185 -10486146.20919 +3314 3185 -13681836.08202 +3315 3185 -68832448.03044 +3316 3185 -6857568.701869 +3317 3185 -84449189.35104 +3318 3185 -23680008.71958 +3319 3185 17343714.91106 +3320 3185 -50324486.557 +3186 3186 992511389.303 +3187 3186 35119063.81891 +3188 3186 9148842.328762 +3189 3186 -29871813.60808 +3190 3186 -79429052.75312 +3191 3186 4942840.519856 +3204 3186 -95427568.72765 +3205 3186 -62499999.98975 +3206 3186 24401752.70261 +3207 3186 -213493975.2883 +3208 3186 15647034.81436 +3209 3186 -1463149.762763 +3210 3186 -62618476.51791 +3211 3186 58698725.1008 +3212 3186 -4372518.931206 +3276 3186 -25604579.22317 +3277 3186 15625000.00514 +3278 3186 10250460.04156 +3279 3186 -97575268.52249 +3280 3186 -8504195.56173 +3281 3186 58021091.66608 +3294 3186 21503247.52855 +3295 3186 3.844499588013e-06 +3296 3186 571475.7571353 +3297 3186 132051494.7157 +3298 3186 9477689.141959 +3299 3186 2282727.085888 +3300 3186 -35986362.149 +3301 3186 -19319676.5803 +3302 3186 18187125.68919 +3315 3186 -26159485.64696 +3316 3186 -15625000.00513 +3317 3186 -10821935.79869 +3318 3186 -89582178.40493 +3319 3186 3452677.552407 +3320 3186 -64250585.4472 +3321 3186 -26470165.08373 +3322 3186 14893505.44766 +3323 3186 -14205410.0223 +3187 3187 914984829.2003 +3188 3187 -61105818.0354 +3189 3187 -79459382.15342 +3190 3187 -252787576.3809 +3191 3187 10443239.78177 +3204 3187 -62499999.98975 +3205 3187 -76676646.58022 +3206 3187 12206449.1576 +3207 3187 15647034.81436 +3208 3187 42833571.97188 +3209 3187 -15208606.30983 +3210 3187 58698725.1008 +3211 3187 -97793792.46068 +3212 3187 4402916.111798 +3276 3187 15625000.00514 +3277 3187 -20916860.64765 +3278 3187 -9800382.320076 +3279 3187 -8497290.497415 +3280 3187 -27308762.83038 +3281 3187 3191507.057319 +3294 3187 5.88595867157e-06 +3295 3187 -37871677.86274 +3296 3187 -40710209.81623 +3297 3187 9477689.141955 +3298 3187 109752727.6785 +3299 3187 -15866049.47295 +3300 3187 -19326581.64461 +3301 3187 -91511011.65031 +3302 3187 56876286.44125 +3315 3187 -15625000.00513 +3316 3187 -21471767.07144 +3317 3187 -10486146.20919 +3318 3187 3452677.552406 +3319 3187 -24850939.14401 +3320 3187 -892452.6419469 +3321 3187 14893505.44766 +3322 3187 -33645005.25799 +3323 3187 17715406.89793 +3188 3188 861646857.7911 +3189 3188 4945264.009223 +3190 3188 10445336.85376 +3191 3188 -7035870.455932 +3204 3188 24744634.64751 +3205 3188 12480754.71352 +3206 3188 -30166259.15992 +3207 3188 -7635024.761751 +3208 3188 -15208606.30983 +3209 3188 49654690.13772 +3210 3188 -4372518.93053 +3211 3188 4402916.111798 +3212 3188 -20483455.54872 +3276 3188 10250460.04156 +3277 3188 -9800382.320076 +3278 3188 -12202085.61857 +3279 3188 59735093.58159 +3280 3188 2922838.786602 +3281 3188 -68107736.01619 +3294 3188 571475.7571355 +3295 3188 -40435904.26086 +3296 3188 -4812102.970013 +3297 3188 2294279.514953 +3298 3188 -15856807.28418 +3299 3188 -100567669.0549 +3300 3188 18193455.55287 +3301 3188 56875386.93533 +3302 3188 -80811222.28552 +3315 3188 -10821935.79869 +3316 3188 -10486146.20919 +3317 3188 -13681836.08202 +3318 3188 -65964995.16965 +3319 3188 -892452.6414047 +3320 3188 -81785163.2726 +3321 3188 -14205410.0223 +3322 3188 17715406.89793 +3323 3188 -32227642.79622 +3189 3189 574782817.0468 +3190 3189 9802196.101842 +3191 3189 402791.3222623 +3207 3189 -98180257.21191 +3208 3189 -62016385.48823 +3209 3189 3728150.838127 +3210 3189 -154343775.7057 +3211 3189 20854973.3041 +3212 3189 -1249532.660522 +3213 3189 68140235.52204 +3214 3189 -21818726.25984 +3215 3189 -103490.0609071 +3216 3189 -55799918.28419 +3217 3189 57546336.30698 +3218 3189 -858274.0909733 +3279 3189 -9327793.667405 +3280 3189 18770715.19911 +3281 3189 14702750.48531 +3297 3189 -28699225.70619 +3298 3189 -19326581.64462 +3299 3189 -15770281.05553 +3300 3189 39934892.99282 +3301 3189 2177854.19997 +3302 3189 13470020.49524 +3318 3189 -32222410.0076 +3319 3189 -15532299.34722 +3320 3189 -16029085.59877 +3321 3189 -83057758.80047 +3322 3189 4596360.426188 +3323 3189 -67109824.10549 +3324 3189 -7768576.502317 +3325 3189 -5210204.11628 +3326 3189 7902397.597512 +3327 3189 -26657122.19396 +3328 3189 14524155.28285 +3329 3189 -16661672.26316 +3190 3190 684972887.8256 +3191 3190 -12516121.50345 +3207 3190 -62016385.48823 +3208 3190 -68498112.25618 +3209 3190 1098703.593309 +3210 3190 20854973.30411 +3211 3190 93705147.04257 +3212 3190 -3583791.720977 +3213 3190 3181273.736054 +3214 3190 -53313429.18758 +3215 3190 506062.6241023 +3216 3190 57546336.30698 +3217 3190 -64061175.52891 +3218 3190 547642.7682184 +3279 3190 12513810.13274 +3280 3190 -16748668.58149 +3281 3190 -13266641.09381 +3297 3190 -19319676.5803 +3298 3190 -84223875.20751 +3299 3190 -51752701.14713 +3300 3190 2177854.199968 +3301 3190 64911621.45824 +3302 3190 1186914.700328 +3318 3190 -15532299.34722 +3319 3190 -25137786.72497 +3320 3190 -13282262.11058 +3321 3190 4596360.426188 +3322 3190 -20386045.03311 +3323 3190 2220623.492421 +3324 3190 1039795.885773 +3325 3190 -38105284.24576 +3326 3190 33458816.87333 +3327 3190 14524155.28285 +3328 3190 -28107955.55054 +3329 3190 16801283.08314 +3191 3191 632106309.024 +3207 3191 3728150.838465 +3208 3191 1098703.59358 +3209 3191 -21737210.67115 +3210 3191 -1249532.660522 +3211 3191 -3583791.720977 +3212 3191 100128059.1202 +3213 3191 -103490.0609037 +3214 3191 506062.624102 +3215 3191 73682121.44694 +3216 3191 -858274.0906357 +3217 3191 547642.7682184 +3218 3191 172238.4706765 +3279 3191 9801833.656871 +3280 3191 -17187848.41903 +3281 3191 -17453241.53233 +3297 3191 -15765058.67383 +3298 3191 -51754546.12901 +3299 3191 -61378858.43802 +3300 3191 -13257132.27814 +3301 3191 -7207016.094271 +3302 3191 -120184450.9424 +3318 3191 -16029085.59877 +3319 3191 -13282262.11058 +3320 3191 -26270313.32675 +3321 3191 -67109824.10583 +3322 3191 2220623.492963 +3323 3191 -88573459.20302 +3324 3191 -222602.4044776 +3325 3191 33458816.87333 +3326 3191 -48112195.40656 +3327 3191 -16661672.26316 +3328 3191 16801283.08314 +3329 3191 -32155464.84456 +3192 3192 512192460.3863 +3193 3192 7.033348083496e-06 +3194 3192 -2285830.273855 +3195 3192 57853373.36857 +3196 3192 12499999.99794 +3197 3192 -4857481.874016 +3282 3192 -93459816.96553 +3283 3192 1.579523086548e-06 +3284 3192 66889426.94725 +3285 3192 -38668381.31079 +3286 3192 -15625000.00514 +3287 3192 23108532.96245 +3303 3192 59569111.10081 +3304 3192 1.192092895508e-07 +3305 3192 -13286440.8446 +3306 3192 -16053172.23825 +3307 3192 3125000.001022 +3308 3192 -4393116.289629 +3193 3193 437188771.8336 +3194 3193 -54860518.82542 +3195 3193 -12499999.99795 +3196 3193 -60896469.18594 +3197 3193 27704564.96822 +3282 3193 -6.705522537231e-07 +3283 3193 -24709454.43242 +3284 3193 -6857568.701869 +3285 3193 -15625000.00514 +3286 3193 -33980662.73527 +3287 3193 16657951.02195 +3303 3193 -5.960464477539e-08 +3304 3193 40818236.80798 +3305 3193 -13715137.39698 +3306 3193 -3125000.001031 +3307 3193 -45740634.9339 +3308 3193 34001665.91618 +3194 3194 468617531.6838 +3195 3194 5428976.457627 +3196 3194 27155953.8572 +3197 3194 29967325.27615 +3282 3194 66546545.00303 +3283 3194 -6857568.701869 +3284 3194 -74918497.68596 +3285 3194 23108532.96245 +3286 3194 16657951.02195 +3287 3194 -47038891.18556 +3303 3194 13857934.15094 +3304 3194 -13715137.39698 +3305 3194 -65456206.19348 +3306 3194 4964592.046777 +3307 3194 34001665.91632 +3308 3194 -73885507.49175 +3195 3195 512192460.3863 +3196 3195 7.033348083496e-06 +3197 3195 -2285830.273855 +3198 3195 57853373.36857 +3199 3195 12499999.99794 +3200 3195 -4857481.874016 +3282 3195 -25604579.22317 +3283 3195 15625000.00514 +3284 3195 10250460.04156 +3285 3195 -93459816.96553 +3286 3195 1.579523086548e-06 +3287 3195 66889426.94725 +3288 3195 -38668381.31079 +3289 3195 -15625000.00514 +3290 3195 23108532.96245 +3303 3195 10751623.76428 +3304 3195 -3125000.001025 +3305 3195 -1821501.705457 +3306 3195 59569111.10081 +3307 3195 1.192092895508e-07 +3308 3195 -13286440.8446 +3309 3195 -16053172.23825 +3310 3195 3125000.001022 +3311 3195 -4393116.289629 +3196 3196 437188771.8336 +3197 3196 -54860518.82542 +3198 3196 -12499999.99795 +3199 3196 -60896469.18594 +3200 3196 27704564.96822 +3282 3196 15625000.00514 +3283 3196 -20916860.64765 +3284 3196 -9800382.320076 +3285 3196 -6.705522537231e-07 +3286 3196 -24709454.43242 +3287 3196 -6857568.701869 +3288 3196 -15625000.00514 +3289 3196 -33980662.73527 +3290 3196 16657951.02195 +3303 3196 3125000.00103 +3304 3196 -18935838.93137 +3305 3196 -20286528.5192 +3306 3196 -5.960464477539e-08 +3307 3196 40818236.80798 +3308 3196 -13715137.39698 +3309 3196 -3125000.001031 +3310 3196 -45740634.9339 +3311 3196 34001665.91618 +3197 3197 468617531.6838 +3198 3197 5428976.457627 +3199 3197 27155953.8572 +3200 3197 29967325.27615 +3282 3197 10250460.04156 +3283 3197 -9800382.320076 +3284 3197 -12202085.61857 +3285 3197 66546545.00303 +3286 3197 -6857568.701869 +3287 3197 -74918497.68596 +3288 3197 23108532.96245 +3289 3197 16657951.02195 +3290 3197 -47038891.18556 +3303 3197 2392977.462593 +3304 3197 -20286528.51934 +3305 3197 -2406051.485007 +3306 3197 13857934.15094 +3307 3197 -13715137.39698 +3308 3197 -65456206.19348 +3309 3197 4964592.046777 +3310 3197 34001665.91632 +3311 3197 -73885507.49175 +3198 3198 512192460.3863 +3199 3198 7.033348083496e-06 +3200 3198 -2285830.273855 +3201 3198 57853373.36857 +3202 3198 12499999.99794 +3203 3198 -4857481.874016 +3285 3198 -25604579.22317 +3286 3198 15625000.00514 +3287 3198 10250460.04156 +3288 3198 -93459816.96553 +3289 3198 1.579523086548e-06 +3290 3198 66889426.94725 +3291 3198 -38668381.31079 +3292 3198 -15625000.00514 +3293 3198 23108532.96245 +3306 3198 10751623.76428 +3307 3198 -3125000.001025 +3308 3198 -1821501.705457 +3309 3198 59569111.10081 +3310 3198 1.192092895508e-07 +3311 3198 -13286440.8446 +3312 3198 -16053172.23825 +3313 3198 3125000.001022 +3314 3198 -4393116.289629 +3199 3199 437188771.8336 +3200 3199 -54860518.82542 +3201 3199 -12499999.99795 +3202 3199 -60896469.18594 +3203 3199 27704564.96822 +3285 3199 15625000.00514 +3286 3199 -20916860.64765 +3287 3199 -9800382.320076 +3288 3199 -6.705522537231e-07 +3289 3199 -24709454.43242 +3290 3199 -6857568.701869 +3291 3199 -15625000.00514 +3292 3199 -33980662.73527 +3293 3199 16657951.02195 +3306 3199 3125000.00103 +3307 3199 -18935838.93137 +3308 3199 -20286528.5192 +3309 3199 -5.960464477539e-08 +3310 3199 40818236.80798 +3311 3199 -13715137.39698 +3312 3199 -3125000.001031 +3313 3199 -45740634.9339 +3314 3199 34001665.91618 +3200 3200 468617531.6838 +3201 3200 5428976.457627 +3202 3200 27155953.8572 +3203 3200 29967325.27615 +3285 3200 10250460.04156 +3286 3200 -9800382.320076 +3287 3200 -12202085.61857 +3288 3200 66546545.00303 +3289 3200 -6857568.701869 +3290 3200 -74918497.68596 +3291 3200 23108532.96245 +3292 3200 16657951.02195 +3293 3200 -47038891.18556 +3306 3200 2392977.462593 +3307 3200 -20286528.51934 +3308 3200 -2406051.485007 +3309 3200 13857934.15094 +3310 3200 -13715137.39698 +3311 3200 -65456206.19348 +3312 3200 4964592.046777 +3313 3200 34001665.91632 +3314 3200 -73885507.49175 +3201 3201 512192460.3863 +3202 3201 7.033348083496e-06 +3203 3201 -2285830.273855 +3204 3201 57853373.36857 +3205 3201 12499999.99794 +3206 3201 -4857481.874016 +3288 3201 -25604579.22317 +3289 3201 15625000.00514 +3290 3201 10250460.04156 +3291 3201 -93459816.96553 +3292 3201 1.579523086548e-06 +3293 3201 66889426.94725 +3294 3201 -38668381.31079 +3295 3201 -15625000.00514 +3296 3201 23108532.96245 +3309 3201 10751623.76428 +3310 3201 -3125000.001025 +3311 3201 -1821501.705457 +3312 3201 59569111.10081 +3313 3201 1.192092895508e-07 +3314 3201 -13286440.8446 +3315 3201 -16053172.23825 +3316 3201 3125000.001022 +3317 3201 -4393116.289629 +3202 3202 437188771.8336 +3203 3202 -54860518.82542 +3204 3202 -12499999.99795 +3205 3202 -60896469.18594 +3206 3202 27704564.96822 +3288 3202 15625000.00514 +3289 3202 -20916860.64765 +3290 3202 -9800382.320076 +3291 3202 -6.705522537231e-07 +3292 3202 -24709454.43242 +3293 3202 -6857568.701869 +3294 3202 -15625000.00514 +3295 3202 -33980662.73527 +3296 3202 16657951.02195 +3309 3202 3125000.00103 +3310 3202 -18935838.93137 +3311 3202 -20286528.5192 +3312 3202 -5.960464477539e-08 +3313 3202 40818236.80798 +3314 3202 -13715137.39698 +3315 3202 -3125000.001031 +3316 3202 -45740634.9339 +3317 3202 34001665.91618 +3203 3203 468617531.6838 +3204 3203 5428976.457627 +3205 3203 27155953.8572 +3206 3203 29967325.27615 +3288 3203 10250460.04156 +3289 3203 -9800382.320076 +3290 3203 -12202085.61857 +3291 3203 66546545.00303 +3292 3203 -6857568.701869 +3293 3203 -74918497.68596 +3294 3203 23108532.96245 +3295 3203 16657951.02195 +3296 3203 -47038891.18556 +3309 3203 2392977.462593 +3310 3203 -20286528.51934 +3311 3203 -2406051.485007 +3312 3203 13857934.15094 +3313 3203 -13715137.39698 +3314 3203 -65456206.19348 +3315 3203 4964592.046777 +3316 3203 34001665.91632 +3317 3203 -73885507.49175 +3204 3204 512192460.3863 +3205 3204 7.033348083496e-06 +3206 3204 -2285830.273855 +3207 3204 57853373.36857 +3208 3204 12499999.99794 +3209 3204 -4857481.874016 +3291 3204 -25604579.22317 +3292 3204 15625000.00514 +3293 3204 10250460.04156 +3294 3204 -93459816.96553 +3295 3204 1.579523086548e-06 +3296 3204 66889426.94725 +3297 3204 -38668381.31079 +3298 3204 -15625000.00514 +3299 3204 23108532.96245 +3312 3204 10751623.76428 +3313 3204 -3125000.001025 +3314 3204 -1821501.705457 +3315 3204 59569111.10081 +3316 3204 1.192092895508e-07 +3317 3204 -13286440.8446 +3318 3204 -16053172.23825 +3319 3204 3125000.001022 +3320 3204 -4393116.289629 +3205 3205 437188771.8336 +3206 3205 -54860518.82542 +3207 3205 -12499999.99795 +3208 3205 -60896469.18594 +3209 3205 27704564.96822 +3291 3205 15625000.00514 +3292 3205 -20916860.64765 +3293 3205 -9800382.320076 +3294 3205 -6.705522537231e-07 +3295 3205 -24709454.43242 +3296 3205 -6857568.701869 +3297 3205 -15625000.00514 +3298 3205 -33980662.73527 +3299 3205 16657951.02195 +3312 3205 3125000.00103 +3313 3205 -18935838.93137 +3314 3205 -20286528.5192 +3315 3205 -5.960464477539e-08 +3316 3205 40818236.80798 +3317 3205 -13715137.39698 +3318 3205 -3125000.001031 +3319 3205 -45740634.9339 +3320 3205 34001665.91618 +3206 3206 468617531.6838 +3207 3206 5428976.457627 +3208 3206 27155953.8572 +3209 3206 29967325.27615 +3291 3206 10250460.04156 +3292 3206 -9800382.320076 +3293 3206 -12202085.61857 +3294 3206 66546545.00303 +3295 3206 -6857568.701869 +3296 3206 -74918497.68596 +3297 3206 23108532.96245 +3298 3206 16657951.02195 +3299 3206 -47038891.18556 +3312 3206 2392977.462593 +3313 3206 -20286528.51934 +3314 3206 -2406051.485007 +3315 3206 13857934.15094 +3316 3206 -13715137.39698 +3317 3206 -65456206.19348 +3318 3206 4964592.046777 +3319 3206 34001665.91632 +3320 3206 -73885507.49175 +3207 3207 501194760.8906 +3208 3207 483471.9809724 +3209 3207 19729280.16759 +3210 3207 44528872.06075 +3211 3207 -4114121.29889 +3212 3207 635927.0856277 +3294 3207 -25604579.22317 +3295 3207 15625000.00514 +3296 3207 10250460.04156 +3297 3207 -86013553.03927 +3298 3207 3452677.552412 +3299 3207 62017904.11412 +3300 3207 -34009408.60001 +3301 3207 -15532299.34722 +3302 3207 17899994.27348 +3315 3207 10751623.76428 +3316 3207 -3125000.001025 +3317 3207 -1821501.705457 +3318 3207 56563393.23584 +3319 3207 92650.6663835 +3320 3207 -8207569.820517 +3321 3207 -9203173.996336 +3322 3207 -513028.8756769 +3323 3207 606407.5417179 +3208 3208 437133202.0984 +3209 3208 -31817886.27979 +3210 3208 -29114121.29479 +3211 3208 -77420340.95587 +3212 3208 5468163.759479 +3294 3208 15625000.00514 +3295 3208 -20916860.64765 +3296 3208 -9800382.320076 +3297 3208 3452677.55241 +3298 3208 -21282313.77832 +3299 3208 -7081688.752109 +3300 3208 -15532299.34722 +3301 3208 -26924785.31737 +3302 3208 13861835.12055 +3315 3208 3125000.00103 +3316 3208 -18935838.93137 +3317 3208 -20286528.5192 +3318 3208 92650.66638345 +3319 3208 40212069.25493 +3320 3208 -8282245.163074 +3321 3208 -6763028.87773 +3322 3208 -39667968.43887 +3323 3208 31589009.6339 +3209 3209 455080439.0651 +3210 3209 2693218.751954 +3211 3209 5468163.759479 +3212 3209 41134895.59769 +3294 3209 10250460.04156 +3295 3209 -9800382.320076 +3296 3209 -12202085.61857 +3297 3209 63732313.83809 +3298 3209 -7081688.751431 +3299 3209 -72268828.96409 +3300 3209 17899994.27348 +3301 3209 13861835.12055 +3302 3209 -31035642.9065 +3315 3209 2392977.462593 +3316 3209 -20286528.51934 +3317 3209 -2406051.485007 +3318 3209 18936249.61947 +3319 3209 -8282245.163075 +3320 3209 -69887100.3344 +3321 3209 7906546.432157 +3322 3209 31589009.63336 +3323 3209 -45575484.98117 +3210 3210 481849890.3224 +3211 3210 15010015.02383 +3212 3210 -426689.5447848 +3213 3210 -107360334.9424 +3214 3210 -67453663.6725 +3215 3210 856135.6311209 +3216 3210 41478841.44736 +3217 3210 2004071.538552 +3218 3210 -243668.8036907 +3297 3210 -23450146.25553 +3298 3210 14893505.44767 +3299 3210 11987471.93075 +3300 3210 -82373339.0086 +3301 3210 4596360.426198 +3302 3210 66525939.76111 +3318 3210 -3847546.99128 +3319 3210 -6763028.877732 +3320 3210 -6615467.456925 +3321 3210 37962745.80211 +3322 3210 3192182.501996 +3323 3210 -13435900.63133 +3324 3210 -38261419.07277 +3325 3210 -16725844.72742 +3326 3210 20523831.22127 +3327 3210 -11797802.80594 +3328 3210 806825.2292982 +3329 3210 509819.6200195 +3211 3211 486564576.3674 +3212 3211 -8519439.366185 +3213 3211 -67453663.6725 +3214 3211 -83396331.77573 +3215 3211 547642.7682181 +3216 3211 -22995928.45734 +3217 3211 -78124241.55322 +3218 3211 1684508.447692 +3297 3211 14893505.44767 +3298 3211 -30624986.4298 +3299 3211 -15617926.44635 +3300 3211 4596360.426197 +3301 3211 -19701625.24124 +3302 3211 -3968612.617741 +3318 3211 -513028.8756778 +3319 3211 -34312341.43383 +3320 3211 -28888420.91165 +3321 3211 3192182.501998 +3322 3211 37009258.52328 +3323 3211 -2072638.533522 +3324 3211 -16725844.72742 +3325 3211 -32459566.88009 +3326 3211 16801283.08314 +3327 3211 -5443174.772755 +3328 3211 -41678246.87034 +3329 3211 33746315.42611 +3212 3212 495996266.0283 +3213 3212 856135.6311208 +3214 3212 547642.7682181 +3215 3212 -19162917.77615 +3216 3212 442095.0850828 +3217 3212 1684508.447692 +3218 3212 51813863.68401 +3297 3212 11987471.93075 +3298 3212 -15617926.44635 +3299 3212 -24174259.25437 +3300 3212 66525939.76145 +3301 3212 -3968612.617063 +3302 3212 -86748339.75803 +3318 3212 -343974.3999875 +3319 3212 -28888420.91233 +3320 3212 -31293812.96768 +3321 3212 13291252.14205 +3322 3212 -2072638.533522 +3323 3212 -98128494.52017 +3324 3212 20523831.22127 +3325 3212 16801283.08314 +3326 3212 -36507076.17412 +3327 3212 7259021.011803 +3328 3212 33746315.42611 +3329 3212 -47861372.87769 +3213 3213 274109986.6413 +3214 3213 71818726.25164 +3215 3213 -467979.8463044 +3216 3213 -89889442.78013 +3217 3213 -7546336.315187 +3218 3213 -284665.7239107 +3300 3213 -7219965.39104 +3301 3213 1039795.885773 +3302 3213 166199.6820345 +3321 3213 -37712807.96149 +3322 3213 -16725844.72742 +3323 3213 -20101168.79207 +3324 3213 18907354.30941 +3325 3213 17710204.12039 +3326 3213 8010333.882971 +3327 3213 -46474803.17729 +3328 3213 -2024155.278742 +3329 3213 -36825364.77294 +3214 3214 243219901.3759 +3215 3214 -506062.6240954 +3216 3214 17453663.68071 +3217 3214 38490304.02822 +3218 3214 -547642.7682143 +3300 3214 -5210204.116281 +3301 3214 -37556673.13449 +3302 3214 -33207849.78238 +3321 3214 -16725844.72742 +3322 3214 -31910955.76881 +3323 3214 -16532050.26114 +3324 3214 17710204.12039 +3325 3214 11158124.54034 +3326 3214 6541183.120091 +3327 3214 4225844.723312 +3328 3214 -14190717.85745 +3329 3214 3198716.923426 +3215 3215 280391387.7469 +3216 3215 -284665.7239074 +3217 3215 -547642.7682146 +3218 3215 51757260.42444 +3300 3215 -7958800.319788 +3301 3215 -33207849.78238 +3302 3215 -46649232.44314 +3321 3215 -20101168.79207 +3322 3215 -16532050.26114 +3323 3215 -35044113.21069 +3324 3215 -8239666.11436 +3325 3215 -6792150.211052 +3326 3215 -61832834.65378 +3327 3215 -36825364.77378 +3328 3215 -3467949.74543 +3329 3215 -49807745.61347 +3216 3216 238211408.5094 +3217 3216 -52004071.53035 +3218 3216 -670683.0487667 +3300 3216 -26108511.08268 +3301 3216 14524155.28285 +3302 3216 16227129.83098 +3321 3216 -10151969.47316 +3322 3216 -5443174.772757 +3323 3216 -7054937.323181 +3324 3216 -46474803.17728 +3325 3216 4225844.723317 +3326 3216 36688437.29824 +3327 3216 15734839.28688 +3328 3216 -13306825.23341 +3329 3216 -6736949.250256 +3217 3217 237696001.9464 +3218 3217 -1684508.447682 +3300 3217 14524155.28285 +3301 3217 -27559344.43926 +3302 3217 -16532050.26114 +3321 3217 806825.2292974 +3322 3217 -40032413.53758 +3323 3217 -32920351.2296 +3324 3217 -2024155.278737 +3325 3217 -14190717.85745 +3326 3217 3198716.923426 +3327 3217 -13306825.2334 +3328 3217 14782031.38802 +3329 3217 6253684.567311 +3218 3218 253592341.1342 +3300 3218 16227129.83098 +3301 3218 -16532050.26114 +3302 3218 -30692501.88114 +3321 3218 -648617.8757846 +3322 3218 -32920351.2296 +3323 3218 -43472483.99027 +3324 3218 36688437.29756 +3325 3218 -3467949.745429 +3326 3218 -49807745.61347 +3327 3218 6418571.580917 +3328 3218 -7079648.763832 +3329 3218 -54695120.37178 +3219 3219 661240911.694 +3220 3219 62499999.98975 +3221 3219 26309808.76172 +3222 3219 -351489360.7944 +3223 3219 -62521288.22773 +3224 3219 -26300660.30375 +3225 3219 7540034.174547 +3226 3219 50021288.22979 +3227 3219 -21267537.14313 +3330 3219 76701211.16396 +3331 3219 15625000.00514 +3332 3219 21009550.22758 +3333 3219 -125983237.2565 +3334 3219 -15630322.06463 +3335 3219 -74621947.50591 +3336 3219 -24799837.07904 +3337 3219 12505322.06361 +3338 3219 -18723479.73292 +3220 3220 567462589.8818 +3221 3220 -68593390.60176 +3222 3220 -62531932.34673 +3223 3220 -57670510.07978 +3224 3220 -38001573.29657 +3225 3220 75031932.34468 +3226 3220 7540034.174547 +3227 3220 23874977.56666 +3330 3220 15625000.00514 +3331 3220 53256630.69937 +3332 3220 -5602780.460976 +3333 3220 -15632983.09438 +3334 3220 -52528524.54163 +3335 3220 -23113573.91808 +3336 3220 18757983.09541 +3337 3220 -24799837.07904 +3338 3220 22467775.67917 +3221 3221 641486746.383 +3222 3221 -26296086.07475 +3223 3221 -30591858.55204 +3224 3221 -15523139.55333 +3225 3221 -31901305.7147 +3226 3221 15916651.71111 +3227 3221 20106757.79879 +3330 3221 -6140600.947398 +3331 3221 -27322678.94813 +3332 3221 -75919024.90121 +3333 3221 -74277994.97009 +3334 3221 -21190287.58241 +3335 3221 -105509843.5958 +3336 3221 -28085219.59939 +3337 3221 14978517.11945 +3338 3221 -66132898.87745 +3222 3222 1128168022.401 +3223 3222 62553220.58474 +3224 3222 30858743.66929 +3225 3222 17446621.74987 +3226 3222 -62521288.22774 +3227 3222 26696512.96211 +3228 3222 -239474705.9488 +3229 3222 2.950429916382e-06 +3230 3222 -4571806.052598 +3231 3222 -95620685.86526 +3232 3222 62499999.98975 +3233 3222 -26687656.37071 +3330 3222 -111681734.2619 +3331 3222 -15632983.09438 +3332 3222 61472760.90482 +3333 3222 149252626.5636 +3334 3222 15638305.15389 +3335 3222 7711980.245565 +3336 3222 -47230742.81426 +3337 3222 -15630322.06464 +3338 3222 23688071.7797 +3339 3222 -97033826.33989 +3340 3222 1.400709152222e-06 +3341 3222 -69175329.97466 +3342 3222 -39900479.57507 +3343 3222 15625000.00513 +3344 3222 -23680008.71958 +3223 3223 959386203.4543 +3224 3223 -85034422.38434 +3225 3223 -62531932.34674 +3226 3223 -201344781.4455 +3227 3223 45541679.93477 +3228 3223 2.920627593994e-06 +3229 3223 35526744.0481 +3230 3223 -27430274.79396 +3231 3223 62499999.98974 +3232 3223 -76869811.57243 +3233 3223 14949512.39685 +3330 3223 -15630322.06464 +3331 3223 -38227021.54706 +3332 3223 5963051.430523 +3333 3223 15638305.15389 +3334 3223 107057171.8061 +3335 3223 -21260770.12636 +3336 3223 -15632983.09439 +3337 3223 -101928593.64 +3338 3223 65822290.07648 +3339 3223 7.450580596924e-07 +3340 3223 -28283463.80681 +3341 3223 -6857568.701869 +3342 3223 15625000.00513 +3343 3223 -35212760.99956 +3344 3223 17343714.91106 +3224 3224 989397032.1941 +3225 3224 27043823.20204 +3226 3224 53225583.49043 +3227 3224 22257684.43985 +3228 3224 -4571806.052597 +3229 3224 -27430274.79396 +3230 3224 58631507.34796 +3231 3224 -27030538.31493 +3232 3224 15223817.95222 +3233 3224 -30681326.51173 +3330 3224 61128808.369 +3331 3224 4044385.985747 +3332 3224 -67372502.27695 +3333 3224 7717756.425008 +3334 3224 -21256149.23011 +3335 3224 -106755752.9646 +3336 3224 23692103.30976 +3337 3224 67469018.6918 +3338 3224 -132015307.5643 +3339 3224 -68832448.03044 +3340 3224 -6857568.701869 +3341 3224 -84449189.35104 +3342 3224 -23680008.71958 +3343 3224 17343714.91106 +3344 3224 -50324486.557 +3225 3225 661240911.694 +3226 3225 62499999.98975 +3227 3225 26309808.76172 +3228 3225 -94266302.18495 +3229 3225 -62499999.98975 +3230 3225 24744635.2875 +3231 3225 -351489360.7944 +3232 3225 -62521288.22773 +3233 3225 -26300660.30375 +3234 3225 7540034.174547 +3235 3225 50021288.22979 +3236 3225 -21267537.14313 +3330 3225 2016499.187392 +3331 3225 18757983.09541 +3332 3225 12648670.74487 +3333 3225 -6124104.06778 +3334 3225 -15632983.09438 +3335 3225 -10255693.28227 +3336 3225 76701211.16396 +3337 3225 15625000.00514 +3338 3225 21009550.22758 +3339 3225 -26159485.64696 +3340 3225 -15625000.00513 +3341 3225 -10821935.79869 +3342 3225 -125983237.2565 +3343 3225 -15630322.06463 +3344 3225 -74621947.50591 +3345 3225 -24799837.07904 +3346 3225 12505322.06361 +3347 3225 -18723479.73292 +3226 3226 567462589.8818 +3227 3226 -68593390.60176 +3228 3226 -62499999.98975 +3229 3226 -75515427.89211 +3230 3226 12480762.39712 +3231 3226 -62531932.34673 +3232 3226 -57670510.07978 +3233 3226 -38001573.29657 +3234 3226 75031932.34468 +3235 3226 7540034.174547 +3236 3226 23874977.56666 +3330 3226 12505322.06361 +3331 3226 2016499.187392 +3332 3226 -6746002.447256 +3333 3226 -15630322.06463 +3334 3226 -60821954.89356 +3335 3226 -41130474.11058 +3336 3226 15625000.00514 +3337 3226 53256630.69937 +3338 3226 -5602780.460976 +3339 3226 -15625000.00513 +3340 3226 -21471767.07144 +3341 3226 -10486146.20919 +3342 3226 -15632983.09438 +3343 3226 -52528524.54163 +3344 3226 -23113573.91808 +3345 3226 18757983.09541 +3346 3226 -24799837.07904 +3347 3226 22467775.67917 +3227 3227 641486746.383 +3228 3227 24401753.34329 +3229 3227 12206456.84174 +3230 3227 -27069636.69752 +3231 3227 -26296086.07475 +3232 3227 -30591858.55204 +3233 3227 -15523139.55333 +3234 3227 -31901305.7147 +3235 3227 15916651.71111 +3236 3227 20106757.79879 +3330 3227 8432447.163244 +3331 3227 -10119003.67088 +3332 3227 5377331.166378 +3333 3227 -10253948.8687 +3334 3227 -42777202.9092 +3335 3227 -22397604.24035 +3336 3227 -6140600.947398 +3337 3227 -27322678.94813 +3338 3227 -75919024.90121 +3339 3227 -10821935.79869 +3340 3227 -10486146.20919 +3341 3227 -13681836.08202 +3342 3227 -74277994.97009 +3343 3227 -21190287.58241 +3344 3227 -105509843.5958 +3345 3227 -28085219.59939 +3346 3227 14978517.11945 +3347 3227 -66132898.87745 +3228 3228 1042603210.19 +3229 3228 2.193450927734e-05 +3230 3228 9143612.105123 +3231 3228 120306386.5889 +3232 3228 -9.268522262573e-06 +3233 3228 2285903.027413 +3237 3228 -239474705.9488 +3238 3228 2.950429916382e-06 +3239 3228 -4571806.052598 +3240 3228 -95620685.86526 +3241 3228 62499999.98975 +3242 3228 -26687656.37071 +3333 3228 -93459816.96553 +3334 3228 1.579523086548e-06 +3335 3228 66889426.94725 +3336 3228 -38668381.31079 +3337 3228 -15625000.00514 +3338 3228 23108532.96245 +3339 3228 119183368.3243 +3340 3228 4.112720489502e-06 +3341 3228 2285903.027438 +3342 3228 -32106344.47651 +3343 3228 -9.387731552124e-06 +3344 3228 571475.757148 +3348 3228 -97033826.33989 +3349 3228 1.400709152222e-06 +3350 3228 -69175329.97466 +3351 3228 -39900479.57507 +3352 3228 15625000.00513 +3353 3228 -23680008.71958 +3229 3229 892596215.9216 +3230 3229 -109721099.1218 +3231 3229 -9.95397567749e-06 +3232 3229 -117193314.8593 +3233 3229 54860549.56089 +3237 3229 2.920627593994e-06 +3238 3229 35526744.0481 +3239 3229 -27430274.79396 +3240 3229 62499999.98974 +3241 3229 -76869811.57243 +3242 3229 14949512.39685 +3333 3229 -6.705522537231e-07 +3334 3229 -24709454.43242 +3335 3229 -6857568.701869 +3336 3229 -15625000.00514 +3337 3229 -33980662.73527 +3338 3229 16657951.02195 +3339 3229 4.053115844727e-06 +3340 3229 81681619.73861 +3341 3229 -27430274.79396 +3342 3229 -8.40425491333e-06 +3343 3229 -91481269.86781 +3344 3229 68140484.61019 +3348 3229 7.450580596924e-07 +3349 3229 -28283463.80681 +3350 3229 -6857568.701869 +3351 3229 15625000.00513 +3352 3229 -35212760.99956 +3353 3229 17343714.91106 +3230 3230 985817875.0266 +3231 3230 2285903.027413 +3232 3230 54860549.56089 +3233 3230 72200645.50821 +3237 3230 -4571806.052597 +3238 3230 -27430274.79396 +3239 3230 58631507.34796 +3240 3230 -27030538.31493 +3241 3230 15223817.95222 +3242 3230 -30681326.51173 +3333 3230 66546545.00303 +3334 3230 -6857568.701869 +3335 3230 -74918497.68596 +3336 3230 23108532.96245 +3337 3230 16657951.02195 +3338 3230 -47038891.18556 +3339 3230 2285903.027438 +3340 3230 -27430274.79396 +3341 3230 -130792022.7266 +3342 3230 571475.7571481 +3343 3230 67866179.05482 +3344 3230 -147771014.9835 +3348 3230 -68832448.03044 +3349 3230 -6857568.701869 +3350 3230 -84449189.35104 +3351 3230 -23680008.71958 +3352 3230 17343714.91106 +3353 3230 -50324486.557 +3231 3231 1128168022.401 +3232 3231 62553220.58474 +3233 3231 30858743.66929 +3234 3231 17446621.74987 +3235 3231 -62521288.22774 +3236 3231 26696512.96211 +3237 3231 -94266302.18495 +3238 3231 -62499999.98975 +3239 3231 24744635.2875 +3240 3231 -239474705.9488 +3241 3231 2.950429916382e-06 +3242 3231 -4571806.052598 +3243 3231 -95620685.86526 +3244 3231 62499999.98975 +3245 3231 -26687656.37071 +3333 3231 -25604579.22317 +3334 3231 15625000.00514 +3335 3231 10250460.04156 +3336 3231 -111681734.2619 +3337 3231 -15632983.09438 +3338 3231 61472760.90482 +3339 3231 21503247.52855 +3340 3231 3.844499588013e-06 +3341 3231 571475.7571353 +3342 3231 149252626.5636 +3343 3231 15638305.15389 +3344 3231 7711980.245565 +3345 3231 -47230742.81426 +3346 3231 -15630322.06464 +3347 3231 23688071.7797 +3348 3231 -26159485.64696 +3349 3231 -15625000.00513 +3350 3231 -10821935.79869 +3351 3231 -97033826.33989 +3352 3231 1.400709152222e-06 +3353 3231 -69175329.97466 +3354 3231 -39900479.57507 +3355 3231 15625000.00513 +3356 3231 -23680008.71958 +3232 3232 959386203.4543 +3233 3232 -85034422.38434 +3234 3232 -62531932.34674 +3235 3232 -201344781.4455 +3236 3232 45541679.93477 +3237 3232 -62499999.98975 +3238 3232 -75515427.89211 +3239 3232 12480762.39712 +3240 3232 2.920627593994e-06 +3241 3232 35526744.0481 +3242 3232 -27430274.79396 +3243 3232 62499999.98974 +3244 3232 -76869811.57243 +3245 3232 14949512.39685 +3333 3232 15625000.00514 +3334 3232 -20916860.64765 +3335 3232 -9800382.320076 +3336 3232 -15630322.06464 +3337 3232 -38227021.54706 +3338 3232 5963051.430523 +3339 3232 5.88595867157e-06 +3340 3232 -37871677.86274 +3341 3232 -40710209.81623 +3342 3232 15638305.15389 +3343 3232 107057171.8061 +3344 3232 -21260770.12636 +3345 3232 -15632983.09439 +3346 3232 -101928593.64 +3347 3232 65822290.07648 +3348 3232 -15625000.00513 +3349 3232 -21471767.07144 +3350 3232 -10486146.20919 +3351 3232 7.450580596924e-07 +3352 3232 -28283463.80681 +3353 3232 -6857568.701869 +3354 3232 15625000.00513 +3355 3232 -35212760.99956 +3356 3232 17343714.91106 +3233 3233 989397032.1941 +3234 3233 27043823.20204 +3235 3233 53225583.49043 +3236 3233 22257684.43985 +3237 3233 24401753.34329 +3238 3233 12206456.84174 +3239 3233 -27069636.69752 +3240 3233 -4571806.052597 +3241 3233 -27430274.79396 +3242 3233 58631507.34796 +3243 3233 -27030538.31493 +3244 3233 15223817.95222 +3245 3233 -30681326.51173 +3333 3233 10250460.04156 +3334 3233 -9800382.320076 +3335 3233 -12202085.61857 +3336 3233 61128808.369 +3337 3233 4044385.985747 +3338 3233 -67372502.27695 +3339 3233 571475.7571355 +3340 3233 -40435904.26086 +3341 3233 -4812102.970013 +3342 3233 7717756.425008 +3343 3233 -21256149.23011 +3344 3233 -106755752.9646 +3345 3233 23692103.30976 +3346 3233 67469018.6918 +3347 3233 -132015307.5643 +3348 3233 -10821935.79869 +3349 3233 -10486146.20919 +3350 3233 -13681836.08202 +3351 3233 -68832448.03044 +3352 3233 -6857568.701869 +3353 3233 -84449189.35104 +3354 3233 -23680008.71958 +3355 3233 17343714.91106 +3356 3233 -50324486.557 +3234 3234 661240911.694 +3235 3234 62499999.98975 +3236 3234 26309808.76172 +3240 3234 -94266302.18495 +3241 3234 -62499999.98975 +3242 3234 24744635.2875 +3243 3234 -351489360.7944 +3244 3234 -62521288.22773 +3245 3234 -26300660.30375 +3246 3234 7540034.174547 +3247 3234 50021288.22979 +3248 3234 -21267537.14313 +3336 3234 2016499.187392 +3337 3234 18757983.09541 +3338 3234 12648670.74487 +3342 3234 -6124104.06778 +3343 3234 -15632983.09438 +3344 3234 -10255693.28227 +3345 3234 76701211.16396 +3346 3234 15625000.00514 +3347 3234 21009550.22758 +3351 3234 -26159485.64696 +3352 3234 -15625000.00513 +3353 3234 -10821935.79869 +3354 3234 -125983237.2565 +3355 3234 -15630322.06463 +3356 3234 -74621947.50591 +3357 3234 -24799837.07904 +3358 3234 12505322.06361 +3359 3234 -18723479.73292 +3235 3235 567462589.8818 +3236 3235 -68593390.60176 +3240 3235 -62499999.98975 +3241 3235 -75515427.89211 +3242 3235 12480762.39712 +3243 3235 -62531932.34673 +3244 3235 -57670510.07978 +3245 3235 -38001573.29657 +3246 3235 75031932.34468 +3247 3235 7540034.174547 +3248 3235 23874977.56666 +3336 3235 12505322.06361 +3337 3235 2016499.187392 +3338 3235 -6746002.447256 +3342 3235 -15630322.06463 +3343 3235 -60821954.89356 +3344 3235 -41130474.11058 +3345 3235 15625000.00514 +3346 3235 53256630.69937 +3347 3235 -5602780.460976 +3351 3235 -15625000.00513 +3352 3235 -21471767.07144 +3353 3235 -10486146.20919 +3354 3235 -15632983.09438 +3355 3235 -52528524.54163 +3356 3235 -23113573.91808 +3357 3235 18757983.09541 +3358 3235 -24799837.07904 +3359 3235 22467775.67917 +3236 3236 641486746.383 +3240 3236 24401753.34329 +3241 3236 12206456.84174 +3242 3236 -27069636.69752 +3243 3236 -26296086.07475 +3244 3236 -30591858.55204 +3245 3236 -15523139.55333 +3246 3236 -31901305.7147 +3247 3236 15916651.71111 +3248 3236 20106757.79879 +3336 3236 8432447.163244 +3337 3236 -10119003.67088 +3338 3236 5377331.166378 +3342 3236 -10253948.8687 +3343 3236 -42777202.9092 +3344 3236 -22397604.24035 +3345 3236 -6140600.947398 +3346 3236 -27322678.94813 +3347 3236 -75919024.90121 +3351 3236 -10821935.79869 +3352 3236 -10486146.20919 +3353 3236 -13681836.08202 +3354 3236 -74277994.97009 +3355 3236 -21190287.58241 +3356 3236 -105509843.5958 +3357 3236 -28085219.59939 +3358 3236 14978517.11945 +3359 3236 -66132898.87745 +3237 3237 1042603210.19 +3238 3237 2.193450927734e-05 +3239 3237 9143612.105123 +3240 3237 120306386.5889 +3241 3237 -9.268522262573e-06 +3242 3237 2285903.027413 +3249 3237 -239474705.9488 +3250 3237 2.950429916382e-06 +3251 3237 -4571806.052598 +3252 3237 -95620685.86526 +3253 3237 62499999.98975 +3254 3237 -26687656.37071 +3339 3237 -93459816.96553 +3340 3237 1.579523086548e-06 +3341 3237 66889426.94725 +3342 3237 -38668381.31079 +3343 3237 -15625000.00514 +3344 3237 23108532.96245 +3348 3237 119183368.3243 +3349 3237 4.112720489502e-06 +3350 3237 2285903.027438 +3351 3237 -32106344.47651 +3352 3237 -9.387731552124e-06 +3353 3237 571475.757148 +3360 3237 -97033826.33989 +3361 3237 1.400709152222e-06 +3362 3237 -69175329.97466 +3363 3237 -39900479.57507 +3364 3237 15625000.00513 +3365 3237 -23680008.71958 +3238 3238 892596215.9216 +3239 3238 -109721099.1218 +3240 3238 -9.95397567749e-06 +3241 3238 -117193314.8593 +3242 3238 54860549.56089 +3249 3238 2.920627593994e-06 +3250 3238 35526744.0481 +3251 3238 -27430274.79396 +3252 3238 62499999.98974 +3253 3238 -76869811.57243 +3254 3238 14949512.39685 +3339 3238 -6.705522537231e-07 +3340 3238 -24709454.43242 +3341 3238 -6857568.701869 +3342 3238 -15625000.00514 +3343 3238 -33980662.73527 +3344 3238 16657951.02195 +3348 3238 4.053115844727e-06 +3349 3238 81681619.73861 +3350 3238 -27430274.79396 +3351 3238 -8.40425491333e-06 +3352 3238 -91481269.86781 +3353 3238 68140484.61019 +3360 3238 7.450580596924e-07 +3361 3238 -28283463.80681 +3362 3238 -6857568.701869 +3363 3238 15625000.00513 +3364 3238 -35212760.99956 +3365 3238 17343714.91106 +3239 3239 985817875.0266 +3240 3239 2285903.027413 +3241 3239 54860549.56089 +3242 3239 72200645.50821 +3249 3239 -4571806.052597 +3250 3239 -27430274.79396 +3251 3239 58631507.34796 +3252 3239 -27030538.31493 +3253 3239 15223817.95222 +3254 3239 -30681326.51173 +3339 3239 66546545.00303 +3340 3239 -6857568.701869 +3341 3239 -74918497.68596 +3342 3239 23108532.96245 +3343 3239 16657951.02195 +3344 3239 -47038891.18556 +3348 3239 2285903.027438 +3349 3239 -27430274.79396 +3350 3239 -130792022.7266 +3351 3239 571475.7571481 +3352 3239 67866179.05482 +3353 3239 -147771014.9835 +3360 3239 -68832448.03044 +3361 3239 -6857568.701869 +3362 3239 -84449189.35104 +3363 3239 -23680008.71958 +3364 3239 17343714.91106 +3365 3239 -50324486.557 +3240 3240 1042603210.19 +3241 3240 2.193450927734e-05 +3242 3240 9143612.105123 +3243 3240 120306386.5889 +3244 3240 -9.268522262573e-06 +3245 3240 2285903.027413 +3249 3240 -94266302.18495 +3250 3240 -62499999.98975 +3251 3240 24744635.2875 +3252 3240 -239474705.9488 +3253 3240 2.950429916382e-06 +3254 3240 -4571806.052598 +3255 3240 -95620685.86526 +3256 3240 62499999.98975 +3257 3240 -26687656.37071 +3339 3240 -25604579.22317 +3340 3240 15625000.00514 +3341 3240 10250460.04156 +3342 3240 -93459816.96553 +3343 3240 1.579523086548e-06 +3344 3240 66889426.94725 +3345 3240 -38668381.31079 +3346 3240 -15625000.00514 +3347 3240 23108532.96245 +3348 3240 21503247.52855 +3349 3240 3.844499588013e-06 +3350 3240 571475.7571353 +3351 3240 119183368.3243 +3352 3240 4.112720489502e-06 +3353 3240 2285903.027438 +3354 3240 -32106344.47651 +3355 3240 -9.387731552124e-06 +3356 3240 571475.757148 +3360 3240 -26159485.64696 +3361 3240 -15625000.00513 +3362 3240 -10821935.79869 +3363 3240 -97033826.33989 +3364 3240 1.400709152222e-06 +3365 3240 -69175329.97466 +3366 3240 -39900479.57507 +3367 3240 15625000.00513 +3368 3240 -23680008.71958 +3241 3241 892596215.9216 +3242 3241 -109721099.1218 +3243 3241 -9.95397567749e-06 +3244 3241 -117193314.8593 +3245 3241 54860549.56089 +3249 3241 -62499999.98975 +3250 3241 -75515427.89211 +3251 3241 12480762.39712 +3252 3241 2.920627593994e-06 +3253 3241 35526744.0481 +3254 3241 -27430274.79396 +3255 3241 62499999.98974 +3256 3241 -76869811.57243 +3257 3241 14949512.39685 +3339 3241 15625000.00514 +3340 3241 -20916860.64765 +3341 3241 -9800382.320076 +3342 3241 -6.705522537231e-07 +3343 3241 -24709454.43242 +3344 3241 -6857568.701869 +3345 3241 -15625000.00514 +3346 3241 -33980662.73527 +3347 3241 16657951.02195 +3348 3241 5.88595867157e-06 +3349 3241 -37871677.86274 +3350 3241 -40710209.81623 +3351 3241 4.053115844727e-06 +3352 3241 81681619.73861 +3353 3241 -27430274.79396 +3354 3241 -8.40425491333e-06 +3355 3241 -91481269.86781 +3356 3241 68140484.61019 +3360 3241 -15625000.00513 +3361 3241 -21471767.07144 +3362 3241 -10486146.20919 +3363 3241 7.450580596924e-07 +3364 3241 -28283463.80681 +3365 3241 -6857568.701869 +3366 3241 15625000.00513 +3367 3241 -35212760.99956 +3368 3241 17343714.91106 +3242 3242 985817875.0266 +3243 3242 2285903.027413 +3244 3242 54860549.56089 +3245 3242 72200645.50821 +3249 3242 24401753.34329 +3250 3242 12206456.84174 +3251 3242 -27069636.69752 +3252 3242 -4571806.052597 +3253 3242 -27430274.79396 +3254 3242 58631507.34796 +3255 3242 -27030538.31493 +3256 3242 15223817.95222 +3257 3242 -30681326.51173 +3339 3242 10250460.04156 +3340 3242 -9800382.320076 +3341 3242 -12202085.61857 +3342 3242 66546545.00303 +3343 3242 -6857568.701869 +3344 3242 -74918497.68596 +3345 3242 23108532.96245 +3346 3242 16657951.02195 +3347 3242 -47038891.18556 +3348 3242 571475.7571355 +3349 3242 -40435904.26086 +3350 3242 -4812102.970013 +3351 3242 2285903.027438 +3352 3242 -27430274.79396 +3353 3242 -130792022.7266 +3354 3242 571475.7571481 +3355 3242 67866179.05482 +3356 3242 -147771014.9835 +3360 3242 -10821935.79869 +3361 3242 -10486146.20919 +3362 3242 -13681836.08202 +3363 3242 -68832448.03044 +3364 3242 -6857568.701869 +3365 3242 -84449189.35104 +3366 3242 -23680008.71958 +3367 3242 17343714.91106 +3368 3242 -50324486.557 +3243 3243 1128168022.401 +3244 3243 62553220.58474 +3245 3243 30858743.66929 +3246 3243 17446621.74987 +3247 3243 -62521288.22774 +3248 3243 26696512.96211 +3252 3243 -94266302.18495 +3253 3243 -62499999.98975 +3254 3243 24744635.2875 +3255 3243 -239474705.9488 +3256 3243 2.950429916382e-06 +3257 3243 -4571806.052598 +3258 3243 -95620685.86526 +3259 3243 62499999.98975 +3260 3243 -26687656.37071 +3342 3243 -25604579.22317 +3343 3243 15625000.00514 +3344 3243 10250460.04156 +3345 3243 -111681734.2619 +3346 3243 -15632983.09438 +3347 3243 61472760.90482 +3351 3243 21503247.52855 +3352 3243 3.844499588013e-06 +3353 3243 571475.7571353 +3354 3243 149252626.5636 +3355 3243 15638305.15389 +3356 3243 7711980.245565 +3357 3243 -47230742.81426 +3358 3243 -15630322.06464 +3359 3243 23688071.7797 +3363 3243 -26159485.64696 +3364 3243 -15625000.00513 +3365 3243 -10821935.79869 +3366 3243 -97033826.33989 +3367 3243 1.400709152222e-06 +3368 3243 -69175329.97466 +3369 3243 -39900479.57507 +3370 3243 15625000.00513 +3371 3243 -23680008.71958 +3244 3244 959386203.4543 +3245 3244 -85034422.38434 +3246 3244 -62531932.34674 +3247 3244 -201344781.4455 +3248 3244 45541679.93477 +3252 3244 -62499999.98975 +3253 3244 -75515427.89211 +3254 3244 12480762.39712 +3255 3244 2.920627593994e-06 +3256 3244 35526744.0481 +3257 3244 -27430274.79396 +3258 3244 62499999.98974 +3259 3244 -76869811.57243 +3260 3244 14949512.39685 +3342 3244 15625000.00514 +3343 3244 -20916860.64765 +3344 3244 -9800382.320076 +3345 3244 -15630322.06464 +3346 3244 -38227021.54706 +3347 3244 5963051.430523 +3351 3244 5.88595867157e-06 +3352 3244 -37871677.86274 +3353 3244 -40710209.81623 +3354 3244 15638305.15389 +3355 3244 107057171.8061 +3356 3244 -21260770.12636 +3357 3244 -15632983.09439 +3358 3244 -101928593.64 +3359 3244 65822290.07648 +3363 3244 -15625000.00513 +3364 3244 -21471767.07144 +3365 3244 -10486146.20919 +3366 3244 7.450580596924e-07 +3367 3244 -28283463.80681 +3368 3244 -6857568.701869 +3369 3244 15625000.00513 +3370 3244 -35212760.99956 +3371 3244 17343714.91106 +3245 3245 989397032.1941 +3246 3245 27043823.20204 +3247 3245 53225583.49043 +3248 3245 22257684.43985 +3252 3245 24401753.34329 +3253 3245 12206456.84174 +3254 3245 -27069636.69752 +3255 3245 -4571806.052597 +3256 3245 -27430274.79396 +3257 3245 58631507.34796 +3258 3245 -27030538.31493 +3259 3245 15223817.95222 +3260 3245 -30681326.51173 +3342 3245 10250460.04156 +3343 3245 -9800382.320076 +3344 3245 -12202085.61857 +3345 3245 61128808.369 +3346 3245 4044385.985747 +3347 3245 -67372502.27695 +3351 3245 571475.7571355 +3352 3245 -40435904.26086 +3353 3245 -4812102.970013 +3354 3245 7717756.425008 +3355 3245 -21256149.23011 +3356 3245 -106755752.9646 +3357 3245 23692103.30976 +3358 3245 67469018.6918 +3359 3245 -132015307.5643 +3363 3245 -10821935.79869 +3364 3245 -10486146.20919 +3365 3245 -13681836.08202 +3366 3245 -68832448.03044 +3367 3245 -6857568.701869 +3368 3245 -84449189.35104 +3369 3245 -23680008.71958 +3370 3245 17343714.91106 +3371 3245 -50324486.557 +3246 3246 661240911.694 +3247 3246 62499999.98975 +3248 3246 26309808.76172 +3255 3246 -94266302.18495 +3256 3246 -62499999.98975 +3257 3246 24744635.2875 +3258 3246 -351489360.7944 +3259 3246 -62521288.22773 +3260 3246 -26300660.30375 +3261 3246 7540034.174547 +3262 3246 50021288.22979 +3263 3246 -21267537.14313 +3345 3246 2016499.187392 +3346 3246 18757983.09541 +3347 3246 12648670.74487 +3354 3246 -6124104.06778 +3355 3246 -15632983.09438 +3356 3246 -10255693.28227 +3357 3246 76701211.16396 +3358 3246 15625000.00514 +3359 3246 21009550.22758 +3366 3246 -26159485.64696 +3367 3246 -15625000.00513 +3368 3246 -10821935.79869 +3369 3246 -125983237.2565 +3370 3246 -15630322.06463 +3371 3246 -74621947.50591 +3372 3246 -24799837.07904 +3373 3246 12505322.06361 +3374 3246 -18723479.73292 +3247 3247 567462589.8818 +3248 3247 -68593390.60176 +3255 3247 -62499999.98975 +3256 3247 -75515427.89211 +3257 3247 12480762.39712 +3258 3247 -62531932.34673 +3259 3247 -57670510.07978 +3260 3247 -38001573.29657 +3261 3247 75031932.34468 +3262 3247 7540034.174547 +3263 3247 23874977.56666 +3345 3247 12505322.06361 +3346 3247 2016499.187392 +3347 3247 -6746002.447256 +3354 3247 -15630322.06463 +3355 3247 -60821954.89356 +3356 3247 -41130474.11058 +3357 3247 15625000.00514 +3358 3247 53256630.69937 +3359 3247 -5602780.460976 +3366 3247 -15625000.00513 +3367 3247 -21471767.07144 +3368 3247 -10486146.20919 +3369 3247 -15632983.09438 +3370 3247 -52528524.54163 +3371 3247 -23113573.91808 +3372 3247 18757983.09541 +3373 3247 -24799837.07904 +3374 3247 22467775.67917 +3248 3248 641486746.383 +3255 3248 24401753.34329 +3256 3248 12206456.84174 +3257 3248 -27069636.69752 +3258 3248 -26296086.07475 +3259 3248 -30591858.55204 +3260 3248 -15523139.55333 +3261 3248 -31901305.7147 +3262 3248 15916651.71111 +3263 3248 20106757.79879 +3345 3248 8432447.163244 +3346 3248 -10119003.67088 +3347 3248 5377331.166378 +3354 3248 -10253948.8687 +3355 3248 -42777202.9092 +3356 3248 -22397604.24035 +3357 3248 -6140600.947398 +3358 3248 -27322678.94813 +3359 3248 -75919024.90121 +3366 3248 -10821935.79869 +3367 3248 -10486146.20919 +3368 3248 -13681836.08202 +3369 3248 -74277994.97009 +3370 3248 -21190287.58241 +3371 3248 -105509843.5958 +3372 3248 -28085219.59939 +3373 3248 14978517.11945 +3374 3248 -66132898.87745 +3249 3249 1042603210.19 +3250 3249 2.193450927734e-05 +3251 3249 9143612.105123 +3252 3249 120306386.5889 +3253 3249 -9.268522262573e-06 +3254 3249 2285903.027413 +3264 3249 -239474705.9488 +3265 3249 2.950429916382e-06 +3266 3249 -4571806.052598 +3267 3249 -95620685.86526 +3268 3249 62499999.98975 +3269 3249 -26687656.37071 +3348 3249 -93459816.96553 +3349 3249 1.579523086548e-06 +3350 3249 66889426.94725 +3351 3249 -38668381.31079 +3352 3249 -15625000.00514 +3353 3249 23108532.96245 +3360 3249 119183368.3243 +3361 3249 4.112720489502e-06 +3362 3249 2285903.027438 +3363 3249 -32106344.47651 +3364 3249 -9.387731552124e-06 +3365 3249 571475.757148 +3375 3249 -97033826.33989 +3376 3249 1.400709152222e-06 +3377 3249 -69175329.97466 +3378 3249 -39900479.57507 +3379 3249 15625000.00513 +3380 3249 -23680008.71958 +3250 3250 892596215.9216 +3251 3250 -109721099.1218 +3252 3250 -9.95397567749e-06 +3253 3250 -117193314.8593 +3254 3250 54860549.56089 +3264 3250 2.920627593994e-06 +3265 3250 35526744.0481 +3266 3250 -27430274.79396 +3267 3250 62499999.98974 +3268 3250 -76869811.57243 +3269 3250 14949512.39685 +3348 3250 -6.705522537231e-07 +3349 3250 -24709454.43242 +3350 3250 -6857568.701869 +3351 3250 -15625000.00514 +3352 3250 -33980662.73527 +3353 3250 16657951.02195 +3360 3250 4.053115844727e-06 +3361 3250 81681619.73861 +3362 3250 -27430274.79396 +3363 3250 -8.40425491333e-06 +3364 3250 -91481269.86781 +3365 3250 68140484.61019 +3375 3250 7.450580596924e-07 +3376 3250 -28283463.80681 +3377 3250 -6857568.701869 +3378 3250 15625000.00513 +3379 3250 -35212760.99956 +3380 3250 17343714.91106 +3251 3251 985817875.0266 +3252 3251 2285903.027413 +3253 3251 54860549.56089 +3254 3251 72200645.50821 +3264 3251 -4571806.052597 +3265 3251 -27430274.79396 +3266 3251 58631507.34796 +3267 3251 -27030538.31493 +3268 3251 15223817.95222 +3269 3251 -30681326.51173 +3348 3251 66546545.00303 +3349 3251 -6857568.701869 +3350 3251 -74918497.68596 +3351 3251 23108532.96245 +3352 3251 16657951.02195 +3353 3251 -47038891.18556 +3360 3251 2285903.027438 +3361 3251 -27430274.79396 +3362 3251 -130792022.7266 +3363 3251 571475.7571481 +3364 3251 67866179.05482 +3365 3251 -147771014.9835 +3375 3251 -68832448.03044 +3376 3251 -6857568.701869 +3377 3251 -84449189.35104 +3378 3251 -23680008.71958 +3379 3251 17343714.91106 +3380 3251 -50324486.557 +3252 3252 1042603210.19 +3253 3252 2.193450927734e-05 +3254 3252 9143612.105123 +3255 3252 120306386.5889 +3256 3252 -9.268522262573e-06 +3257 3252 2285903.027413 +3264 3252 -94266302.18495 +3265 3252 -62499999.98975 +3266 3252 24744635.2875 +3267 3252 -239474705.9488 +3268 3252 2.950429916382e-06 +3269 3252 -4571806.052598 +3270 3252 -95620685.86526 +3271 3252 62499999.98975 +3272 3252 -26687656.37071 +3348 3252 -25604579.22317 +3349 3252 15625000.00514 +3350 3252 10250460.04156 +3351 3252 -93459816.96553 +3352 3252 1.579523086548e-06 +3353 3252 66889426.94725 +3354 3252 -38668381.31079 +3355 3252 -15625000.00514 +3356 3252 23108532.96245 +3360 3252 21503247.52855 +3361 3252 3.844499588013e-06 +3362 3252 571475.7571353 +3363 3252 119183368.3243 +3364 3252 4.112720489502e-06 +3365 3252 2285903.027438 +3366 3252 -32106344.47651 +3367 3252 -9.387731552124e-06 +3368 3252 571475.757148 +3375 3252 -26159485.64696 +3376 3252 -15625000.00513 +3377 3252 -10821935.79869 +3378 3252 -97033826.33989 +3379 3252 1.400709152222e-06 +3380 3252 -69175329.97466 +3381 3252 -39900479.57507 +3382 3252 15625000.00513 +3383 3252 -23680008.71958 +3253 3253 892596215.9216 +3254 3253 -109721099.1218 +3255 3253 -9.95397567749e-06 +3256 3253 -117193314.8593 +3257 3253 54860549.56089 +3264 3253 -62499999.98975 +3265 3253 -75515427.89211 +3266 3253 12480762.39712 +3267 3253 2.920627593994e-06 +3268 3253 35526744.0481 +3269 3253 -27430274.79396 +3270 3253 62499999.98974 +3271 3253 -76869811.57243 +3272 3253 14949512.39685 +3348 3253 15625000.00514 +3349 3253 -20916860.64765 +3350 3253 -9800382.320076 +3351 3253 -6.705522537231e-07 +3352 3253 -24709454.43242 +3353 3253 -6857568.701869 +3354 3253 -15625000.00514 +3355 3253 -33980662.73527 +3356 3253 16657951.02195 +3360 3253 5.88595867157e-06 +3361 3253 -37871677.86274 +3362 3253 -40710209.81623 +3363 3253 4.053115844727e-06 +3364 3253 81681619.73861 +3365 3253 -27430274.79396 +3366 3253 -8.40425491333e-06 +3367 3253 -91481269.86781 +3368 3253 68140484.61019 +3375 3253 -15625000.00513 +3376 3253 -21471767.07144 +3377 3253 -10486146.20919 +3378 3253 7.450580596924e-07 +3379 3253 -28283463.80681 +3380 3253 -6857568.701869 +3381 3253 15625000.00513 +3382 3253 -35212760.99956 +3383 3253 17343714.91106 +3254 3254 985817875.0266 +3255 3254 2285903.027413 +3256 3254 54860549.56089 +3257 3254 72200645.50821 +3264 3254 24401753.34329 +3265 3254 12206456.84174 +3266 3254 -27069636.69752 +3267 3254 -4571806.052597 +3268 3254 -27430274.79396 +3269 3254 58631507.34796 +3270 3254 -27030538.31493 +3271 3254 15223817.95222 +3272 3254 -30681326.51173 +3348 3254 10250460.04156 +3349 3254 -9800382.320076 +3350 3254 -12202085.61857 +3351 3254 66546545.00303 +3352 3254 -6857568.701869 +3353 3254 -74918497.68596 +3354 3254 23108532.96245 +3355 3254 16657951.02195 +3356 3254 -47038891.18556 +3360 3254 571475.7571355 +3361 3254 -40435904.26086 +3362 3254 -4812102.970013 +3363 3254 2285903.027438 +3364 3254 -27430274.79396 +3365 3254 -130792022.7266 +3366 3254 571475.7571481 +3367 3254 67866179.05482 +3368 3254 -147771014.9835 +3375 3254 -10821935.79869 +3376 3254 -10486146.20919 +3377 3254 -13681836.08202 +3378 3254 -68832448.03044 +3379 3254 -6857568.701869 +3380 3254 -84449189.35104 +3381 3254 -23680008.71958 +3382 3254 17343714.91106 +3383 3254 -50324486.557 +3255 3255 1042603210.19 +3256 3255 2.193450927734e-05 +3257 3255 9143612.105123 +3258 3255 120306386.5889 +3259 3255 -9.268522262573e-06 +3260 3255 2285903.027413 +3267 3255 -94266302.18495 +3268 3255 -62499999.98975 +3269 3255 24744635.2875 +3270 3255 -239474705.9488 +3271 3255 2.950429916382e-06 +3272 3255 -4571806.052598 +3273 3255 -95620685.86526 +3274 3255 62499999.98975 +3275 3255 -26687656.37071 +3351 3255 -25604579.22317 +3352 3255 15625000.00514 +3353 3255 10250460.04156 +3354 3255 -93459816.96553 +3355 3255 1.579523086548e-06 +3356 3255 66889426.94725 +3357 3255 -38668381.31079 +3358 3255 -15625000.00514 +3359 3255 23108532.96245 +3363 3255 21503247.52855 +3364 3255 3.844499588013e-06 +3365 3255 571475.7571353 +3366 3255 119183368.3243 +3367 3255 4.112720489502e-06 +3368 3255 2285903.027438 +3369 3255 -32106344.47651 +3370 3255 -9.387731552124e-06 +3371 3255 571475.757148 +3378 3255 -26159485.64696 +3379 3255 -15625000.00513 +3380 3255 -10821935.79869 +3381 3255 -97033826.33989 +3382 3255 1.400709152222e-06 +3383 3255 -69175329.97466 +3384 3255 -39900479.57507 +3385 3255 15625000.00513 +3386 3255 -23680008.71958 +3256 3256 892596215.9216 +3257 3256 -109721099.1218 +3258 3256 -9.95397567749e-06 +3259 3256 -117193314.8593 +3260 3256 54860549.56089 +3267 3256 -62499999.98975 +3268 3256 -75515427.89211 +3269 3256 12480762.39712 +3270 3256 2.920627593994e-06 +3271 3256 35526744.0481 +3272 3256 -27430274.79396 +3273 3256 62499999.98974 +3274 3256 -76869811.57243 +3275 3256 14949512.39685 +3351 3256 15625000.00514 +3352 3256 -20916860.64765 +3353 3256 -9800382.320076 +3354 3256 -6.705522537231e-07 +3355 3256 -24709454.43242 +3356 3256 -6857568.701869 +3357 3256 -15625000.00514 +3358 3256 -33980662.73527 +3359 3256 16657951.02195 +3363 3256 5.88595867157e-06 +3364 3256 -37871677.86274 +3365 3256 -40710209.81623 +3366 3256 4.053115844727e-06 +3367 3256 81681619.73861 +3368 3256 -27430274.79396 +3369 3256 -8.40425491333e-06 +3370 3256 -91481269.86781 +3371 3256 68140484.61019 +3378 3256 -15625000.00513 +3379 3256 -21471767.07144 +3380 3256 -10486146.20919 +3381 3256 7.450580596924e-07 +3382 3256 -28283463.80681 +3383 3256 -6857568.701869 +3384 3256 15625000.00513 +3385 3256 -35212760.99956 +3386 3256 17343714.91106 +3257 3257 985817875.0266 +3258 3257 2285903.027413 +3259 3257 54860549.56089 +3260 3257 72200645.50821 +3267 3257 24401753.34329 +3268 3257 12206456.84174 +3269 3257 -27069636.69752 +3270 3257 -4571806.052597 +3271 3257 -27430274.79396 +3272 3257 58631507.34796 +3273 3257 -27030538.31493 +3274 3257 15223817.95222 +3275 3257 -30681326.51173 +3351 3257 10250460.04156 +3352 3257 -9800382.320076 +3353 3257 -12202085.61857 +3354 3257 66546545.00303 +3355 3257 -6857568.701869 +3356 3257 -74918497.68596 +3357 3257 23108532.96245 +3358 3257 16657951.02195 +3359 3257 -47038891.18556 +3363 3257 571475.7571355 +3364 3257 -40435904.26086 +3365 3257 -4812102.970013 +3366 3257 2285903.027438 +3367 3257 -27430274.79396 +3368 3257 -130792022.7266 +3369 3257 571475.7571481 +3370 3257 67866179.05482 +3371 3257 -147771014.9835 +3378 3257 -10821935.79869 +3379 3257 -10486146.20919 +3380 3257 -13681836.08202 +3381 3257 -68832448.03044 +3382 3257 -6857568.701869 +3383 3257 -84449189.35104 +3384 3257 -23680008.71958 +3385 3257 17343714.91106 +3386 3257 -50324486.557 +3258 3258 1128168022.401 +3259 3258 62553220.58474 +3260 3258 30858743.66929 +3261 3258 17446621.74987 +3262 3258 -62521288.22774 +3263 3258 26696512.96211 +3270 3258 -94266302.18495 +3271 3258 -62499999.98975 +3272 3258 24744635.2875 +3273 3258 -239474705.9488 +3274 3258 2.950429916382e-06 +3275 3258 -4571806.052598 +3276 3258 -95620685.86526 +3277 3258 62499999.98975 +3278 3258 -26687656.37071 +3354 3258 -25604579.22317 +3355 3258 15625000.00514 +3356 3258 10250460.04156 +3357 3258 -111681734.2619 +3358 3258 -15632983.09438 +3359 3258 61472760.90482 +3366 3258 21503247.52855 +3367 3258 3.844499588013e-06 +3368 3258 571475.7571353 +3369 3258 149252626.5636 +3370 3258 15638305.15389 +3371 3258 7711980.245565 +3372 3258 -47230742.81426 +3373 3258 -15630322.06464 +3374 3258 23688071.7797 +3381 3258 -26159485.64696 +3382 3258 -15625000.00513 +3383 3258 -10821935.79869 +3384 3258 -97033826.33989 +3385 3258 1.400709152222e-06 +3386 3258 -69175329.97466 +3387 3258 -39900479.57507 +3388 3258 15625000.00513 +3389 3258 -23680008.71958 +3259 3259 959386203.4543 +3260 3259 -85034422.38434 +3261 3259 -62531932.34674 +3262 3259 -201344781.4455 +3263 3259 45541679.93477 +3270 3259 -62499999.98975 +3271 3259 -75515427.89211 +3272 3259 12480762.39712 +3273 3259 2.920627593994e-06 +3274 3259 35526744.0481 +3275 3259 -27430274.79396 +3276 3259 62499999.98974 +3277 3259 -76869811.57243 +3278 3259 14949512.39685 +3354 3259 15625000.00514 +3355 3259 -20916860.64765 +3356 3259 -9800382.320076 +3357 3259 -15630322.06464 +3358 3259 -38227021.54706 +3359 3259 5963051.430523 +3366 3259 5.88595867157e-06 +3367 3259 -37871677.86274 +3368 3259 -40710209.81623 +3369 3259 15638305.15389 +3370 3259 107057171.8061 +3371 3259 -21260770.12636 +3372 3259 -15632983.09439 +3373 3259 -101928593.64 +3374 3259 65822290.07648 +3381 3259 -15625000.00513 +3382 3259 -21471767.07144 +3383 3259 -10486146.20919 +3384 3259 7.450580596924e-07 +3385 3259 -28283463.80681 +3386 3259 -6857568.701869 +3387 3259 15625000.00513 +3388 3259 -35212760.99956 +3389 3259 17343714.91106 +3260 3260 989397032.1941 +3261 3260 27043823.20204 +3262 3260 53225583.49043 +3263 3260 22257684.43985 +3270 3260 24401753.34329 +3271 3260 12206456.84174 +3272 3260 -27069636.69752 +3273 3260 -4571806.052597 +3274 3260 -27430274.79396 +3275 3260 58631507.34796 +3276 3260 -27030538.31493 +3277 3260 15223817.95222 +3278 3260 -30681326.51173 +3354 3260 10250460.04156 +3355 3260 -9800382.320076 +3356 3260 -12202085.61857 +3357 3260 61128808.369 +3358 3260 4044385.985747 +3359 3260 -67372502.27695 +3366 3260 571475.7571355 +3367 3260 -40435904.26086 +3368 3260 -4812102.970013 +3369 3260 7717756.425008 +3370 3260 -21256149.23011 +3371 3260 -106755752.9646 +3372 3260 23692103.30976 +3373 3260 67469018.6918 +3374 3260 -132015307.5643 +3381 3260 -10821935.79869 +3382 3260 -10486146.20919 +3383 3260 -13681836.08202 +3384 3260 -68832448.03044 +3385 3260 -6857568.701869 +3386 3260 -84449189.35104 +3387 3260 -23680008.71958 +3388 3260 17343714.91106 +3389 3260 -50324486.557 +3261 3261 661240911.694 +3262 3261 62499999.98975 +3263 3261 26309808.76172 +3273 3261 -94266302.18495 +3274 3261 -62499999.98975 +3275 3261 24744635.2875 +3276 3261 -351489360.7944 +3277 3261 -62521288.22773 +3278 3261 -26300660.30375 +3279 3261 7540034.174547 +3280 3261 50021288.22979 +3281 3261 -21267537.14313 +3357 3261 2016499.187392 +3358 3261 18757983.09541 +3359 3261 12648670.74487 +3369 3261 -6124104.06778 +3370 3261 -15632983.09438 +3371 3261 -10255693.28227 +3372 3261 76701211.16396 +3373 3261 15625000.00514 +3374 3261 21009550.22758 +3384 3261 -26159485.64696 +3385 3261 -15625000.00513 +3386 3261 -10821935.79869 +3387 3261 -125983237.2565 +3388 3261 -15630322.06463 +3389 3261 -74621947.50591 +3390 3261 -24799837.07904 +3391 3261 12505322.06361 +3392 3261 -18723479.73292 +3262 3262 567462589.8818 +3263 3262 -68593390.60176 +3273 3262 -62499999.98975 +3274 3262 -75515427.89211 +3275 3262 12480762.39712 +3276 3262 -62531932.34673 +3277 3262 -57670510.07978 +3278 3262 -38001573.29657 +3279 3262 75031932.34468 +3280 3262 7540034.174547 +3281 3262 23874977.56666 +3357 3262 12505322.06361 +3358 3262 2016499.187392 +3359 3262 -6746002.447256 +3369 3262 -15630322.06463 +3370 3262 -60821954.89356 +3371 3262 -41130474.11058 +3372 3262 15625000.00514 +3373 3262 53256630.69937 +3374 3262 -5602780.460976 +3384 3262 -15625000.00513 +3385 3262 -21471767.07144 +3386 3262 -10486146.20919 +3387 3262 -15632983.09438 +3388 3262 -52528524.54163 +3389 3262 -23113573.91808 +3390 3262 18757983.09541 +3391 3262 -24799837.07904 +3392 3262 22467775.67917 +3263 3263 641486746.383 +3273 3263 24401753.34329 +3274 3263 12206456.84174 +3275 3263 -27069636.69752 +3276 3263 -26296086.07475 +3277 3263 -30591858.55204 +3278 3263 -15523139.55333 +3279 3263 -31901305.7147 +3280 3263 15916651.71111 +3281 3263 20106757.79879 +3357 3263 8432447.163244 +3358 3263 -10119003.67088 +3359 3263 5377331.166378 +3369 3263 -10253948.8687 +3370 3263 -42777202.9092 +3371 3263 -22397604.24035 +3372 3263 -6140600.947398 +3373 3263 -27322678.94813 +3374 3263 -75919024.90121 +3384 3263 -10821935.79869 +3385 3263 -10486146.20919 +3386 3263 -13681836.08202 +3387 3263 -74277994.97009 +3388 3263 -21190287.58241 +3389 3263 -105509843.5958 +3390 3263 -28085219.59939 +3391 3263 14978517.11945 +3392 3263 -66132898.87745 +3264 3264 1042603210.19 +3265 3264 2.193450927734e-05 +3266 3264 9143612.105123 +3267 3264 120306386.5889 +3268 3264 -9.268522262573e-06 +3269 3264 2285903.027413 +3282 3264 -239474705.9488 +3283 3264 2.950429916382e-06 +3284 3264 -4571806.052598 +3285 3264 -95620685.86526 +3286 3264 62499999.98975 +3287 3264 -26687656.37071 +3360 3264 -93459816.96553 +3361 3264 1.579523086548e-06 +3362 3264 66889426.94725 +3363 3264 -38668381.31079 +3364 3264 -15625000.00514 +3365 3264 23108532.96245 +3375 3264 119183368.3243 +3376 3264 4.112720489502e-06 +3377 3264 2285903.027438 +3378 3264 -32106344.47651 +3379 3264 -9.387731552124e-06 +3380 3264 571475.757148 +3393 3264 -97033826.33989 +3394 3264 1.400709152222e-06 +3395 3264 -69175329.97466 +3396 3264 -39900479.57507 +3397 3264 15625000.00513 +3398 3264 -23680008.71958 +3265 3265 892596215.9216 +3266 3265 -109721099.1218 +3267 3265 -9.95397567749e-06 +3268 3265 -117193314.8593 +3269 3265 54860549.56089 +3282 3265 2.920627593994e-06 +3283 3265 35526744.0481 +3284 3265 -27430274.79396 +3285 3265 62499999.98974 +3286 3265 -76869811.57243 +3287 3265 14949512.39685 +3360 3265 -6.705522537231e-07 +3361 3265 -24709454.43242 +3362 3265 -6857568.701869 +3363 3265 -15625000.00514 +3364 3265 -33980662.73527 +3365 3265 16657951.02195 +3375 3265 4.053115844727e-06 +3376 3265 81681619.73861 +3377 3265 -27430274.79396 +3378 3265 -8.40425491333e-06 +3379 3265 -91481269.86781 +3380 3265 68140484.61019 +3393 3265 7.450580596924e-07 +3394 3265 -28283463.80681 +3395 3265 -6857568.701869 +3396 3265 15625000.00513 +3397 3265 -35212760.99956 +3398 3265 17343714.91106 +3266 3266 985817875.0266 +3267 3266 2285903.027413 +3268 3266 54860549.56089 +3269 3266 72200645.50821 +3282 3266 -4571806.052597 +3283 3266 -27430274.79396 +3284 3266 58631507.34796 +3285 3266 -27030538.31493 +3286 3266 15223817.95222 +3287 3266 -30681326.51173 +3360 3266 66546545.00303 +3361 3266 -6857568.701869 +3362 3266 -74918497.68596 +3363 3266 23108532.96245 +3364 3266 16657951.02195 +3365 3266 -47038891.18556 +3375 3266 2285903.027438 +3376 3266 -27430274.79396 +3377 3266 -130792022.7266 +3378 3266 571475.7571481 +3379 3266 67866179.05482 +3380 3266 -147771014.9835 +3393 3266 -68832448.03044 +3394 3266 -6857568.701869 +3395 3266 -84449189.35104 +3396 3266 -23680008.71958 +3397 3266 17343714.91106 +3398 3266 -50324486.557 +3267 3267 1042603210.19 +3268 3267 2.193450927734e-05 +3269 3267 9143612.105123 +3270 3267 120306386.5889 +3271 3267 -9.268522262573e-06 +3272 3267 2285903.027413 +3282 3267 -94266302.18495 +3283 3267 -62499999.98975 +3284 3267 24744635.2875 +3285 3267 -239474705.9488 +3286 3267 2.950429916382e-06 +3287 3267 -4571806.052598 +3288 3267 -95620685.86526 +3289 3267 62499999.98975 +3290 3267 -26687656.37071 +3360 3267 -25604579.22317 +3361 3267 15625000.00514 +3362 3267 10250460.04156 +3363 3267 -93459816.96553 +3364 3267 1.579523086548e-06 +3365 3267 66889426.94725 +3366 3267 -38668381.31079 +3367 3267 -15625000.00514 +3368 3267 23108532.96245 +3375 3267 21503247.52855 +3376 3267 3.844499588013e-06 +3377 3267 571475.7571353 +3378 3267 119183368.3243 +3379 3267 4.112720489502e-06 +3380 3267 2285903.027438 +3381 3267 -32106344.47651 +3382 3267 -9.387731552124e-06 +3383 3267 571475.757148 +3393 3267 -26159485.64696 +3394 3267 -15625000.00513 +3395 3267 -10821935.79869 +3396 3267 -97033826.33989 +3397 3267 1.400709152222e-06 +3398 3267 -69175329.97466 +3399 3267 -39900479.57507 +3400 3267 15625000.00513 +3401 3267 -23680008.71958 +3268 3268 892596215.9216 +3269 3268 -109721099.1218 +3270 3268 -9.95397567749e-06 +3271 3268 -117193314.8593 +3272 3268 54860549.56089 +3282 3268 -62499999.98975 +3283 3268 -75515427.89211 +3284 3268 12480762.39712 +3285 3268 2.920627593994e-06 +3286 3268 35526744.0481 +3287 3268 -27430274.79396 +3288 3268 62499999.98974 +3289 3268 -76869811.57243 +3290 3268 14949512.39685 +3360 3268 15625000.00514 +3361 3268 -20916860.64765 +3362 3268 -9800382.320076 +3363 3268 -6.705522537231e-07 +3364 3268 -24709454.43242 +3365 3268 -6857568.701869 +3366 3268 -15625000.00514 +3367 3268 -33980662.73527 +3368 3268 16657951.02195 +3375 3268 5.88595867157e-06 +3376 3268 -37871677.86274 +3377 3268 -40710209.81623 +3378 3268 4.053115844727e-06 +3379 3268 81681619.73861 +3380 3268 -27430274.79396 +3381 3268 -8.40425491333e-06 +3382 3268 -91481269.86781 +3383 3268 68140484.61019 +3393 3268 -15625000.00513 +3394 3268 -21471767.07144 +3395 3268 -10486146.20919 +3396 3268 7.450580596924e-07 +3397 3268 -28283463.80681 +3398 3268 -6857568.701869 +3399 3268 15625000.00513 +3400 3268 -35212760.99956 +3401 3268 17343714.91106 +3269 3269 985817875.0266 +3270 3269 2285903.027413 +3271 3269 54860549.56089 +3272 3269 72200645.50821 +3282 3269 24401753.34329 +3283 3269 12206456.84174 +3284 3269 -27069636.69752 +3285 3269 -4571806.052597 +3286 3269 -27430274.79396 +3287 3269 58631507.34796 +3288 3269 -27030538.31493 +3289 3269 15223817.95222 +3290 3269 -30681326.51173 +3360 3269 10250460.04156 +3361 3269 -9800382.320076 +3362 3269 -12202085.61857 +3363 3269 66546545.00303 +3364 3269 -6857568.701869 +3365 3269 -74918497.68596 +3366 3269 23108532.96245 +3367 3269 16657951.02195 +3368 3269 -47038891.18556 +3375 3269 571475.7571355 +3376 3269 -40435904.26086 +3377 3269 -4812102.970013 +3378 3269 2285903.027438 +3379 3269 -27430274.79396 +3380 3269 -130792022.7266 +3381 3269 571475.7571481 +3382 3269 67866179.05482 +3383 3269 -147771014.9835 +3393 3269 -10821935.79869 +3394 3269 -10486146.20919 +3395 3269 -13681836.08202 +3396 3269 -68832448.03044 +3397 3269 -6857568.701869 +3398 3269 -84449189.35104 +3399 3269 -23680008.71958 +3400 3269 17343714.91106 +3401 3269 -50324486.557 +3270 3270 1042603210.19 +3271 3270 2.193450927734e-05 +3272 3270 9143612.105123 +3273 3270 120306386.5889 +3274 3270 -9.268522262573e-06 +3275 3270 2285903.027413 +3285 3270 -94266302.18495 +3286 3270 -62499999.98975 +3287 3270 24744635.2875 +3288 3270 -239474705.9488 +3289 3270 2.950429916382e-06 +3290 3270 -4571806.052598 +3291 3270 -95620685.86526 +3292 3270 62499999.98975 +3293 3270 -26687656.37071 +3363 3270 -25604579.22317 +3364 3270 15625000.00514 +3365 3270 10250460.04156 +3366 3270 -93459816.96553 +3367 3270 1.579523086548e-06 +3368 3270 66889426.94725 +3369 3270 -38668381.31079 +3370 3270 -15625000.00514 +3371 3270 23108532.96245 +3378 3270 21503247.52855 +3379 3270 3.844499588013e-06 +3380 3270 571475.7571353 +3381 3270 119183368.3243 +3382 3270 4.112720489502e-06 +3383 3270 2285903.027438 +3384 3270 -32106344.47651 +3385 3270 -9.387731552124e-06 +3386 3270 571475.757148 +3396 3270 -26159485.64696 +3397 3270 -15625000.00513 +3398 3270 -10821935.79869 +3399 3270 -97033826.33989 +3400 3270 1.400709152222e-06 +3401 3270 -69175329.97466 +3402 3270 -39900479.57507 +3403 3270 15625000.00513 +3404 3270 -23680008.71958 +3271 3271 892596215.9216 +3272 3271 -109721099.1218 +3273 3271 -9.95397567749e-06 +3274 3271 -117193314.8593 +3275 3271 54860549.56089 +3285 3271 -62499999.98975 +3286 3271 -75515427.89211 +3287 3271 12480762.39712 +3288 3271 2.920627593994e-06 +3289 3271 35526744.0481 +3290 3271 -27430274.79396 +3291 3271 62499999.98974 +3292 3271 -76869811.57243 +3293 3271 14949512.39685 +3363 3271 15625000.00514 +3364 3271 -20916860.64765 +3365 3271 -9800382.320076 +3366 3271 -6.705522537231e-07 +3367 3271 -24709454.43242 +3368 3271 -6857568.701869 +3369 3271 -15625000.00514 +3370 3271 -33980662.73527 +3371 3271 16657951.02195 +3378 3271 5.88595867157e-06 +3379 3271 -37871677.86274 +3380 3271 -40710209.81623 +3381 3271 4.053115844727e-06 +3382 3271 81681619.73861 +3383 3271 -27430274.79396 +3384 3271 -8.40425491333e-06 +3385 3271 -91481269.86781 +3386 3271 68140484.61019 +3396 3271 -15625000.00513 +3397 3271 -21471767.07144 +3398 3271 -10486146.20919 +3399 3271 7.450580596924e-07 +3400 3271 -28283463.80681 +3401 3271 -6857568.701869 +3402 3271 15625000.00513 +3403 3271 -35212760.99956 +3404 3271 17343714.91106 +3272 3272 985817875.0266 +3273 3272 2285903.027413 +3274 3272 54860549.56089 +3275 3272 72200645.50821 +3285 3272 24401753.34329 +3286 3272 12206456.84174 +3287 3272 -27069636.69752 +3288 3272 -4571806.052597 +3289 3272 -27430274.79396 +3290 3272 58631507.34796 +3291 3272 -27030538.31493 +3292 3272 15223817.95222 +3293 3272 -30681326.51173 +3363 3272 10250460.04156 +3364 3272 -9800382.320076 +3365 3272 -12202085.61857 +3366 3272 66546545.00303 +3367 3272 -6857568.701869 +3368 3272 -74918497.68596 +3369 3272 23108532.96245 +3370 3272 16657951.02195 +3371 3272 -47038891.18556 +3378 3272 571475.7571355 +3379 3272 -40435904.26086 +3380 3272 -4812102.970013 +3381 3272 2285903.027438 +3382 3272 -27430274.79396 +3383 3272 -130792022.7266 +3384 3272 571475.7571481 +3385 3272 67866179.05482 +3386 3272 -147771014.9835 +3396 3272 -10821935.79869 +3397 3272 -10486146.20919 +3398 3272 -13681836.08202 +3399 3272 -68832448.03044 +3400 3272 -6857568.701869 +3401 3272 -84449189.35104 +3402 3272 -23680008.71958 +3403 3272 17343714.91106 +3404 3272 -50324486.557 +3273 3273 1042603210.19 +3274 3273 2.193450927734e-05 +3275 3273 9143612.105123 +3276 3273 120306386.5889 +3277 3273 -9.268522262573e-06 +3278 3273 2285903.027413 +3288 3273 -94266302.18495 +3289 3273 -62499999.98975 +3290 3273 24744635.2875 +3291 3273 -239474705.9488 +3292 3273 2.950429916382e-06 +3293 3273 -4571806.052598 +3294 3273 -95620685.86526 +3295 3273 62499999.98975 +3296 3273 -26687656.37071 +3366 3273 -25604579.22317 +3367 3273 15625000.00514 +3368 3273 10250460.04156 +3369 3273 -93459816.96553 +3370 3273 1.579523086548e-06 +3371 3273 66889426.94725 +3372 3273 -38668381.31079 +3373 3273 -15625000.00514 +3374 3273 23108532.96245 +3381 3273 21503247.52855 +3382 3273 3.844499588013e-06 +3383 3273 571475.7571353 +3384 3273 119183368.3243 +3385 3273 4.112720489502e-06 +3386 3273 2285903.027438 +3387 3273 -32106344.47651 +3388 3273 -9.387731552124e-06 +3389 3273 571475.757148 +3399 3273 -26159485.64696 +3400 3273 -15625000.00513 +3401 3273 -10821935.79869 +3402 3273 -97033826.33989 +3403 3273 1.400709152222e-06 +3404 3273 -69175329.97466 +3405 3273 -39900479.57507 +3406 3273 15625000.00513 +3407 3273 -23680008.71958 +3274 3274 892596215.9216 +3275 3274 -109721099.1218 +3276 3274 -9.95397567749e-06 +3277 3274 -117193314.8593 +3278 3274 54860549.56089 +3288 3274 -62499999.98975 +3289 3274 -75515427.89211 +3290 3274 12480762.39712 +3291 3274 2.920627593994e-06 +3292 3274 35526744.0481 +3293 3274 -27430274.79396 +3294 3274 62499999.98974 +3295 3274 -76869811.57243 +3296 3274 14949512.39685 +3366 3274 15625000.00514 +3367 3274 -20916860.64765 +3368 3274 -9800382.320076 +3369 3274 -6.705522537231e-07 +3370 3274 -24709454.43242 +3371 3274 -6857568.701869 +3372 3274 -15625000.00514 +3373 3274 -33980662.73527 +3374 3274 16657951.02195 +3381 3274 5.88595867157e-06 +3382 3274 -37871677.86274 +3383 3274 -40710209.81623 +3384 3274 4.053115844727e-06 +3385 3274 81681619.73861 +3386 3274 -27430274.79396 +3387 3274 -8.40425491333e-06 +3388 3274 -91481269.86781 +3389 3274 68140484.61019 +3399 3274 -15625000.00513 +3400 3274 -21471767.07144 +3401 3274 -10486146.20919 +3402 3274 7.450580596924e-07 +3403 3274 -28283463.80681 +3404 3274 -6857568.701869 +3405 3274 15625000.00513 +3406 3274 -35212760.99956 +3407 3274 17343714.91106 +3275 3275 985817875.0266 +3276 3275 2285903.027413 +3277 3275 54860549.56089 +3278 3275 72200645.50821 +3288 3275 24401753.34329 +3289 3275 12206456.84174 +3290 3275 -27069636.69752 +3291 3275 -4571806.052597 +3292 3275 -27430274.79396 +3293 3275 58631507.34796 +3294 3275 -27030538.31493 +3295 3275 15223817.95222 +3296 3275 -30681326.51173 +3366 3275 10250460.04156 +3367 3275 -9800382.320076 +3368 3275 -12202085.61857 +3369 3275 66546545.00303 +3370 3275 -6857568.701869 +3371 3275 -74918497.68596 +3372 3275 23108532.96245 +3373 3275 16657951.02195 +3374 3275 -47038891.18556 +3381 3275 571475.7571355 +3382 3275 -40435904.26086 +3383 3275 -4812102.970013 +3384 3275 2285903.027438 +3385 3275 -27430274.79396 +3386 3275 -130792022.7266 +3387 3275 571475.7571481 +3388 3275 67866179.05482 +3389 3275 -147771014.9835 +3399 3275 -10821935.79869 +3400 3275 -10486146.20919 +3401 3275 -13681836.08202 +3402 3275 -68832448.03044 +3403 3275 -6857568.701869 +3404 3275 -84449189.35104 +3405 3275 -23680008.71958 +3406 3275 17343714.91106 +3407 3275 -50324486.557 +3276 3276 1128168022.401 +3277 3276 62553220.58474 +3278 3276 30858743.66929 +3279 3276 17446621.74987 +3280 3276 -62521288.22774 +3281 3276 26696512.96211 +3291 3276 -94266302.18495 +3292 3276 -62499999.98975 +3293 3276 24744635.2875 +3294 3276 -239474705.9488 +3295 3276 2.950429916382e-06 +3296 3276 -4571806.052598 +3297 3276 -95620685.86526 +3298 3276 62499999.98975 +3299 3276 -26687656.37071 +3369 3276 -25604579.22317 +3370 3276 15625000.00514 +3371 3276 10250460.04156 +3372 3276 -111681734.2619 +3373 3276 -15632983.09438 +3374 3276 61472760.90482 +3384 3276 21503247.52855 +3385 3276 3.844499588013e-06 +3386 3276 571475.7571353 +3387 3276 149252626.5636 +3388 3276 15638305.15389 +3389 3276 7711980.245565 +3390 3276 -47230742.81426 +3391 3276 -15630322.06464 +3392 3276 23688071.7797 +3402 3276 -26159485.64696 +3403 3276 -15625000.00513 +3404 3276 -10821935.79869 +3405 3276 -97033826.33989 +3406 3276 1.400709152222e-06 +3407 3276 -69175329.97466 +3408 3276 -39900479.57507 +3409 3276 15625000.00513 +3410 3276 -23680008.71958 +3277 3277 959386203.4543 +3278 3277 -85034422.38434 +3279 3277 -62531932.34674 +3280 3277 -201344781.4455 +3281 3277 45541679.93477 +3291 3277 -62499999.98975 +3292 3277 -75515427.89211 +3293 3277 12480762.39712 +3294 3277 2.920627593994e-06 +3295 3277 35526744.0481 +3296 3277 -27430274.79396 +3297 3277 62499999.98974 +3298 3277 -76869811.57243 +3299 3277 14949512.39685 +3369 3277 15625000.00514 +3370 3277 -20916860.64765 +3371 3277 -9800382.320076 +3372 3277 -15630322.06464 +3373 3277 -38227021.54706 +3374 3277 5963051.430523 +3384 3277 5.88595867157e-06 +3385 3277 -37871677.86274 +3386 3277 -40710209.81623 +3387 3277 15638305.15389 +3388 3277 107057171.8061 +3389 3277 -21260770.12636 +3390 3277 -15632983.09439 +3391 3277 -101928593.64 +3392 3277 65822290.07648 +3402 3277 -15625000.00513 +3403 3277 -21471767.07144 +3404 3277 -10486146.20919 +3405 3277 7.450580596924e-07 +3406 3277 -28283463.80681 +3407 3277 -6857568.701869 +3408 3277 15625000.00513 +3409 3277 -35212760.99956 +3410 3277 17343714.91106 +3278 3278 989397032.1941 +3279 3278 27043823.20204 +3280 3278 53225583.49043 +3281 3278 22257684.43985 +3291 3278 24401753.34329 +3292 3278 12206456.84174 +3293 3278 -27069636.69752 +3294 3278 -4571806.052597 +3295 3278 -27430274.79396 +3296 3278 58631507.34796 +3297 3278 -27030538.31493 +3298 3278 15223817.95222 +3299 3278 -30681326.51173 +3369 3278 10250460.04156 +3370 3278 -9800382.320076 +3371 3278 -12202085.61857 +3372 3278 61128808.369 +3373 3278 4044385.985747 +3374 3278 -67372502.27695 +3384 3278 571475.7571355 +3385 3278 -40435904.26086 +3386 3278 -4812102.970013 +3387 3278 7717756.425008 +3388 3278 -21256149.23011 +3389 3278 -106755752.9646 +3390 3278 23692103.30976 +3391 3278 67469018.6918 +3392 3278 -132015307.5643 +3402 3278 -10821935.79869 +3403 3278 -10486146.20919 +3404 3278 -13681836.08202 +3405 3278 -68832448.03044 +3406 3278 -6857568.701869 +3407 3278 -84449189.35104 +3408 3278 -23680008.71958 +3409 3278 17343714.91106 +3410 3278 -50324486.557 +3279 3279 600178947.3725 +3280 3279 37725262.55381 +3281 3279 -13827796.63441 +3294 3279 -94266302.18495 +3295 3279 -62499999.98975 +3296 3279 24744635.2875 +3297 3279 -293151746.8795 +3298 3279 -37775820.80688 +3299 3279 -1256051.514156 +3300 3279 -295864.016185 +3301 3279 50050558.24487 +3302 3279 -2747124.263025 +3372 3279 2016499.187392 +3373 3279 18757983.09541 +3374 3279 12648670.74487 +3387 3279 -6124104.06778 +3388 3279 -15632983.09438 +3389 3279 -10255693.28227 +3390 3279 65666544.26174 +3391 3279 10333339.53909 +3392 3279 9670962.265862 +3405 3279 -26159485.64696 +3406 3279 -15625000.00513 +3407 3279 -10821935.79869 +3408 3279 -106870441.9849 +3409 3279 -10344958.86108 +3410 3279 -63962837.30182 +3411 3279 -13431713.52885 +3412 3279 12511619.32611 +3413 3279 -12546378.89565 +3280 3280 542232249.1086 +3281 3280 -69126882.73255 +3294 3280 -62499999.98975 +3295 3280 -75515427.89211 +3296 3280 12480762.39712 +3297 3280 -37801099.93342 +3298 3280 -10394286.81598 +3299 3280 -18514480.73787 +3300 3280 75075837.36731 +3301 3280 -25066096.91336 +3302 3280 6020484.825208 +3372 3280 12505322.06361 +3373 3280 2016499.187392 +3374 3280 -6746002.447256 +3387 3280 -15630322.06463 +3388 3280 -60821954.89356 +3389 3280 -41130474.11058 +3390 3280 10333339.53908 +3391 3280 49691553.75032 +3392 3280 -6634440.888398 +3405 3280 -15625000.00513 +3406 3280 -21471767.07144 +3407 3280 -10486146.20919 +3408 3280 -10350768.52208 +3409 3280 -35778359.74888 +3410 3280 -14032597.42536 +3411 3280 18767428.98916 +3412 3280 -18538673.00316 +3413 3280 20479811.65281 +3281 3281 586937705.6795 +3294 3281 24401753.34329 +3295 3281 12206456.84174 +3296 3281 -27069636.69752 +3297 3281 -8797975.588425 +3298 3281 -17415982.97645 +3299 3281 6990733.835282 +3300 3281 -4120686.394537 +3301 3281 4922929.795991 +3302 3281 23981262.18735 +3372 3281 8432447.163244 +3373 3281 -10119003.67088 +3374 3281 5377331.166378 +3387 3281 -10253948.8687 +3388 3281 -42777202.9092 +3389 3281 -22397604.24035 +3390 3281 -15760902.34505 +3391 3281 -26425457.75927 +3392 3281 -82032786.80308 +3405 3281 -10821935.79869 +3406 3281 -10486146.20919 +3407 3281 -13681836.08202 +3408 3281 -65676910.20889 +3409 3281 -13478401.78615 +3410 3281 -82961365.51657 +3411 3281 -18819568.34348 +3412 3281 15461438.19274 +3413 3281 -30710943.26928 +3282 3282 1042603210.19 +3283 3282 2.193450927734e-05 +3284 3282 9143612.105123 +3285 3282 120306386.5889 +3286 3282 -9.268522262573e-06 +3287 3282 2285903.027413 +3303 3282 -239474705.9488 +3304 3282 2.950429916382e-06 +3305 3282 -4571806.052598 +3306 3282 -95620685.86526 +3307 3282 62499999.98975 +3308 3282 -26687656.37071 +3375 3282 -93459816.96553 +3376 3282 1.579523086548e-06 +3377 3282 66889426.94725 +3378 3282 -38668381.31079 +3379 3282 -15625000.00514 +3380 3282 23108532.96245 +3393 3282 119183368.3243 +3394 3282 4.112720489502e-06 +3395 3282 2285903.027438 +3396 3282 -32106344.47651 +3397 3282 -9.387731552124e-06 +3398 3282 571475.757148 +3414 3282 -97033826.33989 +3415 3282 1.400709152222e-06 +3416 3282 -69175329.97466 +3417 3282 -39900479.57507 +3418 3282 15625000.00513 +3419 3282 -23680008.71958 +3283 3283 892596215.9216 +3284 3283 -109721099.1218 +3285 3283 -9.95397567749e-06 +3286 3283 -117193314.8593 +3287 3283 54860549.56089 +3303 3283 2.920627593994e-06 +3304 3283 35526744.0481 +3305 3283 -27430274.79396 +3306 3283 62499999.98974 +3307 3283 -76869811.57243 +3308 3283 14949512.39685 +3375 3283 -6.705522537231e-07 +3376 3283 -24709454.43242 +3377 3283 -6857568.701869 +3378 3283 -15625000.00514 +3379 3283 -33980662.73527 +3380 3283 16657951.02195 +3393 3283 4.053115844727e-06 +3394 3283 81681619.73861 +3395 3283 -27430274.79396 +3396 3283 -8.40425491333e-06 +3397 3283 -91481269.86781 +3398 3283 68140484.61019 +3414 3283 7.450580596924e-07 +3415 3283 -28283463.80681 +3416 3283 -6857568.701869 +3417 3283 15625000.00513 +3418 3283 -35212760.99956 +3419 3283 17343714.91106 +3284 3284 985817875.0266 +3285 3284 2285903.027413 +3286 3284 54860549.56089 +3287 3284 72200645.50821 +3303 3284 -4571806.052597 +3304 3284 -27430274.79396 +3305 3284 58631507.34796 +3306 3284 -27030538.31493 +3307 3284 15223817.95222 +3308 3284 -30681326.51173 +3375 3284 66546545.00303 +3376 3284 -6857568.701869 +3377 3284 -74918497.68596 +3378 3284 23108532.96245 +3379 3284 16657951.02195 +3380 3284 -47038891.18556 +3393 3284 2285903.027438 +3394 3284 -27430274.79396 +3395 3284 -130792022.7266 +3396 3284 571475.7571481 +3397 3284 67866179.05482 +3398 3284 -147771014.9835 +3414 3284 -68832448.03044 +3415 3284 -6857568.701869 +3416 3284 -84449189.35104 +3417 3284 -23680008.71958 +3418 3284 17343714.91106 +3419 3284 -50324486.557 +3285 3285 1042603210.19 +3286 3285 2.193450927734e-05 +3287 3285 9143612.105123 +3288 3285 120306386.5889 +3289 3285 -9.268522262573e-06 +3290 3285 2285903.027413 +3303 3285 -94266302.18495 +3304 3285 -62499999.98975 +3305 3285 24744635.2875 +3306 3285 -239474705.9488 +3307 3285 2.950429916382e-06 +3308 3285 -4571806.052598 +3309 3285 -95620685.86526 +3310 3285 62499999.98975 +3311 3285 -26687656.37071 +3375 3285 -25604579.22317 +3376 3285 15625000.00514 +3377 3285 10250460.04156 +3378 3285 -93459816.96553 +3379 3285 1.579523086548e-06 +3380 3285 66889426.94725 +3381 3285 -38668381.31079 +3382 3285 -15625000.00514 +3383 3285 23108532.96245 +3393 3285 21503247.52855 +3394 3285 3.844499588013e-06 +3395 3285 571475.7571353 +3396 3285 119183368.3243 +3397 3285 4.112720489502e-06 +3398 3285 2285903.027438 +3399 3285 -32106344.47651 +3400 3285 -9.387731552124e-06 +3401 3285 571475.757148 +3414 3285 -26159485.64696 +3415 3285 -15625000.00513 +3416 3285 -10821935.79869 +3417 3285 -97033826.33989 +3418 3285 1.400709152222e-06 +3419 3285 -69175329.97466 +3420 3285 -39900479.57507 +3421 3285 15625000.00513 +3422 3285 -23680008.71958 +3286 3286 892596215.9216 +3287 3286 -109721099.1218 +3288 3286 -9.95397567749e-06 +3289 3286 -117193314.8593 +3290 3286 54860549.56089 +3303 3286 -62499999.98975 +3304 3286 -75515427.89211 +3305 3286 12480762.39712 +3306 3286 2.920627593994e-06 +3307 3286 35526744.0481 +3308 3286 -27430274.79396 +3309 3286 62499999.98974 +3310 3286 -76869811.57243 +3311 3286 14949512.39685 +3375 3286 15625000.00514 +3376 3286 -20916860.64765 +3377 3286 -9800382.320076 +3378 3286 -6.705522537231e-07 +3379 3286 -24709454.43242 +3380 3286 -6857568.701869 +3381 3286 -15625000.00514 +3382 3286 -33980662.73527 +3383 3286 16657951.02195 +3393 3286 5.88595867157e-06 +3394 3286 -37871677.86274 +3395 3286 -40710209.81623 +3396 3286 4.053115844727e-06 +3397 3286 81681619.73861 +3398 3286 -27430274.79396 +3399 3286 -8.40425491333e-06 +3400 3286 -91481269.86781 +3401 3286 68140484.61019 +3414 3286 -15625000.00513 +3415 3286 -21471767.07144 +3416 3286 -10486146.20919 +3417 3286 7.450580596924e-07 +3418 3286 -28283463.80681 +3419 3286 -6857568.701869 +3420 3286 15625000.00513 +3421 3286 -35212760.99956 +3422 3286 17343714.91106 +3287 3287 985817875.0266 +3288 3287 2285903.027413 +3289 3287 54860549.56089 +3290 3287 72200645.50821 +3303 3287 24401753.34329 +3304 3287 12206456.84174 +3305 3287 -27069636.69752 +3306 3287 -4571806.052597 +3307 3287 -27430274.79396 +3308 3287 58631507.34796 +3309 3287 -27030538.31493 +3310 3287 15223817.95222 +3311 3287 -30681326.51173 +3375 3287 10250460.04156 +3376 3287 -9800382.320076 +3377 3287 -12202085.61857 +3378 3287 66546545.00303 +3379 3287 -6857568.701869 +3380 3287 -74918497.68596 +3381 3287 23108532.96245 +3382 3287 16657951.02195 +3383 3287 -47038891.18556 +3393 3287 571475.7571355 +3394 3287 -40435904.26086 +3395 3287 -4812102.970013 +3396 3287 2285903.027438 +3397 3287 -27430274.79396 +3398 3287 -130792022.7266 +3399 3287 571475.7571481 +3400 3287 67866179.05482 +3401 3287 -147771014.9835 +3414 3287 -10821935.79869 +3415 3287 -10486146.20919 +3416 3287 -13681836.08202 +3417 3287 -68832448.03044 +3418 3287 -6857568.701869 +3419 3287 -84449189.35104 +3420 3287 -23680008.71958 +3421 3287 17343714.91106 +3422 3287 -50324486.557 +3288 3288 1042603210.19 +3289 3288 2.193450927734e-05 +3290 3288 9143612.105123 +3291 3288 120306386.5889 +3292 3288 -9.268522262573e-06 +3293 3288 2285903.027413 +3306 3288 -94266302.18495 +3307 3288 -62499999.98975 +3308 3288 24744635.2875 +3309 3288 -239474705.9488 +3310 3288 2.950429916382e-06 +3311 3288 -4571806.052598 +3312 3288 -95620685.86526 +3313 3288 62499999.98975 +3314 3288 -26687656.37071 +3378 3288 -25604579.22317 +3379 3288 15625000.00514 +3380 3288 10250460.04156 +3381 3288 -93459816.96553 +3382 3288 1.579523086548e-06 +3383 3288 66889426.94725 +3384 3288 -38668381.31079 +3385 3288 -15625000.00514 +3386 3288 23108532.96245 +3396 3288 21503247.52855 +3397 3288 3.844499588013e-06 +3398 3288 571475.7571353 +3399 3288 119183368.3243 +3400 3288 4.112720489502e-06 +3401 3288 2285903.027438 +3402 3288 -32106344.47651 +3403 3288 -9.387731552124e-06 +3404 3288 571475.757148 +3417 3288 -26159485.64696 +3418 3288 -15625000.00513 +3419 3288 -10821935.79869 +3420 3288 -97033826.33989 +3421 3288 1.400709152222e-06 +3422 3288 -69175329.97466 +3423 3288 -39900479.57507 +3424 3288 15625000.00513 +3425 3288 -23680008.71958 +3289 3289 892596215.9216 +3290 3289 -109721099.1218 +3291 3289 -9.95397567749e-06 +3292 3289 -117193314.8593 +3293 3289 54860549.56089 +3306 3289 -62499999.98975 +3307 3289 -75515427.89211 +3308 3289 12480762.39712 +3309 3289 2.920627593994e-06 +3310 3289 35526744.0481 +3311 3289 -27430274.79396 +3312 3289 62499999.98974 +3313 3289 -76869811.57243 +3314 3289 14949512.39685 +3378 3289 15625000.00514 +3379 3289 -20916860.64765 +3380 3289 -9800382.320076 +3381 3289 -6.705522537231e-07 +3382 3289 -24709454.43242 +3383 3289 -6857568.701869 +3384 3289 -15625000.00514 +3385 3289 -33980662.73527 +3386 3289 16657951.02195 +3396 3289 5.88595867157e-06 +3397 3289 -37871677.86274 +3398 3289 -40710209.81623 +3399 3289 4.053115844727e-06 +3400 3289 81681619.73861 +3401 3289 -27430274.79396 +3402 3289 -8.40425491333e-06 +3403 3289 -91481269.86781 +3404 3289 68140484.61019 +3417 3289 -15625000.00513 +3418 3289 -21471767.07144 +3419 3289 -10486146.20919 +3420 3289 7.450580596924e-07 +3421 3289 -28283463.80681 +3422 3289 -6857568.701869 +3423 3289 15625000.00513 +3424 3289 -35212760.99956 +3425 3289 17343714.91106 +3290 3290 985817875.0266 +3291 3290 2285903.027413 +3292 3290 54860549.56089 +3293 3290 72200645.50821 +3306 3290 24401753.34329 +3307 3290 12206456.84174 +3308 3290 -27069636.69752 +3309 3290 -4571806.052597 +3310 3290 -27430274.79396 +3311 3290 58631507.34796 +3312 3290 -27030538.31493 +3313 3290 15223817.95222 +3314 3290 -30681326.51173 +3378 3290 10250460.04156 +3379 3290 -9800382.320076 +3380 3290 -12202085.61857 +3381 3290 66546545.00303 +3382 3290 -6857568.701869 +3383 3290 -74918497.68596 +3384 3290 23108532.96245 +3385 3290 16657951.02195 +3386 3290 -47038891.18556 +3396 3290 571475.7571355 +3397 3290 -40435904.26086 +3398 3290 -4812102.970013 +3399 3290 2285903.027438 +3400 3290 -27430274.79396 +3401 3290 -130792022.7266 +3402 3290 571475.7571481 +3403 3290 67866179.05482 +3404 3290 -147771014.9835 +3417 3290 -10821935.79869 +3418 3290 -10486146.20919 +3419 3290 -13681836.08202 +3420 3290 -68832448.03044 +3421 3290 -6857568.701869 +3422 3290 -84449189.35104 +3423 3290 -23680008.71958 +3424 3290 17343714.91106 +3425 3290 -50324486.557 +3291 3291 1042603210.19 +3292 3291 2.193450927734e-05 +3293 3291 9143612.105123 +3294 3291 120306386.5889 +3295 3291 -9.268522262573e-06 +3296 3291 2285903.027413 +3309 3291 -94266302.18495 +3310 3291 -62499999.98975 +3311 3291 24744635.2875 +3312 3291 -239474705.9488 +3313 3291 2.950429916382e-06 +3314 3291 -4571806.052598 +3315 3291 -95620685.86526 +3316 3291 62499999.98975 +3317 3291 -26687656.37071 +3381 3291 -25604579.22317 +3382 3291 15625000.00514 +3383 3291 10250460.04156 +3384 3291 -93459816.96553 +3385 3291 1.579523086548e-06 +3386 3291 66889426.94725 +3387 3291 -38668381.31079 +3388 3291 -15625000.00514 +3389 3291 23108532.96245 +3399 3291 21503247.52855 +3400 3291 3.844499588013e-06 +3401 3291 571475.7571353 +3402 3291 119183368.3243 +3403 3291 4.112720489502e-06 +3404 3291 2285903.027438 +3405 3291 -32106344.47651 +3406 3291 -9.387731552124e-06 +3407 3291 571475.757148 +3420 3291 -26159485.64696 +3421 3291 -15625000.00513 +3422 3291 -10821935.79869 +3423 3291 -97033826.33989 +3424 3291 1.400709152222e-06 +3425 3291 -69175329.97466 +3426 3291 -39900479.57507 +3427 3291 15625000.00513 +3428 3291 -23680008.71958 +3292 3292 892596215.9216 +3293 3292 -109721099.1218 +3294 3292 -9.95397567749e-06 +3295 3292 -117193314.8593 +3296 3292 54860549.56089 +3309 3292 -62499999.98975 +3310 3292 -75515427.89211 +3311 3292 12480762.39712 +3312 3292 2.920627593994e-06 +3313 3292 35526744.0481 +3314 3292 -27430274.79396 +3315 3292 62499999.98974 +3316 3292 -76869811.57243 +3317 3292 14949512.39685 +3381 3292 15625000.00514 +3382 3292 -20916860.64765 +3383 3292 -9800382.320076 +3384 3292 -6.705522537231e-07 +3385 3292 -24709454.43242 +3386 3292 -6857568.701869 +3387 3292 -15625000.00514 +3388 3292 -33980662.73527 +3389 3292 16657951.02195 +3399 3292 5.88595867157e-06 +3400 3292 -37871677.86274 +3401 3292 -40710209.81623 +3402 3292 4.053115844727e-06 +3403 3292 81681619.73861 +3404 3292 -27430274.79396 +3405 3292 -8.40425491333e-06 +3406 3292 -91481269.86781 +3407 3292 68140484.61019 +3420 3292 -15625000.00513 +3421 3292 -21471767.07144 +3422 3292 -10486146.20919 +3423 3292 7.450580596924e-07 +3424 3292 -28283463.80681 +3425 3292 -6857568.701869 +3426 3292 15625000.00513 +3427 3292 -35212760.99956 +3428 3292 17343714.91106 +3293 3293 985817875.0266 +3294 3293 2285903.027413 +3295 3293 54860549.56089 +3296 3293 72200645.50821 +3309 3293 24401753.34329 +3310 3293 12206456.84174 +3311 3293 -27069636.69752 +3312 3293 -4571806.052597 +3313 3293 -27430274.79396 +3314 3293 58631507.34796 +3315 3293 -27030538.31493 +3316 3293 15223817.95222 +3317 3293 -30681326.51173 +3381 3293 10250460.04156 +3382 3293 -9800382.320076 +3383 3293 -12202085.61857 +3384 3293 66546545.00303 +3385 3293 -6857568.701869 +3386 3293 -74918497.68596 +3387 3293 23108532.96245 +3388 3293 16657951.02195 +3389 3293 -47038891.18556 +3399 3293 571475.7571355 +3400 3293 -40435904.26086 +3401 3293 -4812102.970013 +3402 3293 2285903.027438 +3403 3293 -27430274.79396 +3404 3293 -130792022.7266 +3405 3293 571475.7571481 +3406 3293 67866179.05482 +3407 3293 -147771014.9835 +3420 3293 -10821935.79869 +3421 3293 -10486146.20919 +3422 3293 -13681836.08202 +3423 3293 -68832448.03044 +3424 3293 -6857568.701869 +3425 3293 -84449189.35104 +3426 3293 -23680008.71958 +3427 3293 17343714.91106 +3428 3293 -50324486.557 +3294 3294 1042603210.19 +3295 3294 2.193450927734e-05 +3296 3294 9143612.105123 +3297 3294 120306386.5889 +3298 3294 -9.268522262573e-06 +3299 3294 2285903.027413 +3312 3294 -94266302.18495 +3313 3294 -62499999.98975 +3314 3294 24744635.2875 +3315 3294 -239474705.9488 +3316 3294 2.950429916382e-06 +3317 3294 -4571806.052598 +3318 3294 -95620685.86526 +3319 3294 62499999.98975 +3320 3294 -26687656.37071 +3384 3294 -25604579.22317 +3385 3294 15625000.00514 +3386 3294 10250460.04156 +3387 3294 -93459816.96553 +3388 3294 1.579523086548e-06 +3389 3294 66889426.94725 +3390 3294 -38668381.31079 +3391 3294 -15625000.00514 +3392 3294 23108532.96245 +3402 3294 21503247.52855 +3403 3294 3.844499588013e-06 +3404 3294 571475.7571353 +3405 3294 119183368.3243 +3406 3294 4.112720489502e-06 +3407 3294 2285903.027438 +3408 3294 -32106344.47651 +3409 3294 -9.387731552124e-06 +3410 3294 571475.757148 +3423 3294 -26159485.64696 +3424 3294 -15625000.00513 +3425 3294 -10821935.79869 +3426 3294 -97033826.33989 +3427 3294 1.400709152222e-06 +3428 3294 -69175329.97466 +3429 3294 -39900479.57507 +3430 3294 15625000.00513 +3431 3294 -23680008.71958 +3295 3295 892596215.9216 +3296 3295 -109721099.1218 +3297 3295 -9.95397567749e-06 +3298 3295 -117193314.8593 +3299 3295 54860549.56089 +3312 3295 -62499999.98975 +3313 3295 -75515427.89211 +3314 3295 12480762.39712 +3315 3295 2.920627593994e-06 +3316 3295 35526744.0481 +3317 3295 -27430274.79396 +3318 3295 62499999.98974 +3319 3295 -76869811.57243 +3320 3295 14949512.39685 +3384 3295 15625000.00514 +3385 3295 -20916860.64765 +3386 3295 -9800382.320076 +3387 3295 -6.705522537231e-07 +3388 3295 -24709454.43242 +3389 3295 -6857568.701869 +3390 3295 -15625000.00514 +3391 3295 -33980662.73527 +3392 3295 16657951.02195 +3402 3295 5.88595867157e-06 +3403 3295 -37871677.86274 +3404 3295 -40710209.81623 +3405 3295 4.053115844727e-06 +3406 3295 81681619.73861 +3407 3295 -27430274.79396 +3408 3295 -8.40425491333e-06 +3409 3295 -91481269.86781 +3410 3295 68140484.61019 +3423 3295 -15625000.00513 +3424 3295 -21471767.07144 +3425 3295 -10486146.20919 +3426 3295 7.450580596924e-07 +3427 3295 -28283463.80681 +3428 3295 -6857568.701869 +3429 3295 15625000.00513 +3430 3295 -35212760.99956 +3431 3295 17343714.91106 +3296 3296 985817875.0266 +3297 3296 2285903.027413 +3298 3296 54860549.56089 +3299 3296 72200645.50821 +3312 3296 24401753.34329 +3313 3296 12206456.84174 +3314 3296 -27069636.69752 +3315 3296 -4571806.052597 +3316 3296 -27430274.79396 +3317 3296 58631507.34796 +3318 3296 -27030538.31493 +3319 3296 15223817.95222 +3320 3296 -30681326.51173 +3384 3296 10250460.04156 +3385 3296 -9800382.320076 +3386 3296 -12202085.61857 +3387 3296 66546545.00303 +3388 3296 -6857568.701869 +3389 3296 -74918497.68596 +3390 3296 23108532.96245 +3391 3296 16657951.02195 +3392 3296 -47038891.18556 +3402 3296 571475.7571355 +3403 3296 -40435904.26086 +3404 3296 -4812102.970013 +3405 3296 2285903.027438 +3406 3296 -27430274.79396 +3407 3296 -130792022.7266 +3408 3296 571475.7571481 +3409 3296 67866179.05482 +3410 3296 -147771014.9835 +3423 3296 -10821935.79869 +3424 3296 -10486146.20919 +3425 3296 -13681836.08202 +3426 3296 -68832448.03044 +3427 3296 -6857568.701869 +3428 3296 -84449189.35104 +3429 3296 -23680008.71958 +3430 3296 17343714.91106 +3431 3296 -50324486.557 +3297 3297 1035907821.889 +3298 3297 40720864.10725 +3299 3297 9150670.592108 +3300 3297 -13553326.64045 +3301 3297 -75259059.17135 +3302 3297 4752365.253985 +3315 3297 -94266302.18495 +3316 3297 -62499999.98975 +3317 3297 24744635.2875 +3318 3297 -215979427.1388 +3319 3297 12040799.05848 +3320 3297 -612033.9502044 +3321 3297 -66477077.19527 +3322 3297 60298495.93906 +3323 3297 -4491915.002784 +3387 3297 -25604579.22317 +3388 3297 15625000.00514 +3389 3297 10250460.04156 +3390 3297 -103436156.438 +3391 3297 -10350768.52208 +3392 3297 61482412.84568 +3405 3297 21503247.52855 +3406 3297 3.844499588013e-06 +3407 3297 571475.7571353 +3408 3297 131757605.1285 +3409 3297 10883246.74728 +3410 3297 2279585.359685 +3411 3297 -36126426.97389 +3412 3297 -18339298.48663 +3413 3297 18999429.52286 +3426 3297 -26159485.64696 +3427 3297 -15625000.00513 +3428 3297 -10821935.79869 +3429 3297 -92843586.12443 +3430 3297 2583957.046466 +3431 3297 -66781939.86803 +3432 3297 -28459782.66519 +3433 3297 15222863.21497 +3434 3297 -15946233.92645 +3298 3298 935772345.0432 +3299 3298 -65825099.27941 +3300 3298 -75284338.29789 +3301 3298 -234963497.7551 +3302 3298 10060083.50378 +3315 3298 -62499999.98975 +3316 3298 -75515427.89211 +3317 3298 12480762.39712 +3318 3298 12040799.05849 +3319 3298 45327393.94003 +3320 3298 -16678780.64226 +3321 3298 60298495.93905 +3322 3298 -88997757.51486 +3323 3298 4003871.938917 +3387 3298 15625000.00514 +3388 3298 -20916860.64765 +3389 3298 -9800382.320076 +3390 3298 -10344958.86108 +3391 3298 -32344074.20199 +3392 3298 5139701.049837 +3405 3298 5.88595867157e-06 +3406 3298 -37871677.86274 +3407 3298 -40710209.81623 +3408 3298 10883246.74728 +3409 3298 104151967.825 +3410 3298 -16241176.13329 +3411 3298 -18345108.14763 +3412 3298 -91334291.07195 +3413 3298 59528706.98488 +3426 3298 -15625000.00513 +3427 3298 -21471767.07144 +3428 3298 -10486146.20919 +3429 3298 2583957.046465 +3430 3298 -26969019.99144 +3431 3298 -1735814.665134 +3432 3298 15222863.21497 +3433 3298 -32613441.3924 +3434 3298 17623591.55946 +3299 3299 926320393.7883 +3300 3299 4754399.607948 +3301 3299 10061803.60335 +3302 3299 13106850.14392 +3315 3299 24401753.34329 +3316 3299 12206456.84174 +3317 3299 -27069636.69752 +3318 3299 -8155436.726743 +3319 3299 -16678780.64226 +3320 3299 61481729.40711 +3321 3299 -4491915.002108 +3322 3299 4003871.938917 +3323 3299 -16574342.61114 +3387 3299 10250460.04156 +3388 3299 -9800382.320076 +3389 3299 -12202085.61857 +3390 3299 63196485.75275 +3391 3299 5144712.253762 +3392 3299 -73803270.72483 +3405 3299 571475.7571355 +3406 3299 -40435904.26086 +3407 3299 -4812102.970013 +3408 3299 2290581.919219 +3409 3299 -15135156.45706 +3410 3299 -113860390.812 +3411 3299 19005396.74573 +3412 3299 59528200.21841 +3413 3299 -86717110.56998 +3426 3299 -10821935.79869 +3427 3299 -10486146.20919 +3428 3299 -13681836.08202 +3429 3299 -68496349.59065 +3430 3299 -1461509.109081 +3431 3299 -86067604.18011 +3432 3299 -15946233.92645 +3433 3299 17623591.55946 +3434 3299 -33840037.48144 +3300 3300 588770587.9403 +3301 3300 7652236.866376 +3302 3300 446911.4688625 +3318 3300 -95938327.17325 +3319 3300 -62221889.125 +3320 3300 3753790.277217 +3321 3300 -169290249.2095 +3322 3300 16019779.71915 +3323 3300 -1089860.549835 +3324 3300 69942878.16334 +3325 3300 -19874379.98696 +3326 3300 -121964.6218983 +3327 3300 -61207996.79291 +3328 3300 58632753.45702 +3329 3300 -879534.2312962 +3390 3300 -9124574.864806 +3391 3300 18767428.98916 +3392 3300 16759462.39556 +3408 3300 -28508580.62171 +3409 3300 -18345108.14763 +3410 3300 -16671081.90644 +3411 3300 35679552.15368 +3412 3300 1655379.388776 +3413 3300 14165948.25441 +3429 3300 -32510576.07318 +3430 3300 -15574325.71153 +3431 3300 -16880670.05429 +3432 3300 -88819293.76525 +3433 3300 3437545.20277 +3434 3300 -70500570.73188 +3435 3300 -7622122.072972 +3436 3300 -4729780.206454 +3437 3300 7040650.668737 +3438 3300 -28304511.99637 +3439 3300 14788860.4849 +3440 3300 -17524016.40433 +3301 3301 679134303.0822 +3302 3301 -11620757.79788 +3318 3301 -62221889.125 +3319 3301 -68870616.90601 +3320 3301 1214164.49255 +3321 3301 16019779.71915 +3322 3301 84011428.11482 +3323 3301 -3414009.299908 +3324 3301 5125620.008936 +3325 3301 -51269016.14184 +3326 3301 497911.9161388 +3327 3301 58632753.45702 +3328 3301 -64548801.20942 +3329 3301 529627.1496301 +3390 3301 12511619.32611 +3391 3301 -14231534.33912 +3392 3301 -13158898.02962 +3408 3301 -18339298.48663 +3409 3301 -83716444.71977 +3410 3301 -54581883.12002 +3411 3301 1655379.388774 +3412 3301 56036966.87791 +3413 3301 1932874.632548 +3429 3301 -15574325.71153 +3430 3301 -26045146.46973 +3431 3301 -13941698.99809 +3432 3301 3437545.202769 +3433 3301 -24846613.1138 +3434 3301 1574541.669722 +3435 3301 1520219.795599 +3436 3301 -37884423.86236 +3437 3301 33456830.95586 +3438 3301 14788860.4849 +3439 3301 -28522911.61373 +3440 3301 16796943.73319 +3302 3302 656403085.8504 +3318 3302 3753790.277555 +3319 3302 1214164.49282 +3320 3302 -18712183.00421 +3321 3302 -1089860.549835 +3322 3302 -3414009.299908 +3323 3302 99513420.62195 +3324 3302 -121964.6218953 +3325 3302 497911.9161386 +3326 3302 75507335.14742 +3327 3302 -879534.2309586 +3328 3302 529627.1496301 +3329 3302 -659231.5568017 +3390 3302 11172974.93037 +3391 3302 -17628488.72141 +3392 3302 -19225240.16517 +3408 3302 -16666052.77693 +3409 3302 -54583174.79693 +3410 3302 -66402853.6308 +3411 3302 -13932732.29653 +3412 3302 -7556887.577361 +3413 3302 -135188700.698 +3429 3302 -16880670.05429 +3430 3302 -13941698.99809 +3431 3302 -27798747.1414 +3432 3302 -70500570.73222 +3433 3302 1574541.670129 +3434 3302 -94439191.19081 +3435 3302 -1084349.333422 +3436 3302 33456830.95586 +3437 3302 -48399876.41365 +3438 3302 -17524016.40433 +3439 3302 16796943.73319 +3440 3302 -33105676.73507 +3303 3303 521301605.0952 +3304 3303 1.144409179688e-05 +3305 3303 4571806.05256 +3306 3303 60175766.35577 +3307 3303 12499999.99795 +3308 3303 -3143072.791566 +3393 3303 -93459816.96553 +3394 3303 1.579523086548e-06 +3395 3303 66889426.94725 +3396 3303 -38668381.31079 +3397 3303 -15625000.00514 +3398 3303 23108532.96245 +3414 3303 59569111.10081 +3415 3303 1.192092895508e-07 +3416 3303 -13286440.8446 +3417 3303 -16053172.23825 +3418 3303 3125000.001022 +3419 3303 -4393116.289629 +3304 3304 446298107.9608 +3305 3304 -54860549.56088 +3306 3304 -12499999.99795 +3307 3304 -58574084.36832 +3308 3304 27155969.22494 +3393 3304 -6.705522537231e-07 +3394 3304 -24709454.43242 +3395 3304 -6857568.701869 +3396 3304 -15625000.00514 +3397 3304 -33980662.73527 +3398 3304 16657951.02195 +3414 3304 -5.960464477539e-08 +3415 3304 40818236.80798 +3416 3304 -13715137.39698 +3417 3304 -3125000.001031 +3418 3304 -45740634.9339 +3419 3304 34001665.91618 +3305 3305 492908937.5133 +3306 3305 7143385.540075 +3307 3305 27704580.33596 +3308 3305 36160517.58431 +3393 3305 66546545.00303 +3394 3305 -6857568.701869 +3395 3305 -74918497.68596 +3396 3305 23108532.96245 +3397 3305 16657951.02195 +3398 3305 -47038891.18556 +3414 3305 13857934.15094 +3415 3305 -13715137.39698 +3416 3305 -65456206.19348 +3417 3305 4964592.046777 +3418 3305 34001665.91632 +3419 3305 -73885507.49175 +3306 3306 521301605.0952 +3307 3306 1.144409179688e-05 +3308 3306 4571806.05256 +3309 3306 60175766.35577 +3310 3306 12499999.99795 +3311 3306 -3143072.791566 +3393 3306 -25604579.22317 +3394 3306 15625000.00514 +3395 3306 10250460.04156 +3396 3306 -93459816.96553 +3397 3306 1.579523086548e-06 +3398 3306 66889426.94725 +3399 3306 -38668381.31079 +3400 3306 -15625000.00514 +3401 3306 23108532.96245 +3414 3306 10751623.76428 +3415 3306 -3125000.001025 +3416 3306 -1821501.705457 +3417 3306 59569111.10081 +3418 3306 1.192092895508e-07 +3419 3306 -13286440.8446 +3420 3306 -16053172.23825 +3421 3306 3125000.001022 +3422 3306 -4393116.289629 +3307 3307 446298107.9608 +3308 3307 -54860549.56088 +3309 3307 -12499999.99795 +3310 3307 -58574084.36832 +3311 3307 27155969.22494 +3393 3307 15625000.00514 +3394 3307 -20916860.64765 +3395 3307 -9800382.320076 +3396 3307 -6.705522537231e-07 +3397 3307 -24709454.43242 +3398 3307 -6857568.701869 +3399 3307 -15625000.00514 +3400 3307 -33980662.73527 +3401 3307 16657951.02195 +3414 3307 3125000.00103 +3415 3307 -18935838.93137 +3416 3307 -20286528.5192 +3417 3307 -5.960464477539e-08 +3418 3307 40818236.80798 +3419 3307 -13715137.39698 +3420 3307 -3125000.001031 +3421 3307 -45740634.9339 +3422 3307 34001665.91618 +3308 3308 492908937.5133 +3309 3308 7143385.540075 +3310 3308 27704580.33596 +3311 3308 36160517.58431 +3393 3308 10250460.04156 +3394 3308 -9800382.320076 +3395 3308 -12202085.61857 +3396 3308 66546545.00303 +3397 3308 -6857568.701869 +3398 3308 -74918497.68596 +3399 3308 23108532.96245 +3400 3308 16657951.02195 +3401 3308 -47038891.18556 +3414 3308 2392977.462593 +3415 3308 -20286528.51934 +3416 3308 -2406051.485007 +3417 3308 13857934.15094 +3418 3308 -13715137.39698 +3419 3308 -65456206.19348 +3420 3308 4964592.046777 +3421 3308 34001665.91632 +3422 3308 -73885507.49175 +3309 3309 521301605.0952 +3310 3309 1.144409179688e-05 +3311 3309 4571806.05256 +3312 3309 60175766.35577 +3313 3309 12499999.99795 +3314 3309 -3143072.791566 +3396 3309 -25604579.22317 +3397 3309 15625000.00514 +3398 3309 10250460.04156 +3399 3309 -93459816.96553 +3400 3309 1.579523086548e-06 +3401 3309 66889426.94725 +3402 3309 -38668381.31079 +3403 3309 -15625000.00514 +3404 3309 23108532.96245 +3417 3309 10751623.76428 +3418 3309 -3125000.001025 +3419 3309 -1821501.705457 +3420 3309 59569111.10081 +3421 3309 1.192092895508e-07 +3422 3309 -13286440.8446 +3423 3309 -16053172.23825 +3424 3309 3125000.001022 +3425 3309 -4393116.289629 +3310 3310 446298107.9608 +3311 3310 -54860549.56088 +3312 3310 -12499999.99795 +3313 3310 -58574084.36832 +3314 3310 27155969.22494 +3396 3310 15625000.00514 +3397 3310 -20916860.64765 +3398 3310 -9800382.320076 +3399 3310 -6.705522537231e-07 +3400 3310 -24709454.43242 +3401 3310 -6857568.701869 +3402 3310 -15625000.00514 +3403 3310 -33980662.73527 +3404 3310 16657951.02195 +3417 3310 3125000.00103 +3418 3310 -18935838.93137 +3419 3310 -20286528.5192 +3420 3310 -5.960464477539e-08 +3421 3310 40818236.80798 +3422 3310 -13715137.39698 +3423 3310 -3125000.001031 +3424 3310 -45740634.9339 +3425 3310 34001665.91618 +3311 3311 492908937.5133 +3312 3311 7143385.540075 +3313 3311 27704580.33596 +3314 3311 36160517.58431 +3396 3311 10250460.04156 +3397 3311 -9800382.320076 +3398 3311 -12202085.61857 +3399 3311 66546545.00303 +3400 3311 -6857568.701869 +3401 3311 -74918497.68596 +3402 3311 23108532.96245 +3403 3311 16657951.02195 +3404 3311 -47038891.18556 +3417 3311 2392977.462593 +3418 3311 -20286528.51934 +3419 3311 -2406051.485007 +3420 3311 13857934.15094 +3421 3311 -13715137.39698 +3422 3311 -65456206.19348 +3423 3311 4964592.046777 +3424 3311 34001665.91632 +3425 3311 -73885507.49175 +3312 3312 521301605.0952 +3313 3312 1.144409179688e-05 +3314 3312 4571806.05256 +3315 3312 60175766.35577 +3316 3312 12499999.99795 +3317 3312 -3143072.791566 +3399 3312 -25604579.22317 +3400 3312 15625000.00514 +3401 3312 10250460.04156 +3402 3312 -93459816.96553 +3403 3312 1.579523086548e-06 +3404 3312 66889426.94725 +3405 3312 -38668381.31079 +3406 3312 -15625000.00514 +3407 3312 23108532.96245 +3420 3312 10751623.76428 +3421 3312 -3125000.001025 +3422 3312 -1821501.705457 +3423 3312 59569111.10081 +3424 3312 1.192092895508e-07 +3425 3312 -13286440.8446 +3426 3312 -16053172.23825 +3427 3312 3125000.001022 +3428 3312 -4393116.289629 +3313 3313 446298107.9608 +3314 3313 -54860549.56088 +3315 3313 -12499999.99795 +3316 3313 -58574084.36832 +3317 3313 27155969.22494 +3399 3313 15625000.00514 +3400 3313 -20916860.64765 +3401 3313 -9800382.320076 +3402 3313 -6.705522537231e-07 +3403 3313 -24709454.43242 +3404 3313 -6857568.701869 +3405 3313 -15625000.00514 +3406 3313 -33980662.73527 +3407 3313 16657951.02195 +3420 3313 3125000.00103 +3421 3313 -18935838.93137 +3422 3313 -20286528.5192 +3423 3313 -5.960464477539e-08 +3424 3313 40818236.80798 +3425 3313 -13715137.39698 +3426 3313 -3125000.001031 +3427 3313 -45740634.9339 +3428 3313 34001665.91618 +3314 3314 492908937.5133 +3315 3314 7143385.540075 +3316 3314 27704580.33596 +3317 3314 36160517.58431 +3399 3314 10250460.04156 +3400 3314 -9800382.320076 +3401 3314 -12202085.61857 +3402 3314 66546545.00303 +3403 3314 -6857568.701869 +3404 3314 -74918497.68596 +3405 3314 23108532.96245 +3406 3314 16657951.02195 +3407 3314 -47038891.18556 +3420 3314 2392977.462593 +3421 3314 -20286528.51934 +3422 3314 -2406051.485007 +3423 3314 13857934.15094 +3424 3314 -13715137.39698 +3425 3314 -65456206.19348 +3426 3314 4964592.046777 +3427 3314 34001665.91632 +3428 3314 -73885507.49175 +3315 3315 521301605.0952 +3316 3315 1.144409179688e-05 +3317 3315 4571806.05256 +3318 3315 60175766.35577 +3319 3315 12499999.99795 +3320 3315 -3143072.791566 +3402 3315 -25604579.22317 +3403 3315 15625000.00514 +3404 3315 10250460.04156 +3405 3315 -93459816.96553 +3406 3315 1.579523086548e-06 +3407 3315 66889426.94725 +3408 3315 -38668381.31079 +3409 3315 -15625000.00514 +3410 3315 23108532.96245 +3423 3315 10751623.76428 +3424 3315 -3125000.001025 +3425 3315 -1821501.705457 +3426 3315 59569111.10081 +3427 3315 1.192092895508e-07 +3428 3315 -13286440.8446 +3429 3315 -16053172.23825 +3430 3315 3125000.001022 +3431 3315 -4393116.289629 +3316 3316 446298107.9608 +3317 3316 -54860549.56088 +3318 3316 -12499999.99795 +3319 3316 -58574084.36832 +3320 3316 27155969.22494 +3402 3316 15625000.00514 +3403 3316 -20916860.64765 +3404 3316 -9800382.320076 +3405 3316 -6.705522537231e-07 +3406 3316 -24709454.43242 +3407 3316 -6857568.701869 +3408 3316 -15625000.00514 +3409 3316 -33980662.73527 +3410 3316 16657951.02195 +3423 3316 3125000.00103 +3424 3316 -18935838.93137 +3425 3316 -20286528.5192 +3426 3316 -5.960464477539e-08 +3427 3316 40818236.80798 +3428 3316 -13715137.39698 +3429 3316 -3125000.001031 +3430 3316 -45740634.9339 +3431 3316 34001665.91618 +3317 3317 492908937.5133 +3318 3317 7143385.540075 +3319 3317 27704580.33596 +3320 3317 36160517.58431 +3402 3317 10250460.04156 +3403 3317 -9800382.320076 +3404 3317 -12202085.61857 +3405 3317 66546545.00303 +3406 3317 -6857568.701869 +3407 3317 -74918497.68596 +3408 3317 23108532.96245 +3409 3317 16657951.02195 +3410 3317 -47038891.18556 +3423 3317 2392977.462593 +3424 3317 -20286528.51934 +3425 3317 -2406051.485007 +3426 3317 13857934.15094 +3427 3317 -13715137.39698 +3428 3317 -65456206.19348 +3429 3317 4964592.046777 +3430 3317 34001665.91632 +3431 3317 -73885507.49175 +3318 3318 512919684.7442 +3319 3318 277859.0827601 +3320 3318 23183746.35062 +3321 3318 52632871.13715 +3322 3318 -96769.00803724 +3323 3318 419288.9836029 +3405 3318 -25604579.22317 +3406 3318 15625000.00514 +3407 3318 10250460.04156 +3408 3318 -89305058.1739 +3409 3318 2583957.046472 +3410 3318 64629778.85911 +3411 3318 -34387866.91098 +3412 3318 -15574325.71152 +3413 3318 18762819.54075 +3426 3318 10751623.76428 +3427 3318 -3125000.001025 +3428 3318 -1821501.705457 +3429 3318 54397998.43316 +3430 3318 50599.66069502 +3431 3318 -8544829.381506 +3432 3318 -8999605.967961 +3433 3318 439769.0002548 +3434 3318 -473741.2428953 +3319 3319 446243430.4062 +3320 3319 -34445483.83251 +3321 3319 -25096769.00393 +3322 3319 -69066429.4396 +3323 3319 5335868.360457 +3405 3319 15625000.00514 +3406 3319 -20916860.64765 +3407 3319 -9800382.320076 +3408 3319 2583957.04647 +3409 3319 -23430492.04089 +3410 3319 -6553522.997743 +3411 3319 -15574325.71152 +3412 3319 -27922437.30753 +3413 3319 14573926.01127 +3426 3319 3125000.00103 +3427 3319 -18935838.93137 +3428 3319 -20286528.5192 +3429 3319 50599.66069496 +3430 3319 37427394.32585 +3431 3319 -8530220.726501 +3432 3319 -5810231.001798 +3433 3319 -39369253.47696 +3434 3319 32242561.88557 +3320 3320 483393300.2846 +3321 3320 2476580.649929 +3322 3320 5335868.360457 +3323 3320 50197647.73292 +3405 3320 10250460.04156 +3406 3320 -9800382.320076 +3407 3320 -12202085.61857 +3408 3320 66344188.58291 +3409 3320 -6279217.441555 +3410 3320 -76631529.64527 +3411 3320 18762819.54075 +3412 3320 14573926.01127 +3413 3320 -32804856.04221 +3426 3320 2392977.462593 +3427 3320 -20286528.51934 +3428 3320 -2406051.485007 +3429 3320 19284753.94725 +3430 3320 -7981609.61548 +3431 3320 -76421561.87405 +3432 3320 7169279.592269 +3433 3320 32242561.88517 +3434 3320 -47927216.87771 +3321 3321 493979409.6462 +3322 3321 10740346.00452 +3323 3321 -162501.3412886 +3324 3321 -102481955.1195 +3325 3321 -66367246.52247 +3326 3321 834875.4907987 +3327 3321 48903259.76668 +3328 3321 4405393.863676 +3329 3321 -310234.8039477 +3408 3321 -25379569.00674 +3409 3321 15222863.21497 +3410 3321 13675467.47217 +3411 3321 -88164971.38851 +3412 3321 3437545.202782 +3413 3321 69992832.02249 +3429 3321 -3493491.887329 +3430 3321 -5810231.0018 +3431 3321 -5981206.519598 +3432 3321 36561069.75252 +3433 3321 2225739.982271 +3434 3321 -14060665.87398 +3435 3321 -37337194.291 +3436 3321 -16461139.52537 +3437 3321 20518691.9415 +3438 3321 -10818972.69166 +3439 3321 1385222.127153 +3440 3321 -534841.2643511 +3322 3322 481892445.1481 +3323 3322 -8075954.830394 +3324 3322 -66367246.52247 +3325 3322 -80026535.58188 +3326 3322 529627.1496299 +3327 3322 -20594606.13222 +3328 3322 -70546891.70076 +3329 3322 1620596.681338 +3408 3322 15222863.21497 +3409 3322 -29533227.73396 +3410 3322 -15709741.78482 +3411 3322 3437545.202781 +3412 3322 -24192290.73706 +3413 3322 -3243166.662888 +3429 3322 439769.0002542 +3430 3322 -33863139.39634 +3431 3322 -29606396.43753 +3432 3322 2225739.982274 +3433 3322 31531560.9283 +3434 3322 -1968582.791773 +3435 3322 -16461139.52537 +3436 3322 -31910167.47421 +3437 3322 16796943.73319 +3438 3322 -4864777.874899 +3439 3322 -40665865.09945 +3440 3322 33730943.9438 +3323 3323 510808562.0931 +3324 3323 834875.4907988 +3325 3323 529627.1496299 +3326 3323 -16136965.92926 +3327 3323 375529.0848255 +3328 3323 1620596.681338 +3329 3323 58235035.49457 +3408 3323 13675467.47217 +3409 3323 -15709741.78482 +3410 3323 -25626134.39224 +3411 3323 69992832.02282 +3412 3323 -3243166.662346 +3413 3323 -92694331.5195 +3429 3323 633168.4820659 +3430 3323 -29606396.43807 +3431 3323 -33244245.99602 +3432 3323 14038014.67696 +3433 3323 -1968582.791773 +3434 3323 -106482561.1728 +3435 3323 20518691.9415 +3436 3323 16796943.73319 +3437 3323 -36492932.59555 +3438 3323 6557242.07182 +3439 3323 33730943.9438 +3440 3323 -48481473.02449 +3324 3324 273404566.2226 +3325 3324 69874379.97876 +3326 3324 -449505.2853138 +3327 3324 -93670600.38049 +3328 3324 -8632753.465224 +3329 3324 -263405.5835879 +3411 3324 -7073510.961695 +3412 3324 1520219.795598 +3413 3324 1018862.4752 +3432 3324 -36788583.17971 +3433 3324 -16461139.52537 +3434 3324 -20106308.07184 +3435 3324 18212288.76877 +3436 3324 17229780.21056 +3437 3324 8014875.950861 +3438 3324 -47947639.07035 +3439 3324 -2288860.480793 +3440 3324 -37677430.35422 +3325 3325 242272710.5527 +3326 3325 -497911.9161291 +3327 3325 16367246.53067 +3328 3325 36217730.05694 +3329 3325 -529627.1496239 +3411 3325 -4729780.206456 +3412 3325 -37335812.75109 +3413 3325 -33209835.69985 +3432 3325 -16461139.52537 +3433 3325 -31361556.36294 +3434 3325 -16536389.61109 +3435 3325 17229780.21056 +3436 3325 10388653.04564 +3437 3325 6543169.037562 +3438 3325 3961139.521261 +3439 3325 -15288728.37461 +3440 3325 3203056.273373 +3326 3326 281492099.9733 +3327 3326 -263405.5835847 +3328 3326 -529627.149624 +3329 3326 51657234.50443 +3411 3326 -7106137.526792 +3412 3326 -33209835.69985 +3413 3326 -46936913.45023 +3432 3326 -20106308.07184 +3433 3326 -16536389.61109 +3434 3326 -35029969.63213 +3435 3326 -8235124.04647 +3436 3326 -6790164.293581 +3437 3326 -63008116.61013 +3438 3326 -37677430.35489 +3439 3326 -3463610.395482 +3440 3326 -51284852.15548 +3327 3327 244365115.1874 +3328 3327 -54405393.85547 +3329 3327 -604117.0485091 +3411 3327 -27755900.88508 +3412 3327 14788860.4849 +3413 3327 17079195.4126 +3432 3327 -9173139.358883 +3433 3327 -4864777.874901 +3434 3327 -6385188.485611 +3435 3327 -47947639.07035 +3436 3327 3961139.521267 +3437 3327 37550781.4389 +3438 3327 15681790.42398 +3439 3327 -13885222.13126 +3440 3327 -7063816.143437 +3328 3328 237267740.6339 +3329 3328 -1620596.681323 +3411 3328 14788860.4849 +3412 3328 -27974300.50245 +3413 3328 -16536389.61109 +3432 3328 1385222.127153 +3433 3328 -39020031.76669 +3434 3328 -32935722.71191 +3435 3328 -2288860.480787 +3436 3328 -15288728.37461 +3437 3328 3203056.273374 +3438 3328 -13885222.13126 +3439 3328 13088171.7534 +3440 3328 6269056.04962 +3329 3329 259806368.9729 +3411 3329 17079195.4126 +3412 3329 -16536389.61109 +3413 3329 -31642713.77164 +3432 3329 364012.9061733 +3433 3329 -32935722.71191 +3434 3329 -44092584.13708 +3435 3329 37550781.43839 +3436 3329 -3463610.395482 +3437 3329 -51284852.15548 +3438 3329 6777468.576512 +3439 3329 -7064277.281522 +3440 3329 -57499553.64335 +3330 3330 672539349.2322 +3331 3330 62499999.98975 +3332 3330 33164131.31328 +3333 3330 -347114474.3686 +3334 3330 -62519355.57327 +3335 3330 -27670762.35809 +3336 3330 9372586.160465 +3337 3330 50019355.57532 +3338 3330 -19895735.37814 +3441 3330 64179725.07093 +3442 3330 15625000.00514 +3443 3330 22379883.77153 +3444 3330 -131080904.1793 +3445 3330 -15629389.46552 +3446 3330 -81477706.67803 +3447 3330 -28030795.60664 +3448 3330 12504389.4645 +3449 3330 -20094076.36695 +3331 3331 578763407.3196 +3332 3331 -63106764.95873 +3333 3331 -62529033.36503 +3334 3331 -53301772.56443 +3335 3331 -38274305.78037 +3336 3331 75029033.36299 +3337 3331 9372586.160465 +3338 3331 25519231.22886 +3441 3331 15625000.00513 +3442 3331 40736294.19042 +3443 3331 -4504985.17355 +3444 3331 -15631584.19572 +3445 3331 -57629159.23151 +3446 3331 -24484028.50059 +3447 3331 18756584.19674 +3448 3331 -28030795.60664 +3449 3331 24112532.59506 +3332 3332 671642303.0214 +3333 3332 -24924077.88049 +3334 3332 -30316506.48178 +3335 3332 -3879396.610056 +3336 3332 -29843603.06721 +3337 3332 17012820.81924 +3338 3332 24993563.09457 +3441 3332 -7512792.611826 +3442 3332 -28418903.81719 +3443 3332 -109296917.9411 +3444 3332 -81133941.74793 +3445 3332 -22561100.97091 +3446 3332 -119114540.4154 +3447 3332 -30141114.55043 +3448 3332 16075021.73004 +3449 3332 -74748788.28438 +3333 3333 1145935402.266 +3334 3333 62548388.94858 +3335 3333 30860151.66558 +3336 3333 21182372.10022 +3337 3333 -62519355.57328 +3338 3333 27039120.36991 +3339 3333 -234498519.637 +3340 3333 3.576278686523e-06 +3341 3333 -5943331.630163 +3342 3333 -94399229.23175 +3343 3333 62499999.98975 +3344 3333 -27030537.76527 +3441 3333 -115335214.0726 +3442 3333 -15631584.19572 +3443 3333 68329440.16886 +3444 3333 130473837.5578 +3445 3333 15635973.65611 +3446 3333 7712253.313144 +3447 3333 -53686446.86531 +3448 3333 -15629389.46553 +3449 3333 25401550.08976 +3450 3333 -102220422.2785 +3451 3333 1.013278961182e-06 +3452 3333 -76032967.78832 +3453 3333 -41874328.64406 +3454 3333 15625000.00513 +3455 3333 -25394418.17384 +3334 3334 977156127.6318 +3335 3334 -85033333.84819 +3336 3334 -62529033.36504 +3337 3334 -197605220.9809 +3338 3334 46638027.38239 +3339 3334 4.14252281189e-06 +3340 3334 40502862.18745 +3341 3334 -27430287.99363 +3342 3334 62499999.98975 +3343 3334 -75648396.04218 +3344 3334 15223824.55232 +3441 3334 -15629389.46552 +3442 3334 -41883469.12474 +3443 3334 7334445.059211 +3444 3334 15635973.65611 +3445 3334 88279612.65644 +3446 3334 -21260570.15053 +3447 3334 -15631584.19572 +3448 3334 -108382459.4402 +3449 3334 71307025.97358 +3450 3334 -7.748603820801e-07 +3451 3334 -33470093.0295 +3452 3334 -6857575.146393 +3453 3334 15625000.00513 +3454 3334 -37186630.13654 +3455 3334 18715245.91155 +3335 3335 1036803405.136 +3336 3335 26700529.72734 +3337 3335 52127606.5745 +3338 3335 32215992.22129 +3339 3335 -3200276.075057 +3340 3335 -27430287.99363 +3341 3335 71900937.83954 +3342 3335 -26687655.82037 +3343 3335 14949518.99641 +3344 3335 -27424184.68052 +3441 3335 67985675.23876 +3442 3335 5415714.150796 +3443 3335 -77126033.46393 +3444 3335 7717499.145858 +3445 3335 -21256373.52338 +3446 3335 -156819638.9591 +3447 3335 25405116.04772 +3448 3335 72953597.68388 +3449 3335 -149232299.5136 +3450 3335 -75690085.8441 +3451 3335 -6857575.146393 +3452 3335 -98280306.98791 +3453 3335 -25394418.17384 +3454 3335 18715245.91155 +3455 3335 -55588121.11081 +3336 3336 672539349.2322 +3337 3336 62499999.98975 +3338 3336 33164131.31328 +3339 3336 -93044845.55145 +3340 3336 -62499999.98975 +3341 3336 24401753.89294 +3342 3336 -347114474.3686 +3343 3336 -62519355.57327 +3344 3336 -27670762.35809 +3345 3336 9372586.160465 +3346 3336 50019355.57532 +3347 3336 -19895735.37814 +3441 3336 1493260.574915 +3442 3336 18756584.19674 +3443 3336 14705768.01689 +3444 3336 -8426923.443562 +3445 3336 -15631584.19572 +3446 3336 -11969908.87826 +3447 3336 64179725.07093 +3448 3336 15625000.00514 +3449 3336 22379883.77153 +3450 3336 -26778951.03495 +3451 3336 -15625000.00513 +3452 3336 -12536345.25295 +3453 3336 -131080904.1793 +3454 3336 -15629389.46552 +3455 3336 -81477706.67803 +3456 3336 -28030795.60664 +3457 3336 12504389.4645 +3458 3336 -20094076.36695 +3337 3337 578763407.3196 +3338 3337 -63106764.95873 +3339 3337 -62499999.98975 +3340 3337 -74294012.36186 +3341 3337 12206463.4413 +3342 3337 -62529033.36503 +3343 3337 -53301772.56443 +3344 3337 -38274305.78037 +3345 3337 75029033.36299 +3346 3337 9372586.160465 +3347 3337 25519231.22886 +3441 3337 12504389.4645 +3442 3337 1493260.574915 +3443 3337 -7843093.74256 +3444 3337 -15629389.46552 +3445 3337 -63122936.0184 +3446 3337 -46615995.93793 +3447 3337 15625000.00513 +3448 3337 40736294.19042 +3449 3337 -4504985.17355 +3450 3337 -15625000.00513 +3451 3337 -22091252.52743 +3452 3337 -11857670.76516 +3453 3337 -15631584.19572 +3454 3337 -57629159.23151 +3455 3337 -24484028.50059 +3456 3337 18756584.19674 +3457 3337 -28030795.60664 +3458 3337 24112532.59506 +3338 3338 671642303.0214 +3339 3338 24744635.83784 +3340 3338 12480768.99722 +3341 3338 -23812494.86631 +3342 3338 -24924077.88049 +3343 3338 -30316506.48178 +3344 3338 -3879396.610056 +3345 3338 -29843603.06721 +3346 3338 17012820.81924 +3347 3338 24993563.09457 +3441 3338 9803845.344592 +3442 3338 -11764640.61384 +3443 3338 3982028.199772 +3444 3338 -11968229.26313 +3445 3338 -48262567.85004 +3446 3338 -28540237.05556 +3447 3338 -7512792.611826 +3448 3338 -28418903.81719 +3449 3338 -109296917.9411 +3450 3338 -12536345.25295 +3451 3338 -11857670.76516 +3452 3338 -15333780.81983 +3453 3338 -81133941.74793 +3454 3338 -22561100.97091 +3455 3338 -119114540.4154 +3456 3338 -30141114.55043 +3457 3338 16075021.73004 +3458 3338 -74748788.28438 +3339 3339 1062868161.752 +3340 3339 1.955032348633e-05 +3341 3339 9143607.705144 +3342 3339 125282264.7016 +3343 3339 -9.357929229736e-06 +3344 3339 2285901.927418 +3348 3339 -234498519.637 +3349 3339 3.576278686523e-06 +3350 3339 -5943331.630163 +3351 3339 -94399229.23175 +3352 3339 62499999.98975 +3353 3339 -27030537.76527 +3444 3339 -98285243.92273 +3445 3339 1.072883605957e-06 +3446 3339 73747066.90912 +3447 3339 -40551938.13439 +3448 3339 -15625000.00514 +3449 3339 24822942.95376 +3450 3339 99158852.54101 +3451 3339 3.457069396973e-06 +3452 3339 2285900.879224 +3453 3339 -39821273.75826 +3454 3339 -8.895993232727e-06 +3455 3339 571475.2200941 +3459 3339 -102220422.2785 +3460 3339 1.013278961182e-06 +3461 3339 -76032967.78832 +3462 3339 -41874328.64406 +3463 3339 15625000.00513 +3464 3339 -25394418.17384 +3340 3340 912861496.3092 +3341 3340 -109721151.9205 +3342 3340 -9.924173355103e-06 +3343 3340 -112217450.7807 +3344 3340 55957798.18227 +3348 3340 4.14252281189e-06 +3349 3340 40502862.18745 +3350 3340 -27430287.99363 +3351 3340 62499999.98975 +3352 3340 -75648396.04218 +3353 3340 15223824.55232 +3444 3340 -4.172325134277e-07 +3445 3340 -29534914.67368 +3446 3340 -6857575.146393 +3447 3340 -15625000.00514 +3448 3340 -35864239.62686 +3449 3340 18029482.02244 +3450 3340 3.814697265625e-06 +3451 3340 61657264.49931 +3452 3340 -27430300.57206 +3453 3340 -7.718801498413e-06 +3454 3340 -99196206.00148 +3455 3340 73626608.60945 +3459 3340 -7.748603820801e-07 +3460 3340 -33470093.0295 +3461 3340 -6857575.146393 +3462 3340 15625000.00513 +3463 3340 -37186630.13654 +3464 3340 18715245.91155 +3341 3341 1039858352.722 +3342 3341 2285901.927418 +3343 3341 53763353.73819 +3344 3341 85469901.76562 +3348 3341 -3200276.075057 +3349 3341 -27430287.99363 +3350 3341 71900937.83954 +3351 3341 -26687655.82037 +3352 3341 14949518.99641 +3353 3341 -27424184.68052 +3444 3341 73404184.96491 +3445 3341 -6857575.146392 +3446 3341 -87786498.03904 +3447 3341 24822942.95376 +3448 3341 18029482.02244 +3449 3341 -52061746.4183 +3450 3341 2285900.879224 +3451 3341 -27430300.57206 +3452 3341 -184190435.19 +3453 3341 571475.2200943 +3454 3341 73352303.05408 +3455 3341 -168344038.6739 +3459 3341 -75690085.8441 +3460 3341 -6857575.146393 +3461 3341 -98280306.98791 +3462 3341 -25394418.17384 +3463 3341 18715245.91155 +3464 3341 -55588121.11081 +3342 3342 1145935402.266 +3343 3342 62548388.94858 +3344 3342 30860151.66558 +3345 3342 21182372.10022 +3346 3342 -62519355.57328 +3347 3342 27039120.36991 +3348 3342 -93044845.55145 +3349 3342 -62499999.98975 +3350 3342 24401753.89294 +3351 3342 -234498519.637 +3352 3342 3.576278686523e-06 +3353 3342 -5943331.630163 +3354 3342 -94399229.23175 +3355 3342 62499999.98975 +3356 3342 -27030537.76527 +3444 3342 -26133752.36576 +3445 3342 15625000.00514 +3446 3342 11964870.03287 +3447 3342 -115335214.0726 +3448 3342 -15631584.19572 +3449 3342 68329440.16886 +3450 3342 19205852.96814 +3451 3342 4.768371582031e-06 +3452 3342 571475.220082 +3453 3342 130473837.5578 +3454 3342 15635973.65611 +3455 3342 7712253.313144 +3456 3342 -53686446.86531 +3457 3342 -15629389.46553 +3458 3342 25401550.08976 +3459 3342 -26778951.03495 +3460 3342 -15625000.00513 +3461 3342 -12536345.25295 +3462 3342 -102220422.2785 +3463 3342 1.013278961182e-06 +3464 3342 -76032967.78832 +3465 3342 -41874328.64406 +3466 3342 15625000.00513 +3467 3342 -25394418.17384 +3343 3343 977156127.6318 +3344 3343 -85033333.84819 +3345 3343 -62529033.36504 +3346 3343 -197605220.9809 +3347 3343 46638027.38239 +3348 3343 -62499999.98975 +3349 3343 -74294012.36186 +3350 3343 12206463.4413 +3351 3343 4.14252281189e-06 +3352 3343 40502862.18745 +3353 3343 -27430287.99363 +3354 3343 62499999.98975 +3355 3343 -75648396.04218 +3356 3343 15223824.55232 +3444 3343 15625000.00514 +3445 3343 -21446053.85824 +3446 3343 -11171906.87604 +3447 3343 -15629389.46552 +3448 3343 -41883469.12474 +3449 3343 7334445.059211 +3450 3343 6.780028343201e-06 +3451 3343 -40169079.27509 +3452 3343 -46196308.03739 +3453 3343 15635973.65611 +3454 3343 88279612.65644 +3455 3343 -21260570.15053 +3456 3343 -15631584.19572 +3457 3343 -108382459.4402 +3458 3343 71307025.97358 +3459 3343 -15625000.00513 +3460 3343 -22091252.52743 +3461 3343 -11857670.76516 +3462 3343 -7.748603820801e-07 +3463 3343 -33470093.0295 +3464 3343 -6857575.146393 +3465 3343 15625000.00513 +3466 3343 -37186630.13654 +3467 3343 18715245.91155 +3344 3344 1036803405.136 +3345 3344 26700529.72734 +3346 3344 52127606.5745 +3347 3344 32215992.22129 +3348 3344 24744635.83784 +3349 3344 12480768.99722 +3350 3344 -23812494.86631 +3351 3344 -3200276.075057 +3352 3344 -27430287.99363 +3353 3344 71900937.83954 +3354 3344 -26687655.82037 +3355 3344 14949518.99641 +3356 3344 -27424184.68052 +3444 3344 11964870.03287 +3445 3344 -11171906.87604 +3446 3344 -13613251.03531 +3447 3344 67985675.23876 +3448 3344 5415714.150796 +3449 3344 -77126033.46393 +3450 3344 571475.2200821 +3451 3344 -45922002.48202 +3452 3344 -10938367.40355 +3453 3344 7717499.145858 +3454 3344 -21256373.52338 +3455 3344 -156819638.9591 +3456 3344 25405116.04772 +3457 3344 72953597.68388 +3458 3344 -149232299.5136 +3459 3344 -12536345.25295 +3460 3344 -11857670.76516 +3461 3344 -15333780.81983 +3462 3344 -75690085.8441 +3463 3344 -6857575.146393 +3464 3344 -98280306.98791 +3465 3344 -25394418.17384 +3466 3344 18715245.91155 +3467 3344 -55588121.11081 +3345 3345 672539349.2322 +3346 3345 62499999.98975 +3347 3345 33164131.31328 +3351 3345 -93044845.55145 +3352 3345 -62499999.98975 +3353 3345 24401753.89294 +3354 3345 -347114474.3686 +3355 3345 -62519355.57327 +3356 3345 -27670762.35809 +3357 3345 9372586.160465 +3358 3345 50019355.57532 +3359 3345 -19895735.37814 +3447 3345 1493260.574915 +3448 3345 18756584.19674 +3449 3345 14705768.01689 +3453 3345 -8426923.443562 +3454 3345 -15631584.19572 +3455 3345 -11969908.87826 +3456 3345 64179725.07093 +3457 3345 15625000.00514 +3458 3345 22379883.77153 +3462 3345 -26778951.03495 +3463 3345 -15625000.00513 +3464 3345 -12536345.25295 +3465 3345 -131080904.1793 +3466 3345 -15629389.46552 +3467 3345 -81477706.67803 +3468 3345 -28030795.60664 +3469 3345 12504389.4645 +3470 3345 -20094076.36695 +3346 3346 578763407.3196 +3347 3346 -63106764.95873 +3351 3346 -62499999.98975 +3352 3346 -74294012.36186 +3353 3346 12206463.4413 +3354 3346 -62529033.36503 +3355 3346 -53301772.56443 +3356 3346 -38274305.78037 +3357 3346 75029033.36299 +3358 3346 9372586.160465 +3359 3346 25519231.22886 +3447 3346 12504389.4645 +3448 3346 1493260.574915 +3449 3346 -7843093.74256 +3453 3346 -15629389.46552 +3454 3346 -63122936.0184 +3455 3346 -46615995.93793 +3456 3346 15625000.00513 +3457 3346 40736294.19042 +3458 3346 -4504985.17355 +3462 3346 -15625000.00513 +3463 3346 -22091252.52743 +3464 3346 -11857670.76516 +3465 3346 -15631584.19572 +3466 3346 -57629159.23151 +3467 3346 -24484028.50059 +3468 3346 18756584.19674 +3469 3346 -28030795.60664 +3470 3346 24112532.59506 +3347 3347 671642303.0214 +3351 3347 24744635.83784 +3352 3347 12480768.99722 +3353 3347 -23812494.86631 +3354 3347 -24924077.88049 +3355 3347 -30316506.48178 +3356 3347 -3879396.610056 +3357 3347 -29843603.06721 +3358 3347 17012820.81924 +3359 3347 24993563.09457 +3447 3347 9803845.344592 +3448 3347 -11764640.61384 +3449 3347 3982028.199772 +3453 3347 -11968229.26313 +3454 3347 -48262567.85004 +3455 3347 -28540237.05556 +3456 3347 -7512792.611826 +3457 3347 -28418903.81719 +3458 3347 -109296917.9411 +3462 3347 -12536345.25295 +3463 3347 -11857670.76516 +3464 3347 -15333780.81983 +3465 3347 -81133941.74793 +3466 3347 -22561100.97091 +3467 3347 -119114540.4154 +3468 3347 -30141114.55043 +3469 3347 16075021.73004 +3470 3347 -74748788.28438 +3348 3348 1062868161.752 +3349 3348 1.955032348633e-05 +3350 3348 9143607.705144 +3351 3348 125282264.7016 +3352 3348 -9.357929229736e-06 +3353 3348 2285901.927418 +3360 3348 -234498519.637 +3361 3348 3.576278686523e-06 +3362 3348 -5943331.630163 +3363 3348 -94399229.23175 +3364 3348 62499999.98975 +3365 3348 -27030537.76527 +3450 3348 -98285243.92273 +3451 3348 1.072883605957e-06 +3452 3348 73747066.90912 +3453 3348 -40551938.13439 +3454 3348 -15625000.00514 +3455 3348 24822942.95376 +3459 3348 99158852.54101 +3460 3348 3.457069396973e-06 +3461 3348 2285900.879224 +3462 3348 -39821273.75826 +3463 3348 -8.895993232727e-06 +3464 3348 571475.2200941 +3471 3348 -102220422.2785 +3472 3348 1.013278961182e-06 +3473 3348 -76032967.78832 +3474 3348 -41874328.64406 +3475 3348 15625000.00513 +3476 3348 -25394418.17384 +3349 3349 912861496.3092 +3350 3349 -109721151.9205 +3351 3349 -9.924173355103e-06 +3352 3349 -112217450.7807 +3353 3349 55957798.18227 +3360 3349 4.14252281189e-06 +3361 3349 40502862.18745 +3362 3349 -27430287.99363 +3363 3349 62499999.98975 +3364 3349 -75648396.04218 +3365 3349 15223824.55232 +3450 3349 -4.172325134277e-07 +3451 3349 -29534914.67368 +3452 3349 -6857575.146393 +3453 3349 -15625000.00514 +3454 3349 -35864239.62686 +3455 3349 18029482.02244 +3459 3349 3.814697265625e-06 +3460 3349 61657264.49931 +3461 3349 -27430300.57206 +3462 3349 -7.718801498413e-06 +3463 3349 -99196206.00148 +3464 3349 73626608.60945 +3471 3349 -7.748603820801e-07 +3472 3349 -33470093.0295 +3473 3349 -6857575.146393 +3474 3349 15625000.00513 +3475 3349 -37186630.13654 +3476 3349 18715245.91155 +3350 3350 1039858352.722 +3351 3350 2285901.927418 +3352 3350 53763353.73819 +3353 3350 85469901.76562 +3360 3350 -3200276.075057 +3361 3350 -27430287.99363 +3362 3350 71900937.83954 +3363 3350 -26687655.82037 +3364 3350 14949518.99641 +3365 3350 -27424184.68052 +3450 3350 73404184.96491 +3451 3350 -6857575.146392 +3452 3350 -87786498.03904 +3453 3350 24822942.95376 +3454 3350 18029482.02244 +3455 3350 -52061746.4183 +3459 3350 2285900.879224 +3460 3350 -27430300.57206 +3461 3350 -184190435.19 +3462 3350 571475.2200943 +3463 3350 73352303.05408 +3464 3350 -168344038.6739 +3471 3350 -75690085.8441 +3472 3350 -6857575.146393 +3473 3350 -98280306.98791 +3474 3350 -25394418.17384 +3475 3350 18715245.91155 +3476 3350 -55588121.11081 +3351 3351 1062868161.752 +3352 3351 1.955032348633e-05 +3353 3351 9143607.705144 +3354 3351 125282264.7016 +3355 3351 -9.357929229736e-06 +3356 3351 2285901.927418 +3360 3351 -93044845.55145 +3361 3351 -62499999.98975 +3362 3351 24401753.89294 +3363 3351 -234498519.637 +3364 3351 3.576278686523e-06 +3365 3351 -5943331.630163 +3366 3351 -94399229.23175 +3367 3351 62499999.98975 +3368 3351 -27030537.76527 +3450 3351 -26133752.36576 +3451 3351 15625000.00514 +3452 3351 11964870.03287 +3453 3351 -98285243.92273 +3454 3351 1.072883605957e-06 +3455 3351 73747066.90912 +3456 3351 -40551938.13439 +3457 3351 -15625000.00514 +3458 3351 24822942.95376 +3459 3351 19205852.96814 +3460 3351 4.768371582031e-06 +3461 3351 571475.220082 +3462 3351 99158852.54101 +3463 3351 3.457069396973e-06 +3464 3351 2285900.879224 +3465 3351 -39821273.75826 +3466 3351 -8.895993232727e-06 +3467 3351 571475.2200941 +3471 3351 -26778951.03495 +3472 3351 -15625000.00513 +3473 3351 -12536345.25295 +3474 3351 -102220422.2785 +3475 3351 1.013278961182e-06 +3476 3351 -76032967.78832 +3477 3351 -41874328.64406 +3478 3351 15625000.00513 +3479 3351 -25394418.17384 +3352 3352 912861496.3092 +3353 3352 -109721151.9205 +3354 3352 -9.924173355103e-06 +3355 3352 -112217450.7807 +3356 3352 55957798.18227 +3360 3352 -62499999.98975 +3361 3352 -74294012.36186 +3362 3352 12206463.4413 +3363 3352 4.14252281189e-06 +3364 3352 40502862.18745 +3365 3352 -27430287.99363 +3366 3352 62499999.98975 +3367 3352 -75648396.04218 +3368 3352 15223824.55232 +3450 3352 15625000.00514 +3451 3352 -21446053.85824 +3452 3352 -11171906.87604 +3453 3352 -4.172325134277e-07 +3454 3352 -29534914.67368 +3455 3352 -6857575.146393 +3456 3352 -15625000.00514 +3457 3352 -35864239.62686 +3458 3352 18029482.02244 +3459 3352 6.780028343201e-06 +3460 3352 -40169079.27509 +3461 3352 -46196308.03739 +3462 3352 3.814697265625e-06 +3463 3352 61657264.49931 +3464 3352 -27430300.57206 +3465 3352 -7.718801498413e-06 +3466 3352 -99196206.00148 +3467 3352 73626608.60945 +3471 3352 -15625000.00513 +3472 3352 -22091252.52743 +3473 3352 -11857670.76516 +3474 3352 -7.748603820801e-07 +3475 3352 -33470093.0295 +3476 3352 -6857575.146393 +3477 3352 15625000.00513 +3478 3352 -37186630.13654 +3479 3352 18715245.91155 +3353 3353 1039858352.722 +3354 3353 2285901.927418 +3355 3353 53763353.73819 +3356 3353 85469901.76562 +3360 3353 24744635.83784 +3361 3353 12480768.99722 +3362 3353 -23812494.86631 +3363 3353 -3200276.075057 +3364 3353 -27430287.99363 +3365 3353 71900937.83954 +3366 3353 -26687655.82037 +3367 3353 14949518.99641 +3368 3353 -27424184.68052 +3450 3353 11964870.03287 +3451 3353 -11171906.87604 +3452 3353 -13613251.03531 +3453 3353 73404184.96491 +3454 3353 -6857575.146392 +3455 3353 -87786498.03904 +3456 3353 24822942.95376 +3457 3353 18029482.02244 +3458 3353 -52061746.4183 +3459 3353 571475.2200821 +3460 3353 -45922002.48202 +3461 3353 -10938367.40355 +3462 3353 2285900.879224 +3463 3353 -27430300.57206 +3464 3353 -184190435.19 +3465 3353 571475.2200943 +3466 3353 73352303.05408 +3467 3353 -168344038.6739 +3471 3353 -12536345.25295 +3472 3353 -11857670.76516 +3473 3353 -15333780.81983 +3474 3353 -75690085.8441 +3475 3353 -6857575.146393 +3476 3353 -98280306.98791 +3477 3353 -25394418.17384 +3478 3353 18715245.91155 +3479 3353 -55588121.11081 +3354 3354 1145935402.266 +3355 3354 62548388.94858 +3356 3354 30860151.66558 +3357 3354 21182372.10022 +3358 3354 -62519355.57328 +3359 3354 27039120.36991 +3363 3354 -93044845.55145 +3364 3354 -62499999.98975 +3365 3354 24401753.89294 +3366 3354 -234498519.637 +3367 3354 3.576278686523e-06 +3368 3354 -5943331.630163 +3369 3354 -94399229.23175 +3370 3354 62499999.98975 +3371 3354 -27030537.76527 +3453 3354 -26133752.36576 +3454 3354 15625000.00514 +3455 3354 11964870.03287 +3456 3354 -115335214.0726 +3457 3354 -15631584.19572 +3458 3354 68329440.16886 +3462 3354 19205852.96814 +3463 3354 4.768371582031e-06 +3464 3354 571475.220082 +3465 3354 130473837.5578 +3466 3354 15635973.65611 +3467 3354 7712253.313144 +3468 3354 -53686446.86531 +3469 3354 -15629389.46553 +3470 3354 25401550.08976 +3474 3354 -26778951.03495 +3475 3354 -15625000.00513 +3476 3354 -12536345.25295 +3477 3354 -102220422.2785 +3478 3354 1.013278961182e-06 +3479 3354 -76032967.78832 +3480 3354 -41874328.64406 +3481 3354 15625000.00513 +3482 3354 -25394418.17384 +3355 3355 977156127.6318 +3356 3355 -85033333.84819 +3357 3355 -62529033.36504 +3358 3355 -197605220.9809 +3359 3355 46638027.38239 +3363 3355 -62499999.98975 +3364 3355 -74294012.36186 +3365 3355 12206463.4413 +3366 3355 4.14252281189e-06 +3367 3355 40502862.18745 +3368 3355 -27430287.99363 +3369 3355 62499999.98975 +3370 3355 -75648396.04218 +3371 3355 15223824.55232 +3453 3355 15625000.00514 +3454 3355 -21446053.85824 +3455 3355 -11171906.87604 +3456 3355 -15629389.46552 +3457 3355 -41883469.12474 +3458 3355 7334445.059211 +3462 3355 6.780028343201e-06 +3463 3355 -40169079.27509 +3464 3355 -46196308.03739 +3465 3355 15635973.65611 +3466 3355 88279612.65644 +3467 3355 -21260570.15053 +3468 3355 -15631584.19572 +3469 3355 -108382459.4402 +3470 3355 71307025.97358 +3474 3355 -15625000.00513 +3475 3355 -22091252.52743 +3476 3355 -11857670.76516 +3477 3355 -7.748603820801e-07 +3478 3355 -33470093.0295 +3479 3355 -6857575.146393 +3480 3355 15625000.00513 +3481 3355 -37186630.13654 +3482 3355 18715245.91155 +3356 3356 1036803405.136 +3357 3356 26700529.72734 +3358 3356 52127606.5745 +3359 3356 32215992.22129 +3363 3356 24744635.83784 +3364 3356 12480768.99722 +3365 3356 -23812494.86631 +3366 3356 -3200276.075057 +3367 3356 -27430287.99363 +3368 3356 71900937.83954 +3369 3356 -26687655.82037 +3370 3356 14949518.99641 +3371 3356 -27424184.68052 +3453 3356 11964870.03287 +3454 3356 -11171906.87604 +3455 3356 -13613251.03531 +3456 3356 67985675.23876 +3457 3356 5415714.150796 +3458 3356 -77126033.46393 +3462 3356 571475.2200821 +3463 3356 -45922002.48202 +3464 3356 -10938367.40355 +3465 3356 7717499.145858 +3466 3356 -21256373.52338 +3467 3356 -156819638.9591 +3468 3356 25405116.04772 +3469 3356 72953597.68388 +3470 3356 -149232299.5136 +3474 3356 -12536345.25295 +3475 3356 -11857670.76516 +3476 3356 -15333780.81983 +3477 3356 -75690085.8441 +3478 3356 -6857575.146393 +3479 3356 -98280306.98791 +3480 3356 -25394418.17384 +3481 3356 18715245.91155 +3482 3356 -55588121.11081 +3357 3357 672539349.2322 +3358 3357 62499999.98975 +3359 3357 33164131.31328 +3366 3357 -93044845.55145 +3367 3357 -62499999.98975 +3368 3357 24401753.89294 +3369 3357 -347114474.3686 +3370 3357 -62519355.57327 +3371 3357 -27670762.35809 +3372 3357 9372586.160465 +3373 3357 50019355.57532 +3374 3357 -19895735.37814 +3456 3357 1493260.574915 +3457 3357 18756584.19674 +3458 3357 14705768.01689 +3465 3357 -8426923.443562 +3466 3357 -15631584.19572 +3467 3357 -11969908.87826 +3468 3357 64179725.07093 +3469 3357 15625000.00514 +3470 3357 22379883.77153 +3477 3357 -26778951.03495 +3478 3357 -15625000.00513 +3479 3357 -12536345.25295 +3480 3357 -131080904.1793 +3481 3357 -15629389.46552 +3482 3357 -81477706.67803 +3483 3357 -28030795.60664 +3484 3357 12504389.4645 +3485 3357 -20094076.36695 +3358 3358 578763407.3196 +3359 3358 -63106764.95873 +3366 3358 -62499999.98975 +3367 3358 -74294012.36186 +3368 3358 12206463.4413 +3369 3358 -62529033.36503 +3370 3358 -53301772.56443 +3371 3358 -38274305.78037 +3372 3358 75029033.36299 +3373 3358 9372586.160465 +3374 3358 25519231.22886 +3456 3358 12504389.4645 +3457 3358 1493260.574915 +3458 3358 -7843093.74256 +3465 3358 -15629389.46552 +3466 3358 -63122936.0184 +3467 3358 -46615995.93793 +3468 3358 15625000.00513 +3469 3358 40736294.19042 +3470 3358 -4504985.17355 +3477 3358 -15625000.00513 +3478 3358 -22091252.52743 +3479 3358 -11857670.76516 +3480 3358 -15631584.19572 +3481 3358 -57629159.23151 +3482 3358 -24484028.50059 +3483 3358 18756584.19674 +3484 3358 -28030795.60664 +3485 3358 24112532.59506 +3359 3359 671642303.0214 +3366 3359 24744635.83784 +3367 3359 12480768.99722 +3368 3359 -23812494.86631 +3369 3359 -24924077.88049 +3370 3359 -30316506.48178 +3371 3359 -3879396.610056 +3372 3359 -29843603.06721 +3373 3359 17012820.81924 +3374 3359 24993563.09457 +3456 3359 9803845.344592 +3457 3359 -11764640.61384 +3458 3359 3982028.199772 +3465 3359 -11968229.26313 +3466 3359 -48262567.85004 +3467 3359 -28540237.05556 +3468 3359 -7512792.611826 +3469 3359 -28418903.81719 +3470 3359 -109296917.9411 +3477 3359 -12536345.25295 +3478 3359 -11857670.76516 +3479 3359 -15333780.81983 +3480 3359 -81133941.74793 +3481 3359 -22561100.97091 +3482 3359 -119114540.4154 +3483 3359 -30141114.55043 +3484 3359 16075021.73004 +3485 3359 -74748788.28438 +3360 3360 1062868161.752 +3361 3360 1.955032348633e-05 +3362 3360 9143607.705144 +3363 3360 125282264.7016 +3364 3360 -9.357929229736e-06 +3365 3360 2285901.927418 +3375 3360 -234498519.637 +3376 3360 3.576278686523e-06 +3377 3360 -5943331.630163 +3378 3360 -94399229.23175 +3379 3360 62499999.98975 +3380 3360 -27030537.76527 +3459 3360 -98285243.92273 +3460 3360 1.072883605957e-06 +3461 3360 73747066.90912 +3462 3360 -40551938.13439 +3463 3360 -15625000.00514 +3464 3360 24822942.95376 +3471 3360 99158852.54101 +3472 3360 3.457069396973e-06 +3473 3360 2285900.879224 +3474 3360 -39821273.75826 +3475 3360 -8.895993232727e-06 +3476 3360 571475.2200941 +3486 3360 -102220422.2785 +3487 3360 1.013278961182e-06 +3488 3360 -76032967.78832 +3489 3360 -41874328.64406 +3490 3360 15625000.00513 +3491 3360 -25394418.17384 +3361 3361 912861496.3092 +3362 3361 -109721151.9205 +3363 3361 -9.924173355103e-06 +3364 3361 -112217450.7807 +3365 3361 55957798.18227 +3375 3361 4.14252281189e-06 +3376 3361 40502862.18745 +3377 3361 -27430287.99363 +3378 3361 62499999.98975 +3379 3361 -75648396.04218 +3380 3361 15223824.55232 +3459 3361 -4.172325134277e-07 +3460 3361 -29534914.67368 +3461 3361 -6857575.146393 +3462 3361 -15625000.00514 +3463 3361 -35864239.62686 +3464 3361 18029482.02244 +3471 3361 3.814697265625e-06 +3472 3361 61657264.49931 +3473 3361 -27430300.57206 +3474 3361 -7.718801498413e-06 +3475 3361 -99196206.00148 +3476 3361 73626608.60945 +3486 3361 -7.748603820801e-07 +3487 3361 -33470093.0295 +3488 3361 -6857575.146393 +3489 3361 15625000.00513 +3490 3361 -37186630.13654 +3491 3361 18715245.91155 +3362 3362 1039858352.722 +3363 3362 2285901.927418 +3364 3362 53763353.73819 +3365 3362 85469901.76562 +3375 3362 -3200276.075057 +3376 3362 -27430287.99363 +3377 3362 71900937.83954 +3378 3362 -26687655.82037 +3379 3362 14949518.99641 +3380 3362 -27424184.68052 +3459 3362 73404184.96491 +3460 3362 -6857575.146392 +3461 3362 -87786498.03904 +3462 3362 24822942.95376 +3463 3362 18029482.02244 +3464 3362 -52061746.4183 +3471 3362 2285900.879224 +3472 3362 -27430300.57206 +3473 3362 -184190435.19 +3474 3362 571475.2200943 +3475 3362 73352303.05408 +3476 3362 -168344038.6739 +3486 3362 -75690085.8441 +3487 3362 -6857575.146393 +3488 3362 -98280306.98791 +3489 3362 -25394418.17384 +3490 3362 18715245.91155 +3491 3362 -55588121.11081 +3363 3363 1062868161.752 +3364 3363 1.955032348633e-05 +3365 3363 9143607.705144 +3366 3363 125282264.7016 +3367 3363 -9.357929229736e-06 +3368 3363 2285901.927418 +3375 3363 -93044845.55145 +3376 3363 -62499999.98975 +3377 3363 24401753.89294 +3378 3363 -234498519.637 +3379 3363 3.576278686523e-06 +3380 3363 -5943331.630163 +3381 3363 -94399229.23175 +3382 3363 62499999.98975 +3383 3363 -27030537.76527 +3459 3363 -26133752.36576 +3460 3363 15625000.00514 +3461 3363 11964870.03287 +3462 3363 -98285243.92273 +3463 3363 1.072883605957e-06 +3464 3363 73747066.90912 +3465 3363 -40551938.13439 +3466 3363 -15625000.00514 +3467 3363 24822942.95376 +3471 3363 19205852.96814 +3472 3363 4.768371582031e-06 +3473 3363 571475.220082 +3474 3363 99158852.54101 +3475 3363 3.457069396973e-06 +3476 3363 2285900.879224 +3477 3363 -39821273.75826 +3478 3363 -8.895993232727e-06 +3479 3363 571475.2200941 +3486 3363 -26778951.03495 +3487 3363 -15625000.00513 +3488 3363 -12536345.25295 +3489 3363 -102220422.2785 +3490 3363 1.013278961182e-06 +3491 3363 -76032967.78832 +3492 3363 -41874328.64406 +3493 3363 15625000.00513 +3494 3363 -25394418.17384 +3364 3364 912861496.3092 +3365 3364 -109721151.9205 +3366 3364 -9.924173355103e-06 +3367 3364 -112217450.7807 +3368 3364 55957798.18227 +3375 3364 -62499999.98975 +3376 3364 -74294012.36186 +3377 3364 12206463.4413 +3378 3364 4.14252281189e-06 +3379 3364 40502862.18745 +3380 3364 -27430287.99363 +3381 3364 62499999.98975 +3382 3364 -75648396.04218 +3383 3364 15223824.55232 +3459 3364 15625000.00514 +3460 3364 -21446053.85824 +3461 3364 -11171906.87604 +3462 3364 -4.172325134277e-07 +3463 3364 -29534914.67368 +3464 3364 -6857575.146393 +3465 3364 -15625000.00514 +3466 3364 -35864239.62686 +3467 3364 18029482.02244 +3471 3364 6.780028343201e-06 +3472 3364 -40169079.27509 +3473 3364 -46196308.03739 +3474 3364 3.814697265625e-06 +3475 3364 61657264.49931 +3476 3364 -27430300.57206 +3477 3364 -7.718801498413e-06 +3478 3364 -99196206.00148 +3479 3364 73626608.60945 +3486 3364 -15625000.00513 +3487 3364 -22091252.52743 +3488 3364 -11857670.76516 +3489 3364 -7.748603820801e-07 +3490 3364 -33470093.0295 +3491 3364 -6857575.146393 +3492 3364 15625000.00513 +3493 3364 -37186630.13654 +3494 3364 18715245.91155 +3365 3365 1039858352.722 +3366 3365 2285901.927418 +3367 3365 53763353.73819 +3368 3365 85469901.76562 +3375 3365 24744635.83784 +3376 3365 12480768.99722 +3377 3365 -23812494.86631 +3378 3365 -3200276.075057 +3379 3365 -27430287.99363 +3380 3365 71900937.83954 +3381 3365 -26687655.82037 +3382 3365 14949518.99641 +3383 3365 -27424184.68052 +3459 3365 11964870.03287 +3460 3365 -11171906.87604 +3461 3365 -13613251.03531 +3462 3365 73404184.96491 +3463 3365 -6857575.146392 +3464 3365 -87786498.03904 +3465 3365 24822942.95376 +3466 3365 18029482.02244 +3467 3365 -52061746.4183 +3471 3365 571475.2200821 +3472 3365 -45922002.48202 +3473 3365 -10938367.40355 +3474 3365 2285900.879224 +3475 3365 -27430300.57206 +3476 3365 -184190435.19 +3477 3365 571475.2200943 +3478 3365 73352303.05408 +3479 3365 -168344038.6739 +3486 3365 -12536345.25295 +3487 3365 -11857670.76516 +3488 3365 -15333780.81983 +3489 3365 -75690085.8441 +3490 3365 -6857575.146393 +3491 3365 -98280306.98791 +3492 3365 -25394418.17384 +3493 3365 18715245.91155 +3494 3365 -55588121.11081 +3366 3366 1062868161.752 +3367 3366 1.955032348633e-05 +3368 3366 9143607.705144 +3369 3366 125282264.7016 +3370 3366 -9.357929229736e-06 +3371 3366 2285901.927418 +3378 3366 -93044845.55145 +3379 3366 -62499999.98975 +3380 3366 24401753.89294 +3381 3366 -234498519.637 +3382 3366 3.576278686523e-06 +3383 3366 -5943331.630163 +3384 3366 -94399229.23175 +3385 3366 62499999.98975 +3386 3366 -27030537.76527 +3462 3366 -26133752.36576 +3463 3366 15625000.00514 +3464 3366 11964870.03287 +3465 3366 -98285243.92273 +3466 3366 1.072883605957e-06 +3467 3366 73747066.90912 +3468 3366 -40551938.13439 +3469 3366 -15625000.00514 +3470 3366 24822942.95376 +3474 3366 19205852.96814 +3475 3366 4.768371582031e-06 +3476 3366 571475.220082 +3477 3366 99158852.54101 +3478 3366 3.457069396973e-06 +3479 3366 2285900.879224 +3480 3366 -39821273.75826 +3481 3366 -8.895993232727e-06 +3482 3366 571475.2200941 +3489 3366 -26778951.03495 +3490 3366 -15625000.00513 +3491 3366 -12536345.25295 +3492 3366 -102220422.2785 +3493 3366 1.013278961182e-06 +3494 3366 -76032967.78832 +3495 3366 -41874328.64406 +3496 3366 15625000.00513 +3497 3366 -25394418.17384 +3367 3367 912861496.3092 +3368 3367 -109721151.9205 +3369 3367 -9.924173355103e-06 +3370 3367 -112217450.7807 +3371 3367 55957798.18227 +3378 3367 -62499999.98975 +3379 3367 -74294012.36186 +3380 3367 12206463.4413 +3381 3367 4.14252281189e-06 +3382 3367 40502862.18745 +3383 3367 -27430287.99363 +3384 3367 62499999.98975 +3385 3367 -75648396.04218 +3386 3367 15223824.55232 +3462 3367 15625000.00514 +3463 3367 -21446053.85824 +3464 3367 -11171906.87604 +3465 3367 -4.172325134277e-07 +3466 3367 -29534914.67368 +3467 3367 -6857575.146393 +3468 3367 -15625000.00514 +3469 3367 -35864239.62686 +3470 3367 18029482.02244 +3474 3367 6.780028343201e-06 +3475 3367 -40169079.27509 +3476 3367 -46196308.03739 +3477 3367 3.814697265625e-06 +3478 3367 61657264.49931 +3479 3367 -27430300.57206 +3480 3367 -7.718801498413e-06 +3481 3367 -99196206.00148 +3482 3367 73626608.60945 +3489 3367 -15625000.00513 +3490 3367 -22091252.52743 +3491 3367 -11857670.76516 +3492 3367 -7.748603820801e-07 +3493 3367 -33470093.0295 +3494 3367 -6857575.146393 +3495 3367 15625000.00513 +3496 3367 -37186630.13654 +3497 3367 18715245.91155 +3368 3368 1039858352.722 +3369 3368 2285901.927418 +3370 3368 53763353.73819 +3371 3368 85469901.76562 +3378 3368 24744635.83784 +3379 3368 12480768.99722 +3380 3368 -23812494.86631 +3381 3368 -3200276.075057 +3382 3368 -27430287.99363 +3383 3368 71900937.83954 +3384 3368 -26687655.82037 +3385 3368 14949518.99641 +3386 3368 -27424184.68052 +3462 3368 11964870.03287 +3463 3368 -11171906.87604 +3464 3368 -13613251.03531 +3465 3368 73404184.96491 +3466 3368 -6857575.146392 +3467 3368 -87786498.03904 +3468 3368 24822942.95376 +3469 3368 18029482.02244 +3470 3368 -52061746.4183 +3474 3368 571475.2200821 +3475 3368 -45922002.48202 +3476 3368 -10938367.40355 +3477 3368 2285900.879224 +3478 3368 -27430300.57206 +3479 3368 -184190435.19 +3480 3368 571475.2200943 +3481 3368 73352303.05408 +3482 3368 -168344038.6739 +3489 3368 -12536345.25295 +3490 3368 -11857670.76516 +3491 3368 -15333780.81983 +3492 3368 -75690085.8441 +3493 3368 -6857575.146393 +3494 3368 -98280306.98791 +3495 3368 -25394418.17384 +3496 3368 18715245.91155 +3497 3368 -55588121.11081 +3369 3369 1145935402.266 +3370 3369 62548388.94858 +3371 3369 30860151.66558 +3372 3369 21182372.10022 +3373 3369 -62519355.57328 +3374 3369 27039120.36991 +3381 3369 -93044845.55145 +3382 3369 -62499999.98975 +3383 3369 24401753.89294 +3384 3369 -234498519.637 +3385 3369 3.576278686523e-06 +3386 3369 -5943331.630163 +3387 3369 -94399229.23175 +3388 3369 62499999.98975 +3389 3369 -27030537.76527 +3465 3369 -26133752.36576 +3466 3369 15625000.00514 +3467 3369 11964870.03287 +3468 3369 -115335214.0726 +3469 3369 -15631584.19572 +3470 3369 68329440.16886 +3477 3369 19205852.96814 +3478 3369 4.768371582031e-06 +3479 3369 571475.220082 +3480 3369 130473837.5578 +3481 3369 15635973.65611 +3482 3369 7712253.313144 +3483 3369 -53686446.86531 +3484 3369 -15629389.46553 +3485 3369 25401550.08976 +3492 3369 -26778951.03495 +3493 3369 -15625000.00513 +3494 3369 -12536345.25295 +3495 3369 -102220422.2785 +3496 3369 1.013278961182e-06 +3497 3369 -76032967.78832 +3498 3369 -41874328.64406 +3499 3369 15625000.00513 +3500 3369 -25394418.17384 +3370 3370 977156127.6318 +3371 3370 -85033333.84819 +3372 3370 -62529033.36504 +3373 3370 -197605220.9809 +3374 3370 46638027.38239 +3381 3370 -62499999.98975 +3382 3370 -74294012.36186 +3383 3370 12206463.4413 +3384 3370 4.14252281189e-06 +3385 3370 40502862.18745 +3386 3370 -27430287.99363 +3387 3370 62499999.98975 +3388 3370 -75648396.04218 +3389 3370 15223824.55232 +3465 3370 15625000.00514 +3466 3370 -21446053.85824 +3467 3370 -11171906.87604 +3468 3370 -15629389.46552 +3469 3370 -41883469.12474 +3470 3370 7334445.059211 +3477 3370 6.780028343201e-06 +3478 3370 -40169079.27509 +3479 3370 -46196308.03739 +3480 3370 15635973.65611 +3481 3370 88279612.65644 +3482 3370 -21260570.15053 +3483 3370 -15631584.19572 +3484 3370 -108382459.4402 +3485 3370 71307025.97358 +3492 3370 -15625000.00513 +3493 3370 -22091252.52743 +3494 3370 -11857670.76516 +3495 3370 -7.748603820801e-07 +3496 3370 -33470093.0295 +3497 3370 -6857575.146393 +3498 3370 15625000.00513 +3499 3370 -37186630.13654 +3500 3370 18715245.91155 +3371 3371 1036803405.136 +3372 3371 26700529.72734 +3373 3371 52127606.5745 +3374 3371 32215992.22129 +3381 3371 24744635.83784 +3382 3371 12480768.99722 +3383 3371 -23812494.86631 +3384 3371 -3200276.075057 +3385 3371 -27430287.99363 +3386 3371 71900937.83954 +3387 3371 -26687655.82037 +3388 3371 14949518.99641 +3389 3371 -27424184.68052 +3465 3371 11964870.03287 +3466 3371 -11171906.87604 +3467 3371 -13613251.03531 +3468 3371 67985675.23876 +3469 3371 5415714.150796 +3470 3371 -77126033.46393 +3477 3371 571475.2200821 +3478 3371 -45922002.48202 +3479 3371 -10938367.40355 +3480 3371 7717499.145858 +3481 3371 -21256373.52338 +3482 3371 -156819638.9591 +3483 3371 25405116.04772 +3484 3371 72953597.68388 +3485 3371 -149232299.5136 +3492 3371 -12536345.25295 +3493 3371 -11857670.76516 +3494 3371 -15333780.81983 +3495 3371 -75690085.8441 +3496 3371 -6857575.146393 +3497 3371 -98280306.98791 +3498 3371 -25394418.17384 +3499 3371 18715245.91155 +3500 3371 -55588121.11081 +3372 3372 672539349.2322 +3373 3372 62499999.98975 +3374 3372 33164131.31328 +3384 3372 -93044845.55145 +3385 3372 -62499999.98975 +3386 3372 24401753.89294 +3387 3372 -347114474.3686 +3388 3372 -62519355.57327 +3389 3372 -27670762.35809 +3390 3372 9372586.160465 +3391 3372 50019355.57532 +3392 3372 -19895735.37814 +3468 3372 1493260.574915 +3469 3372 18756584.19674 +3470 3372 14705768.01689 +3480 3372 -8426923.443562 +3481 3372 -15631584.19572 +3482 3372 -11969908.87826 +3483 3372 64179725.07093 +3484 3372 15625000.00514 +3485 3372 22379883.77153 +3495 3372 -26778951.03495 +3496 3372 -15625000.00513 +3497 3372 -12536345.25295 +3498 3372 -131080904.1793 +3499 3372 -15629389.46552 +3500 3372 -81477706.67803 +3501 3372 -28030795.60664 +3502 3372 12504389.4645 +3503 3372 -20094076.36695 +3373 3373 578763407.3196 +3374 3373 -63106764.95873 +3384 3373 -62499999.98975 +3385 3373 -74294012.36186 +3386 3373 12206463.4413 +3387 3373 -62529033.36503 +3388 3373 -53301772.56443 +3389 3373 -38274305.78037 +3390 3373 75029033.36299 +3391 3373 9372586.160465 +3392 3373 25519231.22886 +3468 3373 12504389.4645 +3469 3373 1493260.574915 +3470 3373 -7843093.74256 +3480 3373 -15629389.46552 +3481 3373 -63122936.0184 +3482 3373 -46615995.93793 +3483 3373 15625000.00513 +3484 3373 40736294.19042 +3485 3373 -4504985.17355 +3495 3373 -15625000.00513 +3496 3373 -22091252.52743 +3497 3373 -11857670.76516 +3498 3373 -15631584.19572 +3499 3373 -57629159.23151 +3500 3373 -24484028.50059 +3501 3373 18756584.19674 +3502 3373 -28030795.60664 +3503 3373 24112532.59506 +3374 3374 671642303.0214 +3384 3374 24744635.83784 +3385 3374 12480768.99722 +3386 3374 -23812494.86631 +3387 3374 -24924077.88049 +3388 3374 -30316506.48178 +3389 3374 -3879396.610056 +3390 3374 -29843603.06721 +3391 3374 17012820.81924 +3392 3374 24993563.09457 +3468 3374 9803845.344592 +3469 3374 -11764640.61384 +3470 3374 3982028.199772 +3480 3374 -11968229.26313 +3481 3374 -48262567.85004 +3482 3374 -28540237.05556 +3483 3374 -7512792.611826 +3484 3374 -28418903.81719 +3485 3374 -109296917.9411 +3495 3374 -12536345.25295 +3496 3374 -11857670.76516 +3497 3374 -15333780.81983 +3498 3374 -81133941.74793 +3499 3374 -22561100.97091 +3500 3374 -119114540.4154 +3501 3374 -30141114.55043 +3502 3374 16075021.73004 +3503 3374 -74748788.28438 +3375 3375 1062868161.752 +3376 3375 1.955032348633e-05 +3377 3375 9143607.705144 +3378 3375 125282264.7016 +3379 3375 -9.357929229736e-06 +3380 3375 2285901.927418 +3393 3375 -234498519.637 +3394 3375 3.576278686523e-06 +3395 3375 -5943331.630163 +3396 3375 -94399229.23175 +3397 3375 62499999.98975 +3398 3375 -27030537.76527 +3471 3375 -98285243.92273 +3472 3375 1.072883605957e-06 +3473 3375 73747066.90912 +3474 3375 -40551938.13439 +3475 3375 -15625000.00514 +3476 3375 24822942.95376 +3486 3375 99158852.54101 +3487 3375 3.457069396973e-06 +3488 3375 2285900.879224 +3489 3375 -39821273.75826 +3490 3375 -8.895993232727e-06 +3491 3375 571475.2200941 +3504 3375 -102220422.2785 +3505 3375 1.013278961182e-06 +3506 3375 -76032967.78832 +3507 3375 -41874328.64406 +3508 3375 15625000.00513 +3509 3375 -25394418.17384 +3376 3376 912861496.3092 +3377 3376 -109721151.9205 +3378 3376 -9.924173355103e-06 +3379 3376 -112217450.7807 +3380 3376 55957798.18227 +3393 3376 4.14252281189e-06 +3394 3376 40502862.18745 +3395 3376 -27430287.99363 +3396 3376 62499999.98975 +3397 3376 -75648396.04218 +3398 3376 15223824.55232 +3471 3376 -4.172325134277e-07 +3472 3376 -29534914.67368 +3473 3376 -6857575.146393 +3474 3376 -15625000.00514 +3475 3376 -35864239.62686 +3476 3376 18029482.02244 +3486 3376 3.814697265625e-06 +3487 3376 61657264.49931 +3488 3376 -27430300.57206 +3489 3376 -7.718801498413e-06 +3490 3376 -99196206.00148 +3491 3376 73626608.60945 +3504 3376 -7.748603820801e-07 +3505 3376 -33470093.0295 +3506 3376 -6857575.146393 +3507 3376 15625000.00513 +3508 3376 -37186630.13654 +3509 3376 18715245.91155 +3377 3377 1039858352.722 +3378 3377 2285901.927418 +3379 3377 53763353.73819 +3380 3377 85469901.76562 +3393 3377 -3200276.075057 +3394 3377 -27430287.99363 +3395 3377 71900937.83954 +3396 3377 -26687655.82037 +3397 3377 14949518.99641 +3398 3377 -27424184.68052 +3471 3377 73404184.96491 +3472 3377 -6857575.146392 +3473 3377 -87786498.03904 +3474 3377 24822942.95376 +3475 3377 18029482.02244 +3476 3377 -52061746.4183 +3486 3377 2285900.879224 +3487 3377 -27430300.57206 +3488 3377 -184190435.19 +3489 3377 571475.2200943 +3490 3377 73352303.05408 +3491 3377 -168344038.6739 +3504 3377 -75690085.8441 +3505 3377 -6857575.146393 +3506 3377 -98280306.98791 +3507 3377 -25394418.17384 +3508 3377 18715245.91155 +3509 3377 -55588121.11081 +3378 3378 1062868161.752 +3379 3378 1.955032348633e-05 +3380 3378 9143607.705144 +3381 3378 125282264.7016 +3382 3378 -9.357929229736e-06 +3383 3378 2285901.927418 +3393 3378 -93044845.55145 +3394 3378 -62499999.98975 +3395 3378 24401753.89294 +3396 3378 -234498519.637 +3397 3378 3.576278686523e-06 +3398 3378 -5943331.630163 +3399 3378 -94399229.23175 +3400 3378 62499999.98975 +3401 3378 -27030537.76527 +3471 3378 -26133752.36576 +3472 3378 15625000.00514 +3473 3378 11964870.03287 +3474 3378 -98285243.92273 +3475 3378 1.072883605957e-06 +3476 3378 73747066.90912 +3477 3378 -40551938.13439 +3478 3378 -15625000.00514 +3479 3378 24822942.95376 +3486 3378 19205852.96814 +3487 3378 4.768371582031e-06 +3488 3378 571475.220082 +3489 3378 99158852.54101 +3490 3378 3.457069396973e-06 +3491 3378 2285900.879224 +3492 3378 -39821273.75826 +3493 3378 -8.895993232727e-06 +3494 3378 571475.2200941 +3504 3378 -26778951.03495 +3505 3378 -15625000.00513 +3506 3378 -12536345.25295 +3507 3378 -102220422.2785 +3508 3378 1.013278961182e-06 +3509 3378 -76032967.78832 +3510 3378 -41874328.64406 +3511 3378 15625000.00513 +3512 3378 -25394418.17384 +3379 3379 912861496.3092 +3380 3379 -109721151.9205 +3381 3379 -9.924173355103e-06 +3382 3379 -112217450.7807 +3383 3379 55957798.18227 +3393 3379 -62499999.98975 +3394 3379 -74294012.36186 +3395 3379 12206463.4413 +3396 3379 4.14252281189e-06 +3397 3379 40502862.18745 +3398 3379 -27430287.99363 +3399 3379 62499999.98975 +3400 3379 -75648396.04218 +3401 3379 15223824.55232 +3471 3379 15625000.00514 +3472 3379 -21446053.85824 +3473 3379 -11171906.87604 +3474 3379 -4.172325134277e-07 +3475 3379 -29534914.67368 +3476 3379 -6857575.146393 +3477 3379 -15625000.00514 +3478 3379 -35864239.62686 +3479 3379 18029482.02244 +3486 3379 6.780028343201e-06 +3487 3379 -40169079.27509 +3488 3379 -46196308.03739 +3489 3379 3.814697265625e-06 +3490 3379 61657264.49931 +3491 3379 -27430300.57206 +3492 3379 -7.718801498413e-06 +3493 3379 -99196206.00148 +3494 3379 73626608.60945 +3504 3379 -15625000.00513 +3505 3379 -22091252.52743 +3506 3379 -11857670.76516 +3507 3379 -7.748603820801e-07 +3508 3379 -33470093.0295 +3509 3379 -6857575.146393 +3510 3379 15625000.00513 +3511 3379 -37186630.13654 +3512 3379 18715245.91155 +3380 3380 1039858352.722 +3381 3380 2285901.927418 +3382 3380 53763353.73819 +3383 3380 85469901.76562 +3393 3380 24744635.83784 +3394 3380 12480768.99722 +3395 3380 -23812494.86631 +3396 3380 -3200276.075057 +3397 3380 -27430287.99363 +3398 3380 71900937.83954 +3399 3380 -26687655.82037 +3400 3380 14949518.99641 +3401 3380 -27424184.68052 +3471 3380 11964870.03287 +3472 3380 -11171906.87604 +3473 3380 -13613251.03531 +3474 3380 73404184.96491 +3475 3380 -6857575.146392 +3476 3380 -87786498.03904 +3477 3380 24822942.95376 +3478 3380 18029482.02244 +3479 3380 -52061746.4183 +3486 3380 571475.2200821 +3487 3380 -45922002.48202 +3488 3380 -10938367.40355 +3489 3380 2285900.879224 +3490 3380 -27430300.57206 +3491 3380 -184190435.19 +3492 3380 571475.2200943 +3493 3380 73352303.05408 +3494 3380 -168344038.6739 +3504 3380 -12536345.25295 +3505 3380 -11857670.76516 +3506 3380 -15333780.81983 +3507 3380 -75690085.8441 +3508 3380 -6857575.146393 +3509 3380 -98280306.98791 +3510 3380 -25394418.17384 +3511 3380 18715245.91155 +3512 3380 -55588121.11081 +3381 3381 1062868161.752 +3382 3381 1.955032348633e-05 +3383 3381 9143607.705144 +3384 3381 125282264.7016 +3385 3381 -9.357929229736e-06 +3386 3381 2285901.927418 +3396 3381 -93044845.55145 +3397 3381 -62499999.98975 +3398 3381 24401753.89294 +3399 3381 -234498519.637 +3400 3381 3.576278686523e-06 +3401 3381 -5943331.630163 +3402 3381 -94399229.23175 +3403 3381 62499999.98975 +3404 3381 -27030537.76527 +3474 3381 -26133752.36576 +3475 3381 15625000.00514 +3476 3381 11964870.03287 +3477 3381 -98285243.92273 +3478 3381 1.072883605957e-06 +3479 3381 73747066.90912 +3480 3381 -40551938.13439 +3481 3381 -15625000.00514 +3482 3381 24822942.95376 +3489 3381 19205852.96814 +3490 3381 4.768371582031e-06 +3491 3381 571475.220082 +3492 3381 99158852.54101 +3493 3381 3.457069396973e-06 +3494 3381 2285900.879224 +3495 3381 -39821273.75826 +3496 3381 -8.895993232727e-06 +3497 3381 571475.2200941 +3507 3381 -26778951.03495 +3508 3381 -15625000.00513 +3509 3381 -12536345.25295 +3510 3381 -102220422.2785 +3511 3381 1.013278961182e-06 +3512 3381 -76032967.78832 +3513 3381 -41874328.64406 +3514 3381 15625000.00513 +3515 3381 -25394418.17384 +3382 3382 912861496.3092 +3383 3382 -109721151.9205 +3384 3382 -9.924173355103e-06 +3385 3382 -112217450.7807 +3386 3382 55957798.18227 +3396 3382 -62499999.98975 +3397 3382 -74294012.36186 +3398 3382 12206463.4413 +3399 3382 4.14252281189e-06 +3400 3382 40502862.18745 +3401 3382 -27430287.99363 +3402 3382 62499999.98975 +3403 3382 -75648396.04218 +3404 3382 15223824.55232 +3474 3382 15625000.00514 +3475 3382 -21446053.85824 +3476 3382 -11171906.87604 +3477 3382 -4.172325134277e-07 +3478 3382 -29534914.67368 +3479 3382 -6857575.146393 +3480 3382 -15625000.00514 +3481 3382 -35864239.62686 +3482 3382 18029482.02244 +3489 3382 6.780028343201e-06 +3490 3382 -40169079.27509 +3491 3382 -46196308.03739 +3492 3382 3.814697265625e-06 +3493 3382 61657264.49931 +3494 3382 -27430300.57206 +3495 3382 -7.718801498413e-06 +3496 3382 -99196206.00148 +3497 3382 73626608.60945 +3507 3382 -15625000.00513 +3508 3382 -22091252.52743 +3509 3382 -11857670.76516 +3510 3382 -7.748603820801e-07 +3511 3382 -33470093.0295 +3512 3382 -6857575.146393 +3513 3382 15625000.00513 +3514 3382 -37186630.13654 +3515 3382 18715245.91155 +3383 3383 1039858352.722 +3384 3383 2285901.927418 +3385 3383 53763353.73819 +3386 3383 85469901.76562 +3396 3383 24744635.83784 +3397 3383 12480768.99722 +3398 3383 -23812494.86631 +3399 3383 -3200276.075057 +3400 3383 -27430287.99363 +3401 3383 71900937.83954 +3402 3383 -26687655.82037 +3403 3383 14949518.99641 +3404 3383 -27424184.68052 +3474 3383 11964870.03287 +3475 3383 -11171906.87604 +3476 3383 -13613251.03531 +3477 3383 73404184.96491 +3478 3383 -6857575.146392 +3479 3383 -87786498.03904 +3480 3383 24822942.95376 +3481 3383 18029482.02244 +3482 3383 -52061746.4183 +3489 3383 571475.2200821 +3490 3383 -45922002.48202 +3491 3383 -10938367.40355 +3492 3383 2285900.879224 +3493 3383 -27430300.57206 +3494 3383 -184190435.19 +3495 3383 571475.2200943 +3496 3383 73352303.05408 +3497 3383 -168344038.6739 +3507 3383 -12536345.25295 +3508 3383 -11857670.76516 +3509 3383 -15333780.81983 +3510 3383 -75690085.8441 +3511 3383 -6857575.146393 +3512 3383 -98280306.98791 +3513 3383 -25394418.17384 +3514 3383 18715245.91155 +3515 3383 -55588121.11081 +3384 3384 1062868161.752 +3385 3384 1.955032348633e-05 +3386 3384 9143607.705144 +3387 3384 125282264.7016 +3388 3384 -9.357929229736e-06 +3389 3384 2285901.927418 +3399 3384 -93044845.55145 +3400 3384 -62499999.98975 +3401 3384 24401753.89294 +3402 3384 -234498519.637 +3403 3384 3.576278686523e-06 +3404 3384 -5943331.630163 +3405 3384 -94399229.23175 +3406 3384 62499999.98975 +3407 3384 -27030537.76527 +3477 3384 -26133752.36576 +3478 3384 15625000.00514 +3479 3384 11964870.03287 +3480 3384 -98285243.92273 +3481 3384 1.072883605957e-06 +3482 3384 73747066.90912 +3483 3384 -40551938.13439 +3484 3384 -15625000.00514 +3485 3384 24822942.95376 +3492 3384 19205852.96814 +3493 3384 4.768371582031e-06 +3494 3384 571475.220082 +3495 3384 99158852.54101 +3496 3384 3.457069396973e-06 +3497 3384 2285900.879224 +3498 3384 -39821273.75826 +3499 3384 -8.895993232727e-06 +3500 3384 571475.2200941 +3510 3384 -26778951.03495 +3511 3384 -15625000.00513 +3512 3384 -12536345.25295 +3513 3384 -102220422.2785 +3514 3384 1.013278961182e-06 +3515 3384 -76032967.78832 +3516 3384 -41874328.64406 +3517 3384 15625000.00513 +3518 3384 -25394418.17384 +3385 3385 912861496.3092 +3386 3385 -109721151.9205 +3387 3385 -9.924173355103e-06 +3388 3385 -112217450.7807 +3389 3385 55957798.18227 +3399 3385 -62499999.98975 +3400 3385 -74294012.36186 +3401 3385 12206463.4413 +3402 3385 4.14252281189e-06 +3403 3385 40502862.18745 +3404 3385 -27430287.99363 +3405 3385 62499999.98975 +3406 3385 -75648396.04218 +3407 3385 15223824.55232 +3477 3385 15625000.00514 +3478 3385 -21446053.85824 +3479 3385 -11171906.87604 +3480 3385 -4.172325134277e-07 +3481 3385 -29534914.67368 +3482 3385 -6857575.146393 +3483 3385 -15625000.00514 +3484 3385 -35864239.62686 +3485 3385 18029482.02244 +3492 3385 6.780028343201e-06 +3493 3385 -40169079.27509 +3494 3385 -46196308.03739 +3495 3385 3.814697265625e-06 +3496 3385 61657264.49931 +3497 3385 -27430300.57206 +3498 3385 -7.718801498413e-06 +3499 3385 -99196206.00148 +3500 3385 73626608.60945 +3510 3385 -15625000.00513 +3511 3385 -22091252.52743 +3512 3385 -11857670.76516 +3513 3385 -7.748603820801e-07 +3514 3385 -33470093.0295 +3515 3385 -6857575.146393 +3516 3385 15625000.00513 +3517 3385 -37186630.13654 +3518 3385 18715245.91155 +3386 3386 1039858352.722 +3387 3386 2285901.927418 +3388 3386 53763353.73819 +3389 3386 85469901.76562 +3399 3386 24744635.83784 +3400 3386 12480768.99722 +3401 3386 -23812494.86631 +3402 3386 -3200276.075057 +3403 3386 -27430287.99363 +3404 3386 71900937.83954 +3405 3386 -26687655.82037 +3406 3386 14949518.99641 +3407 3386 -27424184.68052 +3477 3386 11964870.03287 +3478 3386 -11171906.87604 +3479 3386 -13613251.03531 +3480 3386 73404184.96491 +3481 3386 -6857575.146392 +3482 3386 -87786498.03904 +3483 3386 24822942.95376 +3484 3386 18029482.02244 +3485 3386 -52061746.4183 +3492 3386 571475.2200821 +3493 3386 -45922002.48202 +3494 3386 -10938367.40355 +3495 3386 2285900.879224 +3496 3386 -27430300.57206 +3497 3386 -184190435.19 +3498 3386 571475.2200943 +3499 3386 73352303.05408 +3500 3386 -168344038.6739 +3510 3386 -12536345.25295 +3511 3386 -11857670.76516 +3512 3386 -15333780.81983 +3513 3386 -75690085.8441 +3514 3386 -6857575.146393 +3515 3386 -98280306.98791 +3516 3386 -25394418.17384 +3517 3386 18715245.91155 +3518 3386 -55588121.11081 +3387 3387 1145935402.266 +3388 3387 62548388.94858 +3389 3387 30860151.66558 +3390 3387 21182372.10022 +3391 3387 -62519355.57328 +3392 3387 27039120.36991 +3402 3387 -93044845.55145 +3403 3387 -62499999.98975 +3404 3387 24401753.89294 +3405 3387 -234498519.637 +3406 3387 3.576278686523e-06 +3407 3387 -5943331.630163 +3408 3387 -94399229.23175 +3409 3387 62499999.98975 +3410 3387 -27030537.76527 +3480 3387 -26133752.36576 +3481 3387 15625000.00514 +3482 3387 11964870.03287 +3483 3387 -115335214.0726 +3484 3387 -15631584.19572 +3485 3387 68329440.16886 +3495 3387 19205852.96814 +3496 3387 4.768371582031e-06 +3497 3387 571475.220082 +3498 3387 130473837.5578 +3499 3387 15635973.65611 +3500 3387 7712253.313144 +3501 3387 -53686446.86531 +3502 3387 -15629389.46553 +3503 3387 25401550.08976 +3513 3387 -26778951.03495 +3514 3387 -15625000.00513 +3515 3387 -12536345.25295 +3516 3387 -102220422.2785 +3517 3387 1.013278961182e-06 +3518 3387 -76032967.78832 +3519 3387 -41874328.64406 +3520 3387 15625000.00513 +3521 3387 -25394418.17384 +3388 3388 977156127.6318 +3389 3388 -85033333.84819 +3390 3388 -62529033.36504 +3391 3388 -197605220.9809 +3392 3388 46638027.38239 +3402 3388 -62499999.98975 +3403 3388 -74294012.36186 +3404 3388 12206463.4413 +3405 3388 4.14252281189e-06 +3406 3388 40502862.18745 +3407 3388 -27430287.99363 +3408 3388 62499999.98975 +3409 3388 -75648396.04218 +3410 3388 15223824.55232 +3480 3388 15625000.00514 +3481 3388 -21446053.85824 +3482 3388 -11171906.87604 +3483 3388 -15629389.46552 +3484 3388 -41883469.12474 +3485 3388 7334445.059211 +3495 3388 6.780028343201e-06 +3496 3388 -40169079.27509 +3497 3388 -46196308.03739 +3498 3388 15635973.65611 +3499 3388 88279612.65644 +3500 3388 -21260570.15053 +3501 3388 -15631584.19572 +3502 3388 -108382459.4402 +3503 3388 71307025.97358 +3513 3388 -15625000.00513 +3514 3388 -22091252.52743 +3515 3388 -11857670.76516 +3516 3388 -7.748603820801e-07 +3517 3388 -33470093.0295 +3518 3388 -6857575.146393 +3519 3388 15625000.00513 +3520 3388 -37186630.13654 +3521 3388 18715245.91155 +3389 3389 1036803405.136 +3390 3389 26700529.72734 +3391 3389 52127606.5745 +3392 3389 32215992.22129 +3402 3389 24744635.83784 +3403 3389 12480768.99722 +3404 3389 -23812494.86631 +3405 3389 -3200276.075057 +3406 3389 -27430287.99363 +3407 3389 71900937.83954 +3408 3389 -26687655.82037 +3409 3389 14949518.99641 +3410 3389 -27424184.68052 +3480 3389 11964870.03287 +3481 3389 -11171906.87604 +3482 3389 -13613251.03531 +3483 3389 67985675.23876 +3484 3389 5415714.150796 +3485 3389 -77126033.46393 +3495 3389 571475.2200821 +3496 3389 -45922002.48202 +3497 3389 -10938367.40355 +3498 3389 7717499.145858 +3499 3389 -21256373.52338 +3500 3389 -156819638.9591 +3501 3389 25405116.04772 +3502 3389 72953597.68388 +3503 3389 -149232299.5136 +3513 3389 -12536345.25295 +3514 3389 -11857670.76516 +3515 3389 -15333780.81983 +3516 3389 -75690085.8441 +3517 3389 -6857575.146393 +3518 3389 -98280306.98791 +3519 3389 -25394418.17384 +3520 3389 18715245.91155 +3521 3389 -55588121.11081 +3390 3390 624177588.0977 +3391 3390 44771201.06216 +3392 3390 -10528787.07099 +3405 3390 -93044845.55145 +3406 3390 -62499999.98975 +3407 3390 24401753.89294 +3408 3390 -306121171.2699 +3409 3390 -44814096.9728 +3410 3390 -1812498.000401 +3411 3390 7315323.621087 +3412 3390 50042895.90245 +3413 3390 -2746529.772747 +3483 3390 1493260.574915 +3484 3390 18756584.19674 +3485 3390 14705768.01689 +3498 3390 -8426923.443562 +3499 3390 -15631584.19572 +3500 3390 -11969908.87826 +3501 3390 57208053.40963 +3502 3390 12012672.80452 +3503 3390 11011317.07793 +3516 3390 -26778951.03495 +3517 3390 -15625000.00513 +3518 3390 -12536345.25295 +3519 3390 -114994229.098 +3520 3390 -12022605.74552 +3521 3390 -70788401.11925 +3522 3390 -13789915.32092 +3523 3390 12509932.94511 +3524 3390 -13917270.56417 +3391 3391 554873465.2641 +3392 3391 -63143435.45857 +3405 3391 -62499999.98975 +3406 3391 -74294012.36186 +3407 3391 12206463.4413 +3408 3391 -44835544.92813 +3409 3391 -20217050.21208 +3410 3391 -17039568.2124 +3411 3391 75064343.85367 +3412 3391 -9247914.711671 +3413 3391 5419777.187231 +3483 3391 12504389.4645 +3484 3391 1493260.574915 +3485 3391 -7843093.74256 +3498 3391 -15629389.46552 +3499 3391 -63122936.0184 +3500 3391 -46615995.93793 +3501 3391 12012672.80452 +3502 3391 38649078.93965 +3503 3391 -5152657.419769 +3516 3391 -15625000.00513 +3517 3391 -22091252.52743 +3518 3391 -11857670.76516 +3519 3391 -12027572.21602 +3520 3391 -43151737.0681 +3521 3391 -15928192.70217 +3522 3391 18764899.41767 +3523 3391 -17065118.81357 +3524 3391 20617693.61 +3392 3392 621301487.0834 +3405 3392 24744635.83784 +3406 3392 12480768.99722 +3407 3392 -23812494.86631 +3408 3392 -7983140.536079 +3409 3392 -15941307.43553 +3410 3392 10248959.56633 +3411 3392 -4119794.65912 +3412 3392 4322211.812592 +3413 3392 36070767.98899 +3483 3392 9803845.344592 +3484 3392 -11764640.61384 +3485 3392 3982028.199772 +3498 3392 -11968229.26313 +3499 3392 -48262567.85004 +3500 3392 -28540237.05556 +3501 3392 -17163098.26417 +3502 3392 -27687003.01679 +3503 3392 -111776345.5784 +3516 3392 -12536345.25295 +3517 3392 -11857670.76516 +3518 3392 -15333780.81983 +3519 3392 -72502527.79782 +3520 3392 -15648904.09818 +3521 3392 -95603640.48409 +3522 3392 -20875905.84626 +3523 3392 15050910.90763 +3524 3392 -33497904.02979 +3393 3393 1062868161.752 +3394 3393 1.955032348633e-05 +3395 3393 9143607.705144 +3396 3393 125282264.7016 +3397 3393 -9.357929229736e-06 +3398 3393 2285901.927418 +3414 3393 -234498519.637 +3415 3393 3.576278686523e-06 +3416 3393 -5943331.630163 +3417 3393 -94399229.23175 +3418 3393 62499999.98975 +3419 3393 -27030537.76527 +3486 3393 -98285243.92273 +3487 3393 1.072883605957e-06 +3488 3393 73747066.90912 +3489 3393 -40551938.13439 +3490 3393 -15625000.00514 +3491 3393 24822942.95376 +3504 3393 99158852.54101 +3505 3393 3.457069396973e-06 +3506 3393 2285900.879224 +3507 3393 -39821273.75826 +3508 3393 -8.895993232727e-06 +3509 3393 571475.2200941 +3525 3393 -102220422.2785 +3526 3393 1.013278961182e-06 +3527 3393 -76032967.78832 +3528 3393 -41874328.64406 +3529 3393 15625000.00513 +3530 3393 -25394418.17384 +3394 3394 912861496.3092 +3395 3394 -109721151.9205 +3396 3394 -9.924173355103e-06 +3397 3394 -112217450.7807 +3398 3394 55957798.18227 +3414 3394 4.14252281189e-06 +3415 3394 40502862.18745 +3416 3394 -27430287.99363 +3417 3394 62499999.98975 +3418 3394 -75648396.04218 +3419 3394 15223824.55232 +3486 3394 -4.172325134277e-07 +3487 3394 -29534914.67368 +3488 3394 -6857575.146393 +3489 3394 -15625000.00514 +3490 3394 -35864239.62686 +3491 3394 18029482.02244 +3504 3394 3.814697265625e-06 +3505 3394 61657264.49931 +3506 3394 -27430300.57206 +3507 3394 -7.718801498413e-06 +3508 3394 -99196206.00148 +3509 3394 73626608.60945 +3525 3394 -7.748603820801e-07 +3526 3394 -33470093.0295 +3527 3394 -6857575.146393 +3528 3394 15625000.00513 +3529 3394 -37186630.13654 +3530 3394 18715245.91155 +3395 3395 1039858352.722 +3396 3395 2285901.927418 +3397 3395 53763353.73819 +3398 3395 85469901.76562 +3414 3395 -3200276.075057 +3415 3395 -27430287.99363 +3416 3395 71900937.83954 +3417 3395 -26687655.82037 +3418 3395 14949518.99641 +3419 3395 -27424184.68052 +3486 3395 73404184.96491 +3487 3395 -6857575.146392 +3488 3395 -87786498.03904 +3489 3395 24822942.95376 +3490 3395 18029482.02244 +3491 3395 -52061746.4183 +3504 3395 2285900.879224 +3505 3395 -27430300.57206 +3506 3395 -184190435.19 +3507 3395 571475.2200943 +3508 3395 73352303.05408 +3509 3395 -168344038.6739 +3525 3395 -75690085.8441 +3526 3395 -6857575.146393 +3527 3395 -98280306.98791 +3528 3395 -25394418.17384 +3529 3395 18715245.91155 +3530 3395 -55588121.11081 +3396 3396 1062868161.752 +3397 3396 1.955032348633e-05 +3398 3396 9143607.705144 +3399 3396 125282264.7016 +3400 3396 -9.357929229736e-06 +3401 3396 2285901.927418 +3414 3396 -93044845.55145 +3415 3396 -62499999.98975 +3416 3396 24401753.89294 +3417 3396 -234498519.637 +3418 3396 3.576278686523e-06 +3419 3396 -5943331.630163 +3420 3396 -94399229.23175 +3421 3396 62499999.98975 +3422 3396 -27030537.76527 +3486 3396 -26133752.36576 +3487 3396 15625000.00514 +3488 3396 11964870.03287 +3489 3396 -98285243.92273 +3490 3396 1.072883605957e-06 +3491 3396 73747066.90912 +3492 3396 -40551938.13439 +3493 3396 -15625000.00514 +3494 3396 24822942.95376 +3504 3396 19205852.96814 +3505 3396 4.768371582031e-06 +3506 3396 571475.220082 +3507 3396 99158852.54101 +3508 3396 3.457069396973e-06 +3509 3396 2285900.879224 +3510 3396 -39821273.75826 +3511 3396 -8.895993232727e-06 +3512 3396 571475.2200941 +3525 3396 -26778951.03495 +3526 3396 -15625000.00513 +3527 3396 -12536345.25295 +3528 3396 -102220422.2785 +3529 3396 1.013278961182e-06 +3530 3396 -76032967.78832 +3531 3396 -41874328.64406 +3532 3396 15625000.00513 +3533 3396 -25394418.17384 +3397 3397 912861496.3092 +3398 3397 -109721151.9205 +3399 3397 -9.924173355103e-06 +3400 3397 -112217450.7807 +3401 3397 55957798.18227 +3414 3397 -62499999.98975 +3415 3397 -74294012.36186 +3416 3397 12206463.4413 +3417 3397 4.14252281189e-06 +3418 3397 40502862.18745 +3419 3397 -27430287.99363 +3420 3397 62499999.98975 +3421 3397 -75648396.04218 +3422 3397 15223824.55232 +3486 3397 15625000.00514 +3487 3397 -21446053.85824 +3488 3397 -11171906.87604 +3489 3397 -4.172325134277e-07 +3490 3397 -29534914.67368 +3491 3397 -6857575.146393 +3492 3397 -15625000.00514 +3493 3397 -35864239.62686 +3494 3397 18029482.02244 +3504 3397 6.780028343201e-06 +3505 3397 -40169079.27509 +3506 3397 -46196308.03739 +3507 3397 3.814697265625e-06 +3508 3397 61657264.49931 +3509 3397 -27430300.57206 +3510 3397 -7.718801498413e-06 +3511 3397 -99196206.00148 +3512 3397 73626608.60945 +3525 3397 -15625000.00513 +3526 3397 -22091252.52743 +3527 3397 -11857670.76516 +3528 3397 -7.748603820801e-07 +3529 3397 -33470093.0295 +3530 3397 -6857575.146393 +3531 3397 15625000.00513 +3532 3397 -37186630.13654 +3533 3397 18715245.91155 +3398 3398 1039858352.722 +3399 3398 2285901.927418 +3400 3398 53763353.73819 +3401 3398 85469901.76562 +3414 3398 24744635.83784 +3415 3398 12480768.99722 +3416 3398 -23812494.86631 +3417 3398 -3200276.075057 +3418 3398 -27430287.99363 +3419 3398 71900937.83954 +3420 3398 -26687655.82037 +3421 3398 14949518.99641 +3422 3398 -27424184.68052 +3486 3398 11964870.03287 +3487 3398 -11171906.87604 +3488 3398 -13613251.03531 +3489 3398 73404184.96491 +3490 3398 -6857575.146392 +3491 3398 -87786498.03904 +3492 3398 24822942.95376 +3493 3398 18029482.02244 +3494 3398 -52061746.4183 +3504 3398 571475.2200821 +3505 3398 -45922002.48202 +3506 3398 -10938367.40355 +3507 3398 2285900.879224 +3508 3398 -27430300.57206 +3509 3398 -184190435.19 +3510 3398 571475.2200943 +3511 3398 73352303.05408 +3512 3398 -168344038.6739 +3525 3398 -12536345.25295 +3526 3398 -11857670.76516 +3527 3398 -15333780.81983 +3528 3398 -75690085.8441 +3529 3398 -6857575.146393 +3530 3398 -98280306.98791 +3531 3398 -25394418.17384 +3532 3398 18715245.91155 +3533 3398 -55588121.11081 +3399 3399 1062868161.752 +3400 3399 1.955032348633e-05 +3401 3399 9143607.705144 +3402 3399 125282264.7016 +3403 3399 -9.357929229736e-06 +3404 3399 2285901.927418 +3417 3399 -93044845.55145 +3418 3399 -62499999.98975 +3419 3399 24401753.89294 +3420 3399 -234498519.637 +3421 3399 3.576278686523e-06 +3422 3399 -5943331.630163 +3423 3399 -94399229.23175 +3424 3399 62499999.98975 +3425 3399 -27030537.76527 +3489 3399 -26133752.36576 +3490 3399 15625000.00514 +3491 3399 11964870.03287 +3492 3399 -98285243.92273 +3493 3399 1.072883605957e-06 +3494 3399 73747066.90912 +3495 3399 -40551938.13439 +3496 3399 -15625000.00514 +3497 3399 24822942.95376 +3507 3399 19205852.96814 +3508 3399 4.768371582031e-06 +3509 3399 571475.220082 +3510 3399 99158852.54101 +3511 3399 3.457069396973e-06 +3512 3399 2285900.879224 +3513 3399 -39821273.75826 +3514 3399 -8.895993232727e-06 +3515 3399 571475.2200941 +3528 3399 -26778951.03495 +3529 3399 -15625000.00513 +3530 3399 -12536345.25295 +3531 3399 -102220422.2785 +3532 3399 1.013278961182e-06 +3533 3399 -76032967.78832 +3534 3399 -41874328.64406 +3535 3399 15625000.00513 +3536 3399 -25394418.17384 +3400 3400 912861496.3092 +3401 3400 -109721151.9205 +3402 3400 -9.924173355103e-06 +3403 3400 -112217450.7807 +3404 3400 55957798.18227 +3417 3400 -62499999.98975 +3418 3400 -74294012.36186 +3419 3400 12206463.4413 +3420 3400 4.14252281189e-06 +3421 3400 40502862.18745 +3422 3400 -27430287.99363 +3423 3400 62499999.98975 +3424 3400 -75648396.04218 +3425 3400 15223824.55232 +3489 3400 15625000.00514 +3490 3400 -21446053.85824 +3491 3400 -11171906.87604 +3492 3400 -4.172325134277e-07 +3493 3400 -29534914.67368 +3494 3400 -6857575.146393 +3495 3400 -15625000.00514 +3496 3400 -35864239.62686 +3497 3400 18029482.02244 +3507 3400 6.780028343201e-06 +3508 3400 -40169079.27509 +3509 3400 -46196308.03739 +3510 3400 3.814697265625e-06 +3511 3400 61657264.49931 +3512 3400 -27430300.57206 +3513 3400 -7.718801498413e-06 +3514 3400 -99196206.00148 +3515 3400 73626608.60945 +3528 3400 -15625000.00513 +3529 3400 -22091252.52743 +3530 3400 -11857670.76516 +3531 3400 -7.748603820801e-07 +3532 3400 -33470093.0295 +3533 3400 -6857575.146393 +3534 3400 15625000.00513 +3535 3400 -37186630.13654 +3536 3400 18715245.91155 +3401 3401 1039858352.722 +3402 3401 2285901.927418 +3403 3401 53763353.73819 +3404 3401 85469901.76562 +3417 3401 24744635.83784 +3418 3401 12480768.99722 +3419 3401 -23812494.86631 +3420 3401 -3200276.075057 +3421 3401 -27430287.99363 +3422 3401 71900937.83954 +3423 3401 -26687655.82037 +3424 3401 14949518.99641 +3425 3401 -27424184.68052 +3489 3401 11964870.03287 +3490 3401 -11171906.87604 +3491 3401 -13613251.03531 +3492 3401 73404184.96491 +3493 3401 -6857575.146392 +3494 3401 -87786498.03904 +3495 3401 24822942.95376 +3496 3401 18029482.02244 +3497 3401 -52061746.4183 +3507 3401 571475.2200821 +3508 3401 -45922002.48202 +3509 3401 -10938367.40355 +3510 3401 2285900.879224 +3511 3401 -27430300.57206 +3512 3401 -184190435.19 +3513 3401 571475.2200943 +3514 3401 73352303.05408 +3515 3401 -168344038.6739 +3528 3401 -12536345.25295 +3529 3401 -11857670.76516 +3530 3401 -15333780.81983 +3531 3401 -75690085.8441 +3532 3401 -6857575.146393 +3533 3401 -98280306.98791 +3534 3401 -25394418.17384 +3535 3401 18715245.91155 +3536 3401 -55588121.11081 +3402 3402 1062868161.752 +3403 3402 1.955032348633e-05 +3404 3402 9143607.705144 +3405 3402 125282264.7016 +3406 3402 -9.357929229736e-06 +3407 3402 2285901.927418 +3420 3402 -93044845.55145 +3421 3402 -62499999.98975 +3422 3402 24401753.89294 +3423 3402 -234498519.637 +3424 3402 3.576278686523e-06 +3425 3402 -5943331.630163 +3426 3402 -94399229.23175 +3427 3402 62499999.98975 +3428 3402 -27030537.76527 +3492 3402 -26133752.36576 +3493 3402 15625000.00514 +3494 3402 11964870.03287 +3495 3402 -98285243.92273 +3496 3402 1.072883605957e-06 +3497 3402 73747066.90912 +3498 3402 -40551938.13439 +3499 3402 -15625000.00514 +3500 3402 24822942.95376 +3510 3402 19205852.96814 +3511 3402 4.768371582031e-06 +3512 3402 571475.220082 +3513 3402 99158852.54101 +3514 3402 3.457069396973e-06 +3515 3402 2285900.879224 +3516 3402 -39821273.75826 +3517 3402 -8.895993232727e-06 +3518 3402 571475.2200941 +3531 3402 -26778951.03495 +3532 3402 -15625000.00513 +3533 3402 -12536345.25295 +3534 3402 -102220422.2785 +3535 3402 1.013278961182e-06 +3536 3402 -76032967.78832 +3537 3402 -41874328.64406 +3538 3402 15625000.00513 +3539 3402 -25394418.17384 +3403 3403 912861496.3092 +3404 3403 -109721151.9205 +3405 3403 -9.924173355103e-06 +3406 3403 -112217450.7807 +3407 3403 55957798.18227 +3420 3403 -62499999.98975 +3421 3403 -74294012.36186 +3422 3403 12206463.4413 +3423 3403 4.14252281189e-06 +3424 3403 40502862.18745 +3425 3403 -27430287.99363 +3426 3403 62499999.98975 +3427 3403 -75648396.04218 +3428 3403 15223824.55232 +3492 3403 15625000.00514 +3493 3403 -21446053.85824 +3494 3403 -11171906.87604 +3495 3403 -4.172325134277e-07 +3496 3403 -29534914.67368 +3497 3403 -6857575.146393 +3498 3403 -15625000.00514 +3499 3403 -35864239.62686 +3500 3403 18029482.02244 +3510 3403 6.780028343201e-06 +3511 3403 -40169079.27509 +3512 3403 -46196308.03739 +3513 3403 3.814697265625e-06 +3514 3403 61657264.49931 +3515 3403 -27430300.57206 +3516 3403 -7.718801498413e-06 +3517 3403 -99196206.00148 +3518 3403 73626608.60945 +3531 3403 -15625000.00513 +3532 3403 -22091252.52743 +3533 3403 -11857670.76516 +3534 3403 -7.748603820801e-07 +3535 3403 -33470093.0295 +3536 3403 -6857575.146393 +3537 3403 15625000.00513 +3538 3403 -37186630.13654 +3539 3403 18715245.91155 +3404 3404 1039858352.722 +3405 3404 2285901.927418 +3406 3404 53763353.73819 +3407 3404 85469901.76562 +3420 3404 24744635.83784 +3421 3404 12480768.99722 +3422 3404 -23812494.86631 +3423 3404 -3200276.075057 +3424 3404 -27430287.99363 +3425 3404 71900937.83954 +3426 3404 -26687655.82037 +3427 3404 14949518.99641 +3428 3404 -27424184.68052 +3492 3404 11964870.03287 +3493 3404 -11171906.87604 +3494 3404 -13613251.03531 +3495 3404 73404184.96491 +3496 3404 -6857575.146392 +3497 3404 -87786498.03904 +3498 3404 24822942.95376 +3499 3404 18029482.02244 +3500 3404 -52061746.4183 +3510 3404 571475.2200821 +3511 3404 -45922002.48202 +3512 3404 -10938367.40355 +3513 3404 2285900.879224 +3514 3404 -27430300.57206 +3515 3404 -184190435.19 +3516 3404 571475.2200943 +3517 3404 73352303.05408 +3518 3404 -168344038.6739 +3531 3404 -12536345.25295 +3532 3404 -11857670.76516 +3533 3404 -15333780.81983 +3534 3404 -75690085.8441 +3535 3404 -6857575.146393 +3536 3404 -98280306.98791 +3537 3404 -25394418.17384 +3538 3404 18715245.91155 +3539 3404 -55588121.11081 +3405 3405 1062868161.752 +3406 3405 1.955032348633e-05 +3407 3405 9143607.705144 +3408 3405 125282264.7016 +3409 3405 -9.357929229736e-06 +3410 3405 2285901.927418 +3423 3405 -93044845.55145 +3424 3405 -62499999.98975 +3425 3405 24401753.89294 +3426 3405 -234498519.637 +3427 3405 3.576278686523e-06 +3428 3405 -5943331.630163 +3429 3405 -94399229.23175 +3430 3405 62499999.98975 +3431 3405 -27030537.76527 +3495 3405 -26133752.36576 +3496 3405 15625000.00514 +3497 3405 11964870.03287 +3498 3405 -98285243.92273 +3499 3405 1.072883605957e-06 +3500 3405 73747066.90912 +3501 3405 -40551938.13439 +3502 3405 -15625000.00514 +3503 3405 24822942.95376 +3513 3405 19205852.96814 +3514 3405 4.768371582031e-06 +3515 3405 571475.220082 +3516 3405 99158852.54101 +3517 3405 3.457069396973e-06 +3518 3405 2285900.879224 +3519 3405 -39821273.75826 +3520 3405 -8.895993232727e-06 +3521 3405 571475.2200941 +3534 3405 -26778951.03495 +3535 3405 -15625000.00513 +3536 3405 -12536345.25295 +3537 3405 -102220422.2785 +3538 3405 1.013278961182e-06 +3539 3405 -76032967.78832 +3540 3405 -41874328.64406 +3541 3405 15625000.00513 +3542 3405 -25394418.17384 +3406 3406 912861496.3092 +3407 3406 -109721151.9205 +3408 3406 -9.924173355103e-06 +3409 3406 -112217450.7807 +3410 3406 55957798.18227 +3423 3406 -62499999.98975 +3424 3406 -74294012.36186 +3425 3406 12206463.4413 +3426 3406 4.14252281189e-06 +3427 3406 40502862.18745 +3428 3406 -27430287.99363 +3429 3406 62499999.98975 +3430 3406 -75648396.04218 +3431 3406 15223824.55232 +3495 3406 15625000.00514 +3496 3406 -21446053.85824 +3497 3406 -11171906.87604 +3498 3406 -4.172325134277e-07 +3499 3406 -29534914.67368 +3500 3406 -6857575.146393 +3501 3406 -15625000.00514 +3502 3406 -35864239.62686 +3503 3406 18029482.02244 +3513 3406 6.780028343201e-06 +3514 3406 -40169079.27509 +3515 3406 -46196308.03739 +3516 3406 3.814697265625e-06 +3517 3406 61657264.49931 +3518 3406 -27430300.57206 +3519 3406 -7.718801498413e-06 +3520 3406 -99196206.00148 +3521 3406 73626608.60945 +3534 3406 -15625000.00513 +3535 3406 -22091252.52743 +3536 3406 -11857670.76516 +3537 3406 -7.748603820801e-07 +3538 3406 -33470093.0295 +3539 3406 -6857575.146393 +3540 3406 15625000.00513 +3541 3406 -37186630.13654 +3542 3406 18715245.91155 +3407 3407 1039858352.722 +3408 3407 2285901.927418 +3409 3407 53763353.73819 +3410 3407 85469901.76562 +3423 3407 24744635.83784 +3424 3407 12480768.99722 +3425 3407 -23812494.86631 +3426 3407 -3200276.075057 +3427 3407 -27430287.99363 +3428 3407 71900937.83954 +3429 3407 -26687655.82037 +3430 3407 14949518.99641 +3431 3407 -27424184.68052 +3495 3407 11964870.03287 +3496 3407 -11171906.87604 +3497 3407 -13613251.03531 +3498 3407 73404184.96491 +3499 3407 -6857575.146392 +3500 3407 -87786498.03904 +3501 3407 24822942.95376 +3502 3407 18029482.02244 +3503 3407 -52061746.4183 +3513 3407 571475.2200821 +3514 3407 -45922002.48202 +3515 3407 -10938367.40355 +3516 3407 2285900.879224 +3517 3407 -27430300.57206 +3518 3407 -184190435.19 +3519 3407 571475.2200943 +3520 3407 73352303.05408 +3521 3407 -168344038.6739 +3534 3407 -12536345.25295 +3535 3407 -11857670.76516 +3536 3407 -15333780.81983 +3537 3407 -75690085.8441 +3538 3407 -6857575.146393 +3539 3407 -98280306.98791 +3540 3407 -25394418.17384 +3541 3407 18715245.91155 +3542 3407 -55588121.11081 +3408 3408 1075173652.846 +3409 3408 46334615.81186 +3410 3408 9124226.612516 +3411 3408 1916926.255678 +3412 3408 -71562144.11825 +3413 3408 4586649.454248 +3426 3408 -93044845.55145 +3427 3408 -62499999.98975 +3428 3408 24401753.89294 +3429 3408 -218823261.2053 +3430 3408 8693888.23577 +3431 3408 -1141242.668708 +3432 3408 -70901410.64439 +3433 3408 61369184.99877 +3434 3408 -4585483.569651 +3498 3408 -26133752.36576 +3499 3408 15625000.00514 +3500 3408 11964870.03287 +3501 3408 -111379581.0895 +3502 3408 -12027572.21602 +3503 3408 68369548.91265 +3516 3408 19205852.96814 +3517 3408 4.768371582031e-06 +3518 3408 571475.220082 +3519 3408 120911111.2073 +3520 3408 12278922.06453 +3521 3408 2270598.06335 +3522 3408 -36700079.12217 +3523 3408 -17466056.76703 +3524 3408 19817312.72048 +3537 3408 -26778951.03495 +3538 3408 -15625000.00513 +3539 3408 -12536345.25295 +3540 3408 -98620103.2208 +3541 3408 1778213.472963 +3542 3408 -72744377.11155 +3543 3408 -30606173.22176 +3544 3408 15436493.44556 +3545 3408 -17681366.86574 +3409 3409 955054398.0361 +3410 3409 -59710257.41375 +3411 3409 -71583592.07358 +3412 3409 -218430104.7672 +3413 3409 9734746.878626 +3426 3409 -62499999.98975 +3427 3409 -74294012.36186 +3428 3409 12206463.4413 +3429 3409 8693888.235771 +3430 3409 46696952.88892 +3431 3409 -15374856.65955 +3432 3409 61369184.99877 +3433 3409 -81861410.86036 +3434 3409 3664812.614708 +3498 3409 15625000.00514 +3499 3409 -21446053.85824 +3500 3409 -11171906.87604 +3501 3409 -12022605.74552 +3502 3409 -39537089.05956 +3503 3409 7359372.223937 +3516 3409 6.780028343201e-06 +3517 3409 -40169079.27509 +3518 3409 -46196308.03739 +3519 3409 12278922.06453 +3520 3409 88590814.60077 +3521 3409 -15549265.97361 +3522 3409 -17471023.23754 +3523 3409 -91686021.10489 +3524 3409 62194368.75178 +3537 3409 -15625000.00513 +3538 3409 -22091252.52743 +3539 3409 -11857670.76516 +3540 3409 1778213.472961 +3541 3409 -31772368.13475 +3542 3409 -2298329.894473 +3543 3409 15436493.44556 +3544 3409 -31990626.5204 +3545 3409 17545113.68925 +3410 3410 982065205.3903 +3411 3410 4588386.563072 +3412 3410 9736189.179777 +3413 3410 33362944.22637 +3426 3410 24744635.83784 +3427 3410 12480768.99722 +3428 3410 -23812494.86631 +3429 3410 -7313117.667695 +3430 3410 -15374856.65955 +3431 3410 70793885.3786 +3432 3410 -4585483.568976 +3433 3410 3664812.614708 +3434 3410 -13149747.71181 +3498 3410 11964870.03287 +3499 3410 -11171906.87604 +3500 3410 -13613251.03531 +3501 3410 70083675.59122 +3502 3410 7089578.00376 +3503 3410 -85964579.12796 +3516 3410 571475.2200821 +3517 3410 -45922002.48202 +3518 3410 -10938367.40355 +3519 3410 2281089.798958 +3520 3410 -15540872.40854 +3521 3410 -154748576.3714 +3522 3410 19822961.88866 +3523 3410 62194150.41038 +3524 3410 -93237810.97087 +3537 3410 -12536345.25295 +3538 3410 -11857670.76516 +3539 3410 -15333780.81983 +3540 3410 -74458786.83433 +3541 3410 -2298329.894201 +3542 3410 -97429758.39169 +3543 3410 -17681366.86574 +3544 3410 17545113.68925 +3545 3410 -35671678.22496 +3411 3411 605103202.4825 +3412 3411 5616654.661039 +3413 3411 484531.4385712 +3429 3411 -93529557.10328 +3430 3411 -62357763.20029 +3431 3411 3773531.373596 +3432 3411 -183018439.214 +3433 3411 11569778.02511 +3434 3411 -944334.4519733 +3435 3411 71508600.70521 +3436 3411 -17974760.11169 +3437 3411 -139838.4039876 +3438 3411 -66781052.77063 +3439 3411 59665338.84574 +3440 3411 -899426.3036951 +3501 3411 -9302628.702825 +3502 3411 18764899.41767 +3503 3411 18816193.68425 +3519 3411 -28751449.72098 +3520 3411 -17471023.23754 +3521 3411 -17566411.9441 +3522 3411 31494515.43557 +3523 3411 1158847.128799 +3524 3411 14860448.35881 +3540 3411 -32807336.98145 +3541 3411 -15601315.81942 +3542 3411 -17733537.44274 +3543 3411 -94362051.98175 +3544 3411 2368086.475652 +3545 3411 -73894565.1737 +3546 3411 -7533777.190493 +3547 3411 -4260257.921041 +3548 3411 6179048.228008 +3549 3411 -29991436.33932 +3550 3411 15040763.95587 +3551 3411 -18386036.82208 +3412 3412 678108327.2261 +3413 3412 -10914628.25135 +3429 3412 -62357763.20029 +3430 3412 -68815724.21444 +3431 3412 1310585.605053 +3432 3412 11569778.02511 +3433 3412 75433646.11065 +3434 3412 -3265168.713637 +3435 3412 7025239.884211 +3436 3412 -49350516.58907 +3437 3412 490165.0741894 +3438 3412 59665338.84574 +3439 3412 -65182709.07778 +3440 3412 512891.4409334 +3501 3412 12509932.94511 +3502 3412 -12577832.19548 +3503 3412 -13016519.16007 +3519 3412 -17466056.76704 +3520 3412 -83737391.70371 +3521 3412 -57398629.61985 +3522 3412 1158847.128796 +3523 3412 47746735.68824 +3524 3412 2639318.658195 +3540 3412 -15601315.81942 +3541 3412 -26902770.57574 +3542 3412 -14605313.75058 +3543 3412 2368086.475653 +3544 3412 -29115968.9013 +3545 3412 923765.0025147 +3546 3412 1989742.081013 +3547 3412 -37694269.5522 +3548 3412 33454941.08177 +3549 3412 15040763.95587 +3550 3412 -28972668.24107 +3551 3412 16792906.76868 +3413 3413 683948498.04 +3429 3413 3773531.373933 +3430 3413 1310585.605323 +3431 3413 -15395465.36467 +3432 3413 -944334.451972 +3433 3413 -3265168.713637 +3434 3413 99728654.97492 +3435 3413 -139838.403985 +3436 3413 490165.0741892 +3437 3413 77233581.16884 +3438 3413 -899426.3033575 +3439 3413 512891.4409334 +3440 3413 -1575637.096933 +3501 3413 12544129.12283 +3502 3413 -18034518.9332 +3503 3413 -21531806.38154 +3519 3413 -17561569.6073 +3520 3413 -57399512.28169 +3521 3413 -72041465.90101 +3522 3413 -14609759.96969 +3523 3413 -7946564.416753 +3524 3413 -150648682.0086 +3540 3413 -17733537.44274 +3541 3413 -14605313.75058 +3542 3413 -29379378.11343 +3543 3413 -73894565.17404 +3544 3413 923765.0027867 +3545 3413 -100288486.4379 +3546 3413 -1945951.77432 +3547 3413 33454941.08177 +3548 3413 -48711782.95365 +3549 3413 -18386036.82208 +3550 3413 16792906.76868 +3551 3413 -34076172.82057 +3414 3414 531253496.3852 +3415 3414 8.702278137207e-06 +3416 3414 -2285835.035192 +3417 3414 62618559.28942 +3418 3414 12499999.99795 +3419 3414 -4857483.06435 +3504 3414 -98285243.92273 +3505 3414 1.072883605957e-06 +3506 3414 73747066.90912 +3507 3414 -40551938.13439 +3508 3414 -15625000.00514 +3509 3414 24822942.95376 +3525 3414 49556853.20918 +3526 3414 2.026557922363e-06 +3527 3414 -14657969.69626 +3528 3414 -19910636.87912 +3529 3414 3125000.001023 +3530 3414 -4735998.502713 +3415 3415 456250163.6639 +3416 3415 -54860575.96022 +3417 3415 -12499999.99795 +3418 3415 -56131298.45172 +3419 3415 27704593.53563 +3504 3415 -4.172325134277e-07 +3505 3415 -29534914.67368 +3506 3415 -6857575.146393 +3507 3415 -15625000.00514 +3508 3415 -35864239.62686 +3509 3415 18029482.02244 +3525 3415 2.264976501465e-06 +3526 3415 30806059.18833 +3527 3415 -13715150.28603 +3528 3415 -3125000.00103 +3529 3415 -49598103.00073 +3530 3415 36744727.91581 +3416 3416 519447617.7192 +3417 3416 5428975.267292 +3418 3416 27155982.42461 +3419 3416 42674756.05248 +3504 3416 73404184.96491 +3505 3416 -6857575.146392 +3506 3416 -87786498.03904 +3507 3416 24822942.95376 +3508 3416 18029482.02244 +3509 3416 -52061746.4183 +3525 3416 15229460.85439 +3526 3416 -13715150.28603 +3527 3416 -92155412.4252 +3528 3416 5307473.722807 +3529 3416 36744727.91595 +3530 3416 -84172019.33696 +3417 3417 531253496.3852 +3418 3417 8.702278137207e-06 +3419 3417 -2285835.035192 +3420 3417 62618559.28942 +3421 3417 12499999.99795 +3422 3417 -4857483.06435 +3504 3417 -26133752.36576 +3505 3417 15625000.00514 +3506 3417 11964870.03287 +3507 3417 -98285243.92273 +3508 3417 1.072883605957e-06 +3509 3417 73747066.90912 +3510 3417 -40551938.13439 +3511 3417 -15625000.00514 +3512 3417 24822942.95376 +3525 3417 9602926.484067 +3526 3417 -3125000.001024 +3527 3417 -2164383.918541 +3528 3417 49556853.20918 +3529 3417 2.026557922363e-06 +3530 3417 -14657969.69626 +3531 3417 -19910636.87912 +3532 3417 3125000.001023 +3533 3417 -4735998.502713 +3418 3418 456250163.6639 +3419 3418 -54860575.96022 +3420 3418 -12499999.99795 +3421 3418 -56131298.45172 +3422 3418 27704593.53563 +3504 3418 15625000.00514 +3505 3418 -21446053.85824 +3506 3418 -11171906.87604 +3507 3418 -4.172325134277e-07 +3508 3418 -29534914.67368 +3509 3418 -6857575.146393 +3510 3418 -15625000.00514 +3511 3418 -35864239.62686 +3512 3418 18029482.02244 +3525 3418 3125000.001031 +3526 3418 -20084539.63755 +3527 3418 -23029577.62979 +3528 3418 2.264976501465e-06 +3529 3418 30806059.18833 +3530 3418 -13715150.28603 +3531 3418 -3125000.00103 +3532 3418 -49598103.00073 +3533 3418 36744727.91581 +3419 3419 519447617.7192 +3420 3419 5428975.267292 +3421 3419 27155982.42461 +3422 3419 42674756.05248 +3504 3419 11964870.03287 +3505 3419 -11171906.87604 +3506 3419 -13613251.03531 +3507 3419 73404184.96491 +3508 3419 -6857575.146392 +3509 3419 -87786498.03904 +3510 3419 24822942.95376 +3511 3419 18029482.02244 +3512 3419 -52061746.4183 +3525 3419 2735859.138623 +3526 3419 -23029577.62992 +3527 3419 -5469183.701778 +3528 3419 15229460.85439 +3529 3419 -13715150.28603 +3530 3419 -92155412.4252 +3531 3419 5307473.722807 +3532 3419 36744727.91595 +3533 3419 -84172019.33696 +3420 3420 531253496.3852 +3421 3420 8.702278137207e-06 +3422 3420 -2285835.035192 +3423 3420 62618559.28942 +3424 3420 12499999.99795 +3425 3420 -4857483.06435 +3507 3420 -26133752.36576 +3508 3420 15625000.00514 +3509 3420 11964870.03287 +3510 3420 -98285243.92273 +3511 3420 1.072883605957e-06 +3512 3420 73747066.90912 +3513 3420 -40551938.13439 +3514 3420 -15625000.00514 +3515 3420 24822942.95376 +3528 3420 9602926.484067 +3529 3420 -3125000.001024 +3530 3420 -2164383.918541 +3531 3420 49556853.20918 +3532 3420 2.026557922363e-06 +3533 3420 -14657969.69626 +3534 3420 -19910636.87912 +3535 3420 3125000.001023 +3536 3420 -4735998.502713 +3421 3421 456250163.6639 +3422 3421 -54860575.96022 +3423 3421 -12499999.99795 +3424 3421 -56131298.45172 +3425 3421 27704593.53563 +3507 3421 15625000.00514 +3508 3421 -21446053.85824 +3509 3421 -11171906.87604 +3510 3421 -4.172325134277e-07 +3511 3421 -29534914.67368 +3512 3421 -6857575.146393 +3513 3421 -15625000.00514 +3514 3421 -35864239.62686 +3515 3421 18029482.02244 +3528 3421 3125000.001031 +3529 3421 -20084539.63755 +3530 3421 -23029577.62979 +3531 3421 2.264976501465e-06 +3532 3421 30806059.18833 +3533 3421 -13715150.28603 +3534 3421 -3125000.00103 +3535 3421 -49598103.00073 +3536 3421 36744727.91581 +3422 3422 519447617.7192 +3423 3422 5428975.267292 +3424 3422 27155982.42461 +3425 3422 42674756.05248 +3507 3422 11964870.03287 +3508 3422 -11171906.87604 +3509 3422 -13613251.03531 +3510 3422 73404184.96491 +3511 3422 -6857575.146392 +3512 3422 -87786498.03904 +3513 3422 24822942.95376 +3514 3422 18029482.02244 +3515 3422 -52061746.4183 +3528 3422 2735859.138623 +3529 3422 -23029577.62992 +3530 3422 -5469183.701778 +3531 3422 15229460.85439 +3532 3422 -13715150.28603 +3533 3422 -92155412.4252 +3534 3422 5307473.722807 +3535 3422 36744727.91595 +3536 3422 -84172019.33696 +3423 3423 531253496.3852 +3424 3423 8.702278137207e-06 +3425 3423 -2285835.035192 +3426 3423 62618559.28942 +3427 3423 12499999.99795 +3428 3423 -4857483.06435 +3510 3423 -26133752.36576 +3511 3423 15625000.00514 +3512 3423 11964870.03287 +3513 3423 -98285243.92273 +3514 3423 1.072883605957e-06 +3515 3423 73747066.90912 +3516 3423 -40551938.13439 +3517 3423 -15625000.00514 +3518 3423 24822942.95376 +3531 3423 9602926.484067 +3532 3423 -3125000.001024 +3533 3423 -2164383.918541 +3534 3423 49556853.20918 +3535 3423 2.026557922363e-06 +3536 3423 -14657969.69626 +3537 3423 -19910636.87912 +3538 3423 3125000.001023 +3539 3423 -4735998.502713 +3424 3424 456250163.6639 +3425 3424 -54860575.96022 +3426 3424 -12499999.99795 +3427 3424 -56131298.45172 +3428 3424 27704593.53563 +3510 3424 15625000.00514 +3511 3424 -21446053.85824 +3512 3424 -11171906.87604 +3513 3424 -4.172325134277e-07 +3514 3424 -29534914.67368 +3515 3424 -6857575.146393 +3516 3424 -15625000.00514 +3517 3424 -35864239.62686 +3518 3424 18029482.02244 +3531 3424 3125000.001031 +3532 3424 -20084539.63755 +3533 3424 -23029577.62979 +3534 3424 2.264976501465e-06 +3535 3424 30806059.18833 +3536 3424 -13715150.28603 +3537 3424 -3125000.00103 +3538 3424 -49598103.00073 +3539 3424 36744727.91581 +3425 3425 519447617.7192 +3426 3425 5428975.267292 +3427 3425 27155982.42461 +3428 3425 42674756.05248 +3510 3425 11964870.03287 +3511 3425 -11171906.87604 +3512 3425 -13613251.03531 +3513 3425 73404184.96491 +3514 3425 -6857575.146392 +3515 3425 -87786498.03904 +3516 3425 24822942.95376 +3517 3425 18029482.02244 +3518 3425 -52061746.4183 +3531 3425 2735859.138623 +3532 3425 -23029577.62992 +3533 3425 -5469183.701778 +3534 3425 15229460.85439 +3535 3425 -13715150.28603 +3536 3425 -92155412.4252 +3537 3425 5307473.722807 +3538 3425 36744727.91595 +3539 3425 -84172019.33696 +3426 3426 531253496.3852 +3427 3426 8.702278137207e-06 +3428 3426 -2285835.035192 +3429 3426 62618559.28942 +3430 3426 12499999.99795 +3431 3426 -4857483.06435 +3513 3426 -26133752.36576 +3514 3426 15625000.00514 +3515 3426 11964870.03287 +3516 3426 -98285243.92273 +3517 3426 1.072883605957e-06 +3518 3426 73747066.90912 +3519 3426 -40551938.13439 +3520 3426 -15625000.00514 +3521 3426 24822942.95376 +3534 3426 9602926.484067 +3535 3426 -3125000.001024 +3536 3426 -2164383.918541 +3537 3426 49556853.20918 +3538 3426 2.026557922363e-06 +3539 3426 -14657969.69626 +3540 3426 -19910636.87912 +3541 3426 3125000.001023 +3542 3426 -4735998.502713 +3427 3427 456250163.6639 +3428 3427 -54860575.96022 +3429 3427 -12499999.99795 +3430 3427 -56131298.45172 +3431 3427 27704593.53563 +3513 3427 15625000.00514 +3514 3427 -21446053.85824 +3515 3427 -11171906.87604 +3516 3427 -4.172325134277e-07 +3517 3427 -29534914.67368 +3518 3427 -6857575.146393 +3519 3427 -15625000.00514 +3520 3427 -35864239.62686 +3521 3427 18029482.02244 +3534 3427 3125000.001031 +3535 3427 -20084539.63755 +3536 3427 -23029577.62979 +3537 3427 2.264976501465e-06 +3538 3427 30806059.18833 +3539 3427 -13715150.28603 +3540 3427 -3125000.00103 +3541 3427 -49598103.00073 +3542 3427 36744727.91581 +3428 3428 519447617.7192 +3429 3428 5428975.267292 +3430 3428 27155982.42461 +3431 3428 42674756.05248 +3513 3428 11964870.03287 +3514 3428 -11171906.87604 +3515 3428 -13613251.03531 +3516 3428 73404184.96491 +3517 3428 -6857575.146392 +3518 3428 -87786498.03904 +3519 3428 24822942.95376 +3520 3428 18029482.02244 +3521 3428 -52061746.4183 +3534 3428 2735859.138623 +3535 3428 -23029577.62992 +3536 3428 -5469183.701778 +3537 3428 15229460.85439 +3538 3428 -13715150.28603 +3539 3428 -92155412.4252 +3540 3428 5307473.722807 +3541 3428 36744727.91595 +3542 3428 -84172019.33696 +3429 3429 522704651.1313 +3430 3429 141896.0766639 +3431 3429 19774674.20139 +3432 3429 59979012.46658 +3433 3429 3521978.896065 +3434 3429 223245.4222929 +3516 3429 -26133752.36576 +3517 3429 15625000.00514 +3518 3429 11964870.03287 +3519 3429 -94931088.19469 +3520 3429 1778213.472971 +3521 3429 70668209.66918 +3522 3429 -34774920.06465 +3523 3429 -15601315.81941 +3524 3429 19624361.87508 +3537 3429 9602926.484067 +3538 3429 -3125000.001024 +3539 3429 -2164383.918541 +3540 3429 47127590.05582 +3541 3429 23589.49173892 +3542 3429 -9569136.5938 +3543 3429 -9037623.796586 +3544 3429 1299512.850601 +3545 3429 -1549059.953223 +3430 3430 453674266.6075 +3431 3430 -31606008.9039 +3432 3430 -21478021.09983 +3433 3430 -61225625.4412 +3434 3430 5210611.870475 +3516 3430 15625000.00514 +3517 3430 -21446053.85824 +3518 3430 -11171906.87604 +3519 3430 1778213.472969 +3520 3430 -28083353.10861 +3521 3430 -5744510.44953 +3522 3430 -15601315.81941 +3523 3430 -28870353.65893 +3524 3430 15281839.03701 +3537 3430 3125000.001031 +3538 3430 -20084539.63755 +3539 3430 -23029577.62979 +3540 3430 23589.49173927 +3541 3430 29596081.79884 +3542 3430 -8233769.735779 +3543 3430 -4950487.151452 +3544 3430 -39258649.4173 +3545 3430 32897925.65411 +3431 3431 506379680.2075 +3432 3431 2280537.088619 +3433 3431 5210611.870475 +3434 3431 59105129.33173 +3516 3431 11964870.03287 +3517 3431 -11171906.87604 +3518 3431 -13613251.03531 +3519 3431 72382619.39281 +3520 3431 -5744510.449122 +3521 3431 -87592384.98863 +3522 3431 19624361.87508 +3523 3431 15281839.03701 +3524 3431 -34626266.33531 +3537 3431 2735859.138623 +3538 3431 -23029577.62992 +3539 3431 -5469183.701778 +3540 3431 20317738.40129 +3541 3431 -8233769.735779 +3542 3431 -96598600.18896 +3543 3431 6436842.826668 +3544 3431 32897925.65384 +3545 3431 -50491961.43478 +3432 3432 507163372.2162 +3433 3432 7237603.668449 +3434 3432 63171.26888609 +3435 3432 -97768552.76553 +3436 3432 -65334661.13375 +3437 3432 814983.4184016 +3438 3432 55904688.30974 +3439 3432 6636115.541256 +3440 3432 -371929.3114105 +3519 3432 -27465764.73306 +3520 3432 15436493.44557 +3521 3432 15369153.97845 +3522 3432 -93737827.02013 +3523 3432 2368086.475668 +3524 3432 73456476.46843 +3540 3432 -3381022.64037 +3541 3432 -4950487.151454 +3542 3432 -5342115.507985 +3543 3432 35297954.45178 +3544 3432 1431829.559498 +3545 3432 -14694178.46936 +3546 3432 -36452504.04978 +3547 3432 -16209236.0544 +3548 3432 20513876.38514 +3549 3432 -9940171.192638 +3550 3432 1923313.725128 +3551 3432 -1578351.743113 +3433 3433 479243839.2419 +3434 3433 -7684547.900964 +3435 3433 -65334661.13375 +3436 3433 -76803021.57588 +3437 3433 512891.4409333 +3438 3433 -18363884.45464 +3439 3433 -63428757.10643 +3440 3433 1561400.688534 +3519 3433 15436493.44557 +3520 3433 -28850218.03171 +3521 3433 -15788219.65503 +3522 3433 2368086.475667 +3523 3433 -28491743.93969 +3524 3433 -2522415.552542 +3540 3433 1299512.850601 +3541 3433 -33602048.2611 +3542 3433 -30322560.44655 +3543 3433 1431829.559502 +3544 3433 26422223.1926 +3545 3433 -1876397.074467 +3546 3433 -16209236.0544 +3547 3433 -31395568.63249 +3548 3433 16792906.76868 +3549 3433 -4326686.276925 +3550 3433 -39761979.51182 +3551 3433 33716685.95988 +3434 3434 526719601.0496 +3435 3434 814983.4184014 +3436 3434 512891.4409332 +3437 3434 -13195949.59502 +3438 3434 313834.5773636 +3439 3434 1561400.688533 +3440 3434 64415432.93373 +3519 3434 15369153.97845 +3520 3434 -15788219.65503 +3521 3434 -27297255.58841 +3522 3434 73456476.46876 +3523 3434 -2522415.552135 +3524 3434 -98623886.54024 +3540 3434 1615141.438405 +3541 3434 -30322560.44696 +3542 3434 -35407691.68486 +3543 3434 14776029.85913 +3544 3434 -1876397.074467 +3545 3434 -114825169.0474 +3546 3434 20513876.38514 +3547 3434 16792906.76868 +3548 3434 -36499073.21199 +3549 3434 5856613.537447 +3550 3434 33716685.95988 +3551 3434 -49158484.41831 +3435 3435 272936065.9033 +3436 3435 67974760.10349 +3437 3435 -431631.5032227 +3438 3435 -97286780.51185 +3439 3435 -9665338.853946 +3440 3435 -243513.5111909 +3522 3435 -6985166.079218 +3523 3435 1989742.081013 +3524 3435 1871669.756412 +3543 3435 -35903892.93849 +3544 3435 -16209236.0544 +3545 3435 -20111123.62821 +3546 3435 17575332.77501 +3547 3435 16760257.92515 +3548 3435 8019273.530703 +3549 3435 -49380940.42286 +3550 3435 -2540763.951765 +3551 3435 -38529819.65891 +3436 3436 241451433.2226 +3437 3436 -490165.0741773 +3438 3436 15334661.14195 +3439 3436 34091438.27351 +3440 3436 -512891.4409258 +3522 3436 -4260257.921042 +3523 3436 -37145658.44093 +3524 3436 -33211725.57395 +3543 3436 -16209236.0544 +3544 3436 -30846957.52121 +3545 3436 -16540426.57559 +3546 3436 16760257.92515 +3547 3436 9649887.624199 +3548 3436 6545058.911655 +3549 3436 3709236.050289 +3550 3436 -16351938.32763 +3551 3436 3207093.237879 +3437 3437 282691779.8788 +3438 3437 -243513.5111878 +3439 3437 -512891.440926 +3440 3437 51642144.09707 +3522 3437 -6253330.245749 +3523 3437 -33211725.57395 +3524 3437 -47248819.99024 +3543 3437 -20111123.62821 +3544 3437 -16540426.57559 +3545 3437 -35036110.24856 +3546 3437 -8230726.466628 +3547 3437 -6788274.419488 +3548 3437 -64159173.03356 +3549 3437 -38529819.65942 +3550 3437 -3459573.430977 +3551 3437 -52741674.50249 +3438 3438 250941811.6415 +3439 3438 -56636115.53305 +3440 3438 -542422.5410457 +3522 3438 -29442825.22804 +3523 3438 15040763.95587 +3524 3438 17931584.71763 +3543 3438 -8294337.85986 +3544 3438 -4326686.276927 +3545 3438 -5714289.242432 +3546 3438 -49380940.42286 +3547 3438 3709236.050297 +3548 3438 38412801.85615 +3549 3438 15728770.17635 +3550 3438 -14423313.72924 +3551 3438 -7391833.442228 +3439 3439 237298694.5795 +3440 3439 -1561400.688515 +3522 3439 15040763.95587 +3523 3439 -28424057.12979 +3524 3439 -16540426.57559 +3543 3439 1923313.725128 +3544 3439 -38116146.17906 +3545 3439 -32949980.69584 +3546 3439 -2540763.951758 +3547 3439 -16351938.32763 +3548 3439 3207093.237879 +3549 3439 -14423313.72924 +3550 3439 11502808.30206 +3551 3439 6283314.033542 +3440 3440 266261171.1829 +3522 3440 17931584.71763 +3523 3440 -16540426.57559 +3524 3440 -32613209.85713 +3543 3440 1377794.09374 +3544 3440 -32949980.69584 +3545 3440 -44769595.53089 +3546 3440 38412801.85581 +3547 3440 -3459573.430977 +3548 3440 -52741674.50249 +3549 3440 7135215.166498 +3550 3440 -7050019.297601 +3551 3440 -60247075.66791 +3441 3441 686246478.3192 +3442 3441 62499999.98975 +3443 3441 26305964.70958 +3444 3441 -342709650.4072 +3445 3441 -62517557.83129 +3446 3441 -26298419.34625 +3447 3441 11295368.10194 +3448 3441 50017557.83334 +3449 3441 -21265985.17297 +3552 3441 64179725.07093 +3553 3441 15625000.00514 +3554 3441 22379883.77153 +3555 3441 -131080904.1793 +3556 3441 -15629389.46552 +3557 3441 -81477706.67803 +3558 3441 -28030795.60664 +3559 3441 12504389.4645 +3560 3441 -20094076.36695 +3442 3442 592472754.8433 +3443 3442 -68590352.01097 +3444 3442 -62526336.75206 +3445 3442 -48902670.76065 +3446 3442 -37999764.78392 +3447 3442 75026336.75001 +3448 3442 11295368.10194 +3449 3442 23873156.16496 +3552 3442 15625000.00513 +3553 3442 40736294.19042 +3554 3442 -4504985.17355 +3555 3442 -15631584.19572 +3556 3442 -57629159.23151 +3557 3442 -24484028.50059 +3558 3442 18756584.19674 +3559 3442 -28030795.60664 +3560 3442 24112532.59506 +3443 3443 708219203.5496 +3444 3443 -26294646.66457 +3445 3443 -30590657.17329 +3446 3443 7845748.044902 +3447 3443 -31898977.75945 +3448 3443 15915437.44331 +3449 3443 30120981.60519 +3552 3443 -7512792.611826 +3553 3443 -28418903.81719 +3554 3443 -109296917.9411 +3555 3443 -81133941.74793 +3556 3443 -22561100.97091 +3557 3443 -119114540.4154 +3558 3443 -30141114.55043 +3559 3443 16075021.73004 +3560 3443 -74748788.28438 +3444 3444 1165690130.316 +3445 3444 62543894.59362 +3446 3444 30858903.05731 +3447 3444 26211628.98162 +3448 3444 -62517557.8313 +3449 3444 26694959.91784 +3450 3444 -229462147.1059 +3451 3444 3.129243850708e-06 +3452 3444 -4571801.756165 +3453 3444 -93117579.12609 +3454 3444 62499999.98975 +3455 3444 -26687655.2966 +3552 3444 -115335214.0726 +3553 3444 -15631584.19572 +3554 3444 68329440.16886 +3555 3444 130473837.5578 +3556 3444 15635973.65611 +3557 3444 7712253.313144 +3558 3444 -53686446.86531 +3559 3444 -15629389.46553 +3560 3444 25401550.08976 +3561 3444 -102220422.2785 +3562 3444 1.013278961182e-06 +3563 3444 -76032967.78832 +3564 3444 -41874328.64406 +3565 3444 15625000.00513 +3566 3444 -25394418.17384 +3445 3445 996913230.7936 +3446 3445 -85034368.77329 +3447 3445 -62526336.75207 +3448 3445 -192572421.21 +3449 3445 45540401.39811 +3450 3445 3.904104232788e-06 +3451 3445 45539169.75475 +3452 3445 -27430300.57206 +3453 3445 62499999.98975 +3454 3445 -74366785.10525 +3455 3445 14949525.28589 +3552 3445 -15629389.46552 +3553 3445 -41883469.12474 +3554 3445 7334445.059211 +3555 3445 15635973.65611 +3556 3445 88279612.65644 +3557 3445 -21260570.15053 +3558 3445 -15631584.19572 +3559 3445 -108382459.4402 +3560 3445 71307025.97358 +3561 3445 -7.748603820801e-07 +3562 3445 -33470093.0295 +3563 3445 -6857575.146393 +3564 3445 15625000.00513 +3565 3445 -37186630.13654 +3566 3445 18715245.91155 +3446 3446 1089507525.384 +3447 3446 27041494.17268 +3448 3446 53223718.26906 +3449 3446 45623912.47205 +3450 3446 -4571801.756165 +3451 3446 -27430300.57206 +3452 3446 85330883.72684 +3453 3446 -27030537.24082 +3454 3446 15223830.84127 +3455 3446 -24006523.35327 +3552 3446 67985675.23876 +3553 3446 5415714.150796 +3554 3446 -77126033.46393 +3555 3446 7717499.145858 +3556 3446 -21256373.52338 +3557 3446 -156819638.9591 +3558 3446 25405116.04772 +3559 3446 72953597.68388 +3560 3446 -149232299.5136 +3561 3446 -75690085.8441 +3562 3446 -6857575.146393 +3563 3446 -98280306.98791 +3564 3446 -25394418.17384 +3565 3446 18715245.91155 +3566 3446 -55588121.11081 +3447 3447 686246478.3192 +3448 3447 62499999.98975 +3449 3447 26305964.70958 +3450 3447 -91763195.44578 +3451 3447 -62499999.98975 +3452 3447 24744636.36161 +3453 3447 -342709650.4072 +3454 3447 -62517557.83129 +3455 3447 -26298419.34625 +3456 3447 11295368.10194 +3457 3447 50017557.83334 +3458 3447 -21265985.17297 +3552 3447 1493260.574915 +3553 3447 18756584.19674 +3554 3447 14705768.01689 +3555 3447 -8426923.443562 +3556 3447 -15631584.19572 +3557 3447 -11969908.87826 +3558 3447 64179725.07093 +3559 3447 15625000.00514 +3560 3447 22379883.77153 +3561 3447 -26778951.03495 +3562 3447 -15625000.00513 +3563 3447 -12536345.25295 +3564 3447 -131080904.1793 +3565 3447 -15629389.46552 +3566 3447 -81477706.67803 +3567 3447 -28030795.60664 +3568 3447 12504389.4645 +3569 3447 -20094076.36695 +3448 3448 592472754.8433 +3449 3448 -68590352.01097 +3450 3448 -62499999.98975 +3451 3448 -73012401.42493 +3452 3448 12480775.28616 +3453 3448 -62526336.75206 +3454 3448 -48902670.76065 +3455 3448 -37999764.78392 +3456 3448 75026336.75001 +3457 3448 11295368.10194 +3458 3448 23873156.16496 +3552 3448 12504389.4645 +3553 3448 1493260.574915 +3554 3448 -7843093.74256 +3555 3448 -15629389.46552 +3556 3448 -63122936.0184 +3557 3448 -46615995.93793 +3558 3448 15625000.00513 +3559 3448 40736294.19042 +3560 3448 -4504985.17355 +3561 3448 -15625000.00513 +3562 3448 -22091252.52743 +3563 3448 -11857670.76516 +3564 3448 -15631584.19572 +3565 3448 -57629159.23151 +3566 3448 -24484028.50059 +3567 3448 18756584.19674 +3568 3448 -28030795.60664 +3569 3448 24112532.59506 +3449 3449 708219203.5496 +3450 3449 24401754.41739 +3451 3449 12206469.73079 +3452 3449 -20394833.53905 +3453 3449 -26294646.66457 +3454 3449 -30590657.17329 +3455 3449 7845748.044902 +3456 3449 -31898977.75945 +3457 3449 15915437.44331 +3458 3449 30120981.60519 +3552 3449 9803845.344592 +3553 3449 -11764640.61384 +3554 3449 3982028.199772 +3555 3449 -11968229.26313 +3556 3449 -48262567.85004 +3557 3449 -28540237.05556 +3558 3449 -7512792.611826 +3559 3449 -28418903.81719 +3560 3449 -109296917.9411 +3561 3449 -12536345.25295 +3562 3449 -11857670.76516 +3563 3449 -15333780.81983 +3564 3449 -81133941.74793 +3565 3449 -22561100.97091 +3566 3449 -119114540.4154 +3567 3449 -30141114.55043 +3568 3449 16075021.73004 +3569 3449 -74748788.28438 +3450 3450 1082651565.536 +3451 3450 1.692771911621e-05 +3452 3450 9143603.512253 +3453 3450 130318343.5391 +3454 3450 -8.195638656616e-06 +3455 3450 2285900.879194 +3459 3450 -229462147.1059 +3460 3450 3.129243850708e-06 +3461 3450 -4571801.756165 +3462 3450 -93117579.12609 +3463 3450 62499999.98975 +3464 3450 -26687655.2966 +3555 3450 -98285243.92273 +3556 3450 1.072883605957e-06 +3557 3450 73747066.90912 +3558 3450 -40551938.13439 +3559 3450 -15625000.00514 +3560 3450 24822942.95376 +3561 3450 99158852.54101 +3562 3450 3.457069396973e-06 +3563 3450 2285900.879224 +3564 3450 -39821273.75826 +3565 3450 -8.895993232727e-06 +3566 3450 571475.2200941 +3570 3450 -102220422.2785 +3571 3450 1.013278961182e-06 +3572 3450 -76032967.78832 +3573 3450 -41874328.64406 +3574 3450 15625000.00513 +3575 3450 -25394418.17384 +3451 3451 932645213.4434 +3452 3451 -109721202.2342 +3453 3451 -8.702278137207e-06 +3454 3451 -107181385.3168 +3455 3451 54860601.11709 +3459 3451 3.904104232788e-06 +3460 3451 45539169.75475 +3461 3451 -27430300.57206 +3462 3451 62499999.98975 +3463 3451 -74366785.10525 +3464 3451 14949525.28589 +3555 3451 -4.172325134277e-07 +3556 3451 -29534914.67368 +3557 3451 -6857575.146393 +3558 3451 -15625000.00514 +3559 3451 -35864239.62686 +3560 3451 18029482.02244 +3561 3451 3.814697265625e-06 +3562 3451 61657264.49931 +3563 3451 -27430300.57206 +3564 3451 -7.718801498413e-06 +3565 3451 -99196206.00148 +3566 3451 73626608.60945 +3570 3451 -7.748603820801e-07 +3571 3451 -33470093.0295 +3572 3451 -6857575.146393 +3573 3451 15625000.00513 +3574 3451 -37186630.13654 +3575 3451 18715245.91155 +3452 3452 1092614674.45 +3453 3452 2285900.879194 +3454 3452 54860601.11708 +3455 3452 98899681.61908 +3459 3452 -4571801.756165 +3460 3452 -27430300.57206 +3461 3452 85330883.72684 +3462 3452 -27030537.24082 +3463 3452 15223830.84127 +3464 3452 -24006523.35327 +3555 3452 73404184.96491 +3556 3452 -6857575.146392 +3557 3452 -87786498.03904 +3558 3452 24822942.95376 +3559 3452 18029482.02244 +3560 3452 -52061746.4183 +3561 3452 2285900.879224 +3562 3452 -27430300.57206 +3563 3452 -184190435.19 +3564 3452 571475.2200943 +3565 3452 73352303.05408 +3566 3452 -168344038.6739 +3570 3452 -75690085.8441 +3571 3452 -6857575.146393 +3572 3452 -98280306.98791 +3573 3452 -25394418.17384 +3574 3452 18715245.91155 +3575 3452 -55588121.11081 +3453 3453 1165690130.316 +3454 3453 62543894.59362 +3455 3453 30858903.05731 +3456 3453 26211628.98162 +3457 3453 -62517557.8313 +3458 3453 26694959.91784 +3459 3453 -91763195.44578 +3460 3453 -62499999.98975 +3461 3453 24744636.36161 +3462 3453 -229462147.1059 +3463 3453 3.129243850708e-06 +3464 3453 -4571801.756165 +3465 3453 -93117579.12609 +3466 3453 62499999.98975 +3467 3453 -26687655.2966 +3555 3453 -26133752.36576 +3556 3453 15625000.00514 +3557 3453 11964870.03287 +3558 3453 -115335214.0726 +3559 3453 -15631584.19572 +3560 3453 68329440.16886 +3561 3453 19205852.96814 +3562 3453 4.768371582031e-06 +3563 3453 571475.220082 +3564 3453 130473837.5578 +3565 3453 15635973.65611 +3566 3453 7712253.313144 +3567 3453 -53686446.86531 +3568 3453 -15629389.46553 +3569 3453 25401550.08976 +3570 3453 -26778951.03495 +3571 3453 -15625000.00513 +3572 3453 -12536345.25295 +3573 3453 -102220422.2785 +3574 3453 1.013278961182e-06 +3575 3453 -76032967.78832 +3576 3453 -41874328.64406 +3577 3453 15625000.00513 +3578 3453 -25394418.17384 +3454 3454 996913230.7936 +3455 3454 -85034368.77329 +3456 3454 -62526336.75207 +3457 3454 -192572421.21 +3458 3454 45540401.39811 +3459 3454 -62499999.98975 +3460 3454 -73012401.42493 +3461 3454 12480775.28616 +3462 3454 3.904104232788e-06 +3463 3454 45539169.75475 +3464 3454 -27430300.57206 +3465 3454 62499999.98975 +3466 3454 -74366785.10525 +3467 3454 14949525.28589 +3555 3454 15625000.00514 +3556 3454 -21446053.85824 +3557 3454 -11171906.87604 +3558 3454 -15629389.46552 +3559 3454 -41883469.12474 +3560 3454 7334445.059211 +3561 3454 6.780028343201e-06 +3562 3454 -40169079.27509 +3563 3454 -46196308.03739 +3564 3454 15635973.65611 +3565 3454 88279612.65644 +3566 3454 -21260570.15053 +3567 3454 -15631584.19572 +3568 3454 -108382459.4402 +3569 3454 71307025.97358 +3570 3454 -15625000.00513 +3571 3454 -22091252.52743 +3572 3454 -11857670.76516 +3573 3454 -7.748603820801e-07 +3574 3454 -33470093.0295 +3575 3454 -6857575.146393 +3576 3454 15625000.00513 +3577 3454 -37186630.13654 +3578 3454 18715245.91155 +3455 3455 1089507525.384 +3456 3455 27041494.17268 +3457 3455 53223718.26906 +3458 3455 45623912.47205 +3459 3455 24401754.41739 +3460 3455 12206469.73079 +3461 3455 -20394833.53905 +3462 3455 -4571801.756165 +3463 3455 -27430300.57206 +3464 3455 85330883.72684 +3465 3455 -27030537.24082 +3466 3455 15223830.84127 +3467 3455 -24006523.35327 +3555 3455 11964870.03287 +3556 3455 -11171906.87604 +3557 3455 -13613251.03531 +3558 3455 67985675.23876 +3559 3455 5415714.150796 +3560 3455 -77126033.46393 +3561 3455 571475.2200821 +3562 3455 -45922002.48202 +3563 3455 -10938367.40355 +3564 3455 7717499.145858 +3565 3455 -21256373.52338 +3566 3455 -156819638.9591 +3567 3455 25405116.04772 +3568 3455 72953597.68388 +3569 3455 -149232299.5136 +3570 3455 -12536345.25295 +3571 3455 -11857670.76516 +3572 3455 -15333780.81983 +3573 3455 -75690085.8441 +3574 3455 -6857575.146393 +3575 3455 -98280306.98791 +3576 3455 -25394418.17384 +3577 3455 18715245.91155 +3578 3455 -55588121.11081 +3456 3456 686246478.3192 +3457 3456 62499999.98975 +3458 3456 26305964.70958 +3462 3456 -91763195.44578 +3463 3456 -62499999.98975 +3464 3456 24744636.36161 +3465 3456 -342709650.4072 +3466 3456 -62517557.83129 +3467 3456 -26298419.34625 +3468 3456 11295368.10194 +3469 3456 50017557.83334 +3470 3456 -21265985.17297 +3558 3456 1493260.574915 +3559 3456 18756584.19674 +3560 3456 14705768.01689 +3564 3456 -8426923.443562 +3565 3456 -15631584.19572 +3566 3456 -11969908.87826 +3567 3456 64179725.07093 +3568 3456 15625000.00514 +3569 3456 22379883.77153 +3573 3456 -26778951.03495 +3574 3456 -15625000.00513 +3575 3456 -12536345.25295 +3576 3456 -131080904.1793 +3577 3456 -15629389.46552 +3578 3456 -81477706.67803 +3579 3456 -28030795.60664 +3580 3456 12504389.4645 +3581 3456 -20094076.36695 +3457 3457 592472754.8433 +3458 3457 -68590352.01097 +3462 3457 -62499999.98975 +3463 3457 -73012401.42493 +3464 3457 12480775.28616 +3465 3457 -62526336.75206 +3466 3457 -48902670.76065 +3467 3457 -37999764.78392 +3468 3457 75026336.75001 +3469 3457 11295368.10194 +3470 3457 23873156.16496 +3558 3457 12504389.4645 +3559 3457 1493260.574915 +3560 3457 -7843093.74256 +3564 3457 -15629389.46552 +3565 3457 -63122936.0184 +3566 3457 -46615995.93793 +3567 3457 15625000.00513 +3568 3457 40736294.19042 +3569 3457 -4504985.17355 +3573 3457 -15625000.00513 +3574 3457 -22091252.52743 +3575 3457 -11857670.76516 +3576 3457 -15631584.19572 +3577 3457 -57629159.23151 +3578 3457 -24484028.50059 +3579 3457 18756584.19674 +3580 3457 -28030795.60664 +3581 3457 24112532.59506 +3458 3458 708219203.5496 +3462 3458 24401754.41739 +3463 3458 12206469.73079 +3464 3458 -20394833.53905 +3465 3458 -26294646.66457 +3466 3458 -30590657.17329 +3467 3458 7845748.044902 +3468 3458 -31898977.75945 +3469 3458 15915437.44331 +3470 3458 30120981.60519 +3558 3458 9803845.344592 +3559 3458 -11764640.61384 +3560 3458 3982028.199772 +3564 3458 -11968229.26313 +3565 3458 -48262567.85004 +3566 3458 -28540237.05556 +3567 3458 -7512792.611826 +3568 3458 -28418903.81719 +3569 3458 -109296917.9411 +3573 3458 -12536345.25295 +3574 3458 -11857670.76516 +3575 3458 -15333780.81983 +3576 3458 -81133941.74793 +3577 3458 -22561100.97091 +3578 3458 -119114540.4154 +3579 3458 -30141114.55043 +3580 3458 16075021.73004 +3581 3458 -74748788.28438 +3459 3459 1082651565.536 +3460 3459 1.692771911621e-05 +3461 3459 9143603.512253 +3462 3459 130318343.5391 +3463 3459 -8.195638656616e-06 +3464 3459 2285900.879194 +3471 3459 -229462147.1059 +3472 3459 3.129243850708e-06 +3473 3459 -4571801.756165 +3474 3459 -93117579.12609 +3475 3459 62499999.98975 +3476 3459 -26687655.2966 +3561 3459 -98285243.92273 +3562 3459 1.072883605957e-06 +3563 3459 73747066.90912 +3564 3459 -40551938.13439 +3565 3459 -15625000.00514 +3566 3459 24822942.95376 +3570 3459 99158852.54101 +3571 3459 3.457069396973e-06 +3572 3459 2285900.879224 +3573 3459 -39821273.75826 +3574 3459 -8.895993232727e-06 +3575 3459 571475.2200941 +3582 3459 -102220422.2785 +3583 3459 1.013278961182e-06 +3584 3459 -76032967.78832 +3585 3459 -41874328.64406 +3586 3459 15625000.00513 +3587 3459 -25394418.17384 +3460 3460 932645213.4434 +3461 3460 -109721202.2342 +3462 3460 -8.702278137207e-06 +3463 3460 -107181385.3168 +3464 3460 54860601.11709 +3471 3460 3.904104232788e-06 +3472 3460 45539169.75475 +3473 3460 -27430300.57206 +3474 3460 62499999.98975 +3475 3460 -74366785.10525 +3476 3460 14949525.28589 +3561 3460 -4.172325134277e-07 +3562 3460 -29534914.67368 +3563 3460 -6857575.146393 +3564 3460 -15625000.00514 +3565 3460 -35864239.62686 +3566 3460 18029482.02244 +3570 3460 3.814697265625e-06 +3571 3460 61657264.49931 +3572 3460 -27430300.57206 +3573 3460 -7.718801498413e-06 +3574 3460 -99196206.00148 +3575 3460 73626608.60945 +3582 3460 -7.748603820801e-07 +3583 3460 -33470093.0295 +3584 3460 -6857575.146393 +3585 3460 15625000.00513 +3586 3460 -37186630.13654 +3587 3460 18715245.91155 +3461 3461 1092614674.45 +3462 3461 2285900.879194 +3463 3461 54860601.11708 +3464 3461 98899681.61908 +3471 3461 -4571801.756165 +3472 3461 -27430300.57206 +3473 3461 85330883.72684 +3474 3461 -27030537.24082 +3475 3461 15223830.84127 +3476 3461 -24006523.35327 +3561 3461 73404184.96491 +3562 3461 -6857575.146392 +3563 3461 -87786498.03904 +3564 3461 24822942.95376 +3565 3461 18029482.02244 +3566 3461 -52061746.4183 +3570 3461 2285900.879224 +3571 3461 -27430300.57206 +3572 3461 -184190435.19 +3573 3461 571475.2200943 +3574 3461 73352303.05408 +3575 3461 -168344038.6739 +3582 3461 -75690085.8441 +3583 3461 -6857575.146393 +3584 3461 -98280306.98791 +3585 3461 -25394418.17384 +3586 3461 18715245.91155 +3587 3461 -55588121.11081 +3462 3462 1082651565.536 +3463 3462 1.692771911621e-05 +3464 3462 9143603.512253 +3465 3462 130318343.5391 +3466 3462 -8.195638656616e-06 +3467 3462 2285900.879194 +3471 3462 -91763195.44578 +3472 3462 -62499999.98975 +3473 3462 24744636.36161 +3474 3462 -229462147.1059 +3475 3462 3.129243850708e-06 +3476 3462 -4571801.756165 +3477 3462 -93117579.12609 +3478 3462 62499999.98975 +3479 3462 -26687655.2966 +3561 3462 -26133752.36576 +3562 3462 15625000.00514 +3563 3462 11964870.03287 +3564 3462 -98285243.92273 +3565 3462 1.072883605957e-06 +3566 3462 73747066.90912 +3567 3462 -40551938.13439 +3568 3462 -15625000.00514 +3569 3462 24822942.95376 +3570 3462 19205852.96814 +3571 3462 4.768371582031e-06 +3572 3462 571475.220082 +3573 3462 99158852.54101 +3574 3462 3.457069396973e-06 +3575 3462 2285900.879224 +3576 3462 -39821273.75826 +3577 3462 -8.895993232727e-06 +3578 3462 571475.2200941 +3582 3462 -26778951.03495 +3583 3462 -15625000.00513 +3584 3462 -12536345.25295 +3585 3462 -102220422.2785 +3586 3462 1.013278961182e-06 +3587 3462 -76032967.78832 +3588 3462 -41874328.64406 +3589 3462 15625000.00513 +3590 3462 -25394418.17384 +3463 3463 932645213.4434 +3464 3463 -109721202.2342 +3465 3463 -8.702278137207e-06 +3466 3463 -107181385.3168 +3467 3463 54860601.11709 +3471 3463 -62499999.98975 +3472 3463 -73012401.42493 +3473 3463 12480775.28616 +3474 3463 3.904104232788e-06 +3475 3463 45539169.75475 +3476 3463 -27430300.57206 +3477 3463 62499999.98975 +3478 3463 -74366785.10525 +3479 3463 14949525.28589 +3561 3463 15625000.00514 +3562 3463 -21446053.85824 +3563 3463 -11171906.87604 +3564 3463 -4.172325134277e-07 +3565 3463 -29534914.67368 +3566 3463 -6857575.146393 +3567 3463 -15625000.00514 +3568 3463 -35864239.62686 +3569 3463 18029482.02244 +3570 3463 6.780028343201e-06 +3571 3463 -40169079.27509 +3572 3463 -46196308.03739 +3573 3463 3.814697265625e-06 +3574 3463 61657264.49931 +3575 3463 -27430300.57206 +3576 3463 -7.718801498413e-06 +3577 3463 -99196206.00148 +3578 3463 73626608.60945 +3582 3463 -15625000.00513 +3583 3463 -22091252.52743 +3584 3463 -11857670.76516 +3585 3463 -7.748603820801e-07 +3586 3463 -33470093.0295 +3587 3463 -6857575.146393 +3588 3463 15625000.00513 +3589 3463 -37186630.13654 +3590 3463 18715245.91155 +3464 3464 1092614674.45 +3465 3464 2285900.879194 +3466 3464 54860601.11708 +3467 3464 98899681.61908 +3471 3464 24401754.41739 +3472 3464 12206469.73079 +3473 3464 -20394833.53905 +3474 3464 -4571801.756165 +3475 3464 -27430300.57206 +3476 3464 85330883.72684 +3477 3464 -27030537.24082 +3478 3464 15223830.84127 +3479 3464 -24006523.35327 +3561 3464 11964870.03287 +3562 3464 -11171906.87604 +3563 3464 -13613251.03531 +3564 3464 73404184.96491 +3565 3464 -6857575.146392 +3566 3464 -87786498.03904 +3567 3464 24822942.95376 +3568 3464 18029482.02244 +3569 3464 -52061746.4183 +3570 3464 571475.2200821 +3571 3464 -45922002.48202 +3572 3464 -10938367.40355 +3573 3464 2285900.879224 +3574 3464 -27430300.57206 +3575 3464 -184190435.19 +3576 3464 571475.2200943 +3577 3464 73352303.05408 +3578 3464 -168344038.6739 +3582 3464 -12536345.25295 +3583 3464 -11857670.76516 +3584 3464 -15333780.81983 +3585 3464 -75690085.8441 +3586 3464 -6857575.146393 +3587 3464 -98280306.98791 +3588 3464 -25394418.17384 +3589 3464 18715245.91155 +3590 3464 -55588121.11081 +3465 3465 1165690130.316 +3466 3465 62543894.59362 +3467 3465 30858903.05731 +3468 3465 26211628.98162 +3469 3465 -62517557.8313 +3470 3465 26694959.91784 +3474 3465 -91763195.44578 +3475 3465 -62499999.98975 +3476 3465 24744636.36161 +3477 3465 -229462147.1059 +3478 3465 3.129243850708e-06 +3479 3465 -4571801.756165 +3480 3465 -93117579.12609 +3481 3465 62499999.98975 +3482 3465 -26687655.2966 +3564 3465 -26133752.36576 +3565 3465 15625000.00514 +3566 3465 11964870.03287 +3567 3465 -115335214.0726 +3568 3465 -15631584.19572 +3569 3465 68329440.16886 +3573 3465 19205852.96814 +3574 3465 4.768371582031e-06 +3575 3465 571475.220082 +3576 3465 130473837.5578 +3577 3465 15635973.65611 +3578 3465 7712253.313144 +3579 3465 -53686446.86531 +3580 3465 -15629389.46553 +3581 3465 25401550.08976 +3585 3465 -26778951.03495 +3586 3465 -15625000.00513 +3587 3465 -12536345.25295 +3588 3465 -102220422.2785 +3589 3465 1.013278961182e-06 +3590 3465 -76032967.78832 +3591 3465 -41874328.64406 +3592 3465 15625000.00513 +3593 3465 -25394418.17384 +3466 3466 996913230.7936 +3467 3466 -85034368.77329 +3468 3466 -62526336.75207 +3469 3466 -192572421.21 +3470 3466 45540401.39811 +3474 3466 -62499999.98975 +3475 3466 -73012401.42493 +3476 3466 12480775.28616 +3477 3466 3.904104232788e-06 +3478 3466 45539169.75475 +3479 3466 -27430300.57206 +3480 3466 62499999.98975 +3481 3466 -74366785.10525 +3482 3466 14949525.28589 +3564 3466 15625000.00514 +3565 3466 -21446053.85824 +3566 3466 -11171906.87604 +3567 3466 -15629389.46552 +3568 3466 -41883469.12474 +3569 3466 7334445.059211 +3573 3466 6.780028343201e-06 +3574 3466 -40169079.27509 +3575 3466 -46196308.03739 +3576 3466 15635973.65611 +3577 3466 88279612.65644 +3578 3466 -21260570.15053 +3579 3466 -15631584.19572 +3580 3466 -108382459.4402 +3581 3466 71307025.97358 +3585 3466 -15625000.00513 +3586 3466 -22091252.52743 +3587 3466 -11857670.76516 +3588 3466 -7.748603820801e-07 +3589 3466 -33470093.0295 +3590 3466 -6857575.146393 +3591 3466 15625000.00513 +3592 3466 -37186630.13654 +3593 3466 18715245.91155 +3467 3467 1089507525.384 +3468 3467 27041494.17268 +3469 3467 53223718.26906 +3470 3467 45623912.47205 +3474 3467 24401754.41739 +3475 3467 12206469.73079 +3476 3467 -20394833.53905 +3477 3467 -4571801.756165 +3478 3467 -27430300.57206 +3479 3467 85330883.72684 +3480 3467 -27030537.24082 +3481 3467 15223830.84127 +3482 3467 -24006523.35327 +3564 3467 11964870.03287 +3565 3467 -11171906.87604 +3566 3467 -13613251.03531 +3567 3467 67985675.23876 +3568 3467 5415714.150796 +3569 3467 -77126033.46393 +3573 3467 571475.2200821 +3574 3467 -45922002.48202 +3575 3467 -10938367.40355 +3576 3467 7717499.145858 +3577 3467 -21256373.52338 +3578 3467 -156819638.9591 +3579 3467 25405116.04772 +3580 3467 72953597.68388 +3581 3467 -149232299.5136 +3585 3467 -12536345.25295 +3586 3467 -11857670.76516 +3587 3467 -15333780.81983 +3588 3467 -75690085.8441 +3589 3467 -6857575.146393 +3590 3467 -98280306.98791 +3591 3467 -25394418.17384 +3592 3467 18715245.91155 +3593 3467 -55588121.11081 +3468 3468 686246478.3192 +3469 3468 62499999.98975 +3470 3468 26305964.70958 +3477 3468 -91763195.44578 +3478 3468 -62499999.98975 +3479 3468 24744636.36161 +3480 3468 -342709650.4072 +3481 3468 -62517557.83129 +3482 3468 -26298419.34625 +3483 3468 11295368.10194 +3484 3468 50017557.83334 +3485 3468 -21265985.17297 +3567 3468 1493260.574915 +3568 3468 18756584.19674 +3569 3468 14705768.01689 +3576 3468 -8426923.443562 +3577 3468 -15631584.19572 +3578 3468 -11969908.87826 +3579 3468 64179725.07093 +3580 3468 15625000.00514 +3581 3468 22379883.77153 +3588 3468 -26778951.03495 +3589 3468 -15625000.00513 +3590 3468 -12536345.25295 +3591 3468 -131080904.1793 +3592 3468 -15629389.46552 +3593 3468 -81477706.67803 +3594 3468 -28030795.60664 +3595 3468 12504389.4645 +3596 3468 -20094076.36695 +3469 3469 592472754.8433 +3470 3469 -68590352.01097 +3477 3469 -62499999.98975 +3478 3469 -73012401.42493 +3479 3469 12480775.28616 +3480 3469 -62526336.75206 +3481 3469 -48902670.76065 +3482 3469 -37999764.78392 +3483 3469 75026336.75001 +3484 3469 11295368.10194 +3485 3469 23873156.16496 +3567 3469 12504389.4645 +3568 3469 1493260.574915 +3569 3469 -7843093.74256 +3576 3469 -15629389.46552 +3577 3469 -63122936.0184 +3578 3469 -46615995.93793 +3579 3469 15625000.00513 +3580 3469 40736294.19042 +3581 3469 -4504985.17355 +3588 3469 -15625000.00513 +3589 3469 -22091252.52743 +3590 3469 -11857670.76516 +3591 3469 -15631584.19572 +3592 3469 -57629159.23151 +3593 3469 -24484028.50059 +3594 3469 18756584.19674 +3595 3469 -28030795.60664 +3596 3469 24112532.59506 +3470 3470 708219203.5496 +3477 3470 24401754.41739 +3478 3470 12206469.73079 +3479 3470 -20394833.53905 +3480 3470 -26294646.66457 +3481 3470 -30590657.17329 +3482 3470 7845748.044902 +3483 3470 -31898977.75945 +3484 3470 15915437.44331 +3485 3470 30120981.60519 +3567 3470 9803845.344592 +3568 3470 -11764640.61384 +3569 3470 3982028.199772 +3576 3470 -11968229.26313 +3577 3470 -48262567.85004 +3578 3470 -28540237.05556 +3579 3470 -7512792.611826 +3580 3470 -28418903.81719 +3581 3470 -109296917.9411 +3588 3470 -12536345.25295 +3589 3470 -11857670.76516 +3590 3470 -15333780.81983 +3591 3470 -81133941.74793 +3592 3470 -22561100.97091 +3593 3470 -119114540.4154 +3594 3470 -30141114.55043 +3595 3470 16075021.73004 +3596 3470 -74748788.28438 +3471 3471 1082651565.536 +3472 3471 1.692771911621e-05 +3473 3471 9143603.512253 +3474 3471 130318343.5391 +3475 3471 -8.195638656616e-06 +3476 3471 2285900.879194 +3486 3471 -229462147.1059 +3487 3471 3.129243850708e-06 +3488 3471 -4571801.756165 +3489 3471 -93117579.12609 +3490 3471 62499999.98975 +3491 3471 -26687655.2966 +3570 3471 -98285243.92273 +3571 3471 1.072883605957e-06 +3572 3471 73747066.90912 +3573 3471 -40551938.13439 +3574 3471 -15625000.00514 +3575 3471 24822942.95376 +3582 3471 99158852.54101 +3583 3471 3.457069396973e-06 +3584 3471 2285900.879224 +3585 3471 -39821273.75826 +3586 3471 -8.895993232727e-06 +3587 3471 571475.2200941 +3597 3471 -102220422.2785 +3598 3471 1.013278961182e-06 +3599 3471 -76032967.78832 +3600 3471 -41874328.64406 +3601 3471 15625000.00513 +3602 3471 -25394418.17384 +3472 3472 932645213.4434 +3473 3472 -109721202.2342 +3474 3472 -8.702278137207e-06 +3475 3472 -107181385.3168 +3476 3472 54860601.11709 +3486 3472 3.904104232788e-06 +3487 3472 45539169.75475 +3488 3472 -27430300.57206 +3489 3472 62499999.98975 +3490 3472 -74366785.10525 +3491 3472 14949525.28589 +3570 3472 -4.172325134277e-07 +3571 3472 -29534914.67368 +3572 3472 -6857575.146393 +3573 3472 -15625000.00514 +3574 3472 -35864239.62686 +3575 3472 18029482.02244 +3582 3472 3.814697265625e-06 +3583 3472 61657264.49931 +3584 3472 -27430300.57206 +3585 3472 -7.718801498413e-06 +3586 3472 -99196206.00148 +3587 3472 73626608.60945 +3597 3472 -7.748603820801e-07 +3598 3472 -33470093.0295 +3599 3472 -6857575.146393 +3600 3472 15625000.00513 +3601 3472 -37186630.13654 +3602 3472 18715245.91155 +3473 3473 1092614674.45 +3474 3473 2285900.879194 +3475 3473 54860601.11708 +3476 3473 98899681.61908 +3486 3473 -4571801.756165 +3487 3473 -27430300.57206 +3488 3473 85330883.72684 +3489 3473 -27030537.24082 +3490 3473 15223830.84127 +3491 3473 -24006523.35327 +3570 3473 73404184.96491 +3571 3473 -6857575.146392 +3572 3473 -87786498.03904 +3573 3473 24822942.95376 +3574 3473 18029482.02244 +3575 3473 -52061746.4183 +3582 3473 2285900.879224 +3583 3473 -27430300.57206 +3584 3473 -184190435.19 +3585 3473 571475.2200943 +3586 3473 73352303.05408 +3587 3473 -168344038.6739 +3597 3473 -75690085.8441 +3598 3473 -6857575.146393 +3599 3473 -98280306.98791 +3600 3473 -25394418.17384 +3601 3473 18715245.91155 +3602 3473 -55588121.11081 +3474 3474 1082651565.536 +3475 3474 1.692771911621e-05 +3476 3474 9143603.512253 +3477 3474 130318343.5391 +3478 3474 -8.195638656616e-06 +3479 3474 2285900.879194 +3486 3474 -91763195.44578 +3487 3474 -62499999.98975 +3488 3474 24744636.36161 +3489 3474 -229462147.1059 +3490 3474 3.129243850708e-06 +3491 3474 -4571801.756165 +3492 3474 -93117579.12609 +3493 3474 62499999.98975 +3494 3474 -26687655.2966 +3570 3474 -26133752.36576 +3571 3474 15625000.00514 +3572 3474 11964870.03287 +3573 3474 -98285243.92273 +3574 3474 1.072883605957e-06 +3575 3474 73747066.90912 +3576 3474 -40551938.13439 +3577 3474 -15625000.00514 +3578 3474 24822942.95376 +3582 3474 19205852.96814 +3583 3474 4.768371582031e-06 +3584 3474 571475.220082 +3585 3474 99158852.54101 +3586 3474 3.457069396973e-06 +3587 3474 2285900.879224 +3588 3474 -39821273.75826 +3589 3474 -8.895993232727e-06 +3590 3474 571475.2200941 +3597 3474 -26778951.03495 +3598 3474 -15625000.00513 +3599 3474 -12536345.25295 +3600 3474 -102220422.2785 +3601 3474 1.013278961182e-06 +3602 3474 -76032967.78832 +3603 3474 -41874328.64406 +3604 3474 15625000.00513 +3605 3474 -25394418.17384 +3475 3475 932645213.4434 +3476 3475 -109721202.2342 +3477 3475 -8.702278137207e-06 +3478 3475 -107181385.3168 +3479 3475 54860601.11709 +3486 3475 -62499999.98975 +3487 3475 -73012401.42493 +3488 3475 12480775.28616 +3489 3475 3.904104232788e-06 +3490 3475 45539169.75475 +3491 3475 -27430300.57206 +3492 3475 62499999.98975 +3493 3475 -74366785.10525 +3494 3475 14949525.28589 +3570 3475 15625000.00514 +3571 3475 -21446053.85824 +3572 3475 -11171906.87604 +3573 3475 -4.172325134277e-07 +3574 3475 -29534914.67368 +3575 3475 -6857575.146393 +3576 3475 -15625000.00514 +3577 3475 -35864239.62686 +3578 3475 18029482.02244 +3582 3475 6.780028343201e-06 +3583 3475 -40169079.27509 +3584 3475 -46196308.03739 +3585 3475 3.814697265625e-06 +3586 3475 61657264.49931 +3587 3475 -27430300.57206 +3588 3475 -7.718801498413e-06 +3589 3475 -99196206.00148 +3590 3475 73626608.60945 +3597 3475 -15625000.00513 +3598 3475 -22091252.52743 +3599 3475 -11857670.76516 +3600 3475 -7.748603820801e-07 +3601 3475 -33470093.0295 +3602 3475 -6857575.146393 +3603 3475 15625000.00513 +3604 3475 -37186630.13654 +3605 3475 18715245.91155 +3476 3476 1092614674.45 +3477 3476 2285900.879194 +3478 3476 54860601.11708 +3479 3476 98899681.61908 +3486 3476 24401754.41739 +3487 3476 12206469.73079 +3488 3476 -20394833.53905 +3489 3476 -4571801.756165 +3490 3476 -27430300.57206 +3491 3476 85330883.72684 +3492 3476 -27030537.24082 +3493 3476 15223830.84127 +3494 3476 -24006523.35327 +3570 3476 11964870.03287 +3571 3476 -11171906.87604 +3572 3476 -13613251.03531 +3573 3476 73404184.96491 +3574 3476 -6857575.146392 +3575 3476 -87786498.03904 +3576 3476 24822942.95376 +3577 3476 18029482.02244 +3578 3476 -52061746.4183 +3582 3476 571475.2200821 +3583 3476 -45922002.48202 +3584 3476 -10938367.40355 +3585 3476 2285900.879224 +3586 3476 -27430300.57206 +3587 3476 -184190435.19 +3588 3476 571475.2200943 +3589 3476 73352303.05408 +3590 3476 -168344038.6739 +3597 3476 -12536345.25295 +3598 3476 -11857670.76516 +3599 3476 -15333780.81983 +3600 3476 -75690085.8441 +3601 3476 -6857575.146393 +3602 3476 -98280306.98791 +3603 3476 -25394418.17384 +3604 3476 18715245.91155 +3605 3476 -55588121.11081 +3477 3477 1082651565.536 +3478 3477 1.692771911621e-05 +3479 3477 9143603.512253 +3480 3477 130318343.5391 +3481 3477 -8.195638656616e-06 +3482 3477 2285900.879194 +3489 3477 -91763195.44578 +3490 3477 -62499999.98975 +3491 3477 24744636.36161 +3492 3477 -229462147.1059 +3493 3477 3.129243850708e-06 +3494 3477 -4571801.756165 +3495 3477 -93117579.12609 +3496 3477 62499999.98975 +3497 3477 -26687655.2966 +3573 3477 -26133752.36576 +3574 3477 15625000.00514 +3575 3477 11964870.03287 +3576 3477 -98285243.92273 +3577 3477 1.072883605957e-06 +3578 3477 73747066.90912 +3579 3477 -40551938.13439 +3580 3477 -15625000.00514 +3581 3477 24822942.95376 +3585 3477 19205852.96814 +3586 3477 4.768371582031e-06 +3587 3477 571475.220082 +3588 3477 99158852.54101 +3589 3477 3.457069396973e-06 +3590 3477 2285900.879224 +3591 3477 -39821273.75826 +3592 3477 -8.895993232727e-06 +3593 3477 571475.2200941 +3600 3477 -26778951.03495 +3601 3477 -15625000.00513 +3602 3477 -12536345.25295 +3603 3477 -102220422.2785 +3604 3477 1.013278961182e-06 +3605 3477 -76032967.78832 +3606 3477 -41874328.64406 +3607 3477 15625000.00513 +3608 3477 -25394418.17384 +3478 3478 932645213.4434 +3479 3478 -109721202.2342 +3480 3478 -8.702278137207e-06 +3481 3478 -107181385.3168 +3482 3478 54860601.11709 +3489 3478 -62499999.98975 +3490 3478 -73012401.42493 +3491 3478 12480775.28616 +3492 3478 3.904104232788e-06 +3493 3478 45539169.75475 +3494 3478 -27430300.57206 +3495 3478 62499999.98975 +3496 3478 -74366785.10525 +3497 3478 14949525.28589 +3573 3478 15625000.00514 +3574 3478 -21446053.85824 +3575 3478 -11171906.87604 +3576 3478 -4.172325134277e-07 +3577 3478 -29534914.67368 +3578 3478 -6857575.146393 +3579 3478 -15625000.00514 +3580 3478 -35864239.62686 +3581 3478 18029482.02244 +3585 3478 6.780028343201e-06 +3586 3478 -40169079.27509 +3587 3478 -46196308.03739 +3588 3478 3.814697265625e-06 +3589 3478 61657264.49931 +3590 3478 -27430300.57206 +3591 3478 -7.718801498413e-06 +3592 3478 -99196206.00148 +3593 3478 73626608.60945 +3600 3478 -15625000.00513 +3601 3478 -22091252.52743 +3602 3478 -11857670.76516 +3603 3478 -7.748603820801e-07 +3604 3478 -33470093.0295 +3605 3478 -6857575.146393 +3606 3478 15625000.00513 +3607 3478 -37186630.13654 +3608 3478 18715245.91155 +3479 3479 1092614674.45 +3480 3479 2285900.879194 +3481 3479 54860601.11708 +3482 3479 98899681.61908 +3489 3479 24401754.41739 +3490 3479 12206469.73079 +3491 3479 -20394833.53905 +3492 3479 -4571801.756165 +3493 3479 -27430300.57206 +3494 3479 85330883.72684 +3495 3479 -27030537.24082 +3496 3479 15223830.84127 +3497 3479 -24006523.35327 +3573 3479 11964870.03287 +3574 3479 -11171906.87604 +3575 3479 -13613251.03531 +3576 3479 73404184.96491 +3577 3479 -6857575.146392 +3578 3479 -87786498.03904 +3579 3479 24822942.95376 +3580 3479 18029482.02244 +3581 3479 -52061746.4183 +3585 3479 571475.2200821 +3586 3479 -45922002.48202 +3587 3479 -10938367.40355 +3588 3479 2285900.879224 +3589 3479 -27430300.57206 +3590 3479 -184190435.19 +3591 3479 571475.2200943 +3592 3479 73352303.05408 +3593 3479 -168344038.6739 +3600 3479 -12536345.25295 +3601 3479 -11857670.76516 +3602 3479 -15333780.81983 +3603 3479 -75690085.8441 +3604 3479 -6857575.146393 +3605 3479 -98280306.98791 +3606 3479 -25394418.17384 +3607 3479 18715245.91155 +3608 3479 -55588121.11081 +3480 3480 1165690130.316 +3481 3480 62543894.59362 +3482 3480 30858903.05731 +3483 3480 26211628.98162 +3484 3480 -62517557.8313 +3485 3480 26694959.91784 +3492 3480 -91763195.44578 +3493 3480 -62499999.98975 +3494 3480 24744636.36161 +3495 3480 -229462147.1059 +3496 3480 3.129243850708e-06 +3497 3480 -4571801.756165 +3498 3480 -93117579.12609 +3499 3480 62499999.98975 +3500 3480 -26687655.2966 +3576 3480 -26133752.36576 +3577 3480 15625000.00514 +3578 3480 11964870.03287 +3579 3480 -115335214.0726 +3580 3480 -15631584.19572 +3581 3480 68329440.16886 +3588 3480 19205852.96814 +3589 3480 4.768371582031e-06 +3590 3480 571475.220082 +3591 3480 130473837.5578 +3592 3480 15635973.65611 +3593 3480 7712253.313144 +3594 3480 -53686446.86531 +3595 3480 -15629389.46553 +3596 3480 25401550.08976 +3603 3480 -26778951.03495 +3604 3480 -15625000.00513 +3605 3480 -12536345.25295 +3606 3480 -102220422.2785 +3607 3480 1.013278961182e-06 +3608 3480 -76032967.78832 +3609 3480 -41874328.64406 +3610 3480 15625000.00513 +3611 3480 -25394418.17384 +3481 3481 996913230.7936 +3482 3481 -85034368.77329 +3483 3481 -62526336.75207 +3484 3481 -192572421.21 +3485 3481 45540401.39811 +3492 3481 -62499999.98975 +3493 3481 -73012401.42493 +3494 3481 12480775.28616 +3495 3481 3.904104232788e-06 +3496 3481 45539169.75475 +3497 3481 -27430300.57206 +3498 3481 62499999.98975 +3499 3481 -74366785.10525 +3500 3481 14949525.28589 +3576 3481 15625000.00514 +3577 3481 -21446053.85824 +3578 3481 -11171906.87604 +3579 3481 -15629389.46552 +3580 3481 -41883469.12474 +3581 3481 7334445.059211 +3588 3481 6.780028343201e-06 +3589 3481 -40169079.27509 +3590 3481 -46196308.03739 +3591 3481 15635973.65611 +3592 3481 88279612.65644 +3593 3481 -21260570.15053 +3594 3481 -15631584.19572 +3595 3481 -108382459.4402 +3596 3481 71307025.97358 +3603 3481 -15625000.00513 +3604 3481 -22091252.52743 +3605 3481 -11857670.76516 +3606 3481 -7.748603820801e-07 +3607 3481 -33470093.0295 +3608 3481 -6857575.146393 +3609 3481 15625000.00513 +3610 3481 -37186630.13654 +3611 3481 18715245.91155 +3482 3482 1089507525.384 +3483 3482 27041494.17268 +3484 3482 53223718.26906 +3485 3482 45623912.47205 +3492 3482 24401754.41739 +3493 3482 12206469.73079 +3494 3482 -20394833.53905 +3495 3482 -4571801.756165 +3496 3482 -27430300.57206 +3497 3482 85330883.72684 +3498 3482 -27030537.24082 +3499 3482 15223830.84127 +3500 3482 -24006523.35327 +3576 3482 11964870.03287 +3577 3482 -11171906.87604 +3578 3482 -13613251.03531 +3579 3482 67985675.23876 +3580 3482 5415714.150796 +3581 3482 -77126033.46393 +3588 3482 571475.2200821 +3589 3482 -45922002.48202 +3590 3482 -10938367.40355 +3591 3482 7717499.145858 +3592 3482 -21256373.52338 +3593 3482 -156819638.9591 +3594 3482 25405116.04772 +3595 3482 72953597.68388 +3596 3482 -149232299.5136 +3603 3482 -12536345.25295 +3604 3482 -11857670.76516 +3605 3482 -15333780.81983 +3606 3482 -75690085.8441 +3607 3482 -6857575.146393 +3608 3482 -98280306.98791 +3609 3482 -25394418.17384 +3610 3482 18715245.91155 +3611 3482 -55588121.11081 +3483 3483 686246478.3192 +3484 3483 62499999.98975 +3485 3483 26305964.70958 +3495 3483 -91763195.44578 +3496 3483 -62499999.98975 +3497 3483 24744636.36161 +3498 3483 -342709650.4072 +3499 3483 -62517557.83129 +3500 3483 -26298419.34625 +3501 3483 11295368.10194 +3502 3483 50017557.83334 +3503 3483 -21265985.17297 +3579 3483 1493260.574915 +3580 3483 18756584.19674 +3581 3483 14705768.01689 +3591 3483 -8426923.443562 +3592 3483 -15631584.19572 +3593 3483 -11969908.87826 +3594 3483 64179725.07093 +3595 3483 15625000.00514 +3596 3483 22379883.77153 +3606 3483 -26778951.03495 +3607 3483 -15625000.00513 +3608 3483 -12536345.25295 +3609 3483 -131080904.1793 +3610 3483 -15629389.46552 +3611 3483 -81477706.67803 +3612 3483 -28030795.60664 +3613 3483 12504389.4645 +3614 3483 -20094076.36695 +3484 3484 592472754.8433 +3485 3484 -68590352.01097 +3495 3484 -62499999.98975 +3496 3484 -73012401.42493 +3497 3484 12480775.28616 +3498 3484 -62526336.75206 +3499 3484 -48902670.76065 +3500 3484 -37999764.78392 +3501 3484 75026336.75001 +3502 3484 11295368.10194 +3503 3484 23873156.16496 +3579 3484 12504389.4645 +3580 3484 1493260.574915 +3581 3484 -7843093.74256 +3591 3484 -15629389.46552 +3592 3484 -63122936.0184 +3593 3484 -46615995.93793 +3594 3484 15625000.00513 +3595 3484 40736294.19042 +3596 3484 -4504985.17355 +3606 3484 -15625000.00513 +3607 3484 -22091252.52743 +3608 3484 -11857670.76516 +3609 3484 -15631584.19572 +3610 3484 -57629159.23151 +3611 3484 -24484028.50059 +3612 3484 18756584.19674 +3613 3484 -28030795.60664 +3614 3484 24112532.59506 +3485 3485 708219203.5496 +3495 3485 24401754.41739 +3496 3485 12206469.73079 +3497 3485 -20394833.53905 +3498 3485 -26294646.66457 +3499 3485 -30590657.17329 +3500 3485 7845748.044902 +3501 3485 -31898977.75945 +3502 3485 15915437.44331 +3503 3485 30120981.60519 +3579 3485 9803845.344592 +3580 3485 -11764640.61384 +3581 3485 3982028.199772 +3591 3485 -11968229.26313 +3592 3485 -48262567.85004 +3593 3485 -28540237.05556 +3594 3485 -7512792.611826 +3595 3485 -28418903.81719 +3596 3485 -109296917.9411 +3606 3485 -12536345.25295 +3607 3485 -11857670.76516 +3608 3485 -15333780.81983 +3609 3485 -81133941.74793 +3610 3485 -22561100.97091 +3611 3485 -119114540.4154 +3612 3485 -30141114.55043 +3613 3485 16075021.73004 +3614 3485 -74748788.28438 +3486 3486 1082651565.536 +3487 3486 1.692771911621e-05 +3488 3486 9143603.512253 +3489 3486 130318343.5391 +3490 3486 -8.195638656616e-06 +3491 3486 2285900.879194 +3504 3486 -229462147.1059 +3505 3486 3.129243850708e-06 +3506 3486 -4571801.756165 +3507 3486 -93117579.12609 +3508 3486 62499999.98975 +3509 3486 -26687655.2966 +3582 3486 -98285243.92273 +3583 3486 1.072883605957e-06 +3584 3486 73747066.90912 +3585 3486 -40551938.13439 +3586 3486 -15625000.00514 +3587 3486 24822942.95376 +3597 3486 99158852.54101 +3598 3486 3.457069396973e-06 +3599 3486 2285900.879224 +3600 3486 -39821273.75826 +3601 3486 -8.895993232727e-06 +3602 3486 571475.2200941 +3615 3486 -102220422.2785 +3616 3486 1.013278961182e-06 +3617 3486 -76032967.78832 +3618 3486 -41874328.64406 +3619 3486 15625000.00513 +3620 3486 -25394418.17384 +3487 3487 932645213.4434 +3488 3487 -109721202.2342 +3489 3487 -8.702278137207e-06 +3490 3487 -107181385.3168 +3491 3487 54860601.11709 +3504 3487 3.904104232788e-06 +3505 3487 45539169.75475 +3506 3487 -27430300.57206 +3507 3487 62499999.98975 +3508 3487 -74366785.10525 +3509 3487 14949525.28589 +3582 3487 -4.172325134277e-07 +3583 3487 -29534914.67368 +3584 3487 -6857575.146393 +3585 3487 -15625000.00514 +3586 3487 -35864239.62686 +3587 3487 18029482.02244 +3597 3487 3.814697265625e-06 +3598 3487 61657264.49931 +3599 3487 -27430300.57206 +3600 3487 -7.718801498413e-06 +3601 3487 -99196206.00148 +3602 3487 73626608.60945 +3615 3487 -7.748603820801e-07 +3616 3487 -33470093.0295 +3617 3487 -6857575.146393 +3618 3487 15625000.00513 +3619 3487 -37186630.13654 +3620 3487 18715245.91155 +3488 3488 1092614674.45 +3489 3488 2285900.879194 +3490 3488 54860601.11708 +3491 3488 98899681.61908 +3504 3488 -4571801.756165 +3505 3488 -27430300.57206 +3506 3488 85330883.72684 +3507 3488 -27030537.24082 +3508 3488 15223830.84127 +3509 3488 -24006523.35327 +3582 3488 73404184.96491 +3583 3488 -6857575.146392 +3584 3488 -87786498.03904 +3585 3488 24822942.95376 +3586 3488 18029482.02244 +3587 3488 -52061746.4183 +3597 3488 2285900.879224 +3598 3488 -27430300.57206 +3599 3488 -184190435.19 +3600 3488 571475.2200943 +3601 3488 73352303.05408 +3602 3488 -168344038.6739 +3615 3488 -75690085.8441 +3616 3488 -6857575.146393 +3617 3488 -98280306.98791 +3618 3488 -25394418.17384 +3619 3488 18715245.91155 +3620 3488 -55588121.11081 +3489 3489 1082651565.536 +3490 3489 1.692771911621e-05 +3491 3489 9143603.512253 +3492 3489 130318343.5391 +3493 3489 -8.195638656616e-06 +3494 3489 2285900.879194 +3504 3489 -91763195.44578 +3505 3489 -62499999.98975 +3506 3489 24744636.36161 +3507 3489 -229462147.1059 +3508 3489 3.129243850708e-06 +3509 3489 -4571801.756165 +3510 3489 -93117579.12609 +3511 3489 62499999.98975 +3512 3489 -26687655.2966 +3582 3489 -26133752.36576 +3583 3489 15625000.00514 +3584 3489 11964870.03287 +3585 3489 -98285243.92273 +3586 3489 1.072883605957e-06 +3587 3489 73747066.90912 +3588 3489 -40551938.13439 +3589 3489 -15625000.00514 +3590 3489 24822942.95376 +3597 3489 19205852.96814 +3598 3489 4.768371582031e-06 +3599 3489 571475.220082 +3600 3489 99158852.54101 +3601 3489 3.457069396973e-06 +3602 3489 2285900.879224 +3603 3489 -39821273.75826 +3604 3489 -8.895993232727e-06 +3605 3489 571475.2200941 +3615 3489 -26778951.03495 +3616 3489 -15625000.00513 +3617 3489 -12536345.25295 +3618 3489 -102220422.2785 +3619 3489 1.013278961182e-06 +3620 3489 -76032967.78832 +3621 3489 -41874328.64406 +3622 3489 15625000.00513 +3623 3489 -25394418.17384 +3490 3490 932645213.4434 +3491 3490 -109721202.2342 +3492 3490 -8.702278137207e-06 +3493 3490 -107181385.3168 +3494 3490 54860601.11709 +3504 3490 -62499999.98975 +3505 3490 -73012401.42493 +3506 3490 12480775.28616 +3507 3490 3.904104232788e-06 +3508 3490 45539169.75475 +3509 3490 -27430300.57206 +3510 3490 62499999.98975 +3511 3490 -74366785.10525 +3512 3490 14949525.28589 +3582 3490 15625000.00514 +3583 3490 -21446053.85824 +3584 3490 -11171906.87604 +3585 3490 -4.172325134277e-07 +3586 3490 -29534914.67368 +3587 3490 -6857575.146393 +3588 3490 -15625000.00514 +3589 3490 -35864239.62686 +3590 3490 18029482.02244 +3597 3490 6.780028343201e-06 +3598 3490 -40169079.27509 +3599 3490 -46196308.03739 +3600 3490 3.814697265625e-06 +3601 3490 61657264.49931 +3602 3490 -27430300.57206 +3603 3490 -7.718801498413e-06 +3604 3490 -99196206.00148 +3605 3490 73626608.60945 +3615 3490 -15625000.00513 +3616 3490 -22091252.52743 +3617 3490 -11857670.76516 +3618 3490 -7.748603820801e-07 +3619 3490 -33470093.0295 +3620 3490 -6857575.146393 +3621 3490 15625000.00513 +3622 3490 -37186630.13654 +3623 3490 18715245.91155 +3491 3491 1092614674.45 +3492 3491 2285900.879194 +3493 3491 54860601.11708 +3494 3491 98899681.61908 +3504 3491 24401754.41739 +3505 3491 12206469.73079 +3506 3491 -20394833.53905 +3507 3491 -4571801.756165 +3508 3491 -27430300.57206 +3509 3491 85330883.72684 +3510 3491 -27030537.24082 +3511 3491 15223830.84127 +3512 3491 -24006523.35327 +3582 3491 11964870.03287 +3583 3491 -11171906.87604 +3584 3491 -13613251.03531 +3585 3491 73404184.96491 +3586 3491 -6857575.146392 +3587 3491 -87786498.03904 +3588 3491 24822942.95376 +3589 3491 18029482.02244 +3590 3491 -52061746.4183 +3597 3491 571475.2200821 +3598 3491 -45922002.48202 +3599 3491 -10938367.40355 +3600 3491 2285900.879224 +3601 3491 -27430300.57206 +3602 3491 -184190435.19 +3603 3491 571475.2200943 +3604 3491 73352303.05408 +3605 3491 -168344038.6739 +3615 3491 -12536345.25295 +3616 3491 -11857670.76516 +3617 3491 -15333780.81983 +3618 3491 -75690085.8441 +3619 3491 -6857575.146393 +3620 3491 -98280306.98791 +3621 3491 -25394418.17384 +3622 3491 18715245.91155 +3623 3491 -55588121.11081 +3492 3492 1082651565.536 +3493 3492 1.692771911621e-05 +3494 3492 9143603.512253 +3495 3492 130318343.5391 +3496 3492 -8.195638656616e-06 +3497 3492 2285900.879194 +3507 3492 -91763195.44578 +3508 3492 -62499999.98975 +3509 3492 24744636.36161 +3510 3492 -229462147.1059 +3511 3492 3.129243850708e-06 +3512 3492 -4571801.756165 +3513 3492 -93117579.12609 +3514 3492 62499999.98975 +3515 3492 -26687655.2966 +3585 3492 -26133752.36576 +3586 3492 15625000.00514 +3587 3492 11964870.03287 +3588 3492 -98285243.92273 +3589 3492 1.072883605957e-06 +3590 3492 73747066.90912 +3591 3492 -40551938.13439 +3592 3492 -15625000.00514 +3593 3492 24822942.95376 +3600 3492 19205852.96814 +3601 3492 4.768371582031e-06 +3602 3492 571475.220082 +3603 3492 99158852.54101 +3604 3492 3.457069396973e-06 +3605 3492 2285900.879224 +3606 3492 -39821273.75826 +3607 3492 -8.895993232727e-06 +3608 3492 571475.2200941 +3618 3492 -26778951.03495 +3619 3492 -15625000.00513 +3620 3492 -12536345.25295 +3621 3492 -102220422.2785 +3622 3492 1.013278961182e-06 +3623 3492 -76032967.78832 +3624 3492 -41874328.64406 +3625 3492 15625000.00513 +3626 3492 -25394418.17384 +3493 3493 932645213.4434 +3494 3493 -109721202.2342 +3495 3493 -8.702278137207e-06 +3496 3493 -107181385.3168 +3497 3493 54860601.11709 +3507 3493 -62499999.98975 +3508 3493 -73012401.42493 +3509 3493 12480775.28616 +3510 3493 3.904104232788e-06 +3511 3493 45539169.75475 +3512 3493 -27430300.57206 +3513 3493 62499999.98975 +3514 3493 -74366785.10525 +3515 3493 14949525.28589 +3585 3493 15625000.00514 +3586 3493 -21446053.85824 +3587 3493 -11171906.87604 +3588 3493 -4.172325134277e-07 +3589 3493 -29534914.67368 +3590 3493 -6857575.146393 +3591 3493 -15625000.00514 +3592 3493 -35864239.62686 +3593 3493 18029482.02244 +3600 3493 6.780028343201e-06 +3601 3493 -40169079.27509 +3602 3493 -46196308.03739 +3603 3493 3.814697265625e-06 +3604 3493 61657264.49931 +3605 3493 -27430300.57206 +3606 3493 -7.718801498413e-06 +3607 3493 -99196206.00148 +3608 3493 73626608.60945 +3618 3493 -15625000.00513 +3619 3493 -22091252.52743 +3620 3493 -11857670.76516 +3621 3493 -7.748603820801e-07 +3622 3493 -33470093.0295 +3623 3493 -6857575.146393 +3624 3493 15625000.00513 +3625 3493 -37186630.13654 +3626 3493 18715245.91155 +3494 3494 1092614674.45 +3495 3494 2285900.879194 +3496 3494 54860601.11708 +3497 3494 98899681.61908 +3507 3494 24401754.41739 +3508 3494 12206469.73079 +3509 3494 -20394833.53905 +3510 3494 -4571801.756165 +3511 3494 -27430300.57206 +3512 3494 85330883.72684 +3513 3494 -27030537.24082 +3514 3494 15223830.84127 +3515 3494 -24006523.35327 +3585 3494 11964870.03287 +3586 3494 -11171906.87604 +3587 3494 -13613251.03531 +3588 3494 73404184.96491 +3589 3494 -6857575.146392 +3590 3494 -87786498.03904 +3591 3494 24822942.95376 +3592 3494 18029482.02244 +3593 3494 -52061746.4183 +3600 3494 571475.2200821 +3601 3494 -45922002.48202 +3602 3494 -10938367.40355 +3603 3494 2285900.879224 +3604 3494 -27430300.57206 +3605 3494 -184190435.19 +3606 3494 571475.2200943 +3607 3494 73352303.05408 +3608 3494 -168344038.6739 +3618 3494 -12536345.25295 +3619 3494 -11857670.76516 +3620 3494 -15333780.81983 +3621 3494 -75690085.8441 +3622 3494 -6857575.146393 +3623 3494 -98280306.98791 +3624 3494 -25394418.17384 +3625 3494 18715245.91155 +3626 3494 -55588121.11081 +3495 3495 1082651565.536 +3496 3495 1.692771911621e-05 +3497 3495 9143603.512253 +3498 3495 130318343.5391 +3499 3495 -8.195638656616e-06 +3500 3495 2285900.879194 +3510 3495 -91763195.44578 +3511 3495 -62499999.98975 +3512 3495 24744636.36161 +3513 3495 -229462147.1059 +3514 3495 3.129243850708e-06 +3515 3495 -4571801.756165 +3516 3495 -93117579.12609 +3517 3495 62499999.98975 +3518 3495 -26687655.2966 +3588 3495 -26133752.36576 +3589 3495 15625000.00514 +3590 3495 11964870.03287 +3591 3495 -98285243.92273 +3592 3495 1.072883605957e-06 +3593 3495 73747066.90912 +3594 3495 -40551938.13439 +3595 3495 -15625000.00514 +3596 3495 24822942.95376 +3603 3495 19205852.96814 +3604 3495 4.768371582031e-06 +3605 3495 571475.220082 +3606 3495 99158852.54101 +3607 3495 3.457069396973e-06 +3608 3495 2285900.879224 +3609 3495 -39821273.75826 +3610 3495 -8.895993232727e-06 +3611 3495 571475.2200941 +3621 3495 -26778951.03495 +3622 3495 -15625000.00513 +3623 3495 -12536345.25295 +3624 3495 -102220422.2785 +3625 3495 1.013278961182e-06 +3626 3495 -76032967.78832 +3627 3495 -41874328.64406 +3628 3495 15625000.00513 +3629 3495 -25394418.17384 +3496 3496 932645213.4434 +3497 3496 -109721202.2342 +3498 3496 -8.702278137207e-06 +3499 3496 -107181385.3168 +3500 3496 54860601.11709 +3510 3496 -62499999.98975 +3511 3496 -73012401.42493 +3512 3496 12480775.28616 +3513 3496 3.904104232788e-06 +3514 3496 45539169.75475 +3515 3496 -27430300.57206 +3516 3496 62499999.98975 +3517 3496 -74366785.10525 +3518 3496 14949525.28589 +3588 3496 15625000.00514 +3589 3496 -21446053.85824 +3590 3496 -11171906.87604 +3591 3496 -4.172325134277e-07 +3592 3496 -29534914.67368 +3593 3496 -6857575.146393 +3594 3496 -15625000.00514 +3595 3496 -35864239.62686 +3596 3496 18029482.02244 +3603 3496 6.780028343201e-06 +3604 3496 -40169079.27509 +3605 3496 -46196308.03739 +3606 3496 3.814697265625e-06 +3607 3496 61657264.49931 +3608 3496 -27430300.57206 +3609 3496 -7.718801498413e-06 +3610 3496 -99196206.00148 +3611 3496 73626608.60945 +3621 3496 -15625000.00513 +3622 3496 -22091252.52743 +3623 3496 -11857670.76516 +3624 3496 -7.748603820801e-07 +3625 3496 -33470093.0295 +3626 3496 -6857575.146393 +3627 3496 15625000.00513 +3628 3496 -37186630.13654 +3629 3496 18715245.91155 +3497 3497 1092614674.45 +3498 3497 2285900.879194 +3499 3497 54860601.11708 +3500 3497 98899681.61908 +3510 3497 24401754.41739 +3511 3497 12206469.73079 +3512 3497 -20394833.53905 +3513 3497 -4571801.756165 +3514 3497 -27430300.57206 +3515 3497 85330883.72684 +3516 3497 -27030537.24082 +3517 3497 15223830.84127 +3518 3497 -24006523.35327 +3588 3497 11964870.03287 +3589 3497 -11171906.87604 +3590 3497 -13613251.03531 +3591 3497 73404184.96491 +3592 3497 -6857575.146392 +3593 3497 -87786498.03904 +3594 3497 24822942.95376 +3595 3497 18029482.02244 +3596 3497 -52061746.4183 +3603 3497 571475.2200821 +3604 3497 -45922002.48202 +3605 3497 -10938367.40355 +3606 3497 2285900.879224 +3607 3497 -27430300.57206 +3608 3497 -184190435.19 +3609 3497 571475.2200943 +3610 3497 73352303.05408 +3611 3497 -168344038.6739 +3621 3497 -12536345.25295 +3622 3497 -11857670.76516 +3623 3497 -15333780.81983 +3624 3497 -75690085.8441 +3625 3497 -6857575.146393 +3626 3497 -98280306.98791 +3627 3497 -25394418.17384 +3628 3497 18715245.91155 +3629 3497 -55588121.11081 +3498 3498 1165690130.316 +3499 3498 62543894.59362 +3500 3498 30858903.05731 +3501 3498 26211628.98162 +3502 3498 -62517557.8313 +3503 3498 26694959.91784 +3513 3498 -91763195.44578 +3514 3498 -62499999.98975 +3515 3498 24744636.36161 +3516 3498 -229462147.1059 +3517 3498 3.129243850708e-06 +3518 3498 -4571801.756165 +3519 3498 -93117579.12609 +3520 3498 62499999.98975 +3521 3498 -26687655.2966 +3591 3498 -26133752.36576 +3592 3498 15625000.00514 +3593 3498 11964870.03287 +3594 3498 -115335214.0726 +3595 3498 -15631584.19572 +3596 3498 68329440.16886 +3606 3498 19205852.96814 +3607 3498 4.768371582031e-06 +3608 3498 571475.220082 +3609 3498 130473837.5578 +3610 3498 15635973.65611 +3611 3498 7712253.313144 +3612 3498 -53686446.86531 +3613 3498 -15629389.46553 +3614 3498 25401550.08976 +3624 3498 -26778951.03495 +3625 3498 -15625000.00513 +3626 3498 -12536345.25295 +3627 3498 -102220422.2785 +3628 3498 1.013278961182e-06 +3629 3498 -76032967.78832 +3630 3498 -41874328.64406 +3631 3498 15625000.00513 +3632 3498 -25394418.17384 +3499 3499 996913230.7936 +3500 3499 -85034368.77329 +3501 3499 -62526336.75207 +3502 3499 -192572421.21 +3503 3499 45540401.39811 +3513 3499 -62499999.98975 +3514 3499 -73012401.42493 +3515 3499 12480775.28616 +3516 3499 3.904104232788e-06 +3517 3499 45539169.75475 +3518 3499 -27430300.57206 +3519 3499 62499999.98975 +3520 3499 -74366785.10525 +3521 3499 14949525.28589 +3591 3499 15625000.00514 +3592 3499 -21446053.85824 +3593 3499 -11171906.87604 +3594 3499 -15629389.46552 +3595 3499 -41883469.12474 +3596 3499 7334445.059211 +3606 3499 6.780028343201e-06 +3607 3499 -40169079.27509 +3608 3499 -46196308.03739 +3609 3499 15635973.65611 +3610 3499 88279612.65644 +3611 3499 -21260570.15053 +3612 3499 -15631584.19572 +3613 3499 -108382459.4402 +3614 3499 71307025.97358 +3624 3499 -15625000.00513 +3625 3499 -22091252.52743 +3626 3499 -11857670.76516 +3627 3499 -7.748603820801e-07 +3628 3499 -33470093.0295 +3629 3499 -6857575.146393 +3630 3499 15625000.00513 +3631 3499 -37186630.13654 +3632 3499 18715245.91155 +3500 3500 1089507525.384 +3501 3500 27041494.17268 +3502 3500 53223718.26906 +3503 3500 45623912.47205 +3513 3500 24401754.41739 +3514 3500 12206469.73079 +3515 3500 -20394833.53905 +3516 3500 -4571801.756165 +3517 3500 -27430300.57206 +3518 3500 85330883.72684 +3519 3500 -27030537.24082 +3520 3500 15223830.84127 +3521 3500 -24006523.35327 +3591 3500 11964870.03287 +3592 3500 -11171906.87604 +3593 3500 -13613251.03531 +3594 3500 67985675.23876 +3595 3500 5415714.150796 +3596 3500 -77126033.46393 +3606 3500 571475.2200821 +3607 3500 -45922002.48202 +3608 3500 -10938367.40355 +3609 3500 7717499.145858 +3610 3500 -21256373.52338 +3611 3500 -156819638.9591 +3612 3500 25405116.04772 +3613 3500 72953597.68388 +3614 3500 -149232299.5136 +3624 3500 -12536345.25295 +3625 3500 -11857670.76516 +3626 3500 -15333780.81983 +3627 3500 -75690085.8441 +3628 3500 -6857575.146393 +3629 3500 -98280306.98791 +3630 3500 -25394418.17384 +3631 3500 18715245.91155 +3632 3500 -55588121.11081 +3501 3501 653068470.5481 +3502 3501 51182522.29112 +3503 3501 -14075591.44842 +3516 3501 -91763195.44578 +3517 3501 -62499999.98975 +3518 3501 24744636.36161 +3519 3501 -315959922.3283 +3520 3501 -51219443.04345 +3521 3501 -1009127.195598 +3522 3501 14126098.18154 +3523 3501 50036920.74413 +3524 3501 -2746063.173858 +3594 3501 1493260.574915 +3595 3501 18756584.19674 +3596 3501 14705768.01689 +3609 3501 -8426923.443562 +3610 3501 -15631584.19572 +3611 3501 -11969908.87826 +3612 3501 57174585.59698 +3613 3501 13544133.69379 +3614 3501 11668680.97911 +3627 3501 -26778951.03495 +3628 3501 -15625000.00513 +3629 3501 -12536345.25295 +3630 3501 -120250044.4998 +3631 3501 -13552736.157 +3632 3501 -74187983.11656 +3633 3501 -14447038.24357 +3634 3501 12508602.46732 +3635 3501 -15288233.60612 +3502 3502 574312661.4285 +3503 3502 -68239667.19298 +3516 3502 -62499999.98975 +3517 3502 -73012401.42493 +3518 3502 12480775.28616 +3519 3502 -51237903.41962 +3520 3502 -27189411.59528 +3521 3502 -18317053.54182 +3522 3502 75055381.1162 +3523 3502 4144652.738794 +3524 3502 4938030.416524 +3594 3502 12504389.4645 +3595 3502 1493260.574915 +3596 3502 -7843093.74256 +3609 3502 -15629389.46552 +3610 3502 -63122936.0184 +3611 3502 -46615995.93793 +3612 3502 13544133.69379 +3613 3502 36444414.94717 +3614 3502 -4791843.499179 +3627 3502 -15625000.00513 +3628 3502 -22091252.52743 +3629 3502 -11857670.76516 +3630 3502 -13557037.38861 +3631 3502 -47722549.95791 +3632 3502 -18100147.64644 +3633 3502 18762903.70099 +3634 3502 -16236048.06839 +3635 3502 20781353.42089 +3503 3503 670482888.5982 +3516 3503 24401754.41739 +3517 3503 12206469.73079 +3518 3503 -20394833.53905 +3519 3503 -8551486.517594 +3520 3503 -17218969.19268 +3521 3503 18458538.37432 +3522 3503 -4119094.760787 +3523 3503 3840470.11218 +3524 3503 47651040.59353 +3594 3503 9803845.344592 +3595 3503 -11764640.61384 +3596 3503 3982028.199772 +3609 3503 -11968229.26313 +3610 3503 -48262567.85004 +3611 3503 -28540237.05556 +3612 3503 -17876801.63845 +3613 3503 -27875325.58272 +3614 3503 -118608665.1674 +3627 3503 -12536345.25295 +3628 3503 -11857670.76516 +3629 3503 -15333780.81983 +3630 3503 -75902151.56773 +3631 3503 -17547038.78856 +3632 3503 -101389882.4658 +3633 3503 -22932350.40918 +3634 3503 14666146.34475 +3635 3503 -36736425.49136 +3504 3504 1082651565.536 +3505 3504 1.692771911621e-05 +3506 3504 9143603.512253 +3507 3504 130318343.5391 +3508 3504 -8.195638656616e-06 +3509 3504 2285900.879194 +3525 3504 -229462147.1059 +3526 3504 3.129243850708e-06 +3527 3504 -4571801.756165 +3528 3504 -93117579.12609 +3529 3504 62499999.98975 +3530 3504 -26687655.2966 +3597 3504 -98285243.92273 +3598 3504 1.072883605957e-06 +3599 3504 73747066.90912 +3600 3504 -40551938.13439 +3601 3504 -15625000.00514 +3602 3504 24822942.95376 +3615 3504 99158852.54101 +3616 3504 3.457069396973e-06 +3617 3504 2285900.879224 +3618 3504 -39821273.75826 +3619 3504 -8.895993232727e-06 +3620 3504 571475.2200941 +3636 3504 -102220422.2785 +3637 3504 1.013278961182e-06 +3638 3504 -76032967.78832 +3639 3504 -41874328.64406 +3640 3504 15625000.00513 +3641 3504 -25394418.17384 +3505 3505 932645213.4434 +3506 3505 -109721202.2342 +3507 3505 -8.702278137207e-06 +3508 3505 -107181385.3168 +3509 3505 54860601.11709 +3525 3505 3.904104232788e-06 +3526 3505 45539169.75475 +3527 3505 -27430300.57206 +3528 3505 62499999.98975 +3529 3505 -74366785.10525 +3530 3505 14949525.28589 +3597 3505 -4.172325134277e-07 +3598 3505 -29534914.67368 +3599 3505 -6857575.146393 +3600 3505 -15625000.00514 +3601 3505 -35864239.62686 +3602 3505 18029482.02244 +3615 3505 3.814697265625e-06 +3616 3505 61657264.49931 +3617 3505 -27430300.57206 +3618 3505 -7.718801498413e-06 +3619 3505 -99196206.00148 +3620 3505 73626608.60945 +3636 3505 -7.748603820801e-07 +3637 3505 -33470093.0295 +3638 3505 -6857575.146393 +3639 3505 15625000.00513 +3640 3505 -37186630.13654 +3641 3505 18715245.91155 +3506 3506 1092614674.45 +3507 3506 2285900.879194 +3508 3506 54860601.11708 +3509 3506 98899681.61908 +3525 3506 -4571801.756165 +3526 3506 -27430300.57206 +3527 3506 85330883.72684 +3528 3506 -27030537.24082 +3529 3506 15223830.84127 +3530 3506 -24006523.35327 +3597 3506 73404184.96491 +3598 3506 -6857575.146392 +3599 3506 -87786498.03904 +3600 3506 24822942.95376 +3601 3506 18029482.02244 +3602 3506 -52061746.4183 +3615 3506 2285900.879224 +3616 3506 -27430300.57206 +3617 3506 -184190435.19 +3618 3506 571475.2200943 +3619 3506 73352303.05408 +3620 3506 -168344038.6739 +3636 3506 -75690085.8441 +3637 3506 -6857575.146393 +3638 3506 -98280306.98791 +3639 3506 -25394418.17384 +3640 3506 18715245.91155 +3641 3506 -55588121.11081 +3507 3507 1082651565.536 +3508 3507 1.692771911621e-05 +3509 3507 9143603.512253 +3510 3507 130318343.5391 +3511 3507 -8.195638656616e-06 +3512 3507 2285900.879194 +3525 3507 -91763195.44578 +3526 3507 -62499999.98975 +3527 3507 24744636.36161 +3528 3507 -229462147.1059 +3529 3507 3.129243850708e-06 +3530 3507 -4571801.756165 +3531 3507 -93117579.12609 +3532 3507 62499999.98975 +3533 3507 -26687655.2966 +3597 3507 -26133752.36576 +3598 3507 15625000.00514 +3599 3507 11964870.03287 +3600 3507 -98285243.92273 +3601 3507 1.072883605957e-06 +3602 3507 73747066.90912 +3603 3507 -40551938.13439 +3604 3507 -15625000.00514 +3605 3507 24822942.95376 +3615 3507 19205852.96814 +3616 3507 4.768371582031e-06 +3617 3507 571475.220082 +3618 3507 99158852.54101 +3619 3507 3.457069396973e-06 +3620 3507 2285900.879224 +3621 3507 -39821273.75826 +3622 3507 -8.895993232727e-06 +3623 3507 571475.2200941 +3636 3507 -26778951.03495 +3637 3507 -15625000.00513 +3638 3507 -12536345.25295 +3639 3507 -102220422.2785 +3640 3507 1.013278961182e-06 +3641 3507 -76032967.78832 +3642 3507 -41874328.64406 +3643 3507 15625000.00513 +3644 3507 -25394418.17384 +3508 3508 932645213.4434 +3509 3508 -109721202.2342 +3510 3508 -8.702278137207e-06 +3511 3508 -107181385.3168 +3512 3508 54860601.11709 +3525 3508 -62499999.98975 +3526 3508 -73012401.42493 +3527 3508 12480775.28616 +3528 3508 3.904104232788e-06 +3529 3508 45539169.75475 +3530 3508 -27430300.57206 +3531 3508 62499999.98975 +3532 3508 -74366785.10525 +3533 3508 14949525.28589 +3597 3508 15625000.00514 +3598 3508 -21446053.85824 +3599 3508 -11171906.87604 +3600 3508 -4.172325134277e-07 +3601 3508 -29534914.67368 +3602 3508 -6857575.146393 +3603 3508 -15625000.00514 +3604 3508 -35864239.62686 +3605 3508 18029482.02244 +3615 3508 6.780028343201e-06 +3616 3508 -40169079.27509 +3617 3508 -46196308.03739 +3618 3508 3.814697265625e-06 +3619 3508 61657264.49931 +3620 3508 -27430300.57206 +3621 3508 -7.718801498413e-06 +3622 3508 -99196206.00148 +3623 3508 73626608.60945 +3636 3508 -15625000.00513 +3637 3508 -22091252.52743 +3638 3508 -11857670.76516 +3639 3508 -7.748603820801e-07 +3640 3508 -33470093.0295 +3641 3508 -6857575.146393 +3642 3508 15625000.00513 +3643 3508 -37186630.13654 +3644 3508 18715245.91155 +3509 3509 1092614674.45 +3510 3509 2285900.879194 +3511 3509 54860601.11708 +3512 3509 98899681.61908 +3525 3509 24401754.41739 +3526 3509 12206469.73079 +3527 3509 -20394833.53905 +3528 3509 -4571801.756165 +3529 3509 -27430300.57206 +3530 3509 85330883.72684 +3531 3509 -27030537.24082 +3532 3509 15223830.84127 +3533 3509 -24006523.35327 +3597 3509 11964870.03287 +3598 3509 -11171906.87604 +3599 3509 -13613251.03531 +3600 3509 73404184.96491 +3601 3509 -6857575.146392 +3602 3509 -87786498.03904 +3603 3509 24822942.95376 +3604 3509 18029482.02244 +3605 3509 -52061746.4183 +3615 3509 571475.2200821 +3616 3509 -45922002.48202 +3617 3509 -10938367.40355 +3618 3509 2285900.879224 +3619 3509 -27430300.57206 +3620 3509 -184190435.19 +3621 3509 571475.2200943 +3622 3509 73352303.05408 +3623 3509 -168344038.6739 +3636 3509 -12536345.25295 +3637 3509 -11857670.76516 +3638 3509 -15333780.81983 +3639 3509 -75690085.8441 +3640 3509 -6857575.146393 +3641 3509 -98280306.98791 +3642 3509 -25394418.17384 +3643 3509 18715245.91155 +3644 3509 -55588121.11081 +3510 3510 1082651565.536 +3511 3510 1.692771911621e-05 +3512 3510 9143603.512253 +3513 3510 130318343.5391 +3514 3510 -8.195638656616e-06 +3515 3510 2285900.879194 +3528 3510 -91763195.44578 +3529 3510 -62499999.98975 +3530 3510 24744636.36161 +3531 3510 -229462147.1059 +3532 3510 3.129243850708e-06 +3533 3510 -4571801.756165 +3534 3510 -93117579.12609 +3535 3510 62499999.98975 +3536 3510 -26687655.2966 +3600 3510 -26133752.36576 +3601 3510 15625000.00514 +3602 3510 11964870.03287 +3603 3510 -98285243.92273 +3604 3510 1.072883605957e-06 +3605 3510 73747066.90912 +3606 3510 -40551938.13439 +3607 3510 -15625000.00514 +3608 3510 24822942.95376 +3618 3510 19205852.96814 +3619 3510 4.768371582031e-06 +3620 3510 571475.220082 +3621 3510 99158852.54101 +3622 3510 3.457069396973e-06 +3623 3510 2285900.879224 +3624 3510 -39821273.75826 +3625 3510 -8.895993232727e-06 +3626 3510 571475.2200941 +3639 3510 -26778951.03495 +3640 3510 -15625000.00513 +3641 3510 -12536345.25295 +3642 3510 -102220422.2785 +3643 3510 1.013278961182e-06 +3644 3510 -76032967.78832 +3645 3510 -41874328.64406 +3646 3510 15625000.00513 +3647 3510 -25394418.17384 +3511 3511 932645213.4434 +3512 3511 -109721202.2342 +3513 3511 -8.702278137207e-06 +3514 3511 -107181385.3168 +3515 3511 54860601.11709 +3528 3511 -62499999.98975 +3529 3511 -73012401.42493 +3530 3511 12480775.28616 +3531 3511 3.904104232788e-06 +3532 3511 45539169.75475 +3533 3511 -27430300.57206 +3534 3511 62499999.98975 +3535 3511 -74366785.10525 +3536 3511 14949525.28589 +3600 3511 15625000.00514 +3601 3511 -21446053.85824 +3602 3511 -11171906.87604 +3603 3511 -4.172325134277e-07 +3604 3511 -29534914.67368 +3605 3511 -6857575.146393 +3606 3511 -15625000.00514 +3607 3511 -35864239.62686 +3608 3511 18029482.02244 +3618 3511 6.780028343201e-06 +3619 3511 -40169079.27509 +3620 3511 -46196308.03739 +3621 3511 3.814697265625e-06 +3622 3511 61657264.49931 +3623 3511 -27430300.57206 +3624 3511 -7.718801498413e-06 +3625 3511 -99196206.00148 +3626 3511 73626608.60945 +3639 3511 -15625000.00513 +3640 3511 -22091252.52743 +3641 3511 -11857670.76516 +3642 3511 -7.748603820801e-07 +3643 3511 -33470093.0295 +3644 3511 -6857575.146393 +3645 3511 15625000.00513 +3646 3511 -37186630.13654 +3647 3511 18715245.91155 +3512 3512 1092614674.45 +3513 3512 2285900.879194 +3514 3512 54860601.11708 +3515 3512 98899681.61908 +3528 3512 24401754.41739 +3529 3512 12206469.73079 +3530 3512 -20394833.53905 +3531 3512 -4571801.756165 +3532 3512 -27430300.57206 +3533 3512 85330883.72684 +3534 3512 -27030537.24082 +3535 3512 15223830.84127 +3536 3512 -24006523.35327 +3600 3512 11964870.03287 +3601 3512 -11171906.87604 +3602 3512 -13613251.03531 +3603 3512 73404184.96491 +3604 3512 -6857575.146392 +3605 3512 -87786498.03904 +3606 3512 24822942.95376 +3607 3512 18029482.02244 +3608 3512 -52061746.4183 +3618 3512 571475.2200821 +3619 3512 -45922002.48202 +3620 3512 -10938367.40355 +3621 3512 2285900.879224 +3622 3512 -27430300.57206 +3623 3512 -184190435.19 +3624 3512 571475.2200943 +3625 3512 73352303.05408 +3626 3512 -168344038.6739 +3639 3512 -12536345.25295 +3640 3512 -11857670.76516 +3641 3512 -15333780.81983 +3642 3512 -75690085.8441 +3643 3512 -6857575.146393 +3644 3512 -98280306.98791 +3645 3512 -25394418.17384 +3646 3512 18715245.91155 +3647 3512 -55588121.11081 +3513 3513 1082651565.536 +3514 3513 1.692771911621e-05 +3515 3513 9143603.512253 +3516 3513 130318343.5391 +3517 3513 -8.195638656616e-06 +3518 3513 2285900.879194 +3531 3513 -91763195.44578 +3532 3513 -62499999.98975 +3533 3513 24744636.36161 +3534 3513 -229462147.1059 +3535 3513 3.129243850708e-06 +3536 3513 -4571801.756165 +3537 3513 -93117579.12609 +3538 3513 62499999.98975 +3539 3513 -26687655.2966 +3603 3513 -26133752.36576 +3604 3513 15625000.00514 +3605 3513 11964870.03287 +3606 3513 -98285243.92273 +3607 3513 1.072883605957e-06 +3608 3513 73747066.90912 +3609 3513 -40551938.13439 +3610 3513 -15625000.00514 +3611 3513 24822942.95376 +3621 3513 19205852.96814 +3622 3513 4.768371582031e-06 +3623 3513 571475.220082 +3624 3513 99158852.54101 +3625 3513 3.457069396973e-06 +3626 3513 2285900.879224 +3627 3513 -39821273.75826 +3628 3513 -8.895993232727e-06 +3629 3513 571475.2200941 +3642 3513 -26778951.03495 +3643 3513 -15625000.00513 +3644 3513 -12536345.25295 +3645 3513 -102220422.2785 +3646 3513 1.013278961182e-06 +3647 3513 -76032967.78832 +3648 3513 -41874328.64406 +3649 3513 15625000.00513 +3650 3513 -25394418.17384 +3514 3514 932645213.4434 +3515 3514 -109721202.2342 +3516 3514 -8.702278137207e-06 +3517 3514 -107181385.3168 +3518 3514 54860601.11709 +3531 3514 -62499999.98975 +3532 3514 -73012401.42493 +3533 3514 12480775.28616 +3534 3514 3.904104232788e-06 +3535 3514 45539169.75475 +3536 3514 -27430300.57206 +3537 3514 62499999.98975 +3538 3514 -74366785.10525 +3539 3514 14949525.28589 +3603 3514 15625000.00514 +3604 3514 -21446053.85824 +3605 3514 -11171906.87604 +3606 3514 -4.172325134277e-07 +3607 3514 -29534914.67368 +3608 3514 -6857575.146393 +3609 3514 -15625000.00514 +3610 3514 -35864239.62686 +3611 3514 18029482.02244 +3621 3514 6.780028343201e-06 +3622 3514 -40169079.27509 +3623 3514 -46196308.03739 +3624 3514 3.814697265625e-06 +3625 3514 61657264.49931 +3626 3514 -27430300.57206 +3627 3514 -7.718801498413e-06 +3628 3514 -99196206.00148 +3629 3514 73626608.60945 +3642 3514 -15625000.00513 +3643 3514 -22091252.52743 +3644 3514 -11857670.76516 +3645 3514 -7.748603820801e-07 +3646 3514 -33470093.0295 +3647 3514 -6857575.146393 +3648 3514 15625000.00513 +3649 3514 -37186630.13654 +3650 3514 18715245.91155 +3515 3515 1092614674.45 +3516 3515 2285900.879194 +3517 3515 54860601.11708 +3518 3515 98899681.61908 +3531 3515 24401754.41739 +3532 3515 12206469.73079 +3533 3515 -20394833.53905 +3534 3515 -4571801.756165 +3535 3515 -27430300.57206 +3536 3515 85330883.72684 +3537 3515 -27030537.24082 +3538 3515 15223830.84127 +3539 3515 -24006523.35327 +3603 3515 11964870.03287 +3604 3515 -11171906.87604 +3605 3515 -13613251.03531 +3606 3515 73404184.96491 +3607 3515 -6857575.146392 +3608 3515 -87786498.03904 +3609 3515 24822942.95376 +3610 3515 18029482.02244 +3611 3515 -52061746.4183 +3621 3515 571475.2200821 +3622 3515 -45922002.48202 +3623 3515 -10938367.40355 +3624 3515 2285900.879224 +3625 3515 -27430300.57206 +3626 3515 -184190435.19 +3627 3515 571475.2200943 +3628 3515 73352303.05408 +3629 3515 -168344038.6739 +3642 3515 -12536345.25295 +3643 3515 -11857670.76516 +3644 3515 -15333780.81983 +3645 3515 -75690085.8441 +3646 3515 -6857575.146393 +3647 3515 -98280306.98791 +3648 3515 -25394418.17384 +3649 3515 18715245.91155 +3650 3515 -55588121.11081 +3516 3516 1082651565.536 +3517 3516 1.692771911621e-05 +3518 3516 9143603.512253 +3519 3516 130318343.5391 +3520 3516 -8.195638656616e-06 +3521 3516 2285900.879194 +3534 3516 -91763195.44578 +3535 3516 -62499999.98975 +3536 3516 24744636.36161 +3537 3516 -229462147.1059 +3538 3516 3.129243850708e-06 +3539 3516 -4571801.756165 +3540 3516 -93117579.12609 +3541 3516 62499999.98975 +3542 3516 -26687655.2966 +3606 3516 -26133752.36576 +3607 3516 15625000.00514 +3608 3516 11964870.03287 +3609 3516 -98285243.92273 +3610 3516 1.072883605957e-06 +3611 3516 73747066.90912 +3612 3516 -40551938.13439 +3613 3516 -15625000.00514 +3614 3516 24822942.95376 +3624 3516 19205852.96814 +3625 3516 4.768371582031e-06 +3626 3516 571475.220082 +3627 3516 99158852.54101 +3628 3516 3.457069396973e-06 +3629 3516 2285900.879224 +3630 3516 -39821273.75826 +3631 3516 -8.895993232727e-06 +3632 3516 571475.2200941 +3645 3516 -26778951.03495 +3646 3516 -15625000.00513 +3647 3516 -12536345.25295 +3648 3516 -102220422.2785 +3649 3516 1.013278961182e-06 +3650 3516 -76032967.78832 +3651 3516 -41874328.64406 +3652 3516 15625000.00513 +3653 3516 -25394418.17384 +3517 3517 932645213.4434 +3518 3517 -109721202.2342 +3519 3517 -8.702278137207e-06 +3520 3517 -107181385.3168 +3521 3517 54860601.11709 +3534 3517 -62499999.98975 +3535 3517 -73012401.42493 +3536 3517 12480775.28616 +3537 3517 3.904104232788e-06 +3538 3517 45539169.75475 +3539 3517 -27430300.57206 +3540 3517 62499999.98975 +3541 3517 -74366785.10525 +3542 3517 14949525.28589 +3606 3517 15625000.00514 +3607 3517 -21446053.85824 +3608 3517 -11171906.87604 +3609 3517 -4.172325134277e-07 +3610 3517 -29534914.67368 +3611 3517 -6857575.146393 +3612 3517 -15625000.00514 +3613 3517 -35864239.62686 +3614 3517 18029482.02244 +3624 3517 6.780028343201e-06 +3625 3517 -40169079.27509 +3626 3517 -46196308.03739 +3627 3517 3.814697265625e-06 +3628 3517 61657264.49931 +3629 3517 -27430300.57206 +3630 3517 -7.718801498413e-06 +3631 3517 -99196206.00148 +3632 3517 73626608.60945 +3645 3517 -15625000.00513 +3646 3517 -22091252.52743 +3647 3517 -11857670.76516 +3648 3517 -7.748603820801e-07 +3649 3517 -33470093.0295 +3650 3517 -6857575.146393 +3651 3517 15625000.00513 +3652 3517 -37186630.13654 +3653 3517 18715245.91155 +3518 3518 1092614674.45 +3519 3518 2285900.879194 +3520 3518 54860601.11708 +3521 3518 98899681.61908 +3534 3518 24401754.41739 +3535 3518 12206469.73079 +3536 3518 -20394833.53905 +3537 3518 -4571801.756165 +3538 3518 -27430300.57206 +3539 3518 85330883.72684 +3540 3518 -27030537.24082 +3541 3518 15223830.84127 +3542 3518 -24006523.35327 +3606 3518 11964870.03287 +3607 3518 -11171906.87604 +3608 3518 -13613251.03531 +3609 3518 73404184.96491 +3610 3518 -6857575.146392 +3611 3518 -87786498.03904 +3612 3518 24822942.95376 +3613 3518 18029482.02244 +3614 3518 -52061746.4183 +3624 3518 571475.2200821 +3625 3518 -45922002.48202 +3626 3518 -10938367.40355 +3627 3518 2285900.879224 +3628 3518 -27430300.57206 +3629 3518 -184190435.19 +3630 3518 571475.2200943 +3631 3518 73352303.05408 +3632 3518 -168344038.6739 +3645 3518 -12536345.25295 +3646 3518 -11857670.76516 +3647 3518 -15333780.81983 +3648 3518 -75690085.8441 +3649 3518 -6857575.146393 +3650 3518 -98280306.98791 +3651 3518 -25394418.17384 +3652 3518 18715245.91155 +3653 3518 -55588121.11081 +3519 3519 1119567064.823 +3520 3519 51868578.37564 +3521 3519 9078619.584517 +3522 3519 16739573.67208 +3523 3519 -68255098.98124 +3524 3519 4440784.766338 +3537 3519 -91763195.44578 +3538 3519 -62499999.98975 +3539 3519 24744636.36161 +3540 3519 -219541507.9457 +3541 3519 5590443.380515 +3542 3519 -308077.8811086 +3543 3519 -75671590.24938 +3544 3519 62033980.64472 +3545 3519 -4658919.241186 +3609 3519 -26133752.36576 +3610 3519 15625000.00514 +3611 3519 11964870.03287 +3612 3519 -116635571.6621 +3613 3519 -13557037.38861 +3614 3519 71825261.52009 +3627 3519 19205852.96814 +3628 3519 4.768371582031e-06 +3629 3519 571475.220082 +3630 3519 119513491.7636 +3631 3519 13646802.5259 +3632 3519 2257650.049491 +3633 3519 -37663498.656 +3634 3519 -16681828.38297 +3635 3519 20639715.93369 +3648 3519 -26778951.03495 +3649 3519 -15625000.00513 +3650 3519 -12536345.25295 +3651 3519 -101736939.0315 +3652 3519 1031079.308418 +3653 3519 -75280279.48546 +3654 3519 -32862857.84378 +3655 3519 15560983.93726 +3656 3519 -19412034.49389 +3520 3520 981611138.411 +3521 3520 -64673518.78673 +3522 3520 -68273559.3574 +3523 3520 -202871285.6405 +3524 3520 9454749.061244 +3537 3520 -62499999.98975 +3538 3520 -73012401.42493 +3539 3520 12480775.28616 +3540 3520 5590443.380517 +3541 3520 49584393.39806 +3542 3520 -16791816.53285 +3543 3520 62033980.64471 +3544 3520 -76003075.78772 +3545 3520 3373418.155893 +3609 3520 15625000.00514 +3610 3520 -21446053.85824 +3611 3520 -11171906.87604 +3612 3520 -13552736.15701 +3613 3520 -44108077.12019 +3614 3520 9302354.58656 +3627 3520 6.780028343201e-06 +3628 3520 -40169079.27509 +3629 3520 -46196308.03739 +3630 3520 13646802.52589 +3631 3520 82967131.3934 +3632 3520 -15977932.15831 +3633 3520 -16686129.61458 +3634 3520 -92498249.21409 +3635 3520 64870490.37463 +3648 3520 -15625000.00513 +3649 3520 -22091252.52743 +3650 3520 -11857670.76516 +3651 3520 1031079.308416 +3652 3520 -34052279.33202 +3653 3520 -3130435.378702 +3654 3520 15560983.93726 +3655 3520 -31694365.92876 +3656 3520 17477326.20954 +3521 3521 1053716606.38 +3522 3521 4442288.575716 +3523 3521 9455979.495823 +3524 3521 53874562.57944 +3537 3521 24401754.41739 +3538 3521 12206469.73079 +3539 3521 -20394833.53905 +3540 3521 -7851480.657647 +3541 3521 -16791816.53285 +3542 3521 84352977.65236 +3543 3521 -4658919.240511 +3544 3521 3373418.155893 +3545 3521 -10044511.20959 +3609 3521 11964870.03287 +3610 3521 -11171906.87604 +3611 3521 -13613251.03531 +3612 3521 73539429.97126 +3613 3521 9306457.422693 +3614 3521 -91751288.23183 +3627 3521 571475.2200821 +3628 3521 -45922002.48202 +3629 3521 -10938367.40355 +3630 3521 2267681.283016 +3631 3521 -14872684.79652 +3632 3521 -169875280.5724 +3633 3521 20645082.7339 +3634 3521 64870488.0431 +3635 3521 -100342559.1602 +3648 3521 -12536345.25295 +3649 3521 -11857670.76516 +3650 3521 -15333780.81983 +3651 3521 -76994689.20841 +3652 3521 -2856129.82292 +3653 3521 -102037504.2931 +3654 3521 -19412034.49389 +3655 3521 17477326.20954 +3656 3521 -37687237.45018 +3522 3522 623317858.5368 +3523 3522 3675811.7928 +3524 3522 517107.2674251 +3540 3522 -90991721.40217 +3541 3522 -62441458.17468 +3542 3522 3788785.758507 +3543 3522 -195665726.9223 +3544 3522 7452350.770389 +3545 3522 -810784.3127724 +3546 3522 72846196.4546 +3547 3522 -16117683.85556 +3548 3522 -157155.5887424 +3549 3522 -72505863.56765 +3550 3522 60649157.70826 +3551 3522 -918091.382888 +3612 3522 -9779519.734472 +3613 3522 18762903.70099 +3614 3522 20872950.87833 +3630 3522 -29384033.50768 +3631 3522 -16686129.61458 +3632 3522 -18457319.24497 +3633 3522 27287164.95526 +3634 3522 684062.1150855 +3635 3522 15553829.11912 +3651 3522 -33120558.02393 +3652 3522 -15616945.6841 +3653 3522 -18587389.84292 +3654 3522 -99717017.87952 +3655 3522 1376184.523421 +3656 3522 -77291329.02194 +3657 3522 -7501425.829938 +3658 3522 -3801118.93258 +3659 3522 5317579.933864 +3660 3522 -31714807.53314 +3661 3522 15281043.89176 +3662 3522 -19247766.26639 +3523 3523 680695003.4004 +3524 3523 -10342881.00179 +3540 3523 -62441458.17468 +3541 3523 -68421577.40789 +3542 3523 1392259.099982 +3543 3523 7452350.77039 +3544 3523 67820764.43311 +3545 3523 -3133252.076033 +3546 3523 8882316.140337 +3547 3523 -47551906.89358 +3548 3523 482784.0969671 +3549 3523 60649157.70826 +3550 3523 -65949235.67731 +3551 3523 497300.0129927 +3612 3523 12508602.46732 +3613 3523 -11568529.55929 +3614 3523 -12849308.9116 +3630 3523 -16681828.38297 +3631 3523 -84218784.06579 +3632 3523 -60205510.16422 +3633 3523 684062.1150822 +3634 3523 39801359.55164 +3635 3523 3317151.913985 +3651 3523 -15616945.6841 +3652 3523 -27729259.16604 +3653 3523 -15272198.20777 +3654 3523 1376184.523421 +3655 3523 -33227547.88426 +3656 3523 269158.2598691 +3657 3523 2448881.069472 +3658 3523 -37533389.70497 +3659 3523 33453138.41178 +3660 3523 15281043.89176 +3661 3523 -29454046.72473 +3662 3523 16789140.72124 +3524 3524 714283333.8847 +3540 3524 3788785.758844 +3541 3524 1392259.100252 +3542 3524 -11821835.32419 +3543 3524 -810784.3127718 +3544 3524 -3133252.076033 +3545 3524 100694743.5742 +3546 3524 -157155.5887394 +3547 3524 482784.096967 +3548 3524 78864901.84259 +3549 3524 -918091.3825506 +3550 3524 497300.0129927 +3551 3524 -2569640.608923 +3612 3524 13915300.58555 +3613 3524 -18415738.09842 +3614 3524 -24289709.4671 +3630 3524 -18452655.06576 +3631 3524 -60206083.47894 +3632 3524 -78263985.43137 +3633 3524 -15287906.98693 +3634 3524 -8365059.572945 +3635 3524 -166656134.6925 +3651 3524 -18587389.84292 +3652 3524 -15272198.20777 +3653 3524 -31019516.42629 +3654 3524 -77291329.02227 +3655 3524 269158.2600059 +3656 3524 -106138990.6835 +3657 3524 -2807420.068633 +3658 3524 33453138.41178 +3659 3524 -49046947.17697 +3660 3524 -19247766.26639 +3661 3524 16789140.72124 +3662 3524 -35065242.93145 +3525 3525 541325782.7681 +3526 3525 6.437301635742e-06 +3527 3525 4571801.756125 +3528 3525 65181744.83088 +3529 3525 12499999.99795 +3530 3525 -3143073.865676 +3615 3525 -98285243.92273 +3616 3525 1.072883605957e-06 +3617 3525 73747066.90912 +3618 3525 -40551938.13439 +3619 3525 -15625000.00514 +3620 3525 24822942.95376 +3636 3525 49556853.20918 +3637 3525 2.026557922363e-06 +3638 3525 -14657969.69626 +3639 3525 -19910636.87912 +3640 3525 3125000.001023 +3641 3525 -4735998.502713 +3526 3526 466322606.7217 +3527 3526 -54860601.11707 +3528 3526 -12499999.99795 +3529 3526 -53568119.59706 +3530 3526 27155995.00303 +3615 3526 -4.172325134277e-07 +3616 3526 -29534914.67368 +3617 3526 -6857575.146393 +3618 3526 -15625000.00514 +3619 3526 -35864239.62686 +3620 3526 18029482.02244 +3636 3526 2.264976501465e-06 +3637 3526 30806059.18833 +3638 3526 -13715150.28603 +3639 3526 -3125000.00103 +3640 3526 -49598103.00073 +3641 3526 36744727.91581 +3527 3527 546307337.2251 +3528 3527 7143384.465966 +3529 3527 27704606.11405 +3530 3527 49510035.63975 +3615 3527 73404184.96491 +3616 3527 -6857575.146392 +3617 3527 -87786498.03904 +3618 3527 24822942.95376 +3619 3527 18029482.02244 +3620 3527 -52061746.4183 +3636 3527 15229460.85439 +3637 3527 -13715150.28603 +3638 3527 -92155412.4252 +3639 3527 5307473.722807 +3640 3527 36744727.91595 +3641 3527 -84172019.33696 +3528 3528 541325782.7681 +3529 3528 6.437301635742e-06 +3530 3528 4571801.756125 +3531 3528 65181744.83088 +3532 3528 12499999.99795 +3533 3528 -3143073.865676 +3615 3528 -26133752.36576 +3616 3528 15625000.00514 +3617 3528 11964870.03287 +3618 3528 -98285243.92273 +3619 3528 1.072883605957e-06 +3620 3528 73747066.90912 +3621 3528 -40551938.13439 +3622 3528 -15625000.00514 +3623 3528 24822942.95376 +3636 3528 9602926.484067 +3637 3528 -3125000.001024 +3638 3528 -2164383.918541 +3639 3528 49556853.20918 +3640 3528 2.026557922363e-06 +3641 3528 -14657969.69626 +3642 3528 -19910636.87912 +3643 3528 3125000.001023 +3644 3528 -4735998.502713 +3529 3529 466322606.7217 +3530 3529 -54860601.11707 +3531 3529 -12499999.99795 +3532 3529 -53568119.59706 +3533 3529 27155995.00303 +3615 3529 15625000.00514 +3616 3529 -21446053.85824 +3617 3529 -11171906.87604 +3618 3529 -4.172325134277e-07 +3619 3529 -29534914.67368 +3620 3529 -6857575.146393 +3621 3529 -15625000.00514 +3622 3529 -35864239.62686 +3623 3529 18029482.02244 +3636 3529 3125000.001031 +3637 3529 -20084539.63755 +3638 3529 -23029577.62979 +3639 3529 2.264976501465e-06 +3640 3529 30806059.18833 +3641 3529 -13715150.28603 +3642 3529 -3125000.00103 +3643 3529 -49598103.00073 +3644 3529 36744727.91581 +3530 3530 546307337.2251 +3531 3530 7143384.465966 +3532 3530 27704606.11405 +3533 3530 49510035.63975 +3615 3530 11964870.03287 +3616 3530 -11171906.87604 +3617 3530 -13613251.03531 +3618 3530 73404184.96491 +3619 3530 -6857575.146392 +3620 3530 -87786498.03904 +3621 3530 24822942.95376 +3622 3530 18029482.02244 +3623 3530 -52061746.4183 +3636 3530 2735859.138623 +3637 3530 -23029577.62992 +3638 3530 -5469183.701778 +3639 3530 15229460.85439 +3640 3530 -13715150.28603 +3641 3530 -92155412.4252 +3642 3530 5307473.722807 +3643 3530 36744727.91595 +3644 3530 -84172019.33696 +3531 3531 541325782.7681 +3532 3531 6.437301635742e-06 +3533 3531 4571801.756125 +3534 3531 65181744.83088 +3535 3531 12499999.99795 +3536 3531 -3143073.865676 +3618 3531 -26133752.36576 +3619 3531 15625000.00514 +3620 3531 11964870.03287 +3621 3531 -98285243.92273 +3622 3531 1.072883605957e-06 +3623 3531 73747066.90912 +3624 3531 -40551938.13439 +3625 3531 -15625000.00514 +3626 3531 24822942.95376 +3639 3531 9602926.484067 +3640 3531 -3125000.001024 +3641 3531 -2164383.918541 +3642 3531 49556853.20918 +3643 3531 2.026557922363e-06 +3644 3531 -14657969.69626 +3645 3531 -19910636.87912 +3646 3531 3125000.001023 +3647 3531 -4735998.502713 +3532 3532 466322606.7217 +3533 3532 -54860601.11707 +3534 3532 -12499999.99795 +3535 3532 -53568119.59706 +3536 3532 27155995.00303 +3618 3532 15625000.00514 +3619 3532 -21446053.85824 +3620 3532 -11171906.87604 +3621 3532 -4.172325134277e-07 +3622 3532 -29534914.67368 +3623 3532 -6857575.146393 +3624 3532 -15625000.00514 +3625 3532 -35864239.62686 +3626 3532 18029482.02244 +3639 3532 3125000.001031 +3640 3532 -20084539.63755 +3641 3532 -23029577.62979 +3642 3532 2.264976501465e-06 +3643 3532 30806059.18833 +3644 3532 -13715150.28603 +3645 3532 -3125000.00103 +3646 3532 -49598103.00073 +3647 3532 36744727.91581 +3533 3533 546307337.2251 +3534 3533 7143384.465966 +3535 3533 27704606.11405 +3536 3533 49510035.63975 +3618 3533 11964870.03287 +3619 3533 -11171906.87604 +3620 3533 -13613251.03531 +3621 3533 73404184.96491 +3622 3533 -6857575.146392 +3623 3533 -87786498.03904 +3624 3533 24822942.95376 +3625 3533 18029482.02244 +3626 3533 -52061746.4183 +3639 3533 2735859.138623 +3640 3533 -23029577.62992 +3641 3533 -5469183.701778 +3642 3533 15229460.85439 +3643 3533 -13715150.28603 +3644 3533 -92155412.4252 +3645 3533 5307473.722807 +3646 3533 36744727.91595 +3647 3533 -84172019.33696 +3534 3534 541325782.7681 +3535 3534 6.437301635742e-06 +3536 3534 4571801.756125 +3537 3534 65181744.83088 +3538 3534 12499999.99795 +3539 3534 -3143073.865676 +3621 3534 -26133752.36576 +3622 3534 15625000.00514 +3623 3534 11964870.03287 +3624 3534 -98285243.92273 +3625 3534 1.072883605957e-06 +3626 3534 73747066.90912 +3627 3534 -40551938.13439 +3628 3534 -15625000.00514 +3629 3534 24822942.95376 +3642 3534 9602926.484067 +3643 3534 -3125000.001024 +3644 3534 -2164383.918541 +3645 3534 49556853.20918 +3646 3534 2.026557922363e-06 +3647 3534 -14657969.69626 +3648 3534 -19910636.87912 +3649 3534 3125000.001023 +3650 3534 -4735998.502713 +3535 3535 466322606.7217 +3536 3535 -54860601.11707 +3537 3535 -12499999.99795 +3538 3535 -53568119.59706 +3539 3535 27155995.00303 +3621 3535 15625000.00514 +3622 3535 -21446053.85824 +3623 3535 -11171906.87604 +3624 3535 -4.172325134277e-07 +3625 3535 -29534914.67368 +3626 3535 -6857575.146393 +3627 3535 -15625000.00514 +3628 3535 -35864239.62686 +3629 3535 18029482.02244 +3642 3535 3125000.001031 +3643 3535 -20084539.63755 +3644 3535 -23029577.62979 +3645 3535 2.264976501465e-06 +3646 3535 30806059.18833 +3647 3535 -13715150.28603 +3648 3535 -3125000.00103 +3649 3535 -49598103.00073 +3650 3535 36744727.91581 +3536 3536 546307337.2251 +3537 3536 7143384.465966 +3538 3536 27704606.11405 +3539 3536 49510035.63975 +3621 3536 11964870.03287 +3622 3536 -11171906.87604 +3623 3536 -13613251.03531 +3624 3536 73404184.96491 +3625 3536 -6857575.146392 +3626 3536 -87786498.03904 +3627 3536 24822942.95376 +3628 3536 18029482.02244 +3629 3536 -52061746.4183 +3642 3536 2735859.138623 +3643 3536 -23029577.62992 +3644 3536 -5469183.701778 +3645 3536 15229460.85439 +3646 3536 -13715150.28603 +3647 3536 -92155412.4252 +3648 3536 5307473.722807 +3649 3536 36744727.91595 +3650 3536 -84172019.33696 +3537 3537 541325782.7681 +3538 3537 6.437301635742e-06 +3539 3537 4571801.756125 +3540 3537 65181744.83088 +3541 3537 12499999.99795 +3542 3537 -3143073.865676 +3624 3537 -26133752.36576 +3625 3537 15625000.00514 +3626 3537 11964870.03287 +3627 3537 -98285243.92273 +3628 3537 1.072883605957e-06 +3629 3537 73747066.90912 +3630 3537 -40551938.13439 +3631 3537 -15625000.00514 +3632 3537 24822942.95376 +3645 3537 9602926.484067 +3646 3537 -3125000.001024 +3647 3537 -2164383.918541 +3648 3537 49556853.20918 +3649 3537 2.026557922363e-06 +3650 3537 -14657969.69626 +3651 3537 -19910636.87912 +3652 3537 3125000.001023 +3653 3537 -4735998.502713 +3538 3538 466322606.7217 +3539 3538 -54860601.11707 +3540 3538 -12499999.99795 +3541 3538 -53568119.59706 +3542 3538 27155995.00303 +3624 3538 15625000.00514 +3625 3538 -21446053.85824 +3626 3538 -11171906.87604 +3627 3538 -4.172325134277e-07 +3628 3538 -29534914.67368 +3629 3538 -6857575.146393 +3630 3538 -15625000.00514 +3631 3538 -35864239.62686 +3632 3538 18029482.02244 +3645 3538 3125000.001031 +3646 3538 -20084539.63755 +3647 3538 -23029577.62979 +3648 3538 2.264976501465e-06 +3649 3538 30806059.18833 +3650 3538 -13715150.28603 +3651 3538 -3125000.00103 +3652 3538 -49598103.00073 +3653 3538 36744727.91581 +3539 3539 546307337.2251 +3540 3539 7143384.465966 +3541 3539 27704606.11405 +3542 3539 49510035.63975 +3624 3539 11964870.03287 +3625 3539 -11171906.87604 +3626 3539 -13613251.03531 +3627 3539 73404184.96491 +3628 3539 -6857575.146392 +3629 3539 -87786498.03904 +3630 3539 24822942.95376 +3631 3539 18029482.02244 +3632 3539 -52061746.4183 +3645 3539 2735859.138623 +3646 3539 -23029577.62992 +3647 3539 -5469183.701778 +3648 3539 15229460.85439 +3649 3539 -13715150.28603 +3650 3539 -92155412.4252 +3651 3539 5307473.722807 +3652 3539 36744727.91595 +3653 3539 -84172019.33696 +3540 3540 535568240.4202 +3541 3540 58128.69620621 +3542 3540 23218753.21209 +3543 3540 66687073.10683 +3544 3540 6792886.106159 +3545 3540 45330.57174599 +3627 3540 -26133752.36576 +3628 3540 15625000.00514 +3629 3540 11964870.03287 +3630 3540 -98078021.4205 +3631 3540 1031079.308427 +3632 3540 73275536.4611 +3633 3540 -35178433.35253 +3634 3540 -15616945.6841 +3635 3540 20484919.19769 +3648 3540 9602926.484067 +3649 3540 -3125000.001024 +3650 3540 -2164383.918541 +3651 3540 44756559.78498 +3652 3540 7943.295568347 +3653 3540 -9908664.635919 +3654 3540 -9289690.704191 +3655 3540 2077923.076005 +3656 3540 -2620124.358963 +3541 3541 464393931.4614 +3542 3541 -34267393.04202 +3543 3541 -18207113.88974 +3544 3541 -53835592.86528 +3545 3541 5092680.185999 +3627 3541 15625000.00514 +3628 3541 -21446053.85824 +3629 3541 -11171906.87604 +3630 3541 1031079.308425 +3631 3541 -30393361.72101 +3632 3541 -5205088.156207 +3633 3541 -15616945.6841 +3634 3541 -29787134.49463 +3635 3541 15986482.35805 +3648 3541 3125000.001031 +3649 3541 -20084539.63755 +3650 3541 -23029577.62979 +3651 3541 7943.295568764 +3652 3541 26711708.06824 +3653 3541 -8489193.347654 +3654 3541 -4172076.926047 +3655 3541 -39321029.93073 +3656 3541 33555116.98496 +3542 3542 537488440.5739 +3543 3542 2102622.238072 +3544 3542 5092680.185999 +3545 3542 67906904.50199 +3627 3542 11964870.03287 +3628 3542 -11171906.87604 +3629 3542 -13613251.03531 +3630 3542 74989946.18456 +3631 3542 -4930782.600289 +3632 3542 -92280390.6637 +3633 3542 20484919.19769 +3634 3542 15986482.35805 +3635 3542 -36507183.96923 +3648 3542 2735859.138623 +3649 3542 -23029577.62992 +3650 3542 -5469183.701778 +3651 3542 20663974.24795 +3652 3542 -7940582.236633 +3653 3542 -103726319.7821 +3654 3542 5708660.365653 +3655 3542 33555116.98482 +3656 3542 -53258101.71172 +3543 3543 521142175.6205 +3544 3543 4357310.012615 +3545 3543 256979.8629427 +3546 3543 -93206905.2309 +3547 3543 -64350842.27123 +3548 3543 796318.3392085 +3549 3543 62527224.36834 +3550 3543 8714314.733252 +3551 3543 -429272.4433933 +3630 3543 -29662254.52482 +3631 3543 15560983.93727 +3632 3543 17067305.79587 +3633 3543 -99122890.33304 +3634 3543 1376184.523438 +3635 3543 76917351.50796 +3651 3543 -3482602.472394 +3652 3543 -4172076.926049 +3653 3543 -4698770.191785 +3654 3543 34117046.21824 +3655 3543 778570.1040945 +3656 3543 -15334961.99471 +3657 3543 -35604260.65942 +3658 3543 -15968956.1185 +3659 3543 20509351.80222 +3660 3543 -9151163.575078 +3661 3543 2425294.479764 +3662 3543 -2620832.474664 +3544 3544 478263488.7933 +3545 3544 -7336562.232819 +3546 3544 -64350842.27123 +3547 3544 -73712126.30103 +3548 3544 497300.0129924 +3549 3544 -16285685.26264 +3550 3544 -56721207.5792 +3551 3544 1506415.954023 +3630 3544 15560983.93727 +3631 3544 -28493762.60981 +3632 3544 -15856007.13474 +3633 3544 1376184.523438 +3634 3544 -32633420.33777 +3635 3544 -1805494.517635 +3651 3544 2077923.076005 +3652 3544 -33513941.69894 +3653 3544 -31036896.89325 +3654 3544 778570.1040981 +3655 3544 21602897.83365 +3656 3544 -1794166.615711 +3657 3544 -15968956.1185 +3658 3544 -30912591.64709 +3659 3544 16789140.72124 +3660 3544 -3824705.522288 +3661 3544 -38955306.88653 +3662 3544 33703424.44008 +3545 3545 543561032.3812 +3546 3545 796318.3392083 +3547 3545 497300.0129924 +3548 3545 -10332531.23264 +3549 3545 256491.4453803 +3550 3545 1506415.954023 +3551 3545 70380363.83328 +3630 3545 17067305.79587 +3631 3545 -15856007.13474 +3632 3545 -29152295.26628 +3633 3545 76917351.50829 +3634 3545 -1805494.517364 +3635 3545 -104554650.5595 +3651 3545 2601368.699331 +3652 3545 -31036896.89352 +3653 3545 -37772533.09358 +3654 3545 15506774.11134 +3655 3545 -1794166.615711 +3656 3545 -123193199.9205 +3657 3545 20509351.80222 +3658 3545 16789140.72124 +3659 3545 -36523787.8538 +3660 3545 5157014.750283 +3661 3545 33703424.44008 +3662 3545 -49886534.23033 +3546 3546 272695692.3765 +3547 3546 66117683.84736 +3548 3546 -414314.3184705 +3549 3546 -100751205.8239 +3550 3546 -10649157.71646 +3551 3546 -224848.4319969 +3633 3546 -6952814.718665 +3634 3546 2448881.069473 +3635 3546 2724611.184208 +3654 3546 -35055649.54814 +3655 3546 -15968956.11851 +3656 3546 -20115648.21112 +3657 3546 16994370.30315 +3658 3546 16301118.93669 +3659 3546 8023536.963962 +3660 3546 -50777794.92451 +3661 3546 -2781043.887658 +3662 3546 -39382499.93705 +3547 3547 240750045.7496 +3548 3547 -482784.0969512 +3549 3547 14350842.27944 +3550 3547 32097765.22126 +3551 3547 -497300.0129839 +3633 3547 -3801118.932581 +3634 3547 -36984778.59371 +3635 3547 -33213528.24393 +3654 3547 -15968956.11851 +3655 3547 -30363980.53581 +3656 3547 -16544192.62304 +3657 3547 16301118.93669 +3658 3547 8940396.665666 +3659 3547 6546861.581638 +3660 3547 3468956.114395 +3661 3547 -17383526.42432 +3662 3547 3210859.285327 +3548 3548 283986385.1319 +3549 3548 -224848.4319939 +3550 3548 -497300.0129839 +3551 3548 51704651.66159 +3633 3548 -5400388.818121 +3634 3548 -33213528.24393 +3635 3548 -47583984.21356 +3654 3548 -20115648.21112 +3655 3548 -16544192.62304 +3656 3548 -35060824.89038 +3657 3548 -8226463.033369 +3658 3548 -6786471.749505 +3659 3548 -65286971.7737 +3660 3548 -39382499.93739 +3661 3548 -3455807.383529 +3662 3548 -54179922.82412 +3549 3549 257897400.5802 +3550 3549 -58714314.72505 +3551 3549 -485079.4090633 +3633 3549 -31166196.42186 +3634 3549 15281043.89176 +3635 3549 18784264.9961 +3654 3549 -7505330.242306 +3655 3549 -3824705.52229 +3656 3549 -5042360.252043 +3657 3549 -50777794.92451 +3658 3549 3468956.114404 +3659 3549 39274531.29995 +3660 3549 15865543.81017 +3661 3549 -14925294.48387 +3662 3549 -7720880.488229 +3550 3550 237740233.5922 +3551 3550 -1506415.954004 +3633 3550 15281043.89176 +3634 3550 -28905435.61346 +3635 3550 -16544192.62304 +3654 3550 2425294.479764 +3655 3550 -37309473.55378 +3656 3550 -32963242.21564 +3657 3550 -2781043.887649 +3658 3550 -17383526.42432 +3659 3550 3210859.285327 +3660 3550 -14925294.48387 +3661 3550 10014657.81304 +3662 3550 6296575.553343 +3551 3551 272931439.9327 +3633 3551 18784264.9961 +3634 3551 -16544192.62304 +3635 3551 -33602279.96802 +3654 3551 2392605.028518 +3655 3551 -32963242.21564 +3656 3551 -45497645.34292 +3657 3551 39274531.29978 +3658 3551 -3455807.383529 +3659 3551 -54179922.82412 +3660 3551 7491932.009273 +3661 3551 -7036757.7778 +3662 3551 -62943559.27428 +3552 3552 698751952.167 +3553 3552 62499999.98975 +3554 3552 33160993.85051 +3555 3552 -337915744.7523 +3556 3552 -62516096.56266 +3557 3552 -27668847.19038 +3558 3552 13308405.80675 +3559 3552 50016096.56471 +3560 3552 -19894290.40682 +3663 3552 50455843.08525 +3664 3552 15625000.00514 +3665 3552 23750485.45243 +3666 3552 -136601119.3265 +3667 3552 -15628682.15673 +3668 3552 -88333821.76341 +3669 3552 -31442472.41633 +3670 3552 12503682.1557 +3671 3552 -21464859.02542 +3553 3553 604980043.3115 +3554 3553 -63103934.68082 +3555 3553 -62524144.84911 +3556 3553 -44113422.33778 +3557 3553 -38272833.23799 +3558 3553 75024144.84706 +3559 3553 13308405.80675 +3560 3553 25517746.91897 +3663 3553 15625000.00514 +3664 3553 27013291.43733 +3665 3553 -3407345.083582 +3666 3553 -15630523.23252 +3667 3553 -63151629.12586 +3668 3553 -25854695.88552 +3669 3553 18755523.23355 +3670 3553 -31442472.41633 +3671 3553 25757502.85539 +3554 3554 741587115.0734 +3555 3554 -24922773.86031 +3556 3554 -30315528.70936 +3557 3554 20612357.80692 +3558 3554 -29841435.61023 +3559 3554 17011831.27931 +3560 3554 35489082.15132 +3663 3554 -8884805.348678 +3664 3554 -29515355.2492 +3665 3554 -145884263.2499 +3666 3554 -87990199.11779 +3667 3554 -23932056.04702 +3668 3554 -133843411.9462 +3669 3554 -32197288.53812 +3670 3554 17171668.57026 +3671 3554 -83846593.11021 +3555 3555 1185266328.887 +3556 3555 62540241.42204 +3557 3555 30860066.01788 +3558 3555 30368144.44572 +3559 3555 -62516096.56266 +3560 3555 27037674.41794 +3561 3555 -224004433.2424 +3562 3555 3.09944152832e-06 +3563 3555 -5943327.707585 +3564 3555 -91775737.73549 +3565 3555 62499999.98974 +3566 3555 -27030536.78462 +3663 3555 -119411159.8837 +3664 3555 -15630523.23252 +3665 3555 75186254.88774 +3666 3555 109890622.1535 +3667 3555 15634205.38412 +3668 3555 7712478.882864 +3669 3555 -60563825.20041 +3670 3555 -15628682.15673 +3671 3555 27115214.46942 +3672 3555 -107888591.8846 +3673 3555 1.713633537292e-06 +3674 3555 -82890605.78265 +3675 3555 -43968569.74338 +3676 3555 15625000.00513 +3677 3555 -27108827.67327 +3556 3556 1016491380.459 +3557 3556 -85033469.8302 +3558 3556 -62524144.84912 +3559 3556 -188413029.0158 +3560 3556 46636948.6184 +3561 3556 3.695487976074e-06 +3562 3556 50996827.03073 +3563 3556 -27430311.52865 +3564 3556 62499999.98974 +3565 3556 -73024977.83304 +3566 3556 15223836.31984 +3663 3556 -15628682.15673 +3664 3556 -45961669.68301 +3665 3556 8705839.731277 +3666 3556 15634205.38412 +3667 3556 67697343.25408 +3668 3556 -21260405.06448 +3669 3556 -15630523.23252 +3670 3556 -115258445.5683 +3671 3556 76792017.46155 +3672 3556 1.668930053711e-06 +3673 3556 -39138290.32084 +3674 3556 -6857580.506883 +3675 3556 15625000.00513 +3676 3556 -39280887.92821 +3677 3556 20086776.37002 +3557 3557 1141730954.706 +3558 3557 26698361.28971 +3559 3557 52125943.97254 +3560 3557 56705174.06508 +3561 3557 -3200272.15248 +3562 3557 -27430311.52865 +3563 3557 99884455.60809 +3564 3557 -26687654.83973 +3565 3557 14949530.76392 +3566 3557 -20428342.61214 +3663 3557 74842632.24213 +3664 3557 6787043.609902 +3665 3557 -88003520.09856 +3666 3557 7717283.578221 +3667 3557 -21256561.34093 +3668 3557 -211698416.8248 +3669 3557 27118407.8675 +3670 3557 78438470.16785 +3671 3557 -167573319.7819 +3672 3557 -82547723.83843 +3673 3557 -6857580.506883 +3674 3557 -113395588.2476 +3675 3557 -27108827.67327 +3676 3557 20086776.37002 +3677 3557 -61172794.84886 +3558 3558 698751952.167 +3559 3558 62499999.98975 +3560 3558 33160993.85051 +3561 3558 -90421354.05518 +3562 3558 -62499999.98975 +3563 3558 24401754.87359 +3564 3558 -337915744.7523 +3565 3558 -62516096.56266 +3566 3558 -27668847.19038 +3567 3558 13308405.80675 +3568 3558 50016096.56471 +3569 3558 -19894290.40682 +3663 3558 789479.8663111 +3664 3558 18755523.23355 +3665 3558 16762853.88037 +3666 3558 -11151323.14121 +3667 3558 -15630523.23252 +3668 3558 -13684113.02055 +3669 3558 50455843.08525 +3670 3558 15625000.00514 +3671 3558 23750485.45243 +3672 3558 -27518808.45327 +3673 3558 -15625000.00513 +3674 3558 -14250754.75238 +3675 3558 -136601119.3265 +3676 3558 -15628682.15673 +3677 3558 -88333821.76341 +3678 3558 -31442472.41633 +3679 3558 12503682.1557 +3680 3558 -21464859.02542 +3559 3559 604980043.3115 +3560 3559 -63103934.68082 +3561 3559 -62499999.98975 +3562 3559 -71670594.15271 +3563 3559 12206475.20882 +3564 3559 -62524144.84911 +3565 3559 -44113422.33778 +3566 3559 -38272833.23799 +3567 3559 75024144.84706 +3568 3559 13308405.80675 +3569 3559 25517746.91897 +3663 3559 12503682.1557 +3664 3559 789479.8663122 +3665 3559 -8940185.539224 +3666 3559 -15628682.15672 +3667 3559 -65845943.5091 +3668 3559 -52101581.10086 +3669 3559 15625000.00514 +3670 3559 27013291.43733 +3671 3559 -3407345.083582 +3672 3559 -15625000.00513 +3673 3559 -22831126.63809 +3674 3559 -13229195.86314 +3675 3559 -15630523.23252 +3676 3559 -63151629.12586 +3677 3559 -25854695.88552 +3678 3559 18755523.23355 +3679 3559 -31442472.41633 +3680 3559 25757502.85539 +3560 3560 741587115.0734 +3561 3560 24744636.81848 +3562 3560 12480780.76473 +3563 3560 -16816652.79793 +3564 3560 -24922773.86031 +3565 3560 -30315528.70936 +3566 3560 20612357.80692 +3567 3560 -29841435.61023 +3568 3560 17011831.27931 +3569 3560 35489082.15132 +3663 3560 11175235.92025 +3664 3560 -13410278.30884 +3665 3560 2105279.643495 +3666 3560 -13682502.0067 +3667 3560 -53748034.02747 +3668 3560 -35806647.62401 +3669 3560 -8884805.348678 +3670 3560 -29515355.2492 +3671 3560 -145884263.2499 +3672 3560 -14250754.75238 +3673 3560 -13229195.86314 +3674 3560 -17306764.74188 +3675 3560 -87990199.11779 +3676 3560 -23932056.04702 +3677 3560 -133843411.9462 +3678 3560 -32197288.53812 +3679 3560 17171668.57026 +3680 3560 -83846593.11021 +3561 3561 1104842790.893 +3562 3561 1.609325408936e-05 +3563 3561 9143599.859988 +3564 3561 135775801.5773 +3565 3561 -6.794929504395e-06 +3566 3561 2285899.966128 +3570 3561 -224004433.2424 +3571 3561 3.09944152832e-06 +3572 3561 -5943327.707585 +3573 3561 -91775737.73549 +3574 3561 62499999.98974 +3575 3561 -27030536.78462 +3666 3561 -103592244.5474 +3667 3561 1.892447471619e-06 +3668 3561 80604706.69032 +3669 3561 -42555886.98831 +3670 3561 -15625000.00514 +3671 3561 26537352.8999 +3672 3561 77208121.14848 +3673 3561 3.09944152832e-06 +3674 3561 2285899.092361 +3675 3561 -48017751.39621 +3676 3561 -8.776783943176e-06 +3677 3561 571474.7733788 +3681 3561 -107888591.8846 +3682 3561 1.713633537292e-06 +3683 3561 -82890605.78265 +3684 3561 -43968569.74338 +3685 3561 15625000.00513 +3686 3561 -27108827.67327 +3562 3562 954836711.7471 +3563 3562 -109721246.0606 +3564 3562 -6.705522537231e-06 +3565 3562 -101723938.9279 +3566 3562 55957845.25232 +3570 3562 3.695487976074e-06 +3571 3562 50996827.03073 +3572 3562 -27430311.52865 +3573 3562 62499999.98974 +3574 3562 -73024977.83304 +3575 3562 15223836.31984 +3666 3562 -9.983777999878e-07 +3667 3562 -34841942.9836 +3668 3562 -6857580.506883 +3669 3562 -15625000.00514 +3670 3562 -37868205.17313 +3671 3562 19401012.48091 +3672 3562 3.09944152832e-06 +3673 3562 39706666.64553 +3674 3562 -27430322.01402 +3675 3562 -7.04824924469e-06 +3676 3562 -107392689.3388 +3677 3562 79112730.44064 +3681 3562 1.668930053711e-06 +3682 3562 -39138290.32084 +3683 3562 -6857580.506883 +3684 3562 15625000.00513 +3685 3562 -39280887.92821 +3686 3562 20086776.37002 +3563 3563 1151791779.138 +3564 3563 2285899.966128 +3565 3563 53763400.80823 +3566 3563 113453108.8746 +3570 3563 -3200272.15248 +3571 3563 -27430311.52865 +3572 3563 99884455.60809 +3573 3563 -26687654.83973 +3574 3563 14949530.76392 +3575 3563 -20428342.61214 +3666 3563 80261824.7461 +3667 3563 -6857580.506883 +3668 3563 -101938662.0149 +3669 3563 26537352.8999 +3670 3563 19401012.48091 +3671 3563 -57405640.83529 +3672 3563 2285899.092361 +3673 3563 -27430322.01402 +3674 3563 -242725472.4512 +3675 3563 571474.773379 +3676 3563 78838424.88527 +3677 3563 -190201211.678 +3681 3563 -82547723.83843 +3682 3563 -6857580.506883 +3683 3563 -113395588.2476 +3684 3563 -27108827.67327 +3685 3563 20086776.37002 +3686 3563 -61172794.84886 +3564 3564 1185266328.887 +3565 3564 62540241.42204 +3566 3564 30860066.01788 +3567 3564 30368144.44572 +3568 3564 -62516096.56266 +3569 3564 27037674.41794 +3570 3564 -90421354.05518 +3571 3564 -62499999.98975 +3572 3564 24401754.87359 +3573 3564 -224004433.2424 +3574 3564 3.09944152832e-06 +3575 3564 -5943327.707585 +3576 3564 -91775737.73549 +3577 3564 62499999.98974 +3578 3564 -27030536.78462 +3666 3564 -26783317.53868 +3667 3564 15625000.00513 +3668 3564 13679279.97901 +3669 3564 -119411159.8837 +3670 3564 -15630523.23252 +3671 3564 75186254.88774 +3672 3564 16426910.05153 +3673 3564 4.485249519348e-06 +3674 3564 571474.7733669 +3675 3564 109890622.1535 +3676 3564 15634205.38412 +3677 3564 7712478.882864 +3678 3564 -60563825.20041 +3679 3564 -15628682.15673 +3680 3564 27115214.46942 +3681 3564 -27518808.45327 +3682 3564 -15625000.00513 +3683 3564 -14250754.75238 +3684 3564 -107888591.8846 +3685 3564 1.713633537292e-06 +3686 3564 -82890605.78265 +3687 3564 -43968569.74338 +3688 3564 15625000.00513 +3689 3564 -27108827.67327 +3565 3565 1016491380.459 +3566 3565 -85033469.8302 +3567 3565 -62524144.84912 +3568 3565 -188413029.0158 +3569 3565 46636948.6184 +3570 3565 -62499999.98975 +3571 3565 -71670594.15271 +3572 3565 12206475.20882 +3573 3565 3.695487976074e-06 +3574 3565 50996827.03073 +3575 3565 -27430311.52865 +3576 3565 62499999.98974 +3577 3565 -73024977.83304 +3578 3565 15223836.31984 +3666 3565 15625000.00513 +3667 3565 -22095635.7235 +3668 3565 -12543431.97403 +3669 3565 -15628682.15673 +3670 3565 -45961669.68301 +3671 3565 8705839.731277 +3672 3565 5.781650543213e-06 +3673 3565 -42948027.89108 +3674 3565 -51682408.42662 +3675 3565 15634205.38412 +3676 3565 67697343.25408 +3677 3565 -21260405.06448 +3678 3565 -15630523.23252 +3679 3565 -115258445.5683 +3680 3565 76792017.46155 +3681 3565 -15625000.00513 +3682 3565 -22831126.63809 +3683 3565 -13229195.86314 +3684 3565 1.668930053711e-06 +3685 3565 -39138290.32084 +3686 3565 -6857580.506883 +3687 3565 15625000.00513 +3688 3565 -39280887.92821 +3689 3565 20086776.37002 +3566 3566 1141730954.706 +3567 3566 26698361.28971 +3568 3566 52125943.97254 +3569 3566 56705174.06508 +3570 3566 24744636.81848 +3571 3566 12480780.76473 +3572 3566 -16816652.79793 +3573 3566 -3200272.15248 +3574 3566 -27430311.52865 +3575 3566 99884455.60809 +3576 3566 -26687654.83973 +3577 3566 14949530.76392 +3578 3566 -20428342.61214 +3666 3566 13679279.97901 +3667 3566 -12543431.97403 +3668 3566 -15345455.6363 +3669 3566 74842632.24213 +3670 3566 6787043.609902 +3671 3566 -88003520.09856 +3672 3566 571474.7733671 +3673 3566 -51408102.87125 +3674 3566 -18348781.1507 +3675 3566 7717283.578221 +3676 3566 -21256561.34093 +3677 3566 -211698416.8248 +3678 3566 27118407.8675 +3679 3566 78438470.16785 +3680 3566 -167573319.7819 +3681 3566 -14250754.75238 +3682 3566 -13229195.86314 +3683 3566 -17306764.74188 +3684 3566 -82547723.83843 +3685 3566 -6857580.506883 +3686 3566 -113395588.2476 +3687 3566 -27108827.67327 +3688 3566 20086776.37002 +3689 3566 -61172794.84886 +3567 3567 698751952.167 +3568 3567 62499999.98975 +3569 3567 33160993.85051 +3573 3567 -90421354.05518 +3574 3567 -62499999.98975 +3575 3567 24401754.87359 +3576 3567 -337915744.7523 +3577 3567 -62516096.56266 +3578 3567 -27668847.19038 +3579 3567 13308405.80675 +3580 3567 50016096.56471 +3581 3567 -19894290.40682 +3669 3567 789479.8663111 +3670 3567 18755523.23355 +3671 3567 16762853.88037 +3675 3567 -11151323.14121 +3676 3567 -15630523.23252 +3677 3567 -13684113.02055 +3678 3567 50455843.08525 +3679 3567 15625000.00514 +3680 3567 23750485.45243 +3684 3567 -27518808.45327 +3685 3567 -15625000.00513 +3686 3567 -14250754.75238 +3687 3567 -136601119.3265 +3688 3567 -15628682.15673 +3689 3567 -88333821.76341 +3690 3567 -31442472.41633 +3691 3567 12503682.1557 +3692 3567 -21464859.02542 +3568 3568 604980043.3115 +3569 3568 -63103934.68082 +3573 3568 -62499999.98975 +3574 3568 -71670594.15271 +3575 3568 12206475.20882 +3576 3568 -62524144.84911 +3577 3568 -44113422.33778 +3578 3568 -38272833.23799 +3579 3568 75024144.84706 +3580 3568 13308405.80675 +3581 3568 25517746.91897 +3669 3568 12503682.1557 +3670 3568 789479.8663122 +3671 3568 -8940185.539224 +3675 3568 -15628682.15672 +3676 3568 -65845943.5091 +3677 3568 -52101581.10086 +3678 3568 15625000.00514 +3679 3568 27013291.43733 +3680 3568 -3407345.083582 +3684 3568 -15625000.00513 +3685 3568 -22831126.63809 +3686 3568 -13229195.86314 +3687 3568 -15630523.23252 +3688 3568 -63151629.12586 +3689 3568 -25854695.88552 +3690 3568 18755523.23355 +3691 3568 -31442472.41633 +3692 3568 25757502.85539 +3569 3569 741587115.0734 +3573 3569 24744636.81848 +3574 3569 12480780.76473 +3575 3569 -16816652.79793 +3576 3569 -24922773.86031 +3577 3569 -30315528.70936 +3578 3569 20612357.80692 +3579 3569 -29841435.61023 +3580 3569 17011831.27931 +3581 3569 35489082.15132 +3669 3569 11175235.92025 +3670 3569 -13410278.30884 +3671 3569 2105279.643495 +3675 3569 -13682502.0067 +3676 3569 -53748034.02747 +3677 3569 -35806647.62401 +3678 3569 -8884805.348678 +3679 3569 -29515355.2492 +3680 3569 -145884263.2499 +3684 3569 -14250754.75238 +3685 3569 -13229195.86314 +3686 3569 -17306764.74188 +3687 3569 -87990199.11779 +3688 3569 -23932056.04702 +3689 3569 -133843411.9462 +3690 3569 -32197288.53812 +3691 3569 17171668.57026 +3692 3569 -83846593.11021 +3570 3570 1104842790.893 +3571 3570 1.609325408936e-05 +3572 3570 9143599.859988 +3573 3570 135775801.5773 +3574 3570 -6.794929504395e-06 +3575 3570 2285899.966128 +3582 3570 -224004433.2424 +3583 3570 3.09944152832e-06 +3584 3570 -5943327.707585 +3585 3570 -91775737.73549 +3586 3570 62499999.98974 +3587 3570 -27030536.78462 +3672 3570 -103592244.5474 +3673 3570 1.892447471619e-06 +3674 3570 80604706.69032 +3675 3570 -42555886.98831 +3676 3570 -15625000.00514 +3677 3570 26537352.8999 +3681 3570 77208121.14848 +3682 3570 3.09944152832e-06 +3683 3570 2285899.092361 +3684 3570 -48017751.39621 +3685 3570 -8.776783943176e-06 +3686 3570 571474.7733788 +3693 3570 -107888591.8846 +3694 3570 1.713633537292e-06 +3695 3570 -82890605.78265 +3696 3570 -43968569.74338 +3697 3570 15625000.00513 +3698 3570 -27108827.67327 +3571 3571 954836711.7471 +3572 3571 -109721246.0606 +3573 3571 -6.705522537231e-06 +3574 3571 -101723938.9279 +3575 3571 55957845.25232 +3582 3571 3.695487976074e-06 +3583 3571 50996827.03073 +3584 3571 -27430311.52865 +3585 3571 62499999.98974 +3586 3571 -73024977.83304 +3587 3571 15223836.31984 +3672 3571 -9.983777999878e-07 +3673 3571 -34841942.9836 +3674 3571 -6857580.506883 +3675 3571 -15625000.00514 +3676 3571 -37868205.17313 +3677 3571 19401012.48091 +3681 3571 3.09944152832e-06 +3682 3571 39706666.64553 +3683 3571 -27430322.01402 +3684 3571 -7.04824924469e-06 +3685 3571 -107392689.3388 +3686 3571 79112730.44064 +3693 3571 1.668930053711e-06 +3694 3571 -39138290.32084 +3695 3571 -6857580.506883 +3696 3571 15625000.00513 +3697 3571 -39280887.92821 +3698 3571 20086776.37002 +3572 3572 1151791779.138 +3573 3572 2285899.966128 +3574 3572 53763400.80823 +3575 3572 113453108.8746 +3582 3572 -3200272.15248 +3583 3572 -27430311.52865 +3584 3572 99884455.60809 +3585 3572 -26687654.83973 +3586 3572 14949530.76392 +3587 3572 -20428342.61214 +3672 3572 80261824.7461 +3673 3572 -6857580.506883 +3674 3572 -101938662.0149 +3675 3572 26537352.8999 +3676 3572 19401012.48091 +3677 3572 -57405640.83529 +3681 3572 2285899.092361 +3682 3572 -27430322.01402 +3683 3572 -242725472.4512 +3684 3572 571474.773379 +3685 3572 78838424.88527 +3686 3572 -190201211.678 +3693 3572 -82547723.83843 +3694 3572 -6857580.506883 +3695 3572 -113395588.2476 +3696 3572 -27108827.67327 +3697 3572 20086776.37002 +3698 3572 -61172794.84886 +3573 3573 1104842790.893 +3574 3573 1.609325408936e-05 +3575 3573 9143599.859988 +3576 3573 135775801.5773 +3577 3573 -6.794929504395e-06 +3578 3573 2285899.966128 +3582 3573 -90421354.05518 +3583 3573 -62499999.98975 +3584 3573 24401754.87359 +3585 3573 -224004433.2424 +3586 3573 3.09944152832e-06 +3587 3573 -5943327.707585 +3588 3573 -91775737.73549 +3589 3573 62499999.98974 +3590 3573 -27030536.78462 +3672 3573 -26783317.53868 +3673 3573 15625000.00513 +3674 3573 13679279.97901 +3675 3573 -103592244.5474 +3676 3573 1.892447471619e-06 +3677 3573 80604706.69032 +3678 3573 -42555886.98831 +3679 3573 -15625000.00514 +3680 3573 26537352.8999 +3681 3573 16426910.05153 +3682 3573 4.485249519348e-06 +3683 3573 571474.7733669 +3684 3573 77208121.14848 +3685 3573 3.09944152832e-06 +3686 3573 2285899.092361 +3687 3573 -48017751.39621 +3688 3573 -8.776783943176e-06 +3689 3573 571474.7733788 +3693 3573 -27518808.45327 +3694 3573 -15625000.00513 +3695 3573 -14250754.75238 +3696 3573 -107888591.8846 +3697 3573 1.713633537292e-06 +3698 3573 -82890605.78265 +3699 3573 -43968569.74338 +3700 3573 15625000.00513 +3701 3573 -27108827.67327 +3574 3574 954836711.7471 +3575 3574 -109721246.0606 +3576 3574 -6.705522537231e-06 +3577 3574 -101723938.9279 +3578 3574 55957845.25232 +3582 3574 -62499999.98975 +3583 3574 -71670594.15271 +3584 3574 12206475.20882 +3585 3574 3.695487976074e-06 +3586 3574 50996827.03073 +3587 3574 -27430311.52865 +3588 3574 62499999.98974 +3589 3574 -73024977.83304 +3590 3574 15223836.31984 +3672 3574 15625000.00513 +3673 3574 -22095635.7235 +3674 3574 -12543431.97403 +3675 3574 -9.983777999878e-07 +3676 3574 -34841942.9836 +3677 3574 -6857580.506883 +3678 3574 -15625000.00514 +3679 3574 -37868205.17313 +3680 3574 19401012.48091 +3681 3574 5.781650543213e-06 +3682 3574 -42948027.89108 +3683 3574 -51682408.42662 +3684 3574 3.09944152832e-06 +3685 3574 39706666.64553 +3686 3574 -27430322.01402 +3687 3574 -7.04824924469e-06 +3688 3574 -107392689.3388 +3689 3574 79112730.44064 +3693 3574 -15625000.00513 +3694 3574 -22831126.63809 +3695 3574 -13229195.86314 +3696 3574 1.668930053711e-06 +3697 3574 -39138290.32084 +3698 3574 -6857580.506883 +3699 3574 15625000.00513 +3700 3574 -39280887.92821 +3701 3574 20086776.37002 +3575 3575 1151791779.138 +3576 3575 2285899.966128 +3577 3575 53763400.80823 +3578 3575 113453108.8746 +3582 3575 24744636.81848 +3583 3575 12480780.76473 +3584 3575 -16816652.79793 +3585 3575 -3200272.15248 +3586 3575 -27430311.52865 +3587 3575 99884455.60809 +3588 3575 -26687654.83973 +3589 3575 14949530.76392 +3590 3575 -20428342.61214 +3672 3575 13679279.97901 +3673 3575 -12543431.97403 +3674 3575 -15345455.6363 +3675 3575 80261824.7461 +3676 3575 -6857580.506883 +3677 3575 -101938662.0149 +3678 3575 26537352.8999 +3679 3575 19401012.48091 +3680 3575 -57405640.83529 +3681 3575 571474.7733671 +3682 3575 -51408102.87125 +3683 3575 -18348781.1507 +3684 3575 2285899.092361 +3685 3575 -27430322.01402 +3686 3575 -242725472.4512 +3687 3575 571474.773379 +3688 3575 78838424.88527 +3689 3575 -190201211.678 +3693 3575 -14250754.75238 +3694 3575 -13229195.86314 +3695 3575 -17306764.74188 +3696 3575 -82547723.83843 +3697 3575 -6857580.506883 +3698 3575 -113395588.2476 +3699 3575 -27108827.67327 +3700 3575 20086776.37002 +3701 3575 -61172794.84886 +3576 3576 1185266328.887 +3577 3576 62540241.42204 +3578 3576 30860066.01788 +3579 3576 30368144.44572 +3580 3576 -62516096.56266 +3581 3576 27037674.41794 +3585 3576 -90421354.05518 +3586 3576 -62499999.98975 +3587 3576 24401754.87359 +3588 3576 -224004433.2424 +3589 3576 3.09944152832e-06 +3590 3576 -5943327.707585 +3591 3576 -91775737.73549 +3592 3576 62499999.98974 +3593 3576 -27030536.78462 +3675 3576 -26783317.53868 +3676 3576 15625000.00513 +3677 3576 13679279.97901 +3678 3576 -119411159.8837 +3679 3576 -15630523.23252 +3680 3576 75186254.88774 +3684 3576 16426910.05153 +3685 3576 4.485249519348e-06 +3686 3576 571474.7733669 +3687 3576 109890622.1535 +3688 3576 15634205.38412 +3689 3576 7712478.882864 +3690 3576 -60563825.20041 +3691 3576 -15628682.15673 +3692 3576 27115214.46942 +3696 3576 -27518808.45327 +3697 3576 -15625000.00513 +3698 3576 -14250754.75238 +3699 3576 -107888591.8846 +3700 3576 1.713633537292e-06 +3701 3576 -82890605.78265 +3702 3576 -43968569.74338 +3703 3576 15625000.00513 +3704 3576 -27108827.67327 +3577 3577 1016491380.459 +3578 3577 -85033469.8302 +3579 3577 -62524144.84912 +3580 3577 -188413029.0158 +3581 3577 46636948.6184 +3585 3577 -62499999.98975 +3586 3577 -71670594.15271 +3587 3577 12206475.20882 +3588 3577 3.695487976074e-06 +3589 3577 50996827.03073 +3590 3577 -27430311.52865 +3591 3577 62499999.98974 +3592 3577 -73024977.83304 +3593 3577 15223836.31984 +3675 3577 15625000.00513 +3676 3577 -22095635.7235 +3677 3577 -12543431.97403 +3678 3577 -15628682.15673 +3679 3577 -45961669.68301 +3680 3577 8705839.731277 +3684 3577 5.781650543213e-06 +3685 3577 -42948027.89108 +3686 3577 -51682408.42662 +3687 3577 15634205.38412 +3688 3577 67697343.25408 +3689 3577 -21260405.06448 +3690 3577 -15630523.23252 +3691 3577 -115258445.5683 +3692 3577 76792017.46155 +3696 3577 -15625000.00513 +3697 3577 -22831126.63809 +3698 3577 -13229195.86314 +3699 3577 1.668930053711e-06 +3700 3577 -39138290.32084 +3701 3577 -6857580.506883 +3702 3577 15625000.00513 +3703 3577 -39280887.92821 +3704 3577 20086776.37002 +3578 3578 1141730954.706 +3579 3578 26698361.28971 +3580 3578 52125943.97254 +3581 3578 56705174.06508 +3585 3578 24744636.81848 +3586 3578 12480780.76473 +3587 3578 -16816652.79793 +3588 3578 -3200272.15248 +3589 3578 -27430311.52865 +3590 3578 99884455.60809 +3591 3578 -26687654.83973 +3592 3578 14949530.76392 +3593 3578 -20428342.61214 +3675 3578 13679279.97901 +3676 3578 -12543431.97403 +3677 3578 -15345455.6363 +3678 3578 74842632.24213 +3679 3578 6787043.609902 +3680 3578 -88003520.09856 +3684 3578 571474.7733671 +3685 3578 -51408102.87125 +3686 3578 -18348781.1507 +3687 3578 7717283.578221 +3688 3578 -21256561.34093 +3689 3578 -211698416.8248 +3690 3578 27118407.8675 +3691 3578 78438470.16785 +3692 3578 -167573319.7819 +3696 3578 -14250754.75238 +3697 3578 -13229195.86314 +3698 3578 -17306764.74188 +3699 3578 -82547723.83843 +3700 3578 -6857580.506883 +3701 3578 -113395588.2476 +3702 3578 -27108827.67327 +3703 3578 20086776.37002 +3704 3578 -61172794.84886 +3579 3579 698751952.167 +3580 3579 62499999.98975 +3581 3579 33160993.85051 +3588 3579 -90421354.05518 +3589 3579 -62499999.98975 +3590 3579 24401754.87359 +3591 3579 -337915744.7523 +3592 3579 -62516096.56266 +3593 3579 -27668847.19038 +3594 3579 13308405.80675 +3595 3579 50016096.56471 +3596 3579 -19894290.40682 +3678 3579 789479.8663111 +3679 3579 18755523.23355 +3680 3579 16762853.88037 +3687 3579 -11151323.14121 +3688 3579 -15630523.23252 +3689 3579 -13684113.02055 +3690 3579 50455843.08525 +3691 3579 15625000.00514 +3692 3579 23750485.45243 +3699 3579 -27518808.45327 +3700 3579 -15625000.00513 +3701 3579 -14250754.75238 +3702 3579 -136601119.3265 +3703 3579 -15628682.15673 +3704 3579 -88333821.76341 +3705 3579 -31442472.41633 +3706 3579 12503682.1557 +3707 3579 -21464859.02542 +3580 3580 604980043.3115 +3581 3580 -63103934.68082 +3588 3580 -62499999.98975 +3589 3580 -71670594.15271 +3590 3580 12206475.20882 +3591 3580 -62524144.84911 +3592 3580 -44113422.33778 +3593 3580 -38272833.23799 +3594 3580 75024144.84706 +3595 3580 13308405.80675 +3596 3580 25517746.91897 +3678 3580 12503682.1557 +3679 3580 789479.8663122 +3680 3580 -8940185.539224 +3687 3580 -15628682.15672 +3688 3580 -65845943.5091 +3689 3580 -52101581.10086 +3690 3580 15625000.00514 +3691 3580 27013291.43733 +3692 3580 -3407345.083582 +3699 3580 -15625000.00513 +3700 3580 -22831126.63809 +3701 3580 -13229195.86314 +3702 3580 -15630523.23252 +3703 3580 -63151629.12586 +3704 3580 -25854695.88552 +3705 3580 18755523.23355 +3706 3580 -31442472.41633 +3707 3580 25757502.85539 +3581 3581 741587115.0734 +3588 3581 24744636.81848 +3589 3581 12480780.76473 +3590 3581 -16816652.79793 +3591 3581 -24922773.86031 +3592 3581 -30315528.70936 +3593 3581 20612357.80692 +3594 3581 -29841435.61023 +3595 3581 17011831.27931 +3596 3581 35489082.15132 +3678 3581 11175235.92025 +3679 3581 -13410278.30884 +3680 3581 2105279.643495 +3687 3581 -13682502.0067 +3688 3581 -53748034.02747 +3689 3581 -35806647.62401 +3690 3581 -8884805.348678 +3691 3581 -29515355.2492 +3692 3581 -145884263.2499 +3699 3581 -14250754.75238 +3700 3581 -13229195.86314 +3701 3581 -17306764.74188 +3702 3581 -87990199.11779 +3703 3581 -23932056.04702 +3704 3581 -133843411.9462 +3705 3581 -32197288.53812 +3706 3581 17171668.57026 +3707 3581 -83846593.11021 +3582 3582 1104842790.893 +3583 3582 1.609325408936e-05 +3584 3582 9143599.859988 +3585 3582 135775801.5773 +3586 3582 -6.794929504395e-06 +3587 3582 2285899.966128 +3597 3582 -224004433.2424 +3598 3582 3.09944152832e-06 +3599 3582 -5943327.707585 +3600 3582 -91775737.73549 +3601 3582 62499999.98974 +3602 3582 -27030536.78462 +3681 3582 -103592244.5474 +3682 3582 1.892447471619e-06 +3683 3582 80604706.69032 +3684 3582 -42555886.98831 +3685 3582 -15625000.00514 +3686 3582 26537352.8999 +3693 3582 77208121.14848 +3694 3582 3.09944152832e-06 +3695 3582 2285899.092361 +3696 3582 -48017751.39621 +3697 3582 -8.776783943176e-06 +3698 3582 571474.7733788 +3708 3582 -107888591.8846 +3709 3582 1.713633537292e-06 +3710 3582 -82890605.78265 +3711 3582 -43968569.74338 +3712 3582 15625000.00513 +3713 3582 -27108827.67327 +3583 3583 954836711.7471 +3584 3583 -109721246.0606 +3585 3583 -6.705522537231e-06 +3586 3583 -101723938.9279 +3587 3583 55957845.25232 +3597 3583 3.695487976074e-06 +3598 3583 50996827.03073 +3599 3583 -27430311.52865 +3600 3583 62499999.98974 +3601 3583 -73024977.83304 +3602 3583 15223836.31984 +3681 3583 -9.983777999878e-07 +3682 3583 -34841942.9836 +3683 3583 -6857580.506883 +3684 3583 -15625000.00514 +3685 3583 -37868205.17313 +3686 3583 19401012.48091 +3693 3583 3.09944152832e-06 +3694 3583 39706666.64553 +3695 3583 -27430322.01402 +3696 3583 -7.04824924469e-06 +3697 3583 -107392689.3388 +3698 3583 79112730.44064 +3708 3583 1.668930053711e-06 +3709 3583 -39138290.32084 +3710 3583 -6857580.506883 +3711 3583 15625000.00513 +3712 3583 -39280887.92821 +3713 3583 20086776.37002 +3584 3584 1151791779.138 +3585 3584 2285899.966128 +3586 3584 53763400.80823 +3587 3584 113453108.8746 +3597 3584 -3200272.15248 +3598 3584 -27430311.52865 +3599 3584 99884455.60809 +3600 3584 -26687654.83973 +3601 3584 14949530.76392 +3602 3584 -20428342.61214 +3681 3584 80261824.7461 +3682 3584 -6857580.506883 +3683 3584 -101938662.0149 +3684 3584 26537352.8999 +3685 3584 19401012.48091 +3686 3584 -57405640.83529 +3693 3584 2285899.092361 +3694 3584 -27430322.01402 +3695 3584 -242725472.4512 +3696 3584 571474.773379 +3697 3584 78838424.88527 +3698 3584 -190201211.678 +3708 3584 -82547723.83843 +3709 3584 -6857580.506883 +3710 3584 -113395588.2476 +3711 3584 -27108827.67327 +3712 3584 20086776.37002 +3713 3584 -61172794.84886 +3585 3585 1104842790.893 +3586 3585 1.609325408936e-05 +3587 3585 9143599.859988 +3588 3585 135775801.5773 +3589 3585 -6.794929504395e-06 +3590 3585 2285899.966128 +3597 3585 -90421354.05518 +3598 3585 -62499999.98975 +3599 3585 24401754.87359 +3600 3585 -224004433.2424 +3601 3585 3.09944152832e-06 +3602 3585 -5943327.707585 +3603 3585 -91775737.73549 +3604 3585 62499999.98974 +3605 3585 -27030536.78462 +3681 3585 -26783317.53868 +3682 3585 15625000.00513 +3683 3585 13679279.97901 +3684 3585 -103592244.5474 +3685 3585 1.892447471619e-06 +3686 3585 80604706.69032 +3687 3585 -42555886.98831 +3688 3585 -15625000.00514 +3689 3585 26537352.8999 +3693 3585 16426910.05153 +3694 3585 4.485249519348e-06 +3695 3585 571474.7733669 +3696 3585 77208121.14848 +3697 3585 3.09944152832e-06 +3698 3585 2285899.092361 +3699 3585 -48017751.39621 +3700 3585 -8.776783943176e-06 +3701 3585 571474.7733788 +3708 3585 -27518808.45327 +3709 3585 -15625000.00513 +3710 3585 -14250754.75238 +3711 3585 -107888591.8846 +3712 3585 1.713633537292e-06 +3713 3585 -82890605.78265 +3714 3585 -43968569.74338 +3715 3585 15625000.00513 +3716 3585 -27108827.67327 +3586 3586 954836711.7471 +3587 3586 -109721246.0606 +3588 3586 -6.705522537231e-06 +3589 3586 -101723938.9279 +3590 3586 55957845.25232 +3597 3586 -62499999.98975 +3598 3586 -71670594.15271 +3599 3586 12206475.20882 +3600 3586 3.695487976074e-06 +3601 3586 50996827.03073 +3602 3586 -27430311.52865 +3603 3586 62499999.98974 +3604 3586 -73024977.83304 +3605 3586 15223836.31984 +3681 3586 15625000.00513 +3682 3586 -22095635.7235 +3683 3586 -12543431.97403 +3684 3586 -9.983777999878e-07 +3685 3586 -34841942.9836 +3686 3586 -6857580.506883 +3687 3586 -15625000.00514 +3688 3586 -37868205.17313 +3689 3586 19401012.48091 +3693 3586 5.781650543213e-06 +3694 3586 -42948027.89108 +3695 3586 -51682408.42662 +3696 3586 3.09944152832e-06 +3697 3586 39706666.64553 +3698 3586 -27430322.01402 +3699 3586 -7.04824924469e-06 +3700 3586 -107392689.3388 +3701 3586 79112730.44064 +3708 3586 -15625000.00513 +3709 3586 -22831126.63809 +3710 3586 -13229195.86314 +3711 3586 1.668930053711e-06 +3712 3586 -39138290.32084 +3713 3586 -6857580.506883 +3714 3586 15625000.00513 +3715 3586 -39280887.92821 +3716 3586 20086776.37002 +3587 3587 1151791779.138 +3588 3587 2285899.966128 +3589 3587 53763400.80823 +3590 3587 113453108.8746 +3597 3587 24744636.81848 +3598 3587 12480780.76473 +3599 3587 -16816652.79793 +3600 3587 -3200272.15248 +3601 3587 -27430311.52865 +3602 3587 99884455.60809 +3603 3587 -26687654.83973 +3604 3587 14949530.76392 +3605 3587 -20428342.61214 +3681 3587 13679279.97901 +3682 3587 -12543431.97403 +3683 3587 -15345455.6363 +3684 3587 80261824.7461 +3685 3587 -6857580.506883 +3686 3587 -101938662.0149 +3687 3587 26537352.8999 +3688 3587 19401012.48091 +3689 3587 -57405640.83529 +3693 3587 571474.7733671 +3694 3587 -51408102.87125 +3695 3587 -18348781.1507 +3696 3587 2285899.092361 +3697 3587 -27430322.01402 +3698 3587 -242725472.4512 +3699 3587 571474.773379 +3700 3587 78838424.88527 +3701 3587 -190201211.678 +3708 3587 -14250754.75238 +3709 3587 -13229195.86314 +3710 3587 -17306764.74188 +3711 3587 -82547723.83843 +3712 3587 -6857580.506883 +3713 3587 -113395588.2476 +3714 3587 -27108827.67327 +3715 3587 20086776.37002 +3716 3587 -61172794.84886 +3588 3588 1104842790.893 +3589 3588 1.609325408936e-05 +3590 3588 9143599.859988 +3591 3588 135775801.5773 +3592 3588 -6.794929504395e-06 +3593 3588 2285899.966128 +3600 3588 -90421354.05518 +3601 3588 -62499999.98975 +3602 3588 24401754.87359 +3603 3588 -224004433.2424 +3604 3588 3.09944152832e-06 +3605 3588 -5943327.707585 +3606 3588 -91775737.73549 +3607 3588 62499999.98974 +3608 3588 -27030536.78462 +3684 3588 -26783317.53868 +3685 3588 15625000.00513 +3686 3588 13679279.97901 +3687 3588 -103592244.5474 +3688 3588 1.892447471619e-06 +3689 3588 80604706.69032 +3690 3588 -42555886.98831 +3691 3588 -15625000.00514 +3692 3588 26537352.8999 +3696 3588 16426910.05153 +3697 3588 4.485249519348e-06 +3698 3588 571474.7733669 +3699 3588 77208121.14848 +3700 3588 3.09944152832e-06 +3701 3588 2285899.092361 +3702 3588 -48017751.39621 +3703 3588 -8.776783943176e-06 +3704 3588 571474.7733788 +3711 3588 -27518808.45327 +3712 3588 -15625000.00513 +3713 3588 -14250754.75238 +3714 3588 -107888591.8846 +3715 3588 1.713633537292e-06 +3716 3588 -82890605.78265 +3717 3588 -43968569.74338 +3718 3588 15625000.00513 +3719 3588 -27108827.67327 +3589 3589 954836711.7471 +3590 3589 -109721246.0606 +3591 3589 -6.705522537231e-06 +3592 3589 -101723938.9279 +3593 3589 55957845.25232 +3600 3589 -62499999.98975 +3601 3589 -71670594.15271 +3602 3589 12206475.20882 +3603 3589 3.695487976074e-06 +3604 3589 50996827.03073 +3605 3589 -27430311.52865 +3606 3589 62499999.98974 +3607 3589 -73024977.83304 +3608 3589 15223836.31984 +3684 3589 15625000.00513 +3685 3589 -22095635.7235 +3686 3589 -12543431.97403 +3687 3589 -9.983777999878e-07 +3688 3589 -34841942.9836 +3689 3589 -6857580.506883 +3690 3589 -15625000.00514 +3691 3589 -37868205.17313 +3692 3589 19401012.48091 +3696 3589 5.781650543213e-06 +3697 3589 -42948027.89108 +3698 3589 -51682408.42662 +3699 3589 3.09944152832e-06 +3700 3589 39706666.64553 +3701 3589 -27430322.01402 +3702 3589 -7.04824924469e-06 +3703 3589 -107392689.3388 +3704 3589 79112730.44064 +3711 3589 -15625000.00513 +3712 3589 -22831126.63809 +3713 3589 -13229195.86314 +3714 3589 1.668930053711e-06 +3715 3589 -39138290.32084 +3716 3589 -6857580.506883 +3717 3589 15625000.00513 +3718 3589 -39280887.92821 +3719 3589 20086776.37002 +3590 3590 1151791779.138 +3591 3590 2285899.966128 +3592 3590 53763400.80823 +3593 3590 113453108.8746 +3600 3590 24744636.81848 +3601 3590 12480780.76473 +3602 3590 -16816652.79793 +3603 3590 -3200272.15248 +3604 3590 -27430311.52865 +3605 3590 99884455.60809 +3606 3590 -26687654.83973 +3607 3590 14949530.76392 +3608 3590 -20428342.61214 +3684 3590 13679279.97901 +3685 3590 -12543431.97403 +3686 3590 -15345455.6363 +3687 3590 80261824.7461 +3688 3590 -6857580.506883 +3689 3590 -101938662.0149 +3690 3590 26537352.8999 +3691 3590 19401012.48091 +3692 3590 -57405640.83529 +3696 3590 571474.7733671 +3697 3590 -51408102.87125 +3698 3590 -18348781.1507 +3699 3590 2285899.092361 +3700 3590 -27430322.01402 +3701 3590 -242725472.4512 +3702 3590 571474.773379 +3703 3590 78838424.88527 +3704 3590 -190201211.678 +3711 3590 -14250754.75238 +3712 3590 -13229195.86314 +3713 3590 -17306764.74188 +3714 3590 -82547723.83843 +3715 3590 -6857580.506883 +3716 3590 -113395588.2476 +3717 3590 -27108827.67327 +3718 3590 20086776.37002 +3719 3590 -61172794.84886 +3591 3591 1185266328.887 +3592 3591 62540241.42204 +3593 3591 30860066.01788 +3594 3591 30368144.44572 +3595 3591 -62516096.56266 +3596 3591 27037674.41794 +3603 3591 -90421354.05518 +3604 3591 -62499999.98975 +3605 3591 24401754.87359 +3606 3591 -224004433.2424 +3607 3591 3.09944152832e-06 +3608 3591 -5943327.707585 +3609 3591 -91775737.73549 +3610 3591 62499999.98974 +3611 3591 -27030536.78462 +3687 3591 -26783317.53868 +3688 3591 15625000.00513 +3689 3591 13679279.97901 +3690 3591 -119411159.8837 +3691 3591 -15630523.23252 +3692 3591 75186254.88774 +3699 3591 16426910.05153 +3700 3591 4.485249519348e-06 +3701 3591 571474.7733669 +3702 3591 109890622.1535 +3703 3591 15634205.38412 +3704 3591 7712478.882864 +3705 3591 -60563825.20041 +3706 3591 -15628682.15673 +3707 3591 27115214.46942 +3714 3591 -27518808.45327 +3715 3591 -15625000.00513 +3716 3591 -14250754.75238 +3717 3591 -107888591.8846 +3718 3591 1.713633537292e-06 +3719 3591 -82890605.78265 +3720 3591 -43968569.74338 +3721 3591 15625000.00513 +3722 3591 -27108827.67327 +3592 3592 1016491380.459 +3593 3592 -85033469.8302 +3594 3592 -62524144.84912 +3595 3592 -188413029.0158 +3596 3592 46636948.6184 +3603 3592 -62499999.98975 +3604 3592 -71670594.15271 +3605 3592 12206475.20882 +3606 3592 3.695487976074e-06 +3607 3592 50996827.03073 +3608 3592 -27430311.52865 +3609 3592 62499999.98974 +3610 3592 -73024977.83304 +3611 3592 15223836.31984 +3687 3592 15625000.00513 +3688 3592 -22095635.7235 +3689 3592 -12543431.97403 +3690 3592 -15628682.15673 +3691 3592 -45961669.68301 +3692 3592 8705839.731277 +3699 3592 5.781650543213e-06 +3700 3592 -42948027.89108 +3701 3592 -51682408.42662 +3702 3592 15634205.38412 +3703 3592 67697343.25408 +3704 3592 -21260405.06448 +3705 3592 -15630523.23252 +3706 3592 -115258445.5683 +3707 3592 76792017.46155 +3714 3592 -15625000.00513 +3715 3592 -22831126.63809 +3716 3592 -13229195.86314 +3717 3592 1.668930053711e-06 +3718 3592 -39138290.32084 +3719 3592 -6857580.506883 +3720 3592 15625000.00513 +3721 3592 -39280887.92821 +3722 3592 20086776.37002 +3593 3593 1141730954.706 +3594 3593 26698361.28971 +3595 3593 52125943.97254 +3596 3593 56705174.06508 +3603 3593 24744636.81848 +3604 3593 12480780.76473 +3605 3593 -16816652.79793 +3606 3593 -3200272.15248 +3607 3593 -27430311.52865 +3608 3593 99884455.60809 +3609 3593 -26687654.83973 +3610 3593 14949530.76392 +3611 3593 -20428342.61214 +3687 3593 13679279.97901 +3688 3593 -12543431.97403 +3689 3593 -15345455.6363 +3690 3593 74842632.24213 +3691 3593 6787043.609902 +3692 3593 -88003520.09856 +3699 3593 571474.7733671 +3700 3593 -51408102.87125 +3701 3593 -18348781.1507 +3702 3593 7717283.578221 +3703 3593 -21256561.34093 +3704 3593 -211698416.8248 +3705 3593 27118407.8675 +3706 3593 78438470.16785 +3707 3593 -167573319.7819 +3714 3593 -14250754.75238 +3715 3593 -13229195.86314 +3716 3593 -17306764.74188 +3717 3593 -82547723.83843 +3718 3593 -6857580.506883 +3719 3593 -113395588.2476 +3720 3593 -27108827.67327 +3721 3593 20086776.37002 +3722 3593 -61172794.84886 +3594 3594 698751952.167 +3595 3594 62499999.98975 +3596 3594 33160993.85051 +3606 3594 -90421354.05518 +3607 3594 -62499999.98975 +3608 3594 24401754.87359 +3609 3594 -337915744.7523 +3610 3594 -62516096.56266 +3611 3594 -27668847.19038 +3612 3594 13308405.80675 +3613 3594 50016096.56471 +3614 3594 -19894290.40682 +3690 3594 789479.8663111 +3691 3594 18755523.23355 +3692 3594 16762853.88037 +3702 3594 -11151323.14121 +3703 3594 -15630523.23252 +3704 3594 -13684113.02055 +3705 3594 50455843.08525 +3706 3594 15625000.00514 +3707 3594 23750485.45243 +3717 3594 -27518808.45327 +3718 3594 -15625000.00513 +3719 3594 -14250754.75238 +3720 3594 -136601119.3265 +3721 3594 -15628682.15673 +3722 3594 -88333821.76341 +3723 3594 -31442472.41633 +3724 3594 12503682.1557 +3725 3594 -21464859.02542 +3595 3595 604980043.3115 +3596 3595 -63103934.68082 +3606 3595 -62499999.98975 +3607 3595 -71670594.15271 +3608 3595 12206475.20882 +3609 3595 -62524144.84911 +3610 3595 -44113422.33778 +3611 3595 -38272833.23799 +3612 3595 75024144.84706 +3613 3595 13308405.80675 +3614 3595 25517746.91897 +3690 3595 12503682.1557 +3691 3595 789479.8663122 +3692 3595 -8940185.539224 +3702 3595 -15628682.15672 +3703 3595 -65845943.5091 +3704 3595 -52101581.10086 +3705 3595 15625000.00514 +3706 3595 27013291.43733 +3707 3595 -3407345.083582 +3717 3595 -15625000.00513 +3718 3595 -22831126.63809 +3719 3595 -13229195.86314 +3720 3595 -15630523.23252 +3721 3595 -63151629.12586 +3722 3595 -25854695.88552 +3723 3595 18755523.23355 +3724 3595 -31442472.41633 +3725 3595 25757502.85539 +3596 3596 741587115.0734 +3606 3596 24744636.81848 +3607 3596 12480780.76473 +3608 3596 -16816652.79793 +3609 3596 -24922773.86031 +3610 3596 -30315528.70936 +3611 3596 20612357.80692 +3612 3596 -29841435.61023 +3613 3596 17011831.27931 +3614 3596 35489082.15132 +3690 3596 11175235.92025 +3691 3596 -13410278.30884 +3692 3596 2105279.643495 +3702 3596 -13682502.0067 +3703 3596 -53748034.02747 +3704 3596 -35806647.62401 +3705 3596 -8884805.348678 +3706 3596 -29515355.2492 +3707 3596 -145884263.2499 +3717 3596 -14250754.75238 +3718 3596 -13229195.86314 +3719 3596 -17306764.74188 +3720 3596 -87990199.11779 +3721 3596 -23932056.04702 +3722 3596 -133843411.9462 +3723 3596 -32197288.53812 +3724 3596 17171668.57026 +3725 3596 -83846593.11021 +3597 3597 1104842790.893 +3598 3597 1.609325408936e-05 +3599 3597 9143599.859988 +3600 3597 135775801.5773 +3601 3597 -6.794929504395e-06 +3602 3597 2285899.966128 +3615 3597 -224004433.2424 +3616 3597 3.09944152832e-06 +3617 3597 -5943327.707585 +3618 3597 -91775737.73549 +3619 3597 62499999.98974 +3620 3597 -27030536.78462 +3693 3597 -103592244.5474 +3694 3597 1.892447471619e-06 +3695 3597 80604706.69032 +3696 3597 -42555886.98831 +3697 3597 -15625000.00514 +3698 3597 26537352.8999 +3708 3597 77208121.14848 +3709 3597 3.09944152832e-06 +3710 3597 2285899.092361 +3711 3597 -48017751.39621 +3712 3597 -8.776783943176e-06 +3713 3597 571474.7733788 +3726 3597 -107888591.8846 +3727 3597 1.713633537292e-06 +3728 3597 -82890605.78265 +3729 3597 -43968569.74338 +3730 3597 15625000.00513 +3731 3597 -27108827.67327 +3598 3598 954836711.7471 +3599 3598 -109721246.0606 +3600 3598 -6.705522537231e-06 +3601 3598 -101723938.9279 +3602 3598 55957845.25232 +3615 3598 3.695487976074e-06 +3616 3598 50996827.03073 +3617 3598 -27430311.52865 +3618 3598 62499999.98974 +3619 3598 -73024977.83304 +3620 3598 15223836.31984 +3693 3598 -9.983777999878e-07 +3694 3598 -34841942.9836 +3695 3598 -6857580.506883 +3696 3598 -15625000.00514 +3697 3598 -37868205.17313 +3698 3598 19401012.48091 +3708 3598 3.09944152832e-06 +3709 3598 39706666.64553 +3710 3598 -27430322.01402 +3711 3598 -7.04824924469e-06 +3712 3598 -107392689.3388 +3713 3598 79112730.44064 +3726 3598 1.668930053711e-06 +3727 3598 -39138290.32084 +3728 3598 -6857580.506883 +3729 3598 15625000.00513 +3730 3598 -39280887.92821 +3731 3598 20086776.37002 +3599 3599 1151791779.138 +3600 3599 2285899.966128 +3601 3599 53763400.80823 +3602 3599 113453108.8746 +3615 3599 -3200272.15248 +3616 3599 -27430311.52865 +3617 3599 99884455.60809 +3618 3599 -26687654.83973 +3619 3599 14949530.76392 +3620 3599 -20428342.61214 +3693 3599 80261824.7461 +3694 3599 -6857580.506883 +3695 3599 -101938662.0149 +3696 3599 26537352.8999 +3697 3599 19401012.48091 +3698 3599 -57405640.83529 +3708 3599 2285899.092361 +3709 3599 -27430322.01402 +3710 3599 -242725472.4512 +3711 3599 571474.773379 +3712 3599 78838424.88527 +3713 3599 -190201211.678 +3726 3599 -82547723.83843 +3727 3599 -6857580.506883 +3728 3599 -113395588.2476 +3729 3599 -27108827.67327 +3730 3599 20086776.37002 +3731 3599 -61172794.84886 +3600 3600 1104842790.893 +3601 3600 1.609325408936e-05 +3602 3600 9143599.859988 +3603 3600 135775801.5773 +3604 3600 -6.794929504395e-06 +3605 3600 2285899.966128 +3615 3600 -90421354.05518 +3616 3600 -62499999.98975 +3617 3600 24401754.87359 +3618 3600 -224004433.2424 +3619 3600 3.09944152832e-06 +3620 3600 -5943327.707585 +3621 3600 -91775737.73549 +3622 3600 62499999.98974 +3623 3600 -27030536.78462 +3693 3600 -26783317.53868 +3694 3600 15625000.00513 +3695 3600 13679279.97901 +3696 3600 -103592244.5474 +3697 3600 1.892447471619e-06 +3698 3600 80604706.69032 +3699 3600 -42555886.98831 +3700 3600 -15625000.00514 +3701 3600 26537352.8999 +3708 3600 16426910.05153 +3709 3600 4.485249519348e-06 +3710 3600 571474.7733669 +3711 3600 77208121.14848 +3712 3600 3.09944152832e-06 +3713 3600 2285899.092361 +3714 3600 -48017751.39621 +3715 3600 -8.776783943176e-06 +3716 3600 571474.7733788 +3726 3600 -27518808.45327 +3727 3600 -15625000.00513 +3728 3600 -14250754.75238 +3729 3600 -107888591.8846 +3730 3600 1.713633537292e-06 +3731 3600 -82890605.78265 +3732 3600 -43968569.74338 +3733 3600 15625000.00513 +3734 3600 -27108827.67327 +3601 3601 954836711.7471 +3602 3601 -109721246.0606 +3603 3601 -6.705522537231e-06 +3604 3601 -101723938.9279 +3605 3601 55957845.25232 +3615 3601 -62499999.98975 +3616 3601 -71670594.15271 +3617 3601 12206475.20882 +3618 3601 3.695487976074e-06 +3619 3601 50996827.03073 +3620 3601 -27430311.52865 +3621 3601 62499999.98974 +3622 3601 -73024977.83304 +3623 3601 15223836.31984 +3693 3601 15625000.00513 +3694 3601 -22095635.7235 +3695 3601 -12543431.97403 +3696 3601 -9.983777999878e-07 +3697 3601 -34841942.9836 +3698 3601 -6857580.506883 +3699 3601 -15625000.00514 +3700 3601 -37868205.17313 +3701 3601 19401012.48091 +3708 3601 5.781650543213e-06 +3709 3601 -42948027.89108 +3710 3601 -51682408.42662 +3711 3601 3.09944152832e-06 +3712 3601 39706666.64553 +3713 3601 -27430322.01402 +3714 3601 -7.04824924469e-06 +3715 3601 -107392689.3388 +3716 3601 79112730.44064 +3726 3601 -15625000.00513 +3727 3601 -22831126.63809 +3728 3601 -13229195.86314 +3729 3601 1.668930053711e-06 +3730 3601 -39138290.32084 +3731 3601 -6857580.506883 +3732 3601 15625000.00513 +3733 3601 -39280887.92821 +3734 3601 20086776.37002 +3602 3602 1151791779.138 +3603 3602 2285899.966128 +3604 3602 53763400.80823 +3605 3602 113453108.8746 +3615 3602 24744636.81848 +3616 3602 12480780.76473 +3617 3602 -16816652.79793 +3618 3602 -3200272.15248 +3619 3602 -27430311.52865 +3620 3602 99884455.60809 +3621 3602 -26687654.83973 +3622 3602 14949530.76392 +3623 3602 -20428342.61214 +3693 3602 13679279.97901 +3694 3602 -12543431.97403 +3695 3602 -15345455.6363 +3696 3602 80261824.7461 +3697 3602 -6857580.506883 +3698 3602 -101938662.0149 +3699 3602 26537352.8999 +3700 3602 19401012.48091 +3701 3602 -57405640.83529 +3708 3602 571474.7733671 +3709 3602 -51408102.87125 +3710 3602 -18348781.1507 +3711 3602 2285899.092361 +3712 3602 -27430322.01402 +3713 3602 -242725472.4512 +3714 3602 571474.773379 +3715 3602 78838424.88527 +3716 3602 -190201211.678 +3726 3602 -14250754.75238 +3727 3602 -13229195.86314 +3728 3602 -17306764.74188 +3729 3602 -82547723.83843 +3730 3602 -6857580.506883 +3731 3602 -113395588.2476 +3732 3602 -27108827.67327 +3733 3602 20086776.37002 +3734 3602 -61172794.84886 +3603 3603 1104842790.893 +3604 3603 1.609325408936e-05 +3605 3603 9143599.859988 +3606 3603 135775801.5773 +3607 3603 -6.794929504395e-06 +3608 3603 2285899.966128 +3618 3603 -90421354.05518 +3619 3603 -62499999.98975 +3620 3603 24401754.87359 +3621 3603 -224004433.2424 +3622 3603 3.09944152832e-06 +3623 3603 -5943327.707585 +3624 3603 -91775737.73549 +3625 3603 62499999.98974 +3626 3603 -27030536.78462 +3696 3603 -26783317.53868 +3697 3603 15625000.00513 +3698 3603 13679279.97901 +3699 3603 -103592244.5474 +3700 3603 1.892447471619e-06 +3701 3603 80604706.69032 +3702 3603 -42555886.98831 +3703 3603 -15625000.00514 +3704 3603 26537352.8999 +3711 3603 16426910.05153 +3712 3603 4.485249519348e-06 +3713 3603 571474.7733669 +3714 3603 77208121.14848 +3715 3603 3.09944152832e-06 +3716 3603 2285899.092361 +3717 3603 -48017751.39621 +3718 3603 -8.776783943176e-06 +3719 3603 571474.7733788 +3729 3603 -27518808.45327 +3730 3603 -15625000.00513 +3731 3603 -14250754.75238 +3732 3603 -107888591.8846 +3733 3603 1.713633537292e-06 +3734 3603 -82890605.78265 +3735 3603 -43968569.74338 +3736 3603 15625000.00513 +3737 3603 -27108827.67327 +3604 3604 954836711.7471 +3605 3604 -109721246.0606 +3606 3604 -6.705522537231e-06 +3607 3604 -101723938.9279 +3608 3604 55957845.25232 +3618 3604 -62499999.98975 +3619 3604 -71670594.15271 +3620 3604 12206475.20882 +3621 3604 3.695487976074e-06 +3622 3604 50996827.03073 +3623 3604 -27430311.52865 +3624 3604 62499999.98974 +3625 3604 -73024977.83304 +3626 3604 15223836.31984 +3696 3604 15625000.00513 +3697 3604 -22095635.7235 +3698 3604 -12543431.97403 +3699 3604 -9.983777999878e-07 +3700 3604 -34841942.9836 +3701 3604 -6857580.506883 +3702 3604 -15625000.00514 +3703 3604 -37868205.17313 +3704 3604 19401012.48091 +3711 3604 5.781650543213e-06 +3712 3604 -42948027.89108 +3713 3604 -51682408.42662 +3714 3604 3.09944152832e-06 +3715 3604 39706666.64553 +3716 3604 -27430322.01402 +3717 3604 -7.04824924469e-06 +3718 3604 -107392689.3388 +3719 3604 79112730.44064 +3729 3604 -15625000.00513 +3730 3604 -22831126.63809 +3731 3604 -13229195.86314 +3732 3604 1.668930053711e-06 +3733 3604 -39138290.32084 +3734 3604 -6857580.506883 +3735 3604 15625000.00513 +3736 3604 -39280887.92821 +3737 3604 20086776.37002 +3605 3605 1151791779.138 +3606 3605 2285899.966128 +3607 3605 53763400.80823 +3608 3605 113453108.8746 +3618 3605 24744636.81848 +3619 3605 12480780.76473 +3620 3605 -16816652.79793 +3621 3605 -3200272.15248 +3622 3605 -27430311.52865 +3623 3605 99884455.60809 +3624 3605 -26687654.83973 +3625 3605 14949530.76392 +3626 3605 -20428342.61214 +3696 3605 13679279.97901 +3697 3605 -12543431.97403 +3698 3605 -15345455.6363 +3699 3605 80261824.7461 +3700 3605 -6857580.506883 +3701 3605 -101938662.0149 +3702 3605 26537352.8999 +3703 3605 19401012.48091 +3704 3605 -57405640.83529 +3711 3605 571474.7733671 +3712 3605 -51408102.87125 +3713 3605 -18348781.1507 +3714 3605 2285899.092361 +3715 3605 -27430322.01402 +3716 3605 -242725472.4512 +3717 3605 571474.773379 +3718 3605 78838424.88527 +3719 3605 -190201211.678 +3729 3605 -14250754.75238 +3730 3605 -13229195.86314 +3731 3605 -17306764.74188 +3732 3605 -82547723.83843 +3733 3605 -6857580.506883 +3734 3605 -113395588.2476 +3735 3605 -27108827.67327 +3736 3605 20086776.37002 +3737 3605 -61172794.84886 +3606 3606 1104842790.893 +3607 3606 1.609325408936e-05 +3608 3606 9143599.859988 +3609 3606 135775801.5773 +3610 3606 -6.794929504395e-06 +3611 3606 2285899.966128 +3621 3606 -90421354.05518 +3622 3606 -62499999.98975 +3623 3606 24401754.87359 +3624 3606 -224004433.2424 +3625 3606 3.09944152832e-06 +3626 3606 -5943327.707585 +3627 3606 -91775737.73549 +3628 3606 62499999.98974 +3629 3606 -27030536.78462 +3699 3606 -26783317.53868 +3700 3606 15625000.00513 +3701 3606 13679279.97901 +3702 3606 -103592244.5474 +3703 3606 1.892447471619e-06 +3704 3606 80604706.69032 +3705 3606 -42555886.98831 +3706 3606 -15625000.00514 +3707 3606 26537352.8999 +3714 3606 16426910.05153 +3715 3606 4.485249519348e-06 +3716 3606 571474.7733669 +3717 3606 77208121.14848 +3718 3606 3.09944152832e-06 +3719 3606 2285899.092361 +3720 3606 -48017751.39621 +3721 3606 -8.776783943176e-06 +3722 3606 571474.7733788 +3732 3606 -27518808.45327 +3733 3606 -15625000.00513 +3734 3606 -14250754.75238 +3735 3606 -107888591.8846 +3736 3606 1.713633537292e-06 +3737 3606 -82890605.78265 +3738 3606 -43968569.74338 +3739 3606 15625000.00513 +3740 3606 -27108827.67327 +3607 3607 954836711.7471 +3608 3607 -109721246.0606 +3609 3607 -6.705522537231e-06 +3610 3607 -101723938.9279 +3611 3607 55957845.25232 +3621 3607 -62499999.98975 +3622 3607 -71670594.15271 +3623 3607 12206475.20882 +3624 3607 3.695487976074e-06 +3625 3607 50996827.03073 +3626 3607 -27430311.52865 +3627 3607 62499999.98974 +3628 3607 -73024977.83304 +3629 3607 15223836.31984 +3699 3607 15625000.00513 +3700 3607 -22095635.7235 +3701 3607 -12543431.97403 +3702 3607 -9.983777999878e-07 +3703 3607 -34841942.9836 +3704 3607 -6857580.506883 +3705 3607 -15625000.00514 +3706 3607 -37868205.17313 +3707 3607 19401012.48091 +3714 3607 5.781650543213e-06 +3715 3607 -42948027.89108 +3716 3607 -51682408.42662 +3717 3607 3.09944152832e-06 +3718 3607 39706666.64553 +3719 3607 -27430322.01402 +3720 3607 -7.04824924469e-06 +3721 3607 -107392689.3388 +3722 3607 79112730.44064 +3732 3607 -15625000.00513 +3733 3607 -22831126.63809 +3734 3607 -13229195.86314 +3735 3607 1.668930053711e-06 +3736 3607 -39138290.32084 +3737 3607 -6857580.506883 +3738 3607 15625000.00513 +3739 3607 -39280887.92821 +3740 3607 20086776.37002 +3608 3608 1151791779.138 +3609 3608 2285899.966128 +3610 3608 53763400.80823 +3611 3608 113453108.8746 +3621 3608 24744636.81848 +3622 3608 12480780.76473 +3623 3608 -16816652.79793 +3624 3608 -3200272.15248 +3625 3608 -27430311.52865 +3626 3608 99884455.60809 +3627 3608 -26687654.83973 +3628 3608 14949530.76392 +3629 3608 -20428342.61214 +3699 3608 13679279.97901 +3700 3608 -12543431.97403 +3701 3608 -15345455.6363 +3702 3608 80261824.7461 +3703 3608 -6857580.506883 +3704 3608 -101938662.0149 +3705 3608 26537352.8999 +3706 3608 19401012.48091 +3707 3608 -57405640.83529 +3714 3608 571474.7733671 +3715 3608 -51408102.87125 +3716 3608 -18348781.1507 +3717 3608 2285899.092361 +3718 3608 -27430322.01402 +3719 3608 -242725472.4512 +3720 3608 571474.773379 +3721 3608 78838424.88527 +3722 3608 -190201211.678 +3732 3608 -14250754.75238 +3733 3608 -13229195.86314 +3734 3608 -17306764.74188 +3735 3608 -82547723.83843 +3736 3608 -6857580.506883 +3737 3608 -113395588.2476 +3738 3608 -27108827.67327 +3739 3608 20086776.37002 +3740 3608 -61172794.84886 +3609 3609 1185266328.887 +3610 3609 62540241.42204 +3611 3609 30860066.01788 +3612 3609 30368144.44572 +3613 3609 -62516096.56266 +3614 3609 27037674.41794 +3624 3609 -90421354.05518 +3625 3609 -62499999.98975 +3626 3609 24401754.87359 +3627 3609 -224004433.2424 +3628 3609 3.09944152832e-06 +3629 3609 -5943327.707585 +3630 3609 -91775737.73549 +3631 3609 62499999.98974 +3632 3609 -27030536.78462 +3702 3609 -26783317.53868 +3703 3609 15625000.00513 +3704 3609 13679279.97901 +3705 3609 -119411159.8837 +3706 3609 -15630523.23252 +3707 3609 75186254.88774 +3717 3609 16426910.05153 +3718 3609 4.485249519348e-06 +3719 3609 571474.7733669 +3720 3609 109890622.1535 +3721 3609 15634205.38412 +3722 3609 7712478.882864 +3723 3609 -60563825.20041 +3724 3609 -15628682.15673 +3725 3609 27115214.46942 +3735 3609 -27518808.45327 +3736 3609 -15625000.00513 +3737 3609 -14250754.75238 +3738 3609 -107888591.8846 +3739 3609 1.713633537292e-06 +3740 3609 -82890605.78265 +3741 3609 -43968569.74338 +3742 3609 15625000.00513 +3743 3609 -27108827.67327 +3610 3610 1016491380.459 +3611 3610 -85033469.8302 +3612 3610 -62524144.84912 +3613 3610 -188413029.0158 +3614 3610 46636948.6184 +3624 3610 -62499999.98975 +3625 3610 -71670594.15271 +3626 3610 12206475.20882 +3627 3610 3.695487976074e-06 +3628 3610 50996827.03073 +3629 3610 -27430311.52865 +3630 3610 62499999.98974 +3631 3610 -73024977.83304 +3632 3610 15223836.31984 +3702 3610 15625000.00513 +3703 3610 -22095635.7235 +3704 3610 -12543431.97403 +3705 3610 -15628682.15673 +3706 3610 -45961669.68301 +3707 3610 8705839.731277 +3717 3610 5.781650543213e-06 +3718 3610 -42948027.89108 +3719 3610 -51682408.42662 +3720 3610 15634205.38412 +3721 3610 67697343.25408 +3722 3610 -21260405.06448 +3723 3610 -15630523.23252 +3724 3610 -115258445.5683 +3725 3610 76792017.46155 +3735 3610 -15625000.00513 +3736 3610 -22831126.63809 +3737 3610 -13229195.86314 +3738 3610 1.668930053711e-06 +3739 3610 -39138290.32084 +3740 3610 -6857580.506883 +3741 3610 15625000.00513 +3742 3610 -39280887.92821 +3743 3610 20086776.37002 +3611 3611 1141730954.706 +3612 3611 26698361.28971 +3613 3611 52125943.97254 +3614 3611 56705174.06508 +3624 3611 24744636.81848 +3625 3611 12480780.76473 +3626 3611 -16816652.79793 +3627 3611 -3200272.15248 +3628 3611 -27430311.52865 +3629 3611 99884455.60809 +3630 3611 -26687654.83973 +3631 3611 14949530.76392 +3632 3611 -20428342.61214 +3702 3611 13679279.97901 +3703 3611 -12543431.97403 +3704 3611 -15345455.6363 +3705 3611 74842632.24213 +3706 3611 6787043.609902 +3707 3611 -88003520.09856 +3717 3611 571474.7733671 +3718 3611 -51408102.87125 +3719 3611 -18348781.1507 +3720 3611 7717283.578221 +3721 3611 -21256561.34093 +3722 3611 -211698416.8248 +3723 3611 27118407.8675 +3724 3611 78438470.16785 +3725 3611 -167573319.7819 +3735 3611 -14250754.75238 +3736 3611 -13229195.86314 +3737 3611 -17306764.74188 +3738 3611 -82547723.83843 +3739 3611 -6857580.506883 +3740 3611 -113395588.2476 +3741 3611 -27108827.67327 +3742 3611 20086776.37002 +3743 3611 -61172794.84886 +3612 3612 677400133.3289 +3613 3612 57041619.96368 +3614 3612 -10754501.96958 +3627 3612 -90421354.05518 +3628 3612 -62499999.98975 +3629 3612 24401754.87359 +3630 3612 -325398175.4315 +3631 3612 -57073776.75131 +3632 3612 -1587457.988453 +3633 3612 20401810.48982 +3634 3612 50032156.77943 +3635 3612 -2745688.895618 +3705 3612 789479.8663111 +3706 3612 18755523.23355 +3707 3612 16762853.88037 +3720 3612 -11151323.14121 +3721 3612 -15630523.23252 +3722 3612 -13684113.02055 +3723 3612 47191822.66489 +3724 3612 14946498.26301 +3725 3612 13014221.82389 +3738 3612 -27518808.45327 +3739 3612 -15625000.00513 +3740 3612 -14250754.75238 +3741 3612 -128111353.7422 +3742 3612 -14954029.75625 +3743 3612 -81018857.78974 +3744 3612 -15349095.37302 +3745 3612 12507531.49735 +3746 3612 -16659255.21042 +3613 3613 590623589.3511 +3614 3613 -62444456.30045 +3627 3613 -62499999.98975 +3628 3613 -71670594.15271 +3629 3613 12206475.20882 +3630 3613 -57089855.14513 +3631 3613 -34005965.86669 +3632 3613 -16859606.35942 +3633 3613 75048235.16915 +3634 3613 15816558.46177 +3635 3613 4543067.024131 +3705 3613 12503682.1557 +3706 3613 789479.8663122 +3707 3613 -8940185.539224 +3720 3613 -15628682.15672 +3721 3613 -65845943.5091 +3722 3613 -52101581.10086 +3723 3613 14946498.263 +3724 3613 24602513.67136 +3725 3613 -3350281.619218 +3738 3613 -15625000.00513 +3739 3613 -22831126.63809 +3740 3613 -13229195.86314 +3741 3613 -14957795.50287 +3742 3613 -54956148.79942 +3743 3613 -19999621.90016 +3744 3613 18761297.24603 +3745 3613 -15908052.76959 +3746 3613 20964116.01977 +3614 3614 709279085.6458 +3627 3614 24744636.81848 +3628 3614 12480780.76473 +3629 3614 -16816652.79793 +3630 3614 -7758437.967454 +3631 3614 -15761657.05467 +3632 3614 24777136.49351 +3633 3614 -4118533.343426 +3634 3614 3445519.29042 +3635 3614 58990080.00089 +3705 3614 11175235.92025 +3706 3614 -13410278.30884 +3707 3614 2105279.643495 +3720 3614 -13682502.0067 +3721 3614 -53748034.02747 +3722 3614 -35806647.62401 +3723 3614 -19273894.57614 +3724 3614 -29176868.80117 +3725 3614 -151535111.2545 +3738 3614 -14250754.75238 +3739 3614 -13229195.86314 +3740 3614 -17306764.74188 +3741 3614 -82733059.37263 +3742 3614 -19721218.30569 +3743 3614 -114816200.9011 +3744 3614 -24988882.81563 +3745 3614 14300470.30205 +3746 3614 -40371963.59817 +3615 3615 1104842790.893 +3616 3615 1.609325408936e-05 +3617 3615 9143599.859988 +3618 3615 135775801.5773 +3619 3615 -6.794929504395e-06 +3620 3615 2285899.966128 +3636 3615 -224004433.2424 +3637 3615 3.09944152832e-06 +3638 3615 -5943327.707585 +3639 3615 -91775737.73549 +3640 3615 62499999.98974 +3641 3615 -27030536.78462 +3708 3615 -103592244.5474 +3709 3615 1.892447471619e-06 +3710 3615 80604706.69032 +3711 3615 -42555886.98831 +3712 3615 -15625000.00514 +3713 3615 26537352.8999 +3726 3615 77208121.14848 +3727 3615 3.09944152832e-06 +3728 3615 2285899.092361 +3729 3615 -48017751.39621 +3730 3615 -8.776783943176e-06 +3731 3615 571474.7733788 +3747 3615 -107888591.8846 +3748 3615 1.713633537292e-06 +3749 3615 -82890605.78265 +3750 3615 -43968569.74338 +3751 3615 15625000.00513 +3752 3615 -27108827.67327 +3616 3616 954836711.7471 +3617 3616 -109721246.0606 +3618 3616 -6.705522537231e-06 +3619 3616 -101723938.9279 +3620 3616 55957845.25232 +3636 3616 3.695487976074e-06 +3637 3616 50996827.03073 +3638 3616 -27430311.52865 +3639 3616 62499999.98974 +3640 3616 -73024977.83304 +3641 3616 15223836.31984 +3708 3616 -9.983777999878e-07 +3709 3616 -34841942.9836 +3710 3616 -6857580.506883 +3711 3616 -15625000.00514 +3712 3616 -37868205.17313 +3713 3616 19401012.48091 +3726 3616 3.09944152832e-06 +3727 3616 39706666.64553 +3728 3616 -27430322.01402 +3729 3616 -7.04824924469e-06 +3730 3616 -107392689.3388 +3731 3616 79112730.44064 +3747 3616 1.668930053711e-06 +3748 3616 -39138290.32084 +3749 3616 -6857580.506883 +3750 3616 15625000.00513 +3751 3616 -39280887.92821 +3752 3616 20086776.37002 +3617 3617 1151791779.138 +3618 3617 2285899.966128 +3619 3617 53763400.80823 +3620 3617 113453108.8746 +3636 3617 -3200272.15248 +3637 3617 -27430311.52865 +3638 3617 99884455.60809 +3639 3617 -26687654.83973 +3640 3617 14949530.76392 +3641 3617 -20428342.61214 +3708 3617 80261824.7461 +3709 3617 -6857580.506883 +3710 3617 -101938662.0149 +3711 3617 26537352.8999 +3712 3617 19401012.48091 +3713 3617 -57405640.83529 +3726 3617 2285899.092361 +3727 3617 -27430322.01402 +3728 3617 -242725472.4512 +3729 3617 571474.773379 +3730 3617 78838424.88527 +3731 3617 -190201211.678 +3747 3617 -82547723.83843 +3748 3617 -6857580.506883 +3749 3617 -113395588.2476 +3750 3617 -27108827.67327 +3751 3617 20086776.37002 +3752 3617 -61172794.84886 +3618 3618 1104842790.893 +3619 3618 1.609325408936e-05 +3620 3618 9143599.859988 +3621 3618 135775801.5773 +3622 3618 -6.794929504395e-06 +3623 3618 2285899.966128 +3636 3618 -90421354.05518 +3637 3618 -62499999.98975 +3638 3618 24401754.87359 +3639 3618 -224004433.2424 +3640 3618 3.09944152832e-06 +3641 3618 -5943327.707585 +3642 3618 -91775737.73549 +3643 3618 62499999.98974 +3644 3618 -27030536.78462 +3708 3618 -26783317.53868 +3709 3618 15625000.00513 +3710 3618 13679279.97901 +3711 3618 -103592244.5474 +3712 3618 1.892447471619e-06 +3713 3618 80604706.69032 +3714 3618 -42555886.98831 +3715 3618 -15625000.00514 +3716 3618 26537352.8999 +3726 3618 16426910.05153 +3727 3618 4.485249519348e-06 +3728 3618 571474.7733669 +3729 3618 77208121.14848 +3730 3618 3.09944152832e-06 +3731 3618 2285899.092361 +3732 3618 -48017751.39621 +3733 3618 -8.776783943176e-06 +3734 3618 571474.7733788 +3747 3618 -27518808.45327 +3748 3618 -15625000.00513 +3749 3618 -14250754.75238 +3750 3618 -107888591.8846 +3751 3618 1.713633537292e-06 +3752 3618 -82890605.78265 +3753 3618 -43968569.74338 +3754 3618 15625000.00513 +3755 3618 -27108827.67327 +3619 3619 954836711.7471 +3620 3619 -109721246.0606 +3621 3619 -6.705522537231e-06 +3622 3619 -101723938.9279 +3623 3619 55957845.25232 +3636 3619 -62499999.98975 +3637 3619 -71670594.15271 +3638 3619 12206475.20882 +3639 3619 3.695487976074e-06 +3640 3619 50996827.03073 +3641 3619 -27430311.52865 +3642 3619 62499999.98974 +3643 3619 -73024977.83304 +3644 3619 15223836.31984 +3708 3619 15625000.00513 +3709 3619 -22095635.7235 +3710 3619 -12543431.97403 +3711 3619 -9.983777999878e-07 +3712 3619 -34841942.9836 +3713 3619 -6857580.506883 +3714 3619 -15625000.00514 +3715 3619 -37868205.17313 +3716 3619 19401012.48091 +3726 3619 5.781650543213e-06 +3727 3619 -42948027.89108 +3728 3619 -51682408.42662 +3729 3619 3.09944152832e-06 +3730 3619 39706666.64553 +3731 3619 -27430322.01402 +3732 3619 -7.04824924469e-06 +3733 3619 -107392689.3388 +3734 3619 79112730.44064 +3747 3619 -15625000.00513 +3748 3619 -22831126.63809 +3749 3619 -13229195.86314 +3750 3619 1.668930053711e-06 +3751 3619 -39138290.32084 +3752 3619 -6857580.506883 +3753 3619 15625000.00513 +3754 3619 -39280887.92821 +3755 3619 20086776.37002 +3620 3620 1151791779.138 +3621 3620 2285899.966128 +3622 3620 53763400.80823 +3623 3620 113453108.8746 +3636 3620 24744636.81848 +3637 3620 12480780.76473 +3638 3620 -16816652.79793 +3639 3620 -3200272.15248 +3640 3620 -27430311.52865 +3641 3620 99884455.60809 +3642 3620 -26687654.83973 +3643 3620 14949530.76392 +3644 3620 -20428342.61214 +3708 3620 13679279.97901 +3709 3620 -12543431.97403 +3710 3620 -15345455.6363 +3711 3620 80261824.7461 +3712 3620 -6857580.506883 +3713 3620 -101938662.0149 +3714 3620 26537352.8999 +3715 3620 19401012.48091 +3716 3620 -57405640.83529 +3726 3620 571474.7733671 +3727 3620 -51408102.87125 +3728 3620 -18348781.1507 +3729 3620 2285899.092361 +3730 3620 -27430322.01402 +3731 3620 -242725472.4512 +3732 3620 571474.773379 +3733 3620 78838424.88527 +3734 3620 -190201211.678 +3747 3620 -14250754.75238 +3748 3620 -13229195.86314 +3749 3620 -17306764.74188 +3750 3620 -82547723.83843 +3751 3620 -6857580.506883 +3752 3620 -113395588.2476 +3753 3620 -27108827.67327 +3754 3620 20086776.37002 +3755 3620 -61172794.84886 +3621 3621 1104842790.893 +3622 3621 1.609325408936e-05 +3623 3621 9143599.859988 +3624 3621 135775801.5773 +3625 3621 -6.794929504395e-06 +3626 3621 2285899.966128 +3639 3621 -90421354.05518 +3640 3621 -62499999.98975 +3641 3621 24401754.87359 +3642 3621 -224004433.2424 +3643 3621 3.09944152832e-06 +3644 3621 -5943327.707585 +3645 3621 -91775737.73549 +3646 3621 62499999.98974 +3647 3621 -27030536.78462 +3711 3621 -26783317.53868 +3712 3621 15625000.00513 +3713 3621 13679279.97901 +3714 3621 -103592244.5474 +3715 3621 1.892447471619e-06 +3716 3621 80604706.69032 +3717 3621 -42555886.98831 +3718 3621 -15625000.00514 +3719 3621 26537352.8999 +3729 3621 16426910.05153 +3730 3621 4.485249519348e-06 +3731 3621 571474.7733669 +3732 3621 77208121.14848 +3733 3621 3.09944152832e-06 +3734 3621 2285899.092361 +3735 3621 -48017751.39621 +3736 3621 -8.776783943176e-06 +3737 3621 571474.7733788 +3750 3621 -27518808.45327 +3751 3621 -15625000.00513 +3752 3621 -14250754.75238 +3753 3621 -107888591.8846 +3754 3621 1.713633537292e-06 +3755 3621 -82890605.78265 +3756 3621 -43968569.74338 +3757 3621 15625000.00513 +3758 3621 -27108827.67327 +3622 3622 954836711.7471 +3623 3622 -109721246.0606 +3624 3622 -6.705522537231e-06 +3625 3622 -101723938.9279 +3626 3622 55957845.25232 +3639 3622 -62499999.98975 +3640 3622 -71670594.15271 +3641 3622 12206475.20882 +3642 3622 3.695487976074e-06 +3643 3622 50996827.03073 +3644 3622 -27430311.52865 +3645 3622 62499999.98974 +3646 3622 -73024977.83304 +3647 3622 15223836.31984 +3711 3622 15625000.00513 +3712 3622 -22095635.7235 +3713 3622 -12543431.97403 +3714 3622 -9.983777999878e-07 +3715 3622 -34841942.9836 +3716 3622 -6857580.506883 +3717 3622 -15625000.00514 +3718 3622 -37868205.17313 +3719 3622 19401012.48091 +3729 3622 5.781650543213e-06 +3730 3622 -42948027.89108 +3731 3622 -51682408.42662 +3732 3622 3.09944152832e-06 +3733 3622 39706666.64553 +3734 3622 -27430322.01402 +3735 3622 -7.04824924469e-06 +3736 3622 -107392689.3388 +3737 3622 79112730.44064 +3750 3622 -15625000.00513 +3751 3622 -22831126.63809 +3752 3622 -13229195.86314 +3753 3622 1.668930053711e-06 +3754 3622 -39138290.32084 +3755 3622 -6857580.506883 +3756 3622 15625000.00513 +3757 3622 -39280887.92821 +3758 3622 20086776.37002 +3623 3623 1151791779.138 +3624 3623 2285899.966128 +3625 3623 53763400.80823 +3626 3623 113453108.8746 +3639 3623 24744636.81848 +3640 3623 12480780.76473 +3641 3623 -16816652.79793 +3642 3623 -3200272.15248 +3643 3623 -27430311.52865 +3644 3623 99884455.60809 +3645 3623 -26687654.83973 +3646 3623 14949530.76392 +3647 3623 -20428342.61214 +3711 3623 13679279.97901 +3712 3623 -12543431.97403 +3713 3623 -15345455.6363 +3714 3623 80261824.7461 +3715 3623 -6857580.506883 +3716 3623 -101938662.0149 +3717 3623 26537352.8999 +3718 3623 19401012.48091 +3719 3623 -57405640.83529 +3729 3623 571474.7733671 +3730 3623 -51408102.87125 +3731 3623 -18348781.1507 +3732 3623 2285899.092361 +3733 3623 -27430322.01402 +3734 3623 -242725472.4512 +3735 3623 571474.773379 +3736 3623 78838424.88527 +3737 3623 -190201211.678 +3750 3623 -14250754.75238 +3751 3623 -13229195.86314 +3752 3623 -17306764.74188 +3753 3623 -82547723.83843 +3754 3623 -6857580.506883 +3755 3623 -113395588.2476 +3756 3623 -27108827.67327 +3757 3623 20086776.37002 +3758 3623 -61172794.84886 +3624 3624 1104842790.893 +3625 3624 1.609325408936e-05 +3626 3624 9143599.859988 +3627 3624 135775801.5773 +3628 3624 -6.794929504395e-06 +3629 3624 2285899.966128 +3642 3624 -90421354.05518 +3643 3624 -62499999.98975 +3644 3624 24401754.87359 +3645 3624 -224004433.2424 +3646 3624 3.09944152832e-06 +3647 3624 -5943327.707585 +3648 3624 -91775737.73549 +3649 3624 62499999.98974 +3650 3624 -27030536.78462 +3714 3624 -26783317.53868 +3715 3624 15625000.00513 +3716 3624 13679279.97901 +3717 3624 -103592244.5474 +3718 3624 1.892447471619e-06 +3719 3624 80604706.69032 +3720 3624 -42555886.98831 +3721 3624 -15625000.00514 +3722 3624 26537352.8999 +3732 3624 16426910.05153 +3733 3624 4.485249519348e-06 +3734 3624 571474.7733669 +3735 3624 77208121.14848 +3736 3624 3.09944152832e-06 +3737 3624 2285899.092361 +3738 3624 -48017751.39621 +3739 3624 -8.776783943176e-06 +3740 3624 571474.7733788 +3753 3624 -27518808.45327 +3754 3624 -15625000.00513 +3755 3624 -14250754.75238 +3756 3624 -107888591.8846 +3757 3624 1.713633537292e-06 +3758 3624 -82890605.78265 +3759 3624 -43968569.74338 +3760 3624 15625000.00513 +3761 3624 -27108827.67327 +3625 3625 954836711.7471 +3626 3625 -109721246.0606 +3627 3625 -6.705522537231e-06 +3628 3625 -101723938.9279 +3629 3625 55957845.25232 +3642 3625 -62499999.98975 +3643 3625 -71670594.15271 +3644 3625 12206475.20882 +3645 3625 3.695487976074e-06 +3646 3625 50996827.03073 +3647 3625 -27430311.52865 +3648 3625 62499999.98974 +3649 3625 -73024977.83304 +3650 3625 15223836.31984 +3714 3625 15625000.00513 +3715 3625 -22095635.7235 +3716 3625 -12543431.97403 +3717 3625 -9.983777999878e-07 +3718 3625 -34841942.9836 +3719 3625 -6857580.506883 +3720 3625 -15625000.00514 +3721 3625 -37868205.17313 +3722 3625 19401012.48091 +3732 3625 5.781650543213e-06 +3733 3625 -42948027.89108 +3734 3625 -51682408.42662 +3735 3625 3.09944152832e-06 +3736 3625 39706666.64553 +3737 3625 -27430322.01402 +3738 3625 -7.04824924469e-06 +3739 3625 -107392689.3388 +3740 3625 79112730.44064 +3753 3625 -15625000.00513 +3754 3625 -22831126.63809 +3755 3625 -13229195.86314 +3756 3625 1.668930053711e-06 +3757 3625 -39138290.32084 +3758 3625 -6857580.506883 +3759 3625 15625000.00513 +3760 3625 -39280887.92821 +3761 3625 20086776.37002 +3626 3626 1151791779.138 +3627 3626 2285899.966128 +3628 3626 53763400.80823 +3629 3626 113453108.8746 +3642 3626 24744636.81848 +3643 3626 12480780.76473 +3644 3626 -16816652.79793 +3645 3626 -3200272.15248 +3646 3626 -27430311.52865 +3647 3626 99884455.60809 +3648 3626 -26687654.83973 +3649 3626 14949530.76392 +3650 3626 -20428342.61214 +3714 3626 13679279.97901 +3715 3626 -12543431.97403 +3716 3626 -15345455.6363 +3717 3626 80261824.7461 +3718 3626 -6857580.506883 +3719 3626 -101938662.0149 +3720 3626 26537352.8999 +3721 3626 19401012.48091 +3722 3626 -57405640.83529 +3732 3626 571474.7733671 +3733 3626 -51408102.87125 +3734 3626 -18348781.1507 +3735 3626 2285899.092361 +3736 3626 -27430322.01402 +3737 3626 -242725472.4512 +3738 3626 571474.773379 +3739 3626 78838424.88527 +3740 3626 -190201211.678 +3753 3626 -14250754.75238 +3754 3626 -13229195.86314 +3755 3626 -17306764.74188 +3756 3626 -82547723.83843 +3757 3626 -6857580.506883 +3758 3626 -113395588.2476 +3759 3626 -27108827.67327 +3760 3626 20086776.37002 +3761 3626 -61172794.84886 +3627 3627 1104842790.893 +3628 3627 1.609325408936e-05 +3629 3627 9143599.859988 +3630 3627 135775801.5773 +3631 3627 -6.794929504395e-06 +3632 3627 2285899.966128 +3645 3627 -90421354.05518 +3646 3627 -62499999.98975 +3647 3627 24401754.87359 +3648 3627 -224004433.2424 +3649 3627 3.09944152832e-06 +3650 3627 -5943327.707585 +3651 3627 -91775737.73549 +3652 3627 62499999.98974 +3653 3627 -27030536.78462 +3717 3627 -26783317.53868 +3718 3627 15625000.00513 +3719 3627 13679279.97901 +3720 3627 -103592244.5474 +3721 3627 1.892447471619e-06 +3722 3627 80604706.69032 +3723 3627 -42555886.98831 +3724 3627 -15625000.00514 +3725 3627 26537352.8999 +3735 3627 16426910.05153 +3736 3627 4.485249519348e-06 +3737 3627 571474.7733669 +3738 3627 77208121.14848 +3739 3627 3.09944152832e-06 +3740 3627 2285899.092361 +3741 3627 -48017751.39621 +3742 3627 -8.776783943176e-06 +3743 3627 571474.7733788 +3756 3627 -27518808.45327 +3757 3627 -15625000.00513 +3758 3627 -14250754.75238 +3759 3627 -107888591.8846 +3760 3627 1.713633537292e-06 +3761 3627 -82890605.78265 +3762 3627 -43968569.74338 +3763 3627 15625000.00513 +3764 3627 -27108827.67327 +3628 3628 954836711.7471 +3629 3628 -109721246.0606 +3630 3628 -6.705522537231e-06 +3631 3628 -101723938.9279 +3632 3628 55957845.25232 +3645 3628 -62499999.98975 +3646 3628 -71670594.15271 +3647 3628 12206475.20882 +3648 3628 3.695487976074e-06 +3649 3628 50996827.03073 +3650 3628 -27430311.52865 +3651 3628 62499999.98974 +3652 3628 -73024977.83304 +3653 3628 15223836.31984 +3717 3628 15625000.00513 +3718 3628 -22095635.7235 +3719 3628 -12543431.97403 +3720 3628 -9.983777999878e-07 +3721 3628 -34841942.9836 +3722 3628 -6857580.506883 +3723 3628 -15625000.00514 +3724 3628 -37868205.17313 +3725 3628 19401012.48091 +3735 3628 5.781650543213e-06 +3736 3628 -42948027.89108 +3737 3628 -51682408.42662 +3738 3628 3.09944152832e-06 +3739 3628 39706666.64553 +3740 3628 -27430322.01402 +3741 3628 -7.04824924469e-06 +3742 3628 -107392689.3388 +3743 3628 79112730.44064 +3756 3628 -15625000.00513 +3757 3628 -22831126.63809 +3758 3628 -13229195.86314 +3759 3628 1.668930053711e-06 +3760 3628 -39138290.32084 +3761 3628 -6857580.506883 +3762 3628 15625000.00513 +3763 3628 -39280887.92821 +3764 3628 20086776.37002 +3629 3629 1151791779.138 +3630 3629 2285899.966128 +3631 3629 53763400.80823 +3632 3629 113453108.8746 +3645 3629 24744636.81848 +3646 3629 12480780.76473 +3647 3629 -16816652.79793 +3648 3629 -3200272.15248 +3649 3629 -27430311.52865 +3650 3629 99884455.60809 +3651 3629 -26687654.83973 +3652 3629 14949530.76392 +3653 3629 -20428342.61214 +3717 3629 13679279.97901 +3718 3629 -12543431.97403 +3719 3629 -15345455.6363 +3720 3629 80261824.7461 +3721 3629 -6857580.506883 +3722 3629 -101938662.0149 +3723 3629 26537352.8999 +3724 3629 19401012.48091 +3725 3629 -57405640.83529 +3735 3629 571474.7733671 +3736 3629 -51408102.87125 +3737 3629 -18348781.1507 +3738 3629 2285899.092361 +3739 3629 -27430322.01402 +3740 3629 -242725472.4512 +3741 3629 571474.773379 +3742 3629 78838424.88527 +3743 3629 -190201211.678 +3756 3629 -14250754.75238 +3757 3629 -13229195.86314 +3758 3629 -17306764.74188 +3759 3629 -82547723.83843 +3760 3629 -6857580.506883 +3761 3629 -113395588.2476 +3762 3629 -27108827.67327 +3763 3629 20086776.37002 +3764 3629 -61172794.84886 +3630 3630 1159636637.338 +3631 3630 57267063.74011 +3632 3630 9020084.21679 +3633 3630 31068618.59239 +3634 3630 -65274374.9039 +3635 3630 4311134.649271 +3648 3630 -90421354.05518 +3649 3630 -62499999.98975 +3650 3630 24401754.87359 +3651 3630 -220710941.0308 +3652 3630 2712121.047365 +3653 3630 -855474.0274411 +3654 3630 -80630013.79547 +3655 3630 62385045.26156 +3656 3630 -4716463.569327 +3720 3630 -26783317.53868 +3721 3630 15625000.00513 +3722 3630 13679279.97901 +3723 3630 -124316437.4178 +3724 3630 -14957795.50287 +3725 3630 78707522.62756 +3738 3630 16426910.05153 +3739 3630 4.485249519348e-06 +3740 3630 571474.7733669 +3741 3630 106567923.342 +3742 3630 14976154.3703 +3743 3630 2242040.339887 +3744 3630 -38982657.32228 +3745 3630 -15972608.5643 +3746 3630 21465843.53807 +3759 3630 -27518808.45327 +3760 3630 -15625000.00513 +3761 3630 -14250754.75238 +3762 3630 -107633678.2844 +3763 3630 337880.5181414 +3764 3630 -81247218.16221 +3765 3630 -35196367.11042 +3766 3630 15616369.17874 +3767 3630 -21139158.27512 +3631 3631 1005630507.664 +3632 3631 -58747305.48163 +3633 3631 -65290453.29772 +3634 3631 -188051818.3445 +3635 3631 9211005.933655 +3648 3631 -62499999.98975 +3649 3631 -71670594.15271 +3650 3631 12206475.20882 +3651 3631 2712121.047367 +3652 3631 51529818.24322 +3653 3631 -15449642.33916 +3654 3631 62385045.26156 +3655 3631 -71138195.32306 +3656 3631 3120533.507055 +3720 3631 15625000.00513 +3721 3631 -22095635.7235 +3722 3631 -12543431.97403 +3723 3631 -14954029.75625 +3724 3631 -51161232.47498 +3725 3631 11517596.47983 +3738 3631 5.781650543213e-06 +3739 3631 -42948027.89108 +3740 3631 -51682408.42662 +3741 3631 14976154.3703 +3742 3631 66205199.90227 +3743 3631 -15327806.57963 +3744 3631 -15976374.31093 +3745 3631 -93719762.45757 +3746 3631 67555030.84424 +3759 3631 -15625000.00513 +3760 3631 -22831126.63809 +3761 3631 -13229195.86314 +3762 3631 337880.5181415 +3763 3631 -39223021.22566 +3764 3631 -3684799.406556 +3765 3631 15616369.17874 +3766 3631 -31662826.22467 +3767 3631 17418239.39067 +3632 3632 1116099565.682 +3633 3632 4312451.31953 +3634 3632 9212070.355586 +3635 3632 74748743.47656 +3648 3632 24744636.81848 +3649 3632 12480780.76473 +3650 3632 -16816652.79793 +3651 3632 -7027349.026428 +3652 3632 -15449642.33916 +3653 3632 95423237.22936 +3654 3632 -4716463.568652 +3655 3632 3120533.507055 +3656 3632 -7137235.120732 +3720 3632 13679279.97901 +3721 3632 -12543431.97403 +3722 3632 -15345455.6363 +3723 3632 80421724.21045 +3724 3632 11247053.56524 +3725 3632 -104696424.0359 +3738 3632 571474.7733671 +3739 3632 -51408102.87125 +3740 3632 -18348781.1507 +3741 3632 2251649.800783 +3742 3632 -15320118.87702 +3743 3632 -215234303.521 +3744 3632 21470957.25149 +3745 3632 67555192.73323 +3746 3632 -108007902.8681 +3759 3632 -14250754.75238 +3760 3632 -13229195.86314 +3761 3632 -17306764.74188 +3762 3632 -82961627.88533 +3763 3632 -3684799.406555 +3764 3632 -114363640.4791 +3765 3632 -21139158.27512 +3766 3632 17418239.39067 +3767 3632 -39860548.18916 +3633 3633 643114116.341 +3634 3633 1815262.806053 +3635 3633 545690.5594623 +3651 3633 -88351160.48298 +3652 3633 -62485443.67478 +3653 3633 3800566.078527 +3654 3633 -207344403.6932 +3655 3633 3624976.418577 +3656 3633 -687512.8056319 +3657 3633 73963822.68434 +3658 3633 -14301178.74488 +3659 3633 -173954.9675533 +3660 3633 -78370874.87386 +3661 3633 61588601.32361 +3662 3633 -935651.2844473 +3723 3633 -10501282.92581 +3724 3633 18761297.24603 +3725 3633 22929736.41723 +3741 3633 -30372317.15758 +3742 3633 -15976374.31093 +3743 3633 -19344589.06185 +3744 3633 22995899.35193 +3745 3633 227894.836162 +3746 3633 16246316.0836 +3762 3633 -33455777.13317 +3763 3633 -15623874.23674 +3764 3633 -19442010.85091 +3765 3633 -104909724.8711 +3766 3633 452225.1981282 +3767 3633 -80690483.95003 +3768 3633 -7523100.327808 +3769 3633 -3351893.393406 +3770 3633 4456236.678043 +3771 3633 -33471919.22362 +3772 3633 15510724.66075 +3773 3633 -20109233.0943 +3634 3634 686119149.4706 +3635 3634 -9870113.888656 +3651 3634 -62485443.67478 +3652 3634 -67751390.65724 +3653 3634 1462280.361642 +3654 3634 3624976.418576 +3655 3634 61053696.21525 +3656 3634 -3015261.418273 +3657 3634 10698821.25101 +3658 3634 -45867734.52917 +3659 3634 475736.0394503 +3660 3634 61588601.32361 +3661 3634 -66836531.55906 +3662 3634 482735.8839684 +3723 3634 12507531.49735 +3724 3634 -11060240.32237 +3725 3634 -12663686.66971 +3741 3634 -15972608.56431 +3742 3634 -85109422.29288 +3743 3634 -63004424.41222 +3744 3634 227894.8361608 +3745 3634 32042317.97522 +3746 3634 3973582.995076 +3762 3634 -15623874.23674 +3763 3634 -28538119.24658 +3764 3634 -15941688.91568 +3765 3634 452225.198129 +3766 3634 -37207991.53993 +3767 3634 -388625.0459828 +3768 3634 2898106.608647 +3769 3634 -37400484.43975 +3770 3634 33451415.26071 +3771 3634 15510724.66075 +3772 3634 -29964282.42088 +3773 3634 16785618.37505 +3635 3635 747110544.2067 +3651 3635 3800566.078864 +3652 3635 1462280.361912 +3653 3635 -8016031.629538 +3654 3635 -687512.8056315 +3655 3635 -3015261.418274 +3656 3635 102348319.6376 +3657 3635 -173954.9675504 +3658 3635 475736.03945 +3659 3635 80405010.0952 +3660 3635 -935651.2841095 +3661 3635 482735.8839684 +3662 3635 -3634854.967177 +3723 3635 15286490.94482 +3724 3635 -18778561.99058 +3725 3635 -27444463.73893 +3741 3635 -19340093.59196 +3742 3635 -63004759.50055 +3743 3635 -85046995.76227 +3744 3635 -15966947.8 +3745 3635 -8805110.802092 +3746 3635 -183271847.5442 +3762 3635 -19442010.85091 +3763 3635 -15941688.91568 +3764 3635 -32724423.62665 +3765 3635 -80690483.95036 +3766 3635 -388625.0459812 +3767 3635 -112004990.4481 +3768 3635 -3668763.324622 +3769 3635 33451415.26071 +3770 3635 -49404477.66436 +3771 3635 -20109233.0943 +3772 3635 16785618.37505 +3773 3635 -36071393.98125 +3636 3636 552240810.9557 +3637 3636 6.198883056641e-06 +3638 3636 -2285838.95777 +3639 3636 67865327.72727 +3640 3636 12499999.99795 +3641 3636 -4857484.044995 +3726 3636 -103592244.5474 +3727 3636 1.892447471619e-06 +3728 3636 80604706.69032 +3729 3636 -42555886.98831 +3730 3636 -15625000.00514 +3731 3636 26537352.8999 +3747 3636 38581487.51291 +3748 3636 -1.847743988037e-06 +3749 3636 -16029498.36724 +3750 3636 -24008875.6981 +3751 3636 3125000.001023 +3752 3636 -5078880.670627 +3637 3637 477237771.3828 +3638 3637 -54860623.03027 +3639 3637 -12499999.99795 +3640 3637 -50884542.52531 +3641 3637 27704617.07065 +3726 3637 -9.983777999878e-07 +3727 3637 -34841942.9836 +3728 3637 -6857580.506883 +3729 3637 -15625000.00514 +3730 3637 -37868205.17313 +3731 3637 19401012.48091 +3747 3637 -2.026557922363e-06 +3748 3637 19830760.26143 +3749 3637 -13715161.00701 +3750 3637 -3125000.00103 +3751 3637 -53696344.6694 +3752 3637 39487788.83141 +3638 3638 575414330.9272 +3639 3638 5428974.286648 +3640 3638 27156005.95963 +3641 3638 56666359.60696 +3726 3638 80261824.7461 +3727 3638 -6857580.506883 +3728 3638 -101938662.0149 +3729 3638 26537352.8999 +3730 3638 19401012.48091 +3731 3638 -57405640.83529 +3747 3638 16600987.73851 +3748 3638 -13715161.00701 +3749 3638 -121422931.0558 +3750 3638 5650355.444006 +3751 3638 39487788.83154 +3752 3638 -95100605.83899 +3639 3639 552240810.9557 +3640 3639 6.198883056641e-06 +3641 3639 -2285838.95777 +3642 3639 67865327.72727 +3643 3639 12499999.99795 +3644 3639 -4857484.044995 +3726 3639 -26783317.53868 +3727 3639 15625000.00513 +3728 3639 13679279.97901 +3729 3639 -103592244.5474 +3730 3639 1.892447471619e-06 +3731 3639 80604706.69032 +3732 3639 -42555886.98831 +3733 3639 -15625000.00514 +3734 3639 26537352.8999 +3747 3639 8213455.025764 +3748 3639 -3125000.001024 +3749 3639 -2507266.086456 +3750 3639 38581487.51291 +3751 3639 -1.847743988037e-06 +3752 3639 -16029498.36724 +3753 3639 -24008875.6981 +3754 3639 3125000.001023 +3755 3639 -5078880.670627 +3640 3640 477237771.3828 +3641 3640 -54860623.03027 +3642 3640 -12499999.99795 +3643 3640 -50884542.52531 +3644 3640 27704617.07065 +3726 3640 15625000.00513 +3727 3640 -22095635.7235 +3728 3640 -12543431.97403 +3729 3640 -9.983777999878e-07 +3730 3640 -34841942.9836 +3731 3640 -6857580.506883 +3732 3640 -15625000.00514 +3733 3640 -37868205.17313 +3734 3640 19401012.48091 +3747 3640 3125000.00103 +3748 3640 -21474013.94555 +3749 3640 -25772627.8244 +3750 3640 -2.026557922363e-06 +3751 3640 19830760.26143 +3752 3640 -13715161.00701 +3753 3640 -3125000.00103 +3754 3640 -53696344.6694 +3755 3640 39487788.83141 +3641 3641 575414330.9272 +3642 3641 5428974.286648 +3643 3641 27156005.95963 +3644 3641 56666359.60696 +3726 3641 13679279.97901 +3727 3641 -12543431.97403 +3728 3641 -15345455.6363 +3729 3641 80261824.7461 +3730 3641 -6857580.506883 +3731 3641 -101938662.0149 +3732 3641 26537352.8999 +3733 3641 19401012.48091 +3734 3641 -57405640.83529 +3747 3641 3078740.859823 +3748 3641 -25772627.82454 +3749 3641 -9174390.575351 +3750 3641 16600987.73851 +3751 3641 -13715161.00701 +3752 3641 -121422931.0558 +3753 3641 5650355.444006 +3754 3641 39487788.83154 +3755 3641 -95100605.83899 +3642 3642 552240810.9557 +3643 3642 6.198883056641e-06 +3644 3642 -2285838.95777 +3645 3642 67865327.72727 +3646 3642 12499999.99795 +3647 3642 -4857484.044995 +3729 3642 -26783317.53868 +3730 3642 15625000.00513 +3731 3642 13679279.97901 +3732 3642 -103592244.5474 +3733 3642 1.892447471619e-06 +3734 3642 80604706.69032 +3735 3642 -42555886.98831 +3736 3642 -15625000.00514 +3737 3642 26537352.8999 +3750 3642 8213455.025764 +3751 3642 -3125000.001024 +3752 3642 -2507266.086456 +3753 3642 38581487.51291 +3754 3642 -1.847743988037e-06 +3755 3642 -16029498.36724 +3756 3642 -24008875.6981 +3757 3642 3125000.001023 +3758 3642 -5078880.670627 +3643 3643 477237771.3828 +3644 3643 -54860623.03027 +3645 3643 -12499999.99795 +3646 3643 -50884542.52531 +3647 3643 27704617.07065 +3729 3643 15625000.00513 +3730 3643 -22095635.7235 +3731 3643 -12543431.97403 +3732 3643 -9.983777999878e-07 +3733 3643 -34841942.9836 +3734 3643 -6857580.506883 +3735 3643 -15625000.00514 +3736 3643 -37868205.17313 +3737 3643 19401012.48091 +3750 3643 3125000.00103 +3751 3643 -21474013.94555 +3752 3643 -25772627.8244 +3753 3643 -2.026557922363e-06 +3754 3643 19830760.26143 +3755 3643 -13715161.00701 +3756 3643 -3125000.00103 +3757 3643 -53696344.6694 +3758 3643 39487788.83141 +3644 3644 575414330.9272 +3645 3644 5428974.286648 +3646 3644 27156005.95963 +3647 3644 56666359.60696 +3729 3644 13679279.97901 +3730 3644 -12543431.97403 +3731 3644 -15345455.6363 +3732 3644 80261824.7461 +3733 3644 -6857580.506883 +3734 3644 -101938662.0149 +3735 3644 26537352.8999 +3736 3644 19401012.48091 +3737 3644 -57405640.83529 +3750 3644 3078740.859823 +3751 3644 -25772627.82454 +3752 3644 -9174390.575351 +3753 3644 16600987.73851 +3754 3644 -13715161.00701 +3755 3644 -121422931.0558 +3756 3644 5650355.444006 +3757 3644 39487788.83154 +3758 3644 -95100605.83899 +3645 3645 552240810.9557 +3646 3645 6.198883056641e-06 +3647 3645 -2285838.95777 +3648 3645 67865327.72727 +3649 3645 12499999.99795 +3650 3645 -4857484.044995 +3732 3645 -26783317.53868 +3733 3645 15625000.00513 +3734 3645 13679279.97901 +3735 3645 -103592244.5474 +3736 3645 1.892447471619e-06 +3737 3645 80604706.69032 +3738 3645 -42555886.98831 +3739 3645 -15625000.00514 +3740 3645 26537352.8999 +3753 3645 8213455.025764 +3754 3645 -3125000.001024 +3755 3645 -2507266.086456 +3756 3645 38581487.51291 +3757 3645 -1.847743988037e-06 +3758 3645 -16029498.36724 +3759 3645 -24008875.6981 +3760 3645 3125000.001023 +3761 3645 -5078880.670627 +3646 3646 477237771.3828 +3647 3646 -54860623.03027 +3648 3646 -12499999.99795 +3649 3646 -50884542.52531 +3650 3646 27704617.07065 +3732 3646 15625000.00513 +3733 3646 -22095635.7235 +3734 3646 -12543431.97403 +3735 3646 -9.983777999878e-07 +3736 3646 -34841942.9836 +3737 3646 -6857580.506883 +3738 3646 -15625000.00514 +3739 3646 -37868205.17313 +3740 3646 19401012.48091 +3753 3646 3125000.00103 +3754 3646 -21474013.94555 +3755 3646 -25772627.8244 +3756 3646 -2.026557922363e-06 +3757 3646 19830760.26143 +3758 3646 -13715161.00701 +3759 3646 -3125000.00103 +3760 3646 -53696344.6694 +3761 3646 39487788.83141 +3647 3647 575414330.9272 +3648 3647 5428974.286648 +3649 3647 27156005.95963 +3650 3647 56666359.60696 +3732 3647 13679279.97901 +3733 3647 -12543431.97403 +3734 3647 -15345455.6363 +3735 3647 80261824.7461 +3736 3647 -6857580.506883 +3737 3647 -101938662.0149 +3738 3647 26537352.8999 +3739 3647 19401012.48091 +3740 3647 -57405640.83529 +3753 3647 3078740.859823 +3754 3647 -25772627.82454 +3755 3647 -9174390.575351 +3756 3647 16600987.73851 +3757 3647 -13715161.00701 +3758 3647 -121422931.0558 +3759 3647 5650355.444006 +3760 3647 39487788.83154 +3761 3647 -95100605.83899 +3648 3648 552240810.9557 +3649 3648 6.198883056641e-06 +3650 3648 -2285838.95777 +3651 3648 67865327.72727 +3652 3648 12499999.99795 +3653 3648 -4857484.044995 +3735 3648 -26783317.53868 +3736 3648 15625000.00513 +3737 3648 13679279.97901 +3738 3648 -103592244.5474 +3739 3648 1.892447471619e-06 +3740 3648 80604706.69032 +3741 3648 -42555886.98831 +3742 3648 -15625000.00514 +3743 3648 26537352.8999 +3756 3648 8213455.025764 +3757 3648 -3125000.001024 +3758 3648 -2507266.086456 +3759 3648 38581487.51291 +3760 3648 -1.847743988037e-06 +3761 3648 -16029498.36724 +3762 3648 -24008875.6981 +3763 3648 3125000.001023 +3764 3648 -5078880.670627 +3649 3649 477237771.3828 +3650 3649 -54860623.03027 +3651 3649 -12499999.99795 +3652 3649 -50884542.52531 +3653 3649 27704617.07065 +3735 3649 15625000.00513 +3736 3649 -22095635.7235 +3737 3649 -12543431.97403 +3738 3649 -9.983777999878e-07 +3739 3649 -34841942.9836 +3740 3649 -6857580.506883 +3741 3649 -15625000.00514 +3742 3649 -37868205.17313 +3743 3649 19401012.48091 +3756 3649 3125000.00103 +3757 3649 -21474013.94555 +3758 3649 -25772627.8244 +3759 3649 -2.026557922363e-06 +3760 3649 19830760.26143 +3761 3649 -13715161.00701 +3762 3649 -3125000.00103 +3763 3649 -53696344.6694 +3764 3649 39487788.83141 +3650 3650 575414330.9272 +3651 3650 5428974.286648 +3652 3650 27156005.95963 +3653 3650 56666359.60696 +3735 3650 13679279.97901 +3736 3650 -12543431.97403 +3737 3650 -15345455.6363 +3738 3650 80261824.7461 +3739 3650 -6857580.506883 +3740 3650 -101938662.0149 +3741 3650 26537352.8999 +3742 3650 19401012.48091 +3743 3650 -57405640.83529 +3756 3650 3078740.859823 +3757 3650 -25772627.82454 +3758 3650 -9174390.575351 +3759 3650 16600987.73851 +3760 3650 -13715161.00701 +3761 3650 -121422931.0558 +3762 3650 5650355.444006 +3763 3650 39487788.83154 +3764 3650 -95100605.83899 +3651 3651 546427747.6316 +3652 3651 14084.27154636 +3653 3651 19801718.51323 +3654 3651 72858320.95034 +3655 3651 9759238.364084 +3656 3651 -116602.2357446 +3738 3651 -26783317.53868 +3739 3651 15625000.00513 +3740 3651 13679279.97901 +3741 3651 -103824273.5978 +3742 3651 337880.518146 +3743 3651 79309465.83793 +3744 3651 -35603944.70717 +3745 3651 -15623874.23674 +3746 3651 21344707.91248 +3759 3651 8213455.025764 +3760 3651 -3125000.001024 +3761 3651 -2507266.086456 +3762 3651 36785557.19904 +3763 3651 1001.460290611 +3764 3651 -10934725.82542 +3765 3651 -9732528.17502 +3766 3651 2784992.254198 +3767 3651 -3687434.039309 +3652 3652 473282839.044 +3653 3652 -31454317.56922 +3654 3652 -15240761.63181 +3655 3652 -46838189.21174 +3656 3652 4981976.156287 +3738 3652 15625000.00513 +3739 3652 -22095635.7235 +3740 3652 -12543431.97403 +3741 3652 337880.5181429 +3742 3652 -35413616.53907 +3743 3652 -4387924.406508 +3744 3652 -15623874.23674 +3745 3652 -30686286.82058 +3746 3652 16688519.42836 +3759 3652 3125000.00103 +3760 3652 -21474013.94555 +3761 3652 -25772627.8244 +3762 3652 1001.460290015 +3763 3652 18267026.88321 +3764 3652 -8198617.671864 +3765 3652 -3465007.747854 +3766 3652 -39542525.64835 +3767 3652 34214082.44842 +3653 3653 563211198.8205 +3654 3653 1940689.430582 +3655 3653 4981976.156287 +3656 3653 76646397.41118 +3738 3653 13679279.97901 +3739 3653 -12543431.97403 +3740 3653 -15345455.6363 +3741 3653 81023875.56122 +3742 3653 -4387924.406372 +3743 3653 -104205227.9814 +3744 3653 21344707.91248 +3745 3653 16688519.42836 +3746 3653 -38452870.49066 +3759 3653 3078740.859823 +3760 3653 -25772627.82454 +3761 3653 -9174390.575351 +3762 3653 21695204.72477 +3763 3653 -8198617.671865 +3764 3653 -125793345.0864 +3765 3653 4984232.630034 +3766 3653 34214082.44842 +3767 3653 -56215515.01345 +3654 3654 535719626.833 +3655 3654 1986554.525402 +3656 3654 424185.6203845 +3657 3654 -88785458.20547 +3658 3654 -63411398.65587 +3659 3654 778758.4376477 +3660 3654 68808927.91007 +3661 3654 10655584.08215 +3662 3654 -482712.6707865 +3741 3654 -31935568.9612 +3742 3654 15616369.17874 +3743 3654 18769001.46021 +3744 3654 -104345694.7398 +3745 3654 452225.1981363 +3746 3654 80375835.46763 +3762 3654 -3774952.867633 +3763 3654 -3465007.747854 +3764 3654 -4051670.15019 +3765 3654 32975566.42036 +3766 3654 240896.7043756 +3767 3654 -15981841.05615 +3768 3654 -34789757.76571 +3769 3654 -15739275.34951 +3770 3654 20505089.8357 +3771 3654 -8443092.085658 +3772 3654 2894792.016114 +3773 3654 -3662387.778975 +3655 3655 478673986.4768 +3656 3655 -7025191.624467 +3657 3655 -63411398.65587 +3658 3655 -70742000.30841 +3659 3655 482735.8839682 +3660 3655 -14344415.91375 +3661 3655 -50382297.84958 +3662 3655 1455207.495472 +3741 3655 15616369.17874 +3742 3655 -28402028.07545 +3743 3655 -15915093.95361 +3744 3655 452225.1981353 +3745 3655 -36643961.40857 +3746 3655 -1091750.045935 +3762 3655 2784992.254199 +3763 3655 -33584950.34097 +3764 3655 -31749459.20734 +3765 3655 240896.7043772 +3766 3655 17012000.22864 +3767 3655 -1720373.374572 +3768 3655 -15739275.34951 +3769 3655 -30458471.87417 +3770 3655 16785618.37505 +3771 3655 -3355207.985938 +3772 3655 -38236088.52908 +3773 3655 33691058.20639 +3656 3656 561203178.0176 +3657 3656 778758.4376477 +3658 3656 482735.8839681 +3659 3656 -7540323.716533 +3660 3656 203051.2179867 +3661 3656 1455207.495472 +3662 3656 76151663.76902 +3741 3656 18769001.46021 +3742 3656 -15915093.95361 +3743 3656 -31165086.45791 +3744 3656 80375835.46797 +3745 3656 -1091750.045798 +3746 3656 -110500910.0978 +3762 3656 3591350.685652 +3763 3656 -31749459.20747 +3764 3656 -40328647.52708 +3765 3656 16231422.82745 +3766 3656 -1720373.374572 +3767 3656 -131615230.9477 +3768 3656 20505089.8357 +3769 3656 16785618.37505 +3770 3656 -36565583.43453 +3771 3656 4458341.39036 +3772 3656 33691058.20639 +3773 3656 -50660541.5339 +3657 3657 272675288.3693 +3658 3657 64301178.73667 +3659 3657 -397514.9396582 +3660 3657 -104075430.6267 +3661 3657 -11588601.33182 +3662 3657 -207288.5304373 +3744 3657 -6974489.216529 +3745 3657 2898106.608647 +3746 3657 3577677.650328 +3765 3657 -34241146.65443 +3766 3657 -15739275.34951 +3767 3657 -20119910.17764 +3768 3657 16467433.68971 +3769 3657 15851893.39751 +3770 3657 8027675.358897 +3771 3657 -52140908.9295 +3772 3657 -3010724.656649 +3773 3657 -40235442.83158 +3658 3658 240163095.6078 +3659 3658 -475736.039438 +3660 3658 13411398.66408 +3661 3658 30224861.45123 +3662 3658 -482735.8839618 +3744 3658 -3351893.393406 +3745 3658 -36851873.32848 +3746 3658 -33215251.395 +3765 3658 -15739275.34951 +3766 3658 -29909860.76288 +3767 3658 -16547714.96923 +3768 3658 15851893.39751 +3769 3658 8258880.289149 +3770 3658 6548584.732711 +3771 3658 3239275.345404 +3772 3658 -18386257.30854 +3773 3658 3214381.631519 +3659 3659 285372202.8062 +3660 3659 -207288.530434 +3661 3659 -482735.8839618 +3662 3659 51838370.07238 +3744 3659 -4547322.35217 +3745 3659 -33215251.395 +3746 3659 -47941514.70095 +3765 3659 -20119910.17764 +3766 3659 -16547714.96923 +3767 3659 -35102620.4711 +3768 3659 -8222324.638434 +3769 3659 -6784748.598432 +3770 3659 -66392404.24977 +3771 3659 -40235442.83175 +3772 3659 -3452285.037337 +3773 3659 -55601090.20684 +3660 3660 265193822.0356 +3661 3660 -60655584.07394 +3662 3660 -431639.1816709 +3744 3660 -32923308.11233 +3745 3660 15510724.66075 +3746 3660 19637207.89097 +3765 3660 -6797258.752877 +3766 3660 -3355207.985938 +3767 3660 -4369505.834413 +3768 3660 -52140908.9295 +3769 3660 3239275.345408 +3770 3660 40135998.12736 +3771 3660 16083253.57212 +3772 3660 -15394792.02022 +3773 3660 -8050852.961471 +3661 3661 238550412.4026 +3662 3661 -1455207.495458 +3744 3661 15510724.66075 +3745 3661 -29415671.3096 +3746 3661 -16547714.96923 +3765 3661 2894792.016115 +3766 3661 -36590255.19631 +3767 3661 -32975608.44932 +3768 3661 -3010724.656646 +3769 3661 -18386257.30854 +3770 3661 3214381.631519 +3771 3661 -15394792.02022 +3772 3661 8613961.591849 +3773 3661 6308941.787031 +3662 3662 279795339.6462 +3744 3662 19637207.89097 +3745 3662 -16547714.96923 +3746 3662 -34608431.01782 +3765 3662 3408341.390536 +3766 3662 -32975608.44932 +3767 3662 -46271652.64648 +3768 3662 40135998.12736 +3769 3662 -3452285.037337 +3770 3662 -55601090.20684 +3771 3662 7847723.424807 +3772 3662 -7024391.544111 +3773 3662 -65594085.3891 +3663 3663 713665840.9484 +3664 3663 62499999.98975 +3665 3663 26303045.6496 +3666 3663 -333091779.4995 +3667 3663 -62514728.59611 +3668 3663 -26296716.12064 +3669 3663 15411687.79098 +3670 3663 50014728.59815 +3671 3663 -21264808.11782 +3774 3663 50455843.08525 +3775 3663 15625000.00514 +3776 3663 23750485.45243 +3777 3663 -136601119.3265 +3778 3663 -15628682.15673 +3779 3663 -88333821.76341 +3780 3663 -31442472.41633 +3781 3663 12503682.1557 +3782 3663 -21464859.02542 +3664 3664 619895634.403 +3665 3664 -68588052.25144 +3666 3664 -62522092.89929 +3667 3664 -39293818.84171 +3668 3664 -37998394.10174 +3669 3664 75022092.89723 +3670 3664 15411687.79098 +3671 3664 23871774.7618 +3774 3664 15625000.00514 +3775 3664 27013291.43733 +3776 3664 -3407345.083582 +3777 3664 -15630523.23252 +3778 3664 -63151629.12586 +3779 3664 -25854695.88552 +3780 3664 18755523.23355 +3781 3664 -31442472.41633 +3782 3664 25757502.85539 +3665 3665 781376197.173 +3666 3665 -26293551.35616 +3667 3665 -30589746.95883 +3668 3665 33460212.57848 +3669 3665 -31897212.17672 +3670 3665 15914516.50787 +3671 3665 41097834.10927 +3774 3665 -8884805.348678 +3775 3665 -29515355.2492 +3776 3665 -145884263.2499 +3777 3665 -87990199.11779 +3778 3665 -23932056.04702 +3779 3665 -133843411.9462 +3780 3665 -32197288.53812 +3781 3665 17171668.57026 +3782 3665 -83846593.11021 +3666 3666 1206829602.888 +3667 3666 62536821.50566 +3668 3666 30859020.00955 +3669 3666 35818303.75647 +3670 3666 -62514728.59611 +3671 3666 26693781.96925 +3672 3666 -218486531.0803 +3673 3666 2.98023223877e-06 +3674 3666 -4571798.18244 +3675 3666 -90373702.5448 +3676 3666 62499999.98974 +3677 3666 -26687654.40317 +3774 3666 -119411159.8837 +3775 3666 -15630523.23252 +3776 3666 75186254.88774 +3777 3666 109890622.1535 +3778 3666 15634205.38412 +3779 3666 7712478.882864 +3780 3666 -60563825.20041 +3781 3666 -15628682.15673 +3782 3666 27115214.46942 +3783 3666 -107888591.8846 +3784 3666 1.713633537292e-06 +3785 3666 -82890605.78265 +3786 3666 -43968569.74338 +3787 3666 15625000.00513 +3788 3666 -27108827.67327 +3667 3667 1038056487.373 +3668 3667 -85034336.6799 +3669 3667 -62522092.89929 +3670 3667 -182960177.6074 +3671 3667 45539436.5079 +3672 3667 4.291534423828e-06 +3673 3667 56514675.03912 +3674 3667 -27430322.01402 +3675 3667 62499999.98974 +3676 3667 -71622975.29333 +3677 3667 14949536.00687 +3774 3667 -15628682.15673 +3775 3667 -45961669.68301 +3776 3667 8705839.731277 +3777 3667 15634205.38412 +3778 3667 67697343.25408 +3779 3667 -21260405.06448 +3780 3667 -15630523.23252 +3781 3667 -115258445.5683 +3782 3667 76792017.46155 +3783 3667 1.668930053711e-06 +3784 3667 -39138290.32084 +3785 3667 -6857580.506883 +3786 3667 15625000.00513 +3787 3667 -39280887.92821 +3788 3667 20086776.37002 +3668 3668 1199251971.759 +3669 3668 27039727.69652 +3670 3668 53222308.42241 +3671 3668 71236333.03937 +3672 3668 -4571798.18244 +3673 3668 -27430322.01402 +3674 3668 114598543.8875 +3675 3668 -27030536.34739 +3676 3668 15223841.56225 +3677 3668 -16689642.3626 +3774 3668 74842632.24213 +3775 3668 6787043.609902 +3776 3668 -88003520.09856 +3777 3668 7717283.578221 +3778 3668 -21256561.34093 +3779 3668 -211698416.8248 +3780 3668 27118407.8675 +3781 3668 78438470.16785 +3782 3668 -167573319.7819 +3783 3668 -82547723.83843 +3784 3668 -6857580.506883 +3785 3668 -113395588.2476 +3786 3668 -27108827.67327 +3787 3668 20086776.37002 +3788 3668 -61172794.84886 +3669 3669 713665840.9484 +3670 3669 62499999.98975 +3671 3669 26303045.6496 +3672 3669 -89019318.86449 +3673 3669 -62499999.98974 +3674 3669 24744637.25504 +3675 3669 -333091779.4995 +3676 3669 -62514728.59611 +3677 3669 -26296716.12064 +3678 3669 15411687.79098 +3679 3669 50014728.59815 +3680 3669 -21264808.11782 +3774 3669 789479.8663111 +3775 3669 18755523.23355 +3776 3669 16762853.88037 +3777 3669 -11151323.14121 +3778 3669 -15630523.23252 +3779 3669 -13684113.02055 +3780 3669 50455843.08525 +3781 3669 15625000.00514 +3782 3669 23750485.45243 +3783 3669 -27518808.45327 +3784 3669 -15625000.00513 +3785 3669 -14250754.75238 +3786 3669 -136601119.3265 +3787 3669 -15628682.15673 +3788 3669 -88333821.76341 +3789 3669 -31442472.41633 +3790 3669 12503682.1557 +3791 3669 -21464859.02542 +3670 3670 619895634.403 +3671 3670 -68588052.25144 +3672 3670 -62499999.98974 +3673 3670 -70268591.613 +3674 3670 12480786.00715 +3675 3670 -62522092.89929 +3676 3670 -39293818.84171 +3677 3670 -37998394.10174 +3678 3670 75022092.89723 +3679 3670 15411687.79098 +3680 3670 23871774.7618 +3774 3670 12503682.1557 +3775 3670 789479.8663122 +3776 3670 -8940185.539224 +3777 3670 -15628682.15672 +3778 3670 -65845943.5091 +3779 3670 -52101581.10086 +3780 3670 15625000.00514 +3781 3670 27013291.43733 +3782 3670 -3407345.083582 +3783 3670 -15625000.00513 +3784 3670 -22831126.63809 +3785 3670 -13229195.86314 +3786 3670 -15630523.23252 +3787 3670 -63151629.12586 +3788 3670 -25854695.88552 +3789 3670 18755523.23355 +3790 3670 -31442472.41633 +3791 3670 25757502.85539 +3671 3671 781376197.173 +3672 3671 24401755.31083 +3673 3671 12206480.45177 +3674 3671 -13077952.54839 +3675 3671 -26293551.35616 +3676 3671 -30589746.95883 +3677 3671 33460212.57848 +3678 3671 -31897212.17672 +3679 3671 15914516.50787 +3680 3671 41097834.10927 +3774 3671 11175235.92025 +3775 3671 -13410278.30884 +3776 3671 2105279.643495 +3777 3671 -13682502.0067 +3778 3671 -53748034.02747 +3779 3671 -35806647.62401 +3780 3671 -8884805.348678 +3781 3671 -29515355.2492 +3782 3671 -145884263.2499 +3783 3671 -14250754.75238 +3784 3671 -13229195.86314 +3785 3671 -17306764.74188 +3786 3671 -87990199.11779 +3787 3671 -23932056.04702 +3788 3671 -133843411.9462 +3789 3671 -32197288.53812 +3790 3671 17171668.57026 +3791 3671 -83846593.11021 +3672 3672 1126552465.849 +3673 3672 1.227855682373e-05 +3674 3672 9143596.364805 +3675 3672 141293458.9169 +3676 3672 -4.947185516357e-06 +3677 3672 2285899.092331 +3681 3672 -218486531.0803 +3682 3672 2.98023223877e-06 +3683 3672 -4571798.18244 +3684 3672 -90373702.5448 +3685 3672 62499999.98974 +3686 3672 -26687654.40317 +3777 3672 -103592244.5474 +3778 3672 1.892447471619e-06 +3779 3672 80604706.69032 +3780 3672 -42555886.98831 +3781 3672 -15625000.00514 +3782 3672 26537352.8999 +3783 3672 77208121.14848 +3784 3672 3.09944152832e-06 +3785 3672 2285899.092361 +3786 3672 -48017751.39621 +3787 3672 -8.776783943176e-06 +3788 3672 571474.7733788 +3792 3672 -107888591.8846 +3793 3672 1.713633537292e-06 +3794 3672 -82890605.78265 +3795 3672 -43968569.74338 +3796 3672 15625000.00513 +3797 3672 -27108827.67327 +3673 3673 976546647.911 +3674 3673 -109721288.002 +3675 3673 -4.738569259644e-06 +3676 3673 -96206292.73656 +3677 3673 54860644.00101 +3681 3673 4.291534423828e-06 +3682 3673 56514675.03912 +3683 3673 -27430322.01402 +3684 3673 62499999.98974 +3685 3673 -71622975.29333 +3686 3673 14949536.00687 +3777 3673 -9.983777999878e-07 +3778 3673 -34841942.9836 +3779 3673 -6857580.506883 +3780 3673 -15625000.00514 +3781 3673 -37868205.17313 +3782 3673 19401012.48091 +3783 3673 3.09944152832e-06 +3784 3673 39706666.64553 +3785 3673 -27430322.01402 +3786 3673 -7.04824924469e-06 +3787 3673 -107392689.3388 +3788 3673 79112730.44064 +3792 3673 1.668930053711e-06 +3793 3673 -39138290.32084 +3794 3673 -6857580.506883 +3795 3673 15625000.00513 +3796 3673 -39280887.92821 +3797 3673 20086776.37002 +3674 3674 1209684727.759 +3675 3674 2285899.092332 +3676 3674 54860644.00101 +3677 3674 128167058.7484 +3681 3674 -4571798.18244 +3682 3674 -27430322.01402 +3683 3674 114598543.8875 +3684 3674 -27030536.34739 +3685 3674 15223841.56225 +3686 3674 -16689642.3626 +3777 3674 80261824.7461 +3778 3674 -6857580.506883 +3779 3674 -101938662.0149 +3780 3674 26537352.8999 +3781 3674 19401012.48091 +3782 3674 -57405640.83529 +3783 3674 2285899.092361 +3784 3674 -27430322.01402 +3785 3674 -242725472.4512 +3786 3674 571474.773379 +3787 3674 78838424.88527 +3788 3674 -190201211.678 +3792 3674 -82547723.83843 +3793 3674 -6857580.506883 +3794 3674 -113395588.2476 +3795 3674 -27108827.67327 +3796 3674 20086776.37002 +3797 3674 -61172794.84886 +3675 3675 1206829602.888 +3676 3675 62536821.50566 +3677 3675 30859020.00955 +3678 3675 35818303.75647 +3679 3675 -62514728.59611 +3680 3675 26693781.96925 +3681 3675 -89019318.86449 +3682 3675 -62499999.98974 +3683 3675 24744637.25504 +3684 3675 -218486531.0803 +3685 3675 2.98023223877e-06 +3686 3675 -4571798.18244 +3687 3675 -90373702.5448 +3688 3675 62499999.98974 +3689 3675 -26687654.40317 +3777 3675 -26783317.53868 +3778 3675 15625000.00513 +3779 3675 13679279.97901 +3780 3675 -119411159.8837 +3781 3675 -15630523.23252 +3782 3675 75186254.88774 +3783 3675 16426910.05153 +3784 3675 4.485249519348e-06 +3785 3675 571474.7733669 +3786 3675 109890622.1535 +3787 3675 15634205.38412 +3788 3675 7712478.882864 +3789 3675 -60563825.20041 +3790 3675 -15628682.15673 +3791 3675 27115214.46942 +3792 3675 -27518808.45327 +3793 3675 -15625000.00513 +3794 3675 -14250754.75238 +3795 3675 -107888591.8846 +3796 3675 1.713633537292e-06 +3797 3675 -82890605.78265 +3798 3675 -43968569.74338 +3799 3675 15625000.00513 +3800 3675 -27108827.67327 +3676 3676 1038056487.373 +3677 3676 -85034336.6799 +3678 3676 -62522092.89929 +3679 3676 -182960177.6074 +3680 3676 45539436.5079 +3681 3676 -62499999.98974 +3682 3676 -70268591.613 +3683 3676 12480786.00715 +3684 3676 4.291534423828e-06 +3685 3676 56514675.03912 +3686 3676 -27430322.01402 +3687 3676 62499999.98974 +3688 3676 -71622975.29333 +3689 3676 14949536.00687 +3777 3676 15625000.00513 +3778 3676 -22095635.7235 +3779 3676 -12543431.97403 +3780 3676 -15628682.15673 +3781 3676 -45961669.68301 +3782 3676 8705839.731277 +3783 3676 5.781650543213e-06 +3784 3676 -42948027.89108 +3785 3676 -51682408.42662 +3786 3676 15634205.38412 +3787 3676 67697343.25408 +3788 3676 -21260405.06448 +3789 3676 -15630523.23252 +3790 3676 -115258445.5683 +3791 3676 76792017.46155 +3792 3676 -15625000.00513 +3793 3676 -22831126.63809 +3794 3676 -13229195.86314 +3795 3676 1.668930053711e-06 +3796 3676 -39138290.32084 +3797 3676 -6857580.506883 +3798 3676 15625000.00513 +3799 3676 -39280887.92821 +3800 3676 20086776.37002 +3677 3677 1199251971.759 +3678 3677 27039727.69652 +3679 3677 53222308.42241 +3680 3677 71236333.03937 +3681 3677 24401755.31083 +3682 3677 12206480.45177 +3683 3677 -13077952.54839 +3684 3677 -4571798.18244 +3685 3677 -27430322.01402 +3686 3677 114598543.8875 +3687 3677 -27030536.34739 +3688 3677 15223841.56225 +3689 3677 -16689642.3626 +3777 3677 13679279.97901 +3778 3677 -12543431.97403 +3779 3677 -15345455.6363 +3780 3677 74842632.24213 +3781 3677 6787043.609902 +3782 3677 -88003520.09856 +3783 3677 571474.7733671 +3784 3677 -51408102.87125 +3785 3677 -18348781.1507 +3786 3677 7717283.578221 +3787 3677 -21256561.34093 +3788 3677 -211698416.8248 +3789 3677 27118407.8675 +3790 3677 78438470.16785 +3791 3677 -167573319.7819 +3792 3677 -14250754.75238 +3793 3677 -13229195.86314 +3794 3677 -17306764.74188 +3795 3677 -82547723.83843 +3796 3677 -6857580.506883 +3797 3677 -113395588.2476 +3798 3677 -27108827.67327 +3799 3677 20086776.37002 +3800 3677 -61172794.84886 +3678 3678 713665840.9484 +3679 3678 62499999.98975 +3680 3678 26303045.6496 +3684 3678 -89019318.86449 +3685 3678 -62499999.98974 +3686 3678 24744637.25504 +3687 3678 -333091779.4995 +3688 3678 -62514728.59611 +3689 3678 -26296716.12064 +3690 3678 15411687.79098 +3691 3678 50014728.59815 +3692 3678 -21264808.11782 +3780 3678 789479.8663111 +3781 3678 18755523.23355 +3782 3678 16762853.88037 +3786 3678 -11151323.14121 +3787 3678 -15630523.23252 +3788 3678 -13684113.02055 +3789 3678 50455843.08525 +3790 3678 15625000.00514 +3791 3678 23750485.45243 +3795 3678 -27518808.45327 +3796 3678 -15625000.00513 +3797 3678 -14250754.75238 +3798 3678 -136601119.3265 +3799 3678 -15628682.15673 +3800 3678 -88333821.76341 +3801 3678 -31442472.41633 +3802 3678 12503682.1557 +3803 3678 -21464859.02542 +3679 3679 619895634.403 +3680 3679 -68588052.25144 +3684 3679 -62499999.98974 +3685 3679 -70268591.613 +3686 3679 12480786.00715 +3687 3679 -62522092.89929 +3688 3679 -39293818.84171 +3689 3679 -37998394.10174 +3690 3679 75022092.89723 +3691 3679 15411687.79098 +3692 3679 23871774.7618 +3780 3679 12503682.1557 +3781 3679 789479.8663122 +3782 3679 -8940185.539224 +3786 3679 -15628682.15672 +3787 3679 -65845943.5091 +3788 3679 -52101581.10086 +3789 3679 15625000.00514 +3790 3679 27013291.43733 +3791 3679 -3407345.083582 +3795 3679 -15625000.00513 +3796 3679 -22831126.63809 +3797 3679 -13229195.86314 +3798 3679 -15630523.23252 +3799 3679 -63151629.12586 +3800 3679 -25854695.88552 +3801 3679 18755523.23355 +3802 3679 -31442472.41633 +3803 3679 25757502.85539 +3680 3680 781376197.173 +3684 3680 24401755.31083 +3685 3680 12206480.45177 +3686 3680 -13077952.54839 +3687 3680 -26293551.35616 +3688 3680 -30589746.95883 +3689 3680 33460212.57848 +3690 3680 -31897212.17672 +3691 3680 15914516.50787 +3692 3680 41097834.10927 +3780 3680 11175235.92025 +3781 3680 -13410278.30884 +3782 3680 2105279.643495 +3786 3680 -13682502.0067 +3787 3680 -53748034.02747 +3788 3680 -35806647.62401 +3789 3680 -8884805.348678 +3790 3680 -29515355.2492 +3791 3680 -145884263.2499 +3795 3680 -14250754.75238 +3796 3680 -13229195.86314 +3797 3680 -17306764.74188 +3798 3680 -87990199.11779 +3799 3680 -23932056.04702 +3800 3680 -133843411.9462 +3801 3680 -32197288.53812 +3802 3680 17171668.57026 +3803 3680 -83846593.11021 +3681 3681 1126552465.849 +3682 3681 1.227855682373e-05 +3683 3681 9143596.364805 +3684 3681 141293458.9169 +3685 3681 -4.947185516357e-06 +3686 3681 2285899.092331 +3693 3681 -218486531.0803 +3694 3681 2.98023223877e-06 +3695 3681 -4571798.18244 +3696 3681 -90373702.5448 +3697 3681 62499999.98974 +3698 3681 -26687654.40317 +3783 3681 -103592244.5474 +3784 3681 1.892447471619e-06 +3785 3681 80604706.69032 +3786 3681 -42555886.98831 +3787 3681 -15625000.00514 +3788 3681 26537352.8999 +3792 3681 77208121.14848 +3793 3681 3.09944152832e-06 +3794 3681 2285899.092361 +3795 3681 -48017751.39621 +3796 3681 -8.776783943176e-06 +3797 3681 571474.7733788 +3804 3681 -107888591.8846 +3805 3681 1.713633537292e-06 +3806 3681 -82890605.78265 +3807 3681 -43968569.74338 +3808 3681 15625000.00513 +3809 3681 -27108827.67327 +3682 3682 976546647.911 +3683 3682 -109721288.002 +3684 3682 -4.738569259644e-06 +3685 3682 -96206292.73656 +3686 3682 54860644.00101 +3693 3682 4.291534423828e-06 +3694 3682 56514675.03912 +3695 3682 -27430322.01402 +3696 3682 62499999.98974 +3697 3682 -71622975.29333 +3698 3682 14949536.00687 +3783 3682 -9.983777999878e-07 +3784 3682 -34841942.9836 +3785 3682 -6857580.506883 +3786 3682 -15625000.00514 +3787 3682 -37868205.17313 +3788 3682 19401012.48091 +3792 3682 3.09944152832e-06 +3793 3682 39706666.64553 +3794 3682 -27430322.01402 +3795 3682 -7.04824924469e-06 +3796 3682 -107392689.3388 +3797 3682 79112730.44064 +3804 3682 1.668930053711e-06 +3805 3682 -39138290.32084 +3806 3682 -6857580.506883 +3807 3682 15625000.00513 +3808 3682 -39280887.92821 +3809 3682 20086776.37002 +3683 3683 1209684727.759 +3684 3683 2285899.092332 +3685 3683 54860644.00101 +3686 3683 128167058.7484 +3693 3683 -4571798.18244 +3694 3683 -27430322.01402 +3695 3683 114598543.8875 +3696 3683 -27030536.34739 +3697 3683 15223841.56225 +3698 3683 -16689642.3626 +3783 3683 80261824.7461 +3784 3683 -6857580.506883 +3785 3683 -101938662.0149 +3786 3683 26537352.8999 +3787 3683 19401012.48091 +3788 3683 -57405640.83529 +3792 3683 2285899.092361 +3793 3683 -27430322.01402 +3794 3683 -242725472.4512 +3795 3683 571474.773379 +3796 3683 78838424.88527 +3797 3683 -190201211.678 +3804 3683 -82547723.83843 +3805 3683 -6857580.506883 +3806 3683 -113395588.2476 +3807 3683 -27108827.67327 +3808 3683 20086776.37002 +3809 3683 -61172794.84886 +3684 3684 1126552465.849 +3685 3684 1.227855682373e-05 +3686 3684 9143596.364805 +3687 3684 141293458.9169 +3688 3684 -4.947185516357e-06 +3689 3684 2285899.092331 +3693 3684 -89019318.86449 +3694 3684 -62499999.98974 +3695 3684 24744637.25504 +3696 3684 -218486531.0803 +3697 3684 2.98023223877e-06 +3698 3684 -4571798.18244 +3699 3684 -90373702.5448 +3700 3684 62499999.98974 +3701 3684 -26687654.40317 +3783 3684 -26783317.53868 +3784 3684 15625000.00513 +3785 3684 13679279.97901 +3786 3684 -103592244.5474 +3787 3684 1.892447471619e-06 +3788 3684 80604706.69032 +3789 3684 -42555886.98831 +3790 3684 -15625000.00514 +3791 3684 26537352.8999 +3792 3684 16426910.05153 +3793 3684 4.485249519348e-06 +3794 3684 571474.7733669 +3795 3684 77208121.14848 +3796 3684 3.09944152832e-06 +3797 3684 2285899.092361 +3798 3684 -48017751.39621 +3799 3684 -8.776783943176e-06 +3800 3684 571474.7733788 +3804 3684 -27518808.45327 +3805 3684 -15625000.00513 +3806 3684 -14250754.75238 +3807 3684 -107888591.8846 +3808 3684 1.713633537292e-06 +3809 3684 -82890605.78265 +3810 3684 -43968569.74338 +3811 3684 15625000.00513 +3812 3684 -27108827.67327 +3685 3685 976546647.911 +3686 3685 -109721288.002 +3687 3685 -4.738569259644e-06 +3688 3685 -96206292.73656 +3689 3685 54860644.00101 +3693 3685 -62499999.98974 +3694 3685 -70268591.613 +3695 3685 12480786.00715 +3696 3685 4.291534423828e-06 +3697 3685 56514675.03912 +3698 3685 -27430322.01402 +3699 3685 62499999.98974 +3700 3685 -71622975.29333 +3701 3685 14949536.00687 +3783 3685 15625000.00513 +3784 3685 -22095635.7235 +3785 3685 -12543431.97403 +3786 3685 -9.983777999878e-07 +3787 3685 -34841942.9836 +3788 3685 -6857580.506883 +3789 3685 -15625000.00514 +3790 3685 -37868205.17313 +3791 3685 19401012.48091 +3792 3685 5.781650543213e-06 +3793 3685 -42948027.89108 +3794 3685 -51682408.42662 +3795 3685 3.09944152832e-06 +3796 3685 39706666.64553 +3797 3685 -27430322.01402 +3798 3685 -7.04824924469e-06 +3799 3685 -107392689.3388 +3800 3685 79112730.44064 +3804 3685 -15625000.00513 +3805 3685 -22831126.63809 +3806 3685 -13229195.86314 +3807 3685 1.668930053711e-06 +3808 3685 -39138290.32084 +3809 3685 -6857580.506883 +3810 3685 15625000.00513 +3811 3685 -39280887.92821 +3812 3685 20086776.37002 +3686 3686 1209684727.759 +3687 3686 2285899.092332 +3688 3686 54860644.00101 +3689 3686 128167058.7484 +3693 3686 24401755.31083 +3694 3686 12206480.45177 +3695 3686 -13077952.54839 +3696 3686 -4571798.18244 +3697 3686 -27430322.01402 +3698 3686 114598543.8875 +3699 3686 -27030536.34739 +3700 3686 15223841.56225 +3701 3686 -16689642.3626 +3783 3686 13679279.97901 +3784 3686 -12543431.97403 +3785 3686 -15345455.6363 +3786 3686 80261824.7461 +3787 3686 -6857580.506883 +3788 3686 -101938662.0149 +3789 3686 26537352.8999 +3790 3686 19401012.48091 +3791 3686 -57405640.83529 +3792 3686 571474.7733671 +3793 3686 -51408102.87125 +3794 3686 -18348781.1507 +3795 3686 2285899.092361 +3796 3686 -27430322.01402 +3797 3686 -242725472.4512 +3798 3686 571474.773379 +3799 3686 78838424.88527 +3800 3686 -190201211.678 +3804 3686 -14250754.75238 +3805 3686 -13229195.86314 +3806 3686 -17306764.74188 +3807 3686 -82547723.83843 +3808 3686 -6857580.506883 +3809 3686 -113395588.2476 +3810 3686 -27108827.67327 +3811 3686 20086776.37002 +3812 3686 -61172794.84886 +3687 3687 1206829602.888 +3688 3687 62536821.50566 +3689 3687 30859020.00955 +3690 3687 35818303.75647 +3691 3687 -62514728.59611 +3692 3687 26693781.96925 +3696 3687 -89019318.86449 +3697 3687 -62499999.98974 +3698 3687 24744637.25504 +3699 3687 -218486531.0803 +3700 3687 2.98023223877e-06 +3701 3687 -4571798.18244 +3702 3687 -90373702.5448 +3703 3687 62499999.98974 +3704 3687 -26687654.40317 +3786 3687 -26783317.53868 +3787 3687 15625000.00513 +3788 3687 13679279.97901 +3789 3687 -119411159.8837 +3790 3687 -15630523.23252 +3791 3687 75186254.88774 +3795 3687 16426910.05153 +3796 3687 4.485249519348e-06 +3797 3687 571474.7733669 +3798 3687 109890622.1535 +3799 3687 15634205.38412 +3800 3687 7712478.882864 +3801 3687 -60563825.20041 +3802 3687 -15628682.15673 +3803 3687 27115214.46942 +3807 3687 -27518808.45327 +3808 3687 -15625000.00513 +3809 3687 -14250754.75238 +3810 3687 -107888591.8846 +3811 3687 1.713633537292e-06 +3812 3687 -82890605.78265 +3813 3687 -43968569.74338 +3814 3687 15625000.00513 +3815 3687 -27108827.67327 +3688 3688 1038056487.373 +3689 3688 -85034336.6799 +3690 3688 -62522092.89929 +3691 3688 -182960177.6074 +3692 3688 45539436.5079 +3696 3688 -62499999.98974 +3697 3688 -70268591.613 +3698 3688 12480786.00715 +3699 3688 4.291534423828e-06 +3700 3688 56514675.03912 +3701 3688 -27430322.01402 +3702 3688 62499999.98974 +3703 3688 -71622975.29333 +3704 3688 14949536.00687 +3786 3688 15625000.00513 +3787 3688 -22095635.7235 +3788 3688 -12543431.97403 +3789 3688 -15628682.15673 +3790 3688 -45961669.68301 +3791 3688 8705839.731277 +3795 3688 5.781650543213e-06 +3796 3688 -42948027.89108 +3797 3688 -51682408.42662 +3798 3688 15634205.38412 +3799 3688 67697343.25408 +3800 3688 -21260405.06448 +3801 3688 -15630523.23252 +3802 3688 -115258445.5683 +3803 3688 76792017.46155 +3807 3688 -15625000.00513 +3808 3688 -22831126.63809 +3809 3688 -13229195.86314 +3810 3688 1.668930053711e-06 +3811 3688 -39138290.32084 +3812 3688 -6857580.506883 +3813 3688 15625000.00513 +3814 3688 -39280887.92821 +3815 3688 20086776.37002 +3689 3689 1199251971.759 +3690 3689 27039727.69652 +3691 3689 53222308.42241 +3692 3689 71236333.03937 +3696 3689 24401755.31083 +3697 3689 12206480.45177 +3698 3689 -13077952.54839 +3699 3689 -4571798.18244 +3700 3689 -27430322.01402 +3701 3689 114598543.8875 +3702 3689 -27030536.34739 +3703 3689 15223841.56225 +3704 3689 -16689642.3626 +3786 3689 13679279.97901 +3787 3689 -12543431.97403 +3788 3689 -15345455.6363 +3789 3689 74842632.24213 +3790 3689 6787043.609902 +3791 3689 -88003520.09856 +3795 3689 571474.7733671 +3796 3689 -51408102.87125 +3797 3689 -18348781.1507 +3798 3689 7717283.578221 +3799 3689 -21256561.34093 +3800 3689 -211698416.8248 +3801 3689 27118407.8675 +3802 3689 78438470.16785 +3803 3689 -167573319.7819 +3807 3689 -14250754.75238 +3808 3689 -13229195.86314 +3809 3689 -17306764.74188 +3810 3689 -82547723.83843 +3811 3689 -6857580.506883 +3812 3689 -113395588.2476 +3813 3689 -27108827.67327 +3814 3689 20086776.37002 +3815 3689 -61172794.84886 +3690 3690 713665840.9484 +3691 3690 62499999.98975 +3692 3690 26303045.6496 +3699 3690 -89019318.86449 +3700 3690 -62499999.98974 +3701 3690 24744637.25504 +3702 3690 -333091779.4995 +3703 3690 -62514728.59611 +3704 3690 -26296716.12064 +3705 3690 15411687.79098 +3706 3690 50014728.59815 +3707 3690 -21264808.11782 +3789 3690 789479.8663111 +3790 3690 18755523.23355 +3791 3690 16762853.88037 +3798 3690 -11151323.14121 +3799 3690 -15630523.23252 +3800 3690 -13684113.02055 +3801 3690 50455843.08525 +3802 3690 15625000.00514 +3803 3690 23750485.45243 +3810 3690 -27518808.45327 +3811 3690 -15625000.00513 +3812 3690 -14250754.75238 +3813 3690 -136601119.3265 +3814 3690 -15628682.15673 +3815 3690 -88333821.76341 +3816 3690 -31442472.41633 +3817 3690 12503682.1557 +3818 3690 -21464859.02542 +3691 3691 619895634.403 +3692 3691 -68588052.25144 +3699 3691 -62499999.98974 +3700 3691 -70268591.613 +3701 3691 12480786.00715 +3702 3691 -62522092.89929 +3703 3691 -39293818.84171 +3704 3691 -37998394.10174 +3705 3691 75022092.89723 +3706 3691 15411687.79098 +3707 3691 23871774.7618 +3789 3691 12503682.1557 +3790 3691 789479.8663122 +3791 3691 -8940185.539224 +3798 3691 -15628682.15672 +3799 3691 -65845943.5091 +3800 3691 -52101581.10086 +3801 3691 15625000.00514 +3802 3691 27013291.43733 +3803 3691 -3407345.083582 +3810 3691 -15625000.00513 +3811 3691 -22831126.63809 +3812 3691 -13229195.86314 +3813 3691 -15630523.23252 +3814 3691 -63151629.12586 +3815 3691 -25854695.88552 +3816 3691 18755523.23355 +3817 3691 -31442472.41633 +3818 3691 25757502.85539 +3692 3692 781376197.173 +3699 3692 24401755.31083 +3700 3692 12206480.45177 +3701 3692 -13077952.54839 +3702 3692 -26293551.35616 +3703 3692 -30589746.95883 +3704 3692 33460212.57848 +3705 3692 -31897212.17672 +3706 3692 15914516.50787 +3707 3692 41097834.10927 +3789 3692 11175235.92025 +3790 3692 -13410278.30884 +3791 3692 2105279.643495 +3798 3692 -13682502.0067 +3799 3692 -53748034.02747 +3800 3692 -35806647.62401 +3801 3692 -8884805.348678 +3802 3692 -29515355.2492 +3803 3692 -145884263.2499 +3810 3692 -14250754.75238 +3811 3692 -13229195.86314 +3812 3692 -17306764.74188 +3813 3692 -87990199.11779 +3814 3692 -23932056.04702 +3815 3692 -133843411.9462 +3816 3692 -32197288.53812 +3817 3692 17171668.57026 +3818 3692 -83846593.11021 +3693 3693 1126552465.849 +3694 3693 1.227855682373e-05 +3695 3693 9143596.364805 +3696 3693 141293458.9169 +3697 3693 -4.947185516357e-06 +3698 3693 2285899.092331 +3708 3693 -218486531.0803 +3709 3693 2.98023223877e-06 +3710 3693 -4571798.18244 +3711 3693 -90373702.5448 +3712 3693 62499999.98974 +3713 3693 -26687654.40317 +3792 3693 -103592244.5474 +3793 3693 1.892447471619e-06 +3794 3693 80604706.69032 +3795 3693 -42555886.98831 +3796 3693 -15625000.00514 +3797 3693 26537352.8999 +3804 3693 77208121.14848 +3805 3693 3.09944152832e-06 +3806 3693 2285899.092361 +3807 3693 -48017751.39621 +3808 3693 -8.776783943176e-06 +3809 3693 571474.7733788 +3819 3693 -107888591.8846 +3820 3693 1.713633537292e-06 +3821 3693 -82890605.78265 +3822 3693 -43968569.74338 +3823 3693 15625000.00513 +3824 3693 -27108827.67327 +3694 3694 976546647.911 +3695 3694 -109721288.002 +3696 3694 -4.738569259644e-06 +3697 3694 -96206292.73656 +3698 3694 54860644.00101 +3708 3694 4.291534423828e-06 +3709 3694 56514675.03912 +3710 3694 -27430322.01402 +3711 3694 62499999.98974 +3712 3694 -71622975.29333 +3713 3694 14949536.00687 +3792 3694 -9.983777999878e-07 +3793 3694 -34841942.9836 +3794 3694 -6857580.506883 +3795 3694 -15625000.00514 +3796 3694 -37868205.17313 +3797 3694 19401012.48091 +3804 3694 3.09944152832e-06 +3805 3694 39706666.64553 +3806 3694 -27430322.01402 +3807 3694 -7.04824924469e-06 +3808 3694 -107392689.3388 +3809 3694 79112730.44064 +3819 3694 1.668930053711e-06 +3820 3694 -39138290.32084 +3821 3694 -6857580.506883 +3822 3694 15625000.00513 +3823 3694 -39280887.92821 +3824 3694 20086776.37002 +3695 3695 1209684727.759 +3696 3695 2285899.092332 +3697 3695 54860644.00101 +3698 3695 128167058.7484 +3708 3695 -4571798.18244 +3709 3695 -27430322.01402 +3710 3695 114598543.8875 +3711 3695 -27030536.34739 +3712 3695 15223841.56225 +3713 3695 -16689642.3626 +3792 3695 80261824.7461 +3793 3695 -6857580.506883 +3794 3695 -101938662.0149 +3795 3695 26537352.8999 +3796 3695 19401012.48091 +3797 3695 -57405640.83529 +3804 3695 2285899.092361 +3805 3695 -27430322.01402 +3806 3695 -242725472.4512 +3807 3695 571474.773379 +3808 3695 78838424.88527 +3809 3695 -190201211.678 +3819 3695 -82547723.83843 +3820 3695 -6857580.506883 +3821 3695 -113395588.2476 +3822 3695 -27108827.67327 +3823 3695 20086776.37002 +3824 3695 -61172794.84886 +3696 3696 1126552465.849 +3697 3696 1.227855682373e-05 +3698 3696 9143596.364805 +3699 3696 141293458.9169 +3700 3696 -4.947185516357e-06 +3701 3696 2285899.092331 +3708 3696 -89019318.86449 +3709 3696 -62499999.98974 +3710 3696 24744637.25504 +3711 3696 -218486531.0803 +3712 3696 2.98023223877e-06 +3713 3696 -4571798.18244 +3714 3696 -90373702.5448 +3715 3696 62499999.98974 +3716 3696 -26687654.40317 +3792 3696 -26783317.53868 +3793 3696 15625000.00513 +3794 3696 13679279.97901 +3795 3696 -103592244.5474 +3796 3696 1.892447471619e-06 +3797 3696 80604706.69032 +3798 3696 -42555886.98831 +3799 3696 -15625000.00514 +3800 3696 26537352.8999 +3804 3696 16426910.05153 +3805 3696 4.485249519348e-06 +3806 3696 571474.7733669 +3807 3696 77208121.14848 +3808 3696 3.09944152832e-06 +3809 3696 2285899.092361 +3810 3696 -48017751.39621 +3811 3696 -8.776783943176e-06 +3812 3696 571474.7733788 +3819 3696 -27518808.45327 +3820 3696 -15625000.00513 +3821 3696 -14250754.75238 +3822 3696 -107888591.8846 +3823 3696 1.713633537292e-06 +3824 3696 -82890605.78265 +3825 3696 -43968569.74338 +3826 3696 15625000.00513 +3827 3696 -27108827.67327 +3697 3697 976546647.911 +3698 3697 -109721288.002 +3699 3697 -4.738569259644e-06 +3700 3697 -96206292.73656 +3701 3697 54860644.00101 +3708 3697 -62499999.98974 +3709 3697 -70268591.613 +3710 3697 12480786.00715 +3711 3697 4.291534423828e-06 +3712 3697 56514675.03912 +3713 3697 -27430322.01402 +3714 3697 62499999.98974 +3715 3697 -71622975.29333 +3716 3697 14949536.00687 +3792 3697 15625000.00513 +3793 3697 -22095635.7235 +3794 3697 -12543431.97403 +3795 3697 -9.983777999878e-07 +3796 3697 -34841942.9836 +3797 3697 -6857580.506883 +3798 3697 -15625000.00514 +3799 3697 -37868205.17313 +3800 3697 19401012.48091 +3804 3697 5.781650543213e-06 +3805 3697 -42948027.89108 +3806 3697 -51682408.42662 +3807 3697 3.09944152832e-06 +3808 3697 39706666.64553 +3809 3697 -27430322.01402 +3810 3697 -7.04824924469e-06 +3811 3697 -107392689.3388 +3812 3697 79112730.44064 +3819 3697 -15625000.00513 +3820 3697 -22831126.63809 +3821 3697 -13229195.86314 +3822 3697 1.668930053711e-06 +3823 3697 -39138290.32084 +3824 3697 -6857580.506883 +3825 3697 15625000.00513 +3826 3697 -39280887.92821 +3827 3697 20086776.37002 +3698 3698 1209684727.759 +3699 3698 2285899.092332 +3700 3698 54860644.00101 +3701 3698 128167058.7484 +3708 3698 24401755.31083 +3709 3698 12206480.45177 +3710 3698 -13077952.54839 +3711 3698 -4571798.18244 +3712 3698 -27430322.01402 +3713 3698 114598543.8875 +3714 3698 -27030536.34739 +3715 3698 15223841.56225 +3716 3698 -16689642.3626 +3792 3698 13679279.97901 +3793 3698 -12543431.97403 +3794 3698 -15345455.6363 +3795 3698 80261824.7461 +3796 3698 -6857580.506883 +3797 3698 -101938662.0149 +3798 3698 26537352.8999 +3799 3698 19401012.48091 +3800 3698 -57405640.83529 +3804 3698 571474.7733671 +3805 3698 -51408102.87125 +3806 3698 -18348781.1507 +3807 3698 2285899.092361 +3808 3698 -27430322.01402 +3809 3698 -242725472.4512 +3810 3698 571474.773379 +3811 3698 78838424.88527 +3812 3698 -190201211.678 +3819 3698 -14250754.75238 +3820 3698 -13229195.86314 +3821 3698 -17306764.74188 +3822 3698 -82547723.83843 +3823 3698 -6857580.506883 +3824 3698 -113395588.2476 +3825 3698 -27108827.67327 +3826 3698 20086776.37002 +3827 3698 -61172794.84886 +3699 3699 1126552465.849 +3700 3699 1.227855682373e-05 +3701 3699 9143596.364805 +3702 3699 141293458.9169 +3703 3699 -4.947185516357e-06 +3704 3699 2285899.092331 +3711 3699 -89019318.86449 +3712 3699 -62499999.98974 +3713 3699 24744637.25504 +3714 3699 -218486531.0803 +3715 3699 2.98023223877e-06 +3716 3699 -4571798.18244 +3717 3699 -90373702.5448 +3718 3699 62499999.98974 +3719 3699 -26687654.40317 +3795 3699 -26783317.53868 +3796 3699 15625000.00513 +3797 3699 13679279.97901 +3798 3699 -103592244.5474 +3799 3699 1.892447471619e-06 +3800 3699 80604706.69032 +3801 3699 -42555886.98831 +3802 3699 -15625000.00514 +3803 3699 26537352.8999 +3807 3699 16426910.05153 +3808 3699 4.485249519348e-06 +3809 3699 571474.7733669 +3810 3699 77208121.14848 +3811 3699 3.09944152832e-06 +3812 3699 2285899.092361 +3813 3699 -48017751.39621 +3814 3699 -8.776783943176e-06 +3815 3699 571474.7733788 +3822 3699 -27518808.45327 +3823 3699 -15625000.00513 +3824 3699 -14250754.75238 +3825 3699 -107888591.8846 +3826 3699 1.713633537292e-06 +3827 3699 -82890605.78265 +3828 3699 -43968569.74338 +3829 3699 15625000.00513 +3830 3699 -27108827.67327 +3700 3700 976546647.911 +3701 3700 -109721288.002 +3702 3700 -4.738569259644e-06 +3703 3700 -96206292.73656 +3704 3700 54860644.00101 +3711 3700 -62499999.98974 +3712 3700 -70268591.613 +3713 3700 12480786.00715 +3714 3700 4.291534423828e-06 +3715 3700 56514675.03912 +3716 3700 -27430322.01402 +3717 3700 62499999.98974 +3718 3700 -71622975.29333 +3719 3700 14949536.00687 +3795 3700 15625000.00513 +3796 3700 -22095635.7235 +3797 3700 -12543431.97403 +3798 3700 -9.983777999878e-07 +3799 3700 -34841942.9836 +3800 3700 -6857580.506883 +3801 3700 -15625000.00514 +3802 3700 -37868205.17313 +3803 3700 19401012.48091 +3807 3700 5.781650543213e-06 +3808 3700 -42948027.89108 +3809 3700 -51682408.42662 +3810 3700 3.09944152832e-06 +3811 3700 39706666.64553 +3812 3700 -27430322.01402 +3813 3700 -7.04824924469e-06 +3814 3700 -107392689.3388 +3815 3700 79112730.44064 +3822 3700 -15625000.00513 +3823 3700 -22831126.63809 +3824 3700 -13229195.86314 +3825 3700 1.668930053711e-06 +3826 3700 -39138290.32084 +3827 3700 -6857580.506883 +3828 3700 15625000.00513 +3829 3700 -39280887.92821 +3830 3700 20086776.37002 +3701 3701 1209684727.759 +3702 3701 2285899.092332 +3703 3701 54860644.00101 +3704 3701 128167058.7484 +3711 3701 24401755.31083 +3712 3701 12206480.45177 +3713 3701 -13077952.54839 +3714 3701 -4571798.18244 +3715 3701 -27430322.01402 +3716 3701 114598543.8875 +3717 3701 -27030536.34739 +3718 3701 15223841.56225 +3719 3701 -16689642.3626 +3795 3701 13679279.97901 +3796 3701 -12543431.97403 +3797 3701 -15345455.6363 +3798 3701 80261824.7461 +3799 3701 -6857580.506883 +3800 3701 -101938662.0149 +3801 3701 26537352.8999 +3802 3701 19401012.48091 +3803 3701 -57405640.83529 +3807 3701 571474.7733671 +3808 3701 -51408102.87125 +3809 3701 -18348781.1507 +3810 3701 2285899.092361 +3811 3701 -27430322.01402 +3812 3701 -242725472.4512 +3813 3701 571474.773379 +3814 3701 78838424.88527 +3815 3701 -190201211.678 +3822 3701 -14250754.75238 +3823 3701 -13229195.86314 +3824 3701 -17306764.74188 +3825 3701 -82547723.83843 +3826 3701 -6857580.506883 +3827 3701 -113395588.2476 +3828 3701 -27108827.67327 +3829 3701 20086776.37002 +3830 3701 -61172794.84886 +3702 3702 1206829602.888 +3703 3702 62536821.50566 +3704 3702 30859020.00955 +3705 3702 35818303.75647 +3706 3702 -62514728.59611 +3707 3702 26693781.96925 +3714 3702 -89019318.86449 +3715 3702 -62499999.98974 +3716 3702 24744637.25504 +3717 3702 -218486531.0803 +3718 3702 2.98023223877e-06 +3719 3702 -4571798.18244 +3720 3702 -90373702.5448 +3721 3702 62499999.98974 +3722 3702 -26687654.40317 +3798 3702 -26783317.53868 +3799 3702 15625000.00513 +3800 3702 13679279.97901 +3801 3702 -119411159.8837 +3802 3702 -15630523.23252 +3803 3702 75186254.88774 +3810 3702 16426910.05153 +3811 3702 4.485249519348e-06 +3812 3702 571474.7733669 +3813 3702 109890622.1535 +3814 3702 15634205.38412 +3815 3702 7712478.882864 +3816 3702 -60563825.20041 +3817 3702 -15628682.15673 +3818 3702 27115214.46942 +3825 3702 -27518808.45327 +3826 3702 -15625000.00513 +3827 3702 -14250754.75238 +3828 3702 -107888591.8846 +3829 3702 1.713633537292e-06 +3830 3702 -82890605.78265 +3831 3702 -43968569.74338 +3832 3702 15625000.00513 +3833 3702 -27108827.67327 +3703 3703 1038056487.373 +3704 3703 -85034336.6799 +3705 3703 -62522092.89929 +3706 3703 -182960177.6074 +3707 3703 45539436.5079 +3714 3703 -62499999.98974 +3715 3703 -70268591.613 +3716 3703 12480786.00715 +3717 3703 4.291534423828e-06 +3718 3703 56514675.03912 +3719 3703 -27430322.01402 +3720 3703 62499999.98974 +3721 3703 -71622975.29333 +3722 3703 14949536.00687 +3798 3703 15625000.00513 +3799 3703 -22095635.7235 +3800 3703 -12543431.97403 +3801 3703 -15628682.15673 +3802 3703 -45961669.68301 +3803 3703 8705839.731277 +3810 3703 5.781650543213e-06 +3811 3703 -42948027.89108 +3812 3703 -51682408.42662 +3813 3703 15634205.38412 +3814 3703 67697343.25408 +3815 3703 -21260405.06448 +3816 3703 -15630523.23252 +3817 3703 -115258445.5683 +3818 3703 76792017.46155 +3825 3703 -15625000.00513 +3826 3703 -22831126.63809 +3827 3703 -13229195.86314 +3828 3703 1.668930053711e-06 +3829 3703 -39138290.32084 +3830 3703 -6857580.506883 +3831 3703 15625000.00513 +3832 3703 -39280887.92821 +3833 3703 20086776.37002 +3704 3704 1199251971.759 +3705 3704 27039727.69652 +3706 3704 53222308.42241 +3707 3704 71236333.03937 +3714 3704 24401755.31083 +3715 3704 12206480.45177 +3716 3704 -13077952.54839 +3717 3704 -4571798.18244 +3718 3704 -27430322.01402 +3719 3704 114598543.8875 +3720 3704 -27030536.34739 +3721 3704 15223841.56225 +3722 3704 -16689642.3626 +3798 3704 13679279.97901 +3799 3704 -12543431.97403 +3800 3704 -15345455.6363 +3801 3704 74842632.24213 +3802 3704 6787043.609902 +3803 3704 -88003520.09856 +3810 3704 571474.7733671 +3811 3704 -51408102.87125 +3812 3704 -18348781.1507 +3813 3704 7717283.578221 +3814 3704 -21256561.34093 +3815 3704 -211698416.8248 +3816 3704 27118407.8675 +3817 3704 78438470.16785 +3818 3704 -167573319.7819 +3825 3704 -14250754.75238 +3826 3704 -13229195.86314 +3827 3704 -17306764.74188 +3828 3704 -82547723.83843 +3829 3704 -6857580.506883 +3830 3704 -113395588.2476 +3831 3704 -27108827.67327 +3832 3704 20086776.37002 +3833 3704 -61172794.84886 +3705 3705 713665840.9484 +3706 3705 62499999.98975 +3707 3705 26303045.6496 +3717 3705 -89019318.86449 +3718 3705 -62499999.98974 +3719 3705 24744637.25504 +3720 3705 -333091779.4995 +3721 3705 -62514728.59611 +3722 3705 -26296716.12064 +3723 3705 15411687.79098 +3724 3705 50014728.59815 +3725 3705 -21264808.11782 +3801 3705 789479.8663111 +3802 3705 18755523.23355 +3803 3705 16762853.88037 +3813 3705 -11151323.14121 +3814 3705 -15630523.23252 +3815 3705 -13684113.02055 +3816 3705 50455843.08525 +3817 3705 15625000.00514 +3818 3705 23750485.45243 +3828 3705 -27518808.45327 +3829 3705 -15625000.00513 +3830 3705 -14250754.75238 +3831 3705 -136601119.3265 +3832 3705 -15628682.15673 +3833 3705 -88333821.76341 +3834 3705 -31442472.41633 +3835 3705 12503682.1557 +3836 3705 -21464859.02542 +3706 3706 619895634.403 +3707 3706 -68588052.25144 +3717 3706 -62499999.98974 +3718 3706 -70268591.613 +3719 3706 12480786.00715 +3720 3706 -62522092.89929 +3721 3706 -39293818.84171 +3722 3706 -37998394.10174 +3723 3706 75022092.89723 +3724 3706 15411687.79098 +3725 3706 23871774.7618 +3801 3706 12503682.1557 +3802 3706 789479.8663122 +3803 3706 -8940185.539224 +3813 3706 -15628682.15672 +3814 3706 -65845943.5091 +3815 3706 -52101581.10086 +3816 3706 15625000.00514 +3817 3706 27013291.43733 +3818 3706 -3407345.083582 +3828 3706 -15625000.00513 +3829 3706 -22831126.63809 +3830 3706 -13229195.86314 +3831 3706 -15630523.23252 +3832 3706 -63151629.12586 +3833 3706 -25854695.88552 +3834 3706 18755523.23355 +3835 3706 -31442472.41633 +3836 3706 25757502.85539 +3707 3707 781376197.173 +3717 3707 24401755.31083 +3718 3707 12206480.45177 +3719 3707 -13077952.54839 +3720 3707 -26293551.35616 +3721 3707 -30589746.95883 +3722 3707 33460212.57848 +3723 3707 -31897212.17672 +3724 3707 15914516.50787 +3725 3707 41097834.10927 +3801 3707 11175235.92025 +3802 3707 -13410278.30884 +3803 3707 2105279.643495 +3813 3707 -13682502.0067 +3814 3707 -53748034.02747 +3815 3707 -35806647.62401 +3816 3707 -8884805.348678 +3817 3707 -29515355.2492 +3818 3707 -145884263.2499 +3828 3707 -14250754.75238 +3829 3707 -13229195.86314 +3830 3707 -17306764.74188 +3831 3707 -87990199.11779 +3832 3707 -23932056.04702 +3833 3707 -133843411.9462 +3834 3707 -32197288.53812 +3835 3707 17171668.57026 +3836 3707 -83846593.11021 +3708 3708 1126552465.849 +3709 3708 1.227855682373e-05 +3710 3708 9143596.364805 +3711 3708 141293458.9169 +3712 3708 -4.947185516357e-06 +3713 3708 2285899.092331 +3726 3708 -218486531.0803 +3727 3708 2.98023223877e-06 +3728 3708 -4571798.18244 +3729 3708 -90373702.5448 +3730 3708 62499999.98974 +3731 3708 -26687654.40317 +3804 3708 -103592244.5474 +3805 3708 1.892447471619e-06 +3806 3708 80604706.69032 +3807 3708 -42555886.98831 +3808 3708 -15625000.00514 +3809 3708 26537352.8999 +3819 3708 77208121.14848 +3820 3708 3.09944152832e-06 +3821 3708 2285899.092361 +3822 3708 -48017751.39621 +3823 3708 -8.776783943176e-06 +3824 3708 571474.7733788 +3837 3708 -107888591.8846 +3838 3708 1.713633537292e-06 +3839 3708 -82890605.78265 +3840 3708 -43968569.74338 +3841 3708 15625000.00513 +3842 3708 -27108827.67327 +3709 3709 976546647.911 +3710 3709 -109721288.002 +3711 3709 -4.738569259644e-06 +3712 3709 -96206292.73656 +3713 3709 54860644.00101 +3726 3709 4.291534423828e-06 +3727 3709 56514675.03912 +3728 3709 -27430322.01402 +3729 3709 62499999.98974 +3730 3709 -71622975.29333 +3731 3709 14949536.00687 +3804 3709 -9.983777999878e-07 +3805 3709 -34841942.9836 +3806 3709 -6857580.506883 +3807 3709 -15625000.00514 +3808 3709 -37868205.17313 +3809 3709 19401012.48091 +3819 3709 3.09944152832e-06 +3820 3709 39706666.64553 +3821 3709 -27430322.01402 +3822 3709 -7.04824924469e-06 +3823 3709 -107392689.3388 +3824 3709 79112730.44064 +3837 3709 1.668930053711e-06 +3838 3709 -39138290.32084 +3839 3709 -6857580.506883 +3840 3709 15625000.00513 +3841 3709 -39280887.92821 +3842 3709 20086776.37002 +3710 3710 1209684727.759 +3711 3710 2285899.092332 +3712 3710 54860644.00101 +3713 3710 128167058.7484 +3726 3710 -4571798.18244 +3727 3710 -27430322.01402 +3728 3710 114598543.8875 +3729 3710 -27030536.34739 +3730 3710 15223841.56225 +3731 3710 -16689642.3626 +3804 3710 80261824.7461 +3805 3710 -6857580.506883 +3806 3710 -101938662.0149 +3807 3710 26537352.8999 +3808 3710 19401012.48091 +3809 3710 -57405640.83529 +3819 3710 2285899.092361 +3820 3710 -27430322.01402 +3821 3710 -242725472.4512 +3822 3710 571474.773379 +3823 3710 78838424.88527 +3824 3710 -190201211.678 +3837 3710 -82547723.83843 +3838 3710 -6857580.506883 +3839 3710 -113395588.2476 +3840 3710 -27108827.67327 +3841 3710 20086776.37002 +3842 3710 -61172794.84886 +3711 3711 1126552465.849 +3712 3711 1.227855682373e-05 +3713 3711 9143596.364805 +3714 3711 141293458.9169 +3715 3711 -4.947185516357e-06 +3716 3711 2285899.092331 +3726 3711 -89019318.86449 +3727 3711 -62499999.98974 +3728 3711 24744637.25504 +3729 3711 -218486531.0803 +3730 3711 2.98023223877e-06 +3731 3711 -4571798.18244 +3732 3711 -90373702.5448 +3733 3711 62499999.98974 +3734 3711 -26687654.40317 +3804 3711 -26783317.53868 +3805 3711 15625000.00513 +3806 3711 13679279.97901 +3807 3711 -103592244.5474 +3808 3711 1.892447471619e-06 +3809 3711 80604706.69032 +3810 3711 -42555886.98831 +3811 3711 -15625000.00514 +3812 3711 26537352.8999 +3819 3711 16426910.05153 +3820 3711 4.485249519348e-06 +3821 3711 571474.7733669 +3822 3711 77208121.14848 +3823 3711 3.09944152832e-06 +3824 3711 2285899.092361 +3825 3711 -48017751.39621 +3826 3711 -8.776783943176e-06 +3827 3711 571474.7733788 +3837 3711 -27518808.45327 +3838 3711 -15625000.00513 +3839 3711 -14250754.75238 +3840 3711 -107888591.8846 +3841 3711 1.713633537292e-06 +3842 3711 -82890605.78265 +3843 3711 -43968569.74338 +3844 3711 15625000.00513 +3845 3711 -27108827.67327 +3712 3712 976546647.911 +3713 3712 -109721288.002 +3714 3712 -4.738569259644e-06 +3715 3712 -96206292.73656 +3716 3712 54860644.00101 +3726 3712 -62499999.98974 +3727 3712 -70268591.613 +3728 3712 12480786.00715 +3729 3712 4.291534423828e-06 +3730 3712 56514675.03912 +3731 3712 -27430322.01402 +3732 3712 62499999.98974 +3733 3712 -71622975.29333 +3734 3712 14949536.00687 +3804 3712 15625000.00513 +3805 3712 -22095635.7235 +3806 3712 -12543431.97403 +3807 3712 -9.983777999878e-07 +3808 3712 -34841942.9836 +3809 3712 -6857580.506883 +3810 3712 -15625000.00514 +3811 3712 -37868205.17313 +3812 3712 19401012.48091 +3819 3712 5.781650543213e-06 +3820 3712 -42948027.89108 +3821 3712 -51682408.42662 +3822 3712 3.09944152832e-06 +3823 3712 39706666.64553 +3824 3712 -27430322.01402 +3825 3712 -7.04824924469e-06 +3826 3712 -107392689.3388 +3827 3712 79112730.44064 +3837 3712 -15625000.00513 +3838 3712 -22831126.63809 +3839 3712 -13229195.86314 +3840 3712 1.668930053711e-06 +3841 3712 -39138290.32084 +3842 3712 -6857580.506883 +3843 3712 15625000.00513 +3844 3712 -39280887.92821 +3845 3712 20086776.37002 +3713 3713 1209684727.759 +3714 3713 2285899.092332 +3715 3713 54860644.00101 +3716 3713 128167058.7484 +3726 3713 24401755.31083 +3727 3713 12206480.45177 +3728 3713 -13077952.54839 +3729 3713 -4571798.18244 +3730 3713 -27430322.01402 +3731 3713 114598543.8875 +3732 3713 -27030536.34739 +3733 3713 15223841.56225 +3734 3713 -16689642.3626 +3804 3713 13679279.97901 +3805 3713 -12543431.97403 +3806 3713 -15345455.6363 +3807 3713 80261824.7461 +3808 3713 -6857580.506883 +3809 3713 -101938662.0149 +3810 3713 26537352.8999 +3811 3713 19401012.48091 +3812 3713 -57405640.83529 +3819 3713 571474.7733671 +3820 3713 -51408102.87125 +3821 3713 -18348781.1507 +3822 3713 2285899.092361 +3823 3713 -27430322.01402 +3824 3713 -242725472.4512 +3825 3713 571474.773379 +3826 3713 78838424.88527 +3827 3713 -190201211.678 +3837 3713 -14250754.75238 +3838 3713 -13229195.86314 +3839 3713 -17306764.74188 +3840 3713 -82547723.83843 +3841 3713 -6857580.506883 +3842 3713 -113395588.2476 +3843 3713 -27108827.67327 +3844 3713 20086776.37002 +3845 3713 -61172794.84886 +3714 3714 1126552465.849 +3715 3714 1.227855682373e-05 +3716 3714 9143596.364805 +3717 3714 141293458.9169 +3718 3714 -4.947185516357e-06 +3719 3714 2285899.092331 +3729 3714 -89019318.86449 +3730 3714 -62499999.98974 +3731 3714 24744637.25504 +3732 3714 -218486531.0803 +3733 3714 2.98023223877e-06 +3734 3714 -4571798.18244 +3735 3714 -90373702.5448 +3736 3714 62499999.98974 +3737 3714 -26687654.40317 +3807 3714 -26783317.53868 +3808 3714 15625000.00513 +3809 3714 13679279.97901 +3810 3714 -103592244.5474 +3811 3714 1.892447471619e-06 +3812 3714 80604706.69032 +3813 3714 -42555886.98831 +3814 3714 -15625000.00514 +3815 3714 26537352.8999 +3822 3714 16426910.05153 +3823 3714 4.485249519348e-06 +3824 3714 571474.7733669 +3825 3714 77208121.14848 +3826 3714 3.09944152832e-06 +3827 3714 2285899.092361 +3828 3714 -48017751.39621 +3829 3714 -8.776783943176e-06 +3830 3714 571474.7733788 +3840 3714 -27518808.45327 +3841 3714 -15625000.00513 +3842 3714 -14250754.75238 +3843 3714 -107888591.8846 +3844 3714 1.713633537292e-06 +3845 3714 -82890605.78265 +3846 3714 -43968569.74338 +3847 3714 15625000.00513 +3848 3714 -27108827.67327 +3715 3715 976546647.911 +3716 3715 -109721288.002 +3717 3715 -4.738569259644e-06 +3718 3715 -96206292.73656 +3719 3715 54860644.00101 +3729 3715 -62499999.98974 +3730 3715 -70268591.613 +3731 3715 12480786.00715 +3732 3715 4.291534423828e-06 +3733 3715 56514675.03912 +3734 3715 -27430322.01402 +3735 3715 62499999.98974 +3736 3715 -71622975.29333 +3737 3715 14949536.00687 +3807 3715 15625000.00513 +3808 3715 -22095635.7235 +3809 3715 -12543431.97403 +3810 3715 -9.983777999878e-07 +3811 3715 -34841942.9836 +3812 3715 -6857580.506883 +3813 3715 -15625000.00514 +3814 3715 -37868205.17313 +3815 3715 19401012.48091 +3822 3715 5.781650543213e-06 +3823 3715 -42948027.89108 +3824 3715 -51682408.42662 +3825 3715 3.09944152832e-06 +3826 3715 39706666.64553 +3827 3715 -27430322.01402 +3828 3715 -7.04824924469e-06 +3829 3715 -107392689.3388 +3830 3715 79112730.44064 +3840 3715 -15625000.00513 +3841 3715 -22831126.63809 +3842 3715 -13229195.86314 +3843 3715 1.668930053711e-06 +3844 3715 -39138290.32084 +3845 3715 -6857580.506883 +3846 3715 15625000.00513 +3847 3715 -39280887.92821 +3848 3715 20086776.37002 +3716 3716 1209684727.759 +3717 3716 2285899.092332 +3718 3716 54860644.00101 +3719 3716 128167058.7484 +3729 3716 24401755.31083 +3730 3716 12206480.45177 +3731 3716 -13077952.54839 +3732 3716 -4571798.18244 +3733 3716 -27430322.01402 +3734 3716 114598543.8875 +3735 3716 -27030536.34739 +3736 3716 15223841.56225 +3737 3716 -16689642.3626 +3807 3716 13679279.97901 +3808 3716 -12543431.97403 +3809 3716 -15345455.6363 +3810 3716 80261824.7461 +3811 3716 -6857580.506883 +3812 3716 -101938662.0149 +3813 3716 26537352.8999 +3814 3716 19401012.48091 +3815 3716 -57405640.83529 +3822 3716 571474.7733671 +3823 3716 -51408102.87125 +3824 3716 -18348781.1507 +3825 3716 2285899.092361 +3826 3716 -27430322.01402 +3827 3716 -242725472.4512 +3828 3716 571474.773379 +3829 3716 78838424.88527 +3830 3716 -190201211.678 +3840 3716 -14250754.75238 +3841 3716 -13229195.86314 +3842 3716 -17306764.74188 +3843 3716 -82547723.83843 +3844 3716 -6857580.506883 +3845 3716 -113395588.2476 +3846 3716 -27108827.67327 +3847 3716 20086776.37002 +3848 3716 -61172794.84886 +3717 3717 1126552465.849 +3718 3717 1.227855682373e-05 +3719 3717 9143596.364805 +3720 3717 141293458.9169 +3721 3717 -4.947185516357e-06 +3722 3717 2285899.092331 +3732 3717 -89019318.86449 +3733 3717 -62499999.98974 +3734 3717 24744637.25504 +3735 3717 -218486531.0803 +3736 3717 2.98023223877e-06 +3737 3717 -4571798.18244 +3738 3717 -90373702.5448 +3739 3717 62499999.98974 +3740 3717 -26687654.40317 +3810 3717 -26783317.53868 +3811 3717 15625000.00513 +3812 3717 13679279.97901 +3813 3717 -103592244.5474 +3814 3717 1.892447471619e-06 +3815 3717 80604706.69032 +3816 3717 -42555886.98831 +3817 3717 -15625000.00514 +3818 3717 26537352.8999 +3825 3717 16426910.05153 +3826 3717 4.485249519348e-06 +3827 3717 571474.7733669 +3828 3717 77208121.14848 +3829 3717 3.09944152832e-06 +3830 3717 2285899.092361 +3831 3717 -48017751.39621 +3832 3717 -8.776783943176e-06 +3833 3717 571474.7733788 +3843 3717 -27518808.45327 +3844 3717 -15625000.00513 +3845 3717 -14250754.75238 +3846 3717 -107888591.8846 +3847 3717 1.713633537292e-06 +3848 3717 -82890605.78265 +3849 3717 -43968569.74338 +3850 3717 15625000.00513 +3851 3717 -27108827.67327 +3718 3718 976546647.911 +3719 3718 -109721288.002 +3720 3718 -4.738569259644e-06 +3721 3718 -96206292.73656 +3722 3718 54860644.00101 +3732 3718 -62499999.98974 +3733 3718 -70268591.613 +3734 3718 12480786.00715 +3735 3718 4.291534423828e-06 +3736 3718 56514675.03912 +3737 3718 -27430322.01402 +3738 3718 62499999.98974 +3739 3718 -71622975.29333 +3740 3718 14949536.00687 +3810 3718 15625000.00513 +3811 3718 -22095635.7235 +3812 3718 -12543431.97403 +3813 3718 -9.983777999878e-07 +3814 3718 -34841942.9836 +3815 3718 -6857580.506883 +3816 3718 -15625000.00514 +3817 3718 -37868205.17313 +3818 3718 19401012.48091 +3825 3718 5.781650543213e-06 +3826 3718 -42948027.89108 +3827 3718 -51682408.42662 +3828 3718 3.09944152832e-06 +3829 3718 39706666.64553 +3830 3718 -27430322.01402 +3831 3718 -7.04824924469e-06 +3832 3718 -107392689.3388 +3833 3718 79112730.44064 +3843 3718 -15625000.00513 +3844 3718 -22831126.63809 +3845 3718 -13229195.86314 +3846 3718 1.668930053711e-06 +3847 3718 -39138290.32084 +3848 3718 -6857580.506883 +3849 3718 15625000.00513 +3850 3718 -39280887.92821 +3851 3718 20086776.37002 +3719 3719 1209684727.759 +3720 3719 2285899.092332 +3721 3719 54860644.00101 +3722 3719 128167058.7484 +3732 3719 24401755.31083 +3733 3719 12206480.45177 +3734 3719 -13077952.54839 +3735 3719 -4571798.18244 +3736 3719 -27430322.01402 +3737 3719 114598543.8875 +3738 3719 -27030536.34739 +3739 3719 15223841.56225 +3740 3719 -16689642.3626 +3810 3719 13679279.97901 +3811 3719 -12543431.97403 +3812 3719 -15345455.6363 +3813 3719 80261824.7461 +3814 3719 -6857580.506883 +3815 3719 -101938662.0149 +3816 3719 26537352.8999 +3817 3719 19401012.48091 +3818 3719 -57405640.83529 +3825 3719 571474.7733671 +3826 3719 -51408102.87125 +3827 3719 -18348781.1507 +3828 3719 2285899.092361 +3829 3719 -27430322.01402 +3830 3719 -242725472.4512 +3831 3719 571474.773379 +3832 3719 78838424.88527 +3833 3719 -190201211.678 +3843 3719 -14250754.75238 +3844 3719 -13229195.86314 +3845 3719 -17306764.74188 +3846 3719 -82547723.83843 +3847 3719 -6857580.506883 +3848 3719 -113395588.2476 +3849 3719 -27108827.67327 +3850 3719 20086776.37002 +3851 3719 -61172794.84886 +3720 3720 1206829602.888 +3721 3720 62536821.50566 +3722 3720 30859020.00955 +3723 3720 35818303.75647 +3724 3720 -62514728.59611 +3725 3720 26693781.96925 +3735 3720 -89019318.86449 +3736 3720 -62499999.98974 +3737 3720 24744637.25504 +3738 3720 -218486531.0803 +3739 3720 2.98023223877e-06 +3740 3720 -4571798.18244 +3741 3720 -90373702.5448 +3742 3720 62499999.98974 +3743 3720 -26687654.40317 +3813 3720 -26783317.53868 +3814 3720 15625000.00513 +3815 3720 13679279.97901 +3816 3720 -119411159.8837 +3817 3720 -15630523.23252 +3818 3720 75186254.88774 +3828 3720 16426910.05153 +3829 3720 4.485249519348e-06 +3830 3720 571474.7733669 +3831 3720 109890622.1535 +3832 3720 15634205.38412 +3833 3720 7712478.882864 +3834 3720 -60563825.20041 +3835 3720 -15628682.15673 +3836 3720 27115214.46942 +3846 3720 -27518808.45327 +3847 3720 -15625000.00513 +3848 3720 -14250754.75238 +3849 3720 -107888591.8846 +3850 3720 1.713633537292e-06 +3851 3720 -82890605.78265 +3852 3720 -43968569.74338 +3853 3720 15625000.00513 +3854 3720 -27108827.67327 +3721 3721 1038056487.373 +3722 3721 -85034336.6799 +3723 3721 -62522092.89929 +3724 3721 -182960177.6074 +3725 3721 45539436.5079 +3735 3721 -62499999.98974 +3736 3721 -70268591.613 +3737 3721 12480786.00715 +3738 3721 4.291534423828e-06 +3739 3721 56514675.03912 +3740 3721 -27430322.01402 +3741 3721 62499999.98974 +3742 3721 -71622975.29333 +3743 3721 14949536.00687 +3813 3721 15625000.00513 +3814 3721 -22095635.7235 +3815 3721 -12543431.97403 +3816 3721 -15628682.15673 +3817 3721 -45961669.68301 +3818 3721 8705839.731277 +3828 3721 5.781650543213e-06 +3829 3721 -42948027.89108 +3830 3721 -51682408.42662 +3831 3721 15634205.38412 +3832 3721 67697343.25408 +3833 3721 -21260405.06448 +3834 3721 -15630523.23252 +3835 3721 -115258445.5683 +3836 3721 76792017.46155 +3846 3721 -15625000.00513 +3847 3721 -22831126.63809 +3848 3721 -13229195.86314 +3849 3721 1.668930053711e-06 +3850 3721 -39138290.32084 +3851 3721 -6857580.506883 +3852 3721 15625000.00513 +3853 3721 -39280887.92821 +3854 3721 20086776.37002 +3722 3722 1199251971.759 +3723 3722 27039727.69652 +3724 3722 53222308.42241 +3725 3722 71236333.03937 +3735 3722 24401755.31083 +3736 3722 12206480.45177 +3737 3722 -13077952.54839 +3738 3722 -4571798.18244 +3739 3722 -27430322.01402 +3740 3722 114598543.8875 +3741 3722 -27030536.34739 +3742 3722 15223841.56225 +3743 3722 -16689642.3626 +3813 3722 13679279.97901 +3814 3722 -12543431.97403 +3815 3722 -15345455.6363 +3816 3722 74842632.24213 +3817 3722 6787043.609902 +3818 3722 -88003520.09856 +3828 3722 571474.7733671 +3829 3722 -51408102.87125 +3830 3722 -18348781.1507 +3831 3722 7717283.578221 +3832 3722 -21256561.34093 +3833 3722 -211698416.8248 +3834 3722 27118407.8675 +3835 3722 78438470.16785 +3836 3722 -167573319.7819 +3846 3722 -14250754.75238 +3847 3722 -13229195.86314 +3848 3722 -17306764.74188 +3849 3722 -82547723.83843 +3850 3722 -6857580.506883 +3851 3722 -113395588.2476 +3852 3722 -27108827.67327 +3853 3722 20086776.37002 +3854 3722 -61172794.84886 +3723 3723 706551906.5059 +3724 3723 62417112.17672 +3725 3723 -14282093.03959 +3738 3723 -89019318.86449 +3739 3723 -62499999.98974 +3740 3723 24744637.25504 +3741 3723 -332076358.0832 +3742 3723 -62445400.64684 +3743 3723 -803160.0738334 +3744 3723 26319971.87446 +3745 3723 50028288.46192 +3746 3723 -2745383.255368 +3816 3723 789479.8663111 +3817 3723 18755523.23355 +3818 3723 16762853.88037 +3831 3723 -11151323.14121 +3832 3723 -15630523.23252 +3833 3723 -13684113.02055 +3834 3723 46470413.46474 +3835 3723 16235473.27994 +3836 3723 13676114.56996 +3849 3723 -27518808.45327 +3850 3723 -15625000.00513 +3851 3723 -14250754.75238 +3852 3723 -132948615.2463 +3853 3723 -16242128.17313 +3854 3723 -84423084.10332 +3855 3723 -16459257.1867 +3856 3723 12506654.8973 +3857 3723 -18030325.78853 +3724 3724 612861139.5605 +3725 3724 -67677862.13804 +3738 3724 -62499999.98974 +3739 3724 -70268591.613 +3740 3724 12480786.00715 +3741 3724 -62459544.88191 +3742 3724 -38277258.88191 +3743 3724 -18152324.58222 +3744 3724 75042432.69288 +3745 3724 26239393.73097 +3746 3724 4213360.948835 +3816 3724 12503682.1557 +3817 3724 789479.8663122 +3818 3724 -8940185.539224 +3831 3724 -15628682.15672 +3832 3724 -65845943.5091 +3833 3724 -52101581.10086 +3834 3724 16235473.27994 +3835 3724 22268881.83647 +3836 3724 -3019008.474344 +3849 3724 -15625000.00513 +3850 3724 -22831126.63809 +3851 3724 -13229195.86314 +3852 3724 -16245455.61973 +3853 3724 -59216101.33218 +3854 3724 -22175016.50334 +3855 3724 18759982.34595 +3856 3724 -15983300.91978 +3857 3724 21161428.32241 +3725 3725 762630407.7355 +3738 3725 24401755.31083 +3739 3725 12206480.45177 +3740 3725 -13077952.54839 +3741 3725 -8345786.630533 +3742 3725 -17054481.01644 +3743 3725 35862722.46929 +3744 3725 -4118074.883052 +3745 3725 3115829.182002 +3746 3725 70267169.80871 +3816 3725 11175235.92025 +3817 3725 -13410278.30884 +3818 3725 2105279.643495 +3831 3725 -13682502.0067 +3832 3725 -53748034.02747 +3833 3725 -35806647.62401 +3834 3725 -19983141.87505 +3835 3725 -29394519.18652 +3836 3725 -159353009.1983 +3849 3725 -14250754.75238 +3850 3725 -13229195.86314 +3851 3725 -17306764.74188 +3852 3725 -86137312.42499 +3853 3725 -21622642.20025 +3854 3725 -120786511.1716 +3855 3725 -27045488.6828 +3856 3725 13949330.84847 +3857 3725 -44367308.76476 +3726 3726 1126552465.849 +3727 3726 1.227855682373e-05 +3728 3726 9143596.364805 +3729 3726 141293458.9169 +3730 3726 -4.947185516357e-06 +3731 3726 2285899.092331 +3747 3726 -218486531.0803 +3748 3726 2.98023223877e-06 +3749 3726 -4571798.18244 +3750 3726 -90373702.5448 +3751 3726 62499999.98974 +3752 3726 -26687654.40317 +3819 3726 -103592244.5474 +3820 3726 1.892447471619e-06 +3821 3726 80604706.69032 +3822 3726 -42555886.98831 +3823 3726 -15625000.00514 +3824 3726 26537352.8999 +3837 3726 77208121.14848 +3838 3726 3.09944152832e-06 +3839 3726 2285899.092361 +3840 3726 -48017751.39621 +3841 3726 -8.776783943176e-06 +3842 3726 571474.7733788 +3858 3726 -107888591.8846 +3859 3726 1.713633537292e-06 +3860 3726 -82890605.78265 +3861 3726 -43968569.74338 +3862 3726 15625000.00513 +3863 3726 -27108827.67327 +3727 3727 976546647.911 +3728 3727 -109721288.002 +3729 3727 -4.738569259644e-06 +3730 3727 -96206292.73656 +3731 3727 54860644.00101 +3747 3727 4.291534423828e-06 +3748 3727 56514675.03912 +3749 3727 -27430322.01402 +3750 3727 62499999.98974 +3751 3727 -71622975.29333 +3752 3727 14949536.00687 +3819 3727 -9.983777999878e-07 +3820 3727 -34841942.9836 +3821 3727 -6857580.506883 +3822 3727 -15625000.00514 +3823 3727 -37868205.17313 +3824 3727 19401012.48091 +3837 3727 3.09944152832e-06 +3838 3727 39706666.64553 +3839 3727 -27430322.01402 +3840 3727 -7.04824924469e-06 +3841 3727 -107392689.3388 +3842 3727 79112730.44064 +3858 3727 1.668930053711e-06 +3859 3727 -39138290.32084 +3860 3727 -6857580.506883 +3861 3727 15625000.00513 +3862 3727 -39280887.92821 +3863 3727 20086776.37002 +3728 3728 1209684727.759 +3729 3728 2285899.092332 +3730 3728 54860644.00101 +3731 3728 128167058.7484 +3747 3728 -4571798.18244 +3748 3728 -27430322.01402 +3749 3728 114598543.8875 +3750 3728 -27030536.34739 +3751 3728 15223841.56225 +3752 3728 -16689642.3626 +3819 3728 80261824.7461 +3820 3728 -6857580.506883 +3821 3728 -101938662.0149 +3822 3728 26537352.8999 +3823 3728 19401012.48091 +3824 3728 -57405640.83529 +3837 3728 2285899.092361 +3838 3728 -27430322.01402 +3839 3728 -242725472.4512 +3840 3728 571474.773379 +3841 3728 78838424.88527 +3842 3728 -190201211.678 +3858 3728 -82547723.83843 +3859 3728 -6857580.506883 +3860 3728 -113395588.2476 +3861 3728 -27108827.67327 +3862 3728 20086776.37002 +3863 3728 -61172794.84886 +3729 3729 1126552465.849 +3730 3729 1.227855682373e-05 +3731 3729 9143596.364805 +3732 3729 141293458.9169 +3733 3729 -4.947185516357e-06 +3734 3729 2285899.092331 +3747 3729 -89019318.86449 +3748 3729 -62499999.98974 +3749 3729 24744637.25504 +3750 3729 -218486531.0803 +3751 3729 2.98023223877e-06 +3752 3729 -4571798.18244 +3753 3729 -90373702.5448 +3754 3729 62499999.98974 +3755 3729 -26687654.40317 +3819 3729 -26783317.53868 +3820 3729 15625000.00513 +3821 3729 13679279.97901 +3822 3729 -103592244.5474 +3823 3729 1.892447471619e-06 +3824 3729 80604706.69032 +3825 3729 -42555886.98831 +3826 3729 -15625000.00514 +3827 3729 26537352.8999 +3837 3729 16426910.05153 +3838 3729 4.485249519348e-06 +3839 3729 571474.7733669 +3840 3729 77208121.14848 +3841 3729 3.09944152832e-06 +3842 3729 2285899.092361 +3843 3729 -48017751.39621 +3844 3729 -8.776783943176e-06 +3845 3729 571474.7733788 +3858 3729 -27518808.45327 +3859 3729 -15625000.00513 +3860 3729 -14250754.75238 +3861 3729 -107888591.8846 +3862 3729 1.713633537292e-06 +3863 3729 -82890605.78265 +3864 3729 -43968569.74338 +3865 3729 15625000.00513 +3866 3729 -27108827.67327 +3730 3730 976546647.911 +3731 3730 -109721288.002 +3732 3730 -4.738569259644e-06 +3733 3730 -96206292.73656 +3734 3730 54860644.00101 +3747 3730 -62499999.98974 +3748 3730 -70268591.613 +3749 3730 12480786.00715 +3750 3730 4.291534423828e-06 +3751 3730 56514675.03912 +3752 3730 -27430322.01402 +3753 3730 62499999.98974 +3754 3730 -71622975.29333 +3755 3730 14949536.00687 +3819 3730 15625000.00513 +3820 3730 -22095635.7235 +3821 3730 -12543431.97403 +3822 3730 -9.983777999878e-07 +3823 3730 -34841942.9836 +3824 3730 -6857580.506883 +3825 3730 -15625000.00514 +3826 3730 -37868205.17313 +3827 3730 19401012.48091 +3837 3730 5.781650543213e-06 +3838 3730 -42948027.89108 +3839 3730 -51682408.42662 +3840 3730 3.09944152832e-06 +3841 3730 39706666.64553 +3842 3730 -27430322.01402 +3843 3730 -7.04824924469e-06 +3844 3730 -107392689.3388 +3845 3730 79112730.44064 +3858 3730 -15625000.00513 +3859 3730 -22831126.63809 +3860 3730 -13229195.86314 +3861 3730 1.668930053711e-06 +3862 3730 -39138290.32084 +3863 3730 -6857580.506883 +3864 3730 15625000.00513 +3865 3730 -39280887.92821 +3866 3730 20086776.37002 +3731 3731 1209684727.759 +3732 3731 2285899.092332 +3733 3731 54860644.00101 +3734 3731 128167058.7484 +3747 3731 24401755.31083 +3748 3731 12206480.45177 +3749 3731 -13077952.54839 +3750 3731 -4571798.18244 +3751 3731 -27430322.01402 +3752 3731 114598543.8875 +3753 3731 -27030536.34739 +3754 3731 15223841.56225 +3755 3731 -16689642.3626 +3819 3731 13679279.97901 +3820 3731 -12543431.97403 +3821 3731 -15345455.6363 +3822 3731 80261824.7461 +3823 3731 -6857580.506883 +3824 3731 -101938662.0149 +3825 3731 26537352.8999 +3826 3731 19401012.48091 +3827 3731 -57405640.83529 +3837 3731 571474.7733671 +3838 3731 -51408102.87125 +3839 3731 -18348781.1507 +3840 3731 2285899.092361 +3841 3731 -27430322.01402 +3842 3731 -242725472.4512 +3843 3731 571474.773379 +3844 3731 78838424.88527 +3845 3731 -190201211.678 +3858 3731 -14250754.75238 +3859 3731 -13229195.86314 +3860 3731 -17306764.74188 +3861 3731 -82547723.83843 +3862 3731 -6857580.506883 +3863 3731 -113395588.2476 +3864 3731 -27108827.67327 +3865 3731 20086776.37002 +3866 3731 -61172794.84886 +3732 3732 1126552465.849 +3733 3732 1.227855682373e-05 +3734 3732 9143596.364805 +3735 3732 141293458.9169 +3736 3732 -4.947185516357e-06 +3737 3732 2285899.092331 +3750 3732 -89019318.86449 +3751 3732 -62499999.98974 +3752 3732 24744637.25504 +3753 3732 -218486531.0803 +3754 3732 2.98023223877e-06 +3755 3732 -4571798.18244 +3756 3732 -90373702.5448 +3757 3732 62499999.98974 +3758 3732 -26687654.40317 +3822 3732 -26783317.53868 +3823 3732 15625000.00513 +3824 3732 13679279.97901 +3825 3732 -103592244.5474 +3826 3732 1.892447471619e-06 +3827 3732 80604706.69032 +3828 3732 -42555886.98831 +3829 3732 -15625000.00514 +3830 3732 26537352.8999 +3840 3732 16426910.05153 +3841 3732 4.485249519348e-06 +3842 3732 571474.7733669 +3843 3732 77208121.14848 +3844 3732 3.09944152832e-06 +3845 3732 2285899.092361 +3846 3732 -48017751.39621 +3847 3732 -8.776783943176e-06 +3848 3732 571474.7733788 +3861 3732 -27518808.45327 +3862 3732 -15625000.00513 +3863 3732 -14250754.75238 +3864 3732 -107888591.8846 +3865 3732 1.713633537292e-06 +3866 3732 -82890605.78265 +3867 3732 -43968569.74338 +3868 3732 15625000.00513 +3869 3732 -27108827.67327 +3733 3733 976546647.911 +3734 3733 -109721288.002 +3735 3733 -4.738569259644e-06 +3736 3733 -96206292.73656 +3737 3733 54860644.00101 +3750 3733 -62499999.98974 +3751 3733 -70268591.613 +3752 3733 12480786.00715 +3753 3733 4.291534423828e-06 +3754 3733 56514675.03912 +3755 3733 -27430322.01402 +3756 3733 62499999.98974 +3757 3733 -71622975.29333 +3758 3733 14949536.00687 +3822 3733 15625000.00513 +3823 3733 -22095635.7235 +3824 3733 -12543431.97403 +3825 3733 -9.983777999878e-07 +3826 3733 -34841942.9836 +3827 3733 -6857580.506883 +3828 3733 -15625000.00514 +3829 3733 -37868205.17313 +3830 3733 19401012.48091 +3840 3733 5.781650543213e-06 +3841 3733 -42948027.89108 +3842 3733 -51682408.42662 +3843 3733 3.09944152832e-06 +3844 3733 39706666.64553 +3845 3733 -27430322.01402 +3846 3733 -7.04824924469e-06 +3847 3733 -107392689.3388 +3848 3733 79112730.44064 +3861 3733 -15625000.00513 +3862 3733 -22831126.63809 +3863 3733 -13229195.86314 +3864 3733 1.668930053711e-06 +3865 3733 -39138290.32084 +3866 3733 -6857580.506883 +3867 3733 15625000.00513 +3868 3733 -39280887.92821 +3869 3733 20086776.37002 +3734 3734 1209684727.759 +3735 3734 2285899.092332 +3736 3734 54860644.00101 +3737 3734 128167058.7484 +3750 3734 24401755.31083 +3751 3734 12206480.45177 +3752 3734 -13077952.54839 +3753 3734 -4571798.18244 +3754 3734 -27430322.01402 +3755 3734 114598543.8875 +3756 3734 -27030536.34739 +3757 3734 15223841.56225 +3758 3734 -16689642.3626 +3822 3734 13679279.97901 +3823 3734 -12543431.97403 +3824 3734 -15345455.6363 +3825 3734 80261824.7461 +3826 3734 -6857580.506883 +3827 3734 -101938662.0149 +3828 3734 26537352.8999 +3829 3734 19401012.48091 +3830 3734 -57405640.83529 +3840 3734 571474.7733671 +3841 3734 -51408102.87125 +3842 3734 -18348781.1507 +3843 3734 2285899.092361 +3844 3734 -27430322.01402 +3845 3734 -242725472.4512 +3846 3734 571474.773379 +3847 3734 78838424.88527 +3848 3734 -190201211.678 +3861 3734 -14250754.75238 +3862 3734 -13229195.86314 +3863 3734 -17306764.74188 +3864 3734 -82547723.83843 +3865 3734 -6857580.506883 +3866 3734 -113395588.2476 +3867 3734 -27108827.67327 +3868 3734 20086776.37002 +3869 3734 -61172794.84886 +3735 3735 1126552465.849 +3736 3735 1.227855682373e-05 +3737 3735 9143596.364805 +3738 3735 141293458.9169 +3739 3735 -4.947185516357e-06 +3740 3735 2285899.092331 +3753 3735 -89019318.86449 +3754 3735 -62499999.98974 +3755 3735 24744637.25504 +3756 3735 -218486531.0803 +3757 3735 2.98023223877e-06 +3758 3735 -4571798.18244 +3759 3735 -90373702.5448 +3760 3735 62499999.98974 +3761 3735 -26687654.40317 +3825 3735 -26783317.53868 +3826 3735 15625000.00513 +3827 3735 13679279.97901 +3828 3735 -103592244.5474 +3829 3735 1.892447471619e-06 +3830 3735 80604706.69032 +3831 3735 -42555886.98831 +3832 3735 -15625000.00514 +3833 3735 26537352.8999 +3843 3735 16426910.05153 +3844 3735 4.485249519348e-06 +3845 3735 571474.7733669 +3846 3735 77208121.14848 +3847 3735 3.09944152832e-06 +3848 3735 2285899.092361 +3849 3735 -48017751.39621 +3850 3735 -8.776783943176e-06 +3851 3735 571474.7733788 +3864 3735 -27518808.45327 +3865 3735 -15625000.00513 +3866 3735 -14250754.75238 +3867 3735 -107888591.8846 +3868 3735 1.713633537292e-06 +3869 3735 -82890605.78265 +3870 3735 -43968569.74338 +3871 3735 15625000.00513 +3872 3735 -27108827.67327 +3736 3736 976546647.911 +3737 3736 -109721288.002 +3738 3736 -4.738569259644e-06 +3739 3736 -96206292.73656 +3740 3736 54860644.00101 +3753 3736 -62499999.98974 +3754 3736 -70268591.613 +3755 3736 12480786.00715 +3756 3736 4.291534423828e-06 +3757 3736 56514675.03912 +3758 3736 -27430322.01402 +3759 3736 62499999.98974 +3760 3736 -71622975.29333 +3761 3736 14949536.00687 +3825 3736 15625000.00513 +3826 3736 -22095635.7235 +3827 3736 -12543431.97403 +3828 3736 -9.983777999878e-07 +3829 3736 -34841942.9836 +3830 3736 -6857580.506883 +3831 3736 -15625000.00514 +3832 3736 -37868205.17313 +3833 3736 19401012.48091 +3843 3736 5.781650543213e-06 +3844 3736 -42948027.89108 +3845 3736 -51682408.42662 +3846 3736 3.09944152832e-06 +3847 3736 39706666.64553 +3848 3736 -27430322.01402 +3849 3736 -7.04824924469e-06 +3850 3736 -107392689.3388 +3851 3736 79112730.44064 +3864 3736 -15625000.00513 +3865 3736 -22831126.63809 +3866 3736 -13229195.86314 +3867 3736 1.668930053711e-06 +3868 3736 -39138290.32084 +3869 3736 -6857580.506883 +3870 3736 15625000.00513 +3871 3736 -39280887.92821 +3872 3736 20086776.37002 +3737 3737 1209684727.759 +3738 3737 2285899.092332 +3739 3737 54860644.00101 +3740 3737 128167058.7484 +3753 3737 24401755.31083 +3754 3737 12206480.45177 +3755 3737 -13077952.54839 +3756 3737 -4571798.18244 +3757 3737 -27430322.01402 +3758 3737 114598543.8875 +3759 3737 -27030536.34739 +3760 3737 15223841.56225 +3761 3737 -16689642.3626 +3825 3737 13679279.97901 +3826 3737 -12543431.97403 +3827 3737 -15345455.6363 +3828 3737 80261824.7461 +3829 3737 -6857580.506883 +3830 3737 -101938662.0149 +3831 3737 26537352.8999 +3832 3737 19401012.48091 +3833 3737 -57405640.83529 +3843 3737 571474.7733671 +3844 3737 -51408102.87125 +3845 3737 -18348781.1507 +3846 3737 2285899.092361 +3847 3737 -27430322.01402 +3848 3737 -242725472.4512 +3849 3737 571474.773379 +3850 3737 78838424.88527 +3851 3737 -190201211.678 +3864 3737 -14250754.75238 +3865 3737 -13229195.86314 +3866 3737 -17306764.74188 +3867 3737 -82547723.83843 +3868 3737 -6857580.506883 +3869 3737 -113395588.2476 +3870 3737 -27108827.67327 +3871 3737 20086776.37002 +3872 3737 -61172794.84886 +3738 3738 1126552465.849 +3739 3738 1.227855682373e-05 +3740 3738 9143596.364805 +3741 3738 141293458.9169 +3742 3738 -4.947185516357e-06 +3743 3738 2285899.092331 +3756 3738 -89019318.86449 +3757 3738 -62499999.98974 +3758 3738 24744637.25504 +3759 3738 -218486531.0803 +3760 3738 2.98023223877e-06 +3761 3738 -4571798.18244 +3762 3738 -90373702.5448 +3763 3738 62499999.98974 +3764 3738 -26687654.40317 +3828 3738 -26783317.53868 +3829 3738 15625000.00513 +3830 3738 13679279.97901 +3831 3738 -103592244.5474 +3832 3738 1.892447471619e-06 +3833 3738 80604706.69032 +3834 3738 -42555886.98831 +3835 3738 -15625000.00514 +3836 3738 26537352.8999 +3846 3738 16426910.05153 +3847 3738 4.485249519348e-06 +3848 3738 571474.7733669 +3849 3738 77208121.14848 +3850 3738 3.09944152832e-06 +3851 3738 2285899.092361 +3852 3738 -48017751.39621 +3853 3738 -8.776783943176e-06 +3854 3738 571474.7733788 +3867 3738 -27518808.45327 +3868 3738 -15625000.00513 +3869 3738 -14250754.75238 +3870 3738 -107888591.8846 +3871 3738 1.713633537292e-06 +3872 3738 -82890605.78265 +3873 3738 -43968569.74338 +3874 3738 15625000.00513 +3875 3738 -27108827.67327 +3739 3739 976546647.911 +3740 3739 -109721288.002 +3741 3739 -4.738569259644e-06 +3742 3739 -96206292.73656 +3743 3739 54860644.00101 +3756 3739 -62499999.98974 +3757 3739 -70268591.613 +3758 3739 12480786.00715 +3759 3739 4.291534423828e-06 +3760 3739 56514675.03912 +3761 3739 -27430322.01402 +3762 3739 62499999.98974 +3763 3739 -71622975.29333 +3764 3739 14949536.00687 +3828 3739 15625000.00513 +3829 3739 -22095635.7235 +3830 3739 -12543431.97403 +3831 3739 -9.983777999878e-07 +3832 3739 -34841942.9836 +3833 3739 -6857580.506883 +3834 3739 -15625000.00514 +3835 3739 -37868205.17313 +3836 3739 19401012.48091 +3846 3739 5.781650543213e-06 +3847 3739 -42948027.89108 +3848 3739 -51682408.42662 +3849 3739 3.09944152832e-06 +3850 3739 39706666.64553 +3851 3739 -27430322.01402 +3852 3739 -7.04824924469e-06 +3853 3739 -107392689.3388 +3854 3739 79112730.44064 +3867 3739 -15625000.00513 +3868 3739 -22831126.63809 +3869 3739 -13229195.86314 +3870 3739 1.668930053711e-06 +3871 3739 -39138290.32084 +3872 3739 -6857580.506883 +3873 3739 15625000.00513 +3874 3739 -39280887.92821 +3875 3739 20086776.37002 +3740 3740 1209684727.759 +3741 3740 2285899.092332 +3742 3740 54860644.00101 +3743 3740 128167058.7484 +3756 3740 24401755.31083 +3757 3740 12206480.45177 +3758 3740 -13077952.54839 +3759 3740 -4571798.18244 +3760 3740 -27430322.01402 +3761 3740 114598543.8875 +3762 3740 -27030536.34739 +3763 3740 15223841.56225 +3764 3740 -16689642.3626 +3828 3740 13679279.97901 +3829 3740 -12543431.97403 +3830 3740 -15345455.6363 +3831 3740 80261824.7461 +3832 3740 -6857580.506883 +3833 3740 -101938662.0149 +3834 3740 26537352.8999 +3835 3740 19401012.48091 +3836 3740 -57405640.83529 +3846 3740 571474.7733671 +3847 3740 -51408102.87125 +3848 3740 -18348781.1507 +3849 3740 2285899.092361 +3850 3740 -27430322.01402 +3851 3740 -242725472.4512 +3852 3740 571474.773379 +3853 3740 78838424.88527 +3854 3740 -190201211.678 +3867 3740 -14250754.75238 +3868 3740 -13229195.86314 +3869 3740 -17306764.74188 +3870 3740 -82547723.83843 +3871 3740 -6857580.506883 +3872 3740 -113395588.2476 +3873 3740 -27108827.67327 +3874 3740 20086776.37002 +3875 3740 -61172794.84886 +3741 3741 1204754822.305 +3742 3741 62497357.07621 +3743 3741 8952962.2647 +3744 3741 45024925.86313 +3745 3741 -62570336.85273 +3746 3741 4194937.250903 +3759 3741 -89019318.86449 +3760 3741 -62499999.98974 +3761 3741 24744637.25504 +3762 3741 -219851604.8368 +3763 3741 40242.33966598 +3764 3741 -40004.89876187 +3765 3741 -85662760.9757 +3766 3741 62492282.31877 +3767 3741 -4761332.72443 +3831 3741 -26783317.53868 +3832 3741 15625000.00513 +3833 3741 13679279.97901 +3834 3741 -129153814.3351 +3835 3741 -16245455.61973 +3836 3741 82158969.80008 +3849 3741 16426910.05153 +3850 3741 4.485249519348e-06 +3851 3741 571474.7733669 +3852 3741 104024325.5148 +3853 3741 16260854.35681 +3854 3741 2224683.703303 +3855 3741 -40630590.51198 +3856 3741 -15327351.62456 +3857 3741 22295084.26312 +3870 3741 -27518808.45327 +3871 3741 -15625000.00513 +3872 3741 -14250754.75238 +3873 3741 -110653931.884 +3874 3741 -305984.1418301 +3875 3741 -83787444.46656 +3876 3741 -37582436.37865 +3877 3741 15617937.02931 +3878 3741 -22863442.41946 +3742 3742 1036206231.181 +3743 3742 -63859055.41908 +3744 3742 -62584481.0878 +3745 3742 -173792340.1873 +3746 3742 8996740.020617 +3759 3742 -62499999.98974 +3760 3742 -70268591.613 +3761 3742 12480786.00715 +3762 3742 40242.33966711 +3763 3742 55101624.38748 +3764 3742 -16838726.0431 +3765 3742 62492282.31877 +3766 3742 -67050935.07603 +3767 3742 2899204.461618 +3831 3742 15625000.00513 +3832 3742 -22095635.7235 +3833 3742 -12543431.97403 +3834 3742 -16242128.17313 +3835 3742 -55421300.42098 +3836 3742 13456767.21673 +3849 3742 5.781650543213e-06 +3850 3742 -42948027.89108 +3851 3742 -51682408.42662 +3852 3742 16260854.35681 +3853 3742 60193058.58581 +3854 3742 -15789635.31347 +3855 3742 -15330679.07116 +3856 3742 -95311088.41941 +3857 3742 70246455.99071 +3870 3742 -15625000.00513 +3871 3742 -22831126.63809 +3872 3742 -13229195.86314 +3873 3742 -305984.1418316 +3874 3742 -41608792.32606 +3875 3742 -4510931.026938 +3876 3742 15617937.02931 +3877 3742 -31848750.70198 +3878 3742 17366327.12976 +3743 3743 1194167608.39 +3744 3743 4196101.101037 +3745 3743 8997671.484154 +3746 3743 96068025.68697 +3759 3743 24401755.31083 +3760 3743 12206480.45177 +3761 3743 -13077952.54839 +3762 3743 -7583407.675302 +3763 3743 -16838726.0431 +3764 3743 110744786.4731 +3765 3743 -4761332.723755 +3766 3743 2899204.461618 +3767 3743 -4337375.443198 +3831 3743 13679279.97901 +3832 3743 -12543431.97403 +3833 3743 -15345455.6363 +3834 3743 83873198.12175 +3835 3743 13460242.0837 +3836 3743 -110667042.0751 +3849 3743 571474.7733671 +3850 3743 -51408102.87125 +3851 3743 -18348781.1507 +3852 3743 2233905.431621 +3853 3743 -14685035.59046 +3854 3743 -232308263.7716 +3855 3743 22299969.37665 +3856 3743 70246744.15636 +3857 3743 -116215570.0634 +3870 3743 -14250754.75238 +3871 3743 -13229195.86314 +3872 3743 -17306764.74188 +3873 3743 -85501854.18985 +3874 3743 -4236625.471426 +3875 3743 -119293921.0885 +3876 3743 -22863442.41946 +3877 3743 17366327.12976 +3878 3743 -42171970.90008 +3744 3744 664287766.0269 +3745 3744 24091.37187457 +3746 3744 571059.7622714 +3762 3744 -85626578.19959 +3763 3744 -62498840.1633 +3764 3744 3809616.386258 +3765 3744 -218147695.2755 +3766 3744 52750.43064576 +3767 3744 -573164.2357075 +3768 3744 74869081.74691 +3769 3744 -12523451.48296 +3770 3744 -190270.809375 +3771 3744 -84365929.45554 +3772 3744 62487498.23866 +3773 3744 -952211.7649758 +3834 3744 -11431103.66588 +3835 3744 18759982.34595 +3836 3744 24986550.61557 +3852 3744 -31689345.25595 +3853 3744 -15330679.07116 +3854 3744 -20228823.39131 +3855 3744 18578016.42486 +3856 3744 -212048.4434399 +3857 3744 16938078.048 +3873 3744 -33816955.75253 +3874 3744 -15624066.27071 +3875 3744 -20297239.76849 +3876 3744 -109961515.6943 +3877 3744 -411737.3918817 +3878 3744 -84091725.01815 +3879 3744 -7596963.016065 +3880 3744 -2912152.926645 +3881 3744 3595010.390649 +3882 3744 -35260385.50178 +3883 3744 15730701.75788 +3884 3744 -20970461.98783 +3745 3745 693856738.6524 +3746 3745 -9472423.040339 +3762 3745 -62498840.1633 +3763 3745 -66851597.3442 +3764 3745 1522937.794223 +3765 3745 52750.43064803 +3766 3745 55036643.93943 +3767 3745 -2908904.606411 +3768 3745 12476548.51293 +3769 3745 -44293034.1186 +3770 3745 468992.1784517 +3771 3745 62487498.23866 +3772 3745 -67834262.09186 +3773 3745 469097.6150822 +3834 3745 12506654.8973 +3835 3745 -10955147.39897 +3836 3745 -12464032.54073 +3852 3745 -15327351.62456 +3853 3745 -86369843.16339 +3854 3745 -65796808.19713 +3855 3745 -212048.4434426 +3856 3745 24360358.36927 +3857 3745 4613573.717161 +3873 3745 -15624066.27071 +3874 3745 -29339377.68916 +3875 3745 -16613289.94378 +3876 3745 -411737.3918818 +3877 3745 -41078918.26341 +3878 3745 -1049079.875028 +3879 3745 3337847.075409 +3880 3745 -37294366.69524 +3881 3745 33449764.91022 +3882 3745 15730701.75788 +3883 3745 -30500957.62076 +3884 3745 16782316.0706 +3746 3746 782229023.3854 +3762 3746 3809616.386596 +3763 3746 1522937.794493 +3764 3746 -3996051.731711 +3765 3746 -573164.2357077 +3766 3746 -2908904.606411 +3767 3746 104637633.003 +3768 3746 -190270.8093724 +3769 3746 468992.1784514 +3770 3746 81857334.49913 +3771 3746 -952211.7646383 +3772 3746 469097.6150822 +3773 3746 -4765687.76924 +3834 3746 16657700.41038 +3835 3746 -19127368.11652 +3836 3746 -30958899.37592 +3852 3746 -20224487.07758 +3853 3746 -65796957.16143 +3854 3746 -92372249.38064 +3855 3746 -16646713.61315 +3856 3746 -9261719.67195 +3857 3746 -200537782.5998 +3873 3746 -20297239.76849 +3874 3746 -16613289.94378 +3875 3746 -34497965.15509 +3876 3746 -84091725.01849 +3877 3746 -1049079.875162 +3878 3746 -117898245.7723 +3879 3746 -4529989.612186 +3880 3746 33449764.91022 +3881 3746 -49783549.25395 +3882 3746 -20970461.98783 +3883 3746 16782316.0706 +3884 3746 -37093315.02675 +3747 3747 563276232.9245 +3748 3747 3.09944152832e-06 +3749 3747 4571798.182401 +3750 3747 70669302.51978 +3751 3747 12499999.99795 +3752 3747 -3143074.759108 +3837 3747 -103592244.5474 +3838 3747 1.892447471619e-06 +3839 3747 80604706.69032 +3840 3747 -42555886.98831 +3841 3747 -15625000.00514 +3842 3747 26537352.8999 +3858 3747 38581487.51291 +3859 3747 -1.847743988037e-06 +3860 3747 -16029498.36724 +3861 3747 -24008875.6981 +3862 3747 3125000.001023 +3863 3747 -5078880.670627 +3748 3748 488273323.9555 +3749 3748 -54860644.001 +3750 3748 -12499999.99795 +3751 3748 -48080573.30694 +3752 3748 27156016.445 +3837 3748 -9.983777999878e-07 +3838 3748 -34841942.9836 +3839 3748 -6857580.506883 +3840 3748 -15625000.00514 +3841 3748 -37868205.17313 +3842 3748 19401012.48091 +3858 3748 -2.026557922363e-06 +3859 3748 19830760.26143 +3860 3748 -13715161.00701 +3861 3748 -3125000.00103 +3862 3748 -53696344.6694 +3863 3748 39487788.83141 +3749 3749 604842363.8797 +3750 3749 7143383.572535 +3751 3749 27704627.55602 +3752 3749 64143724.20442 +3837 3749 80261824.7461 +3838 3749 -6857580.506883 +3839 3749 -101938662.0149 +3840 3749 26537352.8999 +3841 3749 19401012.48091 +3842 3749 -57405640.83529 +3858 3749 16600987.73851 +3859 3749 -13715161.00701 +3860 3749 -121422931.0558 +3861 3749 5650355.444006 +3862 3749 39487788.83154 +3863 3749 -95100605.83899 +3750 3750 563276232.9245 +3751 3750 3.09944152832e-06 +3752 3750 4571798.182401 +3753 3750 70669302.51978 +3754 3750 12499999.99795 +3755 3750 -3143074.759108 +3837 3750 -26783317.53868 +3838 3750 15625000.00513 +3839 3750 13679279.97901 +3840 3750 -103592244.5474 +3841 3750 1.892447471619e-06 +3842 3750 80604706.69032 +3843 3750 -42555886.98831 +3844 3750 -15625000.00514 +3845 3750 26537352.8999 +3858 3750 8213455.025764 +3859 3750 -3125000.001024 +3860 3750 -2507266.086456 +3861 3750 38581487.51291 +3862 3750 -1.847743988037e-06 +3863 3750 -16029498.36724 +3864 3750 -24008875.6981 +3865 3750 3125000.001023 +3866 3750 -5078880.670627 +3751 3751 488273323.9555 +3752 3751 -54860644.001 +3753 3751 -12499999.99795 +3754 3751 -48080573.30694 +3755 3751 27156016.445 +3837 3751 15625000.00513 +3838 3751 -22095635.7235 +3839 3751 -12543431.97403 +3840 3751 -9.983777999878e-07 +3841 3751 -34841942.9836 +3842 3751 -6857580.506883 +3843 3751 -15625000.00514 +3844 3751 -37868205.17313 +3845 3751 19401012.48091 +3858 3751 3125000.00103 +3859 3751 -21474013.94555 +3860 3751 -25772627.8244 +3861 3751 -2.026557922363e-06 +3862 3751 19830760.26143 +3863 3751 -13715161.00701 +3864 3751 -3125000.00103 +3865 3751 -53696344.6694 +3866 3751 39487788.83141 +3752 3752 604842363.8797 +3753 3752 7143383.572535 +3754 3752 27704627.55602 +3755 3752 64143724.20442 +3837 3752 13679279.97901 +3838 3752 -12543431.97403 +3839 3752 -15345455.6363 +3840 3752 80261824.7461 +3841 3752 -6857580.506883 +3842 3752 -101938662.0149 +3843 3752 26537352.8999 +3844 3752 19401012.48091 +3845 3752 -57405640.83529 +3858 3752 3078740.859823 +3859 3752 -25772627.82454 +3860 3752 -9174390.575351 +3861 3752 16600987.73851 +3862 3752 -13715161.00701 +3863 3752 -121422931.0558 +3864 3752 5650355.444006 +3865 3752 39487788.83154 +3866 3752 -95100605.83899 +3753 3753 563276232.9245 +3754 3753 3.09944152832e-06 +3755 3753 4571798.182401 +3756 3753 70669302.51978 +3757 3753 12499999.99795 +3758 3753 -3143074.759108 +3840 3753 -26783317.53868 +3841 3753 15625000.00513 +3842 3753 13679279.97901 +3843 3753 -103592244.5474 +3844 3753 1.892447471619e-06 +3845 3753 80604706.69032 +3846 3753 -42555886.98831 +3847 3753 -15625000.00514 +3848 3753 26537352.8999 +3861 3753 8213455.025764 +3862 3753 -3125000.001024 +3863 3753 -2507266.086456 +3864 3753 38581487.51291 +3865 3753 -1.847743988037e-06 +3866 3753 -16029498.36724 +3867 3753 -24008875.6981 +3868 3753 3125000.001023 +3869 3753 -5078880.670627 +3754 3754 488273323.9555 +3755 3754 -54860644.001 +3756 3754 -12499999.99795 +3757 3754 -48080573.30694 +3758 3754 27156016.445 +3840 3754 15625000.00513 +3841 3754 -22095635.7235 +3842 3754 -12543431.97403 +3843 3754 -9.983777999878e-07 +3844 3754 -34841942.9836 +3845 3754 -6857580.506883 +3846 3754 -15625000.00514 +3847 3754 -37868205.17313 +3848 3754 19401012.48091 +3861 3754 3125000.00103 +3862 3754 -21474013.94555 +3863 3754 -25772627.8244 +3864 3754 -2.026557922363e-06 +3865 3754 19830760.26143 +3866 3754 -13715161.00701 +3867 3754 -3125000.00103 +3868 3754 -53696344.6694 +3869 3754 39487788.83141 +3755 3755 604842363.8797 +3756 3755 7143383.572535 +3757 3755 27704627.55602 +3758 3755 64143724.20442 +3840 3755 13679279.97901 +3841 3755 -12543431.97403 +3842 3755 -15345455.6363 +3843 3755 80261824.7461 +3844 3755 -6857580.506883 +3845 3755 -101938662.0149 +3846 3755 26537352.8999 +3847 3755 19401012.48091 +3848 3755 -57405640.83529 +3861 3755 3078740.859823 +3862 3755 -25772627.82454 +3863 3755 -9174390.575351 +3864 3755 16600987.73851 +3865 3755 -13715161.00701 +3866 3755 -121422931.0558 +3867 3755 5650355.444006 +3868 3755 39487788.83154 +3869 3755 -95100605.83899 +3756 3756 563276232.9245 +3757 3756 3.09944152832e-06 +3758 3756 4571798.182401 +3759 3756 70669302.51978 +3760 3756 12499999.99795 +3761 3756 -3143074.759108 +3843 3756 -26783317.53868 +3844 3756 15625000.00513 +3845 3756 13679279.97901 +3846 3756 -103592244.5474 +3847 3756 1.892447471619e-06 +3848 3756 80604706.69032 +3849 3756 -42555886.98831 +3850 3756 -15625000.00514 +3851 3756 26537352.8999 +3864 3756 8213455.025764 +3865 3756 -3125000.001024 +3866 3756 -2507266.086456 +3867 3756 38581487.51291 +3868 3756 -1.847743988037e-06 +3869 3756 -16029498.36724 +3870 3756 -24008875.6981 +3871 3756 3125000.001023 +3872 3756 -5078880.670627 +3757 3757 488273323.9555 +3758 3757 -54860644.001 +3759 3757 -12499999.99795 +3760 3757 -48080573.30694 +3761 3757 27156016.445 +3843 3757 15625000.00513 +3844 3757 -22095635.7235 +3845 3757 -12543431.97403 +3846 3757 -9.983777999878e-07 +3847 3757 -34841942.9836 +3848 3757 -6857580.506883 +3849 3757 -15625000.00514 +3850 3757 -37868205.17313 +3851 3757 19401012.48091 +3864 3757 3125000.00103 +3865 3757 -21474013.94555 +3866 3757 -25772627.8244 +3867 3757 -2.026557922363e-06 +3868 3757 19830760.26143 +3869 3757 -13715161.00701 +3870 3757 -3125000.00103 +3871 3757 -53696344.6694 +3872 3757 39487788.83141 +3758 3758 604842363.8797 +3759 3758 7143383.572535 +3760 3758 27704627.55602 +3761 3758 64143724.20442 +3843 3758 13679279.97901 +3844 3758 -12543431.97403 +3845 3758 -15345455.6363 +3846 3758 80261824.7461 +3847 3758 -6857580.506883 +3848 3758 -101938662.0149 +3849 3758 26537352.8999 +3850 3758 19401012.48091 +3851 3758 -57405640.83529 +3864 3758 3078740.859823 +3865 3758 -25772627.82454 +3866 3758 -9174390.575351 +3867 3758 16600987.73851 +3868 3758 -13715161.00701 +3869 3758 -121422931.0558 +3870 3758 5650355.444006 +3871 3758 39487788.83154 +3872 3758 -95100605.83899 +3759 3759 563276232.9245 +3760 3759 3.09944152832e-06 +3761 3759 4571798.182401 +3762 3759 70669302.51978 +3763 3759 12499999.99795 +3764 3759 -3143074.759108 +3846 3759 -26783317.53868 +3847 3759 15625000.00513 +3848 3759 13679279.97901 +3849 3759 -103592244.5474 +3850 3759 1.892447471619e-06 +3851 3759 80604706.69032 +3852 3759 -42555886.98831 +3853 3759 -15625000.00514 +3854 3759 26537352.8999 +3867 3759 8213455.025764 +3868 3759 -3125000.001024 +3869 3759 -2507266.086456 +3870 3759 38581487.51291 +3871 3759 -1.847743988037e-06 +3872 3759 -16029498.36724 +3873 3759 -24008875.6981 +3874 3759 3125000.001023 +3875 3759 -5078880.670627 +3760 3760 488273323.9555 +3761 3760 -54860644.001 +3762 3760 -12499999.99795 +3763 3760 -48080573.30694 +3764 3760 27156016.445 +3846 3760 15625000.00513 +3847 3760 -22095635.7235 +3848 3760 -12543431.97403 +3849 3760 -9.983777999878e-07 +3850 3760 -34841942.9836 +3851 3760 -6857580.506883 +3852 3760 -15625000.00514 +3853 3760 -37868205.17313 +3854 3760 19401012.48091 +3867 3760 3125000.00103 +3868 3760 -21474013.94555 +3869 3760 -25772627.8244 +3870 3760 -2.026557922363e-06 +3871 3760 19830760.26143 +3872 3760 -13715161.00701 +3873 3760 -3125000.00103 +3874 3760 -53696344.6694 +3875 3760 39487788.83141 +3761 3761 604842363.8797 +3762 3761 7143383.572535 +3763 3761 27704627.55602 +3764 3761 64143724.20442 +3846 3761 13679279.97901 +3847 3761 -12543431.97403 +3848 3761 -15345455.6363 +3849 3761 80261824.7461 +3850 3761 -6857580.506883 +3851 3761 -101938662.0149 +3852 3761 26537352.8999 +3853 3761 19401012.48091 +3854 3761 -57405640.83529 +3867 3761 3078740.859823 +3868 3761 -25772627.82454 +3869 3761 -9174390.575351 +3870 3761 16600987.73851 +3871 3761 -13715161.00701 +3872 3761 -121422931.0558 +3873 3761 5650355.444006 +3874 3761 39487788.83154 +3875 3761 -95100605.83899 +3762 3762 560320827.2113 +3763 3762 639.901719451 +3764 3762 23239591.98142 +3765 3762 78578401.33592 +3766 3762 12457957.93012 +3767 3762 -264411.8076911 +3849 3762 -26783317.53868 +3850 3762 15625000.00513 +3851 3762 13679279.97901 +3852 3762 -106874624.6125 +3853 3762 -305984.1418223 +3854 3762 81912468.6994 +3855 3762 -36055415.57193 +3856 3762 -15624066.27071 +3857 3762 22203888.71768 +3870 3762 8213455.025764 +3871 3762 -3125000.001024 +3872 3762 -2507266.086456 +3873 3762 34185986.02995 +3874 3762 798.6461966634 +3875 3762 -11275630.76041 +3876 3762 -10346432.29075 +3877 3762 3429251.762236 +3878 3762 -4751421.104327 +3763 3763 485350920.2351 +3764 3763 -34136717.37342 +3765 3763 -12542042.06577 +3766 3763 -40180753.19227 +3767 3763 4878203.170454 +3849 3763 15625000.00513 +3850 3763 -22095635.7235 +3851 3763 -12543431.97403 +3852 3763 -305984.1418242 +3853 3763 -37829485.05459 +3854 3763 -3842528.249337 +3855 3763 -15624066.27071 +3856 3763 -31577837.50856 +3857 3763 17388446.1785 +3870 3763 3125000.00103 +3871 3763 -21474013.94555 +3872 3763 -25772627.8244 +3873 3763 798.6461972594 +3874 3763 15227309.46198 +3875 3763 -8458758.259206 +3876 3763 -2820748.239817 +3877 3763 -39910686.18794 +3878 3763 34874733.46178 +3764 3764 597013597.6343 +3765 3764 1792879.858635 +3766 3764 4878203.170454 +3767 3764 85361307.078 +3849 3764 13679279.97901 +3850 3764 -12543431.97403 +3851 3764 -15345455.6363 +3852 3764 83626878.42252 +3853 3764 -3568222.69369 +3854 3764 -109215768.3646 +3855 3764 22203888.71769 +3856 3764 17388446.1785 +3857 3764 -40467191.34016 +3870 3764 3078740.859823 +3871 3764 -25772627.82454 +3872 3764 -9174390.575351 +3873 3764 22040063.67856 +3874 3764 -7910147.148185 +3875 3764 -133536023.2831 +3876 3764 4263127.509742 +3877 3764 34874733.46192 +3878 3764 -59355434.68897 +3765 3765 550746202.1403 +3766 3765 36066.57850146 +3767 3765 569002.3382969 +3768 3765 -84494054.45551 +3769 3765 -62512501.74082 +3770 3765 762197.9571191 +3771 3765 74782825.51741 +3772 3765 12473444.47867 +3773 3765 -532638.751045 +3852 3765 -34261443.39917 +3853 3765 15617937.02931 +3854 3765 20473536.76144 +3855 3765 -109427582.9781 +3856 3765 -411737.3918647 +3857 3765 83832233.28727 +3873 3765 -4238369.907793 +3874 3765 -2820748.239818 +3875 3765 -3401247.493269 +3876 3765 31840797.35778 +3877 3765 -201113.0826508 +3878 3765 -16633868.93328 +3879 3765 -34006609.4597 +3880 3765 -15519298.25239 +3881 3765 20501065.80357 +3882 3765 -7808250.756493 +3883 3765 3334959.937417 +3884 3765 -4703108.31416 +3766 3766 480255926.3528 +3767 3766 -6744998.921652 +3768 3766 -62512501.74082 +3769 3766 -67882308.96685 +3770 3766 469097.615082 +3771 3766 -12526555.51723 +3772 3766 -44375654.77008 +3773 3766 1407398.280953 +3852 3766 15617937.02931 +3853 3766 -28527757.72252 +3854 3766 -15967006.21452 +3855 3766 -411737.3918659 +3856 3766 -40544985.54718 +3857 3766 -380677.0974279 +3873 3766 3429251.762237 +3874 3766 -33802623.805 +3875 3766 -32460335.97153 +3876 3766 -201113.0826469 +3877 3766 12600540.20203 +3878 3766 -1653796.126267 +3879 3766 -15519298.25239 +3880 3766 -30030791.60498 +3881 3766 16782316.0706 +3882 3766 -2915040.064636 +3883 3766 -37595840.66582 +3884 3766 33679499.33911 +3767 3767 579545011.66 +3768 3767 762197.9571192 +3769 3767 469097.615082 +3770 3767 -4813734.644226 +3771 3767 153125.1377279 +3772 3767 1407398.280952 +3773 3767 81748273.77839 +3852 3767 20473536.76144 +3853 3767 -15967006.21452 +3854 3767 -33315989.62148 +3855 3767 83832233.28761 +3856 3767 -380677.0974262 +3857 3767 -116474425.1957 +3873 3767 4584655.287299 +3874 3767 -32460335.97153 +3875 3767 -43067268.3344 +3876 3767 16950922.72787 +3877 3767 -1653796.126267 +3878 3767 -140113637.8354 +3879 3767 20501065.80357 +3880 3767 16782316.0706 +3881 3767 -36623149.01096 +3882 3767 3760502.799563 +3883 3767 33679499.33911 +3884 3767 -51476087.71803 +3768 3768 272867251.5293 +3769 3768 62523451.47476 +3770 3768 -381199.097837 +3771 3768 -107269612.1541 +3772 3768 -12487498.24687 +3773 3768 -190728.0499092 +3855 3768 -7048351.904789 +3856 3768 3337847.075409 +3857 3768 4430861.084874 +3876 3768 -33457998.34841 +3877 3768 -15519298.25239 +3878 3768 -20123934.20978 +3879 3768 15992685.2667 +3880 3768 15412152.93075 +3881 3768 8031696.785406 +3882 3768 -53472668.34682 +3883 3768 -3230701.753776 +3884 3768 -41088623.6605 +3769 3769 239685617.4198 +3770 3769 -468992.1784413 +3771 3769 12512501.74903 +3772 3769 28462392.33225 +3773 3769 -469097.6150756 +3855 3769 -2912152.926645 +3856 3769 -36745755.58397 +3857 3769 -33216901.74549 +3876 3769 -15519298.25239 +3877 3769 -29482180.49371 +3878 3769 -16551017.27368 +3879 3769 15412152.93075 +3880 3769 7604151.433358 +3881 3769 6550235.083201 +3882 3769 3019298.248277 +3883 3769 -19362548.68901 +3884 3769 3217683.935962 +3770 3770 286845804.3292 +3771 3770 -190728.0499058 +3772 3770 -469097.6150757 +3773 3770 52037706.92696 +3855 3770 -3694138.917793 +3856 3770 -33216901.74549 +3857 3770 -48320586.29054 +3876 3770 -20123934.20978 +3877 3770 -16551017.27368 +3878 3770 -35160186.04754 +3879 3770 -8218303.211925 +3880 3770 -6783098.247942 +3881 3770 -67476295.62359 +3882 3770 -41088623.6605 +3883 3770 -3448982.732894 +3884 3770 -57006487.59384 +3771 3771 272798049.4256 +3772 3771 -62473444.47046 +3773 3771 -381713.1014125 +3855 3771 -34711774.39049 +3856 3771 15730701.75788 +3857 3771 20490388.72023 +3876 3771 -6162417.423721 +3877 3771 -2915040.064636 +3878 3771 -3695816.647659 +3879 3771 -53472668.34682 +3880 3771 3019298.248286 +3881 3771 40997227.02038 +3882 3771 16374193.49437 +3883 3771 -15834959.94153 +3884 3771 -8381660.203837 +3772 3772 239692857.863 +3773 3772 -1407398.280936 +3855 3772 15730701.75788 +3856 3772 -29952346.50949 +3857 3772 -16551017.27368 +3876 3772 3334959.937418 +3877 3772 -35950007.33306 +3878 3772 -32987167.3166 +3879 3772 -3230701.753769 +3880 3772 -19362548.68901 +3881 3772 3217683.935962 +3882 3772 -15834959.94153 +3883 3772 7292235.86488 +3884 3772 6320500.654305 +3773 3773 286833929.2861 +3855 3773 20490388.72023 +3856 3773 -16551017.27368 +3857 3773 -35630352.06332 +3876 3773 4424912.521678 +3877 3773 -32987167.3166 +3878 3773 -47087198.83062 +3879 3773 40997227.02055 +3880 3773 -3448982.732894 +3881 3773 -57006487.59384 +3882 3773 8202680.071217 +3883 3773 -7012832.676838 +3884 3773 -68203072.62332 +3774 3774 731873593.1548 +3775 3774 63656944.434 +3776 3774 18282582.06852 +3777 3774 -339558601.0551 +3778 3774 -63664153.72624 +3779 3774 -14174508.59703 +3780 3774 22166321.31964 +3781 3774 50932764.83944 +3782 3774 -9608497.922564 +3885 3774 41127258.27048 +3886 3774 16203472.22755 +3887 3774 17343888.84954 +3888 3774 -135326679.0276 +3889 3774 -16203472.09792 +3890 3774 -86719444.24762 +3891 3774 -13923315.162 +3892 3774 12962777.65241 +3893 3774 -17343888.52033 +3775 3775 636376493.3815 +3776 3775 -30188925.21508 +3777 3775 -63667758.37236 +3778 3775 -40346533.53339 +3779 3775 -19199086.44689 +3780 3775 76399147.25916 +3781 3775 22166321.31964 +3782 3775 13164421.99706 +3885 3775 16203472.22755 +3886 3775 16821163.40287 +3887 3775 13874999.85144 +3888 3775 -16203472.0331 +3889 3775 -59169888.51194 +3890 3775 -17343749.90781 +3891 3775 19444166.47861 +3892 3775 -13923315.162 +3893 3775 20812499.90895 +3776 3776 809270793.6919 +3777 3776 -12120471.86127 +3778 3776 -15085251.33671 +3779 3776 33187550.82531 +3780 3776 -14412746.88385 +3781 3776 8776281.331372 +3782 3776 59110190.1857 +3885 3776 -17343888.84951 +3886 3776 -13874999.85143 +3887 3776 -181091253.0988 +3888 3776 -86719444.24762 +3889 3776 -17343749.94043 +3890 3776 -121957897.9018 +3891 3776 -26015832.7805 +3892 3776 13874999.9393 +3893 3776 -37128840.43199 +3777 3777 1236679322.481 +3778 3777 63674967.6646 +3779 3777 15441526.4422 +3780 3777 49455964.79174 +3781 3777 -63664153.72624 +3782 3777 13608792.08924 +3783 3777 -223854518.1091 +3784 3777 1.281499862671e-06 +3785 3777 -3314544.719882 +3786 3777 -89126355.34779 +3787 3777 63656944.434 +3788 3777 -13600988.60888 +3885 3777 -135326679.0277 +3886 3777 -16203472.0331 +3887 3777 86719444.24762 +3888 3777 101875695.1567 +3889 3777 16203471.90348 +3890 3777 0.03654569387436 +3891 3777 -36808280.87074 +3892 3777 -16203472.09792 +3893 3777 21679860.74398 +3894 3777 -113177912.5204 +3895 3777 6.407499313354e-07 +3896 3777 -86719444.43019 +3897 3777 -36072082.53397 +3898 3777 16203472.22755 +3899 3777 -21679861.11823 +3778 3778 1064791031.509 +3779 3778 -42507558.78941 +3780 3778 -63667758.37236 +3781 3778 -173356800.7659 +3782 3778 23590660.68649 +3783 3778 2.622604370117e-06 +3784 3778 56237222.37539 +3785 3778 -13715162.23406 +3786 3778 63656944.434 +3787 3778 -70028557.53863 +3788 3778 7680497.783698 +3885 3778 -16203472.09792 +3886 3778 -59169888.51195 +3887 3778 17343749.94043 +3888 3778 16203471.90348 +3889 3778 58124724.28025 +3890 3778 0.029221534729 +3891 3778 -16203472.03311 +3892 3778 -93520195.52346 +3893 3778 69374999.6084 +3894 3778 -1.177191734314e-06 +3895 3778 -41882340.60421 +3896 3778 8.344650268555e-07 +3897 3778 16203472.22754 +3898 3778 -31210863.52937 +3899 3778 17343750.0057 +3779 3779 1241583328.715 +3780 3779 13269811.8847 +3781 3779 25790082.19602 +3782 3779 107138521.2855 +3783 3779 -1257253.053552 +3784 3779 -13715162.23407 +3785 3779 113190145.6041 +3786 3779 -13258106.66415 +3787 3779 7406192.227917 +3788 3779 -9211261.686427 +3885 3779 86719444.24762 +3886 3779 17343749.9078 +3887 3779 -121957897.9018 +3888 3779 -0.03648543357849 +3889 3779 -0.02920261025429 +3890 3779 -251706576.231 +3891 3779 21679860.55685 +3892 3779 69374999.49133 +3893 3779 -104457508.7431 +3894 3779 -86719444.43019 +3895 3779 8.940696716309e-07 +3896 3779 -121047307.7997 +3897 3779 -21679861.11823 +3898 3779 17343750.0057 +3899 3779 -38039431.35476 +3780 3780 731873593.1548 +3781 3780 63656944.434 +3782 3780 18282582.06852 +3783 3780 -88449163.50764 +3784 3780 -63656944.434 +3785 3780 12115157.22023 +3786 3780 -339558601.0551 +3787 3780 -63664153.72624 +3788 3780 -14174508.59703 +3789 3780 22166321.31964 +3790 3780 50932764.83944 +3791 3780 -9608497.922564 +3885 3780 -13923315.16199 +3886 3780 19444166.47861 +3887 3780 26015832.7805 +3888 3780 -36808280.87074 +3889 3780 -16203472.0331 +3890 3780 -21679860.55685 +3891 3780 41127258.27048 +3892 3780 16203472.22755 +3893 3780 17343888.84954 +3894 3780 -36072082.53397 +3895 3780 -16203472.22754 +3896 3780 -21679861.11823 +3897 3780 -135326679.0276 +3898 3780 -16203472.09792 +3899 3780 -86719444.24762 +3900 3780 -13923315.162 +3901 3780 12962777.65241 +3902 3780 -17343888.52033 +3781 3781 636376493.3815 +3782 3781 -30188925.21508 +3783 3781 -63656944.434 +3784 3781 -69351365.69847 +3785 3781 6034664.450365 +3786 3781 -63667758.37236 +3787 3781 -40346533.53339 +3788 3781 -19199086.44689 +3789 3781 76399147.25916 +3790 3781 22166321.31964 +3791 3781 13164421.99706 +3885 3781 12962777.65241 +3886 3781 -13923315.162 +3887 3781 -13874999.9393 +3888 3781 -16203472.09791 +3889 3781 -93520195.52345 +3890 3781 -69374999.49133 +3891 3781 16203472.22755 +3892 3781 16821163.40287 +3893 3781 13874999.85144 +3894 3781 -16203472.22754 +3895 3781 -31210863.52937 +3896 3781 -17343750.0057 +3897 3781 -16203472.0331 +3898 3781 -59169888.51194 +3899 3781 -17343749.90781 +3900 3781 19444166.47861 +3901 3781 -13923315.162 +3902 3781 20812499.90895 +3782 3782 809270793.6919 +3783 3782 12458039.16496 +3784 3782 6308970.006146 +3785 3782 -7405416.779322 +3786 3782 -12120471.86127 +3787 3782 -15085251.33671 +3788 3782 33187550.82531 +3789 3782 -14412746.88385 +3790 3782 8776281.331372 +3791 3782 59110190.1857 +3885 3782 17343888.52033 +3886 3782 -20812499.90894 +3887 3782 -37128840.43198 +3888 3782 -21679860.74397 +3889 3782 -69374999.6084 +3890 3782 -104457508.7431 +3891 3782 -17343888.84951 +3892 3782 -13874999.85143 +3893 3782 -181091253.0988 +3894 3782 -21679861.11823 +3895 3782 -17343750.0057 +3896 3782 -38039431.35476 +3897 3782 -86719444.24762 +3898 3782 -17343749.94043 +3899 3782 -121957897.9018 +3900 3782 -26015832.7805 +3901 3782 13874999.9393 +3902 3782 -37128840.43199 +3783 3783 1137565312.076 +3784 3783 4.64916229248e-06 +3785 3783 4571797.773345 +3786 3783 153072235.6709 +3787 3783 -3.814697265625e-06 +3788 3783 1142949.443904 +3792 3783 -223854518.1091 +3793 3783 1.281499862671e-06 +3794 3783 -3314544.719882 +3795 3783 -89126355.34779 +3796 3783 63656944.434 +3797 3783 -13600988.60888 +3888 3783 -113177912.5205 +3889 3783 -1.952052116394e-06 +3890 3783 86719444.4302 +3891 3783 -36072082.53399 +3892 3783 -16203472.22755 +3893 3783 21679861.11823 +3894 3783 65803613.40852 +3895 3783 4.112720489502e-06 +3896 3783 3.081560134888e-05 +3897 3783 -14659514.18418 +3898 3783 -1.010298728943e-05 +3899 3783 8.165836334229e-06 +3903 3783 -113177912.5204 +3904 3783 6.407499313354e-07 +3905 3783 -86719444.43019 +3906 3783 -36072082.53397 +3907 3783 16203472.22755 +3908 3783 -21679861.11823 +3784 3784 984782929.6775 +3785 3784 -54860648.90923 +3786 3784 -3.695487976074e-06 +3787 3784 -88823909.23288 +3788 3784 28253241.12114 +3792 3784 2.622604370117e-06 +3793 3784 56237222.37539 +3794 3784 -13715162.23406 +3795 3784 63656944.434 +3796 3784 -70028557.53863 +3797 3784 7680497.783698 +3888 3784 -4.097819328308e-06 +3889 3784 -41882340.60423 +3890 3784 1.296401023865e-06 +3891 3784 -16203472.22755 +3892 3784 -31210863.52938 +3893 3784 17343750.0057 +3894 3784 4.053115844727e-06 +3895 3784 26913861.39084 +3896 3784 4.738569259644e-06 +3897 3784 -7.331371307373e-06 +3898 3784 -76232648.10076 +3899 3784 69374999.9886 +3903 3784 -1.177191734314e-06 +3904 3784 -41882340.60421 +3905 3784 8.344650268555e-07 +3906 3784 16203472.22754 +3907 3784 -31210863.52937 +3908 3784 17343750.0057 +3785 3785 1205835345.84 +3786 3785 1142949.443904 +3787 3785 26607407.78808 +3788 3785 154975139.2593 +3792 3785 -1257253.053552 +3793 3785 -13715162.23407 +3794 3785 113190145.6041 +3795 3785 -13258106.66415 +3796 3785 7406192.227917 +3797 3785 -9211261.686427 +3888 3785 86719444.4302 +3889 3785 1.415610313416e-06 +3890 3785 -121047307.7997 +3891 3785 21679861.11823 +3892 3785 17343750.0057 +3893 3785 -38039431.35476 +3894 3785 3.02791595459e-05 +3895 3785 4.619359970093e-06 +3896 3785 -289746007.2349 +3897 3785 8.165836334229e-06 +3898 3785 69374999.9886 +3899 3785 -103546919.3888 +3903 3785 -86719444.43019 +3904 3785 8.940696716309e-07 +3905 3785 -121047307.7997 +3906 3785 -21679861.11823 +3907 3785 17343750.0057 +3908 3785 -38039431.35476 +3786 3786 1236679322.481 +3787 3786 63674967.6646 +3788 3786 15441526.4422 +3789 3786 49455964.79174 +3790 3786 -63664153.72624 +3791 3786 13608792.08924 +3792 3786 -88449163.50764 +3793 3786 -63656944.434 +3794 3786 12115157.22023 +3795 3786 -223854518.1091 +3796 3786 1.281499862671e-06 +3797 3786 -3314544.719882 +3798 3786 -89126355.34779 +3799 3786 63656944.434 +3800 3786 -13600988.60888 +3888 3786 -36072082.53399 +3889 3786 16203472.22755 +3890 3786 21679861.11823 +3891 3786 -135326679.0277 +3892 3786 -16203472.0331 +3893 3786 86719444.24762 +3894 3786 -14659514.18418 +3895 3786 7.62939453125e-06 +3896 3786 7.152557373047e-06 +3897 3786 101875695.1567 +3898 3786 16203471.90348 +3899 3786 0.03654569387436 +3900 3786 -36808280.87074 +3901 3786 -16203472.09792 +3902 3786 21679860.74398 +3903 3786 -36072082.53397 +3904 3786 -16203472.22754 +3905 3786 -21679861.11823 +3906 3786 -113177912.5204 +3907 3786 6.407499313354e-07 +3908 3786 -86719444.43019 +3909 3786 -36072082.53397 +3910 3786 16203472.22755 +3911 3786 -21679861.11823 +3787 3787 1064791031.509 +3788 3787 -42507558.78941 +3789 3787 -63667758.37236 +3790 3787 -173356800.7659 +3791 3787 23590660.68649 +3792 3787 -63656944.434 +3793 3787 -69351365.69847 +3794 3787 6034664.450365 +3795 3787 2.622604370117e-06 +3796 3787 56237222.37539 +3797 3787 -13715162.23406 +3798 3787 63656944.434 +3799 3787 -70028557.53863 +3800 3787 7680497.783698 +3888 3787 16203472.22755 +3889 3787 -31210863.52938 +3890 3787 -17343750.00569 +3891 3787 -16203472.09792 +3892 3787 -59169888.51195 +3893 3787 17343749.94043 +3894 3787 8.970499038696e-06 +3895 3787 -76232648.10075 +3896 3787 -69374999.9886 +3897 3787 16203471.90348 +3898 3787 58124724.28025 +3899 3787 0.029221534729 +3900 3787 -16203472.03311 +3901 3787 -93520195.52346 +3902 3787 69374999.6084 +3903 3787 -16203472.22754 +3904 3787 -31210863.52937 +3905 3787 -17343750.0057 +3906 3787 -1.177191734314e-06 +3907 3787 -41882340.60421 +3908 3787 8.344650268555e-07 +3909 3787 16203472.22754 +3910 3787 -31210863.52937 +3911 3787 17343750.0057 +3788 3788 1241583328.715 +3789 3788 13269811.8847 +3790 3788 25790082.19602 +3791 3788 107138521.2855 +3792 3788 12458039.16496 +3793 3788 6308970.006146 +3794 3788 -7405416.779322 +3795 3788 -1257253.053552 +3796 3788 -13715162.23407 +3797 3788 113190145.6041 +3798 3788 -13258106.66415 +3799 3788 7406192.227917 +3800 3788 -9211261.686427 +3888 3788 21679861.11823 +3889 3788 -17343750.00569 +3890 3788 -38039431.35476 +3891 3788 86719444.24762 +3892 3788 17343749.9078 +3893 3788 -121957897.9018 +3894 3788 7.182359695435e-06 +3895 3788 -69374999.9886 +3896 3788 -103546919.3888 +3897 3788 -0.03648543357849 +3898 3788 -0.02920261025429 +3899 3788 -251706576.231 +3900 3788 21679860.55685 +3901 3788 69374999.49133 +3902 3788 -104457508.7431 +3903 3788 -21679861.11823 +3904 3788 -17343750.0057 +3905 3788 -38039431.35476 +3906 3788 -86719444.43019 +3907 3788 8.940696716309e-07 +3908 3788 -121047307.7997 +3909 3788 -21679861.11823 +3910 3788 17343750.0057 +3911 3788 -38039431.35476 +3789 3789 731873593.1548 +3790 3789 63656944.434 +3791 3789 18282582.06852 +3795 3789 -88449163.50764 +3796 3789 -63656944.434 +3797 3789 12115157.22023 +3798 3789 -339558601.0551 +3799 3789 -63664153.72624 +3800 3789 -14174508.59703 +3801 3789 22166321.31964 +3802 3789 50932764.83944 +3803 3789 -9608497.922564 +3891 3789 -13923315.16199 +3892 3789 19444166.47861 +3893 3789 26015832.7805 +3897 3789 -36808280.87074 +3898 3789 -16203472.0331 +3899 3789 -21679860.55685 +3900 3789 41127258.27048 +3901 3789 16203472.22755 +3902 3789 17343888.84954 +3906 3789 -36072082.53397 +3907 3789 -16203472.22754 +3908 3789 -21679861.11823 +3909 3789 -135326679.0276 +3910 3789 -16203472.09792 +3911 3789 -86719444.24762 +3912 3789 -13923315.162 +3913 3789 12962777.65241 +3914 3789 -17343888.52033 +3790 3790 636376493.3815 +3791 3790 -30188925.21508 +3795 3790 -63656944.434 +3796 3790 -69351365.69847 +3797 3790 6034664.450365 +3798 3790 -63667758.37236 +3799 3790 -40346533.53339 +3800 3790 -19199086.44689 +3801 3790 76399147.25916 +3802 3790 22166321.31964 +3803 3790 13164421.99706 +3891 3790 12962777.65241 +3892 3790 -13923315.162 +3893 3790 -13874999.9393 +3897 3790 -16203472.09791 +3898 3790 -93520195.52345 +3899 3790 -69374999.49133 +3900 3790 16203472.22755 +3901 3790 16821163.40287 +3902 3790 13874999.85144 +3906 3790 -16203472.22754 +3907 3790 -31210863.52937 +3908 3790 -17343750.0057 +3909 3790 -16203472.0331 +3910 3790 -59169888.51194 +3911 3790 -17343749.90781 +3912 3790 19444166.47861 +3913 3790 -13923315.162 +3914 3790 20812499.90895 +3791 3791 809270793.6919 +3795 3791 12458039.16496 +3796 3791 6308970.006146 +3797 3791 -7405416.779322 +3798 3791 -12120471.86127 +3799 3791 -15085251.33671 +3800 3791 33187550.82531 +3801 3791 -14412746.88385 +3802 3791 8776281.331372 +3803 3791 59110190.1857 +3891 3791 17343888.52033 +3892 3791 -20812499.90894 +3893 3791 -37128840.43198 +3897 3791 -21679860.74397 +3898 3791 -69374999.6084 +3899 3791 -104457508.7431 +3900 3791 -17343888.84951 +3901 3791 -13874999.85143 +3902 3791 -181091253.0988 +3906 3791 -21679861.11823 +3907 3791 -17343750.0057 +3908 3791 -38039431.35476 +3909 3791 -86719444.24762 +3910 3791 -17343749.94043 +3911 3791 -121957897.9018 +3912 3791 -26015832.7805 +3913 3791 13874999.9393 +3914 3791 -37128840.43199 +3792 3792 1137565312.076 +3793 3792 4.64916229248e-06 +3794 3792 4571797.773345 +3795 3792 153072235.6709 +3796 3792 -3.814697265625e-06 +3797 3792 1142949.443904 +3804 3792 -223854518.1091 +3805 3792 1.281499862671e-06 +3806 3792 -3314544.719882 +3807 3792 -89126355.34779 +3808 3792 63656944.434 +3809 3792 -13600988.60888 +3894 3792 -113177912.5205 +3895 3792 -1.952052116394e-06 +3896 3792 86719444.4302 +3897 3792 -36072082.53399 +3898 3792 -16203472.22755 +3899 3792 21679861.11823 +3903 3792 65803613.40852 +3904 3792 4.112720489502e-06 +3905 3792 3.081560134888e-05 +3906 3792 -14659514.18418 +3907 3792 -1.010298728943e-05 +3908 3792 8.165836334229e-06 +3915 3792 -113177912.5204 +3916 3792 6.407499313354e-07 +3917 3792 -86719444.43019 +3918 3792 -36072082.53397 +3919 3792 16203472.22755 +3920 3792 -21679861.11823 +3793 3793 984782929.6775 +3794 3793 -54860648.90923 +3795 3793 -3.695487976074e-06 +3796 3793 -88823909.23288 +3797 3793 28253241.12114 +3804 3793 2.622604370117e-06 +3805 3793 56237222.37539 +3806 3793 -13715162.23406 +3807 3793 63656944.434 +3808 3793 -70028557.53863 +3809 3793 7680497.783698 +3894 3793 -4.097819328308e-06 +3895 3793 -41882340.60423 +3896 3793 1.296401023865e-06 +3897 3793 -16203472.22755 +3898 3793 -31210863.52938 +3899 3793 17343750.0057 +3903 3793 4.053115844727e-06 +3904 3793 26913861.39084 +3905 3793 4.738569259644e-06 +3906 3793 -7.331371307373e-06 +3907 3793 -76232648.10076 +3908 3793 69374999.9886 +3915 3793 -1.177191734314e-06 +3916 3793 -41882340.60421 +3917 3793 8.344650268555e-07 +3918 3793 16203472.22754 +3919 3793 -31210863.52937 +3920 3793 17343750.0057 +3794 3794 1205835345.84 +3795 3794 1142949.443904 +3796 3794 26607407.78808 +3797 3794 154975139.2593 +3804 3794 -1257253.053552 +3805 3794 -13715162.23407 +3806 3794 113190145.6041 +3807 3794 -13258106.66415 +3808 3794 7406192.227917 +3809 3794 -9211261.686427 +3894 3794 86719444.4302 +3895 3794 1.415610313416e-06 +3896 3794 -121047307.7997 +3897 3794 21679861.11823 +3898 3794 17343750.0057 +3899 3794 -38039431.35476 +3903 3794 3.02791595459e-05 +3904 3794 4.619359970093e-06 +3905 3794 -289746007.2349 +3906 3794 8.165836334229e-06 +3907 3794 69374999.9886 +3908 3794 -103546919.3888 +3915 3794 -86719444.43019 +3916 3794 8.940696716309e-07 +3917 3794 -121047307.7997 +3918 3794 -21679861.11823 +3919 3794 17343750.0057 +3920 3794 -38039431.35476 +3795 3795 1137565312.076 +3796 3795 4.64916229248e-06 +3797 3795 4571797.773345 +3798 3795 153072235.6709 +3799 3795 -3.814697265625e-06 +3800 3795 1142949.443904 +3804 3795 -88449163.50764 +3805 3795 -63656944.434 +3806 3795 12115157.22023 +3807 3795 -223854518.1091 +3808 3795 1.281499862671e-06 +3809 3795 -3314544.719882 +3810 3795 -89126355.34779 +3811 3795 63656944.434 +3812 3795 -13600988.60888 +3894 3795 -36072082.53399 +3895 3795 16203472.22755 +3896 3795 21679861.11823 +3897 3795 -113177912.5205 +3898 3795 -1.952052116394e-06 +3899 3795 86719444.4302 +3900 3795 -36072082.53399 +3901 3795 -16203472.22755 +3902 3795 21679861.11823 +3903 3795 -14659514.18418 +3904 3795 7.62939453125e-06 +3905 3795 7.152557373047e-06 +3906 3795 65803613.40852 +3907 3795 4.112720489502e-06 +3908 3795 3.081560134888e-05 +3909 3795 -14659514.18418 +3910 3795 -1.010298728943e-05 +3911 3795 8.165836334229e-06 +3915 3795 -36072082.53397 +3916 3795 -16203472.22754 +3917 3795 -21679861.11823 +3918 3795 -113177912.5204 +3919 3795 6.407499313354e-07 +3920 3795 -86719444.43019 +3921 3795 -36072082.53397 +3922 3795 16203472.22755 +3923 3795 -21679861.11823 +3796 3796 984782929.6775 +3797 3796 -54860648.90923 +3798 3796 -3.695487976074e-06 +3799 3796 -88823909.23288 +3800 3796 28253241.12114 +3804 3796 -63656944.434 +3805 3796 -69351365.69847 +3806 3796 6034664.450365 +3807 3796 2.622604370117e-06 +3808 3796 56237222.37539 +3809 3796 -13715162.23406 +3810 3796 63656944.434 +3811 3796 -70028557.53863 +3812 3796 7680497.783698 +3894 3796 16203472.22755 +3895 3796 -31210863.52938 +3896 3796 -17343750.00569 +3897 3796 -4.097819328308e-06 +3898 3796 -41882340.60423 +3899 3796 1.296401023865e-06 +3900 3796 -16203472.22755 +3901 3796 -31210863.52938 +3902 3796 17343750.0057 +3903 3796 8.970499038696e-06 +3904 3796 -76232648.10075 +3905 3796 -69374999.9886 +3906 3796 4.053115844727e-06 +3907 3796 26913861.39084 +3908 3796 4.738569259644e-06 +3909 3796 -7.331371307373e-06 +3910 3796 -76232648.10076 +3911 3796 69374999.9886 +3915 3796 -16203472.22754 +3916 3796 -31210863.52937 +3917 3796 -17343750.0057 +3918 3796 -1.177191734314e-06 +3919 3796 -41882340.60421 +3920 3796 8.344650268555e-07 +3921 3796 16203472.22754 +3922 3796 -31210863.52937 +3923 3796 17343750.0057 +3797 3797 1205835345.84 +3798 3797 1142949.443904 +3799 3797 26607407.78808 +3800 3797 154975139.2593 +3804 3797 12458039.16496 +3805 3797 6308970.006146 +3806 3797 -7405416.779322 +3807 3797 -1257253.053552 +3808 3797 -13715162.23407 +3809 3797 113190145.6041 +3810 3797 -13258106.66415 +3811 3797 7406192.227917 +3812 3797 -9211261.686427 +3894 3797 21679861.11823 +3895 3797 -17343750.00569 +3896 3797 -38039431.35476 +3897 3797 86719444.4302 +3898 3797 1.415610313416e-06 +3899 3797 -121047307.7997 +3900 3797 21679861.11823 +3901 3797 17343750.0057 +3902 3797 -38039431.35476 +3903 3797 7.182359695435e-06 +3904 3797 -69374999.9886 +3905 3797 -103546919.3888 +3906 3797 3.02791595459e-05 +3907 3797 4.619359970093e-06 +3908 3797 -289746007.2349 +3909 3797 8.165836334229e-06 +3910 3797 69374999.9886 +3911 3797 -103546919.3888 +3915 3797 -21679861.11823 +3916 3797 -17343750.0057 +3917 3797 -38039431.35476 +3918 3797 -86719444.43019 +3919 3797 8.940696716309e-07 +3920 3797 -121047307.7997 +3921 3797 -21679861.11823 +3922 3797 17343750.0057 +3923 3797 -38039431.35476 +3798 3798 1236679322.481 +3799 3798 63674967.6646 +3800 3798 15441526.4422 +3801 3798 49455964.79174 +3802 3798 -63664153.72624 +3803 3798 13608792.08924 +3807 3798 -88449163.50764 +3808 3798 -63656944.434 +3809 3798 12115157.22023 +3810 3798 -223854518.1091 +3811 3798 1.281499862671e-06 +3812 3798 -3314544.719882 +3813 3798 -89126355.34779 +3814 3798 63656944.434 +3815 3798 -13600988.60888 +3897 3798 -36072082.53399 +3898 3798 16203472.22755 +3899 3798 21679861.11823 +3900 3798 -135326679.0277 +3901 3798 -16203472.0331 +3902 3798 86719444.24762 +3906 3798 -14659514.18418 +3907 3798 7.62939453125e-06 +3908 3798 7.152557373047e-06 +3909 3798 101875695.1567 +3910 3798 16203471.90348 +3911 3798 0.03654569387436 +3912 3798 -36808280.87074 +3913 3798 -16203472.09792 +3914 3798 21679860.74398 +3918 3798 -36072082.53397 +3919 3798 -16203472.22754 +3920 3798 -21679861.11823 +3921 3798 -113177912.5204 +3922 3798 6.407499313354e-07 +3923 3798 -86719444.43019 +3924 3798 -36072082.53397 +3925 3798 16203472.22755 +3926 3798 -21679861.11823 +3799 3799 1064791031.509 +3800 3799 -42507558.78941 +3801 3799 -63667758.37236 +3802 3799 -173356800.7659 +3803 3799 23590660.68649 +3807 3799 -63656944.434 +3808 3799 -69351365.69847 +3809 3799 6034664.450365 +3810 3799 2.622604370117e-06 +3811 3799 56237222.37539 +3812 3799 -13715162.23406 +3813 3799 63656944.434 +3814 3799 -70028557.53863 +3815 3799 7680497.783698 +3897 3799 16203472.22755 +3898 3799 -31210863.52938 +3899 3799 -17343750.00569 +3900 3799 -16203472.09792 +3901 3799 -59169888.51195 +3902 3799 17343749.94043 +3906 3799 8.970499038696e-06 +3907 3799 -76232648.10075 +3908 3799 -69374999.9886 +3909 3799 16203471.90348 +3910 3799 58124724.28025 +3911 3799 0.029221534729 +3912 3799 -16203472.03311 +3913 3799 -93520195.52346 +3914 3799 69374999.6084 +3918 3799 -16203472.22754 +3919 3799 -31210863.52937 +3920 3799 -17343750.0057 +3921 3799 -1.177191734314e-06 +3922 3799 -41882340.60421 +3923 3799 8.344650268555e-07 +3924 3799 16203472.22754 +3925 3799 -31210863.52937 +3926 3799 17343750.0057 +3800 3800 1241583328.715 +3801 3800 13269811.8847 +3802 3800 25790082.19602 +3803 3800 107138521.2855 +3807 3800 12458039.16496 +3808 3800 6308970.006146 +3809 3800 -7405416.779322 +3810 3800 -1257253.053552 +3811 3800 -13715162.23407 +3812 3800 113190145.6041 +3813 3800 -13258106.66415 +3814 3800 7406192.227917 +3815 3800 -9211261.686427 +3897 3800 21679861.11823 +3898 3800 -17343750.00569 +3899 3800 -38039431.35476 +3900 3800 86719444.24762 +3901 3800 17343749.9078 +3902 3800 -121957897.9018 +3906 3800 7.182359695435e-06 +3907 3800 -69374999.9886 +3908 3800 -103546919.3888 +3909 3800 -0.03648543357849 +3910 3800 -0.02920261025429 +3911 3800 -251706576.231 +3912 3800 21679860.55685 +3913 3800 69374999.49133 +3914 3800 -104457508.7431 +3918 3800 -21679861.11823 +3919 3800 -17343750.0057 +3920 3800 -38039431.35476 +3921 3800 -86719444.43019 +3922 3800 8.940696716309e-07 +3923 3800 -121047307.7997 +3924 3800 -21679861.11823 +3925 3800 17343750.0057 +3926 3800 -38039431.35476 +3801 3801 731873593.1548 +3802 3801 63656944.434 +3803 3801 18282582.06852 +3810 3801 -88449163.50764 +3811 3801 -63656944.434 +3812 3801 12115157.22023 +3813 3801 -339558601.0551 +3814 3801 -63664153.72624 +3815 3801 -14174508.59703 +3816 3801 22166321.31964 +3817 3801 50932764.83944 +3818 3801 -9608497.922564 +3900 3801 -13923315.16199 +3901 3801 19444166.47861 +3902 3801 26015832.7805 +3909 3801 -36808280.87074 +3910 3801 -16203472.0331 +3911 3801 -21679860.55685 +3912 3801 41127258.27048 +3913 3801 16203472.22755 +3914 3801 17343888.84954 +3921 3801 -36072082.53397 +3922 3801 -16203472.22754 +3923 3801 -21679861.11823 +3924 3801 -135326679.0276 +3925 3801 -16203472.09792 +3926 3801 -86719444.24762 +3927 3801 -13923315.162 +3928 3801 12962777.65241 +3929 3801 -17343888.52033 +3802 3802 636376493.3815 +3803 3802 -30188925.21508 +3810 3802 -63656944.434 +3811 3802 -69351365.69847 +3812 3802 6034664.450365 +3813 3802 -63667758.37236 +3814 3802 -40346533.53339 +3815 3802 -19199086.44689 +3816 3802 76399147.25916 +3817 3802 22166321.31964 +3818 3802 13164421.99706 +3900 3802 12962777.65241 +3901 3802 -13923315.162 +3902 3802 -13874999.9393 +3909 3802 -16203472.09791 +3910 3802 -93520195.52345 +3911 3802 -69374999.49133 +3912 3802 16203472.22755 +3913 3802 16821163.40287 +3914 3802 13874999.85144 +3921 3802 -16203472.22754 +3922 3802 -31210863.52937 +3923 3802 -17343750.0057 +3924 3802 -16203472.0331 +3925 3802 -59169888.51194 +3926 3802 -17343749.90781 +3927 3802 19444166.47861 +3928 3802 -13923315.162 +3929 3802 20812499.90895 +3803 3803 809270793.6919 +3810 3803 12458039.16496 +3811 3803 6308970.006146 +3812 3803 -7405416.779322 +3813 3803 -12120471.86127 +3814 3803 -15085251.33671 +3815 3803 33187550.82531 +3816 3803 -14412746.88385 +3817 3803 8776281.331372 +3818 3803 59110190.1857 +3900 3803 17343888.52033 +3901 3803 -20812499.90894 +3902 3803 -37128840.43198 +3909 3803 -21679860.74397 +3910 3803 -69374999.6084 +3911 3803 -104457508.7431 +3912 3803 -17343888.84951 +3913 3803 -13874999.85143 +3914 3803 -181091253.0988 +3921 3803 -21679861.11823 +3922 3803 -17343750.0057 +3923 3803 -38039431.35476 +3924 3803 -86719444.24762 +3925 3803 -17343749.94043 +3926 3803 -121957897.9018 +3927 3803 -26015832.7805 +3928 3803 13874999.9393 +3929 3803 -37128840.43199 +3804 3804 1137565312.076 +3805 3804 4.64916229248e-06 +3806 3804 4571797.773345 +3807 3804 153072235.6709 +3808 3804 -3.814697265625e-06 +3809 3804 1142949.443904 +3819 3804 -223854518.1091 +3820 3804 1.281499862671e-06 +3821 3804 -3314544.719882 +3822 3804 -89126355.34779 +3823 3804 63656944.434 +3824 3804 -13600988.60888 +3903 3804 -113177912.5205 +3904 3804 -1.952052116394e-06 +3905 3804 86719444.4302 +3906 3804 -36072082.53399 +3907 3804 -16203472.22755 +3908 3804 21679861.11823 +3915 3804 65803613.40852 +3916 3804 4.112720489502e-06 +3917 3804 3.081560134888e-05 +3918 3804 -14659514.18418 +3919 3804 -1.010298728943e-05 +3920 3804 8.165836334229e-06 +3930 3804 -113177912.5204 +3931 3804 6.407499313354e-07 +3932 3804 -86719444.43019 +3933 3804 -36072082.53397 +3934 3804 16203472.22755 +3935 3804 -21679861.11823 +3805 3805 984782929.6775 +3806 3805 -54860648.90923 +3807 3805 -3.695487976074e-06 +3808 3805 -88823909.23288 +3809 3805 28253241.12114 +3819 3805 2.622604370117e-06 +3820 3805 56237222.37539 +3821 3805 -13715162.23406 +3822 3805 63656944.434 +3823 3805 -70028557.53863 +3824 3805 7680497.783698 +3903 3805 -4.097819328308e-06 +3904 3805 -41882340.60423 +3905 3805 1.296401023865e-06 +3906 3805 -16203472.22755 +3907 3805 -31210863.52938 +3908 3805 17343750.0057 +3915 3805 4.053115844727e-06 +3916 3805 26913861.39084 +3917 3805 4.738569259644e-06 +3918 3805 -7.331371307373e-06 +3919 3805 -76232648.10076 +3920 3805 69374999.9886 +3930 3805 -1.177191734314e-06 +3931 3805 -41882340.60421 +3932 3805 8.344650268555e-07 +3933 3805 16203472.22754 +3934 3805 -31210863.52937 +3935 3805 17343750.0057 +3806 3806 1205835345.84 +3807 3806 1142949.443904 +3808 3806 26607407.78808 +3809 3806 154975139.2593 +3819 3806 -1257253.053552 +3820 3806 -13715162.23407 +3821 3806 113190145.6041 +3822 3806 -13258106.66415 +3823 3806 7406192.227917 +3824 3806 -9211261.686427 +3903 3806 86719444.4302 +3904 3806 1.415610313416e-06 +3905 3806 -121047307.7997 +3906 3806 21679861.11823 +3907 3806 17343750.0057 +3908 3806 -38039431.35476 +3915 3806 3.02791595459e-05 +3916 3806 4.619359970093e-06 +3917 3806 -289746007.2349 +3918 3806 8.165836334229e-06 +3919 3806 69374999.9886 +3920 3806 -103546919.3888 +3930 3806 -86719444.43019 +3931 3806 8.940696716309e-07 +3932 3806 -121047307.7997 +3933 3806 -21679861.11823 +3934 3806 17343750.0057 +3935 3806 -38039431.35476 +3807 3807 1137565312.076 +3808 3807 4.64916229248e-06 +3809 3807 4571797.773345 +3810 3807 153072235.6709 +3811 3807 -3.814697265625e-06 +3812 3807 1142949.443904 +3819 3807 -88449163.50764 +3820 3807 -63656944.434 +3821 3807 12115157.22023 +3822 3807 -223854518.1091 +3823 3807 1.281499862671e-06 +3824 3807 -3314544.719882 +3825 3807 -89126355.34779 +3826 3807 63656944.434 +3827 3807 -13600988.60888 +3903 3807 -36072082.53399 +3904 3807 16203472.22755 +3905 3807 21679861.11823 +3906 3807 -113177912.5205 +3907 3807 -1.952052116394e-06 +3908 3807 86719444.4302 +3909 3807 -36072082.53399 +3910 3807 -16203472.22755 +3911 3807 21679861.11823 +3915 3807 -14659514.18418 +3916 3807 7.62939453125e-06 +3917 3807 7.152557373047e-06 +3918 3807 65803613.40852 +3919 3807 4.112720489502e-06 +3920 3807 3.081560134888e-05 +3921 3807 -14659514.18418 +3922 3807 -1.010298728943e-05 +3923 3807 8.165836334229e-06 +3930 3807 -36072082.53397 +3931 3807 -16203472.22754 +3932 3807 -21679861.11823 +3933 3807 -113177912.5204 +3934 3807 6.407499313354e-07 +3935 3807 -86719444.43019 +3936 3807 -36072082.53397 +3937 3807 16203472.22755 +3938 3807 -21679861.11823 +3808 3808 984782929.6775 +3809 3808 -54860648.90923 +3810 3808 -3.695487976074e-06 +3811 3808 -88823909.23288 +3812 3808 28253241.12114 +3819 3808 -63656944.434 +3820 3808 -69351365.69847 +3821 3808 6034664.450365 +3822 3808 2.622604370117e-06 +3823 3808 56237222.37539 +3824 3808 -13715162.23406 +3825 3808 63656944.434 +3826 3808 -70028557.53863 +3827 3808 7680497.783698 +3903 3808 16203472.22755 +3904 3808 -31210863.52938 +3905 3808 -17343750.00569 +3906 3808 -4.097819328308e-06 +3907 3808 -41882340.60423 +3908 3808 1.296401023865e-06 +3909 3808 -16203472.22755 +3910 3808 -31210863.52938 +3911 3808 17343750.0057 +3915 3808 8.970499038696e-06 +3916 3808 -76232648.10075 +3917 3808 -69374999.9886 +3918 3808 4.053115844727e-06 +3919 3808 26913861.39084 +3920 3808 4.738569259644e-06 +3921 3808 -7.331371307373e-06 +3922 3808 -76232648.10076 +3923 3808 69374999.9886 +3930 3808 -16203472.22754 +3931 3808 -31210863.52937 +3932 3808 -17343750.0057 +3933 3808 -1.177191734314e-06 +3934 3808 -41882340.60421 +3935 3808 8.344650268555e-07 +3936 3808 16203472.22754 +3937 3808 -31210863.52937 +3938 3808 17343750.0057 +3809 3809 1205835345.84 +3810 3809 1142949.443904 +3811 3809 26607407.78808 +3812 3809 154975139.2593 +3819 3809 12458039.16496 +3820 3809 6308970.006146 +3821 3809 -7405416.779322 +3822 3809 -1257253.053552 +3823 3809 -13715162.23407 +3824 3809 113190145.6041 +3825 3809 -13258106.66415 +3826 3809 7406192.227917 +3827 3809 -9211261.686427 +3903 3809 21679861.11823 +3904 3809 -17343750.00569 +3905 3809 -38039431.35476 +3906 3809 86719444.4302 +3907 3809 1.415610313416e-06 +3908 3809 -121047307.7997 +3909 3809 21679861.11823 +3910 3809 17343750.0057 +3911 3809 -38039431.35476 +3915 3809 7.182359695435e-06 +3916 3809 -69374999.9886 +3917 3809 -103546919.3888 +3918 3809 3.02791595459e-05 +3919 3809 4.619359970093e-06 +3920 3809 -289746007.2349 +3921 3809 8.165836334229e-06 +3922 3809 69374999.9886 +3923 3809 -103546919.3888 +3930 3809 -21679861.11823 +3931 3809 -17343750.0057 +3932 3809 -38039431.35476 +3933 3809 -86719444.43019 +3934 3809 8.940696716309e-07 +3935 3809 -121047307.7997 +3936 3809 -21679861.11823 +3937 3809 17343750.0057 +3938 3809 -38039431.35476 +3810 3810 1137565312.076 +3811 3810 4.64916229248e-06 +3812 3810 4571797.773345 +3813 3810 153072235.6709 +3814 3810 -3.814697265625e-06 +3815 3810 1142949.443904 +3822 3810 -88449163.50764 +3823 3810 -63656944.434 +3824 3810 12115157.22023 +3825 3810 -223854518.1091 +3826 3810 1.281499862671e-06 +3827 3810 -3314544.719882 +3828 3810 -89126355.34779 +3829 3810 63656944.434 +3830 3810 -13600988.60888 +3906 3810 -36072082.53399 +3907 3810 16203472.22755 +3908 3810 21679861.11823 +3909 3810 -113177912.5205 +3910 3810 -1.952052116394e-06 +3911 3810 86719444.4302 +3912 3810 -36072082.53399 +3913 3810 -16203472.22755 +3914 3810 21679861.11823 +3918 3810 -14659514.18418 +3919 3810 7.62939453125e-06 +3920 3810 7.152557373047e-06 +3921 3810 65803613.40852 +3922 3810 4.112720489502e-06 +3923 3810 3.081560134888e-05 +3924 3810 -14659514.18418 +3925 3810 -1.010298728943e-05 +3926 3810 8.165836334229e-06 +3933 3810 -36072082.53397 +3934 3810 -16203472.22754 +3935 3810 -21679861.11823 +3936 3810 -113177912.5204 +3937 3810 6.407499313354e-07 +3938 3810 -86719444.43019 +3939 3810 -36072082.53397 +3940 3810 16203472.22755 +3941 3810 -21679861.11823 +3811 3811 984782929.6775 +3812 3811 -54860648.90923 +3813 3811 -3.695487976074e-06 +3814 3811 -88823909.23288 +3815 3811 28253241.12114 +3822 3811 -63656944.434 +3823 3811 -69351365.69847 +3824 3811 6034664.450365 +3825 3811 2.622604370117e-06 +3826 3811 56237222.37539 +3827 3811 -13715162.23406 +3828 3811 63656944.434 +3829 3811 -70028557.53863 +3830 3811 7680497.783698 +3906 3811 16203472.22755 +3907 3811 -31210863.52938 +3908 3811 -17343750.00569 +3909 3811 -4.097819328308e-06 +3910 3811 -41882340.60423 +3911 3811 1.296401023865e-06 +3912 3811 -16203472.22755 +3913 3811 -31210863.52938 +3914 3811 17343750.0057 +3918 3811 8.970499038696e-06 +3919 3811 -76232648.10075 +3920 3811 -69374999.9886 +3921 3811 4.053115844727e-06 +3922 3811 26913861.39084 +3923 3811 4.738569259644e-06 +3924 3811 -7.331371307373e-06 +3925 3811 -76232648.10076 +3926 3811 69374999.9886 +3933 3811 -16203472.22754 +3934 3811 -31210863.52937 +3935 3811 -17343750.0057 +3936 3811 -1.177191734314e-06 +3937 3811 -41882340.60421 +3938 3811 8.344650268555e-07 +3939 3811 16203472.22754 +3940 3811 -31210863.52937 +3941 3811 17343750.0057 +3812 3812 1205835345.84 +3813 3812 1142949.443904 +3814 3812 26607407.78808 +3815 3812 154975139.2593 +3822 3812 12458039.16496 +3823 3812 6308970.006146 +3824 3812 -7405416.779322 +3825 3812 -1257253.053552 +3826 3812 -13715162.23407 +3827 3812 113190145.6041 +3828 3812 -13258106.66415 +3829 3812 7406192.227917 +3830 3812 -9211261.686427 +3906 3812 21679861.11823 +3907 3812 -17343750.00569 +3908 3812 -38039431.35476 +3909 3812 86719444.4302 +3910 3812 1.415610313416e-06 +3911 3812 -121047307.7997 +3912 3812 21679861.11823 +3913 3812 17343750.0057 +3914 3812 -38039431.35476 +3918 3812 7.182359695435e-06 +3919 3812 -69374999.9886 +3920 3812 -103546919.3888 +3921 3812 3.02791595459e-05 +3922 3812 4.619359970093e-06 +3923 3812 -289746007.2349 +3924 3812 8.165836334229e-06 +3925 3812 69374999.9886 +3926 3812 -103546919.3888 +3933 3812 -21679861.11823 +3934 3812 -17343750.0057 +3935 3812 -38039431.35476 +3936 3812 -86719444.43019 +3937 3812 8.940696716309e-07 +3938 3812 -121047307.7997 +3939 3812 -21679861.11823 +3940 3812 17343750.0057 +3941 3812 -38039431.35476 +3813 3813 1236679322.481 +3814 3813 63674967.6646 +3815 3813 15441526.4422 +3816 3813 49455964.79174 +3817 3813 -63664153.72624 +3818 3813 13608792.08924 +3825 3813 -88449163.50764 +3826 3813 -63656944.434 +3827 3813 12115157.22023 +3828 3813 -223854518.1091 +3829 3813 1.281499862671e-06 +3830 3813 -3314544.719882 +3831 3813 -89126355.34779 +3832 3813 63656944.434 +3833 3813 -13600988.60888 +3909 3813 -36072082.53399 +3910 3813 16203472.22755 +3911 3813 21679861.11823 +3912 3813 -135326679.0277 +3913 3813 -16203472.0331 +3914 3813 86719444.24762 +3921 3813 -14659514.18418 +3922 3813 7.62939453125e-06 +3923 3813 7.152557373047e-06 +3924 3813 101875695.1567 +3925 3813 16203471.90348 +3926 3813 0.03654569387436 +3927 3813 -36808280.87074 +3928 3813 -16203472.09792 +3929 3813 21679860.74398 +3936 3813 -36072082.53397 +3937 3813 -16203472.22754 +3938 3813 -21679861.11823 +3939 3813 -113177912.5204 +3940 3813 6.407499313354e-07 +3941 3813 -86719444.43019 +3942 3813 -36072082.53397 +3943 3813 16203472.22755 +3944 3813 -21679861.11823 +3814 3814 1064791031.509 +3815 3814 -42507558.78941 +3816 3814 -63667758.37236 +3817 3814 -173356800.7659 +3818 3814 23590660.68649 +3825 3814 -63656944.434 +3826 3814 -69351365.69847 +3827 3814 6034664.450365 +3828 3814 2.622604370117e-06 +3829 3814 56237222.37539 +3830 3814 -13715162.23406 +3831 3814 63656944.434 +3832 3814 -70028557.53863 +3833 3814 7680497.783698 +3909 3814 16203472.22755 +3910 3814 -31210863.52938 +3911 3814 -17343750.00569 +3912 3814 -16203472.09792 +3913 3814 -59169888.51195 +3914 3814 17343749.94043 +3921 3814 8.970499038696e-06 +3922 3814 -76232648.10075 +3923 3814 -69374999.9886 +3924 3814 16203471.90348 +3925 3814 58124724.28025 +3926 3814 0.029221534729 +3927 3814 -16203472.03311 +3928 3814 -93520195.52346 +3929 3814 69374999.6084 +3936 3814 -16203472.22754 +3937 3814 -31210863.52937 +3938 3814 -17343750.0057 +3939 3814 -1.177191734314e-06 +3940 3814 -41882340.60421 +3941 3814 8.344650268555e-07 +3942 3814 16203472.22754 +3943 3814 -31210863.52937 +3944 3814 17343750.0057 +3815 3815 1241583328.715 +3816 3815 13269811.8847 +3817 3815 25790082.19602 +3818 3815 107138521.2855 +3825 3815 12458039.16496 +3826 3815 6308970.006146 +3827 3815 -7405416.779322 +3828 3815 -1257253.053552 +3829 3815 -13715162.23407 +3830 3815 113190145.6041 +3831 3815 -13258106.66415 +3832 3815 7406192.227917 +3833 3815 -9211261.686427 +3909 3815 21679861.11823 +3910 3815 -17343750.00569 +3911 3815 -38039431.35476 +3912 3815 86719444.24762 +3913 3815 17343749.9078 +3914 3815 -121957897.9018 +3921 3815 7.182359695435e-06 +3922 3815 -69374999.9886 +3923 3815 -103546919.3888 +3924 3815 -0.03648543357849 +3925 3815 -0.02920261025429 +3926 3815 -251706576.231 +3927 3815 21679860.55685 +3928 3815 69374999.49133 +3929 3815 -104457508.7431 +3936 3815 -21679861.11823 +3937 3815 -17343750.0057 +3938 3815 -38039431.35476 +3939 3815 -86719444.43019 +3940 3815 8.940696716309e-07 +3941 3815 -121047307.7997 +3942 3815 -21679861.11823 +3943 3815 17343750.0057 +3944 3815 -38039431.35476 +3816 3816 731873593.1548 +3817 3816 63656944.434 +3818 3816 18282582.06852 +3828 3816 -88449163.50764 +3829 3816 -63656944.434 +3830 3816 12115157.22023 +3831 3816 -339558601.0551 +3832 3816 -63664153.72624 +3833 3816 -14174508.59703 +3834 3816 22166321.31964 +3835 3816 50932764.83944 +3836 3816 -9608497.922564 +3912 3816 -13923315.16199 +3913 3816 19444166.47861 +3914 3816 26015832.7805 +3924 3816 -36808280.87074 +3925 3816 -16203472.0331 +3926 3816 -21679860.55685 +3927 3816 41127258.27048 +3928 3816 16203472.22755 +3929 3816 17343888.84954 +3939 3816 -36072082.53397 +3940 3816 -16203472.22754 +3941 3816 -21679861.11823 +3942 3816 -135326679.0276 +3943 3816 -16203472.09792 +3944 3816 -86719444.24762 +3945 3816 -13923315.162 +3946 3816 12962777.65241 +3947 3816 -17343888.52033 +3817 3817 636376493.3815 +3818 3817 -30188925.21508 +3828 3817 -63656944.434 +3829 3817 -69351365.69847 +3830 3817 6034664.450365 +3831 3817 -63667758.37236 +3832 3817 -40346533.53339 +3833 3817 -19199086.44689 +3834 3817 76399147.25916 +3835 3817 22166321.31964 +3836 3817 13164421.99706 +3912 3817 12962777.65241 +3913 3817 -13923315.162 +3914 3817 -13874999.9393 +3924 3817 -16203472.09791 +3925 3817 -93520195.52345 +3926 3817 -69374999.49133 +3927 3817 16203472.22755 +3928 3817 16821163.40287 +3929 3817 13874999.85144 +3939 3817 -16203472.22754 +3940 3817 -31210863.52937 +3941 3817 -17343750.0057 +3942 3817 -16203472.0331 +3943 3817 -59169888.51194 +3944 3817 -17343749.90781 +3945 3817 19444166.47861 +3946 3817 -13923315.162 +3947 3817 20812499.90895 +3818 3818 809270793.6919 +3828 3818 12458039.16496 +3829 3818 6308970.006146 +3830 3818 -7405416.779322 +3831 3818 -12120471.86127 +3832 3818 -15085251.33671 +3833 3818 33187550.82531 +3834 3818 -14412746.88385 +3835 3818 8776281.331372 +3836 3818 59110190.1857 +3912 3818 17343888.52033 +3913 3818 -20812499.90894 +3914 3818 -37128840.43198 +3924 3818 -21679860.74397 +3925 3818 -69374999.6084 +3926 3818 -104457508.7431 +3927 3818 -17343888.84951 +3928 3818 -13874999.85143 +3929 3818 -181091253.0988 +3939 3818 -21679861.11823 +3940 3818 -17343750.0057 +3941 3818 -38039431.35476 +3942 3818 -86719444.24762 +3943 3818 -17343749.94043 +3944 3818 -121957897.9018 +3945 3818 -26015832.7805 +3946 3818 13874999.9393 +3947 3818 -37128840.43199 +3819 3819 1137565312.076 +3820 3819 4.64916229248e-06 +3821 3819 4571797.773345 +3822 3819 153072235.6709 +3823 3819 -3.814697265625e-06 +3824 3819 1142949.443904 +3837 3819 -223854518.1091 +3838 3819 1.281499862671e-06 +3839 3819 -3314544.719882 +3840 3819 -89126355.34779 +3841 3819 63656944.434 +3842 3819 -13600988.60888 +3915 3819 -113177912.5205 +3916 3819 -1.952052116394e-06 +3917 3819 86719444.4302 +3918 3819 -36072082.53399 +3919 3819 -16203472.22755 +3920 3819 21679861.11823 +3930 3819 65803613.40852 +3931 3819 4.112720489502e-06 +3932 3819 3.081560134888e-05 +3933 3819 -14659514.18418 +3934 3819 -1.010298728943e-05 +3935 3819 8.165836334229e-06 +3948 3819 -113177912.5204 +3949 3819 6.407499313354e-07 +3950 3819 -86719444.43019 +3951 3819 -36072082.53397 +3952 3819 16203472.22755 +3953 3819 -21679861.11823 +3820 3820 984782929.6775 +3821 3820 -54860648.90923 +3822 3820 -3.695487976074e-06 +3823 3820 -88823909.23288 +3824 3820 28253241.12114 +3837 3820 2.622604370117e-06 +3838 3820 56237222.37539 +3839 3820 -13715162.23406 +3840 3820 63656944.434 +3841 3820 -70028557.53863 +3842 3820 7680497.783698 +3915 3820 -4.097819328308e-06 +3916 3820 -41882340.60423 +3917 3820 1.296401023865e-06 +3918 3820 -16203472.22755 +3919 3820 -31210863.52938 +3920 3820 17343750.0057 +3930 3820 4.053115844727e-06 +3931 3820 26913861.39084 +3932 3820 4.738569259644e-06 +3933 3820 -7.331371307373e-06 +3934 3820 -76232648.10076 +3935 3820 69374999.9886 +3948 3820 -1.177191734314e-06 +3949 3820 -41882340.60421 +3950 3820 8.344650268555e-07 +3951 3820 16203472.22754 +3952 3820 -31210863.52937 +3953 3820 17343750.0057 +3821 3821 1205835345.84 +3822 3821 1142949.443904 +3823 3821 26607407.78808 +3824 3821 154975139.2593 +3837 3821 -1257253.053552 +3838 3821 -13715162.23407 +3839 3821 113190145.6041 +3840 3821 -13258106.66415 +3841 3821 7406192.227917 +3842 3821 -9211261.686427 +3915 3821 86719444.4302 +3916 3821 1.415610313416e-06 +3917 3821 -121047307.7997 +3918 3821 21679861.11823 +3919 3821 17343750.0057 +3920 3821 -38039431.35476 +3930 3821 3.02791595459e-05 +3931 3821 4.619359970093e-06 +3932 3821 -289746007.2349 +3933 3821 8.165836334229e-06 +3934 3821 69374999.9886 +3935 3821 -103546919.3888 +3948 3821 -86719444.43019 +3949 3821 8.940696716309e-07 +3950 3821 -121047307.7997 +3951 3821 -21679861.11823 +3952 3821 17343750.0057 +3953 3821 -38039431.35476 +3822 3822 1137565312.076 +3823 3822 4.64916229248e-06 +3824 3822 4571797.773345 +3825 3822 153072235.6709 +3826 3822 -3.814697265625e-06 +3827 3822 1142949.443904 +3837 3822 -88449163.50764 +3838 3822 -63656944.434 +3839 3822 12115157.22023 +3840 3822 -223854518.1091 +3841 3822 1.281499862671e-06 +3842 3822 -3314544.719882 +3843 3822 -89126355.34779 +3844 3822 63656944.434 +3845 3822 -13600988.60888 +3915 3822 -36072082.53399 +3916 3822 16203472.22755 +3917 3822 21679861.11823 +3918 3822 -113177912.5205 +3919 3822 -1.952052116394e-06 +3920 3822 86719444.4302 +3921 3822 -36072082.53399 +3922 3822 -16203472.22755 +3923 3822 21679861.11823 +3930 3822 -14659514.18418 +3931 3822 7.62939453125e-06 +3932 3822 7.152557373047e-06 +3933 3822 65803613.40852 +3934 3822 4.112720489502e-06 +3935 3822 3.081560134888e-05 +3936 3822 -14659514.18418 +3937 3822 -1.010298728943e-05 +3938 3822 8.165836334229e-06 +3948 3822 -36072082.53397 +3949 3822 -16203472.22754 +3950 3822 -21679861.11823 +3951 3822 -113177912.5204 +3952 3822 6.407499313354e-07 +3953 3822 -86719444.43019 +3954 3822 -36072082.53397 +3955 3822 16203472.22755 +3956 3822 -21679861.11823 +3823 3823 984782929.6775 +3824 3823 -54860648.90923 +3825 3823 -3.695487976074e-06 +3826 3823 -88823909.23288 +3827 3823 28253241.12114 +3837 3823 -63656944.434 +3838 3823 -69351365.69847 +3839 3823 6034664.450365 +3840 3823 2.622604370117e-06 +3841 3823 56237222.37539 +3842 3823 -13715162.23406 +3843 3823 63656944.434 +3844 3823 -70028557.53863 +3845 3823 7680497.783698 +3915 3823 16203472.22755 +3916 3823 -31210863.52938 +3917 3823 -17343750.00569 +3918 3823 -4.097819328308e-06 +3919 3823 -41882340.60423 +3920 3823 1.296401023865e-06 +3921 3823 -16203472.22755 +3922 3823 -31210863.52938 +3923 3823 17343750.0057 +3930 3823 8.970499038696e-06 +3931 3823 -76232648.10075 +3932 3823 -69374999.9886 +3933 3823 4.053115844727e-06 +3934 3823 26913861.39084 +3935 3823 4.738569259644e-06 +3936 3823 -7.331371307373e-06 +3937 3823 -76232648.10076 +3938 3823 69374999.9886 +3948 3823 -16203472.22754 +3949 3823 -31210863.52937 +3950 3823 -17343750.0057 +3951 3823 -1.177191734314e-06 +3952 3823 -41882340.60421 +3953 3823 8.344650268555e-07 +3954 3823 16203472.22754 +3955 3823 -31210863.52937 +3956 3823 17343750.0057 +3824 3824 1205835345.84 +3825 3824 1142949.443904 +3826 3824 26607407.78808 +3827 3824 154975139.2593 +3837 3824 12458039.16496 +3838 3824 6308970.006146 +3839 3824 -7405416.779322 +3840 3824 -1257253.053552 +3841 3824 -13715162.23407 +3842 3824 113190145.6041 +3843 3824 -13258106.66415 +3844 3824 7406192.227917 +3845 3824 -9211261.686427 +3915 3824 21679861.11823 +3916 3824 -17343750.00569 +3917 3824 -38039431.35476 +3918 3824 86719444.4302 +3919 3824 1.415610313416e-06 +3920 3824 -121047307.7997 +3921 3824 21679861.11823 +3922 3824 17343750.0057 +3923 3824 -38039431.35476 +3930 3824 7.182359695435e-06 +3931 3824 -69374999.9886 +3932 3824 -103546919.3888 +3933 3824 3.02791595459e-05 +3934 3824 4.619359970093e-06 +3935 3824 -289746007.2349 +3936 3824 8.165836334229e-06 +3937 3824 69374999.9886 +3938 3824 -103546919.3888 +3948 3824 -21679861.11823 +3949 3824 -17343750.0057 +3950 3824 -38039431.35476 +3951 3824 -86719444.43019 +3952 3824 8.940696716309e-07 +3953 3824 -121047307.7997 +3954 3824 -21679861.11823 +3955 3824 17343750.0057 +3956 3824 -38039431.35476 +3825 3825 1137565312.076 +3826 3825 4.64916229248e-06 +3827 3825 4571797.773345 +3828 3825 153072235.6709 +3829 3825 -3.814697265625e-06 +3830 3825 1142949.443904 +3840 3825 -88449163.50764 +3841 3825 -63656944.434 +3842 3825 12115157.22023 +3843 3825 -223854518.1091 +3844 3825 1.281499862671e-06 +3845 3825 -3314544.719882 +3846 3825 -89126355.34779 +3847 3825 63656944.434 +3848 3825 -13600988.60888 +3918 3825 -36072082.53399 +3919 3825 16203472.22755 +3920 3825 21679861.11823 +3921 3825 -113177912.5205 +3922 3825 -1.952052116394e-06 +3923 3825 86719444.4302 +3924 3825 -36072082.53399 +3925 3825 -16203472.22755 +3926 3825 21679861.11823 +3933 3825 -14659514.18418 +3934 3825 7.62939453125e-06 +3935 3825 7.152557373047e-06 +3936 3825 65803613.40852 +3937 3825 4.112720489502e-06 +3938 3825 3.081560134888e-05 +3939 3825 -14659514.18418 +3940 3825 -1.010298728943e-05 +3941 3825 8.165836334229e-06 +3951 3825 -36072082.53397 +3952 3825 -16203472.22754 +3953 3825 -21679861.11823 +3954 3825 -113177912.5204 +3955 3825 6.407499313354e-07 +3956 3825 -86719444.43019 +3957 3825 -36072082.53397 +3958 3825 16203472.22755 +3959 3825 -21679861.11823 +3826 3826 984782929.6775 +3827 3826 -54860648.90923 +3828 3826 -3.695487976074e-06 +3829 3826 -88823909.23288 +3830 3826 28253241.12114 +3840 3826 -63656944.434 +3841 3826 -69351365.69847 +3842 3826 6034664.450365 +3843 3826 2.622604370117e-06 +3844 3826 56237222.37539 +3845 3826 -13715162.23406 +3846 3826 63656944.434 +3847 3826 -70028557.53863 +3848 3826 7680497.783698 +3918 3826 16203472.22755 +3919 3826 -31210863.52938 +3920 3826 -17343750.00569 +3921 3826 -4.097819328308e-06 +3922 3826 -41882340.60423 +3923 3826 1.296401023865e-06 +3924 3826 -16203472.22755 +3925 3826 -31210863.52938 +3926 3826 17343750.0057 +3933 3826 8.970499038696e-06 +3934 3826 -76232648.10075 +3935 3826 -69374999.9886 +3936 3826 4.053115844727e-06 +3937 3826 26913861.39084 +3938 3826 4.738569259644e-06 +3939 3826 -7.331371307373e-06 +3940 3826 -76232648.10076 +3941 3826 69374999.9886 +3951 3826 -16203472.22754 +3952 3826 -31210863.52937 +3953 3826 -17343750.0057 +3954 3826 -1.177191734314e-06 +3955 3826 -41882340.60421 +3956 3826 8.344650268555e-07 +3957 3826 16203472.22754 +3958 3826 -31210863.52937 +3959 3826 17343750.0057 +3827 3827 1205835345.84 +3828 3827 1142949.443904 +3829 3827 26607407.78808 +3830 3827 154975139.2593 +3840 3827 12458039.16496 +3841 3827 6308970.006146 +3842 3827 -7405416.779322 +3843 3827 -1257253.053552 +3844 3827 -13715162.23407 +3845 3827 113190145.6041 +3846 3827 -13258106.66415 +3847 3827 7406192.227917 +3848 3827 -9211261.686427 +3918 3827 21679861.11823 +3919 3827 -17343750.00569 +3920 3827 -38039431.35476 +3921 3827 86719444.4302 +3922 3827 1.415610313416e-06 +3923 3827 -121047307.7997 +3924 3827 21679861.11823 +3925 3827 17343750.0057 +3926 3827 -38039431.35476 +3933 3827 7.182359695435e-06 +3934 3827 -69374999.9886 +3935 3827 -103546919.3888 +3936 3827 3.02791595459e-05 +3937 3827 4.619359970093e-06 +3938 3827 -289746007.2349 +3939 3827 8.165836334229e-06 +3940 3827 69374999.9886 +3941 3827 -103546919.3888 +3951 3827 -21679861.11823 +3952 3827 -17343750.0057 +3953 3827 -38039431.35476 +3954 3827 -86719444.43019 +3955 3827 8.940696716309e-07 +3956 3827 -121047307.7997 +3957 3827 -21679861.11823 +3958 3827 17343750.0057 +3959 3827 -38039431.35476 +3828 3828 1137565312.076 +3829 3828 4.64916229248e-06 +3830 3828 4571797.773345 +3831 3828 153072235.6709 +3832 3828 -3.814697265625e-06 +3833 3828 1142949.443904 +3843 3828 -88449163.50764 +3844 3828 -63656944.434 +3845 3828 12115157.22023 +3846 3828 -223854518.1091 +3847 3828 1.281499862671e-06 +3848 3828 -3314544.719882 +3849 3828 -89126355.34779 +3850 3828 63656944.434 +3851 3828 -13600988.60888 +3921 3828 -36072082.53399 +3922 3828 16203472.22755 +3923 3828 21679861.11823 +3924 3828 -113177912.5205 +3925 3828 -1.952052116394e-06 +3926 3828 86719444.4302 +3927 3828 -36072082.53399 +3928 3828 -16203472.22755 +3929 3828 21679861.11823 +3936 3828 -14659514.18418 +3937 3828 7.62939453125e-06 +3938 3828 7.152557373047e-06 +3939 3828 65803613.40852 +3940 3828 4.112720489502e-06 +3941 3828 3.081560134888e-05 +3942 3828 -14659514.18418 +3943 3828 -1.010298728943e-05 +3944 3828 8.165836334229e-06 +3954 3828 -36072082.53397 +3955 3828 -16203472.22754 +3956 3828 -21679861.11823 +3957 3828 -113177912.5204 +3958 3828 6.407499313354e-07 +3959 3828 -86719444.43019 +3960 3828 -36072082.53397 +3961 3828 16203472.22755 +3962 3828 -21679861.11823 +3829 3829 984782929.6775 +3830 3829 -54860648.90923 +3831 3829 -3.695487976074e-06 +3832 3829 -88823909.23288 +3833 3829 28253241.12114 +3843 3829 -63656944.434 +3844 3829 -69351365.69847 +3845 3829 6034664.450365 +3846 3829 2.622604370117e-06 +3847 3829 56237222.37539 +3848 3829 -13715162.23406 +3849 3829 63656944.434 +3850 3829 -70028557.53863 +3851 3829 7680497.783698 +3921 3829 16203472.22755 +3922 3829 -31210863.52938 +3923 3829 -17343750.00569 +3924 3829 -4.097819328308e-06 +3925 3829 -41882340.60423 +3926 3829 1.296401023865e-06 +3927 3829 -16203472.22755 +3928 3829 -31210863.52938 +3929 3829 17343750.0057 +3936 3829 8.970499038696e-06 +3937 3829 -76232648.10075 +3938 3829 -69374999.9886 +3939 3829 4.053115844727e-06 +3940 3829 26913861.39084 +3941 3829 4.738569259644e-06 +3942 3829 -7.331371307373e-06 +3943 3829 -76232648.10076 +3944 3829 69374999.9886 +3954 3829 -16203472.22754 +3955 3829 -31210863.52937 +3956 3829 -17343750.0057 +3957 3829 -1.177191734314e-06 +3958 3829 -41882340.60421 +3959 3829 8.344650268555e-07 +3960 3829 16203472.22754 +3961 3829 -31210863.52937 +3962 3829 17343750.0057 +3830 3830 1205835345.84 +3831 3830 1142949.443904 +3832 3830 26607407.78808 +3833 3830 154975139.2593 +3843 3830 12458039.16496 +3844 3830 6308970.006146 +3845 3830 -7405416.779322 +3846 3830 -1257253.053552 +3847 3830 -13715162.23407 +3848 3830 113190145.6041 +3849 3830 -13258106.66415 +3850 3830 7406192.227917 +3851 3830 -9211261.686427 +3921 3830 21679861.11823 +3922 3830 -17343750.00569 +3923 3830 -38039431.35476 +3924 3830 86719444.4302 +3925 3830 1.415610313416e-06 +3926 3830 -121047307.7997 +3927 3830 21679861.11823 +3928 3830 17343750.0057 +3929 3830 -38039431.35476 +3936 3830 7.182359695435e-06 +3937 3830 -69374999.9886 +3938 3830 -103546919.3888 +3939 3830 3.02791595459e-05 +3940 3830 4.619359970093e-06 +3941 3830 -289746007.2349 +3942 3830 8.165836334229e-06 +3943 3830 69374999.9886 +3944 3830 -103546919.3888 +3954 3830 -21679861.11823 +3955 3830 -17343750.0057 +3956 3830 -38039431.35476 +3957 3830 -86719444.43019 +3958 3830 8.940696716309e-07 +3959 3830 -121047307.7997 +3960 3830 -21679861.11823 +3961 3830 17343750.0057 +3962 3830 -38039431.35476 +3831 3831 1236679322.481 +3832 3831 63674967.6646 +3833 3831 15441526.4422 +3834 3831 49455964.79174 +3835 3831 -63664153.72624 +3836 3831 13608792.08924 +3846 3831 -88449163.50764 +3847 3831 -63656944.434 +3848 3831 12115157.22023 +3849 3831 -223854518.1091 +3850 3831 1.281499862671e-06 +3851 3831 -3314544.719882 +3852 3831 -89126355.34779 +3853 3831 63656944.434 +3854 3831 -13600988.60888 +3924 3831 -36072082.53399 +3925 3831 16203472.22755 +3926 3831 21679861.11823 +3927 3831 -135326679.0277 +3928 3831 -16203472.0331 +3929 3831 86719444.24762 +3939 3831 -14659514.18418 +3940 3831 7.62939453125e-06 +3941 3831 7.152557373047e-06 +3942 3831 101875695.1567 +3943 3831 16203471.90348 +3944 3831 0.03654569387436 +3945 3831 -36808280.87074 +3946 3831 -16203472.09792 +3947 3831 21679860.74398 +3957 3831 -36072082.53397 +3958 3831 -16203472.22754 +3959 3831 -21679861.11823 +3960 3831 -113177912.5204 +3961 3831 6.407499313354e-07 +3962 3831 -86719444.43019 +3963 3831 -36072082.53397 +3964 3831 16203472.22755 +3965 3831 -21679861.11823 +3832 3832 1064791031.509 +3833 3832 -42507558.78941 +3834 3832 -63667758.37236 +3835 3832 -173356800.7659 +3836 3832 23590660.68649 +3846 3832 -63656944.434 +3847 3832 -69351365.69847 +3848 3832 6034664.450365 +3849 3832 2.622604370117e-06 +3850 3832 56237222.37539 +3851 3832 -13715162.23406 +3852 3832 63656944.434 +3853 3832 -70028557.53863 +3854 3832 7680497.783698 +3924 3832 16203472.22755 +3925 3832 -31210863.52938 +3926 3832 -17343750.00569 +3927 3832 -16203472.09792 +3928 3832 -59169888.51195 +3929 3832 17343749.94043 +3939 3832 8.970499038696e-06 +3940 3832 -76232648.10075 +3941 3832 -69374999.9886 +3942 3832 16203471.90348 +3943 3832 58124724.28025 +3944 3832 0.029221534729 +3945 3832 -16203472.03311 +3946 3832 -93520195.52346 +3947 3832 69374999.6084 +3957 3832 -16203472.22754 +3958 3832 -31210863.52937 +3959 3832 -17343750.0057 +3960 3832 -1.177191734314e-06 +3961 3832 -41882340.60421 +3962 3832 8.344650268555e-07 +3963 3832 16203472.22754 +3964 3832 -31210863.52937 +3965 3832 17343750.0057 +3833 3833 1241583328.715 +3834 3833 13269811.8847 +3835 3833 25790082.19602 +3836 3833 107138521.2855 +3846 3833 12458039.16496 +3847 3833 6308970.006146 +3848 3833 -7405416.779322 +3849 3833 -1257253.053552 +3850 3833 -13715162.23407 +3851 3833 113190145.6041 +3852 3833 -13258106.66415 +3853 3833 7406192.227917 +3854 3833 -9211261.686427 +3924 3833 21679861.11823 +3925 3833 -17343750.00569 +3926 3833 -38039431.35476 +3927 3833 86719444.24762 +3928 3833 17343749.9078 +3929 3833 -121957897.9018 +3939 3833 7.182359695435e-06 +3940 3833 -69374999.9886 +3941 3833 -103546919.3888 +3942 3833 -0.03648543357849 +3943 3833 -0.02920261025429 +3944 3833 -251706576.231 +3945 3833 21679860.55685 +3946 3833 69374999.49133 +3947 3833 -104457508.7431 +3957 3833 -21679861.11823 +3958 3833 -17343750.0057 +3959 3833 -38039431.35476 +3960 3833 -86719444.43019 +3961 3833 8.940696716309e-07 +3962 3833 -121047307.7997 +3963 3833 -21679861.11823 +3964 3833 17343750.0057 +3965 3833 -38039431.35476 +3834 3834 753206313.808 +3835 3834 68026432.09525 +3836 3834 -4626567.456927 +3849 3834 -88449163.50764 +3850 3834 -63656944.434 +3851 3834 12115157.22023 +3852 3834 -341975368.7049 +3853 3834 -68039344.23401 +3854 3834 -876918.7379556 +3855 3834 31371891.95152 +3856 3834 50938467.68596 +3857 3834 -1381632.119869 +3927 3834 -13923315.16199 +3928 3834 19444166.47861 +3929 3834 26015832.7805 +3942 3834 -36808280.87074 +3943 3834 -16203472.0331 +3944 3834 -21679860.55685 +3945 3834 42592361.7517 +3946 3834 17468608.18462 +3947 3834 17682222.18139 +3960 3834 -36072082.53397 +3961 3834 -16203472.22754 +3962 3834 -21679861.11823 +3963 3834 -139005882.4837 +3964 3834 -17468608.05498 +3965 3834 -88411110.90688 +3966 3834 -13882071.21844 +3967 3834 12962777.65241 +3968 3834 -18020555.17262 +3835 3835 652353022.169 +3836 3835 -29654678.01534 +3849 3835 -63656944.434 +3850 3835 -69351365.69847 +3851 3835 6034664.450365 +3852 3835 -68045800.30339 +3853 3835 -40783133.78399 +3854 3835 -8009373.208703 +3855 3835 76407701.52894 +3856 3835 34747916.41813 +3857 3835 1988516.814094 +3927 3835 12962777.65241 +3928 3835 -13923315.162 +3929 3835 -13874999.9393 +3942 3835 -16203472.09791 +3943 3835 -93520195.52345 +3944 3835 -69374999.49133 +3945 3835 17468608.18461 +3946 3835 16743847.91339 +3947 3835 14145833.18359 +3960 3835 -16203472.22754 +3961 3835 -31210863.52937 +3962 3835 -17343750.0057 +3963 3835 -17468607.99017 +3964 3835 -62280769.56998 +3965 3835 -18697916.56855 +3966 3835 19444166.47861 +3967 3835 -12907974.64576 +3968 3835 20270833.25379 +3836 3836 845960452.2258 +3849 3836 12458039.16496 +3850 3836 6308970.006146 +3851 3836 -7405416.779322 +3852 3836 -3628661.835378 +3853 3836 -7464235.36192 +3854 3836 50316458.1007 +3855 3836 -2072448.179803 +3856 3836 1443101.03928 +3857 3836 80282354.07081 +3927 3836 17343888.52033 +3928 3836 -20812499.90894 +3929 3836 -37128840.43198 +3942 3836 -21679860.74397 +3943 3836 -69374999.6084 +3944 3836 -104457508.7431 +3945 3836 -17682222.18136 +3946 3836 -14145833.18358 +3947 3836 -183017309.7474 +3960 3836 -21679861.11823 +3961 3836 -17343750.0057 +3962 3836 -38039431.35476 +3963 3836 -88411110.90688 +3964 3836 -18697916.60118 +3965 3836 -124962011.2801 +3966 3836 -27030832.75893 +3967 3836 13062499.95656 +3968 3836 -37992953.15516 +3837 3837 1137565312.076 +3838 3837 4.64916229248e-06 +3839 3837 4571797.773345 +3840 3837 153072235.6709 +3841 3837 -3.814697265625e-06 +3842 3837 1142949.443904 +3858 3837 -223854518.1091 +3859 3837 1.281499862671e-06 +3860 3837 -3314544.719882 +3861 3837 -89126355.34779 +3862 3837 63656944.434 +3863 3837 -13600988.60888 +3930 3837 -113177912.5205 +3931 3837 -1.952052116394e-06 +3932 3837 86719444.4302 +3933 3837 -36072082.53399 +3934 3837 -16203472.22755 +3935 3837 21679861.11823 +3948 3837 65803613.40852 +3949 3837 4.112720489502e-06 +3950 3837 3.081560134888e-05 +3951 3837 -14659514.18418 +3952 3837 -1.010298728943e-05 +3953 3837 8.165836334229e-06 +3969 3837 -113177912.5204 +3970 3837 6.407499313354e-07 +3971 3837 -86719444.43019 +3972 3837 -36072082.53397 +3973 3837 16203472.22755 +3974 3837 -21679861.11823 +3838 3838 984782929.6775 +3839 3838 -54860648.90923 +3840 3838 -3.695487976074e-06 +3841 3838 -88823909.23288 +3842 3838 28253241.12114 +3858 3838 2.622604370117e-06 +3859 3838 56237222.37539 +3860 3838 -13715162.23406 +3861 3838 63656944.434 +3862 3838 -70028557.53863 +3863 3838 7680497.783698 +3930 3838 -4.097819328308e-06 +3931 3838 -41882340.60423 +3932 3838 1.296401023865e-06 +3933 3838 -16203472.22755 +3934 3838 -31210863.52938 +3935 3838 17343750.0057 +3948 3838 4.053115844727e-06 +3949 3838 26913861.39084 +3950 3838 4.738569259644e-06 +3951 3838 -7.331371307373e-06 +3952 3838 -76232648.10076 +3953 3838 69374999.9886 +3969 3838 -1.177191734314e-06 +3970 3838 -41882340.60421 +3971 3838 8.344650268555e-07 +3972 3838 16203472.22754 +3973 3838 -31210863.52937 +3974 3838 17343750.0057 +3839 3839 1205835345.84 +3840 3839 1142949.443904 +3841 3839 26607407.78808 +3842 3839 154975139.2593 +3858 3839 -1257253.053552 +3859 3839 -13715162.23407 +3860 3839 113190145.6041 +3861 3839 -13258106.66415 +3862 3839 7406192.227917 +3863 3839 -9211261.686427 +3930 3839 86719444.4302 +3931 3839 1.415610313416e-06 +3932 3839 -121047307.7997 +3933 3839 21679861.11823 +3934 3839 17343750.0057 +3935 3839 -38039431.35476 +3948 3839 3.02791595459e-05 +3949 3839 4.619359970093e-06 +3950 3839 -289746007.2349 +3951 3839 8.165836334229e-06 +3952 3839 69374999.9886 +3953 3839 -103546919.3888 +3969 3839 -86719444.43019 +3970 3839 8.940696716309e-07 +3971 3839 -121047307.7997 +3972 3839 -21679861.11823 +3973 3839 17343750.0057 +3974 3839 -38039431.35476 +3840 3840 1137565312.076 +3841 3840 4.64916229248e-06 +3842 3840 4571797.773345 +3843 3840 153072235.6709 +3844 3840 -3.814697265625e-06 +3845 3840 1142949.443904 +3858 3840 -88449163.50764 +3859 3840 -63656944.434 +3860 3840 12115157.22023 +3861 3840 -223854518.1091 +3862 3840 1.281499862671e-06 +3863 3840 -3314544.719882 +3864 3840 -89126355.34779 +3865 3840 63656944.434 +3866 3840 -13600988.60888 +3930 3840 -36072082.53399 +3931 3840 16203472.22755 +3932 3840 21679861.11823 +3933 3840 -113177912.5205 +3934 3840 -1.952052116394e-06 +3935 3840 86719444.4302 +3936 3840 -36072082.53399 +3937 3840 -16203472.22755 +3938 3840 21679861.11823 +3948 3840 -14659514.18418 +3949 3840 7.62939453125e-06 +3950 3840 7.152557373047e-06 +3951 3840 65803613.40852 +3952 3840 4.112720489502e-06 +3953 3840 3.081560134888e-05 +3954 3840 -14659514.18418 +3955 3840 -1.010298728943e-05 +3956 3840 8.165836334229e-06 +3969 3840 -36072082.53397 +3970 3840 -16203472.22754 +3971 3840 -21679861.11823 +3972 3840 -113177912.5204 +3973 3840 6.407499313354e-07 +3974 3840 -86719444.43019 +3975 3840 -36072082.53397 +3976 3840 16203472.22755 +3977 3840 -21679861.11823 +3841 3841 984782929.6775 +3842 3841 -54860648.90923 +3843 3841 -3.695487976074e-06 +3844 3841 -88823909.23288 +3845 3841 28253241.12114 +3858 3841 -63656944.434 +3859 3841 -69351365.69847 +3860 3841 6034664.450365 +3861 3841 2.622604370117e-06 +3862 3841 56237222.37539 +3863 3841 -13715162.23406 +3864 3841 63656944.434 +3865 3841 -70028557.53863 +3866 3841 7680497.783698 +3930 3841 16203472.22755 +3931 3841 -31210863.52938 +3932 3841 -17343750.00569 +3933 3841 -4.097819328308e-06 +3934 3841 -41882340.60423 +3935 3841 1.296401023865e-06 +3936 3841 -16203472.22755 +3937 3841 -31210863.52938 +3938 3841 17343750.0057 +3948 3841 8.970499038696e-06 +3949 3841 -76232648.10075 +3950 3841 -69374999.9886 +3951 3841 4.053115844727e-06 +3952 3841 26913861.39084 +3953 3841 4.738569259644e-06 +3954 3841 -7.331371307373e-06 +3955 3841 -76232648.10076 +3956 3841 69374999.9886 +3969 3841 -16203472.22754 +3970 3841 -31210863.52937 +3971 3841 -17343750.0057 +3972 3841 -1.177191734314e-06 +3973 3841 -41882340.60421 +3974 3841 8.344650268555e-07 +3975 3841 16203472.22754 +3976 3841 -31210863.52937 +3977 3841 17343750.0057 +3842 3842 1205835345.84 +3843 3842 1142949.443904 +3844 3842 26607407.78808 +3845 3842 154975139.2593 +3858 3842 12458039.16496 +3859 3842 6308970.006146 +3860 3842 -7405416.779322 +3861 3842 -1257253.053552 +3862 3842 -13715162.23407 +3863 3842 113190145.6041 +3864 3842 -13258106.66415 +3865 3842 7406192.227917 +3866 3842 -9211261.686427 +3930 3842 21679861.11823 +3931 3842 -17343750.00569 +3932 3842 -38039431.35476 +3933 3842 86719444.4302 +3934 3842 1.415610313416e-06 +3935 3842 -121047307.7997 +3936 3842 21679861.11823 +3937 3842 17343750.0057 +3938 3842 -38039431.35476 +3948 3842 7.182359695435e-06 +3949 3842 -69374999.9886 +3950 3842 -103546919.3888 +3951 3842 3.02791595459e-05 +3952 3842 4.619359970093e-06 +3953 3842 -289746007.2349 +3954 3842 8.165836334229e-06 +3955 3842 69374999.9886 +3956 3842 -103546919.3888 +3969 3842 -21679861.11823 +3970 3842 -17343750.0057 +3971 3842 -38039431.35476 +3972 3842 -86719444.43019 +3973 3842 8.940696716309e-07 +3974 3842 -121047307.7997 +3975 3842 -21679861.11823 +3976 3842 17343750.0057 +3977 3842 -38039431.35476 +3843 3843 1137565312.076 +3844 3843 4.64916229248e-06 +3845 3843 4571797.773345 +3846 3843 153072235.6709 +3847 3843 -3.814697265625e-06 +3848 3843 1142949.443904 +3861 3843 -88449163.50764 +3862 3843 -63656944.434 +3863 3843 12115157.22023 +3864 3843 -223854518.1091 +3865 3843 1.281499862671e-06 +3866 3843 -3314544.719882 +3867 3843 -89126355.34779 +3868 3843 63656944.434 +3869 3843 -13600988.60888 +3933 3843 -36072082.53399 +3934 3843 16203472.22755 +3935 3843 21679861.11823 +3936 3843 -113177912.5205 +3937 3843 -1.952052116394e-06 +3938 3843 86719444.4302 +3939 3843 -36072082.53399 +3940 3843 -16203472.22755 +3941 3843 21679861.11823 +3951 3843 -14659514.18418 +3952 3843 7.62939453125e-06 +3953 3843 7.152557373047e-06 +3954 3843 65803613.40852 +3955 3843 4.112720489502e-06 +3956 3843 3.081560134888e-05 +3957 3843 -14659514.18418 +3958 3843 -1.010298728943e-05 +3959 3843 8.165836334229e-06 +3972 3843 -36072082.53397 +3973 3843 -16203472.22754 +3974 3843 -21679861.11823 +3975 3843 -113177912.5204 +3976 3843 6.407499313354e-07 +3977 3843 -86719444.43019 +3978 3843 -36072082.53397 +3979 3843 16203472.22755 +3980 3843 -21679861.11823 +3844 3844 984782929.6775 +3845 3844 -54860648.90923 +3846 3844 -3.695487976074e-06 +3847 3844 -88823909.23288 +3848 3844 28253241.12114 +3861 3844 -63656944.434 +3862 3844 -69351365.69847 +3863 3844 6034664.450365 +3864 3844 2.622604370117e-06 +3865 3844 56237222.37539 +3866 3844 -13715162.23406 +3867 3844 63656944.434 +3868 3844 -70028557.53863 +3869 3844 7680497.783698 +3933 3844 16203472.22755 +3934 3844 -31210863.52938 +3935 3844 -17343750.00569 +3936 3844 -4.097819328308e-06 +3937 3844 -41882340.60423 +3938 3844 1.296401023865e-06 +3939 3844 -16203472.22755 +3940 3844 -31210863.52938 +3941 3844 17343750.0057 +3951 3844 8.970499038696e-06 +3952 3844 -76232648.10075 +3953 3844 -69374999.9886 +3954 3844 4.053115844727e-06 +3955 3844 26913861.39084 +3956 3844 4.738569259644e-06 +3957 3844 -7.331371307373e-06 +3958 3844 -76232648.10076 +3959 3844 69374999.9886 +3972 3844 -16203472.22754 +3973 3844 -31210863.52937 +3974 3844 -17343750.0057 +3975 3844 -1.177191734314e-06 +3976 3844 -41882340.60421 +3977 3844 8.344650268555e-07 +3978 3844 16203472.22754 +3979 3844 -31210863.52937 +3980 3844 17343750.0057 +3845 3845 1205835345.84 +3846 3845 1142949.443904 +3847 3845 26607407.78808 +3848 3845 154975139.2593 +3861 3845 12458039.16496 +3862 3845 6308970.006146 +3863 3845 -7405416.779322 +3864 3845 -1257253.053552 +3865 3845 -13715162.23407 +3866 3845 113190145.6041 +3867 3845 -13258106.66415 +3868 3845 7406192.227917 +3869 3845 -9211261.686427 +3933 3845 21679861.11823 +3934 3845 -17343750.00569 +3935 3845 -38039431.35476 +3936 3845 86719444.4302 +3937 3845 1.415610313416e-06 +3938 3845 -121047307.7997 +3939 3845 21679861.11823 +3940 3845 17343750.0057 +3941 3845 -38039431.35476 +3951 3845 7.182359695435e-06 +3952 3845 -69374999.9886 +3953 3845 -103546919.3888 +3954 3845 3.02791595459e-05 +3955 3845 4.619359970093e-06 +3956 3845 -289746007.2349 +3957 3845 8.165836334229e-06 +3958 3845 69374999.9886 +3959 3845 -103546919.3888 +3972 3845 -21679861.11823 +3973 3845 -17343750.0057 +3974 3845 -38039431.35476 +3975 3845 -86719444.43019 +3976 3845 8.940696716309e-07 +3977 3845 -121047307.7997 +3978 3845 -21679861.11823 +3979 3845 17343750.0057 +3980 3845 -38039431.35476 +3846 3846 1137565312.076 +3847 3846 4.64916229248e-06 +3848 3846 4571797.773345 +3849 3846 153072235.6709 +3850 3846 -3.814697265625e-06 +3851 3846 1142949.443904 +3864 3846 -88449163.50764 +3865 3846 -63656944.434 +3866 3846 12115157.22023 +3867 3846 -223854518.1091 +3868 3846 1.281499862671e-06 +3869 3846 -3314544.719882 +3870 3846 -89126355.34779 +3871 3846 63656944.434 +3872 3846 -13600988.60888 +3936 3846 -36072082.53399 +3937 3846 16203472.22755 +3938 3846 21679861.11823 +3939 3846 -113177912.5205 +3940 3846 -1.952052116394e-06 +3941 3846 86719444.4302 +3942 3846 -36072082.53399 +3943 3846 -16203472.22755 +3944 3846 21679861.11823 +3954 3846 -14659514.18418 +3955 3846 7.62939453125e-06 +3956 3846 7.152557373047e-06 +3957 3846 65803613.40852 +3958 3846 4.112720489502e-06 +3959 3846 3.081560134888e-05 +3960 3846 -14659514.18418 +3961 3846 -1.010298728943e-05 +3962 3846 8.165836334229e-06 +3975 3846 -36072082.53397 +3976 3846 -16203472.22754 +3977 3846 -21679861.11823 +3978 3846 -113177912.5204 +3979 3846 6.407499313354e-07 +3980 3846 -86719444.43019 +3981 3846 -36072082.53397 +3982 3846 16203472.22755 +3983 3846 -21679861.11823 +3847 3847 984782929.6775 +3848 3847 -54860648.90923 +3849 3847 -3.695487976074e-06 +3850 3847 -88823909.23288 +3851 3847 28253241.12114 +3864 3847 -63656944.434 +3865 3847 -69351365.69847 +3866 3847 6034664.450365 +3867 3847 2.622604370117e-06 +3868 3847 56237222.37539 +3869 3847 -13715162.23406 +3870 3847 63656944.434 +3871 3847 -70028557.53863 +3872 3847 7680497.783698 +3936 3847 16203472.22755 +3937 3847 -31210863.52938 +3938 3847 -17343750.00569 +3939 3847 -4.097819328308e-06 +3940 3847 -41882340.60423 +3941 3847 1.296401023865e-06 +3942 3847 -16203472.22755 +3943 3847 -31210863.52938 +3944 3847 17343750.0057 +3954 3847 8.970499038696e-06 +3955 3847 -76232648.10075 +3956 3847 -69374999.9886 +3957 3847 4.053115844727e-06 +3958 3847 26913861.39084 +3959 3847 4.738569259644e-06 +3960 3847 -7.331371307373e-06 +3961 3847 -76232648.10076 +3962 3847 69374999.9886 +3975 3847 -16203472.22754 +3976 3847 -31210863.52937 +3977 3847 -17343750.0057 +3978 3847 -1.177191734314e-06 +3979 3847 -41882340.60421 +3980 3847 8.344650268555e-07 +3981 3847 16203472.22754 +3982 3847 -31210863.52937 +3983 3847 17343750.0057 +3848 3848 1205835345.84 +3849 3848 1142949.443904 +3850 3848 26607407.78808 +3851 3848 154975139.2593 +3864 3848 12458039.16496 +3865 3848 6308970.006146 +3866 3848 -7405416.779322 +3867 3848 -1257253.053552 +3868 3848 -13715162.23407 +3869 3848 113190145.6041 +3870 3848 -13258106.66415 +3871 3848 7406192.227917 +3872 3848 -9211261.686427 +3936 3848 21679861.11823 +3937 3848 -17343750.00569 +3938 3848 -38039431.35476 +3939 3848 86719444.4302 +3940 3848 1.415610313416e-06 +3941 3848 -121047307.7997 +3942 3848 21679861.11823 +3943 3848 17343750.0057 +3944 3848 -38039431.35476 +3954 3848 7.182359695435e-06 +3955 3848 -69374999.9886 +3956 3848 -103546919.3888 +3957 3848 3.02791595459e-05 +3958 3848 4.619359970093e-06 +3959 3848 -289746007.2349 +3960 3848 8.165836334229e-06 +3961 3848 69374999.9886 +3962 3848 -103546919.3888 +3975 3848 -21679861.11823 +3976 3848 -17343750.0057 +3977 3848 -38039431.35476 +3978 3848 -86719444.43019 +3979 3848 8.940696716309e-07 +3980 3848 -121047307.7997 +3981 3848 -21679861.11823 +3982 3848 17343750.0057 +3983 3848 -38039431.35476 +3849 3849 1137565312.076 +3850 3849 4.64916229248e-06 +3851 3849 4571797.773345 +3852 3849 153072235.6709 +3853 3849 -3.814697265625e-06 +3854 3849 1142949.443904 +3867 3849 -88449163.50764 +3868 3849 -63656944.434 +3869 3849 12115157.22023 +3870 3849 -223854518.1091 +3871 3849 1.281499862671e-06 +3872 3849 -3314544.719882 +3873 3849 -89126355.34779 +3874 3849 63656944.434 +3875 3849 -13600988.60888 +3939 3849 -36072082.53399 +3940 3849 16203472.22755 +3941 3849 21679861.11823 +3942 3849 -113177912.5205 +3943 3849 -1.952052116394e-06 +3944 3849 86719444.4302 +3945 3849 -36072082.53399 +3946 3849 -16203472.22755 +3947 3849 21679861.11823 +3957 3849 -14659514.18418 +3958 3849 7.62939453125e-06 +3959 3849 7.152557373047e-06 +3960 3849 65803613.40852 +3961 3849 4.112720489502e-06 +3962 3849 3.081560134888e-05 +3963 3849 -14659514.18418 +3964 3849 -1.010298728943e-05 +3965 3849 8.165836334229e-06 +3978 3849 -36072082.53397 +3979 3849 -16203472.22754 +3980 3849 -21679861.11823 +3981 3849 -113177912.5204 +3982 3849 6.407499313354e-07 +3983 3849 -86719444.43019 +3984 3849 -36072082.53397 +3985 3849 16203472.22755 +3986 3849 -21679861.11823 +3850 3850 984782929.6775 +3851 3850 -54860648.90923 +3852 3850 -3.695487976074e-06 +3853 3850 -88823909.23288 +3854 3850 28253241.12114 +3867 3850 -63656944.434 +3868 3850 -69351365.69847 +3869 3850 6034664.450365 +3870 3850 2.622604370117e-06 +3871 3850 56237222.37539 +3872 3850 -13715162.23406 +3873 3850 63656944.434 +3874 3850 -70028557.53863 +3875 3850 7680497.783698 +3939 3850 16203472.22755 +3940 3850 -31210863.52938 +3941 3850 -17343750.00569 +3942 3850 -4.097819328308e-06 +3943 3850 -41882340.60423 +3944 3850 1.296401023865e-06 +3945 3850 -16203472.22755 +3946 3850 -31210863.52938 +3947 3850 17343750.0057 +3957 3850 8.970499038696e-06 +3958 3850 -76232648.10075 +3959 3850 -69374999.9886 +3960 3850 4.053115844727e-06 +3961 3850 26913861.39084 +3962 3850 4.738569259644e-06 +3963 3850 -7.331371307373e-06 +3964 3850 -76232648.10076 +3965 3850 69374999.9886 +3978 3850 -16203472.22754 +3979 3850 -31210863.52937 +3980 3850 -17343750.0057 +3981 3850 -1.177191734314e-06 +3982 3850 -41882340.60421 +3983 3850 8.344650268555e-07 +3984 3850 16203472.22754 +3985 3850 -31210863.52937 +3986 3850 17343750.0057 +3851 3851 1205835345.84 +3852 3851 1142949.443904 +3853 3851 26607407.78808 +3854 3851 154975139.2593 +3867 3851 12458039.16496 +3868 3851 6308970.006146 +3869 3851 -7405416.779322 +3870 3851 -1257253.053552 +3871 3851 -13715162.23407 +3872 3851 113190145.6041 +3873 3851 -13258106.66415 +3874 3851 7406192.227917 +3875 3851 -9211261.686427 +3939 3851 21679861.11823 +3940 3851 -17343750.00569 +3941 3851 -38039431.35476 +3942 3851 86719444.4302 +3943 3851 1.415610313416e-06 +3944 3851 -121047307.7997 +3945 3851 21679861.11823 +3946 3851 17343750.0057 +3947 3851 -38039431.35476 +3957 3851 7.182359695435e-06 +3958 3851 -69374999.9886 +3959 3851 -103546919.3888 +3960 3851 3.02791595459e-05 +3961 3851 4.619359970093e-06 +3962 3851 -289746007.2349 +3963 3851 8.165836334229e-06 +3964 3851 69374999.9886 +3965 3851 -103546919.3888 +3978 3851 -21679861.11823 +3979 3851 -17343750.0057 +3980 3851 -38039431.35476 +3981 3851 -86719444.43019 +3982 3851 8.940696716309e-07 +3983 3851 -121047307.7997 +3984 3851 -21679861.11823 +3985 3851 17343750.0057 +3986 3851 -38039431.35476 +3852 3852 1269720907.856 +3853 3852 68143803.88653 +3854 3852 4472085.757898 +3855 3852 56630151.75876 +3856 3852 -61493522.07384 +3857 3852 2066539.235759 +3870 3852 -88449163.50764 +3871 3852 -63656944.434 +3872 3852 12115157.22023 +3873 3852 -221842316.0237 +3874 3852 -2192752.606858 +3875 3852 -488260.9777767 +3876 3852 -92167492.31837 +3877 3852 63588271.09756 +3878 3852 -2394222.752949 +3942 3852 -36072082.53399 +3943 3852 16203472.22755 +3944 3852 21679861.11823 +3945 3852 -139005882.4838 +3946 3852 -17468607.99017 +3947 3852 88411110.90689 +3960 3852 -14659514.18418 +3961 3852 7.62939453125e-06 +3962 3852 7.152557373047e-06 +3963 3852 104468568.107 +3964 3852 17495749.11933 +3965 3852 0.03796535730362 +3966 3852 -35762896.95689 +3967 3852 -15573449.9111 +3968 3852 21679166.28526 +3981 3852 -36072082.53397 +3982 3852 -16203472.22754 +3983 3852 -21679861.11823 +3984 3852 -114724288.833 +3985 3852 -635253.1045092 +3986 3852 -87564583.31886 +3987 3852 -37742508.83701 +3988 3852 16181561.88645 +3989 3852 -22525694.45184 +3853 3853 1086127371.027 +3854 3853 -27673448.94957 +3855 3853 -61499978.14322 +3856 3853 -166059630.2496 +3857 3853 4422580.871377 +3870 3853 -63656944.434 +3871 3853 -69351365.69847 +3872 3853 6034664.450365 +3873 3853 -2192752.606858 +3874 3853 60350350.0081 +3875 3853 -7394473.435481 +3876 3853 63588271.09756 +3877 3853 -65568525.14848 +3878 3853 1374962.965883 +3942 3853 16203472.22755 +3943 3853 -31210863.52938 +3944 3853 -17343750.00569 +3945 3853 -17468608.05499 +3946 3853 -62280769.57 +3947 3853 18697916.60118 +3960 3853 8.970499038696e-06 +3961 3853 -76232648.10075 +3962 3853 -69374999.9886 +3963 3853 17495749.11933 +3964 3853 57330719.05929 +3965 3853 0.0303530395031 +3966 3853 -15573449.84629 +3967 3853 -92437084.05277 +3968 3853 69374999.59698 +3981 3853 -16203472.22754 +3982 3853 -31210863.52937 +3983 3853 -17343750.0057 +3984 3853 -635253.1045111 +3985 3853 -42821513.04608 +3986 3853 -677083.3331571 +3987 3853 16181561.88645 +3988 3853 -30707665.48679 +3989 3853 16666666.67214 +3854 3854 1294220130.987 +3855 3854 2071591.406919 +3856 3854 4430099.551854 +3857 3854 113359280.4676 +3870 3854 12458039.16496 +3871 3854 6308970.006146 +3872 3854 -7405416.779322 +3873 3854 -3231316.532882 +3874 3854 -7394473.435481 +3875 3854 129130465.5522 +3876 3854 -2394222.752611 +3877 3854 1374962.965883 +3878 3854 -3084530.879807 +3942 3854 21679861.11823 +3943 3854 -17343750.00569 +3944 3854 -38039431.35476 +3945 3854 88411110.90689 +3946 3854 18697916.56855 +3947 3854 -124962011.2801 +3960 3854 7.182359695435e-06 +3961 3854 -69374999.9886 +3962 3854 -103546919.3888 +3963 3854 -0.03791534900665 +3964 3854 -0.03035178780556 +3965 3854 -255055797.837 +3966 3854 21679166.091 +3967 3854 69374999.4742 +3968 3854 -105412602.9399 +3981 3854 -21679861.11823 +3982 3854 -17343750.0057 +3983 3854 -38039431.35476 +3984 3854 -87564583.31903 +3985 3854 -677083.3332905 +3986 3854 -122108417.4801 +3987 3854 -22525694.45184 +3988 3854 16666666.67214 +3989 3854 -38357223.71349 +3855 3855 690428323.8106 +3856 3855 -1526145.223039 +3857 3855 294203.4919279 +3873 3855 -85206561.85399 +3874 3855 -63648145.55862 +3875 3855 1907505.069545 +3876 3855 -233498878.8511 +3877 3855 -2953519.016915 +3878 3855 -246183.6404445 +3879 3855 75671100.45934 +3880 3855 -11197009.81833 +3881 3855 -101111.1356556 +3882 3855 -91977007.54163 +3883 3855 64417096.23118 +3884 3855 -482029.2342617 +3945 3855 -13882071.21844 +3946 3855 19444166.47861 +3947 3855 27030832.75893 +3963 3855 -35762896.9569 +3964 3855 -15573449.84628 +3965 3855 -21679166.091 +3966 3855 24359103.43621 +3967 3855 -442912.9657402 +3968 3855 17135277.77496 +3984 3855 -35736813.43153 +3985 3855 -16200678.02492 +3986 3855 -21679166.67379 +3987 3855 -113692433.8764 +3988 3855 -855995.94238 +3989 3855 -85676388.87482 +3990 3855 -6375113.374563 +3991 3855 -2795132.258683 +3992 3855 3215972.223778 +3993 3855 -36573838.1928 +3994 3855 16424002.55938 +3995 3855 -21159027.78473 +3856 3856 709101692.0832 +3857 3856 -4623228.324144 +3873 3856 -63648145.55862 +3874 3856 -67612861.43276 +3875 3856 781772.525224 +3876 3856 -2953519.016915 +3877 3856 48917447.31709 +3878 3856 -1417705.220885 +3879 3856 14265767.95527 +3880 3856 -45017324.84969 +3881 3856 232055.2517371 +3882 3856 64417096.23118 +3883 3856 -70658219.55288 +3884 3856 229699.3659164 +3945 3856 12962777.65241 +3946 3856 -12907974.64577 +3947 3856 -13062499.95656 +3963 3856 -15573449.9111 +3964 3856 -92437084.05279 +3965 3856 -69374999.4742 +3966 3856 -442912.9657424 +3967 3856 28707972.02069 +3968 3856 7208333.185864 +3984 3856 -16200678.02492 +3985 3856 -31311329.22223 +3986 3856 -17343750.0057 +3987 3856 -855995.9423803 +3988 3856 -41658168.45665 +3989 3856 -677083.3331592 +3990 3856 3686256.632335 +3991 3856 -37070043.77932 +3992 3856 33333333.32785 +3993 3856 16424002.55938 +3994 3856 -30987435.47836 +3995 3856 16666666.67214 +3857 3857 813645978.3204 +3873 3857 1907505.069714 +3874 3857 781772.5253592 +3875 3857 -1613944.686177 +3876 3857 -246183.6404451 +3877 3857 -1417705.220885 +3878 3857 102943642.7192 +3879 3857 -101111.1356529 +3880 3857 232055.2517369 +3881 3857 81331741.41331 +3882 3857 -482029.2340931 +3883 3857 229699.3659164 +3884 3857 -7498333.015678 +3945 3857 18020555.17262 +3946 3857 -20270833.25379 +3947 3857 -37992953.15517 +3963 3857 -21679166.28526 +3964 3857 -69374999.59698 +3965 3857 -105412602.9399 +3966 3857 -17135277.77496 +3967 3857 -7208333.185869 +3968 3857 -197305370.7383 +3984 3857 -21679166.67379 +3985 3857 -17343750.0057 +3986 3857 -37974851.43985 +3987 3857 -85676388.87482 +3988 3857 -677083.3332927 +3989 3857 -117555867.1805 +3990 3857 -4909027.779056 +3991 3857 33333333.32785 +3992 3857 -47673130.40164 +3993 3857 -21159027.78473 +3994 3857 16666666.67214 +3995 3857 -36522727.11636 +3858 3858 570930829.7064 +3859 3858 -1.072883605957e-06 +3860 3858 -2857330.279152 +3861 3858 77084447.78357 +3862 3858 12731388.8868 +3863 3858 -2857344.722774 +3948 3858 -113177912.5205 +3949 3858 -1.952052116394e-06 +3950 3858 86719444.4302 +3951 3858 -36072082.53399 +3952 3858 -16203472.22755 +3953 3858 21679861.11823 +3969 3858 32901806.70425 +3970 3858 2.026557922363e-06 +3971 3858 -17343888.88602 +3972 3858 -7329757.09209 +3973 3858 3240694.445505 +3974 3858 -4335972.223642 +3859 3859 494539638.5074 +3860 3859 -27430324.4546 +3861 3859 -12731388.8868 +3862 3859 -43863624.66835 +3863 3859 13989467.78282 +3948 3859 -4.097819328308e-06 +3949 3859 -41882340.60423 +3950 3859 1.296401023865e-06 +3951 3859 -16203472.22755 +3952 3859 -31210863.52938 +3953 3859 17343750.0057 +3969 3859 1.430511474609e-06 +3970 3859 13456930.69541 +3971 3859 -4.410743713379e-06 +3972 3859 -3240694.445512 +3973 3859 -38116324.05037 +3974 3859 34687499.9943 +3860 3860 608646136.0366 +3861 3860 2285884.443047 +3862 3860 13440856.6718 +3863 3860 78949782.82454 +3948 3860 86719444.4302 +3949 3860 1.415610313416e-06 +3950 3860 -121047307.7997 +3951 3860 21679861.11823 +3952 3860 17343750.0057 +3953 3860 -38039431.35476 +3969 3860 17343888.88605 +3970 3860 -4.410743713379e-06 +3971 3860 -144873003.6175 +3972 3860 4335972.22365 +3973 3860 34687499.9943 +3974 3860 -51773459.69442 +3861 3861 570930829.7064 +3862 3861 -1.072883605957e-06 +3863 3861 -2857330.279152 +3864 3861 77084447.78357 +3865 3861 12731388.8868 +3866 3861 -2857344.722774 +3948 3861 -36072082.53399 +3949 3861 16203472.22755 +3950 3861 21679861.11823 +3951 3861 -113177912.5205 +3952 3861 -1.952052116394e-06 +3953 3861 86719444.4302 +3954 3861 -36072082.53399 +3955 3861 -16203472.22755 +3956 3861 21679861.11823 +3969 3861 -7329757.092094 +3970 3861 -3240694.445505 +3971 3861 -4335972.223642 +3972 3861 32901806.70425 +3973 3861 2.026557922363e-06 +3974 3861 -17343888.88602 +3975 3861 -7329757.09209 +3976 3861 3240694.445505 +3977 3861 -4335972.223642 +3862 3862 494539638.5074 +3863 3862 -27430324.4546 +3864 3862 -12731388.8868 +3865 3862 -43863624.66835 +3866 3862 13989467.78282 +3948 3862 16203472.22755 +3949 3862 -31210863.52938 +3950 3862 -17343750.00569 +3951 3862 -4.097819328308e-06 +3952 3862 -41882340.60423 +3953 3862 1.296401023865e-06 +3954 3862 -16203472.22755 +3955 3862 -31210863.52938 +3956 3862 17343750.0057 +3969 3862 3240694.445514 +3970 3862 -38116324.05038 +3971 3862 -34687499.9943 +3972 3862 1.430511474609e-06 +3973 3862 13456930.69541 +3974 3862 -4.410743713379e-06 +3975 3862 -3240694.445512 +3976 3862 -38116324.05037 +3977 3862 34687499.9943 +3863 3863 608646136.0366 +3864 3863 2285884.443047 +3865 3863 13440856.6718 +3866 3863 78949782.82454 +3948 3863 21679861.11823 +3949 3863 -17343750.00569 +3950 3863 -38039431.35476 +3951 3863 86719444.4302 +3952 3863 1.415610313416e-06 +3953 3863 -121047307.7997 +3954 3863 21679861.11823 +3955 3863 17343750.0057 +3956 3863 -38039431.35476 +3969 3863 4335972.22365 +3970 3863 -34687499.9943 +3971 3863 -51773459.69442 +3972 3863 17343888.88605 +3973 3863 -4.410743713379e-06 +3974 3863 -144873003.6175 +3975 3863 4335972.22365 +3976 3863 34687499.9943 +3977 3863 -51773459.69442 +3864 3864 570930829.7064 +3865 3864 -1.072883605957e-06 +3866 3864 -2857330.279152 +3867 3864 77084447.78357 +3868 3864 12731388.8868 +3869 3864 -2857344.722774 +3951 3864 -36072082.53399 +3952 3864 16203472.22755 +3953 3864 21679861.11823 +3954 3864 -113177912.5205 +3955 3864 -1.952052116394e-06 +3956 3864 86719444.4302 +3957 3864 -36072082.53399 +3958 3864 -16203472.22755 +3959 3864 21679861.11823 +3972 3864 -7329757.092094 +3973 3864 -3240694.445505 +3974 3864 -4335972.223642 +3975 3864 32901806.70425 +3976 3864 2.026557922363e-06 +3977 3864 -17343888.88602 +3978 3864 -7329757.09209 +3979 3864 3240694.445505 +3980 3864 -4335972.223642 +3865 3865 494539638.5074 +3866 3865 -27430324.4546 +3867 3865 -12731388.8868 +3868 3865 -43863624.66835 +3869 3865 13989467.78282 +3951 3865 16203472.22755 +3952 3865 -31210863.52938 +3953 3865 -17343750.00569 +3954 3865 -4.097819328308e-06 +3955 3865 -41882340.60423 +3956 3865 1.296401023865e-06 +3957 3865 -16203472.22755 +3958 3865 -31210863.52938 +3959 3865 17343750.0057 +3972 3865 3240694.445514 +3973 3865 -38116324.05038 +3974 3865 -34687499.9943 +3975 3865 1.430511474609e-06 +3976 3865 13456930.69541 +3977 3865 -4.410743713379e-06 +3978 3865 -3240694.445512 +3979 3865 -38116324.05037 +3980 3865 34687499.9943 +3866 3866 608646136.0366 +3867 3866 2285884.443047 +3868 3866 13440856.6718 +3869 3866 78949782.82454 +3951 3866 21679861.11823 +3952 3866 -17343750.00569 +3953 3866 -38039431.35476 +3954 3866 86719444.4302 +3955 3866 1.415610313416e-06 +3956 3866 -121047307.7997 +3957 3866 21679861.11823 +3958 3866 17343750.0057 +3959 3866 -38039431.35476 +3972 3866 4335972.22365 +3973 3866 -34687499.9943 +3974 3866 -51773459.69442 +3975 3866 17343888.88605 +3976 3866 -4.410743713379e-06 +3977 3866 -144873003.6175 +3978 3866 4335972.22365 +3979 3866 34687499.9943 +3980 3866 -51773459.69442 +3867 3867 570930829.7064 +3868 3867 -1.072883605957e-06 +3869 3867 -2857330.279152 +3870 3867 77084447.78357 +3871 3867 12731388.8868 +3872 3867 -2857344.722774 +3954 3867 -36072082.53399 +3955 3867 16203472.22755 +3956 3867 21679861.11823 +3957 3867 -113177912.5205 +3958 3867 -1.952052116394e-06 +3959 3867 86719444.4302 +3960 3867 -36072082.53399 +3961 3867 -16203472.22755 +3962 3867 21679861.11823 +3975 3867 -7329757.092094 +3976 3867 -3240694.445505 +3977 3867 -4335972.223642 +3978 3867 32901806.70425 +3979 3867 2.026557922363e-06 +3980 3867 -17343888.88602 +3981 3867 -7329757.09209 +3982 3867 3240694.445505 +3983 3867 -4335972.223642 +3868 3868 494539638.5074 +3869 3868 -27430324.4546 +3870 3868 -12731388.8868 +3871 3868 -43863624.66835 +3872 3868 13989467.78282 +3954 3868 16203472.22755 +3955 3868 -31210863.52938 +3956 3868 -17343750.00569 +3957 3868 -4.097819328308e-06 +3958 3868 -41882340.60423 +3959 3868 1.296401023865e-06 +3960 3868 -16203472.22755 +3961 3868 -31210863.52938 +3962 3868 17343750.0057 +3975 3868 3240694.445514 +3976 3868 -38116324.05038 +3977 3868 -34687499.9943 +3978 3868 1.430511474609e-06 +3979 3868 13456930.69541 +3980 3868 -4.410743713379e-06 +3981 3868 -3240694.445512 +3982 3868 -38116324.05037 +3983 3868 34687499.9943 +3869 3869 608646136.0366 +3870 3869 2285884.443047 +3871 3869 13440856.6718 +3872 3869 78949782.82454 +3954 3869 21679861.11823 +3955 3869 -17343750.00569 +3956 3869 -38039431.35476 +3957 3869 86719444.4302 +3958 3869 1.415610313416e-06 +3959 3869 -121047307.7997 +3960 3869 21679861.11823 +3961 3869 17343750.0057 +3962 3869 -38039431.35476 +3975 3869 4335972.22365 +3976 3869 -34687499.9943 +3977 3869 -51773459.69442 +3978 3869 17343888.88605 +3979 3869 -4.410743713379e-06 +3980 3869 -144873003.6175 +3981 3869 4335972.22365 +3982 3869 34687499.9943 +3983 3869 -51773459.69442 +3870 3870 570930829.7064 +3871 3870 -1.072883605957e-06 +3872 3870 -2857330.279152 +3873 3870 77084447.78357 +3874 3870 12731388.8868 +3875 3870 -2857344.722774 +3957 3870 -36072082.53399 +3958 3870 16203472.22755 +3959 3870 21679861.11823 +3960 3870 -113177912.5205 +3961 3870 -1.952052116394e-06 +3962 3870 86719444.4302 +3963 3870 -36072082.53399 +3964 3870 -16203472.22755 +3965 3870 21679861.11823 +3978 3870 -7329757.092094 +3979 3870 -3240694.445505 +3980 3870 -4335972.223642 +3981 3870 32901806.70425 +3982 3870 2.026557922363e-06 +3983 3870 -17343888.88602 +3984 3870 -7329757.09209 +3985 3870 3240694.445505 +3986 3870 -4335972.223642 +3871 3871 494539638.5074 +3872 3871 -27430324.4546 +3873 3871 -12731388.8868 +3874 3871 -43863624.66835 +3875 3871 13989467.78282 +3957 3871 16203472.22755 +3958 3871 -31210863.52938 +3959 3871 -17343750.00569 +3960 3871 -4.097819328308e-06 +3961 3871 -41882340.60423 +3962 3871 1.296401023865e-06 +3963 3871 -16203472.22755 +3964 3871 -31210863.52938 +3965 3871 17343750.0057 +3978 3871 3240694.445514 +3979 3871 -38116324.05038 +3980 3871 -34687499.9943 +3981 3871 1.430511474609e-06 +3982 3871 13456930.69541 +3983 3871 -4.410743713379e-06 +3984 3871 -3240694.445512 +3985 3871 -38116324.05037 +3986 3871 34687499.9943 +3872 3872 608646136.0366 +3873 3872 2285884.443047 +3874 3872 13440856.6718 +3875 3872 78949782.82454 +3957 3872 21679861.11823 +3958 3872 -17343750.00569 +3959 3872 -38039431.35476 +3960 3872 86719444.4302 +3961 3872 1.415610313416e-06 +3962 3872 -121047307.7997 +3963 3872 21679861.11823 +3964 3872 17343750.0057 +3965 3872 -38039431.35476 +3978 3872 4335972.22365 +3979 3872 -34687499.9943 +3980 3872 -51773459.69442 +3981 3872 17343888.88605 +3982 3872 -4.410743713379e-06 +3983 3872 -144873003.6175 +3984 3872 4335972.22365 +3985 3872 34687499.9943 +3986 3872 -51773459.69442 +3873 3873 584777336.9746 +3874 3873 8233.997064114 +3875 3873 9050879.702598 +3876 3873 83891523.67113 +3877 3873 14907108.62122 +3878 3873 -183665.463271 +3960 3873 -36072082.53399 +3961 3873 16203472.22755 +3962 3873 21679861.11823 +3963 3873 -114724288.8331 +3964 3873 -635253.1045028 +3965 3873 87564583.31904 +3966 3873 -35736813.43153 +3967 3873 -16200678.02491 +3968 3873 21679166.67379 +3981 3873 -7329757.092094 +3982 3873 -3240694.445505 +3983 3873 -4335972.223642 +3984 3873 33236111.75388 +3985 3873 2649.269784987 +3986 3873 -17343611.10825 +3987 3873 -6450528.111146 +3988 3873 3870504.077598 +3989 3873 -5182361.112478 +3874 3874 506890648.9322 +3875 3874 -14990761.54941 +3876 3874 -10555669.15238 +3877 3874 -36157880.09678 +3878 3874 2402246.893188 +3960 3874 16203472.22755 +3961 3874 -31210863.52938 +3962 3874 -17343750.00569 +3963 3874 -635253.1045053 +3964 3874 -42821513.0461 +3965 3874 677083.3332872 +3966 3874 -16200678.02491 +3967 3874 -31311329.22222 +3968 3874 17343750.00569 +3981 3874 3240694.445514 +3982 3874 -38116324.05038 +3983 3874 -34687499.9943 +3984 3874 2649.269785047 +3985 3874 13357668.57743 +3986 3874 -8.702278137207e-06 +3987 3874 -2610884.813419 +3988 3874 -36974996.97727 +3989 3874 34010416.66101 +3875 3875 642732276.2337 +3876 3875 844980.3698907 +3877 3875 2402246.893187 +3878 3875 92220882.30562 +3960 3875 21679861.11823 +3961 3875 -17343750.00569 +3962 3875 -38039431.35476 +3963 3875 87564583.31887 +3964 3875 677083.3331538 +3965 3875 -122108417.4801 +3966 3875 21679166.67379 +3967 3875 17343750.00569 +3968 3875 -37974851.43984 +3981 3875 4335972.22365 +3982 3875 -34687499.9943 +3983 3875 -51773459.69442 +3984 3875 17343611.10827 +3985 3875 -8.702278137207e-06 +3986 3875 -144806554.3753 +3987 3875 3489305.557202 +3988 3875 34010416.66114 +3989 3875 -50836907.65005 +3876 3876 569990048.566 +3877 3876 -1419907.296957 +3878 3876 332759.6698096 +3879 3876 -82916439.46504 +3880 3876 -62896792.63683 +3881 3876 375175.6267792 +3882 3876 80126740.36145 +3883 3876 14237617.00553 +3884 3876 -284037.0516534 +3963 3876 -37742508.83701 +3964 3876 16181561.88645 +3965 3876 22525694.45184 +3966 3876 -113692433.8764 +3967 3876 -855995.9423645 +3968 3876 85676388.87482 +3984 3876 -6450528.111161 +3985 3876 -2610884.81342 +3986 3876 -3489305.557202 +3987 3876 37702548.37275 +3988 3876 -408992.820539 +3989 3876 -17135277.77496 +3990 3876 -33940233.84008 +3991 3876 -15982941.89571 +3992 3876 20312500.00667 +3993 3876 -5632342.894131 +3994 3876 3677253.585592 +3995 3876 -5078333.3345 +3877 3877 486720818.0868 +3878 3877 -3275946.215516 +3879 3877 -62896792.63683 +3880 3877 -67260506.52416 +3881 3877 229699.3659162 +3882 3877 -11225160.76807 +3883 3877 -41225851.67031 +3884 3877 686742.2114756 +3963 3877 16181561.88645 +3964 3877 -30707665.4868 +3965 3877 -16666666.67214 +3966 3877 -855995.9423657 +3967 3877 -41658168.45665 +3968 3877 677083.3332849 +3984 3877 3870504.077599 +3985 3877 -36974996.9773 +3986 3877 -34010416.66115 +3987 3877 -408992.820535 +3988 3877 16106902.49244 +3989 3877 -1.171231269836e-05 +3990 3877 -15982941.89571 +3991 3877 -29999833.84609 +3992 3877 16666666.67214 +3993 3877 -2804135.305426 +3994 3877 -36521736.91163 +3995 3877 33333333.32785 +3878 3878 594757336.3219 +3879 3878 375175.6267794 +3880 3878 229699.3659162 +3881 3878 -4100619.986957 +3882 3878 58844.89273202 +3883 3878 686742.2114754 +3884 3878 85064628.09103 +3963 3878 22525694.45184 +3964 3878 -16666666.67214 +3965 3878 -38357223.7135 +3966 3878 85676388.87482 +3967 3878 677083.3331515 +3968 3878 -117555867.1805 +3984 3878 5182361.112479 +3985 3878 -34010416.66102 +3986 3878 -50836907.65008 +3987 3878 17135277.77496 +3988 3878 -1.192092895508e-05 +3989 3878 -135669723.6375 +3990 3878 20312500.00667 +3991 3878 16666666.67214 +3992 3878 -35535125.48409 +3993 3878 3385277.779223 +3994 3878 33333333.32785 +3995 3878 -48059816.83043 +3879 3879 275798770.109 +3880 3879 62122565.36553 +3881 3879 -184623.8179488 +3882 3879 -113209643.2581 +3883 3879 -13491540.68398 +3884 3879 -89440.67317849 +3966 3879 -6375113.374575 +3967 3879 3686256.632336 +3968 3879 4909027.779057 +3987 3879 -33940233.84009 +3988 3879 -15982941.89571 +3989 3879 -20312500.00667 +3990 3879 18902645.55566 +3991 3879 15757910.04072 +3992 3879 8124999.998668 +3993 3879 -54847530.63036 +3994 3879 -3461224.777349 +3995 3879 -41471527.77105 +3880 3880 241323393.3602 +3881 3880 -232055.2517254 +3882 3880 11971237.08962 +3883 3880 26298225.85892 +3884 3880 -229699.3659078 +3966 3880 -2795132.258684 +3967 3880 -37070043.77934 +3968 3880 -33333333.32786 +3987 3880 -15982941.89571 +3988 3880 -29999833.8461 +3989 3880 -16666666.67214 +3990 3880 15757910.04072 +3991 3880 10101612.40577 +3992 3880 6666666.66557 +3993 3880 3020164.11367 +3994 3880 -19291967.06971 +3995 3880 3333333.334426 +3881 3881 286987305.8901 +3882 3881 -89440.67317563 +3883 3881 -229699.3659079 +3884 3881 50031673.60422 +3966 3881 -3215972.223779 +3967 3881 -33333333.32786 +3968 3881 -47673130.40167 +3987 3881 -20312500.00667 +3988 3881 -16666666.67214 +3989 3881 -35535125.48411 +3990 3881 -8124999.998663 +3991 3881 -6666666.665573 +3992 3881 -63738650.14914 +3993 3881 -41471527.77088 +3994 3881 -3333333.33443 +3995 3881 -56413713.40338 +3882 3882 282532125.9073 +3883 3882 -65163172.55273 +3884 3882 -173138.874578 +3966 3882 -36573838.19281 +3967 3882 16424002.55938 +3968 3882 21159027.78473 +3987 3882 -5632342.894148 +3988 3882 -2804135.305426 +3989 3882 -3385277.779223 +3990 3882 -54847530.63036 +3991 3882 3020164.113678 +3992 3882 41471527.77088 +3993 3882 19748607.35903 +3994 3882 -16640031.36763 +3995 3882 -8463611.109722 +3883 3883 243058060.8333 +3884 3883 -686742.2114532 +3966 3883 16424002.55938 +3967 3883 -30987435.47837 +3968 3883 -16666666.67214 +3987 3883 3677253.585593 +3988 3883 -36521736.91167 +3989 3883 -33333333.32786 +3990 3883 -3461224.777342 +3991 3883 -19291967.06971 +3992 3883 3333333.334426 +3993 3883 -16640031.36763 +3994 3883 9496035.10145 +3995 3883 6666666.665565 +3884 3884 292327939.2378 +3966 3884 21159027.78473 +3967 3884 -16666666.67214 +3968 3884 -36522727.11638 +3987 3884 5078333.334501 +3988 3884 -33333333.32786 +3989 3884 -48059816.83045 +3990 3884 41471527.77105 +3991 3884 -3333333.33443 +3992 3884 -56413713.40338 +3993 3884 8463611.10972 +3994 3884 -6666666.665577 +3995 3884 -65150687.6052 +3885 3885 721441645.4454 +3886 3885 64813888.87825 +3887 3885 -8.821487426758e-06 +3888 3885 -346380299.6592 +3889 3885 -64813888.35974 +3890 3885 -2.676248550415e-05 +3891 3885 27846630.32399 +3892 3885 51851110.58409 +3996 3885 41127258.27048 +3997 3885 16203472.22755 +3998 3885 17343888.84954 +3999 3885 -135326679.0276 +4000 3885 -16203472.09792 +4001 3885 -86719444.24762 +4002 3885 -13923315.162 +4003 3885 12962777.65241 +4004 3885 -17343888.52033 +3886 3886 624217266.0229 +3887 3886 -7.51187935966e-06 +3888 3886 -64813888.10048 +3889 3886 -41753137.74642 +3890 3886 -7.390975952148e-06 +3891 3886 77776665.87613 +3892 3886 27846630.32398 +3893 3886 6.794929504395e-06 +3996 3886 16203472.22755 +3997 3886 16821163.40287 +3998 3886 13874999.85144 +3999 3886 -16203472.0331 +4000 3886 -59169888.51194 +4001 3886 -17343749.90781 +4002 3886 19444166.47861 +4003 3886 -13923315.162 +4004 3886 20812499.90895 +3887 3887 760788621.1472 +3888 3887 -2.646446228027e-05 +3889 3887 -5.185604095459e-06 +3890 3887 31972185.12589 +3892 3887 4.708766937256e-06 +3893 3887 74257680.86397 +3996 3887 -17343888.84951 +3997 3887 -13874999.85143 +3998 3887 -181091253.0988 +3999 3887 -86719444.24762 +4000 3887 -17343749.94043 +4001 3887 -121957897.9018 +4002 3887 -26015832.7805 +4003 3887 13874999.9393 +4004 3887 -37128840.43199 +3888 3888 1242901705.056 +3889 3888 64813887.58197 +3890 3888 -3.838539123535e-05 +3891 3888 47693290.89467 +3892 3888 -64813888.35975 +3893 3888 -7.510185241699e-06 +3894 3888 -229938603.1375 +3895 3888 -1.400709152222e-06 +3896 3888 -1.621246337891e-05 +3897 3888 -88595068.35711 +3898 3888 64813888.87826 +3899 3888 -3.75509262085e-06 +3996 3888 -135326679.0277 +3997 3888 -16203472.0331 +3998 3888 86719444.24762 +3999 3888 101875695.1567 +4000 3888 16203471.90348 +4001 3888 0.03654569387436 +4002 3888 -36808280.87074 +4003 3888 -16203472.09792 +4004 3888 21679860.74398 +4005 3888 -113177912.5204 +4006 3888 6.407499313354e-07 +4007 3888 -86719444.43019 +4008 3888 -36072082.53397 +4009 3888 16203472.22755 +4010 3888 -21679861.11823 +3889 3889 1067897821.637 +3891 3889 -64813888.10049 +3892 3889 -179154367.6044 +3893 3889 -1.16229057312e-05 +3894 3889 7.748603820801e-07 +3895 3889 55243684.38681 +3896 3889 -1.788139343262e-06 +3897 3889 64813888.87826 +3898 3889 -69150192.34827 +3899 3889 -4.619359970093e-07 +3996 3889 -16203472.09792 +3997 3889 -59169888.51195 +3998 3889 17343749.94043 +3999 3889 16203471.90348 +4000 3889 58124724.28025 +4001 3889 0.029221534729 +4002 3889 -16203472.03311 +4003 3889 -93520195.52346 +4004 3889 69374999.6084 +4005 3889 -1.177191734314e-06 +4006 3889 -41882340.60421 +4007 3889 8.344650268555e-07 +4008 3889 16203472.22754 +4009 3889 -31210863.52937 +4010 3889 17343750.0057 +3890 3890 1220904161.253 +3891 3890 -7.390975952148e-06 +3892 3890 -9.536743164063e-06 +3893 3890 101973736.7139 +3894 3890 -1.54972076416e-05 +3895 3890 -1.907348632813e-06 +3896 3890 109872226.963 +3897 3890 -3.635883331299e-06 +3898 3890 -6.109476089478e-07 +3899 3890 -3642360.79014 +3996 3890 86719444.24762 +3997 3890 17343749.9078 +3998 3890 -121957897.9018 +3999 3890 -0.03648543357849 +4000 3890 -0.02920261025429 +4001 3890 -251706576.231 +4002 3890 21679860.55685 +4003 3890 69374999.49133 +4004 3890 -104457508.7431 +4005 3890 -86719444.43019 +4006 3890 8.940696716309e-07 +4007 3890 -121047307.7997 +4008 3890 -21679861.11823 +4009 3890 17343750.0057 +4010 3890 -38039431.35476 +3891 3891 721441645.4454 +3892 3891 64813888.87825 +3893 3891 -8.821487426758e-06 +3894 3891 -88595068.35711 +3895 3891 -64813888.87825 +3896 3891 -4.26173210144e-06 +3897 3891 -346380299.6592 +3898 3891 -64813888.35974 +3899 3891 -2.676248550415e-05 +3900 3891 27846630.32399 +3901 3891 51851110.58409 +3996 3891 -13923315.16199 +3997 3891 19444166.47861 +3998 3891 26015832.7805 +3999 3891 -36808280.87074 +4000 3891 -16203472.0331 +4001 3891 -21679860.55685 +4002 3891 41127258.27048 +4003 3891 16203472.22755 +4004 3891 17343888.84954 +4005 3891 -36072082.53397 +4006 3891 -16203472.22754 +4007 3891 -21679861.11823 +4008 3891 -135326679.0276 +4009 3891 -16203472.09792 +4010 3891 -86719444.24762 +4011 3891 -13923315.162 +4012 3891 12962777.65241 +4013 3891 -17343888.52033 +3892 3892 624217266.0229 +3893 3892 -7.273460780558e-06 +3894 3892 -64813888.87825 +3895 3892 -69150192.34827 +3896 3892 -6.705522537231e-07 +3897 3892 -64813888.10048 +3898 3892 -41753137.74642 +3899 3892 -7.390975952148e-06 +3900 3892 77776665.87613 +3901 3892 27846630.32398 +3902 3892 6.794929504395e-06 +3996 3892 12962777.65241 +3997 3892 -13923315.162 +3998 3892 -13874999.9393 +3999 3892 -16203472.09791 +4000 3892 -93520195.52345 +4001 3892 -69374999.49133 +4002 3892 16203472.22755 +4003 3892 16821163.40287 +4004 3892 13874999.85144 +4005 3892 -16203472.22754 +4006 3892 -31210863.52937 +4007 3892 -17343750.0057 +4008 3892 -16203472.0331 +4009 3892 -59169888.51194 +4010 3892 -17343749.90781 +4011 3892 19444166.47861 +4012 3892 -13923315.162 +4013 3892 20812499.90895 +3893 3893 760788621.1472 +3894 3893 -4.231929779053e-06 +3895 3893 -5.811452865601e-07 +3896 3893 -3642360.790142 +3897 3893 -2.646446228027e-05 +3898 3893 -5.185604095459e-06 +3899 3893 31972185.12589 +3901 3893 4.708766937256e-06 +3902 3893 74257680.86397 +3996 3893 17343888.52033 +3997 3893 -20812499.90894 +3998 3893 -37128840.43198 +3999 3893 -21679860.74397 +4000 3893 -69374999.6084 +4001 3893 -104457508.7431 +4002 3893 -17343888.84951 +4003 3893 -13874999.85143 +4004 3893 -181091253.0988 +4005 3893 -21679861.11823 +4006 3893 -17343750.0057 +4007 3893 -38039431.35476 +4008 3893 -86719444.24762 +4009 3893 -17343749.94043 +4010 3893 -121957897.9018 +4011 3893 -26015832.7805 +4012 3893 13874999.9393 +4013 3893 -37128840.43199 +3894 3894 1154306639.95 +3895 3894 4.053115844727e-06 +3896 3894 -5.984306335449e-05 +3897 3894 164134990.0133 +3898 3894 -4.798173904419e-06 +3899 3894 -1.537799835205e-05 +3903 3894 -229938603.1375 +3904 3894 -1.400709152222e-06 +3905 3894 -1.621246337891e-05 +3906 3894 -88595068.35711 +3907 3894 64813888.87826 +3908 3894 -3.75509262085e-06 +3999 3894 -113177912.5205 +4000 3894 -1.952052116394e-06 +4001 3894 86719444.4302 +4002 3894 -36072082.53399 +4003 3894 -16203472.22755 +4004 3894 21679861.11823 +4005 3894 65803613.40852 +4006 3894 4.112720489502e-06 +4007 3894 3.081560134888e-05 +4008 3894 -14659514.18418 +4009 3894 -1.010298728943e-05 +4010 3894 8.165836334229e-06 +4014 3894 -113177912.5204 +4015 3894 6.407499313354e-07 +4016 3894 -86719444.43019 +4017 3894 -36072082.53397 +4018 3894 16203472.22755 +4019 3894 -21679861.11823 +3895 3895 998747631.9559 +3896 3895 -6.675720214844e-06 +3897 3895 -3.397464752197e-06 +3898 3895 -82157545.53163 +3899 3895 -2.264976501465e-06 +3903 3895 7.748603820801e-07 +3904 3895 55243684.38681 +3905 3895 -1.788139343262e-06 +3906 3895 64813888.87826 +3907 3895 -69150192.34827 +3908 3895 -4.619359970093e-07 +3999 3895 -4.097819328308e-06 +4000 3895 -41882340.60423 +4001 3895 1.296401023865e-06 +4002 3895 -16203472.22755 +4003 3895 -31210863.52938 +4004 3895 17343750.0057 +4005 3895 4.053115844727e-06 +4006 3895 26913861.39084 +4007 3895 4.738569259644e-06 +4008 3895 -7.331371307373e-06 +4009 3895 -76232648.10076 +4010 3895 69374999.9886 +4014 3895 -1.177191734314e-06 +4015 3895 -41882340.60421 +4016 3895 8.344650268555e-07 +4017 3895 16203472.22754 +4018 3895 -31210863.52937 +4019 3895 17343750.0057 +3896 3896 1217261802.153 +3897 3896 -1.52587890625e-05 +3898 3896 -2.562999725342e-06 +3899 3896 179873780.5718 +3903 3896 -1.54972076416e-05 +3904 3896 -1.907348632813e-06 +3905 3896 109872226.963 +3906 3896 -3.635883331299e-06 +3907 3896 -6.109476089478e-07 +3908 3896 -3642360.79014 +3999 3896 86719444.4302 +4000 3896 1.415610313416e-06 +4001 3896 -121047307.7997 +4002 3896 21679861.11823 +4003 3896 17343750.0057 +4004 3896 -38039431.35476 +4005 3896 3.02791595459e-05 +4006 3896 4.619359970093e-06 +4007 3896 -289746007.2349 +4008 3896 8.165836334229e-06 +4009 3896 69374999.9886 +4010 3896 -103546919.3888 +4014 3896 -86719444.43019 +4015 3896 8.940696716309e-07 +4016 3896 -121047307.7997 +4017 3896 -21679861.11823 +4018 3896 17343750.0057 +4019 3896 -38039431.35476 +3897 3897 1242901705.056 +3898 3897 64813887.58197 +3899 3897 -3.838539123535e-05 +3900 3897 47693290.89467 +3901 3897 -64813888.35975 +3902 3897 -7.510185241699e-06 +3903 3897 -88595068.35711 +3904 3897 -64813888.87825 +3905 3897 -4.26173210144e-06 +3906 3897 -229938603.1375 +3907 3897 -1.400709152222e-06 +3908 3897 -1.621246337891e-05 +3909 3897 -88595068.35711 +3910 3897 64813888.87826 +3911 3897 -3.75509262085e-06 +3999 3897 -36072082.53399 +4000 3897 16203472.22755 +4001 3897 21679861.11823 +4002 3897 -135326679.0277 +4003 3897 -16203472.0331 +4004 3897 86719444.24762 +4005 3897 -14659514.18418 +4006 3897 7.62939453125e-06 +4007 3897 7.152557373047e-06 +4008 3897 101875695.1567 +4009 3897 16203471.90348 +4010 3897 0.03654569387436 +4011 3897 -36808280.87074 +4012 3897 -16203472.09792 +4013 3897 21679860.74398 +4014 3897 -36072082.53397 +4015 3897 -16203472.22754 +4016 3897 -21679861.11823 +4017 3897 -113177912.5204 +4018 3897 6.407499313354e-07 +4019 3897 -86719444.43019 +4020 3897 -36072082.53397 +4021 3897 16203472.22755 +4022 3897 -21679861.11823 +3898 3898 1067897821.637 +3900 3898 -64813888.10049 +3901 3898 -179154367.6044 +3902 3898 -1.16229057312e-05 +3903 3898 -64813888.87825 +3904 3898 -69150192.34827 +3905 3898 -6.705522537231e-07 +3906 3898 7.748603820801e-07 +3907 3898 55243684.38681 +3908 3898 -1.788139343262e-06 +3909 3898 64813888.87826 +3910 3898 -69150192.34827 +3911 3898 -4.619359970093e-07 +3999 3898 16203472.22755 +4000 3898 -31210863.52938 +4001 3898 -17343750.00569 +4002 3898 -16203472.09792 +4003 3898 -59169888.51195 +4004 3898 17343749.94043 +4005 3898 8.970499038696e-06 +4006 3898 -76232648.10075 +4007 3898 -69374999.9886 +4008 3898 16203471.90348 +4009 3898 58124724.28025 +4010 3898 0.029221534729 +4011 3898 -16203472.03311 +4012 3898 -93520195.52346 +4013 3898 69374999.6084 +4014 3898 -16203472.22754 +4015 3898 -31210863.52937 +4016 3898 -17343750.0057 +4017 3898 -1.177191734314e-06 +4018 3898 -41882340.60421 +4019 3898 8.344650268555e-07 +4020 3898 16203472.22754 +4021 3898 -31210863.52937 +4022 3898 17343750.0057 +3899 3899 1220904161.253 +3900 3899 -7.390975952148e-06 +3901 3899 -9.536743164063e-06 +3902 3899 101973736.7139 +3903 3899 -4.231929779053e-06 +3904 3899 -5.811452865601e-07 +3905 3899 -3642360.790142 +3906 3899 -1.54972076416e-05 +3907 3899 -1.907348632813e-06 +3908 3899 109872226.963 +3909 3899 -3.635883331299e-06 +3910 3899 -6.109476089478e-07 +3911 3899 -3642360.79014 +3999 3899 21679861.11823 +4000 3899 -17343750.00569 +4001 3899 -38039431.35476 +4002 3899 86719444.24762 +4003 3899 17343749.9078 +4004 3899 -121957897.9018 +4005 3899 7.182359695435e-06 +4006 3899 -69374999.9886 +4007 3899 -103546919.3888 +4008 3899 -0.03648543357849 +4009 3899 -0.02920261025429 +4010 3899 -251706576.231 +4011 3899 21679860.55685 +4012 3899 69374999.49133 +4013 3899 -104457508.7431 +4014 3899 -21679861.11823 +4015 3899 -17343750.0057 +4016 3899 -38039431.35476 +4017 3899 -86719444.43019 +4018 3899 8.940696716309e-07 +4019 3899 -121047307.7997 +4020 3899 -21679861.11823 +4021 3899 17343750.0057 +4022 3899 -38039431.35476 +3900 3900 721441645.4454 +3901 3900 64813888.87825 +3902 3900 -8.821487426758e-06 +3906 3900 -88595068.35711 +3907 3900 -64813888.87825 +3908 3900 -4.26173210144e-06 +3909 3900 -346380299.6592 +3910 3900 -64813888.35974 +3911 3900 -2.676248550415e-05 +3912 3900 27846630.32399 +3913 3900 51851110.58409 +4002 3900 -13923315.16199 +4003 3900 19444166.47861 +4004 3900 26015832.7805 +4008 3900 -36808280.87074 +4009 3900 -16203472.0331 +4010 3900 -21679860.55685 +4011 3900 41127258.27048 +4012 3900 16203472.22755 +4013 3900 17343888.84954 +4017 3900 -36072082.53397 +4018 3900 -16203472.22754 +4019 3900 -21679861.11823 +4020 3900 -135326679.0276 +4021 3900 -16203472.09792 +4022 3900 -86719444.24762 +4023 3900 -13923315.162 +4024 3900 12962777.65241 +4025 3900 -17343888.52033 +3901 3901 624217266.0229 +3902 3901 -7.273460780558e-06 +3906 3901 -64813888.87825 +3907 3901 -69150192.34827 +3908 3901 -6.705522537231e-07 +3909 3901 -64813888.10048 +3910 3901 -41753137.74642 +3911 3901 -7.390975952148e-06 +3912 3901 77776665.87613 +3913 3901 27846630.32398 +3914 3901 6.794929504395e-06 +4002 3901 12962777.65241 +4003 3901 -13923315.162 +4004 3901 -13874999.9393 +4008 3901 -16203472.09791 +4009 3901 -93520195.52345 +4010 3901 -69374999.49133 +4011 3901 16203472.22755 +4012 3901 16821163.40287 +4013 3901 13874999.85144 +4017 3901 -16203472.22754 +4018 3901 -31210863.52937 +4019 3901 -17343750.0057 +4020 3901 -16203472.0331 +4021 3901 -59169888.51194 +4022 3901 -17343749.90781 +4023 3901 19444166.47861 +4024 3901 -13923315.162 +4025 3901 20812499.90895 +3902 3902 760788621.1472 +3906 3902 -4.231929779053e-06 +3907 3902 -5.811452865601e-07 +3908 3902 -3642360.790142 +3909 3902 -2.646446228027e-05 +3910 3902 -5.185604095459e-06 +3911 3902 31972185.12589 +3913 3902 4.708766937256e-06 +3914 3902 74257680.86397 +4002 3902 17343888.52033 +4003 3902 -20812499.90894 +4004 3902 -37128840.43198 +4008 3902 -21679860.74397 +4009 3902 -69374999.6084 +4010 3902 -104457508.7431 +4011 3902 -17343888.84951 +4012 3902 -13874999.85143 +4013 3902 -181091253.0988 +4017 3902 -21679861.11823 +4018 3902 -17343750.0057 +4019 3902 -38039431.35476 +4020 3902 -86719444.24762 +4021 3902 -17343749.94043 +4022 3902 -121957897.9018 +4023 3902 -26015832.7805 +4024 3902 13874999.9393 +4025 3902 -37128840.43199 +3903 3903 1154306639.95 +3904 3903 4.053115844727e-06 +3905 3903 -5.984306335449e-05 +3906 3903 164134990.0133 +3907 3903 -4.798173904419e-06 +3908 3903 -1.537799835205e-05 +3915 3903 -229938603.1375 +3916 3903 -1.400709152222e-06 +3917 3903 -1.621246337891e-05 +3918 3903 -88595068.35711 +3919 3903 64813888.87826 +3920 3903 -3.75509262085e-06 +4005 3903 -113177912.5205 +4006 3903 -1.952052116394e-06 +4007 3903 86719444.4302 +4008 3903 -36072082.53399 +4009 3903 -16203472.22755 +4010 3903 21679861.11823 +4014 3903 65803613.40852 +4015 3903 4.112720489502e-06 +4016 3903 3.081560134888e-05 +4017 3903 -14659514.18418 +4018 3903 -1.010298728943e-05 +4019 3903 8.165836334229e-06 +4026 3903 -113177912.5204 +4027 3903 6.407499313354e-07 +4028 3903 -86719444.43019 +4029 3903 -36072082.53397 +4030 3903 16203472.22755 +4031 3903 -21679861.11823 +3904 3904 998747631.9559 +3905 3904 -6.675720214844e-06 +3906 3904 -3.397464752197e-06 +3907 3904 -82157545.53163 +3908 3904 -2.264976501465e-06 +3915 3904 7.748603820801e-07 +3916 3904 55243684.38681 +3917 3904 -1.788139343262e-06 +3918 3904 64813888.87826 +3919 3904 -69150192.34827 +3920 3904 -4.619359970093e-07 +4005 3904 -4.097819328308e-06 +4006 3904 -41882340.60423 +4007 3904 1.296401023865e-06 +4008 3904 -16203472.22755 +4009 3904 -31210863.52938 +4010 3904 17343750.0057 +4014 3904 4.053115844727e-06 +4015 3904 26913861.39084 +4016 3904 4.738569259644e-06 +4017 3904 -7.331371307373e-06 +4018 3904 -76232648.10076 +4019 3904 69374999.9886 +4026 3904 -1.177191734314e-06 +4027 3904 -41882340.60421 +4028 3904 8.344650268555e-07 +4029 3904 16203472.22754 +4030 3904 -31210863.52937 +4031 3904 17343750.0057 +3905 3905 1217261802.153 +3906 3905 -1.52587890625e-05 +3907 3905 -2.562999725342e-06 +3908 3905 179873780.5718 +3915 3905 -1.54972076416e-05 +3916 3905 -1.907348632813e-06 +3917 3905 109872226.963 +3918 3905 -3.635883331299e-06 +3919 3905 -6.109476089478e-07 +3920 3905 -3642360.79014 +4005 3905 86719444.4302 +4006 3905 1.415610313416e-06 +4007 3905 -121047307.7997 +4008 3905 21679861.11823 +4009 3905 17343750.0057 +4010 3905 -38039431.35476 +4014 3905 3.02791595459e-05 +4015 3905 4.619359970093e-06 +4016 3905 -289746007.2349 +4017 3905 8.165836334229e-06 +4018 3905 69374999.9886 +4019 3905 -103546919.3888 +4026 3905 -86719444.43019 +4027 3905 8.940696716309e-07 +4028 3905 -121047307.7997 +4029 3905 -21679861.11823 +4030 3905 17343750.0057 +4031 3905 -38039431.35476 +3906 3906 1154306639.95 +3907 3906 4.053115844727e-06 +3908 3906 -5.984306335449e-05 +3909 3906 164134990.0133 +3910 3906 -4.798173904419e-06 +3911 3906 -1.537799835205e-05 +3915 3906 -88595068.35711 +3916 3906 -64813888.87825 +3917 3906 -4.26173210144e-06 +3918 3906 -229938603.1375 +3919 3906 -1.400709152222e-06 +3920 3906 -1.621246337891e-05 +3921 3906 -88595068.35711 +3922 3906 64813888.87826 +3923 3906 -3.75509262085e-06 +4005 3906 -36072082.53399 +4006 3906 16203472.22755 +4007 3906 21679861.11823 +4008 3906 -113177912.5205 +4009 3906 -1.952052116394e-06 +4010 3906 86719444.4302 +4011 3906 -36072082.53399 +4012 3906 -16203472.22755 +4013 3906 21679861.11823 +4014 3906 -14659514.18418 +4015 3906 7.62939453125e-06 +4016 3906 7.152557373047e-06 +4017 3906 65803613.40852 +4018 3906 4.112720489502e-06 +4019 3906 3.081560134888e-05 +4020 3906 -14659514.18418 +4021 3906 -1.010298728943e-05 +4022 3906 8.165836334229e-06 +4026 3906 -36072082.53397 +4027 3906 -16203472.22754 +4028 3906 -21679861.11823 +4029 3906 -113177912.5204 +4030 3906 6.407499313354e-07 +4031 3906 -86719444.43019 +4032 3906 -36072082.53397 +4033 3906 16203472.22755 +4034 3906 -21679861.11823 +3907 3907 998747631.9559 +3908 3907 -6.675720214844e-06 +3909 3907 -3.397464752197e-06 +3910 3907 -82157545.53163 +3911 3907 -2.264976501465e-06 +3915 3907 -64813888.87825 +3916 3907 -69150192.34827 +3917 3907 -6.705522537231e-07 +3918 3907 7.748603820801e-07 +3919 3907 55243684.38681 +3920 3907 -1.788139343262e-06 +3921 3907 64813888.87826 +3922 3907 -69150192.34827 +3923 3907 -4.619359970093e-07 +4005 3907 16203472.22755 +4006 3907 -31210863.52938 +4007 3907 -17343750.00569 +4008 3907 -4.097819328308e-06 +4009 3907 -41882340.60423 +4010 3907 1.296401023865e-06 +4011 3907 -16203472.22755 +4012 3907 -31210863.52938 +4013 3907 17343750.0057 +4014 3907 8.970499038696e-06 +4015 3907 -76232648.10075 +4016 3907 -69374999.9886 +4017 3907 4.053115844727e-06 +4018 3907 26913861.39084 +4019 3907 4.738569259644e-06 +4020 3907 -7.331371307373e-06 +4021 3907 -76232648.10076 +4022 3907 69374999.9886 +4026 3907 -16203472.22754 +4027 3907 -31210863.52937 +4028 3907 -17343750.0057 +4029 3907 -1.177191734314e-06 +4030 3907 -41882340.60421 +4031 3907 8.344650268555e-07 +4032 3907 16203472.22754 +4033 3907 -31210863.52937 +4034 3907 17343750.0057 +3908 3908 1217261802.153 +3909 3908 -1.52587890625e-05 +3910 3908 -2.562999725342e-06 +3911 3908 179873780.5718 +3915 3908 -4.231929779053e-06 +3916 3908 -5.811452865601e-07 +3917 3908 -3642360.790142 +3918 3908 -1.54972076416e-05 +3919 3908 -1.907348632813e-06 +3920 3908 109872226.963 +3921 3908 -3.635883331299e-06 +3922 3908 -6.109476089478e-07 +3923 3908 -3642360.79014 +4005 3908 21679861.11823 +4006 3908 -17343750.00569 +4007 3908 -38039431.35476 +4008 3908 86719444.4302 +4009 3908 1.415610313416e-06 +4010 3908 -121047307.7997 +4011 3908 21679861.11823 +4012 3908 17343750.0057 +4013 3908 -38039431.35476 +4014 3908 7.182359695435e-06 +4015 3908 -69374999.9886 +4016 3908 -103546919.3888 +4017 3908 3.02791595459e-05 +4018 3908 4.619359970093e-06 +4019 3908 -289746007.2349 +4020 3908 8.165836334229e-06 +4021 3908 69374999.9886 +4022 3908 -103546919.3888 +4026 3908 -21679861.11823 +4027 3908 -17343750.0057 +4028 3908 -38039431.35476 +4029 3908 -86719444.43019 +4030 3908 8.940696716309e-07 +4031 3908 -121047307.7997 +4032 3908 -21679861.11823 +4033 3908 17343750.0057 +4034 3908 -38039431.35476 +3909 3909 1242901705.056 +3910 3909 64813887.58197 +3911 3909 -3.838539123535e-05 +3912 3909 47693290.89467 +3913 3909 -64813888.35975 +3914 3909 -7.510185241699e-06 +3918 3909 -88595068.35711 +3919 3909 -64813888.87825 +3920 3909 -4.26173210144e-06 +3921 3909 -229938603.1375 +3922 3909 -1.400709152222e-06 +3923 3909 -1.621246337891e-05 +3924 3909 -88595068.35711 +3925 3909 64813888.87826 +3926 3909 -3.75509262085e-06 +4008 3909 -36072082.53399 +4009 3909 16203472.22755 +4010 3909 21679861.11823 +4011 3909 -135326679.0277 +4012 3909 -16203472.0331 +4013 3909 86719444.24762 +4017 3909 -14659514.18418 +4018 3909 7.62939453125e-06 +4019 3909 7.152557373047e-06 +4020 3909 101875695.1567 +4021 3909 16203471.90348 +4022 3909 0.03654569387436 +4023 3909 -36808280.87074 +4024 3909 -16203472.09792 +4025 3909 21679860.74398 +4029 3909 -36072082.53397 +4030 3909 -16203472.22754 +4031 3909 -21679861.11823 +4032 3909 -113177912.5204 +4033 3909 6.407499313354e-07 +4034 3909 -86719444.43019 +4035 3909 -36072082.53397 +4036 3909 16203472.22755 +4037 3909 -21679861.11823 +3910 3910 1067897821.637 +3912 3910 -64813888.10049 +3913 3910 -179154367.6044 +3914 3910 -1.16229057312e-05 +3918 3910 -64813888.87825 +3919 3910 -69150192.34827 +3920 3910 -6.705522537231e-07 +3921 3910 7.748603820801e-07 +3922 3910 55243684.38681 +3923 3910 -1.788139343262e-06 +3924 3910 64813888.87826 +3925 3910 -69150192.34827 +3926 3910 -4.619359970093e-07 +4008 3910 16203472.22755 +4009 3910 -31210863.52938 +4010 3910 -17343750.00569 +4011 3910 -16203472.09792 +4012 3910 -59169888.51195 +4013 3910 17343749.94043 +4017 3910 8.970499038696e-06 +4018 3910 -76232648.10075 +4019 3910 -69374999.9886 +4020 3910 16203471.90348 +4021 3910 58124724.28025 +4022 3910 0.029221534729 +4023 3910 -16203472.03311 +4024 3910 -93520195.52346 +4025 3910 69374999.6084 +4029 3910 -16203472.22754 +4030 3910 -31210863.52937 +4031 3910 -17343750.0057 +4032 3910 -1.177191734314e-06 +4033 3910 -41882340.60421 +4034 3910 8.344650268555e-07 +4035 3910 16203472.22754 +4036 3910 -31210863.52937 +4037 3910 17343750.0057 +3911 3911 1220904161.253 +3912 3911 -7.390975952148e-06 +3913 3911 -9.536743164063e-06 +3914 3911 101973736.7139 +3918 3911 -4.231929779053e-06 +3919 3911 -5.811452865601e-07 +3920 3911 -3642360.790142 +3921 3911 -1.54972076416e-05 +3922 3911 -1.907348632813e-06 +3923 3911 109872226.963 +3924 3911 -3.635883331299e-06 +3925 3911 -6.109476089478e-07 +3926 3911 -3642360.79014 +4008 3911 21679861.11823 +4009 3911 -17343750.00569 +4010 3911 -38039431.35476 +4011 3911 86719444.24762 +4012 3911 17343749.9078 +4013 3911 -121957897.9018 +4017 3911 7.182359695435e-06 +4018 3911 -69374999.9886 +4019 3911 -103546919.3888 +4020 3911 -0.03648543357849 +4021 3911 -0.02920261025429 +4022 3911 -251706576.231 +4023 3911 21679860.55685 +4024 3911 69374999.49133 +4025 3911 -104457508.7431 +4029 3911 -21679861.11823 +4030 3911 -17343750.0057 +4031 3911 -38039431.35476 +4032 3911 -86719444.43019 +4033 3911 8.940696716309e-07 +4034 3911 -121047307.7997 +4035 3911 -21679861.11823 +4036 3911 17343750.0057 +4037 3911 -38039431.35476 +3912 3912 721441645.4454 +3913 3912 64813888.87825 +3914 3912 -8.821487426758e-06 +3921 3912 -88595068.35711 +3922 3912 -64813888.87825 +3923 3912 -4.26173210144e-06 +3924 3912 -346380299.6592 +3925 3912 -64813888.35974 +3926 3912 -2.676248550415e-05 +3927 3912 27846630.32399 +3928 3912 51851110.58409 +4011 3912 -13923315.16199 +4012 3912 19444166.47861 +4013 3912 26015832.7805 +4020 3912 -36808280.87074 +4021 3912 -16203472.0331 +4022 3912 -21679860.55685 +4023 3912 41127258.27048 +4024 3912 16203472.22755 +4025 3912 17343888.84954 +4032 3912 -36072082.53397 +4033 3912 -16203472.22754 +4034 3912 -21679861.11823 +4035 3912 -135326679.0276 +4036 3912 -16203472.09792 +4037 3912 -86719444.24762 +4038 3912 -13923315.162 +4039 3912 12962777.65241 +4040 3912 -17343888.52033 +3913 3913 624217266.0229 +3914 3913 -7.273460780558e-06 +3921 3913 -64813888.87825 +3922 3913 -69150192.34827 +3923 3913 -6.705522537231e-07 +3924 3913 -64813888.10048 +3925 3913 -41753137.74642 +3926 3913 -7.390975952148e-06 +3927 3913 77776665.87613 +3928 3913 27846630.32398 +3929 3913 6.794929504395e-06 +4011 3913 12962777.65241 +4012 3913 -13923315.162 +4013 3913 -13874999.9393 +4020 3913 -16203472.09791 +4021 3913 -93520195.52345 +4022 3913 -69374999.49133 +4023 3913 16203472.22755 +4024 3913 16821163.40287 +4025 3913 13874999.85144 +4032 3913 -16203472.22754 +4033 3913 -31210863.52937 +4034 3913 -17343750.0057 +4035 3913 -16203472.0331 +4036 3913 -59169888.51194 +4037 3913 -17343749.90781 +4038 3913 19444166.47861 +4039 3913 -13923315.162 +4040 3913 20812499.90895 +3914 3914 760788621.1472 +3921 3914 -4.231929779053e-06 +3922 3914 -5.811452865601e-07 +3923 3914 -3642360.790142 +3924 3914 -2.646446228027e-05 +3925 3914 -5.185604095459e-06 +3926 3914 31972185.12589 +3928 3914 4.708766937256e-06 +3929 3914 74257680.86397 +4011 3914 17343888.52033 +4012 3914 -20812499.90894 +4013 3914 -37128840.43198 +4020 3914 -21679860.74397 +4021 3914 -69374999.6084 +4022 3914 -104457508.7431 +4023 3914 -17343888.84951 +4024 3914 -13874999.85143 +4025 3914 -181091253.0988 +4032 3914 -21679861.11823 +4033 3914 -17343750.0057 +4034 3914 -38039431.35476 +4035 3914 -86719444.24762 +4036 3914 -17343749.94043 +4037 3914 -121957897.9018 +4038 3914 -26015832.7805 +4039 3914 13874999.9393 +4040 3914 -37128840.43199 +3915 3915 1154306639.95 +3916 3915 4.053115844727e-06 +3917 3915 -5.984306335449e-05 +3918 3915 164134990.0133 +3919 3915 -4.798173904419e-06 +3920 3915 -1.537799835205e-05 +3930 3915 -229938603.1375 +3931 3915 -1.400709152222e-06 +3932 3915 -1.621246337891e-05 +3933 3915 -88595068.35711 +3934 3915 64813888.87826 +3935 3915 -3.75509262085e-06 +4014 3915 -113177912.5205 +4015 3915 -1.952052116394e-06 +4016 3915 86719444.4302 +4017 3915 -36072082.53399 +4018 3915 -16203472.22755 +4019 3915 21679861.11823 +4026 3915 65803613.40852 +4027 3915 4.112720489502e-06 +4028 3915 3.081560134888e-05 +4029 3915 -14659514.18418 +4030 3915 -1.010298728943e-05 +4031 3915 8.165836334229e-06 +4041 3915 -113177912.5204 +4042 3915 6.407499313354e-07 +4043 3915 -86719444.43019 +4044 3915 -36072082.53397 +4045 3915 16203472.22755 +4046 3915 -21679861.11823 +3916 3916 998747631.9559 +3917 3916 -6.675720214844e-06 +3918 3916 -3.397464752197e-06 +3919 3916 -82157545.53163 +3920 3916 -2.264976501465e-06 +3930 3916 7.748603820801e-07 +3931 3916 55243684.38681 +3932 3916 -1.788139343262e-06 +3933 3916 64813888.87826 +3934 3916 -69150192.34827 +3935 3916 -4.619359970093e-07 +4014 3916 -4.097819328308e-06 +4015 3916 -41882340.60423 +4016 3916 1.296401023865e-06 +4017 3916 -16203472.22755 +4018 3916 -31210863.52938 +4019 3916 17343750.0057 +4026 3916 4.053115844727e-06 +4027 3916 26913861.39084 +4028 3916 4.738569259644e-06 +4029 3916 -7.331371307373e-06 +4030 3916 -76232648.10076 +4031 3916 69374999.9886 +4041 3916 -1.177191734314e-06 +4042 3916 -41882340.60421 +4043 3916 8.344650268555e-07 +4044 3916 16203472.22754 +4045 3916 -31210863.52937 +4046 3916 17343750.0057 +3917 3917 1217261802.153 +3918 3917 -1.52587890625e-05 +3919 3917 -2.562999725342e-06 +3920 3917 179873780.5718 +3930 3917 -1.54972076416e-05 +3931 3917 -1.907348632813e-06 +3932 3917 109872226.963 +3933 3917 -3.635883331299e-06 +3934 3917 -6.109476089478e-07 +3935 3917 -3642360.79014 +4014 3917 86719444.4302 +4015 3917 1.415610313416e-06 +4016 3917 -121047307.7997 +4017 3917 21679861.11823 +4018 3917 17343750.0057 +4019 3917 -38039431.35476 +4026 3917 3.02791595459e-05 +4027 3917 4.619359970093e-06 +4028 3917 -289746007.2349 +4029 3917 8.165836334229e-06 +4030 3917 69374999.9886 +4031 3917 -103546919.3888 +4041 3917 -86719444.43019 +4042 3917 8.940696716309e-07 +4043 3917 -121047307.7997 +4044 3917 -21679861.11823 +4045 3917 17343750.0057 +4046 3917 -38039431.35476 +3918 3918 1154306639.95 +3919 3918 4.053115844727e-06 +3920 3918 -5.984306335449e-05 +3921 3918 164134990.0133 +3922 3918 -4.798173904419e-06 +3923 3918 -1.537799835205e-05 +3930 3918 -88595068.35711 +3931 3918 -64813888.87825 +3932 3918 -4.26173210144e-06 +3933 3918 -229938603.1375 +3934 3918 -1.400709152222e-06 +3935 3918 -1.621246337891e-05 +3936 3918 -88595068.35711 +3937 3918 64813888.87826 +3938 3918 -3.75509262085e-06 +4014 3918 -36072082.53399 +4015 3918 16203472.22755 +4016 3918 21679861.11823 +4017 3918 -113177912.5205 +4018 3918 -1.952052116394e-06 +4019 3918 86719444.4302 +4020 3918 -36072082.53399 +4021 3918 -16203472.22755 +4022 3918 21679861.11823 +4026 3918 -14659514.18418 +4027 3918 7.62939453125e-06 +4028 3918 7.152557373047e-06 +4029 3918 65803613.40852 +4030 3918 4.112720489502e-06 +4031 3918 3.081560134888e-05 +4032 3918 -14659514.18418 +4033 3918 -1.010298728943e-05 +4034 3918 8.165836334229e-06 +4041 3918 -36072082.53397 +4042 3918 -16203472.22754 +4043 3918 -21679861.11823 +4044 3918 -113177912.5204 +4045 3918 6.407499313354e-07 +4046 3918 -86719444.43019 +4047 3918 -36072082.53397 +4048 3918 16203472.22755 +4049 3918 -21679861.11823 +3919 3919 998747631.9559 +3920 3919 -6.675720214844e-06 +3921 3919 -3.397464752197e-06 +3922 3919 -82157545.53163 +3923 3919 -2.264976501465e-06 +3930 3919 -64813888.87825 +3931 3919 -69150192.34827 +3932 3919 -6.705522537231e-07 +3933 3919 7.748603820801e-07 +3934 3919 55243684.38681 +3935 3919 -1.788139343262e-06 +3936 3919 64813888.87826 +3937 3919 -69150192.34827 +3938 3919 -4.619359970093e-07 +4014 3919 16203472.22755 +4015 3919 -31210863.52938 +4016 3919 -17343750.00569 +4017 3919 -4.097819328308e-06 +4018 3919 -41882340.60423 +4019 3919 1.296401023865e-06 +4020 3919 -16203472.22755 +4021 3919 -31210863.52938 +4022 3919 17343750.0057 +4026 3919 8.970499038696e-06 +4027 3919 -76232648.10075 +4028 3919 -69374999.9886 +4029 3919 4.053115844727e-06 +4030 3919 26913861.39084 +4031 3919 4.738569259644e-06 +4032 3919 -7.331371307373e-06 +4033 3919 -76232648.10076 +4034 3919 69374999.9886 +4041 3919 -16203472.22754 +4042 3919 -31210863.52937 +4043 3919 -17343750.0057 +4044 3919 -1.177191734314e-06 +4045 3919 -41882340.60421 +4046 3919 8.344650268555e-07 +4047 3919 16203472.22754 +4048 3919 -31210863.52937 +4049 3919 17343750.0057 +3920 3920 1217261802.153 +3921 3920 -1.52587890625e-05 +3922 3920 -2.562999725342e-06 +3923 3920 179873780.5718 +3930 3920 -4.231929779053e-06 +3931 3920 -5.811452865601e-07 +3932 3920 -3642360.790142 +3933 3920 -1.54972076416e-05 +3934 3920 -1.907348632813e-06 +3935 3920 109872226.963 +3936 3920 -3.635883331299e-06 +3937 3920 -6.109476089478e-07 +3938 3920 -3642360.79014 +4014 3920 21679861.11823 +4015 3920 -17343750.00569 +4016 3920 -38039431.35476 +4017 3920 86719444.4302 +4018 3920 1.415610313416e-06 +4019 3920 -121047307.7997 +4020 3920 21679861.11823 +4021 3920 17343750.0057 +4022 3920 -38039431.35476 +4026 3920 7.182359695435e-06 +4027 3920 -69374999.9886 +4028 3920 -103546919.3888 +4029 3920 3.02791595459e-05 +4030 3920 4.619359970093e-06 +4031 3920 -289746007.2349 +4032 3920 8.165836334229e-06 +4033 3920 69374999.9886 +4034 3920 -103546919.3888 +4041 3920 -21679861.11823 +4042 3920 -17343750.0057 +4043 3920 -38039431.35476 +4044 3920 -86719444.43019 +4045 3920 8.940696716309e-07 +4046 3920 -121047307.7997 +4047 3920 -21679861.11823 +4048 3920 17343750.0057 +4049 3920 -38039431.35476 +3921 3921 1154306639.95 +3922 3921 4.053115844727e-06 +3923 3921 -5.984306335449e-05 +3924 3921 164134990.0133 +3925 3921 -4.798173904419e-06 +3926 3921 -1.537799835205e-05 +3933 3921 -88595068.35711 +3934 3921 -64813888.87825 +3935 3921 -4.26173210144e-06 +3936 3921 -229938603.1375 +3937 3921 -1.400709152222e-06 +3938 3921 -1.621246337891e-05 +3939 3921 -88595068.35711 +3940 3921 64813888.87826 +3941 3921 -3.75509262085e-06 +4017 3921 -36072082.53399 +4018 3921 16203472.22755 +4019 3921 21679861.11823 +4020 3921 -113177912.5205 +4021 3921 -1.952052116394e-06 +4022 3921 86719444.4302 +4023 3921 -36072082.53399 +4024 3921 -16203472.22755 +4025 3921 21679861.11823 +4029 3921 -14659514.18418 +4030 3921 7.62939453125e-06 +4031 3921 7.152557373047e-06 +4032 3921 65803613.40852 +4033 3921 4.112720489502e-06 +4034 3921 3.081560134888e-05 +4035 3921 -14659514.18418 +4036 3921 -1.010298728943e-05 +4037 3921 8.165836334229e-06 +4044 3921 -36072082.53397 +4045 3921 -16203472.22754 +4046 3921 -21679861.11823 +4047 3921 -113177912.5204 +4048 3921 6.407499313354e-07 +4049 3921 -86719444.43019 +4050 3921 -36072082.53397 +4051 3921 16203472.22755 +4052 3921 -21679861.11823 +3922 3922 998747631.9559 +3923 3922 -6.675720214844e-06 +3924 3922 -3.397464752197e-06 +3925 3922 -82157545.53163 +3926 3922 -2.264976501465e-06 +3933 3922 -64813888.87825 +3934 3922 -69150192.34827 +3935 3922 -6.705522537231e-07 +3936 3922 7.748603820801e-07 +3937 3922 55243684.38681 +3938 3922 -1.788139343262e-06 +3939 3922 64813888.87826 +3940 3922 -69150192.34827 +3941 3922 -4.619359970093e-07 +4017 3922 16203472.22755 +4018 3922 -31210863.52938 +4019 3922 -17343750.00569 +4020 3922 -4.097819328308e-06 +4021 3922 -41882340.60423 +4022 3922 1.296401023865e-06 +4023 3922 -16203472.22755 +4024 3922 -31210863.52938 +4025 3922 17343750.0057 +4029 3922 8.970499038696e-06 +4030 3922 -76232648.10075 +4031 3922 -69374999.9886 +4032 3922 4.053115844727e-06 +4033 3922 26913861.39084 +4034 3922 4.738569259644e-06 +4035 3922 -7.331371307373e-06 +4036 3922 -76232648.10076 +4037 3922 69374999.9886 +4044 3922 -16203472.22754 +4045 3922 -31210863.52937 +4046 3922 -17343750.0057 +4047 3922 -1.177191734314e-06 +4048 3922 -41882340.60421 +4049 3922 8.344650268555e-07 +4050 3922 16203472.22754 +4051 3922 -31210863.52937 +4052 3922 17343750.0057 +3923 3923 1217261802.153 +3924 3923 -1.52587890625e-05 +3925 3923 -2.562999725342e-06 +3926 3923 179873780.5718 +3933 3923 -4.231929779053e-06 +3934 3923 -5.811452865601e-07 +3935 3923 -3642360.790142 +3936 3923 -1.54972076416e-05 +3937 3923 -1.907348632813e-06 +3938 3923 109872226.963 +3939 3923 -3.635883331299e-06 +3940 3923 -6.109476089478e-07 +3941 3923 -3642360.79014 +4017 3923 21679861.11823 +4018 3923 -17343750.00569 +4019 3923 -38039431.35476 +4020 3923 86719444.4302 +4021 3923 1.415610313416e-06 +4022 3923 -121047307.7997 +4023 3923 21679861.11823 +4024 3923 17343750.0057 +4025 3923 -38039431.35476 +4029 3923 7.182359695435e-06 +4030 3923 -69374999.9886 +4031 3923 -103546919.3888 +4032 3923 3.02791595459e-05 +4033 3923 4.619359970093e-06 +4034 3923 -289746007.2349 +4035 3923 8.165836334229e-06 +4036 3923 69374999.9886 +4037 3923 -103546919.3888 +4044 3923 -21679861.11823 +4045 3923 -17343750.0057 +4046 3923 -38039431.35476 +4047 3923 -86719444.43019 +4048 3923 8.940696716309e-07 +4049 3923 -121047307.7997 +4050 3923 -21679861.11823 +4051 3923 17343750.0057 +4052 3923 -38039431.35476 +3924 3924 1242901705.056 +3925 3924 64813887.58197 +3926 3924 -3.838539123535e-05 +3927 3924 47693290.89467 +3928 3924 -64813888.35975 +3929 3924 -7.510185241699e-06 +3936 3924 -88595068.35711 +3937 3924 -64813888.87825 +3938 3924 -4.26173210144e-06 +3939 3924 -229938603.1375 +3940 3924 -1.400709152222e-06 +3941 3924 -1.621246337891e-05 +3942 3924 -88595068.35711 +3943 3924 64813888.87826 +3944 3924 -3.75509262085e-06 +4020 3924 -36072082.53399 +4021 3924 16203472.22755 +4022 3924 21679861.11823 +4023 3924 -135326679.0277 +4024 3924 -16203472.0331 +4025 3924 86719444.24762 +4032 3924 -14659514.18418 +4033 3924 7.62939453125e-06 +4034 3924 7.152557373047e-06 +4035 3924 101875695.1567 +4036 3924 16203471.90348 +4037 3924 0.03654569387436 +4038 3924 -36808280.87074 +4039 3924 -16203472.09792 +4040 3924 21679860.74398 +4047 3924 -36072082.53397 +4048 3924 -16203472.22754 +4049 3924 -21679861.11823 +4050 3924 -113177912.5204 +4051 3924 6.407499313354e-07 +4052 3924 -86719444.43019 +4053 3924 -36072082.53397 +4054 3924 16203472.22755 +4055 3924 -21679861.11823 +3925 3925 1067897821.637 +3927 3925 -64813888.10049 +3928 3925 -179154367.6044 +3929 3925 -1.16229057312e-05 +3936 3925 -64813888.87825 +3937 3925 -69150192.34827 +3938 3925 -6.705522537231e-07 +3939 3925 7.748603820801e-07 +3940 3925 55243684.38681 +3941 3925 -1.788139343262e-06 +3942 3925 64813888.87826 +3943 3925 -69150192.34827 +3944 3925 -4.619359970093e-07 +4020 3925 16203472.22755 +4021 3925 -31210863.52938 +4022 3925 -17343750.00569 +4023 3925 -16203472.09792 +4024 3925 -59169888.51195 +4025 3925 17343749.94043 +4032 3925 8.970499038696e-06 +4033 3925 -76232648.10075 +4034 3925 -69374999.9886 +4035 3925 16203471.90348 +4036 3925 58124724.28025 +4037 3925 0.029221534729 +4038 3925 -16203472.03311 +4039 3925 -93520195.52346 +4040 3925 69374999.6084 +4047 3925 -16203472.22754 +4048 3925 -31210863.52937 +4049 3925 -17343750.0057 +4050 3925 -1.177191734314e-06 +4051 3925 -41882340.60421 +4052 3925 8.344650268555e-07 +4053 3925 16203472.22754 +4054 3925 -31210863.52937 +4055 3925 17343750.0057 +3926 3926 1220904161.253 +3927 3926 -7.390975952148e-06 +3928 3926 -9.536743164063e-06 +3929 3926 101973736.7139 +3936 3926 -4.231929779053e-06 +3937 3926 -5.811452865601e-07 +3938 3926 -3642360.790142 +3939 3926 -1.54972076416e-05 +3940 3926 -1.907348632813e-06 +3941 3926 109872226.963 +3942 3926 -3.635883331299e-06 +3943 3926 -6.109476089478e-07 +3944 3926 -3642360.79014 +4020 3926 21679861.11823 +4021 3926 -17343750.00569 +4022 3926 -38039431.35476 +4023 3926 86719444.24762 +4024 3926 17343749.9078 +4025 3926 -121957897.9018 +4032 3926 7.182359695435e-06 +4033 3926 -69374999.9886 +4034 3926 -103546919.3888 +4035 3926 -0.03648543357849 +4036 3926 -0.02920261025429 +4037 3926 -251706576.231 +4038 3926 21679860.55685 +4039 3926 69374999.49133 +4040 3926 -104457508.7431 +4047 3926 -21679861.11823 +4048 3926 -17343750.0057 +4049 3926 -38039431.35476 +4050 3926 -86719444.43019 +4051 3926 8.940696716309e-07 +4052 3926 -121047307.7997 +4053 3926 -21679861.11823 +4054 3926 17343750.0057 +4055 3926 -38039431.35476 +3927 3927 721441645.4454 +3928 3927 64813888.87825 +3929 3927 -8.821487426758e-06 +3939 3927 -88595068.35711 +3940 3927 -64813888.87825 +3941 3927 -4.26173210144e-06 +3942 3927 -346380299.6592 +3943 3927 -64813888.35974 +3944 3927 -2.676248550415e-05 +3945 3927 27846630.32399 +3946 3927 51851110.58409 +4023 3927 -13923315.16199 +4024 3927 19444166.47861 +4025 3927 26015832.7805 +4035 3927 -36808280.87074 +4036 3927 -16203472.0331 +4037 3927 -21679860.55685 +4038 3927 41127258.27048 +4039 3927 16203472.22755 +4040 3927 17343888.84954 +4050 3927 -36072082.53397 +4051 3927 -16203472.22754 +4052 3927 -21679861.11823 +4053 3927 -135326679.0276 +4054 3927 -16203472.09792 +4055 3927 -86719444.24762 +4056 3927 -13923315.162 +4057 3927 12962777.65241 +4058 3927 -17343888.52033 +3928 3928 624217266.0229 +3929 3928 -7.273460780558e-06 +3939 3928 -64813888.87825 +3940 3928 -69150192.34827 +3941 3928 -6.705522537231e-07 +3942 3928 -64813888.10048 +3943 3928 -41753137.74642 +3944 3928 -7.390975952148e-06 +3945 3928 77776665.87613 +3946 3928 27846630.32398 +3947 3928 6.794929504395e-06 +4023 3928 12962777.65241 +4024 3928 -13923315.162 +4025 3928 -13874999.9393 +4035 3928 -16203472.09791 +4036 3928 -93520195.52345 +4037 3928 -69374999.49133 +4038 3928 16203472.22755 +4039 3928 16821163.40287 +4040 3928 13874999.85144 +4050 3928 -16203472.22754 +4051 3928 -31210863.52937 +4052 3928 -17343750.0057 +4053 3928 -16203472.0331 +4054 3928 -59169888.51194 +4055 3928 -17343749.90781 +4056 3928 19444166.47861 +4057 3928 -13923315.162 +4058 3928 20812499.90895 +3929 3929 760788621.1472 +3939 3929 -4.231929779053e-06 +3940 3929 -5.811452865601e-07 +3941 3929 -3642360.790142 +3942 3929 -2.646446228027e-05 +3943 3929 -5.185604095459e-06 +3944 3929 31972185.12589 +3946 3929 4.708766937256e-06 +3947 3929 74257680.86397 +4023 3929 17343888.52033 +4024 3929 -20812499.90894 +4025 3929 -37128840.43198 +4035 3929 -21679860.74397 +4036 3929 -69374999.6084 +4037 3929 -104457508.7431 +4038 3929 -17343888.84951 +4039 3929 -13874999.85143 +4040 3929 -181091253.0988 +4050 3929 -21679861.11823 +4051 3929 -17343750.0057 +4052 3929 -38039431.35476 +4053 3929 -86719444.24762 +4054 3929 -17343749.94043 +4055 3929 -121957897.9018 +4056 3929 -26015832.7805 +4057 3929 13874999.9393 +4058 3929 -37128840.43199 +3930 3930 1154306639.95 +3931 3930 4.053115844727e-06 +3932 3930 -5.984306335449e-05 +3933 3930 164134990.0133 +3934 3930 -4.798173904419e-06 +3935 3930 -1.537799835205e-05 +3948 3930 -229938603.1375 +3949 3930 -1.400709152222e-06 +3950 3930 -1.621246337891e-05 +3951 3930 -88595068.35711 +3952 3930 64813888.87826 +3953 3930 -3.75509262085e-06 +4026 3930 -113177912.5205 +4027 3930 -1.952052116394e-06 +4028 3930 86719444.4302 +4029 3930 -36072082.53399 +4030 3930 -16203472.22755 +4031 3930 21679861.11823 +4041 3930 65803613.40852 +4042 3930 4.112720489502e-06 +4043 3930 3.081560134888e-05 +4044 3930 -14659514.18418 +4045 3930 -1.010298728943e-05 +4046 3930 8.165836334229e-06 +4059 3930 -113177912.5204 +4060 3930 6.407499313354e-07 +4061 3930 -86719444.43019 +4062 3930 -36072082.53397 +4063 3930 16203472.22755 +4064 3930 -21679861.11823 +3931 3931 998747631.9559 +3932 3931 -6.675720214844e-06 +3933 3931 -3.397464752197e-06 +3934 3931 -82157545.53163 +3935 3931 -2.264976501465e-06 +3948 3931 7.748603820801e-07 +3949 3931 55243684.38681 +3950 3931 -1.788139343262e-06 +3951 3931 64813888.87826 +3952 3931 -69150192.34827 +3953 3931 -4.619359970093e-07 +4026 3931 -4.097819328308e-06 +4027 3931 -41882340.60423 +4028 3931 1.296401023865e-06 +4029 3931 -16203472.22755 +4030 3931 -31210863.52938 +4031 3931 17343750.0057 +4041 3931 4.053115844727e-06 +4042 3931 26913861.39084 +4043 3931 4.738569259644e-06 +4044 3931 -7.331371307373e-06 +4045 3931 -76232648.10076 +4046 3931 69374999.9886 +4059 3931 -1.177191734314e-06 +4060 3931 -41882340.60421 +4061 3931 8.344650268555e-07 +4062 3931 16203472.22754 +4063 3931 -31210863.52937 +4064 3931 17343750.0057 +3932 3932 1217261802.153 +3933 3932 -1.52587890625e-05 +3934 3932 -2.562999725342e-06 +3935 3932 179873780.5718 +3948 3932 -1.54972076416e-05 +3949 3932 -1.907348632813e-06 +3950 3932 109872226.963 +3951 3932 -3.635883331299e-06 +3952 3932 -6.109476089478e-07 +3953 3932 -3642360.79014 +4026 3932 86719444.4302 +4027 3932 1.415610313416e-06 +4028 3932 -121047307.7997 +4029 3932 21679861.11823 +4030 3932 17343750.0057 +4031 3932 -38039431.35476 +4041 3932 3.02791595459e-05 +4042 3932 4.619359970093e-06 +4043 3932 -289746007.2349 +4044 3932 8.165836334229e-06 +4045 3932 69374999.9886 +4046 3932 -103546919.3888 +4059 3932 -86719444.43019 +4060 3932 8.940696716309e-07 +4061 3932 -121047307.7997 +4062 3932 -21679861.11823 +4063 3932 17343750.0057 +4064 3932 -38039431.35476 +3933 3933 1154306639.95 +3934 3933 4.053115844727e-06 +3935 3933 -5.984306335449e-05 +3936 3933 164134990.0133 +3937 3933 -4.798173904419e-06 +3938 3933 -1.537799835205e-05 +3948 3933 -88595068.35711 +3949 3933 -64813888.87825 +3950 3933 -4.26173210144e-06 +3951 3933 -229938603.1375 +3952 3933 -1.400709152222e-06 +3953 3933 -1.621246337891e-05 +3954 3933 -88595068.35711 +3955 3933 64813888.87826 +3956 3933 -3.75509262085e-06 +4026 3933 -36072082.53399 +4027 3933 16203472.22755 +4028 3933 21679861.11823 +4029 3933 -113177912.5205 +4030 3933 -1.952052116394e-06 +4031 3933 86719444.4302 +4032 3933 -36072082.53399 +4033 3933 -16203472.22755 +4034 3933 21679861.11823 +4041 3933 -14659514.18418 +4042 3933 7.62939453125e-06 +4043 3933 7.152557373047e-06 +4044 3933 65803613.40852 +4045 3933 4.112720489502e-06 +4046 3933 3.081560134888e-05 +4047 3933 -14659514.18418 +4048 3933 -1.010298728943e-05 +4049 3933 8.165836334229e-06 +4059 3933 -36072082.53397 +4060 3933 -16203472.22754 +4061 3933 -21679861.11823 +4062 3933 -113177912.5204 +4063 3933 6.407499313354e-07 +4064 3933 -86719444.43019 +4065 3933 -36072082.53397 +4066 3933 16203472.22755 +4067 3933 -21679861.11823 +3934 3934 998747631.9559 +3935 3934 -6.675720214844e-06 +3936 3934 -3.397464752197e-06 +3937 3934 -82157545.53163 +3938 3934 -2.264976501465e-06 +3948 3934 -64813888.87825 +3949 3934 -69150192.34827 +3950 3934 -6.705522537231e-07 +3951 3934 7.748603820801e-07 +3952 3934 55243684.38681 +3953 3934 -1.788139343262e-06 +3954 3934 64813888.87826 +3955 3934 -69150192.34827 +3956 3934 -4.619359970093e-07 +4026 3934 16203472.22755 +4027 3934 -31210863.52938 +4028 3934 -17343750.00569 +4029 3934 -4.097819328308e-06 +4030 3934 -41882340.60423 +4031 3934 1.296401023865e-06 +4032 3934 -16203472.22755 +4033 3934 -31210863.52938 +4034 3934 17343750.0057 +4041 3934 8.970499038696e-06 +4042 3934 -76232648.10075 +4043 3934 -69374999.9886 +4044 3934 4.053115844727e-06 +4045 3934 26913861.39084 +4046 3934 4.738569259644e-06 +4047 3934 -7.331371307373e-06 +4048 3934 -76232648.10076 +4049 3934 69374999.9886 +4059 3934 -16203472.22754 +4060 3934 -31210863.52937 +4061 3934 -17343750.0057 +4062 3934 -1.177191734314e-06 +4063 3934 -41882340.60421 +4064 3934 8.344650268555e-07 +4065 3934 16203472.22754 +4066 3934 -31210863.52937 +4067 3934 17343750.0057 +3935 3935 1217261802.153 +3936 3935 -1.52587890625e-05 +3937 3935 -2.562999725342e-06 +3938 3935 179873780.5718 +3948 3935 -4.231929779053e-06 +3949 3935 -5.811452865601e-07 +3950 3935 -3642360.790142 +3951 3935 -1.54972076416e-05 +3952 3935 -1.907348632813e-06 +3953 3935 109872226.963 +3954 3935 -3.635883331299e-06 +3955 3935 -6.109476089478e-07 +3956 3935 -3642360.79014 +4026 3935 21679861.11823 +4027 3935 -17343750.00569 +4028 3935 -38039431.35476 +4029 3935 86719444.4302 +4030 3935 1.415610313416e-06 +4031 3935 -121047307.7997 +4032 3935 21679861.11823 +4033 3935 17343750.0057 +4034 3935 -38039431.35476 +4041 3935 7.182359695435e-06 +4042 3935 -69374999.9886 +4043 3935 -103546919.3888 +4044 3935 3.02791595459e-05 +4045 3935 4.619359970093e-06 +4046 3935 -289746007.2349 +4047 3935 8.165836334229e-06 +4048 3935 69374999.9886 +4049 3935 -103546919.3888 +4059 3935 -21679861.11823 +4060 3935 -17343750.0057 +4061 3935 -38039431.35476 +4062 3935 -86719444.43019 +4063 3935 8.940696716309e-07 +4064 3935 -121047307.7997 +4065 3935 -21679861.11823 +4066 3935 17343750.0057 +4067 3935 -38039431.35476 +3936 3936 1154306639.95 +3937 3936 4.053115844727e-06 +3938 3936 -5.984306335449e-05 +3939 3936 164134990.0133 +3940 3936 -4.798173904419e-06 +3941 3936 -1.537799835205e-05 +3951 3936 -88595068.35711 +3952 3936 -64813888.87825 +3953 3936 -4.26173210144e-06 +3954 3936 -229938603.1375 +3955 3936 -1.400709152222e-06 +3956 3936 -1.621246337891e-05 +3957 3936 -88595068.35711 +3958 3936 64813888.87826 +3959 3936 -3.75509262085e-06 +4029 3936 -36072082.53399 +4030 3936 16203472.22755 +4031 3936 21679861.11823 +4032 3936 -113177912.5205 +4033 3936 -1.952052116394e-06 +4034 3936 86719444.4302 +4035 3936 -36072082.53399 +4036 3936 -16203472.22755 +4037 3936 21679861.11823 +4044 3936 -14659514.18418 +4045 3936 7.62939453125e-06 +4046 3936 7.152557373047e-06 +4047 3936 65803613.40852 +4048 3936 4.112720489502e-06 +4049 3936 3.081560134888e-05 +4050 3936 -14659514.18418 +4051 3936 -1.010298728943e-05 +4052 3936 8.165836334229e-06 +4062 3936 -36072082.53397 +4063 3936 -16203472.22754 +4064 3936 -21679861.11823 +4065 3936 -113177912.5204 +4066 3936 6.407499313354e-07 +4067 3936 -86719444.43019 +4068 3936 -36072082.53397 +4069 3936 16203472.22755 +4070 3936 -21679861.11823 +3937 3937 998747631.9559 +3938 3937 -6.675720214844e-06 +3939 3937 -3.397464752197e-06 +3940 3937 -82157545.53163 +3941 3937 -2.264976501465e-06 +3951 3937 -64813888.87825 +3952 3937 -69150192.34827 +3953 3937 -6.705522537231e-07 +3954 3937 7.748603820801e-07 +3955 3937 55243684.38681 +3956 3937 -1.788139343262e-06 +3957 3937 64813888.87826 +3958 3937 -69150192.34827 +3959 3937 -4.619359970093e-07 +4029 3937 16203472.22755 +4030 3937 -31210863.52938 +4031 3937 -17343750.00569 +4032 3937 -4.097819328308e-06 +4033 3937 -41882340.60423 +4034 3937 1.296401023865e-06 +4035 3937 -16203472.22755 +4036 3937 -31210863.52938 +4037 3937 17343750.0057 +4044 3937 8.970499038696e-06 +4045 3937 -76232648.10075 +4046 3937 -69374999.9886 +4047 3937 4.053115844727e-06 +4048 3937 26913861.39084 +4049 3937 4.738569259644e-06 +4050 3937 -7.331371307373e-06 +4051 3937 -76232648.10076 +4052 3937 69374999.9886 +4062 3937 -16203472.22754 +4063 3937 -31210863.52937 +4064 3937 -17343750.0057 +4065 3937 -1.177191734314e-06 +4066 3937 -41882340.60421 +4067 3937 8.344650268555e-07 +4068 3937 16203472.22754 +4069 3937 -31210863.52937 +4070 3937 17343750.0057 +3938 3938 1217261802.153 +3939 3938 -1.52587890625e-05 +3940 3938 -2.562999725342e-06 +3941 3938 179873780.5718 +3951 3938 -4.231929779053e-06 +3952 3938 -5.811452865601e-07 +3953 3938 -3642360.790142 +3954 3938 -1.54972076416e-05 +3955 3938 -1.907348632813e-06 +3956 3938 109872226.963 +3957 3938 -3.635883331299e-06 +3958 3938 -6.109476089478e-07 +3959 3938 -3642360.79014 +4029 3938 21679861.11823 +4030 3938 -17343750.00569 +4031 3938 -38039431.35476 +4032 3938 86719444.4302 +4033 3938 1.415610313416e-06 +4034 3938 -121047307.7997 +4035 3938 21679861.11823 +4036 3938 17343750.0057 +4037 3938 -38039431.35476 +4044 3938 7.182359695435e-06 +4045 3938 -69374999.9886 +4046 3938 -103546919.3888 +4047 3938 3.02791595459e-05 +4048 3938 4.619359970093e-06 +4049 3938 -289746007.2349 +4050 3938 8.165836334229e-06 +4051 3938 69374999.9886 +4052 3938 -103546919.3888 +4062 3938 -21679861.11823 +4063 3938 -17343750.0057 +4064 3938 -38039431.35476 +4065 3938 -86719444.43019 +4066 3938 8.940696716309e-07 +4067 3938 -121047307.7997 +4068 3938 -21679861.11823 +4069 3938 17343750.0057 +4070 3938 -38039431.35476 +3939 3939 1154306639.95 +3940 3939 4.053115844727e-06 +3941 3939 -5.984306335449e-05 +3942 3939 164134990.0133 +3943 3939 -4.798173904419e-06 +3944 3939 -1.537799835205e-05 +3954 3939 -88595068.35711 +3955 3939 -64813888.87825 +3956 3939 -4.26173210144e-06 +3957 3939 -229938603.1375 +3958 3939 -1.400709152222e-06 +3959 3939 -1.621246337891e-05 +3960 3939 -88595068.35711 +3961 3939 64813888.87826 +3962 3939 -3.75509262085e-06 +4032 3939 -36072082.53399 +4033 3939 16203472.22755 +4034 3939 21679861.11823 +4035 3939 -113177912.5205 +4036 3939 -1.952052116394e-06 +4037 3939 86719444.4302 +4038 3939 -36072082.53399 +4039 3939 -16203472.22755 +4040 3939 21679861.11823 +4047 3939 -14659514.18418 +4048 3939 7.62939453125e-06 +4049 3939 7.152557373047e-06 +4050 3939 65803613.40852 +4051 3939 4.112720489502e-06 +4052 3939 3.081560134888e-05 +4053 3939 -14659514.18418 +4054 3939 -1.010298728943e-05 +4055 3939 8.165836334229e-06 +4065 3939 -36072082.53397 +4066 3939 -16203472.22754 +4067 3939 -21679861.11823 +4068 3939 -113177912.5204 +4069 3939 6.407499313354e-07 +4070 3939 -86719444.43019 +4071 3939 -36072082.53397 +4072 3939 16203472.22755 +4073 3939 -21679861.11823 +3940 3940 998747631.9559 +3941 3940 -6.675720214844e-06 +3942 3940 -3.397464752197e-06 +3943 3940 -82157545.53163 +3944 3940 -2.264976501465e-06 +3954 3940 -64813888.87825 +3955 3940 -69150192.34827 +3956 3940 -6.705522537231e-07 +3957 3940 7.748603820801e-07 +3958 3940 55243684.38681 +3959 3940 -1.788139343262e-06 +3960 3940 64813888.87826 +3961 3940 -69150192.34827 +3962 3940 -4.619359970093e-07 +4032 3940 16203472.22755 +4033 3940 -31210863.52938 +4034 3940 -17343750.00569 +4035 3940 -4.097819328308e-06 +4036 3940 -41882340.60423 +4037 3940 1.296401023865e-06 +4038 3940 -16203472.22755 +4039 3940 -31210863.52938 +4040 3940 17343750.0057 +4047 3940 8.970499038696e-06 +4048 3940 -76232648.10075 +4049 3940 -69374999.9886 +4050 3940 4.053115844727e-06 +4051 3940 26913861.39084 +4052 3940 4.738569259644e-06 +4053 3940 -7.331371307373e-06 +4054 3940 -76232648.10076 +4055 3940 69374999.9886 +4065 3940 -16203472.22754 +4066 3940 -31210863.52937 +4067 3940 -17343750.0057 +4068 3940 -1.177191734314e-06 +4069 3940 -41882340.60421 +4070 3940 8.344650268555e-07 +4071 3940 16203472.22754 +4072 3940 -31210863.52937 +4073 3940 17343750.0057 +3941 3941 1217261802.153 +3942 3941 -1.52587890625e-05 +3943 3941 -2.562999725342e-06 +3944 3941 179873780.5718 +3954 3941 -4.231929779053e-06 +3955 3941 -5.811452865601e-07 +3956 3941 -3642360.790142 +3957 3941 -1.54972076416e-05 +3958 3941 -1.907348632813e-06 +3959 3941 109872226.963 +3960 3941 -3.635883331299e-06 +3961 3941 -6.109476089478e-07 +3962 3941 -3642360.79014 +4032 3941 21679861.11823 +4033 3941 -17343750.00569 +4034 3941 -38039431.35476 +4035 3941 86719444.4302 +4036 3941 1.415610313416e-06 +4037 3941 -121047307.7997 +4038 3941 21679861.11823 +4039 3941 17343750.0057 +4040 3941 -38039431.35476 +4047 3941 7.182359695435e-06 +4048 3941 -69374999.9886 +4049 3941 -103546919.3888 +4050 3941 3.02791595459e-05 +4051 3941 4.619359970093e-06 +4052 3941 -289746007.2349 +4053 3941 8.165836334229e-06 +4054 3941 69374999.9886 +4055 3941 -103546919.3888 +4065 3941 -21679861.11823 +4066 3941 -17343750.0057 +4067 3941 -38039431.35476 +4068 3941 -86719444.43019 +4069 3941 8.940696716309e-07 +4070 3941 -121047307.7997 +4071 3941 -21679861.11823 +4072 3941 17343750.0057 +4073 3941 -38039431.35476 +3942 3942 1242901705.056 +3943 3942 64813887.58197 +3944 3942 -3.838539123535e-05 +3945 3942 47693290.89467 +3946 3942 -64813888.35975 +3947 3942 -7.510185241699e-06 +3957 3942 -88595068.35711 +3958 3942 -64813888.87825 +3959 3942 -4.26173210144e-06 +3960 3942 -229938603.1375 +3961 3942 -1.400709152222e-06 +3962 3942 -1.621246337891e-05 +3963 3942 -88595068.35711 +3964 3942 64813888.87826 +3965 3942 -3.75509262085e-06 +4035 3942 -36072082.53399 +4036 3942 16203472.22755 +4037 3942 21679861.11823 +4038 3942 -135326679.0277 +4039 3942 -16203472.0331 +4040 3942 86719444.24762 +4050 3942 -14659514.18418 +4051 3942 7.62939453125e-06 +4052 3942 7.152557373047e-06 +4053 3942 101875695.1567 +4054 3942 16203471.90348 +4055 3942 0.03654569387436 +4056 3942 -36808280.87074 +4057 3942 -16203472.09792 +4058 3942 21679860.74398 +4068 3942 -36072082.53397 +4069 3942 -16203472.22754 +4070 3942 -21679861.11823 +4071 3942 -113177912.5204 +4072 3942 6.407499313354e-07 +4073 3942 -86719444.43019 +4074 3942 -36072082.53397 +4075 3942 16203472.22755 +4076 3942 -21679861.11823 +3943 3943 1067897821.637 +3945 3943 -64813888.10049 +3946 3943 -179154367.6044 +3947 3943 -1.16229057312e-05 +3957 3943 -64813888.87825 +3958 3943 -69150192.34827 +3959 3943 -6.705522537231e-07 +3960 3943 7.748603820801e-07 +3961 3943 55243684.38681 +3962 3943 -1.788139343262e-06 +3963 3943 64813888.87826 +3964 3943 -69150192.34827 +3965 3943 -4.619359970093e-07 +4035 3943 16203472.22755 +4036 3943 -31210863.52938 +4037 3943 -17343750.00569 +4038 3943 -16203472.09792 +4039 3943 -59169888.51195 +4040 3943 17343749.94043 +4050 3943 8.970499038696e-06 +4051 3943 -76232648.10075 +4052 3943 -69374999.9886 +4053 3943 16203471.90348 +4054 3943 58124724.28025 +4055 3943 0.029221534729 +4056 3943 -16203472.03311 +4057 3943 -93520195.52346 +4058 3943 69374999.6084 +4068 3943 -16203472.22754 +4069 3943 -31210863.52937 +4070 3943 -17343750.0057 +4071 3943 -1.177191734314e-06 +4072 3943 -41882340.60421 +4073 3943 8.344650268555e-07 +4074 3943 16203472.22754 +4075 3943 -31210863.52937 +4076 3943 17343750.0057 +3944 3944 1220904161.253 +3945 3944 -7.390975952148e-06 +3946 3944 -9.536743164063e-06 +3947 3944 101973736.7139 +3957 3944 -4.231929779053e-06 +3958 3944 -5.811452865601e-07 +3959 3944 -3642360.790142 +3960 3944 -1.54972076416e-05 +3961 3944 -1.907348632813e-06 +3962 3944 109872226.963 +3963 3944 -3.635883331299e-06 +3964 3944 -6.109476089478e-07 +3965 3944 -3642360.79014 +4035 3944 21679861.11823 +4036 3944 -17343750.00569 +4037 3944 -38039431.35476 +4038 3944 86719444.24762 +4039 3944 17343749.9078 +4040 3944 -121957897.9018 +4050 3944 7.182359695435e-06 +4051 3944 -69374999.9886 +4052 3944 -103546919.3888 +4053 3944 -0.03648543357849 +4054 3944 -0.02920261025429 +4055 3944 -251706576.231 +4056 3944 21679860.55685 +4057 3944 69374999.49133 +4058 3944 -104457508.7431 +4068 3944 -21679861.11823 +4069 3944 -17343750.0057 +4070 3944 -38039431.35476 +4071 3944 -86719444.43019 +4072 3944 8.940696716309e-07 +4073 3944 -121047307.7997 +4074 3944 -21679861.11823 +4075 3944 17343750.0057 +4076 3944 -38039431.35476 +3945 3945 733825161.8322 +3946 3945 69874541.14581 +3947 3945 -2.193450927734e-05 +3960 3945 -88595068.35711 +3961 3945 -64813888.87825 +3962 3945 -4.26173210144e-06 +3963 3945 -357844273.7831 +3964 3945 -69875651.73839 +3965 3945 -1.645088195801e-05 +3966 3945 31270320.21803 +3967 3945 51852221.69519 +3968 3945 2.264976501465e-06 +4038 3945 -13923315.16199 +4039 3945 19444166.47861 +4040 3945 26015832.7805 +4053 3945 -36808280.87074 +4054 3945 -16203472.0331 +4055 3945 -21679860.55685 +4056 3945 42596488.85742 +4057 3945 17468662.4055 +4058 3945 17682222.18139 +4071 3945 -36072082.53397 +4072 3945 -16203472.22754 +4073 3945 -21679861.11823 +4074 3945 -139008174.7088 +4075 3945 -17469217.83142 +4076 3945 -88411110.90688 +4077 3945 -13881426.19349 +4078 3945 12963333.20796 +4079 3945 -18020555.17262 +3946 3946 630427502.0707 +3947 3946 -7.875263690948e-06 +3960 3946 -64813888.87825 +3961 3946 -69150192.34827 +3962 3946 -6.705522537231e-07 +3963 3946 -69876207.03469 +3964 3946 -50940301.31525 +3965 3946 -9.536743164063e-07 +3966 3946 77778332.54279 +3967 3946 35166790.002 +3968 3946 5.960464477539e-07 +4038 3946 12962777.65241 +4039 3946 -13923315.162 +4040 3946 -13874999.9393 +4053 3946 -16203472.09791 +4054 3946 -93520195.52345 +4055 3946 -69374999.49133 +4056 3946 17468662.4055 +4057 3946 16746172.7895 +4058 3946 14145833.18359 +4071 3946 -16203472.22754 +4072 3946 -31210863.52937 +4073 3946 -17343750.0057 +4074 3946 -17469495.54439 +4075 3946 -62281301.31302 +4076 3946 -18697916.56855 +4077 3946 19444999.81194 +4078 3946 -12907287.87322 +4079 3946 20270833.25379 +3947 3947 770466102.9009 +3960 3947 -4.231929779053e-06 +3961 3947 -5.811452865601e-07 +3962 3947 -3642360.790142 +3963 3947 -1.710653305054e-05 +3964 3947 -1.132488250732e-06 +3965 3947 28643285.85722 +3966 3947 2.98023223877e-06 +3967 3947 5.364418029785e-07 +3968 3947 79491050.79751 +4038 3947 17343888.52033 +4039 3947 -20812499.90894 +4040 3947 -37128840.43198 +4053 3947 -21679860.74397 +4054 3947 -69374999.6084 +4055 3947 -104457508.7431 +4056 3947 -17682222.18137 +4057 3947 -14145833.18358 +4058 3947 -183012919.9131 +4071 3947 -21679861.11823 +4072 3947 -17343750.0057 +4073 3947 -38039431.35476 +4074 3947 -88411110.90688 +4075 3947 -18697916.60118 +4076 3947 -124961466.3518 +4077 3947 -27030832.75893 +4078 3947 13062499.95656 +4079 3947 -37991274.83622 +3948 3948 1154306639.95 +3949 3948 4.053115844727e-06 +3950 3948 -5.984306335449e-05 +3951 3948 164134990.0133 +3952 3948 -4.798173904419e-06 +3953 3948 -1.537799835205e-05 +3969 3948 -229938603.1375 +3970 3948 -1.400709152222e-06 +3971 3948 -1.621246337891e-05 +3972 3948 -88595068.35711 +3973 3948 64813888.87826 +3974 3948 -3.75509262085e-06 +4041 3948 -113177912.5205 +4042 3948 -1.952052116394e-06 +4043 3948 86719444.4302 +4044 3948 -36072082.53399 +4045 3948 -16203472.22755 +4046 3948 21679861.11823 +4059 3948 65803613.40852 +4060 3948 4.112720489502e-06 +4061 3948 3.081560134888e-05 +4062 3948 -14659514.18418 +4063 3948 -1.010298728943e-05 +4064 3948 8.165836334229e-06 +4080 3948 -113177912.5204 +4081 3948 6.407499313354e-07 +4082 3948 -86719444.43019 +4083 3948 -36072082.53397 +4084 3948 16203472.22755 +4085 3948 -21679861.11823 +3949 3949 998747631.9559 +3950 3949 -6.675720214844e-06 +3951 3949 -3.397464752197e-06 +3952 3949 -82157545.53163 +3953 3949 -2.264976501465e-06 +3969 3949 7.748603820801e-07 +3970 3949 55243684.38681 +3971 3949 -1.788139343262e-06 +3972 3949 64813888.87826 +3973 3949 -69150192.34827 +3974 3949 -4.619359970093e-07 +4041 3949 -4.097819328308e-06 +4042 3949 -41882340.60423 +4043 3949 1.296401023865e-06 +4044 3949 -16203472.22755 +4045 3949 -31210863.52938 +4046 3949 17343750.0057 +4059 3949 4.053115844727e-06 +4060 3949 26913861.39084 +4061 3949 4.738569259644e-06 +4062 3949 -7.331371307373e-06 +4063 3949 -76232648.10076 +4064 3949 69374999.9886 +4080 3949 -1.177191734314e-06 +4081 3949 -41882340.60421 +4082 3949 8.344650268555e-07 +4083 3949 16203472.22754 +4084 3949 -31210863.52937 +4085 3949 17343750.0057 +3950 3950 1217261802.153 +3951 3950 -1.52587890625e-05 +3952 3950 -2.562999725342e-06 +3953 3950 179873780.5718 +3969 3950 -1.54972076416e-05 +3970 3950 -1.907348632813e-06 +3971 3950 109872226.963 +3972 3950 -3.635883331299e-06 +3973 3950 -6.109476089478e-07 +3974 3950 -3642360.79014 +4041 3950 86719444.4302 +4042 3950 1.415610313416e-06 +4043 3950 -121047307.7997 +4044 3950 21679861.11823 +4045 3950 17343750.0057 +4046 3950 -38039431.35476 +4059 3950 3.02791595459e-05 +4060 3950 4.619359970093e-06 +4061 3950 -289746007.2349 +4062 3950 8.165836334229e-06 +4063 3950 69374999.9886 +4064 3950 -103546919.3888 +4080 3950 -86719444.43019 +4081 3950 8.940696716309e-07 +4082 3950 -121047307.7997 +4083 3950 -21679861.11823 +4084 3950 17343750.0057 +4085 3950 -38039431.35476 +3951 3951 1154306639.95 +3952 3951 4.053115844727e-06 +3953 3951 -5.984306335449e-05 +3954 3951 164134990.0133 +3955 3951 -4.798173904419e-06 +3956 3951 -1.537799835205e-05 +3969 3951 -88595068.35711 +3970 3951 -64813888.87825 +3971 3951 -4.26173210144e-06 +3972 3951 -229938603.1375 +3973 3951 -1.400709152222e-06 +3974 3951 -1.621246337891e-05 +3975 3951 -88595068.35711 +3976 3951 64813888.87826 +3977 3951 -3.75509262085e-06 +4041 3951 -36072082.53399 +4042 3951 16203472.22755 +4043 3951 21679861.11823 +4044 3951 -113177912.5205 +4045 3951 -1.952052116394e-06 +4046 3951 86719444.4302 +4047 3951 -36072082.53399 +4048 3951 -16203472.22755 +4049 3951 21679861.11823 +4059 3951 -14659514.18418 +4060 3951 7.62939453125e-06 +4061 3951 7.152557373047e-06 +4062 3951 65803613.40852 +4063 3951 4.112720489502e-06 +4064 3951 3.081560134888e-05 +4065 3951 -14659514.18418 +4066 3951 -1.010298728943e-05 +4067 3951 8.165836334229e-06 +4080 3951 -36072082.53397 +4081 3951 -16203472.22754 +4082 3951 -21679861.11823 +4083 3951 -113177912.5204 +4084 3951 6.407499313354e-07 +4085 3951 -86719444.43019 +4086 3951 -36072082.53397 +4087 3951 16203472.22755 +4088 3951 -21679861.11823 +3952 3952 998747631.9559 +3953 3952 -6.675720214844e-06 +3954 3952 -3.397464752197e-06 +3955 3952 -82157545.53163 +3956 3952 -2.264976501465e-06 +3969 3952 -64813888.87825 +3970 3952 -69150192.34827 +3971 3952 -6.705522537231e-07 +3972 3952 7.748603820801e-07 +3973 3952 55243684.38681 +3974 3952 -1.788139343262e-06 +3975 3952 64813888.87826 +3976 3952 -69150192.34827 +3977 3952 -4.619359970093e-07 +4041 3952 16203472.22755 +4042 3952 -31210863.52938 +4043 3952 -17343750.00569 +4044 3952 -4.097819328308e-06 +4045 3952 -41882340.60423 +4046 3952 1.296401023865e-06 +4047 3952 -16203472.22755 +4048 3952 -31210863.52938 +4049 3952 17343750.0057 +4059 3952 8.970499038696e-06 +4060 3952 -76232648.10075 +4061 3952 -69374999.9886 +4062 3952 4.053115844727e-06 +4063 3952 26913861.39084 +4064 3952 4.738569259644e-06 +4065 3952 -7.331371307373e-06 +4066 3952 -76232648.10076 +4067 3952 69374999.9886 +4080 3952 -16203472.22754 +4081 3952 -31210863.52937 +4082 3952 -17343750.0057 +4083 3952 -1.177191734314e-06 +4084 3952 -41882340.60421 +4085 3952 8.344650268555e-07 +4086 3952 16203472.22754 +4087 3952 -31210863.52937 +4088 3952 17343750.0057 +3953 3953 1217261802.153 +3954 3953 -1.52587890625e-05 +3955 3953 -2.562999725342e-06 +3956 3953 179873780.5718 +3969 3953 -4.231929779053e-06 +3970 3953 -5.811452865601e-07 +3971 3953 -3642360.790142 +3972 3953 -1.54972076416e-05 +3973 3953 -1.907348632813e-06 +3974 3953 109872226.963 +3975 3953 -3.635883331299e-06 +3976 3953 -6.109476089478e-07 +3977 3953 -3642360.79014 +4041 3953 21679861.11823 +4042 3953 -17343750.00569 +4043 3953 -38039431.35476 +4044 3953 86719444.4302 +4045 3953 1.415610313416e-06 +4046 3953 -121047307.7997 +4047 3953 21679861.11823 +4048 3953 17343750.0057 +4049 3953 -38039431.35476 +4059 3953 7.182359695435e-06 +4060 3953 -69374999.9886 +4061 3953 -103546919.3888 +4062 3953 3.02791595459e-05 +4063 3953 4.619359970093e-06 +4064 3953 -289746007.2349 +4065 3953 8.165836334229e-06 +4066 3953 69374999.9886 +4067 3953 -103546919.3888 +4080 3953 -21679861.11823 +4081 3953 -17343750.0057 +4082 3953 -38039431.35476 +4083 3953 -86719444.43019 +4084 3953 8.940696716309e-07 +4085 3953 -121047307.7997 +4086 3953 -21679861.11823 +4087 3953 17343750.0057 +4088 3953 -38039431.35476 +3954 3954 1154306639.95 +3955 3954 4.053115844727e-06 +3956 3954 -5.984306335449e-05 +3957 3954 164134990.0133 +3958 3954 -4.798173904419e-06 +3959 3954 -1.537799835205e-05 +3972 3954 -88595068.35711 +3973 3954 -64813888.87825 +3974 3954 -4.26173210144e-06 +3975 3954 -229938603.1375 +3976 3954 -1.400709152222e-06 +3977 3954 -1.621246337891e-05 +3978 3954 -88595068.35711 +3979 3954 64813888.87826 +3980 3954 -3.75509262085e-06 +4044 3954 -36072082.53399 +4045 3954 16203472.22755 +4046 3954 21679861.11823 +4047 3954 -113177912.5205 +4048 3954 -1.952052116394e-06 +4049 3954 86719444.4302 +4050 3954 -36072082.53399 +4051 3954 -16203472.22755 +4052 3954 21679861.11823 +4062 3954 -14659514.18418 +4063 3954 7.62939453125e-06 +4064 3954 7.152557373047e-06 +4065 3954 65803613.40852 +4066 3954 4.112720489502e-06 +4067 3954 3.081560134888e-05 +4068 3954 -14659514.18418 +4069 3954 -1.010298728943e-05 +4070 3954 8.165836334229e-06 +4083 3954 -36072082.53397 +4084 3954 -16203472.22754 +4085 3954 -21679861.11823 +4086 3954 -113177912.5204 +4087 3954 6.407499313354e-07 +4088 3954 -86719444.43019 +4089 3954 -36072082.53397 +4090 3954 16203472.22755 +4091 3954 -21679861.11823 +3955 3955 998747631.9559 +3956 3955 -6.675720214844e-06 +3957 3955 -3.397464752197e-06 +3958 3955 -82157545.53163 +3959 3955 -2.264976501465e-06 +3972 3955 -64813888.87825 +3973 3955 -69150192.34827 +3974 3955 -6.705522537231e-07 +3975 3955 7.748603820801e-07 +3976 3955 55243684.38681 +3977 3955 -1.788139343262e-06 +3978 3955 64813888.87826 +3979 3955 -69150192.34827 +3980 3955 -4.619359970093e-07 +4044 3955 16203472.22755 +4045 3955 -31210863.52938 +4046 3955 -17343750.00569 +4047 3955 -4.097819328308e-06 +4048 3955 -41882340.60423 +4049 3955 1.296401023865e-06 +4050 3955 -16203472.22755 +4051 3955 -31210863.52938 +4052 3955 17343750.0057 +4062 3955 8.970499038696e-06 +4063 3955 -76232648.10075 +4064 3955 -69374999.9886 +4065 3955 4.053115844727e-06 +4066 3955 26913861.39084 +4067 3955 4.738569259644e-06 +4068 3955 -7.331371307373e-06 +4069 3955 -76232648.10076 +4070 3955 69374999.9886 +4083 3955 -16203472.22754 +4084 3955 -31210863.52937 +4085 3955 -17343750.0057 +4086 3955 -1.177191734314e-06 +4087 3955 -41882340.60421 +4088 3955 8.344650268555e-07 +4089 3955 16203472.22754 +4090 3955 -31210863.52937 +4091 3955 17343750.0057 +3956 3956 1217261802.153 +3957 3956 -1.52587890625e-05 +3958 3956 -2.562999725342e-06 +3959 3956 179873780.5718 +3972 3956 -4.231929779053e-06 +3973 3956 -5.811452865601e-07 +3974 3956 -3642360.790142 +3975 3956 -1.54972076416e-05 +3976 3956 -1.907348632813e-06 +3977 3956 109872226.963 +3978 3956 -3.635883331299e-06 +3979 3956 -6.109476089478e-07 +3980 3956 -3642360.79014 +4044 3956 21679861.11823 +4045 3956 -17343750.00569 +4046 3956 -38039431.35476 +4047 3956 86719444.4302 +4048 3956 1.415610313416e-06 +4049 3956 -121047307.7997 +4050 3956 21679861.11823 +4051 3956 17343750.0057 +4052 3956 -38039431.35476 +4062 3956 7.182359695435e-06 +4063 3956 -69374999.9886 +4064 3956 -103546919.3888 +4065 3956 3.02791595459e-05 +4066 3956 4.619359970093e-06 +4067 3956 -289746007.2349 +4068 3956 8.165836334229e-06 +4069 3956 69374999.9886 +4070 3956 -103546919.3888 +4083 3956 -21679861.11823 +4084 3956 -17343750.0057 +4085 3956 -38039431.35476 +4086 3956 -86719444.43019 +4087 3956 8.940696716309e-07 +4088 3956 -121047307.7997 +4089 3956 -21679861.11823 +4090 3956 17343750.0057 +4091 3956 -38039431.35476 +3957 3957 1154306639.95 +3958 3957 4.053115844727e-06 +3959 3957 -5.984306335449e-05 +3960 3957 164134990.0133 +3961 3957 -4.798173904419e-06 +3962 3957 -1.537799835205e-05 +3975 3957 -88595068.35711 +3976 3957 -64813888.87825 +3977 3957 -4.26173210144e-06 +3978 3957 -229938603.1375 +3979 3957 -1.400709152222e-06 +3980 3957 -1.621246337891e-05 +3981 3957 -88595068.35711 +3982 3957 64813888.87826 +3983 3957 -3.75509262085e-06 +4047 3957 -36072082.53399 +4048 3957 16203472.22755 +4049 3957 21679861.11823 +4050 3957 -113177912.5205 +4051 3957 -1.952052116394e-06 +4052 3957 86719444.4302 +4053 3957 -36072082.53399 +4054 3957 -16203472.22755 +4055 3957 21679861.11823 +4065 3957 -14659514.18418 +4066 3957 7.62939453125e-06 +4067 3957 7.152557373047e-06 +4068 3957 65803613.40852 +4069 3957 4.112720489502e-06 +4070 3957 3.081560134888e-05 +4071 3957 -14659514.18418 +4072 3957 -1.010298728943e-05 +4073 3957 8.165836334229e-06 +4086 3957 -36072082.53397 +4087 3957 -16203472.22754 +4088 3957 -21679861.11823 +4089 3957 -113177912.5204 +4090 3957 6.407499313354e-07 +4091 3957 -86719444.43019 +4092 3957 -36072082.53397 +4093 3957 16203472.22755 +4094 3957 -21679861.11823 +3958 3958 998747631.9559 +3959 3958 -6.675720214844e-06 +3960 3958 -3.397464752197e-06 +3961 3958 -82157545.53163 +3962 3958 -2.264976501465e-06 +3975 3958 -64813888.87825 +3976 3958 -69150192.34827 +3977 3958 -6.705522537231e-07 +3978 3958 7.748603820801e-07 +3979 3958 55243684.38681 +3980 3958 -1.788139343262e-06 +3981 3958 64813888.87826 +3982 3958 -69150192.34827 +3983 3958 -4.619359970093e-07 +4047 3958 16203472.22755 +4048 3958 -31210863.52938 +4049 3958 -17343750.00569 +4050 3958 -4.097819328308e-06 +4051 3958 -41882340.60423 +4052 3958 1.296401023865e-06 +4053 3958 -16203472.22755 +4054 3958 -31210863.52938 +4055 3958 17343750.0057 +4065 3958 8.970499038696e-06 +4066 3958 -76232648.10075 +4067 3958 -69374999.9886 +4068 3958 4.053115844727e-06 +4069 3958 26913861.39084 +4070 3958 4.738569259644e-06 +4071 3958 -7.331371307373e-06 +4072 3958 -76232648.10076 +4073 3958 69374999.9886 +4086 3958 -16203472.22754 +4087 3958 -31210863.52937 +4088 3958 -17343750.0057 +4089 3958 -1.177191734314e-06 +4090 3958 -41882340.60421 +4091 3958 8.344650268555e-07 +4092 3958 16203472.22754 +4093 3958 -31210863.52937 +4094 3958 17343750.0057 +3959 3959 1217261802.153 +3960 3959 -1.52587890625e-05 +3961 3959 -2.562999725342e-06 +3962 3959 179873780.5718 +3975 3959 -4.231929779053e-06 +3976 3959 -5.811452865601e-07 +3977 3959 -3642360.790142 +3978 3959 -1.54972076416e-05 +3979 3959 -1.907348632813e-06 +3980 3959 109872226.963 +3981 3959 -3.635883331299e-06 +3982 3959 -6.109476089478e-07 +3983 3959 -3642360.79014 +4047 3959 21679861.11823 +4048 3959 -17343750.00569 +4049 3959 -38039431.35476 +4050 3959 86719444.4302 +4051 3959 1.415610313416e-06 +4052 3959 -121047307.7997 +4053 3959 21679861.11823 +4054 3959 17343750.0057 +4055 3959 -38039431.35476 +4065 3959 7.182359695435e-06 +4066 3959 -69374999.9886 +4067 3959 -103546919.3888 +4068 3959 3.02791595459e-05 +4069 3959 4.619359970093e-06 +4070 3959 -289746007.2349 +4071 3959 8.165836334229e-06 +4072 3959 69374999.9886 +4073 3959 -103546919.3888 +4086 3959 -21679861.11823 +4087 3959 -17343750.0057 +4088 3959 -38039431.35476 +4089 3959 -86719444.43019 +4090 3959 8.940696716309e-07 +4091 3959 -121047307.7997 +4092 3959 -21679861.11823 +4093 3959 17343750.0057 +4094 3959 -38039431.35476 +3960 3960 1154306639.95 +3961 3960 4.053115844727e-06 +3962 3960 -5.984306335449e-05 +3963 3960 164134990.0133 +3964 3960 -4.798173904419e-06 +3965 3960 -1.537799835205e-05 +3978 3960 -88595068.35711 +3979 3960 -64813888.87825 +3980 3960 -4.26173210144e-06 +3981 3960 -229938603.1375 +3982 3960 -1.400709152222e-06 +3983 3960 -1.621246337891e-05 +3984 3960 -88595068.35711 +3985 3960 64813888.87826 +3986 3960 -3.75509262085e-06 +4050 3960 -36072082.53399 +4051 3960 16203472.22755 +4052 3960 21679861.11823 +4053 3960 -113177912.5205 +4054 3960 -1.952052116394e-06 +4055 3960 86719444.4302 +4056 3960 -36072082.53399 +4057 3960 -16203472.22755 +4058 3960 21679861.11823 +4068 3960 -14659514.18418 +4069 3960 7.62939453125e-06 +4070 3960 7.152557373047e-06 +4071 3960 65803613.40852 +4072 3960 4.112720489502e-06 +4073 3960 3.081560134888e-05 +4074 3960 -14659514.18418 +4075 3960 -1.010298728943e-05 +4076 3960 8.165836334229e-06 +4089 3960 -36072082.53397 +4090 3960 -16203472.22754 +4091 3960 -21679861.11823 +4092 3960 -113177912.5204 +4093 3960 6.407499313354e-07 +4094 3960 -86719444.43019 +4095 3960 -36072082.53397 +4096 3960 16203472.22755 +4097 3960 -21679861.11823 +3961 3961 998747631.9559 +3962 3961 -6.675720214844e-06 +3963 3961 -3.397464752197e-06 +3964 3961 -82157545.53163 +3965 3961 -2.264976501465e-06 +3978 3961 -64813888.87825 +3979 3961 -69150192.34827 +3980 3961 -6.705522537231e-07 +3981 3961 7.748603820801e-07 +3982 3961 55243684.38681 +3983 3961 -1.788139343262e-06 +3984 3961 64813888.87826 +3985 3961 -69150192.34827 +3986 3961 -4.619359970093e-07 +4050 3961 16203472.22755 +4051 3961 -31210863.52938 +4052 3961 -17343750.00569 +4053 3961 -4.097819328308e-06 +4054 3961 -41882340.60423 +4055 3961 1.296401023865e-06 +4056 3961 -16203472.22755 +4057 3961 -31210863.52938 +4058 3961 17343750.0057 +4068 3961 8.970499038696e-06 +4069 3961 -76232648.10075 +4070 3961 -69374999.9886 +4071 3961 4.053115844727e-06 +4072 3961 26913861.39084 +4073 3961 4.738569259644e-06 +4074 3961 -7.331371307373e-06 +4075 3961 -76232648.10076 +4076 3961 69374999.9886 +4089 3961 -16203472.22754 +4090 3961 -31210863.52937 +4091 3961 -17343750.0057 +4092 3961 -1.177191734314e-06 +4093 3961 -41882340.60421 +4094 3961 8.344650268555e-07 +4095 3961 16203472.22754 +4096 3961 -31210863.52937 +4097 3961 17343750.0057 +3962 3962 1217261802.153 +3963 3962 -1.52587890625e-05 +3964 3962 -2.562999725342e-06 +3965 3962 179873780.5718 +3978 3962 -4.231929779053e-06 +3979 3962 -5.811452865601e-07 +3980 3962 -3642360.790142 +3981 3962 -1.54972076416e-05 +3982 3962 -1.907348632813e-06 +3983 3962 109872226.963 +3984 3962 -3.635883331299e-06 +3985 3962 -6.109476089478e-07 +3986 3962 -3642360.79014 +4050 3962 21679861.11823 +4051 3962 -17343750.00569 +4052 3962 -38039431.35476 +4053 3962 86719444.4302 +4054 3962 1.415610313416e-06 +4055 3962 -121047307.7997 +4056 3962 21679861.11823 +4057 3962 17343750.0057 +4058 3962 -38039431.35476 +4068 3962 7.182359695435e-06 +4069 3962 -69374999.9886 +4070 3962 -103546919.3888 +4071 3962 3.02791595459e-05 +4072 3962 4.619359970093e-06 +4073 3962 -289746007.2349 +4074 3962 8.165836334229e-06 +4075 3962 69374999.9886 +4076 3962 -103546919.3888 +4089 3962 -21679861.11823 +4090 3962 -17343750.0057 +4091 3962 -38039431.35476 +4092 3962 -86719444.43019 +4093 3962 8.940696716309e-07 +4094 3962 -121047307.7997 +4095 3962 -21679861.11823 +4096 3962 17343750.0057 +4097 3962 -38039431.35476 +3963 3963 1264143404.142 +3964 3963 69984496.09991 +3965 3963 -4.60147857666e-05 +3966 3963 56216718.86035 +3967 3963 -62295134.49991 +3968 3963 -1.907348632813e-06 +3981 3963 -88595068.35711 +3982 3963 -64813888.87825 +3983 3963 -4.26173210144e-06 +3984 3963 -235044286.8786 +3985 3963 -2540789.090044 +3986 3963 -1.227855682373e-05 +3987 3963 -95281145.7069 +3988 3963 64727634.52473 +3989 3963 3.665685653687e-06 +4053 3963 -36072082.53399 +4054 3963 16203472.22755 +4055 3963 21679861.11823 +4056 3963 -139008174.7088 +4057 3963 -17469495.54439 +4058 3963 88411110.90689 +4071 3963 -14659514.18418 +4072 3963 7.62939453125e-06 +4073 3963 7.152557373047e-06 +4074 3963 104477359.7431 +4075 3963 17496498.94787 +4076 3963 0.03796523809433 +4077 3963 -35761582.98115 +4078 3963 -15574117.3542 +4079 3963 21679166.28526 +4092 3963 -36072082.53397 +4093 3963 -16203472.22754 +4094 3963 -21679861.11823 +4095 3963 -114725173.6726 +4096 3963 -635141.4411426 +4097 3963 -87564583.31886 +4098 3963 -37743330.80579 +4099 3963 16182255.39186 +4100 3963 -22525694.45184 +3964 3964 1075589634.327 +3965 3964 1.347064971924e-05 +3966 3964 -62295134.24065 +3967 3964 -170484887.2684 +3968 3964 -5.185604095459e-06 +3981 3964 -64813888.87825 +3982 3964 -69150192.34827 +3983 3964 -6.705522537231e-07 +3984 3964 -2541344.645598 +3985 3964 52569923.74254 +3986 3964 6.318092346191e-06 +3987 3964 64727634.52473 +3988 3964 -67141169.32472 +3989 3964 4.619359970093e-07 +4053 3964 16203472.22755 +4054 3964 -31210863.52938 +4055 3964 -17343750.00569 +4056 3964 -17469217.83143 +4057 3964 -62281301.31304 +4058 3964 18697916.60118 +4071 3964 8.970499038696e-06 +4072 3964 -76232648.10075 +4073 3964 -69374999.9886 +4074 3964 17496498.94786 +4075 3964 57338323.8368 +4076 3964 0.03035295009613 +4077 3964 -15574117.28939 +4078 3964 -92438199.00546 +4079 3964 69374999.59698 +4092 3964 -16203472.22754 +4093 3964 -31210863.52937 +4094 3964 -17343750.0057 +4095 3964 -635419.218922 +4096 3964 -42820844.07815 +4097 3964 -677083.3331566 +4098 3964 16182255.39186 +4099 3964 -30708185.95798 +4100 3964 16666666.67214 +3965 3965 1236468691.55 +3966 3965 -1.54972076416e-06 +3967 3965 -5.036592483521e-06 +3968 3965 109730878.4261 +3981 3965 -4.231929779053e-06 +3982 3965 -5.811452865601e-07 +3983 3965 -3642360.790142 +3984 3965 -1.358985900879e-05 +3985 3965 5.960464477539e-06 +3986 3965 108515321.757 +3987 3965 3.635883331299e-06 +3988 3965 4.768371582031e-07 +3989 3965 -4919850.093644 +4053 3965 21679861.11823 +4054 3965 -17343750.00569 +4055 3965 -38039431.35476 +4056 3965 88411110.90689 +4057 3965 18697916.56855 +4058 3965 -124961466.3518 +4071 3965 7.182359695435e-06 +4072 3965 -69374999.9886 +4073 3965 -103546919.3888 +4074 3965 -0.03791528940201 +4075 3965 -0.0303518474102 +4076 3965 -255045254.8364 +4077 3965 21679166.091 +4078 3965 69374999.47419 +4079 3965 -105409529.5055 +4092 3965 -21679861.11823 +4093 3965 -17343750.0057 +4094 3965 -38039431.35476 +4095 3965 -87564583.31903 +4096 3965 -677083.3332901 +4097 3965 -122106772.304 +4098 3965 -22525694.45184 +4099 3965 16666666.67214 +4100 3965 -38356746.04355 +3966 3966 696472573.0656 +3967 3966 -1771689.826602 +3968 3966 -2.384185791016e-07 +3984 3966 -87258192.16973 +3985 3966 -64804100.71711 +3986 3966 -4.500150680542e-06 +3987 3966 -242104687.4354 +3988 3966 -3424057.139938 +3989 3966 -7.450580596924e-07 +3990 3966 75831742.92238 +3991 3966 -11180768.61541 +3992 3966 -2.384185791016e-06 +3993 3966 -95109676.42566 +3994 3966 65697417.99692 +3995 3966 6.496906280518e-06 +4056 3966 -13881426.19349 +4057 3966 19444999.81194 +4058 3966 27030832.75893 +4074 3966 -35761582.98116 +4075 3966 -15574117.28939 +4076 3966 -21679166.091 +4077 3966 24368704.92005 +4078 3966 -442931.9479949 +4079 3966 17135277.77496 +4095 3966 -35737549.44071 +4096 3966 -16201372.34961 +4097 3966 -21679166.67379 +4098 3966 -113694268.311 +4099 3966 -856032.6284447 +4100 3966 -85676388.87482 +4101 3966 -6373939.007678 +4102 3966 -2795252.051776 +4103 3966 3215972.223778 +4104 3966 -36574674.40711 +4105 3966 16424706.45526 +4106 3966 -21159027.78473 +3967 3967 713868420.1604 +3968 3967 2.801418304443e-05 +3984 3967 -64804100.71711 +3985 3967 -69555876.00861 +3986 3967 2.98023223877e-08 +3987 3967 -3424057.139937 +3988 3967 46038548.55542 +3989 3967 1.448392868042e-05 +3990 3967 14745342.49145 +3991 3967 -46950609.66778 +3992 3967 -3.695487976074e-06 +3993 3967 65697417.99692 +3994 3967 -72763586.73756 +3995 3967 -7.003545761108e-07 +4056 3967 12963333.20796 +4057 3967 -12907287.87322 +4058 3967 -13062499.95656 +4074 3967 -15574117.3542 +4075 3967 -92438199.00548 +4076 3967 -69374999.4742 +4077 3967 -442931.947997 +4078 3967 28717759.88727 +4079 3967 7208333.185863 +4095 3967 -16201372.34961 +4096 3967 -31311875.5651 +4097 3967 -17343750.0057 +4098 3967 -856032.6284447 +4099 3967 -41656915.6643 +4100 3967 -677083.3331583 +4101 3967 3686414.617019 +4102 3967 -37070184.92824 +4103 3967 33333333.32785 +4104 3967 16424706.45526 +4105 3967 -30988032.27199 +4106 3967 16666666.67214 +3968 3968 808185795.7469 +3984 3968 -4.559755325317e-06 +3985 3968 8.940696716309e-08 +3986 3968 -3390328.224569 +3987 3968 -8.344650268555e-07 +3988 3968 1.460313796997e-05 +3989 3968 96899236.61813 +3990 3968 3.576278686523e-07 +3991 3968 -3.904104232788e-06 +3992 3968 79524039.77178 +3993 3968 6.049871444702e-06 +3994 3968 -7.003545761108e-07 +3995 3968 -9590542.374578 +4056 3968 18020555.17262 +4057 3968 -20270833.25379 +4058 3968 -37991274.83623 +4074 3968 -21679166.28526 +4075 3968 -69374999.59698 +4076 3968 -105409529.5055 +4077 3968 -17135277.77496 +4078 3968 -7208333.18587 +4079 3968 -197291006.784 +4095 3968 -21679166.67379 +4096 3968 -17343750.0057 +4097 3968 -37974357.38229 +4098 3968 -85676388.87482 +4099 3968 -677083.3332918 +4100 3968 -117552803.5799 +4101 3968 -4909027.779057 +4102 3968 33333333.32785 +4103 3968 -47671313.32517 +4104 3968 -21159027.78473 +4105 3968 16666666.67214 +4106 3968 -36522342.37636 +3969 3969 577153319.975 +3970 3969 -3.814697265625e-06 +3971 3969 -3.170967102051e-05 +3972 3969 82067495.00666 +3973 3969 12962777.77565 +3974 3969 -7.867813110352e-06 +4059 3969 -113177912.5205 +4060 3969 -1.952052116394e-06 +4061 3969 86719444.4302 +4062 3969 -36072082.53399 +4063 3969 -16203472.22755 +4064 3969 21679861.11823 +4080 3969 32901806.70425 +4081 3969 2.026557922363e-06 +4082 3969 -17343888.88602 +4083 3969 -7329757.09209 +4084 3969 3240694.445505 +4085 3969 -4335972.223642 +3970 3970 499373815.978 +3971 3970 1.025199890137e-05 +3972 3970 -12962777.77565 +3973 3970 -41078772.7658 +3974 3970 2.264976501465e-06 +4059 3970 -4.097819328308e-06 +4060 3970 -41882340.60423 +4061 3970 1.296401023865e-06 +4062 3970 -16203472.22755 +4063 3970 -31210863.52938 +4064 3970 17343750.0057 +4080 3970 1.430511474609e-06 +4081 3970 13456930.69541 +4082 3970 -4.410743713379e-06 +4083 3970 -3240694.445512 +4084 3970 -38116324.05037 +4085 3970 34687499.9943 +3971 3971 608630901.0765 +3972 3971 -7.867813110352e-06 +3973 3971 2.115964889526e-06 +3974 3971 89936890.28591 +4059 3971 86719444.4302 +4060 3971 1.415610313416e-06 +4061 3971 -121047307.7997 +4062 3971 21679861.11823 +4063 3971 17343750.0057 +4064 3971 -38039431.35476 +4080 3971 17343888.88605 +4081 3971 -4.410743713379e-06 +4082 3971 -144873003.6175 +4083 3971 4335972.22365 +4084 3971 34687499.9943 +4085 3971 -51773459.69442 +3972 3972 577153319.975 +3973 3972 -3.814697265625e-06 +3974 3972 -3.170967102051e-05 +3975 3972 82067495.00666 +3976 3972 12962777.77565 +3977 3972 -7.867813110352e-06 +4059 3972 -36072082.53399 +4060 3972 16203472.22755 +4061 3972 21679861.11823 +4062 3972 -113177912.5205 +4063 3972 -1.952052116394e-06 +4064 3972 86719444.4302 +4065 3972 -36072082.53399 +4066 3972 -16203472.22755 +4067 3972 21679861.11823 +4080 3972 -7329757.092094 +4081 3972 -3240694.445505 +4082 3972 -4335972.223642 +4083 3972 32901806.70425 +4084 3972 2.026557922363e-06 +4085 3972 -17343888.88602 +4086 3972 -7329757.09209 +4087 3972 3240694.445505 +4088 3972 -4335972.223642 +3973 3973 499373815.978 +3974 3973 1.025199890137e-05 +3975 3973 -12962777.77565 +3976 3973 -41078772.7658 +3977 3973 2.264976501465e-06 +4059 3973 16203472.22755 +4060 3973 -31210863.52938 +4061 3973 -17343750.00569 +4062 3973 -4.097819328308e-06 +4063 3973 -41882340.60423 +4064 3973 1.296401023865e-06 +4065 3973 -16203472.22755 +4066 3973 -31210863.52938 +4067 3973 17343750.0057 +4080 3973 3240694.445514 +4081 3973 -38116324.05038 +4082 3973 -34687499.9943 +4083 3973 1.430511474609e-06 +4084 3973 13456930.69541 +4085 3973 -4.410743713379e-06 +4086 3973 -3240694.445512 +4087 3973 -38116324.05037 +4088 3973 34687499.9943 +3974 3974 608630901.0765 +3975 3974 -7.867813110352e-06 +3976 3974 2.115964889526e-06 +3977 3974 89936890.28591 +4059 3974 21679861.11823 +4060 3974 -17343750.00569 +4061 3974 -38039431.35476 +4062 3974 86719444.4302 +4063 3974 1.415610313416e-06 +4064 3974 -121047307.7997 +4065 3974 21679861.11823 +4066 3974 17343750.0057 +4067 3974 -38039431.35476 +4080 3974 4335972.22365 +4081 3974 -34687499.9943 +4082 3974 -51773459.69442 +4083 3974 17343888.88605 +4084 3974 -4.410743713379e-06 +4085 3974 -144873003.6175 +4086 3974 4335972.22365 +4087 3974 34687499.9943 +4088 3974 -51773459.69442 +3975 3975 577153319.975 +3976 3975 -3.814697265625e-06 +3977 3975 -3.170967102051e-05 +3978 3975 82067495.00666 +3979 3975 12962777.77565 +3980 3975 -7.867813110352e-06 +4062 3975 -36072082.53399 +4063 3975 16203472.22755 +4064 3975 21679861.11823 +4065 3975 -113177912.5205 +4066 3975 -1.952052116394e-06 +4067 3975 86719444.4302 +4068 3975 -36072082.53399 +4069 3975 -16203472.22755 +4070 3975 21679861.11823 +4083 3975 -7329757.092094 +4084 3975 -3240694.445505 +4085 3975 -4335972.223642 +4086 3975 32901806.70425 +4087 3975 2.026557922363e-06 +4088 3975 -17343888.88602 +4089 3975 -7329757.09209 +4090 3975 3240694.445505 +4091 3975 -4335972.223642 +3976 3976 499373815.978 +3977 3976 1.025199890137e-05 +3978 3976 -12962777.77565 +3979 3976 -41078772.7658 +3980 3976 2.264976501465e-06 +4062 3976 16203472.22755 +4063 3976 -31210863.52938 +4064 3976 -17343750.00569 +4065 3976 -4.097819328308e-06 +4066 3976 -41882340.60423 +4067 3976 1.296401023865e-06 +4068 3976 -16203472.22755 +4069 3976 -31210863.52938 +4070 3976 17343750.0057 +4083 3976 3240694.445514 +4084 3976 -38116324.05038 +4085 3976 -34687499.9943 +4086 3976 1.430511474609e-06 +4087 3976 13456930.69541 +4088 3976 -4.410743713379e-06 +4089 3976 -3240694.445512 +4090 3976 -38116324.05037 +4091 3976 34687499.9943 +3977 3977 608630901.0765 +3978 3977 -7.867813110352e-06 +3979 3977 2.115964889526e-06 +3980 3977 89936890.28591 +4062 3977 21679861.11823 +4063 3977 -17343750.00569 +4064 3977 -38039431.35476 +4065 3977 86719444.4302 +4066 3977 1.415610313416e-06 +4067 3977 -121047307.7997 +4068 3977 21679861.11823 +4069 3977 17343750.0057 +4070 3977 -38039431.35476 +4083 3977 4335972.22365 +4084 3977 -34687499.9943 +4085 3977 -51773459.69442 +4086 3977 17343888.88605 +4087 3977 -4.410743713379e-06 +4088 3977 -144873003.6175 +4089 3977 4335972.22365 +4090 3977 34687499.9943 +4091 3977 -51773459.69442 +3978 3978 577153319.975 +3979 3978 -3.814697265625e-06 +3980 3978 -3.170967102051e-05 +3981 3978 82067495.00666 +3982 3978 12962777.77565 +3983 3978 -7.867813110352e-06 +4065 3978 -36072082.53399 +4066 3978 16203472.22755 +4067 3978 21679861.11823 +4068 3978 -113177912.5205 +4069 3978 -1.952052116394e-06 +4070 3978 86719444.4302 +4071 3978 -36072082.53399 +4072 3978 -16203472.22755 +4073 3978 21679861.11823 +4086 3978 -7329757.092094 +4087 3978 -3240694.445505 +4088 3978 -4335972.223642 +4089 3978 32901806.70425 +4090 3978 2.026557922363e-06 +4091 3978 -17343888.88602 +4092 3978 -7329757.09209 +4093 3978 3240694.445505 +4094 3978 -4335972.223642 +3979 3979 499373815.978 +3980 3979 1.025199890137e-05 +3981 3979 -12962777.77565 +3982 3979 -41078772.7658 +3983 3979 2.264976501465e-06 +4065 3979 16203472.22755 +4066 3979 -31210863.52938 +4067 3979 -17343750.00569 +4068 3979 -4.097819328308e-06 +4069 3979 -41882340.60423 +4070 3979 1.296401023865e-06 +4071 3979 -16203472.22755 +4072 3979 -31210863.52938 +4073 3979 17343750.0057 +4086 3979 3240694.445514 +4087 3979 -38116324.05038 +4088 3979 -34687499.9943 +4089 3979 1.430511474609e-06 +4090 3979 13456930.69541 +4091 3979 -4.410743713379e-06 +4092 3979 -3240694.445512 +4093 3979 -38116324.05037 +4094 3979 34687499.9943 +3980 3980 608630901.0765 +3981 3980 -7.867813110352e-06 +3982 3980 2.115964889526e-06 +3983 3980 89936890.28591 +4065 3980 21679861.11823 +4066 3980 -17343750.00569 +4067 3980 -38039431.35476 +4068 3980 86719444.4302 +4069 3980 1.415610313416e-06 +4070 3980 -121047307.7997 +4071 3980 21679861.11823 +4072 3980 17343750.0057 +4073 3980 -38039431.35476 +4086 3980 4335972.22365 +4087 3980 -34687499.9943 +4088 3980 -51773459.69442 +4089 3980 17343888.88605 +4090 3980 -4.410743713379e-06 +4091 3980 -144873003.6175 +4092 3980 4335972.22365 +4093 3980 34687499.9943 +4094 3980 -51773459.69442 +3981 3981 577153319.975 +3982 3981 -3.814697265625e-06 +3983 3981 -3.170967102051e-05 +3984 3981 82067495.00666 +3985 3981 12962777.77565 +3986 3981 -7.867813110352e-06 +4068 3981 -36072082.53399 +4069 3981 16203472.22755 +4070 3981 21679861.11823 +4071 3981 -113177912.5205 +4072 3981 -1.952052116394e-06 +4073 3981 86719444.4302 +4074 3981 -36072082.53399 +4075 3981 -16203472.22755 +4076 3981 21679861.11823 +4089 3981 -7329757.092094 +4090 3981 -3240694.445505 +4091 3981 -4335972.223642 +4092 3981 32901806.70425 +4093 3981 2.026557922363e-06 +4094 3981 -17343888.88602 +4095 3981 -7329757.09209 +4096 3981 3240694.445505 +4097 3981 -4335972.223642 +3982 3982 499373815.978 +3983 3982 1.025199890137e-05 +3984 3982 -12962777.77565 +3985 3982 -41078772.7658 +3986 3982 2.264976501465e-06 +4068 3982 16203472.22755 +4069 3982 -31210863.52938 +4070 3982 -17343750.00569 +4071 3982 -4.097819328308e-06 +4072 3982 -41882340.60423 +4073 3982 1.296401023865e-06 +4074 3982 -16203472.22755 +4075 3982 -31210863.52938 +4076 3982 17343750.0057 +4089 3982 3240694.445514 +4090 3982 -38116324.05038 +4091 3982 -34687499.9943 +4092 3982 1.430511474609e-06 +4093 3982 13456930.69541 +4094 3982 -4.410743713379e-06 +4095 3982 -3240694.445512 +4096 3982 -38116324.05037 +4097 3982 34687499.9943 +3983 3983 608630901.0765 +3984 3983 -7.867813110352e-06 +3985 3983 2.115964889526e-06 +3986 3983 89936890.28591 +4068 3983 21679861.11823 +4069 3983 -17343750.00569 +4070 3983 -38039431.35476 +4071 3983 86719444.4302 +4072 3983 1.415610313416e-06 +4073 3983 -121047307.7997 +4074 3983 21679861.11823 +4075 3983 17343750.0057 +4076 3983 -38039431.35476 +4089 3983 4335972.22365 +4090 3983 -34687499.9943 +4091 3983 -51773459.69442 +4092 3983 17343888.88605 +4093 3983 -4.410743713379e-06 +4094 3983 -144873003.6175 +4095 3983 4335972.22365 +4096 3983 34687499.9943 +4097 3983 -51773459.69442 +3984 3984 578486932.6103 +3985 3984 11986.19510341 +3986 3984 -2.169609069824e-05 +3987 3984 84494256.20949 +3988 3984 15482348.065 +3989 3984 1.311302185059e-06 +4071 3984 -36072082.53399 +4072 3984 16203472.22755 +4073 3984 21679861.11823 +4074 3984 -114725173.6726 +4075 3984 -635419.2189152 +4076 3984 87564583.31904 +4077 3984 -35737549.44071 +4078 3984 -16201372.3496 +4079 3984 21679166.67379 +4092 3984 -7329757.092094 +4093 3984 -3240694.445505 +4094 3984 -4335972.223642 +4095 3984 33240013.48478 +4096 3984 3343.827772319 +4097 3984 -17343611.10825 +4098 3984 -6449228.918503 +4099 3984 3870669.958714 +4100 3984 -5182361.112478 +3985 3985 498972289.4165 +3986 3985 2.264976501465e-05 +3987 3985 -10443763.04186 +3988 3985 -37606235.61531 +3989 3985 1.877546310425e-06 +4071 3985 16203472.22755 +4072 3985 -31210863.52938 +4073 3985 -17343750.00569 +4074 3985 -635141.4411397 +4075 3985 -42820844.07817 +4076 3985 677083.3332876 +4077 3985 -16201372.3496 +4078 3985 -31311875.56509 +4079 3985 17343750.00569 +4092 3985 3240694.445514 +4093 3985 -38116324.05038 +4094 3985 -34687499.9943 +4095 3985 3343.827771783 +4096 3985 13361135.04474 +4097 3985 -6.437301635742e-06 +4098 3985 -2610996.710082 +4099 3985 -36975005.99484 +4100 3985 34010416.66101 +3986 3986 608877037.9683 +3987 3986 -3.576278686523e-07 +3988 3986 1.966953277588e-06 +3989 3986 90773136.12632 +4071 3986 21679861.11823 +4072 3986 -17343750.00569 +4073 3986 -38039431.35476 +4074 3986 87564583.31887 +4075 3986 677083.3331542 +4076 3986 -122106772.304 +4077 3986 21679166.67379 +4078 3986 17343750.00569 +4079 3986 -37974357.38228 +4092 3986 4335972.22365 +4093 3986 -34687499.9943 +4094 3986 -51773459.69442 +4095 3986 17343611.10827 +4096 3986 -6.526708602905e-06 +4097 3986 -144801169.7145 +4098 3986 3489305.557202 +4099 3986 34010416.66114 +4100 3986 -50834884.67833 +3987 3987 576078114.5405 +3988 3987 -1636006.338362 +3989 3987 -1.192092895508e-06 +3990 3987 -84575033.27924 +3991 3987 -63933137.53737 +3992 3987 -5.602836608887e-06 +3993 3987 80892647.57501 +3994 3987 14709329.53279 +3995 3987 1.072883605957e-06 +4074 3987 -37743330.8058 +4075 3987 16182255.39187 +4076 3987 22525694.45184 +4077 3987 -113694268.311 +4078 3987 -856032.628432 +4079 3987 85676388.87482 +4095 3987 -6449228.918515 +4096 3987 -2610996.710082 +4097 3987 -3489305.557202 +4098 3987 37710239.3424 +4099 3987 -409010.3490507 +4100 3987 -17135277.77496 +4101 3987 -33940957.18403 +4102 3987 -15983626.88872 +4103 3987 20312500.00667 +4104 3987 -5631106.840498 +4105 3987 3677411.184425 +4106 3987 -5078333.3345 +3988 3988 489693679.98 +3989 3988 3.409385681152e-05 +3990 3988 -63933137.53736 +3991 3988 -68813095.55765 +3992 3988 -9.238719940186e-07 +3993 3988 -11216781.57407 +3994 3988 -42667576.13433 +3995 3988 6.556510925293e-07 +4074 3988 16182255.39187 +4075 3988 -30708185.95799 +4076 3988 -16666666.67214 +4077 3988 -856032.6284325 +4078 3988 -41656915.6643 +4079 3988 677083.3332858 +4095 3988 3870669.958715 +4096 3988 -36975005.99487 +4097 3988 -34010416.66115 +4098 3988 -409010.3490478 +4099 3988 16113667.92119 +4100 3988 -7.688999176025e-06 +4101 3988 -15983626.88872 +4102 3988 -30000388.31333 +4103 3988 16666666.67214 +4104 3988 -2804255.48437 +4105 3988 -36521824.70809 +4106 3988 33333333.32785 +3989 3989 591348648.5328 +3990 3989 -5.483627319336e-06 +3991 3989 -9.536743164063e-07 +3992 3989 -5640051.194669 +3993 3989 -1.072883605957e-06 +3994 3989 5.960464477539e-07 +3995 3989 83549951.75354 +4074 3989 22525694.45184 +4075 3989 -16666666.67214 +4076 3989 -38356746.04356 +4077 3989 85676388.87482 +4078 3989 677083.3331523 +4079 3989 -117552803.5799 +4095 3989 5182361.112479 +4096 3989 -34010416.66102 +4097 3989 -50834884.67835 +4098 3989 17135277.77496 +4099 3989 -7.659196853638e-06 +4100 3989 -135659337.8091 +4101 3989 20312500.00667 +4102 3989 16666666.67214 +4103 3989 -35534698.41771 +4104 3989 3385277.779223 +4105 3989 33333333.32785 +4106 3989 -48057936.71774 +3990 3990 278277688.0438 +3991 3990 63032990.82913 +3992 3990 7.867813110352e-06 +3993 3990 -117017201.3105 +3994 3990 -13845195.78321 +3995 3990 -3.039836883545e-06 +4077 3990 -6373939.007691 +4078 3990 3686414.61702 +4079 3990 4909027.779057 +4098 3990 -33940957.18403 +4099 3990 -15983626.88872 +4100 3990 -20312500.00667 +4101 3990 18906350.86048 +4102 3990 15758585.38937 +4103 3990 8124999.998668 +4104 3990 -54848418.75583 +4105 3990 -3461373.117672 +4106 3990 -41471527.77105 +3991 3991 243072801.0766 +3992 3991 1.418590545654e-05 +3993 3991 12080915.32365 +3994 3991 25208100.52529 +3995 3991 7.987022399902e-06 +4077 3991 -2795252.051777 +4078 3991 -37070184.92826 +4079 3991 -33333333.32786 +4098 3991 -15983626.88872 +4099 3991 -30000388.31335 +4100 3991 -16666666.67214 +4101 3991 15758585.38937 +4102 3991 10104940.51806 +4103 3991 6666666.66557 +4104 3991 3020293.551124 +4105 3991 -19291331.36354 +4106 3991 3333333.334427 +3992 3992 285481231.0942 +3993 3992 -2.384185791016e-07 +3994 3992 7.867813110352e-06 +3995 3992 47347303.99915 +4077 3992 -3215972.223779 +4078 3992 -33333333.32786 +4079 3992 -47671313.3252 +4098 3992 -20312500.00667 +4099 3992 -16666666.67214 +4100 3992 -35534698.41772 +4101 3992 -8124999.998663 +4102 3992 -6666666.665573 +4103 3992 -63733661.36496 +4104 3992 -41471527.77088 +4105 3992 -3333333.334429 +4106 3992 -56412231.12431 +3993 3993 285841125.8965 +3994 3993 -66561551.7465 +3995 3993 -5.960464477539e-06 +4077 3993 -36574674.40712 +4078 3993 16424706.45526 +4079 3993 21159027.78473 +4098 3993 -5631106.840512 +4099 3993 -2804255.484371 +4100 3993 -3385277.779223 +4101 3993 -54848418.75583 +4102 3993 3020293.55113 +4103 3993 41471527.77088 +4104 3993 19752408.62642 +4105 3993 -16640744.52202 +4106 3993 -8463611.109722 +3994 3994 244829958.0819 +3995 3994 1.835823059082e-05 +4077 3994 16424706.45526 +4078 3994 -30988032.272 +4079 3994 -16666666.67214 +4098 3994 3677411.184426 +4099 3994 -36521824.70811 +4100 3994 -33333333.32786 +4101 3994 -3461373.117666 +4102 3994 -19291331.36354 +4103 3994 3333333.334427 +4104 3994 -16640744.52202 +4105 3994 9499396.966606 +4106 3994 6666666.665568 +3995 3995 290978341.916 +4077 3995 21159027.78473 +4078 3995 -16666666.67214 +4079 3995 -36522342.37638 +4098 3995 5078333.334501 +4099 3995 -33333333.32786 +4100 3995 -48057936.71776 +4101 3995 41471527.77105 +4102 3995 -3333333.334429 +4103 3995 -56412231.12431 +4104 3995 8463611.10972 +4105 3995 -6666666.665575 +4106 3995 -65145600.12031 +3996 3996 721441645.4454 +3997 3996 64813888.87825 +3998 3996 -8.821487426758e-06 +3999 3996 -346380299.6592 +4000 3996 -64813888.35974 +4001 3996 -2.676248550415e-05 +4002 3996 27846630.32399 +4003 3996 51851110.58409 +4107 3996 41127258.27048 +4108 3996 16203472.22755 +4109 3996 17343888.84954 +4110 3996 -135326679.0276 +4111 3996 -16203472.09792 +4112 3996 -86719444.24762 +4113 3996 -13923315.162 +4114 3996 12962777.65241 +4115 3996 -17343888.52033 +3997 3997 624217266.0229 +3998 3997 -7.51187935966e-06 +3999 3997 -64813888.10048 +4000 3997 -41753137.74642 +4001 3997 -7.390975952148e-06 +4002 3997 77776665.87613 +4003 3997 27846630.32398 +4004 3997 6.794929504395e-06 +4107 3997 16203472.22755 +4108 3997 16821163.40287 +4109 3997 13874999.85144 +4110 3997 -16203472.0331 +4111 3997 -59169888.51194 +4112 3997 -17343749.90781 +4113 3997 19444166.47861 +4114 3997 -13923315.162 +4115 3997 20812499.90895 +3998 3998 760788621.1472 +3999 3998 -2.646446228027e-05 +4000 3998 -5.185604095459e-06 +4001 3998 31972185.12589 +4003 3998 4.708766937256e-06 +4004 3998 74257680.86397 +4107 3998 -17343888.84951 +4108 3998 -13874999.85143 +4109 3998 -181091253.0988 +4110 3998 -86719444.24762 +4111 3998 -17343749.94043 +4112 3998 -121957897.9018 +4113 3998 -26015832.7805 +4114 3998 13874999.9393 +4115 3998 -37128840.43199 +3999 3999 1242901705.056 +4000 3999 64813887.58197 +4001 3999 -3.838539123535e-05 +4002 3999 47693290.89467 +4003 3999 -64813888.35975 +4004 3999 -7.510185241699e-06 +4005 3999 -229938603.1375 +4006 3999 -1.400709152222e-06 +4007 3999 -1.621246337891e-05 +4008 3999 -88595068.35711 +4009 3999 64813888.87826 +4010 3999 -3.75509262085e-06 +4107 3999 -135326679.0277 +4108 3999 -16203472.0331 +4109 3999 86719444.24762 +4110 3999 101875695.1567 +4111 3999 16203471.90348 +4112 3999 0.03654569387436 +4113 3999 -36808280.87074 +4114 3999 -16203472.09792 +4115 3999 21679860.74398 +4116 3999 -113177912.5204 +4117 3999 6.407499313354e-07 +4118 3999 -86719444.43019 +4119 3999 -36072082.53397 +4120 3999 16203472.22755 +4121 3999 -21679861.11823 +4000 4000 1067897821.637 +4002 4000 -64813888.10049 +4003 4000 -179154367.6044 +4004 4000 -1.16229057312e-05 +4005 4000 7.748603820801e-07 +4006 4000 55243684.38681 +4007 4000 -1.788139343262e-06 +4008 4000 64813888.87826 +4009 4000 -69150192.34827 +4010 4000 -4.619359970093e-07 +4107 4000 -16203472.09792 +4108 4000 -59169888.51195 +4109 4000 17343749.94043 +4110 4000 16203471.90348 +4111 4000 58124724.28025 +4112 4000 0.029221534729 +4113 4000 -16203472.03311 +4114 4000 -93520195.52346 +4115 4000 69374999.6084 +4116 4000 -1.177191734314e-06 +4117 4000 -41882340.60421 +4118 4000 8.344650268555e-07 +4119 4000 16203472.22754 +4120 4000 -31210863.52937 +4121 4000 17343750.0057 +4001 4001 1220904161.253 +4002 4001 -7.390975952148e-06 +4003 4001 -9.536743164063e-06 +4004 4001 101973736.7139 +4005 4001 -1.54972076416e-05 +4006 4001 -1.907348632813e-06 +4007 4001 109872226.963 +4008 4001 -3.635883331299e-06 +4009 4001 -6.109476089478e-07 +4010 4001 -3642360.79014 +4107 4001 86719444.24762 +4108 4001 17343749.9078 +4109 4001 -121957897.9018 +4110 4001 -0.03648543357849 +4111 4001 -0.02920261025429 +4112 4001 -251706576.231 +4113 4001 21679860.55685 +4114 4001 69374999.49133 +4115 4001 -104457508.7431 +4116 4001 -86719444.43019 +4117 4001 8.940696716309e-07 +4118 4001 -121047307.7997 +4119 4001 -21679861.11823 +4120 4001 17343750.0057 +4121 4001 -38039431.35476 +4002 4002 721441645.4454 +4003 4002 64813888.87825 +4004 4002 -8.821487426758e-06 +4005 4002 -88595068.35711 +4006 4002 -64813888.87825 +4007 4002 -4.26173210144e-06 +4008 4002 -346380299.6592 +4009 4002 -64813888.35974 +4010 4002 -2.676248550415e-05 +4011 4002 27846630.32399 +4012 4002 51851110.58409 +4107 4002 -13923315.16199 +4108 4002 19444166.47861 +4109 4002 26015832.7805 +4110 4002 -36808280.87074 +4111 4002 -16203472.0331 +4112 4002 -21679860.55685 +4113 4002 41127258.27048 +4114 4002 16203472.22755 +4115 4002 17343888.84954 +4116 4002 -36072082.53397 +4117 4002 -16203472.22754 +4118 4002 -21679861.11823 +4119 4002 -135326679.0276 +4120 4002 -16203472.09792 +4121 4002 -86719444.24762 +4122 4002 -13923315.162 +4123 4002 12962777.65241 +4124 4002 -17343888.52033 +4003 4003 624217266.0229 +4004 4003 -7.273460780558e-06 +4005 4003 -64813888.87825 +4006 4003 -69150192.34827 +4007 4003 -6.705522537231e-07 +4008 4003 -64813888.10048 +4009 4003 -41753137.74642 +4010 4003 -7.390975952148e-06 +4011 4003 77776665.87613 +4012 4003 27846630.32398 +4013 4003 6.794929504395e-06 +4107 4003 12962777.65241 +4108 4003 -13923315.162 +4109 4003 -13874999.9393 +4110 4003 -16203472.09791 +4111 4003 -93520195.52345 +4112 4003 -69374999.49133 +4113 4003 16203472.22755 +4114 4003 16821163.40287 +4115 4003 13874999.85144 +4116 4003 -16203472.22754 +4117 4003 -31210863.52937 +4118 4003 -17343750.0057 +4119 4003 -16203472.0331 +4120 4003 -59169888.51194 +4121 4003 -17343749.90781 +4122 4003 19444166.47861 +4123 4003 -13923315.162 +4124 4003 20812499.90895 +4004 4004 760788621.1472 +4005 4004 -4.231929779053e-06 +4006 4004 -5.811452865601e-07 +4007 4004 -3642360.790142 +4008 4004 -2.646446228027e-05 +4009 4004 -5.185604095459e-06 +4010 4004 31972185.12589 +4012 4004 4.708766937256e-06 +4013 4004 74257680.86397 +4107 4004 17343888.52033 +4108 4004 -20812499.90894 +4109 4004 -37128840.43198 +4110 4004 -21679860.74397 +4111 4004 -69374999.6084 +4112 4004 -104457508.7431 +4113 4004 -17343888.84951 +4114 4004 -13874999.85143 +4115 4004 -181091253.0988 +4116 4004 -21679861.11823 +4117 4004 -17343750.0057 +4118 4004 -38039431.35476 +4119 4004 -86719444.24762 +4120 4004 -17343749.94043 +4121 4004 -121957897.9018 +4122 4004 -26015832.7805 +4123 4004 13874999.9393 +4124 4004 -37128840.43199 +4005 4005 1154306639.95 +4006 4005 4.053115844727e-06 +4007 4005 -5.984306335449e-05 +4008 4005 164134990.0133 +4009 4005 -4.798173904419e-06 +4010 4005 -1.537799835205e-05 +4014 4005 -229938603.1375 +4015 4005 -1.400709152222e-06 +4016 4005 -1.621246337891e-05 +4017 4005 -88595068.35711 +4018 4005 64813888.87826 +4019 4005 -3.75509262085e-06 +4110 4005 -113177912.5205 +4111 4005 -1.952052116394e-06 +4112 4005 86719444.4302 +4113 4005 -36072082.53399 +4114 4005 -16203472.22755 +4115 4005 21679861.11823 +4116 4005 65803613.40852 +4117 4005 4.112720489502e-06 +4118 4005 3.081560134888e-05 +4119 4005 -14659514.18418 +4120 4005 -1.010298728943e-05 +4121 4005 8.165836334229e-06 +4125 4005 -113177912.5204 +4126 4005 6.407499313354e-07 +4127 4005 -86719444.43019 +4128 4005 -36072082.53397 +4129 4005 16203472.22755 +4130 4005 -21679861.11823 +4006 4006 998747631.9559 +4007 4006 -6.675720214844e-06 +4008 4006 -3.397464752197e-06 +4009 4006 -82157545.53163 +4010 4006 -2.264976501465e-06 +4014 4006 7.748603820801e-07 +4015 4006 55243684.38681 +4016 4006 -1.788139343262e-06 +4017 4006 64813888.87826 +4018 4006 -69150192.34827 +4019 4006 -4.619359970093e-07 +4110 4006 -4.097819328308e-06 +4111 4006 -41882340.60423 +4112 4006 1.296401023865e-06 +4113 4006 -16203472.22755 +4114 4006 -31210863.52938 +4115 4006 17343750.0057 +4116 4006 4.053115844727e-06 +4117 4006 26913861.39084 +4118 4006 4.738569259644e-06 +4119 4006 -7.331371307373e-06 +4120 4006 -76232648.10076 +4121 4006 69374999.9886 +4125 4006 -1.177191734314e-06 +4126 4006 -41882340.60421 +4127 4006 8.344650268555e-07 +4128 4006 16203472.22754 +4129 4006 -31210863.52937 +4130 4006 17343750.0057 +4007 4007 1217261802.153 +4008 4007 -1.52587890625e-05 +4009 4007 -2.562999725342e-06 +4010 4007 179873780.5718 +4014 4007 -1.54972076416e-05 +4015 4007 -1.907348632813e-06 +4016 4007 109872226.963 +4017 4007 -3.635883331299e-06 +4018 4007 -6.109476089478e-07 +4019 4007 -3642360.79014 +4110 4007 86719444.4302 +4111 4007 1.415610313416e-06 +4112 4007 -121047307.7997 +4113 4007 21679861.11823 +4114 4007 17343750.0057 +4115 4007 -38039431.35476 +4116 4007 3.02791595459e-05 +4117 4007 4.619359970093e-06 +4118 4007 -289746007.2349 +4119 4007 8.165836334229e-06 +4120 4007 69374999.9886 +4121 4007 -103546919.3888 +4125 4007 -86719444.43019 +4126 4007 8.940696716309e-07 +4127 4007 -121047307.7997 +4128 4007 -21679861.11823 +4129 4007 17343750.0057 +4130 4007 -38039431.35476 +4008 4008 1242901705.056 +4009 4008 64813887.58197 +4010 4008 -3.838539123535e-05 +4011 4008 47693290.89467 +4012 4008 -64813888.35975 +4013 4008 -7.510185241699e-06 +4014 4008 -88595068.35711 +4015 4008 -64813888.87825 +4016 4008 -4.26173210144e-06 +4017 4008 -229938603.1375 +4018 4008 -1.400709152222e-06 +4019 4008 -1.621246337891e-05 +4020 4008 -88595068.35711 +4021 4008 64813888.87826 +4022 4008 -3.75509262085e-06 +4110 4008 -36072082.53399 +4111 4008 16203472.22755 +4112 4008 21679861.11823 +4113 4008 -135326679.0277 +4114 4008 -16203472.0331 +4115 4008 86719444.24762 +4116 4008 -14659514.18418 +4117 4008 7.62939453125e-06 +4118 4008 7.152557373047e-06 +4119 4008 101875695.1567 +4120 4008 16203471.90348 +4121 4008 0.03654569387436 +4122 4008 -36808280.87074 +4123 4008 -16203472.09792 +4124 4008 21679860.74398 +4125 4008 -36072082.53397 +4126 4008 -16203472.22754 +4127 4008 -21679861.11823 +4128 4008 -113177912.5204 +4129 4008 6.407499313354e-07 +4130 4008 -86719444.43019 +4131 4008 -36072082.53397 +4132 4008 16203472.22755 +4133 4008 -21679861.11823 +4009 4009 1067897821.637 +4011 4009 -64813888.10049 +4012 4009 -179154367.6044 +4013 4009 -1.16229057312e-05 +4014 4009 -64813888.87825 +4015 4009 -69150192.34827 +4016 4009 -6.705522537231e-07 +4017 4009 7.748603820801e-07 +4018 4009 55243684.38681 +4019 4009 -1.788139343262e-06 +4020 4009 64813888.87826 +4021 4009 -69150192.34827 +4022 4009 -4.619359970093e-07 +4110 4009 16203472.22755 +4111 4009 -31210863.52938 +4112 4009 -17343750.00569 +4113 4009 -16203472.09792 +4114 4009 -59169888.51195 +4115 4009 17343749.94043 +4116 4009 8.970499038696e-06 +4117 4009 -76232648.10075 +4118 4009 -69374999.9886 +4119 4009 16203471.90348 +4120 4009 58124724.28025 +4121 4009 0.029221534729 +4122 4009 -16203472.03311 +4123 4009 -93520195.52346 +4124 4009 69374999.6084 +4125 4009 -16203472.22754 +4126 4009 -31210863.52937 +4127 4009 -17343750.0057 +4128 4009 -1.177191734314e-06 +4129 4009 -41882340.60421 +4130 4009 8.344650268555e-07 +4131 4009 16203472.22754 +4132 4009 -31210863.52937 +4133 4009 17343750.0057 +4010 4010 1220904161.253 +4011 4010 -7.390975952148e-06 +4012 4010 -9.536743164063e-06 +4013 4010 101973736.7139 +4014 4010 -4.231929779053e-06 +4015 4010 -5.811452865601e-07 +4016 4010 -3642360.790142 +4017 4010 -1.54972076416e-05 +4018 4010 -1.907348632813e-06 +4019 4010 109872226.963 +4020 4010 -3.635883331299e-06 +4021 4010 -6.109476089478e-07 +4022 4010 -3642360.79014 +4110 4010 21679861.11823 +4111 4010 -17343750.00569 +4112 4010 -38039431.35476 +4113 4010 86719444.24762 +4114 4010 17343749.9078 +4115 4010 -121957897.9018 +4116 4010 7.182359695435e-06 +4117 4010 -69374999.9886 +4118 4010 -103546919.3888 +4119 4010 -0.03648543357849 +4120 4010 -0.02920261025429 +4121 4010 -251706576.231 +4122 4010 21679860.55685 +4123 4010 69374999.49133 +4124 4010 -104457508.7431 +4125 4010 -21679861.11823 +4126 4010 -17343750.0057 +4127 4010 -38039431.35476 +4128 4010 -86719444.43019 +4129 4010 8.940696716309e-07 +4130 4010 -121047307.7997 +4131 4010 -21679861.11823 +4132 4010 17343750.0057 +4133 4010 -38039431.35476 +4011 4011 721441645.4454 +4012 4011 64813888.87825 +4013 4011 -8.821487426758e-06 +4017 4011 -88595068.35711 +4018 4011 -64813888.87825 +4019 4011 -4.26173210144e-06 +4020 4011 -346380299.6592 +4021 4011 -64813888.35974 +4022 4011 -2.676248550415e-05 +4023 4011 27846630.32399 +4024 4011 51851110.58409 +4113 4011 -13923315.16199 +4114 4011 19444166.47861 +4115 4011 26015832.7805 +4119 4011 -36808280.87074 +4120 4011 -16203472.0331 +4121 4011 -21679860.55685 +4122 4011 41127258.27048 +4123 4011 16203472.22755 +4124 4011 17343888.84954 +4128 4011 -36072082.53397 +4129 4011 -16203472.22754 +4130 4011 -21679861.11823 +4131 4011 -135326679.0276 +4132 4011 -16203472.09792 +4133 4011 -86719444.24762 +4134 4011 -13923315.162 +4135 4011 12962777.65241 +4136 4011 -17343888.52033 +4012 4012 624217266.0229 +4013 4012 -7.273460780558e-06 +4017 4012 -64813888.87825 +4018 4012 -69150192.34827 +4019 4012 -6.705522537231e-07 +4020 4012 -64813888.10048 +4021 4012 -41753137.74642 +4022 4012 -7.390975952148e-06 +4023 4012 77776665.87613 +4024 4012 27846630.32398 +4025 4012 6.794929504395e-06 +4113 4012 12962777.65241 +4114 4012 -13923315.162 +4115 4012 -13874999.9393 +4119 4012 -16203472.09791 +4120 4012 -93520195.52345 +4121 4012 -69374999.49133 +4122 4012 16203472.22755 +4123 4012 16821163.40287 +4124 4012 13874999.85144 +4128 4012 -16203472.22754 +4129 4012 -31210863.52937 +4130 4012 -17343750.0057 +4131 4012 -16203472.0331 +4132 4012 -59169888.51194 +4133 4012 -17343749.90781 +4134 4012 19444166.47861 +4135 4012 -13923315.162 +4136 4012 20812499.90895 +4013 4013 760788621.1472 +4017 4013 -4.231929779053e-06 +4018 4013 -5.811452865601e-07 +4019 4013 -3642360.790142 +4020 4013 -2.646446228027e-05 +4021 4013 -5.185604095459e-06 +4022 4013 31972185.12589 +4024 4013 4.708766937256e-06 +4025 4013 74257680.86397 +4113 4013 17343888.52033 +4114 4013 -20812499.90894 +4115 4013 -37128840.43198 +4119 4013 -21679860.74397 +4120 4013 -69374999.6084 +4121 4013 -104457508.7431 +4122 4013 -17343888.84951 +4123 4013 -13874999.85143 +4124 4013 -181091253.0988 +4128 4013 -21679861.11823 +4129 4013 -17343750.0057 +4130 4013 -38039431.35476 +4131 4013 -86719444.24762 +4132 4013 -17343749.94043 +4133 4013 -121957897.9018 +4134 4013 -26015832.7805 +4135 4013 13874999.9393 +4136 4013 -37128840.43199 +4014 4014 1154306639.95 +4015 4014 4.053115844727e-06 +4016 4014 -5.984306335449e-05 +4017 4014 164134990.0133 +4018 4014 -4.798173904419e-06 +4019 4014 -1.537799835205e-05 +4026 4014 -229938603.1375 +4027 4014 -1.400709152222e-06 +4028 4014 -1.621246337891e-05 +4029 4014 -88595068.35711 +4030 4014 64813888.87826 +4031 4014 -3.75509262085e-06 +4116 4014 -113177912.5205 +4117 4014 -1.952052116394e-06 +4118 4014 86719444.4302 +4119 4014 -36072082.53399 +4120 4014 -16203472.22755 +4121 4014 21679861.11823 +4125 4014 65803613.40852 +4126 4014 4.112720489502e-06 +4127 4014 3.081560134888e-05 +4128 4014 -14659514.18418 +4129 4014 -1.010298728943e-05 +4130 4014 8.165836334229e-06 +4137 4014 -113177912.5204 +4138 4014 6.407499313354e-07 +4139 4014 -86719444.43019 +4140 4014 -36072082.53397 +4141 4014 16203472.22755 +4142 4014 -21679861.11823 +4015 4015 998747631.9559 +4016 4015 -6.675720214844e-06 +4017 4015 -3.397464752197e-06 +4018 4015 -82157545.53163 +4019 4015 -2.264976501465e-06 +4026 4015 7.748603820801e-07 +4027 4015 55243684.38681 +4028 4015 -1.788139343262e-06 +4029 4015 64813888.87826 +4030 4015 -69150192.34827 +4031 4015 -4.619359970093e-07 +4116 4015 -4.097819328308e-06 +4117 4015 -41882340.60423 +4118 4015 1.296401023865e-06 +4119 4015 -16203472.22755 +4120 4015 -31210863.52938 +4121 4015 17343750.0057 +4125 4015 4.053115844727e-06 +4126 4015 26913861.39084 +4127 4015 4.738569259644e-06 +4128 4015 -7.331371307373e-06 +4129 4015 -76232648.10076 +4130 4015 69374999.9886 +4137 4015 -1.177191734314e-06 +4138 4015 -41882340.60421 +4139 4015 8.344650268555e-07 +4140 4015 16203472.22754 +4141 4015 -31210863.52937 +4142 4015 17343750.0057 +4016 4016 1217261802.153 +4017 4016 -1.52587890625e-05 +4018 4016 -2.562999725342e-06 +4019 4016 179873780.5718 +4026 4016 -1.54972076416e-05 +4027 4016 -1.907348632813e-06 +4028 4016 109872226.963 +4029 4016 -3.635883331299e-06 +4030 4016 -6.109476089478e-07 +4031 4016 -3642360.79014 +4116 4016 86719444.4302 +4117 4016 1.415610313416e-06 +4118 4016 -121047307.7997 +4119 4016 21679861.11823 +4120 4016 17343750.0057 +4121 4016 -38039431.35476 +4125 4016 3.02791595459e-05 +4126 4016 4.619359970093e-06 +4127 4016 -289746007.2349 +4128 4016 8.165836334229e-06 +4129 4016 69374999.9886 +4130 4016 -103546919.3888 +4137 4016 -86719444.43019 +4138 4016 8.940696716309e-07 +4139 4016 -121047307.7997 +4140 4016 -21679861.11823 +4141 4016 17343750.0057 +4142 4016 -38039431.35476 +4017 4017 1154306639.95 +4018 4017 4.053115844727e-06 +4019 4017 -5.984306335449e-05 +4020 4017 164134990.0133 +4021 4017 -4.798173904419e-06 +4022 4017 -1.537799835205e-05 +4026 4017 -88595068.35711 +4027 4017 -64813888.87825 +4028 4017 -4.26173210144e-06 +4029 4017 -229938603.1375 +4030 4017 -1.400709152222e-06 +4031 4017 -1.621246337891e-05 +4032 4017 -88595068.35711 +4033 4017 64813888.87826 +4034 4017 -3.75509262085e-06 +4116 4017 -36072082.53399 +4117 4017 16203472.22755 +4118 4017 21679861.11823 +4119 4017 -113177912.5205 +4120 4017 -1.952052116394e-06 +4121 4017 86719444.4302 +4122 4017 -36072082.53399 +4123 4017 -16203472.22755 +4124 4017 21679861.11823 +4125 4017 -14659514.18418 +4126 4017 7.62939453125e-06 +4127 4017 7.152557373047e-06 +4128 4017 65803613.40852 +4129 4017 4.112720489502e-06 +4130 4017 3.081560134888e-05 +4131 4017 -14659514.18418 +4132 4017 -1.010298728943e-05 +4133 4017 8.165836334229e-06 +4137 4017 -36072082.53397 +4138 4017 -16203472.22754 +4139 4017 -21679861.11823 +4140 4017 -113177912.5204 +4141 4017 6.407499313354e-07 +4142 4017 -86719444.43019 +4143 4017 -36072082.53397 +4144 4017 16203472.22755 +4145 4017 -21679861.11823 +4018 4018 998747631.9559 +4019 4018 -6.675720214844e-06 +4020 4018 -3.397464752197e-06 +4021 4018 -82157545.53163 +4022 4018 -2.264976501465e-06 +4026 4018 -64813888.87825 +4027 4018 -69150192.34827 +4028 4018 -6.705522537231e-07 +4029 4018 7.748603820801e-07 +4030 4018 55243684.38681 +4031 4018 -1.788139343262e-06 +4032 4018 64813888.87826 +4033 4018 -69150192.34827 +4034 4018 -4.619359970093e-07 +4116 4018 16203472.22755 +4117 4018 -31210863.52938 +4118 4018 -17343750.00569 +4119 4018 -4.097819328308e-06 +4120 4018 -41882340.60423 +4121 4018 1.296401023865e-06 +4122 4018 -16203472.22755 +4123 4018 -31210863.52938 +4124 4018 17343750.0057 +4125 4018 8.970499038696e-06 +4126 4018 -76232648.10075 +4127 4018 -69374999.9886 +4128 4018 4.053115844727e-06 +4129 4018 26913861.39084 +4130 4018 4.738569259644e-06 +4131 4018 -7.331371307373e-06 +4132 4018 -76232648.10076 +4133 4018 69374999.9886 +4137 4018 -16203472.22754 +4138 4018 -31210863.52937 +4139 4018 -17343750.0057 +4140 4018 -1.177191734314e-06 +4141 4018 -41882340.60421 +4142 4018 8.344650268555e-07 +4143 4018 16203472.22754 +4144 4018 -31210863.52937 +4145 4018 17343750.0057 +4019 4019 1217261802.153 +4020 4019 -1.52587890625e-05 +4021 4019 -2.562999725342e-06 +4022 4019 179873780.5718 +4026 4019 -4.231929779053e-06 +4027 4019 -5.811452865601e-07 +4028 4019 -3642360.790142 +4029 4019 -1.54972076416e-05 +4030 4019 -1.907348632813e-06 +4031 4019 109872226.963 +4032 4019 -3.635883331299e-06 +4033 4019 -6.109476089478e-07 +4034 4019 -3642360.79014 +4116 4019 21679861.11823 +4117 4019 -17343750.00569 +4118 4019 -38039431.35476 +4119 4019 86719444.4302 +4120 4019 1.415610313416e-06 +4121 4019 -121047307.7997 +4122 4019 21679861.11823 +4123 4019 17343750.0057 +4124 4019 -38039431.35476 +4125 4019 7.182359695435e-06 +4126 4019 -69374999.9886 +4127 4019 -103546919.3888 +4128 4019 3.02791595459e-05 +4129 4019 4.619359970093e-06 +4130 4019 -289746007.2349 +4131 4019 8.165836334229e-06 +4132 4019 69374999.9886 +4133 4019 -103546919.3888 +4137 4019 -21679861.11823 +4138 4019 -17343750.0057 +4139 4019 -38039431.35476 +4140 4019 -86719444.43019 +4141 4019 8.940696716309e-07 +4142 4019 -121047307.7997 +4143 4019 -21679861.11823 +4144 4019 17343750.0057 +4145 4019 -38039431.35476 +4020 4020 1242901705.056 +4021 4020 64813887.58197 +4022 4020 -3.838539123535e-05 +4023 4020 47693290.89467 +4024 4020 -64813888.35975 +4025 4020 -7.510185241699e-06 +4029 4020 -88595068.35711 +4030 4020 -64813888.87825 +4031 4020 -4.26173210144e-06 +4032 4020 -229938603.1375 +4033 4020 -1.400709152222e-06 +4034 4020 -1.621246337891e-05 +4035 4020 -88595068.35711 +4036 4020 64813888.87826 +4037 4020 -3.75509262085e-06 +4119 4020 -36072082.53399 +4120 4020 16203472.22755 +4121 4020 21679861.11823 +4122 4020 -135326679.0277 +4123 4020 -16203472.0331 +4124 4020 86719444.24762 +4128 4020 -14659514.18418 +4129 4020 7.62939453125e-06 +4130 4020 7.152557373047e-06 +4131 4020 101875695.1567 +4132 4020 16203471.90348 +4133 4020 0.03654569387436 +4134 4020 -36808280.87074 +4135 4020 -16203472.09792 +4136 4020 21679860.74398 +4140 4020 -36072082.53397 +4141 4020 -16203472.22754 +4142 4020 -21679861.11823 +4143 4020 -113177912.5204 +4144 4020 6.407499313354e-07 +4145 4020 -86719444.43019 +4146 4020 -36072082.53397 +4147 4020 16203472.22755 +4148 4020 -21679861.11823 +4021 4021 1067897821.637 +4023 4021 -64813888.10049 +4024 4021 -179154367.6044 +4025 4021 -1.16229057312e-05 +4029 4021 -64813888.87825 +4030 4021 -69150192.34827 +4031 4021 -6.705522537231e-07 +4032 4021 7.748603820801e-07 +4033 4021 55243684.38681 +4034 4021 -1.788139343262e-06 +4035 4021 64813888.87826 +4036 4021 -69150192.34827 +4037 4021 -4.619359970093e-07 +4119 4021 16203472.22755 +4120 4021 -31210863.52938 +4121 4021 -17343750.00569 +4122 4021 -16203472.09792 +4123 4021 -59169888.51195 +4124 4021 17343749.94043 +4128 4021 8.970499038696e-06 +4129 4021 -76232648.10075 +4130 4021 -69374999.9886 +4131 4021 16203471.90348 +4132 4021 58124724.28025 +4133 4021 0.029221534729 +4134 4021 -16203472.03311 +4135 4021 -93520195.52346 +4136 4021 69374999.6084 +4140 4021 -16203472.22754 +4141 4021 -31210863.52937 +4142 4021 -17343750.0057 +4143 4021 -1.177191734314e-06 +4144 4021 -41882340.60421 +4145 4021 8.344650268555e-07 +4146 4021 16203472.22754 +4147 4021 -31210863.52937 +4148 4021 17343750.0057 +4022 4022 1220904161.253 +4023 4022 -7.390975952148e-06 +4024 4022 -9.536743164063e-06 +4025 4022 101973736.7139 +4029 4022 -4.231929779053e-06 +4030 4022 -5.811452865601e-07 +4031 4022 -3642360.790142 +4032 4022 -1.54972076416e-05 +4033 4022 -1.907348632813e-06 +4034 4022 109872226.963 +4035 4022 -3.635883331299e-06 +4036 4022 -6.109476089478e-07 +4037 4022 -3642360.79014 +4119 4022 21679861.11823 +4120 4022 -17343750.00569 +4121 4022 -38039431.35476 +4122 4022 86719444.24762 +4123 4022 17343749.9078 +4124 4022 -121957897.9018 +4128 4022 7.182359695435e-06 +4129 4022 -69374999.9886 +4130 4022 -103546919.3888 +4131 4022 -0.03648543357849 +4132 4022 -0.02920261025429 +4133 4022 -251706576.231 +4134 4022 21679860.55685 +4135 4022 69374999.49133 +4136 4022 -104457508.7431 +4140 4022 -21679861.11823 +4141 4022 -17343750.0057 +4142 4022 -38039431.35476 +4143 4022 -86719444.43019 +4144 4022 8.940696716309e-07 +4145 4022 -121047307.7997 +4146 4022 -21679861.11823 +4147 4022 17343750.0057 +4148 4022 -38039431.35476 +4023 4023 721441645.4454 +4024 4023 64813888.87825 +4025 4023 -8.821487426758e-06 +4032 4023 -88595068.35711 +4033 4023 -64813888.87825 +4034 4023 -4.26173210144e-06 +4035 4023 -346380299.6592 +4036 4023 -64813888.35974 +4037 4023 -2.676248550415e-05 +4038 4023 27846630.32399 +4039 4023 51851110.58409 +4122 4023 -13923315.16199 +4123 4023 19444166.47861 +4124 4023 26015832.7805 +4131 4023 -36808280.87074 +4132 4023 -16203472.0331 +4133 4023 -21679860.55685 +4134 4023 41127258.27048 +4135 4023 16203472.22755 +4136 4023 17343888.84954 +4143 4023 -36072082.53397 +4144 4023 -16203472.22754 +4145 4023 -21679861.11823 +4146 4023 -135326679.0276 +4147 4023 -16203472.09792 +4148 4023 -86719444.24762 +4149 4023 -13923315.162 +4150 4023 12962777.65241 +4151 4023 -17343888.52033 +4024 4024 624217266.0229 +4025 4024 -7.273460780558e-06 +4032 4024 -64813888.87825 +4033 4024 -69150192.34827 +4034 4024 -6.705522537231e-07 +4035 4024 -64813888.10048 +4036 4024 -41753137.74642 +4037 4024 -7.390975952148e-06 +4038 4024 77776665.87613 +4039 4024 27846630.32398 +4040 4024 6.794929504395e-06 +4122 4024 12962777.65241 +4123 4024 -13923315.162 +4124 4024 -13874999.9393 +4131 4024 -16203472.09791 +4132 4024 -93520195.52345 +4133 4024 -69374999.49133 +4134 4024 16203472.22755 +4135 4024 16821163.40287 +4136 4024 13874999.85144 +4143 4024 -16203472.22754 +4144 4024 -31210863.52937 +4145 4024 -17343750.0057 +4146 4024 -16203472.0331 +4147 4024 -59169888.51194 +4148 4024 -17343749.90781 +4149 4024 19444166.47861 +4150 4024 -13923315.162 +4151 4024 20812499.90895 +4025 4025 760788621.1472 +4032 4025 -4.231929779053e-06 +4033 4025 -5.811452865601e-07 +4034 4025 -3642360.790142 +4035 4025 -2.646446228027e-05 +4036 4025 -5.185604095459e-06 +4037 4025 31972185.12589 +4039 4025 4.708766937256e-06 +4040 4025 74257680.86397 +4122 4025 17343888.52033 +4123 4025 -20812499.90894 +4124 4025 -37128840.43198 +4131 4025 -21679860.74397 +4132 4025 -69374999.6084 +4133 4025 -104457508.7431 +4134 4025 -17343888.84951 +4135 4025 -13874999.85143 +4136 4025 -181091253.0988 +4143 4025 -21679861.11823 +4144 4025 -17343750.0057 +4145 4025 -38039431.35476 +4146 4025 -86719444.24762 +4147 4025 -17343749.94043 +4148 4025 -121957897.9018 +4149 4025 -26015832.7805 +4150 4025 13874999.9393 +4151 4025 -37128840.43199 +4026 4026 1154306639.95 +4027 4026 4.053115844727e-06 +4028 4026 -5.984306335449e-05 +4029 4026 164134990.0133 +4030 4026 -4.798173904419e-06 +4031 4026 -1.537799835205e-05 +4041 4026 -229938603.1375 +4042 4026 -1.400709152222e-06 +4043 4026 -1.621246337891e-05 +4044 4026 -88595068.35711 +4045 4026 64813888.87826 +4046 4026 -3.75509262085e-06 +4125 4026 -113177912.5205 +4126 4026 -1.952052116394e-06 +4127 4026 86719444.4302 +4128 4026 -36072082.53399 +4129 4026 -16203472.22755 +4130 4026 21679861.11823 +4137 4026 65803613.40852 +4138 4026 4.112720489502e-06 +4139 4026 3.081560134888e-05 +4140 4026 -14659514.18418 +4141 4026 -1.010298728943e-05 +4142 4026 8.165836334229e-06 +4152 4026 -113177912.5204 +4153 4026 6.407499313354e-07 +4154 4026 -86719444.43019 +4155 4026 -36072082.53397 +4156 4026 16203472.22755 +4157 4026 -21679861.11823 +4027 4027 998747631.9559 +4028 4027 -6.675720214844e-06 +4029 4027 -3.397464752197e-06 +4030 4027 -82157545.53163 +4031 4027 -2.264976501465e-06 +4041 4027 7.748603820801e-07 +4042 4027 55243684.38681 +4043 4027 -1.788139343262e-06 +4044 4027 64813888.87826 +4045 4027 -69150192.34827 +4046 4027 -4.619359970093e-07 +4125 4027 -4.097819328308e-06 +4126 4027 -41882340.60423 +4127 4027 1.296401023865e-06 +4128 4027 -16203472.22755 +4129 4027 -31210863.52938 +4130 4027 17343750.0057 +4137 4027 4.053115844727e-06 +4138 4027 26913861.39084 +4139 4027 4.738569259644e-06 +4140 4027 -7.331371307373e-06 +4141 4027 -76232648.10076 +4142 4027 69374999.9886 +4152 4027 -1.177191734314e-06 +4153 4027 -41882340.60421 +4154 4027 8.344650268555e-07 +4155 4027 16203472.22754 +4156 4027 -31210863.52937 +4157 4027 17343750.0057 +4028 4028 1217261802.153 +4029 4028 -1.52587890625e-05 +4030 4028 -2.562999725342e-06 +4031 4028 179873780.5718 +4041 4028 -1.54972076416e-05 +4042 4028 -1.907348632813e-06 +4043 4028 109872226.963 +4044 4028 -3.635883331299e-06 +4045 4028 -6.109476089478e-07 +4046 4028 -3642360.79014 +4125 4028 86719444.4302 +4126 4028 1.415610313416e-06 +4127 4028 -121047307.7997 +4128 4028 21679861.11823 +4129 4028 17343750.0057 +4130 4028 -38039431.35476 +4137 4028 3.02791595459e-05 +4138 4028 4.619359970093e-06 +4139 4028 -289746007.2349 +4140 4028 8.165836334229e-06 +4141 4028 69374999.9886 +4142 4028 -103546919.3888 +4152 4028 -86719444.43019 +4153 4028 8.940696716309e-07 +4154 4028 -121047307.7997 +4155 4028 -21679861.11823 +4156 4028 17343750.0057 +4157 4028 -38039431.35476 +4029 4029 1154306639.95 +4030 4029 4.053115844727e-06 +4031 4029 -5.984306335449e-05 +4032 4029 164134990.0133 +4033 4029 -4.798173904419e-06 +4034 4029 -1.537799835205e-05 +4041 4029 -88595068.35711 +4042 4029 -64813888.87825 +4043 4029 -4.26173210144e-06 +4044 4029 -229938603.1375 +4045 4029 -1.400709152222e-06 +4046 4029 -1.621246337891e-05 +4047 4029 -88595068.35711 +4048 4029 64813888.87826 +4049 4029 -3.75509262085e-06 +4125 4029 -36072082.53399 +4126 4029 16203472.22755 +4127 4029 21679861.11823 +4128 4029 -113177912.5205 +4129 4029 -1.952052116394e-06 +4130 4029 86719444.4302 +4131 4029 -36072082.53399 +4132 4029 -16203472.22755 +4133 4029 21679861.11823 +4137 4029 -14659514.18418 +4138 4029 7.62939453125e-06 +4139 4029 7.152557373047e-06 +4140 4029 65803613.40852 +4141 4029 4.112720489502e-06 +4142 4029 3.081560134888e-05 +4143 4029 -14659514.18418 +4144 4029 -1.010298728943e-05 +4145 4029 8.165836334229e-06 +4152 4029 -36072082.53397 +4153 4029 -16203472.22754 +4154 4029 -21679861.11823 +4155 4029 -113177912.5204 +4156 4029 6.407499313354e-07 +4157 4029 -86719444.43019 +4158 4029 -36072082.53397 +4159 4029 16203472.22755 +4160 4029 -21679861.11823 +4030 4030 998747631.9559 +4031 4030 -6.675720214844e-06 +4032 4030 -3.397464752197e-06 +4033 4030 -82157545.53163 +4034 4030 -2.264976501465e-06 +4041 4030 -64813888.87825 +4042 4030 -69150192.34827 +4043 4030 -6.705522537231e-07 +4044 4030 7.748603820801e-07 +4045 4030 55243684.38681 +4046 4030 -1.788139343262e-06 +4047 4030 64813888.87826 +4048 4030 -69150192.34827 +4049 4030 -4.619359970093e-07 +4125 4030 16203472.22755 +4126 4030 -31210863.52938 +4127 4030 -17343750.00569 +4128 4030 -4.097819328308e-06 +4129 4030 -41882340.60423 +4130 4030 1.296401023865e-06 +4131 4030 -16203472.22755 +4132 4030 -31210863.52938 +4133 4030 17343750.0057 +4137 4030 8.970499038696e-06 +4138 4030 -76232648.10075 +4139 4030 -69374999.9886 +4140 4030 4.053115844727e-06 +4141 4030 26913861.39084 +4142 4030 4.738569259644e-06 +4143 4030 -7.331371307373e-06 +4144 4030 -76232648.10076 +4145 4030 69374999.9886 +4152 4030 -16203472.22754 +4153 4030 -31210863.52937 +4154 4030 -17343750.0057 +4155 4030 -1.177191734314e-06 +4156 4030 -41882340.60421 +4157 4030 8.344650268555e-07 +4158 4030 16203472.22754 +4159 4030 -31210863.52937 +4160 4030 17343750.0057 +4031 4031 1217261802.153 +4032 4031 -1.52587890625e-05 +4033 4031 -2.562999725342e-06 +4034 4031 179873780.5718 +4041 4031 -4.231929779053e-06 +4042 4031 -5.811452865601e-07 +4043 4031 -3642360.790142 +4044 4031 -1.54972076416e-05 +4045 4031 -1.907348632813e-06 +4046 4031 109872226.963 +4047 4031 -3.635883331299e-06 +4048 4031 -6.109476089478e-07 +4049 4031 -3642360.79014 +4125 4031 21679861.11823 +4126 4031 -17343750.00569 +4127 4031 -38039431.35476 +4128 4031 86719444.4302 +4129 4031 1.415610313416e-06 +4130 4031 -121047307.7997 +4131 4031 21679861.11823 +4132 4031 17343750.0057 +4133 4031 -38039431.35476 +4137 4031 7.182359695435e-06 +4138 4031 -69374999.9886 +4139 4031 -103546919.3888 +4140 4031 3.02791595459e-05 +4141 4031 4.619359970093e-06 +4142 4031 -289746007.2349 +4143 4031 8.165836334229e-06 +4144 4031 69374999.9886 +4145 4031 -103546919.3888 +4152 4031 -21679861.11823 +4153 4031 -17343750.0057 +4154 4031 -38039431.35476 +4155 4031 -86719444.43019 +4156 4031 8.940696716309e-07 +4157 4031 -121047307.7997 +4158 4031 -21679861.11823 +4159 4031 17343750.0057 +4160 4031 -38039431.35476 +4032 4032 1154306639.95 +4033 4032 4.053115844727e-06 +4034 4032 -5.984306335449e-05 +4035 4032 164134990.0133 +4036 4032 -4.798173904419e-06 +4037 4032 -1.537799835205e-05 +4044 4032 -88595068.35711 +4045 4032 -64813888.87825 +4046 4032 -4.26173210144e-06 +4047 4032 -229938603.1375 +4048 4032 -1.400709152222e-06 +4049 4032 -1.621246337891e-05 +4050 4032 -88595068.35711 +4051 4032 64813888.87826 +4052 4032 -3.75509262085e-06 +4128 4032 -36072082.53399 +4129 4032 16203472.22755 +4130 4032 21679861.11823 +4131 4032 -113177912.5205 +4132 4032 -1.952052116394e-06 +4133 4032 86719444.4302 +4134 4032 -36072082.53399 +4135 4032 -16203472.22755 +4136 4032 21679861.11823 +4140 4032 -14659514.18418 +4141 4032 7.62939453125e-06 +4142 4032 7.152557373047e-06 +4143 4032 65803613.40852 +4144 4032 4.112720489502e-06 +4145 4032 3.081560134888e-05 +4146 4032 -14659514.18418 +4147 4032 -1.010298728943e-05 +4148 4032 8.165836334229e-06 +4155 4032 -36072082.53397 +4156 4032 -16203472.22754 +4157 4032 -21679861.11823 +4158 4032 -113177912.5204 +4159 4032 6.407499313354e-07 +4160 4032 -86719444.43019 +4161 4032 -36072082.53397 +4162 4032 16203472.22755 +4163 4032 -21679861.11823 +4033 4033 998747631.9559 +4034 4033 -6.675720214844e-06 +4035 4033 -3.397464752197e-06 +4036 4033 -82157545.53163 +4037 4033 -2.264976501465e-06 +4044 4033 -64813888.87825 +4045 4033 -69150192.34827 +4046 4033 -6.705522537231e-07 +4047 4033 7.748603820801e-07 +4048 4033 55243684.38681 +4049 4033 -1.788139343262e-06 +4050 4033 64813888.87826 +4051 4033 -69150192.34827 +4052 4033 -4.619359970093e-07 +4128 4033 16203472.22755 +4129 4033 -31210863.52938 +4130 4033 -17343750.00569 +4131 4033 -4.097819328308e-06 +4132 4033 -41882340.60423 +4133 4033 1.296401023865e-06 +4134 4033 -16203472.22755 +4135 4033 -31210863.52938 +4136 4033 17343750.0057 +4140 4033 8.970499038696e-06 +4141 4033 -76232648.10075 +4142 4033 -69374999.9886 +4143 4033 4.053115844727e-06 +4144 4033 26913861.39084 +4145 4033 4.738569259644e-06 +4146 4033 -7.331371307373e-06 +4147 4033 -76232648.10076 +4148 4033 69374999.9886 +4155 4033 -16203472.22754 +4156 4033 -31210863.52937 +4157 4033 -17343750.0057 +4158 4033 -1.177191734314e-06 +4159 4033 -41882340.60421 +4160 4033 8.344650268555e-07 +4161 4033 16203472.22754 +4162 4033 -31210863.52937 +4163 4033 17343750.0057 +4034 4034 1217261802.153 +4035 4034 -1.52587890625e-05 +4036 4034 -2.562999725342e-06 +4037 4034 179873780.5718 +4044 4034 -4.231929779053e-06 +4045 4034 -5.811452865601e-07 +4046 4034 -3642360.790142 +4047 4034 -1.54972076416e-05 +4048 4034 -1.907348632813e-06 +4049 4034 109872226.963 +4050 4034 -3.635883331299e-06 +4051 4034 -6.109476089478e-07 +4052 4034 -3642360.79014 +4128 4034 21679861.11823 +4129 4034 -17343750.00569 +4130 4034 -38039431.35476 +4131 4034 86719444.4302 +4132 4034 1.415610313416e-06 +4133 4034 -121047307.7997 +4134 4034 21679861.11823 +4135 4034 17343750.0057 +4136 4034 -38039431.35476 +4140 4034 7.182359695435e-06 +4141 4034 -69374999.9886 +4142 4034 -103546919.3888 +4143 4034 3.02791595459e-05 +4144 4034 4.619359970093e-06 +4145 4034 -289746007.2349 +4146 4034 8.165836334229e-06 +4147 4034 69374999.9886 +4148 4034 -103546919.3888 +4155 4034 -21679861.11823 +4156 4034 -17343750.0057 +4157 4034 -38039431.35476 +4158 4034 -86719444.43019 +4159 4034 8.940696716309e-07 +4160 4034 -121047307.7997 +4161 4034 -21679861.11823 +4162 4034 17343750.0057 +4163 4034 -38039431.35476 +4035 4035 1242901705.056 +4036 4035 64813887.58197 +4037 4035 -3.838539123535e-05 +4038 4035 47693290.89467 +4039 4035 -64813888.35975 +4040 4035 -7.510185241699e-06 +4047 4035 -88595068.35711 +4048 4035 -64813888.87825 +4049 4035 -4.26173210144e-06 +4050 4035 -229938603.1375 +4051 4035 -1.400709152222e-06 +4052 4035 -1.621246337891e-05 +4053 4035 -88595068.35711 +4054 4035 64813888.87826 +4055 4035 -3.75509262085e-06 +4131 4035 -36072082.53399 +4132 4035 16203472.22755 +4133 4035 21679861.11823 +4134 4035 -135326679.0277 +4135 4035 -16203472.0331 +4136 4035 86719444.24762 +4143 4035 -14659514.18418 +4144 4035 7.62939453125e-06 +4145 4035 7.152557373047e-06 +4146 4035 101875695.1567 +4147 4035 16203471.90348 +4148 4035 0.03654569387436 +4149 4035 -36808280.87074 +4150 4035 -16203472.09792 +4151 4035 21679860.74398 +4158 4035 -36072082.53397 +4159 4035 -16203472.22754 +4160 4035 -21679861.11823 +4161 4035 -113177912.5204 +4162 4035 6.407499313354e-07 +4163 4035 -86719444.43019 +4164 4035 -36072082.53397 +4165 4035 16203472.22755 +4166 4035 -21679861.11823 +4036 4036 1067897821.637 +4038 4036 -64813888.10049 +4039 4036 -179154367.6044 +4040 4036 -1.16229057312e-05 +4047 4036 -64813888.87825 +4048 4036 -69150192.34827 +4049 4036 -6.705522537231e-07 +4050 4036 7.748603820801e-07 +4051 4036 55243684.38681 +4052 4036 -1.788139343262e-06 +4053 4036 64813888.87826 +4054 4036 -69150192.34827 +4055 4036 -4.619359970093e-07 +4131 4036 16203472.22755 +4132 4036 -31210863.52938 +4133 4036 -17343750.00569 +4134 4036 -16203472.09792 +4135 4036 -59169888.51195 +4136 4036 17343749.94043 +4143 4036 8.970499038696e-06 +4144 4036 -76232648.10075 +4145 4036 -69374999.9886 +4146 4036 16203471.90348 +4147 4036 58124724.28025 +4148 4036 0.029221534729 +4149 4036 -16203472.03311 +4150 4036 -93520195.52346 +4151 4036 69374999.6084 +4158 4036 -16203472.22754 +4159 4036 -31210863.52937 +4160 4036 -17343750.0057 +4161 4036 -1.177191734314e-06 +4162 4036 -41882340.60421 +4163 4036 8.344650268555e-07 +4164 4036 16203472.22754 +4165 4036 -31210863.52937 +4166 4036 17343750.0057 +4037 4037 1220904161.253 +4038 4037 -7.390975952148e-06 +4039 4037 -9.536743164063e-06 +4040 4037 101973736.7139 +4047 4037 -4.231929779053e-06 +4048 4037 -5.811452865601e-07 +4049 4037 -3642360.790142 +4050 4037 -1.54972076416e-05 +4051 4037 -1.907348632813e-06 +4052 4037 109872226.963 +4053 4037 -3.635883331299e-06 +4054 4037 -6.109476089478e-07 +4055 4037 -3642360.79014 +4131 4037 21679861.11823 +4132 4037 -17343750.00569 +4133 4037 -38039431.35476 +4134 4037 86719444.24762 +4135 4037 17343749.9078 +4136 4037 -121957897.9018 +4143 4037 7.182359695435e-06 +4144 4037 -69374999.9886 +4145 4037 -103546919.3888 +4146 4037 -0.03648543357849 +4147 4037 -0.02920261025429 +4148 4037 -251706576.231 +4149 4037 21679860.55685 +4150 4037 69374999.49133 +4151 4037 -104457508.7431 +4158 4037 -21679861.11823 +4159 4037 -17343750.0057 +4160 4037 -38039431.35476 +4161 4037 -86719444.43019 +4162 4037 8.940696716309e-07 +4163 4037 -121047307.7997 +4164 4037 -21679861.11823 +4165 4037 17343750.0057 +4166 4037 -38039431.35476 +4038 4038 721441645.4454 +4039 4038 64813888.87825 +4040 4038 -8.821487426758e-06 +4050 4038 -88595068.35711 +4051 4038 -64813888.87825 +4052 4038 -4.26173210144e-06 +4053 4038 -346380299.6592 +4054 4038 -64813888.35974 +4055 4038 -2.676248550415e-05 +4056 4038 27846630.32399 +4057 4038 51851110.58409 +4134 4038 -13923315.16199 +4135 4038 19444166.47861 +4136 4038 26015832.7805 +4146 4038 -36808280.87074 +4147 4038 -16203472.0331 +4148 4038 -21679860.55685 +4149 4038 41127258.27048 +4150 4038 16203472.22755 +4151 4038 17343888.84954 +4161 4038 -36072082.53397 +4162 4038 -16203472.22754 +4163 4038 -21679861.11823 +4164 4038 -135326679.0276 +4165 4038 -16203472.09792 +4166 4038 -86719444.24762 +4167 4038 -13923315.162 +4168 4038 12962777.65241 +4169 4038 -17343888.52033 +4039 4039 624217266.0229 +4040 4039 -7.273460780558e-06 +4050 4039 -64813888.87825 +4051 4039 -69150192.34827 +4052 4039 -6.705522537231e-07 +4053 4039 -64813888.10048 +4054 4039 -41753137.74642 +4055 4039 -7.390975952148e-06 +4056 4039 77776665.87613 +4057 4039 27846630.32398 +4058 4039 6.794929504395e-06 +4134 4039 12962777.65241 +4135 4039 -13923315.162 +4136 4039 -13874999.9393 +4146 4039 -16203472.09791 +4147 4039 -93520195.52345 +4148 4039 -69374999.49133 +4149 4039 16203472.22755 +4150 4039 16821163.40287 +4151 4039 13874999.85144 +4161 4039 -16203472.22754 +4162 4039 -31210863.52937 +4163 4039 -17343750.0057 +4164 4039 -16203472.0331 +4165 4039 -59169888.51194 +4166 4039 -17343749.90781 +4167 4039 19444166.47861 +4168 4039 -13923315.162 +4169 4039 20812499.90895 +4040 4040 760788621.1472 +4050 4040 -4.231929779053e-06 +4051 4040 -5.811452865601e-07 +4052 4040 -3642360.790142 +4053 4040 -2.646446228027e-05 +4054 4040 -5.185604095459e-06 +4055 4040 31972185.12589 +4057 4040 4.708766937256e-06 +4058 4040 74257680.86397 +4134 4040 17343888.52033 +4135 4040 -20812499.90894 +4136 4040 -37128840.43198 +4146 4040 -21679860.74397 +4147 4040 -69374999.6084 +4148 4040 -104457508.7431 +4149 4040 -17343888.84951 +4150 4040 -13874999.85143 +4151 4040 -181091253.0988 +4161 4040 -21679861.11823 +4162 4040 -17343750.0057 +4163 4040 -38039431.35476 +4164 4040 -86719444.24762 +4165 4040 -17343749.94043 +4166 4040 -121957897.9018 +4167 4040 -26015832.7805 +4168 4040 13874999.9393 +4169 4040 -37128840.43199 +4041 4041 1154306639.95 +4042 4041 4.053115844727e-06 +4043 4041 -5.984306335449e-05 +4044 4041 164134990.0133 +4045 4041 -4.798173904419e-06 +4046 4041 -1.537799835205e-05 +4059 4041 -229938603.1375 +4060 4041 -1.400709152222e-06 +4061 4041 -1.621246337891e-05 +4062 4041 -88595068.35711 +4063 4041 64813888.87826 +4064 4041 -3.75509262085e-06 +4137 4041 -113177912.5205 +4138 4041 -1.952052116394e-06 +4139 4041 86719444.4302 +4140 4041 -36072082.53399 +4141 4041 -16203472.22755 +4142 4041 21679861.11823 +4152 4041 65803613.40852 +4153 4041 4.112720489502e-06 +4154 4041 3.081560134888e-05 +4155 4041 -14659514.18418 +4156 4041 -1.010298728943e-05 +4157 4041 8.165836334229e-06 +4170 4041 -113177912.5204 +4171 4041 6.407499313354e-07 +4172 4041 -86719444.43019 +4173 4041 -36072082.53397 +4174 4041 16203472.22755 +4175 4041 -21679861.11823 +4042 4042 998747631.9559 +4043 4042 -6.675720214844e-06 +4044 4042 -3.397464752197e-06 +4045 4042 -82157545.53163 +4046 4042 -2.264976501465e-06 +4059 4042 7.748603820801e-07 +4060 4042 55243684.38681 +4061 4042 -1.788139343262e-06 +4062 4042 64813888.87826 +4063 4042 -69150192.34827 +4064 4042 -4.619359970093e-07 +4137 4042 -4.097819328308e-06 +4138 4042 -41882340.60423 +4139 4042 1.296401023865e-06 +4140 4042 -16203472.22755 +4141 4042 -31210863.52938 +4142 4042 17343750.0057 +4152 4042 4.053115844727e-06 +4153 4042 26913861.39084 +4154 4042 4.738569259644e-06 +4155 4042 -7.331371307373e-06 +4156 4042 -76232648.10076 +4157 4042 69374999.9886 +4170 4042 -1.177191734314e-06 +4171 4042 -41882340.60421 +4172 4042 8.344650268555e-07 +4173 4042 16203472.22754 +4174 4042 -31210863.52937 +4175 4042 17343750.0057 +4043 4043 1217261802.153 +4044 4043 -1.52587890625e-05 +4045 4043 -2.562999725342e-06 +4046 4043 179873780.5718 +4059 4043 -1.54972076416e-05 +4060 4043 -1.907348632813e-06 +4061 4043 109872226.963 +4062 4043 -3.635883331299e-06 +4063 4043 -6.109476089478e-07 +4064 4043 -3642360.79014 +4137 4043 86719444.4302 +4138 4043 1.415610313416e-06 +4139 4043 -121047307.7997 +4140 4043 21679861.11823 +4141 4043 17343750.0057 +4142 4043 -38039431.35476 +4152 4043 3.02791595459e-05 +4153 4043 4.619359970093e-06 +4154 4043 -289746007.2349 +4155 4043 8.165836334229e-06 +4156 4043 69374999.9886 +4157 4043 -103546919.3888 +4170 4043 -86719444.43019 +4171 4043 8.940696716309e-07 +4172 4043 -121047307.7997 +4173 4043 -21679861.11823 +4174 4043 17343750.0057 +4175 4043 -38039431.35476 +4044 4044 1154306639.95 +4045 4044 4.053115844727e-06 +4046 4044 -5.984306335449e-05 +4047 4044 164134990.0133 +4048 4044 -4.798173904419e-06 +4049 4044 -1.537799835205e-05 +4059 4044 -88595068.35711 +4060 4044 -64813888.87825 +4061 4044 -4.26173210144e-06 +4062 4044 -229938603.1375 +4063 4044 -1.400709152222e-06 +4064 4044 -1.621246337891e-05 +4065 4044 -88595068.35711 +4066 4044 64813888.87826 +4067 4044 -3.75509262085e-06 +4137 4044 -36072082.53399 +4138 4044 16203472.22755 +4139 4044 21679861.11823 +4140 4044 -113177912.5205 +4141 4044 -1.952052116394e-06 +4142 4044 86719444.4302 +4143 4044 -36072082.53399 +4144 4044 -16203472.22755 +4145 4044 21679861.11823 +4152 4044 -14659514.18418 +4153 4044 7.62939453125e-06 +4154 4044 7.152557373047e-06 +4155 4044 65803613.40852 +4156 4044 4.112720489502e-06 +4157 4044 3.081560134888e-05 +4158 4044 -14659514.18418 +4159 4044 -1.010298728943e-05 +4160 4044 8.165836334229e-06 +4170 4044 -36072082.53397 +4171 4044 -16203472.22754 +4172 4044 -21679861.11823 +4173 4044 -113177912.5204 +4174 4044 6.407499313354e-07 +4175 4044 -86719444.43019 +4176 4044 -36072082.53397 +4177 4044 16203472.22755 +4178 4044 -21679861.11823 +4045 4045 998747631.9559 +4046 4045 -6.675720214844e-06 +4047 4045 -3.397464752197e-06 +4048 4045 -82157545.53163 +4049 4045 -2.264976501465e-06 +4059 4045 -64813888.87825 +4060 4045 -69150192.34827 +4061 4045 -6.705522537231e-07 +4062 4045 7.748603820801e-07 +4063 4045 55243684.38681 +4064 4045 -1.788139343262e-06 +4065 4045 64813888.87826 +4066 4045 -69150192.34827 +4067 4045 -4.619359970093e-07 +4137 4045 16203472.22755 +4138 4045 -31210863.52938 +4139 4045 -17343750.00569 +4140 4045 -4.097819328308e-06 +4141 4045 -41882340.60423 +4142 4045 1.296401023865e-06 +4143 4045 -16203472.22755 +4144 4045 -31210863.52938 +4145 4045 17343750.0057 +4152 4045 8.970499038696e-06 +4153 4045 -76232648.10075 +4154 4045 -69374999.9886 +4155 4045 4.053115844727e-06 +4156 4045 26913861.39084 +4157 4045 4.738569259644e-06 +4158 4045 -7.331371307373e-06 +4159 4045 -76232648.10076 +4160 4045 69374999.9886 +4170 4045 -16203472.22754 +4171 4045 -31210863.52937 +4172 4045 -17343750.0057 +4173 4045 -1.177191734314e-06 +4174 4045 -41882340.60421 +4175 4045 8.344650268555e-07 +4176 4045 16203472.22754 +4177 4045 -31210863.52937 +4178 4045 17343750.0057 +4046 4046 1217261802.153 +4047 4046 -1.52587890625e-05 +4048 4046 -2.562999725342e-06 +4049 4046 179873780.5718 +4059 4046 -4.231929779053e-06 +4060 4046 -5.811452865601e-07 +4061 4046 -3642360.790142 +4062 4046 -1.54972076416e-05 +4063 4046 -1.907348632813e-06 +4064 4046 109872226.963 +4065 4046 -3.635883331299e-06 +4066 4046 -6.109476089478e-07 +4067 4046 -3642360.79014 +4137 4046 21679861.11823 +4138 4046 -17343750.00569 +4139 4046 -38039431.35476 +4140 4046 86719444.4302 +4141 4046 1.415610313416e-06 +4142 4046 -121047307.7997 +4143 4046 21679861.11823 +4144 4046 17343750.0057 +4145 4046 -38039431.35476 +4152 4046 7.182359695435e-06 +4153 4046 -69374999.9886 +4154 4046 -103546919.3888 +4155 4046 3.02791595459e-05 +4156 4046 4.619359970093e-06 +4157 4046 -289746007.2349 +4158 4046 8.165836334229e-06 +4159 4046 69374999.9886 +4160 4046 -103546919.3888 +4170 4046 -21679861.11823 +4171 4046 -17343750.0057 +4172 4046 -38039431.35476 +4173 4046 -86719444.43019 +4174 4046 8.940696716309e-07 +4175 4046 -121047307.7997 +4176 4046 -21679861.11823 +4177 4046 17343750.0057 +4178 4046 -38039431.35476 +4047 4047 1154306639.95 +4048 4047 4.053115844727e-06 +4049 4047 -5.984306335449e-05 +4050 4047 164134990.0133 +4051 4047 -4.798173904419e-06 +4052 4047 -1.537799835205e-05 +4062 4047 -88595068.35711 +4063 4047 -64813888.87825 +4064 4047 -4.26173210144e-06 +4065 4047 -229938603.1375 +4066 4047 -1.400709152222e-06 +4067 4047 -1.621246337891e-05 +4068 4047 -88595068.35711 +4069 4047 64813888.87826 +4070 4047 -3.75509262085e-06 +4140 4047 -36072082.53399 +4141 4047 16203472.22755 +4142 4047 21679861.11823 +4143 4047 -113177912.5205 +4144 4047 -1.952052116394e-06 +4145 4047 86719444.4302 +4146 4047 -36072082.53399 +4147 4047 -16203472.22755 +4148 4047 21679861.11823 +4155 4047 -14659514.18418 +4156 4047 7.62939453125e-06 +4157 4047 7.152557373047e-06 +4158 4047 65803613.40852 +4159 4047 4.112720489502e-06 +4160 4047 3.081560134888e-05 +4161 4047 -14659514.18418 +4162 4047 -1.010298728943e-05 +4163 4047 8.165836334229e-06 +4173 4047 -36072082.53397 +4174 4047 -16203472.22754 +4175 4047 -21679861.11823 +4176 4047 -113177912.5204 +4177 4047 6.407499313354e-07 +4178 4047 -86719444.43019 +4179 4047 -36072082.53397 +4180 4047 16203472.22755 +4181 4047 -21679861.11823 +4048 4048 998747631.9559 +4049 4048 -6.675720214844e-06 +4050 4048 -3.397464752197e-06 +4051 4048 -82157545.53163 +4052 4048 -2.264976501465e-06 +4062 4048 -64813888.87825 +4063 4048 -69150192.34827 +4064 4048 -6.705522537231e-07 +4065 4048 7.748603820801e-07 +4066 4048 55243684.38681 +4067 4048 -1.788139343262e-06 +4068 4048 64813888.87826 +4069 4048 -69150192.34827 +4070 4048 -4.619359970093e-07 +4140 4048 16203472.22755 +4141 4048 -31210863.52938 +4142 4048 -17343750.00569 +4143 4048 -4.097819328308e-06 +4144 4048 -41882340.60423 +4145 4048 1.296401023865e-06 +4146 4048 -16203472.22755 +4147 4048 -31210863.52938 +4148 4048 17343750.0057 +4155 4048 8.970499038696e-06 +4156 4048 -76232648.10075 +4157 4048 -69374999.9886 +4158 4048 4.053115844727e-06 +4159 4048 26913861.39084 +4160 4048 4.738569259644e-06 +4161 4048 -7.331371307373e-06 +4162 4048 -76232648.10076 +4163 4048 69374999.9886 +4173 4048 -16203472.22754 +4174 4048 -31210863.52937 +4175 4048 -17343750.0057 +4176 4048 -1.177191734314e-06 +4177 4048 -41882340.60421 +4178 4048 8.344650268555e-07 +4179 4048 16203472.22754 +4180 4048 -31210863.52937 +4181 4048 17343750.0057 +4049 4049 1217261802.153 +4050 4049 -1.52587890625e-05 +4051 4049 -2.562999725342e-06 +4052 4049 179873780.5718 +4062 4049 -4.231929779053e-06 +4063 4049 -5.811452865601e-07 +4064 4049 -3642360.790142 +4065 4049 -1.54972076416e-05 +4066 4049 -1.907348632813e-06 +4067 4049 109872226.963 +4068 4049 -3.635883331299e-06 +4069 4049 -6.109476089478e-07 +4070 4049 -3642360.79014 +4140 4049 21679861.11823 +4141 4049 -17343750.00569 +4142 4049 -38039431.35476 +4143 4049 86719444.4302 +4144 4049 1.415610313416e-06 +4145 4049 -121047307.7997 +4146 4049 21679861.11823 +4147 4049 17343750.0057 +4148 4049 -38039431.35476 +4155 4049 7.182359695435e-06 +4156 4049 -69374999.9886 +4157 4049 -103546919.3888 +4158 4049 3.02791595459e-05 +4159 4049 4.619359970093e-06 +4160 4049 -289746007.2349 +4161 4049 8.165836334229e-06 +4162 4049 69374999.9886 +4163 4049 -103546919.3888 +4173 4049 -21679861.11823 +4174 4049 -17343750.0057 +4175 4049 -38039431.35476 +4176 4049 -86719444.43019 +4177 4049 8.940696716309e-07 +4178 4049 -121047307.7997 +4179 4049 -21679861.11823 +4180 4049 17343750.0057 +4181 4049 -38039431.35476 +4050 4050 1154306639.95 +4051 4050 4.053115844727e-06 +4052 4050 -5.984306335449e-05 +4053 4050 164134990.0133 +4054 4050 -4.798173904419e-06 +4055 4050 -1.537799835205e-05 +4065 4050 -88595068.35711 +4066 4050 -64813888.87825 +4067 4050 -4.26173210144e-06 +4068 4050 -229938603.1375 +4069 4050 -1.400709152222e-06 +4070 4050 -1.621246337891e-05 +4071 4050 -88595068.35711 +4072 4050 64813888.87826 +4073 4050 -3.75509262085e-06 +4143 4050 -36072082.53399 +4144 4050 16203472.22755 +4145 4050 21679861.11823 +4146 4050 -113177912.5205 +4147 4050 -1.952052116394e-06 +4148 4050 86719444.4302 +4149 4050 -36072082.53399 +4150 4050 -16203472.22755 +4151 4050 21679861.11823 +4158 4050 -14659514.18418 +4159 4050 7.62939453125e-06 +4160 4050 7.152557373047e-06 +4161 4050 65803613.40852 +4162 4050 4.112720489502e-06 +4163 4050 3.081560134888e-05 +4164 4050 -14659514.18418 +4165 4050 -1.010298728943e-05 +4166 4050 8.165836334229e-06 +4176 4050 -36072082.53397 +4177 4050 -16203472.22754 +4178 4050 -21679861.11823 +4179 4050 -113177912.5204 +4180 4050 6.407499313354e-07 +4181 4050 -86719444.43019 +4182 4050 -36072082.53397 +4183 4050 16203472.22755 +4184 4050 -21679861.11823 +4051 4051 998747631.9559 +4052 4051 -6.675720214844e-06 +4053 4051 -3.397464752197e-06 +4054 4051 -82157545.53163 +4055 4051 -2.264976501465e-06 +4065 4051 -64813888.87825 +4066 4051 -69150192.34827 +4067 4051 -6.705522537231e-07 +4068 4051 7.748603820801e-07 +4069 4051 55243684.38681 +4070 4051 -1.788139343262e-06 +4071 4051 64813888.87826 +4072 4051 -69150192.34827 +4073 4051 -4.619359970093e-07 +4143 4051 16203472.22755 +4144 4051 -31210863.52938 +4145 4051 -17343750.00569 +4146 4051 -4.097819328308e-06 +4147 4051 -41882340.60423 +4148 4051 1.296401023865e-06 +4149 4051 -16203472.22755 +4150 4051 -31210863.52938 +4151 4051 17343750.0057 +4158 4051 8.970499038696e-06 +4159 4051 -76232648.10075 +4160 4051 -69374999.9886 +4161 4051 4.053115844727e-06 +4162 4051 26913861.39084 +4163 4051 4.738569259644e-06 +4164 4051 -7.331371307373e-06 +4165 4051 -76232648.10076 +4166 4051 69374999.9886 +4176 4051 -16203472.22754 +4177 4051 -31210863.52937 +4178 4051 -17343750.0057 +4179 4051 -1.177191734314e-06 +4180 4051 -41882340.60421 +4181 4051 8.344650268555e-07 +4182 4051 16203472.22754 +4183 4051 -31210863.52937 +4184 4051 17343750.0057 +4052 4052 1217261802.153 +4053 4052 -1.52587890625e-05 +4054 4052 -2.562999725342e-06 +4055 4052 179873780.5718 +4065 4052 -4.231929779053e-06 +4066 4052 -5.811452865601e-07 +4067 4052 -3642360.790142 +4068 4052 -1.54972076416e-05 +4069 4052 -1.907348632813e-06 +4070 4052 109872226.963 +4071 4052 -3.635883331299e-06 +4072 4052 -6.109476089478e-07 +4073 4052 -3642360.79014 +4143 4052 21679861.11823 +4144 4052 -17343750.00569 +4145 4052 -38039431.35476 +4146 4052 86719444.4302 +4147 4052 1.415610313416e-06 +4148 4052 -121047307.7997 +4149 4052 21679861.11823 +4150 4052 17343750.0057 +4151 4052 -38039431.35476 +4158 4052 7.182359695435e-06 +4159 4052 -69374999.9886 +4160 4052 -103546919.3888 +4161 4052 3.02791595459e-05 +4162 4052 4.619359970093e-06 +4163 4052 -289746007.2349 +4164 4052 8.165836334229e-06 +4165 4052 69374999.9886 +4166 4052 -103546919.3888 +4176 4052 -21679861.11823 +4177 4052 -17343750.0057 +4178 4052 -38039431.35476 +4179 4052 -86719444.43019 +4180 4052 8.940696716309e-07 +4181 4052 -121047307.7997 +4182 4052 -21679861.11823 +4183 4052 17343750.0057 +4184 4052 -38039431.35476 +4053 4053 1242901705.056 +4054 4053 64813887.58197 +4055 4053 -3.838539123535e-05 +4056 4053 47693290.89467 +4057 4053 -64813888.35975 +4058 4053 -7.510185241699e-06 +4068 4053 -88595068.35711 +4069 4053 -64813888.87825 +4070 4053 -4.26173210144e-06 +4071 4053 -229938603.1375 +4072 4053 -1.400709152222e-06 +4073 4053 -1.621246337891e-05 +4074 4053 -88595068.35711 +4075 4053 64813888.87826 +4076 4053 -3.75509262085e-06 +4146 4053 -36072082.53399 +4147 4053 16203472.22755 +4148 4053 21679861.11823 +4149 4053 -135326679.0277 +4150 4053 -16203472.0331 +4151 4053 86719444.24762 +4161 4053 -14659514.18418 +4162 4053 7.62939453125e-06 +4163 4053 7.152557373047e-06 +4164 4053 101875695.1567 +4165 4053 16203471.90348 +4166 4053 0.03654569387436 +4167 4053 -36808280.87074 +4168 4053 -16203472.09792 +4169 4053 21679860.74398 +4179 4053 -36072082.53397 +4180 4053 -16203472.22754 +4181 4053 -21679861.11823 +4182 4053 -113177912.5204 +4183 4053 6.407499313354e-07 +4184 4053 -86719444.43019 +4185 4053 -36072082.53397 +4186 4053 16203472.22755 +4187 4053 -21679861.11823 +4054 4054 1067897821.637 +4056 4054 -64813888.10049 +4057 4054 -179154367.6044 +4058 4054 -1.16229057312e-05 +4068 4054 -64813888.87825 +4069 4054 -69150192.34827 +4070 4054 -6.705522537231e-07 +4071 4054 7.748603820801e-07 +4072 4054 55243684.38681 +4073 4054 -1.788139343262e-06 +4074 4054 64813888.87826 +4075 4054 -69150192.34827 +4076 4054 -4.619359970093e-07 +4146 4054 16203472.22755 +4147 4054 -31210863.52938 +4148 4054 -17343750.00569 +4149 4054 -16203472.09792 +4150 4054 -59169888.51195 +4151 4054 17343749.94043 +4161 4054 8.970499038696e-06 +4162 4054 -76232648.10075 +4163 4054 -69374999.9886 +4164 4054 16203471.90348 +4165 4054 58124724.28025 +4166 4054 0.029221534729 +4167 4054 -16203472.03311 +4168 4054 -93520195.52346 +4169 4054 69374999.6084 +4179 4054 -16203472.22754 +4180 4054 -31210863.52937 +4181 4054 -17343750.0057 +4182 4054 -1.177191734314e-06 +4183 4054 -41882340.60421 +4184 4054 8.344650268555e-07 +4185 4054 16203472.22754 +4186 4054 -31210863.52937 +4187 4054 17343750.0057 +4055 4055 1220904161.253 +4056 4055 -7.390975952148e-06 +4057 4055 -9.536743164063e-06 +4058 4055 101973736.7139 +4068 4055 -4.231929779053e-06 +4069 4055 -5.811452865601e-07 +4070 4055 -3642360.790142 +4071 4055 -1.54972076416e-05 +4072 4055 -1.907348632813e-06 +4073 4055 109872226.963 +4074 4055 -3.635883331299e-06 +4075 4055 -6.109476089478e-07 +4076 4055 -3642360.79014 +4146 4055 21679861.11823 +4147 4055 -17343750.00569 +4148 4055 -38039431.35476 +4149 4055 86719444.24762 +4150 4055 17343749.9078 +4151 4055 -121957897.9018 +4161 4055 7.182359695435e-06 +4162 4055 -69374999.9886 +4163 4055 -103546919.3888 +4164 4055 -0.03648543357849 +4165 4055 -0.02920261025429 +4166 4055 -251706576.231 +4167 4055 21679860.55685 +4168 4055 69374999.49133 +4169 4055 -104457508.7431 +4179 4055 -21679861.11823 +4180 4055 -17343750.0057 +4181 4055 -38039431.35476 +4182 4055 -86719444.43019 +4183 4055 8.940696716309e-07 +4184 4055 -121047307.7997 +4185 4055 -21679861.11823 +4186 4055 17343750.0057 +4187 4055 -38039431.35476 +4056 4056 733825161.8322 +4057 4056 69874541.14581 +4058 4056 -2.217292785645e-05 +4071 4056 -88595068.35711 +4072 4056 -64813888.87825 +4073 4056 -4.26173210144e-06 +4074 4056 -357844273.783 +4075 4056 -69875651.73839 +4076 4056 -1.627206802368e-05 +4077 4056 31270320.21804 +4078 4056 51852221.69518 +4079 4056 2.145767211914e-06 +4149 4056 -13923315.16199 +4150 4056 19444166.47861 +4151 4056 26015832.7805 +4164 4056 -36808280.87074 +4165 4056 -16203472.0331 +4166 4056 -21679860.55685 +4167 4056 42592361.75168 +4168 4056 17468608.18462 +4169 4056 17682222.18139 +4182 4056 -36072082.53397 +4183 4056 -16203472.22754 +4184 4056 -21679861.11823 +4185 4056 -139005882.4837 +4186 4056 -17468608.05498 +4187 4056 -88411110.90688 +4188 4056 -13882071.21844 +4189 4056 12962777.65241 +4190 4056 -18020555.17262 +4057 4057 630427502.0707 +4058 4057 -7.890164852142e-06 +4071 4057 -64813888.87825 +4072 4057 -69150192.34827 +4073 4057 -6.705522537231e-07 +4074 4057 -69876207.03468 +4075 4057 -50940301.31523 +4076 4057 -8.344650268555e-07 +4077 4057 77778332.54278 +4078 4057 35166790.002 +4079 4057 3.576278686523e-07 +4149 4057 12962777.65241 +4150 4057 -13923315.162 +4151 4057 -13874999.9393 +4164 4057 -16203472.09791 +4165 4057 -93520195.52345 +4166 4057 -69374999.49133 +4167 4057 17468608.18461 +4168 4057 16743847.91338 +4169 4057 14145833.18359 +4182 4057 -16203472.22754 +4183 4057 -31210863.52937 +4184 4057 -17343750.0057 +4185 4057 -17468607.99017 +4186 4057 -62280769.56998 +4187 4057 -18697916.56855 +4188 4057 19444166.47861 +4189 4057 -12907974.64577 +4190 4057 20270833.25379 +4058 4058 770466102.9009 +4071 4058 -4.231929779053e-06 +4072 4058 -5.811452865601e-07 +4073 4058 -3642360.790142 +4074 4058 -1.692771911621e-05 +4075 4058 -1.072883605957e-06 +4076 4058 28643285.85725 +4077 4058 2.741813659668e-06 +4078 4058 3.576278686523e-07 +4079 4058 79491050.79752 +4149 4058 17343888.52033 +4150 4058 -20812499.90894 +4151 4058 -37128840.43198 +4164 4058 -21679860.74397 +4165 4058 -69374999.6084 +4166 4058 -104457508.7431 +4167 4058 -17682222.18136 +4168 4058 -14145833.18358 +4169 4058 -183017309.7474 +4182 4058 -21679861.11823 +4183 4058 -17343750.0057 +4184 4058 -38039431.35476 +4185 4058 -88411110.90688 +4186 4058 -18697916.60118 +4187 4058 -124962011.2801 +4188 4058 -27030832.75893 +4189 4058 13062499.95656 +4190 4058 -37992953.15517 +4059 4059 1154306639.95 +4060 4059 4.053115844727e-06 +4061 4059 -5.984306335449e-05 +4062 4059 164134990.0133 +4063 4059 -4.798173904419e-06 +4064 4059 -1.537799835205e-05 +4080 4059 -229938603.1375 +4081 4059 -1.400709152222e-06 +4082 4059 -1.621246337891e-05 +4083 4059 -88595068.35711 +4084 4059 64813888.87826 +4085 4059 -3.75509262085e-06 +4152 4059 -113177912.5205 +4153 4059 -1.952052116394e-06 +4154 4059 86719444.4302 +4155 4059 -36072082.53399 +4156 4059 -16203472.22755 +4157 4059 21679861.11823 +4170 4059 65803613.40852 +4171 4059 4.112720489502e-06 +4172 4059 3.081560134888e-05 +4173 4059 -14659514.18418 +4174 4059 -1.010298728943e-05 +4175 4059 8.165836334229e-06 +4191 4059 -113177912.5204 +4192 4059 6.407499313354e-07 +4193 4059 -86719444.43019 +4194 4059 -36072082.53397 +4195 4059 16203472.22755 +4196 4059 -21679861.11823 +4060 4060 998747631.9559 +4061 4060 -6.675720214844e-06 +4062 4060 -3.397464752197e-06 +4063 4060 -82157545.53163 +4064 4060 -2.264976501465e-06 +4080 4060 7.748603820801e-07 +4081 4060 55243684.38681 +4082 4060 -1.788139343262e-06 +4083 4060 64813888.87826 +4084 4060 -69150192.34827 +4085 4060 -4.619359970093e-07 +4152 4060 -4.097819328308e-06 +4153 4060 -41882340.60423 +4154 4060 1.296401023865e-06 +4155 4060 -16203472.22755 +4156 4060 -31210863.52938 +4157 4060 17343750.0057 +4170 4060 4.053115844727e-06 +4171 4060 26913861.39084 +4172 4060 4.738569259644e-06 +4173 4060 -7.331371307373e-06 +4174 4060 -76232648.10076 +4175 4060 69374999.9886 +4191 4060 -1.177191734314e-06 +4192 4060 -41882340.60421 +4193 4060 8.344650268555e-07 +4194 4060 16203472.22754 +4195 4060 -31210863.52937 +4196 4060 17343750.0057 +4061 4061 1217261802.153 +4062 4061 -1.52587890625e-05 +4063 4061 -2.562999725342e-06 +4064 4061 179873780.5718 +4080 4061 -1.54972076416e-05 +4081 4061 -1.907348632813e-06 +4082 4061 109872226.963 +4083 4061 -3.635883331299e-06 +4084 4061 -6.109476089478e-07 +4085 4061 -3642360.79014 +4152 4061 86719444.4302 +4153 4061 1.415610313416e-06 +4154 4061 -121047307.7997 +4155 4061 21679861.11823 +4156 4061 17343750.0057 +4157 4061 -38039431.35476 +4170 4061 3.02791595459e-05 +4171 4061 4.619359970093e-06 +4172 4061 -289746007.2349 +4173 4061 8.165836334229e-06 +4174 4061 69374999.9886 +4175 4061 -103546919.3888 +4191 4061 -86719444.43019 +4192 4061 8.940696716309e-07 +4193 4061 -121047307.7997 +4194 4061 -21679861.11823 +4195 4061 17343750.0057 +4196 4061 -38039431.35476 +4062 4062 1154306639.95 +4063 4062 4.053115844727e-06 +4064 4062 -5.984306335449e-05 +4065 4062 164134990.0133 +4066 4062 -4.798173904419e-06 +4067 4062 -1.537799835205e-05 +4080 4062 -88595068.35711 +4081 4062 -64813888.87825 +4082 4062 -4.26173210144e-06 +4083 4062 -229938603.1375 +4084 4062 -1.400709152222e-06 +4085 4062 -1.621246337891e-05 +4086 4062 -88595068.35711 +4087 4062 64813888.87826 +4088 4062 -3.75509262085e-06 +4152 4062 -36072082.53399 +4153 4062 16203472.22755 +4154 4062 21679861.11823 +4155 4062 -113177912.5205 +4156 4062 -1.952052116394e-06 +4157 4062 86719444.4302 +4158 4062 -36072082.53399 +4159 4062 -16203472.22755 +4160 4062 21679861.11823 +4170 4062 -14659514.18418 +4171 4062 7.62939453125e-06 +4172 4062 7.152557373047e-06 +4173 4062 65803613.40852 +4174 4062 4.112720489502e-06 +4175 4062 3.081560134888e-05 +4176 4062 -14659514.18418 +4177 4062 -1.010298728943e-05 +4178 4062 8.165836334229e-06 +4191 4062 -36072082.53397 +4192 4062 -16203472.22754 +4193 4062 -21679861.11823 +4194 4062 -113177912.5204 +4195 4062 6.407499313354e-07 +4196 4062 -86719444.43019 +4197 4062 -36072082.53397 +4198 4062 16203472.22755 +4199 4062 -21679861.11823 +4063 4063 998747631.9559 +4064 4063 -6.675720214844e-06 +4065 4063 -3.397464752197e-06 +4066 4063 -82157545.53163 +4067 4063 -2.264976501465e-06 +4080 4063 -64813888.87825 +4081 4063 -69150192.34827 +4082 4063 -6.705522537231e-07 +4083 4063 7.748603820801e-07 +4084 4063 55243684.38681 +4085 4063 -1.788139343262e-06 +4086 4063 64813888.87826 +4087 4063 -69150192.34827 +4088 4063 -4.619359970093e-07 +4152 4063 16203472.22755 +4153 4063 -31210863.52938 +4154 4063 -17343750.00569 +4155 4063 -4.097819328308e-06 +4156 4063 -41882340.60423 +4157 4063 1.296401023865e-06 +4158 4063 -16203472.22755 +4159 4063 -31210863.52938 +4160 4063 17343750.0057 +4170 4063 8.970499038696e-06 +4171 4063 -76232648.10075 +4172 4063 -69374999.9886 +4173 4063 4.053115844727e-06 +4174 4063 26913861.39084 +4175 4063 4.738569259644e-06 +4176 4063 -7.331371307373e-06 +4177 4063 -76232648.10076 +4178 4063 69374999.9886 +4191 4063 -16203472.22754 +4192 4063 -31210863.52937 +4193 4063 -17343750.0057 +4194 4063 -1.177191734314e-06 +4195 4063 -41882340.60421 +4196 4063 8.344650268555e-07 +4197 4063 16203472.22754 +4198 4063 -31210863.52937 +4199 4063 17343750.0057 +4064 4064 1217261802.153 +4065 4064 -1.52587890625e-05 +4066 4064 -2.562999725342e-06 +4067 4064 179873780.5718 +4080 4064 -4.231929779053e-06 +4081 4064 -5.811452865601e-07 +4082 4064 -3642360.790142 +4083 4064 -1.54972076416e-05 +4084 4064 -1.907348632813e-06 +4085 4064 109872226.963 +4086 4064 -3.635883331299e-06 +4087 4064 -6.109476089478e-07 +4088 4064 -3642360.79014 +4152 4064 21679861.11823 +4153 4064 -17343750.00569 +4154 4064 -38039431.35476 +4155 4064 86719444.4302 +4156 4064 1.415610313416e-06 +4157 4064 -121047307.7997 +4158 4064 21679861.11823 +4159 4064 17343750.0057 +4160 4064 -38039431.35476 +4170 4064 7.182359695435e-06 +4171 4064 -69374999.9886 +4172 4064 -103546919.3888 +4173 4064 3.02791595459e-05 +4174 4064 4.619359970093e-06 +4175 4064 -289746007.2349 +4176 4064 8.165836334229e-06 +4177 4064 69374999.9886 +4178 4064 -103546919.3888 +4191 4064 -21679861.11823 +4192 4064 -17343750.0057 +4193 4064 -38039431.35476 +4194 4064 -86719444.43019 +4195 4064 8.940696716309e-07 +4196 4064 -121047307.7997 +4197 4064 -21679861.11823 +4198 4064 17343750.0057 +4199 4064 -38039431.35476 +4065 4065 1154306639.95 +4066 4065 4.053115844727e-06 +4067 4065 -5.984306335449e-05 +4068 4065 164134990.0133 +4069 4065 -4.798173904419e-06 +4070 4065 -1.537799835205e-05 +4083 4065 -88595068.35711 +4084 4065 -64813888.87825 +4085 4065 -4.26173210144e-06 +4086 4065 -229938603.1375 +4087 4065 -1.400709152222e-06 +4088 4065 -1.621246337891e-05 +4089 4065 -88595068.35711 +4090 4065 64813888.87826 +4091 4065 -3.75509262085e-06 +4155 4065 -36072082.53399 +4156 4065 16203472.22755 +4157 4065 21679861.11823 +4158 4065 -113177912.5205 +4159 4065 -1.952052116394e-06 +4160 4065 86719444.4302 +4161 4065 -36072082.53399 +4162 4065 -16203472.22755 +4163 4065 21679861.11823 +4173 4065 -14659514.18418 +4174 4065 7.62939453125e-06 +4175 4065 7.152557373047e-06 +4176 4065 65803613.40852 +4177 4065 4.112720489502e-06 +4178 4065 3.081560134888e-05 +4179 4065 -14659514.18418 +4180 4065 -1.010298728943e-05 +4181 4065 8.165836334229e-06 +4194 4065 -36072082.53397 +4195 4065 -16203472.22754 +4196 4065 -21679861.11823 +4197 4065 -113177912.5204 +4198 4065 6.407499313354e-07 +4199 4065 -86719444.43019 +4200 4065 -36072082.53397 +4201 4065 16203472.22755 +4202 4065 -21679861.11823 +4066 4066 998747631.9559 +4067 4066 -6.675720214844e-06 +4068 4066 -3.397464752197e-06 +4069 4066 -82157545.53163 +4070 4066 -2.264976501465e-06 +4083 4066 -64813888.87825 +4084 4066 -69150192.34827 +4085 4066 -6.705522537231e-07 +4086 4066 7.748603820801e-07 +4087 4066 55243684.38681 +4088 4066 -1.788139343262e-06 +4089 4066 64813888.87826 +4090 4066 -69150192.34827 +4091 4066 -4.619359970093e-07 +4155 4066 16203472.22755 +4156 4066 -31210863.52938 +4157 4066 -17343750.00569 +4158 4066 -4.097819328308e-06 +4159 4066 -41882340.60423 +4160 4066 1.296401023865e-06 +4161 4066 -16203472.22755 +4162 4066 -31210863.52938 +4163 4066 17343750.0057 +4173 4066 8.970499038696e-06 +4174 4066 -76232648.10075 +4175 4066 -69374999.9886 +4176 4066 4.053115844727e-06 +4177 4066 26913861.39084 +4178 4066 4.738569259644e-06 +4179 4066 -7.331371307373e-06 +4180 4066 -76232648.10076 +4181 4066 69374999.9886 +4194 4066 -16203472.22754 +4195 4066 -31210863.52937 +4196 4066 -17343750.0057 +4197 4066 -1.177191734314e-06 +4198 4066 -41882340.60421 +4199 4066 8.344650268555e-07 +4200 4066 16203472.22754 +4201 4066 -31210863.52937 +4202 4066 17343750.0057 +4067 4067 1217261802.153 +4068 4067 -1.52587890625e-05 +4069 4067 -2.562999725342e-06 +4070 4067 179873780.5718 +4083 4067 -4.231929779053e-06 +4084 4067 -5.811452865601e-07 +4085 4067 -3642360.790142 +4086 4067 -1.54972076416e-05 +4087 4067 -1.907348632813e-06 +4088 4067 109872226.963 +4089 4067 -3.635883331299e-06 +4090 4067 -6.109476089478e-07 +4091 4067 -3642360.79014 +4155 4067 21679861.11823 +4156 4067 -17343750.00569 +4157 4067 -38039431.35476 +4158 4067 86719444.4302 +4159 4067 1.415610313416e-06 +4160 4067 -121047307.7997 +4161 4067 21679861.11823 +4162 4067 17343750.0057 +4163 4067 -38039431.35476 +4173 4067 7.182359695435e-06 +4174 4067 -69374999.9886 +4175 4067 -103546919.3888 +4176 4067 3.02791595459e-05 +4177 4067 4.619359970093e-06 +4178 4067 -289746007.2349 +4179 4067 8.165836334229e-06 +4180 4067 69374999.9886 +4181 4067 -103546919.3888 +4194 4067 -21679861.11823 +4195 4067 -17343750.0057 +4196 4067 -38039431.35476 +4197 4067 -86719444.43019 +4198 4067 8.940696716309e-07 +4199 4067 -121047307.7997 +4200 4067 -21679861.11823 +4201 4067 17343750.0057 +4202 4067 -38039431.35476 +4068 4068 1154306639.95 +4069 4068 4.053115844727e-06 +4070 4068 -5.984306335449e-05 +4071 4068 164134990.0133 +4072 4068 -4.798173904419e-06 +4073 4068 -1.537799835205e-05 +4086 4068 -88595068.35711 +4087 4068 -64813888.87825 +4088 4068 -4.26173210144e-06 +4089 4068 -229938603.1375 +4090 4068 -1.400709152222e-06 +4091 4068 -1.621246337891e-05 +4092 4068 -88595068.35711 +4093 4068 64813888.87826 +4094 4068 -3.75509262085e-06 +4158 4068 -36072082.53399 +4159 4068 16203472.22755 +4160 4068 21679861.11823 +4161 4068 -113177912.5205 +4162 4068 -1.952052116394e-06 +4163 4068 86719444.4302 +4164 4068 -36072082.53399 +4165 4068 -16203472.22755 +4166 4068 21679861.11823 +4176 4068 -14659514.18418 +4177 4068 7.62939453125e-06 +4178 4068 7.152557373047e-06 +4179 4068 65803613.40852 +4180 4068 4.112720489502e-06 +4181 4068 3.081560134888e-05 +4182 4068 -14659514.18418 +4183 4068 -1.010298728943e-05 +4184 4068 8.165836334229e-06 +4197 4068 -36072082.53397 +4198 4068 -16203472.22754 +4199 4068 -21679861.11823 +4200 4068 -113177912.5204 +4201 4068 6.407499313354e-07 +4202 4068 -86719444.43019 +4203 4068 -36072082.53397 +4204 4068 16203472.22755 +4205 4068 -21679861.11823 +4069 4069 998747631.9559 +4070 4069 -6.675720214844e-06 +4071 4069 -3.397464752197e-06 +4072 4069 -82157545.53163 +4073 4069 -2.264976501465e-06 +4086 4069 -64813888.87825 +4087 4069 -69150192.34827 +4088 4069 -6.705522537231e-07 +4089 4069 7.748603820801e-07 +4090 4069 55243684.38681 +4091 4069 -1.788139343262e-06 +4092 4069 64813888.87826 +4093 4069 -69150192.34827 +4094 4069 -4.619359970093e-07 +4158 4069 16203472.22755 +4159 4069 -31210863.52938 +4160 4069 -17343750.00569 +4161 4069 -4.097819328308e-06 +4162 4069 -41882340.60423 +4163 4069 1.296401023865e-06 +4164 4069 -16203472.22755 +4165 4069 -31210863.52938 +4166 4069 17343750.0057 +4176 4069 8.970499038696e-06 +4177 4069 -76232648.10075 +4178 4069 -69374999.9886 +4179 4069 4.053115844727e-06 +4180 4069 26913861.39084 +4181 4069 4.738569259644e-06 +4182 4069 -7.331371307373e-06 +4183 4069 -76232648.10076 +4184 4069 69374999.9886 +4197 4069 -16203472.22754 +4198 4069 -31210863.52937 +4199 4069 -17343750.0057 +4200 4069 -1.177191734314e-06 +4201 4069 -41882340.60421 +4202 4069 8.344650268555e-07 +4203 4069 16203472.22754 +4204 4069 -31210863.52937 +4205 4069 17343750.0057 +4070 4070 1217261802.153 +4071 4070 -1.52587890625e-05 +4072 4070 -2.562999725342e-06 +4073 4070 179873780.5718 +4086 4070 -4.231929779053e-06 +4087 4070 -5.811452865601e-07 +4088 4070 -3642360.790142 +4089 4070 -1.54972076416e-05 +4090 4070 -1.907348632813e-06 +4091 4070 109872226.963 +4092 4070 -3.635883331299e-06 +4093 4070 -6.109476089478e-07 +4094 4070 -3642360.79014 +4158 4070 21679861.11823 +4159 4070 -17343750.00569 +4160 4070 -38039431.35476 +4161 4070 86719444.4302 +4162 4070 1.415610313416e-06 +4163 4070 -121047307.7997 +4164 4070 21679861.11823 +4165 4070 17343750.0057 +4166 4070 -38039431.35476 +4176 4070 7.182359695435e-06 +4177 4070 -69374999.9886 +4178 4070 -103546919.3888 +4179 4070 3.02791595459e-05 +4180 4070 4.619359970093e-06 +4181 4070 -289746007.2349 +4182 4070 8.165836334229e-06 +4183 4070 69374999.9886 +4184 4070 -103546919.3888 +4197 4070 -21679861.11823 +4198 4070 -17343750.0057 +4199 4070 -38039431.35476 +4200 4070 -86719444.43019 +4201 4070 8.940696716309e-07 +4202 4070 -121047307.7997 +4203 4070 -21679861.11823 +4204 4070 17343750.0057 +4205 4070 -38039431.35476 +4071 4071 1154306639.95 +4072 4071 4.053115844727e-06 +4073 4071 -5.984306335449e-05 +4074 4071 164134990.0133 +4075 4071 -4.798173904419e-06 +4076 4071 -1.537799835205e-05 +4089 4071 -88595068.35711 +4090 4071 -64813888.87825 +4091 4071 -4.26173210144e-06 +4092 4071 -229938603.1375 +4093 4071 -1.400709152222e-06 +4094 4071 -1.621246337891e-05 +4095 4071 -88595068.35711 +4096 4071 64813888.87826 +4097 4071 -3.75509262085e-06 +4161 4071 -36072082.53399 +4162 4071 16203472.22755 +4163 4071 21679861.11823 +4164 4071 -113177912.5205 +4165 4071 -1.952052116394e-06 +4166 4071 86719444.4302 +4167 4071 -36072082.53399 +4168 4071 -16203472.22755 +4169 4071 21679861.11823 +4179 4071 -14659514.18418 +4180 4071 7.62939453125e-06 +4181 4071 7.152557373047e-06 +4182 4071 65803613.40852 +4183 4071 4.112720489502e-06 +4184 4071 3.081560134888e-05 +4185 4071 -14659514.18418 +4186 4071 -1.010298728943e-05 +4187 4071 8.165836334229e-06 +4200 4071 -36072082.53397 +4201 4071 -16203472.22754 +4202 4071 -21679861.11823 +4203 4071 -113177912.5204 +4204 4071 6.407499313354e-07 +4205 4071 -86719444.43019 +4206 4071 -36072082.53397 +4207 4071 16203472.22755 +4208 4071 -21679861.11823 +4072 4072 998747631.9559 +4073 4072 -6.675720214844e-06 +4074 4072 -3.397464752197e-06 +4075 4072 -82157545.53163 +4076 4072 -2.264976501465e-06 +4089 4072 -64813888.87825 +4090 4072 -69150192.34827 +4091 4072 -6.705522537231e-07 +4092 4072 7.748603820801e-07 +4093 4072 55243684.38681 +4094 4072 -1.788139343262e-06 +4095 4072 64813888.87826 +4096 4072 -69150192.34827 +4097 4072 -4.619359970093e-07 +4161 4072 16203472.22755 +4162 4072 -31210863.52938 +4163 4072 -17343750.00569 +4164 4072 -4.097819328308e-06 +4165 4072 -41882340.60423 +4166 4072 1.296401023865e-06 +4167 4072 -16203472.22755 +4168 4072 -31210863.52938 +4169 4072 17343750.0057 +4179 4072 8.970499038696e-06 +4180 4072 -76232648.10075 +4181 4072 -69374999.9886 +4182 4072 4.053115844727e-06 +4183 4072 26913861.39084 +4184 4072 4.738569259644e-06 +4185 4072 -7.331371307373e-06 +4186 4072 -76232648.10076 +4187 4072 69374999.9886 +4200 4072 -16203472.22754 +4201 4072 -31210863.52937 +4202 4072 -17343750.0057 +4203 4072 -1.177191734314e-06 +4204 4072 -41882340.60421 +4205 4072 8.344650268555e-07 +4206 4072 16203472.22754 +4207 4072 -31210863.52937 +4208 4072 17343750.0057 +4073 4073 1217261802.153 +4074 4073 -1.52587890625e-05 +4075 4073 -2.562999725342e-06 +4076 4073 179873780.5718 +4089 4073 -4.231929779053e-06 +4090 4073 -5.811452865601e-07 +4091 4073 -3642360.790142 +4092 4073 -1.54972076416e-05 +4093 4073 -1.907348632813e-06 +4094 4073 109872226.963 +4095 4073 -3.635883331299e-06 +4096 4073 -6.109476089478e-07 +4097 4073 -3642360.79014 +4161 4073 21679861.11823 +4162 4073 -17343750.00569 +4163 4073 -38039431.35476 +4164 4073 86719444.4302 +4165 4073 1.415610313416e-06 +4166 4073 -121047307.7997 +4167 4073 21679861.11823 +4168 4073 17343750.0057 +4169 4073 -38039431.35476 +4179 4073 7.182359695435e-06 +4180 4073 -69374999.9886 +4181 4073 -103546919.3888 +4182 4073 3.02791595459e-05 +4183 4073 4.619359970093e-06 +4184 4073 -289746007.2349 +4185 4073 8.165836334229e-06 +4186 4073 69374999.9886 +4187 4073 -103546919.3888 +4200 4073 -21679861.11823 +4201 4073 -17343750.0057 +4202 4073 -38039431.35476 +4203 4073 -86719444.43019 +4204 4073 8.940696716309e-07 +4205 4073 -121047307.7997 +4206 4073 -21679861.11823 +4207 4073 17343750.0057 +4208 4073 -38039431.35476 +4074 4074 1264143404.142 +4075 4074 69984496.09989 +4076 4074 -4.458427429199e-05 +4077 4074 56216718.86036 +4078 4074 -62295134.4999 +4079 4074 -1.54972076416e-06 +4092 4074 -88595068.35711 +4093 4074 -64813888.87825 +4094 4074 -4.26173210144e-06 +4095 4074 -235044286.8786 +4096 4074 -2540789.090044 +4097 4074 -1.227855682373e-05 +4098 4074 -95281145.70689 +4099 4074 64727634.52473 +4100 4074 3.576278686523e-06 +4164 4074 -36072082.53399 +4165 4074 16203472.22755 +4166 4074 21679861.11823 +4167 4074 -139005882.4837 +4168 4074 -17468607.99017 +4169 4074 88411110.90689 +4182 4074 -14659514.18418 +4183 4074 7.62939453125e-06 +4184 4074 7.152557373047e-06 +4185 4074 104468568.1069 +4186 4074 17495749.11933 +4187 4074 0.03796529769897 +4188 4074 -35762896.95689 +4189 4074 -15573449.91109 +4190 4074 21679166.28526 +4203 4074 -36072082.53397 +4204 4074 -16203472.22754 +4205 4074 -21679861.11823 +4206 4074 -114724288.833 +4207 4074 -635253.1045082 +4208 4074 -87564583.31886 +4209 4074 -37742508.837 +4210 4074 16181561.88644 +4211 4074 -22525694.45184 +4075 4075 1075589634.327 +4076 4075 1.180171966553e-05 +4077 4075 -62295134.24064 +4078 4075 -170484887.2683 +4079 4075 -5.960464477539e-06 +4092 4075 -64813888.87825 +4093 4075 -69150192.34827 +4094 4075 -6.705522537231e-07 +4095 4075 -2541344.645597 +4096 4075 52569923.74254 +4097 4075 4.887580871582e-06 +4098 4075 64727634.52473 +4099 4075 -67141169.32471 +4164 4075 16203472.22755 +4165 4075 -31210863.52938 +4166 4075 -17343750.00569 +4167 4075 -17468608.05498 +4168 4075 -62280769.56999 +4169 4075 18697916.60118 +4182 4075 8.970499038696e-06 +4183 4075 -76232648.10075 +4184 4075 -69374999.9886 +4185 4075 17495749.11932 +4186 4075 57330719.05925 +4187 4075 0.0303547680378 +4188 4075 -15573449.84628 +4189 4075 -92437084.05277 +4190 4075 69374999.59698 +4203 4075 -16203472.22754 +4204 4075 -31210863.52937 +4205 4075 -17343750.0057 +4206 4075 -635253.1045087 +4207 4075 -42821513.04609 +4208 4075 -677083.3331559 +4209 4075 16181561.88644 +4210 4075 -30707665.48679 +4211 4075 16666666.67214 +4076 4076 1236468691.55 +4077 4076 -1.54972076416e-06 +4078 4076 -5.69224357605e-06 +4079 4076 109730878.4261 +4092 4076 -4.231929779053e-06 +4093 4076 -5.811452865601e-07 +4094 4076 -3642360.790142 +4095 4076 -1.347064971924e-05 +4096 4076 4.768371582031e-06 +4097 4076 108515321.757 +4098 4076 3.635883331299e-06 +4099 4076 -1.490116119385e-08 +4100 4076 -4919850.093637 +4164 4076 21679861.11823 +4165 4076 -17343750.00569 +4166 4076 -38039431.35476 +4167 4076 88411110.90689 +4168 4076 18697916.56855 +4169 4076 -124962011.2801 +4182 4076 7.182359695435e-06 +4183 4076 -69374999.9886 +4184 4076 -103546919.3888 +4185 4076 -0.03791528940201 +4186 4076 -0.03035008907318 +4187 4076 -255055797.8371 +4188 4076 21679166.091 +4189 4076 69374999.4742 +4190 4076 -105412602.9399 +4203 4076 -21679861.11823 +4204 4076 -17343750.0057 +4205 4076 -38039431.35476 +4206 4076 -87564583.31903 +4207 4076 -677083.3332893 +4208 4076 -122108417.4801 +4209 4076 -22525694.45184 +4210 4076 16666666.67214 +4211 4076 -38357223.71349 +4077 4077 696472573.0655 +4078 4077 -1771689.826609 +4079 4077 1.192092895508e-06 +4095 4077 -87258192.16972 +4096 4077 -64804100.71711 +4097 4077 -4.500150680542e-06 +4098 4077 -242104687.4354 +4099 4077 -3424057.139935 +4100 4077 -8.940696716309e-07 +4101 4077 75831742.92238 +4102 4077 -11180768.61541 +4103 4077 -2.026557922363e-06 +4104 4077 -95109676.42566 +4105 4077 65697417.99692 +4106 4077 6.526708602905e-06 +4167 4077 -13882071.21844 +4168 4077 19444166.47861 +4169 4077 27030832.75893 +4185 4077 -35762896.9569 +4186 4077 -15573449.84628 +4187 4077 -21679166.091 +4188 4077 24359103.43618 +4189 4077 -442912.965739 +4190 4077 17135277.77496 +4206 4077 -35736813.43153 +4207 4077 -16200678.02491 +4208 4077 -21679166.67379 +4209 4077 -113692433.8764 +4210 4077 -855995.9423768 +4211 4077 -85676388.87482 +4212 4077 -6375113.374567 +4213 4077 -2795132.258682 +4214 4077 3215972.223778 +4215 4077 -36573838.1928 +4216 4077 16424002.55938 +4217 4077 -21159027.78473 +4078 4078 713868420.1604 +4079 4078 2.408027648926e-05 +4095 4078 -64804100.71711 +4096 4078 -69555876.00861 +4097 4078 -4.619359970093e-07 +4098 4078 -3424057.139936 +4099 4078 46038548.55542 +4100 4078 1.239776611328e-05 +4101 4078 14745342.49144 +4102 4078 -46950609.66777 +4103 4078 -4.500150680542e-06 +4104 4078 65697417.99692 +4105 4078 -72763586.73755 +4106 4078 -1.296401023865e-06 +4167 4078 12962777.65241 +4168 4078 -12907974.64577 +4169 4078 -13062499.95656 +4185 4078 -15573449.91109 +4186 4078 -92437084.05278 +4187 4078 -69374999.4742 +4188 4078 -442912.96574 +4189 4078 28707972.02065 +4190 4078 7208333.185868 +4206 4078 -16200678.02491 +4207 4078 -31311329.22223 +4208 4078 -17343750.0057 +4209 4078 -855995.9423762 +4210 4078 -41658168.45665 +4211 4078 -677083.3331569 +4212 4078 3686256.632335 +4213 4078 -37070043.77932 +4214 4078 33333333.32785 +4215 4078 16424002.55938 +4216 4078 -30987435.47836 +4217 4078 16666666.67214 +4079 4079 808185795.747 +4095 4079 -4.52995300293e-06 +4096 4079 -4.619359970093e-07 +4097 4079 -3390328.224563 +4098 4079 -1.132488250732e-06 +4099 4079 1.233816146851e-05 +4100 4079 96899236.61815 +4101 4079 3.576278686523e-07 +4102 4079 -4.738569259644e-06 +4103 4079 79524039.77179 +4104 4079 6.139278411865e-06 +4105 4079 -1.35600566864e-06 +4106 4079 -9590542.374572 +4167 4079 18020555.17262 +4168 4079 -20270833.25379 +4169 4079 -37992953.15518 +4185 4079 -21679166.28526 +4186 4079 -69374999.59698 +4187 4079 -105412602.9399 +4188 4079 -17135277.77496 +4189 4079 -7208333.185865 +4190 4079 -197305370.7384 +4206 4079 -21679166.67379 +4207 4079 -17343750.0057 +4208 4079 -37974851.43985 +4209 4079 -85676388.87482 +4210 4079 -677083.3332903 +4211 4079 -117555867.1805 +4212 4079 -4909027.779057 +4213 4079 33333333.32785 +4214 4079 -47673130.40165 +4215 4079 -21159027.78473 +4216 4079 16666666.67214 +4217 4079 -36522727.11637 +4080 4080 577153319.975 +4081 4080 -3.814697265625e-06 +4082 4080 -3.170967102051e-05 +4083 4080 82067495.00666 +4084 4080 12962777.77565 +4085 4080 -7.867813110352e-06 +4170 4080 -113177912.5205 +4171 4080 -1.952052116394e-06 +4172 4080 86719444.4302 +4173 4080 -36072082.53399 +4174 4080 -16203472.22755 +4175 4080 21679861.11823 +4191 4080 32901806.70425 +4192 4080 2.026557922363e-06 +4193 4080 -17343888.88602 +4194 4080 -7329757.09209 +4195 4080 3240694.445505 +4196 4080 -4335972.223642 +4081 4081 499373815.978 +4082 4081 1.025199890137e-05 +4083 4081 -12962777.77565 +4084 4081 -41078772.7658 +4085 4081 2.264976501465e-06 +4170 4081 -4.097819328308e-06 +4171 4081 -41882340.60423 +4172 4081 1.296401023865e-06 +4173 4081 -16203472.22755 +4174 4081 -31210863.52938 +4175 4081 17343750.0057 +4191 4081 1.430511474609e-06 +4192 4081 13456930.69541 +4193 4081 -4.410743713379e-06 +4194 4081 -3240694.445512 +4195 4081 -38116324.05037 +4196 4081 34687499.9943 +4082 4082 608630901.0765 +4083 4082 -7.867813110352e-06 +4084 4082 2.115964889526e-06 +4085 4082 89936890.28591 +4170 4082 86719444.4302 +4171 4082 1.415610313416e-06 +4172 4082 -121047307.7997 +4173 4082 21679861.11823 +4174 4082 17343750.0057 +4175 4082 -38039431.35476 +4191 4082 17343888.88605 +4192 4082 -4.410743713379e-06 +4193 4082 -144873003.6175 +4194 4082 4335972.22365 +4195 4082 34687499.9943 +4196 4082 -51773459.69442 +4083 4083 577153319.975 +4084 4083 -3.814697265625e-06 +4085 4083 -3.170967102051e-05 +4086 4083 82067495.00666 +4087 4083 12962777.77565 +4088 4083 -7.867813110352e-06 +4170 4083 -36072082.53399 +4171 4083 16203472.22755 +4172 4083 21679861.11823 +4173 4083 -113177912.5205 +4174 4083 -1.952052116394e-06 +4175 4083 86719444.4302 +4176 4083 -36072082.53399 +4177 4083 -16203472.22755 +4178 4083 21679861.11823 +4191 4083 -7329757.092094 +4192 4083 -3240694.445505 +4193 4083 -4335972.223642 +4194 4083 32901806.70425 +4195 4083 2.026557922363e-06 +4196 4083 -17343888.88602 +4197 4083 -7329757.09209 +4198 4083 3240694.445505 +4199 4083 -4335972.223642 +4084 4084 499373815.978 +4085 4084 1.025199890137e-05 +4086 4084 -12962777.77565 +4087 4084 -41078772.7658 +4088 4084 2.264976501465e-06 +4170 4084 16203472.22755 +4171 4084 -31210863.52938 +4172 4084 -17343750.00569 +4173 4084 -4.097819328308e-06 +4174 4084 -41882340.60423 +4175 4084 1.296401023865e-06 +4176 4084 -16203472.22755 +4177 4084 -31210863.52938 +4178 4084 17343750.0057 +4191 4084 3240694.445514 +4192 4084 -38116324.05038 +4193 4084 -34687499.9943 +4194 4084 1.430511474609e-06 +4195 4084 13456930.69541 +4196 4084 -4.410743713379e-06 +4197 4084 -3240694.445512 +4198 4084 -38116324.05037 +4199 4084 34687499.9943 +4085 4085 608630901.0765 +4086 4085 -7.867813110352e-06 +4087 4085 2.115964889526e-06 +4088 4085 89936890.28591 +4170 4085 21679861.11823 +4171 4085 -17343750.00569 +4172 4085 -38039431.35476 +4173 4085 86719444.4302 +4174 4085 1.415610313416e-06 +4175 4085 -121047307.7997 +4176 4085 21679861.11823 +4177 4085 17343750.0057 +4178 4085 -38039431.35476 +4191 4085 4335972.22365 +4192 4085 -34687499.9943 +4193 4085 -51773459.69442 +4194 4085 17343888.88605 +4195 4085 -4.410743713379e-06 +4196 4085 -144873003.6175 +4197 4085 4335972.22365 +4198 4085 34687499.9943 +4199 4085 -51773459.69442 +4086 4086 577153319.975 +4087 4086 -3.814697265625e-06 +4088 4086 -3.170967102051e-05 +4089 4086 82067495.00666 +4090 4086 12962777.77565 +4091 4086 -7.867813110352e-06 +4173 4086 -36072082.53399 +4174 4086 16203472.22755 +4175 4086 21679861.11823 +4176 4086 -113177912.5205 +4177 4086 -1.952052116394e-06 +4178 4086 86719444.4302 +4179 4086 -36072082.53399 +4180 4086 -16203472.22755 +4181 4086 21679861.11823 +4194 4086 -7329757.092094 +4195 4086 -3240694.445505 +4196 4086 -4335972.223642 +4197 4086 32901806.70425 +4198 4086 2.026557922363e-06 +4199 4086 -17343888.88602 +4200 4086 -7329757.09209 +4201 4086 3240694.445505 +4202 4086 -4335972.223642 +4087 4087 499373815.978 +4088 4087 1.025199890137e-05 +4089 4087 -12962777.77565 +4090 4087 -41078772.7658 +4091 4087 2.264976501465e-06 +4173 4087 16203472.22755 +4174 4087 -31210863.52938 +4175 4087 -17343750.00569 +4176 4087 -4.097819328308e-06 +4177 4087 -41882340.60423 +4178 4087 1.296401023865e-06 +4179 4087 -16203472.22755 +4180 4087 -31210863.52938 +4181 4087 17343750.0057 +4194 4087 3240694.445514 +4195 4087 -38116324.05038 +4196 4087 -34687499.9943 +4197 4087 1.430511474609e-06 +4198 4087 13456930.69541 +4199 4087 -4.410743713379e-06 +4200 4087 -3240694.445512 +4201 4087 -38116324.05037 +4202 4087 34687499.9943 +4088 4088 608630901.0765 +4089 4088 -7.867813110352e-06 +4090 4088 2.115964889526e-06 +4091 4088 89936890.28591 +4173 4088 21679861.11823 +4174 4088 -17343750.00569 +4175 4088 -38039431.35476 +4176 4088 86719444.4302 +4177 4088 1.415610313416e-06 +4178 4088 -121047307.7997 +4179 4088 21679861.11823 +4180 4088 17343750.0057 +4181 4088 -38039431.35476 +4194 4088 4335972.22365 +4195 4088 -34687499.9943 +4196 4088 -51773459.69442 +4197 4088 17343888.88605 +4198 4088 -4.410743713379e-06 +4199 4088 -144873003.6175 +4200 4088 4335972.22365 +4201 4088 34687499.9943 +4202 4088 -51773459.69442 +4089 4089 577153319.975 +4090 4089 -3.814697265625e-06 +4091 4089 -3.170967102051e-05 +4092 4089 82067495.00666 +4093 4089 12962777.77565 +4094 4089 -7.867813110352e-06 +4176 4089 -36072082.53399 +4177 4089 16203472.22755 +4178 4089 21679861.11823 +4179 4089 -113177912.5205 +4180 4089 -1.952052116394e-06 +4181 4089 86719444.4302 +4182 4089 -36072082.53399 +4183 4089 -16203472.22755 +4184 4089 21679861.11823 +4197 4089 -7329757.092094 +4198 4089 -3240694.445505 +4199 4089 -4335972.223642 +4200 4089 32901806.70425 +4201 4089 2.026557922363e-06 +4202 4089 -17343888.88602 +4203 4089 -7329757.09209 +4204 4089 3240694.445505 +4205 4089 -4335972.223642 +4090 4090 499373815.978 +4091 4090 1.025199890137e-05 +4092 4090 -12962777.77565 +4093 4090 -41078772.7658 +4094 4090 2.264976501465e-06 +4176 4090 16203472.22755 +4177 4090 -31210863.52938 +4178 4090 -17343750.00569 +4179 4090 -4.097819328308e-06 +4180 4090 -41882340.60423 +4181 4090 1.296401023865e-06 +4182 4090 -16203472.22755 +4183 4090 -31210863.52938 +4184 4090 17343750.0057 +4197 4090 3240694.445514 +4198 4090 -38116324.05038 +4199 4090 -34687499.9943 +4200 4090 1.430511474609e-06 +4201 4090 13456930.69541 +4202 4090 -4.410743713379e-06 +4203 4090 -3240694.445512 +4204 4090 -38116324.05037 +4205 4090 34687499.9943 +4091 4091 608630901.0765 +4092 4091 -7.867813110352e-06 +4093 4091 2.115964889526e-06 +4094 4091 89936890.28591 +4176 4091 21679861.11823 +4177 4091 -17343750.00569 +4178 4091 -38039431.35476 +4179 4091 86719444.4302 +4180 4091 1.415610313416e-06 +4181 4091 -121047307.7997 +4182 4091 21679861.11823 +4183 4091 17343750.0057 +4184 4091 -38039431.35476 +4197 4091 4335972.22365 +4198 4091 -34687499.9943 +4199 4091 -51773459.69442 +4200 4091 17343888.88605 +4201 4091 -4.410743713379e-06 +4202 4091 -144873003.6175 +4203 4091 4335972.22365 +4204 4091 34687499.9943 +4205 4091 -51773459.69442 +4092 4092 577153319.975 +4093 4092 -3.814697265625e-06 +4094 4092 -3.170967102051e-05 +4095 4092 82067495.00666 +4096 4092 12962777.77565 +4097 4092 -7.867813110352e-06 +4179 4092 -36072082.53399 +4180 4092 16203472.22755 +4181 4092 21679861.11823 +4182 4092 -113177912.5205 +4183 4092 -1.952052116394e-06 +4184 4092 86719444.4302 +4185 4092 -36072082.53399 +4186 4092 -16203472.22755 +4187 4092 21679861.11823 +4200 4092 -7329757.092094 +4201 4092 -3240694.445505 +4202 4092 -4335972.223642 +4203 4092 32901806.70425 +4204 4092 2.026557922363e-06 +4205 4092 -17343888.88602 +4206 4092 -7329757.09209 +4207 4092 3240694.445505 +4208 4092 -4335972.223642 +4093 4093 499373815.978 +4094 4093 1.025199890137e-05 +4095 4093 -12962777.77565 +4096 4093 -41078772.7658 +4097 4093 2.264976501465e-06 +4179 4093 16203472.22755 +4180 4093 -31210863.52938 +4181 4093 -17343750.00569 +4182 4093 -4.097819328308e-06 +4183 4093 -41882340.60423 +4184 4093 1.296401023865e-06 +4185 4093 -16203472.22755 +4186 4093 -31210863.52938 +4187 4093 17343750.0057 +4200 4093 3240694.445514 +4201 4093 -38116324.05038 +4202 4093 -34687499.9943 +4203 4093 1.430511474609e-06 +4204 4093 13456930.69541 +4205 4093 -4.410743713379e-06 +4206 4093 -3240694.445512 +4207 4093 -38116324.05037 +4208 4093 34687499.9943 +4094 4094 608630901.0765 +4095 4094 -7.867813110352e-06 +4096 4094 2.115964889526e-06 +4097 4094 89936890.28591 +4179 4094 21679861.11823 +4180 4094 -17343750.00569 +4181 4094 -38039431.35476 +4182 4094 86719444.4302 +4183 4094 1.415610313416e-06 +4184 4094 -121047307.7997 +4185 4094 21679861.11823 +4186 4094 17343750.0057 +4187 4094 -38039431.35476 +4200 4094 4335972.22365 +4201 4094 -34687499.9943 +4202 4094 -51773459.69442 +4203 4094 17343888.88605 +4204 4094 -4.410743713379e-06 +4205 4094 -144873003.6175 +4206 4094 4335972.22365 +4207 4094 34687499.9943 +4208 4094 -51773459.69442 +4095 4095 578486932.6103 +4096 4095 11986.19510007 +4097 4095 -2.288818359375e-05 +4098 4095 84494256.20949 +4099 4095 15482348.065 +4100 4095 1.072883605957e-06 +4182 4095 -36072082.53399 +4183 4095 16203472.22755 +4184 4095 21679861.11823 +4185 4095 -114724288.8331 +4186 4095 -635253.1045037 +4187 4095 87564583.31904 +4188 4095 -35736813.43152 +4189 4095 -16200678.02491 +4190 4095 21679166.67379 +4203 4095 -7329757.092094 +4204 4095 -3240694.445505 +4205 4095 -4335972.223642 +4206 4095 33236111.75387 +4207 4095 2649.269782305 +4208 4095 -17343611.10825 +4209 4095 -6450528.111152 +4210 4095 3870504.077597 +4211 4095 -5182361.112478 +4096 4096 498972289.4165 +4097 4096 1.955032348633e-05 +4098 4096 -10443763.04186 +4099 4096 -37606235.6153 +4100 4096 3.8743019104e-07 +4182 4096 16203472.22755 +4183 4096 -31210863.52938 +4184 4096 -17343750.00569 +4185 4096 -635253.1045074 +4186 4096 -42821513.04611 +4187 4096 677083.3332883 +4188 4096 -16200678.02491 +4189 4096 -31311329.22222 +4190 4096 17343750.00569 +4203 4096 3240694.445514 +4204 4096 -38116324.05038 +4205 4096 -34687499.9943 +4206 4096 2649.26978153 +4207 4096 13357668.57741 +4208 4096 -5.722045898438e-06 +4209 4096 -2610884.81342 +4210 4096 -36974996.97728 +4211 4096 34010416.66101 +4097 4097 608877037.9683 +4098 4097 -5.960464477539e-07 +4099 4097 4.768371582031e-07 +4100 4097 90773136.12633 +4182 4097 21679861.11823 +4183 4097 -17343750.00569 +4184 4097 -38039431.35476 +4185 4097 87564583.31887 +4186 4097 677083.333155 +4187 4097 -122108417.4801 +4188 4097 21679166.67379 +4189 4097 17343750.00569 +4190 4097 -37974851.43984 +4203 4097 4335972.22365 +4204 4097 -34687499.9943 +4205 4097 -51773459.69442 +4206 4097 17343611.10828 +4207 4097 -5.781650543213e-06 +4208 4097 -144806554.3753 +4209 4097 3489305.557203 +4210 4097 34010416.66114 +4211 4097 -50836907.65006 +4098 4098 576078114.5405 +4099 4098 -1636006.338361 +4100 4098 -9.536743164063e-07 +4101 4098 -84575033.27923 +4102 4098 -63933137.53736 +4103 4098 -5.543231964111e-06 +4104 4098 80892647.57501 +4105 4098 14709329.53279 +4106 4098 9.536743164063e-07 +4185 4098 -37742508.83701 +4186 4098 16181561.88645 +4187 4098 22525694.45184 +4188 4098 -113692433.8764 +4189 4098 -855995.9423672 +4190 4098 85676388.87482 +4206 4098 -6450528.111163 +4207 4098 -2610884.81342 +4208 4098 -3489305.557202 +4209 4098 37702548.37273 +4210 4098 -408992.8205404 +4211 4098 -17135277.77496 +4212 4098 -33940233.84008 +4213 4098 -15982941.89571 +4214 4098 20312500.00667 +4215 4098 -5632342.894137 +4216 4098 3677253.585591 +4217 4098 -5078333.334501 +4099 4099 489693679.98 +4100 4099 2.896785736084e-05 +4101 4099 -63933137.53736 +4102 4099 -68813095.55764 +4103 4099 -1.490116119385e-06 +4104 4099 -11216781.57406 +4105 4099 -42667576.13432 +4106 4099 -9.238719940186e-07 +4185 4099 16181561.88645 +4186 4099 -30707665.4868 +4187 4099 -16666666.67214 +4188 4099 -855995.942369 +4189 4099 -41658168.45665 +4190 4099 677083.3332871 +4206 4099 3870504.077598 +4207 4099 -36974996.9773 +4208 4099 -34010416.66115 +4209 4099 -408992.8205381 +4210 4099 16106902.49242 +4211 4099 -6.198883056641e-06 +4212 4099 -15982941.89571 +4213 4099 -29999833.84609 +4214 4099 16666666.67214 +4215 4099 -2804135.305426 +4216 4099 -36521736.91164 +4217 4099 33333333.32785 +4100 4100 591348648.5328 +4101 4100 -5.513429641724e-06 +4102 4100 -1.490116119385e-06 +4103 4100 -5640051.194663 +4104 4100 -1.072883605957e-06 +4105 4100 -9.238719940186e-07 +4106 4100 83549951.75354 +4185 4100 22525694.45184 +4186 4100 -16666666.67214 +4187 4100 -38357223.7135 +4188 4100 85676388.87482 +4189 4100 677083.3331537 +4190 4100 -117555867.1805 +4206 4100 5182361.112479 +4207 4100 -34010416.66102 +4208 4100 -50836907.65008 +4209 4100 17135277.77496 +4210 4100 -6.258487701416e-06 +4211 4100 -135669723.6375 +4212 4100 20312500.00667 +4213 4100 16666666.67214 +4214 4100 -35535125.4841 +4215 4100 3385277.779223 +4216 4100 33333333.32785 +4217 4100 -48059816.83043 +4101 4101 278277688.0438 +4102 4101 63032990.82912 +4103 4101 8.106231689453e-06 +4104 4101 -117017201.3105 +4105 4101 -13845195.78321 +4106 4101 -2.741813659668e-06 +4188 4101 -6375113.374578 +4189 4101 3686256.632336 +4190 4101 4909027.779056 +4209 4101 -33940233.84009 +4210 4101 -15982941.89571 +4211 4101 -20312500.00667 +4212 4101 18902645.55565 +4213 4101 15757910.04072 +4214 4101 8124999.998667 +4215 4101 -54847530.63036 +4216 4101 -3461224.777347 +4217 4101 -41471527.77105 +4102 4102 243072801.0765 +4103 4102 1.251697540283e-05 +4104 4102 12080915.32365 +4105 4102 25208100.5253 +4106 4102 6.85453414917e-06 +4188 4102 -2795132.258682 +4189 4102 -37070043.77933 +4190 4102 -33333333.32786 +4209 4102 -15982941.89571 +4210 4102 -29999833.8461 +4211 4102 -16666666.67214 +4212 4102 15757910.04072 +4213 4102 10101612.40576 +4214 4102 6666666.665572 +4215 4102 3020164.113671 +4216 4102 -19291967.06971 +4217 4102 3333333.334427 +4103 4103 285481231.0942 +4104 4103 1.788139343262e-07 +4105 4103 6.85453414917e-06 +4106 4103 47347303.99915 +4188 4103 -3215972.223779 +4189 4103 -33333333.32786 +4190 4103 -47673130.40168 +4209 4103 -20312500.00667 +4210 4103 -16666666.67214 +4211 4103 -35535125.48411 +4212 4103 -8124999.998663 +4213 4103 -6666666.665571 +4214 4103 -63738650.14916 +4215 4103 -41471527.77088 +4216 4103 -3333333.334429 +4217 4103 -56413713.40339 +4104 4104 285841125.8965 +4105 4104 -66561551.7465 +4106 4104 -6.437301635742e-06 +4188 4104 -36573838.1928 +4189 4104 16424002.55938 +4190 4104 21159027.78473 +4209 4104 -5632342.894149 +4210 4104 -2804135.305427 +4211 4104 -3385277.779223 +4212 4104 -54847530.63036 +4213 4104 3020164.113676 +4214 4104 41471527.77088 +4215 4104 19748607.35902 +4216 4104 -16640031.36763 +4217 4104 -8463611.109722 +4105 4105 244829958.0819 +4106 4105 1.54972076416e-05 +4188 4105 16424002.55938 +4189 4105 -30987435.47837 +4190 4105 -16666666.67214 +4209 4105 3677253.585592 +4210 4105 -36521736.91166 +4211 4105 -33333333.32786 +4212 4105 -3461224.777343 +4213 4105 -19291967.06971 +4214 4105 3333333.334427 +4215 4105 -16640031.36763 +4216 4105 9496035.101444 +4217 4105 6666666.665568 +4106 4106 290978341.916 +4188 4106 21159027.78473 +4189 4106 -16666666.67214 +4190 4106 -36522727.11638 +4209 4106 5078333.334501 +4210 4106 -33333333.32786 +4211 4106 -48059816.83046 +4212 4106 41471527.77105 +4213 4106 -3333333.334429 +4214 4106 -56413713.40339 +4215 4106 8463611.10972 +4216 4106 -6666666.665574 +4217 4106 -65150687.60521 +4107 4107 824455161.8017 +4108 4107 81018055.54225 +4109 4107 -8.583068847656e-06 +4110 4107 -460053204.795 +4111 4107 -81018054.89409 +4112 4107 -1.305341720581e-05 +4113 4107 23205392.66699 +4114 4107 64814443.78565 +4115 4107 1.54972076416e-06 +4218 4107 139046393.5639 +4219 4107 24305555.56354 +4220 4107 17343888.84952 +4221 4107 -175918799.4896 +4222 4107 -24305555.36909 +4223 4107 -86719444.24762 +4224 4107 -9282077.505002 +4225 4107 19444444.25638 +4226 4107 -17343888.52033 +4108 4108 702923645.8189 +4109 4108 7.830374228711e-07 +4110 4108 -81018054.57002 +4111 4108 -79265988.49504 +4112 4108 -7.152557373047e-07 +4113 4108 97221665.67847 +4114 4108 23205392.66698 +4115 4108 3.457069396973e-06 +4218 4108 24305555.56354 +4219 4108 102586730.4102 +4220 4108 13874999.85143 +4221 4108 -24305555.27187 +4222 4108 -61681981.76159 +4223 4108 -17343749.90781 +4224 4108 29166666.38457 +4225 4108 -9282077.504995 +4226 4108 20812499.90894 +4109 4109 744714928.2643 +4110 4109 -1.293420791626e-05 +4111 4109 3.576278686523e-07 +4112 4109 -32232076.56353 +4113 4109 1.192092895508e-06 +4114 4109 3.218650817871e-06 +4115 4109 61881047.11197 +4218 4109 -17343888.84952 +4219 4109 -13874999.85144 +4220 4109 -65361760.6378 +4221 4109 -86719444.24762 +4222 4109 -17343749.94044 +4223 4109 -110741809.7386 +4224 4109 -26015832.7805 +4225 4109 13874999.9393 +4226 4109 -24752206.67999 +4110 4110 1437608510.215 +4111 4110 81018053.92186 +4112 4110 -4.029273986816e-05 +4113 4110 32543005.93566 +4114 4110 -81018054.8941 +4115 4110 -4.887580871582e-06 +4116 4110 -318367567.7659 +4117 4110 -2.443790435791e-06 +4118 4110 -1.460313796997e-05 +4119 4110 -118480247.2419 +4120 4110 81018055.54225 +4121 4110 -3.516674041748e-06 +4218 4110 -175918799.4897 +4219 4110 -24305555.27186 +4220 4110 86719444.24762 +4221 4110 268847663.9159 +4222 4110 24305555.07742 +4223 4110 0.03653132915497 +4224 4110 -28139091.37671 +4225 4110 -24305555.36909 +4226 4110 21679860.74398 +4227 4110 -138827443.8751 +4228 4110 -5.066394805908e-07 +4229 4110 -86719444.43019 +4230 4110 -46373434.23611 +4231 4110 24305555.56353 +4232 4110 -21679861.11823 +4111 4111 1218851780.873 +4112 4111 -1.430511474609e-06 +4113 4111 -81018054.57003 +4114 4111 -251018997.7335 +4115 4111 -4.26173210144e-06 +4116 4111 -1.072883605957e-06 +4117 4111 38113347.20754 +4118 4111 -1.192092895508e-06 +4119 4111 81018055.54225 +4120 4111 -94173943.88989 +4121 4111 -2.682209014893e-07 +4218 4111 -24305555.36908 +4219 4111 -61681981.7616 +4220 4111 17343749.94043 +4221 4111 24305555.07742 +4222 4111 203220270.0671 +4223 4111 0.02920919656754 +4224 4111 -24305555.27186 +4225 4111 -113208178.6284 +4226 4111 69374999.6084 +4227 4111 -8.344650268555e-07 +4228 4111 -31882558.21681 +4229 4111 -3.278255462646e-07 +4230 4111 24305555.56353 +4231 4111 -39081501.55875 +4232 4111 17343750.00569 +4112 4112 1216724781.271 +4113 4112 -4.52995300293e-06 +4114 4112 -3.457069396973e-06 +4115 4112 55270613.64501 +4116 4112 -1.388788223267e-05 +4117 4112 -1.072883605957e-06 +4118 4112 54829860.44019 +4119 4112 -3.36766242981e-06 +4120 4112 -3.576278686523e-07 +4121 4112 -25180890.14437 +4218 4112 86719444.24762 +4219 4112 17343749.9078 +4220 4112 -110741809.7386 +4221 4112 -0.03649973869324 +4222 4112 -0.02921465039253 +4223 4112 -68146756.53808 +4224 4112 21679860.55685 +4225 4112 69374999.49133 +4226 4112 -84490851.68298 +4227 4112 -86719444.43019 +4228 4112 -2.682209014893e-07 +4229 4112 -99061955.12461 +4230 4112 -21679861.11823 +4231 4112 17343750.00569 +4232 4112 -36432062.04358 +4113 4113 824455161.8017 +4114 4113 81018055.54225 +4115 4113 -8.583068847656e-06 +4116 4113 -118480247.2419 +4117 4113 -81018055.54225 +4118 4113 -3.695487976074e-06 +4119 4113 -460053204.795 +4120 4113 -81018054.89409 +4121 4113 -1.305341720581e-05 +4122 4113 23205392.66699 +4123 4113 64814443.78565 +4124 4113 1.54972076416e-06 +4218 4113 -9282077.50499 +4219 4113 29166666.38457 +4220 4113 26015832.78049 +4221 4113 -28139091.37673 +4222 4113 -24305555.27187 +4223 4113 -21679860.55685 +4224 4113 139046393.5639 +4225 4113 24305555.56354 +4226 4113 17343888.84952 +4227 4113 -46373434.23611 +4228 4113 -24305555.56353 +4229 4113 -21679861.11823 +4230 4113 -175918799.4896 +4231 4113 -24305555.36909 +4232 4113 -86719444.24762 +4233 4113 -9282077.505002 +4234 4113 19444444.25638 +4235 4113 -17343888.52033 +4114 4114 702923645.8189 +4115 4114 7.830374228711e-07 +4116 4114 -81018055.54225 +4117 4114 -94173943.88989 +4118 4114 -1.9371509552e-07 +4119 4114 -81018054.57002 +4120 4114 -79265988.49504 +4121 4114 -7.152557373047e-07 +4122 4114 97221665.67847 +4123 4114 23205392.66698 +4124 4114 3.457069396973e-06 +4218 4114 19444444.25638 +4219 4114 -9282077.505 +4220 4114 -13874999.9393 +4221 4114 -24305555.36909 +4222 4114 -113208178.6284 +4223 4114 -69374999.49133 +4224 4114 24305555.56354 +4225 4114 102586730.4102 +4226 4114 13874999.85143 +4227 4114 -24305555.56353 +4228 4114 -39081501.55875 +4229 4114 -17343750.0057 +4230 4114 -24305555.27187 +4231 4114 -61681981.76159 +4232 4114 -17343749.90781 +4233 4114 29166666.38457 +4234 4114 -9282077.504995 +4235 4114 20812499.90894 +4115 4115 744714928.2643 +4116 4115 -3.576278686523e-06 +4117 4115 -1.341104507446e-07 +4118 4115 -25180890.14438 +4119 4115 -1.293420791626e-05 +4120 4115 3.576278686523e-07 +4121 4115 -32232076.56353 +4122 4115 1.192092895508e-06 +4123 4115 3.218650817871e-06 +4124 4115 61881047.11197 +4218 4115 17343888.52033 +4219 4115 -20812499.90895 +4220 4115 -24752206.67999 +4221 4115 -21679860.74398 +4222 4115 -69374999.6084 +4223 4115 -84490851.68299 +4224 4115 -17343888.84952 +4225 4115 -13874999.85144 +4226 4115 -65361760.6378 +4227 4115 -21679861.11823 +4228 4115 -17343750.0057 +4229 4115 -36432062.04358 +4230 4115 -86719444.24762 +4231 4115 -17343749.94044 +4232 4115 -110741809.7386 +4233 4115 -26015832.7805 +4234 4115 13874999.9393 +4235 4115 -24752206.67999 +4116 4116 1319128267.022 +4117 4116 9.775161743164e-06 +4118 4116 -5.745887756348e-05 +4119 4116 174228645.9499 +4120 4116 -4.291534423828e-06 +4121 4116 -1.45435333252e-05 +4125 4116 -318367567.7659 +4126 4116 -2.443790435791e-06 +4127 4116 -1.460313796997e-05 +4128 4116 -118480247.2419 +4129 4116 81018055.54225 +4130 4116 -3.516674041748e-06 +4221 4116 -138827443.8752 +4222 4116 2.682209014893e-07 +4223 4116 86719444.4302 +4224 4116 -46373434.23614 +4225 4116 -24305555.56354 +4226 4116 21679861.11823 +4227 4116 222474230.8735 +4228 4116 3.933906555176e-06 +4229 4116 2.622604370117e-05 +4230 4116 8952264.76783 +4231 4116 -1.302361488342e-05 +4232 4116 6.914138793945e-06 +4236 4116 -138827443.8751 +4237 4116 -5.066394805908e-07 +4238 4116 -86719444.43019 +4239 4116 -46373434.23611 +4240 4116 24305555.56353 +4241 4116 -21679861.11823 +4117 4117 1124677840.302 +4118 4117 -3.814697265625e-06 +4119 4117 -4.947185516357e-06 +4120 4117 -133639662.3675 +4121 4117 -8.046627044678e-07 +4125 4117 -1.072883605957e-06 +4126 4117 38113347.20754 +4127 4117 -1.192092895508e-06 +4128 4117 81018055.54225 +4129 4117 -94173943.88989 +4130 4117 -2.682209014893e-07 +4221 4117 -2.294778823853e-06 +4222 4117 -31882558.21685 +4223 4117 2.682209014893e-07 +4224 4117 -24305555.56354 +4225 4117 -39081501.55876 +4226 4117 17343750.0057 +4227 4117 4.410743713379e-06 +4228 4117 164138769.4832 +4229 4117 -1.192092895508e-07 +4230 4117 -1.156330108643e-05 +4231 4117 -83408755.55014 +4232 4117 69374999.9886 +4236 4117 -8.344650268555e-07 +4237 4117 -31882558.21681 +4238 4117 -3.278255462646e-07 +4239 4117 24305555.56353 +4240 4117 -39081501.55875 +4241 4117 17343750.00569 +4118 4118 1191543893.2 +4119 4118 -1.45435333252e-05 +4120 4118 -1.192092895508e-06 +4121 4118 142332552.4786 +4125 4118 -1.388788223267e-05 +4126 4118 -1.072883605957e-06 +4127 4118 54829860.44019 +4128 4118 -3.36766242981e-06 +4129 4118 -3.576278686523e-07 +4130 4118 -25180890.14437 +4221 4118 86719444.4302 +4222 4118 3.427267074585e-07 +4223 4118 -99061955.12464 +4224 4118 21679861.11823 +4225 4118 17343750.0057 +4226 4118 -36432062.04359 +4227 4118 2.598762512207e-05 +4228 4118 5.960464477539e-08 +4229 4118 -104578818.0156 +4230 4118 6.973743438721e-06 +4231 4118 69374999.9886 +4232 4118 -72810997.49471 +4236 4118 -86719444.43019 +4237 4118 -2.682209014893e-07 +4238 4118 -99061955.12461 +4239 4118 -21679861.11823 +4240 4118 17343750.00569 +4241 4118 -36432062.04358 +4119 4119 1437608510.215 +4120 4119 81018053.92186 +4121 4119 -4.029273986816e-05 +4122 4119 32543005.93566 +4123 4119 -81018054.8941 +4124 4119 -4.887580871582e-06 +4125 4119 -118480247.2419 +4126 4119 -81018055.54225 +4127 4119 -3.695487976074e-06 +4128 4119 -318367567.7659 +4129 4119 -2.443790435791e-06 +4130 4119 -1.460313796997e-05 +4131 4119 -118480247.2419 +4132 4119 81018055.54225 +4133 4119 -3.516674041748e-06 +4221 4119 -46373434.23613 +4222 4119 24305555.56354 +4223 4119 21679861.11823 +4224 4119 -175918799.4897 +4225 4119 -24305555.27186 +4226 4119 86719444.24762 +4227 4119 8952264.76783 +4228 4119 9.298324584961e-06 +4229 4119 6.228685379028e-06 +4230 4119 268847663.9159 +4231 4119 24305555.07742 +4232 4119 0.03653132915497 +4233 4119 -28139091.37671 +4234 4119 -24305555.36909 +4235 4119 21679860.74398 +4236 4119 -46373434.23611 +4237 4119 -24305555.56353 +4238 4119 -21679861.11823 +4239 4119 -138827443.8751 +4240 4119 -5.066394805908e-07 +4241 4119 -86719444.43019 +4242 4119 -46373434.23611 +4243 4119 24305555.56353 +4244 4119 -21679861.11823 +4120 4120 1218851780.873 +4121 4120 -1.430511474609e-06 +4122 4120 -81018054.57003 +4123 4120 -251018997.7335 +4124 4120 -4.26173210144e-06 +4125 4120 -81018055.54225 +4126 4120 -94173943.88989 +4127 4120 -1.9371509552e-07 +4128 4120 -1.072883605957e-06 +4129 4120 38113347.20754 +4130 4120 -1.192092895508e-06 +4131 4120 81018055.54225 +4132 4120 -94173943.88989 +4133 4120 -2.682209014893e-07 +4221 4120 24305555.56354 +4222 4120 -39081501.55876 +4223 4120 -17343750.00569 +4224 4120 -24305555.36908 +4225 4120 -61681981.7616 +4226 4120 17343749.94043 +4227 4120 1.069903373718e-05 +4228 4120 -83408755.55014 +4229 4120 -69374999.9886 +4230 4120 24305555.07742 +4231 4120 203220270.0671 +4232 4120 0.02920919656754 +4233 4120 -24305555.27186 +4234 4120 -113208178.6284 +4235 4120 69374999.6084 +4236 4120 -24305555.56353 +4237 4120 -39081501.55875 +4238 4120 -17343750.0057 +4239 4120 -8.344650268555e-07 +4240 4120 -31882558.21681 +4241 4120 -3.278255462646e-07 +4242 4120 24305555.56353 +4243 4120 -39081501.55875 +4244 4120 17343750.00569 +4121 4121 1216724781.271 +4122 4121 -4.52995300293e-06 +4123 4121 -3.457069396973e-06 +4124 4121 55270613.64501 +4125 4121 -3.576278686523e-06 +4126 4121 -1.341104507446e-07 +4127 4121 -25180890.14438 +4128 4121 -1.388788223267e-05 +4129 4121 -1.072883605957e-06 +4130 4121 54829860.44019 +4131 4121 -3.36766242981e-06 +4132 4121 -3.576278686523e-07 +4133 4121 -25180890.14437 +4221 4121 21679861.11823 +4222 4121 -17343750.0057 +4223 4121 -36432062.04359 +4224 4121 86719444.24762 +4225 4121 17343749.9078 +4226 4121 -110741809.7386 +4227 4121 6.169080734253e-06 +4228 4121 -69374999.9886 +4229 4121 -72810997.49471 +4230 4121 -0.03649973869324 +4231 4121 -0.02921465039253 +4232 4121 -68146756.53808 +4233 4121 21679860.55685 +4234 4121 69374999.49133 +4235 4121 -84490851.68298 +4236 4121 -21679861.11823 +4237 4121 -17343750.0057 +4238 4121 -36432062.04358 +4239 4121 -86719444.43019 +4240 4121 -2.682209014893e-07 +4241 4121 -99061955.12461 +4242 4121 -21679861.11823 +4243 4121 17343750.00569 +4244 4121 -36432062.04358 +4122 4122 824455161.8017 +4123 4122 81018055.54225 +4124 4122 -8.583068847656e-06 +4128 4122 -118480247.2419 +4129 4122 -81018055.54225 +4130 4122 -3.695487976074e-06 +4131 4122 -460053204.795 +4132 4122 -81018054.89409 +4133 4122 -1.305341720581e-05 +4134 4122 23205392.66699 +4135 4122 64814443.78565 +4136 4122 1.54972076416e-06 +4224 4122 -9282077.50499 +4225 4122 29166666.38457 +4226 4122 26015832.78049 +4230 4122 -28139091.37673 +4231 4122 -24305555.27187 +4232 4122 -21679860.55685 +4233 4122 139046393.5639 +4234 4122 24305555.56354 +4235 4122 17343888.84952 +4239 4122 -46373434.23611 +4240 4122 -24305555.56353 +4241 4122 -21679861.11823 +4242 4122 -175918799.4896 +4243 4122 -24305555.36909 +4244 4122 -86719444.24762 +4245 4122 -9282077.505002 +4246 4122 19444444.25638 +4247 4122 -17343888.52033 +4123 4123 702923645.8189 +4124 4123 7.830374228711e-07 +4128 4123 -81018055.54225 +4129 4123 -94173943.88989 +4130 4123 -1.9371509552e-07 +4131 4123 -81018054.57002 +4132 4123 -79265988.49504 +4133 4123 -7.152557373047e-07 +4134 4123 97221665.67847 +4135 4123 23205392.66698 +4136 4123 3.457069396973e-06 +4224 4123 19444444.25638 +4225 4123 -9282077.505 +4226 4123 -13874999.9393 +4230 4123 -24305555.36909 +4231 4123 -113208178.6284 +4232 4123 -69374999.49133 +4233 4123 24305555.56354 +4234 4123 102586730.4102 +4235 4123 13874999.85143 +4239 4123 -24305555.56353 +4240 4123 -39081501.55875 +4241 4123 -17343750.0057 +4242 4123 -24305555.27187 +4243 4123 -61681981.76159 +4244 4123 -17343749.90781 +4245 4123 29166666.38457 +4246 4123 -9282077.504995 +4247 4123 20812499.90894 +4124 4124 744714928.2643 +4128 4124 -3.576278686523e-06 +4129 4124 -1.341104507446e-07 +4130 4124 -25180890.14438 +4131 4124 -1.293420791626e-05 +4132 4124 3.576278686523e-07 +4133 4124 -32232076.56353 +4134 4124 1.192092895508e-06 +4135 4124 3.218650817871e-06 +4136 4124 61881047.11197 +4224 4124 17343888.52033 +4225 4124 -20812499.90895 +4226 4124 -24752206.67999 +4230 4124 -21679860.74398 +4231 4124 -69374999.6084 +4232 4124 -84490851.68299 +4233 4124 -17343888.84952 +4234 4124 -13874999.85144 +4235 4124 -65361760.6378 +4239 4124 -21679861.11823 +4240 4124 -17343750.0057 +4241 4124 -36432062.04358 +4242 4124 -86719444.24762 +4243 4124 -17343749.94044 +4244 4124 -110741809.7386 +4245 4124 -26015832.7805 +4246 4124 13874999.9393 +4247 4124 -24752206.67999 +4125 4125 1319128267.022 +4126 4125 9.775161743164e-06 +4127 4125 -5.745887756348e-05 +4128 4125 174228645.9499 +4129 4125 -4.291534423828e-06 +4130 4125 -1.45435333252e-05 +4137 4125 -318367567.7659 +4138 4125 -2.443790435791e-06 +4139 4125 -1.460313796997e-05 +4140 4125 -118480247.2419 +4141 4125 81018055.54225 +4142 4125 -3.516674041748e-06 +4227 4125 -138827443.8752 +4228 4125 2.682209014893e-07 +4229 4125 86719444.4302 +4230 4125 -46373434.23614 +4231 4125 -24305555.56354 +4232 4125 21679861.11823 +4236 4125 222474230.8735 +4237 4125 3.933906555176e-06 +4238 4125 2.622604370117e-05 +4239 4125 8952264.76783 +4240 4125 -1.302361488342e-05 +4241 4125 6.914138793945e-06 +4248 4125 -138827443.8751 +4249 4125 -5.066394805908e-07 +4250 4125 -86719444.43019 +4251 4125 -46373434.23611 +4252 4125 24305555.56353 +4253 4125 -21679861.11823 +4126 4126 1124677840.302 +4127 4126 -3.814697265625e-06 +4128 4126 -4.947185516357e-06 +4129 4126 -133639662.3675 +4130 4126 -8.046627044678e-07 +4137 4126 -1.072883605957e-06 +4138 4126 38113347.20754 +4139 4126 -1.192092895508e-06 +4140 4126 81018055.54225 +4141 4126 -94173943.88989 +4142 4126 -2.682209014893e-07 +4227 4126 -2.294778823853e-06 +4228 4126 -31882558.21685 +4229 4126 2.682209014893e-07 +4230 4126 -24305555.56354 +4231 4126 -39081501.55876 +4232 4126 17343750.0057 +4236 4126 4.410743713379e-06 +4237 4126 164138769.4832 +4238 4126 -1.192092895508e-07 +4239 4126 -1.156330108643e-05 +4240 4126 -83408755.55014 +4241 4126 69374999.9886 +4248 4126 -8.344650268555e-07 +4249 4126 -31882558.21681 +4250 4126 -3.278255462646e-07 +4251 4126 24305555.56353 +4252 4126 -39081501.55875 +4253 4126 17343750.00569 +4127 4127 1191543893.2 +4128 4127 -1.45435333252e-05 +4129 4127 -1.192092895508e-06 +4130 4127 142332552.4786 +4137 4127 -1.388788223267e-05 +4138 4127 -1.072883605957e-06 +4139 4127 54829860.44019 +4140 4127 -3.36766242981e-06 +4141 4127 -3.576278686523e-07 +4142 4127 -25180890.14437 +4227 4127 86719444.4302 +4228 4127 3.427267074585e-07 +4229 4127 -99061955.12464 +4230 4127 21679861.11823 +4231 4127 17343750.0057 +4232 4127 -36432062.04359 +4236 4127 2.598762512207e-05 +4237 4127 5.960464477539e-08 +4238 4127 -104578818.0156 +4239 4127 6.973743438721e-06 +4240 4127 69374999.9886 +4241 4127 -72810997.49471 +4248 4127 -86719444.43019 +4249 4127 -2.682209014893e-07 +4250 4127 -99061955.12461 +4251 4127 -21679861.11823 +4252 4127 17343750.00569 +4253 4127 -36432062.04358 +4128 4128 1319128267.022 +4129 4128 9.775161743164e-06 +4130 4128 -5.745887756348e-05 +4131 4128 174228645.9499 +4132 4128 -4.291534423828e-06 +4133 4128 -1.45435333252e-05 +4137 4128 -118480247.2419 +4138 4128 -81018055.54225 +4139 4128 -3.695487976074e-06 +4140 4128 -318367567.7659 +4141 4128 -2.443790435791e-06 +4142 4128 -1.460313796997e-05 +4143 4128 -118480247.2419 +4144 4128 81018055.54225 +4145 4128 -3.516674041748e-06 +4227 4128 -46373434.23613 +4228 4128 24305555.56354 +4229 4128 21679861.11823 +4230 4128 -138827443.8752 +4231 4128 2.682209014893e-07 +4232 4128 86719444.4302 +4233 4128 -46373434.23614 +4234 4128 -24305555.56354 +4235 4128 21679861.11823 +4236 4128 8952264.76783 +4237 4128 9.298324584961e-06 +4238 4128 6.228685379028e-06 +4239 4128 222474230.8735 +4240 4128 3.933906555176e-06 +4241 4128 2.622604370117e-05 +4242 4128 8952264.76783 +4243 4128 -1.302361488342e-05 +4244 4128 6.914138793945e-06 +4248 4128 -46373434.23611 +4249 4128 -24305555.56353 +4250 4128 -21679861.11823 +4251 4128 -138827443.8751 +4252 4128 -5.066394805908e-07 +4253 4128 -86719444.43019 +4254 4128 -46373434.23611 +4255 4128 24305555.56353 +4256 4128 -21679861.11823 +4129 4129 1124677840.302 +4130 4129 -3.814697265625e-06 +4131 4129 -4.947185516357e-06 +4132 4129 -133639662.3675 +4133 4129 -8.046627044678e-07 +4137 4129 -81018055.54225 +4138 4129 -94173943.88989 +4139 4129 -1.9371509552e-07 +4140 4129 -1.072883605957e-06 +4141 4129 38113347.20754 +4142 4129 -1.192092895508e-06 +4143 4129 81018055.54225 +4144 4129 -94173943.88989 +4145 4129 -2.682209014893e-07 +4227 4129 24305555.56354 +4228 4129 -39081501.55876 +4229 4129 -17343750.00569 +4230 4129 -2.294778823853e-06 +4231 4129 -31882558.21685 +4232 4129 2.682209014893e-07 +4233 4129 -24305555.56354 +4234 4129 -39081501.55876 +4235 4129 17343750.0057 +4236 4129 1.069903373718e-05 +4237 4129 -83408755.55014 +4238 4129 -69374999.9886 +4239 4129 4.410743713379e-06 +4240 4129 164138769.4832 +4241 4129 -1.192092895508e-07 +4242 4129 -1.156330108643e-05 +4243 4129 -83408755.55014 +4244 4129 69374999.9886 +4248 4129 -24305555.56353 +4249 4129 -39081501.55875 +4250 4129 -17343750.0057 +4251 4129 -8.344650268555e-07 +4252 4129 -31882558.21681 +4253 4129 -3.278255462646e-07 +4254 4129 24305555.56353 +4255 4129 -39081501.55875 +4256 4129 17343750.00569 +4130 4130 1191543893.2 +4131 4130 -1.45435333252e-05 +4132 4130 -1.192092895508e-06 +4133 4130 142332552.4786 +4137 4130 -3.576278686523e-06 +4138 4130 -1.341104507446e-07 +4139 4130 -25180890.14438 +4140 4130 -1.388788223267e-05 +4141 4130 -1.072883605957e-06 +4142 4130 54829860.44019 +4143 4130 -3.36766242981e-06 +4144 4130 -3.576278686523e-07 +4145 4130 -25180890.14437 +4227 4130 21679861.11823 +4228 4130 -17343750.0057 +4229 4130 -36432062.04359 +4230 4130 86719444.4302 +4231 4130 3.427267074585e-07 +4232 4130 -99061955.12464 +4233 4130 21679861.11823 +4234 4130 17343750.0057 +4235 4130 -36432062.04359 +4236 4130 6.169080734253e-06 +4237 4130 -69374999.9886 +4238 4130 -72810997.49471 +4239 4130 2.598762512207e-05 +4240 4130 5.960464477539e-08 +4241 4130 -104578818.0156 +4242 4130 6.973743438721e-06 +4243 4130 69374999.9886 +4244 4130 -72810997.49471 +4248 4130 -21679861.11823 +4249 4130 -17343750.0057 +4250 4130 -36432062.04358 +4251 4130 -86719444.43019 +4252 4130 -2.682209014893e-07 +4253 4130 -99061955.12461 +4254 4130 -21679861.11823 +4255 4130 17343750.00569 +4256 4130 -36432062.04358 +4131 4131 1437608510.215 +4132 4131 81018053.92186 +4133 4131 -4.029273986816e-05 +4134 4131 32543005.93566 +4135 4131 -81018054.8941 +4136 4131 -4.887580871582e-06 +4140 4131 -118480247.2419 +4141 4131 -81018055.54225 +4142 4131 -3.695487976074e-06 +4143 4131 -318367567.7659 +4144 4131 -2.443790435791e-06 +4145 4131 -1.460313796997e-05 +4146 4131 -118480247.2419 +4147 4131 81018055.54225 +4148 4131 -3.516674041748e-06 +4230 4131 -46373434.23613 +4231 4131 24305555.56354 +4232 4131 21679861.11823 +4233 4131 -175918799.4897 +4234 4131 -24305555.27186 +4235 4131 86719444.24762 +4239 4131 8952264.76783 +4240 4131 9.298324584961e-06 +4241 4131 6.228685379028e-06 +4242 4131 268847663.9159 +4243 4131 24305555.07742 +4244 4131 0.03653132915497 +4245 4131 -28139091.37671 +4246 4131 -24305555.36909 +4247 4131 21679860.74398 +4251 4131 -46373434.23611 +4252 4131 -24305555.56353 +4253 4131 -21679861.11823 +4254 4131 -138827443.8751 +4255 4131 -5.066394805908e-07 +4256 4131 -86719444.43019 +4257 4131 -46373434.23611 +4258 4131 24305555.56353 +4259 4131 -21679861.11823 +4132 4132 1218851780.873 +4133 4132 -1.430511474609e-06 +4134 4132 -81018054.57003 +4135 4132 -251018997.7335 +4136 4132 -4.26173210144e-06 +4140 4132 -81018055.54225 +4141 4132 -94173943.88989 +4142 4132 -1.9371509552e-07 +4143 4132 -1.072883605957e-06 +4144 4132 38113347.20754 +4145 4132 -1.192092895508e-06 +4146 4132 81018055.54225 +4147 4132 -94173943.88989 +4148 4132 -2.682209014893e-07 +4230 4132 24305555.56354 +4231 4132 -39081501.55876 +4232 4132 -17343750.00569 +4233 4132 -24305555.36908 +4234 4132 -61681981.7616 +4235 4132 17343749.94043 +4239 4132 1.069903373718e-05 +4240 4132 -83408755.55014 +4241 4132 -69374999.9886 +4242 4132 24305555.07742 +4243 4132 203220270.0671 +4244 4132 0.02920919656754 +4245 4132 -24305555.27186 +4246 4132 -113208178.6284 +4247 4132 69374999.6084 +4251 4132 -24305555.56353 +4252 4132 -39081501.55875 +4253 4132 -17343750.0057 +4254 4132 -8.344650268555e-07 +4255 4132 -31882558.21681 +4256 4132 -3.278255462646e-07 +4257 4132 24305555.56353 +4258 4132 -39081501.55875 +4259 4132 17343750.00569 +4133 4133 1216724781.271 +4134 4133 -4.52995300293e-06 +4135 4133 -3.457069396973e-06 +4136 4133 55270613.64501 +4140 4133 -3.576278686523e-06 +4141 4133 -1.341104507446e-07 +4142 4133 -25180890.14438 +4143 4133 -1.388788223267e-05 +4144 4133 -1.072883605957e-06 +4145 4133 54829860.44019 +4146 4133 -3.36766242981e-06 +4147 4133 -3.576278686523e-07 +4148 4133 -25180890.14437 +4230 4133 21679861.11823 +4231 4133 -17343750.0057 +4232 4133 -36432062.04359 +4233 4133 86719444.24762 +4234 4133 17343749.9078 +4235 4133 -110741809.7386 +4239 4133 6.169080734253e-06 +4240 4133 -69374999.9886 +4241 4133 -72810997.49471 +4242 4133 -0.03649973869324 +4243 4133 -0.02921465039253 +4244 4133 -68146756.53808 +4245 4133 21679860.55685 +4246 4133 69374999.49133 +4247 4133 -84490851.68298 +4251 4133 -21679861.11823 +4252 4133 -17343750.0057 +4253 4133 -36432062.04358 +4254 4133 -86719444.43019 +4255 4133 -2.682209014893e-07 +4256 4133 -99061955.12461 +4257 4133 -21679861.11823 +4258 4133 17343750.00569 +4259 4133 -36432062.04358 +4134 4134 824455161.8017 +4135 4134 81018055.54225 +4136 4134 -8.583068847656e-06 +4143 4134 -118480247.2419 +4144 4134 -81018055.54225 +4145 4134 -3.695487976074e-06 +4146 4134 -460053204.795 +4147 4134 -81018054.89409 +4148 4134 -1.305341720581e-05 +4149 4134 23205392.66699 +4150 4134 64814443.78565 +4151 4134 1.54972076416e-06 +4233 4134 -9282077.50499 +4234 4134 29166666.38457 +4235 4134 26015832.78049 +4242 4134 -28139091.37673 +4243 4134 -24305555.27187 +4244 4134 -21679860.55685 +4245 4134 139046393.5639 +4246 4134 24305555.56354 +4247 4134 17343888.84952 +4254 4134 -46373434.23611 +4255 4134 -24305555.56353 +4256 4134 -21679861.11823 +4257 4134 -175918799.4896 +4258 4134 -24305555.36909 +4259 4134 -86719444.24762 +4260 4134 -9282077.505002 +4261 4134 19444444.25638 +4262 4134 -17343888.52033 +4135 4135 702923645.8189 +4136 4135 7.830374228711e-07 +4143 4135 -81018055.54225 +4144 4135 -94173943.88989 +4145 4135 -1.9371509552e-07 +4146 4135 -81018054.57002 +4147 4135 -79265988.49504 +4148 4135 -7.152557373047e-07 +4149 4135 97221665.67847 +4150 4135 23205392.66698 +4151 4135 3.457069396973e-06 +4233 4135 19444444.25638 +4234 4135 -9282077.505 +4235 4135 -13874999.9393 +4242 4135 -24305555.36909 +4243 4135 -113208178.6284 +4244 4135 -69374999.49133 +4245 4135 24305555.56354 +4246 4135 102586730.4102 +4247 4135 13874999.85143 +4254 4135 -24305555.56353 +4255 4135 -39081501.55875 +4256 4135 -17343750.0057 +4257 4135 -24305555.27187 +4258 4135 -61681981.76159 +4259 4135 -17343749.90781 +4260 4135 29166666.38457 +4261 4135 -9282077.504995 +4262 4135 20812499.90894 +4136 4136 744714928.2643 +4143 4136 -3.576278686523e-06 +4144 4136 -1.341104507446e-07 +4145 4136 -25180890.14438 +4146 4136 -1.293420791626e-05 +4147 4136 3.576278686523e-07 +4148 4136 -32232076.56353 +4149 4136 1.192092895508e-06 +4150 4136 3.218650817871e-06 +4151 4136 61881047.11197 +4233 4136 17343888.52033 +4234 4136 -20812499.90895 +4235 4136 -24752206.67999 +4242 4136 -21679860.74398 +4243 4136 -69374999.6084 +4244 4136 -84490851.68299 +4245 4136 -17343888.84952 +4246 4136 -13874999.85144 +4247 4136 -65361760.6378 +4254 4136 -21679861.11823 +4255 4136 -17343750.0057 +4256 4136 -36432062.04358 +4257 4136 -86719444.24762 +4258 4136 -17343749.94044 +4259 4136 -110741809.7386 +4260 4136 -26015832.7805 +4261 4136 13874999.9393 +4262 4136 -24752206.67999 +4137 4137 1319128267.022 +4138 4137 9.775161743164e-06 +4139 4137 -5.745887756348e-05 +4140 4137 174228645.9499 +4141 4137 -4.291534423828e-06 +4142 4137 -1.45435333252e-05 +4152 4137 -318367567.7659 +4153 4137 -2.443790435791e-06 +4154 4137 -1.460313796997e-05 +4155 4137 -118480247.2419 +4156 4137 81018055.54225 +4157 4137 -3.516674041748e-06 +4236 4137 -138827443.8752 +4237 4137 2.682209014893e-07 +4238 4137 86719444.4302 +4239 4137 -46373434.23614 +4240 4137 -24305555.56354 +4241 4137 21679861.11823 +4248 4137 222474230.8735 +4249 4137 3.933906555176e-06 +4250 4137 2.622604370117e-05 +4251 4137 8952264.76783 +4252 4137 -1.302361488342e-05 +4253 4137 6.914138793945e-06 +4263 4137 -138827443.8751 +4264 4137 -5.066394805908e-07 +4265 4137 -86719444.43019 +4266 4137 -46373434.23611 +4267 4137 24305555.56353 +4268 4137 -21679861.11823 +4138 4138 1124677840.302 +4139 4138 -3.814697265625e-06 +4140 4138 -4.947185516357e-06 +4141 4138 -133639662.3675 +4142 4138 -8.046627044678e-07 +4152 4138 -1.072883605957e-06 +4153 4138 38113347.20754 +4154 4138 -1.192092895508e-06 +4155 4138 81018055.54225 +4156 4138 -94173943.88989 +4157 4138 -2.682209014893e-07 +4236 4138 -2.294778823853e-06 +4237 4138 -31882558.21685 +4238 4138 2.682209014893e-07 +4239 4138 -24305555.56354 +4240 4138 -39081501.55876 +4241 4138 17343750.0057 +4248 4138 4.410743713379e-06 +4249 4138 164138769.4832 +4250 4138 -1.192092895508e-07 +4251 4138 -1.156330108643e-05 +4252 4138 -83408755.55014 +4253 4138 69374999.9886 +4263 4138 -8.344650268555e-07 +4264 4138 -31882558.21681 +4265 4138 -3.278255462646e-07 +4266 4138 24305555.56353 +4267 4138 -39081501.55875 +4268 4138 17343750.00569 +4139 4139 1191543893.2 +4140 4139 -1.45435333252e-05 +4141 4139 -1.192092895508e-06 +4142 4139 142332552.4786 +4152 4139 -1.388788223267e-05 +4153 4139 -1.072883605957e-06 +4154 4139 54829860.44019 +4155 4139 -3.36766242981e-06 +4156 4139 -3.576278686523e-07 +4157 4139 -25180890.14437 +4236 4139 86719444.4302 +4237 4139 3.427267074585e-07 +4238 4139 -99061955.12464 +4239 4139 21679861.11823 +4240 4139 17343750.0057 +4241 4139 -36432062.04359 +4248 4139 2.598762512207e-05 +4249 4139 5.960464477539e-08 +4250 4139 -104578818.0156 +4251 4139 6.973743438721e-06 +4252 4139 69374999.9886 +4253 4139 -72810997.49471 +4263 4139 -86719444.43019 +4264 4139 -2.682209014893e-07 +4265 4139 -99061955.12461 +4266 4139 -21679861.11823 +4267 4139 17343750.00569 +4268 4139 -36432062.04358 +4140 4140 1319128267.022 +4141 4140 9.775161743164e-06 +4142 4140 -5.745887756348e-05 +4143 4140 174228645.9499 +4144 4140 -4.291534423828e-06 +4145 4140 -1.45435333252e-05 +4152 4140 -118480247.2419 +4153 4140 -81018055.54225 +4154 4140 -3.695487976074e-06 +4155 4140 -318367567.7659 +4156 4140 -2.443790435791e-06 +4157 4140 -1.460313796997e-05 +4158 4140 -118480247.2419 +4159 4140 81018055.54225 +4160 4140 -3.516674041748e-06 +4236 4140 -46373434.23613 +4237 4140 24305555.56354 +4238 4140 21679861.11823 +4239 4140 -138827443.8752 +4240 4140 2.682209014893e-07 +4241 4140 86719444.4302 +4242 4140 -46373434.23614 +4243 4140 -24305555.56354 +4244 4140 21679861.11823 +4248 4140 8952264.76783 +4249 4140 9.298324584961e-06 +4250 4140 6.228685379028e-06 +4251 4140 222474230.8735 +4252 4140 3.933906555176e-06 +4253 4140 2.622604370117e-05 +4254 4140 8952264.76783 +4255 4140 -1.302361488342e-05 +4256 4140 6.914138793945e-06 +4263 4140 -46373434.23611 +4264 4140 -24305555.56353 +4265 4140 -21679861.11823 +4266 4140 -138827443.8751 +4267 4140 -5.066394805908e-07 +4268 4140 -86719444.43019 +4269 4140 -46373434.23611 +4270 4140 24305555.56353 +4271 4140 -21679861.11823 +4141 4141 1124677840.302 +4142 4141 -3.814697265625e-06 +4143 4141 -4.947185516357e-06 +4144 4141 -133639662.3675 +4145 4141 -8.046627044678e-07 +4152 4141 -81018055.54225 +4153 4141 -94173943.88989 +4154 4141 -1.9371509552e-07 +4155 4141 -1.072883605957e-06 +4156 4141 38113347.20754 +4157 4141 -1.192092895508e-06 +4158 4141 81018055.54225 +4159 4141 -94173943.88989 +4160 4141 -2.682209014893e-07 +4236 4141 24305555.56354 +4237 4141 -39081501.55876 +4238 4141 -17343750.00569 +4239 4141 -2.294778823853e-06 +4240 4141 -31882558.21685 +4241 4141 2.682209014893e-07 +4242 4141 -24305555.56354 +4243 4141 -39081501.55876 +4244 4141 17343750.0057 +4248 4141 1.069903373718e-05 +4249 4141 -83408755.55014 +4250 4141 -69374999.9886 +4251 4141 4.410743713379e-06 +4252 4141 164138769.4832 +4253 4141 -1.192092895508e-07 +4254 4141 -1.156330108643e-05 +4255 4141 -83408755.55014 +4256 4141 69374999.9886 +4263 4141 -24305555.56353 +4264 4141 -39081501.55875 +4265 4141 -17343750.0057 +4266 4141 -8.344650268555e-07 +4267 4141 -31882558.21681 +4268 4141 -3.278255462646e-07 +4269 4141 24305555.56353 +4270 4141 -39081501.55875 +4271 4141 17343750.00569 +4142 4142 1191543893.2 +4143 4142 -1.45435333252e-05 +4144 4142 -1.192092895508e-06 +4145 4142 142332552.4786 +4152 4142 -3.576278686523e-06 +4153 4142 -1.341104507446e-07 +4154 4142 -25180890.14438 +4155 4142 -1.388788223267e-05 +4156 4142 -1.072883605957e-06 +4157 4142 54829860.44019 +4158 4142 -3.36766242981e-06 +4159 4142 -3.576278686523e-07 +4160 4142 -25180890.14437 +4236 4142 21679861.11823 +4237 4142 -17343750.0057 +4238 4142 -36432062.04359 +4239 4142 86719444.4302 +4240 4142 3.427267074585e-07 +4241 4142 -99061955.12464 +4242 4142 21679861.11823 +4243 4142 17343750.0057 +4244 4142 -36432062.04359 +4248 4142 6.169080734253e-06 +4249 4142 -69374999.9886 +4250 4142 -72810997.49471 +4251 4142 2.598762512207e-05 +4252 4142 5.960464477539e-08 +4253 4142 -104578818.0156 +4254 4142 6.973743438721e-06 +4255 4142 69374999.9886 +4256 4142 -72810997.49471 +4263 4142 -21679861.11823 +4264 4142 -17343750.0057 +4265 4142 -36432062.04358 +4266 4142 -86719444.43019 +4267 4142 -2.682209014893e-07 +4268 4142 -99061955.12461 +4269 4142 -21679861.11823 +4270 4142 17343750.00569 +4271 4142 -36432062.04358 +4143 4143 1319128267.022 +4144 4143 9.775161743164e-06 +4145 4143 -5.745887756348e-05 +4146 4143 174228645.9499 +4147 4143 -4.291534423828e-06 +4148 4143 -1.45435333252e-05 +4155 4143 -118480247.2419 +4156 4143 -81018055.54225 +4157 4143 -3.695487976074e-06 +4158 4143 -318367567.7659 +4159 4143 -2.443790435791e-06 +4160 4143 -1.460313796997e-05 +4161 4143 -118480247.2419 +4162 4143 81018055.54225 +4163 4143 -3.516674041748e-06 +4239 4143 -46373434.23613 +4240 4143 24305555.56354 +4241 4143 21679861.11823 +4242 4143 -138827443.8752 +4243 4143 2.682209014893e-07 +4244 4143 86719444.4302 +4245 4143 -46373434.23614 +4246 4143 -24305555.56354 +4247 4143 21679861.11823 +4251 4143 8952264.76783 +4252 4143 9.298324584961e-06 +4253 4143 6.228685379028e-06 +4254 4143 222474230.8735 +4255 4143 3.933906555176e-06 +4256 4143 2.622604370117e-05 +4257 4143 8952264.76783 +4258 4143 -1.302361488342e-05 +4259 4143 6.914138793945e-06 +4266 4143 -46373434.23611 +4267 4143 -24305555.56353 +4268 4143 -21679861.11823 +4269 4143 -138827443.8751 +4270 4143 -5.066394805908e-07 +4271 4143 -86719444.43019 +4272 4143 -46373434.23611 +4273 4143 24305555.56353 +4274 4143 -21679861.11823 +4144 4144 1124677840.302 +4145 4144 -3.814697265625e-06 +4146 4144 -4.947185516357e-06 +4147 4144 -133639662.3675 +4148 4144 -8.046627044678e-07 +4155 4144 -81018055.54225 +4156 4144 -94173943.88989 +4157 4144 -1.9371509552e-07 +4158 4144 -1.072883605957e-06 +4159 4144 38113347.20754 +4160 4144 -1.192092895508e-06 +4161 4144 81018055.54225 +4162 4144 -94173943.88989 +4163 4144 -2.682209014893e-07 +4239 4144 24305555.56354 +4240 4144 -39081501.55876 +4241 4144 -17343750.00569 +4242 4144 -2.294778823853e-06 +4243 4144 -31882558.21685 +4244 4144 2.682209014893e-07 +4245 4144 -24305555.56354 +4246 4144 -39081501.55876 +4247 4144 17343750.0057 +4251 4144 1.069903373718e-05 +4252 4144 -83408755.55014 +4253 4144 -69374999.9886 +4254 4144 4.410743713379e-06 +4255 4144 164138769.4832 +4256 4144 -1.192092895508e-07 +4257 4144 -1.156330108643e-05 +4258 4144 -83408755.55014 +4259 4144 69374999.9886 +4266 4144 -24305555.56353 +4267 4144 -39081501.55875 +4268 4144 -17343750.0057 +4269 4144 -8.344650268555e-07 +4270 4144 -31882558.21681 +4271 4144 -3.278255462646e-07 +4272 4144 24305555.56353 +4273 4144 -39081501.55875 +4274 4144 17343750.00569 +4145 4145 1191543893.2 +4146 4145 -1.45435333252e-05 +4147 4145 -1.192092895508e-06 +4148 4145 142332552.4786 +4155 4145 -3.576278686523e-06 +4156 4145 -1.341104507446e-07 +4157 4145 -25180890.14438 +4158 4145 -1.388788223267e-05 +4159 4145 -1.072883605957e-06 +4160 4145 54829860.44019 +4161 4145 -3.36766242981e-06 +4162 4145 -3.576278686523e-07 +4163 4145 -25180890.14437 +4239 4145 21679861.11823 +4240 4145 -17343750.0057 +4241 4145 -36432062.04359 +4242 4145 86719444.4302 +4243 4145 3.427267074585e-07 +4244 4145 -99061955.12464 +4245 4145 21679861.11823 +4246 4145 17343750.0057 +4247 4145 -36432062.04359 +4251 4145 6.169080734253e-06 +4252 4145 -69374999.9886 +4253 4145 -72810997.49471 +4254 4145 2.598762512207e-05 +4255 4145 5.960464477539e-08 +4256 4145 -104578818.0156 +4257 4145 6.973743438721e-06 +4258 4145 69374999.9886 +4259 4145 -72810997.49471 +4266 4145 -21679861.11823 +4267 4145 -17343750.0057 +4268 4145 -36432062.04358 +4269 4145 -86719444.43019 +4270 4145 -2.682209014893e-07 +4271 4145 -99061955.12461 +4272 4145 -21679861.11823 +4273 4145 17343750.00569 +4274 4145 -36432062.04358 +4146 4146 1437608510.215 +4147 4146 81018053.92186 +4148 4146 -4.029273986816e-05 +4149 4146 32543005.93566 +4150 4146 -81018054.8941 +4151 4146 -4.887580871582e-06 +4158 4146 -118480247.2419 +4159 4146 -81018055.54225 +4160 4146 -3.695487976074e-06 +4161 4146 -318367567.7659 +4162 4146 -2.443790435791e-06 +4163 4146 -1.460313796997e-05 +4164 4146 -118480247.2419 +4165 4146 81018055.54225 +4166 4146 -3.516674041748e-06 +4242 4146 -46373434.23613 +4243 4146 24305555.56354 +4244 4146 21679861.11823 +4245 4146 -175918799.4897 +4246 4146 -24305555.27186 +4247 4146 86719444.24762 +4254 4146 8952264.76783 +4255 4146 9.298324584961e-06 +4256 4146 6.228685379028e-06 +4257 4146 268847663.9159 +4258 4146 24305555.07742 +4259 4146 0.03653132915497 +4260 4146 -28139091.37671 +4261 4146 -24305555.36909 +4262 4146 21679860.74398 +4269 4146 -46373434.23611 +4270 4146 -24305555.56353 +4271 4146 -21679861.11823 +4272 4146 -138827443.8751 +4273 4146 -5.066394805908e-07 +4274 4146 -86719444.43019 +4275 4146 -46373434.23611 +4276 4146 24305555.56353 +4277 4146 -21679861.11823 +4147 4147 1218851780.873 +4148 4147 -1.430511474609e-06 +4149 4147 -81018054.57003 +4150 4147 -251018997.7335 +4151 4147 -4.26173210144e-06 +4158 4147 -81018055.54225 +4159 4147 -94173943.88989 +4160 4147 -1.9371509552e-07 +4161 4147 -1.072883605957e-06 +4162 4147 38113347.20754 +4163 4147 -1.192092895508e-06 +4164 4147 81018055.54225 +4165 4147 -94173943.88989 +4166 4147 -2.682209014893e-07 +4242 4147 24305555.56354 +4243 4147 -39081501.55876 +4244 4147 -17343750.00569 +4245 4147 -24305555.36908 +4246 4147 -61681981.7616 +4247 4147 17343749.94043 +4254 4147 1.069903373718e-05 +4255 4147 -83408755.55014 +4256 4147 -69374999.9886 +4257 4147 24305555.07742 +4258 4147 203220270.0671 +4259 4147 0.02920919656754 +4260 4147 -24305555.27186 +4261 4147 -113208178.6284 +4262 4147 69374999.6084 +4269 4147 -24305555.56353 +4270 4147 -39081501.55875 +4271 4147 -17343750.0057 +4272 4147 -8.344650268555e-07 +4273 4147 -31882558.21681 +4274 4147 -3.278255462646e-07 +4275 4147 24305555.56353 +4276 4147 -39081501.55875 +4277 4147 17343750.00569 +4148 4148 1216724781.271 +4149 4148 -4.52995300293e-06 +4150 4148 -3.457069396973e-06 +4151 4148 55270613.64501 +4158 4148 -3.576278686523e-06 +4159 4148 -1.341104507446e-07 +4160 4148 -25180890.14438 +4161 4148 -1.388788223267e-05 +4162 4148 -1.072883605957e-06 +4163 4148 54829860.44019 +4164 4148 -3.36766242981e-06 +4165 4148 -3.576278686523e-07 +4166 4148 -25180890.14437 +4242 4148 21679861.11823 +4243 4148 -17343750.0057 +4244 4148 -36432062.04359 +4245 4148 86719444.24762 +4246 4148 17343749.9078 +4247 4148 -110741809.7386 +4254 4148 6.169080734253e-06 +4255 4148 -69374999.9886 +4256 4148 -72810997.49471 +4257 4148 -0.03649973869324 +4258 4148 -0.02921465039253 +4259 4148 -68146756.53808 +4260 4148 21679860.55685 +4261 4148 69374999.49133 +4262 4148 -84490851.68298 +4269 4148 -21679861.11823 +4270 4148 -17343750.0057 +4271 4148 -36432062.04358 +4272 4148 -86719444.43019 +4273 4148 -2.682209014893e-07 +4274 4148 -99061955.12461 +4275 4148 -21679861.11823 +4276 4148 17343750.00569 +4277 4148 -36432062.04358 +4149 4149 824455161.8017 +4150 4149 81018055.54225 +4151 4149 -8.583068847656e-06 +4161 4149 -118480247.2419 +4162 4149 -81018055.54225 +4163 4149 -3.695487976074e-06 +4164 4149 -460053204.795 +4165 4149 -81018054.89409 +4166 4149 -1.305341720581e-05 +4167 4149 23205392.66699 +4168 4149 64814443.78565 +4169 4149 1.54972076416e-06 +4245 4149 -9282077.50499 +4246 4149 29166666.38457 +4247 4149 26015832.78049 +4257 4149 -28139091.37673 +4258 4149 -24305555.27187 +4259 4149 -21679860.55685 +4260 4149 139046393.5639 +4261 4149 24305555.56354 +4262 4149 17343888.84952 +4272 4149 -46373434.23611 +4273 4149 -24305555.56353 +4274 4149 -21679861.11823 +4275 4149 -175918799.4896 +4276 4149 -24305555.36909 +4277 4149 -86719444.24762 +4278 4149 -9282077.505002 +4279 4149 19444444.25638 +4280 4149 -17343888.52033 +4150 4150 702923645.8189 +4151 4150 7.830374228711e-07 +4161 4150 -81018055.54225 +4162 4150 -94173943.88989 +4163 4150 -1.9371509552e-07 +4164 4150 -81018054.57002 +4165 4150 -79265988.49504 +4166 4150 -7.152557373047e-07 +4167 4150 97221665.67847 +4168 4150 23205392.66698 +4169 4150 3.457069396973e-06 +4245 4150 19444444.25638 +4246 4150 -9282077.505 +4247 4150 -13874999.9393 +4257 4150 -24305555.36909 +4258 4150 -113208178.6284 +4259 4150 -69374999.49133 +4260 4150 24305555.56354 +4261 4150 102586730.4102 +4262 4150 13874999.85143 +4272 4150 -24305555.56353 +4273 4150 -39081501.55875 +4274 4150 -17343750.0057 +4275 4150 -24305555.27187 +4276 4150 -61681981.76159 +4277 4150 -17343749.90781 +4278 4150 29166666.38457 +4279 4150 -9282077.504995 +4280 4150 20812499.90894 +4151 4151 744714928.2643 +4161 4151 -3.576278686523e-06 +4162 4151 -1.341104507446e-07 +4163 4151 -25180890.14438 +4164 4151 -1.293420791626e-05 +4165 4151 3.576278686523e-07 +4166 4151 -32232076.56353 +4167 4151 1.192092895508e-06 +4168 4151 3.218650817871e-06 +4169 4151 61881047.11197 +4245 4151 17343888.52033 +4246 4151 -20812499.90895 +4247 4151 -24752206.67999 +4257 4151 -21679860.74398 +4258 4151 -69374999.6084 +4259 4151 -84490851.68299 +4260 4151 -17343888.84952 +4261 4151 -13874999.85144 +4262 4151 -65361760.6378 +4272 4151 -21679861.11823 +4273 4151 -17343750.0057 +4274 4151 -36432062.04358 +4275 4151 -86719444.24762 +4276 4151 -17343749.94044 +4277 4151 -110741809.7386 +4278 4151 -26015832.7805 +4279 4151 13874999.9393 +4280 4151 -24752206.67999 +4152 4152 1319128267.022 +4153 4152 9.775161743164e-06 +4154 4152 -5.745887756348e-05 +4155 4152 174228645.9499 +4156 4152 -4.291534423828e-06 +4157 4152 -1.45435333252e-05 +4170 4152 -318367567.7659 +4171 4152 -2.443790435791e-06 +4172 4152 -1.460313796997e-05 +4173 4152 -118480247.2419 +4174 4152 81018055.54225 +4175 4152 -3.516674041748e-06 +4248 4152 -138827443.8752 +4249 4152 2.682209014893e-07 +4250 4152 86719444.4302 +4251 4152 -46373434.23614 +4252 4152 -24305555.56354 +4253 4152 21679861.11823 +4263 4152 222474230.8735 +4264 4152 3.933906555176e-06 +4265 4152 2.622604370117e-05 +4266 4152 8952264.76783 +4267 4152 -1.302361488342e-05 +4268 4152 6.914138793945e-06 +4281 4152 -138827443.8751 +4282 4152 -5.066394805908e-07 +4283 4152 -86719444.43019 +4284 4152 -46373434.23611 +4285 4152 24305555.56353 +4286 4152 -21679861.11823 +4153 4153 1124677840.302 +4154 4153 -3.814697265625e-06 +4155 4153 -4.947185516357e-06 +4156 4153 -133639662.3675 +4157 4153 -8.046627044678e-07 +4170 4153 -1.072883605957e-06 +4171 4153 38113347.20754 +4172 4153 -1.192092895508e-06 +4173 4153 81018055.54225 +4174 4153 -94173943.88989 +4175 4153 -2.682209014893e-07 +4248 4153 -2.294778823853e-06 +4249 4153 -31882558.21685 +4250 4153 2.682209014893e-07 +4251 4153 -24305555.56354 +4252 4153 -39081501.55876 +4253 4153 17343750.0057 +4263 4153 4.410743713379e-06 +4264 4153 164138769.4832 +4265 4153 -1.192092895508e-07 +4266 4153 -1.156330108643e-05 +4267 4153 -83408755.55014 +4268 4153 69374999.9886 +4281 4153 -8.344650268555e-07 +4282 4153 -31882558.21681 +4283 4153 -3.278255462646e-07 +4284 4153 24305555.56353 +4285 4153 -39081501.55875 +4286 4153 17343750.00569 +4154 4154 1191543893.2 +4155 4154 -1.45435333252e-05 +4156 4154 -1.192092895508e-06 +4157 4154 142332552.4786 +4170 4154 -1.388788223267e-05 +4171 4154 -1.072883605957e-06 +4172 4154 54829860.44019 +4173 4154 -3.36766242981e-06 +4174 4154 -3.576278686523e-07 +4175 4154 -25180890.14437 +4248 4154 86719444.4302 +4249 4154 3.427267074585e-07 +4250 4154 -99061955.12464 +4251 4154 21679861.11823 +4252 4154 17343750.0057 +4253 4154 -36432062.04359 +4263 4154 2.598762512207e-05 +4264 4154 5.960464477539e-08 +4265 4154 -104578818.0156 +4266 4154 6.973743438721e-06 +4267 4154 69374999.9886 +4268 4154 -72810997.49471 +4281 4154 -86719444.43019 +4282 4154 -2.682209014893e-07 +4283 4154 -99061955.12461 +4284 4154 -21679861.11823 +4285 4154 17343750.00569 +4286 4154 -36432062.04358 +4155 4155 1319128267.022 +4156 4155 9.775161743164e-06 +4157 4155 -5.745887756348e-05 +4158 4155 174228645.9499 +4159 4155 -4.291534423828e-06 +4160 4155 -1.45435333252e-05 +4170 4155 -118480247.2419 +4171 4155 -81018055.54225 +4172 4155 -3.695487976074e-06 +4173 4155 -318367567.7659 +4174 4155 -2.443790435791e-06 +4175 4155 -1.460313796997e-05 +4176 4155 -118480247.2419 +4177 4155 81018055.54225 +4178 4155 -3.516674041748e-06 +4248 4155 -46373434.23613 +4249 4155 24305555.56354 +4250 4155 21679861.11823 +4251 4155 -138827443.8752 +4252 4155 2.682209014893e-07 +4253 4155 86719444.4302 +4254 4155 -46373434.23614 +4255 4155 -24305555.56354 +4256 4155 21679861.11823 +4263 4155 8952264.76783 +4264 4155 9.298324584961e-06 +4265 4155 6.228685379028e-06 +4266 4155 222474230.8735 +4267 4155 3.933906555176e-06 +4268 4155 2.622604370117e-05 +4269 4155 8952264.76783 +4270 4155 -1.302361488342e-05 +4271 4155 6.914138793945e-06 +4281 4155 -46373434.23611 +4282 4155 -24305555.56353 +4283 4155 -21679861.11823 +4284 4155 -138827443.8751 +4285 4155 -5.066394805908e-07 +4286 4155 -86719444.43019 +4287 4155 -46373434.23611 +4288 4155 24305555.56353 +4289 4155 -21679861.11823 +4156 4156 1124677840.302 +4157 4156 -3.814697265625e-06 +4158 4156 -4.947185516357e-06 +4159 4156 -133639662.3675 +4160 4156 -8.046627044678e-07 +4170 4156 -81018055.54225 +4171 4156 -94173943.88989 +4172 4156 -1.9371509552e-07 +4173 4156 -1.072883605957e-06 +4174 4156 38113347.20754 +4175 4156 -1.192092895508e-06 +4176 4156 81018055.54225 +4177 4156 -94173943.88989 +4178 4156 -2.682209014893e-07 +4248 4156 24305555.56354 +4249 4156 -39081501.55876 +4250 4156 -17343750.00569 +4251 4156 -2.294778823853e-06 +4252 4156 -31882558.21685 +4253 4156 2.682209014893e-07 +4254 4156 -24305555.56354 +4255 4156 -39081501.55876 +4256 4156 17343750.0057 +4263 4156 1.069903373718e-05 +4264 4156 -83408755.55014 +4265 4156 -69374999.9886 +4266 4156 4.410743713379e-06 +4267 4156 164138769.4832 +4268 4156 -1.192092895508e-07 +4269 4156 -1.156330108643e-05 +4270 4156 -83408755.55014 +4271 4156 69374999.9886 +4281 4156 -24305555.56353 +4282 4156 -39081501.55875 +4283 4156 -17343750.0057 +4284 4156 -8.344650268555e-07 +4285 4156 -31882558.21681 +4286 4156 -3.278255462646e-07 +4287 4156 24305555.56353 +4288 4156 -39081501.55875 +4289 4156 17343750.00569 +4157 4157 1191543893.2 +4158 4157 -1.45435333252e-05 +4159 4157 -1.192092895508e-06 +4160 4157 142332552.4786 +4170 4157 -3.576278686523e-06 +4171 4157 -1.341104507446e-07 +4172 4157 -25180890.14438 +4173 4157 -1.388788223267e-05 +4174 4157 -1.072883605957e-06 +4175 4157 54829860.44019 +4176 4157 -3.36766242981e-06 +4177 4157 -3.576278686523e-07 +4178 4157 -25180890.14437 +4248 4157 21679861.11823 +4249 4157 -17343750.0057 +4250 4157 -36432062.04359 +4251 4157 86719444.4302 +4252 4157 3.427267074585e-07 +4253 4157 -99061955.12464 +4254 4157 21679861.11823 +4255 4157 17343750.0057 +4256 4157 -36432062.04359 +4263 4157 6.169080734253e-06 +4264 4157 -69374999.9886 +4265 4157 -72810997.49471 +4266 4157 2.598762512207e-05 +4267 4157 5.960464477539e-08 +4268 4157 -104578818.0156 +4269 4157 6.973743438721e-06 +4270 4157 69374999.9886 +4271 4157 -72810997.49471 +4281 4157 -21679861.11823 +4282 4157 -17343750.0057 +4283 4157 -36432062.04358 +4284 4157 -86719444.43019 +4285 4157 -2.682209014893e-07 +4286 4157 -99061955.12461 +4287 4157 -21679861.11823 +4288 4157 17343750.00569 +4289 4157 -36432062.04358 +4158 4158 1319128267.022 +4159 4158 9.775161743164e-06 +4160 4158 -5.745887756348e-05 +4161 4158 174228645.9499 +4162 4158 -4.291534423828e-06 +4163 4158 -1.45435333252e-05 +4173 4158 -118480247.2419 +4174 4158 -81018055.54225 +4175 4158 -3.695487976074e-06 +4176 4158 -318367567.7659 +4177 4158 -2.443790435791e-06 +4178 4158 -1.460313796997e-05 +4179 4158 -118480247.2419 +4180 4158 81018055.54225 +4181 4158 -3.516674041748e-06 +4251 4158 -46373434.23613 +4252 4158 24305555.56354 +4253 4158 21679861.11823 +4254 4158 -138827443.8752 +4255 4158 2.682209014893e-07 +4256 4158 86719444.4302 +4257 4158 -46373434.23614 +4258 4158 -24305555.56354 +4259 4158 21679861.11823 +4266 4158 8952264.76783 +4267 4158 9.298324584961e-06 +4268 4158 6.228685379028e-06 +4269 4158 222474230.8735 +4270 4158 3.933906555176e-06 +4271 4158 2.622604370117e-05 +4272 4158 8952264.76783 +4273 4158 -1.302361488342e-05 +4274 4158 6.914138793945e-06 +4284 4158 -46373434.23611 +4285 4158 -24305555.56353 +4286 4158 -21679861.11823 +4287 4158 -138827443.8751 +4288 4158 -5.066394805908e-07 +4289 4158 -86719444.43019 +4290 4158 -46373434.23611 +4291 4158 24305555.56353 +4292 4158 -21679861.11823 +4159 4159 1124677840.302 +4160 4159 -3.814697265625e-06 +4161 4159 -4.947185516357e-06 +4162 4159 -133639662.3675 +4163 4159 -8.046627044678e-07 +4173 4159 -81018055.54225 +4174 4159 -94173943.88989 +4175 4159 -1.9371509552e-07 +4176 4159 -1.072883605957e-06 +4177 4159 38113347.20754 +4178 4159 -1.192092895508e-06 +4179 4159 81018055.54225 +4180 4159 -94173943.88989 +4181 4159 -2.682209014893e-07 +4251 4159 24305555.56354 +4252 4159 -39081501.55876 +4253 4159 -17343750.00569 +4254 4159 -2.294778823853e-06 +4255 4159 -31882558.21685 +4256 4159 2.682209014893e-07 +4257 4159 -24305555.56354 +4258 4159 -39081501.55876 +4259 4159 17343750.0057 +4266 4159 1.069903373718e-05 +4267 4159 -83408755.55014 +4268 4159 -69374999.9886 +4269 4159 4.410743713379e-06 +4270 4159 164138769.4832 +4271 4159 -1.192092895508e-07 +4272 4159 -1.156330108643e-05 +4273 4159 -83408755.55014 +4274 4159 69374999.9886 +4284 4159 -24305555.56353 +4285 4159 -39081501.55875 +4286 4159 -17343750.0057 +4287 4159 -8.344650268555e-07 +4288 4159 -31882558.21681 +4289 4159 -3.278255462646e-07 +4290 4159 24305555.56353 +4291 4159 -39081501.55875 +4292 4159 17343750.00569 +4160 4160 1191543893.2 +4161 4160 -1.45435333252e-05 +4162 4160 -1.192092895508e-06 +4163 4160 142332552.4786 +4173 4160 -3.576278686523e-06 +4174 4160 -1.341104507446e-07 +4175 4160 -25180890.14438 +4176 4160 -1.388788223267e-05 +4177 4160 -1.072883605957e-06 +4178 4160 54829860.44019 +4179 4160 -3.36766242981e-06 +4180 4160 -3.576278686523e-07 +4181 4160 -25180890.14437 +4251 4160 21679861.11823 +4252 4160 -17343750.0057 +4253 4160 -36432062.04359 +4254 4160 86719444.4302 +4255 4160 3.427267074585e-07 +4256 4160 -99061955.12464 +4257 4160 21679861.11823 +4258 4160 17343750.0057 +4259 4160 -36432062.04359 +4266 4160 6.169080734253e-06 +4267 4160 -69374999.9886 +4268 4160 -72810997.49471 +4269 4160 2.598762512207e-05 +4270 4160 5.960464477539e-08 +4271 4160 -104578818.0156 +4272 4160 6.973743438721e-06 +4273 4160 69374999.9886 +4274 4160 -72810997.49471 +4284 4160 -21679861.11823 +4285 4160 -17343750.0057 +4286 4160 -36432062.04358 +4287 4160 -86719444.43019 +4288 4160 -2.682209014893e-07 +4289 4160 -99061955.12461 +4290 4160 -21679861.11823 +4291 4160 17343750.00569 +4292 4160 -36432062.04358 +4161 4161 1319128267.022 +4162 4161 9.775161743164e-06 +4163 4161 -5.745887756348e-05 +4164 4161 174228645.9499 +4165 4161 -4.291534423828e-06 +4166 4161 -1.45435333252e-05 +4176 4161 -118480247.2419 +4177 4161 -81018055.54225 +4178 4161 -3.695487976074e-06 +4179 4161 -318367567.7659 +4180 4161 -2.443790435791e-06 +4181 4161 -1.460313796997e-05 +4182 4161 -118480247.2419 +4183 4161 81018055.54225 +4184 4161 -3.516674041748e-06 +4254 4161 -46373434.23613 +4255 4161 24305555.56354 +4256 4161 21679861.11823 +4257 4161 -138827443.8752 +4258 4161 2.682209014893e-07 +4259 4161 86719444.4302 +4260 4161 -46373434.23614 +4261 4161 -24305555.56354 +4262 4161 21679861.11823 +4269 4161 8952264.76783 +4270 4161 9.298324584961e-06 +4271 4161 6.228685379028e-06 +4272 4161 222474230.8735 +4273 4161 3.933906555176e-06 +4274 4161 2.622604370117e-05 +4275 4161 8952264.76783 +4276 4161 -1.302361488342e-05 +4277 4161 6.914138793945e-06 +4287 4161 -46373434.23611 +4288 4161 -24305555.56353 +4289 4161 -21679861.11823 +4290 4161 -138827443.8751 +4291 4161 -5.066394805908e-07 +4292 4161 -86719444.43019 +4293 4161 -46373434.23611 +4294 4161 24305555.56353 +4295 4161 -21679861.11823 +4162 4162 1124677840.302 +4163 4162 -3.814697265625e-06 +4164 4162 -4.947185516357e-06 +4165 4162 -133639662.3675 +4166 4162 -8.046627044678e-07 +4176 4162 -81018055.54225 +4177 4162 -94173943.88989 +4178 4162 -1.9371509552e-07 +4179 4162 -1.072883605957e-06 +4180 4162 38113347.20754 +4181 4162 -1.192092895508e-06 +4182 4162 81018055.54225 +4183 4162 -94173943.88989 +4184 4162 -2.682209014893e-07 +4254 4162 24305555.56354 +4255 4162 -39081501.55876 +4256 4162 -17343750.00569 +4257 4162 -2.294778823853e-06 +4258 4162 -31882558.21685 +4259 4162 2.682209014893e-07 +4260 4162 -24305555.56354 +4261 4162 -39081501.55876 +4262 4162 17343750.0057 +4269 4162 1.069903373718e-05 +4270 4162 -83408755.55014 +4271 4162 -69374999.9886 +4272 4162 4.410743713379e-06 +4273 4162 164138769.4832 +4274 4162 -1.192092895508e-07 +4275 4162 -1.156330108643e-05 +4276 4162 -83408755.55014 +4277 4162 69374999.9886 +4287 4162 -24305555.56353 +4288 4162 -39081501.55875 +4289 4162 -17343750.0057 +4290 4162 -8.344650268555e-07 +4291 4162 -31882558.21681 +4292 4162 -3.278255462646e-07 +4293 4162 24305555.56353 +4294 4162 -39081501.55875 +4295 4162 17343750.00569 +4163 4163 1191543893.2 +4164 4163 -1.45435333252e-05 +4165 4163 -1.192092895508e-06 +4166 4163 142332552.4786 +4176 4163 -3.576278686523e-06 +4177 4163 -1.341104507446e-07 +4178 4163 -25180890.14438 +4179 4163 -1.388788223267e-05 +4180 4163 -1.072883605957e-06 +4181 4163 54829860.44019 +4182 4163 -3.36766242981e-06 +4183 4163 -3.576278686523e-07 +4184 4163 -25180890.14437 +4254 4163 21679861.11823 +4255 4163 -17343750.0057 +4256 4163 -36432062.04359 +4257 4163 86719444.4302 +4258 4163 3.427267074585e-07 +4259 4163 -99061955.12464 +4260 4163 21679861.11823 +4261 4163 17343750.0057 +4262 4163 -36432062.04359 +4269 4163 6.169080734253e-06 +4270 4163 -69374999.9886 +4271 4163 -72810997.49471 +4272 4163 2.598762512207e-05 +4273 4163 5.960464477539e-08 +4274 4163 -104578818.0156 +4275 4163 6.973743438721e-06 +4276 4163 69374999.9886 +4277 4163 -72810997.49471 +4287 4163 -21679861.11823 +4288 4163 -17343750.0057 +4289 4163 -36432062.04358 +4290 4163 -86719444.43019 +4291 4163 -2.682209014893e-07 +4292 4163 -99061955.12461 +4293 4163 -21679861.11823 +4294 4163 17343750.00569 +4295 4163 -36432062.04358 +4164 4164 1437608510.215 +4165 4164 81018053.92186 +4166 4164 -4.029273986816e-05 +4167 4164 32543005.93566 +4168 4164 -81018054.8941 +4169 4164 -4.887580871582e-06 +4179 4164 -118480247.2419 +4180 4164 -81018055.54225 +4181 4164 -3.695487976074e-06 +4182 4164 -318367567.7659 +4183 4164 -2.443790435791e-06 +4184 4164 -1.460313796997e-05 +4185 4164 -118480247.2419 +4186 4164 81018055.54225 +4187 4164 -3.516674041748e-06 +4257 4164 -46373434.23613 +4258 4164 24305555.56354 +4259 4164 21679861.11823 +4260 4164 -175918799.4897 +4261 4164 -24305555.27186 +4262 4164 86719444.24762 +4272 4164 8952264.76783 +4273 4164 9.298324584961e-06 +4274 4164 6.228685379028e-06 +4275 4164 268847663.9159 +4276 4164 24305555.07742 +4277 4164 0.03653132915497 +4278 4164 -28139091.37671 +4279 4164 -24305555.36909 +4280 4164 21679860.74398 +4290 4164 -46373434.23611 +4291 4164 -24305555.56353 +4292 4164 -21679861.11823 +4293 4164 -138827443.8751 +4294 4164 -5.066394805908e-07 +4295 4164 -86719444.43019 +4296 4164 -46373434.23611 +4297 4164 24305555.56353 +4298 4164 -21679861.11823 +4165 4165 1218851780.873 +4166 4165 -1.430511474609e-06 +4167 4165 -81018054.57003 +4168 4165 -251018997.7335 +4169 4165 -4.26173210144e-06 +4179 4165 -81018055.54225 +4180 4165 -94173943.88989 +4181 4165 -1.9371509552e-07 +4182 4165 -1.072883605957e-06 +4183 4165 38113347.20754 +4184 4165 -1.192092895508e-06 +4185 4165 81018055.54225 +4186 4165 -94173943.88989 +4187 4165 -2.682209014893e-07 +4257 4165 24305555.56354 +4258 4165 -39081501.55876 +4259 4165 -17343750.00569 +4260 4165 -24305555.36908 +4261 4165 -61681981.7616 +4262 4165 17343749.94043 +4272 4165 1.069903373718e-05 +4273 4165 -83408755.55014 +4274 4165 -69374999.9886 +4275 4165 24305555.07742 +4276 4165 203220270.0671 +4277 4165 0.02920919656754 +4278 4165 -24305555.27186 +4279 4165 -113208178.6284 +4280 4165 69374999.6084 +4290 4165 -24305555.56353 +4291 4165 -39081501.55875 +4292 4165 -17343750.0057 +4293 4165 -8.344650268555e-07 +4294 4165 -31882558.21681 +4295 4165 -3.278255462646e-07 +4296 4165 24305555.56353 +4297 4165 -39081501.55875 +4298 4165 17343750.00569 +4166 4166 1216724781.271 +4167 4166 -4.52995300293e-06 +4168 4166 -3.457069396973e-06 +4169 4166 55270613.64501 +4179 4166 -3.576278686523e-06 +4180 4166 -1.341104507446e-07 +4181 4166 -25180890.14438 +4182 4166 -1.388788223267e-05 +4183 4166 -1.072883605957e-06 +4184 4166 54829860.44019 +4185 4166 -3.36766242981e-06 +4186 4166 -3.576278686523e-07 +4187 4166 -25180890.14437 +4257 4166 21679861.11823 +4258 4166 -17343750.0057 +4259 4166 -36432062.04359 +4260 4166 86719444.24762 +4261 4166 17343749.9078 +4262 4166 -110741809.7386 +4272 4166 6.169080734253e-06 +4273 4166 -69374999.9886 +4274 4166 -72810997.49471 +4275 4166 -0.03649973869324 +4276 4166 -0.02921465039253 +4277 4166 -68146756.53808 +4278 4166 21679860.55685 +4279 4166 69374999.49133 +4280 4166 -84490851.68298 +4290 4166 -21679861.11823 +4291 4166 -17343750.0057 +4292 4166 -36432062.04358 +4293 4166 -86719444.43019 +4294 4166 -2.682209014893e-07 +4295 4166 -99061955.12461 +4296 4166 -21679861.11823 +4297 4166 17343750.00569 +4298 4166 -36432062.04358 +4167 4167 839023631.6674 +4168 4167 87343789.54536 +4169 4167 -1.788139343262e-05 +4182 4167 -118480247.2419 +4183 4167 -81018055.54225 +4184 4167 -3.695487976074e-06 +4185 4167 -474827934.8941 +4186 4167 -87343788.8972 +4187 4167 -1.013278961182e-05 +4188 4167 27033058.92538 +4189 4167 64814443.78564 +4190 4167 -1.192092895508e-07 +4260 4167 -9282077.50499 +4261 4167 29166666.38457 +4262 4167 26015832.78049 +4275 4167 -28139091.37673 +4276 4167 -24305555.27187 +4277 4167 -21679860.55685 +4278 4167 142149470.4916 +4279 4167 26203286.60958 +4280 4167 17682222.18138 +4293 4167 -46373434.23611 +4294 4167 -24305555.56353 +4295 4167 -21679861.11823 +4296 4167 -180984988.3575 +4297 4167 -26203286.41513 +4298 4167 -88411110.90688 +4299 4167 -8767515.558548 +4300 4167 19444444.25638 +4301 4167 -18020555.17262 +4168 4168 709779954.7303 +4169 4168 -3.48687171936e-06 +4182 4168 -81018055.54225 +4183 4168 -94173943.88989 +4184 4168 -1.9371509552e-07 +4185 4168 -87343788.57312 +4186 4168 -91199082.2484 +4188 4168 97221665.67847 +4189 4168 31903583.53394 +4190 4168 -7.152557373047e-07 +4260 4168 19444444.25638 +4261 4168 -9282077.505 +4262 4168 -13874999.9393 +4275 4168 -24305555.36909 +4276 4168 -113208178.6284 +4277 4168 -69374999.49133 +4278 4168 26203286.60958 +4279 4168 103376145.8295 +4280 4168 14145833.18358 +4293 4168 -24305555.56353 +4294 4168 -39081501.55875 +4295 4168 -17343750.0057 +4296 4168 -26203286.31791 +4297 4168 -65895674.85385 +4298 4168 -18697916.56855 +4299 4168 29166666.38457 +4300 4168 -7306349.825743 +4301 4168 20270833.25379 +4169 4169 754398934.9387 +4182 4169 -3.576278686523e-06 +4183 4169 -1.341104507446e-07 +4184 4169 -25180890.14438 +4185 4169 -9.834766387939e-06 +4186 4169 -1.788139343262e-07 +4187 4169 -37595585.9186 +4188 4169 -1.311302185059e-06 +4189 4169 -4.172325134277e-07 +4190 4169 67217632.52583 +4260 4169 17343888.52033 +4261 4169 -20812499.90895 +4262 4169 -24752206.67999 +4275 4169 -21679860.74398 +4276 4169 -69374999.6084 +4277 4169 -84490851.68299 +4278 4169 -17682222.18137 +4279 4169 -14145833.18359 +4280 4169 -65836512.72296 +4293 4169 -21679861.11823 +4294 4169 -17343750.0057 +4295 4169 -36432062.04358 +4296 4169 -88411110.90688 +4297 4169 -18697916.60118 +4298 4169 -114040857.0942 +4299 4169 -27030832.75893 +4300 4169 13062499.95656 +4301 4169 -24841207.22226 +4170 4170 1319128267.022 +4171 4170 9.775161743164e-06 +4172 4170 -5.745887756348e-05 +4173 4170 174228645.9499 +4174 4170 -4.291534423828e-06 +4175 4170 -1.45435333252e-05 +4191 4170 -318367567.7659 +4192 4170 -2.443790435791e-06 +4193 4170 -1.460313796997e-05 +4194 4170 -118480247.2419 +4195 4170 81018055.54225 +4196 4170 -3.516674041748e-06 +4263 4170 -138827443.8752 +4264 4170 2.682209014893e-07 +4265 4170 86719444.4302 +4266 4170 -46373434.23614 +4267 4170 -24305555.56354 +4268 4170 21679861.11823 +4281 4170 222474230.8735 +4282 4170 3.933906555176e-06 +4283 4170 2.622604370117e-05 +4284 4170 8952264.76783 +4285 4170 -1.302361488342e-05 +4286 4170 6.914138793945e-06 +4302 4170 -138827443.8751 +4303 4170 -5.066394805908e-07 +4304 4170 -86719444.43019 +4305 4170 -46373434.23611 +4306 4170 24305555.56353 +4307 4170 -21679861.11823 +4171 4171 1124677840.302 +4172 4171 -3.814697265625e-06 +4173 4171 -4.947185516357e-06 +4174 4171 -133639662.3675 +4175 4171 -8.046627044678e-07 +4191 4171 -1.072883605957e-06 +4192 4171 38113347.20754 +4193 4171 -1.192092895508e-06 +4194 4171 81018055.54225 +4195 4171 -94173943.88989 +4196 4171 -2.682209014893e-07 +4263 4171 -2.294778823853e-06 +4264 4171 -31882558.21685 +4265 4171 2.682209014893e-07 +4266 4171 -24305555.56354 +4267 4171 -39081501.55876 +4268 4171 17343750.0057 +4281 4171 4.410743713379e-06 +4282 4171 164138769.4832 +4283 4171 -1.192092895508e-07 +4284 4171 -1.156330108643e-05 +4285 4171 -83408755.55014 +4286 4171 69374999.9886 +4302 4171 -8.344650268555e-07 +4303 4171 -31882558.21681 +4304 4171 -3.278255462646e-07 +4305 4171 24305555.56353 +4306 4171 -39081501.55875 +4307 4171 17343750.00569 +4172 4172 1191543893.2 +4173 4172 -1.45435333252e-05 +4174 4172 -1.192092895508e-06 +4175 4172 142332552.4786 +4191 4172 -1.388788223267e-05 +4192 4172 -1.072883605957e-06 +4193 4172 54829860.44019 +4194 4172 -3.36766242981e-06 +4195 4172 -3.576278686523e-07 +4196 4172 -25180890.14437 +4263 4172 86719444.4302 +4264 4172 3.427267074585e-07 +4265 4172 -99061955.12464 +4266 4172 21679861.11823 +4267 4172 17343750.0057 +4268 4172 -36432062.04359 +4281 4172 2.598762512207e-05 +4282 4172 5.960464477539e-08 +4283 4172 -104578818.0156 +4284 4172 6.973743438721e-06 +4285 4172 69374999.9886 +4286 4172 -72810997.49471 +4302 4172 -86719444.43019 +4303 4172 -2.682209014893e-07 +4304 4172 -99061955.12461 +4305 4172 -21679861.11823 +4306 4172 17343750.00569 +4307 4172 -36432062.04358 +4173 4173 1319128267.022 +4174 4173 9.775161743164e-06 +4175 4173 -5.745887756348e-05 +4176 4173 174228645.9499 +4177 4173 -4.291534423828e-06 +4178 4173 -1.45435333252e-05 +4191 4173 -118480247.2419 +4192 4173 -81018055.54225 +4193 4173 -3.695487976074e-06 +4194 4173 -318367567.7659 +4195 4173 -2.443790435791e-06 +4196 4173 -1.460313796997e-05 +4197 4173 -118480247.2419 +4198 4173 81018055.54225 +4199 4173 -3.516674041748e-06 +4263 4173 -46373434.23613 +4264 4173 24305555.56354 +4265 4173 21679861.11823 +4266 4173 -138827443.8752 +4267 4173 2.682209014893e-07 +4268 4173 86719444.4302 +4269 4173 -46373434.23614 +4270 4173 -24305555.56354 +4271 4173 21679861.11823 +4281 4173 8952264.76783 +4282 4173 9.298324584961e-06 +4283 4173 6.228685379028e-06 +4284 4173 222474230.8735 +4285 4173 3.933906555176e-06 +4286 4173 2.622604370117e-05 +4287 4173 8952264.76783 +4288 4173 -1.302361488342e-05 +4289 4173 6.914138793945e-06 +4302 4173 -46373434.23611 +4303 4173 -24305555.56353 +4304 4173 -21679861.11823 +4305 4173 -138827443.8751 +4306 4173 -5.066394805908e-07 +4307 4173 -86719444.43019 +4308 4173 -46373434.23611 +4309 4173 24305555.56353 +4310 4173 -21679861.11823 +4174 4174 1124677840.302 +4175 4174 -3.814697265625e-06 +4176 4174 -4.947185516357e-06 +4177 4174 -133639662.3675 +4178 4174 -8.046627044678e-07 +4191 4174 -81018055.54225 +4192 4174 -94173943.88989 +4193 4174 -1.9371509552e-07 +4194 4174 -1.072883605957e-06 +4195 4174 38113347.20754 +4196 4174 -1.192092895508e-06 +4197 4174 81018055.54225 +4198 4174 -94173943.88989 +4199 4174 -2.682209014893e-07 +4263 4174 24305555.56354 +4264 4174 -39081501.55876 +4265 4174 -17343750.00569 +4266 4174 -2.294778823853e-06 +4267 4174 -31882558.21685 +4268 4174 2.682209014893e-07 +4269 4174 -24305555.56354 +4270 4174 -39081501.55876 +4271 4174 17343750.0057 +4281 4174 1.069903373718e-05 +4282 4174 -83408755.55014 +4283 4174 -69374999.9886 +4284 4174 4.410743713379e-06 +4285 4174 164138769.4832 +4286 4174 -1.192092895508e-07 +4287 4174 -1.156330108643e-05 +4288 4174 -83408755.55014 +4289 4174 69374999.9886 +4302 4174 -24305555.56353 +4303 4174 -39081501.55875 +4304 4174 -17343750.0057 +4305 4174 -8.344650268555e-07 +4306 4174 -31882558.21681 +4307 4174 -3.278255462646e-07 +4308 4174 24305555.56353 +4309 4174 -39081501.55875 +4310 4174 17343750.00569 +4175 4175 1191543893.2 +4176 4175 -1.45435333252e-05 +4177 4175 -1.192092895508e-06 +4178 4175 142332552.4786 +4191 4175 -3.576278686523e-06 +4192 4175 -1.341104507446e-07 +4193 4175 -25180890.14438 +4194 4175 -1.388788223267e-05 +4195 4175 -1.072883605957e-06 +4196 4175 54829860.44019 +4197 4175 -3.36766242981e-06 +4198 4175 -3.576278686523e-07 +4199 4175 -25180890.14437 +4263 4175 21679861.11823 +4264 4175 -17343750.0057 +4265 4175 -36432062.04359 +4266 4175 86719444.4302 +4267 4175 3.427267074585e-07 +4268 4175 -99061955.12464 +4269 4175 21679861.11823 +4270 4175 17343750.0057 +4271 4175 -36432062.04359 +4281 4175 6.169080734253e-06 +4282 4175 -69374999.9886 +4283 4175 -72810997.49471 +4284 4175 2.598762512207e-05 +4285 4175 5.960464477539e-08 +4286 4175 -104578818.0156 +4287 4175 6.973743438721e-06 +4288 4175 69374999.9886 +4289 4175 -72810997.49471 +4302 4175 -21679861.11823 +4303 4175 -17343750.0057 +4304 4175 -36432062.04358 +4305 4175 -86719444.43019 +4306 4175 -2.682209014893e-07 +4307 4175 -99061955.12461 +4308 4175 -21679861.11823 +4309 4175 17343750.00569 +4310 4175 -36432062.04358 +4176 4176 1319128267.022 +4177 4176 9.775161743164e-06 +4178 4176 -5.745887756348e-05 +4179 4176 174228645.9499 +4180 4176 -4.291534423828e-06 +4181 4176 -1.45435333252e-05 +4194 4176 -118480247.2419 +4195 4176 -81018055.54225 +4196 4176 -3.695487976074e-06 +4197 4176 -318367567.7659 +4198 4176 -2.443790435791e-06 +4199 4176 -1.460313796997e-05 +4200 4176 -118480247.2419 +4201 4176 81018055.54225 +4202 4176 -3.516674041748e-06 +4266 4176 -46373434.23613 +4267 4176 24305555.56354 +4268 4176 21679861.11823 +4269 4176 -138827443.8752 +4270 4176 2.682209014893e-07 +4271 4176 86719444.4302 +4272 4176 -46373434.23614 +4273 4176 -24305555.56354 +4274 4176 21679861.11823 +4284 4176 8952264.76783 +4285 4176 9.298324584961e-06 +4286 4176 6.228685379028e-06 +4287 4176 222474230.8735 +4288 4176 3.933906555176e-06 +4289 4176 2.622604370117e-05 +4290 4176 8952264.76783 +4291 4176 -1.302361488342e-05 +4292 4176 6.914138793945e-06 +4305 4176 -46373434.23611 +4306 4176 -24305555.56353 +4307 4176 -21679861.11823 +4308 4176 -138827443.8751 +4309 4176 -5.066394805908e-07 +4310 4176 -86719444.43019 +4311 4176 -46373434.23611 +4312 4176 24305555.56353 +4313 4176 -21679861.11823 +4177 4177 1124677840.302 +4178 4177 -3.814697265625e-06 +4179 4177 -4.947185516357e-06 +4180 4177 -133639662.3675 +4181 4177 -8.046627044678e-07 +4194 4177 -81018055.54225 +4195 4177 -94173943.88989 +4196 4177 -1.9371509552e-07 +4197 4177 -1.072883605957e-06 +4198 4177 38113347.20754 +4199 4177 -1.192092895508e-06 +4200 4177 81018055.54225 +4201 4177 -94173943.88989 +4202 4177 -2.682209014893e-07 +4266 4177 24305555.56354 +4267 4177 -39081501.55876 +4268 4177 -17343750.00569 +4269 4177 -2.294778823853e-06 +4270 4177 -31882558.21685 +4271 4177 2.682209014893e-07 +4272 4177 -24305555.56354 +4273 4177 -39081501.55876 +4274 4177 17343750.0057 +4284 4177 1.069903373718e-05 +4285 4177 -83408755.55014 +4286 4177 -69374999.9886 +4287 4177 4.410743713379e-06 +4288 4177 164138769.4832 +4289 4177 -1.192092895508e-07 +4290 4177 -1.156330108643e-05 +4291 4177 -83408755.55014 +4292 4177 69374999.9886 +4305 4177 -24305555.56353 +4306 4177 -39081501.55875 +4307 4177 -17343750.0057 +4308 4177 -8.344650268555e-07 +4309 4177 -31882558.21681 +4310 4177 -3.278255462646e-07 +4311 4177 24305555.56353 +4312 4177 -39081501.55875 +4313 4177 17343750.00569 +4178 4178 1191543893.2 +4179 4178 -1.45435333252e-05 +4180 4178 -1.192092895508e-06 +4181 4178 142332552.4786 +4194 4178 -3.576278686523e-06 +4195 4178 -1.341104507446e-07 +4196 4178 -25180890.14438 +4197 4178 -1.388788223267e-05 +4198 4178 -1.072883605957e-06 +4199 4178 54829860.44019 +4200 4178 -3.36766242981e-06 +4201 4178 -3.576278686523e-07 +4202 4178 -25180890.14437 +4266 4178 21679861.11823 +4267 4178 -17343750.0057 +4268 4178 -36432062.04359 +4269 4178 86719444.4302 +4270 4178 3.427267074585e-07 +4271 4178 -99061955.12464 +4272 4178 21679861.11823 +4273 4178 17343750.0057 +4274 4178 -36432062.04359 +4284 4178 6.169080734253e-06 +4285 4178 -69374999.9886 +4286 4178 -72810997.49471 +4287 4178 2.598762512207e-05 +4288 4178 5.960464477539e-08 +4289 4178 -104578818.0156 +4290 4178 6.973743438721e-06 +4291 4178 69374999.9886 +4292 4178 -72810997.49471 +4305 4178 -21679861.11823 +4306 4178 -17343750.0057 +4307 4178 -36432062.04358 +4308 4178 -86719444.43019 +4309 4178 -2.682209014893e-07 +4310 4178 -99061955.12461 +4311 4178 -21679861.11823 +4312 4178 17343750.00569 +4313 4178 -36432062.04358 +4179 4179 1319128267.022 +4180 4179 9.775161743164e-06 +4181 4179 -5.745887756348e-05 +4182 4179 174228645.9499 +4183 4179 -4.291534423828e-06 +4184 4179 -1.45435333252e-05 +4197 4179 -118480247.2419 +4198 4179 -81018055.54225 +4199 4179 -3.695487976074e-06 +4200 4179 -318367567.7659 +4201 4179 -2.443790435791e-06 +4202 4179 -1.460313796997e-05 +4203 4179 -118480247.2419 +4204 4179 81018055.54225 +4205 4179 -3.516674041748e-06 +4269 4179 -46373434.23613 +4270 4179 24305555.56354 +4271 4179 21679861.11823 +4272 4179 -138827443.8752 +4273 4179 2.682209014893e-07 +4274 4179 86719444.4302 +4275 4179 -46373434.23614 +4276 4179 -24305555.56354 +4277 4179 21679861.11823 +4287 4179 8952264.76783 +4288 4179 9.298324584961e-06 +4289 4179 6.228685379028e-06 +4290 4179 222474230.8735 +4291 4179 3.933906555176e-06 +4292 4179 2.622604370117e-05 +4293 4179 8952264.76783 +4294 4179 -1.302361488342e-05 +4295 4179 6.914138793945e-06 +4308 4179 -46373434.23611 +4309 4179 -24305555.56353 +4310 4179 -21679861.11823 +4311 4179 -138827443.8751 +4312 4179 -5.066394805908e-07 +4313 4179 -86719444.43019 +4314 4179 -46373434.23611 +4315 4179 24305555.56353 +4316 4179 -21679861.11823 +4180 4180 1124677840.302 +4181 4180 -3.814697265625e-06 +4182 4180 -4.947185516357e-06 +4183 4180 -133639662.3675 +4184 4180 -8.046627044678e-07 +4197 4180 -81018055.54225 +4198 4180 -94173943.88989 +4199 4180 -1.9371509552e-07 +4200 4180 -1.072883605957e-06 +4201 4180 38113347.20754 +4202 4180 -1.192092895508e-06 +4203 4180 81018055.54225 +4204 4180 -94173943.88989 +4205 4180 -2.682209014893e-07 +4269 4180 24305555.56354 +4270 4180 -39081501.55876 +4271 4180 -17343750.00569 +4272 4180 -2.294778823853e-06 +4273 4180 -31882558.21685 +4274 4180 2.682209014893e-07 +4275 4180 -24305555.56354 +4276 4180 -39081501.55876 +4277 4180 17343750.0057 +4287 4180 1.069903373718e-05 +4288 4180 -83408755.55014 +4289 4180 -69374999.9886 +4290 4180 4.410743713379e-06 +4291 4180 164138769.4832 +4292 4180 -1.192092895508e-07 +4293 4180 -1.156330108643e-05 +4294 4180 -83408755.55014 +4295 4180 69374999.9886 +4308 4180 -24305555.56353 +4309 4180 -39081501.55875 +4310 4180 -17343750.0057 +4311 4180 -8.344650268555e-07 +4312 4180 -31882558.21681 +4313 4180 -3.278255462646e-07 +4314 4180 24305555.56353 +4315 4180 -39081501.55875 +4316 4180 17343750.00569 +4181 4181 1191543893.2 +4182 4181 -1.45435333252e-05 +4183 4181 -1.192092895508e-06 +4184 4181 142332552.4786 +4197 4181 -3.576278686523e-06 +4198 4181 -1.341104507446e-07 +4199 4181 -25180890.14438 +4200 4181 -1.388788223267e-05 +4201 4181 -1.072883605957e-06 +4202 4181 54829860.44019 +4203 4181 -3.36766242981e-06 +4204 4181 -3.576278686523e-07 +4205 4181 -25180890.14437 +4269 4181 21679861.11823 +4270 4181 -17343750.0057 +4271 4181 -36432062.04359 +4272 4181 86719444.4302 +4273 4181 3.427267074585e-07 +4274 4181 -99061955.12464 +4275 4181 21679861.11823 +4276 4181 17343750.0057 +4277 4181 -36432062.04359 +4287 4181 6.169080734253e-06 +4288 4181 -69374999.9886 +4289 4181 -72810997.49471 +4290 4181 2.598762512207e-05 +4291 4181 5.960464477539e-08 +4292 4181 -104578818.0156 +4293 4181 6.973743438721e-06 +4294 4181 69374999.9886 +4295 4181 -72810997.49471 +4308 4181 -21679861.11823 +4309 4181 -17343750.0057 +4310 4181 -36432062.04358 +4311 4181 -86719444.43019 +4312 4181 -2.682209014893e-07 +4313 4181 -99061955.12461 +4314 4181 -21679861.11823 +4315 4181 17343750.00569 +4316 4181 -36432062.04358 +4182 4182 1319128267.022 +4183 4182 9.775161743164e-06 +4184 4182 -5.745887756348e-05 +4185 4182 174228645.9499 +4186 4182 -4.291534423828e-06 +4187 4182 -1.45435333252e-05 +4200 4182 -118480247.2419 +4201 4182 -81018055.54225 +4202 4182 -3.695487976074e-06 +4203 4182 -318367567.7659 +4204 4182 -2.443790435791e-06 +4205 4182 -1.460313796997e-05 +4206 4182 -118480247.2419 +4207 4182 81018055.54225 +4208 4182 -3.516674041748e-06 +4272 4182 -46373434.23613 +4273 4182 24305555.56354 +4274 4182 21679861.11823 +4275 4182 -138827443.8752 +4276 4182 2.682209014893e-07 +4277 4182 86719444.4302 +4278 4182 -46373434.23614 +4279 4182 -24305555.56354 +4280 4182 21679861.11823 +4290 4182 8952264.76783 +4291 4182 9.298324584961e-06 +4292 4182 6.228685379028e-06 +4293 4182 222474230.8735 +4294 4182 3.933906555176e-06 +4295 4182 2.622604370117e-05 +4296 4182 8952264.76783 +4297 4182 -1.302361488342e-05 +4298 4182 6.914138793945e-06 +4311 4182 -46373434.23611 +4312 4182 -24305555.56353 +4313 4182 -21679861.11823 +4314 4182 -138827443.8751 +4315 4182 -5.066394805908e-07 +4316 4182 -86719444.43019 +4317 4182 -46373434.23611 +4318 4182 24305555.56353 +4319 4182 -21679861.11823 +4183 4183 1124677840.302 +4184 4183 -3.814697265625e-06 +4185 4183 -4.947185516357e-06 +4186 4183 -133639662.3675 +4187 4183 -8.046627044678e-07 +4200 4183 -81018055.54225 +4201 4183 -94173943.88989 +4202 4183 -1.9371509552e-07 +4203 4183 -1.072883605957e-06 +4204 4183 38113347.20754 +4205 4183 -1.192092895508e-06 +4206 4183 81018055.54225 +4207 4183 -94173943.88989 +4208 4183 -2.682209014893e-07 +4272 4183 24305555.56354 +4273 4183 -39081501.55876 +4274 4183 -17343750.00569 +4275 4183 -2.294778823853e-06 +4276 4183 -31882558.21685 +4277 4183 2.682209014893e-07 +4278 4183 -24305555.56354 +4279 4183 -39081501.55876 +4280 4183 17343750.0057 +4290 4183 1.069903373718e-05 +4291 4183 -83408755.55014 +4292 4183 -69374999.9886 +4293 4183 4.410743713379e-06 +4294 4183 164138769.4832 +4295 4183 -1.192092895508e-07 +4296 4183 -1.156330108643e-05 +4297 4183 -83408755.55014 +4298 4183 69374999.9886 +4311 4183 -24305555.56353 +4312 4183 -39081501.55875 +4313 4183 -17343750.0057 +4314 4183 -8.344650268555e-07 +4315 4183 -31882558.21681 +4316 4183 -3.278255462646e-07 +4317 4183 24305555.56353 +4318 4183 -39081501.55875 +4319 4183 17343750.00569 +4184 4184 1191543893.2 +4185 4184 -1.45435333252e-05 +4186 4184 -1.192092895508e-06 +4187 4184 142332552.4786 +4200 4184 -3.576278686523e-06 +4201 4184 -1.341104507446e-07 +4202 4184 -25180890.14438 +4203 4184 -1.388788223267e-05 +4204 4184 -1.072883605957e-06 +4205 4184 54829860.44019 +4206 4184 -3.36766242981e-06 +4207 4184 -3.576278686523e-07 +4208 4184 -25180890.14437 +4272 4184 21679861.11823 +4273 4184 -17343750.0057 +4274 4184 -36432062.04359 +4275 4184 86719444.4302 +4276 4184 3.427267074585e-07 +4277 4184 -99061955.12464 +4278 4184 21679861.11823 +4279 4184 17343750.0057 +4280 4184 -36432062.04359 +4290 4184 6.169080734253e-06 +4291 4184 -69374999.9886 +4292 4184 -72810997.49471 +4293 4184 2.598762512207e-05 +4294 4184 5.960464477539e-08 +4295 4184 -104578818.0156 +4296 4184 6.973743438721e-06 +4297 4184 69374999.9886 +4298 4184 -72810997.49471 +4311 4184 -21679861.11823 +4312 4184 -17343750.0057 +4313 4184 -36432062.04358 +4314 4184 -86719444.43019 +4315 4184 -2.682209014893e-07 +4316 4184 -99061955.12461 +4317 4184 -21679861.11823 +4318 4184 17343750.00569 +4319 4184 -36432062.04358 +4185 4185 1462641058.094 +4186 4185 87479495.38205 +4187 4185 -4.52995300293e-05 +4188 4185 42596143.66857 +4189 4185 -77867916.96021 +4190 4185 1.072883605957e-06 +4203 4185 -118480247.2419 +4204 4185 -81018055.54225 +4205 4185 -3.695487976074e-06 +4206 4185 -324895063.8002 +4207 4185 -3176292.746493 +4208 4185 -9.357929229736e-06 +4209 4185 -126834155.7336 +4210 4185 80908502.89777 +4211 4185 7.748603820801e-07 +4275 4185 -46373434.23613 +4276 4185 24305555.56354 +4277 4185 21679861.11823 +4278 4185 -180984988.3575 +4279 4185 -26203286.31791 +4280 4185 88411110.90689 +4293 4185 8952264.76783 +4294 4185 9.298324584961e-06 +4295 4185 6.228685379028e-06 +4296 4185 274245586.3934 +4297 4185 26243998.59326 +4298 4185 0.03795540332794 +4299 4185 -25967702.04295 +4300 4185 -23360508.58819 +4301 4185 21679166.28526 +4314 4185 -46373434.23611 +4315 4185 -24305555.56353 +4316 4185 -21679861.11823 +4317 4185 -140996480.1669 +4318 4185 -952893.2695215 +4319 4185 -87564583.31886 +4320 4185 -48879322.66663 +4321 4185 24272689.58237 +4322 4185 -22525694.45184 +4186 4186 1226949792.75 +4187 4186 1.54972076416e-06 +4188 4186 -77867916.63614 +4189 4186 -240777220.5996 +4190 4186 8.642673492432e-07 +4203 4186 -81018055.54225 +4204 4186 -94173943.88989 +4205 4186 -1.9371509552e-07 +4206 4186 -3176292.746491 +4207 4186 34621896.54898 +4208 4186 2.384185791016e-06 +4209 4186 80908502.89777 +4210 4186 -91659637.50231 +4211 4186 4.619359970093e-07 +4275 4186 24305555.56354 +4276 4186 -39081501.55876 +4277 4186 -17343750.00569 +4278 4186 -26203286.41513 +4279 4186 -65895674.85387 +4280 4186 18697916.60118 +4293 4186 1.069903373718e-05 +4294 4186 -83408755.55014 +4295 4186 -69374999.9886 +4296 4186 26243998.59325 +4297 4186 203537802.7107 +4298 4186 0.03034836053848 +4299 4186 -23360508.49097 +4300 4186 -110980197.151 +4301 4186 69374999.59698 +4314 4186 -24305555.56353 +4315 4186 -39081501.55875 +4316 4186 -17343750.0057 +4317 4186 -952893.2695235 +4318 4186 -33140775.69073 +4319 4186 -677083.3331564 +4320 4186 24272689.58237 +4321 4186 -38326906.89252 +4322 4186 16666666.67214 +4187 4187 1232160055.067 +4188 4187 1.311302185059e-06 +4189 4187 8.046627044678e-07 +4190 4187 63364897.36566 +4203 4187 -3.576278686523e-06 +4204 4187 -1.341104507446e-07 +4205 4187 -25180890.14438 +4206 4187 -9.536743164063e-06 +4207 4187 2.503395080566e-06 +4208 4187 52736138.02881 +4209 4187 5.662441253662e-07 +4210 4187 4.91738319397e-07 +4211 4187 -26774413.26387 +4275 4187 21679861.11823 +4276 4187 -17343750.0057 +4277 4187 -36432062.04359 +4278 4187 88411110.90689 +4279 4187 18697916.56855 +4280 4187 -114040857.0943 +4293 4187 6.169080734253e-06 +4294 4187 -69374999.9886 +4295 4187 -72810997.49471 +4296 4187 -0.03792554140091 +4297 4187 -0.03035613894463 +4298 4187 -69147840.74464 +4299 4187 21679166.091 +4300 4187 69374999.4742 +4301 4187 -84314737.28063 +4314 4187 -21679861.11823 +4315 4187 -17343750.0057 +4316 4187 -36432062.04358 +4317 4187 -87564583.31903 +4318 4187 -677083.3332899 +4319 4187 -100252145.5455 +4320 4187 -22525694.45184 +4321 4187 16666666.67214 +4322 4187 -36909325.87324 +4188 4188 787388547.2823 +4189 4188 -2214583.809871 +4190 4188 1.430511474609e-06 +4206 4188 -116805592.7516 +4207 4188 -81004084.40933 +4208 4188 -1.579523086548e-06 +4209 4188 -332162222.5414 +4210 4188 -4280016.395824 +4211 4188 -2.384185791016e-07 +4212 4188 80715855.11751 +4213 4188 -13975781.07962 +4214 4188 -1.311302185059e-06 +4215 4188 -125994423.3344 +4216 4188 82120716.65231 +4217 4188 2.652406692505e-06 +4278 4188 -8767515.558547 +4279 4188 29166666.38457 +4280 4188 27030832.75893 +4296 4188 -25967702.04295 +4297 4188 -23360508.49097 +4298 4188 -21679166.091 +4299 4188 119740849.7094 +4300 4188 -664378.9397402 +4301 4188 17135277.77496 +4317 4188 -45870736.57861 +4318 4188 -24301364.19971 +4319 4188 -21679166.67379 +4320 4188 -141002035.2671 +4321 4188 -1284012.256595 +4322 4188 -85676388.87482 +4323 4188 4511607.61049 +4324 4188 -4192758.28457 +4325 4188 3215972.223778 +4326 4188 -47751770.62455 +4327 4188 24636355.787 +4328 4188 -21159027.78473 +4189 4189 809133076.5767 +4190 4189 9.655952453613e-06 +4206 4189 -81004084.40933 +4207 4189 -94677982.04967 +4208 4189 4.91738319397e-07 +4209 4189 -4280016.395824 +4210 4189 28012191.60674 +4211 4189 6.07967376709e-06 +4212 4189 18431441.13728 +4213 4189 -72760112.34643 +4214 4189 -2.413988113403e-06 +4215 4189 82120716.65231 +4216 4189 -98062170.35532 +4217 4189 -1.490116119385e-07 +4278 4189 19444444.25638 +4279 4189 -7306349.825742 +4280 4189 -13062499.95656 +4296 4189 -23360508.58819 +4297 4189 -110980197.151 +4298 4189 -69374999.4742 +4299 4189 -664378.9397414 +4300 4189 126264245.7775 +4301 4189 7208333.185862 +4317 4189 -24301364.19971 +4318 4189 -39232415.43151 +4319 4189 -17343750.0057 +4320 4189 -1284012.256596 +4321 4189 -32949093.52409 +4322 4189 -677083.3331572 +4323 4189 5529463.940844 +4324 4189 -41531445.75453 +4325 4189 33333333.32786 +4326 4189 24636355.787 +4327 4189 -39372046.84255 +4328 4189 16666666.67214 +4190 4190 788376653.8888 +4206 4190 -1.698732376099e-06 +4207 4190 4.91738319397e-07 +4208 4190 -24862535.50895 +4209 4190 -2.384185791016e-07 +4210 4190 6.258487701416e-06 +4211 4190 42361810.64111 +4212 4190 -2.384185791016e-07 +4213 4190 -2.443790435791e-06 +4214 4190 61876825.47302 +4215 4190 2.205371856689e-06 +4216 4190 -1.192092895508e-07 +4217 4190 -30944974.07514 +4278 4190 18020555.17262 +4279 4190 -20270833.25379 +4280 4190 -24841207.22225 +4296 4190 -21679166.28526 +4297 4190 -69374999.59698 +4298 4190 -84314737.28062 +4299 4190 -17135277.77496 +4300 4190 -7208333.18587 +4301 4190 -74091157.2951 +4317 4190 -21679166.67379 +4318 4190 -17343750.0057 +4319 4190 -36335759.26896 +4320 4190 -85676388.87482 +4321 4190 -677083.3332907 +4322 4190 -97565514.93122 +4323 4190 -4909027.779057 +4324 4190 33333333.32786 +4325 4190 -33978945.7605 +4326 4190 -21159027.78473 +4327 4190 16666666.67214 +4328 4190 -35825485.57976 +4191 4191 659564133.511 +4192 4191 1.192092895508e-06 +4193 4191 -3.0517578125e-05 +4194 4191 87114322.97494 +4195 4191 16203611.10845 +4196 4191 -7.62939453125e-06 +4281 4191 -138827443.8752 +4282 4191 2.682209014893e-07 +4283 4191 86719444.4302 +4284 4191 -46373434.23614 +4285 4191 -24305555.56354 +4286 4191 21679861.11823 +4302 4191 111237115.4367 +4303 4191 -8.344650268555e-07 +4304 4191 -17343888.88603 +4305 4191 4476132.383917 +4306 4191 4861111.1127 +4307 4191 -4335972.223642 +4192 4192 562338920.1509 +4193 4192 8.344650268555e-06 +4194 4192 -16203611.10845 +4195 4192 -66819831.18376 +4196 4192 2.235174179077e-06 +4281 4192 -2.294778823853e-06 +4282 4192 -31882558.21685 +4283 4192 2.682209014893e-07 +4284 4192 -24305555.56354 +4285 4192 -39081501.55876 +4286 4192 17343750.0057 +4302 4192 -7.152557373047e-07 +4303 4192 82069384.74161 +4304 4192 -3.75509262085e-06 +4305 4192 -4861111.112713 +4306 4192 -41704377.77507 +4307 4192 34687499.9943 +4193 4193 595771946.5998 +4194 4193 -7.62939453125e-06 +4195 4193 2.026557922363e-06 +4196 4193 71166276.23929 +4281 4193 86719444.4302 +4282 4193 3.427267074585e-07 +4283 4193 -99061955.12464 +4284 4193 21679861.11823 +4285 4193 17343750.0057 +4286 4193 -36432062.04359 +4302 4193 17343888.88605 +4303 4193 -3.576278686523e-06 +4304 4193 -52289409.00778 +4305 4193 4335972.22365 +4306 4193 34687499.9943 +4307 4193 -36405498.74735 +4194 4194 659564133.511 +4195 4194 1.192092895508e-06 +4196 4194 -3.0517578125e-05 +4197 4194 87114322.97494 +4198 4194 16203611.10845 +4199 4194 -7.62939453125e-06 +4281 4194 -46373434.23613 +4282 4194 24305555.56354 +4283 4194 21679861.11823 +4284 4194 -138827443.8752 +4285 4194 2.682209014893e-07 +4286 4194 86719444.4302 +4287 4194 -46373434.23614 +4288 4194 -24305555.56354 +4289 4194 21679861.11823 +4302 4194 4476132.383914 +4303 4194 -4861111.112702 +4304 4194 -4335972.223643 +4305 4194 111237115.4367 +4306 4194 -8.344650268555e-07 +4307 4194 -17343888.88603 +4308 4194 4476132.383917 +4309 4194 4861111.1127 +4310 4194 -4335972.223642 +4195 4195 562338920.1509 +4196 4195 8.344650268555e-06 +4197 4195 -16203611.10845 +4198 4195 -66819831.18376 +4199 4195 2.235174179077e-06 +4281 4195 24305555.56354 +4282 4195 -39081501.55876 +4283 4195 -17343750.00569 +4284 4195 -2.294778823853e-06 +4285 4195 -31882558.21685 +4286 4195 2.682209014893e-07 +4287 4195 -24305555.56354 +4288 4195 -39081501.55876 +4289 4195 17343750.0057 +4302 4195 4861111.112712 +4303 4195 -41704377.77507 +4304 4195 -34687499.9943 +4305 4195 -7.152557373047e-07 +4306 4195 82069384.74161 +4307 4195 -3.75509262085e-06 +4308 4195 -4861111.112713 +4309 4195 -41704377.77507 +4310 4195 34687499.9943 +4196 4196 595771946.5998 +4197 4196 -7.62939453125e-06 +4198 4196 2.026557922363e-06 +4199 4196 71166276.23929 +4281 4196 21679861.11823 +4282 4196 -17343750.0057 +4283 4196 -36432062.04359 +4284 4196 86719444.4302 +4285 4196 3.427267074585e-07 +4286 4196 -99061955.12464 +4287 4196 21679861.11823 +4288 4196 17343750.0057 +4289 4196 -36432062.04359 +4302 4196 4335972.223649 +4303 4196 -34687499.9943 +4304 4196 -36405498.74736 +4305 4196 17343888.88605 +4306 4196 -3.576278686523e-06 +4307 4196 -52289409.00778 +4308 4196 4335972.22365 +4309 4196 34687499.9943 +4310 4196 -36405498.74735 +4197 4197 659564133.511 +4198 4197 1.192092895508e-06 +4199 4197 -3.0517578125e-05 +4200 4197 87114322.97494 +4201 4197 16203611.10845 +4202 4197 -7.62939453125e-06 +4284 4197 -46373434.23613 +4285 4197 24305555.56354 +4286 4197 21679861.11823 +4287 4197 -138827443.8752 +4288 4197 2.682209014893e-07 +4289 4197 86719444.4302 +4290 4197 -46373434.23614 +4291 4197 -24305555.56354 +4292 4197 21679861.11823 +4305 4197 4476132.383914 +4306 4197 -4861111.112702 +4307 4197 -4335972.223643 +4308 4197 111237115.4367 +4309 4197 -8.344650268555e-07 +4310 4197 -17343888.88603 +4311 4197 4476132.383917 +4312 4197 4861111.1127 +4313 4197 -4335972.223642 +4198 4198 562338920.1509 +4199 4198 8.344650268555e-06 +4200 4198 -16203611.10845 +4201 4198 -66819831.18376 +4202 4198 2.235174179077e-06 +4284 4198 24305555.56354 +4285 4198 -39081501.55876 +4286 4198 -17343750.00569 +4287 4198 -2.294778823853e-06 +4288 4198 -31882558.21685 +4289 4198 2.682209014893e-07 +4290 4198 -24305555.56354 +4291 4198 -39081501.55876 +4292 4198 17343750.0057 +4305 4198 4861111.112712 +4306 4198 -41704377.77507 +4307 4198 -34687499.9943 +4308 4198 -7.152557373047e-07 +4309 4198 82069384.74161 +4310 4198 -3.75509262085e-06 +4311 4198 -4861111.112713 +4312 4198 -41704377.77507 +4313 4198 34687499.9943 +4199 4199 595771946.5998 +4200 4199 -7.62939453125e-06 +4201 4199 2.026557922363e-06 +4202 4199 71166276.23929 +4284 4199 21679861.11823 +4285 4199 -17343750.0057 +4286 4199 -36432062.04359 +4287 4199 86719444.4302 +4288 4199 3.427267074585e-07 +4289 4199 -99061955.12464 +4290 4199 21679861.11823 +4291 4199 17343750.0057 +4292 4199 -36432062.04359 +4305 4199 4335972.223649 +4306 4199 -34687499.9943 +4307 4199 -36405498.74736 +4308 4199 17343888.88605 +4309 4199 -3.576278686523e-06 +4310 4199 -52289409.00778 +4311 4199 4335972.22365 +4312 4199 34687499.9943 +4313 4199 -36405498.74735 +4200 4200 659564133.511 +4201 4200 1.192092895508e-06 +4202 4200 -3.0517578125e-05 +4203 4200 87114322.97494 +4204 4200 16203611.10845 +4205 4200 -7.62939453125e-06 +4287 4200 -46373434.23613 +4288 4200 24305555.56354 +4289 4200 21679861.11823 +4290 4200 -138827443.8752 +4291 4200 2.682209014893e-07 +4292 4200 86719444.4302 +4293 4200 -46373434.23614 +4294 4200 -24305555.56354 +4295 4200 21679861.11823 +4308 4200 4476132.383914 +4309 4200 -4861111.112702 +4310 4200 -4335972.223643 +4311 4200 111237115.4367 +4312 4200 -8.344650268555e-07 +4313 4200 -17343888.88603 +4314 4200 4476132.383917 +4315 4200 4861111.1127 +4316 4200 -4335972.223642 +4201 4201 562338920.1509 +4202 4201 8.344650268555e-06 +4203 4201 -16203611.10845 +4204 4201 -66819831.18376 +4205 4201 2.235174179077e-06 +4287 4201 24305555.56354 +4288 4201 -39081501.55876 +4289 4201 -17343750.00569 +4290 4201 -2.294778823853e-06 +4291 4201 -31882558.21685 +4292 4201 2.682209014893e-07 +4293 4201 -24305555.56354 +4294 4201 -39081501.55876 +4295 4201 17343750.0057 +4308 4201 4861111.112712 +4309 4201 -41704377.77507 +4310 4201 -34687499.9943 +4311 4201 -7.152557373047e-07 +4312 4201 82069384.74161 +4313 4201 -3.75509262085e-06 +4314 4201 -4861111.112713 +4315 4201 -41704377.77507 +4316 4201 34687499.9943 +4202 4202 595771946.5998 +4203 4202 -7.62939453125e-06 +4204 4202 2.026557922363e-06 +4205 4202 71166276.23929 +4287 4202 21679861.11823 +4288 4202 -17343750.0057 +4289 4202 -36432062.04359 +4290 4202 86719444.4302 +4291 4202 3.427267074585e-07 +4292 4202 -99061955.12464 +4293 4202 21679861.11823 +4294 4202 17343750.0057 +4295 4202 -36432062.04359 +4308 4202 4335972.223649 +4309 4202 -34687499.9943 +4310 4202 -36405498.74736 +4311 4202 17343888.88605 +4312 4202 -3.576278686523e-06 +4313 4202 -52289409.00778 +4314 4202 4335972.22365 +4315 4202 34687499.9943 +4316 4202 -36405498.74735 +4203 4203 659564133.511 +4204 4203 1.192092895508e-06 +4205 4203 -3.0517578125e-05 +4206 4203 87114322.97494 +4207 4203 16203611.10845 +4208 4203 -7.62939453125e-06 +4290 4203 -46373434.23613 +4291 4203 24305555.56354 +4292 4203 21679861.11823 +4293 4203 -138827443.8752 +4294 4203 2.682209014893e-07 +4295 4203 86719444.4302 +4296 4203 -46373434.23614 +4297 4203 -24305555.56354 +4298 4203 21679861.11823 +4311 4203 4476132.383914 +4312 4203 -4861111.112702 +4313 4203 -4335972.223643 +4314 4203 111237115.4367 +4315 4203 -8.344650268555e-07 +4316 4203 -17343888.88603 +4317 4203 4476132.383917 +4318 4203 4861111.1127 +4319 4203 -4335972.223642 +4204 4204 562338920.1509 +4205 4204 8.344650268555e-06 +4206 4204 -16203611.10845 +4207 4204 -66819831.18376 +4208 4204 2.235174179077e-06 +4290 4204 24305555.56354 +4291 4204 -39081501.55876 +4292 4204 -17343750.00569 +4293 4204 -2.294778823853e-06 +4294 4204 -31882558.21685 +4295 4204 2.682209014893e-07 +4296 4204 -24305555.56354 +4297 4204 -39081501.55876 +4298 4204 17343750.0057 +4311 4204 4861111.112712 +4312 4204 -41704377.77507 +4313 4204 -34687499.9943 +4314 4204 -7.152557373047e-07 +4315 4204 82069384.74161 +4316 4204 -3.75509262085e-06 +4317 4204 -4861111.112713 +4318 4204 -41704377.77507 +4319 4204 34687499.9943 +4205 4205 595771946.5998 +4206 4205 -7.62939453125e-06 +4207 4205 2.026557922363e-06 +4208 4205 71166276.23929 +4290 4205 21679861.11823 +4291 4205 -17343750.0057 +4292 4205 -36432062.04359 +4293 4205 86719444.4302 +4294 4205 3.427267074585e-07 +4295 4205 -99061955.12464 +4296 4205 21679861.11823 +4297 4205 17343750.0057 +4298 4205 -36432062.04359 +4311 4205 4335972.223649 +4312 4205 -34687499.9943 +4313 4205 -36405498.74736 +4314 4205 17343888.88605 +4315 4205 -3.576278686523e-06 +4316 4205 -52289409.00778 +4317 4205 4335972.22365 +4318 4205 34687499.9943 +4319 4205 -36405498.74735 +4206 4206 661228297.9436 +4207 4206 13246.46245313 +4208 4206 -2.217292785645e-05 +4209 4206 90298955.40877 +4210 4206 19352686.25957 +4211 4206 4.768371582031e-07 +4293 4206 -46373434.23613 +4294 4206 24305555.56354 +4295 4206 21679861.11823 +4296 4206 -140996480.167 +4297 4206 -952893.2695185 +4298 4206 87564583.31904 +4299 4206 -45870736.57861 +4300 4206 -24301364.19971 +4301 4206 21679166.67379 +4314 4206 4476132.383914 +4315 4206 -4861111.112702 +4316 4206 -4335972.223643 +4317 4206 111737658.2525 +4318 4206 3973.96144855 +4319 4206 -17343611.10825 +4320 4206 5643546.059494 +4321 4206 5805839.056954 +4322 4206 -5182361.112479 +4207 4207 561835230.1649 +4208 4207 1.120567321777e-05 +4209 4207 -13054535.95733 +4210 4207 -62324697.05688 +4211 4207 2.32458114624e-06 +4293 4207 24305555.56354 +4294 4207 -39081501.55876 +4295 4207 -17343750.00569 +4296 4207 -952893.2695203 +4297 4207 -33140775.69076 +4298 4207 677083.3332878 +4299 4207 -24301364.19971 +4300 4207 -39232415.4315 +4301 4207 17343750.00569 +4314 4207 4861111.112712 +4315 4207 -41704377.77507 +4316 4207 -34687499.9943 +4317 4207 3973.961447358 +4318 4207 81919567.51516 +4319 4207 -4.619359970093e-06 +4320 4207 -3916383.168459 +4321 4207 -40143811.34479 +4322 4207 34010416.66101 +4208 4208 596084528.6123 +4209 4208 2.384185791016e-07 +4210 4208 2.32458114624e-06 +4211 4208 72618276.19601 +4293 4208 21679861.11823 +4294 4208 -17343750.0057 +4295 4208 -36432062.04359 +4296 4208 87564583.31887 +4297 4208 677083.3331544 +4298 4208 -100252145.5455 +4299 4208 21679166.67379 +4300 4208 17343750.00569 +4301 4208 -36335759.26896 +4314 4208 4335972.223649 +4315 4208 -34687499.9943 +4316 4208 -36405498.74736 +4317 4208 17343611.10827 +4318 4208 -4.559755325317e-06 +4319 4208 -52192192.18038 +4320 4208 3489305.557202 +4321 4208 34010416.66115 +4322 4208 -35404513.64281 +4209 4209 661029666.5103 +4210 4209 -2044981.630182 +4211 4209 -1.907348632813e-06 +4212 4209 -112826288.707 +4213 4209 -79915394.43217 +4214 4209 -1.892447471619e-06 +4215 4209 86751688.89203 +4216 4209 18386425.51773 +4217 4209 1.192092895508e-07 +4296 4209 -48879322.66663 +4297 4209 24272689.58237 +4298 4209 22525694.45184 +4299 4209 -141002035.2671 +4300 4209 -1284012.25659 +4301 4209 85676388.87482 +4317 4209 5643546.059493 +4318 4209 -3916383.168459 +4319 4209 -3489305.557201 +4320 4209 115620942.6216 +4321 4209 -613497.9950585 +4322 4209 -17135277.77496 +4323 4209 -43801307.66029 +4324 4209 -23974755.34006 +4325 4209 20312500.00667 +4326 4209 5916032.269865 +4327 4209 5515959.177803 +4328 4209 -5078333.334502 +4210 4210 553050511.6211 +4211 4210 1.490116119385e-05 +4212 4210 -79915394.43217 +4213 4210 -93124119.87001 +4214 4210 -5.960464477539e-08 +4215 4210 -14020796.69916 +4216 4210 -67696604.96948 +4217 4210 2.056360244751e-06 +4296 4210 24272689.58237 +4297 4210 -38326906.89252 +4298 4210 -16666666.67214 +4299 4210 -1284012.256589 +4300 4210 -32949093.52409 +4301 4210 677083.3332867 +4317 4210 5805839.056955 +4318 4210 -40143811.3448 +4319 4210 -34010416.66115 +4320 4210 -613497.9950569 +4321 4210 83227011.03068 +4322 4210 -5.275011062622e-06 +4323 4210 -23974755.34006 +4324 4210 -37890623.23096 +4325 4210 16666666.67214 +4326 4210 -4206263.04761 +4327 4210 -40418720.68143 +4328 4210 33333333.32786 +4211 4211 581686391.3615 +4212 4211 -1.966953277588e-06 +4213 4211 -5.960464477539e-08 +4214 4211 -26006923.58984 +4215 4211 -3.576278686523e-07 +4216 4211 2.056360244751e-06 +4217 4211 66135242.1995 +4296 4211 22525694.45184 +4297 4211 -16666666.67214 +4298 4211 -36909325.87324 +4299 4211 85676388.87482 +4300 4211 677083.3331533 +4301 4211 -97565514.93122 +4317 4211 5182361.112479 +4318 4211 -34010416.66101 +4319 4211 -35404513.64281 +4320 4211 17135277.77496 +4321 4211 -5.30481338501e-06 +4322 4211 -45997327.00158 +4323 4211 20312500.00667 +4324 4211 16666666.67214 +4325 4211 -34344061.96817 +4326 4211 3385277.779223 +4327 4211 33333333.32786 +4328 4211 -33784975.63128 +4212 4212 319697428.1411 +4213 4212 78790225.51341 +4214 4212 3.814697265625e-06 +4215 4212 -160487333.6906 +4216 4212 -17306272.21852 +4217 4212 -2.145767211914e-06 +4299 4212 4511607.610488 +4300 4212 5529463.940844 +4301 4212 4909027.779056 +4320 4212 -43801307.66029 +4321 4212 -23974755.34006 +4322 4212 -20312500.00667 +4323 4212 56503201.94981 +4324 4212 23637202.7354 +4325 4212 8124999.998666 +4326 4212 -68052930.47167 +4327 4212 -5191911.33618 +4328 4212 -41471527.77105 +4213 4213 275691885.2208 +4214 4213 6.675720214844e-06 +4215 4213 15100949.99838 +4216 4213 17292007.85667 +4217 4213 3.516674041748e-06 +4299 4213 -4192758.28457 +4300 4213 -41531445.75454 +4301 4213 -33333333.32786 +4320 4213 -23974755.34006 +4321 4213 -37890623.23096 +4322 4213 -16666666.67214 +4323 4213 23637202.7354 +4324 4213 43301463.62872 +4325 4213 6666666.66557 +4326 4213 4530310.889233 +4327 4213 -14718823.21489 +4328 4213 3333333.334427 +4214 4214 281793058.4744 +4215 4214 -1.192092895508e-06 +4216 4214 3.457069396973e-06 +4217 4214 21269468.60514 +4299 4214 -3215972.223779 +4300 4214 -33333333.32786 +4301 4214 -33978945.7605 +4320 4214 -20312500.00667 +4321 4214 -16666666.67214 +4322 4214 -34344061.96817 +4323 4214 -8124999.998665 +4324 4214 -6666666.665573 +4325 4214 -20545798.26112 +4326 4214 -41471527.77088 +4327 4214 -3333333.334429 +4328 4214 -46703003.53464 +4215 4215 328571172.4911 +4216 4215 -83200869.95153 +4217 4215 -1.907348632813e-06 +4299 4215 -47751770.62455 +4300 4215 24636355.78701 +4301 4215 21159027.78473 +4320 4215 5916032.269864 +4321 4215 -4206263.04761 +4322 4215 -3385277.779223 +4323 4215 -68052930.47167 +4324 4215 4530310.889237 +4325 4215 41471527.77088 +4326 4215 58352668.82658 +4327 4215 -24960403.62863 +4328 4215 -8463611.10972 +4216 4216 277307871.8262 +4217 4216 7.748603820801e-06 +4299 4216 24636355.78701 +4300 4216 -39372046.84256 +4301 4216 -16666666.67214 +4320 4216 5515959.177804 +4321 4216 -40418720.68143 +4322 4216 -33333333.32786 +4323 4216 -5191911.336177 +4324 4216 -14718823.21489 +4325 4216 3333333.334427 +4326 4216 -24960403.62863 +4327 4216 42973590.73909 +4328 4216 6666666.665569 +4217 4217 287116541.5586 +4299 4217 21159027.78473 +4300 4217 -16666666.67214 +4301 4217 -35825485.57976 +4320 4217 5078333.334501 +4321 4217 -33333333.32786 +4322 4217 -33784975.63128 +4323 4217 41471527.77105 +4324 4217 -3333333.334429 +4325 4217 -46703003.53464 +4326 4217 8463611.109722 +4327 4217 -6666666.665574 +4328 4217 -21115868.58705 +4218 4218 927468678.158 +4219 4218 97222222.20623 +4220 4218 -8.106231689453e-06 +4221 4218 -573726109.9308 +4222 4218 -97222221.42845 +4223 4218 8.940696716309e-07 +4224 4218 18564155.00999 +4225 4218 77777776.9872 +4226 4218 2.861022949219e-06 +4329 4218 139046393.5639 +4330 4218 24305555.56354 +4331 4218 17343888.84952 +4332 4218 -175918799.4896 +4333 4218 -24305555.36909 +4334 4218 -86719444.24762 +4335 4218 -9282077.505002 +4336 4218 19444444.25638 +4337 4218 -17343888.52033 +4219 4219 781630025.6149 +4220 4219 8.412431954121e-06 +4221 4219 -97222221.03956 +4222 4219 -116778839.2437 +4223 4219 5.602836608887e-06 +4224 4219 116666665.4808 +4225 4219 18564155.00998 +4226 4219 5.960464477539e-07 +4329 4219 24305555.56354 +4330 4219 102586730.4102 +4331 4219 13874999.85143 +4332 4219 -24305555.27187 +4333 4219 -61681981.76159 +4334 4219 -17343749.90781 +4335 4219 29166666.38457 +4336 4219 -9282077.504995 +4337 4219 20812499.90894 +4220 4220 728641235.3813 +4221 4220 4.172325134277e-07 +4222 4220 4.887580871582e-06 +4223 4220 -96436338.25295 +4224 4220 2.503395080566e-06 +4225 4220 1.251697540283e-06 +4226 4220 49504413.35998 +4329 4220 -17343888.84952 +4330 4220 -13874999.85144 +4331 4220 -65361760.6378 +4332 4220 -86719444.24762 +4333 4220 -17343749.94044 +4334 4220 -110741809.7386 +4335 4220 -26015832.7805 +4336 4220 13874999.9393 +4337 4220 -24752206.67999 +4221 4221 1632315315.374 +4222 4221 97222220.26178 +4223 4221 -4.172325134277e-05 +4224 4221 17392720.97666 +4225 4221 -97222221.42845 +4226 4221 -2.145767211914e-06 +4227 4221 -406796532.3944 +4228 4221 -2.801418304443e-06 +4229 4221 -1.233816146851e-05 +4230 4221 -148365426.1266 +4231 4221 97222222.20624 +4232 4221 -3.308057785034e-06 +4329 4221 -175918799.4897 +4330 4221 -24305555.27186 +4331 4221 86719444.24762 +4332 4221 268847663.9159 +4333 4221 24305555.07742 +4334 4221 0.03653132915497 +4335 4221 -28139091.37671 +4336 4221 -24305555.36909 +4337 4221 21679860.74398 +4338 4221 -138827443.8751 +4339 4221 -5.066394805908e-07 +4340 4221 -86719444.43019 +4341 4221 -46373434.23611 +4342 4221 24305555.56353 +4343 4221 -21679861.11823 +4222 4222 1369805740.108 +4223 4222 -2.145767211914e-06 +4224 4222 -97222221.03956 +4225 4222 -322883627.8625 +4226 4222 4.798173904419e-06 +4227 4222 -3.09944152832e-06 +4228 4222 20983010.02827 +4229 4222 -4.768371582031e-07 +4230 4222 97222222.20624 +4231 4222 -119197695.4315 +4232 4222 -7.450580596924e-08 +4329 4222 -24305555.36908 +4330 4222 -61681981.7616 +4331 4222 17343749.94043 +4332 4222 24305555.07742 +4333 4222 203220270.0671 +4334 4222 0.02920919656754 +4335 4222 -24305555.27186 +4336 4222 -113208178.6284 +4337 4222 69374999.6084 +4338 4222 -8.344650268555e-07 +4339 4222 -31882558.21681 +4340 4222 -3.278255462646e-07 +4341 4222 24305555.56353 +4342 4222 -39081501.55875 +4343 4222 17343750.00569 +4223 4223 1212545401.289 +4224 4223 -1.788139343262e-06 +4225 4223 3.75509262085e-06 +4226 4223 8567490.576108 +4227 4223 -1.20997428894e-05 +4228 4223 -4.768371582031e-07 +4229 4223 -212506.0825927 +4230 4223 -3.278255462646e-06 +4231 4223 -2.086162567139e-07 +4232 4223 -46719419.49861 +4329 4223 86719444.24762 +4330 4223 17343749.9078 +4331 4223 -110741809.7386 +4332 4223 -0.03649973869324 +4333 4223 -0.02921465039253 +4334 4223 -68146756.53808 +4335 4223 21679860.55685 +4336 4223 69374999.49133 +4337 4223 -84490851.68298 +4338 4223 -86719444.43019 +4339 4223 -2.682209014893e-07 +4340 4223 -99061955.12461 +4341 4223 -21679861.11823 +4342 4223 17343750.00569 +4343 4223 -36432062.04358 +4224 4224 927468678.158 +4225 4224 97222222.20623 +4226 4224 -8.106231689453e-06 +4227 4224 -148365426.1266 +4228 4224 -97222222.20624 +4229 4224 -3.039836883545e-06 +4230 4224 -573726109.9308 +4231 4224 -97222221.42845 +4232 4224 8.940696716309e-07 +4233 4224 18564155.00999 +4234 4224 77777776.9872 +4235 4224 2.861022949219e-06 +4329 4224 -9282077.50499 +4330 4224 29166666.38457 +4331 4224 26015832.78049 +4332 4224 -28139091.37673 +4333 4224 -24305555.27187 +4334 4224 -21679860.55685 +4335 4224 139046393.5639 +4336 4224 24305555.56354 +4337 4224 17343888.84952 +4338 4224 -46373434.23611 +4339 4224 -24305555.56353 +4340 4224 -21679861.11823 +4341 4224 -175918799.4896 +4342 4224 -24305555.36909 +4343 4224 -86719444.24762 +4344 4224 -9282077.505002 +4345 4224 19444444.25638 +4346 4224 -17343888.52033 +4225 4225 781630025.6149 +4226 4225 8.412431954121e-06 +4227 4225 -97222222.20624 +4228 4225 -119197695.4315 +4229 4225 2.831220626831e-07 +4230 4225 -97222221.03956 +4231 4225 -116778839.2437 +4232 4225 5.602836608887e-06 +4233 4225 116666665.4808 +4234 4225 18564155.00998 +4235 4225 5.960464477539e-07 +4329 4225 19444444.25638 +4330 4225 -9282077.505 +4331 4225 -13874999.9393 +4332 4225 -24305555.36909 +4333 4225 -113208178.6284 +4334 4225 -69374999.49133 +4335 4225 24305555.56354 +4336 4225 102586730.4102 +4337 4225 13874999.85143 +4338 4225 -24305555.56353 +4339 4225 -39081501.55875 +4340 4225 -17343750.0057 +4341 4225 -24305555.27187 +4342 4225 -61681981.76159 +4343 4225 -17343749.90781 +4344 4225 29166666.38457 +4345 4225 -9282077.504995 +4346 4225 20812499.90894 +4226 4226 728641235.3813 +4227 4226 -2.890825271606e-06 +4228 4226 3.8743019104e-07 +4229 4226 -46719419.49861 +4230 4226 4.172325134277e-07 +4231 4226 4.887580871582e-06 +4232 4226 -96436338.25295 +4233 4226 2.503395080566e-06 +4234 4226 1.251697540283e-06 +4235 4226 49504413.35998 +4329 4226 17343888.52033 +4330 4226 -20812499.90895 +4331 4226 -24752206.67999 +4332 4226 -21679860.74398 +4333 4226 -69374999.6084 +4334 4226 -84490851.68299 +4335 4226 -17343888.84952 +4336 4226 -13874999.85144 +4337 4226 -65361760.6378 +4338 4226 -21679861.11823 +4339 4226 -17343750.0057 +4340 4226 -36432062.04358 +4341 4226 -86719444.24762 +4342 4226 -17343749.94044 +4343 4226 -110741809.7386 +4344 4226 -26015832.7805 +4345 4226 13874999.9393 +4346 4226 -24752206.67999 +4227 4227 1483949894.094 +4228 4227 7.867813110352e-06 +4229 4227 -5.507469177246e-05 +4230 4227 184322301.8864 +4231 4227 -2.622604370117e-06 +4232 4227 -1.358985900879e-05 +4236 4227 -406796532.3944 +4237 4227 -2.801418304443e-06 +4238 4227 -1.233816146851e-05 +4239 4227 -148365426.1266 +4240 4227 97222222.20624 +4241 4227 -3.308057785034e-06 +4332 4227 -138827443.8752 +4333 4227 2.682209014893e-07 +4334 4227 86719444.4302 +4335 4227 -46373434.23614 +4336 4227 -24305555.56354 +4337 4227 21679861.11823 +4338 4227 222474230.8735 +4339 4227 3.933906555176e-06 +4340 4227 2.622604370117e-05 +4341 4227 8952264.76783 +4342 4227 -1.302361488342e-05 +4343 4227 6.914138793945e-06 +4347 4227 -138827443.8751 +4348 4227 -5.066394805908e-07 +4349 4227 -86719444.43019 +4350 4227 -46373434.23611 +4351 4227 24305555.56353 +4352 4227 -21679861.11823 +4228 4228 1250608048.648 +4229 4228 -1.192092895508e-06 +4230 4228 -3.159046173096e-06 +4231 4228 -185121779.2034 +4232 4228 8.046627044678e-07 +4236 4228 -3.09944152832e-06 +4237 4228 20983010.02827 +4238 4228 -4.768371582031e-07 +4239 4228 97222222.20624 +4240 4228 -119197695.4315 +4241 4228 -7.450580596924e-08 +4332 4228 -2.294778823853e-06 +4333 4228 -31882558.21685 +4334 4228 2.682209014893e-07 +4335 4228 -24305555.56354 +4336 4228 -39081501.55876 +4337 4228 17343750.0057 +4338 4228 4.410743713379e-06 +4339 4228 164138769.4832 +4340 4228 -1.192092895508e-07 +4341 4228 -1.156330108643e-05 +4342 4228 -83408755.55014 +4343 4228 69374999.9886 +4347 4228 -8.344650268555e-07 +4348 4228 -31882558.21681 +4349 4228 -3.278255462646e-07 +4350 4228 24305555.56353 +4351 4228 -39081501.55875 +4352 4228 17343750.00569 +4229 4229 1165825984.246 +4230 4229 -1.382827758789e-05 +4231 4229 1.788139343262e-07 +4232 4229 104791324.3853 +4236 4229 -1.20997428894e-05 +4237 4229 -4.768371582031e-07 +4238 4229 -212506.0825927 +4239 4229 -3.278255462646e-06 +4240 4229 -2.086162567139e-07 +4241 4229 -46719419.49861 +4332 4229 86719444.4302 +4333 4229 3.427267074585e-07 +4334 4229 -99061955.12464 +4335 4229 21679861.11823 +4336 4229 17343750.0057 +4337 4229 -36432062.04359 +4338 4229 2.598762512207e-05 +4339 4229 5.960464477539e-08 +4340 4229 -104578818.0156 +4341 4229 6.973743438721e-06 +4342 4229 69374999.9886 +4343 4229 -72810997.49471 +4347 4229 -86719444.43019 +4348 4229 -2.682209014893e-07 +4349 4229 -99061955.12461 +4350 4229 -21679861.11823 +4351 4229 17343750.00569 +4352 4229 -36432062.04358 +4230 4230 1632315315.374 +4231 4230 97222220.26178 +4232 4230 -4.172325134277e-05 +4233 4230 17392720.97666 +4234 4230 -97222221.42845 +4235 4230 -2.145767211914e-06 +4236 4230 -148365426.1266 +4237 4230 -97222222.20624 +4238 4230 -3.039836883545e-06 +4239 4230 -406796532.3944 +4240 4230 -2.801418304443e-06 +4241 4230 -1.233816146851e-05 +4242 4230 -148365426.1266 +4243 4230 97222222.20624 +4244 4230 -3.308057785034e-06 +4332 4230 -46373434.23613 +4333 4230 24305555.56354 +4334 4230 21679861.11823 +4335 4230 -175918799.4897 +4336 4230 -24305555.27186 +4337 4230 86719444.24762 +4338 4230 8952264.76783 +4339 4230 9.298324584961e-06 +4340 4230 6.228685379028e-06 +4341 4230 268847663.9159 +4342 4230 24305555.07742 +4343 4230 0.03653132915497 +4344 4230 -28139091.37671 +4345 4230 -24305555.36909 +4346 4230 21679860.74398 +4347 4230 -46373434.23611 +4348 4230 -24305555.56353 +4349 4230 -21679861.11823 +4350 4230 -138827443.8751 +4351 4230 -5.066394805908e-07 +4352 4230 -86719444.43019 +4353 4230 -46373434.23611 +4354 4230 24305555.56353 +4355 4230 -21679861.11823 +4231 4231 1369805740.108 +4232 4231 -2.145767211914e-06 +4233 4231 -97222221.03956 +4234 4231 -322883627.8625 +4235 4231 4.798173904419e-06 +4236 4231 -97222222.20624 +4237 4231 -119197695.4315 +4238 4231 2.831220626831e-07 +4239 4231 -3.09944152832e-06 +4240 4231 20983010.02827 +4241 4231 -4.768371582031e-07 +4242 4231 97222222.20624 +4243 4231 -119197695.4315 +4244 4231 -7.450580596924e-08 +4332 4231 24305555.56354 +4333 4231 -39081501.55876 +4334 4231 -17343750.00569 +4335 4231 -24305555.36908 +4336 4231 -61681981.7616 +4337 4231 17343749.94043 +4338 4231 1.069903373718e-05 +4339 4231 -83408755.55014 +4340 4231 -69374999.9886 +4341 4231 24305555.07742 +4342 4231 203220270.0671 +4343 4231 0.02920919656754 +4344 4231 -24305555.27186 +4345 4231 -113208178.6284 +4346 4231 69374999.6084 +4347 4231 -24305555.56353 +4348 4231 -39081501.55875 +4349 4231 -17343750.0057 +4350 4231 -8.344650268555e-07 +4351 4231 -31882558.21681 +4352 4231 -3.278255462646e-07 +4353 4231 24305555.56353 +4354 4231 -39081501.55875 +4355 4231 17343750.00569 +4232 4232 1212545401.289 +4233 4232 -1.788139343262e-06 +4234 4232 3.75509262085e-06 +4235 4232 8567490.576108 +4236 4232 -2.890825271606e-06 +4237 4232 3.8743019104e-07 +4238 4232 -46719419.49861 +4239 4232 -1.20997428894e-05 +4240 4232 -4.768371582031e-07 +4241 4232 -212506.0825927 +4242 4232 -3.278255462646e-06 +4243 4232 -2.086162567139e-07 +4244 4232 -46719419.49861 +4332 4232 21679861.11823 +4333 4232 -17343750.0057 +4334 4232 -36432062.04359 +4335 4232 86719444.24762 +4336 4232 17343749.9078 +4337 4232 -110741809.7386 +4338 4232 6.169080734253e-06 +4339 4232 -69374999.9886 +4340 4232 -72810997.49471 +4341 4232 -0.03649973869324 +4342 4232 -0.02921465039253 +4343 4232 -68146756.53808 +4344 4232 21679860.55685 +4345 4232 69374999.49133 +4346 4232 -84490851.68298 +4347 4232 -21679861.11823 +4348 4232 -17343750.0057 +4349 4232 -36432062.04358 +4350 4232 -86719444.43019 +4351 4232 -2.682209014893e-07 +4352 4232 -99061955.12461 +4353 4232 -21679861.11823 +4354 4232 17343750.00569 +4355 4232 -36432062.04358 +4233 4233 927468678.158 +4234 4233 97222222.20623 +4235 4233 -8.106231689453e-06 +4239 4233 -148365426.1266 +4240 4233 -97222222.20624 +4241 4233 -3.039836883545e-06 +4242 4233 -573726109.9308 +4243 4233 -97222221.42845 +4244 4233 8.940696716309e-07 +4245 4233 18564155.00999 +4246 4233 77777776.9872 +4247 4233 2.861022949219e-06 +4335 4233 -9282077.50499 +4336 4233 29166666.38457 +4337 4233 26015832.78049 +4341 4233 -28139091.37673 +4342 4233 -24305555.27187 +4343 4233 -21679860.55685 +4344 4233 139046393.5639 +4345 4233 24305555.56354 +4346 4233 17343888.84952 +4350 4233 -46373434.23611 +4351 4233 -24305555.56353 +4352 4233 -21679861.11823 +4353 4233 -175918799.4896 +4354 4233 -24305555.36909 +4355 4233 -86719444.24762 +4356 4233 -9282077.505002 +4357 4233 19444444.25638 +4358 4233 -17343888.52033 +4234 4234 781630025.6149 +4235 4234 8.412431954121e-06 +4239 4234 -97222222.20624 +4240 4234 -119197695.4315 +4241 4234 2.831220626831e-07 +4242 4234 -97222221.03956 +4243 4234 -116778839.2437 +4244 4234 5.602836608887e-06 +4245 4234 116666665.4808 +4246 4234 18564155.00998 +4247 4234 5.960464477539e-07 +4335 4234 19444444.25638 +4336 4234 -9282077.505 +4337 4234 -13874999.9393 +4341 4234 -24305555.36909 +4342 4234 -113208178.6284 +4343 4234 -69374999.49133 +4344 4234 24305555.56354 +4345 4234 102586730.4102 +4346 4234 13874999.85143 +4350 4234 -24305555.56353 +4351 4234 -39081501.55875 +4352 4234 -17343750.0057 +4353 4234 -24305555.27187 +4354 4234 -61681981.76159 +4355 4234 -17343749.90781 +4356 4234 29166666.38457 +4357 4234 -9282077.504995 +4358 4234 20812499.90894 +4235 4235 728641235.3813 +4239 4235 -2.890825271606e-06 +4240 4235 3.8743019104e-07 +4241 4235 -46719419.49861 +4242 4235 4.172325134277e-07 +4243 4235 4.887580871582e-06 +4244 4235 -96436338.25295 +4245 4235 2.503395080566e-06 +4246 4235 1.251697540283e-06 +4247 4235 49504413.35998 +4335 4235 17343888.52033 +4336 4235 -20812499.90895 +4337 4235 -24752206.67999 +4341 4235 -21679860.74398 +4342 4235 -69374999.6084 +4343 4235 -84490851.68299 +4344 4235 -17343888.84952 +4345 4235 -13874999.85144 +4346 4235 -65361760.6378 +4350 4235 -21679861.11823 +4351 4235 -17343750.0057 +4352 4235 -36432062.04358 +4353 4235 -86719444.24762 +4354 4235 -17343749.94044 +4355 4235 -110741809.7386 +4356 4235 -26015832.7805 +4357 4235 13874999.9393 +4358 4235 -24752206.67999 +4236 4236 1483949894.094 +4237 4236 7.867813110352e-06 +4238 4236 -5.507469177246e-05 +4239 4236 184322301.8864 +4240 4236 -2.622604370117e-06 +4241 4236 -1.358985900879e-05 +4248 4236 -406796532.3944 +4249 4236 -2.801418304443e-06 +4250 4236 -1.233816146851e-05 +4251 4236 -148365426.1266 +4252 4236 97222222.20624 +4253 4236 -3.308057785034e-06 +4338 4236 -138827443.8752 +4339 4236 2.682209014893e-07 +4340 4236 86719444.4302 +4341 4236 -46373434.23614 +4342 4236 -24305555.56354 +4343 4236 21679861.11823 +4347 4236 222474230.8735 +4348 4236 3.933906555176e-06 +4349 4236 2.622604370117e-05 +4350 4236 8952264.76783 +4351 4236 -1.302361488342e-05 +4352 4236 6.914138793945e-06 +4359 4236 -138827443.8751 +4360 4236 -5.066394805908e-07 +4361 4236 -86719444.43019 +4362 4236 -46373434.23611 +4363 4236 24305555.56353 +4364 4236 -21679861.11823 +4237 4237 1250608048.648 +4238 4237 -1.192092895508e-06 +4239 4237 -3.159046173096e-06 +4240 4237 -185121779.2034 +4241 4237 8.046627044678e-07 +4248 4237 -3.09944152832e-06 +4249 4237 20983010.02827 +4250 4237 -4.768371582031e-07 +4251 4237 97222222.20624 +4252 4237 -119197695.4315 +4253 4237 -7.450580596924e-08 +4338 4237 -2.294778823853e-06 +4339 4237 -31882558.21685 +4340 4237 2.682209014893e-07 +4341 4237 -24305555.56354 +4342 4237 -39081501.55876 +4343 4237 17343750.0057 +4347 4237 4.410743713379e-06 +4348 4237 164138769.4832 +4349 4237 -1.192092895508e-07 +4350 4237 -1.156330108643e-05 +4351 4237 -83408755.55014 +4352 4237 69374999.9886 +4359 4237 -8.344650268555e-07 +4360 4237 -31882558.21681 +4361 4237 -3.278255462646e-07 +4362 4237 24305555.56353 +4363 4237 -39081501.55875 +4364 4237 17343750.00569 +4238 4238 1165825984.246 +4239 4238 -1.382827758789e-05 +4240 4238 1.788139343262e-07 +4241 4238 104791324.3853 +4248 4238 -1.20997428894e-05 +4249 4238 -4.768371582031e-07 +4250 4238 -212506.0825927 +4251 4238 -3.278255462646e-06 +4252 4238 -2.086162567139e-07 +4253 4238 -46719419.49861 +4338 4238 86719444.4302 +4339 4238 3.427267074585e-07 +4340 4238 -99061955.12464 +4341 4238 21679861.11823 +4342 4238 17343750.0057 +4343 4238 -36432062.04359 +4347 4238 2.598762512207e-05 +4348 4238 5.960464477539e-08 +4349 4238 -104578818.0156 +4350 4238 6.973743438721e-06 +4351 4238 69374999.9886 +4352 4238 -72810997.49471 +4359 4238 -86719444.43019 +4360 4238 -2.682209014893e-07 +4361 4238 -99061955.12461 +4362 4238 -21679861.11823 +4363 4238 17343750.00569 +4364 4238 -36432062.04358 +4239 4239 1483949894.094 +4240 4239 7.867813110352e-06 +4241 4239 -5.507469177246e-05 +4242 4239 184322301.8864 +4243 4239 -2.622604370117e-06 +4244 4239 -1.358985900879e-05 +4248 4239 -148365426.1266 +4249 4239 -97222222.20624 +4250 4239 -3.039836883545e-06 +4251 4239 -406796532.3944 +4252 4239 -2.801418304443e-06 +4253 4239 -1.233816146851e-05 +4254 4239 -148365426.1266 +4255 4239 97222222.20624 +4256 4239 -3.308057785034e-06 +4338 4239 -46373434.23613 +4339 4239 24305555.56354 +4340 4239 21679861.11823 +4341 4239 -138827443.8752 +4342 4239 2.682209014893e-07 +4343 4239 86719444.4302 +4344 4239 -46373434.23614 +4345 4239 -24305555.56354 +4346 4239 21679861.11823 +4347 4239 8952264.76783 +4348 4239 9.298324584961e-06 +4349 4239 6.228685379028e-06 +4350 4239 222474230.8735 +4351 4239 3.933906555176e-06 +4352 4239 2.622604370117e-05 +4353 4239 8952264.76783 +4354 4239 -1.302361488342e-05 +4355 4239 6.914138793945e-06 +4359 4239 -46373434.23611 +4360 4239 -24305555.56353 +4361 4239 -21679861.11823 +4362 4239 -138827443.8751 +4363 4239 -5.066394805908e-07 +4364 4239 -86719444.43019 +4365 4239 -46373434.23611 +4366 4239 24305555.56353 +4367 4239 -21679861.11823 +4240 4240 1250608048.648 +4241 4240 -1.192092895508e-06 +4242 4240 -3.159046173096e-06 +4243 4240 -185121779.2034 +4244 4240 8.046627044678e-07 +4248 4240 -97222222.20624 +4249 4240 -119197695.4315 +4250 4240 2.831220626831e-07 +4251 4240 -3.09944152832e-06 +4252 4240 20983010.02827 +4253 4240 -4.768371582031e-07 +4254 4240 97222222.20624 +4255 4240 -119197695.4315 +4256 4240 -7.450580596924e-08 +4338 4240 24305555.56354 +4339 4240 -39081501.55876 +4340 4240 -17343750.00569 +4341 4240 -2.294778823853e-06 +4342 4240 -31882558.21685 +4343 4240 2.682209014893e-07 +4344 4240 -24305555.56354 +4345 4240 -39081501.55876 +4346 4240 17343750.0057 +4347 4240 1.069903373718e-05 +4348 4240 -83408755.55014 +4349 4240 -69374999.9886 +4350 4240 4.410743713379e-06 +4351 4240 164138769.4832 +4352 4240 -1.192092895508e-07 +4353 4240 -1.156330108643e-05 +4354 4240 -83408755.55014 +4355 4240 69374999.9886 +4359 4240 -24305555.56353 +4360 4240 -39081501.55875 +4361 4240 -17343750.0057 +4362 4240 -8.344650268555e-07 +4363 4240 -31882558.21681 +4364 4240 -3.278255462646e-07 +4365 4240 24305555.56353 +4366 4240 -39081501.55875 +4367 4240 17343750.00569 +4241 4241 1165825984.246 +4242 4241 -1.382827758789e-05 +4243 4241 1.788139343262e-07 +4244 4241 104791324.3853 +4248 4241 -2.890825271606e-06 +4249 4241 3.8743019104e-07 +4250 4241 -46719419.49861 +4251 4241 -1.20997428894e-05 +4252 4241 -4.768371582031e-07 +4253 4241 -212506.0825927 +4254 4241 -3.278255462646e-06 +4255 4241 -2.086162567139e-07 +4256 4241 -46719419.49861 +4338 4241 21679861.11823 +4339 4241 -17343750.0057 +4340 4241 -36432062.04359 +4341 4241 86719444.4302 +4342 4241 3.427267074585e-07 +4343 4241 -99061955.12464 +4344 4241 21679861.11823 +4345 4241 17343750.0057 +4346 4241 -36432062.04359 +4347 4241 6.169080734253e-06 +4348 4241 -69374999.9886 +4349 4241 -72810997.49471 +4350 4241 2.598762512207e-05 +4351 4241 5.960464477539e-08 +4352 4241 -104578818.0156 +4353 4241 6.973743438721e-06 +4354 4241 69374999.9886 +4355 4241 -72810997.49471 +4359 4241 -21679861.11823 +4360 4241 -17343750.0057 +4361 4241 -36432062.04358 +4362 4241 -86719444.43019 +4363 4241 -2.682209014893e-07 +4364 4241 -99061955.12461 +4365 4241 -21679861.11823 +4366 4241 17343750.00569 +4367 4241 -36432062.04358 +4242 4242 1632315315.374 +4243 4242 97222220.26178 +4244 4242 -4.172325134277e-05 +4245 4242 17392720.97666 +4246 4242 -97222221.42845 +4247 4242 -2.145767211914e-06 +4251 4242 -148365426.1266 +4252 4242 -97222222.20624 +4253 4242 -3.039836883545e-06 +4254 4242 -406796532.3944 +4255 4242 -2.801418304443e-06 +4256 4242 -1.233816146851e-05 +4257 4242 -148365426.1266 +4258 4242 97222222.20624 +4259 4242 -3.308057785034e-06 +4341 4242 -46373434.23613 +4342 4242 24305555.56354 +4343 4242 21679861.11823 +4344 4242 -175918799.4897 +4345 4242 -24305555.27186 +4346 4242 86719444.24762 +4350 4242 8952264.76783 +4351 4242 9.298324584961e-06 +4352 4242 6.228685379028e-06 +4353 4242 268847663.9159 +4354 4242 24305555.07742 +4355 4242 0.03653132915497 +4356 4242 -28139091.37671 +4357 4242 -24305555.36909 +4358 4242 21679860.74398 +4362 4242 -46373434.23611 +4363 4242 -24305555.56353 +4364 4242 -21679861.11823 +4365 4242 -138827443.8751 +4366 4242 -5.066394805908e-07 +4367 4242 -86719444.43019 +4368 4242 -46373434.23611 +4369 4242 24305555.56353 +4370 4242 -21679861.11823 +4243 4243 1369805740.108 +4244 4243 -2.145767211914e-06 +4245 4243 -97222221.03956 +4246 4243 -322883627.8625 +4247 4243 4.798173904419e-06 +4251 4243 -97222222.20624 +4252 4243 -119197695.4315 +4253 4243 2.831220626831e-07 +4254 4243 -3.09944152832e-06 +4255 4243 20983010.02827 +4256 4243 -4.768371582031e-07 +4257 4243 97222222.20624 +4258 4243 -119197695.4315 +4259 4243 -7.450580596924e-08 +4341 4243 24305555.56354 +4342 4243 -39081501.55876 +4343 4243 -17343750.00569 +4344 4243 -24305555.36908 +4345 4243 -61681981.7616 +4346 4243 17343749.94043 +4350 4243 1.069903373718e-05 +4351 4243 -83408755.55014 +4352 4243 -69374999.9886 +4353 4243 24305555.07742 +4354 4243 203220270.0671 +4355 4243 0.02920919656754 +4356 4243 -24305555.27186 +4357 4243 -113208178.6284 +4358 4243 69374999.6084 +4362 4243 -24305555.56353 +4363 4243 -39081501.55875 +4364 4243 -17343750.0057 +4365 4243 -8.344650268555e-07 +4366 4243 -31882558.21681 +4367 4243 -3.278255462646e-07 +4368 4243 24305555.56353 +4369 4243 -39081501.55875 +4370 4243 17343750.00569 +4244 4244 1212545401.289 +4245 4244 -1.788139343262e-06 +4246 4244 3.75509262085e-06 +4247 4244 8567490.576108 +4251 4244 -2.890825271606e-06 +4252 4244 3.8743019104e-07 +4253 4244 -46719419.49861 +4254 4244 -1.20997428894e-05 +4255 4244 -4.768371582031e-07 +4256 4244 -212506.0825927 +4257 4244 -3.278255462646e-06 +4258 4244 -2.086162567139e-07 +4259 4244 -46719419.49861 +4341 4244 21679861.11823 +4342 4244 -17343750.0057 +4343 4244 -36432062.04359 +4344 4244 86719444.24762 +4345 4244 17343749.9078 +4346 4244 -110741809.7386 +4350 4244 6.169080734253e-06 +4351 4244 -69374999.9886 +4352 4244 -72810997.49471 +4353 4244 -0.03649973869324 +4354 4244 -0.02921465039253 +4355 4244 -68146756.53808 +4356 4244 21679860.55685 +4357 4244 69374999.49133 +4358 4244 -84490851.68298 +4362 4244 -21679861.11823 +4363 4244 -17343750.0057 +4364 4244 -36432062.04358 +4365 4244 -86719444.43019 +4366 4244 -2.682209014893e-07 +4367 4244 -99061955.12461 +4368 4244 -21679861.11823 +4369 4244 17343750.00569 +4370 4244 -36432062.04358 +4245 4245 927468678.158 +4246 4245 97222222.20623 +4247 4245 -8.106231689453e-06 +4254 4245 -148365426.1266 +4255 4245 -97222222.20624 +4256 4245 -3.039836883545e-06 +4257 4245 -573726109.9308 +4258 4245 -97222221.42845 +4259 4245 8.940696716309e-07 +4260 4245 18564155.00999 +4261 4245 77777776.9872 +4262 4245 2.861022949219e-06 +4344 4245 -9282077.50499 +4345 4245 29166666.38457 +4346 4245 26015832.78049 +4353 4245 -28139091.37673 +4354 4245 -24305555.27187 +4355 4245 -21679860.55685 +4356 4245 139046393.5639 +4357 4245 24305555.56354 +4358 4245 17343888.84952 +4365 4245 -46373434.23611 +4366 4245 -24305555.56353 +4367 4245 -21679861.11823 +4368 4245 -175918799.4896 +4369 4245 -24305555.36909 +4370 4245 -86719444.24762 +4371 4245 -9282077.505002 +4372 4245 19444444.25638 +4373 4245 -17343888.52033 +4246 4246 781630025.6149 +4247 4246 8.412431954121e-06 +4254 4246 -97222222.20624 +4255 4246 -119197695.4315 +4256 4246 2.831220626831e-07 +4257 4246 -97222221.03956 +4258 4246 -116778839.2437 +4259 4246 5.602836608887e-06 +4260 4246 116666665.4808 +4261 4246 18564155.00998 +4262 4246 5.960464477539e-07 +4344 4246 19444444.25638 +4345 4246 -9282077.505 +4346 4246 -13874999.9393 +4353 4246 -24305555.36909 +4354 4246 -113208178.6284 +4355 4246 -69374999.49133 +4356 4246 24305555.56354 +4357 4246 102586730.4102 +4358 4246 13874999.85143 +4365 4246 -24305555.56353 +4366 4246 -39081501.55875 +4367 4246 -17343750.0057 +4368 4246 -24305555.27187 +4369 4246 -61681981.76159 +4370 4246 -17343749.90781 +4371 4246 29166666.38457 +4372 4246 -9282077.504995 +4373 4246 20812499.90894 +4247 4247 728641235.3813 +4254 4247 -2.890825271606e-06 +4255 4247 3.8743019104e-07 +4256 4247 -46719419.49861 +4257 4247 4.172325134277e-07 +4258 4247 4.887580871582e-06 +4259 4247 -96436338.25295 +4260 4247 2.503395080566e-06 +4261 4247 1.251697540283e-06 +4262 4247 49504413.35998 +4344 4247 17343888.52033 +4345 4247 -20812499.90895 +4346 4247 -24752206.67999 +4353 4247 -21679860.74398 +4354 4247 -69374999.6084 +4355 4247 -84490851.68299 +4356 4247 -17343888.84952 +4357 4247 -13874999.85144 +4358 4247 -65361760.6378 +4365 4247 -21679861.11823 +4366 4247 -17343750.0057 +4367 4247 -36432062.04358 +4368 4247 -86719444.24762 +4369 4247 -17343749.94044 +4370 4247 -110741809.7386 +4371 4247 -26015832.7805 +4372 4247 13874999.9393 +4373 4247 -24752206.67999 +4248 4248 1483949894.094 +4249 4248 7.867813110352e-06 +4250 4248 -5.507469177246e-05 +4251 4248 184322301.8864 +4252 4248 -2.622604370117e-06 +4253 4248 -1.358985900879e-05 +4263 4248 -406796532.3944 +4264 4248 -2.801418304443e-06 +4265 4248 -1.233816146851e-05 +4266 4248 -148365426.1266 +4267 4248 97222222.20624 +4268 4248 -3.308057785034e-06 +4347 4248 -138827443.8752 +4348 4248 2.682209014893e-07 +4349 4248 86719444.4302 +4350 4248 -46373434.23614 +4351 4248 -24305555.56354 +4352 4248 21679861.11823 +4359 4248 222474230.8735 +4360 4248 3.933906555176e-06 +4361 4248 2.622604370117e-05 +4362 4248 8952264.76783 +4363 4248 -1.302361488342e-05 +4364 4248 6.914138793945e-06 +4374 4248 -138827443.8751 +4375 4248 -5.066394805908e-07 +4376 4248 -86719444.43019 +4377 4248 -46373434.23611 +4378 4248 24305555.56353 +4379 4248 -21679861.11823 +4249 4249 1250608048.648 +4250 4249 -1.192092895508e-06 +4251 4249 -3.159046173096e-06 +4252 4249 -185121779.2034 +4253 4249 8.046627044678e-07 +4263 4249 -3.09944152832e-06 +4264 4249 20983010.02827 +4265 4249 -4.768371582031e-07 +4266 4249 97222222.20624 +4267 4249 -119197695.4315 +4268 4249 -7.450580596924e-08 +4347 4249 -2.294778823853e-06 +4348 4249 -31882558.21685 +4349 4249 2.682209014893e-07 +4350 4249 -24305555.56354 +4351 4249 -39081501.55876 +4352 4249 17343750.0057 +4359 4249 4.410743713379e-06 +4360 4249 164138769.4832 +4361 4249 -1.192092895508e-07 +4362 4249 -1.156330108643e-05 +4363 4249 -83408755.55014 +4364 4249 69374999.9886 +4374 4249 -8.344650268555e-07 +4375 4249 -31882558.21681 +4376 4249 -3.278255462646e-07 +4377 4249 24305555.56353 +4378 4249 -39081501.55875 +4379 4249 17343750.00569 +4250 4250 1165825984.246 +4251 4250 -1.382827758789e-05 +4252 4250 1.788139343262e-07 +4253 4250 104791324.3853 +4263 4250 -1.20997428894e-05 +4264 4250 -4.768371582031e-07 +4265 4250 -212506.0825927 +4266 4250 -3.278255462646e-06 +4267 4250 -2.086162567139e-07 +4268 4250 -46719419.49861 +4347 4250 86719444.4302 +4348 4250 3.427267074585e-07 +4349 4250 -99061955.12464 +4350 4250 21679861.11823 +4351 4250 17343750.0057 +4352 4250 -36432062.04359 +4359 4250 2.598762512207e-05 +4360 4250 5.960464477539e-08 +4361 4250 -104578818.0156 +4362 4250 6.973743438721e-06 +4363 4250 69374999.9886 +4364 4250 -72810997.49471 +4374 4250 -86719444.43019 +4375 4250 -2.682209014893e-07 +4376 4250 -99061955.12461 +4377 4250 -21679861.11823 +4378 4250 17343750.00569 +4379 4250 -36432062.04358 +4251 4251 1483949894.094 +4252 4251 7.867813110352e-06 +4253 4251 -5.507469177246e-05 +4254 4251 184322301.8864 +4255 4251 -2.622604370117e-06 +4256 4251 -1.358985900879e-05 +4263 4251 -148365426.1266 +4264 4251 -97222222.20624 +4265 4251 -3.039836883545e-06 +4266 4251 -406796532.3944 +4267 4251 -2.801418304443e-06 +4268 4251 -1.233816146851e-05 +4269 4251 -148365426.1266 +4270 4251 97222222.20624 +4271 4251 -3.308057785034e-06 +4347 4251 -46373434.23613 +4348 4251 24305555.56354 +4349 4251 21679861.11823 +4350 4251 -138827443.8752 +4351 4251 2.682209014893e-07 +4352 4251 86719444.4302 +4353 4251 -46373434.23614 +4354 4251 -24305555.56354 +4355 4251 21679861.11823 +4359 4251 8952264.76783 +4360 4251 9.298324584961e-06 +4361 4251 6.228685379028e-06 +4362 4251 222474230.8735 +4363 4251 3.933906555176e-06 +4364 4251 2.622604370117e-05 +4365 4251 8952264.76783 +4366 4251 -1.302361488342e-05 +4367 4251 6.914138793945e-06 +4374 4251 -46373434.23611 +4375 4251 -24305555.56353 +4376 4251 -21679861.11823 +4377 4251 -138827443.8751 +4378 4251 -5.066394805908e-07 +4379 4251 -86719444.43019 +4380 4251 -46373434.23611 +4381 4251 24305555.56353 +4382 4251 -21679861.11823 +4252 4252 1250608048.648 +4253 4252 -1.192092895508e-06 +4254 4252 -3.159046173096e-06 +4255 4252 -185121779.2034 +4256 4252 8.046627044678e-07 +4263 4252 -97222222.20624 +4264 4252 -119197695.4315 +4265 4252 2.831220626831e-07 +4266 4252 -3.09944152832e-06 +4267 4252 20983010.02827 +4268 4252 -4.768371582031e-07 +4269 4252 97222222.20624 +4270 4252 -119197695.4315 +4271 4252 -7.450580596924e-08 +4347 4252 24305555.56354 +4348 4252 -39081501.55876 +4349 4252 -17343750.00569 +4350 4252 -2.294778823853e-06 +4351 4252 -31882558.21685 +4352 4252 2.682209014893e-07 +4353 4252 -24305555.56354 +4354 4252 -39081501.55876 +4355 4252 17343750.0057 +4359 4252 1.069903373718e-05 +4360 4252 -83408755.55014 +4361 4252 -69374999.9886 +4362 4252 4.410743713379e-06 +4363 4252 164138769.4832 +4364 4252 -1.192092895508e-07 +4365 4252 -1.156330108643e-05 +4366 4252 -83408755.55014 +4367 4252 69374999.9886 +4374 4252 -24305555.56353 +4375 4252 -39081501.55875 +4376 4252 -17343750.0057 +4377 4252 -8.344650268555e-07 +4378 4252 -31882558.21681 +4379 4252 -3.278255462646e-07 +4380 4252 24305555.56353 +4381 4252 -39081501.55875 +4382 4252 17343750.00569 +4253 4253 1165825984.246 +4254 4253 -1.382827758789e-05 +4255 4253 1.788139343262e-07 +4256 4253 104791324.3853 +4263 4253 -2.890825271606e-06 +4264 4253 3.8743019104e-07 +4265 4253 -46719419.49861 +4266 4253 -1.20997428894e-05 +4267 4253 -4.768371582031e-07 +4268 4253 -212506.0825927 +4269 4253 -3.278255462646e-06 +4270 4253 -2.086162567139e-07 +4271 4253 -46719419.49861 +4347 4253 21679861.11823 +4348 4253 -17343750.0057 +4349 4253 -36432062.04359 +4350 4253 86719444.4302 +4351 4253 3.427267074585e-07 +4352 4253 -99061955.12464 +4353 4253 21679861.11823 +4354 4253 17343750.0057 +4355 4253 -36432062.04359 +4359 4253 6.169080734253e-06 +4360 4253 -69374999.9886 +4361 4253 -72810997.49471 +4362 4253 2.598762512207e-05 +4363 4253 5.960464477539e-08 +4364 4253 -104578818.0156 +4365 4253 6.973743438721e-06 +4366 4253 69374999.9886 +4367 4253 -72810997.49471 +4374 4253 -21679861.11823 +4375 4253 -17343750.0057 +4376 4253 -36432062.04358 +4377 4253 -86719444.43019 +4378 4253 -2.682209014893e-07 +4379 4253 -99061955.12461 +4380 4253 -21679861.11823 +4381 4253 17343750.00569 +4382 4253 -36432062.04358 +4254 4254 1483949894.094 +4255 4254 7.867813110352e-06 +4256 4254 -5.507469177246e-05 +4257 4254 184322301.8864 +4258 4254 -2.622604370117e-06 +4259 4254 -1.358985900879e-05 +4266 4254 -148365426.1266 +4267 4254 -97222222.20624 +4268 4254 -3.039836883545e-06 +4269 4254 -406796532.3944 +4270 4254 -2.801418304443e-06 +4271 4254 -1.233816146851e-05 +4272 4254 -148365426.1266 +4273 4254 97222222.20624 +4274 4254 -3.308057785034e-06 +4350 4254 -46373434.23613 +4351 4254 24305555.56354 +4352 4254 21679861.11823 +4353 4254 -138827443.8752 +4354 4254 2.682209014893e-07 +4355 4254 86719444.4302 +4356 4254 -46373434.23614 +4357 4254 -24305555.56354 +4358 4254 21679861.11823 +4362 4254 8952264.76783 +4363 4254 9.298324584961e-06 +4364 4254 6.228685379028e-06 +4365 4254 222474230.8735 +4366 4254 3.933906555176e-06 +4367 4254 2.622604370117e-05 +4368 4254 8952264.76783 +4369 4254 -1.302361488342e-05 +4370 4254 6.914138793945e-06 +4377 4254 -46373434.23611 +4378 4254 -24305555.56353 +4379 4254 -21679861.11823 +4380 4254 -138827443.8751 +4381 4254 -5.066394805908e-07 +4382 4254 -86719444.43019 +4383 4254 -46373434.23611 +4384 4254 24305555.56353 +4385 4254 -21679861.11823 +4255 4255 1250608048.648 +4256 4255 -1.192092895508e-06 +4257 4255 -3.159046173096e-06 +4258 4255 -185121779.2034 +4259 4255 8.046627044678e-07 +4266 4255 -97222222.20624 +4267 4255 -119197695.4315 +4268 4255 2.831220626831e-07 +4269 4255 -3.09944152832e-06 +4270 4255 20983010.02827 +4271 4255 -4.768371582031e-07 +4272 4255 97222222.20624 +4273 4255 -119197695.4315 +4274 4255 -7.450580596924e-08 +4350 4255 24305555.56354 +4351 4255 -39081501.55876 +4352 4255 -17343750.00569 +4353 4255 -2.294778823853e-06 +4354 4255 -31882558.21685 +4355 4255 2.682209014893e-07 +4356 4255 -24305555.56354 +4357 4255 -39081501.55876 +4358 4255 17343750.0057 +4362 4255 1.069903373718e-05 +4363 4255 -83408755.55014 +4364 4255 -69374999.9886 +4365 4255 4.410743713379e-06 +4366 4255 164138769.4832 +4367 4255 -1.192092895508e-07 +4368 4255 -1.156330108643e-05 +4369 4255 -83408755.55014 +4370 4255 69374999.9886 +4377 4255 -24305555.56353 +4378 4255 -39081501.55875 +4379 4255 -17343750.0057 +4380 4255 -8.344650268555e-07 +4381 4255 -31882558.21681 +4382 4255 -3.278255462646e-07 +4383 4255 24305555.56353 +4384 4255 -39081501.55875 +4385 4255 17343750.00569 +4256 4256 1165825984.246 +4257 4256 -1.382827758789e-05 +4258 4256 1.788139343262e-07 +4259 4256 104791324.3853 +4266 4256 -2.890825271606e-06 +4267 4256 3.8743019104e-07 +4268 4256 -46719419.49861 +4269 4256 -1.20997428894e-05 +4270 4256 -4.768371582031e-07 +4271 4256 -212506.0825927 +4272 4256 -3.278255462646e-06 +4273 4256 -2.086162567139e-07 +4274 4256 -46719419.49861 +4350 4256 21679861.11823 +4351 4256 -17343750.0057 +4352 4256 -36432062.04359 +4353 4256 86719444.4302 +4354 4256 3.427267074585e-07 +4355 4256 -99061955.12464 +4356 4256 21679861.11823 +4357 4256 17343750.0057 +4358 4256 -36432062.04359 +4362 4256 6.169080734253e-06 +4363 4256 -69374999.9886 +4364 4256 -72810997.49471 +4365 4256 2.598762512207e-05 +4366 4256 5.960464477539e-08 +4367 4256 -104578818.0156 +4368 4256 6.973743438721e-06 +4369 4256 69374999.9886 +4370 4256 -72810997.49471 +4377 4256 -21679861.11823 +4378 4256 -17343750.0057 +4379 4256 -36432062.04358 +4380 4256 -86719444.43019 +4381 4256 -2.682209014893e-07 +4382 4256 -99061955.12461 +4383 4256 -21679861.11823 +4384 4256 17343750.00569 +4385 4256 -36432062.04358 +4257 4257 1632315315.374 +4258 4257 97222220.26178 +4259 4257 -4.172325134277e-05 +4260 4257 17392720.97666 +4261 4257 -97222221.42845 +4262 4257 -2.145767211914e-06 +4269 4257 -148365426.1266 +4270 4257 -97222222.20624 +4271 4257 -3.039836883545e-06 +4272 4257 -406796532.3944 +4273 4257 -2.801418304443e-06 +4274 4257 -1.233816146851e-05 +4275 4257 -148365426.1266 +4276 4257 97222222.20624 +4277 4257 -3.308057785034e-06 +4353 4257 -46373434.23613 +4354 4257 24305555.56354 +4355 4257 21679861.11823 +4356 4257 -175918799.4897 +4357 4257 -24305555.27186 +4358 4257 86719444.24762 +4365 4257 8952264.76783 +4366 4257 9.298324584961e-06 +4367 4257 6.228685379028e-06 +4368 4257 268847663.9159 +4369 4257 24305555.07742 +4370 4257 0.03653132915497 +4371 4257 -28139091.37671 +4372 4257 -24305555.36909 +4373 4257 21679860.74398 +4380 4257 -46373434.23611 +4381 4257 -24305555.56353 +4382 4257 -21679861.11823 +4383 4257 -138827443.8751 +4384 4257 -5.066394805908e-07 +4385 4257 -86719444.43019 +4386 4257 -46373434.23611 +4387 4257 24305555.56353 +4388 4257 -21679861.11823 +4258 4258 1369805740.108 +4259 4258 -2.145767211914e-06 +4260 4258 -97222221.03956 +4261 4258 -322883627.8625 +4262 4258 4.798173904419e-06 +4269 4258 -97222222.20624 +4270 4258 -119197695.4315 +4271 4258 2.831220626831e-07 +4272 4258 -3.09944152832e-06 +4273 4258 20983010.02827 +4274 4258 -4.768371582031e-07 +4275 4258 97222222.20624 +4276 4258 -119197695.4315 +4277 4258 -7.450580596924e-08 +4353 4258 24305555.56354 +4354 4258 -39081501.55876 +4355 4258 -17343750.00569 +4356 4258 -24305555.36908 +4357 4258 -61681981.7616 +4358 4258 17343749.94043 +4365 4258 1.069903373718e-05 +4366 4258 -83408755.55014 +4367 4258 -69374999.9886 +4368 4258 24305555.07742 +4369 4258 203220270.0671 +4370 4258 0.02920919656754 +4371 4258 -24305555.27186 +4372 4258 -113208178.6284 +4373 4258 69374999.6084 +4380 4258 -24305555.56353 +4381 4258 -39081501.55875 +4382 4258 -17343750.0057 +4383 4258 -8.344650268555e-07 +4384 4258 -31882558.21681 +4385 4258 -3.278255462646e-07 +4386 4258 24305555.56353 +4387 4258 -39081501.55875 +4388 4258 17343750.00569 +4259 4259 1212545401.289 +4260 4259 -1.788139343262e-06 +4261 4259 3.75509262085e-06 +4262 4259 8567490.576108 +4269 4259 -2.890825271606e-06 +4270 4259 3.8743019104e-07 +4271 4259 -46719419.49861 +4272 4259 -1.20997428894e-05 +4273 4259 -4.768371582031e-07 +4274 4259 -212506.0825927 +4275 4259 -3.278255462646e-06 +4276 4259 -2.086162567139e-07 +4277 4259 -46719419.49861 +4353 4259 21679861.11823 +4354 4259 -17343750.0057 +4355 4259 -36432062.04359 +4356 4259 86719444.24762 +4357 4259 17343749.9078 +4358 4259 -110741809.7386 +4365 4259 6.169080734253e-06 +4366 4259 -69374999.9886 +4367 4259 -72810997.49471 +4368 4259 -0.03649973869324 +4369 4259 -0.02921465039253 +4370 4259 -68146756.53808 +4371 4259 21679860.55685 +4372 4259 69374999.49133 +4373 4259 -84490851.68298 +4380 4259 -21679861.11823 +4381 4259 -17343750.0057 +4382 4259 -36432062.04358 +4383 4259 -86719444.43019 +4384 4259 -2.682209014893e-07 +4385 4259 -99061955.12461 +4386 4259 -21679861.11823 +4387 4259 17343750.00569 +4388 4259 -36432062.04358 +4260 4260 927468678.158 +4261 4260 97222222.20623 +4262 4260 -8.106231689453e-06 +4272 4260 -148365426.1266 +4273 4260 -97222222.20624 +4274 4260 -3.039836883545e-06 +4275 4260 -573726109.9308 +4276 4260 -97222221.42845 +4277 4260 8.940696716309e-07 +4278 4260 18564155.00999 +4279 4260 77777776.9872 +4280 4260 2.861022949219e-06 +4356 4260 -9282077.50499 +4357 4260 29166666.38457 +4358 4260 26015832.78049 +4368 4260 -28139091.37673 +4369 4260 -24305555.27187 +4370 4260 -21679860.55685 +4371 4260 139046393.5639 +4372 4260 24305555.56354 +4373 4260 17343888.84952 +4383 4260 -46373434.23611 +4384 4260 -24305555.56353 +4385 4260 -21679861.11823 +4386 4260 -175918799.4896 +4387 4260 -24305555.36909 +4388 4260 -86719444.24762 +4389 4260 -9282077.505002 +4390 4260 19444444.25638 +4391 4260 -17343888.52033 +4261 4261 781630025.6149 +4262 4261 8.412431954121e-06 +4272 4261 -97222222.20624 +4273 4261 -119197695.4315 +4274 4261 2.831220626831e-07 +4275 4261 -97222221.03956 +4276 4261 -116778839.2437 +4277 4261 5.602836608887e-06 +4278 4261 116666665.4808 +4279 4261 18564155.00998 +4280 4261 5.960464477539e-07 +4356 4261 19444444.25638 +4357 4261 -9282077.505 +4358 4261 -13874999.9393 +4368 4261 -24305555.36909 +4369 4261 -113208178.6284 +4370 4261 -69374999.49133 +4371 4261 24305555.56354 +4372 4261 102586730.4102 +4373 4261 13874999.85143 +4383 4261 -24305555.56353 +4384 4261 -39081501.55875 +4385 4261 -17343750.0057 +4386 4261 -24305555.27187 +4387 4261 -61681981.76159 +4388 4261 -17343749.90781 +4389 4261 29166666.38457 +4390 4261 -9282077.504995 +4391 4261 20812499.90894 +4262 4262 728641235.3813 +4272 4262 -2.890825271606e-06 +4273 4262 3.8743019104e-07 +4274 4262 -46719419.49861 +4275 4262 4.172325134277e-07 +4276 4262 4.887580871582e-06 +4277 4262 -96436338.25295 +4278 4262 2.503395080566e-06 +4279 4262 1.251697540283e-06 +4280 4262 49504413.35998 +4356 4262 17343888.52033 +4357 4262 -20812499.90895 +4358 4262 -24752206.67999 +4368 4262 -21679860.74398 +4369 4262 -69374999.6084 +4370 4262 -84490851.68299 +4371 4262 -17343888.84952 +4372 4262 -13874999.85144 +4373 4262 -65361760.6378 +4383 4262 -21679861.11823 +4384 4262 -17343750.0057 +4385 4262 -36432062.04358 +4386 4262 -86719444.24762 +4387 4262 -17343749.94044 +4388 4262 -110741809.7386 +4389 4262 -26015832.7805 +4390 4262 13874999.9393 +4391 4262 -24752206.67999 +4263 4263 1483949894.094 +4264 4263 7.867813110352e-06 +4265 4263 -5.507469177246e-05 +4266 4263 184322301.8864 +4267 4263 -2.622604370117e-06 +4268 4263 -1.358985900879e-05 +4281 4263 -406796532.3944 +4282 4263 -2.801418304443e-06 +4283 4263 -1.233816146851e-05 +4284 4263 -148365426.1266 +4285 4263 97222222.20624 +4286 4263 -3.308057785034e-06 +4359 4263 -138827443.8752 +4360 4263 2.682209014893e-07 +4361 4263 86719444.4302 +4362 4263 -46373434.23614 +4363 4263 -24305555.56354 +4364 4263 21679861.11823 +4374 4263 222474230.8735 +4375 4263 3.933906555176e-06 +4376 4263 2.622604370117e-05 +4377 4263 8952264.76783 +4378 4263 -1.302361488342e-05 +4379 4263 6.914138793945e-06 +4392 4263 -138827443.8751 +4393 4263 -5.066394805908e-07 +4394 4263 -86719444.43019 +4395 4263 -46373434.23611 +4396 4263 24305555.56353 +4397 4263 -21679861.11823 +4264 4264 1250608048.648 +4265 4264 -1.192092895508e-06 +4266 4264 -3.159046173096e-06 +4267 4264 -185121779.2034 +4268 4264 8.046627044678e-07 +4281 4264 -3.09944152832e-06 +4282 4264 20983010.02827 +4283 4264 -4.768371582031e-07 +4284 4264 97222222.20624 +4285 4264 -119197695.4315 +4286 4264 -7.450580596924e-08 +4359 4264 -2.294778823853e-06 +4360 4264 -31882558.21685 +4361 4264 2.682209014893e-07 +4362 4264 -24305555.56354 +4363 4264 -39081501.55876 +4364 4264 17343750.0057 +4374 4264 4.410743713379e-06 +4375 4264 164138769.4832 +4376 4264 -1.192092895508e-07 +4377 4264 -1.156330108643e-05 +4378 4264 -83408755.55014 +4379 4264 69374999.9886 +4392 4264 -8.344650268555e-07 +4393 4264 -31882558.21681 +4394 4264 -3.278255462646e-07 +4395 4264 24305555.56353 +4396 4264 -39081501.55875 +4397 4264 17343750.00569 +4265 4265 1165825984.246 +4266 4265 -1.382827758789e-05 +4267 4265 1.788139343262e-07 +4268 4265 104791324.3853 +4281 4265 -1.20997428894e-05 +4282 4265 -4.768371582031e-07 +4283 4265 -212506.0825927 +4284 4265 -3.278255462646e-06 +4285 4265 -2.086162567139e-07 +4286 4265 -46719419.49861 +4359 4265 86719444.4302 +4360 4265 3.427267074585e-07 +4361 4265 -99061955.12464 +4362 4265 21679861.11823 +4363 4265 17343750.0057 +4364 4265 -36432062.04359 +4374 4265 2.598762512207e-05 +4375 4265 5.960464477539e-08 +4376 4265 -104578818.0156 +4377 4265 6.973743438721e-06 +4378 4265 69374999.9886 +4379 4265 -72810997.49471 +4392 4265 -86719444.43019 +4393 4265 -2.682209014893e-07 +4394 4265 -99061955.12461 +4395 4265 -21679861.11823 +4396 4265 17343750.00569 +4397 4265 -36432062.04358 +4266 4266 1483949894.094 +4267 4266 7.867813110352e-06 +4268 4266 -5.507469177246e-05 +4269 4266 184322301.8864 +4270 4266 -2.622604370117e-06 +4271 4266 -1.358985900879e-05 +4281 4266 -148365426.1266 +4282 4266 -97222222.20624 +4283 4266 -3.039836883545e-06 +4284 4266 -406796532.3944 +4285 4266 -2.801418304443e-06 +4286 4266 -1.233816146851e-05 +4287 4266 -148365426.1266 +4288 4266 97222222.20624 +4289 4266 -3.308057785034e-06 +4359 4266 -46373434.23613 +4360 4266 24305555.56354 +4361 4266 21679861.11823 +4362 4266 -138827443.8752 +4363 4266 2.682209014893e-07 +4364 4266 86719444.4302 +4365 4266 -46373434.23614 +4366 4266 -24305555.56354 +4367 4266 21679861.11823 +4374 4266 8952264.76783 +4375 4266 9.298324584961e-06 +4376 4266 6.228685379028e-06 +4377 4266 222474230.8735 +4378 4266 3.933906555176e-06 +4379 4266 2.622604370117e-05 +4380 4266 8952264.76783 +4381 4266 -1.302361488342e-05 +4382 4266 6.914138793945e-06 +4392 4266 -46373434.23611 +4393 4266 -24305555.56353 +4394 4266 -21679861.11823 +4395 4266 -138827443.8751 +4396 4266 -5.066394805908e-07 +4397 4266 -86719444.43019 +4398 4266 -46373434.23611 +4399 4266 24305555.56353 +4400 4266 -21679861.11823 +4267 4267 1250608048.648 +4268 4267 -1.192092895508e-06 +4269 4267 -3.159046173096e-06 +4270 4267 -185121779.2034 +4271 4267 8.046627044678e-07 +4281 4267 -97222222.20624 +4282 4267 -119197695.4315 +4283 4267 2.831220626831e-07 +4284 4267 -3.09944152832e-06 +4285 4267 20983010.02827 +4286 4267 -4.768371582031e-07 +4287 4267 97222222.20624 +4288 4267 -119197695.4315 +4289 4267 -7.450580596924e-08 +4359 4267 24305555.56354 +4360 4267 -39081501.55876 +4361 4267 -17343750.00569 +4362 4267 -2.294778823853e-06 +4363 4267 -31882558.21685 +4364 4267 2.682209014893e-07 +4365 4267 -24305555.56354 +4366 4267 -39081501.55876 +4367 4267 17343750.0057 +4374 4267 1.069903373718e-05 +4375 4267 -83408755.55014 +4376 4267 -69374999.9886 +4377 4267 4.410743713379e-06 +4378 4267 164138769.4832 +4379 4267 -1.192092895508e-07 +4380 4267 -1.156330108643e-05 +4381 4267 -83408755.55014 +4382 4267 69374999.9886 +4392 4267 -24305555.56353 +4393 4267 -39081501.55875 +4394 4267 -17343750.0057 +4395 4267 -8.344650268555e-07 +4396 4267 -31882558.21681 +4397 4267 -3.278255462646e-07 +4398 4267 24305555.56353 +4399 4267 -39081501.55875 +4400 4267 17343750.00569 +4268 4268 1165825984.246 +4269 4268 -1.382827758789e-05 +4270 4268 1.788139343262e-07 +4271 4268 104791324.3853 +4281 4268 -2.890825271606e-06 +4282 4268 3.8743019104e-07 +4283 4268 -46719419.49861 +4284 4268 -1.20997428894e-05 +4285 4268 -4.768371582031e-07 +4286 4268 -212506.0825927 +4287 4268 -3.278255462646e-06 +4288 4268 -2.086162567139e-07 +4289 4268 -46719419.49861 +4359 4268 21679861.11823 +4360 4268 -17343750.0057 +4361 4268 -36432062.04359 +4362 4268 86719444.4302 +4363 4268 3.427267074585e-07 +4364 4268 -99061955.12464 +4365 4268 21679861.11823 +4366 4268 17343750.0057 +4367 4268 -36432062.04359 +4374 4268 6.169080734253e-06 +4375 4268 -69374999.9886 +4376 4268 -72810997.49471 +4377 4268 2.598762512207e-05 +4378 4268 5.960464477539e-08 +4379 4268 -104578818.0156 +4380 4268 6.973743438721e-06 +4381 4268 69374999.9886 +4382 4268 -72810997.49471 +4392 4268 -21679861.11823 +4393 4268 -17343750.0057 +4394 4268 -36432062.04358 +4395 4268 -86719444.43019 +4396 4268 -2.682209014893e-07 +4397 4268 -99061955.12461 +4398 4268 -21679861.11823 +4399 4268 17343750.00569 +4400 4268 -36432062.04358 +4269 4269 1483949894.094 +4270 4269 7.867813110352e-06 +4271 4269 -5.507469177246e-05 +4272 4269 184322301.8864 +4273 4269 -2.622604370117e-06 +4274 4269 -1.358985900879e-05 +4284 4269 -148365426.1266 +4285 4269 -97222222.20624 +4286 4269 -3.039836883545e-06 +4287 4269 -406796532.3944 +4288 4269 -2.801418304443e-06 +4289 4269 -1.233816146851e-05 +4290 4269 -148365426.1266 +4291 4269 97222222.20624 +4292 4269 -3.308057785034e-06 +4362 4269 -46373434.23613 +4363 4269 24305555.56354 +4364 4269 21679861.11823 +4365 4269 -138827443.8752 +4366 4269 2.682209014893e-07 +4367 4269 86719444.4302 +4368 4269 -46373434.23614 +4369 4269 -24305555.56354 +4370 4269 21679861.11823 +4377 4269 8952264.76783 +4378 4269 9.298324584961e-06 +4379 4269 6.228685379028e-06 +4380 4269 222474230.8735 +4381 4269 3.933906555176e-06 +4382 4269 2.622604370117e-05 +4383 4269 8952264.76783 +4384 4269 -1.302361488342e-05 +4385 4269 6.914138793945e-06 +4395 4269 -46373434.23611 +4396 4269 -24305555.56353 +4397 4269 -21679861.11823 +4398 4269 -138827443.8751 +4399 4269 -5.066394805908e-07 +4400 4269 -86719444.43019 +4401 4269 -46373434.23611 +4402 4269 24305555.56353 +4403 4269 -21679861.11823 +4270 4270 1250608048.648 +4271 4270 -1.192092895508e-06 +4272 4270 -3.159046173096e-06 +4273 4270 -185121779.2034 +4274 4270 8.046627044678e-07 +4284 4270 -97222222.20624 +4285 4270 -119197695.4315 +4286 4270 2.831220626831e-07 +4287 4270 -3.09944152832e-06 +4288 4270 20983010.02827 +4289 4270 -4.768371582031e-07 +4290 4270 97222222.20624 +4291 4270 -119197695.4315 +4292 4270 -7.450580596924e-08 +4362 4270 24305555.56354 +4363 4270 -39081501.55876 +4364 4270 -17343750.00569 +4365 4270 -2.294778823853e-06 +4366 4270 -31882558.21685 +4367 4270 2.682209014893e-07 +4368 4270 -24305555.56354 +4369 4270 -39081501.55876 +4370 4270 17343750.0057 +4377 4270 1.069903373718e-05 +4378 4270 -83408755.55014 +4379 4270 -69374999.9886 +4380 4270 4.410743713379e-06 +4381 4270 164138769.4832 +4382 4270 -1.192092895508e-07 +4383 4270 -1.156330108643e-05 +4384 4270 -83408755.55014 +4385 4270 69374999.9886 +4395 4270 -24305555.56353 +4396 4270 -39081501.55875 +4397 4270 -17343750.0057 +4398 4270 -8.344650268555e-07 +4399 4270 -31882558.21681 +4400 4270 -3.278255462646e-07 +4401 4270 24305555.56353 +4402 4270 -39081501.55875 +4403 4270 17343750.00569 +4271 4271 1165825984.246 +4272 4271 -1.382827758789e-05 +4273 4271 1.788139343262e-07 +4274 4271 104791324.3853 +4284 4271 -2.890825271606e-06 +4285 4271 3.8743019104e-07 +4286 4271 -46719419.49861 +4287 4271 -1.20997428894e-05 +4288 4271 -4.768371582031e-07 +4289 4271 -212506.0825927 +4290 4271 -3.278255462646e-06 +4291 4271 -2.086162567139e-07 +4292 4271 -46719419.49861 +4362 4271 21679861.11823 +4363 4271 -17343750.0057 +4364 4271 -36432062.04359 +4365 4271 86719444.4302 +4366 4271 3.427267074585e-07 +4367 4271 -99061955.12464 +4368 4271 21679861.11823 +4369 4271 17343750.0057 +4370 4271 -36432062.04359 +4377 4271 6.169080734253e-06 +4378 4271 -69374999.9886 +4379 4271 -72810997.49471 +4380 4271 2.598762512207e-05 +4381 4271 5.960464477539e-08 +4382 4271 -104578818.0156 +4383 4271 6.973743438721e-06 +4384 4271 69374999.9886 +4385 4271 -72810997.49471 +4395 4271 -21679861.11823 +4396 4271 -17343750.0057 +4397 4271 -36432062.04358 +4398 4271 -86719444.43019 +4399 4271 -2.682209014893e-07 +4400 4271 -99061955.12461 +4401 4271 -21679861.11823 +4402 4271 17343750.00569 +4403 4271 -36432062.04358 +4272 4272 1483949894.094 +4273 4272 7.867813110352e-06 +4274 4272 -5.507469177246e-05 +4275 4272 184322301.8864 +4276 4272 -2.622604370117e-06 +4277 4272 -1.358985900879e-05 +4287 4272 -148365426.1266 +4288 4272 -97222222.20624 +4289 4272 -3.039836883545e-06 +4290 4272 -406796532.3944 +4291 4272 -2.801418304443e-06 +4292 4272 -1.233816146851e-05 +4293 4272 -148365426.1266 +4294 4272 97222222.20624 +4295 4272 -3.308057785034e-06 +4365 4272 -46373434.23613 +4366 4272 24305555.56354 +4367 4272 21679861.11823 +4368 4272 -138827443.8752 +4369 4272 2.682209014893e-07 +4370 4272 86719444.4302 +4371 4272 -46373434.23614 +4372 4272 -24305555.56354 +4373 4272 21679861.11823 +4380 4272 8952264.76783 +4381 4272 9.298324584961e-06 +4382 4272 6.228685379028e-06 +4383 4272 222474230.8735 +4384 4272 3.933906555176e-06 +4385 4272 2.622604370117e-05 +4386 4272 8952264.76783 +4387 4272 -1.302361488342e-05 +4388 4272 6.914138793945e-06 +4398 4272 -46373434.23611 +4399 4272 -24305555.56353 +4400 4272 -21679861.11823 +4401 4272 -138827443.8751 +4402 4272 -5.066394805908e-07 +4403 4272 -86719444.43019 +4404 4272 -46373434.23611 +4405 4272 24305555.56353 +4406 4272 -21679861.11823 +4273 4273 1250608048.648 +4274 4273 -1.192092895508e-06 +4275 4273 -3.159046173096e-06 +4276 4273 -185121779.2034 +4277 4273 8.046627044678e-07 +4287 4273 -97222222.20624 +4288 4273 -119197695.4315 +4289 4273 2.831220626831e-07 +4290 4273 -3.09944152832e-06 +4291 4273 20983010.02827 +4292 4273 -4.768371582031e-07 +4293 4273 97222222.20624 +4294 4273 -119197695.4315 +4295 4273 -7.450580596924e-08 +4365 4273 24305555.56354 +4366 4273 -39081501.55876 +4367 4273 -17343750.00569 +4368 4273 -2.294778823853e-06 +4369 4273 -31882558.21685 +4370 4273 2.682209014893e-07 +4371 4273 -24305555.56354 +4372 4273 -39081501.55876 +4373 4273 17343750.0057 +4380 4273 1.069903373718e-05 +4381 4273 -83408755.55014 +4382 4273 -69374999.9886 +4383 4273 4.410743713379e-06 +4384 4273 164138769.4832 +4385 4273 -1.192092895508e-07 +4386 4273 -1.156330108643e-05 +4387 4273 -83408755.55014 +4388 4273 69374999.9886 +4398 4273 -24305555.56353 +4399 4273 -39081501.55875 +4400 4273 -17343750.0057 +4401 4273 -8.344650268555e-07 +4402 4273 -31882558.21681 +4403 4273 -3.278255462646e-07 +4404 4273 24305555.56353 +4405 4273 -39081501.55875 +4406 4273 17343750.00569 +4274 4274 1165825984.246 +4275 4274 -1.382827758789e-05 +4276 4274 1.788139343262e-07 +4277 4274 104791324.3853 +4287 4274 -2.890825271606e-06 +4288 4274 3.8743019104e-07 +4289 4274 -46719419.49861 +4290 4274 -1.20997428894e-05 +4291 4274 -4.768371582031e-07 +4292 4274 -212506.0825927 +4293 4274 -3.278255462646e-06 +4294 4274 -2.086162567139e-07 +4295 4274 -46719419.49861 +4365 4274 21679861.11823 +4366 4274 -17343750.0057 +4367 4274 -36432062.04359 +4368 4274 86719444.4302 +4369 4274 3.427267074585e-07 +4370 4274 -99061955.12464 +4371 4274 21679861.11823 +4372 4274 17343750.0057 +4373 4274 -36432062.04359 +4380 4274 6.169080734253e-06 +4381 4274 -69374999.9886 +4382 4274 -72810997.49471 +4383 4274 2.598762512207e-05 +4384 4274 5.960464477539e-08 +4385 4274 -104578818.0156 +4386 4274 6.973743438721e-06 +4387 4274 69374999.9886 +4388 4274 -72810997.49471 +4398 4274 -21679861.11823 +4399 4274 -17343750.0057 +4400 4274 -36432062.04358 +4401 4274 -86719444.43019 +4402 4274 -2.682209014893e-07 +4403 4274 -99061955.12461 +4404 4274 -21679861.11823 +4405 4274 17343750.00569 +4406 4274 -36432062.04358 +4275 4275 1632315315.374 +4276 4275 97222220.26178 +4277 4275 -4.172325134277e-05 +4278 4275 17392720.97666 +4279 4275 -97222221.42845 +4280 4275 -2.145767211914e-06 +4290 4275 -148365426.1266 +4291 4275 -97222222.20624 +4292 4275 -3.039836883545e-06 +4293 4275 -406796532.3944 +4294 4275 -2.801418304443e-06 +4295 4275 -1.233816146851e-05 +4296 4275 -148365426.1266 +4297 4275 97222222.20624 +4298 4275 -3.308057785034e-06 +4368 4275 -46373434.23613 +4369 4275 24305555.56354 +4370 4275 21679861.11823 +4371 4275 -175918799.4897 +4372 4275 -24305555.27186 +4373 4275 86719444.24762 +4383 4275 8952264.76783 +4384 4275 9.298324584961e-06 +4385 4275 6.228685379028e-06 +4386 4275 268847663.9159 +4387 4275 24305555.07742 +4388 4275 0.03653132915497 +4389 4275 -28139091.37671 +4390 4275 -24305555.36909 +4391 4275 21679860.74398 +4401 4275 -46373434.23611 +4402 4275 -24305555.56353 +4403 4275 -21679861.11823 +4404 4275 -138827443.8751 +4405 4275 -5.066394805908e-07 +4406 4275 -86719444.43019 +4407 4275 -46373434.23611 +4408 4275 24305555.56353 +4409 4275 -21679861.11823 +4276 4276 1369805740.108 +4277 4276 -2.145767211914e-06 +4278 4276 -97222221.03956 +4279 4276 -322883627.8625 +4280 4276 4.798173904419e-06 +4290 4276 -97222222.20624 +4291 4276 -119197695.4315 +4292 4276 2.831220626831e-07 +4293 4276 -3.09944152832e-06 +4294 4276 20983010.02827 +4295 4276 -4.768371582031e-07 +4296 4276 97222222.20624 +4297 4276 -119197695.4315 +4298 4276 -7.450580596924e-08 +4368 4276 24305555.56354 +4369 4276 -39081501.55876 +4370 4276 -17343750.00569 +4371 4276 -24305555.36908 +4372 4276 -61681981.7616 +4373 4276 17343749.94043 +4383 4276 1.069903373718e-05 +4384 4276 -83408755.55014 +4385 4276 -69374999.9886 +4386 4276 24305555.07742 +4387 4276 203220270.0671 +4388 4276 0.02920919656754 +4389 4276 -24305555.27186 +4390 4276 -113208178.6284 +4391 4276 69374999.6084 +4401 4276 -24305555.56353 +4402 4276 -39081501.55875 +4403 4276 -17343750.0057 +4404 4276 -8.344650268555e-07 +4405 4276 -31882558.21681 +4406 4276 -3.278255462646e-07 +4407 4276 24305555.56353 +4408 4276 -39081501.55875 +4409 4276 17343750.00569 +4277 4277 1212545401.289 +4278 4277 -1.788139343262e-06 +4279 4277 3.75509262085e-06 +4280 4277 8567490.576108 +4290 4277 -2.890825271606e-06 +4291 4277 3.8743019104e-07 +4292 4277 -46719419.49861 +4293 4277 -1.20997428894e-05 +4294 4277 -4.768371582031e-07 +4295 4277 -212506.0825927 +4296 4277 -3.278255462646e-06 +4297 4277 -2.086162567139e-07 +4298 4277 -46719419.49861 +4368 4277 21679861.11823 +4369 4277 -17343750.0057 +4370 4277 -36432062.04359 +4371 4277 86719444.24762 +4372 4277 17343749.9078 +4373 4277 -110741809.7386 +4383 4277 6.169080734253e-06 +4384 4277 -69374999.9886 +4385 4277 -72810997.49471 +4386 4277 -0.03649973869324 +4387 4277 -0.02921465039253 +4388 4277 -68146756.53808 +4389 4277 21679860.55685 +4390 4277 69374999.49133 +4391 4277 -84490851.68298 +4401 4277 -21679861.11823 +4402 4277 -17343750.0057 +4403 4277 -36432062.04358 +4404 4277 -86719444.43019 +4405 4277 -2.682209014893e-07 +4406 4277 -99061955.12461 +4407 4277 -21679861.11823 +4408 4277 17343750.00569 +4409 4277 -36432062.04358 +4278 4278 944226635.8557 +4279 4278 104813146.3867 +4280 4278 -9.775161743164e-06 +4293 4278 -148365426.1266 +4294 4278 -97222222.20624 +4295 4278 -3.039836883545e-06 +4296 4278 -591818040.3847 +4297 4278 -104813145.6089 +4298 4278 -1.108646392822e-05 +4299 4278 22795227.75345 +4300 4278 77777776.98722 +4301 4278 2.145767211914e-06 +4371 4278 -9282077.50499 +4372 4278 29166666.38457 +4373 4278 26015832.78049 +4386 4278 -28139091.37673 +4387 4278 -24305555.27187 +4388 4278 -21679860.55685 +4389 4278 142149470.4917 +4390 4278 26203286.60958 +4391 4278 17682222.18138 +4404 4278 -46373434.23611 +4405 4278 -24305555.56353 +4406 4278 -21679861.11823 +4407 4278 -180984988.3575 +4408 4278 -26203286.41514 +4409 4278 -88411110.90688 +4410 4278 -8767515.55854 +4411 4278 19444444.25639 +4412 4278 -18020555.17262 +4279 4279 789133337.2837 +4280 4279 2.644956111908e-06 +4293 4279 -97222222.20624 +4294 4279 -119197695.4315 +4295 4279 2.831220626831e-07 +4296 4279 -104813145.22 +4297 4279 -131460786.5969 +4298 4279 -4.768371582031e-07 +4299 4279 116666665.4808 +4300 4279 28639890.68178 +4301 4279 3.576278686523e-07 +4371 4279 19444444.25638 +4372 4279 -9282077.505 +4373 4279 -13874999.9393 +4386 4279 -24305555.36909 +4387 4279 -113208178.6284 +4388 4279 -69374999.49133 +4389 4279 26203286.60958 +4390 4279 103376145.8295 +4391 4279 14145833.18358 +4404 4279 -24305555.56353 +4405 4279 -39081501.55875 +4406 4279 -17343750.0057 +4407 4279 -26203286.31792 +4408 4279 -65895674.85386 +4409 4279 -18697916.56855 +4410 4279 29166666.38458 +4411 4279 -7306349.825737 +4412 4279 20270833.25379 +4280 4280 738330627.0228 +4293 4280 -2.890825271606e-06 +4294 4280 3.8743019104e-07 +4295 4280 -46719419.49861 +4296 4280 -1.20997428894e-05 +4297 4280 -1.192092895508e-07 +4298 4280 -103838327.6491 +4299 4280 2.622604370117e-06 +4300 4280 1.788139343262e-07 +4301 4280 54942611.08087 +4371 4280 17343888.52033 +4372 4280 -20812499.90895 +4373 4280 -24752206.67999 +4386 4280 -21679860.74398 +4387 4280 -69374999.6084 +4388 4280 -84490851.68299 +4389 4280 -17682222.18137 +4390 4280 -14145833.18359 +4391 4280 -65836512.72294 +4404 4280 -21679861.11823 +4405 4280 -17343750.0057 +4406 4280 -36432062.04358 +4407 4280 -88411110.90689 +4408 4280 -18697916.60118 +4409 4280 -114040857.0942 +4410 4280 -27030832.75893 +4411 4280 13062499.95656 +4412 4280 -24841207.22224 +4281 4281 1483949894.094 +4282 4281 7.867813110352e-06 +4283 4281 -5.507469177246e-05 +4284 4281 184322301.8864 +4285 4281 -2.622604370117e-06 +4286 4281 -1.358985900879e-05 +4302 4281 -406796532.3944 +4303 4281 -2.801418304443e-06 +4304 4281 -1.233816146851e-05 +4305 4281 -148365426.1266 +4306 4281 97222222.20624 +4307 4281 -3.308057785034e-06 +4374 4281 -138827443.8752 +4375 4281 2.682209014893e-07 +4376 4281 86719444.4302 +4377 4281 -46373434.23614 +4378 4281 -24305555.56354 +4379 4281 21679861.11823 +4392 4281 222474230.8735 +4393 4281 3.933906555176e-06 +4394 4281 2.622604370117e-05 +4395 4281 8952264.76783 +4396 4281 -1.302361488342e-05 +4397 4281 6.914138793945e-06 +4413 4281 -138827443.8751 +4414 4281 -5.066394805908e-07 +4415 4281 -86719444.43019 +4416 4281 -46373434.23611 +4417 4281 24305555.56353 +4418 4281 -21679861.11823 +4282 4282 1250608048.648 +4283 4282 -1.192092895508e-06 +4284 4282 -3.159046173096e-06 +4285 4282 -185121779.2034 +4286 4282 8.046627044678e-07 +4302 4282 -3.09944152832e-06 +4303 4282 20983010.02827 +4304 4282 -4.768371582031e-07 +4305 4282 97222222.20624 +4306 4282 -119197695.4315 +4307 4282 -7.450580596924e-08 +4374 4282 -2.294778823853e-06 +4375 4282 -31882558.21685 +4376 4282 2.682209014893e-07 +4377 4282 -24305555.56354 +4378 4282 -39081501.55876 +4379 4282 17343750.0057 +4392 4282 4.410743713379e-06 +4393 4282 164138769.4832 +4394 4282 -1.192092895508e-07 +4395 4282 -1.156330108643e-05 +4396 4282 -83408755.55014 +4397 4282 69374999.9886 +4413 4282 -8.344650268555e-07 +4414 4282 -31882558.21681 +4415 4282 -3.278255462646e-07 +4416 4282 24305555.56353 +4417 4282 -39081501.55875 +4418 4282 17343750.00569 +4283 4283 1165825984.246 +4284 4283 -1.382827758789e-05 +4285 4283 1.788139343262e-07 +4286 4283 104791324.3853 +4302 4283 -1.20997428894e-05 +4303 4283 -4.768371582031e-07 +4304 4283 -212506.0825927 +4305 4283 -3.278255462646e-06 +4306 4283 -2.086162567139e-07 +4307 4283 -46719419.49861 +4374 4283 86719444.4302 +4375 4283 3.427267074585e-07 +4376 4283 -99061955.12464 +4377 4283 21679861.11823 +4378 4283 17343750.0057 +4379 4283 -36432062.04359 +4392 4283 2.598762512207e-05 +4393 4283 5.960464477539e-08 +4394 4283 -104578818.0156 +4395 4283 6.973743438721e-06 +4396 4283 69374999.9886 +4397 4283 -72810997.49471 +4413 4283 -86719444.43019 +4414 4283 -2.682209014893e-07 +4415 4283 -99061955.12461 +4416 4283 -21679861.11823 +4417 4283 17343750.00569 +4418 4283 -36432062.04358 +4284 4284 1483949894.094 +4285 4284 7.867813110352e-06 +4286 4284 -5.507469177246e-05 +4287 4284 184322301.8864 +4288 4284 -2.622604370117e-06 +4289 4284 -1.358985900879e-05 +4302 4284 -148365426.1266 +4303 4284 -97222222.20624 +4304 4284 -3.039836883545e-06 +4305 4284 -406796532.3944 +4306 4284 -2.801418304443e-06 +4307 4284 -1.233816146851e-05 +4308 4284 -148365426.1266 +4309 4284 97222222.20624 +4310 4284 -3.308057785034e-06 +4374 4284 -46373434.23613 +4375 4284 24305555.56354 +4376 4284 21679861.11823 +4377 4284 -138827443.8752 +4378 4284 2.682209014893e-07 +4379 4284 86719444.4302 +4380 4284 -46373434.23614 +4381 4284 -24305555.56354 +4382 4284 21679861.11823 +4392 4284 8952264.76783 +4393 4284 9.298324584961e-06 +4394 4284 6.228685379028e-06 +4395 4284 222474230.8735 +4396 4284 3.933906555176e-06 +4397 4284 2.622604370117e-05 +4398 4284 8952264.76783 +4399 4284 -1.302361488342e-05 +4400 4284 6.914138793945e-06 +4413 4284 -46373434.23611 +4414 4284 -24305555.56353 +4415 4284 -21679861.11823 +4416 4284 -138827443.8751 +4417 4284 -5.066394805908e-07 +4418 4284 -86719444.43019 +4419 4284 -46373434.23611 +4420 4284 24305555.56353 +4421 4284 -21679861.11823 +4285 4285 1250608048.648 +4286 4285 -1.192092895508e-06 +4287 4285 -3.159046173096e-06 +4288 4285 -185121779.2034 +4289 4285 8.046627044678e-07 +4302 4285 -97222222.20624 +4303 4285 -119197695.4315 +4304 4285 2.831220626831e-07 +4305 4285 -3.09944152832e-06 +4306 4285 20983010.02827 +4307 4285 -4.768371582031e-07 +4308 4285 97222222.20624 +4309 4285 -119197695.4315 +4310 4285 -7.450580596924e-08 +4374 4285 24305555.56354 +4375 4285 -39081501.55876 +4376 4285 -17343750.00569 +4377 4285 -2.294778823853e-06 +4378 4285 -31882558.21685 +4379 4285 2.682209014893e-07 +4380 4285 -24305555.56354 +4381 4285 -39081501.55876 +4382 4285 17343750.0057 +4392 4285 1.069903373718e-05 +4393 4285 -83408755.55014 +4394 4285 -69374999.9886 +4395 4285 4.410743713379e-06 +4396 4285 164138769.4832 +4397 4285 -1.192092895508e-07 +4398 4285 -1.156330108643e-05 +4399 4285 -83408755.55014 +4400 4285 69374999.9886 +4413 4285 -24305555.56353 +4414 4285 -39081501.55875 +4415 4285 -17343750.0057 +4416 4285 -8.344650268555e-07 +4417 4285 -31882558.21681 +4418 4285 -3.278255462646e-07 +4419 4285 24305555.56353 +4420 4285 -39081501.55875 +4421 4285 17343750.00569 +4286 4286 1165825984.246 +4287 4286 -1.382827758789e-05 +4288 4286 1.788139343262e-07 +4289 4286 104791324.3853 +4302 4286 -2.890825271606e-06 +4303 4286 3.8743019104e-07 +4304 4286 -46719419.49861 +4305 4286 -1.20997428894e-05 +4306 4286 -4.768371582031e-07 +4307 4286 -212506.0825927 +4308 4286 -3.278255462646e-06 +4309 4286 -2.086162567139e-07 +4310 4286 -46719419.49861 +4374 4286 21679861.11823 +4375 4286 -17343750.0057 +4376 4286 -36432062.04359 +4377 4286 86719444.4302 +4378 4286 3.427267074585e-07 +4379 4286 -99061955.12464 +4380 4286 21679861.11823 +4381 4286 17343750.0057 +4382 4286 -36432062.04359 +4392 4286 6.169080734253e-06 +4393 4286 -69374999.9886 +4394 4286 -72810997.49471 +4395 4286 2.598762512207e-05 +4396 4286 5.960464477539e-08 +4397 4286 -104578818.0156 +4398 4286 6.973743438721e-06 +4399 4286 69374999.9886 +4400 4286 -72810997.49471 +4413 4286 -21679861.11823 +4414 4286 -17343750.0057 +4415 4286 -36432062.04358 +4416 4286 -86719444.43019 +4417 4286 -2.682209014893e-07 +4418 4286 -99061955.12461 +4419 4286 -21679861.11823 +4420 4286 17343750.00569 +4421 4286 -36432062.04358 +4287 4287 1483949894.094 +4288 4287 7.867813110352e-06 +4289 4287 -5.507469177246e-05 +4290 4287 184322301.8864 +4291 4287 -2.622604370117e-06 +4292 4287 -1.358985900879e-05 +4305 4287 -148365426.1266 +4306 4287 -97222222.20624 +4307 4287 -3.039836883545e-06 +4308 4287 -406796532.3944 +4309 4287 -2.801418304443e-06 +4310 4287 -1.233816146851e-05 +4311 4287 -148365426.1266 +4312 4287 97222222.20624 +4313 4287 -3.308057785034e-06 +4377 4287 -46373434.23613 +4378 4287 24305555.56354 +4379 4287 21679861.11823 +4380 4287 -138827443.8752 +4381 4287 2.682209014893e-07 +4382 4287 86719444.4302 +4383 4287 -46373434.23614 +4384 4287 -24305555.56354 +4385 4287 21679861.11823 +4395 4287 8952264.76783 +4396 4287 9.298324584961e-06 +4397 4287 6.228685379028e-06 +4398 4287 222474230.8735 +4399 4287 3.933906555176e-06 +4400 4287 2.622604370117e-05 +4401 4287 8952264.76783 +4402 4287 -1.302361488342e-05 +4403 4287 6.914138793945e-06 +4416 4287 -46373434.23611 +4417 4287 -24305555.56353 +4418 4287 -21679861.11823 +4419 4287 -138827443.8751 +4420 4287 -5.066394805908e-07 +4421 4287 -86719444.43019 +4422 4287 -46373434.23611 +4423 4287 24305555.56353 +4424 4287 -21679861.11823 +4288 4288 1250608048.648 +4289 4288 -1.192092895508e-06 +4290 4288 -3.159046173096e-06 +4291 4288 -185121779.2034 +4292 4288 8.046627044678e-07 +4305 4288 -97222222.20624 +4306 4288 -119197695.4315 +4307 4288 2.831220626831e-07 +4308 4288 -3.09944152832e-06 +4309 4288 20983010.02827 +4310 4288 -4.768371582031e-07 +4311 4288 97222222.20624 +4312 4288 -119197695.4315 +4313 4288 -7.450580596924e-08 +4377 4288 24305555.56354 +4378 4288 -39081501.55876 +4379 4288 -17343750.00569 +4380 4288 -2.294778823853e-06 +4381 4288 -31882558.21685 +4382 4288 2.682209014893e-07 +4383 4288 -24305555.56354 +4384 4288 -39081501.55876 +4385 4288 17343750.0057 +4395 4288 1.069903373718e-05 +4396 4288 -83408755.55014 +4397 4288 -69374999.9886 +4398 4288 4.410743713379e-06 +4399 4288 164138769.4832 +4400 4288 -1.192092895508e-07 +4401 4288 -1.156330108643e-05 +4402 4288 -83408755.55014 +4403 4288 69374999.9886 +4416 4288 -24305555.56353 +4417 4288 -39081501.55875 +4418 4288 -17343750.0057 +4419 4288 -8.344650268555e-07 +4420 4288 -31882558.21681 +4421 4288 -3.278255462646e-07 +4422 4288 24305555.56353 +4423 4288 -39081501.55875 +4424 4288 17343750.00569 +4289 4289 1165825984.246 +4290 4289 -1.382827758789e-05 +4291 4289 1.788139343262e-07 +4292 4289 104791324.3853 +4305 4289 -2.890825271606e-06 +4306 4289 3.8743019104e-07 +4307 4289 -46719419.49861 +4308 4289 -1.20997428894e-05 +4309 4289 -4.768371582031e-07 +4310 4289 -212506.0825927 +4311 4289 -3.278255462646e-06 +4312 4289 -2.086162567139e-07 +4313 4289 -46719419.49861 +4377 4289 21679861.11823 +4378 4289 -17343750.0057 +4379 4289 -36432062.04359 +4380 4289 86719444.4302 +4381 4289 3.427267074585e-07 +4382 4289 -99061955.12464 +4383 4289 21679861.11823 +4384 4289 17343750.0057 +4385 4289 -36432062.04359 +4395 4289 6.169080734253e-06 +4396 4289 -69374999.9886 +4397 4289 -72810997.49471 +4398 4289 2.598762512207e-05 +4399 4289 5.960464477539e-08 +4400 4289 -104578818.0156 +4401 4289 6.973743438721e-06 +4402 4289 69374999.9886 +4403 4289 -72810997.49471 +4416 4289 -21679861.11823 +4417 4289 -17343750.0057 +4418 4289 -36432062.04358 +4419 4289 -86719444.43019 +4420 4289 -2.682209014893e-07 +4421 4289 -99061955.12461 +4422 4289 -21679861.11823 +4423 4289 17343750.00569 +4424 4289 -36432062.04358 +4290 4290 1483949894.094 +4291 4290 7.867813110352e-06 +4292 4290 -5.507469177246e-05 +4293 4290 184322301.8864 +4294 4290 -2.622604370117e-06 +4295 4290 -1.358985900879e-05 +4308 4290 -148365426.1266 +4309 4290 -97222222.20624 +4310 4290 -3.039836883545e-06 +4311 4290 -406796532.3944 +4312 4290 -2.801418304443e-06 +4313 4290 -1.233816146851e-05 +4314 4290 -148365426.1266 +4315 4290 97222222.20624 +4316 4290 -3.308057785034e-06 +4380 4290 -46373434.23613 +4381 4290 24305555.56354 +4382 4290 21679861.11823 +4383 4290 -138827443.8752 +4384 4290 2.682209014893e-07 +4385 4290 86719444.4302 +4386 4290 -46373434.23614 +4387 4290 -24305555.56354 +4388 4290 21679861.11823 +4398 4290 8952264.76783 +4399 4290 9.298324584961e-06 +4400 4290 6.228685379028e-06 +4401 4290 222474230.8735 +4402 4290 3.933906555176e-06 +4403 4290 2.622604370117e-05 +4404 4290 8952264.76783 +4405 4290 -1.302361488342e-05 +4406 4290 6.914138793945e-06 +4419 4290 -46373434.23611 +4420 4290 -24305555.56353 +4421 4290 -21679861.11823 +4422 4290 -138827443.8751 +4423 4290 -5.066394805908e-07 +4424 4290 -86719444.43019 +4425 4290 -46373434.23611 +4426 4290 24305555.56353 +4427 4290 -21679861.11823 +4291 4291 1250608048.648 +4292 4291 -1.192092895508e-06 +4293 4291 -3.159046173096e-06 +4294 4291 -185121779.2034 +4295 4291 8.046627044678e-07 +4308 4291 -97222222.20624 +4309 4291 -119197695.4315 +4310 4291 2.831220626831e-07 +4311 4291 -3.09944152832e-06 +4312 4291 20983010.02827 +4313 4291 -4.768371582031e-07 +4314 4291 97222222.20624 +4315 4291 -119197695.4315 +4316 4291 -7.450580596924e-08 +4380 4291 24305555.56354 +4381 4291 -39081501.55876 +4382 4291 -17343750.00569 +4383 4291 -2.294778823853e-06 +4384 4291 -31882558.21685 +4385 4291 2.682209014893e-07 +4386 4291 -24305555.56354 +4387 4291 -39081501.55876 +4388 4291 17343750.0057 +4398 4291 1.069903373718e-05 +4399 4291 -83408755.55014 +4400 4291 -69374999.9886 +4401 4291 4.410743713379e-06 +4402 4291 164138769.4832 +4403 4291 -1.192092895508e-07 +4404 4291 -1.156330108643e-05 +4405 4291 -83408755.55014 +4406 4291 69374999.9886 +4419 4291 -24305555.56353 +4420 4291 -39081501.55875 +4421 4291 -17343750.0057 +4422 4291 -8.344650268555e-07 +4423 4291 -31882558.21681 +4424 4291 -3.278255462646e-07 +4425 4291 24305555.56353 +4426 4291 -39081501.55875 +4427 4291 17343750.00569 +4292 4292 1165825984.246 +4293 4292 -1.382827758789e-05 +4294 4292 1.788139343262e-07 +4295 4292 104791324.3853 +4308 4292 -2.890825271606e-06 +4309 4292 3.8743019104e-07 +4310 4292 -46719419.49861 +4311 4292 -1.20997428894e-05 +4312 4292 -4.768371582031e-07 +4313 4292 -212506.0825927 +4314 4292 -3.278255462646e-06 +4315 4292 -2.086162567139e-07 +4316 4292 -46719419.49861 +4380 4292 21679861.11823 +4381 4292 -17343750.0057 +4382 4292 -36432062.04359 +4383 4292 86719444.4302 +4384 4292 3.427267074585e-07 +4385 4292 -99061955.12464 +4386 4292 21679861.11823 +4387 4292 17343750.0057 +4388 4292 -36432062.04359 +4398 4292 6.169080734253e-06 +4399 4292 -69374999.9886 +4400 4292 -72810997.49471 +4401 4292 2.598762512207e-05 +4402 4292 5.960464477539e-08 +4403 4292 -104578818.0156 +4404 4292 6.973743438721e-06 +4405 4292 69374999.9886 +4406 4292 -72810997.49471 +4419 4292 -21679861.11823 +4420 4292 -17343750.0057 +4421 4292 -36432062.04358 +4422 4292 -86719444.43019 +4423 4292 -2.682209014893e-07 +4424 4292 -99061955.12461 +4425 4292 -21679861.11823 +4426 4292 17343750.00569 +4427 4292 -36432062.04358 +4293 4293 1483949894.094 +4294 4293 7.867813110352e-06 +4295 4293 -5.507469177246e-05 +4296 4293 184322301.8864 +4297 4293 -2.622604370117e-06 +4298 4293 -1.358985900879e-05 +4311 4293 -148365426.1266 +4312 4293 -97222222.20624 +4313 4293 -3.039836883545e-06 +4314 4293 -406796532.3944 +4315 4293 -2.801418304443e-06 +4316 4293 -1.233816146851e-05 +4317 4293 -148365426.1266 +4318 4293 97222222.20624 +4319 4293 -3.308057785034e-06 +4383 4293 -46373434.23613 +4384 4293 24305555.56354 +4385 4293 21679861.11823 +4386 4293 -138827443.8752 +4387 4293 2.682209014893e-07 +4388 4293 86719444.4302 +4389 4293 -46373434.23614 +4390 4293 -24305555.56354 +4391 4293 21679861.11823 +4401 4293 8952264.76783 +4402 4293 9.298324584961e-06 +4403 4293 6.228685379028e-06 +4404 4293 222474230.8735 +4405 4293 3.933906555176e-06 +4406 4293 2.622604370117e-05 +4407 4293 8952264.76783 +4408 4293 -1.302361488342e-05 +4409 4293 6.914138793945e-06 +4422 4293 -46373434.23611 +4423 4293 -24305555.56353 +4424 4293 -21679861.11823 +4425 4293 -138827443.8751 +4426 4293 -5.066394805908e-07 +4427 4293 -86719444.43019 +4428 4293 -46373434.23611 +4429 4293 24305555.56353 +4430 4293 -21679861.11823 +4294 4294 1250608048.648 +4295 4294 -1.192092895508e-06 +4296 4294 -3.159046173096e-06 +4297 4294 -185121779.2034 +4298 4294 8.046627044678e-07 +4311 4294 -97222222.20624 +4312 4294 -119197695.4315 +4313 4294 2.831220626831e-07 +4314 4294 -3.09944152832e-06 +4315 4294 20983010.02827 +4316 4294 -4.768371582031e-07 +4317 4294 97222222.20624 +4318 4294 -119197695.4315 +4319 4294 -7.450580596924e-08 +4383 4294 24305555.56354 +4384 4294 -39081501.55876 +4385 4294 -17343750.00569 +4386 4294 -2.294778823853e-06 +4387 4294 -31882558.21685 +4388 4294 2.682209014893e-07 +4389 4294 -24305555.56354 +4390 4294 -39081501.55876 +4391 4294 17343750.0057 +4401 4294 1.069903373718e-05 +4402 4294 -83408755.55014 +4403 4294 -69374999.9886 +4404 4294 4.410743713379e-06 +4405 4294 164138769.4832 +4406 4294 -1.192092895508e-07 +4407 4294 -1.156330108643e-05 +4408 4294 -83408755.55014 +4409 4294 69374999.9886 +4422 4294 -24305555.56353 +4423 4294 -39081501.55875 +4424 4294 -17343750.0057 +4425 4294 -8.344650268555e-07 +4426 4294 -31882558.21681 +4427 4294 -3.278255462646e-07 +4428 4294 24305555.56353 +4429 4294 -39081501.55875 +4430 4294 17343750.00569 +4295 4295 1165825984.246 +4296 4295 -1.382827758789e-05 +4297 4295 1.788139343262e-07 +4298 4295 104791324.3853 +4311 4295 -2.890825271606e-06 +4312 4295 3.8743019104e-07 +4313 4295 -46719419.49861 +4314 4295 -1.20997428894e-05 +4315 4295 -4.768371582031e-07 +4316 4295 -212506.0825927 +4317 4295 -3.278255462646e-06 +4318 4295 -2.086162567139e-07 +4319 4295 -46719419.49861 +4383 4295 21679861.11823 +4384 4295 -17343750.0057 +4385 4295 -36432062.04359 +4386 4295 86719444.4302 +4387 4295 3.427267074585e-07 +4388 4295 -99061955.12464 +4389 4295 21679861.11823 +4390 4295 17343750.0057 +4391 4295 -36432062.04359 +4401 4295 6.169080734253e-06 +4402 4295 -69374999.9886 +4403 4295 -72810997.49471 +4404 4295 2.598762512207e-05 +4405 4295 5.960464477539e-08 +4406 4295 -104578818.0156 +4407 4295 6.973743438721e-06 +4408 4295 69374999.9886 +4409 4295 -72810997.49471 +4422 4295 -21679861.11823 +4423 4295 -17343750.0057 +4424 4295 -36432062.04358 +4425 4295 -86719444.43019 +4426 4295 -2.682209014893e-07 +4427 4295 -99061955.12461 +4428 4295 -21679861.11823 +4429 4295 17343750.00569 +4430 4295 -36432062.04358 +4296 4296 1661147708.834 +4297 4296 104975994.3213 +4298 4296 -3.504753112793e-05 +4299 4296 28973926.47989 +4300 4296 -93442034.30675 +4301 4296 -1.907348632813e-06 +4314 4296 -148365426.1266 +4315 4296 -97222222.20624 +4316 4296 -3.039836883545e-06 +4317 4296 -414750020.4148 +4318 4296 -3811573.076203 +4319 4296 -6.437301635742e-06 +4320 4296 -158390003.058 +4321 4296 97090758.28167 +4322 4296 3.248453140259e-06 +4386 4296 -46373434.23613 +4387 4296 24305555.56354 +4388 4296 21679861.11823 +4389 4296 -180984988.3575 +4390 4296 -26203286.31792 +4391 4296 88411110.90689 +4404 4296 8952264.76783 +4405 4296 9.298324584961e-06 +4406 4296 6.228685379028e-06 +4407 4296 274245586.3935 +4408 4296 26243998.59327 +4409 4296 0.03795969486237 +4410 4296 -25967702.04294 +4411 4296 -23360508.5882 +4412 4296 21679166.28526 +4425 4296 -46373434.23611 +4426 4296 -24305555.56353 +4427 4296 -21679861.11823 +4428 4296 -140996480.1669 +4429 4296 -952893.2695213 +4430 4296 -87564583.31886 +4431 4296 -48879322.66664 +4432 4296 24272689.58238 +4433 4296 -22525694.45184 +4297 4297 1378316574.243 +4298 4297 9.655952453613e-06 +4299 4297 -93442033.91786 +4300 4297 -311076053.7847 +4301 4297 -7.063150405884e-06 +4314 4297 -97222222.20624 +4315 4297 -119197695.4315 +4316 4297 2.831220626831e-07 +4317 4297 -3811573.07621 +4318 4297 16672797.27745 +4319 4297 3.218650817871e-06 +4320 4297 97090758.28167 +4321 4297 -116180339.9824 +4322 4297 -6.705522537231e-07 +4386 4297 24305555.56354 +4387 4297 -39081501.55876 +4388 4297 -17343750.00569 +4389 4297 -26203286.41514 +4390 4297 -65895674.85388 +4391 4297 18697916.60118 +4404 4297 1.069903373718e-05 +4405 4297 -83408755.55014 +4406 4297 -69374999.9886 +4407 4297 26243998.59326 +4408 4297 203537802.7108 +4409 4297 0.03035727143288 +4410 4297 -23360508.49098 +4411 4297 -110980197.151 +4412 4297 69374999.59697 +4425 4297 -24305555.56353 +4426 4297 -39081501.55875 +4427 4297 -17343750.0057 +4428 4297 -952893.2695255 +4429 4297 -33140775.69073 +4430 4297 -677083.3331553 +4431 4297 24272689.58238 +4432 4297 -38326906.89252 +4433 4297 16666666.67214 +4298 4298 1227849607.294 +4299 4298 -9.536743164063e-07 +4300 4298 -7.063150405884e-06 +4301 4298 16993676.64505 +4314 4298 -2.890825271606e-06 +4315 4298 3.8743019104e-07 +4316 4298 -46719419.49861 +4317 4298 -8.046627044678e-06 +4318 4298 3.457069396973e-06 +4319 4298 -3046182.050696 +4320 4298 3.159046173096e-06 +4321 4298 -7.599592208862e-07 +4322 4298 -48631203.38772 +4386 4298 21679861.11823 +4387 4298 -17343750.0057 +4388 4298 -36432062.04359 +4389 4298 88411110.90689 +4390 4298 18697916.56855 +4391 4298 -114040857.0942 +4404 4298 6.169080734253e-06 +4405 4298 -69374999.9886 +4406 4298 -72810997.49471 +4407 4298 -0.03792124986649 +4408 4298 -0.03034713864326 +4409 4298 -69147840.74458 +4410 4298 21679166.091 +4411 4298 69374999.47419 +4412 4298 -84314737.28059 +4425 4298 -21679861.11823 +4426 4298 -17343750.0057 +4427 4298 -36432062.04358 +4428 4298 -87564583.31903 +4429 4298 -677083.3332887 +4430 4298 -100252145.5455 +4431 4298 -22525694.45184 +4432 4298 16666666.67214 +4433 4298 -36909325.87324 +4299 4299 878310888.4809 +4300 4299 -2657515.757646 +4301 4299 4.768371582031e-07 +4317 4299 -146355658.7119 +4318 4299 -97205456.75096 +4319 4299 -3.725290298462e-06 +4320 4299 -422227983.6708 +4321 4299 -5136049.023841 +4322 4299 -4.172325134277e-07 +4323 4299 85600144.70804 +4324 4299 -16771033.13002 +4325 4299 -1.668930053711e-06 +4326 4299 -156881939.5358 +4327 4299 98545423.09949 +4328 4299 3.606081008911e-06 +4389 4299 -8767515.558542 +4390 4299 29166666.38458 +4391 4299 27030832.75893 +4407 4299 -25967702.04296 +4408 4299 -23360508.49098 +4409 4299 -21679166.091 +4410 4299 119740849.7095 +4411 4299 -664378.9397371 +4412 4299 17135277.77496 +4428 4299 -45870736.57862 +4429 4299 -24301364.19972 +4430 4299 -21679166.67379 +4431 4299 -141002035.2672 +4432 4299 -1284012.256597 +4433 4299 -85676388.87482 +4434 4299 4511607.610503 +4435 4299 -4192758.28457 +4436 4299 3215972.223777 +4437 4299 -47751770.62456 +4438 4299 24636355.78701 +4439 4299 -21159027.78473 +4300 4300 904404472.7404 +4301 4300 1.704692840576e-05 +4317 4300 -97205456.75096 +4318 4300 -119802374.1365 +4319 4300 -1.087784767151e-06 +4320 4300 -5136049.02384 +4321 4300 9983783.088483 +4322 4300 6.914138793945e-06 +4323 4300 22117855.75248 +4324 4300 -98572068.66135 +4325 4300 -4.559755325317e-06 +4326 4300 98545423.09949 +4327 4300 -123363044.4243 +4328 4300 -8.940696716309e-07 +4389 4300 19444444.25639 +4390 4300 -7306349.825739 +4391 4300 -13062499.95656 +4407 4300 -23360508.5882 +4408 4300 -110980197.151 +4409 4300 -69374999.4742 +4410 4300 -664378.9397382 +4411 4300 126264245.7776 +4412 4300 7208333.185874 +4428 4300 -24301364.19972 +4429 4300 -39232415.43152 +4430 4300 -17343750.0057 +4431 4300 -1284012.256597 +4432 4300 -32949093.52409 +4433 4300 -677083.3331551 +4434 4300 5529463.940846 +4435 4300 -41531445.75454 +4436 4300 33333333.32785 +4437 4300 24636355.78701 +4438 4300 -39372046.84256 +4439 4300 16666666.67214 +4301 4301 768562010.6434 +4317 4301 -3.784894943237e-06 +4318 4301 -9.536743164063e-07 +4319 4301 -46336936.97172 +4320 4301 -1.788139343262e-07 +4321 4301 7.092952728271e-06 +4322 4301 -12181640.54615 +4323 4301 3.576278686523e-07 +4324 4301 -4.827976226807e-06 +4325 4301 44227455.09152 +4326 4301 3.159046173096e-06 +4327 4301 -9.089708328247e-07 +4328 4301 -52301561.2662 +4389 4301 18020555.17262 +4390 4301 -20270833.25379 +4391 4301 -24841207.22225 +4407 4301 -21679166.28527 +4408 4301 -69374999.59699 +4409 4301 -84314737.28064 +4410 4301 -17135277.77496 +4411 4301 -7208333.185859 +4412 4301 -74091157.29502 +4428 4301 -21679166.67379 +4429 4301 -17343750.0057 +4430 4301 -36335759.26896 +4431 4301 -85676388.87482 +4432 4301 -677083.3332886 +4433 4301 -97565514.93121 +4434 4301 -4909027.779057 +4435 4301 33333333.32785 +4436 4301 -33978945.76048 +4437 4301 -21159027.78473 +4438 4301 16666666.67214 +4439 4301 -35825485.57976 +4302 4302 741974947.0469 +4303 4302 5.006790161133e-06 +4304 4302 -2.908706665039e-05 +4305 4302 92161150.94322 +4306 4302 19444444.44125 +4307 4302 -7.271766662598e-06 +4392 4302 -138827443.8752 +4393 4302 2.682209014893e-07 +4394 4302 86719444.4302 +4395 4302 -46373434.23614 +4396 4302 -24305555.56354 +4397 4302 21679861.11823 +4413 4302 111237115.4367 +4414 4302 -8.344650268555e-07 +4415 4302 -17343888.88603 +4416 4302 4476132.383917 +4417 4302 4861111.1127 +4418 4302 -4335972.223642 +4303 4303 625304024.3239 +4304 4303 6.198883056641e-06 +4305 4303 -19444444.44125 +4306 4303 -92560889.60172 +4307 4303 2.32458114624e-06 +4392 4303 -2.294778823853e-06 +4393 4303 -31882558.21685 +4394 4303 2.682209014893e-07 +4395 4303 -24305555.56354 +4396 4303 -39081501.55876 +4397 4303 17343750.0057 +4413 4303 -7.152557373047e-07 +4414 4303 82069384.74161 +4415 4303 -3.75509262085e-06 +4416 4303 -4861111.112713 +4417 4303 -41704377.77507 +4418 4303 34687499.9943 +4304 4304 582912992.1231 +4305 4304 -7.271766662598e-06 +4306 4304 1.877546310425e-06 +4307 4304 52395662.19267 +4392 4304 86719444.4302 +4393 4304 3.427267074585e-07 +4394 4304 -99061955.12464 +4395 4304 21679861.11823 +4396 4304 17343750.0057 +4397 4304 -36432062.04359 +4413 4304 17343888.88605 +4414 4304 -3.576278686523e-06 +4415 4304 -52289409.00778 +4416 4304 4335972.22365 +4417 4304 34687499.9943 +4418 4304 -36405498.74735 +4305 4305 741974947.0469 +4306 4305 5.006790161133e-06 +4307 4305 -2.908706665039e-05 +4308 4305 92161150.94322 +4309 4305 19444444.44125 +4310 4305 -7.271766662598e-06 +4392 4305 -46373434.23613 +4393 4305 24305555.56354 +4394 4305 21679861.11823 +4395 4305 -138827443.8752 +4396 4305 2.682209014893e-07 +4397 4305 86719444.4302 +4398 4305 -46373434.23614 +4399 4305 -24305555.56354 +4400 4305 21679861.11823 +4413 4305 4476132.383914 +4414 4305 -4861111.112702 +4415 4305 -4335972.223643 +4416 4305 111237115.4367 +4417 4305 -8.344650268555e-07 +4418 4305 -17343888.88603 +4419 4305 4476132.383917 +4420 4305 4861111.1127 +4421 4305 -4335972.223642 +4306 4306 625304024.3239 +4307 4306 6.198883056641e-06 +4308 4306 -19444444.44125 +4309 4306 -92560889.60172 +4310 4306 2.32458114624e-06 +4392 4306 24305555.56354 +4393 4306 -39081501.55876 +4394 4306 -17343750.00569 +4395 4306 -2.294778823853e-06 +4396 4306 -31882558.21685 +4397 4306 2.682209014893e-07 +4398 4306 -24305555.56354 +4399 4306 -39081501.55876 +4400 4306 17343750.0057 +4413 4306 4861111.112712 +4414 4306 -41704377.77507 +4415 4306 -34687499.9943 +4416 4306 -7.152557373047e-07 +4417 4306 82069384.74161 +4418 4306 -3.75509262085e-06 +4419 4306 -4861111.112713 +4420 4306 -41704377.77507 +4421 4306 34687499.9943 +4307 4307 582912992.1231 +4308 4307 -7.271766662598e-06 +4309 4307 1.877546310425e-06 +4310 4307 52395662.19267 +4392 4307 21679861.11823 +4393 4307 -17343750.0057 +4394 4307 -36432062.04359 +4395 4307 86719444.4302 +4396 4307 3.427267074585e-07 +4397 4307 -99061955.12464 +4398 4307 21679861.11823 +4399 4307 17343750.0057 +4400 4307 -36432062.04359 +4413 4307 4335972.223649 +4414 4307 -34687499.9943 +4415 4307 -36405498.74736 +4416 4307 17343888.88605 +4417 4307 -3.576278686523e-06 +4418 4307 -52289409.00778 +4419 4307 4335972.22365 +4420 4307 34687499.9943 +4421 4307 -36405498.74735 +4308 4308 741974947.0469 +4309 4308 5.006790161133e-06 +4310 4308 -2.908706665039e-05 +4311 4308 92161150.94322 +4312 4308 19444444.44125 +4313 4308 -7.271766662598e-06 +4395 4308 -46373434.23613 +4396 4308 24305555.56354 +4397 4308 21679861.11823 +4398 4308 -138827443.8752 +4399 4308 2.682209014893e-07 +4400 4308 86719444.4302 +4401 4308 -46373434.23614 +4402 4308 -24305555.56354 +4403 4308 21679861.11823 +4416 4308 4476132.383914 +4417 4308 -4861111.112702 +4418 4308 -4335972.223643 +4419 4308 111237115.4367 +4420 4308 -8.344650268555e-07 +4421 4308 -17343888.88603 +4422 4308 4476132.383917 +4423 4308 4861111.1127 +4424 4308 -4335972.223642 +4309 4309 625304024.3239 +4310 4309 6.198883056641e-06 +4311 4309 -19444444.44125 +4312 4309 -92560889.60172 +4313 4309 2.32458114624e-06 +4395 4309 24305555.56354 +4396 4309 -39081501.55876 +4397 4309 -17343750.00569 +4398 4309 -2.294778823853e-06 +4399 4309 -31882558.21685 +4400 4309 2.682209014893e-07 +4401 4309 -24305555.56354 +4402 4309 -39081501.55876 +4403 4309 17343750.0057 +4416 4309 4861111.112712 +4417 4309 -41704377.77507 +4418 4309 -34687499.9943 +4419 4309 -7.152557373047e-07 +4420 4309 82069384.74161 +4421 4309 -3.75509262085e-06 +4422 4309 -4861111.112713 +4423 4309 -41704377.77507 +4424 4309 34687499.9943 +4310 4310 582912992.1231 +4311 4310 -7.271766662598e-06 +4312 4310 1.877546310425e-06 +4313 4310 52395662.19267 +4395 4310 21679861.11823 +4396 4310 -17343750.0057 +4397 4310 -36432062.04359 +4398 4310 86719444.4302 +4399 4310 3.427267074585e-07 +4400 4310 -99061955.12464 +4401 4310 21679861.11823 +4402 4310 17343750.0057 +4403 4310 -36432062.04359 +4416 4310 4335972.223649 +4417 4310 -34687499.9943 +4418 4310 -36405498.74736 +4419 4310 17343888.88605 +4420 4310 -3.576278686523e-06 +4421 4310 -52289409.00778 +4422 4310 4335972.22365 +4423 4310 34687499.9943 +4424 4310 -36405498.74735 +4311 4311 741974947.0469 +4312 4311 5.006790161133e-06 +4313 4311 -2.908706665039e-05 +4314 4311 92161150.94322 +4315 4311 19444444.44125 +4316 4311 -7.271766662598e-06 +4398 4311 -46373434.23613 +4399 4311 24305555.56354 +4400 4311 21679861.11823 +4401 4311 -138827443.8752 +4402 4311 2.682209014893e-07 +4403 4311 86719444.4302 +4404 4311 -46373434.23614 +4405 4311 -24305555.56354 +4406 4311 21679861.11823 +4419 4311 4476132.383914 +4420 4311 -4861111.112702 +4421 4311 -4335972.223643 +4422 4311 111237115.4367 +4423 4311 -8.344650268555e-07 +4424 4311 -17343888.88603 +4425 4311 4476132.383917 +4426 4311 4861111.1127 +4427 4311 -4335972.223642 +4312 4312 625304024.3239 +4313 4312 6.198883056641e-06 +4314 4312 -19444444.44125 +4315 4312 -92560889.60172 +4316 4312 2.32458114624e-06 +4398 4312 24305555.56354 +4399 4312 -39081501.55876 +4400 4312 -17343750.00569 +4401 4312 -2.294778823853e-06 +4402 4312 -31882558.21685 +4403 4312 2.682209014893e-07 +4404 4312 -24305555.56354 +4405 4312 -39081501.55876 +4406 4312 17343750.0057 +4419 4312 4861111.112712 +4420 4312 -41704377.77507 +4421 4312 -34687499.9943 +4422 4312 -7.152557373047e-07 +4423 4312 82069384.74161 +4424 4312 -3.75509262085e-06 +4425 4312 -4861111.112713 +4426 4312 -41704377.77507 +4427 4312 34687499.9943 +4313 4313 582912992.1231 +4314 4313 -7.271766662598e-06 +4315 4313 1.877546310425e-06 +4316 4313 52395662.19267 +4398 4313 21679861.11823 +4399 4313 -17343750.0057 +4400 4313 -36432062.04359 +4401 4313 86719444.4302 +4402 4313 3.427267074585e-07 +4403 4313 -99061955.12464 +4404 4313 21679861.11823 +4405 4313 17343750.0057 +4406 4313 -36432062.04359 +4419 4313 4335972.223649 +4420 4313 -34687499.9943 +4421 4313 -36405498.74736 +4422 4313 17343888.88605 +4423 4313 -3.576278686523e-06 +4424 4313 -52289409.00778 +4425 4313 4335972.22365 +4426 4313 34687499.9943 +4427 4313 -36405498.74735 +4314 4314 741974947.0469 +4315 4314 5.006790161133e-06 +4316 4314 -2.908706665039e-05 +4317 4314 92161150.94322 +4318 4314 19444444.44125 +4319 4314 -7.271766662598e-06 +4401 4314 -46373434.23613 +4402 4314 24305555.56354 +4403 4314 21679861.11823 +4404 4314 -138827443.8752 +4405 4314 2.682209014893e-07 +4406 4314 86719444.4302 +4407 4314 -46373434.23614 +4408 4314 -24305555.56354 +4409 4314 21679861.11823 +4422 4314 4476132.383914 +4423 4314 -4861111.112702 +4424 4314 -4335972.223643 +4425 4314 111237115.4367 +4426 4314 -8.344650268555e-07 +4427 4314 -17343888.88603 +4428 4314 4476132.383917 +4429 4314 4861111.1127 +4430 4314 -4335972.223642 +4315 4315 625304024.3239 +4316 4315 6.198883056641e-06 +4317 4315 -19444444.44125 +4318 4315 -92560889.60172 +4319 4315 2.32458114624e-06 +4401 4315 24305555.56354 +4402 4315 -39081501.55876 +4403 4315 -17343750.00569 +4404 4315 -2.294778823853e-06 +4405 4315 -31882558.21685 +4406 4315 2.682209014893e-07 +4407 4315 -24305555.56354 +4408 4315 -39081501.55876 +4409 4315 17343750.0057 +4422 4315 4861111.112712 +4423 4315 -41704377.77507 +4424 4315 -34687499.9943 +4425 4315 -7.152557373047e-07 +4426 4315 82069384.74161 +4427 4315 -3.75509262085e-06 +4428 4315 -4861111.112713 +4429 4315 -41704377.77507 +4430 4315 34687499.9943 +4316 4316 582912992.1231 +4317 4316 -7.271766662598e-06 +4318 4316 1.877546310425e-06 +4319 4316 52395662.19267 +4401 4316 21679861.11823 +4402 4316 -17343750.0057 +4403 4316 -36432062.04359 +4404 4316 86719444.4302 +4405 4316 3.427267074585e-07 +4406 4316 -99061955.12464 +4407 4316 21679861.11823 +4408 4316 17343750.0057 +4409 4316 -36432062.04359 +4422 4316 4335972.223649 +4423 4316 -34687499.9943 +4424 4316 -36405498.74736 +4425 4316 17343888.88605 +4426 4316 -3.576278686523e-06 +4427 4316 -52289409.00778 +4428 4316 4335972.22365 +4429 4316 34687499.9943 +4430 4316 -36405498.74735 +4317 4317 743972693.3092 +4318 4317 15895.84579444 +4319 4317 -1.430511474609e-05 +4320 4317 96103889.57229 +4321 4317 23223356.21638 +4322 4317 9.536743164063e-07 +4404 4317 -46373434.23613 +4405 4317 24305555.56354 +4406 4317 21679861.11823 +4407 4317 -140996480.167 +4408 4317 -952893.2695191 +4409 4317 87564583.31904 +4410 4317 -45870736.57862 +4411 4317 -24301364.19971 +4412 4317 21679166.67378 +4425 4317 4476132.383914 +4426 4317 -4861111.112702 +4427 4317 -4335972.223643 +4428 4317 111737658.2526 +4429 4317 3973.961452007 +4430 4317 -17343611.10825 +4431 4317 5643546.059508 +4432 4317 5805839.056957 +4433 4317 -5182361.11248 +4318 4318 624700330.4184 +4319 4318 1.120567321777e-05 +4320 4318 -15665532.66612 +4321 4318 -87045539.95468 +4322 4318 1.788139343262e-07 +4404 4318 24305555.56354 +4405 4318 -39081501.55876 +4406 4318 -17343750.00569 +4407 4318 -952893.2695192 +4408 4318 -33140775.69075 +4409 4318 677083.3332889 +4410 4318 -24301364.19971 +4411 4318 -39232415.43151 +4412 4318 17343750.00569 +4425 4318 4861111.112712 +4426 4318 -41704377.77507 +4427 4318 -34687499.9943 +4428 4318 3973.961451173 +4429 4318 81919567.51518 +4430 4318 -3.188848495483e-06 +4431 4318 -3916383.168459 +4432 4318 -40143811.34479 +4433 4318 34010416.66101 +4319 4319 583290059.4325 +4320 4319 5.960464477539e-07 +4322 4319 54461159.75298 +4404 4319 21679861.11823 +4405 4319 -17343750.0057 +4406 4319 -36432062.04359 +4407 4319 87564583.31887 +4408 4319 677083.3331555 +4409 4319 -100252145.5455 +4410 4319 21679166.67378 +4411 4319 17343750.00569 +4412 4319 -36335759.26895 +4425 4319 4335972.223649 +4426 4319 -34687499.9943 +4427 4319 -36405498.74736 +4428 4319 17343611.10827 +4429 4319 -3.039836883545e-06 +4430 4319 -52192192.18036 +4431 4319 3489305.5572 +4432 4319 34010416.66114 +4433 4319 -35404513.64279 +4320 4320 745987487.9303 +4321 4320 -2453991.97904 +4322 4320 -3.814697265625e-06 +4323 4320 -141080087.6865 +4324 4320 -95899021.31302 +4325 4320 -2.71201133728e-06 +4326 4320 92610986.19901 +4327 4320 22063836.70035 +4328 4320 -2.384185791016e-07 +4407 4320 -48879322.66665 +4408 4320 24272689.58238 +4409 4320 22525694.45184 +4410 4320 -141002035.2672 +4411 4320 -1284012.256587 +4412 4320 85676388.87482 +4428 4320 5643546.059495 +4429 4320 -3916383.16846 +4430 4320 -3489305.5572 +4431 4320 115620942.6217 +4432 4320 -613497.9950675 +4433 4320 -17135277.77496 +4434 4320 -43801307.6603 +4435 4320 -23974755.34007 +4436 4320 20312500.00667 +4437 4320 5916032.26988 +4438 4320 5515959.177805 +4439 4320 -5078333.334502 +4321 4321 616411761.6305 +4322 4321 1.382827758789e-05 +4323 4321 -95899021.31302 +4324 4321 -117437349.9808 +4325 4321 -7.450580596924e-07 +4326 4321 -16825052.18215 +4327 4321 -92728025.51489 +4328 4321 1.341104507446e-06 +4407 4321 24272689.58238 +4408 4321 -38326906.89253 +4409 4321 -16666666.67214 +4410 4321 -1284012.256589 +4411 4321 -32949093.52409 +4412 4321 677083.3332888 +4428 4321 5805839.056958 +4429 4321 -40143811.34482 +4430 4321 -34010416.66115 +4431 4321 -613497.9950655 +4432 4321 83227011.03075 +4433 4321 -3.36766242981e-06 +4434 4321 -23974755.34007 +4435 4321 -37890623.23096 +4436 4321 16666666.67214 +4437 4321 -4206263.047611 +4438 4321 -40418720.68142 +4439 4321 33333333.32785 +4322 4322 572020605.8755 +4323 4322 -3.069639205933e-06 +4324 4322 -8.642673492432e-07 +4325 4322 -46375866.82272 +4326 4322 -5.960464477539e-07 +4327 4322 1.192092895508e-06 +4328 4322 48718383.22464 +4407 4322 22525694.45184 +4408 4322 -16666666.67214 +4409 4322 -36909325.87325 +4410 4322 85676388.87482 +4411 4322 677083.3331554 +4412 4322 -97565514.93121 +4428 4322 5182361.112481 +4429 4322 -34010416.66102 +4430 4322 -35404513.64282 +4431 4322 17135277.77496 +4432 4322 -3.308057785034e-06 +4433 4322 -45997327.00151 +4434 4322 20312500.00667 +4435 4322 16666666.67214 +4436 4322 -34344061.96816 +4437 4322 3385277.779222 +4438 4322 33333333.32785 +4439 4322 -33784975.63126 +4323 4323 361120236.1713 +4324 4323 94548810.89502 +4325 4323 4.291534423828e-06 +4326 4323 -203961436.0495 +4327 4323 -20767645.33449 +4328 4323 -2.741813659668e-06 +4410 4323 4511607.610493 +4411 4323 5529463.940847 +4412 4323 4909027.779058 +4431 4323 -43801307.6603 +4432 4323 -23974755.34007 +4433 4323 -20312500.00667 +4434 4323 56503201.94985 +4435 4323 23637202.73541 +4436 4323 8124999.998668 +4437 4323 -68052930.47169 +4438 4323 -5191911.336182 +4439 4323 -41471527.77105 +4324 4324 308313282.913 +4325 4324 7.510185241699e-06 +4326 4324 18121243.54802 +4327 4324 9374992.872532 +4328 4324 3.516674041748e-06 +4410 4324 -4192758.28457 +4411 4324 -41531445.75455 +4412 4324 -33333333.32786 +4431 4324 -23974755.34007 +4432 4324 -37890623.23097 +4433 4324 -16666666.67214 +4434 4324 23637202.7354 +4435 4324 43301463.62875 +4436 4324 6666666.665574 +4437 4324 4530310.889235 +4438 4324 -14718823.21488 +4439 4324 3333333.334428 +4325 4325 278103282.9517 +4326 4325 -1.072883605957e-06 +4327 4325 3.635883331299e-06 +4328 4325 -4811252.171662 +4410 4325 -3215972.223778 +4411 4325 -33333333.32786 +4412 4325 -33978945.76051 +4431 4325 -20312500.00667 +4432 4325 -16666666.67214 +4433 4325 -34344061.96817 +4434 4325 -8124999.998663 +4435 4325 -6666666.665569 +4436 4325 -20545798.26109 +4437 4325 -41471527.77088 +4438 4325 -3333333.334428 +4439 4325 -46703003.53464 +4326 4326 371304389.3859 +4327 4326 -99841614.46535 +4328 4326 -3.337860107422e-06 +4410 4326 -47751770.62457 +4411 4326 24636355.78702 +4412 4326 21159027.78473 +4431 4326 5916032.269869 +4432 4326 -4206263.047611 +4433 4326 -3385277.779222 +4434 4326 -68052930.47169 +4435 4326 4530310.88924 +4436 4326 41471527.77088 +4437 4326 58352668.82663 +4438 4326 -24960403.62864 +4439 4326 -8463611.109723 +4327 4327 309788077.0662 +4328 4327 6.914138793945e-06 +4410 4327 24636355.78702 +4411 4327 -39372046.84257 +4412 4327 -16666666.67214 +4431 4327 5515959.177806 +4432 4327 -40418720.68145 +4433 4327 -33333333.32786 +4434 4327 -5191911.336178 +4435 4327 -14718823.21489 +4436 4327 3333333.334428 +4437 4327 -24960403.62864 +4438 4327 42973590.73913 +4439 4327 6666666.665569 +4328 4328 283253096.8787 +4410 4328 21159027.78473 +4411 4328 -16666666.67214 +4412 4328 -35825485.57977 +4431 4328 5078333.334503 +4432 4328 -33333333.32786 +4433 4328 -33784975.63128 +4434 4328 41471527.77105 +4435 4328 -3333333.334428 +4436 4328 -46703003.53464 +4437 4328 8463611.10972 +4438 4328 -6666666.665573 +4439 4328 -21115868.58701 +4329 4329 927468678.158 +4330 4329 97222222.20623 +4331 4329 -8.106231689453e-06 +4332 4329 -573726109.9308 +4333 4329 -97222221.42845 +4334 4329 8.940696716309e-07 +4335 4329 18564155.00999 +4336 4329 77777776.9872 +4337 4329 2.861022949219e-06 +4440 4329 139046393.5639 +4441 4329 24305555.56354 +4442 4329 17343888.84952 +4443 4329 -175918799.4896 +4444 4329 -24305555.36909 +4445 4329 -86719444.24762 +4446 4329 -9282077.505002 +4447 4329 19444444.25638 +4448 4329 -17343888.52033 +4330 4330 781630025.6149 +4331 4330 8.412431954121e-06 +4332 4330 -97222221.03956 +4333 4330 -116778839.2437 +4334 4330 5.602836608887e-06 +4335 4330 116666665.4808 +4336 4330 18564155.00998 +4337 4330 5.960464477539e-07 +4440 4330 24305555.56354 +4441 4330 102586730.4102 +4442 4330 13874999.85143 +4443 4330 -24305555.27187 +4444 4330 -61681981.76159 +4445 4330 -17343749.90781 +4446 4330 29166666.38457 +4447 4330 -9282077.504995 +4448 4330 20812499.90894 +4331 4331 728641235.3813 +4332 4331 4.172325134277e-07 +4333 4331 4.887580871582e-06 +4334 4331 -96436338.25295 +4335 4331 2.503395080566e-06 +4336 4331 1.251697540283e-06 +4337 4331 49504413.35998 +4440 4331 -17343888.84952 +4441 4331 -13874999.85144 +4442 4331 -65361760.6378 +4443 4331 -86719444.24762 +4444 4331 -17343749.94044 +4445 4331 -110741809.7386 +4446 4331 -26015832.7805 +4447 4331 13874999.9393 +4448 4331 -24752206.67999 +4332 4332 1632315315.374 +4333 4332 97222220.26178 +4334 4332 -4.172325134277e-05 +4335 4332 17392720.97666 +4336 4332 -97222221.42845 +4337 4332 -2.145767211914e-06 +4338 4332 -406796532.3944 +4339 4332 -2.801418304443e-06 +4340 4332 -1.233816146851e-05 +4341 4332 -148365426.1266 +4342 4332 97222222.20624 +4343 4332 -3.308057785034e-06 +4440 4332 -175918799.4897 +4441 4332 -24305555.27186 +4442 4332 86719444.24762 +4443 4332 268847663.9159 +4444 4332 24305555.07742 +4445 4332 0.03653132915497 +4446 4332 -28139091.37671 +4447 4332 -24305555.36909 +4448 4332 21679860.74398 +4449 4332 -138827443.8751 +4450 4332 -5.066394805908e-07 +4451 4332 -86719444.43019 +4452 4332 -46373434.23611 +4453 4332 24305555.56353 +4454 4332 -21679861.11823 +4333 4333 1369805740.108 +4334 4333 -2.145767211914e-06 +4335 4333 -97222221.03956 +4336 4333 -322883627.8625 +4337 4333 4.798173904419e-06 +4338 4333 -3.09944152832e-06 +4339 4333 20983010.02827 +4340 4333 -4.768371582031e-07 +4341 4333 97222222.20624 +4342 4333 -119197695.4315 +4343 4333 -7.450580596924e-08 +4440 4333 -24305555.36908 +4441 4333 -61681981.7616 +4442 4333 17343749.94043 +4443 4333 24305555.07742 +4444 4333 203220270.0671 +4445 4333 0.02920919656754 +4446 4333 -24305555.27186 +4447 4333 -113208178.6284 +4448 4333 69374999.6084 +4449 4333 -8.344650268555e-07 +4450 4333 -31882558.21681 +4451 4333 -3.278255462646e-07 +4452 4333 24305555.56353 +4453 4333 -39081501.55875 +4454 4333 17343750.00569 +4334 4334 1212545401.289 +4335 4334 -1.788139343262e-06 +4336 4334 3.75509262085e-06 +4337 4334 8567490.576108 +4338 4334 -1.20997428894e-05 +4339 4334 -4.768371582031e-07 +4340 4334 -212506.0825927 +4341 4334 -3.278255462646e-06 +4342 4334 -2.086162567139e-07 +4343 4334 -46719419.49861 +4440 4334 86719444.24762 +4441 4334 17343749.9078 +4442 4334 -110741809.7386 +4443 4334 -0.03649973869324 +4444 4334 -0.02921465039253 +4445 4334 -68146756.53808 +4446 4334 21679860.55685 +4447 4334 69374999.49133 +4448 4334 -84490851.68298 +4449 4334 -86719444.43019 +4450 4334 -2.682209014893e-07 +4451 4334 -99061955.12461 +4452 4334 -21679861.11823 +4453 4334 17343750.00569 +4454 4334 -36432062.04358 +4335 4335 927468678.158 +4336 4335 97222222.20623 +4337 4335 -8.106231689453e-06 +4338 4335 -148365426.1266 +4339 4335 -97222222.20624 +4340 4335 -3.039836883545e-06 +4341 4335 -573726109.9308 +4342 4335 -97222221.42845 +4343 4335 8.940696716309e-07 +4344 4335 18564155.00999 +4345 4335 77777776.9872 +4346 4335 2.861022949219e-06 +4440 4335 -9282077.50499 +4441 4335 29166666.38457 +4442 4335 26015832.78049 +4443 4335 -28139091.37673 +4444 4335 -24305555.27187 +4445 4335 -21679860.55685 +4446 4335 139046393.5639 +4447 4335 24305555.56354 +4448 4335 17343888.84952 +4449 4335 -46373434.23611 +4450 4335 -24305555.56353 +4451 4335 -21679861.11823 +4452 4335 -175918799.4896 +4453 4335 -24305555.36909 +4454 4335 -86719444.24762 +4455 4335 -9282077.505002 +4456 4335 19444444.25638 +4457 4335 -17343888.52033 +4336 4336 781630025.6149 +4337 4336 8.412431954121e-06 +4338 4336 -97222222.20624 +4339 4336 -119197695.4315 +4340 4336 2.831220626831e-07 +4341 4336 -97222221.03956 +4342 4336 -116778839.2437 +4343 4336 5.602836608887e-06 +4344 4336 116666665.4808 +4345 4336 18564155.00998 +4346 4336 5.960464477539e-07 +4440 4336 19444444.25638 +4441 4336 -9282077.505 +4442 4336 -13874999.9393 +4443 4336 -24305555.36909 +4444 4336 -113208178.6284 +4445 4336 -69374999.49133 +4446 4336 24305555.56354 +4447 4336 102586730.4102 +4448 4336 13874999.85143 +4449 4336 -24305555.56353 +4450 4336 -39081501.55875 +4451 4336 -17343750.0057 +4452 4336 -24305555.27187 +4453 4336 -61681981.76159 +4454 4336 -17343749.90781 +4455 4336 29166666.38457 +4456 4336 -9282077.504995 +4457 4336 20812499.90894 +4337 4337 728641235.3813 +4338 4337 -2.890825271606e-06 +4339 4337 3.8743019104e-07 +4340 4337 -46719419.49861 +4341 4337 4.172325134277e-07 +4342 4337 4.887580871582e-06 +4343 4337 -96436338.25295 +4344 4337 2.503395080566e-06 +4345 4337 1.251697540283e-06 +4346 4337 49504413.35998 +4440 4337 17343888.52033 +4441 4337 -20812499.90895 +4442 4337 -24752206.67999 +4443 4337 -21679860.74398 +4444 4337 -69374999.6084 +4445 4337 -84490851.68299 +4446 4337 -17343888.84952 +4447 4337 -13874999.85144 +4448 4337 -65361760.6378 +4449 4337 -21679861.11823 +4450 4337 -17343750.0057 +4451 4337 -36432062.04358 +4452 4337 -86719444.24762 +4453 4337 -17343749.94044 +4454 4337 -110741809.7386 +4455 4337 -26015832.7805 +4456 4337 13874999.9393 +4457 4337 -24752206.67999 +4338 4338 1483949894.094 +4339 4338 7.867813110352e-06 +4340 4338 -5.507469177246e-05 +4341 4338 184322301.8864 +4342 4338 -2.622604370117e-06 +4343 4338 -1.358985900879e-05 +4347 4338 -406796532.3944 +4348 4338 -2.801418304443e-06 +4349 4338 -1.233816146851e-05 +4350 4338 -148365426.1266 +4351 4338 97222222.20624 +4352 4338 -3.308057785034e-06 +4443 4338 -138827443.8752 +4444 4338 2.682209014893e-07 +4445 4338 86719444.4302 +4446 4338 -46373434.23614 +4447 4338 -24305555.56354 +4448 4338 21679861.11823 +4449 4338 222474230.8735 +4450 4338 3.933906555176e-06 +4451 4338 2.622604370117e-05 +4452 4338 8952264.76783 +4453 4338 -1.302361488342e-05 +4454 4338 6.914138793945e-06 +4458 4338 -138827443.8751 +4459 4338 -5.066394805908e-07 +4460 4338 -86719444.43019 +4461 4338 -46373434.23611 +4462 4338 24305555.56353 +4463 4338 -21679861.11823 +4339 4339 1250608048.648 +4340 4339 -1.192092895508e-06 +4341 4339 -3.159046173096e-06 +4342 4339 -185121779.2034 +4343 4339 8.046627044678e-07 +4347 4339 -3.09944152832e-06 +4348 4339 20983010.02827 +4349 4339 -4.768371582031e-07 +4350 4339 97222222.20624 +4351 4339 -119197695.4315 +4352 4339 -7.450580596924e-08 +4443 4339 -2.294778823853e-06 +4444 4339 -31882558.21685 +4445 4339 2.682209014893e-07 +4446 4339 -24305555.56354 +4447 4339 -39081501.55876 +4448 4339 17343750.0057 +4449 4339 4.410743713379e-06 +4450 4339 164138769.4832 +4451 4339 -1.192092895508e-07 +4452 4339 -1.156330108643e-05 +4453 4339 -83408755.55014 +4454 4339 69374999.9886 +4458 4339 -8.344650268555e-07 +4459 4339 -31882558.21681 +4460 4339 -3.278255462646e-07 +4461 4339 24305555.56353 +4462 4339 -39081501.55875 +4463 4339 17343750.00569 +4340 4340 1165825984.246 +4341 4340 -1.382827758789e-05 +4342 4340 1.788139343262e-07 +4343 4340 104791324.3853 +4347 4340 -1.20997428894e-05 +4348 4340 -4.768371582031e-07 +4349 4340 -212506.0825927 +4350 4340 -3.278255462646e-06 +4351 4340 -2.086162567139e-07 +4352 4340 -46719419.49861 +4443 4340 86719444.4302 +4444 4340 3.427267074585e-07 +4445 4340 -99061955.12464 +4446 4340 21679861.11823 +4447 4340 17343750.0057 +4448 4340 -36432062.04359 +4449 4340 2.598762512207e-05 +4450 4340 5.960464477539e-08 +4451 4340 -104578818.0156 +4452 4340 6.973743438721e-06 +4453 4340 69374999.9886 +4454 4340 -72810997.49471 +4458 4340 -86719444.43019 +4459 4340 -2.682209014893e-07 +4460 4340 -99061955.12461 +4461 4340 -21679861.11823 +4462 4340 17343750.00569 +4463 4340 -36432062.04358 +4341 4341 1632315315.374 +4342 4341 97222220.26178 +4343 4341 -4.172325134277e-05 +4344 4341 17392720.97666 +4345 4341 -97222221.42845 +4346 4341 -2.145767211914e-06 +4347 4341 -148365426.1266 +4348 4341 -97222222.20624 +4349 4341 -3.039836883545e-06 +4350 4341 -406796532.3944 +4351 4341 -2.801418304443e-06 +4352 4341 -1.233816146851e-05 +4353 4341 -148365426.1266 +4354 4341 97222222.20624 +4355 4341 -3.308057785034e-06 +4443 4341 -46373434.23613 +4444 4341 24305555.56354 +4445 4341 21679861.11823 +4446 4341 -175918799.4897 +4447 4341 -24305555.27186 +4448 4341 86719444.24762 +4449 4341 8952264.76783 +4450 4341 9.298324584961e-06 +4451 4341 6.228685379028e-06 +4452 4341 268847663.9159 +4453 4341 24305555.07742 +4454 4341 0.03653132915497 +4455 4341 -28139091.37671 +4456 4341 -24305555.36909 +4457 4341 21679860.74398 +4458 4341 -46373434.23611 +4459 4341 -24305555.56353 +4460 4341 -21679861.11823 +4461 4341 -138827443.8751 +4462 4341 -5.066394805908e-07 +4463 4341 -86719444.43019 +4464 4341 -46373434.23611 +4465 4341 24305555.56353 +4466 4341 -21679861.11823 +4342 4342 1369805740.108 +4343 4342 -2.145767211914e-06 +4344 4342 -97222221.03956 +4345 4342 -322883627.8625 +4346 4342 4.798173904419e-06 +4347 4342 -97222222.20624 +4348 4342 -119197695.4315 +4349 4342 2.831220626831e-07 +4350 4342 -3.09944152832e-06 +4351 4342 20983010.02827 +4352 4342 -4.768371582031e-07 +4353 4342 97222222.20624 +4354 4342 -119197695.4315 +4355 4342 -7.450580596924e-08 +4443 4342 24305555.56354 +4444 4342 -39081501.55876 +4445 4342 -17343750.00569 +4446 4342 -24305555.36908 +4447 4342 -61681981.7616 +4448 4342 17343749.94043 +4449 4342 1.069903373718e-05 +4450 4342 -83408755.55014 +4451 4342 -69374999.9886 +4452 4342 24305555.07742 +4453 4342 203220270.0671 +4454 4342 0.02920919656754 +4455 4342 -24305555.27186 +4456 4342 -113208178.6284 +4457 4342 69374999.6084 +4458 4342 -24305555.56353 +4459 4342 -39081501.55875 +4460 4342 -17343750.0057 +4461 4342 -8.344650268555e-07 +4462 4342 -31882558.21681 +4463 4342 -3.278255462646e-07 +4464 4342 24305555.56353 +4465 4342 -39081501.55875 +4466 4342 17343750.00569 +4343 4343 1212545401.289 +4344 4343 -1.788139343262e-06 +4345 4343 3.75509262085e-06 +4346 4343 8567490.576108 +4347 4343 -2.890825271606e-06 +4348 4343 3.8743019104e-07 +4349 4343 -46719419.49861 +4350 4343 -1.20997428894e-05 +4351 4343 -4.768371582031e-07 +4352 4343 -212506.0825927 +4353 4343 -3.278255462646e-06 +4354 4343 -2.086162567139e-07 +4355 4343 -46719419.49861 +4443 4343 21679861.11823 +4444 4343 -17343750.0057 +4445 4343 -36432062.04359 +4446 4343 86719444.24762 +4447 4343 17343749.9078 +4448 4343 -110741809.7386 +4449 4343 6.169080734253e-06 +4450 4343 -69374999.9886 +4451 4343 -72810997.49471 +4452 4343 -0.03649973869324 +4453 4343 -0.02921465039253 +4454 4343 -68146756.53808 +4455 4343 21679860.55685 +4456 4343 69374999.49133 +4457 4343 -84490851.68298 +4458 4343 -21679861.11823 +4459 4343 -17343750.0057 +4460 4343 -36432062.04358 +4461 4343 -86719444.43019 +4462 4343 -2.682209014893e-07 +4463 4343 -99061955.12461 +4464 4343 -21679861.11823 +4465 4343 17343750.00569 +4466 4343 -36432062.04358 +4344 4344 927468678.158 +4345 4344 97222222.20623 +4346 4344 -8.106231689453e-06 +4350 4344 -148365426.1266 +4351 4344 -97222222.20624 +4352 4344 -3.039836883545e-06 +4353 4344 -573726109.9308 +4354 4344 -97222221.42845 +4355 4344 8.940696716309e-07 +4356 4344 18564155.00999 +4357 4344 77777776.9872 +4358 4344 2.861022949219e-06 +4446 4344 -9282077.50499 +4447 4344 29166666.38457 +4448 4344 26015832.78049 +4452 4344 -28139091.37673 +4453 4344 -24305555.27187 +4454 4344 -21679860.55685 +4455 4344 139046393.5639 +4456 4344 24305555.56354 +4457 4344 17343888.84952 +4461 4344 -46373434.23611 +4462 4344 -24305555.56353 +4463 4344 -21679861.11823 +4464 4344 -175918799.4896 +4465 4344 -24305555.36909 +4466 4344 -86719444.24762 +4467 4344 -9282077.505002 +4468 4344 19444444.25638 +4469 4344 -17343888.52033 +4345 4345 781630025.6149 +4346 4345 8.412431954121e-06 +4350 4345 -97222222.20624 +4351 4345 -119197695.4315 +4352 4345 2.831220626831e-07 +4353 4345 -97222221.03956 +4354 4345 -116778839.2437 +4355 4345 5.602836608887e-06 +4356 4345 116666665.4808 +4357 4345 18564155.00998 +4358 4345 5.960464477539e-07 +4446 4345 19444444.25638 +4447 4345 -9282077.505 +4448 4345 -13874999.9393 +4452 4345 -24305555.36909 +4453 4345 -113208178.6284 +4454 4345 -69374999.49133 +4455 4345 24305555.56354 +4456 4345 102586730.4102 +4457 4345 13874999.85143 +4461 4345 -24305555.56353 +4462 4345 -39081501.55875 +4463 4345 -17343750.0057 +4464 4345 -24305555.27187 +4465 4345 -61681981.76159 +4466 4345 -17343749.90781 +4467 4345 29166666.38457 +4468 4345 -9282077.504995 +4469 4345 20812499.90894 +4346 4346 728641235.3813 +4350 4346 -2.890825271606e-06 +4351 4346 3.8743019104e-07 +4352 4346 -46719419.49861 +4353 4346 4.172325134277e-07 +4354 4346 4.887580871582e-06 +4355 4346 -96436338.25295 +4356 4346 2.503395080566e-06 +4357 4346 1.251697540283e-06 +4358 4346 49504413.35998 +4446 4346 17343888.52033 +4447 4346 -20812499.90895 +4448 4346 -24752206.67999 +4452 4346 -21679860.74398 +4453 4346 -69374999.6084 +4454 4346 -84490851.68299 +4455 4346 -17343888.84952 +4456 4346 -13874999.85144 +4457 4346 -65361760.6378 +4461 4346 -21679861.11823 +4462 4346 -17343750.0057 +4463 4346 -36432062.04358 +4464 4346 -86719444.24762 +4465 4346 -17343749.94044 +4466 4346 -110741809.7386 +4467 4346 -26015832.7805 +4468 4346 13874999.9393 +4469 4346 -24752206.67999 +4347 4347 1483949894.094 +4348 4347 7.867813110352e-06 +4349 4347 -5.507469177246e-05 +4350 4347 184322301.8864 +4351 4347 -2.622604370117e-06 +4352 4347 -1.358985900879e-05 +4359 4347 -406796532.3944 +4360 4347 -2.801418304443e-06 +4361 4347 -1.233816146851e-05 +4362 4347 -148365426.1266 +4363 4347 97222222.20624 +4364 4347 -3.308057785034e-06 +4449 4347 -138827443.8752 +4450 4347 2.682209014893e-07 +4451 4347 86719444.4302 +4452 4347 -46373434.23614 +4453 4347 -24305555.56354 +4454 4347 21679861.11823 +4458 4347 222474230.8735 +4459 4347 3.933906555176e-06 +4460 4347 2.622604370117e-05 +4461 4347 8952264.76783 +4462 4347 -1.302361488342e-05 +4463 4347 6.914138793945e-06 +4470 4347 -138827443.8751 +4471 4347 -5.066394805908e-07 +4472 4347 -86719444.43019 +4473 4347 -46373434.23611 +4474 4347 24305555.56353 +4475 4347 -21679861.11823 +4348 4348 1250608048.648 +4349 4348 -1.192092895508e-06 +4350 4348 -3.159046173096e-06 +4351 4348 -185121779.2034 +4352 4348 8.046627044678e-07 +4359 4348 -3.09944152832e-06 +4360 4348 20983010.02827 +4361 4348 -4.768371582031e-07 +4362 4348 97222222.20624 +4363 4348 -119197695.4315 +4364 4348 -7.450580596924e-08 +4449 4348 -2.294778823853e-06 +4450 4348 -31882558.21685 +4451 4348 2.682209014893e-07 +4452 4348 -24305555.56354 +4453 4348 -39081501.55876 +4454 4348 17343750.0057 +4458 4348 4.410743713379e-06 +4459 4348 164138769.4832 +4460 4348 -1.192092895508e-07 +4461 4348 -1.156330108643e-05 +4462 4348 -83408755.55014 +4463 4348 69374999.9886 +4470 4348 -8.344650268555e-07 +4471 4348 -31882558.21681 +4472 4348 -3.278255462646e-07 +4473 4348 24305555.56353 +4474 4348 -39081501.55875 +4475 4348 17343750.00569 +4349 4349 1165825984.246 +4350 4349 -1.382827758789e-05 +4351 4349 1.788139343262e-07 +4352 4349 104791324.3853 +4359 4349 -1.20997428894e-05 +4360 4349 -4.768371582031e-07 +4361 4349 -212506.0825927 +4362 4349 -3.278255462646e-06 +4363 4349 -2.086162567139e-07 +4364 4349 -46719419.49861 +4449 4349 86719444.4302 +4450 4349 3.427267074585e-07 +4451 4349 -99061955.12464 +4452 4349 21679861.11823 +4453 4349 17343750.0057 +4454 4349 -36432062.04359 +4458 4349 2.598762512207e-05 +4459 4349 5.960464477539e-08 +4460 4349 -104578818.0156 +4461 4349 6.973743438721e-06 +4462 4349 69374999.9886 +4463 4349 -72810997.49471 +4470 4349 -86719444.43019 +4471 4349 -2.682209014893e-07 +4472 4349 -99061955.12461 +4473 4349 -21679861.11823 +4474 4349 17343750.00569 +4475 4349 -36432062.04358 +4350 4350 1483949894.094 +4351 4350 7.867813110352e-06 +4352 4350 -5.507469177246e-05 +4353 4350 184322301.8864 +4354 4350 -2.622604370117e-06 +4355 4350 -1.358985900879e-05 +4359 4350 -148365426.1266 +4360 4350 -97222222.20624 +4361 4350 -3.039836883545e-06 +4362 4350 -406796532.3944 +4363 4350 -2.801418304443e-06 +4364 4350 -1.233816146851e-05 +4365 4350 -148365426.1266 +4366 4350 97222222.20624 +4367 4350 -3.308057785034e-06 +4449 4350 -46373434.23613 +4450 4350 24305555.56354 +4451 4350 21679861.11823 +4452 4350 -138827443.8752 +4453 4350 2.682209014893e-07 +4454 4350 86719444.4302 +4455 4350 -46373434.23614 +4456 4350 -24305555.56354 +4457 4350 21679861.11823 +4458 4350 8952264.76783 +4459 4350 9.298324584961e-06 +4460 4350 6.228685379028e-06 +4461 4350 222474230.8735 +4462 4350 3.933906555176e-06 +4463 4350 2.622604370117e-05 +4464 4350 8952264.76783 +4465 4350 -1.302361488342e-05 +4466 4350 6.914138793945e-06 +4470 4350 -46373434.23611 +4471 4350 -24305555.56353 +4472 4350 -21679861.11823 +4473 4350 -138827443.8751 +4474 4350 -5.066394805908e-07 +4475 4350 -86719444.43019 +4476 4350 -46373434.23611 +4477 4350 24305555.56353 +4478 4350 -21679861.11823 +4351 4351 1250608048.648 +4352 4351 -1.192092895508e-06 +4353 4351 -3.159046173096e-06 +4354 4351 -185121779.2034 +4355 4351 8.046627044678e-07 +4359 4351 -97222222.20624 +4360 4351 -119197695.4315 +4361 4351 2.831220626831e-07 +4362 4351 -3.09944152832e-06 +4363 4351 20983010.02827 +4364 4351 -4.768371582031e-07 +4365 4351 97222222.20624 +4366 4351 -119197695.4315 +4367 4351 -7.450580596924e-08 +4449 4351 24305555.56354 +4450 4351 -39081501.55876 +4451 4351 -17343750.00569 +4452 4351 -2.294778823853e-06 +4453 4351 -31882558.21685 +4454 4351 2.682209014893e-07 +4455 4351 -24305555.56354 +4456 4351 -39081501.55876 +4457 4351 17343750.0057 +4458 4351 1.069903373718e-05 +4459 4351 -83408755.55014 +4460 4351 -69374999.9886 +4461 4351 4.410743713379e-06 +4462 4351 164138769.4832 +4463 4351 -1.192092895508e-07 +4464 4351 -1.156330108643e-05 +4465 4351 -83408755.55014 +4466 4351 69374999.9886 +4470 4351 -24305555.56353 +4471 4351 -39081501.55875 +4472 4351 -17343750.0057 +4473 4351 -8.344650268555e-07 +4474 4351 -31882558.21681 +4475 4351 -3.278255462646e-07 +4476 4351 24305555.56353 +4477 4351 -39081501.55875 +4478 4351 17343750.00569 +4352 4352 1165825984.246 +4353 4352 -1.382827758789e-05 +4354 4352 1.788139343262e-07 +4355 4352 104791324.3853 +4359 4352 -2.890825271606e-06 +4360 4352 3.8743019104e-07 +4361 4352 -46719419.49861 +4362 4352 -1.20997428894e-05 +4363 4352 -4.768371582031e-07 +4364 4352 -212506.0825927 +4365 4352 -3.278255462646e-06 +4366 4352 -2.086162567139e-07 +4367 4352 -46719419.49861 +4449 4352 21679861.11823 +4450 4352 -17343750.0057 +4451 4352 -36432062.04359 +4452 4352 86719444.4302 +4453 4352 3.427267074585e-07 +4454 4352 -99061955.12464 +4455 4352 21679861.11823 +4456 4352 17343750.0057 +4457 4352 -36432062.04359 +4458 4352 6.169080734253e-06 +4459 4352 -69374999.9886 +4460 4352 -72810997.49471 +4461 4352 2.598762512207e-05 +4462 4352 5.960464477539e-08 +4463 4352 -104578818.0156 +4464 4352 6.973743438721e-06 +4465 4352 69374999.9886 +4466 4352 -72810997.49471 +4470 4352 -21679861.11823 +4471 4352 -17343750.0057 +4472 4352 -36432062.04358 +4473 4352 -86719444.43019 +4474 4352 -2.682209014893e-07 +4475 4352 -99061955.12461 +4476 4352 -21679861.11823 +4477 4352 17343750.00569 +4478 4352 -36432062.04358 +4353 4353 1632315315.374 +4354 4353 97222220.26178 +4355 4353 -4.172325134277e-05 +4356 4353 17392720.97666 +4357 4353 -97222221.42845 +4358 4353 -2.145767211914e-06 +4362 4353 -148365426.1266 +4363 4353 -97222222.20624 +4364 4353 -3.039836883545e-06 +4365 4353 -406796532.3944 +4366 4353 -2.801418304443e-06 +4367 4353 -1.233816146851e-05 +4368 4353 -148365426.1266 +4369 4353 97222222.20624 +4370 4353 -3.308057785034e-06 +4452 4353 -46373434.23613 +4453 4353 24305555.56354 +4454 4353 21679861.11823 +4455 4353 -175918799.4897 +4456 4353 -24305555.27186 +4457 4353 86719444.24762 +4461 4353 8952264.76783 +4462 4353 9.298324584961e-06 +4463 4353 6.228685379028e-06 +4464 4353 268847663.9159 +4465 4353 24305555.07742 +4466 4353 0.03653132915497 +4467 4353 -28139091.37671 +4468 4353 -24305555.36909 +4469 4353 21679860.74398 +4473 4353 -46373434.23611 +4474 4353 -24305555.56353 +4475 4353 -21679861.11823 +4476 4353 -138827443.8751 +4477 4353 -5.066394805908e-07 +4478 4353 -86719444.43019 +4479 4353 -46373434.23611 +4480 4353 24305555.56353 +4481 4353 -21679861.11823 +4354 4354 1369805740.108 +4355 4354 -2.145767211914e-06 +4356 4354 -97222221.03956 +4357 4354 -322883627.8625 +4358 4354 4.798173904419e-06 +4362 4354 -97222222.20624 +4363 4354 -119197695.4315 +4364 4354 2.831220626831e-07 +4365 4354 -3.09944152832e-06 +4366 4354 20983010.02827 +4367 4354 -4.768371582031e-07 +4368 4354 97222222.20624 +4369 4354 -119197695.4315 +4370 4354 -7.450580596924e-08 +4452 4354 24305555.56354 +4453 4354 -39081501.55876 +4454 4354 -17343750.00569 +4455 4354 -24305555.36908 +4456 4354 -61681981.7616 +4457 4354 17343749.94043 +4461 4354 1.069903373718e-05 +4462 4354 -83408755.55014 +4463 4354 -69374999.9886 +4464 4354 24305555.07742 +4465 4354 203220270.0671 +4466 4354 0.02920919656754 +4467 4354 -24305555.27186 +4468 4354 -113208178.6284 +4469 4354 69374999.6084 +4473 4354 -24305555.56353 +4474 4354 -39081501.55875 +4475 4354 -17343750.0057 +4476 4354 -8.344650268555e-07 +4477 4354 -31882558.21681 +4478 4354 -3.278255462646e-07 +4479 4354 24305555.56353 +4480 4354 -39081501.55875 +4481 4354 17343750.00569 +4355 4355 1212545401.289 +4356 4355 -1.788139343262e-06 +4357 4355 3.75509262085e-06 +4358 4355 8567490.576108 +4362 4355 -2.890825271606e-06 +4363 4355 3.8743019104e-07 +4364 4355 -46719419.49861 +4365 4355 -1.20997428894e-05 +4366 4355 -4.768371582031e-07 +4367 4355 -212506.0825927 +4368 4355 -3.278255462646e-06 +4369 4355 -2.086162567139e-07 +4370 4355 -46719419.49861 +4452 4355 21679861.11823 +4453 4355 -17343750.0057 +4454 4355 -36432062.04359 +4455 4355 86719444.24762 +4456 4355 17343749.9078 +4457 4355 -110741809.7386 +4461 4355 6.169080734253e-06 +4462 4355 -69374999.9886 +4463 4355 -72810997.49471 +4464 4355 -0.03649973869324 +4465 4355 -0.02921465039253 +4466 4355 -68146756.53808 +4467 4355 21679860.55685 +4468 4355 69374999.49133 +4469 4355 -84490851.68298 +4473 4355 -21679861.11823 +4474 4355 -17343750.0057 +4475 4355 -36432062.04358 +4476 4355 -86719444.43019 +4477 4355 -2.682209014893e-07 +4478 4355 -99061955.12461 +4479 4355 -21679861.11823 +4480 4355 17343750.00569 +4481 4355 -36432062.04358 +4356 4356 927468678.158 +4357 4356 97222222.20623 +4358 4356 -8.106231689453e-06 +4365 4356 -148365426.1266 +4366 4356 -97222222.20624 +4367 4356 -3.039836883545e-06 +4368 4356 -573726109.9308 +4369 4356 -97222221.42845 +4370 4356 8.940696716309e-07 +4371 4356 18564155.00999 +4372 4356 77777776.9872 +4373 4356 2.861022949219e-06 +4455 4356 -9282077.50499 +4456 4356 29166666.38457 +4457 4356 26015832.78049 +4464 4356 -28139091.37673 +4465 4356 -24305555.27187 +4466 4356 -21679860.55685 +4467 4356 139046393.5639 +4468 4356 24305555.56354 +4469 4356 17343888.84952 +4476 4356 -46373434.23611 +4477 4356 -24305555.56353 +4478 4356 -21679861.11823 +4479 4356 -175918799.4896 +4480 4356 -24305555.36909 +4481 4356 -86719444.24762 +4482 4356 -9282077.505002 +4483 4356 19444444.25638 +4484 4356 -17343888.52033 +4357 4357 781630025.6149 +4358 4357 8.412431954121e-06 +4365 4357 -97222222.20624 +4366 4357 -119197695.4315 +4367 4357 2.831220626831e-07 +4368 4357 -97222221.03956 +4369 4357 -116778839.2437 +4370 4357 5.602836608887e-06 +4371 4357 116666665.4808 +4372 4357 18564155.00998 +4373 4357 5.960464477539e-07 +4455 4357 19444444.25638 +4456 4357 -9282077.505 +4457 4357 -13874999.9393 +4464 4357 -24305555.36909 +4465 4357 -113208178.6284 +4466 4357 -69374999.49133 +4467 4357 24305555.56354 +4468 4357 102586730.4102 +4469 4357 13874999.85143 +4476 4357 -24305555.56353 +4477 4357 -39081501.55875 +4478 4357 -17343750.0057 +4479 4357 -24305555.27187 +4480 4357 -61681981.76159 +4481 4357 -17343749.90781 +4482 4357 29166666.38457 +4483 4357 -9282077.504995 +4484 4357 20812499.90894 +4358 4358 728641235.3813 +4365 4358 -2.890825271606e-06 +4366 4358 3.8743019104e-07 +4367 4358 -46719419.49861 +4368 4358 4.172325134277e-07 +4369 4358 4.887580871582e-06 +4370 4358 -96436338.25295 +4371 4358 2.503395080566e-06 +4372 4358 1.251697540283e-06 +4373 4358 49504413.35998 +4455 4358 17343888.52033 +4456 4358 -20812499.90895 +4457 4358 -24752206.67999 +4464 4358 -21679860.74398 +4465 4358 -69374999.6084 +4466 4358 -84490851.68299 +4467 4358 -17343888.84952 +4468 4358 -13874999.85144 +4469 4358 -65361760.6378 +4476 4358 -21679861.11823 +4477 4358 -17343750.0057 +4478 4358 -36432062.04358 +4479 4358 -86719444.24762 +4480 4358 -17343749.94044 +4481 4358 -110741809.7386 +4482 4358 -26015832.7805 +4483 4358 13874999.9393 +4484 4358 -24752206.67999 +4359 4359 1483949894.094 +4360 4359 7.867813110352e-06 +4361 4359 -5.507469177246e-05 +4362 4359 184322301.8864 +4363 4359 -2.622604370117e-06 +4364 4359 -1.358985900879e-05 +4374 4359 -406796532.3944 +4375 4359 -2.801418304443e-06 +4376 4359 -1.233816146851e-05 +4377 4359 -148365426.1266 +4378 4359 97222222.20624 +4379 4359 -3.308057785034e-06 +4458 4359 -138827443.8752 +4459 4359 2.682209014893e-07 +4460 4359 86719444.4302 +4461 4359 -46373434.23614 +4462 4359 -24305555.56354 +4463 4359 21679861.11823 +4470 4359 222474230.8735 +4471 4359 3.933906555176e-06 +4472 4359 2.622604370117e-05 +4473 4359 8952264.76783 +4474 4359 -1.302361488342e-05 +4475 4359 6.914138793945e-06 +4485 4359 -138827443.8751 +4486 4359 -5.066394805908e-07 +4487 4359 -86719444.43019 +4488 4359 -46373434.23611 +4489 4359 24305555.56353 +4490 4359 -21679861.11823 +4360 4360 1250608048.648 +4361 4360 -1.192092895508e-06 +4362 4360 -3.159046173096e-06 +4363 4360 -185121779.2034 +4364 4360 8.046627044678e-07 +4374 4360 -3.09944152832e-06 +4375 4360 20983010.02827 +4376 4360 -4.768371582031e-07 +4377 4360 97222222.20624 +4378 4360 -119197695.4315 +4379 4360 -7.450580596924e-08 +4458 4360 -2.294778823853e-06 +4459 4360 -31882558.21685 +4460 4360 2.682209014893e-07 +4461 4360 -24305555.56354 +4462 4360 -39081501.55876 +4463 4360 17343750.0057 +4470 4360 4.410743713379e-06 +4471 4360 164138769.4832 +4472 4360 -1.192092895508e-07 +4473 4360 -1.156330108643e-05 +4474 4360 -83408755.55014 +4475 4360 69374999.9886 +4485 4360 -8.344650268555e-07 +4486 4360 -31882558.21681 +4487 4360 -3.278255462646e-07 +4488 4360 24305555.56353 +4489 4360 -39081501.55875 +4490 4360 17343750.00569 +4361 4361 1165825984.246 +4362 4361 -1.382827758789e-05 +4363 4361 1.788139343262e-07 +4364 4361 104791324.3853 +4374 4361 -1.20997428894e-05 +4375 4361 -4.768371582031e-07 +4376 4361 -212506.0825927 +4377 4361 -3.278255462646e-06 +4378 4361 -2.086162567139e-07 +4379 4361 -46719419.49861 +4458 4361 86719444.4302 +4459 4361 3.427267074585e-07 +4460 4361 -99061955.12464 +4461 4361 21679861.11823 +4462 4361 17343750.0057 +4463 4361 -36432062.04359 +4470 4361 2.598762512207e-05 +4471 4361 5.960464477539e-08 +4472 4361 -104578818.0156 +4473 4361 6.973743438721e-06 +4474 4361 69374999.9886 +4475 4361 -72810997.49471 +4485 4361 -86719444.43019 +4486 4361 -2.682209014893e-07 +4487 4361 -99061955.12461 +4488 4361 -21679861.11823 +4489 4361 17343750.00569 +4490 4361 -36432062.04358 +4362 4362 1483949894.094 +4363 4362 7.867813110352e-06 +4364 4362 -5.507469177246e-05 +4365 4362 184322301.8864 +4366 4362 -2.622604370117e-06 +4367 4362 -1.358985900879e-05 +4374 4362 -148365426.1266 +4375 4362 -97222222.20624 +4376 4362 -3.039836883545e-06 +4377 4362 -406796532.3944 +4378 4362 -2.801418304443e-06 +4379 4362 -1.233816146851e-05 +4380 4362 -148365426.1266 +4381 4362 97222222.20624 +4382 4362 -3.308057785034e-06 +4458 4362 -46373434.23613 +4459 4362 24305555.56354 +4460 4362 21679861.11823 +4461 4362 -138827443.8752 +4462 4362 2.682209014893e-07 +4463 4362 86719444.4302 +4464 4362 -46373434.23614 +4465 4362 -24305555.56354 +4466 4362 21679861.11823 +4470 4362 8952264.76783 +4471 4362 9.298324584961e-06 +4472 4362 6.228685379028e-06 +4473 4362 222474230.8735 +4474 4362 3.933906555176e-06 +4475 4362 2.622604370117e-05 +4476 4362 8952264.76783 +4477 4362 -1.302361488342e-05 +4478 4362 6.914138793945e-06 +4485 4362 -46373434.23611 +4486 4362 -24305555.56353 +4487 4362 -21679861.11823 +4488 4362 -138827443.8751 +4489 4362 -5.066394805908e-07 +4490 4362 -86719444.43019 +4491 4362 -46373434.23611 +4492 4362 24305555.56353 +4493 4362 -21679861.11823 +4363 4363 1250608048.648 +4364 4363 -1.192092895508e-06 +4365 4363 -3.159046173096e-06 +4366 4363 -185121779.2034 +4367 4363 8.046627044678e-07 +4374 4363 -97222222.20624 +4375 4363 -119197695.4315 +4376 4363 2.831220626831e-07 +4377 4363 -3.09944152832e-06 +4378 4363 20983010.02827 +4379 4363 -4.768371582031e-07 +4380 4363 97222222.20624 +4381 4363 -119197695.4315 +4382 4363 -7.450580596924e-08 +4458 4363 24305555.56354 +4459 4363 -39081501.55876 +4460 4363 -17343750.00569 +4461 4363 -2.294778823853e-06 +4462 4363 -31882558.21685 +4463 4363 2.682209014893e-07 +4464 4363 -24305555.56354 +4465 4363 -39081501.55876 +4466 4363 17343750.0057 +4470 4363 1.069903373718e-05 +4471 4363 -83408755.55014 +4472 4363 -69374999.9886 +4473 4363 4.410743713379e-06 +4474 4363 164138769.4832 +4475 4363 -1.192092895508e-07 +4476 4363 -1.156330108643e-05 +4477 4363 -83408755.55014 +4478 4363 69374999.9886 +4485 4363 -24305555.56353 +4486 4363 -39081501.55875 +4487 4363 -17343750.0057 +4488 4363 -8.344650268555e-07 +4489 4363 -31882558.21681 +4490 4363 -3.278255462646e-07 +4491 4363 24305555.56353 +4492 4363 -39081501.55875 +4493 4363 17343750.00569 +4364 4364 1165825984.246 +4365 4364 -1.382827758789e-05 +4366 4364 1.788139343262e-07 +4367 4364 104791324.3853 +4374 4364 -2.890825271606e-06 +4375 4364 3.8743019104e-07 +4376 4364 -46719419.49861 +4377 4364 -1.20997428894e-05 +4378 4364 -4.768371582031e-07 +4379 4364 -212506.0825927 +4380 4364 -3.278255462646e-06 +4381 4364 -2.086162567139e-07 +4382 4364 -46719419.49861 +4458 4364 21679861.11823 +4459 4364 -17343750.0057 +4460 4364 -36432062.04359 +4461 4364 86719444.4302 +4462 4364 3.427267074585e-07 +4463 4364 -99061955.12464 +4464 4364 21679861.11823 +4465 4364 17343750.0057 +4466 4364 -36432062.04359 +4470 4364 6.169080734253e-06 +4471 4364 -69374999.9886 +4472 4364 -72810997.49471 +4473 4364 2.598762512207e-05 +4474 4364 5.960464477539e-08 +4475 4364 -104578818.0156 +4476 4364 6.973743438721e-06 +4477 4364 69374999.9886 +4478 4364 -72810997.49471 +4485 4364 -21679861.11823 +4486 4364 -17343750.0057 +4487 4364 -36432062.04358 +4488 4364 -86719444.43019 +4489 4364 -2.682209014893e-07 +4490 4364 -99061955.12461 +4491 4364 -21679861.11823 +4492 4364 17343750.00569 +4493 4364 -36432062.04358 +4365 4365 1483949894.094 +4366 4365 7.867813110352e-06 +4367 4365 -5.507469177246e-05 +4368 4365 184322301.8864 +4369 4365 -2.622604370117e-06 +4370 4365 -1.358985900879e-05 +4377 4365 -148365426.1266 +4378 4365 -97222222.20624 +4379 4365 -3.039836883545e-06 +4380 4365 -406796532.3944 +4381 4365 -2.801418304443e-06 +4382 4365 -1.233816146851e-05 +4383 4365 -148365426.1266 +4384 4365 97222222.20624 +4385 4365 -3.308057785034e-06 +4461 4365 -46373434.23613 +4462 4365 24305555.56354 +4463 4365 21679861.11823 +4464 4365 -138827443.8752 +4465 4365 2.682209014893e-07 +4466 4365 86719444.4302 +4467 4365 -46373434.23614 +4468 4365 -24305555.56354 +4469 4365 21679861.11823 +4473 4365 8952264.76783 +4474 4365 9.298324584961e-06 +4475 4365 6.228685379028e-06 +4476 4365 222474230.8735 +4477 4365 3.933906555176e-06 +4478 4365 2.622604370117e-05 +4479 4365 8952264.76783 +4480 4365 -1.302361488342e-05 +4481 4365 6.914138793945e-06 +4488 4365 -46373434.23611 +4489 4365 -24305555.56353 +4490 4365 -21679861.11823 +4491 4365 -138827443.8751 +4492 4365 -5.066394805908e-07 +4493 4365 -86719444.43019 +4494 4365 -46373434.23611 +4495 4365 24305555.56353 +4496 4365 -21679861.11823 +4366 4366 1250608048.648 +4367 4366 -1.192092895508e-06 +4368 4366 -3.159046173096e-06 +4369 4366 -185121779.2034 +4370 4366 8.046627044678e-07 +4377 4366 -97222222.20624 +4378 4366 -119197695.4315 +4379 4366 2.831220626831e-07 +4380 4366 -3.09944152832e-06 +4381 4366 20983010.02827 +4382 4366 -4.768371582031e-07 +4383 4366 97222222.20624 +4384 4366 -119197695.4315 +4385 4366 -7.450580596924e-08 +4461 4366 24305555.56354 +4462 4366 -39081501.55876 +4463 4366 -17343750.00569 +4464 4366 -2.294778823853e-06 +4465 4366 -31882558.21685 +4466 4366 2.682209014893e-07 +4467 4366 -24305555.56354 +4468 4366 -39081501.55876 +4469 4366 17343750.0057 +4473 4366 1.069903373718e-05 +4474 4366 -83408755.55014 +4475 4366 -69374999.9886 +4476 4366 4.410743713379e-06 +4477 4366 164138769.4832 +4478 4366 -1.192092895508e-07 +4479 4366 -1.156330108643e-05 +4480 4366 -83408755.55014 +4481 4366 69374999.9886 +4488 4366 -24305555.56353 +4489 4366 -39081501.55875 +4490 4366 -17343750.0057 +4491 4366 -8.344650268555e-07 +4492 4366 -31882558.21681 +4493 4366 -3.278255462646e-07 +4494 4366 24305555.56353 +4495 4366 -39081501.55875 +4496 4366 17343750.00569 +4367 4367 1165825984.246 +4368 4367 -1.382827758789e-05 +4369 4367 1.788139343262e-07 +4370 4367 104791324.3853 +4377 4367 -2.890825271606e-06 +4378 4367 3.8743019104e-07 +4379 4367 -46719419.49861 +4380 4367 -1.20997428894e-05 +4381 4367 -4.768371582031e-07 +4382 4367 -212506.0825927 +4383 4367 -3.278255462646e-06 +4384 4367 -2.086162567139e-07 +4385 4367 -46719419.49861 +4461 4367 21679861.11823 +4462 4367 -17343750.0057 +4463 4367 -36432062.04359 +4464 4367 86719444.4302 +4465 4367 3.427267074585e-07 +4466 4367 -99061955.12464 +4467 4367 21679861.11823 +4468 4367 17343750.0057 +4469 4367 -36432062.04359 +4473 4367 6.169080734253e-06 +4474 4367 -69374999.9886 +4475 4367 -72810997.49471 +4476 4367 2.598762512207e-05 +4477 4367 5.960464477539e-08 +4478 4367 -104578818.0156 +4479 4367 6.973743438721e-06 +4480 4367 69374999.9886 +4481 4367 -72810997.49471 +4488 4367 -21679861.11823 +4489 4367 -17343750.0057 +4490 4367 -36432062.04358 +4491 4367 -86719444.43019 +4492 4367 -2.682209014893e-07 +4493 4367 -99061955.12461 +4494 4367 -21679861.11823 +4495 4367 17343750.00569 +4496 4367 -36432062.04358 +4368 4368 1632315315.374 +4369 4368 97222220.26178 +4370 4368 -4.172325134277e-05 +4371 4368 17392720.97666 +4372 4368 -97222221.42845 +4373 4368 -2.145767211914e-06 +4380 4368 -148365426.1266 +4381 4368 -97222222.20624 +4382 4368 -3.039836883545e-06 +4383 4368 -406796532.3944 +4384 4368 -2.801418304443e-06 +4385 4368 -1.233816146851e-05 +4386 4368 -148365426.1266 +4387 4368 97222222.20624 +4388 4368 -3.308057785034e-06 +4464 4368 -46373434.23613 +4465 4368 24305555.56354 +4466 4368 21679861.11823 +4467 4368 -175918799.4897 +4468 4368 -24305555.27186 +4469 4368 86719444.24762 +4476 4368 8952264.76783 +4477 4368 9.298324584961e-06 +4478 4368 6.228685379028e-06 +4479 4368 268847663.9159 +4480 4368 24305555.07742 +4481 4368 0.03653132915497 +4482 4368 -28139091.37671 +4483 4368 -24305555.36909 +4484 4368 21679860.74398 +4491 4368 -46373434.23611 +4492 4368 -24305555.56353 +4493 4368 -21679861.11823 +4494 4368 -138827443.8751 +4495 4368 -5.066394805908e-07 +4496 4368 -86719444.43019 +4497 4368 -46373434.23611 +4498 4368 24305555.56353 +4499 4368 -21679861.11823 +4369 4369 1369805740.108 +4370 4369 -2.145767211914e-06 +4371 4369 -97222221.03956 +4372 4369 -322883627.8625 +4373 4369 4.798173904419e-06 +4380 4369 -97222222.20624 +4381 4369 -119197695.4315 +4382 4369 2.831220626831e-07 +4383 4369 -3.09944152832e-06 +4384 4369 20983010.02827 +4385 4369 -4.768371582031e-07 +4386 4369 97222222.20624 +4387 4369 -119197695.4315 +4388 4369 -7.450580596924e-08 +4464 4369 24305555.56354 +4465 4369 -39081501.55876 +4466 4369 -17343750.00569 +4467 4369 -24305555.36908 +4468 4369 -61681981.7616 +4469 4369 17343749.94043 +4476 4369 1.069903373718e-05 +4477 4369 -83408755.55014 +4478 4369 -69374999.9886 +4479 4369 24305555.07742 +4480 4369 203220270.0671 +4481 4369 0.02920919656754 +4482 4369 -24305555.27186 +4483 4369 -113208178.6284 +4484 4369 69374999.6084 +4491 4369 -24305555.56353 +4492 4369 -39081501.55875 +4493 4369 -17343750.0057 +4494 4369 -8.344650268555e-07 +4495 4369 -31882558.21681 +4496 4369 -3.278255462646e-07 +4497 4369 24305555.56353 +4498 4369 -39081501.55875 +4499 4369 17343750.00569 +4370 4370 1212545401.289 +4371 4370 -1.788139343262e-06 +4372 4370 3.75509262085e-06 +4373 4370 8567490.576108 +4380 4370 -2.890825271606e-06 +4381 4370 3.8743019104e-07 +4382 4370 -46719419.49861 +4383 4370 -1.20997428894e-05 +4384 4370 -4.768371582031e-07 +4385 4370 -212506.0825927 +4386 4370 -3.278255462646e-06 +4387 4370 -2.086162567139e-07 +4388 4370 -46719419.49861 +4464 4370 21679861.11823 +4465 4370 -17343750.0057 +4466 4370 -36432062.04359 +4467 4370 86719444.24762 +4468 4370 17343749.9078 +4469 4370 -110741809.7386 +4476 4370 6.169080734253e-06 +4477 4370 -69374999.9886 +4478 4370 -72810997.49471 +4479 4370 -0.03649973869324 +4480 4370 -0.02921465039253 +4481 4370 -68146756.53808 +4482 4370 21679860.55685 +4483 4370 69374999.49133 +4484 4370 -84490851.68298 +4491 4370 -21679861.11823 +4492 4370 -17343750.0057 +4493 4370 -36432062.04358 +4494 4370 -86719444.43019 +4495 4370 -2.682209014893e-07 +4496 4370 -99061955.12461 +4497 4370 -21679861.11823 +4498 4370 17343750.00569 +4499 4370 -36432062.04358 +4371 4371 927468678.158 +4372 4371 97222222.20623 +4373 4371 -8.106231689453e-06 +4383 4371 -148365426.1266 +4384 4371 -97222222.20624 +4385 4371 -3.039836883545e-06 +4386 4371 -573726109.9308 +4387 4371 -97222221.42845 +4388 4371 8.940696716309e-07 +4389 4371 18564155.00999 +4390 4371 77777776.9872 +4391 4371 2.861022949219e-06 +4467 4371 -9282077.50499 +4468 4371 29166666.38457 +4469 4371 26015832.78049 +4479 4371 -28139091.37673 +4480 4371 -24305555.27187 +4481 4371 -21679860.55685 +4482 4371 139046393.5639 +4483 4371 24305555.56354 +4484 4371 17343888.84952 +4494 4371 -46373434.23611 +4495 4371 -24305555.56353 +4496 4371 -21679861.11823 +4497 4371 -175918799.4896 +4498 4371 -24305555.36909 +4499 4371 -86719444.24762 +4500 4371 -9282077.505002 +4501 4371 19444444.25638 +4502 4371 -17343888.52033 +4372 4372 781630025.6149 +4373 4372 8.412431954121e-06 +4383 4372 -97222222.20624 +4384 4372 -119197695.4315 +4385 4372 2.831220626831e-07 +4386 4372 -97222221.03956 +4387 4372 -116778839.2437 +4388 4372 5.602836608887e-06 +4389 4372 116666665.4808 +4390 4372 18564155.00998 +4391 4372 5.960464477539e-07 +4467 4372 19444444.25638 +4468 4372 -9282077.505 +4469 4372 -13874999.9393 +4479 4372 -24305555.36909 +4480 4372 -113208178.6284 +4481 4372 -69374999.49133 +4482 4372 24305555.56354 +4483 4372 102586730.4102 +4484 4372 13874999.85143 +4494 4372 -24305555.56353 +4495 4372 -39081501.55875 +4496 4372 -17343750.0057 +4497 4372 -24305555.27187 +4498 4372 -61681981.76159 +4499 4372 -17343749.90781 +4500 4372 29166666.38457 +4501 4372 -9282077.504995 +4502 4372 20812499.90894 +4373 4373 728641235.3813 +4383 4373 -2.890825271606e-06 +4384 4373 3.8743019104e-07 +4385 4373 -46719419.49861 +4386 4373 4.172325134277e-07 +4387 4373 4.887580871582e-06 +4388 4373 -96436338.25295 +4389 4373 2.503395080566e-06 +4390 4373 1.251697540283e-06 +4391 4373 49504413.35998 +4467 4373 17343888.52033 +4468 4373 -20812499.90895 +4469 4373 -24752206.67999 +4479 4373 -21679860.74398 +4480 4373 -69374999.6084 +4481 4373 -84490851.68299 +4482 4373 -17343888.84952 +4483 4373 -13874999.85144 +4484 4373 -65361760.6378 +4494 4373 -21679861.11823 +4495 4373 -17343750.0057 +4496 4373 -36432062.04358 +4497 4373 -86719444.24762 +4498 4373 -17343749.94044 +4499 4373 -110741809.7386 +4500 4373 -26015832.7805 +4501 4373 13874999.9393 +4502 4373 -24752206.67999 +4374 4374 1483949894.094 +4375 4374 7.867813110352e-06 +4376 4374 -5.507469177246e-05 +4377 4374 184322301.8864 +4378 4374 -2.622604370117e-06 +4379 4374 -1.358985900879e-05 +4392 4374 -406796532.3944 +4393 4374 -2.801418304443e-06 +4394 4374 -1.233816146851e-05 +4395 4374 -148365426.1266 +4396 4374 97222222.20624 +4397 4374 -3.308057785034e-06 +4470 4374 -138827443.8752 +4471 4374 2.682209014893e-07 +4472 4374 86719444.4302 +4473 4374 -46373434.23614 +4474 4374 -24305555.56354 +4475 4374 21679861.11823 +4485 4374 222474230.8735 +4486 4374 3.933906555176e-06 +4487 4374 2.622604370117e-05 +4488 4374 8952264.76783 +4489 4374 -1.302361488342e-05 +4490 4374 6.914138793945e-06 +4503 4374 -138827443.8751 +4504 4374 -5.066394805908e-07 +4505 4374 -86719444.43019 +4506 4374 -46373434.23611 +4507 4374 24305555.56353 +4508 4374 -21679861.11823 +4375 4375 1250608048.648 +4376 4375 -1.192092895508e-06 +4377 4375 -3.159046173096e-06 +4378 4375 -185121779.2034 +4379 4375 8.046627044678e-07 +4392 4375 -3.09944152832e-06 +4393 4375 20983010.02827 +4394 4375 -4.768371582031e-07 +4395 4375 97222222.20624 +4396 4375 -119197695.4315 +4397 4375 -7.450580596924e-08 +4470 4375 -2.294778823853e-06 +4471 4375 -31882558.21685 +4472 4375 2.682209014893e-07 +4473 4375 -24305555.56354 +4474 4375 -39081501.55876 +4475 4375 17343750.0057 +4485 4375 4.410743713379e-06 +4486 4375 164138769.4832 +4487 4375 -1.192092895508e-07 +4488 4375 -1.156330108643e-05 +4489 4375 -83408755.55014 +4490 4375 69374999.9886 +4503 4375 -8.344650268555e-07 +4504 4375 -31882558.21681 +4505 4375 -3.278255462646e-07 +4506 4375 24305555.56353 +4507 4375 -39081501.55875 +4508 4375 17343750.00569 +4376 4376 1165825984.246 +4377 4376 -1.382827758789e-05 +4378 4376 1.788139343262e-07 +4379 4376 104791324.3853 +4392 4376 -1.20997428894e-05 +4393 4376 -4.768371582031e-07 +4394 4376 -212506.0825927 +4395 4376 -3.278255462646e-06 +4396 4376 -2.086162567139e-07 +4397 4376 -46719419.49861 +4470 4376 86719444.4302 +4471 4376 3.427267074585e-07 +4472 4376 -99061955.12464 +4473 4376 21679861.11823 +4474 4376 17343750.0057 +4475 4376 -36432062.04359 +4485 4376 2.598762512207e-05 +4486 4376 5.960464477539e-08 +4487 4376 -104578818.0156 +4488 4376 6.973743438721e-06 +4489 4376 69374999.9886 +4490 4376 -72810997.49471 +4503 4376 -86719444.43019 +4504 4376 -2.682209014893e-07 +4505 4376 -99061955.12461 +4506 4376 -21679861.11823 +4507 4376 17343750.00569 +4508 4376 -36432062.04358 +4377 4377 1483949894.094 +4378 4377 7.867813110352e-06 +4379 4377 -5.507469177246e-05 +4380 4377 184322301.8864 +4381 4377 -2.622604370117e-06 +4382 4377 -1.358985900879e-05 +4392 4377 -148365426.1266 +4393 4377 -97222222.20624 +4394 4377 -3.039836883545e-06 +4395 4377 -406796532.3944 +4396 4377 -2.801418304443e-06 +4397 4377 -1.233816146851e-05 +4398 4377 -148365426.1266 +4399 4377 97222222.20624 +4400 4377 -3.308057785034e-06 +4470 4377 -46373434.23613 +4471 4377 24305555.56354 +4472 4377 21679861.11823 +4473 4377 -138827443.8752 +4474 4377 2.682209014893e-07 +4475 4377 86719444.4302 +4476 4377 -46373434.23614 +4477 4377 -24305555.56354 +4478 4377 21679861.11823 +4485 4377 8952264.76783 +4486 4377 9.298324584961e-06 +4487 4377 6.228685379028e-06 +4488 4377 222474230.8735 +4489 4377 3.933906555176e-06 +4490 4377 2.622604370117e-05 +4491 4377 8952264.76783 +4492 4377 -1.302361488342e-05 +4493 4377 6.914138793945e-06 +4503 4377 -46373434.23611 +4504 4377 -24305555.56353 +4505 4377 -21679861.11823 +4506 4377 -138827443.8751 +4507 4377 -5.066394805908e-07 +4508 4377 -86719444.43019 +4509 4377 -46373434.23611 +4510 4377 24305555.56353 +4511 4377 -21679861.11823 +4378 4378 1250608048.648 +4379 4378 -1.192092895508e-06 +4380 4378 -3.159046173096e-06 +4381 4378 -185121779.2034 +4382 4378 8.046627044678e-07 +4392 4378 -97222222.20624 +4393 4378 -119197695.4315 +4394 4378 2.831220626831e-07 +4395 4378 -3.09944152832e-06 +4396 4378 20983010.02827 +4397 4378 -4.768371582031e-07 +4398 4378 97222222.20624 +4399 4378 -119197695.4315 +4400 4378 -7.450580596924e-08 +4470 4378 24305555.56354 +4471 4378 -39081501.55876 +4472 4378 -17343750.00569 +4473 4378 -2.294778823853e-06 +4474 4378 -31882558.21685 +4475 4378 2.682209014893e-07 +4476 4378 -24305555.56354 +4477 4378 -39081501.55876 +4478 4378 17343750.0057 +4485 4378 1.069903373718e-05 +4486 4378 -83408755.55014 +4487 4378 -69374999.9886 +4488 4378 4.410743713379e-06 +4489 4378 164138769.4832 +4490 4378 -1.192092895508e-07 +4491 4378 -1.156330108643e-05 +4492 4378 -83408755.55014 +4493 4378 69374999.9886 +4503 4378 -24305555.56353 +4504 4378 -39081501.55875 +4505 4378 -17343750.0057 +4506 4378 -8.344650268555e-07 +4507 4378 -31882558.21681 +4508 4378 -3.278255462646e-07 +4509 4378 24305555.56353 +4510 4378 -39081501.55875 +4511 4378 17343750.00569 +4379 4379 1165825984.246 +4380 4379 -1.382827758789e-05 +4381 4379 1.788139343262e-07 +4382 4379 104791324.3853 +4392 4379 -2.890825271606e-06 +4393 4379 3.8743019104e-07 +4394 4379 -46719419.49861 +4395 4379 -1.20997428894e-05 +4396 4379 -4.768371582031e-07 +4397 4379 -212506.0825927 +4398 4379 -3.278255462646e-06 +4399 4379 -2.086162567139e-07 +4400 4379 -46719419.49861 +4470 4379 21679861.11823 +4471 4379 -17343750.0057 +4472 4379 -36432062.04359 +4473 4379 86719444.4302 +4474 4379 3.427267074585e-07 +4475 4379 -99061955.12464 +4476 4379 21679861.11823 +4477 4379 17343750.0057 +4478 4379 -36432062.04359 +4485 4379 6.169080734253e-06 +4486 4379 -69374999.9886 +4487 4379 -72810997.49471 +4488 4379 2.598762512207e-05 +4489 4379 5.960464477539e-08 +4490 4379 -104578818.0156 +4491 4379 6.973743438721e-06 +4492 4379 69374999.9886 +4493 4379 -72810997.49471 +4503 4379 -21679861.11823 +4504 4379 -17343750.0057 +4505 4379 -36432062.04358 +4506 4379 -86719444.43019 +4507 4379 -2.682209014893e-07 +4508 4379 -99061955.12461 +4509 4379 -21679861.11823 +4510 4379 17343750.00569 +4511 4379 -36432062.04358 +4380 4380 1483949894.094 +4381 4380 7.867813110352e-06 +4382 4380 -5.507469177246e-05 +4383 4380 184322301.8864 +4384 4380 -2.622604370117e-06 +4385 4380 -1.358985900879e-05 +4395 4380 -148365426.1266 +4396 4380 -97222222.20624 +4397 4380 -3.039836883545e-06 +4398 4380 -406796532.3944 +4399 4380 -2.801418304443e-06 +4400 4380 -1.233816146851e-05 +4401 4380 -148365426.1266 +4402 4380 97222222.20624 +4403 4380 -3.308057785034e-06 +4473 4380 -46373434.23613 +4474 4380 24305555.56354 +4475 4380 21679861.11823 +4476 4380 -138827443.8752 +4477 4380 2.682209014893e-07 +4478 4380 86719444.4302 +4479 4380 -46373434.23614 +4480 4380 -24305555.56354 +4481 4380 21679861.11823 +4488 4380 8952264.76783 +4489 4380 9.298324584961e-06 +4490 4380 6.228685379028e-06 +4491 4380 222474230.8735 +4492 4380 3.933906555176e-06 +4493 4380 2.622604370117e-05 +4494 4380 8952264.76783 +4495 4380 -1.302361488342e-05 +4496 4380 6.914138793945e-06 +4506 4380 -46373434.23611 +4507 4380 -24305555.56353 +4508 4380 -21679861.11823 +4509 4380 -138827443.8751 +4510 4380 -5.066394805908e-07 +4511 4380 -86719444.43019 +4512 4380 -46373434.23611 +4513 4380 24305555.56353 +4514 4380 -21679861.11823 +4381 4381 1250608048.648 +4382 4381 -1.192092895508e-06 +4383 4381 -3.159046173096e-06 +4384 4381 -185121779.2034 +4385 4381 8.046627044678e-07 +4395 4381 -97222222.20624 +4396 4381 -119197695.4315 +4397 4381 2.831220626831e-07 +4398 4381 -3.09944152832e-06 +4399 4381 20983010.02827 +4400 4381 -4.768371582031e-07 +4401 4381 97222222.20624 +4402 4381 -119197695.4315 +4403 4381 -7.450580596924e-08 +4473 4381 24305555.56354 +4474 4381 -39081501.55876 +4475 4381 -17343750.00569 +4476 4381 -2.294778823853e-06 +4477 4381 -31882558.21685 +4478 4381 2.682209014893e-07 +4479 4381 -24305555.56354 +4480 4381 -39081501.55876 +4481 4381 17343750.0057 +4488 4381 1.069903373718e-05 +4489 4381 -83408755.55014 +4490 4381 -69374999.9886 +4491 4381 4.410743713379e-06 +4492 4381 164138769.4832 +4493 4381 -1.192092895508e-07 +4494 4381 -1.156330108643e-05 +4495 4381 -83408755.55014 +4496 4381 69374999.9886 +4506 4381 -24305555.56353 +4507 4381 -39081501.55875 +4508 4381 -17343750.0057 +4509 4381 -8.344650268555e-07 +4510 4381 -31882558.21681 +4511 4381 -3.278255462646e-07 +4512 4381 24305555.56353 +4513 4381 -39081501.55875 +4514 4381 17343750.00569 +4382 4382 1165825984.246 +4383 4382 -1.382827758789e-05 +4384 4382 1.788139343262e-07 +4385 4382 104791324.3853 +4395 4382 -2.890825271606e-06 +4396 4382 3.8743019104e-07 +4397 4382 -46719419.49861 +4398 4382 -1.20997428894e-05 +4399 4382 -4.768371582031e-07 +4400 4382 -212506.0825927 +4401 4382 -3.278255462646e-06 +4402 4382 -2.086162567139e-07 +4403 4382 -46719419.49861 +4473 4382 21679861.11823 +4474 4382 -17343750.0057 +4475 4382 -36432062.04359 +4476 4382 86719444.4302 +4477 4382 3.427267074585e-07 +4478 4382 -99061955.12464 +4479 4382 21679861.11823 +4480 4382 17343750.0057 +4481 4382 -36432062.04359 +4488 4382 6.169080734253e-06 +4489 4382 -69374999.9886 +4490 4382 -72810997.49471 +4491 4382 2.598762512207e-05 +4492 4382 5.960464477539e-08 +4493 4382 -104578818.0156 +4494 4382 6.973743438721e-06 +4495 4382 69374999.9886 +4496 4382 -72810997.49471 +4506 4382 -21679861.11823 +4507 4382 -17343750.0057 +4508 4382 -36432062.04358 +4509 4382 -86719444.43019 +4510 4382 -2.682209014893e-07 +4511 4382 -99061955.12461 +4512 4382 -21679861.11823 +4513 4382 17343750.00569 +4514 4382 -36432062.04358 +4383 4383 1483949894.094 +4384 4383 7.867813110352e-06 +4385 4383 -5.507469177246e-05 +4386 4383 184322301.8864 +4387 4383 -2.622604370117e-06 +4388 4383 -1.358985900879e-05 +4398 4383 -148365426.1266 +4399 4383 -97222222.20624 +4400 4383 -3.039836883545e-06 +4401 4383 -406796532.3944 +4402 4383 -2.801418304443e-06 +4403 4383 -1.233816146851e-05 +4404 4383 -148365426.1266 +4405 4383 97222222.20624 +4406 4383 -3.308057785034e-06 +4476 4383 -46373434.23613 +4477 4383 24305555.56354 +4478 4383 21679861.11823 +4479 4383 -138827443.8752 +4480 4383 2.682209014893e-07 +4481 4383 86719444.4302 +4482 4383 -46373434.23614 +4483 4383 -24305555.56354 +4484 4383 21679861.11823 +4491 4383 8952264.76783 +4492 4383 9.298324584961e-06 +4493 4383 6.228685379028e-06 +4494 4383 222474230.8735 +4495 4383 3.933906555176e-06 +4496 4383 2.622604370117e-05 +4497 4383 8952264.76783 +4498 4383 -1.302361488342e-05 +4499 4383 6.914138793945e-06 +4509 4383 -46373434.23611 +4510 4383 -24305555.56353 +4511 4383 -21679861.11823 +4512 4383 -138827443.8751 +4513 4383 -5.066394805908e-07 +4514 4383 -86719444.43019 +4515 4383 -46373434.23611 +4516 4383 24305555.56353 +4517 4383 -21679861.11823 +4384 4384 1250608048.648 +4385 4384 -1.192092895508e-06 +4386 4384 -3.159046173096e-06 +4387 4384 -185121779.2034 +4388 4384 8.046627044678e-07 +4398 4384 -97222222.20624 +4399 4384 -119197695.4315 +4400 4384 2.831220626831e-07 +4401 4384 -3.09944152832e-06 +4402 4384 20983010.02827 +4403 4384 -4.768371582031e-07 +4404 4384 97222222.20624 +4405 4384 -119197695.4315 +4406 4384 -7.450580596924e-08 +4476 4384 24305555.56354 +4477 4384 -39081501.55876 +4478 4384 -17343750.00569 +4479 4384 -2.294778823853e-06 +4480 4384 -31882558.21685 +4481 4384 2.682209014893e-07 +4482 4384 -24305555.56354 +4483 4384 -39081501.55876 +4484 4384 17343750.0057 +4491 4384 1.069903373718e-05 +4492 4384 -83408755.55014 +4493 4384 -69374999.9886 +4494 4384 4.410743713379e-06 +4495 4384 164138769.4832 +4496 4384 -1.192092895508e-07 +4497 4384 -1.156330108643e-05 +4498 4384 -83408755.55014 +4499 4384 69374999.9886 +4509 4384 -24305555.56353 +4510 4384 -39081501.55875 +4511 4384 -17343750.0057 +4512 4384 -8.344650268555e-07 +4513 4384 -31882558.21681 +4514 4384 -3.278255462646e-07 +4515 4384 24305555.56353 +4516 4384 -39081501.55875 +4517 4384 17343750.00569 +4385 4385 1165825984.246 +4386 4385 -1.382827758789e-05 +4387 4385 1.788139343262e-07 +4388 4385 104791324.3853 +4398 4385 -2.890825271606e-06 +4399 4385 3.8743019104e-07 +4400 4385 -46719419.49861 +4401 4385 -1.20997428894e-05 +4402 4385 -4.768371582031e-07 +4403 4385 -212506.0825927 +4404 4385 -3.278255462646e-06 +4405 4385 -2.086162567139e-07 +4406 4385 -46719419.49861 +4476 4385 21679861.11823 +4477 4385 -17343750.0057 +4478 4385 -36432062.04359 +4479 4385 86719444.4302 +4480 4385 3.427267074585e-07 +4481 4385 -99061955.12464 +4482 4385 21679861.11823 +4483 4385 17343750.0057 +4484 4385 -36432062.04359 +4491 4385 6.169080734253e-06 +4492 4385 -69374999.9886 +4493 4385 -72810997.49471 +4494 4385 2.598762512207e-05 +4495 4385 5.960464477539e-08 +4496 4385 -104578818.0156 +4497 4385 6.973743438721e-06 +4498 4385 69374999.9886 +4499 4385 -72810997.49471 +4509 4385 -21679861.11823 +4510 4385 -17343750.0057 +4511 4385 -36432062.04358 +4512 4385 -86719444.43019 +4513 4385 -2.682209014893e-07 +4514 4385 -99061955.12461 +4515 4385 -21679861.11823 +4516 4385 17343750.00569 +4517 4385 -36432062.04358 +4386 4386 1632315315.374 +4387 4386 97222220.26178 +4388 4386 -4.172325134277e-05 +4389 4386 17392720.97666 +4390 4386 -97222221.42845 +4391 4386 -2.145767211914e-06 +4401 4386 -148365426.1266 +4402 4386 -97222222.20624 +4403 4386 -3.039836883545e-06 +4404 4386 -406796532.3944 +4405 4386 -2.801418304443e-06 +4406 4386 -1.233816146851e-05 +4407 4386 -148365426.1266 +4408 4386 97222222.20624 +4409 4386 -3.308057785034e-06 +4479 4386 -46373434.23613 +4480 4386 24305555.56354 +4481 4386 21679861.11823 +4482 4386 -175918799.4897 +4483 4386 -24305555.27186 +4484 4386 86719444.24762 +4494 4386 8952264.76783 +4495 4386 9.298324584961e-06 +4496 4386 6.228685379028e-06 +4497 4386 268847663.9159 +4498 4386 24305555.07742 +4499 4386 0.03653132915497 +4500 4386 -28139091.37671 +4501 4386 -24305555.36909 +4502 4386 21679860.74398 +4512 4386 -46373434.23611 +4513 4386 -24305555.56353 +4514 4386 -21679861.11823 +4515 4386 -138827443.8751 +4516 4386 -5.066394805908e-07 +4517 4386 -86719444.43019 +4518 4386 -46373434.23611 +4519 4386 24305555.56353 +4520 4386 -21679861.11823 +4387 4387 1369805740.108 +4388 4387 -2.145767211914e-06 +4389 4387 -97222221.03956 +4390 4387 -322883627.8625 +4391 4387 4.798173904419e-06 +4401 4387 -97222222.20624 +4402 4387 -119197695.4315 +4403 4387 2.831220626831e-07 +4404 4387 -3.09944152832e-06 +4405 4387 20983010.02827 +4406 4387 -4.768371582031e-07 +4407 4387 97222222.20624 +4408 4387 -119197695.4315 +4409 4387 -7.450580596924e-08 +4479 4387 24305555.56354 +4480 4387 -39081501.55876 +4481 4387 -17343750.00569 +4482 4387 -24305555.36908 +4483 4387 -61681981.7616 +4484 4387 17343749.94043 +4494 4387 1.069903373718e-05 +4495 4387 -83408755.55014 +4496 4387 -69374999.9886 +4497 4387 24305555.07742 +4498 4387 203220270.0671 +4499 4387 0.02920919656754 +4500 4387 -24305555.27186 +4501 4387 -113208178.6284 +4502 4387 69374999.6084 +4512 4387 -24305555.56353 +4513 4387 -39081501.55875 +4514 4387 -17343750.0057 +4515 4387 -8.344650268555e-07 +4516 4387 -31882558.21681 +4517 4387 -3.278255462646e-07 +4518 4387 24305555.56353 +4519 4387 -39081501.55875 +4520 4387 17343750.00569 +4388 4388 1212545401.289 +4389 4388 -1.788139343262e-06 +4390 4388 3.75509262085e-06 +4391 4388 8567490.576108 +4401 4388 -2.890825271606e-06 +4402 4388 3.8743019104e-07 +4403 4388 -46719419.49861 +4404 4388 -1.20997428894e-05 +4405 4388 -4.768371582031e-07 +4406 4388 -212506.0825927 +4407 4388 -3.278255462646e-06 +4408 4388 -2.086162567139e-07 +4409 4388 -46719419.49861 +4479 4388 21679861.11823 +4480 4388 -17343750.0057 +4481 4388 -36432062.04359 +4482 4388 86719444.24762 +4483 4388 17343749.9078 +4484 4388 -110741809.7386 +4494 4388 6.169080734253e-06 +4495 4388 -69374999.9886 +4496 4388 -72810997.49471 +4497 4388 -0.03649973869324 +4498 4388 -0.02921465039253 +4499 4388 -68146756.53808 +4500 4388 21679860.55685 +4501 4388 69374999.49133 +4502 4388 -84490851.68298 +4512 4388 -21679861.11823 +4513 4388 -17343750.0057 +4514 4388 -36432062.04358 +4515 4388 -86719444.43019 +4516 4388 -2.682209014893e-07 +4517 4388 -99061955.12461 +4518 4388 -21679861.11823 +4519 4388 17343750.00569 +4520 4388 -36432062.04358 +4389 4389 944226635.8558 +4390 4389 104813146.3867 +4391 4389 -5.006790161133e-06 +4404 4389 -148365426.1266 +4405 4389 -97222222.20624 +4406 4389 -3.039836883545e-06 +4407 4389 -591818040.3848 +4408 4389 -104813145.6089 +4409 4389 -1.752376556396e-05 +4410 4389 22795227.75344 +4411 4389 77777776.98725 +4412 4389 4.887580871582e-06 +4482 4389 -9282077.50499 +4483 4389 29166666.38457 +4484 4389 26015832.78049 +4497 4389 -28139091.37673 +4498 4389 -24305555.27187 +4499 4389 -21679860.55685 +4500 4389 142149470.4917 +4501 4389 26203286.60958 +4502 4389 17682222.18138 +4515 4389 -46373434.23611 +4516 4389 -24305555.56353 +4517 4389 -21679861.11823 +4518 4389 -180984988.3575 +4519 4389 -26203286.41514 +4520 4389 -88411110.90689 +4521 4389 -8767515.558537 +4522 4389 19444444.25639 +4523 4389 -18020555.17262 +4390 4390 789133337.2837 +4391 4390 2.846121788025e-06 +4404 4390 -97222222.20624 +4405 4390 -119197695.4315 +4406 4390 2.831220626831e-07 +4407 4390 -104813145.2201 +4408 4390 -131460786.597 +4409 4390 -2.503395080566e-06 +4410 4390 116666665.4809 +4411 4390 28639890.68178 +4412 4390 2.384185791016e-06 +4482 4390 19444444.25638 +4483 4390 -9282077.505 +4484 4390 -13874999.9393 +4497 4390 -24305555.36909 +4498 4390 -113208178.6284 +4499 4390 -69374999.49133 +4500 4390 26203286.60958 +4501 4390 103376145.8296 +4502 4390 14145833.18358 +4515 4390 -24305555.56353 +4516 4390 -39081501.55875 +4517 4390 -17343750.0057 +4518 4390 -26203286.31793 +4519 4390 -65895674.85387 +4520 4390 -18697916.56855 +4521 4390 29166666.38459 +4522 4390 -7306349.825734 +4523 4390 20270833.25379 +4391 4391 738330627.0228 +4404 4391 -2.890825271606e-06 +4405 4391 3.8743019104e-07 +4406 4391 -46719419.49861 +4407 4391 -1.990795135498e-05 +4408 4391 -1.54972076416e-06 +4409 4391 -103838327.6491 +4410 4391 7.390975952148e-06 +4411 4391 1.609325408936e-06 +4412 4391 54942611.08085 +4482 4391 17343888.52033 +4483 4391 -20812499.90895 +4484 4391 -24752206.67999 +4497 4391 -21679860.74398 +4498 4391 -69374999.6084 +4499 4391 -84490851.68299 +4500 4391 -17682222.18137 +4501 4391 -14145833.18359 +4502 4391 -65836512.72291 +4515 4391 -21679861.11823 +4516 4391 -17343750.0057 +4517 4391 -36432062.04358 +4518 4391 -88411110.90689 +4519 4391 -18697916.60118 +4520 4391 -114040857.0942 +4521 4391 -27030832.75893 +4522 4391 13062499.95656 +4523 4391 -24841207.22224 +4392 4392 1483949894.094 +4393 4392 7.867813110352e-06 +4394 4392 -5.507469177246e-05 +4395 4392 184322301.8864 +4396 4392 -2.622604370117e-06 +4397 4392 -1.358985900879e-05 +4413 4392 -406796532.3944 +4414 4392 -2.801418304443e-06 +4415 4392 -1.233816146851e-05 +4416 4392 -148365426.1266 +4417 4392 97222222.20624 +4418 4392 -3.308057785034e-06 +4485 4392 -138827443.8752 +4486 4392 2.682209014893e-07 +4487 4392 86719444.4302 +4488 4392 -46373434.23614 +4489 4392 -24305555.56354 +4490 4392 21679861.11823 +4503 4392 222474230.8735 +4504 4392 3.933906555176e-06 +4505 4392 2.622604370117e-05 +4506 4392 8952264.76783 +4507 4392 -1.302361488342e-05 +4508 4392 6.914138793945e-06 +4524 4392 -138827443.8751 +4525 4392 -5.066394805908e-07 +4526 4392 -86719444.43019 +4527 4392 -46373434.23611 +4528 4392 24305555.56353 +4529 4392 -21679861.11823 +4393 4393 1250608048.648 +4394 4393 -1.192092895508e-06 +4395 4393 -3.159046173096e-06 +4396 4393 -185121779.2034 +4397 4393 8.046627044678e-07 +4413 4393 -3.09944152832e-06 +4414 4393 20983010.02827 +4415 4393 -4.768371582031e-07 +4416 4393 97222222.20624 +4417 4393 -119197695.4315 +4418 4393 -7.450580596924e-08 +4485 4393 -2.294778823853e-06 +4486 4393 -31882558.21685 +4487 4393 2.682209014893e-07 +4488 4393 -24305555.56354 +4489 4393 -39081501.55876 +4490 4393 17343750.0057 +4503 4393 4.410743713379e-06 +4504 4393 164138769.4832 +4505 4393 -1.192092895508e-07 +4506 4393 -1.156330108643e-05 +4507 4393 -83408755.55014 +4508 4393 69374999.9886 +4524 4393 -8.344650268555e-07 +4525 4393 -31882558.21681 +4526 4393 -3.278255462646e-07 +4527 4393 24305555.56353 +4528 4393 -39081501.55875 +4529 4393 17343750.00569 +4394 4394 1165825984.246 +4395 4394 -1.382827758789e-05 +4396 4394 1.788139343262e-07 +4397 4394 104791324.3853 +4413 4394 -1.20997428894e-05 +4414 4394 -4.768371582031e-07 +4415 4394 -212506.0825927 +4416 4394 -3.278255462646e-06 +4417 4394 -2.086162567139e-07 +4418 4394 -46719419.49861 +4485 4394 86719444.4302 +4486 4394 3.427267074585e-07 +4487 4394 -99061955.12464 +4488 4394 21679861.11823 +4489 4394 17343750.0057 +4490 4394 -36432062.04359 +4503 4394 2.598762512207e-05 +4504 4394 5.960464477539e-08 +4505 4394 -104578818.0156 +4506 4394 6.973743438721e-06 +4507 4394 69374999.9886 +4508 4394 -72810997.49471 +4524 4394 -86719444.43019 +4525 4394 -2.682209014893e-07 +4526 4394 -99061955.12461 +4527 4394 -21679861.11823 +4528 4394 17343750.00569 +4529 4394 -36432062.04358 +4395 4395 1483949894.094 +4396 4395 7.867813110352e-06 +4397 4395 -5.507469177246e-05 +4398 4395 184322301.8864 +4399 4395 -2.622604370117e-06 +4400 4395 -1.358985900879e-05 +4413 4395 -148365426.1266 +4414 4395 -97222222.20624 +4415 4395 -3.039836883545e-06 +4416 4395 -406796532.3944 +4417 4395 -2.801418304443e-06 +4418 4395 -1.233816146851e-05 +4419 4395 -148365426.1266 +4420 4395 97222222.20624 +4421 4395 -3.308057785034e-06 +4485 4395 -46373434.23613 +4486 4395 24305555.56354 +4487 4395 21679861.11823 +4488 4395 -138827443.8752 +4489 4395 2.682209014893e-07 +4490 4395 86719444.4302 +4491 4395 -46373434.23614 +4492 4395 -24305555.56354 +4493 4395 21679861.11823 +4503 4395 8952264.76783 +4504 4395 9.298324584961e-06 +4505 4395 6.228685379028e-06 +4506 4395 222474230.8735 +4507 4395 3.933906555176e-06 +4508 4395 2.622604370117e-05 +4509 4395 8952264.76783 +4510 4395 -1.302361488342e-05 +4511 4395 6.914138793945e-06 +4524 4395 -46373434.23611 +4525 4395 -24305555.56353 +4526 4395 -21679861.11823 +4527 4395 -138827443.8751 +4528 4395 -5.066394805908e-07 +4529 4395 -86719444.43019 +4530 4395 -46373434.23611 +4531 4395 24305555.56353 +4532 4395 -21679861.11823 +4396 4396 1250608048.648 +4397 4396 -1.192092895508e-06 +4398 4396 -3.159046173096e-06 +4399 4396 -185121779.2034 +4400 4396 8.046627044678e-07 +4413 4396 -97222222.20624 +4414 4396 -119197695.4315 +4415 4396 2.831220626831e-07 +4416 4396 -3.09944152832e-06 +4417 4396 20983010.02827 +4418 4396 -4.768371582031e-07 +4419 4396 97222222.20624 +4420 4396 -119197695.4315 +4421 4396 -7.450580596924e-08 +4485 4396 24305555.56354 +4486 4396 -39081501.55876 +4487 4396 -17343750.00569 +4488 4396 -2.294778823853e-06 +4489 4396 -31882558.21685 +4490 4396 2.682209014893e-07 +4491 4396 -24305555.56354 +4492 4396 -39081501.55876 +4493 4396 17343750.0057 +4503 4396 1.069903373718e-05 +4504 4396 -83408755.55014 +4505 4396 -69374999.9886 +4506 4396 4.410743713379e-06 +4507 4396 164138769.4832 +4508 4396 -1.192092895508e-07 +4509 4396 -1.156330108643e-05 +4510 4396 -83408755.55014 +4511 4396 69374999.9886 +4524 4396 -24305555.56353 +4525 4396 -39081501.55875 +4526 4396 -17343750.0057 +4527 4396 -8.344650268555e-07 +4528 4396 -31882558.21681 +4529 4396 -3.278255462646e-07 +4530 4396 24305555.56353 +4531 4396 -39081501.55875 +4532 4396 17343750.00569 +4397 4397 1165825984.246 +4398 4397 -1.382827758789e-05 +4399 4397 1.788139343262e-07 +4400 4397 104791324.3853 +4413 4397 -2.890825271606e-06 +4414 4397 3.8743019104e-07 +4415 4397 -46719419.49861 +4416 4397 -1.20997428894e-05 +4417 4397 -4.768371582031e-07 +4418 4397 -212506.0825927 +4419 4397 -3.278255462646e-06 +4420 4397 -2.086162567139e-07 +4421 4397 -46719419.49861 +4485 4397 21679861.11823 +4486 4397 -17343750.0057 +4487 4397 -36432062.04359 +4488 4397 86719444.4302 +4489 4397 3.427267074585e-07 +4490 4397 -99061955.12464 +4491 4397 21679861.11823 +4492 4397 17343750.0057 +4493 4397 -36432062.04359 +4503 4397 6.169080734253e-06 +4504 4397 -69374999.9886 +4505 4397 -72810997.49471 +4506 4397 2.598762512207e-05 +4507 4397 5.960464477539e-08 +4508 4397 -104578818.0156 +4509 4397 6.973743438721e-06 +4510 4397 69374999.9886 +4511 4397 -72810997.49471 +4524 4397 -21679861.11823 +4525 4397 -17343750.0057 +4526 4397 -36432062.04358 +4527 4397 -86719444.43019 +4528 4397 -2.682209014893e-07 +4529 4397 -99061955.12461 +4530 4397 -21679861.11823 +4531 4397 17343750.00569 +4532 4397 -36432062.04358 +4398 4398 1483949894.094 +4399 4398 7.867813110352e-06 +4400 4398 -5.507469177246e-05 +4401 4398 184322301.8864 +4402 4398 -2.622604370117e-06 +4403 4398 -1.358985900879e-05 +4416 4398 -148365426.1266 +4417 4398 -97222222.20624 +4418 4398 -3.039836883545e-06 +4419 4398 -406796532.3944 +4420 4398 -2.801418304443e-06 +4421 4398 -1.233816146851e-05 +4422 4398 -148365426.1266 +4423 4398 97222222.20624 +4424 4398 -3.308057785034e-06 +4488 4398 -46373434.23613 +4489 4398 24305555.56354 +4490 4398 21679861.11823 +4491 4398 -138827443.8752 +4492 4398 2.682209014893e-07 +4493 4398 86719444.4302 +4494 4398 -46373434.23614 +4495 4398 -24305555.56354 +4496 4398 21679861.11823 +4506 4398 8952264.76783 +4507 4398 9.298324584961e-06 +4508 4398 6.228685379028e-06 +4509 4398 222474230.8735 +4510 4398 3.933906555176e-06 +4511 4398 2.622604370117e-05 +4512 4398 8952264.76783 +4513 4398 -1.302361488342e-05 +4514 4398 6.914138793945e-06 +4527 4398 -46373434.23611 +4528 4398 -24305555.56353 +4529 4398 -21679861.11823 +4530 4398 -138827443.8751 +4531 4398 -5.066394805908e-07 +4532 4398 -86719444.43019 +4533 4398 -46373434.23611 +4534 4398 24305555.56353 +4535 4398 -21679861.11823 +4399 4399 1250608048.648 +4400 4399 -1.192092895508e-06 +4401 4399 -3.159046173096e-06 +4402 4399 -185121779.2034 +4403 4399 8.046627044678e-07 +4416 4399 -97222222.20624 +4417 4399 -119197695.4315 +4418 4399 2.831220626831e-07 +4419 4399 -3.09944152832e-06 +4420 4399 20983010.02827 +4421 4399 -4.768371582031e-07 +4422 4399 97222222.20624 +4423 4399 -119197695.4315 +4424 4399 -7.450580596924e-08 +4488 4399 24305555.56354 +4489 4399 -39081501.55876 +4490 4399 -17343750.00569 +4491 4399 -2.294778823853e-06 +4492 4399 -31882558.21685 +4493 4399 2.682209014893e-07 +4494 4399 -24305555.56354 +4495 4399 -39081501.55876 +4496 4399 17343750.0057 +4506 4399 1.069903373718e-05 +4507 4399 -83408755.55014 +4508 4399 -69374999.9886 +4509 4399 4.410743713379e-06 +4510 4399 164138769.4832 +4511 4399 -1.192092895508e-07 +4512 4399 -1.156330108643e-05 +4513 4399 -83408755.55014 +4514 4399 69374999.9886 +4527 4399 -24305555.56353 +4528 4399 -39081501.55875 +4529 4399 -17343750.0057 +4530 4399 -8.344650268555e-07 +4531 4399 -31882558.21681 +4532 4399 -3.278255462646e-07 +4533 4399 24305555.56353 +4534 4399 -39081501.55875 +4535 4399 17343750.00569 +4400 4400 1165825984.246 +4401 4400 -1.382827758789e-05 +4402 4400 1.788139343262e-07 +4403 4400 104791324.3853 +4416 4400 -2.890825271606e-06 +4417 4400 3.8743019104e-07 +4418 4400 -46719419.49861 +4419 4400 -1.20997428894e-05 +4420 4400 -4.768371582031e-07 +4421 4400 -212506.0825927 +4422 4400 -3.278255462646e-06 +4423 4400 -2.086162567139e-07 +4424 4400 -46719419.49861 +4488 4400 21679861.11823 +4489 4400 -17343750.0057 +4490 4400 -36432062.04359 +4491 4400 86719444.4302 +4492 4400 3.427267074585e-07 +4493 4400 -99061955.12464 +4494 4400 21679861.11823 +4495 4400 17343750.0057 +4496 4400 -36432062.04359 +4506 4400 6.169080734253e-06 +4507 4400 -69374999.9886 +4508 4400 -72810997.49471 +4509 4400 2.598762512207e-05 +4510 4400 5.960464477539e-08 +4511 4400 -104578818.0156 +4512 4400 6.973743438721e-06 +4513 4400 69374999.9886 +4514 4400 -72810997.49471 +4527 4400 -21679861.11823 +4528 4400 -17343750.0057 +4529 4400 -36432062.04358 +4530 4400 -86719444.43019 +4531 4400 -2.682209014893e-07 +4532 4400 -99061955.12461 +4533 4400 -21679861.11823 +4534 4400 17343750.00569 +4535 4400 -36432062.04358 +4401 4401 1483949894.094 +4402 4401 7.867813110352e-06 +4403 4401 -5.507469177246e-05 +4404 4401 184322301.8864 +4405 4401 -2.622604370117e-06 +4406 4401 -1.358985900879e-05 +4419 4401 -148365426.1266 +4420 4401 -97222222.20624 +4421 4401 -3.039836883545e-06 +4422 4401 -406796532.3944 +4423 4401 -2.801418304443e-06 +4424 4401 -1.233816146851e-05 +4425 4401 -148365426.1266 +4426 4401 97222222.20624 +4427 4401 -3.308057785034e-06 +4491 4401 -46373434.23613 +4492 4401 24305555.56354 +4493 4401 21679861.11823 +4494 4401 -138827443.8752 +4495 4401 2.682209014893e-07 +4496 4401 86719444.4302 +4497 4401 -46373434.23614 +4498 4401 -24305555.56354 +4499 4401 21679861.11823 +4509 4401 8952264.76783 +4510 4401 9.298324584961e-06 +4511 4401 6.228685379028e-06 +4512 4401 222474230.8735 +4513 4401 3.933906555176e-06 +4514 4401 2.622604370117e-05 +4515 4401 8952264.76783 +4516 4401 -1.302361488342e-05 +4517 4401 6.914138793945e-06 +4530 4401 -46373434.23611 +4531 4401 -24305555.56353 +4532 4401 -21679861.11823 +4533 4401 -138827443.8751 +4534 4401 -5.066394805908e-07 +4535 4401 -86719444.43019 +4536 4401 -46373434.23611 +4537 4401 24305555.56353 +4538 4401 -21679861.11823 +4402 4402 1250608048.648 +4403 4402 -1.192092895508e-06 +4404 4402 -3.159046173096e-06 +4405 4402 -185121779.2034 +4406 4402 8.046627044678e-07 +4419 4402 -97222222.20624 +4420 4402 -119197695.4315 +4421 4402 2.831220626831e-07 +4422 4402 -3.09944152832e-06 +4423 4402 20983010.02827 +4424 4402 -4.768371582031e-07 +4425 4402 97222222.20624 +4426 4402 -119197695.4315 +4427 4402 -7.450580596924e-08 +4491 4402 24305555.56354 +4492 4402 -39081501.55876 +4493 4402 -17343750.00569 +4494 4402 -2.294778823853e-06 +4495 4402 -31882558.21685 +4496 4402 2.682209014893e-07 +4497 4402 -24305555.56354 +4498 4402 -39081501.55876 +4499 4402 17343750.0057 +4509 4402 1.069903373718e-05 +4510 4402 -83408755.55014 +4511 4402 -69374999.9886 +4512 4402 4.410743713379e-06 +4513 4402 164138769.4832 +4514 4402 -1.192092895508e-07 +4515 4402 -1.156330108643e-05 +4516 4402 -83408755.55014 +4517 4402 69374999.9886 +4530 4402 -24305555.56353 +4531 4402 -39081501.55875 +4532 4402 -17343750.0057 +4533 4402 -8.344650268555e-07 +4534 4402 -31882558.21681 +4535 4402 -3.278255462646e-07 +4536 4402 24305555.56353 +4537 4402 -39081501.55875 +4538 4402 17343750.00569 +4403 4403 1165825984.246 +4404 4403 -1.382827758789e-05 +4405 4403 1.788139343262e-07 +4406 4403 104791324.3853 +4419 4403 -2.890825271606e-06 +4420 4403 3.8743019104e-07 +4421 4403 -46719419.49861 +4422 4403 -1.20997428894e-05 +4423 4403 -4.768371582031e-07 +4424 4403 -212506.0825927 +4425 4403 -3.278255462646e-06 +4426 4403 -2.086162567139e-07 +4427 4403 -46719419.49861 +4491 4403 21679861.11823 +4492 4403 -17343750.0057 +4493 4403 -36432062.04359 +4494 4403 86719444.4302 +4495 4403 3.427267074585e-07 +4496 4403 -99061955.12464 +4497 4403 21679861.11823 +4498 4403 17343750.0057 +4499 4403 -36432062.04359 +4509 4403 6.169080734253e-06 +4510 4403 -69374999.9886 +4511 4403 -72810997.49471 +4512 4403 2.598762512207e-05 +4513 4403 5.960464477539e-08 +4514 4403 -104578818.0156 +4515 4403 6.973743438721e-06 +4516 4403 69374999.9886 +4517 4403 -72810997.49471 +4530 4403 -21679861.11823 +4531 4403 -17343750.0057 +4532 4403 -36432062.04358 +4533 4403 -86719444.43019 +4534 4403 -2.682209014893e-07 +4535 4403 -99061955.12461 +4536 4403 -21679861.11823 +4537 4403 17343750.00569 +4538 4403 -36432062.04358 +4404 4404 1483949894.094 +4405 4404 7.867813110352e-06 +4406 4404 -5.507469177246e-05 +4407 4404 184322301.8864 +4408 4404 -2.622604370117e-06 +4409 4404 -1.358985900879e-05 +4422 4404 -148365426.1266 +4423 4404 -97222222.20624 +4424 4404 -3.039836883545e-06 +4425 4404 -406796532.3944 +4426 4404 -2.801418304443e-06 +4427 4404 -1.233816146851e-05 +4428 4404 -148365426.1266 +4429 4404 97222222.20624 +4430 4404 -3.308057785034e-06 +4494 4404 -46373434.23613 +4495 4404 24305555.56354 +4496 4404 21679861.11823 +4497 4404 -138827443.8752 +4498 4404 2.682209014893e-07 +4499 4404 86719444.4302 +4500 4404 -46373434.23614 +4501 4404 -24305555.56354 +4502 4404 21679861.11823 +4512 4404 8952264.76783 +4513 4404 9.298324584961e-06 +4514 4404 6.228685379028e-06 +4515 4404 222474230.8735 +4516 4404 3.933906555176e-06 +4517 4404 2.622604370117e-05 +4518 4404 8952264.76783 +4519 4404 -1.302361488342e-05 +4520 4404 6.914138793945e-06 +4533 4404 -46373434.23611 +4534 4404 -24305555.56353 +4535 4404 -21679861.11823 +4536 4404 -138827443.8751 +4537 4404 -5.066394805908e-07 +4538 4404 -86719444.43019 +4539 4404 -46373434.23611 +4540 4404 24305555.56353 +4541 4404 -21679861.11823 +4405 4405 1250608048.648 +4406 4405 -1.192092895508e-06 +4407 4405 -3.159046173096e-06 +4408 4405 -185121779.2034 +4409 4405 8.046627044678e-07 +4422 4405 -97222222.20624 +4423 4405 -119197695.4315 +4424 4405 2.831220626831e-07 +4425 4405 -3.09944152832e-06 +4426 4405 20983010.02827 +4427 4405 -4.768371582031e-07 +4428 4405 97222222.20624 +4429 4405 -119197695.4315 +4430 4405 -7.450580596924e-08 +4494 4405 24305555.56354 +4495 4405 -39081501.55876 +4496 4405 -17343750.00569 +4497 4405 -2.294778823853e-06 +4498 4405 -31882558.21685 +4499 4405 2.682209014893e-07 +4500 4405 -24305555.56354 +4501 4405 -39081501.55876 +4502 4405 17343750.0057 +4512 4405 1.069903373718e-05 +4513 4405 -83408755.55014 +4514 4405 -69374999.9886 +4515 4405 4.410743713379e-06 +4516 4405 164138769.4832 +4517 4405 -1.192092895508e-07 +4518 4405 -1.156330108643e-05 +4519 4405 -83408755.55014 +4520 4405 69374999.9886 +4533 4405 -24305555.56353 +4534 4405 -39081501.55875 +4535 4405 -17343750.0057 +4536 4405 -8.344650268555e-07 +4537 4405 -31882558.21681 +4538 4405 -3.278255462646e-07 +4539 4405 24305555.56353 +4540 4405 -39081501.55875 +4541 4405 17343750.00569 +4406 4406 1165825984.246 +4407 4406 -1.382827758789e-05 +4408 4406 1.788139343262e-07 +4409 4406 104791324.3853 +4422 4406 -2.890825271606e-06 +4423 4406 3.8743019104e-07 +4424 4406 -46719419.49861 +4425 4406 -1.20997428894e-05 +4426 4406 -4.768371582031e-07 +4427 4406 -212506.0825927 +4428 4406 -3.278255462646e-06 +4429 4406 -2.086162567139e-07 +4430 4406 -46719419.49861 +4494 4406 21679861.11823 +4495 4406 -17343750.0057 +4496 4406 -36432062.04359 +4497 4406 86719444.4302 +4498 4406 3.427267074585e-07 +4499 4406 -99061955.12464 +4500 4406 21679861.11823 +4501 4406 17343750.0057 +4502 4406 -36432062.04359 +4512 4406 6.169080734253e-06 +4513 4406 -69374999.9886 +4514 4406 -72810997.49471 +4515 4406 2.598762512207e-05 +4516 4406 5.960464477539e-08 +4517 4406 -104578818.0156 +4518 4406 6.973743438721e-06 +4519 4406 69374999.9886 +4520 4406 -72810997.49471 +4533 4406 -21679861.11823 +4534 4406 -17343750.0057 +4535 4406 -36432062.04358 +4536 4406 -86719444.43019 +4537 4406 -2.682209014893e-07 +4538 4406 -99061955.12461 +4539 4406 -21679861.11823 +4540 4406 17343750.00569 +4541 4406 -36432062.04358 +4407 4407 1661147708.835 +4408 4407 104975994.3214 +4409 4407 -2.622604370117e-05 +4410 4407 28973926.47985 +4411 4407 -93442034.30678 +4412 4407 -5.245208740234e-06 +4425 4407 -148365426.1266 +4426 4407 -97222222.20624 +4427 4407 -3.039836883545e-06 +4428 4407 -414750020.4148 +4429 4407 -3811573.076203 +4430 4407 -7.62939453125e-06 +4431 4407 -158390003.0581 +4432 4407 97090758.28169 +4433 4407 7.271766662598e-06 +4497 4407 -46373434.23613 +4498 4407 24305555.56354 +4499 4407 21679861.11823 +4500 4407 -180984988.3576 +4501 4407 -26203286.31793 +4502 4407 88411110.90689 +4515 4407 8952264.76783 +4516 4407 9.298324584961e-06 +4517 4407 6.228685379028e-06 +4518 4407 274245586.3935 +4519 4407 26243998.59328 +4520 4407 0.03795856237411 +4521 4407 -25967702.04295 +4522 4407 -23360508.58821 +4523 4407 21679166.28526 +4536 4407 -46373434.23611 +4537 4407 -24305555.56353 +4538 4407 -21679861.11823 +4539 4407 -140996480.1669 +4540 4407 -952893.2695225 +4541 4407 -87564583.31886 +4542 4407 -48879322.66665 +4543 4407 24272689.58238 +4544 4407 -22525694.45184 +4408 4408 1378316574.243 +4409 4408 2.27689743042e-05 +4410 4408 -93442033.9179 +4411 4408 -311076053.7848 +4412 4408 -1.84178352356e-05 +4425 4408 -97222222.20624 +4426 4408 -119197695.4315 +4427 4408 2.831220626831e-07 +4428 4408 -3811573.076217 +4429 4408 16672797.27746 +4430 4408 6.437301635742e-06 +4431 4408 97090758.28169 +4432 4408 -116180339.9824 +4433 4408 -2.279877662659e-06 +4497 4408 24305555.56354 +4498 4408 -39081501.55876 +4499 4408 -17343750.00569 +4500 4408 -26203286.41515 +4501 4408 -65895674.85389 +4502 4408 18697916.60118 +4515 4408 1.069903373718e-05 +4516 4408 -83408755.55014 +4517 4408 -69374999.9886 +4518 4408 26243998.59327 +4519 4408 203537802.7108 +4520 4408 0.03035420179367 +4521 4408 -23360508.49099 +4522 4408 -110980197.151 +4523 4408 69374999.59698 +4536 4408 -24305555.56353 +4537 4408 -39081501.55875 +4538 4408 -17343750.0057 +4539 4408 -952893.2695275 +4540 4408 -33140775.69073 +4541 4408 -677083.3331562 +4542 4408 24272689.58238 +4543 4408 -38326906.89252 +4544 4408 16666666.67214 +4409 4409 1227849607.295 +4410 4409 -4.768371582031e-06 +4411 4409 -1.84178352356e-05 +4412 4409 16993676.64499 +4425 4409 -2.890825271606e-06 +4426 4409 3.8743019104e-07 +4427 4409 -46719419.49861 +4428 4409 -1.019239425659e-05 +4429 4409 6.794929504395e-06 +4430 4409 -3046182.050705 +4431 4409 7.182359695435e-06 +4432 4409 -2.369284629822e-06 +4433 4409 -48631203.38775 +4497 4409 21679861.11823 +4498 4409 -17343750.0057 +4499 4409 -36432062.04359 +4500 4409 88411110.90689 +4501 4409 18697916.56855 +4502 4409 -114040857.0943 +4515 4409 6.169080734253e-06 +4516 4409 -69374999.9886 +4517 4409 -72810997.49471 +4518 4409 -0.03792208433151 +4519 4409 -0.03035029768944 +4520 4409 -69147840.74455 +4521 4409 21679166.091 +4522 4409 69374999.47419 +4523 4409 -84314737.2806 +4536 4409 -21679861.11823 +4537 4409 -17343750.0057 +4538 4409 -36432062.04358 +4539 4409 -87564583.31903 +4540 4409 -677083.3332895 +4541 4409 -100252145.5455 +4542 4409 -22525694.45184 +4543 4409 16666666.67214 +4544 4409 -36909325.87324 +4410 4410 878310888.481 +4411 4410 -2657515.757642 +4412 4410 1.192092895508e-06 +4428 4410 -146355658.7119 +4429 4410 -97205456.75097 +4430 4410 -8.851289749146e-06 +4431 4410 -422227983.6709 +4432 4410 -5136049.023847 +4433 4410 -1.490116119385e-06 +4434 4410 85600144.70805 +4435 4410 -16771033.13002 +4436 4410 -2.384185791016e-06 +4437 4410 -156881939.5358 +4438 4410 98545423.09951 +4439 4410 9.715557098389e-06 +4500 4410 -8767515.558538 +4501 4410 29166666.38459 +4502 4410 27030832.75893 +4518 4410 -25967702.04296 +4519 4410 -23360508.49099 +4520 4410 -21679166.091 +4521 4410 119740849.7095 +4522 4410 -664378.9397355 +4523 4410 17135277.77496 +4539 4410 -45870736.57862 +4540 4410 -24301364.19972 +4541 4410 -21679166.67379 +4542 4410 -141002035.2672 +4543 4410 -1284012.256601 +4544 4410 -85676388.87482 +4545 4410 4511607.610505 +4546 4410 -4192758.284571 +4547 4410 3215972.223777 +4548 4410 -47751770.62456 +4549 4410 24636355.78701 +4550 4410 -21159027.78472 +4411 4411 904404472.7405 +4412 4411 3.612041473389e-05 +4428 4411 -97205456.75097 +4429 4411 -119802374.1366 +4430 4411 -3.308057785034e-06 +4431 4411 -5136049.023845 +4432 4411 9983783.088469 +4433 4411 1.45435333252e-05 +4434 4411 22117855.75249 +4435 4411 -98572068.66138 +4436 4411 -9.775161743164e-06 +4437 4411 98545423.09951 +4438 4411 -123363044.4243 +4439 4411 -3.531575202942e-06 +4500 4411 19444444.25639 +4501 4411 -7306349.825734 +4502 4411 -13062499.95656 +4518 4411 -23360508.58821 +4519 4411 -110980197.151 +4520 4411 -69374999.4742 +4521 4411 -664378.9397378 +4522 4411 126264245.7776 +4523 4411 7208333.185869 +4539 4411 -24301364.19972 +4540 4411 -39232415.43152 +4541 4411 -17343750.0057 +4542 4411 -1284012.256601 +4543 4411 -32949093.52409 +4544 4411 -677083.3331561 +4545 4411 5529463.940845 +4546 4411 -41531445.75453 +4547 4411 33333333.32785 +4548 4411 24636355.78701 +4549 4411 -39372046.84256 +4550 4411 16666666.67214 +4412 4412 768562010.6434 +4428 4412 -8.642673492432e-06 +4429 4412 -3.188848495483e-06 +4430 4412 -46336936.97173 +4431 4412 -1.132488250732e-06 +4432 4412 1.466274261475e-05 +4433 4412 -12181640.5462 +4434 4412 1.430511474609e-06 +4435 4412 -9.983777999878e-06 +4436 4412 44227455.09151 +4437 4412 9.298324584961e-06 +4438 4412 -3.591179847717e-06 +4439 4412 -52301561.26622 +4500 4412 18020555.17262 +4501 4412 -20270833.25379 +4502 4412 -24841207.22224 +4518 4412 -21679166.28527 +4519 4412 -69374999.59699 +4520 4412 -84314737.28063 +4521 4412 -17135277.77496 +4522 4412 -7208333.185864 +4523 4412 -74091157.29499 +4539 4412 -21679166.67379 +4540 4412 -17343750.0057 +4541 4412 -36335759.26896 +4542 4412 -85676388.87482 +4543 4412 -677083.3332896 +4544 4412 -97565514.93121 +4545 4412 -4909027.779057 +4546 4412 33333333.32785 +4547 4412 -33978945.76048 +4548 4412 -21159027.78472 +4549 4412 16666666.67214 +4550 4412 -35825485.57976 +4413 4413 741974947.0469 +4414 4413 5.006790161133e-06 +4415 4413 -2.908706665039e-05 +4416 4413 92161150.94322 +4417 4413 19444444.44125 +4418 4413 -7.271766662598e-06 +4503 4413 -138827443.8752 +4504 4413 2.682209014893e-07 +4505 4413 86719444.4302 +4506 4413 -46373434.23614 +4507 4413 -24305555.56354 +4508 4413 21679861.11823 +4524 4413 111237115.4367 +4525 4413 -8.344650268555e-07 +4526 4413 -17343888.88603 +4527 4413 4476132.383917 +4528 4413 4861111.1127 +4529 4413 -4335972.223642 +4414 4414 625304024.3239 +4415 4414 6.198883056641e-06 +4416 4414 -19444444.44125 +4417 4414 -92560889.60172 +4418 4414 2.32458114624e-06 +4503 4414 -2.294778823853e-06 +4504 4414 -31882558.21685 +4505 4414 2.682209014893e-07 +4506 4414 -24305555.56354 +4507 4414 -39081501.55876 +4508 4414 17343750.0057 +4524 4414 -7.152557373047e-07 +4525 4414 82069384.74161 +4526 4414 -3.75509262085e-06 +4527 4414 -4861111.112713 +4528 4414 -41704377.77507 +4529 4414 34687499.9943 +4415 4415 582912992.1231 +4416 4415 -7.271766662598e-06 +4417 4415 1.877546310425e-06 +4418 4415 52395662.19267 +4503 4415 86719444.4302 +4504 4415 3.427267074585e-07 +4505 4415 -99061955.12464 +4506 4415 21679861.11823 +4507 4415 17343750.0057 +4508 4415 -36432062.04359 +4524 4415 17343888.88605 +4525 4415 -3.576278686523e-06 +4526 4415 -52289409.00778 +4527 4415 4335972.22365 +4528 4415 34687499.9943 +4529 4415 -36405498.74735 +4416 4416 741974947.0469 +4417 4416 5.006790161133e-06 +4418 4416 -2.908706665039e-05 +4419 4416 92161150.94322 +4420 4416 19444444.44125 +4421 4416 -7.271766662598e-06 +4503 4416 -46373434.23613 +4504 4416 24305555.56354 +4505 4416 21679861.11823 +4506 4416 -138827443.8752 +4507 4416 2.682209014893e-07 +4508 4416 86719444.4302 +4509 4416 -46373434.23614 +4510 4416 -24305555.56354 +4511 4416 21679861.11823 +4524 4416 4476132.383914 +4525 4416 -4861111.112702 +4526 4416 -4335972.223643 +4527 4416 111237115.4367 +4528 4416 -8.344650268555e-07 +4529 4416 -17343888.88603 +4530 4416 4476132.383917 +4531 4416 4861111.1127 +4532 4416 -4335972.223642 +4417 4417 625304024.3239 +4418 4417 6.198883056641e-06 +4419 4417 -19444444.44125 +4420 4417 -92560889.60172 +4421 4417 2.32458114624e-06 +4503 4417 24305555.56354 +4504 4417 -39081501.55876 +4505 4417 -17343750.00569 +4506 4417 -2.294778823853e-06 +4507 4417 -31882558.21685 +4508 4417 2.682209014893e-07 +4509 4417 -24305555.56354 +4510 4417 -39081501.55876 +4511 4417 17343750.0057 +4524 4417 4861111.112712 +4525 4417 -41704377.77507 +4526 4417 -34687499.9943 +4527 4417 -7.152557373047e-07 +4528 4417 82069384.74161 +4529 4417 -3.75509262085e-06 +4530 4417 -4861111.112713 +4531 4417 -41704377.77507 +4532 4417 34687499.9943 +4418 4418 582912992.1231 +4419 4418 -7.271766662598e-06 +4420 4418 1.877546310425e-06 +4421 4418 52395662.19267 +4503 4418 21679861.11823 +4504 4418 -17343750.0057 +4505 4418 -36432062.04359 +4506 4418 86719444.4302 +4507 4418 3.427267074585e-07 +4508 4418 -99061955.12464 +4509 4418 21679861.11823 +4510 4418 17343750.0057 +4511 4418 -36432062.04359 +4524 4418 4335972.223649 +4525 4418 -34687499.9943 +4526 4418 -36405498.74736 +4527 4418 17343888.88605 +4528 4418 -3.576278686523e-06 +4529 4418 -52289409.00778 +4530 4418 4335972.22365 +4531 4418 34687499.9943 +4532 4418 -36405498.74735 +4419 4419 741974947.0469 +4420 4419 5.006790161133e-06 +4421 4419 -2.908706665039e-05 +4422 4419 92161150.94322 +4423 4419 19444444.44125 +4424 4419 -7.271766662598e-06 +4506 4419 -46373434.23613 +4507 4419 24305555.56354 +4508 4419 21679861.11823 +4509 4419 -138827443.8752 +4510 4419 2.682209014893e-07 +4511 4419 86719444.4302 +4512 4419 -46373434.23614 +4513 4419 -24305555.56354 +4514 4419 21679861.11823 +4527 4419 4476132.383914 +4528 4419 -4861111.112702 +4529 4419 -4335972.223643 +4530 4419 111237115.4367 +4531 4419 -8.344650268555e-07 +4532 4419 -17343888.88603 +4533 4419 4476132.383917 +4534 4419 4861111.1127 +4535 4419 -4335972.223642 +4420 4420 625304024.3239 +4421 4420 6.198883056641e-06 +4422 4420 -19444444.44125 +4423 4420 -92560889.60172 +4424 4420 2.32458114624e-06 +4506 4420 24305555.56354 +4507 4420 -39081501.55876 +4508 4420 -17343750.00569 +4509 4420 -2.294778823853e-06 +4510 4420 -31882558.21685 +4511 4420 2.682209014893e-07 +4512 4420 -24305555.56354 +4513 4420 -39081501.55876 +4514 4420 17343750.0057 +4527 4420 4861111.112712 +4528 4420 -41704377.77507 +4529 4420 -34687499.9943 +4530 4420 -7.152557373047e-07 +4531 4420 82069384.74161 +4532 4420 -3.75509262085e-06 +4533 4420 -4861111.112713 +4534 4420 -41704377.77507 +4535 4420 34687499.9943 +4421 4421 582912992.1231 +4422 4421 -7.271766662598e-06 +4423 4421 1.877546310425e-06 +4424 4421 52395662.19267 +4506 4421 21679861.11823 +4507 4421 -17343750.0057 +4508 4421 -36432062.04359 +4509 4421 86719444.4302 +4510 4421 3.427267074585e-07 +4511 4421 -99061955.12464 +4512 4421 21679861.11823 +4513 4421 17343750.0057 +4514 4421 -36432062.04359 +4527 4421 4335972.223649 +4528 4421 -34687499.9943 +4529 4421 -36405498.74736 +4530 4421 17343888.88605 +4531 4421 -3.576278686523e-06 +4532 4421 -52289409.00778 +4533 4421 4335972.22365 +4534 4421 34687499.9943 +4535 4421 -36405498.74735 +4422 4422 741974947.0469 +4423 4422 5.006790161133e-06 +4424 4422 -2.908706665039e-05 +4425 4422 92161150.94322 +4426 4422 19444444.44125 +4427 4422 -7.271766662598e-06 +4509 4422 -46373434.23613 +4510 4422 24305555.56354 +4511 4422 21679861.11823 +4512 4422 -138827443.8752 +4513 4422 2.682209014893e-07 +4514 4422 86719444.4302 +4515 4422 -46373434.23614 +4516 4422 -24305555.56354 +4517 4422 21679861.11823 +4530 4422 4476132.383914 +4531 4422 -4861111.112702 +4532 4422 -4335972.223643 +4533 4422 111237115.4367 +4534 4422 -8.344650268555e-07 +4535 4422 -17343888.88603 +4536 4422 4476132.383917 +4537 4422 4861111.1127 +4538 4422 -4335972.223642 +4423 4423 625304024.3239 +4424 4423 6.198883056641e-06 +4425 4423 -19444444.44125 +4426 4423 -92560889.60172 +4427 4423 2.32458114624e-06 +4509 4423 24305555.56354 +4510 4423 -39081501.55876 +4511 4423 -17343750.00569 +4512 4423 -2.294778823853e-06 +4513 4423 -31882558.21685 +4514 4423 2.682209014893e-07 +4515 4423 -24305555.56354 +4516 4423 -39081501.55876 +4517 4423 17343750.0057 +4530 4423 4861111.112712 +4531 4423 -41704377.77507 +4532 4423 -34687499.9943 +4533 4423 -7.152557373047e-07 +4534 4423 82069384.74161 +4535 4423 -3.75509262085e-06 +4536 4423 -4861111.112713 +4537 4423 -41704377.77507 +4538 4423 34687499.9943 +4424 4424 582912992.1231 +4425 4424 -7.271766662598e-06 +4426 4424 1.877546310425e-06 +4427 4424 52395662.19267 +4509 4424 21679861.11823 +4510 4424 -17343750.0057 +4511 4424 -36432062.04359 +4512 4424 86719444.4302 +4513 4424 3.427267074585e-07 +4514 4424 -99061955.12464 +4515 4424 21679861.11823 +4516 4424 17343750.0057 +4517 4424 -36432062.04359 +4530 4424 4335972.223649 +4531 4424 -34687499.9943 +4532 4424 -36405498.74736 +4533 4424 17343888.88605 +4534 4424 -3.576278686523e-06 +4535 4424 -52289409.00778 +4536 4424 4335972.22365 +4537 4424 34687499.9943 +4538 4424 -36405498.74735 +4425 4425 741974947.0469 +4426 4425 5.006790161133e-06 +4427 4425 -2.908706665039e-05 +4428 4425 92161150.94322 +4429 4425 19444444.44125 +4430 4425 -7.271766662598e-06 +4512 4425 -46373434.23613 +4513 4425 24305555.56354 +4514 4425 21679861.11823 +4515 4425 -138827443.8752 +4516 4425 2.682209014893e-07 +4517 4425 86719444.4302 +4518 4425 -46373434.23614 +4519 4425 -24305555.56354 +4520 4425 21679861.11823 +4533 4425 4476132.383914 +4534 4425 -4861111.112702 +4535 4425 -4335972.223643 +4536 4425 111237115.4367 +4537 4425 -8.344650268555e-07 +4538 4425 -17343888.88603 +4539 4425 4476132.383917 +4540 4425 4861111.1127 +4541 4425 -4335972.223642 +4426 4426 625304024.3239 +4427 4426 6.198883056641e-06 +4428 4426 -19444444.44125 +4429 4426 -92560889.60172 +4430 4426 2.32458114624e-06 +4512 4426 24305555.56354 +4513 4426 -39081501.55876 +4514 4426 -17343750.00569 +4515 4426 -2.294778823853e-06 +4516 4426 -31882558.21685 +4517 4426 2.682209014893e-07 +4518 4426 -24305555.56354 +4519 4426 -39081501.55876 +4520 4426 17343750.0057 +4533 4426 4861111.112712 +4534 4426 -41704377.77507 +4535 4426 -34687499.9943 +4536 4426 -7.152557373047e-07 +4537 4426 82069384.74161 +4538 4426 -3.75509262085e-06 +4539 4426 -4861111.112713 +4540 4426 -41704377.77507 +4541 4426 34687499.9943 +4427 4427 582912992.1231 +4428 4427 -7.271766662598e-06 +4429 4427 1.877546310425e-06 +4430 4427 52395662.19267 +4512 4427 21679861.11823 +4513 4427 -17343750.0057 +4514 4427 -36432062.04359 +4515 4427 86719444.4302 +4516 4427 3.427267074585e-07 +4517 4427 -99061955.12464 +4518 4427 21679861.11823 +4519 4427 17343750.0057 +4520 4427 -36432062.04359 +4533 4427 4335972.223649 +4534 4427 -34687499.9943 +4535 4427 -36405498.74736 +4536 4427 17343888.88605 +4537 4427 -3.576278686523e-06 +4538 4427 -52289409.00778 +4539 4427 4335972.22365 +4540 4427 34687499.9943 +4541 4427 -36405498.74735 +4428 4428 743972693.3092 +4429 4428 15895.84580994 +4430 4428 -1.239776611328e-05 +4431 4428 96103889.57229 +4432 4428 23223356.21639 +4433 4428 2.145767211914e-06 +4515 4428 -46373434.23613 +4516 4428 24305555.56354 +4517 4428 21679861.11823 +4518 4428 -140996480.167 +4519 4428 -952893.2695184 +4520 4428 87564583.31904 +4521 4428 -45870736.57862 +4522 4428 -24301364.19971 +4523 4428 21679166.67378 +4536 4428 4476132.383914 +4537 4428 -4861111.112702 +4538 4428 -4335972.223643 +4539 4428 111737658.2526 +4540 4428 3973.961454153 +4541 4428 -17343611.10825 +4542 4428 5643546.059512 +4543 4428 5805839.056957 +4544 4428 -5182361.11248 +4429 4429 624700330.4184 +4430 4429 1.978874206543e-05 +4431 4429 -15665532.66612 +4432 4429 -87045539.95471 +4433 4429 -3.546476364136e-06 +4515 4429 24305555.56354 +4516 4429 -39081501.55876 +4517 4429 -17343750.00569 +4518 4429 -952893.2695179 +4519 4429 -33140775.69075 +4520 4429 677083.3332881 +4521 4429 -24301364.19971 +4522 4429 -39232415.43151 +4523 4429 17343750.00569 +4536 4429 4861111.112712 +4537 4429 -41704377.77507 +4538 4429 -34687499.9943 +4539 4429 3973.961454034 +4540 4429 81919567.51518 +4541 4429 -4.976987838745e-06 +4542 4429 -3916383.16846 +4543 4429 -40143811.34479 +4544 4429 34010416.66101 +4430 4430 583290059.4325 +4431 4430 -9.536743164063e-07 +4432 4430 -3.75509262085e-06 +4433 4430 54461159.75296 +4515 4430 21679861.11823 +4516 4430 -17343750.0057 +4517 4430 -36432062.04359 +4518 4430 87564583.31887 +4519 4430 677083.3331547 +4520 4430 -100252145.5455 +4521 4430 21679166.67378 +4522 4430 17343750.00569 +4523 4430 -36335759.26895 +4536 4430 4335972.223649 +4537 4430 -34687499.9943 +4538 4430 -36405498.74736 +4539 4430 17343611.10827 +4540 4430 -4.589557647705e-06 +4541 4430 -52192192.18035 +4542 4430 3489305.557201 +4543 4430 34010416.66114 +4544 4430 -35404513.64279 +4431 4431 745987487.9304 +4432 4431 -2453991.979044 +4433 4431 -2.861022949219e-06 +4434 4431 -141080087.6865 +4435 4431 -95899021.31304 +4436 4431 -9.119510650635e-06 +4437 4431 92610986.19902 +4438 4431 22063836.70036 +4439 4431 1.668930053711e-06 +4518 4431 -48879322.66665 +4519 4431 24272689.58238 +4520 4431 22525694.45184 +4521 4431 -141002035.2672 +4522 4431 -1284012.256585 +4523 4431 85676388.87482 +4539 4431 5643546.059496 +4540 4431 -3916383.16846 +4541 4431 -3489305.557201 +4542 4431 115620942.6217 +4543 4431 -613497.9950656 +4544 4431 -17135277.77496 +4545 4431 -43801307.6603 +4546 4431 -23974755.34007 +4547 4431 20312500.00667 +4548 4431 5916032.269886 +4549 4431 5515959.177805 +4550 4431 -5078333.334501 +4432 4432 616411761.6306 +4433 4432 3.254413604736e-05 +4434 4432 -95899021.31304 +4435 4432 -117437349.9809 +4436 4432 -3.94880771637e-06 +4437 4432 -16825052.18215 +4438 4432 -92728025.51491 +4439 4432 -5.006790161133e-06 +4518 4432 24272689.58238 +4519 4432 -38326906.89253 +4520 4432 -16666666.67214 +4521 4432 -1284012.256587 +4522 4432 -32949093.52409 +4523 4432 677083.333288 +4539 4432 5805839.056958 +4540 4432 -40143811.34482 +4541 4432 -34010416.66115 +4542 4432 -613497.9950618 +4543 4432 83227011.03075 +4544 4432 -4.321336746216e-06 +4545 4432 -23974755.34007 +4546 4432 -37890623.23096 +4547 4432 16666666.67214 +4548 4432 -4206263.047611 +4549 4432 -40418720.68142 +4550 4432 33333333.32785 +4433 4433 572020605.8755 +4434 4433 -9.298324584961e-06 +4435 4433 -3.933906555176e-06 +4436 4433 -46375866.82274 +4437 4433 -1.907348632813e-06 +4438 4433 -4.976987838745e-06 +4439 4433 48718383.22463 +4518 4433 22525694.45184 +4519 4433 -16666666.67214 +4520 4433 -36909325.87325 +4521 4433 85676388.87482 +4522 4433 677083.3331545 +4523 4433 -97565514.93121 +4539 4433 5182361.112481 +4540 4433 -34010416.66102 +4541 4433 -35404513.64282 +4542 4433 17135277.77496 +4543 4433 -4.26173210144e-06 +4544 4433 -45997327.0015 +4545 4433 20312500.00667 +4546 4433 16666666.67214 +4547 4433 -34344061.96816 +4548 4433 3385277.779222 +4549 4433 33333333.32785 +4550 4433 -33784975.63125 +4434 4434 361120236.1714 +4435 4434 94548810.89504 +4436 4434 1.192092895508e-05 +4437 4434 -203961436.0496 +4438 4434 -20767645.33449 +4439 4434 -3.784894943237e-06 +4521 4434 4511607.610493 +4522 4434 5529463.940846 +4523 4434 4909027.779057 +4542 4434 -43801307.66031 +4543 4434 -23974755.34007 +4544 4434 -20312500.00667 +4545 4434 56503201.94985 +4546 4434 23637202.73541 +4547 4434 8124999.998669 +4548 4434 -68052930.47169 +4549 4434 -5191911.336184 +4550 4434 -41471527.77105 +4435 4435 308313282.913 +4436 4435 1.406669616699e-05 +4437 4435 18121243.54802 +4438 4435 9374992.87252 +4439 4435 7.748603820801e-06 +4521 4435 -4192758.284571 +4522 4435 -41531445.75455 +4523 4435 -33333333.32786 +4542 4435 -23974755.34007 +4543 4435 -37890623.23097 +4544 4435 -16666666.67214 +4545 4435 23637202.73541 +4546 4435 43301463.62875 +4547 4435 6666666.665572 +4548 4435 4530310.889233 +4549 4435 -14718823.21489 +4550 4435 3333333.334428 +4436 4436 278103282.9517 +4437 4436 5.364418029785e-07 +4438 4436 7.62939453125e-06 +4439 4436 -4811252.171693 +4521 4436 -3215972.223778 +4522 4436 -33333333.32786 +4523 4436 -33978945.76051 +4542 4436 -20312500.00667 +4543 4436 -16666666.67214 +4544 4436 -34344061.96818 +4545 4436 -8124999.998662 +4546 4436 -6666666.66557 +4547 4436 -20545798.26108 +4548 4436 -41471527.77088 +4549 4436 -3333333.334428 +4550 4436 -46703003.53464 +4437 4437 371304389.3859 +4438 4437 -99841614.46537 +4439 4437 -9.298324584961e-06 +4521 4437 -47751770.62457 +4522 4437 24636355.78702 +4523 4437 21159027.78473 +4542 4437 5916032.269866 +4543 4437 -4206263.047612 +4544 4437 -3385277.779223 +4545 4437 -68052930.47169 +4546 4437 4530310.889241 +4547 4437 41471527.77088 +4548 4437 58352668.82663 +4549 4437 -24960403.62864 +4550 4437 -8463611.109724 +4438 4438 309788077.0662 +4439 4438 1.740455627441e-05 +4521 4438 24636355.78702 +4522 4438 -39372046.84257 +4523 4438 -16666666.67214 +4542 4438 5515959.177807 +4543 4438 -40418720.68145 +4544 4438 -33333333.32786 +4545 4438 -5191911.336177 +4546 4438 -14718823.21489 +4547 4438 3333333.334428 +4548 4438 -24960403.62864 +4549 4438 42973590.73913 +4550 4438 6666666.665569 +4439 4439 283253096.8787 +4521 4439 21159027.78473 +4522 4439 -16666666.67214 +4523 4439 -35825485.57977 +4542 4439 5078333.334503 +4543 4439 -33333333.32786 +4544 4439 -33784975.63129 +4545 4439 41471527.77105 +4546 4439 -3333333.334428 +4547 4439 -46703003.53464 +4548 4439 8463611.109719 +4549 4439 -6666666.665573 +4550 4439 -21115868.58701 +4440 4440 927468678.158 +4441 4440 97222222.20623 +4442 4440 -8.106231689453e-06 +4443 4440 -573726109.9308 +4444 4440 -97222221.42845 +4445 4440 8.940696716309e-07 +4446 4440 18564155.00999 +4447 4440 77777776.9872 +4448 4440 2.861022949219e-06 +4551 4440 139046393.5639 +4552 4440 24305555.56354 +4553 4440 17343888.84952 +4554 4440 -175918799.4896 +4555 4440 -24305555.36909 +4556 4440 -86719444.24762 +4557 4440 -9282077.505002 +4558 4440 19444444.25638 +4559 4440 -17343888.52033 +4441 4441 781630025.6149 +4442 4441 8.412431954121e-06 +4443 4441 -97222221.03956 +4444 4441 -116778839.2437 +4445 4441 5.602836608887e-06 +4446 4441 116666665.4808 +4447 4441 18564155.00998 +4448 4441 5.960464477539e-07 +4551 4441 24305555.56354 +4552 4441 102586730.4102 +4553 4441 13874999.85143 +4554 4441 -24305555.27187 +4555 4441 -61681981.76159 +4556 4441 -17343749.90781 +4557 4441 29166666.38457 +4558 4441 -9282077.504995 +4559 4441 20812499.90894 +4442 4442 728641235.3813 +4443 4442 4.172325134277e-07 +4444 4442 4.887580871582e-06 +4445 4442 -96436338.25295 +4446 4442 2.503395080566e-06 +4447 4442 1.251697540283e-06 +4448 4442 49504413.35998 +4551 4442 -17343888.84952 +4552 4442 -13874999.85144 +4553 4442 -65361760.6378 +4554 4442 -86719444.24762 +4555 4442 -17343749.94044 +4556 4442 -110741809.7386 +4557 4442 -26015832.7805 +4558 4442 13874999.9393 +4559 4442 -24752206.67999 +4443 4443 1632315315.374 +4444 4443 97222220.26178 +4445 4443 -4.172325134277e-05 +4446 4443 17392720.97666 +4447 4443 -97222221.42845 +4448 4443 -2.145767211914e-06 +4449 4443 -406796532.3944 +4450 4443 -2.801418304443e-06 +4451 4443 -1.233816146851e-05 +4452 4443 -148365426.1266 +4453 4443 97222222.20624 +4454 4443 -3.308057785034e-06 +4551 4443 -175918799.4897 +4552 4443 -24305555.27186 +4553 4443 86719444.24762 +4554 4443 268847663.9159 +4555 4443 24305555.07742 +4556 4443 0.03653132915497 +4557 4443 -28139091.37671 +4558 4443 -24305555.36909 +4559 4443 21679860.74398 +4560 4443 -138827443.8751 +4561 4443 -5.066394805908e-07 +4562 4443 -86719444.43019 +4563 4443 -46373434.23611 +4564 4443 24305555.56353 +4565 4443 -21679861.11823 +4444 4444 1369805740.108 +4445 4444 -2.145767211914e-06 +4446 4444 -97222221.03956 +4447 4444 -322883627.8625 +4448 4444 4.798173904419e-06 +4449 4444 -3.09944152832e-06 +4450 4444 20983010.02827 +4451 4444 -4.768371582031e-07 +4452 4444 97222222.20624 +4453 4444 -119197695.4315 +4454 4444 -7.450580596924e-08 +4551 4444 -24305555.36908 +4552 4444 -61681981.7616 +4553 4444 17343749.94043 +4554 4444 24305555.07742 +4555 4444 203220270.0671 +4556 4444 0.02920919656754 +4557 4444 -24305555.27186 +4558 4444 -113208178.6284 +4559 4444 69374999.6084 +4560 4444 -8.344650268555e-07 +4561 4444 -31882558.21681 +4562 4444 -3.278255462646e-07 +4563 4444 24305555.56353 +4564 4444 -39081501.55875 +4565 4444 17343750.00569 +4445 4445 1212545401.289 +4446 4445 -1.788139343262e-06 +4447 4445 3.75509262085e-06 +4448 4445 8567490.576108 +4449 4445 -1.20997428894e-05 +4450 4445 -4.768371582031e-07 +4451 4445 -212506.0825927 +4452 4445 -3.278255462646e-06 +4453 4445 -2.086162567139e-07 +4454 4445 -46719419.49861 +4551 4445 86719444.24762 +4552 4445 17343749.9078 +4553 4445 -110741809.7386 +4554 4445 -0.03649973869324 +4555 4445 -0.02921465039253 +4556 4445 -68146756.53808 +4557 4445 21679860.55685 +4558 4445 69374999.49133 +4559 4445 -84490851.68298 +4560 4445 -86719444.43019 +4561 4445 -2.682209014893e-07 +4562 4445 -99061955.12461 +4563 4445 -21679861.11823 +4564 4445 17343750.00569 +4565 4445 -36432062.04358 +4446 4446 927468678.158 +4447 4446 97222222.20623 +4448 4446 -8.106231689453e-06 +4449 4446 -148365426.1266 +4450 4446 -97222222.20624 +4451 4446 -3.039836883545e-06 +4452 4446 -573726109.9308 +4453 4446 -97222221.42845 +4454 4446 8.940696716309e-07 +4455 4446 18564155.00999 +4456 4446 77777776.9872 +4457 4446 2.861022949219e-06 +4551 4446 -9282077.50499 +4552 4446 29166666.38457 +4553 4446 26015832.78049 +4554 4446 -28139091.37673 +4555 4446 -24305555.27187 +4556 4446 -21679860.55685 +4557 4446 139046393.5639 +4558 4446 24305555.56354 +4559 4446 17343888.84952 +4560 4446 -46373434.23611 +4561 4446 -24305555.56353 +4562 4446 -21679861.11823 +4563 4446 -175918799.4896 +4564 4446 -24305555.36909 +4565 4446 -86719444.24762 +4566 4446 -9282077.505002 +4567 4446 19444444.25638 +4568 4446 -17343888.52033 +4447 4447 781630025.6149 +4448 4447 8.412431954121e-06 +4449 4447 -97222222.20624 +4450 4447 -119197695.4315 +4451 4447 2.831220626831e-07 +4452 4447 -97222221.03956 +4453 4447 -116778839.2437 +4454 4447 5.602836608887e-06 +4455 4447 116666665.4808 +4456 4447 18564155.00998 +4457 4447 5.960464477539e-07 +4551 4447 19444444.25638 +4552 4447 -9282077.505 +4553 4447 -13874999.9393 +4554 4447 -24305555.36909 +4555 4447 -113208178.6284 +4556 4447 -69374999.49133 +4557 4447 24305555.56354 +4558 4447 102586730.4102 +4559 4447 13874999.85143 +4560 4447 -24305555.56353 +4561 4447 -39081501.55875 +4562 4447 -17343750.0057 +4563 4447 -24305555.27187 +4564 4447 -61681981.76159 +4565 4447 -17343749.90781 +4566 4447 29166666.38457 +4567 4447 -9282077.504995 +4568 4447 20812499.90894 +4448 4448 728641235.3813 +4449 4448 -2.890825271606e-06 +4450 4448 3.8743019104e-07 +4451 4448 -46719419.49861 +4452 4448 4.172325134277e-07 +4453 4448 4.887580871582e-06 +4454 4448 -96436338.25295 +4455 4448 2.503395080566e-06 +4456 4448 1.251697540283e-06 +4457 4448 49504413.35998 +4551 4448 17343888.52033 +4552 4448 -20812499.90895 +4553 4448 -24752206.67999 +4554 4448 -21679860.74398 +4555 4448 -69374999.6084 +4556 4448 -84490851.68299 +4557 4448 -17343888.84952 +4558 4448 -13874999.85144 +4559 4448 -65361760.6378 +4560 4448 -21679861.11823 +4561 4448 -17343750.0057 +4562 4448 -36432062.04358 +4563 4448 -86719444.24762 +4564 4448 -17343749.94044 +4565 4448 -110741809.7386 +4566 4448 -26015832.7805 +4567 4448 13874999.9393 +4568 4448 -24752206.67999 +4449 4449 1483949894.094 +4450 4449 7.867813110352e-06 +4451 4449 -5.507469177246e-05 +4452 4449 184322301.8864 +4453 4449 -2.622604370117e-06 +4454 4449 -1.358985900879e-05 +4458 4449 -406796532.3944 +4459 4449 -2.801418304443e-06 +4460 4449 -1.233816146851e-05 +4461 4449 -148365426.1266 +4462 4449 97222222.20624 +4463 4449 -3.308057785034e-06 +4554 4449 -138827443.8752 +4555 4449 2.682209014893e-07 +4556 4449 86719444.4302 +4557 4449 -46373434.23614 +4558 4449 -24305555.56354 +4559 4449 21679861.11823 +4560 4449 222474230.8735 +4561 4449 3.933906555176e-06 +4562 4449 2.622604370117e-05 +4563 4449 8952264.76783 +4564 4449 -1.302361488342e-05 +4565 4449 6.914138793945e-06 +4569 4449 -138827443.8751 +4570 4449 -5.066394805908e-07 +4571 4449 -86719444.43019 +4572 4449 -46373434.23611 +4573 4449 24305555.56353 +4574 4449 -21679861.11823 +4450 4450 1250608048.648 +4451 4450 -1.192092895508e-06 +4452 4450 -3.159046173096e-06 +4453 4450 -185121779.2034 +4454 4450 8.046627044678e-07 +4458 4450 -3.09944152832e-06 +4459 4450 20983010.02827 +4460 4450 -4.768371582031e-07 +4461 4450 97222222.20624 +4462 4450 -119197695.4315 +4463 4450 -7.450580596924e-08 +4554 4450 -2.294778823853e-06 +4555 4450 -31882558.21685 +4556 4450 2.682209014893e-07 +4557 4450 -24305555.56354 +4558 4450 -39081501.55876 +4559 4450 17343750.0057 +4560 4450 4.410743713379e-06 +4561 4450 164138769.4832 +4562 4450 -1.192092895508e-07 +4563 4450 -1.156330108643e-05 +4564 4450 -83408755.55014 +4565 4450 69374999.9886 +4569 4450 -8.344650268555e-07 +4570 4450 -31882558.21681 +4571 4450 -3.278255462646e-07 +4572 4450 24305555.56353 +4573 4450 -39081501.55875 +4574 4450 17343750.00569 +4451 4451 1165825984.246 +4452 4451 -1.382827758789e-05 +4453 4451 1.788139343262e-07 +4454 4451 104791324.3853 +4458 4451 -1.20997428894e-05 +4459 4451 -4.768371582031e-07 +4460 4451 -212506.0825927 +4461 4451 -3.278255462646e-06 +4462 4451 -2.086162567139e-07 +4463 4451 -46719419.49861 +4554 4451 86719444.4302 +4555 4451 3.427267074585e-07 +4556 4451 -99061955.12464 +4557 4451 21679861.11823 +4558 4451 17343750.0057 +4559 4451 -36432062.04359 +4560 4451 2.598762512207e-05 +4561 4451 5.960464477539e-08 +4562 4451 -104578818.0156 +4563 4451 6.973743438721e-06 +4564 4451 69374999.9886 +4565 4451 -72810997.49471 +4569 4451 -86719444.43019 +4570 4451 -2.682209014893e-07 +4571 4451 -99061955.12461 +4572 4451 -21679861.11823 +4573 4451 17343750.00569 +4574 4451 -36432062.04358 +4452 4452 1632315315.374 +4453 4452 97222220.26178 +4454 4452 -4.172325134277e-05 +4455 4452 17392720.97666 +4456 4452 -97222221.42845 +4457 4452 -2.145767211914e-06 +4458 4452 -148365426.1266 +4459 4452 -97222222.20624 +4460 4452 -3.039836883545e-06 +4461 4452 -406796532.3944 +4462 4452 -2.801418304443e-06 +4463 4452 -1.233816146851e-05 +4464 4452 -148365426.1266 +4465 4452 97222222.20624 +4466 4452 -3.308057785034e-06 +4554 4452 -46373434.23613 +4555 4452 24305555.56354 +4556 4452 21679861.11823 +4557 4452 -175918799.4897 +4558 4452 -24305555.27186 +4559 4452 86719444.24762 +4560 4452 8952264.76783 +4561 4452 9.298324584961e-06 +4562 4452 6.228685379028e-06 +4563 4452 268847663.9159 +4564 4452 24305555.07742 +4565 4452 0.03653132915497 +4566 4452 -28139091.37671 +4567 4452 -24305555.36909 +4568 4452 21679860.74398 +4569 4452 -46373434.23611 +4570 4452 -24305555.56353 +4571 4452 -21679861.11823 +4572 4452 -138827443.8751 +4573 4452 -5.066394805908e-07 +4574 4452 -86719444.43019 +4575 4452 -46373434.23611 +4576 4452 24305555.56353 +4577 4452 -21679861.11823 +4453 4453 1369805740.108 +4454 4453 -2.145767211914e-06 +4455 4453 -97222221.03956 +4456 4453 -322883627.8625 +4457 4453 4.798173904419e-06 +4458 4453 -97222222.20624 +4459 4453 -119197695.4315 +4460 4453 2.831220626831e-07 +4461 4453 -3.09944152832e-06 +4462 4453 20983010.02827 +4463 4453 -4.768371582031e-07 +4464 4453 97222222.20624 +4465 4453 -119197695.4315 +4466 4453 -7.450580596924e-08 +4554 4453 24305555.56354 +4555 4453 -39081501.55876 +4556 4453 -17343750.00569 +4557 4453 -24305555.36908 +4558 4453 -61681981.7616 +4559 4453 17343749.94043 +4560 4453 1.069903373718e-05 +4561 4453 -83408755.55014 +4562 4453 -69374999.9886 +4563 4453 24305555.07742 +4564 4453 203220270.0671 +4565 4453 0.02920919656754 +4566 4453 -24305555.27186 +4567 4453 -113208178.6284 +4568 4453 69374999.6084 +4569 4453 -24305555.56353 +4570 4453 -39081501.55875 +4571 4453 -17343750.0057 +4572 4453 -8.344650268555e-07 +4573 4453 -31882558.21681 +4574 4453 -3.278255462646e-07 +4575 4453 24305555.56353 +4576 4453 -39081501.55875 +4577 4453 17343750.00569 +4454 4454 1212545401.289 +4455 4454 -1.788139343262e-06 +4456 4454 3.75509262085e-06 +4457 4454 8567490.576108 +4458 4454 -2.890825271606e-06 +4459 4454 3.8743019104e-07 +4460 4454 -46719419.49861 +4461 4454 -1.20997428894e-05 +4462 4454 -4.768371582031e-07 +4463 4454 -212506.0825927 +4464 4454 -3.278255462646e-06 +4465 4454 -2.086162567139e-07 +4466 4454 -46719419.49861 +4554 4454 21679861.11823 +4555 4454 -17343750.0057 +4556 4454 -36432062.04359 +4557 4454 86719444.24762 +4558 4454 17343749.9078 +4559 4454 -110741809.7386 +4560 4454 6.169080734253e-06 +4561 4454 -69374999.9886 +4562 4454 -72810997.49471 +4563 4454 -0.03649973869324 +4564 4454 -0.02921465039253 +4565 4454 -68146756.53808 +4566 4454 21679860.55685 +4567 4454 69374999.49133 +4568 4454 -84490851.68298 +4569 4454 -21679861.11823 +4570 4454 -17343750.0057 +4571 4454 -36432062.04358 +4572 4454 -86719444.43019 +4573 4454 -2.682209014893e-07 +4574 4454 -99061955.12461 +4575 4454 -21679861.11823 +4576 4454 17343750.00569 +4577 4454 -36432062.04358 +4455 4455 927468678.158 +4456 4455 97222222.20623 +4457 4455 -8.106231689453e-06 +4461 4455 -148365426.1266 +4462 4455 -97222222.20624 +4463 4455 -3.039836883545e-06 +4464 4455 -573726109.9308 +4465 4455 -97222221.42845 +4466 4455 8.940696716309e-07 +4467 4455 18564155.00999 +4468 4455 77777776.9872 +4469 4455 2.861022949219e-06 +4557 4455 -9282077.50499 +4558 4455 29166666.38457 +4559 4455 26015832.78049 +4563 4455 -28139091.37673 +4564 4455 -24305555.27187 +4565 4455 -21679860.55685 +4566 4455 139046393.5639 +4567 4455 24305555.56354 +4568 4455 17343888.84952 +4572 4455 -46373434.23611 +4573 4455 -24305555.56353 +4574 4455 -21679861.11823 +4575 4455 -175918799.4896 +4576 4455 -24305555.36909 +4577 4455 -86719444.24762 +4578 4455 -9282077.505002 +4579 4455 19444444.25638 +4580 4455 -17343888.52033 +4456 4456 781630025.6149 +4457 4456 8.412431954121e-06 +4461 4456 -97222222.20624 +4462 4456 -119197695.4315 +4463 4456 2.831220626831e-07 +4464 4456 -97222221.03956 +4465 4456 -116778839.2437 +4466 4456 5.602836608887e-06 +4467 4456 116666665.4808 +4468 4456 18564155.00998 +4469 4456 5.960464477539e-07 +4557 4456 19444444.25638 +4558 4456 -9282077.505 +4559 4456 -13874999.9393 +4563 4456 -24305555.36909 +4564 4456 -113208178.6284 +4565 4456 -69374999.49133 +4566 4456 24305555.56354 +4567 4456 102586730.4102 +4568 4456 13874999.85143 +4572 4456 -24305555.56353 +4573 4456 -39081501.55875 +4574 4456 -17343750.0057 +4575 4456 -24305555.27187 +4576 4456 -61681981.76159 +4577 4456 -17343749.90781 +4578 4456 29166666.38457 +4579 4456 -9282077.504995 +4580 4456 20812499.90894 +4457 4457 728641235.3813 +4461 4457 -2.890825271606e-06 +4462 4457 3.8743019104e-07 +4463 4457 -46719419.49861 +4464 4457 4.172325134277e-07 +4465 4457 4.887580871582e-06 +4466 4457 -96436338.25295 +4467 4457 2.503395080566e-06 +4468 4457 1.251697540283e-06 +4469 4457 49504413.35998 +4557 4457 17343888.52033 +4558 4457 -20812499.90895 +4559 4457 -24752206.67999 +4563 4457 -21679860.74398 +4564 4457 -69374999.6084 +4565 4457 -84490851.68299 +4566 4457 -17343888.84952 +4567 4457 -13874999.85144 +4568 4457 -65361760.6378 +4572 4457 -21679861.11823 +4573 4457 -17343750.0057 +4574 4457 -36432062.04358 +4575 4457 -86719444.24762 +4576 4457 -17343749.94044 +4577 4457 -110741809.7386 +4578 4457 -26015832.7805 +4579 4457 13874999.9393 +4580 4457 -24752206.67999 +4458 4458 1483949894.094 +4459 4458 7.867813110352e-06 +4460 4458 -5.507469177246e-05 +4461 4458 184322301.8864 +4462 4458 -2.622604370117e-06 +4463 4458 -1.358985900879e-05 +4470 4458 -406796532.3944 +4471 4458 -2.801418304443e-06 +4472 4458 -1.233816146851e-05 +4473 4458 -148365426.1266 +4474 4458 97222222.20624 +4475 4458 -3.308057785034e-06 +4560 4458 -138827443.8752 +4561 4458 2.682209014893e-07 +4562 4458 86719444.4302 +4563 4458 -46373434.23614 +4564 4458 -24305555.56354 +4565 4458 21679861.11823 +4569 4458 222474230.8735 +4570 4458 3.933906555176e-06 +4571 4458 2.622604370117e-05 +4572 4458 8952264.76783 +4573 4458 -1.302361488342e-05 +4574 4458 6.914138793945e-06 +4581 4458 -138827443.8751 +4582 4458 -5.066394805908e-07 +4583 4458 -86719444.43019 +4584 4458 -46373434.23611 +4585 4458 24305555.56353 +4586 4458 -21679861.11823 +4459 4459 1250608048.648 +4460 4459 -1.192092895508e-06 +4461 4459 -3.159046173096e-06 +4462 4459 -185121779.2034 +4463 4459 8.046627044678e-07 +4470 4459 -3.09944152832e-06 +4471 4459 20983010.02827 +4472 4459 -4.768371582031e-07 +4473 4459 97222222.20624 +4474 4459 -119197695.4315 +4475 4459 -7.450580596924e-08 +4560 4459 -2.294778823853e-06 +4561 4459 -31882558.21685 +4562 4459 2.682209014893e-07 +4563 4459 -24305555.56354 +4564 4459 -39081501.55876 +4565 4459 17343750.0057 +4569 4459 4.410743713379e-06 +4570 4459 164138769.4832 +4571 4459 -1.192092895508e-07 +4572 4459 -1.156330108643e-05 +4573 4459 -83408755.55014 +4574 4459 69374999.9886 +4581 4459 -8.344650268555e-07 +4582 4459 -31882558.21681 +4583 4459 -3.278255462646e-07 +4584 4459 24305555.56353 +4585 4459 -39081501.55875 +4586 4459 17343750.00569 +4460 4460 1165825984.246 +4461 4460 -1.382827758789e-05 +4462 4460 1.788139343262e-07 +4463 4460 104791324.3853 +4470 4460 -1.20997428894e-05 +4471 4460 -4.768371582031e-07 +4472 4460 -212506.0825927 +4473 4460 -3.278255462646e-06 +4474 4460 -2.086162567139e-07 +4475 4460 -46719419.49861 +4560 4460 86719444.4302 +4561 4460 3.427267074585e-07 +4562 4460 -99061955.12464 +4563 4460 21679861.11823 +4564 4460 17343750.0057 +4565 4460 -36432062.04359 +4569 4460 2.598762512207e-05 +4570 4460 5.960464477539e-08 +4571 4460 -104578818.0156 +4572 4460 6.973743438721e-06 +4573 4460 69374999.9886 +4574 4460 -72810997.49471 +4581 4460 -86719444.43019 +4582 4460 -2.682209014893e-07 +4583 4460 -99061955.12461 +4584 4460 -21679861.11823 +4585 4460 17343750.00569 +4586 4460 -36432062.04358 +4461 4461 1483949894.094 +4462 4461 7.867813110352e-06 +4463 4461 -5.507469177246e-05 +4464 4461 184322301.8864 +4465 4461 -2.622604370117e-06 +4466 4461 -1.358985900879e-05 +4470 4461 -148365426.1266 +4471 4461 -97222222.20624 +4472 4461 -3.039836883545e-06 +4473 4461 -406796532.3944 +4474 4461 -2.801418304443e-06 +4475 4461 -1.233816146851e-05 +4476 4461 -148365426.1266 +4477 4461 97222222.20624 +4478 4461 -3.308057785034e-06 +4560 4461 -46373434.23613 +4561 4461 24305555.56354 +4562 4461 21679861.11823 +4563 4461 -138827443.8752 +4564 4461 2.682209014893e-07 +4565 4461 86719444.4302 +4566 4461 -46373434.23614 +4567 4461 -24305555.56354 +4568 4461 21679861.11823 +4569 4461 8952264.76783 +4570 4461 9.298324584961e-06 +4571 4461 6.228685379028e-06 +4572 4461 222474230.8735 +4573 4461 3.933906555176e-06 +4574 4461 2.622604370117e-05 +4575 4461 8952264.76783 +4576 4461 -1.302361488342e-05 +4577 4461 6.914138793945e-06 +4581 4461 -46373434.23611 +4582 4461 -24305555.56353 +4583 4461 -21679861.11823 +4584 4461 -138827443.8751 +4585 4461 -5.066394805908e-07 +4586 4461 -86719444.43019 +4587 4461 -46373434.23611 +4588 4461 24305555.56353 +4589 4461 -21679861.11823 +4462 4462 1250608048.648 +4463 4462 -1.192092895508e-06 +4464 4462 -3.159046173096e-06 +4465 4462 -185121779.2034 +4466 4462 8.046627044678e-07 +4470 4462 -97222222.20624 +4471 4462 -119197695.4315 +4472 4462 2.831220626831e-07 +4473 4462 -3.09944152832e-06 +4474 4462 20983010.02827 +4475 4462 -4.768371582031e-07 +4476 4462 97222222.20624 +4477 4462 -119197695.4315 +4478 4462 -7.450580596924e-08 +4560 4462 24305555.56354 +4561 4462 -39081501.55876 +4562 4462 -17343750.00569 +4563 4462 -2.294778823853e-06 +4564 4462 -31882558.21685 +4565 4462 2.682209014893e-07 +4566 4462 -24305555.56354 +4567 4462 -39081501.55876 +4568 4462 17343750.0057 +4569 4462 1.069903373718e-05 +4570 4462 -83408755.55014 +4571 4462 -69374999.9886 +4572 4462 4.410743713379e-06 +4573 4462 164138769.4832 +4574 4462 -1.192092895508e-07 +4575 4462 -1.156330108643e-05 +4576 4462 -83408755.55014 +4577 4462 69374999.9886 +4581 4462 -24305555.56353 +4582 4462 -39081501.55875 +4583 4462 -17343750.0057 +4584 4462 -8.344650268555e-07 +4585 4462 -31882558.21681 +4586 4462 -3.278255462646e-07 +4587 4462 24305555.56353 +4588 4462 -39081501.55875 +4589 4462 17343750.00569 +4463 4463 1165825984.246 +4464 4463 -1.382827758789e-05 +4465 4463 1.788139343262e-07 +4466 4463 104791324.3853 +4470 4463 -2.890825271606e-06 +4471 4463 3.8743019104e-07 +4472 4463 -46719419.49861 +4473 4463 -1.20997428894e-05 +4474 4463 -4.768371582031e-07 +4475 4463 -212506.0825927 +4476 4463 -3.278255462646e-06 +4477 4463 -2.086162567139e-07 +4478 4463 -46719419.49861 +4560 4463 21679861.11823 +4561 4463 -17343750.0057 +4562 4463 -36432062.04359 +4563 4463 86719444.4302 +4564 4463 3.427267074585e-07 +4565 4463 -99061955.12464 +4566 4463 21679861.11823 +4567 4463 17343750.0057 +4568 4463 -36432062.04359 +4569 4463 6.169080734253e-06 +4570 4463 -69374999.9886 +4571 4463 -72810997.49471 +4572 4463 2.598762512207e-05 +4573 4463 5.960464477539e-08 +4574 4463 -104578818.0156 +4575 4463 6.973743438721e-06 +4576 4463 69374999.9886 +4577 4463 -72810997.49471 +4581 4463 -21679861.11823 +4582 4463 -17343750.0057 +4583 4463 -36432062.04358 +4584 4463 -86719444.43019 +4585 4463 -2.682209014893e-07 +4586 4463 -99061955.12461 +4587 4463 -21679861.11823 +4588 4463 17343750.00569 +4589 4463 -36432062.04358 +4464 4464 1632315315.374 +4465 4464 97222220.26178 +4466 4464 -4.172325134277e-05 +4467 4464 17392720.97666 +4468 4464 -97222221.42845 +4469 4464 -2.145767211914e-06 +4473 4464 -148365426.1266 +4474 4464 -97222222.20624 +4475 4464 -3.039836883545e-06 +4476 4464 -406796532.3944 +4477 4464 -2.801418304443e-06 +4478 4464 -1.233816146851e-05 +4479 4464 -148365426.1266 +4480 4464 97222222.20624 +4481 4464 -3.308057785034e-06 +4563 4464 -46373434.23613 +4564 4464 24305555.56354 +4565 4464 21679861.11823 +4566 4464 -175918799.4897 +4567 4464 -24305555.27186 +4568 4464 86719444.24762 +4572 4464 8952264.76783 +4573 4464 9.298324584961e-06 +4574 4464 6.228685379028e-06 +4575 4464 268847663.9159 +4576 4464 24305555.07742 +4577 4464 0.03653132915497 +4578 4464 -28139091.37671 +4579 4464 -24305555.36909 +4580 4464 21679860.74398 +4584 4464 -46373434.23611 +4585 4464 -24305555.56353 +4586 4464 -21679861.11823 +4587 4464 -138827443.8751 +4588 4464 -5.066394805908e-07 +4589 4464 -86719444.43019 +4590 4464 -46373434.23611 +4591 4464 24305555.56353 +4592 4464 -21679861.11823 +4465 4465 1369805740.108 +4466 4465 -2.145767211914e-06 +4467 4465 -97222221.03956 +4468 4465 -322883627.8625 +4469 4465 4.798173904419e-06 +4473 4465 -97222222.20624 +4474 4465 -119197695.4315 +4475 4465 2.831220626831e-07 +4476 4465 -3.09944152832e-06 +4477 4465 20983010.02827 +4478 4465 -4.768371582031e-07 +4479 4465 97222222.20624 +4480 4465 -119197695.4315 +4481 4465 -7.450580596924e-08 +4563 4465 24305555.56354 +4564 4465 -39081501.55876 +4565 4465 -17343750.00569 +4566 4465 -24305555.36908 +4567 4465 -61681981.7616 +4568 4465 17343749.94043 +4572 4465 1.069903373718e-05 +4573 4465 -83408755.55014 +4574 4465 -69374999.9886 +4575 4465 24305555.07742 +4576 4465 203220270.0671 +4577 4465 0.02920919656754 +4578 4465 -24305555.27186 +4579 4465 -113208178.6284 +4580 4465 69374999.6084 +4584 4465 -24305555.56353 +4585 4465 -39081501.55875 +4586 4465 -17343750.0057 +4587 4465 -8.344650268555e-07 +4588 4465 -31882558.21681 +4589 4465 -3.278255462646e-07 +4590 4465 24305555.56353 +4591 4465 -39081501.55875 +4592 4465 17343750.00569 +4466 4466 1212545401.289 +4467 4466 -1.788139343262e-06 +4468 4466 3.75509262085e-06 +4469 4466 8567490.576108 +4473 4466 -2.890825271606e-06 +4474 4466 3.8743019104e-07 +4475 4466 -46719419.49861 +4476 4466 -1.20997428894e-05 +4477 4466 -4.768371582031e-07 +4478 4466 -212506.0825927 +4479 4466 -3.278255462646e-06 +4480 4466 -2.086162567139e-07 +4481 4466 -46719419.49861 +4563 4466 21679861.11823 +4564 4466 -17343750.0057 +4565 4466 -36432062.04359 +4566 4466 86719444.24762 +4567 4466 17343749.9078 +4568 4466 -110741809.7386 +4572 4466 6.169080734253e-06 +4573 4466 -69374999.9886 +4574 4466 -72810997.49471 +4575 4466 -0.03649973869324 +4576 4466 -0.02921465039253 +4577 4466 -68146756.53808 +4578 4466 21679860.55685 +4579 4466 69374999.49133 +4580 4466 -84490851.68298 +4584 4466 -21679861.11823 +4585 4466 -17343750.0057 +4586 4466 -36432062.04358 +4587 4466 -86719444.43019 +4588 4466 -2.682209014893e-07 +4589 4466 -99061955.12461 +4590 4466 -21679861.11823 +4591 4466 17343750.00569 +4592 4466 -36432062.04358 +4467 4467 927468678.158 +4468 4467 97222222.20623 +4469 4467 -8.106231689453e-06 +4476 4467 -148365426.1266 +4477 4467 -97222222.20624 +4478 4467 -3.039836883545e-06 +4479 4467 -573726109.9308 +4480 4467 -97222221.42845 +4481 4467 8.940696716309e-07 +4482 4467 18564155.00999 +4483 4467 77777776.9872 +4484 4467 2.861022949219e-06 +4566 4467 -9282077.50499 +4567 4467 29166666.38457 +4568 4467 26015832.78049 +4575 4467 -28139091.37673 +4576 4467 -24305555.27187 +4577 4467 -21679860.55685 +4578 4467 139046393.5639 +4579 4467 24305555.56354 +4580 4467 17343888.84952 +4587 4467 -46373434.23611 +4588 4467 -24305555.56353 +4589 4467 -21679861.11823 +4590 4467 -175918799.4896 +4591 4467 -24305555.36909 +4592 4467 -86719444.24762 +4593 4467 -9282077.505002 +4594 4467 19444444.25638 +4595 4467 -17343888.52033 +4468 4468 781630025.6149 +4469 4468 8.412431954121e-06 +4476 4468 -97222222.20624 +4477 4468 -119197695.4315 +4478 4468 2.831220626831e-07 +4479 4468 -97222221.03956 +4480 4468 -116778839.2437 +4481 4468 5.602836608887e-06 +4482 4468 116666665.4808 +4483 4468 18564155.00998 +4484 4468 5.960464477539e-07 +4566 4468 19444444.25638 +4567 4468 -9282077.505 +4568 4468 -13874999.9393 +4575 4468 -24305555.36909 +4576 4468 -113208178.6284 +4577 4468 -69374999.49133 +4578 4468 24305555.56354 +4579 4468 102586730.4102 +4580 4468 13874999.85143 +4587 4468 -24305555.56353 +4588 4468 -39081501.55875 +4589 4468 -17343750.0057 +4590 4468 -24305555.27187 +4591 4468 -61681981.76159 +4592 4468 -17343749.90781 +4593 4468 29166666.38457 +4594 4468 -9282077.504995 +4595 4468 20812499.90894 +4469 4469 728641235.3813 +4476 4469 -2.890825271606e-06 +4477 4469 3.8743019104e-07 +4478 4469 -46719419.49861 +4479 4469 4.172325134277e-07 +4480 4469 4.887580871582e-06 +4481 4469 -96436338.25295 +4482 4469 2.503395080566e-06 +4483 4469 1.251697540283e-06 +4484 4469 49504413.35998 +4566 4469 17343888.52033 +4567 4469 -20812499.90895 +4568 4469 -24752206.67999 +4575 4469 -21679860.74398 +4576 4469 -69374999.6084 +4577 4469 -84490851.68299 +4578 4469 -17343888.84952 +4579 4469 -13874999.85144 +4580 4469 -65361760.6378 +4587 4469 -21679861.11823 +4588 4469 -17343750.0057 +4589 4469 -36432062.04358 +4590 4469 -86719444.24762 +4591 4469 -17343749.94044 +4592 4469 -110741809.7386 +4593 4469 -26015832.7805 +4594 4469 13874999.9393 +4595 4469 -24752206.67999 +4470 4470 1483949894.094 +4471 4470 7.867813110352e-06 +4472 4470 -5.507469177246e-05 +4473 4470 184322301.8864 +4474 4470 -2.622604370117e-06 +4475 4470 -1.358985900879e-05 +4485 4470 -406796532.3944 +4486 4470 -2.801418304443e-06 +4487 4470 -1.233816146851e-05 +4488 4470 -148365426.1266 +4489 4470 97222222.20624 +4490 4470 -3.308057785034e-06 +4569 4470 -138827443.8752 +4570 4470 2.682209014893e-07 +4571 4470 86719444.4302 +4572 4470 -46373434.23614 +4573 4470 -24305555.56354 +4574 4470 21679861.11823 +4581 4470 222474230.8735 +4582 4470 3.933906555176e-06 +4583 4470 2.622604370117e-05 +4584 4470 8952264.76783 +4585 4470 -1.302361488342e-05 +4586 4470 6.914138793945e-06 +4596 4470 -138827443.8751 +4597 4470 -5.066394805908e-07 +4598 4470 -86719444.43019 +4599 4470 -46373434.23611 +4600 4470 24305555.56353 +4601 4470 -21679861.11823 +4471 4471 1250608048.648 +4472 4471 -1.192092895508e-06 +4473 4471 -3.159046173096e-06 +4474 4471 -185121779.2034 +4475 4471 8.046627044678e-07 +4485 4471 -3.09944152832e-06 +4486 4471 20983010.02827 +4487 4471 -4.768371582031e-07 +4488 4471 97222222.20624 +4489 4471 -119197695.4315 +4490 4471 -7.450580596924e-08 +4569 4471 -2.294778823853e-06 +4570 4471 -31882558.21685 +4571 4471 2.682209014893e-07 +4572 4471 -24305555.56354 +4573 4471 -39081501.55876 +4574 4471 17343750.0057 +4581 4471 4.410743713379e-06 +4582 4471 164138769.4832 +4583 4471 -1.192092895508e-07 +4584 4471 -1.156330108643e-05 +4585 4471 -83408755.55014 +4586 4471 69374999.9886 +4596 4471 -8.344650268555e-07 +4597 4471 -31882558.21681 +4598 4471 -3.278255462646e-07 +4599 4471 24305555.56353 +4600 4471 -39081501.55875 +4601 4471 17343750.00569 +4472 4472 1165825984.246 +4473 4472 -1.382827758789e-05 +4474 4472 1.788139343262e-07 +4475 4472 104791324.3853 +4485 4472 -1.20997428894e-05 +4486 4472 -4.768371582031e-07 +4487 4472 -212506.0825927 +4488 4472 -3.278255462646e-06 +4489 4472 -2.086162567139e-07 +4490 4472 -46719419.49861 +4569 4472 86719444.4302 +4570 4472 3.427267074585e-07 +4571 4472 -99061955.12464 +4572 4472 21679861.11823 +4573 4472 17343750.0057 +4574 4472 -36432062.04359 +4581 4472 2.598762512207e-05 +4582 4472 5.960464477539e-08 +4583 4472 -104578818.0156 +4584 4472 6.973743438721e-06 +4585 4472 69374999.9886 +4586 4472 -72810997.49471 +4596 4472 -86719444.43019 +4597 4472 -2.682209014893e-07 +4598 4472 -99061955.12461 +4599 4472 -21679861.11823 +4600 4472 17343750.00569 +4601 4472 -36432062.04358 +4473 4473 1483949894.094 +4474 4473 7.867813110352e-06 +4475 4473 -5.507469177246e-05 +4476 4473 184322301.8864 +4477 4473 -2.622604370117e-06 +4478 4473 -1.358985900879e-05 +4485 4473 -148365426.1266 +4486 4473 -97222222.20624 +4487 4473 -3.039836883545e-06 +4488 4473 -406796532.3944 +4489 4473 -2.801418304443e-06 +4490 4473 -1.233816146851e-05 +4491 4473 -148365426.1266 +4492 4473 97222222.20624 +4493 4473 -3.308057785034e-06 +4569 4473 -46373434.23613 +4570 4473 24305555.56354 +4571 4473 21679861.11823 +4572 4473 -138827443.8752 +4573 4473 2.682209014893e-07 +4574 4473 86719444.4302 +4575 4473 -46373434.23614 +4576 4473 -24305555.56354 +4577 4473 21679861.11823 +4581 4473 8952264.76783 +4582 4473 9.298324584961e-06 +4583 4473 6.228685379028e-06 +4584 4473 222474230.8735 +4585 4473 3.933906555176e-06 +4586 4473 2.622604370117e-05 +4587 4473 8952264.76783 +4588 4473 -1.302361488342e-05 +4589 4473 6.914138793945e-06 +4596 4473 -46373434.23611 +4597 4473 -24305555.56353 +4598 4473 -21679861.11823 +4599 4473 -138827443.8751 +4600 4473 -5.066394805908e-07 +4601 4473 -86719444.43019 +4602 4473 -46373434.23611 +4603 4473 24305555.56353 +4604 4473 -21679861.11823 +4474 4474 1250608048.648 +4475 4474 -1.192092895508e-06 +4476 4474 -3.159046173096e-06 +4477 4474 -185121779.2034 +4478 4474 8.046627044678e-07 +4485 4474 -97222222.20624 +4486 4474 -119197695.4315 +4487 4474 2.831220626831e-07 +4488 4474 -3.09944152832e-06 +4489 4474 20983010.02827 +4490 4474 -4.768371582031e-07 +4491 4474 97222222.20624 +4492 4474 -119197695.4315 +4493 4474 -7.450580596924e-08 +4569 4474 24305555.56354 +4570 4474 -39081501.55876 +4571 4474 -17343750.00569 +4572 4474 -2.294778823853e-06 +4573 4474 -31882558.21685 +4574 4474 2.682209014893e-07 +4575 4474 -24305555.56354 +4576 4474 -39081501.55876 +4577 4474 17343750.0057 +4581 4474 1.069903373718e-05 +4582 4474 -83408755.55014 +4583 4474 -69374999.9886 +4584 4474 4.410743713379e-06 +4585 4474 164138769.4832 +4586 4474 -1.192092895508e-07 +4587 4474 -1.156330108643e-05 +4588 4474 -83408755.55014 +4589 4474 69374999.9886 +4596 4474 -24305555.56353 +4597 4474 -39081501.55875 +4598 4474 -17343750.0057 +4599 4474 -8.344650268555e-07 +4600 4474 -31882558.21681 +4601 4474 -3.278255462646e-07 +4602 4474 24305555.56353 +4603 4474 -39081501.55875 +4604 4474 17343750.00569 +4475 4475 1165825984.246 +4476 4475 -1.382827758789e-05 +4477 4475 1.788139343262e-07 +4478 4475 104791324.3853 +4485 4475 -2.890825271606e-06 +4486 4475 3.8743019104e-07 +4487 4475 -46719419.49861 +4488 4475 -1.20997428894e-05 +4489 4475 -4.768371582031e-07 +4490 4475 -212506.0825927 +4491 4475 -3.278255462646e-06 +4492 4475 -2.086162567139e-07 +4493 4475 -46719419.49861 +4569 4475 21679861.11823 +4570 4475 -17343750.0057 +4571 4475 -36432062.04359 +4572 4475 86719444.4302 +4573 4475 3.427267074585e-07 +4574 4475 -99061955.12464 +4575 4475 21679861.11823 +4576 4475 17343750.0057 +4577 4475 -36432062.04359 +4581 4475 6.169080734253e-06 +4582 4475 -69374999.9886 +4583 4475 -72810997.49471 +4584 4475 2.598762512207e-05 +4585 4475 5.960464477539e-08 +4586 4475 -104578818.0156 +4587 4475 6.973743438721e-06 +4588 4475 69374999.9886 +4589 4475 -72810997.49471 +4596 4475 -21679861.11823 +4597 4475 -17343750.0057 +4598 4475 -36432062.04358 +4599 4475 -86719444.43019 +4600 4475 -2.682209014893e-07 +4601 4475 -99061955.12461 +4602 4475 -21679861.11823 +4603 4475 17343750.00569 +4604 4475 -36432062.04358 +4476 4476 1483949894.094 +4477 4476 7.867813110352e-06 +4478 4476 -5.507469177246e-05 +4479 4476 184322301.8864 +4480 4476 -2.622604370117e-06 +4481 4476 -1.358985900879e-05 +4488 4476 -148365426.1266 +4489 4476 -97222222.20624 +4490 4476 -3.039836883545e-06 +4491 4476 -406796532.3944 +4492 4476 -2.801418304443e-06 +4493 4476 -1.233816146851e-05 +4494 4476 -148365426.1266 +4495 4476 97222222.20624 +4496 4476 -3.308057785034e-06 +4572 4476 -46373434.23613 +4573 4476 24305555.56354 +4574 4476 21679861.11823 +4575 4476 -138827443.8752 +4576 4476 2.682209014893e-07 +4577 4476 86719444.4302 +4578 4476 -46373434.23614 +4579 4476 -24305555.56354 +4580 4476 21679861.11823 +4584 4476 8952264.76783 +4585 4476 9.298324584961e-06 +4586 4476 6.228685379028e-06 +4587 4476 222474230.8735 +4588 4476 3.933906555176e-06 +4589 4476 2.622604370117e-05 +4590 4476 8952264.76783 +4591 4476 -1.302361488342e-05 +4592 4476 6.914138793945e-06 +4599 4476 -46373434.23611 +4600 4476 -24305555.56353 +4601 4476 -21679861.11823 +4602 4476 -138827443.8751 +4603 4476 -5.066394805908e-07 +4604 4476 -86719444.43019 +4605 4476 -46373434.23611 +4606 4476 24305555.56353 +4607 4476 -21679861.11823 +4477 4477 1250608048.648 +4478 4477 -1.192092895508e-06 +4479 4477 -3.159046173096e-06 +4480 4477 -185121779.2034 +4481 4477 8.046627044678e-07 +4488 4477 -97222222.20624 +4489 4477 -119197695.4315 +4490 4477 2.831220626831e-07 +4491 4477 -3.09944152832e-06 +4492 4477 20983010.02827 +4493 4477 -4.768371582031e-07 +4494 4477 97222222.20624 +4495 4477 -119197695.4315 +4496 4477 -7.450580596924e-08 +4572 4477 24305555.56354 +4573 4477 -39081501.55876 +4574 4477 -17343750.00569 +4575 4477 -2.294778823853e-06 +4576 4477 -31882558.21685 +4577 4477 2.682209014893e-07 +4578 4477 -24305555.56354 +4579 4477 -39081501.55876 +4580 4477 17343750.0057 +4584 4477 1.069903373718e-05 +4585 4477 -83408755.55014 +4586 4477 -69374999.9886 +4587 4477 4.410743713379e-06 +4588 4477 164138769.4832 +4589 4477 -1.192092895508e-07 +4590 4477 -1.156330108643e-05 +4591 4477 -83408755.55014 +4592 4477 69374999.9886 +4599 4477 -24305555.56353 +4600 4477 -39081501.55875 +4601 4477 -17343750.0057 +4602 4477 -8.344650268555e-07 +4603 4477 -31882558.21681 +4604 4477 -3.278255462646e-07 +4605 4477 24305555.56353 +4606 4477 -39081501.55875 +4607 4477 17343750.00569 +4478 4478 1165825984.246 +4479 4478 -1.382827758789e-05 +4480 4478 1.788139343262e-07 +4481 4478 104791324.3853 +4488 4478 -2.890825271606e-06 +4489 4478 3.8743019104e-07 +4490 4478 -46719419.49861 +4491 4478 -1.20997428894e-05 +4492 4478 -4.768371582031e-07 +4493 4478 -212506.0825927 +4494 4478 -3.278255462646e-06 +4495 4478 -2.086162567139e-07 +4496 4478 -46719419.49861 +4572 4478 21679861.11823 +4573 4478 -17343750.0057 +4574 4478 -36432062.04359 +4575 4478 86719444.4302 +4576 4478 3.427267074585e-07 +4577 4478 -99061955.12464 +4578 4478 21679861.11823 +4579 4478 17343750.0057 +4580 4478 -36432062.04359 +4584 4478 6.169080734253e-06 +4585 4478 -69374999.9886 +4586 4478 -72810997.49471 +4587 4478 2.598762512207e-05 +4588 4478 5.960464477539e-08 +4589 4478 -104578818.0156 +4590 4478 6.973743438721e-06 +4591 4478 69374999.9886 +4592 4478 -72810997.49471 +4599 4478 -21679861.11823 +4600 4478 -17343750.0057 +4601 4478 -36432062.04358 +4602 4478 -86719444.43019 +4603 4478 -2.682209014893e-07 +4604 4478 -99061955.12461 +4605 4478 -21679861.11823 +4606 4478 17343750.00569 +4607 4478 -36432062.04358 +4479 4479 1632315315.374 +4480 4479 97222220.26178 +4481 4479 -4.172325134277e-05 +4482 4479 17392720.97666 +4483 4479 -97222221.42845 +4484 4479 -2.145767211914e-06 +4491 4479 -148365426.1266 +4492 4479 -97222222.20624 +4493 4479 -3.039836883545e-06 +4494 4479 -406796532.3944 +4495 4479 -2.801418304443e-06 +4496 4479 -1.233816146851e-05 +4497 4479 -148365426.1266 +4498 4479 97222222.20624 +4499 4479 -3.308057785034e-06 +4575 4479 -46373434.23613 +4576 4479 24305555.56354 +4577 4479 21679861.11823 +4578 4479 -175918799.4897 +4579 4479 -24305555.27186 +4580 4479 86719444.24762 +4587 4479 8952264.76783 +4588 4479 9.298324584961e-06 +4589 4479 6.228685379028e-06 +4590 4479 268847663.9159 +4591 4479 24305555.07742 +4592 4479 0.03653132915497 +4593 4479 -28139091.37671 +4594 4479 -24305555.36909 +4595 4479 21679860.74398 +4602 4479 -46373434.23611 +4603 4479 -24305555.56353 +4604 4479 -21679861.11823 +4605 4479 -138827443.8751 +4606 4479 -5.066394805908e-07 +4607 4479 -86719444.43019 +4608 4479 -46373434.23611 +4609 4479 24305555.56353 +4610 4479 -21679861.11823 +4480 4480 1369805740.108 +4481 4480 -2.145767211914e-06 +4482 4480 -97222221.03956 +4483 4480 -322883627.8625 +4484 4480 4.798173904419e-06 +4491 4480 -97222222.20624 +4492 4480 -119197695.4315 +4493 4480 2.831220626831e-07 +4494 4480 -3.09944152832e-06 +4495 4480 20983010.02827 +4496 4480 -4.768371582031e-07 +4497 4480 97222222.20624 +4498 4480 -119197695.4315 +4499 4480 -7.450580596924e-08 +4575 4480 24305555.56354 +4576 4480 -39081501.55876 +4577 4480 -17343750.00569 +4578 4480 -24305555.36908 +4579 4480 -61681981.7616 +4580 4480 17343749.94043 +4587 4480 1.069903373718e-05 +4588 4480 -83408755.55014 +4589 4480 -69374999.9886 +4590 4480 24305555.07742 +4591 4480 203220270.0671 +4592 4480 0.02920919656754 +4593 4480 -24305555.27186 +4594 4480 -113208178.6284 +4595 4480 69374999.6084 +4602 4480 -24305555.56353 +4603 4480 -39081501.55875 +4604 4480 -17343750.0057 +4605 4480 -8.344650268555e-07 +4606 4480 -31882558.21681 +4607 4480 -3.278255462646e-07 +4608 4480 24305555.56353 +4609 4480 -39081501.55875 +4610 4480 17343750.00569 +4481 4481 1212545401.289 +4482 4481 -1.788139343262e-06 +4483 4481 3.75509262085e-06 +4484 4481 8567490.576108 +4491 4481 -2.890825271606e-06 +4492 4481 3.8743019104e-07 +4493 4481 -46719419.49861 +4494 4481 -1.20997428894e-05 +4495 4481 -4.768371582031e-07 +4496 4481 -212506.0825927 +4497 4481 -3.278255462646e-06 +4498 4481 -2.086162567139e-07 +4499 4481 -46719419.49861 +4575 4481 21679861.11823 +4576 4481 -17343750.0057 +4577 4481 -36432062.04359 +4578 4481 86719444.24762 +4579 4481 17343749.9078 +4580 4481 -110741809.7386 +4587 4481 6.169080734253e-06 +4588 4481 -69374999.9886 +4589 4481 -72810997.49471 +4590 4481 -0.03649973869324 +4591 4481 -0.02921465039253 +4592 4481 -68146756.53808 +4593 4481 21679860.55685 +4594 4481 69374999.49133 +4595 4481 -84490851.68298 +4602 4481 -21679861.11823 +4603 4481 -17343750.0057 +4604 4481 -36432062.04358 +4605 4481 -86719444.43019 +4606 4481 -2.682209014893e-07 +4607 4481 -99061955.12461 +4608 4481 -21679861.11823 +4609 4481 17343750.00569 +4610 4481 -36432062.04358 +4482 4482 927468678.158 +4483 4482 97222222.20623 +4484 4482 -8.106231689453e-06 +4494 4482 -148365426.1266 +4495 4482 -97222222.20624 +4496 4482 -3.039836883545e-06 +4497 4482 -573726109.9308 +4498 4482 -97222221.42845 +4499 4482 8.940696716309e-07 +4500 4482 18564155.00999 +4501 4482 77777776.9872 +4502 4482 2.861022949219e-06 +4578 4482 -9282077.50499 +4579 4482 29166666.38457 +4580 4482 26015832.78049 +4590 4482 -28139091.37673 +4591 4482 -24305555.27187 +4592 4482 -21679860.55685 +4593 4482 139046393.5639 +4594 4482 24305555.56354 +4595 4482 17343888.84952 +4605 4482 -46373434.23611 +4606 4482 -24305555.56353 +4607 4482 -21679861.11823 +4608 4482 -175918799.4896 +4609 4482 -24305555.36909 +4610 4482 -86719444.24762 +4611 4482 -9282077.505002 +4612 4482 19444444.25638 +4613 4482 -17343888.52033 +4483 4483 781630025.6149 +4484 4483 8.412431954121e-06 +4494 4483 -97222222.20624 +4495 4483 -119197695.4315 +4496 4483 2.831220626831e-07 +4497 4483 -97222221.03956 +4498 4483 -116778839.2437 +4499 4483 5.602836608887e-06 +4500 4483 116666665.4808 +4501 4483 18564155.00998 +4502 4483 5.960464477539e-07 +4578 4483 19444444.25638 +4579 4483 -9282077.505 +4580 4483 -13874999.9393 +4590 4483 -24305555.36909 +4591 4483 -113208178.6284 +4592 4483 -69374999.49133 +4593 4483 24305555.56354 +4594 4483 102586730.4102 +4595 4483 13874999.85143 +4605 4483 -24305555.56353 +4606 4483 -39081501.55875 +4607 4483 -17343750.0057 +4608 4483 -24305555.27187 +4609 4483 -61681981.76159 +4610 4483 -17343749.90781 +4611 4483 29166666.38457 +4612 4483 -9282077.504995 +4613 4483 20812499.90894 +4484 4484 728641235.3813 +4494 4484 -2.890825271606e-06 +4495 4484 3.8743019104e-07 +4496 4484 -46719419.49861 +4497 4484 4.172325134277e-07 +4498 4484 4.887580871582e-06 +4499 4484 -96436338.25295 +4500 4484 2.503395080566e-06 +4501 4484 1.251697540283e-06 +4502 4484 49504413.35998 +4578 4484 17343888.52033 +4579 4484 -20812499.90895 +4580 4484 -24752206.67999 +4590 4484 -21679860.74398 +4591 4484 -69374999.6084 +4592 4484 -84490851.68299 +4593 4484 -17343888.84952 +4594 4484 -13874999.85144 +4595 4484 -65361760.6378 +4605 4484 -21679861.11823 +4606 4484 -17343750.0057 +4607 4484 -36432062.04358 +4608 4484 -86719444.24762 +4609 4484 -17343749.94044 +4610 4484 -110741809.7386 +4611 4484 -26015832.7805 +4612 4484 13874999.9393 +4613 4484 -24752206.67999 +4485 4485 1483949894.094 +4486 4485 7.867813110352e-06 +4487 4485 -5.507469177246e-05 +4488 4485 184322301.8864 +4489 4485 -2.622604370117e-06 +4490 4485 -1.358985900879e-05 +4503 4485 -406796532.3944 +4504 4485 -2.801418304443e-06 +4505 4485 -1.233816146851e-05 +4506 4485 -148365426.1266 +4507 4485 97222222.20624 +4508 4485 -3.308057785034e-06 +4581 4485 -138827443.8752 +4582 4485 2.682209014893e-07 +4583 4485 86719444.4302 +4584 4485 -46373434.23614 +4585 4485 -24305555.56354 +4586 4485 21679861.11823 +4596 4485 222474230.8735 +4597 4485 3.933906555176e-06 +4598 4485 2.622604370117e-05 +4599 4485 8952264.76783 +4600 4485 -1.302361488342e-05 +4601 4485 6.914138793945e-06 +4614 4485 -138827443.8751 +4615 4485 -5.066394805908e-07 +4616 4485 -86719444.43019 +4617 4485 -46373434.23611 +4618 4485 24305555.56353 +4619 4485 -21679861.11823 +4486 4486 1250608048.648 +4487 4486 -1.192092895508e-06 +4488 4486 -3.159046173096e-06 +4489 4486 -185121779.2034 +4490 4486 8.046627044678e-07 +4503 4486 -3.09944152832e-06 +4504 4486 20983010.02827 +4505 4486 -4.768371582031e-07 +4506 4486 97222222.20624 +4507 4486 -119197695.4315 +4508 4486 -7.450580596924e-08 +4581 4486 -2.294778823853e-06 +4582 4486 -31882558.21685 +4583 4486 2.682209014893e-07 +4584 4486 -24305555.56354 +4585 4486 -39081501.55876 +4586 4486 17343750.0057 +4596 4486 4.410743713379e-06 +4597 4486 164138769.4832 +4598 4486 -1.192092895508e-07 +4599 4486 -1.156330108643e-05 +4600 4486 -83408755.55014 +4601 4486 69374999.9886 +4614 4486 -8.344650268555e-07 +4615 4486 -31882558.21681 +4616 4486 -3.278255462646e-07 +4617 4486 24305555.56353 +4618 4486 -39081501.55875 +4619 4486 17343750.00569 +4487 4487 1165825984.246 +4488 4487 -1.382827758789e-05 +4489 4487 1.788139343262e-07 +4490 4487 104791324.3853 +4503 4487 -1.20997428894e-05 +4504 4487 -4.768371582031e-07 +4505 4487 -212506.0825927 +4506 4487 -3.278255462646e-06 +4507 4487 -2.086162567139e-07 +4508 4487 -46719419.49861 +4581 4487 86719444.4302 +4582 4487 3.427267074585e-07 +4583 4487 -99061955.12464 +4584 4487 21679861.11823 +4585 4487 17343750.0057 +4586 4487 -36432062.04359 +4596 4487 2.598762512207e-05 +4597 4487 5.960464477539e-08 +4598 4487 -104578818.0156 +4599 4487 6.973743438721e-06 +4600 4487 69374999.9886 +4601 4487 -72810997.49471 +4614 4487 -86719444.43019 +4615 4487 -2.682209014893e-07 +4616 4487 -99061955.12461 +4617 4487 -21679861.11823 +4618 4487 17343750.00569 +4619 4487 -36432062.04358 +4488 4488 1483949894.094 +4489 4488 7.867813110352e-06 +4490 4488 -5.507469177246e-05 +4491 4488 184322301.8864 +4492 4488 -2.622604370117e-06 +4493 4488 -1.358985900879e-05 +4503 4488 -148365426.1266 +4504 4488 -97222222.20624 +4505 4488 -3.039836883545e-06 +4506 4488 -406796532.3944 +4507 4488 -2.801418304443e-06 +4508 4488 -1.233816146851e-05 +4509 4488 -148365426.1266 +4510 4488 97222222.20624 +4511 4488 -3.308057785034e-06 +4581 4488 -46373434.23613 +4582 4488 24305555.56354 +4583 4488 21679861.11823 +4584 4488 -138827443.8752 +4585 4488 2.682209014893e-07 +4586 4488 86719444.4302 +4587 4488 -46373434.23614 +4588 4488 -24305555.56354 +4589 4488 21679861.11823 +4596 4488 8952264.76783 +4597 4488 9.298324584961e-06 +4598 4488 6.228685379028e-06 +4599 4488 222474230.8735 +4600 4488 3.933906555176e-06 +4601 4488 2.622604370117e-05 +4602 4488 8952264.76783 +4603 4488 -1.302361488342e-05 +4604 4488 6.914138793945e-06 +4614 4488 -46373434.23611 +4615 4488 -24305555.56353 +4616 4488 -21679861.11823 +4617 4488 -138827443.8751 +4618 4488 -5.066394805908e-07 +4619 4488 -86719444.43019 +4620 4488 -46373434.23611 +4621 4488 24305555.56353 +4622 4488 -21679861.11823 +4489 4489 1250608048.648 +4490 4489 -1.192092895508e-06 +4491 4489 -3.159046173096e-06 +4492 4489 -185121779.2034 +4493 4489 8.046627044678e-07 +4503 4489 -97222222.20624 +4504 4489 -119197695.4315 +4505 4489 2.831220626831e-07 +4506 4489 -3.09944152832e-06 +4507 4489 20983010.02827 +4508 4489 -4.768371582031e-07 +4509 4489 97222222.20624 +4510 4489 -119197695.4315 +4511 4489 -7.450580596924e-08 +4581 4489 24305555.56354 +4582 4489 -39081501.55876 +4583 4489 -17343750.00569 +4584 4489 -2.294778823853e-06 +4585 4489 -31882558.21685 +4586 4489 2.682209014893e-07 +4587 4489 -24305555.56354 +4588 4489 -39081501.55876 +4589 4489 17343750.0057 +4596 4489 1.069903373718e-05 +4597 4489 -83408755.55014 +4598 4489 -69374999.9886 +4599 4489 4.410743713379e-06 +4600 4489 164138769.4832 +4601 4489 -1.192092895508e-07 +4602 4489 -1.156330108643e-05 +4603 4489 -83408755.55014 +4604 4489 69374999.9886 +4614 4489 -24305555.56353 +4615 4489 -39081501.55875 +4616 4489 -17343750.0057 +4617 4489 -8.344650268555e-07 +4618 4489 -31882558.21681 +4619 4489 -3.278255462646e-07 +4620 4489 24305555.56353 +4621 4489 -39081501.55875 +4622 4489 17343750.00569 +4490 4490 1165825984.246 +4491 4490 -1.382827758789e-05 +4492 4490 1.788139343262e-07 +4493 4490 104791324.3853 +4503 4490 -2.890825271606e-06 +4504 4490 3.8743019104e-07 +4505 4490 -46719419.49861 +4506 4490 -1.20997428894e-05 +4507 4490 -4.768371582031e-07 +4508 4490 -212506.0825927 +4509 4490 -3.278255462646e-06 +4510 4490 -2.086162567139e-07 +4511 4490 -46719419.49861 +4581 4490 21679861.11823 +4582 4490 -17343750.0057 +4583 4490 -36432062.04359 +4584 4490 86719444.4302 +4585 4490 3.427267074585e-07 +4586 4490 -99061955.12464 +4587 4490 21679861.11823 +4588 4490 17343750.0057 +4589 4490 -36432062.04359 +4596 4490 6.169080734253e-06 +4597 4490 -69374999.9886 +4598 4490 -72810997.49471 +4599 4490 2.598762512207e-05 +4600 4490 5.960464477539e-08 +4601 4490 -104578818.0156 +4602 4490 6.973743438721e-06 +4603 4490 69374999.9886 +4604 4490 -72810997.49471 +4614 4490 -21679861.11823 +4615 4490 -17343750.0057 +4616 4490 -36432062.04358 +4617 4490 -86719444.43019 +4618 4490 -2.682209014893e-07 +4619 4490 -99061955.12461 +4620 4490 -21679861.11823 +4621 4490 17343750.00569 +4622 4490 -36432062.04358 +4491 4491 1483949894.094 +4492 4491 7.867813110352e-06 +4493 4491 -5.507469177246e-05 +4494 4491 184322301.8864 +4495 4491 -2.622604370117e-06 +4496 4491 -1.358985900879e-05 +4506 4491 -148365426.1266 +4507 4491 -97222222.20624 +4508 4491 -3.039836883545e-06 +4509 4491 -406796532.3944 +4510 4491 -2.801418304443e-06 +4511 4491 -1.233816146851e-05 +4512 4491 -148365426.1266 +4513 4491 97222222.20624 +4514 4491 -3.308057785034e-06 +4584 4491 -46373434.23613 +4585 4491 24305555.56354 +4586 4491 21679861.11823 +4587 4491 -138827443.8752 +4588 4491 2.682209014893e-07 +4589 4491 86719444.4302 +4590 4491 -46373434.23614 +4591 4491 -24305555.56354 +4592 4491 21679861.11823 +4599 4491 8952264.76783 +4600 4491 9.298324584961e-06 +4601 4491 6.228685379028e-06 +4602 4491 222474230.8735 +4603 4491 3.933906555176e-06 +4604 4491 2.622604370117e-05 +4605 4491 8952264.76783 +4606 4491 -1.302361488342e-05 +4607 4491 6.914138793945e-06 +4617 4491 -46373434.23611 +4618 4491 -24305555.56353 +4619 4491 -21679861.11823 +4620 4491 -138827443.8751 +4621 4491 -5.066394805908e-07 +4622 4491 -86719444.43019 +4623 4491 -46373434.23611 +4624 4491 24305555.56353 +4625 4491 -21679861.11823 +4492 4492 1250608048.648 +4493 4492 -1.192092895508e-06 +4494 4492 -3.159046173096e-06 +4495 4492 -185121779.2034 +4496 4492 8.046627044678e-07 +4506 4492 -97222222.20624 +4507 4492 -119197695.4315 +4508 4492 2.831220626831e-07 +4509 4492 -3.09944152832e-06 +4510 4492 20983010.02827 +4511 4492 -4.768371582031e-07 +4512 4492 97222222.20624 +4513 4492 -119197695.4315 +4514 4492 -7.450580596924e-08 +4584 4492 24305555.56354 +4585 4492 -39081501.55876 +4586 4492 -17343750.00569 +4587 4492 -2.294778823853e-06 +4588 4492 -31882558.21685 +4589 4492 2.682209014893e-07 +4590 4492 -24305555.56354 +4591 4492 -39081501.55876 +4592 4492 17343750.0057 +4599 4492 1.069903373718e-05 +4600 4492 -83408755.55014 +4601 4492 -69374999.9886 +4602 4492 4.410743713379e-06 +4603 4492 164138769.4832 +4604 4492 -1.192092895508e-07 +4605 4492 -1.156330108643e-05 +4606 4492 -83408755.55014 +4607 4492 69374999.9886 +4617 4492 -24305555.56353 +4618 4492 -39081501.55875 +4619 4492 -17343750.0057 +4620 4492 -8.344650268555e-07 +4621 4492 -31882558.21681 +4622 4492 -3.278255462646e-07 +4623 4492 24305555.56353 +4624 4492 -39081501.55875 +4625 4492 17343750.00569 +4493 4493 1165825984.246 +4494 4493 -1.382827758789e-05 +4495 4493 1.788139343262e-07 +4496 4493 104791324.3853 +4506 4493 -2.890825271606e-06 +4507 4493 3.8743019104e-07 +4508 4493 -46719419.49861 +4509 4493 -1.20997428894e-05 +4510 4493 -4.768371582031e-07 +4511 4493 -212506.0825927 +4512 4493 -3.278255462646e-06 +4513 4493 -2.086162567139e-07 +4514 4493 -46719419.49861 +4584 4493 21679861.11823 +4585 4493 -17343750.0057 +4586 4493 -36432062.04359 +4587 4493 86719444.4302 +4588 4493 3.427267074585e-07 +4589 4493 -99061955.12464 +4590 4493 21679861.11823 +4591 4493 17343750.0057 +4592 4493 -36432062.04359 +4599 4493 6.169080734253e-06 +4600 4493 -69374999.9886 +4601 4493 -72810997.49471 +4602 4493 2.598762512207e-05 +4603 4493 5.960464477539e-08 +4604 4493 -104578818.0156 +4605 4493 6.973743438721e-06 +4606 4493 69374999.9886 +4607 4493 -72810997.49471 +4617 4493 -21679861.11823 +4618 4493 -17343750.0057 +4619 4493 -36432062.04358 +4620 4493 -86719444.43019 +4621 4493 -2.682209014893e-07 +4622 4493 -99061955.12461 +4623 4493 -21679861.11823 +4624 4493 17343750.00569 +4625 4493 -36432062.04358 +4494 4494 1483949894.094 +4495 4494 7.867813110352e-06 +4496 4494 -5.507469177246e-05 +4497 4494 184322301.8864 +4498 4494 -2.622604370117e-06 +4499 4494 -1.358985900879e-05 +4509 4494 -148365426.1266 +4510 4494 -97222222.20624 +4511 4494 -3.039836883545e-06 +4512 4494 -406796532.3944 +4513 4494 -2.801418304443e-06 +4514 4494 -1.233816146851e-05 +4515 4494 -148365426.1266 +4516 4494 97222222.20624 +4517 4494 -3.308057785034e-06 +4587 4494 -46373434.23613 +4588 4494 24305555.56354 +4589 4494 21679861.11823 +4590 4494 -138827443.8752 +4591 4494 2.682209014893e-07 +4592 4494 86719444.4302 +4593 4494 -46373434.23614 +4594 4494 -24305555.56354 +4595 4494 21679861.11823 +4602 4494 8952264.76783 +4603 4494 9.298324584961e-06 +4604 4494 6.228685379028e-06 +4605 4494 222474230.8735 +4606 4494 3.933906555176e-06 +4607 4494 2.622604370117e-05 +4608 4494 8952264.76783 +4609 4494 -1.302361488342e-05 +4610 4494 6.914138793945e-06 +4620 4494 -46373434.23611 +4621 4494 -24305555.56353 +4622 4494 -21679861.11823 +4623 4494 -138827443.8751 +4624 4494 -5.066394805908e-07 +4625 4494 -86719444.43019 +4626 4494 -46373434.23611 +4627 4494 24305555.56353 +4628 4494 -21679861.11823 +4495 4495 1250608048.648 +4496 4495 -1.192092895508e-06 +4497 4495 -3.159046173096e-06 +4498 4495 -185121779.2034 +4499 4495 8.046627044678e-07 +4509 4495 -97222222.20624 +4510 4495 -119197695.4315 +4511 4495 2.831220626831e-07 +4512 4495 -3.09944152832e-06 +4513 4495 20983010.02827 +4514 4495 -4.768371582031e-07 +4515 4495 97222222.20624 +4516 4495 -119197695.4315 +4517 4495 -7.450580596924e-08 +4587 4495 24305555.56354 +4588 4495 -39081501.55876 +4589 4495 -17343750.00569 +4590 4495 -2.294778823853e-06 +4591 4495 -31882558.21685 +4592 4495 2.682209014893e-07 +4593 4495 -24305555.56354 +4594 4495 -39081501.55876 +4595 4495 17343750.0057 +4602 4495 1.069903373718e-05 +4603 4495 -83408755.55014 +4604 4495 -69374999.9886 +4605 4495 4.410743713379e-06 +4606 4495 164138769.4832 +4607 4495 -1.192092895508e-07 +4608 4495 -1.156330108643e-05 +4609 4495 -83408755.55014 +4610 4495 69374999.9886 +4620 4495 -24305555.56353 +4621 4495 -39081501.55875 +4622 4495 -17343750.0057 +4623 4495 -8.344650268555e-07 +4624 4495 -31882558.21681 +4625 4495 -3.278255462646e-07 +4626 4495 24305555.56353 +4627 4495 -39081501.55875 +4628 4495 17343750.00569 +4496 4496 1165825984.246 +4497 4496 -1.382827758789e-05 +4498 4496 1.788139343262e-07 +4499 4496 104791324.3853 +4509 4496 -2.890825271606e-06 +4510 4496 3.8743019104e-07 +4511 4496 -46719419.49861 +4512 4496 -1.20997428894e-05 +4513 4496 -4.768371582031e-07 +4514 4496 -212506.0825927 +4515 4496 -3.278255462646e-06 +4516 4496 -2.086162567139e-07 +4517 4496 -46719419.49861 +4587 4496 21679861.11823 +4588 4496 -17343750.0057 +4589 4496 -36432062.04359 +4590 4496 86719444.4302 +4591 4496 3.427267074585e-07 +4592 4496 -99061955.12464 +4593 4496 21679861.11823 +4594 4496 17343750.0057 +4595 4496 -36432062.04359 +4602 4496 6.169080734253e-06 +4603 4496 -69374999.9886 +4604 4496 -72810997.49471 +4605 4496 2.598762512207e-05 +4606 4496 5.960464477539e-08 +4607 4496 -104578818.0156 +4608 4496 6.973743438721e-06 +4609 4496 69374999.9886 +4610 4496 -72810997.49471 +4620 4496 -21679861.11823 +4621 4496 -17343750.0057 +4622 4496 -36432062.04358 +4623 4496 -86719444.43019 +4624 4496 -2.682209014893e-07 +4625 4496 -99061955.12461 +4626 4496 -21679861.11823 +4627 4496 17343750.00569 +4628 4496 -36432062.04358 +4497 4497 1632315315.374 +4498 4497 97222220.26178 +4499 4497 -4.172325134277e-05 +4500 4497 17392720.97666 +4501 4497 -97222221.42845 +4502 4497 -2.145767211914e-06 +4512 4497 -148365426.1266 +4513 4497 -97222222.20624 +4514 4497 -3.039836883545e-06 +4515 4497 -406796532.3944 +4516 4497 -2.801418304443e-06 +4517 4497 -1.233816146851e-05 +4518 4497 -148365426.1266 +4519 4497 97222222.20624 +4520 4497 -3.308057785034e-06 +4590 4497 -46373434.23613 +4591 4497 24305555.56354 +4592 4497 21679861.11823 +4593 4497 -175918799.4897 +4594 4497 -24305555.27186 +4595 4497 86719444.24762 +4605 4497 8952264.76783 +4606 4497 9.298324584961e-06 +4607 4497 6.228685379028e-06 +4608 4497 268847663.9159 +4609 4497 24305555.07742 +4610 4497 0.03653132915497 +4611 4497 -28139091.37671 +4612 4497 -24305555.36909 +4613 4497 21679860.74398 +4623 4497 -46373434.23611 +4624 4497 -24305555.56353 +4625 4497 -21679861.11823 +4626 4497 -138827443.8751 +4627 4497 -5.066394805908e-07 +4628 4497 -86719444.43019 +4629 4497 -46373434.23611 +4630 4497 24305555.56353 +4631 4497 -21679861.11823 +4498 4498 1369805740.108 +4499 4498 -2.145767211914e-06 +4500 4498 -97222221.03956 +4501 4498 -322883627.8625 +4502 4498 4.798173904419e-06 +4512 4498 -97222222.20624 +4513 4498 -119197695.4315 +4514 4498 2.831220626831e-07 +4515 4498 -3.09944152832e-06 +4516 4498 20983010.02827 +4517 4498 -4.768371582031e-07 +4518 4498 97222222.20624 +4519 4498 -119197695.4315 +4520 4498 -7.450580596924e-08 +4590 4498 24305555.56354 +4591 4498 -39081501.55876 +4592 4498 -17343750.00569 +4593 4498 -24305555.36908 +4594 4498 -61681981.7616 +4595 4498 17343749.94043 +4605 4498 1.069903373718e-05 +4606 4498 -83408755.55014 +4607 4498 -69374999.9886 +4608 4498 24305555.07742 +4609 4498 203220270.0671 +4610 4498 0.02920919656754 +4611 4498 -24305555.27186 +4612 4498 -113208178.6284 +4613 4498 69374999.6084 +4623 4498 -24305555.56353 +4624 4498 -39081501.55875 +4625 4498 -17343750.0057 +4626 4498 -8.344650268555e-07 +4627 4498 -31882558.21681 +4628 4498 -3.278255462646e-07 +4629 4498 24305555.56353 +4630 4498 -39081501.55875 +4631 4498 17343750.00569 +4499 4499 1212545401.289 +4500 4499 -1.788139343262e-06 +4501 4499 3.75509262085e-06 +4502 4499 8567490.576108 +4512 4499 -2.890825271606e-06 +4513 4499 3.8743019104e-07 +4514 4499 -46719419.49861 +4515 4499 -1.20997428894e-05 +4516 4499 -4.768371582031e-07 +4517 4499 -212506.0825927 +4518 4499 -3.278255462646e-06 +4519 4499 -2.086162567139e-07 +4520 4499 -46719419.49861 +4590 4499 21679861.11823 +4591 4499 -17343750.0057 +4592 4499 -36432062.04359 +4593 4499 86719444.24762 +4594 4499 17343749.9078 +4595 4499 -110741809.7386 +4605 4499 6.169080734253e-06 +4606 4499 -69374999.9886 +4607 4499 -72810997.49471 +4608 4499 -0.03649973869324 +4609 4499 -0.02921465039253 +4610 4499 -68146756.53808 +4611 4499 21679860.55685 +4612 4499 69374999.49133 +4613 4499 -84490851.68298 +4623 4499 -21679861.11823 +4624 4499 -17343750.0057 +4625 4499 -36432062.04358 +4626 4499 -86719444.43019 +4627 4499 -2.682209014893e-07 +4628 4499 -99061955.12461 +4629 4499 -21679861.11823 +4630 4499 17343750.00569 +4631 4499 -36432062.04358 +4500 4500 944226635.8558 +4501 4500 104813146.3867 +4502 4500 -9.059906005859e-06 +4515 4500 -148365426.1266 +4516 4500 -97222222.20624 +4517 4500 -3.039836883545e-06 +4518 4500 -591818040.3848 +4519 4500 -104813145.6089 +4520 4500 -1.09076499939e-05 +4521 4500 22795227.75344 +4522 4500 77777776.98724 +4523 4500 1.311302185059e-06 +4593 4500 -9282077.50499 +4594 4500 29166666.38457 +4595 4500 26015832.78049 +4608 4500 -28139091.37673 +4609 4500 -24305555.27187 +4610 4500 -21679860.55685 +4611 4500 142149470.4916 +4612 4500 26203286.60958 +4613 4500 17682222.18138 +4626 4500 -46373434.23611 +4627 4500 -24305555.56353 +4628 4500 -21679861.11823 +4629 4500 -180984988.3575 +4630 4500 -26203286.41514 +4631 4500 -88411110.90688 +4632 4500 -8767515.558541 +4633 4500 19444444.25639 +4634 4500 -18020555.17262 +4501 4501 789133337.2837 +4502 4501 2.719461917877e-06 +4515 4501 -97222222.20624 +4516 4501 -119197695.4315 +4517 4501 2.831220626831e-07 +4518 4501 -104813145.2201 +4519 4501 -131460786.597 +4520 4501 -9.536743164063e-07 +4521 4501 116666665.4809 +4522 4501 28639890.68178 +4523 4501 5.960464477539e-07 +4593 4501 19444444.25638 +4594 4501 -9282077.505 +4595 4501 -13874999.9393 +4608 4501 -24305555.36909 +4609 4501 -113208178.6284 +4610 4501 -69374999.49133 +4611 4501 26203286.60958 +4612 4501 103376145.8295 +4613 4501 14145833.18358 +4626 4501 -24305555.56353 +4627 4501 -39081501.55875 +4628 4501 -17343750.0057 +4629 4501 -26203286.31792 +4630 4501 -65895674.85386 +4631 4501 -18697916.56855 +4632 4501 29166666.38458 +4633 4501 -7306349.825738 +4634 4501 20270833.25379 +4502 4502 738330627.0228 +4515 4502 -2.890825271606e-06 +4516 4502 3.8743019104e-07 +4517 4502 -46719419.49861 +4518 4502 -1.251697540283e-05 +4519 4502 -4.768371582031e-07 +4520 4502 -103838327.6491 +4521 4502 1.907348632813e-06 +4522 4502 4.172325134277e-07 +4523 4502 54942611.08084 +4593 4502 17343888.52033 +4594 4502 -20812499.90895 +4595 4502 -24752206.67999 +4608 4502 -21679860.74398 +4609 4502 -69374999.6084 +4610 4502 -84490851.68299 +4611 4502 -17682222.18137 +4612 4502 -14145833.18359 +4613 4502 -65836512.72295 +4626 4502 -21679861.11823 +4627 4502 -17343750.0057 +4628 4502 -36432062.04358 +4629 4502 -88411110.90688 +4630 4502 -18697916.60118 +4631 4502 -114040857.0942 +4632 4502 -27030832.75893 +4633 4502 13062499.95656 +4634 4502 -24841207.22225 +4503 4503 1483949894.094 +4504 4503 7.867813110352e-06 +4505 4503 -5.507469177246e-05 +4506 4503 184322301.8864 +4507 4503 -2.622604370117e-06 +4508 4503 -1.358985900879e-05 +4524 4503 -406796532.3944 +4525 4503 -2.801418304443e-06 +4526 4503 -1.233816146851e-05 +4527 4503 -148365426.1266 +4528 4503 97222222.20624 +4529 4503 -3.308057785034e-06 +4596 4503 -138827443.8752 +4597 4503 2.682209014893e-07 +4598 4503 86719444.4302 +4599 4503 -46373434.23614 +4600 4503 -24305555.56354 +4601 4503 21679861.11823 +4614 4503 222474230.8735 +4615 4503 3.933906555176e-06 +4616 4503 2.622604370117e-05 +4617 4503 8952264.76783 +4618 4503 -1.302361488342e-05 +4619 4503 6.914138793945e-06 +4635 4503 -138827443.8751 +4636 4503 -5.066394805908e-07 +4637 4503 -86719444.43019 +4638 4503 -46373434.23611 +4639 4503 24305555.56353 +4640 4503 -21679861.11823 +4504 4504 1250608048.648 +4505 4504 -1.192092895508e-06 +4506 4504 -3.159046173096e-06 +4507 4504 -185121779.2034 +4508 4504 8.046627044678e-07 +4524 4504 -3.09944152832e-06 +4525 4504 20983010.02827 +4526 4504 -4.768371582031e-07 +4527 4504 97222222.20624 +4528 4504 -119197695.4315 +4529 4504 -7.450580596924e-08 +4596 4504 -2.294778823853e-06 +4597 4504 -31882558.21685 +4598 4504 2.682209014893e-07 +4599 4504 -24305555.56354 +4600 4504 -39081501.55876 +4601 4504 17343750.0057 +4614 4504 4.410743713379e-06 +4615 4504 164138769.4832 +4616 4504 -1.192092895508e-07 +4617 4504 -1.156330108643e-05 +4618 4504 -83408755.55014 +4619 4504 69374999.9886 +4635 4504 -8.344650268555e-07 +4636 4504 -31882558.21681 +4637 4504 -3.278255462646e-07 +4638 4504 24305555.56353 +4639 4504 -39081501.55875 +4640 4504 17343750.00569 +4505 4505 1165825984.246 +4506 4505 -1.382827758789e-05 +4507 4505 1.788139343262e-07 +4508 4505 104791324.3853 +4524 4505 -1.20997428894e-05 +4525 4505 -4.768371582031e-07 +4526 4505 -212506.0825927 +4527 4505 -3.278255462646e-06 +4528 4505 -2.086162567139e-07 +4529 4505 -46719419.49861 +4596 4505 86719444.4302 +4597 4505 3.427267074585e-07 +4598 4505 -99061955.12464 +4599 4505 21679861.11823 +4600 4505 17343750.0057 +4601 4505 -36432062.04359 +4614 4505 2.598762512207e-05 +4615 4505 5.960464477539e-08 +4616 4505 -104578818.0156 +4617 4505 6.973743438721e-06 +4618 4505 69374999.9886 +4619 4505 -72810997.49471 +4635 4505 -86719444.43019 +4636 4505 -2.682209014893e-07 +4637 4505 -99061955.12461 +4638 4505 -21679861.11823 +4639 4505 17343750.00569 +4640 4505 -36432062.04358 +4506 4506 1483949894.094 +4507 4506 7.867813110352e-06 +4508 4506 -5.507469177246e-05 +4509 4506 184322301.8864 +4510 4506 -2.622604370117e-06 +4511 4506 -1.358985900879e-05 +4524 4506 -148365426.1266 +4525 4506 -97222222.20624 +4526 4506 -3.039836883545e-06 +4527 4506 -406796532.3944 +4528 4506 -2.801418304443e-06 +4529 4506 -1.233816146851e-05 +4530 4506 -148365426.1266 +4531 4506 97222222.20624 +4532 4506 -3.308057785034e-06 +4596 4506 -46373434.23613 +4597 4506 24305555.56354 +4598 4506 21679861.11823 +4599 4506 -138827443.8752 +4600 4506 2.682209014893e-07 +4601 4506 86719444.4302 +4602 4506 -46373434.23614 +4603 4506 -24305555.56354 +4604 4506 21679861.11823 +4614 4506 8952264.76783 +4615 4506 9.298324584961e-06 +4616 4506 6.228685379028e-06 +4617 4506 222474230.8735 +4618 4506 3.933906555176e-06 +4619 4506 2.622604370117e-05 +4620 4506 8952264.76783 +4621 4506 -1.302361488342e-05 +4622 4506 6.914138793945e-06 +4635 4506 -46373434.23611 +4636 4506 -24305555.56353 +4637 4506 -21679861.11823 +4638 4506 -138827443.8751 +4639 4506 -5.066394805908e-07 +4640 4506 -86719444.43019 +4641 4506 -46373434.23611 +4642 4506 24305555.56353 +4643 4506 -21679861.11823 +4507 4507 1250608048.648 +4508 4507 -1.192092895508e-06 +4509 4507 -3.159046173096e-06 +4510 4507 -185121779.2034 +4511 4507 8.046627044678e-07 +4524 4507 -97222222.20624 +4525 4507 -119197695.4315 +4526 4507 2.831220626831e-07 +4527 4507 -3.09944152832e-06 +4528 4507 20983010.02827 +4529 4507 -4.768371582031e-07 +4530 4507 97222222.20624 +4531 4507 -119197695.4315 +4532 4507 -7.450580596924e-08 +4596 4507 24305555.56354 +4597 4507 -39081501.55876 +4598 4507 -17343750.00569 +4599 4507 -2.294778823853e-06 +4600 4507 -31882558.21685 +4601 4507 2.682209014893e-07 +4602 4507 -24305555.56354 +4603 4507 -39081501.55876 +4604 4507 17343750.0057 +4614 4507 1.069903373718e-05 +4615 4507 -83408755.55014 +4616 4507 -69374999.9886 +4617 4507 4.410743713379e-06 +4618 4507 164138769.4832 +4619 4507 -1.192092895508e-07 +4620 4507 -1.156330108643e-05 +4621 4507 -83408755.55014 +4622 4507 69374999.9886 +4635 4507 -24305555.56353 +4636 4507 -39081501.55875 +4637 4507 -17343750.0057 +4638 4507 -8.344650268555e-07 +4639 4507 -31882558.21681 +4640 4507 -3.278255462646e-07 +4641 4507 24305555.56353 +4642 4507 -39081501.55875 +4643 4507 17343750.00569 +4508 4508 1165825984.246 +4509 4508 -1.382827758789e-05 +4510 4508 1.788139343262e-07 +4511 4508 104791324.3853 +4524 4508 -2.890825271606e-06 +4525 4508 3.8743019104e-07 +4526 4508 -46719419.49861 +4527 4508 -1.20997428894e-05 +4528 4508 -4.768371582031e-07 +4529 4508 -212506.0825927 +4530 4508 -3.278255462646e-06 +4531 4508 -2.086162567139e-07 +4532 4508 -46719419.49861 +4596 4508 21679861.11823 +4597 4508 -17343750.0057 +4598 4508 -36432062.04359 +4599 4508 86719444.4302 +4600 4508 3.427267074585e-07 +4601 4508 -99061955.12464 +4602 4508 21679861.11823 +4603 4508 17343750.0057 +4604 4508 -36432062.04359 +4614 4508 6.169080734253e-06 +4615 4508 -69374999.9886 +4616 4508 -72810997.49471 +4617 4508 2.598762512207e-05 +4618 4508 5.960464477539e-08 +4619 4508 -104578818.0156 +4620 4508 6.973743438721e-06 +4621 4508 69374999.9886 +4622 4508 -72810997.49471 +4635 4508 -21679861.11823 +4636 4508 -17343750.0057 +4637 4508 -36432062.04358 +4638 4508 -86719444.43019 +4639 4508 -2.682209014893e-07 +4640 4508 -99061955.12461 +4641 4508 -21679861.11823 +4642 4508 17343750.00569 +4643 4508 -36432062.04358 +4509 4509 1483949894.094 +4510 4509 7.867813110352e-06 +4511 4509 -5.507469177246e-05 +4512 4509 184322301.8864 +4513 4509 -2.622604370117e-06 +4514 4509 -1.358985900879e-05 +4527 4509 -148365426.1266 +4528 4509 -97222222.20624 +4529 4509 -3.039836883545e-06 +4530 4509 -406796532.3944 +4531 4509 -2.801418304443e-06 +4532 4509 -1.233816146851e-05 +4533 4509 -148365426.1266 +4534 4509 97222222.20624 +4535 4509 -3.308057785034e-06 +4599 4509 -46373434.23613 +4600 4509 24305555.56354 +4601 4509 21679861.11823 +4602 4509 -138827443.8752 +4603 4509 2.682209014893e-07 +4604 4509 86719444.4302 +4605 4509 -46373434.23614 +4606 4509 -24305555.56354 +4607 4509 21679861.11823 +4617 4509 8952264.76783 +4618 4509 9.298324584961e-06 +4619 4509 6.228685379028e-06 +4620 4509 222474230.8735 +4621 4509 3.933906555176e-06 +4622 4509 2.622604370117e-05 +4623 4509 8952264.76783 +4624 4509 -1.302361488342e-05 +4625 4509 6.914138793945e-06 +4638 4509 -46373434.23611 +4639 4509 -24305555.56353 +4640 4509 -21679861.11823 +4641 4509 -138827443.8751 +4642 4509 -5.066394805908e-07 +4643 4509 -86719444.43019 +4644 4509 -46373434.23611 +4645 4509 24305555.56353 +4646 4509 -21679861.11823 +4510 4510 1250608048.648 +4511 4510 -1.192092895508e-06 +4512 4510 -3.159046173096e-06 +4513 4510 -185121779.2034 +4514 4510 8.046627044678e-07 +4527 4510 -97222222.20624 +4528 4510 -119197695.4315 +4529 4510 2.831220626831e-07 +4530 4510 -3.09944152832e-06 +4531 4510 20983010.02827 +4532 4510 -4.768371582031e-07 +4533 4510 97222222.20624 +4534 4510 -119197695.4315 +4535 4510 -7.450580596924e-08 +4599 4510 24305555.56354 +4600 4510 -39081501.55876 +4601 4510 -17343750.00569 +4602 4510 -2.294778823853e-06 +4603 4510 -31882558.21685 +4604 4510 2.682209014893e-07 +4605 4510 -24305555.56354 +4606 4510 -39081501.55876 +4607 4510 17343750.0057 +4617 4510 1.069903373718e-05 +4618 4510 -83408755.55014 +4619 4510 -69374999.9886 +4620 4510 4.410743713379e-06 +4621 4510 164138769.4832 +4622 4510 -1.192092895508e-07 +4623 4510 -1.156330108643e-05 +4624 4510 -83408755.55014 +4625 4510 69374999.9886 +4638 4510 -24305555.56353 +4639 4510 -39081501.55875 +4640 4510 -17343750.0057 +4641 4510 -8.344650268555e-07 +4642 4510 -31882558.21681 +4643 4510 -3.278255462646e-07 +4644 4510 24305555.56353 +4645 4510 -39081501.55875 +4646 4510 17343750.00569 +4511 4511 1165825984.246 +4512 4511 -1.382827758789e-05 +4513 4511 1.788139343262e-07 +4514 4511 104791324.3853 +4527 4511 -2.890825271606e-06 +4528 4511 3.8743019104e-07 +4529 4511 -46719419.49861 +4530 4511 -1.20997428894e-05 +4531 4511 -4.768371582031e-07 +4532 4511 -212506.0825927 +4533 4511 -3.278255462646e-06 +4534 4511 -2.086162567139e-07 +4535 4511 -46719419.49861 +4599 4511 21679861.11823 +4600 4511 -17343750.0057 +4601 4511 -36432062.04359 +4602 4511 86719444.4302 +4603 4511 3.427267074585e-07 +4604 4511 -99061955.12464 +4605 4511 21679861.11823 +4606 4511 17343750.0057 +4607 4511 -36432062.04359 +4617 4511 6.169080734253e-06 +4618 4511 -69374999.9886 +4619 4511 -72810997.49471 +4620 4511 2.598762512207e-05 +4621 4511 5.960464477539e-08 +4622 4511 -104578818.0156 +4623 4511 6.973743438721e-06 +4624 4511 69374999.9886 +4625 4511 -72810997.49471 +4638 4511 -21679861.11823 +4639 4511 -17343750.0057 +4640 4511 -36432062.04358 +4641 4511 -86719444.43019 +4642 4511 -2.682209014893e-07 +4643 4511 -99061955.12461 +4644 4511 -21679861.11823 +4645 4511 17343750.00569 +4646 4511 -36432062.04358 +4512 4512 1483949894.094 +4513 4512 7.867813110352e-06 +4514 4512 -5.507469177246e-05 +4515 4512 184322301.8864 +4516 4512 -2.622604370117e-06 +4517 4512 -1.358985900879e-05 +4530 4512 -148365426.1266 +4531 4512 -97222222.20624 +4532 4512 -3.039836883545e-06 +4533 4512 -406796532.3944 +4534 4512 -2.801418304443e-06 +4535 4512 -1.233816146851e-05 +4536 4512 -148365426.1266 +4537 4512 97222222.20624 +4538 4512 -3.308057785034e-06 +4602 4512 -46373434.23613 +4603 4512 24305555.56354 +4604 4512 21679861.11823 +4605 4512 -138827443.8752 +4606 4512 2.682209014893e-07 +4607 4512 86719444.4302 +4608 4512 -46373434.23614 +4609 4512 -24305555.56354 +4610 4512 21679861.11823 +4620 4512 8952264.76783 +4621 4512 9.298324584961e-06 +4622 4512 6.228685379028e-06 +4623 4512 222474230.8735 +4624 4512 3.933906555176e-06 +4625 4512 2.622604370117e-05 +4626 4512 8952264.76783 +4627 4512 -1.302361488342e-05 +4628 4512 6.914138793945e-06 +4641 4512 -46373434.23611 +4642 4512 -24305555.56353 +4643 4512 -21679861.11823 +4644 4512 -138827443.8751 +4645 4512 -5.066394805908e-07 +4646 4512 -86719444.43019 +4647 4512 -46373434.23611 +4648 4512 24305555.56353 +4649 4512 -21679861.11823 +4513 4513 1250608048.648 +4514 4513 -1.192092895508e-06 +4515 4513 -3.159046173096e-06 +4516 4513 -185121779.2034 +4517 4513 8.046627044678e-07 +4530 4513 -97222222.20624 +4531 4513 -119197695.4315 +4532 4513 2.831220626831e-07 +4533 4513 -3.09944152832e-06 +4534 4513 20983010.02827 +4535 4513 -4.768371582031e-07 +4536 4513 97222222.20624 +4537 4513 -119197695.4315 +4538 4513 -7.450580596924e-08 +4602 4513 24305555.56354 +4603 4513 -39081501.55876 +4604 4513 -17343750.00569 +4605 4513 -2.294778823853e-06 +4606 4513 -31882558.21685 +4607 4513 2.682209014893e-07 +4608 4513 -24305555.56354 +4609 4513 -39081501.55876 +4610 4513 17343750.0057 +4620 4513 1.069903373718e-05 +4621 4513 -83408755.55014 +4622 4513 -69374999.9886 +4623 4513 4.410743713379e-06 +4624 4513 164138769.4832 +4625 4513 -1.192092895508e-07 +4626 4513 -1.156330108643e-05 +4627 4513 -83408755.55014 +4628 4513 69374999.9886 +4641 4513 -24305555.56353 +4642 4513 -39081501.55875 +4643 4513 -17343750.0057 +4644 4513 -8.344650268555e-07 +4645 4513 -31882558.21681 +4646 4513 -3.278255462646e-07 +4647 4513 24305555.56353 +4648 4513 -39081501.55875 +4649 4513 17343750.00569 +4514 4514 1165825984.246 +4515 4514 -1.382827758789e-05 +4516 4514 1.788139343262e-07 +4517 4514 104791324.3853 +4530 4514 -2.890825271606e-06 +4531 4514 3.8743019104e-07 +4532 4514 -46719419.49861 +4533 4514 -1.20997428894e-05 +4534 4514 -4.768371582031e-07 +4535 4514 -212506.0825927 +4536 4514 -3.278255462646e-06 +4537 4514 -2.086162567139e-07 +4538 4514 -46719419.49861 +4602 4514 21679861.11823 +4603 4514 -17343750.0057 +4604 4514 -36432062.04359 +4605 4514 86719444.4302 +4606 4514 3.427267074585e-07 +4607 4514 -99061955.12464 +4608 4514 21679861.11823 +4609 4514 17343750.0057 +4610 4514 -36432062.04359 +4620 4514 6.169080734253e-06 +4621 4514 -69374999.9886 +4622 4514 -72810997.49471 +4623 4514 2.598762512207e-05 +4624 4514 5.960464477539e-08 +4625 4514 -104578818.0156 +4626 4514 6.973743438721e-06 +4627 4514 69374999.9886 +4628 4514 -72810997.49471 +4641 4514 -21679861.11823 +4642 4514 -17343750.0057 +4643 4514 -36432062.04358 +4644 4514 -86719444.43019 +4645 4514 -2.682209014893e-07 +4646 4514 -99061955.12461 +4647 4514 -21679861.11823 +4648 4514 17343750.00569 +4649 4514 -36432062.04358 +4515 4515 1483949894.094 +4516 4515 7.867813110352e-06 +4517 4515 -5.507469177246e-05 +4518 4515 184322301.8864 +4519 4515 -2.622604370117e-06 +4520 4515 -1.358985900879e-05 +4533 4515 -148365426.1266 +4534 4515 -97222222.20624 +4535 4515 -3.039836883545e-06 +4536 4515 -406796532.3944 +4537 4515 -2.801418304443e-06 +4538 4515 -1.233816146851e-05 +4539 4515 -148365426.1266 +4540 4515 97222222.20624 +4541 4515 -3.308057785034e-06 +4605 4515 -46373434.23613 +4606 4515 24305555.56354 +4607 4515 21679861.11823 +4608 4515 -138827443.8752 +4609 4515 2.682209014893e-07 +4610 4515 86719444.4302 +4611 4515 -46373434.23614 +4612 4515 -24305555.56354 +4613 4515 21679861.11823 +4623 4515 8952264.76783 +4624 4515 9.298324584961e-06 +4625 4515 6.228685379028e-06 +4626 4515 222474230.8735 +4627 4515 3.933906555176e-06 +4628 4515 2.622604370117e-05 +4629 4515 8952264.76783 +4630 4515 -1.302361488342e-05 +4631 4515 6.914138793945e-06 +4644 4515 -46373434.23611 +4645 4515 -24305555.56353 +4646 4515 -21679861.11823 +4647 4515 -138827443.8751 +4648 4515 -5.066394805908e-07 +4649 4515 -86719444.43019 +4650 4515 -46373434.23611 +4651 4515 24305555.56353 +4652 4515 -21679861.11823 +4516 4516 1250608048.648 +4517 4516 -1.192092895508e-06 +4518 4516 -3.159046173096e-06 +4519 4516 -185121779.2034 +4520 4516 8.046627044678e-07 +4533 4516 -97222222.20624 +4534 4516 -119197695.4315 +4535 4516 2.831220626831e-07 +4536 4516 -3.09944152832e-06 +4537 4516 20983010.02827 +4538 4516 -4.768371582031e-07 +4539 4516 97222222.20624 +4540 4516 -119197695.4315 +4541 4516 -7.450580596924e-08 +4605 4516 24305555.56354 +4606 4516 -39081501.55876 +4607 4516 -17343750.00569 +4608 4516 -2.294778823853e-06 +4609 4516 -31882558.21685 +4610 4516 2.682209014893e-07 +4611 4516 -24305555.56354 +4612 4516 -39081501.55876 +4613 4516 17343750.0057 +4623 4516 1.069903373718e-05 +4624 4516 -83408755.55014 +4625 4516 -69374999.9886 +4626 4516 4.410743713379e-06 +4627 4516 164138769.4832 +4628 4516 -1.192092895508e-07 +4629 4516 -1.156330108643e-05 +4630 4516 -83408755.55014 +4631 4516 69374999.9886 +4644 4516 -24305555.56353 +4645 4516 -39081501.55875 +4646 4516 -17343750.0057 +4647 4516 -8.344650268555e-07 +4648 4516 -31882558.21681 +4649 4516 -3.278255462646e-07 +4650 4516 24305555.56353 +4651 4516 -39081501.55875 +4652 4516 17343750.00569 +4517 4517 1165825984.246 +4518 4517 -1.382827758789e-05 +4519 4517 1.788139343262e-07 +4520 4517 104791324.3853 +4533 4517 -2.890825271606e-06 +4534 4517 3.8743019104e-07 +4535 4517 -46719419.49861 +4536 4517 -1.20997428894e-05 +4537 4517 -4.768371582031e-07 +4538 4517 -212506.0825927 +4539 4517 -3.278255462646e-06 +4540 4517 -2.086162567139e-07 +4541 4517 -46719419.49861 +4605 4517 21679861.11823 +4606 4517 -17343750.0057 +4607 4517 -36432062.04359 +4608 4517 86719444.4302 +4609 4517 3.427267074585e-07 +4610 4517 -99061955.12464 +4611 4517 21679861.11823 +4612 4517 17343750.0057 +4613 4517 -36432062.04359 +4623 4517 6.169080734253e-06 +4624 4517 -69374999.9886 +4625 4517 -72810997.49471 +4626 4517 2.598762512207e-05 +4627 4517 5.960464477539e-08 +4628 4517 -104578818.0156 +4629 4517 6.973743438721e-06 +4630 4517 69374999.9886 +4631 4517 -72810997.49471 +4644 4517 -21679861.11823 +4645 4517 -17343750.0057 +4646 4517 -36432062.04358 +4647 4517 -86719444.43019 +4648 4517 -2.682209014893e-07 +4649 4517 -99061955.12461 +4650 4517 -21679861.11823 +4651 4517 17343750.00569 +4652 4517 -36432062.04358 +4518 4518 1661147708.835 +4519 4518 104975994.3214 +4520 4518 -3.314018249512e-05 +4521 4518 28973926.47986 +4522 4518 -93442034.30678 +4523 4518 -1.668930053711e-06 +4536 4518 -148365426.1266 +4537 4518 -97222222.20624 +4538 4518 -3.039836883545e-06 +4539 4518 -414750020.4148 +4540 4518 -3811573.076203 +4541 4518 -7.390975952148e-06 +4542 4518 -158390003.0581 +4543 4518 97090758.28168 +4544 4518 3.516674041748e-06 +4608 4518 -46373434.23613 +4609 4518 24305555.56354 +4610 4518 21679861.11823 +4611 4518 -180984988.3575 +4612 4518 -26203286.31792 +4613 4518 88411110.90689 +4626 4518 8952264.76783 +4627 4518 9.298324584961e-06 +4628 4518 6.228685379028e-06 +4629 4518 274245586.3934 +4630 4518 26243998.59327 +4631 4518 0.0379564166069 +4632 4518 -25967702.04295 +4633 4518 -23360508.5882 +4634 4518 21679166.28526 +4647 4518 -46373434.23611 +4648 4518 -24305555.56353 +4649 4518 -21679861.11823 +4650 4518 -140996480.1669 +4651 4518 -952893.2695236 +4652 4518 -87564583.31886 +4653 4518 -48879322.66663 +4654 4518 24272689.58237 +4655 4518 -22525694.45184 +4519 4519 1378316574.243 +4520 4519 1.299381256104e-05 +4521 4519 -93442033.91789 +4522 4519 -311076053.7848 +4523 4519 -5.543231964111e-06 +4536 4519 -97222222.20624 +4537 4519 -119197695.4315 +4538 4519 2.831220626831e-07 +4539 4519 -3811573.076213 +4540 4519 16672797.27745 +4541 4519 5.483627319336e-06 +4542 4519 97090758.28168 +4543 4519 -116180339.9824 +4544 4519 -2.384185791016e-07 +4608 4519 24305555.56354 +4609 4519 -39081501.55876 +4610 4519 -17343750.00569 +4611 4519 -26203286.41514 +4612 4519 -65895674.85388 +4613 4519 18697916.60118 +4626 4519 1.069903373718e-05 +4627 4519 -83408755.55014 +4628 4519 -69374999.9886 +4629 4519 26243998.59326 +4630 4519 203537802.7107 +4631 4519 0.03034961223602 +4632 4519 -23360508.49098 +4633 4519 -110980197.151 +4634 4519 69374999.59698 +4647 4519 -24305555.56353 +4648 4519 -39081501.55875 +4649 4519 -17343750.0057 +4650 4519 -952893.2695259 +4651 4519 -33140775.69073 +4652 4519 -677083.3331571 +4653 4519 24272689.58237 +4654 4519 -38326906.89251 +4655 4519 16666666.67214 +4520 4520 1227849607.295 +4521 4520 -7.152557373047e-07 +4522 4520 -5.275011062622e-06 +4523 4520 16993676.64502 +4536 4520 -2.890825271606e-06 +4537 4520 3.8743019104e-07 +4538 4520 -46719419.49861 +4539 4520 -9.238719940186e-06 +4540 4520 5.841255187988e-06 +4541 4520 -3046182.050694 +4542 4520 3.36766242981e-06 +4543 4520 -1.788139343262e-07 +4544 4520 -48631203.38773 +4608 4520 21679861.11823 +4609 4520 -17343750.0057 +4610 4520 -36432062.04359 +4611 4520 88411110.90689 +4612 4520 18697916.56855 +4613 4520 -114040857.0943 +4626 4520 6.169080734253e-06 +4627 4520 -69374999.9886 +4628 4520 -72810997.49471 +4629 4520 -0.03792423009872 +4630 4520 -0.03035497665405 +4631 4520 -69147840.74461 +4632 4520 21679166.091 +4633 4520 69374999.4742 +4634 4520 -84314737.28062 +4647 4520 -21679861.11823 +4648 4520 -17343750.0057 +4649 4520 -36432062.04358 +4650 4520 -87564583.31903 +4651 4520 -677083.3332905 +4652 4520 -100252145.5455 +4653 4520 -22525694.45184 +4654 4520 16666666.67214 +4655 4520 -36909325.87324 +4521 4521 878310888.4809 +4522 4521 -2657515.75764 +4523 4521 -4.768371582031e-07 +4539 4521 -146355658.7119 +4540 4521 -97205456.75096 +4541 4521 -4.738569259644e-06 +4542 4521 -422227983.6709 +4543 4521 -5136049.023845 +4544 4521 -1.072883605957e-06 +4545 4521 85600144.70804 +4546 4521 -16771033.13002 +4547 4521 -1.192092895508e-06 +4548 4521 -156881939.5358 +4549 4521 98545423.0995 +4550 4521 5.125999450684e-06 +4611 4521 -8767515.558542 +4612 4521 29166666.38458 +4613 4521 27030832.75893 +4629 4521 -25967702.04296 +4630 4521 -23360508.49098 +4631 4521 -21679166.091 +4632 4521 119740849.7094 +4633 4521 -664378.9397368 +4634 4521 17135277.77496 +4650 4521 -45870736.57861 +4651 4521 -24301364.19971 +4652 4521 -21679166.67379 +4653 4521 -141002035.2671 +4654 4521 -1284012.2566 +4655 4521 -85676388.87482 +4656 4521 4511607.610493 +4657 4521 -4192758.28457 +4658 4521 3215972.223778 +4659 4521 -47751770.62455 +4660 4521 24636355.78701 +4661 4521 -21159027.78473 +4522 4522 904404472.7405 +4523 4522 2.038478851318e-05 +4539 4522 -97205456.75096 +4540 4522 -119802374.1365 +4541 4522 -4.91738319397e-07 +4542 4522 -5136049.023844 +4543 4522 9983783.088479 +4544 4522 1.126527786255e-05 +4545 4522 22117855.75248 +4546 4522 -98572068.66136 +4547 4522 -3.457069396973e-06 +4548 4522 98545423.09949 +4549 4522 -123363044.4243 +4550 4522 -7.003545761108e-07 +4611 4522 19444444.25639 +4612 4522 -7306349.825739 +4613 4522 -13062499.95656 +4629 4522 -23360508.5882 +4630 4522 -110980197.151 +4631 4522 -69374999.4742 +4632 4522 -664378.939739 +4633 4522 126264245.7775 +4634 4522 7208333.185862 +4650 4522 -24301364.19971 +4651 4522 -39232415.43151 +4652 4522 -17343750.0057 +4653 4522 -1284012.256601 +4654 4522 -32949093.52409 +4655 4522 -677083.3331589 +4656 4522 5529463.940844 +4657 4522 -41531445.75453 +4658 4522 33333333.32786 +4659 4522 24636355.78701 +4660 4522 -39372046.84255 +4661 4522 16666666.67214 +4523 4523 768562010.6434 +4539 4523 -4.708766937256e-06 +4540 4523 -5.811452865601e-07 +4541 4523 -46336936.97172 +4542 4523 -1.251697540283e-06 +4543 4523 1.132488250732e-05 +4544 4523 -12181640.54617 +4545 4523 4.768371582031e-07 +4546 4523 -3.576278686523e-06 +4547 4523 44227455.09152 +4548 4523 4.827976226807e-06 +4549 4523 -7.301568984985e-07 +4550 4523 -52301561.2662 +4611 4523 18020555.17262 +4612 4523 -20270833.25379 +4613 4523 -24841207.22225 +4629 4523 -21679166.28526 +4630 4523 -69374999.59698 +4631 4523 -84314737.28063 +4632 4523 -17135277.77496 +4633 4523 -7208333.185871 +4634 4523 -74091157.29507 +4650 4523 -21679166.67379 +4651 4523 -17343750.0057 +4652 4523 -36335759.26896 +4653 4523 -85676388.87481 +4654 4523 -677083.3332923 +4655 4523 -97565514.93122 +4656 4523 -4909027.779057 +4657 4523 33333333.32786 +4658 4523 -33978945.7605 +4659 4523 -21159027.78473 +4660 4523 16666666.67214 +4661 4523 -35825485.57976 +4524 4524 741974947.0469 +4525 4524 5.006790161133e-06 +4526 4524 -2.908706665039e-05 +4527 4524 92161150.94322 +4528 4524 19444444.44125 +4529 4524 -7.271766662598e-06 +4614 4524 -138827443.8752 +4615 4524 2.682209014893e-07 +4616 4524 86719444.4302 +4617 4524 -46373434.23614 +4618 4524 -24305555.56354 +4619 4524 21679861.11823 +4635 4524 111237115.4367 +4636 4524 -8.344650268555e-07 +4637 4524 -17343888.88603 +4638 4524 4476132.383917 +4639 4524 4861111.1127 +4640 4524 -4335972.223642 +4525 4525 625304024.3239 +4526 4525 6.198883056641e-06 +4527 4525 -19444444.44125 +4528 4525 -92560889.60172 +4529 4525 2.32458114624e-06 +4614 4525 -2.294778823853e-06 +4615 4525 -31882558.21685 +4616 4525 2.682209014893e-07 +4617 4525 -24305555.56354 +4618 4525 -39081501.55876 +4619 4525 17343750.0057 +4635 4525 -7.152557373047e-07 +4636 4525 82069384.74161 +4637 4525 -3.75509262085e-06 +4638 4525 -4861111.112713 +4639 4525 -41704377.77507 +4640 4525 34687499.9943 +4526 4526 582912992.1231 +4527 4526 -7.271766662598e-06 +4528 4526 1.877546310425e-06 +4529 4526 52395662.19267 +4614 4526 86719444.4302 +4615 4526 3.427267074585e-07 +4616 4526 -99061955.12464 +4617 4526 21679861.11823 +4618 4526 17343750.0057 +4619 4526 -36432062.04359 +4635 4526 17343888.88605 +4636 4526 -3.576278686523e-06 +4637 4526 -52289409.00778 +4638 4526 4335972.22365 +4639 4526 34687499.9943 +4640 4526 -36405498.74735 +4527 4527 741974947.0469 +4528 4527 5.006790161133e-06 +4529 4527 -2.908706665039e-05 +4530 4527 92161150.94322 +4531 4527 19444444.44125 +4532 4527 -7.271766662598e-06 +4614 4527 -46373434.23613 +4615 4527 24305555.56354 +4616 4527 21679861.11823 +4617 4527 -138827443.8752 +4618 4527 2.682209014893e-07 +4619 4527 86719444.4302 +4620 4527 -46373434.23614 +4621 4527 -24305555.56354 +4622 4527 21679861.11823 +4635 4527 4476132.383914 +4636 4527 -4861111.112702 +4637 4527 -4335972.223643 +4638 4527 111237115.4367 +4639 4527 -8.344650268555e-07 +4640 4527 -17343888.88603 +4641 4527 4476132.383917 +4642 4527 4861111.1127 +4643 4527 -4335972.223642 +4528 4528 625304024.3239 +4529 4528 6.198883056641e-06 +4530 4528 -19444444.44125 +4531 4528 -92560889.60172 +4532 4528 2.32458114624e-06 +4614 4528 24305555.56354 +4615 4528 -39081501.55876 +4616 4528 -17343750.00569 +4617 4528 -2.294778823853e-06 +4618 4528 -31882558.21685 +4619 4528 2.682209014893e-07 +4620 4528 -24305555.56354 +4621 4528 -39081501.55876 +4622 4528 17343750.0057 +4635 4528 4861111.112712 +4636 4528 -41704377.77507 +4637 4528 -34687499.9943 +4638 4528 -7.152557373047e-07 +4639 4528 82069384.74161 +4640 4528 -3.75509262085e-06 +4641 4528 -4861111.112713 +4642 4528 -41704377.77507 +4643 4528 34687499.9943 +4529 4529 582912992.1231 +4530 4529 -7.271766662598e-06 +4531 4529 1.877546310425e-06 +4532 4529 52395662.19267 +4614 4529 21679861.11823 +4615 4529 -17343750.0057 +4616 4529 -36432062.04359 +4617 4529 86719444.4302 +4618 4529 3.427267074585e-07 +4619 4529 -99061955.12464 +4620 4529 21679861.11823 +4621 4529 17343750.0057 +4622 4529 -36432062.04359 +4635 4529 4335972.223649 +4636 4529 -34687499.9943 +4637 4529 -36405498.74736 +4638 4529 17343888.88605 +4639 4529 -3.576278686523e-06 +4640 4529 -52289409.00778 +4641 4529 4335972.22365 +4642 4529 34687499.9943 +4643 4529 -36405498.74735 +4530 4530 741974947.0469 +4531 4530 5.006790161133e-06 +4532 4530 -2.908706665039e-05 +4533 4530 92161150.94322 +4534 4530 19444444.44125 +4535 4530 -7.271766662598e-06 +4617 4530 -46373434.23613 +4618 4530 24305555.56354 +4619 4530 21679861.11823 +4620 4530 -138827443.8752 +4621 4530 2.682209014893e-07 +4622 4530 86719444.4302 +4623 4530 -46373434.23614 +4624 4530 -24305555.56354 +4625 4530 21679861.11823 +4638 4530 4476132.383914 +4639 4530 -4861111.112702 +4640 4530 -4335972.223643 +4641 4530 111237115.4367 +4642 4530 -8.344650268555e-07 +4643 4530 -17343888.88603 +4644 4530 4476132.383917 +4645 4530 4861111.1127 +4646 4530 -4335972.223642 +4531 4531 625304024.3239 +4532 4531 6.198883056641e-06 +4533 4531 -19444444.44125 +4534 4531 -92560889.60172 +4535 4531 2.32458114624e-06 +4617 4531 24305555.56354 +4618 4531 -39081501.55876 +4619 4531 -17343750.00569 +4620 4531 -2.294778823853e-06 +4621 4531 -31882558.21685 +4622 4531 2.682209014893e-07 +4623 4531 -24305555.56354 +4624 4531 -39081501.55876 +4625 4531 17343750.0057 +4638 4531 4861111.112712 +4639 4531 -41704377.77507 +4640 4531 -34687499.9943 +4641 4531 -7.152557373047e-07 +4642 4531 82069384.74161 +4643 4531 -3.75509262085e-06 +4644 4531 -4861111.112713 +4645 4531 -41704377.77507 +4646 4531 34687499.9943 +4532 4532 582912992.1231 +4533 4532 -7.271766662598e-06 +4534 4532 1.877546310425e-06 +4535 4532 52395662.19267 +4617 4532 21679861.11823 +4618 4532 -17343750.0057 +4619 4532 -36432062.04359 +4620 4532 86719444.4302 +4621 4532 3.427267074585e-07 +4622 4532 -99061955.12464 +4623 4532 21679861.11823 +4624 4532 17343750.0057 +4625 4532 -36432062.04359 +4638 4532 4335972.223649 +4639 4532 -34687499.9943 +4640 4532 -36405498.74736 +4641 4532 17343888.88605 +4642 4532 -3.576278686523e-06 +4643 4532 -52289409.00778 +4644 4532 4335972.22365 +4645 4532 34687499.9943 +4646 4532 -36405498.74735 +4533 4533 741974947.0469 +4534 4533 5.006790161133e-06 +4535 4533 -2.908706665039e-05 +4536 4533 92161150.94322 +4537 4533 19444444.44125 +4538 4533 -7.271766662598e-06 +4620 4533 -46373434.23613 +4621 4533 24305555.56354 +4622 4533 21679861.11823 +4623 4533 -138827443.8752 +4624 4533 2.682209014893e-07 +4625 4533 86719444.4302 +4626 4533 -46373434.23614 +4627 4533 -24305555.56354 +4628 4533 21679861.11823 +4641 4533 4476132.383914 +4642 4533 -4861111.112702 +4643 4533 -4335972.223643 +4644 4533 111237115.4367 +4645 4533 -8.344650268555e-07 +4646 4533 -17343888.88603 +4647 4533 4476132.383917 +4648 4533 4861111.1127 +4649 4533 -4335972.223642 +4534 4534 625304024.3239 +4535 4534 6.198883056641e-06 +4536 4534 -19444444.44125 +4537 4534 -92560889.60172 +4538 4534 2.32458114624e-06 +4620 4534 24305555.56354 +4621 4534 -39081501.55876 +4622 4534 -17343750.00569 +4623 4534 -2.294778823853e-06 +4624 4534 -31882558.21685 +4625 4534 2.682209014893e-07 +4626 4534 -24305555.56354 +4627 4534 -39081501.55876 +4628 4534 17343750.0057 +4641 4534 4861111.112712 +4642 4534 -41704377.77507 +4643 4534 -34687499.9943 +4644 4534 -7.152557373047e-07 +4645 4534 82069384.74161 +4646 4534 -3.75509262085e-06 +4647 4534 -4861111.112713 +4648 4534 -41704377.77507 +4649 4534 34687499.9943 +4535 4535 582912992.1231 +4536 4535 -7.271766662598e-06 +4537 4535 1.877546310425e-06 +4538 4535 52395662.19267 +4620 4535 21679861.11823 +4621 4535 -17343750.0057 +4622 4535 -36432062.04359 +4623 4535 86719444.4302 +4624 4535 3.427267074585e-07 +4625 4535 -99061955.12464 +4626 4535 21679861.11823 +4627 4535 17343750.0057 +4628 4535 -36432062.04359 +4641 4535 4335972.223649 +4642 4535 -34687499.9943 +4643 4535 -36405498.74736 +4644 4535 17343888.88605 +4645 4535 -3.576278686523e-06 +4646 4535 -52289409.00778 +4647 4535 4335972.22365 +4648 4535 34687499.9943 +4649 4535 -36405498.74735 +4536 4536 741974947.0469 +4537 4536 5.006790161133e-06 +4538 4536 -2.908706665039e-05 +4539 4536 92161150.94322 +4540 4536 19444444.44125 +4541 4536 -7.271766662598e-06 +4623 4536 -46373434.23613 +4624 4536 24305555.56354 +4625 4536 21679861.11823 +4626 4536 -138827443.8752 +4627 4536 2.682209014893e-07 +4628 4536 86719444.4302 +4629 4536 -46373434.23614 +4630 4536 -24305555.56354 +4631 4536 21679861.11823 +4644 4536 4476132.383914 +4645 4536 -4861111.112702 +4646 4536 -4335972.223643 +4647 4536 111237115.4367 +4648 4536 -8.344650268555e-07 +4649 4536 -17343888.88603 +4650 4536 4476132.383917 +4651 4536 4861111.1127 +4652 4536 -4335972.223642 +4537 4537 625304024.3239 +4538 4537 6.198883056641e-06 +4539 4537 -19444444.44125 +4540 4537 -92560889.60172 +4541 4537 2.32458114624e-06 +4623 4537 24305555.56354 +4624 4537 -39081501.55876 +4625 4537 -17343750.00569 +4626 4537 -2.294778823853e-06 +4627 4537 -31882558.21685 +4628 4537 2.682209014893e-07 +4629 4537 -24305555.56354 +4630 4537 -39081501.55876 +4631 4537 17343750.0057 +4644 4537 4861111.112712 +4645 4537 -41704377.77507 +4646 4537 -34687499.9943 +4647 4537 -7.152557373047e-07 +4648 4537 82069384.74161 +4649 4537 -3.75509262085e-06 +4650 4537 -4861111.112713 +4651 4537 -41704377.77507 +4652 4537 34687499.9943 +4538 4538 582912992.1231 +4539 4538 -7.271766662598e-06 +4540 4538 1.877546310425e-06 +4541 4538 52395662.19267 +4623 4538 21679861.11823 +4624 4538 -17343750.0057 +4625 4538 -36432062.04359 +4626 4538 86719444.4302 +4627 4538 3.427267074585e-07 +4628 4538 -99061955.12464 +4629 4538 21679861.11823 +4630 4538 17343750.0057 +4631 4538 -36432062.04359 +4644 4538 4335972.223649 +4645 4538 -34687499.9943 +4646 4538 -36405498.74736 +4647 4538 17343888.88605 +4648 4538 -3.576278686523e-06 +4649 4538 -52289409.00778 +4650 4538 4335972.22365 +4651 4538 34687499.9943 +4652 4538 -36405498.74735 +4539 4539 743972693.3092 +4540 4539 15895.84580326 +4541 4539 -1.50203704834e-05 +4542 4539 96103889.5723 +4543 4539 23223356.21638 +4544 4539 1.668930053711e-06 +4626 4539 -46373434.23613 +4627 4539 24305555.56354 +4628 4539 21679861.11823 +4629 4539 -140996480.167 +4630 4539 -952893.2695162 +4631 4539 87564583.31904 +4632 4539 -45870736.57861 +4633 4539 -24301364.19971 +4634 4539 21679166.67379 +4647 4539 4476132.383914 +4648 4539 -4861111.112702 +4649 4539 -4335972.223643 +4650 4539 111737658.2526 +4651 4539 3973.961447597 +4652 4539 -17343611.10825 +4653 4539 5643546.0595 +4654 4539 5805839.056953 +4655 4539 -5182361.11248 +4540 4540 624700330.4184 +4541 4540 1.788139343262e-05 +4542 4540 -15665532.66612 +4543 4540 -87045539.95468 +4544 4540 5.960464477539e-07 +4626 4540 24305555.56354 +4627 4540 -39081501.55876 +4628 4540 -17343750.00569 +4629 4540 -952893.2695182 +4630 4540 -33140775.69076 +4631 4540 677083.3332871 +4632 4540 -24301364.19971 +4633 4540 -39232415.4315 +4634 4540 17343750.00569 +4647 4540 4861111.112712 +4648 4540 -41704377.77507 +4649 4540 -34687499.9943 +4650 4540 3973.961447477 +4651 4540 81919567.51516 +4652 4540 -6.735324859619e-06 +4653 4540 -3916383.16846 +4654 4540 -40143811.34479 +4655 4540 34010416.66101 +4541 4541 583290059.4325 +4542 4541 -1.192092895508e-07 +4543 4541 7.748603820801e-07 +4544 4541 54461159.75298 +4626 4541 21679861.11823 +4627 4541 -17343750.0057 +4628 4541 -36432062.04359 +4629 4541 87564583.31887 +4630 4541 677083.3331537 +4631 4541 -100252145.5455 +4632 4541 21679166.67379 +4633 4541 17343750.00569 +4634 4541 -36335759.26895 +4647 4541 4335972.223649 +4648 4541 -34687499.9943 +4649 4541 -36405498.74736 +4650 4541 17343611.10827 +4651 4541 -6.496906280518e-06 +4652 4541 -52192192.18038 +4653 4541 3489305.557201 +4654 4541 34010416.66114 +4655 4541 -35404513.64281 +4542 4542 745987487.9303 +4543 4542 -2453991.979033 +4544 4542 -1.192092895508e-06 +4545 4542 -141080087.6865 +4546 4542 -95899021.31303 +4547 4542 -4.440546035767e-06 +4548 4542 92610986.19901 +4549 4542 22063836.70035 +4550 4542 1.54972076416e-06 +4629 4542 -48879322.66664 +4630 4542 24272689.58238 +4631 4542 22525694.45184 +4632 4542 -141002035.2671 +4633 4542 -1284012.256585 +4634 4542 85676388.87482 +4650 4542 5643546.05949 +4651 4542 -3916383.16846 +4652 4542 -3489305.557201 +4653 4542 115620942.6216 +4654 4542 -613497.9950627 +4655 4542 -17135277.77496 +4656 4542 -43801307.66029 +4657 4542 -23974755.34006 +4658 4542 20312500.00667 +4659 4542 5916032.26987 +4660 4542 5515959.177802 +4661 4542 -5078333.334501 +4543 4543 616411761.6305 +4544 4543 2.765655517578e-05 +4545 4543 -95899021.31303 +4546 4543 -117437349.9808 +4547 4543 -9.536743164063e-07 +4548 4543 -16825052.18215 +4549 4543 -92728025.5149 +4550 4543 3.576278686523e-07 +4629 4543 24272689.58238 +4630 4543 -38326906.89252 +4631 4543 -16666666.67214 +4632 4543 -1284012.256586 +4633 4543 -32949093.52409 +4634 4543 677083.333285 +4650 4543 5805839.056955 +4651 4543 -40143811.34481 +4652 4543 -34010416.66115 +4653 4543 -613497.9950588 +4654 4543 83227011.03069 +4655 4543 -1.034140586853e-05 +4656 4543 -23974755.34006 +4657 4543 -37890623.23096 +4658 4543 16666666.67214 +4659 4543 -4206263.047611 +4660 4543 -40418720.68142 +4661 4543 33333333.32786 +4544 4544 572020605.8755 +4545 4544 -4.291534423828e-06 +4546 4544 -8.79168510437e-07 +4547 4544 -46375866.82273 +4548 4544 -3.576278686523e-07 +4549 4544 3.278255462646e-07 +4550 4544 48718383.22464 +4629 4544 22525694.45184 +4630 4544 -16666666.67214 +4631 4544 -36909325.87324 +4632 4544 85676388.87482 +4633 4544 677083.3331516 +4634 4544 -97565514.93122 +4650 4544 5182361.11248 +4651 4544 -34010416.66102 +4652 4544 -35404513.64282 +4653 4544 17135277.77496 +4654 4544 -1.025199890137e-05 +4655 4544 -45997327.00157 +4656 4544 20312500.00667 +4657 4544 16666666.67214 +4658 4544 -34344061.96817 +4659 4544 3385277.779223 +4660 4544 33333333.32786 +4661 4544 -33784975.63128 +4545 4545 361120236.1713 +4546 4545 94548810.89503 +4547 4545 5.722045898438e-06 +4548 4545 -203961436.0496 +4549 4545 -20767645.33449 +4550 4545 -2.413988113403e-06 +4632 4545 4511607.610489 +4633 4545 5529463.940845 +4634 4545 4909027.779056 +4653 4545 -43801307.66029 +4654 4545 -23974755.34007 +4655 4545 -20312500.00667 +4656 4545 56503201.94982 +4657 4545 23637202.7354 +4658 4545 8124999.998666 +4659 4545 -68052930.47167 +4660 4545 -5191911.336183 +4661 4545 -41471527.77105 +4546 4546 308313282.913 +4547 4546 9.775161743164e-06 +4548 4546 18121243.54801 +4549 4546 9374992.872524 +4550 4546 5.900859832764e-06 +4632 4546 -4192758.28457 +4633 4546 -41531445.75454 +4634 4546 -33333333.32786 +4653 4546 -23974755.34007 +4654 4546 -37890623.23096 +4655 4546 -16666666.67214 +4656 4546 23637202.7354 +4657 4546 43301463.62873 +4658 4546 6666666.665569 +4659 4546 4530310.889231 +4660 4546 -14718823.21489 +4661 4546 3333333.334426 +4547 4547 278103282.9517 +4548 4547 -2.98023223877e-07 +4549 4547 5.781650543213e-06 +4550 4547 -4811252.171681 +4632 4547 -3215972.223779 +4633 4547 -33333333.32786 +4634 4547 -33978945.7605 +4653 4547 -20312500.00667 +4654 4547 -16666666.67214 +4655 4547 -34344061.96817 +4656 4547 -8124999.998665 +4657 4547 -6666666.665574 +4658 4547 -20545798.26111 +4659 4547 -41471527.77088 +4660 4547 -3333333.33443 +4661 4547 -46703003.53464 +4548 4548 371304389.3859 +4549 4548 -99841614.46535 +4550 4548 -4.52995300293e-06 +4632 4548 -47751770.62456 +4633 4548 24636355.78701 +4634 4548 21159027.78473 +4653 4548 5916032.269863 +4654 4548 -4206263.047612 +4655 4548 -3385277.779223 +4656 4548 -68052930.47167 +4657 4548 4530310.889239 +4658 4548 41471527.77088 +4659 4548 58352668.82659 +4660 4548 -24960403.62863 +4661 4548 -8463611.10972 +4549 4549 309788077.0662 +4550 4549 1.430511474609e-05 +4632 4549 24636355.78701 +4633 4549 -39372046.84256 +4634 4549 -16666666.67214 +4653 4549 5515959.177803 +4654 4549 -40418720.68144 +4655 4549 -33333333.32786 +4656 4549 -5191911.336175 +4657 4549 -14718823.21489 +4658 4549 3333333.334426 +4659 4549 -24960403.62863 +4660 4549 42973590.7391 +4661 4549 6666666.665565 +4550 4550 283253096.8786 +4632 4550 21159027.78473 +4633 4550 -16666666.67214 +4634 4550 -35825485.57977 +4653 4550 5078333.334501 +4654 4550 -33333333.32786 +4655 4550 -33784975.63128 +4656 4550 41471527.77105 +4657 4550 -3333333.33443 +4658 4550 -46703003.53464 +4659 4550 8463611.109722 +4660 4550 -6666666.665577 +4661 4550 -21115868.58705 +4551 4551 927468678.158 +4552 4551 97222222.20623 +4553 4551 -8.106231689453e-06 +4554 4551 -573726109.9308 +4555 4551 -97222221.42845 +4556 4551 8.940696716309e-07 +4557 4551 18564155.00999 +4558 4551 77777776.9872 +4559 4551 2.861022949219e-06 +4662 4551 139046393.5639 +4663 4551 24305555.56354 +4664 4551 17343888.84952 +4665 4551 -175918799.4896 +4666 4551 -24305555.36909 +4667 4551 -86719444.24762 +4668 4551 -9282077.505002 +4669 4551 19444444.25638 +4670 4551 -17343888.52033 +4552 4552 781630025.6149 +4553 4552 8.412431954121e-06 +4554 4552 -97222221.03956 +4555 4552 -116778839.2437 +4556 4552 5.602836608887e-06 +4557 4552 116666665.4808 +4558 4552 18564155.00998 +4559 4552 5.960464477539e-07 +4662 4552 24305555.56354 +4663 4552 102586730.4102 +4664 4552 13874999.85143 +4665 4552 -24305555.27187 +4666 4552 -61681981.76159 +4667 4552 -17343749.90781 +4668 4552 29166666.38457 +4669 4552 -9282077.504995 +4670 4552 20812499.90894 +4553 4553 728641235.3813 +4554 4553 4.172325134277e-07 +4555 4553 4.887580871582e-06 +4556 4553 -96436338.25295 +4557 4553 2.503395080566e-06 +4558 4553 1.251697540283e-06 +4559 4553 49504413.35998 +4662 4553 -17343888.84952 +4663 4553 -13874999.85144 +4664 4553 -65361760.6378 +4665 4553 -86719444.24762 +4666 4553 -17343749.94044 +4667 4553 -110741809.7386 +4668 4553 -26015832.7805 +4669 4553 13874999.9393 +4670 4553 -24752206.67999 +4554 4554 1632315315.374 +4555 4554 97222220.26178 +4556 4554 -4.172325134277e-05 +4557 4554 17392720.97666 +4558 4554 -97222221.42845 +4559 4554 -2.145767211914e-06 +4560 4554 -406796532.3944 +4561 4554 -2.801418304443e-06 +4562 4554 -1.233816146851e-05 +4563 4554 -148365426.1266 +4564 4554 97222222.20624 +4565 4554 -3.308057785034e-06 +4662 4554 -175918799.4897 +4663 4554 -24305555.27186 +4664 4554 86719444.24762 +4665 4554 268847663.9159 +4666 4554 24305555.07742 +4667 4554 0.03653132915497 +4668 4554 -28139091.37671 +4669 4554 -24305555.36909 +4670 4554 21679860.74398 +4671 4554 -138827443.8751 +4672 4554 -5.066394805908e-07 +4673 4554 -86719444.43019 +4674 4554 -46373434.23611 +4675 4554 24305555.56353 +4676 4554 -21679861.11823 +4555 4555 1369805740.108 +4556 4555 -2.145767211914e-06 +4557 4555 -97222221.03956 +4558 4555 -322883627.8625 +4559 4555 4.798173904419e-06 +4560 4555 -3.09944152832e-06 +4561 4555 20983010.02827 +4562 4555 -4.768371582031e-07 +4563 4555 97222222.20624 +4564 4555 -119197695.4315 +4565 4555 -7.450580596924e-08 +4662 4555 -24305555.36908 +4663 4555 -61681981.7616 +4664 4555 17343749.94043 +4665 4555 24305555.07742 +4666 4555 203220270.0671 +4667 4555 0.02920919656754 +4668 4555 -24305555.27186 +4669 4555 -113208178.6284 +4670 4555 69374999.6084 +4671 4555 -8.344650268555e-07 +4672 4555 -31882558.21681 +4673 4555 -3.278255462646e-07 +4674 4555 24305555.56353 +4675 4555 -39081501.55875 +4676 4555 17343750.00569 +4556 4556 1212545401.289 +4557 4556 -1.788139343262e-06 +4558 4556 3.75509262085e-06 +4559 4556 8567490.576108 +4560 4556 -1.20997428894e-05 +4561 4556 -4.768371582031e-07 +4562 4556 -212506.0825927 +4563 4556 -3.278255462646e-06 +4564 4556 -2.086162567139e-07 +4565 4556 -46719419.49861 +4662 4556 86719444.24762 +4663 4556 17343749.9078 +4664 4556 -110741809.7386 +4665 4556 -0.03649973869324 +4666 4556 -0.02921465039253 +4667 4556 -68146756.53808 +4668 4556 21679860.55685 +4669 4556 69374999.49133 +4670 4556 -84490851.68298 +4671 4556 -86719444.43019 +4672 4556 -2.682209014893e-07 +4673 4556 -99061955.12461 +4674 4556 -21679861.11823 +4675 4556 17343750.00569 +4676 4556 -36432062.04358 +4557 4557 927468678.158 +4558 4557 97222222.20623 +4559 4557 -8.106231689453e-06 +4560 4557 -148365426.1266 +4561 4557 -97222222.20624 +4562 4557 -3.039836883545e-06 +4563 4557 -573726109.9308 +4564 4557 -97222221.42845 +4565 4557 8.940696716309e-07 +4566 4557 18564155.00999 +4567 4557 77777776.9872 +4568 4557 2.861022949219e-06 +4662 4557 -9282077.50499 +4663 4557 29166666.38457 +4664 4557 26015832.78049 +4665 4557 -28139091.37673 +4666 4557 -24305555.27187 +4667 4557 -21679860.55685 +4668 4557 139046393.5639 +4669 4557 24305555.56354 +4670 4557 17343888.84952 +4671 4557 -46373434.23611 +4672 4557 -24305555.56353 +4673 4557 -21679861.11823 +4674 4557 -175918799.4896 +4675 4557 -24305555.36909 +4676 4557 -86719444.24762 +4677 4557 -9282077.505002 +4678 4557 19444444.25638 +4679 4557 -17343888.52033 +4558 4558 781630025.6149 +4559 4558 8.412431954121e-06 +4560 4558 -97222222.20624 +4561 4558 -119197695.4315 +4562 4558 2.831220626831e-07 +4563 4558 -97222221.03956 +4564 4558 -116778839.2437 +4565 4558 5.602836608887e-06 +4566 4558 116666665.4808 +4567 4558 18564155.00998 +4568 4558 5.960464477539e-07 +4662 4558 19444444.25638 +4663 4558 -9282077.505 +4664 4558 -13874999.9393 +4665 4558 -24305555.36909 +4666 4558 -113208178.6284 +4667 4558 -69374999.49133 +4668 4558 24305555.56354 +4669 4558 102586730.4102 +4670 4558 13874999.85143 +4671 4558 -24305555.56353 +4672 4558 -39081501.55875 +4673 4558 -17343750.0057 +4674 4558 -24305555.27187 +4675 4558 -61681981.76159 +4676 4558 -17343749.90781 +4677 4558 29166666.38457 +4678 4558 -9282077.504995 +4679 4558 20812499.90894 +4559 4559 728641235.3813 +4560 4559 -2.890825271606e-06 +4561 4559 3.8743019104e-07 +4562 4559 -46719419.49861 +4563 4559 4.172325134277e-07 +4564 4559 4.887580871582e-06 +4565 4559 -96436338.25295 +4566 4559 2.503395080566e-06 +4567 4559 1.251697540283e-06 +4568 4559 49504413.35998 +4662 4559 17343888.52033 +4663 4559 -20812499.90895 +4664 4559 -24752206.67999 +4665 4559 -21679860.74398 +4666 4559 -69374999.6084 +4667 4559 -84490851.68299 +4668 4559 -17343888.84952 +4669 4559 -13874999.85144 +4670 4559 -65361760.6378 +4671 4559 -21679861.11823 +4672 4559 -17343750.0057 +4673 4559 -36432062.04358 +4674 4559 -86719444.24762 +4675 4559 -17343749.94044 +4676 4559 -110741809.7386 +4677 4559 -26015832.7805 +4678 4559 13874999.9393 +4679 4559 -24752206.67999 +4560 4560 1483949894.094 +4561 4560 7.867813110352e-06 +4562 4560 -5.507469177246e-05 +4563 4560 184322301.8864 +4564 4560 -2.622604370117e-06 +4565 4560 -1.358985900879e-05 +4569 4560 -406796532.3944 +4570 4560 -2.801418304443e-06 +4571 4560 -1.233816146851e-05 +4572 4560 -148365426.1266 +4573 4560 97222222.20624 +4574 4560 -3.308057785034e-06 +4665 4560 -138827443.8752 +4666 4560 2.682209014893e-07 +4667 4560 86719444.4302 +4668 4560 -46373434.23614 +4669 4560 -24305555.56354 +4670 4560 21679861.11823 +4671 4560 222474230.8735 +4672 4560 3.933906555176e-06 +4673 4560 2.622604370117e-05 +4674 4560 8952264.76783 +4675 4560 -1.302361488342e-05 +4676 4560 6.914138793945e-06 +4680 4560 -138827443.8751 +4681 4560 -5.066394805908e-07 +4682 4560 -86719444.43019 +4683 4560 -46373434.23611 +4684 4560 24305555.56353 +4685 4560 -21679861.11823 +4561 4561 1250608048.648 +4562 4561 -1.192092895508e-06 +4563 4561 -3.159046173096e-06 +4564 4561 -185121779.2034 +4565 4561 8.046627044678e-07 +4569 4561 -3.09944152832e-06 +4570 4561 20983010.02827 +4571 4561 -4.768371582031e-07 +4572 4561 97222222.20624 +4573 4561 -119197695.4315 +4574 4561 -7.450580596924e-08 +4665 4561 -2.294778823853e-06 +4666 4561 -31882558.21685 +4667 4561 2.682209014893e-07 +4668 4561 -24305555.56354 +4669 4561 -39081501.55876 +4670 4561 17343750.0057 +4671 4561 4.410743713379e-06 +4672 4561 164138769.4832 +4673 4561 -1.192092895508e-07 +4674 4561 -1.156330108643e-05 +4675 4561 -83408755.55014 +4676 4561 69374999.9886 +4680 4561 -8.344650268555e-07 +4681 4561 -31882558.21681 +4682 4561 -3.278255462646e-07 +4683 4561 24305555.56353 +4684 4561 -39081501.55875 +4685 4561 17343750.00569 +4562 4562 1165825984.246 +4563 4562 -1.382827758789e-05 +4564 4562 1.788139343262e-07 +4565 4562 104791324.3853 +4569 4562 -1.20997428894e-05 +4570 4562 -4.768371582031e-07 +4571 4562 -212506.0825927 +4572 4562 -3.278255462646e-06 +4573 4562 -2.086162567139e-07 +4574 4562 -46719419.49861 +4665 4562 86719444.4302 +4666 4562 3.427267074585e-07 +4667 4562 -99061955.12464 +4668 4562 21679861.11823 +4669 4562 17343750.0057 +4670 4562 -36432062.04359 +4671 4562 2.598762512207e-05 +4672 4562 5.960464477539e-08 +4673 4562 -104578818.0156 +4674 4562 6.973743438721e-06 +4675 4562 69374999.9886 +4676 4562 -72810997.49471 +4680 4562 -86719444.43019 +4681 4562 -2.682209014893e-07 +4682 4562 -99061955.12461 +4683 4562 -21679861.11823 +4684 4562 17343750.00569 +4685 4562 -36432062.04358 +4563 4563 1632315315.374 +4564 4563 97222220.26178 +4565 4563 -4.172325134277e-05 +4566 4563 17392720.97666 +4567 4563 -97222221.42845 +4568 4563 -2.145767211914e-06 +4569 4563 -148365426.1266 +4570 4563 -97222222.20624 +4571 4563 -3.039836883545e-06 +4572 4563 -406796532.3944 +4573 4563 -2.801418304443e-06 +4574 4563 -1.233816146851e-05 +4575 4563 -148365426.1266 +4576 4563 97222222.20624 +4577 4563 -3.308057785034e-06 +4665 4563 -46373434.23613 +4666 4563 24305555.56354 +4667 4563 21679861.11823 +4668 4563 -175918799.4897 +4669 4563 -24305555.27186 +4670 4563 86719444.24762 +4671 4563 8952264.76783 +4672 4563 9.298324584961e-06 +4673 4563 6.228685379028e-06 +4674 4563 268847663.9159 +4675 4563 24305555.07742 +4676 4563 0.03653132915497 +4677 4563 -28139091.37671 +4678 4563 -24305555.36909 +4679 4563 21679860.74398 +4680 4563 -46373434.23611 +4681 4563 -24305555.56353 +4682 4563 -21679861.11823 +4683 4563 -138827443.8751 +4684 4563 -5.066394805908e-07 +4685 4563 -86719444.43019 +4686 4563 -46373434.23611 +4687 4563 24305555.56353 +4688 4563 -21679861.11823 +4564 4564 1369805740.108 +4565 4564 -2.145767211914e-06 +4566 4564 -97222221.03956 +4567 4564 -322883627.8625 +4568 4564 4.798173904419e-06 +4569 4564 -97222222.20624 +4570 4564 -119197695.4315 +4571 4564 2.831220626831e-07 +4572 4564 -3.09944152832e-06 +4573 4564 20983010.02827 +4574 4564 -4.768371582031e-07 +4575 4564 97222222.20624 +4576 4564 -119197695.4315 +4577 4564 -7.450580596924e-08 +4665 4564 24305555.56354 +4666 4564 -39081501.55876 +4667 4564 -17343750.00569 +4668 4564 -24305555.36908 +4669 4564 -61681981.7616 +4670 4564 17343749.94043 +4671 4564 1.069903373718e-05 +4672 4564 -83408755.55014 +4673 4564 -69374999.9886 +4674 4564 24305555.07742 +4675 4564 203220270.0671 +4676 4564 0.02920919656754 +4677 4564 -24305555.27186 +4678 4564 -113208178.6284 +4679 4564 69374999.6084 +4680 4564 -24305555.56353 +4681 4564 -39081501.55875 +4682 4564 -17343750.0057 +4683 4564 -8.344650268555e-07 +4684 4564 -31882558.21681 +4685 4564 -3.278255462646e-07 +4686 4564 24305555.56353 +4687 4564 -39081501.55875 +4688 4564 17343750.00569 +4565 4565 1212545401.289 +4566 4565 -1.788139343262e-06 +4567 4565 3.75509262085e-06 +4568 4565 8567490.576108 +4569 4565 -2.890825271606e-06 +4570 4565 3.8743019104e-07 +4571 4565 -46719419.49861 +4572 4565 -1.20997428894e-05 +4573 4565 -4.768371582031e-07 +4574 4565 -212506.0825927 +4575 4565 -3.278255462646e-06 +4576 4565 -2.086162567139e-07 +4577 4565 -46719419.49861 +4665 4565 21679861.11823 +4666 4565 -17343750.0057 +4667 4565 -36432062.04359 +4668 4565 86719444.24762 +4669 4565 17343749.9078 +4670 4565 -110741809.7386 +4671 4565 6.169080734253e-06 +4672 4565 -69374999.9886 +4673 4565 -72810997.49471 +4674 4565 -0.03649973869324 +4675 4565 -0.02921465039253 +4676 4565 -68146756.53808 +4677 4565 21679860.55685 +4678 4565 69374999.49133 +4679 4565 -84490851.68298 +4680 4565 -21679861.11823 +4681 4565 -17343750.0057 +4682 4565 -36432062.04358 +4683 4565 -86719444.43019 +4684 4565 -2.682209014893e-07 +4685 4565 -99061955.12461 +4686 4565 -21679861.11823 +4687 4565 17343750.00569 +4688 4565 -36432062.04358 +4566 4566 927468678.158 +4567 4566 97222222.20623 +4568 4566 -8.106231689453e-06 +4572 4566 -148365426.1266 +4573 4566 -97222222.20624 +4574 4566 -3.039836883545e-06 +4575 4566 -573726109.9308 +4576 4566 -97222221.42845 +4577 4566 8.940696716309e-07 +4578 4566 18564155.00999 +4579 4566 77777776.9872 +4580 4566 2.861022949219e-06 +4668 4566 -9282077.50499 +4669 4566 29166666.38457 +4670 4566 26015832.78049 +4674 4566 -28139091.37673 +4675 4566 -24305555.27187 +4676 4566 -21679860.55685 +4677 4566 139046393.5639 +4678 4566 24305555.56354 +4679 4566 17343888.84952 +4683 4566 -46373434.23611 +4684 4566 -24305555.56353 +4685 4566 -21679861.11823 +4686 4566 -175918799.4896 +4687 4566 -24305555.36909 +4688 4566 -86719444.24762 +4689 4566 -9282077.505002 +4690 4566 19444444.25638 +4691 4566 -17343888.52033 +4567 4567 781630025.6149 +4568 4567 8.412431954121e-06 +4572 4567 -97222222.20624 +4573 4567 -119197695.4315 +4574 4567 2.831220626831e-07 +4575 4567 -97222221.03956 +4576 4567 -116778839.2437 +4577 4567 5.602836608887e-06 +4578 4567 116666665.4808 +4579 4567 18564155.00998 +4580 4567 5.960464477539e-07 +4668 4567 19444444.25638 +4669 4567 -9282077.505 +4670 4567 -13874999.9393 +4674 4567 -24305555.36909 +4675 4567 -113208178.6284 +4676 4567 -69374999.49133 +4677 4567 24305555.56354 +4678 4567 102586730.4102 +4679 4567 13874999.85143 +4683 4567 -24305555.56353 +4684 4567 -39081501.55875 +4685 4567 -17343750.0057 +4686 4567 -24305555.27187 +4687 4567 -61681981.76159 +4688 4567 -17343749.90781 +4689 4567 29166666.38457 +4690 4567 -9282077.504995 +4691 4567 20812499.90894 +4568 4568 728641235.3813 +4572 4568 -2.890825271606e-06 +4573 4568 3.8743019104e-07 +4574 4568 -46719419.49861 +4575 4568 4.172325134277e-07 +4576 4568 4.887580871582e-06 +4577 4568 -96436338.25295 +4578 4568 2.503395080566e-06 +4579 4568 1.251697540283e-06 +4580 4568 49504413.35998 +4668 4568 17343888.52033 +4669 4568 -20812499.90895 +4670 4568 -24752206.67999 +4674 4568 -21679860.74398 +4675 4568 -69374999.6084 +4676 4568 -84490851.68299 +4677 4568 -17343888.84952 +4678 4568 -13874999.85144 +4679 4568 -65361760.6378 +4683 4568 -21679861.11823 +4684 4568 -17343750.0057 +4685 4568 -36432062.04358 +4686 4568 -86719444.24762 +4687 4568 -17343749.94044 +4688 4568 -110741809.7386 +4689 4568 -26015832.7805 +4690 4568 13874999.9393 +4691 4568 -24752206.67999 +4569 4569 1483949894.094 +4570 4569 7.867813110352e-06 +4571 4569 -5.507469177246e-05 +4572 4569 184322301.8864 +4573 4569 -2.622604370117e-06 +4574 4569 -1.358985900879e-05 +4581 4569 -406796532.3944 +4582 4569 -2.801418304443e-06 +4583 4569 -1.233816146851e-05 +4584 4569 -148365426.1266 +4585 4569 97222222.20624 +4586 4569 -3.308057785034e-06 +4671 4569 -138827443.8752 +4672 4569 2.682209014893e-07 +4673 4569 86719444.4302 +4674 4569 -46373434.23614 +4675 4569 -24305555.56354 +4676 4569 21679861.11823 +4680 4569 222474230.8735 +4681 4569 3.933906555176e-06 +4682 4569 2.622604370117e-05 +4683 4569 8952264.76783 +4684 4569 -1.302361488342e-05 +4685 4569 6.914138793945e-06 +4692 4569 -138827443.8751 +4693 4569 -5.066394805908e-07 +4694 4569 -86719444.43019 +4695 4569 -46373434.23611 +4696 4569 24305555.56353 +4697 4569 -21679861.11823 +4570 4570 1250608048.648 +4571 4570 -1.192092895508e-06 +4572 4570 -3.159046173096e-06 +4573 4570 -185121779.2034 +4574 4570 8.046627044678e-07 +4581 4570 -3.09944152832e-06 +4582 4570 20983010.02827 +4583 4570 -4.768371582031e-07 +4584 4570 97222222.20624 +4585 4570 -119197695.4315 +4586 4570 -7.450580596924e-08 +4671 4570 -2.294778823853e-06 +4672 4570 -31882558.21685 +4673 4570 2.682209014893e-07 +4674 4570 -24305555.56354 +4675 4570 -39081501.55876 +4676 4570 17343750.0057 +4680 4570 4.410743713379e-06 +4681 4570 164138769.4832 +4682 4570 -1.192092895508e-07 +4683 4570 -1.156330108643e-05 +4684 4570 -83408755.55014 +4685 4570 69374999.9886 +4692 4570 -8.344650268555e-07 +4693 4570 -31882558.21681 +4694 4570 -3.278255462646e-07 +4695 4570 24305555.56353 +4696 4570 -39081501.55875 +4697 4570 17343750.00569 +4571 4571 1165825984.246 +4572 4571 -1.382827758789e-05 +4573 4571 1.788139343262e-07 +4574 4571 104791324.3853 +4581 4571 -1.20997428894e-05 +4582 4571 -4.768371582031e-07 +4583 4571 -212506.0825927 +4584 4571 -3.278255462646e-06 +4585 4571 -2.086162567139e-07 +4586 4571 -46719419.49861 +4671 4571 86719444.4302 +4672 4571 3.427267074585e-07 +4673 4571 -99061955.12464 +4674 4571 21679861.11823 +4675 4571 17343750.0057 +4676 4571 -36432062.04359 +4680 4571 2.598762512207e-05 +4681 4571 5.960464477539e-08 +4682 4571 -104578818.0156 +4683 4571 6.973743438721e-06 +4684 4571 69374999.9886 +4685 4571 -72810997.49471 +4692 4571 -86719444.43019 +4693 4571 -2.682209014893e-07 +4694 4571 -99061955.12461 +4695 4571 -21679861.11823 +4696 4571 17343750.00569 +4697 4571 -36432062.04358 +4572 4572 1483949894.094 +4573 4572 7.867813110352e-06 +4574 4572 -5.507469177246e-05 +4575 4572 184322301.8864 +4576 4572 -2.622604370117e-06 +4577 4572 -1.358985900879e-05 +4581 4572 -148365426.1266 +4582 4572 -97222222.20624 +4583 4572 -3.039836883545e-06 +4584 4572 -406796532.3944 +4585 4572 -2.801418304443e-06 +4586 4572 -1.233816146851e-05 +4587 4572 -148365426.1266 +4588 4572 97222222.20624 +4589 4572 -3.308057785034e-06 +4671 4572 -46373434.23613 +4672 4572 24305555.56354 +4673 4572 21679861.11823 +4674 4572 -138827443.8752 +4675 4572 2.682209014893e-07 +4676 4572 86719444.4302 +4677 4572 -46373434.23614 +4678 4572 -24305555.56354 +4679 4572 21679861.11823 +4680 4572 8952264.76783 +4681 4572 9.298324584961e-06 +4682 4572 6.228685379028e-06 +4683 4572 222474230.8735 +4684 4572 3.933906555176e-06 +4685 4572 2.622604370117e-05 +4686 4572 8952264.76783 +4687 4572 -1.302361488342e-05 +4688 4572 6.914138793945e-06 +4692 4572 -46373434.23611 +4693 4572 -24305555.56353 +4694 4572 -21679861.11823 +4695 4572 -138827443.8751 +4696 4572 -5.066394805908e-07 +4697 4572 -86719444.43019 +4698 4572 -46373434.23611 +4699 4572 24305555.56353 +4700 4572 -21679861.11823 +4573 4573 1250608048.648 +4574 4573 -1.192092895508e-06 +4575 4573 -3.159046173096e-06 +4576 4573 -185121779.2034 +4577 4573 8.046627044678e-07 +4581 4573 -97222222.20624 +4582 4573 -119197695.4315 +4583 4573 2.831220626831e-07 +4584 4573 -3.09944152832e-06 +4585 4573 20983010.02827 +4586 4573 -4.768371582031e-07 +4587 4573 97222222.20624 +4588 4573 -119197695.4315 +4589 4573 -7.450580596924e-08 +4671 4573 24305555.56354 +4672 4573 -39081501.55876 +4673 4573 -17343750.00569 +4674 4573 -2.294778823853e-06 +4675 4573 -31882558.21685 +4676 4573 2.682209014893e-07 +4677 4573 -24305555.56354 +4678 4573 -39081501.55876 +4679 4573 17343750.0057 +4680 4573 1.069903373718e-05 +4681 4573 -83408755.55014 +4682 4573 -69374999.9886 +4683 4573 4.410743713379e-06 +4684 4573 164138769.4832 +4685 4573 -1.192092895508e-07 +4686 4573 -1.156330108643e-05 +4687 4573 -83408755.55014 +4688 4573 69374999.9886 +4692 4573 -24305555.56353 +4693 4573 -39081501.55875 +4694 4573 -17343750.0057 +4695 4573 -8.344650268555e-07 +4696 4573 -31882558.21681 +4697 4573 -3.278255462646e-07 +4698 4573 24305555.56353 +4699 4573 -39081501.55875 +4700 4573 17343750.00569 +4574 4574 1165825984.246 +4575 4574 -1.382827758789e-05 +4576 4574 1.788139343262e-07 +4577 4574 104791324.3853 +4581 4574 -2.890825271606e-06 +4582 4574 3.8743019104e-07 +4583 4574 -46719419.49861 +4584 4574 -1.20997428894e-05 +4585 4574 -4.768371582031e-07 +4586 4574 -212506.0825927 +4587 4574 -3.278255462646e-06 +4588 4574 -2.086162567139e-07 +4589 4574 -46719419.49861 +4671 4574 21679861.11823 +4672 4574 -17343750.0057 +4673 4574 -36432062.04359 +4674 4574 86719444.4302 +4675 4574 3.427267074585e-07 +4676 4574 -99061955.12464 +4677 4574 21679861.11823 +4678 4574 17343750.0057 +4679 4574 -36432062.04359 +4680 4574 6.169080734253e-06 +4681 4574 -69374999.9886 +4682 4574 -72810997.49471 +4683 4574 2.598762512207e-05 +4684 4574 5.960464477539e-08 +4685 4574 -104578818.0156 +4686 4574 6.973743438721e-06 +4687 4574 69374999.9886 +4688 4574 -72810997.49471 +4692 4574 -21679861.11823 +4693 4574 -17343750.0057 +4694 4574 -36432062.04358 +4695 4574 -86719444.43019 +4696 4574 -2.682209014893e-07 +4697 4574 -99061955.12461 +4698 4574 -21679861.11823 +4699 4574 17343750.00569 +4700 4574 -36432062.04358 +4575 4575 1632315315.374 +4576 4575 97222220.26178 +4577 4575 -4.172325134277e-05 +4578 4575 17392720.97666 +4579 4575 -97222221.42845 +4580 4575 -2.145767211914e-06 +4584 4575 -148365426.1266 +4585 4575 -97222222.20624 +4586 4575 -3.039836883545e-06 +4587 4575 -406796532.3944 +4588 4575 -2.801418304443e-06 +4589 4575 -1.233816146851e-05 +4590 4575 -148365426.1266 +4591 4575 97222222.20624 +4592 4575 -3.308057785034e-06 +4674 4575 -46373434.23613 +4675 4575 24305555.56354 +4676 4575 21679861.11823 +4677 4575 -175918799.4897 +4678 4575 -24305555.27186 +4679 4575 86719444.24762 +4683 4575 8952264.76783 +4684 4575 9.298324584961e-06 +4685 4575 6.228685379028e-06 +4686 4575 268847663.9159 +4687 4575 24305555.07742 +4688 4575 0.03653132915497 +4689 4575 -28139091.37671 +4690 4575 -24305555.36909 +4691 4575 21679860.74398 +4695 4575 -46373434.23611 +4696 4575 -24305555.56353 +4697 4575 -21679861.11823 +4698 4575 -138827443.8751 +4699 4575 -5.066394805908e-07 +4700 4575 -86719444.43019 +4701 4575 -46373434.23611 +4702 4575 24305555.56353 +4703 4575 -21679861.11823 +4576 4576 1369805740.108 +4577 4576 -2.145767211914e-06 +4578 4576 -97222221.03956 +4579 4576 -322883627.8625 +4580 4576 4.798173904419e-06 +4584 4576 -97222222.20624 +4585 4576 -119197695.4315 +4586 4576 2.831220626831e-07 +4587 4576 -3.09944152832e-06 +4588 4576 20983010.02827 +4589 4576 -4.768371582031e-07 +4590 4576 97222222.20624 +4591 4576 -119197695.4315 +4592 4576 -7.450580596924e-08 +4674 4576 24305555.56354 +4675 4576 -39081501.55876 +4676 4576 -17343750.00569 +4677 4576 -24305555.36908 +4678 4576 -61681981.7616 +4679 4576 17343749.94043 +4683 4576 1.069903373718e-05 +4684 4576 -83408755.55014 +4685 4576 -69374999.9886 +4686 4576 24305555.07742 +4687 4576 203220270.0671 +4688 4576 0.02920919656754 +4689 4576 -24305555.27186 +4690 4576 -113208178.6284 +4691 4576 69374999.6084 +4695 4576 -24305555.56353 +4696 4576 -39081501.55875 +4697 4576 -17343750.0057 +4698 4576 -8.344650268555e-07 +4699 4576 -31882558.21681 +4700 4576 -3.278255462646e-07 +4701 4576 24305555.56353 +4702 4576 -39081501.55875 +4703 4576 17343750.00569 +4577 4577 1212545401.289 +4578 4577 -1.788139343262e-06 +4579 4577 3.75509262085e-06 +4580 4577 8567490.576108 +4584 4577 -2.890825271606e-06 +4585 4577 3.8743019104e-07 +4586 4577 -46719419.49861 +4587 4577 -1.20997428894e-05 +4588 4577 -4.768371582031e-07 +4589 4577 -212506.0825927 +4590 4577 -3.278255462646e-06 +4591 4577 -2.086162567139e-07 +4592 4577 -46719419.49861 +4674 4577 21679861.11823 +4675 4577 -17343750.0057 +4676 4577 -36432062.04359 +4677 4577 86719444.24762 +4678 4577 17343749.9078 +4679 4577 -110741809.7386 +4683 4577 6.169080734253e-06 +4684 4577 -69374999.9886 +4685 4577 -72810997.49471 +4686 4577 -0.03649973869324 +4687 4577 -0.02921465039253 +4688 4577 -68146756.53808 +4689 4577 21679860.55685 +4690 4577 69374999.49133 +4691 4577 -84490851.68298 +4695 4577 -21679861.11823 +4696 4577 -17343750.0057 +4697 4577 -36432062.04358 +4698 4577 -86719444.43019 +4699 4577 -2.682209014893e-07 +4700 4577 -99061955.12461 +4701 4577 -21679861.11823 +4702 4577 17343750.00569 +4703 4577 -36432062.04358 +4578 4578 927468678.158 +4579 4578 97222222.20623 +4580 4578 -8.106231689453e-06 +4587 4578 -148365426.1266 +4588 4578 -97222222.20624 +4589 4578 -3.039836883545e-06 +4590 4578 -573726109.9308 +4591 4578 -97222221.42845 +4592 4578 8.940696716309e-07 +4593 4578 18564155.00999 +4594 4578 77777776.9872 +4595 4578 2.861022949219e-06 +4677 4578 -9282077.50499 +4678 4578 29166666.38457 +4679 4578 26015832.78049 +4686 4578 -28139091.37673 +4687 4578 -24305555.27187 +4688 4578 -21679860.55685 +4689 4578 139046393.5639 +4690 4578 24305555.56354 +4691 4578 17343888.84952 +4698 4578 -46373434.23611 +4699 4578 -24305555.56353 +4700 4578 -21679861.11823 +4701 4578 -175918799.4896 +4702 4578 -24305555.36909 +4703 4578 -86719444.24762 +4704 4578 -9282077.505002 +4705 4578 19444444.25638 +4706 4578 -17343888.52033 +4579 4579 781630025.6149 +4580 4579 8.412431954121e-06 +4587 4579 -97222222.20624 +4588 4579 -119197695.4315 +4589 4579 2.831220626831e-07 +4590 4579 -97222221.03956 +4591 4579 -116778839.2437 +4592 4579 5.602836608887e-06 +4593 4579 116666665.4808 +4594 4579 18564155.00998 +4595 4579 5.960464477539e-07 +4677 4579 19444444.25638 +4678 4579 -9282077.505 +4679 4579 -13874999.9393 +4686 4579 -24305555.36909 +4687 4579 -113208178.6284 +4688 4579 -69374999.49133 +4689 4579 24305555.56354 +4690 4579 102586730.4102 +4691 4579 13874999.85143 +4698 4579 -24305555.56353 +4699 4579 -39081501.55875 +4700 4579 -17343750.0057 +4701 4579 -24305555.27187 +4702 4579 -61681981.76159 +4703 4579 -17343749.90781 +4704 4579 29166666.38457 +4705 4579 -9282077.504995 +4706 4579 20812499.90894 +4580 4580 728641235.3813 +4587 4580 -2.890825271606e-06 +4588 4580 3.8743019104e-07 +4589 4580 -46719419.49861 +4590 4580 4.172325134277e-07 +4591 4580 4.887580871582e-06 +4592 4580 -96436338.25295 +4593 4580 2.503395080566e-06 +4594 4580 1.251697540283e-06 +4595 4580 49504413.35998 +4677 4580 17343888.52033 +4678 4580 -20812499.90895 +4679 4580 -24752206.67999 +4686 4580 -21679860.74398 +4687 4580 -69374999.6084 +4688 4580 -84490851.68299 +4689 4580 -17343888.84952 +4690 4580 -13874999.85144 +4691 4580 -65361760.6378 +4698 4580 -21679861.11823 +4699 4580 -17343750.0057 +4700 4580 -36432062.04358 +4701 4580 -86719444.24762 +4702 4580 -17343749.94044 +4703 4580 -110741809.7386 +4704 4580 -26015832.7805 +4705 4580 13874999.9393 +4706 4580 -24752206.67999 +4581 4581 1483949894.094 +4582 4581 7.867813110352e-06 +4583 4581 -5.507469177246e-05 +4584 4581 184322301.8864 +4585 4581 -2.622604370117e-06 +4586 4581 -1.358985900879e-05 +4596 4581 -406796532.3944 +4597 4581 -2.801418304443e-06 +4598 4581 -1.233816146851e-05 +4599 4581 -148365426.1266 +4600 4581 97222222.20624 +4601 4581 -3.308057785034e-06 +4680 4581 -138827443.8752 +4681 4581 2.682209014893e-07 +4682 4581 86719444.4302 +4683 4581 -46373434.23614 +4684 4581 -24305555.56354 +4685 4581 21679861.11823 +4692 4581 222474230.8735 +4693 4581 3.933906555176e-06 +4694 4581 2.622604370117e-05 +4695 4581 8952264.76783 +4696 4581 -1.302361488342e-05 +4697 4581 6.914138793945e-06 +4707 4581 -138827443.8751 +4708 4581 -5.066394805908e-07 +4709 4581 -86719444.43019 +4710 4581 -46373434.23611 +4711 4581 24305555.56353 +4712 4581 -21679861.11823 +4582 4582 1250608048.648 +4583 4582 -1.192092895508e-06 +4584 4582 -3.159046173096e-06 +4585 4582 -185121779.2034 +4586 4582 8.046627044678e-07 +4596 4582 -3.09944152832e-06 +4597 4582 20983010.02827 +4598 4582 -4.768371582031e-07 +4599 4582 97222222.20624 +4600 4582 -119197695.4315 +4601 4582 -7.450580596924e-08 +4680 4582 -2.294778823853e-06 +4681 4582 -31882558.21685 +4682 4582 2.682209014893e-07 +4683 4582 -24305555.56354 +4684 4582 -39081501.55876 +4685 4582 17343750.0057 +4692 4582 4.410743713379e-06 +4693 4582 164138769.4832 +4694 4582 -1.192092895508e-07 +4695 4582 -1.156330108643e-05 +4696 4582 -83408755.55014 +4697 4582 69374999.9886 +4707 4582 -8.344650268555e-07 +4708 4582 -31882558.21681 +4709 4582 -3.278255462646e-07 +4710 4582 24305555.56353 +4711 4582 -39081501.55875 +4712 4582 17343750.00569 +4583 4583 1165825984.246 +4584 4583 -1.382827758789e-05 +4585 4583 1.788139343262e-07 +4586 4583 104791324.3853 +4596 4583 -1.20997428894e-05 +4597 4583 -4.768371582031e-07 +4598 4583 -212506.0825927 +4599 4583 -3.278255462646e-06 +4600 4583 -2.086162567139e-07 +4601 4583 -46719419.49861 +4680 4583 86719444.4302 +4681 4583 3.427267074585e-07 +4682 4583 -99061955.12464 +4683 4583 21679861.11823 +4684 4583 17343750.0057 +4685 4583 -36432062.04359 +4692 4583 2.598762512207e-05 +4693 4583 5.960464477539e-08 +4694 4583 -104578818.0156 +4695 4583 6.973743438721e-06 +4696 4583 69374999.9886 +4697 4583 -72810997.49471 +4707 4583 -86719444.43019 +4708 4583 -2.682209014893e-07 +4709 4583 -99061955.12461 +4710 4583 -21679861.11823 +4711 4583 17343750.00569 +4712 4583 -36432062.04358 +4584 4584 1483949894.094 +4585 4584 7.867813110352e-06 +4586 4584 -5.507469177246e-05 +4587 4584 184322301.8864 +4588 4584 -2.622604370117e-06 +4589 4584 -1.358985900879e-05 +4596 4584 -148365426.1266 +4597 4584 -97222222.20624 +4598 4584 -3.039836883545e-06 +4599 4584 -406796532.3944 +4600 4584 -2.801418304443e-06 +4601 4584 -1.233816146851e-05 +4602 4584 -148365426.1266 +4603 4584 97222222.20624 +4604 4584 -3.308057785034e-06 +4680 4584 -46373434.23613 +4681 4584 24305555.56354 +4682 4584 21679861.11823 +4683 4584 -138827443.8752 +4684 4584 2.682209014893e-07 +4685 4584 86719444.4302 +4686 4584 -46373434.23614 +4687 4584 -24305555.56354 +4688 4584 21679861.11823 +4692 4584 8952264.76783 +4693 4584 9.298324584961e-06 +4694 4584 6.228685379028e-06 +4695 4584 222474230.8735 +4696 4584 3.933906555176e-06 +4697 4584 2.622604370117e-05 +4698 4584 8952264.76783 +4699 4584 -1.302361488342e-05 +4700 4584 6.914138793945e-06 +4707 4584 -46373434.23611 +4708 4584 -24305555.56353 +4709 4584 -21679861.11823 +4710 4584 -138827443.8751 +4711 4584 -5.066394805908e-07 +4712 4584 -86719444.43019 +4713 4584 -46373434.23611 +4714 4584 24305555.56353 +4715 4584 -21679861.11823 +4585 4585 1250608048.648 +4586 4585 -1.192092895508e-06 +4587 4585 -3.159046173096e-06 +4588 4585 -185121779.2034 +4589 4585 8.046627044678e-07 +4596 4585 -97222222.20624 +4597 4585 -119197695.4315 +4598 4585 2.831220626831e-07 +4599 4585 -3.09944152832e-06 +4600 4585 20983010.02827 +4601 4585 -4.768371582031e-07 +4602 4585 97222222.20624 +4603 4585 -119197695.4315 +4604 4585 -7.450580596924e-08 +4680 4585 24305555.56354 +4681 4585 -39081501.55876 +4682 4585 -17343750.00569 +4683 4585 -2.294778823853e-06 +4684 4585 -31882558.21685 +4685 4585 2.682209014893e-07 +4686 4585 -24305555.56354 +4687 4585 -39081501.55876 +4688 4585 17343750.0057 +4692 4585 1.069903373718e-05 +4693 4585 -83408755.55014 +4694 4585 -69374999.9886 +4695 4585 4.410743713379e-06 +4696 4585 164138769.4832 +4697 4585 -1.192092895508e-07 +4698 4585 -1.156330108643e-05 +4699 4585 -83408755.55014 +4700 4585 69374999.9886 +4707 4585 -24305555.56353 +4708 4585 -39081501.55875 +4709 4585 -17343750.0057 +4710 4585 -8.344650268555e-07 +4711 4585 -31882558.21681 +4712 4585 -3.278255462646e-07 +4713 4585 24305555.56353 +4714 4585 -39081501.55875 +4715 4585 17343750.00569 +4586 4586 1165825984.246 +4587 4586 -1.382827758789e-05 +4588 4586 1.788139343262e-07 +4589 4586 104791324.3853 +4596 4586 -2.890825271606e-06 +4597 4586 3.8743019104e-07 +4598 4586 -46719419.49861 +4599 4586 -1.20997428894e-05 +4600 4586 -4.768371582031e-07 +4601 4586 -212506.0825927 +4602 4586 -3.278255462646e-06 +4603 4586 -2.086162567139e-07 +4604 4586 -46719419.49861 +4680 4586 21679861.11823 +4681 4586 -17343750.0057 +4682 4586 -36432062.04359 +4683 4586 86719444.4302 +4684 4586 3.427267074585e-07 +4685 4586 -99061955.12464 +4686 4586 21679861.11823 +4687 4586 17343750.0057 +4688 4586 -36432062.04359 +4692 4586 6.169080734253e-06 +4693 4586 -69374999.9886 +4694 4586 -72810997.49471 +4695 4586 2.598762512207e-05 +4696 4586 5.960464477539e-08 +4697 4586 -104578818.0156 +4698 4586 6.973743438721e-06 +4699 4586 69374999.9886 +4700 4586 -72810997.49471 +4707 4586 -21679861.11823 +4708 4586 -17343750.0057 +4709 4586 -36432062.04358 +4710 4586 -86719444.43019 +4711 4586 -2.682209014893e-07 +4712 4586 -99061955.12461 +4713 4586 -21679861.11823 +4714 4586 17343750.00569 +4715 4586 -36432062.04358 +4587 4587 1483949894.094 +4588 4587 7.867813110352e-06 +4589 4587 -5.507469177246e-05 +4590 4587 184322301.8864 +4591 4587 -2.622604370117e-06 +4592 4587 -1.358985900879e-05 +4599 4587 -148365426.1266 +4600 4587 -97222222.20624 +4601 4587 -3.039836883545e-06 +4602 4587 -406796532.3944 +4603 4587 -2.801418304443e-06 +4604 4587 -1.233816146851e-05 +4605 4587 -148365426.1266 +4606 4587 97222222.20624 +4607 4587 -3.308057785034e-06 +4683 4587 -46373434.23613 +4684 4587 24305555.56354 +4685 4587 21679861.11823 +4686 4587 -138827443.8752 +4687 4587 2.682209014893e-07 +4688 4587 86719444.4302 +4689 4587 -46373434.23614 +4690 4587 -24305555.56354 +4691 4587 21679861.11823 +4695 4587 8952264.76783 +4696 4587 9.298324584961e-06 +4697 4587 6.228685379028e-06 +4698 4587 222474230.8735 +4699 4587 3.933906555176e-06 +4700 4587 2.622604370117e-05 +4701 4587 8952264.76783 +4702 4587 -1.302361488342e-05 +4703 4587 6.914138793945e-06 +4710 4587 -46373434.23611 +4711 4587 -24305555.56353 +4712 4587 -21679861.11823 +4713 4587 -138827443.8751 +4714 4587 -5.066394805908e-07 +4715 4587 -86719444.43019 +4716 4587 -46373434.23611 +4717 4587 24305555.56353 +4718 4587 -21679861.11823 +4588 4588 1250608048.648 +4589 4588 -1.192092895508e-06 +4590 4588 -3.159046173096e-06 +4591 4588 -185121779.2034 +4592 4588 8.046627044678e-07 +4599 4588 -97222222.20624 +4600 4588 -119197695.4315 +4601 4588 2.831220626831e-07 +4602 4588 -3.09944152832e-06 +4603 4588 20983010.02827 +4604 4588 -4.768371582031e-07 +4605 4588 97222222.20624 +4606 4588 -119197695.4315 +4607 4588 -7.450580596924e-08 +4683 4588 24305555.56354 +4684 4588 -39081501.55876 +4685 4588 -17343750.00569 +4686 4588 -2.294778823853e-06 +4687 4588 -31882558.21685 +4688 4588 2.682209014893e-07 +4689 4588 -24305555.56354 +4690 4588 -39081501.55876 +4691 4588 17343750.0057 +4695 4588 1.069903373718e-05 +4696 4588 -83408755.55014 +4697 4588 -69374999.9886 +4698 4588 4.410743713379e-06 +4699 4588 164138769.4832 +4700 4588 -1.192092895508e-07 +4701 4588 -1.156330108643e-05 +4702 4588 -83408755.55014 +4703 4588 69374999.9886 +4710 4588 -24305555.56353 +4711 4588 -39081501.55875 +4712 4588 -17343750.0057 +4713 4588 -8.344650268555e-07 +4714 4588 -31882558.21681 +4715 4588 -3.278255462646e-07 +4716 4588 24305555.56353 +4717 4588 -39081501.55875 +4718 4588 17343750.00569 +4589 4589 1165825984.246 +4590 4589 -1.382827758789e-05 +4591 4589 1.788139343262e-07 +4592 4589 104791324.3853 +4599 4589 -2.890825271606e-06 +4600 4589 3.8743019104e-07 +4601 4589 -46719419.49861 +4602 4589 -1.20997428894e-05 +4603 4589 -4.768371582031e-07 +4604 4589 -212506.0825927 +4605 4589 -3.278255462646e-06 +4606 4589 -2.086162567139e-07 +4607 4589 -46719419.49861 +4683 4589 21679861.11823 +4684 4589 -17343750.0057 +4685 4589 -36432062.04359 +4686 4589 86719444.4302 +4687 4589 3.427267074585e-07 +4688 4589 -99061955.12464 +4689 4589 21679861.11823 +4690 4589 17343750.0057 +4691 4589 -36432062.04359 +4695 4589 6.169080734253e-06 +4696 4589 -69374999.9886 +4697 4589 -72810997.49471 +4698 4589 2.598762512207e-05 +4699 4589 5.960464477539e-08 +4700 4589 -104578818.0156 +4701 4589 6.973743438721e-06 +4702 4589 69374999.9886 +4703 4589 -72810997.49471 +4710 4589 -21679861.11823 +4711 4589 -17343750.0057 +4712 4589 -36432062.04358 +4713 4589 -86719444.43019 +4714 4589 -2.682209014893e-07 +4715 4589 -99061955.12461 +4716 4589 -21679861.11823 +4717 4589 17343750.00569 +4718 4589 -36432062.04358 +4590 4590 1632315315.374 +4591 4590 97222220.26178 +4592 4590 -4.172325134277e-05 +4593 4590 17392720.97666 +4594 4590 -97222221.42845 +4595 4590 -2.145767211914e-06 +4602 4590 -148365426.1266 +4603 4590 -97222222.20624 +4604 4590 -3.039836883545e-06 +4605 4590 -406796532.3944 +4606 4590 -2.801418304443e-06 +4607 4590 -1.233816146851e-05 +4608 4590 -148365426.1266 +4609 4590 97222222.20624 +4610 4590 -3.308057785034e-06 +4686 4590 -46373434.23613 +4687 4590 24305555.56354 +4688 4590 21679861.11823 +4689 4590 -175918799.4897 +4690 4590 -24305555.27186 +4691 4590 86719444.24762 +4698 4590 8952264.76783 +4699 4590 9.298324584961e-06 +4700 4590 6.228685379028e-06 +4701 4590 268847663.9159 +4702 4590 24305555.07742 +4703 4590 0.03653132915497 +4704 4590 -28139091.37671 +4705 4590 -24305555.36909 +4706 4590 21679860.74398 +4713 4590 -46373434.23611 +4714 4590 -24305555.56353 +4715 4590 -21679861.11823 +4716 4590 -138827443.8751 +4717 4590 -5.066394805908e-07 +4718 4590 -86719444.43019 +4719 4590 -46373434.23611 +4720 4590 24305555.56353 +4721 4590 -21679861.11823 +4591 4591 1369805740.108 +4592 4591 -2.145767211914e-06 +4593 4591 -97222221.03956 +4594 4591 -322883627.8625 +4595 4591 4.798173904419e-06 +4602 4591 -97222222.20624 +4603 4591 -119197695.4315 +4604 4591 2.831220626831e-07 +4605 4591 -3.09944152832e-06 +4606 4591 20983010.02827 +4607 4591 -4.768371582031e-07 +4608 4591 97222222.20624 +4609 4591 -119197695.4315 +4610 4591 -7.450580596924e-08 +4686 4591 24305555.56354 +4687 4591 -39081501.55876 +4688 4591 -17343750.00569 +4689 4591 -24305555.36908 +4690 4591 -61681981.7616 +4691 4591 17343749.94043 +4698 4591 1.069903373718e-05 +4699 4591 -83408755.55014 +4700 4591 -69374999.9886 +4701 4591 24305555.07742 +4702 4591 203220270.0671 +4703 4591 0.02920919656754 +4704 4591 -24305555.27186 +4705 4591 -113208178.6284 +4706 4591 69374999.6084 +4713 4591 -24305555.56353 +4714 4591 -39081501.55875 +4715 4591 -17343750.0057 +4716 4591 -8.344650268555e-07 +4717 4591 -31882558.21681 +4718 4591 -3.278255462646e-07 +4719 4591 24305555.56353 +4720 4591 -39081501.55875 +4721 4591 17343750.00569 +4592 4592 1212545401.289 +4593 4592 -1.788139343262e-06 +4594 4592 3.75509262085e-06 +4595 4592 8567490.576108 +4602 4592 -2.890825271606e-06 +4603 4592 3.8743019104e-07 +4604 4592 -46719419.49861 +4605 4592 -1.20997428894e-05 +4606 4592 -4.768371582031e-07 +4607 4592 -212506.0825927 +4608 4592 -3.278255462646e-06 +4609 4592 -2.086162567139e-07 +4610 4592 -46719419.49861 +4686 4592 21679861.11823 +4687 4592 -17343750.0057 +4688 4592 -36432062.04359 +4689 4592 86719444.24762 +4690 4592 17343749.9078 +4691 4592 -110741809.7386 +4698 4592 6.169080734253e-06 +4699 4592 -69374999.9886 +4700 4592 -72810997.49471 +4701 4592 -0.03649973869324 +4702 4592 -0.02921465039253 +4703 4592 -68146756.53808 +4704 4592 21679860.55685 +4705 4592 69374999.49133 +4706 4592 -84490851.68298 +4713 4592 -21679861.11823 +4714 4592 -17343750.0057 +4715 4592 -36432062.04358 +4716 4592 -86719444.43019 +4717 4592 -2.682209014893e-07 +4718 4592 -99061955.12461 +4719 4592 -21679861.11823 +4720 4592 17343750.00569 +4721 4592 -36432062.04358 +4593 4593 927468678.158 +4594 4593 97222222.20623 +4595 4593 -8.106231689453e-06 +4605 4593 -148365426.1266 +4606 4593 -97222222.20624 +4607 4593 -3.039836883545e-06 +4608 4593 -573726109.9308 +4609 4593 -97222221.42845 +4610 4593 8.940696716309e-07 +4611 4593 18564155.00999 +4612 4593 77777776.9872 +4613 4593 2.861022949219e-06 +4689 4593 -9282077.50499 +4690 4593 29166666.38457 +4691 4593 26015832.78049 +4701 4593 -28139091.37673 +4702 4593 -24305555.27187 +4703 4593 -21679860.55685 +4704 4593 139046393.5639 +4705 4593 24305555.56354 +4706 4593 17343888.84952 +4716 4593 -46373434.23611 +4717 4593 -24305555.56353 +4718 4593 -21679861.11823 +4719 4593 -175918799.4896 +4720 4593 -24305555.36909 +4721 4593 -86719444.24762 +4722 4593 -9282077.505002 +4723 4593 19444444.25638 +4724 4593 -17343888.52033 +4594 4594 781630025.6149 +4595 4594 8.412431954121e-06 +4605 4594 -97222222.20624 +4606 4594 -119197695.4315 +4607 4594 2.831220626831e-07 +4608 4594 -97222221.03956 +4609 4594 -116778839.2437 +4610 4594 5.602836608887e-06 +4611 4594 116666665.4808 +4612 4594 18564155.00998 +4613 4594 5.960464477539e-07 +4689 4594 19444444.25638 +4690 4594 -9282077.505 +4691 4594 -13874999.9393 +4701 4594 -24305555.36909 +4702 4594 -113208178.6284 +4703 4594 -69374999.49133 +4704 4594 24305555.56354 +4705 4594 102586730.4102 +4706 4594 13874999.85143 +4716 4594 -24305555.56353 +4717 4594 -39081501.55875 +4718 4594 -17343750.0057 +4719 4594 -24305555.27187 +4720 4594 -61681981.76159 +4721 4594 -17343749.90781 +4722 4594 29166666.38457 +4723 4594 -9282077.504995 +4724 4594 20812499.90894 +4595 4595 728641235.3813 +4605 4595 -2.890825271606e-06 +4606 4595 3.8743019104e-07 +4607 4595 -46719419.49861 +4608 4595 4.172325134277e-07 +4609 4595 4.887580871582e-06 +4610 4595 -96436338.25295 +4611 4595 2.503395080566e-06 +4612 4595 1.251697540283e-06 +4613 4595 49504413.35998 +4689 4595 17343888.52033 +4690 4595 -20812499.90895 +4691 4595 -24752206.67999 +4701 4595 -21679860.74398 +4702 4595 -69374999.6084 +4703 4595 -84490851.68299 +4704 4595 -17343888.84952 +4705 4595 -13874999.85144 +4706 4595 -65361760.6378 +4716 4595 -21679861.11823 +4717 4595 -17343750.0057 +4718 4595 -36432062.04358 +4719 4595 -86719444.24762 +4720 4595 -17343749.94044 +4721 4595 -110741809.7386 +4722 4595 -26015832.7805 +4723 4595 13874999.9393 +4724 4595 -24752206.67999 +4596 4596 1483949894.094 +4597 4596 7.867813110352e-06 +4598 4596 -5.507469177246e-05 +4599 4596 184322301.8864 +4600 4596 -2.622604370117e-06 +4601 4596 -1.358985900879e-05 +4614 4596 -406796532.3944 +4615 4596 -2.801418304443e-06 +4616 4596 -1.233816146851e-05 +4617 4596 -148365426.1266 +4618 4596 97222222.20624 +4619 4596 -3.308057785034e-06 +4692 4596 -138827443.8752 +4693 4596 2.682209014893e-07 +4694 4596 86719444.4302 +4695 4596 -46373434.23614 +4696 4596 -24305555.56354 +4697 4596 21679861.11823 +4707 4596 222474230.8735 +4708 4596 3.933906555176e-06 +4709 4596 2.622604370117e-05 +4710 4596 8952264.76783 +4711 4596 -1.302361488342e-05 +4712 4596 6.914138793945e-06 +4725 4596 -138827443.8751 +4726 4596 -5.066394805908e-07 +4727 4596 -86719444.43019 +4728 4596 -46373434.23611 +4729 4596 24305555.56353 +4730 4596 -21679861.11823 +4597 4597 1250608048.648 +4598 4597 -1.192092895508e-06 +4599 4597 -3.159046173096e-06 +4600 4597 -185121779.2034 +4601 4597 8.046627044678e-07 +4614 4597 -3.09944152832e-06 +4615 4597 20983010.02827 +4616 4597 -4.768371582031e-07 +4617 4597 97222222.20624 +4618 4597 -119197695.4315 +4619 4597 -7.450580596924e-08 +4692 4597 -2.294778823853e-06 +4693 4597 -31882558.21685 +4694 4597 2.682209014893e-07 +4695 4597 -24305555.56354 +4696 4597 -39081501.55876 +4697 4597 17343750.0057 +4707 4597 4.410743713379e-06 +4708 4597 164138769.4832 +4709 4597 -1.192092895508e-07 +4710 4597 -1.156330108643e-05 +4711 4597 -83408755.55014 +4712 4597 69374999.9886 +4725 4597 -8.344650268555e-07 +4726 4597 -31882558.21681 +4727 4597 -3.278255462646e-07 +4728 4597 24305555.56353 +4729 4597 -39081501.55875 +4730 4597 17343750.00569 +4598 4598 1165825984.246 +4599 4598 -1.382827758789e-05 +4600 4598 1.788139343262e-07 +4601 4598 104791324.3853 +4614 4598 -1.20997428894e-05 +4615 4598 -4.768371582031e-07 +4616 4598 -212506.0825927 +4617 4598 -3.278255462646e-06 +4618 4598 -2.086162567139e-07 +4619 4598 -46719419.49861 +4692 4598 86719444.4302 +4693 4598 3.427267074585e-07 +4694 4598 -99061955.12464 +4695 4598 21679861.11823 +4696 4598 17343750.0057 +4697 4598 -36432062.04359 +4707 4598 2.598762512207e-05 +4708 4598 5.960464477539e-08 +4709 4598 -104578818.0156 +4710 4598 6.973743438721e-06 +4711 4598 69374999.9886 +4712 4598 -72810997.49471 +4725 4598 -86719444.43019 +4726 4598 -2.682209014893e-07 +4727 4598 -99061955.12461 +4728 4598 -21679861.11823 +4729 4598 17343750.00569 +4730 4598 -36432062.04358 +4599 4599 1483949894.094 +4600 4599 7.867813110352e-06 +4601 4599 -5.507469177246e-05 +4602 4599 184322301.8864 +4603 4599 -2.622604370117e-06 +4604 4599 -1.358985900879e-05 +4614 4599 -148365426.1266 +4615 4599 -97222222.20624 +4616 4599 -3.039836883545e-06 +4617 4599 -406796532.3944 +4618 4599 -2.801418304443e-06 +4619 4599 -1.233816146851e-05 +4620 4599 -148365426.1266 +4621 4599 97222222.20624 +4622 4599 -3.308057785034e-06 +4692 4599 -46373434.23613 +4693 4599 24305555.56354 +4694 4599 21679861.11823 +4695 4599 -138827443.8752 +4696 4599 2.682209014893e-07 +4697 4599 86719444.4302 +4698 4599 -46373434.23614 +4699 4599 -24305555.56354 +4700 4599 21679861.11823 +4707 4599 8952264.76783 +4708 4599 9.298324584961e-06 +4709 4599 6.228685379028e-06 +4710 4599 222474230.8735 +4711 4599 3.933906555176e-06 +4712 4599 2.622604370117e-05 +4713 4599 8952264.76783 +4714 4599 -1.302361488342e-05 +4715 4599 6.914138793945e-06 +4725 4599 -46373434.23611 +4726 4599 -24305555.56353 +4727 4599 -21679861.11823 +4728 4599 -138827443.8751 +4729 4599 -5.066394805908e-07 +4730 4599 -86719444.43019 +4731 4599 -46373434.23611 +4732 4599 24305555.56353 +4733 4599 -21679861.11823 +4600 4600 1250608048.648 +4601 4600 -1.192092895508e-06 +4602 4600 -3.159046173096e-06 +4603 4600 -185121779.2034 +4604 4600 8.046627044678e-07 +4614 4600 -97222222.20624 +4615 4600 -119197695.4315 +4616 4600 2.831220626831e-07 +4617 4600 -3.09944152832e-06 +4618 4600 20983010.02827 +4619 4600 -4.768371582031e-07 +4620 4600 97222222.20624 +4621 4600 -119197695.4315 +4622 4600 -7.450580596924e-08 +4692 4600 24305555.56354 +4693 4600 -39081501.55876 +4694 4600 -17343750.00569 +4695 4600 -2.294778823853e-06 +4696 4600 -31882558.21685 +4697 4600 2.682209014893e-07 +4698 4600 -24305555.56354 +4699 4600 -39081501.55876 +4700 4600 17343750.0057 +4707 4600 1.069903373718e-05 +4708 4600 -83408755.55014 +4709 4600 -69374999.9886 +4710 4600 4.410743713379e-06 +4711 4600 164138769.4832 +4712 4600 -1.192092895508e-07 +4713 4600 -1.156330108643e-05 +4714 4600 -83408755.55014 +4715 4600 69374999.9886 +4725 4600 -24305555.56353 +4726 4600 -39081501.55875 +4727 4600 -17343750.0057 +4728 4600 -8.344650268555e-07 +4729 4600 -31882558.21681 +4730 4600 -3.278255462646e-07 +4731 4600 24305555.56353 +4732 4600 -39081501.55875 +4733 4600 17343750.00569 +4601 4601 1165825984.246 +4602 4601 -1.382827758789e-05 +4603 4601 1.788139343262e-07 +4604 4601 104791324.3853 +4614 4601 -2.890825271606e-06 +4615 4601 3.8743019104e-07 +4616 4601 -46719419.49861 +4617 4601 -1.20997428894e-05 +4618 4601 -4.768371582031e-07 +4619 4601 -212506.0825927 +4620 4601 -3.278255462646e-06 +4621 4601 -2.086162567139e-07 +4622 4601 -46719419.49861 +4692 4601 21679861.11823 +4693 4601 -17343750.0057 +4694 4601 -36432062.04359 +4695 4601 86719444.4302 +4696 4601 3.427267074585e-07 +4697 4601 -99061955.12464 +4698 4601 21679861.11823 +4699 4601 17343750.0057 +4700 4601 -36432062.04359 +4707 4601 6.169080734253e-06 +4708 4601 -69374999.9886 +4709 4601 -72810997.49471 +4710 4601 2.598762512207e-05 +4711 4601 5.960464477539e-08 +4712 4601 -104578818.0156 +4713 4601 6.973743438721e-06 +4714 4601 69374999.9886 +4715 4601 -72810997.49471 +4725 4601 -21679861.11823 +4726 4601 -17343750.0057 +4727 4601 -36432062.04358 +4728 4601 -86719444.43019 +4729 4601 -2.682209014893e-07 +4730 4601 -99061955.12461 +4731 4601 -21679861.11823 +4732 4601 17343750.00569 +4733 4601 -36432062.04358 +4602 4602 1483949894.094 +4603 4602 7.867813110352e-06 +4604 4602 -5.507469177246e-05 +4605 4602 184322301.8864 +4606 4602 -2.622604370117e-06 +4607 4602 -1.358985900879e-05 +4617 4602 -148365426.1266 +4618 4602 -97222222.20624 +4619 4602 -3.039836883545e-06 +4620 4602 -406796532.3944 +4621 4602 -2.801418304443e-06 +4622 4602 -1.233816146851e-05 +4623 4602 -148365426.1266 +4624 4602 97222222.20624 +4625 4602 -3.308057785034e-06 +4695 4602 -46373434.23613 +4696 4602 24305555.56354 +4697 4602 21679861.11823 +4698 4602 -138827443.8752 +4699 4602 2.682209014893e-07 +4700 4602 86719444.4302 +4701 4602 -46373434.23614 +4702 4602 -24305555.56354 +4703 4602 21679861.11823 +4710 4602 8952264.76783 +4711 4602 9.298324584961e-06 +4712 4602 6.228685379028e-06 +4713 4602 222474230.8735 +4714 4602 3.933906555176e-06 +4715 4602 2.622604370117e-05 +4716 4602 8952264.76783 +4717 4602 -1.302361488342e-05 +4718 4602 6.914138793945e-06 +4728 4602 -46373434.23611 +4729 4602 -24305555.56353 +4730 4602 -21679861.11823 +4731 4602 -138827443.8751 +4732 4602 -5.066394805908e-07 +4733 4602 -86719444.43019 +4734 4602 -46373434.23611 +4735 4602 24305555.56353 +4736 4602 -21679861.11823 +4603 4603 1250608048.648 +4604 4603 -1.192092895508e-06 +4605 4603 -3.159046173096e-06 +4606 4603 -185121779.2034 +4607 4603 8.046627044678e-07 +4617 4603 -97222222.20624 +4618 4603 -119197695.4315 +4619 4603 2.831220626831e-07 +4620 4603 -3.09944152832e-06 +4621 4603 20983010.02827 +4622 4603 -4.768371582031e-07 +4623 4603 97222222.20624 +4624 4603 -119197695.4315 +4625 4603 -7.450580596924e-08 +4695 4603 24305555.56354 +4696 4603 -39081501.55876 +4697 4603 -17343750.00569 +4698 4603 -2.294778823853e-06 +4699 4603 -31882558.21685 +4700 4603 2.682209014893e-07 +4701 4603 -24305555.56354 +4702 4603 -39081501.55876 +4703 4603 17343750.0057 +4710 4603 1.069903373718e-05 +4711 4603 -83408755.55014 +4712 4603 -69374999.9886 +4713 4603 4.410743713379e-06 +4714 4603 164138769.4832 +4715 4603 -1.192092895508e-07 +4716 4603 -1.156330108643e-05 +4717 4603 -83408755.55014 +4718 4603 69374999.9886 +4728 4603 -24305555.56353 +4729 4603 -39081501.55875 +4730 4603 -17343750.0057 +4731 4603 -8.344650268555e-07 +4732 4603 -31882558.21681 +4733 4603 -3.278255462646e-07 +4734 4603 24305555.56353 +4735 4603 -39081501.55875 +4736 4603 17343750.00569 +4604 4604 1165825984.246 +4605 4604 -1.382827758789e-05 +4606 4604 1.788139343262e-07 +4607 4604 104791324.3853 +4617 4604 -2.890825271606e-06 +4618 4604 3.8743019104e-07 +4619 4604 -46719419.49861 +4620 4604 -1.20997428894e-05 +4621 4604 -4.768371582031e-07 +4622 4604 -212506.0825927 +4623 4604 -3.278255462646e-06 +4624 4604 -2.086162567139e-07 +4625 4604 -46719419.49861 +4695 4604 21679861.11823 +4696 4604 -17343750.0057 +4697 4604 -36432062.04359 +4698 4604 86719444.4302 +4699 4604 3.427267074585e-07 +4700 4604 -99061955.12464 +4701 4604 21679861.11823 +4702 4604 17343750.0057 +4703 4604 -36432062.04359 +4710 4604 6.169080734253e-06 +4711 4604 -69374999.9886 +4712 4604 -72810997.49471 +4713 4604 2.598762512207e-05 +4714 4604 5.960464477539e-08 +4715 4604 -104578818.0156 +4716 4604 6.973743438721e-06 +4717 4604 69374999.9886 +4718 4604 -72810997.49471 +4728 4604 -21679861.11823 +4729 4604 -17343750.0057 +4730 4604 -36432062.04358 +4731 4604 -86719444.43019 +4732 4604 -2.682209014893e-07 +4733 4604 -99061955.12461 +4734 4604 -21679861.11823 +4735 4604 17343750.00569 +4736 4604 -36432062.04358 +4605 4605 1483949894.094 +4606 4605 7.867813110352e-06 +4607 4605 -5.507469177246e-05 +4608 4605 184322301.8864 +4609 4605 -2.622604370117e-06 +4610 4605 -1.358985900879e-05 +4620 4605 -148365426.1266 +4621 4605 -97222222.20624 +4622 4605 -3.039836883545e-06 +4623 4605 -406796532.3944 +4624 4605 -2.801418304443e-06 +4625 4605 -1.233816146851e-05 +4626 4605 -148365426.1266 +4627 4605 97222222.20624 +4628 4605 -3.308057785034e-06 +4698 4605 -46373434.23613 +4699 4605 24305555.56354 +4700 4605 21679861.11823 +4701 4605 -138827443.8752 +4702 4605 2.682209014893e-07 +4703 4605 86719444.4302 +4704 4605 -46373434.23614 +4705 4605 -24305555.56354 +4706 4605 21679861.11823 +4713 4605 8952264.76783 +4714 4605 9.298324584961e-06 +4715 4605 6.228685379028e-06 +4716 4605 222474230.8735 +4717 4605 3.933906555176e-06 +4718 4605 2.622604370117e-05 +4719 4605 8952264.76783 +4720 4605 -1.302361488342e-05 +4721 4605 6.914138793945e-06 +4731 4605 -46373434.23611 +4732 4605 -24305555.56353 +4733 4605 -21679861.11823 +4734 4605 -138827443.8751 +4735 4605 -5.066394805908e-07 +4736 4605 -86719444.43019 +4737 4605 -46373434.23611 +4738 4605 24305555.56353 +4739 4605 -21679861.11823 +4606 4606 1250608048.648 +4607 4606 -1.192092895508e-06 +4608 4606 -3.159046173096e-06 +4609 4606 -185121779.2034 +4610 4606 8.046627044678e-07 +4620 4606 -97222222.20624 +4621 4606 -119197695.4315 +4622 4606 2.831220626831e-07 +4623 4606 -3.09944152832e-06 +4624 4606 20983010.02827 +4625 4606 -4.768371582031e-07 +4626 4606 97222222.20624 +4627 4606 -119197695.4315 +4628 4606 -7.450580596924e-08 +4698 4606 24305555.56354 +4699 4606 -39081501.55876 +4700 4606 -17343750.00569 +4701 4606 -2.294778823853e-06 +4702 4606 -31882558.21685 +4703 4606 2.682209014893e-07 +4704 4606 -24305555.56354 +4705 4606 -39081501.55876 +4706 4606 17343750.0057 +4713 4606 1.069903373718e-05 +4714 4606 -83408755.55014 +4715 4606 -69374999.9886 +4716 4606 4.410743713379e-06 +4717 4606 164138769.4832 +4718 4606 -1.192092895508e-07 +4719 4606 -1.156330108643e-05 +4720 4606 -83408755.55014 +4721 4606 69374999.9886 +4731 4606 -24305555.56353 +4732 4606 -39081501.55875 +4733 4606 -17343750.0057 +4734 4606 -8.344650268555e-07 +4735 4606 -31882558.21681 +4736 4606 -3.278255462646e-07 +4737 4606 24305555.56353 +4738 4606 -39081501.55875 +4739 4606 17343750.00569 +4607 4607 1165825984.246 +4608 4607 -1.382827758789e-05 +4609 4607 1.788139343262e-07 +4610 4607 104791324.3853 +4620 4607 -2.890825271606e-06 +4621 4607 3.8743019104e-07 +4622 4607 -46719419.49861 +4623 4607 -1.20997428894e-05 +4624 4607 -4.768371582031e-07 +4625 4607 -212506.0825927 +4626 4607 -3.278255462646e-06 +4627 4607 -2.086162567139e-07 +4628 4607 -46719419.49861 +4698 4607 21679861.11823 +4699 4607 -17343750.0057 +4700 4607 -36432062.04359 +4701 4607 86719444.4302 +4702 4607 3.427267074585e-07 +4703 4607 -99061955.12464 +4704 4607 21679861.11823 +4705 4607 17343750.0057 +4706 4607 -36432062.04359 +4713 4607 6.169080734253e-06 +4714 4607 -69374999.9886 +4715 4607 -72810997.49471 +4716 4607 2.598762512207e-05 +4717 4607 5.960464477539e-08 +4718 4607 -104578818.0156 +4719 4607 6.973743438721e-06 +4720 4607 69374999.9886 +4721 4607 -72810997.49471 +4731 4607 -21679861.11823 +4732 4607 -17343750.0057 +4733 4607 -36432062.04358 +4734 4607 -86719444.43019 +4735 4607 -2.682209014893e-07 +4736 4607 -99061955.12461 +4737 4607 -21679861.11823 +4738 4607 17343750.00569 +4739 4607 -36432062.04358 +4608 4608 1632315315.374 +4609 4608 97222220.26178 +4610 4608 -4.172325134277e-05 +4611 4608 17392720.97666 +4612 4608 -97222221.42845 +4613 4608 -2.145767211914e-06 +4623 4608 -148365426.1266 +4624 4608 -97222222.20624 +4625 4608 -3.039836883545e-06 +4626 4608 -406796532.3944 +4627 4608 -2.801418304443e-06 +4628 4608 -1.233816146851e-05 +4629 4608 -148365426.1266 +4630 4608 97222222.20624 +4631 4608 -3.308057785034e-06 +4701 4608 -46373434.23613 +4702 4608 24305555.56354 +4703 4608 21679861.11823 +4704 4608 -175918799.4897 +4705 4608 -24305555.27186 +4706 4608 86719444.24762 +4716 4608 8952264.76783 +4717 4608 9.298324584961e-06 +4718 4608 6.228685379028e-06 +4719 4608 268847663.9159 +4720 4608 24305555.07742 +4721 4608 0.03653132915497 +4722 4608 -28139091.37671 +4723 4608 -24305555.36909 +4724 4608 21679860.74398 +4734 4608 -46373434.23611 +4735 4608 -24305555.56353 +4736 4608 -21679861.11823 +4737 4608 -138827443.8751 +4738 4608 -5.066394805908e-07 +4739 4608 -86719444.43019 +4740 4608 -46373434.23611 +4741 4608 24305555.56353 +4742 4608 -21679861.11823 +4609 4609 1369805740.108 +4610 4609 -2.145767211914e-06 +4611 4609 -97222221.03956 +4612 4609 -322883627.8625 +4613 4609 4.798173904419e-06 +4623 4609 -97222222.20624 +4624 4609 -119197695.4315 +4625 4609 2.831220626831e-07 +4626 4609 -3.09944152832e-06 +4627 4609 20983010.02827 +4628 4609 -4.768371582031e-07 +4629 4609 97222222.20624 +4630 4609 -119197695.4315 +4631 4609 -7.450580596924e-08 +4701 4609 24305555.56354 +4702 4609 -39081501.55876 +4703 4609 -17343750.00569 +4704 4609 -24305555.36908 +4705 4609 -61681981.7616 +4706 4609 17343749.94043 +4716 4609 1.069903373718e-05 +4717 4609 -83408755.55014 +4718 4609 -69374999.9886 +4719 4609 24305555.07742 +4720 4609 203220270.0671 +4721 4609 0.02920919656754 +4722 4609 -24305555.27186 +4723 4609 -113208178.6284 +4724 4609 69374999.6084 +4734 4609 -24305555.56353 +4735 4609 -39081501.55875 +4736 4609 -17343750.0057 +4737 4609 -8.344650268555e-07 +4738 4609 -31882558.21681 +4739 4609 -3.278255462646e-07 +4740 4609 24305555.56353 +4741 4609 -39081501.55875 +4742 4609 17343750.00569 +4610 4610 1212545401.289 +4611 4610 -1.788139343262e-06 +4612 4610 3.75509262085e-06 +4613 4610 8567490.576108 +4623 4610 -2.890825271606e-06 +4624 4610 3.8743019104e-07 +4625 4610 -46719419.49861 +4626 4610 -1.20997428894e-05 +4627 4610 -4.768371582031e-07 +4628 4610 -212506.0825927 +4629 4610 -3.278255462646e-06 +4630 4610 -2.086162567139e-07 +4631 4610 -46719419.49861 +4701 4610 21679861.11823 +4702 4610 -17343750.0057 +4703 4610 -36432062.04359 +4704 4610 86719444.24762 +4705 4610 17343749.9078 +4706 4610 -110741809.7386 +4716 4610 6.169080734253e-06 +4717 4610 -69374999.9886 +4718 4610 -72810997.49471 +4719 4610 -0.03649973869324 +4720 4610 -0.02921465039253 +4721 4610 -68146756.53808 +4722 4610 21679860.55685 +4723 4610 69374999.49133 +4724 4610 -84490851.68298 +4734 4610 -21679861.11823 +4735 4610 -17343750.0057 +4736 4610 -36432062.04358 +4737 4610 -86719444.43019 +4738 4610 -2.682209014893e-07 +4739 4610 -99061955.12461 +4740 4610 -21679861.11823 +4741 4610 17343750.00569 +4742 4610 -36432062.04358 +4611 4611 944226635.8558 +4612 4611 104813146.3867 +4613 4611 -1.025199890137e-05 +4626 4611 -148365426.1266 +4627 4611 -97222222.20624 +4628 4611 -3.039836883545e-06 +4629 4611 -591818040.3847 +4630 4611 -104813145.6089 +4631 4611 -7.987022399902e-06 +4632 4611 22795227.75344 +4633 4611 77777776.98724 +4634 4611 -4.768371582031e-07 +4704 4611 -9282077.50499 +4705 4611 29166666.38457 +4706 4611 26015832.78049 +4719 4611 -28139091.37673 +4720 4611 -24305555.27187 +4721 4611 -21679860.55685 +4722 4611 142149470.4917 +4723 4611 26203286.60958 +4724 4611 17682222.18138 +4737 4611 -46373434.23611 +4738 4611 -24305555.56353 +4739 4611 -21679861.11823 +4740 4611 -180984988.3575 +4741 4611 -26203286.41514 +4742 4611 -88411110.90688 +4743 4611 -8767515.55854 +4744 4611 19444444.25639 +4745 4611 -18020555.17262 +4612 4612 789133337.2837 +4613 4612 2.71201133728e-06 +4626 4612 -97222222.20624 +4627 4612 -119197695.4315 +4628 4612 2.831220626831e-07 +4629 4612 -104813145.22 +4630 4612 -131460786.5969 +4631 4612 -2.384185791016e-07 +4632 4612 116666665.4809 +4633 4612 28639890.68178 +4634 4612 3.576278686523e-07 +4704 4612 19444444.25638 +4705 4612 -9282077.505 +4706 4612 -13874999.9393 +4719 4612 -24305555.36909 +4720 4612 -113208178.6284 +4721 4612 -69374999.49133 +4722 4612 26203286.60958 +4723 4612 103376145.8296 +4724 4612 14145833.18358 +4737 4612 -24305555.56353 +4738 4612 -39081501.55875 +4739 4612 -17343750.0057 +4740 4612 -26203286.31792 +4741 4612 -65895674.85386 +4742 4612 -18697916.56855 +4743 4612 29166666.38459 +4744 4612 -7306349.825737 +4745 4612 20270833.25379 +4613 4613 738330627.0228 +4626 4613 -2.890825271606e-06 +4627 4613 3.8743019104e-07 +4628 4613 -46719419.49861 +4629 4613 -8.523464202881e-06 +4630 4613 5.960464477539e-08 +4631 4613 -103838327.6491 +4632 4613 -8.344650268555e-07 +4633 4613 2.384185791016e-07 +4634 4613 54942611.08085 +4704 4613 17343888.52033 +4705 4613 -20812499.90895 +4706 4613 -24752206.67999 +4719 4613 -21679860.74398 +4720 4613 -69374999.6084 +4721 4613 -84490851.68299 +4722 4613 -17682222.18137 +4723 4613 -14145833.18359 +4724 4613 -65836512.72293 +4737 4613 -21679861.11823 +4738 4613 -17343750.0057 +4739 4613 -36432062.04358 +4740 4613 -88411110.90688 +4741 4613 -18697916.60118 +4742 4613 -114040857.0942 +4743 4613 -27030832.75893 +4744 4613 13062499.95656 +4745 4613 -24841207.22224 +4614 4614 1483949894.094 +4615 4614 7.867813110352e-06 +4616 4614 -5.507469177246e-05 +4617 4614 184322301.8864 +4618 4614 -2.622604370117e-06 +4619 4614 -1.358985900879e-05 +4635 4614 -406796532.3944 +4636 4614 -2.801418304443e-06 +4637 4614 -1.233816146851e-05 +4638 4614 -148365426.1266 +4639 4614 97222222.20624 +4640 4614 -3.308057785034e-06 +4707 4614 -138827443.8752 +4708 4614 2.682209014893e-07 +4709 4614 86719444.4302 +4710 4614 -46373434.23614 +4711 4614 -24305555.56354 +4712 4614 21679861.11823 +4725 4614 222474230.8735 +4726 4614 3.933906555176e-06 +4727 4614 2.622604370117e-05 +4728 4614 8952264.76783 +4729 4614 -1.302361488342e-05 +4730 4614 6.914138793945e-06 +4746 4614 -138827443.8751 +4747 4614 -5.066394805908e-07 +4748 4614 -86719444.43019 +4749 4614 -46373434.23611 +4750 4614 24305555.56353 +4751 4614 -21679861.11823 +4615 4615 1250608048.648 +4616 4615 -1.192092895508e-06 +4617 4615 -3.159046173096e-06 +4618 4615 -185121779.2034 +4619 4615 8.046627044678e-07 +4635 4615 -3.09944152832e-06 +4636 4615 20983010.02827 +4637 4615 -4.768371582031e-07 +4638 4615 97222222.20624 +4639 4615 -119197695.4315 +4640 4615 -7.450580596924e-08 +4707 4615 -2.294778823853e-06 +4708 4615 -31882558.21685 +4709 4615 2.682209014893e-07 +4710 4615 -24305555.56354 +4711 4615 -39081501.55876 +4712 4615 17343750.0057 +4725 4615 4.410743713379e-06 +4726 4615 164138769.4832 +4727 4615 -1.192092895508e-07 +4728 4615 -1.156330108643e-05 +4729 4615 -83408755.55014 +4730 4615 69374999.9886 +4746 4615 -8.344650268555e-07 +4747 4615 -31882558.21681 +4748 4615 -3.278255462646e-07 +4749 4615 24305555.56353 +4750 4615 -39081501.55875 +4751 4615 17343750.00569 +4616 4616 1165825984.246 +4617 4616 -1.382827758789e-05 +4618 4616 1.788139343262e-07 +4619 4616 104791324.3853 +4635 4616 -1.20997428894e-05 +4636 4616 -4.768371582031e-07 +4637 4616 -212506.0825927 +4638 4616 -3.278255462646e-06 +4639 4616 -2.086162567139e-07 +4640 4616 -46719419.49861 +4707 4616 86719444.4302 +4708 4616 3.427267074585e-07 +4709 4616 -99061955.12464 +4710 4616 21679861.11823 +4711 4616 17343750.0057 +4712 4616 -36432062.04359 +4725 4616 2.598762512207e-05 +4726 4616 5.960464477539e-08 +4727 4616 -104578818.0156 +4728 4616 6.973743438721e-06 +4729 4616 69374999.9886 +4730 4616 -72810997.49471 +4746 4616 -86719444.43019 +4747 4616 -2.682209014893e-07 +4748 4616 -99061955.12461 +4749 4616 -21679861.11823 +4750 4616 17343750.00569 +4751 4616 -36432062.04358 +4617 4617 1483949894.094 +4618 4617 7.867813110352e-06 +4619 4617 -5.507469177246e-05 +4620 4617 184322301.8864 +4621 4617 -2.622604370117e-06 +4622 4617 -1.358985900879e-05 +4635 4617 -148365426.1266 +4636 4617 -97222222.20624 +4637 4617 -3.039836883545e-06 +4638 4617 -406796532.3944 +4639 4617 -2.801418304443e-06 +4640 4617 -1.233816146851e-05 +4641 4617 -148365426.1266 +4642 4617 97222222.20624 +4643 4617 -3.308057785034e-06 +4707 4617 -46373434.23613 +4708 4617 24305555.56354 +4709 4617 21679861.11823 +4710 4617 -138827443.8752 +4711 4617 2.682209014893e-07 +4712 4617 86719444.4302 +4713 4617 -46373434.23614 +4714 4617 -24305555.56354 +4715 4617 21679861.11823 +4725 4617 8952264.76783 +4726 4617 9.298324584961e-06 +4727 4617 6.228685379028e-06 +4728 4617 222474230.8735 +4729 4617 3.933906555176e-06 +4730 4617 2.622604370117e-05 +4731 4617 8952264.76783 +4732 4617 -1.302361488342e-05 +4733 4617 6.914138793945e-06 +4746 4617 -46373434.23611 +4747 4617 -24305555.56353 +4748 4617 -21679861.11823 +4749 4617 -138827443.8751 +4750 4617 -5.066394805908e-07 +4751 4617 -86719444.43019 +4752 4617 -46373434.23611 +4753 4617 24305555.56353 +4754 4617 -21679861.11823 +4618 4618 1250608048.648 +4619 4618 -1.192092895508e-06 +4620 4618 -3.159046173096e-06 +4621 4618 -185121779.2034 +4622 4618 8.046627044678e-07 +4635 4618 -97222222.20624 +4636 4618 -119197695.4315 +4637 4618 2.831220626831e-07 +4638 4618 -3.09944152832e-06 +4639 4618 20983010.02827 +4640 4618 -4.768371582031e-07 +4641 4618 97222222.20624 +4642 4618 -119197695.4315 +4643 4618 -7.450580596924e-08 +4707 4618 24305555.56354 +4708 4618 -39081501.55876 +4709 4618 -17343750.00569 +4710 4618 -2.294778823853e-06 +4711 4618 -31882558.21685 +4712 4618 2.682209014893e-07 +4713 4618 -24305555.56354 +4714 4618 -39081501.55876 +4715 4618 17343750.0057 +4725 4618 1.069903373718e-05 +4726 4618 -83408755.55014 +4727 4618 -69374999.9886 +4728 4618 4.410743713379e-06 +4729 4618 164138769.4832 +4730 4618 -1.192092895508e-07 +4731 4618 -1.156330108643e-05 +4732 4618 -83408755.55014 +4733 4618 69374999.9886 +4746 4618 -24305555.56353 +4747 4618 -39081501.55875 +4748 4618 -17343750.0057 +4749 4618 -8.344650268555e-07 +4750 4618 -31882558.21681 +4751 4618 -3.278255462646e-07 +4752 4618 24305555.56353 +4753 4618 -39081501.55875 +4754 4618 17343750.00569 +4619 4619 1165825984.246 +4620 4619 -1.382827758789e-05 +4621 4619 1.788139343262e-07 +4622 4619 104791324.3853 +4635 4619 -2.890825271606e-06 +4636 4619 3.8743019104e-07 +4637 4619 -46719419.49861 +4638 4619 -1.20997428894e-05 +4639 4619 -4.768371582031e-07 +4640 4619 -212506.0825927 +4641 4619 -3.278255462646e-06 +4642 4619 -2.086162567139e-07 +4643 4619 -46719419.49861 +4707 4619 21679861.11823 +4708 4619 -17343750.0057 +4709 4619 -36432062.04359 +4710 4619 86719444.4302 +4711 4619 3.427267074585e-07 +4712 4619 -99061955.12464 +4713 4619 21679861.11823 +4714 4619 17343750.0057 +4715 4619 -36432062.04359 +4725 4619 6.169080734253e-06 +4726 4619 -69374999.9886 +4727 4619 -72810997.49471 +4728 4619 2.598762512207e-05 +4729 4619 5.960464477539e-08 +4730 4619 -104578818.0156 +4731 4619 6.973743438721e-06 +4732 4619 69374999.9886 +4733 4619 -72810997.49471 +4746 4619 -21679861.11823 +4747 4619 -17343750.0057 +4748 4619 -36432062.04358 +4749 4619 -86719444.43019 +4750 4619 -2.682209014893e-07 +4751 4619 -99061955.12461 +4752 4619 -21679861.11823 +4753 4619 17343750.00569 +4754 4619 -36432062.04358 +4620 4620 1483949894.094 +4621 4620 7.867813110352e-06 +4622 4620 -5.507469177246e-05 +4623 4620 184322301.8864 +4624 4620 -2.622604370117e-06 +4625 4620 -1.358985900879e-05 +4638 4620 -148365426.1266 +4639 4620 -97222222.20624 +4640 4620 -3.039836883545e-06 +4641 4620 -406796532.3944 +4642 4620 -2.801418304443e-06 +4643 4620 -1.233816146851e-05 +4644 4620 -148365426.1266 +4645 4620 97222222.20624 +4646 4620 -3.308057785034e-06 +4710 4620 -46373434.23613 +4711 4620 24305555.56354 +4712 4620 21679861.11823 +4713 4620 -138827443.8752 +4714 4620 2.682209014893e-07 +4715 4620 86719444.4302 +4716 4620 -46373434.23614 +4717 4620 -24305555.56354 +4718 4620 21679861.11823 +4728 4620 8952264.76783 +4729 4620 9.298324584961e-06 +4730 4620 6.228685379028e-06 +4731 4620 222474230.8735 +4732 4620 3.933906555176e-06 +4733 4620 2.622604370117e-05 +4734 4620 8952264.76783 +4735 4620 -1.302361488342e-05 +4736 4620 6.914138793945e-06 +4749 4620 -46373434.23611 +4750 4620 -24305555.56353 +4751 4620 -21679861.11823 +4752 4620 -138827443.8751 +4753 4620 -5.066394805908e-07 +4754 4620 -86719444.43019 +4755 4620 -46373434.23611 +4756 4620 24305555.56353 +4757 4620 -21679861.11823 +4621 4621 1250608048.648 +4622 4621 -1.192092895508e-06 +4623 4621 -3.159046173096e-06 +4624 4621 -185121779.2034 +4625 4621 8.046627044678e-07 +4638 4621 -97222222.20624 +4639 4621 -119197695.4315 +4640 4621 2.831220626831e-07 +4641 4621 -3.09944152832e-06 +4642 4621 20983010.02827 +4643 4621 -4.768371582031e-07 +4644 4621 97222222.20624 +4645 4621 -119197695.4315 +4646 4621 -7.450580596924e-08 +4710 4621 24305555.56354 +4711 4621 -39081501.55876 +4712 4621 -17343750.00569 +4713 4621 -2.294778823853e-06 +4714 4621 -31882558.21685 +4715 4621 2.682209014893e-07 +4716 4621 -24305555.56354 +4717 4621 -39081501.55876 +4718 4621 17343750.0057 +4728 4621 1.069903373718e-05 +4729 4621 -83408755.55014 +4730 4621 -69374999.9886 +4731 4621 4.410743713379e-06 +4732 4621 164138769.4832 +4733 4621 -1.192092895508e-07 +4734 4621 -1.156330108643e-05 +4735 4621 -83408755.55014 +4736 4621 69374999.9886 +4749 4621 -24305555.56353 +4750 4621 -39081501.55875 +4751 4621 -17343750.0057 +4752 4621 -8.344650268555e-07 +4753 4621 -31882558.21681 +4754 4621 -3.278255462646e-07 +4755 4621 24305555.56353 +4756 4621 -39081501.55875 +4757 4621 17343750.00569 +4622 4622 1165825984.246 +4623 4622 -1.382827758789e-05 +4624 4622 1.788139343262e-07 +4625 4622 104791324.3853 +4638 4622 -2.890825271606e-06 +4639 4622 3.8743019104e-07 +4640 4622 -46719419.49861 +4641 4622 -1.20997428894e-05 +4642 4622 -4.768371582031e-07 +4643 4622 -212506.0825927 +4644 4622 -3.278255462646e-06 +4645 4622 -2.086162567139e-07 +4646 4622 -46719419.49861 +4710 4622 21679861.11823 +4711 4622 -17343750.0057 +4712 4622 -36432062.04359 +4713 4622 86719444.4302 +4714 4622 3.427267074585e-07 +4715 4622 -99061955.12464 +4716 4622 21679861.11823 +4717 4622 17343750.0057 +4718 4622 -36432062.04359 +4728 4622 6.169080734253e-06 +4729 4622 -69374999.9886 +4730 4622 -72810997.49471 +4731 4622 2.598762512207e-05 +4732 4622 5.960464477539e-08 +4733 4622 -104578818.0156 +4734 4622 6.973743438721e-06 +4735 4622 69374999.9886 +4736 4622 -72810997.49471 +4749 4622 -21679861.11823 +4750 4622 -17343750.0057 +4751 4622 -36432062.04358 +4752 4622 -86719444.43019 +4753 4622 -2.682209014893e-07 +4754 4622 -99061955.12461 +4755 4622 -21679861.11823 +4756 4622 17343750.00569 +4757 4622 -36432062.04358 +4623 4623 1483949894.094 +4624 4623 7.867813110352e-06 +4625 4623 -5.507469177246e-05 +4626 4623 184322301.8864 +4627 4623 -2.622604370117e-06 +4628 4623 -1.358985900879e-05 +4641 4623 -148365426.1266 +4642 4623 -97222222.20624 +4643 4623 -3.039836883545e-06 +4644 4623 -406796532.3944 +4645 4623 -2.801418304443e-06 +4646 4623 -1.233816146851e-05 +4647 4623 -148365426.1266 +4648 4623 97222222.20624 +4649 4623 -3.308057785034e-06 +4713 4623 -46373434.23613 +4714 4623 24305555.56354 +4715 4623 21679861.11823 +4716 4623 -138827443.8752 +4717 4623 2.682209014893e-07 +4718 4623 86719444.4302 +4719 4623 -46373434.23614 +4720 4623 -24305555.56354 +4721 4623 21679861.11823 +4731 4623 8952264.76783 +4732 4623 9.298324584961e-06 +4733 4623 6.228685379028e-06 +4734 4623 222474230.8735 +4735 4623 3.933906555176e-06 +4736 4623 2.622604370117e-05 +4737 4623 8952264.76783 +4738 4623 -1.302361488342e-05 +4739 4623 6.914138793945e-06 +4752 4623 -46373434.23611 +4753 4623 -24305555.56353 +4754 4623 -21679861.11823 +4755 4623 -138827443.8751 +4756 4623 -5.066394805908e-07 +4757 4623 -86719444.43019 +4758 4623 -46373434.23611 +4759 4623 24305555.56353 +4760 4623 -21679861.11823 +4624 4624 1250608048.648 +4625 4624 -1.192092895508e-06 +4626 4624 -3.159046173096e-06 +4627 4624 -185121779.2034 +4628 4624 8.046627044678e-07 +4641 4624 -97222222.20624 +4642 4624 -119197695.4315 +4643 4624 2.831220626831e-07 +4644 4624 -3.09944152832e-06 +4645 4624 20983010.02827 +4646 4624 -4.768371582031e-07 +4647 4624 97222222.20624 +4648 4624 -119197695.4315 +4649 4624 -7.450580596924e-08 +4713 4624 24305555.56354 +4714 4624 -39081501.55876 +4715 4624 -17343750.00569 +4716 4624 -2.294778823853e-06 +4717 4624 -31882558.21685 +4718 4624 2.682209014893e-07 +4719 4624 -24305555.56354 +4720 4624 -39081501.55876 +4721 4624 17343750.0057 +4731 4624 1.069903373718e-05 +4732 4624 -83408755.55014 +4733 4624 -69374999.9886 +4734 4624 4.410743713379e-06 +4735 4624 164138769.4832 +4736 4624 -1.192092895508e-07 +4737 4624 -1.156330108643e-05 +4738 4624 -83408755.55014 +4739 4624 69374999.9886 +4752 4624 -24305555.56353 +4753 4624 -39081501.55875 +4754 4624 -17343750.0057 +4755 4624 -8.344650268555e-07 +4756 4624 -31882558.21681 +4757 4624 -3.278255462646e-07 +4758 4624 24305555.56353 +4759 4624 -39081501.55875 +4760 4624 17343750.00569 +4625 4625 1165825984.246 +4626 4625 -1.382827758789e-05 +4627 4625 1.788139343262e-07 +4628 4625 104791324.3853 +4641 4625 -2.890825271606e-06 +4642 4625 3.8743019104e-07 +4643 4625 -46719419.49861 +4644 4625 -1.20997428894e-05 +4645 4625 -4.768371582031e-07 +4646 4625 -212506.0825927 +4647 4625 -3.278255462646e-06 +4648 4625 -2.086162567139e-07 +4649 4625 -46719419.49861 +4713 4625 21679861.11823 +4714 4625 -17343750.0057 +4715 4625 -36432062.04359 +4716 4625 86719444.4302 +4717 4625 3.427267074585e-07 +4718 4625 -99061955.12464 +4719 4625 21679861.11823 +4720 4625 17343750.0057 +4721 4625 -36432062.04359 +4731 4625 6.169080734253e-06 +4732 4625 -69374999.9886 +4733 4625 -72810997.49471 +4734 4625 2.598762512207e-05 +4735 4625 5.960464477539e-08 +4736 4625 -104578818.0156 +4737 4625 6.973743438721e-06 +4738 4625 69374999.9886 +4739 4625 -72810997.49471 +4752 4625 -21679861.11823 +4753 4625 -17343750.0057 +4754 4625 -36432062.04358 +4755 4625 -86719444.43019 +4756 4625 -2.682209014893e-07 +4757 4625 -99061955.12461 +4758 4625 -21679861.11823 +4759 4625 17343750.00569 +4760 4625 -36432062.04358 +4626 4626 1483949894.094 +4627 4626 7.867813110352e-06 +4628 4626 -5.507469177246e-05 +4629 4626 184322301.8864 +4630 4626 -2.622604370117e-06 +4631 4626 -1.358985900879e-05 +4644 4626 -148365426.1266 +4645 4626 -97222222.20624 +4646 4626 -3.039836883545e-06 +4647 4626 -406796532.3944 +4648 4626 -2.801418304443e-06 +4649 4626 -1.233816146851e-05 +4650 4626 -148365426.1266 +4651 4626 97222222.20624 +4652 4626 -3.308057785034e-06 +4716 4626 -46373434.23613 +4717 4626 24305555.56354 +4718 4626 21679861.11823 +4719 4626 -138827443.8752 +4720 4626 2.682209014893e-07 +4721 4626 86719444.4302 +4722 4626 -46373434.23614 +4723 4626 -24305555.56354 +4724 4626 21679861.11823 +4734 4626 8952264.76783 +4735 4626 9.298324584961e-06 +4736 4626 6.228685379028e-06 +4737 4626 222474230.8735 +4738 4626 3.933906555176e-06 +4739 4626 2.622604370117e-05 +4740 4626 8952264.76783 +4741 4626 -1.302361488342e-05 +4742 4626 6.914138793945e-06 +4755 4626 -46373434.23611 +4756 4626 -24305555.56353 +4757 4626 -21679861.11823 +4758 4626 -138827443.8751 +4759 4626 -5.066394805908e-07 +4760 4626 -86719444.43019 +4761 4626 -46373434.23611 +4762 4626 24305555.56353 +4763 4626 -21679861.11823 +4627 4627 1250608048.648 +4628 4627 -1.192092895508e-06 +4629 4627 -3.159046173096e-06 +4630 4627 -185121779.2034 +4631 4627 8.046627044678e-07 +4644 4627 -97222222.20624 +4645 4627 -119197695.4315 +4646 4627 2.831220626831e-07 +4647 4627 -3.09944152832e-06 +4648 4627 20983010.02827 +4649 4627 -4.768371582031e-07 +4650 4627 97222222.20624 +4651 4627 -119197695.4315 +4652 4627 -7.450580596924e-08 +4716 4627 24305555.56354 +4717 4627 -39081501.55876 +4718 4627 -17343750.00569 +4719 4627 -2.294778823853e-06 +4720 4627 -31882558.21685 +4721 4627 2.682209014893e-07 +4722 4627 -24305555.56354 +4723 4627 -39081501.55876 +4724 4627 17343750.0057 +4734 4627 1.069903373718e-05 +4735 4627 -83408755.55014 +4736 4627 -69374999.9886 +4737 4627 4.410743713379e-06 +4738 4627 164138769.4832 +4739 4627 -1.192092895508e-07 +4740 4627 -1.156330108643e-05 +4741 4627 -83408755.55014 +4742 4627 69374999.9886 +4755 4627 -24305555.56353 +4756 4627 -39081501.55875 +4757 4627 -17343750.0057 +4758 4627 -8.344650268555e-07 +4759 4627 -31882558.21681 +4760 4627 -3.278255462646e-07 +4761 4627 24305555.56353 +4762 4627 -39081501.55875 +4763 4627 17343750.00569 +4628 4628 1165825984.246 +4629 4628 -1.382827758789e-05 +4630 4628 1.788139343262e-07 +4631 4628 104791324.3853 +4644 4628 -2.890825271606e-06 +4645 4628 3.8743019104e-07 +4646 4628 -46719419.49861 +4647 4628 -1.20997428894e-05 +4648 4628 -4.768371582031e-07 +4649 4628 -212506.0825927 +4650 4628 -3.278255462646e-06 +4651 4628 -2.086162567139e-07 +4652 4628 -46719419.49861 +4716 4628 21679861.11823 +4717 4628 -17343750.0057 +4718 4628 -36432062.04359 +4719 4628 86719444.4302 +4720 4628 3.427267074585e-07 +4721 4628 -99061955.12464 +4722 4628 21679861.11823 +4723 4628 17343750.0057 +4724 4628 -36432062.04359 +4734 4628 6.169080734253e-06 +4735 4628 -69374999.9886 +4736 4628 -72810997.49471 +4737 4628 2.598762512207e-05 +4738 4628 5.960464477539e-08 +4739 4628 -104578818.0156 +4740 4628 6.973743438721e-06 +4741 4628 69374999.9886 +4742 4628 -72810997.49471 +4755 4628 -21679861.11823 +4756 4628 -17343750.0057 +4757 4628 -36432062.04358 +4758 4628 -86719444.43019 +4759 4628 -2.682209014893e-07 +4760 4628 -99061955.12461 +4761 4628 -21679861.11823 +4762 4628 17343750.00569 +4763 4628 -36432062.04358 +4629 4629 1661147708.835 +4630 4629 104975994.3213 +4631 4629 -3.910064697266e-05 +4632 4629 28973926.47985 +4633 4629 -93442034.30677 +4634 4629 -1.192092895508e-07 +4647 4629 -148365426.1266 +4648 4629 -97222222.20624 +4649 4629 -3.039836883545e-06 +4650 4629 -414750020.4148 +4651 4629 -3811573.0762 +4652 4629 -7.867813110352e-06 +4653 4629 -158390003.0581 +4654 4629 97090758.28168 +4655 4629 2.413988113403e-06 +4719 4629 -46373434.23613 +4720 4629 24305555.56354 +4721 4629 21679861.11823 +4722 4629 -180984988.3576 +4723 4629 -26203286.31792 +4724 4629 88411110.90689 +4737 4629 8952264.76783 +4738 4629 9.298324584961e-06 +4739 4629 6.228685379028e-06 +4740 4629 274245586.3935 +4741 4629 26243998.59326 +4742 4629 0.03795725107193 +4743 4629 -25967702.04294 +4744 4629 -23360508.5882 +4745 4629 21679166.28526 +4758 4629 -46373434.23611 +4759 4629 -24305555.56353 +4760 4629 -21679861.11823 +4761 4629 -140996480.1669 +4762 4629 -952893.269521 +4763 4629 -87564583.31886 +4764 4629 -48879322.66665 +4765 4629 24272689.58238 +4766 4629 -22525694.45184 +4630 4630 1378316574.243 +4631 4630 6.914138793945e-06 +4632 4630 -93442033.91788 +4633 4630 -311076053.7848 +4634 4630 7.450580596924e-07 +4647 4630 -97222222.20624 +4648 4630 -119197695.4315 +4649 4630 2.831220626831e-07 +4650 4630 -3811573.076214 +4651 4630 16672797.27745 +4652 4630 4.64916229248e-06 +4653 4630 97090758.28168 +4654 4630 -116180339.9824 +4655 4630 4.023313522339e-07 +4719 4630 24305555.56354 +4720 4630 -39081501.55876 +4721 4630 -17343750.00569 +4722 4630 -26203286.41514 +4723 4630 -65895674.85388 +4724 4630 18697916.60118 +4737 4630 1.069903373718e-05 +4738 4630 -83408755.55014 +4739 4630 -69374999.9886 +4740 4630 26243998.59326 +4741 4630 203537802.7108 +4742 4630 0.03034967184067 +4743 4630 -23360508.49098 +4744 4630 -110980197.151 +4745 4630 69374999.59698 +4758 4630 -24305555.56353 +4759 4630 -39081501.55875 +4760 4630 -17343750.0057 +4761 4630 -952893.2695279 +4762 4630 -33140775.69073 +4763 4630 -677083.3331567 +4764 4630 24272689.58238 +4765 4630 -38326906.89253 +4766 4630 16666666.67214 +4631 4631 1227849607.294 +4632 4631 1.311302185059e-06 +4633 4631 4.470348358154e-07 +4634 4631 16993676.645 +4647 4631 -2.890825271606e-06 +4648 4631 3.8743019104e-07 +4649 4631 -46719419.49861 +4650 4631 -9.059906005859e-06 +4651 4631 4.64916229248e-06 +4652 4631 -3046182.050712 +4653 4631 2.205371856689e-06 +4654 4631 2.98023223877e-07 +4655 4631 -48631203.38774 +4719 4631 21679861.11823 +4720 4631 -17343750.0057 +4721 4631 -36432062.04359 +4722 4631 88411110.90689 +4723 4631 18697916.56855 +4724 4631 -114040857.0943 +4737 4631 6.169080734253e-06 +4738 4631 -69374999.9886 +4739 4631 -72810997.49471 +4740 4631 -0.03792351484299 +4741 4631 -0.03035482764244 +4742 4631 -69147840.74453 +4743 4631 21679166.091 +4744 4631 69374999.4742 +4745 4631 -84314737.2806 +4758 4631 -21679861.11823 +4759 4631 -17343750.0057 +4760 4631 -36432062.04358 +4761 4631 -87564583.31903 +4762 4631 -677083.33329 +4763 4631 -100252145.5455 +4764 4631 -22525694.45184 +4765 4631 16666666.67214 +4766 4631 -36909325.87324 +4632 4632 878310888.481 +4633 4632 -2657515.757649 +4634 4632 -9.536743164063e-07 +4650 4632 -146355658.7119 +4651 4632 -97205456.75097 +4652 4632 -2.801418304443e-06 +4653 4632 -422227983.6709 +4654 4632 -5136049.023844 +4655 4632 4.768371582031e-07 +4656 4632 85600144.70804 +4657 4632 -16771033.13002 +4658 4632 -1.311302185059e-06 +4659 4632 -156881939.5358 +4660 4632 98545423.0995 +4661 4632 2.205371856689e-06 +4722 4632 -8767515.558539 +4723 4632 29166666.38459 +4724 4632 27030832.75893 +4740 4632 -25967702.04295 +4741 4632 -23360508.49098 +4742 4632 -21679166.091 +4743 4632 119740849.7095 +4744 4632 -664378.939739 +4745 4632 17135277.77496 +4761 4632 -45870736.57863 +4762 4632 -24301364.19972 +4763 4632 -21679166.67379 +4764 4632 -141002035.2672 +4765 4632 -1284012.2566 +4766 4632 -85676388.87481 +4767 4632 4511607.610508 +4768 4632 -4192758.284571 +4769 4632 3215972.223777 +4770 4632 -47751770.62457 +4771 4632 24636355.78702 +4772 4632 -21159027.78473 +4633 4633 904404472.7405 +4634 4633 1.776218414307e-05 +4650 4633 -97205456.75097 +4651 4633 -119802374.1365 +4652 4633 4.321336746216e-07 +4653 4633 -5136049.023847 +4654 4633 9983783.088476 +4655 4633 9.000301361084e-06 +4656 4633 22117855.75249 +4657 4633 -98572068.66138 +4658 4633 -9.238719940186e-07 +4659 4633 98545423.0995 +4660 4633 -123363044.4243 +4661 4633 5.662441253662e-07 +4722 4633 19444444.25639 +4723 4633 -7306349.825736 +4724 4633 -13062499.95656 +4740 4633 -23360508.5882 +4741 4633 -110980197.151 +4742 4633 -69374999.4742 +4743 4633 -664378.9397418 +4744 4633 126264245.7776 +4745 4633 7208333.185864 +4761 4633 -24301364.19972 +4762 4633 -39232415.43152 +4763 4633 -17343750.0057 +4764 4633 -1284012.256601 +4765 4633 -32949093.52408 +4766 4633 -677083.3331573 +4767 4633 5529463.940848 +4768 4633 -41531445.75454 +4769 4633 33333333.32785 +4770 4633 24636355.78702 +4771 4633 -39372046.84257 +4772 4633 16666666.67214 +4634 4634 768562010.6434 +4650 4634 -2.801418304443e-06 +4651 4634 4.470348358154e-07 +4652 4634 -46336936.97173 +4653 4634 8.940696716309e-07 +4654 4634 9.059906005859e-06 +4655 4634 -12181640.54619 +4657 4634 -9.834766387939e-07 +4658 4634 44227455.09151 +4659 4634 1.788139343262e-06 +4660 4634 5.513429641724e-07 +4661 4634 -52301561.26621 +4722 4634 18020555.17262 +4723 4634 -20270833.25379 +4724 4634 -24841207.22224 +4740 4634 -21679166.28526 +4741 4634 -69374999.59698 +4742 4634 -84314737.28062 +4743 4634 -17135277.77496 +4744 4634 -7208333.18587 +4745 4634 -74091157.29495 +4761 4634 -21679166.67379 +4762 4634 -17343750.0057 +4763 4634 -36335759.26896 +4764 4634 -85676388.87481 +4765 4634 -677083.3332908 +4766 4634 -97565514.9312 +4767 4634 -4909027.779057 +4768 4634 33333333.32785 +4769 4634 -33978945.76048 +4770 4634 -21159027.78473 +4771 4634 16666666.67214 +4772 4634 -35825485.57976 +4635 4635 741974947.0469 +4636 4635 5.006790161133e-06 +4637 4635 -2.908706665039e-05 +4638 4635 92161150.94322 +4639 4635 19444444.44125 +4640 4635 -7.271766662598e-06 +4725 4635 -138827443.8752 +4726 4635 2.682209014893e-07 +4727 4635 86719444.4302 +4728 4635 -46373434.23614 +4729 4635 -24305555.56354 +4730 4635 21679861.11823 +4746 4635 111237115.4367 +4747 4635 -8.344650268555e-07 +4748 4635 -17343888.88603 +4749 4635 4476132.383917 +4750 4635 4861111.1127 +4751 4635 -4335972.223642 +4636 4636 625304024.3239 +4637 4636 6.198883056641e-06 +4638 4636 -19444444.44125 +4639 4636 -92560889.60172 +4640 4636 2.32458114624e-06 +4725 4636 -2.294778823853e-06 +4726 4636 -31882558.21685 +4727 4636 2.682209014893e-07 +4728 4636 -24305555.56354 +4729 4636 -39081501.55876 +4730 4636 17343750.0057 +4746 4636 -7.152557373047e-07 +4747 4636 82069384.74161 +4748 4636 -3.75509262085e-06 +4749 4636 -4861111.112713 +4750 4636 -41704377.77507 +4751 4636 34687499.9943 +4637 4637 582912992.1231 +4638 4637 -7.271766662598e-06 +4639 4637 1.877546310425e-06 +4640 4637 52395662.19267 +4725 4637 86719444.4302 +4726 4637 3.427267074585e-07 +4727 4637 -99061955.12464 +4728 4637 21679861.11823 +4729 4637 17343750.0057 +4730 4637 -36432062.04359 +4746 4637 17343888.88605 +4747 4637 -3.576278686523e-06 +4748 4637 -52289409.00778 +4749 4637 4335972.22365 +4750 4637 34687499.9943 +4751 4637 -36405498.74735 +4638 4638 741974947.0469 +4639 4638 5.006790161133e-06 +4640 4638 -2.908706665039e-05 +4641 4638 92161150.94322 +4642 4638 19444444.44125 +4643 4638 -7.271766662598e-06 +4725 4638 -46373434.23613 +4726 4638 24305555.56354 +4727 4638 21679861.11823 +4728 4638 -138827443.8752 +4729 4638 2.682209014893e-07 +4730 4638 86719444.4302 +4731 4638 -46373434.23614 +4732 4638 -24305555.56354 +4733 4638 21679861.11823 +4746 4638 4476132.383914 +4747 4638 -4861111.112702 +4748 4638 -4335972.223643 +4749 4638 111237115.4367 +4750 4638 -8.344650268555e-07 +4751 4638 -17343888.88603 +4752 4638 4476132.383917 +4753 4638 4861111.1127 +4754 4638 -4335972.223642 +4639 4639 625304024.3239 +4640 4639 6.198883056641e-06 +4641 4639 -19444444.44125 +4642 4639 -92560889.60172 +4643 4639 2.32458114624e-06 +4725 4639 24305555.56354 +4726 4639 -39081501.55876 +4727 4639 -17343750.00569 +4728 4639 -2.294778823853e-06 +4729 4639 -31882558.21685 +4730 4639 2.682209014893e-07 +4731 4639 -24305555.56354 +4732 4639 -39081501.55876 +4733 4639 17343750.0057 +4746 4639 4861111.112712 +4747 4639 -41704377.77507 +4748 4639 -34687499.9943 +4749 4639 -7.152557373047e-07 +4750 4639 82069384.74161 +4751 4639 -3.75509262085e-06 +4752 4639 -4861111.112713 +4753 4639 -41704377.77507 +4754 4639 34687499.9943 +4640 4640 582912992.1231 +4641 4640 -7.271766662598e-06 +4642 4640 1.877546310425e-06 +4643 4640 52395662.19267 +4725 4640 21679861.11823 +4726 4640 -17343750.0057 +4727 4640 -36432062.04359 +4728 4640 86719444.4302 +4729 4640 3.427267074585e-07 +4730 4640 -99061955.12464 +4731 4640 21679861.11823 +4732 4640 17343750.0057 +4733 4640 -36432062.04359 +4746 4640 4335972.223649 +4747 4640 -34687499.9943 +4748 4640 -36405498.74736 +4749 4640 17343888.88605 +4750 4640 -3.576278686523e-06 +4751 4640 -52289409.00778 +4752 4640 4335972.22365 +4753 4640 34687499.9943 +4754 4640 -36405498.74735 +4641 4641 741974947.0469 +4642 4641 5.006790161133e-06 +4643 4641 -2.908706665039e-05 +4644 4641 92161150.94322 +4645 4641 19444444.44125 +4646 4641 -7.271766662598e-06 +4728 4641 -46373434.23613 +4729 4641 24305555.56354 +4730 4641 21679861.11823 +4731 4641 -138827443.8752 +4732 4641 2.682209014893e-07 +4733 4641 86719444.4302 +4734 4641 -46373434.23614 +4735 4641 -24305555.56354 +4736 4641 21679861.11823 +4749 4641 4476132.383914 +4750 4641 -4861111.112702 +4751 4641 -4335972.223643 +4752 4641 111237115.4367 +4753 4641 -8.344650268555e-07 +4754 4641 -17343888.88603 +4755 4641 4476132.383917 +4756 4641 4861111.1127 +4757 4641 -4335972.223642 +4642 4642 625304024.3239 +4643 4642 6.198883056641e-06 +4644 4642 -19444444.44125 +4645 4642 -92560889.60172 +4646 4642 2.32458114624e-06 +4728 4642 24305555.56354 +4729 4642 -39081501.55876 +4730 4642 -17343750.00569 +4731 4642 -2.294778823853e-06 +4732 4642 -31882558.21685 +4733 4642 2.682209014893e-07 +4734 4642 -24305555.56354 +4735 4642 -39081501.55876 +4736 4642 17343750.0057 +4749 4642 4861111.112712 +4750 4642 -41704377.77507 +4751 4642 -34687499.9943 +4752 4642 -7.152557373047e-07 +4753 4642 82069384.74161 +4754 4642 -3.75509262085e-06 +4755 4642 -4861111.112713 +4756 4642 -41704377.77507 +4757 4642 34687499.9943 +4643 4643 582912992.1231 +4644 4643 -7.271766662598e-06 +4645 4643 1.877546310425e-06 +4646 4643 52395662.19267 +4728 4643 21679861.11823 +4729 4643 -17343750.0057 +4730 4643 -36432062.04359 +4731 4643 86719444.4302 +4732 4643 3.427267074585e-07 +4733 4643 -99061955.12464 +4734 4643 21679861.11823 +4735 4643 17343750.0057 +4736 4643 -36432062.04359 +4749 4643 4335972.223649 +4750 4643 -34687499.9943 +4751 4643 -36405498.74736 +4752 4643 17343888.88605 +4753 4643 -3.576278686523e-06 +4754 4643 -52289409.00778 +4755 4643 4335972.22365 +4756 4643 34687499.9943 +4757 4643 -36405498.74735 +4644 4644 741974947.0469 +4645 4644 5.006790161133e-06 +4646 4644 -2.908706665039e-05 +4647 4644 92161150.94322 +4648 4644 19444444.44125 +4649 4644 -7.271766662598e-06 +4731 4644 -46373434.23613 +4732 4644 24305555.56354 +4733 4644 21679861.11823 +4734 4644 -138827443.8752 +4735 4644 2.682209014893e-07 +4736 4644 86719444.4302 +4737 4644 -46373434.23614 +4738 4644 -24305555.56354 +4739 4644 21679861.11823 +4752 4644 4476132.383914 +4753 4644 -4861111.112702 +4754 4644 -4335972.223643 +4755 4644 111237115.4367 +4756 4644 -8.344650268555e-07 +4757 4644 -17343888.88603 +4758 4644 4476132.383917 +4759 4644 4861111.1127 +4760 4644 -4335972.223642 +4645 4645 625304024.3239 +4646 4645 6.198883056641e-06 +4647 4645 -19444444.44125 +4648 4645 -92560889.60172 +4649 4645 2.32458114624e-06 +4731 4645 24305555.56354 +4732 4645 -39081501.55876 +4733 4645 -17343750.00569 +4734 4645 -2.294778823853e-06 +4735 4645 -31882558.21685 +4736 4645 2.682209014893e-07 +4737 4645 -24305555.56354 +4738 4645 -39081501.55876 +4739 4645 17343750.0057 +4752 4645 4861111.112712 +4753 4645 -41704377.77507 +4754 4645 -34687499.9943 +4755 4645 -7.152557373047e-07 +4756 4645 82069384.74161 +4757 4645 -3.75509262085e-06 +4758 4645 -4861111.112713 +4759 4645 -41704377.77507 +4760 4645 34687499.9943 +4646 4646 582912992.1231 +4647 4646 -7.271766662598e-06 +4648 4646 1.877546310425e-06 +4649 4646 52395662.19267 +4731 4646 21679861.11823 +4732 4646 -17343750.0057 +4733 4646 -36432062.04359 +4734 4646 86719444.4302 +4735 4646 3.427267074585e-07 +4736 4646 -99061955.12464 +4737 4646 21679861.11823 +4738 4646 17343750.0057 +4739 4646 -36432062.04359 +4752 4646 4335972.223649 +4753 4646 -34687499.9943 +4754 4646 -36405498.74736 +4755 4646 17343888.88605 +4756 4646 -3.576278686523e-06 +4757 4646 -52289409.00778 +4758 4646 4335972.22365 +4759 4646 34687499.9943 +4760 4646 -36405498.74735 +4647 4647 741974947.0469 +4648 4647 5.006790161133e-06 +4649 4647 -2.908706665039e-05 +4650 4647 92161150.94322 +4651 4647 19444444.44125 +4652 4647 -7.271766662598e-06 +4734 4647 -46373434.23613 +4735 4647 24305555.56354 +4736 4647 21679861.11823 +4737 4647 -138827443.8752 +4738 4647 2.682209014893e-07 +4739 4647 86719444.4302 +4740 4647 -46373434.23614 +4741 4647 -24305555.56354 +4742 4647 21679861.11823 +4755 4647 4476132.383914 +4756 4647 -4861111.112702 +4757 4647 -4335972.223643 +4758 4647 111237115.4367 +4759 4647 -8.344650268555e-07 +4760 4647 -17343888.88603 +4761 4647 4476132.383917 +4762 4647 4861111.1127 +4763 4647 -4335972.223642 +4648 4648 625304024.3239 +4649 4648 6.198883056641e-06 +4650 4648 -19444444.44125 +4651 4648 -92560889.60172 +4652 4648 2.32458114624e-06 +4734 4648 24305555.56354 +4735 4648 -39081501.55876 +4736 4648 -17343750.00569 +4737 4648 -2.294778823853e-06 +4738 4648 -31882558.21685 +4739 4648 2.682209014893e-07 +4740 4648 -24305555.56354 +4741 4648 -39081501.55876 +4742 4648 17343750.0057 +4755 4648 4861111.112712 +4756 4648 -41704377.77507 +4757 4648 -34687499.9943 +4758 4648 -7.152557373047e-07 +4759 4648 82069384.74161 +4760 4648 -3.75509262085e-06 +4761 4648 -4861111.112713 +4762 4648 -41704377.77507 +4763 4648 34687499.9943 +4649 4649 582912992.1231 +4650 4649 -7.271766662598e-06 +4651 4649 1.877546310425e-06 +4652 4649 52395662.19267 +4734 4649 21679861.11823 +4735 4649 -17343750.0057 +4736 4649 -36432062.04359 +4737 4649 86719444.4302 +4738 4649 3.427267074585e-07 +4739 4649 -99061955.12464 +4740 4649 21679861.11823 +4741 4649 17343750.0057 +4742 4649 -36432062.04359 +4755 4649 4335972.223649 +4756 4649 -34687499.9943 +4757 4649 -36405498.74736 +4758 4649 17343888.88605 +4759 4649 -3.576278686523e-06 +4760 4649 -52289409.00778 +4761 4649 4335972.22365 +4762 4649 34687499.9943 +4763 4649 -36405498.74735 +4650 4650 743972693.3092 +4651 4650 15895.84580994 +4652 4650 -1.621246337891e-05 +4653 4650 96103889.57229 +4654 4650 23223356.21638 +4655 4650 1.311302185059e-06 +4737 4650 -46373434.23613 +4738 4650 24305555.56354 +4739 4650 21679861.11823 +4740 4650 -140996480.167 +4741 4650 -952893.2695191 +4742 4650 87564583.31904 +4743 4650 -45870736.57862 +4744 4650 -24301364.19972 +4745 4650 21679166.67378 +4758 4650 4476132.383914 +4759 4650 -4861111.112702 +4760 4650 -4335972.223643 +4761 4650 111737658.2526 +4762 4650 3973.961459279 +4763 4650 -17343611.10825 +4764 4650 5643546.059514 +4765 4650 5805839.056956 +4766 4650 -5182361.11248 +4651 4651 624700330.4184 +4652 4651 1.406669616699e-05 +4653 4651 -15665532.66612 +4654 4651 -87045539.95469 +4655 4651 1.907348632813e-06 +4737 4651 24305555.56354 +4738 4651 -39081501.55876 +4739 4651 -17343750.00569 +4740 4651 -952893.2695158 +4741 4651 -33140775.69075 +4742 4651 677083.3332877 +4743 4651 -24301364.19972 +4744 4651 -39232415.43151 +4745 4651 17343750.00569 +4758 4651 4861111.112712 +4759 4651 -41704377.77507 +4760 4651 -34687499.9943 +4761 4651 3973.961458564 +4762 4651 81919567.5152 +4763 4651 -4.589557647705e-06 +4764 4651 -3916383.168461 +4765 4651 -40143811.34479 +4766 4651 34010416.66101 +4652 4652 583290059.4325 +4653 4652 2.384185791016e-07 +4654 4652 1.609325408936e-06 +4655 4652 54461159.75297 +4737 4652 21679861.11823 +4738 4652 -17343750.0057 +4739 4652 -36432062.04359 +4740 4652 87564583.31887 +4741 4652 677083.3331543 +4742 4652 -100252145.5455 +4743 4652 21679166.67378 +4744 4652 17343750.00569 +4745 4652 -36335759.26895 +4758 4652 4335972.223649 +4759 4652 -34687499.9943 +4760 4652 -36405498.74736 +4761 4652 17343611.10827 +4762 4652 -4.291534423828e-06 +4763 4652 -52192192.18033 +4764 4652 3489305.557201 +4765 4652 34010416.66114 +4766 4652 -35404513.64279 +4653 4653 745987487.9303 +4654 4653 -2453991.979028 +4655 4653 -3.814697265625e-06 +4656 4653 -141080087.6865 +4657 4653 -95899021.31303 +4658 4653 -1.296401023865e-06 +4659 4653 92610986.19901 +4660 4653 22063836.70035 +4661 4653 -3.576278686523e-07 +4740 4653 -48879322.66666 +4741 4653 24272689.58239 +4742 4653 22525694.45184 +4743 4653 -141002035.2672 +4744 4653 -1284012.256587 +4745 4653 85676388.87482 +4761 4653 5643546.059503 +4762 4653 -3916383.168461 +4763 4653 -3489305.557201 +4764 4653 115620942.6217 +4765 4653 -613497.995061 +4766 4653 -17135277.77496 +4767 4653 -43801307.66031 +4768 4653 -23974755.34007 +4769 4653 20312500.00667 +4770 4653 5916032.269885 +4771 4653 5515959.177805 +4772 4653 -5078333.334501 +4654 4654 616411761.6305 +4655 4654 1.907348632813e-05 +4656 4654 -95899021.31303 +4657 4654 -117437349.9809 +4658 4654 9.387731552124e-07 +4659 4654 -16825052.18216 +4660 4654 -92728025.5149 +4661 4654 3.844499588013e-06 +4740 4654 24272689.58239 +4741 4654 -38326906.89254 +4742 4654 -16666666.67214 +4743 4654 -1284012.256586 +4744 4654 -32949093.52409 +4745 4654 677083.3332867 +4761 4654 5805839.056958 +4762 4654 -40143811.34482 +4763 4654 -34010416.66115 +4764 4654 -613497.9950583 +4765 4654 83227011.03077 +4766 4654 -4.678964614868e-06 +4767 4654 -23974755.34007 +4768 4654 -37890623.23097 +4769 4654 16666666.67214 +4770 4654 -4206263.047613 +4771 4654 -40418720.68143 +4772 4654 33333333.32785 +4655 4655 572020605.8755 +4656 4655 -1.54972076416e-06 +4657 4655 8.493661880493e-07 +4658 4655 -46375866.82274 +4659 4655 -3.576278686523e-07 +4660 4655 3.725290298462e-06 +4661 4655 48718383.22463 +4740 4655 22525694.45184 +4741 4655 -16666666.67214 +4742 4655 -36909325.87325 +4743 4655 85676388.87482 +4744 4655 677083.3331533 +4745 4655 -97565514.93121 +4761 4655 5182361.11248 +4762 4655 -34010416.66102 +4763 4655 -35404513.64281 +4764 4655 17135277.77496 +4765 4655 -4.738569259644e-06 +4766 4655 -45997327.00148 +4767 4655 20312500.00667 +4768 4655 16666666.67214 +4769 4655 -34344061.96816 +4770 4655 3385277.779222 +4771 4655 33333333.32785 +4772 4655 -33784975.63126 +4656 4656 361120236.1713 +4657 4656 94548810.89504 +4658 4656 2.861022949219e-06 +4659 4656 -203961436.0496 +4660 4656 -20767645.33449 +4661 4656 -2.056360244751e-06 +4743 4656 4511607.610497 +4744 4656 5529463.940849 +4745 4656 4909027.779057 +4764 4656 -43801307.66031 +4765 4656 -23974755.34008 +4766 4656 -20312500.00667 +4767 4656 56503201.94986 +4768 4656 23637202.73541 +4769 4656 8124999.998667 +4770 4656 -68052930.47169 +4771 4656 -5191911.336185 +4772 4656 -41471527.77105 +4657 4657 308313282.913 +4658 4657 8.821487426758e-06 +4659 4657 18121243.54801 +4660 4657 9374992.872531 +4661 4657 4.52995300293e-06 +4743 4657 -4192758.284571 +4744 4657 -41531445.75456 +4745 4657 -33333333.32786 +4764 4657 -23974755.34008 +4765 4657 -37890623.23098 +4766 4657 -16666666.67214 +4767 4657 23637202.73541 +4768 4657 43301463.62877 +4769 4657 6666666.66557 +4770 4657 4530310.889233 +4771 4657 -14718823.21488 +4772 4657 3333333.334427 +4658 4658 278103282.9517 +4659 4658 -8.344650268555e-07 +4660 4658 4.52995300293e-06 +4661 4658 -4811252.171673 +4743 4658 -3215972.223779 +4744 4658 -33333333.32786 +4745 4658 -33978945.7605 +4764 4658 -20312500.00667 +4765 4658 -16666666.67214 +4766 4658 -34344061.96817 +4767 4658 -8124999.998664 +4768 4658 -6666666.665573 +4769 4658 -20545798.26107 +4770 4658 -41471527.77088 +4771 4658 -3333333.334429 +4772 4658 -46703003.53463 +4659 4659 371304389.3859 +4660 4659 -99841614.46536 +4661 4659 -2.145767211914e-06 +4743 4659 -47751770.62458 +4744 4659 24636355.78702 +4745 4659 21159027.78473 +4764 4659 5916032.269875 +4765 4659 -4206263.047613 +4766 4659 -3385277.779223 +4767 4659 -68052930.47169 +4768 4659 4530310.88924 +4769 4659 41471527.77088 +4770 4659 58352668.82663 +4771 4659 -24960403.62864 +4772 4659 -8463611.109722 +4660 4660 309788077.0662 +4661 4660 9.059906005859e-06 +4743 4660 24636355.78702 +4744 4660 -39372046.84258 +4745 4660 -16666666.67214 +4764 4660 5515959.177806 +4765 4660 -40418720.68145 +4766 4660 -33333333.32786 +4767 4660 -5191911.336178 +4768 4660 -14718823.21488 +4769 4660 3333333.334427 +4770 4660 -24960403.62864 +4771 4660 42973590.73914 +4772 4660 6666666.665569 +4661 4661 283253096.8787 +4743 4661 21159027.78473 +4744 4661 -16666666.67214 +4745 4661 -35825485.57977 +4764 4661 5078333.334502 +4765 4661 -33333333.32786 +4766 4661 -33784975.63127 +4767 4661 41471527.77105 +4768 4661 -3333333.334429 +4769 4661 -46703003.53464 +4770 4661 8463611.10972 +4771 4661 -6666666.665574 +4772 4661 -21115868.587 +4662 4662 927468678.158 +4663 4662 97222222.20623 +4664 4662 -8.106231689453e-06 +4665 4662 -573726109.9308 +4666 4662 -97222221.42845 +4667 4662 8.940696716309e-07 +4668 4662 18564155.00999 +4669 4662 77777776.9872 +4670 4662 2.861022949219e-06 +4773 4662 139046393.5639 +4774 4662 24305555.56354 +4776 4662 -175918799.4896 +4777 4662 -24305555.36909 +4779 4662 -9282077.505002 +4780 4662 19444444.25638 +4663 4663 781630025.6149 +4664 4663 8.412431954121e-06 +4665 4663 -97222221.03956 +4666 4663 -116778839.2437 +4667 4663 5.602836608887e-06 +4668 4663 116666665.4808 +4669 4663 18564155.00998 +4670 4663 5.960464477539e-07 +4773 4663 24305555.56354 +4774 4663 102586730.4102 +4776 4663 -24305555.27187 +4777 4663 -61681981.76159 +4779 4663 29166666.38457 +4780 4663 -9282077.504995 +4664 4664 728641235.3813 +4665 4664 4.172325134277e-07 +4666 4664 4.887580871582e-06 +4667 4664 -96436338.25295 +4668 4664 2.503395080566e-06 +4669 4664 1.251697540283e-06 +4670 4664 49504413.35998 +4773 4664 -17343888.84952 +4774 4664 -13874999.85144 +4776 4664 -86719444.24762 +4777 4664 -17343749.94044 +4779 4664 -26015832.7805 +4780 4664 13874999.9393 +4665 4665 1632315315.374 +4666 4665 97222220.26178 +4667 4665 -4.172325134277e-05 +4668 4665 17392720.97666 +4669 4665 -97222221.42845 +4670 4665 -2.145767211914e-06 +4671 4665 -406796532.3944 +4672 4665 -2.801418304443e-06 +4673 4665 -1.233816146851e-05 +4674 4665 -148365426.1266 +4675 4665 97222222.20624 +4676 4665 -3.308057785034e-06 +4773 4665 -175918799.4897 +4774 4665 -24305555.27186 +4776 4665 268847663.9159 +4777 4665 24305555.07742 +4779 4665 -28139091.37671 +4780 4665 -24305555.36909 +4782 4665 -138827443.8751 +4783 4665 -5.066394805908e-07 +4785 4665 -46373434.23611 +4786 4665 24305555.56353 +4666 4666 1369805740.108 +4667 4666 -2.145767211914e-06 +4668 4666 -97222221.03956 +4669 4666 -322883627.8625 +4670 4666 4.798173904419e-06 +4671 4666 -3.09944152832e-06 +4672 4666 20983010.02827 +4673 4666 -4.768371582031e-07 +4674 4666 97222222.20624 +4675 4666 -119197695.4315 +4676 4666 -7.450580596924e-08 +4773 4666 -24305555.36908 +4774 4666 -61681981.7616 +4776 4666 24305555.07742 +4777 4666 203220270.0671 +4779 4666 -24305555.27186 +4780 4666 -113208178.6284 +4782 4666 -8.344650268555e-07 +4783 4666 -31882558.21681 +4785 4666 24305555.56353 +4786 4666 -39081501.55875 +4667 4667 1212545401.289 +4668 4667 -1.788139343262e-06 +4669 4667 3.75509262085e-06 +4670 4667 8567490.576108 +4671 4667 -1.20997428894e-05 +4672 4667 -4.768371582031e-07 +4673 4667 -212506.0825927 +4674 4667 -3.278255462646e-06 +4675 4667 -2.086162567139e-07 +4676 4667 -46719419.49861 +4773 4667 86719444.24762 +4774 4667 17343749.9078 +4776 4667 -0.03649973869324 +4777 4667 -0.02921465039253 +4779 4667 21679860.55685 +4780 4667 69374999.49133 +4782 4667 -86719444.43019 +4783 4667 -2.682209014893e-07 +4785 4667 -21679861.11823 +4786 4667 17343750.00569 +4668 4668 927468678.158 +4669 4668 97222222.20623 +4670 4668 -8.106231689453e-06 +4671 4668 -148365426.1266 +4672 4668 -97222222.20624 +4673 4668 -3.039836883545e-06 +4674 4668 -573726109.9308 +4675 4668 -97222221.42845 +4676 4668 8.940696716309e-07 +4677 4668 18564155.00999 +4678 4668 77777776.9872 +4679 4668 2.861022949219e-06 +4773 4668 -9282077.50499 +4774 4668 29166666.38457 +4776 4668 -28139091.37673 +4777 4668 -24305555.27187 +4779 4668 139046393.5639 +4780 4668 24305555.56354 +4782 4668 -46373434.23611 +4783 4668 -24305555.56353 +4785 4668 -175918799.4896 +4786 4668 -24305555.36909 +4788 4668 -9282077.505002 +4789 4668 19444444.25638 +4669 4669 781630025.6149 +4670 4669 8.412431954121e-06 +4671 4669 -97222222.20624 +4672 4669 -119197695.4315 +4673 4669 2.831220626831e-07 +4674 4669 -97222221.03956 +4675 4669 -116778839.2437 +4676 4669 5.602836608887e-06 +4677 4669 116666665.4808 +4678 4669 18564155.00998 +4679 4669 5.960464477539e-07 +4773 4669 19444444.25638 +4774 4669 -9282077.505 +4776 4669 -24305555.36909 +4777 4669 -113208178.6284 +4779 4669 24305555.56354 +4780 4669 102586730.4102 +4782 4669 -24305555.56353 +4783 4669 -39081501.55875 +4785 4669 -24305555.27187 +4786 4669 -61681981.76159 +4788 4669 29166666.38457 +4789 4669 -9282077.504995 +4670 4670 728641235.3813 +4671 4670 -2.890825271606e-06 +4672 4670 3.8743019104e-07 +4673 4670 -46719419.49861 +4674 4670 4.172325134277e-07 +4675 4670 4.887580871582e-06 +4676 4670 -96436338.25295 +4677 4670 2.503395080566e-06 +4678 4670 1.251697540283e-06 +4679 4670 49504413.35998 +4773 4670 17343888.52033 +4774 4670 -20812499.90895 +4776 4670 -21679860.74398 +4777 4670 -69374999.6084 +4779 4670 -17343888.84952 +4780 4670 -13874999.85144 +4782 4670 -21679861.11823 +4783 4670 -17343750.0057 +4785 4670 -86719444.24762 +4786 4670 -17343749.94044 +4788 4670 -26015832.7805 +4789 4670 13874999.9393 +4671 4671 1483949894.094 +4672 4671 7.867813110352e-06 +4673 4671 -5.507469177246e-05 +4674 4671 184322301.8864 +4675 4671 -2.622604370117e-06 +4676 4671 -1.358985900879e-05 +4680 4671 -406796532.3944 +4681 4671 -2.801418304443e-06 +4682 4671 -1.233816146851e-05 +4683 4671 -148365426.1266 +4684 4671 97222222.20624 +4685 4671 -3.308057785034e-06 +4776 4671 -138827443.8752 +4777 4671 2.682209014893e-07 +4779 4671 -46373434.23614 +4780 4671 -24305555.56354 +4782 4671 222474230.8735 +4783 4671 3.933906555176e-06 +4785 4671 8952264.76783 +4786 4671 -1.302361488342e-05 +4791 4671 -138827443.8751 +4792 4671 -5.066394805908e-07 +4794 4671 -46373434.23611 +4795 4671 24305555.56353 +4672 4672 1250608048.648 +4673 4672 -1.192092895508e-06 +4674 4672 -3.159046173096e-06 +4675 4672 -185121779.2034 +4676 4672 8.046627044678e-07 +4680 4672 -3.09944152832e-06 +4681 4672 20983010.02827 +4682 4672 -4.768371582031e-07 +4683 4672 97222222.20624 +4684 4672 -119197695.4315 +4685 4672 -7.450580596924e-08 +4776 4672 -2.294778823853e-06 +4777 4672 -31882558.21685 +4779 4672 -24305555.56354 +4780 4672 -39081501.55876 +4782 4672 4.410743713379e-06 +4783 4672 164138769.4832 +4785 4672 -1.156330108643e-05 +4786 4672 -83408755.55014 +4791 4672 -8.344650268555e-07 +4792 4672 -31882558.21681 +4794 4672 24305555.56353 +4795 4672 -39081501.55875 +4673 4673 1165825984.246 +4674 4673 -1.382827758789e-05 +4675 4673 1.788139343262e-07 +4676 4673 104791324.3853 +4680 4673 -1.20997428894e-05 +4681 4673 -4.768371582031e-07 +4682 4673 -212506.0825927 +4683 4673 -3.278255462646e-06 +4684 4673 -2.086162567139e-07 +4685 4673 -46719419.49861 +4776 4673 86719444.4302 +4777 4673 3.427267074585e-07 +4779 4673 21679861.11823 +4780 4673 17343750.0057 +4782 4673 2.598762512207e-05 +4783 4673 5.960464477539e-08 +4785 4673 6.973743438721e-06 +4786 4673 69374999.9886 +4791 4673 -86719444.43019 +4792 4673 -2.682209014893e-07 +4794 4673 -21679861.11823 +4795 4673 17343750.00569 +4674 4674 1632315315.374 +4675 4674 97222220.26178 +4676 4674 -4.172325134277e-05 +4677 4674 17392720.97666 +4678 4674 -97222221.42845 +4679 4674 -2.145767211914e-06 +4680 4674 -148365426.1266 +4681 4674 -97222222.20624 +4682 4674 -3.039836883545e-06 +4683 4674 -406796532.3944 +4684 4674 -2.801418304443e-06 +4685 4674 -1.233816146851e-05 +4686 4674 -148365426.1266 +4687 4674 97222222.20624 +4688 4674 -3.308057785034e-06 +4776 4674 -46373434.23613 +4777 4674 24305555.56354 +4779 4674 -175918799.4897 +4780 4674 -24305555.27186 +4782 4674 8952264.76783 +4783 4674 9.298324584961e-06 +4785 4674 268847663.9159 +4786 4674 24305555.07742 +4788 4674 -28139091.37671 +4789 4674 -24305555.36909 +4791 4674 -46373434.23611 +4792 4674 -24305555.56353 +4794 4674 -138827443.8751 +4795 4674 -5.066394805908e-07 +4797 4674 -46373434.23611 +4798 4674 24305555.56353 +4675 4675 1369805740.108 +4676 4675 -2.145767211914e-06 +4677 4675 -97222221.03956 +4678 4675 -322883627.8625 +4679 4675 4.798173904419e-06 +4680 4675 -97222222.20624 +4681 4675 -119197695.4315 +4682 4675 2.831220626831e-07 +4683 4675 -3.09944152832e-06 +4684 4675 20983010.02827 +4685 4675 -4.768371582031e-07 +4686 4675 97222222.20624 +4687 4675 -119197695.4315 +4688 4675 -7.450580596924e-08 +4776 4675 24305555.56354 +4777 4675 -39081501.55876 +4779 4675 -24305555.36908 +4780 4675 -61681981.7616 +4782 4675 1.069903373718e-05 +4783 4675 -83408755.55014 +4785 4675 24305555.07742 +4786 4675 203220270.0671 +4788 4675 -24305555.27186 +4789 4675 -113208178.6284 +4791 4675 -24305555.56353 +4792 4675 -39081501.55875 +4794 4675 -8.344650268555e-07 +4795 4675 -31882558.21681 +4797 4675 24305555.56353 +4798 4675 -39081501.55875 +4676 4676 1212545401.289 +4677 4676 -1.788139343262e-06 +4678 4676 3.75509262085e-06 +4679 4676 8567490.576108 +4680 4676 -2.890825271606e-06 +4681 4676 3.8743019104e-07 +4682 4676 -46719419.49861 +4683 4676 -1.20997428894e-05 +4684 4676 -4.768371582031e-07 +4685 4676 -212506.0825927 +4686 4676 -3.278255462646e-06 +4687 4676 -2.086162567139e-07 +4688 4676 -46719419.49861 +4776 4676 21679861.11823 +4777 4676 -17343750.0057 +4779 4676 86719444.24762 +4780 4676 17343749.9078 +4782 4676 6.169080734253e-06 +4783 4676 -69374999.9886 +4785 4676 -0.03649973869324 +4786 4676 -0.02921465039253 +4788 4676 21679860.55685 +4789 4676 69374999.49133 +4791 4676 -21679861.11823 +4792 4676 -17343750.0057 +4794 4676 -86719444.43019 +4795 4676 -2.682209014893e-07 +4797 4676 -21679861.11823 +4798 4676 17343750.00569 +4677 4677 927468678.158 +4678 4677 97222222.20623 +4679 4677 -8.106231689453e-06 +4683 4677 -148365426.1266 +4684 4677 -97222222.20624 +4685 4677 -3.039836883545e-06 +4686 4677 -573726109.9308 +4687 4677 -97222221.42845 +4688 4677 8.940696716309e-07 +4689 4677 18564155.00999 +4690 4677 77777776.9872 +4691 4677 2.861022949219e-06 +4779 4677 -9282077.50499 +4780 4677 29166666.38457 +4785 4677 -28139091.37673 +4786 4677 -24305555.27187 +4788 4677 139046393.5639 +4789 4677 24305555.56354 +4794 4677 -46373434.23611 +4795 4677 -24305555.56353 +4797 4677 -175918799.4896 +4798 4677 -24305555.36909 +4800 4677 -9282077.505002 +4801 4677 19444444.25638 +4678 4678 781630025.6149 +4679 4678 8.412431954121e-06 +4683 4678 -97222222.20624 +4684 4678 -119197695.4315 +4685 4678 2.831220626831e-07 +4686 4678 -97222221.03956 +4687 4678 -116778839.2437 +4688 4678 5.602836608887e-06 +4689 4678 116666665.4808 +4690 4678 18564155.00998 +4691 4678 5.960464477539e-07 +4779 4678 19444444.25638 +4780 4678 -9282077.505 +4785 4678 -24305555.36909 +4786 4678 -113208178.6284 +4788 4678 24305555.56354 +4789 4678 102586730.4102 +4794 4678 -24305555.56353 +4795 4678 -39081501.55875 +4797 4678 -24305555.27187 +4798 4678 -61681981.76159 +4800 4678 29166666.38457 +4801 4678 -9282077.504995 +4679 4679 728641235.3813 +4683 4679 -2.890825271606e-06 +4684 4679 3.8743019104e-07 +4685 4679 -46719419.49861 +4686 4679 4.172325134277e-07 +4687 4679 4.887580871582e-06 +4688 4679 -96436338.25295 +4689 4679 2.503395080566e-06 +4690 4679 1.251697540283e-06 +4691 4679 49504413.35998 +4779 4679 17343888.52033 +4780 4679 -20812499.90895 +4785 4679 -21679860.74398 +4786 4679 -69374999.6084 +4788 4679 -17343888.84952 +4789 4679 -13874999.85144 +4794 4679 -21679861.11823 +4795 4679 -17343750.0057 +4797 4679 -86719444.24762 +4798 4679 -17343749.94044 +4800 4679 -26015832.7805 +4801 4679 13874999.9393 +4680 4680 1483949894.094 +4681 4680 7.867813110352e-06 +4682 4680 -5.507469177246e-05 +4683 4680 184322301.8864 +4684 4680 -2.622604370117e-06 +4685 4680 -1.358985900879e-05 +4692 4680 -406796532.3944 +4693 4680 -2.801418304443e-06 +4694 4680 -1.233816146851e-05 +4695 4680 -148365426.1266 +4696 4680 97222222.20624 +4697 4680 -3.308057785034e-06 +4782 4680 -138827443.8752 +4783 4680 2.682209014893e-07 +4785 4680 -46373434.23614 +4786 4680 -24305555.56354 +4791 4680 222474230.8735 +4792 4680 3.933906555176e-06 +4794 4680 8952264.76783 +4795 4680 -1.302361488342e-05 +4803 4680 -138827443.8751 +4804 4680 -5.066394805908e-07 +4806 4680 -46373434.23611 +4807 4680 24305555.56353 +4681 4681 1250608048.648 +4682 4681 -1.192092895508e-06 +4683 4681 -3.159046173096e-06 +4684 4681 -185121779.2034 +4685 4681 8.046627044678e-07 +4692 4681 -3.09944152832e-06 +4693 4681 20983010.02827 +4694 4681 -4.768371582031e-07 +4695 4681 97222222.20624 +4696 4681 -119197695.4315 +4697 4681 -7.450580596924e-08 +4782 4681 -2.294778823853e-06 +4783 4681 -31882558.21685 +4785 4681 -24305555.56354 +4786 4681 -39081501.55876 +4791 4681 4.410743713379e-06 +4792 4681 164138769.4832 +4794 4681 -1.156330108643e-05 +4795 4681 -83408755.55014 +4803 4681 -8.344650268555e-07 +4804 4681 -31882558.21681 +4806 4681 24305555.56353 +4807 4681 -39081501.55875 +4682 4682 1165825984.246 +4683 4682 -1.382827758789e-05 +4684 4682 1.788139343262e-07 +4685 4682 104791324.3853 +4692 4682 -1.20997428894e-05 +4693 4682 -4.768371582031e-07 +4694 4682 -212506.0825927 +4695 4682 -3.278255462646e-06 +4696 4682 -2.086162567139e-07 +4697 4682 -46719419.49861 +4782 4682 86719444.4302 +4783 4682 3.427267074585e-07 +4785 4682 21679861.11823 +4786 4682 17343750.0057 +4791 4682 2.598762512207e-05 +4792 4682 5.960464477539e-08 +4794 4682 6.973743438721e-06 +4795 4682 69374999.9886 +4803 4682 -86719444.43019 +4804 4682 -2.682209014893e-07 +4806 4682 -21679861.11823 +4807 4682 17343750.00569 +4683 4683 1483949894.094 +4684 4683 7.867813110352e-06 +4685 4683 -5.507469177246e-05 +4686 4683 184322301.8864 +4687 4683 -2.622604370117e-06 +4688 4683 -1.358985900879e-05 +4692 4683 -148365426.1266 +4693 4683 -97222222.20624 +4694 4683 -3.039836883545e-06 +4695 4683 -406796532.3944 +4696 4683 -2.801418304443e-06 +4697 4683 -1.233816146851e-05 +4698 4683 -148365426.1266 +4699 4683 97222222.20624 +4700 4683 -3.308057785034e-06 +4782 4683 -46373434.23613 +4783 4683 24305555.56354 +4785 4683 -138827443.8752 +4786 4683 2.682209014893e-07 +4788 4683 -46373434.23614 +4789 4683 -24305555.56354 +4791 4683 8952264.76783 +4792 4683 9.298324584961e-06 +4794 4683 222474230.8735 +4795 4683 3.933906555176e-06 +4797 4683 8952264.76783 +4798 4683 -1.302361488342e-05 +4803 4683 -46373434.23611 +4804 4683 -24305555.56353 +4806 4683 -138827443.8751 +4807 4683 -5.066394805908e-07 +4809 4683 -46373434.23611 +4810 4683 24305555.56353 +4684 4684 1250608048.648 +4685 4684 -1.192092895508e-06 +4686 4684 -3.159046173096e-06 +4687 4684 -185121779.2034 +4688 4684 8.046627044678e-07 +4692 4684 -97222222.20624 +4693 4684 -119197695.4315 +4694 4684 2.831220626831e-07 +4695 4684 -3.09944152832e-06 +4696 4684 20983010.02827 +4697 4684 -4.768371582031e-07 +4698 4684 97222222.20624 +4699 4684 -119197695.4315 +4700 4684 -7.450580596924e-08 +4782 4684 24305555.56354 +4783 4684 -39081501.55876 +4785 4684 -2.294778823853e-06 +4786 4684 -31882558.21685 +4788 4684 -24305555.56354 +4789 4684 -39081501.55876 +4791 4684 1.069903373718e-05 +4792 4684 -83408755.55014 +4794 4684 4.410743713379e-06 +4795 4684 164138769.4832 +4797 4684 -1.156330108643e-05 +4798 4684 -83408755.55014 +4803 4684 -24305555.56353 +4804 4684 -39081501.55875 +4806 4684 -8.344650268555e-07 +4807 4684 -31882558.21681 +4809 4684 24305555.56353 +4810 4684 -39081501.55875 +4685 4685 1165825984.246 +4686 4685 -1.382827758789e-05 +4687 4685 1.788139343262e-07 +4688 4685 104791324.3853 +4692 4685 -2.890825271606e-06 +4693 4685 3.8743019104e-07 +4694 4685 -46719419.49861 +4695 4685 -1.20997428894e-05 +4696 4685 -4.768371582031e-07 +4697 4685 -212506.0825927 +4698 4685 -3.278255462646e-06 +4699 4685 -2.086162567139e-07 +4700 4685 -46719419.49861 +4782 4685 21679861.11823 +4783 4685 -17343750.0057 +4785 4685 86719444.4302 +4786 4685 3.427267074585e-07 +4788 4685 21679861.11823 +4789 4685 17343750.0057 +4791 4685 6.169080734253e-06 +4792 4685 -69374999.9886 +4794 4685 2.598762512207e-05 +4795 4685 5.960464477539e-08 +4797 4685 6.973743438721e-06 +4798 4685 69374999.9886 +4803 4685 -21679861.11823 +4804 4685 -17343750.0057 +4806 4685 -86719444.43019 +4807 4685 -2.682209014893e-07 +4809 4685 -21679861.11823 +4810 4685 17343750.00569 +4686 4686 1632315315.374 +4687 4686 97222220.26178 +4688 4686 -4.172325134277e-05 +4689 4686 17392720.97666 +4690 4686 -97222221.42845 +4691 4686 -2.145767211914e-06 +4695 4686 -148365426.1266 +4696 4686 -97222222.20624 +4697 4686 -3.039836883545e-06 +4698 4686 -406796532.3944 +4699 4686 -2.801418304443e-06 +4700 4686 -1.233816146851e-05 +4701 4686 -148365426.1266 +4702 4686 97222222.20624 +4703 4686 -3.308057785034e-06 +4785 4686 -46373434.23613 +4786 4686 24305555.56354 +4788 4686 -175918799.4897 +4789 4686 -24305555.27186 +4794 4686 8952264.76783 +4795 4686 9.298324584961e-06 +4797 4686 268847663.9159 +4798 4686 24305555.07742 +4800 4686 -28139091.37671 +4801 4686 -24305555.36909 +4806 4686 -46373434.23611 +4807 4686 -24305555.56353 +4809 4686 -138827443.8751 +4810 4686 -5.066394805908e-07 +4812 4686 -46373434.23611 +4813 4686 24305555.56353 +4687 4687 1369805740.108 +4688 4687 -2.145767211914e-06 +4689 4687 -97222221.03956 +4690 4687 -322883627.8625 +4691 4687 4.798173904419e-06 +4695 4687 -97222222.20624 +4696 4687 -119197695.4315 +4697 4687 2.831220626831e-07 +4698 4687 -3.09944152832e-06 +4699 4687 20983010.02827 +4700 4687 -4.768371582031e-07 +4701 4687 97222222.20624 +4702 4687 -119197695.4315 +4703 4687 -7.450580596924e-08 +4785 4687 24305555.56354 +4786 4687 -39081501.55876 +4788 4687 -24305555.36908 +4789 4687 -61681981.7616 +4794 4687 1.069903373718e-05 +4795 4687 -83408755.55014 +4797 4687 24305555.07742 +4798 4687 203220270.0671 +4800 4687 -24305555.27186 +4801 4687 -113208178.6284 +4806 4687 -24305555.56353 +4807 4687 -39081501.55875 +4809 4687 -8.344650268555e-07 +4810 4687 -31882558.21681 +4812 4687 24305555.56353 +4813 4687 -39081501.55875 +4688 4688 1212545401.289 +4689 4688 -1.788139343262e-06 +4690 4688 3.75509262085e-06 +4691 4688 8567490.576108 +4695 4688 -2.890825271606e-06 +4696 4688 3.8743019104e-07 +4697 4688 -46719419.49861 +4698 4688 -1.20997428894e-05 +4699 4688 -4.768371582031e-07 +4700 4688 -212506.0825927 +4701 4688 -3.278255462646e-06 +4702 4688 -2.086162567139e-07 +4703 4688 -46719419.49861 +4785 4688 21679861.11823 +4786 4688 -17343750.0057 +4788 4688 86719444.24762 +4789 4688 17343749.9078 +4794 4688 6.169080734253e-06 +4795 4688 -69374999.9886 +4797 4688 -0.03649973869324 +4798 4688 -0.02921465039253 +4800 4688 21679860.55685 +4801 4688 69374999.49133 +4806 4688 -21679861.11823 +4807 4688 -17343750.0057 +4809 4688 -86719444.43019 +4810 4688 -2.682209014893e-07 +4812 4688 -21679861.11823 +4813 4688 17343750.00569 +4689 4689 927468678.158 +4690 4689 97222222.20623 +4691 4689 -8.106231689453e-06 +4698 4689 -148365426.1266 +4699 4689 -97222222.20624 +4700 4689 -3.039836883545e-06 +4701 4689 -573726109.9308 +4702 4689 -97222221.42845 +4703 4689 8.940696716309e-07 +4704 4689 18564155.00999 +4705 4689 77777776.9872 +4706 4689 2.861022949219e-06 +4788 4689 -9282077.50499 +4789 4689 29166666.38457 +4797 4689 -28139091.37673 +4798 4689 -24305555.27187 +4800 4689 139046393.5639 +4801 4689 24305555.56354 +4809 4689 -46373434.23611 +4810 4689 -24305555.56353 +4812 4689 -175918799.4896 +4813 4689 -24305555.36909 +4815 4689 -9282077.505002 +4816 4689 19444444.25638 +4690 4690 781630025.6149 +4691 4690 8.412431954121e-06 +4698 4690 -97222222.20624 +4699 4690 -119197695.4315 +4700 4690 2.831220626831e-07 +4701 4690 -97222221.03956 +4702 4690 -116778839.2437 +4703 4690 5.602836608887e-06 +4704 4690 116666665.4808 +4705 4690 18564155.00998 +4706 4690 5.960464477539e-07 +4788 4690 19444444.25638 +4789 4690 -9282077.505 +4797 4690 -24305555.36909 +4798 4690 -113208178.6284 +4800 4690 24305555.56354 +4801 4690 102586730.4102 +4809 4690 -24305555.56353 +4810 4690 -39081501.55875 +4812 4690 -24305555.27187 +4813 4690 -61681981.76159 +4815 4690 29166666.38457 +4816 4690 -9282077.504995 +4691 4691 728641235.3813 +4698 4691 -2.890825271606e-06 +4699 4691 3.8743019104e-07 +4700 4691 -46719419.49861 +4701 4691 4.172325134277e-07 +4702 4691 4.887580871582e-06 +4703 4691 -96436338.25295 +4704 4691 2.503395080566e-06 +4705 4691 1.251697540283e-06 +4706 4691 49504413.35998 +4788 4691 17343888.52033 +4789 4691 -20812499.90895 +4797 4691 -21679860.74398 +4798 4691 -69374999.6084 +4800 4691 -17343888.84952 +4801 4691 -13874999.85144 +4809 4691 -21679861.11823 +4810 4691 -17343750.0057 +4812 4691 -86719444.24762 +4813 4691 -17343749.94044 +4815 4691 -26015832.7805 +4816 4691 13874999.9393 +4692 4692 1483949894.094 +4693 4692 7.867813110352e-06 +4694 4692 -5.507469177246e-05 +4695 4692 184322301.8864 +4696 4692 -2.622604370117e-06 +4697 4692 -1.358985900879e-05 +4707 4692 -406796532.3944 +4708 4692 -2.801418304443e-06 +4709 4692 -1.233816146851e-05 +4710 4692 -148365426.1266 +4711 4692 97222222.20624 +4712 4692 -3.308057785034e-06 +4791 4692 -138827443.8752 +4792 4692 2.682209014893e-07 +4794 4692 -46373434.23614 +4795 4692 -24305555.56354 +4803 4692 222474230.8735 +4804 4692 3.933906555176e-06 +4806 4692 8952264.76783 +4807 4692 -1.302361488342e-05 +4818 4692 -138827443.8751 +4819 4692 -5.066394805908e-07 +4821 4692 -46373434.23611 +4822 4692 24305555.56353 +4693 4693 1250608048.648 +4694 4693 -1.192092895508e-06 +4695 4693 -3.159046173096e-06 +4696 4693 -185121779.2034 +4697 4693 8.046627044678e-07 +4707 4693 -3.09944152832e-06 +4708 4693 20983010.02827 +4709 4693 -4.768371582031e-07 +4710 4693 97222222.20624 +4711 4693 -119197695.4315 +4712 4693 -7.450580596924e-08 +4791 4693 -2.294778823853e-06 +4792 4693 -31882558.21685 +4794 4693 -24305555.56354 +4795 4693 -39081501.55876 +4803 4693 4.410743713379e-06 +4804 4693 164138769.4832 +4806 4693 -1.156330108643e-05 +4807 4693 -83408755.55014 +4818 4693 -8.344650268555e-07 +4819 4693 -31882558.21681 +4821 4693 24305555.56353 +4822 4693 -39081501.55875 +4694 4694 1165825984.246 +4695 4694 -1.382827758789e-05 +4696 4694 1.788139343262e-07 +4697 4694 104791324.3853 +4707 4694 -1.20997428894e-05 +4708 4694 -4.768371582031e-07 +4709 4694 -212506.0825927 +4710 4694 -3.278255462646e-06 +4711 4694 -2.086162567139e-07 +4712 4694 -46719419.49861 +4791 4694 86719444.4302 +4792 4694 3.427267074585e-07 +4794 4694 21679861.11823 +4795 4694 17343750.0057 +4803 4694 2.598762512207e-05 +4804 4694 5.960464477539e-08 +4806 4694 6.973743438721e-06 +4807 4694 69374999.9886 +4818 4694 -86719444.43019 +4819 4694 -2.682209014893e-07 +4821 4694 -21679861.11823 +4822 4694 17343750.00569 +4695 4695 1483949894.094 +4696 4695 7.867813110352e-06 +4697 4695 -5.507469177246e-05 +4698 4695 184322301.8864 +4699 4695 -2.622604370117e-06 +4700 4695 -1.358985900879e-05 +4707 4695 -148365426.1266 +4708 4695 -97222222.20624 +4709 4695 -3.039836883545e-06 +4710 4695 -406796532.3944 +4711 4695 -2.801418304443e-06 +4712 4695 -1.233816146851e-05 +4713 4695 -148365426.1266 +4714 4695 97222222.20624 +4715 4695 -3.308057785034e-06 +4791 4695 -46373434.23613 +4792 4695 24305555.56354 +4794 4695 -138827443.8752 +4795 4695 2.682209014893e-07 +4797 4695 -46373434.23614 +4798 4695 -24305555.56354 +4803 4695 8952264.76783 +4804 4695 9.298324584961e-06 +4806 4695 222474230.8735 +4807 4695 3.933906555176e-06 +4809 4695 8952264.76783 +4810 4695 -1.302361488342e-05 +4818 4695 -46373434.23611 +4819 4695 -24305555.56353 +4821 4695 -138827443.8751 +4822 4695 -5.066394805908e-07 +4824 4695 -46373434.23611 +4825 4695 24305555.56353 +4696 4696 1250608048.648 +4697 4696 -1.192092895508e-06 +4698 4696 -3.159046173096e-06 +4699 4696 -185121779.2034 +4700 4696 8.046627044678e-07 +4707 4696 -97222222.20624 +4708 4696 -119197695.4315 +4709 4696 2.831220626831e-07 +4710 4696 -3.09944152832e-06 +4711 4696 20983010.02827 +4712 4696 -4.768371582031e-07 +4713 4696 97222222.20624 +4714 4696 -119197695.4315 +4715 4696 -7.450580596924e-08 +4791 4696 24305555.56354 +4792 4696 -39081501.55876 +4794 4696 -2.294778823853e-06 +4795 4696 -31882558.21685 +4797 4696 -24305555.56354 +4798 4696 -39081501.55876 +4803 4696 1.069903373718e-05 +4804 4696 -83408755.55014 +4806 4696 4.410743713379e-06 +4807 4696 164138769.4832 +4809 4696 -1.156330108643e-05 +4810 4696 -83408755.55014 +4818 4696 -24305555.56353 +4819 4696 -39081501.55875 +4821 4696 -8.344650268555e-07 +4822 4696 -31882558.21681 +4824 4696 24305555.56353 +4825 4696 -39081501.55875 +4697 4697 1165825984.246 +4698 4697 -1.382827758789e-05 +4699 4697 1.788139343262e-07 +4700 4697 104791324.3853 +4707 4697 -2.890825271606e-06 +4708 4697 3.8743019104e-07 +4709 4697 -46719419.49861 +4710 4697 -1.20997428894e-05 +4711 4697 -4.768371582031e-07 +4712 4697 -212506.0825927 +4713 4697 -3.278255462646e-06 +4714 4697 -2.086162567139e-07 +4715 4697 -46719419.49861 +4791 4697 21679861.11823 +4792 4697 -17343750.0057 +4794 4697 86719444.4302 +4795 4697 3.427267074585e-07 +4797 4697 21679861.11823 +4798 4697 17343750.0057 +4803 4697 6.169080734253e-06 +4804 4697 -69374999.9886 +4806 4697 2.598762512207e-05 +4807 4697 5.960464477539e-08 +4809 4697 6.973743438721e-06 +4810 4697 69374999.9886 +4818 4697 -21679861.11823 +4819 4697 -17343750.0057 +4821 4697 -86719444.43019 +4822 4697 -2.682209014893e-07 +4824 4697 -21679861.11823 +4825 4697 17343750.00569 +4698 4698 1483949894.094 +4699 4698 7.867813110352e-06 +4700 4698 -5.507469177246e-05 +4701 4698 184322301.8864 +4702 4698 -2.622604370117e-06 +4703 4698 -1.358985900879e-05 +4710 4698 -148365426.1266 +4711 4698 -97222222.20624 +4712 4698 -3.039836883545e-06 +4713 4698 -406796532.3944 +4714 4698 -2.801418304443e-06 +4715 4698 -1.233816146851e-05 +4716 4698 -148365426.1266 +4717 4698 97222222.20624 +4718 4698 -3.308057785034e-06 +4794 4698 -46373434.23613 +4795 4698 24305555.56354 +4797 4698 -138827443.8752 +4798 4698 2.682209014893e-07 +4800 4698 -46373434.23614 +4801 4698 -24305555.56354 +4806 4698 8952264.76783 +4807 4698 9.298324584961e-06 +4809 4698 222474230.8735 +4810 4698 3.933906555176e-06 +4812 4698 8952264.76783 +4813 4698 -1.302361488342e-05 +4821 4698 -46373434.23611 +4822 4698 -24305555.56353 +4824 4698 -138827443.8751 +4825 4698 -5.066394805908e-07 +4827 4698 -46373434.23611 +4828 4698 24305555.56353 +4699 4699 1250608048.648 +4700 4699 -1.192092895508e-06 +4701 4699 -3.159046173096e-06 +4702 4699 -185121779.2034 +4703 4699 8.046627044678e-07 +4710 4699 -97222222.20624 +4711 4699 -119197695.4315 +4712 4699 2.831220626831e-07 +4713 4699 -3.09944152832e-06 +4714 4699 20983010.02827 +4715 4699 -4.768371582031e-07 +4716 4699 97222222.20624 +4717 4699 -119197695.4315 +4718 4699 -7.450580596924e-08 +4794 4699 24305555.56354 +4795 4699 -39081501.55876 +4797 4699 -2.294778823853e-06 +4798 4699 -31882558.21685 +4800 4699 -24305555.56354 +4801 4699 -39081501.55876 +4806 4699 1.069903373718e-05 +4807 4699 -83408755.55014 +4809 4699 4.410743713379e-06 +4810 4699 164138769.4832 +4812 4699 -1.156330108643e-05 +4813 4699 -83408755.55014 +4821 4699 -24305555.56353 +4822 4699 -39081501.55875 +4824 4699 -8.344650268555e-07 +4825 4699 -31882558.21681 +4827 4699 24305555.56353 +4828 4699 -39081501.55875 +4700 4700 1165825984.246 +4701 4700 -1.382827758789e-05 +4702 4700 1.788139343262e-07 +4703 4700 104791324.3853 +4710 4700 -2.890825271606e-06 +4711 4700 3.8743019104e-07 +4712 4700 -46719419.49861 +4713 4700 -1.20997428894e-05 +4714 4700 -4.768371582031e-07 +4715 4700 -212506.0825927 +4716 4700 -3.278255462646e-06 +4717 4700 -2.086162567139e-07 +4718 4700 -46719419.49861 +4794 4700 21679861.11823 +4795 4700 -17343750.0057 +4797 4700 86719444.4302 +4798 4700 3.427267074585e-07 +4800 4700 21679861.11823 +4801 4700 17343750.0057 +4806 4700 6.169080734253e-06 +4807 4700 -69374999.9886 +4809 4700 2.598762512207e-05 +4810 4700 5.960464477539e-08 +4812 4700 6.973743438721e-06 +4813 4700 69374999.9886 +4821 4700 -21679861.11823 +4822 4700 -17343750.0057 +4824 4700 -86719444.43019 +4825 4700 -2.682209014893e-07 +4827 4700 -21679861.11823 +4828 4700 17343750.00569 +4701 4701 1632315315.374 +4702 4701 97222220.26178 +4703 4701 -4.172325134277e-05 +4704 4701 17392720.97666 +4705 4701 -97222221.42845 +4706 4701 -2.145767211914e-06 +4713 4701 -148365426.1266 +4714 4701 -97222222.20624 +4715 4701 -3.039836883545e-06 +4716 4701 -406796532.3944 +4717 4701 -2.801418304443e-06 +4718 4701 -1.233816146851e-05 +4719 4701 -148365426.1266 +4720 4701 97222222.20624 +4721 4701 -3.308057785034e-06 +4797 4701 -46373434.23613 +4798 4701 24305555.56354 +4800 4701 -175918799.4897 +4801 4701 -24305555.27186 +4809 4701 8952264.76783 +4810 4701 9.298324584961e-06 +4812 4701 268847663.9159 +4813 4701 24305555.07742 +4815 4701 -28139091.37671 +4816 4701 -24305555.36909 +4824 4701 -46373434.23611 +4825 4701 -24305555.56353 +4827 4701 -138827443.8751 +4828 4701 -5.066394805908e-07 +4830 4701 -46373434.23611 +4831 4701 24305555.56353 +4702 4702 1369805740.108 +4703 4702 -2.145767211914e-06 +4704 4702 -97222221.03956 +4705 4702 -322883627.8625 +4706 4702 4.798173904419e-06 +4713 4702 -97222222.20624 +4714 4702 -119197695.4315 +4715 4702 2.831220626831e-07 +4716 4702 -3.09944152832e-06 +4717 4702 20983010.02827 +4718 4702 -4.768371582031e-07 +4719 4702 97222222.20624 +4720 4702 -119197695.4315 +4721 4702 -7.450580596924e-08 +4797 4702 24305555.56354 +4798 4702 -39081501.55876 +4800 4702 -24305555.36908 +4801 4702 -61681981.7616 +4809 4702 1.069903373718e-05 +4810 4702 -83408755.55014 +4812 4702 24305555.07742 +4813 4702 203220270.0671 +4815 4702 -24305555.27186 +4816 4702 -113208178.6284 +4824 4702 -24305555.56353 +4825 4702 -39081501.55875 +4827 4702 -8.344650268555e-07 +4828 4702 -31882558.21681 +4830 4702 24305555.56353 +4831 4702 -39081501.55875 +4703 4703 1212545401.289 +4704 4703 -1.788139343262e-06 +4705 4703 3.75509262085e-06 +4706 4703 8567490.576108 +4713 4703 -2.890825271606e-06 +4714 4703 3.8743019104e-07 +4715 4703 -46719419.49861 +4716 4703 -1.20997428894e-05 +4717 4703 -4.768371582031e-07 +4718 4703 -212506.0825927 +4719 4703 -3.278255462646e-06 +4720 4703 -2.086162567139e-07 +4721 4703 -46719419.49861 +4797 4703 21679861.11823 +4798 4703 -17343750.0057 +4800 4703 86719444.24762 +4801 4703 17343749.9078 +4809 4703 6.169080734253e-06 +4810 4703 -69374999.9886 +4812 4703 -0.03649973869324 +4813 4703 -0.02921465039253 +4815 4703 21679860.55685 +4816 4703 69374999.49133 +4824 4703 -21679861.11823 +4825 4703 -17343750.0057 +4827 4703 -86719444.43019 +4828 4703 -2.682209014893e-07 +4830 4703 -21679861.11823 +4831 4703 17343750.00569 +4704 4704 927468678.158 +4705 4704 97222222.20623 +4706 4704 -8.106231689453e-06 +4716 4704 -148365426.1266 +4717 4704 -97222222.20624 +4718 4704 -3.039836883545e-06 +4719 4704 -573726109.9308 +4720 4704 -97222221.42845 +4721 4704 8.940696716309e-07 +4722 4704 18564155.00999 +4723 4704 77777776.9872 +4724 4704 2.861022949219e-06 +4800 4704 -9282077.50499 +4801 4704 29166666.38457 +4812 4704 -28139091.37673 +4813 4704 -24305555.27187 +4815 4704 139046393.5639 +4816 4704 24305555.56354 +4827 4704 -46373434.23611 +4828 4704 -24305555.56353 +4830 4704 -175918799.4896 +4831 4704 -24305555.36909 +4833 4704 -9282077.505002 +4834 4704 19444444.25638 +4705 4705 781630025.6149 +4706 4705 8.412431954121e-06 +4716 4705 -97222222.20624 +4717 4705 -119197695.4315 +4718 4705 2.831220626831e-07 +4719 4705 -97222221.03956 +4720 4705 -116778839.2437 +4721 4705 5.602836608887e-06 +4722 4705 116666665.4808 +4723 4705 18564155.00998 +4724 4705 5.960464477539e-07 +4800 4705 19444444.25638 +4801 4705 -9282077.505 +4812 4705 -24305555.36909 +4813 4705 -113208178.6284 +4815 4705 24305555.56354 +4816 4705 102586730.4102 +4827 4705 -24305555.56353 +4828 4705 -39081501.55875 +4830 4705 -24305555.27187 +4831 4705 -61681981.76159 +4833 4705 29166666.38457 +4834 4705 -9282077.504995 +4706 4706 728641235.3813 +4716 4706 -2.890825271606e-06 +4717 4706 3.8743019104e-07 +4718 4706 -46719419.49861 +4719 4706 4.172325134277e-07 +4720 4706 4.887580871582e-06 +4721 4706 -96436338.25295 +4722 4706 2.503395080566e-06 +4723 4706 1.251697540283e-06 +4724 4706 49504413.35998 +4800 4706 17343888.52033 +4801 4706 -20812499.90895 +4812 4706 -21679860.74398 +4813 4706 -69374999.6084 +4815 4706 -17343888.84952 +4816 4706 -13874999.85144 +4827 4706 -21679861.11823 +4828 4706 -17343750.0057 +4830 4706 -86719444.24762 +4831 4706 -17343749.94044 +4833 4706 -26015832.7805 +4834 4706 13874999.9393 +4707 4707 1483949894.094 +4708 4707 7.867813110352e-06 +4709 4707 -5.507469177246e-05 +4710 4707 184322301.8864 +4711 4707 -2.622604370117e-06 +4712 4707 -1.358985900879e-05 +4725 4707 -406796532.3944 +4726 4707 -2.801418304443e-06 +4727 4707 -1.233816146851e-05 +4728 4707 -148365426.1266 +4729 4707 97222222.20624 +4730 4707 -3.308057785034e-06 +4803 4707 -138827443.8752 +4804 4707 2.682209014893e-07 +4806 4707 -46373434.23614 +4807 4707 -24305555.56354 +4818 4707 222474230.8735 +4819 4707 3.933906555176e-06 +4821 4707 8952264.76783 +4822 4707 -1.302361488342e-05 +4836 4707 -138827443.8751 +4837 4707 -5.066394805908e-07 +4839 4707 -46373434.23611 +4840 4707 24305555.56353 +4708 4708 1250608048.648 +4709 4708 -1.192092895508e-06 +4710 4708 -3.159046173096e-06 +4711 4708 -185121779.2034 +4712 4708 8.046627044678e-07 +4725 4708 -3.09944152832e-06 +4726 4708 20983010.02827 +4727 4708 -4.768371582031e-07 +4728 4708 97222222.20624 +4729 4708 -119197695.4315 +4730 4708 -7.450580596924e-08 +4803 4708 -2.294778823853e-06 +4804 4708 -31882558.21685 +4806 4708 -24305555.56354 +4807 4708 -39081501.55876 +4818 4708 4.410743713379e-06 +4819 4708 164138769.4832 +4821 4708 -1.156330108643e-05 +4822 4708 -83408755.55014 +4836 4708 -8.344650268555e-07 +4837 4708 -31882558.21681 +4839 4708 24305555.56353 +4840 4708 -39081501.55875 +4709 4709 1165825984.246 +4710 4709 -1.382827758789e-05 +4711 4709 1.788139343262e-07 +4712 4709 104791324.3853 +4725 4709 -1.20997428894e-05 +4726 4709 -4.768371582031e-07 +4727 4709 -212506.0825927 +4728 4709 -3.278255462646e-06 +4729 4709 -2.086162567139e-07 +4730 4709 -46719419.49861 +4803 4709 86719444.4302 +4804 4709 3.427267074585e-07 +4806 4709 21679861.11823 +4807 4709 17343750.0057 +4818 4709 2.598762512207e-05 +4819 4709 5.960464477539e-08 +4821 4709 6.973743438721e-06 +4822 4709 69374999.9886 +4836 4709 -86719444.43019 +4837 4709 -2.682209014893e-07 +4839 4709 -21679861.11823 +4840 4709 17343750.00569 +4710 4710 1483949894.094 +4711 4710 7.867813110352e-06 +4712 4710 -5.507469177246e-05 +4713 4710 184322301.8864 +4714 4710 -2.622604370117e-06 +4715 4710 -1.358985900879e-05 +4725 4710 -148365426.1266 +4726 4710 -97222222.20624 +4727 4710 -3.039836883545e-06 +4728 4710 -406796532.3944 +4729 4710 -2.801418304443e-06 +4730 4710 -1.233816146851e-05 +4731 4710 -148365426.1266 +4732 4710 97222222.20624 +4733 4710 -3.308057785034e-06 +4803 4710 -46373434.23613 +4804 4710 24305555.56354 +4806 4710 -138827443.8752 +4807 4710 2.682209014893e-07 +4809 4710 -46373434.23614 +4810 4710 -24305555.56354 +4818 4710 8952264.76783 +4819 4710 9.298324584961e-06 +4821 4710 222474230.8735 +4822 4710 3.933906555176e-06 +4824 4710 8952264.76783 +4825 4710 -1.302361488342e-05 +4836 4710 -46373434.23611 +4837 4710 -24305555.56353 +4839 4710 -138827443.8751 +4840 4710 -5.066394805908e-07 +4842 4710 -46373434.23611 +4843 4710 24305555.56353 +4711 4711 1250608048.648 +4712 4711 -1.192092895508e-06 +4713 4711 -3.159046173096e-06 +4714 4711 -185121779.2034 +4715 4711 8.046627044678e-07 +4725 4711 -97222222.20624 +4726 4711 -119197695.4315 +4727 4711 2.831220626831e-07 +4728 4711 -3.09944152832e-06 +4729 4711 20983010.02827 +4730 4711 -4.768371582031e-07 +4731 4711 97222222.20624 +4732 4711 -119197695.4315 +4733 4711 -7.450580596924e-08 +4803 4711 24305555.56354 +4804 4711 -39081501.55876 +4806 4711 -2.294778823853e-06 +4807 4711 -31882558.21685 +4809 4711 -24305555.56354 +4810 4711 -39081501.55876 +4818 4711 1.069903373718e-05 +4819 4711 -83408755.55014 +4821 4711 4.410743713379e-06 +4822 4711 164138769.4832 +4824 4711 -1.156330108643e-05 +4825 4711 -83408755.55014 +4836 4711 -24305555.56353 +4837 4711 -39081501.55875 +4839 4711 -8.344650268555e-07 +4840 4711 -31882558.21681 +4842 4711 24305555.56353 +4843 4711 -39081501.55875 +4712 4712 1165825984.246 +4713 4712 -1.382827758789e-05 +4714 4712 1.788139343262e-07 +4715 4712 104791324.3853 +4725 4712 -2.890825271606e-06 +4726 4712 3.8743019104e-07 +4727 4712 -46719419.49861 +4728 4712 -1.20997428894e-05 +4729 4712 -4.768371582031e-07 +4730 4712 -212506.0825927 +4731 4712 -3.278255462646e-06 +4732 4712 -2.086162567139e-07 +4733 4712 -46719419.49861 +4803 4712 21679861.11823 +4804 4712 -17343750.0057 +4806 4712 86719444.4302 +4807 4712 3.427267074585e-07 +4809 4712 21679861.11823 +4810 4712 17343750.0057 +4818 4712 6.169080734253e-06 +4819 4712 -69374999.9886 +4821 4712 2.598762512207e-05 +4822 4712 5.960464477539e-08 +4824 4712 6.973743438721e-06 +4825 4712 69374999.9886 +4836 4712 -21679861.11823 +4837 4712 -17343750.0057 +4839 4712 -86719444.43019 +4840 4712 -2.682209014893e-07 +4842 4712 -21679861.11823 +4843 4712 17343750.00569 +4713 4713 1483949894.094 +4714 4713 7.867813110352e-06 +4715 4713 -5.507469177246e-05 +4716 4713 184322301.8864 +4717 4713 -2.622604370117e-06 +4718 4713 -1.358985900879e-05 +4728 4713 -148365426.1266 +4729 4713 -97222222.20624 +4730 4713 -3.039836883545e-06 +4731 4713 -406796532.3944 +4732 4713 -2.801418304443e-06 +4733 4713 -1.233816146851e-05 +4734 4713 -148365426.1266 +4735 4713 97222222.20624 +4736 4713 -3.308057785034e-06 +4806 4713 -46373434.23613 +4807 4713 24305555.56354 +4809 4713 -138827443.8752 +4810 4713 2.682209014893e-07 +4812 4713 -46373434.23614 +4813 4713 -24305555.56354 +4821 4713 8952264.76783 +4822 4713 9.298324584961e-06 +4824 4713 222474230.8735 +4825 4713 3.933906555176e-06 +4827 4713 8952264.76783 +4828 4713 -1.302361488342e-05 +4839 4713 -46373434.23611 +4840 4713 -24305555.56353 +4842 4713 -138827443.8751 +4843 4713 -5.066394805908e-07 +4845 4713 -46373434.23611 +4846 4713 24305555.56353 +4714 4714 1250608048.648 +4715 4714 -1.192092895508e-06 +4716 4714 -3.159046173096e-06 +4717 4714 -185121779.2034 +4718 4714 8.046627044678e-07 +4728 4714 -97222222.20624 +4729 4714 -119197695.4315 +4730 4714 2.831220626831e-07 +4731 4714 -3.09944152832e-06 +4732 4714 20983010.02827 +4733 4714 -4.768371582031e-07 +4734 4714 97222222.20624 +4735 4714 -119197695.4315 +4736 4714 -7.450580596924e-08 +4806 4714 24305555.56354 +4807 4714 -39081501.55876 +4809 4714 -2.294778823853e-06 +4810 4714 -31882558.21685 +4812 4714 -24305555.56354 +4813 4714 -39081501.55876 +4821 4714 1.069903373718e-05 +4822 4714 -83408755.55014 +4824 4714 4.410743713379e-06 +4825 4714 164138769.4832 +4827 4714 -1.156330108643e-05 +4828 4714 -83408755.55014 +4839 4714 -24305555.56353 +4840 4714 -39081501.55875 +4842 4714 -8.344650268555e-07 +4843 4714 -31882558.21681 +4845 4714 24305555.56353 +4846 4714 -39081501.55875 +4715 4715 1165825984.246 +4716 4715 -1.382827758789e-05 +4717 4715 1.788139343262e-07 +4718 4715 104791324.3853 +4728 4715 -2.890825271606e-06 +4729 4715 3.8743019104e-07 +4730 4715 -46719419.49861 +4731 4715 -1.20997428894e-05 +4732 4715 -4.768371582031e-07 +4733 4715 -212506.0825927 +4734 4715 -3.278255462646e-06 +4735 4715 -2.086162567139e-07 +4736 4715 -46719419.49861 +4806 4715 21679861.11823 +4807 4715 -17343750.0057 +4809 4715 86719444.4302 +4810 4715 3.427267074585e-07 +4812 4715 21679861.11823 +4813 4715 17343750.0057 +4821 4715 6.169080734253e-06 +4822 4715 -69374999.9886 +4824 4715 2.598762512207e-05 +4825 4715 5.960464477539e-08 +4827 4715 6.973743438721e-06 +4828 4715 69374999.9886 +4839 4715 -21679861.11823 +4840 4715 -17343750.0057 +4842 4715 -86719444.43019 +4843 4715 -2.682209014893e-07 +4845 4715 -21679861.11823 +4846 4715 17343750.00569 +4716 4716 1483949894.094 +4717 4716 7.867813110352e-06 +4718 4716 -5.507469177246e-05 +4719 4716 184322301.8864 +4720 4716 -2.622604370117e-06 +4721 4716 -1.358985900879e-05 +4731 4716 -148365426.1266 +4732 4716 -97222222.20624 +4733 4716 -3.039836883545e-06 +4734 4716 -406796532.3944 +4735 4716 -2.801418304443e-06 +4736 4716 -1.233816146851e-05 +4737 4716 -148365426.1266 +4738 4716 97222222.20624 +4739 4716 -3.308057785034e-06 +4809 4716 -46373434.23613 +4810 4716 24305555.56354 +4812 4716 -138827443.8752 +4813 4716 2.682209014893e-07 +4815 4716 -46373434.23614 +4816 4716 -24305555.56354 +4824 4716 8952264.76783 +4825 4716 9.298324584961e-06 +4827 4716 222474230.8735 +4828 4716 3.933906555176e-06 +4830 4716 8952264.76783 +4831 4716 -1.302361488342e-05 +4842 4716 -46373434.23611 +4843 4716 -24305555.56353 +4845 4716 -138827443.8751 +4846 4716 -5.066394805908e-07 +4848 4716 -46373434.23611 +4849 4716 24305555.56353 +4717 4717 1250608048.648 +4718 4717 -1.192092895508e-06 +4719 4717 -3.159046173096e-06 +4720 4717 -185121779.2034 +4721 4717 8.046627044678e-07 +4731 4717 -97222222.20624 +4732 4717 -119197695.4315 +4733 4717 2.831220626831e-07 +4734 4717 -3.09944152832e-06 +4735 4717 20983010.02827 +4736 4717 -4.768371582031e-07 +4737 4717 97222222.20624 +4738 4717 -119197695.4315 +4739 4717 -7.450580596924e-08 +4809 4717 24305555.56354 +4810 4717 -39081501.55876 +4812 4717 -2.294778823853e-06 +4813 4717 -31882558.21685 +4815 4717 -24305555.56354 +4816 4717 -39081501.55876 +4824 4717 1.069903373718e-05 +4825 4717 -83408755.55014 +4827 4717 4.410743713379e-06 +4828 4717 164138769.4832 +4830 4717 -1.156330108643e-05 +4831 4717 -83408755.55014 +4842 4717 -24305555.56353 +4843 4717 -39081501.55875 +4845 4717 -8.344650268555e-07 +4846 4717 -31882558.21681 +4848 4717 24305555.56353 +4849 4717 -39081501.55875 +4718 4718 1165825984.246 +4719 4718 -1.382827758789e-05 +4720 4718 1.788139343262e-07 +4721 4718 104791324.3853 +4731 4718 -2.890825271606e-06 +4732 4718 3.8743019104e-07 +4733 4718 -46719419.49861 +4734 4718 -1.20997428894e-05 +4735 4718 -4.768371582031e-07 +4736 4718 -212506.0825927 +4737 4718 -3.278255462646e-06 +4738 4718 -2.086162567139e-07 +4739 4718 -46719419.49861 +4809 4718 21679861.11823 +4810 4718 -17343750.0057 +4812 4718 86719444.4302 +4813 4718 3.427267074585e-07 +4815 4718 21679861.11823 +4816 4718 17343750.0057 +4824 4718 6.169080734253e-06 +4825 4718 -69374999.9886 +4827 4718 2.598762512207e-05 +4828 4718 5.960464477539e-08 +4830 4718 6.973743438721e-06 +4831 4718 69374999.9886 +4842 4718 -21679861.11823 +4843 4718 -17343750.0057 +4845 4718 -86719444.43019 +4846 4718 -2.682209014893e-07 +4848 4718 -21679861.11823 +4849 4718 17343750.00569 +4719 4719 1632315315.374 +4720 4719 97222220.26178 +4721 4719 -4.172325134277e-05 +4722 4719 17392720.97666 +4723 4719 -97222221.42845 +4724 4719 -2.145767211914e-06 +4734 4719 -148365426.1266 +4735 4719 -97222222.20624 +4736 4719 -3.039836883545e-06 +4737 4719 -406796532.3944 +4738 4719 -2.801418304443e-06 +4739 4719 -1.233816146851e-05 +4740 4719 -148365426.1266 +4741 4719 97222222.20624 +4742 4719 -3.308057785034e-06 +4812 4719 -46373434.23613 +4813 4719 24305555.56354 +4815 4719 -175918799.4897 +4816 4719 -24305555.27186 +4827 4719 8952264.76783 +4828 4719 9.298324584961e-06 +4830 4719 268847663.9159 +4831 4719 24305555.07742 +4833 4719 -28139091.37671 +4834 4719 -24305555.36909 +4845 4719 -46373434.23611 +4846 4719 -24305555.56353 +4848 4719 -138827443.8751 +4849 4719 -5.066394805908e-07 +4851 4719 -46373434.23611 +4852 4719 24305555.56353 +4720 4720 1369805740.108 +4721 4720 -2.145767211914e-06 +4722 4720 -97222221.03956 +4723 4720 -322883627.8625 +4724 4720 4.798173904419e-06 +4734 4720 -97222222.20624 +4735 4720 -119197695.4315 +4736 4720 2.831220626831e-07 +4737 4720 -3.09944152832e-06 +4738 4720 20983010.02827 +4739 4720 -4.768371582031e-07 +4740 4720 97222222.20624 +4741 4720 -119197695.4315 +4742 4720 -7.450580596924e-08 +4812 4720 24305555.56354 +4813 4720 -39081501.55876 +4815 4720 -24305555.36908 +4816 4720 -61681981.7616 +4827 4720 1.069903373718e-05 +4828 4720 -83408755.55014 +4830 4720 24305555.07742 +4831 4720 203220270.0671 +4833 4720 -24305555.27186 +4834 4720 -113208178.6284 +4845 4720 -24305555.56353 +4846 4720 -39081501.55875 +4848 4720 -8.344650268555e-07 +4849 4720 -31882558.21681 +4851 4720 24305555.56353 +4852 4720 -39081501.55875 +4721 4721 1212545401.289 +4722 4721 -1.788139343262e-06 +4723 4721 3.75509262085e-06 +4724 4721 8567490.576108 +4734 4721 -2.890825271606e-06 +4735 4721 3.8743019104e-07 +4736 4721 -46719419.49861 +4737 4721 -1.20997428894e-05 +4738 4721 -4.768371582031e-07 +4739 4721 -212506.0825927 +4740 4721 -3.278255462646e-06 +4741 4721 -2.086162567139e-07 +4742 4721 -46719419.49861 +4812 4721 21679861.11823 +4813 4721 -17343750.0057 +4815 4721 86719444.24762 +4816 4721 17343749.9078 +4827 4721 6.169080734253e-06 +4828 4721 -69374999.9886 +4830 4721 -0.03649973869324 +4831 4721 -0.02921465039253 +4833 4721 21679860.55685 +4834 4721 69374999.49133 +4845 4721 -21679861.11823 +4846 4721 -17343750.0057 +4848 4721 -86719444.43019 +4849 4721 -2.682209014893e-07 +4851 4721 -21679861.11823 +4852 4721 17343750.00569 +4722 4722 944226635.8558 +4723 4722 104813146.3867 +4724 4722 -5.006790161133e-06 +4737 4722 -148365426.1266 +4738 4722 -97222222.20624 +4739 4722 -3.039836883545e-06 +4740 4722 -591818040.3848 +4741 4722 -104813145.6089 +4742 4722 -1.507997512817e-05 +4743 4722 22795227.75344 +4744 4722 77777776.98725 +4745 4722 3.218650817871e-06 +4815 4722 -9282077.50499 +4816 4722 29166666.38457 +4830 4722 -28139091.37673 +4831 4722 -24305555.27187 +4833 4722 142149470.4917 +4834 4722 26203286.60958 +4848 4722 -46373434.23611 +4849 4722 -24305555.56353 +4851 4722 -180984988.3575 +4852 4722 -26203286.41514 +4854 4722 -8767515.55854 +4855 4722 19444444.25639 +4723 4723 789133337.2837 +4724 4723 2.995133399963e-06 +4737 4723 -97222222.20624 +4738 4723 -119197695.4315 +4739 4723 2.831220626831e-07 +4740 4723 -104813145.2201 +4741 4723 -131460786.597 +4742 4723 -1.668930053711e-06 +4743 4723 116666665.4809 +4744 4723 28639890.68178 +4745 4723 1.54972076416e-06 +4815 4723 19444444.25638 +4816 4723 -9282077.505 +4830 4723 -24305555.36909 +4831 4723 -113208178.6284 +4833 4723 26203286.60958 +4834 4723 103376145.8296 +4848 4723 -24305555.56353 +4849 4723 -39081501.55875 +4851 4723 -26203286.31793 +4852 4723 -65895674.85387 +4854 4723 29166666.38459 +4855 4723 -7306349.825735 +4724 4724 738330627.0228 +4737 4724 -2.890825271606e-06 +4738 4724 3.8743019104e-07 +4739 4724 -46719419.49861 +4740 4724 -1.716613769531e-05 +4741 4724 -1.013278961182e-06 +4742 4724 -103838327.6491 +4743 4724 5.245208740234e-06 +4744 4724 1.132488250732e-06 +4745 4724 54942611.08085 +4815 4724 17343888.52033 +4816 4724 -20812499.90895 +4830 4724 -21679860.74398 +4831 4724 -69374999.6084 +4833 4724 -17682222.18137 +4834 4724 -14145833.18359 +4848 4724 -21679861.11823 +4849 4724 -17343750.0057 +4851 4724 -88411110.90689 +4852 4724 -18697916.60118 +4854 4724 -27030832.75893 +4855 4724 13062499.95656 +4725 4725 1483949894.094 +4726 4725 7.867813110352e-06 +4727 4725 -5.507469177246e-05 +4728 4725 184322301.8864 +4729 4725 -2.622604370117e-06 +4730 4725 -1.358985900879e-05 +4746 4725 -406796532.3944 +4747 4725 -2.801418304443e-06 +4748 4725 -1.233816146851e-05 +4749 4725 -148365426.1266 +4750 4725 97222222.20624 +4751 4725 -3.308057785034e-06 +4818 4725 -138827443.8752 +4819 4725 2.682209014893e-07 +4821 4725 -46373434.23614 +4822 4725 -24305555.56354 +4836 4725 222474230.8735 +4837 4725 3.933906555176e-06 +4839 4725 8952264.76783 +4840 4725 -1.302361488342e-05 +4857 4725 -138827443.8751 +4858 4725 -5.066394805908e-07 +4860 4725 -46373434.23611 +4861 4725 24305555.56353 +4726 4726 1250608048.648 +4727 4726 -1.192092895508e-06 +4728 4726 -3.159046173096e-06 +4729 4726 -185121779.2034 +4730 4726 8.046627044678e-07 +4746 4726 -3.09944152832e-06 +4747 4726 20983010.02827 +4748 4726 -4.768371582031e-07 +4749 4726 97222222.20624 +4750 4726 -119197695.4315 +4751 4726 -7.450580596924e-08 +4818 4726 -2.294778823853e-06 +4819 4726 -31882558.21685 +4821 4726 -24305555.56354 +4822 4726 -39081501.55876 +4836 4726 4.410743713379e-06 +4837 4726 164138769.4832 +4839 4726 -1.156330108643e-05 +4840 4726 -83408755.55014 +4857 4726 -8.344650268555e-07 +4858 4726 -31882558.21681 +4860 4726 24305555.56353 +4861 4726 -39081501.55875 +4727 4727 1165825984.246 +4728 4727 -1.382827758789e-05 +4729 4727 1.788139343262e-07 +4730 4727 104791324.3853 +4746 4727 -1.20997428894e-05 +4747 4727 -4.768371582031e-07 +4748 4727 -212506.0825927 +4749 4727 -3.278255462646e-06 +4750 4727 -2.086162567139e-07 +4751 4727 -46719419.49861 +4818 4727 86719444.4302 +4819 4727 3.427267074585e-07 +4821 4727 21679861.11823 +4822 4727 17343750.0057 +4836 4727 2.598762512207e-05 +4837 4727 5.960464477539e-08 +4839 4727 6.973743438721e-06 +4840 4727 69374999.9886 +4857 4727 -86719444.43019 +4858 4727 -2.682209014893e-07 +4860 4727 -21679861.11823 +4861 4727 17343750.00569 +4728 4728 1483949894.094 +4729 4728 7.867813110352e-06 +4730 4728 -5.507469177246e-05 +4731 4728 184322301.8864 +4732 4728 -2.622604370117e-06 +4733 4728 -1.358985900879e-05 +4746 4728 -148365426.1266 +4747 4728 -97222222.20624 +4748 4728 -3.039836883545e-06 +4749 4728 -406796532.3944 +4750 4728 -2.801418304443e-06 +4751 4728 -1.233816146851e-05 +4752 4728 -148365426.1266 +4753 4728 97222222.20624 +4754 4728 -3.308057785034e-06 +4818 4728 -46373434.23613 +4819 4728 24305555.56354 +4821 4728 -138827443.8752 +4822 4728 2.682209014893e-07 +4824 4728 -46373434.23614 +4825 4728 -24305555.56354 +4836 4728 8952264.76783 +4837 4728 9.298324584961e-06 +4839 4728 222474230.8735 +4840 4728 3.933906555176e-06 +4842 4728 8952264.76783 +4843 4728 -1.302361488342e-05 +4857 4728 -46373434.23611 +4858 4728 -24305555.56353 +4860 4728 -138827443.8751 +4861 4728 -5.066394805908e-07 +4863 4728 -46373434.23611 +4864 4728 24305555.56353 +4729 4729 1250608048.648 +4730 4729 -1.192092895508e-06 +4731 4729 -3.159046173096e-06 +4732 4729 -185121779.2034 +4733 4729 8.046627044678e-07 +4746 4729 -97222222.20624 +4747 4729 -119197695.4315 +4748 4729 2.831220626831e-07 +4749 4729 -3.09944152832e-06 +4750 4729 20983010.02827 +4751 4729 -4.768371582031e-07 +4752 4729 97222222.20624 +4753 4729 -119197695.4315 +4754 4729 -7.450580596924e-08 +4818 4729 24305555.56354 +4819 4729 -39081501.55876 +4821 4729 -2.294778823853e-06 +4822 4729 -31882558.21685 +4824 4729 -24305555.56354 +4825 4729 -39081501.55876 +4836 4729 1.069903373718e-05 +4837 4729 -83408755.55014 +4839 4729 4.410743713379e-06 +4840 4729 164138769.4832 +4842 4729 -1.156330108643e-05 +4843 4729 -83408755.55014 +4857 4729 -24305555.56353 +4858 4729 -39081501.55875 +4860 4729 -8.344650268555e-07 +4861 4729 -31882558.21681 +4863 4729 24305555.56353 +4864 4729 -39081501.55875 +4730 4730 1165825984.246 +4731 4730 -1.382827758789e-05 +4732 4730 1.788139343262e-07 +4733 4730 104791324.3853 +4746 4730 -2.890825271606e-06 +4747 4730 3.8743019104e-07 +4748 4730 -46719419.49861 +4749 4730 -1.20997428894e-05 +4750 4730 -4.768371582031e-07 +4751 4730 -212506.0825927 +4752 4730 -3.278255462646e-06 +4753 4730 -2.086162567139e-07 +4754 4730 -46719419.49861 +4818 4730 21679861.11823 +4819 4730 -17343750.0057 +4821 4730 86719444.4302 +4822 4730 3.427267074585e-07 +4824 4730 21679861.11823 +4825 4730 17343750.0057 +4836 4730 6.169080734253e-06 +4837 4730 -69374999.9886 +4839 4730 2.598762512207e-05 +4840 4730 5.960464477539e-08 +4842 4730 6.973743438721e-06 +4843 4730 69374999.9886 +4857 4730 -21679861.11823 +4858 4730 -17343750.0057 +4860 4730 -86719444.43019 +4861 4730 -2.682209014893e-07 +4863 4730 -21679861.11823 +4864 4730 17343750.00569 +4731 4731 1483949894.094 +4732 4731 7.867813110352e-06 +4733 4731 -5.507469177246e-05 +4734 4731 184322301.8864 +4735 4731 -2.622604370117e-06 +4736 4731 -1.358985900879e-05 +4749 4731 -148365426.1266 +4750 4731 -97222222.20624 +4751 4731 -3.039836883545e-06 +4752 4731 -406796532.3944 +4753 4731 -2.801418304443e-06 +4754 4731 -1.233816146851e-05 +4755 4731 -148365426.1266 +4756 4731 97222222.20624 +4757 4731 -3.308057785034e-06 +4821 4731 -46373434.23613 +4822 4731 24305555.56354 +4824 4731 -138827443.8752 +4825 4731 2.682209014893e-07 +4827 4731 -46373434.23614 +4828 4731 -24305555.56354 +4839 4731 8952264.76783 +4840 4731 9.298324584961e-06 +4842 4731 222474230.8735 +4843 4731 3.933906555176e-06 +4845 4731 8952264.76783 +4846 4731 -1.302361488342e-05 +4860 4731 -46373434.23611 +4861 4731 -24305555.56353 +4863 4731 -138827443.8751 +4864 4731 -5.066394805908e-07 +4866 4731 -46373434.23611 +4867 4731 24305555.56353 +4732 4732 1250608048.648 +4733 4732 -1.192092895508e-06 +4734 4732 -3.159046173096e-06 +4735 4732 -185121779.2034 +4736 4732 8.046627044678e-07 +4749 4732 -97222222.20624 +4750 4732 -119197695.4315 +4751 4732 2.831220626831e-07 +4752 4732 -3.09944152832e-06 +4753 4732 20983010.02827 +4754 4732 -4.768371582031e-07 +4755 4732 97222222.20624 +4756 4732 -119197695.4315 +4757 4732 -7.450580596924e-08 +4821 4732 24305555.56354 +4822 4732 -39081501.55876 +4824 4732 -2.294778823853e-06 +4825 4732 -31882558.21685 +4827 4732 -24305555.56354 +4828 4732 -39081501.55876 +4839 4732 1.069903373718e-05 +4840 4732 -83408755.55014 +4842 4732 4.410743713379e-06 +4843 4732 164138769.4832 +4845 4732 -1.156330108643e-05 +4846 4732 -83408755.55014 +4860 4732 -24305555.56353 +4861 4732 -39081501.55875 +4863 4732 -8.344650268555e-07 +4864 4732 -31882558.21681 +4866 4732 24305555.56353 +4867 4732 -39081501.55875 +4733 4733 1165825984.246 +4734 4733 -1.382827758789e-05 +4735 4733 1.788139343262e-07 +4736 4733 104791324.3853 +4749 4733 -2.890825271606e-06 +4750 4733 3.8743019104e-07 +4751 4733 -46719419.49861 +4752 4733 -1.20997428894e-05 +4753 4733 -4.768371582031e-07 +4754 4733 -212506.0825927 +4755 4733 -3.278255462646e-06 +4756 4733 -2.086162567139e-07 +4757 4733 -46719419.49861 +4821 4733 21679861.11823 +4822 4733 -17343750.0057 +4824 4733 86719444.4302 +4825 4733 3.427267074585e-07 +4827 4733 21679861.11823 +4828 4733 17343750.0057 +4839 4733 6.169080734253e-06 +4840 4733 -69374999.9886 +4842 4733 2.598762512207e-05 +4843 4733 5.960464477539e-08 +4845 4733 6.973743438721e-06 +4846 4733 69374999.9886 +4860 4733 -21679861.11823 +4861 4733 -17343750.0057 +4863 4733 -86719444.43019 +4864 4733 -2.682209014893e-07 +4866 4733 -21679861.11823 +4867 4733 17343750.00569 +4734 4734 1483949894.094 +4735 4734 7.867813110352e-06 +4736 4734 -5.507469177246e-05 +4737 4734 184322301.8864 +4738 4734 -2.622604370117e-06 +4739 4734 -1.358985900879e-05 +4752 4734 -148365426.1266 +4753 4734 -97222222.20624 +4754 4734 -3.039836883545e-06 +4755 4734 -406796532.3944 +4756 4734 -2.801418304443e-06 +4757 4734 -1.233816146851e-05 +4758 4734 -148365426.1266 +4759 4734 97222222.20624 +4760 4734 -3.308057785034e-06 +4824 4734 -46373434.23613 +4825 4734 24305555.56354 +4827 4734 -138827443.8752 +4828 4734 2.682209014893e-07 +4830 4734 -46373434.23614 +4831 4734 -24305555.56354 +4842 4734 8952264.76783 +4843 4734 9.298324584961e-06 +4845 4734 222474230.8735 +4846 4734 3.933906555176e-06 +4848 4734 8952264.76783 +4849 4734 -1.302361488342e-05 +4863 4734 -46373434.23611 +4864 4734 -24305555.56353 +4866 4734 -138827443.8751 +4867 4734 -5.066394805908e-07 +4869 4734 -46373434.23611 +4870 4734 24305555.56353 +4735 4735 1250608048.648 +4736 4735 -1.192092895508e-06 +4737 4735 -3.159046173096e-06 +4738 4735 -185121779.2034 +4739 4735 8.046627044678e-07 +4752 4735 -97222222.20624 +4753 4735 -119197695.4315 +4754 4735 2.831220626831e-07 +4755 4735 -3.09944152832e-06 +4756 4735 20983010.02827 +4757 4735 -4.768371582031e-07 +4758 4735 97222222.20624 +4759 4735 -119197695.4315 +4760 4735 -7.450580596924e-08 +4824 4735 24305555.56354 +4825 4735 -39081501.55876 +4827 4735 -2.294778823853e-06 +4828 4735 -31882558.21685 +4830 4735 -24305555.56354 +4831 4735 -39081501.55876 +4842 4735 1.069903373718e-05 +4843 4735 -83408755.55014 +4845 4735 4.410743713379e-06 +4846 4735 164138769.4832 +4848 4735 -1.156330108643e-05 +4849 4735 -83408755.55014 +4863 4735 -24305555.56353 +4864 4735 -39081501.55875 +4866 4735 -8.344650268555e-07 +4867 4735 -31882558.21681 +4869 4735 24305555.56353 +4870 4735 -39081501.55875 +4736 4736 1165825984.246 +4737 4736 -1.382827758789e-05 +4738 4736 1.788139343262e-07 +4739 4736 104791324.3853 +4752 4736 -2.890825271606e-06 +4753 4736 3.8743019104e-07 +4754 4736 -46719419.49861 +4755 4736 -1.20997428894e-05 +4756 4736 -4.768371582031e-07 +4757 4736 -212506.0825927 +4758 4736 -3.278255462646e-06 +4759 4736 -2.086162567139e-07 +4760 4736 -46719419.49861 +4824 4736 21679861.11823 +4825 4736 -17343750.0057 +4827 4736 86719444.4302 +4828 4736 3.427267074585e-07 +4830 4736 21679861.11823 +4831 4736 17343750.0057 +4842 4736 6.169080734253e-06 +4843 4736 -69374999.9886 +4845 4736 2.598762512207e-05 +4846 4736 5.960464477539e-08 +4848 4736 6.973743438721e-06 +4849 4736 69374999.9886 +4863 4736 -21679861.11823 +4864 4736 -17343750.0057 +4866 4736 -86719444.43019 +4867 4736 -2.682209014893e-07 +4869 4736 -21679861.11823 +4870 4736 17343750.00569 +4737 4737 1483949894.094 +4738 4737 7.867813110352e-06 +4739 4737 -5.507469177246e-05 +4740 4737 184322301.8864 +4741 4737 -2.622604370117e-06 +4742 4737 -1.358985900879e-05 +4755 4737 -148365426.1266 +4756 4737 -97222222.20624 +4757 4737 -3.039836883545e-06 +4758 4737 -406796532.3944 +4759 4737 -2.801418304443e-06 +4760 4737 -1.233816146851e-05 +4761 4737 -148365426.1266 +4762 4737 97222222.20624 +4763 4737 -3.308057785034e-06 +4827 4737 -46373434.23613 +4828 4737 24305555.56354 +4830 4737 -138827443.8752 +4831 4737 2.682209014893e-07 +4833 4737 -46373434.23614 +4834 4737 -24305555.56354 +4845 4737 8952264.76783 +4846 4737 9.298324584961e-06 +4848 4737 222474230.8735 +4849 4737 3.933906555176e-06 +4851 4737 8952264.76783 +4852 4737 -1.302361488342e-05 +4866 4737 -46373434.23611 +4867 4737 -24305555.56353 +4869 4737 -138827443.8751 +4870 4737 -5.066394805908e-07 +4872 4737 -46373434.23611 +4873 4737 24305555.56353 +4738 4738 1250608048.648 +4739 4738 -1.192092895508e-06 +4740 4738 -3.159046173096e-06 +4741 4738 -185121779.2034 +4742 4738 8.046627044678e-07 +4755 4738 -97222222.20624 +4756 4738 -119197695.4315 +4757 4738 2.831220626831e-07 +4758 4738 -3.09944152832e-06 +4759 4738 20983010.02827 +4760 4738 -4.768371582031e-07 +4761 4738 97222222.20624 +4762 4738 -119197695.4315 +4763 4738 -7.450580596924e-08 +4827 4738 24305555.56354 +4828 4738 -39081501.55876 +4830 4738 -2.294778823853e-06 +4831 4738 -31882558.21685 +4833 4738 -24305555.56354 +4834 4738 -39081501.55876 +4845 4738 1.069903373718e-05 +4846 4738 -83408755.55014 +4848 4738 4.410743713379e-06 +4849 4738 164138769.4832 +4851 4738 -1.156330108643e-05 +4852 4738 -83408755.55014 +4866 4738 -24305555.56353 +4867 4738 -39081501.55875 +4869 4738 -8.344650268555e-07 +4870 4738 -31882558.21681 +4872 4738 24305555.56353 +4873 4738 -39081501.55875 +4739 4739 1165825984.246 +4740 4739 -1.382827758789e-05 +4741 4739 1.788139343262e-07 +4742 4739 104791324.3853 +4755 4739 -2.890825271606e-06 +4756 4739 3.8743019104e-07 +4757 4739 -46719419.49861 +4758 4739 -1.20997428894e-05 +4759 4739 -4.768371582031e-07 +4760 4739 -212506.0825927 +4761 4739 -3.278255462646e-06 +4762 4739 -2.086162567139e-07 +4763 4739 -46719419.49861 +4827 4739 21679861.11823 +4828 4739 -17343750.0057 +4830 4739 86719444.4302 +4831 4739 3.427267074585e-07 +4833 4739 21679861.11823 +4834 4739 17343750.0057 +4845 4739 6.169080734253e-06 +4846 4739 -69374999.9886 +4848 4739 2.598762512207e-05 +4849 4739 5.960464477539e-08 +4851 4739 6.973743438721e-06 +4852 4739 69374999.9886 +4866 4739 -21679861.11823 +4867 4739 -17343750.0057 +4869 4739 -86719444.43019 +4870 4739 -2.682209014893e-07 +4872 4739 -21679861.11823 +4873 4739 17343750.00569 +4740 4740 1661147708.835 +4741 4740 104975994.3213 +4742 4740 -2.908706665039e-05 +4743 4740 28973926.47986 +4744 4740 -93442034.30678 +4745 4740 -4.887580871582e-06 +4758 4740 -148365426.1266 +4759 4740 -97222222.20624 +4760 4740 -3.039836883545e-06 +4761 4740 -414750020.4149 +4762 4740 -3811573.076195 +4763 4740 -8.344650268555e-06 +4764 4740 -158390003.0581 +4765 4740 97090758.2817 +4766 4740 7.480382919312e-06 +4830 4740 -46373434.23613 +4831 4740 24305555.56354 +4833 4740 -180984988.3576 +4834 4740 -26203286.31793 +4848 4740 8952264.76783 +4849 4740 9.298324584961e-06 +4851 4740 274245586.3935 +4852 4740 26243998.59327 +4854 4740 -25967702.04294 +4855 4740 -23360508.5882 +4869 4740 -46373434.23611 +4870 4740 -24305555.56353 +4872 4740 -140996480.1669 +4873 4740 -952893.2695205 +4875 4740 -48879322.66664 +4876 4740 24272689.58238 +4741 4741 1378316574.243 +4742 4741 2.241134643555e-05 +4743 4741 -93442033.91789 +4744 4741 -311076053.7848 +4745 4741 -1.373887062073e-05 +4758 4741 -97222222.20624 +4759 4741 -119197695.4315 +4760 4741 2.831220626831e-07 +4761 4741 -3811573.076215 +4762 4741 16672797.27744 +4763 4741 6.914138793945e-06 +4764 4741 97090758.2817 +4765 4741 -116180339.9824 +4766 4741 -2.041459083557e-06 +4830 4741 24305555.56354 +4831 4741 -39081501.55876 +4833 4741 -26203286.41514 +4834 4741 -65895674.85389 +4848 4741 1.069903373718e-05 +4849 4741 -83408755.55014 +4851 4741 26243998.59327 +4852 4741 203537802.7108 +4854 4741 -23360508.49098 +4855 4741 -110980197.151 +4869 4741 -24305555.56353 +4870 4741 -39081501.55875 +4872 4741 -952893.2695257 +4873 4741 -33140775.69073 +4875 4741 24272689.58238 +4876 4741 -38326906.89252 +4742 4742 1227849607.294 +4743 4742 -3.337860107422e-06 +4744 4742 -1.326203346252e-05 +4745 4742 16993676.64498 +4758 4742 -2.890825271606e-06 +4759 4742 3.8743019104e-07 +4760 4742 -46719419.49861 +4761 4742 -1.120567321777e-05 +4762 4742 7.152557373047e-06 +4763 4742 -3046182.050739 +4764 4742 7.480382919312e-06 +4765 4742 -2.101063728333e-06 +4766 4742 -48631203.38775 +4830 4742 21679861.11823 +4831 4742 -17343750.0057 +4833 4742 88411110.90689 +4834 4742 18697916.56855 +4848 4742 6.169080734253e-06 +4849 4742 -69374999.9886 +4851 4742 -0.03792053461075 +4852 4742 -0.03034740686417 +4854 4742 21679166.091 +4855 4742 69374999.47419 +4869 4742 -21679861.11823 +4870 4742 -17343750.0057 +4872 4742 -87564583.31903 +4873 4742 -677083.3332888 +4875 4742 -22525694.45184 +4876 4742 16666666.67214 +4743 4743 878310888.4811 +4744 4743 -2657515.757653 +4745 4743 9.536743164063e-07 +4761 4743 -146355658.7119 +4762 4743 -97205456.75099 +4763 4743 -8.374452590942e-06 +4764 4743 -422227983.671 +4765 4743 -5136049.02384 +4766 4743 -9.536743164063e-07 +4767 4743 85600144.70805 +4768 4743 -16771033.13002 +4769 4743 -2.264976501465e-06 +4770 4743 -156881939.5358 +4771 4743 98545423.09952 +4772 4743 9.477138519287e-06 +4833 4743 -8767515.558543 +4834 4743 29166666.38459 +4851 4743 -25967702.04296 +4852 4743 -23360508.49098 +4854 4743 119740849.7095 +4855 4743 -664378.9397391 +4872 4743 -45870736.57863 +4873 4743 -24301364.19972 +4875 4743 -141002035.2672 +4876 4743 -1284012.256597 +4878 4743 4511607.610506 +4879 4743 -4192758.284571 +4881 4743 -47751770.62456 +4882 4743 24636355.78701 +4744 4744 904404472.7406 +4745 4744 3.480911254883e-05 +4761 4744 -97205456.75099 +4762 4744 -119802374.1366 +4763 4744 -2.965331077576e-06 +4764 4744 -5136049.023842 +4765 4744 9983783.088459 +4766 4744 1.490116119385e-05 +4767 4744 22117855.75249 +4768 4744 -98572068.6614 +4769 4744 -8.374452590942e-06 +4770 4744 98545423.09952 +4771 4744 -123363044.4244 +4772 4744 -3.159046173096e-06 +4833 4744 19444444.25639 +4834 4744 -7306349.825738 +4851 4744 -23360508.5882 +4852 4744 -110980197.151 +4854 4744 -664378.9397408 +4855 4744 126264245.7776 +4872 4744 -24301364.19972 +4873 4744 -39232415.43152 +4875 4744 -1284012.256598 +4876 4744 -32949093.52409 +4878 4744 5529463.940846 +4879 4744 -41531445.75453 +4881 4744 24636355.78701 +4882 4744 -39372046.84256 +4745 4745 768562010.6434 +4761 4745 -8.344650268555e-06 +4762 4745 -2.875924110413e-06 +4763 4745 -46336936.97175 +4764 4745 -5.364418029785e-07 +4765 4745 1.47819519043e-05 +4766 4745 -12181640.54623 +4767 4745 1.430511474609e-06 +4768 4745 -8.553266525269e-06 +4769 4745 44227455.0915 +4770 4745 9.089708328247e-06 +4771 4745 -3.17394733429e-06 +4772 4745 -52301561.26623 +4833 4745 18020555.17262 +4834 4745 -20270833.25379 +4851 4745 -21679166.28527 +4852 4745 -69374999.59699 +4854 4745 -17135277.77496 +4855 4745 -7208333.18586 +4872 4745 -21679166.67379 +4873 4745 -17343750.0057 +4875 4745 -85676388.87482 +4876 4745 -677083.3332884 +4878 4745 -4909027.779056 +4879 4745 33333333.32785 +4881 4745 -21159027.78472 +4882 4745 16666666.67214 +4746 4746 741974947.0469 +4747 4746 5.006790161133e-06 +4748 4746 -2.908706665039e-05 +4749 4746 92161150.94322 +4750 4746 19444444.44125 +4751 4746 -7.271766662598e-06 +4836 4746 -138827443.8752 +4837 4746 2.682209014893e-07 +4839 4746 -46373434.23614 +4840 4746 -24305555.56354 +4857 4746 111237115.4367 +4858 4746 -8.344650268555e-07 +4860 4746 4476132.383917 +4861 4746 4861111.1127 +4747 4747 625304024.3239 +4748 4747 6.198883056641e-06 +4749 4747 -19444444.44125 +4750 4747 -92560889.60172 +4751 4747 2.32458114624e-06 +4836 4747 -2.294778823853e-06 +4837 4747 -31882558.21685 +4839 4747 -24305555.56354 +4840 4747 -39081501.55876 +4857 4747 -7.152557373047e-07 +4858 4747 82069384.74161 +4860 4747 -4861111.112713 +4861 4747 -41704377.77507 +4748 4748 582912992.1231 +4749 4748 -7.271766662598e-06 +4750 4748 1.877546310425e-06 +4751 4748 52395662.19267 +4836 4748 86719444.4302 +4837 4748 3.427267074585e-07 +4839 4748 21679861.11823 +4840 4748 17343750.0057 +4857 4748 17343888.88605 +4858 4748 -3.576278686523e-06 +4860 4748 4335972.22365 +4861 4748 34687499.9943 +4749 4749 741974947.0469 +4750 4749 5.006790161133e-06 +4751 4749 -2.908706665039e-05 +4752 4749 92161150.94322 +4753 4749 19444444.44125 +4754 4749 -7.271766662598e-06 +4836 4749 -46373434.23613 +4837 4749 24305555.56354 +4839 4749 -138827443.8752 +4840 4749 2.682209014893e-07 +4842 4749 -46373434.23614 +4843 4749 -24305555.56354 +4857 4749 4476132.383914 +4858 4749 -4861111.112702 +4860 4749 111237115.4367 +4861 4749 -8.344650268555e-07 +4863 4749 4476132.383917 +4864 4749 4861111.1127 +4750 4750 625304024.3239 +4751 4750 6.198883056641e-06 +4752 4750 -19444444.44125 +4753 4750 -92560889.60172 +4754 4750 2.32458114624e-06 +4836 4750 24305555.56354 +4837 4750 -39081501.55876 +4839 4750 -2.294778823853e-06 +4840 4750 -31882558.21685 +4842 4750 -24305555.56354 +4843 4750 -39081501.55876 +4857 4750 4861111.112712 +4858 4750 -41704377.77507 +4860 4750 -7.152557373047e-07 +4861 4750 82069384.74161 +4863 4750 -4861111.112713 +4864 4750 -41704377.77507 +4751 4751 582912992.1231 +4752 4751 -7.271766662598e-06 +4753 4751 1.877546310425e-06 +4754 4751 52395662.19267 +4836 4751 21679861.11823 +4837 4751 -17343750.0057 +4839 4751 86719444.4302 +4840 4751 3.427267074585e-07 +4842 4751 21679861.11823 +4843 4751 17343750.0057 +4857 4751 4335972.223649 +4858 4751 -34687499.9943 +4860 4751 17343888.88605 +4861 4751 -3.576278686523e-06 +4863 4751 4335972.22365 +4864 4751 34687499.9943 +4752 4752 741974947.0469 +4753 4752 5.006790161133e-06 +4754 4752 -2.908706665039e-05 +4755 4752 92161150.94322 +4756 4752 19444444.44125 +4757 4752 -7.271766662598e-06 +4839 4752 -46373434.23613 +4840 4752 24305555.56354 +4842 4752 -138827443.8752 +4843 4752 2.682209014893e-07 +4845 4752 -46373434.23614 +4846 4752 -24305555.56354 +4860 4752 4476132.383914 +4861 4752 -4861111.112702 +4863 4752 111237115.4367 +4864 4752 -8.344650268555e-07 +4866 4752 4476132.383917 +4867 4752 4861111.1127 +4753 4753 625304024.3239 +4754 4753 6.198883056641e-06 +4755 4753 -19444444.44125 +4756 4753 -92560889.60172 +4757 4753 2.32458114624e-06 +4839 4753 24305555.56354 +4840 4753 -39081501.55876 +4842 4753 -2.294778823853e-06 +4843 4753 -31882558.21685 +4845 4753 -24305555.56354 +4846 4753 -39081501.55876 +4860 4753 4861111.112712 +4861 4753 -41704377.77507 +4863 4753 -7.152557373047e-07 +4864 4753 82069384.74161 +4866 4753 -4861111.112713 +4867 4753 -41704377.77507 +4754 4754 582912992.1231 +4755 4754 -7.271766662598e-06 +4756 4754 1.877546310425e-06 +4757 4754 52395662.19267 +4839 4754 21679861.11823 +4840 4754 -17343750.0057 +4842 4754 86719444.4302 +4843 4754 3.427267074585e-07 +4845 4754 21679861.11823 +4846 4754 17343750.0057 +4860 4754 4335972.223649 +4861 4754 -34687499.9943 +4863 4754 17343888.88605 +4864 4754 -3.576278686523e-06 +4866 4754 4335972.22365 +4867 4754 34687499.9943 +4755 4755 741974947.0469 +4756 4755 5.006790161133e-06 +4757 4755 -2.908706665039e-05 +4758 4755 92161150.94322 +4759 4755 19444444.44125 +4760 4755 -7.271766662598e-06 +4842 4755 -46373434.23613 +4843 4755 24305555.56354 +4845 4755 -138827443.8752 +4846 4755 2.682209014893e-07 +4848 4755 -46373434.23614 +4849 4755 -24305555.56354 +4863 4755 4476132.383914 +4864 4755 -4861111.112702 +4866 4755 111237115.4367 +4867 4755 -8.344650268555e-07 +4869 4755 4476132.383917 +4870 4755 4861111.1127 +4756 4756 625304024.3239 +4757 4756 6.198883056641e-06 +4758 4756 -19444444.44125 +4759 4756 -92560889.60172 +4760 4756 2.32458114624e-06 +4842 4756 24305555.56354 +4843 4756 -39081501.55876 +4845 4756 -2.294778823853e-06 +4846 4756 -31882558.21685 +4848 4756 -24305555.56354 +4849 4756 -39081501.55876 +4863 4756 4861111.112712 +4864 4756 -41704377.77507 +4866 4756 -7.152557373047e-07 +4867 4756 82069384.74161 +4869 4756 -4861111.112713 +4870 4756 -41704377.77507 +4757 4757 582912992.1231 +4758 4757 -7.271766662598e-06 +4759 4757 1.877546310425e-06 +4760 4757 52395662.19267 +4842 4757 21679861.11823 +4843 4757 -17343750.0057 +4845 4757 86719444.4302 +4846 4757 3.427267074585e-07 +4848 4757 21679861.11823 +4849 4757 17343750.0057 +4863 4757 4335972.223649 +4864 4757 -34687499.9943 +4866 4757 17343888.88605 +4867 4757 -3.576278686523e-06 +4869 4757 4335972.22365 +4870 4757 34687499.9943 +4758 4758 741974947.0469 +4759 4758 5.006790161133e-06 +4760 4758 -2.908706665039e-05 +4761 4758 92161150.94322 +4762 4758 19444444.44125 +4763 4758 -7.271766662598e-06 +4845 4758 -46373434.23613 +4846 4758 24305555.56354 +4848 4758 -138827443.8752 +4849 4758 2.682209014893e-07 +4851 4758 -46373434.23614 +4852 4758 -24305555.56354 +4866 4758 4476132.383914 +4867 4758 -4861111.112702 +4869 4758 111237115.4367 +4870 4758 -8.344650268555e-07 +4872 4758 4476132.383917 +4873 4758 4861111.1127 +4759 4759 625304024.3239 +4760 4759 6.198883056641e-06 +4761 4759 -19444444.44125 +4762 4759 -92560889.60172 +4763 4759 2.32458114624e-06 +4845 4759 24305555.56354 +4846 4759 -39081501.55876 +4848 4759 -2.294778823853e-06 +4849 4759 -31882558.21685 +4851 4759 -24305555.56354 +4852 4759 -39081501.55876 +4866 4759 4861111.112712 +4867 4759 -41704377.77507 +4869 4759 -7.152557373047e-07 +4870 4759 82069384.74161 +4872 4759 -4861111.112713 +4873 4759 -41704377.77507 +4760 4760 582912992.1231 +4761 4760 -7.271766662598e-06 +4762 4760 1.877546310425e-06 +4763 4760 52395662.19267 +4845 4760 21679861.11823 +4846 4760 -17343750.0057 +4848 4760 86719444.4302 +4849 4760 3.427267074585e-07 +4851 4760 21679861.11823 +4852 4760 17343750.0057 +4866 4760 4335972.223649 +4867 4760 -34687499.9943 +4869 4760 17343888.88605 +4870 4760 -3.576278686523e-06 +4872 4760 4335972.22365 +4873 4760 34687499.9943 +4761 4761 743972693.3093 +4762 4761 15895.84582305 +4763 4761 -1.215934753418e-05 +4764 4761 96103889.57231 +4765 4761 23223356.21639 +4766 4761 2.145767211914e-06 +4848 4761 -46373434.23613 +4849 4761 24305555.56354 +4851 4761 -140996480.167 +4852 4761 -952893.2695176 +4854 4761 -45870736.57862 +4855 4761 -24301364.19972 +4869 4761 4476132.383914 +4870 4761 -4861111.112702 +4872 4761 111737658.2526 +4873 4761 3973.961454272 +4875 4761 5643546.059514 +4876 4761 5805839.056956 +4762 4762 624700330.4184 +4763 4762 2.026557922363e-05 +4764 4762 -15665532.66612 +4765 4762 -87045539.95471 +4766 4762 -4.470348358154e-06 +4848 4762 24305555.56354 +4849 4762 -39081501.55876 +4851 4762 -952893.2695167 +4852 4762 -33140775.69075 +4854 4762 -24301364.19972 +4855 4762 -39232415.43151 +4869 4762 4861111.112712 +4870 4762 -41704377.77507 +4872 4762 3973.961453795 +4873 4762 81919567.51518 +4875 4762 -3916383.16846 +4876 4762 -40143811.34479 +4763 4763 583290059.4325 +4764 4763 -1.192092895508e-06 +4765 4763 -4.589557647705e-06 +4766 4763 54461159.75297 +4848 4763 21679861.11823 +4849 4763 -17343750.0057 +4851 4763 87564583.31887 +4852 4763 677083.3331556 +4854 4763 21679166.67378 +4855 4763 17343750.00569 +4869 4763 4335972.223649 +4870 4763 -34687499.9943 +4872 4763 17343611.10827 +4873 4763 -2.473592758179e-06 +4875 4763 3489305.557201 +4876 4763 34010416.66114 +4764 4764 745987487.9304 +4765 4764 -2453991.979034 +4766 4764 -2.622604370117e-06 +4767 4764 -141080087.6866 +4768 4764 -95899021.31305 +4769 4764 -8.359551429749e-06 +4770 4764 92610986.19902 +4771 4764 22063836.70035 +4772 4764 1.430511474609e-06 +4851 4764 -48879322.66665 +4852 4764 24272689.58238 +4854 4764 -141002035.2672 +4855 4764 -1284012.256585 +4872 4764 5643546.059495 +4873 4764 -3916383.168461 +4875 4764 115620942.6217 +4876 4764 -613497.9950649 +4878 4764 -43801307.6603 +4879 4764 -23974755.34007 +4881 4764 5916032.269884 +4882 4764 5515959.177805 +4765 4765 616411761.6306 +4766 4765 3.147125244141e-05 +4767 4765 -95899021.31305 +4768 4765 -117437349.9809 +4769 4765 -3.337860107422e-06 +4770 4765 -16825052.18216 +4771 4765 -92728025.51492 +4772 4765 -4.708766937256e-06 +4851 4765 24272689.58238 +4852 4765 -38326906.89253 +4854 4765 -1284012.256586 +4855 4765 -32949093.52409 +4872 4765 5805839.056957 +4873 4765 -40143811.34482 +4875 4765 -613497.9950616 +4876 4765 83227011.03075 +4878 4765 -23974755.34007 +4879 4765 -37890623.23096 +4881 4765 -4206263.047611 +4882 4765 -40418720.68142 +4766 4766 572020605.8755 +4767 4766 -8.553266525269e-06 +4768 4766 -3.397464752197e-06 +4769 4766 -46375866.82275 +4770 4766 -1.907348632813e-06 +4771 4766 -4.738569259644e-06 +4772 4766 48718383.22462 +4851 4766 22525694.45184 +4852 4766 -16666666.67214 +4854 4766 85676388.87482 +4855 4766 677083.3331557 +4872 4766 5182361.11248 +4873 4766 -34010416.66102 +4875 4766 17135277.77496 +4876 4766 -1.698732376099e-06 +4878 4766 20312500.00667 +4879 4766 16666666.67214 +4881 4766 3385277.779223 +4882 4766 33333333.32785 +4767 4767 361120236.1714 +4768 4767 94548810.89505 +4769 4767 1.120567321777e-05 +4770 4767 -203961436.0496 +4771 4767 -20767645.33449 +4772 4767 -3.635883331299e-06 +4854 4767 4511607.610492 +4855 4767 5529463.940847 +4875 4767 -43801307.66031 +4876 4767 -23974755.34007 +4878 4767 56503201.94985 +4879 4767 23637202.73541 +4881 4767 -68052930.47169 +4882 4767 -5191911.336183 +4768 4768 308313282.913 +4769 4768 1.609325408936e-05 +4770 4768 18121243.54802 +4771 4768 9374992.872524 +4772 4768 7.987022399902e-06 +4854 4768 -4192758.284571 +4855 4768 -41531445.75455 +4875 4768 -23974755.34007 +4876 4768 -37890623.23097 +4878 4768 23637202.73541 +4879 4768 43301463.62875 +4881 4768 4530310.889234 +4882 4768 -14718823.21488 +4769 4769 278103282.9517 +4770 4769 5.364418029785e-07 +4771 4769 7.927417755127e-06 +4772 4769 -4811252.171694 +4854 4769 -3215972.223779 +4855 4769 -33333333.32786 +4875 4769 -20312500.00667 +4876 4769 -16666666.67214 +4878 4769 -8124999.998662 +4879 4769 -6666666.665569 +4881 4769 -41471527.77088 +4882 4769 -3333333.334428 +4770 4770 371304389.3859 +4771 4770 -99841614.46538 +4772 4770 -9.536743164063e-06 +4854 4770 -47751770.62457 +4855 4770 24636355.78702 +4875 4770 5916032.269866 +4876 4770 -4206263.047612 +4878 4770 -68052930.47169 +4879 4770 4530310.889241 +4881 4770 58352668.82662 +4882 4770 -24960403.62864 +4771 4771 309788077.0663 +4772 4771 1.561641693115e-05 +4854 4771 24636355.78702 +4855 4771 -39372046.84257 +4875 4771 5515959.177806 +4876 4771 -40418720.68145 +4878 4771 -5191911.336177 +4879 4771 -14718823.21488 +4881 4771 -24960403.62864 +4882 4771 42973590.73913 +4772 4772 283253096.8787 +4854 4772 21159027.78473 +4855 4772 -16666666.67214 +4875 4772 5078333.334502 +4876 4772 -33333333.32786 +4878 4772 41471527.77105 +4879 4772 -3333333.334428 +4881 4772 8463611.109719 +4882 4772 -6666666.665572 +4773 4773 463734339.079 +4774 4773 48611111.10311 +4776 4773 -286863054.9654 +4777 4773 -48611110.71422 +4779 4773 9282077.504984 +4780 4773 38888888.4936 +4774 4774 390815012.8075 +4776 4774 -48611110.51978 +4777 4774 -58389419.62183 +4779 4774 58333332.7404 +4780 4774 9282077.504984 +4775 4775 1 +4776 4776 816157657.6872 +4777 4776 48611110.13091 +4779 4776 8696360.488349 +4780 4776 -48611110.71423 +4782 4776 -203398266.1972 +4783 4776 -2.920627593994e-06 +4785 4776 -74182713.06331 +4786 4776 48611111.10312 +4777 4777 684902870.0541 +4779 4777 -48611110.51978 +4780 4777 -161441813.9313 +4782 4777 -2.801418304443e-06 +4783 4777 10491505.01414 +4785 4777 48611111.10312 +4786 4777 -59598847.71575 +4778 4778 1 +4779 4779 463734339.079 +4780 4779 48611111.10311 +4782 4779 -74182713.06331 +4783 4779 -48611111.10312 +4785 4779 -286863054.9654 +4786 4779 -48611110.71422 +4788 4779 9282077.504984 +4789 4779 38888888.4936 +4780 4780 390815012.8075 +4782 4780 -48611111.10312 +4783 4780 -59598847.71576 +4785 4780 -48611110.51978 +4786 4780 -58389419.62183 +4788 4780 58333332.7404 +4789 4780 9282077.504984 +4781 4781 1 +4782 4782 741974947.0469 +4783 4782 1.335144042969e-05 +4785 4782 92161150.94322 +4786 4782 -4.291534423828e-06 +4791 4782 -203398266.1972 +4792 4782 -2.920627593994e-06 +4794 4782 -74182713.06331 +4795 4782 48611111.10312 +4783 4783 625304024.3239 +4785 4783 -1.192092895508e-07 +4786 4783 -92560889.60172 +4791 4783 -2.801418304443e-06 +4792 4783 10491505.01414 +4794 4783 48611111.10312 +4795 4783 -59598847.71575 +4784 4784 1 +4785 4785 816157657.6872 +4786 4785 48611110.13091 +4788 4785 8696360.488349 +4789 4785 -48611110.71423 +4791 4785 -74182713.06331 +4792 4785 -48611111.10312 +4794 4785 -203398266.1972 +4795 4785 -2.920627593994e-06 +4797 4785 -74182713.06331 +4798 4785 48611111.10312 +4786 4786 684902870.0541 +4788 4786 -48611110.51978 +4789 4786 -161441813.9313 +4791 4786 -48611111.10312 +4792 4786 -59598847.71576 +4794 4786 -2.801418304443e-06 +4795 4786 10491505.01414 +4797 4786 48611111.10312 +4798 4786 -59598847.71575 +4787 4787 1 +4788 4788 463734339.079 +4789 4788 48611111.10311 +4794 4788 -74182713.06331 +4795 4788 -48611111.10312 +4797 4788 -286863054.9654 +4798 4788 -48611110.71422 +4800 4788 9282077.504984 +4801 4788 38888888.4936 +4789 4789 390815012.8075 +4794 4789 -48611111.10312 +4795 4789 -59598847.71576 +4797 4789 -48611110.51978 +4798 4789 -58389419.62183 +4800 4789 58333332.7404 +4801 4789 9282077.504984 +4790 4790 1 +4791 4791 741974947.0469 +4792 4791 1.335144042969e-05 +4794 4791 92161150.94322 +4795 4791 -4.291534423828e-06 +4803 4791 -203398266.1972 +4804 4791 -2.920627593994e-06 +4806 4791 -74182713.06331 +4807 4791 48611111.10312 +4792 4792 625304024.3239 +4794 4792 -1.192092895508e-07 +4795 4792 -92560889.60172 +4803 4792 -2.801418304443e-06 +4804 4792 10491505.01414 +4806 4792 48611111.10312 +4807 4792 -59598847.71575 +4793 4793 1 +4794 4794 741974947.0469 +4795 4794 1.335144042969e-05 +4797 4794 92161150.94322 +4798 4794 -4.291534423828e-06 +4803 4794 -74182713.06331 +4804 4794 -48611111.10312 +4806 4794 -203398266.1972 +4807 4794 -2.920627593994e-06 +4809 4794 -74182713.06331 +4810 4794 48611111.10312 +4795 4795 625304024.3239 +4797 4795 -1.192092895508e-07 +4798 4795 -92560889.60172 +4803 4795 -48611111.10312 +4804 4795 -59598847.71576 +4806 4795 -2.801418304443e-06 +4807 4795 10491505.01414 +4809 4795 48611111.10312 +4810 4795 -59598847.71575 +4796 4796 1 +4797 4797 816157657.6872 +4798 4797 48611110.13091 +4800 4797 8696360.488349 +4801 4797 -48611110.71423 +4806 4797 -74182713.06331 +4807 4797 -48611111.10312 +4809 4797 -203398266.1972 +4810 4797 -2.920627593994e-06 +4812 4797 -74182713.06331 +4813 4797 48611111.10312 +4798 4798 684902870.0541 +4800 4798 -48611110.51978 +4801 4798 -161441813.9313 +4806 4798 -48611111.10312 +4807 4798 -59598847.71576 +4809 4798 -2.801418304443e-06 +4810 4798 10491505.01414 +4812 4798 48611111.10312 +4813 4798 -59598847.71575 +4799 4799 1 +4800 4800 463734339.079 +4801 4800 48611111.10311 +4809 4800 -74182713.06331 +4810 4800 -48611111.10312 +4812 4800 -286863054.9654 +4813 4800 -48611110.71422 +4815 4800 9282077.504984 +4816 4800 38888888.4936 +4801 4801 390815012.8075 +4809 4801 -48611111.10312 +4810 4801 -59598847.71576 +4812 4801 -48611110.51978 +4813 4801 -58389419.62183 +4815 4801 58333332.7404 +4816 4801 9282077.504984 +4802 4802 1 +4803 4803 741974947.0469 +4804 4803 1.335144042969e-05 +4806 4803 92161150.94322 +4807 4803 -4.291534423828e-06 +4818 4803 -203398266.1972 +4819 4803 -2.920627593994e-06 +4821 4803 -74182713.06331 +4822 4803 48611111.10312 +4804 4804 625304024.3239 +4806 4804 -1.192092895508e-07 +4807 4804 -92560889.60172 +4818 4804 -2.801418304443e-06 +4819 4804 10491505.01414 +4821 4804 48611111.10312 +4822 4804 -59598847.71575 +4805 4805 1 +4806 4806 741974947.0469 +4807 4806 1.335144042969e-05 +4809 4806 92161150.94322 +4810 4806 -4.291534423828e-06 +4818 4806 -74182713.06331 +4819 4806 -48611111.10312 +4821 4806 -203398266.1972 +4822 4806 -2.920627593994e-06 +4824 4806 -74182713.06331 +4825 4806 48611111.10312 +4807 4807 625304024.3239 +4809 4807 -1.192092895508e-07 +4810 4807 -92560889.60172 +4818 4807 -48611111.10312 +4819 4807 -59598847.71576 +4821 4807 -2.801418304443e-06 +4822 4807 10491505.01414 +4824 4807 48611111.10312 +4825 4807 -59598847.71575 +4808 4808 1 +4809 4809 741974947.0469 +4810 4809 1.335144042969e-05 +4812 4809 92161150.94322 +4813 4809 -4.291534423828e-06 +4821 4809 -74182713.06331 +4822 4809 -48611111.10312 +4824 4809 -203398266.1972 +4825 4809 -2.920627593994e-06 +4827 4809 -74182713.06331 +4828 4809 48611111.10312 +4810 4810 625304024.3239 +4812 4810 -1.192092895508e-07 +4813 4810 -92560889.60172 +4821 4810 -48611111.10312 +4822 4810 -59598847.71576 +4824 4810 -2.801418304443e-06 +4825 4810 10491505.01414 +4827 4810 48611111.10312 +4828 4810 -59598847.71575 +4811 4811 1 +4812 4812 816157657.6872 +4813 4812 48611110.13091 +4815 4812 8696360.488349 +4816 4812 -48611110.71423 +4824 4812 -74182713.06331 +4825 4812 -48611111.10312 +4827 4812 -203398266.1972 +4828 4812 -2.920627593994e-06 +4830 4812 -74182713.06331 +4831 4812 48611111.10312 +4813 4813 684902870.0541 +4815 4813 -48611110.51978 +4816 4813 -161441813.9313 +4824 4813 -48611111.10312 +4825 4813 -59598847.71576 +4827 4813 -2.801418304443e-06 +4828 4813 10491505.01414 +4830 4813 48611111.10312 +4831 4813 -59598847.71575 +4814 4814 1 +4815 4815 463734339.079 +4816 4815 48611111.10311 +4827 4815 -74182713.06331 +4828 4815 -48611111.10312 +4830 4815 -286863054.9654 +4831 4815 -48611110.71422 +4833 4815 9282077.504984 +4834 4815 38888888.4936 +4816 4816 390815012.8075 +4827 4816 -48611111.10312 +4828 4816 -59598847.71576 +4830 4816 -48611110.51978 +4831 4816 -58389419.62183 +4833 4816 58333332.7404 +4834 4816 9282077.504984 +4817 4817 1 +4818 4818 741974947.0469 +4819 4818 1.335144042969e-05 +4821 4818 92161150.94322 +4822 4818 -4.291534423828e-06 +4836 4818 -203398266.1972 +4837 4818 -2.920627593994e-06 +4839 4818 -74182713.06331 +4840 4818 48611111.10312 +4819 4819 625304024.3239 +4821 4819 -1.192092895508e-07 +4822 4819 -92560889.60172 +4836 4819 -2.801418304443e-06 +4837 4819 10491505.01414 +4839 4819 48611111.10312 +4840 4819 -59598847.71575 +4820 4820 1 +4821 4821 741974947.0469 +4822 4821 1.335144042969e-05 +4824 4821 92161150.94322 +4825 4821 -4.291534423828e-06 +4836 4821 -74182713.06331 +4837 4821 -48611111.10312 +4839 4821 -203398266.1972 +4840 4821 -2.920627593994e-06 +4842 4821 -74182713.06331 +4843 4821 48611111.10312 +4822 4822 625304024.3239 +4824 4822 -1.192092895508e-07 +4825 4822 -92560889.60172 +4836 4822 -48611111.10312 +4837 4822 -59598847.71576 +4839 4822 -2.801418304443e-06 +4840 4822 10491505.01414 +4842 4822 48611111.10312 +4843 4822 -59598847.71575 +4823 4823 1 +4824 4824 741974947.0469 +4825 4824 1.335144042969e-05 +4827 4824 92161150.94322 +4828 4824 -4.291534423828e-06 +4839 4824 -74182713.06331 +4840 4824 -48611111.10312 +4842 4824 -203398266.1972 +4843 4824 -2.920627593994e-06 +4845 4824 -74182713.06331 +4846 4824 48611111.10312 +4825 4825 625304024.3239 +4827 4825 -1.192092895508e-07 +4828 4825 -92560889.60172 +4839 4825 -48611111.10312 +4840 4825 -59598847.71576 +4842 4825 -2.801418304443e-06 +4843 4825 10491505.01414 +4845 4825 48611111.10312 +4846 4825 -59598847.71575 +4826 4826 1 +4827 4827 741974947.0469 +4828 4827 1.335144042969e-05 +4830 4827 92161150.94322 +4831 4827 -4.291534423828e-06 +4842 4827 -74182713.06331 +4843 4827 -48611111.10312 +4845 4827 -203398266.1972 +4846 4827 -2.920627593994e-06 +4848 4827 -74182713.06331 +4849 4827 48611111.10312 +4828 4828 625304024.3239 +4830 4828 -1.192092895508e-07 +4831 4828 -92560889.60172 +4842 4828 -48611111.10312 +4843 4828 -59598847.71576 +4845 4828 -2.801418304443e-06 +4846 4828 10491505.01414 +4848 4828 48611111.10312 +4849 4828 -59598847.71575 +4829 4829 1 +4830 4830 816157657.6872 +4831 4830 48611110.13091 +4833 4830 8696360.488349 +4834 4830 -48611110.71423 +4845 4830 -74182713.06331 +4846 4830 -48611111.10312 +4848 4830 -203398266.1972 +4849 4830 -2.920627593994e-06 +4851 4830 -74182713.06331 +4852 4830 48611111.10312 +4831 4831 684902870.0541 +4833 4831 -48611110.51978 +4834 4831 -161441813.9313 +4845 4831 -48611111.10312 +4846 4831 -59598847.71576 +4848 4831 -2.801418304443e-06 +4849 4831 10491505.01414 +4851 4831 48611111.10312 +4852 4831 -59598847.71575 +4832 4832 1 +4833 4833 472113317.9279 +4834 4833 52406573.19334 +4848 4833 -74182713.06331 +4849 4833 -48611111.10312 +4851 4833 -295909020.1924 +4852 4833 -52406572.80447 +4854 4833 11397613.87671 +4855 4833 38888888.49362 +4834 4834 394566668.6419 +4848 4834 -48611111.10312 +4849 4834 -59598847.71576 +4851 4834 -52406572.61003 +4852 4834 -65730393.29849 +4854 4834 58333332.74044 +4855 4834 14319945.34088 +4835 4835 1 +4836 4836 741974947.0469 +4837 4836 1.335144042969e-05 +4839 4836 92161150.94322 +4840 4836 -4.291534423828e-06 +4857 4836 -203398266.1972 +4858 4836 -2.920627593994e-06 +4860 4836 -74182713.06331 +4861 4836 48611111.10312 +4837 4837 625304024.3239 +4839 4837 -1.192092895508e-07 +4840 4837 -92560889.60172 +4857 4837 -2.801418304443e-06 +4858 4837 10491505.01414 +4860 4837 48611111.10312 +4861 4837 -59598847.71575 +4838 4838 1 +4839 4839 741974947.0469 +4840 4839 1.335144042969e-05 +4842 4839 92161150.94322 +4843 4839 -4.291534423828e-06 +4857 4839 -74182713.06331 +4858 4839 -48611111.10312 +4860 4839 -203398266.1972 +4861 4839 -2.920627593994e-06 +4863 4839 -74182713.06331 +4864 4839 48611111.10312 +4840 4840 625304024.3239 +4842 4840 -1.192092895508e-07 +4843 4840 -92560889.60172 +4857 4840 -48611111.10312 +4858 4840 -59598847.71576 +4860 4840 -2.801418304443e-06 +4861 4840 10491505.01414 +4863 4840 48611111.10312 +4864 4840 -59598847.71575 +4841 4841 1 +4842 4842 741974947.0469 +4843 4842 1.335144042969e-05 +4845 4842 92161150.94322 +4846 4842 -4.291534423828e-06 +4860 4842 -74182713.06331 +4861 4842 -48611111.10312 +4863 4842 -203398266.1972 +4864 4842 -2.920627593994e-06 +4866 4842 -74182713.06331 +4867 4842 48611111.10312 +4843 4843 625304024.3239 +4845 4843 -1.192092895508e-07 +4846 4843 -92560889.60172 +4860 4843 -48611111.10312 +4861 4843 -59598847.71576 +4863 4843 -2.801418304443e-06 +4864 4843 10491505.01414 +4866 4843 48611111.10312 +4867 4843 -59598847.71575 +4844 4844 1 +4845 4845 741974947.0469 +4846 4845 1.335144042969e-05 +4848 4845 92161150.94322 +4849 4845 -4.291534423828e-06 +4863 4845 -74182713.06331 +4864 4845 -48611111.10312 +4866 4845 -203398266.1972 +4867 4845 -2.920627593994e-06 +4869 4845 -74182713.06331 +4870 4845 48611111.10312 +4846 4846 625304024.3239 +4848 4846 -1.192092895508e-07 +4849 4846 -92560889.60172 +4863 4846 -48611111.10312 +4864 4846 -59598847.71576 +4866 4846 -2.801418304443e-06 +4867 4846 10491505.01414 +4869 4846 48611111.10312 +4870 4846 -59598847.71575 +4847 4847 1 +4848 4848 741974947.0469 +4849 4848 1.335144042969e-05 +4851 4848 92161150.94322 +4852 4848 -4.291534423828e-06 +4866 4848 -74182713.06331 +4867 4848 -48611111.10312 +4869 4848 -203398266.1972 +4870 4848 -2.920627593994e-06 +4872 4848 -74182713.06331 +4873 4848 48611111.10312 +4849 4849 625304024.3239 +4851 4849 -1.192092895508e-07 +4852 4849 -92560889.60172 +4866 4849 -48611111.10312 +4867 4849 -59598847.71576 +4869 4849 -2.801418304443e-06 +4870 4849 10491505.01414 +4872 4849 48611111.10312 +4873 4849 -59598847.71575 +4850 4850 1 +4851 4851 830573854.4174 +4852 4851 52487997.16069 +4854 4851 14486963.23993 +4855 4851 -46721017.15339 +4869 4851 -74182713.06331 +4870 4851 -48611111.10312 +4872 4851 -207375010.2074 +4873 4851 -1905786.538097 +4875 4851 -79195001.52904 +4876 4851 48545379.14084 +4852 4852 689158287.1216 +4854 4852 -46721016.95895 +4855 4852 -155538026.8924 +4869 4852 -48611111.10312 +4870 4852 -59598847.71576 +4872 4852 -1905786.538106 +4873 4852 8336398.63873 +4875 4852 48545379.14084 +4876 4852 -58090169.9912 +4853 4853 1 +4854 4854 439155444.2405 +4855 4854 -1328757.878829 +4872 4854 -73177829.35596 +4873 4854 -48602728.37549 +4875 4854 -211113991.8355 +4876 4854 -2568024.51192 +4878 4854 42800072.35402 +4879 4854 -8385516.565012 +4881 4854 -78440969.76791 +4882 4854 49272711.54975 +4855 4855 452202236.3703 +4872 4855 -48602728.37549 +4873 4855 -59901187.06828 +4875 4855 -2568024.511923 +4876 4855 4991891.544235 +4878 4855 11058927.87624 +4879 4855 -49286034.33069 +4881 4855 49272711.54975 +4882 4855 -61681522.21217 +4856 4856 1 +4857 4857 370987473.5234 +4858 4857 6.914138793945e-06 +4860 4857 46080575.4716 +4861 4857 9722222.220623 +4858 4858 312652012.1619 +4860 4858 -9722222.220622 +4861 4858 -46280444.80086 +4859 4859 1 +4860 4860 370987473.5234 +4861 4860 6.914138793945e-06 +4863 4860 46080575.4716 +4864 4860 9722222.220623 +4861 4861 312652012.1619 +4863 4861 -9722222.220622 +4864 4861 -46280444.80086 +4862 4862 1 +4863 4863 370987473.5234 +4864 4863 6.914138793945e-06 +4866 4863 46080575.4716 +4867 4863 9722222.220623 +4864 4864 312652012.1619 +4866 4864 -9722222.220622 +4867 4864 -46280444.80086 +4865 4865 1 +4866 4866 370987473.5234 +4867 4866 6.914138793945e-06 +4869 4866 46080575.4716 +4870 4866 9722222.220623 +4867 4867 312652012.1619 +4869 4867 -9722222.220622 +4870 4867 -46280444.80086 +4868 4868 1 +4869 4869 370987473.5234 +4870 4869 6.914138793945e-06 +4872 4869 46080575.4716 +4873 4869 9722222.220623 +4870 4870 312652012.1619 +4872 4870 -9722222.220622 +4873 4870 -46280444.80086 +4871 4871 1 +4872 4872 371986346.6546 +4873 4872 7947.922919989 +4875 4872 48051944.78615 +4876 4872 11611678.10819 +4873 4873 312350165.2092 +4875 4873 -7832766.333059 +4876 4873 -43522769.97735 +4874 4874 1 +4875 4875 372993743.9652 +4876 4875 -1226995.989509 +4878 4875 -70540043.84328 +4879 4875 -47949510.65652 +4881 4875 46305493.09951 +4882 4875 11031918.35018 +4876 4876 308205880.8153 +4878 4876 -47949510.65652 +4879 4876 -58718674.99043 +4881 4876 -8412526.091075 +4882 4876 -46364012.75746 +4877 4877 1 +4878 4878 180560118.0857 +4879 4878 47274405.44752 +4881 4878 -101980718.0248 +4882 4878 -10383822.66724 +4879 4879 154156641.4565 +4881 4879 9060621.774008 +4882 4879 4687496.436255 +4880 4880 1 +4881 4881 185652194.6929 +4882 4881 -49920807.23268 +4882 4882 154894038.5331 +4883 4883 1 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/fs_183_1 b/OpenDSSC/klusolve/CSparse/Matrix/fs_183_1 new file mode 100644 index 0000000..7797188 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/fs_183_1 @@ -0,0 +1,1069 @@ +0 0 0.002560366756349 +1 0 -1.1708957011e-07 +19 0 -2.586020978498e-09 +20 0 -4.21919637073e-09 +21 0 -1.539733401845e-09 +22 0 -6.992289087251e-10 +23 0 -4.146605957406e-10 +25 0 -9.308915110713e-10 +26 0 -9.604355274254e-10 +41 0 2.171877777815e-10 +42 0 3.647892785308e-08 +43 0 -1.336119643102e-08 +48 0 1.408677324709e-08 +49 0 1.305985310558e-09 +50 0 -1.305985310558e-09 +55 0 1.913774718225e-09 +56 0 1.157436047015e-08 +58 0 8.188399588829e-10 +59 0 3.175236018339e-10 +60 0 2.641174449437e-10 +61 0 1.806834262368e-09 +63 0 1.282846930985e-09 +64 0 4.905553913699e-10 +66 0 -1.222950896396e-09 +67 0 3.400474955813e-09 +69 0 7.424492418032e-10 +70 0 2.273214423366e-10 +71 0 -5.283442852457e-09 +72 0 3.062630817767e-09 +73 0 3.065874619571e-10 +74 0 -5.094621858827e-11 +75 0 3.960494500802e-10 +77 0 4.877537231018e-10 +78 0 -4.040563386643e-11 +79 0 2.816301020271e-10 +80 0 5.826517970276e-10 +81 0 4.086508172586e-10 +82 0 -3.911529194823e-11 +83 0 2.678169982465e-10 +85 0 -8.092386069823e-11 +86 0 2.232108616543e-10 +88 0 -5.675705795258e-11 +89 0 2.189991319367e-10 +90 0 3.291028612829e-10 +91 0 2.716647717251e-10 +92 0 5.497860474784e-10 +93 0 6.707083412842e-10 +94 0 -4.570873073371e-11 +95 0 2.972566894958e-10 +97 0 -3.773121829515e-11 +98 0 3.084061767158e-10 +100 0 -7.635917326112e-11 +101 0 -9.31539362895e-11 +102 0 1.426533063689e-09 +103 0 -3.117499412749e-09 +104 0 3.663312222128e-10 +105 0 -1.573096874488e-09 +106 0 4.411931980445e-10 +108 0 5.849297948125e-10 +109 0 -5.849297948125e-10 +111 0 2.37578324949e-09 +112 0 -3.466111061052e-09 +113 0 3.907987277182e-10 +114 0 9.58833451452e-10 +115 0 4.195017191123e-10 +117 0 4.11819413623e-10 +118 0 -4.11819413623e-10 +121 0 1.09032781156e-09 +122 0 7.32132897605e-10 +123 0 -7.32132897605e-10 +124 0 4.496357023427e-10 +125 0 4.955473972382e-10 +126 0 7.153774580173e-10 +127 0 1.479748156533e-09 +128 0 6.992289087255e-10 +129 0 8.243559438288e-10 +130 0 9.604355274199e-10 +131 0 4.146605957404e-10 +132 0 4.353441138305e-10 +135 0 -1.811030893479e-25 +136 0 -3.789615200312e-08 +139 0 9.673369514853e-13 +143 0 -1.408677324709e-08 +157 0 -1.157436047015e-08 +158 0 -3.720608980593e-09 +159 0 -1.116096648379e-09 +160 0 -5.853406000804e-10 +161 0 -1.773402322355e-09 +162 0 -3.400474955813e-09 +163 0 -1.138498691883e-09 +164 0 -2.273214423366e-10 +165 0 -3.062630817767e-09 +166 0 -5.640474200845e-10 +167 0 -4.473480892354e-10 +168 0 -2.425148100789e-10 +169 0 -5.017279363293e-10 +170 0 -3.51893759306e-10 +171 0 -2.232108616543e-10 +172 0 -2.189991319367e-10 +173 0 -2.833941305492e-10 +174 0 -2.3393355343e-10 +175 0 -4.734268742175e-10 +176 0 -5.775544049947e-10 +178 0 -4.411931980445e-10 +181 0 -4.195017191123e-10 +0 1 -3.383430159138e-16 +1 1 0.002562768415974 +41 1 3.592572729579e-13 +42 1 6.776264827548e-09 +44 1 -1.22477633951e-08 +45 1 -6.776264827554e-09 +50 1 2.084654127474e-09 +51 1 -2.084654127467e-09 +52 1 -2.084654127479e-09 +56 1 6.232347945464e-09 +57 1 -6.232347945464e-09 +61 1 1.051739346752e-09 +62 1 -1.051739346751e-09 +64 1 2.855471681108e-10 +65 1 -2.855471681108e-10 +75 1 2.305362470616e-10 +76 1 -2.305362470616e-10 +83 1 1.558934765912e-10 +84 1 -1.558934765912e-10 +95 1 1.730300132886e-10 +96 1 -1.730300132886e-10 +98 1 1.795200133122e-10 +99 1 -1.795200133122e-10 +107 1 -7.358794192803e-10 +108 1 7.358794192803e-10 +109 1 1.097807355488e-09 +110 1 -1.097807355488e-09 +117 1 5.180953913322e-10 +118 1 8.609286077266e-10 +119 1 -8.609286077266e-10 +120 1 -5.180953913322e-10 +135 1 -7.712897469546e-25 +136 1 1.224776339511e-08 +139 1 -1.998289194383e-13 +140 1 -1.59089384321e-13 +146 1 -2.5e-06 +2 2 0.002580237047555 +48 2 3.732994910464e-11 +136 2 1.224776339511e-09 +141 2 -1.224776339511e-09 +142 2 -3.732994910478e-11 +143 2 -3.732994910464e-11 +145 2 -2e-05 +3 3 0.002560236106991 +136 3 3.215427927254e-10 +137 3 -3.215427927254e-10 +4 4 0.002560235791703 +136 4 6.25497283521e-12 +157 4 -6.25497283521e-12 +5 5 0.002560236045299 +55 5 -2.598512597553e-10 +136 5 2.598512597553e-10 +6 6 0.002560238207518 +63 6 -1.197293314616e-09 +69 6 -1.224776339511e-09 +136 6 2.422069654126e-09 +7 7 0.002560238204238 +58 7 -2.073248123406e-09 +59 7 -3.45541353901e-10 +136 7 2.418789477308e-09 +8 8 0.002560238221515 +73 8 -6.046973693266e-10 +77 8 -1.831369175675e-09 +136 8 2.436066545003e-09 +9 9 0.002560239760404 +79 9 -4.119702232899e-10 +80 9 -2.338209375429e-09 +81 9 -1.224776339511e-09 +136 9 3.974955938231e-09 +10 10 0.002560239292762 +90 10 -4.1197022329e-10 +91 10 -2.004179464654e-10 +92 10 -1.224776339511e-09 +93 10 -1.670149553878e-09 +136 10 3.507314063145e-09 +11 11 0.002560245365513 +19 11 -1.824940942984e-14 +41 11 1.824919610165e-14 +67 11 -9.580046406017e-09 +68 11 -1.824919610165e-14 +136 11 9.580046406017e-09 +12 12 0.002560267253745 +19 12 -6.406758531213e-14 +20 12 -6.406758531213e-14 +41 12 1.281355477283e-13 +42 12 -6.406777544864e-14 +68 12 -6.406777386417e-14 +72 12 -3.146816878888e-08 +136 12 3.146816878888e-08 +157 12 -6.406777386417e-14 +13 13 0.002560236483522 +124 13 -6.980733871843e-10 +136 13 6.980733871849e-10 +14 14 0.00256024291142 +102 14 -6.012538393961e-09 +136 14 7.125971429882e-09 +177 14 -1.113433035919e-09 +15 15 0.002560251373511 +114 15 -1.224776339511e-08 +136 15 1.558806250287e-08 +180 15 -3.340299107757e-09 +16 16 0.002560262507841 +111 16 -2.672239286205e-08 +136 16 2.672239286205e-08 +17 17 0.002560252486944 +121 17 -1.670149553878e-08 +136 17 1.670149553879e-08 +18 18 0.002560244136196 +122 18 -8.350747769391e-09 +136 18 8.350747769386e-09 +3 19 -1.019050359178e-08 +19 19 0.002560245975952 +42 19 -1.019050349627e-08 +44 19 -4.038103921654e-17 +47 19 0 +136 19 1.019050345554e-08 +137 19 0 +139 19 4.072997690462e-17 +3 20 0 +20 20 0.002560254946453 +42 20 0 +44 20 -1.865674463727e-17 +56 20 -1.916100433649e-08 +136 20 1.916100431562e-08 +139 20 2.087411316368e-17 +157 20 0 +3 21 0 +5 21 0 +21 21 0.002560258054109 +42 21 0 +55 21 0 +61 21 -2.226866071837e-08 +136 21 2.226866071836e-08 +3 22 0 +6 22 0 +11 22 0 +20 22 0 +22 22 0.002560252486944 +42 22 0 +63 22 0 +64 22 -1.670149553878e-08 +136 22 1.670149553866e-08 +3 23 0 +6 23 0 +23 23 0.002560252486944 +42 23 0 +69 23 0 +75 23 -1.67014955388e-08 +136 23 1.670149553893e-08 +3 24 0 +7 24 0 +12 24 0 +20 24 0 +24 24 0.002560237455598 +42 24 0 +59 24 0 +83 24 -1.670149553913e-09 +136 24 1.670149553913e-09 +3 25 0 +25 25 0.002560236342165 +56 25 0 +70 25 -5.567165179605e-10 +136 25 5.567165179645e-10 +157 25 0 +26 26 0.002560239571121 +55 26 0 +56 26 0 +60 26 -3.785672322123e-09 +136 26 3.78567232212e-09 +27 27 0.002560242132017 +55 27 0 +61 27 0 +89 27 -6.346568304741e-09 +136 27 6.346568305847e-09 +28 28 0.002560242132017 +56 28 0 +63 28 0 +64 28 0 +86 28 -6.346568304728e-09 +136 28 6.346568304223e-09 +157 28 0 +29 29 0.002560235785448 +56 29 0 +69 29 0 +75 29 0 +157 29 0 +19 30 -1.22477647953e-09 +30 30 0.002560237010225 +42 30 -1.224776353574e-09 +136 30 1.224776337829e-09 +20 31 -3.674329017938e-09 +31 31 0.002560239459777 +42 31 -3.67432901844e-09 +136 31 3.674329018535e-09 +32 32 0.002560280507511 +126 32 -4.472206250153e-08 +136 32 4.472206250153e-08 +33 33 0.002560311921433 +127 33 -7.613598441436e-08 +136 33 7.613598441436e-08 +34 34 0.002560335994421 +129 34 -1.002089732327e-07 +136 34 1.002089732327e-07 +35 35 0.002560272421112 +128 35 -3.663566345244e-08 +136 35 3.663566345244e-08 +36 36 0.002560307793476 +130 36 -7.200802816513e-08 +136 36 7.200802816513e-08 +37 37 0.002560274529531 +131 37 -3.874408291661e-08 +136 37 3.874408291661e-08 +38 38 0.002560246586652 +132 38 -1.080120422477e-08 +136 38 1.080120422477e-08 +39 39 0.002560297068413 +125 39 -6.128296525551e-08 +136 39 6.128296525557e-08 +40 40 0.002560250260078 +136 40 1.447462946702e-08 +179 40 -1.447462946694e-08 +0 41 0.01959713882917 +1 41 -0.0195734543737 +11 41 5.470666548231e-07 +12 41 1.045301631314e-06 +19 41 -1.06971747048e-06 +20 41 -5.22650815657e-07 +41 41 0.02219765160175 +42 41 -5.227136107366e-07 +68 41 -1.069713542891e-06 +135 41 0 +136 41 6.298045247717e-11 +138 41 0 +139 41 -2.368449673054e-05 +147 41 -1.5e-05 +157 41 -5.226505491834e-07 +0 42 12.85660947467 +1 42 -11.61477992426 +41 42 3.155818156655e-11 +42 42 14.10099940671 +45 42 -1.241829550736 +46 42 -3.95951429917e-08 +48 42 9.156397070899e-09 +54 42 -9.156402619557e-09 +135 42 -2.952908677967e-24 +136 42 -12.85660941827 +0 43 0 +1 43 -7.348658035297e-09 +43 43 0.002560243134106 +136 43 7.348658037033e-09 +1 44 0 +44 44 0.002615235874523 +52 44 -3e-05 +136 44 8.907464288464e-11 +139 44 -8.90746428735e-11 +144 44 -2.5e-05 +1 45 -0.009866610928398 +42 45 -0.009866610928589 +45 45 0.01242684671403 +42 46 -7.813937183221e-10 +44 46 0 +46 46 0.002590236566843 +53 46 -3e-05 +136 46 7.81394413174e-10 +139 46 2.086591291478e-17 +47 47 0.002560235789603 +136 47 4.154625999537e-12 +137 47 -4.154625999537e-12 +0 48 3.174471475334 +1 48 -3.174471475334 +2 48 0.007477326419287 +19 48 -4.660849919314e-09 +30 48 -4.651519116252e-09 +42 48 8.206737146991e-09 +48 48 3.18450906156 +54 48 -8.226488015661e-09 +55 48 2.3273038548e-10 +56 48 1.157409717687e-10 +58 48 6.432076925481e-11 +59 48 3.955350175667e-11 +60 48 2.130154064686e-11 +61 48 6.741586490436e-11 +63 48 1.015204377654e-10 +64 48 1.830397952409e-11 +66 48 -2.130154064686e-11 +67 48 2.742345777721e-10 +69 48 7.703276924401e-11 +70 48 1.832998873123e-11 +72 48 2.46989933294e-10 +73 48 3.397452682535e-11 +75 48 1.477973195675e-11 +77 48 3.607477030183e-11 +79 48 1.955892376855e-11 +80 48 4.046382400654e-11 +81 48 2.837604498868e-11 +86 48 1.800487364199e-11 +89 48 1.76602516474e-11 +90 48 2.285559077342e-11 +91 48 1.886317747758e-11 +92 48 3.818151608009e-11 +93 48 4.657598768421e-11 +95 48 1.109292684479e-11 +98 48 1.150907415902e-11 +142 48 -0.007477326380339 +143 48 -3.181948808246 +157 48 -1.157409717687e-10 +158 48 -3.001462503844e-10 +159 48 -7.541369609961e-11 +160 48 -3.955350175667e-11 +161 48 -1.198244172895e-10 +162 48 -2.742410800739e-10 +163 48 -9.181250120076e-11 +164 48 -1.832998873123e-11 +165 48 -2.469834309922e-10 +166 48 -4.548360098437e-11 +167 48 -3.607477030183e-11 +168 48 -1.955892376855e-11 +169 48 -4.046382400654e-11 +170 48 -2.838254729046e-11 +171 48 -1.800487364199e-11 +172 48 -1.76602516474e-11 +173 48 -2.285559077342e-11 +174 48 -1.886317747758e-11 +175 48 -3.818151608009e-11 +176 48 -4.657598768421e-11 +0 49 1.587235737478 +1 49 -1.587235737627 +49 49 1.589795973443 +50 49 -1.587235737657 +1 50 1.15969220199 +50 50 1.16225243772 +51 50 -1.159692201935 +52 50 -1.159692201935 +51 51 0.002560235785448 +52 52 0.002560235785448 +53 53 0.002560235785448 +54 54 0.002560235785448 +0 55 0.4920430785978 +1 55 -0.4920430786783 +48 55 1.760841129905e-10 +55 55 0.4946033146353 +143 55 -1.760846653791e-10 +158 55 -0.4920430788498 +0 56 4.126812917873 +1 56 -2.503243835186 +48 56 1.831229970625e-10 +56 56 5.752942236585 +57 56 -1.623569082708 +143 56 -1.83128052366e-10 +157 56 -4.126812918092 +1 57 -4.20505517238e-05 +56 57 -4.205055172407e-05 +57 57 0.002607286337172 +148 57 -5e-06 +0 58 0.5872772225917 +1 58 -0.5872772229227 +48 58 1.760985569519e-10 +58 58 0.5898374588947 +143 58 -1.76084666663e-10 +159 58 -0.5872772231093 +0 59 0.5872772226272 +1 59 -0.5872772228874 +48 59 1.761039768105e-10 +59 59 0.5898374588947 +143 59 -1.760846658855e-10 +160 59 -0.5872772231093 +0 60 0.4920430782541 +1 60 -0.4920430787321 +42 60 -0.4920430788507 +48 60 1.761058645096e-10 +60 60 0.4946033146353 +66 60 -0.4920430788499 +143 60 -1.760846663789e-10 +0 61 1.063447943607 +1 61 -0.611167985462 +48 61 1.760796391616e-10 +55 61 -1.063447944406 +61 61 1.518288138946 +62 61 -0.4522799587544 +143 61 -1.760846641892e-10 +1 62 -4.205055172351e-05 +61 62 -4.205055172407e-05 +62 62 0.002607286337172 +149 62 -5e-06 +0 63 0.587277222639 +1 63 -0.5872772229313 +48 63 1.760915824221e-10 +63 63 0.5898374588947 +143 63 -1.760846645129e-10 +161 63 -0.5872772231093 +0 64 1.063447944716 +1 64 -0.6111679856255 +48 64 1.760485001368e-10 +63 64 -1.063447944406 +64 64 1.518288138946 +65 64 -0.4522799587544 +143 64 -1.760846620023e-10 +1 65 -4.205055171448e-05 +64 65 -4.205055172407e-05 +65 65 0.002607286337172 +150 65 -5e-06 +56 66 0 +66 66 0.002560235785448 +0 67 0.4920430786916 +1 67 -0.4920430786737 +48 67 1.76087455517e-10 +67 67 0.4946033146353 +143 67 -1.760846658223e-10 +162 67 -0.4920430788499 +42 68 -4471.999999998 +68 68 2236.002560236 +0 69 0.4920430781392 +1 69 -0.4920430786817 +48 69 1.76081375747e-10 +69 69 0.4946033146558 +143 69 -1.760846641579e-10 +163 69 -0.4920430788704 +0 70 0.4920430784468 +1 70 -0.4920430787271 +48 70 1.76045894176e-10 +70 70 0.4946033146352 +143 70 -1.760846630309e-10 +164 70 -0.4920430788498 +3 71 0 +20 71 0 +71 71 0.002560235785448 +0 72 0.4920430786528 +1 72 -0.4920430786728 +48 72 1.760879170302e-10 +72 72 0.4946033146352 +143 72 -1.760846649084e-10 +165 72 -0.4920430788498 +0 73 0.5364856792436 +1 73 -0.4920430786501 +48 73 1.76076432387e-10 +73 73 0.5390459152896 +74 73 -0.04444260065442 +143 73 -1.760846654441e-10 +166 73 -0.4920430788498 +52 74 -3.000000000035e-05 +74 74 0.002590235785448 +0 75 1.063447942908 +1 75 -0.611167985407 +48 75 1.760890988945e-10 +69 75 -1.063447944406 +75 75 1.518288138946 +76 75 -0.4522799587544 +143 75 -1.760846677221e-10 +1 76 -4.20505517325e-05 +75 76 -4.205055172408e-05 +76 76 0.002607286337172 +151 76 -5e-06 +0 77 0.5364856784025 +1 77 -0.4920430785641 +48 77 1.760864303599e-10 +77 77 0.5390459152898 +78 77 -0.04444260065443 +143 77 -1.760846692902e-10 +167 77 -0.4920430788499 +52 78 -3.000000000004e-05 +78 78 0.002590235785448 +0 79 0.5714048638366 +1 79 -0.4920430788403 +48 79 1.761313366208e-10 +79 79 0.5739651015182 +82 79 -0.07936178688284 +143 79 -1.760846606554e-10 +168 79 -0.4920430788499 +0 80 0.5714048658603 +1 80 -0.4920430786621 +48 80 1.760978635704e-10 +80 80 0.5739651015181 +85 80 -0.07936178688274 +143 80 -1.7608466099e-10 +169 80 -0.4920430788498 +0 81 0.5714048637404 +1 81 -0.4920430786228 +48 81 1.76111764434e-10 +81 81 0.5739651015181 +88 81 -0.07936178688285 +143 81 -1.760846745068e-10 +170 81 -0.4920430788498 +52 82 -2.999999999955e-05 +82 82 0.002590235785448 +0 83 1.063447940963 +1 83 -0.6111679852405 +59 83 -1.06344794423 +83 83 1.51828813877 +84 83 -0.4522799587544 +1 84 -4.205055174117e-05 +83 84 -4.205055172408e-05 +84 84 0.002607286337172 +152 84 -5e-06 +52 85 -3.000000000001e-05 +85 85 0.002590235785448 +0 86 0.4920430770882 +1 86 -0.492043078801 +48 86 1.76116592985e-10 +86 86 0.4946033146353 +143 86 -1.760846726148e-10 +171 86 -0.4920430788499 +56 87 0 +61 87 0 +87 87 0.002560235785448 +52 88 -2.999999999991e-05 +88 88 0.002590235785448 +0 89 0.4920430795657 +1 89 -0.4920430786908 +48 89 1.760903935369e-10 +89 89 0.4946033146352 +143 89 -1.760846741761e-10 +172 89 -0.4920430788498 +0 90 0.5714048645668 +1 90 -0.4920430787554 +48 90 1.761092705536e-10 +90 90 0.5739651015181 +94 90 -0.07936178688281 +143 90 -1.760846678343e-10 +173 90 -0.4920430788498 +0 91 0.5714048628028 +1 91 -0.4920430784636 +48 91 1.760938499993e-10 +91 91 0.5739651015181 +97 91 -0.07936178688285 +143 91 -1.760846559022e-10 +174 91 -0.4920430788499 +0 92 0.5714048647635 +1 92 -0.4920430786719 +48 92 1.760842468591e-10 +92 92 0.5739651015181 +100 92 -0.07936178688332 +143 92 -1.760846666463e-10 +175 92 -0.4920430788498 +0 93 0.5714048650255 +1 93 -0.4920430786659 +48 93 1.760701683169e-10 +93 93 0.5739651015181 +101 93 -0.07936178688317 +143 93 -1.760846640724e-10 +176 93 -0.4920430788498 +52 94 -2.999999999991e-05 +94 94 0.002590235785448 +0 95 1.063447939988 +1 95 -0.6111679854925 +48 95 1.760865894972e-10 +58 95 -1.063447944406 +95 95 1.518288138946 +96 95 -0.4522799587544 +143 95 -1.760846670718e-10 +1 96 -4.20505517104e-05 +95 96 -4.205055172407e-05 +96 96 0.002607286337172 +153 96 -5e-06 +52 97 -3.000000000023e-05 +97 97 0.002590235785448 +0 98 1.063447942306 +1 98 -0.6111679855538 +48 98 1.761258586564e-10 +73 98 -1.063447944406 +98 98 1.518288138946 +99 98 -0.4522799587544 +143 98 -1.76084677565e-10 +1 99 -4.205055174038e-05 +98 99 -4.205055172407e-05 +99 99 0.002607286337172 +154 99 -5e-06 +52 100 -3.000000000001e-05 +100 100 0.002590235785448 +52 101 -3.000000000001e-05 +101 101 0.002590235785448 +0 102 0.4920430783954 +1 102 -0.4920430786518 +42 102 -0.4920430786736 +71 102 -0.4920430786731 +102 102 0.4946033144592 +103 102 -0.4920430786731 +103 103 0.002560258054109 +104 103 -2.226866071837e-08 +136 103 2.226866071835e-08 +0 104 0.4920430785024 +1 104 -0.4920430786679 +42 104 -0.4920430786738 +104 104 0.4946033144592 +105 104 -0.9840861573462 +3 105 0 +19 105 0 +105 105 0.002560235785448 +0 106 0.4920430787744 +1 106 -0.4920430786336 +106 106 0.4946033144592 +178 106 -0.4920430786737 +1 107 -4.205055172973e-05 +107 107 0.002607286337172 +108 107 -4.205055172408e-05 +155 107 -5e-06 +0 108 0.492043078665 +1 108 -0.0397631199438 +107 108 -0.4522799587544 +108 108 0.9468832732136 +109 108 -0.4920430786737 +1 109 0.4522799587133 +109 109 0.4548401945398 +110 109 -0.4522799587545 +52 110 -3.000000000002e-05 +110 110 0.002590235785448 +0 111 0.4920430787639 +1 111 -0.4920430786612 +42 111 -0.4920430786738 +71 111 -0.4920430786741 +111 111 0.4946033144592 +112 111 -0.4920430786741 +112 112 0.002560258054109 +113 112 -2.226866071837e-08 +136 112 2.226866071842e-08 +0 113 0.492043077127 +1 113 -0.4920430786716 +42 113 -0.4920430786734 +71 113 -0.4920430786716 +105 113 -0.4920430786716 +113 113 0.4946033144592 +0 114 0.4920430789374 +1 114 -0.4920430786817 +42 114 -0.4920430786738 +66 114 -0.4920430786737 +103 114 -0.4920430786738 +114 114 0.4946033144592 +0 115 0.4920430771209 +1 115 -0.4920430786049 +115 115 0.4946033144592 +181 115 -0.4920430786738 +116 116 0.002560258054109 +136 116 2.226866071865e-08 +182 116 -2.226866071838e-08 +0 117 0.4920430792701 +1 117 -0.03976312002707 +117 117 0.9468832732136 +118 117 -0.4920430786737 +120 117 -0.4522799587544 +1 118 0.4522799587949 +118 118 0.4548401945399 +119 118 -0.4522799587544 +52 119 -2.999999999999e-05 +119 119 0.002590235785448 +1 120 -4.210351212105e-05 +117 120 -4.210351211667e-05 +120 120 0.002607339297565 +156 120 -5e-06 +0 121 0.4920430788121 +1 121 -0.4920430786437 +42 121 -0.4920430786738 +71 121 -0.4920430786718 +112 121 -0.4920430786718 +121 121 0.4946033144592 +0 122 0.4920430783275 +1 122 -0.4920430786632 +42 122 -0.4920430786737 +103 122 -0.4920430786737 +122 122 0.4946033144592 +123 122 -0.4920430786737 +3 123 0 +21 123 0 +123 123 0.002560235785448 +0 124 0.4920430781638 +1 124 -0.4920430787149 +42 124 -0.492043078674 +105 124 -0.4920430786718 +124 124 0.4946033144592 +0 125 0.4920430783304 +1 125 -0.4920430787081 +19 125 -0.4920430787081 +25 125 -0.4920430786766 +42 125 -0.4920430786737 +125 125 0.4946033144592 +0 126 0.4920430788384 +1 126 -0.4920430786653 +19 126 -0.4920430786653 +21 126 -0.4920430786707 +42 126 -0.4920430786738 +126 126 0.4946033144592 +0 127 0.4920430782251 +1 127 -0.4920430786839 +20 127 -0.9840861573261 +42 127 -0.4920430786736 +127 127 0.4946033144592 +0 128 4.920430783576 +1 128 -4.920430786231 +22 128 -4.920430786735 +42 128 -9.840861573471 +128 128 4.922991022523 +0 129 0.4920430784622 +1 129 -0.4920430786878 +20 129 -0.4920430786878 +21 129 -0.4920430786737 +42 129 -0.4920430786737 +129 129 0.4946033144592 +0 130 0.492043078061 +1 130 -0.4920430786408 +19 130 -0.4920430787053 +26 130 -0.4920430786771 +42 130 -0.4920430786737 +130 130 0.4946033144592 +0 131 0.4920430786715 +1 131 -0.4920430786715 +19 131 -0.4920430786715 +23 131 -0.4920430786738 +42 131 -0.4920430786737 +131 131 0.4946033144591 +0 132 0.4920430771688 +1 132 -0.4920430787426 +20 132 -0.4920430785995 +25 132 -0.4920430786711 +42 132 -0.4920430786737 +132 132 0.4946033144591 +3 133 0 +7 133 0 +12 133 0 +20 133 0 +42 133 0 +58 133 0 +95 133 -1.670149553868e-08 +133 133 0.002560252486944 +136 133 1.670149553899e-08 +3 134 0 +8 134 0 +12 134 0 +20 134 0 +42 134 0 +73 134 0 +98 134 -5.344478572417e-08 +134 134 0.002560289230234 +136 134 5.344478572347e-08 +0 135 -7.111615739898 +1 135 7.17828713746 +41 135 -88821.07168099 +42 135 0 +135 135 88835.01890368 +136 135 0 +137 135 0 +0 136 19.04682885138 +1 136 12.69780942333 +2 136 1.551897928024 +3 136 4.542268257074 +4 136 0.5229845102146 +5 136 0.7613816461353 +6 136 1.480230569393 +7 136 1.000339760513 +8 136 0.512851928463 +9 136 0.8853929618887 +10 136 1.357290834111 +11 136 4.537130330448 +12 136 4.055676354829 +13 136 0.3312138382014 +14 136 2.042784344269 +15 136 1.34525930264 +16 136 3.076618012512 +17 136 1.244411855421 +18 136 0.7338649798254 +19 136 1.348270950961 +20 136 0.6469882275473 +21 136 0.2369911487333 +22 136 0.04863623886552 +23 136 0.02521370220331 +24 136 0.0007713506269431 +25 136 0.01435088885521 +26 136 0.06679405394823 +27 136 0.002489159161422 +28 136 0.00849074313382 +30 136 0.0001270842306168 +31 136 0.382161620131 +32 136 0.7100070793526 +33 136 1.799538208012 +34 136 0.865355063926 +35 136 0.6870828123593 +36 136 1.059317102324 +37 136 0.2813771214523 +38 136 0.31085305976 +39 136 0.3966738983409 +40 136 0.0580211220974 +41 136 1.174501910599e-09 +42 136 -1.730690936564 +43 136 -18.9880240538 +44 136 -12.75561059991 +46 136 4.518678508122e-06 +47 136 0.05235981401697 +55 136 -0.7613816459101 +56 136 -1.029149847639 +58 136 -0.8574340804235 +59 136 -0.1429056800706 +60 136 -0.06679405395313 +61 136 -0.2369911487297 +63 136 -0.7317172575218 +64 136 -0.04863623886561 +67 136 -4.537130330346 +69 136 -0.7485133118877 +70 136 -0.01435088885262 +72 136 -4.055676354803 +73 136 -0.1273036701897 +75 136 -0.02521370220349 +77 136 -0.3855482582889 +79 136 -0.09176341623108 +80 136 -0.5208193894197 +81 136 -0.2728101563627 +83 136 -0.0007713506269865 +86 136 -0.008490743133777 +89 136 -0.002489159161422 +90 136 -0.1594278122623 +91 136 -0.07755947623575 +92 136 -0.4739745769963 +93 136 -0.6463289686313 +95 136 -0.005294262221911 +98 136 -0.007368421405836 +102 136 -1.723599290493 +103 136 0.2124294538529 +104 136 -0.2124294538527 +111 136 -3.076618012459 +112 136 0.2472943022219 +113 136 -0.247294302222 +114 136 -1.056989452061 +116 136 0.01727652875782 +121 136 -1.244411855365 +122 136 -0.7338649797077 +124 136 -0.3312138382308 +125 136 -0.3966738983424 +126 136 -0.710007079354 +127 136 -1.799538208108 +128 136 -0.6870828123639 +129 136 -0.8653550639193 +130 136 -1.059317102321 +131 136 -0.2813771214472 +132 136 -0.3108530598792 +133 136 0.005294262221824 +134 136 0.007368421405836 +135 136 -3.782226733727e-24 +136 136 73.06959962922 +137 136 -5.943026113463 +139 136 -0.001003621431071 +141 136 -1.551897927995 +157 136 -0.52298446947 +177 136 -0.319185053795 +179 136 -0.0580211220982 +180 136 -0.2882698505622 +182 136 -0.01727652875733 +42 137 -7778510.286871 +137 137 7778510.289384 +135 138 -765000000 +136 138 -115453078.1193 +138 138 822724342.888 +0 139 30.14975346743 +1 139 -56.69119543686 +3 139 0 +19 139 0.0001184669871946 +20 139 2.369339743891e-05 +42 139 -0.0001178587861442 +44 139 -0.0001421603846335 +46 139 2.634022891202e-09 +56 139 -2.451314668066e-05 +135 139 0 +139 139 33.79163103904 +140 139 -3.623762789545 +1 140 -0.01666608622337 +52 140 -6.000026836812e-05 +139 140 -0.01666609507463 +140 140 0.01922185093315 +49 141 -5200 +141 141 5200.002525756 +51 142 -228387.6175097 +142 142 228387.6200291 +19 143 -9360.000000003 +42 143 -9360 +143 143 9360.002525756 +144 144 0.00252575585851 +145 145 0.00252575585851 +146 146 0.00252575585851 +147 147 0.00252575585851 +148 148 0.00252575585851 +149 149 0.00252575585851 +150 150 0.00252575585851 +151 151 0.00252575585851 +152 152 0.00252575585851 +153 153 0.00252575585851 +154 154 0.00252575585851 +155 155 0.00252575585851 +156 156 0.00252575585851 +48 157 -2652000 +157 157 2652000.002526 +19 158 -33.00000000199 +20 158 -192.3999999996 +42 158 -192.4 +157 158 -33 +158 158 225.4025257558 +20 159 -1199.999999857 +26 159 -1092.000000009 +42 159 -1092 +55 159 -1200.000000001 +159 159 2292.002525756 +19 160 -3200.000000038 +22 160 -192.3999999999 +42 160 -192.3999999999 +63 160 -3200 +160 160 3392.402525756 +21 161 -192.3999999995 +42 161 -192.4 +161 161 192.4025257559 +19 162 -4472.000000018 +42 162 -2236 +162 162 2236.002525756 +20 163 -1099.999999993 +25 163 -192.4000000026 +42 163 -192.3999999997 +157 163 -1100 +163 163 1292.402525756 +42 164 -192.3999999999 +71 164 -192.3999999969 +164 164 192.4025257558 +19 165 -2236.000000018 +20 165 -2236.000000018 +42 165 -2236 +165 165 2236.002525756 +23 166 -192.4000000001 +42 166 -192.3999999999 +166 166 192.4025257559 +25 167 -33.30000000023 +157 167 -33.3 +167 167 33.30252575586 +24 168 -192.4000000003 +42 168 -192.4000000003 +168 168 192.4025257559 +28 169 -192.4000000001 +42 169 -192.3999999999 +169 169 192.4025257559 +27 170 -192.4 +42 170 -192.4 +170 170 192.4025257559 +42 171 -192.3999999997 +87 171 -192.4 +171 171 192.4025257559 +42 172 -192.3999999998 +87 172 -192.4 +172 172 192.4025257558 +42 173 -192.4000000002 +133 173 -192.3999999999 +173 173 192.4025257559 +134 174 -192.4000000002 +174 174 192.4025257558 +29 175 -192.4 +42 175 -192.4 +175 175 192.4025257559 +25 176 -3199.999999985 +55 176 -3200 +176 176 3200.002525756 +106 177 -2236 +177 177 2236.002525756 +40 178 -2236.000000006 +42 178 -2236.000000001 +178 178 2236.002525756 +108 179 -2236 +179 179 2236.002525756 +115 180 -2236 +180 180 2236.002525756 +42 181 -2236.000000002 +116 181 -2235.999999999 +181 181 2236.002525756 +117 182 -2236.000000002 +182 182 2236.002525756 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/ibm32a b/OpenDSSC/klusolve/CSparse/Matrix/ibm32a new file mode 100644 index 0000000..d474d02 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/ibm32a @@ -0,0 +1,123 @@ +0 0 1 +1 0 1 +2 0 1 +3 0 1 +6 0 1 +25 0 1 +0 1 1 +1 1 1 +8 1 1 +20 1 1 +27 1 1 +1 2 1 +2 2 1 +5 2 1 +7 2 1 +8 2 1 +28 2 1 +2 3 1 +3 3 1 +4 3 1 +11 3 1 +2 4 1 +4 4 1 +22 4 1 +26 4 1 +0 5 1 +5 5 1 +15 5 1 +2 6 1 +6 6 1 +13 6 1 +20 6 1 +30 6 1 +0 7 1 +7 7 1 +11 7 1 +16 7 1 +26 7 1 +6 8 1 +8 8 1 +9 8 1 +12 8 1 +18 8 1 +22 8 1 +26 8 1 +0 9 1 +9 9 1 +10 9 1 +20 9 1 +22 9 1 +24 9 1 +26 9 1 +1 10 1 +10 10 1 +14 10 1 +17 10 1 +28 10 1 +5 11 1 +11 11 1 +23 11 1 +10 12 1 +12 12 1 +2 13 1 +13 13 1 +1 14 1 +14 14 1 +19 14 1 +3 15 1 +15 15 1 +21 15 1 +3 16 1 +15 16 1 +16 16 1 +5 17 1 +9 17 1 +17 17 1 +19 17 1 +29 17 1 +0 18 1 +18 18 1 +25 18 1 +7 19 1 +15 19 1 +19 19 1 +2 20 1 +20 20 1 +31 20 1 +10 21 1 +21 21 1 +1 22 1 +16 22 1 +20 22 1 +22 22 1 +11 23 1 +23 23 1 +25 23 1 +5 24 1 +14 24 1 +17 24 1 +23 24 1 +24 24 1 +12 25 1 +17 25 1 +21 25 1 +25 25 1 +4 26 1 +23 26 1 +25 26 1 +26 26 1 +8 27 1 +27 27 1 +2 28 1 +4 28 1 +26 28 1 +28 28 1 +31 28 1 +11 29 1 +16 29 1 +22 29 1 +29 29 1 +12 30 1 +13 30 1 +30 30 1 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/ibm32b b/OpenDSSC/klusolve/CSparse/Matrix/ibm32b new file mode 100644 index 0000000..9a70e18 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/ibm32b @@ -0,0 +1,123 @@ +0 0 1 +1 0 1 +5 0 1 +7 0 1 +9 0 1 +18 0 1 +0 1 1 +1 1 1 +2 1 1 +10 1 1 +14 1 1 +22 1 1 +0 2 1 +2 2 1 +3 2 1 +4 2 1 +6 2 1 +13 2 1 +20 2 1 +28 2 1 +0 3 1 +3 3 1 +15 3 1 +16 3 1 +3 4 1 +4 4 1 +26 4 1 +28 4 1 +2 5 1 +5 5 1 +11 5 1 +17 5 1 +24 5 1 +0 6 1 +6 6 1 +8 6 1 +2 7 1 +7 7 1 +19 7 1 +1 8 1 +2 8 1 +8 8 1 +27 8 1 +8 9 1 +9 9 1 +17 9 1 +9 10 1 +10 10 1 +12 10 1 +21 10 1 +3 11 1 +7 11 1 +11 11 1 +23 11 1 +29 11 1 +8 12 1 +12 12 1 +25 12 1 +30 12 1 +6 13 1 +13 13 1 +30 13 1 +10 14 1 +14 14 1 +24 14 1 +5 15 1 +15 15 1 +16 15 1 +19 15 1 +7 16 1 +16 16 1 +22 16 1 +29 16 1 +10 17 1 +17 17 1 +24 17 1 +25 17 1 +8 18 1 +18 18 1 +14 19 1 +17 19 1 +19 19 1 +1 20 1 +6 20 1 +9 20 1 +20 20 1 +22 20 1 +15 21 1 +21 21 1 +25 21 1 +4 22 1 +8 22 1 +9 22 1 +22 22 1 +29 22 1 +11 23 1 +23 23 1 +24 23 1 +26 23 1 +9 24 1 +24 24 1 +0 25 1 +18 25 1 +23 25 1 +25 25 1 +26 25 1 +4 26 1 +7 26 1 +8 26 1 +9 26 1 +26 26 1 +28 26 1 +1 27 1 +27 27 1 +2 28 1 +10 28 1 +28 28 1 +17 29 1 +29 29 1 +6 30 1 +30 30 1 +20 31 1 +28 31 1 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/lp_afiro b/OpenDSSC/klusolve/CSparse/Matrix/lp_afiro new file mode 100644 index 0000000..0e2c5ae --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/lp_afiro @@ -0,0 +1,102 @@ +2 0 1 +3 1 1 +6 2 1 +7 3 1 +8 4 1 +9 5 1 +12 6 1 +13 7 1 +16 8 1 +17 9 1 +18 10 1 +19 11 1 +20 12 1 +21 13 1 +22 14 1 +23 15 1 +24 16 1 +25 17 1 +26 18 1 +0 19 -1 +1 19 -1.06 +2 19 1 +23 19 0.301 +0 20 1 +3 20 -1 +0 21 1 +21 21 -1 +1 22 1 +25 22 1 +4 23 -1 +5 23 -1.06 +6 23 1 +24 23 0.301 +4 24 -1 +5 24 -1.06 +7 24 1 +24 24 0.313 +4 25 -1 +5 25 -0.96 +8 25 1 +24 25 0.313 +4 26 -1 +5 26 -0.86 +9 26 1 +24 26 0.326 +6 27 -1 +20 27 2.364 +7 28 -1 +20 28 2.386 +8 29 -1 +20 29 2.408 +9 30 -1 +20 30 2.429 +3 31 1.4 +4 31 1 +4 32 1 +22 32 -1 +5 33 1 +26 33 1 +10 34 -1 +11 34 -0.43 +12 34 1 +21 34 0.109 +10 35 1 +13 35 -1 +10 36 1 +23 36 -1 +10 37 1 +20 37 -1 +11 38 1 +25 38 1 +14 39 -0.43 +15 39 1 +16 39 1 +22 39 0.109 +14 40 -0.43 +15 40 1 +17 40 1 +22 40 0.108 +14 41 -0.39 +15 41 1 +18 41 1 +22 41 0.108 +14 42 -0.37 +15 42 1 +19 42 1 +22 42 0.107 +16 43 -1 +20 43 2.191 +17 44 -1 +20 44 2.219 +18 45 -1 +20 45 2.249 +19 46 -1 +20 46 2.279 +13 47 1.4 +15 47 -1 +15 48 1 +24 48 -1 +14 49 1 +26 49 1 +15 50 1 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/mbeacxc b/OpenDSSC/klusolve/CSparse/Matrix/mbeacxc new file mode 100644 index 0000000..f9b4c06 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/mbeacxc @@ -0,0 +1,49920 @@ +5 0 0.0045458972 +6 0 0.24555165 +18 0 0.025517598 +24 0 7.0999988e-05 +62 0 0.0068898983 +98 0 0.0028766999 +102 0 0.11666727 +103 0 8.8799992e-05 +104 0 0.0011898 +107 0 0.0042084977 +108 0 1.779999e-05 +111 0 0.00094119995 +114 0 8.8799992e-05 +117 0 0.0014915999 +118 0 0.012057398 +119 0 0.0002308 +120 0 0.0001776 +126 0 1.779999e-05 +141 0 3.5499994e-05 +143 0 0.0015626999 +160 0 0.0002485998 +171 0 8.8799992e-05 +172 0 1.779999e-05 +189 0 1.779999e-05 +194 0 1.779999e-05 +198 0 0.00014209999 +200 0 8.8799992e-05 +201 0 7.0999988e-05 +206 0 3.5499994e-05 +214 0 0.00062149996 +217 0 0.0011719998 +223 0 0.00095889997 +228 0 0.00037289993 +229 0 0.0037113 +234 0 0.0047767982 +237 0 0.0039421991 +242 0 1.779999e-05 +253 0 0.00039069983 +279 0 8.8799992e-05 +283 0 3.5499994e-05 +307 0 0.0001065 +315 0 0.0017402 +317 0 0.00095889997 +318 0 1.779999e-05 +322 0 5.3299998e-05 +329 0 0.0049720965 +356 0 8.8799992e-05 +357 0 0.00014209999 +358 0 8.8799992e-05 +384 0 7.0999988e-05 +387 0 1.779999e-05 +394 0 0.00026639993 +397 0 5.3299998e-05 +402 0 0.00062149996 +422 0 1.779999e-05 +438 0 3.5499994e-05 +442 0 3.5499994e-05 +443 0 0.0044926964 +444 0 1.779999e-05 +445 0 0.032176699 +446 0 0.00053269998 +447 0 3.5499994e-05 +448 0 0.00012429999 +450 0 0.0026991998 +452 0 0.0080086999 +454 0 0.0002308 +455 0 0.021841798 +456 0 0.00078129978 +457 0 0.0098198988 +458 0 0.00037289993 +459 0 3.5499994e-05 +460 0 0.0055580996 +463 0 0.029246699 +464 0 1.779999e-05 +467 0 0.0031963999 +468 0 0.00021309999 +469 0 0.0013851 +470 0 0.00040839985 +471 0 0.0032495998 +473 0 1.779999e-05 +476 0 0.0017402 +478 0 0.00035519991 +483 0 0.00014209999 +490 0 3.5499994e-05 +6 1 0.16098946 +18 1 0.12319708 +62 1 0.0048390999 +102 1 0.38757879 +114 1 2.3599991e-05 +117 1 0.0025966 +118 1 0.020938098 +119 1 0.00040129991 +120 1 0.00030689989 +126 1 2.3599991e-05 +141 1 4.7199996e-05 +171 1 9.4399991e-05 +172 1 2.3599991e-05 +194 1 0.0046738982 +195 1 0.011023797 +200 1 9.4399991e-05 +201 1 9.4399991e-05 +206 1 4.7199996e-05 +214 1 0.00028329995 +217 1 0.00054289983 +223 1 0.00092059979 +228 1 0.0059249997 +229 1 0.00068459986 +234 1 0.0055944994 +237 1 0.0020772999 +279 1 0.00014159999 +283 1 4.7199996e-05 +307 1 0.000118 +317 1 0.00096779992 +318 1 2.3599991e-05 +322 1 2.3599991e-05 +329 1 0.0028326998 +356 1 9.4399991e-05 +357 1 7.0799986e-05 +358 1 4.7199996e-05 +384 1 4.7199996e-05 +394 1 0.00016519999 +397 1 4.7199996e-05 +402 1 0.00028329995 +438 1 4.7199996e-05 +442 1 4.7199996e-05 +443 1 0.010575298 +445 1 0.0052403994 +446 1 0.0011094999 +447 1 4.7199996e-05 +448 1 0.00014159999 +450 1 0.0026909998 +452 1 0.0080494992 +453 1 0.00051929988 +454 1 0.00023609999 +455 1 0.042230196 +456 1 0.012062397 +457 1 0.0048862994 +458 1 0.00037769997 +459 1 2.3599991e-05 +460 1 0.0033047998 +463 1 0.0162878 +464 1 2.3599991e-05 +467 1 0.0015815999 +468 1 0.00021239999 +469 1 0.0014398999 +470 1 0.00040129991 +471 1 0.0017467998 +473 1 2.3599991e-05 +476 1 0.027901698 +478 1 0.00035409979 +483 1 0.00014159999 +490 1 4.7199996e-05 +0 2 0.0031091999 +2 2 0.36019218 +3 2 0.0014519999 +5 2 0.0087651983 +6 2 0.22969705 +9 2 3.2999997e-06 +11 2 7.9399993e-05 +14 2 0.00015219999 +18 2 0.016207296 +62 2 0.0048456974 +82 2 1.32e-05 +83 2 3.2999997e-06 +84 2 3.2999997e-06 +98 2 0.00080039981 +102 2 0.058878798 +103 2 2.9799994e-05 +104 2 0.00033739978 +107 2 0.0011741999 +108 2 3.2999997e-06 +111 2 0.00025799987 +113 2 6.5999993e-06 +114 2 5.2899995e-05 +117 2 0.0015479999 +118 2 0.012585498 +119 2 0.00022819999 +120 2 0.00017859999 +126 2 6.5999993e-06 +141 2 2.6499998e-05 +171 2 8.5999985e-05 +172 2 1.9799991e-05 +189 2 6.5999993e-06 +193 2 1.6499995e-05 +194 2 9.8999999e-06 +197 2 3.2999997e-06 +200 2 9.5899988e-05 +201 2 7.2799987e-05 +203 2 6.5999993e-06 +204 2 6.5999993e-06 +206 2 1.32e-05 +207 2 3.2999997e-06 +214 2 0.00036709988 +217 2 0.0007077998 +223 2 0.00086989999 +228 2 0.00048289984 +234 2 0.0037838998 +237 2 0.0030958999 +242 2 9.8999999e-06 +252 2 3.2999997e-06 +279 2 9.5899988e-05 +283 2 4.9599999e-05 +307 2 0.00010579999 +317 2 0.00093609979 +318 2 9.8999999e-06 +322 2 3.6399986e-05 +329 2 0.0040253997 +356 2 8.9299996e-05 +357 2 0.00010919999 +358 2 5.6199991e-05 +384 2 4.9599999e-05 +387 2 3.2999997e-06 +394 2 0.00020839999 +397 2 4.6299989e-05 +402 2 0.00043659983 +419 2 3.2999997e-06 +422 2 9.8999999e-06 +423 2 3.2999997e-06 +425 2 3.2999997e-06 +430 2 3.2999997e-06 +431 2 3.2999997e-06 +433 2 3.2999997e-06 +434 2 3.2999997e-06 +438 2 2.9799994e-05 +442 2 3.9699997e-05 +443 2 0.0041576996 +444 2 9.8999999e-06 +445 2 0.004623998 +446 2 0.00069129979 +447 2 3.6399986e-05 +448 2 7.9399993e-05 +450 2 0.0026791999 +452 2 0.0080043972 +454 2 0.00015219999 +455 2 0.032106999 +456 2 0.0010187 +457 2 0.0087452978 +458 2 4.6299989e-05 +459 2 1.6499995e-05 +460 2 0.0044586994 +463 2 0.022627398 +464 2 1.32e-05 +467 2 0.0026625998 +468 2 0.0002249 +469 2 0.0014056999 +470 2 0.00039689988 +471 2 0.0028014998 +473 2 9.8999999e-06 +476 2 0.0022987998 +478 2 0.00035389978 +483 2 0.0001389 +490 2 3.309999e-05 +3 3 0.068147898 +5 3 0.00082899979 +6 3 0.21903497 +18 3 0.0076272972 +62 3 0.0031503998 +98 3 0.012104098 +101 3 0.037307199 +102 3 0.16630739 +103 3 0.00049739983 +104 3 0.0049742982 +107 3 0.017741699 +111 3 0.0039793998 +114 3 0.0014922998 +117 3 0.00066319993 +118 3 0.0051400997 +119 3 0.0001658 +200 3 0.0001658 +201 3 0.0001658 +214 3 0.00066319993 +217 3 0.00099489978 +223 3 0.0024871 +228 3 0.0021555 +234 3 0.0084562972 +237 3 0.0013265 +251 3 0.023379199 +279 3 0.0001658 +307 3 0.0001658 +317 3 0.00082899979 +322 3 0.0016580999 +329 3 0.00082899979 +356 3 0.0001658 +394 3 0.0001658 +402 3 0.0001658 +443 3 0.0061349981 +445 3 0.0051400997 +446 3 0.00066319993 +447 3 0.00049739983 +448 3 0.0001658 +450 3 0.0026529999 +452 3 0.0079588965 +453 3 0.00066319993 +454 3 0.0001658 +455 3 0.030343197 +456 3 0.0043110996 +457 3 0.0024871 +458 3 0.00049739983 +460 3 0.0023212999 +463 3 0.028685097 +467 3 0.0021555 +468 3 0.0001658 +469 3 0.0014922998 +470 3 0.00049739983 +471 3 0.0013265 +476 3 0.0096169971 +478 3 0.00033159996 +483 3 0.0001658 +490 3 0.0001658 +0 4 0.00024319999 +1 4 0.00072969985 +2 4 0.0031619 +3 4 0.0087560974 +4 4 0.012696397 +18 4 0.18679768 +24 4 0.0016538999 +25 4 0.0018485 +62 4 0.0087074973 +114 4 4.8599992e-05 +171 4 9.7299999e-05 +200 4 9.7299999e-05 +201 4 9.7299999e-05 +206 4 4.8599992e-05 +214 4 0.028019696 +215 4 0.078124166 +217 4 0.045775197 +223 4 0.00029189978 +234 4 0.022765998 +237 4 0.0063724965 +273 4 9.7299999e-05 +279 4 4.8599992e-05 +283 4 4.8599992e-05 +307 4 9.7299999e-05 +317 4 0.00097289984 +322 4 9.7299999e-05 +329 4 0.0094857998 +356 4 0.00029189978 +357 4 0.0001946 +358 4 9.7299999e-05 +384 4 4.8599992e-05 +394 4 0.00087559992 +397 4 9.7299999e-05 +402 4 0.00068099983 +438 4 4.8599992e-05 +442 4 4.8599992e-05 +443 4 0.0069075972 +445 4 0.0049617998 +446 4 0.0019944999 +447 4 4.8599992e-05 +448 4 0.00048649986 +450 4 0.0026268 +453 4 0.006858997 +454 4 0.0070535988 +455 4 0.038672999 +457 4 0.010118198 +458 4 0.00034049992 +460 4 0.009388499 +463 4 0.17463636 +467 4 0.012745097 +468 4 0.0001946 +469 4 0.0014106999 +470 4 0.00038919994 +471 4 0.0042807981 +478 4 0.00034049992 +483 4 0.00014589999 +490 4 4.8599992e-05 +0 5 0.00028399983 +1 5 0.00099389977 +2 5 0.023086797 +3 5 0.0034359999 +5 5 0.043362197 +18 5 0.017066598 +24 5 0.0023852999 +25 5 0.0011642999 +62 5 0.010109298 +114 5 2.8399998e-05 +141 5 2.8399998e-05 +171 5 8.5199994e-05 +172 5 2.8399998e-05 +200 5 8.5199994e-05 +201 5 8.5199994e-05 +206 5 5.6799996e-05 +214 5 0.0090017989 +215 5 0.037569199 +217 5 0.0083486997 +223 5 0.00017039999 +234 5 0.025670897 +237 5 0.0047706999 +242 5 2.8399998e-05 +273 5 8.5199994e-05 +279 5 0.00017039999 +283 5 5.6799996e-05 +307 5 0.00011359999 +317 5 0.0009370998 +318 5 2.8399998e-05 +322 5 5.6799996e-05 +329 5 0.0070991963 +356 5 0.00031239982 +357 5 0.00011359999 +358 5 5.6799996e-05 +384 5 2.8399998e-05 +394 5 0.00070989993 +397 5 5.6799996e-05 +402 5 0.00045439997 +438 5 2.8399998e-05 +442 5 5.6799996e-05 +443 5 0.0051114969 +445 5 0.0034075999 +446 5 0.0017037999 +447 5 5.6799996e-05 +448 5 0.0005394998 +450 5 0.0026409 +453 5 0.0031804999 +454 5 0.0026125 +455 5 0.0240523 +457 5 0.0058497973 +458 5 0.00036919978 +459 5 2.8399998e-05 +460 5 0.0082350969 +463 5 0.15800089 +464 5 2.8399998e-05 +467 5 0.010506898 +468 5 0.0002272 +469 5 0.0013914998 +470 5 0.00039759977 +471 5 0.0026976999 +478 5 0.00036919978 +483 5 0.00014199999 +490 5 5.6799996e-05 +0 6 0.0077898987 +1 6 0.0020032998 +2 6 0.028940197 +3 6 0.0054982975 +6 6 0.023989499 +7 6 0.0047560968 +13 6 0.0006773998 +18 6 0.018692899 +24 6 0.0040714964 +25 6 0.0020754 +62 6 0.0094761997 +108 6 7.1999993e-06 +114 6 7.1999993e-06 +126 6 7.1999993e-06 +141 6 0.0035670998 +171 6 8.6499989e-05 +172 6 2.159999e-05 +189 6 0.0001657 +194 6 1.44e-05 +200 6 9.3699986e-05 +201 6 7.2099996e-05 +203 6 7.1999993e-06 +204 6 7.1999993e-06 +206 6 1.44e-05 +214 6 0.020516098 +215 6 0.054731198 +217 6 0.019910797 +223 6 0.0001946 +234 6 0.031282198 +237 6 0.0060171969 +241 6 0.00040349993 +242 6 1.44e-05 +273 6 0.00020179999 +279 6 8.6499989e-05 +283 6 5.0399991e-05 +307 6 0.0001009 +317 6 0.00093679992 +318 6 1.44e-05 +322 6 0.0012683 +329 6 0.009490598 +356 6 0.00030989992 +357 6 0.00010809999 +358 6 6.4899999e-05 +384 6 2.8799986e-05 +387 6 7.1999993e-06 +394 6 0.0010016998 +397 6 5.0399991e-05 +402 6 0.00046839984 +422 6 7.1999993e-06 +430 6 7.1999993e-06 +434 6 7.1999993e-06 +438 6 2.159999e-05 +442 6 5.0399991e-05 +443 6 0.0065648966 +444 6 1.44e-05 +445 6 0.0085104965 +446 6 0.0025221999 +447 6 0.00011529999 +448 6 0.00069179991 +450 6 0.0026590999 +453 6 0.0036175 +454 6 0.006672997 +455 6 0.039324299 +456 6 2.159999e-05 +457 6 0.0064423978 +458 6 0.00036749989 +459 6 2.159999e-05 +460 6 0.0073791966 +463 6 0.1141609 +464 6 2.159999e-05 +467 6 0.015197899 +468 6 0.0002234 +469 6 0.0013907999 +470 6 0.00039629987 +471 6 0.0029400999 +473 6 7.1999993e-06 +478 6 0.00036029983 +483 6 0.00013689999 +490 6 3.5999998e-05 +3 7 0.0092790984 +7 7 0.0563883 +18 7 0.0513919 +24 7 0.00071379985 +62 7 0.0028551 +153 7 0.00071379985 +154 7 0.0028551 +172 7 0.00071379985 +193 7 0.0028551 +214 7 0.0107066 +215 7 0.044967897 +217 7 0.015703097 +223 7 0.00071379985 +234 7 0.030692399 +237 7 0.0099928975 +241 7 0.024982199 +317 7 0.0014275999 +329 7 0.014275499 +357 7 0.00071379985 +394 7 0.0014275999 +402 7 0.00071379985 +443 7 0.0035688998 +445 7 0.0135617 +446 7 0.00071379985 +448 7 0.00071379985 +450 7 0.0028551 +453 7 0.00071379985 +454 7 0.0064239986 +455 7 0.037116297 +457 7 0.016416799 +460 7 0.011420399 +463 7 0.084225595 +467 7 0.016416799 +469 7 0.0014275999 +470 7 0.00071379985 +471 7 0.0064239986 +478 7 0.00071379985 +0 8 0.00013659999 +1 8 0.00020489999 +2 8 0.00027319998 +3 8 0.0088114999 +8 8 0.00095629995 +18 8 0.019398898 +24 8 0.0011612 +25 8 0.00013659999 +62 8 0.0118852 +114 8 6.8299996e-05 +130 8 0.0064890981 +171 8 0.00013659999 +200 8 0.00013659999 +201 8 6.8299996e-05 +206 8 6.8299996e-05 +214 8 0.0077185966 +217 8 0.0088114999 +223 8 0.00040979986 +234 8 0.014275998 +237 8 0.0064207986 +241 8 0.0020491998 +273 8 6.8299996e-05 +279 8 6.8299996e-05 +283 8 6.8299996e-05 +307 8 0.00013659999 +317 8 0.00088799978 +329 8 0.0085382983 +356 8 0.00027319998 +357 8 0.00020489999 +358 8 0.00013659999 +384 8 6.8299996e-05 +394 8 0.00054639997 +397 8 0.00013659999 +402 8 0.00081969984 +438 8 6.8299996e-05 +442 8 6.8299996e-05 +443 8 0.00081969984 +445 8 0.0017759998 +446 8 0.0004780998 +448 8 0.00034149992 +450 8 0.0027321998 +454 8 0.00034149992 +455 8 0.048497297 +457 8 0.0061474964 +458 8 0.00034149992 +460 8 0.011816896 +463 8 0.12233609 +467 8 0.0062157996 +468 8 0.00020489999 +469 8 0.0013660998 +470 8 0.00040979986 +471 8 0.0049179979 +478 8 0.00034149992 +483 8 0.00013659999 +490 8 6.8299996e-05 +0 9 4.4799992e-05 +1 9 0.0001792 +2 9 0.00013439999 +3 9 0.00094079995 +16 9 0.011827398 +18 9 0.073786974 +24 9 0.0014783998 +25 9 8.9599998e-05 +62 9 0.0079297982 +114 9 4.4799992e-05 +141 9 4.4799992e-05 +153 9 0.00062719989 +154 9 0.0023743999 +171 9 8.9599998e-05 +172 9 0.049460098 +189 9 4.4799992e-05 +193 9 0.0023743999 +198 9 8.9599998e-05 +200 9 0.00013439999 +201 9 8.9599998e-05 +206 9 4.4799992e-05 +214 9 0.0173827 +215 9 0.12580079 +217 9 0.0284485 +223 9 0.0001792 +234 9 0.030823 +237 9 0.0035392998 +273 9 4.4799992e-05 +283 9 4.4799992e-05 +307 9 0.00013439999 +317 9 0.0010751998 +322 9 4.4799992e-05 +329 9 0.0050176978 +356 9 0.00031359983 +357 9 8.9599998e-05 +358 9 8.9599998e-05 +384 9 4.4799992e-05 +394 9 0.00044799992 +397 9 4.4799992e-05 +402 9 0.00035839994 +438 9 4.4799992e-05 +442 9 4.4799992e-05 +443 9 0.010259397 +445 9 0.0056896992 +446 9 0.0021952 +447 9 4.4799992e-05 +448 9 0.00058239978 +450 9 0.0026433 +453 9 0.00022399999 +454 9 0.0046144985 +455 9 0.053178597 +456 9 0.0053760968 +457 9 0.0056448989 +458 9 0.00040319981 +460 9 0.0054208972 +463 9 0.021862797 +467 9 0.0072577 +468 9 0.00022399999 +469 9 0.0014336 +470 9 0.00044799992 +471 9 0.0022847999 +478 9 0.00035839994 +483 9 0.00013439999 +490 9 4.4799992e-05 +3 10 0.0016096998 +16 10 0.0072434992 +18 10 0.074849069 +24 10 0.0016096998 +62 10 0.013279699 +153 10 0.00080479984 +154 10 0.0024144999 +172 10 0.00080479984 +193 10 0.0024144999 +214 10 0.012072399 +215 10 0.1191147 +217 10 0.016498998 +234 10 0.029376298 +237 10 0.0040240996 +317 10 0.0012071999 +329 10 0.0028168999 +356 10 0.0004023998 +394 10 0.0004023998 +443 10 0.0088530965 +445 10 0.0040240996 +446 10 0.0016096998 +448 10 0.00080479984 +450 10 0.0028168999 +453 10 0.0016096998 +455 10 0.047082499 +456 10 0.0040240996 +457 10 0.0060361996 +458 10 0.0004023998 +460 10 0.006438598 +463 10 0.024144899 +467 10 0.0100604 +468 10 0.0004023998 +469 10 0.0016096998 +470 10 0.0004023998 +471 10 0.0024144999 +478 10 0.0004023998 +0 11 0.0001144 +1 11 0.0001716 +2 11 0.00028599985 +3 11 0.0028891 +11 11 0.015704099 +16 11 0.016247597 +18 11 0.048456799 +24 11 0.001373 +25 11 0.0011441999 +62 11 0.0060069971 +114 11 2.8599999e-05 +141 11 2.8599999e-05 +153 11 0.00062929979 +154 11 0.0024027999 +171 11 8.5799998e-05 +172 11 0.00077229994 +193 11 0.0024599999 +198 11 8.5799998e-05 +200 11 8.5799998e-05 +201 11 8.5799998e-05 +206 11 5.7199999e-05 +214 11 0.0097256973 +215 11 0.046883497 +217 11 0.0125576 +223 11 0.0001716 +234 11 0.011356197 +237 11 0.0036613999 +273 11 8.5799998e-05 +283 11 5.7199999e-05 +307 11 0.0001144 +317 11 0.0010583999 +322 11 5.7199999e-05 +329 11 0.0051202998 +356 11 0.00028599985 +357 11 0.0001144 +358 11 8.5799998e-05 +384 11 2.8599999e-05 +394 11 0.00042909989 +397 11 5.7199999e-05 +402 11 0.00037189992 +438 11 2.8599999e-05 +442 11 5.7199999e-05 +443 11 0.0042620972 +445 11 0.0073514991 +446 11 0.0010869999 +447 11 5.7199999e-05 +448 11 0.0002288 +450 11 0.0026602999 +453 11 0.0001144 +454 11 0.0031178999 +455 11 0.051946599 +456 11 0.0074086972 +457 11 0.0062930994 +458 11 0.00037189992 +459 11 2.8599999e-05 +460 11 0.0046339966 +463 11 0.044938397 +464 11 2.8599999e-05 +467 11 0.0062358975 +468 11 0.0002288 +469 11 0.0014016 +470 11 0.00040049991 +471 11 0.0025743998 +478 11 0.00037189992 +483 11 0.000143 +490 11 5.7199999e-05 +3 12 0.0059012994 +12 12 0.0362124 +18 12 0.046405599 +24 12 0.0020118 +25 12 0.00013409999 +62 12 0.008851897 +171 12 0.00013409999 +200 12 0.00013409999 +201 12 0.00013409999 +214 12 0.014216699 +215 12 0.10005355 +217 12 0.0189109 +223 12 0.00026819995 +234 12 0.017972097 +237 12 0.0046941973 +273 12 0.00013409999 +279 12 0.00013409999 +307 12 0.00013409999 +317 12 0.00093879993 +329 12 0.0060353987 +356 12 0.0004023998 +357 12 0.00013409999 +394 12 0.00080469996 +397 12 0.00013409999 +402 12 0.00026819995 +442 12 0.00013409999 +443 12 0.0068400986 +445 12 0.0040235966 +446 12 0.0013412 +448 12 0.0004023998 +450 12 0.0028164999 +453 12 0.00093879993 +455 12 0.032188799 +457 12 0.010058999 +458 12 0.0004023998 +460 12 0.0115343 +463 12 0.11614805 +467 12 0.0107296 +468 12 0.00026819995 +469 12 0.0014752999 +470 12 0.0004023998 +471 12 0.0033529999 +478 12 0.0004023998 +483 12 0.00013409999 +490 12 0.00013409999 +3 13 0.0014612998 +13 13 0.010715999 +16 13 0.0029225999 +18 13 0.049683399 +24 13 0.0053579994 +25 13 0.00048709987 +62 13 0.0014612998 +214 13 0.017535299 +215 13 0.2513395 +217 13 0.014612798 +234 13 0.014612798 +237 13 0.0043837987 +273 13 0.00048709987 +317 13 0.0014612998 +329 13 0.0043837987 +443 13 0.017048199 +445 13 0.007306397 +446 13 0.0019483999 +450 13 0.0024354998 +453 13 0.00097419997 +455 13 0.069654167 +457 13 0.009741798 +460 13 0.004870899 +463 13 0.07355088 +467 13 0.010715999 +469 13 0.0014612998 +470 13 0.00048709987 +471 13 0.0038967 +478 13 0.00048709987 +0 14 0.0011772998 +1 14 0.0014295999 +2 14 0.011142597 +3 14 0.0033006999 +14 14 0.056007598 +18 14 0.021213099 +24 14 0.00058869994 +25 14 0.00077789999 +62 14 0.0082623996 +114 14 2.1e-05 +126 14 2.1e-05 +141 14 4.2e-05 +171 14 0.0001051 +172 14 2.1e-05 +194 14 2.1e-05 +200 14 8.4099986e-05 +201 14 8.4099986e-05 +206 14 4.2e-05 +214 14 0.015767898 +215 14 0.010911398 +217 14 0.026931599 +223 14 0.00016819999 +234 14 0.022348396 +237 14 0.0057184994 +242 14 2.1e-05 +273 14 2.1e-05 +279 14 0.00014719999 +283 14 4.2e-05 +307 14 0.0001051 +317 14 0.0009670998 +318 14 2.1e-05 +322 14 4.2e-05 +329 14 0.0089350976 +356 14 0.00031539984 +357 14 0.0001261 +358 14 0.0001051 +384 14 4.2e-05 +394 14 0.0009039999 +397 14 6.3099986e-05 +402 14 0.00054659997 +438 14 4.2e-05 +442 14 6.3099986e-05 +443 14 0.0023546999 +444 14 2.1e-05 +445 14 0.0030063998 +446 14 0.0012403999 +447 14 4.2e-05 +448 14 0.00046249991 +450 14 0.0026910999 +453 14 0.00031539984 +454 14 0.00086199981 +455 14 0.020182896 +457 14 0.0066434965 +458 14 0.00037839985 +459 14 2.1e-05 +460 14 0.0073162988 +463 14 0.10947114 +464 14 2.1e-05 +467 14 0.013875697 +468 14 0.0002102 +469 14 0.0013875999 +470 14 0.0003994999 +471 14 0.0029222998 +473 14 2.1e-05 +478 14 0.00035739993 +483 14 0.00014719999 +490 14 4.2e-05 +1 16 0.00035179988 +3 16 0.0021813998 +16 16 0.054183397 +18 16 0.013932899 +22 16 0.00056289998 +24 16 0.0019703 +25 16 7.0399998e-05 +60 16 0.00014069999 +62 16 0.0052775964 +101 16 7.0399998e-05 +114 16 7.0399998e-05 +141 16 0.00091479998 +143 16 0.0015480998 +171 16 7.0399998e-05 +198 16 0.0033072999 +200 16 7.0399998e-05 +201 16 7.0399998e-05 +206 16 7.0399998e-05 +214 16 0.0030961998 +215 16 0.00014069999 +217 16 0.0026035998 +223 16 0.00021109999 +234 16 0.016114298 +237 16 0.0038701999 +241 16 0.010766298 +263 16 0.0040109977 +273 16 7.0399998e-05 +279 16 7.0399998e-05 +283 16 7.0399998e-05 +307 16 7.0399998e-05 +317 16 0.00077399984 +328 16 7.0399998e-05 +329 16 0.005840499 +356 16 0.00028149993 +357 16 0.00014069999 +394 16 0.00056289998 +397 16 7.0399998e-05 +402 16 0.00028149993 +442 16 7.0399998e-05 +443 16 0.0012665999 +444 16 7.0399998e-05 +445 16 0.0052775964 +446 16 0.00063329982 +447 16 0.00014069999 +448 16 0.00028149993 +450 16 0.0023924999 +452 16 0.0069663972 +453 16 0.0074589998 +454 16 0.00049259979 +455 16 0.053550098 +456 16 0.0247695 +457 16 0.0041516982 +458 16 0.00035179988 +460 16 0.0045738965 +463 16 0.0157624 +467 16 0.0066849999 +468 16 0.012806997 +469 16 0.0013369999 +470 16 0.00042219996 +471 16 0.0028851 +478 16 0.00028149993 +483 16 0.00014069999 +490 16 7.0399998e-05 +3 17 0.0019595998 +6 17 0.0056116991 +12 17 0.00017809999 +16 17 0.00093529979 +17 17 0.0040973984 +18 17 0.023560297 +62 17 0.0004453999 +98 17 0.00031179981 +101 17 0.010822598 +102 17 0.0042755976 +104 17 0.0001336 +107 17 0.0004453999 +108 17 4.449999e-05 +111 17 8.9099995e-05 +114 17 0.00017809999 +118 17 0.0001336 +123 17 0.010599896 +126 17 4.449999e-05 +139 17 0.0083284974 +141 17 0.011401597 +143 17 0.0035184999 +154 17 0.010020897 +194 17 4.449999e-05 +200 17 4.449999e-05 +206 17 8.9099995e-05 +207 17 0.001737 +214 17 0.0089965984 +215 17 0.00071259984 +217 17 0.00075709983 +223 17 0.0016923998 +228 17 0.0001336 +233 17 0.0037856998 +234 17 0.023248598 +237 17 0.0018259999 +240 17 4.449999e-05 +251 17 0.00062349997 +252 17 0.0001336 +300 17 0.017414197 +317 17 0.0013806999 +319 17 0.004587397 +322 17 0.0084620975 +326 17 0.0042755976 +328 17 0.0079721995 +329 17 0.00031179981 +350 17 0.0076603964 +356 17 8.9099995e-05 +384 17 0.0011133999 +387 17 4.449999e-05 +394 17 8.9099995e-05 +397 17 4.449999e-05 +402 17 8.9099995e-05 +404 17 4.449999e-05 +406 17 0.020353597 +407 17 0.0082393996 +414 17 0.0036074999 +422 17 4.449999e-05 +430 17 0.0031621999 +443 17 0.0021378 +444 17 0.0016033 +445 17 0.011134397 +446 17 0.00080169993 +447 17 0.0016033 +448 17 0.0004453999 +450 17 0.0021378 +452 17 0.0003562998 +453 17 0.00031179981 +454 17 4.449999e-05 +455 17 0.031443499 +456 17 0.00066809985 +457 17 0.0050326996 +458 17 4.449999e-05 +459 17 8.9099995e-05 +460 17 0.0068141967 +463 17 0.010688998 +464 17 0.0022713998 +465 17 0.00062349997 +467 17 0.017235998 +468 17 0.0019150998 +469 17 0.0035629999 +470 17 0.0019150998 +471 17 0.0096200965 +473 17 4.449999e-05 +476 17 0.00026719994 +477 17 0.0004453999 +478 17 0.0001336 +483 17 0.00026719994 +489 17 0.00017809999 +490 17 0.00026719994 +491 17 0.0011133999 +0 18 0.0003849999 +1 18 0.045257699 +2 18 0.019127999 +3 18 0.00055339979 +4 18 9.619999e-05 +5 18 0.00076989993 +6 18 0.016721997 +7 18 0.0018044999 +9 18 2.4099994e-05 +11 18 9.619999e-05 +12 18 9.619999e-05 +13 18 2.4099994e-05 +14 18 0.00052929996 +16 18 0.0096481964 +17 18 0.0025262998 +18 18 0.030460499 +24 18 0.00045709987 +25 18 9.619999e-05 +60 18 0.013112899 +62 18 0.00096239988 +79 18 2.4099994e-05 +82 18 2.4099994e-05 +83 18 2.4099994e-05 +84 18 2.4099994e-05 +98 18 0.00055339979 +101 18 0.0049564987 +102 18 0.0056061 +104 18 0.00057749986 +107 18 0.0001203 +108 18 4.8099988e-05 +111 18 2.4099994e-05 +113 18 7.2199997e-05 +114 18 0.0001203 +117 18 9.619999e-05 +118 18 0.00079399999 +126 18 7.2199997e-05 +127 18 2.4099994e-05 +130 18 2.4099994e-05 +141 18 9.619999e-05 +143 18 0.010249697 +153 18 0.0031518999 +154 18 4.8099988e-05 +172 18 0.0043789968 +192 18 0.00021649999 +193 18 4.8099988e-05 +194 18 0.00048119994 +195 18 4.8099988e-05 +196 18 7.2199997e-05 +197 18 0.0001203 +198 18 0.027837899 +201 18 7.2199997e-05 +203 18 0.0003849999 +204 18 0.00055339979 +206 18 0.00093839993 +207 18 0.00031279982 +209 18 9.619999e-05 +214 18 0.0013714 +215 18 0.017564099 +217 18 0.014508396 +219 18 2.4099994e-05 +223 18 0.0001203 +228 18 4.8099988e-05 +229 18 2.4099994e-05 +234 18 0.0194408 +237 18 0.0015399 +240 18 2.4099994e-05 +241 18 0.0001203 +248 18 2.4099994e-05 +250 18 2.4099994e-05 +251 18 0.00079399999 +252 18 0.00033679977 +263 18 2.4099994e-05 +267 18 0.0022856998 +279 18 2.4099994e-05 +315 18 2.4099994e-05 +317 18 7.2199997e-05 +322 18 0.0037774998 +326 18 0.0036090999 +328 18 0.0042827986 +329 18 0.0027188 +330 18 0.0027669999 +356 18 4.8099988e-05 +363 18 2.4099994e-05 +387 18 4.8099988e-05 +394 18 0.00014439999 +397 18 7.2199997e-05 +398 18 0.0019007998 +402 18 0.0038977999 +404 18 0.0013714 +412 18 0.00079399999 +419 18 2.4099994e-05 +422 18 0.00043309992 +423 18 2.4099994e-05 +425 18 2.4099994e-05 +430 18 4.8099988e-05 +431 18 7.2199997e-05 +432 18 7.2199997e-05 +433 18 0.0002406 +434 18 0.00028869999 +438 18 0.00055339979 +443 18 0.0034647 +444 18 0.0045714974 +445 18 0.0066406988 +446 18 0.00089019979 +447 18 0.017179199 +448 18 0.0003849999 +449 18 2.4099994e-05 +450 18 0.0056541972 +452 18 0.0075308979 +453 18 0.0026225999 +454 18 0.00033679977 +455 18 0.031446997 +456 18 0.0060872994 +457 18 0.0045233965 +458 18 0.0041383989 +459 18 7.2199997e-05 +460 18 0.0058706999 +463 18 0.035681598 +464 18 0.0041383989 +465 18 0.0012270999 +467 18 0.047423098 +468 18 0.0051007979 +469 18 0.0114046 +470 18 0.0067849979 +471 18 0.016000196 +473 18 0.00014439999 +474 18 4.8099988e-05 +476 18 0.00098649994 +477 18 7.2199997e-05 +478 18 0.0027909998 +483 18 0.0013714 +489 18 0.0002406 +490 18 0.00052929996 +491 18 9.619999e-05 +19 19 0.018687297 +20 19 0.0071814992 +21 19 0.0027798999 +22 19 0.0033976999 +24 19 0.0048648976 +60 19 0.025250997 +114 19 7.7199991e-05 +126 19 7.7199991e-05 +159 19 0.00054049981 +160 19 0.0015443999 +206 19 0.0001544 +214 19 0.0068725981 +215 19 0.00092659984 +220 19 0.010965299 +234 19 0.010115799 +237 19 0.010038599 +242 19 0.0026254999 +252 19 0.00030889991 +254 19 0.00030889991 +267 19 0.0012355 +272 19 0.00023169999 +277 19 0.010656398 +282 19 0.014517397 +283 19 0.0108108 +294 19 7.7199991e-05 +295 19 0.0041699 +312 19 0.0016215998 +317 19 0.00061779981 +322 19 0.011196896 +328 19 0.0035520999 +331 19 0.009034697 +332 19 0.009034697 +335 19 0.0020848999 +336 19 7.7199991e-05 +340 19 0.00023169999 +343 19 7.7199991e-05 +350 19 0.00092659984 +352 19 0.0019304999 +356 19 0.00030889991 +372 19 0.0020076998 +374 19 0.00023169999 +384 19 0.0003860998 +398 19 0.0001544 +402 19 0.018455599 +408 19 0.0016215998 +442 19 0.0020848999 +443 19 0.0056370981 +444 19 0.0035520999 +445 19 0.0078763999 +446 19 0.00069499994 +447 19 0.0030887998 +448 19 7.7199991e-05 +450 19 0.00077219983 +452 19 0.038146697 +453 19 0.0203861 +454 19 0.0064864978 +455 19 0.023629297 +456 19 0.00030889991 +457 19 0.0030115999 +459 19 0.0014672 +460 19 0.0010038998 +463 19 0.19752896 +464 19 0.00023169999 +465 19 0.00030889991 +467 19 0.019845597 +468 19 0.0097296983 +469 19 0.0013126999 +470 19 0.0012355 +471 19 0.0019304999 +473 19 7.7199991e-05 +477 19 0.0003860998 +478 19 0.00069499994 +483 19 0.0013899999 +489 19 0.0029344 +490 19 0.0001544 +491 19 0.0094207972 +19 20 6.4199994e-05 +20 20 0.13482279 +21 20 0.0053928979 +22 20 0.0001926 +24 20 0.00038519991 +60 20 0.0049434975 +114 20 6.4199994e-05 +126 20 6.4199994e-05 +130 20 0.00038519991 +143 20 6.4199994e-05 +159 20 0.0026322999 +160 20 6.4199994e-05 +194 20 6.4199994e-05 +206 20 0.00012839999 +214 20 0.026001498 +215 20 0.0015407999 +220 20 0.006805297 +234 20 0.010336399 +237 20 0.024011299 +242 20 0.00070619979 +252 20 0.00038519991 +254 20 0.00077039981 +265 20 0.0001926 +267 20 0.0069978982 +277 20 0.0044298992 +282 20 0.010464799 +283 20 0.0079609975 +284 20 6.4199994e-05 +294 20 0.001926 +312 20 0.0030174998 +317 20 0.00051359995 +322 20 0.0082177967 +328 20 6.4199994e-05 +331 20 0.0093733966 +332 20 0.0090523995 +335 20 0.001284 +336 20 0.00089879986 +350 20 6.4199994e-05 +356 20 0.00038519991 +358 20 0.00012839999 +372 20 0.00070619979 +384 20 0.00025679986 +386 20 0.00025679986 +398 20 0.00044939993 +402 20 0.00077039981 +408 20 0.0017976 +413 20 0.00032099988 +422 20 6.4199994e-05 +442 20 6.4199994e-05 +443 20 0.0041731 +444 20 0.00012839999 +445 20 0.0041731 +446 20 0.00096299988 +447 20 0.00038519991 +448 20 0.0001926 +450 20 0.00077039981 +452 20 0.027413998 +453 20 0.0050076991 +454 20 0.0012198 +455 20 0.032999497 +456 20 0.00051359995 +457 20 0.0059706978 +458 20 6.4199994e-05 +459 20 0.0030174998 +460 20 0.00083459984 +463 20 0.010528997 +464 20 6.4199994e-05 +465 20 0.00044939993 +467 20 0.014766298 +468 20 0.00083459984 +469 20 0.0013481998 +470 20 0.0015407999 +471 20 0.0023753999 +473 20 6.4199994e-05 +477 20 0.00032099988 +478 20 0.00077039981 +483 20 0.00070619979 +489 20 0.00070619979 +490 20 0.0001926 +491 20 0.022984099 +20 21 0.0012299998 +21 21 0.045971699 +22 21 0.00015379999 +24 21 0.00015379999 +60 21 0.013837598 +114 21 0.00015379999 +159 21 0.0053812973 +160 21 0.0039974973 +206 21 0.0003074999 +214 21 0.021678999 +215 21 0.0003074999 +220 21 0.0087637976 +223 21 0.0015374999 +224 21 0.0003074999 +234 21 0.012915097 +237 21 0.0063037984 +242 21 0.0007687998 +252 21 0.00061499979 +254 21 0.00061499979 +272 21 0.0038437999 +277 21 0.017681397 +282 21 0.00015379999 +295 21 0.0003074999 +305 21 0.00015379999 +312 21 0.0044588 +322 21 0.0072262995 +328 21 0.010762598 +331 21 0.014145099 +332 21 0.0133764 +335 21 0.0018449998 +336 21 0.0010762999 +341 21 0.0010762999 +350 21 0.00015379999 +352 21 0.0003074999 +356 21 0.0004612999 +358 21 0.0130689 +372 21 0.0026137999 +384 21 0.0003074999 +398 21 0.0018449998 +402 21 0.0015374999 +442 21 0.0063037984 +443 21 0.0030749999 +444 21 0.0070725977 +445 21 0.0047662966 +446 21 0.0004612999 +447 21 0.0044588 +450 21 0.0007687998 +452 21 0.029520299 +453 21 0.0035362998 +454 21 0.0024599999 +455 21 0.019372698 +456 21 0.00061499979 +457 21 0.011377599 +458 21 0.0041512996 +459 21 0.0069187991 +460 21 0.0052275993 +463 21 0.0435117 +464 21 0.0027674998 +465 21 0.00061499979 +467 21 0.023216497 +468 21 0.0010762999 +469 21 0.0018449998 +470 21 0.0012299998 +471 21 0.0033824998 +477 21 0.0007687998 +478 21 0.0010762999 +483 21 0.0013837998 +489 21 0.00061499979 +490 21 0.00015379999 +491 21 0.0047662966 +19 22 0.00029419991 +22 22 0.12051398 +60 22 0.0083099976 +82 22 1.8399995e-05 +108 22 1.8399995e-05 +114 22 1.8399995e-05 +126 22 1.8399995e-05 +130 22 0.0020774999 +150 22 0.00071699987 +159 22 0.0068943985 +189 22 1.8399995e-05 +190 22 9.1899987e-05 +192 22 1.8399995e-05 +193 22 0.0022796998 +194 22 1.8399995e-05 +200 22 1.8399995e-05 +203 22 1.8399995e-05 +204 22 3.6799989e-05 +206 22 5.5199998e-05 +207 22 1.8399995e-05 +214 22 0.00051479996 +215 22 0.0025738999 +220 22 0.0070965998 +223 22 3.6799989e-05 +234 22 0.014395498 +237 22 0.0050558969 +242 22 0.0036401998 +252 22 3.6799989e-05 +264 22 0.00049639982 +265 22 0.0012502 +267 22 0.00012869999 +272 22 5.5199998e-05 +273 22 0.0029048 +277 22 0.0097991973 +282 22 1.8399995e-05 +284 22 1.8399995e-05 +295 22 0.0026841999 +305 22 1.8399995e-05 +312 22 0.012299597 +317 22 0.00029419991 +322 22 0.0033276998 +328 22 0.0015626999 +331 22 0.031125899 +332 22 0.016270798 +335 22 0.0027760998 +340 22 0.00018389999 +352 22 0.00068019982 +356 22 0.00034929998 +358 22 0.00064349989 +372 22 0.00049639982 +374 22 5.5199998e-05 +384 22 0.0001103 +385 22 0.0020223998 +387 22 1.8399995e-05 +394 22 3.6799989e-05 +397 22 3.6799989e-05 +402 22 0.00022059999 +417 22 0.00012869999 +422 22 1.8399995e-05 +430 22 1.8399995e-05 +433 22 1.8399995e-05 +434 22 1.8399995e-05 +442 22 0.00068019982 +443 22 0.0030334999 +444 22 0.00022059999 +445 22 0.0035299 +446 22 0.00047799991 +447 22 0.0022429998 +448 22 0.00018389999 +450 22 0.00093759992 +452 22 0.019524898 +453 22 0.0001103 +454 22 0.00055159978 +455 22 0.030004397 +456 22 0.00064349989 +457 22 0.0031989999 +458 22 9.1899987e-05 +459 22 0.00080889999 +460 22 0.0025370999 +463 22 0.041090596 +464 22 9.1899987e-05 +465 22 0.00064349989 +467 22 0.022742298 +468 22 0.0010478999 +469 22 0.0025922998 +470 22 0.0013052998 +471 22 0.0035850999 +473 22 3.6799989e-05 +477 22 0.00027579977 +478 22 0.0009192999 +483 22 0.0005698998 +489 22 0.00027579977 +490 22 0.0001103 +491 22 0.0050926991 +9 23 1.7899991e-05 +16 23 5.9999993e-06 +21 23 2.3899993e-05 +22 23 5.9999993e-06 +23 23 0.033729199 +24 23 3.5899997e-05 +25 23 5.9999993e-06 +60 23 0.0041899979 +66 23 4.1799998e-05 +74 23 0.036938999 +79 23 5.9999993e-06 +82 23 2.3899993e-05 +83 23 2.3899993e-05 +84 23 1.7899991e-05 +108 23 2.9899995e-05 +113 23 4.1799998e-05 +114 23 9.5599986e-05 +126 23 4.7799986e-05 +127 23 5.9999993e-06 +150 23 0.0001255 +189 23 4.1799998e-05 +190 23 2.3899993e-05 +192 23 1.2e-05 +194 23 1.7899991e-05 +196 23 5.9999993e-06 +197 23 1.2e-05 +200 23 2.3899993e-05 +201 23 1.2e-05 +203 23 1.7899991e-05 +204 23 1.7899991e-05 +206 23 3.5899997e-05 +207 23 1.2e-05 +209 23 5.9999993e-06 +214 23 0.0043453984 +215 23 5.9999993e-06 +223 23 0.0021098999 +233 23 0.00019129999 +234 23 0.0036699998 +237 23 0.0002331 +241 23 1.2e-05 +242 23 5.9999993e-06 +248 23 1.7899991e-05 +250 23 1.2e-05 +251 23 5.9999993e-06 +252 23 0.0002331 +254 23 0.0001255 +263 23 5.9999993e-06 +272 23 8.3699997e-05 +277 23 0.006281998 +281 23 0.00028689997 +287 23 5.9999993e-06 +307 23 0.00093839993 +311 23 2.3899993e-05 +317 23 5.9999993e-06 +319 23 0.0001853 +324 23 0.0032754999 +326 23 0.0010758999 +328 23 0.0025462999 +331 23 0.00053789979 +333 23 0.0060369968 +340 23 0.00016739999 +349 23 5.9999993e-06 +350 23 0.0024924998 +351 23 0.0001375 +354 23 0.0010519999 +356 23 0.00039449986 +358 23 0.0041301996 +369 23 0.00028089993 +370 23 0.0004482998 +372 23 0.0051223971 +374 23 0.00094439997 +380 23 5.9999993e-06 +385 23 0.0002331 +386 23 0.00010159999 +387 23 3.5899997e-05 +390 23 0.00016139999 +394 23 1.7899991e-05 +397 23 1.7899991e-05 +402 23 0.00010759999 +404 23 0.0001853 +414 23 0.00047819992 +419 23 5.9999993e-06 +422 23 2.9899995e-05 +423 23 1.2e-05 +425 23 5.9999993e-06 +430 23 2.3899993e-05 +431 23 5.9999993e-06 +432 23 5.9999993e-06 +433 23 1.2e-05 +434 23 1.2e-05 +442 23 0.0002271 +443 23 0.00059169997 +444 23 0.0005857998 +445 23 0.0013149998 +446 23 0.0001733 +447 23 0.0033053998 +448 23 7.7699995e-05 +449 23 1.2e-05 +450 23 0.0026000999 +452 23 0.0088342987 +453 23 0.0029348 +454 23 0.0021756999 +455 23 0.0046322979 +456 23 0.00054389983 +457 23 0.0033710999 +458 23 8.9699999e-05 +459 23 0.00082489988 +460 23 0.0020740998 +463 23 0.15183824 +464 23 0.00059769978 +465 23 0.00030479999 +467 23 0.014524497 +468 23 0.00026299991 +469 23 0.007280197 +470 23 0.0056543984 +471 23 0.0014344999 +473 23 0.00010159999 +477 23 1.7899991e-05 +478 23 0.00035859994 +483 23 0.00055589993 +489 23 0.00039449986 +490 23 0.00035859994 +491 23 5.3799988e-05 +22 24 0.0014771998 +24 24 0.025145996 +25 24 3.4399985e-05 +60 24 0.0065956973 +108 24 3.4399985e-05 +114 24 6.8699999e-05 +126 24 3.4399985e-05 +150 24 0.00072139991 +160 24 6.8699999e-05 +169 24 0.0002061 +171 24 3.4399985e-05 +190 24 0.0001374 +191 24 3.4399985e-05 +192 24 0.0001374 +193 24 0.0040535964 +194 24 0.0001031 +197 24 3.4399985e-05 +198 24 0.0001374 +200 24 6.8699999e-05 +203 24 6.8699999e-05 +204 24 6.8699999e-05 +206 24 0.0001374 +207 24 3.4399985e-05 +214 24 0.0023015998 +215 24 0.0015115 +218 24 3.4399985e-05 +220 24 0.009275198 +223 24 0.0002748 +231 24 0.0001718 +233 24 6.8699999e-05 +234 24 0.030951597 +235 24 0.0001031 +237 24 0.0067673996 +240 24 0.00034349994 +241 24 0.0002061 +242 24 0.0021986 +252 24 0.0001374 +254 24 0.0083132982 +266 24 0.0002061 +267 24 3.4399985e-05 +269 24 3.4399985e-05 +270 24 0.0001031 +272 24 0.00061829994 +273 24 0.00037789997 +276 24 3.4399985e-05 +277 24 0.011954699 +282 24 0.0089659989 +283 24 0.00079009985 +289 24 0.00079009985 +292 24 0.00030919979 +295 24 0.0015801999 +297 24 0.0009961999 +300 24 3.4399985e-05 +301 24 3.4399985e-05 +305 24 0.0012367 +307 24 0.00037789997 +312 24 0.0018206998 +317 24 0.0002748 +322 24 0.0071452968 +326 24 3.4399985e-05 +328 24 0.011130199 +331 24 0.020336699 +332 24 0.015218098 +335 24 0.0041909963 +336 24 0.0029199999 +337 24 0.0014771998 +341 24 6.8699999e-05 +350 24 0.0002405 +351 24 0.0018549999 +352 24 0.00034349994 +354 24 0.0020611 +356 24 0.00048089982 +358 24 0.00085879979 +371 24 0.0001031 +372 24 0.0012023 +373 24 3.4399985e-05 +374 24 0.0002061 +384 24 0.0001031 +386 24 0.00030919979 +387 24 3.4399985e-05 +394 24 0.0001031 +397 24 6.8699999e-05 +402 24 0.0059772991 +422 24 0.0001031 +433 24 3.4399985e-05 +434 24 3.4399985e-05 +438 24 3.4399985e-05 +442 24 0.0012023 +443 24 0.0036413998 +444 24 0.0017519998 +445 24 0.009275198 +446 24 0.0012709999 +447 24 0.0022328999 +448 24 0.00044659991 +450 24 0.0012709999 +452 24 0.025523897 +453 24 0.0073857978 +454 24 0.0037101 +455 24 0.0282721 +456 24 0.0018549999 +457 24 0.0065269992 +458 24 0.0002748 +459 24 0.0027137999 +460 24 0.004637599 +463 24 0.0366541 +464 24 0.0012023 +465 24 0.00085879979 +467 24 0.0297492 +468 24 0.0016832999 +469 24 0.0038130998 +470 24 0.0011679998 +471 24 0.0098247975 +473 24 3.4399985e-05 +477 24 3.4399985e-05 +478 24 0.0012367 +483 24 0.00054959999 +489 24 0.00092749996 +490 24 0.0001031 +491 24 0.0042253993 +22 25 0.0014227999 +24 25 0.017073199 +25 25 0.032520298 +60 25 0.011788599 +104 25 0.00020329999 +114 25 0.00020329999 +126 25 0.00020329999 +130 25 0.00060979999 +160 25 0.0008129999 +190 25 0.00020329999 +193 25 0.0028454999 +194 25 0.00020329999 +206 25 0.00020329999 +214 25 0.015243899 +218 25 0.00060979999 +220 25 0.0044714995 +223 25 0.0012194999 +231 25 0.00020329999 +234 25 0.016869899 +237 25 0.0028454999 +240 25 0.00020329999 +242 25 0.00040649995 +252 25 0.00020329999 +257 25 0.00020329999 +272 25 0.00020329999 +277 25 0.017886199 +282 25 0.0028454999 +283 25 0.0024389999 +292 25 0.00060979999 +295 25 0.00060979999 +297 25 0.00020329999 +305 25 0.0020325 +308 25 0.00020329999 +312 25 0.0071137995 +322 25 0.0022357998 +328 25 0.0079267994 +331 25 0.013821099 +332 25 0.0097560994 +333 25 0.00020329999 +335 25 0.0008129999 +336 25 0.0020325 +337 25 0.0012194999 +350 25 0.0008129999 +351 25 0.00060979999 +352 25 0.0008129999 +354 25 0.0010162999 +356 25 0.0010162999 +371 25 0.00040649995 +372 25 0.0016259998 +374 25 0.00060979999 +384 25 0.00020329999 +394 25 0.00020329999 +402 25 0.0020325 +408 25 0.00060979999 +442 25 0.0054877996 +443 25 0.0065040998 +444 25 0.0044714995 +445 25 0.0032519998 +446 25 0.00060979999 +447 25 0.0038617998 +448 25 0.00020329999 +450 25 0.0014227999 +452 25 0.038008098 +453 25 0.041260198 +454 25 0.0091462992 +455 25 0.014837399 +456 25 0.0014227999 +457 25 0.015447199 +458 25 0.00020329999 +459 25 0.0014227999 +460 25 0.0018292998 +463 25 0.045934997 +464 25 0.00060979999 +465 25 0.00040649995 +467 25 0.034349598 +468 25 0.0010162999 +469 25 0.0022357998 +470 25 0.0022357998 +471 25 0.0063007995 +473 25 0.00020329999 +478 25 0.0010162999 +483 25 0.0034552999 +489 25 0.0014227999 +490 25 0.00020329999 +491 25 0.0052846 +7 26 0.00024609989 +9 26 2.0499996e-05 +16 26 0.0015481999 +17 26 3.3999995e-06 +18 26 0.0011995998 +24 26 0.0024024998 +60 26 0.00048529985 +79 26 1.7099999e-05 +80 26 2.729999e-05 +82 26 3.7599995e-05 +83 26 2.729999e-05 +84 26 2.729999e-05 +108 26 3.7599995e-05 +113 26 4.4399989e-05 +114 26 0.00015379999 +126 26 7.1799994e-05 +127 26 1.0299999e-05 +134 26 0.010697 +135 26 0.00015379999 +139 26 0.0018010999 +141 26 2.729999e-05 +142 26 0.0001162 +150 26 0.00012299999 +154 26 2.3899993e-05 +160 26 0.051157497 +161 26 0.0011312 +162 26 0.0035849998 +163 26 0.038553499 +164 26 0.0095007978 +165 26 0.024753399 +167 26 0.023434199 +168 26 2.3899993e-05 +170 26 0.00059119985 +171 26 0.0032124999 +177 26 0.0012063999 +182 26 0.0015207999 +189 26 3.7599995e-05 +191 26 0.0027818999 +192 26 0.00058439979 +194 26 4.0999992e-05 +195 26 3.0799987e-05 +196 26 6.7999999e-06 +197 26 0.001432 +198 26 4.4399989e-05 +201 26 3.0799987e-05 +203 26 4.7799986e-05 +204 26 7.1799994e-05 +206 26 0.0001504 +207 26 3.7599995e-05 +209 26 1.37e-05 +214 26 0.0002153 +215 26 0.00011959999 +218 26 1.7099999e-05 +219 26 0.00026999996 +223 26 0.00023919999 +233 26 0.0032295999 +234 26 0.00068689999 +235 26 0.00024949992 +236 26 0.0061754994 +237 26 0.0013601999 +240 26 0.00090909982 +241 26 0.0094802976 +242 26 0.00021869999 +248 26 3.0799987e-05 +250 26 1.37e-05 +251 26 6.7999999e-06 +252 26 0.0011586 +254 26 0.0029424999 +255 26 0.0065069981 +256 26 0.0031817998 +257 26 0.00080649997 +258 26 0.0017497998 +259 26 0.0032090999 +263 26 3.3999995e-06 +264 26 0.010167297 +265 26 0.0019172998 +266 26 0.0312468 +267 26 9.229999e-05 +268 26 0.0056013986 +269 26 0.0021940998 +270 26 4.7799986e-05 +271 26 0.0014079998 +272 26 8.8899993e-05 +273 26 0.00046139979 +274 26 0.0028126999 +277 26 0.0026348999 +279 26 0.0020915 +282 26 0.0013020998 +285 26 3.0799987e-05 +292 26 0.0030109 +293 26 4.7799986e-05 +295 26 0.0049144998 +302 26 0.0050374977 +303 26 0.004220698 +304 26 0.0028331999 +305 26 2.0499996e-05 +306 26 0.015512299 +307 26 0.0004784998 +308 26 0.01055 +309 26 0.00057069981 +310 26 0.00022209999 +311 26 0.0017497998 +312 26 0.0001299 +317 26 0.0024913999 +318 26 7.5199991e-05 +319 26 0.0058884993 +322 26 0.0011687998 +323 26 6.7999999e-06 +324 26 0.00042379997 +326 26 3.3999995e-06 +331 26 0.0014524998 +341 26 0.00020509999 +350 26 0.0020949999 +352 26 0.00039639999 +356 26 4.0999992e-05 +358 26 0.00016059999 +363 26 3.3999995e-06 +366 26 0.012026399 +368 26 0.00056389999 +371 26 0.0032398999 +374 26 6.7999999e-06 +380 26 0.0010799998 +383 26 0.0015207999 +384 26 3.7599995e-05 +385 26 0.0040019974 +386 26 0.0019479999 +387 26 6.8399997e-05 +390 26 0.00065279985 +394 26 0.0001333 +397 26 3.3999995e-06 +398 26 0.00053659989 +402 26 0.00028019981 +412 26 6.7999999e-06 +414 26 1.0299999e-05 +415 26 0.0013840999 +419 26 1.0299999e-05 +422 26 0.0001948 +423 26 2.3899993e-05 +425 26 1.0299999e-05 +430 26 3.4199998e-05 +431 26 2.3899993e-05 +432 26 1.0299999e-05 +433 26 2.729999e-05 +434 26 3.0799987e-05 +438 26 0.00026659993 +439 26 0.0014729998 +441 26 6.7999999e-06 +442 26 3.3999995e-06 +443 26 0.010608099 +444 26 0.00020509999 +445 26 0.0136429 +446 26 0.0016814 +447 26 0.0010115998 +448 26 3.3999995e-06 +449 26 1.37e-05 +450 26 0.0049417987 +452 26 0.00074499985 +453 26 8.8899993e-05 +454 26 0.0014660999 +455 26 0.046813797 +456 26 0.059373397 +457 26 0.0051946975 +458 26 0.00037929998 +459 26 2.729999e-05 +460 26 0.0038002999 +463 26 0.010515798 +464 26 0.00026319991 +465 26 0.00015719999 +467 26 0.012781698 +468 26 0.00077919988 +469 26 0.033734798 +470 26 0.0076621994 +471 26 0.0042445995 +473 26 0.00017429999 +477 26 5.1299998e-05 +478 26 0.00086119981 +483 26 0.00054679997 +489 26 9.9099998e-05 +490 26 0.00061519979 +491 26 0.00019139999 +7 27 0.00040699984 +16 27 0.0021831999 +18 27 0.0016281998 +24 27 0.0034043998 +60 27 0.00014799999 +80 27 7.3999996e-05 +108 27 3.6999991e-05 +113 27 3.6999991e-05 +114 27 7.3999996e-05 +126 27 3.6999991e-05 +134 27 0.011175297 +135 27 0.00014799999 +139 27 0.0010730999 +141 27 3.6999991e-05 +142 27 7.3999996e-05 +150 27 3.6999991e-05 +154 27 7.3999996e-05 +160 27 0.033488799 +161 27 0.00070309988 +162 27 0.0018871999 +163 27 0.026161898 +164 27 0.0076228976 +165 27 0.021869399 +167 27 0.0045144968 +168 27 0.00048109982 +170 27 0.00055509992 +171 27 0.0026642999 +177 27 0.00099909981 +182 27 0.0012210999 +191 27 0.0023312999 +192 27 0.00055509992 +195 27 0.00040699984 +197 27 0.00096209999 +198 27 3.6999991e-05 +206 27 7.3999996e-05 +214 27 0.00029599993 +215 27 0.00011099999 +219 27 0.0017392 +223 27 0.00036999979 +233 27 0.0055875964 +234 27 0.0017392 +235 27 0.0014062 +236 27 0.0037743999 +237 27 0.0010360999 +240 27 0.00092509994 +241 27 0.0099540986 +242 27 0.000185 +252 27 0.00085109985 +254 27 0.0026642999 +255 27 0.0043294989 +256 27 0.0021092 +257 27 0.00059209997 +258 27 0.0012951 +259 27 0.0022201999 +262 27 3.6999991e-05 +264 27 0.0068827979 +265 27 0.0042554997 +266 27 0.025939897 +267 27 0.00025899988 +268 27 0.0059946999 +269 27 0.0013320998 +270 27 3.6999991e-05 +271 27 0.0023683 +272 27 7.3999996e-05 +273 27 0.00029599993 +274 27 0.0027382998 +277 27 0.0046254992 +279 27 0.0016651999 +282 27 0.0019611998 +285 27 0.00014799999 +292 27 0.0025902998 +293 27 0.00011099999 +295 27 0.0052175969 +302 27 0.0028122999 +303 27 0.0038113999 +304 27 0.0027013 +305 27 0.00025899988 +306 27 0.016577899 +307 27 0.00048109982 +308 27 0.0099910982 +309 27 0.0017021999 +310 27 0.00022199999 +311 27 0.0028863 +312 27 0.00025899988 +317 27 0.00092509994 +318 27 3.6999991e-05 +319 27 0.0049955994 +322 27 0.0017761998 +324 27 0.00044399989 +331 27 0.0010730999 +334 27 0.00025899988 +341 27 7.3999996e-05 +350 27 0.0030713 +352 27 0.0010730999 +356 27 7.3999996e-05 +358 27 3.6999991e-05 +366 27 0.013173498 +368 27 0.0011470998 +371 27 0.0042554997 +380 27 0.0012951 +381 27 0.0012210999 +383 27 0.0017761998 +384 27 0.00011099999 +385 27 0.0032933999 +386 27 0.0027382998 +387 27 3.6999991e-05 +390 27 0.00066609983 +394 27 7.3999996e-05 +398 27 0.00040699984 +402 27 0.00025899988 +415 27 0.0012951 +422 27 3.6999991e-05 +430 27 3.6999991e-05 +438 27 0.00025899988 +439 27 0.00096209999 +441 27 3.6999991e-05 +443 27 0.0071787983 +444 27 7.3999996e-05 +445 27 0.013617497 +446 27 0.00085109985 +447 27 0.00036999979 +450 27 0.0016651999 +452 27 0.00025899988 +453 27 3.6999991e-05 +454 27 0.00048109982 +455 27 0.037374198 +456 27 0.045145098 +457 27 0.0017392 +458 27 0.00022199999 +460 27 0.0022942999 +463 27 0.0035523998 +464 27 7.3999996e-05 +465 27 3.6999991e-05 +467 27 0.008547999 +468 27 0.00025899988 +469 27 0.065201283 +470 27 0.0025902998 +471 27 0.0027752998 +473 27 7.3999996e-05 +478 27 0.00029599993 +483 27 0.000185 +489 27 3.6999991e-05 +490 27 0.00022199999 +491 27 0.00014799999 +7 28 0.00049079978 +9 28 8.2999995e-06 +16 28 0.0028199998 +18 28 0.0021046 +24 28 0.0045419969 +60 28 0.00010809999 +80 28 7.4899988e-05 +82 28 8.2999995e-06 +83 28 8.2999995e-06 +84 28 8.2999995e-06 +108 28 1.6599995e-05 +113 28 1.6599995e-05 +114 28 3.3299992e-05 +126 28 2.4999987e-05 +127 28 8.2999995e-06 +134 28 0.012502898 +135 28 0.00019129999 +139 28 0.00054899999 +141 28 2.4999987e-05 +142 28 4.1599997e-05 +150 28 3.3299992e-05 +154 28 9.1499998e-05 +159 28 8.2999995e-06 +160 28 0.0223605 +161 28 0.00031609996 +162 28 0.00069879997 +163 28 0.018567197 +164 28 0.013417996 +165 28 0.021229196 +167 28 0.0083601996 +168 28 0.0009066998 +170 28 0.00054069981 +171 28 0.0023873998 +177 28 0.0017386 +182 28 0.0021627999 +183 28 1.6599995e-05 +189 28 8.2999995e-06 +191 28 0.0021378999 +192 28 0.00049909996 +194 28 8.2999995e-06 +195 28 0.0007487 +197 28 0.00069879997 +198 28 3.3299992e-05 +201 28 8.2999995e-06 +203 28 8.2999995e-06 +204 28 1.6599995e-05 +206 28 4.1599997e-05 +207 28 8.2999995e-06 +214 28 0.00029119989 +215 28 0.00010809999 +218 28 2.4999987e-05 +219 28 0.0021545 +220 28 8.2999995e-06 +223 28 0.00048249983 +233 28 0.0054736994 +234 28 0.0026868999 +235 28 0.0023624999 +236 28 0.0021627999 +237 28 0.00064049987 +240 28 0.00092339981 +241 28 0.010914098 +242 28 0.000183 +248 28 8.2999995e-06 +250 28 8.2999995e-06 +252 28 0.00066549983 +254 28 0.0025787998 +255 28 0.0029281999 +256 28 0.0012643998 +257 28 0.00049079978 +258 28 0.00095659983 +259 28 0.0015472998 +262 28 7.4899988e-05 +264 28 0.0048413984 +265 28 0.0064219981 +266 28 0.023990899 +267 28 0.00034939987 +268 28 0.0068461969 +269 28 0.00059059984 +270 28 2.4999987e-05 +271 28 0.0028948998 +272 28 7.4899988e-05 +273 28 0.00019129999 +274 28 0.0030029998 +277 28 0.0063969977 +279 28 0.0014308 +282 28 0.0026785999 +285 28 0.00014969999 +292 28 0.0025121998 +293 28 0.0001581 +295 28 0.0057481974 +302 28 0.0021046 +303 28 0.0046583973 +304 28 0.0027700998 +305 28 0.00031609996 +306 28 0.018883299 +307 28 0.00045749987 +308 28 0.020472199 +309 28 0.0026452998 +310 28 0.00025789998 +311 28 0.0038681999 +312 28 0.0003992999 +317 28 0.00057399995 +318 28 1.6599995e-05 +319 28 0.004724998 +322 28 0.0022127999 +324 28 0.00048249983 +331 28 0.00066549983 +334 28 0.00044089998 +335 28 8.2999995e-06 +341 28 4.1599997e-05 +350 28 0.004009597 +352 28 0.0013392998 +356 28 0.00014969999 +358 28 4.1599997e-05 +366 28 0.011454798 +368 28 0.0014640999 +371 28 0.0054736994 +374 28 2.4999987e-05 +380 28 0.0015305998 +383 28 0.0020879998 +384 28 0.0001581 +385 28 0.0029447998 +386 28 0.0034605998 +387 28 1.6599995e-05 +390 28 0.00074039982 +394 28 4.1599997e-05 +397 28 8.2999995e-06 +398 28 0.00032439991 +402 28 0.00016639999 +412 28 8.2999995e-06 +414 28 8.2999995e-06 +415 28 0.0013059999 +419 28 3.3299992e-05 +422 28 4.9899987e-05 +423 28 8.2999995e-06 +425 28 8.2999995e-06 +430 28 1.6599995e-05 +431 28 8.2999995e-06 +433 28 8.2999995e-06 +434 28 8.2999995e-06 +438 28 0.00029119989 +439 28 0.00041589979 +441 28 6.6499997e-05 +443 28 0.0068212971 +444 28 4.9899987e-05 +445 28 0.017810199 +446 28 0.00080689997 +447 28 0.0003992999 +448 28 8.2999995e-06 +450 28 0.0011063998 +452 28 0.00016639999 +453 28 1.6599995e-05 +454 28 0.00033269986 +455 28 0.0379912 +456 28 0.041984197 +457 28 0.0011562998 +458 28 0.00013309999 +460 28 0.0017551999 +463 28 0.0023542 +464 28 5.8199992e-05 +465 28 3.3299992e-05 +467 28 0.0056566969 +468 28 0.00017469999 +469 28 0.060168698 +470 28 0.0017135998 +471 28 0.0017718999 +473 28 4.1599997e-05 +477 28 8.2999995e-06 +478 28 0.00019129999 +483 28 0.0001165 +489 28 2.4999987e-05 +490 28 0.0001414 +491 28 6.6499997e-05 +7 29 0.00025089993 +9 29 2.5099987e-05 +16 29 0.0013299999 +18 29 0.0010038 +24 29 0.0021329999 +60 29 0.00030109985 +80 29 0.00022579999 +82 29 2.5099987e-05 +83 29 2.5099987e-05 +84 29 2.5099987e-05 +108 29 5.0199989e-05 +113 29 5.0199989e-05 +114 29 0.00010039999 +126 29 7.5299991e-05 +127 29 2.5099987e-05 +139 29 0.00030109985 +141 29 5.0199989e-05 +142 29 2.5099987e-05 +150 29 0.00010039999 +154 29 0.00010039999 +160 29 0.0070262998 +161 29 0.00087829982 +162 29 2.5099987e-05 +163 29 0.0124969 +164 29 0.0074528977 +165 29 0.0085821971 +168 29 0.00022579999 +170 29 0.00022579999 +171 29 0.0026850998 +177 29 0.00097869989 +182 29 0.0012546999 +183 29 2.5099987e-05 +189 29 2.5099987e-05 +191 29 0.00020079999 +192 29 0.00032619992 +194 29 2.5099987e-05 +197 29 0.0011292 +198 29 5.0199989e-05 +201 29 2.5099987e-05 +203 29 2.5099987e-05 +204 29 5.0199989e-05 +206 29 0.0001255 +207 29 2.5099987e-05 +214 29 7.5299991e-05 +215 29 7.5299991e-05 +219 29 0.0030866 +223 29 0.0003513 +233 29 0.0041655973 +234 29 0.0017064 +235 29 0.0010038 +236 29 0.00037639984 +237 29 0.00095359981 +240 29 0.0008280999 +241 29 0.00040149991 +242 29 0.00010039999 +252 29 0.00037639984 +254 29 0.0025093998 +255 29 0.0077540986 +256 29 0.0014052999 +257 29 0.00020079999 +258 29 0.00045169983 +259 29 0.0023337998 +264 29 0.0091592968 +265 29 0.0091342963 +266 29 0.035558298 +267 29 0.0001757 +268 29 0.0074027963 +269 29 0.00040149991 +270 29 5.0199989e-05 +271 29 0.0032872998 +272 29 0.00022579999 +273 29 0.00020079999 +274 29 0.0020325999 +277 29 0.011467997 +279 29 0.00090339989 +282 29 0.0032119998 +285 29 7.5299991e-05 +292 29 0.0027353 +293 29 0.00020079999 +295 29 0.0055206977 +302 29 0.0031116998 +303 29 0.0045419969 +304 29 0.0030363998 +305 29 0.0047678985 +306 29 0.033726498 +307 29 0.00095359981 +308 29 0.026599698 +309 29 0.0032621999 +310 29 0.0035132 +311 29 0.0069259964 +312 29 0.0011292 +317 29 0.0015808998 +318 29 5.0199989e-05 +319 29 0.0050689988 +322 29 0.0084064975 +324 29 0.0016311 +331 29 0.00095359981 +334 29 0.0085068978 +335 29 2.5099987e-05 +341 29 0.0001255 +350 29 0.0024089999 +352 29 0.0036887999 +356 29 0.0019071999 +358 29 0.00010039999 +366 29 0.0050940998 +368 29 0.00097869989 +371 29 0.0062985979 +374 29 0.0001757 +380 29 0.00092849997 +383 29 0.00077789999 +384 29 0.0001757 +385 29 0.0027853998 +386 29 0.0039648972 +387 29 5.0199989e-05 +390 29 0.0016059999 +394 29 0.00010039999 +398 29 0.00022579999 +402 29 0.00020079999 +412 29 2.5099987e-05 +414 29 2.5099987e-05 +415 29 0.0044416972 +419 29 0.00020079999 +422 29 0.0001506 +423 29 2.5099987e-05 +425 29 2.5099987e-05 +430 29 5.0199989e-05 +431 29 2.5099987e-05 +433 29 2.5099987e-05 +434 29 2.5099987e-05 +438 29 0.00020079999 +439 29 0.00045169983 +441 29 5.0199989e-05 +443 29 0.0043161996 +444 29 0.0001255 +445 29 0.011066496 +446 29 0.00072769984 +447 29 0.00060229981 +450 29 0.0030614999 +452 29 0.00045169983 +453 29 5.0199989e-05 +454 29 0.00092849997 +455 29 0.034479298 +456 29 0.028030097 +457 29 0.0032119998 +458 29 0.00022579999 +460 29 0.0025344999 +463 29 0.0065495968 +464 29 0.0001757 +465 29 0.00010039999 +467 29 0.0081304982 +468 29 0.00047679991 +469 29 0.072547078 +470 29 0.0047678985 +471 29 0.00266 +473 29 0.00010039999 +477 29 2.5099987e-05 +478 29 0.00052699982 +483 29 0.00032619992 +489 29 7.5299991e-05 +490 29 0.00037639984 +491 29 0.00020079999 +9 30 1.3399999e-05 +16 30 4.0199986e-05 +24 30 0.0016213998 +60 30 0.00012059999 +80 30 1.3399999e-05 +82 30 1.3399999e-05 +83 30 1.3399999e-05 +84 30 1.3399999e-05 +108 30 1.3399999e-05 +113 30 2.6799986e-05 +114 30 5.3599986e-05 +126 30 2.6799986e-05 +134 30 0.0025459998 +135 30 4.0199986e-05 +139 30 0.00072359992 +141 30 2.6799986e-05 +142 30 5.3599986e-05 +150 30 4.0199986e-05 +160 30 0.040333398 +161 30 0.00033499999 +162 30 0.0014605999 +163 30 0.050034799 +164 30 0.022015899 +165 30 0.031891499 +167 30 0.010009598 +170 30 0.00080399984 +171 30 0.0067802966 +177 30 0.0028541998 +182 30 0.0034973 +189 30 1.3399999e-05 +191 30 0.003082 +192 30 0.0020367999 +194 30 1.3399999e-05 +195 30 1.3399999e-05 +197 30 0.0011925998 +198 30 2.6799986e-05 +203 30 1.3399999e-05 +204 30 1.3399999e-05 +206 30 4.0199986e-05 +207 30 1.3399999e-05 +214 30 0.00013399999 +215 30 4.0199986e-05 +218 30 4.0199986e-05 +219 30 0.00095139979 +223 30 0.00016079999 +233 30 0.010545596 +234 30 0.00077719986 +235 30 0.00010719999 +236 30 0.0021439998 +237 30 0.00077719986 +240 30 0.00054939999 +241 30 0.017205298 +242 30 0.00030819979 +252 30 0.00046899985 +254 30 0.0018759998 +255 30 0.0026397998 +256 30 0.0044754967 +257 30 0.00032159989 +258 30 0.0009782 +259 30 0.0035642998 +264 30 0.0041538998 +265 30 0.0016213998 +266 30 0.021734498 +267 30 9.3799987e-05 +268 30 0.0076378994 +269 30 0.00049579982 +270 30 2.6799986e-05 +271 30 0.0017553999 +272 30 2.6799986e-05 +273 30 0.00020099999 +274 30 0.0039126985 +277 30 0.0031355999 +279 30 0.0014739998 +282 30 0.0011657998 +285 30 1.3399999e-05 +292 30 0.003966298 +293 30 4.0199986e-05 +295 30 0.018196899 +302 30 0.0028541998 +303 30 0.023275398 +304 30 0.0019161999 +306 30 0.019228697 +307 30 0.00053599989 +308 30 0.0144316 +309 30 0.0016615998 +310 30 0.007879097 +311 30 0.0019697999 +312 30 5.3599986e-05 +317 30 0.0006163998 +318 30 2.6799986e-05 +319 30 0.0043548979 +322 30 0.0062442981 +324 30 0.00025459984 +331 30 0.00079059997 +334 30 8.0399986e-05 +341 30 5.3599986e-05 +350 30 0.0018357998 +352 30 0.00017419999 +356 30 2.6799986e-05 +358 30 4.0199986e-05 +366 30 0.011992797 +368 30 0.00068339985 +371 30 0.0128638 +380 30 0.0019295998 +383 30 0.0013533998 +385 30 0.013614196 +386 30 0.0025727998 +387 30 1.3399999e-05 +390 30 0.0021573999 +394 30 4.0199986e-05 +397 30 1.3399999e-05 +398 30 0.00033499999 +402 30 0.00020099999 +414 30 1.3399999e-05 +415 30 0.0013935999 +422 30 6.6999986e-05 +423 30 1.3399999e-05 +425 30 1.3399999e-05 +430 30 1.3399999e-05 +431 30 1.3399999e-05 +433 30 1.3399999e-05 +434 30 1.3399999e-05 +438 30 0.00057619996 +439 30 0.00071019982 +441 30 1.3399999e-05 +443 30 0.0095942989 +444 30 5.3599986e-05 +445 30 0.011228997 +446 30 0.00091119995 +447 30 0.00036179996 +450 30 0.0011925998 +452 30 0.00017419999 +453 30 2.6799986e-05 +454 30 0.00036179996 +455 30 0.051950999 +456 30 0.068982184 +457 30 0.0012461999 +458 30 0.00014739999 +460 30 0.0017955999 +463 30 0.0025459998 +464 30 6.6999986e-05 +465 30 2.6799986e-05 +467 30 0.006740097 +468 30 0.00018759999 +469 30 0.0037518998 +470 30 0.0018491999 +471 30 0.0021171998 +473 30 4.0199986e-05 +477 30 1.3399999e-05 +478 30 0.00020099999 +483 30 0.00012059999 +489 30 2.6799986e-05 +490 30 0.00014739999 +491 30 8.0399986e-05 +7 31 0.00010629999 +9 31 5.3099997e-05 +16 31 0.00042509986 +18 31 0.00026569981 +24 31 0.0066949986 +60 31 0.00037189992 +80 31 0.00010629999 +82 31 5.3099997e-05 +83 31 5.3099997e-05 +84 31 5.3099997e-05 +108 31 5.3099997e-05 +113 31 0.00010629999 +114 31 0.00015939999 +126 31 5.3099997e-05 +134 31 0.0017002998 +135 31 5.3099997e-05 +139 31 0.00031879987 +141 31 5.3099997e-05 +150 31 0.00010629999 +154 31 0.00010629999 +160 31 0.007704597 +162 31 0.00031879987 +163 31 0.0030286999 +164 31 0.0019659998 +165 31 0.0065886974 +166 31 0.012646098 +167 31 0.0034538 +168 31 0.0013814999 +170 31 0.00021249999 +171 31 0.00085019995 +177 31 0.00026569981 +182 31 0.005313497 +183 31 0.0034005998 +189 31 5.3099997e-05 +191 31 0.0006907999 +192 31 0.00085019995 +194 31 5.3099997e-05 +197 31 0.00015939999 +198 31 5.3099997e-05 +203 31 5.3099997e-05 +204 31 5.3099997e-05 +206 31 0.00015939999 +207 31 5.3099997e-05 +214 31 0.00010629999 +219 31 0.0030286999 +223 31 0.00042509986 +233 31 0.0077576973 +234 31 0.0034005998 +235 31 0.0054197982 +236 31 0.0028692998 +237 31 0.00074389996 +240 31 0.00026569981 +241 31 0.008554697 +242 31 5.3099997e-05 +252 31 0.0044632964 +254 31 0.0042507984 +255 31 0.004728999 +256 31 0.0030818 +257 31 0.00026569981 +258 31 0.00074389996 +259 31 0.0020722998 +262 31 0.00015939999 +264 31 0.0074919984 +265 31 0.011105198 +266 31 0.037353899 +267 31 0.00058449991 +268 31 0.0073325969 +269 31 0.00058449991 +271 31 0.0028161998 +272 31 0.00015939999 +273 31 0.00010629999 +274 31 0.0070137978 +277 31 0.010573898 +279 31 0.0011689998 +282 31 0.0038256999 +292 31 0.0042507984 +293 31 0.00015939999 +295 31 0.011105198 +302 31 0.0031349999 +303 31 0.0026566999 +304 31 0.0057916977 +305 31 0.020669498 +306 31 0.016524997 +307 31 0.00079699978 +308 31 0.014665198 +309 31 0.0037725999 +310 31 0.0063761994 +311 31 0.010254998 +312 31 0.00047819992 +315 31 0.00015939999 +317 31 0.0019659998 +318 31 5.3099997e-05 +319 31 0.013974499 +322 31 0.0040382966 +324 31 0.0013814999 +331 31 0.00063759997 +334 31 0.0071200989 +335 31 0.0019659998 +341 31 0.00015939999 +350 31 0.00090329978 +352 31 0.0021784999 +356 31 0.00079699978 +358 31 0.00010629999 +366 31 0.011530299 +368 31 0.00026569981 +371 31 0.011689696 +380 31 0.00095639983 +383 31 0.0014877999 +384 31 0.00031879987 +385 31 0.0038788998 +386 31 0.0071200989 +387 31 5.3099997e-05 +390 31 0.0012220999 +394 31 0.00015939999 +398 31 0.00031879987 +402 31 0.00015939999 +414 31 0.00026569981 +415 31 0.0032943999 +419 31 0.00010629999 +422 31 0.00015939999 +423 31 5.3099997e-05 +430 31 5.3099997e-05 +431 31 5.3099997e-05 +433 31 5.3099997e-05 +434 31 5.3099997e-05 +438 31 0.00037189992 +439 31 0.00037189992 +441 31 0.00015939999 +443 31 0.0047820993 +444 31 0.00015939999 +445 31 0.017481398 +446 31 0.00042509986 +447 31 0.00058449991 +450 31 0.0038256999 +452 31 0.00058449991 +453 31 5.3099997e-05 +454 31 0.0011157999 +455 31 0.036769398 +456 31 0.028799098 +457 31 0.0040382966 +458 31 0.00021249999 +460 31 0.0027098998 +463 31 0.0081827976 +464 31 0.00021249999 +465 31 0.00010629999 +467 31 0.0064292997 +468 31 0.00058449991 +469 31 0.085440993 +470 31 0.0059510991 +471 31 0.0021253999 +473 31 0.00010629999 +478 31 0.0006907999 +483 31 0.00042509986 +489 31 5.3099997e-05 +490 31 0.00047819992 +491 31 0.00026569981 +16 32 0.00054049981 +18 32 0.00027029985 +24 32 0.0064864978 +60 32 0.00054049981 +114 32 0.00027029985 +126 32 0.00027029985 +134 32 0.0056756996 +139 32 0.00027029985 +160 32 0.0078377984 +162 32 0.00027029985 +163 32 0.0032431998 +164 32 0.0018918999 +165 32 0.0070269965 +166 32 0.012432396 +167 32 0.0035134999 +168 32 0.0027027 +170 32 0.00027029985 +171 32 0.00081079989 +177 32 0.00027029985 +182 32 0.0043242984 +183 32 0.0029729998 +191 32 0.0010811 +192 32 0.00054049981 +214 32 0.00027029985 +219 32 0.0027027 +223 32 0.00054049981 +233 32 0.004594598 +234 32 0.0016215998 +235 32 0.0013513998 +236 32 0.0021621999 +237 32 0.0010811 +240 32 0.00027029985 +241 32 0.0081080981 +242 32 0.00027029985 +252 32 0.0021621999 +254 32 0.0072972998 +255 32 0.010270298 +256 32 0.0029729998 +257 32 0.00054049981 +258 32 0.0010811 +259 32 0.0024323999 +262 32 0.00027029985 +264 32 0.0162162 +265 32 0.014054097 +266 32 0.045135099 +267 32 0.0010811 +268 32 0.0024323999 +269 32 0.0029729998 +271 32 0.0040540993 +273 32 0.00027029985 +274 32 0.0067567974 +277 32 0.010270298 +279 32 0.0010811 +282 32 0.0043242984 +285 32 0.00027029985 +292 32 0.0043242984 +293 32 0.00027029985 +295 32 0.0083783977 +302 32 0.0037837999 +303 32 0.0032431998 +304 32 0.0043242984 +305 32 0.0075675994 +306 32 0.034054097 +307 32 0.00054049981 +308 32 0.012432396 +309 32 0.0081080981 +310 32 0.0097296983 +311 32 0.012162197 +312 32 0.00027029985 +315 32 0.00027029985 +317 32 0.0021621999 +319 32 0.013783798 +322 32 0.004594598 +324 32 0.0010811 +331 32 0.00081079989 +334 32 0.0072972998 +335 32 0.0016215998 +341 32 0.00027029985 +350 32 0.0010811 +352 32 0.0016215998 +356 32 0.00054049981 +366 32 0.0078377984 +368 32 0.00054049981 +371 32 0.0091891997 +380 32 0.0010811 +383 32 0.0018918999 +384 32 0.00027029985 +385 32 0.0040540993 +386 32 0.0054053999 +390 32 0.00081079989 +394 32 0.00027029985 +398 32 0.00027029985 +402 32 0.00027029985 +414 32 0.00027029985 +415 32 0.0018918999 +438 32 0.00027029985 +439 32 0.00027029985 +441 32 0.00027029985 +443 32 0.0035134999 +444 32 0.00027029985 +445 32 0.012432396 +446 32 0.00054049981 +447 32 0.00054049981 +450 32 0.0040540993 +452 32 0.00054049981 +454 32 0.0010811 +455 32 0.031621598 +456 32 0.024054099 +457 32 0.0043242984 +458 32 0.00027029985 +460 32 0.0027027 +463 32 0.0086485967 +464 32 0.00027029985 +467 32 0.0072972998 +468 32 0.00054049981 +469 32 0.085945845 +470 32 0.0064864978 +471 32 0.0024323999 +473 32 0.00027029985 +478 32 0.00054049981 +483 32 0.00054049981 +490 32 0.00054049981 +491 32 0.00027029985 +7 33 5.7599987e-05 +16 33 0.00026869983 +18 33 0.00023029999 +24 33 0.0027830999 +80 33 5.7599987e-05 +134 33 0.00021109999 +139 33 3.8399987e-05 +141 33 1.9199986e-05 +154 33 1.9199986e-05 +159 33 1.9199986e-05 +160 33 0.0011515999 +162 33 0.00011519999 +163 33 0.00042229984 +164 33 0.00028789998 +165 33 0.0014203 +166 33 0.0017273999 +167 33 0.00051819999 +168 33 0.0012476 +170 33 5.7599987e-05 +171 33 0.00015359999 +177 33 3.8399987e-05 +182 33 0.00069099991 +183 33 0.00044149999 +191 33 0.00023029999 +192 33 0.00030709989 +197 33 1.9199986e-05 +198 33 1.9199986e-05 +214 33 3.8399987e-05 +215 33 1.9199986e-05 +219 33 0.0004606999 +223 33 0.00011519999 +233 33 0.0058348998 +234 33 0.0018809999 +235 33 0.0012859998 +236 33 0.0023991999 +237 33 0.00024949992 +240 33 3.8399987e-05 +241 33 0.0029558998 +242 33 1.9199986e-05 +252 33 0.00084449979 +254 33 0.0013436 +255 33 0.0020344998 +256 33 0.00013439999 +257 33 0.0025527999 +258 33 0.00015359999 +259 33 0.00042229984 +262 33 7.6799988e-05 +264 33 0.0031478 +265 33 0.00044149999 +266 33 0.011784997 +267 33 0.00015359999 +268 33 0.00038389978 +269 33 0.00069099991 +271 33 0.0016122998 +272 33 7.6799988e-05 +273 33 0.00086369994 +274 33 0.0050671995 +275 33 0.023781199 +276 33 0.0015354999 +277 33 0.0068905987 +279 33 0.00030709989 +282 33 0.0010556998 +285 33 7.6799988e-05 +292 33 0.0018809999 +293 33 0.00036469987 +295 33 0.0047216974 +302 33 0.00069099991 +303 33 0.00057579996 +304 33 0.004875198 +305 33 0.098656356 +306 33 0.0040882975 +307 33 0.055930898 +308 33 0.012322497 +309 33 0.0128599 +310 33 0.0025336 +311 33 0.0035316998 +312 33 0.00026869983 +315 33 7.6799988e-05 +319 33 0.0012476 +322 33 0.0013627999 +324 33 0.11134356 +331 33 0.00028789998 +334 33 0.00049899984 +335 33 0.00023029999 +336 33 0.030153599 +350 33 0.0004606999 +351 33 0.00030709989 +352 33 0.0012283998 +354 33 0.00024949992 +356 33 0.0004606999 +366 33 0.0061035976 +368 33 5.7599987e-05 +371 33 0.004875198 +374 33 1.9199986e-05 +380 33 0.00038389978 +383 33 0.00042229984 +384 33 0.00013439999 +385 33 0.011458699 +386 33 0.0031478 +390 33 0.00049899984 +398 33 0.00021109999 +402 33 7.6799988e-05 +414 33 0.00090209977 +415 33 0.0019769999 +419 33 3.8399987e-05 +438 33 9.5999989e-05 +439 33 5.7599987e-05 +441 33 0.00015359999 +443 33 0.006161198 +445 33 0.014299396 +446 33 0.00057579996 +447 33 0.00017269999 +455 33 0.041708298 +456 33 0.020921297 +458 33 3.8399987e-05 +460 33 0.00049899984 +467 33 0.0027062998 +469 33 0.033301298 +471 33 0.00071019982 +7 34 0.00020759999 +9 34 3.1899996e-05 +16 34 0.0010856998 +18 34 0.00079829991 +24 34 0.0053009987 +60 34 0.00036719977 +79 34 1.5999991e-05 +80 34 0.00011179999 +82 34 3.1899996e-05 +83 34 3.1899996e-05 +84 34 3.1899996e-05 +108 34 4.7899986e-05 +113 34 7.9799996e-05 +114 34 0.00014369999 +126 34 7.9799996e-05 +127 34 1.5999991e-05 +134 34 0.0025227999 +135 34 4.7899986e-05 +139 34 9.5799987e-05 +141 34 4.7899986e-05 +150 34 0.00011179999 +154 34 3.1899996e-05 +159 34 1.5999991e-05 +160 34 0.002874 +162 34 7.9799996e-05 +163 34 0.00094199996 +164 34 0.00065459986 +165 34 0.0030496998 +166 34 0.0038959 +167 34 0.0010537999 +168 34 0.0023630999 +170 34 7.9799996e-05 +171 34 0.0004629998 +177 34 9.5799987e-05 +182 34 0.0025386999 +183 34 0.0016445999 +189 34 3.1899996e-05 +191 34 0.00075039989 +192 34 0.00076639978 +194 34 4.7899986e-05 +196 34 3.1899996e-05 +197 34 7.9799996e-05 +198 34 4.7899986e-05 +201 34 4.7899986e-05 +203 34 4.7899986e-05 +204 34 6.3899992e-05 +206 34 0.0001277 +207 34 4.7899986e-05 +209 34 1.5999991e-05 +214 34 0.00023949999 +215 34 4.7899986e-05 +219 34 0.0017084 +223 34 0.00038319989 +233 34 0.0027462998 +234 34 0.0018041998 +235 34 0.0024269999 +236 34 0.0017084 +237 34 0.00070249988 +240 34 0.0003513 +241 34 0.0072329976 +242 34 0.0001277 +248 34 4.7899986e-05 +250 34 3.1899996e-05 +251 34 1.5999991e-05 +252 34 0.0052370988 +254 34 0.0042311996 +255 34 0.0035605999 +256 34 0.0016285998 +257 34 0.00019159999 +258 34 0.00033529988 +259 34 0.0010698 +262 34 0.00020759999 +263 34 1.5999991e-05 +264 34 0.0056042969 +265 34 0.0083665997 +266 34 0.030768 +267 34 0.0004629998 +268 34 0.0023790998 +269 34 0.0035126999 +270 34 4.7899986e-05 +271 34 0.0033849999 +272 34 0.0001756 +273 34 0.0002235 +274 34 0.0098674968 +277 34 0.0091968998 +279 34 0.00075039989 +282 34 0.0024269999 +285 34 0.00011179999 +292 34 0.0032891999 +293 34 0.00039919978 +294 34 3.1899996e-05 +295 34 0.011543997 +302 34 0.0016285998 +303 34 0.0015008999 +304 34 0.0074245967 +305 34 0.0407153 +306 34 0.013172597 +307 34 0.0010698 +308 34 0.024045996 +309 34 0.0075841993 +310 34 0.026504897 +311 34 0.020102199 +312 34 0.00052689994 +315 34 0.0007185 +317 34 0.0019159999 +318 34 9.5799987e-05 +319 34 0.0056362972 +322 34 0.0038959 +323 34 1.5999991e-05 +324 34 0.0011974999 +331 34 0.00060669985 +334 34 0.010553997 +335 34 0.00095799984 +341 34 0.00015969999 +350 34 0.00051089982 +352 34 0.0028261 +356 34 0.00083029992 +358 34 0.0001277 +363 34 1.5999991e-05 +366 34 0.016365997 +368 34 0.00014369999 +371 34 0.012102798 +374 34 3.1899996e-05 +380 34 0.00095799984 +383 34 0.00094199996 +384 34 0.00036719977 +385 34 0.0107616 +386 34 0.0073446967 +387 34 4.7899986e-05 +390 34 0.0012613998 +394 34 0.00011179999 +398 34 0.00049499981 +402 34 0.00014369999 +412 34 1.5999991e-05 +414 34 0.00015969999 +415 34 0.0047261976 +419 34 0.00011179999 +422 34 0.00020759999 +423 34 3.1899996e-05 +425 34 1.5999991e-05 +430 34 3.1899996e-05 +431 34 3.1899996e-05 +432 34 1.5999991e-05 +433 34 4.7899986e-05 +434 34 3.1899996e-05 +438 34 0.0001277 +439 34 0.00020759999 +443 34 0.0047899969 +444 34 0.00015969999 +445 34 0.017898798 +446 34 0.00086219981 +447 34 0.00079829991 +449 34 1.5999991e-05 +450 34 0.0036882998 +452 34 0.00055879983 +453 34 7.9799996e-05 +454 34 0.0011335998 +455 34 0.037553899 +456 34 0.027047697 +457 34 0.0038959 +458 34 0.00020759999 +459 34 4.7899986e-05 +460 34 0.0025546998 +463 34 0.0078556985 +464 34 0.00019159999 +465 34 0.00011179999 +467 34 0.0058916993 +468 34 0.00059079984 +469 34 0.074852288 +470 34 0.0057160966 +471 34 0.0019159999 +473 34 0.0001277 +477 34 6.3899992e-05 +478 34 0.00068659987 +483 34 0.00039919978 +489 34 7.9799996e-05 +490 34 0.0004629998 +491 34 0.0002235 +7 35 0.00016639999 +9 35 5.5499986e-05 +16 35 0.0010537999 +18 35 0.00077649998 +24 35 0.0083194971 +60 35 0.00033279997 +80 35 0.00011089999 +82 35 5.5499986e-05 +108 35 5.5499986e-05 +113 35 5.5499986e-05 +114 35 0.00011089999 +126 35 5.5499986e-05 +139 35 5.5499986e-05 +141 35 5.5499986e-05 +150 35 0.00011089999 +154 35 5.5499986e-05 +160 35 0.0023294999 +162 35 0.00033279997 +163 35 0.00083189993 +164 35 0.0005545998 +165 35 0.0032168999 +166 35 0.0034941998 +167 35 0.0009982998 +168 35 0.0026621998 +170 35 0.00011089999 +171 35 0.00044369977 +177 35 0.00011089999 +182 35 0.0012202 +183 35 0.00077649998 +189 35 5.5499986e-05 +191 35 0.0007209999 +192 35 0.0005545998 +194 35 5.5499986e-05 +197 35 5.5499986e-05 +198 35 5.5499986e-05 +203 35 5.5499986e-05 +206 35 0.00011089999 +214 35 5.5499986e-05 +215 35 5.5499986e-05 +219 35 0.0010537999 +223 35 0.00038819993 +233 35 0.017914597 +234 35 0.0065445974 +235 35 0.0046588965 +236 35 0.0085967965 +237 35 0.0007209999 +240 35 5.5499986e-05 +241 35 0.0061008967 +242 35 5.5499986e-05 +252 35 0.0021076 +254 35 0.0034941998 +255 35 0.0038824 +256 35 0.00022189999 +257 35 0.00016639999 +258 35 0.0002772999 +259 35 0.00077649998 +262 35 0.00016639999 +264 35 0.0059899986 +265 35 0.0066000968 +266 35 0.025013898 +267 35 0.0002772999 +268 35 0.00083189993 +269 35 0.0038824 +270 35 5.5499986e-05 +271 35 0.0028285999 +272 35 0.00011089999 +273 35 0.0002772999 +274 35 0.0063227974 +277 35 0.011258997 +279 35 0.0007209999 +282 35 0.0018302999 +285 35 0.00016639999 +292 35 0.0037159999 +293 35 0.00016639999 +294 35 5.5499986e-05 +295 35 0.007820297 +302 35 0.0012756998 +303 35 0.0011646999 +304 35 0.0047697984 +305 35 0.072157443 +306 35 0.018635597 +307 35 0.049473099 +308 35 0.014808699 +309 35 0.0074320994 +310 35 0.012756497 +311 35 0.0167499 +312 35 0.00061009987 +315 35 0.00038819993 +317 35 0.0017193998 +318 35 5.5499986e-05 +319 35 0.0027731999 +322 35 0.0024957999 +324 35 0.0023294999 +331 35 0.00066559995 +334 35 0.00016639999 +335 35 0.00044369977 +341 35 0.00016639999 +350 35 0.00033279997 +352 35 0.0018302999 +356 35 0.00066559995 +358 35 0.00011089999 +366 35 0.0091513991 +368 35 0.00011089999 +371 35 0.0082639977 +380 35 0.00061009987 +383 35 0.00066559995 +384 35 0.0002772999 +385 35 0.007820297 +386 35 0.0050470978 +387 35 5.5499986e-05 +390 35 0.00083189993 +394 35 0.00011089999 +398 35 0.00033279997 +402 35 0.00011089999 +414 35 0.00011089999 +415 35 0.002995 +419 35 5.5499986e-05 +422 35 0.00016639999 +430 35 5.5499986e-05 +434 35 5.5499986e-05 +438 35 0.00016639999 +439 35 0.00011089999 +441 35 0.00011089999 +443 35 0.0051580966 +444 35 0.00011089999 +445 35 0.0253466 +446 35 0.0009982998 +447 35 0.00049919984 +450 35 0.0033278 +452 35 0.00049919984 +453 35 5.5499986e-05 +454 35 0.0009982998 +455 35 0.035607297 +456 35 0.028618999 +457 35 0.0034941998 +458 35 0.00022189999 +460 35 0.0024404 +463 35 0.0070992969 +464 35 0.00016639999 +465 35 0.00011089999 +467 35 0.0058235973 +468 35 0.00049919984 +469 35 0.065723777 +470 35 0.0051580966 +471 35 0.0019967 +473 35 0.00011089999 +478 35 0.0005545998 +483 35 0.00033279997 +489 35 5.5499986e-05 +490 35 0.00038819993 +491 35 0.00022189999 +7 36 0.00045729987 +16 36 0.0022865999 +18 36 0.0015244 +24 36 0.0057926998 +60 36 0.00030489988 +80 36 0.0001524 +114 36 0.0001524 +126 36 0.0001524 +150 36 0.0001524 +160 36 0.0042682998 +162 36 0.00030489988 +163 36 0.0036584998 +164 36 0.00045729987 +165 36 0.0038109999 +166 36 0.0022865999 +167 36 0.00076219998 +168 36 0.0033536998 +170 36 0.0001524 +171 36 0.00030489988 +182 36 0.0092987977 +183 36 0.0060975999 +191 36 0.00076219998 +192 36 0.00045729987 +214 36 0.00045729987 +215 36 0.0001524 +219 36 0.0018292998 +223 36 0.00060979999 +233 36 0.0030487999 +234 36 0.0045731999 +235 36 0.0032011999 +236 36 0.0054877996 +237 36 0.00060979999 +241 36 0.0050304979 +252 36 0.0022865999 +254 36 0.0042682998 +255 36 0.0025914998 +256 36 0.00091459998 +257 36 0.0001524 +258 36 0.00030489988 +259 36 0.00076219998 +262 36 0.0001524 +264 36 0.005335398 +265 36 0.010823198 +266 36 0.046951197 +267 36 0.00045729987 +268 36 0.00091459998 +269 36 0.0015244 +271 36 0.0024389999 +272 36 0.0001524 +273 36 0.00030489988 +274 36 0.0056401975 +277 36 0.010213397 +279 36 0.00060979999 +282 36 0.001372 +285 36 0.0001524 +292 36 0.0024389999 +293 36 0.00030489988 +295 36 0.0065548979 +302 36 0.00091459998 +303 36 0.001372 +304 36 0.0047255978 +305 36 0.046341497 +306 36 0.021036599 +307 36 0.0035060998 +308 36 0.016006097 +309 36 0.0065548979 +310 36 0.010975599 +311 36 0.017530497 +312 36 0.00045729987 +315 36 0.00045729987 +317 36 0.0012194999 +319 36 0.0018292998 +322 36 0.0041158982 +324 36 0.0018292998 +331 36 0.00045729987 +334 36 0.056097597 +335 36 0.0035060998 +341 36 0.0001524 +350 36 0.0001524 +352 36 0.0015244 +356 36 0.00045729987 +358 36 0.0001524 +366 36 0.0079267994 +368 36 0.00091459998 +371 36 0.0082316995 +380 36 0.00045729987 +383 36 0.00045729987 +384 36 0.00030489988 +385 36 0.018140197 +386 36 0.0048779994 +390 36 0.00060979999 +394 36 0.0001524 +398 36 0.00030489988 +402 36 0.0001524 +415 36 0.0028962998 +438 36 0.0001524 +441 36 0.0030487999 +443 36 0.0035060998 +444 36 0.0001524 +445 36 0.023323197 +446 36 0.00045729987 +447 36 0.00030489988 +450 36 0.0027438998 +452 36 0.00045729987 +454 36 0.00076219998 +455 36 0.035975598 +456 36 0.021493897 +457 36 0.0028962998 +458 36 0.0001524 +460 36 0.0015244 +463 36 0.0057926998 +464 36 0.0001524 +467 36 0.0051828995 +468 36 0.00045729987 +469 36 0.062652349 +470 36 0.0041158982 +471 36 0.0015244 +473 36 0.0001524 +478 36 0.00030489988 +483 36 0.00030489988 +490 36 0.00030489988 +491 36 0.0001524 +7 37 5.2299991e-05 +9 37 3.4899989e-05 +16 37 0.00034869998 +18 37 0.0002441 +24 37 0.0072867982 +60 37 0.00034869998 +79 37 1.7399987e-05 +80 37 0.0001395 +82 37 3.4899989e-05 +83 37 3.4899989e-05 +84 37 3.4899989e-05 +108 37 5.2299991e-05 +113 37 5.2299991e-05 +114 37 0.000122 +126 37 6.9699992e-05 +127 37 1.7399987e-05 +134 37 6.9699992e-05 +139 37 0.0001395 +141 37 3.4899989e-05 +142 37 1.7399987e-05 +150 37 0.0001046 +154 37 3.4899989e-05 +159 37 1.7399987e-05 +160 37 0.0036259999 +162 37 0.00020919999 +163 37 0.0012899998 +164 37 0.00081929984 +165 37 0.0039048998 +166 37 0.0053691976 +167 37 0.0014294998 +168 37 0.0028763998 +170 37 0.0001046 +171 37 0.00041839993 +177 37 0.000122 +182 37 0.0014294998 +183 37 0.0008890999 +189 37 3.4899989e-05 +191 37 0.0010284998 +192 37 0.00092389993 +194 37 3.4899989e-05 +196 37 1.7399987e-05 +197 37 6.9699992e-05 +198 37 3.4899989e-05 +201 37 5.2299991e-05 +203 37 3.4899989e-05 +204 37 5.2299991e-05 +206 37 0.0001395 +207 37 3.4899989e-05 +209 37 1.7399987e-05 +214 37 0.00015689999 +215 37 1.7399987e-05 +218 37 1.7399987e-05 +219 37 0.0016909998 +223 37 0.00034869998 +233 37 0.0037479999 +234 37 0.0047938973 +235 37 0.0036084999 +236 37 0.0058398992 +237 37 0.00059269997 +240 37 0.00026149978 +241 37 0.008507099 +242 37 6.9699992e-05 +248 37 1.7399987e-05 +250 37 1.7399987e-05 +252 37 0.0040442981 +254 37 0.0039222986 +255 37 0.0050205998 +256 37 0.00083679985 +257 37 0.00022659999 +258 37 0.00031379983 +259 37 0.00083679985 +264 37 0.0078794993 +265 37 0.0077399984 +266 37 0.029129799 +267 37 0.00052299979 +268 37 0.0029634999 +269 37 0.0022314 +270 37 3.4899989e-05 +271 37 0.0044452995 +272 37 0.00019179999 +273 37 0.00027889991 +274 37 0.013318498 +277 37 0.013684496 +279 37 0.0011504998 +282 37 0.0021964998 +285 37 0.00015689999 +292 37 0.0040617995 +293 37 0.00027889991 +294 37 3.4899989e-05 +295 37 0.0139286 +302 37 0.0012725999 +303 37 0.0011157 +304 37 0.0080363974 +305 37 0.051443398 +306 37 0.010041099 +307 37 0.0011157 +308 37 0.020570397 +309 37 0.0080712996 +310 37 0.0038176998 +311 37 0.0119587 +312 37 0.00066239992 +315 37 0.0001046 +317 37 0.0017955999 +318 37 6.9699992e-05 +319 37 0.0042534992 +322 37 0.0042360984 +324 37 0.0027019999 +331 37 0.00048809987 +334 37 0.0027542999 +335 37 0.00050549977 +341 37 0.00015689999 +350 37 0.00080189994 +352 37 0.0030856 +356 37 0.0010807998 +358 37 0.000122 +366 37 0.016142499 +368 37 0.0001046 +371 37 0.0148177 +374 37 3.4899989e-05 +380 37 0.0010982 +383 37 0.00080189994 +384 37 0.00043579983 +385 37 0.0128478 +386 37 0.0088382997 +387 37 6.9699992e-05 +390 37 0.0014991998 +394 37 0.0001046 +398 37 0.00054039992 +402 37 0.0001046 +412 37 1.7399987e-05 +414 37 0.00015689999 +415 37 0.0052297972 +419 37 0.00015689999 +422 37 0.00017429999 +423 37 1.7399987e-05 +425 37 1.7399987e-05 +430 37 3.4899989e-05 +431 37 1.7399987e-05 +432 37 1.7399987e-05 +433 37 1.7399987e-05 +434 37 3.4899989e-05 +438 37 0.00017429999 +439 37 0.00022659999 +441 37 0.00022659999 +443 37 0.0057178997 +444 37 0.0001395 +445 37 0.023655999 +446 37 0.00081929984 +447 37 0.00062759989 +450 37 0.0034864999 +452 37 0.00052299979 +453 37 5.2299991e-05 +454 37 0.0010284998 +455 37 0.037288196 +456 37 0.027403899 +457 37 0.0036783 +458 37 0.00019179999 +459 37 1.7399987e-05 +460 37 0.0024406 +463 37 0.0074262992 +464 37 0.00019179999 +465 37 0.000122 +467 37 0.0046021976 +468 37 0.00054039992 +469 37 0.077069163 +470 37 0.0054214969 +471 37 0.0015689 +473 37 0.000122 +477 37 3.4899989e-05 +478 37 0.00061009987 +483 37 0.00036609988 +489 37 6.9699992e-05 +490 37 0.00043579983 +491 37 0.00020919999 +24 38 0.0020142 +60 38 0.00011849999 +114 38 0.00011849999 +162 38 0.0003554998 +163 38 0.0033175 +164 38 0.0020142 +165 38 0.005568698 +166 38 0.24111366 +167 38 0.062085297 +168 38 0.00011849999 +170 38 0.00023699999 +171 38 0.0003554998 +177 38 0.00023699999 +182 38 0.0034359999 +183 38 0.0021326998 +191 38 0.00059239985 +192 38 0.0004739 +219 38 0.0008293998 +223 38 0.00011849999 +233 38 0.0034359999 +234 38 0.0017772999 +235 38 0.00059239985 +236 38 0.0024881999 +237 38 0.0004739 +241 38 0.0023697 +252 38 0.0014217999 +254 38 0.0015403 +255 38 0.0033175 +256 38 0.00011849999 +257 38 0.00011849999 +258 38 0.00011849999 +259 38 0.0004739 +262 38 0.00011849999 +264 38 0.0052132979 +265 38 0.0028436 +266 38 0.0088862963 +267 38 0.00023699999 +268 38 0.00071089994 +269 38 0.00023699999 +271 38 0.0018956999 +272 38 0.00011849999 +273 38 0.00011849999 +274 38 0.0034359999 +277 38 0.0034359999 +279 38 0.00071089994 +282 38 0.00094789988 +285 38 0.00011849999 +292 38 0.0016587998 +295 38 0.0042653978 +302 38 0.00071089994 +303 38 0.0004739 +304 38 0.0029620999 +305 38 0.0063980967 +306 38 0.0068719983 +307 38 0.00011849999 +308 38 0.0068719983 +309 38 0.0049762987 +311 38 0.0041468963 +312 38 0.00023699999 +315 38 0.00011849999 +317 38 0.0004739 +319 38 0.004502397 +322 38 0.0015403 +324 38 0.0004739 +331 38 0.00023699999 +334 38 0.00011849999 +335 38 0.0011847999 +350 38 0.00011849999 +352 38 0.0013032998 +356 38 0.00023699999 +366 38 0.0059241988 +368 38 0.00011849999 +371 38 0.004502397 +380 38 0.0003554998 +383 38 0.0004739 +384 38 0.00011849999 +385 38 0.0042653978 +386 38 0.0026065998 +390 38 0.0004739 +398 38 0.00023699999 +415 38 0.0018956999 +438 38 0.00023699999 +439 38 0.00011849999 +441 38 0.00011849999 +443 38 0.0028436 +445 38 0.0074644983 +446 38 0.0011847999 +447 38 0.00011849999 +450 38 0.0010664 +452 38 0.00011849999 +454 38 0.00023699999 +455 38 0.036611397 +456 38 0.021919399 +457 38 0.0010664 +460 38 0.0004739 +463 38 0.0022511999 +467 38 0.0023697 +468 38 0.00011849999 +469 38 0.0479858 +470 38 0.0016587998 +471 38 0.0008293998 +478 38 0.00011849999 +483 38 0.00011849999 +490 38 0.00011849999 +7 39 0.00021789999 +9 39 3.1099989e-05 +16 39 0.0013229998 +18 39 0.0009804999 +24 39 0.0079221986 +60 39 0.00031129993 +79 39 1.5599988e-05 +80 39 0.00012449999 +82 39 3.1099989e-05 +83 39 3.1099989e-05 +84 39 3.1099989e-05 +108 39 4.6699992e-05 +113 39 6.2299994e-05 +114 39 0.0001089 +126 39 6.2299994e-05 +127 39 1.5599988e-05 +134 39 0.0097120963 +135 39 0.00015559999 +139 39 9.3399998e-05 +141 39 3.1099989e-05 +150 39 0.0001089 +154 39 3.1099989e-05 +159 39 1.5599988e-05 +160 39 0.0035330998 +162 39 0.00014009999 +163 39 0.0014475 +164 39 0.00088719977 +165 39 0.003393 +166 39 0.0056030974 +167 39 0.0015409 +168 39 0.0022100999 +170 39 9.3399998e-05 +171 39 0.00045139994 +177 39 0.00012449999 +181 39 0.0011672999 +182 39 0.0014008 +183 39 0.0008405 +189 39 3.1099989e-05 +191 39 0.0011517999 +192 39 0.00082489988 +194 39 4.6699992e-05 +196 39 1.5599988e-05 +197 39 7.7799996e-05 +198 39 3.1099989e-05 +201 39 4.6699992e-05 +203 39 3.1099989e-05 +204 39 4.6699992e-05 +206 39 0.00012449999 +207 39 3.1099989e-05 +209 39 1.5599988e-05 +214 39 0.00026459992 +215 39 6.2299994e-05 +218 39 1.5599988e-05 +219 39 0.0017120999 +223 39 0.00032679993 +233 39 0.0035641999 +234 39 0.0041244999 +235 39 0.0070194975 +236 39 0.0034397 +237 39 0.00082489988 +240 39 0.00062259985 +241 39 0.0071127973 +242 39 0.00012449999 +248 39 3.1099989e-05 +250 39 1.5599988e-05 +252 39 0.0027548999 +254 39 0.0035797998 +255 39 0.0049649999 +256 39 0.00077819987 +257 39 0.0002023 +258 39 0.00034239981 +259 39 0.0010427998 +262 39 0.00021789999 +264 39 0.0077197999 +265 39 0.0059921965 +266 39 0.0221323 +267 39 0.00054469984 +268 39 0.0023657999 +269 39 0.0020544999 +270 39 3.1099989e-05 +271 39 0.0026925998 +272 39 0.00014009999 +273 39 0.0002489998 +274 39 0.0094785988 +277 39 0.0075952969 +279 39 0.000856 +282 39 0.0023035 +285 39 0.00012449999 +292 39 0.0034552999 +293 39 0.0002023 +294 39 4.6699992e-05 +295 39 0.011782099 +302 39 0.0015874999 +303 39 0.0014942 +304 39 0.0062411986 +305 39 0.050972797 +306 39 0.023797698 +307 39 0.00088719977 +308 39 0.015766498 +309 39 0.011595298 +310 39 0.0058365986 +311 39 0.012964997 +312 39 0.00057589984 +315 39 0.00017119999 +317 39 0.0016186999 +318 39 7.7799996e-05 +319 39 0.0081555992 +322 39 0.0039376989 +323 39 1.5599988e-05 +324 39 0.000856 +331 39 0.00073149987 +334 39 0.0016031 +335 39 0.00048249983 +341 39 0.00014009999 +350 39 0.00046689995 +352 39 0.0023657999 +356 39 0.00079379999 +358 39 0.0001089 +366 39 0.0123735 +368 39 0.00014009999 +371 39 0.012638099 +374 39 4.6699992e-05 +380 39 0.0009649999 +383 39 0.00087159988 +384 39 0.00038909982 +385 39 0.011891097 +386 39 0.0075952969 +387 39 4.6699992e-05 +390 39 0.0012762998 +394 39 9.3399998e-05 +397 39 1.5599988e-05 +398 39 0.00042019994 +402 39 0.0002023 +412 39 1.5599988e-05 +414 39 0.00014009999 +415 39 0.0039532967 +419 39 0.0001089 +422 39 0.00015559999 +423 39 1.5599988e-05 +425 39 1.5599988e-05 +430 39 3.1099989e-05 +431 39 3.1099989e-05 +432 39 1.5599988e-05 +433 39 3.1099989e-05 +434 39 3.1099989e-05 +438 39 0.00015559999 +439 39 0.00015559999 +441 39 0.0002023 +443 39 0.0054629967 +444 39 0.00012449999 +445 39 0.019937698 +446 39 0.00094939978 +447 39 0.00063809985 +449 39 1.5599988e-05 +450 39 0.003144 +452 39 0.00046689995 +453 39 6.2299994e-05 +454 39 0.00094939978 +455 39 0.035844397 +456 39 0.026381299 +457 39 0.0033151999 +458 39 0.00021789999 +459 39 1.5599988e-05 +460 39 0.0026303998 +463 39 0.0067081973 +464 39 0.00017119999 +465 39 0.0001089 +467 39 0.0065057985 +468 39 0.00051359995 +469 39 0.11573535 +470 39 0.0048559979 +471 39 0.0022256998 +473 39 0.0001089 +477 39 4.6699992e-05 +478 39 0.00054469984 +483 39 0.00034239981 +489 39 7.7799996e-05 +490 39 0.00038909982 +491 39 0.0002023 +7 40 7.1799994e-05 +9 40 2.3899993e-05 +16 40 0.00035889982 +18 40 0.00028709997 +24 40 0.0048085973 +60 40 0.00026319991 +80 40 9.5699987e-05 +82 40 2.3899993e-05 +83 40 2.3899993e-05 +84 40 2.3899993e-05 +108 40 4.7799986e-05 +113 40 4.7799986e-05 +114 40 9.5699987e-05 +126 40 7.1799994e-05 +127 40 2.3899993e-05 +134 40 0.0011243999 +135 40 2.3899993e-05 +139 40 0.00023919999 +141 40 2.3899993e-05 +142 40 2.3899993e-05 +150 40 7.1799994e-05 +154 40 4.7799986e-05 +159 40 2.3899993e-05 +160 40 0.0047846995 +162 40 9.5699987e-05 +163 40 0.0018659998 +164 40 0.0012679 +165 40 0.0040190965 +166 40 0.0077989995 +167 40 0.0021052998 +168 40 0.0014354 +170 40 9.5699987e-05 +171 40 0.00071769999 +177 40 0.00016749999 +182 40 0.00081339991 +183 40 0.00040669995 +189 40 2.3899993e-05 +191 40 0.0011482998 +192 40 0.00093299989 +194 40 2.3899993e-05 +197 40 9.5699987e-05 +198 40 2.3899993e-05 +201 40 2.3899993e-05 +203 40 2.3899993e-05 +204 40 4.7799986e-05 +206 40 0.00011959999 +207 40 2.3899993e-05 +214 40 0.0002153 +215 40 2.3899993e-05 +219 40 0.00189 +223 40 0.00026319991 +233 40 0.004162699 +234 40 0.001555 +235 40 0.0013875999 +236 40 0.0016985999 +237 40 0.00045449985 +240 40 0.00031099981 +241 40 0.0091147982 +242 40 7.1799994e-05 +252 40 0.00088519999 +254 40 0.0031339999 +255 40 0.0023206 +256 40 0.0012439999 +257 40 0.00011959999 +258 40 0.00062199985 +259 40 0.0018420999 +262 40 0.00023919999 +264 40 0.0036841999 +265 40 0.0065549985 +266 40 0.021626797 +267 40 0.00052629993 +268 40 0.0054305978 +269 40 0.0018420999 +270 40 2.3899993e-05 +271 40 0.0035885 +272 40 0.00023919999 +273 40 0.00014349999 +274 40 0.0099760965 +277 40 0.010287099 +279 40 0.0009808999 +282 40 0.0038516999 +285 40 0.00014349999 +292 40 0.0048085973 +293 40 0.0002153 +294 40 2.3899993e-05 +295 40 0.013468899 +302 40 0.0028468999 +304 40 0.010071799 +305 40 0.031674597 +306 40 0.012416299 +307 40 0.0012439999 +308 40 0.019928198 +309 40 0.0046650991 +311 40 0.0082535967 +312 40 0.0005502 +315 40 7.1799994e-05 +317 40 0.0014114999 +318 40 4.7799986e-05 +319 40 0.011770297 +322 40 0.0045454986 +324 40 0.0013875999 +331 40 0.00035889982 +334 40 0.0089233965 +335 40 0.0002153 +341 40 0.00011959999 +350 40 0.00078949984 +352 40 0.0038037999 +356 40 0.00093299989 +358 40 9.5699987e-05 +366 40 0.020909097 +368 40 0.00026319991 +371 40 0.014162697 +374 40 2.3899993e-05 +380 40 0.0011482998 +383 40 0.0014832998 +384 40 0.00035889982 +385 40 0.011770297 +386 40 0.0085884966 +387 40 4.7799986e-05 +390 40 0.0014354 +394 40 9.5699987e-05 +398 40 0.00066989986 +402 40 9.5699987e-05 +412 40 2.3899993e-05 +414 40 0.00028709997 +415 40 0.0062678978 +419 40 0.00011959999 +422 40 0.00014349999 +423 40 2.3899993e-05 +425 40 2.3899993e-05 +430 40 4.7799986e-05 +431 40 2.3899993e-05 +433 40 2.3899993e-05 +434 40 2.3899993e-05 +438 40 0.0002153 +439 40 0.00026319991 +441 40 0.0002153 +443 40 0.0043779984 +444 40 0.00011959999 +445 40 0.0179426 +446 40 0.00052629993 +447 40 0.0004784998 +450 40 0.0027272999 +452 40 0.00040669995 +453 40 4.7799986e-05 +454 40 0.00078949984 +455 40 0.033803798 +456 40 0.024880398 +457 40 0.0028468999 +458 40 0.00014349999 +460 40 0.0018420999 +463 40 0.0057655983 +464 40 0.00014349999 +465 40 9.5699987e-05 +467 40 0.0039233975 +468 40 0.00043059979 +469 40 0.11217695 +470 40 0.0042104982 +471 40 0.0012200999 +473 40 9.5699987e-05 +477 40 2.3899993e-05 +478 40 0.00045449985 +483 40 0.00028709997 +489 40 7.1799994e-05 +490 40 0.00033489987 +491 40 0.00016749999 +7 41 6.8799985e-05 +9 41 3.4399985e-05 +16 41 0.00020639999 +18 41 0.00013759999 +24 41 0.0057435967 +60 41 0.00037829997 +80 41 0.00010319999 +82 41 3.4399985e-05 +83 41 3.4399985e-05 +84 41 3.4399985e-05 +108 41 6.8799985e-05 +113 41 6.8799985e-05 +114 41 0.00013759999 +126 41 0.00010319999 +134 41 0.0020291999 +135 41 3.4399985e-05 +139 41 0.00013759999 +141 41 3.4399985e-05 +150 41 0.00010319999 +154 41 3.4399985e-05 +159 41 3.4399985e-05 +160 41 0.0044365972 +162 41 0.00020639999 +163 41 0.0016508 +164 41 0.0010662 +165 41 0.0042990968 +166 41 0.0068096966 +167 41 0.0018227999 +168 41 0.0024074998 +170 41 0.00013759999 +171 41 0.00061909994 +177 41 0.00013759999 +181 41 0.0026481999 +182 41 0.011383999 +183 41 0.0073255971 +189 41 3.4399985e-05 +191 41 0.00079099997 +192 41 0.00072219991 +194 41 3.4399985e-05 +197 41 6.8799985e-05 +198 41 3.4399985e-05 +201 41 3.4399985e-05 +203 41 3.4399985e-05 +204 41 6.8799985e-05 +206 41 0.00017199999 +207 41 3.4399985e-05 +214 41 0.00027509988 +219 41 0.001926 +223 41 0.00037829997 +233 41 0.0034049 +234 41 0.0020635999 +235 41 0.0010317999 +236 41 0.0026825999 +237 41 0.00075659994 +240 41 0.00030949991 +241 41 0.0082541965 +242 41 0.00010319999 +252 41 0.0023387 +254 41 0.0058123991 +255 41 0.0036455998 +256 41 0.0011349998 +257 41 0.00020639999 +258 41 0.00051589985 +259 41 0.0014444999 +262 41 0.00017199999 +264 41 0.0057091974 +265 41 0.0091827996 +266 41 0.032672998 +267 41 0.0004127 +269 41 0.0073255971 +270 41 0.00010319999 +271 41 0.0035079999 +272 41 0.00020639999 +273 41 0.00017199999 +274 41 0.010902498 +277 41 0.012622099 +282 41 0.0031297 +285 41 0.00013759999 +292 41 0.0044022985 +293 41 0.00027509988 +295 41 0.010489799 +302 41 0.0022010999 +303 41 0.0018916 +304 41 0.0090108998 +305 41 0.023490198 +306 41 0.017196298 +307 41 0.00079099997 +308 41 0.0208763 +309 41 0.007875897 +310 41 0.0073599964 +311 41 0.010386597 +312 41 0.00055029988 +315 41 0.00020639999 +317 41 0.0019947998 +318 41 6.8799985e-05 +319 41 0.0088732988 +322 41 0.0037143999 +324 41 0.0019947998 +331 41 0.00061909994 +334 41 0.0060874969 +335 41 0.0042646974 +341 41 0.00017199999 +350 41 0.00065349997 +352 41 0.0034736998 +356 41 0.0008254 +358 41 0.00010319999 +366 41 0.018675197 +368 41 0.00017199999 +371 41 0.011005599 +374 41 6.8799985e-05 +380 41 0.00089419982 +383 41 0.0011349998 +384 41 0.00027509988 +385 41 0.0098706968 +386 41 0.0067409985 +387 41 6.8799985e-05 +390 41 0.0011006 +394 41 0.00013759999 +398 41 0.00061909994 +402 41 0.00020639999 +412 41 3.4399985e-05 +414 41 0.00020639999 +415 41 0.0057091974 +419 41 0.00013759999 +422 41 0.00020639999 +423 41 3.4399985e-05 +425 41 3.4399985e-05 +430 41 6.8799985e-05 +431 41 3.4399985e-05 +433 41 3.4399985e-05 +434 41 3.4399985e-05 +438 41 0.00017199999 +439 41 0.0002407 +441 41 0.00020639999 +443 41 0.0044022985 +444 41 0.00017199999 +445 41 0.016233299 +446 41 0.0010317999 +447 41 0.00061909994 +450 41 0.0037487999 +452 41 0.00055029988 +453 41 6.8799985e-05 +454 41 0.0011006 +455 41 0.037281599 +456 41 0.024143599 +457 41 0.0039207973 +458 41 0.0002407 +460 41 0.0024074998 +463 41 0.0079790987 +464 41 0.00020639999 +465 41 0.00013759999 +467 41 0.0060186982 +468 41 0.00058469991 +469 41 0.10001379 +470 41 0.0058123991 +471 41 0.0020635999 +473 41 0.00013759999 +477 41 3.4399985e-05 +478 41 0.00065349997 +483 41 0.00037829997 +489 41 0.00010319999 +490 41 0.00048149982 +491 41 0.00020639999 +7 42 6.179999e-05 +16 42 0.00030909991 +18 42 0.00018549999 +24 42 0.0051932 +60 42 0.0001236 +80 42 9.2699993e-05 +108 42 3.0899988e-05 +113 42 3.0899988e-05 +114 42 6.179999e-05 +126 42 3.0899988e-05 +134 42 0.00046369992 +139 42 3.0899988e-05 +141 42 3.0899988e-05 +150 42 3.0899988e-05 +159 42 6.179999e-05 +160 42 0.0017001999 +162 42 6.179999e-05 +163 42 0.00021639999 +164 42 0.00018549999 +165 42 0.00095829996 +166 42 0.00095829996 +167 42 0.00027819979 +168 42 0.0066460967 +170 42 3.0899988e-05 +171 42 0.0001546 +182 42 0.00055639981 +183 42 0.00033999979 +191 42 0.00018549999 +192 42 0.0002472999 +195 42 0.00046369992 +197 42 3.0899988e-05 +198 42 3.0899988e-05 +206 42 6.179999e-05 +214 42 3.0899988e-05 +219 42 0.00040189992 +223 42 0.00021639999 +233 42 0.0012365 +234 42 0.0051004998 +235 42 0.0096753985 +236 42 0.00095829996 +237 42 0.0012055999 +240 42 3.0899988e-05 +241 42 0.0017310998 +242 42 3.0899988e-05 +252 42 0.0011747 +254 42 0.0014218998 +255 42 0.00092739984 +256 42 0.00030909991 +257 42 6.179999e-05 +258 42 0.0013291999 +259 42 0.0002472999 +262 42 0.0017001999 +264 42 0.0014837999 +265 42 0.0059041977 +266 42 0.016043298 +267 42 0.0001236 +268 42 0.00046369992 +269 42 0.0011127999 +271 42 0.0034311998 +272 42 3.0899988e-05 +273 42 6.179999e-05 +274 42 0.0022874998 +277 42 0.0034620999 +279 42 0.00018549999 +282 42 0.0013291999 +285 42 3.0899988e-05 +292 42 0.00083459984 +293 42 9.2699993e-05 +295 42 0.27020085 +302 42 0.00037089991 +303 42 0.00037089991 +304 42 0.0016691999 +305 42 0.027573399 +306 42 0.0035857998 +307 42 0.0002472999 +308 42 0.0058732964 +309 42 0.0022256998 +310 42 0.005656898 +311 42 0.0059968978 +312 42 0.0004327998 +315 42 0.0001546 +317 42 0.00068009994 +318 42 3.0899988e-05 +319 42 0.0012055999 +322 42 0.0029365998 +324 42 0.016723298 +331 42 0.0013291999 +334 42 0.0018855999 +335 42 0.00021639999 +341 42 6.179999e-05 +350 42 9.2699993e-05 +352 42 0.0012673999 +356 42 0.00068009994 +358 42 3.0899988e-05 +366 42 0.0036166999 +368 42 3.0899988e-05 +371 42 0.0027202 +380 42 0.00021639999 +383 42 0.00021639999 +384 42 0.0010509999 +385 42 0.0040803999 +386 42 0.030757297 +387 42 3.0899988e-05 +390 42 0.00027819979 +394 42 3.0899988e-05 +397 42 3.0899988e-05 +398 42 0.0001236 +402 42 0.00033999979 +414 42 3.0899988e-05 +415 42 0.0010201 +419 42 3.0899988e-05 +422 42 3.0899988e-05 +430 42 3.0899988e-05 +438 42 6.179999e-05 +439 42 6.179999e-05 +441 42 6.179999e-05 +443 42 0.0033075998 +444 42 6.179999e-05 +445 42 0.016383298 +446 42 0.00089639984 +447 42 0.00018549999 +448 42 3.0899988e-05 +450 42 0.0011747 +452 42 0.00018549999 +453 42 3.0899988e-05 +454 42 0.00033999979 +455 42 0.037341598 +456 42 0.013137598 +457 42 0.0012365 +458 42 0.00021639999 +460 42 0.0018546998 +463 42 0.0025348 +464 42 6.179999e-05 +465 42 3.0899988e-05 +467 42 0.010324597 +468 42 0.00018549999 +469 42 0.018485297 +470 42 0.0018546998 +471 42 0.0034311998 +473 42 3.0899988e-05 +478 42 0.00018549999 +483 42 0.0001236 +489 42 3.0899988e-05 +490 42 0.0001546 +491 42 0.0001236 +24 43 0.013648998 +134 43 0.00027859979 +160 43 0.004735399 +163 43 0.0011141999 +164 43 0.00055709993 +165 43 0.0013927999 +166 43 0.0033425998 +167 43 0.00083569996 +168 43 0.019220099 +191 43 0.00027859979 +192 43 0.00083569996 +233 43 0.00027859979 +234 43 0.0019498998 +235 43 0.0066851974 +236 43 0.00055709993 +237 43 0.00083569996 +241 43 0.0027854999 +252 43 0.00027859979 +255 43 0.00055709993 +262 43 0.00027859979 +264 43 0.00055709993 +265 43 0.011977699 +266 43 0.0061280988 +268 43 0.00027859979 +271 43 0.00055709993 +274 43 0.0011141999 +277 43 0.14512527 +279 43 0.00027859979 +282 43 0.00027859979 +285 43 0.00027859979 +292 43 0.00055709993 +295 43 0.013091899 +302 43 0.00027859979 +303 43 0.00027859979 +304 43 0.00055709993 +305 43 0.021726999 +306 43 0.0011141999 +308 43 0.0011141999 +309 43 0.0011141999 +310 43 0.0016712998 +311 43 0.0019498998 +317 43 0.00027859979 +319 43 0.00083569996 +322 43 0.0036211999 +324 43 0.084958196 +326 43 0.067687988 +331 43 0.00055709993 +334 43 0.00055709993 +356 43 0.00083569996 +366 43 0.0011141999 +371 43 0.0144847 +380 43 0.00083569996 +384 43 0.00055709993 +385 43 0.020055696 +386 43 0.029247899 +390 43 0.0013927999 +402 43 0.00027859979 +415 43 0.00027859979 +441 43 0.00027859979 +443 43 0.0055709966 +445 43 0.0231198 +446 43 0.00055709993 +450 43 0.00055709993 +455 43 0.0462396 +456 43 0.0064066984 +457 43 0.00055709993 +460 43 0.00083569996 +463 43 0.0011141999 +467 43 0.0066851974 +469 43 0.010306399 +470 43 0.00083569996 +471 43 0.0019498998 +7 44 2.4899986e-05 +9 44 1.24e-05 +16 44 8.7099994e-05 +18 44 6.2199993e-05 +24 44 0.0012937 +60 44 7.4599986e-05 +80 44 7.4599986e-05 +82 44 1.24e-05 +108 44 1.24e-05 +113 44 1.24e-05 +114 44 2.4899986e-05 +126 44 1.24e-05 +134 44 4.9799986e-05 +141 44 2.4899986e-05 +150 44 2.4899986e-05 +159 44 0.00011199999 +160 44 0.0042542964 +162 44 2.4899986e-05 +163 44 6.2199993e-05 +164 44 6.2199993e-05 +165 44 0.0010076 +166 44 0.00027369987 +167 44 7.4599986e-05 +168 44 0.022316199 +170 44 3.7299993e-05 +171 44 0.00018659999 +182 44 0.00012439999 +183 44 7.4599986e-05 +189 44 1.24e-05 +191 44 6.2199993e-05 +192 44 0.00018659999 +194 44 1.24e-05 +195 44 0.00080859987 +198 44 2.4899986e-05 +203 44 1.24e-05 +206 44 2.4899986e-05 +214 44 0.00013679999 +219 44 0.00013679999 +220 44 2.4899986e-05 +223 44 0.00016169999 +233 44 0.00079609989 +234 44 0.00083339983 +235 44 0.00077119982 +236 44 0.00059709977 +237 44 0.0010324998 +241 44 0.00073389988 +242 44 6.2199993e-05 +252 44 0.00023629999 +254 44 0.0019405 +255 44 0.0011816998 +256 44 2.4899986e-05 +257 44 0.0010698 +258 44 0.0005349 +259 44 6.2199993e-05 +262 44 0.013733096 +264 44 0.0010698 +265 44 0.015511896 +266 44 0.016730897 +267 44 8.7099994e-05 +268 44 8.7099994e-05 +269 44 0.00033589988 +271 44 0.0074138977 +272 44 0.0007836998 +273 44 0.00039809989 +274 44 0.0008582999 +277 44 0.024605099 +279 44 0.0012563998 +282 44 0.00075879996 +285 44 1.24e-05 +292 44 0.00055979984 +293 44 1.24e-05 +294 44 1.24e-05 +295 44 0.0496579 +302 44 9.9499986e-05 +303 44 9.9499986e-05 +304 44 0.00069659995 +305 44 0.058265999 +306 44 0.0013807998 +307 44 0.06998378 +308 44 0.0015299998 +309 44 0.0016668998 +310 44 0.0012314999 +311 44 0.0072520971 +312 44 0.00059709977 +315 44 3.7299993e-05 +317 44 0.00038559991 +318 44 1.24e-05 +319 44 0.00028609997 +322 44 0.0016543998 +324 44 0.099614382 +331 44 0.0011443999 +334 44 0.00022389999 +335 44 4.9799986e-05 +341 44 3.7299993e-05 +350 44 2.4899986e-05 +352 44 0.00079609989 +356 44 0.00062199985 +358 44 2.4899986e-05 +366 44 0.00087079988 +368 44 1.24e-05 +371 44 0.00072149979 +374 44 0.00073389988 +380 44 6.2199993e-05 +383 44 8.7099994e-05 +384 44 2.4899986e-05 +385 44 0.0225899 +386 44 0.021619599 +387 44 1.24e-05 +390 44 7.4599986e-05 +394 44 2.4899986e-05 +397 44 2.4899986e-05 +398 44 2.4899986e-05 +402 44 0.00028609997 +414 44 0.0061698966 +415 44 0.0002487998 +422 44 3.7299993e-05 +430 44 1.24e-05 +438 44 6.2199993e-05 +439 44 1.24e-05 +441 44 7.4599986e-05 +443 44 0.0043661967 +444 44 2.4899986e-05 +445 44 0.0088318996 +446 44 0.0011568998 +447 44 0.00026119989 +450 44 0.00073389988 +452 44 0.00011199999 +453 44 1.24e-05 +454 44 0.0002115 +455 44 0.0447568 +456 44 0.016880199 +457 44 0.00077119982 +458 44 0.00018659999 +460 44 0.0016917998 +463 44 0.0015673998 +464 44 3.7299993e-05 +465 44 2.4899986e-05 +467 44 0.0087572969 +468 44 0.00011199999 +469 44 0.035539199 +470 44 0.0011443999 +471 44 0.0028859 +473 44 2.4899986e-05 +478 44 0.00012439999 +483 44 7.4599986e-05 +489 44 1.24e-05 +490 44 8.7099994e-05 +491 44 6.2199993e-05 +16 45 0.00012079999 +18 45 6.0399994e-05 +24 45 0.010453198 +60 45 0.00024169999 +108 45 6.0399994e-05 +113 45 6.0399994e-05 +114 45 0.00012079999 +126 45 6.0399994e-05 +134 45 6.0399994e-05 +141 45 6.0399994e-05 +150 45 6.0399994e-05 +160 45 0.00030209986 +163 45 6.0399994e-05 +164 45 6.0399994e-05 +165 45 0.0001813 +166 45 0.0001813 +168 45 0.00030209986 +171 45 6.0399994e-05 +182 45 0.00012079999 +183 45 6.0399994e-05 +191 45 6.0399994e-05 +192 45 0.00012079999 +198 45 6.0399994e-05 +206 45 0.00012079999 +214 45 0.0033232998 +219 45 6.0399994e-05 +220 45 0.0010271999 +223 45 0.00024169999 +233 45 0.0045316964 +234 45 0.060120799 +235 45 0.0087008998 +236 45 0.00036249985 +237 45 0.0016917998 +241 45 0.0070090964 +242 45 0.00012079999 +252 45 0.00024169999 +254 45 0.00030209986 +255 45 0.00024169999 +256 45 6.0399994e-05 +259 45 6.0399994e-05 +264 45 0.00036249985 +265 45 0.0016917998 +266 45 0.023867097 +268 45 0.00012079999 +269 45 0.00012079999 +271 45 0.0001813 +274 45 0.00036249985 +277 45 0.088157058 +279 45 6.0399994e-05 +282 45 0.00012079999 +292 45 0.00060419994 +295 45 0.0069485977 +302 45 0.00012079999 +303 45 0.00012079999 +304 45 0.00024169999 +305 45 0.010876097 +306 45 0.0009062998 +307 45 0.086344361 +308 45 0.006525699 +309 45 0.0087008998 +310 45 0.0009062998 +311 45 0.0032627999 +312 45 6.0399994e-05 +317 45 0.0013897 +318 45 6.0399994e-05 +319 45 0.00024169999 +322 45 0.004048299 +324 45 0.083504498 +331 45 0.0018126999 +334 45 0.00024169999 +335 45 6.0399994e-05 +341 45 0.00012079999 +352 45 0.00012079999 +356 45 0.0029002998 +358 45 6.0399994e-05 +366 45 0.00066469982 +371 45 0.012144998 +374 45 0.0039274991 +380 45 6.0399994e-05 +385 45 0.0018730999 +386 45 0.0012689 +387 45 6.0399994e-05 +390 45 6.0399994e-05 +394 45 6.0399994e-05 +402 45 0.00042299996 +414 45 0.039154097 +415 45 0.0001813 +422 45 6.0399994e-05 +430 45 6.0399994e-05 +443 45 0.0048942976 +444 45 0.00012079999 +445 45 0.011842899 +446 45 0.0025982 +447 45 0.00078549981 +448 45 0.0012084998 +450 45 0.0024772999 +452 45 0.00036249985 +453 45 6.0399994e-05 +454 45 0.00072509982 +455 45 0.067190289 +456 45 0.028398797 +457 45 0.0025982 +458 45 0.00030209986 +460 45 0.0029002998 +463 45 0.0053172 +464 45 0.00012079999 +465 45 6.0399994e-05 +467 45 0.013534699 +468 45 0.00036249985 +469 45 0.015528698 +470 45 0.0038671 +471 45 0.0045920983 +473 45 6.0399994e-05 +478 45 0.00042299996 +483 45 0.00024169999 +489 45 6.0399994e-05 +490 45 0.00030209986 +491 45 0.00024169999 +24 46 0.0098591968 +214 46 0.0031689999 +220 46 0.0014084999 +233 46 0.015140798 +234 46 0.058098599 +235 46 0.0056337975 +237 46 0.0021126999 +265 46 0.0014084999 +266 46 0.0038731999 +277 46 0.20352107 +295 46 0.011619698 +305 46 0.0014084999 +306 46 0.00035209977 +307 46 0.12746477 +311 46 0.00070419977 +317 46 0.00035209977 +322 46 0.0031689999 +324 46 0.025704198 +331 46 0.0024647999 +356 46 0.0028168999 +371 46 0.021830998 +374 46 0.0021126999 +385 46 0.0028168999 +386 46 0.0017605999 +390 46 0.0014084999 +402 46 0.00070419977 +414 46 0.0098591968 +443 46 0.0056337975 +445 46 0.010211296 +446 46 0.0024647999 +448 46 0.0010562998 +450 46 0.00070419977 +455 46 0.063028157 +456 46 0.020774599 +457 46 0.00070419977 +458 46 0.00035209977 +460 46 0.0021126999 +463 46 0.0014084999 +467 46 0.019718297 +469 46 0.011971798 +470 46 0.0010562998 +471 46 0.0063379966 +16 47 0.00018589999 +24 47 0.0015798998 +60 47 9.2899994e-05 +114 47 9.2899994e-05 +160 47 0.00037169992 +165 47 0.00046469993 +214 47 9.2899994e-05 +220 47 9.2899994e-05 +223 47 9.2899994e-05 +233 47 0.00092939986 +234 47 0.0045538992 +235 47 0.00083639985 +236 47 9.2899994e-05 +237 47 0.00065059983 +241 47 0.010408897 +254 47 0.0028809998 +255 47 0.00027879979 +258 47 9.2899994e-05 +259 47 0.00018589999 +264 47 0.00055759982 +265 47 0.019330896 +266 47 0.0096653998 +271 47 0.020817798 +274 47 0.00037169992 +277 47 0.013196997 +282 47 0.20836425 +292 47 0.00027879979 +295 47 0.00055759982 +302 47 9.2899994e-05 +306 47 0.00046469993 +307 47 0.071840048 +308 47 0.0070631988 +309 47 0.0010223 +310 47 0.0055761971 +311 47 0.0013010998 +312 47 9.2899994e-05 +317 47 0.00027879979 +319 47 0.00018589999 +322 47 0.00018589999 +324 47 0.096096694 +331 47 0.00065059983 +350 47 9.2899994e-05 +356 47 0.00083639985 +371 47 0.004089199 +374 47 0.00065059983 +385 47 0.0043679997 +386 47 0.00046469993 +402 47 9.2899994e-05 +414 47 0.0098512992 +443 47 0.0029739998 +445 47 0.0092936978 +446 47 0.00065059983 +447 47 0.00018589999 +448 47 9.2899994e-05 +450 47 0.00074349996 +452 47 9.2899994e-05 +454 47 0.00018589999 +455 47 0.039405197 +456 47 0.029182199 +457 47 0.00074349996 +458 47 9.2899994e-05 +460 47 0.0072490983 +463 47 0.0015798998 +467 47 0.015613399 +468 47 9.2899994e-05 +469 47 0.022676598 +470 47 0.0012081999 +471 47 0.0016728998 +478 47 9.2899994e-05 +483 47 9.2899994e-05 +490 47 9.2899994e-05 +7 48 0.00019979999 +16 48 0.0013486999 +18 48 0.00094909989 +24 48 0.012986999 +60 48 0.00024979981 +80 48 9.9899989e-05 +82 48 4.9999988e-05 +108 48 4.9999988e-05 +113 48 4.9999988e-05 +114 48 9.9899989e-05 +126 48 4.9999988e-05 +134 48 4.9999988e-05 +139 48 9.9899989e-05 +141 48 4.9999988e-05 +150 48 9.9899989e-05 +154 48 4.9999988e-05 +160 48 0.0023975999 +163 48 0.00024979981 +165 48 0.0012987 +166 48 4.9999988e-05 +168 48 0.00089909998 +170 48 4.9999988e-05 +171 48 4.9999988e-05 +182 48 0.00014989999 +183 48 9.9899989e-05 +189 48 4.9999988e-05 +191 48 9.9899989e-05 +192 48 9.9899989e-05 +194 48 4.9999988e-05 +197 48 4.9999988e-05 +198 48 4.9999988e-05 +203 48 4.9999988e-05 +206 48 9.9899989e-05 +214 48 4.9999988e-05 +215 48 9.9899989e-05 +219 48 0.00074929977 +220 48 0.00069929985 +223 48 0.00034969999 +233 48 0.0010988999 +234 48 0.0015484998 +235 48 0.0051448978 +236 48 0.00019979999 +237 48 0.0016982998 +241 48 0.0035963999 +242 48 0.00024979981 +252 48 4.9999988e-05 +254 48 0.00069929985 +255 48 0.00059939991 +256 48 4.9999988e-05 +257 48 9.9899989e-05 +258 48 0.015734296 +259 48 4.9999988e-05 +264 48 0.0013486999 +265 48 0.075074852 +266 48 0.022827197 +267 48 4.9999988e-05 +268 48 4.9999988e-05 +269 48 0.00029969984 +271 48 0.0143856 +273 48 9.9899989e-05 +274 48 0.004245799 +277 48 0.012287699 +279 48 0.00049949996 +282 48 0.084765196 +285 48 4.9999988e-05 +292 48 0.00014989999 +293 48 4.9999988e-05 +295 48 0.0023476998 +302 48 4.9999988e-05 +303 48 0.0024974998 +304 48 0.0056942999 +305 48 0.017981999 +306 48 0.0028471998 +307 48 0.0020978998 +308 48 0.0065933987 +309 48 0.0019480998 +310 48 0.0019480998 +311 48 0.0049450994 +312 48 0.00039959978 +317 48 0.0013985999 +318 48 4.9999988e-05 +319 48 0.00069929985 +322 48 0.0015484998 +324 48 0.00089909998 +331 48 0.0017982 +334 48 4.9999988e-05 +335 48 0.0021478999 +336 48 0.0027971999 +341 48 0.00014989999 +350 48 0.00089909998 +352 48 0.0015484998 +356 48 9.9899989e-05 +358 48 9.9899989e-05 +366 48 0.00014989999 +368 48 0.039210796 +371 48 0.0091408975 +374 48 9.9899989e-05 +380 48 9.9899989e-05 +384 48 4.9999988e-05 +385 48 0.0014984999 +386 48 0.0014984999 +387 48 4.9999988e-05 +394 48 9.9899989e-05 +402 48 0.00039959978 +414 48 0.0031468999 +415 48 0.0016982998 +422 48 0.00014989999 +430 48 4.9999988e-05 +438 48 4.9999988e-05 +439 48 4.9999988e-05 +441 48 4.9999988e-05 +443 48 0.0033965998 +444 48 9.9899989e-05 +445 48 0.015534498 +446 48 0.00089909998 +447 48 0.00049949996 +450 48 0.0026473999 +452 48 0.00039959978 +453 48 4.9999988e-05 +454 48 0.0007991998 +455 48 0.0412088 +456 48 0.011438597 +457 48 0.0027971999 +458 48 0.00034969999 +460 48 0.0053945966 +463 48 0.0056942999 +464 48 0.00014989999 +465 48 9.9899989e-05 +467 48 0.016683299 +468 48 0.00039959978 +469 48 0.026923098 +470 48 0.0041458979 +471 48 0.0046453997 +473 48 9.9899989e-05 +478 48 0.00044959993 +483 48 0.00029969984 +489 48 4.9999988e-05 +490 48 0.00034969999 +491 48 0.00019979999 +7 49 0.00058139977 +16 49 0.0027131999 +18 49 0.0017441998 +24 49 0.014534898 +60 49 0.00019379999 +114 49 0.00019379999 +160 49 0.006395299 +165 49 0.0015503999 +166 49 0.00019379999 +168 49 0.0015503999 +192 49 0.00019379999 +215 49 0.00019379999 +219 49 0.00019379999 +223 49 0.00038759992 +233 49 0.00058139977 +234 49 0.0021317999 +235 49 0.006007798 +236 49 0.00058139977 +237 49 0.0015503999 +241 49 0.0017441998 +252 49 0.00038759992 +254 49 0.0025193999 +255 49 0.00038759992 +257 49 0.00019379999 +258 49 0.00038759992 +259 49 0.00019379999 +264 49 0.00038759992 +265 49 0.014728699 +266 49 0.032364298 +267 49 0.00038759992 +268 49 0.00019379999 +269 49 0.00019379999 +271 49 0.00058139977 +273 49 0.00019379999 +274 49 0.0019379999 +277 49 0.0093022995 +279 49 0.00019379999 +282 49 0.00077519985 +292 49 0.00058139977 +295 49 0.013372097 +302 49 0.00019379999 +303 49 0.00058139977 +304 49 0.00077519985 +305 49 0.06996119 +306 49 0.0029069998 +307 49 0.0050387979 +308 49 0.0023255998 +309 49 0.0032945999 +310 49 0.0029069998 +311 49 0.0071704984 +312 49 0.00038759992 +317 49 0.0015503999 +319 49 0.00038759992 +322 49 0.0029069998 +324 49 0.017829496 +326 49 0.00096899993 +331 49 0.0017441998 +334 49 0.012984499 +341 49 0.00019379999 +352 49 0.0034883998 +356 49 0.00019379999 +366 49 0.0038759999 +371 49 0.0054263994 +380 49 0.00019379999 +385 49 0.0050387979 +386 49 0.0067828968 +390 49 0.00038759992 +394 49 0.00019379999 +402 49 0.00038759992 +415 49 0.00038759992 +441 49 0.0034883998 +443 49 0.0032945999 +444 49 0.00019379999 +445 49 0.049418598 +446 49 0.00038759992 +447 49 0.00038759992 +450 49 0.0029069998 +452 49 0.00038759992 +454 49 0.00077519985 +455 49 0.020736396 +456 49 0.0073642991 +457 49 0.0029069998 +458 49 0.00038759992 +460 49 0.0027131999 +463 49 0.0058139972 +464 49 0.00019379999 +467 49 0.013953499 +468 49 0.00038759992 +469 49 0.096705377 +470 49 0.0044573992 +471 49 0.0046511963 +473 49 0.00019379999 +478 49 0.00038759992 +483 49 0.00038759992 +490 49 0.00038759992 +491 49 0.00019379999 +7 50 8.6299988e-05 +9 50 9.5999994e-06 +16 50 0.00047939993 +18 50 0.00035479991 +24 50 0.043887198 +60 50 0.00012469999 +82 50 9.5999994e-06 +83 50 9.5999994e-06 +84 50 9.5999994e-06 +108 50 1.9199986e-05 +113 50 1.9199986e-05 +114 50 3.8399987e-05 +126 50 2.8799986e-05 +127 50 9.5999994e-06 +141 50 4.7899986e-05 +150 50 3.8399987e-05 +159 50 9.5999994e-06 +160 50 0.0011026999 +165 50 0.0043340996 +168 50 0.00093969982 +170 50 0.00010549999 +171 50 3.8399987e-05 +189 50 9.5999994e-06 +192 50 0.00020139999 +194 50 9.5999994e-06 +198 50 4.7899986e-05 +201 50 9.5999994e-06 +203 50 9.5999994e-06 +204 50 1.9199986e-05 +206 50 4.7899986e-05 +207 50 9.5999994e-06 +215 50 0.00070959982 +218 50 9.5999994e-06 +220 50 0.0011697998 +223 50 0.00024929992 +233 50 0.005781997 +234 50 0.043580398 +235 50 0.032093197 +237 50 0.0017450999 +241 50 0.00012469999 +242 50 3.8399987e-05 +248 50 9.5999994e-06 +250 50 9.5999994e-06 +252 50 9.5999994e-06 +254 50 0.016645897 +255 50 0.00012469999 +258 50 0.0015628999 +265 50 0.070208073 +266 50 0.032745197 +269 50 4.7899986e-05 +270 50 0.00014379999 +274 50 0.0026464998 +277 50 0.010806397 +279 50 0.00068079983 +282 50 0.00017259999 +295 50 0.0011409998 +305 50 0.028391998 +308 50 0.013232298 +309 50 0.0077283978 +311 50 0.016003497 +312 50 1.9199986e-05 +317 50 0.00064239977 +318 50 1.9199986e-05 +319 50 2.8799986e-05 +322 50 0.007440798 +331 50 0.0019943998 +341 50 4.7899986e-05 +358 50 3.8399987e-05 +371 50 0.00026849983 +385 50 0.0078818984 +386 50 0.0014094999 +387 50 1.9199986e-05 +394 50 4.7899986e-05 +397 50 2.8799986e-05 +402 50 0.000489 +412 50 9.5999994e-06 +419 50 9.5999994e-06 +422 50 5.7499987e-05 +423 50 9.5999994e-06 +425 50 9.5999994e-06 +430 50 1.9199986e-05 +431 50 9.5999994e-06 +433 50 9.5999994e-06 +434 50 9.5999994e-06 +438 50 0.00026849983 +441 50 0.0048230998 +443 50 0.0090708993 +444 50 4.7899986e-05 +445 50 0.026196197 +446 50 0.0030491999 +447 50 0.00045069982 +448 50 0.00089169992 +450 50 0.0012464998 +452 50 0.00018219999 +453 50 1.9199986e-05 +454 50 0.00037399982 +455 50 0.047914498 +456 50 0.018026698 +457 50 0.0013040998 +458 50 0.00030679977 +460 50 0.00373 +463 50 0.0026464998 +464 50 6.7099987e-05 +465 50 3.8399987e-05 +467 50 0.0151213 +468 50 0.00019179999 +469 50 0.0253428 +470 50 0.0019272999 +471 50 0.0050244965 +473 50 3.8399987e-05 +477 50 9.5999994e-06 +478 50 0.00022049999 +483 50 0.00013419999 +489 50 2.8799986e-05 +490 50 0.00015339999 +491 50 8.6299988e-05 +7 51 0.0001736 +16 51 0.00086809997 +18 51 0.00069439993 +24 51 0.0022568998 +60 51 0.0001736 +114 51 0.0001736 +134 51 0.0062499978 +135 51 0.0001736 +139 51 0.0012152998 +142 51 0.0001736 +160 51 0.0446181 +161 51 0.00086809997 +162 51 0.0027778 +163 51 0.043402798 +164 51 0.0119792 +165 51 0.027777798 +167 51 0.016145799 +170 51 0.00069439993 +171 51 0.0024305999 +177 51 0.0015624999 +182 51 0.0019097 +191 51 0.0031249998 +192 51 0.0015624999 +197 51 0.00086809997 +214 51 0.0001736 +215 51 0.0001736 +219 51 0.0010416999 +223 51 0.0001736 +233 51 0.0086805969 +234 51 0.00069439993 +235 51 0.0001736 +236 51 0.0041666999 +237 51 0.0012152998 +240 51 0.00052079977 +241 51 0.013715297 +242 51 0.00034719985 +252 51 0.00069439993 +254 51 0.0024305999 +255 51 0.004513897 +256 51 0.0043402985 +257 51 0.00069439993 +258 51 0.0013889 +259 51 0.0032986 +264 51 0.0071180984 +265 51 0.0015624999 +266 51 0.025694396 +267 51 0.0001736 +268 51 0.0062499978 +269 51 0.0013889 +271 51 0.0017360998 +273 51 0.00034719985 +274 51 0.0036457998 +277 51 0.0029513999 +279 51 0.0017360998 +282 51 0.0012152998 +292 51 0.0034721999 +295 51 0.0119792 +302 51 0.0039930977 +303 51 0.013888899 +304 51 0.0024305999 +306 51 0.0170139 +307 51 0.00052079977 +308 51 0.013020799 +309 51 0.0010416999 +310 51 0.0043402985 +311 51 0.0019097 +312 51 0.0001736 +317 51 0.00086809997 +319 51 0.0050346963 +322 51 0.0043402985 +324 51 0.00034719985 +331 51 0.0012152998 +341 51 0.0001736 +350 51 0.0019097 +352 51 0.00034719985 +366 51 0.011805598 +368 51 0.00086809997 +371 51 0.0085068978 +380 51 0.00069439993 +383 51 0.0017360998 +385 51 0.0093749985 +386 51 0.0043402985 +390 51 0.0013889 +398 51 0.00052079977 +402 51 0.00034719985 +415 51 0.0012152998 +438 51 0.00052079977 +439 51 0.0010416999 +443 51 0.0083332993 +445 51 0.0088541992 +446 51 0.00086809997 +447 51 0.00034719985 +450 51 0.0019097 +452 51 0.00034719985 +454 51 0.00052079977 +455 51 0.0432292 +456 51 0.057638898 +457 51 0.0019097 +458 51 0.0001736 +460 51 0.0024305999 +463 51 0.0039930977 +464 51 0.0001736 +467 51 0.0105903 +468 51 0.00034719985 +469 51 0.031423599 +470 51 0.0029513999 +471 51 0.0034721999 +478 51 0.0001736 +483 51 0.0001736 +490 51 0.0001736 +491 51 0.0001736 +24 52 0.011103399 +60 52 6.9799993e-05 +114 52 6.9799993e-05 +141 52 6.9799993e-05 +159 52 0.00013969999 +160 52 0.035265397 +162 52 0.0025837999 +163 52 0.014804497 +165 52 0.020530697 +168 52 0.015642498 +170 52 0.00055869995 +171 52 0.00069829985 +191 52 0.0038407999 +192 52 0.00090779993 +197 52 0.00013969999 +198 52 6.9799993e-05 +214 52 6.9799993e-05 +223 52 0.0004888 +233 52 0.0055865981 +234 52 0.0023742998 +235 52 0.0035615 +236 52 0.0065641999 +237 52 0.00090779993 +241 52 0.0147346 +254 52 0.0045390986 +255 52 0.00027929991 +262 52 0.0047485977 +264 52 0.0111732 +265 52 0.032681599 +266 52 0.071298897 +268 52 0.0036312998 +274 52 0.00069829985 +277 52 0.008379899 +279 52 0.011871498 +292 52 0.00090779993 +293 52 0.0037010999 +295 52 0.015921798 +304 52 6.9799993e-05 +306 52 0.0050278977 +307 52 0.0097764991 +308 52 0.099860251 +309 52 0.0023742998 +310 52 0.046159197 +311 52 0.00083799986 +317 52 0.0004888 +319 52 0.0030027998 +322 52 0.037150797 +324 52 0.0017457998 +331 52 0.00090779993 +341 52 6.9799993e-05 +350 52 0.0011172998 +356 52 0.00020949999 +366 52 6.9799993e-05 +371 52 0.0023742998 +385 52 0.0071228966 +386 52 0.0027234999 +398 52 0.00020949999 +402 52 0.00020949999 +415 52 0.0007681998 +438 52 0.00034919987 +443 52 0.010125697 +444 52 6.9799993e-05 +445 52 0.016969297 +446 52 0.0011172998 +447 52 0.00083799986 +450 52 0.00090779993 +452 52 0.00013969999 +454 52 0.00020949999 +455 52 0.051815599 +456 52 0.054189898 +457 52 0.00097769988 +458 52 0.00013969999 +460 52 0.002933 +463 52 0.0019552999 +464 52 6.9799993e-05 +467 52 0.0078910999 +468 52 0.00013969999 +469 52 0.0062150992 +470 52 0.0014664999 +471 52 0.0025139998 +478 52 0.00013969999 +483 52 6.9799993e-05 +490 52 0.00013969999 +491 52 6.9799993e-05 +24 53 0.00089739985 +60 53 4.269999e-05 +80 53 0.00029909983 +114 53 4.269999e-05 +160 53 0.00029909983 +192 53 4.269999e-05 +214 53 0.014828399 +220 53 0.00051279995 +223 53 0.021152899 +233 53 0.0012392998 +234 53 0.021323897 +237 53 0.0061107986 +241 53 0.00025639986 +242 53 0.00025639986 +254 53 0.0276911 +273 53 0.012050796 +277 53 0.17024904 +312 53 0.0014101998 +317 53 0.00025639986 +319 53 0.00081189978 +322 53 0.00094009982 +324 53 0.0018374999 +331 53 0.0071363971 +333 53 0.048630398 +341 53 4.269999e-05 +350 53 0.006794598 +356 53 0.00068369997 +374 53 0.0014528998 +397 53 8.5499996e-05 +402 53 0.0017092999 +438 53 8.5499996e-05 +443 53 0.014272898 +445 53 0.0099567994 +446 53 0.0043587983 +447 53 0.00017089999 +448 53 0.00042729988 +450 53 0.00047009997 +452 53 8.5499996e-05 +454 53 0.00012819999 +455 53 0.041322999 +456 53 0.0062817968 +457 53 0.00051279995 +458 53 0.00098289992 +460 53 0.0068799965 +463 53 0.0010255999 +464 53 4.269999e-05 +467 53 0.053459298 +468 53 8.5499996e-05 +469 53 0.00068369997 +470 53 0.0007691998 +471 53 0.017606098 +478 53 8.5499996e-05 +483 53 4.269999e-05 +490 53 4.269999e-05 +491 53 8.5499996e-05 +60 54 0.00026829983 +114 54 0.00026829983 +214 54 0.0085859969 +220 54 0.035148896 +234 54 0.036222197 +237 54 0.0053661987 +317 54 0.0018781999 +331 54 0.0059028976 +341 54 0.00026829983 +394 54 0.00026829983 +402 54 0.0016098998 +443 54 0.0026830998 +444 54 0.00026829983 +445 54 0.007244397 +446 54 0.0021464999 +447 54 0.00053659989 +448 54 0.00053659989 +450 54 0.0037564 +452 54 0.00053659989 +454 54 0.00080489996 +455 54 0.0238798 +456 54 0.0056345984 +457 54 0.0040246993 +458 54 0.00080489996 +460 54 0.0053661987 +463 54 0.0080493987 +464 54 0.00026829983 +467 54 0.042124998 +468 54 0.00053659989 +469 54 0.0050978996 +470 54 0.0059028976 +471 54 0.014488898 +478 54 0.00053659989 +483 54 0.00026829983 +490 54 0.00053659989 +491 54 0.00026829983 +7 55 0.00027599977 +16 55 0.0018398999 +18 55 0.0012878999 +24 55 0.011315499 +60 55 0.00018399999 +80 55 9.1999987e-05 +108 55 9.1999987e-05 +113 55 9.1999987e-05 +114 55 0.00018399999 +126 55 9.1999987e-05 +134 55 0.0016558999 +139 55 9.1999987e-05 +150 55 9.1999987e-05 +160 55 0.0030359 +162 55 0.00018399999 +164 55 0.00055199978 +165 55 0.0029438999 +166 55 0.0033119 +167 55 0.0010119998 +168 55 0.0030359 +170 55 9.1999987e-05 +171 55 0.00027599977 +182 55 0.0033119 +183 55 0.0022078999 +191 55 0.00045999978 +192 55 0.00073599978 +195 55 9.1999987e-05 +197 55 9.1999987e-05 +206 55 9.1999987e-05 +214 55 0.00027599977 +215 55 0.00018399999 +219 55 0.0010119998 +220 55 0.00027599977 +223 55 0.00027599977 +233 55 0.0074516982 +234 55 0.010395598 +235 55 0.0068076998 +236 55 0.00055199978 +237 55 0.0018398999 +241 55 0.0062556975 +242 55 9.1999987e-05 +252 55 0.0014718999 +254 55 0.0050597973 +255 55 0.0022998999 +256 55 0.00064399978 +258 55 0.0018398999 +259 55 0.00073599978 +262 55 0.00091999979 +264 55 0.0037717998 +265 55 0.022999097 +266 55 0.025758997 +267 55 0.00036799978 +268 55 0.0013798999 +269 55 0.0022998999 +271 55 0.0046917982 +272 55 0.00018399999 +273 55 0.00027599977 +274 55 0.0056117997 +277 55 0.014903396 +279 55 0.00055199978 +282 55 0.0035879 +285 55 9.1999987e-05 +292 55 0.0022998999 +293 55 0.00018399999 +295 55 0.018215299 +302 55 0.0011039998 +303 55 0.0013798999 +304 55 0.0048757978 +305 55 0.025482997 +306 55 0.010487597 +307 55 0.027506899 +308 55 0.014075398 +309 55 0.0060717985 +310 55 0.0053357966 +311 55 0.014167398 +312 55 0.00036799978 +315 55 0.00018399999 +317 55 0.0011039998 +319 55 0.0043237992 +322 55 0.0045997985 +324 55 0.0111316 +326 55 0.0011039998 +331 55 0.0018398999 +334 55 0.0034959 +335 55 0.0013798999 +336 55 0.00018399999 +341 55 9.1999987e-05 +350 55 0.00045999978 +352 55 0.0046917982 +356 55 0.00082799979 +358 55 9.1999987e-05 +366 55 0.0085556991 +368 55 0.0033119 +371 55 0.010763597 +374 55 0.00027599977 +380 55 0.00073599978 +383 55 0.00064399978 +384 55 0.00027599977 +385 55 0.011959497 +386 55 0.0081876963 +387 55 9.1999987e-05 +390 55 0.0010119998 +394 55 9.1999987e-05 +398 55 0.00027599977 +402 55 0.00055199978 +414 55 0.0022078999 +415 55 0.0027598999 +419 55 9.1999987e-05 +422 55 9.1999987e-05 +438 55 0.00018399999 +439 55 0.00018399999 +441 55 0.0010119998 +443 55 0.0037717998 +444 55 9.1999987e-05 +445 55 0.017295297 +446 55 0.0010119998 +447 55 0.00027599977 +448 55 9.1999987e-05 +450 55 0.0022078999 +452 55 0.00036799978 +454 55 0.00064399978 +455 55 0.037074499 +456 55 0.023643099 +457 55 0.0022998999 +458 55 0.00036799978 +460 55 0.0028518999 +463 55 0.0045997985 +464 55 9.1999987e-05 +467 55 0.015639398 +468 55 0.00036799978 +469 55 0.081600666 +470 55 0.0034039 +471 55 0.004783798 +473 55 9.1999987e-05 +478 55 0.00036799978 +483 55 0.00018399999 +490 55 0.00027599977 +491 55 9.1999987e-05 +7 56 9.2099988e-05 +16 56 0.00032229978 +18 56 0.00023019999 +24 56 0.017541397 +60 56 9.2099988e-05 +80 56 0.00013809999 +108 56 4.5999986e-05 +113 56 4.5999986e-05 +114 56 9.2099988e-05 +126 56 4.5999986e-05 +150 56 4.5999986e-05 +159 56 4.5999986e-05 +160 56 0.0020717999 +165 56 0.0017955999 +166 56 4.5999986e-05 +168 56 0.0075045973 +170 56 9.2099988e-05 +171 56 9.2099988e-05 +191 56 4.5999986e-05 +192 56 0.00013809999 +195 56 4.5999986e-05 +206 56 4.5999986e-05 +214 56 0.00023019999 +215 56 0.00013809999 +217 56 4.5999986e-05 +220 56 0.0029006 +223 56 0.00018419999 +233 56 0.0014272998 +234 56 0.037891299 +235 56 0.0029006 +236 56 0.00023019999 +237 56 0.0029006 +240 56 9.2099988e-05 +241 56 0.004557997 +242 56 0.0014272998 +252 56 4.5999986e-05 +254 56 0.015009198 +255 56 0.00013809999 +257 56 4.5999986e-05 +258 56 0.00023019999 +259 56 4.5999986e-05 +262 56 0.0035911999 +264 56 0.00064459979 +265 56 0.0081951991 +266 56 0.0084714964 +267 56 4.5999986e-05 +268 56 4.5999986e-05 +271 56 0.0005063999 +272 56 0.00018419999 +273 56 0.00018419999 +274 56 0.0004143999 +277 56 0.011325996 +279 56 0.00073659979 +282 56 0.00027619977 +292 56 0.00013809999 +293 56 4.5999986e-05 +295 56 0.016482498 +302 56 4.5999986e-05 +303 56 9.2099988e-05 +304 56 4.5999986e-05 +305 56 0.026058897 +306 56 0.0006905999 +307 56 0.027532198 +308 56 0.0050183982 +309 56 0.0010128999 +310 56 0.00032229978 +311 56 0.0090699978 +312 56 0.0005524999 +317 56 0.00059849978 +319 56 0.0004143999 +322 56 0.0040975995 +324 56 0.0031768 +331 56 0.0031768 +333 56 0.00027619977 +334 56 4.5999986e-05 +341 56 4.5999986e-05 +352 56 0.0015192998 +356 56 0.00087479991 +358 56 4.5999986e-05 +366 56 0.00023019999 +368 56 4.5999986e-05 +371 56 0.00013809999 +374 56 0.0005524999 +380 56 4.5999986e-05 +385 56 0.0031307999 +386 56 0.0054787993 +387 56 4.5999986e-05 +394 56 4.5999986e-05 +397 56 4.5999986e-05 +402 56 0.00078269979 +414 56 0.0019336999 +415 56 4.5999986e-05 +422 56 4.5999986e-05 +438 56 9.2099988e-05 +441 56 0.00036829989 +443 56 0.0048802979 +444 56 4.5999986e-05 +445 56 0.013075497 +446 56 0.0022559999 +447 56 0.00013809999 +448 56 0.00073659979 +450 56 0.0011509999 +452 56 0.00018419999 +454 56 0.00036829989 +455 56 0.034300197 +456 56 0.012522999 +457 56 0.0011970999 +458 56 0.00046039978 +460 56 0.0031768 +463 56 0.0023941 +464 56 4.5999986e-05 +467 56 0.0240792 +468 56 0.00018419999 +469 56 0.034990799 +470 56 0.0017494999 +471 56 0.0079189986 +473 56 4.5999986e-05 +478 56 0.00018419999 +483 56 0.00013809999 +490 56 0.00013809999 +491 56 9.2099988e-05 +7 57 0.000103 +16 57 0.00056669977 +18 57 0.00036059995 +24 57 0.0215353 +60 57 0.000103 +80 57 5.1499999e-05 +114 57 5.1499999e-05 +126 57 5.1499999e-05 +134 57 0.00025759987 +141 57 5.1499999e-05 +159 57 0.000103 +160 57 0.0035548999 +161 57 5.1499999e-05 +162 57 0.000103 +163 57 0.0012365 +164 57 0.00077279983 +165 57 0.0034002999 +166 57 0.0051519983 +167 57 0.0014425998 +168 57 0.013137598 +170 57 0.000103 +171 57 0.00025759987 +177 57 0.000103 +182 57 0.00056669977 +183 57 0.00030909991 +191 57 0.00025759987 +192 57 0.0001546 +198 57 5.1499999e-05 +214 57 0.000103 +215 57 0.0001546 +219 57 0.00036059995 +220 57 0.00025759987 +223 57 0.00030909991 +233 57 0.0026789999 +234 57 0.014425598 +235 57 0.024626497 +236 57 0.0011333998 +237 57 0.0017517 +241 57 0.0031941999 +242 57 5.1499999e-05 +252 57 0.00041219988 +254 57 0.0047397986 +255 57 0.00066979998 +256 57 5.1499999e-05 +257 57 0.0021122999 +258 57 0.0019061998 +259 57 0.00041219988 +264 57 0.0011333998 +265 57 0.024574999 +266 57 0.023132399 +267 57 0.0001546 +268 57 0.0002061 +269 57 0.0013909999 +271 57 0.0048428997 +273 57 0.0010303999 +274 57 0.0029365998 +277 57 0.0092735998 +279 57 0.00041219988 +282 57 0.0042245984 +285 57 5.1499999e-05 +292 57 0.00087579992 +293 57 5.1499999e-05 +294 57 5.1499999e-05 +295 57 0.0015455999 +302 57 0.00061819982 +303 57 0.00077279983 +304 57 0.0022153999 +305 57 0.0303967 +306 57 0.0026789999 +307 57 0.018341098 +308 57 0.0065944977 +309 57 0.0045852996 +310 57 0.0032972998 +311 57 0.013807297 +312 57 0.0002061 +315 57 5.1499999e-05 +317 57 0.00041219988 +319 57 0.00097889989 +322 57 0.0067490973 +324 57 0.033642497 +331 57 0.0020607999 +334 57 0.00072129979 +335 57 0.00036059995 +336 57 0.00025759987 +341 57 5.1499999e-05 +350 57 0.00025759987 +351 57 0.00030909991 +352 57 0.00051519996 +354 57 0.0002061 +356 57 0.00051519996 +358 57 5.1499999e-05 +366 57 0.0015970999 +368 57 0.0037608999 +371 57 0.0026274999 +374 57 0.000103 +380 57 0.0001546 +383 57 0.00036059995 +385 57 0.0088613965 +386 57 0.0010819 +390 57 0.0001546 +394 57 5.1499999e-05 +398 57 5.1499999e-05 +402 57 0.00046369992 +414 57 0.0016486 +415 57 0.00061819982 +438 57 0.000103 +441 57 0.00082429987 +443 57 0.0053580999 +444 57 5.1499999e-05 +445 57 0.026944898 +446 57 0.0012879998 +447 57 0.000103 +448 57 0.000103 +450 57 0.00087579992 +452 57 0.000103 +454 57 0.0002061 +455 57 0.033642497 +456 57 0.014270999 +457 57 0.00087579992 +458 57 0.00030909991 +460 57 0.0032456999 +463 57 0.0017517 +464 57 5.1499999e-05 +467 57 0.017568298 +468 57 0.0001546 +469 57 0.059659999 +470 57 0.0013394998 +471 57 0.0050488971 +473 57 5.1499999e-05 +478 57 0.000103 +483 57 0.000103 +490 57 0.000103 +491 57 0.000103 +16 58 0.00056229997 +24 58 0.017992698 +160 58 0.0061849989 +165 58 0.0022490998 +168 58 0.0044981986 +192 58 0.0014056999 +215 58 0.00028109993 +220 58 0.00028109993 +223 58 0.00028109993 +233 58 0.0016867998 +234 58 0.0132134 +235 58 0.0081528984 +237 58 0.0022490998 +241 58 0.0042169988 +254 58 0.0053415969 +258 58 0.00028109993 +262 58 0.00056229997 +265 58 0.022209696 +266 58 0.025021099 +267 58 0.00028109993 +273 58 0.00028109993 +274 58 0.0011244998 +277 58 0.024739899 +279 58 0.00028109993 +285 58 0.00028109993 +292 58 0.00028109993 +295 58 0.021366298 +305 58 0.027832396 +308 58 0.0030924999 +309 58 0.0047792979 +311 58 0.0168681 +317 58 0.00056229997 +319 58 0.00028109993 +322 58 0.0084340982 +326 58 0.0033735998 +331 58 0.0025301999 +334 58 0.0084340982 +356 58 0.0014056999 +366 58 0.0014056999 +371 58 0.022490896 +380 58 0.0014056999 +384 58 0.0008433999 +385 58 0.019117199 +386 58 0.016586997 +390 58 0.0025301999 +402 58 0.00056229997 +419 58 0.00028109993 +441 58 0.0016867998 +443 58 0.0033735998 +445 58 0.030081499 +446 58 0.0008433999 +450 58 0.0011244998 +452 58 0.00028109993 +454 58 0.00028109993 +455 58 0.027551297 +456 58 0.014900196 +457 58 0.0011244998 +458 58 0.00028109993 +460 58 0.0025301999 +463 58 0.0022490998 +467 58 0.0205229 +468 58 0.00028109993 +469 58 0.0019679999 +470 58 0.0016867998 +471 58 0.0064660981 +478 58 0.00028109993 +9 59 9.7999991e-06 +16 59 9.7999991e-06 +24 59 0.00025509996 +60 59 0.00025509996 +79 59 9.7999991e-06 +82 59 1.9599989e-05 +83 59 9.7999991e-06 +84 59 9.7999991e-06 +108 59 2.9399991e-05 +113 59 3.9199993e-05 +114 59 7.8499987e-05 +126 59 3.9199993e-05 +127 59 9.7999991e-06 +134 59 0.0015109999 +135 59 2.9399991e-05 +139 59 0.00052979984 +141 59 2.9399991e-05 +142 59 4.9099996e-05 +150 59 7.8499987e-05 +154 59 2.9399991e-05 +158 59 0.0020309999 +160 59 0.0040913969 +161 59 0.00024529989 +162 59 0.00037279981 +163 59 0.0039147995 +164 59 0.0097917989 +165 59 0.0057003982 +168 59 1.9599989e-05 +171 59 6.8699999e-05 +177 59 0.0009321 +182 59 0.0027275998 +189 59 1.9599989e-05 +191 59 0.000206 +192 59 0.00038259989 +194 59 1.9599989e-05 +195 59 0.00010789999 +196 59 9.7999991e-06 +197 59 0.006004598 +201 59 2.9399991e-05 +203 59 2.9399991e-05 +204 59 2.9399991e-05 +206 59 7.8499987e-05 +207 59 1.9599989e-05 +209 59 9.7999991e-06 +214 59 2.9399991e-05 +218 59 3.9199993e-05 +219 59 0.0039147995 +223 59 3.9199993e-05 +233 59 0.056719799 +234 59 0.0032769998 +235 59 0.00036299997 +236 59 0.026902899 +237 59 0.0011478998 +240 59 0.00089279981 +241 59 0.0093992986 +242 59 0.00027469988 +248 59 1.9599989e-05 +250 59 9.7999991e-06 +251 59 9.7999991e-06 +252 59 0.0023546999 +254 59 0.00018639999 +255 59 0.00026489981 +256 59 0.00017659999 +258 59 0.00060829986 +259 59 0.00061809993 +263 59 9.7999991e-06 +264 59 0.00056909979 +265 59 0.0024136 +266 59 0.0012361999 +267 59 2.9399991e-05 +268 59 0.0032867999 +269 59 2.9399991e-05 +271 59 0.007397797 +273 59 4.9099996e-05 +274 59 0.00066719996 +277 59 0.0010890998 +279 59 0.00055929995 +282 59 0.00042189984 +292 59 0.0017857 +293 59 0.00052979984 +295 59 0.0015993 +303 59 0.0054158978 +304 59 0.0092619993 +305 59 7.8499987e-05 +306 59 0.0022075998 +307 59 0.0010890998 +308 59 0.016561698 +309 59 7.8499987e-05 +310 59 1.9599989e-05 +311 59 5.8899997e-05 +312 59 9.7999991e-06 +317 59 0.0013343999 +318 59 5.8899997e-05 +319 59 0.00030419999 +322 59 0.00090269977 +323 59 9.7999991e-06 +331 59 0.00049059978 +334 59 0.0065441988 +335 59 0.0010399998 +336 59 0.0045916997 +341 59 0.00036299997 +350 59 0.00091249985 +352 59 0.0001962 +356 59 0.0011282999 +358 59 0.00024529989 +366 59 0.027471997 +368 59 0.00030419999 +371 59 0.0024626998 +380 59 0.0023252999 +381 59 0.00022569999 +383 59 0.019279398 +384 59 1.9599989e-05 +385 59 0.0040716976 +386 59 0.0024037999 +387 59 2.9399991e-05 +390 59 1.9599989e-05 +394 59 7.8499987e-05 +397 59 2.9399991e-05 +398 59 0.0011086999 +402 59 0.0002942998 +412 59 9.7999991e-06 +415 59 0.005219698 +419 59 9.7999991e-06 +422 59 2.9399991e-05 +423 59 9.7999991e-06 +425 59 9.7999991e-06 +430 59 2.9399991e-05 +431 59 9.7999991e-06 +432 59 9.7999991e-06 +433 59 9.7999991e-06 +434 59 9.7999991e-06 +438 59 0.0040520988 +439 59 0.0046799965 +441 59 9.7999991e-06 +443 59 0.0037479999 +444 59 9.809999e-05 +445 59 0.016954098 +446 59 0.00084379991 +447 59 0.00057889987 +448 59 6.8699999e-05 +449 59 9.7999991e-06 +450 59 0.0025509999 +452 59 0.00038259989 +453 59 4.9099996e-05 +454 59 0.0006769998 +455 59 0.0474873 +456 59 0.064951599 +457 59 0.0026980999 +458 59 8.8299988e-05 +459 59 2.9399991e-05 +460 59 0.0033064999 +463 59 0.0053962991 +464 59 0.0001275 +465 59 9.809999e-05 +467 59 0.0048369989 +468 59 0.00040229992 +469 59 0.0040324964 +470 59 0.003953997 +471 59 0.0026294999 +473 59 8.8299988e-05 +477 59 3.9199993e-05 +478 59 0.00045129983 +483 59 0.00028449995 +489 59 5.8899997e-05 +490 59 0.00030419999 +491 59 0.0001374 +9 60 2.6099995e-05 +16 60 0.0002345 +24 60 0.00038219988 +60 60 0.00059929979 +79 60 8.6999999e-06 +82 60 4.3399996e-05 +83 60 3.4699988e-05 +84 60 3.4699988e-05 +108 60 5.2099989e-05 +113 60 7.8199999e-05 +114 60 0.0001911 +126 60 7.8199999e-05 +127 60 1.7399987e-05 +134 60 0.000139 +139 60 0.00097279996 +141 60 6.9499991e-05 +142 60 0.00010419999 +150 60 0.00018239999 +154 60 6.9499991e-05 +160 60 0.0064015985 +161 60 0.0001563 +162 60 0.00022579999 +163 60 0.0030140998 +164 60 0.00022579999 +165 60 0.0102496 +167 60 6.9499991e-05 +168 60 1.7399987e-05 +171 60 0.000139 +182 60 0.00014769999 +189 60 6.0799997e-05 +191 60 0.00043429993 +192 60 0.000139 +194 60 6.0799997e-05 +195 60 8.6899992e-05 +196 60 8.6999999e-06 +197 60 0.0002345 +198 60 8.6999999e-06 +201 60 6.0799997e-05 +203 60 5.2099989e-05 +204 60 6.9499991e-05 +206 60 0.00018239999 +207 60 4.3399996e-05 +209 60 1.7399987e-05 +214 60 0.00011289999 +218 60 1.7399987e-05 +219 60 0.0030226998 +223 60 8.6899992e-05 +233 60 0.022627197 +234 60 0.012143098 +235 60 0.00085119996 +236 60 0.011274498 +237 60 0.0027621998 +240 60 0.00057329983 +241 60 0.0073831975 +242 60 0.00031269994 +248 60 4.3399996e-05 +250 60 1.7399987e-05 +251 60 8.6999999e-06 +252 60 0.0023886999 +254 60 0.00061669992 +255 60 0.00058199978 +256 60 0.00067749992 +257 60 0.015556697 +258 60 0.00016499999 +259 60 0.0020325 +263 60 8.6999999e-06 +264 60 0.0039434992 +265 60 0.0012681999 +266 60 0.0058022998 +267 60 4.3399996e-05 +268 60 0.0013897999 +269 60 6.9499991e-05 +271 60 0.00071229995 +273 60 5.2099989e-05 +274 60 0.00044299988 +275 60 0.015930198 +277 60 0.0024667999 +279 60 0.00098149991 +282 60 0.00096419989 +292 60 0.00058199978 +293 60 0.00057329983 +295 60 0.0023104998 +302 60 0.0010162999 +303 60 0.0043516979 +304 60 0.010049798 +305 60 0.0004168998 +306 60 0.0023712998 +307 60 0.0021019999 +308 60 0.0074525997 +311 60 0.0004776998 +312 60 0.00044299988 +317 60 0.0031529998 +318 60 0.00013029999 +319 60 0.0016416998 +322 60 0.00087729981 +323 60 1.7399987e-05 +324 60 0.0015721999 +331 60 0.0011812998 +334 60 0.0042213984 +335 60 0.00067749992 +336 60 0.0029618999 +341 60 0.00026059989 +350 60 0.00030399999 +352 60 0.00028659985 +356 60 0.00071229995 +358 60 0.0003560998 +363 60 8.6999999e-06 +366 60 0.0284121 +368 60 0.00018239999 +371 60 0.0062191971 +374 60 6.0799997e-05 +380 60 0.00013029999 +381 60 8.6999999e-06 +383 60 0.0001563 +384 60 3.4699988e-05 +385 60 0.013854299 +386 60 0.018040899 +387 60 7.8199999e-05 +390 60 0.0019456998 +394 60 0.00019979999 +397 60 2.6099995e-05 +398 60 8.6999999e-06 +402 60 0.00071229995 +412 60 1.7399987e-05 +415 60 0.0042474978 +419 60 2.6099995e-05 +422 60 7.8199999e-05 +423 60 2.6099995e-05 +425 60 1.7399987e-05 +430 60 5.2099989e-05 +431 60 1.7399987e-05 +432 60 1.7399987e-05 +433 60 2.6099995e-05 +434 60 3.4699988e-05 +438 60 0.0014852998 +439 60 0.0001737 +441 60 1.7399987e-05 +443 60 0.004516799 +444 60 0.00025189994 +445 60 0.017789099 +446 60 0.0014070999 +447 60 0.0010162999 +448 60 0.00019979999 +449 60 1.7399987e-05 +450 60 0.0060888976 +452 60 0.00090339989 +453 60 0.00011289999 +454 60 0.0016156 +455 60 0.038305499 +456 60 0.036133997 +457 60 0.0064015985 +458 60 7.8199999e-05 +459 60 4.3399996e-05 +460 60 0.005072698 +463 60 0.012881398 +464 60 0.00032139989 +465 60 0.00021719999 +467 60 0.0067577995 +468 60 0.00095549994 +469 60 0.0096327998 +470 60 0.0094330981 +471 60 0.0056111999 +473 60 0.00019979999 +477 60 7.8199999e-05 +478 60 0.0010684 +483 60 0.00066009979 +489 60 0.00013029999 +490 60 0.00071229995 +491 60 0.00027799979 +24 61 0.00032479991 +60 61 0.00064959982 +108 61 0.00032479991 +114 61 0.00064959982 +126 61 0.00032479991 +134 61 0.00032479991 +139 61 0.0012991 +150 61 0.00032479991 +160 61 0.0045468993 +161 61 0.00032479991 +162 61 0.00064959982 +163 61 0.0045468993 +164 61 0.00032479991 +165 61 0.010392997 +182 61 0.0032477998 +191 61 0.00032479991 +192 61 0.00064959982 +197 61 0.0077946968 +206 61 0.00064959982 +219 61 0.0051964968 +233 61 0.069503069 +234 61 0.0074699968 +235 61 0.00032479991 +236 61 0.031828497 +237 61 0.0025982 +240 61 0.00064959982 +241 61 0.015264697 +242 61 0.00032479991 +252 61 0.0025982 +254 61 0.00032479991 +255 61 0.00032479991 +258 61 0.00032479991 +259 61 0.00064959982 +264 61 0.00064959982 +265 61 0.0029229999 +266 61 0.0016238999 +268 61 0.0035726 +271 61 0.0087690987 +273 61 0.00032479991 +274 61 0.00097429985 +277 61 0.0012991 +279 61 0.00097429985 +282 61 0.00064959982 +292 61 0.0022735 +293 61 0.00064959982 +295 61 0.0016238999 +303 61 0.0061707981 +304 61 0.011692099 +306 61 0.0025982 +307 61 0.0025982 +308 61 0.023059398 +317 61 0.0025982 +319 61 0.00032479991 +322 61 0.0016238999 +324 61 0.025332898 +331 61 0.00097429985 +334 61 0.0084442981 +335 61 0.0012991 +336 61 0.0058460981 +341 61 0.00064959982 +350 61 0.0012991 +356 61 0.0016238999 +366 61 0.011692099 +368 61 0.00032479991 +371 61 0.0032477998 +380 61 0.0025982 +381 61 0.00032479991 +383 61 0.022409897 +385 61 0.0058460981 +386 61 0.0032477998 +387 61 0.00032479991 +394 61 0.00032479991 +398 61 0.0012991 +402 61 0.00064959982 +415 61 0.0058460981 +438 61 0.0048717 +439 61 0.0051964968 +443 61 0.0019486998 +445 61 0.019811597 +446 61 0.00097429985 +447 61 0.00064959982 +450 61 0.0058460981 +452 61 0.00097429985 +454 61 0.0012991 +455 61 0.051964898 +456 61 0.070477366 +457 61 0.0058460981 +460 61 0.0055212975 +463 61 0.012341697 +464 61 0.00032479991 +467 61 0.011367299 +468 61 0.00097429985 +469 61 0.0087690987 +470 61 0.0090938993 +471 61 0.0058460981 +473 61 0.00032479991 +478 61 0.00064959982 +483 61 0.00064959982 +490 61 0.00097429985 +491 61 0.00032479991 +18 62 0.0013247 +24 62 0.029640697 +60 62 0.00016559999 +114 62 0.00016559999 +126 62 0.00016559999 +134 62 0.007948298 +139 62 0.00049679982 +160 62 0.033945996 +162 62 0.0009935 +163 62 0.0026493999 +165 62 0.015896697 +166 62 0.0011590999 +168 62 0.0155655 +170 62 0.00033119996 +171 62 0.0009935 +191 62 0.0021527 +192 62 0.00049679982 +206 62 0.00016559999 +219 62 0.00049679982 +233 62 0.055141598 +234 62 0.0099353977 +235 62 0.022685897 +236 62 0.010432199 +237 62 0.0009935 +241 62 0.012088098 +254 62 0.0041397996 +255 62 0.00016559999 +262 62 0.0019870999 +264 62 0.010266598 +265 62 0.055638399 +266 62 0.030468598 +268 62 0.0039741993 +271 62 0.0009935 +273 62 0.00033119996 +274 62 0.00049679982 +277 62 0.026825599 +279 62 0.010763399 +292 62 0.0024838999 +295 62 0.010929 +305 62 0.0061267987 +306 62 0.0018214998 +307 62 0.0038085999 +308 62 0.058287799 +311 62 0.0019870999 +317 62 0.00066239992 +319 62 0.0026493999 +322 62 0.035105098 +324 62 0.0157311 +331 62 0.005464498 +350 62 0.0011590999 +371 62 0.0016558999 +385 62 0.005464498 +386 62 0.0029805999 +398 62 0.0013247 +402 62 0.00016559999 +438 62 0.0038085999 +441 62 0.00049679982 +443 62 0.0110946 +445 62 0.025997698 +446 62 0.0009935 +447 62 0.00033119996 +450 62 0.0016558999 +452 62 0.00033119996 +454 62 0.00033119996 +455 62 0.057956599 +456 62 0.070707083 +457 62 0.0016558999 +458 62 0.00016559999 +460 62 0.0076171979 +463 62 0.0034773999 +467 62 0.0064579993 +468 62 0.00033119996 +469 62 0.0026493999 +470 62 0.0024838999 +471 62 0.0019870999 +473 62 0.00016559999 +478 62 0.00016559999 +483 62 0.00016559999 +490 62 0.00033119996 +16 63 0.00010599999 +60 63 0.00031799986 +108 63 0.00010599999 +114 63 0.00010599999 +126 63 0.00010599999 +139 63 0.00052989996 +142 63 0.00010599999 +150 63 0.00010599999 +160 63 0.00074189994 +162 63 0.00010599999 +163 63 0.00052989996 +165 63 0.042713299 +168 63 0.00095389993 +171 63 0.00010599999 +191 63 0.00010599999 +194 63 0.00010599999 +206 63 0.00031799986 +219 63 0.00063589984 +223 63 0.00010599999 +233 63 0.0047694966 +234 63 0.0076311976 +235 63 0.0057233982 +236 63 0.0014837999 +237 63 0.0018018 +241 63 0.0044514984 +242 63 0.00010599999 +252 63 0.00042399997 +254 63 0.0023316999 +255 63 0.00010599999 +256 63 0.00010599999 +259 63 0.000212 +262 63 0.0010598998 +264 63 0.00042399997 +265 63 0.00031799986 +266 63 0.0026496998 +268 63 0.00031799986 +271 63 0.00010599999 +273 63 0.000212 +277 63 0.00031799986 +279 63 0.000212 +292 63 0.00010599999 +295 63 0.0051933974 +302 63 0.000212 +303 63 0.00063589984 +304 63 0.0014837999 +305 63 0.00042399997 +306 63 0.00042399997 +307 63 0.0026496998 +308 63 0.0041334964 +309 63 0.00095389993 +310 63 0.000212 +311 63 0.000212 +312 63 0.00074189994 +317 63 0.0020138 +318 63 0.00010599999 +319 63 0.000212 +322 63 0.0012718998 +324 63 0.000212 +331 63 0.00074189994 +334 63 0.00063589984 +335 63 0.00010599999 +336 63 0.00031799986 +356 63 0.00010599999 +358 63 0.00010599999 +366 63 0.0108108 +371 63 0.00084789982 +385 63 0.019607797 +386 63 0.066772699 +387 63 0.00010599999 +390 63 0.000212 +394 63 0.00010599999 +402 63 0.00052989996 +415 63 0.0010598998 +422 63 0.00010599999 +430 63 0.00010599999 +438 63 0.00031799986 +441 63 0.000212 +443 63 0.0027556999 +444 63 0.000212 +445 63 0.0083730966 +446 63 0.00063589984 +447 63 0.00063589984 +448 63 0.00010599999 +450 63 0.0036036 +452 63 0.00052989996 +453 63 0.00010599999 +454 63 0.00095389993 +455 63 0.025649197 +456 63 0.029994696 +457 63 0.0037095998 +458 63 0.00052989996 +460 63 0.0025436999 +463 63 0.0075251982 +464 63 0.00031799986 +467 63 0.018865898 +468 63 0.00052989996 +469 63 0.0055113994 +470 63 0.0055113994 +471 63 0.0052993968 +473 63 0.00010599999 +478 63 0.00063589984 +483 63 0.00042399997 +490 63 0.00052989996 +491 63 0.000212 +9 64 5.1999989e-05 +24 64 0.010512598 +60 64 0.00031229993 +80 64 0.00010409999 +82 64 5.1999989e-05 +83 64 5.1999989e-05 +84 64 5.1999989e-05 +108 64 5.1999989e-05 +113 64 0.00010409999 +114 64 0.00010409999 +126 64 5.1999989e-05 +139 64 0.00046839984 +141 64 5.1999989e-05 +142 64 5.1999989e-05 +150 64 0.00010409999 +154 64 5.1999989e-05 +159 64 0.014675997 +160 64 0.010720797 +163 64 0.0002082 +165 64 0.0050480999 +168 64 0.032890998 +171 64 0.00010409999 +189 64 5.1999989e-05 +191 64 5.1999989e-05 +194 64 5.1999989e-05 +203 64 5.1999989e-05 +204 64 0.00010409999 +206 64 5.1999989e-05 +207 64 5.1999989e-05 +219 64 0.0001561 +220 64 0.00026019989 +223 64 5.1999989e-05 +233 64 0.0060889982 +234 64 0.0062971972 +235 64 0.00078059989 +236 64 0.0006765998 +237 64 0.0014052 +241 64 0.0036429998 +242 64 0.00010409999 +252 64 0.0002082 +254 64 0.0013530999 +255 64 5.1999989e-05 +256 64 5.1999989e-05 +259 64 0.00010409999 +264 64 0.0002082 +265 64 0.0001561 +266 64 0.00052039977 +268 64 0.00010409999 +271 64 0.0002082 +273 64 0.00026019989 +274 64 5.1999989e-05 +277 64 0.024407998 +279 64 0.00026019989 +292 64 5.1999989e-05 +293 64 5.1999989e-05 +295 64 0.0013010998 +302 64 0.00010409999 +303 64 0.0002082 +304 64 0.00046839984 +305 64 0.0083788969 +306 64 0.00010409999 +307 64 0.0023939998 +308 64 0.0034347998 +312 64 0.0039551966 +317 64 0.0016132998 +318 64 5.1999989e-05 +319 64 0.00010409999 +322 64 0.0006765998 +324 64 0.0006765998 +326 64 0.0247203 +331 64 0.00062449998 +334 64 0.00026019989 +335 64 5.1999989e-05 +336 64 0.00010409999 +356 64 5.1999989e-05 +358 64 5.1999989e-05 +366 64 0.0041633993 +371 64 0.00036429986 +374 64 0.0029663998 +385 64 0.0029143998 +386 64 0.0047358982 +387 64 5.1999989e-05 +390 64 0.016185299 +394 64 0.00010409999 +402 64 0.00036429986 +415 64 0.00036429986 +422 64 5.1999989e-05 +423 64 5.1999989e-05 +430 64 5.1999989e-05 +431 64 5.1999989e-05 +434 64 5.1999989e-05 +438 64 0.00041629979 +443 64 0.0057766996 +444 64 0.0001561 +445 64 0.014311697 +446 64 0.0037470998 +447 64 0.00062449998 +448 64 0.00010409999 +450 64 0.0031225998 +452 64 0.00046839984 +453 64 5.1999989e-05 +454 64 0.00083269994 +455 64 0.048191499 +456 64 0.0091074966 +457 64 0.0032786999 +458 64 0.00041629979 +460 64 0.0023418998 +463 64 0.0066093989 +464 64 0.0001561 +465 64 0.00010409999 +467 64 0.015872996 +468 64 0.00046839984 +469 64 0.0051001981 +470 64 0.0048399977 +471 64 0.0045276992 +473 64 0.00010409999 +478 64 0.00052039977 +483 64 0.00031229993 +489 64 5.1999989e-05 +490 64 0.00041629979 +491 64 0.00026019989 +60 65 7.2199997e-05 +114 65 7.2199997e-05 +139 65 0.00014439999 +160 65 0.00043329992 +163 65 0.00021669999 +165 65 0.0024553998 +191 65 7.2199997e-05 +195 65 0.00014439999 +206 65 7.2199997e-05 +217 65 0.00064999983 +219 65 0.00072219991 +233 65 0.0086660981 +234 65 0.0022387998 +235 65 0.0010833 +236 65 0.0007944 +237 65 0.00043329992 +241 65 0.00086659985 +252 65 0.00021669999 +254 65 0.0012276999 +255 65 7.2199997e-05 +257 65 0.0025997998 +259 65 0.00014439999 +262 65 0.0011554998 +264 65 0.00028889999 +265 65 0.0017331999 +266 65 0.00072219991 +268 65 0.00014439999 +271 65 0.0011554998 +272 65 0.00021669999 +273 65 0.00021669999 +274 65 0.00064999983 +275 65 0.052574597 +277 65 0.0064995997 +279 65 7.2199997e-05 +292 65 7.2199997e-05 +293 65 7.2199997e-05 +295 65 0.015093498 +302 65 7.2199997e-05 +303 65 0.00028889999 +304 65 0.0044052973 +305 65 0.0064273998 +306 65 0.0010833 +307 65 0.0096771978 +308 65 0.0024553998 +309 65 0.00028889999 +310 65 7.2199997e-05 +311 65 0.00014439999 +312 65 0.005127497 +317 65 0.00028889999 +319 65 0.00014439999 +322 65 0.00093879993 +324 65 0.021087598 +331 65 0.0044774972 +334 65 0.00028889999 +335 65 7.2199997e-05 +336 65 0.00014439999 +356 65 7.2199997e-05 +358 65 7.2199997e-05 +366 65 0.0052718967 +371 65 0.0023832 +374 65 0.007655099 +385 65 0.0037552998 +386 65 0.031198099 +390 65 0.00014439999 +402 65 7.2199997e-05 +414 65 0.0036831 +415 65 0.00050549977 +438 65 0.00036109984 +443 65 0.0038274999 +445 65 0.0032497998 +446 65 7.2199997e-05 +447 65 7.2199997e-05 +450 65 0.00064999983 +452 65 7.2199997e-05 +454 65 0.00014439999 +455 65 0.021376498 +456 65 0.011771496 +457 65 0.00064999983 +458 65 0.00043329992 +460 65 0.00036109984 +463 65 0.0013720999 +464 65 7.2199997e-05 +467 65 0.016393397 +468 65 7.2199997e-05 +469 65 0.0010109998 +470 65 0.0010109998 +471 65 0.0028164999 +478 65 7.2199997e-05 +483 65 7.2199997e-05 +490 65 0.00014439999 +18 66 0.00024149999 +24 66 0.014734298 +60 66 0.00024149999 +114 66 0.00024149999 +126 66 0.00024149999 +134 66 0.0024154999 +139 66 0.00048309984 +160 66 0.00072459993 +163 66 0.00024149999 +165 66 0.0050724968 +168 66 0.00024149999 +206 66 0.00024149999 +214 66 0.00096619991 +219 66 0.00072459993 +223 66 0.00048309984 +233 66 0.0084540993 +234 66 0.012077298 +235 66 0.025603898 +236 66 0.0016907998 +237 66 0.0014493 +240 66 0.00072459993 +241 66 0.0043477975 +242 66 0.00024149999 +252 66 0.00024149999 +254 66 0.00072459993 +255 66 0.00024149999 +259 66 0.00024149999 +264 66 0.00024149999 +266 66 0.015942 +268 66 0.00024149999 +269 66 0.00096619991 +273 66 0.00048309984 +274 66 0.00024149999 +277 66 0.12294686 +282 66 0.0014493 +295 66 0.00024149999 +303 66 0.00048309984 +304 66 0.00072459993 +305 66 0.0048308969 +306 66 0.00024149999 +307 66 0.0031400998 +308 66 0.0036231999 +311 66 0.0014493 +317 66 0.0014493 +322 66 0.0028986 +324 66 0.029951699 +331 66 0.00096619991 +334 66 0.00024149999 +336 66 0.00024149999 +366 66 0.0050724968 +371 66 0.00072459993 +374 66 0.0014493 +385 66 0.0016907998 +386 66 0.0014493 +390 66 0.00024149999 +402 66 0.00024149999 +414 66 0.0014493 +415 66 0.00048309984 +438 66 0.00072459993 +441 66 0.00048309984 +443 66 0.0041062981 +445 66 0.0135266 +446 66 0.00096619991 +447 66 0.00048309984 +450 66 0.0028986 +452 66 0.00048309984 +454 66 0.00072459993 +455 66 0.022946898 +456 66 0.0099033974 +457 66 0.0028986 +458 66 0.00048309984 +460 66 0.0016907998 +463 66 0.0060385987 +464 66 0.00024149999 +467 66 0.018599 +468 66 0.00048309984 +469 66 0.0045893975 +470 66 0.0045893975 +471 66 0.0048308969 +473 66 0.00024149999 +478 66 0.00048309984 +483 66 0.00024149999 +490 66 0.00048309984 +491 66 0.00024149999 +18 67 0.001003 +24 67 0.0090270974 +165 67 0.0040119998 +166 67 0.0030089999 +214 67 0.001003 +220 67 0.001003 +233 67 0.011033099 +234 67 0.041123398 +235 67 0.005014997 +237 67 0.001003 +241 67 0.0030089999 +266 67 0.0040119998 +271 67 0.001003 +273 67 0.001003 +274 67 0.001003 +277 67 0.15346038 +295 67 0.010030098 +305 67 0.023069199 +307 67 0.0080240965 +308 67 0.0020059999 +317 67 0.001003 +322 67 0.0040119998 +324 67 0.076228678 +331 67 0.0040119998 +366 67 0.001003 +371 67 0.014042098 +374 67 0.0030089999 +385 67 0.0020059999 +386 67 0.0040119998 +414 67 0.0070210993 +438 67 0.001003 +443 67 0.0030089999 +445 67 0.010030098 +450 67 0.0020059999 +455 67 0.033099297 +456 67 0.018054198 +457 67 0.0020059999 +460 67 0.0030089999 +463 67 0.0040119998 +467 67 0.018054198 +469 67 0.0030089999 +470 67 0.0030089999 +471 67 0.005014997 +490 67 0.001003 +7 68 0.00013489999 +16 68 0.00040459982 +18 68 0.0016857998 +24 68 0.020633899 +60 68 0.00026969984 +82 68 6.7399989e-05 +108 68 6.7399989e-05 +114 68 6.7399989e-05 +126 68 6.7399989e-05 +139 68 0.00040459982 +142 68 6.7399989e-05 +150 68 6.7399989e-05 +154 68 6.7399989e-05 +160 68 0.00033719977 +163 68 0.00013489999 +165 68 0.0046526976 +168 68 0.00013489999 +171 68 6.7399989e-05 +191 68 6.7399989e-05 +192 68 6.7399989e-05 +194 68 6.7399989e-05 +203 68 6.7399989e-05 +204 68 6.7399989e-05 +206 68 0.0002023 +219 68 0.00053939992 +223 68 6.7399989e-05 +233 68 0.036817297 +234 68 0.0087659992 +235 68 0.0225893 +236 68 0.00053939992 +237 68 0.0014159998 +241 68 0.011867799 +242 68 6.7399989e-05 +252 68 0.00013489999 +254 68 0.012002699 +259 68 0.00013489999 +264 68 0.0002023 +265 68 0.0095077977 +266 68 0.0093728974 +268 68 6.7399989e-05 +269 68 0.00053939992 +271 68 0.0030343998 +273 68 0.00033719977 +274 68 0.0015508998 +277 68 0.0036412999 +279 68 6.7399989e-05 +282 68 0.0071476996 +292 68 0.00013489999 +295 68 6.7399989e-05 +302 68 6.7399989e-05 +303 68 0.00013489999 +304 68 0.00040459982 +305 68 0.0048549995 +306 68 0.00013489999 +307 68 0.0022251999 +308 68 0.0043829978 +311 68 0.00013489999 +317 68 0.0014834998 +318 68 6.7399989e-05 +319 68 6.7399989e-05 +322 68 0.0016182999 +324 68 0.040391099 +331 68 0.00053939992 +334 68 0.0002023 +336 68 0.00013489999 +350 68 6.7399989e-05 +358 68 6.7399989e-05 +366 68 0.0033714999 +371 68 0.0020228999 +374 68 0.0052595995 +385 68 0.0010114999 +386 68 0.00087659992 +387 68 6.7399989e-05 +390 68 6.7399989e-05 +394 68 6.7399989e-05 +402 68 0.00040459982 +414 68 0.0025624 +415 68 0.00033719977 +430 68 6.7399989e-05 +438 68 0.0026297998 +441 68 0.00047199987 +443 68 0.0036412999 +444 68 0.0002023 +445 68 0.017464597 +446 68 0.0010788999 +447 68 0.00053939992 +448 68 6.7399989e-05 +450 68 0.0027647 +452 68 0.00040459982 +453 68 6.7399989e-05 +454 68 0.00074169994 +455 68 0.0277141 +456 68 0.030815899 +457 68 0.0028994998 +458 68 0.00040459982 +460 68 0.0017531998 +463 68 0.0057990998 +464 68 0.0002023 +465 68 6.7399989e-05 +467 68 0.015643999 +468 68 0.00040459982 +469 68 0.0051246993 +470 68 0.0042480975 +471 68 0.0041806996 +473 68 0.00013489999 +478 68 0.00047199987 +483 68 0.00026969984 +489 68 6.7399989e-05 +490 68 0.00040459982 +491 68 0.0002023 +16 69 0.0001604 +18 69 0.00048129982 +24 69 0.013637099 +60 69 0.00080219982 +82 69 0.0001604 +108 69 0.0001604 +114 69 0.0001604 +126 69 0.0001604 +134 69 0.0016043999 +139 69 0.0011230998 +141 69 0.0001604 +142 69 0.0001604 +150 69 0.0001604 +154 69 0.0001604 +160 69 0.0016043999 +162 69 0.0001604 +163 69 0.0011230998 +165 69 0.012513999 +171 69 0.0001604 +191 69 0.0001604 +194 69 0.0001604 +203 69 0.0001604 +206 69 0.0001604 +207 69 0.0001604 +219 69 0.00096259988 +220 69 0.0001604 +223 69 0.0001604 +233 69 0.014278799 +234 69 0.017166696 +235 69 0.0097865984 +236 69 0.0022461 +237 69 0.0035295999 +240 69 0.0011230998 +241 69 0.0091448985 +242 69 0.00048129982 +252 69 0.00064169988 +254 69 0.021177597 +255 69 0.0054547973 +256 69 0.0001604 +258 69 0.0028879 +259 69 0.0003209 +264 69 0.0038504999 +265 69 0.0145997 +266 69 0.012995299 +267 69 0.0001604 +268 69 0.00048129982 +269 69 0.0003209 +271 69 0.0016043999 +273 69 0.00048129982 +274 69 0.00064169988 +277 69 0.0036899999 +279 69 0.0003209 +282 69 0.004171297 +292 69 0.0001604 +293 69 0.0001604 +295 69 0.00048129982 +302 69 0.0003209 +303 69 0.00096259988 +304 69 0.0022461 +305 69 0.0027273998 +306 69 0.00080219982 +307 69 0.0044921972 +308 69 0.008503098 +311 69 0.008021798 +312 69 0.0001604 +317 69 0.0040108971 +318 69 0.0001604 +319 69 0.0003209 +322 69 0.013155799 +324 69 0.011230499 +331 69 0.0014438999 +334 69 0.00096259988 +335 69 0.0001604 +336 69 0.00048129982 +356 69 0.0001604 +358 69 0.0001604 +366 69 0.016204096 +371 69 0.00064169988 +374 69 0.0014438999 +385 69 0.0032086999 +386 69 0.0038504999 +387 69 0.0001604 +390 69 0.0003209 +394 69 0.0003209 +402 69 0.0011230998 +415 69 0.0016043999 +422 69 0.0001604 +430 69 0.0001604 +434 69 0.0001604 +438 69 0.00096259988 +441 69 0.0003209 +443 69 0.0046526976 +444 69 0.00048129982 +445 69 0.023102798 +446 69 0.0017647999 +447 69 0.0012834999 +448 69 0.0001604 +450 69 0.0073800981 +452 69 0.0011230998 +453 69 0.0001604 +454 69 0.0019252 +455 69 0.029038999 +456 69 0.022300698 +457 69 0.0077008978 +458 69 0.00064169988 +460 69 0.0062569976 +463 69 0.0155623 +464 69 0.00064169988 +465 69 0.0001604 +467 69 0.027755499 +468 69 0.0011230998 +469 69 0.012032699 +470 69 0.011390999 +471 69 0.0093052983 +473 69 0.0003209 +478 69 0.0012834999 +483 69 0.00080219982 +489 69 0.0001604 +490 69 0.00096259988 +491 69 0.00048129982 +24 70 0.0033783999 +60 70 0.00067569991 +114 70 0.00067569991 +126 70 0.00067569991 +139 70 0.0013513998 +159 70 0.0013513998 +160 70 0.0027027 +165 70 0.0094594993 +168 70 0.0027027 +206 70 0.00067569991 +233 70 0.019594599 +234 70 0.012162197 +235 70 0.00067569991 +236 70 0.0020269998 +237 70 0.0040540993 +241 70 0.0087837987 +254 70 0.0013513998 +264 70 0.00067569991 +266 70 0.0013513998 +277 70 0.0027027 +295 70 0.0060810968 +303 70 0.0013513998 +304 70 0.00067569991 +305 70 0.0020269998 +307 70 0.0020269998 +308 70 0.0081080981 +312 70 0.0047296993 +317 70 0.0033783999 +324 70 0.00067569991 +326 70 0.0027027 +331 70 0.0013513998 +334 70 0.00067569991 +366 70 0.0087837987 +371 70 0.00067569991 +374 70 0.00067569991 +385 70 0.0067567974 +386 70 0.0108108 +390 70 0.017567597 +402 70 0.00067569991 +415 70 0.00067569991 +438 70 0.0013513998 +443 70 0.00067569991 +445 70 0.013513498 +446 70 0.00067569991 +447 70 0.00067569991 +450 70 0.0074323975 +452 70 0.0013513998 +454 70 0.0020269998 +455 70 0.0162162 +456 70 0.014189199 +457 70 0.0074323975 +460 70 0.0047296993 +463 70 0.014864899 +467 70 0.0074323975 +468 70 0.0013513998 +469 70 0.011486497 +470 70 0.011486497 +471 70 0.0060810968 +473 70 0.00067569991 +478 70 0.00067569991 +483 70 0.00067569991 +490 70 0.0013513998 +491 70 0.00067569991 +16 71 0.0001258 +18 71 0.0001258 +24 71 0.018867899 +60 71 0.00037739985 +108 71 0.0001258 +114 71 0.0001258 +126 71 0.0001258 +134 71 0.00025159982 +139 71 0.00062889978 +142 71 0.0001258 +150 71 0.0001258 +160 71 0.0056603998 +161 71 0.0001258 +162 71 0.00025159982 +163 71 0.0020126 +164 71 0.0001258 +165 71 0.0085534975 +168 71 0.0001258 +171 71 0.0001258 +182 71 0.0001258 +191 71 0.00025159982 +192 71 0.0001258 +194 71 0.0001258 +195 71 0.0001258 +197 71 0.0001258 +206 71 0.00025159982 +219 71 0.0023898999 +223 71 0.0001258 +233 71 0.021006297 +234 71 0.018490598 +235 71 0.011949699 +236 71 0.0075471997 +237 71 0.0020126 +240 71 0.00025159982 +241 71 0.0057861991 +242 71 0.00025159982 +252 71 0.0017609999 +254 71 0.0016351999 +255 71 0.00050309999 +256 71 0.00050309999 +257 71 0.0001258 +258 71 0.0001258 +259 71 0.0013835998 +264 71 0.0027672998 +265 71 0.0020126 +266 71 0.0094339997 +268 71 0.00088049984 +269 71 0.0001258 +271 71 0.00075469981 +273 71 0.00025159982 +274 71 0.00037739985 +277 71 0.0023898999 +279 71 0.00075469981 +282 71 0.0010062999 +292 71 0.00037739985 +293 71 0.00037739985 +295 71 0.0022641998 +302 71 0.00075469981 +303 71 0.0027672998 +304 71 0.007169798 +305 71 0.0050313994 +306 71 0.0017609999 +307 71 0.0022641998 +308 71 0.0069181994 +309 71 0.00088049984 +310 71 0.0001258 +311 71 0.0010062999 +312 71 0.00050309999 +317 71 0.0021384 +318 71 0.0001258 +319 71 0.0010062999 +322 71 0.0022641998 +324 71 0.0038993999 +331 71 0.0010062999 +334 71 0.0027672998 +335 71 0.00050309999 +336 71 0.0018867999 +341 71 0.00025159982 +350 71 0.00025159982 +352 71 0.0001258 +356 71 0.00050309999 +358 71 0.00062889978 +366 71 0.053459097 +368 71 0.0001258 +371 71 0.004528299 +374 71 0.00062889978 +380 71 0.0001258 +385 71 0.0099370964 +386 71 0.013584897 +387 71 0.0001258 +390 71 0.0012578999 +394 71 0.0001258 +402 71 0.00050309999 +414 71 0.00025159982 +415 71 0.0054087974 +422 71 0.0001258 +430 71 0.0001258 +438 71 0.0012578999 +439 71 0.0001258 +441 71 0.00050309999 +443 71 0.0038993999 +444 71 0.00025159982 +445 71 0.017987397 +446 71 0.0011320999 +447 71 0.00062889978 +448 71 0.0001258 +450 71 0.0040251985 +452 71 0.00062889978 +453 71 0.0001258 +454 71 0.0011320999 +455 71 0.030440297 +456 71 0.0261635 +457 71 0.0041508973 +458 71 0.00025159982 +460 71 0.0032704 +463 71 0.0084276982 +464 71 0.00025159982 +467 71 0.010817599 +468 71 0.00062889978 +469 71 0.0065408982 +470 71 0.0062892996 +471 71 0.004528299 +473 71 0.0001258 +478 71 0.00062889978 +483 71 0.00037739985 +490 71 0.00050309999 +491 71 0.00025159982 +16 72 0.000166 +18 72 0.000166 +24 72 0.0041500963 +60 72 0.00033199997 +80 72 0.00049799983 +108 72 0.000166 +114 72 0.00033199997 +126 72 0.000166 +139 72 0.00049799983 +141 72 0.00049799983 +150 72 0.000166 +160 72 0.0016599998 +162 72 0.000166 +163 72 0.0008299998 +165 72 0.005478099 +182 72 0.000166 +191 72 0.000166 +206 72 0.00033199997 +217 72 0.000166 +219 72 0.0009959999 +220 72 0.0024899999 +233 72 0.012782197 +234 72 0.032868497 +235 72 0.0018259999 +236 72 0.0023239998 +237 72 0.0013279999 +240 72 0.0019919998 +241 72 0.0041500963 +242 72 0.00049799983 +252 72 0.00066399993 +255 72 0.000166 +256 72 0.000166 +257 72 0.00033199997 +259 72 0.00033199997 +262 72 0.000166 +264 72 0.00066399993 +265 72 0.00049799983 +266 72 0.0023239998 +268 72 0.0009959999 +271 72 0.00049799983 +273 72 0.000166 +274 72 0.000166 +275 72 0.000166 +277 72 0.0018259999 +279 72 0.00033199997 +292 72 0.000166 +293 72 0.000166 +295 72 0.0049800985 +302 72 0.00033199997 +303 72 0.0009959999 +304 72 0.002656 +305 72 0.0029879999 +306 72 0.0008299998 +307 72 0.0048140995 +308 72 0.0044820979 +311 72 0.0011619998 +312 72 0.0016599998 +317 72 0.0013279999 +319 72 0.00033199997 +322 72 0.0046480969 +324 72 0.007802099 +331 72 0.001494 +333 72 0.00066399993 +334 72 0.0009959999 +335 72 0.000166 +336 72 0.00049799983 +356 72 0.00066399993 +358 72 0.000166 +366 72 0.016932297 +371 72 0.001494 +374 72 0.0009959999 +385 72 0.0034860999 +386 72 0.013280198 +387 72 0.000166 +390 72 0.00049799983 +394 72 0.000166 +402 72 0.00033199997 +414 72 0.00033199997 +415 72 0.0016599998 +438 72 0.0008299998 +443 72 0.0013279999 +445 72 0.0091300979 +446 72 0.0009959999 +447 72 0.00033199997 +448 72 0.000166 +450 72 0.0028219998 +452 72 0.00049799983 +454 72 0.00066399993 +455 72 0.020916298 +456 72 0.014608197 +457 72 0.0029879999 +458 72 0.00049799983 +460 72 0.0021579999 +463 72 0.0061420985 +464 72 0.000166 +467 72 0.018094297 +468 72 0.00049799983 +469 72 0.0044820979 +470 72 0.0044820979 +471 72 0.0048140995 +473 72 0.000166 +478 72 0.00033199997 +483 72 0.00033199997 +490 72 0.00049799983 +491 72 0.000166 +9 73 2.3899993e-05 +16 73 2.3899993e-05 +24 73 0.061835498 +60 73 0.00033449987 +79 73 2.3899993e-05 +80 73 4.7799986e-05 +82 73 2.3899993e-05 +83 73 2.3899993e-05 +84 73 2.3899993e-05 +108 73 2.3899993e-05 +113 73 7.1699993e-05 +114 73 0.00011949999 +126 73 7.1699993e-05 +127 73 2.3899993e-05 +134 73 0.00038229977 +139 73 0.00054949988 +141 73 4.7799986e-05 +142 73 7.1699993e-05 +150 73 9.5599986e-05 +154 73 4.7799986e-05 +160 73 0.0054714978 +165 73 0.0093660988 +168 73 0.00062119984 +171 73 7.1699993e-05 +189 73 2.3899993e-05 +192 73 2.3899993e-05 +194 73 4.7799986e-05 +197 73 2.3899993e-05 +201 73 4.7799986e-05 +203 73 4.7799986e-05 +204 73 4.7799986e-05 +206 73 9.5599986e-05 +207 73 2.3899993e-05 +209 73 2.3899993e-05 +219 73 0.00066899997 +220 73 0.00014339999 +223 73 4.7799986e-05 +233 73 0.0071440972 +234 73 0.037679497 +235 73 0.035696398 +237 73 0.0016007998 +241 73 0.0055909976 +242 73 0.00011949999 +248 73 2.3899993e-05 +250 73 2.3899993e-05 +252 73 2.3899993e-05 +254 73 0.0018875999 +258 73 9.5599986e-05 +265 73 0.0027476999 +266 73 0.017872099 +271 73 2.3899993e-05 +273 73 0.00052559981 +277 73 0.00074069994 +305 73 0.014718197 +307 73 0.0021025999 +308 73 0.010680199 +309 73 0.0018636999 +310 73 0.00050179986 +311 73 0.0022459999 +317 73 0.0017919999 +318 73 4.7799986e-05 +322 73 0.0033210998 +324 73 0.00023889999 +331 73 0.00066899997 +384 73 2.3899993e-05 +385 73 0.00083629997 +387 73 4.7799986e-05 +394 73 0.00011949999 +397 73 2.3899993e-05 +402 73 0.00040619983 +412 73 2.3899993e-05 +419 73 2.3899993e-05 +422 73 7.1699993e-05 +423 73 2.3899993e-05 +425 73 2.3899993e-05 +430 73 2.3899993e-05 +431 73 2.3899993e-05 +433 73 2.3899993e-05 +434 73 2.3899993e-05 +438 73 0.00040619983 +441 73 0.0015052999 +443 73 0.0086731985 +444 73 0.00014339999 +445 73 0.034358297 +446 73 0.0028671999 +447 73 0.0004778998 +448 73 0.0004300999 +450 73 0.0034883998 +452 73 0.00052559981 +453 73 7.1699993e-05 +454 73 0.00093179988 +455 73 0.022029497 +456 73 0.013810199 +457 73 0.0036795 +458 73 0.00028669997 +460 73 0.0026282 +463 73 0.0073590986 +464 73 0.00016729999 +465 73 0.00011949999 +467 73 0.012496099 +468 73 0.00054949988 +469 73 0.0054475963 +470 73 0.0053998977 +471 73 0.004396297 +473 73 0.00011949999 +477 73 4.7799986e-05 +478 73 0.00062119984 +483 73 0.00035839994 +489 73 7.1699993e-05 +490 73 0.0004300999 +491 73 0.00021499999 +18 74 0.00030299998 +24 74 0.00090909982 +60 74 0.00045449985 +80 74 0.00015149999 +108 74 0.00015149999 +114 74 0.00015149999 +126 74 0.00015149999 +139 74 0.00075759995 +142 74 0.00015149999 +150 74 0.00015149999 +160 74 0.00030299998 +165 74 0.007878799 +171 74 0.00015149999 +182 74 0.0018181999 +183 74 0.00090909982 +194 74 0.00015149999 +206 74 0.00045449985 +214 74 0.013181798 +220 74 0.00060609984 +223 74 0.017878797 +233 74 0.00060609984 +234 74 0.017727297 +237 74 0.0033332999 +240 74 0.00045449985 +241 74 0.0057575963 +242 74 0.00030299998 +254 74 0.022121198 +265 74 0.0031817998 +266 74 0.00030299998 +273 74 0.010302998 +274 74 0.00030299998 +277 74 0.053484797 +305 74 0.00015149999 +307 74 0.0034848 +308 74 0.0056061 +312 74 0.0010605999 +317 74 0.0027272999 +318 74 0.00015149999 +322 74 0.0042423978 +324 74 0.0081817992 +331 74 0.0287879 +333 74 0.040757596 +350 74 0.0056061 +371 74 0.00030299998 +374 74 0.00090909982 +387 74 0.00015149999 +394 74 0.00015149999 +402 74 0.00075759995 +422 74 0.00015149999 +430 74 0.00015149999 +443 74 0.010606099 +444 74 0.00030299998 +445 74 0.014848497 +446 74 0.0015151999 +447 74 0.00090909982 +448 74 0.00015149999 +450 74 0.004999999 +452 74 0.00075759995 +453 74 0.00015149999 +454 74 0.004999999 +455 74 0.030151498 +456 74 0.0075757988 +457 74 0.0053029992 +458 74 0.00045449985 +460 74 0.0040908977 +463 74 0.010606099 +464 74 0.00030299998 +467 74 0.021818198 +468 74 0.00075759995 +469 74 0.007878799 +470 74 0.007878799 +471 74 0.0069696978 +473 74 0.00015149999 +478 74 0.00090909982 +483 74 0.00045449985 +490 74 0.00075759995 +491 74 0.00030299998 +16 75 0.0001852 +24 75 0.014999997 +60 75 0.00037039979 +108 75 0.0001852 +114 75 0.00037039979 +126 75 0.0001852 +134 75 0.0001852 +139 75 0.00055559981 +150 75 0.0001852 +160 75 0.007407397 +162 75 0.0001852 +163 75 0.0024073999 +165 75 0.0072221979 +166 75 0.0001852 +167 75 0.0012963 +182 75 0.00055559981 +191 75 0.00037039979 +192 75 0.0001852 +206 75 0.00037039979 +219 75 0.0012963 +233 75 0.025185198 +234 75 0.014259297 +235 75 0.0087036975 +236 75 0.0024073999 +237 75 0.0014815 +241 75 0.004444398 +242 75 0.0001852 +252 75 0.00074069994 +254 75 0.0012963 +255 75 0.0001852 +256 75 0.0001852 +257 75 0.0001852 +259 75 0.00037039979 +264 75 0.00074069994 +265 75 0.0022221999 +266 75 0.0092592984 +268 75 0.0024073999 +271 75 0.00037039979 +273 75 0.00037039979 +277 75 0.0014815 +279 75 0.00055559981 +292 75 0.0001852 +293 75 0.0001852 +295 75 0.0024073999 +302 75 0.00037039979 +303 75 0.00092589995 +304 75 0.0024073999 +305 75 0.0062962994 +306 75 0.0012963 +307 75 0.002963 +308 75 0.0055555999 +309 75 0.00055559981 +311 75 0.0014815 +312 75 0.00037039979 +317 75 0.0016666998 +319 75 0.0011111 +322 75 0.0025926 +324 75 0.0014815 +331 75 0.00074069994 +334 75 0.00092589995 +335 75 0.0001852 +336 75 0.00055559981 +356 75 0.0001852 +358 75 0.0001852 +366 75 0.017036997 +371 75 0.0025926 +374 75 0.00037039979 +380 75 0.0001852 +385 75 0.0038888999 +386 75 0.0062962994 +387 75 0.0001852 +390 75 0.00055559981 +394 75 0.0001852 +402 75 0.00037039979 +414 75 0.0001852 +415 75 0.0014815 +438 75 0.0016666998 +441 75 0.00037039979 +443 75 0.0031480999 +444 75 0.0001852 +445 75 0.014259297 +446 75 0.00092589995 +447 75 0.00037039979 +450 75 0.0033332999 +452 75 0.00055559981 +454 75 0.00092589995 +455 75 0.018333297 +456 75 0.022222199 +457 75 0.0035184999 +458 75 0.00055559981 +460 75 0.0025926 +463 75 0.0072221979 +464 75 0.0001852 +467 75 0.018518496 +468 75 0.00055559981 +469 75 0.005185198 +470 75 0.005185198 +471 75 0.004999999 +473 75 0.0001852 +478 75 0.00037039979 +483 75 0.00037039979 +490 75 0.00055559981 +491 75 0.0001852 +9 76 7.9199992e-05 +16 76 2.6399997e-05 +18 76 2.6399997e-05 +22 76 7.9199992e-05 +60 76 0.0039842986 +76 76 0.012955498 +79 76 2.6399997e-05 +81 76 0.00060689985 +82 76 0.0001583 +83 76 0.00010549999 +84 76 0.00010549999 +108 76 0.00018469999 +113 76 0.0002638998 +114 76 0.00055409991 +126 76 0.00029019988 +127 76 5.2799995e-05 +130 76 7.9199992e-05 +134 76 2.6399997e-05 +150 76 0.00042219996 +181 76 5.2799995e-05 +187 76 2.6399997e-05 +189 76 0.00029019988 +190 76 0.00010549999 +192 76 5.2799995e-05 +194 76 7.9199992e-05 +196 76 2.6399997e-05 +197 76 5.2799995e-05 +198 76 5.2799995e-05 +200 76 0.00010549999 +201 76 7.9199992e-05 +203 76 7.9199992e-05 +204 76 0.00010549999 +206 76 0.00021109999 +207 76 5.2799995e-05 +209 76 2.6399997e-05 +214 76 5.2799995e-05 +223 76 5.2799995e-05 +224 76 0.001161 +233 76 0.00081799994 +234 76 0.0016886999 +237 76 7.9199992e-05 +240 76 0.00047489977 +241 76 0.0015039998 +248 76 0.00010549999 +250 76 5.2799995e-05 +251 76 2.6399997e-05 +252 76 0.00023749999 +263 76 2.6399997e-05 +270 76 0.00034299982 +272 76 0.00076519977 +277 76 0.0067019984 +282 76 0.00021109999 +283 76 0.00036939979 +284 76 0.00044859992 +292 76 0.00013189999 +293 76 0.0024275 +294 76 0.00063329982 +295 76 0.00071239984 +296 76 0.00084429979 +298 76 0.0020052998 +299 76 0.0010026998 +312 76 0.0048285984 +315 76 0.0013720999 +319 76 0.0017414999 +320 76 0.00092349993 +321 76 0.00097629987 +322 76 7.9199992e-05 +324 76 0.00047489977 +326 76 0.00010549999 +338 76 2.6399997e-05 +339 76 0.00013189999 +340 76 0.003694 +350 76 0.0023482998 +351 76 0.0002638998 +354 76 0.0007387998 +356 76 2.6399997e-05 +358 76 0.0027704998 +359 76 0.0001583 +369 76 0.00039579999 +370 76 2.6399997e-05 +372 76 0.0019788998 +380 76 5.2799995e-05 +384 76 5.2799995e-05 +386 76 7.9199992e-05 +387 76 0.00029019988 +390 76 0.032058898 +391 76 0.00010549999 +392 76 0.0019788998 +393 76 0.023430698 +396 76 2.6399997e-05 +397 76 0.00010549999 +402 76 0.0029815999 +403 76 0.00010549999 +404 76 0.006965898 +405 76 0.08731097 +413 76 0.0062797964 +414 76 0.00081799994 +419 76 7.9199992e-05 +420 76 0.00010549999 +422 76 0.00021109999 +423 76 7.9199992e-05 +425 76 5.2799995e-05 +430 76 0.0001583 +431 76 2.6399997e-05 +432 76 2.6399997e-05 +433 76 5.2799995e-05 +434 76 5.2799995e-05 +443 76 0.00044859992 +444 76 0.0014775998 +445 76 0.0020844999 +446 76 0.00013189999 +447 76 0.0027704998 +449 76 5.2799995e-05 +450 76 0.0058048964 +452 76 0.0045647994 +453 76 0.00036939979 +454 76 0.00031659985 +455 76 0.0078893974 +456 76 0.0021372999 +457 76 0.0027704998 +458 76 0.0013984998 +459 76 0.00058049988 +460 76 0.00089709996 +463 76 0.0092086978 +464 76 0.0014511999 +465 76 0.0031398998 +467 76 0.023931999 +468 76 0.0011345998 +469 76 0.012981899 +470 76 0.028786998 +471 76 0.0031398998 +473 76 0.00058049988 +477 76 0.00013189999 +478 76 0.0015568 +479 76 2.6399997e-05 +483 76 0.0038786998 +490 76 0.0022427998 +491 76 0.00010549999 +9 77 7.0099995e-05 +22 77 0.0034355 +24 77 0.00035059988 +60 77 0.0043468997 +77 77 0.082521141 +78 77 0.00070109987 +82 77 7.0099995e-05 +83 77 7.0099995e-05 +84 77 7.0099995e-05 +108 77 7.0099995e-05 +113 77 0.00014019999 +114 77 0.00021029999 +126 77 0.00014019999 +127 77 7.0099995e-05 +137 77 0.00063099992 +150 77 0.008833997 +165 77 7.0099995e-05 +171 77 7.0099995e-05 +172 77 0.021173697 +189 77 7.0099995e-05 +190 77 0.00014019999 +192 77 7.0099995e-05 +194 77 7.0099995e-05 +198 77 0.010867298 +200 77 0.00014019999 +201 77 7.0099995e-05 +203 77 7.0099995e-05 +204 77 0.00014019999 +206 77 0.00028039981 +207 77 7.0099995e-05 +214 77 0.00091139995 +218 77 0.00014019999 +220 77 0.0086937994 +224 77 0.0018228998 +229 77 0.0010517 +233 77 0.00014019999 +234 77 0.0060996972 +237 77 0.00028039981 +240 77 0.00084129977 +241 77 0.0016125999 +242 77 0.00035059988 +248 77 7.0099995e-05 +250 77 7.0099995e-05 +252 77 0.00035059988 +270 77 0.00021029999 +271 77 7.0099995e-05 +272 77 7.0099995e-05 +273 77 0.00014019999 +277 77 0.15754044 +282 77 0.0051180981 +283 77 0.008833997 +284 77 0.00056089996 +285 77 0.023206897 +288 77 0.00014019999 +292 77 0.0084834993 +293 77 0.022645999 +294 77 0.00028039981 +295 77 0.0011217999 +296 77 0.0065904967 +298 77 0.00014019999 +299 77 0.0056789964 +304 77 0.00014019999 +307 77 7.0099995e-05 +308 77 7.0099995e-05 +312 77 0.0035055999 +315 77 0.0077823997 +319 77 0.00035059988 +320 77 0.0021734999 +321 77 7.0099995e-05 +322 77 0.0082731992 +324 77 0.00028039981 +326 77 0.0046974979 +328 77 0.00035059988 +331 77 0.00063099992 +333 77 7.0099995e-05 +338 77 0.00063099992 +339 77 7.0099995e-05 +340 77 0.008833997 +341 77 7.0099995e-05 +349 77 7.0099995e-05 +350 77 0.00014019999 +351 77 0.00077119982 +352 77 7.0099995e-05 +354 77 0.00070109987 +356 77 7.0099995e-05 +358 77 0.0072214976 +366 77 0.00028039981 +369 77 0.00014019999 +370 77 0.00014019999 +371 77 0.00035059988 +372 77 0.0014722999 +373 77 0.00014019999 +384 77 7.0099995e-05 +386 77 0.00028039981 +387 77 7.0099995e-05 +390 77 0.00091139995 +391 77 7.0099995e-05 +392 77 0.0072915964 +393 77 0.0051180981 +398 77 0.00014019999 +402 77 0.00028039981 +404 77 0.00021029999 +405 77 0.0011918999 +413 77 0.00021029999 +415 77 7.0099995e-05 +419 77 0.0030848999 +422 77 0.00021029999 +423 77 0.00014019999 +424 77 7.0099995e-05 +425 77 7.0099995e-05 +426 77 7.0099995e-05 +430 77 7.0099995e-05 +431 77 7.0099995e-05 +433 77 7.0099995e-05 +434 77 7.0099995e-05 +438 77 0.00014019999 +441 77 0.00014019999 +442 77 7.0099995e-05 +443 77 0.0077823997 +444 77 0.00063099992 +445 77 0.0082731992 +446 77 0.00084129977 +447 77 0.0015425 +448 77 7.0099995e-05 +450 77 0.0068007968 +452 77 0.0178083 +453 77 0.0081328973 +454 77 0.00084129977 +455 77 0.0250999 +456 77 0.00056089996 +457 77 0.00098159979 +458 77 0.0013320998 +459 77 0.00014019999 +460 77 0.0010517 +463 77 0.0058893971 +464 77 0.00077119982 +465 77 0.0022435999 +467 77 0.025941197 +468 77 0.0060996972 +469 77 0.0091144964 +470 77 0.010306399 +471 77 0.0013320998 +473 77 0.00021029999 +477 77 0.00014019999 +478 77 0.0016125999 +483 77 0.00098159979 +489 77 7.0099995e-05 +490 77 0.00091139995 +491 77 0.00098159979 +22 78 0.00031939987 +60 78 0.0022356999 +77 78 0.020121399 +78 78 0.16671985 +114 78 0.00031939987 +130 78 0.00031939987 +156 78 0.017246898 +172 78 0.00031939987 +198 78 0.00031939987 +206 78 0.00031939987 +214 78 0.00063879997 +225 78 0.00095819985 +234 78 0.0015968999 +237 78 0.00031939987 +240 78 0.0114979 +241 78 0.00063879997 +252 78 0.00031939987 +270 78 0.00031939987 +271 78 0.00031939987 +277 78 0.035451896 +278 78 0.00031939987 +282 78 0.047588598 +283 78 0.0099009983 +284 78 0.00063879997 +285 78 0.00031939987 +292 78 0.00095819985 +293 78 0.0325775 +294 78 0.0028744999 +295 78 0.028744798 +296 78 0.004152 +298 78 0.0092621967 +299 78 0.0086233988 +312 78 0.0038325998 +313 78 0.0025550998 +315 78 0.0035132999 +319 78 0.00063879997 +320 78 0.0038325998 +321 78 0.0038325998 +323 78 0.00031939987 +324 78 0.00031939987 +326 78 0.0031939 +328 78 0.0105398 +340 78 0.0092621967 +351 78 0.0083040968 +353 78 0.00063879997 +354 78 0.016288698 +357 78 0.00031939987 +358 78 0.0079846978 +366 78 0.00095819985 +369 78 0.00031939987 +372 78 0.00095819985 +373 78 0.00063879997 +375 78 0.00031939987 +386 78 0.00031939987 +387 78 0.00031939987 +390 78 0.0022356999 +391 78 0.00031939987 +392 78 0.0015968999 +393 78 0.0038325998 +397 78 0.00095819985 +398 78 0.00031939987 +401 78 0.00095819985 +402 78 0.0079846978 +404 78 0.0073458999 +405 78 0.0025550998 +414 78 0.00063879997 +443 78 0.0031939 +444 78 0.00031939987 +445 78 0.015330598 +447 78 0.0015968999 +450 78 0.004152 +452 78 0.0044713989 +453 78 0.0012774998 +454 78 0.00063879997 +455 78 0.020760097 +457 78 0.00063879997 +458 78 0.00063879997 +460 78 0.00063879997 +463 78 0.0038325998 +464 78 0.00031939987 +465 78 0.0012774998 +467 78 0.015969299 +468 78 0.0012774998 +469 78 0.0038325998 +470 78 0.0057489984 +471 78 0.0015968999 +478 78 0.00095819985 +483 78 0.0019162998 +490 78 0.00063879997 +491 78 0.013094898 +22 79 0.00051709986 +60 79 0.0033608999 +79 79 0.026628699 +108 79 0.00025849999 +114 79 0.00051709986 +126 79 0.00025849999 +161 79 0.018355697 +190 79 0.00025849999 +194 79 0.00025849999 +198 79 0.0028437998 +200 79 0.00025849999 +206 79 0.00051709986 +220 79 0.0072388984 +229 79 0.00051709986 +234 79 0.0033608999 +237 79 0.00025849999 +240 79 0.00025849999 +241 79 0.010082699 +252 79 0.00025849999 +270 79 0.00025849999 +277 79 0.036711499 +282 79 0.010082699 +283 79 0.015253399 +284 79 0.00051709986 +292 79 0.0012926999 +293 79 0.0054291971 +294 79 0.0025852998 +296 79 0.0043949969 +298 79 0.008272998 +299 79 0.0010340998 +312 79 0.012409497 +313 79 0.00025849999 +315 79 0.0080144964 +320 79 0.0072388984 +321 79 0.0031023999 +322 79 0.013443597 +340 79 0.018097199 +351 79 0.0020682998 +358 79 0.0056876987 +387 79 0.00025849999 +392 79 0.0018096999 +393 79 0.0025852998 +402 79 0.00051709986 +422 79 0.00025849999 +441 79 0.0028437998 +443 79 0.0023267998 +444 79 0.00051709986 +445 79 0.003878 +446 79 0.00025849999 +447 79 0.011892498 +450 79 0.0067217983 +452 79 0.0067217983 +453 79 0.0020682998 +454 79 0.0015511999 +455 79 0.016287498 +456 79 0.00025849999 +457 79 0.00077559985 +458 79 0.0023267998 +459 79 0.00025849999 +460 79 0.0010340998 +463 79 0.004136499 +464 79 0.00077559985 +465 79 0.0023267998 +467 79 0.028955497 +468 79 0.0074973963 +469 79 0.008272998 +470 79 0.0093070976 +471 79 0.0010340998 +473 79 0.00025849999 +477 79 0.00025849999 +478 79 0.0020682998 +483 79 0.0012926999 +490 79 0.0010340998 +491 79 0.0018096999 +22 80 0.00066919997 +24 80 0.0002231 +60 80 0.010484099 +79 80 0.009368699 +80 80 0.020521998 +108 80 0.0002231 +114 80 0.00044609979 +126 80 0.0002231 +135 80 0.0002231 +160 80 0.0022306 +171 80 0.0013383999 +191 80 0.0011153 +194 80 0.0002231 +198 80 0.013160799 +206 80 0.00044609979 +220 80 0.039036397 +225 80 0.00044609979 +229 80 0.00089229993 +234 80 0.0026767999 +237 80 0.0002231 +241 80 0.010260999 +252 80 0.0002231 +270 80 0.0071380995 +271 80 0.0002231 +277 80 0.017845199 +284 80 0.00044609979 +287 80 0.052866399 +292 80 0.16417575 +315 80 0.036805697 +320 80 0.0044612996 +321 80 0.009368699 +340 80 0.013606999 +351 80 0.0002231 +358 80 0.0040151998 +387 80 0.0002231 +443 80 0.0051304996 +444 80 0.010260999 +445 80 0.017175999 +446 80 0.00044609979 +447 80 0.0064688995 +450 80 0.0055765994 +452 80 0.0071380995 +453 80 0.0017845 +454 80 0.00089229993 +455 80 0.023867898 +456 80 0.0002231 +457 80 0.00066919997 +458 80 0.0011153 +459 80 0.0002231 +460 80 0.00089229993 +463 80 0.0017845 +464 80 0.00066919997 +465 80 0.0013383999 +467 80 0.024090998 +468 80 0.0055765994 +469 80 0.0057996996 +470 80 0.0066918992 +471 80 0.00066919997 +473 80 0.0002231 +477 80 0.0002231 +478 80 0.0013383999 +483 80 0.00066919997 +490 80 0.00066919997 +491 80 0.0013383999 +9 81 0.00017429999 +22 81 0.00052279979 +24 81 0.00017429999 +60 81 0.0060996972 +77 81 0.013419297 +79 81 0.010108098 +81 81 0.00017429999 +82 81 0.00017429999 +108 81 0.00017429999 +114 81 0.00034859986 +120 81 0.00017429999 +126 81 0.00017429999 +130 81 0.00017429999 +150 81 0.00052279979 +160 81 0.0012198999 +161 81 0.00052279979 +172 81 0.0012198999 +181 81 0.00017429999 +189 81 0.00017429999 +190 81 0.00017429999 +194 81 0.00017429999 +198 81 0.0017428 +200 81 0.00017429999 +203 81 0.00017429999 +204 81 0.00017429999 +206 81 0.00052279979 +214 81 0.00052279979 +218 81 0.00017429999 +220 81 0.005053997 +223 81 0.00017429999 +224 81 0.00017429999 +229 81 0.00052279979 +234 81 0.0033113 +237 81 0.00017429999 +240 81 0.0015685 +241 81 0.0024398998 +252 81 0.00017429999 +270 81 0.00017429999 +277 81 0.031892598 +282 81 0.011327997 +283 81 0.0087137967 +284 81 0.00052279979 +285 81 0.0012198999 +287 81 0.00017429999 +289 81 0.0024398998 +290 81 0.00017429999 +292 81 0.0020913 +293 81 0.006622497 +294 81 0.0022655998 +295 81 0.00017429999 +296 81 0.009585198 +298 81 0.0024398998 +299 81 0.0067967996 +312 81 0.0031369999 +313 81 0.00034859986 +315 81 0.0026141999 +318 81 0.0017428 +319 81 0.00034859986 +320 81 0.0087137967 +321 81 0.0013941999 +322 81 0.0078424998 +326 81 0.0043568984 +328 81 0.0017428 +333 81 0.00017429999 +338 81 0.00087139988 +340 81 0.0041825995 +351 81 0.0047054999 +354 81 0.00017429999 +358 81 0.011153698 +369 81 0.00017429999 +386 81 0.00017429999 +387 81 0.00017429999 +390 81 0.0026141999 +391 81 0.00017429999 +392 81 0.0202161 +393 81 0.0085395984 +397 81 0.00017429999 +402 81 0.00034859986 +403 81 0.00017429999 +404 81 0.0047054999 +405 81 0.026315797 +414 81 0.00017429999 +419 81 0.0013941999 +422 81 0.00017429999 +430 81 0.00017429999 +434 81 0.00017429999 +442 81 0.00017429999 +443 81 0.0017428 +444 81 0.0010456999 +445 81 0.0031369999 +447 81 0.0022655998 +450 81 0.0078424998 +452 81 0.010979399 +453 81 0.0020913 +454 81 0.0012198999 +455 81 0.012896497 +456 81 0.00069709984 +457 81 0.00087139988 +458 81 0.0017428 +459 81 0.00034859986 +460 81 0.00087139988 +463 81 0.0031369999 +464 81 0.0013941999 +465 81 0.0024398998 +467 81 0.033286899 +468 81 0.0027883998 +469 81 0.013244998 +470 81 0.016033497 +471 81 0.0013941999 +473 81 0.00034859986 +478 81 0.0020913 +483 81 0.0026141999 +490 81 0.0013941999 +491 81 0.0034854999 +0 82 6.5899992e-05 +1 82 4.2299987e-05 +2 82 0.72868645 +3 82 4.2299987e-05 +5 82 0.00035749981 +6 82 0.0049346983 +9 82 3.2899989e-05 +11 82 2.349999e-05 +14 82 4.6999994e-06 +17 82 6.5899992e-05 +18 82 0.00033399998 +22 82 0.0001317 +25 82 4.2299987e-05 +60 82 0.00076209987 +62 82 9.8799996e-05 +79 82 4.6999994e-06 +82 82 0.067349672 +83 82 0.0025684999 +84 82 2.349999e-05 +88 82 0.00019759999 +94 82 9.3999997e-06 +97 82 4.6999994e-06 +98 82 2.349999e-05 +102 82 0.0012089999 +104 82 9.3999997e-06 +107 82 2.8199996e-05 +108 82 4.6999994e-06 +111 82 4.6999994e-06 +113 82 9.3999997e-06 +114 82 1.4099999e-05 +117 82 4.2299987e-05 +118 82 0.00030109985 +119 82 1.8799998e-05 +120 82 0.0002774999 +122 82 2.349999e-05 +125 82 0.0014253999 +126 82 9.3999997e-06 +127 82 4.6999994e-06 +141 82 4.6999994e-06 +149 82 4.6999994e-06 +150 82 0.00012699999 +153 82 0.00013639999 +172 82 0.00011289999 +189 82 3.2899989e-05 +190 82 1.8799998e-05 +192 82 1.8799998e-05 +193 82 3.2899989e-05 +194 82 1.4099999e-05 +196 82 4.6999994e-06 +197 82 4.6999994e-06 +198 82 0.0048499964 +200 82 9.3999997e-06 +201 82 9.3999997e-06 +203 82 1.4099999e-05 +204 82 0.00019759999 +206 82 9.8799996e-05 +207 82 9.3999997e-06 +209 82 4.6999994e-06 +214 82 0.00036219996 +217 82 1.4099999e-05 +218 82 9.3999997e-06 +223 82 0.00013639999 +228 82 9.3999997e-06 +229 82 0.00068209996 +230 82 0.00015519999 +234 82 0.00088439998 +237 82 0.00015519999 +241 82 0.0053721964 +242 82 0.0001599 +248 82 4.6999994e-06 +250 82 4.6999994e-06 +251 82 4.6999994e-06 +252 82 1.4099999e-05 +253 82 4.6999994e-06 +272 82 0.00013639999 +279 82 0.0002023 +300 82 0.0019945998 +301 82 0.00011759999 +317 82 1.8799998e-05 +325 82 1.4099999e-05 +329 82 8.469999e-05 +344 82 0.00054099993 +356 82 6.5899992e-05 +358 82 7.0599999e-05 +384 82 9.3999997e-06 +387 82 9.3999997e-06 +394 82 9.3999997e-06 +397 82 4.6999994e-06 +402 82 4.6999994e-05 +404 82 1.8799998e-05 +414 82 0.00010819999 +419 82 4.6999994e-06 +422 82 1.8799998e-05 +423 82 4.6999994e-06 +425 82 4.6999994e-06 +430 82 4.6999994e-06 +431 82 4.6999994e-06 +432 82 4.6999994e-06 +433 82 9.3999997e-06 +434 82 9.3999997e-06 +443 82 0.0012371999 +444 82 1.8799998e-05 +445 82 0.0057108998 +446 82 0.00031519984 +447 82 6.5899992e-05 +448 82 1.4099999e-05 +450 82 0.00055979984 +452 82 0.0028036998 +453 82 0.0011336999 +454 82 0.00030109985 +455 82 0.030807696 +456 82 0.0001599 +457 82 0.0010537 +458 82 9.8799996e-05 +459 82 0.00038099987 +460 82 0.00071029994 +463 82 0.0011713 +464 82 2.349999e-05 +465 82 0.00030579977 +467 82 0.0025072999 +468 82 0.0014489 +469 82 0.00072439993 +470 82 0.00078559993 +471 82 0.00066799996 +472 82 7.9999998e-05 +473 82 1.4099999e-05 +476 82 4.6999994e-05 +477 82 4.2299987e-05 +478 82 0.00021639999 +483 82 0.00040459982 +489 82 4.2299987e-05 +490 82 6.1199986e-05 +491 82 0.00044219987 +0 83 7.9699996e-05 +1 83 0.00090279989 +2 83 0.34128594 +3 83 2.6599999e-05 +5 83 0.00037169992 +6 83 0.00023899999 +9 83 5.3099997e-05 +11 83 9.2899994e-05 +13 83 1.3299999e-05 +14 83 1.3299999e-05 +17 83 0.00018589999 +22 83 7.9699996e-05 +25 83 1.3299999e-05 +60 83 0.0011815999 +82 83 0.31769359 +83 83 0.033775397 +84 83 0.00029209978 +85 83 1.3299999e-05 +87 83 6.6399996e-05 +88 83 0.00099569978 +90 83 2.6599999e-05 +93 83 5.3099997e-05 +94 83 7.9699996e-05 +98 83 3.9799997e-05 +103 83 1.3299999e-05 +104 83 1.3299999e-05 +107 83 3.9799997e-05 +108 83 1.3299999e-05 +114 83 3.9799997e-05 +115 83 1.3299999e-05 +118 83 2.6599999e-05 +120 83 1.3299999e-05 +122 83 3.9799997e-05 +124 83 3.9799997e-05 +125 83 0.0055628978 +126 83 1.3299999e-05 +130 83 1.3299999e-05 +149 83 1.3299999e-05 +150 83 0.00022569999 +153 83 6.6399996e-05 +172 83 5.3099997e-05 +189 83 3.9799997e-05 +190 83 3.9799997e-05 +192 83 0.00087619992 +193 83 0.0072090998 +194 83 2.6599999e-05 +198 83 0.011377998 +200 83 1.3299999e-05 +203 83 1.3299999e-05 +204 83 0.010090098 +206 83 0.00019909999 +207 83 1.3299999e-05 +214 83 0.00033189985 +223 83 0.00019909999 +224 83 0.00010619999 +229 83 0.00066379993 +230 83 0.00026549981 +234 83 0.0013408998 +237 83 0.00014599999 +240 83 0.00010619999 +241 83 0.011616897 +242 83 0.00017259999 +252 83 1.3299999e-05 +253 83 0.00014599999 +272 83 0.00018589999 +277 83 1.3299999e-05 +279 83 0.00049119978 +300 83 0.0060009994 +301 83 5.3099997e-05 +314 83 2.6599999e-05 +315 83 1.3299999e-05 +316 83 0.00017259999 +318 83 1.3299999e-05 +344 83 0.00051779998 +356 83 6.6399996e-05 +358 83 0.00010619999 +384 83 1.3299999e-05 +387 83 1.3299999e-05 +394 83 1.3299999e-05 +402 83 5.3099997e-05 +404 83 1.3299999e-05 +414 83 5.3099997e-05 +422 83 2.6599999e-05 +430 83 1.3299999e-05 +433 83 1.3299999e-05 +434 83 1.3299999e-05 +442 83 6.6399996e-05 +443 83 0.0023498998 +444 83 6.6399996e-05 +445 83 0.012984399 +446 83 0.00037169992 +447 83 0.0014072999 +448 83 1.3299999e-05 +450 83 0.00082309986 +452 83 0.0034385999 +453 83 0.0017259 +454 83 0.00039829989 +455 83 0.0437859 +456 83 0.00018589999 +457 83 0.001009 +458 83 0.00023899999 +459 83 0.0010753998 +460 83 0.00086299982 +463 83 0.0031597998 +464 83 7.9699996e-05 +465 83 0.0013408998 +467 83 0.003359 +468 83 0.0026021998 +469 83 0.0012877998 +470 83 0.0014205999 +471 83 0.0010753998 +472 83 3.9799997e-05 +473 83 3.9799997e-05 +477 83 3.9799997e-05 +478 83 0.00034519983 +483 83 0.00057089981 +489 83 5.3099997e-05 +490 83 0.00014599999 +491 83 0.00029209978 +1 84 0.62848139 +2 84 0.00014199999 +3 84 0.0009937 +4 84 2.8399998e-05 +5 84 5.6799996e-05 +6 84 0.00031229993 +9 84 5.6799996e-05 +11 84 8.5199994e-05 +14 84 0.004059799 +18 84 0.0001987 +60 84 0.0010221 +82 84 0.0013626998 +83 84 0.00014199999 +84 84 0.026374798 +85 84 0.00011359999 +94 84 8.5199994e-05 +102 84 0.00059619988 +108 84 2.8399998e-05 +114 84 5.6799996e-05 +118 84 0.00017029999 +120 84 2.8399998e-05 +122 84 2.8399998e-05 +125 84 2.8399998e-05 +126 84 2.8399998e-05 +150 84 0.00045419997 +172 84 0.0029525999 +189 84 2.8399998e-05 +190 84 8.5199994e-05 +192 84 2.8399998e-05 +193 84 0.012775697 +194 84 8.5199994e-05 +195 84 0.0002271 +197 84 2.8399998e-05 +198 84 0.015728399 +200 84 2.8399998e-05 +203 84 5.6799996e-05 +204 84 0.0010787998 +206 84 0.00017029999 +207 84 2.8399998e-05 +214 84 0.0024699999 +223 84 0.00014199999 +229 84 0.00059619988 +230 84 0.00053939992 +234 84 0.0023563998 +237 84 0.00028389995 +240 84 2.8399998e-05 +241 84 0.00014199999 +242 84 0.00017029999 +252 84 2.8399998e-05 +272 84 0.00025549997 +277 84 2.8399998e-05 +279 84 0.00079489988 +300 84 0.00025549997 +325 84 2.8399998e-05 +344 84 0.00045419997 +356 84 5.6799996e-05 +358 84 0.0002271 +366 84 2.8399998e-05 +387 84 2.8399998e-05 +394 84 2.8399998e-05 +397 84 2.8399998e-05 +402 84 0.00014199999 +422 84 8.5199994e-05 +433 84 2.8399998e-05 +434 84 2.8399998e-05 +443 84 0.0009368998 +444 84 5.6799996e-05 +445 84 0.010845199 +446 84 0.00017029999 +447 84 0.00082329987 +448 84 2.8399998e-05 +450 84 0.0017317999 +452 84 0.0049682967 +453 84 0.0012492 +454 84 0.0015330999 +455 84 0.049796999 +456 84 0.00039749988 +457 84 0.00028389995 +458 84 0.00028389995 +459 84 0.00014199999 +460 84 0.0007664999 +463 84 0.0015330999 +464 84 8.5199994e-05 +465 84 0.0010787998 +467 84 0.0041449964 +468 84 0.0030377998 +469 84 0.0009937 +470 84 0.0011355998 +471 84 0.0022429 +473 84 2.8399998e-05 +476 84 5.6799996e-05 +477 84 2.8399998e-05 +478 84 0.00070979982 +483 84 0.0003690999 +489 84 0.00014199999 +490 84 0.00011359999 +491 84 0.00031229993 +1 85 0.41609979 +2 85 0.000189 +9 85 0.0032123998 +11 85 0.0022675998 +60 85 0.0015117 +82 85 0.0041571967 +83 85 0.00056689978 +84 85 0.14852607 +85 85 0.0060468987 +97 85 0.000189 +98 85 0.00037789997 +105 85 0.000189 +107 85 0.00037789997 +114 85 0.000189 +122 85 0.00094479998 +125 85 0.000189 +172 85 0.000189 +189 85 0.00037789997 +192 85 0.00075589982 +193 85 0.013416499 +194 85 0.000189 +198 85 0.034580499 +204 85 0.00037789997 +206 85 0.00037789997 +214 85 0.00056689978 +223 85 0.00056689978 +229 85 0.00056689978 +230 85 0.00075589982 +234 85 0.0032123998 +237 85 0.00037789997 +240 85 0.00094479998 +241 85 0.0011337998 +242 85 0.000189 +253 85 0.000189 +272 85 0.00056689978 +279 85 0.0015117 +300 85 0.0096371993 +325 85 0.0015117 +344 85 0.00056689978 +358 85 0.00037789997 +366 85 0.000189 +402 85 0.000189 +443 85 0.00094479998 +445 85 0.011526797 +446 85 0.00037789997 +447 85 0.00075589982 +450 85 0.0020786 +452 85 0.0056688972 +453 85 0.0020786 +454 85 0.0013227998 +455 85 0.062547147 +456 85 0.00037789997 +457 85 0.0049130991 +458 85 0.00094479998 +459 85 0.00094479998 +460 85 0.00075589982 +463 85 0.0047240965 +465 85 0.0011337998 +467 85 0.0060468987 +468 85 0.0079364963 +469 85 0.0013227998 +470 85 0.0015117 +471 85 0.0022675998 +478 85 0.00075589982 +483 85 0.00037789997 +490 85 0.000189 +491 85 0.000189 +0 86 0.32495898 +1 86 0.0032823998 +22 86 0.00025249994 +60 86 0.0020198999 +82 86 0.00025249994 +84 86 0.00050499989 +86 86 0.019820698 +87 86 0.011614699 +88 86 0.020704497 +90 86 0.31662667 +107 86 0.0036611999 +115 86 0.0013887 +125 86 0.00025249994 +192 86 0.021840699 +193 86 0.0020198999 +194 86 0.00025249994 +198 86 0.023355599 +204 86 0.0041660964 +206 86 0.00025249994 +214 86 0.00050499989 +223 86 0.00025249994 +229 86 0.00088369986 +230 86 0.00012619999 +234 86 0.0027774 +237 86 0.00025249994 +240 86 0.00012619999 +241 86 0.0045448989 +242 86 0.00050499989 +253 86 0.00012619999 +272 86 0.00025249994 +277 86 0.00012619999 +279 86 0.00012619999 +300 86 0.012119699 +325 86 0.00050499989 +344 86 0.00088369986 +350 86 0.00037869997 +351 86 0.00025249994 +356 86 0.00012619999 +366 86 0.00012619999 +443 86 0.0018936999 +444 86 0.00037869997 +445 86 0.0090897977 +446 86 0.00025249994 +447 86 0.0018936999 +450 86 0.00088369986 +452 86 0.0034087 +453 86 0.0032823998 +454 86 0.00050499989 +455 86 0.050498698 +456 86 0.00037869997 +457 86 0.0021461998 +458 86 0.00025249994 +459 86 0.00050499989 +460 86 0.0011361998 +463 86 0.0017674998 +464 86 0.00012619999 +465 86 0.0050498992 +467 86 0.0039136 +468 86 0.004797399 +469 86 0.00088369986 +470 86 0.00075749983 +471 86 0.0025248998 +478 86 0.00025249994 +483 86 0.00075749983 +490 86 0.00025249994 +491 86 0.00075749983 +0 87 0.29069388 +3 87 3.6099998e-05 +9 87 3.6099998e-05 +11 87 7.2199997e-05 +13 87 3.6099998e-05 +14 87 7.2199997e-05 +22 87 7.2199997e-05 +25 87 0.00014429999 +60 87 0.00093819993 +82 87 7.2199997e-05 +86 87 0.0014795 +87 87 0.24414527 +88 87 0.0046548992 +90 87 0.088875294 +104 87 3.6099998e-05 +105 87 3.6099998e-05 +107 87 0.0010463998 +114 87 3.6099998e-05 +122 87 7.2199997e-05 +125 87 0.0019484998 +130 87 0.0011908 +150 87 0.0012629 +151 87 0.0013712 +190 87 3.6099998e-05 +192 87 0.023887698 +193 87 0.0117273 +194 87 3.6099998e-05 +198 87 0.0105366 +203 87 3.6099998e-05 +204 87 0.0088767 +206 87 0.00018039999 +214 87 0.0037527999 +223 87 0.00050519989 +229 87 0.00079389988 +230 87 0.00014429999 +234 87 0.0029227999 +237 87 0.00036079995 +240 87 0.00021649999 +241 87 0.018727697 +242 87 0.0010103998 +253 87 3.6099998e-05 +272 87 0.00032479991 +277 87 7.2199997e-05 +279 87 0.00036079995 +300 87 0.0055569969 +317 87 0.0011908 +324 87 0.00014429999 +325 87 0.0022371998 +326 87 0.00082989992 +340 87 0.0010463998 +344 87 0.002165 +349 87 3.6099998e-05 +356 87 7.2199997e-05 +358 87 0.0001083 +366 87 0.00086599984 +394 87 3.6099998e-05 +402 87 0.00014429999 +422 87 3.6099998e-05 +434 87 3.6099998e-05 +442 87 0.00075779995 +443 87 0.0022733 +444 87 0.0016599 +445 87 0.0093457997 +446 87 0.00028869999 +447 87 0.0011185999 +448 87 7.2199997e-05 +450 87 0.0020567998 +452 87 0.0031392998 +453 87 0.0030671998 +454 87 0.0014072999 +455 87 0.071266174 +456 87 0.0004329998 +457 87 0.0020567998 +458 87 0.00032479991 +459 87 0.0018041998 +460 87 0.0011908 +463 87 0.0046908967 +464 87 0.00093819993 +465 87 0.005448699 +467 87 0.007469397 +468 87 0.0110057 +469 87 0.0004329998 +470 87 0.0004329998 +471 87 0.0024175998 +472 87 0.00036079995 +477 87 3.6099998e-05 +478 87 0.00028869999 +483 87 0.00028869999 +489 87 0.0001083 +490 87 0.00018039999 +491 87 3.6099998e-05 +0 88 0.30537045 +1 88 0.0011586999 +2 88 5.789999e-05 +3 88 5.789999e-05 +5 88 5.789999e-05 +9 88 0.00011589999 +10 88 5.789999e-05 +11 88 0.00011589999 +13 88 0.00011589999 +14 88 0.0001738 +22 88 0.00052139978 +60 88 0.0017959999 +82 88 0.00028969999 +84 88 0.00011589999 +86 88 0.0057354979 +87 88 0.0069520995 +88 88 0.071896195 +90 88 0.1147095 +98 88 0.00011589999 +104 88 0.00023169999 +105 88 0.0001738 +107 88 0.009443298 +109 88 0.00011589999 +114 88 5.789999e-05 +115 88 0.0079948977 +116 88 0.00023169999 +122 88 0.0001738 +125 88 5.789999e-05 +150 88 0.00023169999 +151 88 5.789999e-05 +172 88 5.789999e-05 +192 88 0.040495899 +193 88 0.009443298 +194 88 0.00034759985 +198 88 0.023173597 +204 88 0.0057933964 +206 88 0.00028969999 +214 88 0.0020277 +223 88 0.00011589999 +229 88 0.00063729985 +230 88 0.0001738 +234 88 0.0034180998 +237 88 0.00034759985 +240 88 0.00023169999 +241 88 0.0057933964 +242 88 0.0016800999 +253 88 0.00057929987 +272 88 0.00034759985 +277 88 5.789999e-05 +279 88 0.00040549994 +300 88 0.067261457 +301 88 5.789999e-05 +314 88 5.789999e-05 +324 88 0.0001738 +325 88 0.0018538998 +340 88 0.00011589999 +344 88 0.0012166 +350 88 0.0021435998 +351 88 0.0012166 +356 88 5.789999e-05 +358 88 0.00011589999 +366 88 0.00023169999 +402 88 0.0001738 +443 88 0.0038816 +444 88 0.0012166 +445 88 0.0064885989 +446 88 0.00052139978 +447 88 0.0019697999 +450 88 0.0010427998 +452 88 0.0047505982 +453 88 0.004171297 +454 88 0.00092689996 +455 88 0.0436823 +456 88 0.00052139978 +457 88 0.0022594 +458 88 0.00046349992 +459 88 0.00046349992 +460 88 0.0013903999 +463 88 0.0036497999 +464 88 0.00011589999 +465 88 0.0057354979 +467 88 0.0074734986 +468 88 0.016858798 +469 88 0.0011586999 +470 88 0.00086899986 +471 88 0.0029545999 +472 88 5.789999e-05 +477 88 5.789999e-05 +478 88 0.00040549994 +483 88 0.00057929987 +489 88 0.0001738 +490 88 0.00034759985 +491 88 0.001738 +0 89 0.15343666 +2 89 0.0001314 +10 89 0.0053225979 +14 89 6.5699991e-05 +22 89 6.5699991e-05 +60 89 0.0025628 +86 89 0.0048626997 +87 89 0.00072279992 +88 89 0.083322346 +89 89 0.0011170998 +90 89 0.12938625 +104 89 0.012682296 +105 89 0.0085424967 +107 89 0.027795997 +108 89 0.00019709999 +109 89 0.0076225996 +114 89 6.5699991e-05 +115 89 0.00019709999 +116 89 0.0089367963 +117 89 0.0001314 +119 89 0.00098569994 +125 89 6.5699991e-05 +126 89 6.5699991e-05 +150 89 0.0001314 +172 89 6.5699991e-05 +189 89 0.0001314 +190 89 6.5699991e-05 +192 89 0.010645296 +193 89 0.0081481971 +194 89 0.00052569993 +198 89 0.065645874 +203 89 6.5699991e-05 +204 89 0.0001314 +206 89 0.00032859994 +214 89 0.0017084999 +223 89 0.00019709999 +229 89 0.00059139985 +230 89 0.00026279991 +234 89 0.0048626997 +237 89 0.00078849983 +240 89 0.00019709999 +241 89 0.0083453991 +242 89 0.00059139985 +253 89 6.5699991e-05 +272 89 0.00059139985 +279 89 0.00039429986 +300 89 0.0017741998 +301 89 0.0001314 +314 89 6.5699991e-05 +324 89 0.00026279991 +325 89 0.00019709999 +344 89 0.00045999978 +350 89 6.5699991e-05 +351 89 0.00032859994 +356 89 6.5699991e-05 +358 89 0.00026279991 +366 89 0.00091999979 +402 89 0.00026279991 +422 89 6.5699991e-05 +434 89 6.5699991e-05 +443 89 0.0045340993 +444 89 0.00019709999 +445 89 0.0056511983 +446 89 0.0006571 +447 89 0.0032199 +448 89 6.5699991e-05 +450 89 0.0019055998 +452 89 0.0095938966 +453 89 0.0018398999 +454 89 0.00052569993 +455 89 0.048429497 +456 89 0.00098569994 +457 89 0.0022341998 +458 89 0.0006571 +459 89 0.00052569993 +460 89 0.0019055998 +463 89 0.0058482997 +464 89 0.0001314 +465 89 0.0080167986 +467 89 0.0065054968 +468 89 0.017413598 +469 89 0.0025628 +470 89 0.0024312998 +471 89 0.0061111972 +472 89 6.5699991e-05 +473 89 6.5699991e-05 +478 89 0.0006571 +483 89 0.0017084999 +489 89 0.00026279991 +490 89 0.00026279991 +491 89 6.5699991e-05 +0 90 0.3519575 +1 90 0.00019929999 +2 90 0.00029369979 +5 90 0.00087069999 +6 90 0.047343798 +9 90 2.1e-05 +10 90 1.05e-05 +11 90 1.05e-05 +18 90 0.0049200989 +22 90 0.00028319983 +24 90 1.05e-05 +60 90 0.0015840998 +62 90 0.0013322998 +79 90 1.05e-05 +82 90 1.05e-05 +83 90 1.05e-05 +84 90 3.1499992e-05 +86 90 0.0024128 +87 90 0.0039653964 +88 90 0.011634 +90 90 0.098159969 +98 90 0.00055599981 +102 90 0.022502199 +103 90 2.1e-05 +104 90 0.00026229979 +105 90 2.1e-05 +107 90 0.0067034997 +108 90 1.05e-05 +109 90 2.1e-05 +111 90 0.00017829999 +113 90 2.1e-05 +114 90 6.2899999e-05 +115 90 0.00015739999 +116 90 2.1e-05 +117 90 0.00028319983 +118 90 0.0023184 +119 90 4.2e-05 +120 90 3.1499992e-05 +122 90 2.1e-05 +125 90 2.1e-05 +126 90 3.1499992e-05 +127 90 1.05e-05 +130 90 1.05e-05 +141 90 1.05e-05 +143 90 0.00030419999 +150 90 0.00015739999 +151 90 3.1499992e-05 +160 90 5.2499992e-05 +171 90 2.1e-05 +172 90 0.00013639999 +189 90 0.00011539999 +190 90 4.2e-05 +191 90 2.1e-05 +192 90 0.0013007999 +193 90 0.00037769997 +194 90 0.0012484 +196 90 1.05e-05 +197 90 1.05e-05 +198 90 0.047238898 +200 90 4.2e-05 +201 90 3.1499992e-05 +203 90 3.1499992e-05 +204 90 0.00028319983 +206 90 0.00013639999 +207 90 2.1e-05 +209 90 1.05e-05 +214 90 0.00048259995 +217 90 0.0002308 +218 90 2.1e-05 +223 90 0.00024129999 +228 90 7.3399991e-05 +229 90 0.0012063999 +230 90 0.00017829999 +234 90 0.0041751973 +237 90 0.0013007999 +240 90 0.00015739999 +241 90 0.0055389963 +242 90 0.00030419999 +248 90 1.05e-05 +250 90 1.05e-05 +251 90 1.05e-05 +252 90 2.1e-05 +253 90 0.0002098 +272 90 0.00030419999 +279 90 0.0001888 +283 90 1.05e-05 +300 90 0.0025072 +301 90 0.00032519992 +307 90 2.1e-05 +314 90 0.0001678 +315 90 0.00033569988 +317 90 0.00019929999 +322 90 1.05e-05 +324 90 0.0001049 +325 90 8.3899999e-05 +326 90 1.05e-05 +329 90 0.00096509978 +334 90 1.05e-05 +340 90 2.1e-05 +344 90 0.00044059986 +350 90 8.3899999e-05 +351 90 0.00083919987 +356 90 9.4399991e-05 +357 90 2.1e-05 +358 90 0.0001469 +366 90 0.00087069999 +384 90 3.1499992e-05 +387 90 2.1e-05 +394 90 8.3899999e-05 +397 90 2.1e-05 +402 90 0.00032519992 +419 90 1.05e-05 +422 90 4.2e-05 +423 90 1.05e-05 +425 90 1.05e-05 +430 90 1.05e-05 +431 90 1.05e-05 +432 90 1.05e-05 +433 90 2.1e-05 +434 90 2.1e-05 +442 90 2.1e-05 +443 90 0.0019302999 +444 90 0.0001678 +445 90 0.0083399974 +446 90 0.00034619984 +447 90 0.0011119999 +448 90 9.4399991e-05 +450 90 0.0017833998 +452 90 0.0056123994 +453 90 0.0013742999 +454 90 0.00038809981 +455 90 0.026121397 +456 90 0.00093369978 +457 90 0.0036821999 +458 90 0.00055599981 +459 90 0.00071339984 +460 90 0.0023079 +463 90 0.0089064986 +464 90 9.4399991e-05 +465 90 0.0013951999 +467 90 0.0063572973 +468 90 0.0058431998 +469 90 0.0034408998 +470 90 0.0020456999 +471 90 0.0050039999 +472 90 0.0001888 +473 90 5.2499992e-05 +476 90 0.00033569988 +477 90 6.2899999e-05 +478 90 0.00070289988 +483 90 0.0014161998 +489 90 0.00015739999 +490 90 0.00017829999 +491 90 4.2e-05 +0 91 0.0030756998 +3 91 0.00096119987 +9 91 0.00019219999 +11 91 0.00096119987 +17 91 0.37677819 +22 91 0.00019219999 +60 91 0.0024989999 +82 91 0.0049980991 +83 91 0.00038449978 +84 91 0.00038449978 +90 91 0.00076889992 +91 91 0.005190298 +93 91 0.00096119987 +94 91 0.0011533999 +96 91 0.00019219999 +98 91 0.00038449978 +103 91 0.00019219999 +104 91 0.00019219999 +107 91 0.00057669985 +114 91 0.00019219999 +115 91 0.00019219999 +116 91 0.00019219999 +118 91 0.00019219999 +120 91 0.00019219999 +122 91 0.0096116997 +124 91 0.00057669985 +125 91 0.00038449978 +150 91 0.00019219999 +192 91 0.00038449978 +193 91 0.00038449978 +194 91 0.00019219999 +198 91 0.0151865 +204 91 0.017493296 +206 91 0.00096119987 +214 91 0.00096119987 +223 91 0.00076889992 +229 91 0.00038449978 +230 91 0.00076889992 +233 91 0.00019219999 +234 91 0.0028835 +237 91 0.00019219999 +240 91 0.0013455998 +241 91 0.0086504966 +242 91 0.0023067999 +252 91 0.00019219999 +253 91 0.0019222999 +272 91 0.00057669985 +277 91 0.00019219999 +300 91 0.051326398 +314 91 0.00038449978 +340 91 0.00019219999 +344 91 0.00038449978 +356 91 0.00019219999 +358 91 0.00076889992 +366 91 0.00019219999 +402 91 0.00019219999 +443 91 0.0015379 +444 91 0.00019219999 +445 91 0.0042290986 +447 91 0.0098038986 +450 91 0.0021145998 +452 91 0.0036523999 +453 91 0.0013455998 +454 91 0.0017300998 +455 91 0.10976547 +456 91 0.00019219999 +457 91 0.0017300998 +458 91 0.0011533999 +459 91 0.00038449978 +460 91 0.0017300998 +463 91 0.0065358989 +464 91 0.00038449978 +465 91 0.0013455998 +467 91 0.0078815967 +468 91 0.012110699 +469 91 0.0019222999 +470 91 0.0019222999 +471 91 0.0021145998 +478 91 0.00076889992 +483 91 0.0011533999 +489 91 0.00076889992 +490 91 0.00038449978 +491 91 0.0021145998 +0 92 0.00061319978 +1 92 0.0018396999 +2 92 0.0011037998 +3 92 6.1299987e-05 +5 92 6.1299987e-05 +9 92 0.0063775964 +11 92 0.027472898 +13 92 0.0017170999 +14 92 0.00012259999 +16 92 0.00098119979 +17 92 0.0051511973 +22 92 0.00067459978 +60 92 0.0036793998 +82 92 0.066045284 +83 92 0.00079719978 +84 92 0.010424998 +85 92 0.00018399999 +88 92 0.0019009998 +90 92 0.00018399999 +92 92 0.00024529989 +93 92 0.0226283 +94 92 0.028024796 +95 92 0.00024529989 +98 92 0.0072974972 +103 92 0.0025755998 +104 92 0.0038019998 +107 92 0.014288299 +108 92 6.1299987e-05 +114 92 0.00012259999 +115 92 0.0038633998 +116 92 0.0005518999 +118 92 0.0036181 +119 92 0.0009198999 +122 92 0.0072974972 +124 92 0.013920397 +125 92 0.010976899 +126 92 6.1299987e-05 +150 92 6.1299987e-05 +169 92 6.1299987e-05 +172 92 0.00012259999 +189 92 6.1299987e-05 +190 92 6.1299987e-05 +192 92 0.00042929989 +193 92 0.00036789989 +194 92 6.1299987e-05 +198 92 0.016128 +203 92 6.1299987e-05 +204 92 0.0172932 +206 92 0.00018399999 +214 92 0.0036793998 +223 92 0.0012877998 +229 92 0.00079719978 +230 92 0.00042929989 +234 92 0.0026981998 +237 92 0.00018399999 +240 92 0.0014717998 +241 92 0.0082172975 +242 92 0.0011650999 +252 92 6.1299987e-05 +253 92 0.045317996 +272 92 0.0005518999 +277 92 6.1299987e-05 +300 92 0.11522657 +314 92 0.0109156 +325 92 6.1299987e-05 +344 92 0.00036789989 +356 92 6.1299987e-05 +358 92 0.00042929989 +366 92 0.0016556999 +387 92 6.1299987e-05 +402 92 0.00012259999 +414 92 6.1299987e-05 +422 92 6.1299987e-05 +434 92 6.1299987e-05 +443 92 0.0065002963 +444 92 0.00030659977 +445 92 0.027104899 +446 92 0.0011037998 +447 92 0.0031274999 +448 92 6.1299987e-05 +450 92 0.0015943998 +452 92 0.0029434999 +453 92 0.0021462999 +454 92 0.0012877998 +455 92 0.057092 +456 92 0.00018399999 +457 92 0.0013490999 +458 92 0.00049059978 +459 92 0.00024529989 +460 92 0.0016556999 +463 92 0.0075427964 +464 92 0.00018399999 +465 92 0.0054577999 +467 92 0.0082172975 +468 92 0.053473998 +469 92 0.0017170999 +470 92 0.0018396999 +471 92 0.0028208999 +473 92 6.1299987e-05 +477 92 6.1299987e-05 +478 92 0.00067459978 +483 92 0.0011037998 +489 92 0.00024529989 +490 92 0.0024528999 +491 92 0.00024529989 +0 93 0.0046974979 +1 93 0.0001777 +3 93 7.6199998e-05 +5 93 5.0799994e-05 +9 93 0.053576399 +10 93 2.539999e-05 +11 93 0.060482897 +12 93 0.00010159999 +13 93 0.00022849999 +14 93 0.00010159999 +16 93 0.015742797 +17 93 0.00096489978 +21 93 2.539999e-05 +22 93 0.0001777 +24 93 7.6199998e-05 +60 93 0.0026152998 +82 93 0.0047227964 +83 93 0.00012699999 +84 93 0.0012949998 +85 93 0.00022849999 +86 93 2.539999e-05 +87 93 0.00012699999 +88 93 0.00027929991 +90 93 0.0012695999 +93 93 0.0323998 +94 93 0.0075412989 +95 93 0.0021582998 +97 93 0.00020309999 +98 93 0.0018789999 +103 93 0.00012699999 +104 93 0.006804999 +105 93 0.00010159999 +107 93 0.025924899 +108 93 7.6199998e-05 +109 93 5.0799994e-05 +114 93 5.0799994e-05 +115 93 0.0018028 +116 93 0.0045450963 +117 93 2.539999e-05 +118 93 0.00033009984 +119 93 0.00010159999 +120 93 0.00012699999 +122 93 0.0035547998 +124 93 0.0006601999 +125 93 0.0029707998 +126 93 2.539999e-05 +150 93 0.00045699999 +151 93 2.539999e-05 +160 93 0.00048239995 +169 93 0.0010410999 +172 93 0.0020566999 +189 93 5.0799994e-05 +190 93 7.6199998e-05 +192 93 0.00091409986 +193 93 0.00045699999 +194 93 0.00010159999 +197 93 2.539999e-05 +198 93 0.015996698 +200 93 2.539999e-05 +203 93 5.0799994e-05 +204 93 0.018256597 +206 93 0.00063479994 +207 93 2.539999e-05 +214 93 0.0013203998 +218 93 5.0799994e-05 +223 93 0.00096489978 +224 93 5.0799994e-05 +228 93 2.539999e-05 +229 93 0.00083789998 +230 93 0.00053319987 +234 93 0.0027676998 +237 93 0.00025389995 +240 93 0.0014726999 +241 93 0.0060939975 +242 93 0.00093949982 +252 93 0.00010159999 +253 93 0.0412107 +272 93 0.00055859983 +277 93 5.0799994e-05 +279 93 7.6199998e-05 +300 93 0.12799937 +301 93 5.0799994e-05 +314 93 0.006982699 +325 93 0.0011171999 +340 93 2.539999e-05 +344 93 0.00048239995 +350 93 2.539999e-05 +351 93 0.0003554998 +356 93 7.6199998e-05 +358 93 0.00053319987 +366 93 0.0001523 +384 93 5.0799994e-05 +387 93 2.539999e-05 +394 93 2.539999e-05 +397 93 2.539999e-05 +402 93 0.00012699999 +414 93 0.00060939998 +422 93 7.6199998e-05 +430 93 2.539999e-05 +433 93 2.539999e-05 +434 93 2.539999e-05 +443 93 0.008937899 +444 93 0.00048239995 +445 93 0.055937797 +446 93 0.0022851999 +447 93 0.0031486 +448 93 5.0799994e-05 +450 93 0.0020058998 +452 93 0.0042911991 +453 93 0.0040626973 +454 93 0.0014726999 +455 93 0.074194372 +456 93 0.00030469988 +457 93 0.0013203998 +458 93 0.00063479994 +459 93 0.00038089999 +460 93 0.0017773998 +463 93 0.0087854974 +464 93 0.00022849999 +465 93 0.0040626973 +467 93 0.0091917999 +468 93 0.014092397 +469 93 0.0017519998 +470 93 0.0018535999 +471 93 0.0018789999 +473 93 5.0799994e-05 +477 93 2.539999e-05 +478 93 0.00076169986 +483 93 0.00081249978 +489 93 0.0001523 +490 93 0.0013964998 +491 93 0.00055859983 +3 94 0.00027609989 +5 94 0.0016562999 +6 94 0.00013799999 +9 94 0.017529298 +11 94 0.067632854 +13 94 0.00069009978 +14 94 0.00041409978 +16 94 0.0019323998 +17 94 0.00013799999 +18 94 0.011594199 +24 94 0.00027609989 +60 94 0.0019323998 +62 94 0.0012421999 +82 94 0.0011041998 +84 94 0.0005520999 +85 94 0.0011041998 +88 94 0.0030365998 +93 94 0.0005520999 +94 94 0.14837819 +95 94 0.0005520999 +97 94 0.00013799999 +98 94 0.0012421999 +104 94 0.0011041998 +105 94 0.00027609989 +107 94 0.0067632981 +114 94 0.00013799999 +115 94 0.00013799999 +116 94 0.0012421999 +118 94 0.00027609989 +122 94 0.0051069967 +125 94 0.0026224998 +153 94 0.00013799999 +154 94 0.00041409978 +172 94 0.0077294968 +192 94 0.010489997 +193 94 0.0093857981 +198 94 0.067080677 +204 94 0.015182897 +206 94 0.00027609989 +214 94 0.004140798 +215 94 0.019875798 +217 94 0.0044167973 +223 94 0.0015182998 +228 94 0.00013799999 +229 94 0.00069009978 +230 94 0.00041409978 +234 94 0.0063491985 +237 94 0.00069009978 +241 94 0.0092477985 +242 94 0.00041409978 +252 94 0.00013799999 +253 94 0.0042787977 +272 94 0.0005520999 +279 94 0.00069009978 +300 94 0.0016562999 +314 94 0.00082819979 +317 94 0.00013799999 +325 94 0.0099378973 +329 94 0.00082819979 +344 94 0.00027609989 +358 94 0.00041409978 +394 94 0.00013799999 +443 94 0.0097998977 +444 94 0.00013799999 +445 94 0.026362997 +446 94 0.0011041998 +447 94 0.0026224998 +448 94 0.00013799999 +450 94 0.0019323998 +452 94 0.0048308969 +453 94 0.0075913966 +454 94 0.0017942998 +455 94 0.065286398 +456 94 0.00096619991 +457 94 0.0019323998 +458 94 0.0005520999 +459 94 0.00027609989 +460 94 0.0022083998 +463 94 0.0066252984 +464 94 0.00041409978 +465 94 0.00096619991 +467 94 0.0267771 +468 94 0.033264298 +469 94 0.0017942998 +470 94 0.0017942998 +471 94 0.0017942998 +478 94 0.0005520999 +483 94 0.00041409978 +490 94 0.0016562999 +491 94 0.0022083998 +0 95 0.018136699 +3 95 0.00051329983 +5 95 8.5599997e-05 +9 95 0.0129181 +10 95 0.00017109999 +11 95 0.035332397 +12 95 0.00034219981 +13 95 0.0106938 +14 95 0.0021388 +16 95 0.00085549988 +17 95 0.00051329983 +22 95 0.00025669998 +60 95 0.0020531998 +82 95 0.0097527988 +83 95 8.5599997e-05 +84 95 0.0004278 +85 95 0.028402798 +86 95 8.5599997e-05 +87 95 0.014543597 +88 95 0.00059889979 +90 95 0.0053896978 +93 95 0.0022242998 +94 95 0.0015399 +95 95 0.016254596 +97 95 8.5599997e-05 +98 95 0.0011121999 +103 95 8.5599997e-05 +104 95 0.0073572993 +105 95 0.00025669998 +106 95 8.5599997e-05 +107 95 0.0269484 +108 95 0.00034219981 +109 95 0.00017109999 +112 95 8.5599997e-05 +114 95 0.00017109999 +115 95 0.00025669998 +116 95 0.00094109983 +117 95 0.0012832999 +118 95 0.0091538988 +119 95 0.0023953998 +122 95 0.11925739 +124 95 0.00034219981 +125 95 0.016938999 +126 95 8.5599997e-05 +130 95 8.5599997e-05 +150 95 8.5599997e-05 +151 95 8.5599997e-05 +169 95 8.5599997e-05 +172 95 8.5599997e-05 +189 95 8.5599997e-05 +190 95 8.5599997e-05 +192 95 0.0023098998 +193 95 0.010266099 +194 95 8.5599997e-05 +198 95 0.035161298 +204 95 0.0180512 +206 95 0.00017109999 +214 95 0.0014543999 +223 95 0.0014543999 +229 95 0.00085549988 +230 95 0.0004278 +231 95 8.5599997e-05 +234 95 0.001711 +237 95 0.00025669998 +240 95 8.5599997e-05 +241 95 0.016083498 +242 95 0.00094109983 +252 95 8.5599997e-05 +253 95 0.094875455 +272 95 0.00068439986 +277 95 8.5599997e-05 +279 95 0.0011976999 +300 95 0.013003699 +301 95 8.5599997e-05 +314 95 0.018906698 +317 95 8.5599997e-05 +325 95 0.00068439986 +326 95 8.5599997e-05 +340 95 8.5599997e-05 +344 95 0.00059889979 +350 95 8.5599997e-05 +351 95 8.5599997e-05 +356 95 8.5599997e-05 +358 95 0.0004278 +366 95 0.00017109999 +387 95 8.5599997e-05 +402 95 8.5599997e-05 +422 95 8.5599997e-05 +442 95 8.5599997e-05 +443 95 0.0082127973 +444 95 0.0004278 +445 95 0.0376422 +446 95 0.0011976999 +447 95 0.0032509 +450 95 0.0015399 +452 95 0.003422 +453 95 0.0021388 +454 95 0.004619699 +455 95 0.066472769 +456 95 8.5599997e-05 +457 95 0.0014543999 +458 95 0.00068439986 +459 95 0.00051329983 +460 95 0.0017965999 +463 95 0.012233697 +464 95 0.00025669998 +465 95 0.0036787 +467 95 0.0062451996 +468 95 0.065788269 +469 95 0.0020531998 +470 95 0.0022242998 +471 95 0.0016254999 +473 95 8.5599997e-05 +478 95 0.00051329983 +483 95 0.00076999981 +489 95 8.5599997e-05 +490 95 0.003422 +491 95 0.00025669998 +3 96 0.0285137 +9 96 0.0010110999 +11 96 0.0007077998 +17 96 0.49484324 +22 96 0.0002022 +60 96 0.0070778988 +82 96 0.00050559989 +84 96 0.00030329986 +91 96 0.0001011 +96 96 0.0077855997 +97 96 0.0001011 +98 96 0.0001011 +107 96 0.0001011 +114 96 0.0001011 +120 96 0.00050559989 +122 96 0.0059655979 +125 96 0.0001011 +126 96 0.0001011 +190 96 0.0001011 +192 96 0.0029322999 +193 96 0.013346799 +194 96 0.0001011 +198 96 0.021031298 +204 96 0.021132499 +206 96 0.0002022 +214 96 0.0015166998 +223 96 0.0007077998 +229 96 0.00040439982 +230 96 0.00060669985 +234 96 0.0028310998 +237 96 0.00030329986 +241 96 0.0038422998 +242 96 0.0045500994 +252 96 0.0001011 +272 96 0.00040439982 +277 96 0.0001011 +279 96 0.00040439982 +300 96 0.004752297 +301 96 0.0024267 +325 96 0.0035388998 +344 96 0.00050559989 +356 96 0.0001011 +358 96 0.00060669985 +366 96 0.0069766976 +384 96 0.0001011 +402 96 0.0001011 +422 96 0.0001011 +443 96 0.0026288999 +444 96 0.0030333998 +445 96 0.0052577965 +446 96 0.0002022 +447 96 0.0075833984 +450 96 0.0023255998 +452 96 0.0049544983 +453 96 0.00030329986 +454 96 0.00090999994 +455 96 0.12275028 +456 96 0.00030329986 +457 96 0.0012132998 +458 96 0.00080889999 +459 96 0.0002022 +460 96 0.0021233999 +463 96 0.0079878978 +464 96 0.00030329986 +465 96 0.0010110999 +467 96 0.0089989975 +468 96 0.0078867972 +469 96 0.0019210998 +470 96 0.0022244998 +471 96 0.0019210998 +473 96 0.0001011 +478 96 0.00080889999 +483 96 0.00060669985 +489 96 0.0001011 +490 96 0.0002022 +491 96 0.0012132998 +0 97 0.00035029999 +1 97 0.0016347999 +2 97 0.0019267998 +3 97 0.00011679999 +5 97 5.8399994e-05 +6 97 5.8399994e-05 +9 97 0.069860458 +10 97 0.00011679999 +11 97 0.049862798 +13 97 2.919999e-05 +14 97 8.7599998e-05 +16 97 0.00052549993 +17 97 0.0025106999 +24 97 2.919999e-05 +60 97 0.0020436 +82 97 0.038214497 +83 97 0.0036199999 +84 97 0.0235301 +85 97 8.7599998e-05 +86 97 2.919999e-05 +87 97 2.919999e-05 +88 97 0.00014599999 +90 97 8.7599998e-05 +93 97 0.0012552999 +94 97 0.00075899996 +95 97 8.7599998e-05 +96 97 2.919999e-05 +97 97 0.0060430989 +98 97 0.010480497 +100 97 8.7599998e-05 +102 97 2.919999e-05 +103 97 2.919999e-05 +104 97 0.00037949998 +105 97 0.0023939 +107 97 0.011502299 +108 97 0.0001752 +109 97 0.0011676999 +114 97 0.00011679999 +115 97 8.7599998e-05 +116 97 0.0022186998 +118 97 0.00011679999 +119 97 2.919999e-05 +120 97 5.8399994e-05 +122 97 0.017662197 +124 97 0.00011679999 +125 97 0.0057219975 +126 97 5.8399994e-05 +150 97 0.00040869997 +151 97 2.919999e-05 +160 97 2.919999e-05 +169 97 2.919999e-05 +172 97 5.8399994e-05 +189 97 5.8399994e-05 +190 97 8.7599998e-05 +192 97 0.014480099 +193 97 0.010714099 +194 97 8.7599998e-05 +197 97 2.919999e-05 +198 97 0.058650099 +200 97 2.919999e-05 +203 97 5.8399994e-05 +204 97 0.0047001988 +206 97 0.00011679999 +207 97 2.919999e-05 +214 97 0.0097214989 +218 97 2.919999e-05 +223 97 0.0012844999 +224 97 2.919999e-05 +228 97 2.919999e-05 +229 97 0.00037949998 +230 97 0.00058389991 +234 97 0.0028025999 +237 97 0.00026269979 +240 97 0.00043789996 +241 97 0.026974998 +242 97 0.00096339989 +252 97 8.7599998e-05 +253 97 0.0020436 +272 97 0.00081739994 +277 97 2.919999e-05 +300 97 0.019326199 +301 97 0.00090499991 +314 97 0.00035029999 +325 97 0.034156598 +340 97 0.00099259987 +344 97 0.0012844999 +350 97 0.00081739994 +351 97 0.0012260999 +356 97 5.8399994e-05 +358 97 0.00058389991 +366 97 0.0021894998 +384 97 2.919999e-05 +387 97 5.8399994e-05 +394 97 2.919999e-05 +397 97 2.919999e-05 +402 97 0.00011679999 +414 97 2.919999e-05 +422 97 8.7599998e-05 +433 97 2.919999e-05 +434 97 2.919999e-05 +443 97 0.0088456981 +444 97 0.00087579992 +445 97 0.057073597 +446 97 0.0024522999 +447 97 0.0038828 +448 97 2.919999e-05 +450 97 0.0021018998 +452 97 0.0071815997 +453 97 0.0032988999 +454 97 0.0028901999 +455 97 0.076691747 +456 97 0.00029189978 +457 97 0.0013428999 +458 97 0.00075899996 +459 97 0.0013136999 +460 97 0.0017807998 +463 97 0.0060430989 +464 97 0.0011968999 +465 97 0.0023355 +467 97 0.0078238994 +468 97 0.025310896 +469 97 0.0021018998 +470 97 0.0022186998 +471 97 0.002715 +472 97 0.00029189978 +473 97 5.8399994e-05 +477 97 5.8399994e-05 +478 97 0.00081739994 +483 97 0.0006130999 +489 97 0.0002044 +490 97 0.00037949998 +491 97 0.00035029999 +1 98 0.0003554998 +3 98 4.4399989e-05 +4 98 4.4399989e-05 +5 98 0.39633876 +6 98 0.053274699 +9 98 0.00026659993 +10 98 0.00022219999 +11 98 0.00031099981 +13 98 8.8899993e-05 +14 98 0.0059983991 +16 98 8.8899993e-05 +22 98 8.8899993e-05 +25 98 4.4399989e-05 +60 98 0.0023104998 +82 98 0.00044429977 +84 98 8.8899993e-05 +85 98 0.00044429977 +88 98 0.0026659998 +91 98 4.4399989e-05 +93 98 0.0001333 +94 98 4.4399989e-05 +98 98 0.018750597 +99 98 4.4399989e-05 +102 98 0.0033324 +103 98 0.00062209996 +104 98 0.0018661998 +105 98 4.4399989e-05 +107 98 0.010086197 +108 98 4.4399989e-05 +109 98 0.00062209996 +111 98 4.4399989e-05 +114 98 0.0001333 +116 98 0.0027547998 +117 98 0.00026659993 +118 98 0.005865097 +119 98 4.4399989e-05 +120 98 0.00097749988 +122 98 0.0034212999 +126 98 4.4399989e-05 +143 98 0.0011996999 +153 98 0.0052874982 +189 98 4.4399989e-05 +190 98 4.4399989e-05 +191 98 4.4399989e-05 +192 98 0.008442197 +193 98 0.017328698 +194 98 4.4399989e-05 +198 98 0.0039545 +204 98 8.8899993e-05 +206 98 0.00066649984 +214 98 0.0010664 +215 98 8.8899993e-05 +223 98 0.00053319987 +228 98 0.0025770999 +229 98 0.00044429977 +230 98 0.0001777 +234 98 0.0011996999 +237 98 0.0001333 +241 98 0.00026659993 +242 98 0.0023548999 +252 98 4.4399989e-05 +253 98 0.00026659993 +272 98 0.00026659993 +300 98 0.00084419991 +314 98 4.4399989e-05 +325 98 8.8899993e-05 +344 98 0.00053319987 +356 98 8.8899993e-05 +358 98 0.0001777 +384 98 4.4399989e-05 +387 98 4.4399989e-05 +402 98 8.8899993e-05 +414 98 0.0003998999 +422 98 4.4399989e-05 +430 98 4.4399989e-05 +443 98 0.0379899 +444 98 0.0022660999 +445 98 0.011730198 +446 98 0.004309997 +447 98 0.0060872994 +450 98 0.0017328998 +452 98 0.0065315999 +453 98 0.00084419991 +454 98 0.00022219999 +455 98 0.035634898 +456 98 0.0001777 +457 98 0.0018216998 +458 98 4.4399989e-05 +459 98 0.0004888 +460 98 0.0024438 +463 98 0.0025770999 +464 98 0.0022215999 +465 98 0.00044429977 +467 98 0.0078200996 +468 98 0.028036997 +469 98 0.0023993999 +470 98 0.0027547998 +471 98 0.0012884999 +473 98 8.8899993e-05 +477 98 4.4399989e-05 +478 98 0.00031099981 +483 98 0.00062209996 +489 98 4.4399989e-05 +490 98 0.00031099981 +491 98 0.00097749988 +0 99 0.00053259986 +3 99 0.00063909986 +5 99 0.081699967 +6 99 0.042181499 +9 99 0.00053259986 +10 99 0.0095866993 +11 99 0.0011717 +13 99 0.00074559986 +14 99 0.00074559986 +17 99 0.00031959987 +22 99 0.0001065 +60 99 0.0019172998 +82 99 0.0056454986 +84 99 0.0012782 +85 99 0.00042609987 +88 99 0.0063910969 +90 99 0.0001065 +91 99 0.00031959987 +93 99 0.00042609987 +94 99 0.00063909986 +98 99 0.023753699 +99 99 0.0014912998 +101 99 0.00021299999 +102 99 0.00085219997 +103 99 0.021623299 +104 99 0.0021303999 +105 99 0.00021299999 +106 99 0.0001065 +107 99 0.043566298 +108 99 0.00074559986 +109 99 0.00063909986 +114 99 0.00021299999 +115 99 0.00021299999 +118 99 0.0028759998 +120 99 0.0017042998 +122 99 0.0063910969 +124 99 0.00031959987 +125 99 0.00031959987 +126 99 0.0001065 +143 99 0.00053259986 +153 99 0.00042609987 +192 99 0.016510397 +193 99 0.009480197 +194 99 0.0001065 +198 99 0.0498509 +204 99 0.00074559986 +206 99 0.00021299999 +214 99 0.00095869997 +223 99 0.00053259986 +228 99 0.0060715973 +229 99 0.00021299999 +230 99 0.00031959987 +234 99 0.0025564998 +237 99 0.00031959987 +241 99 0.010545399 +242 99 0.0025564998 +252 99 0.0001065 +253 99 0.0013846999 +272 99 0.00042609987 +277 99 0.00021299999 +300 99 0.0087345988 +314 99 0.00031959987 +325 99 0.0038347 +344 99 0.00031959987 +356 99 0.0001065 +358 99 0.00031959987 +387 99 0.0001065 +402 99 0.0001065 +443 99 0.019279897 +444 99 0.0014912998 +445 99 0.012782298 +446 99 0.0020238999 +447 99 0.0054324977 +450 99 0.0015977998 +452 99 0.0047933981 +453 99 0.0025564998 +454 99 0.00063909986 +455 99 0.037707698 +456 99 0.00031959987 +457 99 0.0025564998 +458 99 0.00021299999 +459 99 0.0033020999 +460 99 0.0026629998 +463 99 0.0027694998 +464 99 0.00042609987 +465 99 0.004473798 +467 99 0.0046867989 +468 99 0.097358286 +469 99 0.0031955999 +470 99 0.0033020999 +471 99 0.0021303999 +473 99 0.0001065 +478 99 0.00042609987 +483 99 0.00063909986 +489 99 0.0001065 +490 99 0.0013846999 +491 99 0.00063909986 +0 100 0.0015001998 +3 100 0.00024999981 +5 100 0.13676709 +6 100 0.015126899 +9 100 0.00062509999 +10 100 0.0012502 +11 100 0.0015001998 +13 100 0.00037499983 +14 100 0.00050009997 +17 100 0.00012499999 +60 100 0.0018751998 +82 100 0.0028753998 +84 100 0.00050009997 +85 100 0.0041254982 +88 100 0.025878198 +90 100 0.00037499983 +93 100 0.00062509999 +94 100 0.00087509979 +98 100 0.074884355 +99 100 0.00024999981 +102 100 0.00024999981 +103 100 0.0031253998 +104 100 0.013626698 +105 100 0.00024999981 +107 100 0.057257198 +108 100 0.0050005987 +109 100 0.0056256987 +114 100 0.00024999981 +115 100 0.00012499999 +116 100 0.00062509999 +118 100 0.0080009997 +120 100 0.00037499983 +122 100 0.0221278 +124 100 0.00050009997 +125 100 0.00062509999 +126 100 0.00012499999 +143 100 0.00037499983 +153 100 0.0011250998 +192 100 0.012501597 +193 100 0.013751697 +198 100 0.058382299 +204 100 0.00062509999 +206 100 0.00037499983 +214 100 0.0038754998 +223 100 0.00062509999 +228 100 0.0011250998 +229 100 0.00037499983 +230 100 0.00024999981 +231 100 0.00024999981 +232 100 0.00012499999 +234 100 0.0020003 +237 100 0.00024999981 +241 100 0.012126498 +242 100 0.0025002998 +252 100 0.00012499999 +253 100 0.0016251998 +272 100 0.00050009997 +300 100 0.0071258992 +314 100 0.00050009997 +325 100 0.0032503998 +344 100 0.00050009997 +356 100 0.00012499999 +358 100 0.00024999981 +387 100 0.00012499999 +402 100 0.00012499999 +414 100 0.00012499999 +443 100 0.021252699 +444 100 0.00075009977 +445 100 0.013376698 +446 100 0.0017501998 +447 100 0.0061257966 +450 100 0.0015001998 +452 100 0.0042504966 +453 100 0.0011250998 +454 100 0.00050009997 +455 100 0.0426303 +456 100 0.00024999981 +457 100 0.0022502998 +458 100 0.00012499999 +459 100 0.0010000998 +460 100 0.0027502999 +463 100 0.0053756982 +464 100 0.00075009977 +465 100 0.0056256987 +467 100 0.0052506998 +468 100 0.030628797 +469 100 0.0040004998 +470 100 0.0042504966 +471 100 0.0018751998 +473 100 0.00012499999 +478 100 0.00050009997 +483 100 0.00075009977 +490 100 0.0012502 +491 100 0.00024999981 +1 101 0.00034169992 +2 101 0.0030756998 +3 101 0.0053994991 +5 101 0.005331099 +6 101 0.036839597 +9 101 0.00047839992 +11 101 0.00054679997 +12 101 6.8299996e-05 +13 101 0.0092952996 +16 101 6.8299996e-05 +17 101 0.012165897 +22 101 6.8299996e-05 +24 101 6.8299996e-05 +25 101 0.00027339999 +60 101 0.0017769998 +82 101 0.11195409 +84 101 0.027407598 +85 101 6.8299996e-05 +88 101 0.0021187998 +91 101 0.0071081966 +93 101 0.00013669999 +94 101 6.8299996e-05 +98 101 0.0134646 +101 101 0.0041691996 +102 101 0.020914499 +103 101 0.0018453998 +104 101 0.0056728981 +107 101 0.0095686987 +111 101 0.00047839992 +112 101 0.00034169992 +114 101 0.00082019996 +116 101 6.8299996e-05 +117 101 0.0020503998 +118 101 0.049073897 +119 101 0.00034169992 +120 101 0.045178 +122 101 0.0007517999 +125 101 0.00041009998 +143 101 0.00082019996 +153 101 0.00041009998 +189 101 6.8299996e-05 +192 101 0.00013669999 +193 101 0.018043898 +194 101 6.8299996e-05 +198 101 0.023306698 +204 101 0.0069714971 +206 101 0.00013669999 +214 101 0.0047843978 +215 101 0.0013669999 +223 101 0.0013669999 +228 101 0.013942998 +229 101 0.00034169992 +230 101 0.00027339999 +231 101 0.00013669999 +232 101 6.8299996e-05 +234 101 0.0019820998 +237 101 0.00020499999 +240 101 6.8299996e-05 +241 101 0.0037590999 +242 101 0.0033490998 +252 101 6.8299996e-05 +253 101 0.00034169992 +272 101 0.00082019996 +277 101 0.00013669999 +300 101 0.06855309 +314 101 6.8299996e-05 +325 101 0.00013669999 +344 101 0.00034169992 +356 101 6.8299996e-05 +358 101 0.00020499999 +402 101 6.8299996e-05 +422 101 6.8299996e-05 +443 101 0.010115497 +444 101 0.0010935999 +445 101 0.012917798 +446 101 0.0012302999 +447 101 0.0038274999 +450 101 0.0013669999 +452 101 0.0048526973 +453 101 0.0033490998 +454 101 0.0008884999 +455 101 0.054063298 +456 101 0.00020499999 +457 101 0.0018453998 +458 101 0.00054679997 +459 101 0.0007517999 +460 101 0.0025288998 +463 101 0.0038274999 +464 101 0.00013669999 +465 101 0.00041009998 +467 101 0.0052627996 +468 101 0.058300897 +469 101 0.00068349997 +470 101 0.00068349997 +471 101 0.0015719999 +478 101 0.00034169992 +483 101 0.00068349997 +489 101 6.8299996e-05 +490 101 6.8299996e-05 +491 101 0.00034169992 +0 102 8.4199986e-05 +1 102 0.00060659996 +2 102 0.0006571 +3 102 3.3699995e-05 +4 102 0.00021899999 +5 102 0.010412797 +6 102 0.12756526 +9 102 6.7399989e-05 +10 102 1.6799997e-05 +11 102 5.0499992e-05 +13 102 6.7399989e-05 +14 102 0.011322699 +17 102 3.3699995e-05 +22 102 8.4199986e-05 +24 102 0.00084249978 +25 102 0.0006571 +60 102 0.0013647999 +82 102 0.00092669996 +84 102 0.00025269995 +88 102 0.0071608983 +90 102 1.6799997e-05 +91 102 5.0499992e-05 +93 102 0.00016849999 +98 102 0.040438097 +101 102 3.3699995e-05 +102 102 0.19804549 +103 102 0.0059308968 +104 102 0.012620099 +107 102 0.015534997 +108 102 1.6799997e-05 +111 102 0.0031339999 +112 102 0.0010277999 +114 102 0.0017859999 +116 102 1.6799997e-05 +117 102 0.016882896 +118 102 0.12475145 +119 102 0.0031675999 +120 102 0.050648697 +122 102 6.7399989e-05 +125 102 0.00047179987 +126 102 1.6799997e-05 +143 102 0.0014489999 +151 102 1.6799997e-05 +153 102 0.0018533999 +189 102 5.0499992e-05 +190 102 1.6799997e-05 +192 102 0.00013479999 +193 102 0.0064194985 +194 102 1.6799997e-05 +198 102 0.00050549977 +200 102 1.6799997e-05 +203 102 1.6799997e-05 +204 102 6.7399989e-05 +206 102 5.0499992e-05 +207 102 1.6799997e-05 +214 102 0.008744698 +215 102 0.0059140995 +217 102 1.6799997e-05 +218 102 1.6799997e-05 +223 102 0.0013142 +228 102 0.033058099 +229 102 0.00038749981 +230 102 0.0001853 +234 102 0.0016343999 +237 102 0.0001853 +241 102 0.0001179 +242 102 0.00084249978 +252 102 5.0499992e-05 +253 102 1.6799997e-05 +272 102 0.00023589999 +277 102 3.3699995e-05 +300 102 0.00053919991 +301 102 1.6799997e-05 +324 102 8.4199986e-05 +325 102 3.3699995e-05 +344 102 0.00043809996 +356 102 6.7399989e-05 +358 102 0.0001853 +384 102 1.6799997e-05 +387 102 1.6799997e-05 +394 102 1.6799997e-05 +397 102 1.6799997e-05 +402 102 8.4199986e-05 +422 102 1.6799997e-05 +433 102 1.6799997e-05 +434 102 1.6799997e-05 +443 102 0.030210599 +444 102 0.00089299981 +445 102 0.013513099 +446 102 0.0031507998 +447 102 0.00094359997 +448 102 3.3699995e-05 +450 102 0.00094359997 +452 102 0.0041280985 +453 102 0.0027126998 +454 102 0.0001011 +455 102 0.063875258 +456 102 0.0002022 +457 102 0.0022745999 +458 102 0.00025269995 +459 102 0.0012973999 +460 102 0.0020050998 +463 102 0.0025104999 +464 102 0.00015159999 +465 102 0.00032009999 +467 102 0.006924998 +468 102 0.0045323968 +469 102 0.00074139982 +470 102 0.00072449981 +471 102 0.0016848999 +473 102 1.6799997e-05 +477 102 3.3699995e-05 +478 102 0.00026959996 +483 102 0.00092669996 +489 102 5.0499992e-05 +490 102 6.7399989e-05 +491 102 0.00025269995 +5 103 0.58880275 +60 103 0.0017541 +88 103 0.00014619999 +98 103 0.0002923999 +103 103 0.0029234998 +107 103 0.0002923999 +114 103 0.00014619999 +122 103 0.00014619999 +126 103 0.00014619999 +153 103 0.014763899 +193 103 0.014617696 +198 103 0.012571298 +204 103 0.00014619999 +206 103 0.00014619999 +229 103 0.00043849996 +230 103 0.00014619999 +234 103 0.00043849996 +237 103 0.00014619999 +241 103 0.00014619999 +242 103 0.0057008974 +253 103 0.0002923999 +272 103 0.00014619999 +279 103 0.0002923999 +300 103 0.00087709981 +344 103 0.00058469991 +356 103 0.00014619999 +358 103 0.00014619999 +414 103 0.0002923999 +443 103 0.0024849998 +444 103 0.0039467998 +445 103 0.024996299 +446 103 0.0055546984 +447 103 0.0065779984 +450 103 0.00073089986 +452 103 0.0032158999 +453 103 0.0011693998 +454 103 0.00058469991 +455 103 0.10261655 +457 103 0.0017541 +458 103 0.00014619999 +459 103 0.0002923999 +460 103 0.0024849998 +463 103 0.0019002999 +464 103 0.0002923999 +465 103 0.004677698 +467 103 0.0029234998 +468 103 0.013009798 +469 103 0.0020464999 +470 103 0.0023387999 +471 103 0.00087709981 +473 103 0.00014619999 +478 103 0.00014619999 +483 103 0.00043849996 +490 103 0.0073088966 +491 103 0.011694197 +5 104 0.020244498 +6 104 0.35014009 +13 104 0.00012729999 +14 104 0.0025464999 +21 104 0.00012729999 +22 104 0.0076393969 +24 104 0.00038199988 +60 104 0.0061114989 +82 104 0.0036923999 +98 104 0.00025459984 +104 104 0.0418895 +107 104 0.00012729999 +108 104 0.00012729999 +114 104 0.00012729999 +119 104 0.00012729999 +120 104 0.0005092998 +126 104 0.00012729999 +153 104 0.00012729999 +189 104 0.00012729999 +192 104 0.00012729999 +193 104 0.0005092998 +194 104 0.00012729999 +198 104 0.020881098 +204 104 0.0057295971 +206 104 0.00025459984 +214 104 0.0020371999 +218 104 0.00038199988 +223 104 0.00025459984 +224 104 0.00025459984 +229 104 0.00038199988 +230 104 0.00038199988 +231 104 0.00012729999 +234 104 0.0034377 +237 104 0.00038199988 +241 104 0.00012729999 +242 104 0.00012729999 +252 104 0.00012729999 +272 104 0.0014006 +279 104 0.0005092998 +301 104 0.00025459984 +344 104 0.00038199988 +356 104 0.00012729999 +358 104 0.00038199988 +384 104 0.00012729999 +387 104 0.00012729999 +402 104 0.00012729999 +414 104 0.00089129992 +430 104 0.00012729999 +443 104 0.031448897 +444 104 0.00025459984 +445 104 0.0076393969 +446 104 0.0049655996 +447 104 0.00089129992 +450 104 0.0019099 +452 104 0.010822497 +453 104 0.017443299 +454 104 0.0029283999 +455 104 0.0537306 +456 104 0.0005092998 +457 104 0.0019099 +458 104 0.00076389988 +459 104 0.00089129992 +460 104 0.0029283999 +463 104 0.0021644998 +464 104 0.00038199988 +465 104 0.00063659996 +467 104 0.0099311993 +468 104 0.0031830999 +469 104 0.006366197 +470 104 0.0068754964 +471 104 0.0021644998 +473 104 0.00012729999 +478 104 0.00063659996 +483 104 0.0010185998 +489 104 0.00089129992 +490 104 0.00063659996 +491 104 0.0019099 +0 105 0.0006465998 +5 105 0.0020903 +6 105 0.00070679979 +9 105 0.00010529999 +10 105 0.004180599 +11 105 7.5199991e-05 +14 105 0.00042109983 +22 105 1.5e-05 +60 105 0.0036843999 +82 105 0.0055941977 +83 105 1.5e-05 +84 105 4.5099994e-05 +85 105 0.0062709972 +86 105 3.0099996e-05 +87 105 0.0039550997 +88 105 0.0076845996 +90 105 0.00018049999 +93 105 0.0037596 +94 105 0.0031579998 +97 105 0.0032031999 +98 105 0.11024559 +100 105 0.012256198 +103 105 0.00063159992 +104 105 0.0066318996 +105 105 0.0075341985 +106 105 0.00027069985 +107 105 0.032753397 +108 105 1.5e-05 +109 105 0.00061659981 +113 105 3.0099996e-05 +114 105 4.5099994e-05 +116 105 0.0035189998 +118 105 0.0014285999 +119 105 0.00055639981 +122 105 0.017639898 +125 105 0.013474297 +126 105 1.5e-05 +150 105 0.00093239988 +189 105 0.00022559999 +190 105 9.0199988e-05 +192 105 0.0009474 +193 105 0.012481797 +194 105 9.0199988e-05 +196 105 1.5e-05 +197 105 3.0099996e-05 +198 105 0.018331699 +200 105 4.5099994e-05 +201 105 1.5e-05 +203 105 7.5199991e-05 +204 105 0.013233699 +206 105 0.00025569997 +207 105 6.0199993e-05 +209 105 1.5e-05 +214 105 0.0063761994 +218 105 1.5e-05 +223 105 0.00034589996 +228 105 0.0024812999 +229 105 0.00016539999 +230 105 0.00072179991 +234 105 0.0048723966 +237 105 0.00076699979 +241 105 0.020542298 +242 105 0.0006616998 +252 105 3.0099996e-05 +253 105 1.5e-05 +272 105 0.00052629993 +279 105 0.00036089984 +284 105 3.0099996e-05 +300 105 4.5099994e-05 +317 105 1.5e-05 +325 105 0.0023759999 +340 105 0.00025569997 +344 105 0.00048119994 +356 105 6.0199993e-05 +358 105 0.00063159992 +384 105 3.0099996e-05 +387 105 1.5e-05 +394 105 4.5099994e-05 +397 105 3.0099996e-05 +402 105 0.00028569996 +422 105 7.5199991e-05 +423 105 1.5e-05 +430 105 1.5e-05 +431 105 3.0099996e-05 +432 105 1.5e-05 +433 105 3.0099996e-05 +434 105 6.0199993e-05 +443 105 0.012557 +444 105 0.00045109983 +445 105 0.0090379976 +446 105 0.0008270999 +447 105 0.0020601999 +448 105 0.00010529999 +450 105 0.0057445988 +452 105 0.0041354969 +453 105 0.0030377 +454 105 0.00054139993 +455 105 0.032557897 +456 105 0.0010527 +457 105 0.0031880999 +458 105 0.00037599984 +459 105 0.00085719978 +460 105 0.0015940999 +463 105 0.0077897981 +464 105 0.00060149981 +465 105 0.0032782999 +467 105 0.010496698 +468 105 0.013684798 +469 105 0.009519197 +470 105 0.0016391999 +471 105 0.0088725984 +473 105 4.5099994e-05 +477 105 6.0199993e-05 +478 105 0.0013533998 +483 105 0.0028873 +489 105 0.00022559999 +490 105 0.0016541998 +491 105 3.0099996e-05 +3 106 0.00012139999 +5 106 0.0021237 +6 106 0.0010314998 +9 106 0.0011527999 +10 106 0.0011527999 +11 106 0.0002427 +13 106 0.0002427 +14 106 0.00072809984 +22 106 0.00012139999 +60 106 0.0029123998 +82 106 0.012256499 +85 106 0.0029730999 +87 106 6.0699997e-05 +88 106 0.0024269999 +93 106 6.0699997e-05 +94 106 6.0699997e-05 +97 106 6.0699997e-05 +98 106 0.085917056 +100 106 0.0026697 +103 106 0.00030339998 +104 106 0.014683597 +105 106 0.0040045977 +106 106 0.00030339998 +107 106 0.0461744 +108 106 0.0014561999 +109 106 0.024634399 +114 106 6.0699997e-05 +116 106 0.0050967969 +118 106 0.0052787997 +122 106 0.028092999 +125 106 0.0079484992 +126 106 6.0699997e-05 +189 106 6.0699997e-05 +190 106 6.0699997e-05 +192 106 0.0058855973 +193 106 0.0074630976 +194 106 6.0699997e-05 +198 106 0.054062299 +200 106 6.0699997e-05 +203 106 6.0699997e-05 +204 106 0.017049897 +206 106 0.0002427 +207 106 6.0699997e-05 +214 106 0.0081305988 +223 106 0.00066739996 +228 106 0.0020629999 +229 106 0.00018199999 +230 106 0.00060679996 +234 106 0.0038832999 +237 106 0.00060679996 +241 106 0.020144399 +242 106 0.00012139999 +253 106 0.0002427 +272 106 0.00042469986 +277 106 6.0699997e-05 +279 106 0.00066739996 +300 106 0.0002427 +314 106 6.0699997e-05 +325 106 0.0019415999 +344 106 0.00030339998 +356 106 6.0699997e-05 +358 106 0.00054609985 +394 106 6.0699997e-05 +402 106 0.0002427 +422 106 6.0699997e-05 +433 106 6.0699997e-05 +434 106 6.0699997e-05 +443 106 0.011649799 +444 106 0.00012139999 +445 106 0.0090406984 +446 106 0.00072809984 +447 106 0.0014561999 +448 106 6.0699997e-05 +450 106 0.0023057 +452 106 0.0037011998 +453 106 0.0030944999 +454 106 0.00048539997 +455 106 0.0364662 +456 106 0.00066739996 +457 106 0.0020023 +458 106 0.00048539997 +459 106 0.00036409986 +460 106 0.0016988998 +463 106 0.0157151 +464 106 0.00012139999 +465 106 0.0043079965 +467 106 0.014440898 +468 106 0.013652097 +469 106 0.0013348998 +470 106 0.0014561999 +471 106 0.0041259974 +473 106 6.0699997e-05 +477 106 6.0699997e-05 +478 106 0.00066739996 +483 106 0.00097079994 +489 106 0.00018199999 +490 106 0.00060679996 +5 107 3.119999e-05 +11 107 3.119999e-05 +12 107 0.22531909 +18 107 3.119999e-05 +22 107 0.0014044999 +24 107 0.00059299986 +60 107 0.0024656998 +85 107 3.119999e-05 +88 107 3.119999e-05 +93 107 0.00012479999 +95 107 3.119999e-05 +98 107 3.119999e-05 +104 107 0.00053059985 +107 107 0.36892539 +108 107 3.119999e-05 +112 107 3.119999e-05 +113 107 3.119999e-05 +114 107 9.36e-05 +115 107 6.2399995e-05 +116 107 0.00062419986 +118 107 9.36e-05 +119 107 3.119999e-05 +122 107 0.00012479999 +125 107 3.119999e-05 +126 107 3.119999e-05 +150 107 3.119999e-05 +151 107 0.00068669999 +189 107 0.00012479999 +190 107 3.119999e-05 +193 107 0.0058053993 +194 107 6.2399995e-05 +198 107 0.0039950982 +200 107 3.119999e-05 +203 107 3.119999e-05 +204 107 0.0001561 +206 107 6.2399995e-05 +214 107 0.0034957 +215 107 6.2399995e-05 +223 107 0.00024969992 +228 107 6.2399995e-05 +229 107 0.00040579983 +230 107 0.00018729999 +234 107 0.0043696985 +237 107 0.00018729999 +241 107 3.119999e-05 +242 107 0.0011547999 +252 107 6.2399995e-05 +253 107 0.00040579983 +267 107 0.0040575974 +272 107 0.00056179985 +277 107 0.0012484998 +279 107 0.00012479999 +300 107 0.0001561 +301 107 0.00056179985 +314 107 6.2399995e-05 +324 107 0.00021849999 +344 107 0.00046819984 +350 107 0.0017166999 +356 107 6.2399995e-05 +358 107 0.00037449994 +384 107 3.119999e-05 +387 107 3.119999e-05 +402 107 9.36e-05 +422 107 6.2399995e-05 +434 107 3.119999e-05 +443 107 0.013358697 +444 107 0.0016853998 +445 107 0.0134211 +446 107 0.00034329994 +447 107 0.00099879992 +450 107 0.0011547999 +452 107 0.0019351 +453 107 0.010362398 +454 107 0.0025281999 +455 107 0.028434098 +456 107 0.00028089993 +457 107 0.0044008978 +458 107 0.00040579983 +459 107 0.00037449994 +460 107 0.00024969992 +463 107 0.0035581999 +464 107 0.0013732999 +465 107 0.00040579983 +467 107 0.0042447969 +468 107 0.0046817996 +469 107 0.0035269998 +470 107 0.0010611999 +471 107 0.0014044999 +473 107 3.119999e-05 +477 107 3.119999e-05 +478 107 0.00034329994 +483 107 0.00031209993 +489 107 0.00056179985 +490 107 0.00021849999 +491 107 6.2399995e-05 +0 108 0.00015159999 +3 108 0.0002274 +5 108 7.5799995e-05 +9 108 0.00041679991 +10 108 0.054111399 +11 108 0.00064419978 +13 108 0.0032587999 +14 108 0.027927198 +16 108 3.7899998e-05 +17 108 3.7899998e-05 +22 108 0.00018949999 +60 108 0.0023872999 +82 108 0.00041679991 +85 108 7.5799995e-05 +86 108 0.0019703999 +88 108 0.019439198 +90 108 3.7899998e-05 +93 108 0.00045469985 +94 108 7.5799995e-05 +95 108 3.7899998e-05 +98 108 0.00037889997 +104 108 0.015460398 +105 108 0.00015159999 +106 108 3.7899998e-05 +107 108 0.066881359 +108 108 0.083175361 +109 108 0.053164098 +110 108 0.00079579977 +112 108 3.7899998e-05 +114 108 7.5799995e-05 +115 108 3.7899998e-05 +116 108 0.030503999 +118 108 0.00037889997 +119 108 7.5799995e-05 +122 108 0.0039408989 +124 108 3.7899998e-05 +125 108 0.0053807981 +126 108 3.7899998e-05 +150 108 0.00049259979 +151 108 3.7899998e-05 +189 108 0.00011369999 +190 108 7.5799995e-05 +192 108 0.011746898 +193 108 0.0022356999 +194 108 0.00011369999 +197 108 3.7899998e-05 +198 108 0.040394098 +200 108 3.7899998e-05 +203 108 7.5799995e-05 +204 108 0.0025008998 +206 108 0.00049259979 +207 108 3.7899998e-05 +214 108 0.00060629984 +223 108 0.0012125999 +229 108 0.00030309986 +230 108 0.00060629984 +231 108 0.0002274 +234 108 0.0023494 +237 108 0.0002274 +241 108 0.010647997 +242 108 0.00015159999 +252 108 7.5799995e-05 +253 108 0.0025766999 +272 108 0.00049259979 +277 108 3.7899998e-05 +279 108 0.00068209996 +300 108 0.011367898 +301 108 0.00011369999 +314 108 0.00064419978 +324 108 0.00018949999 +325 108 0.0061007999 +344 108 0.00037889997 +356 108 7.5799995e-05 +358 108 0.00071999989 +384 108 3.7899998e-05 +387 108 3.7899998e-05 +402 108 0.00011369999 +414 108 0.00026529981 +422 108 0.00011369999 +430 108 3.7899998e-05 +433 108 3.7899998e-05 +434 108 3.7899998e-05 +443 108 0.0087911971 +444 108 0.00026529981 +445 108 0.012959499 +446 108 0.0013263 +447 108 0.00079579977 +448 108 3.7899998e-05 +450 108 0.0023494 +452 108 0.0053807981 +453 108 0.0018189 +454 108 0.00037889997 +455 108 0.061424799 +456 108 0.0003409998 +457 108 0.0024251998 +458 108 0.00037889997 +459 108 0.00045469985 +460 108 0.0016293998 +463 108 0.005342897 +464 108 0.00018949999 +465 108 0.0020082998 +467 108 0.0153846 +468 108 0.033383898 +469 108 0.0027282999 +470 108 0.0030314999 +471 108 0.0017051999 +473 108 7.5799995e-05 +477 108 3.7899998e-05 +478 108 0.00079579977 +479 108 0.00018949999 +483 108 0.0014777998 +489 108 7.5799995e-05 +490 108 0.027775697 +491 108 0.00026529981 +3 109 0.0030345998 +5 109 0.0030345998 +9 109 0.0030345998 +10 109 0.0064737983 +11 109 0.0046529993 +13 109 0.0032368999 +14 109 0.0072829984 +17 109 0.00040459982 +22 109 0.00060689985 +60 109 0.0022253999 +85 109 0.0002023 +86 109 0.012542997 +88 109 0.033380497 +98 109 0.0046529993 +104 109 0.020432897 +105 109 0.0014161 +106 109 0.00040459982 +107 109 0.087396264 +108 109 0.015375298 +109 109 0.074044049 +113 109 0.0002023 +114 109 0.0002023 +115 109 0.00040459982 +116 109 0.00060689985 +117 109 0.0002023 +118 109 0.00080919988 +119 109 0.00040459982 +122 109 0.0093060993 +125 109 0.0024277 +191 109 0.0002023 +192 109 0.0036414999 +193 109 0.0020230999 +198 109 0.038235899 +204 109 0.0052599981 +206 109 0.0002023 +214 109 0.0022253999 +223 109 0.0028322998 +229 109 0.0002023 +230 109 0.0002023 +234 109 0.0016184999 +237 109 0.0002023 +241 109 0.013352197 +242 109 0.00040459982 +253 109 0.0030345998 +272 109 0.00060689985 +279 109 0.00060689985 +300 109 0.023669798 +301 109 0.00080919988 +314 109 0.00080919988 +324 109 0.0002023 +325 109 0.0056645982 +344 109 0.00060689985 +356 109 0.0002023 +358 109 0.00060689985 +443 109 0.012947597 +444 109 0.00040459982 +445 109 0.014970697 +446 109 0.0028322998 +447 109 0.0016184999 +450 109 0.0014161 +452 109 0.0058668964 +453 109 0.0016184999 +454 109 0.00040459982 +455 109 0.066154182 +456 109 0.00040459982 +457 109 0.0026299998 +458 109 0.0002023 +459 109 0.00040459982 +460 109 0.0020230999 +463 109 0.0044506975 +464 109 0.0002023 +465 109 0.0016184999 +467 109 0.0226583 +468 109 0.027311299 +469 109 0.0022253999 +470 109 0.0022253999 +471 109 0.0016184999 +478 109 0.00060689985 +483 109 0.00080919988 +489 109 0.0002023 +490 109 0.16710496 +491 109 0.0002023 +10 110 0.0034111999 +13 110 0.0002623999 +14 110 0.0015743999 +60 110 0.0031488 +82 110 0.0002623999 +88 110 0.00078719994 +102 110 0.0002623999 +104 110 0.023091096 +107 110 0.055890799 +108 110 0.004985597 +109 110 0.002624 +110 110 0.073996246 +114 110 0.0002623999 +116 110 0.050642896 +118 110 0.0057727993 +122 110 0.0002623999 +125 110 0.0002623999 +192 110 0.0028863999 +193 110 0.0020991999 +198 110 0.048281297 +204 110 0.015481498 +206 110 0.00052479981 +214 110 0.0023615998 +223 110 0.0002623999 +228 110 0.0041983984 +230 110 0.00052479981 +234 110 0.0055103973 +237 110 0.0002623999 +241 110 0.012070298 +253 110 0.0010495998 +272 110 0.0010495998 +279 110 0.00078719994 +300 110 0.00078719994 +314 110 0.0002623999 +324 110 0.0002623999 +325 110 0.0057727993 +344 110 0.0002623999 +358 110 0.00052479981 +443 110 0.0057727993 +444 110 0.0070847981 +445 110 0.0073471963 +446 110 0.001312 +447 110 0.012070298 +450 110 0.0020991999 +452 110 0.0047231987 +453 110 0.00052479981 +454 110 0.00078719994 +455 110 0.031750198 +457 110 0.0023615998 +459 110 0.00078719994 +460 110 0.0010495998 +463 110 0.0028863999 +464 110 0.00052479981 +465 110 0.010233499 +467 110 0.0083966963 +468 110 0.047756497 +469 110 0.0034111999 +470 110 0.0036735998 +471 110 0.0010495998 +477 110 0.0002623999 +478 110 0.00078719994 +483 110 0.0015743999 +490 110 0.014431898 +491 110 0.0002623999 +5 111 0.0064279996 +6 111 0.012103099 +13 111 0.0072193965 +22 111 0.00021229999 +60 111 0.0038798999 +82 111 1.9299987e-05 +98 111 0.0092654973 +103 111 0.0063120984 +104 111 0.002104 +107 111 0.0010616998 +108 111 1.9299987e-05 +111 111 0.0027796999 +112 111 0.035575699 +113 111 3.8599988e-05 +114 111 0.00086859986 +116 111 7.7199991e-05 +118 111 3.8599988e-05 +125 111 0.0008299998 +126 111 1.9299987e-05 +151 111 1.9299987e-05 +189 111 3.8599988e-05 +190 111 3.8599988e-05 +192 111 0.0014862998 +194 111 5.789999e-05 +197 111 1.9299987e-05 +198 111 0.0283756 +200 111 1.9299987e-05 +203 111 3.8599988e-05 +204 111 0.0051731989 +206 111 0.00021229999 +207 111 1.9299987e-05 +214 111 0.00030889991 +218 111 1.9299987e-05 +223 111 1.9299987e-05 +229 111 0.00067559979 +230 111 0.0001737 +234 111 0.0025672999 +237 111 0.00021229999 +241 111 0.0008299998 +242 111 0.00055979984 +252 111 5.789999e-05 +253 111 0.0545507 +272 111 0.0005983999 +277 111 5.789999e-05 +279 111 0.00069489982 +300 111 0.22260398 +314 111 0.0065437965 +324 111 0.00030889991 +344 111 0.00027019996 +350 111 0.00079139997 +356 111 5.789999e-05 +358 111 0.00034749997 +384 111 5.789999e-05 +387 111 1.9299987e-05 +394 111 1.9299987e-05 +402 111 7.7199991e-05 +422 111 5.789999e-05 +430 111 1.9299987e-05 +433 111 1.9299987e-05 +434 111 1.9299987e-05 +443 111 0.0065437965 +444 111 0.00086859986 +445 111 0.0078177974 +446 111 0.00065629999 +447 111 0.00027019996 +448 111 1.9299987e-05 +450 111 0.0012353999 +452 111 0.0037061998 +453 111 0.0023549998 +454 111 0.0020653999 +455 111 0.0219284 +456 111 0.00032819994 +457 111 0.0034938999 +458 111 0.00032819994 +459 111 0.0003668 +460 111 0.00023159999 +463 111 0.0025479998 +464 111 0.0001351 +465 111 0.0014283999 +467 111 0.0054241978 +468 111 0.043547899 +469 111 0.0070649981 +470 111 0.0013897999 +471 111 0.0031849998 +473 111 3.8599988e-05 +477 111 1.9299987e-05 +478 111 0.00034749997 +483 111 0.00052119978 +489 111 0.0001351 +490 111 0.00011579999 +491 111 1.9299987e-05 +5 112 0.020178299 +6 112 0.49460346 +22 112 0.00046929996 +60 112 0.0065696985 +111 112 0.00046929996 +112 112 0.014077898 +114 112 0.00046929996 +116 112 0.00046929996 +198 112 0.0014077998 +229 112 0.00093849981 +234 112 0.0018771 +253 112 0.00046929996 +272 112 0.00093849981 +277 112 0.00046929996 +300 112 0.00093849981 +344 112 0.00046929996 +350 112 0.00046929996 +358 112 0.00046929996 +443 112 0.025809497 +444 112 0.00046929996 +445 112 0.029094297 +446 112 0.0046925992 +447 112 0.0098544993 +450 112 0.00093849981 +452 112 0.015954997 +453 112 0.0229939 +454 112 0.0023462998 +455 112 0.13233215 +457 112 0.0046925992 +459 112 0.00046929996 +460 112 -0.0018771 +463 112 0.0126701 +464 112 0.00046929996 +467 112 0.0056311972 +468 112 0.00046929996 +469 112 0.00046929996 +470 112 0.00093849981 +471 112 0.00046929996 +478 112 0.00046929996 +490 112 0.00046929996 +491 112 0.00093849981 +6 113 0.00015889999 +9 113 0.081519067 +11 113 0.00015889999 +60 113 0.0016684998 +93 113 0.0373431 +94 113 0.0030987 +104 113 7.9499994e-05 +107 113 0.0081041977 +112 113 0.0027013998 +113 113 0.073335469 +114 113 0.0080247968 +116 113 0.0002384 +126 113 7.9499994e-05 +171 113 0.0025424999 +172 113 0.00015889999 +192 113 0.00055619981 +194 113 7.9499994e-05 +198 113 0.0041315965 +204 113 0.013268698 +206 113 0.00031779986 +223 113 7.9499994e-05 +229 113 0.00039729988 +230 113 0.00015889999 +234 113 0.0011918 +237 113 0.0002384 +241 113 0.00063559995 +242 113 0.0025424999 +253 113 0.06991899 +272 113 0.00071509997 +279 113 0.0002384 +300 113 0.00031779986 +314 113 0.0080247968 +324 113 0.00039729988 +325 113 0.00039729988 +344 113 0.00031779986 +356 113 7.9499994e-05 +358 113 0.0002384 +402 113 7.9499994e-05 +443 113 0.0077863969 +444 113 0.0038137999 +445 113 0.039567798 +446 113 0.0025424999 +447 113 0.0032575999 +450 113 0.0008739999 +452 113 0.0021451998 +453 113 0.0014301999 +454 113 0.0002384 +455 113 0.064198256 +456 113 0.00015889999 +457 113 0.0041315965 +459 113 0.0010328998 +460 113 0.00095339981 +463 113 0.0040520988 +464 113 0.0002384 +465 113 0.0002384 +467 113 0.0026219999 +468 113 0.042984299 +469 113 0.0011123 +470 113 0.0011918 +471 113 0.0011918 +472 113 0.0015890999 +473 113 7.9499994e-05 +478 113 0.0002384 +483 113 0.0002384 +490 113 0.0002384 +5 114 0.0005551998 +6 114 0.0077535994 +9 114 0.00069409981 +22 114 0.00057509984 +60 114 0.0010707998 +93 114 0.0036288998 +98 114 0.00041639991 +102 114 0.0001586 +104 114 7.9299993e-05 +107 114 0.00021809999 +112 114 0.0019631998 +113 114 0.00059489999 +114 114 0.041227099 +117 114 1.9799991e-05 +118 114 9.9199999e-05 +120 114 3.9699997e-05 +126 114 1.9799991e-05 +169 114 0.00061469991 +171 114 0.0013682998 +172 114 0.0072776973 +190 114 1.9799991e-05 +192 114 0.0025978 +194 114 1.9799991e-05 +198 114 0.0045807995 +203 114 1.9799991e-05 +204 114 0.0059291981 +206 114 9.9199999e-05 +214 114 7.9299993e-05 +228 114 1.9799991e-05 +229 114 9.9199999e-05 +230 114 5.9499987e-05 +234 114 0.00079319999 +237 114 7.9299993e-05 +241 114 0.0027762 +242 114 0.0010311999 +252 114 1.9799991e-05 +253 114 0.031629298 +272 114 0.00013879999 +279 114 3.9699997e-05 +314 114 0.0017053999 +324 114 5.9499987e-05 +325 114 0.00023799999 +344 114 7.9299993e-05 +350 114 0.0013682998 +351 114 0.00047589978 +356 114 1.9799991e-05 +358 114 0.00011899999 +384 114 1.9799991e-05 +402 114 3.9699997e-05 +404 114 1.9799991e-05 +422 114 1.9799991e-05 +434 114 1.9799991e-05 +443 114 0.0019234999 +444 114 0.0022012 +445 114 0.0047592968 +446 114 0.0001983 +447 114 0.0093003996 +450 114 0.00043629995 +452 114 0.00085269986 +453 114 0.00045609986 +454 114 0.00033709989 +455 114 0.017073799 +456 114 7.9299993e-05 +457 114 0.0039660968 +458 114 0.00011899999 +459 114 0.0020424998 +460 114 0.00093199988 +463 114 0.0075552985 +464 114 0.0016062998 +465 114 0.00013879999 +467 114 0.0016855998 +468 114 0.042099599 +469 114 0.0012889998 +470 114 0.00031729997 +471 114 0.0005551998 +473 114 1.9799991e-05 +477 114 1.9799991e-05 +478 114 0.00011899999 +483 114 9.9199999e-05 +489 114 3.9699997e-05 +490 114 0.0016458998 +491 114 9.9199999e-05 +0 115 0.0055522993 +1 115 8.1699996e-05 +9 115 0.00081649981 +10 115 2.0399995e-05 +11 115 0.00083689997 +16 115 0.0001429 +17 115 2.0399995e-05 +22 115 0.00089819985 +60 115 0.0023882999 +82 115 0.00036739977 +83 115 4.0799991e-05 +84 115 0.00016329999 +86 115 4.0799991e-05 +87 115 2.0399995e-05 +88 115 0.00059199985 +90 115 0.0015309998 +93 115 0.0083079971 +94 115 0.0001429 +95 115 2.0399995e-05 +97 115 2.0399995e-05 +98 115 8.1699996e-05 +104 115 0.0014493 +105 115 2.0399995e-05 +107 115 0.069770753 +108 115 4.0799991e-05 +113 115 4.0799991e-05 +114 115 6.1199986e-05 +115 115 0.0053276978 +116 115 0.12029225 +118 115 4.0799991e-05 +122 115 0.00012249999 +124 115 4.0799991e-05 +125 115 0.00012249999 +126 115 4.0799991e-05 +127 115 2.0399995e-05 +150 115 0.00030619977 +151 115 2.0399995e-05 +172 115 0.0022249999 +189 115 0.0001429 +190 115 8.1699996e-05 +192 115 0.00010209999 +193 115 4.0799991e-05 +194 115 0.00010209999 +196 115 2.0399995e-05 +197 115 2.0399995e-05 +198 115 0.023066398 +200 115 6.1199986e-05 +201 115 2.0399995e-05 +203 115 6.1199986e-05 +204 115 0.0027965 +206 115 0.00032659993 +207 115 6.1199986e-05 +209 115 2.0399995e-05 +214 115 0.0031843998 +218 115 2.0399995e-05 +223 115 6.1199986e-05 +229 115 0.00091859978 +230 115 0.00042869989 +234 115 0.0039804988 +237 115 0.00057159993 +240 115 2.0399995e-05 +241 115 0.0041029975 +242 115 0.00083689997 +248 115 2.0399995e-05 +252 115 0.0001429 +253 115 0.12004739 +272 115 0.00085729989 +279 115 0.00067359977 +284 115 2.0399995e-05 +300 115 0.16075039 +314 115 0.014452197 +324 115 0.00044909981 +325 115 0.00030619977 +344 115 0.00036739977 +351 115 0.00030619977 +356 115 8.1699996e-05 +358 115 0.00087769981 +366 115 2.0399995e-05 +384 115 4.0799991e-05 +387 115 2.0399995e-05 +394 115 4.0799991e-05 +397 115 2.0399995e-05 +402 115 0.0002041 +419 115 2.0399995e-05 +422 115 8.1699996e-05 +423 115 2.0399995e-05 +425 115 2.0399995e-05 +430 115 2.0399995e-05 +431 115 4.0799991e-05 +432 115 2.0399995e-05 +433 115 4.0799991e-05 +434 115 4.0799991e-05 +443 115 0.0050827973 +444 115 0.00040829997 +445 115 0.011880197 +446 115 0.0011838998 +447 115 0.0011022999 +448 115 8.1699996e-05 +450 115 0.0031027 +452 115 0.0041233972 +453 115 0.0017758999 +454 115 0.00073489989 +455 115 0.0303129 +456 115 0.00091859978 +457 115 0.0046132989 +458 115 0.00040829997 +459 115 0.0013676998 +460 115 0.0012859998 +463 115 0.0109616 +464 115 0.00016329999 +465 115 0.0012451999 +467 115 0.011206597 +468 115 0.057380199 +469 115 0.0087161995 +470 115 0.0031639999 +471 115 0.0057155974 +473 115 6.1199986e-05 +477 115 8.1699996e-05 +478 115 0.0029189999 +483 115 0.0018575999 +489 115 0.00018369999 +490 115 0.00028579985 +491 115 2.0399995e-05 +0 116 0.00080389995 +3 116 0.00053589977 +5 116 0.0039522983 +6 116 0.0026794998 +9 116 0.0017416999 +10 116 0.00033489987 +11 116 0.0015407 +13 116 0.0013398 +14 116 0.0010717998 +16 116 6.6999986e-05 +17 116 6.6999986e-05 +60 116 0.0014736999 +82 116 0.00026799995 +84 116 6.6999986e-05 +85 116 0.00020099999 +87 116 0.00020099999 +88 116 0.00026799995 +90 116 0.00020099999 +93 116 0.0089763999 +94 116 0.00020099999 +95 116 0.00013399999 +98 116 0.0012057999 +99 116 6.6999986e-05 +102 116 0.0013398 +103 116 0.00073689991 +104 116 0.007167697 +105 116 0.00026799995 +106 116 6.6999986e-05 +107 116 0.14529735 +108 116 0.00013399999 +109 116 0.00013399999 +110 116 0.00013399999 +112 116 0.0016076998 +113 116 0.0020095999 +114 116 0.0020766 +115 116 0.0050240979 +116 116 0.044145197 +117 116 0.00013399999 +118 116 0.0063638985 +119 116 0.0014067998 +120 116 0.00040189992 +122 116 0.0020095999 +125 116 0.0013398 +126 116 6.6999986e-05 +172 116 6.6999986e-05 +192 116 0.0010048 +193 116 0.00060289982 +194 116 6.6999986e-05 +198 116 0.018957697 +204 116 0.0061628968 +206 116 0.00013399999 +214 116 0.0050910972 +215 116 6.6999986e-05 +223 116 0.016880997 +228 116 0.0041532964 +229 116 0.00066989986 +230 116 0.00013399999 +231 116 0.00013399999 +232 116 0.00013399999 +234 116 0.0018086999 +237 116 0.00020099999 +241 116 0.0044211969 +242 116 0.0030814998 +252 116 6.6999986e-05 +253 116 0.025187597 +272 116 0.00026799995 +277 116 6.6999986e-05 +279 116 0.00026799995 +300 116 0.011053097 +301 116 0.0019426998 +314 116 0.0034163999 +317 116 6.6999986e-05 +325 116 0.00040189992 +344 116 0.00033489987 +349 116 6.6999986e-05 +356 116 6.6999986e-05 +358 116 0.00026799995 +402 116 6.6999986e-05 +443 116 0.0086414963 +444 116 0.0024116 +445 116 0.0087084994 +446 116 0.0019426998 +447 116 0.0028804999 +450 116 0.0010048 +452 116 0.0024785998 +453 116 0.00087079988 +454 116 0.0010048 +455 116 0.030948598 +456 116 0.00013399999 +457 116 0.0045551993 +458 116 0.00040189992 +459 116 0.00046889996 +460 116 0.00020099999 +463 116 0.014670398 +464 116 0.0026794998 +465 116 0.00053589977 +467 116 0.0042202994 +468 116 0.016278099 +469 116 0.0014736999 +470 116 0.0013398 +471 116 0.0036173998 +473 116 6.6999986e-05 +478 116 0.00026799995 +483 116 0.00040189992 +490 116 0.0148714 +491 116 0.00093779992 +4 117 0.43876797 +5 117 0.027132697 +6 117 0.0068442971 +13 117 0.0002444 +14 117 0.12613046 +60 117 0.0034220999 +82 117 0.0031776999 +88 117 0.0002444 +98 117 0.00073329988 +102 117 0.0034220999 +104 117 0.00097779999 +107 117 0.0002444 +114 117 0.0002444 +117 117 0.032265898 +118 117 0.016132999 +119 117 0.0043998994 +120 117 0.00097779999 +122 117 0.0065998994 +198 117 0.0012222 +204 117 0.00097779999 +206 117 0.0002444 +214 117 0.0012222 +228 117 0.00048889988 +229 117 0.00048889988 +230 117 0.0002444 +231 117 0.0002444 +234 117 0.0014666 +237 117 0.0002444 +241 117 0.00073329988 +242 117 0.00048889988 +253 117 0.00073329988 +272 117 0.00048889988 +300 117 0.00097779999 +301 117 0.0014666 +314 117 0.0002444 +325 117 0.0002444 +344 117 0.00048889988 +351 117 0.0002444 +358 117 0.00048889988 +443 117 0.023710597 +444 117 0.00048889988 +445 117 0.023466099 +446 117 0.0012222 +447 117 0.00048889988 +450 117 0.0014666 +452 117 0.014177497 +453 117 0.0051331967 +454 117 0.0002444 +455 117 0.070642889 +456 117 0.0002444 +457 117 0.0024444 +459 117 0.00048889988 +460 117 0.0063553974 +463 117 0.00048889988 +464 117 0.0002444 +465 117 0.0012222 +467 117 0.0065998994 +468 117 0.0024444 +469 117 0.0012222 +470 117 0.0012222 +471 117 0.0017110999 +478 117 0.00048889988 +483 117 0.00073329988 +490 117 0.00048889988 +491 117 0.0031776999 +4 118 0.0095405988 +5 118 0.0085460991 +6 118 0.0083986968 +13 118 3.6799989e-05 +14 118 0.74266028 +17 118 7.3699994e-05 +22 118 0.00077359984 +60 118 0.0012155999 +82 118 0.007993497 +84 118 3.6799989e-05 +94 118 3.6799989e-05 +102 118 3.6799989e-05 +104 118 0.001584 +114 118 3.6799989e-05 +117 118 0.0023206999 +118 118 0.022654399 +119 118 0.0025416999 +120 118 0.00062619988 +122 118 0.0020627999 +126 118 3.6799989e-05 +151 118 3.6799989e-05 +193 118 0.00092089991 +198 118 0.0014734999 +204 118 0.0002946998 +206 118 7.3699994e-05 +214 118 0.00092089991 +224 118 3.6799989e-05 +229 118 0.00051569985 +230 118 7.3699994e-05 +231 118 3.6799989e-05 +234 118 0.0010682999 +237 118 7.3699994e-05 +241 118 0.0014366 +242 118 0.0013628998 +252 118 3.6799989e-05 +253 118 0.00033149985 +272 118 0.00022099999 +277 118 3.6799989e-05 +279 118 3.6799989e-05 +300 118 0.00040519983 +301 118 0.0015470998 +314 118 3.6799989e-05 +325 118 3.6799989e-05 +344 118 0.00058939983 +350 118 3.6799989e-05 +351 118 0.00022099999 +358 118 0.00014729999 +402 118 3.6799989e-05 +443 118 0.019891698 +444 118 0.0016207998 +445 118 0.011861298 +446 118 0.0042729974 +447 118 0.0012524 +450 118 0.00040519983 +452 118 0.0045308992 +453 118 0.0044203997 +454 118 0.00033149985 +455 118 0.015581798 +456 118 7.3699994e-05 +457 118 0.0025785998 +458 118 0.00018419999 +459 118 0.00044199987 +460 118 0.00040519983 +463 118 0.0011419 +464 118 0.0016575998 +465 118 0.00014729999 +467 118 0.0021733998 +468 118 0.00081039988 +469 118 0.0020996998 +470 118 0.0005524999 +471 118 0.0034625998 +473 118 3.6799989e-05 +477 118 3.6799989e-05 +478 118 0.0001105 +483 118 0.0001105 +489 118 3.6799989e-05 +490 118 0.00014729999 +491 118 0.0036099998 +4 119 0.030545499 +5 119 0.0025454999 +6 119 0.00072729983 +9 119 0.00036359997 +10 119 0.0036364 +11 119 0.00036359997 +13 119 0.056727298 +14 119 0.34036356 +17 119 0.0029090999 +22 119 0.00036359997 +24 119 0.0032726999 +60 119 0.0018181999 +82 119 0.0105455 +84 119 0.00072729983 +88 119 0.0010908998 +104 119 0.0029090999 +107 119 0.0036364 +108 119 0.0050908998 +109 119 0.0025454999 +116 119 0.0018181999 +117 119 0.0079999976 +118 119 0.038545497 +119 119 0.012727298 +120 119 0.021454498 +122 119 0.017454498 +125 119 0.00036359997 +192 119 0.00072729983 +198 119 0.0058181994 +204 119 0.0025454999 +214 119 0.0021817998 +215 119 0.0010908998 +231 119 0.00036359997 +234 119 0.0021817998 +241 119 0.0029090999 +242 119 0.00036359997 +253 119 0.0025454999 +272 119 0.0029090999 +300 119 0.0043635964 +301 119 0.0054544993 +314 119 0.00036359997 +325 119 0.0010908998 +344 119 0.00036359997 +350 119 0.00036359997 +351 119 0.00036359997 +356 119 0.00036359997 +443 119 0.016727298 +444 119 0.00072729983 +445 119 0.0192727 +446 119 0.0149091 +447 119 0.0021817998 +450 119 0.00036359997 +452 119 0.006545499 +453 119 0.0047272965 +454 119 0.00072729983 +455 119 0.044 +457 119 0.0025454999 +459 119 0.0101818 +460 119 0.0025454999 +463 119 0.0018181999 +464 119 0.00036359997 +465 119 0.00072729983 +467 119 0.0050908998 +468 119 0.021090899 +469 119 0.00072729983 +470 119 0.0010908998 +489 119 0.00036359997 +490 119 0.081090868 +491 119 0.0061817989 +1 120 0.004378397 +2 120 0.18949187 +6 120 0.00020359999 +13 120 0.00020359999 +14 120 0.0016291998 +17 120 0.036656097 +21 120 0.00010179999 +22 120 0.00010179999 +24 120 0.00030549988 +60 120 0.0021382999 +82 120 0.040728997 +83 120 0.00061089988 +84 120 0.0096731 +85 120 0.0011199999 +88 120 0.00010179999 +91 120 0.0019345998 +96 120 0.00091639999 +102 120 0.00010179999 +104 120 0.00030549988 +114 120 0.00010179999 +117 120 0.00081459992 +118 120 0.0046837963 +119 120 0.0016291998 +120 120 0.25180739 +122 120 0.0023418998 +125 120 0.00040729996 +126 120 0.00010179999 +153 120 0.00010179999 +193 120 0.00020359999 +194 120 0.00010179999 +198 120 0.0023418998 +204 120 0.00040729996 +206 120 0.00020359999 +214 120 0.0029528998 +218 120 0.00040729996 +223 120 0.00040729996 +224 120 0.00040729996 +225 120 0.00010179999 +229 120 0.00040729996 +230 120 0.00020359999 +231 120 0.00020359999 +232 120 0.00010179999 +234 120 0.0060075 +237 120 0.00020359999 +241 120 0.0021382999 +252 120 0.00010179999 +253 120 0.00030549988 +277 120 0.00030549988 +279 120 0.00010179999 +300 120 0.0015272999 +301 120 0.0037673998 +324 120 0.00020359999 +325 120 0.00010179999 +344 120 0.00040729996 +358 120 0.0005090998 +402 120 0.00010179999 +443 120 0.0079421997 +444 120 0.00010179999 +445 120 0.0091639981 +446 120 0.0015272999 +447 120 0.0019345998 +450 120 0.0016291998 +452 120 0.008145798 +453 120 0.0085530989 +454 120 0.00071279984 +455 120 0.044700097 +456 120 0.00020359999 +457 120 0.0021382999 +458 120 0.00010179999 +459 120 0.00061089988 +460 120 0.0016291998 +463 120 0.0047856979 +464 120 0.00020359999 +465 120 0.0065165982 +467 120 0.0054983981 +468 120 0.0039710999 +469 120 0.0019345998 +470 120 0.0021382999 +471 120 0.0016291998 +473 120 0.00010179999 +478 120 0.00040729996 +483 120 0.00071279984 +490 120 0.00040729996 +491 120 0.004378397 +3 121 0.00041569979 +5 121 4.6199988e-05 +9 121 0.00046189991 +10 121 4.6199988e-05 +11 121 0.00073899981 +13 121 0.0012469999 +14 121 0.00073899981 +17 121 4.6199988e-05 +22 121 4.6199988e-05 +60 121 0.0013394 +93 121 4.6199988e-05 +94 121 9.2399991e-05 +98 121 0.00013859999 +104 121 0.00018469999 +105 121 0.00018469999 +106 121 4.6199988e-05 +107 121 0.0006465998 +108 121 0.00013859999 +109 121 4.6199988e-05 +114 121 9.2399991e-05 +115 121 4.6199988e-05 +116 121 9.2399991e-05 +118 121 4.6199988e-05 +119 121 9.2399991e-05 +120 121 9.2399991e-05 +121 121 0.0005541998 +122 121 0.00073899981 +125 121 0.00013859999 +126 121 4.6199988e-05 +151 121 0.0015703 +153 121 0.0016627 +189 121 4.6199988e-05 +192 121 0.00032329978 +193 121 0.0078514963 +194 121 4.6199988e-05 +198 121 0.031775396 +204 121 0.0052650981 +206 121 9.2399991e-05 +214 121 0.001986 +223 121 0.0002309 +229 121 0.0003694999 +230 121 0.00013859999 +231 121 0.00018469999 +232 121 4.6199988e-05 +234 121 0.0015703 +237 121 0.00013859999 +241 121 0.0060501993 +242 121 0.0015240998 +252 121 4.6199988e-05 +253 121 0.015379597 +272 121 0.0002770999 +279 121 0.0005541998 +300 121 0.052004397 +314 121 0.0026786998 +325 121 9.2399991e-05 +344 121 0.00050799991 +356 121 4.6199988e-05 +358 121 0.0002309 +387 121 4.6199988e-05 +402 121 4.6199988e-05 +443 121 0.0036024 +444 121 0.0043875985 +445 121 0.004202798 +446 121 0.023323499 +447 121 0.0015703 +450 121 0.00073899981 +452 121 0.0023553998 +453 121 0.0013394 +454 121 0.0018936 +455 121 0.032745197 +456 121 0.00013859999 +457 121 0.0024015999 +458 121 4.6199988e-05 +459 121 0.00041569979 +460 121 0.0029557999 +463 121 0.0037872 +464 121 0.0017088 +465 121 0.00032329978 +467 121 0.0039718971 +468 121 0.042259399 +469 121 0.0033714999 +470 121 0.0013394 +471 121 0.0049879998 +473 121 4.6199988e-05 +477 121 4.6199988e-05 +478 121 0.0002309 +483 121 0.00069279992 +490 121 0.4301219 +491 121 0.00032329978 +0 122 0.0065629967 +2 122 0.0081926994 +3 122 4.3999986e-05 +4 122 0.0040082969 +5 122 0.0023345 +6 122 0.0011011998 +9 122 0.00057259994 +10 122 0.0002642998 +11 122 0.0017618998 +13 122 0.00096899993 +14 122 0.10064745 +17 122 4.3999986e-05 +22 122 0.00048449985 +24 122 4.3999986e-05 +60 122 0.0016737999 +82 122 0.041712496 +83 122 4.3999986e-05 +85 122 0.0015856999 +86 122 8.8099987e-05 +87 122 0.0051975995 +88 122 0.00017619999 +90 122 0.0025106999 +93 122 4.3999986e-05 +95 122 0.00088089984 +98 122 4.3999986e-05 +104 122 0.012377199 +107 122 0.0016297 +108 122 0.00044049998 +109 122 0.00022019999 +114 122 4.3999986e-05 +116 122 0.00017619999 +117 122 0.0342246 +118 122 0.18530589 +119 122 0.0606528 +120 122 0.0003082999 +122 122 0.096683264 +125 122 0.00096899993 +126 122 4.3999986e-05 +130 122 4.3999986e-05 +150 122 4.3999986e-05 +151 122 8.8099987e-05 +189 122 4.3999986e-05 +192 122 0.00061669992 +193 122 0.00092499983 +194 122 4.3999986e-05 +198 122 0.0198652 +204 122 0.013874799 +206 122 8.8099987e-05 +214 122 0.0064308979 +223 122 4.3999986e-05 +229 122 0.00048449985 +230 122 0.00013209999 +231 122 0.0016737999 +234 122 0.0023345 +237 122 0.00013209999 +241 122 0.012200996 +242 122 0.0013213998 +252 122 4.3999986e-05 +253 122 0.016473599 +272 122 0.00035239989 +279 122 0.00092499983 +300 122 0.014667697 +301 122 0.0015856999 +314 122 0.0027749999 +317 122 4.3999986e-05 +324 122 0.00013209999 +325 122 0.0024225998 +340 122 0.00013209999 +344 122 0.00057259994 +350 122 0.0014535999 +351 122 0.0019381 +356 122 4.3999986e-05 +358 122 0.00022019999 +402 122 4.3999986e-05 +443 122 0.018455699 +444 122 0.0021582998 +445 122 0.025371097 +446 122 0.0014535999 +447 122 0.0026427999 +450 122 0.00088089984 +452 122 0.0037439999 +453 122 0.0035677999 +454 122 0.0010130999 +455 122 0.045280397 +456 122 0.00013209999 +457 122 0.0022023998 +458 122 0.00048449985 +459 122 0.00052859983 +460 122 0.0016737999 +463 122 0.0020261998 +464 122 0.00039639999 +465 122 0.00048449985 +467 122 0.005770199 +468 122 0.0306127 +469 122 0.0012333 +470 122 0.0010570998 +471 122 0.0011892999 +473 122 4.3999986e-05 +477 122 4.3999986e-05 +478 122 0.0002642998 +483 122 0.00039639999 +490 122 0.00088089984 +491 122 0.0013213998 +17 123 0.00091659999 +22 123 0.00091659999 +60 123 0.021998197 +114 123 0.00091659999 +123 123 0.0018332 +193 123 0.0183318 +198 123 0.00091659999 +206 123 0.0018332 +230 123 0.00091659999 +234 123 0.0082492977 +237 123 0.0018332 +241 123 0.013748899 +272 123 0.0018332 +277 123 0.00091659999 +324 123 0.00091659999 +334 123 0.00091659999 +358 123 0.0027498 +366 123 0.00091659999 +444 123 0.00091659999 +445 123 0.016498599 +447 123 0.0064160973 +450 123 0.0082492977 +452 123 0.076076984 +453 123 0.00091659999 +454 123 0.012832299 +455 123 0.0073326975 +456 123 0.00091659999 +457 123 0.0027498 +458 123 0.0018332 +459 123 0.00091659999 +460 123 0.0036664 +463 123 0.010082498 +464 123 0.0018332 +465 123 0.0018332 +467 123 0.034830399 +468 123 0.0054994971 +469 123 0.010082498 +470 123 0.010999098 +471 123 0.009165898 +478 123 0.0018332 +483 123 0.0054994971 +490 123 0.0018332 +0 124 0.0088593997 +3 124 0.00055369991 +5 124 0.024640098 +9 124 0.00055369991 +11 124 0.0011073998 +13 124 0.00055369991 +14 124 0.0127353 +60 124 0.0024917 +85 124 0.020210396 +87 124 0.0074750967 +88 124 0.00055369991 +90 124 0.0027684998 +94 124 0.0019379999 +97 124 0.0002768999 +98 124 0.27380949 +104 124 0.00055369991 +105 124 0.0002768999 +107 124 0.0019379999 +114 124 0.0002768999 +118 124 0.0011073998 +122 124 0.0016611 +124 124 0.011627898 +125 124 0.0002768999 +192 124 0.013012197 +193 124 0.0096898973 +198 124 0.059523799 +204 124 0.00083059981 +206 124 0.00055369991 +214 124 0.0011073998 +223 124 0.00055369991 +228 124 0.0127353 +229 124 0.0002768999 +230 124 0.00055369991 +234 124 0.0038759999 +237 124 0.00055369991 +241 124 0.033222597 +252 124 0.0002768999 +253 124 0.00055369991 +272 124 0.0002768999 +279 124 0.0013842999 +300 124 0.0011073998 +314 124 0.0002768999 +325 124 0.0002768999 +340 124 0.0002768999 +344 124 0.0002768999 +358 124 0.00083059981 +443 124 0.023255799 +444 124 0.0002768999 +445 124 0.018826097 +446 124 0.00055369991 +447 124 0.011627898 +450 124 0.0024917 +452 124 0.0066444986 +453 124 0.0016611 +454 124 0.00055369991 +455 124 0.040974498 +456 124 0.0002768999 +457 124 0.0024917 +458 124 0.00055369991 +459 124 0.00055369991 +460 124 0.0024917 +463 124 0.0063676983 +464 124 0.00055369991 +465 124 0.0011073998 +467 124 0.0083055981 +468 124 0.026854899 +469 124 0.0033222998 +470 124 0.0035990998 +471 124 0.0024917 +478 124 0.00055369991 +483 124 0.00083059981 +490 124 0.0027684998 +0 125 0.0035058998 +1 125 0.00034269993 +2 125 0.0018189 +3 125 0.014418997 +5 125 0.0044284984 +6 125 0.0038221998 +9 125 0.017160498 +10 125 0.0001318 +11 125 0.025437597 +12 125 7.9099991e-05 +13 125 0.016079698 +14 125 0.025463898 +16 125 0.0004480998 +17 125 0.0026623998 +22 125 0.00021089999 +24 125 2.6399997e-05 +60 125 0.0020297 +82 125 0.0025042 +83 125 0.00010539999 +84 125 0.00052719982 +85 125 0.00055359979 +86 125 7.9099991e-05 +87 125 0.0006589999 +88 125 0.0011862 +90 125 0.0013970998 +91 125 2.6399997e-05 +93 125 0.0011862 +94 125 0.0010279999 +95 125 0.00028999988 +97 125 7.9099991e-05 +98 125 0.0091469996 +100 125 0.00010539999 +102 125 0.00010539999 +103 125 0.0001318 +104 125 0.0079607964 +105 125 0.006563697 +106 125 0.0020560999 +107 125 0.026043899 +108 125 0.0001582 +109 125 0.00081719994 +112 125 2.6399997e-05 +113 125 0.00063259993 +114 125 0.0001318 +115 125 0.0022143 +116 125 0.0027150998 +117 125 0.00097529986 +118 125 0.0044284984 +119 125 0.0021088 +120 125 0.00026359991 +121 125 2.6399997e-05 +122 125 0.029022597 +124 125 0.00010539999 +125 125 0.0054301992 +126 125 5.2699994e-05 +150 125 0.00036899978 +151 125 5.2699994e-05 +153 125 5.2699994e-05 +160 125 2.6399997e-05 +169 125 2.6399997e-05 +172 125 5.2699994e-05 +189 125 5.2699994e-05 +190 125 5.2699994e-05 +191 125 0.00068539986 +192 125 0.011862099 +193 125 0.0037958999 +194 125 0.00010539999 +197 125 2.6399997e-05 +198 125 0.0279154 +200 125 2.6399997e-05 +203 125 5.2699994e-05 +204 125 0.0081188977 +206 125 0.0001318 +207 125 2.6399997e-05 +214 125 0.004191298 +218 125 5.2699994e-05 +219 125 5.2699994e-05 +223 125 0.0088569969 +224 125 2.6399997e-05 +228 125 0.00023719999 +229 125 0.00031629996 +230 125 0.0004480998 +231 125 0.00028999988 +232 125 0.00010539999 +234 125 0.0031895998 +237 125 0.00034269993 +240 125 2.6399997e-05 +241 125 0.029628798 +242 125 0.0014497999 +252 125 0.0001582 +253 125 0.018715698 +270 125 2.6399997e-05 +272 125 0.00036899978 +277 125 7.9099991e-05 +279 125 0.0006589999 +300 125 0.021483596 +301 125 0.00092259981 +314 125 0.0045866966 +317 125 2.6399997e-05 +325 125 0.0043230988 +326 125 2.6399997e-05 +340 125 7.9099991e-05 +344 125 0.00092259981 +350 125 2.6399997e-05 +351 125 5.2699994e-05 +358 125 0.00068539986 +366 125 2.6399997e-05 +384 125 2.6399997e-05 +387 125 2.6399997e-05 +394 125 2.6399997e-05 +397 125 2.6399997e-05 +402 125 0.0001582 +414 125 2.6399997e-05 +419 125 2.6399997e-05 +422 125 0.00010539999 +423 125 2.6399997e-05 +425 125 2.6399997e-05 +430 125 2.6399997e-05 +431 125 2.6399997e-05 +433 125 2.6399997e-05 +434 125 2.6399997e-05 +443 125 0.0096214972 +444 125 0.0019506998 +445 125 0.0294443 +446 125 0.0036640998 +447 125 0.0058255978 +448 125 2.6399997e-05 +450 125 0.0023196999 +452 125 0.0047711991 +453 125 0.0030313998 +454 125 0.00052719982 +455 125 0.053959299 +456 125 0.00050079986 +457 125 0.0041121989 +458 125 0.00047449977 +459 125 0.00050079986 +460 125 0.0021352 +463 125 0.0137337 +464 125 0.00023719999 +465 125 0.0050083995 +467 125 0.011651199 +468 125 0.0526677 +469 125 0.0032686999 +470 125 0.0035322998 +471 125 0.0049029998 +473 125 7.9099991e-05 +477 125 5.2699994e-05 +478 125 0.00068539986 +483 125 0.00086989999 +489 125 0.00023719999 +490 125 0.049688898 +491 125 0.00026359991 +22 126 0.0002077 +60 126 0.00064049987 +104 126 0.00027699978 +108 126 1.7299986e-05 +114 126 1.7299986e-05 +126 126 1.7299986e-05 +129 126 0.19280237 +151 126 1.7299986e-05 +187 126 0.012584597 +189 126 1.7299986e-05 +190 126 1.7299986e-05 +194 126 3.4599987e-05 +198 126 0.0089147985 +200 126 1.7299986e-05 +203 126 1.7299986e-05 +204 126 0.010316998 +206 126 3.4599987e-05 +214 126 0.00015579999 +229 126 0.00076169986 +234 126 0.00070969993 +237 126 8.659999e-05 +241 126 0.016150497 +252 126 3.4599987e-05 +272 126 0.00034619984 +279 126 0.00019039999 +284 126 1.7299986e-05 +325 126 0.0047775991 +340 126 5.1899988e-05 +350 126 0.0006750999 +356 126 1.7299986e-05 +358 126 0.00032889983 +387 126 1.7299986e-05 +402 126 5.1899988e-05 +404 126 1.7299986e-05 +422 126 3.4599987e-05 +430 126 1.7299986e-05 +434 126 1.7299986e-05 +443 126 0.0009347999 +444 126 0.00079629989 +445 126 0.0020252999 +446 126 0.00012119999 +447 126 0.00076169986 +450 126 0.00060589984 +452 126 0.0010213 +453 126 0.0002597 +454 126 0.0002597 +455 126 0.0051584989 +456 126 0.00010389999 +457 126 0.0014020998 +458 126 0.00098669995 +459 126 0.0017309999 +460 126 0.0004153999 +463 126 0.0018867999 +464 126 0.000225 +465 126 0.0042063966 +467 126 0.0027003998 +468 126 0.059530199 +469 126 0.00084819994 +470 126 0.00091739977 +471 126 0.00057119993 +472 126 0.00017309999 +473 126 1.7299986e-05 +477 126 6.9199989e-05 +478 126 0.000225 +483 126 0.0018002999 +489 126 1.7299986e-05 +490 126 8.659999e-05 +491 126 0.00072699995 +8 127 0.017421599 +60 127 0.0017422 +104 127 0.00049779983 +114 127 0.00024889992 +126 127 0.00024889992 +127 127 0.0014932998 +129 127 0.25311095 +150 127 0.00024889992 +172 127 0.00049779983 +187 127 0.00099549978 +194 127 0.00024889992 +198 127 0.033847697 +204 127 0.00074659986 +206 127 0.00049779983 +229 127 0.00074659986 +234 127 0.0032354 +237 127 0.00049779983 +241 127 0.017670497 +252 127 0.00024889992 +272 127 0.00024889992 +279 127 0.00049779983 +317 127 0.00024889992 +325 127 0.0069685988 +358 127 0.0017422 +402 127 0.00024889992 +443 127 0.00024889992 +444 127 0.00024889992 +445 127 0.0037331998 +447 127 0.0017422 +450 127 0.0029865999 +452 127 0.0037331998 +453 127 0.00074659986 +454 127 0.0014932998 +455 127 0.0052264966 +456 127 0.00024889992 +457 127 0.0019909998 +458 127 0.00099549978 +459 127 0.0012443999 +460 127 0.00049779983 +463 127 0.0032354 +464 127 0.00024889992 +465 127 0.0047286972 +467 127 0.010452997 +468 127 0.020408198 +469 127 0.0037331998 +470 127 0.0039820969 +471 127 0.0029865999 +473 127 0.00024889992 +478 127 0.00099549978 +483 127 0.0037331998 +490 127 0.00049779983 +491 127 0.00024889992 +8 128 0.017788097 +22 128 0.0011600999 +60 128 0.0023202 +104 128 0.015854597 +114 128 0.0003866998 +128 128 0.0023202 +129 128 0.25870067 +187 128 0.0042536967 +192 128 0.0019334999 +193 128 0.0073472969 +198 128 0.017788097 +204 128 0.0069605969 +206 128 0.0003866998 +229 128 0.0011600999 +234 128 0.0015467999 +241 128 0.0073472969 +272 128 0.00077339984 +279 128 0.0003866998 +300 128 0.0019334999 +325 128 0.0061871968 +340 128 0.0003866998 +350 128 0.0003866998 +358 128 0.00077339984 +443 128 0.0023202 +444 128 0.0019334999 +445 128 0.0042536967 +446 128 0.0003866998 +447 128 0.018561497 +450 128 0.0015467999 +452 128 0.0019334999 +453 128 0.00077339984 +455 128 0.0058004968 +457 128 0.0023202 +458 128 0.0003866998 +459 128 0.0019334999 +460 128 0.0003866998 +463 128 0.012760997 +464 128 0.0003866998 +465 128 0.0015467999 +467 128 0.0050270967 +468 128 0.11136889 +469 128 0.0030935998 +470 128 0.0034802998 +471 128 0.0015467999 +478 128 0.0003866998 +483 128 0.0038669999 +490 128 0.0003866998 +491 128 0.0030935998 +8 129 0.5532372 +22 129 7.1599992e-05 +60 129 0.00093049998 +104 129 7.1599992e-05 +114 129 3.5799996e-05 +126 129 3.5799996e-05 +129 129 0.26316166 +130 129 3.5799996e-05 +151 129 3.5799996e-05 +159 129 0.00010739999 +160 129 0.00057259994 +172 129 0.0016104998 +186 129 0.00025049993 +187 129 0.0001432 +189 129 3.5799996e-05 +193 129 3.5799996e-05 +198 129 0.00071579986 +204 129 0.00010739999 +206 129 7.1599992e-05 +214 129 7.1599992e-05 +229 129 0.0016462998 +234 129 0.00078739994 +237 129 3.5799996e-05 +241 129 0.00017889999 +252 129 3.5799996e-05 +272 129 0.00010739999 +279 129 3.5799996e-05 +325 129 7.1599992e-05 +356 129 3.5799996e-05 +358 129 0.00021469999 +443 129 0.0017894998 +444 129 7.1599992e-05 +445 129 0.043949798 +446 129 0.00028629997 +447 129 0.00071579986 +450 129 0.00035789981 +452 129 0.0013599999 +453 129 0.00028629997 +454 129 0.00010739999 +455 129 0.0012526 +456 129 3.5799996e-05 +457 129 0.0012883998 +458 129 0.00010739999 +459 129 0.00071579986 +460 129 0.00028629997 +463 129 0.0025768999 +464 129 7.1599992e-05 +465 129 0.00010739999 +467 129 0.0091263987 +468 129 0.0015389998 +469 129 0.0007515999 +470 129 0.00085899979 +471 129 0.0005367999 +473 129 3.5799996e-05 +477 129 3.5799996e-05 +478 129 0.00010739999 +483 129 0.0019325998 +490 129 0.0070147999 +491 129 3.5799996e-05 +2 130 0.0017565 +4 130 0.0603249 +9 130 8.8999996e-06 +13 130 0.0001508 +16 130 8.8999996e-06 +18 130 8.8999996e-06 +22 130 0.00074519985 +25 130 4.4399989e-05 +60 130 0.0025903999 +79 130 8.8999996e-06 +82 130 8.8999996e-06 +83 130 8.8999996e-06 +84 130 6.2099993e-05 +104 130 0.0018451998 +108 130 1.7699989e-05 +113 130 2.6599999e-05 +114 130 6.2099993e-05 +126 130 2.6599999e-05 +127 130 8.8999996e-06 +130 130 0.32233 +131 130 0.00015969999 +132 130 0.052855197 +133 130 0.00045239995 +134 130 4.4399989e-05 +136 130 2.6599999e-05 +137 130 0.0001242 +138 130 0.0014016998 +139 130 0.00025729998 +140 130 6.2099993e-05 +141 130 1.7699989e-05 +142 130 0.00028389995 +143 130 0.0058816969 +145 130 1.7699989e-05 +146 130 2.6599999e-05 +149 130 0.0011443999 +150 130 0.00078949984 +151 130 0.00014189999 +152 130 0.00021289999 +155 130 8.8999996e-06 +156 130 8.8999996e-06 +157 130 0.00013309999 +158 130 7.0999988e-05 +171 130 0.00015969999 +186 130 1.7699989e-05 +187 130 8.8999996e-06 +189 130 7.9799996e-05 +190 130 8.8699991e-05 +192 130 0.0014282998 +193 130 0.0001065 +194 130 5.3199998e-05 +196 130 8.8999996e-06 +197 130 2.6599999e-05 +198 130 0.0062630996 +200 130 2.6599999e-05 +201 130 1.7699989e-05 +203 130 4.4399989e-05 +204 130 5.3199998e-05 +206 130 0.0001065 +207 130 3.5499994e-05 +209 130 8.8999996e-06 +214 130 0.024351697 +219 130 2.6599999e-05 +221 130 0.0012774998 +222 130 1.7699989e-05 +223 130 0.0039565973 +224 130 0.0014548998 +225 130 0.00019519999 +226 130 0.0220984 +227 130 0.043566998 +231 130 0.0045598969 +232 130 1.7699989e-05 +233 130 0.00040809996 +234 130 0.0025016998 +237 130 8.8699991e-05 +240 130 0.0001065 +241 130 0.0035662998 +242 130 5.3199998e-05 +243 130 8.8999996e-06 +248 130 8.8999996e-06 +250 130 8.8999996e-06 +251 130 8.8999996e-06 +252 130 0.0047815964 +253 130 1.7699989e-05 +263 130 8.8999996e-06 +271 130 0.0001242 +272 130 0.00050569978 +277 130 7.9799996e-05 +279 130 0.00011529999 +284 130 1.7699989e-05 +300 130 1.7699989e-05 +317 130 0.00014189999 +319 130 0.00038149999 +322 130 1.7699989e-05 +326 130 0.00079839979 +334 130 8.8999996e-06 +335 130 0.00095809996 +336 130 0.00078069977 +340 130 8.8999996e-06 +345 130 0.0062187985 +350 130 0.0002307 +351 130 1.7699989e-05 +356 130 7.0999988e-05 +358 130 0.0013927999 +365 130 0.0001774 +384 130 4.4399989e-05 +387 130 2.6599999e-05 +392 130 8.8999996e-06 +394 130 8.8999996e-06 +397 130 8.8999996e-06 +402 130 4.4399989e-05 +404 130 1.7699989e-05 +414 130 0.0001774 +419 130 8.8999996e-06 +421 130 0.00040809996 +422 130 0.00076289987 +423 130 8.8999996e-06 +425 130 8.8999996e-06 +430 130 1.7699989e-05 +431 130 1.7699989e-05 +432 130 8.8999996e-06 +433 130 1.7699989e-05 +434 130 2.6599999e-05 +435 130 2.6599999e-05 +437 130 2.6599999e-05 +442 130 8.8999996e-06 +443 130 0.0043380968 +444 130 0.0018540998 +445 130 0.0093946978 +446 130 0.00051449984 +447 130 0.0042670965 +448 130 1.7699989e-05 +449 130 8.8999996e-06 +450 130 0.0029187 +452 130 0.010015696 +453 130 0.0026169999 +454 130 0.0018806998 +455 130 0.043017 +456 130 0.000275 +457 130 0.0022089998 +458 130 0.00062989979 +459 130 0.00055889995 +460 130 0.00048789987 +463 130 0.0063518994 +464 130 0.0014725998 +465 130 0.00086049992 +467 130 0.012473099 +468 130 0.0026258999 +469 130 0.0025372 +470 130 0.0027945 +471 130 0.0010467998 +473 130 6.2099993e-05 +477 130 5.3199998e-05 +478 130 0.00096699991 +479 130 0.00079839979 +483 130 0.0012153999 +489 130 6.2099993e-05 +490 130 0.00040809996 +491 130 0.0013750999 +4 131 0.0029487999 +22 131 0.00018429999 +60 131 0.0027645 +108 131 0.00018429999 +114 131 0.00036859978 +126 131 0.00018429999 +130 131 0.014190897 +131 131 0.0086619966 +132 131 0.20586067 +138 131 0.00018429999 +139 131 0.00018429999 +142 131 0.013085097 +143 131 0.00018429999 +144 131 0.00018429999 +149 131 0.00036859978 +171 131 0.00018429999 +189 131 0.00018429999 +190 131 0.00018429999 +194 131 0.00018429999 +198 131 0.0014743998 +206 131 0.00036859978 +214 131 0.0014743998 +223 131 0.00018429999 +224 131 0.00018429999 +225 131 0.0005528999 +226 131 0.072797596 +227 131 0.10523409 +231 131 0.00018429999 +234 131 0.0031331 +237 131 0.00018429999 +240 131 0.030040499 +241 131 0.00018429999 +252 131 0.0038702998 +272 131 0.00036859978 +279 131 0.00092149992 +345 131 0.0129008 +356 131 0.00018429999 +358 131 0.0014743998 +387 131 0.00018429999 +422 131 0.00018429999 +443 131 0.0011057998 +444 131 0.0005528999 +445 131 0.0145595 +447 131 0.0064503998 +450 131 0.0031331 +452 131 0.009399198 +453 131 0.0022115998 +454 131 0.00036859978 +455 131 0.028566197 +457 131 0.0022115998 +458 131 0.0005528999 +459 131 0.00036859978 +460 131 0.0005528999 +463 131 0.016033899 +464 131 0.0005528999 +465 131 0.0014743998 +467 131 0.009399198 +468 131 0.0053445995 +469 131 0.005528897 +470 131 0.0060817972 +471 131 0.00092149992 +473 131 0.00018429999 +478 131 0.0018429998 +479 131 0.0053445995 +483 131 0.0018429998 +490 131 0.0005528999 +491 131 0.00092149992 +2 132 0.0075674988 +4 132 0.057291199 +9 132 1.9799991e-05 +13 132 0.00021789999 +18 132 1.9799991e-05 +22 132 0.00045559998 +60 132 0.0024167998 +82 132 1.9799991e-05 +83 132 1.9799991e-05 +84 132 1.9799991e-05 +104 132 0.0017432999 +108 132 1.9799991e-05 +113 132 3.9599996e-05 +114 132 7.9199992e-05 +118 132 5.9399987e-05 +126 132 3.9599996e-05 +127 132 1.9799991e-05 +130 132 0.016917899 +131 132 0.0015254 +132 132 0.087363064 +133 132 0.0001981 +134 132 0.0001981 +135 132 1.9799991e-05 +137 132 1.9799991e-05 +138 132 0.0011687998 +140 132 0.00011889999 +142 132 0.00021789999 +143 132 0.0086372979 +144 132 0.00013869999 +149 132 0.0010499 +150 132 0.0008121999 +151 132 1.9799991e-05 +155 132 3.9599996e-05 +158 132 3.9599996e-05 +171 132 0.0072703995 +186 132 0.00051509985 +189 132 1.9799991e-05 +190 132 9.9099998e-05 +192 132 9.9099998e-05 +193 132 5.9399987e-05 +194 132 0.00011889999 +197 132 1.9799991e-05 +198 132 0.009409897 +200 132 1.9799991e-05 +203 132 3.9599996e-05 +204 132 5.9399987e-05 +206 132 9.9099998e-05 +207 132 3.9599996e-05 +209 132 1.9799991e-05 +214 132 0.035856497 +215 132 9.9099998e-05 +221 132 5.9399987e-05 +223 132 0.0016243998 +224 132 0.0025356999 +225 132 0.00021789999 +226 132 0.031042598 +227 132 0.25824594 +231 132 0.0012876999 +233 132 1.9799991e-05 +234 132 0.0025752999 +237 132 7.9199992e-05 +240 132 0.00021789999 +241 132 0.0055071972 +242 132 0.00075279991 +252 132 0.00075279991 +272 132 0.0010102999 +277 132 7.9199992e-05 +279 132 0.00025749998 +284 132 1.9799991e-05 +319 132 1.9799991e-05 +324 132 3.9599996e-05 +326 132 3.9599996e-05 +334 132 1.9799991e-05 +335 132 5.9399987e-05 +336 132 3.9599996e-05 +345 132 0.0073693991 +349 132 0.00051509985 +350 132 1.9799991e-05 +351 132 3.9599996e-05 +356 132 0.00013869999 +358 132 0.0010102999 +377 132 1.9799991e-05 +382 132 0.0001585 +384 132 3.9599996e-05 +387 132 1.9799991e-05 +392 132 0.0015848 +402 132 3.9599996e-05 +404 132 3.9599996e-05 +414 132 0.0016441999 +417 132 1.9799991e-05 +419 132 1.9799991e-05 +421 132 1.9799991e-05 +422 132 0.00013869999 +423 132 1.9799991e-05 +425 132 1.9799991e-05 +430 132 1.9799991e-05 +431 132 1.9799991e-05 +432 132 1.9799991e-05 +433 132 1.9799991e-05 +434 132 3.9599996e-05 +443 132 0.0042987987 +444 132 0.00073299999 +445 132 0.0061411969 +446 132 0.00045559998 +447 132 0.00065369997 +450 132 0.0022781999 +452 132 0.0135304 +453 132 0.0021592998 +454 132 0.0010698 +455 132 0.035836697 +456 132 0.00023769999 +457 132 0.0022584 +458 132 0.00045559998 +459 132 0.0005349 +460 132 0.00073299999 +463 132 0.0063788965 +464 132 0.00033679977 +465 132 0.00099049998 +467 132 0.0069533996 +468 132 0.0029516998 +469 132 0.0030111999 +470 132 0.0030903998 +471 132 0.00067349989 +473 132 5.9399987e-05 +477 132 1.9799991e-05 +478 132 0.0010895999 +479 132 5.9399987e-05 +483 132 0.00073299999 +489 132 7.9199992e-05 +490 132 0.00057449983 +491 132 0.0016243998 +2 133 0.0011536998 +4 133 0.039515398 +22 133 0.0011536998 +60 133 0.0025958999 +104 133 0.00086529995 +114 133 0.00028839987 +130 133 0.008653 +132 133 0.28901064 +133 133 0.010383599 +138 133 0.00086529995 +143 133 0.0017305999 +171 133 0.046149399 +198 133 0.013556398 +206 133 0.00057689985 +214 133 0.029420197 +226 133 0.0028843 +227 133 0.090279758 +231 133 0.0040380992 +234 133 0.0028843 +240 133 0.00028839987 +241 133 0.011248898 +272 133 0.00057689985 +279 133 0.00057689985 +345 133 0.0106721 +358 133 0.00086529995 +443 133 0.0034611998 +444 133 0.00028839987 +445 133 0.015575398 +446 133 0.00057689985 +447 133 0.010383599 +450 133 0.0020189998 +452 133 0.012402698 +453 133 0.0017305999 +454 133 0.0020189998 +455 133 0.0409576 +457 133 0.0020189998 +458 133 0.00028839987 +460 133 0.00028839987 +463 133 0.026535898 +464 133 0.00057689985 +465 133 0.00086529995 +467 133 0.0072107986 +468 133 0.026535898 +469 133 0.0034611998 +470 133 0.0040380992 +471 133 0.0037495999 +478 133 0.00086529995 +483 133 0.0014421998 +490 133 0.0011536998 +491 133 0.00057689985 +2 134 3.2199998e-05 +4 134 0.00061109988 +22 134 0.00028939988 +60 134 0.0012863998 +82 134 3.2199998e-05 +104 134 3.2199998e-05 +108 134 3.2199998e-05 +114 134 3.2199998e-05 +126 134 3.2199998e-05 +130 134 0.028204799 +131 134 0.00032159989 +132 134 0.39058977 +133 134 3.2199998e-05 +134 134 0.035247996 +137 134 3.2199998e-05 +138 134 3.2199998e-05 +139 134 6.4299995e-05 +142 134 0.014247097 +143 134 0.046568498 +149 134 0.00028939988 +150 134 0.00041809981 +151 134 3.2199998e-05 +152 134 6.4299995e-05 +157 134 3.2199998e-05 +158 134 0.0047597997 +171 134 3.2199998e-05 +189 134 0.00048239995 +190 134 6.4299995e-05 +191 134 3.2199998e-05 +192 134 3.2199998e-05 +193 134 3.2199998e-05 +194 134 9.6499993e-05 +197 134 3.2199998e-05 +198 134 0.0052421987 +200 134 3.2199998e-05 +203 134 6.4299995e-05 +204 134 6.4299995e-05 +206 134 9.6499993e-05 +207 134 3.2199998e-05 +214 134 0.014793899 +223 134 3.2199998e-05 +224 134 3.2199998e-05 +225 134 0.018974699 +226 134 0.0019295998 +227 134 0.012542598 +231 134 0.0015758998 +234 134 0.0034411999 +237 134 9.6499993e-05 +240 134 0.027111299 +241 134 0.0048240982 +252 134 6.4299995e-05 +272 134 0.00051459996 +277 134 3.2199998e-05 +279 134 0.00012859999 +345 134 0.0020260999 +351 134 0.0027015 +356 134 6.4299995e-05 +358 134 0.00080399984 +384 134 0.00012859999 +387 134 3.2199998e-05 +402 134 3.2199998e-05 +422 134 9.6499993e-05 +430 134 3.2199998e-05 +433 134 3.2199998e-05 +434 134 3.2199998e-05 +443 134 0.0032803998 +444 134 0.0013506999 +445 134 0.0097124986 +446 134 0.0003537999 +447 134 0.0031516999 +448 134 3.2199998e-05 +450 134 0.0056923963 +452 134 0.004180897 +453 134 0.0034411999 +454 134 0.0035376998 +455 134 0.043995596 +456 134 0.00016079999 +457 134 0.0019617998 +458 134 0.00048239995 +459 134 0.00025729998 +460 134 0.00041809981 +463 134 0.0090692975 +464 134 0.000193 +465 134 0.00051459996 +467 134 0.0080400966 +468 134 0.019650098 +469 134 0.0019295998 +470 134 0.0021225999 +471 134 0.00077189994 +473 134 6.4299995e-05 +477 134 3.2199998e-05 +478 134 0.00064319978 +483 134 0.00073969993 +489 134 6.4299995e-05 +490 134 0.00032159989 +491 134 0.00025729998 +2 135 0.029029798 +23 135 0.0045836978 +60 135 0.0030558 +114 135 0.00076389988 +117 135 0.0015278999 +130 135 0.0068754964 +132 135 0.060351398 +134 135 0.0022918 +135 135 0.0022918 +138 135 0.11764705 +139 135 0.0022918 +142 135 0.0038196999 +143 135 0.073338389 +149 135 0.00076389988 +186 135 0.00076389988 +192 135 0.00076389988 +198 135 0.0022918 +206 135 0.00076389988 +214 135 0.019862499 +219 135 0.00076389988 +224 135 0.011459097 +225 135 0.0015278999 +226 135 0.0045836978 +227 135 0.033613399 +234 135 0.0068754964 +240 135 0.011459097 +241 135 0.0084033981 +243 135 0.00076389988 +272 135 0.00076389988 +279 135 0.0015278999 +345 135 0.0091672987 +358 135 0.0015278999 +442 135 0.010695197 +443 135 0.0068754964 +444 135 0.0038196999 +445 135 0.0076393969 +446 135 0.00076389988 +447 135 0.029793698 +450 135 0.0045836978 +452 135 0.0084033981 +453 135 0.0022918 +454 135 0.0015278999 +455 135 0.032849498 +457 135 0.0022918 +458 135 0.00076389988 +463 135 0.039724998 +464 135 0.00076389988 +465 135 0.00076389988 +467 135 0.0061114989 +468 135 0.0045836978 +469 135 0.0038196999 +470 135 0.0038196999 +471 135 0.00076389988 +478 135 0.00076389988 +483 135 0.0022918 +490 135 0.0015278999 +60 136 0.0062240995 +130 136 0.0020746998 +132 136 0.18672198 +136 136 0.016597498 +143 136 0.0020746998 +149 136 0.0062240995 +198 136 0.012448099 +206 136 0.0020746998 +214 136 0.0394191 +226 136 0.029045597 +227 136 0.010373399 +234 136 0.0082987994 +345 136 0.0082987994 +358 136 0.0020746998 +447 136 0.0020746998 +450 136 0.0041493997 +452 136 0.010373399 +453 136 0.0062240995 +455 136 0.018672198 +457 136 0.0020746998 +463 136 0.014522798 +467 136 0.0082987994 +468 136 0.016597498 +469 136 0.0041493997 +470 136 0.0041493997 +478 136 0.0020746998 +483 136 0.0041493997 +490 136 0.0020746998 +491 136 0.0020746998 +2 137 0.0018843999 +22 137 0.00062809978 +24 137 0.00062809978 +25 137 0.00062809978 +60 137 0.0031406998 +114 137 0.00062809978 +117 137 0.040200997 +130 137 0.010678399 +131 137 0.00062809978 +132 137 0.089195967 +133 137 0.00062809978 +134 137 0.00062809978 +135 137 0.021356799 +137 137 0.0031406998 +138 137 0.15515077 +142 137 0.0031406998 +143 137 0.0069094971 +149 137 0.00062809978 +158 137 0.00062809978 +160 137 0.00062809978 +161 137 0.00062809978 +178 137 0.00062809978 +186 137 0.00062809978 +187 137 0.0012562999 +188 137 0.00062809978 +192 137 0.0018843999 +193 137 0.0012562999 +198 137 0.015075397 +206 137 0.00062809978 +214 137 0.0050251 +219 137 0.0056532994 +223 137 0.0012562999 +224 137 0.0056532994 +225 137 0.00062809978 +226 137 0.0062813982 +227 137 0.0056532994 +234 137 0.0025125998 +240 137 0.0012562999 +241 137 0.0050251 +252 137 0.0012562999 +272 137 0.00062809978 +273 137 0.00062809978 +277 137 0.0012562999 +279 137 0.00062809978 +293 137 0.0012562999 +322 137 0.0037687998 +325 137 0.00062809978 +345 137 0.0037687998 +358 137 0.0012562999 +442 137 0.0012562999 +443 137 0.013191 +444 137 0.0012562999 +445 137 0.011934698 +446 137 0.0043969974 +447 137 0.0031406998 +450 137 0.0025125998 +452 137 0.0094220974 +453 137 0.0056532994 +454 137 0.0012562999 +455 137 0.039572898 +457 137 0.0018843999 +463 137 0.0075376965 +464 137 0.0012562999 +465 137 0.00062809978 +467 137 0.0056532994 +468 137 0.011934698 +469 137 0.0025125998 +470 137 0.0025125998 +471 137 0.00062809978 +478 137 0.00062809978 +483 137 0.0018843999 +490 137 0.026381899 +491 137 0.0012562999 +4 138 0.0418569 +60 138 0.0022830998 +130 138 0.0045661964 +132 138 0.0030440998 +138 138 0.0045661964 +142 138 0.0015220998 +143 138 0.0091323964 +186 138 0.00076099997 +192 138 0.00076099997 +198 138 0.0098934993 +206 138 0.00076099997 +214 138 0.025114197 +219 138 0.00076099997 +223 138 0.00076099997 +224 138 0.0015220998 +226 138 0.0038051999 +227 138 0.0060882978 +230 138 0.0091323964 +234 138 0.0030440998 +241 138 0.00076099997 +272 138 0.00076099997 +279 138 0.00076099997 +345 138 0.026636198 +358 138 0.0015220998 +443 138 0.0304414 +444 138 0.0068492964 +445 138 0.0053271987 +446 138 0.0022830998 +447 138 0.027397297 +450 138 0.0022830998 +452 138 0.0076103993 +453 138 0.0015220998 +454 138 0.0030440998 +455 138 0.15144598 +457 138 0.0022830998 +463 138 0.045662098 +464 138 0.00076099997 +465 138 0.042617999 +467 138 0.0045661964 +468 138 0.00076099997 +469 138 0.0022830998 +470 138 0.0022830998 +478 138 0.00076099997 +483 138 0.0015220998 +490 138 0.0015220998 +491 138 0.21308976 +2 139 0.0001161 +4 139 0.0001161 +60 139 0.0019734998 +82 139 0.0011608999 +108 139 0.0001161 +114 139 0.00023219999 +118 139 0.0001161 +126 139 0.0001161 +130 139 0.12955648 +131 139 0.020663999 +132 139 0.010215897 +134 139 0.0001161 +138 139 0.0001161 +139 139 0.0087067969 +140 139 0.0001161 +141 139 0.0001161 +142 139 0.027977698 +143 139 0.030647799 +149 139 0.068144858 +158 139 0.017993998 +160 139 0.0001161 +161 139 0.00023219999 +171 139 0.0001161 +184 139 0.00092869997 +187 139 0.00023219999 +188 139 0.0001161 +190 139 0.0001161 +194 139 0.00034829997 +198 139 0.012537699 +206 139 0.00023219999 +214 139 0.042256799 +219 139 0.0001161 +222 139 0.00023219999 +223 139 0.013930798 +224 139 0.063501298 +225 139 0.0032505 +226 139 0.00046439981 +227 139 0.00046439981 +230 139 0.0001161 +233 139 0.0069653988 +234 139 0.0033665998 +237 139 0.0001161 +239 139 0.0001161 +240 139 0.0012769999 +241 139 0.047596898 +243 139 0.00046439981 +252 139 0.00023219999 +272 139 0.00069649983 +276 139 0.0001161 +277 139 0.0012769999 +279 139 0.00058049988 +282 139 0.00034829997 +286 139 0.0001161 +290 139 0.0001161 +292 139 0.0001161 +293 139 0.00046439981 +294 139 0.0001161 +295 139 0.0001161 +300 139 0.00023219999 +312 139 0.00058049988 +315 139 0.0008125999 +319 139 0.0001161 +320 139 0.00023219999 +322 139 0.0001161 +326 139 0.00046439981 +340 139 0.00034829997 +345 139 0.0068492964 +349 139 0.00023219999 +350 139 0.0046435967 +356 139 0.0001161 +358 139 0.0011608999 +387 139 0.0001161 +392 139 0.00034829997 +393 139 0.0015091999 +422 139 0.0081262998 +443 139 0.0071975999 +444 139 0.0039470978 +445 139 0.011725098 +446 139 0.0008125999 +447 139 0.0071975999 +450 139 0.0018573999 +452 139 0.0070814975 +453 139 0.0034826999 +454 139 0.0012769999 +455 139 0.050383098 +456 139 0.0001161 +457 139 0.0035987999 +458 139 0.00034829997 +459 139 0.00034829997 +460 139 0.00069649983 +463 139 0.024611097 +464 139 0.0008125999 +465 139 0.010680299 +467 139 0.0049918965 +468 139 0.0022056999 +469 139 0.0032505 +470 139 0.0034826999 +471 139 0.004527498 +473 139 0.0001161 +478 139 0.00058049988 +483 139 0.0012769999 +490 139 0.0010447998 +491 139 0.0013930998 +4 140 0.018298399 +22 140 0.00031279982 +60 140 0.0014075998 +114 140 0.0001564 +130 140 0.0086017996 +132 140 0.0014075998 +140 140 0.022364698 +143 140 0.0001564 +186 140 0.00093839993 +187 140 0.0001564 +198 140 0.0075069964 +206 140 0.00031279982 +214 140 0.011729699 +223 140 0.0029714999 +225 140 0.017359998 +226 140 0.038160797 +227 140 0.56803244 +231 140 0.0001564 +234 140 0.00046919985 +241 140 0.0001564 +242 140 0.0064122975 +252 140 0.032999698 +272 140 0.00031279982 +279 140 0.00046919985 +334 140 0.0034406998 +345 140 0.012824498 +356 140 0.0001564 +358 140 0.00062559987 +443 140 0.0029714999 +444 140 0.0039098971 +445 140 0.0043790974 +446 140 0.0001564 +447 140 0.005317498 +450 140 0.0014075998 +452 140 0.0095401965 +453 140 0.0017203998 +454 140 0.0014075998 +455 140 0.035189196 +457 140 0.0018767999 +459 140 0.00031279982 +460 140 0.00031279982 +463 140 0.012824498 +464 140 0.0057866983 +465 140 0.0048482977 +467 140 0.0028150999 +468 140 0.0007819999 +469 140 0.0021895999 +470 140 0.0007819999 +471 140 0.00046919985 +478 140 0.00046919985 +483 140 0.0007819999 +490 140 0.0001564 +491 140 0.0001564 +2 141 0.00057939999 +4 141 0.0069524981 +60 141 0.0028968998 +114 141 0.00057939999 +130 141 0.0023174998 +132 141 0.070683658 +138 141 0.084588587 +143 141 0.018539999 +160 141 0.0011586999 +171 141 0.0011586999 +198 141 0.023754299 +206 141 0.0011586999 +214 141 0.0069524981 +224 141 0.0011586999 +227 141 0.11066049 +234 141 0.0034761999 +240 141 0.00057939999 +241 141 0.030706797 +271 141 0.0011586999 +272 141 0.00057939999 +277 141 0.0017380998 +279 141 0.0011586999 +312 141 0.00057939999 +326 141 0.00057939999 +345 141 0.0063731 +358 141 0.0023174998 +430 141 0.0011586999 +442 141 0.00057939999 +443 141 0.0069524981 +444 141 0.00057939999 +445 141 0.0086905994 +446 141 0.022595599 +447 141 0.0017380998 +450 141 0.0040555969 +452 141 0.011587497 +453 141 0.0017380998 +454 141 0.00057939999 +455 141 0.0330243 +457 141 0.0023174998 +458 141 0.00057939999 +459 141 0.0028968998 +460 141 0.00057939999 +463 141 0.011008099 +464 141 0.00057939999 +465 141 0.0040555969 +467 141 0.011587497 +468 141 0.025492497 +469 141 0.0046349987 +470 141 0.0040555969 +471 141 0.0017380998 +478 141 0.0017380998 +483 141 0.0017380998 +490 141 0.056199297 +491 141 0.00057939999 +2 142 0.00075669982 +4 142 0.00094589987 +6 142 0.00018919999 +22 142 0.0026484998 +24 142 0.00037839985 +60 142 0.0032159998 +84 142 0.00018919999 +104 142 0.00075669982 +114 142 0.00018919999 +117 142 0.00056749978 +118 142 0.00018919999 +130 142 0.012107499 +131 142 0.00018919999 +132 142 0.014755998 +133 142 0.00037839985 +135 142 0.00037839985 +137 142 0.00018919999 +138 142 0.033106297 +139 142 0.0011350999 +140 142 0.00018919999 +142 142 0.024404097 +143 142 0.031971198 +149 142 0.00018919999 +152 142 0.00037839985 +157 142 0.00018919999 +159 142 0.0034051999 +160 142 0.0013243 +171 142 0.00018919999 +186 142 0.0181612 +187 142 0.010593999 +188 142 0.00037839985 +189 142 0.00056749978 +192 142 0.011918299 +193 142 0.00018919999 +197 142 0.0032159998 +198 142 0.020431299 +204 142 0.00094589987 +206 142 0.00037839985 +208 142 0.0017025999 +214 142 0.086454749 +215 142 0.00037839985 +219 142 0.013999198 +221 142 0.00075669982 +223 142 0.0083238967 +224 142 0.016269397 +225 142 0.00037839985 +226 142 0.070942044 +227 142 0.060726397 +231 142 0.0030268999 +234 142 0.0045402981 +240 142 0.00018919999 +241 142 0.022890698 +243 142 0.00018919999 +252 142 0.00018919999 +272 142 0.00056749978 +279 142 0.00094589987 +322 142 0.00018919999 +324 142 0.00018919999 +326 142 0.00018919999 +345 142 0.0024593 +347 142 0.00018919999 +349 142 0.0017025999 +356 142 0.00018919999 +358 142 0.0011350999 +414 142 0.00018919999 +422 142 0.00018919999 +442 142 0.00018919999 +443 142 0.010404799 +444 142 0.0077562965 +445 142 0.015323497 +446 142 0.0013243 +447 142 0.0096480995 +450 142 0.0028376998 +452 142 0.0102157 +453 142 0.0017025999 +454 142 0.0054861978 +455 142 0.031782098 +457 142 0.0026484998 +458 142 0.00018919999 +459 142 0.00075669982 +460 142 0.00037839985 +463 142 0.015890997 +464 142 0.0049186982 +465 142 0.00056749978 +467 142 0.0081346966 +468 142 0.0088913999 +469 142 0.0035943999 +470 142 0.0032159998 +471 142 0.00056749978 +478 142 0.00075669982 +479 142 0.00037839985 +483 142 0.0013243 +489 142 0.00037839985 +490 142 0.00094589987 +491 142 0.0018918 +2 143 0.16462457 +4 143 0.0047124997 +60 143 0.0018849999 +114 143 0.00031419983 +117 143 0.00031419983 +130 143 0.00094249984 +132 143 0.057807099 +138 143 0.0065974966 +143 143 0.17844796 +149 143 0.0062833987 +171 143 0.0301602 +198 143 0.0087966993 +206 143 0.00062829978 +214 143 0.014451798 +223 143 0.0084825978 +224 143 0.00031419983 +226 143 0.0040841997 +227 143 0.025133498 +231 143 0.00031419983 +234 143 0.0043983981 +241 143 0.00094249984 +242 143 0.00031419983 +272 143 0.00094249984 +277 143 0.00031419983 +279 143 0.00031419983 +345 143 0.0037699998 +358 143 0.0012566999 +443 143 0.0031416998 +444 143 0.0141376 +445 143 0.016965099 +446 143 0.0018849999 +447 143 0.013823397 +450 143 0.0021992 +452 143 0.0081683993 +453 143 0.0015707999 +454 143 0.0135093 +455 143 0.033930298 +457 143 0.0015707999 +458 143 0.00094249984 +459 143 0.00031419983 +460 143 0.00031419983 +463 143 0.0094250999 +464 143 0.0081683993 +465 143 0.00031419983 +467 143 0.0053408965 +468 143 0.033301897 +469 143 0.0025133998 +470 143 0.0028275 +471 143 0.00094249984 +478 143 0.00062829978 +483 143 0.0018849999 +490 143 0.019792598 +491 143 0.0025133998 +4 144 0.00010929999 +22 144 0.00010929999 +60 144 0.0022957998 +114 144 0.00010929999 +126 144 0.00010929999 +132 144 0.22160268 +144 144 0.14245105 +145 144 0.0036076999 +146 144 0.00032799994 +149 144 0.00010929999 +150 144 0.0014211999 +187 144 0.00010929999 +189 144 0.00010929999 +190 144 0.00021869999 +193 144 0.027768698 +194 144 0.028315298 +198 144 0.0317044 +203 144 0.00010929999 +204 144 0.00076529989 +206 144 0.00021869999 +214 144 0.0027331 +227 144 0.027987298 +231 144 0.0064501986 +234 144 0.0019679 +237 144 0.00010929999 +241 144 0.0081993975 +272 144 0.00032799994 +279 144 0.00065599987 +345 144 0.0049195997 +358 144 0.0010932998 +422 144 0.00021869999 +443 144 0.0016398998 +444 144 0.0029517999 +445 144 0.0059035979 +446 144 0.00010929999 +447 144 0.0030610999 +450 144 0.0029517999 +452 144 0.0089646988 +453 144 0.0018584998 +454 144 0.00087459991 +455 144 0.042855598 +456 144 0.00010929999 +457 144 0.0067781992 +458 144 0.0010932998 +459 144 0.00021869999 +460 144 0.0017491998 +463 144 0.011479199 +464 144 0.0021864998 +465 144 0.0014211999 +467 144 0.012791097 +468 144 0.010932498 +469 144 0.0022957998 +470 144 0.0019679 +471 144 0.00087459991 +473 144 0.00010929999 +478 144 0.0016398998 +483 144 0.0025144999 +490 144 0.00021869999 +4 145 0.00033049984 +22 145 0.00033049984 +60 145 0.0019830998 +114 145 0.00016529999 +130 145 0.00066099991 +132 145 0.24838865 +144 145 0.0066104978 +145 145 0.13435799 +146 145 0.00049579982 +149 145 0.00066099991 +150 145 0.0013220999 +190 145 0.00016529999 +193 145 0.0099156983 +194 145 0.0026441999 +198 145 0.015038799 +203 145 0.00016529999 +204 145 0.011072498 +206 145 0.00033049984 +214 145 0.0072714984 +226 145 0.00033049984 +227 145 0.062303796 +231 145 0.0062799975 +234 145 0.0026441999 +237 145 0.00016529999 +241 145 0.017517798 +272 145 0.00049579982 +279 145 0.00049579982 +345 145 0.0094198994 +358 145 0.0011568 +422 145 0.00016529999 +434 145 0.00016529999 +443 145 0.0013220999 +444 145 0.0072714984 +445 145 0.0097504966 +447 145 0.007436797 +450 145 0.0029746999 +452 145 0.0064451993 +453 145 0.0023136998 +454 145 0.00066099991 +455 145 0.042472299 +456 145 0.00016529999 +457 145 0.0021483998 +459 145 0.00033049984 +460 145 0.0016525998 +463 145 0.0059493966 +464 145 0.00066099991 +465 145 0.0013220999 +467 145 0.0071062967 +468 145 0.011733599 +469 145 0.0018179 +470 145 0.0018179 +471 145 0.00082629989 +478 145 0.0016525998 +483 145 0.0026441999 +490 145 0.00033049984 +491 145 0.00016529999 +60 146 0.00088069984 +130 146 0.0017612998 +131 146 0.0074856989 +132 146 0.29854685 +133 146 0.015411697 +144 146 0.0026419999 +145 146 0.0022016999 +146 146 0.12549537 +149 146 0.015851997 +150 146 0.0030822998 +198 146 0.013650399 +226 146 0.00088069984 +227 146 0.0114487 +231 146 0.004843697 +234 146 0.0017612998 +272 146 0.00044029998 +279 146 0.00044029998 +345 146 0.0039629973 +358 146 0.00088069984 +436 146 0.004843697 +437 146 0.0079259984 +443 146 0.00044029998 +444 146 0.0022016999 +445 146 0.0070453994 +447 146 0.0017612998 +450 146 0.0035226999 +452 146 0.0044032969 +453 146 0.0013209998 +454 146 0.0017612998 +455 146 0.028181396 +457 146 0.0017612998 +458 146 0.00044029998 +459 146 0.00044029998 +460 146 0.0022016999 +463 146 0.011888999 +464 146 0.0022016999 +465 146 0.0013209998 +467 146 0.0061646998 +468 146 0.0026419999 +469 146 0.0017612998 +470 146 0.0017612998 +471 146 0.00088069984 +478 146 0.0013209998 +483 146 0.00088069984 +131 147 0.023809496 +132 147 0.28571427 +133 147 0.023809496 +147 147 0.023809496 +149 147 0.047618996 +194 147 0.023809496 +214 147 0.023809496 +226 147 0.023809496 +227 147 0.023809496 +445 147 0.023809496 +455 147 0.023809496 +467 147 0.023809496 +132 148 0.25 +227 148 0.083333254 +463 148 0.083333254 +2 149 5.3199998e-05 +4 149 0.0058772974 +18 149 0.0010372 +22 149 0.0001064 +60 149 0.00087759993 +104 149 5.3199998e-05 +108 149 2.6599999e-05 +114 149 5.3199998e-05 +126 149 2.6599999e-05 +130 149 0.011728097 +131 149 0.00023929999 +132 149 0.30360085 +133 149 0.00029249978 +138 149 5.3199998e-05 +139 149 2.6599999e-05 +142 149 5.3199998e-05 +143 149 0.00023929999 +144 149 5.3199998e-05 +145 149 5.3199998e-05 +146 149 0.0020744 +147 149 5.3199998e-05 +148 149 7.9799996e-05 +149 149 0.096138477 +150 149 0.00071799988 +151 149 0.00085099996 +171 149 0.0047337972 +190 149 7.9799996e-05 +192 149 5.3199998e-05 +193 149 2.6599999e-05 +194 149 0.0001064 +197 149 2.6599999e-05 +198 149 0.023722097 +200 149 2.6599999e-05 +203 149 5.3199998e-05 +204 149 7.9799996e-05 +206 149 5.3199998e-05 +207 149 2.6599999e-05 +214 149 0.025291197 +218 149 2.6599999e-05 +221 149 5.3199998e-05 +223 149 0.00013299999 +224 149 0.0001064 +225 149 0.0001064 +226 149 0.027604897 +227 149 0.078958571 +231 149 0.0071804971 +233 149 2.6599999e-05 +234 149 0.0029785999 +237 149 5.3199998e-05 +240 149 0.0001064 +241 149 0.011861097 +242 149 0.004122097 +252 149 0.00015959999 +272 149 0.0016488 +277 149 0.0001064 +279 149 0.00045209983 +282 149 2.6599999e-05 +315 149 2.6599999e-05 +326 149 2.6599999e-05 +335 149 0.0013828999 +336 149 2.6599999e-05 +345 149 0.0023136998 +351 149 0.0022338999 +358 149 0.00055849995 +387 149 2.6599999e-05 +402 149 2.6599999e-05 +421 149 2.6599999e-05 +422 149 0.0001064 +433 149 2.6599999e-05 +434 149 2.6599999e-05 +436 149 7.9799996e-05 +437 149 0.00013299999 +443 149 0.0030582999 +444 149 0.0013828999 +445 149 0.0065421984 +446 149 0.00031909999 +447 149 0.0012232999 +448 149 2.6599999e-05 +450 149 0.0014094999 +452 149 0.0069676973 +453 149 0.0022604999 +454 149 0.0021274998 +455 149 0.038003299 +456 149 7.9799996e-05 +457 149 0.0019147999 +458 149 0.00069149979 +459 149 0.00066489982 +460 149 0.0017551999 +463 149 0.0085633993 +464 149 0.0011435999 +465 149 0.00069149979 +467 149 0.0045741983 +468 149 0.0057709999 +469 149 0.0018881999 +470 149 0.0013563 +471 149 0.00050529977 +473 149 2.6599999e-05 +477 149 0.00082439999 +478 149 0.00079779979 +479 149 2.6599999e-05 +483 149 0.00074459985 +489 149 5.3199998e-05 +490 149 0.00015959999 +491 149 0.00018619999 +4 150 6.0799997e-05 +9 150 1.2199999e-05 +16 150 4.0999994e-06 +17 150 0.0029328 +18 150 4.0999994e-06 +22 150 3.6499987e-05 +60 150 0.00058819982 +79 150 4.0999994e-06 +82 150 1.6199992e-05 +83 150 1.6199992e-05 +84 150 0.00027579977 +108 150 2.4299996e-05 +113 150 3.2499986e-05 +114 150 8.1099992e-05 +126 150 4.0599989e-05 +127 150 4.0999994e-06 +130 150 0.16148525 +131 150 0.0065591969 +132 150 0.0249631 +133 150 0.0069688968 +135 150 7.709999e-05 +136 150 0.0019226999 +137 150 1.6199992e-05 +138 150 8.0999998e-06 +139 150 4.8699992e-05 +140 150 8.0999998e-06 +141 150 4.0999994e-06 +142 150 0.00038939994 +143 150 0.0014928 +144 150 0.00031229993 +145 150 0.00034069992 +146 150 0.0071067996 +147 150 0.00027579977 +149 150 0.12158644 +150 150 0.15409046 +151 150 4.0999994e-06 +152 150 1.2199999e-05 +155 150 0.0036954 +156 150 0.0087739974 +157 150 0.0025189999 +158 150 0.00056379987 +171 150 8.0999998e-06 +188 150 4.0999994e-06 +189 150 9.74e-05 +190 150 0.00017039999 +192 150 7.709999e-05 +193 150 0.0001947 +194 150 0.0004015998 +196 150 1.2199999e-05 +197 150 2.4299996e-05 +198 150 0.0050826967 +200 150 3.6499987e-05 +201 150 1.6199992e-05 +203 150 6.8999987e-05 +204 150 0.00029609981 +206 150 0.00017439999 +207 150 5.6799996e-05 +208 150 0.0001298 +209 150 1.6199992e-05 +214 150 0.00045029982 +219 150 4.0999994e-06 +222 150 1.2199999e-05 +223 150 2.4299996e-05 +224 150 3.2499986e-05 +225 150 0.00014599999 +226 150 0.00060849986 +227 150 0.0012290999 +231 150 0.00041779992 +234 150 0.0016711999 +237 150 0.0001582 +239 150 4.0999994e-06 +240 150 0.00018659999 +241 150 0.00064499979 +242 150 4.0999994e-06 +243 150 0.0057438985 +248 150 1.6199992e-05 +249 150 4.0999994e-06 +250 150 8.0999998e-06 +251 150 4.0999994e-06 +252 150 1.2199999e-05 +263 150 4.0999994e-06 +272 150 0.00011359999 +276 150 4.0999994e-06 +277 150 6.8999987e-05 +279 150 0.00010949999 +282 150 1.6199992e-05 +292 150 1.2199999e-05 +293 150 8.0999998e-06 +308 150 4.0999994e-06 +315 150 3.2499986e-05 +317 150 0.00079099997 +319 150 1.6199992e-05 +326 150 4.0999994e-06 +328 150 4.0999994e-06 +340 150 4.0999994e-06 +345 150 0.00034889998 +349 150 4.0999994e-06 +351 150 4.0999994e-06 +356 150 2.4299996e-05 +358 150 0.0003205 +363 150 4.0999994e-06 +380 150 4.0999994e-06 +382 150 0.00074639986 +384 150 8.0999998e-06 +387 150 3.2499986e-05 +394 150 1.2199999e-05 +397 150 1.2199999e-05 +402 150 6.0799997e-05 +409 150 4.0999994e-06 +412 150 4.0999994e-06 +419 150 4.0999994e-06 +422 150 8.1099992e-05 +423 150 8.0999998e-06 +425 150 4.0999994e-06 +430 150 2.0299995e-05 +431 150 1.2199999e-05 +432 150 1.2199999e-05 +433 150 4.459999e-05 +434 150 5.6799996e-05 +435 150 0.0010302998 +436 150 0.0035899 +437 150 0.0138404 +442 150 4.0999994e-06 +443 150 0.00054359995 +444 150 0.0022107 +445 150 0.0054842979 +446 150 0.00011359999 +447 150 0.0041374974 +448 150 2.4299996e-05 +449 150 8.0999998e-06 +450 150 0.004161898 +452 150 0.0032491998 +453 150 0.00070579979 +454 150 0.00033259997 +455 150 0.035749096 +456 150 0.00039349985 +457 150 0.0043321997 +458 150 0.00058409991 +459 150 0.00064089987 +460 150 0.00087619992 +463 150 0.0098286979 +464 150 0.0023567998 +465 150 0.0014886998 +467 150 0.012002897 +468 150 0.0055937991 +469 150 0.0033749 +470 150 0.0036791998 +471 150 0.0011357998 +472 150 8.1099992e-05 +473 150 7.709999e-05 +477 150 0.00011359999 +478 150 0.0016387999 +483 150 0.0026974999 +489 150 4.459999e-05 +490 150 0.00048679998 +491 150 0.00021499999 +4 151 0.00014559999 +84 151 0.00029119989 +114 151 0.00014559999 +126 151 0.00014559999 +130 151 0.44182318 +131 151 0.0020386998 +132 151 0.017474897 +133 151 0.0018930999 +134 151 0.00014559999 +136 151 0.0037862 +137 151 0.00072809984 +138 151 0.0005824999 +139 151 0.011795498 +141 151 0.0027669 +142 151 0.011212997 +143 151 0.00087369978 +149 151 0.00072809984 +151 151 0.030580997 +152 151 0.0013106 +155 151 0.0011649998 +157 151 0.00087369978 +158 151 0.00014559999 +171 151 0.00043689995 +184 151 0.00014559999 +190 151 0.00014559999 +193 151 0.010048099 +194 151 0.00029119989 +198 151 0.0042230971 +203 151 0.00014559999 +204 151 0.00014559999 +206 151 0.00029119989 +225 151 0.00014559999 +226 151 0.00014559999 +227 151 0.0005824999 +234 151 0.0017474999 +237 151 0.00029119989 +240 151 0.00043689995 +241 151 0.0055336989 +272 151 0.00029119989 +277 151 0.00029119989 +279 151 0.00014559999 +282 151 0.00014559999 +322 151 0.00014559999 +358 151 0.00072809984 +382 151 0.00029119989 +402 151 0.00014559999 +422 151 0.00029119989 +435 151 0.00014559999 +437 151 0.0052424967 +443 151 0.0005824999 +444 151 0.0040774979 +445 151 0.013106197 +447 151 0.0045142993 +450 151 0.0040774979 +452 151 0.0032036998 +453 151 0.00072809984 +454 151 0.00014559999 +455 151 0.036551598 +456 151 0.00014559999 +457 151 0.0026211999 +458 151 0.0005824999 +459 151 0.00029119989 +460 151 0.0016019 +463 151 0.038444698 +464 151 0.0046599992 +465 151 0.0065530986 +467 151 0.005824998 +468 151 0.015727397 +469 151 0.0027669 +470 151 0.0030580999 +471 151 0.0017474999 +473 151 0.00014559999 +477 151 0.0021843999 +478 151 0.0014561999 +483 151 0.0016019 +490 151 0.00029119989 +491 151 0.00014559999 +2 152 0.00062999991 +4 152 0.022501197 +13 152 0.00013499999 +22 152 0.00076499977 +24 152 4.4999993e-05 +60 152 0.00099009997 +84 152 0.0036001999 +104 152 0.00067499978 +108 152 4.4999993e-05 +114 152 8.9999987e-05 +117 152 4.4999993e-05 +120 152 4.4999993e-05 +126 152 4.4999993e-05 +130 152 0.33387339 +131 152 0.0040051974 +132 152 0.031906798 +133 152 0.0054452978 +136 152 0.0020250999 +137 152 0.0074703991 +138 152 0.0071103983 +139 152 0.012510698 +141 152 0.00017999999 +142 152 0.0103506 +143 152 0.0082354993 +144 152 4.4999993e-05 +145 152 4.4999993e-05 +149 152 0.0092254989 +150 152 0.0016200999 +151 152 0.00049499981 +152 152 0.014265798 +155 152 0.00031499984 +156 152 4.4999993e-05 +157 152 0.0092254989 +158 152 0.0018451 +160 152 0.00013499999 +161 152 8.9999987e-05 +171 152 0.0046802983 +178 152 4.4999993e-05 +189 152 8.9999987e-05 +190 152 0.00013499999 +192 152 0.00062999991 +193 152 0.0063452981 +194 152 8.9999987e-05 +198 152 0.0155259 +200 152 4.4999993e-05 +203 152 4.4999993e-05 +204 152 8.9999987e-05 +206 152 0.00013499999 +207 152 4.4999993e-05 +214 152 0.0096304975 +221 152 0.00049499981 +223 152 0.0016200999 +224 152 0.00080999988 +226 152 0.0096754991 +227 152 0.022096198 +230 152 8.9999987e-05 +231 152 0.0019351 +232 152 0.00017999999 +233 152 0.00017999999 +234 152 0.0018000999 +237 152 0.00013499999 +240 152 0.0027001 +241 152 0.014175799 +243 152 8.9999987e-05 +248 152 8.9999987e-05 +252 152 0.0017551 +253 152 0.00013499999 +271 152 4.4999993e-05 +272 152 0.00044999993 +277 152 0.00017999999 +279 152 0.000225 +300 152 0.00044999993 +315 152 0.00013499999 +317 152 4.4999993e-05 +319 152 0.00035999995 +322 152 0.000225 +326 152 0.00035999995 +335 152 0.00035999995 +336 152 0.00031499984 +345 152 0.0023850999 +350 152 8.9999987e-05 +356 152 8.9999987e-05 +358 152 0.00085499999 +365 152 8.9999987e-05 +382 152 0.00013499999 +387 152 4.4999993e-05 +402 152 4.4999993e-05 +414 152 4.4999993e-05 +421 152 0.00013499999 +422 152 0.00031499984 +433 152 4.4999993e-05 +434 152 8.9999987e-05 +435 152 0.0021150999 +437 152 0.00080999988 +442 152 0.00017999999 +443 152 0.0033302 +444 152 0.0018900998 +445 152 0.0117906 +446 152 0.00031499984 +447 152 0.0034651998 +450 152 0.0040501989 +452 152 0.0063903965 +453 152 0.0018451 +454 152 0.0026550998 +455 152 0.043832399 +456 152 0.00017999999 +457 152 0.0023850999 +458 152 0.00044999993 +459 152 0.00035999995 +460 152 0.0015300999 +463 152 0.010620598 +464 152 0.0027901998 +465 152 0.0010801 +467 152 0.0089104995 +468 152 0.012420699 +469 152 0.0025650999 +470 152 0.0028801998 +471 152 0.0012600999 +473 152 4.4999993e-05 +477 152 0.0010801 +478 152 0.0011250998 +479 152 0.00031499984 +483 152 0.0016200999 +489 152 4.4999993e-05 +490 152 0.00035999995 +491 152 0.00080999988 +4 153 0.0016991999 +60 153 0.0016991999 +114 153 0.00042479998 +130 153 0.15590477 +131 153 0.019965999 +132 153 0.030161399 +133 153 0.0042480975 +139 153 0.014443498 +143 153 0.28377229 +149 153 0.00084959995 +150 153 0.00084959995 +153 153 0.0046728998 +158 153 0.025913298 +187 153 0.031435899 +188 153 0.00042479998 +193 153 0.00042479998 +198 153 0.011469796 +206 153 0.00084959995 +214 153 0.0012743999 +219 153 0.00042479998 +221 153 0.00084959995 +223 153 0.00042479998 +224 153 0.0050976984 +226 153 0.00042479998 +227 153 0.0012743999 +234 153 0.00084959995 +241 153 0.0033984999 +242 153 0.0016991999 +272 153 0.00042479998 +279 153 0.00042479998 +358 153 0.00042479998 +437 153 0.00084959995 +443 153 0.0025489 +444 153 0.00042479998 +445 153 0.010195397 +450 153 0.0025489 +452 153 0.0038232999 +453 153 0.0012743999 +455 153 0.048852999 +457 153 0.0025489 +460 153 0.0012743999 +463 153 0.0093457997 +464 153 0.00042479998 +465 153 0.00084959995 +467 153 0.0042480975 +468 153 0.0016991999 +469 153 0.0025489 +470 153 0.0025489 +471 153 0.0012743999 +478 153 0.00084959995 +483 153 0.0012743999 +490 153 0.00042479998 +491 153 0.00042479998 +4 154 0.0003562998 +22 154 0.0003562998 +60 154 0.0010688 +114 154 0.0003562998 +130 154 0.19202 +131 154 0.028856397 +132 154 0.044531498 +133 154 0.0042749979 +137 154 0.0010688 +139 154 0.085500479 +141 154 0.0078374967 +142 154 0.0024937999 +143 154 0.0049874969 +149 154 0.0021374999 +150 154 0.0003562998 +152 154 0.0003562998 +154 154 0.0092625991 +157 154 0.0003562998 +158 154 0.027431399 +160 154 0.0003562998 +187 154 0.0003562998 +193 154 0.0014249999 +194 154 0.0003562998 +198 154 0.0056999996 +206 154 0.00071249995 +223 154 0.0003562998 +227 154 0.0003562998 +234 154 0.0014249999 +237 154 0.0010688 +241 154 0.0003562998 +252 154 0.0003562998 +272 154 0.0003562998 +277 154 0.0028499998 +279 154 0.0003562998 +282 154 0.00071249995 +283 154 0.0003562998 +293 154 0.0003562998 +312 154 0.0003562998 +315 154 0.0003562998 +328 154 0.0017812999 +329 154 0.00071249995 +345 154 0.0032062999 +350 154 0.0003562998 +351 154 0.0003562998 +354 154 0.00071249995 +358 154 0.0010688 +382 154 0.0003562998 +402 154 0.00071249995 +412 154 0.0003562998 +430 154 0.0003562998 +437 154 0.0363377 +443 154 0.0014249999 +444 154 0.0003562998 +445 154 0.0071249977 +447 154 0.00071249995 +450 154 0.0039187968 +452 154 0.0035624998 +453 154 0.0014249999 +455 154 0.047025297 +457 154 0.0021374999 +458 154 0.0003562998 +460 154 0.0014249999 +463 154 0.012112599 +464 154 0.00071249995 +465 154 0.0010688 +467 154 0.0067687966 +468 154 0.0024937999 +469 154 0.0042749979 +470 154 0.0042749979 +471 154 0.0014249999 +478 154 0.0014249999 +483 154 0.0021374999 +490 154 0.00071249995 +4 155 0.00033979979 +114 155 0.00033979979 +130 155 0.084947288 +132 155 0.17804956 +133 155 0.06252116 +135 155 0.0061161965 +137 155 0.0088344999 +139 155 0.00033979979 +142 155 0.032279998 +143 155 0.0040774979 +149 155 0.00033979979 +150 155 0.00067959982 +155 155 0.015630297 +157 155 0.00033979979 +171 155 0.00033979979 +187 155 0.00033979979 +190 155 0.00033979979 +193 155 0.013591599 +194 155 0.00033979979 +198 155 0.0040774979 +202 155 0.0013591999 +206 155 0.00067959982 +210 155 0.00033979979 +227 155 0.00033979979 +234 155 0.0016988998 +237 155 0.00033979979 +272 155 0.00033979979 +279 155 0.00033979979 +358 155 0.00067959982 +377 155 0.012572199 +382 155 0.00033979979 +437 155 0.0010193998 +443 155 0.00067959982 +444 155 0.0088344999 +445 155 0.0292219 +447 155 0.0142712 +450 155 0.0044172965 +452 155 0.0050967969 +453 155 0.0016988998 +455 155 0.032279998 +456 155 0.00033979979 +457 155 0.026163798 +460 155 0.0016988998 +463 155 0.027183097 +464 155 0.013591599 +465 155 0.013931397 +467 155 0.0057763979 +468 155 0.0020386998 +469 155 0.0030580999 +470 155 0.0033978999 +471 155 0.0016988998 +478 155 0.0016988998 +483 155 0.0016988998 +490 155 0.00033979979 +491 155 0.00033979979 +22 156 0.00025529996 +60 156 0.0015318999 +114 156 8.5099993e-05 +117 156 8.5099993e-05 +126 156 8.5099993e-05 +130 156 0.12017018 +131 156 0.016936198 +132 156 0.0194043 +133 156 0.011914898 +136 156 0.0013616998 +137 156 0.0065531991 +138 156 0.00017019999 +139 156 0.13455319 +142 156 0.035233997 +143 156 0.0003403998 +149 156 0.00085109985 +150 156 8.5099993e-05 +155 156 0.0068935975 +156 156 0.0020426 +157 156 8.5099993e-05 +158 156 0.0069786981 +171 156 8.5099993e-05 +172 156 8.5099993e-05 +188 156 8.5099993e-05 +189 156 8.5099993e-05 +190 156 8.5099993e-05 +194 156 0.0077446997 +198 156 0.0045956969 +203 156 8.5099993e-05 +204 156 0.006808497 +206 156 0.00017019999 +214 156 0.00051059993 +223 156 0.00017019999 +224 156 0.00068089995 +226 156 0.00025529996 +227 156 0.00051059993 +233 156 8.5099993e-05 +234 156 0.00093619991 +237 156 8.5099993e-05 +240 156 8.5099993e-05 +241 156 0.061361697 +243 156 0.026638299 +272 156 0.00017019999 +277 156 0.0094467998 +279 156 0.00025529996 +282 156 8.5099993e-05 +292 156 8.5099993e-05 +293 156 0.00017019999 +298 156 0.00017019999 +299 156 8.5099993e-05 +312 156 0.0003403998 +313 156 0.00076599978 +320 156 8.5099993e-05 +339 156 8.5099993e-05 +340 156 0.00017019999 +345 156 0.00017019999 +350 156 8.5099993e-05 +356 156 8.5099993e-05 +358 156 0.0005957 +382 156 8.5099993e-05 +402 156 8.5099993e-05 +422 156 0.00017019999 +434 156 8.5099993e-05 +437 156 0.00068089995 +443 156 0.0020426 +444 156 0.0039999969 +445 156 0.014893599 +446 156 0.00017019999 +447 156 0.0035744999 +450 156 0.0047659986 +452 156 0.0030637998 +453 156 0.0005957 +455 156 0.040680896 +456 156 8.5099993e-05 +457 156 0.0022127999 +458 156 0.0003403998 +459 156 0.00025529996 +460 156 0.0017020998 +463 156 0.013191499 +464 156 0.0029787 +465 156 0.00068089995 +467 156 0.0056169964 +468 156 0.00085109985 +469 156 0.0057871975 +470 156 0.0018722999 +471 156 0.00076599978 +473 156 8.5099993e-05 +477 156 0.0034893998 +478 156 0.00068089995 +479 156 0.0042552985 +483 156 0.0012765999 +490 156 0.00017019999 +491 156 0.00017019999 +60 157 0.0034188 +130 157 0.060683798 +132 157 0.15982908 +133 157 0.00085469987 +139 157 0.00085469987 +157 157 0.11025637 +198 157 0.0017094 +206 157 0.00085469987 +234 157 0.0025640999 +358 157 0.00085469987 +444 157 0.00085469987 +445 157 0.0025640999 +447 157 0.029059798 +450 157 0.0042734966 +452 157 0.0051281974 +455 157 0.0153846 +457 157 0.0034188 +460 157 0.00085469987 +463 157 0.041880298 +464 157 0.00085469987 +465 157 0.00085469987 +467 157 0.0051281974 +468 157 0.0017094 +469 157 0.0025640999 +470 157 0.0025640999 +471 157 0.0017094 +472 157 0.0085469969 +478 157 0.0017094 +483 157 0.0025640999 +490 157 0.00085469987 +2 158 0.0003994999 +4 158 0.0027965999 +23 158 0.0003994999 +60 158 0.0015980999 +84 158 0.0034624999 +104 158 0.00026629982 +114 158 0.0001332 +126 158 0.0001332 +130 158 0.14848846 +131 158 0.033959199 +132 158 0.094020486 +133 158 0.015181798 +134 158 0.00066589983 +135 158 0.0025302998 +137 158 0.018377896 +138 158 0.0011985998 +139 158 0.016912997 +141 158 0.014116399 +142 158 0.046077996 +143 158 0.0019975998 +149 158 0.023038998 +150 158 0.0025302998 +151 158 0.0001332 +152 158 0.0003994999 +155 158 0.0001332 +156 158 0.0001332 +157 158 0.00053269998 +158 158 0.026101999 +171 158 0.00026629982 +187 158 0.0027965999 +188 158 0.0001332 +190 158 0.0001332 +192 158 0.0001332 +193 158 0.0085230991 +194 158 0.00026629982 +198 158 0.013983198 +203 158 0.0001332 +206 158 0.00026629982 +214 158 0.0018644 +219 158 0.0001332 +221 158 0.0001332 +223 158 0.0071913972 +224 158 0.0015980999 +225 158 0.0003994999 +226 158 0.0037288999 +227 158 0.0093220994 +231 158 0.00026629982 +234 158 0.0023971 +237 158 0.0003994999 +240 158 0.00093219988 +241 158 0.0051937997 +243 158 0.0001332 +252 158 0.00026629982 +271 158 0.00026629982 +272 158 0.00066589983 +277 158 0.0038619998 +279 158 0.0003994999 +282 158 0.0026634999 +283 158 0.0010654 +292 158 0.0003994999 +293 158 0.00026629982 +295 158 0.0001332 +296 158 0.00053269998 +308 158 0.0001332 +312 158 0.0003994999 +313 158 0.00053269998 +315 158 0.0001332 +320 158 0.0001332 +326 158 0.0001332 +328 158 0.00026629982 +340 158 0.0001332 +345 158 0.0003994999 +351 158 0.00026629982 +357 158 0.00026629982 +358 158 0.0007989998 +382 158 0.00026629982 +397 158 0.0001332 +402 158 0.0023971 +412 158 0.00026629982 +422 158 0.0001332 +434 158 0.0001332 +437 158 0.012251999 +442 158 0.0001332 +443 158 0.0023971 +444 158 0.00026629982 +445 158 0.012118798 +446 158 0.00026629982 +447 158 0.0011985998 +450 158 0.0038619998 +452 158 0.0051937997 +453 158 0.0010654 +454 158 0.00026629982 +455 158 0.048475198 +456 158 0.0001332 +457 158 0.0026634999 +458 158 0.00093219988 +459 158 0.0003994999 +460 158 0.0017312998 +463 158 0.0094552971 +464 158 0.0003994999 +465 158 0.0010654 +467 158 0.0067917965 +468 158 0.0035956998 +469 158 0.0027965999 +470 158 0.0029298 +471 158 0.0021307999 +473 158 0.0001332 +478 158 0.0011985998 +483 158 0.0015980999 +490 158 0.00026629982 +491 158 0.0017312998 +3 159 4.2e-05 +9 159 2.1e-05 +16 159 0.00027299998 +17 159 0.35643339 +18 159 0.0015119999 +22 159 0.0036119998 +24 159 2.1e-05 +60 159 0.00081899995 +62 159 8.3999999e-05 +75 159 0.0018689998 +82 159 2.1e-05 +83 159 2.1e-05 +84 159 2.1e-05 +104 159 2.1e-05 +108 159 2.1e-05 +113 159 4.2e-05 +114 159 6.2999999e-05 +126 159 2.1e-05 +130 159 2.1e-05 +141 159 0.0020579998 +150 159 0.00079799979 +151 159 0.00079799979 +159 159 0.026312999 +160 159 0.003759 +161 159 2.1e-05 +165 159 0.0010289999 +170 159 2.1e-05 +186 159 0.00027299998 +190 159 6.2999999e-05 +192 159 2.1e-05 +194 159 2.1e-05 +198 159 0.00088199996 +200 159 2.1e-05 +206 159 4.2e-05 +214 159 0.00081899995 +215 159 0.00067199999 +217 159 0.000189 +218 159 0.000147 +219 159 0.000105 +220 159 0.00075599994 +223 159 6.2999999e-05 +224 159 6.2999999e-05 +233 159 0.0008609998 +234 159 0.033809997 +237 159 0.002226 +240 159 0.0017849999 +241 159 0.0041579977 +242 159 0.0013229998 +251 159 0.00062999991 +252 159 4.2e-05 +270 159 0.000105 +271 159 0.00060899998 +272 159 0.0016589998 +277 159 0.0044309981 +279 159 2.1e-05 +283 159 0.0040109977 +292 159 0.00060899998 +295 159 0.00058799982 +312 159 0.00088199996 +315 159 0.0017429998 +317 159 0.0034019998 +318 159 0.0068459995 +319 159 0.0098699965 +322 159 0.0534871 +326 159 0.0023729999 +329 159 8.3999999e-05 +331 159 0.00065099983 +334 159 0.00071399985 +335 159 4.2e-05 +337 159 0.0025829999 +340 159 0.00046199979 +341 159 0.0017219998 +346 159 0.0019739999 +349 159 0.000126 +350 159 2.1e-05 +352 159 4.2e-05 +354 159 0.0036749998 +356 159 2.1e-05 +358 159 0.00058799982 +372 159 0.00094499998 +374 159 0.00056699989 +384 159 0.00073499978 +387 159 2.1e-05 +394 159 0.000231 +397 159 4.2e-05 +398 159 0.00054599997 +400 159 0.0018059998 +401 159 2.1e-05 +402 159 0.0039269999 +412 159 0.00039899978 +417 159 0.000105 +421 159 2.1e-05 +423 159 2.1e-05 +430 159 2.1e-05 +431 159 2.1e-05 +442 159 0.00094499998 +443 159 0.0050399974 +444 159 0.0011339998 +445 159 0.006719999 +446 159 0.0021209999 +447 159 0.0026459999 +448 159 0.0008609998 +450 159 0.00079799979 +452 159 0.0011759999 +453 159 0.00048299995 +454 159 0.0008609998 +455 159 0.032697 +456 159 0.0025829999 +457 159 0.0018269999 +458 159 0.00050399988 +459 159 0.0013649999 +460 159 0.0021629999 +463 159 0.0040109977 +464 159 0.00065099983 +465 159 0.00052499981 +467 159 0.0096599981 +468 159 0.00079799979 +469 159 0.0021629999 +470 159 0.002289 +471 159 0.013250999 +473 159 4.2e-05 +477 159 0.00071399985 +478 159 0.00060899998 +483 159 0.000147 +489 159 0.00050399988 +490 159 0.000189 +491 159 8.3999999e-05 +9 160 1.6399994e-05 +17 160 0.0038231998 +18 160 0.00065629999 +22 160 0.0026089998 +60 160 0.0022971998 +75 160 0.0015915998 +82 160 1.6399994e-05 +83 160 1.6399994e-05 +84 160 1.6399994e-05 +108 160 1.6399994e-05 +113 160 3.2799988e-05 +114 160 4.9199996e-05 +117 160 1.6399994e-05 +126 160 1.6399994e-05 +130 160 6.559999e-05 +139 160 1.6399994e-05 +141 160 1.6399994e-05 +150 160 0.00049229991 +151 160 0.00044299988 +159 160 0.33716196 +160 160 0.070589364 +161 160 0.00014769999 +162 160 0.0001313 +163 160 1.6399994e-05 +165 160 0.0066782981 +170 160 0.00014769999 +171 160 0.0001313 +172 160 3.2799988e-05 +186 160 8.1999999e-05 +189 160 4.9199996e-05 +190 160 8.1999999e-05 +192 160 0.00034459983 +194 160 6.559999e-05 +197 160 1.6399994e-05 +198 160 8.1999999e-05 +200 160 3.2799988e-05 +203 160 3.2799988e-05 +204 160 3.2799988e-05 +206 160 6.559999e-05 +207 160 1.6399994e-05 +214 160 0.0016243998 +215 160 1.6399994e-05 +218 160 9.8499993e-05 +219 160 0.0005086998 +223 160 4.9199996e-05 +224 160 0.00057429983 +233 160 0.0009680998 +234 160 0.0093363971 +237 160 0.0012469999 +240 160 1.6399994e-05 +241 160 0.00068919989 +242 160 0.0005086998 +251 160 3.2799988e-05 +252 160 0.00057429983 +270 160 0.0009680998 +272 160 0.0010008998 +277 160 0.00067269988 +279 160 0.0005086998 +283 160 4.9199996e-05 +312 160 0.00060709985 +315 160 0.0012963 +317 160 0.0005086998 +318 160 0.0025104999 +319 160 0.0018048999 +322 160 0.0012635 +324 160 1.6399994e-05 +326 160 0.0069079995 +335 160 0.00063989987 +337 160 0.00082039996 +341 160 1.6399994e-05 +346 160 0.0012141999 +349 160 0.0026417999 +350 160 0.00041019986 +352 160 0.00067269988 +354 160 3.2799988e-05 +356 160 0.00014769999 +358 160 0.00063989987 +372 160 1.6399994e-05 +384 160 4.9199996e-05 +387 160 1.6399994e-05 +394 160 8.1999999e-05 +397 160 3.2799988e-05 +400 160 1.6399994e-05 +401 160 0.00031179981 +402 160 0.0010666 +417 160 0.00032819994 +421 160 4.9199996e-05 +422 160 4.9199996e-05 +423 160 1.6399994e-05 +430 160 1.6399994e-05 +431 160 1.6399994e-05 +433 160 1.6399994e-05 +434 160 1.6399994e-05 +442 160 1.6399994e-05 +443 160 0.019017499 +444 160 0.00055789994 +445 160 0.0055788979 +446 160 0.0017392999 +447 160 0.0019197999 +448 160 0.00019689999 +450 160 0.0015423999 +452 160 0.0095989965 +453 160 0.0019689999 +454 160 0.0011157999 +455 160 0.031323798 +456 160 0.0017720999 +457 160 0.0040856972 +458 160 0.00080399984 +459 160 0.0013126999 +460 160 0.0027565998 +463 160 0.0041184984 +464 160 0.00045939977 +465 160 0.00085319998 +467 160 0.010041997 +468 160 0.0027729999 +469 160 0.0027565998 +470 160 0.0016736998 +471 160 0.0091230981 +473 160 3.2799988e-05 +477 160 0.00045939977 +478 160 0.00085319998 +483 160 0.00059069996 +489 160 0.0005086998 +490 160 0.00014769999 +491 160 0.0011649998 +17 161 0.00068559987 +18 161 0.00034279982 +22 161 0.00034279982 +60 161 0.0025710999 +114 161 0.0001714 +126 161 0.0001714 +130 161 0.00034279982 +156 161 0.0001714 +159 161 0.082790494 +160 161 0.23260194 +161 161 0.014569797 +162 161 0.0001714 +165 161 0.0020568999 +170 161 0.00068559987 +171 161 0.00068559987 +190 161 0.0001714 +194 161 0.0001714 +198 161 0.0022282999 +206 161 0.00034279982 +214 161 0.0001714 +219 161 0.0017140999 +233 161 0.0022282999 +234 161 0.0059992969 +237 161 0.00068559987 +241 161 0.0011998999 +252 161 0.0001714 +270 161 0.0435379 +272 161 0.00051419996 +277 161 0.00051419996 +317 161 0.0001714 +318 161 0.0022282999 +319 161 0.00085699977 +322 161 0.0001714 +326 161 0.015940998 +346 161 0.0022282999 +349 161 0.0001714 +356 161 0.0001714 +358 161 0.0058278963 +402 161 0.0001714 +417 161 0.00068559987 +421 161 0.0001714 +422 161 0.0001714 +443 161 0.023825798 +444 161 0.0029139998 +445 161 0.0078847967 +446 161 0.0018854998 +447 161 0.0053136982 +450 161 0.0030854 +452 161 0.016112398 +453 161 0.0027424998 +454 161 0.0011998999 +455 161 0.056050699 +456 161 0.00085699977 +457 161 0.0042851977 +458 161 0.00051419996 +459 161 0.00034279982 +460 161 0.0015427 +463 161 0.010455899 +464 161 0.00051419996 +465 161 0.0015427 +467 161 0.0099416971 +468 161 0.0068563968 +469 161 0.0030854 +470 161 0.0034281998 +471 161 0.012684297 +473 161 0.0001714 +477 161 0.0001714 +478 161 0.0015427 +483 161 0.0011998999 +489 161 0.0001714 +490 161 0.00034279982 +491 161 0.0013712998 +17 162 0.0051753968 +60 162 0.0011500998 +114 162 0.00057499995 +159 162 0.29039675 +160 162 0.086256444 +161 162 0.028752197 +162 162 0.00057499995 +165 162 0.00057499995 +206 162 0.00057499995 +234 162 0.0063254982 +241 162 0.013800997 +270 162 0.00057499995 +272 162 0.00057499995 +277 162 0.00057499995 +317 162 0.00057499995 +318 162 0.0023001998 +319 162 0.0011500998 +322 162 0.00057499995 +346 162 0.0028751998 +358 162 0.0011500998 +417 162 0.00057499995 +443 162 0.021276597 +444 162 0.00057499995 +445 162 0.014951099 +446 162 0.0017251 +447 162 0.0034502998 +450 162 0.0023001998 +452 162 0.0069004968 +454 162 0.010350797 +455 162 0.033927497 +457 162 0.0028751998 +459 162 0.017826296 +460 162 0.0046002977 +463 162 0.0086255968 +464 162 0.00057499995 +465 162 0.0011500998 +467 162 0.0069004968 +468 162 0.0011500998 +469 162 0.0017251 +470 162 0.0017251 +471 162 0.0034502998 +478 162 0.0011500998 +483 162 0.0011500998 +490 162 0.00057499995 +491 162 0.0011500998 +18 163 0.00030919979 +22 163 0.00017669999 +60 163 0.0012808 +75 163 0.00013249999 +82 163 4.4199987e-05 +108 163 4.4199987e-05 +114 163 8.8299988e-05 +126 163 4.4199987e-05 +139 163 4.4199987e-05 +150 163 0.00057419995 +151 163 4.4199987e-05 +156 163 4.4199987e-05 +159 163 0.017710399 +160 163 0.24949205 +161 163 0.0032682999 +162 163 4.4199987e-05 +163 163 0.0022965998 +165 163 0.045137398 +170 163 0.006315697 +171 163 0.012852199 +184 163 4.4199987e-05 +187 163 4.4199987e-05 +189 163 4.4199987e-05 +190 163 8.8299988e-05 +192 163 0.0012365999 +194 163 8.8299988e-05 +198 163 0.0042840987 +200 163 4.4199987e-05 +203 163 4.4199987e-05 +204 163 4.4199987e-05 +206 163 8.8299988e-05 +214 163 4.4199987e-05 +215 163 0.0028265999 +219 163 0.0018107998 +224 163 4.4199987e-05 +233 163 0.0064923987 +234 163 0.0027382998 +236 163 4.4199987e-05 +237 163 0.00039749988 +240 163 0.00013249999 +241 163 0.0051673986 +252 163 0.016694598 +268 163 4.4199987e-05 +270 163 0.013338 +272 163 0.00052999984 +277 163 0.000795 +279 163 8.8299988e-05 +289 163 0.00035329978 +290 163 4.4199987e-05 +293 163 0.00070669991 +297 163 4.4199987e-05 +306 163 4.4199987e-05 +312 163 0.0063598976 +315 163 0.0077289976 +317 163 0.011041399 +318 163 0.0013249998 +319 163 0.040323298 +322 163 0.00052999984 +326 163 0.0065364987 +346 163 0.0012808 +349 163 4.4199987e-05 +358 163 0.0021640998 +387 163 4.4199987e-05 +402 163 0.00013249999 +417 163 0.00039749988 +421 163 4.4199987e-05 +422 163 8.8299988e-05 +430 163 4.4199987e-05 +434 163 4.4199987e-05 +438 163 4.4199987e-05 +443 163 0.026499398 +444 163 0.0021199998 +445 163 0.0076406971 +446 163 0.00159 +447 163 0.0041956976 +448 163 4.4199987e-05 +450 163 0.0018549999 +452 163 0.0052556992 +453 163 0.0012365999 +454 163 0.0010157998 +455 163 0.058475398 +456 163 0.00061829994 +457 163 0.006094899 +458 163 0.00057419995 +459 163 0.00039749988 +460 163 0.0022524998 +463 163 0.0094514973 +464 163 0.0014132999 +465 163 0.0010599999 +467 163 0.0071989968 +468 163 0.0052998997 +469 163 0.0029590998 +470 163 0.0032241 +471 163 0.0044165999 +473 163 8.8299988e-05 +477 163 8.8299988e-05 +478 163 0.0010157998 +483 163 0.00097159995 +489 163 8.8299988e-05 +490 163 0.00026499992 +491 163 0.00017669999 +18 164 0.00045799999 +22 164 0.000229 +60 164 0.0017175998 +108 164 0.0001145 +114 164 0.000229 +126 164 0.0001145 +139 164 0.0001145 +159 164 0.0010305999 +160 164 0.051757697 +161 164 0.035611998 +163 164 0.0001145 +164 164 0.0012595998 +165 164 0.080728292 +170 164 0.025535297 +171 164 0.015916597 +190 164 0.0001145 +192 164 0.0032062 +194 164 0.0001145 +198 164 0.0016031 +206 164 0.000229 +215 164 0.0001145 +219 164 0.013282899 +233 164 0.014771599 +234 164 0.0036642998 +237 164 0.00045799999 +240 164 0.0001145 +241 164 0.0320623 +252 164 0.00068699988 +270 164 0.0269094 +272 164 0.00068699988 +277 164 0.00057249982 +279 164 0.000229 +293 164 0.000229 +312 164 0.0018320999 +315 164 0.0067559965 +317 164 0.0069849975 +318 164 0.0017175998 +319 164 0.028512497 +326 164 0.010992799 +346 164 0.0018320999 +358 164 0.0042367987 +387 164 0.0001145 +402 164 0.000229 +417 164 0.00057249982 +421 164 0.0001145 +422 164 0.0001145 +438 164 0.0030916999 +443 164 0.018206798 +444 164 0.0027482 +445 164 0.006870497 +446 164 0.00057249982 +447 164 0.0037787999 +450 164 0.0025191999 +452 164 0.0056108981 +453 164 0.0016031 +454 164 0.00045799999 +455 164 0.048207898 +456 164 0.00045799999 +457 164 0.0042367987 +458 164 0.00080159982 +459 164 0.00045799999 +460 164 0.0064124987 +463 164 0.022100098 +464 164 0.00045799999 +465 164 0.0014885999 +467 164 0.010420199 +468 164 0.0045802966 +469 164 0.0041222982 +470 164 0.0044657998 +471 164 0.0090460964 +473 164 0.0001145 +477 164 0.0001145 +478 164 0.0014885999 +483 164 0.00091609987 +489 164 0.000229 +490 164 0.00045799999 +17 165 0.0015085 +18 165 0.00028069993 +22 165 0.0012278999 +60 165 0.0018944 +75 165 0.0074372999 +108 165 3.5099991e-05 +114 165 7.0199996e-05 +126 165 3.5099991e-05 +150 165 0.00045609986 +151 165 7.0199996e-05 +159 165 0.23322219 +160 165 0.018663399 +161 165 3.5099991e-05 +162 165 3.5099991e-05 +165 165 0.1547097 +170 165 0.0037185999 +171 165 0.00021049999 +190 165 7.0199996e-05 +192 165 0.0011225999 +194 165 7.0199996e-05 +198 165 0.00010519999 +200 165 3.5099991e-05 +203 165 3.5099991e-05 +204 165 3.5099991e-05 +206 165 7.0199996e-05 +214 165 0.00010519999 +218 165 3.5099991e-05 +219 165 0.015049998 +224 165 0.0052621998 +233 165 0.011296298 +234 165 0.0035432 +237 165 0.00031569996 +241 165 0.0025609999 +242 165 3.5099991e-05 +252 165 0.0001754 +270 165 0.0054726973 +272 165 0.00031569996 +277 165 0.00045609986 +279 165 3.5099991e-05 +312 165 7.0199996e-05 +315 165 0.00014029999 +317 165 0.0049464963 +318 165 0.0014382999 +319 165 0.0003858998 +322 165 0.00024559977 +326 165 0.0033326999 +335 165 3.5099991e-05 +337 165 0.00010519999 +346 165 0.0010173998 +349 165 0.0001754 +350 165 0.00084199989 +352 165 3.5099991e-05 +356 165 0.00014029999 +358 165 0.0015786998 +384 165 0.00014029999 +387 165 3.5099991e-05 +401 165 3.5099991e-05 +402 165 0.0001754 +404 165 7.0199996e-05 +417 165 0.00031569996 +421 165 3.5099991e-05 +422 165 7.0199996e-05 +434 165 3.5099991e-05 +443 165 0.023644999 +444 165 0.0018241999 +445 165 0.0067005977 +446 165 0.0014733998 +447 165 0.0012629 +448 165 3.5099991e-05 +450 165 0.0014382999 +452 165 0.0081739984 +453 165 0.0039641969 +454 165 0.00091209984 +455 165 0.0390458 +456 165 0.00045609986 +457 165 0.0047008991 +458 165 0.00042099995 +459 165 0.00035079988 +460 165 0.0016488 +463 165 0.0050516985 +464 165 0.0001754 +465 165 0.00080689997 +467 165 0.006139297 +468 165 0.0054726973 +469 165 0.0014382999 +470 165 0.0015085 +471 165 0.0037536998 +473 165 3.5099991e-05 +477 165 7.0199996e-05 +478 165 0.00080689997 +483 165 0.00031569996 +489 165 0.00014029999 +490 165 0.00014029999 +491 165 0.00056129997 +18 166 0.00021719999 +22 166 0.00021719999 +60 166 0.00086859986 +114 166 0.00021719999 +126 166 0.00021719999 +159 166 0.006731797 +160 166 0.33333325 +161 166 0.00086859986 +162 166 0.00043429993 +163 166 0.0017372 +164 166 0.00021719999 +165 166 0.014983699 +166 166 0.0045602992 +167 166 0.00043429993 +170 166 0.0045602992 +171 166 0.00065149995 +191 166 0.00021719999 +206 166 0.00021719999 +219 166 0.0043430999 +224 166 0.00086859986 +233 166 0.0076003969 +234 166 0.0028229998 +236 166 0.00043429993 +237 166 0.00043429993 +241 166 0.00065149995 +252 166 0.00065149995 +256 166 0.00043429993 +268 166 0.00043429993 +270 166 0.00086859986 +272 166 0.0028229998 +274 166 0.00021719999 +277 166 0.00021719999 +279 166 0.0062974989 +292 166 0.00021719999 +293 166 0.00021719999 +302 166 0.00021719999 +303 166 0.00021719999 +304 166 0.00021719999 +305 166 0.00043429993 +306 166 0.00065149995 +308 166 0.00021719999 +312 166 0.0060802996 +315 166 0.00021719999 +317 166 0.004777398 +318 166 0.0010857999 +319 166 0.0078175999 +324 166 0.00021719999 +326 166 0.020195398 +346 166 0.0013028998 +356 166 0.00021719999 +358 166 0.0056459978 +366 166 0.00043429993 +385 166 0.0052116998 +402 166 0.00021719999 +417 166 0.00043429993 +443 166 0.0286645 +444 166 0.0086861998 +445 166 0.0086861998 +446 166 0.0017372 +447 166 0.011509199 +450 166 0.0017372 +452 166 0.0028229998 +453 166 0.00086859986 +455 166 0.052117299 +456 166 0.00043429993 +457 166 0.0043430999 +458 166 0.00065149995 +459 166 0.0010857999 +460 166 0.0058631971 +463 166 0.017589599 +464 166 0.0089033991 +465 166 0.00065149995 +467 166 0.0065146983 +468 166 0.0013028998 +469 166 0.0032572998 +470 166 0.0036915999 +471 166 0.0021715998 +473 166 0.00021719999 +478 166 0.00086859986 +483 166 0.00043429993 +490 166 0.00043429993 +18 167 0.00019359999 +22 167 9.6799995e-05 +60 167 0.0008711 +108 167 9.6799995e-05 +114 167 0.00019359999 +126 167 9.6799995e-05 +134 167 0.0003870998 +139 167 9.6799995e-05 +159 167 0.0015485999 +160 167 0.16376305 +161 167 0.021196298 +162 167 0.0067750998 +163 167 0.041134298 +164 167 0.0076460987 +165 167 0.0564266 +166 167 9.6799995e-05 +167 167 0.009775497 +170 167 0.0035810999 +171 167 0.0090978965 +173 167 9.6799995e-05 +176 167 9.6799995e-05 +177 167 0.0015485999 +190 167 9.6799995e-05 +191 167 0.0061942972 +194 167 9.6799995e-05 +206 167 0.00019359999 +219 167 0.0003870998 +224 167 0.00029039988 +233 167 0.0028068 +234 167 0.0020325 +236 167 0.011033699 +237 167 0.0003870998 +240 167 9.6799995e-05 +241 167 0.0049360991 +252 167 0.00019359999 +256 167 0.0083236992 +259 167 0.0022260998 +268 167 0.010162599 +270 167 0.012679096 +272 167 0.00058069988 +274 167 0.0057103969 +277 167 0.0014517999 +279 167 0.0053232983 +289 167 0.00019359999 +292 167 0.0030003998 +293 167 0.0009678998 +295 167 0.0026131999 +302 167 0.0029036 +303 167 0.005032897 +304 167 0.0048392974 +305 167 0.0084203966 +306 167 0.013550099 +308 167 0.0039682984 +312 167 0.0010646998 +317 167 0.00019359999 +318 167 0.0009678998 +319 167 0.011227299 +324 167 0.0043553971 +326 167 0.0003870998 +346 167 0.0009678998 +356 167 0.00019359999 +358 167 0.0047424994 +366 167 0.0082268976 +377 167 0.00019359999 +378 167 0.00029039988 +383 167 0.00067749992 +385 167 0.0016454 +386 167 0.0017422 +387 167 9.6799995e-05 +402 167 0.00077429996 +415 167 0.0020325 +417 167 0.00029039988 +439 167 0.0020325 +443 167 0.023035198 +444 167 0.0009678998 +445 167 0.0133566 +446 167 0.0013549998 +447 167 0.0042585991 +450 167 0.0072589964 +452 167 0.0021292998 +453 167 0.00067749992 +454 167 0.0003870998 +455 167 0.060588498 +456 167 0.00029039988 +457 167 0.0041617975 +458 167 0.0010646998 +459 167 0.0003870998 +460 167 0.0059039965 +463 167 0.020905897 +464 167 0.00048389984 +465 167 0.0008711 +467 167 0.0063878968 +468 167 0.0036778999 +469 167 0.0032906998 +470 167 0.0037747 +471 167 0.0037747 +472 167 0.0019357 +473 167 9.6799995e-05 +477 167 9.6799995e-05 +478 167 0.0008711 +483 167 0.00058069988 +490 167 0.0003870998 +491 167 9.6799995e-05 +17 168 0.0010572998 +22 168 0.0002115 +60 168 0.0014801999 +114 168 0.0002115 +159 168 0.17635858 +160 168 0.21251845 +168 168 0.0074010976 +206 168 0.00042289984 +214 168 0.10467327 +233 168 0.010573097 +234 168 0.0046520978 +237 168 0.0002115 +272 168 0.00063439994 +317 168 0.0002115 +318 168 0.0002115 +322 168 0.0002115 +326 168 0.0088813975 +346 168 0.0012687999 +356 168 0.0002115 +358 168 0.00084579992 +417 168 0.00042289984 +443 168 0.028335799 +444 168 0.0002115 +445 168 0.0086698979 +446 168 0.002749 +447 168 0.010573097 +450 168 0.0019031998 +452 168 0.0067667998 +453 168 0.0078240968 +454 168 0.00084579992 +455 168 0.056037199 +456 168 0.0002115 +457 168 0.0025374999 +458 168 0.00063439994 +459 168 0.0002115 +460 168 0.0050750971 +463 168 0.0012687999 +464 168 0.00042289984 +465 168 0.00042289984 +467 168 0.0063437968 +468 168 0.00084579992 +469 168 0.0025374999 +470 168 0.0029604998 +471 168 0.0016917 +478 168 0.00063439994 +483 168 0.00063439994 +490 168 0.00042289984 +17 169 0.0020547998 +18 169 0.00034249993 +22 169 0.00068489998 +60 169 0.0075341985 +114 169 0.00034249993 +159 169 0.073287666 +160 169 0.28150678 +161 169 0.004794497 +162 169 0.0017122999 +165 169 0.0023973 +169 169 0.0044520982 +170 169 0.00034249993 +171 169 0.0027396998 +172 169 0.00034249993 +188 169 0.0017122999 +198 169 0.0010273999 +206 169 0.00068489998 +219 169 0.0013698998 +224 169 0.0020547998 +233 169 0.00034249993 +234 169 0.0041095987 +237 169 0.00034249993 +270 169 0.0010273999 +272 169 0.00068489998 +277 169 0.0010273999 +279 169 0.030479498 +315 169 0.00034249993 +318 169 0.0020547998 +319 169 0.00034249993 +322 169 0.00034249993 +326 169 0.00068489998 +346 169 0.0023973 +358 169 0.0017122999 +417 169 0.00068489998 +438 169 0.0027396998 +443 169 0.027397297 +444 169 0.00034249993 +445 169 0.024315096 +446 169 0.0017122999 +447 169 0.0023973 +450 169 0.0034246999 +452 169 0.0092465989 +453 169 0.0054794997 +455 169 0.044862997 +456 169 0.00034249993 +457 169 0.0023973 +458 169 0.0023973 +459 169 0.00068489998 +460 169 0.0013698998 +463 169 0.004794497 +464 169 0.00068489998 +465 169 0.00068489998 +467 169 0.013013698 +468 169 0.0051369965 +469 169 0.0037670999 +470 169 0.0041095987 +471 169 0.0034246999 +478 169 0.0013698998 +483 169 0.0010273999 +490 169 0.00068489998 +491 169 0.00034249993 +22 170 0.00067869993 +60 170 0.0023752998 +114 170 0.00033929991 +159 170 0.015269797 +160 170 0.087885976 +161 170 0.0074651986 +162 170 0.0095011964 +165 170 0.010519199 +170 170 0.00033929991 +206 170 0.00033929991 +219 170 0.17237866 +233 170 0.0010179998 +234 170 0.016966399 +241 170 0.014591098 +270 170 0.019002397 +272 170 0.0023752998 +277 170 0.00033929991 +315 170 0.0020359999 +317 170 0.00033929991 +318 170 0.00033929991 +319 170 0.00033929991 +326 170 0.012894496 +346 170 0.0016965999 +358 170 0.0010179998 +417 170 0.00033929991 +438 170 0.0074651986 +443 170 0.010858499 +444 170 0.003054 +445 170 0.024092298 +446 170 0.00067869993 +447 170 0.0159484 +450 170 0.0020359999 +452 170 0.0288429 +453 170 0.0098404996 +454 170 0.0013573 +455 170 0.047845297 +457 170 0.0023752998 +458 170 0.00067869993 +459 170 0.00067869993 +460 170 0.0010179998 +463 170 0.012215797 +464 170 0.00067869993 +465 170 0.00033929991 +467 170 0.0074651986 +468 170 0.015609097 +469 170 0.0023752998 +470 170 0.0023752998 +471 170 0.0016965999 +478 170 0.00067869993 +483 170 0.00067869993 +490 170 0.00033929991 +491 170 0.00033929991 +13 171 6.6999986e-05 +18 171 0.00033519999 +22 171 0.00093849981 +24 171 0.00046919985 +60 171 0.0024132 +75 171 6.6999986e-05 +82 171 0.00013409999 +104 171 0.00020109999 +107 171 0.00020109999 +108 171 6.6999986e-05 +114 171 6.6999986e-05 +126 171 6.6999986e-05 +130 171 0.00060329982 +131 171 6.6999986e-05 +132 171 6.6999986e-05 +139 171 6.6999986e-05 +150 171 0.00093849981 +156 171 6.6999986e-05 +159 171 0.032041799 +160 171 0.13601017 +161 171 0.011730798 +162 171 0.0065021999 +163 171 6.6999986e-05 +165 171 0.010457199 +169 171 0.0010724999 +170 171 0.013473697 +171 171 0.056374799 +172 171 0.00093849981 +186 171 0.0012065999 +187 171 0.00033519999 +188 171 6.6999986e-05 +189 171 6.6999986e-05 +190 171 0.00013409999 +191 171 0.0004021998 +192 171 0.0049604997 +193 171 0.00053629978 +194 171 0.00013409999 +198 171 0.032913297 +200 171 6.6999986e-05 +203 171 6.6999986e-05 +204 171 6.6999986e-05 +206 171 6.6999986e-05 +207 171 6.6999986e-05 +214 171 0.0010054999 +219 171 0.010993399 +223 171 6.6999986e-05 +224 171 0.0091164969 +225 171 6.6999986e-05 +233 171 0.0081109963 +234 171 0.0043571964 +237 171 0.0004021998 +240 171 0.00026809983 +241 171 0.0062340982 +252 171 0.0029495 +267 171 0.00013409999 +270 171 0.016154997 +272 171 0.0011395998 +273 171 0.00013409999 +277 171 0.0012065999 +279 171 0.00020109999 +282 171 6.6999986e-05 +285 171 6.6999986e-05 +292 171 0.00013409999 +293 171 0.00020109999 +298 171 6.6999986e-05 +312 171 0.00046919985 +313 171 0.0047593974 +315 171 0.0085801966 +317 171 0.00013409999 +318 171 0.0017428999 +319 171 0.0030834998 +322 171 0.0004021998 +325 171 6.6999986e-05 +326 171 0.0053625964 +334 171 6.6999986e-05 +340 171 0.00020109999 +346 171 0.0018098999 +347 171 6.6999986e-05 +350 171 0.00020109999 +356 171 0.00013409999 +358 171 0.0016758 +387 171 6.6999986e-05 +402 171 0.00020109999 +417 171 0.00060329982 +421 171 6.6999986e-05 +422 171 6.6999986e-05 +430 171 6.6999986e-05 +431 171 6.6999986e-05 +433 171 6.6999986e-05 +434 171 0.00013409999 +438 171 0.0018098999 +442 171 0.00026809983 +443 171 0.018836297 +444 171 0.00087139988 +445 171 0.0090494975 +446 171 0.0023461999 +447 171 0.0075076967 +448 171 6.6999986e-05 +450 171 0.0031505998 +452 171 0.0146803 +453 171 0.0089823976 +454 171 0.00087139988 +455 171 0.044040799 +456 171 0.00053629978 +457 171 0.0026143 +458 171 0.00067029987 +459 171 0.00053629978 +460 171 0.0014746999 +463 171 0.011730798 +464 171 0.0004021998 +465 171 0.0010724999 +467 171 0.0091835 +468 171 0.0095186979 +469 171 0.0042230971 +470 171 0.0045582987 +471 171 0.0057647973 +473 171 0.00013409999 +477 171 6.6999986e-05 +478 171 0.0014076999 +483 171 0.0010724999 +489 171 0.00020109999 +490 171 0.0004021998 +491 171 0.0010054999 +17 172 0.0017462999 +18 172 0.00043659983 +60 172 0.0028378 +114 172 0.00021829999 +126 172 0.00021829999 +159 172 0.058284197 +160 172 0.21305388 +161 172 0.0032743998 +162 172 0.054136697 +165 172 0.067015886 +169 172 0.0024011999 +170 172 0.00043659983 +171 172 0.00043659983 +172 172 0.0106964 +190 172 0.00021829999 +194 172 0.00021829999 +206 172 0.00043659983 +233 172 0.00021829999 +234 172 0.004584197 +237 172 0.00043659983 +241 172 0.00043659983 +252 172 0.00043659983 +270 172 0.00021829999 +272 172 0.00043659983 +277 172 0.023139097 +279 172 0.017026898 +312 172 0.0021829 +315 172 0.00021829999 +317 172 0.00021829999 +318 172 0.0017462999 +319 172 0.0010914998 +322 172 0.00021829999 +326 172 0.00021829999 +346 172 0.0019645998 +356 172 0.00021829999 +358 172 0.0019645998 +402 172 0.00021829999 +417 172 0.00065489998 +442 172 0.0010914998 +443 172 0.029906098 +444 172 0.00021829999 +445 172 0.0111329 +446 172 0.0024011999 +447 172 0.0015280999 +450 172 0.0034926999 +452 172 0.0082950965 +453 172 0.0024011999 +454 172 0.00043659983 +455 172 0.058502499 +456 172 0.00043659983 +457 172 0.0028378 +458 172 0.0008731999 +459 172 0.013752498 +460 172 0.0010914998 +463 172 0.0072036982 +464 172 0.00043659983 +465 172 0.0010914998 +467 172 0.0098231994 +468 172 0.0019645998 +469 172 0.0032743998 +470 172 0.0037109999 +471 172 0.0030560999 +473 172 0.00021829999 +478 172 0.0015280999 +483 172 0.0013098 +490 172 0.00043659983 +491 172 0.00021829999 +9 173 3.6199999e-05 +18 173 0.00018079999 +22 173 0.0005063999 +60 173 0.0027849998 +82 173 3.6199999e-05 +83 173 3.6199999e-05 +84 173 3.6199999e-05 +108 173 3.6199999e-05 +113 173 7.2299998e-05 +114 173 7.2299998e-05 +117 173 7.2299998e-05 +126 173 3.6199999e-05 +130 173 0.0043040998 +131 173 3.6199999e-05 +132 173 3.6199999e-05 +133 173 7.2299998e-05 +137 173 0.00061489991 +139 173 0.0040870979 +141 173 3.6199999e-05 +143 173 3.6199999e-05 +149 173 7.2299998e-05 +150 173 0.0011211999 +151 173 3.6199999e-05 +154 173 3.6199999e-05 +159 173 0.00018079999 +160 173 0.094437182 +161 173 0.041630499 +162 173 0.0030743999 +165 173 0.037507199 +169 173 0.0005063999 +170 173 0.019133396 +171 173 0.022280097 +172 173 0.00043399981 +173 173 0.0013382998 +175 173 3.6199999e-05 +176 173 3.6199999e-05 +178 173 3.6199999e-05 +188 173 3.6199999e-05 +189 173 7.2299998e-05 +190 173 0.0001447 +192 173 0.0014829 +194 173 0.00054249982 +198 173 0.019386597 +200 173 0.0001085 +203 173 0.0001447 +204 173 7.2299998e-05 +206 173 0.00021699999 +207 173 7.2299998e-05 +214 173 0.0001447 +219 173 0.00021699999 +223 173 3.6199999e-05 +224 173 0.00054249982 +225 173 3.6199999e-05 +227 173 3.6199999e-05 +233 173 0.018807899 +234 173 0.0030019998 +237 173 0.00036169984 +240 173 0.00021699999 +241 173 0.0326606 +243 173 0.0001447 +252 173 0.0088251978 +270 173 0.012080397 +272 173 0.00068719988 +277 173 0.0027849998 +279 173 0.00075949985 +282 173 3.6199999e-05 +283 173 3.6199999e-05 +293 173 0.00028939988 +296 173 3.6199999e-05 +312 173 0.0064380988 +315 173 0.0001085 +317 173 0.0067635998 +318 173 0.0020615999 +319 173 0.030164897 +322 173 0.0013744 +326 173 0.0014105998 +346 173 0.0026764998 +356 173 0.0001085 +358 173 0.0010851 +372 173 3.6199999e-05 +384 173 3.6199999e-05 +387 173 3.6199999e-05 +391 173 3.6199999e-05 +393 173 7.2299998e-05 +394 173 3.6199999e-05 +397 173 3.6199999e-05 +402 173 0.00018079999 +419 173 3.6199999e-05 +422 173 0.0001447 +423 173 3.6199999e-05 +427 173 3.6199999e-05 +428 173 7.2299998e-05 +430 173 0.00021699999 +431 173 3.6199999e-05 +432 173 3.6199999e-05 +433 173 7.2299998e-05 +434 173 7.2299998e-05 +437 173 7.2299998e-05 +438 173 0.0013020998 +443 173 0.017433397 +444 173 0.0013020998 +445 173 0.0073422976 +446 173 0.0010851 +447 173 0.0036531 +448 173 3.6199999e-05 +450 173 0.0038339 +452 173 0.0061848983 +453 173 0.0011574 +454 173 0.0003254998 +455 173 0.056351297 +456 173 0.00047019986 +457 173 0.0033998999 +458 173 0.00043399981 +459 173 0.0003254998 +460 173 0.0061486997 +463 173 0.0098017976 +464 173 0.0005063999 +465 173 0.0012296999 +467 173 0.014322899 +468 173 0.0112486 +469 173 0.0031466999 +470 173 0.0035446 +471 173 0.0026041998 +473 173 7.2299998e-05 +477 173 0.0001447 +478 173 0.0015913998 +483 173 0.0011574 +489 173 0.0001085 +490 173 0.00028939988 +491 173 0.0003254998 +60 174 0.0020682998 +114 174 0.00051709986 +130 174 0.0046535991 +139 174 0.0031023999 +159 174 0.0010340998 +160 174 0.0062047988 +161 174 0.043433297 +165 174 0.012926597 +170 174 0.0010340998 +171 174 0.013443597 +187 174 0.00051709986 +192 174 0.00051709986 +193 174 0.00051709986 +194 174 0.0010340998 +197 174 0.00051709986 +198 174 0.020682499 +206 174 0.00051709986 +214 174 0.0051705986 +219 174 0.020682499 +224 174 0.029472597 +225 174 0.00051709986 +233 174 0.00051709986 +234 174 0.0036193999 +240 174 0.00051709986 +241 174 0.16287488 +252 174 0.0015511999 +272 174 0.00051709986 +274 174 0.00051709986 +277 174 0.0025852998 +279 174 0.0010340998 +282 174 0.00051709986 +292 174 0.00051709986 +293 174 0.0010340998 +294 174 0.00051709986 +295 174 0.00051709986 +312 174 0.00051709986 +315 174 0.0020682998 +318 174 0.00051709986 +319 174 0.016028997 +320 174 0.0010340998 +322 174 0.0010340998 +326 174 0.0020682998 +338 174 0.00051709986 +340 174 0.0010340998 +349 174 0.00051709986 +350 174 0.00051709986 +358 174 0.0020682998 +373 174 0.00051709986 +385 174 0.00051709986 +392 174 0.0010340998 +393 174 0.0062047988 +442 174 0.00051709986 +443 174 0.0046535991 +444 174 0.008272998 +445 174 0.0087900981 +447 174 0.023267798 +450 174 0.0031023999 +452 174 0.010858297 +453 174 0.00051709986 +455 174 0.0506722 +457 174 0.004136499 +458 174 0.00051709986 +459 174 0.024301998 +460 174 0.0051705986 +463 174 0.013443597 +464 174 0.0020682998 +465 174 0.0010340998 +467 174 0.0072388984 +468 174 0.020682499 +469 174 0.0036193999 +470 174 0.004136499 +471 174 0.0025852998 +478 174 0.0010340998 +479 174 0.00051709986 +490 174 0.0067217983 +491 174 0.00051709986 +22 175 0.00063229981 +60 175 0.0022131 +114 175 0.00031619985 +126 175 0.00031619985 +150 175 0.00031619985 +159 175 0.0031615999 +160 175 0.075877249 +161 175 0.036990199 +162 175 0.0123301 +165 175 0.053430296 +170 175 0.026240896 +171 175 0.024660099 +174 175 0.00063229981 +175 175 0.0018968999 +190 175 0.00031619985 +192 175 0.00031619985 +194 175 0.00031619985 +198 175 0.0237117 +206 175 0.00063229981 +219 175 0.00063229981 +233 175 0.016756199 +234 175 0.0025291999 +237 175 0.00031619985 +241 175 0.042680997 +252 175 0.00094849989 +270 175 0.015491597 +272 175 0.00063229981 +277 175 0.00063229981 +279 175 0.0012645999 +295 175 0.00031619985 +312 175 0.00094849989 +315 175 0.00063229981 +317 175 0.0063230991 +318 175 0.0022131 +319 175 0.035093296 +322 175 0.0063230991 +326 175 0.0069553964 +340 175 0.00031619985 +358 175 0.0012645999 +386 175 0.00031619985 +387 175 0.0012645999 +391 175 0.0041099973 +392 175 0.00063229981 +393 175 0.0041099973 +422 175 0.00031619985 +443 175 0.019285496 +444 175 0.00031619985 +445 175 0.0079039 +446 175 0.0012645999 +447 175 0.0098007992 +450 175 0.0041099973 +452 175 0.0066392981 +453 175 0.0012645999 +454 175 0.00063229981 +455 175 0.046790998 +456 175 0.00031619985 +457 175 0.0018968999 +458 175 0.00094849989 +459 175 0.00031619985 +460 175 0.0053745992 +463 175 0.035409398 +464 175 0.00031619985 +465 175 0.0022131 +467 175 0.010116998 +468 175 0.011381596 +469 175 0.0034776998 +470 175 0.0037938999 +471 175 0.0028453998 +473 175 0.00031619985 +478 175 0.0015807999 +483 175 0.0015807999 +490 175 0.00063229981 +491 175 0.00031619985 +9 176 4.9599999e-05 +18 176 0.0012888999 +22 176 9.9099998e-05 +60 176 0.0014375998 +82 176 4.9599999e-05 +83 176 4.9599999e-05 +84 176 4.9599999e-05 +108 176 4.9599999e-05 +114 176 9.9099998e-05 +117 176 0.0062462986 +126 176 4.9599999e-05 +130 176 0.13315487 +131 176 0.0029247999 +132 176 0.0016854999 +133 176 0.003024 +137 176 0.011302799 +139 176 0.018193498 +141 176 0.0027265998 +143 176 0.0036684999 +149 176 0.0015864 +150 176 0.0011401998 +152 176 4.9599999e-05 +156 176 0.00039659999 +158 176 9.9099998e-05 +160 176 0.043575298 +161 176 0.052845497 +162 176 0.0016854999 +165 176 0.0052547976 +170 176 0.0011401998 +171 176 0.010360897 +172 176 0.0001983 +173 176 4.9599999e-05 +176 176 0.0016358998 +178 176 0.00024789991 +187 176 0.0006444999 +189 176 9.9099998e-05 +190 176 0.0001487 +192 176 4.9599999e-05 +194 176 0.0001983 +197 176 4.9599999e-05 +198 176 0.010013897 +200 176 4.9599999e-05 +203 176 9.9099998e-05 +204 176 4.9599999e-05 +206 176 0.0001983 +207 176 4.9599999e-05 +214 176 4.9599999e-05 +219 176 0.0014871999 +233 176 0.003024 +234 176 0.0027265998 +237 176 0.00034699985 +240 176 0.010162599 +241 176 0.044715397 +243 176 0.0066428967 +252 176 0.00034699985 +270 176 0.0017847 +272 176 0.00049569993 +277 176 0.00044619991 +279 176 0.00049569993 +293 176 4.9599999e-05 +312 176 0.0047094971 +315 176 4.9599999e-05 +317 176 0.0066923983 +318 176 0.0017350998 +319 176 0.014673799 +322 176 0.023844898 +326 176 0.00024789991 +346 176 9.9099998e-05 +356 176 9.9099998e-05 +358 176 0.0010409998 +387 176 4.9599999e-05 +402 176 0.0001487 +422 176 0.0001487 +423 176 4.9599999e-05 +430 176 4.9599999e-05 +433 176 4.9599999e-05 +434 176 4.9599999e-05 +437 176 0.0045111999 +438 176 4.9599999e-05 +442 176 4.9599999e-05 +443 176 0.0078821965 +444 176 0.0016854999 +445 176 0.0089727975 +446 176 0.00054529984 +447 176 0.0054530986 +448 176 4.9599999e-05 +450 176 0.0036189 +452 176 0.0034701999 +453 176 0.00089229993 +454 176 0.0016854999 +455 176 0.049573697 +456 176 0.00044619991 +457 176 0.0023299998 +458 176 0.00049569993 +459 176 0.00034699985 +460 176 0.0013881 +463 176 0.013682298 +464 176 0.0013881 +465 176 0.0011898 +467 176 0.012839597 +468 176 0.010063499 +469 176 0.0037675998 +470 176 0.0040649995 +471 176 0.004312899 +473 176 9.9099998e-05 +477 176 0.0020325 +478 176 0.0013384998 +483 176 0.0012392998 +489 176 9.9099998e-05 +490 176 0.00034699985 +491 176 0.0001983 +22 177 0.00022939999 +60 177 0.0017205998 +108 177 0.00011469999 +114 177 0.00022939999 +117 177 0.00011469999 +126 177 0.00011469999 +130 177 0.0020646998 +131 177 0.00057349983 +133 177 0.00057349983 +137 177 0.011126399 +139 177 0.022482198 +141 177 0.00011469999 +149 177 0.0038999999 +150 177 0.0035559 +154 177 0.0057352968 +156 177 0.00022939999 +158 177 0.00011469999 +160 177 0.0080293976 +161 177 0.0018352999 +165 177 0.012043998 +170 177 0.014452897 +171 177 0.0038999999 +178 177 0.00022939999 +188 177 0.00011469999 +189 177 0.00011469999 +190 177 0.00011469999 +194 177 0.00022939999 +198 177 0.027873397 +200 177 0.0041293986 +203 177 0.00011469999 +204 177 0.00011469999 +206 177 0.00022939999 +214 177 0.0038999999 +223 177 0.00011469999 +224 177 0.0012617998 +225 177 0.00011469999 +227 177 0.00011469999 +233 177 0.0069969967 +234 177 0.0033264998 +237 177 0.00034409994 +240 177 0.010438196 +241 177 0.085914195 +243 177 0.00011469999 +252 177 0.020188097 +270 177 0.00011469999 +272 177 0.00034409994 +277 177 0.10690528 +282 177 0.00057349983 +283 177 0.00011469999 +285 177 0.00011469999 +286 177 0.00022939999 +289 177 0.00034409994 +290 177 0.00022939999 +292 177 0.00011469999 +293 177 0.051158499 +294 177 0.00022939999 +295 177 0.00011469999 +307 177 0.00022939999 +312 177 0.0056205988 +313 177 0.00011469999 +315 177 0.013764597 +317 177 0.00022939999 +318 177 0.00011469999 +319 177 0.018926397 +320 177 0.00011469999 +321 177 0.00091759977 +322 177 0.0035559 +324 177 0.00011469999 +326 177 0.036476299 +328 177 0.00022939999 +340 177 0.0010322998 +349 177 0.00022939999 +350 177 0.00011469999 +351 177 0.00011469999 +354 177 0.00034409994 +356 177 0.00011469999 +358 177 0.0011470998 +372 177 0.00011469999 +373 177 0.00011469999 +384 177 0.0019499999 +387 177 0.00011469999 +402 177 0.00011469999 +419 177 0.0037852998 +422 177 0.0034411999 +428 177 0.00034409994 +430 177 0.00034409994 +437 177 0.00011469999 +443 177 0.0096351989 +444 177 0.00022939999 +445 177 0.011241097 +446 177 0.00045879977 +447 177 0.00091759977 +450 177 0.0032116999 +452 177 0.0048175976 +453 177 0.0030969998 +454 177 0.00068819989 +455 177 0.057008497 +456 177 0.00034409994 +457 177 0.0026381998 +458 177 0.00080289994 +459 177 0.00022939999 +460 177 0.0013764999 +463 177 0.010438196 +464 177 0.00022939999 +465 177 0.0010322998 +467 177 0.0077999979 +468 177 0.0056205988 +469 177 0.0038999999 +470 177 0.0043587983 +471 177 0.0021793998 +473 177 0.00011469999 +477 177 0.00034409994 +478 177 0.0013764999 +483 177 0.0013764999 +489 177 0.00011469999 +490 177 0.00034409994 +491 177 0.00022939999 +18 178 0.00018419999 +60 178 0.0018420999 +108 178 9.2099988e-05 +114 178 0.00018419999 +117 178 0.015658099 +126 178 9.2099988e-05 +130 178 0.10776454 +131 178 0.0013815998 +132 178 0.00036839978 +133 178 0.0046973974 +137 178 0.025329299 +138 178 9.2099988e-05 +139 178 0.008565899 +141 178 0.0045131966 +142 178 9.2099988e-05 +143 178 0.0004604999 +149 178 0.0070000999 +150 178 0.0043289997 +152 178 9.2099988e-05 +158 178 0.0076447986 +160 178 0.025881898 +161 178 0.0298425 +162 178 0.00018419999 +165 178 0.0038684998 +170 178 0.00073689991 +171 178 0.0011973998 +172 178 0.00027629989 +176 178 0.00018419999 +178 178 0.023855597 +187 178 9.2099988e-05 +189 178 9.2099988e-05 +190 178 9.2099988e-05 +194 178 0.00018419999 +198 178 0.0165792 +203 178 9.2099988e-05 +204 178 9.2099988e-05 +206 178 0.00018419999 +219 178 0.00018419999 +233 178 0.0038684998 +234 178 0.0022105998 +237 178 0.00027629989 +240 178 0.013355397 +241 178 0.0350926 +243 178 0.00073689991 +252 178 9.2099988e-05 +270 178 0.00027629989 +272 178 0.0004604999 +277 178 0.017776497 +279 178 0.00092109991 +293 178 9.2099988e-05 +312 178 0.0004604999 +315 178 0.0040526986 +317 178 0.00073689991 +318 178 0.00018419999 +319 178 0.004144799 +321 178 9.2099988e-05 +322 178 0.10905409 +326 178 0.0131712 +356 178 9.2099988e-05 +358 178 0.00073689991 +384 178 0.0019341998 +387 178 9.2099988e-05 +402 178 9.2099988e-05 +422 178 9.2099988e-05 +437 178 0.0016578999 +442 178 0.004144799 +443 178 0.0097632967 +444 178 0.0032237 +445 178 0.010407999 +446 178 0.0004604999 +447 178 0.0040526986 +450 178 0.0026711 +452 178 0.0030395 +453 178 0.0011973998 +454 178 0.00073689991 +455 178 0.049921699 +456 178 0.00036839978 +457 178 0.0024869 +458 178 0.0006446999 +459 178 0.0051579997 +460 178 0.0011973998 +463 178 0.011605397 +464 178 0.0012894999 +465 178 0.00082899979 +467 178 0.014184397 +468 178 0.0157502 +469 178 0.004144799 +470 178 0.004605297 +471 178 0.0020262999 +473 178 9.2099988e-05 +477 178 0.0004604999 +478 178 0.0011973998 +483 178 0.0015657998 +489 178 9.2099988e-05 +490 178 0.00036839978 +491 178 0.00018419999 +22 179 0.00075819995 +60 179 0.0022745 +114 179 0.00037909998 +130 179 0.0041697994 +133 179 0.0068233982 +137 179 0.011372298 +139 179 0.017058399 +141 179 0.00037909998 +149 179 0.00037909998 +150 179 0.0049279965 +156 179 0.00037909998 +158 179 0.00037909998 +160 179 0.075056851 +161 179 0.0064442977 +165 179 0.040560998 +169 179 0.00037909998 +170 179 0.015162997 +171 179 0.025018997 +179 179 0.005307097 +180 179 0.0011371998 +185 179 0.00037909998 +198 179 0.015162997 +200 179 0.00037909998 +206 179 0.00075819995 +214 179 0.00037909998 +219 179 0.0015162998 +233 179 0.007202398 +234 179 0.0026534998 +237 179 0.00037909998 +240 179 0.005307097 +241 179 0.034874897 +243 179 0.012130398 +252 179 0.00037909998 +270 179 0.012130398 +272 179 0.00037909998 +277 179 0.018953796 +279 179 0.00075819995 +293 179 0.00037909998 +312 179 0.012130398 +315 179 0.00075819995 +317 179 0.0060651973 +318 179 0.0018954 +319 179 0.042835496 +322 179 0.0022745 +326 179 0.0015162998 +351 179 0.00037909998 +358 179 0.0011371998 +437 179 0.0018954 +442 179 0.00037909998 +443 179 0.012509499 +444 179 0.010234997 +445 179 0.0060651973 +446 179 0.00037909998 +447 179 0.018195599 +450 179 0.0037908 +452 179 0.0056860968 +453 179 0.0018954 +454 179 0.0011371998 +455 179 0.052312396 +456 179 0.00037909998 +457 179 0.0034116998 +460 179 0.0060651973 +463 179 0.0094768964 +464 179 0.0015162998 +465 179 0.00075819995 +467 179 0.0094768964 +468 179 0.0056860968 +469 179 0.0045488998 +470 179 0.0049279965 +471 179 0.0022745 +478 179 0.0011371998 +483 179 0.00075819995 +490 179 0.00075819995 +22 180 0.0026427999 +60 180 0.0035237998 +108 180 0.0001258 +114 180 0.00025169994 +126 180 0.0001258 +130 180 0.0090611987 +133 180 0.0021394 +137 180 0.0057890974 +139 180 0.0090611987 +141 180 0.0001258 +149 180 0.0047822967 +150 180 0.0055373982 +156 180 0.00025169994 +158 180 0.0032720999 +160 180 0.0036495999 +161 180 0.0032720999 +165 180 0.0057890974 +169 180 0.0050339997 +170 180 0.0022652999 +171 180 0.0022652999 +172 180 0.00037749996 +180 180 0.0096903965 +185 180 0.0036495999 +187 180 0.00075509981 +188 180 0.0006291999 +189 180 0.0001258 +190 180 0.0001258 +194 180 0.0001258 +198 180 0.018877398 +200 180 0.0042788982 +203 180 0.0001258 +206 180 0.00025169994 +214 180 0.0032720999 +224 180 0.0015101999 +233 180 0.0096903965 +234 180 0.0021394 +237 180 0.00037749996 +240 180 0.0039012998 +241 180 0.040649399 +243 180 0.0001258 +252 180 0.00088089984 +270 180 0.00025169994 +272 180 0.00075509981 +277 180 0.10596526 +279 180 0.0010068 +282 180 0.00050339988 +283 180 0.00025169994 +284 180 0.0001258 +285 180 0.00037749996 +286 180 0.0001258 +289 180 0.00075509981 +290 180 0.00050339988 +292 180 0.00037749996 +293 180 0.0076767989 +294 180 0.00037749996 +295 180 0.00025169994 +296 180 0.0001258 +299 180 0.0001258 +301 180 0.0001258 +308 180 0.0001258 +312 180 0.004027199 +315 180 0.010319699 +319 180 0.038509898 +320 180 0.00037749996 +321 180 0.00075509981 +322 180 0.0023910999 +325 180 0.0001258 +326 180 0.018374 +328 180 0.0006291999 +339 180 0.0001258 +340 180 0.00088089984 +351 180 0.0035237998 +356 180 0.0001258 +358 180 0.0013842999 +387 180 0.0001258 +392 180 0.0001258 +393 180 0.0001258 +402 180 0.00025169994 +405 180 0.0001258 +413 180 0.0001258 +422 180 0.0001258 +434 180 0.0001258 +437 180 0.0006291999 +443 180 0.0045305975 +444 180 0.0045305975 +445 180 0.0064182989 +446 180 0.00050339988 +447 180 0.0055373982 +450 180 0.0028944998 +452 180 0.0059148967 +453 180 0.0035237998 +454 180 0.0015101999 +455 180 0.040523499 +456 180 0.0001258 +457 180 0.010948896 +458 180 0.00075509981 +459 180 0.00037749996 +460 180 0.0013842999 +463 180 0.014976099 +464 180 0.0056631975 +465 180 0.0010068 +467 180 0.024666499 +468 180 0.0059148967 +469 180 0.0052856989 +470 180 0.0055373982 +471 180 0.0052856989 +473 180 0.0001258 +477 180 0.0010068 +478 180 0.0011325998 +483 180 0.0013842999 +490 180 0.00050339988 +491 180 0.00050339988 +22 181 0.0005804 +60 181 0.0021280998 +108 181 0.00019349999 +114 181 0.0003868998 +117 181 0.00019349999 +126 181 0.00019349999 +130 181 0.013735697 +133 181 0.0013541998 +137 181 0.0061907992 +139 181 0.017217997 +141 181 0.00019349999 +150 181 0.0058037974 +156 181 0.032694899 +158 181 0.0071580969 +160 181 0.036370698 +161 181 0.0027084998 +165 181 0.022441499 +169 181 0.0032887999 +170 181 0.0096731 +171 181 0.0046430975 +178 181 0.00019349999 +180 181 0.00019349999 +181 181 0.0029018999 +189 181 0.00019349999 +190 181 0.00019349999 +194 181 0.00019349999 +198 181 0.012381498 +206 181 0.0003868998 +214 181 0.0005804 +219 181 0.0011608 +224 181 0.0011608 +233 181 0.0069645979 +234 181 0.0023214999 +237 181 0.0009672998 +240 181 0.0021280998 +241 181 0.055329897 +243 181 0.00019349999 +252 181 0.00077379984 +269 181 0.0003868998 +270 181 0.0077383965 +272 181 0.0005804 +277 181 0.068678677 +283 181 0.00019349999 +286 181 0.00019349999 +290 181 0.00019349999 +293 181 0.011220697 +296 181 0.00019349999 +312 181 0.017024599 +315 181 0.011220697 +317 181 0.00019349999 +318 181 0.0015476998 +319 181 0.023602199 +320 181 0.0005804 +321 181 0.0005804 +322 181 0.017411496 +325 181 0.00019349999 +326 181 0.0056103989 +328 181 0.00019349999 +330 181 0.00019349999 +340 181 0.0005804 +354 181 0.0011608 +356 181 0.00019349999 +358 181 0.0013541998 +372 181 0.00019349999 +387 181 0.00019349999 +402 181 0.0003868998 +409 181 0.0021280998 +412 181 0.0003868998 +422 181 0.00019349999 +437 181 0.0003868998 +442 181 0.00019349999 +443 181 0.0102534 +444 181 0.0096731 +445 181 0.017411496 +446 181 0.00019349999 +447 181 0.011414196 +450 181 0.0030953998 +452 181 0.0058037974 +453 181 0.0025149998 +455 181 0.0433353 +456 181 0.00019349999 +457 181 0.0090926997 +458 181 0.0011608 +459 181 0.00019349999 +460 181 0.0058037974 +463 181 0.013155296 +464 181 0.0034822999 +465 181 0.0011608 +467 181 0.0085122995 +468 181 0.0021280998 +469 181 0.0056103989 +470 181 0.0059972964 +471 181 0.0019345998 +473 181 0.00019349999 +477 181 0.0003868998 +478 181 0.0013541998 +483 181 0.0017410999 +490 181 0.0005804 +491 181 0.00019349999 +60 182 0.0017557 +108 182 0.00012539999 +114 182 0.00025079981 +126 182 0.00012539999 +130 182 0.00062699988 +137 182 0.00025079981 +139 182 0.0016303 +150 182 0.005643297 +156 182 0.00062699988 +158 182 0.00012539999 +159 182 0.00062699988 +160 182 0.040381197 +161 182 0.0051416978 +163 182 0.00012539999 +165 182 0.041008297 +169 182 0.00012539999 +170 182 0.034110896 +171 182 0.015675899 +180 182 0.00012539999 +182 182 0.0050162971 +183 182 0.00012539999 +189 182 0.00012539999 +190 182 0.00012539999 +194 182 0.00025079981 +198 182 0.0061449967 +203 182 0.00012539999 +204 182 0.00012539999 +206 182 0.00025079981 +219 182 0.0018810998 +224 182 0.00037619984 +233 182 0.0079007 +234 182 0.0025081998 +237 182 0.00037619984 +241 182 0.081514895 +243 182 0.00012539999 +252 182 0.0219463 +270 182 0.0041383989 +272 182 0.00037619984 +277 182 0.023074999 +279 182 0.0012540999 +293 182 0.0043892972 +312 182 0.005894199 +315 182 0.00087789982 +317 182 0.0067719966 +318 182 0.0015048999 +319 182 0.030850299 +320 182 0.00012539999 +321 182 0.00087789982 +322 182 0.00050159986 +326 182 0.0057686977 +340 182 0.0020064998 +354 182 0.00012539999 +356 182 0.00012539999 +358 182 0.00087789982 +372 182 0.00012539999 +385 182 0.00050159986 +387 182 0.00012539999 +402 182 0.00012539999 +422 182 0.00012539999 +442 182 0.0097817965 +443 182 0.015550498 +444 182 0.0045146979 +445 182 0.0081514977 +446 182 0.00037619984 +447 182 0.0053924993 +450 182 0.0032605999 +452 182 0.0051416978 +453 182 0.0026335998 +454 182 0.0028843998 +455 182 0.0451467 +456 182 0.00037619984 +457 182 0.0028843998 +458 182 0.00050159986 +459 182 0.00025079981 +460 182 0.0062703975 +463 182 0.0200652 +464 182 0.005643297 +465 182 0.0010032998 +467 182 0.0077752993 +468 182 0.0070227981 +469 182 0.0046400987 +470 182 0.0051416978 +471 182 0.008026097 +473 182 0.00012539999 +477 182 0.0017557 +478 182 0.0012540999 +483 182 0.0015048999 +489 182 0.00012539999 +490 182 0.00050159986 +491 182 0.00012539999 +60 183 0.0025807999 +108 183 0.00013579999 +114 183 0.00027169986 +126 183 0.00013579999 +130 183 0.00040749996 +137 183 0.00027169986 +139 183 0.00067919982 +149 183 0.00013579999 +150 183 0.0042107999 +156 183 0.00040749996 +158 183 0.00027169986 +160 183 0.0059765987 +161 183 0.0014942 +165 183 0.0055690967 +169 183 0.0039390996 +170 183 0.0031241998 +171 183 0.0099157989 +172 183 0.00027169986 +180 183 0.00027169986 +182 183 0.00013579999 +183 183 0.0029882998 +185 183 0.00013579999 +189 183 0.00013579999 +190 183 0.00013579999 +194 183 0.00013579999 +198 183 0.014398299 +200 183 0.00013579999 +203 183 0.00013579999 +206 183 0.00027169986 +223 183 0.00013579999 +224 183 0.00027169986 +233 183 0.012360796 +234 183 0.0023091999 +237 183 0.00027169986 +240 183 0.00013579999 +241 183 0.031648997 +242 183 0.00013579999 +252 183 0.014534097 +270 183 0.00013579999 +272 183 0.00054329983 +277 183 0.20320565 +282 183 0.00027169986 +288 183 0.00013579999 +289 183 0.00040749996 +292 183 0.00040749996 +293 183 0.012224898 +294 183 0.00013579999 +295 183 0.00040749996 +296 183 0.00013579999 +297 183 0.00013579999 +298 183 0.00013579999 +307 183 0.00027169986 +312 183 0.012224898 +315 183 0.013583299 +317 183 0.00040749996 +318 183 0.00040749996 +319 183 0.0162999 +320 183 0.00013579999 +321 183 0.027166497 +322 183 0.00013579999 +324 183 0.00027169986 +326 183 0.0039390996 +328 183 0.00013579999 +335 183 0.00027169986 +340 183 0.0036674999 +351 183 0.00027169986 +352 183 0.00013579999 +354 183 0.00027169986 +356 183 0.00013579999 +358 183 0.0010866998 +366 183 0.00040749996 +371 183 0.00013579999 +372 183 0.0012224999 +373 183 0.00027169986 +380 183 0.00013579999 +385 183 0.00040749996 +386 183 0.00027169986 +387 183 0.00013579999 +402 183 0.00013579999 +415 183 0.00013579999 +422 183 0.00013579999 +434 183 0.00013579999 +442 183 0.00013579999 +443 183 0.0051615983 +444 183 0.006248299 +445 183 0.0059765987 +446 183 0.00040749996 +447 183 0.0065199994 +450 183 0.0027166998 +452 183 0.005704999 +453 183 0.0040749982 +454 183 0.0052974969 +455 183 0.035995699 +456 183 0.00013579999 +457 183 0.0074707977 +458 183 0.00081499992 +459 183 0.00027169986 +460 183 0.0013583 +463 183 0.0152133 +464 183 0.0036674999 +465 183 0.00095079979 +467 183 0.0081499964 +468 183 0.006248299 +469 183 0.0047541 +470 183 0.0054332986 +471 183 0.006384097 +473 183 0.00013579999 +477 183 0.0046182983 +478 183 0.0012224999 +483 183 0.0019016999 +490 183 0.00054329983 +491 183 0.00027169986 +16 184 0.00032139989 +22 184 0.00064289989 +60 184 0.0025714999 +84 184 0.00064289989 +114 184 0.00032139989 +126 184 0.00032139989 +130 184 0.0022500998 +131 184 0.0022500998 +133 184 0.00032139989 +139 184 0.094503343 +141 184 0.0070716999 +160 184 0.005142998 +161 184 0.0080359988 +165 184 0.00032139989 +184 184 0.057216298 +187 184 0.00032139989 +198 184 0.0038572999 +206 184 0.00064289989 +214 184 0.011250399 +233 184 0.00032139989 +234 184 0.0028929999 +237 184 0.00032139989 +241 184 0.072966874 +272 184 0.00064289989 +277 184 0.0520733 +279 184 0.00032139989 +289 184 0.0025714999 +293 184 0.026036598 +312 184 0.022179399 +315 184 0.0057858974 +318 184 0.00032139989 +320 184 0.0016071999 +321 184 0.0035357999 +326 184 0.0073930994 +358 184 0.00096429978 +435 184 0.00032139989 +443 184 0.0070716999 +444 184 0.0016071999 +445 184 0.018964998 +447 184 0.0176792 +450 184 0.0032143998 +452 184 0.0041786991 +453 184 0.0019285998 +454 184 0.00064289989 +455 184 0.0347155 +456 184 0.00064289989 +457 184 0.0028929999 +458 184 0.00096429978 +459 184 0.0012857998 +460 184 0.00096429978 +463 184 0.018643498 +464 184 0.00064289989 +465 184 0.00064289989 +467 184 0.0077145994 +468 184 0.016071998 +469 184 0.005464498 +470 184 0.0061073974 +471 184 0.0016071999 +473 184 0.00032139989 +477 184 0.00032139989 +478 184 0.0012857998 +479 184 0.0012857998 +483 184 0.0019285998 +490 184 0.0019285998 +491 184 0.00064289989 +22 185 0.00025809999 +60 185 0.0010322998 +114 185 0.00025809999 +117 185 0.00025809999 +126 185 0.00025809999 +130 185 0.0025805999 +137 185 0.0015483999 +139 185 0.0136774 +142 185 0.00025809999 +149 185 0.0028386998 +150 185 0.0018064999 +156 185 0.00077419984 +158 185 0.00025809999 +160 185 0.0229677 +161 185 0.0072257966 +165 185 0.017548397 +169 185 0.00025809999 +170 185 0.0087741986 +171 185 0.0043870993 +178 185 0.0049031973 +183 185 0.00025809999 +185 185 0.0046451986 +186 185 0.00025809999 +187 185 0.0020644998 +193 185 0.00025809999 +194 185 0.00025809999 +198 185 0.0077418983 +206 185 0.00051609986 +214 185 0.00025809999 +233 185 0.0064515993 +234 185 0.0028386998 +237 185 0.00025809999 +240 185 0.0041289963 +241 185 0.0335484 +242 185 0.00025809999 +252 185 0.0018064999 +253 185 0.00025809999 +270 185 0.0077418983 +272 185 0.00077419984 +277 185 0.078451574 +279 185 0.00051609986 +286 185 0.00077419984 +290 185 0.00077419984 +293 185 0.0061934963 +312 185 0.0098064989 +315 185 0.010838699 +317 185 0.00051609986 +318 185 0.0015483999 +319 185 0.014451597 +320 185 0.0092902966 +321 185 0.011870999 +322 185 0.0020644998 +325 185 0.00051609986 +326 185 0.0079999976 +328 185 0.00051609986 +340 185 0.0012902999 +354 185 0.0085160993 +358 185 0.00077419984 +366 185 0.00025809999 +372 185 0.017290298 +401 185 0.00051609986 +402 185 0.00051609986 +414 185 0.00025809999 +416 185 0.00025809999 +422 185 0.00025809999 +443 185 0.0074838996 +444 185 0.010064498 +445 185 0.0054193996 +447 185 0.013161298 +450 185 0.0030967998 +452 185 0.0051612966 +453 185 0.0015483999 +454 185 0.0015483999 +455 185 0.038967699 +456 185 0.00025809999 +457 185 0.0030967998 +458 185 0.00025809999 +459 185 0.00025809999 +460 185 0.0056773983 +463 185 0.038709696 +464 185 0.0015483999 +465 185 0.00051609986 +467 185 0.0079999976 +468 185 0.0054193996 +469 185 0.0046451986 +470 185 0.0054193996 +471 185 0.0023226 +473 185 0.00025809999 +477 185 0.00051609986 +478 185 0.0010322998 +483 185 0.00077419984 +490 185 0.00051609986 +491 185 0.00077419984 +6 186 0.00053219986 +17 186 0.0001774 +18 186 8.8699991e-05 +21 186 0.0001774 +22 186 0.0046127997 +24 186 0.0025724999 +25 186 0.0020402998 +60 186 0.011443298 +75 186 0.015878599 +104 186 0.0041692965 +114 186 8.8699991e-05 +117 186 0.0062981993 +126 186 8.8699991e-05 +130 186 0.0038143999 +139 186 0.0011531999 +150 186 0.0001774 +159 186 0.1312871 +160 186 0.076554596 +169 186 0.00079839979 +171 186 0.00044349977 +186 186 0.043821499 +187 186 0.00079839979 +192 186 0.00053219986 +193 186 0.00044349977 +198 186 0.0015079998 +206 186 0.0001774 +209 186 0.0001774 +214 186 0.050563298 +215 186 0.00035479991 +218 186 0.00035479991 +219 186 0.0001774 +223 186 0.0028386 +224 186 0.0020402998 +225 186 0.0013305999 +231 186 0.0015966999 +233 186 0.0001774 +234 186 0.018184997 +240 186 0.00035479991 +241 186 0.0017741998 +267 186 0.0018628999 +272 186 0.0029272998 +273 186 8.8699991e-05 +277 186 0.00062099984 +287 186 8.8699991e-05 +318 186 0.00035479991 +322 186 0.0021289999 +324 186 0.0094029978 +326 186 0.0011531999 +347 186 0.0031935 +349 186 8.8699991e-05 +350 186 0.00088709989 +356 186 0.00044349977 +358 186 0.00088709989 +384 186 0.00035479991 +414 186 0.0018628999 +442 186 8.8699991e-05 +443 186 0.038676497 +444 186 0.0014193 +445 186 0.011088397 +446 186 0.0037256998 +447 186 0.0066530965 +448 186 8.8699991e-05 +450 186 0.0015966999 +452 186 0.017475396 +453 186 0.015612498 +454 186 0.020491399 +455 186 0.038853899 +456 186 8.8699991e-05 +457 186 0.0031935 +458 186 0.0010644998 +459 186 0.0017741998 +460 186 0.0012418998 +463 186 0.010999698 +464 186 0.00097579998 +465 186 0.00044349977 +467 186 0.015257698 +468 186 0.0031935 +469 186 0.0041692965 +470 186 0.0039030998 +471 186 0.00062099984 +473 186 8.8699991e-05 +477 186 8.8699991e-05 +478 186 0.00062099984 +483 186 0.0012418998 +489 186 0.0028386 +490 186 0.00044349977 +491 186 0.020313997 +4 187 1.589999e-05 +6 187 0.0022057998 +9 187 1.589999e-05 +16 187 1.589999e-05 +17 187 0.00058719981 +18 187 0.0002063 +21 187 0.00042849989 +22 187 0.0086645968 +24 187 0.0089025982 +25 187 0.00041259988 +60 187 0.012679499 +79 187 1.589999e-05 +82 187 1.589999e-05 +83 187 1.589999e-05 +84 187 1.589999e-05 +104 187 0.011584498 +108 187 3.1699994e-05 +113 187 4.7599999e-05 +114 187 7.9299993e-05 +117 187 0.00092039979 +126 187 4.7599999e-05 +127 187 1.589999e-05 +130 187 0.011235397 +132 187 1.589999e-05 +139 187 7.9299993e-05 +142 187 6.3499989e-05 +143 187 3.1699994e-05 +150 187 0.0004918999 +151 187 1.589999e-05 +159 187 0.072744548 +160 187 0.027564898 +161 187 7.9299993e-05 +169 187 0.0019359998 +170 187 0.00012699999 +171 187 0.00017459999 +172 187 0.00017459999 +186 187 0.14163285 +187 187 0.0062524974 +188 187 0.00031739986 +189 187 7.9299993e-05 +190 187 6.3499989e-05 +192 187 0.0012694998 +193 187 0.0013170999 +194 187 6.3499989e-05 +198 187 0.005189199 +200 187 3.1699994e-05 +201 187 3.1699994e-05 +203 187 6.3499989e-05 +204 187 3.1699994e-05 +206 187 7.9299993e-05 +207 187 3.1699994e-05 +208 187 3.1699994e-05 +209 187 4.7599999e-05 +214 187 0.038514599 +215 187 0.00099979993 +217 187 1.589999e-05 +218 187 0.00012699999 +219 187 0.00055539981 +221 187 0.00017459999 +223 187 0.0040624999 +224 187 0.005649399 +225 187 0.0031579998 +231 187 0.0019677998 +233 187 0.00023799999 +234 187 0.014361698 +237 187 7.9299993e-05 +240 187 0.0008886999 +241 187 0.0074584968 +248 187 1.589999e-05 +250 187 1.589999e-05 +251 187 4.7599999e-05 +252 187 7.9299993e-05 +267 187 0.0013647999 +272 187 0.0012061 +273 187 6.3499989e-05 +277 187 0.00033329986 +279 187 1.589999e-05 +284 187 1.589999e-05 +290 187 3.1699994e-05 +293 187 0.00011109999 +294 187 1.589999e-05 +317 187 1.589999e-05 +318 187 9.5199997e-05 +322 187 0.0051733963 +324 187 0.00069819996 +325 187 4.7599999e-05 +326 187 0.0024120999 +337 187 1.589999e-05 +347 187 0.0029199 +350 187 0.00042849989 +356 187 0.00036499999 +358 187 0.0010155998 +384 187 7.9299993e-05 +387 187 3.1699994e-05 +392 187 1.589999e-05 +402 187 3.1699994e-05 +404 187 3.1699994e-05 +414 187 0.0019995 +419 187 1.589999e-05 +420 187 1.589999e-05 +422 187 9.5199997e-05 +423 187 1.589999e-05 +425 187 1.589999e-05 +430 187 3.1699994e-05 +431 187 1.589999e-05 +432 187 1.589999e-05 +433 187 3.1699994e-05 +434 187 3.1699994e-05 +442 187 0.00042849989 +443 187 0.031421099 +444 187 0.0023804 +445 187 0.013726898 +446 187 0.0034118998 +447 187 0.008061599 +448 187 9.5199997e-05 +449 187 1.589999e-05 +450 187 0.0019995 +452 187 0.023534097 +453 187 0.013028599 +454 187 0.0056017973 +455 187 0.037340298 +456 187 0.00042849989 +457 187 0.0031420998 +458 187 0.00038089999 +459 187 0.0016504 +460 187 0.0008886999 +463 187 0.010838699 +464 187 0.0022216998 +465 187 0.00072999997 +467 187 0.014298197 +468 187 0.008109197 +469 187 0.0053002983 +470 187 0.0045702979 +471 187 0.0014123998 +473 187 9.5199997e-05 +477 187 0.00011109999 +478 187 0.00076169986 +483 187 0.001095 +489 187 0.0019202 +490 187 0.00034909998 +491 187 0.015202697 +6 188 0.00013659999 +9 188 2.729999e-05 +17 188 2.729999e-05 +18 188 0.0001639 +21 188 2.729999e-05 +22 188 0.011200298 +24 188 0.0021853999 +25 188 0.00032779993 +60 188 0.016336098 +75 188 2.729999e-05 +82 188 2.729999e-05 +83 188 2.729999e-05 +84 188 2.729999e-05 +104 188 0.008277297 +108 188 2.729999e-05 +113 188 5.4599994e-05 +114 188 8.1999999e-05 +117 188 5.4599994e-05 +126 188 5.4599994e-05 +127 188 2.729999e-05 +130 188 0.0066108964 +139 188 0.0011473999 +150 188 0.00035509979 +151 188 2.729999e-05 +159 188 0.12257546 +160 188 0.057613499 +169 188 0.0022673998 +171 188 0.0027863998 +172 188 5.4599994e-05 +186 188 0.02251 +187 188 0.00019119999 +188 188 0.0001639 +189 188 5.4599994e-05 +190 188 5.4599994e-05 +192 188 0.0015297998 +193 188 0.00071029994 +194 188 5.4599994e-05 +197 188 2.729999e-05 +198 188 0.002322 +200 188 2.729999e-05 +203 188 5.4599994e-05 +204 188 5.4599994e-05 +206 188 5.4599994e-05 +207 188 2.729999e-05 +209 188 0.00084689981 +214 188 0.028793097 +215 188 8.1999999e-05 +217 188 2.729999e-05 +218 188 0.00024589989 +219 188 0.00030049984 +223 188 0.0088509992 +224 188 0.0050810985 +225 188 0.0032235 +231 188 0.0026497999 +233 188 0.00024589989 +234 188 0.020761598 +237 188 8.1999999e-05 +240 188 0.00084689981 +241 188 0.00040979986 +248 188 2.729999e-05 +251 188 5.4599994e-05 +252 188 8.1999999e-05 +267 188 0.0013658998 +272 188 0.0015297998 +277 188 0.00076489989 +284 188 2.729999e-05 +317 188 2.729999e-05 +318 188 0.00013659999 +322 188 0.0054908991 +324 188 0.0017756999 +326 188 0.0035785998 +347 188 0.0029229999 +350 188 0.0010107998 +356 188 0.00038249977 +358 188 0.0008741999 +384 188 0.00010929999 +387 188 2.729999e-05 +402 188 2.729999e-05 +404 188 5.4599994e-05 +414 188 0.0015024999 +419 188 2.729999e-05 +422 188 0.00010929999 +423 188 2.729999e-05 +425 188 2.729999e-05 +430 188 2.729999e-05 +431 188 2.729999e-05 +433 188 2.729999e-05 +434 188 2.729999e-05 +442 188 2.729999e-05 +443 188 0.0303775 +444 188 0.0025952 +445 188 0.010353498 +446 188 0.0035239998 +447 188 0.0047259964 +448 188 0.00010929999 +450 188 0.0016937 +452 188 0.017019097 +453 188 0.017947897 +454 188 0.0038518 +455 188 0.052040599 +456 188 0.00024589989 +457 188 0.0031961999 +458 188 0.00030049984 +459 188 0.0011747 +460 188 0.00092879985 +463 188 0.015489299 +464 188 0.0018575999 +465 188 0.00054639997 +467 188 0.012866698 +468 188 0.0048352964 +469 188 0.0047259964 +470 188 0.0037971998 +471 188 0.0013385999 +473 188 8.1999999e-05 +477 188 0.00010929999 +478 188 0.00065559987 +483 188 0.0009015 +489 188 0.0017482999 +490 188 0.00030049984 +491 188 0.038436297 +60 189 0.0015085 +104 189 0.00033519999 +108 189 0.0001676 +114 189 0.00033519999 +126 189 0.0001676 +139 189 0.0001676 +187 189 0.26651019 +188 189 0.0098893978 +189 189 0.010224599 +190 189 0.0001676 +192 189 0.0018437998 +194 189 0.00033519999 +196 189 0.00033519999 +198 189 0.030841399 +203 189 0.0001676 +204 189 0.00033519999 +206 189 0.00033519999 +219 189 0.014079798 +234 189 0.0026818998 +237 189 0.0001676 +241 189 0.027991999 +252 189 0.0001676 +272 189 0.00067049987 +279 189 0.00083809998 +317 189 0.0010056999 +347 189 0.0031846999 +356 189 0.00033519999 +358 189 0.0018437998 +387 189 0.0001676 +422 189 0.0001676 +443 189 0.0095540993 +444 189 0.0001676 +445 189 0.017934997 +446 189 0.0001676 +447 189 0.0010056999 +450 189 0.0045255981 +452 189 0.007207498 +453 189 0.0011733 +454 189 0.00050279987 +455 189 0.046262197 +456 189 0.00033519999 +457 189 0.0015085 +458 189 0.00050279987 +459 189 0.00033519999 +460 189 0.00050279987 +463 189 0.031176697 +464 189 0.00033519999 +465 189 0.0092188977 +467 189 0.011733197 +468 189 0.0020113999 +469 189 0.0041903965 +470 189 0.0046932995 +471 189 0.0013408998 +473 189 0.0001676 +477 189 0.0001676 +478 189 0.0013408998 +483 189 0.0013408998 +490 189 0.00050279987 +491 189 0.0050284974 +18 190 0.00010029999 +22 190 5.0199989e-05 +60 190 0.00321 +82 190 5.0199989e-05 +108 190 5.0199989e-05 +114 190 0.00010029999 +126 190 5.0199989e-05 +130 190 0.015548199 +131 190 0.0002006 +132 190 0.0003511 +133 190 5.0199989e-05 +137 190 5.0199989e-05 +138 190 0.0003511 +139 190 0.00010029999 +141 190 5.0199989e-05 +142 190 0.040024098 +143 190 0.00030089985 +149 190 5.0199989e-05 +151 190 5.0199989e-05 +158 190 0.00010029999 +186 190 0.027334698 +187 190 0.32330215 +188 190 0.0026081 +189 190 0.0002006 +190 190 0.00070219999 +192 190 0.0014044 +193 190 5.0199989e-05 +194 190 0.0001505 +197 190 5.0199989e-05 +198 190 0.048550498 +203 190 5.0199989e-05 +204 190 0.0004011998 +206 190 0.00010029999 +208 190 0.00060189981 +214 190 0.00055169989 +219 190 0.0040123984 +221 190 0.0024575999 +223 190 5.0199989e-05 +224 190 0.0002006 +225 190 0.0001505 +226 190 0.00075229979 +227 190 0.00050159986 +228 190 0.0002006 +231 190 5.0199989e-05 +234 190 0.0019560999 +237 190 5.0199989e-05 +240 190 0.00095299981 +241 190 0.017754998 +252 190 0.00010029999 +253 190 5.0199989e-05 +272 190 0.0011535999 +277 190 5.0199989e-05 +293 190 5.0199989e-05 +300 190 5.0199989e-05 +312 190 5.0199989e-05 +347 190 0.0034606999 +356 190 0.0004011998 +358 190 0.00065199984 +384 190 5.0199989e-05 +387 190 5.0199989e-05 +393 190 5.0199989e-05 +416 190 5.0199989e-05 +417 190 5.0199989e-05 +422 190 0.0001505 +437 190 5.0199989e-05 +443 190 0.012639198 +444 190 0.0026081 +445 190 0.015899297 +446 190 0.00055169989 +447 190 0.0054167993 +450 190 0.0015548 +452 190 0.0042631999 +453 190 0.00095299981 +454 190 0.00070219999 +455 190 0.058079999 +456 190 0.00010029999 +457 190 0.0016550999 +458 190 0.00025079981 +459 190 0.00055169989 +460 190 0.00090279989 +463 190 0.0089276992 +464 190 0.00060189981 +465 190 0.0049151964 +467 190 0.0062192976 +468 190 0.024074599 +469 190 0.0013541998 +470 190 0.0015046999 +471 190 0.0017052998 +473 190 5.0199989e-05 +477 190 0.00010029999 +478 190 0.00045139994 +479 190 0.00010029999 +483 190 0.0004011998 +490 190 0.0002006 +491 190 0.00010029999 +18 191 0.00049479981 +22 191 0.0079168975 +24 191 0.016576 +60 191 0.00074219983 +104 191 0.0069272965 +107 191 0.011380497 +114 191 0.00024739979 +126 191 0.00024739979 +130 191 0.011133097 +138 191 0.00024739979 +159 191 0.036120698 +160 191 0.028698698 +161 191 0.00024739979 +165 191 0.00024739979 +169 191 0.0071746968 +170 191 0.00024739979 +171 191 0.00098959985 +186 191 0.022018798 +191 191 0.00024739979 +198 191 0.011133097 +206 191 0.00049479981 +214 191 0.028698698 +219 191 0.0242454 +223 191 0.0017317999 +224 191 0.0022266 +225 191 0.0012369999 +231 191 0.0014843999 +233 191 0.008411698 +234 191 0.010638297 +241 191 0.00024739979 +267 191 0.0059376992 +270 191 0.00024739979 +272 191 0.00098959985 +273 191 0.0054428987 +277 191 0.00074219983 +315 191 0.00024739979 +317 191 0.00024739979 +322 191 0.011627898 +326 191 0.00024739979 +334 191 0.0039583966 +340 191 0.0012369999 +347 191 0.0027213998 +350 191 0.0098960996 +356 191 0.00049479981 +358 191 0.0012369999 +443 191 0.017812997 +444 191 0.0091538988 +445 191 0.024492797 +446 191 0.0022266 +447 191 0.012617499 +450 191 0.0022266 +452 191 0.033399299 +453 191 0.021276597 +454 191 0.0049479976 +455 191 0.042058397 +457 191 0.0029687998 +458 191 0.00024739979 +459 191 0.00098959985 +460 191 0.00074219983 +463 191 0.0098960996 +464 191 0.005690299 +465 191 0.00049479981 +467 191 0.014101896 +468 191 0.013112299 +469 191 0.0037109999 +470 191 0.0039583966 +471 191 0.00074219983 +473 191 0.00024739979 +477 191 0.00049479981 +478 191 0.00098959985 +483 191 0.0012369999 +489 191 0.00049479981 +490 191 0.00049479981 +491 191 0.023503199 +18 192 0.00019119999 +21 192 6.369999e-05 +22 192 0.00063729985 +24 192 0.0013382998 +60 192 0.0027403999 +82 192 0.0001275 +104 192 0.0098782964 +108 192 6.369999e-05 +114 192 6.369999e-05 +126 192 6.369999e-05 +130 192 0.0092409998 +131 192 0.00057359994 +132 192 6.369999e-05 +138 192 6.369999e-05 +139 192 0.00031869998 +142 192 0.0042699985 +143 192 0.0014658 +149 192 0.00044609979 +150 192 0.0016569998 +158 192 0.0001275 +159 192 0.0015294999 +160 192 0.0019756998 +169 192 0.0012745999 +171 192 0.0001275 +186 192 0.0014020998 +187 192 0.1773628 +188 192 0.017462198 +189 192 6.369999e-05 +190 192 6.369999e-05 +192 192 0.0080937967 +193 192 0.0001275 +194 192 0.00019119999 +197 192 6.369999e-05 +198 192 0.032566398 +200 192 6.369999e-05 +203 192 6.369999e-05 +204 192 0.00050979992 +205 192 0.0001275 +206 192 0.0001275 +207 192 6.369999e-05 +208 192 0.0020393999 +209 192 0.0001275 +211 192 0.00019119999 +212 192 0.00019119999 +213 192 0.0001275 +214 192 0.017972097 +219 192 0.015550297 +221 192 0.0099419989 +223 192 0.0001275 +224 192 0.027786598 +229 192 6.369999e-05 +233 192 0.0013382998 +234 192 0.0073289983 +237 192 6.369999e-05 +240 192 0.0043336973 +241 192 0.040022898 +252 192 0.00019119999 +270 192 0.0015294999 +271 192 0.0001275 +272 192 0.00063729985 +273 192 0.00057359994 +276 192 6.369999e-05 +277 192 0.00044609979 +287 192 6.369999e-05 +289 192 6.369999e-05 +290 192 0.0017845 +292 192 6.369999e-05 +293 192 0.0081574991 +294 192 0.00019119999 +296 192 6.369999e-05 +300 192 6.369999e-05 +312 192 6.369999e-05 +315 192 0.00019119999 +322 192 0.0001275 +325 192 0.0026766998 +326 192 0.00019119999 +340 192 0.00038239988 +345 192 6.369999e-05 +347 192 0.0028678998 +348 192 6.369999e-05 +350 192 6.369999e-05 +356 192 0.00044609979 +358 192 0.00095599983 +387 192 6.369999e-05 +392 192 0.0001275 +393 192 0.0001275 +404 192 0.0001275 +416 192 6.369999e-05 +417 192 0.0001275 +420 192 6.369999e-05 +422 192 0.00050979992 +430 192 6.369999e-05 +433 192 6.369999e-05 +434 192 6.369999e-05 +443 192 0.011471499 +444 192 0.0015932999 +445 192 0.013765898 +446 192 0.00089219981 +447 192 0.0026766998 +450 192 0.0025491999 +452 192 0.006691698 +453 192 0.0028041999 +454 192 0.0017206999 +455 192 0.041233797 +456 192 0.00025489996 +457 192 0.0016569998 +458 192 0.00038239988 +459 192 0.00038239988 +460 192 0.00076479977 +463 192 0.0123 +464 192 0.00089219981 +465 192 0.0028678998 +467 192 0.0087948963 +468 192 0.0077113993 +469 192 0.0033139999 +470 192 0.0035688998 +471 192 0.00076479977 +473 192 0.0001275 +477 192 0.00025489996 +478 192 0.00082849991 +483 192 0.00095599983 +489 192 0.0001275 +490 192 0.00038239988 +491 192 0.0012108998 +4 193 5.4299991e-05 +10 193 5.4299991e-05 +14 193 5.4299991e-05 +18 193 0.00016279999 +22 193 5.4299991e-05 +23 193 0.0011398999 +24 193 5.4299991e-05 +60 193 0.0023341998 +104 193 0.0038540999 +107 193 5.4299991e-05 +108 193 0.00016279999 +109 193 5.4299991e-05 +114 193 5.4299991e-05 +116 193 5.4299991e-05 +126 193 5.4299991e-05 +130 193 0.011670798 +131 193 0.0001086 +132 193 0.0003256998 +138 193 5.4299991e-05 +139 193 0.0001086 +142 193 0.0012484998 +143 193 0.0019542 +150 193 0.00081419991 +153 193 5.4299991e-05 +158 193 0.00016279999 +160 193 5.4299991e-05 +169 193 5.4299991e-05 +186 193 0.00075999997 +187 193 0.24546736 +188 193 0.0094451979 +189 193 0.0001086 +190 193 0.0001086 +192 193 0.00048849988 +193 193 0.0041254982 +194 193 0.0003256998 +197 193 5.4299991e-05 +198 193 0.027467199 +200 193 5.4299991e-05 +203 193 0.0001086 +204 193 0.00037999987 +205 193 0.0001086 +206 193 0.0001086 +207 193 5.4299991e-05 +208 193 5.4299991e-05 +209 193 0.0020084998 +211 193 0.00016279999 +212 193 0.00097709987 +213 193 0.00016279999 +214 193 0.0032026998 +219 193 0.0068395995 +221 193 0.0158506 +224 193 0.062099699 +227 193 0.00016279999 +233 193 5.4299991e-05 +234 193 0.0020627999 +237 193 0.0001086 +240 193 0.00092279981 +241 193 0.060145497 +242 193 5.4299991e-05 +252 193 0.0001086 +271 193 5.4299991e-05 +272 193 0.00059709977 +277 193 0.00016279999 +290 193 5.4299991e-05 +293 193 0.0019542 +295 193 0.0001086 +296 193 5.4299991e-05 +315 193 0.0001086 +325 193 0.0034740998 +326 193 5.4299991e-05 +340 193 0.00016279999 +347 193 0.0032026998 +348 193 5.4299991e-05 +356 193 0.00037999987 +358 193 0.0011941998 +372 193 5.4299991e-05 +387 193 5.4299991e-05 +422 193 0.00027139997 +430 193 5.4299991e-05 +433 193 5.4299991e-05 +434 193 5.4299991e-05 +443 193 0.011507999 +444 193 0.0028227 +445 193 0.015036397 +446 193 0.0007056999 +447 193 0.0022798998 +448 193 5.4299991e-05 +450 193 0.0029312999 +452 193 0.0063510984 +453 193 0.0015741999 +454 193 0.0013027999 +455 193 0.047008999 +456 193 0.00016279999 +457 193 0.0016284999 +458 193 0.00043429993 +459 193 0.00027139997 +460 193 0.00086849998 +463 193 0.026815798 +464 193 0.00037999987 +465 193 0.0084138997 +467 193 0.0086852983 +468 193 0.0067310967 +469 193 0.0028227 +470 193 0.0030940999 +471 193 0.0030397999 +473 193 5.4299991e-05 +477 193 0.00016279999 +478 193 0.00081419991 +483 193 0.00092279981 +489 193 5.4299991e-05 +490 193 0.0003256998 +491 193 0.00016279999 +22 194 0.00030299998 +60 194 0.0025757998 +104 194 0.0019697 +114 194 0.00015149999 +126 194 0.00015149999 +130 194 0.00030299998 +159 194 0.0037878999 +160 194 0.0018181999 +171 194 0.00015149999 +186 194 0.0010605999 +187 194 0.15742415 +188 194 0.18045449 +192 194 0.00030299998 +194 194 0.0039393976 +198 194 0.051666699 +204 194 0.00015149999 +206 194 0.00030299998 +211 194 0.00030299998 +214 194 0.0021211999 +219 194 0.0039393976 +221 194 0.00045449985 +223 194 0.00030299998 +224 194 0.0013635999 +225 194 0.00015149999 +234 194 0.0025757998 +240 194 0.00075759995 +241 194 0.0077272989 +272 194 0.00030299998 +277 194 0.0012120998 +279 194 0.0013635999 +294 194 0.00030299998 +296 194 0.00015149999 +312 194 0.00030299998 +317 194 0.00090909982 +319 194 0.00015149999 +322 194 0.00015149999 +326 194 0.00045449985 +340 194 0.0015151999 +347 194 0.0037878999 +356 194 0.00045449985 +358 194 0.0012120998 +361 194 0.00015149999 +372 194 0.00015149999 +392 194 0.00030299998 +393 194 0.00015149999 +419 194 0.00090909982 +420 194 0.00015149999 +422 194 0.00075759995 +434 194 0.00015149999 +443 194 0.020909097 +444 194 0.0046969987 +445 194 0.012727298 +446 194 0.00090909982 +447 194 0.0068181977 +450 194 0.0027272999 +452 194 0.0042423978 +453 194 0.0015151999 +454 194 0.0025757998 +455 194 0.0375758 +457 194 0.0018181999 +458 194 0.00030299998 +459 194 0.00030299998 +460 194 0.00060609984 +463 194 0.037878796 +464 194 0.0054544993 +465 194 0.016060598 +467 194 0.0098484978 +468 194 0.0092423968 +469 194 0.0033332999 +470 194 0.0036364 +471 194 0.00060609984 +473 194 0.00015149999 +477 194 0.00015149999 +478 194 0.00075759995 +483 194 0.00090909982 +490 194 0.00030299998 +491 194 0.0033332999 +22 195 0.0087335967 +60 195 0.0074859969 +114 195 0.00062379986 +186 195 0.076731086 +187 195 0.0043667965 +188 195 0.0087335967 +192 195 0.0074859969 +195 195 0.00062379986 +198 195 0.040548999 +206 195 0.0012476998 +214 195 0.016843397 +219 195 0.0037429999 +224 195 0.0043667965 +234 195 0.0081097968 +241 195 0.026824698 +272 195 0.00062379986 +279 195 0.0018714999 +340 195 0.00062379986 +347 195 0.0043667965 +356 195 0.00062379986 +358 195 0.0018714999 +443 195 0.013100397 +444 195 0.00062379986 +445 195 0.026200898 +446 195 0.0012476998 +447 195 0.013100397 +450 195 0.0043667965 +452 195 0.036805999 +453 195 0.014348097 +454 195 0.0043667965 +455 195 0.034934498 +457 195 0.0018714999 +458 195 0.00062379986 +459 195 0.021210197 +463 195 0.0037429999 +464 195 0.00062379986 +465 195 0.0012476998 +467 195 0.010605097 +468 195 0.0012476998 +469 195 0.0037429999 +470 195 0.0037429999 +471 195 0.00062379986 +478 195 0.0012476998 +483 195 0.0012476998 +489 195 0.0018714999 +490 195 0.00062379986 +491 195 0.037429798 +60 196 0.0018582998 +114 196 0.00023229999 +126 196 0.00023229999 +131 196 0.00023229999 +138 196 0.00023229999 +139 196 0.0023228999 +187 196 0.26666665 +188 196 0.027874596 +189 196 0.0013936998 +192 196 0.005342599 +194 196 0.0011614 +196 196 0.0062717982 +198 196 0.021370497 +204 196 0.0020905999 +206 196 0.00046459981 +207 196 0.0011614 +208 196 0.0037165999 +214 196 0.00023229999 +219 196 0.0030196998 +221 196 0.0013936998 +233 196 0.00023229999 +234 196 0.0018582998 +241 196 0.080139399 +272 196 0.00046459981 +277 196 0.00092919986 +326 196 0.00046459981 +347 196 0.0032519998 +348 196 0.00023229999 +356 196 0.00046459981 +358 196 0.0016259998 +422 196 0.00069689984 +443 196 0.0109175 +444 196 0.0013936998 +445 196 0.0141696 +446 196 0.00023229999 +447 196 0.0020905999 +450 196 0.0039488971 +452 196 0.0048779994 +453 196 0.00092919986 +455 196 0.054587699 +457 196 0.0020905999 +458 196 0.00092919986 +459 196 0.00046459981 +460 196 0.00046459981 +463 196 0.0157956 +464 196 0.00069689984 +465 196 0.0016259998 +467 196 0.011614397 +468 196 0.0027874999 +469 196 0.0046457984 +470 196 0.0051102974 +471 196 0.00069689984 +473 196 0.00023229999 +478 196 0.00092919986 +479 196 0.00069689984 +483 196 0.0013936998 +490 196 0.00046459981 +22 197 0.00014729999 +60 197 0.0029463999 +104 197 0.00029459991 +114 197 0.00014729999 +126 197 0.00014729999 +130 197 0.0013259 +131 197 0.00058929995 +139 197 0.0047141984 +142 197 0.0025044 +159 197 0.00073659979 +160 197 0.0010311999 +161 197 0.00014729999 +165 197 0.00029459991 +170 197 0.00014729999 +171 197 0.00044199987 +186 197 0.0013259 +187 197 0.20035356 +188 197 0.022834398 +189 197 0.0011785999 +190 197 0.00014729999 +192 197 0.0010311999 +193 197 0.00014729999 +194 197 0.00044199987 +196 197 0.00014729999 +197 197 0.0039775968 +198 197 0.039628796 +203 197 0.00014729999 +204 197 0.0025044 +205 197 0.00014729999 +206 197 0.00029459991 +208 197 0.0033882998 +211 197 0.0017678 +212 197 0.00014729999 +214 197 0.014142599 +219 197 0.0064819977 +221 197 0.011490896 +222 197 0.0010311999 +223 197 0.00014729999 +224 197 0.0072185993 +225 197 0.00073659979 +233 197 0.00014729999 +234 197 0.0027990998 +237 197 0.00014729999 +240 197 0.00044199987 +241 197 0.059074797 +270 197 0.00014729999 +271 197 0.00014729999 +272 197 0.00058929995 +276 197 0.00014729999 +277 197 0.00058929995 +282 197 0.00014729999 +293 197 0.0066292994 +294 197 0.00029459991 +296 197 0.00014729999 +315 197 0.00044199987 +325 197 0.0048614964 +326 197 0.00044199987 +340 197 0.00044199987 +347 197 0.0029463999 +356 197 0.00029459991 +358 197 0.0013259 +392 197 0.00044199987 +393 197 0.00014729999 +420 197 0.00014729999 +422 197 0.0011785999 +434 197 0.00014729999 +443 197 0.0095756985 +444 197 0.0048614964 +445 197 0.0123748 +446 197 0.00058929995 +447 197 0.0082498975 +450 197 0.0035356998 +452 197 0.0060400963 +453 197 0.0016204999 +454 197 0.00058929995 +455 197 0.043017097 +457 197 0.0017678 +458 197 0.00029459991 +459 197 0.00029459991 +460 197 0.00073659979 +463 197 0.034767199 +464 197 0.00058929995 +465 197 0.0016204999 +467 197 0.011343498 +468 197 0.0079551972 +469 197 0.0038302999 +470 197 0.0042721964 +471 197 0.00088389986 +473 197 0.00014729999 +477 197 0.00014729999 +478 197 0.0011785999 +479 197 0.00073659979 +483 197 0.0017678 +490 197 0.00058929995 +491 197 0.0035356998 +9 198 1.26e-05 +16 198 1.26e-05 +18 198 6.2899999e-05 +22 198 0.00016339999 +24 198 1.26e-05 +60 198 0.0056322999 +79 198 1.26e-05 +82 198 1.26e-05 +83 198 1.26e-05 +84 198 1.26e-05 +104 198 1.26e-05 +108 198 2.5099987e-05 +113 198 3.7699996e-05 +114 198 7.5399992e-05 +126 198 3.7699996e-05 +127 198 1.26e-05 +130 198 2.5099987e-05 +142 198 1.26e-05 +150 198 0.00057829986 +151 198 1.26e-05 +159 198 0.00022629999 +160 198 0.00033939979 +162 198 2.5099987e-05 +165 198 3.7699996e-05 +169 198 1.26e-05 +171 198 2.5099987e-05 +186 198 3.7699996e-05 +187 198 0.025232296 +188 198 0.3545844 +189 198 0.0001509 +190 198 8.7999986e-05 +192 198 0.0021247 +194 198 0.012685299 +196 198 1.26e-05 +197 198 0.00095549994 +198 198 0.0183427 +200 198 3.7699996e-05 +201 198 2.5099987e-05 +202 198 3.7699996e-05 +203 198 6.2899999e-05 +204 198 0.00055319979 +205 198 1.26e-05 +206 198 0.00016339999 +207 198 5.029999e-05 +208 198 0.00025139982 +209 198 1.26e-05 +210 198 1.26e-05 +211 198 1.26e-05 +212 198 1.26e-05 +213 198 1.26e-05 +214 198 0.0020114998 +218 198 1.26e-05 +219 198 0.0070906989 +221 198 0.0099570975 +223 198 2.5099987e-05 +224 198 0.0090896972 +229 198 1.26e-05 +233 198 0.00013829999 +234 198 0.0061602965 +237 198 0.0001886 +240 198 0.00023889999 +241 198 0.0014583999 +248 198 1.26e-05 +250 198 1.26e-05 +252 198 5.029999e-05 +272 198 0.00052799983 +273 198 1.26e-05 +277 198 0.0053305998 +279 198 0.0012824 +282 198 1.26e-05 +284 198 1.26e-05 +285 198 1.26e-05 +287 198 3.7699996e-05 +289 198 0.00057829986 +290 198 2.5099987e-05 +292 198 2.5099987e-05 +293 198 0.0022127 +295 198 3.7699996e-05 +296 198 1.26e-05 +297 198 1.26e-05 +299 198 1.26e-05 +300 198 1.26e-05 +301 198 1.26e-05 +312 198 3.7699996e-05 +315 198 6.2899999e-05 +317 198 0.0002137 +319 198 1.26e-05 +320 198 2.5099987e-05 +321 198 2.5099987e-05 +322 198 2.5099987e-05 +326 198 0.0012069 +328 198 0.0001509 +330 198 5.029999e-05 +340 198 0.0022629998 +347 198 0.0033944999 +349 198 1.26e-05 +350 198 1.26e-05 +351 198 0.00013829999 +354 198 3.7699996e-05 +356 198 0.0001509 +358 198 0.0012949 +372 198 2.5099987e-05 +384 198 3.7699996e-05 +387 198 2.5099987e-05 +394 198 1.26e-05 +395 198 1.26e-05 +397 198 1.26e-05 +402 198 6.2899999e-05 +419 198 1.26e-05 +422 198 0.0001257 +423 198 1.26e-05 +425 198 1.26e-05 +430 198 2.5099987e-05 +431 198 1.26e-05 +432 198 1.26e-05 +433 198 2.5099987e-05 +434 198 3.7699996e-05 +442 198 0.0009680998 +443 198 0.029934198 +444 198 0.0025143998 +445 198 0.013514999 +446 198 0.00098059978 +447 198 0.0054185987 +448 198 2.5099987e-05 +449 198 1.26e-05 +450 198 0.0042493977 +452 198 0.0060094967 +453 198 0.0022880998 +454 198 0.00055319979 +455 198 0.0278221 +456 198 0.00045259995 +457 198 0.0016217998 +458 198 0.00056569977 +459 198 0.0010937999 +460 198 0.00093029998 +463 198 0.014030498 +464 198 0.0021749998 +465 198 0.0039350986 +467 198 0.011591498 +468 198 0.0071283989 +469 198 0.0031933 +470 198 0.0035452999 +471 198 0.0023383999 +473 198 7.5399992e-05 +477 198 0.00010059999 +478 198 0.00094289985 +479 198 5.029999e-05 +483 198 0.0010308998 +489 198 5.029999e-05 +490 198 0.00027659978 +491 198 0.0001886 +9 199 5.0899995e-05 +18 199 0.00040749996 +60 199 0.0058062971 +82 199 0.00010189999 +83 199 5.0899995e-05 +84 199 5.0899995e-05 +108 199 0.00010189999 +113 199 0.0001528 +114 199 0.0003564998 +126 199 0.0001528 +141 199 0.00025469996 +150 199 5.0899995e-05 +151 199 0.00020369999 +187 199 0.1624223 +189 199 0.00025469996 +190 199 0.00020369999 +192 199 0.0001528 +194 199 0.0003056 +196 199 5.0899995e-05 +197 199 0.00010189999 +200 199 0.0019864 +201 199 0.00010189999 +203 199 0.0003056 +204 199 0.019659799 +205 199 0.0029540998 +206 199 0.0010696 +207 199 0.00025469996 +209 199 0.00020369999 +212 199 0.0005092998 +213 199 0.00010189999 +214 199 0.00040749996 +221 199 0.0040745996 +223 199 5.0899995e-05 +233 199 0.0003056 +234 199 0.0024446999 +237 199 0.0004584 +241 199 0.0019864 +248 199 5.0899995e-05 +250 199 5.0899995e-05 +252 199 5.0899995e-05 +272 199 0.0009168 +277 199 5.0899995e-05 +317 199 0.00025469996 +334 199 0.00040749996 +340 199 0.0003564998 +348 199 0.0015788998 +356 199 5.0899995e-05 +358 199 0.00040749996 +384 199 5.0899995e-05 +387 199 0.0001528 +402 199 0.0001528 +422 199 0.0057552978 +423 199 5.0899995e-05 +425 199 5.0899995e-05 +430 199 0.00010189999 +431 199 5.0899995e-05 +432 199 5.0899995e-05 +433 199 0.0001528 +434 199 0.00020369999 +443 199 0.0049912967 +444 199 0.0123256 +445 199 0.006519299 +446 199 0.00025469996 +447 199 0.027706999 +448 199 5.0899995e-05 +449 199 5.0899995e-05 +450 199 0.021798898 +452 199 0.0045329966 +453 199 0.0006620998 +454 199 0.0003564998 +455 199 0.0251095 +456 199 0.0016297998 +457 199 0.0071304999 +458 199 0.00056029996 +459 199 0.0012732998 +460 199 0.0018336 +463 199 0.028623797 +464 199 0.019557897 +465 199 0.0014260998 +467 199 0.031781599 +468 199 0.0096261986 +469 199 0.015788898 +470 199 0.0170113 +471 199 0.0057043992 +472 199 0.00010189999 +473 199 0.0003564998 +477 199 0.00020369999 +478 199 0.0034633998 +483 199 0.011765298 +489 199 0.00010189999 +490 199 0.0013752 +9 200 7.0999988e-05 +60 200 0.0023425999 +82 200 7.0999988e-05 +83 200 7.0999988e-05 +84 200 7.0999988e-05 +108 200 7.0999988e-05 +113 200 7.0999988e-05 +114 200 0.00021299999 +126 200 0.00014199999 +139 200 0.00021299999 +150 200 0.00035489979 +187 200 0.097536683 +188 200 7.0999988e-05 +189 200 0.0034073999 +190 200 0.00014199999 +192 200 0.0095832981 +194 200 7.0999988e-05 +198 200 0.0013487998 +200 200 0.0033363998 +201 200 0.0013487998 +202 200 0.060055397 +203 200 0.00014199999 +204 200 0.1510613 +205 200 0.00014199999 +206 200 0.00085179997 +207 200 7.0999988e-05 +209 200 0.00085179997 +210 200 0.010932099 +211 200 0.014410399 +214 200 0.00092279981 +221 200 0.0041172989 +234 200 0.00078089978 +237 200 0.00014199999 +241 200 0.00035489979 +272 200 0.00028389995 +279 200 7.0999988e-05 +325 200 0.00014199999 +340 200 0.00042589987 +348 200 0.0010648 +356 200 7.0999988e-05 +358 200 0.00014199999 +387 200 0.00014199999 +402 200 7.0999988e-05 +404 200 7.0999988e-05 +422 200 0.0017746999 +430 200 7.0999988e-05 +433 200 7.0999988e-05 +434 200 7.0999988e-05 +443 200 0.0034073999 +444 200 0.0051820986 +445 200 0.0056789964 +446 200 0.00014199999 +447 200 0.012564797 +450 200 0.0047561973 +452 200 0.0015616999 +453 200 0.00021299999 +455 200 0.0203024 +456 200 0.0010648 +457 200 0.0055369996 +458 200 0.00056789978 +459 200 0.0015616999 +460 200 0.0012778 +463 200 0.12209839 +464 200 0.0056079999 +465 200 0.0026974999 +467 200 0.0326542 +468 200 0.0472776 +469 200 0.012209799 +470 200 0.013629597 +471 200 0.0040462986 +473 200 0.00028389995 +477 200 7.0999988e-05 +478 200 0.0024136 +483 200 0.054376397 +490 200 0.0010648 +491 200 0.00070989993 +9 201 3.309999e-05 +16 201 3.309999e-05 +18 201 3.309999e-05 +60 201 0.0013891 +79 201 3.309999e-05 +82 201 3.309999e-05 +83 201 3.309999e-05 +84 201 3.309999e-05 +108 201 6.6099994e-05 +113 201 9.9199999e-05 +114 201 0.00026459992 +126 201 9.9199999e-05 +127 201 3.309999e-05 +133 201 3.309999e-05 +139 201 0.0024474999 +150 201 0.00033069984 +158 201 3.309999e-05 +160 201 6.6099994e-05 +171 201 3.309999e-05 +187 201 0.058045298 +188 201 6.6099994e-05 +189 201 0.0020836999 +190 201 9.9199999e-05 +192 201 0.0011906999 +194 201 0.00013229999 +198 201 0.0021497998 +200 201 0.0014552998 +201 201 0.015941799 +202 201 0.19222754 +203 201 0.0014221999 +204 201 0.018686999 +205 201 0.0021167998 +206 201 0.00095919985 +207 201 6.6099994e-05 +208 201 0.00039689988 +209 201 9.9199999e-05 +210 201 0.037605397 +211 201 0.0056225993 +212 201 3.309999e-05 +213 201 3.309999e-05 +214 201 9.9199999e-05 +221 201 0.0030427999 +224 201 0.0001984 +234 201 0.00092609995 +237 201 0.00023149999 +240 201 3.309999e-05 +241 201 0.005324997 +243 201 0.00026459992 +248 201 3.309999e-05 +250 201 3.309999e-05 +252 201 3.309999e-05 +263 201 3.309999e-05 +272 201 0.00036379998 +277 201 6.6099994e-05 +279 201 3.309999e-05 +312 201 3.309999e-05 +317 201 3.309999e-05 +325 201 0.0014882998 +326 201 3.309999e-05 +340 201 3.309999e-05 +348 201 0.00079379999 +356 201 3.309999e-05 +358 201 0.0001984 +372 201 3.309999e-05 +387 201 9.9199999e-05 +388 201 3.309999e-05 +390 201 3.309999e-05 +402 201 6.6099994e-05 +404 201 3.309999e-05 +405 201 6.6099994e-05 +419 201 3.309999e-05 +422 201 0.0014552998 +423 201 3.309999e-05 +425 201 3.309999e-05 +428 201 0.00013229999 +430 201 6.6099994e-05 +431 201 3.309999e-05 +432 201 3.309999e-05 +433 201 6.6099994e-05 +434 201 6.6099994e-05 +443 201 0.0019182998 +444 201 0.0068793967 +445 201 0.0051264986 +446 201 6.6099994e-05 +447 201 0.014486499 +449 201 3.309999e-05 +450 201 0.0051264986 +452 201 0.0016205998 +453 201 0.00029769982 +454 201 9.9199999e-05 +455 201 0.012898996 +456 201 0.00079379999 +457 201 0.0054902993 +458 201 0.0006614998 +459 201 0.0006614998 +460 201 0.0014221999 +463 201 0.11992717 +464 201 0.0058210976 +465 201 0.0012236999 +467 201 0.0168017 +468 201 0.025632497 +469 201 0.011179097 +470 201 0.012435898 +471 201 0.0023482998 +473 201 0.00026459992 +477 201 6.6099994e-05 +478 201 0.0019514 +479 201 9.9199999e-05 +483 201 0.031817399 +489 201 3.309999e-05 +490 201 0.0011906999 +491 201 0.0013229998 +60 202 0.0036038999 +82 202 9.4799994e-05 +108 202 9.4799994e-05 +114 202 9.4799994e-05 +126 202 9.4799994e-05 +130 202 9.4799994e-05 +132 202 9.4799994e-05 +139 202 0.0027504 +150 202 0.0034142998 +158 202 9.4799994e-05 +160 202 0.00028449995 +165 202 9.4799994e-05 +171 202 0.00018969999 +172 202 9.4799994e-05 +187 202 0.13154399 +188 202 0.0185888 +189 202 9.4799994e-05 +190 202 0.00037939986 +192 202 0.013941597 +194 202 0.00028449995 +197 202 9.4799994e-05 +198 202 0.0036038999 +200 202 0.0024658998 +201 202 9.4799994e-05 +202 202 0.0018967998 +203 202 0.0036038999 +204 202 0.006069798 +205 202 0.017166197 +206 202 0.0013277999 +207 202 9.4799994e-05 +209 202 0.0014225999 +210 202 0.0090098977 +211 202 0.024848297 +212 202 0.0040780976 +213 202 0.00085359998 +214 202 0.0020864999 +219 202 0.010527298 +221 202 0.016502298 +224 202 0.00075869984 +233 202 0.00028449995 +234 202 0.0021813 +237 202 0.00047419989 +241 202 0.011855099 +243 202 0.0018967998 +272 202 0.00075869984 +277 202 0.00047419989 +279 202 9.4799994e-05 +293 202 9.4799994e-05 +294 202 9.4799994e-05 +312 202 0.00018969999 +315 202 9.4799994e-05 +317 202 9.4799994e-05 +325 202 0.0043626986 +326 202 9.4799994e-05 +348 202 0.0027504 +358 202 0.00037939986 +372 202 9.4799994e-05 +387 202 9.4799994e-05 +398 202 9.4799994e-05 +402 202 9.4799994e-05 +409 202 9.4799994e-05 +422 202 0.014415797 +428 202 0.00075869984 +430 202 9.4799994e-05 +431 202 9.4799994e-05 +433 202 9.4799994e-05 +434 202 0.00037939986 +443 202 0.0063542984 +444 202 0.0027504 +445 202 0.029305797 +446 202 0.00018969999 +447 202 0.0088201985 +450 202 0.0080614984 +452 202 0.0070181973 +453 202 0.001802 +454 202 0.00047419989 +455 202 0.030348998 +456 202 0.00047419989 +457 202 0.0037935998 +458 202 0.00075869984 +459 202 0.00085359998 +460 202 0.0018967998 +463 202 0.015553899 +464 202 0.0023709999 +465 202 0.0019916999 +467 202 0.019252699 +468 202 0.018019699 +469 202 0.0065439977 +470 202 0.0073026977 +471 202 0.0061645992 +472 202 9.4799994e-05 +473 202 0.00018969999 +478 202 0.0016122998 +479 202 9.4799994e-05 +483 202 0.0022761999 +489 202 9.4799994e-05 +490 202 0.00056899991 +9 203 0.00015369999 +60 203 0.0012297998 +82 203 0.00015369999 +83 203 0.00015369999 +84 203 0.00015369999 +108 203 0.00015369999 +113 203 0.00015369999 +114 203 0.0003074999 +126 203 0.00015369999 +127 203 0.00015369999 +133 203 0.00015369999 +150 203 0.0019985 +160 203 0.00015369999 +187 203 0.0424289 +188 203 0.0003074999 +189 203 0.00046119979 +190 203 0.00015369999 +192 203 0.00046119979 +194 203 0.0003074999 +197 203 0.00015369999 +198 203 0.0013835998 +200 203 0.0033819999 +201 203 0.00046119979 +202 203 0.050576497 +203 203 0.010299798 +204 203 0.026748698 +205 203 0.0003074999 +206 203 0.0012297998 +207 203 0.00015369999 +208 203 0.00015369999 +210 203 0.069792449 +211 203 0.0064565986 +221 203 0.0015372999 +224 203 0.00015369999 +234 203 0.0015372999 +237 203 0.0003074999 +241 203 0.0073788986 +248 203 0.00015369999 +250 203 0.00015369999 +252 203 0.00015369999 +272 203 0.00046119979 +277 203 0.00015369999 +279 203 0.00015369999 +317 203 0.00015369999 +348 203 0.0007685998 +358 203 0.0003074999 +387 203 0.00015369999 +402 203 0.00015369999 +419 203 0.00015369999 +422 203 0.0084549971 +423 203 0.00015369999 +425 203 0.00015369999 +428 203 0.00015369999 +430 203 0.00015369999 +431 203 0.00015369999 +433 203 0.00015369999 +434 203 0.00015369999 +443 203 0.0012297998 +444 203 0.0081475973 +445 203 0.0027671 +446 203 0.00015369999 +447 203 0.0167563 +450 203 0.006917797 +452 203 0.0024595999 +453 203 0.0003074999 +455 203 0.010299798 +456 203 0.0007685998 +457 203 0.0039968975 +458 203 0.00061489991 +459 203 0.00046119979 +460 203 0.0012297998 +463 203 0.023674097 +464 203 0.0083012991 +465 203 0.0016909998 +467 203 0.035972297 +468 203 0.017217498 +469 203 0.013835497 +470 203 0.0152191 +471 203 0.004919298 +473 203 0.0003074999 +477 203 0.00015369999 +478 203 0.0041506998 +483 203 0.0063027963 +489 203 0.00015369999 +490 203 0.0012297998 +491 203 0.00015369999 +9 204 2.0699998e-05 +18 204 6.2199993e-05 +22 204 2.0699998e-05 +60 204 0.0037759 +82 204 2.0699998e-05 +83 204 2.0699998e-05 +84 204 2.0699998e-05 +104 204 8.2999992e-05 +108 204 2.0699998e-05 +113 204 6.2199993e-05 +114 204 0.0001452 +126 204 4.1499996e-05 +130 204 0.00029049977 +131 204 2.0699998e-05 +132 204 0.00010369999 +133 204 2.0699998e-05 +138 204 2.0699998e-05 +139 204 0.0001867 +141 204 2.0699998e-05 +142 204 6.2199993e-05 +143 204 4.1499996e-05 +150 204 0.00072609982 +151 204 2.0699998e-05 +159 204 4.1499996e-05 +160 204 2.0699998e-05 +169 204 2.0699998e-05 +171 204 2.0699998e-05 +180 204 2.0699998e-05 +187 204 0.16491359 +188 204 0.0081533976 +189 204 0.0002489998 +190 204 0.000166 +192 204 0.0082985982 +193 204 4.1499996e-05 +194 204 0.00041489978 +196 204 2.0699998e-05 +197 204 4.1499996e-05 +198 204 0.0039832965 +200 204 0.00041489978 +201 204 8.2999992e-05 +202 204 0.00062239985 +203 204 0.00064309989 +204 204 0.022240199 +205 204 0.010041296 +206 204 0.0011824998 +207 204 0.00022819999 +208 204 0.000166 +209 204 0.0040455982 +210 204 0.0018048999 +211 204 0.015352398 +212 204 0.011244599 +213 204 0.0022198998 +214 204 0.0075101964 +219 204 0.0011824998 +221 204 0.021472599 +223 204 4.1499996e-05 +224 204 0.0010372999 +225 204 2.0699998e-05 +226 204 8.2999992e-05 +227 204 6.2199993e-05 +233 204 0.00076759979 +234 204 0.0021160999 +237 204 0.00031119981 +240 204 4.1499996e-05 +241 204 0.008174099 +243 204 6.2199993e-05 +248 204 2.0699998e-05 +252 204 4.1499996e-05 +270 204 2.0699998e-05 +271 204 2.0699998e-05 +272 204 0.00078839995 +277 204 0.0026969998 +279 204 0.00012449999 +287 204 8.2999992e-05 +289 204 0.00091279997 +290 204 6.2199993e-05 +292 204 6.2199993e-05 +293 204 0.0018671998 +294 204 6.2199993e-05 +295 204 2.0699998e-05 +315 204 4.1499996e-05 +317 204 2.0699998e-05 +319 204 6.2199993e-05 +320 204 2.0699998e-05 +321 204 2.0699998e-05 +325 204 0.0024065999 +326 204 8.2999992e-05 +334 204 2.0699998e-05 +340 204 0.00010369999 +347 204 8.2999992e-05 +348 204 0.0040247999 +356 204 2.0699998e-05 +358 204 0.00035269978 +370 204 2.0699998e-05 +384 204 2.0699998e-05 +387 204 6.2199993e-05 +392 204 2.0699998e-05 +394 204 2.0699998e-05 +397 204 2.0699998e-05 +402 204 8.2999992e-05 +421 204 2.0699998e-05 +422 204 0.010829698 +430 204 4.1499996e-05 +431 204 0.00033189985 +432 204 2.0699998e-05 +433 204 8.2999992e-05 +434 204 0.0011824998 +441 204 2.0699998e-05 +442 204 2.0699998e-05 +443 204 0.0067218989 +444 204 0.0023651 +445 204 0.0089831986 +446 204 0.00029049977 +447 204 0.0070122965 +448 204 2.0699998e-05 +450 204 0.0079665966 +452 204 0.0060994998 +453 204 0.0020538999 +454 204 0.00039419997 +455 204 0.031990997 +456 204 0.00078839995 +457 204 0.0033608999 +458 204 0.00066389982 +459 204 0.0011202998 +460 204 0.0017633999 +463 204 0.014315099 +464 204 0.0024895999 +465 204 0.0024895999 +467 204 0.027924698 +468 204 0.0080080964 +469 204 0.0065973997 +470 204 0.0073441975 +471 204 0.0028007999 +472 204 0.0001867 +473 204 0.0001452 +477 204 8.2999992e-05 +478 204 0.0014936998 +479 204 4.1499996e-05 +483 204 0.0037550998 +489 204 8.2999992e-05 +490 204 0.00053939992 +491 204 0.0002489998 +60 205 0.003268 +130 205 0.00065359985 +187 205 0.014379099 +188 205 0.00065359985 +192 205 0.00065359985 +198 205 0.0013071999 +200 205 0.010457497 +203 205 0.0078430995 +204 205 0.0026143999 +205 205 0.00065359985 +206 205 0.00065359985 +208 205 0.00065359985 +209 205 0.00065359985 +211 205 0.0013071999 +212 205 0.0019607998 +214 205 0.029411796 +218 205 0.00065359985 +221 205 0.0019607998 +222 205 0.00065359985 +224 205 0.0019607998 +225 205 0.00065359985 +233 205 0.0013071999 +234 205 0.003268 +241 205 0.0071894974 +270 205 0.0071894974 +272 205 0.00065359985 +292 205 0.0045751967 +293 205 0.069934547 +294 205 0.0071894974 +301 205 0.00065359985 +320 205 0.013725497 +348 205 0.0019607998 +422 205 0.0372549 +434 205 0.0078430995 +442 205 0.011111099 +443 205 0.003268 +444 205 0.0078430995 +445 205 0.0065358989 +447 205 0.016993497 +450 205 0.0065358989 +452 205 0.0058823973 +453 205 0.0019607998 +455 205 0.022222199 +457 205 0.003268 +460 205 0.055555597 +463 205 0.018300697 +464 205 0.00065359985 +465 205 0.00065359985 +467 205 0.013725497 +468 205 0.0026143999 +469 205 0.008496698 +470 205 0.0098038986 +471 205 0.0013071999 +478 205 0.0013071999 +483 205 0.00065359985 +490 205 0.00065359985 +9 206 7.1799994e-05 +60 206 0.0017233 +82 206 7.1799994e-05 +108 206 7.1799994e-05 +114 206 0.00014359999 +126 206 7.1799994e-05 +131 206 7.1799994e-05 +139 206 7.1799994e-05 +150 206 0.0021541 +187 206 0.24965888 +188 206 0.0031593 +189 206 7.1799994e-05 +190 206 7.1799994e-05 +192 206 0.0034464998 +194 206 0.0022976999 +197 206 7.1799994e-05 +198 206 0.010554999 +200 206 0.0017233 +203 206 0.0019387 +204 206 0.0056005977 +205 206 0.00078979996 +206 206 0.0099087991 +207 206 0.00028719986 +208 206 7.1799994e-05 +209 206 0.00028719986 +210 206 7.1799994e-05 +211 206 0.018309798 +212 206 0.0016514999 +213 206 0.00028719986 +214 206 0.00050259987 +219 206 0.0028720999 +221 206 0.0055287965 +233 206 7.1799994e-05 +234 206 0.0013642998 +237 206 0.0002154 +241 206 0.00071799988 +272 206 0.00071799988 +277 206 7.1799994e-05 +279 206 0.00014359999 +317 206 7.1799994e-05 +325 206 0.00014359999 +326 206 7.1799994e-05 +348 206 0.0022976999 +358 206 0.0002154 +387 206 7.1799994e-05 +402 206 7.1799994e-05 +422 206 0.0041645989 +430 206 7.1799994e-05 +433 206 7.1799994e-05 +434 206 0.030229099 +443 206 0.0081136972 +444 206 0.0027284999 +445 206 0.010267798 +446 206 0.00035899994 +447 206 0.0081854984 +450 206 0.0053133965 +452 206 0.0053851977 +453 206 0.0010052 +454 206 0.0015079 +455 206 0.046743698 +456 206 0.00028719986 +457 206 0.0033028999 +458 206 0.00071799988 +459 206 0.00043079979 +460 206 0.0015079 +463 206 0.0078264996 +464 206 0.0021541 +465 206 0.0013642998 +467 206 0.010124199 +468 206 0.0052415989 +469 206 0.0053851977 +470 206 0.0061032996 +471 206 0.0015796998 +473 206 0.00014359999 +478 206 0.0010769998 +483 206 0.0016514999 +489 206 7.1799994e-05 +490 206 0.00050259987 +491 206 7.1799994e-05 +60 207 0.0015452998 +108 207 0.0001717 +114 207 0.00034339982 +126 207 0.0001717 +130 207 0.00034339982 +131 207 0.0072114989 +133 207 0.0001717 +139 207 0.013221197 +141 207 0.0001717 +150 207 0.0001717 +187 207 0.11933374 +188 207 0.028674498 +189 207 0.0001717 +190 207 0.0001717 +192 207 0.0015452998 +194 207 0.016998596 +196 207 0.00034339982 +198 207 0.008928597 +200 207 0.00034339982 +203 207 0.0024037999 +204 207 0.00068679987 +205 207 0.0001717 +206 207 0.00051509985 +207 207 0.026270598 +210 207 0.00034339982 +211 207 0.00034339982 +212 207 0.0001717 +214 207 0.00051509985 +219 207 0.00051509985 +221 207 0.00034339982 +224 207 0.0018886998 +234 207 0.0024037999 +237 207 0.00034339982 +241 207 0.027815897 +243 207 0.00034339982 +252 207 0.0001717 +272 207 0.00051509985 +277 207 0.0070397966 +279 207 0.0001717 +312 207 0.0001717 +315 207 0.0001717 +326 207 0.012019198 +340 207 0.0001717 +347 207 0.0001717 +348 207 0.0024037999 +358 207 0.00034339982 +387 207 0.0001717 +422 207 0.0029189999 +433 207 0.0001717 +434 207 0.0001717 +443 207 0.0065246969 +444 207 0.0010301999 +445 207 0.013221197 +446 207 0.0001717 +447 207 0.0077265985 +450 207 0.0078983977 +452 207 0.0058378987 +453 207 0.0018886998 +454 207 0.00034339982 +455 207 0.0331387 +456 207 0.0001717 +457 207 0.0029189999 +458 207 0.0010301999 +459 207 0.00034339982 +460 207 0.0017169998 +463 207 0.021291196 +464 207 0.00051509985 +465 207 0.0017169998 +467 207 0.012877699 +468 207 0.0070397966 +469 207 0.0060095973 +470 207 0.0065246969 +471 207 0.0022320999 +473 207 0.0001717 +477 207 0.0001717 +478 207 0.0018886998 +483 207 0.0017169998 +489 207 0.0001717 +490 207 0.00068679987 +491 207 0.0001717 +9 208 0.00016349999 +60 208 0.0024517998 +82 208 0.00016349999 +83 208 0.00016349999 +84 208 0.00016349999 +108 208 0.00016349999 +113 208 0.00032689981 +114 208 0.00032689981 +126 208 0.00016349999 +150 208 0.00049039978 +187 208 0.07682246 +188 208 0.00032689981 +189 208 0.018960398 +190 208 0.00016349999 +192 208 0.0034324999 +194 208 0.00032689981 +198 208 0.0068649985 +200 208 0.00016349999 +203 208 0.00016349999 +204 208 0.039065097 +205 208 0.00016349999 +206 208 0.00032689981 +207 208 0.00016349999 +208 208 0.064400077 +211 208 0.00032689981 +212 208 0.00016349999 +214 208 0.00032689981 +221 208 0.015200999 +233 208 0.0024517998 +234 208 0.001798 +237 208 0.00032689981 +241 208 0.044295497 +252 208 0.00016349999 +272 208 0.0014710999 +279 208 0.00016349999 +317 208 0.00016349999 +348 208 0.0014710999 +358 208 0.00032689981 +387 208 0.00016349999 +422 208 0.0062111989 +423 208 0.00016349999 +430 208 0.00016349999 +431 208 0.00016349999 +433 208 0.00016349999 +434 208 0.00016349999 +443 208 0.0027786999 +444 208 0.004086297 +445 208 0.009153299 +447 208 0.014383797 +450 208 0.0053939 +452 208 0.0044131987 +453 208 0.0009806999 +454 208 0.00065379986 +455 208 0.0246813 +456 208 0.00032689981 +457 208 0.0037594 +458 208 0.0013075999 +459 208 0.0009806999 +460 208 0.0014710999 +463 208 0.062602162 +464 208 0.00081729982 +465 208 0.0014710999 +467 208 0.048872199 +468 208 0.0080091991 +469 208 0.0107878 +470 208 0.0120955 +471 208 0.0014710999 +473 208 0.00032689981 +477 208 0.00016349999 +478 208 0.0014710999 +479 208 0.012912698 +483 208 0.0031055999 +490 208 0.0013075999 +491 208 0.00016349999 +60 209 0.0014450999 +114 209 0.00048169983 +126 209 0.00048169983 +130 209 0.032273598 +150 209 0.00048169983 +187 209 0.094412267 +188 209 0.0014450999 +192 209 0.00048169983 +194 209 0.00048169983 +198 209 0.0048169978 +204 209 0.0019267998 +205 209 0.00048169983 +206 209 0.00096339989 +208 209 0.00048169983 +209 209 0.0019267998 +211 209 0.0096338987 +212 209 0.00096339989 +214 209 0.0019267998 +221 209 0.0062619969 +225 209 0.0086704977 +234 209 0.0028901999 +237 209 0.00048169983 +241 209 0.0019267998 +272 209 0.00048169983 +292 209 0.0024084998 +293 209 0.00048169983 +294 209 0.00096339989 +317 209 0.00048169983 +348 209 0.0033718999 +358 209 0.00048169983 +422 209 0.0028901999 +443 209 0.0038535998 +444 209 0.00048169983 +445 209 0.0057802983 +447 209 0.0077070966 +450 209 0.008188799 +452 209 0.0067436993 +453 209 0.00096339989 +454 209 0.0014450999 +455 209 0.015896 +456 209 0.00048169983 +457 209 0.0033718999 +458 209 0.00048169983 +459 209 0.015414298 +460 209 0.0033718999 +463 209 0.025048196 +464 209 0.00096339989 +465 209 0.0014450999 +467 209 0.014450897 +468 209 0.0086704977 +469 209 0.0077070966 +470 209 0.0091521963 +471 209 0.0019267998 +472 209 0.0048169978 +473 209 0.00048169983 +478 209 0.0019267998 +483 209 0.0024084998 +490 209 0.00096339989 +60 210 0.00076079997 +108 210 0.00025359984 +114 210 0.0005071999 +126 210 0.00025359984 +131 210 0.00025359984 +139 210 0.024600599 +150 210 0.00025359984 +187 210 0.043875199 +188 210 0.029165599 +189 210 0.00025359984 +190 210 0.00025359984 +192 210 0.0010144999 +194 210 0.0010144999 +198 210 0.0017752999 +200 210 0.00025359984 +201 210 0.0005071999 +202 210 0.0076083988 +203 210 0.00025359984 +204 210 0.0017752999 +205 210 0.0005071999 +206 210 0.00076079997 +207 210 0.0053258985 +210 210 0.019274697 +211 210 0.00076079997 +212 210 0.00025359984 +214 210 0.00025359984 +219 210 0.022317998 +221 210 0.0005071999 +234 210 0.0035505998 +237 210 0.0005071999 +241 210 0.0050722994 +243 210 0.00025359984 +272 210 0.0005071999 +277 210 0.0045650974 +290 210 0.00025359984 +326 210 0.00025359984 +348 210 0.0038041999 +358 210 0.0005071999 +387 210 0.00025359984 +422 210 0.00076079997 +433 210 0.00025359984 +434 210 0.00025359984 +443 210 0.0035505998 +444 210 0.0005071999 +445 210 0.0053258985 +447 210 0.0017752999 +450 210 0.011919897 +452 210 0.0068475977 +453 210 0.00076079997 +454 210 0.00025359984 +455 210 0.015724096 +456 210 0.00025359984 +457 210 0.0035505998 +458 210 0.0005071999 +459 210 0.00025359984 +460 210 0.0015216998 +463 210 0.015470497 +464 210 0.00076079997 +465 210 0.003297 +467 210 0.017499398 +468 210 0.0043113977 +469 210 0.0063402988 +470 210 0.0071011968 +471 210 0.003297 +473 210 0.00025359984 +478 210 0.0022824998 +483 210 0.003297 +489 210 0.00025359984 +490 210 0.00076079997 +60 211 0.0014368 +114 211 0.00035919994 +150 211 0.00035919994 +187 211 0.022270098 +188 211 0.0014368 +192 211 0.0014368 +194 211 0.00035919994 +198 211 0.00035919994 +202 211 0.0010775998 +203 211 0.00035919994 +204 211 0.0025143998 +205 211 0.0014368 +206 211 0.00035919994 +209 211 0.00035919994 +210 211 0.00071839988 +211 211 0.0021551999 +212 211 0.00071839988 +214 211 0.0010775998 +219 211 0.00071839988 +221 211 0.0021551999 +234 211 0.0017959999 +237 211 0.00035919994 +241 211 0.0010775998 +272 211 0.00035919994 +287 211 0.014008597 +293 211 0.0010775998 +294 211 0.00035919994 +320 211 0.00035919994 +325 211 0.00035919994 +348 211 0.021192499 +358 211 0.00035919994 +422 211 0.026221298 +443 211 0.0010775998 +444 211 0.00071839988 +445 211 0.010057498 +447 211 0.0079022981 +450 211 0.0096982978 +452 211 0.0071838982 +453 211 0.00071839988 +455 211 0.011135098 +457 211 0.0035919999 +458 211 0.0014368 +459 211 0.00035919994 +460 211 0.0021551999 +463 211 0.024425298 +464 211 0.0010775998 +465 211 0.0014368 +467 211 0.0172414 +468 211 0.011853397 +469 211 0.0075430982 +470 211 0.0082614981 +471 211 0.0032327999 +478 211 0.0017959999 +483 211 0.0028736 +490 211 0.00071839988 +60 212 0.0015552 +114 212 0.00077759987 +130 212 0.00077759987 +187 212 0.029548999 +188 212 0.00077759987 +192 212 0.00077759987 +200 212 0.00077759987 +202 212 0.0031103999 +203 212 0.00077759987 +204 212 0.0038879998 +205 212 0.00077759987 +206 212 0.00077759987 +210 212 0.00077759987 +211 212 0.0015552 +212 212 0.0093312971 +214 212 0.0046655983 +221 212 0.0023327998 +234 212 0.0015552 +241 212 0.031881798 +270 212 0.00077759987 +292 212 0.024105798 +293 212 0.0077759996 +294 212 0.038102597 +320 212 0.0015552 +348 212 0.0031103999 +422 212 0.013996899 +434 212 0.00077759987 +442 212 0.0015552 +443 212 0.00077759987 +444 212 0.0015552 +445 212 0.013996899 +447 212 0.0062207989 +450 212 0.0093312971 +452 212 0.0062207989 +453 212 0.0015552 +455 212 0.013996899 +457 212 0.0031103999 +459 212 0.00077759987 +460 212 0.050544299 +463 212 0.022550497 +464 212 0.0023327998 +465 212 0.00077759987 +467 212 0.014774498 +468 212 0.0038879998 +469 212 0.010886498 +470 212 0.010886498 +471 212 0.0015552 +478 212 0.0015552 +483 212 0.0054431967 +490 212 0.00077759987 +114 213 0.0039840974 +187 213 0.011952199 +198 213 0.0039840974 +206 213 0.0039840974 +214 213 0.07171309 +241 213 0.0039840974 +292 213 0.023904398 +293 213 0.0039840974 +294 213 0.011952199 +348 213 0.0079680979 +422 213 0.019920297 +443 213 0.0079680979 +444 213 0.0039840974 +445 213 0.0039840974 +447 213 0.07171309 +450 213 0.0079680979 +452 213 0.0079680979 +455 213 0.011952199 +457 213 0.0039840974 +460 213 0.011952199 +463 213 0.035856597 +464 213 0.0039840974 +467 213 0.011952199 +468 213 0.0039840974 +469 213 0.0079680979 +470 213 0.0079680979 +478 213 0.0039840974 +483 213 0.0079680979 +490 213 0.0039840974 +5 214 1.7299986e-05 +6 214 0.00015029999 +9 214 2.8899987e-05 +10 214 6.359999e-05 +12 214 1.1599999e-05 +13 214 5.1999989e-05 +14 214 4.6199988e-05 +16 214 1.7299986e-05 +17 214 0.0001734 +18 214 0.0002138 +19 214 0.0024389999 +20 214 0.00068779988 +21 214 0.0076001994 +22 214 0.0053634979 +23 214 0.047849398 +24 214 0.0022598 +25 214 0.0090277977 +60 214 0.011460997 +66 214 6.939999e-05 +75 214 1.7299986e-05 +79 214 1.7299986e-05 +82 214 0.00050859991 +83 214 2.3099987e-05 +84 214 2.3099987e-05 +88 214 0.00012139999 +98 214 0.00071669999 +102 214 0.00010399999 +103 214 5.7999996e-06 +104 214 0.00053749979 +107 214 0.0004623998 +108 214 0.00014449999 +109 214 5.1999989e-05 +113 214 6.359999e-05 +114 214 0.0001734 +116 214 4.0499988e-05 +117 214 8.6699991e-05 +118 214 0.00014449999 +119 214 0.00030629989 +120 214 0.00062419986 +122 214 5.7999996e-06 +125 214 5.7999996e-06 +126 214 6.359999e-05 +127 214 1.7299986e-05 +130 214 3.4699988e-05 +131 214 1.1599999e-05 +132 214 2.8899987e-05 +139 214 1.1599999e-05 +140 214 0.00012139999 +150 214 0.0002023 +151 214 0.00010399999 +153 214 5.7999996e-06 +158 214 5.7999996e-06 +159 214 0.0001965 +160 214 0.00015599999 +162 214 5.7999996e-06 +169 214 5.7999996e-06 +171 214 4.0499988e-05 +186 214 0.0022308999 +187 214 0.0002023 +188 214 1.1599999e-05 +189 214 8.089999e-05 +190 214 4.0499988e-05 +192 214 0.00052589993 +193 214 0.0007050999 +194 214 6.359999e-05 +196 214 5.7999996e-06 +197 214 1.1599999e-05 +198 214 0.0035601999 +200 214 4.6199988e-05 +201 214 2.8899987e-05 +202 214 5.7999996e-06 +203 214 2.8899987e-05 +204 214 0.00010979999 +206 214 0.00046809996 +207 214 2.3099987e-05 +209 214 5.7999996e-06 +214 214 0.17221504 +215 214 0.0048374981 +217 214 0.00058949995 +218 214 0.00062999991 +219 214 1.1599999e-05 +220 214 8.089999e-05 +222 214 0.0001907 +223 214 0.0035023999 +224 214 0.0036122999 +225 214 0.00023699999 +226 214 5.7999996e-06 +227 214 2.8899987e-05 +228 214 0.00028899987 +229 214 0.0001849 +230 214 1.1599999e-05 +231 214 0.00073979981 +232 214 5.7799989e-05 +233 214 0.0014044 +234 214 0.013911497 +237 214 0.00011559999 +239 214 5.7999996e-06 +240 214 9.2499991e-05 +241 214 0.0076290965 +242 214 1.1599999e-05 +248 214 2.3099987e-05 +250 214 1.7299986e-05 +251 214 0.00023699999 +252 214 0.00039879978 +253 214 0.00010979999 +254 214 5.7999996e-06 +257 214 5.7999996e-06 +263 214 1.7299986e-05 +267 214 0.0013581999 +270 214 2.3099987e-05 +272 214 0.0002254 +273 214 0.00035259989 +276 214 5.7999996e-06 +277 214 0.0051727965 +278 214 6.939999e-05 +279 214 2.3099987e-05 +282 214 9.8299992e-05 +283 214 4.6199988e-05 +284 214 2.8899987e-05 +285 214 0.0018032 +286 214 0.00078599993 +287 214 0.0064731985 +288 214 0.0012830999 +289 214 0.00082069985 +290 214 0.0031093999 +291 214 5.7999996e-06 +292 214 4.0499988e-05 +293 214 1.7299986e-05 +294 214 0.00082649989 +295 214 3.4699988e-05 +297 214 1.7299986e-05 +298 214 1.7299986e-05 +300 214 0.0011038999 +301 214 0.0036527 +305 214 4.0499988e-05 +307 214 4.6199988e-05 +308 214 5.7999996e-06 +312 214 0.00014449999 +314 214 1.7299986e-05 +315 214 2.8899987e-05 +317 214 5.7999996e-06 +320 214 5.7999996e-06 +321 214 1.7299986e-05 +322 214 5.1999989e-05 +324 214 0.0014564998 +325 214 2.3099987e-05 +326 214 0.0002427 +328 214 0.00012139999 +331 214 0.0002081 +332 214 0.00015029999 +333 214 5.7999996e-06 +335 214 1.1599999e-05 +336 214 2.8899987e-05 +337 214 2.3099987e-05 +340 214 4.6199988e-05 +341 214 5.7999996e-06 +343 214 5.7999996e-06 +349 214 0.0099986978 +350 214 0.0044040978 +351 214 5.1999989e-05 +352 214 2.3099987e-05 +354 214 4.6199988e-05 +356 214 0.0014853999 +358 214 0.00076289987 +359 214 5.7999996e-06 +364 214 5.7999996e-06 +366 214 0.0010287999 +370 214 2.3099987e-05 +371 214 1.7299986e-05 +372 214 3.4699988e-05 +373 214 1.1599999e-05 +374 214 1.7299986e-05 +375 214 0.00059529999 +380 214 1.1599999e-05 +384 214 8.089999e-05 +386 214 5.7999996e-06 +387 214 6.359999e-05 +392 214 5.7999996e-06 +393 214 5.7999996e-06 +394 214 5.7999996e-06 +397 214 5.7999996e-06 +402 214 7.509999e-05 +404 214 1.7299986e-05 +408 214 1.1599999e-05 +414 214 0.0010346 +416 214 5.7999996e-06 +417 214 0.00015029999 +419 214 2.3099987e-05 +421 214 8.089999e-05 +422 214 7.509999e-05 +423 214 1.7299986e-05 +425 214 1.7299986e-05 +430 214 5.1999989e-05 +431 214 2.3099987e-05 +432 214 5.7999996e-06 +433 214 1.1599999e-05 +434 214 1.7299986e-05 +441 214 5.7999996e-06 +442 214 0.00013289999 +443 214 0.014957599 +444 214 0.00278 +445 214 0.011374298 +446 214 0.0048721991 +447 214 0.0071493983 +448 214 0.0033753 +449 214 1.7299986e-05 +450 214 0.0031382998 +452 214 0.023696396 +453 214 0.024459299 +454 214 0.0027279998 +455 214 0.022164799 +456 214 0.00061839982 +457 214 0.0034330999 +458 214 0.00071089994 +459 214 0.0013581999 +460 214 0.0014910998 +463 214 0.0194542 +464 214 0.0027973 +465 214 0.00071089994 +467 214 0.017697196 +468 214 0.008941099 +469 214 0.010102797 +470 214 0.0076001994 +471 214 0.0015604999 +472 214 5.7999996e-06 +473 214 0.0001676 +477 214 0.00043349992 +478 214 0.00068779988 +483 214 0.0011500998 +489 214 0.0015315998 +490 214 0.0025603999 +491 214 0.00087849982 +6 215 0.00011199999 +9 215 7.4699987e-05 +10 215 3.7299993e-05 +11 215 3.7299993e-05 +14 215 0.00033609988 +17 215 3.7299993e-05 +18 215 0.00014939999 +19 215 0.00056019984 +21 215 0.00093369978 +22 215 0.0020915999 +23 215 0.0058638975 +24 215 0.0077313967 +25 215 0.046799097 +60 215 0.0043698996 +72 215 0.00052289991 +82 215 0.0025397998 +84 215 3.7299993e-05 +98 215 7.4699987e-05 +102 215 0.0001867 +104 215 3.7299993e-05 +107 215 7.4699987e-05 +108 215 0.00014939999 +109 215 3.7299993e-05 +114 215 0.00011199999 +116 215 3.7299993e-05 +118 215 0.00011199999 +120 215 0.00029879995 +122 215 3.7299993e-05 +126 215 7.4699987e-05 +153 215 0.0029505999 +171 215 3.7299993e-05 +186 215 0.00014939999 +189 215 7.4699987e-05 +190 215 3.7299993e-05 +192 215 0.0015312999 +193 215 0.0090385973 +194 215 0.00011199999 +198 215 0.002353 +200 215 3.7299993e-05 +203 215 3.7299993e-05 +204 215 3.7299993e-05 +206 215 0.00037349993 +214 215 0.089452446 +215 215 0.13501894 +216 215 0.0024277 +217 215 0.0013446 +218 215 7.4699987e-05 +220 215 7.4699987e-05 +222 215 3.7299993e-05 +223 215 0.00029879995 +224 215 0.00022409999 +228 215 3.7299993e-05 +229 215 7.4699987e-05 +231 215 3.7299993e-05 +233 215 0.00014939999 +234 215 0.0051542968 +237 215 0.0001867 +240 215 3.7299993e-05 +241 215 0.0042578988 +251 215 3.7299993e-05 +252 215 0.00037349993 +267 215 0.00026139989 +272 215 0.00082169985 +273 215 3.7299993e-05 +277 215 0.0013818999 +278 215 0.00014939999 +282 215 7.4699987e-05 +284 215 3.7299993e-05 +285 215 0.00014939999 +286 215 3.7299993e-05 +287 215 0.00052289991 +288 215 0.00014939999 +289 215 0.0011951998 +290 215 0.00044819992 +294 215 7.4699987e-05 +295 215 3.7299993e-05 +300 215 0.0017553999 +301 215 0.0084036998 +312 215 3.7299993e-05 +324 215 0.0012698998 +325 215 3.7299993e-05 +326 215 3.7299993e-05 +340 215 3.7299993e-05 +349 215 0.0040710978 +350 215 0.0027264999 +351 215 3.7299993e-05 +354 215 3.7299993e-05 +356 215 0.0013818999 +358 215 0.00041079987 +366 215 7.4699987e-05 +370 215 3.7299993e-05 +371 215 3.7299993e-05 +375 215 7.4699987e-05 +384 215 7.4699987e-05 +387 215 7.4699987e-05 +402 215 3.7299993e-05 +414 215 0.00041079987 +417 215 0.00011199999 +421 215 7.4699987e-05 +422 215 0.00011199999 +430 215 3.7299993e-05 +434 215 3.7299993e-05 +443 215 0.023119397 +444 215 0.0017180999 +445 215 0.03664 +446 215 0.011727799 +447 215 0.0040337965 +448 215 0.00044819992 +450 215 0.0025770999 +452 215 0.024688099 +453 215 0.059087198 +454 215 0.0045192987 +455 215 0.023156799 +456 215 0.00026139989 +457 215 0.0010457998 +458 215 0.00085899979 +459 215 0.00048549986 +460 215 0.0015312999 +463 215 0.013819396 +464 215 0.0019047998 +465 215 0.00037349993 +467 215 0.010943498 +468 215 0.0056770965 +469 215 0.0045192987 +470 215 0.0046686977 +471 215 0.0011951998 +473 215 0.00011199999 +477 215 0.00022409999 +478 215 0.00056019984 +483 215 0.00082169985 +489 215 0.00093369978 +490 215 0.0070216991 +491 215 0.0022035998 +24 216 0.023255799 +60 216 0.007751897 +82 216 0.007751897 +153 216 0.007751897 +192 216 0.007751897 +193 216 0.015503898 +198 216 0.007751897 +214 216 0.13178289 +215 216 0.28682166 +216 216 0.007751897 +217 216 0.007751897 +300 216 0.007751897 +301 216 0.007751897 +350 216 0.007751897 +443 216 0.023255799 +444 216 0.007751897 +445 216 0.031007797 +446 216 0.007751897 +447 216 0.007751897 +452 216 0.007751897 +455 216 0.038759697 +463 216 0.038759697 +464 216 0.007751897 +467 216 0.015503898 +468 216 0.007751897 +469 216 0.007751897 +470 216 0.007751897 +3 217 0.0001661 +6 217 0.0037368999 +10 217 8.2999992e-05 +13 217 8.2999992e-05 +14 217 8.2999992e-05 +17 217 0.00033219997 +18 217 0.0001661 +19 217 0.00024909992 +20 217 0.00049829995 +21 217 0.0012455999 +22 217 0.0011625998 +23 217 0.0004151999 +24 217 0.0082211979 +25 217 0.0053977966 +60 217 0.00382 +82 217 0.00033219997 +98 217 0.0074737966 +102 217 0.00049829995 +104 217 0.0021590998 +107 217 0.0001661 +108 217 0.00024909992 +109 217 8.2999992e-05 +114 217 8.2999992e-05 +116 217 8.2999992e-05 +118 217 0.00066429982 +119 217 0.00033219997 +120 217 0.00058129989 +122 217 8.2999992e-05 +126 217 8.2999992e-05 +153 217 0.0001661 +159 217 0.0011625998 +160 217 0.0017438999 +186 217 0.00049829995 +189 217 8.2999992e-05 +192 217 0.0033216998 +193 217 0.0048164986 +194 217 8.2999992e-05 +198 217 0.0070585981 +204 217 0.00033219997 +206 217 0.00074739987 +214 217 0.20445108 +215 217 0.0047333986 +216 217 8.2999992e-05 +217 217 0.024414498 +218 217 0.0032386999 +223 217 0.0015777999 +224 217 0.0012455999 +228 217 0.00091349985 +229 217 8.2999992e-05 +230 217 0.0014948 +231 217 0.0015777999 +232 217 0.00066429982 +233 217 0.0008303998 +234 217 0.012622498 +237 217 0.0001661 +240 217 8.2999992e-05 +241 217 0.0076398998 +252 217 0.00033219997 +253 217 0.00074739987 +267 217 0.00049829995 +273 217 0.00091349985 +277 217 0.00066429982 +279 217 0.0001661 +285 217 0.00024909992 +286 217 0.00049829995 +287 217 0.0008303998 +288 217 0.0001661 +289 217 0.0010795998 +290 217 0.00049829995 +294 217 8.2999992e-05 +300 217 0.018435497 +301 217 0.0088024996 +314 217 0.00033219997 +315 217 0.00066429982 +324 217 0.0015777999 +325 217 8.2999992e-05 +326 217 0.0014948 +349 217 0.0013287 +350 217 0.0031555998 +356 217 0.0013287 +358 217 0.00033219997 +366 217 0.0001661 +375 217 8.2999992e-05 +387 217 8.2999992e-05 +414 217 0.0004151999 +417 217 8.2999992e-05 +421 217 0.0001661 +422 217 8.2999992e-05 +430 217 8.2999992e-05 +443 217 0.011792097 +444 217 0.0047333986 +445 217 0.012207299 +446 217 0.0048994981 +447 217 0.0064772964 +448 217 0.0001661 +450 217 0.0023251998 +452 217 0.0087194964 +453 217 0.0064772964 +454 217 0.0042351969 +455 217 0.030891899 +456 217 0.00033219997 +457 217 0.0085533969 +458 217 0.00058129989 +459 217 0.00066429982 +460 217 0.0014116999 +463 217 0.032137498 +464 217 0.0046503991 +465 217 0.0008303998 +467 217 0.025078896 +468 217 0.024746697 +469 217 0.0057298988 +470 217 0.0058129989 +471 217 0.0011625998 +473 217 8.2999992e-05 +477 217 0.00024909992 +478 217 0.00066429982 +483 217 0.0010795998 +489 217 0.00033219997 +490 217 0.014698599 +491 217 0.0017438999 +17 218 0.013446998 +22 218 0.0019679 +24 218 0.00098389992 +60 218 0.0052475967 +75 218 0.00032799994 +82 218 0.00032799994 +104 218 0.0013118999 +114 218 0.00032799994 +120 218 0.00032799994 +130 218 0.0013118999 +139 218 0.00032799994 +159 218 0.069858968 +160 218 0.075434566 +169 218 0.00032799994 +171 218 0.00032799994 +186 218 0.018694699 +192 218 0.00032799994 +193 218 0.015086897 +198 218 0.0085273981 +206 218 0.00098389992 +214 218 0.020662498 +218 218 0.1197114 +219 218 0.00032799994 +223 218 0.0016398998 +224 218 0.0032797998 +225 218 0.00098389992 +231 218 0.00032799994 +234 218 0.011151198 +240 218 0.00032799994 +241 218 0.00065599987 +252 218 0.00032799994 +267 218 0.00032799994 +272 218 0.00098389992 +277 218 0.00098389992 +279 218 0.00032799994 +284 218 0.00032799994 +287 218 0.00032799994 +300 218 0.0059035979 +301 218 0.0022957998 +322 218 0.00098389992 +324 218 0.0016398998 +326 218 0.00098389992 +347 218 0.00032799994 +350 218 0.0075434968 +356 218 0.00098389992 +358 218 0.00065599987 +414 218 0.00032799994 +417 218 0.00032799994 +421 218 0.00065599987 +443 218 0.0242703 +444 218 0.0042636991 +445 218 0.010495197 +446 218 0.0029517999 +447 218 0.015086897 +450 218 0.0026238 +452 218 0.0098392963 +453 218 0.011479199 +454 218 0.0045916997 +455 218 0.042308997 +457 218 0.0026238 +458 218 0.00065599987 +459 218 0.0081993975 +460 218 0.00065599987 +463 218 0.0121351 +464 218 0.00065599987 +465 218 0.00032799994 +467 218 0.010167297 +468 218 0.022958297 +469 218 0.0032797998 +470 218 0.0032797998 +471 218 0.0088553987 +477 218 0.00032799994 +478 218 0.00098389992 +483 218 0.00098389992 +489 218 0.00065599987 +490 218 0.011479199 +491 218 0.0091832988 +0 219 0.00031229993 +5 219 0.00010409999 +6 219 0.00031229993 +12 219 0.00041639991 +13 219 0.00010409999 +14 219 0.0070781969 +17 219 0.00031229993 +18 219 0.0002082 +21 219 0.0002082 +22 219 0.0002082 +23 219 0.00052049989 +24 219 0.0057249963 +60 219 0.0023941 +82 219 0.0087435991 +87 219 0.0002082 +90 219 0.0015613998 +104 219 0.0047881976 +107 219 0.00062449998 +108 219 0.00010409999 +114 219 0.00010409999 +118 219 0.0010408999 +119 219 0.0030185999 +120 219 0.00093679992 +126 219 0.00010409999 +130 219 0.0014572998 +131 219 0.00010409999 +142 219 0.00010409999 +149 219 0.00010409999 +159 219 0.00041639991 +160 219 0.00031229993 +161 219 0.00010409999 +169 219 0.00010409999 +187 219 0.0029145 +188 219 0.0002082 +191 219 0.00093679992 +192 219 0.00229 +193 219 0.0026022999 +194 219 0.0002082 +198 219 0.0087435991 +204 219 0.00031229993 +206 219 0.0002082 +208 219 0.00010409999 +214 219 0.16519195 +215 219 0.00093679992 +218 219 0.018736299 +219 219 0.0091599971 +222 219 0.00031229993 +223 219 0.0066617988 +224 219 0.060372598 +225 219 0.030498598 +227 219 0.00010409999 +228 219 0.00010409999 +229 219 0.0002082 +230 219 0.00010409999 +231 219 0.00031229993 +232 219 0.00010409999 +233 219 0.00052049989 +234 219 0.021026298 +237 219 0.00010409999 +240 219 0.0069740973 +241 219 0.0052044988 +243 219 0.00031229993 +252 219 0.00041639991 +273 219 0.0011449999 +277 219 0.00041639991 +279 219 0.0002082 +282 219 0.0002082 +284 219 0.00010409999 +285 219 0.00010409999 +287 219 0.0066617988 +288 219 0.00010409999 +290 219 0.00010409999 +300 219 0.0086394995 +301 219 0.026439097 +315 219 0.0002082 +317 219 0.00010409999 +319 219 0.00010409999 +322 219 0.00010409999 +324 219 0.00062449998 +326 219 0.0092640966 +337 219 0.00010409999 +340 219 0.0002082 +349 219 0.00010409999 +350 219 0.0031226999 +356 219 0.0012490998 +358 219 0.00052049989 +387 219 0.00010409999 +393 219 0.00010409999 +402 219 0.00010409999 +417 219 0.0002082 +421 219 0.0002082 +422 219 0.00010409999 +430 219 0.00010409999 +442 219 0.00010409999 +443 219 0.011866298 +444 219 0.00229 +445 219 0.012699097 +446 219 0.0028104999 +447 219 0.006245397 +448 219 0.00031229993 +450 219 0.0029145 +452 219 0.0063494965 +453 219 0.0029145 +454 219 0.00229 +455 219 0.031643599 +456 219 0.0002082 +457 219 0.0020817998 +458 219 0.00041639991 +459 219 0.00041639991 +460 219 0.0017694999 +463 219 0.046112198 +464 219 0.00093679992 +465 219 0.00083269994 +467 219 0.010825399 +468 219 0.050483998 +469 219 0.0059331991 +470 219 0.0065576993 +471 219 0.0010408999 +473 219 0.00010409999 +477 219 0.0002082 +478 219 0.00072859996 +483 219 0.0010408999 +490 219 0.0030185999 +491 219 0.00093679992 +18 220 0.00050529977 +21 220 0.00025269995 +22 220 0.0149065 +25 220 0.00025269995 +60 220 0.0058109984 +77 220 0.00025269995 +104 220 0.0017686 +108 220 0.00025269995 +114 220 0.00025269995 +126 220 0.00025269995 +171 220 0.0063162968 +189 220 0.00025269995 +190 220 0.00025269995 +192 220 0.0050530992 +193 220 0.00025269995 +194 220 0.00025269995 +198 220 0.0078321993 +200 220 0.00025269995 +203 220 0.00025269995 +206 220 0.00050529977 +214 220 0.044214197 +215 220 0.043708898 +220 220 0.016927697 +223 220 0.00025269995 +229 220 0.0096007995 +234 220 0.0073268972 +237 220 0.00050529977 +241 220 0.0098534971 +252 220 0.0010105998 +272 220 0.0015158998 +277 220 0.0027792 +282 220 0.00025269995 +284 220 0.00050529977 +287 220 0.00025269995 +292 220 0.0025264998 +301 220 0.032844897 +333 220 0.00025269995 +349 220 0.00025269995 +350 220 0.0078321993 +356 220 0.0012633 +358 220 0.0017686 +387 220 0.00025269995 +417 220 0.00050529977 +421 220 0.00050529977 +422 220 0.00025269995 +430 220 0.00025269995 +434 220 0.00025269995 +443 220 0.0149065 +444 220 0.00075799995 +445 220 0.0060636997 +446 220 0.0017686 +447 220 0.0012633 +450 220 0.0070742965 +452 220 0.017180398 +453 220 0.0078321993 +454 220 0.0010105998 +455 220 0.017685696 +456 220 0.00050529977 +457 220 0.0010105998 +459 220 0.00050529977 +460 220 0.015159197 +463 220 0.0083374977 +464 220 0.00075799995 +465 220 0.0012633 +467 220 0.017685696 +468 220 0.0020211998 +469 220 0.011116698 +470 220 0.012379996 +471 220 0.0020211998 +473 220 0.00025269995 +477 220 0.00025269995 +478 220 0.0022739 +483 220 0.0020211998 +489 220 0.0025264998 +490 220 0.0010105998 +491 220 0.00050529977 +13 221 0.0001981 +21 221 0.0001981 +22 221 0.0001981 +24 221 0.0025752999 +25 221 0.0001981 +60 221 0.0021790999 +108 221 0.0001981 +114 221 0.00039619999 +118 221 0.0001981 +119 221 0.0063390993 +120 221 0.00039619999 +126 221 0.0001981 +131 221 0.00039619999 +171 221 0.00039619999 +187 221 0.0011886 +192 221 0.0017829 +193 221 0.0001981 +194 221 0.0001981 +198 221 0.004754398 +206 221 0.00039619999 +214 221 0.29793978 +215 221 0.0035657999 +218 221 0.014659297 +221 221 0.00039619999 +222 221 0.011093497 +223 221 0.0031695999 +224 221 0.036846299 +225 221 0.0093105994 +230 221 0.0015848 +233 221 0.031893797 +234 221 0.034865297 +237 221 0.0001981 +240 221 0.0001981 +241 221 0.0013867 +252 221 0.00039619999 +276 221 0.0001981 +277 221 0.00099049998 +279 221 0.0001981 +284 221 0.0001981 +287 221 0.0001981 +292 221 0.0001981 +293 221 0.00039619999 +294 221 0.0001981 +300 221 0.0021790999 +301 221 0.010499198 +312 221 0.0001981 +315 221 0.00039619999 +324 221 0.00059429999 +326 221 0.0001981 +349 221 0.0001981 +350 221 0.0063390993 +356 221 0.0013867 +358 221 0.00079239998 +359 221 0.0001981 +361 221 0.0001981 +363 221 0.0001981 +372 221 0.0001981 +387 221 0.0001981 +392 221 0.0001981 +417 221 0.0001981 +419 221 0.0001981 +422 221 0.0001981 +443 221 0.014263097 +444 221 0.001981 +445 221 0.011093497 +446 221 0.0027733999 +447 221 0.010895398 +448 221 0.00059429999 +450 221 0.0029714999 +452 221 0.0063390993 +453 221 0.0015848 +454 221 0.00059429999 +455 221 0.043977797 +457 221 0.0011886 +458 221 0.0001981 +459 221 0.00059429999 +460 221 0.0013867 +463 221 0.015847899 +464 221 0.00059429999 +465 221 0.00059429999 +467 221 0.0089143999 +468 221 0.017036498 +469 221 0.006537199 +470 221 0.0073295981 +471 221 0.00079239998 +473 221 0.0001981 +477 221 0.0001981 +478 221 0.00099049998 +483 221 0.0011886 +490 221 0.00059429999 +491 221 0.00039619999 +23 222 0.051610097 +60 222 0.0039699972 +114 222 0.00044109998 +153 222 0.0066166967 +169 222 0.0066166967 +193 222 0.034406699 +198 222 0.0022055998 +206 222 0.00044109998 +214 222 0.00044109998 +223 222 0.00044109998 +234 222 0.16453457 +252 222 0.00044109998 +272 222 0.00088219997 +277 222 0.00044109998 +350 222 0.014556699 +358 222 0.00044109998 +443 222 0.0022055998 +444 222 0.00044109998 +445 222 0.0083810985 +446 222 0.0039699972 +447 222 0.016321097 +450 222 0.0022055998 +452 222 0.021173399 +453 222 0.022496697 +454 222 0.0017643999 +455 222 0.0410234 +457 222 0.0017643999 +459 222 0.029995598 +460 222 0.0013232999 +463 222 0.029113397 +464 222 0.00044109998 +467 222 0.0070577972 +468 222 0.037494499 +469 222 0.0026466998 +470 222 0.0022055998 +478 222 0.00044109998 +483 222 0.00088219997 +489 222 0.00044109998 +490 222 0.00044109998 +491 222 0.0013232999 +0 223 0.00043869996 +2 223 0.00035099988 +3 223 4.39e-05 +6 223 0.00026319991 +9 223 0.00048259995 +11 223 0.00030709989 +13 223 0.0089061968 +14 223 4.39e-05 +17 223 0.00035099988 +18 223 0.0002194 +19 223 0.0002194 +21 223 0.0064054988 +22 223 0.0019303998 +23 223 0.0025008 +24 223 0.022594698 +25 223 0.00065809977 +60 223 0.0034220999 +77 223 0.00074579986 +82 223 0.0083358996 +83 223 4.39e-05 +84 223 0.0001755 +88 223 0.0001755 +90 223 0.0001316 +97 223 4.39e-05 +98 223 0.00057039992 +102 223 0.0010090999 +104 223 0.0010090999 +107 223 0.00048259995 +108 223 4.39e-05 +113 223 8.7699998e-05 +114 223 0.0001755 +116 223 0.0001755 +117 223 0.0001755 +118 223 0.00061419979 +119 223 0.0046066977 +120 223 0.030755099 +122 223 0.00035099988 +125 223 4.39e-05 +126 223 8.7699998e-05 +130 223 0.00039489986 +131 223 0.0001316 +135 223 4.39e-05 +140 223 4.39e-05 +142 223 4.39e-05 +150 223 0.0001316 +151 223 4.39e-05 +159 223 0.0015355998 +160 223 0.0019742998 +171 223 0.0001755 +172 223 0.0001755 +186 223 0.00043869996 +187 223 0.00070199999 +189 223 8.7699998e-05 +190 223 4.39e-05 +191 223 4.39e-05 +192 223 0.00070199999 +193 223 0.011494797 +194 223 0.00026319991 +197 223 4.39e-05 +198 223 0.0165402 +200 223 4.39e-05 +203 223 4.39e-05 +204 223 0.00048259995 +206 223 0.00039489986 +207 223 4.39e-05 +214 223 0.12438029 +215 223 0.00039489986 +217 223 0.00030709989 +218 223 0.020795897 +219 223 8.7699998e-05 +220 223 0.00061419979 +222 223 0.00083359983 +223 223 0.018689897 +224 223 0.019084796 +225 223 0.0020181998 +228 223 0.00048259995 +229 223 0.0001755 +230 223 0.00039489986 +231 223 0.0048698969 +232 223 0.00083359983 +233 223 0.00083359983 +234 223 0.016496297 +237 223 0.0001316 +240 223 0.00030709989 +241 223 0.009081699 +252 223 0.00057039992 +253 223 0.00057039992 +254 223 0.0010090999 +267 223 8.7699998e-05 +270 223 8.7699998e-05 +273 223 0.00083359983 +274 223 4.39e-05 +277 223 0.0048698969 +278 223 4.39e-05 +282 223 0.00035099988 +283 223 8.7699998e-05 +284 223 0.0001755 +285 223 0.00035099988 +286 223 4.39e-05 +287 223 0.00052649993 +288 223 0.0001755 +289 223 0.0002194 +290 223 0.00057039992 +292 223 0.00026319991 +293 223 0.00061419979 +294 223 0.0001755 +295 223 0.0001755 +296 223 0.0001316 +297 223 4.39e-05 +298 223 4.39e-05 +299 223 4.39e-05 +300 223 0.0044750981 +301 223 0.012547698 +307 223 4.39e-05 +312 223 0.0001755 +314 223 0.0014477998 +315 223 0.00057039992 +319 223 4.39e-05 +322 223 0.0002194 +324 223 0.00087749981 +325 223 0.00026319991 +326 223 0.00057039992 +328 223 8.7699998e-05 +338 223 0.0002194 +340 223 0.00039489986 +349 223 0.00083359983 +350 223 0.002413 +351 223 4.39e-05 +354 223 8.7699998e-05 +355 223 4.39e-05 +356 223 0.0013161998 +358 223 0.00092129991 +366 223 8.7699998e-05 +370 223 0.0001316 +372 223 0.0002194 +373 223 0.00039489986 +374 223 0.0001316 +375 223 4.39e-05 +384 223 4.39e-05 +385 223 4.39e-05 +387 223 4.39e-05 +392 223 0.0001316 +393 223 8.7699998e-05 +402 223 8.7699998e-05 +414 223 8.7699998e-05 +417 223 0.0002194 +419 223 4.39e-05 +420 223 4.39e-05 +421 223 8.7699998e-05 +422 223 0.0002194 +423 223 4.39e-05 +425 223 4.39e-05 +430 223 4.39e-05 +431 223 8.7699998e-05 +433 223 4.39e-05 +434 223 4.39e-05 +442 223 4.39e-05 +443 223 0.013512898 +444 223 0.0021497998 +445 223 0.017066598 +446 223 0.0036414999 +447 223 0.0044311993 +448 223 0.00043869996 +450 223 0.0041678995 +452 223 0.0075899996 +453 223 0.0065370984 +454 223 0.0012722998 +455 223 0.035712697 +456 223 0.00035099988 +457 223 0.0055718981 +458 223 0.00048259995 +459 223 0.0028078998 +460 223 0.0015793999 +463 223 0.023428198 +464 223 0.00078969984 +465 223 0.0022813999 +467 223 0.023472097 +468 223 0.025753498 +469 223 0.0062299967 +470 223 0.0065370984 +471 223 0.0023691 +473 223 0.0001316 +477 223 0.0002194 +478 223 0.00078969984 +479 223 4.39e-05 +483 223 0.0011407 +489 223 0.00026319991 +490 223 0.0021058999 +491 223 0.0030711 +9 224 2.2099994e-05 +13 224 2.2099994e-05 +14 224 6.6199995e-05 +16 224 2.2099994e-05 +17 224 0.00013249999 +18 224 0.00017669999 +19 224 0.00037539983 +20 224 4.4199987e-05 +21 224 0.0014574998 +22 224 0.0032241 +23 224 0.0043502972 +24 224 0.00044169999 +25 224 0.0014574998 +60 224 0.0091864988 +79 224 2.2099994e-05 +82 224 0.00022079999 +83 224 2.2099994e-05 +84 224 2.2099994e-05 +88 224 2.2099994e-05 +98 224 0.0001104 +104 224 0.0001104 +107 224 6.6199995e-05 +108 224 2.2099994e-05 +113 224 6.6199995e-05 +114 224 0.00013249999 +118 224 0.0020758 +119 224 0.0026719999 +120 224 0.0001987 +126 224 8.8299988e-05 +127 224 2.2099994e-05 +130 224 0.00072869984 +131 224 4.4199987e-05 +140 224 0.00046369992 +149 224 2.2099994e-05 +150 224 0.0001987 +151 224 4.4199987e-05 +159 224 0.00024289999 +160 224 0.00033119996 +171 224 0.00081709982 +186 224 0.0014354 +187 224 0.0001104 +188 224 8.8299988e-05 +189 224 6.6199995e-05 +190 224 4.4199987e-05 +192 224 0.0071989968 +193 224 0.00090539991 +194 224 0.00013249999 +197 224 2.2099994e-05 +198 224 0.0083472989 +200 224 4.4199987e-05 +201 224 2.2099994e-05 +202 224 4.4199987e-05 +203 224 2.2099994e-05 +204 224 0.0001546 +206 224 0.00048579997 +207 224 2.2099994e-05 +208 224 2.2099994e-05 +214 224 0.30310929 +215 224 0.0022745 +217 224 6.6199995e-05 +218 224 0.0037319998 +219 224 4.4199987e-05 +222 224 0.0010821 +223 224 0.0061831996 +224 224 0.023164898 +225 224 0.0022745 +226 224 4.4199987e-05 +227 224 0.00026499992 +229 224 0.0025173998 +231 224 0.0014354 +233 224 0.0027162 +234 224 0.010555599 +237 224 8.8299988e-05 +239 224 4.4199987e-05 +240 224 0.00028709997 +241 224 0.022126999 +248 224 2.2099994e-05 +250 224 2.2099994e-05 +251 224 6.6199995e-05 +252 224 0.0011924999 +267 224 0.00035329978 +270 224 0.00046369992 +272 224 2.2099994e-05 +273 224 0.0001546 +274 224 2.2099994e-05 +276 224 2.2099994e-05 +277 224 0.0010599999 +282 224 6.6199995e-05 +285 224 0.00033119996 +286 224 4.4199987e-05 +287 224 0.0012365999 +288 224 0.00022079999 +289 224 0.0001546 +290 224 0.0010157998 +294 224 0.00013249999 +300 224 0.00068459986 +301 224 0.0045269988 +315 224 0.00017669999 +319 224 4.4199987e-05 +322 224 2.2099994e-05 +324 224 0.0013911999 +326 224 0.00017669999 +340 224 0.00083909999 +349 224 0.0028486999 +350 224 0.0021861999 +356 224 0.0010378999 +358 224 0.00070669991 +366 224 0.00017669999 +375 224 8.8299988e-05 +384 224 8.8299988e-05 +385 224 2.2099994e-05 +387 224 6.6199995e-05 +402 224 4.4199987e-05 +404 224 4.4199987e-05 +414 224 0.00081709982 +417 224 0.0001546 +419 224 2.2099994e-05 +421 224 4.4199987e-05 +422 224 6.6199995e-05 +423 224 2.2099994e-05 +425 224 2.2099994e-05 +430 224 2.2099994e-05 +431 224 2.2099994e-05 +433 224 2.2099994e-05 +434 224 2.2099994e-05 +442 224 4.4199987e-05 +443 224 0.0093630999 +444 224 0.0025615999 +445 224 0.0096501969 +446 224 0.0033344999 +447 224 0.012189697 +448 224 0.00033119996 +450 224 0.0038645 +452 224 0.016098399 +453 224 0.0083914995 +454 224 0.0022304 +455 224 0.031843498 +456 224 0.00035329978 +457 224 0.0038423999 +458 224 0.00046369992 +459 224 0.0014795999 +460 224 0.0015678999 +463 224 0.016716696 +464 224 0.0023628999 +465 224 0.0036436999 +467 224 0.014132999 +468 224 0.021354098 +469 224 0.0075302981 +470 224 0.0070002973 +471 224 0.0024291 +473 224 0.00013249999 +477 224 0.0010157998 +478 224 0.00059619988 +479 224 2.2099994e-05 +483 224 0.00081709982 +489 224 0.00064039999 +490 224 0.0010599999 +491 224 0.0018107998 +18 225 0.00022819999 +19 225 0.00038039987 +20 225 7.6099997e-05 +21 225 0.0012933 +22 225 0.0017496999 +23 225 0.007531397 +24 225 0.00038039987 +25 225 0.0016735999 +60 225 0.0059337988 +82 225 7.6099997e-05 +98 225 0.00015209999 +104 225 7.6099997e-05 +107 225 7.6099997e-05 +108 225 7.6099997e-05 +114 225 0.00015209999 +118 225 0.00015209999 +119 225 0.0021300998 +120 225 7.6099997e-05 +126 225 7.6099997e-05 +130 225 0.00022819999 +140 225 0.0015975998 +150 225 7.6099997e-05 +171 225 7.6099997e-05 +186 225 0.00045639998 +187 225 7.6099997e-05 +189 225 7.6099997e-05 +192 225 0.0058576986 +193 225 0.00015209999 +198 225 0.0072270967 +206 225 0.00022819999 +214 225 0.31243819 +215 225 0.0055533983 +217 225 7.6099997e-05 +218 225 0.0074552968 +222 225 0.019018598 +223 225 0.0025864998 +224 225 0.0024343999 +225 225 0.0067705996 +229 225 0.011106897 +231 225 0.0064662993 +233 225 0.0031951 +234 225 0.013084799 +239 225 7.6099997e-05 +240 225 0.00030429987 +241 225 0.0031951 +251 225 7.6099997e-05 +252 225 0.00030429987 +267 225 0.00022819999 +272 225 0.00045639998 +273 225 7.6099997e-05 +277 225 0.0013692998 +282 225 7.6099997e-05 +285 225 0.00038039987 +286 225 7.6099997e-05 +287 225 0.0012933 +288 225 0.00022819999 +290 225 0.0058576986 +294 225 0.00015209999 +300 225 0.00015209999 +301 225 0.00098899985 +315 225 7.6099997e-05 +324 225 0.00091289985 +340 225 0.00030429987 +349 225 0.0050969981 +350 225 0.0034993999 +356 225 0.0011411 +358 225 0.00060859998 +366 225 0.00022819999 +375 225 7.6099997e-05 +387 225 7.6099997e-05 +402 225 7.6099997e-05 +414 225 0.00030429987 +417 225 7.6099997e-05 +421 225 0.00015209999 +443 225 0.011182997 +444 225 0.0034993999 +445 225 0.0089006983 +446 225 0.0031951 +447 225 0.0058576986 +448 225 0.00076069986 +450 225 0.0020539998 +452 225 0.014986698 +453 225 0.012095898 +454 225 0.0019778998 +455 225 0.029212598 +456 225 7.6099997e-05 +457 225 0.0038037 +458 225 0.00060859998 +459 225 0.0012172 +460 225 0.0014453998 +463 225 0.015367098 +464 225 0.0012172 +465 225 0.0041840971 +467 225 0.0095853992 +468 225 0.018105697 +469 225 0.0050969981 +470 225 0.0047926977 +471 225 0.0025864998 +473 225 7.6099997e-05 +477 225 0.00030429987 +478 225 0.00053249998 +483 225 0.00076069986 +489 225 0.00053249998 +490 225 0.0012172 +491 225 0.0026625998 +18 226 0.00014969999 +22 226 0.019760497 +60 226 0.0094310977 +114 226 0.00014969999 +118 226 0.00029939995 +126 226 0.00014969999 +130 226 0.0017963999 +132 226 0.012425099 +150 226 0.00014969999 +186 226 0.13757485 +190 226 0.00014969999 +192 226 0.00014969999 +198 226 0.011526898 +206 226 0.00089819985 +214 226 0.21347308 +215 226 0.00029939995 +223 226 0.017664697 +224 226 0.010628697 +226 226 0.00089819985 +227 226 0.0055388995 +231 226 0.0025448999 +234 226 0.002994 +241 226 0.013622798 +252 226 0.00029939995 +277 226 0.0011975998 +324 226 0.0013472999 +349 226 0.008981999 +350 226 0.00014969999 +356 226 0.0010478999 +358 226 0.001497 +384 226 0.00014969999 +414 226 0.0032933999 +417 226 0.0005987999 +443 226 0.030987997 +444 226 0.00029939995 +445 226 0.012125697 +446 226 0.0041915998 +447 226 0.0010478999 +450 226 0.0031436998 +452 226 0.010329299 +453 226 0.0077843964 +454 226 0.0028442999 +455 226 0.024401199 +457 226 0.0043412969 +458 226 0.0005987999 +459 226 0.001497 +460 226 0.0017963999 +463 226 0.0074849986 +464 226 0.00029939995 +465 226 0.0007485 +467 226 0.011826299 +468 226 0.0035927999 +469 226 0.0043412969 +470 226 0.004041899 +471 226 0.00029939995 +473 226 0.00014969999 +477 226 0.00014969999 +478 226 0.0011975998 +483 226 0.0007485 +489 226 0.0011975998 +490 226 0.00044909981 +491 226 0.0010478999 +2 227 0.00010149999 +4 227 0.00087939994 +9 227 3.3799995e-05 +18 227 0.00016909999 +22 227 0.0043630973 +25 227 0.00016909999 +60 227 0.0095717981 +82 227 3.3799995e-05 +83 227 3.3799995e-05 +84 227 3.3799995e-05 +104 227 3.3799995e-05 +108 227 3.3799995e-05 +113 227 6.7599991e-05 +114 227 0.00010149999 +118 227 0.0010485 +119 227 0.00016909999 +126 227 6.7599991e-05 +127 227 3.3799995e-05 +130 227 0.0024351999 +131 227 3.3799995e-05 +132 227 0.0013867 +143 227 0.0001353 +150 227 0.0004735 +151 227 3.3799995e-05 +171 227 0.0001353 +186 227 0.0088953972 +189 227 3.3799995e-05 +190 227 0.00010149999 +192 227 0.00010149999 +194 227 0.00010149999 +198 227 0.013224598 +200 227 6.7599991e-05 +203 227 3.3799995e-05 +204 227 3.3799995e-05 +206 227 0.00040589995 +207 227 3.3799995e-05 +214 227 0.26828104 +215 227 0.0016572999 +223 227 0.0052086972 +224 227 0.0383549 +225 227 0.00010149999 +226 227 0.0040248968 +227 227 0.029188897 +231 227 0.0015896999 +234 227 0.0046674982 +237 227 6.7599991e-05 +240 227 0.00010149999 +241 227 0.013123199 +248 227 3.3799995e-05 +252 227 0.00030439999 +277 227 3.3799995e-05 +284 227 3.3799995e-05 +315 227 6.7599991e-05 +322 227 3.3799995e-05 +324 227 0.00071029994 +326 227 6.7599991e-05 +340 227 6.7599991e-05 +345 227 0.00010149999 +349 227 0.0080835968 +350 227 3.3799995e-05 +356 227 0.0010146999 +358 227 0.0013867 +384 227 0.00010149999 +387 227 3.3799995e-05 +392 227 3.3799995e-05 +414 227 6.7599991e-05 +417 227 0.00033819978 +419 227 3.3799995e-05 +421 227 6.7599991e-05 +422 227 6.7599991e-05 +423 227 3.3799995e-05 +425 227 3.3799995e-05 +430 227 3.3799995e-05 +431 227 3.3799995e-05 +433 227 3.3799995e-05 +434 227 3.3799995e-05 +443 227 0.0065953992 +444 227 0.00020289999 +445 227 0.0069335997 +446 227 0.0023337998 +447 227 0.0011499999 +448 227 3.3799995e-05 +450 227 0.0039910972 +452 227 0.0126158 +453 227 0.0044645965 +454 227 0.0021307999 +455 227 0.021714099 +456 227 0.0002368 +457 227 0.0039571971 +458 227 0.00037199981 +459 227 0.0016911 +460 227 0.0015219999 +463 227 0.012480598 +464 227 0.0002368 +465 227 0.00064259977 +467 227 0.0097408965 +468 227 0.010112997 +469 227 0.0067644976 +470 227 0.0042616986 +471 227 0.0004735 +473 227 0.00010149999 +477 227 0.0002368 +478 227 0.00087939994 +483 227 0.00030439999 +489 227 0.00060879998 +490 227 0.00037199981 +491 227 0.00094699999 +0 228 0.00020699999 +5 228 1.2899999e-05 +6 228 0.0013325999 +9 228 7.7599994e-05 +10 228 1.2899999e-05 +13 228 0.00032349979 +14 228 1.2899999e-05 +16 228 3.879999e-05 +17 228 0.0001811 +18 228 0.0001164 +19 228 3.879999e-05 +21 228 0.0001294 +22 228 0.00032349979 +23 228 3.879999e-05 +24 228 6.4699998e-05 +25 228 0.00016819999 +60 228 0.0092896968 +79 228 2.5899993e-05 +82 228 0.0022123998 +83 228 7.7599994e-05 +84 228 7.7599994e-05 +85 228 0.00051749987 +88 228 0.00020699999 +90 228 5.1799987e-05 +98 228 6.4699998e-05 +102 228 0.0029628999 +104 228 0.0014231999 +107 228 0.0011514998 +108 228 0.00016819999 +109 228 1.2899999e-05 +110 228 0.00014229999 +113 228 0.00019409999 +114 228 0.0004916999 +115 228 1.2899999e-05 +116 228 0.00037519983 +117 228 2.5899993e-05 +118 228 9.0599991e-05 +119 228 2.5899993e-05 +120 228 0.0016949 +125 228 0.00055629993 +126 228 0.00020699999 +127 228 3.879999e-05 +130 228 9.0599991e-05 +131 228 7.7599994e-05 +133 228 1.2899999e-05 +135 228 1.2899999e-05 +138 228 5.1799987e-05 +139 228 2.5899993e-05 +142 228 3.879999e-05 +149 228 1.2899999e-05 +150 228 0.00019409999 +151 228 6.4699998e-05 +158 228 1.2899999e-05 +159 228 1.2899999e-05 +160 228 1.2899999e-05 +165 228 2.5899993e-05 +170 228 1.2899999e-05 +171 228 1.2899999e-05 +186 228 3.879999e-05 +187 228 9.0599991e-05 +188 228 1.2899999e-05 +189 228 0.00010349999 +190 228 5.1799987e-05 +192 228 0.0056151971 +193 228 0.0025487999 +194 228 0.00010349999 +196 228 1.2899999e-05 +197 228 3.879999e-05 +198 228 0.013818096 +200 228 7.7599994e-05 +201 228 7.7599994e-05 +203 228 7.7599994e-05 +204 228 0.0015137999 +206 228 0.00097039994 +207 228 6.4699998e-05 +209 228 1.2899999e-05 +214 228 0.039177097 +215 228 7.7599994e-05 +217 228 0.0019407 +222 228 1.2899999e-05 +223 228 0.0053046979 +224 228 0.00016819999 +228 228 0.058778599 +229 228 0.00080219982 +230 228 1.2899999e-05 +231 228 0.0001164 +232 228 0.00071159983 +233 228 5.1799987e-05 +234 228 0.0033380999 +237 228 0.0001294 +240 228 0.00014229999 +241 228 0.024893299 +242 228 1.2899999e-05 +248 228 6.4699998e-05 +250 228 5.1799987e-05 +251 228 1.2899999e-05 +252 228 0.00032349979 +253 228 0.016548097 +263 228 1.2899999e-05 +267 228 2.5899993e-05 +271 228 2.5899993e-05 +272 228 7.7599994e-05 +273 228 1.2899999e-05 +277 228 0.00021999999 +282 228 1.2899999e-05 +285 228 3.879999e-05 +286 228 6.4699998e-05 +287 228 0.0001294 +288 228 2.5899993e-05 +290 228 0.00054339995 +293 228 0.00020699999 +294 228 0.00024579978 +296 228 1.2899999e-05 +300 228 0.0056927986 +301 228 0.00067279977 +312 228 0.00010349999 +314 228 0.0026781999 +315 228 7.7599994e-05 +317 228 1.2899999e-05 +319 228 3.879999e-05 +320 228 2.5899993e-05 +321 228 5.1799987e-05 +324 228 3.879999e-05 +325 228 0.00075039989 +326 228 0.0018113998 +340 228 3.879999e-05 +349 228 0.00019409999 +350 228 0.00075039989 +354 228 3.879999e-05 +356 228 0.00014229999 +358 228 0.00036229985 +366 228 2.5899993e-05 +372 228 1.2899999e-05 +375 228 2.5899993e-05 +380 228 3.879999e-05 +384 228 6.4699998e-05 +387 228 0.00019409999 +391 228 3.879999e-05 +393 228 6.4699998e-05 +394 228 1.2899999e-05 +396 228 3.879999e-05 +397 228 1.2899999e-05 +402 228 3.879999e-05 +414 228 0.00016819999 +416 228 0.0016689999 +417 228 0.0001811 +419 228 3.879999e-05 +421 228 2.5899993e-05 +422 228 0.00015529999 +423 228 5.1799987e-05 +425 228 3.879999e-05 +430 228 0.0001164 +431 228 3.879999e-05 +432 228 1.2899999e-05 +433 228 3.879999e-05 +434 228 5.1799987e-05 +438 228 1.2899999e-05 +442 228 1.2899999e-05 +443 228 0.0034544999 +444 228 0.0014231999 +445 228 0.0054340996 +446 228 0.00080219982 +447 228 0.0030663998 +448 228 3.879999e-05 +449 228 3.879999e-05 +450 228 0.0056410991 +452 228 0.0049941987 +453 228 0.0017336998 +454 228 0.0012549998 +455 228 0.023469999 +456 228 0.0017207998 +457 228 0.0041013993 +458 228 0.0010091998 +459 228 0.0022123998 +460 228 0.001462 +463 228 0.026730496 +464 228 0.0015137999 +465 228 0.0081381984 +467 228 0.0363307 +468 228 0.099805892 +469 228 0.022486698 +470 228 0.023172498 +471 228 0.0022382999 +472 228 0.00024579978 +473 228 0.00050459988 +477 228 0.0023806 +478 228 0.0038426998 +479 228 1.2899999e-05 +483 228 0.0020183998 +489 228 0.00014229999 +490 228 0.0082028992 +491 228 0.0014878998 +3 229 0.0001026 +6 229 0.00017089999 +9 229 3.4199998e-05 +13 229 6.8399997e-05 +14 229 3.4199998e-05 +17 229 0.0001026 +18 229 0.00078629982 +19 229 3.4199998e-05 +21 229 0.00027349987 +22 229 0.00047859992 +23 229 0.0001026 +24 229 0.00044439989 +25 229 0.00017089999 +60 229 0.0020853998 +82 229 0.00017089999 +83 229 3.4199998e-05 +84 229 3.4199998e-05 +104 229 0.0003076999 +107 229 0.00068369997 +108 229 3.4199998e-05 +113 229 6.8399997e-05 +114 229 0.0001026 +117 229 6.8399997e-05 +118 229 0.00051279995 +119 229 0.0069398992 +120 229 0.017640397 +122 229 0.00017089999 +126 229 3.4199998e-05 +130 229 0.00071789999 +131 229 3.4199998e-05 +132 229 0.0001026 +137 229 6.8399997e-05 +138 229 3.4199998e-05 +139 229 3.4199998e-05 +142 229 6.8399997e-05 +143 229 0.00023929999 +149 229 6.8399997e-05 +151 229 0.00051279995 +152 229 3.4199998e-05 +157 229 3.4199998e-05 +158 229 6.8399997e-05 +160 229 6.8399997e-05 +186 229 3.4199998e-05 +187 229 3.4199998e-05 +189 229 6.8399997e-05 +190 229 3.4199998e-05 +192 229 0.0031794 +193 229 0.005914297 +194 229 0.0001026 +197 229 3.4199998e-05 +198 229 0.036067098 +200 229 3.4199998e-05 +202 229 0.00085469987 +203 229 6.8399997e-05 +204 229 0.0076236986 +206 229 0.00034189993 +207 229 3.4199998e-05 +214 229 0.10997909 +215 229 0.00013669999 +218 229 0.0010255999 +223 229 0.0044100992 +224 229 0.0018461 +228 229 0.00013669999 +229 229 0.0029400999 +230 229 0.00095719984 +231 229 0.039656799 +232 229 0.015110597 +233 229 0.00051279995 +234 229 0.0049912967 +237 229 6.8399997e-05 +240 229 6.8399997e-05 +241 229 0.057092097 +252 229 0.00068369997 +253 229 0.0031452 +260 229 6.8399997e-05 +261 229 3.4199998e-05 +267 229 3.4199998e-05 +270 229 0.0021537999 +273 229 3.4199998e-05 +277 229 0.00013669999 +285 229 3.4199998e-05 +287 229 0.00017089999 +288 229 3.4199998e-05 +289 229 0.00027349987 +290 229 0.0001026 +294 229 3.4199998e-05 +300 229 0.014392696 +301 229 0.0030083999 +314 229 0.0006153998 +315 229 0.00047859992 +316 229 0.00027349987 +324 229 0.0008888999 +325 229 0.0030767999 +326 229 0.00034189993 +349 229 0.00020509999 +350 229 0.0017434999 +356 229 0.00017089999 +358 229 0.0003076999 +366 229 3.4199998e-05 +384 229 3.4199998e-05 +387 229 3.4199998e-05 +402 229 3.4199998e-05 +404 229 6.8399997e-05 +414 229 0.00054699997 +417 229 0.0001026 +422 229 0.0001026 +423 229 3.4199998e-05 +425 229 0.00037609995 +426 229 0.00027349987 +428 229 0.00058119977 +430 229 3.4199998e-05 +431 229 0.00085469987 +433 229 3.4199998e-05 +434 229 3.4199998e-05 +443 229 0.0116577 +444 229 0.0035895999 +445 229 0.0094697997 +446 229 0.0030767999 +447 229 0.0133329 +448 229 3.4199998e-05 +450 229 0.0026323998 +452 229 0.0038973 +453 229 0.0030083999 +454 229 0.002017 +455 229 0.034460399 +456 229 0.00020509999 +457 229 0.0024614998 +458 229 0.00034189993 +459 229 0.0006153998 +460 229 0.0014699998 +463 229 0.026460599 +464 229 0.0031109999 +465 229 0.0047519989 +467 229 0.011623498 +468 229 0.12539738 +469 229 0.0088201985 +470 229 0.004717797 +471 229 0.00064959982 +472 229 3.4199998e-05 +473 229 0.0001026 +477 229 0.0011282 +478 229 0.00041019986 +483 229 0.0016067999 +489 229 0.00013669999 +490 229 0.0017776999 +491 229 0.00037609995 +3 230 0.0021062 +5 230 0.00073999981 +6 230 0.0059201978 +9 230 5.6899997e-05 +11 230 5.6899997e-05 +13 230 5.6899997e-05 +18 230 0.00017079999 +19 230 5.6899997e-05 +21 230 0.00017079999 +22 230 0.00022769999 +23 230 5.6899997e-05 +24 230 0.0052370988 +25 230 0.00028459984 +60 230 0.0015369998 +82 230 0.00011379999 +83 230 5.6899997e-05 +84 230 5.6899997e-05 +85 230 5.6899997e-05 +98 230 5.6899997e-05 +102 230 0.00022769999 +104 230 0.00022769999 +107 230 0.00011379999 +108 230 5.6899997e-05 +113 230 0.00011379999 +114 230 0.00017079999 +118 230 0.00017079999 +119 230 0.0017646998 +120 230 0.0025615999 +122 230 0.00022769999 +125 230 5.6899997e-05 +126 230 5.6899997e-05 +130 230 0.0009676998 +132 230 0.00011379999 +137 230 5.6899997e-05 +138 230 5.6899997e-05 +139 230 5.6899997e-05 +142 230 0.00017079999 +149 230 5.6899997e-05 +151 230 5.6899997e-05 +152 230 5.6899997e-05 +157 230 5.6899997e-05 +160 230 0.0011384999 +186 230 0.00011379999 +187 230 0.0010245999 +189 230 5.6899997e-05 +190 230 5.6899997e-05 +191 230 5.6899997e-05 +192 230 0.004440099 +193 230 0.0019353998 +194 230 0.00011379999 +198 230 0.023282297 +200 230 5.6899997e-05 +202 230 0.00011379999 +203 230 5.6899997e-05 +204 230 0.0042693987 +206 230 0.00022769999 +207 230 5.6899997e-05 +214 230 0.080890298 +215 230 0.00028459984 +217 230 5.6899997e-05 +218 230 0.00022769999 +223 230 0.010815699 +224 230 0.0048954971 +226 230 5.6899997e-05 +227 230 5.6899997e-05 +228 230 0.00028459984 +229 230 0.00051229983 +230 230 0.020720698 +231 230 0.019126799 +232 230 0.0085956976 +233 230 0.0086525977 +234 230 0.0055216998 +237 230 0.00011379999 +240 230 5.6899997e-05 +241 230 0.060226597 +242 230 0.00011379999 +252 230 0.00039849989 +253 230 0.0078555979 +270 230 0.00022769999 +277 230 0.00056919991 +282 230 0.00017079999 +285 230 5.6899997e-05 +287 230 0.00011379999 +290 230 0.00011379999 +293 230 5.6899997e-05 +294 230 5.6899997e-05 +295 230 0.00017079999 +296 230 0.00011379999 +300 230 0.06330049 +301 230 0.0033586 +307 230 5.6899997e-05 +312 230 5.6899997e-05 +314 230 0.0046677999 +315 230 0.0096202977 +319 230 5.6899997e-05 +322 230 5.6899997e-05 +324 230 0.0031309 +325 230 0.00034149992 +326 230 0.0038139999 +349 230 0.00022769999 +350 230 0.00028459984 +352 230 5.6899997e-05 +356 230 0.00017079999 +358 230 0.00045539998 +368 230 5.6899997e-05 +371 230 5.6899997e-05 +372 230 0.00017079999 +386 230 0.00011379999 +387 230 5.6899997e-05 +398 230 5.6899997e-05 +402 230 5.6899997e-05 +414 230 5.6899997e-05 +417 230 0.00011379999 +421 230 0.00011379999 +422 230 5.6899997e-05 +423 230 5.6899997e-05 +425 230 5.6899997e-05 +426 230 5.6899997e-05 +428 230 5.6899997e-05 +430 230 5.6899997e-05 +431 230 0.00017079999 +433 230 5.6899997e-05 +434 230 5.6899997e-05 +438 230 5.6899997e-05 +441 230 5.6899997e-05 +443 230 0.012466598 +444 230 0.0024477998 +445 230 0.011897299 +446 230 0.0021630998 +447 230 0.0043831989 +448 230 5.6899997e-05 +450 230 0.0027892999 +452 230 0.0042693987 +453 230 0.0026184998 +454 230 0.00085389987 +455 230 0.035236496 +456 230 0.00022769999 +457 230 0.0022769999 +458 230 0.00045539998 +459 230 0.00056919991 +460 230 0.0012522999 +463 230 0.059828099 +464 230 0.0014799999 +465 230 0.0039846972 +467 230 0.019752897 +468 230 0.11686689 +469 230 0.0059770979 +470 230 0.0056924969 +471 230 0.00062619988 +472 230 0.00051229983 +473 230 0.00011379999 +477 230 0.00062619988 +478 230 0.00062619988 +483 230 0.0012522999 +489 230 0.00011379999 +490 230 0.0020492999 +491 230 0.00034149992 +13 231 0.0003382999 +17 231 0.00016909999 +19 231 0.00050739991 +21 231 0.0018606 +22 231 0.0011839999 +23 231 0.025372099 +24 231 0.0015222998 +25 231 0.0020297999 +60 231 0.0049052984 +82 231 0.0035520999 +88 231 0.0006765998 +98 231 0.00016909999 +104 231 0.0003382999 +108 231 0.00016909999 +114 231 0.0003382999 +117 231 0.00016909999 +118 231 0.0037211999 +119 231 0.019790299 +120 231 0.0087956972 +122 231 0.0006765998 +126 231 0.00016909999 +130 231 0.00016909999 +159 231 0.00016909999 +160 231 0.00016909999 +186 231 0.0008456998 +192 231 0.00050739991 +193 231 0.0015222998 +194 231 0.00016909999 +198 231 0.015223298 +204 231 0.012347799 +206 231 0.00050739991 +214 231 0.14918804 +215 231 0.0010148999 +217 231 0.00050739991 +218 231 0.0013531998 +219 231 0.00016909999 +223 231 0.0529432 +224 231 0.0023681 +225 231 0.0008456998 +228 231 0.0003382999 +229 231 0.011332899 +230 231 0.00016909999 +231 231 0.0018606 +232 231 0.0006765998 +233 231 0.00050739991 +234 231 0.061400499 +240 231 0.00016909999 +241 231 0.027401898 +252 231 0.0003382999 +253 231 0.00016909999 +267 231 0.0003382999 +277 231 0.0013531998 +285 231 0.00050739991 +287 231 0.0015222998 +288 231 0.0003382999 +290 231 0.0006765998 +294 231 0.00016909999 +300 231 0.020466797 +301 231 0.019621097 +324 231 0.0003382999 +325 231 0.00016909999 +326 231 0.00016909999 +349 231 0.0023681 +350 231 0.0010148999 +356 231 0.00050739991 +358 231 0.00050739991 +366 231 0.00016909999 +375 231 0.00016909999 +387 231 0.00016909999 +414 231 0.00016909999 +417 231 0.00016909999 +443 231 0.0145467 +444 231 0.0011839999 +445 231 0.014884997 +446 231 0.0049052984 +447 231 0.0035520999 +448 231 0.0027063999 +450 231 0.0033828998 +452 231 0.010994598 +453 231 0.0091339983 +454 231 0.0016915 +455 231 0.038565598 +456 231 0.00016909999 +457 231 0.0028754999 +458 231 0.0003382999 +459 231 0.0010148999 +460 231 0.0013531998 +463 231 0.018606197 +464 231 0.0011839999 +465 231 0.0010148999 +467 231 0.0121786 +468 231 0.032137997 +469 231 0.0071041994 +470 231 0.0069349967 +471 231 0.0010148999 +473 231 0.00016909999 +477 231 0.0003382999 +478 231 0.00050739991 +483 231 0.0016915 +489 231 0.00050739991 +490 231 0.0013531998 +491 231 0.0013531998 +3 232 2.3399989e-05 +6 232 9.3399998e-05 +9 232 2.3399989e-05 +10 232 0.00011679999 +13 232 4.6699992e-05 +14 232 4.6699992e-05 +17 232 0.00030359998 +18 232 0.00011679999 +19 232 2.3399989e-05 +21 232 4.6699992e-05 +22 232 0.00016349999 +23 232 0.00037369994 +24 232 0.00014009999 +25 232 4.6699992e-05 +60 232 0.0019150998 +82 232 0.00030359998 +83 232 2.3399989e-05 +84 232 2.3399989e-05 +85 232 2.3399989e-05 +88 232 2.3399989e-05 +93 232 4.6699992e-05 +102 232 0.00016349999 +104 232 0.00011679999 +107 232 0.00091089983 +108 232 0.0001868 +109 232 9.3399998e-05 +113 232 7.0099995e-05 +114 232 9.3399998e-05 +115 232 2.3399989e-05 +116 232 0.00030359998 +117 232 2.3399989e-05 +118 232 2.3399989e-05 +119 232 0.0009341999 +120 232 0.0034098998 +125 232 2.3399989e-05 +126 232 7.0099995e-05 +127 232 2.3399989e-05 +130 232 0.00028029992 +131 232 0.0002102 +133 232 2.3399989e-05 +135 232 2.3399989e-05 +138 232 0.00014009999 +139 232 7.0099995e-05 +142 232 0.00014009999 +149 232 2.3399989e-05 +151 232 4.6699992e-05 +158 232 0.0009341999 +160 232 4.6699992e-05 +186 232 2.3399989e-05 +187 232 0.0021954 +188 232 4.6699992e-05 +189 232 4.6699992e-05 +190 232 4.6699992e-05 +192 232 0.0024522999 +193 232 0.00046709995 +194 232 0.00011679999 +197 232 2.3399989e-05 +198 232 0.033070996 +200 232 4.6699992e-05 +202 232 4.6699992e-05 +203 232 4.6699992e-05 +204 232 0.00058389991 +206 232 0.00051379995 +207 232 4.6699992e-05 +209 232 2.3399989e-05 +214 232 0.036364097 +215 232 2.3399989e-05 +217 232 0.00011679999 +218 232 7.0099995e-05 +223 232 0.007964097 +224 232 0.0009808999 +228 232 0.0036201 +229 232 0.0023355 +230 232 0.00028029992 +231 232 0.0074736997 +232 232 0.024733197 +233 232 0.00065389997 +234 232 0.0033397998 +237 232 9.3399998e-05 +240 232 0.0002102 +241 232 0.061050497 +242 232 2.3399989e-05 +248 232 2.3399989e-05 +250 232 9.3399998e-05 +252 232 0.00088749989 +253 232 0.026204497 +270 232 0.00011679999 +271 232 7.0099995e-05 +273 232 0.00074739987 +276 232 4.6699992e-05 +277 232 0.00030359998 +282 232 4.6699992e-05 +285 232 2.3399989e-05 +287 232 4.6699992e-05 +290 232 0.0012844999 +293 232 7.0099995e-05 +294 232 0.00037369994 +296 232 2.3399989e-05 +300 232 0.036340699 +301 232 0.00028029992 +312 232 0.0001868 +314 232 0.0039936975 +315 232 0.0019385 +319 232 2.3399989e-05 +320 232 2.3399989e-05 +324 232 0.0010742999 +325 232 0.0009341999 +326 232 0.0096456967 +340 232 0.00056049996 +349 232 7.0099995e-05 +350 232 0.00014009999 +356 232 0.00011679999 +358 232 0.00037369994 +372 232 2.3399989e-05 +384 232 2.3399989e-05 +387 232 7.0099995e-05 +393 232 0.00011679999 +402 232 2.3399989e-05 +414 232 0.00063059991 +416 232 0.00025689998 +417 232 0.00028029992 +419 232 4.6699992e-05 +421 232 4.6699992e-05 +422 232 9.3399998e-05 +423 232 7.0099995e-05 +424 232 0.00072399992 +425 232 4.6699992e-05 +426 232 2.3399989e-05 +428 232 2.3399989e-05 +430 232 2.3399989e-05 +431 232 7.0099995e-05 +432 232 2.3399989e-05 +433 232 2.3399989e-05 +434 232 4.6699992e-05 +438 232 0.0005371999 +441 232 2.3399989e-05 +442 232 2.3399989e-05 +443 232 0.0034098998 +444 232 0.0037602 +445 232 0.0071699992 +446 232 0.00074739987 +447 232 0.0159049 +448 232 4.6699992e-05 +450 232 0.0027325999 +452 232 0.0025223999 +453 232 0.00065389997 +454 232 0.00067729992 +455 232 0.0275358 +456 232 0.00035029999 +457 232 0.0024522999 +458 232 0.00042039994 +459 232 0.00060719997 +460 232 0.0014479998 +463 232 0.023401897 +464 232 0.0024756999 +465 232 0.011140399 +467 232 0.032300297 +468 232 0.20006067 +469 232 0.010673299 +470 232 0.006235797 +471 232 0.00079409988 +472 232 2.3399989e-05 +473 232 0.00011679999 +477 232 0.00063059991 +478 232 0.00074739987 +479 232 2.3399989e-05 +483 232 0.0015180998 +489 232 2.3399989e-05 +490 232 0.0009808999 +491 232 0.00042039994 +9 233 2.8099996e-05 +13 233 2.8099996e-05 +14 233 0.0054736994 +16 233 2.8099996e-05 +17 233 0.0037052999 +18 233 8.4199986e-05 +19 233 0.00047719991 +21 233 0.0019929998 +22 233 8.4199986e-05 +23 233 0.0012069999 +24 233 0.0024981999 +25 233 5.6099991e-05 +60 233 0.0028350998 +79 233 2.8099996e-05 +82 233 0.0001123 +83 233 2.8099996e-05 +84 233 2.8099996e-05 +104 233 2.8099996e-05 +108 233 2.8099996e-05 +113 233 8.4199986e-05 +114 233 0.00014039999 +118 233 0.015101798 +119 233 0.0069052987 +120 233 0.00022459999 +126 233 8.4199986e-05 +127 233 2.8099996e-05 +130 233 2.8099996e-05 +135 233 2.8099996e-05 +150 233 2.8099996e-05 +151 233 2.8099996e-05 +159 233 0.0001123 +160 233 0.00016839999 +169 233 2.8099996e-05 +187 233 0.00053329999 +188 233 0.00022459999 +189 233 0.00014039999 +190 233 5.6099991e-05 +191 233 0.0001123 +192 233 0.00014039999 +193 233 0.0012631998 +194 233 0.0001123 +196 233 2.8099996e-05 +197 233 2.8099996e-05 +198 233 0.0085052997 +200 233 5.6099991e-05 +201 233 5.6099991e-05 +203 233 8.4199986e-05 +204 233 0.0064841993 +206 233 0.00047719991 +207 233 5.6099991e-05 +208 233 0.0011788998 +209 233 2.8099996e-05 +214 233 0.19489115 +215 233 2.8099996e-05 +218 233 0.0030315998 +219 233 5.6099991e-05 +222 233 0.0012631998 +223 233 0.0058385991 +224 233 0.087663174 +225 233 0.0023578999 +226 233 0.00016839999 +227 233 0.0029473999 +229 233 0.0016841998 +230 233 8.4199986e-05 +231 233 0.00064559979 +232 233 8.4199986e-05 +233 233 0.0099648982 +234 233 0.014877196 +237 233 0.0001965 +240 233 8.4199986e-05 +241 233 0.0028350998 +242 233 2.8099996e-05 +248 233 2.8099996e-05 +250 233 2.8099996e-05 +252 233 0.00078599993 +253 233 0.00030879979 +266 233 2.8099996e-05 +267 233 2.8099996e-05 +273 233 0.0052210987 +277 233 0.00022459999 +284 233 5.6099991e-05 +285 233 0.0013754 +287 233 0.0067648999 +288 233 0.0013754 +289 233 8.4199986e-05 +290 233 0.0025825 +293 233 0.00016839999 +300 233 0.045192998 +301 233 0.0104982 +314 233 2.8099996e-05 +315 233 0.00039299997 +319 233 5.6099991e-05 +322 233 2.8099996e-05 +324 233 0.00056139985 +326 233 0.0030595998 +332 233 2.8099996e-05 +349 233 5.6099991e-05 +350 233 8.4199986e-05 +356 233 5.6099991e-05 +358 233 0.00022459999 +384 233 5.6099991e-05 +387 233 5.6099991e-05 +402 233 5.6099991e-05 +414 233 0.00025259983 +417 233 0.00014039999 +419 233 2.8099996e-05 +421 233 5.6099991e-05 +422 233 0.0001123 +423 233 2.8099996e-05 +425 233 2.8099996e-05 +430 233 2.8099996e-05 +431 233 2.8099996e-05 +432 233 2.8099996e-05 +433 233 5.6099991e-05 +434 233 5.6099991e-05 +442 233 0.0018806998 +443 233 0.010806996 +444 233 0.0028350998 +445 233 0.011059597 +446 233 0.0019929998 +447 233 0.010919299 +448 233 8.4199986e-05 +450 233 0.0054174997 +452 233 0.0045473985 +453 233 0.0019648999 +454 233 0.00053329999 +455 233 0.033459596 +456 233 0.00047719991 +457 233 0.0031999999 +458 233 0.00039299997 +459 233 0.00039299997 +460 233 0.0014876998 +463 233 0.029585999 +464 233 0.0020772 +465 233 0.0066525973 +467 233 0.0118737 +468 233 0.0168982 +469 233 0.0056701973 +470 233 0.007719297 +471 233 0.0021052998 +473 233 0.00014039999 +477 233 0.00042109983 +478 233 0.00084209978 +483 233 0.0018245999 +489 233 2.8099996e-05 +490 233 0.0019087999 +491 233 0.00047719991 +9 234 1.0399999e-05 +16 234 3.4999994e-06 +18 234 4.1599997e-05 +19 234 3.4999994e-06 +21 234 2.0799998e-05 +22 234 0.00087069999 +23 234 0.49135369 +24 234 1.0399999e-05 +25 234 2.4299996e-05 +60 234 0.017792199 +66 234 3.4999994e-06 +74 234 0.0010753998 +79 234 3.4999994e-06 +82 234 0.0001145 +83 234 6.8999998e-06 +84 234 6.8999998e-06 +104 234 3.4999994e-06 +108 234 1.0399999e-05 +113 234 2.0799998e-05 +114 234 5.1999989e-05 +117 234 0.00012839999 +118 234 0.0002081 +119 234 0.0001908 +120 234 0.00039199996 +122 234 2.0799998e-05 +126 234 2.0799998e-05 +127 234 3.4999994e-06 +135 234 3.4999994e-06 +150 234 5.8999998e-05 +151 234 3.4999994e-06 +160 234 3.4699988e-05 +186 234 3.4999994e-06 +189 234 4.1599997e-05 +190 234 1.3899999e-05 +191 234 4.1599997e-05 +192 234 2.4299996e-05 +194 234 1.3899999e-05 +196 234 3.4999994e-06 +197 234 3.4999994e-06 +198 234 0.0029451 +200 234 1.3899999e-05 +201 234 1.0399999e-05 +203 234 1.0399999e-05 +204 234 2.4299996e-05 +206 234 1.3899999e-05 +207 234 1.0399999e-05 +209 234 1.7299986e-05 +214 234 0.023873199 +215 234 6.8999998e-06 +218 234 4.5099994e-05 +223 234 0.0035660998 +224 234 3.4999994e-06 +229 234 3.4999994e-06 +230 234 6.8999998e-06 +231 234 0.0029936999 +232 234 3.4999994e-06 +233 234 2.0799998e-05 +234 234 0.064313948 +235 234 6.8999998e-06 +237 234 9.0199988e-05 +241 234 0.00074929977 +242 234 5.1999989e-05 +248 234 6.8999998e-06 +250 234 3.4999994e-06 +251 234 2.0799998e-05 +252 234 6.939999e-05 +253 234 1.0399999e-05 +254 234 3.4999994e-06 +263 234 3.4999994e-06 +267 234 0.00010059999 +272 234 0.00072499993 +273 234 6.2399995e-05 +277 234 0.00048909988 +279 234 6.8999998e-06 +281 234 6.8999998e-06 +285 234 3.4999994e-06 +287 234 1.0399999e-05 +289 234 3.119999e-05 +290 234 0.0015262999 +294 234 6.8999998e-06 +300 234 0.0038053999 +301 234 0.0047523975 +307 234 2.7799993e-05 +315 234 3.4999994e-06 +317 234 3.4999994e-06 +319 234 6.8999998e-06 +324 234 0.0002462999 +326 234 0.0014118999 +328 234 7.2799987e-05 +331 234 1.7299986e-05 +333 234 0.00017689999 +334 234 6.8999998e-06 +337 234 3.4999994e-06 +340 234 1.0399999e-05 +349 234 1.3899999e-05 +350 234 0.0010302998 +351 234 0.00029139989 +354 234 3.119999e-05 +356 234 0.00017689999 +358 234 0.00031909999 +369 234 6.8999998e-06 +370 234 1.3899999e-05 +372 234 0.00014919999 +374 234 2.7799993e-05 +380 234 3.4999994e-06 +384 234 7.9799996e-05 +385 234 6.8999998e-06 +386 234 3.4999994e-06 +387 234 2.0799998e-05 +390 234 3.4999994e-06 +394 234 6.8999998e-06 +397 234 6.8999998e-06 +402 234 4.1599997e-05 +404 234 1.7299986e-05 +414 234 0.00042319996 +417 234 3.4699988e-05 +419 234 3.4999994e-06 +421 234 1.7299986e-05 +422 234 2.7799993e-05 +423 234 3.4999994e-06 +425 234 3.4999994e-06 +430 234 1.0399999e-05 +431 234 6.8999998e-06 +432 234 3.4999994e-06 +433 234 6.8999998e-06 +434 234 6.8999998e-06 +441 234 8.6699991e-05 +442 234 6.8999998e-06 +443 234 0.0035903 +444 234 7.6299999e-05 +445 234 0.0046101995 +446 234 0.0086861998 +447 234 0.0020015999 +448 234 0.033485599 +449 234 3.4999994e-06 +450 234 0.0018177 +452 234 0.0066880994 +453 234 0.012245297 +454 234 0.0013979999 +455 234 0.0072083995 +456 234 0.0002462999 +457 234 0.0045477971 +458 234 0.00017689999 +459 234 0.00058619981 +460 234 0.0011377998 +463 234 0.013358898 +464 234 9.3699986e-05 +465 234 0.00017689999 +467 234 0.0081554987 +468 234 0.0116001 +469 234 0.0021402999 +470 234 0.0023067999 +471 234 0.00060359994 +472 234 6.5899992e-05 +473 234 4.8599992e-05 +477 234 0.0001318 +478 234 0.0001943 +483 234 0.00077009993 +489 234 0.00041279988 +490 234 0.00018389999 +18 235 0.00021619999 +22 235 0.0057284981 +23 235 0.00043229992 +24 235 0.085170746 +25 235 0.00010809999 +60 235 0.0023778998 +114 235 0.00010809999 +126 235 0.00010809999 +135 235 0.00010809999 +160 235 0.00010809999 +171 235 0.0048637986 +191 235 0.00097279996 +192 235 0.0064850971 +193 235 0.00021619999 +194 235 0.00010809999 +198 235 0.0033505999 +203 235 0.00010809999 +206 235 0.00021619999 +214 235 0.00043229992 +215 235 0.00010809999 +218 235 0.00010809999 +220 235 0.00043229992 +223 235 0.00010809999 +231 235 0.013078298 +233 235 0.0014050999 +234 235 0.21379155 +235 235 0.011565097 +237 235 0.00086469995 +241 235 0.020103797 +242 235 0.00010809999 +252 235 0.00021619999 +254 235 0.0073497966 +264 235 0.00021619999 +266 235 0.00010809999 +269 235 0.00021619999 +272 235 0.0011888999 +273 235 0.0069173984 +277 235 0.0016212999 +279 235 0.00010809999 +282 235 0.00043229992 +295 235 0.00010809999 +300 235 0.0029183 +301 235 0.0042152964 +305 235 0.00010809999 +312 235 0.00010809999 +317 235 0.00010809999 +322 235 0.00043229992 +326 235 0.0036748999 +328 235 0.00054039992 +331 235 0.00097279996 +332 235 0.00086469995 +335 235 0.00021619999 +336 235 0.00010809999 +337 235 0.00010809999 +340 235 0.00021619999 +351 235 0.00010809999 +354 235 0.00010809999 +356 235 0.00010809999 +358 235 0.00064849993 +372 235 0.00010809999 +402 235 0.00064849993 +417 235 0.00010809999 +421 235 0.00021619999 +422 235 0.00010809999 +434 235 0.00010809999 +442 235 0.00010809999 +443 235 0.011889298 +444 235 0.0019454998 +445 235 0.070146978 +446 235 0.0070254989 +447 235 0.0033505999 +448 235 0.00021619999 +450 235 0.0022697998 +452 235 0.012105498 +453 235 0.0088628978 +454 235 0.00075659994 +455 235 0.033073898 +456 235 0.00054039992 +457 235 0.0030264 +458 235 0.0014050999 +459 235 0.00054039992 +460 235 0.0022697998 +463 235 0.0155642 +464 235 0.00054039992 +465 235 0.00021619999 +467 235 0.010808498 +468 235 0.0056203976 +469 235 0.0021616998 +470 235 0.0019454998 +471 235 0.0041071996 +473 235 0.00010809999 +477 235 0.00010809999 +478 235 0.00064849993 +483 235 0.00064849993 +489 235 0.00010809999 +490 235 0.00021619999 +491 235 0.00021619999 +18 236 0.0002194 +22 236 0.0038389999 +23 236 0.0015355998 +24 236 0.0085553974 +25 236 0.00010969999 +60 236 0.0023033998 +114 236 0.00010969999 +117 236 0.0042776987 +118 236 0.0036195999 +119 236 0.0037292999 +126 236 0.00010969999 +130 236 0.00010969999 +135 236 0.010749098 +171 236 0.00010969999 +189 236 0.00010969999 +190 236 0.00010969999 +191 236 0.084347844 +192 236 0.0039486997 +194 236 0.00010969999 +198 236 0.013162199 +203 236 0.00010969999 +206 236 0.0002194 +214 236 0.0063616969 +218 236 0.00010969999 +224 236 0.0026323998 +225 236 0.00010969999 +231 236 0.0002194 +233 236 0.0014258998 +234 236 0.15761757 +235 236 0.0010968999 +237 236 0.00065809977 +241 236 0.0084457994 +252 236 0.0002194 +264 236 0.00032909983 +267 236 0.0019742998 +269 236 0.0002194 +272 236 0.00043869996 +273 236 0.055062 +277 236 0.0028517998 +279 236 0.00010969999 +300 236 0.0043873973 +301 236 0.0106395 +315 236 0.00010969999 +317 236 0.00010969999 +326 236 0.0002194 +334 236 0.0002194 +340 236 0.0002194 +349 236 0.00010969999 +356 236 0.00010969999 +358 236 0.00076779979 +402 236 0.00032909983 +417 236 0.00010969999 +421 236 0.0002194 +422 236 0.0042776987 +434 236 0.00010969999 +443 236 0.040912598 +444 236 0.0028517998 +445 236 0.044203099 +446 236 0.0049357973 +447 236 0.0031808999 +448 236 0.0002194 +450 236 0.0025227999 +452 236 0.0062520988 +453 236 0.0084457994 +454 236 0.0017549999 +455 236 0.047932398 +456 236 0.00076779979 +457 236 0.0029614998 +458 236 0.0013161998 +459 236 0.00010969999 +460 236 0.0018646 +463 236 0.0065810978 +464 236 0.00032909983 +465 236 0.00043869996 +467 236 0.0086650997 +468 236 0.0043873973 +469 236 0.0019742998 +470 236 0.0020839998 +471 236 0.0040583983 +473 236 0.00010969999 +477 236 0.00010969999 +478 236 0.00065809977 +483 236 0.00098719983 +489 236 0.00010969999 +490 236 0.0002194 +491 236 0.00032909983 +9 237 1.7499988e-05 +18 237 0.00068069994 +22 237 0.00078539993 +24 237 0.0018151999 +25 237 0.0031241998 +60 237 0.0055676997 +79 237 1.7499988e-05 +82 237 1.7499988e-05 +83 237 1.7499988e-05 +84 237 1.7499988e-05 +108 237 1.7499988e-05 +113 237 5.2399992e-05 +114 237 8.7299995e-05 +126 237 5.2399992e-05 +127 237 1.7499988e-05 +130 237 0.0065799989 +131 237 1.7499988e-05 +140 237 0.10304558 +150 237 0.0003839999 +151 237 0.00034909998 +160 237 0.00017449999 +189 237 5.2399992e-05 +190 237 5.2399992e-05 +192 237 5.2399992e-05 +193 237 0.00099489978 +194 237 6.9799993e-05 +198 237 0.0011518998 +200 237 3.4899989e-05 +201 237 1.7499988e-05 +203 237 6.9799993e-05 +204 237 3.4899989e-05 +206 237 6.9799993e-05 +207 237 3.4899989e-05 +214 237 0.030456398 +222 237 0.022794299 +223 237 0.0019373 +224 237 0.0021292998 +225 237 0.10222524 +234 237 0.0021467998 +237 237 0.0002269 +239 237 0.0060912967 +240 237 0.0051661991 +241 237 0.0094772987 +248 237 1.7499988e-05 +250 237 1.7499988e-05 +251 237 1.7499988e-05 +252 237 0.0001222 +272 237 0.00094249984 +277 237 0.010314997 +282 237 3.4899989e-05 +284 237 3.4899989e-05 +288 237 1.7499988e-05 +312 237 1.7499988e-05 +315 237 3.4899989e-05 +319 237 0.00048869988 +326 237 1.7499988e-05 +349 237 1.7499988e-05 +350 237 0.00095989997 +356 237 0.00024429988 +358 237 0.00095989997 +384 237 3.4899989e-05 +387 237 3.4899989e-05 +402 237 0.0035430999 +404 237 6.9799993e-05 +414 237 0.00047119986 +417 237 0.00027929991 +419 237 1.7499988e-05 +421 237 3.4899989e-05 +422 237 6.9799993e-05 +423 237 1.7499988e-05 +425 237 1.7499988e-05 +430 237 3.4899989e-05 +431 237 1.7499988e-05 +432 237 1.7499988e-05 +433 237 3.4899989e-05 +434 237 3.4899989e-05 +443 237 0.0091979988 +444 237 0.0014312 +445 237 0.011938199 +446 237 0.0023910999 +447 237 0.0065450966 +448 237 1.7499988e-05 +450 237 0.0028275 +452 237 0.0078191981 +453 237 0.0026528998 +454 237 0.0013438999 +455 237 0.018134199 +456 237 0.0002617999 +457 237 0.0046425983 +458 237 6.9799993e-05 +459 237 0.0020420998 +460 237 0.001309 +463 237 0.0075049996 +464 237 0.0011169999 +465 237 0.0037175999 +467 237 0.015900198 +468 237 0.027297299 +469 237 0.0041538998 +470 237 0.0045029968 +471 237 0.0021990999 +473 237 8.7299995e-05 +477 237 0.00061089988 +478 237 0.00069809984 +483 237 0.00085519999 +489 237 5.2399992e-05 +490 237 0.024469797 +491 237 0.00041889981 +24 238 0.0001967 +60 238 0.0017698999 +108 238 0.0001967 +114 238 0.00039329985 +126 238 0.0001967 +130 238 0.075909495 +131 238 0.0078662969 +133 238 0.012192696 +149 238 0.0019665998 +150 238 0.0001967 +171 238 0.018092398 +187 238 0.0001967 +189 238 0.0001967 +190 238 0.0001967 +192 238 0.012389399 +194 238 0.00039329985 +198 238 0.024778798 +200 238 0.0001967 +203 238 0.0001967 +204 238 0.0001967 +206 238 0.00039329985 +214 238 0.017895799 +219 238 0.0070795976 +222 238 0.010816097 +224 238 0.0330383 +225 238 0.019075699 +233 238 0.0031464999 +234 238 0.0043265 +238 238 0.00098329992 +239 238 0.0001967 +240 238 0.0214356 +241 238 0.027925298 +252 238 0.00039329985 +270 238 0.0041297972 +272 238 0.00078659994 +277 238 0.0001967 +340 238 0.00039329985 +358 238 0.0031464999 +387 238 0.0001967 +417 238 0.00098329992 +421 238 0.0001967 +422 238 0.00039329985 +437 238 0.0088495985 +443 238 0.0045230985 +444 238 0.0047197975 +445 238 0.0090461969 +446 238 0.00098329992 +447 238 0.010226198 +450 238 0.0060963966 +452 238 0.0076695979 +453 238 0.00078659994 +454 238 0.0011798998 +455 238 0.026745297 +456 238 0.00039329985 +457 238 0.0033431998 +458 238 0.00098329992 +459 238 0.00058999984 +460 238 0.0011798998 +463 238 0.0078662969 +464 238 0.00078659994 +465 238 0.0019665998 +467 238 0.016322497 +468 238 0.021632299 +469 238 0.0074729994 +470 238 0.0082595982 +471 238 0.0011798998 +473 238 0.0001967 +477 238 0.0001967 +478 238 0.0021631999 +483 238 0.0019665998 +490 238 0.0104228 +21 239 0.0019607998 +22 239 0.0039215982 +25 239 0.0019607998 +60 239 0.0058823973 +130 239 0.0019607998 +140 239 0.0156863 +192 239 0.0019607998 +198 239 0.0019607998 +214 239 0.060784299 +215 239 0.0019607998 +218 239 0.0078430995 +222 239 0.0039215982 +224 239 0.0039215982 +225 239 0.021568596 +233 239 0.0019607998 +234 239 0.031372499 +236 239 0.0019607998 +239 239 0.074509799 +240 239 0.0156863 +241 239 0.0058823973 +277 239 0.0039215982 +287 239 0.0019607998 +334 239 0.0019607998 +340 239 0.0019607998 +349 239 0.0019607998 +350 239 0.0019607998 +443 239 0.013725497 +444 239 0.0019607998 +445 239 0.023529399 +446 239 0.0039215982 +447 239 0.0039215982 +450 239 0.0019607998 +452 239 0.033333298 +453 239 0.0098038986 +455 239 0.031372499 +457 239 0.0019607998 +463 239 0.0058823973 +464 239 0.0019607998 +467 239 0.0156863 +468 239 0.0078430995 +469 239 0.0058823973 +470 239 0.0058823973 +490 239 0.0078430995 +491 239 0.019607797 +0 240 0.00046659983 +4 240 0.00015549999 +9 240 3.8899991e-05 +18 240 0.00011659999 +21 240 0.0001944 +22 240 0.001283 +24 240 0.00093309977 +25 240 7.7799996e-05 +60 240 0.0031103999 +79 240 3.8899991e-05 +82 240 0.00011659999 +83 240 3.8899991e-05 +84 240 3.8899991e-05 +88 240 0.00015549999 +90 240 0.00011659999 +104 240 7.7799996e-05 +108 240 3.8899991e-05 +113 240 7.7799996e-05 +114 240 0.00015549999 +115 240 3.8899991e-05 +117 240 3.8899991e-05 +126 240 7.7799996e-05 +127 240 3.8899991e-05 +130 240 0.028887998 +131 240 0.0039268993 +132 240 0.00050539989 +133 240 0.00046659983 +135 240 0.0001944 +138 240 0.00031099981 +139 240 0.0001944 +140 240 0.0059486963 +142 240 0.00042769988 +143 240 0.00034989999 +149 240 0.00050539989 +150 240 0.00077759987 +151 240 3.8899991e-05 +152 240 3.8899991e-05 +157 240 3.8899991e-05 +158 240 0.00015549999 +160 240 0.00077759987 +161 240 3.8899991e-05 +165 240 3.8899991e-05 +169 240 0.00093309977 +171 240 0.00077759987 +186 240 7.7799996e-05 +187 240 0.0018273999 +188 240 0.0013218999 +189 240 0.00015549999 +190 240 0.00011659999 +191 240 0.00042769988 +192 240 0.0012053 +193 240 7.7799996e-05 +194 240 0.00023329999 +197 240 0.00023329999 +198 240 0.013685796 +200 240 7.7799996e-05 +201 240 3.8899991e-05 +203 240 7.7799996e-05 +204 240 0.00081649981 +206 240 0.00015549999 +207 240 7.7799996e-05 +209 240 3.8899991e-05 +214 240 0.053887997 +218 240 0.00023329999 +219 240 0.001283 +221 240 3.8899991e-05 +222 240 0.0059486963 +223 240 0.0026826998 +224 240 0.015435498 +225 240 0.077293873 +226 240 0.00038879993 +227 240 0.0024883 +228 240 7.7799996e-05 +233 240 0.00023329999 +234 240 0.0036546998 +237 240 7.7799996e-05 +239 240 0.0020607 +240 240 0.028188199 +241 240 0.031765196 +242 240 3.8899991e-05 +243 240 0.00062209996 +248 240 3.8899991e-05 +250 240 3.8899991e-05 +251 240 3.8899991e-05 +252 240 0.00050539989 +254 240 3.8899991e-05 +270 240 3.8899991e-05 +271 240 0.00011659999 +272 240 3.8899991e-05 +273 240 0.00062209996 +274 240 7.7799996e-05 +276 240 0.0020994998 +277 240 0.0088257976 +282 240 0.0096422993 +283 240 0.0001944 +284 240 7.7799996e-05 +292 240 7.7799996e-05 +293 240 0.00011659999 +296 240 7.7799996e-05 +300 240 0.0001944 +312 240 0.00015549999 +313 240 3.8899991e-05 +315 240 0.011003099 +319 240 0.0020994998 +322 240 0.00046659983 +324 240 3.8899991e-05 +326 240 0.0027604999 +340 240 0.0020607 +345 240 7.7799996e-05 +348 240 7.7799996e-05 +349 240 0.0026049998 +350 240 7.7799996e-05 +351 240 7.7799996e-05 +354 240 3.8899991e-05 +356 240 0.00027219998 +357 240 3.8899991e-05 +358 240 0.0020217998 +372 240 7.7799996e-05 +384 240 7.7799996e-05 +385 240 3.8899991e-05 +387 240 7.7799996e-05 +393 240 3.8899991e-05 +402 240 0.00027219998 +414 240 0.00093309977 +416 240 3.8899991e-05 +417 240 0.00058319978 +419 240 3.8899991e-05 +421 240 7.7799996e-05 +422 240 0.0001944 +423 240 3.8899991e-05 +425 240 3.8899991e-05 +430 240 0.00042769988 +431 240 3.8899991e-05 +432 240 3.8899991e-05 +433 240 3.8899991e-05 +434 240 0.00011659999 +437 240 3.8899991e-05 +442 240 0.00015549999 +443 240 0.0079315975 +444 240 0.0033437 +445 240 0.0087480992 +446 240 0.0019828998 +447 240 0.0077759996 +448 240 3.8899991e-05 +450 240 0.0037324999 +452 240 0.01007 +453 240 0.0033825999 +454 240 0.0013218999 +455 240 0.0315708 +456 240 0.00038879993 +457 240 0.0033047998 +458 240 0.00050539989 +459 240 0.00062209996 +460 240 0.0014385998 +463 240 0.0071539991 +464 240 0.0023327998 +465 240 0.0023716998 +467 240 0.0146579 +468 240 0.016990699 +469 240 0.0063374974 +470 240 0.0069595985 +471 240 0.00089419982 +473 240 0.00015549999 +477 240 0.00015549999 +478 240 0.0013218999 +479 240 0.00011659999 +483 240 0.0019439999 +489 240 0.00011659999 +490 240 0.0183126 +491 240 0.0027215998 +0 241 4.4299988e-05 +2 241 0.00027469988 +4 241 6.1999992e-05 +9 241 8.8999996e-06 +13 241 7.9799996e-05 +16 241 8.8999996e-06 +18 241 0.00013289999 +19 241 1.7699989e-05 +21 241 3.5399993e-05 +22 241 0.00024809991 +23 241 0.00058489991 +24 241 0.00026589981 +25 241 1.7699989e-05 +60 241 0.0055033974 +77 241 1.7699989e-05 +79 241 8.8999996e-06 +82 241 0.00016839999 +83 241 1.7699989e-05 +84 241 1.7699989e-05 +90 241 8.8999996e-06 +104 241 5.3199998e-05 +107 241 2.6599999e-05 +108 241 2.6599999e-05 +110 241 3.5399993e-05 +113 241 3.5399993e-05 +114 241 7.0899987e-05 +116 241 2.6599999e-05 +118 241 0.0002216 +119 241 9.7499986e-05 +120 241 7.0899987e-05 +126 241 3.5399993e-05 +127 241 8.8999996e-06 +130 241 0.012008198 +131 241 0.0015419999 +132 241 0.00021269999 +133 241 0.0001241 +135 241 1.7699989e-05 +137 241 8.8999996e-06 +138 241 3.5399993e-05 +139 241 0.00027469988 +140 241 9.7499986e-05 +141 241 8.8999996e-06 +142 241 0.00014179999 +143 241 0.0001507 +149 241 0.00025699986 +150 241 0.0010279999 +151 241 2.6599999e-05 +152 241 0.0001772 +157 241 8.8999996e-06 +158 241 9.7499986e-05 +159 241 0.0001772 +160 241 0.00074439985 +161 241 0.00052289991 +162 241 2.6599999e-05 +165 241 0.0001507 +169 241 0.00068239984 +170 241 0.00046079978 +171 241 0.0037486998 +172 241 2.6599999e-05 +181 241 8.8999996e-06 +184 241 5.3199998e-05 +186 241 0.0001241 +187 241 0.0040853992 +188 241 0.0011254998 +189 241 4.4299988e-05 +190 241 9.7499986e-05 +191 241 7.0899987e-05 +192 241 0.0019673998 +193 241 0.0015065998 +194 241 0.0067705996 +196 241 8.8999996e-06 +197 241 0.001799 +198 241 0.021012098 +200 241 5.3199998e-05 +201 241 2.6599999e-05 +203 241 6.1999992e-05 +204 241 0.00027469988 +206 241 0.0001507 +207 241 4.4299988e-05 +209 241 3.5399993e-05 +212 241 8.8999996e-06 +214 241 0.041448098 +215 241 0.00035449979 +218 241 0.0001507 +219 241 0.00084189977 +221 241 0.00068239984 +222 241 0.00011519999 +223 241 0.00071779988 +224 241 0.15698326 +225 241 0.0032612998 +226 241 0.00020379999 +227 241 0.0010988999 +228 241 3.5399993e-05 +229 241 0.00047859992 +230 241 2.6599999e-05 +231 241 8.8599991e-05 +232 241 4.4299988e-05 +233 241 0.0021888998 +234 241 0.0034385 +237 241 0.00010629999 +239 241 4.4299988e-05 +240 241 0.0023749999 +241 241 0.046685599 +242 241 1.7699989e-05 +243 241 7.0899987e-05 +248 241 1.7699989e-05 +250 241 1.7699989e-05 +251 241 1.7699989e-05 +252 241 0.0075504966 +253 241 5.3199998e-05 +254 241 2.6599999e-05 +262 241 1.7699989e-05 +263 241 8.8999996e-06 +269 241 8.8999996e-06 +270 241 0.00024809991 +271 241 0.0003101998 +272 241 8.8999996e-06 +273 241 0.00042539998 +274 241 0.0016128998 +276 241 7.9799996e-05 +277 241 0.0040322989 +282 241 0.00080649997 +283 241 6.1999992e-05 +284 241 4.4299988e-05 +285 241 4.4299988e-05 +286 241 0.00018609999 +287 241 3.5399993e-05 +288 241 0.00033679977 +289 241 0.00019499999 +290 241 0.00021269999 +292 241 0.0011342999 +293 241 0.0014356999 +294 241 0.00013289999 +295 241 0.00018609999 +296 241 0.00010629999 +297 241 7.9799996e-05 +298 241 6.1999992e-05 +299 241 2.6599999e-05 +300 241 0.00013289999 +301 241 0.0001772 +305 241 8.8999996e-06 +307 241 2.6599999e-05 +312 241 0.00066469982 +313 241 8.8999996e-06 +314 241 3.5399993e-05 +315 241 0.0099520981 +317 241 0.00042539998 +319 241 0.0017014998 +320 241 9.7499986e-05 +321 241 5.3199998e-05 +322 241 0.0029687998 +324 241 7.9799996e-05 +325 241 0.00094819977 +326 241 0.0083126985 +328 241 0.00010629999 +330 241 8.8999996e-06 +335 241 7.9799996e-05 +336 241 8.8599991e-05 +338 241 2.6599999e-05 +340 241 0.0061768964 +341 241 8.8999996e-06 +344 241 8.8999996e-06 +345 241 2.6599999e-05 +347 241 3.5399993e-05 +348 241 0.00060259993 +349 241 0.0035979999 +350 241 8.8599991e-05 +351 241 5.3199998e-05 +352 241 8.8999996e-06 +353 241 8.8999996e-06 +354 241 5.3199998e-05 +355 241 8.8999996e-06 +356 241 0.00058489991 +357 241 1.7699989e-05 +358 241 0.003146 +363 241 8.8999996e-06 +366 241 8.8999996e-06 +369 241 8.8999996e-06 +370 241 5.3199998e-05 +371 241 2.6599999e-05 +372 241 9.7499986e-05 +373 241 2.6599999e-05 +376 241 8.8999996e-06 +380 241 1.7699989e-05 +384 241 2.6599999e-05 +385 241 0.0014799999 +386 241 0.00035449979 +387 241 2.6599999e-05 +390 241 6.1999992e-05 +392 241 0.0001241 +393 241 0.00024809991 +394 241 8.8999996e-06 +397 241 1.7699989e-05 +398 241 2.6599999e-05 +402 241 4.4299988e-05 +404 241 2.6599999e-05 +405 241 0.00023929999 +409 241 2.6599999e-05 +414 241 0.00074439985 +416 241 8.8999996e-06 +417 241 0.00050509977 +419 241 3.5399993e-05 +420 241 8.8999996e-06 +421 241 0.0001241 +422 241 0.0001241 +423 241 8.8999996e-06 +424 241 2.6599999e-05 +425 241 8.8999996e-06 +426 241 8.8999996e-06 +428 241 0.00023929999 +430 241 0.00035449979 +431 241 2.6599999e-05 +432 241 1.7699989e-05 +433 241 3.5399993e-05 +434 241 4.4299988e-05 +437 241 0.0004164998 +438 241 1.7699989e-05 +441 241 1.7699989e-05 +442 241 0.0015596999 +443 241 0.0089240968 +444 241 0.0048209988 +445 241 0.010873798 +446 241 0.0012496 +447 241 0.014968097 +448 241 6.1999992e-05 +449 241 8.8999996e-06 +450 241 0.0045107976 +452 241 0.012442399 +453 241 0.0037308999 +454 241 0.0012317998 +455 241 0.030441299 +456 241 0.00047859992 +457 241 0.0022952999 +458 241 0.00069119991 +459 241 0.0013116 +460 241 0.0013913999 +463 241 0.014223699 +464 241 0.0044753999 +465 241 0.0025699998 +467 241 0.0080467984 +468 241 0.0087822974 +469 241 0.0036334998 +470 241 0.0048032999 +471 241 0.0017547 +473 241 7.0899987e-05 +477 241 0.00053169997 +478 241 0.0011077998 +479 241 0.0016748998 +483 241 0.00069119991 +489 241 0.00010629999 +490 241 0.00062029995 +491 241 0.00093939994 +9 242 0.0001121 +22 242 0.00056059984 +24 242 0.0001121 +25 242 0.0001121 +60 242 0.0029151 +82 242 0.0001121 +108 242 0.0001121 +114 242 0.00022419999 +126 242 0.0001121 +130 242 0.066935778 +131 242 0.0077362992 +132 242 0.00022419999 +140 242 0.0076241978 +142 242 0.0001121 +156 242 0.0001121 +158 242 0.0001121 +160 242 0.0001121 +165 242 0.0001121 +171 242 0.0001121 +187 242 0.00022419999 +189 242 0.0001121 +190 242 0.0001121 +192 242 0.00056059984 +193 242 0.0001121 +194 242 0.00044849981 +197 242 0.0024665999 +198 242 0.0065029971 +200 242 0.0001121 +203 242 0.0001121 +204 242 0.0001121 +206 242 0.00022419999 +214 242 0.026908796 +222 242 0.0107635 +223 242 0.0011211999 +224 242 0.0244422 +225 242 0.072093248 +233 242 0.0001121 +234 242 0.0038120998 +237 242 0.0001121 +239 242 0.0025787998 +240 242 0.013790797 +241 242 0.0028029999 +252 242 0.00056059984 +272 242 0.00067269988 +274 242 0.0001121 +277 242 0.013118099 +282 242 0.00056059984 +284 242 0.0001121 +307 242 0.0001121 +312 242 0.0001121 +315 242 0.00067269988 +319 242 0.011324096 +322 242 0.0077362992 +324 242 0.0001121 +326 242 0.0087453984 +328 242 0.0001121 +340 242 0.0052695982 +349 242 0.00022419999 +350 242 0.0001121 +351 242 0.0001121 +354 242 0.0001121 +356 242 0.00033639977 +358 242 0.0019059998 +372 242 0.00022419999 +385 242 0.0001121 +387 242 0.0001121 +402 242 0.00022419999 +417 242 0.00056059984 +421 242 0.0001121 +422 242 0.00022419999 +430 242 0.0001121 +443 242 0.0061665997 +444 242 0.0012333 +445 242 0.0065029971 +446 242 0.00067269988 +447 242 0.0050453991 +450 242 0.0034756998 +452 242 0.0086332969 +453 242 0.0030271998 +454 242 0.0010090999 +455 242 0.0225362 +456 242 0.00044849981 +457 242 0.0047089979 +458 242 0.00078479992 +459 242 0.00078479992 +460 242 0.0014575999 +463 242 0.009081699 +464 242 0.00078479992 +465 242 0.0014575999 +467 242 0.011996899 +468 242 0.023769498 +469 242 0.0076241978 +470 242 0.0084089972 +471 242 0.0023544999 +473 242 0.00022419999 +477 242 0.0001121 +478 242 0.0012333 +479 242 0.0001121 +483 242 0.0017938998 +490 242 0.0056059994 +491 242 0.00089699985 +22 243 0.00066699996 +25 243 0.0009527998 +60 243 0.0021914998 +82 243 0.41629344 +104 243 0.0015244999 +114 243 9.5299998e-05 +126 243 9.5299998e-05 +130 243 0.00028589997 +142 243 9.5299998e-05 +143 243 9.5299998e-05 +160 243 0.00028589997 +161 243 9.5299998e-05 +188 243 0.0001906 +189 243 9.5299998e-05 +190 243 9.5299998e-05 +194 243 9.5299998e-05 +198 243 0.00057169981 +206 243 0.0001906 +214 243 0.052786998 +218 243 0.012100998 +223 243 0.0012386998 +224 243 9.5299998e-05 +230 243 0.020867098 +231 243 0.014864199 +234 243 0.0046688989 +237 243 9.5299998e-05 +240 243 9.5299998e-05 +241 243 9.5299998e-05 +243 243 0.08575505 +252 243 9.5299998e-05 +267 243 0.0031444 +272 243 0.00028589997 +277 243 0.0004763999 +312 243 9.5299998e-05 +350 243 9.5299998e-05 +358 243 0.00076229987 +422 243 9.5299998e-05 +430 243 0.00028589997 +442 243 0.00066699996 +443 243 0.0078131966 +444 243 0.0001906 +445 243 0.016769897 +446 243 0.0012386998 +447 243 0.0014292998 +450 243 0.0015244999 +452 243 0.0059075989 +453 243 0.0033348999 +454 243 0.00038109999 +455 243 0.052120097 +456 243 9.5299998e-05 +457 243 0.0035255 +458 243 0.00057169981 +459 243 0.00028589997 +460 243 0.0004763999 +463 243 0.0071462989 +464 243 0.0001906 +465 243 0.00076229987 +467 243 0.0044782981 +468 243 0.0010480999 +469 243 0.0019057 +470 243 0.0020009999 +471 243 0.00085759978 +473 243 9.5299998e-05 +478 243 0.00076229987 +483 243 0.0012386998 +490 243 0.00076229987 +491 243 0.0014292998 +60 244 0.0025038 +82 244 0.025538299 +114 244 0.00050079986 +130 244 0.075112641 +131 244 0.00050079986 +133 244 0.00050079986 +135 244 0.0095142983 +142 244 0.035553299 +143 244 0.027541298 +149 244 0.0010014998 +158 244 0.00050079986 +160 244 0.0045067966 +161 244 0.047571398 +188 244 0.070105195 +192 244 0.00050079986 +198 244 0.010015 +206 244 0.00050079986 +214 244 0.0075112991 +218 244 0.0015022999 +223 244 0.00050079986 +224 244 0.0015022999 +225 244 0.0015022999 +230 244 0.0065097995 +231 244 0.0015022999 +234 244 0.0035052998 +240 244 0.00050079986 +241 244 0.014020998 +243 244 0.17526287 +244 244 0.0075112991 +272 244 0.00050079986 +277 244 0.010015 +279 244 0.00050079986 +317 244 0.0010014998 +358 244 0.0010014998 +443 244 0.0080119967 +444 244 0.00050079986 +445 244 0.010015 +446 244 0.0015022999 +450 244 0.0030044999 +452 244 0.0055082999 +453 244 0.00050079986 +454 244 0.0015022999 +455 244 0.045568399 +457 244 0.0035052998 +458 244 0.00050079986 +460 244 0.0010014998 +463 244 0.0080119967 +464 244 0.00050079986 +465 244 0.00050079986 +467 244 0.0065097995 +468 244 0.0020029999 +469 244 0.0030044999 +470 244 0.0035052998 +471 244 0.00050079986 +478 244 0.0015022999 +483 244 0.0065097995 +490 244 0.0010014998 +491 244 0.00050079986 +18 245 3.3199991e-05 +22 245 6.6399996e-05 +60 245 0.0011292 +108 245 6.6399996e-05 +114 245 0.00013279999 +126 245 9.9599987e-05 +130 245 0.0106606 +131 245 0.0046494976 +132 245 0.0028893 +133 245 0.0055128969 +139 245 0.020889398 +141 245 0.0015608999 +142 245 0.0029224998 +143 245 0.0070737973 +149 245 0.0027564999 +150 245 0.0016272999 +151 245 3.3199991e-05 +161 245 0.0031881998 +171 245 0.0027896999 +188 245 0.0015940999 +189 245 0.00019929999 +190 245 0.0001661 +192 245 0.0012951999 +193 245 0.0011292 +194 245 9.9599987e-05 +196 245 3.3199991e-05 +197 245 3.3199991e-05 +198 245 0.0155425 +200 245 3.3199991e-05 +203 245 9.9599987e-05 +204 245 9.9599987e-05 +206 245 0.0001661 +207 245 6.6399996e-05 +209 245 3.3199991e-05 +214 245 0.0025239999 +219 245 0.007571999 +224 245 3.3199991e-05 +230 245 0.0009631 +233 245 0.0010626998 +234 245 0.0017269 +237 245 0.00019929999 +240 245 0.0220185 +241 245 0.049217898 +243 245 0.20706719 +244 245 0.019826598 +245 245 0.0063099973 +246 245 6.6399996e-05 +251 245 0.0022914999 +272 245 0.0002325 +279 245 0.00019929999 +284 245 3.3199991e-05 +292 245 0.0057453997 +315 245 0.0062435977 +317 245 0.00099629979 +335 245 0.0017269 +349 245 0.0057453997 +356 245 6.6399996e-05 +358 245 0.0011292 +387 245 6.6399996e-05 +402 245 6.6399996e-05 +422 245 9.9599987e-05 +430 245 3.3199991e-05 +432 245 3.3199991e-05 +433 245 6.6399996e-05 +434 245 6.6399996e-05 +437 245 0.0052804984 +442 245 0.0029888998 +443 245 0.0009631 +444 245 0.0010626998 +445 245 0.0096974969 +446 245 0.00053139986 +447 245 0.0039519966 +450 245 0.0032213998 +452 245 0.0038192 +453 245 0.00033209985 +454 245 0.0001661 +455 245 0.035468798 +456 245 0.00019929999 +457 245 0.0055128969 +458 245 0.0010958998 +459 245 0.00053139986 +460 245 0.00099629979 +463 245 0.011523999 +464 245 0.00073059998 +465 245 0.0014944999 +467 245 0.015011098 +468 245 0.012453899 +469 245 0.0034538999 +470 245 0.0038855998 +471 245 0.0011623998 +473 245 9.9599987e-05 +477 245 6.6399996e-05 +478 245 0.0017269 +483 245 0.0044169985 +489 245 3.3199991e-05 +490 245 0.00033209985 +491 245 6.6399996e-05 +60 246 0.0012084998 +114 246 0.00060419994 +130 246 0.047129899 +131 246 0.027190298 +132 246 0.0054380968 +133 246 0.0018126999 +139 246 0.062839866 +143 246 0.031419899 +145 246 0.0084591992 +146 246 0.00060419994 +149 246 0.0012084998 +150 246 0.00060419994 +171 246 0.00060419994 +192 246 0.00060419994 +198 246 0.022960696 +206 246 0.00060419994 +214 246 0.00060419994 +219 246 0.010876097 +222 246 0.00060419994 +224 246 0.0012084998 +225 246 0.00060419994 +230 246 0.00060419994 +234 246 0.0018126999 +240 246 0.0277946 +241 246 0.051963698 +243 246 0.068277895 +244 246 0.0054380968 +245 246 0.00060419994 +246 246 0.030815698 +292 246 0.00060419994 +315 246 0.00060419994 +317 246 0.0012084998 +349 246 0.00060419994 +358 246 0.0012084998 +377 246 0.00060419994 +437 246 0.0012084998 +444 246 0.00060419994 +445 246 0.006646499 +447 246 0.0048337989 +450 246 0.0030210998 +452 246 0.0036253999 +453 246 0.00060419994 +455 246 0.033232599 +457 246 0.0042295977 +458 246 0.00060419994 +459 246 0.00060419994 +460 246 0.0012084998 +463 246 0.0096676983 +464 246 0.00060419994 +465 246 0.00060419994 +467 246 0.0090633966 +468 246 0.039879199 +469 246 0.0060422979 +470 246 0.0060422979 +471 246 0.00060419994 +478 246 0.0018126999 +483 246 0.0060422979 +490 246 0.0012084998 +60 247 0.0012361 +82 247 0.0074165985 +114 247 0.0012361 +130 247 0.063040793 +131 247 0.0012361 +133 247 0.034610599 +139 247 0.0037082999 +149 247 0.029666297 +150 247 0.022249699 +156 247 0.0012361 +198 247 0.0173053 +206 247 0.0012361 +214 247 0.0012361 +224 247 0.004944399 +234 247 0.0037082999 +243 247 0.31149566 +317 247 0.0012361 +358 247 0.0012361 +382 247 0.0024722 +437 247 0.009888798 +445 247 0.0086526982 +450 247 0.004944399 +452 247 0.0037082999 +453 247 0.0012361 +455 247 0.028430197 +457 247 0.004944399 +460 247 0.0012361 +463 247 0.0037082999 +465 247 0.0012361 +467 247 0.0086526982 +468 247 0.0074165985 +469 247 0.004944399 +470 247 0.0061804987 +471 247 0.0037082999 +478 247 0.0012361 +483 247 0.0037082999 +490 247 0.0012361 +491 247 0.0012361 +60 248 0.0021007999 +114 248 0.00030009984 +126 248 0.00030009984 +130 248 0.036914799 +131 248 0.023109198 +132 248 0.00030009984 +133 248 0.016206499 +135 248 0.00030009984 +139 248 0.061224498 +141 248 0.00030009984 +142 248 0.021308497 +156 248 0.0054021999 +160 248 0.0024009999 +161 248 0.0015005998 +165 248 0.006902799 +169 248 0.00030009984 +171 248 0.0018006999 +190 248 0.00030009984 +192 248 0.016206499 +194 248 0.00060019991 +198 248 0.0066025965 +206 248 0.00060019991 +224 248 0.0057022981 +234 248 0.0030011998 +237 248 0.00030009984 +241 248 0.076530576 +243 248 0.017106798 +248 248 0.027010798 +272 248 0.00060019991 +279 248 0.00030009984 +284 248 0.00030009984 +315 248 0.017106798 +317 248 0.00090039987 +319 248 0.072328866 +322 248 0.00030009984 +326 248 0.00030009984 +358 248 0.0012004999 +378 248 0.00030009984 +419 248 0.00060019991 +422 248 0.00030009984 +437 248 0.027911197 +442 248 0.021608599 +443 248 0.0024009999 +444 248 0.00060019991 +445 248 0.013505399 +447 248 0.0021007999 +450 248 0.0045017973 +452 248 0.0048018992 +453 248 0.0012004999 +454 248 0.00060019991 +455 248 0.045618199 +456 248 0.00030009984 +457 248 0.0036013999 +458 248 0.0021007999 +459 248 0.00060019991 +460 248 0.0015005998 +463 248 0.034513798 +464 248 0.00060019991 +465 248 0.0012004999 +467 248 0.0090035982 +468 248 0.014405798 +469 248 0.0057022981 +470 248 0.0063024983 +471 248 0.0021007999 +473 248 0.00030009984 +478 248 0.0015005998 +483 248 0.0030011998 +490 248 0.00060019991 +491 248 0.00090039987 +60 249 0.00085229985 +114 249 0.00028409995 +126 249 0.00028409995 +130 249 0.025568198 +131 249 0.0068181977 +133 249 0.0065340996 +139 249 0.11363637 +141 249 0.00028409995 +149 249 0.0011363998 +150 249 0.0014205 +156 249 0.0068181977 +160 249 0.00028409995 +190 249 0.00028409995 +194 249 0.00028409995 +198 249 0.0028408999 +203 249 0.00028409995 +206 249 0.0005681999 +219 249 0.0073863976 +224 249 0.00028409995 +234 249 0.0022727 +237 249 0.00028409995 +241 249 0.093181789 +243 249 0.076420486 +248 249 0.00028409995 +249 249 0.012784097 +272 249 0.00028409995 +277 249 0.00028409995 +279 249 0.00028409995 +284 249 0.00028409995 +292 249 0.00028409995 +317 249 0.0011363998 +319 249 0.025284097 +326 249 0.00028409995 +358 249 0.0014205 +422 249 0.00028409995 +430 249 0.00028409995 +434 249 0.00028409995 +437 249 0.018181797 +442 249 0.0088067986 +443 249 0.0011363998 +444 249 0.00028409995 +445 249 0.010511398 +447 249 0.00085229985 +450 249 0.0056817979 +452 249 0.0053976998 +453 249 0.00085229985 +455 249 0.0480114 +456 249 0.00028409995 +457 249 0.0034091 +458 249 0.0005681999 +459 249 0.00028409995 +460 249 0.0017044998 +463 249 0.014772698 +464 249 0.0005681999 +465 249 0.0014205 +467 249 0.0085226968 +468 249 0.0082385987 +469 249 0.0048294999 +470 249 0.0053976998 +471 249 0.0025567999 +473 249 0.00028409995 +478 249 0.0019885998 +483 249 0.0036931999 +490 249 0.0005681999 +60 250 0.0012578999 +82 250 0.0012578999 +114 250 0.00041929982 +126 250 0.00041929982 +130 250 0.027672999 +131 250 0.018029399 +133 250 0.0075471997 +139 250 0.032285098 +141 250 0.00041929982 +142 250 0.00041929982 +149 250 0.00083859987 +150 250 0.00083859987 +156 250 0.020545099 +160 250 0.0096435994 +161 250 0.00083859987 +171 250 0.00041929982 +188 250 0.00041929982 +193 250 0.0037735999 +198 250 0.018867899 +206 250 0.00083859987 +219 250 0.0075471997 +224 250 0.00041929982 +231 250 0.00041929982 +234 250 0.0033542998 +237 250 0.00041929982 +241 250 0.064570189 +243 250 0.092662454 +249 250 0.00041929982 +250 250 0.00041929982 +251 250 0.00083859987 +252 250 0.00041929982 +272 250 0.00041929982 +279 250 0.00041929982 +290 250 0.0016770998 +292 250 0.00041929982 +298 250 0.0012578999 +312 250 0.0033542998 +315 250 0.00083859987 +317 250 0.00083859987 +319 250 0.015513599 +322 250 0.012578599 +326 250 0.018867899 +358 250 0.0012578999 +378 250 0.014255799 +421 250 0.00083859987 +424 250 0.0012578999 +426 250 0.00041929982 +437 250 0.0083856992 +442 250 0.0012578999 +443 250 0.0012578999 +444 250 0.0037735999 +445 250 0.021802898 +447 250 0.020545099 +450 250 0.0041928999 +452 250 0.0037735999 +455 250 0.031027298 +456 250 0.00041929982 +457 250 0.0037735999 +458 250 0.00083859987 +460 250 0.0012578999 +463 250 0.012159299 +464 250 0.00083859987 +465 250 0.00041929982 +467 250 0.010062899 +468 250 0.019706499 +469 250 0.0062892996 +470 250 0.0075471997 +471 250 0.0016770998 +473 250 0.00041929982 +478 250 0.0012578999 +483 250 0.0041928999 +490 250 0.00083859987 +60 251 0.00065449998 +82 251 0.033376999 +114 251 0.00065449998 +130 251 0.0032722999 +133 251 0.00065449998 +139 251 0.0032722999 +142 251 0.00065449998 +149 251 0.0013088998 +150 251 0.0013088998 +161 251 0.028141398 +171 251 0.00065449998 +188 251 0.0026177999 +191 251 0.00065449998 +193 251 0.0157068 +198 251 0.0058900975 +206 251 0.0013088998 +214 251 0.0013088998 +225 251 0.00065449998 +230 251 0.00065449998 +231 251 0.021596897 +234 251 0.0045811981 +237 251 0.00065449998 +240 251 0.00065449998 +241 251 0.0039266981 +243 251 0.19437164 +251 251 0.0058900975 +312 251 0.0091622993 +315 251 0.0078534 +317 251 0.00065449998 +319 251 0.0235602 +358 251 0.0013088998 +437 251 0.059554998 +443 251 0.00065449998 +445 251 0.0045811981 +450 251 0.0045811981 +452 251 0.0052355975 +453 251 0.0019633998 +455 251 0.038612597 +457 251 0.0039266981 +458 251 0.00065449998 +460 251 -0.024869099 +463 251 0.0065444969 +464 251 0.0013088998 +465 251 0.00065449998 +467 251 0.0065444969 +468 251 0.052355997 +469 251 0.0052355975 +470 251 0.0052355975 +471 251 0.0019633998 +478 251 0.0013088998 +483 251 0.0019633998 +490 251 0.00065449998 +491 251 0.00065449998 +4 252 2.8299997e-05 +18 252 0.0011618 +22 252 0.00042499998 +24 252 0.006403897 +25 252 0.00045339996 +60 252 0.0098324977 +82 252 2.8299997e-05 +108 252 8.4999992e-05 +114 252 0.00011329999 +126 252 8.4999992e-05 +130 252 0.00028339983 +132 252 5.6699995e-05 +135 252 2.8299997e-05 +139 252 5.6699995e-05 +150 252 0.00062339986 +151 252 0.00085009984 +156 252 2.8299997e-05 +159 252 2.8299997e-05 +160 252 0.0043920986 +161 252 0.00039669988 +162 252 0.00076509989 +165 252 0.00036839978 +169 252 0.0012750998 +170 252 0.00022669999 +171 252 0.010144196 +172 252 0.0031452999 +187 252 5.6699995e-05 +189 252 8.4999992e-05 +190 252 8.4999992e-05 +192 252 0.0022384999 +193 252 0.00076509989 +194 252 0.00011329999 +197 252 2.8299997e-05 +198 252 0.01873 +200 252 2.8299997e-05 +203 252 5.6699995e-05 +204 252 8.4999992e-05 +206 252 0.00011329999 +207 252 2.8299997e-05 +214 252 0.015612997 +218 252 2.8299997e-05 +219 252 0.0016150998 +223 252 0.0024368998 +224 252 0.00028339983 +227 252 2.8299997e-05 +228 252 2.8299997e-05 +233 252 0.0028902998 +234 252 0.0026918999 +237 252 0.00017 +240 252 0.0012750998 +241 252 0.059986997 +242 252 0.0012750998 +252 252 0.12668949 +253 252 2.8299997e-05 +263 252 0.00073669991 +267 252 0.00070839981 +268 252 0.00031169993 +270 252 0.00042499998 +271 252 2.8299997e-05 +272 252 0.00073669991 +273 252 0.0047603995 +274 252 0.0009066998 +277 252 0.0013317999 +279 252 0.0010201 +282 252 0.00028339983 +283 252 8.4999992e-05 +284 252 8.4999992e-05 +285 252 2.8299997e-05 +289 252 2.8299997e-05 +290 252 0.0024935999 +292 252 0.00025499985 +293 252 0.00025499985 +295 252 0.00011329999 +296 252 0.00014169999 +298 252 8.4999992e-05 +312 252 0.00017 +313 252 2.8299997e-05 +315 252 0.0029753 +317 252 0.00028339983 +318 252 2.8299997e-05 +319 252 0.00031169993 +320 252 5.6699995e-05 +322 252 5.6699995e-05 +324 252 2.8299997e-05 +325 252 2.8299997e-05 +326 252 0.00014169999 +328 252 8.4999992e-05 +340 252 0.00036839978 +345 252 0.0010483998 +346 252 2.8299997e-05 +349 252 0.00059509999 +350 252 0.00082169985 +351 252 5.6699995e-05 +352 252 0.00011329999 +354 252 5.6699995e-05 +356 252 0.00022669999 +357 252 2.8299997e-05 +358 252 0.0030318999 +369 252 2.8299997e-05 +370 252 0.00031169993 +372 252 8.4999992e-05 +375 252 0.0013317999 +377 252 0.00059509999 +384 252 0.00017 +385 252 8.4999992e-05 +386 252 0.0010201 +387 252 8.4999992e-05 +393 252 5.6699995e-05 +397 252 2.8299997e-05 +398 252 5.6699995e-05 +401 252 5.6699995e-05 +402 252 0.00025499985 +412 252 2.8299997e-05 +414 252 0.00076509989 +417 252 0.00042499998 +419 252 0.0013885 +420 252 2.8299997e-05 +421 252 8.4999992e-05 +422 252 8.4999992e-05 +430 252 5.6699995e-05 +433 252 2.8299997e-05 +434 252 2.8299997e-05 +442 252 8.4999992e-05 +443 252 0.015131298 +444 252 0.0011333998 +445 252 0.011249296 +446 252 0.00085009984 +447 252 0.0041653998 +450 252 0.0032869999 +452 252 0.010710899 +453 252 0.020628497 +454 252 0.0017567999 +455 252 0.038423397 +456 252 0.00028339983 +457 252 0.0035702998 +458 252 0.0021819 +459 252 0.0020684998 +460 252 0.00082169985 +463 252 0.012071099 +464 252 0.0012750998 +465 252 0.00079339999 +467 252 0.015074696 +468 252 0.014196299 +469 252 0.0047320984 +470 252 0.0053554997 +471 252 0.0069138967 +473 252 8.4999992e-05 +477 252 0.00096339989 +478 252 0.0010767998 +483 252 0.0012467999 +489 252 0.00014169999 +490 252 0.00039669988 +491 252 0.0042219982 +9 253 4.7299996e-05 +18 253 0.0002366 +24 253 0.011972897 +60 253 0.0037385998 +82 253 4.7299996e-05 +108 253 4.7299996e-05 +114 253 9.4599993e-05 +126 253 4.7299996e-05 +150 253 0.00075719994 +160 253 0.00037859986 +162 253 0.0022715 +169 253 0.0021768999 +172 253 0.00099379988 +189 253 4.7299996e-05 +190 253 9.4599993e-05 +192 253 0.0032179998 +193 253 4.7299996e-05 +194 253 0.00014199999 +198 253 0.089867949 +200 253 4.7299996e-05 +203 253 4.7299996e-05 +204 253 0.0036912998 +206 253 0.00014199999 +207 253 4.7299996e-05 +214 253 0.033694599 +233 253 0.0015143999 +234 253 0.0053475983 +237 253 0.00014199999 +241 253 0.0048743971 +252 253 0.00033129985 +253 253 0.0031706998 +267 253 0.0065779984 +270 253 0.0020821998 +273 253 0.015948098 +276 253 9.4599993e-05 +277 253 9.4599993e-05 +279 253 0.0041171983 +284 253 9.4599993e-05 +314 253 0.0026027998 +317 253 0.0010410999 +326 253 4.7299996e-05 +340 253 0.0056788996 +349 253 0.0128721 +356 253 0.00018929999 +358 253 0.0035492999 +384 253 4.7299996e-05 +387 253 4.7299996e-05 +402 253 4.7299996e-05 +414 253 0.00094649987 +417 253 0.00052059977 +421 253 9.4599993e-05 +422 253 4.7299996e-05 +430 253 4.7299996e-05 +433 253 4.7299996e-05 +434 253 4.7299996e-05 +442 253 0.0032652998 +443 253 0.0387582 +444 253 0.00014199999 +445 253 0.015096299 +446 253 0.0019403 +447 253 0.00056789978 +448 253 4.7299996e-05 +450 253 0.0026974999 +452 253 0.017604496 +453 253 0.030145299 +454 253 0.0022241999 +455 253 0.0234253 +456 253 0.00033129985 +457 253 0.0026974999 +458 253 0.00033129985 +459 253 0.00080449996 +460 253 0.00085179997 +463 253 0.017415199 +464 253 0.00018929999 +465 253 0.00099379988 +467 253 0.0090861991 +468 253 0.0043537989 +469 253 0.0031706998 +470 253 0.0035019999 +471 253 0.0010410999 +472 253 0.00047319988 +473 253 9.4599993e-05 +477 253 4.7299996e-05 +478 253 0.0012303998 +483 253 0.0010883999 +489 253 9.4599993e-05 +490 253 0.00028389995 +491 253 0.0077137984 +18 254 0.00061059999 +19 254 0.00088809989 +21 254 5.5499986e-05 +22 254 0.025312196 +24 254 0.0511241 +25 254 5.5499986e-05 +60 254 0.034415796 +68 254 0.00088809989 +69 254 0.00044409977 +73 254 0.00011099999 +75 254 5.5499986e-05 +108 254 5.5499986e-05 +114 254 0.00011099999 +126 254 5.5499986e-05 +160 254 0.0017762999 +169 254 0.0027754998 +189 254 5.5499986e-05 +190 254 5.5499986e-05 +193 254 0.012323096 +194 254 0.00011099999 +200 254 5.5499986e-05 +203 254 5.5499986e-05 +204 254 5.5499986e-05 +206 254 0.00011099999 +214 254 0.025978398 +219 254 0.0015542998 +220 254 0.0023313998 +224 254 0.0016097999 +234 254 0.014654499 +235 254 0.00272 +237 254 0.00066609983 +241 254 5.5499986e-05 +242 254 0.0044406988 +251 254 0.00011099999 +252 254 5.5499986e-05 +254 254 0.0020537998 +270 254 0.0029419998 +273 254 0.014987499 +277 254 0.0032195 +287 254 5.5499986e-05 +295 254 0.0018872998 +305 254 0.00016649999 +320 254 0.0019427999 +322 254 0.0013321999 +324 254 0.00049959985 +328 254 0.00055509992 +331 254 0.0049957968 +349 254 0.0011656999 +350 254 0.0023868999 +356 254 0.00038859993 +358 254 0.00038859993 +384 254 0.00016649999 +386 254 0.0025533999 +387 254 5.5499986e-05 +402 254 0.00016649999 +404 254 5.5499986e-05 +414 254 0.00049959985 +417 254 0.00016649999 +422 254 5.5499986e-05 +442 254 0.0044962987 +443 254 0.0329725 +444 254 0.0021094 +445 254 0.0286428 +446 254 0.0036636 +447 254 0.0022759 +448 254 0.00016649999 +450 254 0.0021094 +452 254 0.050402399 +453 254 0.043297298 +454 254 0.0032749998 +455 254 0.016097698 +456 254 0.00066609983 +457 254 0.017596398 +458 254 0.00038859993 +459 254 0.0013321999 +460 254 0.0018318 +463 254 0.0085483976 +464 254 0.0016097999 +465 254 0.00044409977 +467 254 0.018706597 +468 254 0.0026089 +469 254 0.0064945966 +470 254 0.0020537998 +471 254 0.0062169991 +473 254 5.5499986e-05 +477 254 0.0017762999 +478 254 0.00061059999 +483 254 0.00044409977 +489 254 0.00044409977 +490 254 0.00016649999 +491 254 5.5499986e-05 +18 255 0.00042859977 +22 255 0.0021431998 +24 255 0.051007297 +60 255 0.0092155971 +108 255 0.00021429999 +114 255 0.00042859977 +126 255 0.00021429999 +160 255 0.0032146999 +169 255 0.0021431998 +189 255 0.00021429999 +190 255 0.00021429999 +194 255 0.00021429999 +198 255 0.0062151998 +206 255 0.00042859977 +214 255 0.0070723966 +218 255 0.00021429999 +220 255 0.00064289989 +233 255 0.0060008988 +234 255 0.0098585971 +235 255 0.0034290999 +237 255 0.00042859977 +240 255 0.0012858999 +252 255 0.00021429999 +254 255 0.00042859977 +255 255 0.0032146999 +260 255 0.0021431998 +271 255 0.00021429999 +272 255 0.0017144999 +273 255 0.00085729989 +277 255 0.0045005977 +282 255 0.0019287998 +283 255 0.00042859977 +284 255 0.00021429999 +292 255 0.00021429999 +295 255 0.00042859977 +297 255 0.00042859977 +305 255 0.00085729989 +322 255 0.0010715998 +324 255 0.00042859977 +326 255 0.010930099 +328 255 0.0034290999 +331 255 0.0045005977 +335 255 0.0027860999 +351 255 0.0017144999 +354 255 0.0034290999 +356 255 0.00042859977 +358 255 0.0021431998 +372 255 0.00085729989 +387 255 0.00021429999 +402 255 0.0021431998 +417 255 0.00064289989 +443 255 0.010501496 +444 255 0.0070723966 +445 255 0.034933597 +446 255 0.0021431998 +447 255 0.0062151998 +448 255 0.00021429999 +450 255 0.0038576999 +452 255 0.025932297 +453 255 0.076082289 +454 255 0.00064289989 +455 255 0.012430299 +456 255 0.00042859977 +457 255 0.0070723966 +458 255 0.0012858999 +459 255 0.00085729989 +460 255 0.0077153966 +463 255 0.0117874 +464 255 0.00064289989 +465 255 0.0012858999 +467 255 0.0145735 +468 255 0.0079296976 +469 255 0.0057864971 +470 255 0.0062151998 +471 255 0.013501897 +473 255 0.00021429999 +478 255 0.0017144999 +483 255 0.0017144999 +490 255 0.00064289989 +19 256 0.0012429999 +24 256 0.011187099 +60 256 0.0074579976 +114 256 0.00062149996 +160 256 0.0055934973 +198 256 0.032939699 +206 256 0.00062149996 +214 256 0.070229948 +223 256 0.025481697 +233 256 0.013051599 +234 256 0.0018644999 +235 256 0.003729 +240 256 0.0055934973 +256 256 0.0031074998 +263 256 0.0012429999 +268 256 0.00062149996 +272 256 0.0012429999 +273 256 0.011808597 +279 256 0.0018644999 +340 256 0.0012429999 +356 256 0.00062149996 +358 256 0.0024859998 +417 256 0.00062149996 +443 256 0.0074579976 +444 256 0.022374097 +445 256 0.010565598 +446 256 0.00062149996 +447 256 0.028589197 +450 256 0.0043504983 +452 256 0.0149161 +453 256 0.025481697 +454 256 0.0018644999 +455 256 0.016159099 +457 256 0.011808597 +458 256 0.0012429999 +459 256 0.00062149996 +460 256 0.0074579976 +463 256 0.0074579976 +464 256 0.0012429999 +465 256 0.00062149996 +467 256 0.010565598 +468 256 0.013051599 +469 256 0.0074579976 +470 256 0.0074579976 +471 256 0.003729 +478 256 0.0012429999 +483 256 0.0031074998 +490 256 0.0012429999 +18 257 0.00032939995 +19 257 0.0013174999 +21 257 0.056324098 +22 257 0.0029644 +24 257 0.072463751 +60 257 0.0062581971 +114 257 0.00032939995 +126 257 0.00032939995 +160 257 0.0059288964 +169 257 0.012516499 +193 257 0.00032939995 +198 257 0.00032939995 +206 257 0.00065879989 +214 257 0.0108696 +220 257 0.00032939995 +234 257 0.0042818971 +237 257 0.00065879989 +240 257 0.00032939995 +241 257 0.00032939995 +257 257 0.030961797 +267 257 0.00032939995 +270 257 0.00032939995 +272 257 0.00065879989 +273 257 0.0075757988 +275 257 0.0046112984 +277 257 0.0023057 +278 257 0.00032939995 +282 257 0.00032939995 +284 257 0.00032939995 +286 257 0.00032939995 +287 257 0.00032939995 +288 257 0.00032939995 +289 257 0.00098809996 +290 257 0.0088932998 +291 257 0.00032939995 +301 257 0.0042818971 +324 257 0.00032939995 +326 257 0.00032939995 +328 257 0.00065879989 +331 257 0.00098809996 +335 257 0.00065879989 +340 257 0.00032939995 +351 257 0.00032939995 +354 257 0.00065879989 +356 257 0.00032939995 +358 257 0.0013174999 +370 257 0.00098809996 +402 257 0.00032939995 +417 257 0.00032939995 +443 257 0.024374198 +444 257 0.00065879989 +445 257 0.062582254 +446 257 0.0023057 +447 257 0.0082344972 +450 257 0.0029644 +452 257 0.014163397 +453 257 0.0408432 +454 257 0.00065879989 +455 257 0.019104097 +456 257 0.00032939995 +457 257 0.0029644 +458 257 0.00065879989 +459 257 0.00065879989 +460 257 0.0065875985 +463 257 0.015151497 +464 257 0.00065879989 +465 257 0.00065879989 +467 257 0.0079050995 +468 257 0.0059288964 +469 257 0.0059288964 +470 257 0.0065875985 +471 257 0.0016468999 +473 257 0.00032939995 +478 257 0.00098809996 +483 257 0.0013174999 +490 257 0.00065879989 +491 257 0.0026349998 +22 258 0.0040863976 +24 258 0.061295997 +60 258 0.0087565966 +114 258 0.00058379979 +160 258 0.004670199 +169 258 0.0029189 +198 258 0.0017512999 +206 258 0.00058379979 +214 258 0.0017512999 +220 258 0.00058379979 +223 258 0.00058379979 +233 258 0.0011674999 +234 258 0.006421499 +237 258 0.0023351 +240 258 0.0011674999 +258 258 0.0017512999 +268 258 0.004670199 +272 258 0.0011674999 +273 258 0.00058379979 +277 258 0.0023351 +282 258 0.0017512999 +283 258 0.00058379979 +295 258 0.00058379979 +297 258 0.00058379979 +305 258 0.00058379979 +322 258 0.0011674999 +326 258 0.00058379979 +328 258 0.0035025999 +331 258 0.004670199 +335 258 0.0029189 +351 258 0.0017512999 +354 258 0.0029189 +358 258 0.0017512999 +372 258 0.00058379979 +402 258 0.0023351 +417 258 0.00058379979 +443 258 0.012842998 +444 258 0.0052538998 +445 258 0.067133665 +446 258 0.0023351 +447 258 0.016929399 +450 258 0.0035025999 +452 258 0.018096898 +453 258 0.060128398 +455 258 0.0075889975 +457 258 0.0035025999 +458 258 0.0023351 +459 258 0.00058379979 +460 258 0.0075889975 +463 258 0.004670199 +464 258 0.00058379979 +465 258 0.00058379979 +467 258 0.011675399 +468 258 0.0017512999 +469 258 0.0058376975 +470 258 0.0058376975 +471 258 0.0040863976 +478 258 0.0011674999 +483 258 0.0017512999 +490 258 0.0011674999 +22 259 0.00040019979 +24 259 0.036814697 +25 259 0.00040019979 +60 259 0.0052020997 +114 259 0.00040019979 +160 259 0.0016005998 +198 259 0.028011199 +206 259 0.00080029992 +214 259 0.075630248 +223 259 0.0028010998 +224 259 0.00040019979 +233 259 0.0024009999 +234 259 0.0024009999 +240 259 0.00040019979 +241 259 0.00040019979 +267 259 0.00080029992 +268 259 0.0024009999 +270 259 0.0016005998 +272 259 0.00040019979 +273 259 0.016406599 +277 259 0.008803498 +279 259 0.00080029992 +282 259 0.00080029992 +284 259 0.00040019979 +288 259 0.00080029992 +292 259 0.00080029992 +295 259 0.00040019979 +297 259 0.0012004999 +298 259 0.00040019979 +312 259 0.00080029992 +315 259 0.00080029992 +317 259 0.00040019979 +319 259 0.00040019979 +320 259 0.00040019979 +321 259 0.0012004999 +324 259 0.00040019979 +340 259 0.00040019979 +356 259 0.00040019979 +358 259 0.0032012998 +372 259 0.00080029992 +380 259 0.00040019979 +386 259 0.00040019979 +415 259 0.00080029992 +417 259 0.00040019979 +422 259 0.010003999 +443 259 0.012805097 +444 259 0.0052020997 +445 259 0.041216496 +446 259 0.0016005998 +447 259 0.0172069 +450 259 0.0032012998 +452 259 0.008803498 +453 259 0.016006399 +454 259 0.0024009999 +455 259 0.016806699 +457 259 0.0032012998 +458 259 0.00040019979 +459 259 0.00040019979 +460 259 0.00080029992 +463 259 0.0172069 +464 259 0.00040019979 +465 259 0.00080029992 +467 259 0.0068026967 +468 259 0.022409 +469 259 0.0032012998 +470 259 0.0032012998 +471 259 0.0016005998 +478 259 0.0012004999 +483 259 0.0012004999 +490 259 0.00040019979 +491 259 0.00080029992 +22 260 0.0012135999 +24 260 0.0072815977 +60 260 0.0060679987 +114 260 0.0012135999 +198 260 0.0097086988 +206 260 0.0012135999 +214 260 0.040048499 +223 260 0.0133495 +234 260 0.0048543997 +260 260 0.0012135999 +263 260 0.0024271999 +267 260 0.0012135999 +268 260 0.0133495 +273 260 0.0133495 +358 260 0.0072815977 +417 260 0.0012135999 +443 260 0.0097086988 +444 260 0.0012135999 +445 260 0.0097086988 +446 260 0.0012135999 +447 260 0.0048543997 +450 260 0.0060679987 +452 260 0.0097086988 +453 260 0.016990297 +454 260 0.0012135999 +455 260 0.0072815977 +457 260 0.0024271999 +463 260 0.033980597 +464 260 0.0012135999 +465 260 0.0012135999 +467 260 0.0097086988 +468 260 0.0084950998 +469 260 0.0097086988 +470 260 0.0097086988 +478 260 0.0024271999 +483 260 0.0024271999 +490 260 0.0012135999 +491 260 0.0012135999 +24 261 0.020134199 +60 261 0.0033556998 +114 261 0.0016778999 +160 261 0.0033556998 +198 261 0.011744998 +206 261 0.0016778999 +214 261 0.050335597 +223 261 0.020134199 +234 261 0.0050335974 +263 261 0.026845597 +268 261 0.0218121 +272 261 0.0016778999 +273 261 0.0083892979 +284 261 0.0016778999 +358 261 0.0067113973 +417 261 0.0016778999 +443 261 0.0067113973 +444 261 0.0067113973 +445 261 0.018456399 +446 261 0.0016778999 +447 261 0.036912799 +450 261 0.0067113973 +452 261 0.0083892979 +453 261 0.020134199 +455 261 0.010067098 +457 261 0.0050335974 +464 261 0.0016778999 +465 261 0.0016778999 +467 261 0.010067098 +468 261 0.0067113973 +469 261 0.0083892979 +470 261 0.010067098 +471 261 0.0016778999 +478 261 0.0033556998 +483 261 0.0033556998 +490 261 0.0016778999 +18 262 0.00038309977 +22 262 0.0137931 +24 262 0.047892697 +60 262 0.0042145997 +114 262 0.00038309977 +126 262 0.00038309977 +160 262 0.0015325998 +198 262 0.016475096 +206 262 0.0007662999 +214 262 0.062835157 +233 262 0.00038309977 +234 262 0.0042145997 +240 262 0.00038309977 +241 262 0.0007662999 +252 262 0.0007662999 +262 262 0.0011493999 +263 262 0.00038309977 +268 262 0.0022988999 +272 262 0.00038309977 +273 262 0.023754798 +277 262 0.0007662999 +279 262 0.0007662999 +284 262 0.00038309977 +286 262 0.00038309977 +287 262 0.00038309977 +288 262 0.00038309977 +289 262 0.0049807988 +290 262 0.0084290989 +291 262 0.00038309977 +292 262 0.00038309977 +294 262 0.00038309977 +295 262 0.0007662999 +315 262 0.00038309977 +317 262 0.00038309977 +326 262 0.00038309977 +340 262 0.0007662999 +356 262 0.00038309977 +358 262 0.0038313998 +385 262 0.023754798 +386 262 0.0007662999 +417 262 0.0007662999 +438 262 0.014559399 +443 262 0.014559399 +444 262 0.0019156998 +445 262 0.027969297 +446 262 0.0030650999 +447 262 0.013409998 +450 262 0.0038313998 +452 262 0.011494298 +453 262 0.013026796 +454 262 0.0026819999 +455 262 0.017624497 +456 262 0.00038309977 +457 262 0.0030650999 +458 262 0.00038309977 +459 262 0.00038309977 +460 262 0.0007662999 +463 262 0.0038313998 +464 262 0.0007662999 +465 262 0.0011493999 +467 262 0.0095784999 +468 262 0.0019156998 +469 262 0.0061302967 +470 262 0.0068965964 +471 262 0.0015325998 +473 262 0.00038309977 +478 262 0.0019156998 +483 262 0.0019156998 +490 262 0.0007662999 +491 262 0.0019156998 +21 263 0.00067749992 +22 263 0.00067749992 +24 263 0.014905099 +25 263 0.00067749992 +60 263 0.0060975999 +114 263 0.00067749992 +160 263 0.0013549998 +198 263 0.012195099 +206 263 0.0013549998 +214 263 0.0616531 +223 263 0.018292699 +234 263 0.0033874998 +241 263 0.0013549998 +263 263 0.0040649995 +268 263 0.018292699 +272 263 0.00067749992 +273 263 0.018970199 +279 263 0.00067749992 +284 263 0.00067749992 +287 263 0.00067749992 +349 263 0.00067749992 +356 263 0.00067749992 +358 263 0.0054200999 +385 263 0.00067749992 +393 263 0.00067749992 +417 263 0.00067749992 +420 263 0.0013549998 +438 263 0.00067749992 +443 263 0.013550099 +444 263 0.00067749992 +445 263 0.018970199 +446 263 0.0013549998 +447 263 0.0088075995 +450 263 0.0047424994 +452 263 0.010840099 +453 263 0.017615199 +454 263 0.0033874998 +455 263 0.017615199 +457 263 0.0027099999 +460 263 0.00067749992 +463 263 0.017615199 +464 263 0.00067749992 +465 263 0.0013549998 +467 263 0.010162599 +468 263 0.0094850995 +469 263 0.0074525997 +470 263 0.0074525997 +471 263 0.0027099999 +478 263 0.0020325 +483 263 0.0020325 +490 263 0.0013549998 +491 263 0.00067749992 +18 264 0.0002485998 +22 264 0.00074589998 +24 264 0.090377867 +60 264 0.0031078998 +108 264 0.00012429999 +114 264 0.0002485998 +126 264 0.00012429999 +160 264 0.0016160998 +169 264 0.00012429999 +189 264 0.00012429999 +190 264 0.00012429999 +193 264 0.00012429999 +194 264 0.00012429999 +198 264 0.0013674998 +203 264 0.00012429999 +206 264 0.0002485998 +214 264 0.0042267963 +218 264 0.00012429999 +223 264 0.00049729994 +231 264 0.00037289993 +233 264 0.0014918 +234 264 0.0104426 +235 264 0.00074589998 +237 264 0.00099449977 +240 264 0.00012429999 +242 264 0.00012429999 +252 264 0.00012429999 +254 264 0.14022869 +264 264 0.0012431999 +265 264 0.00049729994 +266 264 0.0012431999 +269 264 0.0002485998 +270 264 0.015290897 +272 264 0.0012431999 +273 264 0.033316799 +276 264 0.00012429999 +277 264 0.0037294999 +317 264 0.00012429999 +322 264 0.0039780997 +326 264 0.005842898 +332 264 0.00037289993 +356 264 0.00037289993 +358 264 0.00074589998 +387 264 0.00012429999 +402 264 0.00037289993 +417 264 0.0002485998 +422 264 0.00012429999 +434 264 0.00012429999 +438 264 0.00012429999 +442 264 0.00037289993 +443 264 0.034062698 +444 264 0.0026105999 +445 264 0.059298899 +446 264 0.0041023977 +447 264 0.0070859976 +448 264 0.0002485998 +450 264 0.0036052 +452 264 0.0085777976 +453 264 0.0068373978 +454 264 0.00062159984 +455 264 0.023744397 +456 264 0.0013674998 +457 264 0.0032321999 +458 264 0.00099449977 +459 264 0.00074589998 +460 264 0.0021133998 +463 264 0.031576298 +464 264 0.00099449977 +465 264 0.00087019987 +467 264 0.017031297 +468 264 0.005842898 +469 264 0.0057184994 +470 264 0.0060914978 +471 264 0.0064643994 +473 264 0.00012429999 +478 264 0.0012431999 +483 264 0.0011187999 +489 264 0.0002485998 +490 264 0.00049729994 +9 265 5.2299991e-05 +18 265 0.00036609988 +22 265 0.0023534 +24 265 0.035929099 +60 265 0.0023534 +82 265 5.2299991e-05 +83 265 5.2299991e-05 +84 265 5.2299991e-05 +108 265 5.2299991e-05 +114 265 0.0001046 +120 265 5.2299991e-05 +126 265 5.2299991e-05 +130 265 5.2299991e-05 +137 265 5.2299991e-05 +150 265 0.00041839993 +160 265 0.0015689998 +169 265 0.0025626 +189 265 5.2299991e-05 +190 265 0.0001046 +191 265 0.0001046 +193 265 0.0046545975 +194 265 0.00015689999 +197 265 5.2299991e-05 +198 265 5.2299991e-05 +200 265 5.2299991e-05 +203 265 0.0001046 +204 265 0.0001046 +206 265 0.0001046 +207 265 5.2299991e-05 +214 265 0.018147599 +218 265 0.00015689999 +223 265 0.0047068968 +231 265 0.00020919999 +233 265 0.0073740967 +234 265 0.0088906996 +235 265 0.0019872999 +237 265 0.0010982999 +240 265 0.0014644 +242 265 0.0019872999 +252 265 0.00015689999 +254 265 0.078761578 +264 265 0.0013597999 +265 265 0.016212497 +266 265 0.025103297 +269 265 0.0013074998 +270 265 0.0043407977 +272 265 0.0010459998 +273 265 0.0026671998 +277 265 0.0151143 +293 265 0.0001046 +317 265 5.2299991e-05 +319 265 5.2299991e-05 +322 265 0.060875498 +326 265 0.0001046 +332 265 0.0025102999 +340 265 0.00015689999 +356 265 0.00041839993 +358 265 0.0008890999 +384 265 0.00094139995 +386 265 0.0012551998 +387 265 5.2299991e-05 +394 265 5.2299991e-05 +397 265 5.2299991e-05 +402 265 0.00041839993 +404 265 5.2299991e-05 +417 265 0.00031379983 +421 265 5.2299991e-05 +422 265 0.00015689999 +423 265 5.2299991e-05 +430 265 5.2299991e-05 +433 265 5.2299991e-05 +434 265 5.2299991e-05 +440 265 0.0001046 +442 265 0.0020395999 +443 265 0.0157419 +444 265 0.0020919 +445 265 0.041315798 +446 265 0.0025626 +447 265 0.0050729997 +448 265 0.00015689999 +450 265 0.0040269978 +452 265 0.0055958964 +453 265 0.0030332999 +454 265 0.00067989994 +455 265 0.031065296 +456 265 0.0015689998 +457 265 0.0028763998 +458 265 0.00073219999 +459 265 0.00052299979 +460 265 0.0018304 +463 265 0.0136499 +464 265 0.0007844998 +465 265 0.0008890999 +467 265 0.014172897 +468 265 0.0040792972 +469 265 0.004236199 +470 265 0.0047068968 +471 265 0.0071125999 +473 265 0.0001046 +477 265 0.00020919999 +478 265 0.0012029 +483 265 0.00067989994 +489 265 0.00031379983 +490 265 0.00036609988 +9 266 2.739999e-05 +18 266 0.0002193 +22 266 0.0041934997 +24 266 0.10689318 +60 266 0.0023023 +79 266 2.739999e-05 +82 266 2.739999e-05 +83 266 2.739999e-05 +84 266 2.739999e-05 +108 266 2.739999e-05 +113 266 5.4799995e-05 +114 266 8.2199986e-05 +126 266 5.4799995e-05 +127 266 2.739999e-05 +150 266 0.00032889983 +151 266 2.739999e-05 +160 266 0.0017815998 +169 266 2.739999e-05 +171 266 2.739999e-05 +189 266 5.4799995e-05 +190 266 8.2199986e-05 +192 266 2.739999e-05 +193 266 8.2199986e-05 +194 266 0.00010959999 +197 266 2.739999e-05 +198 266 0.0013155998 +200 266 5.4799995e-05 +201 266 2.739999e-05 +203 266 5.4799995e-05 +204 266 2.739999e-05 +206 266 0.00010959999 +207 266 2.739999e-05 +214 266 0.0024941999 +218 266 0.00019189999 +220 266 0.00043849996 +223 266 0.0037823999 +231 266 0.0015075 +233 266 0.00010959999 +234 266 0.010771498 +235 266 5.4799995e-05 +237 266 0.00073999981 +241 266 8.2199986e-05 +242 266 2.739999e-05 +248 266 2.739999e-05 +250 266 2.739999e-05 +252 266 0.00010959999 +254 266 0.23031378 +265 266 0.00010959999 +266 266 0.0048512965 +270 266 0.00010959999 +272 266 0.0012881998 +273 266 0.0055090971 +277 266 0.0002193 +282 266 5.4799995e-05 +284 266 2.739999e-05 +301 266 2.739999e-05 +317 266 2.739999e-05 +322 266 0.0024667999 +326 266 5.4799995e-05 +328 266 8.2199986e-05 +331 266 0.000137 +332 266 0.0018638 +335 266 2.739999e-05 +336 266 2.739999e-05 +340 266 2.739999e-05 +351 266 0.000137 +354 266 0.00010959999 +358 266 0.0010688999 +384 266 5.4799995e-05 +386 266 8.2199986e-05 +387 266 5.4799995e-05 +394 266 2.739999e-05 +397 266 2.739999e-05 +402 266 0.00032889983 +417 266 0.0002193 +419 266 2.739999e-05 +421 266 2.739999e-05 +422 266 0.00010959999 +423 266 2.739999e-05 +425 266 2.739999e-05 +430 266 2.739999e-05 +431 266 2.739999e-05 +433 266 2.739999e-05 +434 266 2.739999e-05 +438 266 0.00057559996 +442 266 0.0026311998 +443 266 0.033383597 +444 266 0.002412 +445 266 0.097793579 +446 266 0.0064409971 +447 266 0.0060024969 +448 266 0.00019189999 +450 266 0.0040290989 +452 266 0.004714299 +453 266 0.0012059999 +454 266 0.00060299993 +455 266 0.0260107 +456 266 0.0011236998 +457 266 0.0029600998 +458 266 0.00071259984 +459 266 0.00063039991 +460 266 0.0027682998 +463 266 0.010853797 +464 266 0.002686 +465 266 0.00060299993 +467 266 0.014087997 +468 266 0.0055090971 +469 266 0.0054542981 +470 266 0.0046319999 +471 266 0.0046045966 +473 266 0.00010959999 +477 266 0.00010959999 +478 266 0.0007948 +483 266 0.0007948 +489 266 0.0002193 +490 266 0.00038369978 +491 266 2.739999e-05 +19 267 0.0012536999 +21 267 0.00041789981 +22 267 0.047221098 +24 267 0.0589219 +60 267 0.0058503971 +114 267 0.00041789981 +160 267 0.0025072999 +169 267 0.026744697 +192 267 0.0091934986 +193 267 0.026744697 +198 267 0.0071040988 +206 267 0.00041789981 +214 267 0.011282898 +220 267 0.0029251999 +233 267 0.0087755993 +234 267 0.015043899 +237 267 0.00041789981 +240 267 0.00083579984 +254 267 0.0020893998 +265 267 0.00041789981 +266 267 0.00083579984 +267 267 0.0033431 +270 267 0.00041789981 +272 267 0.0029251999 +273 267 0.0041788965 +275 267 0.00041789981 +277 267 0.0033431 +282 267 0.0016714998 +283 267 0.0016714998 +289 267 0.0016714998 +295 267 0.00041789981 +296 267 0.00041789981 +305 267 0.00041789981 +317 267 0.00041789981 +322 267 0.0025072999 +328 267 0.00041789981 +331 267 0.00083579984 +340 267 0.00083579984 +356 267 0.00041789981 +358 267 0.00041789981 +370 267 0.0016714998 +386 267 0.0104471 +402 267 0.0020893998 +417 267 0.00041789981 +443 267 0.042206399 +444 267 0.014208097 +445 267 0.028416198 +446 267 0.0041788965 +447 267 0.021729998 +450 267 0.0025072999 +452 267 0.032177199 +453 267 0.071040452 +454 267 0.0029251999 +455 267 0.021729998 +456 267 0.00083579984 +457 267 0.0025072999 +459 267 0.0012536999 +460 267 0.0020893998 +463 267 0.0075218976 +464 267 0.00083579984 +465 267 0.00041789981 +467 267 0.0071040988 +468 267 0.013790198 +469 267 0.0033431 +470 267 0.0029251999 +471 267 0.0041788965 +478 267 0.00083579984 +483 267 0.00083579984 +490 267 0.00041789981 +22 268 0.0059717 +24 268 0.097082376 +60 268 0.0092133991 +114 268 0.00017059999 +160 268 0.0078484975 +169 268 0.013137698 +188 268 0.085650861 +192 268 0.0061422996 +193 268 0.0324177 +206 268 0.0003411998 +214 268 0.00051189982 +220 268 0.00017059999 +223 268 0.0054597966 +231 268 0.0030711 +233 268 0.0059717 +234 268 0.0095546991 +237 268 0.00051189982 +240 268 0.00051189982 +241 268 0.0040948987 +242 268 0.0058010966 +254 268 0.0010237 +266 268 0.0063128993 +272 268 0.00085309986 +273 268 0.028322797 +276 268 0.00017059999 +277 268 0.0010237 +282 268 0.00068249996 +283 268 0.00017059999 +295 268 0.00017059999 +297 268 0.00017059999 +305 268 0.00017059999 +317 268 0.00017059999 +322 268 0.0003411998 +328 268 0.0010237 +331 268 0.0013649999 +332 268 0.0056303963 +335 268 0.0010237 +340 268 0.0018767999 +351 268 0.00051189982 +354 268 0.0010237 +356 268 0.0003411998 +358 268 0.00051189982 +372 268 0.00017059999 +384 268 0.00017059999 +402 268 0.00068249996 +417 268 0.00017059999 +443 268 0.030882098 +444 268 0.005289197 +445 268 0.034123898 +446 268 0.005289197 +447 268 0.0059717 +450 268 0.0022180998 +452 268 0.018768098 +453 268 0.026616599 +454 268 0.0022180998 +455 268 0.021497998 +456 268 0.00068249996 +457 268 0.0027298999 +459 268 0.00051189982 +460 268 0.0015355998 +463 268 0.010237198 +464 268 0.0068247989 +465 268 0.00017059999 +467 268 0.0066541992 +468 268 0.0059717 +469 268 0.0020474 +470 268 0.0022180998 +471 268 0.0035829998 +478 268 0.00051189982 +483 268 0.00051189982 +489 268 0.00017059999 +490 268 0.0003411998 +491 268 0.00017059999 +22 269 0.00033639977 +24 269 0.057853997 +60 269 0.0036999998 +114 269 0.00033639977 +126 269 0.00033639977 +160 269 0.0057180971 +188 269 0.0033635998 +193 269 0.051126797 +194 269 0.00033639977 +206 269 0.00067269988 +214 269 0.00033639977 +218 269 0.00033639977 +233 269 0.0043726973 +234 269 0.0063908994 +237 269 0.00067269988 +241 269 0.0016817998 +252 269 0.00033639977 +254 269 0.0026908999 +266 269 0.00033639977 +269 269 0.0084089972 +270 269 0.028254297 +272 269 0.0010090999 +276 269 0.016481698 +277 269 0.00067269988 +282 269 0.00033639977 +284 269 0.00033639977 +317 269 0.00033639977 +322 269 0.00067269988 +332 269 0.0023544999 +340 269 0.0010090999 +356 269 0.00033639977 +358 269 0.012781698 +386 269 0.0043726973 +417 269 0.00067269988 +443 269 0.0070635974 +444 269 0.0057180971 +445 269 0.043390498 +446 269 0.053481299 +447 269 0.0094180964 +450 269 0.0057180971 +452 269 0.013790797 +453 269 0.0013454 +454 269 0.0013454 +455 269 0.021190699 +456 269 0.00033639977 +457 269 0.0050453991 +458 269 0.00033639977 +459 269 0.00067269988 +460 269 0.0013454 +463 269 0.042045098 +464 269 0.0010090999 +465 269 0.0010090999 +467 269 0.011436298 +468 269 0.019172598 +469 269 0.0057180971 +470 269 0.0063908994 +471 269 0.016817998 +473 269 0.00033639977 +478 269 0.0016817998 +483 269 0.0020181998 +490 269 0.00067269988 +18 270 0.00022099999 +21 270 0.005857598 +22 270 0.00033159996 +24 270 0.014367796 +60 270 0.0045313984 +104 270 0.00066309981 +108 270 0.0001105 +114 270 0.0001105 +120 270 0.0001105 +126 270 0.0001105 +130 270 0.025640998 +131 270 0.016246699 +142 270 0.00022099999 +143 270 0.00033159996 +150 270 0.0001105 +160 270 0.00033159996 +169 270 0.0001105 +187 270 0.018346597 +188 270 0.0011051998 +189 270 0.00022099999 +190 270 0.0001105 +192 270 0.00055259978 +193 270 0.0022103998 +194 270 0.00022099999 +198 270 0.012599498 +203 270 0.0001105 +204 270 0.0001105 +206 270 0.00022099999 +208 270 0.0001105 +214 270 0.020004399 +219 270 0.024425298 +221 270 0.00066309981 +224 270 0.0081785992 +227 270 0.0020998998 +233 270 0.0001105 +234 270 0.0050839968 +237 270 0.00033159996 +240 270 0.00033159996 +241 270 0.0036471998 +242 270 0.0001105 +252 270 0.00022099999 +270 270 0.11063218 +273 270 0.0011051998 +277 270 0.0080680996 +282 270 0.0016577998 +283 270 0.00033159996 +284 270 0.00033159996 +285 270 0.0001105 +286 270 0.00033159996 +289 270 0.0062996969 +290 270 0.0013263 +292 270 0.00022099999 +293 270 0.00055259978 +294 270 0.002321 +296 270 0.0001105 +297 270 0.0001105 +307 270 0.0011051998 +312 270 0.00022099999 +317 270 0.0001105 +320 270 0.0001105 +321 270 0.00033159996 +322 270 0.00022099999 +324 270 0.00044209999 +325 270 0.0001105 +326 270 0.00022099999 +328 270 0.00022099999 +335 270 0.0001105 +338 270 0.00044209999 +339 270 0.0001105 +340 270 0.00055259978 +347 270 0.00033159996 +349 270 0.00088419998 +350 270 0.00044209999 +351 270 0.00044209999 +352 270 0.0001105 +354 270 0.0013263 +356 270 0.00033159996 +358 270 0.0028736 +371 270 0.0001105 +372 270 0.00066309981 +373 270 0.00077369995 +375 270 0.0011051998 +387 270 0.0001105 +393 270 0.0001105 +402 270 0.00033159996 +417 270 0.00033159996 +422 270 0.0001105 +424 270 0.0019893998 +430 270 0.0001105 +443 270 0.0087311976 +444 270 0.0011051998 +445 270 0.017020296 +446 270 0.0013263 +447 270 0.0097258985 +450 270 0.0035366998 +452 270 0.0099468976 +453 270 0.0032050998 +454 270 0.00099469977 +455 270 0.037577398 +456 270 0.00033159996 +457 270 0.0028736 +458 270 0.00088419998 +459 270 0.00033159996 +460 270 0.002321 +463 270 0.0172414 +464 270 0.00055259978 +465 270 0.00088419998 +467 270 0.0119363 +468 270 0.016799297 +469 270 0.0059681982 +470 270 0.0065207966 +471 270 0.0054155998 +473 270 0.0001105 +477 270 0.0001105 +478 270 0.0011051998 +483 270 0.0025419998 +490 270 0.00055259978 +491 270 0.0039787963 +4 271 0.0001318 +17 271 0.0017127998 +18 271 0.00026349979 +22 271 0.00065879989 +24 271 0.049407098 +60 271 0.0044795983 +108 271 0.0001318 +114 271 0.00026349979 +117 271 0.0001318 +118 271 0.0001318 +119 271 0.0042160973 +126 271 0.0001318 +130 271 0.00052699982 +135 271 0.00065879989 +160 271 0.0018445 +169 271 0.00026349979 +171 271 0.0023714998 +172 271 0.0038208 +186 271 0.0039525963 +189 271 0.0001318 +190 271 0.0001318 +191 271 0.0088273995 +192 271 0.0001318 +194 271 0.00026349979 +198 271 0.014360998 +203 271 0.0001318 +206 271 0.00026349979 +214 271 0.049143597 +219 271 0.032938097 +224 271 0.012121197 +225 271 0.00092229992 +227 271 0.0052700974 +234 271 0.016205497 +237 271 0.00026349979 +239 271 0.0001318 +240 271 0.0054017976 +241 271 0.027667999 +252 271 0.00026349979 +254 271 0.013043497 +267 271 0.0001318 +270 271 0.0014493 +271 271 0.0028986 +272 271 0.0001318 +273 271 0.0038208 +274 271 0.0001318 +276 271 0.0068510994 +277 271 0.0061923973 +282 271 0.0001318 +283 271 0.0001318 +284 271 0.00026349979 +285 271 0.0080368966 +300 271 0.0001318 +301 271 0.00039529987 +315 271 0.0060605966 +317 271 0.00026349979 +322 271 0.0043477975 +326 271 0.0001318 +328 271 0.0001318 +331 271 0.00026349979 +337 271 0.00026349979 +340 271 0.0001318 +349 271 0.0001318 +354 271 0.0001318 +356 271 0.00039529987 +358 271 0.0018445 +386 271 0.0047430992 +387 271 0.0001318 +417 271 0.00039529987 +422 271 0.00026349979 +434 271 0.0001318 +442 271 0.0038208 +443 271 0.015942 +444 271 0.0064558983 +445 271 0.058893297 +446 271 0.0035573 +447 271 0.0044795983 +448 271 0.0001318 +450 271 0.0035573 +452 271 0.011989497 +453 271 0.0054017976 +454 271 0.0018445 +455 271 0.027536198 +456 271 0.00026349979 +457 271 0.0038208 +458 271 0.00092229992 +459 271 0.00092229992 +460 271 0.0019762998 +463 271 0.0094861984 +464 271 0.0013174999 +465 271 0.0010539999 +467 271 0.0118577 +468 271 0.012252998 +469 271 0.0048747994 +470 271 0.0048747994 +471 271 0.002108 +473 271 0.0001318 +477 271 0.0001318 +478 271 0.0015809999 +483 271 0.0014493 +490 271 0.00052699982 +491 271 0.0046112984 +13 272 0.0001356 +18 272 0.00027109985 +21 272 0.0001356 +22 272 0.00027109985 +24 272 0.011522297 +25 272 0.0001356 +60 272 0.0020333 +82 272 0.00054219994 +108 272 0.0001356 +114 272 0.0001356 +119 272 0.00027109985 +120 272 0.00067779981 +126 272 0.0001356 +130 272 0.0035244999 +131 272 0.00040669995 +135 272 0.0085400976 +138 272 0.0001356 +140 272 0.00067779981 +143 272 0.0001356 +150 272 0.0001356 +160 272 0.0013555998 +161 272 0.0001356 +169 272 0.0001356 +171 272 0.06466037 +172 272 0.0001356 +186 272 0.0040666983 +187 272 0.0001356 +188 272 0.0001356 +189 272 0.0001356 +190 272 0.0001356 +191 272 0.056255899 +192 272 0.0001356 +193 272 0.00027109985 +194 272 0.00054219994 +197 272 0.0020333 +198 272 0.0126068 +200 272 0.0001356 +203 272 0.0001356 +204 272 0.0001356 +206 272 0.00027109985 +214 272 0.0094889998 +218 272 0.00040669995 +219 272 0.0044733994 +222 272 0.00081329979 +223 272 0.00067779981 +224 272 0.0036599999 +225 272 0.036057997 +227 272 0.0001356 +231 272 0.0001356 +233 272 0.0001356 +234 272 0.0066422969 +237 272 0.00040669995 +239 272 0.0048799999 +240 272 0.0032533999 +241 272 0.0044733994 +243 272 0.00067779981 +252 272 0.00027109985 +254 272 0.00054219994 +271 272 0.0070488974 +272 272 0.0028466999 +273 272 0.0010845 +274 272 0.0040666983 +276 272 0.00040669995 +277 272 0.0032533999 +279 272 0.00054219994 +282 272 0.0010845 +284 272 0.00040669995 +285 272 0.00040669995 +293 272 0.0001356 +301 272 0.00027109985 +312 272 0.0001356 +315 272 0.0014910998 +317 272 0.0001356 +319 272 0.00027109985 +322 272 0.00027109985 +326 272 0.00054219994 +340 272 0.00040669995 +349 272 0.00027109985 +356 272 0.00040669995 +358 272 0.0029821999 +386 272 0.00027109985 +387 272 0.0001356 +402 272 0.00027109985 +404 272 0.0001356 +414 272 0.0001356 +417 272 0.00054219994 +421 272 0.0001356 +422 272 0.0001356 +430 272 0.0001356 +434 272 0.0001356 +437 272 0.0001356 +442 272 0.0001356 +443 272 0.013284497 +444 272 0.00094889989 +445 272 0.035515796 +446 272 0.0027110998 +447 272 0.0014910998 +450 272 0.0046088994 +452 272 0.0085400976 +453 272 0.0020333 +454 272 0.00067779981 +455 272 0.0322624 +456 272 0.00054219994 +457 272 0.0028466999 +458 272 0.00081329979 +459 272 0.00054219994 +460 272 0.00122 +463 272 0.0070488974 +464 272 0.00067779981 +465 272 0.00122 +467 272 0.010573398 +468 272 0.0043377988 +469 272 0.0066422969 +470 272 0.0074555986 +471 272 0.00244 +473 272 0.0001356 +477 272 0.0001356 +478 272 0.0014910998 +483 272 0.0020333 +490 272 0.0040666983 +491 272 0.0010845 +19 273 0.014090497 +21 273 0.0002135 +22 273 0.0017078998 +23 273 0.00042699999 +24 273 0.075362861 +25 273 0.043552499 +60 273 0.0070452988 +114 273 0.0002135 +126 273 0.0002135 +160 273 0.0019214 +169 273 0.00042699999 +188 273 0.0034158998 +192 273 0.0002135 +193 273 0.013876997 +206 273 0.00042699999 +214 273 0.0215628 +215 273 0.0002135 +218 273 0.0002135 +220 273 0.0010674999 +223 273 0.0002135 +224 273 0.00064049987 +225 273 0.0002135 +231 273 0.0002135 +233 273 0.0002135 +234 273 0.0098206997 +237 273 0.0010674999 +241 273 0.0002135 +242 273 0.00042699999 +254 273 0.0029888998 +257 273 0.0002135 +266 273 0.0002135 +267 273 0.0017078998 +268 273 0.0002135 +270 273 0.00042699999 +273 273 0.047395397 +276 273 0.00085399998 +277 273 0.048676297 +282 273 0.0010674999 +283 273 0.0002135 +284 273 0.0002135 +295 273 0.0002135 +301 273 0.0002135 +305 273 0.0002135 +312 273 0.00064049987 +322 273 0.00064049987 +326 273 0.0002135 +328 273 0.0014944 +331 273 0.0023484 +332 273 0.0019214 +335 273 0.00042699999 +336 273 0.0002135 +337 273 0.0002135 +351 273 0.0002135 +354 273 0.0002135 +356 273 0.00042699999 +358 273 0.0010674999 +402 273 0.00042699999 +417 273 0.0002135 +442 273 0.0002135 +443 273 0.056789096 +444 273 0.00085399998 +445 273 0.058069997 +446 273 0.0053372979 +447 273 0.001281 +450 273 0.0021348998 +452 273 0.0213493 +453 273 0.019214299 +454 273 0.0027753999 +455 273 0.016865898 +456 273 0.00042699999 +457 273 0.0040563978 +458 273 0.0010674999 +459 273 0.0010674999 +460 273 0.0017078998 +463 273 0.0098206997 +464 273 0.0002135 +465 273 0.0002135 +467 273 0.011528596 +468 273 0.0014944 +469 273 0.0029888998 +470 273 0.0029888998 +471 273 0.0023484 +473 273 0.0002135 +478 273 0.00085399998 +483 273 0.00085399998 +489 273 0.00042699999 +490 273 0.00042699999 +491 273 0.00085399998 +18 274 0.00027009984 +21 274 0.00027009984 +22 274 0.00081029977 +24 274 0.010263298 +25 274 0.0054017976 +60 274 0.0035110998 +104 274 0.0024307999 +107 274 0.00054019992 +108 274 0.00013499999 +114 274 0.00027009984 +126 274 0.00013499999 +130 274 0.014989898 +159 274 0.0010803998 +160 274 0.0032410999 +169 274 0.00040509994 +171 274 0.00013499999 +186 274 0.0010803998 +187 274 0.0171506 +190 274 0.00013499999 +191 274 0.0033761 +192 274 0.0066171996 +193 274 0.011343699 +194 274 0.00013499999 +198 274 0.0094530992 +206 274 0.00027009984 +214 274 0.011073597 +219 274 0.0540176 +223 274 0.0059418976 +224 274 0.0239028 +225 274 0.0031059999 +231 274 0.00013499999 +233 274 0.00054019992 +234 274 0.0054017976 +237 274 0.00013499999 +241 274 0.031330198 +252 274 0.011748798 +254 274 0.00094529986 +257 274 0.00013499999 +265 274 0.00027009984 +266 274 0.00027009984 +267 274 0.0016204999 +270 274 0.0033761 +273 274 0.0094530992 +276 274 0.00013499999 +277 274 0.0059418976 +284 274 0.00027009984 +290 274 0.0013503998 +293 274 0.0118839 +322 274 0.013774499 +325 274 0.0082376972 +334 274 0.00013499999 +340 274 0.00013499999 +347 274 0.00013499999 +350 274 0.00054019992 +356 274 0.00040509994 +358 274 0.0017555999 +387 274 0.00013499999 +417 274 0.00027009984 +422 274 0.00013499999 +443 274 0.014449697 +444 274 0.0010803998 +445 274 0.0201215 +446 274 0.0018906 +447 274 0.0064820983 +450 274 0.0028358998 +452 274 0.019446298 +453 274 0.023092497 +454 274 0.0022956999 +455 274 0.034571197 +456 274 0.00027009984 +457 274 0.0029709998 +458 274 0.0010803998 +459 274 0.00067519979 +460 274 0.0012153999 +463 274 0.015529998 +464 274 0.00054019992 +465 274 0.00054019992 +467 274 0.0074273981 +468 274 0.0059418976 +469 274 0.0033761 +470 274 0.0037811999 +471 274 0.0014854998 +473 274 0.00013499999 +478 274 0.00081029977 +483 274 0.00081029977 +490 274 0.00040509994 +491 274 0.0081025995 +19 275 0.019535098 +21 275 0.012116697 +22 275 0.0039564967 +24 275 0.044263098 +25 275 0.0046982989 +60 275 0.0059346966 +114 275 0.0002472999 +120 275 0.0002472999 +126 275 0.0002472999 +130 275 0.00074179983 +131 275 0.00049459981 +160 275 0.0029673998 +169 275 0.0061819963 +187 275 0.0002472999 +192 275 0.0002472999 +193 275 0.0061819963 +198 275 0.0037091998 +206 275 0.00049459981 +214 275 0.010632999 +218 275 0.0002472999 +219 275 0.00074179983 +223 275 0.0002472999 +224 275 0.0027200999 +233 275 0.0002472999 +234 275 0.0044509992 +241 275 0.0002472999 +254 275 0.00049459981 +257 275 0.0024728 +267 275 0.0093965977 +270 275 0.0066765994 +273 275 0.064787269 +275 275 0.0064292997 +277 275 0.005687397 +284 275 0.0002472999 +289 275 0.022255197 +301 275 0.00049459981 +340 275 0.0002472999 +349 275 0.0022254998 +356 275 0.0002472999 +358 275 0.0014836998 +370 275 0.025717098 +386 275 0.0002472999 +417 275 0.0002472999 +443 275 0.051186897 +444 275 0.00074179983 +445 275 0.037091997 +446 275 0.0029673998 +447 275 0.0096438974 +450 275 0.0027200999 +452 275 0.015084099 +453 275 0.019287799 +454 275 0.00098909996 +455 275 0.017062299 +457 275 0.0027200999 +458 275 0.00049459981 +459 275 0.00049459981 +460 275 0.0017309999 +463 275 0.014836799 +464 275 0.00049459981 +465 275 0.0002472999 +467 275 0.0071710981 +468 275 0.0022254998 +469 275 0.0044509992 +470 275 0.0046982989 +471 275 0.0042037964 +473 275 0.0002472999 +478 275 0.00049459981 +483 275 0.00098909996 +490 275 0.00049459981 +491 275 0.0022254998 +21 276 0.00059769978 +24 276 0.0101614 +25 276 0.00059769978 +60 276 0.0023908999 +114 276 0.00059769978 +118 276 0.00059769978 +130 276 0.0017931999 +131 276 0.0011954999 +160 276 0.0011954999 +187 276 0.00059769978 +193 276 0.050806899 +198 276 0.0059772991 +206 276 0.00059769978 +214 276 0.023311399 +219 276 0.0041840971 +224 276 0.0035863998 +233 276 0.0059772991 +234 276 0.0059772991 +241 276 0.00059769978 +252 276 0.00059769978 +268 276 0.0203228 +270 276 0.0071726963 +272 276 0.00059769978 +273 276 0.0017931999 +276 276 0.083084285 +277 276 0.0017931999 +284 276 0.00059769978 +289 276 0.00059769978 +300 276 0.0017931999 +301 276 0.00059769978 +326 276 0.026300099 +340 276 0.0011954999 +356 276 0.00059769978 +358 276 0.0023908999 +417 276 0.00059769978 +443 276 0.011954598 +444 276 0.0101614 +445 276 0.022713698 +447 276 0.028690998 +450 276 0.0047817975 +452 276 0.011356797 +453 276 0.0173341 +454 276 0.0011954999 +455 276 0.034070499 +457 276 0.0029885999 +459 276 0.019724999 +460 276 0.00059769978 +463 276 0.037059199 +464 276 0.0011954999 +465 276 0.00059769978 +467 276 0.0083681978 +468 276 0.0029885999 +469 276 0.0053795986 +470 276 0.0053795986 +471 276 0.0029885999 +478 276 0.0011954999 +483 276 0.0017931999 +490 276 0.00059769978 +491 276 0.00059769978 +9 277 1.17e-05 +16 277 3.8999997e-06 +18 277 0.00011659999 +19 277 0.057920396 +21 277 0.00047409977 +22 277 0.027266096 +23 277 0.00014769999 +24 277 0.0018845999 +25 277 0.0011034999 +60 277 0.0140002 +66 277 1.5499987e-05 +79 277 3.8999997e-06 +82 277 1.17e-05 +83 277 7.7999994e-06 +84 277 7.7999994e-06 +108 277 1.9399988e-05 +113 277 1.9399988e-05 +114 277 6.6099994e-05 +126 277 2.7199989e-05 +127 277 3.8999997e-06 +150 277 0.00035749981 +151 277 2.7199989e-05 +153 277 1.17e-05 +154 277 0.0001127 +160 277 0.0020826999 +161 277 6.9899994e-05 +165 277 0.00057119993 +169 277 0.0011656999 +171 277 0.000101 +172 277 0.0002293 +183 277 0.00058669993 +189 277 6.6099994e-05 +190 277 6.6099994e-05 +192 277 1.5499987e-05 +194 277 4.269999e-05 +195 277 0.00039629987 +196 277 1.17e-05 +197 277 7.7999994e-06 +198 277 0.00054399995 +200 277 1.9399988e-05 +201 277 7.7999994e-06 +203 277 0.00034189993 +204 277 4.269999e-05 +206 277 0.00048179994 +207 277 2.3299988e-05 +209 277 7.7999994e-06 +214 277 0.020030897 +218 277 5.0499992e-05 +223 277 0.00064109988 +224 277 2.3299988e-05 +233 277 0.00048959977 +234 277 0.0049153976 +237 277 6.9899994e-05 +240 277 0.00048569986 +241 277 0.00042349985 +242 277 0.0002137 +248 277 7.7999994e-06 +250 277 3.8999997e-06 +251 277 4.6599991e-05 +252 277 0.00011659999 +262 277 3.8999997e-06 +263 277 3.8999997e-06 +267 277 0.0029958999 +270 277 0.0017990998 +272 277 0.00076159998 +273 277 0.0011463 +276 277 0.00013209999 +277 277 0.17267716 +278 277 0.019902598 +279 277 0.0001049 +280 277 0.00092479982 +281 277 1.9399988e-05 +282 277 0.012259398 +283 277 0.00037299981 +284 277 0.0022421 +285 277 3.8999997e-06 +286 277 0.00062949979 +287 277 0.00045849988 +288 277 0.0045229979 +289 277 0.0016786 +290 277 0.010495298 +291 277 0.0015153999 +292 277 0.00015149999 +293 277 0.000101 +294 277 1.5499987e-05 +295 277 0.0018728999 +296 277 7.7999994e-06 +297 277 3.499999e-05 +298 277 7.7999994e-06 +300 277 0.0001088 +301 277 0.00037299981 +302 277 0.00018259999 +303 277 0.0001127 +306 277 0.00032249978 +307 277 3.8999997e-06 +308 277 0.00033029984 +309 277 8.5499996e-05 +310 277 0.0004778998 +312 277 0.0068737976 +313 277 3.8999997e-06 +315 277 0.0018223999 +317 277 0.000101 +318 277 0.0001088 +319 277 0.00038859993 +320 277 0.0018145998 +321 277 0.0022926 +322 277 0.0019622999 +324 277 0.00086649996 +326 277 0.0067805983 +328 277 7.7999994e-06 +330 277 3.8999997e-06 +331 277 3.8999997e-06 +333 277 3.8999997e-06 +336 277 0.00024869991 +337 277 0.00083929999 +338 277 0.000101 +339 277 0.00012819999 +340 277 0.0039866976 +341 277 0.0001088 +342 277 0.00068779988 +343 277 0.00082379999 +349 277 0.00030309986 +350 277 0.0035593 +351 277 0.0033572998 +352 277 0.0021060999 +353 277 1.9399988e-05 +354 277 0.0045384988 +355 277 0.00036139996 +356 277 0.00042349985 +357 277 0.00012049999 +358 277 0.0026305998 +359 277 0.0014260998 +362 277 5.0499992e-05 +363 277 0.000101 +368 277 0.00013989999 +370 277 0.0017018998 +371 277 0.00058669993 +372 277 0.0001049 +373 277 0.00091309985 +374 277 0.00047019986 +375 277 0.0026655998 +376 277 0.00011659999 +380 277 3.8999997e-06 +384 277 0.0032017999 +385 277 0.00027199998 +386 277 0.00013989999 +387 277 3.1099989e-05 +393 277 3.8999997e-06 +394 277 3.8999997e-06 +395 277 0.00013599999 +397 277 3.8999997e-06 +402 277 3.1099989e-05 +404 277 2.3299988e-05 +408 277 0.00083929999 +409 277 4.269999e-05 +412 277 9.3299997e-05 +413 277 0.00062169996 +414 277 0.00082379999 +415 277 0.00017489999 +417 277 0.00024479977 +419 277 0.0001088 +421 277 0.00014379999 +422 277 3.8899991e-05 +423 277 3.8999997e-06 +425 277 3.8999997e-06 +430 277 1.9399988e-05 +431 277 7.7999994e-06 +432 277 7.7999994e-06 +433 277 1.9399988e-05 +434 277 2.3299988e-05 +438 277 0.00029139989 +441 277 0.00014769999 +442 277 8.9399997e-05 +443 277 0.037411597 +444 277 0.0020088998 +445 277 0.0133591 +446 277 0.008540798 +447 277 0.0046472996 +448 277 0.0002176 +449 277 3.8999997e-06 +450 277 0.0018106999 +452 277 0.016898997 +453 277 0.014497597 +454 277 0.0019701 +455 277 0.0368676 +456 277 0.00026809983 +457 277 0.0021448999 +458 277 0.00040019979 +459 277 0.00054009981 +460 277 0.0022964999 +463 277 0.0014648999 +464 277 0.0019583998 +465 277 0.00076159998 +467 277 0.011863098 +468 277 0.0030075 +469 277 0.0039866976 +470 277 0.0024518999 +471 277 0.0010064 +472 277 7.7699995e-05 +473 277 5.8299993e-05 +477 277 0.00042739999 +478 277 0.00067999982 +483 277 0.00083539984 +489 277 0.0014260998 +490 277 0.0001943 +491 277 0.019747198 +19 278 0.20604849 +21 278 0.032901298 +22 278 0.016118299 +24 278 0.026088398 +25 278 0.0001662 +60 278 0.0144566 +114 278 0.0001662 +130 278 0.00049849995 +131 278 0.00033229985 +160 278 0.0023263998 +169 278 0.0069790967 +172 278 0.00049849995 +187 278 0.0001662 +198 278 0.0001662 +206 278 0.00049849995 +214 278 0.0018277999 +219 278 0.00049849995 +223 278 0.00049849995 +224 278 0.0001662 +234 278 0.0021601999 +252 278 0.0001662 +267 278 0.00033229985 +270 278 0.0023263998 +272 278 0.00083079981 +273 278 0.0001662 +276 278 0.0069790967 +277 278 0.024426699 +278 278 0.010634799 +282 278 0.00099699991 +284 278 0.0019939998 +286 278 0.00049849995 +288 278 0.0011631998 +289 278 0.016949199 +290 278 0.027251597 +291 278 0.0001662 +295 278 0.0001662 +312 278 0.00049849995 +315 278 0.0001662 +320 278 0.0001662 +321 278 0.0001662 +322 278 0.0001662 +324 278 0.00049849995 +326 278 0.00033229985 +340 278 0.00033229985 +350 278 0.00033229985 +351 278 0.00033229985 +352 278 0.0001662 +354 278 0.00033229985 +355 278 0.00083079981 +356 278 0.0001662 +358 278 0.0011631998 +359 278 0.0001662 +375 278 0.028248597 +384 278 0.00033229985 +417 278 0.0001662 +443 278 0.023429699 +444 278 0.0084745996 +445 278 0.019773997 +446 278 0.0034894999 +447 278 0.0054834969 +450 278 0.0014954999 +452 278 0.086739779 +453 278 0.0034894999 +454 278 0.0053173974 +455 278 0.0224327 +457 278 0.0019939998 +459 278 0.00049849995 +460 278 0.0019939998 +463 278 0.0058158971 +464 278 0.0046526976 +465 278 0.00049849995 +467 278 0.016616799 +468 278 0.0084745996 +469 278 0.0023263998 +470 278 0.0021601999 +471 278 0.0001662 +478 278 0.00049849995 +483 278 0.00083079981 +489 278 0.0036556998 +490 278 0.0018277999 +491 278 0.013958097 +19 279 0.0188291 +21 279 0.00029419991 +22 279 0.0088260993 +24 279 0.0011767999 +25 279 0.00029419991 +60 279 0.0079434998 +160 279 0.0023536 +165 279 0.00029419991 +169 279 0.00029419991 +171 279 0.0029419998 +172 279 0.00029419991 +183 279 0.00029419991 +187 279 0.00029419991 +198 279 0.0067666993 +203 279 0.0026477999 +206 279 0.00029419991 +214 279 0.015592799 +223 279 0.017652299 +233 279 0.00029419991 +234 279 0.0047072992 +241 279 0.00088259997 +267 279 0.0035305 +270 279 0.00029419991 +272 279 0.00058839982 +273 279 0.00029419991 +277 279 0.22418356 +278 279 0.0064724982 +279 279 0.0055898987 +280 279 0.00029419991 +282 279 0.0038246999 +284 279 0.0044130981 +286 279 0.0082376972 +287 279 0.00058839982 +288 279 0.0061782971 +289 279 0.0011767999 +290 279 0.0035305 +291 279 0.00058839982 +293 279 0.00029419991 +295 279 0.0023536 +310 279 0.00029419991 +312 279 0.0067666993 +315 279 0.00058839982 +320 279 0.00058839982 +321 279 0.00058839982 +322 279 0.00058839982 +324 279 0.00058839982 +326 279 0.0035305 +337 279 0.00029419991 +340 279 0.029420398 +343 279 0.00029419991 +350 279 0.0032362 +351 279 0.0050014965 +352 279 0.00058839982 +354 279 0.0032362 +355 279 0.00029419991 +356 279 0.00029419991 +358 279 0.0017651999 +359 279 0.00058839982 +361 279 0.00029419991 +370 279 0.00029419991 +372 279 0.00029419991 +373 279 0.0011767999 +374 279 0.00058839982 +375 279 0.00088259997 +384 279 0.0011767999 +408 279 0.00029419991 +413 279 0.00029419991 +414 279 0.00029419991 +417 279 0.00029419991 +419 279 0.00029419991 +443 279 0.017652299 +444 279 0.0020593998 +445 279 0.0097086988 +446 279 0.0032362 +447 279 0.0038246999 +450 279 0.0020593998 +452 279 0.012650799 +453 279 0.0085318983 +454 279 0.0032362 +455 279 0.032656699 +456 279 0.00058839982 +457 279 0.0020593998 +458 279 0.00058839982 +459 279 0.00058839982 +460 279 0.0011767999 +463 279 0.0035305 +464 279 0.0026477999 +465 279 0.00088259997 +467 279 0.018240698 +468 279 0.0038246999 +469 279 0.0038246999 +470 279 0.0035305 +471 279 0.00058839982 +477 279 0.0020593998 +478 279 0.00088259997 +483 279 0.00088259997 +489 279 0.00058839982 +490 279 0.00029419991 +491 279 0.0064724982 +60 280 0.0054445975 +160 280 0.0018149 +169 280 0.0018149 +198 280 0.0018149 +203 280 0.0018149 +214 280 0.058076199 +234 280 0.0018149 +240 280 0.0036297999 +270 280 0.010889299 +277 280 0.44283116 +280 280 0.0054445975 +282 280 0.0072594993 +284 280 0.0018149 +290 280 0.010889299 +295 280 0.0018149 +312 280 0.010889299 +321 280 0.0054445975 +322 280 0.0054445975 +326 280 0.0272232 +342 280 0.0036297999 +350 280 0.0054445975 +351 280 0.0018149 +352 280 0.0090743974 +354 280 0.010889299 +358 280 0.010889299 +370 280 0.019963697 +373 280 0.0018149 +443 280 0.012704197 +444 280 0.0036297999 +445 280 0.010889299 +446 280 0.0018149 +447 280 0.0036297999 +450 280 0.0018149 +452 280 0.0072594993 +453 280 0.0054445975 +454 280 0.0036297999 +455 280 0.016333897 +457 280 0.0018149 +460 280 0.0036297999 +463 280 0.0036297999 +464 280 0.0018149 +467 280 0.025408298 +468 280 0.0018149 +469 280 0.0090743974 +470 280 0.0018149 +477 280 0.0018149 +60 281 0.0036100999 +160 281 0.0036100999 +169 281 0.0036100999 +214 281 0.07581228 +223 281 0.0072201975 +277 281 0.38267148 +282 281 0.010830298 +284 281 0.0036100999 +288 281 0.0072201975 +312 281 0.010830298 +320 281 0.0036100999 +321 281 0.0036100999 +324 281 0.0036100999 +326 281 0.0072201975 +340 281 0.0072201975 +349 281 0.0036100999 +350 281 0.0036100999 +351 281 0.0036100999 +354 281 0.018050499 +358 281 0.014440399 +370 281 0.010830298 +371 281 0.0072201975 +375 281 0.0036100999 +414 281 0.0036100999 +443 281 0.014440399 +444 281 0.0036100999 +445 281 0.010830298 +447 281 0.0036100999 +452 281 0.0072201975 +453 281 0.0072201975 +454 281 0.0036100999 +455 281 0.014440399 +457 281 0.0036100999 +460 281 0.0036100999 +463 281 0.0036100999 +464 281 0.0036100999 +467 281 0.0216606 +468 281 0.0036100999 +469 281 0.0036100999 +470 281 0.0036100999 +477 281 0.0036100999 +9 282 1.6999998e-05 +18 282 0.00015339999 +19 282 0.0019434998 +21 282 1.6999998e-05 +22 282 0.0018070999 +24 282 0.0056257993 +25 282 0.0003409998 +60 282 0.010058299 +77 282 1.6999998e-05 +78 282 0.00013639999 +79 282 1.6999998e-05 +82 282 1.6999998e-05 +83 282 1.6999998e-05 +84 282 1.6999998e-05 +98 282 1.6999998e-05 +104 282 0.00018749999 +108 282 1.6999998e-05 +113 282 3.4099998e-05 +114 282 8.5199994e-05 +126 282 5.1099996e-05 +127 282 1.6999998e-05 +134 282 6.8199995e-05 +150 282 0.00081829983 +151 282 1.6999998e-05 +156 282 0.00040919986 +158 282 0.00010229999 +159 282 3.4099998e-05 +160 282 0.0029662999 +161 282 1.6999998e-05 +162 282 1.6999998e-05 +165 282 3.4099998e-05 +169 282 0.00075009977 +170 282 1.6999998e-05 +171 282 8.5199994e-05 +172 282 0.0010910998 +181 282 8.5199994e-05 +183 282 1.6999998e-05 +189 282 6.8199995e-05 +190 282 0.00011929999 +192 282 3.4099998e-05 +194 282 0.00010229999 +195 282 1.6999998e-05 +196 282 1.6999998e-05 +197 282 1.6999998e-05 +198 282 0.0015001998 +200 282 3.4099998e-05 +201 282 3.4099998e-05 +203 282 5.1099996e-05 +204 282 8.5199994e-05 +206 282 0.00035799993 +207 282 5.1099996e-05 +209 282 1.6999998e-05 +214 282 0.00080129993 +218 282 3.4099998e-05 +219 282 5.1099996e-05 +223 282 0.0048415996 +224 282 1.6999998e-05 +233 282 0.00011929999 +234 282 0.0030685998 +236 282 1.6999998e-05 +237 282 0.00073309988 +240 282 0.00083539984 +241 282 0.00020459999 +242 282 0.00013639999 +248 282 1.6999998e-05 +250 282 1.6999998e-05 +252 282 0.0004602999 +267 282 0.00010229999 +270 282 0.0080124997 +271 282 1.6999998e-05 +272 282 0.0010058 +273 282 3.4099998e-05 +276 282 3.4099998e-05 +277 282 0.060400996 +278 282 0.022094198 +279 282 8.5199994e-05 +280 282 6.8199995e-05 +282 282 0.0060349964 +283 282 0.0023866999 +284 282 0.0077738985 +285 282 5.1099996e-05 +286 282 0.0027788 +287 282 0.00027279998 +288 282 0.0003409998 +289 282 0.001773 +290 282 0.0043983981 +291 282 5.1099996e-05 +292 282 0.00018749999 +293 282 0.00018749999 +294 282 0.00013639999 +295 282 6.8199995e-05 +296 282 0.00015339999 +297 282 0.00013639999 +298 282 8.5199994e-05 +299 282 3.4099998e-05 +301 282 1.6999998e-05 +304 282 5.1099996e-05 +305 282 1.6999998e-05 +306 282 1.6999998e-05 +307 282 0.00011929999 +308 282 1.6999998e-05 +310 282 1.6999998e-05 +312 282 0.00075009977 +313 282 0.0018070999 +315 282 0.00030689989 +319 282 0.00051139994 +320 282 8.5199994e-05 +321 282 6.8199995e-05 +322 282 0.00020459999 +323 282 0.00017049999 +324 282 0.00015339999 +326 282 0.00068189995 +328 282 0.0015683998 +329 282 0.00027279998 +330 282 5.1099996e-05 +331 282 0.00013639999 +332 282 1.6999998e-05 +333 282 1.6999998e-05 +335 282 3.4099998e-05 +337 282 3.4099998e-05 +338 282 0.00027279998 +339 282 6.8199995e-05 +340 282 0.0069215 +341 282 5.1099996e-05 +342 282 0.00011929999 +343 282 5.1099996e-05 +344 282 1.6999998e-05 +345 282 6.8199995e-05 +347 282 0.00010229999 +349 282 0.0036823999 +350 282 0.0004602999 +351 282 0.0012274999 +352 282 8.5199994e-05 +353 282 0.023509197 +354 282 0.012444999 +355 282 0.00013639999 +356 282 0.00030689989 +357 282 0.00020459999 +358 282 0.015632998 +359 282 5.1099996e-05 +366 282 0.00020459999 +370 282 1.6999998e-05 +371 282 6.8199995e-05 +372 282 0.00040919986 +373 282 0.0002387 +374 282 0.0024037999 +375 282 0.013689499 +384 282 0.00030689989 +385 282 0.00011929999 +386 282 1.6999998e-05 +387 282 0.00017049999 +392 282 1.6999998e-05 +394 282 8.5199994e-05 +397 282 0.00047729979 +399 282 5.1099996e-05 +401 282 0.00080129993 +402 282 0.0055234991 +408 282 0.0002387 +412 282 1.6999998e-05 +413 282 1.6999998e-05 +414 282 5.1099996e-05 +415 282 3.4099998e-05 +417 282 0.00054549985 +419 282 3.4099998e-05 +421 282 0.00032389979 +422 282 6.8199995e-05 +423 282 1.6999998e-05 +425 282 1.6999998e-05 +430 282 1.6999998e-05 +431 282 3.4099998e-05 +432 282 1.6999998e-05 +433 282 3.4099998e-05 +434 282 3.4099998e-05 +438 282 0.001432 +443 282 0.012922399 +444 282 0.0015513999 +445 282 0.010160599 +446 282 0.00098879985 +447 282 0.0035118998 +448 282 1.6999998e-05 +450 282 0.0040573999 +452 282 0.020269997 +453 282 0.0080806985 +454 282 0.0017217998 +455 282 0.049456198 +456 282 0.00049439981 +457 282 0.0048415996 +458 282 0.00093759992 +459 282 0.0013297 +460 282 0.0020458 +463 282 0.0021479998 +464 282 0.0012444998 +465 282 0.0010739998 +467 282 0.011405099 +468 282 0.0028640998 +469 282 0.0035289 +470 282 0.0038698998 +471 282 0.0017899999 +473 282 8.5199994e-05 +477 282 0.00010229999 +478 282 0.0012786 +483 282 0.00092059979 +489 282 0.00015339999 +490 282 0.0003409998 +491 282 0.035630297 +18 283 0.00010799999 +19 283 0.010635398 +21 283 0.00010799999 +22 283 0.0059924982 +24 283 0.00032389979 +25 283 0.0002159 +60 283 0.0078820996 +78 283 5.3999989e-05 +108 283 5.3999989e-05 +114 283 0.00010799999 +126 283 5.3999989e-05 +134 283 5.3999989e-05 +150 283 0.00010799999 +156 283 0.00032389979 +158 283 0.00010799999 +160 283 0.00032389979 +165 283 0.00010799999 +168 283 5.3999989e-05 +169 283 0.000162 +171 283 0.00037789997 +172 283 5.3999989e-05 +181 283 5.3999989e-05 +183 283 0.00010799999 +189 283 5.3999989e-05 +190 283 5.3999989e-05 +194 283 5.3999989e-05 +195 283 5.3999989e-05 +198 283 0.0025913999 +203 283 0.00010799999 +206 283 0.00048589986 +214 283 0.0026453999 +223 283 0.0002159 +224 283 0.0005398998 +229 283 0.00070179999 +233 283 0.0002159 +234 283 0.0054527 +237 283 0.00075579993 +240 283 0.0014036999 +241 283 0.0029153 +242 283 0.00043189991 +252 283 0.00037789997 +262 283 0.0002159 +267 283 0.0005398998 +270 283 0.0012416998 +271 283 0.000162 +272 283 0.00043189991 +273 283 0.0002159 +277 283 0.28499699 +278 283 0.0098795965 +279 283 0.00010799999 +280 283 0.00010799999 +282 283 0.0055606999 +283 283 0.0084758997 +284 283 0.0043189973 +286 283 0.00043189991 +287 283 0.00010799999 +288 283 0.00091779977 +289 283 0.0019975 +290 283 0.0017815998 +291 283 0.00026989984 +292 283 0.0021594998 +293 283 0.0025913999 +294 283 0.013766699 +295 283 0.00091779977 +296 283 0.00059389998 +297 283 0.00010799999 +298 283 5.3999989e-05 +299 283 0.000162 +301 283 5.3999989e-05 +302 283 5.3999989e-05 +305 283 5.3999989e-05 +306 283 5.3999989e-05 +307 283 5.3999989e-05 +308 283 5.3999989e-05 +310 283 0.00010799999 +312 283 0.0024293999 +313 283 0.0016196 +315 283 0.00097179995 +317 283 0.000162 +319 283 0.00048589986 +320 283 0.00091779977 +321 283 0.0051826984 +322 283 0.00064779981 +323 283 0.000162 +324 283 0.0027532999 +326 283 0.0051287971 +328 283 0.0010257999 +329 283 0.00048589986 +330 283 5.3999989e-05 +331 283 0.00032389979 +333 283 0.00086379983 +336 283 5.3999989e-05 +337 283 0.000162 +338 283 0.00075579993 +339 283 0.0010257999 +340 283 0.0131188 +341 283 5.3999989e-05 +342 283 0.000162 +343 283 0.0002159 +349 283 5.3999989e-05 +350 283 0.0010257999 +351 283 0.0025374 +352 283 0.00026989984 +353 283 5.3999989e-05 +354 283 0.0028072998 +355 283 0.00037789997 +356 283 0.00026989984 +357 283 0.00032389979 +358 283 0.0073961988 +359 283 0.00026989984 +366 283 0.00010799999 +370 283 0.00010799999 +371 283 0.0002159 +372 283 0.00010799999 +373 283 0.00032389979 +374 283 0.00010799999 +375 283 0.00048589986 +376 283 5.3999989e-05 +384 283 0.00070179999 +385 283 0.000162 +386 283 0.0011336999 +387 283 0.000162 +392 283 5.3999989e-05 +393 283 0.00010799999 +394 283 5.3999989e-05 +397 283 0.00048589986 +398 283 0.00010799999 +399 283 5.3999989e-05 +401 283 0.00059389998 +402 283 0.0053986982 +408 283 0.00032389979 +413 283 0.00010799999 +414 283 0.00010799999 +415 283 5.3999989e-05 +417 283 0.00032389979 +421 283 0.00010799999 +422 283 5.3999989e-05 +434 283 5.3999989e-05 +438 283 5.3999989e-05 +443 283 0.012093097 +444 283 0.0016196 +445 283 0.0080979988 +446 283 0.0023753999 +447 283 0.0028072998 +448 283 0.00010799999 +450 283 0.0022674999 +452 283 0.010419499 +453 283 0.012362998 +454 283 0.0014575999 +455 283 0.031312399 +456 283 0.0002159 +457 283 0.0022135 +458 283 0.00048589986 +459 283 0.00032389979 +460 283 0.0020514999 +463 283 0.0028612998 +464 283 0.00059389998 +465 283 0.00075579993 +467 283 0.011823099 +468 283 0.0018894998 +469 283 0.0031311999 +470 283 0.0031851998 +471 283 0.0010797 +473 283 5.3999989e-05 +477 283 0.00010799999 +478 283 0.00086379983 +483 283 0.00086379983 +489 283 0.00026989984 +490 283 0.00026989984 +491 283 0.0046428964 +60 284 0.0027506999 +114 284 0.0002116 +126 284 0.0002116 +190 284 0.0002116 +194 284 0.0002116 +206 284 0.00042319996 +214 284 0.0086753964 +218 284 0.0002116 +223 284 0.049513299 +233 284 0.0093101971 +234 284 0.018620398 +237 284 0.0002116 +240 284 0.0012695999 +241 284 0.0002116 +270 284 0.0002116 +272 284 0.0010579999 +277 284 0.055649597 +284 284 0.0080405995 +285 284 0.018197197 +286 284 0.0021159998 +287 284 0.0040202998 +288 284 0.00042319996 +289 284 0.0048666969 +290 284 0.018408798 +320 284 0.0019043998 +321 284 0.0002116 +354 284 0.0012695999 +355 284 0.0010579999 +356 284 0.0002116 +358 284 0.0029622999 +417 284 0.00063479994 +443 284 0.0050782971 +444 284 0.0019043998 +445 284 0.005924698 +446 284 0.00042319996 +447 284 0.0063478984 +450 284 0.0025390999 +452 284 0.027930599 +453 284 0.0247567 +454 284 0.0012695999 +455 284 0.015234899 +456 284 0.0027506999 +457 284 0.0016927999 +458 284 0.0010579999 +459 284 0.00063479994 +460 284 0.0014811999 +463 284 0.013753697 +464 284 0.00042319996 +465 284 0.00084639993 +467 284 0.0082521997 +468 284 0.0012695999 +469 284 0.0044434965 +470 284 0.0048666969 +471 284 0.0010579999 +473 284 0.0002116 +478 284 0.0012695999 +483 284 0.0012695999 +490 284 0.00063479994 +19 285 0.045200396 +20 285 0.0023298999 +21 285 0.0055917986 +24 285 0.00093199988 +25 285 0.00046599982 +60 285 0.0018638999 +114 285 0.000233 +169 285 0.00069899997 +171 285 0.019105297 +193 285 0.000233 +198 285 0.0067567974 +206 285 0.00069899997 +214 285 0.046365298 +223 285 0.00046599982 +224 285 0.00046599982 +225 285 0.000233 +234 285 0.0037278999 +240 285 0.0013978998 +241 285 0.0020968998 +270 285 0.00093199988 +272 285 0.0011649998 +273 285 0.00069899997 +276 285 0.000233 +277 285 0.0090866983 +278 285 0.00046599982 +279 285 0.000233 +282 285 0.0011649998 +284 285 0.0041937977 +285 285 0.0011649998 +286 285 0.023532197 +287 285 0.0044267997 +288 285 0.0039608963 +289 285 0.12744635 +290 285 0.038443599 +291 285 0.00069899997 +292 285 0.00046599982 +293 285 0.00046599982 +294 285 0.0016309 +295 285 0.046598297 +296 285 0.00069899997 +298 285 0.00069899997 +301 285 0.0072226971 +312 285 0.0011649998 +315 285 0.00046599982 +320 285 0.011882599 +321 285 0.012814499 +322 285 0.00046599982 +326 285 0.0018638999 +338 285 0.000233 +340 285 0.017707396 +351 285 0.00093199988 +354 285 0.010950599 +355 285 0.0011649998 +356 285 0.000233 +358 285 0.0032618998 +370 285 0.000233 +371 285 0.000233 +373 285 0.000233 +375 285 0.00069899997 +386 285 0.000233 +392 285 0.00046599982 +396 285 0.000233 +397 285 0.0039608963 +402 285 0.000233 +417 285 0.000233 +438 285 0.000233 +443 285 0.010950599 +444 285 0.0083876997 +445 285 0.0034949 +446 285 0.00046599982 +447 285 0.011416599 +450 285 0.0018638999 +452 285 0.017940398 +453 285 0.0097855963 +454 285 0.0016309 +455 285 0.018639296 +457 285 0.0023298999 +458 285 0.000233 +459 285 0.00069899997 +460 285 0.0016309 +463 285 0.016076397 +464 285 0.0011649998 +465 285 0.00046599982 +467 285 0.0067567974 +468 285 0.0020968998 +469 285 0.0032618998 +470 285 0.0023298999 +471 285 0.00093199988 +478 285 0.00046599982 +483 285 0.0013978998 +490 285 0.00046599982 +491 285 0.0018638999 +18 286 0.00028329995 +20 286 0.35669565 +22 286 0.00033999979 +60 286 0.00079319999 +108 286 2.8299997e-05 +114 286 5.6699995e-05 +126 286 5.6699995e-05 +150 286 2.8299997e-05 +151 286 2.8299997e-05 +160 286 5.6699995e-05 +169 286 2.8299997e-05 +172 286 2.8299997e-05 +189 286 2.8299997e-05 +190 286 5.6699995e-05 +194 286 5.6699995e-05 +198 286 5.6699995e-05 +206 286 0.00042489986 +214 286 0.0034844999 +218 286 2.8299997e-05 +223 286 0.00048159994 +224 286 2.8299997e-05 +233 286 2.8299997e-05 +234 286 0.0030311998 +237 286 2.8299997e-05 +240 286 0.00033999979 +241 286 0.00093489978 +242 286 2.8299997e-05 +252 286 5.6699995e-05 +262 286 2.8299997e-05 +267 286 0.00056659989 +272 286 0.00067989994 +277 286 0.0010481998 +282 286 5.6699995e-05 +283 286 2.8299997e-05 +284 286 0.00059489999 +285 286 0.0032578998 +286 286 0.36805576 +287 286 0.0034844999 +288 286 0.0054675974 +289 286 0.0016148 +290 286 0.016601 +291 286 0.0028612998 +292 286 0.00056659989 +293 286 5.6699995e-05 +294 286 5.6699995e-05 +295 286 0.00011329999 +296 286 2.8299997e-05 +312 286 8.4999992e-05 +315 286 5.6699995e-05 +317 286 0.00017 +318 286 0.00017 +319 286 2.8299997e-05 +320 286 2.8299997e-05 +321 286 5.6699995e-05 +324 286 0.0001983 +326 286 8.4999992e-05 +340 286 0.00033999979 +350 286 2.8299997e-05 +351 286 2.8299997e-05 +354 286 0.0014730999 +356 286 0.0001983 +358 286 0.0018696999 +373 286 2.8299997e-05 +375 286 0.0011047998 +386 286 0.00011329999 +387 286 2.8299997e-05 +417 286 0.00011329999 +443 286 0.013229799 +444 286 0.00042489986 +445 286 0.0018980999 +446 286 0.00033999979 +447 286 0.00045329984 +448 286 2.8299997e-05 +450 286 0.00084989984 +452 286 0.0044476986 +453 286 0.0058924966 +454 286 0.0011614999 +455 286 0.0246749 +456 286 0.0026629998 +457 286 0.0021529999 +458 286 0.00014159999 +459 286 0.00082159997 +460 286 0.0017563999 +463 286 0.0016997999 +464 286 0.00036829989 +465 286 0.00014159999 +467 286 0.0039094985 +468 286 0.0028328998 +469 286 0.0035128 +470 286 0.00082159997 +471 286 0.00045329984 +473 286 5.6699995e-05 +477 286 5.6699995e-05 +478 286 0.00022659999 +483 286 0.0001983 +489 286 0.00011329999 +490 286 8.4999992e-05 +491 286 0.050086398 +18 287 0.00073289988 +19 287 0.00043979986 +20 287 0.00043979986 +21 287 0.13559067 +22 287 0.00073289988 +60 287 0.0016123999 +206 287 0.0002931999 +214 287 0.021108199 +223 287 0.0016123999 +234 287 0.0087950975 +240 287 0.00087949983 +241 287 0.0051304996 +272 287 0.0002931999 +277 287 0.0083552971 +278 287 0.0001466 +284 287 0.0013192999 +285 287 0.012313098 +286 287 0.0095279999 +287 287 0.22339487 +288 287 0.015391398 +289 287 0.0086484998 +290 287 0.053649999 +291 287 0.0082086995 +317 287 0.00043979986 +318 287 0.00043979986 +326 287 0.0001466 +340 287 0.0014658 +353 287 0.0002931999 +354 287 0.0038111999 +356 287 0.0002931999 +358 287 0.0043974966 +375 287 0.0032249 +417 287 0.0001466 +443 287 0.028584 +444 287 0.0042509995 +445 287 0.0055701993 +446 287 0.00058629992 +447 287 0.005423598 +450 287 0.0014658 +452 287 0.0045440979 +453 287 0.0051304996 +454 287 0.0014658 +455 287 0.061125796 +456 287 0.0077689998 +457 287 0.0023453999 +458 287 0.0001466 +459 287 0.00058629992 +460 287 0.0026385 +463 287 0.0043974966 +464 287 0.0011727 +465 287 0.0001466 +467 287 0.0055701993 +468 287 0.0071825981 +469 287 0.0095279999 +470 287 0.0013192999 +471 287 0.00087949983 +478 287 0.0033713998 +483 287 0.00043979986 +489 287 0.0001466 +490 287 0.0010260998 +491 287 0.12826145 +18 288 0.00042659999 +20 288 0.0034129999 +21 288 0.24850678 +22 288 0.0055460967 +24 288 0.00021329999 +60 288 0.0021330998 +114 288 0.00021329999 +120 288 0.00021329999 +206 288 0.00063989987 +214 288 0.0153584 +223 288 0.0010666 +234 288 0.022397596 +240 288 0.00063989987 +241 288 0.0017064998 +272 288 0.00063989987 +277 288 0.0076791979 +284 288 0.0014932 +285 288 0.0066125989 +286 288 0.010025598 +287 288 0.015571699 +288 288 0.070392489 +289 288 0.0029862998 +290 288 0.052687697 +291 288 0.0057593994 +317 288 0.00042659999 +318 288 0.00042659999 +324 288 0.00021329999 +340 288 0.00063989987 +354 288 0.0025596998 +356 288 0.00021329999 +358 288 0.0038395999 +375 288 0.0021330998 +417 288 0.00021329999 +443 288 0.036262799 +444 288 0.0012798999 +445 288 0.016638197 +446 288 0.0012798999 +447 288 0.0070391968 +450 288 0.0021330998 +452 288 0.012158699 +453 288 0.012585297 +454 288 0.011732098 +455 288 0.0505546 +456 288 0.0053327978 +457 288 0.0025596998 +458 288 0.00021329999 +459 288 0.00085319998 +460 288 0.0023463999 +463 288 0.0104522 +464 288 0.00085319998 +465 288 0.00021329999 +467 288 0.0068258978 +468 288 0.0049060993 +469 288 0.007465899 +470 288 0.0019197999 +471 288 0.00063989987 +478 288 0.00063989987 +483 288 0.00085319998 +489 288 0.0023463999 +490 288 0.00021329999 +491 288 0.10025597 +18 289 0.0012138998 +19 289 3.6799989e-05 +21 289 0.052896798 +22 289 0.0012874999 +60 289 0.010630898 +114 289 7.3599993e-05 +126 289 3.6799989e-05 +150 289 3.6799989e-05 +151 289 0.0015449999 +160 289 0.00022069999 +169 289 7.3599993e-05 +172 289 0.00025749998 +190 289 3.6799989e-05 +194 289 3.6799989e-05 +198 289 0.0001104 +206 289 0.00058859983 +214 289 0.044436298 +223 289 0.00099319988 +233 289 0.0002942998 +234 289 0.016442899 +237 289 7.3599993e-05 +240 289 0.00033109984 +241 289 0.0045612976 +242 289 0.0001471 +251 289 3.6799989e-05 +252 289 3.6799989e-05 +267 289 0.0018391998 +272 289 0.00088279997 +277 289 0.00022069999 +278 289 0.0041198991 +282 289 0.0001104 +284 289 0.00091959978 +285 289 0.0034945998 +286 289 0.0049291998 +287 289 0.0037152998 +288 289 0.0085340999 +289 289 0.19466615 +290 289 0.0337318 +291 289 0.0031266999 +292 289 3.6799989e-05 +293 289 0.0064741969 +295 289 0.0036416999 +312 289 0.0001471 +315 289 3.6799989e-05 +317 289 0.0011034999 +318 289 0.00018389999 +319 289 3.6799989e-05 +321 289 0.00018389999 +322 289 3.6799989e-05 +324 289 0.00033109984 +326 289 0.00091959978 +337 289 0.00084609981 +340 289 0.0018024999 +350 289 0.00084609981 +351 289 0.0001104 +354 289 0.0016921 +356 289 0.00018389999 +358 289 0.0022070999 +370 289 0.0053705983 +371 289 0.0029059998 +373 289 7.3599993e-05 +375 289 0.0057751983 +384 289 7.3599993e-05 +386 289 0.0010668 +404 289 7.3599993e-05 +417 289 0.00018389999 +421 289 7.3599993e-05 +422 289 3.6799989e-05 +438 289 3.6799989e-05 +443 289 0.025859799 +444 289 0.0022806998 +445 289 0.0068051964 +446 289 0.0015817999 +447 289 0.0015081998 +450 289 0.0026852998 +452 289 0.073643565 +453 289 0.011955097 +454 289 0.0031635 +455 289 0.037814997 +456 289 0.0028692 +457 289 0.0068419985 +458 289 0.00055179978 +459 289 0.00095639983 +460 289 0.0023542 +463 289 0.0049659982 +464 289 0.0018391998 +465 289 0.00033109984 +467 289 0.0082397982 +468 289 0.0020599999 +469 289 0.012139 +470 289 0.00099319988 +471 289 0.00069889985 +473 289 3.6799989e-05 +477 289 0.0001104 +478 289 0.00044139987 +483 289 0.00033109984 +489 289 0.00058859983 +490 289 0.00018389999 +491 289 0.045907699 +18 290 0.00068219984 +19 290 0.0074187964 +20 290 0.0902192 +21 290 0.093459487 +22 290 0.00025579985 +24 290 8.5299995e-05 +25 290 0.00025579985 +60 290 0.0014495999 +114 290 8.5299995e-05 +160 290 8.5299995e-05 +171 290 8.5299995e-05 +198 290 0.00025579985 +206 290 0.00068219984 +214 290 0.015519697 +223 290 0.0013643999 +233 290 8.5299995e-05 +234 290 0.0039225966 +240 290 0.00085269986 +241 290 0.0031550999 +242 290 8.5299995e-05 +267 290 0.00068219984 +270 290 8.5299995e-05 +272 290 0.00059689977 +276 290 0.00017049999 +277 290 0.0020466 +278 290 0.0038373 +282 290 8.5299995e-05 +284 290 0.0010233 +285 290 0.008953698 +286 290 0.10701799 +287 290 0.037349697 +288 290 0.023535397 +289 290 0.0050310977 +290 290 0.067280591 +291 290 0.0081009977 +292 290 0.00034109992 +294 290 8.5299995e-05 +295 290 0.00017049999 +312 290 0.00017049999 +315 290 8.5299995e-05 +317 290 0.00042639999 +318 290 0.00051159994 +320 290 8.5299995e-05 +321 290 0.00025579985 +324 290 0.00025579985 +326 290 0.00085269986 +340 290 0.0017054998 +349 290 8.5299995e-05 +350 290 8.5299995e-05 +351 290 0.00034109992 +353 290 8.5299995e-05 +354 290 0.0036668 +356 290 8.5299995e-05 +358 290 0.0047752969 +373 290 8.5299995e-05 +375 290 0.0030697999 +386 290 8.5299995e-05 +417 290 8.5299995e-05 +438 290 8.5299995e-05 +442 290 8.5299995e-05 +443 290 0.018248498 +444 290 0.0034108998 +445 290 0.0043488964 +446 290 0.00059689977 +447 290 0.0045194998 +450 290 0.0017906998 +452 290 0.016542997 +453 290 0.0070776977 +454 290 0.0019612999 +455 290 0.060288198 +456 290 0.0070776977 +457 290 0.0023876999 +458 290 0.00025579985 +459 290 0.00093799992 +460 290 0.0032404 +463 290 0.0071629994 +464 290 0.0011085998 +465 290 0.00017049999 +467 290 0.0066512972 +468 290 0.0061396994 +469 290 0.0092947967 +470 290 0.0018759998 +471 290 0.0010233 +478 290 0.00068219984 +483 290 0.00034109992 +489 290 0.0013643999 +490 290 0.0119383 +491 290 0.11469257 +18 291 0.0017605999 +60 291 0.00088029983 +214 291 0.024647899 +223 291 0.0035210999 +234 291 0.0026407999 +240 291 0.0026407999 +241 291 0.005281698 +277 291 0.00088029983 +284 291 0.00088029983 +285 291 0.023767598 +286 291 0.022007 +287 291 0.0255282 +288 291 0.036091499 +289 291 0.0105634 +290 291 0.073063374 +291 291 0.021126799 +317 291 0.00088029983 +318 291 0.00088029983 +340 291 0.00088029983 +354 291 0.0096830986 +358 291 0.0096830986 +375 291 0.0079224966 +443 291 0.0255282 +444 291 0.0026407999 +445 291 0.005281698 +446 291 0.00088029983 +447 291 0.0017605999 +450 291 0.0026407999 +452 291 0.004401397 +453 291 0.006161999 +454 291 0.0017605999 +455 291 0.12147886 +456 291 0.019366197 +457 291 0.0026407999 +459 291 0.00088029983 +460 291 0.004401397 +463 291 0.0079224966 +464 291 0.0017605999 +467 291 0.0088027976 +468 291 0.0017605999 +469 291 0.022007 +470 291 0.0026407999 +471 291 0.0026407999 +483 291 0.00088029983 +491 291 0.29577458 +18 292 0.00013619999 +22 292 0.00013619999 +60 292 0.0013275 +108 292 3.3999997e-05 +114 292 6.8099995e-05 +126 292 3.3999997e-05 +131 292 0.00010209999 +132 292 0.00013619999 +139 292 0.00010209999 +151 292 6.8099995e-05 +160 292 0.0036761998 +161 292 0.00030639977 +169 292 0.0012593998 +171 292 0.00071479985 +172 292 0.00078289979 +187 292 0.00010209999 +189 292 3.3999997e-05 +190 292 3.3999997e-05 +194 292 6.8099995e-05 +197 292 6.8099995e-05 +198 292 0.0010211999 +200 292 3.3999997e-05 +203 292 3.3999997e-05 +204 292 3.3999997e-05 +206 292 6.8099995e-05 +214 292 0.0066375993 +223 292 0.00037439982 +224 292 0.0015997998 +225 292 0.00027229986 +233 292 0.0021784999 +234 292 0.0021103998 +237 292 6.8099995e-05 +240 292 0.00017019999 +241 292 0.0066716969 +242 292 0.0011572998 +251 292 3.3999997e-05 +252 292 0.00017019999 +270 292 6.8099995e-05 +271 292 3.3999997e-05 +272 292 0.00047649979 +276 292 0.00010209999 +277 292 0.00068079983 +278 292 3.3999997e-05 +279 292 3.3999997e-05 +282 292 0.0021784999 +283 292 0.00017019999 +284 292 0.0017019999 +285 292 0.00098709995 +286 292 0.37371498 +287 292 0.0010892998 +288 292 0.026550498 +289 292 0.0080331974 +290 292 0.021274399 +291 292 0.0012253998 +292 292 0.033256199 +293 292 0.0046973974 +294 292 0.0002383 +295 292 0.0066375993 +297 292 3.3999997e-05 +299 292 3.3999997e-05 +308 292 0.00010209999 +312 292 0.0016678998 +315 292 0.0012935 +317 292 6.8099995e-05 +318 292 3.3999997e-05 +319 292 0.0013615999 +320 292 3.3999997e-05 +321 292 0.0011232998 +326 292 0.0051398985 +327 292 3.3999997e-05 +337 292 6.8099995e-05 +340 292 0.0070119984 +350 292 0.00078289979 +351 292 0.0010551999 +354 292 0.0056163967 +358 292 0.0012935 +369 292 3.3999997e-05 +370 292 3.3999997e-05 +371 292 6.8099995e-05 +372 292 0.00010209999 +373 292 0.0017019999 +375 292 3.3999997e-05 +376 292 3.3999997e-05 +386 292 0.0014976999 +387 292 3.3999997e-05 +389 292 0.00037439982 +390 292 6.8099995e-05 +392 292 0.00017019999 +393 292 0.0003403998 +417 292 0.0002042 +421 292 6.8099995e-05 +422 292 6.8099995e-05 +438 292 3.3999997e-05 +443 292 0.014977198 +444 292 0.0013955999 +445 292 0.0037443 +446 292 0.00047649979 +447 292 0.0014295999 +450 292 0.0013615999 +452 292 0.0085437968 +453 292 0.0037103 +454 292 0.0028932998 +455 292 0.0584451 +456 292 0.00010209999 +457 292 0.0024848999 +458 292 0.00040849997 +459 292 0.00078289979 +460 292 0.0014976999 +463 292 0.0049356967 +464 292 0.0012593998 +465 292 0.00051059993 +467 292 0.0099053979 +468 292 0.0039825998 +469 292 0.0020082998 +470 292 0.0016678998 +471 292 0.0018720999 +473 292 3.3999997e-05 +477 292 6.8099995e-05 +478 292 0.00051059993 +483 292 0.00071479985 +489 292 0.00010209999 +490 292 0.00017019999 +491 292 0.11202258 +18 293 0.00016649999 +19 293 5.5499986e-05 +21 293 0.0014149998 +22 293 0.00027739978 +60 293 0.0024138 +108 293 2.7699993e-05 +114 293 5.5499986e-05 +126 293 2.7699993e-05 +130 293 2.7699993e-05 +131 293 2.7699993e-05 +132 293 2.7699993e-05 +139 293 2.7699993e-05 +150 293 0.00033289986 +151 293 5.5499986e-05 +160 293 0.0029131998 +169 293 0.0010543 +171 293 0.00038839993 +172 293 0.0037455 +187 293 5.5499986e-05 +189 293 2.7699993e-05 +190 293 5.5499986e-05 +192 293 2.7699993e-05 +194 293 5.5499986e-05 +197 293 2.7699993e-05 +198 293 0.0018865999 +200 293 2.7699993e-05 +203 293 2.7699993e-05 +204 293 0.00022199999 +206 293 0.00033289986 +207 293 2.7699993e-05 +214 293 0.005105 +223 293 0.0010819999 +224 293 0.0007491 +225 293 8.3199993e-05 +233 293 0.0039674975 +234 293 0.0018865999 +237 293 8.3199993e-05 +240 293 8.3199993e-05 +241 293 0.0051327981 +242 293 0.0021917999 +251 293 2.7699993e-05 +252 293 0.00033289986 +267 293 5.5499986e-05 +270 293 2.7699993e-05 +271 293 2.7699993e-05 +272 293 0.00066589983 +276 293 2.7699993e-05 +277 293 0.0011652999 +278 293 0.0023859998 +279 293 0.00022199999 +282 293 0.0018034 +284 293 0.0021640998 +285 293 0.0012208 +286 293 0.010015797 +287 293 0.0011097998 +288 293 0.0030242 +289 293 0.40240818 +290 293 0.016147397 +291 293 0.0022195999 +292 293 0.0029964 +293 293 0.091806948 +294 293 5.5499986e-05 +295 293 0.0038564999 +297 293 2.7699993e-05 +312 293 0.0022751 +315 293 0.00080459984 +317 293 0.0013595 +318 293 0.00013869999 +319 293 0.00083229993 +321 293 0.0025247999 +322 293 0.00063809985 +324 293 2.7699993e-05 +326 293 0.0047720969 +337 293 0.0016368998 +340 293 0.0077961981 +350 293 8.3199993e-05 +351 293 0.0017756999 +354 293 0.0043003969 +356 293 0.00016649999 +358 293 0.0013316998 +370 293 0.00013869999 +371 293 0.00011099999 +373 293 0.0011374999 +375 293 0.00011099999 +384 293 5.5499986e-05 +386 293 0.00077679986 +387 293 2.7699993e-05 +401 293 2.7699993e-05 +402 293 2.7699993e-05 +408 293 2.7699993e-05 +417 293 0.00024969992 +421 293 5.5499986e-05 +422 293 2.7699993e-05 +433 293 2.7699993e-05 +434 293 2.7699993e-05 +438 293 0.00066589983 +443 293 0.013594899 +444 293 0.0012762998 +445 293 0.0055488981 +446 293 0.0003052 +447 293 0.0011097998 +450 293 0.001526 +452 293 0.013039999 +453 293 0.0095718987 +454 293 0.00099879992 +455 293 0.032100499 +456 293 0.00013869999 +457 293 0.0025803 +458 293 0.0012484998 +459 293 0.00086009991 +460 293 0.0016923998 +463 293 0.0021917999 +464 293 0.00083229993 +465 293 0.00041619991 +467 293 0.0076574981 +468 293 0.0065476969 +469 293 0.0029964 +470 293 0.0011374999 +471 293 0.0017756999 +473 293 2.7699993e-05 +477 293 0.00083229993 +478 293 0.00055489992 +483 293 0.00055489992 +489 293 8.3199993e-05 +490 293 0.00013869999 +491 293 0.029575799 +19 294 0.00075719994 +21 294 0.0019876999 +22 294 0.0004733 +60 294 0.0020822999 +108 294 9.4699993e-05 +114 294 0.00018929999 +126 294 9.4699993e-05 +160 294 0.0020822999 +189 294 9.4699993e-05 +190 294 9.4699993e-05 +194 294 9.4699993e-05 +198 294 0.0038806999 +206 294 0.00018929999 +214 294 0.027354497 +223 294 0.0021769998 +224 294 9.4699993e-05 +233 294 0.0020822999 +234 294 0.0015143999 +237 294 9.4699993e-05 +240 294 9.4699993e-05 +241 294 0.015333597 +242 294 0.0021769998 +252 294 9.4699993e-05 +272 294 0.0004733 +277 294 0.0032181998 +278 294 0.005584497 +282 294 0.0022717 +284 294 0.0015143999 +285 294 0.00028399983 +286 294 0.020350199 +287 294 0.023284398 +288 294 0.017415997 +289 294 0.0070988983 +290 294 0.42953146 +291 294 0.013724599 +292 294 0.0015143999 +293 294 0.0017036998 +294 294 0.0032181998 +295 294 0.00066259992 +312 294 0.0031234999 +315 294 0.0025555999 +317 294 9.4699993e-05 +318 294 9.4699993e-05 +320 294 9.4699993e-05 +321 294 0.0037860998 +322 294 9.4699993e-05 +326 294 0.014860399 +337 294 9.4699993e-05 +340 294 0.0107903 +350 294 0.0021769998 +351 294 0.005584497 +353 294 9.4699993e-05 +354 294 0.0023663 +356 294 0.00028399983 +358 294 0.0078560971 +373 294 0.0011357998 +375 294 0.00018929999 +386 294 0.0034075 +387 294 9.4699993e-05 +389 294 0.0019876999 +390 294 0.00037859986 +391 294 9.4699993e-05 +392 294 0.00085189985 +393 294 0.0010411998 +397 294 0.00028399983 +398 294 9.4699993e-05 +417 294 0.00028399983 +438 294 0.0029342 +442 294 0.0019876999 +443 294 0.0073828995 +444 294 0.0035020998 +445 294 0.0042592995 +446 294 0.00037859986 +447 294 0.0043539964 +450 294 0.0016090998 +452 294 0.0086132996 +453 294 0.0043539964 +454 294 0.0024609999 +455 294 0.022148598 +456 294 0.00028399983 +457 294 0.0025555999 +458 294 0.0004733 +459 294 0.00085189985 +460 294 0.0017984 +463 294 0.010317098 +464 294 0.0027448998 +465 294 0.0004733 +467 294 0.012588698 +468 294 0.0035020998 +469 294 0.0039753988 +470 294 0.0025555999 +471 294 0.0036913999 +473 294 9.4699993e-05 +477 294 0.00094649987 +478 294 0.00056789978 +483 294 0.00094649987 +490 294 0.00037859986 +491 294 0.0088972971 +9 295 2.2199994e-05 +18 295 0.00057599996 +19 295 4.4299988e-05 +21 295 2.2199994e-05 +22 295 8.8599991e-05 +25 295 2.2199994e-05 +60 295 0.0013956998 +82 295 2.2199994e-05 +83 295 2.2199994e-05 +84 295 2.2199994e-05 +108 295 2.2199994e-05 +113 295 4.4299988e-05 +114 295 4.4299988e-05 +126 295 2.2199994e-05 +130 295 2.2199994e-05 +131 295 0.0021046 +132 295 0.0025919999 +139 295 0.002016 +150 295 0.00033229985 +151 295 0.00042089983 +160 295 0.0026805999 +169 295 0.0011298 +171 295 0.0095925964 +172 295 0.00064249989 +187 295 0.0022153999 +189 295 4.4299988e-05 +190 295 4.4299988e-05 +194 295 6.6499997e-05 +197 295 0.0016393999 +198 295 0.0036774999 +200 295 2.2199994e-05 +203 295 4.4299988e-05 +204 295 4.4299988e-05 +206 295 4.4299988e-05 +207 295 2.2199994e-05 +214 295 0.010855399 +215 295 2.2199994e-05 +223 295 0.0015064999 +224 295 0.031945799 +225 295 0.005471997 +233 295 0.0016615 +234 295 0.0022374999 +237 295 6.6499997e-05 +240 295 0.0018608999 +241 295 0.010434397 +242 295 0.00062029995 +252 295 0.002016 +262 295 2.2199994e-05 +270 295 0.0015729 +271 295 0.0010854998 +272 295 0.00066459994 +276 295 0.0021488999 +277 295 0.0036553999 +278 295 0.00013289999 +279 295 0.00019939999 +282 295 0.00086399983 +283 295 0.0002215 +284 295 0.0015507999 +285 295 4.4299988e-05 +286 295 0.10673696 +287 295 0.0064023994 +288 295 0.0027027999 +289 295 0.0173021 +290 295 0.0081746988 +291 295 0.00026579993 +292 295 0.1619221 +293 295 0.0580872 +294 295 0.0038547998 +295 295 0.082389951 +296 295 0.0001772 +297 295 2.2199994e-05 +298 295 2.2199994e-05 +312 295 0.0022596999 +313 295 0.0001108 +315 295 0.0004431 +317 295 0.00090829981 +319 295 4.4299988e-05 +320 295 0.0001772 +321 295 0.0044971965 +322 295 6.6499997e-05 +324 295 2.2199994e-05 +326 295 0.0060700998 +328 295 2.2199994e-05 +337 295 0.0007974999 +340 295 0.0066682994 +349 295 2.2199994e-05 +350 295 0.0010411998 +351 295 0.0021267999 +354 295 0.0040097982 +356 295 0.00019939999 +357 295 6.6499997e-05 +358 295 0.0015950999 +370 295 0.00057599996 +371 295 0.00097479997 +372 295 0.00066459994 +373 295 0.0010411998 +375 295 0.00050949981 +376 295 2.2199994e-05 +380 295 2.2199994e-05 +384 295 0.00015509999 +386 295 0.0022374999 +387 295 2.2199994e-05 +390 295 6.6499997e-05 +391 295 2.2199994e-05 +392 295 0.0001772 +393 295 0.00035449979 +397 295 0.00024369999 +398 295 0.0007974999 +402 295 0.00048739999 +417 295 0.00024369999 +421 295 4.4299988e-05 +422 295 4.4299988e-05 +423 295 2.2199994e-05 +430 295 2.2199994e-05 +431 295 2.2199994e-05 +433 295 2.2199994e-05 +434 295 2.2199994e-05 +438 295 6.6499997e-05 +442 295 2.2199994e-05 +443 295 0.0076651983 +444 295 0.0012627998 +445 295 0.0082190968 +446 295 0.00073109986 +447 295 0.0027470998 +448 295 2.2199994e-05 +450 295 0.0028799998 +452 295 0.0079974979 +453 295 0.0021931999 +454 295 0.0014842998 +455 295 0.042003598 +456 295 0.00013289999 +457 295 0.0034337998 +458 295 0.00033229985 +459 295 0.00090829981 +460 295 0.0016615 +463 295 0.0047187991 +464 295 0.0011298 +465 295 0.00050949981 +467 295 0.0081968978 +468 295 0.0052725971 +469 295 0.0068897977 +470 295 0.0023260999 +471 295 0.002016 +473 295 4.4299988e-05 +477 295 0.0007974999 +478 295 0.00057599996 +483 295 0.00075319991 +489 295 4.4299988e-05 +490 295 0.00099689979 +491 295 0.0029020999 +9 296 8.4599989e-05 +18 296 0.00016919999 +21 296 0.00016919999 +24 296 0.0012687999 +60 296 0.013703298 +82 296 8.4599989e-05 +83 296 8.4599989e-05 +84 296 8.4599989e-05 +104 296 0.00016919999 +108 296 8.4599989e-05 +113 296 0.00016919999 +114 296 0.00033839978 +126 296 0.00016919999 +150 296 0.00059209997 +160 296 0.00016919999 +189 296 8.4599989e-05 +190 296 8.4599989e-05 +194 296 0.00016919999 +198 296 0.0036372999 +200 296 8.4599989e-05 +203 296 8.4599989e-05 +204 296 8.4599989e-05 +206 296 0.00016919999 +214 296 0.0014379998 +223 296 0.0047368966 +224 296 8.4599989e-05 +234 296 0.0025376 +237 296 0.00025379984 +241 296 0.0038065 +242 296 8.4599989e-05 +252 296 0.00025379984 +268 296 0.0016917998 +270 296 0.00042289984 +272 296 0.00059209997 +276 296 0.00059209997 +277 296 0.0035526999 +278 296 0.0020301 +279 296 0.00016919999 +282 296 0.0011841999 +283 296 8.4599989e-05 +284 296 0.0028759998 +286 296 0.014887497 +287 296 0.00016919999 +288 296 0.023600098 +289 296 0.21324646 +290 296 0.0032988999 +291 296 8.4599989e-05 +293 296 0.00016919999 +294 296 0.00016919999 +295 296 0.00016919999 +296 296 0.0014379998 +297 296 0.00025379984 +298 296 0.00025379984 +312 296 0.00059209997 +315 296 0.00016919999 +320 296 8.4599989e-05 +326 296 0.0065978989 +328 296 0.00059209997 +329 296 8.4599989e-05 +339 296 0.0016917998 +340 296 0.036372896 +341 296 8.4599989e-05 +349 296 8.4599989e-05 +350 296 0.00016919999 +351 296 0.00042289984 +353 296 0.014295399 +354 296 0.00033839978 +356 296 0.00025379984 +357 296 8.4599989e-05 +358 296 0.0073591992 +372 296 0.00025379984 +374 296 8.4599989e-05 +375 296 0.00025379984 +384 296 0.00025379984 +387 296 8.4599989e-05 +397 296 8.4599989e-05 +402 296 0.00025379984 +417 296 0.00050749979 +419 296 8.4599989e-05 +421 296 8.4599989e-05 +422 296 0.00025379984 +423 296 8.4599989e-05 +425 296 8.4599989e-05 +430 296 8.4599989e-05 +431 296 8.4599989e-05 +434 296 8.4599989e-05 +443 296 0.0084587969 +444 296 0.00059209997 +445 296 0.0074437 +446 296 8.4599989e-05 +447 296 0.0019454998 +450 296 0.0032988999 +452 296 0.011419397 +453 296 0.012011498 +454 296 0.00067669991 +455 296 0.0190323 +456 296 0.00050749979 +457 296 0.0027067999 +458 296 0.00076129986 +459 296 0.00084589981 +460 296 0.0021146999 +463 296 0.0077820979 +464 296 0.00042289984 +465 296 0.0011841999 +467 296 0.015733398 +468 296 0.0036372999 +469 296 0.0084587969 +470 296 0.0094738975 +471 296 0.0010996 +473 296 0.00025379984 +477 296 8.4599989e-05 +478 296 0.0015226 +483 296 0.00093049998 +490 296 0.00076129986 +491 296 0.017848097 +19 297 0.00042689987 +24 297 0.0029882998 +60 297 0.0087512992 +104 297 0.0002134 +108 297 0.0002134 +114 297 0.00042689987 +126 297 0.0002134 +160 297 0.0002134 +190 297 0.0002134 +194 297 0.0002134 +198 297 0.0040554963 +206 297 0.00042689987 +214 297 0.00042689987 +223 297 0.0049092993 +234 297 0.0036285999 +241 297 0.00042689987 +252 297 0.00042689987 +268 297 0.0002134 +270 297 0.00064029987 +272 297 0.00085379998 +277 297 0.010245498 +278 297 0.011739597 +279 297 0.0002134 +282 297 0.001921 +283 297 0.00064029987 +284 297 0.0034151999 +286 297 0.20234787 +288 297 0.0040554963 +289 297 0.032017097 +290 297 0.0017076 +292 297 0.0010672 +293 297 0.0002134 +295 297 0.00042689987 +296 297 0.0002134 +297 297 0.0070437975 +312 297 0.00042689987 +313 297 0.0002134 +315 297 0.0002134 +319 297 0.0002134 +322 297 0.0002134 +324 297 0.0002134 +326 297 0.00064029987 +328 297 0.00042689987 +340 297 0.011739597 +341 297 0.0002134 +349 297 0.0002134 +351 297 0.00042689987 +353 297 0.027534697 +354 297 0.0010672 +356 297 0.0002134 +358 297 0.0096050985 +374 297 0.0002134 +375 297 0.00085379998 +377 297 0.0002134 +380 297 0.0002134 +386 297 0.0002134 +387 297 0.0002134 +402 297 0.00064029987 +415 297 0.00042689987 +417 297 0.00042689987 +419 297 0.0002134 +443 297 0.010031998 +444 297 0.00042689987 +445 297 0.014514398 +447 297 0.0061899982 +450 297 0.0032016998 +452 297 0.011099298 +453 297 0.0064033978 +454 297 0.00042689987 +455 297 0.033724699 +456 297 0.0002134 +457 297 0.0027747999 +458 297 0.0002134 +459 297 0.00085379998 +460 297 0.0017076 +463 297 0.022411998 +464 297 0.00064029987 +465 297 0.00085379998 +467 297 0.011099298 +468 297 0.0017076 +469 297 0.0070437975 +470 297 0.0076840967 +471 297 0.0010672 +473 297 0.0002134 +478 297 0.0012806999 +483 297 0.0012806999 +490 297 0.00085379998 +491 297 0.052721497 +21 298 0.00081929984 +24 298 0.0001639 +60 298 0.010650497 +104 298 0.0001639 +114 298 0.0001639 +126 298 0.0001639 +150 298 0.0001639 +190 298 0.0001639 +194 298 0.0001639 +198 298 0.0075372979 +206 298 0.00032769982 +214 298 0.0086842999 +223 298 0.0045878999 +234 298 0.0026216998 +237 298 0.0001639 +241 298 0.0065541975 +252 298 0.0001639 +268 298 0.00032769982 +270 298 0.0045878999 +272 298 0.00065539987 +276 298 0.013927598 +277 298 0.0026216998 +278 298 0.0029493999 +279 298 0.00032769982 +284 298 0.0036048 +286 298 0.0058986992 +287 298 0.0052432977 +288 298 0.13747334 +289 298 0.053580198 +290 298 0.038833398 +291 298 0.00098309992 +294 298 0.00032769982 +295 298 0.00032769982 +296 298 0.0001639 +298 298 0.0022939998 +312 298 0.012125198 +321 298 0.0001639 +326 298 0.014582999 +339 298 0.0026216998 +340 298 0.061772898 +351 298 0.0062263981 +353 298 0.0077010989 +354 298 0.0001639 +356 298 0.0001639 +358 298 0.015238397 +370 298 0.0001639 +373 298 0.0001639 +374 298 0.0001639 +375 298 0.0001639 +384 298 0.0001639 +386 298 0.0001639 +417 298 0.00065539987 +422 298 0.0001639 +438 298 0.0001639 +443 298 0.0049155988 +444 298 0.0058986992 +445 298 0.0093396977 +447 298 0.0075372979 +450 298 0.0034408998 +452 298 0.011797499 +453 298 0.0091757998 +454 298 0.00098309992 +455 298 0.017532397 +456 298 0.00049159979 +457 298 0.0042601973 +458 298 0.00098309992 +459 298 0.00098309992 +460 298 0.0021300998 +463 298 0.018679298 +464 298 0.00049159979 +465 298 0.00098309992 +467 298 0.0119613 +468 298 0.0016384998 +469 298 0.0042601973 +470 298 0.0045878999 +471 298 0.0011469999 +473 298 0.0001639 +478 298 0.0011469999 +483 298 0.00098309992 +490 298 0.00065539987 +491 298 0.0044240989 +22 299 0.0013623999 +60 299 0.0030653998 +114 299 0.0003405998 +160 299 0.00068119983 +172 299 0.0003405998 +198 299 0.0047683977 +206 299 0.0003405998 +214 299 0.0061307997 +223 299 0.0003405998 +229 299 0.00068119983 +233 299 0.00068119983 +234 299 0.0023842 +240 299 0.00068119983 +241 299 0.014305197 +272 299 0.0003405998 +277 299 0.091961861 +278 299 0.0013623999 +279 299 0.0003405998 +282 299 0.0010217999 +283 299 0.0013623999 +284 299 0.0023842 +286 299 0.044959098 +288 299 0.0034059999 +289 299 0.09162128 +290 299 0.0040871985 +292 299 0.028950997 +293 299 0.070163488 +294 299 0.053814698 +295 299 0.00068119983 +299 299 0.0057901964 +307 299 0.0003405998 +312 299 0.0003405998 +320 299 0.0003405998 +321 299 0.013964597 +324 299 0.0010217999 +326 299 0.010217998 +333 299 0.0003405998 +339 299 0.0003405998 +340 299 0.016008198 +351 299 0.00068119983 +354 299 0.0013623999 +358 299 0.0051089972 +417 299 0.0003405998 +443 299 0.0071525984 +444 299 0.00068119983 +445 299 0.0207766 +447 299 0.0057901964 +450 299 0.0017029999 +452 299 0.012942798 +453 299 0.011580396 +454 299 0.0020436 +455 299 0.027588598 +457 299 0.0023842 +458 299 0.00068119983 +460 299 0.0017029999 +463 299 0.010899197 +464 299 0.0003405998 +465 299 0.00068119983 +467 299 0.009536799 +468 299 0.0013623999 +469 299 0.0047683977 +470 299 0.0037465999 +471 299 0.0003405998 +478 299 0.00068119983 +483 299 0.0010217999 +490 299 0.00068119983 +491 299 0.016008198 +0 300 0.0003052 +9 300 7.0399998e-05 +11 300 4.6899993e-05 +18 300 0.00056339987 +22 300 2.349999e-05 +60 300 0.0020187998 +82 300 2.349999e-05 +84 300 2.349999e-05 +88 300 0.00011739999 +90 300 9.3899987e-05 +93 300 2.349999e-05 +107 300 0.0003052 +108 300 2.349999e-05 +114 300 2.349999e-05 +115 300 4.6899993e-05 +116 300 0.0005398998 +122 300 2.349999e-05 +126 300 2.349999e-05 +130 300 2.349999e-05 +150 300 0.00032859994 +151 300 0.00068079983 +160 300 0.0001408 +169 300 0.0015492998 +187 300 0.0003052 +188 300 0.0013849998 +189 300 2.349999e-05 +190 300 4.6899993e-05 +192 300 0.0002347 +193 300 2.349999e-05 +194 300 7.0399998e-05 +197 300 2.349999e-05 +198 300 0.0081691965 +200 300 2.349999e-05 +203 300 4.6899993e-05 +204 300 0.050517596 +206 300 4.6899993e-05 +207 300 2.349999e-05 +214 300 0.00011739999 +219 300 0.00072769984 +221 300 0.0019248999 +224 300 0.00021129999 +229 300 0.0010797998 +233 300 0.018239897 +234 300 0.0015962999 +237 300 9.3899987e-05 +240 300 0.0010797998 +241 300 9.3899987e-05 +252 300 2.349999e-05 +253 300 0.0005398998 +270 300 0.00058689993 +272 300 0.0006573 +277 300 0.33648676 +279 300 0.00037559983 +284 300 0.00082159997 +287 300 0.0054226965 +290 300 0.00046949997 +293 300 0.090729773 +300 300 0.0022065998 +312 300 2.349999e-05 +314 300 7.0399998e-05 +315 300 0.0006573 +317 300 0.00072769984 +321 300 0.0040845983 +322 300 4.6899993e-05 +325 300 2.349999e-05 +326 300 9.3899987e-05 +339 300 0.0010563999 +340 300 0.0045305975 +341 300 4.6899993e-05 +351 300 0.00070419977 +356 300 0.0001408 +358 300 0.0026525999 +384 300 4.6899993e-05 +387 300 2.349999e-05 +401 300 2.349999e-05 +402 300 4.6899993e-05 +417 300 0.0002347 +421 300 2.349999e-05 +422 300 7.0399998e-05 +430 300 2.349999e-05 +433 300 2.349999e-05 +434 300 2.349999e-05 +443 300 0.0071832985 +444 300 0.0044366978 +445 300 0.0084039979 +446 300 0.00089199981 +447 300 0.029319897 +450 300 0.0015962999 +452 300 0.0048592985 +453 300 0.0033098999 +454 300 0.0011737 +455 300 0.031385697 +456 300 0.00018779999 +457 300 0.0020893 +458 300 0.0012910999 +459 300 0.0017136999 +460 300 0.0016901998 +463 300 0.0102585 +464 300 0.0036150999 +465 300 0.00042249984 +467 300 0.015610699 +468 300 0.012089498 +469 300 0.0064085983 +470 300 0.0031690998 +471 300 0.0015023998 +473 300 2.349999e-05 +477 300 0.0007511999 +478 300 0.00056339987 +483 300 0.00025819987 +489 300 2.349999e-05 +490 300 0.00011739999 +491 300 0.00011739999 +23 301 0.0011695998 +60 301 0.0029239999 +114 301 0.0001949 +156 301 0.0001949 +187 301 0.0001949 +188 301 0.0015594999 +198 301 0.0017543999 +204 301 0.0017543999 +206 301 0.00038989983 +214 301 0.0001949 +219 301 0.00038989983 +223 301 0.0001949 +224 301 0.012280699 +229 301 0.00097469985 +233 301 0.022806998 +234 301 0.0027289998 +237 301 0.0001949 +240 301 0.0001949 +241 301 0.00038989983 +272 301 0.00038989983 +277 301 0.3705653 +284 301 0.00097469985 +285 301 0.0001949 +287 301 0.0001949 +292 301 0.0005847998 +293 301 0.007017497 +295 301 0.0005847998 +298 301 0.00038989983 +299 301 0.0001949 +301 301 0.0011695998 +305 301 0.0001949 +312 301 0.0015594999 +313 301 0.00097469985 +315 301 0.0005847998 +319 301 0.0005847998 +320 301 0.00038989983 +321 301 0.0011695998 +322 301 0.020467799 +324 301 0.0001949 +326 301 0.043469798 +339 301 0.00097469985 +340 301 0.0050681978 +341 301 0.0001949 +351 301 0.0072124973 +356 301 0.0001949 +358 301 0.0031188999 +371 301 0.0001949 +372 301 0.0005847998 +380 301 0.0001949 +386 301 0.00038989983 +402 301 0.0001949 +415 301 0.0005847998 +417 301 0.0001949 +443 301 0.0081870966 +444 301 0.0062377974 +445 301 0.0087718964 +446 301 0.0005847998 +447 301 0.017543897 +450 301 0.0019492998 +452 301 0.0066276975 +453 301 0.0044833981 +454 301 0.00097469985 +455 301 0.0391813 +456 301 0.0001949 +457 301 0.0031188999 +458 301 0.0005847998 +459 301 0.00038989983 +460 301 0.0011695998 +463 301 0.012670599 +464 301 0.0005847998 +465 301 0.00038989983 +467 301 0.0079921968 +468 301 0.0079921968 +469 301 0.0031188999 +470 301 0.0023391999 +471 301 0.0007797 +478 301 0.0005847998 +483 301 0.0005847998 +490 301 0.00038989983 +491 301 0.00038989983 +22 302 0.0012425999 +24 302 0.0021745998 +60 302 0.0040384978 +114 302 0.00031069992 +160 302 0.0012425999 +169 302 0.0012425999 +198 302 0.012736898 +206 302 0.00062129996 +214 302 0.00093199988 +223 302 0.013358198 +224 302 0.0018638999 +229 302 0.00093199988 +233 302 0.018018 +234 302 0.0027959 +237 302 0.00031069992 +240 302 0.00093199988 +241 302 0.0012425999 +270 302 0.0096302964 +272 302 0.0040384978 +277 302 0.14103758 +279 302 0.00062129996 +282 302 0.016154099 +283 302 0.0034171999 +284 302 0.0015532998 +286 302 0.0037278999 +288 302 0.013979498 +289 302 0.0024851998 +292 302 0.010251597 +293 302 0.0034171999 +295 302 0.00031069992 +296 302 0.0034171999 +297 302 0.014290199 +299 302 0.00031069992 +302 302 0.00031069992 +303 302 0.00062129996 +312 302 0.010251597 +313 302 0.00062129996 +315 302 0.0052810982 +317 302 0.00031069992 +319 302 0.00031069992 +320 302 0.0055917986 +321 302 0.023299199 +326 302 0.00031069992 +339 302 0.0040384978 +340 302 0.0052810982 +353 302 0.0031065999 +358 302 0.0021745998 +374 302 0.00062129996 +417 302 0.00062129996 +443 302 0.0086983964 +444 302 0.0074556991 +445 302 0.014290199 +446 302 0.00031069992 +447 302 0.0080769993 +450 302 0.0031065999 +452 302 0.0083876997 +453 302 0.0083876997 +454 302 0.0015532998 +455 302 0.031065498 +456 302 0.00031069992 +457 302 0.0086983964 +458 302 0.0012425999 +459 302 0.00093199988 +460 302 0.0015532998 +463 302 0.012115598 +464 302 0.00062129996 +465 302 0.00062129996 +467 302 0.010251597 +468 302 0.013668798 +469 302 0.0031065999 +470 302 0.0027959 +471 302 0.0012425999 +478 302 0.00093199988 +483 302 0.0015532998 +490 302 0.00062129996 +491 302 0.011183597 +24 303 0.00072109979 +60 303 0.0015864 +114 303 0.00014419999 +126 303 0.00014419999 +160 303 0.0012979999 +190 303 0.00014419999 +194 303 0.00014419999 +198 303 0.0087971985 +206 303 0.00028839987 +214 303 0.00043269992 +223 303 0.0047591999 +229 303 0.00086529995 +233 303 0.00086529995 +234 303 0.0024516999 +237 303 0.00057689985 +240 303 0.0011536998 +241 303 0.0046148971 +270 303 0.0070665963 +272 303 0.0040380992 +277 303 0.0291318 +279 303 0.00028839987 +282 303 0.0067781992 +283 303 0.00057689985 +284 303 0.0015864 +286 303 0.024228398 +288 303 0.00072109979 +289 303 0.0054801963 +290 303 0.00028839987 +292 303 0.11595035 +293 303 0.0036054 +296 303 0.0015864 +297 303 0.059128899 +298 303 0.015575398 +303 303 0.006633997 +312 303 0.041534498 +315 303 0.040092297 +317 303 0.00014419999 +320 303 0.042544 +321 303 0.0011536998 +324 303 0.00043269992 +328 303 0.0023075 +330 303 0.00086529995 +339 303 0.0021632998 +340 303 0.0038939 +341 303 0.00014419999 +350 303 0.00014419999 +351 303 0.00086529995 +353 303 0.00014419999 +354 303 0.00057689985 +358 303 0.006201297 +372 303 0.00043269992 +374 303 0.00028839987 +386 303 0.00014419999 +395 303 0.00014419999 +397 303 0.00014419999 +417 303 0.00043269992 +422 303 0.00014419999 +443 303 0.0043265 +444 303 0.0015864 +445 303 0.0102394 +446 303 0.00014419999 +447 303 0.0060570985 +450 303 0.0027400998 +452 303 0.0057686977 +453 303 0.0027400998 +454 303 0.00057689985 +455 303 0.034612097 +456 303 0.00028839987 +457 303 0.0060570985 +458 303 0.00072109979 +459 303 0.00072109979 +460 303 0.0017305999 +463 303 0.0070665963 +464 303 0.00028839987 +465 303 0.00057689985 +467 303 0.0074992999 +468 303 0.0095182993 +469 303 0.0033169999 +470 303 0.0036054 +471 303 0.0011536998 +473 303 0.00014419999 +478 303 0.00086529995 +483 303 0.00072109979 +490 303 0.00043269992 +491 303 0.0030285998 +21 304 0.00010399999 +22 304 0.00010399999 +60 304 0.0033270998 +108 304 0.00010399999 +114 304 0.00010399999 +126 304 0.00010399999 +135 304 0.00010399999 +160 304 0.0023912999 +169 304 0.00093569979 +171 304 0.0002079 +172 304 0.0023912999 +189 304 0.00010399999 +190 304 0.00010399999 +194 304 0.0002079 +198 304 0.0091494992 +203 304 0.00010399999 +206 304 0.0002079 +214 304 0.00031189993 +223 304 0.00010399999 +224 304 0.00010399999 +229 304 0.00083179981 +233 304 0.0058223978 +234 304 0.0034310999 +236 304 0.00031189993 +237 304 0.0002079 +240 304 0.0021833999 +241 304 0.00051989988 +242 304 0.0002079 +252 304 0.0002079 +270 304 0.0022874 +271 304 0.00010399999 +272 304 0.00010399999 +274 304 0.0002079 +277 304 0.078706563 +278 304 0.00010399999 +279 304 0.00010399999 +282 304 0.011748798 +283 304 0.0002079 +284 304 0.0016635 +285 304 0.00010399999 +286 304 0.0016635 +289 304 0.0016635 +292 304 0.021522097 +293 304 0.015595797 +294 304 0.00010399999 +295 304 0.00051989988 +296 304 0.0029111998 +297 304 0.0017674998 +298 304 0.0039508976 +304 304 0.040964898 +307 304 0.00041589979 +312 304 0.0066541992 +315 304 0.011644799 +319 304 0.00041589979 +320 304 0.0010396999 +321 304 0.004782699 +322 304 0.0069660991 +324 304 0.013828199 +326 304 0.013620298 +328 304 0.0011437 +339 304 0.0019754998 +340 304 0.0046786964 +343 304 0.00010399999 +350 304 0.00083179981 +351 304 0.00072779995 +352 304 0.014348097 +353 304 0.0012476998 +354 304 0.00041589979 +355 304 0.00010399999 +356 304 0.00010399999 +358 304 0.0041588992 +366 304 0.023809496 +370 304 0.0081097968 +371 304 0.00041589979 +372 304 0.039925098 +373 304 0.0019754998 +374 304 0.00083179981 +375 304 0.00010399999 +376 304 0.0042627975 +377 304 0.00010399999 +380 304 0.0002079 +386 304 0.00051989988 +387 304 0.00010399999 +402 304 0.00010399999 +415 304 0.029839899 +417 304 0.00041589979 +419 304 0.004782699 +421 304 0.00010399999 +422 304 0.00010399999 +430 304 0.00010399999 +434 304 0.00010399999 +441 304 0.0025992999 +443 304 0.0043667965 +444 304 0.0030151999 +445 304 0.0065501966 +446 304 0.0002079 +447 304 0.014867999 +450 304 0.0083176978 +452 304 0.0049905963 +453 304 0.0025992999 +454 304 0.00083179981 +455 304 0.044915799 +456 304 0.00031189993 +457 304 0.0051985979 +458 304 0.00072779995 +459 304 0.00072779995 +460 304 0.0016635 +463 304 0.016011599 +464 304 0.00051989988 +465 304 0.0010396999 +467 304 0.0085256994 +468 304 0.011020999 +469 304 0.004782699 +470 304 0.0049905963 +471 304 0.0041588992 +473 304 0.00010399999 +477 304 0.00010399999 +478 304 0.0010396999 +483 304 0.0011437 +490 304 0.00041589979 +491 304 0.0049905963 +9 305 2.9599993e-05 +18 305 0.00097779999 +19 305 0.00029629981 +21 305 5.9299986e-05 +22 305 0.00023699999 +60 305 0.0025185 +79 305 2.9599993e-05 +82 305 2.9599993e-05 +83 305 2.9599993e-05 +84 305 2.9599993e-05 +108 305 2.9599993e-05 +113 305 5.9299986e-05 +114 305 0.00011849999 +126 305 5.9299986e-05 +127 305 2.9599993e-05 +150 305 0.00062219985 +151 305 0.00047409977 +160 305 0.0016295998 +169 305 0.00068149995 +172 305 8.8899993e-05 +189 305 8.8899993e-05 +190 305 8.8899993e-05 +191 305 2.9599993e-05 +192 305 5.9299986e-05 +194 305 8.8899993e-05 +197 305 2.9599993e-05 +198 305 0.0023999999 +200 305 5.9299986e-05 +201 305 5.9299986e-05 +203 305 5.9299986e-05 +204 305 8.8899993e-05 +206 305 0.00011849999 +207 305 5.9299986e-05 +209 305 2.9599993e-05 +214 305 0.00068149995 +218 305 2.9599993e-05 +224 305 2.9599993e-05 +229 305 0.00085929991 +233 305 0.0093036965 +234 305 0.0024295999 +237 305 0.00029629981 +240 305 0.00029629981 +241 305 0.0029926 +242 305 2.9599993e-05 +248 305 2.9599993e-05 +250 305 2.9599993e-05 +252 305 0.00017779999 +262 305 2.9599993e-05 +267 305 2.9599993e-05 +270 305 0.00077039981 +272 305 0.00044439989 +274 305 2.9599993e-05 +277 305 0.34613329 +278 305 0.00011849999 +279 305 0.00011849999 +280 305 0.0025185 +282 305 0.0040295981 +283 305 0.00023699999 +284 305 0.00056299986 +285 305 0.0013925999 +286 305 2.9599993e-05 +288 305 0.0019258999 +289 305 0.0034667 +290 305 0.0024295999 +292 305 0.00079999981 +293 305 0.010903697 +294 305 0.00011849999 +295 305 8.8899993e-05 +296 305 0.00017779999 +297 305 0.0024889 +299 305 8.8899993e-05 +305 305 0.013748098 +307 305 0.0004147999 +308 305 2.9599993e-05 +309 305 2.9599993e-05 +312 305 0.026370399 +315 305 0.0055703968 +317 305 0.00047409977 +318 305 0.0028740999 +319 305 0.00011849999 +320 305 0.0012147999 +321 305 0.0092443973 +322 305 0.0053036995 +324 305 0.00026669982 +326 305 0.0013629999 +327 305 0.00017779999 +328 305 0.00026669982 +331 305 8.8899993e-05 +332 305 2.9599993e-05 +338 305 0.00077039981 +339 305 0.0021332998 +340 305 0.0028147998 +341 305 2.9599993e-05 +343 305 2.9599993e-05 +349 305 8.8899993e-05 +350 305 5.9299986e-05 +351 305 0.0010074 +352 305 8.8899993e-05 +353 305 0.00097779999 +354 305 0.0004147999 +356 305 2.9599993e-05 +358 305 0.012503698 +371 305 0.00011849999 +372 305 0.0023703999 +373 305 8.8899993e-05 +374 305 0.006933298 +375 305 2.9599993e-05 +384 305 8.8899993e-05 +386 305 8.8899993e-05 +387 305 5.9299986e-05 +390 305 5.9299986e-05 +394 305 2.9599993e-05 +397 305 2.9599993e-05 +398 305 2.9599993e-05 +402 305 0.00023699999 +405 305 2.9599993e-05 +408 305 0.00044439989 +417 305 0.00044439989 +419 305 2.9599993e-05 +421 305 5.9299986e-05 +422 305 0.0012443999 +423 305 2.9599993e-05 +425 305 2.9599993e-05 +430 305 2.9599993e-05 +431 305 2.9599993e-05 +432 305 2.9599993e-05 +433 305 2.9599993e-05 +434 305 5.9299986e-05 +443 305 0.0072295964 +444 305 0.0012147999 +445 305 0.0091851987 +446 305 0.00085929991 +447 305 0.0083555989 +448 305 2.9599993e-05 +450 305 0.0033481 +452 305 0.0056592971 +453 305 0.0019556 +454 305 0.0013036998 +455 305 0.034725897 +456 305 0.00056299986 +457 305 0.0028147998 +458 305 0.00047409977 +459 305 0.0003258998 +460 305 0.0022814998 +463 305 0.010607399 +464 305 0.0015703999 +465 305 0.0008888999 +467 305 0.0096592978 +468 305 0.0042962991 +469 305 0.0093332976 +470 305 0.007407397 +471 305 0.0016888999 +473 305 0.00011849999 +477 305 0.00091849989 +478 305 0.001037 +483 305 0.001037 +489 305 8.8899993e-05 +490 305 0.00047409977 +491 305 0.0015703999 +9 306 5.1799987e-05 +18 306 0.00015539999 +24 306 0.00020719999 +60 306 0.0015538 +82 306 5.1799987e-05 +83 306 5.1799987e-05 +84 306 5.1799987e-05 +108 306 5.1799987e-05 +113 306 0.00010359999 +114 306 0.00020719999 +126 306 0.00010359999 +130 306 5.1799987e-05 +139 306 0.00010359999 +150 306 0.00077689998 +159 306 0.00020719999 +160 306 0.0062667988 +161 306 0.00010359999 +163 306 5.1799987e-05 +165 306 0.0032628998 +170 306 0.00015539999 +171 306 0.00046609994 +172 306 0.00025899988 +184 306 5.1799987e-05 +187 306 0.0060078986 +189 306 0.00010359999 +190 306 0.00010359999 +191 306 5.1799987e-05 +194 306 0.0009323 +197 306 5.1799987e-05 +198 306 0.0065775998 +200 306 5.1799987e-05 +203 306 0.00010359999 +204 306 0.00010359999 +206 306 0.00010359999 +207 306 5.1799987e-05 +214 306 0.0024859998 +215 306 5.1799987e-05 +219 306 5.1799987e-05 +224 306 0.00041429978 +229 306 0.00088049984 +233 306 0.0078205988 +234 306 0.0029520998 +237 306 0.00025899988 +240 306 5.1799987e-05 +241 306 0.0100476 +242 306 5.1799987e-05 +252 306 0.052361697 +254 306 0.00031079981 +270 306 0.0013983999 +271 306 5.1799987e-05 +272 306 0.0005696998 +273 306 0.00010359999 +274 306 0.0012947998 +277 306 0.061114598 +278 306 5.1799987e-05 +279 306 0.00025899988 +280 306 5.1799987e-05 +282 306 0.0010358 +283 306 0.00010359999 +284 306 0.00072509982 +286 306 5.1799987e-05 +287 306 5.1799987e-05 +288 306 0.00036249985 +289 306 0.06287545 +290 306 0.009633299 +291 306 5.1799987e-05 +292 306 0.0016055999 +293 306 0.11471927 +295 306 0.00010359999 +296 306 0.00062149996 +297 306 0.0076133981 +305 306 5.1799987e-05 +306 306 0.0030038999 +311 306 5.1799987e-05 +312 306 0.0082866997 +313 306 5.1799987e-05 +315 306 0.004246898 +317 306 0.00025899988 +318 306 5.1799987e-05 +319 306 0.037652798 +320 306 0.0020198999 +321 306 0.0022787999 +322 306 0.011135299 +326 306 0.0097886994 +335 306 5.1799987e-05 +337 306 5.1799987e-05 +339 306 0.0011912 +340 306 0.0012947998 +350 306 5.1799987e-05 +351 306 0.0016055999 +353 306 0.0016572999 +354 306 0.00010359999 +356 306 5.1799987e-05 +357 306 5.1799987e-05 +358 306 0.0030556999 +366 306 5.1799987e-05 +371 306 5.1799987e-05 +372 306 5.1799987e-05 +374 306 0.00015539999 +387 306 5.1799987e-05 +402 306 0.00036249985 +417 306 0.00051789987 +419 306 5.1799987e-05 +421 306 5.1799987e-05 +422 306 0.00020719999 +423 306 5.1799987e-05 +425 306 5.1799987e-05 +430 306 5.1799987e-05 +431 306 5.1799987e-05 +433 306 5.1799987e-05 +434 306 5.1799987e-05 +443 306 0.0073026977 +444 306 0.0018126999 +445 306 0.0093225986 +446 306 0.00036249985 +447 306 0.0097368993 +448 306 5.1799987e-05 +450 306 0.0040915981 +452 306 0.0053345971 +453 306 0.0038325998 +454 306 0.00041429978 +455 306 0.034182698 +456 306 0.0005696998 +457 306 0.0027967999 +458 306 0.00072509982 +459 306 0.00031079981 +460 306 0.0018126999 +463 306 0.028174799 +464 306 0.0011912 +465 306 0.0009323 +467 306 0.0097886994 +468 306 0.0047648996 +469 306 0.0060596988 +470 306 0.0066294 +471 306 0.0040397979 +473 306 0.00015539999 +477 306 0.00010359999 +478 306 0.0012947998 +483 306 0.0014501999 +489 306 5.1799987e-05 +490 306 0.0005696998 +491 306 0.0021235 +9 307 2.9699993e-05 +18 307 0.00074129994 +19 307 0.00029649981 +21 307 0.004685197 +22 307 0.00017789999 +24 307 2.9699993e-05 +60 307 0.0024611999 +77 307 5.9299986e-05 +79 307 2.9699993e-05 +82 307 2.9699993e-05 +83 307 2.9699993e-05 +84 307 2.9699993e-05 +108 307 2.9699993e-05 +113 307 5.9299986e-05 +114 307 0.00011859999 +126 307 5.9299986e-05 +127 307 2.9699993e-05 +142 307 2.9699993e-05 +150 307 0.00062269997 +151 307 0.00059309998 +160 307 0.00083029992 +161 307 2.9699993e-05 +169 307 2.9699993e-05 +171 307 8.8999994e-05 +172 307 0.00026689982 +189 307 8.8999994e-05 +190 307 8.8999994e-05 +191 307 2.9699993e-05 +194 307 0.00011859999 +197 307 2.9699993e-05 +198 307 0.00074129994 +200 307 5.9299986e-05 +201 307 5.9299986e-05 +203 307 5.9299986e-05 +204 307 5.9299986e-05 +206 307 0.00011859999 +207 307 2.9699993e-05 +214 307 0.0010082 +218 307 2.9699993e-05 +223 307 0.0014827 +224 307 2.9699993e-05 +229 307 0.00083029992 +233 307 0.0013046998 +234 307 0.0031728998 +237 307 0.00029649981 +240 307 0.00032619992 +241 307 0.0033211999 +242 307 0.00011859999 +248 307 2.9699993e-05 +250 307 2.9699993e-05 +252 307 0.0017494999 +270 307 0.0022239999 +272 307 0.00094889989 +274 307 0.0014529999 +276 307 0.00077099982 +277 307 0.25199419 +278 307 0.00017789999 +280 307 0.00011859999 +282 307 0.008480899 +283 307 0.0012750998 +284 307 0.00059309998 +285 307 0.0027280999 +286 307 5.9299986e-05 +287 307 0.0011268 +288 307 0.00014829999 +289 307 0.0033507999 +290 307 0.00085989991 +291 307 2.9699993e-05 +292 307 0.0079470985 +293 307 0.006227199 +294 307 0.0013936998 +295 307 0.00023719999 +296 307 0.00041509978 +297 307 0.0053375997 +298 307 0.00023719999 +299 307 0.00023719999 +304 307 0.00041509978 +305 307 0.0030246 +307 307 0.023248199 +308 307 0.00017789999 +312 307 0.0053079985 +313 307 2.9699993e-05 +315 307 0.00088959979 +317 307 0.00068199984 +318 307 0.00074129994 +319 307 0.0012750998 +320 307 0.0016013 +321 307 0.0023722998 +322 307 0.0028763998 +324 307 0.014144599 +326 307 0.0088069998 +327 307 0.0010972 +328 307 0.00035579992 +329 307 2.9699993e-05 +331 307 2.9699993e-05 +332 307 2.9699993e-05 +333 307 5.9299986e-05 +338 307 0.00074129994 +339 307 0.0016901998 +340 307 0.0032321999 +341 307 2.9699993e-05 +343 307 0.0032025999 +344 307 0.00014829999 +347 307 0.00014829999 +349 307 5.9299986e-05 +350 307 0.00083029992 +351 307 0.0015123 +352 307 0.0031136 +353 307 0.00020759999 +354 307 0.0020164 +355 307 2.9699993e-05 +356 307 0.00011859999 +357 307 5.9299986e-05 +358 307 0.0046555996 +366 307 0.0019274999 +369 307 2.9699993e-05 +370 307 8.8999994e-05 +371 307 0.00014829999 +372 307 0.0044182986 +373 307 0.00041509978 +374 307 0.0031432998 +375 307 0.00071169995 +380 307 2.9699993e-05 +384 307 5.9299986e-05 +386 307 8.8999994e-05 +387 307 5.9299986e-05 +390 307 0.00011859999 +392 307 5.9299986e-05 +393 307 0.00011859999 +394 307 2.9699993e-05 +397 307 5.9299986e-05 +398 307 0.00014829999 +401 307 5.9299986e-05 +402 307 0.0014529999 +404 307 0.0010674999 +405 307 0.00047449977 +408 307 0.00011859999 +414 307 0.0011564998 +415 307 0.0012750998 +417 307 0.00038549979 +419 307 5.9299986e-05 +421 307 5.9299986e-05 +422 307 0.00014829999 +423 307 2.9699993e-05 +425 307 2.9699993e-05 +430 307 2.9699993e-05 +431 307 2.9699993e-05 +433 307 2.9699993e-05 +434 307 2.9699993e-05 +441 307 0.0013343999 +442 307 2.9699993e-05 +443 307 0.0061678998 +444 307 0.0029652999 +445 307 0.0093704984 +446 307 0.00080059981 +447 307 0.011179298 +448 307 2.9699993e-05 +450 307 0.0048927963 +452 307 0.0057527982 +453 307 0.0028466999 +454 307 0.0011564998 +455 307 0.0355247 +456 307 0.00059309998 +457 307 0.0027280999 +458 307 0.00044479989 +459 307 0.00029649981 +460 307 0.0018681998 +463 307 0.0109124 +464 307 0.0024909 +465 307 0.0091924965 +467 307 0.0094890967 +468 307 0.0021646998 +469 307 0.011001397 +470 307 0.0074725971 +471 307 0.0032321999 +473 307 0.00011859999 +477 307 0.0010082 +478 307 0.0010674999 +483 307 0.0011268 +489 307 8.8999994e-05 +490 307 0.00047449977 +491 307 0.0020756999 +9 308 3.6999991e-05 +18 308 0.0014416999 +19 308 0.0014785999 +21 308 3.6999991e-05 +22 308 0.0023657999 +24 308 3.6999991e-05 +25 308 3.6999991e-05 +60 308 0.0023287998 +82 308 3.6999991e-05 +83 308 3.6999991e-05 +84 308 3.6999991e-05 +108 308 3.6999991e-05 +113 308 7.3899995e-05 +114 308 0.00014789999 +126 308 7.3899995e-05 +127 308 3.6999991e-05 +130 308 3.6999991e-05 +139 308 3.6999991e-05 +150 308 0.00055449991 +151 308 0.00048059993 +160 308 0.0044728965 +165 308 7.3899995e-05 +169 308 0.0018112999 +171 308 3.6999991e-05 +172 308 0.00022179999 +187 308 0.0001848 +189 308 7.3899995e-05 +190 308 7.3899995e-05 +191 308 0.0038443999 +194 308 0.00014789999 +197 308 3.6999991e-05 +198 308 0.0125314 +200 308 3.6999991e-05 +203 308 7.3899995e-05 +204 308 7.3899995e-05 +206 308 0.00011089999 +207 308 3.6999991e-05 +214 308 0.00096109998 +223 308 0.0003696999 +224 308 3.6999991e-05 +229 308 0.00096109998 +233 308 0.021994699 +234 308 0.0042140968 +236 308 0.0011459 +237 308 0.00033269986 +240 308 0.00025879988 +241 308 0.0059514977 +242 308 7.3899995e-05 +252 308 0.0020700998 +254 308 3.6999991e-05 +267 308 7.3899995e-05 +270 308 0.00092409994 +271 308 3.6999991e-05 +272 308 3.6999991e-05 +273 308 3.6999991e-05 +274 308 7.3899995e-05 +277 308 0.17909944 +278 308 0.00059149996 +280 308 0.0026246 +282 308 0.0040292963 +283 308 0.0001848 +284 308 0.00059149996 +285 308 0.0015155999 +286 308 7.3899995e-05 +287 308 0.0028463998 +288 308 0.0018852998 +289 308 0.018076297 +290 308 0.0011459 +291 308 0.0018483 +292 308 0.0043249987 +293 308 0.070863485 +294 308 0.00088719977 +295 308 0.00029569981 +296 308 0.0022548998 +297 308 0.0038814 +304 308 7.3899995e-05 +305 308 0.0003696999 +306 308 7.3899995e-05 +307 308 0.00022179999 +308 308 0.0011459 +310 308 3.6999991e-05 +311 308 0.0017003999 +312 308 0.012605399 +313 308 7.3899995e-05 +315 308 0.0026614999 +317 308 0.0011459 +318 308 0.0011089998 +319 308 0.0019591998 +320 308 0.0023287998 +321 308 0.0097589977 +322 308 0.0024396998 +324 308 0.0014416999 +326 308 0.0028094 +328 308 0.00011089999 +337 308 7.3899995e-05 +338 308 0.0011459 +339 308 0.0018112999 +340 308 0.0046946965 +343 308 0.00059149996 +350 308 0.0024396998 +351 308 0.0014785999 +352 308 0.0013307999 +353 308 0.0012937998 +354 308 0.0012198999 +355 308 3.6999991e-05 +356 308 0.0016635 +357 308 3.6999991e-05 +358 308 0.0047685988 +359 308 7.3899995e-05 +366 308 0.0023657999 +369 308 3.6999991e-05 +370 308 7.3899995e-05 +371 308 0.0029942 +372 308 0.0051382966 +373 308 0.00014789999 +374 308 0.00066539994 +375 308 7.3899995e-05 +377 308 3.6999991e-05 +380 308 3.6999991e-05 +384 308 0.0017003999 +385 308 3.6999991e-05 +386 308 0.00048059993 +387 308 3.6999991e-05 +390 308 3.6999991e-05 +393 308 3.6999991e-05 +397 308 3.6999991e-05 +398 308 0.0011459 +401 308 0.0015525999 +402 308 0.00066539994 +405 308 3.6999991e-05 +408 308 3.6999991e-05 +412 308 0.00092409994 +414 308 3.6999991e-05 +415 308 0.00022179999 +417 308 0.00040659984 +419 308 0.00014789999 +421 308 7.3899995e-05 +422 308 0.0001848 +423 308 3.6999991e-05 +425 308 3.6999991e-05 +430 308 3.6999991e-05 +431 308 3.6999991e-05 +433 308 3.6999991e-05 +434 308 3.6999991e-05 +438 308 3.6999991e-05 +439 308 0.0011089998 +443 308 0.0071343966 +444 308 0.0015894999 +445 308 0.0096111 +446 308 0.00092409994 +447 308 0.0084651969 +448 308 7.3899995e-05 +450 308 0.0031420998 +452 308 0.0048055984 +453 308 0.0028833 +454 308 0.0011828998 +455 308 0.036854897 +456 308 0.00044359989 +457 308 0.0027723999 +458 308 0.00033269986 +459 308 0.00033269986 +460 308 0.0018852998 +463 308 0.025802199 +464 308 0.0017003999 +465 308 0.00088719977 +467 308 0.0086499974 +468 308 0.0057296976 +469 308 0.0050273985 +470 308 0.0064689964 +471 308 0.0038074998 +473 308 0.00011089999 +477 308 0.001035 +478 308 0.0011089998 +483 308 0.0009980998 +489 308 7.3899995e-05 +490 308 0.00040659984 +491 308 0.0035118 +22 309 0.0034929998 +60 309 0.0019959998 +108 309 0.00016629999 +114 309 0.00033269986 +126 309 0.00016629999 +139 309 0.00033269986 +160 309 0.0018296998 +184 309 0.00016629999 +190 309 0.00016629999 +191 309 0.00016629999 +192 309 0.0033266998 +194 309 0.00016629999 +198 309 0.0078176968 +206 309 0.00033269986 +214 309 0.0078176968 +229 309 0.00066529983 +233 309 0.013140399 +234 309 0.0033266998 +237 309 0.00033269986 +240 309 0.00016629999 +241 309 0.012474999 +242 309 0.00016629999 +252 309 0.00083169993 +270 309 0.00016629999 +272 309 0.00049899984 +277 309 0.16566867 +279 309 0.00016629999 +280 309 0.00016629999 +282 309 0.0056553967 +284 309 0.00066529983 +285 309 0.00016629999 +287 309 0.00016629999 +288 309 0.0016633 +289 309 0.033433098 +290 309 0.00033269986 +292 309 0.001497 +293 309 0.056719899 +296 309 0.0023286999 +297 309 0.00033269986 +305 309 0.0013306998 +309 309 0.0024949999 +312 309 0.015302699 +315 309 0.0073186979 +317 309 0.00016629999 +318 309 0.00033269986 +319 309 0.00033269986 +320 309 0.0033266998 +321 309 0.0084829964 +322 309 0.0054889992 +324 309 0.00016629999 +326 309 0.029274799 +327 309 0.00016629999 +331 309 0.00016629999 +335 309 0.00033269986 +339 309 0.0033266998 +340 309 0.0039919987 +351 309 0.00016629999 +352 309 0.00033269986 +353 309 0.0041582994 +354 309 0.00033269986 +358 309 0.027944099 +366 309 0.00099799992 +370 309 0.00033269986 +371 309 0.00016629999 +372 309 0.001497 +373 309 0.00049899984 +374 309 0.0028277 +387 309 0.00016629999 +390 309 0.00016629999 +402 309 0.00033269986 +405 309 0.00016629999 +417 309 0.00049899984 +422 309 0.00033269986 +443 309 0.006486997 +444 309 0.0056553967 +445 309 0.014304698 +446 309 0.00033269986 +447 309 0.0088156983 +450 309 0.0041582994 +452 309 0.0053226985 +453 309 0.001497 +454 309 0.00066529983 +455 309 0.034930099 +456 309 0.00033269986 +457 309 0.0024949999 +458 309 0.00083169993 +459 309 0.00033269986 +460 309 0.0023286999 +463 309 0.017797697 +464 309 0.00099799992 +465 309 0.00083169993 +467 309 0.0093146972 +468 309 0.0059879981 +469 309 0.0066533983 +470 309 0.0069859996 +471 309 0.0023286999 +473 309 0.00016629999 +478 309 0.001497 +483 309 0.00099799992 +490 309 0.00066529983 +491 309 0.0046573989 +22 310 0.0055714995 +60 310 0.0021947999 +114 310 0.00016879999 +126 310 0.00016879999 +160 310 0.00033769989 +191 310 0.00016879999 +194 310 0.00016879999 +198 310 0.0047272965 +206 310 0.00033769989 +214 310 0.00016879999 +229 310 0.0010129998 +233 310 0.0064156987 +234 310 0.0018571999 +237 310 0.00016879999 +240 310 0.00016879999 +241 310 0.00033769989 +252 310 0.0013506999 +272 310 0.00033769989 +277 310 0.31723785 +279 310 0.00016879999 +280 310 0.00016879999 +282 310 0.0006752999 +283 310 0.00016879999 +284 310 0.00033769989 +289 310 0.0042207986 +290 310 0.00016879999 +292 310 0.0057402998 +293 310 0.013000198 +296 310 0.00033769989 +297 310 0.00016879999 +305 310 0.00050649978 +310 310 0.0054026991 +312 310 0.031065296 +315 310 0.0251562 +318 310 0.00016879999 +319 310 0.00016879999 +320 310 0.0016882999 +321 310 0.0060779974 +322 310 0.012155998 +326 310 0.0297147 +328 310 0.00016879999 +329 310 0.00016879999 +339 310 0.0030389999 +340 310 0.0033767 +351 310 0.0052337982 +353 310 0.0067532994 +358 310 0.0079351999 +366 310 0.00016879999 +372 310 0.00016879999 +374 310 0.0047272965 +390 310 0.00033769989 +392 310 0.00033769989 +393 310 0.00016879999 +404 310 0.00016879999 +405 310 0.0010129998 +417 310 0.00033769989 +443 310 0.0074286982 +444 310 0.0055714995 +445 310 0.0087792985 +446 310 0.00084419991 +447 310 0.0089481995 +450 310 0.0027013 +452 310 0.0037143 +453 310 0.0025324998 +454 310 0.00050649978 +455 310 0.035455 +456 310 0.00016879999 +457 310 0.0027013 +458 310 0.00084419991 +459 310 0.00033769989 +460 310 0.0015194998 +463 310 0.011142999 +464 310 0.0020259998 +465 310 0.00033769989 +467 310 0.0072597973 +468 310 0.0077662989 +469 310 0.0042207986 +470 310 0.0048961975 +471 310 0.0011817999 +473 310 0.00016879999 +478 310 0.00084419991 +483 310 0.00084419991 +490 310 0.00050649978 +491 310 0.0011817999 +18 311 9.9899989e-05 +19 311 0.005791299 +22 311 0.0027957999 +24 311 0.00039939978 +25 311 9.9899989e-05 +60 311 0.0030953998 +108 311 9.9899989e-05 +114 311 9.9899989e-05 +126 311 9.9899989e-05 +160 311 0.0027957999 +165 311 0.00019969999 +169 311 0.00069899997 +172 311 0.0012981 +183 311 9.9899989e-05 +187 311 0.00019969999 +188 311 0.00019969999 +189 311 9.9899989e-05 +190 311 9.9899989e-05 +191 311 9.9899989e-05 +193 311 9.9899989e-05 +194 311 9.9899989e-05 +198 311 0.0022965998 +206 311 0.00019969999 +214 311 0.0016974998 +229 311 0.0010984 +233 311 0.0013978998 +234 311 0.0023963999 +237 311 9.9899989e-05 +240 311 0.00019969999 +241 311 0.0007987998 +252 311 0.0030953998 +267 311 0.00029959995 +270 311 9.9899989e-05 +272 311 0.00059909979 +273 311 0.00019969999 +277 311 0.36575139 +278 311 0.0019969998 +279 311 9.9899989e-05 +280 311 0.00039939978 +282 311 0.0061906986 +284 311 0.00059909979 +285 311 9.9899989e-05 +287 311 9.9899989e-05 +288 311 0.0018971998 +289 311 0.0060908981 +290 311 0.0013978998 +291 311 0.00019969999 +292 311 0.0013978998 +293 311 0.044932596 +295 311 0.00029959995 +296 311 9.9899989e-05 +297 311 0.00059909979 +305 311 0.0007987998 +306 311 9.9899989e-05 +307 311 0.00029959995 +311 311 0.0042935982 +312 311 0.0027957999 +315 311 0.0112831 +318 311 0.00019969999 +319 311 0.0011981998 +320 311 0.0014978 +321 311 0.0017972998 +322 311 0.014677998 +324 311 0.00029959995 +326 311 0.019370899 +337 311 9.9899989e-05 +339 311 0.00059909979 +340 311 0.0025960999 +343 311 9.9899989e-05 +350 311 0.00039939978 +351 311 0.0026959998 +352 311 0.00029959995 +353 311 0.0009984998 +354 311 0.00039939978 +358 311 0.0040938966 +359 311 9.9899989e-05 +366 311 9.9899989e-05 +368 311 9.9899989e-05 +371 311 9.9899989e-05 +372 311 0.00029959995 +373 311 9.9899989e-05 +374 311 0.00059909979 +375 311 0.00029959995 +384 311 0.00029959995 +386 311 9.9899989e-05 +387 311 9.9899989e-05 +408 311 0.00029959995 +413 311 9.9899989e-05 +414 311 9.9899989e-05 +417 311 0.00029959995 +422 311 0.00019969999 +430 311 9.9899989e-05 +443 311 0.011382896 +444 311 0.0025960999 +445 311 0.0090863965 +446 311 0.0015975998 +447 311 0.0046929978 +450 311 0.0028956998 +452 311 0.0066899993 +453 311 0.0034947998 +454 311 0.00069899997 +455 311 0.0390414 +456 311 0.00029959995 +457 311 0.0029954999 +458 311 0.00049929996 +459 311 0.00049929996 +460 311 0.0019969998 +463 311 0.0091861971 +464 311 0.00069899997 +465 311 0.00069899997 +467 311 0.0075885989 +468 311 0.0054917969 +469 311 0.0053918995 +470 311 0.005791299 +471 311 0.0013978998 +473 311 9.9899989e-05 +477 311 9.9899989e-05 +478 311 0.0009984998 +483 311 0.0011981998 +489 311 9.9899989e-05 +490 311 0.00039939978 +491 311 0.0036944998 +9 312 3.1899996e-05 +18 312 0.0011181999 +19 312 0.0022043998 +21 312 3.1899996e-05 +22 312 0.0011181999 +24 312 6.3899992e-05 +25 312 3.1899996e-05 +60 312 0.0029391998 +82 312 3.1899996e-05 +83 312 3.1899996e-05 +84 312 3.1899996e-05 +108 312 3.1899996e-05 +113 312 6.3899992e-05 +114 312 9.5799987e-05 +126 312 3.1899996e-05 +150 312 0.00070289988 +153 312 0.00083059981 +160 312 6.3899992e-05 +165 312 3.1899996e-05 +169 312 0.0014056999 +172 312 0.00079869991 +183 312 3.1899996e-05 +189 312 6.3899992e-05 +190 312 9.5799987e-05 +192 312 9.5799987e-05 +193 312 0.00083059981 +194 312 0.0001278 +198 312 0.0025238998 +200 312 3.1899996e-05 +203 312 0.0001278 +204 312 6.3899992e-05 +206 312 0.00015969999 +207 312 6.3899992e-05 +214 312 0.0036420999 +223 312 3.1899996e-05 +224 312 3.1899996e-05 +229 312 0.00063899998 +233 312 3.1899996e-05 +234 312 0.0050477982 +237 312 0.00025559985 +240 312 0.0021086 +241 312 0.0071562976 +242 312 6.3899992e-05 +252 312 6.3899992e-05 +262 312 3.1899996e-05 +267 312 0.0001278 +270 312 0.0048240982 +271 312 3.1899996e-05 +272 312 0.00063899998 +273 312 3.1899996e-05 +277 312 0.19002587 +278 312 0.0007666999 +279 312 0.0001278 +280 312 3.1899996e-05 +282 312 0.0043129995 +283 312 0.00031949999 +284 312 0.0061019994 +285 312 3.1899996e-05 +286 312 0.0011820998 +287 312 9.5799987e-05 +288 312 0.0016931999 +289 312 0.00041529979 +290 312 0.00060699997 +291 312 9.5799987e-05 +292 312 0.0277946 +293 312 0.0095843971 +294 312 0.00092649995 +295 312 0.0017251999 +296 312 0.00025559985 +297 312 0.0058144964 +298 312 6.3899992e-05 +299 312 3.1899996e-05 +301 312 0.0028752999 +304 312 3.1899996e-05 +307 312 3.1899996e-05 +310 312 3.1899996e-05 +312 312 0.006836798 +313 312 9.5799987e-05 +315 312 0.0054630972 +318 312 0.00054309983 +320 312 0.013481997 +321 312 0.00095839985 +322 312 0.0011500998 +324 312 0.0001278 +326 312 0.0010543 +327 312 3.1899996e-05 +328 312 0.00067089987 +329 312 9.5799987e-05 +337 312 0.00092649995 +338 312 0.0010543 +339 312 0.00038339989 +340 312 0.027219597 +341 312 0.0001278 +342 312 3.1899996e-05 +343 312 3.1899996e-05 +350 312 0.00019169999 +351 312 0.00099039986 +352 312 6.3899992e-05 +354 312 0.00028749998 +356 312 9.5799987e-05 +357 312 0.00019169999 +358 312 0.037155397 +359 312 6.3899992e-05 +366 312 3.1899996e-05 +367 312 3.1899996e-05 +372 312 0.0001278 +373 312 9.5799987e-05 +374 312 3.1899996e-05 +375 312 9.5799987e-05 +384 312 0.00015969999 +386 312 9.5799987e-05 +387 312 3.1899996e-05 +390 312 3.1899996e-05 +392 312 3.1899996e-05 +393 312 3.1899996e-05 +397 312 0.00015969999 +398 312 0.00083059981 +402 312 0.00041529979 +405 312 0.0001278 +408 312 3.1899996e-05 +413 312 3.1899996e-05 +414 312 0.0001278 +417 312 0.00047919992 +421 312 6.3899992e-05 +422 312 9.5799987e-05 +423 312 3.1899996e-05 +430 312 3.1899996e-05 +431 312 3.1899996e-05 +432 312 3.1899996e-05 +433 312 6.3899992e-05 +434 312 6.3899992e-05 +443 312 0.0060380995 +444 312 0.0011820998 +445 312 0.0092648976 +446 312 0.00099039986 +447 312 0.008466199 +448 312 3.1899996e-05 +450 312 0.0034822999 +452 312 0.0083702989 +453 312 0.0040892996 +454 312 0.0021404999 +455 312 0.028657198 +456 312 0.00067089987 +457 312 0.0050157979 +458 312 0.00060699997 +459 312 0.00041529979 +460 312 0.0018529999 +463 312 0.011724897 +464 312 0.0010543 +465 312 0.00092649995 +467 312 0.0096801966 +468 312 0.0046962984 +469 312 0.010478899 +470 312 0.0046323985 +471 312 0.0015653998 +473 312 6.3899992e-05 +477 312 0.0014376999 +478 312 0.0011500998 +479 312 0.0031947999 +483 312 0.0013098998 +489 312 0.0001278 +490 312 0.00028749998 +491 312 0.0048560984 +9 313 1.9299987e-05 +18 313 5.789999e-05 +19 313 0.00034749997 +22 313 0.00046329992 +24 313 1.9299987e-05 +60 313 0.0044206977 +77 313 0.0005983999 +82 313 1.9299987e-05 +83 313 1.9299987e-05 +84 313 1.9299987e-05 +108 313 1.9299987e-05 +113 313 3.8599988e-05 +114 313 3.8599988e-05 +126 313 1.9299987e-05 +134 313 0.0001351 +150 313 0.00061769993 +151 313 1.9299987e-05 +156 313 0.003976699 +158 313 0.000193 +160 313 0.00042469986 +169 313 0.00054049981 +171 313 5.789999e-05 +172 313 0.0019496998 +181 313 0.0001544 +187 313 0.00061769993 +188 313 0.0015056999 +189 313 3.8599988e-05 +190 313 7.7199991e-05 +192 313 5.789999e-05 +194 313 7.7199991e-05 +197 313 1.9299987e-05 +198 313 0.0025095998 +200 313 3.8599988e-05 +203 313 3.8599988e-05 +204 313 5.789999e-05 +206 313 7.7199991e-05 +207 313 3.8599988e-05 +209 313 1.9299987e-05 +214 313 0.0016215998 +218 313 1.9299987e-05 +219 313 0.0007528998 +220 313 5.789999e-05 +223 313 0.00081079989 +224 313 0.0007528998 +229 313 0.00086869998 +233 313 0.0010616998 +234 313 0.0021042 +236 313 1.9299987e-05 +237 313 0.00084939995 +240 313 0.0013319999 +241 313 0.001525 +242 313 7.7199991e-05 +252 313 0.00067559979 +267 313 1.9299987e-05 +270 313 0.0001544 +271 313 7.7199991e-05 +272 313 0.00025099982 +274 313 3.8599988e-05 +277 313 0.31369448 +278 313 0.0001351 +279 313 3.8599988e-05 +282 313 0.0029342 +283 313 0.00042469986 +284 313 0.00084939995 +285 313 0.00025099982 +286 313 0.00057909987 +288 313 0.00092659984 +289 313 0.00023169999 +290 313 7.7199991e-05 +292 313 0.0041503981 +293 313 0.0065054968 +294 313 0.00027029985 +295 313 0.00030889991 +296 313 0.00094589987 +297 313 5.789999e-05 +298 313 0.0049611963 +299 313 0.0020462999 +301 313 5.789999e-05 +312 313 0.012547798 +313 313 0.029052898 +315 313 0.00030889991 +318 313 1.9299987e-05 +319 313 0.0016408998 +320 313 0.0040152967 +321 313 0.00034749997 +322 313 0.00086869998 +323 313 0.00028959988 +325 313 0.00046329992 +326 313 0.0012161999 +328 313 0.00042469986 +330 313 0.00061769993 +338 313 0.00048259995 +339 313 0.0016601998 +340 313 0.0049997978 +350 313 1.9299987e-05 +351 313 0.00086869998 +354 313 1.9299987e-05 +356 313 3.8599988e-05 +357 313 0.00030889991 +358 313 0.0093818977 +366 313 0.00025099982 +372 313 5.789999e-05 +373 313 0.0010231 +374 313 1.9299987e-05 +375 313 1.9299987e-05 +384 313 0.00011579999 +385 313 0.0003668 +386 313 1.9299987e-05 +387 313 0.00028959988 +392 313 7.7199991e-05 +393 313 3.8599988e-05 +394 313 0.0001351 +397 313 0.00083009992 +399 313 5.789999e-05 +401 313 0.0014863999 +402 313 0.012953199 +405 313 0.0007528998 +414 313 5.789999e-05 +417 313 0.0003668 +419 313 1.9299987e-05 +421 313 5.789999e-05 +422 313 5.789999e-05 +423 313 1.9299987e-05 +430 313 1.9299987e-05 +432 313 1.9299987e-05 +433 313 1.9299987e-05 +434 313 3.8599988e-05 +441 313 1.9299987e-05 +443 313 0.0069301985 +444 313 0.00098449993 +445 313 0.0069494992 +446 313 0.00086869998 +447 313 0.0023936999 +448 313 1.9299987e-05 +450 313 0.0019689999 +452 313 0.0071618967 +453 313 0.0017759998 +454 313 0.00052119978 +455 313 0.028937098 +456 313 0.00025099982 +457 313 0.0027990998 +458 313 0.00027029985 +459 313 0.0022199999 +460 313 0.0017374 +463 313 0.0052121989 +464 313 0.0011195999 +465 313 0.00067559979 +467 313 0.0072004981 +468 313 0.0014477998 +469 313 0.0044592991 +470 313 0.0017952998 +471 313 0.0010809998 +473 313 3.8599988e-05 +477 313 7.7199991e-05 +478 313 0.00079149986 +483 313 0.00057909987 +489 313 5.789999e-05 +490 313 0.0001351 +491 313 0.0020462999 +0 314 0.0036722999 +22 314 0.00056499988 +24 314 0.00028249994 +60 314 0.0036722999 +87 314 0.0031072998 +90 314 0.0011298999 +114 314 0.00028249994 +130 314 0.00056499988 +135 314 0.00028249994 +169 314 0.00084749982 +171 314 0.005649697 +172 314 0.0016949 +187 314 0.0050846972 +188 314 0.011299398 +191 314 0.0011298999 +192 314 0.00056499988 +193 314 0.00028249994 +194 314 0.00028249994 +198 314 0.011299398 +204 314 0.0033898 +206 314 0.00028249994 +214 314 0.003954798 +223 314 0.017231598 +224 314 0.020338997 +225 314 0.00056499988 +229 314 0.00084749982 +233 314 0.017231598 +234 314 0.0019773999 +241 314 0.019491497 +252 314 0.00056499988 +270 314 0.0031072998 +272 314 0.0064971969 +277 314 0.19039547 +284 314 0.00084749982 +287 314 0.00028249994 +292 314 0.00028249994 +293 314 0.088983059 +294 314 0.00028249994 +312 314 0.0025423998 +314 314 0.046045199 +315 314 0.00084749982 +321 314 0.0050846972 +322 314 0.00028249994 +326 314 0.00056499988 +339 314 0.0014123998 +340 314 0.005649697 +349 314 0.00028249994 +351 314 0.00028249994 +358 314 0.0045197979 +385 314 0.00028249994 +417 314 0.00028249994 +443 314 0.0079095997 +444 314 0.00084749982 +445 314 0.0093219988 +446 314 0.00028249994 +447 314 0.005649697 +450 314 0.0019773999 +452 314 0.0062146969 +453 314 0.0028249 +454 314 0.00028249994 +455 314 0.031638399 +457 314 0.0016949 +458 314 0.00028249994 +459 314 0.00028249994 +460 314 0.0014123998 +463 314 0.0084745996 +464 314 0.00084749982 +465 314 0.00028249994 +467 314 0.0081920996 +468 314 0.0019773999 +469 314 0.0022598999 +470 314 0.0022598999 +471 314 0.00084749982 +478 314 0.00056499988 +483 314 0.00056499988 +490 314 0.00028249994 +491 314 0.00056499988 +9 315 3.7899998e-05 +18 315 0.00011359999 +19 315 0.0003407998 +21 315 3.7899998e-05 +22 315 0.00060589984 +25 315 3.7899998e-05 +60 315 0.0035974998 +77 315 0.00011359999 +82 315 3.7899998e-05 +108 315 3.7899998e-05 +114 315 7.5699994e-05 +126 315 3.7899998e-05 +130 315 0.00026509981 +131 315 7.5699994e-05 +139 315 0.00015149999 +141 315 3.7899998e-05 +150 315 0.00075739995 +151 315 3.7899998e-05 +156 315 0.00011359999 +160 315 0.0010225 +169 315 0.00053019985 +171 315 0.0041655973 +172 315 0.0020827998 +187 315 0.0020069999 +188 315 0.0051500984 +189 315 3.7899998e-05 +190 315 0.00011359999 +192 315 3.7899998e-05 +194 315 0.00018929999 +197 315 3.7899998e-05 +198 315 0.014996 +200 315 3.7899998e-05 +203 315 7.5699994e-05 +204 315 0.00018929999 +206 315 0.00015149999 +207 315 3.7899998e-05 +214 315 0.0054530986 +219 315 0.0019312999 +220 315 3.7899998e-05 +221 315 3.7899998e-05 +223 315 0.0029537999 +224 315 0.001742 +225 315 0.00015149999 +229 315 0.00075739995 +233 315 0.0040140972 +234 315 0.0027643999 +237 315 0.00018929999 +240 315 0.00030289986 +241 315 0.013973597 +243 315 3.7899998e-05 +252 315 0.0036732999 +270 315 0.00037869997 +272 315 0.00053019985 +274 315 0.0027264999 +277 315 0.16366869 +278 315 0.00011359999 +279 315 3.7899998e-05 +280 315 3.7899998e-05 +282 315 0.0025750999 +283 315 0.00011359999 +284 315 0.004506398 +285 315 0.0048850998 +286 315 0.0003407998 +287 315 7.5699994e-05 +288 315 0.00083309994 +289 315 0.00079519977 +290 315 0.00026509981 +292 315 0.014314398 +293 315 0.038663998 +294 315 0.0021584998 +295 315 0.015791297 +296 315 0.0019691999 +297 315 0.00094669987 +298 315 0.00083309994 +299 315 0.0055287965 +301 315 0.0034460998 +305 315 3.7899998e-05 +307 315 3.7899998e-05 +308 315 3.7899998e-05 +312 315 0.0095807984 +313 315 0.00094669987 +314 315 3.7899998e-05 +315 315 0.017306 +318 315 0.00064379978 +319 315 0.006361898 +320 315 0.0093535967 +321 315 0.0028402 +322 315 0.0014389998 +324 315 0.00011359999 +325 315 0.0012117999 +326 315 0.004619997 +328 315 0.00011359999 +330 315 7.5699994e-05 +331 315 7.5699994e-05 +338 315 0.00060589984 +339 315 0.0018555999 +340 315 0.0063240975 +341 315 3.7899998e-05 +344 315 0.00045439997 +349 315 3.7899998e-05 +350 315 3.7899998e-05 +351 315 0.00079519977 +352 315 3.7899998e-05 +354 315 7.5699994e-05 +356 315 3.7899998e-05 +358 315 0.006361898 +359 315 0.0016661999 +366 315 3.7899998e-05 +370 315 0.0002272 +371 315 0.00015149999 +372 315 0.0033324 +373 315 0.00087099988 +375 315 3.7899998e-05 +376 315 3.7899998e-05 +377 315 7.5699994e-05 +380 315 0.00079519977 +384 315 7.5699994e-05 +385 315 0.0002272 +386 315 0.0023478998 +387 315 3.7899998e-05 +389 315 3.7899998e-05 +390 315 0.00015149999 +392 315 0.00053019985 +393 315 0.00075739995 +398 315 7.5699994e-05 +402 315 0.0049228966 +405 315 0.00011359999 +415 315 0.00041659991 +417 315 0.0005679999 +419 315 0.00018929999 +421 315 7.5699994e-05 +422 315 0.00011359999 +430 315 0.00015149999 +433 315 3.7899998e-05 +434 315 3.7899998e-05 +441 315 0.00011359999 +442 315 3.7899998e-05 +443 315 0.0059453994 +444 315 0.00094669987 +445 315 0.0065133981 +446 315 0.00068159983 +447 315 0.0055666976 +450 315 0.0028779998 +452 315 0.0069677979 +453 315 0.0024992998 +454 315 0.00053019985 +455 315 0.031052399 +456 315 0.00030289986 +457 315 0.0035597 +458 315 0.00049229991 +459 315 0.00037869997 +460 315 0.0018555999 +463 315 0.012458798 +464 315 0.0020448999 +465 315 0.00094669987 +467 315 0.0095807984 +468 315 0.0054151975 +469 315 0.0079523996 +470 315 0.0033702999 +471 315 0.0013253998 +473 315 7.5699994e-05 +477 315 7.5699994e-05 +478 315 0.0011739 +483 315 0.00064379978 +489 315 3.7899998e-05 +490 315 0.00026509981 +491 315 0.00064379978 +60 316 0.0038768998 +114 316 0.0002423 +160 316 0.00048459996 +168 316 0.0002423 +171 316 0.0055730976 +194 316 0.0002423 +198 316 0.0167192 +206 316 0.00048459996 +214 316 0.0062999986 +224 316 0.0012114998 +229 316 0.00048459996 +234 316 0.0048460998 +237 316 0.0002423 +240 316 0.010176897 +241 316 0.017930698 +272 316 0.00048459996 +277 316 0.046765197 +279 316 0.0002423 +282 316 0.0029076999 +283 316 0.0036346 +284 316 0.0046037994 +292 316 0.0065422989 +293 316 0.0048460998 +294 316 0.0012114998 +296 316 0.00048459996 +299 316 0.0002423 +312 316 0.018899899 +315 316 0.0196268 +316 316 0.0019385 +317 316 0.0002423 +319 316 0.0121153 +320 316 0.016961496 +326 316 0.033438299 +340 316 0.0048460998 +353 316 0.0072691999 +356 316 0.0002423 +358 316 0.0026653998 +417 316 0.00048459996 +441 316 0.0096922964 +443 316 0.0019385 +444 316 0.0099345967 +445 316 0.0043614991 +447 316 0.0067845993 +450 316 0.0036346 +452 316 0.0058153979 +453 316 0.0019385 +454 316 0.0031499998 +455 316 0.019142199 +456 316 0.00048459996 +457 316 0.0016961 +458 316 0.00048459996 +459 316 0.00048459996 +460 316 0.0019385 +463 316 0.0050883964 +464 316 0.00096919993 +465 316 0.00072689983 +467 316 0.0094499998 +468 316 0.1344803 +469 316 0.0031499998 +470 316 0.0033922999 +471 316 0.00096919993 +478 316 0.00096919993 +479 316 0.0048460998 +483 316 0.0012114998 +490 316 0.00048459996 +491 316 0.00096919993 +22 317 8.6699991e-05 +24 317 8.6699991e-05 +60 317 0.0027729999 +108 317 8.6699991e-05 +114 317 0.0001733 +126 317 8.6699991e-05 +142 317 0.0001733 +159 317 8.6699991e-05 +160 317 0.00086659985 +161 317 0.00034659985 +168 317 0.0036394999 +171 317 0.050606597 +172 317 0.00060659996 +189 317 8.6699991e-05 +190 317 8.6699991e-05 +192 317 8.6699991e-05 +194 317 0.0001733 +198 317 0.011525098 +200 317 8.6699991e-05 +203 317 8.6699991e-05 +204 317 8.6699991e-05 +206 317 0.0001733 +207 317 8.6699991e-05 +214 317 8.6699991e-05 +224 317 8.6699991e-05 +229 317 0.00060659996 +234 317 0.0038127999 +237 317 0.00025999988 +240 317 0.00043329992 +241 317 0.013431497 +270 317 0.0019063998 +271 317 8.6699991e-05 +272 317 0.00060659996 +277 317 0.095580578 +278 317 0.0001733 +279 317 0.00025999988 +282 317 0.017071098 +283 317 0.027902897 +284 317 0.0044193976 +285 317 0.00034659985 +286 317 8.6699991e-05 +288 317 8.6699991e-05 +289 317 0.00043329992 +290 317 8.6699991e-05 +292 317 0.0033794998 +293 317 0.0032928998 +294 317 0.0001733 +295 317 0.00043329992 +296 317 0.005632598 +297 317 8.6699991e-05 +298 317 0.00025999988 +299 317 0.0064990968 +307 317 0.00025999988 +308 317 8.6699991e-05 +312 317 0.0013865 +313 317 8.6699991e-05 +315 317 0.0048526973 +317 317 0.0045926981 +318 317 8.6699991e-05 +319 317 0.00025999988 +320 317 0.020277299 +324 317 0.0001733 +326 317 0.011785097 +328 317 0.00034659985 +330 317 8.6699991e-05 +338 317 0.0012997999 +339 317 0.00051989988 +340 317 0.0086654983 +341 317 0.0001733 +350 317 0.0001733 +351 317 0.00077989977 +353 317 0.00025999988 +354 317 0.00060659996 +355 317 8.6699991e-05 +356 317 0.00025999988 +357 317 8.6699991e-05 +358 317 0.011525098 +371 317 8.6699991e-05 +372 317 0.00025999988 +373 317 0.00069319992 +375 317 8.6699991e-05 +386 317 0.00025999988 +387 317 8.6699991e-05 +397 317 8.6699991e-05 +401 317 8.6699991e-05 +402 317 0.00095319981 +412 317 8.6699991e-05 +417 317 0.00051989988 +421 317 8.6699991e-05 +422 317 8.6699991e-05 +430 317 8.6699991e-05 +433 317 8.6699991e-05 +434 317 8.6699991e-05 +441 317 8.6699991e-05 +443 317 0.0034661999 +444 317 0.0041593984 +445 317 0.013864797 +446 317 0.00034659985 +447 317 0.005632598 +450 317 0.0036394999 +452 317 0.005979199 +453 317 0.0037262 +454 317 0.00043329992 +455 317 0.033882096 +456 317 0.00025999988 +457 317 0.0019930999 +458 317 0.00086659985 +459 317 0.00043329992 +460 317 0.0019930999 +463 317 0.0088387989 +464 317 0.0027729999 +465 317 0.0010398999 +467 317 0.017850999 +468 317 0.0076255985 +469 317 0.0069323964 +470 317 0.0040727966 +471 317 0.0016464 +473 317 8.6699991e-05 +477 317 8.6699991e-05 +478 317 0.0012131999 +479 317 0.0026862998 +483 317 0.0013865 +489 317 8.6699991e-05 +490 317 0.00043329992 +491 317 0.0026862998 +60 318 0.0023991999 +114 318 0.00047979993 +171 318 0.0062379986 +172 318 0.00047979993 +198 318 0.0052782968 +206 318 0.00095969997 +224 318 0.00047979993 +229 318 0.00047979993 +234 318 0.0033588998 +237 318 0.00095969997 +240 318 0.00047979993 +241 318 0.012475997 +270 318 0.022072896 +272 318 0.00047979993 +276 318 0.00047979993 +277 318 0.14635319 +282 318 0.0038387999 +283 318 0.0014394999 +284 318 0.0043185987 +285 318 0.0014394999 +292 318 0.00047979993 +293 318 0.00047979993 +294 318 0.0023991999 +295 318 0.0033588998 +296 318 0.0033588998 +297 318 0.00047979993 +298 318 0.00095969997 +307 318 0.00095969997 +312 318 0.0014394999 +315 318 0.0014394999 +317 318 0.00047979993 +318 318 0.0038387999 +320 318 0.047504798 +326 318 0.00047979993 +328 318 0.0052782968 +330 318 0.0019193999 +333 318 0.00047979993 +338 318 0.00047979993 +340 318 0.013435699 +341 318 0.00047979993 +351 318 0.0019193999 +354 318 0.0019193999 +358 318 0.0086371973 +371 318 0.00047979993 +372 318 0.0014394999 +373 318 0.0038387999 +386 318 0.0019193999 +398 318 0.00047979993 +417 318 0.00047979993 +443 318 0.0028790999 +444 318 0.00047979993 +445 318 0.0043185987 +447 318 0.018714 +450 318 0.0033588998 +452 318 0.006717898 +453 318 0.0019193999 +454 318 0.00047979993 +455 318 0.024951998 +457 318 0.0023991999 +458 318 0.00095969997 +459 318 0.00047979993 +460 318 0.0014394999 +463 318 0.0091170967 +464 318 0.00047979993 +465 318 0.00047979993 +467 318 0.011516299 +468 318 0.011516299 +469 318 0.0043185987 +470 318 0.0043185987 +471 318 0.0014394999 +478 318 0.00095969997 +483 318 0.0014394999 +490 318 0.00047979993 +491 318 0.0014394999 +9 319 3.1499992e-05 +18 319 9.4399991e-05 +22 319 0.00034609996 +60 319 0.0032406999 +82 319 3.1499992e-05 +83 319 3.1499992e-05 +84 319 3.1499992e-05 +108 319 3.1499992e-05 +113 319 6.2899999e-05 +114 319 9.4399991e-05 +126 319 6.2899999e-05 +139 319 0.00062929979 +150 319 0.00072369981 +151 319 3.1499992e-05 +160 319 0.00044049998 +169 319 0.00091239996 +171 319 0.0050655976 +172 319 0.00037759985 +189 319 9.4399991e-05 +190 319 9.4399991e-05 +192 319 6.2899999e-05 +194 319 0.0001259 +198 319 0.0090613998 +200 319 6.2899999e-05 +203 319 0.0001259 +204 319 6.2899999e-05 +206 319 0.00022019999 +207 319 6.2899999e-05 +214 319 0.0026429 +223 319 0.0025485 +224 319 0.0050026998 +229 319 0.00066069979 +233 319 0.0013528999 +234 319 0.0030834 +237 319 0.0010698 +240 319 0.0060723983 +241 319 0.024258297 +242 319 3.1499992e-05 +252 319 0.0020450999 +253 319 0.0016675999 +270 319 0.0014473 +272 319 3.1499992e-05 +277 319 0.10058838 +279 319 3.1499992e-05 +282 319 0.0094074979 +283 319 0.00037759985 +284 319 0.0040901974 +285 319 0.00056629977 +286 319 0.0023597998 +288 319 0.018122897 +289 319 0.00056629977 +290 319 9.4399991e-05 +292 319 0.013875298 +293 319 0.0098479986 +294 319 0.0026115 +295 319 0.0025171 +296 319 0.0024226999 +297 319 0.0033350999 +298 319 0.0023911998 +304 319 3.1499992e-05 +305 319 3.1499992e-05 +312 319 0.0182487 +313 319 6.2899999e-05 +315 319 0.0082748979 +317 319 3.1499992e-05 +319 319 0.028600197 +320 319 0.00031459983 +321 319 0.0079287998 +322 319 0.0040272996 +324 319 9.4399991e-05 +326 319 0.0072679967 +328 319 3.1499992e-05 +335 319 3.1499992e-05 +337 319 6.2899999e-05 +338 319 0.00050339988 +339 319 0.00062929979 +340 319 0.0056948997 +341 319 6.2899999e-05 +350 319 3.1499992e-05 +351 319 0.00088099996 +353 319 0.00015729999 +354 319 0.00028319983 +356 319 0.00015729999 +357 319 3.1499992e-05 +358 319 0.0042789988 +359 319 6.2899999e-05 +366 319 9.4399991e-05 +367 319 3.1499992e-05 +369 319 0.0001888 +370 319 9.4399991e-05 +372 319 0.008872699 +373 319 3.1499992e-05 +384 319 9.4399991e-05 +385 319 6.2899999e-05 +386 319 0.00022019999 +387 319 6.2899999e-05 +390 319 0.0017618998 +391 319 0.00022019999 +392 319 0.0012899998 +393 319 0.0027372998 +402 319 9.4399991e-05 +405 319 9.4399991e-05 +414 319 6.2899999e-05 +415 319 3.1499992e-05 +417 319 0.00047199987 +419 319 3.1499992e-05 +421 319 6.2899999e-05 +422 319 9.4399991e-05 +423 319 3.1499992e-05 +425 319 3.1499992e-05 +430 319 3.1499992e-05 +431 319 3.1499992e-05 +432 319 3.1499992e-05 +433 319 6.2899999e-05 +434 319 6.2899999e-05 +441 319 0.0011955998 +443 319 0.0042160973 +444 319 0.0016675999 +445 319 0.0092816986 +446 319 0.00040899985 +447 319 0.012176298 +448 319 3.1499992e-05 +450 319 0.0033979998 +452 319 0.0061038993 +453 319 0.0017933999 +454 319 0.00078659994 +455 319 0.029732898 +456 319 0.0005349 +457 319 0.0019192998 +458 319 0.0016989999 +459 319 0.00050339988 +460 319 0.0018877999 +463 319 0.009438999 +464 319 0.0018248998 +465 319 0.0010382999 +467 319 0.0128056 +468 319 0.0011640999 +469 319 0.0066387989 +470 319 0.0042160973 +471 319 0.0012584999 +473 319 9.4399991e-05 +477 319 6.2899999e-05 +478 319 0.0011326999 +483 319 0.0014159 +489 319 6.2899999e-05 +490 319 0.00034609996 +491 319 0.00069219992 +18 320 0.0001928 +22 320 9.6399992e-05 +60 320 0.015715398 +108 320 9.6399992e-05 +114 320 9.6399992e-05 +126 320 9.6399992e-05 +150 320 0.001157 +189 320 9.6399992e-05 +190 320 0.0001928 +192 320 9.6399992e-05 +194 320 0.0001928 +198 320 0.0019282999 +200 320 9.6399992e-05 +203 320 9.6399992e-05 +204 320 9.6399992e-05 +206 320 0.00028919987 +207 320 9.6399992e-05 +214 320 0.024006899 +218 320 9.6399992e-05 +223 320 0.094967186 +224 320 9.6399992e-05 +229 320 0.00038569979 +233 320 0.0037600999 +234 320 0.0062668994 +237 320 0.00038569979 +240 320 0.0010604998 +241 320 0.0034708998 +252 320 0.0031815998 +270 320 0.0071345977 +277 320 0.0086771995 +278 320 9.6399992e-05 +284 320 0.0026995998 +286 320 0.004049398 +287 320 0.0001928 +288 320 0.0074237995 +289 320 0.0016389999 +290 320 0.027767099 +291 320 0.0001928 +292 320 9.6399992e-05 +293 320 0.00048209983 +294 320 9.6399992e-05 +295 320 9.6399992e-05 +312 320 0.0012534 +315 320 0.0042421967 +320 320 0.0006748999 +326 320 0.0001928 +340 320 0.0001928 +349 320 0.0031815998 +351 320 9.6399992e-05 +356 320 0.0001928 +358 320 0.0030852 +384 320 0.00028919987 +387 320 9.6399992e-05 +392 320 0.0001928 +393 320 0.001157 +402 320 0.0001928 +417 320 0.00077129994 +421 320 9.6399992e-05 +422 320 9.6399992e-05 +430 320 9.6399992e-05 +433 320 9.6399992e-05 +434 320 9.6399992e-05 +443 320 0.0078094974 +444 320 0.00057849986 +445 320 0.013883498 +446 320 0.0006748999 +447 320 0.0041457973 +450 320 0.0052062981 +452 320 0.022271499 +453 320 0.0095448978 +454 320 0.0017353999 +455 320 0.017450798 +456 320 0.00077129994 +457 320 0.0054955967 +458 320 0.00086769997 +459 320 0.00057849986 +460 320 0.0024102998 +463 320 0.023814097 +464 320 0.00038569979 +465 320 0.0015425999 +467 320 0.014751296 +468 320 0.0019282999 +469 320 0.0046277978 +470 320 0.0051098987 +471 320 0.0026995998 +473 320 9.6399992e-05 +478 320 0.0018318999 +483 320 0.0010604998 +489 320 0.0001928 +490 320 0.00048209983 +491 320 0.00028919987 +19 321 0.0001372 +22 321 0.0001372 +24 321 0.00041159987 +25 321 0.0001372 +60 321 0.0026069998 +108 321 0.0001372 +114 321 0.00027439999 +126 321 0.0001372 +130 321 0.0001372 +160 321 0.0001372 +171 321 0.00027439999 +187 321 0.0015093 +190 321 0.0001372 +192 321 0.0001372 +194 321 0.00041159987 +198 321 0.0032930998 +203 321 0.0001372 +204 321 0.0001372 +205 321 0.0001372 +206 321 0.00027439999 +211 321 0.0001372 +212 321 0.0001372 +214 321 0.058452297 +221 321 0.0001372 +223 321 0.00027439999 +224 321 0.0024697999 +229 321 0.00068609999 +233 321 0.10812289 +234 321 0.0030186998 +237 321 0.00027439999 +240 321 0.023874898 +241 321 0.014132798 +250 321 0.0001372 +252 321 0.00027439999 +270 321 0.019072399 +272 321 0.00068609999 +273 321 0.0001372 +277 321 0.0057628974 +278 321 0.00041159987 +279 321 0.0001372 +282 321 0.00027439999 +284 321 0.0020581998 +286 321 0.00027439999 +288 321 0.0429473 +289 321 0.0042535998 +290 321 0.0017837998 +292 321 0.00068609999 +293 321 0.0021954 +295 321 0.00082329987 +298 321 0.00041159987 +308 321 0.00054879999 +312 321 0.00041159987 +315 321 0.0001372 +320 321 0.024286497 +321 321 0.026619099 +326 321 0.0001372 +340 321 0.0097419992 +353 321 0.00041159987 +354 321 0.00027439999 +356 321 0.0001372 +358 321 0.00041159987 +369 321 0.00027439999 +370 321 0.0001372 +371 321 0.00027439999 +372 321 0.00041159987 +373 321 0.0032930998 +375 321 0.00027439999 +376 321 0.0001372 +386 321 0.00041159987 +387 321 0.0001372 +393 321 0.00082329987 +402 321 0.0001372 +417 321 0.00054879999 +421 321 0.0001372 +422 321 0.00027439999 +424 321 0.00054879999 +426 321 0.0001372 +434 321 0.0001372 +442 321 0.0001372 +443 321 0.0086442977 +444 321 0.0043907985 +445 321 0.013172299 +446 321 0.001921 +447 321 0.0080954991 +450 321 0.0039790981 +452 321 0.011662997 +453 321 0.011662997 +454 321 0.0038418998 +455 321 0.037184399 +456 321 0.00027439999 +457 321 0.0031558999 +458 321 0.0010976999 +459 321 0.00041159987 +460 321 0.0017837998 +463 321 0.025932997 +464 321 0.0045279972 +465 321 0.0012349 +467 321 0.010702498 +468 321 0.0017837998 +469 321 0.0038418998 +470 321 0.0042535998 +471 321 0.001921 +473 321 0.0001372 +477 321 0.0032930998 +478 321 0.0012349 +483 321 0.00082329987 +490 321 0.00041159987 +491 321 0.0010976999 +18 322 0.00016269999 +19 322 0.0076869987 +21 322 8.1299993e-05 +22 322 0.0036604998 +24 322 0.00048809987 +25 322 0.00016269999 +60 322 0.0049212985 +77 322 8.1299993e-05 +108 322 8.1299993e-05 +114 322 8.1299993e-05 +126 322 8.1299993e-05 +131 322 4.069999e-05 +132 322 4.069999e-05 +139 322 4.069999e-05 +141 322 0.0037417999 +150 322 0.00052869995 +160 322 0.0055720992 +165 322 8.1299993e-05 +169 322 0.00044739991 +171 322 0.0018302 +172 322 0.0012607998 +183 322 8.1299993e-05 +187 322 4.069999e-05 +189 322 8.1299993e-05 +190 322 0.000122 +192 322 8.1299993e-05 +194 322 0.00016269999 +195 322 4.069999e-05 +197 322 4.069999e-05 +198 322 0.011184797 +200 322 4.069999e-05 +203 322 0.0010574998 +204 322 4.069999e-05 +206 322 0.00032539992 +207 322 4.069999e-05 +214 322 0.0093544982 +223 322 0.0065074973 +224 322 0.00069139991 +225 322 0.000122 +229 322 0.00052869995 +233 322 0.000244 +234 322 0.0039044998 +237 322 0.00081339991 +240 322 0.0037417999 +241 322 0.0117542 +242 322 4.069999e-05 +252 322 0.000122 +267 322 0.0014234998 +270 322 0.00020339999 +271 322 4.069999e-05 +272 322 0.00056939991 +273 322 0.00016269999 +276 322 4.069999e-05 +277 322 0.22190589 +278 322 0.0026842998 +279 322 0.0021555999 +280 322 8.1299993e-05 +282 322 0.014926597 +283 322 8.1299993e-05 +284 322 0.0028063999 +285 322 0.0012202 +286 322 0.0059380978 +287 322 0.00044739991 +288 322 0.0097612999 +289 322 0.00077279983 +290 322 0.0019928999 +291 322 0.00020339999 +292 322 0.010737397 +293 322 0.0057753995 +294 322 8.1299993e-05 +295 322 0.010493398 +301 322 4.069999e-05 +302 322 4.069999e-05 +306 322 4.069999e-05 +307 322 4.069999e-05 +308 322 4.069999e-05 +310 322 8.1299993e-05 +311 322 4.069999e-05 +312 322 0.0061820969 +315 322 0.0015454998 +318 322 0.00044739991 +319 322 0.0012202 +320 322 0.004189197 +321 322 0.005734697 +322 322 0.0060193986 +323 322 4.069999e-05 +324 322 0.00016269999 +326 322 0.0017082 +328 322 0.000122 +329 322 4.069999e-05 +330 322 4.069999e-05 +335 322 4.069999e-05 +336 322 4.069999e-05 +337 322 0.000122 +339 322 0.00032539992 +340 322 0.012892999 +342 322 4.069999e-05 +343 322 0.000122 +345 322 4.069999e-05 +347 322 4.069999e-05 +349 322 4.069999e-05 +350 322 0.0013014998 +351 322 0.0029689998 +352 322 0.000244 +353 322 4.069999e-05 +354 322 0.0014234998 +355 322 0.00028469996 +356 322 0.00016269999 +358 322 0.0030503999 +359 322 0.00020339999 +361 322 4.069999e-05 +370 322 4.069999e-05 +371 322 4.069999e-05 +372 322 0.000122 +373 322 0.00044739991 +374 322 0.00093549979 +375 322 0.00032539992 +384 322 0.00040669995 +385 322 4.069999e-05 +387 322 8.1299993e-05 +402 322 0.00020339999 +408 322 0.000122 +413 322 8.1299993e-05 +414 322 8.1299993e-05 +415 322 4.069999e-05 +417 322 0.00048809987 +421 322 8.1299993e-05 +422 322 8.1299993e-05 +430 322 4.069999e-05 +433 322 4.069999e-05 +434 322 8.1299993e-05 +438 322 4.069999e-05 +441 322 0.0010167998 +443 322 0.011062797 +444 322 0.0021555999 +445 322 0.0079716966 +446 322 0.0017488999 +447 322 0.0033350999 +448 322 4.069999e-05 +450 322 0.0030910999 +452 322 0.0089884996 +453 322 0.0052466989 +454 322 0.0015048999 +455 322 0.030625898 +456 322 0.00052869995 +457 322 0.0036604998 +458 322 0.00065079983 +459 322 0.00040669995 +460 322 0.0020742998 +463 322 0.0090697967 +464 322 0.0013422 +465 322 0.00093549979 +467 322 0.012160897 +468 322 0.0036197999 +469 322 0.0035384998 +470 322 0.0036604998 +471 322 0.0014234998 +473 322 8.1299993e-05 +477 322 0.00089479983 +478 322 0.0010980999 +483 322 0.0010980999 +489 322 0.00028469996 +490 322 0.00036599999 +491 322 0.0032943999 +60 323 0.0021851999 +114 323 0.00027309987 +141 323 0.00054629985 +156 323 0.00054629985 +158 323 0.00027309987 +160 323 0.00081939995 +172 323 0.00027309987 +198 323 0.015842699 +206 323 0.00054629985 +214 323 0.0081944987 +223 323 0.00027309987 +224 323 0.00027309987 +229 323 0.00081939995 +233 323 0.0090138987 +234 323 0.0021851999 +237 323 0.00054629985 +240 323 0.020213097 +241 323 0.0027315 +252 323 0.00054629985 +270 323 0.00027309987 +271 323 0.00081939995 +272 323 0.00027309987 +277 323 0.23900568 +278 323 0.00027309987 +279 323 0.00027309987 +282 323 0.011745397 +283 323 0.0032777998 +284 323 0.0016388998 +285 323 0.016935296 +288 323 0.0013656998 +292 323 0.0024583 +293 323 0.0013656998 +294 323 0.00054629985 +295 323 0.0019119999 +296 323 0.0019119999 +312 323 0.023763999 +313 323 0.0040971972 +315 323 0.00081939995 +319 323 0.0010925999 +320 323 0.0098333992 +321 323 0.00081939995 +322 323 0.0010925999 +323 323 0.0046434999 +328 323 0.0024583 +329 323 0.00027309987 +340 323 0.012018599 +351 323 0.0013656998 +354 323 0.00054629985 +355 323 0.0081944987 +357 323 0.0013656998 +358 323 0.0030045998 +366 323 0.00027309987 +374 323 0.0065555982 +385 323 0.00027309987 +387 323 0.00027309987 +397 323 0.0013656998 +401 323 0.0013656998 +402 323 0.013657499 +417 323 0.00027309987 +441 323 0.00027309987 +443 323 0.0060092993 +444 323 0.0084675997 +445 323 0.0062823966 +446 323 0.00027309987 +447 323 0.0084675997 +450 323 0.0024583 +452 323 0.0060092993 +453 323 0.0076481998 +454 323 0.0079212971 +455 323 0.031412199 +457 323 0.0032777998 +458 323 0.00027309987 +459 323 0.00027309987 +460 323 0.0016388998 +463 323 0.0114723 +464 323 0.010925997 +465 323 0.00027309987 +467 323 0.0068286993 +468 323 0.0019119999 +469 323 0.0024583 +470 323 0.0027315 +471 323 0.0038240999 +478 323 0.0010925999 +483 323 0.0010925999 +490 323 0.00027309987 +491 323 0.0010925999 +9 324 2.739999e-05 +18 324 0.00079379999 +19 324 0.00027369987 +21 324 2.739999e-05 +22 324 0.00021899999 +24 324 0.0006295999 +60 324 0.0029563999 +82 324 2.739999e-05 +83 324 2.739999e-05 +84 324 2.739999e-05 +108 324 5.4699995e-05 +113 324 5.4699995e-05 +114 324 0.00013689999 +126 324 8.2099999e-05 +135 324 2.739999e-05 +142 324 0.00010949999 +150 324 0.00065699988 +151 324 0.0010401998 +160 324 0.0003558998 +171 324 0.0006295999 +172 324 2.739999e-05 +187 324 2.739999e-05 +189 324 8.2099999e-05 +190 324 0.00010949999 +191 324 2.739999e-05 +192 324 5.4699995e-05 +194 324 0.00010949999 +198 324 0.0055021979 +200 324 5.4699995e-05 +203 324 0.00010949999 +204 324 8.2099999e-05 +206 324 0.00010949999 +207 324 5.4699995e-05 +214 324 0.00038319989 +223 324 0.0015876999 +224 324 0.00021899999 +229 324 0.00071169995 +233 324 8.2099999e-05 +234 324 0.0034218 +237 324 0.00027369987 +240 324 0.0103474 +241 324 0.0028742999 +242 324 0.0032574998 +252 324 0.00013689999 +254 324 5.4699995e-05 +262 324 8.2099999e-05 +266 324 2.739999e-05 +267 324 2.739999e-05 +270 324 0.0038596999 +272 324 0.0037228998 +277 324 0.077824295 +278 324 0.00021899999 +279 324 2.739999e-05 +282 324 0.0447018 +283 324 0.013933398 +284 324 0.0017245999 +285 324 8.2099999e-05 +286 324 0.016725499 +288 324 0.0016971999 +289 324 0.00060219993 +290 324 0.010292597 +292 324 0.023596399 +293 324 0.0034490998 +294 324 0.00049269991 +295 324 0.0029837999 +296 324 0.0044345967 +297 324 0.0130574 +298 324 0.0101831 +299 324 0.0021352 +303 324 8.2099999e-05 +304 324 0.00010949999 +305 324 8.2099999e-05 +307 324 0.00060219993 +308 324 8.2099999e-05 +312 324 0.013960697 +313 324 2.739999e-05 +315 324 0.0060222968 +317 324 0.00065699988 +318 324 0.00010949999 +319 324 0.001314 +320 324 0.0030385 +321 324 0.0019983 +322 324 0.0028468999 +324 324 0.0213244 +326 324 0.0017519 +327 324 0.00013689999 +328 324 0.00073909992 +329 324 5.4699995e-05 +330 324 0.00068439986 +333 324 0.00049269991 +335 324 2.739999e-05 +338 324 0.0012591998 +339 324 2.739999e-05 +340 324 0.0058032982 +341 324 0.00027369987 +349 324 8.2099999e-05 +350 324 0.0010401998 +351 324 0.0018340999 +352 324 0.00010949999 +353 324 0.0023542 +354 324 0.00087599992 +356 324 0.0003558998 +358 324 0.018559597 +359 324 2.739999e-05 +366 324 0.00032849982 +368 324 0.00090329978 +369 324 0.00021899999 +370 324 0.0001642 +371 324 0.0003558998 +372 324 0.0076099969 +373 324 0.00090329978 +375 324 2.739999e-05 +384 324 8.2099999e-05 +386 324 0.00027369987 +387 324 5.4699995e-05 +390 324 2.739999e-05 +392 324 8.2099999e-05 +393 324 0.0012865998 +394 324 2.739999e-05 +397 324 2.739999e-05 +398 324 2.739999e-05 +402 324 0.00024639978 +404 324 2.739999e-05 +405 324 2.739999e-05 +413 324 5.4699995e-05 +414 324 0.0006295999 +415 324 0.00013689999 +417 324 0.00043799984 +419 324 0.00013689999 +421 324 5.4699995e-05 +422 324 0.00010949999 +423 324 2.739999e-05 +425 324 2.739999e-05 +430 324 5.4699995e-05 +431 324 2.739999e-05 +432 324 2.739999e-05 +433 324 5.4699995e-05 +434 324 5.4699995e-05 +443 324 0.0039144978 +444 324 0.0027647999 +445 324 0.0051736981 +446 324 0.00038319989 +447 324 0.0081574991 +448 324 2.739999e-05 +450 324 0.0035038998 +452 324 0.0064602979 +453 324 0.0027099999 +454 324 0.0016697999 +455 324 0.031534899 +456 324 0.00052009989 +457 324 0.0069803968 +458 324 0.0017245999 +459 324 0.0028468999 +460 324 0.0017792999 +463 324 0.0082942992 +464 324 0.0024362998 +465 324 0.0010401998 +467 324 0.010210499 +468 324 0.0015876999 +469 324 0.014097597 +470 324 0.0063780993 +471 324 0.0044345967 +473 324 0.00010949999 +477 324 5.4699995e-05 +478 324 0.0011771 +483 324 0.0014507999 +489 324 0.00010949999 +490 324 0.00043799984 +491 324 0.0068160966 +24 325 0.0001928 +60 325 0.0028923999 +77 325 0.00057849986 +104 325 0.00077129994 +114 325 0.0001928 +130 325 0.001157 +139 325 0.0001928 +142 325 0.00038569979 +143 325 0.0001928 +150 325 0.00038569979 +160 325 0.001157 +169 325 0.00057849986 +171 325 0.00038569979 +172 325 0.0015425999 +187 325 0.033744697 +188 325 0.0025066999 +189 325 0.00038569979 +192 325 0.001157 +194 325 0.0001928 +197 325 0.0001928 +198 325 0.052834596 +204 325 0.0017353999 +205 325 0.00057849986 +206 325 0.00038569979 +208 325 0.001157 +209 325 0.0001928 +211 325 0.00077129994 +212 325 0.00057849986 +213 325 0.0001928 +214 325 0.004820697 +219 325 0.0015425999 +221 325 0.0026995998 +223 325 0.00077129994 +224 325 0.0088699982 +229 325 0.00057849986 +233 325 0.0019282999 +234 325 0.0026995998 +240 325 0.00057849986 +241 325 0.06440419 +242 325 0.00077129994 +252 325 0.0001928 +271 325 0.0030852 +272 325 0.00077129994 +277 325 0.0053991973 +278 325 0.00077129994 +279 325 0.0001928 +282 325 0.00057849986 +284 325 0.0013497998 +285 325 0.00057849986 +286 325 0.00057849986 +287 325 0.0025066999 +288 325 0.00077129994 +289 325 0.13825679 +290 325 0.0059775971 +291 325 0.00077129994 +292 325 0.0019282999 +293 325 0.1396066 +295 325 0.00077129994 +312 325 0.00077129994 +314 325 0.001157 +315 325 0.00057849986 +317 325 0.00038569979 +319 325 0.0001928 +321 325 0.00096409977 +322 325 0.00038569979 +325 325 0.012148097 +326 325 0.0019282999 +337 325 0.00057849986 +340 325 0.0034708998 +347 325 0.00038569979 +348 325 0.0001928 +349 325 0.0001928 +351 325 0.00057849986 +354 325 0.0015425999 +358 325 0.0013497998 +373 325 0.00038569979 +386 325 0.0001928 +417 325 0.0001928 +422 325 0.00077129994 +438 325 0.0001928 +443 325 0.0080986992 +444 325 0.0050134994 +445 325 0.010026999 +446 325 0.0001928 +447 325 0.0061704963 +450 325 0.0023138998 +452 325 0.010026999 +453 325 0.0055919997 +454 325 0.0013497998 +455 325 0.029116899 +457 325 0.0028923999 +458 325 0.00057849986 +459 325 0.00057849986 +460 325 0.0019282999 +463 325 0.014269199 +464 325 0.00096409977 +465 325 0.00077129994 +467 325 0.0084843971 +468 325 0.004049398 +469 325 0.0034708998 +470 325 0.0028923999 +471 325 0.001157 +477 325 0.00038569979 +478 325 0.00057849986 +479 325 0.0001928 +483 325 0.00077129994 +490 325 0.0001928 +491 325 0.010219797 +9 326 4.5399996e-05 +18 326 0.00013619999 +19 326 0.0032229 +21 326 4.5399996e-05 +22 326 0.0015886999 +24 326 0.0010893999 +25 326 4.5399996e-05 +60 326 0.0026781999 +77 326 0.00013619999 +82 326 9.0799993e-05 +84 326 4.5399996e-05 +108 326 4.5399996e-05 +114 326 9.0799993e-05 +126 326 4.5399996e-05 +130 326 0.00018159999 +131 326 0.00027239998 +132 326 4.5399996e-05 +135 326 4.5399996e-05 +139 326 0.00013619999 +141 326 4.5399996e-05 +142 326 9.0799993e-05 +150 326 0.00059009995 +156 326 4.5399996e-05 +159 326 0.00013619999 +160 326 0.0032682999 +161 326 4.5399996e-05 +165 326 0.00027239998 +169 326 0.00072629983 +170 326 0.00013619999 +171 326 0.0030866999 +172 326 0.000227 +175 326 4.5399996e-05 +183 326 4.5399996e-05 +188 326 0.00013619999 +189 326 4.5399996e-05 +190 326 9.0799993e-05 +191 326 4.5399996e-05 +194 326 0.000227 +197 326 4.5399996e-05 +198 326 0.0052201971 +200 326 4.5399996e-05 +203 326 9.0799993e-05 +204 326 0.00027239998 +206 326 9.0799993e-05 +207 326 4.5399996e-05 +214 326 0.0040398985 +223 326 0.0012255998 +224 326 0.0022241999 +225 326 4.5399996e-05 +227 326 4.5399996e-05 +229 326 0.00063549983 +233 326 0.0068542995 +234 326 0.0032682999 +237 326 0.00027239998 +240 326 0.0048115999 +241 326 0.0192011 +242 326 9.0799993e-05 +243 326 4.5399996e-05 +252 326 0.0023603998 +267 326 0.00018159999 +270 326 0.0016794999 +271 326 9.0799993e-05 +272 326 0.0016341 +273 326 4.5399996e-05 +274 326 4.5399996e-05 +276 326 4.5399996e-05 +277 326 0.13091236 +278 326 0.0012709999 +280 326 4.5399996e-05 +282 326 0.0088969991 +283 326 0.0022695998 +284 326 0.0015886999 +285 326 0.0067180991 +286 326 0.0024057999 +287 326 0.00063549983 +288 326 0.0018610999 +289 326 0.013708599 +290 326 0.0093054995 +291 326 0.00013619999 +292 326 0.0054470971 +293 326 0.028324999 +294 326 0.005810298 +295 326 0.0062187985 +296 326 0.0015886999 +297 326 0.0012709999 +298 326 0.000227 +299 326 0.0020881 +300 326 0.00086249993 +301 326 0.0014525999 +304 326 9.0799993e-05 +306 326 0.00063549983 +307 326 0.00013619999 +308 326 0.0011347998 +310 326 4.5399996e-05 +312 326 0.0071719997 +313 326 0.00027239998 +315 326 0.0145256 +317 326 4.5399996e-05 +319 326 0.0060825981 +320 326 0.0048115999 +321 326 0.0049931966 +322 326 0.0057648979 +324 326 0.00068089995 +326 326 0.016386699 +327 326 4.5399996e-05 +328 326 0.010304097 +329 326 9.0799993e-05 +331 326 4.5399996e-05 +332 326 4.5399996e-05 +337 326 4.5399996e-05 +338 326 4.5399996e-05 +339 326 0.0019518998 +340 326 0.013027698 +341 326 4.5399996e-05 +342 326 4.5399996e-05 +343 326 4.5399996e-05 +344 326 4.5399996e-05 +345 326 4.5399996e-05 +349 326 0.00054469984 +350 326 0.00031769997 +351 326 0.0012709999 +352 326 0.00013619999 +353 326 0.00018159999 +354 326 0.00072629983 +355 326 4.5399996e-05 +356 326 0.000227 +357 326 9.0799993e-05 +358 326 0.0077620968 +359 326 0.00013619999 +364 326 4.5399996e-05 +366 326 0.00018159999 +369 326 0.000227 +370 326 0.000227 +371 326 0.00031769997 +372 326 0.00090789981 +373 326 0.0018610999 +374 326 4.5399996e-05 +375 326 0.000227 +376 326 0.00018159999 +380 326 4.5399996e-05 +384 326 0.000227 +385 326 4.5399996e-05 +386 326 0.00059009995 +387 326 4.5399996e-05 +389 326 0.00090789981 +390 326 0.000227 +391 326 0.00013619999 +392 326 0.00045389985 +393 326 0.0012709999 +397 326 4.5399996e-05 +401 326 9.0799993e-05 +402 326 0.0011801999 +404 326 9.0799993e-05 +405 326 0.00013619999 +408 326 9.0799993e-05 +413 326 4.5399996e-05 +414 326 9.0799993e-05 +415 326 0.00013619999 +417 326 0.00040849997 +421 326 4.5399996e-05 +422 326 9.0799993e-05 +424 326 4.5399996e-05 +428 326 4.5399996e-05 +430 326 0.00018159999 +433 326 4.5399996e-05 +434 326 4.5399996e-05 +437 326 9.0799993e-05 +441 326 9.0799993e-05 +442 326 0.00013619999 +443 326 0.0062187985 +444 326 0.00081709982 +445 326 0.0072173998 +446 326 0.00077169994 +447 326 0.0061733983 +450 326 0.0034043998 +452 326 0.0077620968 +453 326 0.0037221999 +454 326 0.00040849997 +455 326 0.028778899 +456 326 0.00036309985 +457 326 0.0055832975 +458 326 0.00040849997 +459 326 0.00049929996 +460 326 0.0017249 +463 326 0.013073098 +464 326 0.0018157 +465 326 0.0010893999 +467 326 0.010213297 +468 326 0.0025419998 +469 326 0.0044484995 +470 326 0.0044484995 +471 326 0.0017702999 +473 326 9.0799993e-05 +477 326 9.0799993e-05 +478 326 0.0010439998 +483 326 0.00068089995 +489 326 0.00013619999 +490 326 0.00031769997 +491 326 0.0032682999 +9 327 4.6199988e-05 +18 327 0.00013869999 +60 327 0.0018952999 +77 327 9.2499991e-05 +79 327 9.2499991e-05 +82 327 4.6199988e-05 +83 327 4.6199988e-05 +84 327 4.6199988e-05 +108 327 4.6199988e-05 +113 327 9.2499991e-05 +114 327 0.0001849 +126 327 4.6199988e-05 +130 327 4.6199988e-05 +150 327 0.00036979979 +172 327 4.6199988e-05 +181 327 4.6199988e-05 +187 327 4.6199988e-05 +189 327 4.6199988e-05 +190 327 9.2499991e-05 +192 327 4.6199988e-05 +194 327 4.6199988e-05 +198 327 0.0002311 +200 327 4.6199988e-05 +203 327 4.6199988e-05 +204 327 4.6199988e-05 +206 327 0.0002311 +207 327 4.6199988e-05 +214 327 0.00013869999 +218 327 4.6199988e-05 +220 327 4.6199988e-05 +224 327 0.0002311 +233 327 0.00013869999 +234 327 0.0035595 +237 327 4.6199988e-05 +240 327 0.0005084998 +241 327 0.0016641999 +242 327 4.6199988e-05 +252 327 9.2499991e-05 +270 327 0.00046229991 +272 327 0.0005084998 +276 327 4.6199988e-05 +277 327 0.049509998 +282 327 0.047475997 +283 327 0.055149797 +284 327 0.001618 +289 327 0.0001849 +290 327 4.6199988e-05 +292 327 0.0066567995 +293 327 0.0013867998 +294 327 0.0012943998 +295 327 0.0068878978 +296 327 0.0011094999 +297 327 0.0012019 +298 327 0.00087829982 +299 327 0.0083209984 +305 327 0.015671197 +307 327 0.016364597 +308 327 0.010817297 +312 327 0.0065642968 +315 327 0.0002311 +318 327 4.6199988e-05 +319 327 0.00013869999 +320 327 0.00069339992 +321 327 0.0014793 +322 327 0.00013869999 +324 327 0.0096616 +326 327 0.00013869999 +327 327 0.065920889 +328 327 0.0082285963 +331 327 4.6199988e-05 +338 327 0.0010631999 +339 327 0.0002311 +340 327 0.0075813979 +341 327 0.00013869999 +343 327 4.6199988e-05 +350 327 0.0020339999 +351 327 0.0034671 +352 327 4.6199988e-05 +354 327 0.0061020963 +355 327 0.00013869999 +356 327 0.00041609979 +357 327 0.0001849 +358 327 0.014423098 +370 327 0.0023575998 +371 327 0.00013869999 +372 327 0.0046689995 +373 327 0.0023113999 +374 327 4.6199988e-05 +375 327 4.6199988e-05 +376 327 4.6199988e-05 +387 327 4.6199988e-05 +390 327 0.00087829982 +392 327 0.00092459982 +393 327 0.00069339992 +396 327 4.6199988e-05 +397 327 0.00036979979 +398 327 0.0091068968 +403 327 4.6199988e-05 +404 327 0.0054548979 +405 327 0.0042529963 +408 327 0.0001849 +413 327 9.2499991e-05 +414 327 0.0002311 +417 327 0.0003235999 +421 327 4.6199988e-05 +422 327 4.6199988e-05 +423 327 4.6199988e-05 +430 327 4.6199988e-05 +431 327 4.6199988e-05 +433 327 4.6199988e-05 +434 327 9.2499991e-05 +443 327 0.0024962998 +444 327 0.00060099992 +445 327 0.0042991973 +446 327 0.0002311 +447 327 0.0051774979 +450 327 0.0028660998 +452 327 0.0042529963 +453 327 0.0010169998 +454 327 0.00092459982 +455 327 0.018629797 +456 327 0.00046229991 +457 327 0.0028660998 +458 327 0.0002311 +459 327 0.00041609979 +460 327 0.0010631999 +463 327 0.0058247 +464 327 0.00064719981 +465 327 0.0011556998 +467 327 0.0092917979 +468 327 0.00092459982 +469 327 0.0049463995 +470 327 0.0063331984 +471 327 0.0018491 +473 327 0.00013869999 +477 327 9.2499991e-05 +478 327 0.0010169998 +483 327 0.0011556998 +489 327 0.0002311 +490 327 0.00055469992 +491 327 0.0026349998 +9 328 2.8699986e-05 +18 328 8.6099986e-05 +22 328 0.00028689997 +60 328 0.0022374999 +82 328 2.8699986e-05 +83 328 2.8699986e-05 +84 328 2.8699986e-05 +108 328 2.8699986e-05 +113 328 5.7399986e-05 +114 328 8.6099986e-05 +126 328 2.8699986e-05 +130 328 2.8699986e-05 +134 328 2.8699986e-05 +150 328 0.00045899977 +151 328 2.8699986e-05 +156 328 2.8699986e-05 +160 328 0.00022949999 +161 328 2.8699986e-05 +169 328 5.7399986e-05 +172 328 0.00011469999 +187 328 0.00045899977 +189 328 5.7399986e-05 +190 328 5.7399986e-05 +194 328 8.6099986e-05 +197 328 2.8699986e-05 +198 328 0.0039299987 +200 328 2.8699986e-05 +203 328 5.7399986e-05 +204 328 5.7399986e-05 +206 328 0.00020079999 +207 328 2.8699986e-05 +214 328 8.6099986e-05 +223 328 2.8699986e-05 +224 328 0.00011469999 +233 328 0.00077449996 +234 328 0.0027825998 +237 328 0.00091799977 +240 328 0.00077449996 +241 328 0.0038438998 +242 328 0.00034419983 +252 328 0.00014339999 +270 328 0.0044176988 +271 328 0.0004015998 +272 328 0.0059666969 +276 328 2.8699986e-05 +277 328 0.026190497 +282 328 0.069219649 +283 328 0.018932898 +284 328 0.0016637999 +285 328 2.8699986e-05 +286 328 2.8699986e-05 +289 328 0.0066551976 +290 328 2.8699986e-05 +292 328 0.0038438998 +293 328 0.00077449996 +294 328 0.013568599 +295 328 0.0018071998 +296 328 0.024555396 +297 328 0.0012908999 +298 328 0.00037289993 +299 328 0.0050200969 +307 328 0.0049913973 +312 328 0.0088926964 +313 328 0.00048769987 +315 328 0.020309798 +317 328 0.0025531 +319 328 0.00017209999 +320 328 0.0029546998 +321 328 5.7399986e-05 +322 328 0.0041307993 +323 328 0.00014339999 +324 328 0.001922 +326 328 0.00011469999 +327 328 0.0021227999 +328 328 0.1164372 +329 328 0.00028689997 +330 328 0.001004 +331 328 0.0034136998 +332 328 5.7399986e-05 +338 328 0.001463 +339 328 2.8699986e-05 +340 328 0.0094950981 +341 328 0.00028689997 +344 328 2.8699986e-05 +350 328 0.0059379973 +351 328 0.0090074986 +352 328 8.6099986e-05 +354 328 0.010728598 +356 328 0.00091799977 +357 328 0.022289198 +358 328 0.021658096 +366 328 2.8699986e-05 +370 328 0.001004 +371 328 0.00045899977 +372 328 0.0059093982 +373 328 0.0011187999 +375 328 2.8699986e-05 +376 328 2.8699986e-05 +384 328 2.8699986e-05 +387 328 5.7399986e-05 +390 328 5.7399986e-05 +392 328 2.8699986e-05 +393 328 0.00025819987 +397 328 0.011876099 +399 328 8.6099986e-05 +401 328 0.00014339999 +402 328 0.0093229972 +404 328 0.0019506998 +405 328 0.0004302999 +408 328 0.0011473999 +412 328 5.7399986e-05 +413 328 2.8699986e-05 +414 328 0.00011469999 +417 328 0.00031549996 +421 328 2.8699986e-05 +422 328 8.6099986e-05 +423 328 2.8699986e-05 +430 328 2.8699986e-05 +431 328 2.8699986e-05 +433 328 2.8699986e-05 +434 328 2.8699986e-05 +441 328 2.8699986e-05 +443 328 0.0022948999 +444 328 0.00094659999 +445 328 0.0071428977 +446 328 0.00020079999 +447 328 0.0037292 +450 328 0.0027538999 +452 328 0.0044749975 +453 328 0.0014916998 +454 328 0.0010326998 +455 328 0.031812999 +456 328 0.0004302999 +457 328 0.0028972998 +458 328 0.0013482999 +459 328 0.0004302999 +460 328 0.001004 +463 328 0.0026677998 +464 328 0.0011473999 +465 328 0.0008605998 +467 328 0.0091795996 +468 328 0.0046184994 +469 328 0.0033849999 +470 328 0.0036144999 +471 328 0.0053642988 +473 328 5.7399986e-05 +477 328 8.6099986e-05 +478 328 0.0008892999 +483 328 0.0008605998 +489 328 2.8699986e-05 +490 328 0.00034419983 +491 328 0.0038438998 +6 329 2.3299988e-05 +9 329 2.3299988e-05 +18 329 0.00016329999 +22 329 0.0002799998 +24 329 2.3299988e-05 +60 329 0.0022401998 +78 329 4.6699992e-05 +79 329 2.3299988e-05 +82 329 2.3299988e-05 +83 329 2.3299988e-05 +84 329 2.3299988e-05 +98 329 0.0014700999 +102 329 4.6699992e-05 +108 329 2.3299988e-05 +113 329 4.6699992e-05 +114 329 9.3299997e-05 +118 329 2.3299988e-05 +120 329 2.3299988e-05 +126 329 4.6699992e-05 +127 329 2.3299988e-05 +139 329 2.3299988e-05 +142 329 2.3299988e-05 +150 329 0.00046669994 +151 329 2.3299988e-05 +156 329 4.6699992e-05 +160 329 0.0020301 +161 329 9.3299997e-05 +163 329 2.3299988e-05 +165 329 4.6699992e-05 +169 329 0.00037339982 +171 329 2.3299988e-05 +172 329 0.00079339999 +173 329 2.3299988e-05 +176 329 2.3299988e-05 +189 329 0.00011669999 +190 329 6.9999995e-05 +192 329 2.3299988e-05 +194 329 9.3299997e-05 +198 329 0.0012133999 +200 329 4.6699992e-05 +201 329 4.6699992e-05 +203 329 9.3299997e-05 +204 329 6.9999995e-05 +206 329 0.0002799998 +207 329 4.6699992e-05 +214 329 0.00030339998 +224 329 2.3299988e-05 +233 329 0.0024734999 +234 329 0.0027534999 +237 329 0.017781299 +240 329 0.0072104968 +241 329 0.0020067999 +242 329 0.0021702 +248 329 2.3299988e-05 +250 329 2.3299988e-05 +252 329 0.00011669999 +270 329 2.3299988e-05 +271 329 0.0020067999 +272 329 0.00084009999 +277 329 0.087039649 +278 329 4.6699992e-05 +279 329 2.3299988e-05 +282 329 0.041209698 +283 329 0.0107341 +284 329 0.0018900998 +285 329 0.00067669991 +286 329 2.3299988e-05 +289 329 0.00016329999 +292 329 0.0022868 +293 329 0.0013533998 +294 329 6.9999995e-05 +295 329 2.3299988e-05 +296 329 0.0015633998 +297 329 6.9999995e-05 +298 329 0.00062999991 +302 329 2.3299988e-05 +304 329 2.3299988e-05 +305 329 2.3299988e-05 +306 329 9.3299997e-05 +307 329 0.00023339999 +308 329 4.6699992e-05 +312 329 0.0105941 +313 329 0.00025669998 +315 329 0.011037499 +317 329 4.6699992e-05 +318 329 0.00039669988 +319 329 9.3299997e-05 +320 329 4.6699992e-05 +321 329 4.6699992e-05 +322 329 0.0075138994 +323 329 0.0023335 +324 329 0.0001867 +326 329 6.9999995e-05 +328 329 0.037499398 +329 329 0.034022499 +330 329 0.0036169 +331 329 0.0013067999 +335 329 2.3299988e-05 +337 329 4.6699992e-05 +338 329 0.0025668999 +339 329 0.00048999977 +340 329 0.0052736998 +341 329 0.00011669999 +343 329 4.6699992e-05 +344 329 2.3299988e-05 +349 329 4.6699992e-05 +350 329 0.014117699 +351 329 0.014047697 +353 329 4.6699992e-05 +354 329 0.026205298 +356 329 0.0018667998 +357 329 0.0064637996 +358 329 0.0089372993 +366 329 0.00011669999 +371 329 6.9999995e-05 +372 329 0.0045269988 +373 329 0.00016329999 +375 329 2.3299988e-05 +377 329 2.3299988e-05 +378 329 4.6699992e-05 +383 329 2.3299988e-05 +384 329 4.6699992e-05 +386 329 0.00025669998 +387 329 6.9999995e-05 +395 329 0.00023339999 +397 329 0.0060203969 +399 329 0.0028702 +401 329 0.00011669999 +402 329 0.020814899 +412 329 2.3299988e-05 +417 329 0.00034999987 +419 329 2.3299988e-05 +421 329 4.6699992e-05 +422 329 9.3299997e-05 +423 329 2.3299988e-05 +425 329 2.3299988e-05 +430 329 2.3299988e-05 +431 329 2.3299988e-05 +432 329 2.3299988e-05 +433 329 4.6699992e-05 +434 329 4.6699992e-05 +439 329 2.3299988e-05 +441 329 0.00025669998 +442 329 0.00039669988 +443 329 0.0041069984 +444 329 0.00023339999 +445 329 0.0065104999 +446 329 0.00037339982 +447 329 0.0030568999 +450 329 0.0035003 +452 329 0.0037802998 +453 329 0.0026135 +454 329 0.00051339995 +455 329 0.039786298 +456 329 0.00044339988 +457 329 0.0032435998 +458 329 0.00039669988 +459 329 0.0012834 +460 329 0.0010733998 +463 329 0.0024734999 +464 329 0.0001867 +465 329 0.0018435 +467 329 0.0097539984 +468 329 0.011364199 +469 329 0.0039202981 +470 329 0.0043869987 +471 329 0.0012600999 +473 329 9.3299997e-05 +477 329 9.3299997e-05 +478 329 0.00088669988 +483 329 0.0015401 +489 329 6.9999995e-05 +490 329 0.00084009999 +491 329 0.0033602 +18 330 0.00016719999 +22 330 0.00016719999 +60 330 0.0015886 +98 330 8.3599996e-05 +108 330 8.3599996e-05 +114 330 0.00016719999 +126 330 8.3599996e-05 +139 330 8.3599996e-05 +160 330 0.0030099999 +172 330 0.00083609996 +189 330 8.3599996e-05 +190 330 8.3599996e-05 +194 330 8.3599996e-05 +198 330 0.0087792985 +203 330 8.3599996e-05 +206 330 0.00016719999 +214 330 8.3599996e-05 +223 330 8.3599996e-05 +224 330 8.3599996e-05 +233 330 0.0024247 +234 330 0.0020066998 +237 330 0.026672199 +240 330 0.0061036982 +241 330 0.0095317997 +242 330 0.00016719999 +270 330 0.00016719999 +271 330 0.00041809981 +272 330 0.00083609996 +276 330 0.00016719999 +277 330 0.065551758 +282 330 0.014715698 +283 330 0.0048494972 +284 330 0.0015886 +285 330 0.0027591998 +286 330 8.3599996e-05 +292 330 0.0011705998 +293 330 0.0015886 +294 330 0.00058529992 +295 330 0.00058529992 +296 330 0.010117099 +297 330 0.0067725964 +298 330 0.00058529992 +299 330 0.0018394999 +307 330 0.00033439999 +312 330 0.017056897 +313 330 0.00050169998 +315 330 0.017391298 +317 330 0.0091136992 +318 330 8.3599996e-05 +320 330 0.0011705998 +321 330 0.0031772999 +322 330 0.0013377999 +323 330 0.0010032998 +324 330 8.3599996e-05 +326 330 0.00016719999 +328 330 0.13185614 +329 330 0.0024247 +330 330 0.049581897 +338 330 0.00016719999 +340 330 0.0061872974 +341 330 0.00016719999 +350 330 0.0071069971 +351 330 0.010953199 +354 330 0.034949798 +356 330 0.0010869999 +357 330 0.0011705998 +358 330 0.0072741993 +371 330 0.00025079981 +372 330 0.018896297 +373 330 0.0012541998 +385 330 8.3599996e-05 +386 330 0.0056855977 +387 330 8.3599996e-05 +395 330 0.0057691969 +397 330 0.0058527999 +398 330 0.00016719999 +399 330 0.00016719999 +401 330 0.00016719999 +402 330 0.0036789 +409 330 0.0056019984 +412 330 0.00033439999 +417 330 0.00025079981 +419 330 8.3599996e-05 +422 330 8.3599996e-05 +434 330 8.3599996e-05 +441 330 0.0012541998 +442 330 0.0015049998 +443 330 0.0028428 +444 330 0.00083609996 +445 330 0.0064380988 +446 330 0.00025079981 +447 330 0.0056855977 +450 330 0.0025083998 +452 330 0.0032608998 +453 330 0.0016721999 +454 330 0.00025079981 +455 330 0.053344499 +456 330 0.00016719999 +457 330 0.010200698 +458 330 0.00041809981 +459 330 0.00066889985 +460 330 0.0009196999 +463 330 0.0043477975 +464 330 0.00033439999 +465 330 0.0030099999 +467 330 0.011956498 +468 330 0.013545197 +469 330 0.0039297976 +470 330 0.0042641982 +471 330 0.0026755999 +472 330 8.3599996e-05 +473 330 8.3599996e-05 +477 330 8.3599996e-05 +478 330 0.00083609996 +483 330 0.0011705998 +490 330 0.00050169998 +491 330 0.0012541998 +9 331 1.7199985e-05 +16 331 1.7199985e-05 +18 331 8.6199987e-05 +22 331 0.00031049992 +60 331 0.0054679997 +78 331 3.4499986e-05 +79 331 1.7199985e-05 +82 331 1.7199985e-05 +83 331 1.7199985e-05 +84 331 1.7199985e-05 +98 331 3.4499986e-05 +108 331 1.7199985e-05 +113 331 5.1699986e-05 +114 331 0.00010349999 +126 331 5.1699986e-05 +127 331 1.7199985e-05 +134 331 1.7199985e-05 +135 331 1.7199985e-05 +140 331 0.00010349999 +142 331 3.4499986e-05 +150 331 0.00044849981 +151 331 1.7199985e-05 +156 331 3.4499986e-05 +160 331 0.0020698998 +161 331 1.7199985e-05 +165 331 1.7199985e-05 +169 331 0.00046569994 +171 331 1.7199985e-05 +172 331 0.00043119979 +181 331 1.7199985e-05 +189 331 6.8999987e-05 +190 331 6.8999987e-05 +192 331 3.4499986e-05 +194 331 8.6199987e-05 +196 331 1.7199985e-05 +197 331 1.7199985e-05 +198 331 8.6199987e-05 +200 331 5.1699986e-05 +201 331 3.4499986e-05 +203 331 5.1699986e-05 +204 331 8.6199987e-05 +206 331 0.00024149999 +207 331 5.1699986e-05 +209 331 1.7199985e-05 +214 331 0.00024149999 +222 331 1.7199985e-05 +225 331 0.00010349999 +233 331 0.0020525998 +234 331 0.0028460999 +237 331 0.013005797 +240 331 0.0030185999 +241 331 0.00091419998 +242 331 0.0015006999 +248 331 1.7199985e-05 +250 331 1.7199985e-05 +251 331 1.7199985e-05 +252 331 0.00010349999 +263 331 1.7199985e-05 +270 331 0.00012069999 +271 331 0.0036050999 +272 331 0.0027253998 +277 331 0.069686353 +279 331 1.7199985e-05 +282 331 0.047072798 +283 331 0.028564498 +284 331 0.0018801999 +285 331 8.6199987e-05 +289 331 3.4499986e-05 +292 331 0.0010176999 +293 331 0.0007071998 +294 331 0.00010349999 +295 331 0.00048299995 +296 331 0.0024320998 +297 331 0.00060369982 +298 331 0.00086249993 +299 331 8.6199987e-05 +304 331 6.8999987e-05 +305 331 6.8999987e-05 +307 331 0.0053645 +308 331 1.7199985e-05 +312 331 0.0080897994 +313 331 0.00017249999 +315 331 0.0055024996 +318 331 1.7199985e-05 +319 331 0.00012069999 +320 331 5.1699986e-05 +321 331 3.4499986e-05 +322 331 0.0024493998 +323 331 0.0010866998 +324 331 0.0053645 +326 331 0.00018969999 +327 331 3.4499986e-05 +328 331 0.037775598 +329 331 0.00079349987 +330 331 0.00010349999 +331 331 0.061251599 +332 331 0.00032769982 +333 331 8.6199987e-05 +336 331 3.4499986e-05 +337 331 0.00015519999 +338 331 0.0010003999 +339 331 0.0005347 +340 331 0.010142498 +341 331 0.00020699999 +346 331 1.7199985e-05 +349 331 1.7199985e-05 +350 331 0.011125699 +351 331 0.011349898 +352 331 0.00051749987 +353 331 1.7199985e-05 +354 331 0.034256697 +356 331 0.0015178998 +357 331 0.00024149999 +358 331 0.015731197 +366 331 0.00010349999 +370 331 0.00012069999 +371 331 0.0033463 +372 331 0.0053645 +373 331 0.0019836 +374 331 3.4499986e-05 +376 331 3.4499986e-05 +384 331 3.4499986e-05 +387 331 5.1699986e-05 +390 331 6.8999987e-05 +392 331 3.4499986e-05 +393 331 1.7199985e-05 +394 331 1.7199985e-05 +397 331 0.00031049992 +398 331 6.8999987e-05 +399 331 0.0013626998 +401 331 0.0011556998 +402 331 0.014333997 +404 331 0.00037949998 +405 331 0.00018969999 +408 331 0.00089699985 +412 331 5.1699986e-05 +414 331 1.7199985e-05 +415 331 5.1699986e-05 +417 331 0.0002931999 +419 331 1.7199985e-05 +421 331 5.1699986e-05 +422 331 6.8999987e-05 +423 331 1.7199985e-05 +425 331 1.7199985e-05 +430 331 1.7199985e-05 +431 331 3.4499986e-05 +432 331 1.7199985e-05 +433 331 3.4499986e-05 +434 331 3.4499986e-05 +441 331 0.00041399989 +442 331 1.7199985e-05 +443 331 0.0035532999 +444 331 0.0006899999 +445 331 0.0053126998 +446 331 0.00037949998 +447 331 0.0025873999 +448 331 1.7199985e-05 +450 331 0.0045709983 +452 331 0.0044847988 +453 331 0.0018973998 +454 331 0.00062099984 +455 331 0.042156797 +456 331 0.00050019985 +457 331 0.0042259991 +458 331 0.0010521999 +459 331 0.0014316998 +460 331 0.0010348998 +463 331 0.0040362999 +464 331 0.00081069977 +465 331 0.00077619986 +467 331 0.015196498 +468 331 0.0045364983 +469 331 0.0041052997 +470 331 0.0041397996 +471 331 0.0015697 +472 331 0.00018969999 +473 331 8.6199987e-05 +477 331 0.00012069999 +478 331 0.00087969983 +483 331 0.0011211999 +489 331 3.4499986e-05 +490 331 0.00032769982 +491 331 0.00081069977 +22 332 0.00013089999 +60 332 0.0027486999 +77 332 0.0002617999 +82 332 0.00013089999 +108 332 0.00013089999 +114 332 0.0002617999 +126 332 0.00013089999 +130 332 0.00013089999 +131 332 0.00013089999 +138 332 0.00013089999 +142 332 0.0002617999 +151 332 0.00013089999 +160 332 0.0037957998 +172 332 0.00078529981 +187 332 0.00013089999 +189 332 0.00013089999 +190 332 0.00013089999 +194 332 0.00013089999 +198 332 0.0002617999 +203 332 0.00013089999 +206 332 0.00039269985 +214 332 0.00078529981 +224 332 0.00013089999 +233 332 0.0014397998 +234 332 0.0036648999 +237 332 0.0026177999 +240 332 0.0002617999 +241 332 0.0019633998 +242 332 0.010863896 +252 332 0.00013089999 +263 332 0.0011779999 +270 332 0.012565397 +271 332 0.0013088998 +272 332 0.0028795998 +277 332 0.070026159 +282 332 0.042670198 +283 332 0.024476398 +284 332 0.0024869 +285 332 0.0060208999 +286 332 0.00013089999 +289 332 0.00013089999 +292 332 0.00065449998 +293 332 0.0010470999 +294 332 0.0089004971 +295 332 0.0023559998 +296 332 0.0010470999 +297 332 0.0014397998 +298 332 0.00078529981 +305 332 0.00013089999 +307 332 0.0060208999 +312 332 0.0082460977 +315 332 0.00078529981 +320 332 0.00013089999 +321 332 0.0002617999 +322 332 0.00013089999 +324 332 0.0023559998 +326 332 0.0066753998 +328 332 0.011387397 +331 332 0.0075915977 +332 332 0.045549698 +333 332 0.0011779999 +339 332 0.00078529981 +340 332 0.014790598 +341 332 0.00013089999 +343 332 0.00013089999 +344 332 0.00013089999 +349 332 0.0002617999 +350 332 0.0058900975 +351 332 0.014005199 +352 332 0.0036648999 +354 332 0.017277498 +356 332 0.00078529981 +358 332 0.014921498 +370 332 0.00013089999 +371 332 0.0023559998 +372 332 0.015314098 +373 332 0.0013088998 +385 332 0.00013089999 +387 332 0.00013089999 +390 332 0.00013089999 +393 332 0.00013089999 +398 332 0.0091622993 +399 332 0.00013089999 +402 332 0.0010470999 +408 332 0.00013089999 +416 332 0.00013089999 +417 332 0.0005235998 +422 332 0.00013089999 +434 332 0.00013089999 +441 332 0.0030105 +443 332 0.0027486999 +444 332 0.0013088998 +445 332 0.0066753998 +446 332 0.00013089999 +447 332 0.004973799 +450 332 0.0044502988 +452 332 0.0058900975 +453 332 0.0022250998 +454 332 0.00078529981 +455 332 0.036911 +456 332 0.00039269985 +457 332 0.0030105 +458 332 0.0010470999 +459 332 0.00065449998 +460 332 0.0010470999 +463 332 0.0069371983 +464 332 0.0005235998 +465 332 0.00078529981 +467 332 0.0115183 +468 332 0.0052355975 +469 332 0.0058900975 +470 332 0.0064135976 +471 332 0.0066753998 +472 332 0.0024869 +473 332 0.00013089999 +477 332 0.00013089999 +478 332 0.0010470999 +483 332 0.0014397998 +490 332 0.0005235998 +491 332 0.0047119968 +9 333 9.2199989e-05 +19 333 9.2199989e-05 +22 333 9.2199989e-05 +60 333 0.0023961 +77 333 0.00027649989 +79 333 9.2199989e-05 +82 333 9.2199989e-05 +108 333 9.2199989e-05 +114 333 0.00018429999 +126 333 9.2199989e-05 +160 333 0.0012901998 +169 333 0.00027649989 +172 333 0.0005528999 +189 333 9.2199989e-05 +190 333 9.2199989e-05 +192 333 9.2199989e-05 +194 333 9.2199989e-05 +198 333 0.00018429999 +200 333 9.2199989e-05 +203 333 9.2199989e-05 +204 333 9.2199989e-05 +206 333 0.00027649989 +207 333 9.2199989e-05 +214 333 0.0028569 +220 333 9.2199989e-05 +233 333 0.0011058999 +234 333 0.0030411999 +237 333 0.0011979998 +240 333 0.00036859978 +241 333 0.0043313988 +242 333 0.0109667 +270 333 0.0043313988 +272 333 0.00018429999 +277 333 0.072712183 +282 333 0.0319786 +283 333 0.015851099 +284 333 0.0024881999 +285 333 9.2199989e-05 +286 333 0.00027649989 +290 333 0.00018429999 +292 333 0.0020275 +293 333 0.0011979998 +294 333 9.2199989e-05 +296 333 0.00027649989 +297 333 0.0014744999 +298 333 0.00018429999 +299 333 0.00018429999 +305 333 0.0024881999 +307 333 0.00027649989 +312 333 0.0035940998 +315 333 0.0011979998 +319 333 9.2199989e-05 +320 333 9.2199989e-05 +321 333 0.0029489999 +322 333 9.2199989e-05 +324 333 0.011335399 +326 333 0.0037784998 +327 333 9.2199989e-05 +328 333 0.010874599 +331 333 0.00027649989 +333 333 0.0359414 +338 333 0.0019353 +339 333 0.00036859978 +340 333 0.010229498 +341 333 0.00036859978 +350 333 0.0025803999 +351 333 0.012533396 +354 333 0.0073725991 +356 333 0.00046079978 +357 333 0.0008293998 +358 333 0.023684498 +370 333 9.2199989e-05 +371 333 0.0062666982 +372 333 0.0038705999 +373 333 0.0037784998 +374 333 9.2199989e-05 +376 333 0.0009215998 +387 333 9.2199989e-05 +390 333 9.2199989e-05 +392 333 0.00018429999 +393 333 9.2199989e-05 +402 333 0.0042391978 +404 333 9.2199989e-05 +405 333 0.00027649989 +408 333 0.0015666999 +417 333 0.00046079978 +421 333 9.2199989e-05 +422 333 9.2199989e-05 +430 333 9.2199989e-05 +433 333 9.2199989e-05 +434 333 0.00018429999 +443 333 0.0020275 +444 333 0.0014744999 +445 333 0.0036862998 +446 333 0.00036859978 +447 333 0.0029489999 +450 333 0.0087549984 +452 333 0.0062666982 +453 333 0.0023961 +454 333 0.00036859978 +455 333 0.026725598 +456 333 0.00046079978 +457 333 0.0035940998 +458 333 0.00027649989 +459 333 0.00073729991 +460 333 0.0010136999 +463 333 0.017509896 +464 333 0.0005528999 +465 333 0.0010136999 +467 333 0.014837299 +468 333 0.0077411979 +469 333 0.006082397 +470 333 0.0064509995 +471 333 0.0032255 +473 333 0.00018429999 +477 333 9.2199989e-05 +478 333 0.0011058999 +483 333 0.0008293998 +490 333 0.0005528999 +491 333 0.0077411979 +22 334 0.0002291 +60 334 0.0027498 +108 334 0.0002291 +114 334 0.00045829988 +126 334 0.0002291 +160 334 0.0013748999 +172 334 0.0029789 +189 334 0.0002291 +194 334 0.0002291 +198 334 0.0016039999 +206 334 0.00045829988 +214 334 0.0002291 +233 334 0.00068739988 +234 334 0.0041246973 +241 334 0.0183318 +242 334 0.00091659999 +270 334 0.0016039999 +272 334 0.00045829988 +277 334 0.086388588 +282 334 0.021310698 +283 334 0.0054994971 +284 334 0.0029789 +292 334 0.0045829974 +293 334 0.0020623 +295 334 0.009165898 +296 334 0.0061869994 +297 334 0.06393218 +312 334 0.014207099 +320 334 0.0036664 +321 334 0.0192484 +322 334 0.0075618997 +324 334 0.00091659999 +326 334 0.0107699 +328 334 0.034142997 +334 334 0.0087075979 +335 334 0.0002291 +340 334 0.020623296 +351 334 0.0087075979 +354 334 0.031164099 +358 334 0.010082498 +367 334 0.00068739988 +371 334 0.0032080999 +372 334 0.0304766 +387 334 0.0002291 +414 334 0.0018332 +417 334 0.00045829988 +422 334 0.0002291 +443 334 0.0029789 +444 334 0.0032080999 +445 334 0.0045829974 +446 334 0.0002291 +447 334 0.011228196 +450 334 0.004812099 +452 334 0.004812099 +453 334 0.0013748999 +454 334 0.0002291 +455 334 0.026122797 +456 334 0.0002291 +457 334 0.0029789 +458 334 0.00091659999 +459 334 0.0013748999 +460 334 0.00068739988 +463 334 0.0192484 +464 334 0.00068739988 +465 334 0.00091659999 +467 334 0.012603097 +468 334 0.020164996 +469 334 0.009165898 +470 334 0.0096241981 +471 334 0.0089367963 +473 334 0.0002291 +478 334 0.0013748999 +483 334 0.0020623 +490 334 0.00091659999 +491 334 0.00068739988 +22 335 0.00011339999 +24 335 0.00011339999 +60 335 0.0020419999 +82 335 0.00011339999 +108 335 0.00011339999 +114 335 0.00011339999 +120 335 0.0002269 +126 335 0.00011339999 +135 335 0.00011339999 +150 335 0.00011339999 +160 335 0.0013612998 +172 335 0.0005671999 +189 335 0.00011339999 +190 335 0.00011339999 +193 335 0.00011339999 +194 335 0.0002269 +198 335 0.00079409988 +200 335 0.00011339999 +203 335 0.00011339999 +204 335 0.00011339999 +206 335 0.00034029991 +214 335 0.0011343998 +218 335 0.00011339999 +223 335 0.00011339999 +224 335 0.0002269 +233 335 0.00045379996 +234 335 0.0037435999 +237 335 0.0049914978 +241 335 0.0014747998 +242 335 0.012705598 +270 335 0.00011339999 +271 335 0.00011339999 +277 335 0.13045937 +282 335 0.012365296 +283 335 0.0069199987 +284 335 0.0026091998 +286 335 0.00011339999 +288 335 0.00011339999 +289 335 0.00011339999 +292 335 0.0020419999 +293 335 0.0040838979 +294 335 0.00034029991 +295 335 0.0010209999 +296 335 0.0023822999 +297 335 0.00011339999 +298 335 0.00045379996 +299 335 0.00011339999 +301 335 0.00011339999 +305 335 0.0081678964 +307 335 0.0005671999 +312 335 0.0057855994 +315 335 0.0029495 +319 335 0.0039704964 +320 335 0.00011339999 +321 335 0.00011339999 +322 335 0.0010209999 +324 335 0.0039704964 +326 335 0.00011339999 +328 335 0.0015882 +329 335 0.00011339999 +331 335 0.0010209999 +332 335 0.0002269 +335 335 0.034373198 +337 335 0.0036301999 +339 335 0.0010209999 +340 335 0.0031764 +344 335 0.0002269 +347 335 0.00011339999 +349 335 0.0002269 +350 335 0.0038570999 +351 335 0.018831499 +352 335 0.0002269 +354 335 0.019739099 +355 335 0.00011339999 +356 335 0.00045379996 +357 335 0.0020419999 +358 335 0.0080544986 +371 335 0.0057855994 +372 335 0.012138397 +373 335 0.0034033 +387 335 0.00011339999 +390 335 0.00045379996 +392 335 0.00034029991 +393 335 0.0002269 +398 335 0.00011339999 +402 335 0.00034029991 +404 335 0.0002269 +405 335 0.0013612998 +417 335 0.00045379996 +421 335 0.00011339999 +422 335 0.0002269 +430 335 0.00011339999 +443 335 0.0027225998 +444 335 0.0015882 +445 335 0.0063527972 +446 335 0.00011339999 +447 335 0.0043107979 +450 335 0.0044242963 +452 335 0.0049914978 +453 335 0.0018151 +454 335 0.00011339999 +455 335 0.034146298 +456 335 0.00045379996 +457 335 0.0030629998 +458 335 0.0005671999 +459 335 0.00045379996 +460 335 0.0010209999 +463 335 0.016789597 +464 335 0.00068069994 +465 335 0.00090749981 +467 335 0.011571199 +468 335 0.0060124993 +469 335 0.0076006986 +470 335 0.008508198 +471 335 0.0057855994 +473 335 0.0002269 +477 335 0.00011339999 +478 335 0.0012478998 +483 335 0.0018151 +490 335 0.00068069994 +491 335 0.0014747998 +60 336 0.0024917 +108 336 0.00020759999 +114 336 0.00041529979 +126 336 0.00020759999 +160 336 0.0018687998 +165 336 0.00020759999 +181 336 0.00020759999 +190 336 0.00020759999 +194 336 0.00020759999 +198 336 0.00020759999 +206 336 0.00062289997 +214 336 0.00020759999 +233 336 0.00062289997 +234 336 0.0033222998 +237 336 0.0020764 +241 336 0.0078903995 +242 336 0.0083055981 +252 336 0.00020759999 +270 336 0.00062289997 +272 336 0.0035299 +277 336 0.11025745 +282 336 0.030107997 +283 336 0.0091362 +284 336 0.0026992999 +285 336 0.00020759999 +292 336 0.009551499 +293 336 0.0012457999 +294 336 0.00041529979 +295 336 0.0064368993 +296 336 0.0062291995 +297 336 0.0014534998 +298 336 0.010382097 +305 336 0.00020759999 +307 336 0.00062289997 +312 336 0.011420298 +313 336 0.00020759999 +315 336 0.00062289997 +319 336 0.00020759999 +320 336 0.0014534998 +322 336 0.0014534998 +323 336 0.00041529979 +324 336 0.0020764 +328 336 0.0047756992 +331 336 0.0016611 +332 336 0.00062289997 +335 336 0.00041529979 +336 336 0.0049833991 +337 336 0.00062289997 +338 336 0.00020759999 +339 336 0.0010382 +340 336 0.0085132979 +344 336 0.00020759999 +350 336 0.00041529979 +351 336 0.013081398 +354 336 0.056893699 +357 336 0.00020759999 +358 336 0.034883697 +366 336 0.00041529979 +370 336 0.012043197 +371 336 0.0168189 +372 336 0.017649498 +373 336 0.010797299 +376 336 0.004360497 +386 336 0.00020759999 +387 336 0.00020759999 +397 336 0.00041529979 +398 336 0.00020759999 +399 336 0.00020759999 +401 336 0.0014534998 +402 336 0.00083059981 +417 336 0.00041529979 +422 336 0.00020759999 +443 336 0.0022840998 +444 336 0.0016611 +445 336 0.016195998 +446 336 0.00020759999 +447 336 0.0056062974 +450 336 0.004360497 +452 336 0.0049833991 +453 336 0.0031146 +454 336 0.00041529979 +455 336 0.030938499 +456 336 0.00020759999 +457 336 0.0029069998 +458 336 0.0012457999 +459 336 0.00062289997 +460 336 0.00083059981 +463 336 0.011004999 +464 336 0.00062289997 +465 336 0.0012457999 +467 336 0.011835497 +468 336 0.0014534998 +469 336 0.0060215965 +470 336 0.0070597976 +471 336 0.0078903995 +473 336 0.00020759999 +478 336 0.0012457999 +483 336 0.0010382 +490 336 0.00083059981 +491 336 0.0016611 +60 337 0.0020203998 +108 337 9.619999e-05 +114 337 9.619999e-05 +126 337 9.619999e-05 +150 337 9.619999e-05 +160 337 0.0017317999 +169 337 0.00028859987 +171 337 9.619999e-05 +172 337 0.00028859987 +181 337 0.0014430999 +189 337 9.619999e-05 +190 337 9.619999e-05 +194 337 0.0001924 +198 337 0.0001924 +200 337 9.619999e-05 +203 337 9.619999e-05 +206 337 0.00048099994 +214 337 0.0001924 +233 337 0.0011544998 +234 337 0.0031748998 +236 337 0.0001924 +237 337 0.016163196 +240 337 9.619999e-05 +241 337 0.0013468999 +242 337 0.0050990991 +270 337 9.619999e-05 +271 337 0.0018279999 +272 337 9.619999e-05 +277 337 0.076197743 +282 337 0.038772397 +283 337 0.0074080974 +284 337 0.0022127999 +288 337 9.619999e-05 +292 337 0.0010582998 +293 337 0.0053876974 +295 337 0.0010582998 +296 337 0.0015393 +297 337 9.619999e-05 +298 337 9.619999e-05 +305 337 0.0084663965 +307 337 9.619999e-05 +312 337 0.0063497983 +313 337 0.0011544998 +315 337 0.0012506999 +319 337 0.0078891963 +322 337 0.00076969992 +323 337 0.00028859987 +324 337 0.0054838993 +326 337 0.0010582998 +328 337 0.024725799 +329 337 0.0001924 +331 337 0.0016355999 +335 337 0.0001924 +337 337 0.059072498 +339 337 0.00067349989 +340 337 0.0053876974 +341 337 9.619999e-05 +350 337 0.0085625984 +351 337 0.011833798 +353 337 0.0003847999 +354 337 0.037232999 +356 337 0.0010582998 +357 337 0.016836599 +358 337 0.016547997 +366 337 9.619999e-05 +370 337 9.619999e-05 +371 337 0.010871697 +372 337 0.011160299 +373 337 0.0066383965 +376 337 0.0029824998 +387 337 9.619999e-05 +390 337 9.619999e-05 +394 337 0.0058688 +397 337 0.00028859987 +401 337 0.0003847999 +402 337 0.0011544998 +408 337 0.00067349989 +417 337 0.00028859987 +422 337 9.619999e-05 +430 337 9.619999e-05 +441 337 0.0013468999 +443 337 0.0023089999 +444 337 0.0003847999 +445 337 0.0077929981 +446 337 0.0001924 +447 337 0.0058688 +450 337 0.0033672999 +452 337 0.0036559999 +453 337 0.0018279999 +454 337 0.0001924 +455 337 0.035308797 +456 337 0.0003847999 +457 337 0.0027900999 +458 337 0.0010582998 +459 337 0.00048099994 +460 337 0.0010582998 +463 337 0.010679197 +464 337 0.0003847999 +465 337 0.00076969992 +467 337 0.010294396 +468 337 0.0049066991 +469 337 0.0052914992 +470 337 0.0058688 +471 337 0.0024051999 +473 337 9.619999e-05 +477 337 9.619999e-05 +478 337 0.0010582998 +483 337 0.0011544998 +490 337 0.00048099994 +491 337 0.0022127999 +9 338 7.4899988e-05 +18 338 7.4899988e-05 +22 338 0.00022469999 +60 338 0.0049426965 +82 338 7.4899988e-05 +83 338 7.4899988e-05 +84 338 7.4899988e-05 +108 338 7.4899988e-05 +113 338 0.00014979999 +114 338 0.00022469999 +126 338 0.00014979999 +127 338 7.4899988e-05 +150 338 0.00082379999 +160 338 0.0020219998 +171 338 0.00029959995 +172 338 0.00022469999 +189 338 0.00022469999 +190 338 0.00014979999 +192 338 7.4899988e-05 +194 338 0.00014979999 +198 338 0.00014979999 +200 338 7.4899988e-05 +203 338 7.4899988e-05 +204 338 7.4899988e-05 +206 338 0.00037439982 +207 338 7.4899988e-05 +214 338 0.00089869997 +223 338 7.4899988e-05 +233 338 7.4899988e-05 +234 338 0.0072642975 +237 338 0.00014979999 +241 338 0.00029959995 +242 338 7.4899988e-05 +248 338 7.4899988e-05 +250 338 7.4899988e-05 +252 338 0.00014979999 +270 338 0.0050175972 +272 338 7.4899988e-05 +277 338 0.046206798 +282 338 0.038118798 +283 338 0.0038194 +284 338 0.0032203 +285 338 0.00059909979 +286 338 7.4899988e-05 +288 338 7.4899988e-05 +289 338 0.00014979999 +292 338 0.0014978 +293 338 0.0014228998 +294 338 0.00029959995 +295 338 0.0019470998 +296 338 0.0034448998 +297 338 0.0010485 +298 338 0.007788498 +299 338 7.4899988e-05 +300 338 7.4899988e-05 +307 338 0.010185 +312 338 0.0070395991 +315 338 7.4899988e-05 +317 338 0.0007489 +318 338 0.0014978 +319 338 7.4899988e-05 +320 338 0.0017225 +321 338 7.4899988e-05 +322 338 0.0020968998 +324 338 0.00014979999 +326 338 0.00029959995 +328 338 0.00037439982 +331 338 7.4899988e-05 +338 338 0.046057098 +339 338 0.0007489 +340 338 0.017748799 +341 338 0.00059909979 +343 338 0.00014979999 +344 338 7.4899988e-05 +347 338 7.4899988e-05 +349 338 0.00029959995 +350 338 0.018048398 +351 338 0.012656298 +353 338 7.4899988e-05 +354 338 0.0065153986 +356 338 0.0024714 +358 338 0.027559299 +366 338 7.4899988e-05 +371 338 0.0034448998 +372 338 0.016101297 +373 338 0.031678297 +384 338 7.4899988e-05 +387 338 0.00014979999 +393 338 7.4899988e-05 +402 338 7.4899988e-05 +404 338 7.4899988e-05 +405 338 7.4899988e-05 +417 338 0.0056915991 +419 338 7.4899988e-05 +421 338 7.4899988e-05 +422 338 0.00014979999 +423 338 7.4899988e-05 +425 338 7.4899988e-05 +430 338 7.4899988e-05 +431 338 7.4899988e-05 +433 338 7.4899988e-05 +434 338 7.4899988e-05 +443 338 0.0017972998 +444 338 0.00029959995 +445 338 0.0032950998 +446 338 0.00029959995 +447 338 0.0010485 +450 338 0.0062906966 +452 338 0.0077135973 +453 338 0.0020219998 +454 338 0.00037439982 +455 338 0.036246497 +456 338 0.0010485 +457 338 0.0035946998 +458 338 0.00082379999 +459 338 0.00037439982 +460 338 0.0011981998 +463 338 0.0057664998 +464 338 0.00037439982 +465 338 0.0013479998 +467 338 0.012656298 +468 338 0.0017972998 +469 338 0.010185 +470 338 0.011308298 +471 338 0.0013479998 +473 338 0.00029959995 +477 338 7.4899988e-05 +478 338 0.0016476 +483 338 0.0028457998 +489 338 7.4899988e-05 +490 338 0.0014978 +491 338 0.0053172 +19 339 0.00014199999 +24 339 0.00028409995 +60 339 0.0041186996 +82 339 0.00014199999 +108 339 0.00014199999 +114 339 0.00014199999 +126 339 0.00014199999 +150 339 0.00014199999 +160 339 0.0015622999 +169 339 0.00028409995 +172 339 0.00056809979 +189 339 0.00014199999 +190 339 0.00014199999 +193 339 0.00014199999 +194 339 0.00014199999 +203 339 0.00014199999 +204 339 0.00028409995 +206 339 0.00042609987 +214 339 0.00071009994 +223 339 0.0018463 +233 339 0.00014199999 +234 339 0.0069591999 +237 339 0.00014199999 +240 339 0.00014199999 +241 339 0.00014199999 +254 339 0.00042609987 +265 339 0.00014199999 +266 339 0.00014199999 +270 339 0.0052548982 +272 339 0.0052548982 +277 339 0.073284984 +282 339 0.041187298 +283 339 0.010651898 +284 339 0.0032666 +285 339 0.00028409995 +286 339 0.00014199999 +289 339 0.00014199999 +292 339 0.0017042998 +293 339 0.0019883998 +294 339 0.0019883998 +295 339 0.00099419989 +296 339 0.0015622999 +297 339 0.0048288964 +298 339 0.0088055991 +307 339 0.0083794966 +312 339 0.0053969994 +317 339 0.0028404999 +320 339 0.00014199999 +321 339 0.00028409995 +322 339 0.0026984999 +324 339 0.00014199999 +328 339 0.00014199999 +338 339 0.0042607971 +339 339 0.032239698 +340 339 0.012356199 +341 339 0.00042609987 +342 339 0.00028409995 +343 339 0.00028409995 +349 339 0.00028409995 +350 339 0.0124982 +351 339 0.0086634979 +352 339 0.00014199999 +353 339 0.00099419989 +354 339 0.015622798 +355 339 0.00014199999 +356 339 0.0015622999 +358 339 0.035222299 +370 339 0.00014199999 +371 339 0.0032666 +372 339 0.011930097 +373 339 0.027410898 +374 339 0.00014199999 +386 339 0.00014199999 +387 339 0.00014199999 +417 339 0.00071009994 +421 339 0.00014199999 +422 339 0.00014199999 +430 339 0.00014199999 +434 339 0.00014199999 +443 339 0.0021303999 +444 339 0.00042609987 +445 339 0.0036926998 +446 339 0.00028409995 +447 339 0.0012782 +450 339 0.0042607971 +452 339 0.0066751987 +453 339 0.0022723998 +454 339 0.00028409995 +455 339 0.034086097 +456 339 0.00071009994 +457 339 0.0038347 +458 339 0.0011361998 +459 339 0.00042609987 +460 339 0.0011361998 +463 339 0.0066751987 +464 339 0.00042609987 +465 339 0.00085219997 +467 339 0.011646099 +468 339 0.0012782 +469 339 0.0085214972 +470 339 0.0092315972 +471 339 0.00085219997 +473 339 0.00028409995 +477 339 0.00014199999 +478 339 0.0012782 +483 339 0.0018463 +490 339 0.00085219997 +491 339 0.0061070994 +9 340 4.9099996e-05 +18 340 4.9099996e-05 +22 340 7.3599993e-05 +60 340 0.0030415 +82 340 4.9099996e-05 +83 340 4.9099996e-05 +84 340 4.9099996e-05 +108 340 4.9099996e-05 +113 340 9.809999e-05 +114 340 0.00014719999 +126 340 7.3599993e-05 +127 340 2.4499997e-05 +130 340 0.0002942998 +131 340 4.9099996e-05 +134 340 4.9099996e-05 +139 340 2.4499997e-05 +142 340 2.4499997e-05 +150 340 0.0008584999 +156 340 0.00039249985 +158 340 4.9099996e-05 +160 340 0.00026979996 +169 340 0.0001717 +171 340 0.0002942998 +172 340 0.0006622998 +181 340 4.9099996e-05 +187 340 0.0001717 +188 340 0.0001962 +189 340 9.809999e-05 +190 340 0.00012259999 +192 340 7.3599993e-05 +193 340 2.4499997e-05 +194 340 0.00022079999 +196 340 2.4499997e-05 +197 340 4.9099996e-05 +198 340 0.0011037998 +200 340 7.3599993e-05 +201 340 2.4499997e-05 +203 340 7.3599993e-05 +204 340 7.3599993e-05 +206 340 0.00031889998 +207 340 4.9099996e-05 +209 340 2.4499997e-05 +214 340 0.0037528998 +218 340 2.4499997e-05 +219 340 9.809999e-05 +223 340 0.00068679987 +224 340 0.0033604 +225 340 0.00012259999 +227 340 2.4499997e-05 +229 340 4.9099996e-05 +233 340 0.0015207999 +234 340 0.0060830973 +237 340 0.00039249985 +240 340 0.00034339982 +241 340 0.0037037998 +242 340 2.4499997e-05 +248 340 2.4499997e-05 +252 340 0.00053959992 +253 340 2.4499997e-05 +270 340 0.0083641969 +271 340 4.9099996e-05 +272 340 0.00049059978 +274 340 4.9099996e-05 +276 340 4.9099996e-05 +277 340 0.067526758 +278 340 4.9099996e-05 +282 340 0.012460399 +283 340 0.0021584998 +284 340 0.0032867999 +285 340 0.017586898 +286 340 0.0001962 +287 340 0.00078489981 +288 340 0.0009321 +289 340 0.0019622999 +290 340 0.0001962 +292 340 0.0023546999 +293 340 0.0029678999 +294 340 0.00053959992 +295 340 0.0007358999 +296 340 0.0026490998 +297 340 0.0009321 +298 340 0.0024773998 +299 340 0.0001962 +301 340 4.9099996e-05 +307 340 0.00041699992 +312 340 0.0037773999 +313 340 0.0022810998 +315 340 0.00076039997 +317 340 0.0012754998 +318 340 2.4499997e-05 +319 340 0.00076039997 +320 340 0.0024283 +321 340 0.0001962 +322 340 0.00039249985 +323 340 7.3599993e-05 +324 340 2.4499997e-05 +325 340 7.3599993e-05 +326 340 0.0023792998 +328 340 0.00026979996 +330 340 2.4499997e-05 +331 340 4.9099996e-05 +332 340 2.4499997e-05 +338 340 0.0048320964 +339 340 0.00083399983 +340 340 0.044813499 +341 340 0.00022079999 +343 340 0.00044149999 +344 340 7.3599993e-05 +345 340 2.4499997e-05 +347 340 2.4499997e-05 +348 340 2.4499997e-05 +349 340 0.00014719999 +350 340 0.00095659983 +351 340 0.0032378 +353 340 0.0013245 +354 340 0.0011282999 +355 340 2.4499997e-05 +356 340 0.00041699992 +357 340 0.00012259999 +358 340 0.020309497 +366 340 7.3599993e-05 +369 340 0.00012259999 +370 340 9.809999e-05 +371 340 0.00095659983 +372 340 0.0013245 +373 340 0.0015452998 +374 340 0.00058869994 +375 340 2.4499997e-05 +376 340 2.4499997e-05 +384 340 9.809999e-05 +385 340 9.809999e-05 +386 340 0.0001717 +387 340 0.00012259999 +390 340 4.9099996e-05 +392 340 9.809999e-05 +393 340 0.00026979996 +394 340 7.3599993e-05 +397 340 0.00026979996 +398 340 7.3599993e-05 +399 340 2.4499997e-05 +401 340 0.00039249985 +402 340 0.0032867999 +404 340 7.3599993e-05 +405 340 0.0001717 +414 340 9.809999e-05 +415 340 2.4499997e-05 +417 340 0.00068679987 +419 340 2.4499997e-05 +420 340 2.4499997e-05 +421 340 7.3599993e-05 +422 340 0.00012259999 +423 340 4.9099996e-05 +424 340 0.00071129994 +425 340 2.4499997e-05 +430 340 4.9099996e-05 +431 340 4.9099996e-05 +432 340 2.4499997e-05 +433 340 4.9099996e-05 +434 340 4.9099996e-05 +441 340 4.9099996e-05 +442 340 4.9099996e-05 +443 340 0.0025754999 +444 340 0.00061319978 +445 340 0.0030169999 +446 340 0.00034339982 +447 340 0.0025263999 +448 340 2.4499997e-05 +450 340 0.0048565976 +452 340 0.0076773986 +453 340 0.0018886998 +454 340 0.00024529989 +455 340 0.019009497 +456 340 0.00083399983 +457 340 0.0035075999 +458 340 0.0007358999 +459 340 0.00056419987 +460 340 0.0012999999 +463 340 0.0094188973 +464 340 0.00049059978 +465 340 0.0012263998 +467 340 0.012215197 +468 340 0.0018642 +469 340 0.0062301978 +470 340 0.0068924986 +471 340 0.0014962 +473 340 0.00014719999 +477 340 0.00012259999 +478 340 0.0014471998 +479 340 2.4499997e-05 +483 340 0.0014962 +489 340 4.9099996e-05 +490 340 0.0038019 +491 340 0.0014225999 +19 341 0.0001582 +22 341 0.0001582 +60 341 0.0014240998 +108 341 0.0001582 +114 341 0.0001582 +126 341 0.0001582 +150 341 0.0001582 +160 341 0.0012657999 +171 341 0.00031649997 +172 341 0.00094939978 +189 341 0.0001582 +190 341 0.0001582 +194 341 0.0001582 +198 341 0.0068037994 +203 341 0.00031649997 +206 341 0.00047469977 +214 341 0.00079109985 +223 341 0.0017404999 +234 341 0.0080695972 +237 341 0.0001582 +240 341 0.0018986999 +241 341 0.012025297 +267 341 0.0001582 +270 341 0.0022151999 +276 341 0.0042721964 +277 341 0.041139197 +279 341 0.00079109985 +282 341 0.013291098 +283 341 0.0026898999 +284 341 0.0031645999 +285 341 0.011075899 +286 341 0.00047469977 +288 341 0.00031649997 +289 341 0.0014240998 +292 341 0.0015822998 +293 341 0.0020569998 +294 341 0.015189897 +295 341 0.013449397 +296 341 0.032911398 +297 341 0.0011075998 +298 341 0.0128165 +307 341 0.0088607967 +312 341 0.011075899 +315 341 0.0026898999 +317 341 0.00079109985 +318 341 0.0022151999 +320 341 0.0031645999 +321 341 0.0001582 +322 341 0.0001582 +326 341 0.0001582 +328 341 0.0001582 +331 341 0.0001582 +332 341 0.0001582 +338 341 0.0001582 +339 341 0.0001582 +340 341 0.036392398 +341 341 0.0049050972 +344 341 0.0001582 +350 341 0.0001582 +351 341 0.014873397 +353 341 0.0001582 +354 341 0.0128165 +356 341 0.00094939978 +358 341 0.014398698 +371 341 0.0063290969 +372 341 0.0131329 +373 341 0.0344937 +386 341 0.0068037994 +387 341 0.0001582 +417 341 0.00063289981 +421 341 0.0001582 +422 341 0.0001582 +430 341 0.0001582 +434 341 0.0001582 +443 341 0.0017404999 +444 341 0.00079109985 +445 341 0.0037974999 +447 341 0.0075948983 +450 341 0.0036391998 +452 341 0.005854398 +453 341 0.0014240998 +454 341 0.00063289981 +455 341 0.031329099 +456 341 0.00079109985 +457 341 0.0036391998 +458 341 0.0011075998 +459 341 0.00047469977 +460 341 0.0011075998 +463 341 0.012183499 +464 341 0.00079109985 +465 341 0.00094939978 +467 341 0.0099683963 +468 341 0.0028480999 +469 341 0.0066455975 +470 341 0.0074366964 +471 341 0.00094939978 +472 341 0.0014240998 +473 341 0.0001582 +477 341 0.00031649997 +478 341 0.0012657999 +483 341 0.0012657999 +490 341 0.0020569998 +491 341 0.0026898999 +22 342 0.00036019995 +24 342 0.00036019995 +60 342 0.0072045997 +108 342 0.00036019995 +114 342 0.00072049978 +126 342 0.00036019995 +160 342 0.0010807 +172 342 0.00072049978 +206 342 0.00072049978 +223 342 0.0021613999 +234 342 0.0068443976 +240 342 0.0057636984 +270 342 0.0018012 +276 342 0.0010807 +277 342 0.049351599 +278 342 0.0014408999 +282 342 0.015129697 +283 342 0.032780997 +284 342 0.0032420999 +285 342 0.00036019995 +290 342 0.00036019995 +292 342 0.0010807 +294 342 0.012247797 +295 342 0.0010807 +296 342 0.00036019995 +297 342 0.0039624982 +298 342 0.0043227971 +307 342 0.0064840987 +312 342 0.0093659982 +315 342 0.0025215999 +317 342 0.00072049978 +328 342 0.00036019995 +338 342 0.00036019995 +339 342 0.0093659982 +340 342 0.013688799 +341 342 0.00036019995 +342 342 0.013328496 +349 342 0.00036019995 +350 342 0.0223343 +351 342 0.011167098 +353 342 0.0014408999 +354 342 0.011527397 +356 342 0.0014408999 +358 342 0.027017299 +370 342 0.00036019995 +371 342 0.0028817998 +372 342 0.0028817998 +373 342 0.0162104 +374 342 0.00036019995 +375 342 0.00072049978 +386 342 0.0036022998 +387 342 0.00036019995 +417 342 0.00072049978 +443 342 0.0021613999 +444 342 0.00072049978 +445 342 0.0028817998 +447 342 0.0010807 +450 342 0.0036022998 +452 342 0.0079250969 +453 342 0.0068443976 +454 342 0.00072049978 +455 342 0.024495699 +456 342 0.00036019995 +457 342 0.0039624982 +458 342 0.00072049978 +459 342 0.00036019995 +460 342 0.0010807 +463 342 0.0025215999 +464 342 0.00036019995 +465 342 0.00072049978 +467 342 0.011167098 +468 342 0.0010807 +469 342 0.0079250969 +470 342 0.0090057999 +471 342 0.0010807 +473 342 0.00036019995 +478 342 0.0010807 +483 342 0.0018012 +490 342 0.0014408999 +491 342 0.0108069 +60 343 0.0016154998 +108 343 0.0002308 +114 343 0.00046159979 +126 343 0.0002308 +142 343 0.0002308 +160 343 0.0011538998 +172 343 0.00092309993 +194 343 0.0002308 +198 343 0.00069239992 +206 343 0.00069239992 +214 343 0.0011538998 +223 343 0.0023079 +233 343 0.0002308 +234 343 0.0060004964 +236 343 0.0002308 +237 343 0.0002308 +240 343 0.0011538998 +241 343 0.0062311999 +270 343 0.0018463 +277 343 0.045465 +282 343 0.013385598 +283 343 0.0018463 +284 343 0.0030001998 +285 343 0.0057696998 +286 343 0.0002308 +289 343 0.0066927969 +290 343 0.0002308 +292 343 0.018924497 +293 343 0.0027693999 +294 343 0.010616198 +295 343 0.0025386999 +296 343 0.0043849982 +297 343 0.0053080991 +298 343 0.0034617998 +307 343 0.010846999 +312 343 0.012231696 +315 343 0.0078467987 +317 343 0.00046159979 +318 343 0.0002308 +320 343 0.0023079 +321 343 0.00046159979 +322 343 0.0069235973 +324 343 0.0002308 +326 343 0.0080774985 +328 343 0.00069239992 +338 343 0.00046159979 +339 343 0.00092309993 +340 343 0.026540499 +341 343 0.0002308 +343 343 0.0270021 +347 343 0.0002308 +349 343 0.00046159979 +350 343 0.0120009 +351 343 0.0055388995 +353 343 0.0002308 +354 343 0.011539299 +355 343 0.0002308 +356 343 0.0016154998 +358 343 0.016616698 +370 343 0.00046159979 +371 343 0.0023079 +372 343 0.0120009 +373 343 0.014539599 +374 343 0.00046159979 +387 343 0.0002308 +401 343 0.0002308 +402 343 0.0002308 +405 343 0.0002308 +417 343 0.00046159979 +443 343 0.0013846999 +444 343 0.0023079 +445 343 0.0090007 +447 343 0.011077799 +450 343 0.0041541979 +452 343 0.0053080991 +453 343 0.0016154998 +454 343 0.0002308 +455 343 0.025155798 +456 343 0.00046159979 +457 343 0.0036925999 +458 343 0.00069239992 +459 343 0.00046159979 +460 343 0.00069239992 +463 343 0.013847198 +464 343 0.00069239992 +465 343 0.00092309993 +467 343 0.010616198 +468 343 0.0016154998 +469 343 0.0083082989 +470 343 0.0092314966 +471 343 0.00069239992 +473 343 0.0002308 +478 343 0.0013846999 +483 343 0.00069239992 +490 343 0.0011538998 +491 343 0.0032309999 +9 344 0.00010729999 +22 344 0.00010729999 +60 344 0.0025758999 +82 344 0.00010729999 +108 344 0.00010729999 +114 344 0.00021469999 +126 344 0.00010729999 +142 344 0.00010729999 +150 344 0.00010729999 +160 344 0.0038639 +169 344 0.00085859979 +171 344 0.00010729999 +172 344 0.00042929989 +187 344 0.00010729999 +188 344 0.00021469999 +189 344 0.00010729999 +190 344 0.00010729999 +194 344 0.00021469999 +198 344 0.00053669978 +200 344 0.00010729999 +203 344 0.00010729999 +204 344 0.00010729999 +206 344 0.00021469999 +214 344 0.0010732999 +223 344 0.00021469999 +224 344 0.00021469999 +233 344 0.00042929989 +234 344 0.0064397976 +236 344 0.00021469999 +237 344 0.00021469999 +240 344 0.00021469999 +241 344 0.0052591972 +242 344 0.0086937994 +252 344 0.00021469999 +270 344 0.00021469999 +272 344 0.00010729999 +277 344 0.066759646 +282 344 0.0226468 +283 344 0.0031126 +284 344 0.0018245999 +285 344 0.0010732999 +286 344 0.00010729999 +289 344 0.00021469999 +292 344 0.0017172999 +293 344 0.004937198 +294 344 0.0015025998 +295 344 0.0095523968 +296 344 0.0047225989 +297 344 0.0024685999 +298 344 0.00010729999 +299 344 0.00010729999 +301 344 0.00010729999 +307 344 0.012665 +312 344 0.0027905998 +314 344 0.00042929989 +315 344 0.0078350976 +319 344 0.00010729999 +320 344 0.00021469999 +321 344 0.0053664967 +322 344 0.0048298985 +324 344 0.0059031993 +326 344 0.0040785968 +328 344 0.00053669978 +329 344 0.00021469999 +331 344 0.00010729999 +338 344 0.0015025998 +339 344 0.00075129978 +340 344 0.0080497973 +341 344 0.00021469999 +344 344 0.047654796 +347 344 0.00064399978 +349 344 0.00042929989 +350 344 0.0061177984 +351 344 0.0084790997 +352 344 0.0012879998 +354 344 0.018890198 +356 344 0.0010732999 +358 344 0.018031597 +362 344 0.00096599991 +366 344 0.0030053 +371 344 0.0015025998 +372 344 0.015884899 +373 344 0.0084790997 +386 344 0.00010729999 +387 344 0.00010729999 +393 344 0.00010729999 +402 344 0.00021469999 +417 344 0.00053669978 +421 344 0.00010729999 +422 344 0.00021469999 +430 344 0.00010729999 +443 344 0.0021465998 +444 344 0.00042929989 +445 344 0.0040785968 +446 344 0.00021469999 +447 344 0.011913698 +450 344 0.0044005997 +452 344 0.0050444975 +453 344 0.0016099999 +454 344 0.00032199989 +455 344 0.0296233 +456 344 0.00085859979 +457 344 0.0042931996 +458 344 0.00064399978 +459 344 0.00032199989 +460 344 0.0010732999 +463 344 0.023290798 +464 344 0.00053669978 +465 344 0.0011805999 +467 344 0.0099817999 +468 344 0.0015025998 +469 344 0.0078350976 +470 344 0.0085864998 +471 344 0.00096599991 +473 344 0.00021469999 +477 344 0.00010729999 +478 344 0.0012879998 +483 344 0.0020392998 +490 344 0.00075129978 +491 344 0.0042931996 +60 345 0.0033787999 +82 345 0.00012999999 +108 345 0.00012999999 +114 345 0.00012999999 +126 345 0.00012999999 +130 345 0.0005198 +150 345 0.00012999999 +160 345 0.005847998 +161 345 0.0015594999 +172 345 0.00038989983 +189 345 0.00012999999 +190 345 0.00012999999 +194 345 0.0002599 +200 345 0.00012999999 +203 345 0.00012999999 +204 345 0.00012999999 +206 345 0.0002599 +214 345 0.00064979983 +218 345 0.00012999999 +222 345 0.00012999999 +224 345 0.00012999999 +225 345 0.0005198 +234 345 0.0090967976 +236 345 0.00012999999 +237 345 0.00012999999 +240 345 0.00012999999 +241 345 0.017023999 +242 345 0.0057179965 +277 345 0.079662085 +282 345 0.033138398 +283 345 0.0015594999 +284 345 0.0022091998 +290 345 0.0031188999 +292 345 0.0018193999 +293 345 0.012085799 +294 345 0.0031188999 +296 345 0.011305999 +305 345 0.00012999999 +307 345 0.0010396 +312 345 0.010526299 +317 345 0.0011695998 +319 345 0.00012999999 +324 345 0.0025990999 +326 345 0.00012999999 +328 345 0.00012999999 +331 345 0.00012999999 +338 345 0.0027289998 +340 345 0.007017497 +341 345 0.00038989983 +344 345 0.00012999999 +345 345 0.043534797 +347 345 0.00012999999 +349 345 0.00012999999 +350 345 0.0038985999 +351 345 0.0109162 +354 345 0.014684897 +356 345 0.0005198 +358 345 0.0162443 +366 345 0.00012999999 +371 345 0.0014294998 +372 345 0.011176098 +373 345 0.0081870966 +387 345 0.00012999999 +417 345 0.00064979983 +421 345 0.00012999999 +422 345 0.0002599 +430 345 0.00012999999 +443 345 0.0024690998 +444 345 0.0005198 +445 345 0.0042884983 +446 345 0.0002599 +447 345 0.0011695998 +450 345 0.004938297 +452 345 0.007017497 +453 345 0.0012995 +454 345 0.00038989983 +455 345 0.026640698 +456 345 0.0010396 +457 345 0.0038985999 +458 345 0.0012995 +459 345 0.0005198 +460 345 0.0012995 +463 345 0.010396399 +464 345 0.0005198 +465 345 0.0012995 +467 345 0.011695899 +468 345 0.0016893998 +469 345 0.007407397 +470 345 0.0084469989 +471 345 0.0010396 +473 345 0.0002599 +477 345 0.00012999999 +478 345 0.0016893998 +483 345 0.0022091998 +490 345 0.017023999 +491 345 0.0053280964 +60 346 0.0017275 +108 346 0.0002159 +114 346 0.00043189991 +126 346 0.0002159 +160 346 0.0023752998 +194 346 0.0002159 +198 346 0.0090692975 +206 346 0.00043189991 +214 346 0.0002159 +233 346 0.0047505982 +234 346 0.0056142993 +236 346 0.0002159 +237 346 0.00064779981 +241 346 0.0095011964 +242 346 0.0071258992 +270 346 0.0060461983 +272 346 0.00064779981 +277 346 0.041675698 +282 346 0.029799197 +283 346 0.010580897 +284 346 0.0017275 +285 346 0.0088533983 +293 346 0.0010797 +294 346 0.0002159 +295 346 0.0002159 +296 346 0.015331499 +297 346 0.0002159 +298 346 0.00043189991 +307 346 0.0097170994 +311 346 0.0010797 +312 346 0.00064779981 +315 346 0.0002159 +317 346 0.0002159 +318 346 0.0002159 +320 346 0.0062620975 +328 346 0.093284369 +330 346 0.0010797 +331 346 0.0002159 +338 346 0.0017275 +339 346 0.0002159 +340 346 0.06780386 +341 346 0.0002159 +346 346 0.0051824972 +347 346 0.0002159 +350 346 0.00086369994 +351 346 0.014683697 +353 346 0.0066939965 +354 346 0.0015115999 +356 346 0.0002159 +358 346 0.021377698 +371 346 0.0002159 +372 346 0.0246167 +373 346 0.0017275 +387 346 0.0002159 +395 346 0.0002159 +417 346 0.00064779981 +443 346 0.0017275 +444 346 0.0095011964 +445 346 0.0041027963 +447 346 0.011876497 +450 346 0.0038867998 +452 346 0.0047505982 +453 346 0.0019433999 +454 346 0.00086369994 +455 346 0.031742599 +456 346 0.00043189991 +457 346 0.0043186992 +458 346 0.00064779981 +459 346 0.00043189991 +460 346 0.00064779981 +463 346 0.025696397 +464 346 0.00086369994 +465 346 0.00064779981 +467 346 0.0090692975 +468 346 0.0012955999 +469 346 0.0060461983 +470 346 0.0064780973 +471 346 0.00064779981 +473 346 0.0002159 +478 346 0.0010797 +483 346 0.0012955999 +490 346 0.00064779981 +491 346 0.003239 +60 347 0.0046533979 +108 347 0.00024489989 +114 347 0.00048979977 +126 347 0.00024489989 +142 347 0.00024489989 +160 347 0.0034288999 +169 347 0.00073479977 +172 347 0.00097969989 +187 347 0.00024489989 +188 347 0.00048979977 +189 347 0.00024489989 +190 347 0.00024489989 +194 347 0.00024489989 +206 347 0.00048979977 +214 347 0.0029389998 +223 347 0.00024489989 +234 347 0.0063678995 +236 347 0.00024489989 +237 347 0.00024489989 +240 347 0.0097966976 +241 347 0.00024489989 +242 347 0.00024489989 +252 347 0.00024489989 +270 347 0.00048979977 +277 347 0.066372752 +282 347 0.023022298 +283 347 0.012735698 +284 347 0.0019592999 +285 347 0.00024489989 +286 347 0.00048979977 +289 347 0.00048979977 +290 347 0.00024489989 +292 347 0.0031838999 +293 347 0.00024489989 +294 347 0.00073479977 +295 347 0.0036737998 +296 347 0.00024489989 +305 347 0.00024489989 +307 347 0.0058779977 +312 347 0.0034288999 +320 347 0.00048979977 +321 347 0.00048979977 +322 347 0.0024491998 +324 347 0.0036737998 +326 347 0.00024489989 +328 347 0.00048979977 +332 347 0.00048979977 +338 347 0.0026940999 +340 347 0.0061228983 +341 347 0.00048979977 +347 347 0.064903259 +349 347 0.0014694999 +350 347 0.00048979977 +351 347 0.015674699 +354 347 0.027675699 +356 347 0.00048979977 +358 347 0.031349499 +371 347 0.0034288999 +372 347 0.013715398 +373 347 0.017634097 +387 347 0.00024489989 +390 347 0.00024489989 +393 347 0.00024489989 +408 347 0.00024489989 +417 347 0.00048979977 +443 347 0.0012245998 +444 347 0.00048979977 +445 347 0.013715398 +447 347 0.0012245998 +450 347 0.0048983991 +452 347 0.0058779977 +453 347 0.0019592999 +454 347 0.00024489989 +455 347 0.038696997 +456 347 0.00048979977 +457 347 0.0039186999 +458 347 0.00073479977 +459 347 0.00048979977 +460 347 0.0012245998 +463 347 0.016899299 +464 347 0.00048979977 +465 347 0.00097969989 +467 347 0.012000997 +468 347 0.0012245998 +469 347 0.0088169985 +470 347 0.0097966976 +471 347 0.0014694999 +473 347 0.00024489989 +478 347 0.0017143998 +483 347 0.0026940999 +490 347 0.00097969989 +491 347 0.012000997 +22 348 0.0001314 +24 348 0.0001314 +60 348 0.0031545998 +108 348 0.0001314 +114 348 0.0001314 +120 348 0.0001314 +126 348 0.0001314 +130 348 0.00052579981 +140 348 0.00039429986 +150 348 0.0001314 +160 348 0.0067034997 +172 348 0.00052579981 +187 348 0.0010515 +189 348 0.0001314 +190 348 0.0001314 +194 348 0.00026289979 +198 348 0.00039429986 +204 348 0.00026289979 +206 348 0.00026289979 +208 348 0.0001314 +211 348 0.0001314 +214 348 0.0010515 +218 348 0.0001314 +221 348 0.0001314 +222 348 0.0001314 +223 348 0.00026289979 +224 348 0.00052579981 +225 348 0.0009200999 +227 348 0.0001314 +234 348 0.0064405985 +236 348 0.0001314 +237 348 0.0001314 +240 348 0.00039429986 +241 348 0.0024973999 +242 348 0.0092007965 +243 348 0.0001314 +270 348 0.0032859999 +277 348 0.025499497 +282 348 0.033385899 +283 348 0.0093322992 +284 348 0.0017086999 +290 348 0.0013144 +292 348 0.0162986 +293 348 0.0056518987 +294 348 0.0013144 +295 348 0.0009200999 +296 348 0.0047318973 +301 348 0.0001314 +307 348 0.0077549964 +308 348 0.0013144 +312 348 0.0051261969 +315 348 0.0001314 +317 348 0.0014457998 +320 348 0.0001314 +322 348 0.0015772998 +324 348 0.0014457998 +340 348 0.0086750984 +341 348 0.00026289979 +345 348 0.0001314 +347 348 0.00078859995 +348 348 0.054942198 +350 348 0.0068348981 +351 348 0.011698198 +353 348 0.0001314 +354 348 0.027733997 +356 348 0.00052579981 +358 348 0.016693 +359 348 0.0042060986 +361 348 0.0001314 +369 348 0.00026289979 +371 348 0.0015772998 +372 348 0.013144098 +373 348 0.0098579973 +386 348 0.00026289979 +387 348 0.0001314 +392 348 0.0009200999 +393 348 0.0057833977 +417 348 0.00039429986 +422 348 0.00039429986 +430 348 0.00052579981 +443 348 0.0015772998 +444 348 0.0052575991 +445 348 0.0039431974 +446 348 0.0001314 +447 348 0.012224 +450 348 0.0039431974 +452 348 0.0051261969 +453 348 0.0009200999 +454 348 0.0030230999 +455 348 0.023922198 +456 348 0.00078859995 +457 348 0.0078863986 +458 348 0.00065719988 +459 348 0.00039429986 +460 348 0.0011829999 +463 348 0.033254497 +464 348 0.0056518987 +465 348 0.0009200999 +467 348 0.010778099 +468 348 0.0019715999 +469 348 0.007492099 +470 348 0.0082807988 +471 348 0.0010515 +473 348 0.0001314 +477 348 0.0001314 +478 348 0.0011829999 +483 348 0.0015772998 +490 348 0.0009200999 +491 348 0.0055204965 +9 349 3.8899991e-05 +18 349 0.00011659999 +21 349 3.8899991e-05 +22 349 3.8899991e-05 +60 349 0.0023705999 +77 349 7.7699995e-05 +79 349 3.8899991e-05 +82 349 3.8899991e-05 +83 349 3.8899991e-05 +84 349 3.8899991e-05 +108 349 3.8899991e-05 +113 349 7.7699995e-05 +114 349 0.00015539999 +126 349 7.7699995e-05 +127 349 3.8899991e-05 +130 349 0.00015539999 +131 349 3.8899991e-05 +135 349 0.00015539999 +142 349 0.00023319999 +150 349 0.00062179985 +158 349 3.8899991e-05 +160 349 0.0044690967 +165 349 3.8899991e-05 +168 349 3.8899991e-05 +169 349 0.00015539999 +171 349 0.00054409984 +172 349 0.00027199998 +187 349 3.8899991e-05 +189 349 7.7699995e-05 +190 349 7.7699995e-05 +191 349 3.8899991e-05 +194 349 0.00011659999 +197 349 3.8899991e-05 +198 349 0.0012435999 +200 349 3.8899991e-05 +201 349 3.8899991e-05 +203 349 7.7699995e-05 +204 349 0.00011659999 +206 349 0.00015539999 +207 349 3.8899991e-05 +214 349 0.035714298 +219 349 3.8899991e-05 +220 349 3.8899991e-05 +223 349 0.0001943 +224 349 0.00077719986 +225 349 0.00038859993 +227 349 7.7699995e-05 +233 349 0.00069949985 +234 349 0.0054406971 +236 349 0.00015539999 +237 349 0.0012824 +240 349 0.00038859993 +241 349 0.0033032999 +242 349 0.0033421 +243 349 7.7699995e-05 +248 349 3.8899991e-05 +250 349 3.8899991e-05 +251 349 0.00015539999 +252 349 0.0040416978 +262 349 7.7699995e-05 +270 349 0.0023705999 +271 349 3.8899991e-05 +272 349 0.00011659999 +274 349 0.0010103998 +275 349 3.8899991e-05 +276 349 3.8899991e-05 +277 349 0.051647797 +282 349 0.0242888 +283 349 0.0043136999 +284 349 0.0015155999 +285 349 0.0010880998 +286 349 0.0061401986 +287 349 0.00011659999 +288 349 7.7699995e-05 +289 349 0.0073060989 +290 349 0.0024482999 +292 349 0.0052463971 +293 349 0.0034586999 +294 349 0.0099486969 +295 349 0.0010493 +296 349 0.0025648999 +297 349 0.0016710998 +298 349 0.00042749988 +299 349 0.0001943 +305 349 7.7699995e-05 +307 349 0.019081298 +312 349 0.0050908998 +315 349 0.00089379982 +317 349 0.0014767998 +318 349 3.8899991e-05 +319 349 3.8899991e-05 +320 349 0.0026814998 +321 349 0.0054017976 +322 349 0.0032255999 +324 349 0.0083164982 +326 349 0.0034975999 +327 349 3.8899991e-05 +328 349 0.0036141998 +331 349 0.00015539999 +332 349 7.7699995e-05 +333 349 3.8899991e-05 +334 349 7.7699995e-05 +335 349 0.0012824 +338 349 0.0015155999 +339 349 0.00046629994 +340 349 0.0054795966 +341 349 0.0001943 +344 349 0.00066069979 +345 349 0.00011659999 +347 349 0.0018264998 +349 349 0.017021596 +350 349 0.0070728995 +351 349 0.0072283968 +352 349 0.0016321999 +353 349 7.7699995e-05 +354 349 0.027086899 +355 349 0.00050519989 +356 349 0.0010103998 +357 349 3.8899991e-05 +358 349 0.012630198 +366 349 7.7699995e-05 +369 349 0.00011659999 +370 349 0.00015539999 +371 349 0.0024094998 +372 349 0.011503197 +373 349 0.011697497 +374 349 0.00089379982 +375 349 3.8899991e-05 +384 349 3.8899991e-05 +385 349 3.8899991e-05 +386 349 0.00011659999 +387 349 7.7699995e-05 +389 349 0.00034979987 +390 349 0.00027199998 +392 349 0.00066069979 +393 349 0.0052463971 +397 349 7.7699995e-05 +398 349 0.0012047 +402 349 0.0012435999 +404 349 0.0016710998 +405 349 0.00066069979 +408 349 3.8899991e-05 +414 349 0.00015539999 +415 349 3.8899991e-05 +417 349 0.00046629994 +419 349 3.8899991e-05 +420 349 7.7699995e-05 +421 349 0.00031089992 +422 349 0.00015539999 +423 349 3.8899991e-05 +425 349 3.8899991e-05 +430 349 0.00046629994 +431 349 3.8899991e-05 +433 349 3.8899991e-05 +434 349 3.8899991e-05 +442 349 0.00011659999 +443 349 0.0034586999 +444 349 0.0012435999 +445 349 0.0049743988 +446 349 0.0011658999 +447 349 0.0051297992 +450 349 0.0089382976 +452 349 0.0053240992 +453 349 0.0014767998 +454 349 0.00031089992 +455 349 0.029301997 +456 349 0.00093269977 +457 349 0.0041581988 +458 349 0.00054409984 +459 349 0.00050519989 +460 349 0.001127 +463 349 0.023433898 +464 349 0.0005828999 +465 349 0.00097159995 +467 349 0.010181896 +468 349 0.0019041998 +469 349 0.006917499 +470 349 0.0077723972 +471 349 0.0025648999 +473 349 0.00015539999 +477 349 0.00015539999 +478 349 0.0011658999 +479 349 3.8899991e-05 +483 349 0.0013989999 +489 349 3.8899991e-05 +490 349 0.00085499999 +491 349 0.0014378999 +9 350 3.9599996e-05 +18 350 7.9199992e-05 +19 350 3.9599996e-05 +22 350 0.0001583 +24 350 3.9599996e-05 +60 350 0.0024146999 +79 350 3.9599996e-05 +82 350 7.9199992e-05 +83 350 3.9599996e-05 +84 350 3.9599996e-05 +108 350 7.9199992e-05 +113 350 7.9199992e-05 +114 350 0.00019789999 +126 350 0.00011879999 +127 350 3.9599996e-05 +142 350 3.9599996e-05 +150 350 0.00059379986 +151 350 3.9599996e-05 +160 350 0.0025334 +169 350 0.00019789999 +171 350 3.9599996e-05 +172 350 0.00075209979 +187 350 0.00031669997 +188 350 0.0003562998 +189 350 0.00011879999 +190 350 0.00011879999 +192 350 0.0002770999 +194 350 0.0001583 +197 350 0.00031669997 +198 350 0.0027313998 +200 350 7.9199992e-05 +201 350 3.9599996e-05 +203 350 7.9199992e-05 +204 350 3.9599996e-05 +206 350 0.0001583 +207 350 3.9599996e-05 +214 350 0.00047499989 +224 350 7.9199992e-05 +233 350 7.9199992e-05 +234 350 0.0058982 +237 350 0.0002770999 +240 350 0.00011879999 +241 350 0.0055022985 +242 350 0.0093420967 +248 350 3.9599996e-05 +250 350 3.9599996e-05 +252 350 0.00011879999 +270 350 0.00011879999 +271 350 3.9599996e-05 +272 350 0.0049480982 +276 350 3.9599996e-05 +277 350 0.040376898 +282 350 0.067809343 +283 350 0.010410897 +284 350 0.0016229998 +285 350 3.9599996e-05 +286 350 0.0013458999 +289 350 0.00011879999 +290 350 0.00019789999 +292 350 0.0043147989 +293 350 0.0012667 +294 350 0.0060564987 +295 350 0.0027313998 +296 350 0.0068085976 +297 350 0.0090649985 +298 350 0.0001583 +299 350 0.0019792998 +304 350 0.0001583 +305 350 0.00011879999 +307 350 0.0129839 +308 350 7.9199992e-05 +312 350 0.013894398 +313 350 7.9199992e-05 +315 350 0.0005541998 +317 350 3.9599996e-05 +320 350 0.00019789999 +321 350 0.0012270999 +322 350 0.00011879999 +324 350 0.014369398 +326 350 0.00019789999 +327 350 0.00039589987 +328 350 0.0134985 +329 350 7.9199992e-05 +331 350 0.0003562998 +332 350 0.00019789999 +333 350 0.0003562998 +338 350 0.0017021999 +339 350 3.9599996e-05 +340 350 0.010252599 +341 350 0.0002770999 +349 350 0.00011879999 +350 350 0.028738797 +351 350 0.010410897 +352 350 0.0001583 +353 350 3.9599996e-05 +354 350 0.014092296 +355 350 3.9599996e-05 +356 350 0.0033251999 +357 350 0.00011879999 +358 350 0.016665298 +366 350 0.00011879999 +367 350 0.0002770999 +368 350 7.9199992e-05 +369 350 3.9599996e-05 +370 350 0.0026521999 +371 350 0.004987698 +372 350 0.049164798 +373 350 0.0027709999 +375 350 7.9199992e-05 +376 350 0.0001583 +384 350 3.9599996e-05 +386 350 7.9199992e-05 +387 350 0.00011879999 +390 350 3.9599996e-05 +392 350 3.9599996e-05 +393 350 0.00094999978 +397 350 0.00047499989 +398 350 7.9199992e-05 +401 350 3.9599996e-05 +402 350 0.00071249995 +404 350 0.00019789999 +405 350 0.00019789999 +408 350 0.00011879999 +413 350 3.9599996e-05 +414 350 0.0016229998 +415 350 0.00011879999 +417 350 0.00043539982 +419 350 7.9199992e-05 +421 350 7.9199992e-05 +422 350 0.0001583 +423 350 3.9599996e-05 +425 350 3.9599996e-05 +430 350 7.9199992e-05 +431 350 3.9599996e-05 +433 350 3.9599996e-05 +434 350 3.9599996e-05 +443 350 0.0019397 +444 350 0.0020979999 +445 350 0.0053439997 +446 350 0.00023749999 +447 350 0.0041959994 +450 350 0.0051064976 +452 350 0.0054231994 +453 350 0.0018208998 +454 350 0.0005541998 +455 350 0.033924498 +456 350 0.00091049983 +457 350 0.0037606 +458 350 0.00083129993 +459 350 0.0013062998 +460 350 0.00098959985 +463 350 0.0067690983 +464 350 0.00067289989 +465 350 0.0011083998 +467 350 0.011083797 +468 350 0.004275199 +469 350 0.0088274963 +470 350 0.0099358968 +471 350 0.0026917998 +473 350 0.00023749999 +477 350 0.00011879999 +478 350 0.0011876 +483 350 0.0016229998 +489 350 3.9599996e-05 +490 350 0.0008709 +491 350 0.0044334978 +18 351 0.0001394 +19 351 0.00027889991 +22 351 0.00034859986 +60 351 0.003973797 +82 351 6.9699992e-05 +108 351 6.9699992e-05 +114 351 6.9699992e-05 +126 351 6.9699992e-05 +150 351 0.00069719995 +160 351 0.0016035 +169 351 0.00034859986 +172 351 0.00027889991 +189 351 6.9699992e-05 +190 351 0.0001394 +192 351 6.9699992e-05 +194 351 0.00020909999 +198 351 0.0052286983 +200 351 6.9699992e-05 +203 351 6.9699992e-05 +204 351 6.9699992e-05 +206 351 0.00020909999 +207 351 6.9699992e-05 +214 351 0.00020909999 +234 351 0.011851598 +237 351 0.0001394 +270 351 0.0073200986 +277 351 0.15184045 +278 351 6.9699992e-05 +282 351 0.0098995976 +283 351 0.015616298 +284 351 0.0018125998 +285 351 0.00034859986 +286 351 0.0011153999 +290 351 6.9699992e-05 +292 351 0.0020217998 +294 351 0.0001394 +296 351 0.0010456999 +297 351 0.0039040998 +299 351 0.0001394 +312 351 0.0025795 +320 351 0.0013245998 +338 351 0.0009062998 +340 351 0.025306698 +341 351 0.0001394 +351 351 0.075711071 +354 351 0.00244 +356 351 0.0001394 +358 351 0.0092721991 +372 351 0.00083659985 +384 351 6.9699992e-05 +387 351 6.9699992e-05 +402 351 6.9699992e-05 +417 351 0.00048799999 +421 351 6.9699992e-05 +422 351 6.9699992e-05 +430 351 6.9699992e-05 +433 351 6.9699992e-05 +434 351 6.9699992e-05 +443 351 0.0036251999 +444 351 0.00020909999 +445 351 0.0047406964 +446 351 0.00069719995 +447 351 0.00069719995 +450 351 0.0039040998 +452 351 0.0092721991 +453 351 0.0041828975 +454 351 0.0010456999 +455 351 0.024888497 +456 351 0.0007668999 +457 351 0.0036251999 +458 351 0.00020909999 +459 351 0.0011153999 +460 351 0.0011851999 +463 351 0.0046011992 +464 351 0.00027889991 +465 351 0.0010456999 +467 351 0.0087841973 +468 351 0.0020217998 +469 351 0.003973797 +470 351 0.0043920986 +471 351 0.0011851999 +473 351 0.0001394 +477 351 6.9699992e-05 +478 351 0.0012548999 +483 351 0.001464 +489 351 6.9699992e-05 +490 351 0.00041829981 +491 351 0.0029280998 +24 352 0.000141 +25 352 0.000141 +60 352 0.0018324999 +82 352 0.000141 +108 352 0.000141 +114 352 0.000141 +126 352 0.000141 +130 352 0.00070479978 +131 352 0.00042289984 +135 352 0.0087397993 +138 352 0.00028189993 +139 352 0.000141 +142 352 0.00042289984 +150 352 0.000141 +160 352 0.0029602 +169 352 0.00042289984 +172 352 0.00098669995 +187 352 0.00056389999 +188 352 0.000141 +189 352 0.000141 +190 352 0.000141 +192 352 0.000141 +193 352 0.00028189993 +194 352 0.00042289984 +198 352 0.0028192999 +206 352 0.00028189993 +214 352 0.0014095998 +219 352 0.00098669995 +223 352 0.000141 +224 352 0.00084579992 +229 352 0.000141 +233 352 0.00028189993 +234 352 0.0056385994 +236 352 0.00042289984 +237 352 0.000141 +240 352 0.00028189993 +241 352 0.0014095998 +242 352 0.0031011999 +252 352 0.00056389999 +270 352 0.00028189993 +271 352 0.000141 +272 352 0.00070479978 +273 352 0.000141 +277 352 0.07569778 +279 352 0.000141 +282 352 0.015083198 +283 352 0.0022553999 +284 352 0.0015505999 +285 352 0.0014095998 +286 352 0.00028189993 +289 352 0.00056389999 +292 352 0.014237396 +293 352 0.011136197 +294 352 0.00042289984 +295 352 0.021003697 +296 352 0.0057794973 +297 352 0.00070479978 +298 352 0.0097264983 +300 352 0.000141 +304 352 0.00028189993 +307 352 0.00070479978 +312 352 0.0139555 +315 352 0.0081758983 +317 352 0.000141 +320 352 0.0029602 +321 352 0.0043698996 +322 352 0.0067662969 +324 352 0.0098674968 +325 352 0.000141 +326 352 0.0094445981 +327 352 0.000141 +328 352 0.011277098 +331 352 0.000141 +335 352 0.00028189993 +338 352 0.000141 +339 352 0.00098669995 +340 352 0.0046517998 +349 352 0.00056389999 +350 352 0.00042289984 +351 352 0.0094445981 +352 352 0.037073597 +353 352 0.0018324999 +354 352 0.015224099 +355 352 0.000141 +356 352 0.00028189993 +358 352 0.0059204996 +366 352 0.0011276999 +370 352 0.0018324999 +371 352 0.0014095998 +372 352 0.033549499 +373 352 0.0023963999 +380 352 0.000141 +386 352 0.00028189993 +387 352 0.000141 +393 352 0.00028189993 +402 352 0.000141 +414 352 0.000141 +415 352 0.0018324999 +416 352 0.00028189993 +417 352 0.00070479978 +419 352 0.0012687 +422 352 0.00028189993 +430 352 0.000141 +443 352 0.0035240999 +444 352 0.00056389999 +445 352 0.0063433982 +446 352 0.00028189993 +447 352 0.0067662969 +450 352 0.0039469972 +452 352 0.0047927983 +453 352 0.0025374 +454 352 0.00042289984 +455 352 0.043698899 +456 352 0.00084579992 +457 352 0.0038059999 +458 352 0.00070479978 +459 352 0.0012687 +460 352 0.00084579992 +463 352 0.021567497 +464 352 0.00056389999 +465 352 0.00098669995 +467 352 0.0091626979 +468 352 0.0070481971 +469 352 0.0057794973 +470 352 0.0064843968 +471 352 0.0011276999 +473 352 0.000141 +477 352 0.000141 +478 352 0.0012687 +483 352 0.0012687 +490 352 0.00070479978 +491 352 0.0043698996 +21 353 0.0020937999 +24 353 0.0033500998 +60 353 0.0054438971 +114 353 0.00041879993 +160 353 0.023031797 +165 353 0.0037687998 +169 353 0.00041879993 +198 353 0.00083749997 +206 353 0.00083749997 +214 353 0.00041879993 +223 353 0.0012562999 +234 353 0.0058625974 +257 353 0.0012562999 +270 353 0.0012562999 +272 353 0.00041879993 +277 353 0.015912898 +278 353 0.0029312999 +282 353 0.0196817 +283 353 0.00041879993 +284 353 0.0029312999 +286 353 0.0025125998 +288 353 0.0020937999 +289 353 0.011306498 +290 353 0.00083749997 +293 353 0.0041875988 +296 353 0.015075397 +297 353 0.0016749999 +326 353 0.00041879993 +340 353 0.010887798 +349 353 0.00041879993 +351 353 0.00041879993 +353 353 0.0087939985 +354 353 0.0016749999 +356 353 0.00041879993 +358 353 0.0062813982 +374 353 0.00041879993 +375 353 0.0016749999 +417 353 0.00041879993 +443 353 0.0050251 +444 353 0.00041879993 +445 353 0.0046063997 +447 353 0.0029312999 +450 353 0.0046063997 +452 353 0.0096314996 +453 353 0.0058625974 +454 353 0.00041879993 +455 353 0.048576199 +456 353 0.00041879993 +457 353 0.0033500998 +459 353 0.00083749997 +460 353 0.0016749999 +463 353 0.010887798 +464 353 0.00041879993 +465 353 0.00041879993 +467 353 0.011306498 +468 353 0.0020937999 +469 353 0.0037687998 +470 353 0.0041875988 +471 353 0.0020937999 +478 353 0.0012562999 +483 353 0.00083749997 +490 353 0.00041879993 +491 353 0.0062813982 +9 354 6.2399995e-05 +18 354 0.00012479999 +22 354 0.00018729999 +60 354 0.002809 +82 354 6.2399995e-05 +83 354 6.2399995e-05 +84 354 6.2399995e-05 +108 354 6.2399995e-05 +113 354 0.00012479999 +114 354 0.00018729999 +126 354 6.2399995e-05 +135 354 6.2399995e-05 +139 354 6.2399995e-05 +142 354 6.2399995e-05 +150 354 0.00062419986 +160 354 0.0013108999 +169 354 0.00037449994 +171 354 6.2399995e-05 +172 354 0.0010611999 +184 354 6.2399995e-05 +189 354 6.2399995e-05 +190 354 0.00012479999 +192 354 6.2399995e-05 +194 354 0.00012479999 +198 354 0.0035581 +200 354 6.2399995e-05 +203 354 6.2399995e-05 +204 354 6.2399995e-05 +206 354 0.00024969992 +207 354 6.2399995e-05 +214 354 0.00037449994 +224 354 0.00018729999 +233 354 0.00068659987 +234 354 0.0079275966 +237 354 0.00012479999 +240 354 0.00018729999 +241 354 0.00037449994 +242 354 0.0035581 +252 354 6.2399995e-05 +270 354 0.0015604999 +271 354 0.00012479999 +272 354 0.0025592998 +276 354 6.2399995e-05 +277 354 0.070661664 +278 354 0.00012479999 +282 354 0.037702899 +283 354 0.0360175 +284 354 0.0017477998 +285 354 0.0019975 +286 354 0.0043070987 +289 354 0.00018729999 +290 354 6.2399995e-05 +292 354 0.0054306984 +293 354 0.00043699984 +294 354 0.0059924982 +295 354 0.0012484 +296 354 0.0045567974 +297 354 0.0068663992 +298 354 0.0013108999 +299 354 0.0053682998 +303 354 6.2399995e-05 +304 354 6.2399995e-05 +305 354 6.2399995e-05 +307 354 0.00024969992 +308 354 6.2399995e-05 +312 354 0.0077402964 +313 354 0.00018729999 +315 354 0.00068659987 +317 354 6.2399995e-05 +318 354 6.2399995e-05 +319 354 0.00012479999 +320 354 0.0018726999 +322 354 6.2399995e-05 +324 354 0.00056179985 +326 354 0.00012479999 +327 354 0.00049939984 +328 354 0.00043699984 +333 354 0.00031209993 +335 354 0.00012479999 +338 354 0.0022471999 +340 354 0.011235997 +341 354 0.00037449994 +342 354 6.2399995e-05 +343 354 6.2399995e-05 +349 354 6.2399995e-05 +350 354 0.00018729999 +351 354 0.019350797 +352 354 0.00031209993 +353 354 0.00024969992 +354 354 0.029587999 +356 354 0.00018729999 +357 354 0.00024969992 +358 354 0.026841398 +366 354 0.0007491 +371 354 0.00037449994 +372 354 0.012983799 +373 354 0.00068659987 +375 354 0.00012479999 +376 354 0.00012479999 +386 354 6.2399995e-05 +387 354 6.2399995e-05 +390 354 0.00018729999 +392 354 6.2399995e-05 +393 354 0.00018729999 +397 354 0.00031209993 +398 354 6.2399995e-05 +401 354 6.2399995e-05 +402 354 0.00099879992 +404 354 0.0068039969 +405 354 0.0016229998 +413 354 6.2399995e-05 +414 354 0.00031209993 +415 354 6.2399995e-05 +417 354 0.00043699984 +419 354 6.2399995e-05 +421 354 6.2399995e-05 +422 354 6.2399995e-05 +423 354 6.2399995e-05 +430 354 6.2399995e-05 +431 354 6.2399995e-05 +433 354 6.2399995e-05 +434 354 6.2399995e-05 +443 354 0.0022471999 +444 354 0.00049939984 +445 354 0.0036829 +446 354 0.00018729999 +447 354 0.0025592998 +450 354 0.0041822977 +452 354 0.0069287978 +453 354 0.0029962999 +454 354 0.00056179985 +455 354 0.023969997 +456 354 0.00087389979 +457 354 0.0036829 +458 354 0.00099879992 +459 354 0.00087389979 +460 354 0.001186 +463 354 0.007116098 +464 354 0.00037449994 +465 354 0.0013732999 +467 354 0.010798998 +468 354 0.0041198991 +469 354 0.006242197 +470 354 0.0076154992 +471 354 0.0028714 +472 354 0.001186 +473 354 0.00018729999 +477 354 6.2399995e-05 +478 354 0.0013108999 +483 354 0.0015604999 +489 354 6.2399995e-05 +490 354 0.00068659987 +491 354 0.0050561987 +60 355 0.0024044998 +108 355 0.00026719994 +114 355 0.00053429999 +126 355 0.00026719994 +160 355 0.0024044998 +187 355 0.00080149993 +188 355 0.00080149993 +189 355 0.00026719994 +192 355 0.00053429999 +194 355 0.00026719994 +197 355 0.00053429999 +198 355 0.00026719994 +206 355 0.00053429999 +214 355 0.00080149993 +223 355 0.00080149993 +233 355 0.00026719994 +234 355 0.0050760992 +237 355 0.00026719994 +240 355 0.0053432994 +241 355 0.0029387998 +257 355 0.003206 +272 355 0.0029387998 +275 355 0.0042745993 +277 355 0.10633177 +282 355 0.009350799 +284 355 0.0018701998 +289 355 0.00026719994 +292 355 0.009350799 +293 355 0.0048089996 +294 355 0.0085492991 +295 355 0.00080149993 +307 355 0.015495598 +312 355 0.0085492991 +324 355 0.012022398 +328 355 0.00026719994 +339 355 0.0010686999 +340 355 0.003206 +349 355 0.00053429999 +350 355 0.0050760992 +351 355 0.00026719994 +352 355 0.0024044998 +354 355 0.015762798 +355 355 0.063585341 +356 355 0.0010686999 +358 355 0.0048089996 +366 355 0.00026719994 +370 355 0.0082820989 +371 355 0.014159799 +372 355 0.0037403 +373 355 0.0085492991 +374 355 0.00026719994 +387 355 0.00026719994 +393 355 0.018434398 +405 355 0.00026719994 +414 355 0.0050760992 +415 355 0.0040074997 +417 355 0.00053429999 +443 355 0.0029387998 +444 355 0.00026719994 +445 355 0.0045417994 +447 355 0.024846397 +450 355 0.0042745993 +452 355 0.0050760992 +453 355 0.0026717 +455 355 0.049425598 +456 355 0.00053429999 +457 355 0.0037403 +458 355 0.00080149993 +459 355 0.0010686999 +460 355 0.00080149993 +463 355 0.010419399 +464 355 0.00053429999 +465 355 0.0010686999 +467 355 0.010152299 +468 355 0.0013357999 +469 355 0.0082820989 +470 355 0.009350799 +471 355 0.00080149993 +473 355 0.00026719994 +478 355 0.0016029999 +483 355 0.0026717 +490 355 0.0010686999 +491 355 0.0029387998 +9 356 8.4999992e-05 +13 356 0.0001699 +19 356 8.4999992e-05 +21 356 0.0001699 +22 356 8.4999992e-05 +24 356 0.00042479998 +60 356 0.0028039999 +82 356 0.00025489996 +83 356 8.4999992e-05 +84 356 8.4999992e-05 +108 356 8.4999992e-05 +113 356 0.0001699 +114 356 0.0001699 +119 356 8.4999992e-05 +120 356 0.00050979992 +126 356 8.4999992e-05 +135 356 0.0056928992 +142 356 0.019203 +150 356 8.4999992e-05 +160 356 0.0011896 +172 356 0.00059479987 +187 356 0.0050131977 +189 356 0.0001699 +190 356 8.4999992e-05 +191 356 0.0030588999 +193 356 0.0001699 +194 356 0.0001699 +198 356 0.0046732984 +200 356 8.4999992e-05 +203 356 8.4999992e-05 +204 356 8.4999992e-05 +206 356 0.00025489996 +214 356 0.0029738999 +218 356 0.00025489996 +221 356 8.4999992e-05 +223 356 0.00025489996 +224 356 0.0031438998 +231 356 8.4999992e-05 +233 356 8.4999992e-05 +234 356 0.006542597 +236 356 0.0001699 +237 356 0.00033989991 +240 356 0.0023790998 +241 356 0.010366198 +242 356 0.00076469989 +252 356 0.0001699 +270 356 0.00025489996 +272 356 0.0041634999 +277 356 0.066700697 +278 356 0.0001699 +282 356 0.024641 +283 356 0.0045033991 +284 356 0.0017843 +285 356 8.4999992e-05 +286 356 0.00050979992 +289 356 0.00025489996 +290 356 0.00033989991 +292 356 0.007817097 +293 356 0.0069674999 +294 356 0.0024640998 +295 356 0.0075621977 +296 356 0.0033987998 +297 356 0.0057778992 +298 356 0.00042479998 +301 356 0.0001699 +304 356 0.00025489996 +305 356 8.4999992e-05 +307 356 0.0076471977 +312 356 0.0073922984 +315 356 0.010876 +317 356 8.4999992e-05 +320 356 0.0011045998 +321 356 0.00093469978 +322 356 0.00025489996 +324 356 0.0073922984 +326 356 0.00042479998 +328 356 0.00076469989 +329 356 0.00042479998 +338 356 0.0011896 +339 356 0.00050979992 +340 356 0.006457597 +341 356 0.0001699 +344 356 0.00025489996 +347 356 0.00025489996 +349 356 0.00050979992 +350 356 0.012150597 +351 356 0.005438 +352 356 0.0001699 +353 356 0.0001699 +354 356 0.022431798 +355 356 0.00050979992 +356 356 0.017333698 +357 356 8.4999992e-05 +358 356 0.017078798 +364 356 8.4999992e-05 +365 356 8.4999992e-05 +366 356 0.00033989991 +367 356 0.00025489996 +368 356 8.4999992e-05 +370 356 0.0029738999 +371 356 0.006542597 +372 356 0.015294399 +373 356 0.0070523992 +375 356 8.4999992e-05 +386 356 8.4999992e-05 +387 356 8.4999992e-05 +393 356 0.0042483993 +397 356 8.4999992e-05 +402 356 0.00033989991 +405 356 8.4999992e-05 +414 356 0.0035686998 +415 356 0.00025489996 +417 356 0.00042479998 +419 356 8.4999992e-05 +421 356 8.4999992e-05 +422 356 0.00025489996 +423 356 8.4999992e-05 +430 356 8.4999992e-05 +442 356 8.4999992e-05 +443 356 0.0028889 +444 356 0.0013595 +445 356 0.010026298 +446 356 0.0001699 +447 356 0.0039934963 +450 356 0.0084118992 +452 356 0.005438 +453 356 0.0014444999 +454 356 0.00025489996 +455 356 0.057438999 +456 356 0.00076469989 +457 356 0.0036537 +458 356 0.00067979982 +459 356 0.0013595 +460 356 0.0011045998 +463 356 0.021922 +464 356 0.00042479998 +465 356 0.0010195998 +467 356 0.015209399 +468 356 0.005098097 +469 356 0.0073072985 +470 356 0.0076471977 +471 356 0.0044183992 +473 356 0.0001699 +477 356 8.4999992e-05 +478 356 0.0011896 +483 356 0.0021241999 +490 356 0.00059479987 +491 356 0.0032287999 +19 357 0.0001127 +22 357 0.0002254 +60 357 0.0021412999 +108 357 0.0001127 +114 357 0.0002254 +126 357 0.0001127 +135 357 0.0003380999 +143 357 0.0001127 +150 357 0.0003380999 +160 357 0.0001127 +189 357 0.0001127 +190 357 0.0001127 +194 357 0.0002254 +198 357 0.0052969977 +200 357 0.0001127 +203 357 0.0001127 +206 357 0.0003380999 +214 357 0.00056349998 +223 357 0.0001127 +224 357 0.00045079994 +225 357 0.0002254 +233 357 0.0001127 +234 357 0.008452598 +237 357 0.0001127 +240 357 0.0013523998 +241 357 0.0025920998 +242 357 0.0019158998 +262 357 0.0001127 +270 357 0.0048461966 +271 357 0.0001127 +272 357 0.0020285998 +274 357 0.0002254 +277 357 0.062549293 +282 357 0.037529599 +283 357 0.0031555998 +284 357 0.0015777999 +286 357 0.00067619979 +288 357 0.0003380999 +289 357 0.0029302 +290 357 0.00067619979 +292 357 0.0041699968 +293 357 0.017355997 +294 357 0.0067620985 +295 357 0.0061985999 +296 357 0.010030396 +297 357 0.0032682999 +298 357 0.017130598 +299 357 0.0001127 +312 357 0.010931998 +313 357 0.0001127 +315 357 0.0032682999 +317 357 0.001127 +318 357 0.0010142999 +320 357 0.0123972 +321 357 0.00045079994 +322 357 0.0027047999 +324 357 0.00090159988 +326 357 0.001127 +328 357 0.00045079994 +338 357 0.0020285998 +340 357 0.015214697 +341 357 0.0003380999 +343 357 0.0003380999 +351 357 0.0013523998 +353 357 0.0003380999 +354 357 0.001127 +355 357 0.0001127 +356 357 0.0001127 +357 357 0.0024793998 +358 357 0.041699499 +370 357 0.00056349998 +372 357 0.0002254 +374 357 0.0001127 +375 357 0.0002254 +376 357 0.0003380999 +386 357 0.0001127 +387 357 0.0001127 +392 357 0.00056349998 +396 357 0.0002254 +397 357 0.0046207979 +398 357 0.00056349998 +402 357 0.00090159988 +417 357 0.00056349998 +421 357 0.0001127 +422 357 0.0001127 +442 357 0.0014650999 +443 357 0.0023667 +444 357 0.00078889984 +445 357 0.0065366998 +446 357 0.0002254 +447 357 0.0048461966 +450 357 0.0039445981 +452 357 0.0089033991 +453 357 0.0025920998 +454 357 0.00067619979 +455 357 0.020060897 +456 357 0.00056349998 +457 357 0.0032682999 +458 357 0.00078889984 +459 357 0.00045079994 +460 357 0.001127 +463 357 0.020962499 +464 357 0.00078889984 +465 357 0.001127 +467 357 0.0103685 +468 357 0.0034936999 +469 357 0.0039445981 +470 357 0.0043953992 +471 357 0.0029302 +473 357 0.0001127 +477 357 0.0001127 +478 357 0.0012396998 +483 357 0.0012396998 +490 357 0.0003380999 +491 357 0.0029302 +9 358 2.7899994e-05 +18 358 0.0001393 +22 358 0.00066889985 +60 358 0.0020344998 +79 358 2.7899994e-05 +82 358 2.7899994e-05 +83 358 2.7899994e-05 +84 358 2.7899994e-05 +108 358 2.7899994e-05 +113 358 5.5699988e-05 +114 358 8.3599996e-05 +126 358 5.5699988e-05 +127 358 2.7899994e-05 +135 358 0.001923 +142 358 2.7899994e-05 +143 358 0.00075249979 +150 358 0.0017278998 +151 358 2.7899994e-05 +160 358 0.00064099999 +169 358 0.00019509999 +172 358 0.00019509999 +187 358 2.7899994e-05 +189 358 8.3599996e-05 +190 358 0.0001393 +192 358 5.5699988e-05 +194 358 0.0001393 +196 358 2.7899994e-05 +197 358 2.7899994e-05 +198 358 0.0080264993 +200 358 8.3599996e-05 +201 358 5.5699988e-05 +203 358 8.3599996e-05 +204 358 0.0001393 +206 358 0.00019509999 +207 358 8.3599996e-05 +209 358 2.7899994e-05 +214 358 0.0026755 +218 358 2.7899994e-05 +219 358 2.7899994e-05 +223 358 0.00089179981 +224 358 2.7899994e-05 +229 358 0.00030659977 +233 358 0.00072459993 +234 358 0.0123742 +237 358 0.00030659977 +240 358 0.0016442998 +241 358 0.0037066999 +242 358 5.5699988e-05 +248 358 2.7899994e-05 +250 358 2.7899994e-05 +252 358 8.3599996e-05 +270 358 0.003929697 +271 358 2.7899994e-05 +272 358 0.000223 +274 358 0.0020623999 +277 358 0.061285898 +278 358 5.5699988e-05 +282 358 0.024163198 +283 358 0.0012262999 +284 358 0.0022852998 +285 358 5.5699988e-05 +286 358 0.00078039989 +288 358 0.00016719999 +289 358 0.00025079981 +290 358 0.0024247 +292 358 0.010562699 +293 358 0.0085002966 +294 358 0.0017000998 +295 358 0.0009476 +296 358 0.0073576979 +297 358 0.0024247 +298 358 0.0043476969 +299 358 2.7899994e-05 +307 358 0.00016719999 +312 358 0.008639697 +313 358 8.3599996e-05 +315 358 0.0054067969 +317 358 0.0022016999 +318 358 0.00041799992 +320 358 0.0042919964 +321 358 0.0009476 +322 358 0.0054903999 +324 358 0.0019508998 +326 358 0.0040410981 +328 358 0.0022016999 +333 358 2.7899994e-05 +335 358 2.7899994e-05 +338 358 0.0034000999 +339 358 0.00016719999 +340 358 0.014353 +341 358 0.00055739982 +343 358 0.003205 +345 358 2.7899994e-05 +347 358 2.7899994e-05 +349 358 2.7899994e-05 +350 358 0.00025079981 +351 358 0.0048771985 +352 358 2.7899994e-05 +353 358 0.00097539998 +354 358 0.0049329996 +355 358 0.0010868998 +356 358 0.00025079981 +357 358 0.00030659977 +358 358 0.0624565 +359 358 0.00025079981 +366 358 0.0001393 +370 358 0.0043755993 +371 358 2.7899994e-05 +372 358 0.00066889985 +373 358 0.00030659977 +374 358 0.00083609996 +375 358 5.5699988e-05 +376 358 0.0024803998 +384 358 2.7899994e-05 +386 358 5.5699988e-05 +387 358 5.5699988e-05 +390 358 8.3599996e-05 +392 358 0.0001393 +393 358 0.00011149999 +394 358 2.7899994e-05 +397 358 0.00016719999 +398 358 0.0051001981 +401 358 5.5699988e-05 +402 358 0.0027590999 +404 358 5.5699988e-05 +405 358 0.000223 +417 358 0.00064099999 +419 358 2.7899994e-05 +421 358 8.3599996e-05 +422 358 0.00011149999 +423 358 2.7899994e-05 +425 358 2.7899994e-05 +430 358 2.7899994e-05 +431 358 5.5699988e-05 +432 358 2.7899994e-05 +433 358 5.5699988e-05 +434 358 5.5699988e-05 +442 358 0.0006130999 +443 358 0.0028426999 +444 358 0.0027033999 +445 358 0.0071346983 +446 358 0.0006130999 +447 358 0.0074133985 +448 358 0.00011149999 +450 358 0.0051280968 +452 358 0.008054398 +453 358 0.0025082999 +454 358 0.0001393 +455 358 0.021376196 +456 358 0.0012540999 +457 358 0.0051558986 +458 358 0.00047379988 +459 358 0.00030659977 +460 358 0.0011983998 +463 358 0.018505599 +464 358 0.0019508998 +465 358 0.0012262999 +467 358 0.012151297 +468 358 0.0026755 +469 358 0.0046820976 +470 358 0.0072739981 +471 358 0.0020344998 +473 358 0.00011149999 +477 358 0.00011149999 +478 358 0.0015886 +483 358 0.0011704999 +489 358 8.3599996e-05 +490 358 0.00039019994 +491 358 0.0012540999 +9 359 3.2899989e-05 +16 359 1.6399994e-05 +18 359 6.5799992e-05 +22 359 1.6399994e-05 +24 359 1.6399994e-05 +60 359 0.0012828 +76 359 1.6399994e-05 +79 359 1.6399994e-05 +82 359 8.2199986e-05 +83 359 6.5799992e-05 +84 359 6.5799992e-05 +104 359 0.0001316 +108 359 9.8699995e-05 +113 359 0.0001316 +114 359 0.00032889983 +126 359 0.00014799999 +127 359 3.2899989e-05 +130 359 8.2199986e-05 +142 359 4.9299997e-05 +143 359 1.6399994e-05 +150 359 0.0002795998 +151 359 1.6399994e-05 +160 359 0.0002138 +169 359 1.6399994e-05 +175 359 8.2199986e-05 +187 359 0.0024174999 +188 359 0.00026309979 +189 359 9.8699995e-05 +190 359 8.2199986e-05 +192 359 0.00014799999 +193 359 6.5799992e-05 +194 359 0.00037829997 +196 359 1.6399994e-05 +197 359 3.2899989e-05 +198 359 0.0017104 +200 359 0.0001316 +201 359 6.5799992e-05 +203 359 0.00075649982 +204 359 9.8699995e-05 +206 359 0.0009209998 +207 359 6.5799992e-05 +208 359 3.2899989e-05 +209 359 1.6399994e-05 +214 359 0.00078939996 +219 359 0.00026309979 +221 359 0.0001316 +223 359 0.0002138 +224 359 0.00069069979 +233 359 0.0002138 +234 359 0.0015787999 +237 359 0.00011509999 +240 359 0.00052629993 +241 359 0.010936398 +248 359 4.9299997e-05 +250 359 3.2899989e-05 +251 359 1.6399994e-05 +252 359 0.0013485998 +262 359 0.0001316 +263 359 1.6399994e-05 +276 359 0.00059199985 +277 359 0.0052296966 +282 359 0.00064139999 +283 359 3.2899989e-05 +284 359 8.2199986e-05 +285 359 0.00011509999 +289 359 9.8699995e-05 +290 359 8.2199986e-05 +292 359 0.00050979992 +293 359 0.0023846 +294 359 0.0014142999 +295 359 0.0109693 +296 359 0.0025326 +297 359 6.5799992e-05 +298 359 0.0013649999 +299 359 0.00054269983 +305 359 1.6399994e-05 +308 359 0.0045883991 +312 359 0.0045883991 +315 359 0.010837696 +317 359 1.6399994e-05 +319 359 6.5799992e-05 +320 359 0.0058875978 +321 359 0.0013813998 +322 359 0.0020227998 +325 359 0.00011509999 +326 359 0.0016445999 +338 359 0.00014799999 +340 359 0.0028450999 +341 359 1.6399994e-05 +347 359 3.2899989e-05 +351 359 0.00083869998 +354 359 0.0011840998 +356 359 0.0001316 +358 359 0.0023516999 +359 359 0.17314076 +360 359 3.2899989e-05 +361 359 0.00083869998 +363 359 1.6399994e-05 +369 359 0.0001809 +370 359 9.8699995e-05 +371 359 0.0025819999 +372 359 0.0053119995 +373 359 0.011166699 +375 359 8.2199986e-05 +376 359 0.0036181 +380 359 3.2899989e-05 +384 359 1.6399994e-05 +386 359 0.0043580979 +387 359 0.00014799999 +389 359 0.0013649999 +390 359 0.00077299983 +391 359 0.0004276 +392 359 0.049254999 +393 359 0.061112396 +394 359 1.6399994e-05 +396 359 3.2899989e-05 +397 359 1.6399994e-05 +402 359 6.5799992e-05 +404 359 4.9299997e-05 +405 359 9.8699995e-05 +417 359 0.00019729999 +419 359 0.0010032 +421 359 1.6399994e-05 +422 359 0.00011509999 +423 359 4.9299997e-05 +425 359 3.2899989e-05 +430 359 9.8699995e-05 +431 359 3.2899989e-05 +432 359 1.6399994e-05 +433 359 3.2899989e-05 +434 359 4.9299997e-05 +441 359 0.00047689979 +442 359 0.00062489999 +443 359 0.00090449979 +444 359 0.0027957999 +445 359 0.0027792999 +446 359 0.0001316 +447 359 0.010656796 +448 359 1.6399994e-05 +449 359 3.2899989e-05 +450 359 0.0061013997 +452 359 0.0042100996 +453 359 0.00074009993 +454 359 0.0002795998 +455 359 0.032578997 +456 359 0.0012828 +457 359 0.0062165 +458 359 0.0002795998 +459 359 0.0022859999 +460 359 0.0011347998 +463 359 0.042676698 +464 359 0.0028615999 +465 359 0.0019898999 +467 359 0.008913599 +468 359 0.0056737997 +469 359 0.0044567995 +470 359 0.016478598 +471 359 0.0026641998 +472 359 0.00014799999 +473 359 0.00034539984 +477 359 0.00023019999 +478 359 0.0015129999 +483 359 0.0012663 +489 359 4.9299997e-05 +490 359 0.0016116998 +491 359 0.0001809 +9 360 0.00013569999 +22 360 0.00054289983 +60 360 0.0039358996 +82 360 0.00013569999 +83 360 0.00013569999 +84 360 0.00013569999 +108 360 0.00013569999 +113 360 0.00027139997 +114 360 0.00040719984 +126 360 0.00013569999 +175 360 0.00027139997 +187 360 0.0008142998 +189 360 0.00013569999 +190 360 0.00013569999 +194 360 0.0008142998 +198 360 0.0013571999 +200 360 0.00013569999 +206 360 0.0023073 +214 360 0.0010857999 +221 360 0.00013569999 +223 360 0.00013569999 +224 360 0.00013569999 +234 360 0.0016286999 +237 360 0.00013569999 +240 360 0.00067859981 +241 360 0.0089576989 +252 360 0.00054289983 +262 360 0.00013569999 +277 360 0.012486398 +279 360 0.00027139997 +282 360 0.0010857999 +283 360 0.0036644998 +284 360 0.0009500999 +290 360 0.00027139997 +292 360 0.0062431991 +293 360 0.0008142998 +294 360 0.0016286999 +295 360 0.0021715998 +296 360 0.0021715998 +298 360 0.0009500999 +299 360 0.00067859981 +308 360 0.0044787973 +312 360 0.0047502965 +315 360 0.010450598 +320 360 0.0059717968 +321 360 0.00027139997 +322 360 0.00013569999 +326 360 0.0017643999 +340 360 0.006107498 +341 360 0.00013569999 +351 360 0.0012214999 +354 360 0.0013571999 +358 360 0.0096362978 +359 360 0.046552699 +360 360 0.010450598 +361 360 0.0008142998 +362 360 0.00040719984 +363 360 0.00013569999 +364 360 0.00013569999 +366 360 0.00013569999 +369 360 0.0019000999 +370 360 0.00013569999 +371 360 0.0028501998 +372 360 0.0065146983 +373 360 0.011807799 +376 360 0.0036644998 +386 360 0.0057002977 +387 360 0.00027139997 +390 360 0.00013569999 +391 360 0.0044787973 +392 360 0.086862087 +393 360 0.061753497 +417 360 0.00040719984 +419 360 0.00013569999 +423 360 0.00013569999 +424 360 0.00013569999 +430 360 0.00013569999 +431 360 0.00013569999 +434 360 0.0009500999 +441 360 0.0044787973 +443 360 0.00067859981 +444 360 0.0016286999 +445 360 0.0021715998 +447 360 0.010179199 +450 360 0.006107498 +452 360 0.0033930999 +453 360 0.00054289983 +454 360 0.00040719984 +455 360 0.026330099 +456 360 0.00067859981 +457 360 0.0055645965 +458 360 0.0009500999 +459 360 0.0020357999 +460 360 0.0012214999 +463 360 0.031351797 +464 360 0.0010857999 +465 360 0.030944597 +467 360 0.0299946 +468 360 0.006921798 +469 360 0.012893599 +470 360 0.014657997 +471 360 0.0013571999 +472 360 0.0027143999 +473 360 0.00027139997 +477 360 0.00013569999 +478 360 0.0016286999 +483 360 0.0014928998 +490 360 0.0014928998 +491 360 0.0059717968 +9 361 0.0002058 +60 361 0.0022642999 +82 361 0.0002058 +83 361 0.0002058 +84 361 0.0002058 +108 361 0.0002058 +113 361 0.00041169999 +114 361 0.00082339998 +126 361 0.00041169999 +131 361 0.00041169999 +187 361 0.00061749993 +189 361 0.0002058 +190 361 0.0002058 +194 361 0.00041169999 +198 361 0.0146151 +200 361 0.0002058 +203 361 0.0026759999 +206 361 0.0028817998 +224 361 0.0049402975 +233 361 0.011939097 +234 361 0.0016468 +237 361 0.0002058 +240 361 0.0022642999 +241 361 0.074310362 +252 361 0.0002058 +272 361 0.0018525999 +277 361 0.022025499 +279 361 0.00082339998 +282 361 0.0049402975 +284 361 0.0010291999 +293 361 0.0032934998 +295 361 0.00082339998 +296 361 0.011527397 +298 361 0.0069987997 +312 361 0.0010291999 +315 361 0.012350798 +320 361 0.011527397 +321 361 0.013997499 +322 361 0.0002058 +326 361 0.012968298 +340 361 0.0002058 +351 361 0.0014408999 +356 361 0.0002058 +359 361 0.00082339998 +361 361 0.0181145 +372 361 0.0057636984 +386 361 0.0034993999 +387 361 0.0002058 +392 361 0.0024702 +393 361 0.0002058 +417 361 0.00041169999 +419 361 0.0002058 +422 361 0.00041169999 +423 361 0.0002058 +425 361 0.0002058 +430 361 0.0002058 +431 361 0.0002058 +434 361 0.0014408999 +441 361 0.0032934998 +443 361 0.0010291999 +444 361 0.0012351 +445 361 0.012968298 +447 361 0.016673498 +450 361 0.0053519979 +452 361 0.004528597 +453 361 0.0024702 +454 361 0.0002058 +455 361 0.023672298 +456 361 0.00082339998 +457 361 0.0063811988 +458 361 0.0024702 +459 361 0.0020585 +460 361 0.0014408999 +463 361 0.042198397 +464 361 0.0010291999 +465 361 0.0016468 +467 361 0.0296418 +468 361 0.0148209 +469 361 0.0181145 +470 361 0.020172898 +471 361 0.00082339998 +473 361 0.00061749993 +477 361 0.00041169999 +478 361 0.0016468 +483 361 0.0018525999 +490 361 0.0018525999 +491 361 0.0018525999 +60 362 0.0015439999 +108 362 0.00051469984 +114 362 0.00051469984 +126 362 0.00051469984 +187 362 0.00051469984 +198 362 0.0087493993 +206 362 0.0010292998 +233 362 0.0056612976 +234 362 0.0020587 +240 362 0.021616098 +241 362 0.071538866 +262 362 0.00051469984 +272 362 0.0041172989 +277 362 0.044261497 +279 362 0.00051469984 +282 362 0.0036026998 +283 362 0.00051469984 +284 362 0.0010292998 +292 362 0.014410697 +293 362 0.0041172989 +295 362 0.0077199973 +296 362 0.0077199973 +298 362 0.0046319999 +312 362 0.00051469984 +315 362 0.021101397 +317 362 0.00051469984 +320 362 0.009778697 +321 362 0.020586699 +326 362 0.00051469984 +333 362 0.00051469984 +340 362 0.010807998 +351 362 0.0010292998 +353 362 0.0036026998 +358 362 0.0092639998 +362 362 0.033968098 +370 362 0.00051469984 +371 362 0.00051469984 +372 362 0.0082346983 +376 362 0.00051469984 +386 362 0.0066906996 +387 362 0.00051469984 +392 362 0.0061759986 +393 362 0.0015439999 +414 362 0.00051469984 +417 362 0.00051469984 +430 362 0.00051469984 +443 362 0.0010292998 +444 362 0.0010292998 +445 362 0.0046319999 +447 362 0.003088 +450 362 0.0066906996 +452 362 0.0051466972 +453 362 0.0020587 +455 362 0.029850699 +456 362 0.00051469984 +457 362 0.0056612976 +458 362 0.0015439999 +459 362 0.0020587 +460 362 0.0010292998 +463 362 0.0416881 +464 362 0.0025732999 +465 362 0.0020587 +467 362 0.032938797 +468 362 0.0056612976 +469 362 0.022130698 +470 362 0.025218699 +471 362 0.0010292998 +473 362 0.00051469984 +478 362 0.0020587 +483 362 0.0025732999 +490 362 0.0025732999 +491 362 0.0015439999 +9 363 0.0001637 +22 363 0.0001637 +60 363 0.0034387 +82 363 0.0001637 +83 363 0.0001637 +84 363 0.0001637 +104 363 0.0001637 +108 363 0.0001637 +113 363 0.00032749982 +114 363 0.00049119978 +126 363 0.00032749982 +127 363 0.0001637 +130 363 0.0001637 +131 363 0.00098249991 +151 363 0.0001637 +160 363 0.00081869983 +171 363 0.00081869983 +187 363 0.022924498 +188 363 0.00081869983 +189 363 0.0001637 +190 363 0.0001637 +192 363 0.00098249991 +194 363 0.00049119978 +198 363 0.015392199 +200 363 0.0001637 +203 363 0.00032749982 +206 363 0.0022924999 +211 363 0.0001637 +214 363 0.0037661998 +219 363 0.0001637 +221 363 0.0088422969 +223 363 0.00098249991 +224 363 0.0034387 +233 363 0.00081869983 +234 363 0.0024561998 +237 363 0.0001637 +240 363 0.0039298981 +241 363 0.011789698 +242 363 0.0001637 +248 363 0.0001637 +250 363 0.00032749982 +252 363 0.00049119978 +270 363 0.00032749982 +276 363 0.00049119978 +277 363 0.0442116 +279 363 0.0001637 +282 363 0.0024561998 +283 363 0.0001637 +284 363 0.00098249991 +285 363 0.00049119978 +286 363 0.0001637 +288 363 0.0001637 +290 363 0.0001637 +292 363 0.0081872977 +293 363 0.0027836999 +294 363 0.0057310984 +295 363 0.0011461999 +296 363 0.0039298981 +298 363 0.0026198998 +307 363 0.0001637 +308 363 0.006713599 +312 363 0.013918497 +315 363 0.0099884979 +317 363 0.0001637 +320 363 0.0021286998 +321 363 0.0055673979 +322 363 0.0026198998 +326 363 0.0021286998 +339 363 0.0001637 +340 363 0.0070410967 +348 363 0.00098249991 +350 363 0.0001637 +351 363 0.0050760992 +354 363 0.0021286998 +356 363 0.0001637 +358 363 0.0078597963 +359 363 0.0096609965 +360 363 0.0001637 +361 363 0.00081869983 +363 363 0.0081872977 +370 363 0.0016374998 +371 363 0.0029473999 +372 363 0.016865898 +373 363 0.0016374998 +376 363 0.00049119978 +384 363 0.0001637 +386 363 0.0055673979 +387 363 0.00032749982 +390 363 0.00049119978 +392 363 0.0099884979 +393 363 0.0024561998 +398 363 0.0001637 +413 363 0.0001637 +417 363 0.00032749982 +419 363 0.016538396 +420 363 0.00049119978 +422 363 0.0026198998 +423 363 0.00032749982 +424 363 0.0001637 +425 363 0.0001637 +426 363 0.0001637 +430 363 0.0001637 +431 363 0.0001637 +434 363 0.0001637 +441 363 0.0054035969 +442 363 0.00049119978 +443 363 0.0021286998 +444 363 0.0024561998 +445 363 0.0058948994 +446 363 0.0001637 +447 363 0.0027836999 +450 363 0.0050760992 +452 363 0.0049123988 +453 363 0.0018012 +454 363 0.00049119978 +455 363 0.034386799 +456 363 0.0011461999 +457 363 0.0065498985 +458 363 0.00081869983 +459 363 0.0031111999 +460 363 0.00098249991 +463 363 0.040936597 +464 363 0.00131 +465 363 0.0027836999 +467 363 0.027836896 +468 363 0.0065498985 +469 363 0.020468298 +470 363 0.022760797 +471 363 0.00081869983 +473 363 0.00065499987 +478 363 0.0019649998 +479 363 0.0001637 +483 363 0.0019649998 +490 363 0.0019649998 +491 363 0.0027836999 +60 364 0.0018743998 +104 364 0.00031239982 +107 364 0.00093719992 +110 364 0.0012496 +114 364 0.00031239982 +116 364 0.00093719992 +126 364 0.00031239982 +174 364 0.00031239982 +175 364 0.00062479987 +198 364 0.010309298 +204 364 0.00031239982 +206 364 0.00062479987 +233 364 0.0068728998 +234 364 0.0053107999 +236 364 0.00031239982 +240 364 0.0024991999 +241 364 0.011871297 +242 364 0.011246499 +277 364 0.061543297 +282 364 0.00093719992 +284 364 0.0018743998 +292 364 0.0012496 +293 364 0.005623199 +294 364 0.0034363999 +295 364 0.032802198 +296 364 0.0012496 +297 364 0.0034363999 +298 364 0.00093719992 +312 364 0.037175898 +315 364 0.023742598 +319 364 0.0062479973 +320 364 0.0062479973 +340 364 0.0059355982 +358 364 0.0012496 +364 364 0.028740998 +366 364 0.036238696 +370 364 0.0309278 +371 364 0.0134333 +372 364 0.020930998 +373 364 0.0084348992 +375 364 0.0021867999 +376 364 0.021868199 +386 364 0.0090596974 +387 364 0.00031239982 +391 364 0.0012496 +392 364 0.00031239982 +393 364 0.0018743998 +415 364 0.0018743998 +417 364 0.00062479987 +441 364 0.022492997 +443 364 0.0012496 +444 364 0.0031239998 +445 364 0.0065603964 +447 364 0.013745699 +450 364 0.0037487999 +452 364 0.0037487999 +453 364 0.0028116 +454 364 0.00093719992 +455 364 0.036551099 +456 364 0.00062479987 +457 364 0.0012496 +458 364 0.00062479987 +459 364 0.010309298 +460 364 0.00062479987 +463 364 0.016244899 +464 364 0.00062479987 +465 364 0.0012496 +467 364 0.0090596974 +468 364 0.0121837 +469 364 0.0062479973 +470 364 0.0068728998 +471 364 0.00093719992 +473 364 0.00031239982 +478 364 0.0012496 +483 364 0.0018743998 +490 364 0.00093719992 +491 364 0.0021867999 +60 365 0.0021243 +114 365 0.00053109997 +172 365 0.0010620998 +198 365 0.012214597 +206 365 0.00053109997 +233 365 0.0058416985 +234 365 0.0047795996 +236 365 0.00053109997 +240 365 0.0026552998 +241 365 0.012214597 +242 365 0.011152398 +270 365 0.00053109997 +277 365 0.082846463 +279 365 0.00053109997 +282 365 0.015400998 +284 365 0.0015931998 +292 365 0.0047795996 +293 365 0.0031863998 +295 365 0.0074348971 +296 365 0.0026552998 +297 365 0.0026552998 +298 365 0.0095591992 +312 365 0.0132767 +315 365 0.0074348971 +319 365 0.00053109997 +320 365 0.0058416985 +321 365 0.00053109997 +322 365 0.0026552998 +324 365 0.0058416985 +340 365 0.010090299 +341 365 0.00053109997 +351 365 0.0021243 +352 365 0.00053109997 +354 365 0.0053106993 +358 365 0.006903898 +364 365 0.0265534 +365 365 0.019649498 +366 365 0.0053106993 +370 365 0.00053109997 +372 365 0.050982498 +373 365 0.0015931998 +376 365 0.00053109997 +377 365 0.0010620998 +379 365 0.00053109997 +385 365 0.00053109997 +386 365 0.00053109997 +398 365 0.0015931998 +415 365 0.0175252 +417 365 0.00053109997 +419 365 0.016994197 +441 365 0.0037174998 +443 365 0.0010620998 +444 365 0.0010620998 +445 365 0.029208697 +447 365 0.0042484999 +450 365 0.0037174998 +452 365 0.0047795996 +453 365 0.0026552998 +455 365 0.034519397 +456 365 0.00053109997 +457 365 0.0015931998 +458 365 0.00053109997 +459 365 0.027084399 +460 365 0.00053109997 +463 365 0.014338799 +464 365 0.00053109997 +465 365 0.00053109997 +467 365 0.0090280995 +468 365 0.0090280995 +469 365 0.0053106993 +470 365 0.0053106993 +478 365 0.00053109997 +483 365 0.0015931998 +490 365 0.00053109997 +491 365 0.0037174998 +9 366 1.5399986e-05 +16 366 1.5399986e-05 +18 366 7.7199991e-05 +22 366 0.0002931999 +25 366 1.5399986e-05 +60 366 0.0012653 +79 366 1.5399986e-05 +82 366 1.5399986e-05 +83 366 1.5399986e-05 +84 366 1.5399986e-05 +108 366 3.0899988e-05 +113 366 4.6299989e-05 +114 366 9.2599992e-05 +126 366 4.6299989e-05 +127 366 1.5399986e-05 +130 366 1.5399986e-05 +131 366 6.169999e-05 +135 366 4.6299989e-05 +139 366 1.5399986e-05 +150 366 0.0004474998 +151 366 1.5399986e-05 +160 366 0.0023145999 +169 366 0.00021599999 +171 366 1.5399986e-05 +172 366 0.0017127998 +187 366 0.00066349981 +189 366 4.6299989e-05 +190 366 7.7199991e-05 +191 366 0.00050919992 +192 366 3.0899988e-05 +194 366 7.7199991e-05 +196 366 1.5399986e-05 +197 366 1.5399986e-05 +198 366 0.006881997 +200 366 4.6299989e-05 +201 366 3.0899988e-05 +203 366 4.6299989e-05 +204 366 7.7199991e-05 +206 366 0.00010799999 +207 366 4.6299989e-05 +209 366 1.5399986e-05 +214 366 0.0035026998 +218 366 1.5399986e-05 +219 366 0.00021599999 +223 366 0.00041659991 +224 366 7.7199991e-05 +229 366 1.5399986e-05 +233 366 0.0028237998 +234 366 0.0038884999 +236 366 0.00066349981 +237 366 0.0001389 +240 366 0.0038729999 +241 366 0.0081009977 +242 366 0.0035489998 +248 366 1.5399986e-05 +250 366 1.5399986e-05 +252 366 0.00098749995 +270 366 0.0018670999 +271 366 6.169999e-05 +272 366 0.00026229979 +274 366 0.0023453999 +277 366 0.052201197 +279 366 4.6299989e-05 +282 366 0.015754499 +283 366 0.0023916999 +284 366 0.0011264 +285 366 0.00067889993 +286 366 0.00063259993 +287 366 3.0899988e-05 +288 366 6.169999e-05 +289 366 7.7199991e-05 +290 366 0.0002468999 +292 366 0.0293178 +293 366 0.016078498 +294 366 0.0025614998 +295 366 0.0031168999 +296 366 0.0048605986 +297 366 0.0025922998 +298 366 0.0025459998 +299 366 1.5399986e-05 +304 366 0.0033020999 +307 366 0.0001852 +312 366 0.0068510994 +313 366 0.00010799999 +315 366 0.014782399 +317 366 1.5399986e-05 +318 366 1.5399986e-05 +319 366 0.0036878998 +320 366 0.00055549992 +321 366 0.0011880998 +322 366 0.0025151998 +324 366 0.0169889 +326 366 0.0013269999 +327 366 1.5399986e-05 +328 366 0.0037958999 +329 366 3.0899988e-05 +331 366 6.169999e-05 +332 366 1.5399986e-05 +338 366 0.00032399991 +339 366 0.00037029991 +340 366 0.0022836998 +341 366 4.6299989e-05 +344 366 4.6299989e-05 +349 366 6.169999e-05 +350 366 0.00080239982 +351 366 0.0042124987 +352 366 0.0085329972 +353 366 0.00046289992 +354 366 0.0018670999 +355 366 0.0001852 +356 366 7.7199991e-05 +357 366 0.00010799999 +358 366 0.0035952998 +364 366 3.0899988e-05 +366 366 0.069853544 +368 366 0.0004474998 +370 366 0.0001389 +371 366 0.0041353963 +372 366 0.071689785 +373 366 0.033159997 +374 366 1.5399986e-05 +376 366 6.169999e-05 +377 366 3.0899988e-05 +380 366 3.0899988e-05 +384 366 3.0899988e-05 +385 366 0.00012339999 +386 366 0.0033175 +387 366 3.0899988e-05 +390 366 6.169999e-05 +392 366 4.6299989e-05 +393 366 0.00012339999 +397 366 7.7199991e-05 +398 366 0.0004782998 +401 366 1.5399986e-05 +402 366 0.00057089981 +404 366 1.5399986e-05 +405 366 4.6299989e-05 +414 366 1.5399986e-05 +415 366 0.0066041984 +417 366 0.00032399991 +419 366 0.0045982972 +421 366 4.6299989e-05 +422 366 6.169999e-05 +423 366 1.5399986e-05 +425 366 1.5399986e-05 +430 366 1.5399986e-05 +431 366 3.0899988e-05 +432 366 1.5399986e-05 +433 366 3.0899988e-05 +434 366 3.0899988e-05 +441 366 0.0018824998 +442 366 0.00032399991 +443 366 0.0033175 +444 366 0.0012498999 +445 366 0.0063727982 +446 366 0.00043209991 +447 366 0.0022219999 +448 366 1.5399986e-05 +450 366 0.0042433999 +452 366 0.004227899 +453 366 0.0016355999 +454 366 0.00092579983 +455 366 0.040119097 +456 366 0.00063259993 +457 366 0.0018516998 +458 366 0.0001543 +459 366 0.00078699994 +460 366 0.00095669995 +463 366 0.0080237985 +464 366 0.0016355999 +465 366 0.00087949983 +467 366 0.0094433986 +468 366 0.010199498 +469 366 0.0055394992 +470 366 0.0039192997 +471 366 0.0041044988 +473 366 9.2599992e-05 +477 366 0.0001389 +478 366 0.00083319983 +483 366 0.00083319983 +489 366 4.6299989e-05 +490 366 0.00030859979 +491 366 0.0026385998 +60 367 0.0020736 +114 367 0.00051839999 +126 367 0.00051839999 +160 367 0.00051839999 +198 367 0.0088128969 +206 367 0.0010368 +214 367 0.0025919999 +233 367 0.00051839999 +234 367 0.0051839985 +241 367 0.012441698 +242 367 0.034214597 +270 367 0.00051839999 +272 367 0.0020736 +277 367 0.046656299 +279 367 0.00051839999 +282 367 0.020736098 +283 367 0.0057023987 +284 367 0.0015552 +285 367 0.00051839999 +286 367 0.00051839999 +289 367 0.00051839999 +292 367 0.0031103999 +293 367 0.0015552 +294 367 0.0010368 +295 367 0.0010368 +296 367 0.011923298 +297 367 0.0010368 +298 367 0.0010368 +307 367 0.0020736 +312 367 0.0015552 +321 367 0.020736098 +324 367 0.033696197 +328 367 0.0041471981 +329 367 0.00051839999 +333 367 0.00051839999 +340 367 0.0098496974 +349 367 0.0010368 +350 367 0.0010368 +351 367 0.0031103999 +354 367 0.0041471981 +358 367 0.0155521 +367 367 0.025920197 +372 367 0.023846596 +373 367 0.0020736 +402 367 0.00051839999 +414 367 0.06428194 +417 367 0.00051839999 +419 367 0.00051839999 +443 367 0.0010368 +444 367 0.00051839999 +445 367 0.0031103999 +447 367 0.013996899 +450 367 0.0046655983 +452 367 0.0051839985 +453 367 0.0025919999 +454 367 0.0015552 +455 367 0.033177797 +456 367 0.00051839999 +457 367 0.0020736 +458 367 0.0010368 +459 367 0.020217698 +460 367 0.0010368 +463 367 0.022291299 +464 367 0.00051839999 +465 367 0.00051839999 +467 367 0.0093312971 +468 367 0.0088128969 +469 367 0.0057023987 +470 367 0.0057023987 +471 367 0.00051839999 +473 367 0.00051839999 +478 367 0.0010368 +483 367 0.0015552 +490 367 0.0010368 +491 367 0.0015552 +13 368 0.00011179999 +22 368 0.00011179999 +24 368 0.00011179999 +25 368 0.0032434999 +60 368 0.0014539999 +82 368 0.00011179999 +108 368 0.00011179999 +114 368 0.00011179999 +120 368 0.00022369999 +126 368 0.00011179999 +135 368 0.00033549988 +139 368 0.00011179999 +142 368 0.00078289979 +150 368 0.00011179999 +160 368 0.00022369999 +165 368 0.00022369999 +170 368 0.00011179999 +171 368 0.00011179999 +187 368 0.00067109987 +189 368 0.00011179999 +190 368 0.00011179999 +191 368 0.00011179999 +193 368 0.00011179999 +194 368 0.00022369999 +198 368 0.010289699 +206 368 0.00022369999 +214 368 0.0059276968 +218 368 0.00011179999 +223 368 0.00022369999 +224 368 0.011631798 +233 368 0.0027961 +234 368 0.0051447973 +236 368 0.00033549988 +237 368 0.00011179999 +240 368 0.0019013998 +241 368 0.0161056 +242 368 0.0095067993 +252 368 0.00011179999 +270 368 0.0010066 +272 368 0.0026842998 +277 368 0.070461869 +279 368 0.00055919983 +282 368 0.0152108 +283 368 0.00033549988 +284 368 0.0015657998 +289 368 0.00011179999 +292 368 0.0024605999 +293 368 0.0074935965 +294 368 0.0049210973 +295 368 0.00067109987 +296 368 0.0048092976 +297 368 0.0035789998 +298 368 0.0012302999 +299 368 0.00011179999 +301 368 0.00011179999 +307 368 0.018566199 +312 368 0.0079408996 +315 368 0.016553 +317 368 0.00011179999 +318 368 0.0021249999 +319 368 0.0036908998 +320 368 0.0012302999 +321 368 0.0039145984 +322 368 0.00022369999 +324 368 0.017223999 +326 368 0.00044739991 +328 368 0.0040263981 +331 368 0.00011179999 +332 368 0.00011179999 +335 368 0.00011179999 +339 368 0.00044739991 +340 368 0.0031315999 +350 368 0.009394899 +351 368 0.0032434999 +352 368 0.020131998 +354 368 0.010513399 +355 368 0.00011179999 +356 368 0.0019013998 +358 368 0.0053684972 +366 368 0.00033549988 +368 368 0.013868697 +369 368 0.00011179999 +370 368 0.00011179999 +371 368 0.00033549988 +372 368 0.034112498 +373 368 0.00044739991 +377 368 0.00011179999 +380 368 0.00022369999 +386 368 0.014092397 +387 368 0.00011179999 +390 368 0.00033549988 +392 368 0.00033549988 +393 368 0.00044739991 +404 368 0.00011179999 +405 368 0.0014539999 +414 368 0.0061513968 +415 368 0.0026842998 +417 368 0.00044739991 +419 368 0.009618599 +421 368 0.00011179999 +422 368 0.00022369999 +430 368 0.00011179999 +438 368 0.0029079998 +441 368 0.0026842998 +443 368 0.0034671999 +444 368 0.0022368999 +445 368 0.011967298 +446 368 0.00067109987 +447 368 0.0055921972 +450 368 0.0036908998 +452 368 0.0039145984 +453 368 0.0017894998 +454 368 0.00033549988 +455 368 0.044178497 +456 368 0.00067109987 +457 368 0.0021249999 +458 368 0.00044739991 +459 368 0.00022369999 +460 368 0.00089479983 +463 368 0.013868697 +464 368 0.0078290999 +465 368 0.00078289979 +467 368 0.0090593994 +468 368 0.012302898 +469 368 0.006710697 +470 368 0.0076053999 +471 368 0.0010066 +473 368 0.00022369999 +477 368 0.00011179999 +478 368 0.0010066 +483 368 0.0013420999 +490 368 0.00067109987 +491 368 0.0019013998 +9 369 7.0799986e-05 +18 369 0.00014169999 +60 369 0.0029044999 +82 369 7.0799986e-05 +83 369 7.0799986e-05 +84 369 7.0799986e-05 +108 369 7.0799986e-05 +113 369 0.00014169999 +114 369 0.00021249999 +126 369 0.00014169999 +127 369 7.0799986e-05 +150 369 0.00070839981 +165 369 7.0799986e-05 +189 369 0.00014169999 +190 369 0.00014169999 +192 369 7.0799986e-05 +194 369 0.00021249999 +198 369 0.0029044999 +200 369 7.0799986e-05 +201 369 7.0799986e-05 +203 369 7.0799986e-05 +204 369 0.0014167998 +206 369 0.0003541999 +207 369 7.0799986e-05 +214 369 7.0799986e-05 +223 369 7.0799986e-05 +224 369 0.0039670989 +233 369 7.0799986e-05 +234 369 0.0018418999 +237 369 7.0799986e-05 +240 369 7.0799986e-05 +241 369 0.0043212995 +248 369 7.0799986e-05 +250 369 7.0799986e-05 +252 369 0.003117 +262 369 0.00014169999 +277 369 0.010555398 +282 369 0.0014167998 +283 369 0.00014169999 +284 369 0.00049589993 +285 369 7.0799986e-05 +286 369 7.0799986e-05 +290 369 0.0058798976 +292 369 0.0030461999 +293 369 0.003117 +294 369 0.0011334999 +295 369 0.0167186 +296 369 0.0045338981 +297 369 0.00021249999 +305 369 7.0799986e-05 +307 369 7.0799986e-05 +308 369 0.00014169999 +312 369 0.0053130984 +313 369 7.0799986e-05 +315 369 0.011193 +317 369 7.0799986e-05 +320 369 0.0019126998 +321 369 0.00014169999 +322 369 0.0021251999 +326 369 0.0015584999 +340 369 0.0037546 +351 369 0.00021249999 +356 369 0.00014169999 +358 369 0.0057381988 +359 369 0.010484599 +369 369 0.0575234 +370 369 0.0011334999 +371 369 0.0034711999 +372 369 0.0037546 +373 369 0.0016293998 +376 369 0.00042499998 +386 369 0.027203199 +387 369 0.00021249999 +389 369 0.0023377999 +390 369 0.0034003998 +391 369 0.0033296 +392 369 0.028265797 +393 369 0.065670192 +402 369 0.00021249999 +413 369 0.00014169999 +414 369 0.0021960998 +417 369 0.00049589993 +419 369 0.00092089991 +420 369 0.00014169999 +421 369 7.0799986e-05 +422 369 0.00014169999 +423 369 7.0799986e-05 +424 369 0.0026919998 +425 369 7.0799986e-05 +430 369 7.0799986e-05 +431 369 7.0799986e-05 +433 369 7.0799986e-05 +434 369 7.0799986e-05 +443 369 0.00056669977 +444 369 0.0060923994 +445 369 0.0022668999 +446 369 7.0799986e-05 +447 369 0.0083592981 +450 369 0.0089259967 +452 369 0.0043921992 +453 369 0.0010625999 +454 369 0.00056669977 +455 369 0.021039996 +456 369 0.0007793 +457 369 0.0049588978 +458 369 0.00099179987 +459 369 0.00063759997 +460 369 0.0012043 +463 369 0.018418796 +464 369 0.0092093982 +465 369 0.010626197 +467 369 0.016010199 +468 369 0.0062340982 +469 369 0.010272 +470 369 0.011901397 +471 369 0.0030461999 +473 369 0.00028339983 +477 369 0.00021249999 +478 369 0.0016293998 +483 369 0.0017001999 +490 369 0.0087134987 +491 369 0.0035420998 +9 370 6.8699999e-05 +18 370 0.0001375 +22 370 0.0001375 +60 370 0.0027494999 +82 370 6.8699999e-05 +83 370 6.8699999e-05 +84 370 6.8699999e-05 +108 370 6.8699999e-05 +113 370 0.0001375 +114 370 0.0002062 +126 370 6.8699999e-05 +150 370 0.00061859982 +160 370 0.0040554963 +169 370 0.0015121999 +172 370 0.0026807999 +187 370 0.010379396 +189 370 6.8699999e-05 +190 370 6.8699999e-05 +192 370 6.8699999e-05 +194 370 6.8699999e-05 +198 370 0.0043304972 +200 370 6.8699999e-05 +203 370 6.8699999e-05 +204 370 6.8699999e-05 +206 370 0.0001375 +207 370 6.8699999e-05 +214 370 0.0028869999 +223 370 6.8699999e-05 +224 370 0.0001375 +233 370 0.0068737976 +234 370 0.013335198 +237 370 6.8699999e-05 +241 370 0.0030244999 +252 370 0.000275 +262 370 0.015397299 +272 370 0.0068737976 +277 370 0.12998348 +279 370 0.0002062 +282 370 6.8699999e-05 +284 370 0.00041239988 +289 370 0.016359597 +290 370 6.8699999e-05 +292 370 0.012097899 +293 370 0.016772099 +294 370 0.0001375 +295 370 0.062620282 +296 370 0.0001375 +307 370 0.0052240975 +308 370 6.8699999e-05 +312 370 0.0065987967 +315 370 0.0063238963 +320 370 0.0001375 +339 370 0.00048119994 +340 370 0.0015121999 +354 370 6.8699999e-05 +356 370 0.0001375 +358 370 0.0019246999 +359 370 0.0001375 +369 370 0.00068739988 +370 370 0.00082489988 +371 370 0.0026119999 +372 370 6.8699999e-05 +373 370 0.00048119994 +375 370 6.8699999e-05 +376 370 0.044267297 +384 370 6.8699999e-05 +385 370 6.8699999e-05 +386 370 0.019384097 +387 370 6.8699999e-05 +391 370 0.0002062 +392 370 0.00048119994 +393 370 0.0017183998 +396 370 6.8699999e-05 +398 370 6.8699999e-05 +402 370 6.8699999e-05 +404 370 0.0002062 +414 370 0.0056364983 +417 370 0.00041239988 +421 370 6.8699999e-05 +422 370 6.8699999e-05 +423 370 6.8699999e-05 +430 370 6.8699999e-05 +431 370 6.8699999e-05 +433 370 6.8699999e-05 +434 370 0.0001375 +443 370 0.0046053976 +444 370 0.0002062 +445 370 0.0077673979 +446 370 0.00075609982 +447 370 0.00075609982 +448 370 0.0002062 +450 370 0.0043304972 +452 370 0.0063238963 +453 370 0.0010998 +454 370 0.0023371 +455 370 0.0328568 +456 370 0.00034369994 +457 370 0.0030244999 +458 370 0.00096229999 +459 370 0.00034369994 +460 370 0.00096229999 +463 370 0.0048803985 +464 370 0.00041239988 +465 370 0.023302197 +467 370 0.014297497 +468 370 0.0011684999 +469 370 0.0060488991 +470 370 0.0066675991 +471 370 0.00054989988 +473 370 0.0001375 +477 370 0.0001375 +478 370 0.0013748 +483 370 0.0010998 +490 370 0.0093483999 +491 370 0.00082489988 +9 371 4.7399997e-05 +18 371 9.4799994e-05 +22 371 4.7399997e-05 +60 371 0.0020857998 +82 371 4.7399997e-05 +83 371 4.7399997e-05 +84 371 4.7399997e-05 +108 371 4.7399997e-05 +113 371 9.4799994e-05 +114 371 0.00014219999 +126 371 9.4799994e-05 +127 371 4.7399997e-05 +150 371 0.00071109994 +160 371 0.0011850998 +169 371 0.0015168998 +172 371 0.00080589997 +187 371 0.00023699999 +189 371 9.4799994e-05 +190 371 9.4799994e-05 +194 371 0.00014219999 +197 371 4.7399997e-05 +198 371 0.0041715987 +200 371 9.4799994e-05 +201 371 9.4799994e-05 +203 371 9.4799994e-05 +204 371 0.00014219999 +206 371 0.00014219999 +207 371 4.7399997e-05 +214 371 0.00028439984 +223 371 0.00018959999 +224 371 0.008011397 +233 371 0.0019435999 +234 371 0.0024175998 +237 371 9.4799994e-05 +240 371 0.0018961998 +241 371 0.017065696 +248 371 4.7399997e-05 +250 371 4.7399997e-05 +252 371 0.00018959999 +262 371 0.016686399 +272 371 4.7399997e-05 +277 371 0.038018499 +282 371 0.0016117999 +283 371 0.00018959999 +284 371 0.00042659999 +286 371 0.0070632994 +288 371 0.00014219999 +289 371 0.0025123998 +290 371 0.0035078998 +292 371 0.027067997 +293 371 0.0102394 +294 371 0.00085329986 +295 371 0.011045299 +296 371 0.0028442999 +297 371 0.0063047968 +298 371 0.0035078998 +299 371 4.7399997e-05 +305 371 4.7399997e-05 +307 371 9.4799994e-05 +308 371 0.0073002987 +312 371 0.013557699 +315 371 0.0030812998 +317 371 9.4799994e-05 +320 371 0.011282299 +321 371 0.00042659999 +322 371 0.0021331999 +324 371 4.7399997e-05 +326 371 0.00085329986 +327 371 0.00018959999 +328 371 9.4799994e-05 +338 371 0.00047399988 +339 371 0.0005214999 +340 371 0.0037449999 +341 371 4.7399997e-05 +351 371 4.7399997e-05 +354 371 0.0005214999 +356 371 0.00014219999 +358 371 0.0044559985 +359 371 9.4799994e-05 +369 371 0.0027021 +370 371 0.0036976 +371 371 0.010571197 +372 371 0.0036026998 +373 371 0.08063519 +376 371 0.0037923998 +386 371 0.010191999 +387 371 9.4799994e-05 +389 371 0.00014219999 +390 371 0.00023699999 +391 371 4.7399997e-05 +392 371 0.0005214999 +393 371 0.0085327998 +398 371 0.00014219999 +402 371 4.7399997e-05 +405 371 4.7399997e-05 +414 371 4.7399997e-05 +417 371 0.00042659999 +419 371 0.00037919986 +421 371 4.7399997e-05 +422 371 0.00018959999 +423 371 4.7399997e-05 +425 371 4.7399997e-05 +430 371 4.7399997e-05 +431 371 4.7399997e-05 +433 371 4.7399997e-05 +434 371 4.7399997e-05 +441 371 0.0019909998 +443 371 0.002228 +444 371 0.0049300976 +445 371 0.0066365972 +446 371 0.00014219999 +447 371 0.004882697 +450 371 0.0064469986 +452 371 0.0054514967 +453 371 0.00099549978 +454 371 0.00071109994 +455 371 0.026830997 +456 371 0.00056889979 +457 371 0.004740499 +458 371 0.00075849984 +459 371 0.00033179997 +460 371 0.00094809989 +463 371 0.024934798 +464 371 0.0071106963 +465 371 0.011708897 +467 371 0.015880499 +468 371 0.0047878996 +469 371 0.0079165995 +470 371 0.0088172965 +471 371 0.0027494999 +473 371 0.00018959999 +477 371 0.00018959999 +478 371 0.0014694999 +483 371 0.0012798999 +489 371 4.7399997e-05 +490 371 0.00085329986 +491 371 0.0011850998 +9 372 3.5699995e-05 +18 372 0.000143 +19 372 7.1499991e-05 +22 372 0.00017869999 +60 372 0.0025020998 +79 372 3.5699995e-05 +82 372 3.5699995e-05 +83 372 3.5699995e-05 +84 372 3.5699995e-05 +108 372 3.5699995e-05 +113 372 7.1499991e-05 +114 372 0.000143 +126 372 7.1499991e-05 +127 372 3.5699995e-05 +130 372 7.1499991e-05 +134 372 7.1499991e-05 +135 372 0.00071489997 +139 372 3.5699995e-05 +150 372 0.00064339978 +160 372 0.0016084998 +161 372 3.5699995e-05 +169 372 0.00085779978 +172 372 0.00064339978 +187 372 3.5699995e-05 +189 372 0.00010719999 +190 372 0.00010719999 +191 372 0.00085779978 +194 372 0.000143 +197 372 3.5699995e-05 +198 372 0.0048968978 +200 372 7.1499991e-05 +201 372 7.1499991e-05 +203 372 7.1499991e-05 +204 372 7.1499991e-05 +206 372 0.00017869999 +207 372 3.5699995e-05 +214 372 0.000143 +218 372 3.5699995e-05 +223 372 0.000143 +224 372 0.0029666999 +225 372 0.00017869999 +227 372 3.5699995e-05 +233 372 0.0028594998 +234 372 0.0022161 +237 372 0.000143 +240 372 0.00053619989 +241 372 0.0038602999 +242 372 0.0034671 +243 372 3.5699995e-05 +248 372 3.5699995e-05 +250 372 7.1499991e-05 +252 372 0.00021449999 +262 372 0.00010719999 +270 372 0.00028589997 +271 372 0.00025019981 +272 372 0.00028589997 +276 372 0.0030381999 +277 372 0.070057452 +279 372 3.5699995e-05 +282 372 0.027951498 +283 372 0.0043964982 +284 372 0.00053619989 +285 372 3.5699995e-05 +286 372 0.0010722999 +288 372 0.00010719999 +289 372 0.0033955998 +290 372 0.0046823993 +292 372 0.011688199 +293 372 0.0043606982 +294 372 0.00096509978 +295 372 0.052614599 +296 372 0.0068627968 +297 372 0.00089359982 +298 372 0.00035739993 +299 372 0.00050039985 +305 372 0.00025019981 +307 372 0.00050039985 +308 372 0.00025019981 +312 372 0.009114597 +313 372 0.00042889989 +315 372 0.011008997 +317 372 0.0021445998 +319 372 0.00017869999 +320 372 0.0023232999 +321 372 0.00021449999 +322 372 0.00050039985 +323 372 7.1499991e-05 +324 372 0.00028589997 +326 372 0.0028237 +327 372 0.0011437999 +328 372 0.012688998 +330 372 3.5699995e-05 +331 372 0.00025019981 +332 372 0.000143 +338 372 0.00082209986 +339 372 0.00021449999 +340 372 0.011259198 +341 372 0.00010719999 +350 372 0.00046469993 +351 372 0.0084354989 +352 372 0.00010719999 +354 372 0.0096507967 +355 372 3.5699995e-05 +356 372 0.00017869999 +357 372 0.0010366 +358 372 0.0090430975 +366 372 7.1499991e-05 +369 372 0.000143 +370 372 0.00010719999 +371 372 0.0095077977 +372 372 0.015298299 +373 372 0.00060759997 +374 372 3.5699995e-05 +375 372 0.0033241999 +376 372 0.0059691966 +384 372 3.5699995e-05 +386 372 0.00017869999 +387 372 7.1499991e-05 +390 372 0.00028589997 +391 372 0.0010366 +392 372 0.0013939999 +393 372 0.0026807999 +396 372 0.00010719999 +397 372 0.002931 +398 372 0.00017869999 +402 372 0.0021445998 +404 372 0.00032169977 +405 372 0.00028589997 +408 372 0.0029666999 +412 372 0.00010719999 +414 372 7.1499991e-05 +417 372 0.00042889989 +419 372 0.0012867998 +421 372 7.1499991e-05 +422 372 0.000143 +423 372 7.1499991e-05 +424 372 3.5699995e-05 +425 372 3.5699995e-05 +426 372 3.5699995e-05 +430 372 0.000143 +431 372 3.5699995e-05 +433 372 3.5699995e-05 +434 372 3.5699995e-05 +443 372 0.0030024999 +444 372 0.0030739999 +445 372 0.0072201975 +446 372 0.00039319997 +447 372 0.0034671 +450 372 0.0061121993 +452 372 0.0060406998 +453 372 0.0021088999 +454 372 0.00057189981 +455 372 0.026021399 +456 372 0.00046469993 +457 372 0.0028951999 +458 372 0.00064339978 +459 372 0.00046469993 +460 372 0.0010722999 +463 372 0.0115452 +464 372 0.0041462965 +465 372 0.011330698 +467 372 0.015262499 +468 372 0.0028237 +469 372 0.0064695999 +470 372 0.0073988996 +471 372 0.0022876 +473 372 0.000143 +477 372 0.00025019981 +478 372 0.0014654999 +483 372 0.0015727 +489 372 3.5699995e-05 +490 372 0.0048968978 +491 372 0.0024305999 +9 373 7.6299999e-05 +18 373 0.0001527 +60 373 0.0025954 +82 373 7.6299999e-05 +83 373 7.6299999e-05 +84 373 7.6299999e-05 +108 373 7.6299999e-05 +113 373 0.0001527 +114 373 0.000229 +126 373 0.0001527 +127 373 7.6299999e-05 +150 373 0.00061069988 +160 373 0.0010686999 +169 373 7.6299999e-05 +172 373 0.00061069988 +175 373 7.6299999e-05 +189 373 7.6299999e-05 +190 373 0.0001527 +192 373 7.6299999e-05 +194 373 0.0001527 +198 373 0.0060304999 +200 373 7.6299999e-05 +201 373 7.6299999e-05 +203 373 7.6299999e-05 +204 373 7.6299999e-05 +206 373 0.000229 +207 373 7.6299999e-05 +214 373 7.6299999e-05 +223 373 0.0001527 +224 373 0.0070228986 +233 373 0.0016031 +234 373 0.0021374 +237 373 7.6299999e-05 +240 373 0.0014503999 +241 373 0.014427498 +248 373 7.6299999e-05 +250 373 7.6299999e-05 +252 373 0.000229 +262 373 0.0010686999 +270 373 0.0001527 +272 373 7.6299999e-05 +277 373 0.024198499 +282 373 0.0029771 +283 373 0.00030529988 +284 373 0.00053439988 +286 373 0.0032823998 +288 373 0.0001527 +289 373 0.0024426999 +290 373 0.00068699988 +292 373 0.0164885 +293 373 0.0031297999 +294 373 0.00053439988 +295 373 0.016793899 +296 373 0.0024426999 +297 373 0.0012214 +298 373 0.00030529988 +305 373 7.6299999e-05 +307 373 7.6299999e-05 +308 373 0.015877899 +312 373 0.0098472983 +315 373 0.00091599999 +317 373 7.6299999e-05 +319 373 0.0001527 +320 373 0.0067938976 +321 373 0.0037405 +322 373 0.0003817 +324 373 0.000229 +326 373 0.0001527 +327 373 0.0001527 +328 373 7.6299999e-05 +340 373 0.006870199 +351 373 7.6299999e-05 +352 373 7.6299999e-05 +354 373 0.0001527 +356 373 0.0001527 +358 373 0.0044274963 +359 373 0.0012977 +369 373 0.0082442984 +370 373 0.0022900999 +371 373 0.0073281974 +372 373 0.0074045993 +373 373 0.08763355 +376 373 0.0042747967 +386 373 0.011450399 +387 373 0.000229 +389 373 0.00091599999 +390 373 0.00068699988 +391 373 0.0016031 +392 373 0.0012977 +393 373 0.023969498 +405 373 0.0001527 +413 373 7.6299999e-05 +414 373 7.6299999e-05 +415 373 7.6299999e-05 +417 373 0.00053439988 +419 373 0.00061069988 +421 373 7.6299999e-05 +422 373 0.0001527 +423 373 7.6299999e-05 +424 373 7.6299999e-05 +425 373 7.6299999e-05 +430 373 7.6299999e-05 +431 373 7.6299999e-05 +433 373 7.6299999e-05 +434 373 7.6299999e-05 +441 373 0.0017557 +442 373 7.6299999e-05 +443 373 0.001374 +444 373 0.00083969999 +445 373 0.0058014989 +446 373 7.6299999e-05 +447 373 0.0038168 +450 373 0.0076335967 +452 373 0.0067175999 +453 373 0.0016031 +454 373 0.00061069988 +455 373 0.025419798 +456 373 0.00068699988 +457 373 0.0031297999 +458 373 0.00099239987 +459 373 0.00045799999 +460 373 0.00099239987 +463 373 0.011603098 +464 373 0.0010686999 +465 373 0.011144999 +467 373 0.016717598 +468 373 0.0017557 +469 373 0.010839697 +470 373 0.012137398 +471 373 0.0028243999 +473 373 0.00030529988 +477 373 0.0001527 +478 373 0.0016794 +483 373 0.0011449999 +490 373 0.0010686999 +491 373 0.0012977 +22 374 0.00016659999 +60 374 0.0019989999 +108 374 0.00016659999 +114 374 0.00016659999 +126 374 0.00016659999 +130 374 0.00016659999 +131 374 0.00016659999 +160 374 0.0013326998 +169 374 0.00099949981 +171 374 0.00016659999 +172 374 0.00033319998 +187 374 0.00016659999 +190 374 0.00016659999 +198 374 0.0041645989 +204 374 0.00016659999 +206 374 0.00049979985 +214 374 0.0013326998 +223 374 0.057471298 +224 374 0.00033319998 +225 374 0.00016659999 +233 374 0.0019989999 +234 374 0.0011660999 +240 374 0.00099949981 +241 374 0.0016657999 +252 374 0.00083289994 +270 374 0.0028318998 +272 374 0.00033319998 +277 374 0.14192897 +279 374 0.00016659999 +282 374 0.00049979985 +283 374 0.00016659999 +284 374 0.00033319998 +285 374 0.00016659999 +287 374 0.0036648 +290 374 0.008828897 +292 374 0.012660298 +293 374 0.0029984999 +294 374 0.00016659999 +295 374 0.022155598 +296 374 0.0043311976 +297 374 0.0073296987 +312 374 0.011161096 +320 374 0.00016659999 +324 374 0.00016659999 +328 374 0.010994498 +338 374 0.00016659999 +339 374 0.00016659999 +340 374 0.011993997 +344 374 0.00016659999 +356 374 0.00016659999 +358 374 0.0079959966 +370 374 0.015991997 +372 374 0.011827398 +373 374 0.030651297 +374 374 0.015325699 +375 374 0.00049979985 +387 374 0.00016659999 +390 374 0.00016659999 +392 374 0.00033319998 +393 374 0.0011660999 +394 374 0.00066629983 +405 374 0.00016659999 +408 374 0.00033319998 +416 374 0.00016659999 +417 374 0.00049979985 +430 374 0.00016659999 +443 374 0.0064967982 +444 374 0.0036648 +445 374 0.014159597 +446 374 0.00033319998 +447 374 0.0053306967 +450 374 0.0034983 +452 374 0.0058303997 +453 374 0.0028318998 +454 374 0.00049979985 +455 374 0.032317199 +456 374 0.00016659999 +457 374 0.0031650998 +458 374 0.00066629983 +459 374 0.00049979985 +460 374 0.00083289994 +463 374 0.010827899 +464 374 0.00066629983 +465 374 0.0016657999 +467 374 0.019157097 +468 374 0.0084957965 +469 374 0.0074962974 +470 374 0.0079959966 +471 374 0.00049979985 +473 374 0.00016659999 +477 374 0.00016659999 +478 374 0.0011660999 +483 374 0.00083289994 +490 374 0.00099949981 +491 374 0.0019989999 +22 375 0.0038426998 +60 375 0.0065030977 +114 375 0.00029559992 +126 375 0.00029559992 +160 375 0.0011823999 +169 375 0.0011823999 +172 375 0.0011823999 +198 375 0.0029559999 +206 375 0.00059119985 +214 375 0.029263999 +223 375 0.00029559992 +233 375 0.0076854974 +234 375 0.0331067 +241 375 0.055867597 +270 375 0.012710597 +273 375 0.0091634989 +277 375 0.0091634989 +284 375 0.00029559992 +286 375 0.013892997 +292 375 0.0026603998 +295 375 0.0041382983 +312 375 0.0112326 +326 375 0.042565797 +340 375 0.0056162998 +356 375 0.00029559992 +358 375 0.015075397 +372 375 0.008572299 +373 375 0.00059119985 +375 375 0.037244998 +417 375 0.00059119985 +443 375 0.015962198 +444 375 0.015075397 +445 375 0.013597399 +446 375 0.0011823999 +447 375 0.013006199 +450 375 0.0050251 +452 375 0.034289099 +453 375 0.015666597 +454 375 0.0035470999 +455 375 0.023943197 +457 375 0.0032515998 +458 375 0.00088679977 +459 375 0.00059119985 +460 375 0.0011823999 +463 375 0.0032515998 +464 375 0.00088679977 +465 375 0.0014779998 +467 375 0.015962198 +468 375 0.013301797 +469 375 0.0065030977 +470 375 0.0070942976 +471 375 0.00029559992 +473 375 0.00029559992 +477 375 0.00029559992 +478 375 0.0011823999 +483 375 0.00088679977 +490 375 0.00088679977 +491 375 0.0026603998 +22 376 0.0012508 +60 376 0.0022930999 +108 376 0.00020849999 +114 376 0.00020849999 +126 376 0.00020849999 +150 376 0.00020849999 +160 376 0.0012508 +169 376 0.0016676998 +172 376 0.0012508 +187 376 0.033562597 +190 376 0.00020849999 +194 376 0.00020849999 +198 376 0.0052115992 +200 376 0.00020849999 +206 376 0.0004168998 +214 376 0.0045861974 +223 376 0.0010422999 +224 376 0.00062539987 +233 376 0.0050030984 +234 376 0.0027099999 +237 376 0.00020849999 +241 376 0.016468599 +252 376 0.00062539987 +262 376 0.022305597 +272 376 0.00020849999 +276 376 0.00020849999 +277 376 0.026474897 +282 376 0.0012508 +283 376 0.00062539987 +284 376 0.00062539987 +285 376 0.00020849999 +290 376 0.00020849999 +292 376 0.012507796 +293 376 0.015426297 +294 376 0.0035438999 +295 376 0.052115899 +296 376 0.0004168998 +298 376 0.00062539987 +299 376 0.0022930999 +307 376 0.00020849999 +312 376 0.013133198 +315 376 0.012924697 +317 376 0.0018761999 +320 376 0.0012508 +321 376 0.0062538981 +326 376 0.014175497 +328 376 0.0004168998 +331 376 0.00020849999 +332 376 0.00020849999 +335 376 0.00020849999 +340 376 0.0052115992 +349 376 0.00020849999 +351 376 0.00020849999 +354 376 0.00083389995 +355 376 0.00020849999 +356 376 0.00020849999 +358 376 0.0064623989 +359 376 0.00020849999 +369 376 0.0010422999 +370 376 0.0150094 +371 376 0.0193871 +372 376 0.00062539987 +373 376 0.0014591999 +374 376 0.00020849999 +376 376 0.013550099 +384 376 0.0004168998 +385 376 0.0004168998 +386 376 0.0010422999 +387 376 0.00020849999 +390 376 0.00020849999 +392 376 0.0152178 +393 376 0.024181798 +397 376 0.0010422999 +402 376 0.00020849999 +404 376 0.0025016 +405 376 0.0012508 +414 376 0.00020849999 +417 376 0.00062539987 +422 376 0.00020849999 +430 376 0.00020849999 +443 376 0.0025016 +444 376 0.0010422999 +445 376 0.0062538981 +447 376 0.0075046979 +450 376 0.0058369972 +452 376 0.0064623989 +453 376 0.0018761999 +454 376 0.00083389995 +455 376 0.026058 +456 376 0.0004168998 +457 376 0.0027099999 +458 376 0.0014591999 +459 376 0.0004168998 +460 376 0.00062539987 +463 376 0.015843198 +464 376 0.0018761999 +465 376 0.011465497 +467 376 0.0193871 +468 376 0.0020845998 +469 376 0.011256997 +470 376 0.012924697 +471 376 0.0012508 +473 376 0.00020849999 +477 376 0.00020849999 +478 376 0.0018761999 +483 376 0.0010422999 +490 376 0.0014591999 +491 376 0.0012508 +22 377 0.00019199999 +24 377 9.5999989e-05 +60 377 0.0011520998 +108 377 9.5999989e-05 +114 377 0.00019199999 +126 377 9.5999989e-05 +130 377 9.5999989e-05 +131 377 0.0039362982 +135 377 0.0025921999 +137 377 9.5999989e-05 +139 377 0.00019199999 +150 377 9.5999989e-05 +160 377 0.00057599996 +161 377 9.5999989e-05 +165 377 9.5999989e-05 +170 377 9.5999989e-05 +171 377 0.00019199999 +172 377 0.00067199999 +187 377 0.00019199999 +190 377 9.5999989e-05 +191 377 9.5999989e-05 +194 377 0.00019199999 +198 377 0.016609099 +206 377 0.00067199999 +214 377 0.00096009998 +223 377 0.0060484 +224 377 0.0026882 +233 377 0.0080644973 +234 377 0.0014400999 +236 377 0.00028799986 +240 377 0.0026882 +241 377 0.0106567 +242 377 0.00096009998 +252 377 0.015648998 +270 377 0.0003839999 +272 377 0.0021120999 +273 377 9.5999989e-05 +274 377 0.006144397 +277 377 0.10608679 +282 377 0.0049922988 +283 377 0.00019199999 +284 377 0.00047999993 +285 377 9.5999989e-05 +292 377 0.0037441999 +293 377 0.011616699 +294 377 0.0012480998 +295 377 0.014208898 +296 377 0.0030721999 +297 377 0.00028799986 +298 377 0.0040322989 +304 377 0.00057599996 +307 377 9.5999989e-05 +312 377 0.010560699 +315 377 0.020929299 +319 377 0.0134409 +320 377 0.0019200998 +321 377 0.0049922988 +322 377 0.012384798 +324 377 0.0072004981 +326 377 0.0028801998 +328 377 0.00028799986 +339 377 0.00067199999 +340 377 0.0098885968 +341 377 0.00019199999 +350 377 0.00047999993 +351 377 0.0018240998 +352 377 0.0010560998 +354 377 0.0026882 +355 377 0.00028799986 +356 377 9.5999989e-05 +358 377 0.0015360999 +364 377 0.00028799986 +366 377 0.0094085969 +370 377 0.0050882995 +371 377 0.0076804981 +372 377 0.020545296 +373 377 0.0034561998 +377 377 0.012192797 +379 377 0.00019199999 +380 377 0.011808798 +385 377 0.00019199999 +386 377 0.016128998 +387 377 9.5999989e-05 +393 377 9.5999989e-05 +398 377 0.0045122989 +415 377 0.043106798 +417 377 0.0003839999 +419 377 0.022465397 +422 377 0.00019199999 +441 377 0.0032641999 +443 377 0.0045122989 +444 377 0.0018240998 +445 377 0.0071044974 +446 377 0.00019199999 +447 377 0.0038401999 +450 377 0.0028801998 +452 377 0.0050882995 +453 377 0.0034561998 +454 377 0.00086409994 +455 377 0.044546898 +456 377 9.5999989e-05 +457 377 0.0027841998 +458 377 0.00096009998 +459 377 0.00047999993 +460 377 0.00096009998 +463 377 0.016513098 +464 377 0.00057599996 +465 377 0.0016321 +467 377 0.0096005984 +468 377 0.020737298 +469 377 0.0042242967 +470 377 0.0045122989 +471 377 0.00096009998 +472 377 0.00096009998 +473 377 9.5999989e-05 +477 377 9.5999989e-05 +478 377 0.0010560998 +483 377 0.0019200998 +490 377 0.0003839999 +491 377 0.00086409994 +22 378 0.00048609986 +60 378 0.0012500999 +108 378 6.939999e-05 +114 378 0.0001389 +126 378 6.939999e-05 +131 378 0.0013889999 +150 378 0.0001389 +160 378 0.0024307 +171 378 6.939999e-05 +172 378 0.0019445999 +187 378 0.0014583999 +189 378 6.939999e-05 +190 378 6.939999e-05 +191 378 0.0010416999 +194 378 0.0001389 +198 378 0.014098197 +200 378 6.939999e-05 +203 378 6.939999e-05 +204 378 6.939999e-05 +206 378 0.00048609986 +214 378 0.0069448985 +219 378 0.0004166998 +223 378 0.0026391 +233 378 0.013889898 +234 378 0.0013194999 +236 378 0.00062499987 +237 378 6.939999e-05 +240 378 0.0092367977 +241 378 0.053059198 +242 378 0.0004166998 +252 378 0.0012500999 +270 378 0.00034719985 +272 378 0.0037502998 +274 378 0.0097922981 +277 378 0.068685293 +282 378 0.0038196999 +283 378 0.00055559981 +284 378 0.00048609986 +285 378 0.0001389 +286 378 6.939999e-05 +289 378 6.939999e-05 +292 378 0.012431398 +293 378 0.012084197 +294 378 0.00034719985 +295 378 0.012709197 +296 378 0.0013889999 +297 378 0.0004166998 +298 378 0.00034719985 +304 378 0.0015278999 +312 378 0.010278497 +315 378 0.0117369 +319 378 0.011875797 +320 378 0.0001389 +321 378 0.0068754964 +322 378 0.014237098 +324 378 0.0069448985 +326 378 0.0029862998 +328 378 0.0004166998 +338 378 6.939999e-05 +339 378 0.00055559981 +340 378 0.0004166998 +350 378 0.0084033981 +351 378 0.00083339983 +352 378 0.0037502998 +353 378 6.939999e-05 +354 378 0.0002083 +356 378 0.0001389 +358 378 0.0022918 +366 378 0.049934 +368 378 6.939999e-05 +370 378 0.0002083 +371 378 0.0077782981 +372 378 0.050628498 +373 378 0.0087505989 +376 378 0.0001389 +386 378 0.010834098 +387 378 6.939999e-05 +398 378 0.00055559981 +415 378 0.015278798 +417 378 0.00034719985 +419 378 0.00069449982 +421 378 6.939999e-05 +422 378 0.0001389 +441 378 0.00076389988 +442 378 6.939999e-05 +443 378 0.0043058991 +444 378 0.00034719985 +445 378 0.0078477971 +446 378 0.00034719985 +447 378 0.0026391 +450 378 0.0025001999 +452 378 0.0042363964 +453 378 0.0018751 +454 378 0.00090279989 +455 378 0.042364098 +456 378 0.0002083 +457 378 0.0027084998 +458 378 0.00048609986 +459 378 0.0004166998 +460 378 0.00090279989 +463 378 0.0099311993 +464 378 0.0004166998 +465 378 0.004166998 +467 378 0.0075699985 +468 378 0.015834399 +469 378 0.0031251998 +470 378 0.0031947 +471 378 0.0010416999 +473 378 6.939999e-05 +477 378 0.0001389 +478 378 0.00076389988 +483 378 0.0018056999 +490 378 0.00027779979 +491 378 0.00083339983 +22 379 0.0001526 +60 379 0.00091529987 +108 379 7.6299999e-05 +114 379 0.0001526 +126 379 7.6299999e-05 +150 379 7.6299999e-05 +160 379 0.00076279999 +169 379 0.00061019999 +172 379 0.0045766979 +187 379 7.6299999e-05 +190 379 7.6299999e-05 +194 379 0.0001526 +198 379 0.015484396 +206 379 0.00061019999 +214 379 0.00030509988 +219 379 0.00030509988 +223 379 0.00030509988 +224 379 7.6299999e-05 +233 379 0.0073988996 +234 379 0.00099159987 +236 379 0.0010678999 +240 379 0.012051899 +241 379 0.018916897 +242 379 0.0089244992 +252 379 7.6299999e-05 +270 379 0.002746 +271 379 7.6299999e-05 +272 379 0.0001526 +274 379 0.0001526 +277 379 0.099694848 +282 379 0.011060297 +283 379 0.00045769988 +284 379 0.00038139988 +285 379 7.6299999e-05 +292 379 0.002746 +293 379 0.0049579963 +294 379 0.0002288 +295 379 0.0045766979 +296 379 0.0050342977 +297 379 0.0002288 +298 379 0.013424899 +304 379 0.0002288 +312 379 0.013882499 +313 379 0.0001526 +315 379 0.018230397 +319 379 0.0021358 +320 379 0.0022121 +321 379 0.0028223 +322 379 0.0035849998 +324 379 0.0076277964 +326 379 7.6299999e-05 +328 379 0.00030509988 +339 379 0.00030509988 +340 379 0.0017543999 +341 379 0.0026697 +343 379 7.6299999e-05 +351 379 0.0034324999 +352 379 0.00061019999 +354 379 0.0086956993 +356 379 7.6299999e-05 +357 379 7.6299999e-05 +358 379 0.0025171998 +364 379 0.0042714998 +365 379 7.6299999e-05 +366 379 0.011517897 +371 379 0.00030509988 +372 379 0.071929753 +373 379 0.0025934 +377 379 0.0041189976 +379 379 0.0019069 +385 379 0.0019832 +386 379 0.00091529987 +387 379 7.6299999e-05 +397 379 7.6299999e-05 +398 379 0.0062547997 +402 379 0.00068649999 +415 379 0.025858097 +417 379 0.00030509988 +419 379 0.028298996 +421 379 7.6299999e-05 +422 379 0.0001526 +438 379 7.6299999e-05 +441 379 0.0039663985 +443 379 0.0029747998 +444 379 0.0028986 +445 379 0.0063309968 +446 379 0.00030509988 +447 379 0.0025171998 +450 379 0.0017543999 +452 379 0.004195299 +453 379 0.0026697 +454 379 0.00083909999 +455 379 0.036536999 +456 379 7.6299999e-05 +457 379 0.0025171998 +458 379 0.00030509988 +459 379 0.00061019999 +460 379 0.00076279999 +463 379 0.0092295967 +464 379 0.00053389999 +465 379 0.0011441999 +467 379 0.0064072981 +468 379 0.023188397 +469 379 0.0025934 +470 379 0.002746 +471 379 0.00099159987 +473 379 7.6299999e-05 +477 379 0.0001526 +478 379 0.00068649999 +483 379 0.0017543999 +490 379 0.0002288 +491 379 0.00083909999 +9 380 6.7199988e-05 +60 380 0.0046345964 +82 380 6.7199988e-05 +83 380 6.7199988e-05 +84 380 6.7199988e-05 +108 380 6.7199988e-05 +113 380 0.00013429999 +114 380 0.00013429999 +126 380 6.7199988e-05 +130 380 0.011015598 +131 380 0.0016792 +133 380 6.7199988e-05 +137 380 6.7199988e-05 +139 380 0.0058435984 +150 380 0.00080599985 +160 380 6.7199988e-05 +161 380 0.00013429999 +165 380 6.7199988e-05 +170 380 6.7199988e-05 +171 380 0.0090004988 +172 380 6.7199988e-05 +187 380 0.00013429999 +188 380 0.00013429999 +189 380 6.7199988e-05 +190 380 0.00013429999 +192 380 6.7199988e-05 +194 380 0.00013429999 +198 380 0.0190758 +200 380 6.7199988e-05 +203 380 6.7199988e-05 +204 380 0.00073889992 +206 380 0.00067169988 +207 380 6.7199988e-05 +214 380 0.00026869983 +219 380 6.7199988e-05 +223 380 0.0024180999 +224 380 0.019948997 +233 380 0.0032911999 +234 380 0.0017463998 +236 380 0.0003358 +237 380 6.7199988e-05 +240 380 0.0023508999 +241 380 0.036472298 +252 380 0.0065824986 +257 380 6.7199988e-05 +270 380 6.7199988e-05 +272 380 0.00080599985 +274 380 0.0021493998 +275 380 6.7199988e-05 +277 380 0.052659899 +279 380 6.7199988e-05 +282 380 0.0030896999 +284 380 0.00067169988 +285 380 0.00053729978 +286 380 6.7199988e-05 +292 380 0.0040972978 +293 380 0.016120397 +294 380 0.0089333989 +295 380 0.030359998 +296 380 0.0074556991 +298 380 0.0064480975 +299 380 0.00013429999 +301 380 6.7199988e-05 +304 380 6.7199988e-05 +307 380 0.00020149999 +312 380 0.011687297 +315 380 0.011082798 +319 380 0.005507797 +320 380 0.00040299981 +321 380 0.0039628968 +322 380 0.0028881999 +324 380 0.00040299981 +326 380 0.0034926999 +330 380 0.0010746999 +339 380 0.0003358 +340 380 0.0048360974 +350 380 0.00013429999 +351 380 0.00013429999 +352 380 6.7199988e-05 +353 380 6.7199988e-05 +354 380 0.00026869983 +355 380 0.00073889992 +356 380 0.00013429999 +358 380 0.0053734966 +366 380 0.00067169988 +370 380 0.0038285998 +371 380 0.0051047988 +372 380 0.026732899 +373 380 0.00047019986 +380 380 0.012627598 +384 380 6.7199988e-05 +386 380 0.0168592 +387 380 6.7199988e-05 +393 380 0.00020149999 +395 380 0.00060449983 +398 380 0.0017463998 +402 380 0.00020149999 +414 380 6.7199988e-05 +415 380 0.0070526972 +417 380 0.00060449983 +419 380 0.0029553999 +421 380 6.7199988e-05 +422 380 6.7199988e-05 +423 380 6.7199988e-05 +430 380 6.7199988e-05 +433 380 6.7199988e-05 +434 380 6.7199988e-05 +441 380 0.0030896999 +442 380 0.00080599985 +443 380 0.0031568999 +444 380 0.0003358 +445 380 0.0072541982 +446 380 0.00013429999 +447 380 0.0023508999 +450 380 0.0032241 +452 380 0.0053062998 +453 380 0.0018806998 +454 380 0.00060449983 +455 380 0.040032197 +456 380 0.00020149999 +457 380 0.0028210999 +458 380 0.00060449983 +459 380 0.00040299981 +460 380 0.0010746999 +463 380 0.018941399 +464 380 0.0003358 +465 380 0.0016792 +467 380 0.011149898 +468 380 0.032442197 +469 380 0.0051719993 +470 380 0.005507797 +471 380 0.0008731999 +473 380 0.00013429999 +477 380 0.00013429999 +478 380 0.0011419 +479 380 0.0008731999 +483 380 0.002015 +490 380 0.00047019986 +491 380 0.0018806998 +60 381 0.0037928999 +114 381 0.0002231 +126 381 0.0002231 +130 381 0.00044619991 +139 381 0.0002231 +160 381 0.0002231 +171 381 0.00044619991 +172 381 0.0002231 +193 381 0.0017849 +198 381 0.0182954 +206 381 0.00089249993 +214 381 0.0053547993 +219 381 0.0002231 +223 381 0.00044619991 +224 381 0.016287398 +233 381 0.0071396977 +234 381 0.00066929986 +236 381 0.0002231 +240 381 0.0046853982 +241 381 0.026550598 +242 381 0.016733598 +252 381 0.0002231 +271 381 0.00044619991 +272 381 0.0037928999 +274 381 0.00066929986 +277 381 0.031905398 +279 381 0.00089249993 +282 381 0.010263298 +283 381 0.0013386998 +284 381 0.00044619991 +292 381 0.0037928999 +293 381 0.0080320984 +294 381 0.00044619991 +295 381 0.034359697 +296 381 0.022757698 +298 381 0.0002231 +312 381 0.010040198 +313 381 0.00066929986 +315 381 0.025211997 +319 381 0.0080320984 +320 381 0.0002231 +321 381 0.00066929986 +322 381 0.0078089982 +324 381 0.0040160976 +326 381 0.00044619991 +340 381 0.004462298 +349 381 0.0031235998 +350 381 0.00044619991 +351 381 0.0024542999 +352 381 0.0002231 +356 381 0.0037928999 +357 381 0.00044619991 +358 381 0.0031235998 +366 381 0.0026773999 +370 381 0.004462298 +371 381 0.0066933967 +372 381 0.017849199 +373 381 0.0002231 +380 381 0.00066929986 +381 381 0.00044619991 +386 381 0.010709498 +390 381 0.00066929986 +392 381 0.00044619991 +393 381 0.0011155999 +397 381 0.0002231 +398 381 0.0060240999 +402 381 0.0026773999 +415 381 0.0011155999 +417 381 0.00044619991 +419 381 0.00066929986 +438 381 0.0095938966 +441 381 0.0093707964 +443 381 0.0022310999 +444 381 0.0020079999 +445 381 0.007585898 +447 381 0.010932598 +450 381 0.0026773999 +452 381 0.004462298 +453 381 0.0017849 +454 381 0.00089249993 +455 381 0.0305667 +457 381 0.0026773999 +459 381 0.00044619991 +460 381 0.00089249993 +463 381 0.0122713 +464 381 0.00044619991 +465 381 0.0013386998 +467 381 0.0084783994 +468 381 0.0276662 +469 381 0.0051315986 +470 381 0.0055778995 +471 381 0.0015617998 +473 381 0.0002231 +477 381 0.0002231 +478 381 0.00066929986 +479 381 0.0013386998 +483 381 0.0015617998 +490 381 0.00066929986 +491 381 0.0020079999 +60 382 0.0077120997 +114 382 0.00064269989 +172 382 0.0012852999 +198 382 0.0032133998 +206 382 0.0012852999 +234 382 0.0038559998 +241 382 0.00064269989 +242 382 0.0102828 +272 382 0.0044986978 +277 382 0.023136199 +282 382 0.014781497 +284 382 0.00064269989 +292 382 0.0025706999 +293 382 0.0032133998 +295 382 0.034061696 +296 382 0.00064269989 +307 382 0.00064269989 +312 382 0.0044986978 +315 382 0.0064266995 +319 382 0.0038559998 +322 382 0.0032133998 +340 382 0.0025706999 +344 382 0.0019279998 +351 382 0.00064269989 +354 382 0.00064269989 +358 382 0.025706898 +371 382 0.00064269989 +372 382 0.0025706999 +373 382 0.00064269989 +382 382 0.082262158 +386 382 0.0012852999 +417 382 0.00064269989 +441 382 0.0044986978 +444 382 0.00064269989 +445 382 0.0012852999 +447 382 0.012210798 +450 382 0.0032133998 +452 382 0.0064266995 +453 382 0.00064269989 +454 382 0.0019279998 +455 382 0.025706898 +457 382 0.0032133998 +459 382 0.00064269989 +460 382 0.00064269989 +463 382 0.031490996 +464 382 0.00064269989 +465 382 0.0019279998 +467 382 0.014138799 +468 382 0.084832847 +469 382 0.0044986978 +470 382 0.0051413998 +478 382 0.0012852999 +483 382 0.0025706999 +490 382 0.00064269989 +491 382 0.0070693977 +22 383 0.00011879999 +60 383 0.0009500999 +108 383 0.00011879999 +114 383 0.00023749999 +126 383 0.00011879999 +130 383 0.00011879999 +131 383 0.00011879999 +135 383 0.00011879999 +139 383 0.00011879999 +160 383 0.00023749999 +161 383 0.0032066999 +171 383 0.00011879999 +172 383 0.0003562998 +182 383 0.0030878999 +193 383 0.00011879999 +194 383 0.00011879999 +198 383 0.015439399 +206 383 0.00071259984 +214 383 0.0040379986 +223 383 0.0065320991 +224 383 0.0089073963 +233 383 0.009263698 +234 383 0.0009500999 +236 383 0.0003562998 +240 383 0.0089073963 +241 383 0.0108076 +242 383 0.0045130998 +252 383 0.0021378 +270 383 0.0038005 +272 383 0.0043942966 +274 383 0.0047505982 +275 383 0.00011879999 +277 383 0.10558188 +282 383 0.0061757974 +283 383 0.00011879999 +284 383 0.0003562998 +292 383 0.0071258992 +293 383 0.0041567981 +294 383 0.0016627 +295 383 0.011045098 +296 383 0.0046317987 +297 383 0.00023749999 +298 383 0.0074821971 +300 383 0.00011879999 +304 383 0.00023749999 +307 383 0.00023749999 +312 383 0.017695997 +315 383 0.011757698 +319 383 0.0097386986 +320 383 0.0038005 +321 383 0.0065320991 +322 383 0.0061757974 +324 383 0.0081947967 +326 383 0.0058194995 +328 383 0.00023749999 +340 383 0.0059381984 +341 383 0.00011879999 +349 383 0.00011879999 +350 383 0.0003562998 +351 383 0.0047505982 +352 383 0.00083139981 +354 383 0.00071259984 +355 383 0.0009500999 +356 383 0.00023749999 +358 383 0.0019001998 +364 383 0.00011879999 +366 383 0.006650798 +370 383 0.00059379986 +371 383 0.0072446987 +372 383 0.040973898 +373 383 0.0026127999 +377 383 0.00059379986 +379 383 0.00011879999 +380 383 0.0102138 +383 383 0.00011879999 +385 383 0.00011879999 +386 383 0.019477397 +387 383 0.00011879999 +393 383 0.00023749999 +398 383 0.00059379986 +414 383 0.00011879999 +415 383 0.032066498 +417 383 0.00023749999 +419 383 0.0052256994 +438 383 0.0032066999 +441 383 0.0027315998 +443 383 0.0039191991 +444 383 0.0046317987 +445 383 0.0070070997 +446 383 0.00011879999 +447 383 0.0053443983 +450 383 0.0024940998 +452 383 0.0039191991 +453 383 0.0028503998 +454 383 0.0011876 +455 383 0.040142499 +457 383 0.0026127999 +458 383 0.00059379986 +459 383 0.0003562998 +460 383 0.00083139981 +463 383 0.015676998 +464 383 0.00047509978 +465 383 0.0010688999 +467 383 0.0077196993 +468 383 0.019833699 +469 383 0.0041567981 +470 383 0.0043942966 +471 383 0.00059379986 +473 383 0.00011879999 +477 383 0.00011879999 +478 383 0.00059379986 +479 383 0.00047509978 +483 383 0.0021378 +490 383 0.0003562998 +491 383 0.0010688999 +18 384 9.3799987e-05 +60 384 0.0019689 +108 384 9.3799987e-05 +114 384 0.00018749999 +126 384 9.3799987e-05 +150 384 9.3799987e-05 +151 384 9.3799987e-05 +190 384 9.3799987e-05 +194 384 0.00018749999 +198 384 0.0235327 +200 384 9.3799987e-05 +203 384 9.3799987e-05 +204 384 9.3799987e-05 +206 384 0.00018749999 +214 384 0.024282798 +219 384 0.00018749999 +223 384 9.3799987e-05 +224 384 0.00018749999 +233 384 0.00065629999 +234 384 0.0021563999 +237 384 9.3799987e-05 +240 384 9.3799987e-05 +241 384 0.0012188 +252 384 0.073504567 +270 384 9.3799987e-05 +271 384 0.00018749999 +277 384 0.0030001998 +282 384 0.0021563999 +283 384 0.00084379991 +284 384 0.00037499983 +290 384 0.00018749999 +292 384 0.0050627999 +293 384 9.3799987e-05 +294 384 0.019032396 +295 384 0.00028129993 +296 384 0.00056249998 +312 384 0.00046879984 +313 384 0.00037499983 +315 384 0.00018749999 +320 384 0.00018749999 +340 384 0.0018751 +351 384 0.00018749999 +357 384 0.00018749999 +358 384 0.0013126 +370 384 0.00037499983 +384 384 0.00046879984 +385 384 0.0033751999 +386 384 0.00028129993 +387 384 9.3799987e-05 +389 384 0.00084379991 +390 384 0.00018749999 +392 384 0.00037499983 +393 384 0.0027188999 +397 384 0.00018749999 +398 384 0.11110067 +402 384 0.0016875998 +417 384 0.00037499983 +421 384 9.3799987e-05 +422 384 0.00018749999 +443 384 0.0015937998 +444 384 0.0045939982 +445 384 0.0058128983 +446 384 0.00084379991 +447 384 0.0058128983 +450 384 0.004031498 +452 384 0.0059065968 +453 384 0.0029063998 +454 384 0.00074999989 +455 384 0.029251799 +456 384 0.00018749999 +457 384 0.0029063998 +458 384 0.00056249998 +459 384 0.00037499983 +460 384 0.0010312998 +463 384 0.0041252971 +464 384 0.00046879984 +465 384 0.0015937998 +467 384 0.011531997 +468 384 0.010031898 +469 384 0.0032815 +470 384 0.0037501999 +471 384 0.0039376989 +473 384 9.3799987e-05 +477 384 0.00018749999 +478 384 0.0012188 +483 384 0.00065629999 +490 384 0.00037499983 +491 384 0.0012188 +18 385 0.00012879999 +21 385 4.2899992e-05 +22 385 0.00034359982 +24 385 4.2899992e-05 +60 385 0.0015031998 +82 385 4.2899992e-05 +108 385 0.0001718 +114 385 0.00034359982 +126 385 0.0001718 +130 385 0.0043806992 +131 385 0.0014173 +138 385 4.2899992e-05 +139 385 4.2899992e-05 +142 385 4.2899992e-05 +150 385 0.00060129981 +151 385 4.2899992e-05 +156 385 0.0013742999 +160 385 0.0019755999 +161 385 0.0012883998 +171 385 0.0026197999 +187 385 8.5899999e-05 +188 385 0.00012879999 +190 385 8.5899999e-05 +194 385 0.00012879999 +197 385 4.2899992e-05 +198 385 0.020314399 +200 385 8.5899999e-05 +201 385 4.2899992e-05 +203 385 8.5899999e-05 +204 385 0.00012879999 +206 385 0.0001718 +207 385 4.2899992e-05 +214 385 0.0042088963 +219 385 4.2899992e-05 +223 385 0.00068719988 +224 385 0.010693997 +225 385 4.2899992e-05 +227 385 4.2899992e-05 +229 385 4.2899992e-05 +233 385 0.0054972991 +234 385 0.0018038 +237 385 0.00012879999 +240 385 0.00098779984 +241 385 0.038008898 +242 385 4.2899992e-05 +243 385 4.2899992e-05 +252 385 0.032597497 +254 385 0.00012879999 +262 385 8.5899999e-05 +263 385 0.00085899979 +265 385 4.2899992e-05 +266 385 4.2899992e-05 +270 385 0.0009019 +271 385 4.2899992e-05 +272 385 0.0020615 +276 385 4.2899992e-05 +277 385 0.048058797 +282 385 0.0055402964 +283 385 0.00012879999 +284 385 0.00042949989 +286 385 4.2899992e-05 +288 385 0.0012454998 +289 385 0.0014601999 +290 385 0.00030059996 +292 385 0.0038653 +293 385 0.016062498 +294 385 0.00064419978 +295 385 0.0085465983 +296 385 0.01151 +297 385 0.0011165999 +298 385 0.0033069998 +300 385 4.2899992e-05 +312 385 0.011037599 +315 385 0.032683399 +317 385 4.2899992e-05 +319 385 0.00012879999 +320 385 0.010865796 +321 385 0.00025769998 +322 385 0.0024909999 +324 385 0.00012879999 +326 385 0.00060129981 +328 385 0.00021469999 +329 385 8.5899999e-05 +339 385 0.0001718 +340 385 0.0073440969 +350 385 4.2899992e-05 +351 385 0.00012879999 +352 385 4.2899992e-05 +354 385 0.00012879999 +356 385 0.00012879999 +358 385 0.0018896998 +366 385 0.00047239987 +370 385 0.050764497 +371 385 4.2899992e-05 +372 385 0.00047239987 +373 385 0.00034359982 +375 385 4.2899992e-05 +376 385 0.0014173 +384 385 0.017823398 +385 385 0.015203599 +386 385 0.023621399 +387 385 0.0001718 +392 385 0.0003864998 +393 385 0.0027486999 +395 385 0.00012879999 +397 385 0.00021469999 +398 385 0.0015890999 +402 385 0.00012879999 +415 385 4.2899992e-05 +416 385 4.2899992e-05 +417 385 0.00051539997 +419 385 4.2899992e-05 +421 385 4.2899992e-05 +422 385 0.00012879999 +427 385 4.2899992e-05 +430 385 0.00021469999 +433 385 4.2899992e-05 +434 385 4.2899992e-05 +442 385 4.2899992e-05 +443 385 0.0033928999 +444 385 0.0044235997 +445 385 0.0068286993 +446 385 0.00012879999 +447 385 0.0049389973 +450 385 0.0042517968 +452 385 0.0048101991 +453 385 0.0021902998 +454 385 0.00064419978 +455 385 0.043978699 +456 385 0.00012879999 +457 385 0.0030922999 +458 385 0.00081599993 +459 385 0.0003864998 +460 385 0.00073009985 +463 385 0.018038098 +464 385 0.0056261979 +465 385 0.0017608998 +467 385 0.012583699 +468 385 0.0066998973 +469 385 0.0054972991 +470 385 0.0060985982 +471 385 0.0055831969 +473 385 0.0001718 +477 385 0.00030059996 +478 385 0.0012454998 +479 385 0.0011596 +483 385 0.00085899979 +489 385 4.2899992e-05 +490 385 0.00060129981 +491 385 0.00068719988 +9 386 4.7999987e-05 +18 386 0.00014389999 +19 386 0.0003837999 +21 386 0.00014389999 +22 386 0.0004317998 +24 386 0.0003358 +60 386 0.0022546998 +82 386 0.00014389999 +83 386 4.7999987e-05 +84 386 4.7999987e-05 +108 386 9.5899988e-05 +113 386 9.5899988e-05 +114 386 0.00019189999 +117 386 4.7999987e-05 +126 386 9.5899988e-05 +130 386 0.00023989999 +131 386 0.00019189999 +135 386 0.00019189999 +138 386 0.00014389999 +139 386 4.7999987e-05 +142 386 9.5899988e-05 +150 386 0.00062369998 +160 386 9.5899988e-05 +169 386 9.5899988e-05 +175 386 4.7999987e-05 +187 386 0.0010074 +188 386 9.5899988e-05 +189 386 9.5899988e-05 +190 386 9.5899988e-05 +192 386 0.00028779986 +193 386 9.5899988e-05 +194 386 0.00023989999 +197 386 4.7999987e-05 +198 386 0.0086351968 +200 386 9.5899988e-05 +201 386 4.7999987e-05 +203 386 9.5899988e-05 +204 386 9.5899988e-05 +206 386 0.00019189999 +207 386 4.7999987e-05 +214 386 0.0031661999 +219 386 9.5899988e-05 +223 386 0.0045573972 +224 386 0.011177696 +229 386 4.7999987e-05 +233 386 0.00062369998 +234 386 0.0025425998 +237 386 9.5899988e-05 +240 386 0.0038378998 +241 386 0.015831098 +242 386 4.7999987e-05 +252 386 0.0012472998 +262 386 0.0047013983 +270 386 4.7999987e-05 +271 386 9.5899988e-05 +273 386 0.00019189999 +276 386 9.5899988e-05 +277 386 0.079827249 +278 386 0.00014389999 +282 386 0.0047492981 +283 386 0.0003837999 +284 386 0.00057569984 +285 386 0.00019189999 +286 386 0.0051810965 +288 386 0.0039817989 +289 386 0.0030703 +290 386 0.0010074 +292 386 0.026720997 +293 386 0.0096905977 +294 386 0.017270297 +295 386 0.014056098 +296 386 0.0062844977 +297 386 0.0029742999 +298 386 0.00028779986 +300 386 9.5899988e-05 +308 386 0.00023989999 +312 386 0.015159499 +313 386 9.5899988e-05 +315 386 0.0096425973 +317 386 0.0023987 +320 386 0.009018898 +321 386 0.0060925968 +322 386 0.0039817989 +324 386 0.00023989999 +325 386 4.7999987e-05 +326 386 0.00057569984 +328 386 0.00023989999 +339 386 0.00028779986 +340 386 0.0066682994 +343 386 4.7999987e-05 +349 386 4.7999987e-05 +350 386 9.5899988e-05 +351 386 0.00028779986 +352 386 0.00057569984 +353 386 4.7999987e-05 +354 386 0.00062369998 +355 386 4.7999987e-05 +356 386 9.5899988e-05 +357 386 4.7999987e-05 +358 386 0.004941199 +359 386 4.7999987e-05 +369 386 0.0003358 +370 386 0.0013911999 +371 386 0.0003837999 +372 386 0.00086349994 +373 386 0.0022067998 +374 386 4.7999987e-05 +375 386 0.00014389999 +376 386 0.00023989999 +384 386 0.00014389999 +385 386 0.00023989999 +386 386 0.026049398 +387 386 9.5899988e-05 +389 386 0.0016311 +390 386 0.0004317998 +391 386 9.5899988e-05 +392 386 0.0037898999 +393 386 0.0088749975 +396 386 4.7999987e-05 +397 386 9.5899988e-05 +398 386 0.0013432 +402 386 0.00052769994 +414 386 4.7999987e-05 +416 386 0.00014389999 +417 386 0.00067159999 +419 386 9.5899988e-05 +420 386 0.00019189999 +421 386 4.7999987e-05 +422 386 0.00095949997 +423 386 4.7999987e-05 +430 386 9.5899988e-05 +431 386 4.7999987e-05 +433 386 4.7999987e-05 +434 386 4.7999987e-05 +438 386 9.5899988e-05 +441 386 4.7999987e-05 +442 386 4.7999987e-05 +443 386 0.0039337985 +444 386 0.00067159999 +445 386 0.0075317994 +446 386 0.00023989999 +447 386 0.0032621999 +450 386 0.0048452988 +452 386 0.0067161992 +453 386 0.0017749998 +454 386 0.00076759979 +455 386 0.023986597 +456 386 0.0003358 +457 386 0.0031182999 +458 386 0.00081549981 +459 386 0.00071959989 +460 386 0.0010553999 +463 386 0.0118494 +464 386 0.0010074 +465 386 0.0024465998 +467 386 0.014343999 +468 386 0.0023027 +469 386 0.0067161992 +470 386 0.0076276995 +471 386 0.0019669 +473 386 0.00014389999 +477 386 0.00023989999 +478 386 0.0015350999 +479 386 9.5899988e-05 +483 386 0.0012953 +489 386 4.7999987e-05 +490 386 0.00071959989 +491 386 0.0033100999 +9 387 2.6799986e-05 +18 387 8.0299986e-05 +22 387 2.6799986e-05 +60 387 0.0019816 +82 387 2.6799986e-05 +83 387 2.6799986e-05 +84 387 2.6799986e-05 +108 387 2.6799986e-05 +113 387 5.3599986e-05 +114 387 0.00010709999 +126 387 5.3599986e-05 +150 387 0.00037489994 +151 387 2.6799986e-05 +160 387 0.0013388998 +169 387 0.00091049983 +172 387 0.0014727998 +174 387 0.016522497 +175 387 0.061778598 +177 387 0.0016335 +187 387 0.0022761999 +188 387 0.00072299992 +189 387 5.3599986e-05 +190 387 8.0299986e-05 +192 387 0.00010709999 +194 387 8.0299986e-05 +197 387 2.6799986e-05 +198 387 0.0073641986 +200 387 8.0299986e-05 +201 387 2.6799986e-05 +203 387 5.3599986e-05 +204 387 8.0299986e-05 +206 387 0.0026510998 +207 387 5.3599986e-05 +209 387 2.6799986e-05 +214 387 5.3599986e-05 +219 387 5.3599986e-05 +223 387 2.6799986e-05 +224 387 0.0023832999 +234 387 0.00091049983 +236 387 2.6799986e-05 +237 387 5.3599986e-05 +240 387 0.00085689989 +241 387 0.013309099 +252 387 0.0077390969 +262 387 2.6799986e-05 +276 387 2.6799986e-05 +277 387 0.0064536966 +279 387 0.00085689989 +282 387 5.3599986e-05 +283 387 2.6799986e-05 +284 387 0.00013389999 +285 387 0.00064269989 +292 387 5.3599986e-05 +293 387 0.00077659986 +294 387 8.0299986e-05 +295 387 0.0080871992 +296 387 0.00069619995 +298 387 0.00091049983 +312 387 0.0068285987 +315 387 0.020914197 +318 387 8.0299986e-05 +319 387 0.0027047 +320 387 0.0014193 +321 387 5.3599986e-05 +326 387 0.0025974999 +340 387 0.00066949986 +356 387 0.00013389999 +358 387 0.00042849989 +359 387 0.00026779994 +364 387 0.00061589992 +369 387 0.00010709999 +372 387 0.0033741 +382 387 0.00077659986 +384 387 2.6799986e-05 +386 387 0.011113197 +387 387 0.045898799 +390 387 0.00024099999 +391 387 0.14615858 +392 387 0.020619698 +393 387 0.13927639 +396 387 0.00083009992 +402 387 5.3599986e-05 +404 387 2.6799986e-05 +417 387 0.00026779994 +419 387 0.0017674 +421 387 2.6799986e-05 +422 387 0.00013389999 +423 387 2.6799986e-05 +425 387 2.6799986e-05 +430 387 2.6799986e-05 +431 387 2.6799986e-05 +432 387 2.6799986e-05 +433 387 2.6799986e-05 +434 387 0.00016069999 +441 387 0.00064269989 +443 387 0.0016870999 +444 387 0.0013122 +445 387 0.0038560999 +446 387 8.0299986e-05 +447 387 0.0038293998 +450 387 0.0050343983 +452 387 0.0023029998 +453 387 0.00053559989 +454 387 0.00080339983 +455 387 0.0396326 +456 387 0.00013389999 +457 387 0.0048736967 +458 387 0.00056239986 +459 387 0.0021422999 +460 387 0.00091049983 +463 387 0.0103634 +464 387 0.0026778998 +465 387 0.028385498 +467 387 0.0137375 +468 387 0.027769599 +469 387 0.0032402 +470 387 0.0035883998 +471 387 0.0027313998 +473 387 8.0299986e-05 +477 387 0.00058909995 +478 387 0.0010443998 +483 387 0.00096399989 +489 387 2.6799986e-05 +490 387 0.00032129977 +491 387 0.0012585998 +60 388 0.0014654999 +108 388 0.0001832 +114 388 0.0003664 +126 388 0.0001832 +160 388 0.00073269987 +187 388 0.012456499 +190 388 0.0001832 +194 388 0.0003664 +198 388 0.0031140998 +200 388 0.0001832 +204 388 0.084814072 +206 388 0.0003664 +214 388 0.0003664 +224 388 0.050192297 +234 388 0.0025646 +237 388 0.0001832 +241 388 0.020882897 +272 388 0.00054959999 +279 388 0.0001832 +284 388 0.0001832 +293 388 0.0047627985 +317 388 0.0001832 +356 388 0.0001832 +387 388 0.0032972998 +388 388 0.043780897 +390 388 0.0001832 +392 388 0.0001832 +393 388 0.031873997 +417 388 0.0003664 +422 388 0.0003664 +443 388 0.002015 +444 388 0.0060450993 +445 388 0.0137388 +446 388 0.0001832 +447 388 0.0089759976 +450 388 0.0065945983 +452 388 0.0071441978 +453 388 0.0029308998 +454 388 0.00054959999 +455 388 0.040849999 +457 388 0.0047627985 +458 388 0.0014654999 +459 388 0.00054959999 +460 388 0.00073269987 +463 388 0.11705434 +464 388 0.00091589987 +465 388 0.012456499 +467 388 0.056970097 +468 388 0.045429599 +469 388 0.0056786984 +470 388 0.0064113997 +471 388 0.00073269987 +473 388 0.0038468998 +477 388 0.0001832 +478 388 0.0018318 +483 388 0.00073269987 +490 388 0.00054959999 +491 388 0.00091589987 +9 389 2.3799992e-05 +16 389 2.3799992e-05 +18 389 0.00011899999 +22 389 9.5199997e-05 +60 389 0.0026900999 +79 389 2.3799992e-05 +82 389 2.3799992e-05 +83 389 2.3799992e-05 +84 389 2.3799992e-05 +108 389 4.7599999e-05 +113 389 7.1399991e-05 +114 389 0.0001428 +126 389 7.1399991e-05 +127 389 2.3799992e-05 +132 389 2.3799992e-05 +150 389 0.00049989996 +160 389 0.00042849989 +169 389 0.00021429999 +171 389 4.7599999e-05 +172 389 0.0015711999 +189 389 7.1399991e-05 +190 389 9.5199997e-05 +192 389 4.7599999e-05 +194 389 0.0017139998 +196 389 2.3799992e-05 +197 389 2.3799992e-05 +198 389 0.0019520998 +200 389 9.5199997e-05 +201 389 4.7599999e-05 +203 389 7.1399991e-05 +204 389 0.00011899999 +206 389 9.5199997e-05 +207 389 7.1399991e-05 +209 389 2.3799992e-05 +214 389 7.1399991e-05 +219 389 0.0014759998 +223 389 0.0011188998 +224 389 0.0049278997 +225 389 2.3799992e-05 +233 389 0.0022139999 +234 389 0.0010950998 +237 389 9.5199997e-05 +240 389 0.0010237 +241 389 0.0034280999 +248 389 2.3799992e-05 +250 389 2.3799992e-05 +252 389 0.0012616999 +263 389 2.3799992e-05 +270 389 0.0012379 +277 389 0.013378996 +279 389 4.7599999e-05 +284 389 0.00019039999 +285 389 0.0020234999 +286 389 0.00054749986 +287 389 2.3799992e-05 +289 389 4.7599999e-05 +290 389 0.022639599 +292 389 0.011093698 +293 389 0.0020234999 +294 389 0.0103557 +295 389 0.011450697 +296 389 0.0024758 +298 389 0.00052369991 +312 389 0.0042850971 +315 389 0.0036185 +317 389 0.0018092999 +318 389 2.3799992e-05 +319 389 0.0015473999 +320 389 0.0050468966 +321 389 0.0019997 +322 389 0.0030947998 +326 389 0.0036422999 +338 389 0.00035709981 +339 389 0.00011899999 +340 389 0.0029757998 +341 389 2.3799992e-05 +343 389 2.3799992e-05 +351 389 0.00052369991 +354 389 2.3799992e-05 +356 389 0.00011899999 +358 389 0.0041898973 +359 389 2.3799992e-05 +369 389 0.00011899999 +375 389 0.00011899999 +384 389 4.7599999e-05 +386 389 0.016640499 +387 389 7.1399991e-05 +389 389 0.10936528 +390 389 0.022092097 +391 389 0.0041660964 +392 389 0.049350098 +393 389 0.059015397 +396 389 0.0006903999 +398 389 0.0010237 +402 389 4.7599999e-05 +417 389 0.00038089999 +419 389 2.3799992e-05 +421 389 4.7599999e-05 +422 389 9.5199997e-05 +423 389 2.3799992e-05 +425 389 2.3799992e-05 +430 389 4.7599999e-05 +431 389 4.7599999e-05 +432 389 2.3799992e-05 +433 389 4.7599999e-05 +434 389 4.7599999e-05 +443 389 0.0014283999 +444 389 0.0034280999 +445 389 0.0037613998 +446 389 7.1399991e-05 +447 389 0.0054277964 +449 389 2.3799992e-05 +450 389 0.0065704994 +452 389 0.0034995 +453 389 0.0013807998 +454 389 0.00047609978 +455 389 0.017949797 +456 389 0.00052369991 +457 389 0.0039041999 +458 389 0.00083319983 +459 389 0.0016663999 +460 389 0.0011188998 +463 389 0.009760499 +464 389 0.0086415969 +465 389 0.0024995999 +467 389 0.017640296 +468 389 0.0029281999 +469 389 0.0063799992 +470 389 0.0071655996 +471 389 0.0029519999 +472 389 0.00047609978 +473 389 0.00016659999 +477 389 0.0001428 +478 389 0.0014521999 +479 389 0.0010237 +483 389 0.0010950998 +489 389 2.3799992e-05 +490 389 0.00059519988 +491 389 0.00045229984 +9 390 6.6099994e-05 +16 390 3.309999e-05 +17 390 1.0999999e-05 +18 390 9.9199999e-05 +22 390 3.309999e-05 +60 390 0.0021483998 +76 390 0.00016529999 +77 390 0.0004296999 +79 390 2.1999993e-05 +81 390 1.0999999e-05 +82 390 0.0001102 +83 390 6.6099994e-05 +84 390 6.6099994e-05 +108 390 0.00012119999 +113 390 0.00017629999 +114 390 0.00044069998 +126 390 0.00018729999 +127 390 3.309999e-05 +130 390 7.709999e-05 +131 390 3.309999e-05 +138 390 1.0999999e-05 +139 390 1.0999999e-05 +142 390 1.0999999e-05 +150 390 0.00060599996 +151 390 1.0999999e-05 +156 390 1.0999999e-05 +160 390 0.0005398998 +161 390 1.0999999e-05 +165 390 2.1999993e-05 +169 390 4.4099987e-05 +171 390 8.8099987e-05 +172 390 0.00044069998 +174 390 7.709999e-05 +175 390 0.00057289982 +177 390 1.0999999e-05 +181 390 1.0999999e-05 +187 390 9.9199999e-05 +188 390 1.0999999e-05 +189 390 0.0002424 +190 390 0.0001102 +192 390 7.709999e-05 +193 390 8.8099987e-05 +194 390 0.0001102 +196 390 2.1999993e-05 +197 390 3.309999e-05 +198 390 0.0016635999 +200 390 0.00012119999 +201 390 7.709999e-05 +203 390 8.8099987e-05 +204 390 0.00013219999 +206 390 0.002534 +207 390 5.5099998e-05 +209 390 2.1999993e-05 +214 390 0.00059489999 +219 390 3.309999e-05 +220 390 4.4099987e-05 +223 390 7.709999e-05 +224 390 0.00091439998 +225 390 1.0999999e-05 +229 390 1.0999999e-05 +233 390 9.9199999e-05 +234 390 0.0016305998 +237 390 8.8099987e-05 +240 390 0.0014322998 +241 390 0.004561197 +248 390 7.709999e-05 +250 390 4.4099987e-05 +251 390 1.0999999e-05 +252 390 0.0016415999 +262 390 5.5099998e-05 +263 390 1.0999999e-05 +270 390 0.00064999983 +272 390 3.309999e-05 +276 390 0.00012119999 +277 390 0.0080426969 +279 390 5.5099998e-05 +282 390 0.00057289982 +283 390 0.0001542 +284 390 0.00022029999 +285 390 0.00035259989 +286 390 5.5099998e-05 +289 390 5.5099998e-05 +290 390 0.0011788998 +292 390 0.0013330998 +293 390 0.0040653981 +294 390 0.00059489999 +295 390 0.0043738969 +296 390 0.0029195999 +297 390 0.00023139999 +298 390 0.0007821999 +299 390 9.9199999e-05 +300 390 1.0999999e-05 +305 390 0.00085939979 +307 390 1.0999999e-05 +308 390 0.00057289982 +312 390 0.0066985972 +313 390 1.0999999e-05 +315 390 0.008946199 +317 390 0.00067209988 +318 390 7.709999e-05 +319 390 0.00022029999 +320 390 0.0055307969 +321 390 0.0014101998 +322 390 0.0018068999 +324 390 3.309999e-05 +325 390 1.0999999e-05 +326 390 0.0021153998 +328 390 2.1999993e-05 +338 390 0.00023139999 +339 390 6.6099994e-05 +340 390 0.0052442998 +341 390 3.309999e-05 +344 390 1.0999999e-05 +349 390 0.00052879984 +350 390 4.4099987e-05 +351 390 0.00012119999 +353 390 1.0999999e-05 +354 390 0.0001432 +356 390 0.00012119999 +358 390 0.0034924999 +359 390 0.001862 +362 390 1.0999999e-05 +363 390 1.0999999e-05 +366 390 1.0999999e-05 +369 390 0.0072053969 +370 390 0.0016196 +371 390 7.709999e-05 +372 390 0.0024788999 +373 390 0.0001542 +375 390 3.309999e-05 +376 390 2.1999993e-05 +380 390 5.5099998e-05 +384 390 0.0002424 +385 390 0.00064999983 +386 390 0.0070070997 +387 390 0.0016525998 +389 390 0.0012339999 +390 390 0.060651097 +391 390 0.0086596981 +392 390 0.044598699 +393 390 0.097140968 +394 390 1.0999999e-05 +396 390 0.00016529999 +397 390 0.00017629999 +398 390 0.00040759984 +401 390 2.1999993e-05 +402 390 0.0001102 +403 390 2.1999993e-05 +404 390 0.00047379988 +405 390 0.0017186999 +413 390 0.00013219999 +414 390 6.6099994e-05 +415 390 1.0999999e-05 +416 390 1.0999999e-05 +417 390 0.00041869981 +419 390 0.00090339989 +420 390 0.00031949999 +421 390 5.5099998e-05 +422 390 0.00027539977 +423 390 4.4099987e-05 +424 390 1.0999999e-05 +425 390 3.309999e-05 +427 390 8.8099987e-05 +430 390 0.0001102 +431 390 3.309999e-05 +432 390 2.1999993e-05 +433 390 4.4099987e-05 +434 390 0.0001102 +438 390 1.0999999e-05 +441 390 1.0999999e-05 +442 390 2.1999993e-05 +443 390 0.00081529981 +444 390 0.0021153998 +445 390 0.0025670999 +446 390 0.00016529999 +447 390 0.0047044978 +448 390 1.0999999e-05 +449 390 3.309999e-05 +450 390 0.0062027983 +452 390 0.0053324997 +453 390 0.00067209988 +454 390 0.00029749982 +455 390 0.021197598 +456 390 0.0015203999 +457 390 0.0025781 +458 390 0.00082629989 +459 390 0.0011127999 +460 390 0.00095849996 +463 390 0.013419297 +464 390 0.0042196997 +465 390 0.0031399999 +467 390 0.022078998 +468 390 0.0022695998 +469 390 0.012174297 +470 390 0.020228099 +471 390 0.0028535 +472 390 0.0001102 +473 390 0.00045169983 +477 390 0.00012119999 +478 390 0.0020603 +479 390 3.309999e-05 +483 390 0.0034043998 +489 390 3.309999e-05 +490 390 0.0017296998 +491 390 0.0001432 +18 391 0.00016299999 +22 391 8.1499995e-05 +60 391 0.0038301998 +108 391 0.00016299999 +114 391 0.00032599992 +126 391 0.00024449988 +150 391 0.0007334 +175 391 8.1499995e-05 +189 391 0.00016299999 +190 391 0.00016299999 +192 391 0.00065189996 +193 391 0.0005704998 +194 391 0.00016299999 +198 391 0.0048080981 +200 391 8.1499995e-05 +203 391 8.1499995e-05 +204 391 8.1499995e-05 +206 391 0.00016299999 +207 391 8.1499995e-05 +214 391 0.0082307979 +223 391 0.00040749996 +224 391 0.0047265999 +233 391 8.1499995e-05 +234 391 0.0022002999 +237 391 8.1499995e-05 +240 391 8.1499995e-05 +241 391 0.013935298 +252 391 0.12403226 +262 391 0.00016299999 +270 391 0.00016299999 +272 391 0.00065189996 +276 391 0.0036672 +277 391 0.013609298 +282 391 8.1499995e-05 +284 391 0.000489 +290 391 0.00032599992 +292 391 0.0026077998 +293 391 0.0039931983 +294 391 0.0047265999 +295 391 0.0094531998 +296 391 8.1499995e-05 +297 391 0.00097789988 +298 391 8.1499995e-05 +312 391 0.00016299999 +315 391 0.00089639984 +317 391 8.1499995e-05 +320 391 0.0082307979 +321 391 0.0024448 +326 391 0.0052154996 +339 391 8.1499995e-05 +340 391 0.0017114 +351 391 0.000489 +356 391 8.1499995e-05 +358 391 0.0086382963 +369 391 8.1499995e-05 +372 391 8.1499995e-05 +375 391 0.00024449988 +384 391 8.1499995e-05 +385 391 0.00016299999 +386 391 0.00016299999 +387 391 0.00024449988 +389 391 0.0008148998 +390 391 0.0008148998 +391 391 0.0033411998 +392 391 0.0077417977 +393 391 0.057778496 +396 391 0.00089639984 +417 391 0.000489 +421 391 8.1499995e-05 +422 391 8.1499995e-05 +430 391 8.1499995e-05 +433 391 8.1499995e-05 +434 391 8.1499995e-05 +443 391 0.0022002999 +444 391 0.0011409 +445 391 0.0074158981 +447 391 0.0033411998 +450 391 0.0048080981 +452 391 0.0092086978 +453 391 0.0018743 +454 391 0.0011409 +455 391 0.028603997 +456 391 0.00024449988 +457 391 0.0053784996 +458 391 0.0011409 +459 391 0.0044005997 +460 391 0.00097789988 +463 391 0.0125499 +464 391 0.0066008978 +465 391 0.0022002999 +467 391 0.015239198 +468 391 0.0091271996 +469 391 0.0084752999 +470 391 0.0092901997 +471 391 0.0039931983 +473 391 0.00024449988 +477 391 0.00024449988 +478 391 0.0013853998 +483 391 0.0016299 +490 391 0.027055699 +491 391 0.0015483999 +9 392 4.2299987e-05 +16 392 4.2299987e-05 +18 392 0.00016919999 +60 392 0.0027917998 +79 392 4.2299987e-05 +82 392 4.2299987e-05 +83 392 4.2299987e-05 +84 392 4.2299987e-05 +108 392 8.4599989e-05 +113 392 0.00016919999 +114 392 0.00029609981 +126 392 0.00012689999 +127 392 4.2299987e-05 +150 392 0.00080369995 +175 392 0.00012689999 +187 392 0.00033839978 +188 392 8.4599989e-05 +189 392 8.4599989e-05 +190 392 0.00012689999 +192 392 4.2299987e-05 +193 392 4.2299987e-05 +194 392 0.00012689999 +197 392 4.2299987e-05 +198 392 0.0015650999 +200 392 8.4599989e-05 +201 392 8.4599989e-05 +203 392 8.4599989e-05 +204 392 0.00012689999 +206 392 0.0002115 +207 392 8.4599989e-05 +209 392 4.2299987e-05 +214 392 0.022841699 +219 392 4.2299987e-05 +223 392 0.0067678988 +224 392 0.0013112999 +233 392 0.00012689999 +234 392 0.0024533998 +237 392 8.4599989e-05 +240 392 0.0021572998 +241 392 0.0057526976 +242 392 4.2299987e-05 +248 392 4.2299987e-05 +250 392 4.2299987e-05 +252 392 0.0067255981 +262 392 0.0044413991 +263 392 4.2299987e-05 +270 392 0.00029609981 +276 392 0.0011843999 +277 392 0.0015650999 +279 392 4.2299987e-05 +282 392 0.00029609981 +284 392 0.00050759991 +285 392 0.0002115 +290 392 0.0037222998 +292 392 0.0015228 +293 392 0.00059219985 +294 392 0.025633398 +295 392 0.0014381998 +296 392 0.00046529993 +297 392 0.00033839978 +298 392 0.00025379984 +308 392 0.00012689999 +312 392 0.002961 +315 392 0.0240261 +317 392 4.2299987e-05 +320 392 0.011293899 +321 392 0.00059219985 +322 392 0.0006767998 +325 392 4.2299987e-05 +326 392 0.00016919999 +335 392 8.4599989e-05 +339 392 4.2299987e-05 +340 392 0.0031724998 +351 392 8.4599989e-05 +354 392 8.4599989e-05 +356 392 0.0002115 +358 392 0.0012266999 +359 392 0.0048220977 +361 392 4.2299987e-05 +369 392 4.2299987e-05 +370 392 4.2299987e-05 +371 392 8.4599989e-05 +372 392 0.00071909977 +373 392 0.00033839978 +375 392 0.0023687999 +376 392 8.4599989e-05 +384 392 4.2299987e-05 +386 392 0.00054989988 +387 392 0.00016919999 +389 392 0.00050759991 +390 392 0.00042299996 +391 392 0.00054989988 +392 392 0.018823199 +393 392 0.11374307 +396 392 0.0006767998 +402 392 4.2299987e-05 +405 392 4.2299987e-05 +417 392 0.00050759991 +419 392 0.00012689999 +421 392 8.4599989e-05 +422 392 0.00016919999 +423 392 4.2299987e-05 +425 392 4.2299987e-05 +430 392 8.4599989e-05 +431 392 4.2299987e-05 +432 392 4.2299987e-05 +433 392 4.2299987e-05 +434 392 8.4599989e-05 +443 392 0.0013112999 +444 392 0.0032147998 +445 392 0.0041029975 +446 392 0.00071909977 +447 392 0.0063448995 +449 392 4.2299987e-05 +450 392 0.0056681 +452 392 0.0089251995 +453 392 0.0010574998 +454 392 0.0010574998 +455 392 0.022207197 +456 392 0.0010574998 +457 392 0.0059218965 +458 392 0.00093059987 +459 392 0.0013958998 +460 392 0.0012266999 +463 392 0.013831899 +464 392 0.0071485974 +465 392 0.0025379998 +467 392 0.018780898 +468 392 0.0033417 +469 392 0.012478299 +470 392 0.014339499 +471 392 0.0049912967 +473 392 0.00029609981 +477 392 0.00029609981 +478 392 0.0038068998 +483 392 0.0013535998 +489 392 0.00016919999 +490 392 0.0065140985 +491 392 0.0038068998 +9 393 3.9699997e-05 +18 393 0.00015869999 +22 393 5.9499987e-05 +24 393 1.9799991e-05 +60 393 0.0023800998 +77 393 3.9699997e-05 +79 393 1.9799991e-05 +82 393 3.9699997e-05 +83 393 3.9699997e-05 +84 393 3.9699997e-05 +104 393 7.9299993e-05 +108 393 9.9199999e-05 +113 393 7.9299993e-05 +114 393 0.00023799999 +126 393 0.00011899999 +127 393 1.9799991e-05 +130 393 7.9299993e-05 +142 393 3.9699997e-05 +143 393 1.9799991e-05 +150 393 0.0007536998 +151 393 5.9499987e-05 +160 393 0.00015869999 +169 393 3.9699997e-05 +171 393 1.9799991e-05 +172 393 9.9199999e-05 +174 393 0.00017849999 +175 393 0.0020428998 +177 393 1.9799991e-05 +187 393 0.0029155998 +188 393 0.0002776999 +189 393 9.9199999e-05 +190 393 0.00011899999 +192 393 0.00011899999 +193 393 0.0012496 +194 393 0.00013879999 +196 393 1.9799991e-05 +197 393 1.9799991e-05 +198 393 0.0059105977 +200 393 9.9199999e-05 +201 393 3.9699997e-05 +203 393 0.00013879999 +204 393 0.00013879999 +206 393 0.00031729997 +207 393 5.9499987e-05 +208 393 1.9799991e-05 +209 393 1.9799991e-05 +214 393 0.0016263998 +219 393 0.0014676999 +221 393 7.9299993e-05 +223 393 0.0038279998 +224 393 0.0069022998 +225 393 3.9699997e-05 +233 393 0.0001983 +234 393 0.0026775999 +237 393 0.00013879999 +240 393 0.00089249993 +241 393 0.030048799 +242 393 1.9799991e-05 +248 393 1.9799991e-05 +250 393 1.9799991e-05 +252 393 0.0022015998 +262 393 0.0027965999 +268 393 1.9799991e-05 +270 393 0.00011899999 +271 393 0.00011899999 +272 393 3.9699997e-05 +276 393 0.0026180998 +277 393 0.014260799 +278 393 1.9799991e-05 +279 393 7.9299993e-05 +282 393 0.0024197998 +283 393 0.00045619998 +284 393 0.00051569985 +285 393 0.0022015998 +286 393 0.00051569985 +287 393 1.9799991e-05 +288 393 9.9199999e-05 +289 393 0.00061489991 +290 393 0.0021023999 +291 393 1.9799991e-05 +292 393 0.0087071992 +293 393 0.0080327988 +294 393 0.010274097 +295 393 0.014022797 +296 393 0.0019437999 +297 393 0.00031729997 +298 393 0.0007536998 +299 393 5.9499987e-05 +305 393 3.9699997e-05 +307 393 3.9699997e-05 +308 393 0.00051569985 +312 393 0.0067237988 +313 393 0.00021819999 +315 393 0.015371498 +317 393 0.00021819999 +319 393 0.00011899999 +320 393 0.017612796 +321 393 0.00089249993 +322 393 0.0017255999 +325 393 0.0014081998 +326 393 0.0010908998 +328 393 3.9699997e-05 +337 393 9.9199999e-05 +338 393 3.9699997e-05 +340 393 0.0047601983 +341 393 1.9799991e-05 +347 393 1.9799991e-05 +349 393 3.9699997e-05 +350 393 1.9799991e-05 +351 393 0.00025779987 +352 393 1.9799991e-05 +353 393 3.9699997e-05 +354 393 0.00021819999 +356 393 0.00017849999 +357 393 0.00013879999 +358 393 0.0033320999 +359 393 0.012297198 +361 393 5.9499987e-05 +369 393 0.0010313999 +370 393 0.0016065999 +371 393 0.00045619998 +372 393 0.0011900999 +373 393 0.0019040999 +375 393 0.0015470998 +376 393 0.00057519996 +384 393 3.9699997e-05 +385 393 1.9799991e-05 +386 393 0.0033320999 +387 393 0.00065449998 +388 393 1.9799991e-05 +389 393 0.0016858999 +390 393 0.0016263998 +391 393 0.0028164999 +392 393 0.030941296 +393 393 0.14048547 +395 393 1.9799991e-05 +396 393 0.00081319991 +397 393 0.00059499987 +398 393 5.9499987e-05 +402 393 0.0009519998 +405 393 1.9799991e-05 +413 393 1.9799991e-05 +414 393 5.9499987e-05 +417 393 0.00051569985 +419 393 0.0015272 +420 393 3.9699997e-05 +421 393 7.9299993e-05 +422 393 9.9199999e-05 +423 393 3.9699997e-05 +424 393 3.9699997e-05 +425 393 1.9799991e-05 +427 393 1.9799991e-05 +430 393 9.9199999e-05 +431 393 5.9499987e-05 +432 393 1.9799991e-05 +433 393 3.9699997e-05 +434 393 3.9699997e-05 +441 393 5.9499987e-05 +442 393 3.9699997e-05 +443 393 0.0018048999 +444 393 0.0036692999 +445 393 0.0047799982 +446 393 0.00015869999 +447 393 0.0067039989 +448 393 1.9799991e-05 +450 393 0.0058312975 +452 393 0.0065253973 +453 393 0.00099169998 +454 393 0.0010511999 +455 393 0.026835699 +456 393 0.00061489991 +457 393 0.0054345988 +458 393 0.00079339999 +459 393 0.0014479 +460 393 0.00097189983 +463 393 0.015351698 +464 393 0.0077947974 +465 393 0.0031734998 +467 393 0.016402896 +468 393 0.0044229999 +469 393 0.0084889978 +470 393 0.010353398 +471 393 0.0024395999 +472 393 1.9799991e-05 +473 393 0.00021819999 +477 393 0.00021819999 +478 393 0.0018048999 +479 393 1.9799991e-05 +483 393 0.0016065999 +489 393 1.9799991e-05 +490 393 0.0034510999 +491 393 0.0022213999 +21 394 0.00020499999 +60 394 0.0020501998 +108 394 0.00010249999 +114 394 0.00020499999 +126 394 0.00010249999 +150 394 0.0035879 +160 394 0.00040999986 +171 394 0.0050230995 +190 394 0.00010249999 +194 394 0.00020499999 +198 394 0.009943597 +200 394 0.00010249999 +204 394 0.0050230995 +206 394 0.00020499999 +214 394 0.06847769 +224 394 0.0064581968 +225 394 0.0042029992 +233 394 0.0010250998 +234 394 0.0017426999 +237 394 0.00010249999 +240 394 0.0512558 +241 394 0.049205497 +252 394 0.00010249999 +272 394 0.00010249999 +273 394 0.0013325999 +277 394 0.00040999986 +284 394 0.0003074999 +287 394 0.18718606 +288 394 0.00010249999 +290 394 0.0048179999 +294 394 0.0094310977 +295 394 0.00010249999 +315 394 0.00010249999 +326 394 0.00082009984 +340 394 0.0024603 +356 394 0.00010249999 +358 394 0.00092259981 +370 394 0.00010249999 +375 394 0.00061509991 +384 394 0.00010249999 +386 394 0.00010249999 +387 394 0.00010249999 +394 394 0.036904197 +395 394 0.0003074999 +397 394 0.00020499999 +417 394 0.0003074999 +422 394 0.00020499999 +443 394 0.0056380965 +444 394 0.0028702999 +445 394 0.0093284994 +446 394 0.00051259995 +447 394 0.0039978996 +450 394 0.0032803998 +452 394 0.0094310977 +453 394 0.0026652999 +454 394 0.0012300999 +455 394 0.022654999 +456 394 0.00010249999 +457 394 0.0080983974 +458 394 0.00082009984 +459 394 0.00040999986 +460 394 0.00092259981 +463 394 0.016094297 +464 394 0.0017426999 +465 394 0.0045104995 +467 394 0.023577698 +468 394 0.0054330975 +469 394 0.0034854 +470 394 0.0039978996 +471 394 0.0039978996 +473 394 0.00010249999 +477 394 0.00071759988 +478 394 0.0010250998 +483 394 0.00061509991 +490 394 0.00040999986 +491 394 0.0019476998 +21 395 0.005887799 +22 395 0.00030989992 +60 395 0.0024790999 +114 395 0.00030989992 +126 395 0.00030989992 +188 395 0.0021692 +198 395 0.0034087 +206 395 0.00061979983 +214 395 0.044003699 +234 395 0.0015493999 +240 395 0.00061979983 +241 395 0.00061979983 +272 395 0.013015199 +279 395 0.00030989992 +284 395 0.00030989992 +287 395 0.0024790999 +288 395 0.0111559 +290 395 0.057018898 +294 395 0.029439099 +326 395 0.10040289 +340 395 0.0055778995 +358 395 0.0037185999 +375 395 0.015494298 +394 395 0.00061979983 +395 395 0.034087397 +405 395 0.00030989992 +417 395 0.00030989992 +443 395 0.0061976984 +445 395 0.0055778995 +446 395 0.0015493999 +447 395 0.0086767972 +450 395 0.0034087 +452 395 0.0052680969 +453 395 0.00092969998 +454 395 0.0012394998 +455 395 0.0238612 +457 395 0.026030399 +458 395 0.00061979983 +459 395 0.00030989992 +460 395 0.00061979983 +463 395 0.035946697 +464 395 0.0027889998 +465 395 0.0015493999 +467 395 0.019832697 +468 395 0.011465799 +469 395 0.0040284991 +470 395 0.0043383986 +471 395 0.00030989992 +473 395 0.00030989992 +477 395 0.00061979983 +478 395 0.00092969998 +483 395 0.00092969998 +490 395 0.00061979983 +491 395 0.0012394998 +60 396 0.0016305998 +108 396 0.0002329 +114 396 0.00046589994 +126 396 0.0002329 +194 396 0.0002329 +198 396 0.0025622998 +206 396 0.00046589994 +214 396 0.00046589994 +224 396 0.0002329 +233 396 0.00093169999 +234 396 0.0011646999 +241 396 0.0027951999 +252 396 0.007221099 +270 396 0.0002329 +272 396 0.0039598979 +276 396 0.0002329 +277 396 0.003727 +282 396 0.0025622998 +284 396 0.00046589994 +290 396 0.004658699 +292 396 0.0020963999 +293 396 0.004658699 +294 396 0.0055904984 +295 396 0.0041928999 +312 396 0.0023293998 +319 396 0.0048916973 +320 396 0.0002329 +321 396 0.010948099 +326 396 0.0002329 +340 396 0.0051245987 +350 396 0.00069879997 +351 396 0.0020963999 +354 396 0.0358724 +358 396 0.0044257976 +369 396 0.0002329 +372 396 0.0041928999 +375 396 0.015140899 +386 396 0.0011646999 +387 396 0.0002329 +390 396 0.00046589994 +391 396 0.042161699 +392 396 0.00069879997 +393 396 0.0200326 +395 396 0.0002329 +396 396 0.029583 +398 396 0.0016305998 +414 396 0.0016305998 +417 396 0.00046589994 +422 396 0.0002329 +441 396 0.00069879997 +443 396 0.00046589994 +444 396 0.006988097 +445 396 0.010715097 +447 396 0.0090845972 +450 396 0.0044257976 +452 396 0.0041928999 +453 396 0.0016305998 +454 396 0.0030281998 +455 396 0.026787799 +457 396 0.023060799 +458 396 0.00069879997 +459 396 0.00069879997 +460 396 0.00069879997 +463 396 0.045189798 +464 396 0.0093174987 +465 396 0.0090845972 +467 396 0.023293696 +468 396 0.0030281998 +469 396 0.0097833984 +470 396 0.011180997 +471 396 0.010249197 +473 396 0.0002329 +477 396 0.00069879997 +478 396 0.0013975999 +483 396 0.0011646999 +490 396 0.0018634999 +491 396 0.0039598979 +9 397 5.4299991e-05 +18 397 0.00016289999 +19 397 0.0011403 +22 397 0.00038009998 +60 397 0.0030950999 +82 397 5.4299991e-05 +83 397 5.4299991e-05 +84 397 5.4299991e-05 +108 397 5.4299991e-05 +113 397 0.0001086 +114 397 0.0001086 +126 397 5.4299991e-05 +130 397 5.4299991e-05 +135 397 0.0008144998 +137 397 5.4299991e-05 +139 397 5.4299991e-05 +150 397 0.00059729978 +160 397 0.00043439982 +169 397 5.4299991e-05 +172 397 0.0001086 +187 397 0.0001086 +188 397 5.4299991e-05 +189 397 5.4299991e-05 +190 397 0.0001086 +191 397 5.4299991e-05 +194 397 0.00016289999 +197 397 5.4299991e-05 +198 397 0.0054300986 +200 397 5.4299991e-05 +203 397 0.0001086 +204 397 0.0001086 +206 397 0.0001086 +207 397 5.4299991e-05 +214 397 0.0014117998 +223 397 0.00032579992 +224 397 0.0073305964 +225 397 0.0038552999 +233 397 0.00016289999 +234 397 0.0023349 +237 397 0.0001086 +240 397 0.0073305964 +241 397 0.0079821981 +242 397 5.4299991e-05 +252 397 0.00038009998 +262 397 0.0018461999 +270 397 0.0021176999 +271 397 0.00076019997 +272 397 0.00021719999 +277 397 0.051694199 +282 397 0.0122719 +283 397 0.0039638989 +284 397 0.00048869988 +285 397 5.4299991e-05 +286 397 5.4299991e-05 +287 397 0.00027149986 +288 397 0.0022262998 +289 397 0.0045069978 +290 397 5.4299991e-05 +292 397 0.0098826997 +293 397 0.0021176999 +294 397 0.008905299 +295 397 0.042463098 +296 397 0.0085251965 +297 397 0.00038009998 +298 397 0.0084165968 +299 397 5.4299991e-05 +308 397 5.4299991e-05 +312 397 0.0078735985 +313 397 0.0013031999 +315 397 0.0034208999 +319 397 5.4299991e-05 +320 397 0.0051585995 +321 397 0.0037466998 +322 397 0.0064617991 +323 397 5.4299991e-05 +324 397 5.4299991e-05 +326 397 0.007710699 +328 397 0.00021719999 +329 397 5.4299991e-05 +338 397 5.4299991e-05 +339 397 0.00027149986 +340 397 0.0111316 +351 397 0.008905299 +352 397 5.4299991e-05 +354 397 0.0072762966 +356 397 5.4299991e-05 +357 397 0.00076019997 +358 397 0.0023349 +370 397 0.00038009998 +371 397 5.4299991e-05 +372 397 0.0007058999 +373 397 0.00032579992 +374 397 5.4299991e-05 +375 397 0.0037466998 +376 397 5.4299991e-05 +384 397 0.00016289999 +385 397 0.0001086 +386 397 0.0013031999 +387 397 5.4299991e-05 +389 397 5.4299991e-05 +390 397 5.4299991e-05 +391 397 5.4299991e-05 +392 397 0.0079821981 +393 397 0.0014117998 +394 397 5.4299991e-05 +396 397 0.0034751999 +397 397 0.065920889 +402 397 0.0060816966 +404 397 0.0001086 +412 397 5.4299991e-05 +414 397 5.4299991e-05 +417 397 0.00043439982 +421 397 5.4299991e-05 +422 397 0.0001086 +423 397 5.4299991e-05 +430 397 5.4299991e-05 +431 397 5.4299991e-05 +433 397 5.4299991e-05 +434 397 5.4299991e-05 +443 397 0.0033665998 +444 397 0.0015203999 +445 397 0.0076020993 +446 397 0.00032579992 +447 397 0.0019548 +450 397 0.0038552999 +452 397 0.0049413964 +453 397 0.0012488998 +454 397 0.00086879986 +455 397 0.029539499 +456 397 0.00027149986 +457 397 0.0049413964 +458 397 0.00048869988 +459 397 0.00043439982 +460 397 0.00092309993 +463 397 0.0078192987 +464 397 0.0032036998 +465 397 0.0030950999 +467 397 0.023240697 +468 397 0.0029322 +469 397 0.0041267984 +470 397 0.0044525973 +471 397 0.011185899 +473 397 0.0001086 +477 397 0.0008144998 +478 397 0.0010859999 +483 397 0.0008144998 +490 397 0.00043439982 +491 397 0.0033665998 +22 398 0.00040169992 +60 398 0.0010042 +108 398 0.00020079999 +114 398 0.00040169992 +126 398 0.00020079999 +150 398 0.00020079999 +160 398 0.00080339983 +171 398 0.0018075998 +172 398 0.00020079999 +187 398 0.00020079999 +188 398 0.00020079999 +190 398 0.00020079999 +194 398 0.00020079999 +198 398 0.010042198 +200 398 0.00020079999 +206 398 0.00040169992 +214 398 0.0056235977 +223 398 0.00020079999 +224 398 0.010644697 +225 398 0.00020079999 +233 398 0.00040169992 +234 398 0.0022092999 +237 398 0.00020079999 +240 398 0.00020079999 +241 398 0.0092387982 +242 398 0.00020079999 +252 398 0.00040169992 +262 398 0.00020079999 +270 398 0.00020079999 +274 398 0.00040169992 +277 398 0.024703797 +278 398 0.00020079999 +282 398 0.0016066998 +283 398 0.00020079999 +284 398 0.00060249981 +285 398 0.00020079999 +286 398 0.0040168986 +287 398 0.00060249981 +288 398 0.00040169992 +289 398 0.00020079999 +290 398 0.0084353983 +291 398 0.00020079999 +292 398 0.016067497 +293 398 0.0098412968 +294 398 0.031532399 +295 398 0.089576185 +296 398 0.00040169992 +297 398 0.00020079999 +298 398 0.00020079999 +299 398 0.00020079999 +301 398 0.00020079999 +304 398 0.00020079999 +307 398 0.00020079999 +312 398 0.0054227971 +313 398 0.00020079999 +315 398 0.013657399 +319 398 0.00040169992 +320 398 0.00060249981 +321 398 0.00020079999 +322 398 0.00020079999 +324 398 0.0014058999 +326 398 0.0012051 +328 398 0.00020079999 +340 398 0.0078328997 +350 398 0.00020079999 +351 398 0.00060249981 +352 398 0.00080339983 +354 398 0.00020079999 +356 398 0.00020079999 +358 398 0.0036151998 +366 398 0.0054227971 +369 398 0.00040169992 +370 398 0.00020079999 +371 398 0.00040169992 +372 398 0.0068286993 +373 398 0.0026109999 +384 398 0.0056235977 +386 398 0.057642099 +387 398 0.00020079999 +389 398 0.00060249981 +390 398 0.00060249981 +392 398 0.0048201978 +393 398 0.0078328997 +398 398 0.019281 +402 398 0.00020079999 +415 398 0.00080339983 +417 398 0.00040169992 +419 398 0.00060249981 +422 398 0.00020079999 +441 398 0.00020079999 +442 398 0.00020079999 +443 398 0.0028118 +444 398 0.0046193972 +445 398 0.0098412968 +447 398 0.0054227971 +450 398 0.0048201978 +452 398 0.0052218996 +453 398 0.0014058999 +454 398 0.0044185966 +455 398 0.032134999 +456 398 0.00020079999 +457 398 0.0070294999 +458 398 0.0012051 +459 398 0.00040169992 +460 398 0.00080339983 +463 398 0.025707997 +464 398 0.0062260963 +465 398 0.0018075998 +467 398 0.050813399 +468 398 0.0028118 +469 398 0.0070294999 +470 398 0.0072303973 +471 398 0.0010042 +473 398 0.00020079999 +477 398 0.00060249981 +478 398 0.0014058999 +483 398 0.00040169992 +490 398 0.00060249981 +491 398 0.0024100998 +18 399 0.0001181 +60 399 0.0011808998 +78 399 0.00047239987 +113 399 0.0001181 +114 399 0.0001181 +130 399 0.0020075999 +134 399 0.0016532999 +139 399 0.0044874996 +149 399 0.0001181 +150 399 0.00047239987 +151 399 0.00023619999 +156 399 0.0022437 +158 399 0.0001181 +160 399 0.010510199 +161 399 0.00070849992 +163 399 0.00070849992 +165 399 0.011572998 +171 399 0.00047239987 +173 399 0.00035429979 +176 399 0.00035429979 +177 399 0.0001181 +178 399 0.0001181 +181 399 0.0096834973 +191 399 0.00023619999 +194 399 0.0001181 +198 399 0.00023619999 +206 399 0.00023619999 +214 399 0.0001181 +224 399 0.00094469986 +233 399 0.0081482977 +234 399 0.0015351998 +237 399 0.0057864971 +240 399 0.005668398 +241 399 0.0044874996 +242 399 0.0001181 +252 399 0.0090930983 +270 399 0.0001181 +271 399 0.0001181 +274 399 0.00082659977 +277 399 0.079475641 +282 399 0.0060226992 +283 399 0.00094469986 +284 399 0.0010627999 +289 399 0.00035429979 +292 399 0.0027160998 +293 399 0.022909798 +295 399 0.0018894998 +296 399 0.00059049996 +297 399 0.0001181 +298 399 0.0001181 +302 399 0.00035429979 +303 399 0.0033065998 +304 399 0.0011808998 +305 399 0.0001181 +306 399 0.0034246999 +307 399 0.00023619999 +308 399 0.0012989999 +312 399 0.0085025989 +313 399 0.0093291998 +315 399 0.0038969999 +319 399 0.0220831 +320 399 0.0017714 +321 399 0.0017714 +323 399 0.00082659977 +324 399 0.0018894998 +326 399 0.0024798999 +328 399 0.0082663968 +331 399 0.00082659977 +332 399 0.0001181 +337 399 0.0001181 +338 399 0.0010627999 +339 399 0.00047239987 +340 399 0.0016532999 +350 399 0.0001181 +351 399 0.00059049996 +354 399 0.0035426999 +356 399 0.0001181 +357 399 0.00023619999 +358 399 0.0046055987 +366 399 0.023854498 +370 399 0.0001181 +371 399 0.0001181 +372 399 0.0018894998 +373 399 0.0001181 +374 399 0.0001181 +377 399 0.0022437 +378 399 0.0030703999 +383 399 0.0011808998 +384 399 0.0001181 +385 399 0.0012989999 +386 399 0.00023619999 +387 399 0.0001181 +394 399 0.00070849992 +397 399 0.0043693967 +399 399 0.0090930983 +400 399 0.0069673993 +401 399 0.10167688 +402 399 0.042040598 +410 399 0.0001181 +412 399 0.0017714 +417 399 0.00035429979 +421 399 0.0001181 +422 399 0.0001181 +439 399 0.00023619999 +441 399 0.0001181 +443 399 0.0066130981 +444 399 0.00047239987 +445 399 0.0067311972 +446 399 0.00023619999 +447 399 0.0031884999 +450 399 0.0020075999 +452 399 0.0035426999 +453 399 0.0014171 +454 399 0.00023619999 +455 399 0.0422768 +456 399 0.00023619999 +457 399 0.0017714 +458 399 0.00023619999 +459 399 0.00047239987 +460 399 0.00082659977 +463 399 0.011572998 +464 399 0.0034246999 +465 399 0.00082659977 +467 399 0.0085025989 +468 399 0.016532797 +469 399 0.0043693967 +470 399 0.0049597993 +471 399 0.0016532999 +473 399 0.0001181 +477 399 0.0001181 +478 399 0.00094469986 +483 399 0.00070849992 +490 399 0.00035429979 +491 399 0.00035429979 +22 400 0.0001643 +60 400 0.0017255999 +108 400 8.2199986e-05 +114 400 0.0001643 +126 400 8.2199986e-05 +130 400 0.0017255999 +139 400 0.00082169985 +150 400 8.2199986e-05 +160 400 0.022021398 +161 400 0.022432197 +165 400 0.0057517998 +169 400 0.0001643 +181 400 0.0001643 +189 400 8.2199986e-05 +190 400 8.2199986e-05 +194 400 8.2199986e-05 +198 400 8.2199986e-05 +206 400 0.00032869983 +214 400 0.0004929998 +224 400 0.00041079987 +233 400 0.0046835989 +234 400 0.00098599982 +237 400 0.053574398 +240 400 0.0015611998 +241 400 0.0016433999 +242 400 8.2199986e-05 +252 400 0.0001643 +270 400 0.0032046 +271 400 8.2199986e-05 +274 400 0.0026294 +277 400 0.077896476 +282 400 0.010681998 +283 400 0.0031223998 +284 400 0.00090389978 +286 400 8.2199986e-05 +289 400 8.2199986e-05 +292 400 0.0015611998 +293 400 0.067214489 +294 400 0.0002464999 +295 400 0.00082169985 +296 400 0.00041079987 +303 400 8.2199986e-05 +307 400 0.00032869983 +312 400 0.012900598 +313 400 0.0092029981 +315 400 0.0077238977 +319 400 0.0094494969 +320 400 8.2199986e-05 +321 400 0.0036153998 +322 400 8.2199986e-05 +323 400 0.007477399 +324 400 0.0073130988 +326 400 0.0023006999 +328 400 0.00032869983 +331 400 0.0001643 +335 400 8.2199986e-05 +337 400 0.0055052973 +338 400 0.0016433999 +339 400 0.0004929998 +340 400 0.0017255999 +349 400 0.0002464999 +350 400 8.2199986e-05 +351 400 0.0013968998 +354 400 0.0029580998 +356 400 0.0001643 +357 400 8.2199986e-05 +358 400 0.0039440989 +366 400 0.006737899 +372 400 0.0001643 +373 400 0.0001643 +374 400 0.0001643 +378 400 8.2199986e-05 +385 400 0.00073949993 +387 400 8.2199986e-05 +397 400 0.0001643 +399 400 0.0001643 +400 400 0.00082169985 +401 400 0.0020541998 +402 400 0.091454387 +412 400 0.0024650998 +417 400 0.00032869983 +421 400 0.0001643 +422 400 8.2199986e-05 +443 400 0.0082990974 +444 400 0.0023828999 +445 400 0.006819997 +446 400 0.00032869983 +447 400 0.0044370964 +450 400 0.0017255999 +452 400 0.0028758999 +453 400 0.0010682 +454 400 0.0002464999 +455 400 0.045850497 +456 400 8.2199986e-05 +457 400 0.0018076999 +458 400 0.0004929998 +459 400 0.00041079987 +460 400 0.00073949993 +463 400 0.0061626993 +464 400 0.0004929998 +465 400 0.00065739988 +467 400 0.0077238977 +468 400 0.0050944984 +469 400 0.0035332998 +470 400 0.0038619998 +471 400 0.0051766969 +473 400 8.2199986e-05 +477 400 0.0001643 +478 400 0.00073949993 +483 400 0.00090389978 +490 400 0.00032869983 +491 400 0.00065739988 +9 401 7.0999995e-06 +16 401 2.3999992e-06 +18 401 2.6099995e-05 +22 401 0.00035159988 +60 401 0.0012591998 +79 401 2.3999992e-06 +82 401 9.4999996e-06 +83 401 7.0999995e-06 +84 401 7.0999995e-06 +108 401 9.4999996e-06 +113 401 1.19e-05 +114 401 2.6099995e-05 +126 401 1.6599995e-05 +127 401 2.3999992e-06 +130 401 0.00014969999 +134 401 0.0036753998 +137 401 4.7999993e-06 +139 401 0.00014259999 +150 401 0.0001924 +156 401 0.019572198 +158 401 0.0052410997 +160 401 0.00017819999 +161 401 7.0999995e-06 +165 401 0.00022099999 +181 401 0.0041861981 +189 401 2.6099995e-05 +190 401 2.8499999e-05 +192 401 7.0999995e-06 +194 401 0.00059869979 +196 401 2.3999992e-06 +197 401 4.7999993e-06 +198 401 9.4999996e-06 +200 401 1.19e-05 +201 401 4.7999993e-06 +203 401 1.43e-05 +204 401 1.6599995e-05 +206 401 0.00020189999 +207 401 9.4999996e-06 +209 401 2.3999992e-06 +214 401 0.00012119999 +218 401 7.0999995e-06 +219 401 0.0013613999 +223 401 0.00023759999 +224 401 8.079999e-05 +233 401 0.0036254998 +234 401 0.00083869998 +236 401 0.00052739982 +237 401 0.019515198 +240 401 0.0094225965 +241 401 0.0049725994 +242 401 0.0021287999 +248 401 4.7999993e-06 +250 401 2.3999992e-06 +251 401 2.3999992e-06 +252 401 0.0159158 +263 401 2.3999992e-06 +270 401 0.00014019999 +271 401 4.5099994e-05 +272 401 2.3799992e-05 +274 401 1.43e-05 +276 401 8.79e-05 +277 401 0.0096791983 +282 401 0.0051579997 +283 401 0.0011213999 +284 401 0.00038009998 +285 401 6.8899986e-05 +289 401 0.0001164 +290 401 1.19e-05 +292 401 0.0002328 +293 401 0.00096459989 +295 401 0.0001449 +296 401 0.0011997998 +297 401 7.0999995e-06 +298 401 0.00019009999 +299 401 0.00020669999 +303 401 7.129999e-05 +304 401 1.19e-05 +306 401 2.6099995e-05 +307 401 2.3999992e-06 +312 401 0.0092586987 +313 401 0.0885216 +315 401 8.3199993e-05 +318 401 7.5999997e-05 +319 401 0.023254797 +320 401 0.00016159999 +321 401 0.0012543998 +322 401 0.0036136999 +323 401 0.0077238977 +324 401 3.5599995e-05 +326 401 0.00048939977 +328 401 0.011480097 +331 401 3.0899988e-05 +338 401 0.00015919999 +339 401 4.9899987e-05 +340 401 0.0017295999 +341 401 1.19e-05 +350 401 4.7999993e-06 +351 401 0.0010928998 +354 401 7.5999997e-05 +355 401 7.0999995e-06 +356 401 0.00024469988 +357 401 0.0060155988 +358 401 0.00098119979 +359 401 3.5599995e-05 +366 401 0.0069041997 +371 401 2.3999992e-06 +372 401 0.00058679981 +374 401 0.00056309998 +377 401 3.3299992e-05 +378 401 5.4599994e-05 +380 401 2.3999992e-06 +383 401 1.6599995e-05 +384 401 0.0014848998 +385 401 0.0053503998 +386 401 1.19e-05 +387 401 0.0071084984 +392 401 0.00088379998 +393 401 0.00027799979 +394 401 0.0035993999 +397 401 0.020527299 +399 401 0.0018127998 +400 401 0.00015209999 +401 401 0.040363196 +402 401 0.25693089 +404 401 2.6099995e-05 +412 401 0.00016159999 +414 401 0.0013281 +417 401 0.00013069999 +419 401 0.00062479987 +421 401 7.3699994e-05 +422 401 5.2299991e-05 +423 401 4.7999993e-06 +425 401 2.3999992e-06 +430 401 1.19e-05 +431 401 4.7999993e-06 +432 401 2.3999992e-06 +433 401 4.7999993e-06 +434 401 2.1399988e-05 +441 401 0.00031599985 +443 401 0.0087050982 +444 401 0.00048229983 +445 401 0.0074007995 +446 401 0.00023049999 +447 401 0.0016963999 +448 401 1.19e-05 +449 401 2.3999992e-06 +450 401 0.00084819994 +452 401 0.0020051999 +453 401 0.00076029985 +454 401 0.00045849988 +455 401 0.058405399 +456 401 0.0001354 +457 401 0.0019220999 +458 401 0.00010929999 +459 401 0.00054169982 +460 401 0.00084579992 +463 401 0.0010239999 +464 401 0.0006010998 +465 401 0.00026609981 +467 401 0.0040341988 +468 401 0.013839297 +469 401 0.0011498998 +470 401 0.0012852999 +471 401 0.00020189999 +472 401 4.5099994e-05 +473 401 2.8499999e-05 +477 401 0.00014969999 +478 401 0.00030169985 +483 401 0.00050609978 +489 401 1.6599995e-05 +490 401 0.00010219999 +491 401 7.8399986e-05 +9 402 1.44e-05 +16 402 4.7999993e-06 +18 402 5.2699994e-05 +19 402 9.5999994e-06 +22 402 0.00061379978 +24 402 2.3999994e-05 +60 402 0.0025604998 +76 402 9.5999994e-06 +77 402 4.7999993e-06 +78 402 9.5999994e-06 +79 402 1.44e-05 +82 402 2.8799986e-05 +83 402 9.5999994e-06 +84 402 9.5999994e-06 +108 402 1.44e-05 +113 402 2.8799986e-05 +114 402 6.2299994e-05 +117 402 4.7999993e-06 +126 402 2.3999994e-05 +127 402 4.7999993e-06 +130 402 0.00076719979 +131 402 3.8399987e-05 +133 402 4.7999993e-06 +134 402 0.00022059999 +135 402 1.44e-05 +137 402 0.00047949981 +138 402 1.9199986e-05 +139 402 0.00051789987 +140 402 7.1899995e-05 +142 402 0.0001774 +149 402 4.7999993e-06 +150 402 0.0004602999 +156 402 0.0012610999 +158 402 0.00031169993 +159 402 4.7999993e-06 +160 402 0.00012469999 +161 402 2.8799986e-05 +165 402 0.0001007 +169 402 0.00061379978 +170 402 4.7999993e-06 +171 402 0.00020139999 +172 402 0.00088229985 +174 402 3.8399987e-05 +175 402 0.00013429999 +177 402 4.7999993e-06 +181 402 0.00024929992 +187 402 0.00055139977 +188 402 0.00042679999 +189 402 5.2699994e-05 +190 402 6.2299994e-05 +191 402 0.00030209986 +192 402 9.1099995e-05 +194 402 8.1499995e-05 +196 402 4.7999993e-06 +197 402 9.5999994e-06 +198 402 0.0043873973 +200 402 2.3999994e-05 +201 402 9.5999994e-06 +203 402 2.8799986e-05 +204 402 0.00013429999 +206 402 0.00024929992 +207 402 2.3999994e-05 +209 402 4.7999993e-06 +214 402 0.00031649997 +218 402 4.7999993e-06 +219 402 8.6299988e-05 +220 402 4.7999993e-06 +221 402 9.5999994e-06 +222 402 1.9199986e-05 +223 402 0.0018028999 +224 402 0.00269 +225 402 0.0001774 +229 402 9.5999994e-06 +230 402 7.6699987e-05 +233 402 0.0013952998 +234 402 0.0023015998 +236 402 4.3199994e-05 +237 402 0.001707 +239 402 4.7999993e-06 +240 402 0.0046942979 +241 402 0.0042243972 +242 402 0.00086309994 +248 402 9.5999994e-06 +250 402 4.7999993e-06 +251 402 1.9199986e-05 +252 402 0.0018700999 +262 402 1.9199986e-05 +263 402 9.5999994e-06 +270 402 0.0016925998 +271 402 0.0075329989 +272 402 0.0010932998 +274 402 3.3599994e-05 +276 402 0.00019179999 +277 402 0.084425747 +278 402 0.0001007 +279 402 0.00021099999 +282 402 0.071153164 +283 402 0.028041199 +284 402 0.00095419982 +285 402 0.00064729992 +286 402 0.00031169993 +287 402 9.5899988e-05 +288 402 0.0001199 +289 402 0.00089669996 +290 402 0.00011509999 +292 402 0.010548998 +293 402 0.0018461 +294 402 0.00096379989 +295 402 0.0041092969 +296 402 0.014207598 +297 402 0.00028769998 +298 402 0.0013714 +299 402 0.00045069982 +300 402 9.5999994e-06 +303 402 4.7999993e-06 +304 402 5.7499987e-05 +307 402 5.7499987e-05 +308 402 9.5999994e-06 +312 402 0.013416398 +313 402 0.017995697 +315 402 0.0006616998 +317 402 1.9199986e-05 +318 402 0.00024449988 +319 402 0.0021145998 +320 402 0.0045408979 +321 402 0.0014769 +322 402 0.0016494999 +323 402 0.00092539983 +324 402 0.00070009986 +326 402 0.00094939978 +327 402 1.44e-05 +328 402 0.0020234999 +329 402 3.8399987e-05 +330 402 0.000187 +331 402 0.0001966 +332 402 4.7999993e-06 +337 402 1.44e-05 +338 402 0.0007815999 +339 402 0.00024449988 +340 402 0.0048668981 +341 402 0.0001007 +345 402 1.44e-05 +349 402 2.8799986e-05 +350 402 9.5899988e-05 +351 402 0.0077966973 +352 402 0.0009015 +353 402 0.00011509999 +354 402 0.00052749994 +355 402 1.44e-05 +356 402 2.8799986e-05 +357 402 0.0078445971 +358 402 0.0079980977 +359 402 9.5999994e-06 +361 402 4.7999993e-06 +363 402 9.5999994e-06 +366 402 0.0016639 +367 402 9.5999994e-06 +368 402 9.5999994e-06 +369 402 9.5999994e-06 +370 402 0.00020139999 +371 402 0.0001103 +372 402 0.0019850999 +373 402 0.0006616998 +374 402 6.2299994e-05 +375 402 0.00030689989 +376 402 9.5999994e-06 +377 402 4.7999993e-06 +378 402 4.7999993e-06 +380 402 4.7999993e-06 +384 402 0.00018219999 +385 402 0.00041239988 +386 402 0.00024449988 +387 402 0.00054659997 +390 402 3.8399987e-05 +391 402 0.00032129977 +392 402 0.00071449997 +393 402 0.00039319997 +394 402 0.0002158 +396 402 3.3599994e-05 +397 402 0.0064300969 +398 402 1.9199986e-05 +399 402 0.00011509999 +400 402 1.44e-05 +401 402 0.0024358998 +402 402 0.070299685 +404 402 0.00034519983 +405 402 0.0001582 +408 402 4.7999993e-06 +409 402 1.44e-05 +412 402 0.00061859982 +413 402 4.7999993e-06 +414 402 0.0006616998 +415 402 0.0001007 +416 402 1.9199986e-05 +417 402 0.00034999987 +419 402 0.00023019999 +421 402 0.00023019999 +422 402 4.7999987e-05 +423 402 4.7999993e-06 +425 402 4.7999993e-06 +430 402 1.44e-05 +431 402 9.5999994e-06 +432 402 4.7999993e-06 +433 402 1.44e-05 +434 402 1.9199986e-05 +438 402 4.7999993e-06 +441 402 5.7499987e-05 +442 402 1.44e-05 +443 402 0.0053224973 +444 402 0.00089189992 +445 402 0.0074274987 +446 402 0.00055619981 +447 402 0.0015103999 +448 402 1.44e-05 +449 402 4.7999993e-06 +450 402 0.0021386 +452 402 0.0057875998 +453 402 0.0017788999 +454 402 0.00070969993 +455 402 0.037520997 +456 402 0.00064729992 +457 402 0.0019275998 +458 402 0.0001774 +459 402 0.00088709989 +460 402 0.0009782 +463 402 0.0025988999 +464 402 0.0015966999 +465 402 0.0011795999 +467 402 0.0075760968 +468 402 0.0033564998 +469 402 0.0030113 +470 402 0.0033421 +471 402 0.023615398 +472 402 5.7499987e-05 +473 402 6.2299994e-05 +477 402 0.00016299999 +478 402 0.00075759995 +479 402 9.5999994e-06 +483 402 0.0018604998 +489 402 4.3199994e-05 +490 402 0.00029729982 +491 402 0.0053703971 +9 403 7.4699987e-05 +16 403 2.4899986e-05 +17 403 1.25e-05 +18 403 7.4699987e-05 +22 403 2.4899986e-05 +60 403 0.0030271998 +75 403 0.0004608999 +76 403 0.00022419999 +79 403 2.4899986e-05 +81 403 0.00012459999 +82 403 0.00012459999 +83 403 9.9699988e-05 +84 403 9.9699988e-05 +108 403 0.00014949999 +113 403 0.0002118 +114 403 0.00054809987 +126 403 0.0002367 +127 403 4.9799986e-05 +130 403 0.00093429978 +134 403 0.00057309982 +150 403 0.00044849981 +158 403 3.7399994e-05 +160 403 0.00028649997 +171 403 1.25e-05 +172 403 6.2299994e-05 +181 403 0.0016070998 +187 403 1.25e-05 +189 403 0.000137 +190 403 8.7199995e-05 +192 403 2.4899986e-05 +194 403 4.9799986e-05 +196 403 1.25e-05 +197 403 3.7399994e-05 +198 403 2.4899986e-05 +200 403 8.7199995e-05 +201 403 7.4699987e-05 +203 403 3.7399994e-05 +204 403 0.00089699985 +206 403 0.0014326 +207 403 3.7399994e-05 +209 403 1.25e-05 +214 403 0.00017439999 +218 403 1.25e-05 +219 403 0.0001121 +224 403 0.0017814999 +233 403 0.0023047 +234 403 0.0025787998 +237 403 0.0004608999 +240 403 0.00061039999 +241 403 0.00078479992 +248 403 6.2299994e-05 +250 403 4.9799986e-05 +251 403 2.4899986e-05 +252 403 9.9699988e-05 +263 403 1.25e-05 +270 403 2.4899986e-05 +272 403 0.0002491998 +276 403 0.00039859978 +277 403 0.0020181998 +282 403 0.00064779981 +283 403 0.00075989985 +284 403 0.0011834998 +292 403 0.00012459999 +293 403 0.0088823996 +294 403 0.0020554999 +295 403 0.0013704 +296 403 0.0022548998 +297 403 3.7399994e-05 +298 403 0.00078479992 +299 403 0.0042978972 +308 403 1.25e-05 +312 403 0.0068641976 +315 403 0.00097169983 +317 403 9.9699988e-05 +318 403 0.0001121 +319 403 0.004783798 +320 403 0.0022423998 +321 403 0.0025787998 +322 403 0.00064779981 +324 403 0.0011461 +326 403 0.0019433999 +338 403 0.00057309982 +339 403 0.00017439999 +340 403 0.0041234978 +341 403 3.7399994e-05 +350 403 0.0046467967 +351 403 0.00062289997 +354 403 6.2299994e-05 +356 403 0.00066029979 +357 403 9.9699988e-05 +358 403 0.019483998 +359 403 0.0059547983 +369 403 0.001769 +372 403 0.00032389979 +380 403 2.4899986e-05 +384 403 4.9799986e-05 +387 403 0.0002367 +390 403 0.071071684 +392 403 0.0098416992 +393 403 0.020517997 +394 403 3.7399994e-05 +396 403 9.9699988e-05 +397 403 0.0032265999 +402 403 6.2299994e-05 +403 403 0.0034133999 +404 403 0.0446986 +405 403 0.13625085 +413 403 0.0062662996 +414 403 0.0023794 +417 403 0.00031139981 +419 403 0.0016943 +420 403 0.0046467967 +421 403 9.9699988e-05 +422 403 0.0018437998 +423 403 4.9799986e-05 +425 403 3.7399994e-05 +430 403 0.000137 +431 403 4.9799986e-05 +432 403 1.25e-05 +433 403 2.4899986e-05 +434 403 0.0001869 +442 403 1.25e-05 +443 403 0.00077239983 +444 403 0.0036251999 +445 403 0.0047215 +446 403 0.00019929999 +447 403 0.0088326 +448 403 1.25e-05 +449 403 4.9799986e-05 +450 403 0.0047215 +452 403 0.0039241984 +453 403 0.00074749999 +454 403 0.00037369994 +455 403 0.015958399 +456 403 0.0020929 +457 403 0.0026659998 +458 403 0.00057309982 +459 403 0.0011461 +460 403 0.0010090999 +463 403 0.0061541982 +464 403 0.0083342977 +465 403 0.0026659998 +467 403 0.018686697 +468 403 0.0021054 +469 403 0.012121398 +470 403 0.0270583 +471 403 0.0022298999 +473 403 0.00057309982 +477 403 8.7199995e-05 +478 403 0.0013952998 +479 403 0.00072259991 +483 403 0.0020305999 +489 403 2.4899986e-05 +490 403 0.0020554999 +491 403 6.2299994e-05 +9 404 7.509999e-05 +16 404 5.0099989e-05 +18 404 0.00010009999 +22 404 0.0002002 +60 404 0.0038039999 +76 404 5.0099989e-05 +77 404 0.00012509999 +79 404 5.0099989e-05 +82 404 0.00015019999 +83 404 0.00012509999 +84 404 0.00012509999 +108 404 0.0002002 +113 404 0.00027529988 +114 404 0.00067569991 +126 404 0.00030029984 +127 404 7.509999e-05 +130 404 7.509999e-05 +150 404 0.00057559996 +169 404 0.00010009999 +172 404 0.0010760999 +181 404 5.0099989e-05 +187 404 2.4999987e-05 +189 404 0.0002002 +190 404 0.00010009999 +192 404 5.0099989e-05 +194 404 0.00010009999 +196 404 2.4999987e-05 +197 404 5.0099989e-05 +198 404 0.0017267999 +200 404 0.00010009999 +201 404 0.00010009999 +203 404 7.509999e-05 +204 404 0.00010009999 +206 404 0.0016017 +207 404 7.509999e-05 +209 404 2.4999987e-05 +214 404 0.0008758998 +220 404 2.4999987e-05 +224 404 0.0015766998 +233 404 0.00027529988 +234 404 0.0045797974 +237 404 5.0099989e-05 +240 404 0.00095099979 +241 404 0.00015019999 +248 404 0.00010009999 +250 404 7.509999e-05 +251 404 2.4999987e-05 +252 404 0.0001752 +263 404 2.4999987e-05 +271 404 2.4999987e-05 +272 404 0.00095099979 +277 404 0.028630096 +279 404 0.00015019999 +282 404 0.011612199 +283 404 0.0192452 +284 404 0.0013513998 +285 404 2.4999987e-05 +286 404 7.509999e-05 +287 404 2.4999987e-05 +288 404 2.4999987e-05 +289 404 2.4999987e-05 +290 404 0.00080079981 +291 404 2.4999987e-05 +292 404 0.0012512999 +293 404 0.0025527 +294 404 0.0059812963 +295 404 0.00037539983 +296 404 0.008433897 +297 404 0.00037539983 +298 404 0.022023097 +299 404 0.013664298 +305 404 5.0099989e-05 +307 404 7.509999e-05 +308 404 2.4999987e-05 +312 404 0.0040291995 +313 404 2.4999987e-05 +315 404 0.00072579994 +318 404 0.00067569991 +319 404 0.0011511999 +320 404 0.005380597 +321 404 7.509999e-05 +322 404 5.0099989e-05 +324 404 0.0014765998 +326 404 7.509999e-05 +327 404 0.0023273998 +328 404 0.0003252998 +329 404 2.4999987e-05 +331 404 2.4999987e-05 +338 404 0.0014515 +339 404 0.00012509999 +340 404 0.013514198 +341 404 0.00030029984 +343 404 0.00095099979 +350 404 0.0012762998 +351 404 0.0034035998 +354 404 0.0002002 +356 404 0.00042539998 +357 404 0.0021271999 +358 404 0.021422498 +359 404 2.4999987e-05 +366 404 5.0099989e-05 +369 404 2.4999987e-05 +371 404 2.4999987e-05 +372 404 0.00040039979 +373 404 2.4999987e-05 +380 404 5.0099989e-05 +384 404 7.509999e-05 +386 404 2.4999987e-05 +387 404 0.00030029984 +390 404 0.0046798997 +391 404 5.0099989e-05 +392 404 0.00095099979 +393 404 0.0035787998 +396 404 2.4999987e-05 +397 404 0.0054306984 +398 404 2.4999987e-05 +402 404 0.00015019999 +403 404 7.509999e-05 +404 404 0.14269978 +405 404 0.033885598 +413 404 0.0011511999 +414 404 0.0063315965 +417 404 0.00035039987 +419 404 7.509999e-05 +420 404 2.4999987e-05 +421 404 0.00012509999 +422 404 0.0001752 +423 404 0.00010009999 +425 404 7.509999e-05 +430 404 0.0002002 +431 404 7.509999e-05 +432 404 2.4999987e-05 +433 404 5.0099989e-05 +434 404 5.0099989e-05 +443 404 0.0012013 +444 404 0.0010511 +445 404 0.0034285998 +446 404 0.00025029993 +447 404 0.0030532 +448 404 2.4999987e-05 +449 404 7.509999e-05 +450 404 0.0052804984 +452 404 0.0073326975 +453 404 0.0014515 +454 404 0.0015766998 +455 404 0.015816599 +456 404 0.0022773999 +457 404 0.0028279999 +458 404 0.00085089984 +459 404 0.00067569991 +460 404 0.00092599983 +463 404 0.0041793995 +464 404 0.0014264998 +465 404 0.0026777999 +467 404 0.021472499 +468 404 0.0020271 +469 404 0.014239997 +470 404 0.031457998 +471 404 0.00037539983 +473 404 0.00067569991 +477 404 0.00010009999 +478 404 0.0015515999 +483 404 0.0027278999 +489 404 0.00012509999 +490 404 0.0023774998 +491 404 0.0024525998 +9 405 0.00010999999 +16 405 4.3999986e-05 +18 405 0.00013199999 +22 405 0.00015399999 +24 405 2.1999993e-05 +60 405 0.0028153998 +75 405 0.00010999999 +76 405 0.00048389984 +77 405 0.00028589997 +79 405 0.00013199999 +81 405 2.1999993e-05 +82 405 0.00017599999 +83 405 0.00010999999 +84 405 0.00010999999 +108 405 0.00015399999 +113 405 0.0002638998 +114 405 0.00057189981 +126 405 0.0002638998 +127 405 4.3999986e-05 +130 405 0.0020895 +131 405 4.3999986e-05 +132 405 2.1999993e-05 +134 405 0.00013199999 +135 405 2.1999993e-05 +138 405 2.1999993e-05 +139 405 2.1999993e-05 +140 405 2.1999993e-05 +142 405 2.1999993e-05 +150 405 0.00052789995 +156 405 2.1999993e-05 +160 405 8.7999986e-05 +161 405 2.1999993e-05 +165 405 2.1999993e-05 +169 405 0.00015399999 +171 405 0.00010999999 +172 405 0.00054989988 +181 405 0.0018036 +187 405 0.00068179984 +189 405 0.00015399999 +190 405 0.00010999999 +191 405 6.5999993e-05 +192 405 6.5999993e-05 +194 405 0.00013199999 +196 405 2.1999993e-05 +197 405 4.3999986e-05 +198 405 0.0011876998 +200 405 0.00010999999 +201 405 8.7999986e-05 +203 405 6.5999993e-05 +204 405 0.00028589997 +206 405 0.0017376 +207 405 6.5999993e-05 +209 405 2.1999993e-05 +214 405 0.0015395998 +219 405 2.1999993e-05 +220 405 4.3999986e-05 +222 405 4.3999986e-05 +223 405 4.3999986e-05 +224 405 0.0036511999 +225 405 0.00032989983 +233 405 0.0014076999 +234 405 0.0040470995 +237 405 0.00017599999 +240 405 0.0011216998 +241 405 0.0022214998 +248 405 8.7999986e-05 +250 405 4.3999986e-05 +251 405 2.1999993e-05 +252 405 0.00021989999 +262 405 2.1999993e-05 +263 405 4.3999986e-05 +272 405 0.00050589978 +276 405 8.7999986e-05 +277 405 0.013328899 +278 405 2.1999993e-05 +279 405 4.3999986e-05 +282 405 0.004684899 +283 405 0.0076981969 +284 405 0.0013416999 +285 405 0.00010999999 +286 405 4.3999986e-05 +287 405 4.3999986e-05 +288 405 4.3999986e-05 +290 405 0.00092379982 +291 405 2.1999993e-05 +292 405 0.00070379977 +293 405 0.015352499 +294 405 0.0051687993 +295 405 0.0020234999 +296 405 0.004970897 +297 405 0.00013199999 +298 405 0.0028372998 +299 405 0.0056086965 +305 405 6.5999993e-05 +307 405 8.7999986e-05 +308 405 6.5999993e-05 +312 405 0.0089079998 +313 405 4.3999986e-05 +315 405 0.0030792998 +317 405 4.3999986e-05 +318 405 2.1999993e-05 +319 405 0.0031893 +320 405 0.0049268976 +321 405 0.00096779992 +322 405 0.0012096998 +324 405 0.00092379982 +326 405 0.0020234999 +327 405 0.00028589997 +328 405 0.00024189999 +329 405 4.3999986e-05 +331 405 2.1999993e-05 +335 405 2.1999993e-05 +338 405 0.00087979995 +339 405 0.0002638998 +340 405 0.0090838969 +341 405 0.00019799999 +343 405 2.1999993e-05 +350 405 0.0016496 +351 405 0.0031893 +352 405 2.1999993e-05 +354 405 0.0018916 +356 405 0.00041789981 +357 405 6.5999993e-05 +358 405 0.016672198 +359 405 0.0013636998 +366 405 6.5999993e-05 +369 405 0.00052789995 +371 405 2.1999993e-05 +372 405 0.0011876998 +373 405 0.00017599999 +380 405 2.1999993e-05 +384 405 6.5999993e-05 +386 405 8.7999986e-05 +387 405 0.00024189999 +390 405 0.0340482 +391 405 4.3999986e-05 +392 405 0.019817397 +393 405 0.017002098 +396 405 0.00052789995 +397 405 0.0013196999 +398 405 4.3999986e-05 +401 405 2.1999993e-05 +402 405 0.00021989999 +403 405 0.0019574999 +404 405 0.020345297 +405 405 0.099087179 +408 405 0.00010999999 +413 405 0.0025293999 +414 405 0.00079179998 +416 405 2.1999993e-05 +417 405 0.00037389994 +419 405 0.00043989997 +420 405 0.0010777998 +421 405 0.00013199999 +422 405 0.00063789985 +423 405 6.5999993e-05 +425 405 4.3999986e-05 +430 405 0.00015399999 +431 405 6.5999993e-05 +432 405 2.1999993e-05 +433 405 4.3999986e-05 +434 405 8.7999986e-05 +442 405 4.3999986e-05 +443 405 0.0011437 +444 405 0.0049928986 +445 405 0.0036291999 +446 405 0.00021989999 +447 405 0.0080940984 +448 405 2.1999993e-05 +449 405 4.3999986e-05 +450 405 0.0053667985 +452 405 0.0065764971 +453 405 0.0012316999 +454 405 0.00039589987 +455 405 0.017529998 +456 405 0.0020015 +457 405 0.0026613998 +458 405 0.00094579998 +459 405 0.0015615998 +460 405 0.00092379982 +463 405 0.0082700998 +464 405 0.0095897987 +465 405 0.0032332998 +467 405 0.020367298 +468 405 0.0023094998 +469 405 0.012405097 +470 405 0.027471699 +471 405 0.0023534999 +473 405 0.00061589992 +477 405 0.00013199999 +478 405 0.0015615998 +479 405 0.00017599999 +483 405 0.0023094998 +489 405 2.1999993e-05 +490 405 0.0021114999 +491 405 0.00015399999 +9 406 3.1999996e-05 +16 406 3.1999996e-05 +18 406 0.0001602 +22 406 6.4099993e-05 +24 406 9.609999e-05 +60 406 0.0027557998 +76 406 0.00025639986 +79 406 3.1999996e-05 +82 406 3.1999996e-05 +83 406 3.1999996e-05 +84 406 3.1999996e-05 +108 406 6.4099993e-05 +113 406 9.609999e-05 +114 406 0.00022429999 +126 406 9.609999e-05 +127 406 3.1999996e-05 +131 406 0.0012496999 +150 406 0.0010253999 +154 406 0.00092929997 +160 406 0.0023071999 +161 406 0.0014419998 +163 406 0.00022429999 +165 406 0.00089719985 +169 406 9.609999e-05 +171 406 0.0031402998 +177 406 0.005543597 +178 406 0.0015701998 +180 406 0.0049026981 +183 406 0.00086519984 +185 406 0.00064089987 +189 406 9.609999e-05 +190 406 0.0001602 +194 406 0.00012819999 +200 406 6.4099993e-05 +201 406 6.4099993e-05 +203 406 0.00012819999 +204 406 6.4099993e-05 +206 406 0.00070499978 +207 406 6.4099993e-05 +214 406 0.00035249977 +218 406 3.1999996e-05 +219 406 3.1999996e-05 +223 406 0.00012819999 +224 406 0.0010894998 +233 406 0.010926999 +234 406 0.0058319978 +237 406 6.4099993e-05 +240 406 3.1999996e-05 +241 406 0.0010574998 +242 406 0.00048069982 +248 406 3.1999996e-05 +250 406 3.1999996e-05 +252 406 0.0011855999 +254 406 0.00041659991 +256 406 0.00038449978 +259 406 0.00019229999 +263 406 3.1999996e-05 +270 406 3.1999996e-05 +271 406 0.00070499978 +272 406 0.00092929997 +274 406 0.0015701998 +276 406 0.00083309994 +277 406 0.090139985 +279 406 3.1999996e-05 +282 406 0.0017623999 +283 406 0.0014739998 +284 406 0.00012819999 +289 406 0.0029801 +290 406 0.0044220984 +292 406 0.0045181997 +293 406 0.0024353999 +295 406 0.0052231997 +296 406 6.4099993e-05 +297 406 3.1999996e-05 +298 406 3.1999996e-05 +299 406 3.1999996e-05 +302 406 0.00048069982 +303 406 0.00089719985 +304 406 0.00076909992 +305 406 0.019130297 +306 406 0.0049989 +307 406 0.0083955973 +308 406 0.0028518999 +309 406 0.0048065968 +312 406 0.0049347989 +315 406 6.4099993e-05 +319 406 3.1999996e-05 +321 406 3.1999996e-05 +322 406 9.609999e-05 +323 406 0.00028839987 +324 406 0.010382298 +326 406 0.0048065968 +327 406 0.018425398 +328 406 0.012689497 +331 406 0.010574598 +334 406 0.0014419998 +335 406 0.00044859992 +336 406 0.0033004999 +337 406 3.1999996e-05 +338 406 0.00035249977 +339 406 0.0014098999 +340 406 0.0010894998 +341 406 0.00086519984 +349 406 0.0022751 +350 406 0.0056076981 +351 406 0.0024353999 +352 406 0.0071778968 +354 406 0.0092928 +355 406 6.4099993e-05 +356 406 0.0027557998 +358 406 0.0052872971 +359 406 0.00012819999 +366 406 0.0046142973 +368 406 0.0017944998 +369 406 0.0015381 +370 406 0.0050308965 +371 406 0.0010253999 +372 406 0.0030120998 +373 406 0.0049026981 +374 406 0.0094209984 +384 406 9.609999e-05 +385 406 0.00038449978 +386 406 0.00035249977 +387 406 9.609999e-05 +389 406 0.0013458999 +390 406 0.021982197 +391 406 3.1999996e-05 +392 406 0.00054469984 +393 406 0.00054469984 +394 406 0.00035249977 +396 406 0.00028839987 +402 406 9.609999e-05 +404 406 0.0001602 +405 406 0.0017623999 +406 406 0.0042939 +407 406 9.609999e-05 +412 406 0.0017623999 +413 406 0.0037811999 +414 406 0.0015701998 +415 406 0.0034607998 +417 406 0.00070499978 +419 406 0.0022431 +421 406 0.00022429999 +422 406 0.00012819999 +423 406 3.1999996e-05 +425 406 3.1999996e-05 +430 406 6.4099993e-05 +431 406 3.1999996e-05 +432 406 3.1999996e-05 +433 406 6.4099993e-05 +434 406 9.609999e-05 +439 406 0.00028839987 +442 406 0.0012496999 +443 406 0.0033645998 +444 406 0.00032039988 +445 406 0.0059281997 +446 406 0.00044859992 +447 406 0.00073699979 +449 406 3.1999996e-05 +450 406 0.0044861995 +452 406 0.0065369979 +453 406 0.00054469984 +454 406 0.00076909992 +455 406 0.032204296 +456 406 0.0011855999 +457 406 0.0020828999 +458 406 0.00048069982 +459 406 0.0010894998 +460 406 0.0015381 +463 406 0.0038772998 +464 406 0.00038449978 +465 406 0.0017944998 +467 406 0.016502697 +468 406 0.0016982998 +469 406 0.0095811971 +470 406 0.010926999 +471 406 0.00051269983 +473 406 0.00022429999 +477 406 0.00019229999 +478 406 0.0018585999 +483 406 0.0013138 +489 406 6.4099993e-05 +490 406 0.00083309994 +491 406 0.0010253999 +9 407 7.9899997e-05 +18 407 0.00015979999 +60 407 0.0017579 +82 407 7.9899997e-05 +83 407 7.9899997e-05 +84 407 7.9899997e-05 +108 407 7.9899997e-05 +114 407 0.00015979999 +126 407 7.9899997e-05 +134 407 0.0022372999 +137 407 0.0070315972 +138 407 0.0043946989 +139 407 0.0073511973 +141 407 0.0084697977 +143 407 0.0011985998 +149 407 7.9899997e-05 +150 407 0.00071909977 +151 407 0.00015979999 +154 407 0.0060726963 +160 407 0.0095884986 +161 407 0.00031959987 +163 407 0.0095884986 +165 407 0.012624897 +166 407 0.0061525963 +171 407 0.010387499 +173 407 0.00015979999 +176 407 0.00015979999 +177 407 0.00015979999 +178 407 7.9899997e-05 +180 407 7.9899997e-05 +182 407 0.0035158 +189 407 7.9899997e-05 +190 407 7.9899997e-05 +191 407 7.9899997e-05 +194 407 0.00015979999 +198 407 7.9899997e-05 +200 407 7.9899997e-05 +203 407 7.9899997e-05 +204 407 7.9899997e-05 +206 407 0.00063919998 +214 407 0.00023969999 +219 407 0.00023969999 +224 407 0.028046299 +233 407 0.016220499 +234 407 0.0042348988 +237 407 7.9899997e-05 +240 407 0.0023971 +241 407 0.0065520965 +242 407 0.0019975998 +252 407 0.0350779 +270 407 0.0027965999 +272 407 0.00063919998 +274 407 7.9899997e-05 +277 407 0.0087094977 +282 407 0.00055929995 +283 407 0.0021573999 +284 407 7.9899997e-05 +289 407 0.0041549988 +290 407 0.0015980999 +292 407 0.0003994999 +293 407 0.018058296 +295 407 0.00047939993 +296 407 0.0012784998 +297 407 0.00055929995 +302 407 0.00015979999 +303 407 7.9899997e-05 +304 407 0.0091889985 +305 407 0.00023969999 +306 407 0.0013583999 +307 407 0.0034359 +308 407 0.0042348988 +309 407 7.9899997e-05 +312 407 0.0075908974 +315 407 0.0019975998 +319 407 0.0088693984 +320 407 0.0029564998 +321 407 0.0023171999 +322 407 0.0035158 +324 407 0.00015979999 +326 407 0.0119057 +327 407 0.00023969999 +328 407 0.1043548 +331 407 0.00023969999 +340 407 0.0015181999 +350 407 0.0076707974 +351 407 0.0019176998 +352 407 0.0024769998 +354 407 0.015741099 +356 407 0.0023171999 +357 407 0.0043946989 +358 407 0.0032760999 +366 407 0.0036755998 +370 407 0.00071909977 +372 407 0.0020774999 +373 407 7.9899997e-05 +374 407 7.9899997e-05 +377 407 0.00031959987 +378 407 0.0003994999 +383 407 0.00015979999 +384 407 7.9899997e-05 +385 407 7.9899997e-05 +386 407 7.9899997e-05 +387 407 7.9899997e-05 +390 407 0.00023969999 +394 407 0.00095879985 +397 407 0.0003994999 +398 407 0.0034359 +401 407 7.9899997e-05 +402 407 0.0012784998 +406 407 7.9899997e-05 +407 407 0.0178186 +410 407 7.9899997e-05 +412 407 0.0020774999 +413 407 0.00031959987 +415 407 7.9899997e-05 +417 407 0.00047939993 +419 407 0.0027166998 +421 407 0.00015979999 +422 407 0.00015979999 +423 407 7.9899997e-05 +430 407 0.00023969999 +439 407 0.00015979999 +441 407 7.9899997e-05 +443 407 0.004794199 +444 407 0.0043946989 +445 407 0.0096683986 +446 407 0.00015979999 +447 407 0.0033559999 +450 407 0.0030363998 +452 407 0.0033559999 +453 407 0.00087889982 +454 407 0.00031959987 +455 407 0.046264499 +456 407 0.00047939993 +457 407 0.0015980999 +458 407 0.00063919998 +459 407 0.0007989998 +460 407 0.0015181999 +463 407 0.012624897 +464 407 0.00055929995 +465 407 0.0011985998 +467 407 0.0097482987 +468 407 0.0167799 +469 407 0.0063123964 +470 407 0.0069516972 +471 407 0.0039951988 +473 407 0.00015979999 +477 407 7.9899997e-05 +478 407 0.0011985998 +483 407 0.00071909977 +490 407 0.00055929995 +491 407 0.00063919998 +9 408 4.0399987e-05 +18 408 0.00012109999 +22 408 0.00044409977 +60 408 0.00072669983 +82 408 4.0399987e-05 +108 408 4.0399987e-05 +114 408 8.0699989e-05 +126 408 4.0399987e-05 +130 408 4.0399987e-05 +134 408 0.0025435998 +137 408 0.00012109999 +139 408 0.0010093998 +150 408 0.00048449985 +160 408 0.0046430975 +161 408 0.0022205999 +165 408 0.00044409977 +169 408 0.00016149999 +172 408 8.0699989e-05 +181 408 4.0399987e-05 +189 408 4.0399987e-05 +190 408 8.0699989e-05 +192 408 4.0399987e-05 +194 408 4.0399987e-05 +196 408 4.0399987e-05 +198 408 4.0399987e-05 +200 408 4.0399987e-05 +203 408 4.0399987e-05 +204 408 4.0399987e-05 +206 408 0.0003229999 +207 408 4.0399987e-05 +214 408 0.0019379999 +224 408 4.0399987e-05 +233 408 0.0047641993 +234 408 0.0018975998 +237 408 4.0399987e-05 +240 408 0.0056524985 +241 408 0.00072669983 +242 408 0.0014534998 +252 408 0.0039566979 +270 408 0.00044409977 +271 408 8.0699989e-05 +272 408 0.00040369993 +277 408 0.10352069 +278 408 4.0399987e-05 +282 408 0.066779673 +283 408 0.018895298 +284 408 0.00028259982 +286 408 8.0699989e-05 +289 408 0.0041181967 +290 408 4.0399987e-05 +292 408 0.0044815987 +293 408 0.0016553998 +294 408 0.00088819978 +295 408 0.00072669983 +296 408 0.0020994998 +298 408 0.0003229999 +299 408 0.0070655979 +307 408 0.0002422 +312 408 0.0058946982 +313 408 4.0399987e-05 +315 408 0.00048449985 +318 408 0.00012109999 +319 408 0.0061369985 +320 408 0.00020189999 +321 408 0.0015341998 +322 408 0.0028665999 +323 408 0.0039970987 +324 408 0.00016149999 +326 408 0.0073481984 +327 408 4.0399987e-05 +328 408 0.022932798 +331 408 0.00012109999 +332 408 0.00012109999 +338 408 0.00048449985 +339 408 0.0006459998 +340 408 0.0054101981 +341 408 8.0699989e-05 +343 408 4.0399987e-05 +347 408 4.0399987e-05 +349 408 0.0002422 +350 408 0.0035932998 +351 408 0.015301999 +352 408 0.0010497 +353 408 4.0399987e-05 +354 408 0.011627898 +355 408 4.0399987e-05 +356 408 0.00040369993 +357 408 8.0699989e-05 +358 408 0.0057331994 +359 408 4.0399987e-05 +366 408 0.0034721999 +371 408 0.014736798 +372 408 0.0031895998 +373 408 0.00016149999 +374 408 0.00016149999 +375 408 4.0399987e-05 +386 408 0.00040369993 +387 408 4.0399987e-05 +390 408 0.00044409977 +392 408 0.00028259982 +393 408 0.00036339997 +394 408 0.00036339997 +397 408 8.0699989e-05 +398 408 4.0399987e-05 +402 408 0.0002422 +404 408 0.0020994998 +405 408 0.0017764999 +408 408 0.13654715 +412 408 0.0027858999 +414 408 8.0699989e-05 +417 408 0.0003229999 +421 408 8.0699989e-05 +422 408 4.0399987e-05 +430 408 4.0399987e-05 +433 408 4.0399987e-05 +434 408 4.0399987e-05 +443 408 0.0060157999 +444 408 0.00080749998 +445 408 0.0055312999 +446 408 0.00044409977 +447 408 0.0018571999 +450 408 0.0020591 +452 408 0.0039162971 +453 408 0.0013323999 +454 408 0.00044409977 +455 408 0.029231299 +456 408 0.00020189999 +457 408 0.0041181967 +458 408 0.00036339997 +459 408 0.0026244 +460 408 0.00084789982 +463 408 0.005935099 +464 408 0.00036339997 +465 408 0.00072669983 +467 408 0.0075903982 +468 408 0.0018169 +469 408 0.0030280999 +470 408 0.0037145 +471 408 0.00028259982 +473 408 8.0699989e-05 +477 408 8.0699989e-05 +478 408 0.0007670999 +483 408 0.0014130999 +490 408 0.0003229999 +491 408 0.0015745999 +60 409 0.0054290965 +114 409 0.00017509999 +126 409 0.00017509999 +139 409 0.0014010998 +142 409 0.00017509999 +150 409 0.00017509999 +160 409 0.00017509999 +190 409 0.00017509999 +194 409 0.00017509999 +198 409 0.0024517998 +206 409 0.00052539981 +214 409 0.00017509999 +224 409 0.00017509999 +233 409 0.0028020998 +234 409 0.0019263998 +237 409 0.035726797 +240 409 0.0012258999 +241 409 0.0012258999 +272 409 0.0010507999 +277 409 0.062696993 +279 409 0.00017509999 +282 409 0.0054290965 +283 409 0.0099824965 +284 409 0.00070049986 +292 409 0.00017509999 +293 409 0.0017512999 +296 409 0.0082311966 +297 409 0.00017509999 +298 409 0.0010507999 +308 409 0.00017509999 +312 409 0.022591896 +313 409 0.00017509999 +315 409 0.010507897 +317 409 0.00017509999 +320 409 0.026269697 +321 409 0.0071803965 +322 409 0.0064798966 +326 409 0.0052538998 +328 409 0.0099824965 +330 409 0.012434296 +340 409 0.0036777998 +350 409 0.00017509999 +351 409 0.0036777998 +354 409 0.053415097 +356 409 0.00035029999 +357 409 0.00070049986 +358 409 0.0096321963 +372 409 0.00035029999 +385 409 0.0010507999 +386 409 0.00017509999 +395 409 0.00017509999 +397 409 0.00052539981 +398 409 0.0050787963 +402 409 0.0089316964 +409 409 0.15621716 +412 409 0.0085813999 +417 409 0.00052539981 +419 409 0.0012258999 +422 409 0.00017509999 +430 409 0.00017509999 +441 409 0.0031523998 +443 409 0.0024517998 +444 409 0.0010507999 +445 409 0.0047284998 +446 409 0.00017509999 +447 409 0.0057792999 +450 409 0.002627 +452 409 0.0036777998 +453 409 0.0017512999 +454 409 0.00052539981 +455 409 0.057267997 +456 409 0.00017509999 +457 409 0.0040279999 +458 409 0.00052539981 +459 409 0.00070049986 +460 409 0.0010507999 +463 409 0.010682996 +464 409 0.00035029999 +465 409 0.00070049986 +467 409 0.0070052966 +468 409 0.024693497 +469 409 0.0028020998 +470 409 0.0031523998 +471 409 0.00052539981 +473 409 0.00017509999 +477 409 0.00017509999 +478 409 0.0010507999 +483 409 0.00052539981 +490 409 0.00035029999 +491 409 0.00035029999 +60 410 0.00053639989 +114 410 7.6599987e-05 +130 410 7.6599987e-05 +134 410 0.0080453977 +139 410 0.0087349974 +149 410 0.0028349999 +150 410 7.6599987e-05 +151 410 0.0075089969 +154 410 0.00099609978 +156 410 0.00015319999 +160 410 0.045513798 +161 410 0.00061299978 +163 410 0.018925797 +164 410 0.0013025999 +165 410 0.0311087 +170 410 0.00061299978 +171 410 0.012642696 +173 410 0.0086582974 +176 410 0.009347897 +177 410 0.0026051998 +178 410 0.0033713998 +181 410 0.00030649989 +190 410 7.6599987e-05 +191 410 0.0055933967 +194 410 0.00015319999 +198 410 7.6599987e-05 +206 410 0.00015319999 +214 410 0.00015319999 +224 410 0.00045969989 +233 410 0.0026051998 +234 410 0.0012259998 +237 410 0.0064362995 +240 410 0.0022986999 +241 410 0.015630998 +252 410 0.0034479999 +274 410 0.0051336996 +277 410 0.029422998 +282 410 0.0025284998 +283 410 7.6599987e-05 +289 410 0.0060531981 +292 410 0.0016856999 +293 410 0.027737297 +295 410 0.0058998987 +296 410 0.00030649989 +302 410 0.010880399 +303 410 0.0036778999 +304 410 0.017852999 +305 410 7.6599987e-05 +306 410 0.061910998 +307 410 0.0012259998 +308 410 0.034096997 +312 410 0.006512899 +313 410 0.00045969989 +315 410 0.00030649989 +319 410 0.0064362995 +320 410 0.0019155999 +321 410 0.0033713998 +322 410 7.6599987e-05 +324 410 7.6599987e-05 +326 410 0.0028349999 +327 410 7.6599987e-05 +328 410 0.0008427999 +338 410 7.6599987e-05 +340 410 7.6599987e-05 +351 410 7.6599987e-05 +354 410 7.6599987e-05 +356 410 7.6599987e-05 +358 410 0.00015319999 +366 410 0.0046739988 +372 410 7.6599987e-05 +377 410 0.017929699 +378 410 0.024595797 +383 410 0.0081219971 +384 410 0.0036012998 +385 410 0.0047505982 +386 410 0.0031414998 +387 410 0.0009194999 +390 410 7.6599987e-05 +397 410 0.00022989999 +399 410 0.00030649989 +400 410 0.00022989999 +401 410 0.0067427978 +402 410 0.071105659 +407 410 7.6599987e-05 +410 410 0.0046739988 +412 410 0.0023752998 +417 410 0.00045969989 +421 410 7.6599987e-05 +422 410 0.00015319999 +439 410 0.0078920983 +441 410 0.0022986999 +443 410 0.012412798 +444 410 0.0024518999 +445 410 0.011110298 +446 410 0.00038309977 +447 410 0.0032180999 +450 410 0.0019155999 +452 410 0.0024518999 +453 410 0.0012259998 +454 410 0.00022989999 +455 410 0.068883598 +456 410 0.00015319999 +457 410 0.0040609986 +458 410 0.00061299978 +459 410 0.00061299978 +460 410 0.00099609978 +463 410 0.0086582974 +464 410 0.00076619978 +465 410 0.0006895999 +467 410 0.0045972988 +468 410 0.0037544998 +469 410 0.0009194999 +470 410 0.0009194999 +471 410 0.0013025999 +477 410 7.6599987e-05 +478 410 0.0009194999 +483 410 0.00015319999 +490 410 0.00015319999 +491 410 0.00053639989 +9 411 3.119999e-05 +18 411 6.2299994e-05 +60 411 0.00052969996 +82 411 3.119999e-05 +83 411 3.119999e-05 +84 411 3.119999e-05 +108 411 3.119999e-05 +113 411 6.2299994e-05 +114 411 9.3499999e-05 +126 411 3.119999e-05 +134 411 0.026487198 +135 411 0.00037389994 +139 411 0.008569397 +149 411 0.0026798998 +150 411 0.00049859984 +151 411 0.0019319998 +159 411 0.00028049992 +160 411 0.065937459 +161 411 0.0013398998 +163 411 0.015829999 +164 411 0.013087798 +165 411 0.041787397 +170 411 0.0044248998 +171 411 0.0099092983 +173 411 0.0086004995 +176 411 0.0064191967 +177 411 0.0027109999 +178 411 0.0031784999 +182 411 0.0029292 +183 411 0.00012459999 +184 411 0.0017761998 +190 411 6.2299994e-05 +191 411 0.0012775999 +192 411 0.00040509994 +194 411 3.119999e-05 +196 411 3.119999e-05 +200 411 3.119999e-05 +203 411 3.119999e-05 +204 411 3.119999e-05 +206 411 6.2299994e-05 +207 411 3.119999e-05 +214 411 0.00031159981 +219 411 0.00056089996 +223 411 0.00024929992 +229 411 3.119999e-05 +230 411 0.00071669999 +233 411 0.0047053993 +234 411 0.00087249978 +236 411 0.0025240998 +237 411 0.0096288994 +240 411 0.00059209997 +241 411 0.008507099 +252 411 0.00049859984 +259 411 0.0020877998 +268 411 0.0059517995 +270 411 9.3499999e-05 +271 411 0.0023993999 +272 411 0.00040509994 +274 411 0.0032718999 +277 411 0.025832798 +279 411 0.0020877998 +282 411 0.0017761998 +283 411 3.119999e-05 +285 411 6.2299994e-05 +287 411 0.00040509994 +289 411 0.0030226998 +292 411 0.0025863999 +293 411 0.034682598 +294 411 0.00012459999 +295 411 0.0073229 +296 411 0.0014334 +302 411 0.0097534992 +303 411 0.010220896 +304 411 9.3499999e-05 +306 411 0.014116097 +308 411 0.0037393998 +312 411 0.0017138999 +317 411 9.3499999e-05 +318 411 3.119999e-05 +319 411 0.0051415972 +320 411 0.0014646 +321 411 0.00090369978 +324 411 0.00084139989 +326 411 0.0012775999 +337 411 3.119999e-05 +339 411 0.00015579999 +340 411 9.3499999e-05 +341 411 0.0015892 +343 411 3.119999e-05 +346 411 0.00084139989 +350 411 0.00056089996 +356 411 9.3499999e-05 +358 411 0.00015579999 +366 411 0.085382164 +369 411 0.0018384999 +377 411 0.013710998 +378 411 0.020410698 +379 411 0.0013398998 +380 411 0.0017449998 +383 411 0.0091613978 +384 411 6.2299994e-05 +385 411 0.0065438971 +386 411 0.0032408 +387 411 3.119999e-05 +398 411 0.00062319986 +401 411 9.3499999e-05 +402 411 0.049079198 +410 411 3.119999e-05 +411 411 0.0019942999 +412 411 0.0017138999 +415 411 0.00024929992 +417 411 0.00034279982 +419 411 0.00084139989 +421 411 0.00015579999 +422 411 3.119999e-05 +423 411 3.119999e-05 +430 411 3.119999e-05 +431 411 3.119999e-05 +433 411 3.119999e-05 +434 411 3.119999e-05 +438 411 6.2299994e-05 +439 411 0.0010282998 +441 411 0.00099719991 +443 411 0.014583498 +444 411 0.0010905999 +445 411 0.010439098 +446 411 0.00068559987 +447 411 0.0015580999 +450 411 0.0016204 +452 411 0.0016204 +453 411 0.00099719991 +454 411 0.00021809999 +455 411 0.067994058 +456 411 0.00024929992 +457 411 0.0042378977 +458 411 0.00028049992 +459 411 0.00059209997 +460 411 0.00046739983 +463 411 0.0036146999 +464 411 0.0019007998 +465 411 0.00059209997 +467 411 0.0033030999 +468 411 0.0029602998 +469 411 0.0027733999 +470 411 0.003085 +471 411 0.00087249978 +473 411 6.2299994e-05 +478 411 0.00074789999 +483 411 0.00021809999 +489 411 3.119999e-05 +490 411 0.00024929992 +491 411 9.3499999e-05 +60 412 0.0007540998 +114 412 0.0001257 +126 412 0.0001257 +130 412 0.0007540998 +131 412 0.0001257 +132 412 0.0001257 +134 412 0.00037699984 +137 412 0.0001257 +138 412 0.0001257 +139 412 0.0012567998 +141 412 0.0001257 +149 412 0.0001257 +151 412 0.00037699984 +152 412 0.0027649 +154 412 0.0001257 +158 412 0.0001257 +160 412 0.0080431998 +161 412 0.0001257 +163 412 0.0012567998 +164 412 0.0001257 +165 412 0.0030161999 +166 412 0.0001257 +171 412 0.011562098 +173 412 0.00050269999 +176 412 0.00050269999 +177 412 0.0011310999 +178 412 0.0018850998 +182 412 0.0001257 +188 412 0.0001257 +190 412 0.0001257 +191 412 0.0016337999 +194 412 0.0001257 +198 412 0.0012567998 +206 412 0.00037699984 +214 412 0.0001257 +224 412 0.0011310999 +233 412 0.0054039992 +234 412 0.0018850998 +237 412 0.033052698 +240 412 0.0021364999 +241 412 0.0090485997 +242 412 0.0007540998 +252 412 0.00087969983 +274 412 0.00025139982 +277 412 0.12379038 +282 412 0.0026391998 +283 412 0.0036445998 +284 412 0.0006283999 +285 412 0.0001257 +289 412 0.0012567998 +292 412 0.0001257 +293 412 0.035440497 +295 412 0.00037699984 +296 412 0.0015081 +297 412 0.00037699984 +298 412 0.0023877998 +299 412 0.0001257 +302 412 0.0006283999 +303 412 0.0020107999 +304 412 0.0036445998 +306 412 0.0064094998 +307 412 0.00025139982 +308 412 0.018599998 +312 412 0.0086715966 +313 412 0.0001257 +315 412 0.013698597 +317 412 0.00050269999 +319 412 0.0006283999 +320 412 0.0042729974 +321 412 0.0062837973 +322 412 0.0090485997 +326 412 0.013949998 +328 412 0.047756698 +329 412 0.00087969983 +330 412 0.0033932 +337 412 0.00025139982 +338 412 0.0001257 +340 412 0.0031418998 +350 412 0.00087969983 +351 412 0.0059066974 +354 412 0.0057810992 +356 412 0.0001257 +357 412 0.00037699984 +358 412 0.0027649 +366 412 0.00037699984 +372 412 0.0012567998 +377 412 0.0035188999 +378 412 0.0037703 +383 412 0.00050269999 +384 412 0.0007540998 +385 412 0.0011310999 +386 412 0.0030161999 +393 412 0.0028904998 +395 412 0.00025139982 +397 412 0.00037699984 +398 412 0.00037699984 +399 412 0.0001257 +401 412 0.00050269999 +402 412 0.068744481 +407 412 0.00037699984 +408 412 0.0001257 +409 412 0.0090485997 +410 412 0.00025139982 +412 412 0.030664798 +417 412 0.00025139982 +419 412 0.0001257 +421 412 0.00025139982 +428 412 0.00037699984 +430 412 0.00025139982 +437 412 0.0001257 +439 412 0.0016337999 +441 412 0.00037699984 +442 412 0.0001257 +443 412 0.0072891973 +444 412 0.00050269999 +445 412 0.0082945973 +446 412 0.0001257 +447 412 0.0015081 +450 412 0.0026391998 +452 412 0.0032676 +453 412 0.0017594998 +454 412 0.00025139982 +455 412 0.06736207 +457 412 0.004524298 +458 412 0.0007540998 +459 412 0.00050269999 +460 412 0.0007540998 +463 412 0.0064094998 +464 412 0.00025139982 +465 412 0.0006283999 +467 412 0.0071634986 +468 412 0.0060323998 +469 412 0.0031418998 +470 412 0.0035188999 +471 412 0.0006283999 +473 412 0.0001257 +477 412 0.0001257 +478 412 0.0007540998 +483 412 0.00037699984 +490 412 0.00025139982 +491 412 0.0016337999 +9 413 8.6699991e-05 +18 413 0.0001733 +60 413 0.0027731999 +77 413 0.00034669996 +82 413 8.6699991e-05 +83 413 8.6699991e-05 +84 413 8.6699991e-05 +108 413 8.6699991e-05 +113 413 0.0001733 +114 413 0.00025999988 +126 413 8.6699991e-05 +130 413 8.6699991e-05 +150 413 0.0001733 +156 413 8.6699991e-05 +160 413 0.0013865998 +161 413 8.6699991e-05 +165 413 0.0064996965 +171 413 0.00069329981 +172 413 8.6699991e-05 +181 413 8.6699991e-05 +189 413 0.0001733 +190 413 8.6699991e-05 +192 413 0.0001733 +194 413 8.6699991e-05 +196 413 8.6699991e-05 +198 413 0.0025998999 +200 413 8.6699991e-05 +203 413 8.6699991e-05 +204 413 0.0001733 +206 413 0.00051999977 +207 413 8.6699991e-05 +214 413 0.00077999989 +223 413 8.6699991e-05 +224 413 0.0018198998 +228 413 0.00086659985 +233 413 0.00077999989 +234 413 0.0044197999 +237 413 0.00051999977 +240 413 0.0042464994 +241 413 0.012306098 +252 413 0.0037264999 +253 413 0.00034669996 +270 413 8.6699991e-05 +277 413 0.013952699 +279 413 8.6699991e-05 +282 413 0.0050263964 +283 413 0.00086659985 +284 413 0.00060659996 +285 413 8.6699991e-05 +286 413 0.00025999988 +290 413 0.00034669996 +292 413 0.0021666 +293 413 0.0045930967 +294 413 0.00069329981 +295 413 0.0021666 +296 413 0.0042464994 +297 413 0.0012132998 +298 413 0.00060659996 +299 413 0.00051999977 +300 413 8.6699991e-05 +305 413 8.6699991e-05 +308 413 0.011179499 +312 413 0.010139499 +315 413 0.006672997 +317 413 0.00025999988 +318 413 0.00060659996 +319 413 0.00034669996 +320 413 0.0040730983 +321 413 0.00025999988 +322 413 0.0054596998 +325 413 8.6699991e-05 +326 413 0.006672997 +328 413 0.00025999988 +340 413 0.0099661984 +341 413 8.6699991e-05 +349 413 8.6699991e-05 +350 413 8.6699991e-05 +351 413 0.0030331998 +353 413 0.0025998999 +354 413 0.00025999988 +358 413 0.011959396 +359 413 0.00043329992 +369 413 0.012219399 +370 413 0.0001733 +371 413 0.0085795969 +372 413 0.0061529987 +385 413 0.00069329981 +386 413 0.007886298 +387 413 0.00025999988 +390 413 0.0077995993 +391 413 0.0015598999 +392 413 0.020625699 +393 413 0.041251399 +396 413 0.0033797999 +397 413 0.0001733 +402 413 0.00025999988 +403 413 0.0001733 +404 413 0.0012132998 +405 413 0.0061529987 +408 413 0.0011266 +413 413 0.016119197 +414 413 0.00025999988 +417 413 0.00034669996 +419 413 0.011006199 +420 413 0.00095329992 +421 413 8.6699991e-05 +422 413 0.0032931999 +423 413 8.6699991e-05 +424 413 8.6699991e-05 +430 413 8.6699991e-05 +431 413 8.6699991e-05 +433 413 8.6699991e-05 +434 413 8.6699991e-05 +435 413 8.6699991e-05 +438 413 0.0030331998 +443 413 0.0012998998 +444 413 0.0019931998 +445 413 0.0060663968 +446 413 8.6699991e-05 +447 413 0.0048530996 +448 413 8.6699991e-05 +450 413 0.0065863989 +452 413 0.0063263997 +453 413 0.0012998998 +454 413 0.00043329992 +455 413 0.025305498 +456 413 0.0012132998 +457 413 0.0032064999 +458 413 0.0011266 +459 413 0.0036397998 +460 413 0.0014732999 +463 413 0.018805798 +464 413 0.0018198998 +465 413 0.0025131998 +467 413 0.017332498 +468 413 0.0058930963 +469 413 0.010486197 +470 413 0.013086099 +471 413 0.0038131999 +472 413 0.0016466 +473 413 0.0001733 +477 413 8.6699991e-05 +478 413 0.0017332998 +483 413 0.0027731999 +489 413 0.0001733 +490 413 0.0012998998 +491 413 0.0025998999 +9 414 5.6499994e-05 +18 414 0.00011299999 +60 414 0.0029368999 +77 414 0.0003388999 +82 414 0.00016939999 +83 414 5.6499994e-05 +84 414 5.6499994e-05 +108 414 0.00011299999 +113 414 0.00011299999 +114 414 0.00028239982 +126 414 0.00022589999 +127 414 5.6499994e-05 +130 414 0.00011299999 +131 414 0.00011299999 +138 414 5.6499994e-05 +139 414 5.6499994e-05 +142 414 5.6499994e-05 +150 414 0.00073419977 +160 414 0.001186 +165 414 0.00022589999 +172 414 5.6499994e-05 +187 414 0.00011299999 +189 414 0.00022589999 +190 414 0.00011299999 +194 414 0.00022589999 +197 414 5.6499994e-05 +198 414 0.0045181997 +200 414 0.00011299999 +201 414 5.6499994e-05 +203 414 0.00011299999 +204 414 0.0030497999 +206 414 0.00028239982 +207 414 5.6499994e-05 +214 414 0.00045179995 +220 414 5.6499994e-05 +223 414 0.00011299999 +224 414 0.0057607964 +233 414 0.00011299999 +234 414 0.0051394999 +237 414 0.00056479988 +240 414 0.0028239 +241 414 0.0076244995 +242 414 0.00011299999 +252 414 0.0055347979 +253 414 5.6499994e-05 +270 414 0.00011299999 +271 414 0.00028239982 +272 414 0.00011299999 +277 414 0.018637698 +282 414 0.010787297 +283 414 0.0012424998 +284 414 0.0005082998 +285 414 0.00022589999 +286 414 0.00056479988 +289 414 0.00011299999 +290 414 0.00039529987 +292 414 0.0085846968 +293 414 0.0031627999 +294 414 0.0045181997 +295 414 0.0027673999 +296 414 0.012029797 +297 414 0.011408597 +298 414 0.0022025998 +299 414 5.6499994e-05 +300 414 5.6499994e-05 +307 414 0.00022589999 +308 414 0.0016943 +312 414 0.012820497 +313 414 0.00039529987 +315 414 0.0081327967 +317 414 5.6499994e-05 +318 414 5.6499994e-05 +319 414 5.6499994e-05 +320 414 0.0068337992 +321 414 0.00016939999 +322 414 0.0053088963 +324 414 0.00039529987 +325 414 0.00011299999 +326 414 0.0056477971 +328 414 5.6499994e-05 +339 414 5.6499994e-05 +340 414 0.0048570968 +341 414 5.6499994e-05 +343 414 0.00016939999 +344 414 5.6499994e-05 +348 414 5.6499994e-05 +349 414 0.00016939999 +350 414 0.00016939999 +351 414 0.0011296 +353 414 0.00011299999 +354 414 0.00079069985 +356 414 5.6499994e-05 +357 414 0.00022589999 +358 414 0.012538098 +359 414 0.0019202998 +369 414 0.025923397 +370 414 0.002598 +371 414 0.0059301965 +372 414 0.0081892982 +373 414 0.0018072999 +376 414 0.00067769992 +384 414 5.6499994e-05 +386 414 0.0081892982 +387 414 0.00011299999 +389 414 0.00011299999 +390 414 0.0010730999 +391 414 0.0014119998 +392 414 0.0075115971 +393 414 0.030215699 +394 414 5.6499994e-05 +395 414 0.00062129996 +396 414 0.00096009998 +397 414 0.00022589999 +402 414 0.0020897 +404 414 0.00016939999 +405 414 0.0003388999 +413 414 0.0027673999 +414 414 0.0079633966 +415 414 0.00011299999 +416 414 5.6499994e-05 +417 414 0.00056479988 +419 414 0.0024285999 +420 414 0.00067769992 +421 414 5.6499994e-05 +422 414 0.0022590999 +423 414 5.6499994e-05 +424 414 5.6499994e-05 +425 414 5.6499994e-05 +430 414 0.00011299999 +431 414 5.6499994e-05 +433 414 5.6499994e-05 +434 414 5.6499994e-05 +435 414 5.6499994e-05 +438 414 5.6499994e-05 +441 414 5.6499994e-05 +442 414 0.00011299999 +443 414 0.0012989999 +444 414 0.00073419977 +445 414 0.0059301965 +446 414 0.00011299999 +447 414 0.0018072999 +448 414 5.6499994e-05 +450 414 0.0070032999 +452 414 0.0058736987 +453 414 0.0011296 +454 414 0.0003388999 +455 414 0.0194849 +456 414 0.0010165998 +457 414 0.0032756999 +458 414 0.0016943 +459 414 0.0012989999 +460 414 0.0014683998 +463 414 0.011126198 +464 414 0.0009035999 +465 414 0.0021461998 +467 414 0.018468298 +468 414 0.0058736987 +469 414 0.011747397 +470 414 0.013215899 +471 414 0.0049700998 +472 414 5.6499994e-05 +473 414 0.0003388999 +477 414 0.00016939999 +478 414 0.0018072999 +483 414 0.0030497999 +489 414 0.00016939999 +490 414 0.0012989999 +491 414 0.0096012987 +21 415 0.00058899983 +60 415 0.0026505999 +108 415 0.00014729999 +114 415 0.00014729999 +126 415 0.00014729999 +150 415 0.00014729999 +160 415 0.0010307999 +175 415 0.0002944998 +189 415 0.0002944998 +190 415 0.00014729999 +192 415 0.00014729999 +193 415 0.0007362999 +194 415 0.00014729999 +196 415 0.00014729999 +198 415 0.0069208965 +200 415 0.00014729999 +203 415 0.00014729999 +204 415 0.0016198 +206 415 0.00014729999 +207 415 0.00014729999 +224 415 0.010013297 +233 415 0.00014729999 +234 415 0.0044175982 +237 415 0.0007362999 +240 415 0.0044175982 +241 415 0.019731998 +252 415 0.0014724999 +262 415 0.00044179987 +270 415 0.0002944998 +271 415 0.00014729999 +272 415 0.00014729999 +277 415 0.015608899 +282 415 0.0054483972 +283 415 0.0007362999 +284 415 0.00058899983 +286 415 0.00058899983 +290 415 0.00044179987 +292 415 0.024296898 +293 415 0.0051538981 +294 415 0.0016198 +295 415 0.0076571964 +296 415 0.0085406974 +297 415 0.0050065964 +298 415 0.00044179987 +308 415 0.0002944998 +312 415 0.019879296 +313 415 0.00014729999 +315 415 0.0098659992 +317 415 0.00014729999 +318 415 0.00014729999 +320 415 0.0067736991 +322 415 0.012222096 +324 415 0.0007362999 +326 415 0.0014724999 +340 415 0.0070681982 +351 415 0.0002944998 +352 415 0.00014729999 +357 415 0.00014729999 +358 415 0.0058900975 +366 415 0.00088349986 +369 415 0.017375898 +370 415 0.0016198 +371 415 0.0044175982 +372 415 0.0041230991 +373 415 0.0042703971 +376 415 0.0007362999 +386 415 0.016786899 +387 415 0.0002944998 +390 415 0.00014729999 +391 415 0.00088349986 +392 415 0.0032396 +393 415 0.010749497 +402 415 0.0011779999 +408 415 0.0002944998 +414 415 0.010896798 +415 415 0.0060373992 +417 415 0.00058899983 +419 415 0.0013253 +421 415 0.00014729999 +422 415 0.0033867999 +430 415 0.00014729999 +433 415 0.00014729999 +434 415 0.00014729999 +441 415 0.0042703971 +442 415 0.0051538981 +443 415 0.0016198 +444 415 0.0025032999 +445 415 0.010749497 +446 415 0.0002944998 +447 415 0.0082461983 +450 415 0.0073626973 +452 415 0.0050065964 +453 415 0.0013253 +454 415 0.00058899983 +455 415 0.024885897 +456 415 0.00088349986 +457 415 0.0030922999 +458 415 0.0013253 +459 415 0.0013253 +460 415 0.0014724999 +463 415 0.010749497 +464 415 0.00088349986 +465 415 0.0025032999 +467 415 0.015903398 +468 415 0.0075098984 +469 415 0.0070681982 +470 415 0.0076571964 +471 415 0.0044175982 +473 415 0.00014729999 +478 415 0.0019142998 +483 415 0.0032396 +489 415 0.00014729999 +490 415 0.0007362999 +491 415 0.0013253 +6 416 9.8599994e-05 +9 416 9.8599994e-05 +60 416 0.0020699999 +82 416 0.00049289991 +102 416 0.00019709999 +104 416 9.8599994e-05 +107 416 9.8599994e-05 +108 416 9.8599994e-05 +114 416 0.00019709999 +117 416 0.00019709999 +120 416 9.8599994e-05 +126 416 9.8599994e-05 +130 416 0.00098569994 +131 416 0.00039429986 +135 416 9.8599994e-05 +137 416 9.8599994e-05 +138 416 0.00019709999 +139 416 0.0013799998 +142 416 0.00019709999 +150 416 0.0027599998 +159 416 0.0020699999 +160 416 0.0029570998 +161 416 9.8599994e-05 +165 416 0.0056184977 +170 416 0.0030556999 +171 416 9.8599994e-05 +178 416 9.8599994e-05 +184 416 9.8599994e-05 +187 416 0.00029569981 +188 416 9.8599994e-05 +189 416 9.8599994e-05 +190 416 9.8599994e-05 +192 416 0.0006899999 +193 416 0.0030556999 +194 416 0.00029569981 +198 416 0.0068013966 +200 416 9.8599994e-05 +203 416 9.8599994e-05 +204 416 0.00019709999 +206 416 0.00039429986 +207 416 9.8599994e-05 +214 416 0.0059141964 +217 416 0.00019709999 +223 416 0.00049289991 +224 416 0.0006899999 +228 416 0.0048299991 +229 416 0.00019709999 +233 416 0.0045342967 +234 416 0.0041399971 +237 416 0.00059139985 +240 416 0.011631299 +241 416 0.023361299 +242 416 0.0030556999 +252 416 0.0067027994 +253 416 0.0059141964 +268 416 9.8599994e-05 +270 416 0.00019709999 +271 416 9.8599994e-05 +272 416 0.00078859995 +277 416 0.019221298 +279 416 9.8599994e-05 +282 416 0.0011827999 +283 416 0.00019709999 +284 416 9.8599994e-05 +286 416 0.018629897 +290 416 0.0189256 +292 416 0.00019709999 +293 416 0.0013799998 +294 416 0.00039429986 +295 416 0.00019709999 +296 416 0.00019709999 +297 416 0.00019709999 +300 416 0.00049289991 +307 416 0.00019709999 +308 416 9.8599994e-05 +312 416 0.015179899 +314 416 0.00019709999 +315 416 0.014588498 +317 416 0.0029570998 +319 416 0.0089698993 +320 416 0.0087727979 +321 416 0.0094627999 +322 416 0.00049289991 +324 416 0.00029569981 +325 416 0.013405599 +326 416 0.0045342967 +328 416 9.8599994e-05 +340 416 0.006407097 +345 416 0.00019709999 +350 416 0.00039429986 +351 416 0.00019709999 +352 416 0.00019709999 +354 416 0.00039429986 +356 416 9.8599994e-05 +358 416 0.0028585999 +368 416 9.8599994e-05 +369 416 0.00049289991 +372 416 0.00098569994 +375 416 9.8599994e-05 +386 416 0.00039429986 +387 416 9.8599994e-05 +391 416 0.00019709999 +392 416 0.00019709999 +393 416 0.0010843 +395 416 9.8599994e-05 +396 416 0.0027599998 +397 416 9.8599994e-05 +398 416 9.8599994e-05 +402 416 0.00029569981 +405 416 9.8599994e-05 +413 416 9.8599994e-05 +414 416 0.0072941966 +416 416 0.0042384975 +417 416 0.0006899999 +419 416 9.8599994e-05 +421 416 0.00098569994 +422 416 0.0027599998 +430 416 9.8599994e-05 +433 416 9.8599994e-05 +434 416 9.8599994e-05 +441 416 9.8599994e-05 +442 416 0.00029569981 +443 416 0.0023657 +444 416 0.0040413998 +445 416 0.007589899 +446 416 0.00019709999 +447 416 0.0041399971 +448 416 9.8599994e-05 +450 416 0.0068013966 +452 416 0.0052241981 +453 416 0.0015770998 +454 416 0.0036470999 +455 416 0.028191198 +456 416 0.00088709989 +457 416 0.0042384975 +458 416 0.0010843 +459 416 0.00088709989 +460 416 0.0014785999 +463 416 0.015475597 +464 416 0.0051256977 +465 416 0.0019713999 +467 416 0.016362697 +468 416 0.014391299 +469 416 0.0088713989 +470 416 0.0098570995 +471 416 0.0042384975 +473 416 0.00019709999 +477 416 0.00059139985 +478 416 0.0016756998 +479 416 0.0012814 +483 416 0.0010843 +489 416 0.00019709999 +490 416 0.0014785999 +491 416 0.0030556999 +4 417 0.00068269996 +9 417 8.5299995e-05 +60 417 0.0022187999 +82 417 0.0093872994 +83 417 8.5299995e-05 +84 417 8.5299995e-05 +104 417 0.00034139981 +108 417 8.5299995e-05 +113 417 0.00017069999 +114 417 0.00025599985 +117 417 0.0026454998 +120 417 8.5299995e-05 +126 417 8.5299995e-05 +130 417 0.023894899 +131 417 0.0180065 +132 417 0.00051199994 +133 417 0.0021334998 +135 417 0.0028161998 +137 417 8.5299995e-05 +138 417 0.011862099 +139 417 0.0052909963 +141 417 8.5299995e-05 +142 417 0.010923397 +143 417 0.00025599985 +149 417 0.0021334998 +150 417 0.00025599985 +158 417 0.00017069999 +160 417 0.0016213998 +169 417 8.5299995e-05 +187 417 0.021334697 +188 417 0.0040962994 +189 417 0.00017069999 +190 417 8.5299995e-05 +192 417 0.0034989 +193 417 8.5299995e-05 +194 417 0.0039255992 +197 417 8.5299995e-05 +198 417 0.012288798 +200 417 8.5299995e-05 +203 417 0.00017069999 +204 417 0.00017069999 +206 417 0.00017069999 +207 417 8.5299995e-05 +208 417 8.5299995e-05 +214 417 0.0017068 +219 417 0.00059739989 +221 417 0.00025599985 +223 417 0.0029014999 +224 417 0.016384996 +226 417 0.00034139981 +227 417 0.00025599985 +228 417 0.00025599985 +229 417 0.0046935976 +231 417 8.5299995e-05 +232 417 0.00051199994 +233 417 8.5299995e-05 +234 417 0.0040962994 +237 417 0.00059739989 +240 417 0.012032799 +241 417 0.021334697 +243 417 0.00017069999 +252 417 0.0084484965 +253 417 0.00059739989 +268 417 0.00076799979 +271 417 0.0052056983 +277 417 0.016214397 +282 417 0.0043522976 +283 417 0.00034139981 +284 417 0.00017069999 +286 417 8.5299995e-05 +287 417 0.00017069999 +290 417 0.00059739989 +292 417 0.00017069999 +293 417 0.0066563971 +295 417 8.5299995e-05 +296 417 0.0023894999 +297 417 0.00042669987 +300 417 0.0073390976 +312 417 0.0130568 +313 417 0.00017069999 +314 417 8.5299995e-05 +315 417 0.00017069999 +320 417 8.5299995e-05 +325 417 0.00017069999 +326 417 0.00025599985 +340 417 8.5299995e-05 +347 417 8.5299995e-05 +351 417 8.5299995e-05 +354 417 8.5299995e-05 +356 417 8.5299995e-05 +357 417 8.5299995e-05 +358 417 0.0023041 +372 417 0.0019627998 +387 417 8.5299995e-05 +391 417 8.5299995e-05 +393 417 0.0088751987 +394 417 8.5299995e-05 +396 417 8.5299995e-05 +397 417 0.00017069999 +402 417 0.0010241 +404 417 8.5299995e-05 +416 417 0.012374099 +417 417 0.015787698 +421 417 0.00076799979 +422 417 0.00017069999 +423 417 8.5299995e-05 +430 417 0.00025599985 +431 417 8.5299995e-05 +433 417 8.5299995e-05 +434 417 8.5299995e-05 +437 417 8.5299995e-05 +442 417 0.00025599985 +443 417 0.0039255992 +444 417 0.0040108971 +445 417 0.015275598 +446 417 0.00025599985 +447 417 0.0032428999 +448 417 8.5299995e-05 +450 417 0.0067417994 +452 417 0.0048642978 +453 417 0.0015360999 +454 417 0.00076799979 +455 417 0.040109199 +456 417 0.00093869981 +457 417 0.0045229979 +458 417 0.00093869981 +459 417 0.00068269996 +460 417 0.0014507999 +463 417 0.0093872994 +464 417 0.0042668991 +465 417 0.0015360999 +467 417 0.019969299 +468 417 0.027479097 +469 417 0.0071684979 +470 417 0.0076804981 +471 417 0.0040108971 +473 417 0.00017069999 +477 417 0.00051199994 +478 417 0.0013653999 +479 417 0.0028161998 +483 417 0.0017920998 +489 417 0.00017069999 +490 417 0.0015360999 +491 417 0.0018775 +24 418 0.0016246999 +60 418 0.0016246999 +82 418 0.00054159993 +108 418 0.00027079997 +114 418 0.00054159993 +126 418 0.00027079997 +130 418 0.0010831 +131 418 0.00081229978 +138 418 0.00054159993 +139 418 0.0021662998 +142 418 0.00054159993 +160 418 0.00027079997 +165 418 0.0010831 +187 418 0.00081229978 +188 418 0.00027079997 +192 418 0.00027079997 +193 418 0.0086649992 +194 418 0.00054159993 +198 418 0.0043324977 +206 418 0.00054159993 +224 418 0.00054159993 +229 418 0.00027079997 +233 418 0.0021662998 +234 418 0.003791 +237 418 0.00054159993 +240 418 0.00054159993 +241 418 0.0075818971 +252 418 0.00054159993 +268 418 0.0059571974 +270 418 0.010560498 +271 418 0.00027079997 +272 418 0.00081229978 +277 418 0.025995098 +282 418 0.00027079997 +290 418 0.13647437 +293 418 0.0016246999 +294 418 0.030327599 +300 418 0.00027079997 +312 418 0.00054159993 +320 418 0.00027079997 +340 418 0.00081229978 +358 418 0.0024369999 +387 418 0.00027079997 +392 418 0.00027079997 +393 418 0.0016246999 +395 418 0.010831296 +396 418 0.0078526996 +398 418 0.0092065968 +402 418 0.00027079997 +416 418 0.00054159993 +417 418 0.0013538999 +418 418 0.00027079997 +422 418 0.00027079997 +441 418 0.011372898 +443 418 0.0024369999 +444 418 0.013809897 +445 418 0.017600898 +446 418 0.00027079997 +447 418 0.012997597 +450 418 0.0056863986 +452 418 0.0046032965 +453 418 0.0010831 +455 418 0.035472497 +456 418 0.00027079997 +457 418 0.0046032965 +458 418 0.0013538999 +459 418 0.00081229978 +460 418 0.0013538999 +463 418 0.013539098 +464 418 0.0016246999 +465 418 0.011102099 +467 418 0.013809897 +468 418 0.071757376 +469 418 0.0070402995 +470 418 0.0078526996 +471 418 0.0043324977 +473 418 0.00027079997 +477 418 0.00054159993 +478 418 0.0013538999 +483 418 0.0013538999 +489 418 0.00027079997 +490 418 0.00081229978 +18 419 0.00021679999 +22 419 0.00032519992 +60 419 0.0010841 +108 419 0.0001084 +114 419 0.00021679999 +126 419 0.0001084 +130 419 0.0001084 +150 419 0.0001084 +160 419 0.0014093998 +171 419 0.0001084 +187 419 0.0001084 +189 419 0.0001084 +190 419 0.0001084 +194 419 0.00021679999 +198 419 0.010624498 +203 419 0.0001084 +204 419 0.0001084 +206 419 0.00021679999 +221 419 0.0001084 +224 419 0.0092150979 +234 419 0.0026018999 +237 419 0.00032519992 +240 419 0.00043369993 +241 419 0.018863797 +250 419 0.0042280965 +252 419 0.0030355998 +277 419 0.015828297 +282 419 0.0001084 +284 419 0.00065049995 +290 419 0.00097569986 +292 419 0.013659999 +293 419 0.00021679999 +294 419 0.015828297 +295 419 0.0017345999 +296 419 0.0001084 +297 419 0.0001084 +298 419 0.0017345999 +308 419 0.0001084 +312 419 0.0203816 +315 419 0.015394598 +317 419 0.0001084 +320 419 0.011274897 +322 419 0.0035775998 +326 419 0.0039028998 +340 419 0.0026018999 +356 419 0.0001084 +358 419 0.0020597999 +359 419 0.0001084 +361 419 0.0001084 +363 419 0.0001084 +369 419 0.00021679999 +370 419 0.00054209982 +371 419 0.00065049995 +372 419 0.0076972991 +373 419 0.0001084 +380 419 0.0001084 +385 419 0.00075889984 +386 419 0.00043369993 +387 419 0.0001084 +390 419 0.00032519992 +392 419 0.00043369993 +393 419 0.0014093998 +398 419 0.0033608 +402 419 0.0001084 +413 419 0.003144 +414 419 0.00021679999 +415 419 0.0001084 +417 419 0.00054209982 +419 419 0.22820896 +421 419 0.0001084 +422 419 0.00021679999 +423 419 0.0052037984 +424 419 0.0070467964 +426 419 0.0057458989 +441 419 0.00021679999 +442 419 0.0028186999 +443 419 0.0014093998 +444 419 0.004119698 +445 419 0.015177798 +447 419 0.0062878989 +450 419 0.0058542974 +452 419 0.0034691999 +453 419 0.00065049995 +454 419 0.00032519992 +455 419 0.048460498 +456 419 0.00032519992 +457 419 0.0015177999 +458 419 0.00097569986 +459 419 0.00032519992 +460 419 0.00097569986 +463 419 0.0091066994 +464 419 0.0052037984 +465 419 0.012575898 +467 419 0.018213399 +468 419 0.034475297 +469 419 0.0037943998 +470 419 0.004119698 +471 419 0.0021682999 +473 419 0.0001084 +477 419 0.00043369993 +478 419 0.0011924999 +479 419 0.00043369993 +483 419 0.0016261998 +489 419 0.0001084 +490 419 0.00032519992 +491 419 0.00065049995 +60 420 0.0026131 +82 420 0.00016329999 +108 420 0.00016329999 +114 420 0.00016329999 +126 420 0.00016329999 +187 420 0.00016329999 +189 420 0.00016329999 +190 420 0.00016329999 +194 420 0.00032659993 +198 420 0.0019597998 +203 420 0.00016329999 +206 420 0.00065329997 +214 420 0.00048999977 +224 420 0.0037562998 +234 420 0.0042462982 +237 420 0.00048999977 +240 420 0.00016329999 +241 420 0.056344897 +252 420 0.014208697 +270 420 0.00016329999 +273 420 0.00048999977 +276 420 0.00016329999 +277 420 0.0073492974 +282 420 0.0037562998 +283 420 0.00016329999 +284 420 0.00016329999 +290 420 0.0011431999 +292 420 0.00097989989 +293 420 0.0039195977 +294 420 0.0055527985 +295 420 0.00081659993 +296 420 0.0037562998 +297 420 0.00016329999 +298 420 0.017148498 +299 420 0.00016329999 +308 420 0.00097989989 +312 420 0.0029396999 +315 420 0.011105698 +320 420 0.00097989989 +321 420 0.00016329999 +322 420 0.00032659993 +324 420 0.00032659993 +326 420 0.0019597998 +340 420 0.00065329997 +351 420 0.00065329997 +352 420 0.00016329999 +356 420 0.00016329999 +358 420 0.0032664 +359 420 0.00016329999 +366 420 0.0014698999 +369 420 0.0019597998 +370 420 0.00016329999 +371 420 0.00032659993 +372 420 0.0024497998 +373 420 0.00065329997 +386 420 0.00081659993 +387 420 0.00032659993 +390 420 0.0039195977 +391 420 0.00065329997 +392 420 0.017148498 +393 420 0.036746699 +398 420 0.00016329999 +402 420 0.00032659993 +404 420 0.00097989989 +405 420 0.00048999977 +413 420 0.00016329999 +414 420 0.00016329999 +415 420 0.00016329999 +417 420 0.00032659993 +419 420 0.00032659993 +420 420 0.070880294 +421 420 0.0017964998 +422 420 0.00065329997 +430 420 0.00016329999 +434 420 0.00016329999 +435 420 0.005879499 +442 420 0.00065329997 +443 420 0.00081659993 +444 420 0.00081659993 +445 420 0.010778997 +447 420 0.0026131 +450 420 0.0053894967 +452 420 0.0057161972 +453 420 0.00048999977 +454 420 0.00016329999 +455 420 0.035276797 +456 420 0.00081659993 +457 420 0.0037562998 +458 420 0.0017964998 +459 420 0.00065329997 +460 420 0.00097989989 +463 420 0.0097990967 +464 420 0.0011431999 +465 420 0.0011431999 +467 420 0.017311797 +468 420 0.0032664 +469 420 0.010778997 +470 420 0.0125755 +471 420 0.0037562998 +473 420 0.00032659993 +477 420 0.00032659993 +478 420 0.0014698999 +483 420 0.0019597998 +489 420 0.00016329999 +490 420 0.0019597998 +491 420 0.0026131 +60 421 0.0025086999 +108 421 0.000193 +114 421 0.00038599991 +126 421 0.000193 +150 421 0.000193 +187 421 0.00038599991 +189 421 0.000193 +190 421 0.000193 +192 421 0.000193 +194 421 0.00038599991 +198 421 0.0019297998 +200 421 0.000193 +203 421 0.000193 +204 421 0.000193 +206 421 0.00057889987 +214 421 0.0011578999 +223 421 0.000193 +224 421 0.022771098 +234 421 0.0065611973 +237 421 0.00077189994 +240 421 0.000193 +241 421 0.029718298 +252 421 0.030490197 +270 421 0.0034735999 +277 421 0.00096489978 +284 421 0.000193 +290 421 0.041489799 +294 421 0.00038599991 +296 421 0.000193 +312 421 0.000193 +315 421 0.000193 +326 421 0.000193 +356 421 0.000193 +358 421 0.0032805998 +387 421 0.000193 +392 421 0.00057889987 +393 421 0.00038599991 +402 421 0.00038599991 +417 421 0.00057889987 +420 421 0.00038599991 +421 421 0.060401399 +422 421 0.0011578999 +442 421 0.020262398 +443 421 0.0021227 +444 421 0.00057889987 +445 421 0.0119645 +446 421 0.00038599991 +447 421 0.0028945999 +450 421 0.0071400963 +452 421 0.0048243999 +453 421 0.0025086999 +454 421 0.0011578999 +455 421 0.07043606 +456 421 0.00077189994 +457 421 0.0040524974 +458 421 0.0017368 +459 421 0.00057889987 +460 421 0.0015437999 +463 421 0.0121575 +464 421 0.00077189994 +465 421 0.0017368 +467 421 0.016595896 +468 421 0.0144732 +469 421 0.0073330998 +470 421 0.0082979985 +471 421 0.0048243999 +473 421 0.000193 +477 421 0.00038599991 +478 421 0.0023156998 +483 421 0.0021227 +489 421 0.000193 +490 421 0.00077189994 +491 421 0.00096489978 +9 422 1.8599996e-05 +13 422 9.3199997e-05 +16 422 1.8599996e-05 +18 422 9.3199997e-05 +21 422 5.5899989e-05 +22 422 0.0010809 +24 422 0.00026089977 +60 422 0.0057770982 +79 422 1.8599996e-05 +82 422 0.00013049999 +83 422 1.8599996e-05 +84 422 1.8599996e-05 +104 422 9.3199997e-05 +108 422 3.7299993e-05 +113 422 5.5899989e-05 +114 422 9.3199997e-05 +119 422 3.7299993e-05 +120 422 0.00031679985 +126 422 5.5899989e-05 +127 422 1.8599996e-05 +130 422 7.45e-05 +131 422 3.7299993e-05 +132 422 1.8599996e-05 +135 422 0.00054039992 +139 422 3.7299993e-05 +142 422 1.8599996e-05 +143 422 1.8599996e-05 +150 422 0.00029819994 +151 422 1.8599996e-05 +158 422 1.8599996e-05 +159 422 0.00014909999 +160 422 0.00050319987 +162 422 1.8599996e-05 +171 422 5.5899989e-05 +184 422 1.8599996e-05 +186 422 0.00031679985 +187 422 0.016548596 +188 422 0.00013049999 +189 422 5.5899989e-05 +190 422 5.5899989e-05 +192 422 0.0084606968 +193 422 0.00013049999 +194 422 9.3199997e-05 +196 422 1.8599996e-05 +197 422 1.8599996e-05 +198 422 0.0081810988 +200 422 7.45e-05 +201 422 3.7299993e-05 +203 422 5.5899989e-05 +204 422 7.45e-05 +206 422 0.00011179999 +207 422 3.7299993e-05 +208 422 3.7299993e-05 +209 422 1.8599996e-05 +214 422 0.043607898 +218 422 0.00018639999 +219 422 0.00011179999 +221 422 9.3199997e-05 +223 422 0.003950797 +224 422 0.00040999986 +225 422 1.8599996e-05 +230 422 1.8599996e-05 +231 422 3.7299993e-05 +233 422 7.45e-05 +234 422 0.0028512999 +237 422 0.0002423 +240 422 0.00089449994 +241 422 0.012765598 +248 422 1.8599996e-05 +250 422 3.7299993e-05 +252 422 0.0011741 +254 422 1.8599996e-05 +270 422 1.8599996e-05 +277 422 0.0196236 +279 422 1.8599996e-05 +284 422 3.7299993e-05 +290 422 0.0031307999 +292 422 0.00076409988 +293 422 0.0010249999 +294 422 0.014014199 +295 422 5.5899989e-05 +296 422 0.0051993988 +297 422 1.8599996e-05 +298 422 0.0030375998 +300 422 1.8599996e-05 +301 422 0.00013049999 +308 422 3.7299993e-05 +312 422 0.0024785998 +314 422 1.8599996e-05 +315 422 0.0040066987 +318 422 7.45e-05 +320 422 0.00013049999 +321 422 3.7299993e-05 +322 422 0.00096909981 +325 422 0.00050319987 +326 422 0.0056838989 +340 422 5.5899989e-05 +341 422 1.8599996e-05 +347 422 1.8599996e-05 +350 422 1.8599996e-05 +351 422 1.8599996e-05 +354 422 0.0030003998 +356 422 0.00022359999 +358 422 0.0013790999 +359 422 3.7299993e-05 +361 422 1.8599996e-05 +363 422 3.7299993e-05 +369 422 9.3199997e-05 +370 422 0.00018639999 +371 422 1.8599996e-05 +372 422 0.0031494999 +384 422 0.0017704 +386 422 5.5899989e-05 +387 422 5.5899989e-05 +390 422 0.00020499999 +391 422 7.45e-05 +392 422 0.017554998 +393 422 0.0056652986 +394 422 1.8599996e-05 +396 422 0.00014909999 +397 422 1.8599996e-05 +398 422 1.8599996e-05 +402 422 0.00011179999 +404 422 5.5899989e-05 +405 422 1.8599996e-05 +413 422 3.7299993e-05 +417 422 0.00018639999 +419 422 0.0030748998 +420 422 0.0074542984 +421 422 1.8599996e-05 +422 422 0.030245997 +423 422 5.5899989e-05 +424 422 3.7299993e-05 +425 422 1.8599996e-05 +426 422 3.7299993e-05 +427 422 1.8599996e-05 +428 422 1.8599996e-05 +430 422 5.5899989e-05 +431 422 1.8599996e-05 +432 422 1.8599996e-05 +433 422 3.7299993e-05 +434 422 5.5899989e-05 +435 422 0.00050319987 +438 422 0.00048449985 +441 422 0.00035409979 +442 422 0.0022548998 +443 422 0.0028698999 +444 422 0.0012299998 +445 422 0.0047520995 +446 422 0.00093179988 +447 422 0.0044166967 +448 422 1.8599996e-05 +449 422 1.8599996e-05 +450 422 0.004304897 +452 422 0.0029630999 +453 422 0.00089449994 +454 422 0.00095039979 +455 422 0.0232016 +456 422 0.00061499979 +457 422 0.0073424987 +458 422 0.0010809 +459 422 0.0032984999 +460 422 0.0012486 +463 422 0.0079201981 +464 422 0.0017889999 +465 422 0.0038949 +467 422 0.018766299 +468 422 0.0197354 +469 422 0.0050502978 +470 422 0.0056838989 +471 422 0.0015280999 +472 422 0.00018639999 +473 422 0.00011179999 +477 422 0.00046589994 +478 422 0.003950797 +479 422 0.0016027 +483 422 0.00098769995 +489 422 9.3199997e-05 +490 422 0.0004472998 +491 422 0.00011179999 +9 423 9.8699995e-05 +18 423 0.00019729999 +24 423 9.8699995e-05 +82 423 9.8699995e-05 +108 423 9.8699995e-05 +114 423 0.00019729999 +126 423 9.8699995e-05 +150 423 9.8699995e-05 +171 423 0.00019729999 +189 423 9.8699995e-05 +190 423 9.8699995e-05 +192 423 9.8699995e-05 +194 423 9.8699995e-05 +196 423 9.8699995e-05 +198 423 0.0057226978 +200 423 9.8699995e-05 +203 423 9.8699995e-05 +204 423 9.8699995e-05 +206 423 9.8699995e-05 +207 423 9.8699995e-05 +214 423 9.8699995e-05 +224 423 9.8699995e-05 +234 423 0.0022693998 +237 423 0.00019729999 +240 423 9.8699995e-05 +241 423 0.0019733999 +250 423 0.013418797 +252 423 0.0010853 +270 423 0.0031573998 +276 423 0.0095707998 +277 423 0.00069069979 +284 423 9.8699995e-05 +290 423 0.20404536 +292 423 0.00049329991 +294 423 0.057128798 +298 423 0.0011839999 +312 423 0.00019729999 +315 423 0.00019729999 +317 423 0.00029599993 +320 423 0.00019729999 +325 423 0.0070053972 +326 423 9.8699995e-05 +356 423 9.8699995e-05 +358 423 0.0012826999 +372 423 9.8699995e-05 +387 423 9.8699995e-05 +402 423 9.8699995e-05 +417 423 0.00049329991 +419 423 0.0054266974 +421 423 9.8699995e-05 +422 423 9.8699995e-05 +423 423 0.0059200972 +424 423 0.11909229 +426 423 0.00049329991 +430 423 9.8699995e-05 +433 423 9.8699995e-05 +434 423 9.8699995e-05 +438 423 0.0019733999 +441 423 9.8699995e-05 +442 423 0.0022693998 +443 423 0.0013813998 +444 423 0.0039466992 +445 423 0.0063147992 +447 423 0.005130697 +450 423 0.010162797 +452 423 0.0026639998 +453 423 0.00019729999 +454 423 0.0034534 +455 423 0.051406 +456 423 0.00039469986 +457 423 0.0042426996 +458 423 0.00078929984 +459 423 0.00039469986 +460 423 0.00098669995 +463 423 0.0263444 +464 423 0.0073013976 +465 423 0.0012826999 +467 423 0.014800198 +468 423 0.026640397 +469 423 0.0066107996 +470 423 0.0073013976 +471 423 0.0018747 +473 423 0.00019729999 +477 423 9.8699995e-05 +478 423 0.0011839999 +479 423 0.00019729999 +483 423 0.0021706999 +489 423 9.8699995e-05 +490 423 0.0049333982 +491 423 0.00088799978 +24 424 0.013278097 +114 424 0.0001428 +131 424 0.0001428 +171 424 0.0001428 +198 424 0.0041405 +206 424 0.00028559985 +214 424 0.011707596 +234 424 0.0011421998 +237 424 0.0001428 +241 424 0.00028559985 +250 424 0.00085669989 +270 424 0.0098514967 +272 424 0.0001428 +276 424 0.0068531968 +277 424 0.046402097 +279 424 0.0001428 +286 424 0.0001428 +287 424 0.0001428 +288 424 0.0001428 +290 424 0.022130199 +291 424 0.0001428 +292 424 0.0068531968 +294 424 0.0418332 +295 424 0.0001428 +298 424 0.00042829989 +308 424 0.0001428 +317 424 0.0001428 +325 424 0.00042829989 +326 424 0.0001428 +358 424 0.00042829989 +373 424 0.00042829989 +393 424 0.0001428 +417 424 0.0001428 +419 424 0.00042829989 +423 424 0.0025699998 +424 424 0.022701297 +426 424 0.0001428 +438 424 0.0001428 +441 424 0.0011421998 +442 424 0.00028559985 +443 424 0.0044259988 +444 424 0.00028559985 +445 424 0.015848096 +446 424 0.0011421998 +447 424 0.0052826963 +450 424 0.0019989 +452 424 0.0017132999 +453 424 0.0001428 +454 424 0.0001428 +455 424 0.056253597 +457 424 0.0019989 +458 424 0.0001428 +459 424 0.0001428 +460 424 0.0021415998 +463 424 0.0042832978 +464 424 0.00057109981 +465 424 0.00028559985 +467 424 0.0032837999 +468 424 0.0042832978 +469 424 0.0018560998 +470 424 0.0019989 +471 424 0.00071389996 +478 424 0.00028559985 +483 424 0.0019989 +490 424 0.37592798 +491 424 0.0054254979 +22 425 0.00091299997 +60 425 0.0021301999 +108 425 0.00030429987 +114 425 0.00060859998 +126 425 0.00030429987 +171 425 0.027084596 +194 425 0.00030429987 +198 425 0.024649996 +206 425 0.00060859998 +214 425 0.028910499 +234 425 0.0039561987 +237 425 0.00030429987 +240 425 0.00030429987 +241 425 0.0219111 +250 425 0.00030429987 +270 425 0.018563598 +272 425 0.00060859998 +276 425 0.0097383 +277 425 0.079123557 +279 425 0.00060859998 +284 425 0.00030429987 +290 425 0.0608643 +292 425 0.037127197 +293 425 0.00060859998 +294 425 0.06299448 +297 425 0.013390098 +298 425 0.00060859998 +312 425 0.00060859998 +315 425 0.00060859998 +317 425 0.00030429987 +319 425 0.00030429987 +320 425 0.00030429987 +326 425 0.011259899 +339 425 0.00030429987 +340 425 0.00060859998 +353 425 0.00030429987 +358 425 0.0015215999 +387 425 0.00030429987 +417 425 0.00060859998 +424 425 0.00091299997 +425 425 0.0051734969 +426 425 0.00030429987 +441 425 0.00030429987 +443 425 0.0063906983 +444 425 0.0051734969 +445 425 0.013998799 +446 425 0.00060859998 +447 425 0.0146074 +450 425 0.0045647994 +452 425 0.0066950992 +453 425 0.0015215999 +454 425 0.00091299997 +455 425 0.032562397 +456 425 0.00030429987 +457 425 0.0045647994 +458 425 0.00060859998 +459 425 0.00060859998 +460 425 0.00091299997 +463 425 0.0076079965 +464 425 0.00091299997 +465 425 0.00060859998 +467 425 0.0094339997 +468 425 0.018259298 +469 425 0.0063906983 +470 425 0.0073036999 +471 425 0.0018258998 +473 425 0.00030429987 +478 425 0.0012172998 +483 425 0.0033475 +490 425 0.00091299997 +491 425 0.00030429987 +17 426 0.00044509978 +60 426 0.001558 +82 426 0.00022259999 +108 426 0.00022259999 +114 426 0.00044509978 +126 426 0.00022259999 +131 426 0.00022259999 +132 426 0.00022259999 +139 426 0.00022259999 +150 426 0.00022259999 +171 426 0.016470097 +187 426 0.00022259999 +189 426 0.00022259999 +190 426 0.00022259999 +194 426 0.0011127999 +198 426 0.011796098 +203 426 0.00022259999 +206 426 0.00066769985 +208 426 0.00022259999 +214 426 0.0022256998 +223 426 0.00022259999 +224 426 0.0024482999 +233 426 0.0024482999 +234 426 0.0080124997 +237 426 0.00044509978 +241 426 0.016024899 +243 426 0.00044509978 +250 426 0.020698898 +252 426 0.0064544976 +270 426 0.0066770986 +276 426 0.0060092993 +277 426 0.00066769985 +279 426 0.00044509978 +284 426 0.00022259999 +290 426 0.064099669 +292 426 0.015802398 +293 426 0.00044509978 +294 426 0.0037836998 +295 426 0.00022259999 +298 426 0.079234362 +312 426 0.00022259999 +315 426 0.00066769985 +317 426 0.00022259999 +320 426 0.0064544976 +325 426 0.00044509978 +326 426 0.0057867989 +340 426 0.00044509978 +358 426 0.0020030998 +387 426 0.00022259999 +392 426 0.00066769985 +393 426 0.0035611 +417 426 0.00066769985 +419 426 0.00066769985 +422 426 0.00022259999 +423 426 0.00044509978 +424 426 0.1112842 +426 426 0.0244825 +438 426 0.00022259999 +441 426 0.0084575973 +442 426 0.0182506 +443 426 0.0011127999 +444 426 0.0084575973 +445 426 0.012463797 +446 426 0.00022259999 +447 426 0.013576698 +448 426 0.00022259999 +450 426 0.0064544976 +452 426 0.0051190965 +453 426 0.00066769985 +454 426 0.00089029991 +455 426 0.0316047 +456 426 0.00022259999 +457 426 0.0046738982 +458 426 0.00044509978 +459 426 0.00022259999 +460 426 0.0011127999 +463 426 0.016470097 +464 426 0.001558 +465 426 0.0011127999 +467 426 0.012018699 +468 426 0.012241296 +469 426 0.0075672977 +470 426 0.0082349963 +471 426 0.0026707998 +473 426 0.00022259999 +478 426 0.0017804999 +479 426 0.012018699 +483 426 0.0035611 +490 426 0.00066769985 +491 426 0.00044509978 +22 427 0.00018239999 +60 427 0.0027357 +108 427 0.00018239999 +114 427 0.00036479998 +126 427 0.00018239999 +130 427 0.0032829 +135 427 0.0031005 +150 427 0.00018239999 +160 427 0.0492431 +165 427 0.010395799 +171 427 0.041035898 +172 427 0.00091189984 +188 427 0.0078423992 +189 427 0.00018239999 +190 427 0.00018239999 +194 427 0.00036479998 +198 427 0.0063833967 +203 427 0.00018239999 +206 427 0.00054709986 +214 427 0.00036479998 +224 427 0.0142258 +233 427 0.0041947998 +234 427 0.0031005 +237 427 0.00036479998 +241 427 0.0076599978 +248 427 0.018602997 +277 427 0.0116724 +279 427 0.00036479998 +282 427 0.0036475998 +284 427 0.00018239999 +292 427 0.011854798 +297 427 0.0069304965 +298 427 0.0069304965 +312 427 0.00091189984 +315 427 0.0010942998 +321 427 0.00091189984 +322 427 0.00091189984 +356 427 0.00018239999 +358 427 0.0018237999 +387 427 0.017508697 +392 427 0.013313897 +393 427 0.063468874 +402 427 0.00018239999 +417 427 0.00072949985 +421 427 0.00018239999 +422 427 0.00036479998 +427 427 0.077329874 +443 427 0.0067480989 +444 427 0.00054709986 +445 427 0.0041947998 +446 427 0.00036479998 +447 427 0.0052890964 +450 427 0.0052890964 +452 427 0.0049242973 +453 427 0.0023709999 +454 427 0.00054709986 +455 427 0.032463998 +456 427 0.00018239999 +457 427 0.0045594983 +458 427 0.00072949985 +459 427 0.00054709986 +460 427 0.0010942998 +463 427 0.011307698 +464 427 0.00054709986 +465 427 0.0012766998 +467 427 0.010942899 +468 427 0.0087542981 +469 427 0.0069304965 +470 427 0.0076599978 +471 427 0.0021885999 +473 427 0.00018239999 +477 427 0.00018239999 +478 427 0.0016413999 +483 427 0.0031005 +490 427 0.0012766998 +491 427 0.0018237999 +9 428 6.5699991e-05 +18 428 0.0001315 +22 428 6.5699991e-05 +60 428 0.0025636 +82 428 6.5699991e-05 +83 428 6.5699991e-05 +84 428 6.5699991e-05 +108 428 6.5699991e-05 +113 428 0.0001315 +114 428 0.00026289979 +126 428 0.0001315 +130 428 0.0041411966 +132 428 0.0026950999 +135 428 6.5699991e-05 +137 428 6.5699991e-05 +138 428 0.00019719999 +139 428 0.0097942986 +143 428 6.5699991e-05 +150 428 0.00085449987 +154 428 0.0018404999 +158 428 0.0046012998 +160 428 0.017222099 +161 428 0.0021034998 +165 428 0.0024320998 +170 428 0.00032869983 +171 428 0.010517299 +172 428 0.0037467999 +175 428 6.5699991e-05 +187 428 0.0020376998 +188 428 0.016236097 +189 428 0.00026289979 +190 428 0.0001315 +194 428 0.00039439998 +197 428 0.0001315 +198 428 0.044238497 +200 428 6.5699991e-05 +202 428 6.5699991e-05 +203 428 0.0001315 +204 428 0.00046009989 +206 428 0.00026289979 +207 428 6.5699991e-05 +208 428 0.00046009989 +214 428 0.00085449987 +219 428 0.0020376998 +221 428 0.0007230998 +224 428 0.042200699 +225 428 0.00039439998 +227 428 0.00039439998 +233 428 0.0043383986 +234 428 0.0024978998 +237 428 0.0066390969 +240 428 0.0010517 +241 428 0.1003089 +243 428 0.0015775999 +252 428 0.00052589993 +270 428 6.5699991e-05 +277 428 0.023466799 +282 428 0.00019719999 +283 428 0.00019719999 +284 428 0.00019719999 +288 428 6.5699991e-05 +292 428 0.0001315 +293 428 0.0032867 +294 428 0.0024320998 +295 428 0.00019719999 +296 428 0.0001315 +299 428 6.5699991e-05 +300 428 6.5699991e-05 +312 428 0.010122899 +315 428 0.0038124998 +317 428 6.5699991e-05 +319 428 0.0012488998 +320 428 0.0006573 +321 428 0.00059159985 +322 428 0.0024978998 +324 428 6.5699991e-05 +326 428 0.0061131977 +328 428 0.0006573 +330 428 0.0001315 +340 428 0.00032869983 +349 428 0.0007230998 +351 428 0.00026289979 +354 428 0.00052589993 +356 428 6.5699991e-05 +358 428 0.0017747998 +370 428 0.0011831999 +372 428 0.0046670996 +377 428 6.5699991e-05 +380 428 6.5699991e-05 +384 428 0.0013146999 +386 428 6.5699991e-05 +387 428 0.0001315 +391 428 0.00019719999 +393 428 0.00019719999 +398 428 0.0026292999 +402 428 0.00019719999 +409 428 0.0040754974 +412 428 0.0012488998 +415 428 0.0001315 +417 428 0.00052589993 +419 428 0.0001315 +421 428 6.5699991e-05 +422 428 0.00026289979 +423 428 6.5699991e-05 +425 428 6.5699991e-05 +428 428 0.036679197 +429 428 0.00026289979 +430 428 0.0007230998 +431 428 6.5699991e-05 +433 428 6.5699991e-05 +434 428 6.5699991e-05 +443 428 0.0069676973 +444 428 0.00052589993 +445 428 0.011371899 +446 428 0.00059159985 +447 428 0.0039439984 +450 428 0.0045355968 +452 428 0.0060474984 +453 428 0.0015119 +454 428 0.00039439998 +455 428 0.050746098 +456 428 0.00052589993 +457 428 0.0043383986 +458 428 0.00078879995 +459 428 0.0046670996 +460 428 0.0011831999 +463 428 0.022875197 +464 428 0.0042726994 +465 428 0.004929997 +467 428 0.016959198 +468 428 0.06961149 +469 428 0.0067047998 +470 428 0.0071648993 +471 428 0.0020376998 +473 428 0.00019719999 +477 428 0.0001315 +478 428 0.0013803998 +479 428 0.0059816986 +483 428 0.0022348999 +489 428 0.0001315 +490 428 0.00078879995 +491 428 0.00078879995 +60 429 0.0021276998 +114 429 0.00035459991 +130 429 0.10496449 +132 429 0.0039006998 +137 429 0.0021276998 +139 429 0.0031915 +150 429 0.00035459991 +154 429 0.00070919981 +158 429 0.0014183999 +160 429 0.0056737997 +161 429 0.00070919981 +162 429 0.00035459991 +165 429 0.00070919981 +171 429 0.0035460999 +172 429 0.0014183999 +187 429 0.00035459991 +188 429 0.0049644969 +194 429 0.00035459991 +198 429 0.039361697 +206 429 0.00070919981 +219 429 0.00070919981 +224 429 0.027305 +225 429 0.00035459991 +233 429 0.0216312 +234 429 0.0024822999 +237 429 0.0024822999 +240 429 0.0092198998 +241 429 0.11702126 +243 429 0.00070919981 +277 429 0.0070921965 +293 429 0.0010638 +294 429 0.00070919981 +312 429 0.0031915 +315 429 0.0010638 +317 429 0.00035459991 +319 429 0.00035459991 +322 429 0.00070919981 +326 429 0.001773 +328 429 0.00035459991 +349 429 0.00035459991 +358 429 0.001773 +370 429 0.00035459991 +372 429 0.0014183999 +384 429 0.00035459991 +398 429 0.00070919981 +409 429 0.00070919981 +412 429 0.00035459991 +417 429 0.00070919981 +428 429 0.012056697 +429 429 0.026950397 +430 429 0.00035459991 +442 429 0.00070919981 +443 429 0.0028368998 +444 429 0.00035459991 +445 429 0.025886498 +447 429 0.0046098977 +450 429 0.0056737997 +452 429 0.0056737997 +453 429 0.0014183999 +455 429 0.039361697 +456 429 0.00035459991 +457 429 0.0042552985 +458 429 0.00070919981 +459 429 0.022340398 +460 429 0.0014183999 +463 429 0.024468098 +464 429 0.001773 +465 429 0.0024822999 +467 429 0.013120599 +468 429 0.048226997 +469 429 0.0056737997 +470 429 0.0060283989 +471 429 0.0024822999 +478 429 0.0014183999 +479 429 0.0163121 +483 429 0.0042552985 +490 429 0.0010638 +491 429 0.00070919981 +9 430 6.2499996e-05 +18 430 0.00012489999 +22 430 6.2499996e-05 +60 430 0.0034351 +82 430 0.00012489999 +83 430 6.2499996e-05 +84 430 6.2499996e-05 +108 430 6.2499996e-05 +113 430 0.00012489999 +114 430 0.00018739999 +126 430 6.2499996e-05 +130 430 0.011991799 +131 430 0.00024979981 +132 430 0.00031229993 +133 430 0.00068699988 +135 430 0.0033101998 +138 430 0.00024979981 +139 430 0.0018736999 +141 430 0.00081189978 +142 430 0.00018739999 +143 430 6.2499996e-05 +145 430 6.2499996e-05 +149 430 0.00074949977 +150 430 0.004371997 +156 430 0.00012489999 +158 430 0.0046842992 +159 430 6.2499996e-05 +160 430 0.053713098 +161 430 0.0013740999 +165 430 0.0039972998 +169 430 0.0013116 +170 430 0.0011866998 +171 430 0.0051838979 +172 430 6.2499996e-05 +188 430 0.00018739999 +189 430 0.00012489999 +190 430 0.00012489999 +192 430 6.2499996e-05 +194 430 0.00018739999 +197 430 6.2499996e-05 +198 430 0.015739199 +200 430 6.2499996e-05 +203 430 0.00012489999 +204 430 0.0015613998 +206 430 0.00024979981 +207 430 6.2499996e-05 +214 430 0.00062459987 +219 430 0.005621098 +222 430 6.2499996e-05 +224 430 0.029104996 +225 430 0.0099306963 +227 430 0.0092435963 +230 430 0.00031229993 +233 430 0.007557299 +234 430 0.0025606998 +237 430 0.00037469994 +240 430 0.011179797 +241 430 0.020111199 +242 430 0.0025606998 +243 430 0.0110549 +248 430 0.00012489999 +252 430 0.00087439991 +269 430 0.0022484998 +270 430 0.00056209997 +277 430 0.051464599 +282 430 0.0081193969 +283 430 0.0084316991 +284 430 0.00018739999 +292 430 0.0021235 +293 430 0.0074947998 +294 430 0.0014364999 +295 430 6.2499996e-05 +296 430 0.0061207972 +298 430 0.00062459987 +312 430 0.011554599 +315 430 0.00031229993 +319 430 0.00043719984 +321 430 0.00049969996 +322 430 6.2499996e-05 +324 430 0.0026856998 +326 430 0.00018739999 +340 430 6.2499996e-05 +350 430 6.2499996e-05 +351 430 0.00018739999 +354 430 6.2499996e-05 +355 430 6.2499996e-05 +356 430 0.0023108998 +358 430 0.0015613998 +371 430 0.0016862999 +372 430 0.0029354999 +387 430 6.2499996e-05 +392 430 0.0019361998 +393 430 0.0021235 +398 430 6.2499996e-05 +402 430 0.00012489999 +409 430 6.2499996e-05 +417 430 0.00056209997 +421 430 6.2499996e-05 +422 430 0.00018739999 +423 430 6.2499996e-05 +428 430 0.00049969996 +430 430 0.052214097 +431 430 6.2499996e-05 +433 430 6.2499996e-05 +434 430 6.2499996e-05 +437 430 0.00074949977 +441 430 0.0018736999 +442 430 0.00012489999 +443 430 0.0083691999 +444 430 0.0021235 +445 430 0.0098681971 +446 430 0.00099929981 +447 430 0.0033101998 +450 430 0.0078695975 +452 430 0.0053712986 +453 430 0.0023733999 +454 430 0.00056209997 +455 430 0.054462597 +456 430 0.00049969996 +457 430 0.0073698983 +458 430 0.0023733999 +459 430 0.0038722998 +460 430 0.0013116 +463 430 0.017550398 +464 430 0.0053712986 +465 430 0.0012490998 +467 430 0.014802299 +468 430 0.041408997 +469 430 0.013053499 +470 430 0.0066203997 +471 430 0.0019985999 +473 430 0.00012489999 +477 430 0.00018739999 +478 430 0.0013116 +479 430 0.0042470992 +483 430 0.0021235 +489 430 0.0019361998 +490 430 0.0023108998 +491 430 0.0024357999 +13 431 0.00030889991 +24 431 0.00092679984 +60 431 0.0021624998 +114 431 0.00030889991 +120 431 0.00030889991 +126 431 0.00030889991 +130 431 0.00030889991 +131 431 0.00061789993 +135 431 0.021933898 +160 431 0.00061789993 +171 431 0.0027804 +187 431 0.00092679984 +194 431 0.00061789993 +198 431 0.030274898 +206 431 0.00061789993 +214 431 0.00061789993 +224 431 0.043558899 +225 431 0.00030889991 +233 431 0.00061789993 +234 431 0.0021624998 +237 431 0.00030889991 +240 431 0.00061789993 +241 431 0.10534447 +268 431 0.00030889991 +272 431 0.00061789993 +273 431 0.00030889991 +276 431 0.0111214 +277 431 0.0024714 +279 431 0.00061789993 +290 431 0.00030889991 +292 431 0.063639164 +293 431 0.00030889991 +298 431 0.00061789993 +312 431 0.00030889991 +315 431 0.00092679984 +321 431 0.00030889991 +322 431 0.0027804 +326 431 0.029039197 +358 431 0.0012357 +370 431 0.00030889991 +372 431 0.00030889991 +417 431 0.00061789993 +424 431 0.00061789993 +431 431 0.050664198 +432 431 0.00061789993 +433 431 0.00030889991 +434 431 0.00061789993 +442 431 0.0101946 +443 431 0.0040160976 +444 431 0.0071052983 +445 431 0.018226799 +446 431 0.00030889991 +447 431 0.0089588985 +450 431 0.0046338998 +452 431 0.0058695972 +453 431 0.00061789993 +454 431 0.0012357 +455 431 0.0457213 +456 431 0.00030889991 +457 431 0.012665998 +458 431 0.00061789993 +459 431 0.00061789993 +460 431 0.00092679984 +463 431 0.0176089 +464 431 0.00092679984 +465 431 0.011430297 +467 431 0.0092677996 +468 431 0.016990997 +469 431 0.0071052983 +470 431 0.0071052983 +471 431 0.0015445999 +473 431 0.00030889991 +478 431 0.00092679984 +479 431 0.0052517988 +483 431 0.0024714 +490 431 0.00061789993 +491 431 0.0024714 +24 432 0.011454798 +60 432 0.0028636998 +114 432 0.00057269982 +126 432 0.00057269982 +135 432 0.010309298 +139 432 0.00057269982 +156 432 0.00057269982 +159 432 0.00057269982 +160 432 0.0148912 +171 432 0.048682697 +187 432 0.0017181998 +188 432 0.00057269982 +198 432 0.016036697 +206 432 0.0011455 +208 432 0.00057269982 +218 432 0.0011455 +224 432 0.0028636998 +225 432 0.010881998 +233 432 0.012600198 +234 432 0.0091637969 +240 432 0.0068728998 +241 432 0.057273798 +268 432 0.0040091984 +272 432 0.00057269982 +273 432 0.0040091984 +276 432 0.021191299 +277 432 0.002291 +279 432 0.00057269982 +292 432 0.0028636998 +294 432 0.0011455 +312 432 0.0057273991 +315 432 0.0223368 +317 432 0.00057269982 +325 432 0.0017181998 +326 432 0.018327598 +358 432 0.0017181998 +417 432 0.00057269982 +428 432 0.0011455 +430 432 0.00057269982 +431 432 0.002291 +432 432 0.0011455 +433 432 0.0051545985 +434 432 0.010881998 +442 432 0.044100799 +443 432 0.0063000992 +445 432 0.014318399 +446 432 0.00057269982 +447 432 0.0011455 +450 432 0.0045818985 +452 432 0.0057273991 +453 432 0.0034363999 +455 432 0.038946196 +457 432 0.0045818985 +458 432 0.00057269982 +459 432 0.00057269982 +460 432 0.0011455 +463 432 0.0154639 +464 432 0.0017181998 +465 432 0.0011455 +467 432 0.010309298 +468 432 0.053264599 +469 432 0.0080182999 +470 432 0.0091637969 +471 432 0.0017181998 +473 432 0.00057269982 +478 432 0.0011455 +479 432 0.0148912 +483 432 0.0028636998 +490 432 0.0011455 +491 432 0.00057269982 +24 433 0.00060099992 +60 433 0.0030047998 +114 433 0.00060099992 +126 433 0.00060099992 +131 433 0.0012019 +135 433 0.00060099992 +160 433 0.00060099992 +171 433 0.058293298 +187 433 0.0018028999 +198 433 0.012019198 +206 433 0.0012019 +214 433 0.0036058 +224 433 0.025240399 +225 433 0.00060099992 +233 433 0.0012019 +234 433 0.0036058 +237 433 0.00060099992 +240 433 0.025841299 +241 433 0.050480798 +272 433 0.00060099992 +276 433 0.022836499 +277 433 0.040264398 +279 433 0.00060099992 +292 433 0.0012019 +294 433 0.032451898 +315 433 0.044471197 +326 433 0.0096153989 +358 433 0.0018028999 +417 433 0.00060099992 +431 433 0.00060099992 +433 433 0.0024037999 +434 433 0.00060099992 +437 433 0.00060099992 +442 433 0.0024037999 +443 433 0.0030047998 +444 433 0.0012019 +445 433 0.032451898 +447 433 0.0042066984 +450 433 0.0066105984 +452 433 0.0078125 +453 433 0.0030047998 +455 433 0.025240399 +457 433 0.0048076995 +458 433 0.00060099992 +459 433 0.036057699 +460 433 0.0012019 +463 433 0.021033697 +464 433 0.0012019 +465 433 0.0012019 +467 433 0.011418298 +468 433 0.019831698 +469 433 0.012620199 +470 433 0.013822097 +471 433 0.0024037999 +473 433 0.00060099992 +478 433 0.0012019 +479 433 0.0036058 +483 433 0.0030047998 +490 433 0.0018028999 +491 433 0.00060099992 +60 434 0.015398797 +114 434 0.00030799978 +126 434 0.00030799978 +131 434 0.05328 +187 434 0.10101628 +188 434 0.0021557999 +192 434 0.010163199 +198 434 0.037265196 +203 434 0.00030799978 +206 434 0.0018479 +211 434 0.0006159998 +214 434 0.00092389993 +219 434 0.00030799978 +221 434 0.0021557999 +222 434 0.0030797999 +223 434 0.0043116994 +224 434 0.0015399 +233 434 0.0018479 +234 434 0.0120111 +240 434 0.00092389993 +241 434 0.064367056 +272 434 0.00092389993 +276 434 0.012626998 +277 434 0.010779198 +279 434 0.0006159998 +282 434 0.00092389993 +284 434 0.00030799978 +292 434 0.0015399 +293 434 0.0018479 +294 434 0.00092389993 +295 434 0.00030799978 +296 434 0.0021557999 +298 434 0.0012319 +308 434 0.0015399 +312 434 0.0027717999 +315 434 0.0036956999 +320 434 0.0021557999 +321 434 0.0033876998 +322 434 0.0006159998 +326 434 0.041576799 +340 434 0.0012319 +351 434 0.0012319 +354 434 0.00030799978 +358 434 0.0021557999 +359 434 0.0018479 +361 434 0.0024637999 +363 434 0.0018479 +370 434 0.00030799978 +371 434 0.0006159998 +372 434 0.0043116994 +373 434 0.00030799978 +386 434 0.0018479 +392 434 0.0018479 +417 434 0.00030799978 +419 434 0.0021557999 +422 434 0.00030799978 +434 434 0.0024637999 +441 434 0.0015399 +443 434 0.005543597 +444 434 0.0080073997 +445 434 0.012319099 +446 434 0.00030799978 +447 434 0.012319099 +450 434 0.0040036999 +452 434 0.0046195984 +453 434 0.0012319 +454 434 0.00092389993 +455 434 0.046196498 +456 434 0.00030799978 +457 434 0.0052355975 +458 434 0.0006159998 +459 434 0.0012319 +460 434 0.0018479 +463 434 0.020942397 +464 434 0.0024637999 +465 434 0.00092389993 +467 434 0.0157068 +468 434 0.0033876998 +469 434 0.011087198 +470 434 0.012626998 +471 434 0.0012319 +473 434 0.00030799978 +478 434 0.011087198 +483 434 0.0021557999 +490 434 0.0012319 +491 434 0.0015399 +16 435 0.013605397 +60 435 0.00097179995 +82 435 0.00097179995 +84 435 0.038872696 +114 435 0.00097179995 +130 435 0.0019435999 +132 435 0.00097179995 +149 435 0.00097179995 +150 435 0.0019435999 +171 435 0.00097179995 +187 435 0.0019435999 +194 435 0.00097179995 +198 435 0.017492697 +206 435 0.00097179995 +214 435 0.00097179995 +223 435 0.00097179995 +224 435 0.0019435999 +233 435 0.00097179995 +234 435 0.0068026967 +241 435 0.27016515 +272 435 0.00097179995 +277 435 0.00097179995 +279 435 0.00097179995 +292 435 0.00097179995 +293 435 0.00097179995 +298 435 0.00097179995 +326 435 0.0019435999 +358 435 0.0019435999 +417 435 0.00097179995 +435 435 0.033041798 +442 435 0.0029155 +443 435 0.00097179995 +444 435 0.00097179995 +445 435 0.012633599 +447 435 0.0068026967 +450 435 0.0058308989 +452 435 0.0048590973 +455 435 0.047618996 +456 435 0.03207 +457 435 0.0048590973 +459 435 0.060252696 +460 435 0.00097179995 +463 435 0.012633599 +464 435 0.00097179995 +465 435 0.00097179995 +467 435 0.0087463968 +468 435 0.0029155 +469 435 0.0048590973 +470 435 0.0058308989 +471 435 0.0029155 +478 435 0.00097179995 +479 435 0.0019435999 +483 435 0.0029155 +490 435 0.00097179995 +60 436 0.0028652998 +114 436 0.00095509994 +131 436 0.0057306997 +139 436 0.00095509994 +160 436 0.00095509994 +188 436 0.0019101999 +198 436 0.014326598 +206 436 0.00095509994 +224 436 0.09551096 +234 436 0.0047754981 +241 436 0.0057306997 +277 436 0.034383997 +279 436 0.00095509994 +292 436 0.029608399 +293 436 0.0085959993 +295 436 0.00095509994 +312 436 0.00095509994 +315 436 0.0038204 +319 436 0.00095509994 +320 436 0.00095509994 +358 436 0.0019101999 +417 436 0.00095509994 +428 436 0.00095509994 +436 436 0.1432665 +437 436 0.0019101999 +443 436 0.0028652998 +444 436 0.0019101999 +445 436 0.0076408982 +447 436 0.015281796 +450 436 0.0047754981 +452 436 0.0085959993 +455 436 0.043935098 +457 436 0.0028652998 +459 436 0.057306599 +460 436 0.00095509994 +463 436 0.0095510967 +464 436 0.00095509994 +467 436 0.010506198 +468 436 0.0047754981 +469 436 0.0066857971 +470 436 0.0066857971 +471 436 0.0019101999 +478 436 0.00095509994 +483 436 0.0038204 +490 436 0.00095509994 +491 436 0.00095509994 +4 437 0.0005394998 +60 437 0.0014385998 +108 437 0.00017979999 +114 437 0.00035959994 +126 437 0.00017979999 +130 437 0.00017979999 +131 437 0.078223288 +132 437 0.00089909998 +143 437 0.00017979999 +149 437 0.00017979999 +150 437 0.00035959994 +188 437 0.0088113993 +189 437 0.00017979999 +190 437 0.00017979999 +194 437 0.00035959994 +198 437 0.0115087 +206 437 0.00035959994 +214 437 0.00035959994 +224 437 0.027153399 +226 437 0.00035959994 +227 437 0.0028771998 +233 437 0.0050350986 +234 437 0.0032368 +237 437 0.00017979999 +240 437 0.00017979999 +241 437 0.013306998 +277 437 0.043337498 +282 437 0.00017979999 +284 437 0.00017979999 +288 437 0.0046753995 +290 437 0.0043157972 +292 437 0.038122598 +293 437 0.013486799 +295 437 0.00017979999 +298 437 0.00017979999 +312 437 0.0053946972 +313 437 0.00071929977 +315 437 0.036504198 +317 437 0.00017979999 +319 437 0.0005394998 +320 437 0.00035959994 +321 437 0.00017979999 +322 437 0.0062937997 +326 437 0.00017979999 +340 437 0.0005394998 +356 437 0.00017979999 +358 437 0.0017982 +372 437 0.00017979999 +387 437 0.00017979999 +417 437 0.0005394998 +422 437 0.0005394998 +436 437 0.0016184 +437 437 0.031109497 +443 437 0.0035964998 +444 437 0.0071929991 +445 437 0.0055744983 +446 437 0.00017979999 +447 437 0.009530697 +450 437 0.0043157972 +452 437 0.0066534989 +453 437 0.00071929977 +454 437 0.00071929977 +455 437 0.032188497 +456 437 0.00017979999 +457 437 0.0041358992 +458 437 0.00089909998 +459 437 0.0012587998 +460 437 0.0010788999 +463 437 0.0098902993 +464 437 0.0005394998 +465 437 0.00089909998 +467 437 0.0086314976 +468 437 0.0032368 +469 437 0.0062937997 +470 437 0.0064736977 +471 437 0.0017982 +473 437 0.00017979999 +477 437 0.00017979999 +478 437 0.0014385998 +479 437 0.0037762998 +483 437 0.0026973998 +490 437 0.00071929977 +13 438 0.041518997 +60 438 0.0025316 +108 438 0.00025319983 +114 438 0.00050629978 +119 438 0.00025319983 +120 438 0.00050629978 +126 438 0.00025319983 +130 438 0.042278498 +132 438 0.00025319983 +135 438 0.00025319983 +137 438 0.00025319983 +139 438 0.00025319983 +142 438 0.00025319983 +149 438 0.00025319983 +150 438 0.00025319983 +152 438 0.00025319983 +157 438 0.00025319983 +160 438 0.0098733976 +161 438 0.0040505975 +171 438 0.042531598 +172 438 0.00025319983 +189 438 0.00025319983 +190 438 0.00025319983 +193 438 0.00025319983 +194 438 0.00050629978 +198 438 0.0083543994 +204 438 0.00025319983 +206 438 0.00050629978 +214 438 0.0032910998 +219 438 0.0015189999 +224 438 0.00075949985 +227 438 0.0073417984 +228 438 0.00025319983 +231 438 0.0010126999 +232 438 0.00025319983 +233 438 0.0025316 +234 438 0.0032910998 +237 438 0.00025319983 +240 438 0.0012657999 +241 438 0.085316479 +277 438 0.0260759 +284 438 0.00025319983 +292 438 0.00075949985 +293 438 0.0025316 +295 438 0.0068353973 +300 438 0.0010126999 +315 438 0.015949398 +326 438 0.00025319983 +358 438 0.0017722 +387 438 0.00025319983 +417 438 0.00075949985 +422 438 0.00050629978 +431 438 0.00050629978 +438 438 0.0027847998 +442 438 0.054177199 +443 438 0.0065822974 +444 438 0.00025319983 +445 438 0.018227797 +446 438 0.00050629978 +447 438 0.00075949985 +450 438 0.0050632991 +452 438 0.0073417984 +453 438 0.0015189999 +454 438 0.00075949985 +455 438 0.059493698 +456 438 0.00025319983 +457 438 0.0043037981 +458 438 0.00075949985 +459 438 0.00050629978 +460 438 0.0027847998 +463 438 0.0096202977 +464 438 0.00025319983 +465 438 0.0012657999 +467 438 0.010126598 +468 438 0.06556958 +469 438 0.0068353973 +470 438 0.0073417984 +471 438 0.0020252999 +473 438 0.00025319983 +478 438 0.0015189999 +483 438 0.0035442999 +490 438 0.00075949985 +22 439 0.00032639992 +24 439 0.0022845999 +60 439 0.013707597 +114 439 0.00032639992 +119 439 0.0088119991 +132 439 0.0026109999 +134 439 0.00032639992 +143 439 0.00032639992 +169 439 0.0065273978 +171 439 0.0058746971 +191 439 0.058746699 +198 439 0.015339397 +206 439 0.00065269996 +214 439 0.021866798 +224 439 0.072780669 +234 439 0.0048955977 +240 439 0.00065269996 +241 439 0.057114899 +272 439 0.00097909989 +279 439 0.00032639992 +317 439 0.0075064972 +337 439 0.0068537965 +358 439 0.00065269996 +417 439 0.00032639992 +439 439 0.00032639992 +443 439 0.012728497 +444 439 0.012402099 +445 439 0.039164498 +446 439 0.00065269996 +447 439 0.0104439 +450 439 0.0088119991 +452 439 0.0068537965 +453 439 0.0022845999 +454 439 0.013707597 +455 439 0.038511697 +457 439 0.030352499 +458 439 0.013381198 +459 439 0.014360297 +460 439 0.00065269996 +463 439 0.033616196 +464 439 0.014033899 +465 439 0.0120757 +467 439 0.030352499 +468 439 0.071801543 +469 439 0.0267624 +470 439 0.0029372999 +471 439 0.015665799 +478 439 0.015013099 +483 439 0.00097909989 +490 439 0.00065269996 +491 439 0.0084855966 +22 440 0.00025589997 +60 440 0.0028146999 +108 440 0.00025589997 +114 440 0.00051179994 +126 440 0.00025589997 +130 440 0.030706197 +137 440 0.029426798 +142 440 0.0040941983 +160 440 0.038126897 +165 440 0.020726699 +170 440 0.0079323985 +172 440 0.0038382998 +188 440 0.0023029998 +189 440 0.00025589997 +194 440 0.00025589997 +206 440 0.00051179994 +233 440 0.013817798 +234 440 0.0023029998 +237 440 0.00025589997 +241 440 0.0084441975 +252 440 0.00025589997 +272 440 0.0025588998 +277 440 0.075230241 +279 440 0.00025589997 +284 440 0.00025589997 +289 440 0.00025589997 +292 440 0.014585499 +293 440 0.00051179994 +307 440 0.00025589997 +319 440 0.057830099 +324 440 0.00025589997 +358 440 0.0015352999 +387 440 0.00025589997 +417 440 0.00051179994 +422 440 0.00025589997 +440 440 0.095701098 +443 440 0.0071647987 +444 440 0.00025589997 +445 440 0.015353099 +446 440 0.0010235 +447 440 0.0051176995 +450 440 0.0043500997 +452 440 0.0051176995 +453 440 0.0040941983 +454 440 0.00051179994 +455 440 0.061156597 +456 440 0.00025589997 +457 440 0.0038382998 +458 440 0.00076769991 +459 440 0.00051179994 +460 440 0.0010235 +463 440 0.0099794976 +464 440 0.00051179994 +465 440 0.0089559965 +467 440 0.0099794976 +468 440 0.023285598 +469 440 0.0066529997 +470 440 0.0071647987 +471 440 0.0020470999 +473 440 0.00025589997 +478 440 0.0010235 +483 440 0.0038382998 +490 440 0.00076769991 +18 441 0.0001679 +60 441 0.0018465999 +113 441 0.0001679 +114 441 0.0001679 +130 441 0.0001679 +150 441 0.00083929999 +160 441 0.010072198 +165 441 0.0125902 +170 441 0.0043645985 +171 441 0.0090649985 +172 441 0.0001679 +187 441 0.00067149987 +188 441 0.0078898966 +189 441 0.0001679 +190 441 0.0001679 +194 441 0.021487299 +198 441 0.013933197 +203 441 0.0001679 +204 441 0.00067149987 +206 441 0.0001679 +214 441 0.00067149987 +219 441 0.0001679 +221 441 0.0001679 +224 441 0.046835698 +233 441 0.010072198 +234 441 0.0036930998 +237 441 0.00033569988 +240 441 0.0001679 +241 441 0.026355498 +252 441 0.00083929999 +270 441 0.0001679 +277 441 0.044485498 +279 441 0.0001679 +282 441 0.0001679 +284 441 0.0001679 +288 441 0.0001679 +292 441 0.0001679 +293 441 0.018297799 +295 441 0.016451199 +312 441 0.0015107999 +315 441 0.0001679 +319 441 0.007554099 +320 441 0.0001679 +321 441 0.0047003999 +326 441 0.0035253 +340 441 0.0001679 +358 441 0.0016786999 +370 441 0.019137099 +371 441 0.0043645985 +373 441 0.0025179998 +376 441 0.0026858998 +384 441 0.0040288977 +385 441 0.0001679 +386 441 0.0063789971 +398 441 0.0001679 +402 441 0.00033569988 +417 441 0.00050359988 +422 441 0.0001679 +431 441 0.0001679 +441 441 0.016115498 +442 441 0.0028537998 +443 441 0.0068826973 +444 441 0.0025179998 +445 441 0.0095685981 +446 441 0.00033569988 +447 441 0.0047003999 +450 441 0.0048681982 +452 441 0.0058753975 +453 441 0.0028537998 +454 441 0.0001679 +455 441 0.0256841 +456 441 0.00067149987 +457 441 0.0040288977 +458 441 0.00067149987 +459 441 0.00033569988 +460 441 0.001343 +463 441 0.024508998 +464 441 0.00050359988 +465 441 0.001343 +467 441 0.014772497 +468 441 0.015276097 +469 441 0.0083934963 +470 441 0.0092327967 +471 441 0.0023502 +473 441 0.0001679 +478 441 0.0015107999 +483 441 0.0025179998 +490 441 0.00067149987 +4 442 0.00020639999 +9 442 6.8799985e-05 +13 442 0.00013759999 +17 442 0.0010320998 +18 442 0.00013759999 +22 442 0.00020639999 +60 442 0.0040593967 +82 442 0.0087380968 +83 442 6.8799985e-05 +84 442 6.8799985e-05 +104 442 6.8799985e-05 +108 442 6.8799985e-05 +113 442 0.00013759999 +114 442 0.00027519977 +120 442 6.8799985e-05 +126 442 0.00013759999 +130 442 0.0037841999 +131 442 0.0074308999 +132 442 0.0087380968 +138 442 0.00013759999 +139 442 0.0063299984 +143 442 6.8799985e-05 +149 442 0.00013759999 +150 442 0.0011008999 +151 442 6.8799985e-05 +158 442 0.0052978992 +159 442 0.0017888998 +160 442 0.0048162974 +161 442 0.00013759999 +162 442 0.004403498 +165 442 0.00013759999 +171 442 0.010664597 +172 442 6.8799985e-05 +187 442 0.00061919983 +188 442 0.005917199 +189 442 0.00013759999 +190 442 0.00013759999 +192 442 0.0053666979 +193 442 0.0054354966 +194 442 0.0097701997 +197 442 6.8799985e-05 +198 442 0.054492898 +200 442 6.8799985e-05 +203 442 0.00013759999 +204 442 0.00020639999 +206 442 0.00027519977 +207 442 6.8799985e-05 +214 442 0.0088068992 +218 442 6.8799985e-05 +219 442 0.00061919983 +221 442 0.00027519977 +223 442 0.010733496 +224 442 0.0013760999 +225 442 0.0025457998 +226 442 0.00020639999 +227 442 0.0012384998 +228 442 0.00013759999 +230 442 0.0027521998 +232 442 6.8799985e-05 +233 442 0.0083252974 +234 442 0.023255799 +237 442 0.00048159994 +240 442 0.0057106987 +241 442 0.0191276 +252 442 0.0013760999 +253 442 0.00013759999 +270 442 0.004403498 +272 442 0.0013760999 +277 442 0.017889097 +279 442 0.00048159994 +282 442 6.8799985e-05 +283 442 6.8799985e-05 +284 442 0.00020639999 +290 442 0.0020640998 +292 442 0.0087380968 +293 442 0.0072243996 +294 442 0.00027519977 +295 442 0.005917199 +296 442 0.00013759999 +297 442 0.0052290969 +298 442 0.010114197 +300 442 0.00013759999 +312 442 0.005917199 +315 442 0.0065363981 +317 442 6.8799985e-05 +319 442 6.8799985e-05 +320 442 0.0018576998 +321 442 0.0022704999 +322 442 0.0031649999 +326 442 0.028347299 +339 442 0.00061919983 +340 442 0.00041279988 +341 442 0.0030273998 +351 442 0.0023392998 +356 442 0.0030961998 +358 442 0.0048850998 +364 442 0.0024080998 +369 442 6.8799985e-05 +370 442 0.00020639999 +371 442 6.8799985e-05 +372 442 0.00027519977 +380 442 6.8799985e-05 +384 442 6.8799985e-05 +385 442 0.0017888998 +386 442 0.00055039977 +387 442 6.8799985e-05 +390 442 0.00020639999 +392 442 0.00013759999 +393 442 0.00041279988 +398 442 0.00013759999 +402 442 0.00020639999 +409 442 6.8799985e-05 +415 442 6.8799985e-05 +417 442 0.00061919983 +419 442 0.0018576998 +421 442 6.8799985e-05 +422 442 0.00027519977 +423 442 6.8799985e-05 +424 442 6.8799985e-05 +425 442 6.8799985e-05 +428 442 0.00061919983 +430 442 6.8799985e-05 +431 442 0.00013759999 +433 442 6.8799985e-05 +434 442 6.8799985e-05 +437 442 0.00020639999 +442 442 0.030755498 +443 442 0.0050226972 +444 442 0.0028209998 +445 442 0.013141599 +446 442 0.0010320998 +447 442 0.0060547963 +448 442 6.8799985e-05 +450 442 0.0053666979 +452 442 0.0056418963 +453 442 0.0012384998 +454 442 0.00055039977 +455 442 0.0399752 +456 442 0.00075679994 +457 442 0.010251798 +458 442 0.0034401999 +459 442 0.004403498 +460 442 0.0012384998 +463 442 0.023393396 +464 442 0.0018576998 +465 442 0.0050914995 +467 442 0.020916499 +468 442 0.023118198 +469 442 0.0074996985 +470 442 0.0083252974 +471 442 0.0024769998 +473 442 0.00020639999 +477 442 0.00020639999 +478 442 0.0015824998 +479 442 6.8799985e-05 +483 442 0.0022016999 +489 442 0.0024080998 +490 442 0.0025457998 +491 442 6.8799985e-05 +9 443 1.3299999e-05 +16 443 0.00017279999 +60 443 1.9899991e-05 +64 443 0.12640977 +79 443 6.5999993e-06 +82 443 1.9899991e-05 +83 443 1.3299999e-05 +84 443 1.3299999e-05 +108 443 1.9899991e-05 +113 443 2.6599999e-05 +114 443 6.6499997e-05 +123 443 0.00026579993 +126 443 3.9899998e-05 +127 443 6.5999993e-06 +134 443 2.6599999e-05 +141 443 0.00018609999 +143 443 1.3299999e-05 +150 443 0.00045189983 +154 443 0.00036549987 +169 443 1.3299999e-05 +187 443 0.000206 +189 443 0.0001662 +190 443 0.00011959999 +192 443 5.3199998e-05 +194 443 0.00011299999 +196 443 1.9899991e-05 +197 443 2.6599999e-05 +198 443 0.00023929999 +200 443 5.979999e-05 +201 443 2.6599999e-05 +203 443 9.9699988e-05 +204 443 0.0011564 +206 443 0.00072439993 +207 443 7.9799996e-05 +209 443 2.6599999e-05 +214 443 0.0004319998 +217 443 0.0010633999 +218 443 2.6599999e-05 +219 443 6.5999993e-06 +220 443 1.3299999e-05 +223 443 0.00043859985 +229 443 3.9899998e-05 +230 443 6.5999993e-06 +233 443 0.00013289999 +234 443 0.023520697 +237 443 0.0004319998 +240 443 0.00036549987 +241 443 0.0002326 +242 443 0.00043859985 +248 443 1.3299999e-05 +250 443 6.5999993e-06 +251 443 6.5999993e-06 +252 443 0.00051839999 +263 443 6.5999993e-06 +270 443 7.3099989e-05 +271 443 0.0001794 +272 443 6.5999993e-06 +277 443 0.0019673 +279 443 6.5999993e-06 +282 443 0.0062872991 +283 443 0.0014288998 +284 443 3.3199991e-05 +292 443 0.00044529978 +293 443 0.00026579993 +294 443 9.9699988e-05 +295 443 8.6399989e-05 +296 443 0.00014619999 +297 443 9.2999995e-05 +312 443 0.00038549979 +315 443 6.5999993e-06 +317 443 0.00053169997 +318 443 9.2999995e-05 +319 443 0.00065129995 +322 443 0.0012494999 +323 443 1.3299999e-05 +324 443 0.00010629999 +326 443 0.0023726998 +327 443 9.2999995e-05 +328 443 0.002931 +340 443 0.00029909983 +341 443 0.00013289999 +351 443 0.0057887994 +356 443 4.649999e-05 +358 443 0.0002923999 +363 443 6.5999993e-06 +370 443 0.00013289999 +371 443 0.00018609999 +372 443 0.00087729981 +374 443 0.00029909983 +375 443 0.00021269999 +380 443 6.5999993e-06 +384 443 0.00035889982 +385 443 0.00025919988 +386 443 0.00019939999 +387 443 3.3199991e-05 +393 443 5.3199998e-05 +394 443 3.3199991e-05 +395 443 2.6599999e-05 +397 443 3.3199991e-05 +402 443 0.00041209999 +408 443 0.020782497 +412 443 0.00088389986 +414 443 0.00023929999 +417 443 6.5999993e-06 +419 443 6.5999993e-06 +422 443 0.00011299999 +423 443 6.5999993e-06 +425 443 6.5999993e-06 +430 443 2.6599999e-05 +431 443 1.9899991e-05 +432 443 1.9899991e-05 +433 443 5.979999e-05 +434 443 0.00015289999 +439 443 1.3299999e-05 +442 443 3.3199991e-05 +443 443 0.054571599 +444 443 0.00011959999 +445 443 0.010421198 +446 443 0.0006446999 +447 443 0.0021201 +448 443 0.00050509977 +449 443 0.013578098 +450 443 0.0065597966 +452 443 0.010035697 +453 443 0.0016681999 +454 443 0.0025189 +455 443 0.0096435994 +456 443 0.0007509999 +457 443 0.0034693 +458 443 0.00039209984 +459 443 0.0013557998 +460 443 0.0038081999 +463 443 0.016283099 +464 443 0.00012629999 +465 443 0.0014622 +467 443 0.012335297 +468 443 0.0014421998 +469 443 0.0082212985 +470 443 0.0036553999 +471 443 0.0026916999 +472 443 0.00041869981 +473 443 7.3099989e-05 +477 443 0.00011299999 +478 443 0.0015152998 +483 443 0.00107 +486 443 6.5999993e-06 +489 443 0.00049849995 +490 443 0.0028910998 +491 443 1.3299999e-05 +18 444 6.8799985e-05 +22 444 1.38e-05 +25 444 1.38e-05 +60 444 0.0023518999 +70 444 0.020355999 +108 444 4.1299994e-05 +114 444 0.00010999999 +126 444 4.1299994e-05 +134 444 0.00045389985 +135 444 4.1299994e-05 +150 444 0.0050614998 +153 444 0.00016499999 +187 444 0.0001926 +189 444 0.0001238 +190 444 0.00016499999 +192 444 9.6299991e-05 +194 444 9.6299991e-05 +196 444 6.8799985e-05 +197 444 0.00060519995 +198 444 0.00041259988 +200 444 1.38e-05 +201 444 1.38e-05 +202 444 2.7499991e-05 +203 444 9.6299991e-05 +204 444 0.002627 +206 444 0.00017879999 +207 444 6.8799985e-05 +209 444 2.7499991e-05 +223 444 0.0031633999 +229 444 0.0011002999 +230 444 0.00034389994 +231 444 0.00015129999 +233 444 6.8799985e-05 +234 444 0.043380197 +237 444 0.0079497993 +240 444 6.8799985e-05 +241 444 0.0011278 +242 444 0.0018155 +252 444 0.0012379 +272 444 0.00015129999 +282 444 0.00078399992 +283 444 0.0014028999 +307 444 1.38e-05 +308 444 8.2499988e-05 +309 444 1.38e-05 +313 444 0.0038235998 +317 444 0.00039889989 +318 444 2.7499991e-05 +319 444 2.7499991e-05 +322 444 0.0012516 +323 444 0.0001238 +328 444 0.0053640977 +340 444 0.00048139994 +341 444 4.1299994e-05 +350 444 9.6299991e-05 +351 444 0.0025306998 +354 444 9.6299991e-05 +356 444 2.7499991e-05 +358 444 0.00024759979 +366 444 6.8799985e-05 +368 444 2.7499991e-05 +370 444 0.00017879999 +371 444 0.0001375 +372 444 0.0035484999 +373 444 0.0011965998 +374 444 0.00038509979 +375 444 0.00053639989 +376 444 0.00075649982 +384 444 0.00042639999 +385 444 5.4999997e-05 +387 444 4.1299994e-05 +390 444 6.8799985e-05 +391 444 4.1299994e-05 +392 444 0.00042639999 +393 444 0.00016499999 +394 444 0.0037685998 +395 444 4.1299994e-05 +397 444 0.0032046998 +402 444 0.0175776 +408 444 0.0026544998 +412 444 0.0017604998 +422 444 0.0001238 +431 444 1.38e-05 +432 444 2.7499991e-05 +433 444 5.4999997e-05 +434 444 5.4999997e-05 +438 444 2.7499991e-05 +441 444 4.1299994e-05 +442 444 0.00059139985 +443 444 0.0017604998 +444 444 0.0065743998 +445 444 0.014758099 +446 444 0.0013478999 +447 444 0.00023379999 +448 444 0.00090779993 +449 444 0.0001926 +450 444 0.0067119971 +452 444 0.013753999 +453 444 0.0022419 +454 444 0.0040161982 +455 444 0.027081698 +456 444 0.0059554987 +457 444 0.0065606982 +458 444 0.0019393 +459 444 0.0001926 +460 444 0.013987798 +463 444 0.021538798 +464 444 5.4999997e-05 +465 444 0.0011965998 +467 444 0.016656097 +468 444 0.0086924993 +469 444 0.013795298 +470 444 0.0015816998 +471 444 0.040161699 +473 444 4.1299994e-05 +474 444 4.1299994e-05 +475 444 4.1299994e-05 +476 444 2.7499991e-05 +477 444 0.0007976999 +478 444 0.0016229998 +483 444 0.0017879999 +489 444 0.0070282966 +490 444 0.00017879999 +491 444 0.00056389999 +0 445 1.6499995e-05 +1 445 3.2999997e-06 +2 445 8.8899993e-05 +3 445 1.6499995e-05 +5 445 4.2799991e-05 +6 445 5.2699994e-05 +7 445 9.8999999e-06 +9 445 9.8999999e-06 +16 445 3.2999997e-06 +18 445 5.9299986e-05 +22 445 3.2999997e-06 +24 445 1.32e-05 +25 445 3.2999997e-06 +60 445 0.0029501999 +62 445 2.9599993e-05 +64 445 0.00015149999 +68 445 9.8799996e-05 +69 445 4.6099987e-05 +73 445 9.8999999e-06 +75 445 6.5999993e-06 +79 445 3.2999997e-06 +82 445 1.9799991e-05 +83 445 1.6499995e-05 +84 445 1.6499995e-05 +108 445 2.2999986e-05 +113 445 3.2899989e-05 +114 445 8.2299986e-05 +126 445 3.6199999e-05 +127 445 9.8999999e-06 +134 445 3.2999997e-06 +141 445 9.8999999e-06 +150 445 0.00020089999 +154 445 0.00077709998 +169 445 0.00010209999 +189 445 1.6499995e-05 +190 445 0.00011849999 +192 445 0.00038519991 +194 445 8.5599997e-05 +196 445 1.32e-05 +197 445 0.0001449 +198 445 0.00070789992 +200 445 3.6199999e-05 +201 445 2.2999986e-05 +203 445 8.2299986e-05 +204 445 0.0010042998 +206 445 0.00031279982 +207 445 5.9299986e-05 +209 445 1.9799991e-05 +214 445 0.00037539983 +215 445 0.000158 +217 445 4.9399998e-05 +219 445 3.2999997e-06 +223 445 0.00022059999 +229 445 0.00016459999 +233 445 0.00023049999 +234 445 0.027138099 +237 445 0.010543097 +240 445 3.2999997e-06 +241 445 3.2999997e-06 +242 445 0.00017779999 +248 445 1.32e-05 +250 445 9.8999999e-06 +251 445 3.2999997e-06 +252 445 2.2999986e-05 +263 445 3.2999997e-06 +271 445 3.2999997e-06 +272 445 0.00012839999 +277 445 3.2999997e-06 +279 445 3.2999997e-06 +282 445 6.5999993e-06 +283 445 9.8999999e-06 +313 445 1.6499995e-05 +316 445 0.00010539999 +317 445 0.0001317 +322 445 8.8899993e-05 +323 445 2.9599993e-05 +326 445 0.00027989992 +328 445 0.00055319979 +329 445 2.6299997e-05 +335 445 4.2799991e-05 +337 445 4.6099987e-05 +340 445 0.00014819999 +343 445 3.9499995e-05 +351 445 3.6199999e-05 +356 445 4.2799991e-05 +358 445 0.00033589988 +363 445 6.5999993e-06 +366 445 4.6099987e-05 +368 445 0.0001449 +372 445 9.8999999e-06 +375 445 3.2999997e-06 +376 445 3.2999997e-06 +380 445 6.5999993e-06 +384 445 2.2999986e-05 +387 445 3.2899989e-05 +392 445 3.2999997e-06 +393 445 2.9599993e-05 +394 445 0.00060909986 +397 445 0.00038849982 +401 445 0.0019195999 +402 445 0.0052385963 +408 445 2.2999986e-05 +412 445 0.00010209999 +419 445 9.8999999e-06 +422 445 9.55e-05 +423 445 1.32e-05 +425 445 9.8999999e-06 +430 445 2.2999986e-05 +431 445 1.6499995e-05 +432 445 1.6499995e-05 +433 445 4.6099987e-05 +434 445 5.599999e-05 +442 445 7.2399998e-05 +443 445 0.0037141 +444 445 0.00015479999 +445 445 0.1266225 +446 445 0.00071449997 +447 445 0.00037869997 +448 445 0.00056959991 +449 445 0.0031148999 +450 445 0.016440198 +452 445 0.00063549983 +453 445 0.00028649997 +454 445 0.00025349995 +455 445 0.025369897 +456 445 0.010299399 +457 445 0.0036778999 +458 445 0.000214 +459 445 0.00024369999 +460 445 0.015541296 +463 445 0.012390297 +464 445 0.00014159999 +465 445 0.00090549979 +467 445 0.023940898 +468 445 0.0011062999 +469 445 0.0048961975 +470 445 0.0040861964 +471 445 0.0393341 +473 445 8.5599997e-05 +476 445 1.6499995e-05 +477 445 2.9599993e-05 +478 445 0.0011755 +483 445 0.001373 +489 445 0.0014289999 +490 445 0.00031609996 +491 445 5.2699994e-05 +1 446 1.3399999e-05 +7 446 1.3399999e-05 +11 446 1.3399999e-05 +16 446 1.3399999e-05 +18 446 1.3399999e-05 +22 446 0.00012069999 +25 446 1.3399999e-05 +60 446 0.012515098 +66 446 8.0499987e-05 +68 446 0.0080616996 +69 446 0.0037826998 +73 446 0.0007511999 +75 446 0.00052309991 +82 446 0.00012069999 +83 446 1.3399999e-05 +84 446 1.3399999e-05 +86 446 1.3399999e-05 +87 446 1.3399999e-05 +88 446 1.3399999e-05 +90 446 1.3399999e-05 +93 446 1.3399999e-05 +95 446 1.3399999e-05 +96 446 2.6799986e-05 +97 446 1.3399999e-05 +105 446 2.6799986e-05 +106 446 1.3399999e-05 +108 446 6.7099987e-05 +114 446 0.00012069999 +115 446 1.3399999e-05 +121 446 1.3399999e-05 +122 446 1.3399999e-05 +125 446 1.3399999e-05 +126 446 4.0199986e-05 +134 446 0.00037559983 +141 446 0.0030180998 +150 446 0.0002950998 +153 446 1.3399999e-05 +154 446 0.00037559983 +187 446 2.6799986e-05 +189 446 9.3899987e-05 +190 446 0.00010729999 +192 446 2.6799986e-05 +194 446 8.0499987e-05 +196 446 1.3399999e-05 +197 446 1.3399999e-05 +198 446 8.0499987e-05 +200 446 6.7099987e-05 +201 446 2.6799986e-05 +203 446 6.7099987e-05 +204 446 0.00033529988 +206 446 0.00017439999 +207 446 4.0199986e-05 +209 446 1.3399999e-05 +214 446 0.0012474998 +215 446 1.3399999e-05 +217 446 0.00014759999 +223 446 9.3899987e-05 +228 446 1.3399999e-05 +229 446 6.7099987e-05 +230 446 2.6799986e-05 +231 446 4.0199986e-05 +233 446 0.00071089994 +234 446 0.036928199 +237 446 0.00028169993 +240 446 0.00079139997 +242 446 1.3399999e-05 +252 446 1.3399999e-05 +260 446 1.3399999e-05 +267 446 2.6799986e-05 +272 446 1.3399999e-05 +277 446 1.3399999e-05 +279 446 2.6799986e-05 +282 446 0.0015291998 +283 446 0.005808197 +295 446 0.001006 +296 446 0.00025489996 +316 446 0.0021193998 +317 446 0.0002950998 +318 446 2.6799986e-05 +319 446 0.00028169993 +322 446 0.0021327999 +324 446 0.00042919978 +326 446 0.0006573 +327 446 6.7099987e-05 +328 446 0.0019717999 +330 446 2.6799986e-05 +331 446 9.3899987e-05 +340 446 0.00033529988 +350 446 0.0023741999 +351 446 0.00081819994 +356 446 4.0199986e-05 +358 446 0.0013279999 +368 446 1.3399999e-05 +372 446 5.3699987e-05 +374 446 0.00046949997 +375 446 2.6799986e-05 +377 446 1.3399999e-05 +380 446 1.3399999e-05 +384 446 8.0499987e-05 +387 446 4.0199986e-05 +390 446 0.0011669998 +394 446 4.0199986e-05 +397 446 2.6799986e-05 +400 446 2.6799986e-05 +402 446 0.00026829983 +406 446 0.035130799 +407 446 0.0014754999 +412 446 0.0017437998 +413 446 1.3399999e-05 +414 446 0.0013414 +419 446 0.0014487 +422 446 0.00022799999 +431 446 1.3399999e-05 +432 446 1.3399999e-05 +433 446 2.6799986e-05 +434 446 2.6799986e-05 +442 446 0.0010998999 +443 446 0.0007511999 +444 446 6.7099987e-05 +445 446 0.0032460999 +446 446 0.27338696 +447 446 0.00021459999 +448 446 0.00013409999 +449 446 0.0120993 +450 446 0.0082762986 +452 446 0.0078067966 +453 446 0.0022400999 +454 446 0.0008450998 +455 446 0.013749197 +456 446 0.0006438999 +457 446 0.0035009999 +458 446 0.016847797 +459 446 0.0009657999 +460 446 0.018189099 +463 446 0.030167699 +464 446 8.0499987e-05 +465 446 0.00071089994 +467 446 0.038323298 +468 446 0.0040777996 +469 446 0.0028436999 +470 446 0.0019987 +471 446 0.0030314999 +473 446 5.3699987e-05 +474 446 1.3399999e-05 +477 446 4.0199986e-05 +478 446 0.00093899993 +483 446 0.00072429981 +486 446 0.0023339998 +489 446 0.00021459999 +490 446 0.042427897 +1 447 0.00024909992 +7 447 7.2999992e-06 +9 447 8.0599988e-05 +11 447 0.00035169977 +16 447 1.4699999e-05 +17 447 0.0001466 +18 447 7.2999992e-06 +22 447 7.2999992e-06 +25 447 7.2999992e-06 +60 447 0.0017074 +64 447 0.00087939994 +66 447 2.929999e-05 +68 447 0.0028944998 +69 447 0.0013629999 +73 447 0.00027109985 +75 447 0.0014728999 +79 447 7.2999992e-06 +82 447 0.0036199999 +83 447 0.00028579985 +84 447 0.00043969997 +86 447 0.00016119999 +87 447 0.0001832 +88 447 0.0001905 +89 447 0.00027109985 +90 447 0.00041039987 +91 447 4.3999986e-05 +92 447 9.5299998e-05 +93 447 0.00049099978 +94 447 2.1999993e-05 +95 447 0.00024909992 +96 447 0.00079139997 +97 447 0.00032239989 +98 447 5.1299998e-05 +99 447 7.2999992e-06 +100 447 3.6599988e-05 +103 447 1.4699999e-05 +105 447 0.00082069985 +106 447 3.6599988e-05 +107 447 7.3299991e-05 +108 447 0.00081339991 +109 447 0.00013189999 +113 447 6.5999993e-05 +114 447 0.00015389999 +115 447 0.00026379991 +116 447 0.00015389999 +121 447 0.00032239989 +122 447 0.0002272 +124 447 2.1999993e-05 +125 447 0.00016849999 +126 447 7.3299991e-05 +127 447 1.4699999e-05 +130 447 0.00025649997 +134 447 0.0001466 +141 447 2.1999993e-05 +150 447 0.00093799992 +152 447 5.1299998e-05 +154 447 0.00034439983 +169 447 3.6599988e-05 +187 447 1.4699999e-05 +189 447 1.4699999e-05 +190 447 0.00093799992 +192 447 3.6599988e-05 +193 447 7.2999992e-06 +194 447 9.5299998e-05 +195 447 4.3999986e-05 +196 447 0.00072549982 +197 447 2.1999993e-05 +198 447 0.0002272 +199 447 1.4699999e-05 +200 447 0.00011719999 +201 447 1.4699999e-05 +203 447 8.0599988e-05 +204 447 0.0018906 +206 447 0.00098189991 +207 447 5.8599995e-05 +209 447 1.4699999e-05 +214 447 0.00091599999 +217 447 3.6599988e-05 +219 447 8.79e-05 +223 447 0.00026379991 +228 447 7.2999992e-06 +229 447 0.0001466 +230 447 7.2999992e-06 +231 447 5.8599995e-05 +233 447 0.00011719999 +234 447 0.064676344 +237 447 0.0013776999 +240 447 0.00010989999 +241 447 0.00083539984 +242 447 0.00035909982 +248 447 1.4699999e-05 +250 447 7.2999992e-06 +251 447 7.2999992e-06 +252 447 6.5999993e-05 +263 447 7.2999992e-06 +267 447 7.2999992e-06 +272 447 7.2999992e-06 +277 447 1.4699999e-05 +282 447 4.3999986e-05 +283 447 7.2999992e-06 +284 447 2.1999993e-05 +317 447 0.0001905 +318 447 7.2999992e-06 +319 447 2.929999e-05 +322 447 0.0001832 +326 447 1.4699999e-05 +328 447 2.1999993e-05 +330 447 7.2999992e-06 +331 447 3.6599988e-05 +340 447 0.00015389999 +341 447 2.1999993e-05 +351 447 3.6599988e-05 +356 447 3.6599988e-05 +358 447 0.00049099978 +363 447 7.2999992e-06 +371 447 0.00032239989 +372 447 7.2999992e-06 +375 447 0.00024179999 +380 447 7.2999992e-06 +384 447 2.929999e-05 +385 447 0.00030779978 +387 447 6.5999993e-05 +388 447 3.6599988e-05 +390 447 0.00026379991 +391 447 0.00040299981 +392 447 0.0008280999 +393 447 0.0014509 +394 447 0.00065219984 +395 447 0.0001832 +397 447 0.00088669988 +402 447 0.00012459999 +403 447 0.0063825995 +404 447 0.015300699 +405 447 0.013197597 +408 447 0.0001466 +412 447 0.00043969997 +413 447 7.2999992e-06 +414 447 0.0001832 +419 447 1.4699999e-05 +422 447 0.00010989999 +423 447 2.1999993e-05 +425 447 1.4699999e-05 +430 447 2.929999e-05 +431 447 2.929999e-05 +432 447 1.4699999e-05 +433 447 5.1299998e-05 +434 447 5.8599995e-05 +441 447 0.0001905 +442 447 0.00033709989 +443 447 0.0014288998 +444 447 0.00040299981 +445 447 0.011358298 +446 447 0.0017146999 +447 447 0.036822896 +448 447 0.0013776999 +449 447 0.023346797 +450 447 0.011013899 +452 447 0.0020738 +453 447 0.0013043999 +454 447 0.0055984966 +455 447 0.018781498 +456 447 0.00065949978 +457 447 0.0057670996 +458 447 0.021302298 +459 447 0.0007693998 +460 447 0.0047044978 +463 447 0.012127697 +464 447 0.00093059987 +465 447 0.0017952998 +467 447 0.038434997 +468 447 0.016165398 +469 447 0.0032169998 +470 447 0.020606197 +471 447 0.0018173 +472 447 0.0010258998 +473 447 0.0001466 +474 447 7.2999992e-06 +477 447 0.00013189999 +478 447 0.0011064999 +483 447 0.00024909992 +489 447 0.00015389999 +490 447 0.046129398 +491 447 7.2999992e-06 +23 448 0.019549597 +67 448 0.061680298 +108 448 6.1899991e-05 +114 448 0.0001237 +126 448 6.1899991e-05 +154 448 0.0069907978 +187 448 0.00092799985 +189 448 0.0001237 +190 448 6.1899991e-05 +194 448 0.0001237 +197 448 6.1899991e-05 +203 448 0.0001237 +204 448 0.0001237 +206 448 0.0001237 +207 448 6.1899991e-05 +234 448 0.017136797 +237 448 0.00018559999 +272 448 0.004083097 +322 448 0.0045780987 +328 448 0.0028457998 +350 448 0.0054441988 +351 448 0.0051348992 +356 448 6.1899991e-05 +358 448 0.00018559999 +371 448 0.00018559999 +372 448 0.0016703999 +373 448 0.00049489993 +387 448 6.1899991e-05 +389 448 0.0003711998 +393 448 0.00061869994 +402 448 6.1899991e-05 +414 448 0.0031551998 +422 448 0.0001237 +433 448 6.1899991e-05 +434 448 6.1899991e-05 +443 448 0.0003711998 +444 448 6.1899991e-05 +445 448 0.0065577999 +446 448 0.00068049994 +447 448 0.0047636963 +448 448 0.0013609999 +450 448 0.0044542998 +452 448 0.043182399 +453 448 0.010888398 +454 448 0.0022272 +455 448 0.0071145967 +457 448 0.015590198 +458 448 0.00068049994 +459 448 0.00098989997 +460 448 0.0076713972 +463 448 0.013486799 +464 448 0.0001237 +465 448 0.00068049994 +467 448 0.013362996 +468 448 0.00092799985 +469 448 0.0052585974 +470 448 0.0025364999 +471 448 0.0044542998 +473 448 6.1899991e-05 +478 448 0.0028457998 +483 448 0.0001237 +489 448 6.1899991e-05 +490 448 0.00024749991 +9 449 0.00016499999 +16 449 8.2499988e-05 +60 449 0.0034641998 +79 449 8.2499988e-05 +82 449 0.00016499999 +83 449 0.00016499999 +84 449 0.00016499999 +108 449 0.00024739979 +113 449 0.00032989983 +114 449 0.00049489993 +126 449 0.00024739979 +127 449 8.2499988e-05 +169 449 0.0027218999 +189 449 0.00024739979 +190 449 0.00024739979 +192 449 0.00024739979 +194 449 0.00049489993 +196 449 0.00016499999 +197 449 0.00016499999 +198 449 0.0016496 +200 449 0.00032989983 +201 449 0.00016499999 +203 449 0.00041239988 +204 449 0.002227 +206 449 0.00098979985 +207 449 0.00032989983 +209 449 0.00016499999 +223 449 0.00024739979 +234 449 0.0010722999 +237 449 0.0032992 +242 449 0.0026393998 +248 449 8.2499988e-05 +250 449 8.2499988e-05 +252 449 0.00016499999 +272 449 8.2499988e-05 +317 449 0.0010722999 +356 449 8.2499988e-05 +358 449 0.00032989983 +363 449 8.2499988e-05 +384 449 8.2499988e-05 +387 449 0.00024739979 +394 449 0.00024739979 +397 449 0.00032989983 +402 449 0.0014022 +412 449 0.0018970999 +419 449 8.2499988e-05 +422 449 0.00049489993 +423 449 0.00016499999 +425 449 8.2499988e-05 +430 449 0.00024739979 +431 449 0.00016499999 +432 449 0.00016499999 +433 449 0.00024739979 +434 449 0.00032989983 +443 449 0.00024739979 +444 449 0.0037115999 +445 449 0.0038765999 +446 449 8.2499988e-05 +447 449 0.0037115999 +449 449 8.2499988e-05 +450 449 0.024166897 +452 449 0.0017320998 +453 449 0.0006597999 +454 449 0.0032992 +455 449 0.0044539981 +456 449 0.0019794998 +457 449 0.025074199 +458 449 0.0017320998 +459 449 0.00041239988 +460 449 0.029280797 +463 449 0.055262297 +464 449 0.0027218999 +465 449 0.0020619999 +467 449 0.024744298 +468 449 0.022352397 +469 449 0.018888198 +470 449 0.024661798 +471 449 0.0013196999 +473 449 0.00049489993 +477 449 0.0016496 +478 449 0.0027218999 +483 449 0.005773697 +489 449 0.00098979985 +490 449 0.0018970999 +9 450 1.3e-05 +16 450 6.4999995e-06 +18 450 0.0027947 +63 450 0.029890999 +79 450 3.2999997e-06 +82 450 2.2799999e-05 +83 450 1.6299993e-05 +84 450 1.3e-05 +108 450 2.929999e-05 +113 450 3.5899997e-05 +114 450 8.7999986e-05 +126 450 4.2399988e-05 +127 450 6.4999995e-06 +150 450 0.00044999993 +187 450 3.2999997e-06 +189 450 0.00029679993 +190 450 9.7799988e-05 +192 450 9.1299997e-05 +194 450 0.00018589999 +196 450 3.2599986e-05 +197 450 5.54e-05 +200 450 5.54e-05 +201 450 2.6099995e-05 +203 450 0.00018259999 +204 450 0.0015391998 +206 450 0.0012163999 +207 450 0.00014349999 +209 450 0.00016629999 +219 450 9.7999991e-06 +223 450 1.6299993e-05 +234 450 0.00042069983 +237 450 0.0001141 +240 450 0.00013039999 +241 450 6.4999995e-06 +248 450 1.6299993e-05 +250 450 9.7999991e-06 +251 450 3.2999997e-06 +252 450 1.6299993e-05 +263 450 3.2999997e-06 +272 450 3.2999997e-06 +279 450 6.4999995e-06 +295 450 0.00059029995 +322 450 3.2999997e-06 +359 450 0.0001011 +363 450 1.3e-05 +380 450 3.2999997e-06 +384 450 0.00047609978 +387 450 3.5899997e-05 +389 450 0.018637098 +390 450 0.00059029995 +392 450 0.0012750998 +393 450 7.83e-05 +394 450 9.7999991e-06 +395 450 0.00010759999 +397 450 6.4999995e-06 +402 450 4.5699999e-05 +412 450 0.00034569995 +419 450 6.4999995e-06 +422 450 0.00021849999 +423 450 1.3e-05 +425 450 9.7999991e-06 +430 450 2.6099995e-05 +431 450 2.6099995e-05 +432 450 3.9099992e-05 +433 450 0.00010759999 +434 450 0.00016629999 +442 450 7.4999989e-05 +443 450 5.54e-05 +444 450 0.00078589981 +445 450 0.0012945998 +446 450 2.2799999e-05 +447 450 0.00086419983 +448 450 9.7999991e-06 +449 450 9.7999991e-06 +450 450 0.0133182 +452 450 0.0052046999 +453 450 0.00033919979 +454 450 0.0010239999 +455 450 0.0016728998 +456 450 0.0003847999 +457 450 0.0035969999 +458 450 0.00031959987 +459 450 0.0036231 +460 450 0.0018000999 +463 450 0.019996896 +464 450 0.001187 +465 450 0.0033490998 +467 450 0.013367198 +468 450 0.015812997 +469 450 0.0013630998 +470 450 0.0043730997 +471 450 0.0032414999 +472 450 0.00020539999 +473 450 9.1299997e-05 +477 450 4.8899994e-05 +478 450 0.0011445999 +483 450 0.0042947978 +489 450 0.00049239979 +490 450 0.012303997 +450 451 0.023809496 +463 451 0.071428597 +467 451 0.023809496 +468 451 0.023809496 +469 451 0.023809496 +472 451 0.14285707 +473 451 0.071428597 +9 452 9.4999996e-06 +16 452 8.849999e-05 +18 452 0.0029249999 +22 452 0.082447052 +25 452 7.5899996e-05 +65 452 0.043742198 +72 452 0.0024569998 +79 452 3.1999998e-06 +82 452 1.26e-05 +83 452 9.4999996e-06 +84 452 9.4999996e-06 +108 452 1.8999999e-05 +113 452 2.2099994e-05 +114 452 6.3199986e-05 +126 452 3.1599993e-05 +127 452 3.1999998e-06 +135 452 2.2099994e-05 +150 452 0.00039529987 +187 452 7.5899996e-05 +188 452 1.5799989e-05 +189 452 0.00017079999 +190 452 6.3199986e-05 +192 452 0.00012649999 +194 452 0.00027829991 +195 452 6.2999998e-06 +196 452 5.0599992e-05 +197 452 7.5899996e-05 +200 452 4.4299988e-05 +201 452 5.6899997e-05 +203 452 0.00027189986 +204 452 0.00064819981 +206 452 0.0010529999 +207 452 0.00020549999 +209 452 6.3199986e-05 +214 452 0.00078419992 +217 452 6.2999998e-06 +219 452 1.26e-05 +223 452 0.0029187 +228 452 2.8499999e-05 +229 452 5.6899997e-05 +230 452 2.8499999e-05 +231 452 2.8499999e-05 +234 452 0.044997599 +237 452 0.00031309994 +240 452 0.00023719999 +241 452 6.2999998e-06 +242 452 0.00077469996 +248 452 9.4999996e-06 +250 452 6.2999998e-06 +251 452 3.1999998e-06 +252 452 7.5899996e-05 +254 452 0.0001107 +263 452 3.1999998e-06 +272 452 3.1999998e-06 +277 452 0.0001581 +279 452 9.4999996e-06 +295 452 0.00032249978 +315 452 9.4999996e-06 +317 452 6.9599992e-05 +322 452 0.00010439999 +327 452 0.0027037 +328 452 0.00056599989 +351 452 0.00027829991 +352 452 7.9099991e-05 +356 452 0.00029409979 +357 452 9.4999996e-06 +358 452 3.1599993e-05 +359 452 0.00016129999 +363 452 1.5799989e-05 +369 452 8.849999e-05 +370 452 0.00058819982 +371 452 1.5799989e-05 +375 452 0.0001107 +380 452 3.1999998e-06 +384 452 0.0016442998 +387 452 2.2099994e-05 +393 452 3.1599993e-05 +394 452 3.4799988e-05 +396 452 2.2099994e-05 +397 452 3.1999998e-06 +402 452 0.00028459984 +412 452 7.2699986e-05 +413 452 9.4999996e-06 +414 452 4.7399997e-05 +417 452 2.2099994e-05 +419 452 3.1999998e-06 +422 452 0.0003668 +423 452 6.2999998e-06 +425 452 3.1999998e-06 +430 452 1.5799989e-05 +431 452 3.7899998e-05 +432 452 5.6899997e-05 +433 452 0.0001486 +434 452 0.0001929 +438 452 6.2999998e-06 +443 452 0.0075670965 +444 452 0.00020549999 +445 452 0.0060207993 +446 452 0.0020521998 +447 452 0.00059759989 +448 452 0.0002024 +449 452 6.2999998e-06 +450 452 0.0044997968 +452 452 0.11142516 +453 452 0.038730197 +454 452 0.0012078998 +455 452 0.012642298 +456 452 0.00047429977 +457 452 0.0035700998 +458 452 0.0002024 +459 452 0.0063021965 +460 452 0.0017676998 +463 452 0.011465997 +464 452 0.00038259989 +465 452 0.0057234988 +467 452 0.012964897 +468 452 0.0017835 +469 452 0.0033455999 +470 452 0.0033233999 +471 452 0.0028743998 +472 452 0.00014229999 +473 452 6.0099992e-05 +475 452 2.5299989e-05 +477 452 6.0099992e-05 +478 452 0.00036359997 +483 452 0.0032096 +489 452 0.00018019999 +490 452 0.00026879995 +491 452 6.2999998e-06 +7 453 4.7999993e-06 +9 453 4.7999993e-06 +16 453 7.1999995e-05 +18 453 1.9199986e-05 +19 453 6.7199988e-05 +22 453 4.3199994e-05 +23 453 0.17643529 +25 453 4.7999993e-06 +60 453 0.00033609988 +66 453 0.0191787 +68 453 0.0037838998 +69 453 0.0017766999 +73 453 0.00035049999 +74 453 0.00052819983 +75 453 0.00023529999 +79 453 4.7999993e-06 +82 453 4.7999993e-06 +83 453 4.7999993e-06 +84 453 4.7999993e-06 +108 453 4.7999993e-06 +113 453 9.5999994e-06 +114 453 2.3999994e-05 +126 453 1.44e-05 +127 453 4.7999993e-06 +150 453 0.0001489 +153 453 4.7999993e-06 +187 453 9.5999994e-06 +189 453 8.1599996e-05 +190 453 3.3599994e-05 +192 453 1.44e-05 +194 453 4.7999987e-05 +196 453 4.7999993e-06 +197 453 1.44e-05 +200 453 1.44e-05 +201 453 9.5999994e-06 +203 453 3.3599994e-05 +204 453 8.6399989e-05 +206 453 0.00032649981 +207 453 2.8799986e-05 +209 453 4.7999993e-06 +214 453 0.00066749984 +215 453 4.7999993e-06 +217 453 4.3199994e-05 +223 453 3.8399987e-05 +228 453 4.7999993e-06 +229 453 3.3599994e-05 +230 453 1.44e-05 +231 453 1.9199986e-05 +233 453 4.7999993e-06 +234 453 0.00079229986 +237 453 0.00018249999 +248 453 4.7999993e-06 +250 453 4.7999993e-06 +252 453 2.3999994e-05 +267 453 1.9199986e-05 +272 453 4.7999993e-06 +277 453 0.00023529999 +278 453 2.3999994e-05 +281 453 4.7999993e-06 +282 453 1.44e-05 +288 453 4.7999993e-06 +290 453 9.5999994e-06 +307 453 1.44e-05 +312 453 4.7999993e-06 +317 453 2.8799986e-05 +319 453 4.7999993e-06 +324 453 4.7999987e-05 +326 453 1.9199986e-05 +328 453 3.8399987e-05 +330 453 9.5999994e-06 +331 453 5.2799995e-05 +333 453 8.6399989e-05 +340 453 9.5999994e-06 +350 453 3.8399987e-05 +351 453 4.7999993e-06 +354 453 1.9199986e-05 +356 453 0.00020169999 +358 453 5.7599987e-05 +359 453 5.7599987e-05 +368 453 4.7999993e-06 +369 453 4.7999993e-06 +370 453 4.7999993e-06 +372 453 7.1999995e-05 +374 453 1.44e-05 +375 453 4.7999993e-06 +384 453 0.00033129985 +385 453 4.7999993e-06 +387 453 9.5999994e-06 +393 453 4.3199994e-05 +394 453 2.3999994e-05 +402 453 6.2399995e-05 +404 453 4.7999993e-06 +412 453 0.0001008 +413 453 9.5999994e-06 +414 453 0.00011519999 +419 453 4.7999993e-06 +422 453 5.2799995e-05 +423 453 4.7999993e-06 +425 453 4.7999993e-06 +430 453 4.7999993e-06 +431 453 9.5999994e-06 +432 453 4.7999993e-06 +433 453 1.44e-05 +434 453 4.3199994e-05 +438 453 4.7999993e-06 +442 453 4.7999993e-06 +443 453 0.00013449999 +444 453 0.00038409978 +445 453 0.00035049999 +446 453 5.2799995e-05 +447 453 0.0008882999 +448 453 1.44e-05 +450 453 0.0022761 +452 453 0.0028426999 +453 453 0.35604936 +454 453 0.00068669999 +455 453 0.0008882999 +456 453 0.00034569995 +457 453 0.0036109998 +458 453 0.0001585 +459 453 0.0021559999 +460 453 0.0012965 +463 453 0.0092051998 +464 453 0.00066749984 +465 453 0.0021849 +467 453 0.0065641999 +468 453 0.00093159988 +469 453 0.0030491999 +470 453 0.0012772998 +471 453 0.0010084 +473 453 2.3999994e-05 +474 453 4.7999993e-06 +478 453 0.00052339979 +483 453 0.0026554 +489 453 0.00018249999 +490 453 9.5999989e-05 +491 453 2.3999994e-05 +7 454 0.000118 +9 454 3.3699995e-05 +16 454 0.00013479999 +18 454 0.00025279983 +22 454 0.00067409989 +25 454 0.000118 +60 454 0.0063873976 +65 454 0.00023589999 +66 454 0.00091009983 +68 454 0.1192531 +69 454 0.043632898 +72 454 1.6899998e-05 +73 454 0.0083759986 +75 454 0.0056794994 +79 454 1.6899998e-05 +82 454 5.0599992e-05 +83 454 3.3699995e-05 +84 454 3.3699995e-05 +108 454 5.0599992e-05 +113 454 8.4299987e-05 +114 454 0.00013479999 +126 454 6.7399989e-05 +127 454 1.6899998e-05 +134 454 5.0599992e-05 +150 454 0.0010785998 +152 454 5.0599992e-05 +153 454 6.7399989e-05 +187 454 0.00016849999 +188 454 1.6899998e-05 +189 454 0.00016849999 +190 454 0.00026969984 +192 454 5.0599992e-05 +194 454 0.00015169999 +196 454 5.0599992e-05 +197 454 6.7399989e-05 +200 454 3.3699995e-05 +201 454 1.6899998e-05 +202 454 3.3699995e-05 +203 454 0.0001011 +204 454 0.0011292 +206 454 0.00025279983 +207 454 8.4299987e-05 +209 454 3.3699995e-05 +214 454 0.015386898 +215 454 0.000118 +217 454 0.00097749988 +218 454 5.0599992e-05 +219 454 1.6899998e-05 +223 454 0.000118 +228 454 0.00016849999 +229 454 0.00074149994 +230 454 0.00030339998 +231 454 0.00047189998 +234 454 0.011207398 +237 454 0.00094379997 +240 454 5.0599992e-05 +248 454 1.6899998e-05 +250 454 1.6899998e-05 +252 454 0.00016849999 +267 454 0.00033709989 +272 454 6.7399989e-05 +317 454 0.00074149994 +327 454 1.6899998e-05 +329 454 3.3699995e-05 +330 454 0.00023589999 +331 454 0.0010617999 +356 454 0.00030339998 +358 454 5.0599992e-05 +359 454 1.6899998e-05 +363 454 1.6899998e-05 +368 454 0.000118 +384 454 0.0041458979 +387 454 6.7399989e-05 +393 454 1.6899998e-05 +394 454 0.00026969984 +397 454 1.6899998e-05 +402 454 0.00032019988 +412 454 0.00018539999 +413 454 0.0002022 +414 454 0.00040449994 +419 454 1.6899998e-05 +422 454 0.00016849999 +423 454 3.3699995e-05 +425 454 1.6899998e-05 +430 454 5.0599992e-05 +431 454 5.0599992e-05 +432 454 1.6899998e-05 +433 454 6.7399989e-05 +434 454 8.4299987e-05 +438 454 6.7399989e-05 +442 454 1.6899998e-05 +443 454 0.0020728998 +444 454 0.00015169999 +445 454 0.013583697 +446 454 0.00092689996 +447 454 0.0012302999 +448 454 0.00023589999 +450 454 0.011881497 +452 454 0.009555798 +453 454 0.017678998 +454 454 0.028802097 +455 454 0.0066401996 +456 454 0.0029829999 +457 454 0.0030503999 +458 454 3.3699995e-05 +459 454 0.0042469986 +460 454 0.0039435998 +463 454 0.017173398 +464 454 0.0002022 +465 454 0.0011459999 +467 454 0.019920498 +468 454 0.0013987999 +469 454 0.0089826994 +470 454 0.0066738985 +471 454 0.0062524974 +473 454 0.00013479999 +474 454 0.000118 +475 454 3.3699995e-05 +476 454 1.6899998e-05 +477 454 3.3699995e-05 +478 454 0.00021909999 +483 454 0.0034717999 +489 454 0.00032019988 +490 454 0.00050559989 +491 454 1.6899998e-05 +9 455 4.7999993e-06 +16 455 0.0001165 +17 455 7.6999995e-06 +18 455 0.00072969985 +60 455 0.0024815998 +75 455 0.0002407 +79 455 1.3499999e-05 +82 455 3.0799987e-05 +83 455 3.4699988e-05 +84 455 0.00014629999 +97 455 0.0001223 +101 455 4.6199988e-05 +105 455 3.9499995e-05 +108 455 4.1399995e-05 +113 455 0.0002483998 +114 455 0.00017809999 +115 455 4.8099988e-05 +123 455 3.2699987e-05 +126 455 9.5299998e-05 +127 455 2.7899994e-05 +141 455 4.9099996e-05 +149 455 3.2699987e-05 +150 455 0.00020699999 +153 455 0.00071519986 +158 455 7.5999997e-05 +162 455 2.2099994e-05 +169 455 0.00030129985 +171 455 1.5399986e-05 +187 455 0.000978 +189 455 0.00082399999 +190 455 0.000128 +192 455 0.00084039988 +193 455 0.0015776998 +194 455 0.00020309999 +195 455 9.2399991e-05 +196 455 4.7199996e-05 +197 455 0.00045049982 +198 455 0.0022304 +200 455 4.1399995e-05 +201 455 4.0399987e-05 +203 455 0.00023779999 +204 455 0.0010974 +206 455 0.0008278999 +207 455 0.0002387 +209 455 7.1199989e-05 +219 455 1.8299994e-05 +223 455 6.7399989e-05 +229 455 0.00020309999 +230 455 0.0002002 +234 455 0.0086067989 +237 455 0.0011339998 +240 455 6.3499989e-05 +241 455 0.0013341999 +242 455 4.8099988e-05 +248 455 3.7499995e-05 +250 455 8.6999999e-06 +251 455 1.25e-05 +252 455 6.8299996e-05 +253 455 0.00031289994 +263 455 7.6999995e-06 +272 455 1.7299986e-05 +276 455 3.2699987e-05 +279 455 9.5999994e-06 +284 455 2.6999987e-05 +316 455 9.2399991e-05 +318 455 2.3099987e-05 +322 455 9.429999e-05 +323 455 3.8999997e-06 +326 455 2.4999987e-05 +330 455 7.2199997e-05 +335 455 6.6999992e-06 +337 455 6.1599989e-05 +340 455 0.00014439999 +356 455 7.6999995e-06 +358 455 0.00038219988 +359 455 6.7399989e-05 +362 455 1.06e-05 +363 455 2.0199994e-05 +366 455 0.00048029982 +368 455 8.279999e-05 +380 455 6.2599996e-05 +384 455 5.5799988e-05 +387 455 1.5399986e-05 +393 455 3.1799995e-05 +394 455 0.00010199999 +397 455 9.429999e-05 +402 455 0.00037929998 +412 455 0.00011359999 +419 455 3.4699988e-05 +422 455 0.00030799978 +423 455 2.7899994e-05 +425 455 1.25e-05 +430 455 1.5399986e-05 +431 455 4.8099988e-05 +432 455 5.2899995e-05 +433 455 0.00014539999 +434 455 0.0001944 +438 455 8.089999e-05 +442 455 2.6999987e-05 +443 455 0.00051309983 +444 455 0.0022341998 +445 455 0.015707098 +446 455 0.00039269985 +447 455 0.0032046 +448 455 0.0001848 +449 455 0.00037639984 +450 455 0.019686598 +452 455 0.0056803972 +453 455 0.0006920998 +454 455 0.0016643999 +455 455 0.017598599 +456 455 0.0033912999 +457 455 0.0067344978 +458 455 0.00034939987 +459 455 0.00043609994 +460 455 0.0051172972 +463 455 0.023017198 +464 455 0.0041546971 +465 455 0.0031746998 +467 455 0.018062599 +468 455 0.029311799 +469 455 0.0131003 +470 455 0.0187345 +471 455 0.020459499 +473 455 0.00024349999 +477 455 0.0001107 +478 455 0.0023930999 +483 455 0.0033960999 +489 455 0.00096939993 +490 455 0.0011935998 +491 455 3.7499995e-05 +7 456 8.9999997e-07 +9 456 1.3999999e-05 +16 456 6.9999996e-06 +17 456 8.9999997e-07 +18 456 0.00025359984 +22 456 1.6999993e-06 +25 456 8.9999997e-07 +59 456 1.1399999e-05 +60 456 0.0048253983 +64 456 9.5999994e-06 +66 456 8.6999999e-06 +68 456 0.00090249977 +69 456 0.00042409985 +73 456 8.3999999e-05 +75 456 0.00039609987 +79 456 3.4999994e-06 +82 456 1.9199986e-05 +83 456 1.5699989e-05 +84 456 1.49e-05 +108 456 2.539999e-05 +113 456 3.499999e-05 +114 456 8.659999e-05 +126 456 4.2e-05 +127 456 5.1999996e-06 +134 456 1.6999993e-06 +135 456 3.3199991e-05 +141 456 7.8999992e-06 +142 456 5.9499987e-05 +150 456 0.00013029999 +152 456 3.4999994e-06 +153 456 8.9999997e-07 +154 456 6.3799991e-05 +171 456 8.9999997e-07 +187 456 0.00058769993 +189 456 0.00022649999 +190 456 0.00030339998 +192 456 0.0003209 +193 456 0.0035722998 +194 456 4.3999999e-06 +195 456 0.00021079999 +196 456 8.9999997e-07 +197 456 0.0001583 +198 456 0.0011787999 +201 456 7.8999992e-06 +203 456 4.3999999e-06 +204 456 0.001129 +206 456 9.36e-05 +207 456 3.4999994e-06 +209 456 8.9999997e-07 +214 456 0.00014339999 +215 456 1.6999993e-06 +217 456 9.5999994e-06 +220 456 8.9999997e-07 +223 456 4.8099988e-05 +228 456 1.6999993e-06 +229 456 7.8699988e-05 +230 456 0.00055619981 +231 456 4.3999999e-06 +233 456 3.4999994e-06 +234 456 0.0058432966 +237 456 0.00092429994 +240 456 5.3299998e-05 +241 456 0.00083509996 +242 456 1.49e-05 +248 456 6.3799991e-05 +250 456 6.0999992e-06 +251 456 4.3999999e-06 +252 456 1.6599995e-05 +253 456 0.00020899999 +260 456 8.9999997e-07 +263 456 2.5999998e-06 +267 456 3.4999994e-06 +272 456 1.31e-05 +275 456 1.6999993e-06 +282 456 3.4999994e-06 +283 456 1.31e-05 +284 456 1.05e-05 +295 456 2.5999998e-06 +296 456 6.9999996e-06 +307 456 8.9999997e-07 +315 456 3.3199991e-05 +316 456 7.8999992e-06 +317 456 7.8999992e-06 +319 456 2.5999998e-06 +322 456 0.00032009999 +323 456 2.5999998e-06 +324 456 8.9999997e-07 +326 456 1.6999993e-06 +328 456 3.4999994e-06 +330 456 2.5999998e-06 +331 456 1.2199999e-05 +335 456 5.1999996e-06 +340 456 6.9999995e-05 +346 456 1.05e-05 +350 456 5.1999996e-06 +351 456 5.1999996e-06 +356 456 1.1399999e-05 +358 456 0.00010059999 +359 456 2.8899987e-05 +364 456 0.0001679 +366 456 6.8199995e-05 +368 456 3.4999994e-06 +370 456 8.9999997e-07 +374 456 8.9999997e-07 +377 456 6.0999992e-06 +380 456 1.2199999e-05 +382 456 1.1399999e-05 +384 456 0.00015129999 +387 456 3.5899997e-05 +389 456 8.9999997e-07 +390 456 2.5999998e-06 +393 456 2.4499997e-05 +394 456 9.0099988e-05 +397 456 8.0499987e-05 +402 456 0.00026849983 +406 456 7.5199991e-05 +407 456 2.5999998e-06 +408 456 5.1999996e-06 +412 456 1.31e-05 +413 456 1.6999993e-06 +414 456 2.5999998e-06 +419 456 7.8999992e-06 +422 456 0.0001163 +423 456 8.6999999e-06 +425 456 1.3999999e-05 +430 456 2.2699998e-05 +431 456 4.3999999e-06 +432 456 8.9999997e-07 +433 456 3.4999994e-06 +434 456 1.49e-05 +435 456 0.0001758 +438 456 3.4999994e-06 +442 456 7.5199991e-05 +443 456 0.0002789998 +444 456 0.00011889999 +445 456 0.0026951998 +446 456 0.00071359985 +447 456 0.00030779978 +448 456 0.00012069999 +449 456 3.1499992e-05 +450 456 0.0089713968 +452 456 0.0184194 +453 456 0.0026033998 +454 456 0.00090069999 +455 456 0.0057663992 +456 456 0.0016273998 +457 456 0.0090911984 +458 456 0.00036729989 +459 456 0.00049059978 +460 456 0.005153399 +463 456 0.057630599 +464 456 0.00014949999 +465 456 0.0014648 +467 456 0.012564696 +468 456 0.034562498 +469 456 0.0053561963 +470 456 0.0044021979 +471 456 0.0065061972 +472 456 8.9199995e-05 +473 456 9.1799986e-05 +474 456 8.9999997e-07 +477 456 0.00031309994 +478 456 0.0015679998 +483 456 0.0057698973 +486 456 4.3699998e-05 +489 456 0.00052029989 +490 456 0.0016230999 +491 456 2.4499997e-05 +9 457 2.7499991e-05 +16 457 1.5699989e-05 +17 457 3.8999997e-06 +18 457 2.7499991e-05 +60 457 0.0075417981 +68 457 5.4899996e-05 +69 457 2.7499991e-05 +73 457 3.8999997e-06 +75 457 3.8999997e-06 +79 457 1.18e-05 +82 457 3.9199993e-05 +83 457 2.7499991e-05 +84 457 2.7499991e-05 +108 457 5.4899996e-05 +113 457 6.6699999e-05 +114 457 0.00017269999 +126 457 7.8499987e-05 +127 457 1.18e-05 +150 457 3.8999997e-06 +153 457 0.0017147998 +171 457 3.8999997e-06 +187 457 0.00089469994 +189 457 0.00087499991 +190 457 0.0001373 +192 457 0.00017659999 +194 457 0.00039629987 +196 457 7.4599986e-05 +197 457 0.00011379999 +199 457 7.4599986e-05 +200 457 0.0001295 +201 457 5.4899996e-05 +203 457 0.00037669996 +204 457 0.0097470991 +206 457 0.0035903999 +207 457 0.0073612966 +209 457 0.0012987999 +214 457 7.7999994e-06 +219 457 1.9599989e-05 +223 457 1.9599989e-05 +230 457 0.00014909999 +234 457 0.0020915 +237 457 5.4899996e-05 +240 457 1.9599989e-05 +241 457 1.18e-05 +248 457 3.1399992e-05 +250 457 1.5699989e-05 +251 457 7.7999994e-06 +252 457 2.349999e-05 +263 457 7.7999994e-06 +279 457 1.18e-05 +322 457 7.7999994e-06 +326 457 3.8999997e-06 +359 457 0.00078089978 +363 457 2.349999e-05 +380 457 1.18e-05 +384 457 0.0001256 +387 457 7.0599999e-05 +393 457 0.00029039988 +394 457 3.8999997e-06 +397 457 3.8999997e-06 +402 457 2.349999e-05 +412 457 7.4599986e-05 +419 457 1.5699989e-05 +422 457 0.00043159979 +423 457 1.5699989e-05 +425 457 1.5699989e-05 +430 457 4.7099995e-05 +431 457 6.2799998e-05 +432 457 7.8499987e-05 +433 457 0.000204 +434 457 0.00040809996 +442 457 3.8999997e-06 +443 457 0.0001295 +444 457 0.0002158 +445 457 0.0010476999 +446 457 8.6299988e-05 +447 457 0.00060819997 +448 457 3.5299992e-05 +449 457 1.5699989e-05 +450 457 0.015079699 +452 457 0.0082402974 +453 457 0.00081229978 +454 457 0.0018324999 +455 457 0.0029899999 +456 457 0.00058859983 +457 457 0.013529699 +458 457 0.0038257998 +459 457 0.027820699 +460 457 0.0026917998 +463 457 0.022617597 +464 457 0.00027469988 +465 457 0.0027780998 +467 457 0.063218594 +468 457 0.0166061 +469 457 0.015166 +470 457 0.0082794987 +471 457 0.0012085999 +472 457 0.0001452 +473 457 0.00017269999 +477 457 7.8499987e-05 +478 457 0.0025622998 +483 457 0.018540598 +486 457 0.0086090975 +489 457 0.00036489987 +490 457 0.00076119998 +9 458 7.0599999e-05 +16 458 3.5299992e-05 +18 458 7.0599999e-05 +60 458 0.0077514984 +79 458 1.7699989e-05 +82 458 0.0001236 +83 458 8.8299988e-05 +84 458 7.0599999e-05 +108 458 0.00015889999 +113 458 0.00019419999 +114 458 0.00047669979 +126 458 0.00022949999 +127 458 3.5299992e-05 +187 458 1.7699989e-05 +189 458 0.002472 +190 458 0.00024719979 +192 458 0.00040609995 +194 458 0.00091819977 +196 458 0.00015889999 +197 458 0.00026489981 +200 458 0.00031779986 +201 458 0.0001413 +203 458 0.00086519984 +204 458 0.023660697 +206 458 0.0019952999 +207 458 0.00065329997 +209 458 0.00075929984 +219 458 5.2999996e-05 +223 458 8.8299988e-05 +229 458 5.2999996e-05 +231 458 3.5299992e-05 +234 458 0.0056149997 +237 458 0.00086519984 +240 458 5.2999996e-05 +241 458 3.5299992e-05 +242 458 0.00044139987 +248 458 7.0599999e-05 +250 458 5.2999996e-05 +251 458 1.7699989e-05 +252 458 7.0599999e-05 +263 458 1.7699989e-05 +272 458 1.7699989e-05 +279 458 3.5299992e-05 +322 458 1.7699989e-05 +352 458 0.0001236 +363 458 5.2999996e-05 +380 458 1.7699989e-05 +384 458 0.00042379997 +387 458 0.00019419999 +394 458 7.0599999e-05 +397 458 8.8299988e-05 +402 458 0.0003707998 +412 458 0.00040609995 +419 458 3.5299992e-05 +422 458 0.00097109983 +423 458 7.0599999e-05 +425 458 5.2999996e-05 +430 458 0.0001413 +431 458 0.0001236 +432 458 0.00017659999 +433 458 0.00049439981 +434 458 0.00061799982 +442 458 0.0006002998 +443 458 0.00022949999 +444 458 0.0022953998 +445 458 0.0021364999 +446 458 0.00022949999 +447 458 0.0034254999 +448 458 0.0001236 +449 458 5.2999996e-05 +450 458 0.037115499 +452 458 0.020164598 +453 458 0.0034607998 +454 458 0.0088462979 +455 458 0.0061270967 +456 458 0.0024366998 +457 458 0.16089267 +458 458 0.036056098 +459 458 0.13617259 +460 458 0.0064271986 +463 458 0.11118758 +464 458 0.0035138 +465 458 0.0018187 +467 458 0.15382987 +468 458 0.022512998 +469 458 0.056891598 +470 458 0.023837298 +471 458 0.0099409968 +473 458 0.00049439981 +477 458 0.00019419999 +478 458 0.004537899 +483 458 0.018416498 +486 458 0.0380513 +489 458 0.00061799982 +490 458 0.0018187 +9 459 6.11e-05 +16 459 2.4399997e-05 +17 459 1.2199999e-05 +18 459 3.6599988e-05 +60 459 0.0011967998 +79 459 1.2199999e-05 +82 459 9.7699987e-05 +83 459 7.3299991e-05 +84 459 6.11e-05 +108 459 0.00010989999 +113 459 0.00015879999 +114 459 0.00039079995 +126 459 0.00019539999 +127 459 2.4399997e-05 +153 459 4.8799993e-05 +187 459 0.0017708 +189 459 0.0017463998 +190 459 7.3299991e-05 +192 459 0.00013429999 +194 459 0.00029309979 +196 459 4.8799993e-05 +197 459 9.7699987e-05 +200 459 0.0001465 +201 459 7.3299991e-05 +203 459 0.00028089993 +204 459 0.012065798 +206 459 0.0015020999 +207 459 0.0004151999 +209 459 9.7699987e-05 +219 459 1.2199999e-05 +223 459 2.4399997e-05 +234 459 0.00074499985 +237 459 0.00015879999 +240 459 1.2199999e-05 +241 459 2.4399997e-05 +248 459 6.11e-05 +250 459 3.6599988e-05 +251 459 1.2199999e-05 +252 459 4.8799993e-05 +263 459 1.2199999e-05 +279 459 1.2199999e-05 +326 459 1.2199999e-05 +359 459 2.4399997e-05 +363 459 2.4399997e-05 +380 459 2.4399997e-05 +384 459 2.4399997e-05 +387 459 0.00015879999 +393 459 1.2199999e-05 +394 459 1.2199999e-05 +397 459 1.2199999e-05 +402 459 3.6599988e-05 +412 459 0.00040299981 +419 459 3.6599988e-05 +422 459 0.00031749997 +423 459 3.6599988e-05 +425 459 3.6599988e-05 +430 459 9.7699987e-05 +431 459 3.6599988e-05 +432 459 4.8799993e-05 +433 459 0.00015879999 +434 459 0.00019539999 +442 459 1.2199999e-05 +443 459 0.00010989999 +444 459 0.00052509992 +445 459 0.0011479999 +446 459 7.3299991e-05 +447 459 0.0012945 +448 459 1.2199999e-05 +449 459 3.6599988e-05 +450 459 0.032094199 +452 459 0.0012335 +453 459 0.00029309979 +454 459 0.00087929983 +455 459 0.0025646 +456 459 0.0015020999 +457 459 0.018049899 +458 459 0.00065949978 +459 459 0.067595541 +460 459 0.0026011998 +461 459 0.002992 +463 459 0.040838297 +464 459 0.00067169988 +465 459 0.0015753999 +467 459 0.042035099 +468 459 0.0093057975 +469 459 0.012016997 +470 459 0.019918397 +471 459 0.0014898998 +473 459 0.00040299981 +474 459 3.6599988e-05 +477 459 8.5499996e-05 +478 459 0.0016730998 +483 459 0.017683599 +486 459 0.00025649997 +489 459 9.7699987e-05 +490 459 0.0015264999 +9 460 4.3099993e-05 +16 460 2.5199988e-05 +17 460 3.5999992e-06 +18 460 1.44e-05 +79 460 1.0799999e-05 +82 460 7.5499993e-05 +83 460 5.7499987e-05 +84 460 5.3899988e-05 +108 460 9.6999996e-05 +113 460 0.0001294 +114 460 0.00031979987 +126 460 0.0001509 +127 460 2.159999e-05 +150 460 3.5999992e-06 +171 460 3.5999992e-06 +187 460 0.0012612999 +189 460 0.0010636998 +190 460 1.44e-05 +192 460 0.00019759999 +194 460 0.00043119979 +196 460 7.9099991e-05 +197 460 0.0007689998 +200 460 0.00045639998 +201 460 0.00054259994 +203 460 0.00040969998 +204 460 0.0024614998 +206 460 0.0019619998 +207 460 0.00033059996 +209 460 0.00010419999 +219 460 2.159999e-05 +223 460 3.2299999e-05 +229 460 3.5999992e-06 +230 460 3.5999992e-06 +234 460 0.00048149982 +237 460 0.00024079999 +240 460 2.159999e-05 +241 460 2.5199988e-05 +242 460 0.00017249999 +248 460 4.6699992e-05 +250 460 3.2299999e-05 +251 460 1.0799999e-05 +252 460 3.9499995e-05 +263 460 1.0799999e-05 +272 460 3.5999992e-06 +279 460 7.1999993e-06 +315 460 3.5999992e-06 +322 460 7.1999993e-06 +326 460 7.1999993e-06 +359 460 0.0003054 +363 460 2.8699986e-05 +380 460 1.7999992e-05 +384 460 3.9499995e-05 +387 460 0.0001294 +393 460 0.00023719999 +394 460 1.7999992e-05 +397 460 2.5199988e-05 +402 460 0.00011499999 +412 460 6.8299996e-05 +419 460 2.8699986e-05 +422 460 0.00048509985 +423 460 3.5899997e-05 +425 460 2.8699986e-05 +430 460 8.2599989e-05 +431 460 6.4699998e-05 +432 460 7.9099991e-05 +433 460 0.00022999999 +434 460 0.00040609995 +442 460 7.1999993e-06 +443 460 0.00013299999 +444 460 0.00041679991 +445 460 0.0016385999 +446 460 6.8299996e-05 +447 460 0.00086959987 +448 460 1.0799999e-05 +449 460 2.8699986e-05 +450 460 0.011437897 +452 460 0.0014660999 +453 460 0.00062529999 +454 460 0.0012612999 +455 460 0.0023681 +456 460 0.0012182 +457 460 0.017967198 +458 460 0.0020661999 +459 460 0.0095082 +460 460 0.0083259977 +461 460 0.36792135 +463 460 0.012663297 +464 460 0.0005245998 +465 460 0.00033059996 +467 460 0.016109399 +468 460 0.0044594966 +469 460 0.0043587983 +470 460 0.015724897 +471 460 0.0023357 +472 460 0.00013659999 +473 460 0.00033419998 +474 460 0.0051888973 +477 460 0.00011859999 +478 460 0.0041036978 +483 460 0.0041072965 +486 460 3.5999992e-06 +489 460 0.00017609999 +490 460 0.0026375998 +9 461 0.0001068 +16 461 3.879999e-05 +17 461 9.6999993e-06 +60 461 0.004794199 +79 461 2.9099989e-05 +82 461 0.00017469999 +83 461 0.00013589999 +84 461 0.00013589999 +108 461 0.00020379999 +113 461 0.00029109977 +114 461 0.00072789984 +126 461 0.00033969991 +127 461 4.8499991e-05 +171 461 9.6999993e-06 +187 461 0.0043768995 +189 461 0.0033093998 +190 461 8.7299995e-05 +192 461 0.00015529999 +194 461 0.00033969991 +196 461 5.8199992e-05 +197 461 0.00040759984 +200 461 0.0006114 +201 461 0.0002135 +203 461 0.00032999995 +204 461 0.014780499 +206 461 0.0042312965 +207 461 0.00025229994 +209 461 8.7299995e-05 +219 461 1.9399988e-05 +223 461 0.00013589999 +234 461 0.0050561987 +237 461 0.0010384 +240 461 1.9399988e-05 +241 461 4.8499991e-05 +242 461 0.00038819993 +248 461 0.0001068 +250 461 6.7899993e-05 +251 461 3.879999e-05 +252 461 6.7899993e-05 +263 461 1.9399988e-05 +272 461 9.6999993e-06 +279 461 9.6999993e-06 +322 461 9.6999993e-06 +326 461 9.6999993e-06 +363 461 1.9399988e-05 +380 461 4.8499991e-05 +384 461 4.8499991e-05 +387 461 0.00028139981 +394 461 0.00017469999 +397 461 0.00020379999 +402 461 0.00017469999 +412 461 0.00029109977 +419 461 5.8199992e-05 +422 461 0.00042699999 +423 461 6.7899993e-05 +425 461 5.8199992e-05 +430 461 0.00019409999 +431 461 6.7899993e-05 +432 461 5.8199992e-05 +433 461 0.00019409999 +434 461 0.0002329 +442 461 1.9399988e-05 +443 461 0.00035909982 +444 461 0.0028531998 +445 461 0.0032607999 +446 461 0.00030089985 +447 461 0.0043671988 +448 461 0.00015529999 +449 461 0.00080549996 +450 461 0.059908196 +452 461 0.0070359968 +453 461 0.00035909982 +454 461 0.0015915998 +455 461 0.0072300993 +456 461 0.0042215995 +457 461 0.021515697 +458 461 0.00066959998 +459 461 0.0039983988 +460 461 0.0042506978 +463 461 0.055492498 +464 461 0.0048717968 +465 461 0.0096465982 +467 461 0.0523481 +468 461 0.024621297 +469 461 0.024533898 +470 461 0.0414689 +471 461 0.0150523 +473 461 0.00075699994 +477 461 9.6999996e-05 +478 461 0.017332897 +483 461 0.016721498 +486 461 0.00046579982 +489 461 0.0007375998 +490 461 0.0027561998 +7 462 0.00021519999 +18 462 0.0066920966 +59 462 0.069293857 +61 462 0.0034294999 +215 462 0.00046419981 +217 462 0.0001773 +241 462 0.0012935998 +242 462 0.00036509987 +303 462 0.00011739999 +330 462 0.00027379999 +412 462 7.1699993e-05 +443 462 5.35e-05 +445 462 0.00042769988 +446 462 5.1999996e-06 +447 462 2.5999998e-06 +455 462 0.000489 +457 462 0.0045078993 +458 462 0.0029508998 +460 462 0.015934698 +463 462 0.023242299 +467 462 0.0036289999 +469 462 0.0064351968 +486 462 0.0054233 +7 463 3.5599995e-05 +9 463 9.1999991e-06 +11 463 9.9999943e-07 +13 463 8.8599991e-05 +16 463 0.00094469986 +17 463 9.9999943e-07 +18 463 0.0009680998 +22 463 1.6299993e-05 +59 463 0.047734197 +60 463 0.0039569996 +61 463 0.00045709987 +62 463 0.0007685998 +75 463 0.00017199999 +79 463 3.1e-06 +82 463 1.8299994e-05 +83 463 1.2199999e-05 +84 463 1.12e-05 +85 463 1.9999998e-06 +90 463 1.9999998e-06 +93 463 9.9999943e-07 +94 463 9.9999943e-07 +105 463 9.9999943e-07 +108 463 1.7299986e-05 +113 463 2.549999e-05 +114 463 6.4099993e-05 +126 463 2.9499992e-05 +127 463 5.0999997e-06 +130 463 1.9999998e-06 +142 463 9.9999943e-07 +150 463 3.0499999e-05 +151 463 5.0999997e-06 +152 463 8.0999998e-06 +171 463 3.1e-06 +187 463 4.6799993e-05 +189 463 4.6799993e-05 +190 463 3.3599994e-05 +192 463 4.1699997e-05 +194 463 9.2599992e-05 +196 463 2.6499998e-05 +197 463 2.7499991e-05 +198 463 9.9999943e-07 +200 463 5.3999989e-05 +201 463 2.1399988e-05 +203 463 9.0599991e-05 +204 463 0.00012619999 +206 463 0.00021069999 +207 463 6.9199989e-05 +209 463 2.2399996e-05 +215 463 7.0199996e-05 +217 463 1.0199999e-05 +219 463 4.0999994e-06 +223 463 4.3799999e-05 +229 463 3.8699989e-05 +230 463 1.43e-05 +231 463 1.0199999e-05 +234 463 0.0045748986 +237 463 0.00049369992 +240 463 4.0999994e-06 +241 463 0.00039799977 +242 463 0.0001812 +248 463 1.2199999e-05 +250 463 6.0999992e-06 +251 463 3.1e-06 +252 463 1.12e-05 +263 463 1.9999998e-06 +272 463 1.9999998e-06 +279 463 3.1e-06 +303 463 4.069999e-05 +315 463 9.9999943e-07 +322 463 3.1e-06 +326 463 9.9999943e-07 +329 463 2.6499998e-05 +330 463 4.0999994e-06 +352 463 2.8499999e-05 +357 463 3.1e-06 +358 463 1.0199999e-05 +363 463 6.0999992e-06 +380 463 3.1e-06 +384 463 7.8399986e-05 +387 463 2.549999e-05 +394 463 4.6799993e-05 +397 463 4.8899994e-05 +402 463 4.069999e-05 +412 463 9.9999943e-07 +419 463 4.0999994e-06 +422 463 0.0001008 +423 463 6.0999992e-06 +425 463 4.0999994e-06 +428 463 9.9999943e-07 +430 463 1.7299986e-05 +431 463 1.32e-05 +432 463 1.8299994e-05 +433 463 4.8899994e-05 +434 463 6.0099992e-05 +435 463 3.1599993e-05 +438 463 8.0999998e-06 +441 463 9.9999943e-07 +442 463 1.43e-05 +443 463 0.00011299999 +444 463 8.5499996e-05 +445 463 0.0014842998 +446 463 0.0001354 +447 463 0.00031049992 +448 463 0.0001008 +449 463 0.00011299999 +450 463 0.0030061998 +452 463 0.0062219985 +453 463 0.0014648999 +454 463 0.0016166 +455 463 0.0029531999 +456 463 0.0018863999 +457 463 0.0058534965 +458 463 0.00089889998 +459 463 0.00079199998 +460 463 0.0083455965 +461 463 0.00041639991 +463 463 0.10133928 +464 463 0.0001089 +465 463 0.0019646999 +467 463 0.0052253976 +468 463 0.0086590983 +469 463 0.0039314963 +470 463 0.0032127998 +471 463 0.0034194998 +473 463 6.7199988e-05 +474 463 6.0999992e-06 +476 463 1.7299986e-05 +477 463 2.9499992e-05 +478 463 0.00033189985 +483 463 0.00049069989 +486 463 0.00063319993 +489 463 0.00060369982 +490 463 0.00025039981 +9 464 2.3999994e-05 +11 464 0.00065869978 +16 464 0.0012573998 +18 464 0.0020597999 +22 464 0.00052689994 +60 464 0.023771297 +64 464 1.2e-05 +75 464 0.00098199979 +79 464 2.3999994e-05 +82 464 0.0011376999 +83 464 2.3999994e-05 +84 464 2.3999994e-05 +85 464 0.0010298998 +90 464 0.0010658 +93 464 0.00039519998 +94 464 0.00038319989 +105 464 0.00043109991 +106 464 7.1899995e-05 +107 464 0.00020359999 +108 464 2.3999994e-05 +113 464 4.7899986e-05 +114 464 9.5799987e-05 +126 464 4.7899986e-05 +127 464 2.3999994e-05 +130 464 0.00082629989 +142 464 0.00033529988 +150 464 0.0031015999 +151 464 0.0021197 +152 464 0.0037362999 +171 464 0.0010897999 +187 464 0.00064669992 +189 464 0.00034729997 +190 464 0.0034967999 +192 464 0.00010779999 +194 464 0.00022749999 +196 464 0.00035929983 +197 464 5.989999e-05 +198 464 0.00041909982 +200 464 0.0003711998 +201 464 7.1899995e-05 +203 464 0.0012693999 +204 464 0.0041314997 +206 464 0.00049099978 +207 464 0.0001677 +209 464 0.0002156 +215 464 0.00056279986 +217 464 0.00010779999 +219 464 1.2e-05 +223 464 0.00014369999 +229 464 0.0033292 +230 464 0.0036165998 +234 464 0.010753997 +237 464 0.00034729997 +240 464 1.2e-05 +241 464 0.0058918968 +248 464 3.5899997e-05 +250 464 2.3999994e-05 +252 464 0.0017603999 +263 464 0.00046699983 +279 464 1.2e-05 +315 464 0.0005987999 +322 464 0.00035929983 +356 464 5.989999e-05 +363 464 1.2e-05 +384 464 0.00063469983 +387 464 4.7899986e-05 +394 464 2.3999994e-05 +397 464 3.5899997e-05 +402 464 4.7899986e-05 +412 464 0.0002156 +419 464 2.3999994e-05 +422 464 0.00022749999 +423 464 2.3999994e-05 +425 464 2.3999994e-05 +428 464 0.00043109991 +430 464 2.3999994e-05 +431 464 4.7899986e-05 +432 464 3.5899997e-05 +433 464 0.0001198 +434 464 0.00015569999 +435 464 0.0010058999 +438 464 8.3799998e-05 +441 464 0.0004431 +442 464 0.00094609987 +443 464 0.00075449981 +444 464 0.0001317 +445 464 0.0029099998 +446 464 0.00051489985 +447 464 0.00041909982 +448 464 0.00023949999 +449 464 0.0014250998 +450 464 0.0034967999 +452 464 0.034968399 +453 464 0.0075804964 +454 464 0.0075205974 +455 464 0.0090055987 +456 464 0.0036165998 +457 464 0.0091971979 +458 464 0.0070774965 +459 464 0.00067059998 +460 464 0.013388596 +463 464 0.12847286 +464 464 0.0001677 +465 464 0.025807098 +467 464 0.043039899 +468 464 0.014238797 +469 464 0.0053050965 +470 464 0.0046344995 +471 464 0.0071612969 +473 464 9.5799987e-05 +477 464 0.0001198 +478 464 0.0016645999 +483 464 0.0038800999 +489 464 0.0017962998 +490 464 0.0003711998 +9 465 2.2699998e-05 +16 465 1.13e-05 +18 465 9.6399992e-05 +22 465 0.0001872 +60 465 0.0067609996 +79 465 5.6999997e-06 +82 465 3.9699997e-05 +83 465 2.8399998e-05 +84 465 2.2699998e-05 +104 465 0.00016449999 +108 465 5.0999995e-05 +113 465 6.2399995e-05 +114 465 0.00015879999 +117 465 6.2399995e-05 +126 465 7.3699994e-05 +127 465 1.13e-05 +130 465 0.0043843985 +133 465 5.6999997e-06 +137 465 0.00027229986 +139 465 0.00042539998 +149 465 3.9699997e-05 +150 465 0.022103697 +152 465 0.0065284967 +153 465 0.00068059983 +156 465 0.0001928 +158 465 0.0013612998 +160 465 0.00076569989 +161 465 0.0002099 +169 465 0.0002948998 +187 465 0.0006295999 +189 465 8.5099993e-05 +190 465 0.00014179999 +192 465 7.3699994e-05 +193 465 0.0051047988 +194 465 0.00015309999 +196 465 2.8399998e-05 +197 465 0.00093019987 +198 465 0.0039022998 +200 465 0.00036299997 +201 465 4.5399996e-05 +203 465 0.00036299997 +204 465 0.00085649989 +206 465 0.00034599984 +207 465 0.00011339999 +209 465 3.3999997e-05 +214 465 0.0059215985 +215 465 5.6999997e-06 +219 465 2.2699998e-05 +223 465 0.00060119992 +229 465 0.0049516 +230 465 0.0013498999 +231 465 0.00013609999 +233 465 0.0006465998 +234 465 0.0118942 +237 465 0.0026715 +240 465 0.0050990991 +241 465 0.0052181967 +242 465 0.00017019999 +244 465 0.0072147995 +248 465 2.8399998e-05 +250 465 1.6999998e-05 +251 465 5.6999997e-06 +252 465 6.2399995e-05 +263 465 5.6999997e-06 +265 465 0.0041575991 +271 465 5.6999997e-06 +272 465 3.3999997e-05 +279 465 0.0002948998 +284 465 2.2699998e-05 +285 465 2.8399998e-05 +295 465 0.000397 +312 465 0.0016675999 +315 465 0.0010209999 +316 465 0.00089619984 +317 465 0.0018887999 +319 465 0.00030629989 +322 465 0.0057173967 +323 465 5.6999997e-06 +326 465 0.00014179999 +328 465 0.0026431 +340 465 9.6399992e-05 +351 465 0.00036299997 +356 465 0.00010779999 +358 465 0.0025354 +360 465 0.0027111999 +363 465 0.0029210998 +364 465 0.00037439982 +365 465 0.00074299984 +366 465 0.0023708998 +368 465 0.0010152999 +372 465 0.0016845998 +376 465 0.00095859985 +377 465 0.00075999997 +379 465 0.0049686991 +380 465 0.001038 +381 465 0.0019340999 +382 465 3.3999997e-05 +383 465 5.6699995e-05 +384 465 0.00014179999 +387 465 9.0799993e-05 +391 465 0.0090070963 +392 465 0.0091148987 +393 465 0.00031199981 +394 465 0.0002212 +397 465 0.00013609999 +402 465 0.0007487 +403 465 5.6999997e-06 +404 465 1.13e-05 +405 465 1.13e-05 +409 465 0.0016107999 +412 465 0.00031199981 +419 465 0.004089497 +422 465 0.013164699 +423 465 2.2699998e-05 +424 465 0.0029040999 +425 465 1.6999998e-05 +430 465 4.5399996e-05 +431 465 2.2699998e-05 +432 465 2.8399998e-05 +433 465 7.9399993e-05 +434 465 0.00010779999 +437 465 0.00089049991 +440 465 0.019591 +442 465 0.0033634999 +443 465 0.0016107999 +444 465 0.00060119992 +445 465 0.005836498 +446 465 0.00060689985 +447 465 0.0013839998 +448 465 0.0002269 +449 465 3.3999997e-05 +450 465 0.021598898 +452 465 0.0067893974 +453 465 0.0018717998 +454 465 0.0011741 +455 465 0.030180696 +456 465 0.0026657998 +457 465 0.0057910979 +458 465 0.00034599984 +459 465 0.0012080998 +460 465 0.0047190972 +463 465 0.039312597 +464 465 0.0010265999 +465 465 0.037849199 +467 465 0.036969997 +468 465 0.0083944984 +469 465 0.0122572 +470 465 0.0078443997 +471 465 0.017815698 +473 465 0.00016449999 +477 465 5.6699995e-05 +478 465 0.0020589 +483 465 0.0019738998 +489 465 0.0010435998 +490 465 0.0006295999 +491 465 1.13e-05 +9 466 2.3199987e-05 +60 466 0.0092115998 +82 466 2.3199987e-05 +108 466 2.3199987e-05 +114 466 4.639999e-05 +126 466 2.3199987e-05 +149 466 0.0016705999 +150 466 0.00051049981 +187 466 2.3199987e-05 +189 466 9.2799994e-05 +190 466 0.0004176998 +192 466 2.3199987e-05 +194 466 4.639999e-05 +200 466 4.639999e-05 +203 466 2.3199987e-05 +204 466 2.3199987e-05 +206 466 6.9599992e-05 +207 466 2.3199987e-05 +223 466 6.9599992e-05 +230 466 0.00039439998 +232 466 0.043366298 +234 466 0.0054990984 +237 466 2.3199987e-05 +240 466 0.00018559999 +241 466 0.0043156967 +242 466 0.00034799986 +316 466 0.0017865999 +356 466 9.2799994e-05 +380 466 0.0014385998 +384 466 0.0001624 +387 466 2.3199987e-05 +394 466 0.000116 +397 466 0.000116 +402 466 2.3199987e-05 +422 466 2.3199987e-05 +430 466 2.3199987e-05 +433 466 2.3199987e-05 +434 466 2.3199987e-05 +435 466 0.00023199999 +438 466 0.00027839979 +442 466 0.0090722963 +443 466 0.0001624 +444 466 6.9599992e-05 +445 466 0.0021811 +446 466 0.0001624 +447 466 0.0001392 +448 466 0.000116 +450 466 0.0073785 +452 466 0.0069608986 +453 466 0.00092809997 +454 466 0.0018097998 +455 466 0.013666499 +456 466 0.0009976998 +457 466 0.0061255991 +458 466 4.639999e-05 +459 466 0.0024595 +460 466 2.3199987e-05 +463 466 0.078518689 +464 466 9.2799994e-05 +465 466 0.016218897 +467 466 0.0080513991 +468 466 0.0071000978 +469 466 0.0052206963 +470 466 0.0018097998 +471 466 0.008561898 +473 466 4.639999e-05 +478 466 0.0022042999 +483 466 0.0016241998 +489 466 0.00076569989 +490 466 0.0001624 +6 467 3.2199998e-05 +9 467 2.9499992e-05 +16 467 1.3399999e-05 +17 467 2.6999996e-06 +18 467 7.509999e-05 +60 467 0.0067344978 +75 467 0.0014568998 +79 467 0.00054199994 +82 467 4.0199986e-05 +83 467 2.9499992e-05 +84 467 2.9499992e-05 +102 467 4.5599998e-05 +108 467 5.3699987e-05 +113 467 6.7099987e-05 +114 467 0.0001717 +126 467 8.3199993e-05 +127 467 1.3399999e-05 +141 467 0.0002307 +149 467 0.0001851 +150 467 0.00056879991 +152 467 0.00014219999 +153 467 1.6099992e-05 +160 467 0.00041319989 +171 467 0.0002442 +187 467 0.00028709997 +189 467 0.0010356999 +190 467 0.00026559993 +192 467 0.0017976998 +194 467 0.0002388 +196 467 4.0199986e-05 +197 467 6.7099987e-05 +198 467 0.0010248998 +200 467 0.00036489987 +201 467 0.00043999986 +202 467 0.00051779998 +203 467 0.00045609986 +204 467 0.0014972 +206 467 0.0036489998 +207 467 0.00045609986 +209 467 6.7099987e-05 +210 467 0.00045879977 +214 467 0.0027071999 +217 467 0.0014836998 +218 467 8.3199993e-05 +219 467 1.07e-05 +223 467 0.0010195998 +228 467 0.00016899999 +229 467 0.0011670999 +230 467 0.0018485999 +231 467 0.00020929999 +233 467 0.00040779985 +234 467 0.0080975965 +237 467 0.0013442 +238 467 1.3399999e-05 +240 467 0.00022809999 +241 467 0.0051058978 +242 467 0.00054469984 +247 467 2.9499992e-05 +248 467 3.4899989e-05 +250 467 1.6099992e-05 +251 467 0.0001181 +252 467 0.00082099997 +263 467 0.00017439999 +270 467 0.00034609996 +271 467 8.0499987e-05 +272 467 0.00024679978 +279 467 0.00041319989 +284 467 3.7599995e-05 +301 467 0.00023339999 +312 467 0.00099009997 +314 467 0.00026559993 +315 467 0.0019506 +316 467 0.00016899999 +317 467 0.00061979983 +319 467 0.00017439999 +322 467 0.0012985999 +323 467 5.3999993e-06 +324 467 5.3999993e-06 +326 467 0.0026535999 +328 467 0.0022779 +329 467 0.0024952998 +330 467 0.0019612999 +340 467 0.00018239999 +341 467 0.00024149999 +348 467 0.00025489996 +351 467 0.0010731998 +352 467 6.4399996e-05 +356 467 0.00028439984 +358 467 0.0032358 +359 467 0.0016527998 +361 467 0.00080759986 +362 467 9.3899987e-05 +363 467 0.00039439998 +368 467 0.00066809985 +370 467 0.00040509994 +372 467 0.0020472 +373 467 0.00050979992 +374 467 0.0011053998 +375 467 0.0004453999 +376 467 0.0006438999 +380 467 8e-06 +382 467 0.00032729981 +384 467 4.2899992e-05 +387 467 6.9799993e-05 +392 467 0.0044350997 +393 467 0.00059829978 +394 467 0.00011539999 +395 467 8.3199993e-05 +397 467 6.169999e-05 +402 467 0.00037289993 +404 467 2.6999996e-06 +405 467 2.6999996e-06 +406 467 5.3999993e-06 +409 467 0.0018781999 +412 467 0.0003515 +413 467 5.6299992e-05 +414 467 5.8999998e-05 +419 467 1.6099992e-05 +422 467 0.010463998 +423 467 2.1499989e-05 +425 467 1.6099992e-05 +427 467 0.00051779998 +430 467 4.8299989e-05 +431 467 4.2899992e-05 +432 467 0.00031929999 +433 467 0.00012339999 +434 467 0.00039979978 +435 467 0.00028169993 +437 467 8.0499987e-05 +438 467 0.00032729981 +441 467 0.0001985 +442 467 0.0012583998 +443 467 0.0022296 +444 467 0.0023261998 +445 467 0.007056497 +446 467 0.00055539981 +447 467 0.0083711967 +448 467 0.00019319999 +449 467 1.3399999e-05 +450 467 0.021086399 +452 467 0.0052400976 +453 467 0.0010409998 +454 467 0.0024630998 +455 467 0.014257897 +456 467 0.0014032999 +457 467 0.0054868981 +458 467 0.0010007999 +459 467 0.0021088999 +460 467 0.0035416998 +463 467 0.046736699 +464 467 0.0049797967 +465 467 0.0034961 +467 467 0.045102697 +468 467 0.018735997 +469 467 0.015781898 +470 467 0.0093585998 +471 467 0.013571098 +473 467 0.00016899999 +477 467 0.0001449 +478 467 0.0022242998 +483 467 0.011212599 +486 467 7.7799996e-05 +489 467 0.00046689995 +490 467 0.00061439979 +491 467 5.3999993e-06 +9 468 4.6699992e-05 +16 468 2.1199987e-05 +18 468 0.00025459984 +22 468 8.4999992e-06 +60 468 0.003756 +63 468 0.0011415998 +75 468 8.9099995e-05 +79 468 5.5199998e-05 +82 468 6.369999e-05 +83 468 4.6699992e-05 +84 468 4.2399988e-05 +102 468 4.1999992e-06 +108 468 8.4899992e-05 +113 468 0.0001103 +114 468 0.00026309979 +126 468 0.0001316 +127 468 2.549999e-05 +139 468 4.1999992e-06 +141 468 8.0599988e-05 +149 468 1.2699999e-05 +150 468 0.00028429995 +151 468 6.7899993e-05 +152 468 8.4999992e-06 +160 468 0.00028429995 +165 468 0.00032249978 +170 468 0.00010609999 +171 468 0.00025459984 +172 468 8.4999992e-06 +187 468 0.080585241 +188 468 0.0010270998 +189 468 0.00055169989 +190 468 0.00015699999 +192 468 0.0026651998 +194 468 0.0008403 +196 468 5.5199998e-05 +197 468 0.00024189999 +198 468 0.0011119 +199 468 8.4999992e-06 +200 468 0.0010397998 +201 468 0.00012729999 +202 468 0.0048805997 +203 468 0.00060259993 +204 468 0.022247098 +205 468 0.0027798 +206 468 0.0010992 +207 468 0.00024619978 +209 468 0.0010354999 +210 468 0.0023979 +211 468 0.0043458976 +212 468 0.0026015998 +213 468 0.00050499989 +214 468 0.0020498999 +217 468 8.9099995e-05 +218 468 8.4999992e-06 +219 468 0.00012729999 +221 468 0.0057972968 +223 468 9.7599986e-05 +224 468 0.0011797999 +228 468 8.4999992e-06 +229 468 7.2099996e-05 +230 468 0.0001103 +231 468 1.2699999e-05 +233 468 0.0005092998 +234 468 0.0024487998 +237 468 0.00047109998 +240 468 0.00039039995 +241 468 0.0032382 +242 468 3.3999997e-05 +248 468 4.6699992e-05 +250 468 2.549999e-05 +251 468 2.549999e-05 +252 468 0.0001103 +263 468 2.549999e-05 +270 468 7.2099996e-05 +271 468 4.1999992e-06 +272 468 0.00044989982 +277 468 0.0011713 +279 468 7.2099996e-05 +284 468 8.4999992e-06 +287 468 0.00016549999 +292 468 0.0001528 +293 468 0.00095909997 +294 468 0.0002249 +295 468 0.00045409985 +301 468 1.2699999e-05 +312 468 0.00010189999 +314 468 1.6999998e-05 +315 468 0.00011879999 +316 468 8.4999992e-06 +317 468 0.00012309999 +319 468 0.000208 +320 468 9.3399998e-05 +321 468 0.0001146 +322 468 8.0599988e-05 +325 468 0.0004584 +326 468 0.00024619978 +328 468 0.00013579999 +329 468 0.0001485 +330 468 0.00011879999 +334 468 0.00010609999 +340 468 0.0001316 +341 468 1.2699999e-05 +348 468 0.0017315999 +351 468 6.369999e-05 +352 468 4.1999992e-06 +356 468 7.64e-05 +358 468 0.00043709995 +359 468 0.00010609999 +361 468 5.0899995e-05 +362 468 4.1999992e-06 +363 468 4.6699992e-05 +368 468 3.82e-05 +370 468 0.00052629993 +371 468 0.0001103 +372 468 0.00012309999 +373 468 9.7599986e-05 +374 468 6.7899993e-05 +375 468 2.549999e-05 +376 468 0.00010609999 +380 468 1.6999998e-05 +382 468 2.1199987e-05 +384 468 0.0001867 +385 468 4.1999992e-06 +386 468 0.00016549999 +387 468 0.0001103 +388 468 0.0003564998 +389 468 0.00071299984 +390 468 8.9099995e-05 +391 468 0.0015320999 +392 468 0.00031829998 +393 468 4.2399988e-05 +394 468 3.3999997e-05 +395 468 8.4999992e-06 +397 468 2.9699993e-05 +401 468 4.1999992e-06 +402 468 0.0001316 +404 468 4.1999992e-06 +409 468 0.0001146 +412 468 0.00021639999 +413 468 4.1999992e-06 +414 468 4.1999992e-06 +417 468 1.6999998e-05 +419 468 2.549999e-05 +421 468 4.1999992e-06 +422 468 0.0059840977 +423 468 3.82e-05 +425 468 2.549999e-05 +427 468 2.9699993e-05 +430 468 7.2099996e-05 +431 468 0.00011879999 +432 468 0.00014429999 +433 468 0.0001485 +434 468 0.00037349993 +435 468 1.6999998e-05 +437 468 4.1999992e-06 +438 468 2.1199987e-05 +441 468 0.00043289992 +442 468 0.0024614998 +443 468 0.0031235998 +444 468 0.0051309988 +445 468 0.0057251975 +446 468 0.000208 +447 468 0.0114928 +448 468 4.6699992e-05 +449 468 2.549999e-05 +450 468 0.016933598 +451 468 0.00017399999 +452 468 0.0053431988 +453 468 0.0010439998 +454 468 0.00089549995 +455 468 0.017527796 +456 468 0.0012010999 +457 468 0.0064466968 +458 468 0.00062389998 +459 468 0.0018078999 +460 468 0.0033951998 +463 468 0.043382298 +464 468 0.0079320967 +465 468 0.0021346998 +467 468 0.030531399 +468 468 0.016916599 +469 468 0.0119766 +470 468 0.012464698 +471 468 0.0049017966 +472 468 0.031647597 +473 468 0.021988198 +477 468 0.0001316 +478 468 0.0036032 +483 468 0.010113496 +489 468 0.00038619991 +490 468 0.0018036999 +491 468 0.00010609999 +9 469 3.6599988e-05 +16 469 1.4599999e-05 +17 469 3.7e-06 +18 469 1.4599999e-05 +60 469 0.00046439981 +79 469 7.2999992e-06 +82 469 6.2199993e-05 +83 469 4.7499998e-05 +84 469 4.39e-05 +108 469 7.3099989e-05 +113 469 0.00010599999 +114 469 0.00025959988 +126 469 0.00012069999 +127 469 2.1899992e-05 +150 469 9.1399997e-05 +171 469 3.7e-06 +187 469 3.7e-06 +189 469 0.00033279997 +190 469 0.00011339999 +192 469 9.5099997e-05 +194 469 0.0002121 +196 469 3.2899989e-05 +197 469 0.00068379985 +200 469 0.00054849987 +201 469 0.0051302984 +203 469 0.00020109999 +204 469 0.0026437999 +206 469 0.0011298999 +207 469 0.00015359999 +209 469 4.7499998e-05 +210 469 0.00054849987 +214 469 3.7e-06 +219 469 1.0999999e-05 +223 469 2.5599991e-05 +230 469 8.4099986e-05 +233 469 0.00010239999 +234 469 0.0026217999 +237 469 0.00033639977 +240 469 1.8299994e-05 +241 469 0.00074229995 +242 469 0.00018649999 +248 469 5.4899996e-05 +250 469 2.1899992e-05 +251 469 1.0999999e-05 +252 469 0.00036569987 +263 469 7.6799988e-05 +279 469 7.2999992e-06 +322 469 3.7e-06 +326 469 3.7e-06 +356 469 3.6599988e-05 +359 469 0.00011339999 +363 469 1.0999999e-05 +380 469 1.0999999e-05 +384 469 1.0999999e-05 +387 469 0.00010599999 +393 469 8.7799999e-05 +394 469 2.5599991e-05 +397 469 2.5599991e-05 +402 469 1.0999999e-05 +412 469 8.4099986e-05 +419 469 1.4599999e-05 +422 469 0.00086299982 +423 469 2.929999e-05 +425 469 1.4599999e-05 +430 469 6.5799992e-05 +431 469 3.2899989e-05 +432 469 9.8699995e-05 +433 469 0.00011339999 +434 469 0.00019009999 +438 469 0.00010239999 +441 469 0.00037659984 +442 469 0.0011884 +443 469 0.00018649999 +444 469 0.0073352978 +445 469 0.0026071998 +446 469 0.0001755 +447 469 0.011339299 +448 469 7.3099989e-05 +449 469 2.1899992e-05 +450 469 0.018243097 +452 469 0.00046809996 +453 469 0.000128 +454 469 0.00086299982 +455 469 0.0035762 +456 469 0.0011847999 +457 469 0.0082237981 +458 469 0.00072399992 +459 469 0.00047539989 +460 469 0.0022012999 +463 469 0.043547299 +464 469 0.014926497 +465 469 0.0007642 +467 469 0.029885899 +468 469 0.0067428984 +469 469 0.040234298 +470 469 0.015537199 +471 469 0.011763498 +473 469 0.00027429988 +477 469 0.0001755 +478 469 0.0022817999 +483 469 0.0051448978 +489 469 0.00010239999 +490 469 0.0011664999 +491 469 3.7e-06 +1 470 0.0051065981 +9 470 0.0013710998 +11 470 0.010274697 +16 470 2.8699986e-05 +17 470 0.0064303987 +59 470 4.0999994e-06 +60 470 0.0034871998 +64 470 4.0999994e-06 +75 470 0.00015189999 +82 470 0.07518667 +83 470 0.018761799 +84 470 0.010701697 +85 470 0.0014962999 +86 470 0.0035919 +87 470 0.0061553977 +88 470 0.0024013999 +89 470 0.0083884969 +90 470 0.013706498 +91 470 0.001956 +92 470 0.0013771998 +93 470 0.0096179992 +94 470 0.0010817 +95 470 0.0050757974 +96 470 0.0096774995 +97 470 0.0070563965 +98 470 0.0013730999 +99 470 0.00027299998 +100 470 0.0008578999 +103 470 0.00056649977 +104 470 3.0799987e-05 +105 470 0.022238698 +106 470 0.0015947998 +107 470 0.0016747999 +108 470 0.0032676 +109 470 0.00049879984 +111 470 0.029477797 +113 470 0.0066725984 +114 470 0.0311937 +115 470 0.0072760992 +116 470 0.008080598 +121 470 0.0089980997 +122 470 0.0052625984 +123 470 0.00073679979 +124 470 0.00051309983 +125 470 0.0093326978 +152 470 0.00051309983 +187 470 4.0999994e-06 +189 470 0.00010059999 +190 470 0.0012601998 +192 470 2.8699986e-05 +193 470 0.0014634 +194 470 2.0999996e-06 +195 470 0.00025659986 +197 470 0.00038789981 +198 470 0.0062764995 +203 470 2.0999996e-06 +204 470 0.00091129984 +206 470 7.9999998e-05 +214 470 4.0999992e-05 +218 470 0.00015189999 +223 470 0.00017449999 +229 470 0.0021571999 +230 470 0.00039819977 +234 470 0.00023189999 +237 470 3.689999e-05 +240 470 2.0999996e-06 +241 470 0.0031361999 +252 470 0.0010713998 +260 470 0.00079839979 +261 470 1.8499995e-05 +263 470 2.0999996e-06 +296 470 0.0002422 +315 470 0.0010386 +316 470 7.9999998e-05 +317 470 1.44e-05 +322 470 2.0999996e-06 +344 470 0.0003386999 +351 470 2.0999996e-06 +358 470 8.6199987e-05 +368 470 2.0999996e-06 +377 470 2.0999996e-06 +380 470 4.0999994e-06 +384 470 9.8499993e-05 +406 470 2.0999996e-06 +408 470 2.0999996e-06 +412 470 4.0999994e-06 +422 470 8.1999997e-06 +425 470 0.00046799984 +434 470 2.0999996e-06 +435 470 0.0002462999 +442 470 0.00042689987 +443 470 0.0035281999 +445 470 0.011432298 +446 470 0.00046799984 +447 470 0.00017859999 +448 470 6.1999999e-06 +450 470 0.0030828 +452 470 0.011588298 +453 470 0.0011041998 +454 470 0.0032428999 +455 470 0.061297499 +456 470 4.5199995e-05 +457 470 0.0045297965 +458 470 0.0029719998 +459 470 0.0002176 +460 470 0.0030294999 +463 470 0.041891199 +465 470 0.011153199 +467 470 0.011684798 +468 470 0.010305498 +469 470 0.0054287985 +470 470 2.8699986e-05 +471 470 0.00045149983 +472 470 3.8999991e-05 +473 470 0.0086244978 +477 470 0.00013959999 +478 470 0.0012848999 +479 470 0.0019888999 +483 470 0.0012786998 +486 470 1.6399994e-05 +489 470 0.00067939982 +490 470 0.00066909986 +9 471 1.2199999e-05 +16 471 8.0999998e-06 +18 471 4.0999994e-06 +22 471 4.0999994e-06 +60 471 0.0052297972 +66 471 1.2199999e-05 +68 471 0.0013929999 +69 471 0.00065579987 +73 471 0.00013029999 +75 471 0.00081869983 +79 471 4.0999994e-06 +82 471 1.6299993e-05 +83 471 1.2199999e-05 +84 471 1.2199999e-05 +108 471 1.6299993e-05 +113 471 2.4399997e-05 +114 471 5.6999997e-05 +126 471 2.4399997e-05 +127 471 4.0999994e-06 +150 471 0.0022034999 +187 471 4.0999994e-06 +189 471 1.6299993e-05 +190 471 5.6999997e-05 +192 471 0.0012341 +194 471 3.6699988e-05 +196 471 4.0999994e-06 +197 471 1.2199999e-05 +200 471 2.0399995e-05 +201 471 1.2199999e-05 +203 471 2.4399997e-05 +204 471 5.2999996e-05 +206 471 6.5199987e-05 +207 471 2.0399995e-05 +209 471 4.0999994e-06 +214 471 0.00021989999 +217 471 1.6299993e-05 +223 471 8.9599998e-05 +228 471 4.0999994e-06 +229 471 1.2199999e-05 +230 471 4.0999994e-06 +231 471 8.0999998e-06 +233 471 0.0042481981 +234 471 0.0074577965 +237 471 0.010687798 +240 471 0.0037757999 +241 471 4.0999994e-06 +242 471 0.0001222 +248 471 1.2199999e-05 +250 471 4.0999994e-06 +251 471 4.0999994e-06 +252 471 0.0048550963 +263 471 4.0999994e-06 +267 471 4.0999994e-06 +272 471 0.0069975965 +312 471 0.00024849991 +313 471 0.012805797 +317 471 0.0022320999 +319 471 0.0045007989 +323 471 0.0016496 +328 471 0.0018206998 +330 471 4.0999994e-06 +331 471 1.6299993e-05 +340 471 7.7399993e-05 +356 471 0.00035839994 +357 471 0.0062236972 +358 471 0.00023619999 +366 471 0.034645699 +376 471 0.00046429993 +380 471 4.0999994e-06 +384 471 9.7799988e-05 +385 471 0.0040567964 +387 471 0.0055678971 +394 471 0.0001222 +397 471 0.0024601 +402 471 0.23339194 +412 471 0.00044799992 +413 471 4.0999994e-06 +419 471 4.0999994e-06 +422 471 4.4799992e-05 +423 471 8.0999998e-06 +425 471 4.0999994e-06 +430 471 1.2199999e-05 +431 471 8.0999998e-06 +432 471 4.0999994e-06 +433 471 1.2199999e-05 +434 471 1.6299993e-05 +442 471 9.3699986e-05 +443 471 0.0064150989 +444 471 7.3299991e-05 +445 471 0.0042807981 +446 471 0.00025659986 +447 471 0.00086759985 +448 471 0.00013439999 +449 471 0.00027699978 +450 471 0.0062236972 +452 471 0.0041096993 +453 471 0.0013685999 +454 471 0.0010589999 +455 471 0.047207098 +456 471 0.012357697 +457 471 0.0018328999 +458 471 0.00048059993 +459 471 0.00031359983 +460 471 0.0090992972 +463 471 0.037012096 +464 471 9.7799988e-05 +465 471 0.0013440999 +467 471 0.011502396 +468 471 0.0053316988 +469 471 0.0058896989 +470 471 0.0028837 +471 471 0.0027655999 +473 471 5.6999997e-05 +477 471 1.2199999e-05 +478 471 0.00060279993 +483 471 0.00045619998 +489 471 0.00066389982 +490 471 0.00021989999 +491 471 0.0025374999 +9 472 6.9099988e-05 +16 472 2.2999986e-05 +18 472 0.00027639978 +60 472 0.012623798 +79 472 2.2999986e-05 +82 472 9.2099988e-05 +83 472 6.9099988e-05 +84 472 6.9099988e-05 +108 472 9.2099988e-05 +113 472 0.00013819999 +114 472 0.00029949984 +126 472 0.00013819999 +127 472 2.2999986e-05 +189 472 0.00011519999 +190 472 4.6099987e-05 +197 472 2.2999986e-05 +200 472 0.00029949984 +201 472 4.6099987e-05 +203 472 0.00071409997 +204 472 2.2999986e-05 +223 472 2.2999986e-05 +229 472 4.6099987e-05 +230 472 2.2999986e-05 +234 472 0.0014281999 +237 472 0.00032249978 +241 472 4.6099987e-05 +248 472 4.6099987e-05 +250 472 2.2999986e-05 +251 472 2.2999986e-05 +252 472 4.6099987e-05 +263 472 2.2999986e-05 +315 472 2.2999986e-05 +356 472 0.00016129999 +380 472 2.2999986e-05 +384 472 0.00016129999 +387 472 0.00013819999 +394 472 2.2999986e-05 +397 472 2.2999986e-05 +402 472 0.00013819999 +412 472 0.00069109979 +419 472 2.2999986e-05 +422 472 0.0218383 +423 472 4.6099987e-05 +425 472 2.2999986e-05 +430 472 6.9099988e-05 +431 472 2.2999986e-05 +443 472 6.9099988e-05 +444 472 0.00039159996 +445 472 0.0066343993 +446 472 9.2099988e-05 +447 472 0.00089839986 +448 472 2.2999986e-05 +449 472 2.2999986e-05 +450 472 0.0025801 +452 472 0.0088688992 +453 472 0.0024648998 +454 472 0.0016124998 +455 472 0.0057359971 +456 472 0.0013130999 +457 472 0.0077631995 +458 472 0.00025339983 +459 472 0.00082929991 +460 472 0.0027643 +463 472 0.060124397 +464 472 0.0005067999 +465 472 0.00059889979 +467 472 0.0063809976 +468 472 0.039506998 +469 472 0.0066113994 +470 472 0.015272997 +471 472 0.0048145987 +472 472 0.30955994 +473 472 0.00029949984 +477 472 4.6099987e-05 +478 472 0.0017046998 +483 472 0.0031559998 +486 472 2.2999986e-05 +489 472 0.0004606999 +490 472 0.044137299 +0 473 2.3899993e-05 +2 473 0.0013367999 +3 473 0.0051442981 +5 473 4.7699999e-05 +6 473 0.0423957 +9 473 7.1599992e-05 +14 473 1.19e-05 +16 473 7.1599992e-05 +17 473 1.19e-05 +18 473 0.0094053969 +60 473 0.0069226995 +62 473 2.3899993e-05 +75 473 0.0089517981 +79 473 2.3899993e-05 +82 473 0.00010739999 +83 473 8.3599996e-05 +84 473 8.3599996e-05 +101 473 0.0021125998 +102 473 0.00039389986 +105 473 0.000179 +108 473 0.0001313 +113 473 0.00021479999 +114 473 0.00048939977 +118 473 5.9699989e-05 +126 473 0.00021479999 +127 473 3.5799996e-05 +141 473 0.00096679991 +150 473 0.0003819 +154 473 0.0013249 +171 473 1.19e-05 +189 473 8.3599996e-05 +190 473 0.0002387 +192 473 8.3599996e-05 +194 473 0.0002268 +196 473 2.3899993e-05 +197 473 0.00035809982 +200 473 0.0002625999 +201 473 0.00011939999 +203 473 0.0016828999 +204 473 0.0030913998 +206 473 0.00041779992 +207 473 0.00010739999 +209 473 2.3899993e-05 +214 473 3.5799996e-05 +215 473 0.0016232999 +217 473 0.00054899999 +223 473 0.00039389986 +230 473 0.00040579983 +234 473 0.0026974999 +237 473 0.00062069995 +241 473 4.7699999e-05 +242 473 0.00033419998 +244 473 0.0002387 +245 473 0.0016590999 +248 473 8.3599996e-05 +250 473 4.7699999e-05 +251 473 0.0020528999 +252 473 7.1599992e-05 +263 473 1.19e-05 +283 473 1.19e-05 +322 473 0.00015519999 +326 473 1.19e-05 +329 473 2.3899993e-05 +356 473 0.00015519999 +364 473 0.00093099987 +380 473 3.5799996e-05 +384 473 0.0002625999 +387 473 0.00020289999 +388 473 1.19e-05 +391 473 5.9699989e-05 +394 473 4.7699999e-05 +397 473 4.7699999e-05 +402 473 5.9699989e-05 +406 473 5.9699989e-05 +412 473 0.00065649999 +419 473 2.3899993e-05 +422 473 0.00027449988 +423 473 4.7699999e-05 +425 473 3.5799996e-05 +430 473 0.0020291 +431 473 4.7699999e-05 +432 473 2.3899993e-05 +433 473 7.1599992e-05 +434 473 9.55e-05 +442 473 0.0014680999 +443 473 0.0010264998 +444 473 0.00066839997 +445 473 0.0024348998 +446 473 0.00081159989 +447 473 0.0016709999 +448 473 5.9699989e-05 +449 473 7.1599992e-05 +450 473 0.0087130964 +451 473 1.19e-05 +452 473 0.0070181973 +453 473 0.0019335998 +454 473 0.001862 +455 473 0.016483299 +456 473 0.0022677998 +457 473 0.0066004992 +458 473 8.3599996e-05 +459 473 0.00041779992 +460 473 0.010467596 +463 473 0.074001551 +464 473 0.00085939979 +465 473 0.0123774 +467 473 0.037716899 +468 473 0.016972598 +469 473 0.0066481978 +470 473 0.024468299 +471 473 0.0039745979 +472 473 0.0010861999 +473 473 0.069263041 +476 473 2.3899993e-05 +477 473 0.00015519999 +478 473 0.0033180998 +483 473 0.0013128999 +489 473 0.00047739991 +490 473 0.0021841999 +1 474 4.259999e-05 +9 474 3.4099998e-05 +11 474 1.2799999e-05 +16 474 8.4999992e-06 +17 474 4.2999991e-06 +18 474 4.6899993e-05 +60 474 0.00067789992 +79 474 8.4999992e-06 +82 474 0.00014069999 +83 474 6.8199995e-05 +84 474 5.9699989e-05 +86 474 4.2999991e-06 +87 474 8.4999992e-06 +88 474 4.2999991e-06 +89 474 8.4999992e-06 +90 474 7.6699987e-05 +91 474 1.7099999e-05 +92 474 1.2799999e-05 +93 474 8.0999991e-05 +94 474 4.2999991e-06 +95 474 4.2999991e-06 +96 474 4.2999991e-06 +97 474 3.8399987e-05 +98 474 4.2999991e-06 +99 474 8.4999992e-06 +100 474 4.2999991e-06 +101 474 2.1299988e-05 +105 474 2.5599991e-05 +106 474 4.2999991e-06 +107 474 4.2999991e-06 +108 474 4.6899993e-05 +113 474 8.0999991e-05 +114 474 0.0001791 +115 474 4.2999991e-06 +121 474 2.9799994e-05 +122 474 8.4999992e-06 +125 474 2.5599991e-05 +126 474 8.0999991e-05 +127 474 1.2799999e-05 +150 474 0.00017059999 +151 474 4.2999991e-06 +152 474 2.5599991e-05 +171 474 1.2799999e-05 +187 474 4.2999991e-06 +189 474 0.00090819993 +190 474 0.00069929985 +192 474 0.00014919999 +194 474 0.00030269986 +196 474 5.54e-05 +197 474 9.3799987e-05 +198 474 0.0007205999 +200 474 0.00089969998 +201 474 0.0024175998 +203 474 0.00030269986 +204 474 0.00040929997 +206 474 0.00072909985 +207 474 0.00023019999 +209 474 7.6699987e-05 +214 474 0.00057129981 +219 474 1.7099999e-05 +223 474 0.0001279 +228 474 0.019135799 +229 474 1.7099999e-05 +230 474 0.0001279 +234 474 0.0019655998 +237 474 0.00071629998 +240 474 0.00059689977 +241 474 0.00057129981 +242 474 0.00015779999 +248 474 3.8399987e-05 +250 474 2.1299988e-05 +251 474 8.4999992e-06 +252 474 6.3999993e-05 +253 474 1.2799999e-05 +263 474 1.2799999e-05 +279 474 8.4999992e-06 +315 474 1.2799999e-05 +322 474 8.4999992e-06 +326 474 4.2999991e-06 +356 474 3.8399987e-05 +359 474 4.2999991e-06 +363 474 2.1299988e-05 +380 474 1.2799999e-05 +384 474 2.5599991e-05 +387 474 7.6699987e-05 +393 474 4.2999991e-06 +394 474 3.4099998e-05 +397 474 4.259999e-05 +412 474 4.2999991e-06 +416 474 0.0023365 +417 474 0.0058924966 +418 474 0.0024089999 +419 474 8.4999992e-06 +422 474 0.0017907999 +423 474 1.7099999e-05 +424 474 2.1299988e-05 +425 474 1.2799999e-05 +430 474 4.259999e-05 +431 474 4.6899993e-05 +432 474 5.9699989e-05 +433 474 0.00017059999 +434 474 0.00020889999 +435 474 4.2999991e-06 +438 474 8.4999992e-06 +441 474 0.00011509999 +442 474 0.00011939999 +443 474 0.0002388 +444 474 0.00025579985 +445 474 0.00092519983 +446 474 9.3799987e-05 +447 474 0.00055859983 +448 474 3.8399987e-05 +449 474 1.7099999e-05 +450 474 0.0040505975 +452 474 0.0013857 +453 474 0.00030269986 +454 474 0.0018163999 +455 474 0.010433499 +456 474 0.0011170998 +457 474 0.0026733999 +458 474 0.00019189999 +459 474 1.7099999e-05 +460 474 0.015814297 +463 474 0.042249698 +464 474 0.00032399991 +465 474 0.012509897 +467 474 0.018717997 +468 474 5.54e-05 +469 474 0.0092821978 +470 474 0.0090988986 +471 474 0.003973797 +473 474 0.00018759999 +476 474 0.040394999 +477 474 0.00014919999 +478 474 0.0012663 +483 474 0.0065704994 +489 474 0.00015349999 +490 474 0.00069069979 +1 475 0.0018086999 +9 475 0.00035729981 +11 475 0.000795 +16 475 4.4999997e-06 +17 475 0.00017419999 +18 475 0.0008709 +22 475 0.00030369987 +60 475 0.025831498 +79 475 4.4999997e-06 +82 475 0.0079539977 +83 475 0.0019649998 +84 475 0.0015407999 +86 475 0.0005090998 +87 475 0.00035729981 +88 475 9.3799987e-05 +89 475 0.0013577 +90 475 0.0040684976 +91 475 0.0002233 +92 475 0.00045999978 +93 475 0.0024964998 +94 475 0.00026799995 +95 475 0.00027239998 +96 475 0.00095129991 +97 475 0.0010405998 +98 475 8.9299996e-05 +99 475 0.00024119999 +100 475 0.0001027 +103 475 3.1299991e-05 +104 475 4.4999997e-06 +105 475 0.001706 +106 475 0.0002233 +107 475 0.00025009993 +108 475 0.00020099999 +109 475 4.4699991e-05 +113 475 2.6799986e-05 +114 475 6.2499996e-05 +115 475 0.0005806 +116 475 0.0001965 +121 475 0.0021123998 +122 475 0.00033499999 +124 475 4.0199986e-05 +125 475 0.00093339989 +126 475 2.6799986e-05 +127 475 4.4999997e-06 +142 475 8.9299996e-05 +149 475 0.00037069991 +150 475 0.0078646988 +151 475 0.00053149997 +152 475 0.0072081983 +153 475 4.4999997e-06 +189 475 0.00020539999 +190 475 0.0015719999 +192 475 8.9299996e-05 +194 475 0.00020099999 +196 475 3.5699995e-05 +197 475 5.8099991e-05 +198 475 0.00075479993 +199 475 9.8299992e-05 +200 475 0.00065649999 +201 475 0.00010719999 +203 475 0.00018759999 +204 475 0.00093339989 +206 475 0.00077709998 +207 475 0.00014739999 +209 475 4.4699991e-05 +214 475 0.011634 +215 475 0.00013839999 +217 475 0.00013839999 +219 475 1.3399999e-05 +223 475 1.3399999e-05 +228 475 0.0246346 +229 475 0.0016389999 +230 475 0.0013978998 +233 475 0.00010719999 +234 475 0.0067972988 +237 475 5.8099991e-05 +240 475 0.0061585978 +241 475 0.0085345991 +248 475 1.7899991e-05 +250 475 4.4999997e-06 +251 475 4.4999997e-06 +252 475 0.0015274 +253 475 0.00044209999 +261 475 7.1499991e-05 +263 475 0.00026349979 +279 475 4.4999997e-06 +315 475 0.00043319981 +316 475 0.00024119999 +322 475 3.1299991e-05 +356 475 4.0199986e-05 +363 475 8.8999996e-06 +366 475 7.1499991e-05 +380 475 4.4999997e-06 +384 475 0.000795 +387 475 2.6799986e-05 +394 475 4.4999997e-06 +397 475 4.4999997e-06 +402 475 2.2299995e-05 +412 475 0.00060739997 +414 475 0.00012499999 +416 475 0.0019695 +417 475 0.0097269975 +418 475 6.6999986e-05 +419 475 4.4999997e-06 +420 475 8.9299996e-05 +422 475 0.010798797 +423 475 8.8999996e-06 +425 475 0.00035279989 +430 475 1.3399999e-05 +431 475 2.6799986e-05 +432 475 4.0199986e-05 +433 475 0.00010719999 +434 475 0.00013399999 +435 475 0.00012059999 +438 475 0.0001831 +442 475 0.0016836999 +443 475 0.0018846998 +444 475 0.0020721999 +445 475 0.0056717992 +446 475 0.00039299997 +447 475 0.0076904967 +448 475 3.5699995e-05 +449 475 4.4999997e-06 +450 475 0.008248698 +452 475 0.010289699 +453 475 0.0063506998 +454 475 0.0052564964 +455 475 0.020950098 +456 475 0.00026349979 +457 475 0.0065739974 +458 475 0.00058949995 +459 475 1.7899991e-05 +460 475 0.0047383979 +463 475 0.042681798 +464 475 0.0035861998 +465 475 0.0086684972 +467 475 0.0309227 +469 475 0.013197098 +470 475 0.011781398 +471 475 0.0024696998 +472 475 0.00033049984 +473 475 6.2499996e-05 +477 475 0.00021879999 +478 475 0.0015183999 +483 475 0.0046088994 +489 475 0.00025899988 +490 475 0.00033499999 +1 476 0.0024945999 +9 476 0.00036999979 +11 476 0.00081389979 +16 476 1.06e-05 +17 476 6.3399988e-05 +18 476 0.00012679999 +60 476 0.010115899 +79 476 1.06e-05 +82 476 0.0060144998 +83 476 0.0023995 +84 476 0.0017123998 +86 476 0.00034879986 +87 476 0.00060249981 +88 476 0.00035939994 +89 476 0.00060249981 +90 476 0.0044289976 +91 476 0.0011204998 +92 476 0.00086679985 +93 476 0.0048094988 +94 476 0.0003382999 +95 476 0.0002642998 +96 476 0.00038049999 +97 476 0.0023148998 +98 476 0.00020079999 +99 476 0.00046509993 +100 476 0.00020079999 +101 476 0.0012895998 +103 476 6.3399988e-05 +104 476 1.06e-05 +105 476 0.0015009998 +106 476 0.00028539984 +107 476 0.00032769982 +108 476 7.3999996e-05 +109 476 2.1099986e-05 +113 476 3.1699994e-05 +114 476 7.3999996e-05 +115 476 0.00036999979 +116 476 2.1099986e-05 +121 476 0.0016594999 +122 476 0.00059189997 +124 476 0.00012679999 +125 476 0.0014692999 +126 476 3.1699994e-05 +127 476 1.06e-05 +130 476 2.1099986e-05 +150 476 0.00057079992 +151 476 1.06e-05 +152 476 0.0014058999 +153 476 1.06e-05 +171 476 0.00048619998 +187 476 1.06e-05 +189 476 0.00034879986 +190 476 0.00022199999 +192 476 5.2899995e-05 +194 476 0.00012679999 +196 476 2.1099986e-05 +197 476 2.1099986e-05 +198 476 0.0017123998 +200 476 0.00099359988 +201 476 8.4599989e-05 +203 476 0.00010569999 +204 476 0.00083509996 +206 476 0.00048619998 +207 476 7.3999996e-05 +209 476 2.1099986e-05 +214 476 0.0043443963 +219 476 1.06e-05 +223 476 0.00060249981 +228 476 0.022768598 +229 476 0.00089849997 +230 476 0.0011415998 +233 476 3.1699994e-05 +234 476 0.0012895998 +237 476 0.00031709997 +240 476 0.0029491 +241 476 0.0075471997 +248 476 3.1699994e-05 +250 476 0.00017969999 +252 476 0.0016594999 +253 476 0.00041219988 +263 476 0.00052849995 +315 476 0.00073989993 +322 476 0.00012679999 +356 476 4.2299987e-05 +359 476 0.0001586 +363 476 1.06e-05 +384 476 0.00082449988 +387 476 3.1699994e-05 +393 476 0.00012679999 +394 476 3.1699994e-05 +397 476 2.1099986e-05 +402 476 4.2299987e-05 +412 476 0.00019029999 +416 476 0.00065539987 +417 476 0.0020083999 +418 476 0.010781799 +419 476 1.06e-05 +422 476 0.0062893964 +423 476 1.06e-05 +424 476 0.0013424 +425 476 1.06e-05 +430 476 2.1099986e-05 +431 476 3.1699994e-05 +432 476 2.1099986e-05 +433 476 6.3399988e-05 +434 476 0.0001374 +435 476 0.00028539984 +438 476 0.00041219988 +441 476 0.0002642998 +442 476 0.001131 +443 476 0.0011099 +444 476 0.00091959978 +445 476 0.0045663975 +446 476 0.0001586 +447 476 0.0013740999 +448 476 3.1699994e-05 +449 476 1.06e-05 +450 476 0.0097775981 +452 476 0.013826098 +453 476 0.0094710998 +454 476 0.0048517995 +455 476 0.016891498 +456 476 0.00046509993 +457 476 0.0056551993 +458 476 0.00012679999 +459 476 0.00012679999 +460 476 0.0042175986 +463 476 0.038169596 +464 476 0.0013846999 +465 476 0.014650498 +467 476 0.020760197 +468 476 0.0032767998 +469 476 0.015992999 +470 476 0.0069129989 +471 476 0.0032133998 +473 476 7.3999996e-05 +476 476 0.0059510991 +477 476 0.00025369995 +478 476 0.0015538 +483 476 0.0065535977 +489 476 0.00052849995 +490 476 0.00041219988 +3 477 0.00081139989 +9 477 2.4599998e-05 +16 477 8.1999997e-06 +18 477 0.0033439 +22 477 0.0011391998 +60 477 0.021226898 +79 477 8.1999997e-06 +82 477 3.2799988e-05 +83 477 2.4599998e-05 +84 477 2.4599998e-05 +101 477 0.00028679986 +105 477 0.00024589989 +108 477 3.2799988e-05 +113 477 4.9199996e-05 +114 477 0.00011469999 +126 477 4.9199996e-05 +127 477 8.1999997e-06 +150 477 9.8299992e-05 +187 477 0.0010326998 +189 477 0.00022949999 +190 477 0.00026229979 +192 477 0.0001065 +194 477 0.00025409996 +196 477 4.0999992e-05 +197 477 0.00076219998 +198 477 0.00062289997 +199 477 9.8299992e-05 +200 477 0.0011391998 +201 477 0.010260999 +202 477 0.0012293998 +203 477 0.00068019982 +204 477 0.0050321966 +206 477 0.0012620999 +207 477 0.00018849999 +209 477 5.7399986e-05 +210 477 0.0019506 +214 477 0.00086869998 +215 477 0.00027049985 +217 477 0.00030319998 +218 477 7.3799994e-05 +219 477 1.6399994e-05 +223 477 6.559999e-05 +228 477 0.0011145999 +229 477 0.00021309999 +230 477 0.00024589989 +234 477 0.010842897 +237 477 0.00031959987 +240 477 0.00072939997 +241 477 8.1999997e-06 +248 477 2.4599998e-05 +250 477 8.1999997e-06 +251 477 8.1999997e-06 +252 477 0.0019013998 +253 477 0.000336 +263 477 8.1999997e-06 +279 477 8.1999997e-06 +317 477 1.6399994e-05 +318 477 4.0999992e-05 +322 477 8.1999997e-06 +356 477 4.0999992e-05 +359 477 0.00059009995 +363 477 1.6399994e-05 +366 477 0.00013109999 +380 477 8.1999997e-06 +384 477 0.00091789989 +385 477 0.00036879978 +387 477 4.9199996e-05 +388 477 0.00024589989 +393 477 0.0018685998 +394 477 4.0999992e-05 +397 477 1.6399994e-05 +402 477 4.0999992e-05 +412 477 0.00018849999 +417 477 0.00023769999 +419 477 8.1999997e-06 +422 477 0.0010326998 +423 477 1.6399994e-05 +425 477 8.1999997e-06 +428 477 0.00030319998 +430 477 0.000336 +431 477 4.0999992e-05 +432 477 4.9199996e-05 +433 477 0.00013109999 +434 477 0.0004015998 +438 477 0.00050809979 +442 477 0.0017211 +443 477 0.00082779978 +444 477 0.0005655 +445 477 0.0052288994 +446 477 0.00037699984 +447 477 0.0045075975 +448 477 0.0001639 +449 477 8.1999997e-06 +450 477 0.010982297 +452 477 0.013957299 +453 477 0.0050812997 +454 477 0.0041305982 +455 477 0.0067368969 +456 477 0.0009506999 +457 477 0.0028766999 +458 477 0.00074579986 +459 477 0.0039584972 +460 477 0.0032782999 +463 477 0.10760146 +464 477 0.00018849999 +465 477 0.0043600984 +467 477 0.028389998 +468 477 0.010490499 +469 477 0.0046305992 +470 477 0.0067778975 +471 477 0.0063762963 +472 477 0.0029177 +473 477 0.0025406999 +477 477 0.00036879978 +478 477 0.0027947 +483 477 0.004056897 +489 477 0.00090969983 +490 477 0.00043439982 +9 478 0.00012089999 +16 478 4.6999994e-05 +18 478 0.00081929984 +60 478 0.028722197 +75 478 0.0010072999 +79 478 4.0299987e-05 +82 478 0.00020149999 +83 478 0.000141 +84 478 0.00013429999 +101 478 0.00050369999 +105 478 0.00017459999 +106 478 3.3599994e-05 +108 478 0.000235 +113 478 0.00030889991 +114 478 0.00075209979 +126 478 0.00034919987 +127 478 6.7199988e-05 +150 478 0.00096699991 +187 478 6.6999992e-06 +189 478 0.00049019977 +190 478 0.00030889991 +192 478 0.0001545 +194 478 0.00034249993 +196 478 6.0399994e-05 +197 478 0.00012089999 +200 478 0.0029481 +201 478 0.0039352998 +202 478 0.0047679991 +203 478 0.00032229978 +204 478 0.012074497 +206 478 0.00075889984 +207 478 0.00027529988 +209 478 8.0599988e-05 +214 478 6.6999992e-06 +215 478 0.00013429999 +217 478 5.3699987e-05 +219 478 2.0099993e-05 +223 478 2.0099993e-05 +229 478 0.00066479994 +230 478 0.0013094998 +234 478 0.0050634965 +237 478 0.00016119999 +240 478 2.0099993e-05 +241 478 5.3699987e-05 +248 478 0.00013429999 +250 478 7.3899995e-05 +251 478 4.0299987e-05 +252 478 0.0001276 +263 478 4.0299987e-05 +279 478 1.3399999e-05 +316 478 0.00026189978 +322 478 0.0001813 +356 478 4.0299987e-05 +363 478 2.0099993e-05 +366 478 0.00062449998 +380 478 5.3699987e-05 +384 478 0.00049019977 +387 478 0.00031559984 +394 478 1.3399999e-05 +397 478 1.3399999e-05 +402 478 5.3699987e-05 +412 478 0.00014769999 +419 478 6.7199988e-05 +422 478 0.00099389977 +423 478 0.00010739999 +425 478 7.3899995e-05 +428 478 2.6899987e-05 +430 478 0.0002082 +431 478 8.7299995e-05 +432 478 6.7199988e-05 +433 478 0.00018799999 +434 478 0.00022829999 +435 478 0.00082599977 +441 478 0.00026189978 +442 478 0.0029346999 +443 478 0.00032229978 +444 478 0.0010139998 +445 478 0.0033106999 +446 478 0.00024179999 +447 478 0.0022161 +448 478 0.00010739999 +449 478 6.7199988e-05 +450 478 0.016379099 +452 478 0.025747299 +453 478 0.0030622999 +454 478 0.0048149973 +455 478 0.0058088973 +456 478 0.0026055998 +457 478 0.0005371999 +459 478 0.00055069989 +460 478 0.0045732968 +463 478 0.073460996 +464 478 0.0012826999 +465 478 0.0021086999 +467 478 0.025156297 +468 478 0.012739297 +469 478 0.022228297 +470 478 0.037714299 +471 478 0.0013833998 +472 478 0.0019071999 +473 478 0.0027868999 +477 478 0.0096098967 +478 478 0.0049022995 +483 478 0.0188572 +489 478 0.0013497998 +490 478 0.0029010999 +60 479 0.0089971982 +114 479 0.00016359999 +130 479 0.014722697 +171 479 0.015213497 +190 479 0.00032719993 +192 479 0.0107967 +194 479 0.00049079978 +196 479 0.00016359999 +197 479 0.00016359999 +198 479 0.0042531975 +200 479 0.00065429998 +201 479 0.00016359999 +203 479 0.00049079978 +204 479 0.00049079978 +206 479 0.00065429998 +207 479 0.00032719993 +209 479 0.00016359999 +233 479 0.013086896 +234 479 0.00081789983 +237 479 0.00016359999 +241 479 0.016522199 +279 479 0.013577599 +312 479 0.014559098 +315 479 0.014886297 +316 479 0.015540697 +317 479 0.0068705976 +318 479 0.0081792995 +319 479 0.016849298 +322 479 0.015213497 +384 479 0.00016359999 +422 479 0.00049079978 +428 479 0.0075248964 +432 479 0.00016359999 +433 479 0.00032719993 +434 479 0.00032719993 +441 479 0.0063797981 +442 479 0.0053982995 +443 479 0.0014722999 +445 479 0.022247698 +447 479 0.00016359999 +452 479 0.056437097 +453 479 0.010960199 +454 479 0.0049075969 +455 479 0.020284597 +456 479 0.00016359999 +459 479 0.0055618994 +460 479 0.00016359999 +463 479 0.021756899 +464 479 0.00016359999 +465 479 0.0016358998 +467 479 0.014231998 +468 479 0.0070341974 +470 479 0.0022902 +471 479 0.0011451 +472 479 0.0089971982 +478 479 0.0026173999 +483 479 0.017667297 +489 479 0.0042531975 +490 479 0.00032719993 +1 480 0.0012118998 +9 480 0.00030299998 +11 480 0.0013633999 +60 480 0.0089379996 +82 480 0.011664897 +83 480 0.0039387979 +84 480 0.0024238999 +86 480 0.00060599996 +87 480 0.00090899994 +88 480 0.00045449985 +89 480 0.0022723998 +90 480 0.007271599 +91 480 0.00045449985 +92 480 0.00045449985 +93 480 0.0031812999 +94 480 0.00060599996 +95 480 0.00060599996 +96 480 0.0015148998 +97 480 0.0015148998 +98 480 0.00030299998 +99 480 0.00045449985 +100 480 0.00075749983 +104 480 0.0022723998 +105 480 0.0031812999 +106 480 0.00045449985 +107 480 0.00030299998 +108 480 0.0019693999 +114 480 0.00015149999 +116 480 0.0010603999 +122 480 0.00075749983 +149 480 0.00015149999 +190 480 0.00030299998 +192 480 0.00030299998 +194 480 0.00075749983 +196 480 0.00015149999 +197 480 0.00015149999 +200 480 0.00060599996 +201 480 0.00015149999 +203 480 0.00045449985 +204 480 0.00045449985 +206 480 0.00090899994 +207 480 0.00030299998 +209 480 0.00015149999 +234 480 0.00090899994 +237 480 0.00015149999 +356 480 0.00015149999 +384 480 0.00015149999 +422 480 0.00045449985 +428 480 0.00015149999 +432 480 0.00015149999 +433 480 0.00030299998 +434 480 0.00030299998 +438 480 0.0027268999 +442 480 0.0054536983 +443 480 0.00045449985 +445 480 0.0051506981 +450 480 0.0019693999 +452 480 0.0180276 +453 480 0.0034842999 +454 480 0.004999198 +455 480 0.0083320998 +456 480 0.00015149999 +457 480 0.00015149999 +460 480 0.00015149999 +463 480 0.10013628 +465 480 0.0016663999 +467 480 0.012119398 +470 480 0.0010603999 +471 480 0.0021209 +478 480 0.0027268999 +490 480 0.00015149999 +1 481 0.008002799 +9 481 0.0012178 +11 481 0.0050451979 +17 481 0.0013917999 +18 481 0.0029575999 +60 481 0.015483599 +82 481 0.041579697 +83 481 0.017919298 +84 481 0.0092205964 +86 481 0.0020876999 +87 481 0.0026095998 +88 481 0.0012178 +89 481 0.0036533999 +90 481 0.026965898 +91 481 0.00086989999 +92 481 0.0033054999 +93 481 0.012178097 +94 481 0.0012178 +95 481 0.0015657998 +96 481 0.0027835998 +97 481 0.0033054999 +98 481 0.0017396999 +99 481 0.0046972968 +100 481 0.00034789997 +103 481 0.00086989999 +104 481 0.00017399999 +105 481 0.024530299 +106 481 0.0052191988 +107 481 0.0022616999 +108 481 0.0005218999 +109 481 0.00017399999 +114 481 0.00017399999 +115 481 0.0015657998 +116 481 0.00034789997 +121 481 0.0043492988 +122 481 0.0020876999 +124 481 0.0005218999 +125 481 0.006610997 +152 481 0.016005598 +190 481 0.00017399999 +194 481 0.00034789997 +198 481 0.0064369999 +200 481 0.00017399999 +204 481 0.0026095998 +206 481 0.00034789997 +223 481 0.00017399999 +229 481 0.0038273998 +234 481 0.0109603 +241 481 0.017571297 +384 481 0.00034789997 +422 481 0.00034789997 +441 481 0.0041753985 +442 481 0.0064369999 +443 481 0.0020876999 +445 481 0.015831597 +446 481 0.00034789997 +448 481 0.00017399999 +450 481 0.013395999 +452 481 0.032011099 +453 481 0.006262999 +454 481 0.008872699 +455 481 0.030619297 +457 481 0.0046972968 +459 481 0.011134297 +463 481 0.19432849 +465 481 0.008872699 +467 481 0.0311413 +468 481 0.0048712976 +470 481 0.0012178 +471 481 0.00017399999 +478 481 0.00069589983 +483 481 0.008002799 +490 481 0.0012178 +60 482 0.011436399 +105 482 0.0099115968 +106 482 0.00091489987 +114 482 0.0001525 +190 482 0.00045749987 +192 482 0.00030499999 +194 482 0.00060989987 +196 482 0.0001525 +197 482 0.0001525 +200 482 0.00076239998 +201 482 0.00076239998 +202 482 0.0056419969 +203 482 0.00060989987 +204 482 0.029429697 +206 482 0.0013724 +207 482 0.00045749987 +209 482 0.0001525 +234 482 0.004879497 +237 482 0.00030499999 +384 482 0.0001525 +422 482 0.00045749987 +431 482 0.0001525 +432 482 0.0001525 +433 482 0.00030499999 +434 482 0.00030499999 +441 482 0.0051844977 +442 482 0.0041170977 +444 482 0.0073192976 +445 482 0.011131398 +446 482 0.0001525 +447 482 0.0050319992 +450 482 0.021957897 +452 482 0.014028698 +453 482 0.0027446998 +454 482 0.0094540976 +455 482 0.0050319992 +457 482 0.0057943985 +459 482 0.0096065998 +460 482 0.00030499999 +463 482 0.011283897 +464 482 0.0042695999 +465 482 0.0019822998 +467 482 0.037816398 +468 482 0.019365698 +469 482 0.012656298 +470 482 0.0021348 +471 482 0.0073192976 +472 482 0.0065568984 +478 482 0.0035071999 +483 482 0.020890497 +490 482 0.00030499999 +9 483 1.2199999e-05 +22 483 6.0999999e-05 +60 483 0.0036364999 +82 483 1.2199999e-05 +83 483 1.2199999e-05 +84 483 1.2199999e-05 +108 483 2.4399997e-05 +113 483 2.4399997e-05 +114 483 4.8799993e-05 +126 483 2.4399997e-05 +130 483 0.00029289979 +139 483 6.0999999e-05 +141 483 8.5399995e-05 +150 483 1.2199999e-05 +153 483 0.0016229998 +154 483 0.0010738999 +158 483 7.319999e-05 +187 483 0.00023189999 +189 483 0.00014639999 +190 483 0.0002197 +192 483 7.319999e-05 +194 483 4.8799993e-05 +196 483 1.2199999e-05 +197 483 3.6599988e-05 +198 483 0.00034169992 +200 483 8.5399995e-05 +201 483 2.4399997e-05 +202 483 0.00036609988 +203 483 6.0999999e-05 +204 483 0.0012690998 +206 483 4.8799993e-05 +207 483 3.6599988e-05 +209 483 0.0033801999 +223 483 0.0001586 +228 483 1.2199999e-05 +229 483 0.00035389978 +230 483 0.00036609988 +234 483 0.0045150965 +237 483 0.00075659994 +242 483 4.8799993e-05 +243 483 1.2199999e-05 +251 483 0.00029289979 +252 483 1.2199999e-05 +272 483 1.2199999e-05 +277 483 2.4399997e-05 +297 483 1.2199999e-05 +312 483 3.6599988e-05 +335 483 3.6599988e-05 +337 483 4.8799993e-05 +359 483 6.0999999e-05 +362 483 3.6599988e-05 +363 483 0.000183 +364 483 0.0001586 +384 483 7.319999e-05 +387 483 2.4399997e-05 +390 483 7.319999e-05 +394 483 4.8799993e-05 +397 483 0.000183 +402 483 0.0014155 +417 483 6.0999999e-05 +422 483 6.0999999e-05 +423 483 1.2199999e-05 +430 483 1.2199999e-05 +431 483 2.4399997e-05 +432 483 1.2199999e-05 +433 483 2.4399997e-05 +434 483 2.4399997e-05 +443 483 0.0120808 +444 483 0.00046369992 +445 483 0.028920799 +446 483 0.0022940999 +447 483 0.036754999 +448 483 8.5399995e-05 +450 483 0.0020988998 +452 483 0.005466897 +453 483 0.0011958999 +454 483 0.0011105 +455 483 0.0020134998 +456 483 4.8799993e-05 +457 483 4.8799993e-05 +460 483 0.00058569992 +463 483 0.024759598 +464 483 6.0999999e-05 +465 483 3.6599988e-05 +467 483 0.013581797 +468 483 0.0002441 +469 483 0.0024527998 +470 483 0.0016107999 +471 483 0.0074558966 +472 483 2.4399997e-05 +473 483 3.6599988e-05 +477 483 0.00032949983 +478 483 0.00013419999 +489 483 0.00054909987 +490 483 0.0020134998 +9 486 0.00014559999 +59 486 0.0012377 +64 486 0.0010920998 +75 486 0.00014559999 +82 486 7.2799987e-05 +83 486 7.2799987e-05 +84 486 7.2799987e-05 +108 486 0.00014559999 +113 486 7.2799987e-05 +114 486 0.00036399998 +126 486 0.00014559999 +141 486 0.00021839999 +152 486 0.00021839999 +187 486 0.0014560998 +189 486 0.00043679983 +190 486 0.00087369978 +192 486 0.00014559999 +193 486 7.2799987e-05 +194 486 0.00043679983 +195 486 0.00014559999 +196 486 7.2799987e-05 +197 486 0.00021839999 +198 486 0.00021839999 +200 486 7.2799987e-05 +201 486 7.2799987e-05 +202 486 7.2799987e-05 +203 486 0.00043679983 +204 486 0.0025481998 +206 486 0.00072809984 +207 486 0.00021839999 +209 486 7.2799987e-05 +214 486 0.0005824999 +219 486 7.2799987e-05 +220 486 0.00014559999 +223 486 7.2799987e-05 +229 486 0.0080814995 +230 486 0.0038587998 +233 486 0.00014559999 +234 486 0.0051692985 +237 486 0.00043679983 +240 486 0.00065529998 +241 486 0.0059700981 +252 486 0.00080089993 +260 486 7.2799987e-05 +261 486 7.2799987e-05 +275 486 0.00014559999 +282 486 7.2799987e-05 +283 486 0.00014559999 +295 486 0.00014559999 +296 486 0.00072809984 +307 486 7.2799987e-05 +308 486 7.2799987e-05 +315 486 0.0037858998 +316 486 0.00043679983 +319 486 0.00014559999 +322 486 0.00029119989 +328 486 7.2799987e-05 +331 486 0.00014559999 +340 486 7.2799987e-05 +350 486 7.2799987e-05 +351 486 0.00043679983 +368 486 0.00036399998 +370 486 0.00014559999 +377 486 0.00072809984 +380 486 0.00087369978 +384 486 0.00036399998 +387 486 0.00014559999 +389 486 7.2799987e-05 +390 486 7.2799987e-05 +393 486 0.00014559999 +402 486 0.00014559999 +406 486 0.00065529998 +408 486 0.0005824999 +412 486 0.00087369978 +422 486 0.0023297998 +423 486 7.2799987e-05 +425 486 0.00087369978 +430 486 7.2799987e-05 +431 486 0.00014559999 +432 486 7.2799987e-05 +433 486 0.00021839999 +434 486 0.00029119989 +438 486 0.00029119989 +443 486 0.00094649987 +444 486 0.00021839999 +445 486 0.0040043965 +446 486 0.00029119989 +447 486 0.0005824999 +448 486 7.2799987e-05 +450 486 0.0048779994 +452 486 0.0144885 +453 486 0.010411397 +454 486 0.0034947 +455 486 0.0061885975 +456 486 0.00014559999 +457 486 0.039242797 +458 486 0.010192897 +459 486 0.0015288999 +460 486 0.0018201999 +463 486 0.018929698 +464 486 0.00029119989 +465 486 0.019075397 +467 486 0.067054987 +469 486 0.0014560998 +470 486 0.0082999989 +471 486 0.00050959992 +472 486 0.0033490998 +473 486 0.00021839999 +477 486 7.2799987e-05 +483 486 0.0046595968 +486 486 0.004441198 +489 486 0.00065529998 +490 486 0.13673097 +7 489 0.00021439999 +9 489 3.5699995e-05 +16 489 0.00021439999 +18 489 0.00028589997 +22 489 0.00039309985 +25 489 0.00021439999 +60 489 0.011398599 +66 489 0.0016078998 +68 489 0.16208094 +69 489 0.076145172 +73 489 0.0150075 +75 489 0.010147899 +82 489 3.5699995e-05 +83 489 3.5699995e-05 +84 489 3.5699995e-05 +108 489 7.1499991e-05 +113 489 7.1499991e-05 +114 489 0.00017869999 +126 489 0.00010719999 +127 489 3.5699995e-05 +134 489 0.00010719999 +150 489 0.0019294999 +152 489 0.00010719999 +153 489 0.0001429 +187 489 0.00032159989 +189 489 0.00010719999 +190 489 0.00042879977 +192 489 7.1499991e-05 +194 489 0.00017869999 +196 489 7.1499991e-05 +197 489 0.00010719999 +201 489 3.5699995e-05 +202 489 3.5699995e-05 +203 489 0.0001429 +204 489 0.0019652999 +206 489 0.00032159989 +207 489 0.00010719999 +209 489 3.5699995e-05 +214 489 0.024833798 +215 489 0.00021439999 +217 489 0.0017508999 +218 489 7.1499991e-05 +223 489 0.0001429 +228 489 0.00028589997 +229 489 0.0013577999 +230 489 0.00057169981 +231 489 0.00085759978 +234 489 0.0095047988 +237 489 0.00017869999 +240 489 7.1499991e-05 +248 489 3.5699995e-05 +252 489 0.00021439999 +267 489 0.00060739997 +272 489 7.1499991e-05 +317 489 0.0013220999 +329 489 3.5699995e-05 +330 489 0.00039309985 +331 489 0.0019294999 +356 489 0.00021439999 +358 489 7.1499991e-05 +368 489 0.00017869999 +384 489 0.00078609982 +387 489 7.1499991e-05 +394 489 0.00035729981 +402 489 0.0001429 +412 489 0.00032159989 +413 489 0.00035729981 +414 489 3.5699995e-05 +419 489 3.5699995e-05 +422 489 0.00021439999 +423 489 3.5699995e-05 +425 489 3.5699995e-05 +430 489 3.5699995e-05 +431 489 7.1499991e-05 +432 489 3.5699995e-05 +433 489 7.1499991e-05 +434 489 0.00010719999 +438 489 0.00010719999 +442 489 3.5699995e-05 +443 489 0.0030014999 +444 489 0.00017869999 +445 489 0.0054312982 +446 489 0.0012863998 +447 489 0.0017865999 +448 489 0.00017869999 +450 489 0.0078967996 +452 489 0.012899298 +453 489 0.030658197 +454 489 0.0060386993 +455 489 0.0057170987 +456 489 0.0033230998 +457 489 0.00085759978 +459 489 0.0069677979 +460 489 0.0035017999 +463 489 0.020760398 +464 489 0.00025009993 +465 489 0.0010004998 +467 489 0.023547497 +468 489 0.0020366998 +469 489 0.012113199 +470 489 0.0085756965 +471 489 0.0027514 +473 489 0.0001429 +474 489 0.00021439999 +475 489 7.1499991e-05 +476 489 3.5699995e-05 +477 489 7.1499991e-05 +478 489 0.00010719999 +483 489 0.0012148998 +489 489 7.1499991e-05 +490 489 0.00057169981 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/t1 b/OpenDSSC/klusolve/CSparse/Matrix/t1 new file mode 100644 index 0000000..3fbb980 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/t1 @@ -0,0 +1,10 @@ +2 2 3.0 +1 0 3.1 +3 3 1.0 +0 2 3.2 +1 1 2.9 +3 0 3.5 +3 1 0.4 +1 3 0.9 +0 0 4.5 +2 1 1.7 diff --git a/OpenDSSC/klusolve/CSparse/Matrix/west0067 b/OpenDSSC/klusolve/CSparse/Matrix/west0067 new file mode 100644 index 0000000..09e42cb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Matrix/west0067 @@ -0,0 +1,299 @@ +44 55 -1.863354 +54 61 -1.863354 +29 37 -1.567398 +44 56 -1.490683 +54 62 -1.490683 +9 12 -1.265823 +29 38 -1.253918 +44 57 -1.118012 +54 63 -1.118012 +15 31 -1.05 +16 32 -1.05 +17 33 -1.05 +18 34 -1.05 +19 35 -1.05 +24 31 -1.05 +25 32 -1.05 +26 33 -1.05 +27 34 -1.05 +28 35 -1.05 +9 13 -1.012658 +10 20 -1 +11 21 -1 +12 22 -1 +13 23 -1 +14 24 -1 +30 49 -0.9722222 +31 50 -0.9722222 +32 51 -0.9722222 +33 52 -0.9722222 +34 53 -0.9722222 +39 49 -0.9722222 +40 50 -0.9722222 +41 51 -0.9722222 +42 52 -0.9722222 +43 53 -0.9722222 +35 25 -0.9583187 +36 26 -0.9583187 +37 27 -0.9583187 +38 28 -0.9583187 +49 55 -0.9444444 +50 56 -0.9444444 +51 57 -0.9444444 +52 58 -0.9444444 +53 59 -0.9444444 +29 39 -0.9404389 +20 1 -0.9159533 +21 2 -0.9159533 +22 3 -0.9159533 +23 4 -0.9159533 +0 7 -0.8341818 +1 8 -0.8341818 +2 9 -0.8341818 +3 10 -0.8341818 +45 43 -0.8242248 +46 44 -0.8242248 +47 45 -0.8242248 +48 46 -0.8242248 +4 1 -0.8 +5 2 -0.8 +6 3 -0.8 +7 4 -0.8 +8 5 -0.8 +9 14 -0.7594937 +44 58 -0.7453416 +54 64 -0.7453416 +29 40 -0.6269592 +9 15 -0.5063291 +44 59 -0.3726708 +54 65 -0.3726708 +0 17 -0.3361556 +29 41 -0.3134796 +1 17 -0.2939196 +20 42 -0.2788416 +4 0 -0.2788416 +21 42 -0.2680186 +5 0 -0.2680186 +52 54 -0.2667757 +53 54 -0.2630706 +48 66 -0.2541193 +9 16 -0.2531646 +37 60 -0.2475675 +47 66 -0.2421498 +33 48 -0.2362845 +42 48 -0.2362845 +36 60 -0.2356469 +22 42 -0.2323717 +6 0 -0.2323717 +32 48 -0.2303917 +41 48 -0.2303917 +17 30 -0.2286264 +26 30 -0.2286264 +16 30 -0.2232997 +25 30 -0.2232997 +2 17 -0.2214815 +12 19 -0.2144206 +11 19 -0.2140392 +51 54 -0.2122056 +38 60 -0.2074873 +10 19 -0.2071759 +15 30 -0.2070986 +24 30 -0.2070986 +35 60 -0.2069954 +18 30 -0.2024528 +27 30 -0.2024528 +13 19 -0.1986768 +31 48 -0.1947711 +40 48 -0.1947711 +46 66 -0.1918557 +34 48 -0.18039 +43 48 -0.18039 +14 19 -0.1656874 +30 48 -0.1581626 +39 48 -0.1581626 +23 42 -0.1575082 +7 0 -0.1575082 +50 54 -0.1514908 +45 66 -0.1443354 +19 30 -0.1385226 +28 30 -0.1385226 +3 17 -0.118986 +49 54 -0.1064573 +8 0 -0.06325978 +8 6 0.01178291 +28 0 0.03162989 +7 6 0.04759439 +39 54 0.05322864 +40 54 0.07574542 +27 0 0.07875411 +24 36 0.08147449 +6 6 0.08859262 +30 36 0.09052721 +28 36 0.09241909 +25 36 0.09789015 +19 19 0.09941246 +34 36 0.1026879 +41 54 0.1061028 +31 36 0.1087668 +26 36 0.1131608 +27 36 0.1150555 +26 0 0.1161859 +5 6 0.1175679 +18 19 0.1192061 +15 19 0.1243055 +32 36 0.1257342 +33 36 0.1278394 +16 19 0.1284235 +17 19 0.1286524 +43 54 0.1315353 +42 54 0.1333878 +25 0 0.1340093 +4 6 0.1344622 +24 0 0.1394208 +30 43 0.25 +31 44 0.25 +32 45 0.25 +33 46 0.25 +34 47 0.25 +10 12 0.3333333 +11 13 0.3333333 +12 14 0.3333333 +13 15 0.3333333 +14 16 0.3333333 +24 1 0.4 +25 2 0.4 +26 3 0.4 +27 4 0.4 +28 5 0.4 +4 12 0.4 +4 7 0.4 +5 13 0.4 +5 8 0.4 +6 14 0.4 +6 9 0.4 +7 10 0.4 +7 15 0.4 +8 11 0.4 +8 16 0.4 +49 61 0.4444444 +50 62 0.4444444 +51 63 0.4444444 +52 64 0.4444444 +53 65 0.4444444 +15 25 0.45 +16 26 0.45 +17 27 0.45 +18 28 0.45 +19 29 0.45 +39 55 0.4722222 +40 56 0.4722222 +41 57 0.4722222 +42 58 0.4722222 +43 59 0.4722222 +39 25 0.5 +40 26 0.5 +41 27 0.5 +42 28 0.5 +43 29 0.5 +49 43 0.5 +50 44 0.5 +51 45 0.5 +52 46 0.5 +53 47 0.5 +3 15 0.5063291 +15 20 0.6 +16 21 0.6 +17 22 0.6 +18 23 0.6 +19 24 0.6 +23 40 0.6269592 +24 37 0.65 +25 38 0.65 +26 39 0.65 +27 40 0.65 +28 41 0.65 +14 18 0.6666667 +30 37 0.7222222 +31 38 0.7222222 +32 39 0.7222222 +33 40 0.7222222 +34 41 0.7222222 +38 58 0.7453416 +48 64 0.7453416 +2 14 0.7594937 +22 39 0.9404389 +59 31 0.5 +59 32 0.5 +59 33 0.5 +59 34 0.5 +59 35 0.5 +29 42 1 +44 60 1 +54 66 1 +55 18 1 +56 10 1 +56 11 1 +56 7 1 +56 8 1 +56 9 1 +57 12 1 +57 13 1 +57 14 1 +57 15 1 +57 16 1 +58 20 1 +58 21 1 +58 22 1 +58 23 1 +58 24 1 +59 31 0.5 +59 32 0.5 +59 33 0.5 +59 34 0.5 +59 35 0.5 +60 1 1 +60 2 1 +60 3 1 +60 4 1 +60 5 1 +61 37 1 +61 38 1 +61 39 1 +61 40 1 +61 41 1 +62 49 1 +62 50 1 +62 51 1 +62 52 1 +62 53 1 +63 25 1 +63 26 1 +63 27 1 +63 28 1 +63 29 1 +64 55 1 +64 56 1 +64 57 1 +64 58 1 +64 59 1 +65 43 1 +65 44 1 +65 45 1 +65 46 1 +65 47 1 +66 61 1 +66 62 1 +66 63 1 +66 64 1 +66 65 1 +9 17 1 +1 13 1.012658 +37 57 1.118012 +47 63 1.118012 +21 38 1.253918 +0 12 1.265823 +36 56 1.490683 +46 62 1.490683 +20 37 1.567398 +35 55 1.863354 +45 61 1.863354 diff --git a/OpenDSSC/klusolve/CSparse/README.txt b/OpenDSSC/klusolve/CSparse/README.txt new file mode 100644 index 0000000..201a6e5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/README.txt @@ -0,0 +1,427 @@ +CSparse: Copyright (c) 2006-2011, Timothy A. Davis. + +Refer to "Direct Methods for Sparse Linear Systems," Timothy A. Davis, +SIAM, Philadelphia, 2006. No detailed user guide is included in this +package; the user guide is the book itself. + +The algorithms contained in CSparse have been chosen with five goals in mind: +(1) they must embody much of the theory behind sparse matrix algorithms, +(2) they must be either asymptotically optimal in their run time and memory + usage or be fast in practice, +(3) they must be concise so as to be easily understood and short enough to + print in the book, +(4) they must cover a wide spectrum of matrix operations, and +(5) they must be accurate and robust. +The focus is on direct methods; iterative methods and solvers for +eigenvalue problems are beyond the scope of this package. + +No detailed user guide is included in this package; the user guide is the +book itself. Some indication of how to call the CSparse C routines is given +by the M-files in the MATLAB/CSparse directory. + +Complex matrices are not supported, except for methods that operate only +on the nonzero pattern of a matrix. A complex version of CSparse appears +as a separate package, CXSparse ("Concise Extended Sparse matrix package"). + +The performance of the sparse factorization methods in CSparse will not be +competitive with UMFPACK or CHOLMOD, but the codes are much more concise and +easy to understand (see the above goals). Other methods are competitive. + +Some of the MATLAB tests require the AMD package. +See http://www.cise.ufl.edu/research/sparse for CSparse and the AMD ordering +package. See the Doc/License.txt file for the license (GNU LGPL). + +To compile the C-library (./Source) and C demo programs (./Demo) just type +"make" in this directory. This should work on any system with the "make" +command. To run the exhaustive tests, type "make" in the Tcov directory +(Linux is assumed). To compile the MATLAB mexFunctions type "make mex" in +this directory, or just "make" in the MATLAB directory. To remove all files +not in the original distribution, type "make distclean". I recommend that you +use a different level of optimization than "cc -O", which was chosen so that +the Makefile is portable. See Source/Makefile. + +You can simply type "cs_install" while in the CSparse/MATLAB directory to +compile and install CSparse for use in MATLAB. This is especially useful for +a typical Microsoft Windows system, which does not include "make". For more +details, see CSparse/MATLAB/README.txt. + +-------------------------------------------------------------------------------- +Contents: +-------------------------------------------------------------------------------- + +Demo/ demo C programs that use CSparse +Doc/ license and change log +Makefile Makefile for the whole package +MATLAB/ MATLAB interface, demos, and tests for CSparse +Matrix/ sample matrices +README.txt this file +Source/ primary CSparse source files (C only, no MATLAB) +Tcov/ CSparse tests + +-------------------------------------------------------------------------------- +./Doc: license and change log +-------------------------------------------------------------------------------- + +ChangeLog changes in CSparse since first release +lesser.txt the GNU LGPL +License.txt license (GNU LGPL) + +-------------------------------------------------------------------------------- +./Source: Primary source code for CSparse +-------------------------------------------------------------------------------- + +cs_add.c add sparse matrices +cs_amd.c approximate minimum degree +cs_chol.c sparse Cholesky +cs_cholsol.c x=A\b using sparse Cholesky +cs_compress.c convert a triplet form to compressed-column form +cs_counts.c column counts for Cholesky and QR +cs_cumsum.c cumulative sum +cs_dfs.c depth-first-search +cs_dmperm.c Dulmage-Mendelsohn permutation +cs_droptol.c drop small entries from a sparse matrix +cs_dropzeros.c drop zeros from a sparse matrix +cs_dupl.c remove (and sum) duplicates +cs_entry.c add an entry to a triplet matrix +cs_ereach.c nonzero pattern of Cholesky L(k,:) from etree and triu(A(:,k)) +cs_etree.c find elimination tree +cs_fkeep.c drop entries from a sparse matrix +cs_gaxpy.c sparse matrix times dense matrix +cs.h include file for CSparse +cs_happly.c apply Householder reflection +cs_house.c compute Householder reflection +cs_ipvec.c x(p)=b +cs_leaf.c determine if j is a leaf of the skeleton matrix and find lca +cs_load.c load a sparse matrix from a file +cs_lsolve.c x=L\b +cs_ltsolve.c x=L'\b +cs_lu.c sparse LU factorization +cs_lusol.c x=A\b using sparse LU factorization +cs_malloc.c memory manager +cs_maxtrans.c maximum transveral (permutation for zero-free diagonal) +cs_multiply.c sparse matrix multiply +cs_norm.c sparse matrix norm +cs_permute.c permute a sparse matrix +cs_pinv.c invert a permutation vector +cs_post.c postorder an elimination tree +cs_print.c print a sparse matrix +cs_pvec.c x=b(p) +cs_qr.c sparse QR +cs_qrsol.c solve a least-squares problem +cs_randperm.c random permutation +cs_reach.c find nonzero pattern of x=L\b for sparse L and b +cs_scatter.c scatter a sparse vector +cs_scc.c strongly-connected components +cs_schol.c symbolic Cholesky +cs_spsolve.c x=G\b where G, x, and b are sparse, and G upper/lower triangular +cs_sqr.c symbolic QR (also can be used for LU) +cs_symperm.c symmetric permutation of a sparse matrix +cs_tdfs.c depth-first-search of a tree +cs_transpose.c transpose a sparse matrix +cs_updown.c sparse rank-1 Cholesky update/downate +cs_usolve.c x=U\b +cs_util.c various utilities (allocate/free matrices, workspace, etc) +cs_utsolve.c x=U'\b +Makefile Makefile for CSparse +README.txt README file for CSparse + + +-------------------------------------------------------------------------------- +./Demo: C program demos +-------------------------------------------------------------------------------- + +cs_demo1.c read a matrix from a file and perform basic matrix operations +cs_demo2.c read a matrix from a file and solve a linear system +cs_demo3.c read a matrix, solve a linear system, update/downdate +cs_demo.c support routines for cs_demo*.c +cs_demo.h include file for demo programs +cs_demo.out output of "make", which runs the demos on some matrices +Makefile Makefile for Demo programs +readhb.f read a Rutherford-Boeing matrix +README.txt Demo README file + + +-------------------------------------------------------------------------------- +./MATLAB: MATLAB interface, demos, and tests +-------------------------------------------------------------------------------- + +cs_install.m MATLAB function for compiling and installing CSparse for MATLAB +CSparse/ MATLAB interface for CSparse +Demo/ MATLAB demos for CSparse +Makefile MATLAB interface Makefile +README.txt MATLAB README file +Test/ MATLAB test for CSparse, and "textbook" routines +UFget/ MATLAB interface to UF Sparse Matrix Collection + + +-------------------------------------------------------------------------------- +./MATLAB/CSparse: MATLAB interface for CSparse +-------------------------------------------------------------------------------- + +Contents.m Contents of MATLAB interface to CSparse +cs_add.m add two sparse matrices +cs_add_mex.c +cs_amd.m approximate minimum degree +cs_amd_mex.c +cs_chol.m sparse Cholesky +cs_chol_mex.c +cs_cholsol.m x=A\b using a sparse Cholesky +cs_cholsol_mex.c +cs_counts.m column counts for Cholesky or QR (like "symbfact" in MATLAB) +cs_counts_mex.c +cs_dmperm.m Dulmage-Mendelsohn permutation +cs_dmperm_mex.c +cs_dmsol.m x=A\b using dmperm +cs_dmspy.m plot a picture of a dmperm-permuted matrix +cs_droptol.m drop small entries +cs_droptol_mex.c +cs_esep.m find edge separator +cs_etree.m compute elimination tree +cs_etree_mex.c +cs_gaxpy.m sparse matrix times dense vector +cs_gaxpy_mex.c +cs_lsolve.m x=L\b where L is lower triangular +cs_lsolve_mex.c +cs_ltsolve.m x=L'\b where L is lower triangular +cs_ltsolve_mex.c +cs_lu.m sparse LU factorization +cs_lu_mex.c +cs_lusol.m x=A\b using sparse LU factorization +cs_lusol_mex.c +cs_make.m compiles CSparse for use in MATLAB +cs_mex.c support routines for CSparse mexFunctions +cs_mex.h +cs_multiply.m sparse matrix multiply +cs_multiply_mex.c +cs_must_compile.m determine if a source file needs to be compiled with mex +cs_nd.m nested dissection +cs_nsep.m find node separator +cs_permute.m permute a sparse matrix +cs_permute_mex.c +cs_print.m print a sparse matrix +cs_print_mex.c +cs_qleft.m apply Householder vectors to the left +cs_qright.m apply Householder vectors to the right +cs_qr.m sparse QR factorization +cs_qr_mex.c +cs_qrsol.m solve a sparse least squares problem +cs_qrsol_mex.c +cs_randperm.m randdom permutation +cs_randperm_mex.c +cs_scc.m strongly-connected components +cs_scc_mex.c +cs_sep.m convert an edge separator into a node separator +cs_sparse.m convert a triplet form matrix to a compress-column form +cs_sparse_mex.c +cs_symperm.m symmetric permutation of a sparse matrix +cs_symperm_mex.c +cs_sqr.m symbolic QR ordering and analysis +cs_sqr_mex.c +cs_thumb_mex.c compute small "thumbnail" of a sparse matrix (for cspy). +cs_transpose.m transpose a sparse matrix +cs_transpose_mex.c +cs_updown.m sparse Cholesky update/downdate +cs_updown_mex.c +cs_usolve.m x=U\b where U is upper triangular +cs_usolve_mex.c +cs_utsolve.m x=U'\b where U is upper triangular +cs_utsolve_mex.c +cspy.m a color "spy" +Makefile Makefile for CSparse MATLAB interface +README.txt README file for CSparse MATLAB interface + + +-------------------------------------------------------------------------------- +./MATLAB/Demo: MATLAB demos for CSparse +-------------------------------------------------------------------------------- + +Contents.m Contents of MATLAB demo for CSparse +cs_demo.m run all MATLAB demos for CSparse +cs_demo1.m MATLAB version of Demo/cs_demo1.c +cs_demo2.m MATLAB version of Demo/cs_demo2.c +cs_demo3.m MATLAB version of Demo/cs_demo3.c +private/ private functions for MATLAB demos +README.txt README file for CSparse MATLAB demo + + +-------------------------------------------------------------------------------- +./MATLAB/Demo/private: private functions for MATLAB demos +-------------------------------------------------------------------------------- + +demo2.m demo 2 +demo3.m demo 3 +ex_1.m example 1 +ex2.m example 2 +ex3.m example 3 +frand.m generate a random finite-element matrix +get_problem.m get a matrix +is_sym.m determine if a matrix is symmetric +mesh2d1.m construct a 2D mesh (method 1) +mesh2d2.m construct a 2D mesh (method 2) +mesh3d1.m construct a 3D mesh (method 1) +mesh3d2.m construct a 3D mesh (method 2) +print_order.m print the ordering method used +resid.m compute residual +rhs.m create right-hand-side + + +-------------------------------------------------------------------------------- +./MATLAB/Test: Extensive test of CSparse, in MATLAB +-------------------------------------------------------------------------------- + +Makefile Makefile for MATLAB Test directory +README.txt README file for MATLAB/Test +Contents.m Contents of MATLAB/Test, "textbook" files only + +chol_downdate.m downdate a Cholesky factorization. +chol_left.m left-looking Cholesky factorization. +chol_left2.m left-looking Cholesky factorization, more details. +chol_right.m right-looking Cholesky factorization. +chol_super.m left-looking "supernodal" Cholesky factorization. +chol_up.m up-looking Cholesky factorization. +chol_update.m update a Cholesky factorization. +chol_updown.m update or downdate a Cholesky factorization. +cond1est.m 1-norm condition estimate. +cs_fiedler.m the Fiedler vector of a connected graph. +givens2.m find a Givens rotation. +house.m find a Householder reflection. +lu_left.m left-looking LU factorization. +lu_right.m right-looking LU factorization. +lu_rightp.m right-looking LU factorization, with partial pivoting. +lu_rightpr.m recursive right-looking LU, with partial pivoting. +lu_rightr.m recursive right-looking LU. +norm1est.m 1-norm estimate. +qr_givens.m Givens-rotation QR factorization. +qr_givens_full.m Givens-rotation QR factorization, for full matrices. +qr_left.m left-looking Householder QR factorization. +qr_right.m right-looking Householder QR factorization. +cs_fiedler.m Fiedler vector + +cs_frand.m generate a random finite-element matrix +cs_frand_mex.c +cs_ipvec.m x(p)=b +cs_ipvec_mex.c +cs_maxtransr.m recursive maximum matching algorithm +cs_maxtransr_mex.c +cs_pvec.m x=b(p) +cs_pvec_mex.c interface for cs_pvec +cs_reach.m non-recursive reach (interface to CSparse cs_reach) +cs_reach_mex.c non-recursive x=spones(L\sparse(b)) +cs_reachr.m recursive reach (interface to CSparse cs_reachr) +cs_reachr_mex.c +cs_rowcnt.m row counts for sparse Cholesky +cs_rowcnt_mex.c row counts for sparse Cholesky +cs_sparse2.m same as cs_sparse, to test cs_entry function +cs_sparse2_mex.c like cs_sparse, but for testing cs_entry + +cs_test_make.m compiles MATLAB tests + +check_if_same.m check if two inputs are identical or not +choldn.m Cholesky downdate +cholup.m Cholesky update, using Given's rotations +cholupdown.m Cholesky update/downdate (Bischof, Pan, and Tang method) +cs_q1.m construct Q from Householder vectors +cs_test_make.m compiles the CSparse, Demo, and Test mexFunctions. +dmperm_test.m test cs_dmperm +chol_example.m simple Cholesky factorization example +etree_sample.m construct a sample etree and symbolic factorization +gqr3.m QR factorization, based on Givens rotations +happly.m apply Householder reflection to a vector +hmake1.m construct a Householder reflection +mynormest1.m estimate norm(A,1), using LU factorization (L*U = P*A*Q). +myqr.m QR factorization using Householder reflections +another_colormap.m try another color map +cspy_test.m test cspy and cs_dmspy +qr2.m QR factorization based on Householder reflections +sample_colormap.m try a colormap for use in cspy +signum.m compute and display the sign of a column vector x +sqr_example.m test cs_sqr +dmspy_test.m test cspy, cs_dmspy, and cs_dmperm +test_qr.m test various QR factorization methods +test_randperms.m test random permutations +testh.m test Householder reflections +test_qr1.m test QR factorizations +test_qrsol.m test cs_qrsol +test_sep.m test cs_sep, and compare with Gilbert's meshpart vtxsep +testall.m test all CSparse functions (run tests 1 to 28 below) +test1.m test cs_transpose +test2.m test cs_sparse +test3.m test cs_lsolve, cs_ltsolve, cs_usolve, cs_chol +test4.m test cs_multiply +test5.m test cs_add +test6.m test cs_reach, cs_reachr, cs_lsolve, cs_usolve +test7.m test cs_lu +test8.m test cs_cholsol, cs_lusol +test9.m test cs_qr +test10.m test cs_qr +test11.m test cs_rowcnt +test12.m test cs_qr and compare with svd +test13.m test cs_counts, cs_etree +test14.m test cs_droptol +test15.m test cs_amd +test16.m test cs_amd +test17.m test cs_qr, cs_qright, cs_q1, cs_qrleft, cs_qrsol +test18.m test iterative refinement after backslash +test19.m test cs_dmperm, cs_maxtransr, cs_dmspy, cs_scc +test20.m test cholupdown +test21.m test cs_updown +test22.m test cond1est +test23.m test cs_dmspy +test24.m test cs_fielder +test25.m test cs_nd +test26.m test cs_dmsol and cs_dmspy +test27.m test cs_qr, cs_utsolve, cs_qrsol +test28.m test cs_randperm, cs_dmperm + + +-------------------------------------------------------------------------------- +./MATLAB/UFget: MATLAB interface for the UF Sparse Matrix Collection +-------------------------------------------------------------------------------- + +Contents.m Contents of UFget +mat/ default directory where downloaded matrices will be put +README.txt README file for UFget +UFget_defaults.m default parameter settings +UFget_example.m example of use +UFget_install.m installs UFget temporarily (for current session) +UFget_java.class read a url and load it in into MATLAB (compiled Java code) +UFget_java.java read a url and load it in into MATLAB (Java source code) +UFget_lookup.m look up a matrix in the index +UFget.m UFget itself (primary user interface) +UFweb.m open url for a matrix or collection +mat/UF_Index.mat index of matrices in UF Sparse Matrix Collection + + +-------------------------------------------------------------------------------- +./Matrix: Sample matrices, most from Rutherford/Boeing collection +-------------------------------------------------------------------------------- + +ash219 overdetermined pattern of Holland survey. Ashkenazi, 1974. +bcsstk01 stiffness matrix for small generalized eigenvalue problem +bcsstk16 stiffness matrix, Corp of Engineers dam +fs_183_1 unsymmetric facsimile convergence matrix +lp_afiro NETLIB afiro linear programming problem +mbeacxc US economy, 1972. Dan Szyld, while at NYU +t1 small example used in Chapter 2 +west0067 Cavett problem with 5 components (chemical eng., Westerberg) + + +-------------------------------------------------------------------------------- +./Tcov: Exhaustive test coverage of CSparse +-------------------------------------------------------------------------------- + +covall same as covall.linux +covall.linux find coverage (Linux) +covall.sol find coverage (Solaris) +cov.awk coverage summary +cover print uncovered lines +covs print uncovered lines +cstcov_malloc_test.c malloc test +cstcov_malloc_test.h +cstcov_test.c main program for Tcov tests +gcovs run gcov (Linux) +Makefile Makefile for Tcov tests +nil an empty matrix +zero a 1-by-1 zero matrix +README.txt README file for Tcov directory + diff --git a/OpenDSSC/klusolve/CSparse/Source/README.txt b/OpenDSSC/klusolve/CSparse/Source/README.txt new file mode 100644 index 0000000..9507521 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/README.txt @@ -0,0 +1,3 @@ +CSparse/Source directory: primary ANSI C source code files for CSparse. +All of these files are printed verbatim in the book. To compile the +libcsparse.a C-callable library, just type "make" in this directory. diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_add.c b/OpenDSSC/klusolve/CSparse/Source/cs_add.c new file mode 100644 index 0000000..c4841e9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_add.c @@ -0,0 +1,28 @@ +#include "cs.h" +/* C = alpha*A + beta*B */ +cs *cs_add (const cs *A, const cs *B, double alpha, double beta) +{ + int p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values ; + double *x, *Bx, *Cx ; + cs *C ; + if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ + if (A->m != B->m || A->n != B->n) return (NULL) ; + m = A->m ; anz = A->p [A->n] ; + n = B->n ; Bp = B->p ; Bx = B->x ; bnz = Bp [n] ; + w = cs_calloc (m, sizeof (int)) ; /* get workspace */ + values = (A->x != NULL) && (Bx != NULL) ; + x = values ? cs_malloc (m, sizeof (double)) : NULL ; /* get workspace */ + C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result*/ + if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; + Cp = C->p ; Ci = C->i ; Cx = C->x ; + for (j = 0 ; j < n ; j++) + { + Cp [j] = nz ; /* column j of C starts here */ + nz = cs_scatter (A, j, alpha, w, x, j+1, C, nz) ; /* alpha*A(:,j)*/ + nz = cs_scatter (B, j, beta, w, x, j+1, C, nz) ; /* beta*B(:,j) */ + if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; + } + Cp [n] = nz ; /* finalize the last column of C */ + cs_sprealloc (C, 0) ; /* remove extra space from C */ + return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_amd.c b/OpenDSSC/klusolve/CSparse/Source/cs_amd.c new file mode 100644 index 0000000..3c21c9b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_amd.c @@ -0,0 +1,364 @@ +#include "cs.h" +/* clear w */ +static int cs_wclear (int mark, int lemax, int *w, int n) +{ + int k ; + if (mark < 2 || (mark + lemax < 0)) + { + for (k = 0 ; k < n ; k++) if (w [k] != 0) w [k] = 1 ; + mark = 2 ; + } + return (mark) ; /* at this point, w [0..n-1] < mark holds */ +} + +/* keep off-diagonal entries; drop diagonal entries */ +static int cs_diag (int i, int j, double aij, void *other) { return (i != j) ; } + +/* p = amd(A+A') if symmetric is true, or amd(A'A) otherwise */ +int *cs_amd (int order, const cs *A) /* order 0:natural, 1:Chol, 2:LU, 3:QR */ +{ + cs *C, *A2, *AT ; + int *Cp, *Ci, *last, *W, *len, *nv, *next, *P, *head, *elen, *degree, *w, + *hhead, *ATp, *ATi, d, dk, dext, lemax = 0, e, elenk, eln, i, j, k, k1, + k2, k3, jlast, ln, dense, nzmax, mindeg = 0, nvi, nvj, nvk, mark, wnvi, + ok, cnz, nel = 0, p, p1, p2, p3, p4, pj, pk, pk1, pk2, pn, q, n, m, t ; + unsigned int h ; + /* --- Construct matrix C ----------------------------------------------- */ + if (!CS_CSC (A) || order <= 0 || order > 3) return (NULL) ; /* check */ + AT = cs_transpose (A, 0) ; /* compute A' */ + if (!AT) return (NULL) ; + m = A->m ; n = A->n ; + dense = CS_MAX (16, 10 * sqrt ((double) n)) ; /* find dense threshold */ + dense = CS_MIN (n-2, dense) ; + if (order == 1 && n == m) + { + C = cs_add (A, AT, 0, 0) ; /* C = A+A' */ + } + else if (order == 2) + { + ATp = AT->p ; /* drop dense columns from AT */ + ATi = AT->i ; + for (p2 = 0, j = 0 ; j < m ; j++) + { + p = ATp [j] ; /* column j of AT starts here */ + ATp [j] = p2 ; /* new column j starts here */ + if (ATp [j+1] - p > dense) continue ; /* skip dense col j */ + for ( ; p < ATp [j+1] ; p++) ATi [p2++] = ATi [p] ; + } + ATp [m] = p2 ; /* finalize AT */ + A2 = cs_transpose (AT, 0) ; /* A2 = AT' */ + C = A2 ? cs_multiply (AT, A2) : NULL ; /* C=A'*A with no dense rows */ + cs_spfree (A2) ; + } + else + { + C = cs_multiply (AT, A) ; /* C=A'*A */ + } + cs_spfree (AT) ; + if (!C) return (NULL) ; + cs_fkeep (C, &cs_diag, NULL) ; /* drop diagonal entries */ + Cp = C->p ; + cnz = Cp [n] ; + P = cs_malloc (n+1, sizeof (int)) ; /* allocate result */ + W = cs_malloc (8*(n+1), sizeof (int)) ; /* get workspace */ + t = cnz + cnz/5 + 2*n ; /* add elbow room to C */ + if (!P || !W || !cs_sprealloc (C, t)) return (cs_idone (P, C, W, 0)) ; + len = W ; nv = W + (n+1) ; next = W + 2*(n+1) ; + head = W + 3*(n+1) ; elen = W + 4*(n+1) ; degree = W + 5*(n+1) ; + w = W + 6*(n+1) ; hhead = W + 7*(n+1) ; + last = P ; /* use P as workspace for last */ + /* --- Initialize quotient graph ---------------------------------------- */ + for (k = 0 ; k < n ; k++) len [k] = Cp [k+1] - Cp [k] ; + len [n] = 0 ; + nzmax = C->nzmax ; + Ci = C->i ; + for (i = 0 ; i <= n ; i++) + { + head [i] = -1 ; /* degree list i is empty */ + last [i] = -1 ; + next [i] = -1 ; + hhead [i] = -1 ; /* hash list i is empty */ + nv [i] = 1 ; /* node i is just one node */ + w [i] = 1 ; /* node i is alive */ + elen [i] = 0 ; /* Ek of node i is empty */ + degree [i] = len [i] ; /* degree of node i */ + } + mark = cs_wclear (0, 0, w, n) ; /* clear w */ + elen [n] = -2 ; /* n is a dead element */ + Cp [n] = -1 ; /* n is a root of assembly tree */ + w [n] = 0 ; /* n is a dead element */ + /* --- Initialize degree lists ------------------------------------------ */ + for (i = 0 ; i < n ; i++) + { + d = degree [i] ; + if (d == 0) /* node i is empty */ + { + elen [i] = -2 ; /* element i is dead */ + nel++ ; + Cp [i] = -1 ; /* i is a root of assembly tree */ + w [i] = 0 ; + } + else if (d > dense) /* node i is dense */ + { + nv [i] = 0 ; /* absorb i into element n */ + elen [i] = -1 ; /* node i is dead */ + nel++ ; + Cp [i] = CS_FLIP (n) ; + nv [n]++ ; + } + else + { + if (head [d] != -1) last [head [d]] = i ; + next [i] = head [d] ; /* put node i in degree list d */ + head [d] = i ; + } + } + while (nel < n) /* while (selecting pivots) do */ + { + /* --- Select node of minimum approximate degree -------------------- */ + for (k = -1 ; mindeg < n && (k = head [mindeg]) == -1 ; mindeg++) ; + if (next [k] != -1) last [next [k]] = -1 ; + head [mindeg] = next [k] ; /* remove k from degree list */ + elenk = elen [k] ; /* elenk = |Ek| */ + nvk = nv [k] ; /* # of nodes k represents */ + nel += nvk ; /* nv[k] nodes of A eliminated */ + /* --- Garbage collection ------------------------------------------- */ + if (elenk > 0 && cnz + mindeg >= nzmax) + { + for (j = 0 ; j < n ; j++) + { + if ((p = Cp [j]) >= 0) /* j is a live node or element */ + { + Cp [j] = Ci [p] ; /* save first entry of object */ + Ci [p] = CS_FLIP (j) ; /* first entry is now CS_FLIP(j) */ + } + } + for (q = 0, p = 0 ; p < cnz ; ) /* scan all of memory */ + { + if ((j = CS_FLIP (Ci [p++])) >= 0) /* found object j */ + { + Ci [q] = Cp [j] ; /* restore first entry of object */ + Cp [j] = q++ ; /* new pointer to object j */ + for (k3 = 0 ; k3 < len [j]-1 ; k3++) Ci [q++] = Ci [p++] ; + } + } + cnz = q ; /* Ci [cnz...nzmax-1] now free */ + } + /* --- Construct new element ---------------------------------------- */ + dk = 0 ; + nv [k] = -nvk ; /* flag k as in Lk */ + p = Cp [k] ; + pk1 = (elenk == 0) ? p : cnz ; /* do in place if elen[k] == 0 */ + pk2 = pk1 ; + for (k1 = 1 ; k1 <= elenk + 1 ; k1++) + { + if (k1 > elenk) + { + e = k ; /* search the nodes in k */ + pj = p ; /* list of nodes starts at Ci[pj]*/ + ln = len [k] - elenk ; /* length of list of nodes in k */ + } + else + { + e = Ci [p++] ; /* search the nodes in e */ + pj = Cp [e] ; + ln = len [e] ; /* length of list of nodes in e */ + } + for (k2 = 1 ; k2 <= ln ; k2++) + { + i = Ci [pj++] ; + if ((nvi = nv [i]) <= 0) continue ; /* node i dead, or seen */ + dk += nvi ; /* degree[Lk] += size of node i */ + nv [i] = -nvi ; /* negate nv[i] to denote i in Lk*/ + Ci [pk2++] = i ; /* place i in Lk */ + if (next [i] != -1) last [next [i]] = last [i] ; + if (last [i] != -1) /* remove i from degree list */ + { + next [last [i]] = next [i] ; + } + else + { + head [degree [i]] = next [i] ; + } + } + if (e != k) + { + Cp [e] = CS_FLIP (k) ; /* absorb e into k */ + w [e] = 0 ; /* e is now a dead element */ + } + } + if (elenk != 0) cnz = pk2 ; /* Ci [cnz...nzmax] is free */ + degree [k] = dk ; /* external degree of k - |Lk\i| */ + Cp [k] = pk1 ; /* element k is in Ci[pk1..pk2-1] */ + len [k] = pk2 - pk1 ; + elen [k] = -2 ; /* k is now an element */ + /* --- Find set differences ----------------------------------------- */ + mark = cs_wclear (mark, lemax, w, n) ; /* clear w if necessary */ + for (pk = pk1 ; pk < pk2 ; pk++) /* scan 1: find |Le\Lk| */ + { + i = Ci [pk] ; + if ((eln = elen [i]) <= 0) continue ;/* skip if elen[i] empty */ + nvi = -nv [i] ; /* nv [i] was negated */ + wnvi = mark - nvi ; + for (p = Cp [i] ; p <= Cp [i] + eln - 1 ; p++) /* scan Ei */ + { + e = Ci [p] ; + if (w [e] >= mark) + { + w [e] -= nvi ; /* decrement |Le\Lk| */ + } + else if (w [e] != 0) /* ensure e is a live element */ + { + w [e] = degree [e] + wnvi ; /* 1st time e seen in scan 1 */ + } + } + } + /* --- Degree update ------------------------------------------------ */ + for (pk = pk1 ; pk < pk2 ; pk++) /* scan2: degree update */ + { + i = Ci [pk] ; /* consider node i in Lk */ + p1 = Cp [i] ; + p2 = p1 + elen [i] - 1 ; + pn = p1 ; + for (h = 0, d = 0, p = p1 ; p <= p2 ; p++) /* scan Ei */ + { + e = Ci [p] ; + if (w [e] != 0) /* e is an unabsorbed element */ + { + dext = w [e] - mark ; /* dext = |Le\Lk| */ + if (dext > 0) + { + d += dext ; /* sum up the set differences */ + Ci [pn++] = e ; /* keep e in Ei */ + h += e ; /* compute the hash of node i */ + } + else + { + Cp [e] = CS_FLIP (k) ; /* aggressive absorb. e->k */ + w [e] = 0 ; /* e is a dead element */ + } + } + } + elen [i] = pn - p1 + 1 ; /* elen[i] = |Ei| */ + p3 = pn ; + p4 = p1 + len [i] ; + for (p = p2 + 1 ; p < p4 ; p++) /* prune edges in Ai */ + { + j = Ci [p] ; + if ((nvj = nv [j]) <= 0) continue ; /* node j dead or in Lk */ + d += nvj ; /* degree(i) += |j| */ + Ci [pn++] = j ; /* place j in node list of i */ + h += j ; /* compute hash for node i */ + } + if (d == 0) /* check for mass elimination */ + { + Cp [i] = CS_FLIP (k) ; /* absorb i into k */ + nvi = -nv [i] ; + dk -= nvi ; /* |Lk| -= |i| */ + nvk += nvi ; /* |k| += nv[i] */ + nel += nvi ; + nv [i] = 0 ; + elen [i] = -1 ; /* node i is dead */ + } + else + { + degree [i] = CS_MIN (degree [i], d) ; /* update degree(i) */ + Ci [pn] = Ci [p3] ; /* move first node to end */ + Ci [p3] = Ci [p1] ; /* move 1st el. to end of Ei */ + Ci [p1] = k ; /* add k as 1st element in of Ei */ + len [i] = pn - p1 + 1 ; /* new len of adj. list of node i */ + h %= n ; /* finalize hash of i */ + next [i] = hhead [h] ; /* place i in hash bucket */ + hhead [h] = i ; + last [i] = h ; /* save hash of i in last[i] */ + } + } /* scan2 is done */ + degree [k] = dk ; /* finalize |Lk| */ + lemax = CS_MAX (lemax, dk) ; + mark = cs_wclear (mark+lemax, lemax, w, n) ; /* clear w */ + /* --- Supernode detection ------------------------------------------ */ + for (pk = pk1 ; pk < pk2 ; pk++) + { + i = Ci [pk] ; + if (nv [i] >= 0) continue ; /* skip if i is dead */ + h = last [i] ; /* scan hash bucket of node i */ + i = hhead [h] ; + hhead [h] = -1 ; /* hash bucket will be empty */ + for ( ; i != -1 && next [i] != -1 ; i = next [i], mark++) + { + ln = len [i] ; + eln = elen [i] ; + for (p = Cp [i]+1 ; p <= Cp [i] + ln-1 ; p++) w [Ci [p]] = mark; + jlast = i ; + for (j = next [i] ; j != -1 ; ) /* compare i with all j */ + { + ok = (len [j] == ln) && (elen [j] == eln) ; + for (p = Cp [j] + 1 ; ok && p <= Cp [j] + ln - 1 ; p++) + { + if (w [Ci [p]] != mark) ok = 0 ; /* compare i and j*/ + } + if (ok) /* i and j are identical */ + { + Cp [j] = CS_FLIP (i) ; /* absorb j into i */ + nv [i] += nv [j] ; + nv [j] = 0 ; + elen [j] = -1 ; /* node j is dead */ + j = next [j] ; /* delete j from hash bucket */ + next [jlast] = j ; + } + else + { + jlast = j ; /* j and i are different */ + j = next [j] ; + } + } + } + } + /* --- Finalize new element------------------------------------------ */ + for (p = pk1, pk = pk1 ; pk < pk2 ; pk++) /* finalize Lk */ + { + i = Ci [pk] ; + if ((nvi = -nv [i]) <= 0) continue ;/* skip if i is dead */ + nv [i] = nvi ; /* restore nv[i] */ + d = degree [i] + dk - nvi ; /* compute external degree(i) */ + d = CS_MIN (d, n - nel - nvi) ; + if (head [d] != -1) last [head [d]] = i ; + next [i] = head [d] ; /* put i back in degree list */ + last [i] = -1 ; + head [d] = i ; + mindeg = CS_MIN (mindeg, d) ; /* find new minimum degree */ + degree [i] = d ; + Ci [p++] = i ; /* place i in Lk */ + } + nv [k] = nvk ; /* # nodes absorbed into k */ + if ((len [k] = p-pk1) == 0) /* length of adj list of element k*/ + { + Cp [k] = -1 ; /* k is a root of the tree */ + w [k] = 0 ; /* k is now a dead element */ + } + if (elenk != 0) cnz = p ; /* free unused space in Lk */ + } + /* --- Postordering ----------------------------------------------------- */ + for (i = 0 ; i < n ; i++) Cp [i] = CS_FLIP (Cp [i]) ;/* fix assembly tree */ + for (j = 0 ; j <= n ; j++) head [j] = -1 ; + for (j = n ; j >= 0 ; j--) /* place unordered nodes in lists */ + { + if (nv [j] > 0) continue ; /* skip if j is an element */ + next [j] = head [Cp [j]] ; /* place j in list of its parent */ + head [Cp [j]] = j ; + } + for (e = n ; e >= 0 ; e--) /* place elements in lists */ + { + if (nv [e] <= 0) continue ; /* skip unless e is an element */ + if (Cp [e] != -1) + { + next [e] = head [Cp [e]] ; /* place e in list of its parent */ + head [Cp [e]] = e ; + } + } + for (k = 0, i = 0 ; i <= n ; i++) /* postorder the assembly tree */ + { + if (Cp [i] == -1) k = cs_tdfs (i, k, head, next, P, w) ; + } + return (cs_idone (P, C, W, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_chol.c b/OpenDSSC/klusolve/CSparse/Source/cs_chol.c new file mode 100644 index 0000000..eb1cf17 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_chol.c @@ -0,0 +1,58 @@ +#include "cs.h" +/* L = chol (A, [pinv parent cp]), pinv is optional */ +csn *cs_chol (const cs *A, const css *S) +{ + double d, lki, *Lx, *x, *Cx ; + int top, i, p, k, n, *Li, *Lp, *cp, *pinv, *s, *c, *parent, *Cp, *Ci ; + cs *L, *C, *E ; + csn *N ; + if (!CS_CSC (A) || !S || !S->cp || !S->parent) return (NULL) ; + n = A->n ; + N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ + c = cs_malloc (2*n, sizeof (int)) ; /* get int workspace */ + x = cs_malloc (n, sizeof (double)) ; /* get double workspace */ + cp = S->cp ; pinv = S->pinv ; parent = S->parent ; + C = pinv ? cs_symperm (A, pinv, 1) : ((cs *) A) ; + E = pinv ? C : NULL ; /* E is alias for A, or a copy E=A(p,p) */ + if (!N || !c || !x || !C) return (cs_ndone (N, E, c, x, 0)) ; + s = c + n ; + Cp = C->p ; Ci = C->i ; Cx = C->x ; + N->L = L = cs_spalloc (n, n, cp [n], 1, 0) ; /* allocate result */ + if (!L) return (cs_ndone (N, E, c, x, 0)) ; + Lp = L->p ; Li = L->i ; Lx = L->x ; + for (k = 0 ; k < n ; k++) Lp [k] = c [k] = cp [k] ; + for (k = 0 ; k < n ; k++) /* compute L(k,:) for L*L' = C */ + { + /* --- Nonzero pattern of L(k,:) ------------------------------------ */ + top = cs_ereach (C, k, parent, s, c) ; /* find pattern of L(k,:) */ + x [k] = 0 ; /* x (0:k) is now zero */ + for (p = Cp [k] ; p < Cp [k+1] ; p++) /* x = full(triu(C(:,k))) */ + { + if (Ci [p] <= k) x [Ci [p]] = Cx [p] ; + } + d = x [k] ; /* d = C(k,k) */ + x [k] = 0 ; /* clear x for k+1st iteration */ + /* --- Triangular solve --------------------------------------------- */ + for ( ; top < n ; top++) /* solve L(0:k-1,0:k-1) * x = C(:,k) */ + { + i = s [top] ; /* s [top..n-1] is pattern of L(k,:) */ + lki = x [i] / Lx [Lp [i]] ; /* L(k,i) = x (i) / L(i,i) */ + x [i] = 0 ; /* clear x for k+1st iteration */ + for (p = Lp [i] + 1 ; p < c [i] ; p++) + { + x [Li [p]] -= Lx [p] * lki ; + } + d -= lki * lki ; /* d = d - L(k,i)*L(k,i) */ + p = c [i]++ ; + Li [p] = k ; /* store L(k,i) in column i */ + Lx [p] = lki ; + } + /* --- Compute L(k,k) ----------------------------------------------- */ + if (d <= 0) return (cs_ndone (N, E, c, x, 0)) ; /* not pos def */ + p = c [k]++ ; + Li [p] = k ; /* store L(k,k) = sqrt (d) in column k */ + Lx [p] = sqrt (d) ; + } + Lp [n] = cp [n] ; /* finalize L */ + return (cs_ndone (N, E, c, x, 1)) ; /* success: free E,s,x; return N */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_cholsol.c b/OpenDSSC/klusolve/CSparse/Source/cs_cholsol.c new file mode 100644 index 0000000..07df51b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_cholsol.c @@ -0,0 +1,26 @@ +#include "cs.h" +/* x=A\b where A is symmetric positive definite; b overwritten with solution */ +int cs_cholsol (int order, const cs *A, double *b) +{ + double *x ; + css *S ; + csn *N ; + int n, ok ; + if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ + n = A->n ; + S = cs_schol (order, A) ; /* ordering and symbolic analysis */ + N = cs_chol (A, S) ; /* numeric Cholesky factorization */ + x = cs_malloc (n, sizeof (double)) ; /* get workspace */ + ok = (S && N && x) ; + if (ok) + { + cs_ipvec (S->pinv, b, x, n) ; /* x = P*b */ + cs_lsolve (N->L, x) ; /* x = L\x */ + cs_ltsolve (N->L, x) ; /* x = L'\x */ + cs_pvec (S->pinv, x, b, n) ; /* b = P'*x */ + } + cs_free (x) ; + cs_sfree (S) ; + cs_nfree (N) ; + return (ok) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_compress.c b/OpenDSSC/klusolve/CSparse/Source/cs_compress.c new file mode 100644 index 0000000..959e12a --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_compress.c @@ -0,0 +1,22 @@ +#include "cs.h" +/* C = compressed-column form of a triplet matrix T */ +cs *cs_compress (const cs *T) +{ + int m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj ; + double *Cx, *Tx ; + cs *C ; + if (!CS_TRIPLET (T)) return (NULL) ; /* check inputs */ + m = T->m ; n = T->n ; Ti = T->i ; Tj = T->p ; Tx = T->x ; nz = T->nz ; + C = cs_spalloc (m, n, nz, Tx != NULL, 0) ; /* allocate result */ + w = cs_calloc (n, sizeof (int)) ; /* get workspace */ + if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ + Cp = C->p ; Ci = C->i ; Cx = C->x ; + for (k = 0 ; k < nz ; k++) w [Tj [k]]++ ; /* column counts */ + cs_cumsum (Cp, w, n) ; /* column pointers */ + for (k = 0 ; k < nz ; k++) + { + Ci [p = w [Tj [k]]++] = Ti [k] ; /* A(i,j) is the pth entry in C */ + if (Cx) Cx [p] = Tx [k] ; + } + return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_counts.c b/OpenDSSC/klusolve/CSparse/Source/cs_counts.c new file mode 100644 index 0000000..f856861 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_counts.c @@ -0,0 +1,61 @@ +#include "cs.h" +/* column counts of LL'=A or LL'=A'A, given parent & post ordering */ +#define HEAD(k,j) (ata ? head [k] : j) +#define NEXT(J) (ata ? next [J] : -1) +static void init_ata (cs *AT, const int *post, int *w, int **head, int **next) +{ + int i, k, p, m = AT->n, n = AT->m, *ATp = AT->p, *ATi = AT->i ; + *head = w+4*n, *next = w+5*n+1 ; + for (k = 0 ; k < n ; k++) w [post [k]] = k ; /* invert post */ + for (i = 0 ; i < m ; i++) + { + for (k = n, p = ATp[i] ; p < ATp[i+1] ; p++) k = CS_MIN (k, w [ATi[p]]); + (*next) [i] = (*head) [k] ; /* place row i in linked list k */ + (*head) [k] = i ; + } +} +int *cs_counts (const cs *A, const int *parent, const int *post, int ata) +{ + int i, j, k, n, m, J, s, p, q, jleaf, *ATp, *ATi, *maxfirst, *prevleaf, + *ancestor, *head = NULL, *next = NULL, *colcount, *w, *first, *delta ; + cs *AT ; + if (!CS_CSC (A) || !parent || !post) return (NULL) ; /* check inputs */ + m = A->m ; n = A->n ; + s = 4*n + (ata ? (n+m+1) : 0) ; + delta = colcount = cs_malloc (n, sizeof (int)) ; /* allocate result */ + w = cs_malloc (s, sizeof (int)) ; /* get workspace */ + AT = cs_transpose (A, 0) ; /* AT = A' */ + if (!AT || !colcount || !w) return (cs_idone (colcount, AT, w, 0)) ; + ancestor = w ; maxfirst = w+n ; prevleaf = w+2*n ; first = w+3*n ; + for (k = 0 ; k < s ; k++) w [k] = -1 ; /* clear workspace w [0..s-1] */ + for (k = 0 ; k < n ; k++) /* find first [j] */ + { + j = post [k] ; + delta [j] = (first [j] == -1) ? 1 : 0 ; /* delta[j]=1 if j is a leaf */ + for ( ; j != -1 && first [j] == -1 ; j = parent [j]) first [j] = k ; + } + ATp = AT->p ; ATi = AT->i ; + if (ata) init_ata (AT, post, w, &head, &next) ; + for (i = 0 ; i < n ; i++) ancestor [i] = i ; /* each node in its own set */ + for (k = 0 ; k < n ; k++) + { + j = post [k] ; /* j is the kth node in postordered etree */ + if (parent [j] != -1) delta [parent [j]]-- ; /* j is not a root */ + for (J = HEAD (k,j) ; J != -1 ; J = NEXT (J)) /* J=j for LL'=A case */ + { + for (p = ATp [J] ; p < ATp [J+1] ; p++) + { + i = ATi [p] ; + q = cs_leaf (i, j, first, maxfirst, prevleaf, ancestor, &jleaf); + if (jleaf >= 1) delta [j]++ ; /* A(i,j) is in skeleton */ + if (jleaf == 2) delta [q]-- ; /* account for overlap in q */ + } + } + if (parent [j] != -1) ancestor [j] = parent [j] ; + } + for (j = 0 ; j < n ; j++) /* sum up delta's of each child */ + { + if (parent [j] != -1) colcount [parent [j]] += colcount [j] ; + } + return (cs_idone (colcount, AT, w, 1)) ; /* success: free workspace */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_cumsum.c b/OpenDSSC/klusolve/CSparse/Source/cs_cumsum.c new file mode 100644 index 0000000..00a2a6b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_cumsum.c @@ -0,0 +1,17 @@ +#include "cs.h" +/* p [0..n] = cumulative sum of c [0..n-1], and then copy p [0..n-1] into c */ +double cs_cumsum (int *p, int *c, int n) +{ + int i, nz = 0 ; + double nz2 = 0 ; + if (!p || !c) return (-1) ; /* check inputs */ + for (i = 0 ; i < n ; i++) + { + p [i] = nz ; + nz += c [i] ; + nz2 += c [i] ; /* also in double to avoid int overflow */ + c [i] = p [i] ; /* also copy p[0..n-1] back into c[0..n-1]*/ + } + p [n] = nz ; + return (nz2) ; /* return sum (c [0..n-1]) */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_dfs.c b/OpenDSSC/klusolve/CSparse/Source/cs_dfs.c new file mode 100644 index 0000000..71aad09 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_dfs.c @@ -0,0 +1,36 @@ +#include "cs.h" +/* depth-first-search of the graph of a matrix, starting at node j */ +int cs_dfs (int j, cs *G, int top, int *xi, int *pstack, const int *pinv) +{ + int i, p, p2, done, jnew, head = 0, *Gp, *Gi ; + if (!CS_CSC (G) || !xi || !pstack) return (-1) ; /* check inputs */ + Gp = G->p ; Gi = G->i ; + xi [0] = j ; /* initialize the recursion stack */ + while (head >= 0) + { + j = xi [head] ; /* get j from the top of the recursion stack */ + jnew = pinv ? (pinv [j]) : j ; + if (!CS_MARKED (Gp, j)) + { + CS_MARK (Gp, j) ; /* mark node j as visited */ + pstack [head] = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew]) ; + } + done = 1 ; /* node j done if no unvisited neighbors */ + p2 = (jnew < 0) ? 0 : CS_UNFLIP (Gp [jnew+1]) ; + for (p = pstack [head] ; p < p2 ; p++) /* examine all neighbors of j */ + { + i = Gi [p] ; /* consider neighbor node i */ + if (CS_MARKED (Gp, i)) continue ; /* skip visited node i */ + pstack [head] = p ; /* pause depth-first search of node j */ + xi [++head] = i ; /* start dfs at node i */ + done = 0 ; /* node j is not done */ + break ; /* break, to start dfs (i) */ + } + if (done) /* depth-first search at node j is done */ + { + head-- ; /* remove j from the recursion stack */ + xi [--top] = j ; /* and place in the output stack */ + } + } + return (top) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_dmperm.c b/OpenDSSC/klusolve/CSparse/Source/cs_dmperm.c new file mode 100644 index 0000000..6243220 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_dmperm.c @@ -0,0 +1,144 @@ +#include "cs.h" +/* breadth-first search for coarse decomposition (C0,C1,R1 or R0,R3,C3) */ +static int cs_bfs (const cs *A, int n, int *wi, int *wj, int *queue, + const int *imatch, const int *jmatch, int mark) +{ + int *Ap, *Ai, head = 0, tail = 0, j, i, p, j2 ; + cs *C ; + for (j = 0 ; j < n ; j++) /* place all unmatched nodes in queue */ + { + if (imatch [j] >= 0) continue ; /* skip j if matched */ + wj [j] = 0 ; /* j in set C0 (R0 if transpose) */ + queue [tail++] = j ; /* place unmatched col j in queue */ + } + if (tail == 0) return (1) ; /* quick return if no unmatched nodes */ + C = (mark == 1) ? ((cs *) A) : cs_transpose (A, 0) ; + if (!C) return (0) ; /* bfs of C=A' to find R3,C3 from R0 */ + Ap = C->p ; Ai = C->i ; + while (head < tail) /* while queue is not empty */ + { + j = queue [head++] ; /* get the head of the queue */ + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + if (wi [i] >= 0) continue ; /* skip if i is marked */ + wi [i] = mark ; /* i in set R1 (C3 if transpose) */ + j2 = jmatch [i] ; /* traverse alternating path to j2 */ + if (wj [j2] >= 0) continue ;/* skip j2 if it is marked */ + wj [j2] = mark ; /* j2 in set C1 (R3 if transpose) */ + queue [tail++] = j2 ; /* add j2 to queue */ + } + } + if (mark != 1) cs_spfree (C) ; /* free A' if it was created */ + return (1) ; +} + +/* collect matched rows and columns into p and q */ +static void cs_matched (int n, const int *wj, const int *imatch, int *p, int *q, + int *cc, int *rr, int set, int mark) +{ + int kc = cc [set], j ; + int kr = rr [set-1] ; + for (j = 0 ; j < n ; j++) + { + if (wj [j] != mark) continue ; /* skip if j is not in C set */ + p [kr++] = imatch [j] ; + q [kc++] = j ; + } + cc [set+1] = kc ; + rr [set] = kr ; +} + +/* collect unmatched rows into the permutation vector p */ +static void cs_unmatched (int m, const int *wi, int *p, int *rr, int set) +{ + int i, kr = rr [set] ; + for (i = 0 ; i < m ; i++) if (wi [i] == 0) p [kr++] = i ; + rr [set+1] = kr ; +} + +/* return 1 if row i is in R2 */ +static int cs_rprune (int i, int j, double aij, void *other) +{ + int *rr = (int *) other ; + return (i >= rr [1] && i < rr [2]) ; +} + +/* Given A, compute coarse and then fine dmperm */ +csd *cs_dmperm (const cs *A, int seed) +{ + int m, n, i, j, k, cnz, nc, *jmatch, *imatch, *wi, *wj, *pinv, *Cp, *Ci, + *ps, *rs, nb1, nb2, *p, *q, *cc, *rr, *r, *s, ok ; + cs *C ; + csd *D, *scc ; + /* --- Maximum matching ------------------------------------------------- */ + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + m = A->m ; n = A->n ; + D = cs_dalloc (m, n) ; /* allocate result */ + if (!D) return (NULL) ; + p = D->p ; q = D->q ; r = D->r ; s = D->s ; cc = D->cc ; rr = D->rr ; + jmatch = cs_maxtrans (A, seed) ; /* max transversal */ + imatch = jmatch + m ; /* imatch = inverse of jmatch */ + if (!jmatch) return (cs_ddone (D, NULL, jmatch, 0)) ; + /* --- Coarse decomposition --------------------------------------------- */ + wi = r ; wj = s ; /* use r and s as workspace */ + for (j = 0 ; j < n ; j++) wj [j] = -1 ; /* unmark all cols for bfs */ + for (i = 0 ; i < m ; i++) wi [i] = -1 ; /* unmark all rows for bfs */ + cs_bfs (A, n, wi, wj, q, imatch, jmatch, 1) ; /* find C1, R1 from C0*/ + ok = cs_bfs (A, m, wj, wi, p, jmatch, imatch, 3) ; /* find R3, C3 from R0*/ + if (!ok) return (cs_ddone (D, NULL, jmatch, 0)) ; + cs_unmatched (n, wj, q, cc, 0) ; /* unmatched set C0 */ + cs_matched (n, wj, imatch, p, q, cc, rr, 1, 1) ; /* set R1 and C1 */ + cs_matched (n, wj, imatch, p, q, cc, rr, 2, -1) ; /* set R2 and C2 */ + cs_matched (n, wj, imatch, p, q, cc, rr, 3, 3) ; /* set R3 and C3 */ + cs_unmatched (m, wi, p, rr, 3) ; /* unmatched set R0 */ + cs_free (jmatch) ; + /* --- Fine decomposition ----------------------------------------------- */ + pinv = cs_pinv (p, m) ; /* pinv=p' */ + if (!pinv) return (cs_ddone (D, NULL, NULL, 0)) ; + C = cs_permute (A, pinv, q, 0) ;/* C=A(p,q) (it will hold A(R2,C2)) */ + cs_free (pinv) ; + if (!C) return (cs_ddone (D, NULL, NULL, 0)) ; + Cp = C->p ; + nc = cc [3] - cc [2] ; /* delete cols C0, C1, and C3 from C */ + if (cc [2] > 0) for (j = cc [2] ; j <= cc [3] ; j++) Cp [j-cc[2]] = Cp [j] ; + C->n = nc ; + if (rr [2] - rr [1] < m) /* delete rows R0, R1, and R3 from C */ + { + cs_fkeep (C, cs_rprune, rr) ; + cnz = Cp [nc] ; + Ci = C->i ; + if (rr [1] > 0) for (k = 0 ; k < cnz ; k++) Ci [k] -= rr [1] ; + } + C->m = nc ; + scc = cs_scc (C) ; /* find strongly connected components of C*/ + if (!scc) return (cs_ddone (D, C, NULL, 0)) ; + /* --- Combine coarse and fine decompositions --------------------------- */ + ps = scc->p ; /* C(ps,ps) is the permuted matrix */ + rs = scc->r ; /* kth block is rs[k]..rs[k+1]-1 */ + nb1 = scc->nb ; /* # of blocks of A(R2,C2) */ + for (k = 0 ; k < nc ; k++) wj [k] = q [ps [k] + cc [2]] ; + for (k = 0 ; k < nc ; k++) q [k + cc [2]] = wj [k] ; + for (k = 0 ; k < nc ; k++) wi [k] = p [ps [k] + rr [1]] ; + for (k = 0 ; k < nc ; k++) p [k + rr [1]] = wi [k] ; + nb2 = 0 ; /* create the fine block partitions */ + r [0] = s [0] = 0 ; + if (cc [2] > 0) nb2++ ; /* leading coarse block A (R1, [C0 C1]) */ + for (k = 0 ; k < nb1 ; k++) /* coarse block A (R2,C2) */ + { + r [nb2] = rs [k] + rr [1] ; /* A (R2,C2) splits into nb1 fine blocks */ + s [nb2] = rs [k] + cc [2] ; + nb2++ ; + } + if (rr [2] < m) + { + r [nb2] = rr [2] ; /* trailing coarse block A ([R3 R0], C3) */ + s [nb2] = cc [3] ; + nb2++ ; + } + r [nb2] = m ; + s [nb2] = n ; + D->nb = nb2 ; + cs_dfree (scc) ; + return (cs_ddone (D, C, NULL, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_droptol.c b/OpenDSSC/klusolve/CSparse/Source/cs_droptol.c new file mode 100644 index 0000000..2afb660 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_droptol.c @@ -0,0 +1,9 @@ +#include "cs.h" +static int cs_tol (int i, int j, double aij, void *tol) +{ + return (fabs (aij) > *((double *) tol)) ; +} +int cs_droptol (cs *A, double tol) +{ + return (cs_fkeep (A, &cs_tol, &tol)) ; /* keep all large entries */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_dropzeros.c b/OpenDSSC/klusolve/CSparse/Source/cs_dropzeros.c new file mode 100644 index 0000000..998ba40 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_dropzeros.c @@ -0,0 +1,9 @@ +#include "cs.h" +static int cs_nonzero (int i, int j, double aij, void *other) +{ + return (aij != 0) ; +} +int cs_dropzeros (cs *A) +{ + return (cs_fkeep (A, &cs_nonzero, NULL)) ; /* keep all nonzero entries */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_dupl.c b/OpenDSSC/klusolve/CSparse/Source/cs_dupl.c new file mode 100644 index 0000000..352706c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_dupl.c @@ -0,0 +1,34 @@ +#include "cs.h" +/* remove duplicate entries from A */ +int cs_dupl (cs *A) +{ + int i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w ; + double *Ax ; + if (!CS_CSC (A)) return (0) ; /* check inputs */ + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + w = cs_malloc (m, sizeof (int)) ; /* get workspace */ + if (!w) return (0) ; /* out of memory */ + for (i = 0 ; i < m ; i++) w [i] = -1 ; /* row i not yet seen */ + for (j = 0 ; j < n ; j++) + { + q = nz ; /* column j will start at q */ + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; /* A(i,j) is nonzero */ + if (w [i] >= q) + { + Ax [w [i]] += Ax [p] ; /* A(i,j) is a duplicate */ + } + else + { + w [i] = nz ; /* record where row i occurs */ + Ai [nz] = i ; /* keep A(i,j) */ + Ax [nz++] = Ax [p] ; + } + } + Ap [j] = q ; /* record start of column j */ + } + Ap [n] = nz ; /* finalize A */ + cs_free (w) ; /* free workspace */ + return (cs_sprealloc (A, 0)) ; /* remove extra space from A */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_entry.c b/OpenDSSC/klusolve/CSparse/Source/cs_entry.c new file mode 100644 index 0000000..cc640e2 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_entry.c @@ -0,0 +1,13 @@ +#include "cs.h" +/* add an entry to a triplet matrix; return 1 if ok, 0 otherwise */ +int cs_entry (cs *T, int i, int j, double x) +{ + if (!CS_TRIPLET (T) || i < 0 || j < 0) return (0) ; /* check inputs */ + if (T->nz >= T->nzmax && !cs_sprealloc (T,2*(T->nzmax))) return (0) ; + if (T->x) T->x [T->nz] = x ; + T->i [T->nz] = i ; + T->p [T->nz++] = j ; + T->m = CS_MAX (T->m, i+1) ; + T->n = CS_MAX (T->n, j+1) ; + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_ereach.c b/OpenDSSC/klusolve/CSparse/Source/cs_ereach.c new file mode 100644 index 0000000..f46828e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_ereach.c @@ -0,0 +1,23 @@ +#include "cs.h" +/* find nonzero pattern of Cholesky L(k,1:k-1) using etree and triu(A(:,k)) */ +int cs_ereach (const cs *A, int k, const int *parent, int *s, int *w) +{ + int i, p, n, len, top, *Ap, *Ai ; + if (!CS_CSC (A) || !parent || !s || !w) return (-1) ; /* check inputs */ + top = n = A->n ; Ap = A->p ; Ai = A->i ; + CS_MARK (w, k) ; /* mark node k as visited */ + for (p = Ap [k] ; p < Ap [k+1] ; p++) + { + i = Ai [p] ; /* A(i,k) is nonzero */ + if (i > k) continue ; /* only use upper triangular part of A */ + for (len = 0 ; !CS_MARKED (w,i) ; i = parent [i]) /* traverse up etree*/ + { + s [len++] = i ; /* L(k,i) is nonzero */ + CS_MARK (w, i) ; /* mark i as visited */ + } + while (len > 0) s [--top] = s [--len] ; /* push path onto stack */ + } + for (p = top ; p < n ; p++) CS_MARK (w, s [p]) ; /* unmark all nodes */ + CS_MARK (w, k) ; /* unmark node k */ + return (top) ; /* s [top..n-1] contains pattern of L(k,:)*/ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_etree.c b/OpenDSSC/klusolve/CSparse/Source/cs_etree.c new file mode 100644 index 0000000..f937644 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_etree.c @@ -0,0 +1,30 @@ +#include "cs.h" +/* compute the etree of A (using triu(A), or A'A without forming A'A */ +int *cs_etree (const cs *A, int ata) +{ + int i, k, p, m, n, inext, *Ap, *Ai, *w, *parent, *ancestor, *prev ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; + parent = cs_malloc (n, sizeof (int)) ; /* allocate result */ + w = cs_malloc (n + (ata ? m : 0), sizeof (int)) ; /* get workspace */ + if (!w || !parent) return (cs_idone (parent, NULL, w, 0)) ; + ancestor = w ; prev = w + n ; + if (ata) for (i = 0 ; i < m ; i++) prev [i] = -1 ; + for (k = 0 ; k < n ; k++) + { + parent [k] = -1 ; /* node k has no parent yet */ + ancestor [k] = -1 ; /* nor does k have an ancestor */ + for (p = Ap [k] ; p < Ap [k+1] ; p++) + { + i = ata ? (prev [Ai [p]]) : (Ai [p]) ; + for ( ; i != -1 && i < k ; i = inext) /* traverse from i to k */ + { + inext = ancestor [i] ; /* inext = ancestor of i */ + ancestor [i] = k ; /* path compression */ + if (inext == -1) parent [i] = k ; /* no anc., parent is k */ + } + if (ata) prev [Ai [p]] = k ; + } + } + return (cs_idone (parent, NULL, w, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_fkeep.c b/OpenDSSC/klusolve/CSparse/Source/cs_fkeep.c new file mode 100644 index 0000000..96f6ec9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_fkeep.c @@ -0,0 +1,25 @@ +#include "cs.h" +/* drop entries for which fkeep(A(i,j)) is false; return nz if OK, else -1 */ +int cs_fkeep (cs *A, int (*fkeep) (int, int, double, void *), void *other) +{ + int j, p, nz = 0, n, *Ap, *Ai ; + double *Ax ; + if (!CS_CSC (A) || !fkeep) return (-1) ; /* check inputs */ + n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + for (j = 0 ; j < n ; j++) + { + p = Ap [j] ; /* get current location of col j */ + Ap [j] = nz ; /* record new location of col j */ + for ( ; p < Ap [j+1] ; p++) + { + if (fkeep (Ai [p], j, Ax ? Ax [p] : 1, other)) + { + if (Ax) Ax [nz] = Ax [p] ; /* keep A(i,j) */ + Ai [nz++] = Ai [p] ; + } + } + } + Ap [n] = nz ; /* finalize A */ + cs_sprealloc (A, 0) ; /* remove extra space from A */ + return (nz) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_gaxpy.c b/OpenDSSC/klusolve/CSparse/Source/cs_gaxpy.c new file mode 100644 index 0000000..e8f65f5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_gaxpy.c @@ -0,0 +1,17 @@ +#include "cs.h" +/* y = A*x+y */ +int cs_gaxpy (const cs *A, const double *x, double *y) +{ + int p, j, n, *Ap, *Ai ; + double *Ax ; + if (!CS_CSC (A) || !x || !y) return (0) ; /* check inputs */ + n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + for (j = 0 ; j < n ; j++) + { + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + y [Ai [p]] += Ax [p] * x [j] ; + } + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_happly.c b/OpenDSSC/klusolve/CSparse/Source/cs_happly.c new file mode 100644 index 0000000..301a2db --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_happly.c @@ -0,0 +1,19 @@ +#include "cs.h" +/* apply the ith Householder vector to x */ +int cs_happly (const cs *V, int i, double beta, double *x) +{ + int p, *Vp, *Vi ; + double *Vx, tau = 0 ; + if (!CS_CSC (V) || !x) return (0) ; /* check inputs */ + Vp = V->p ; Vi = V->i ; Vx = V->x ; + for (p = Vp [i] ; p < Vp [i+1] ; p++) /* tau = v'*x */ + { + tau += Vx [p] * x [Vi [p]] ; + } + tau *= beta ; /* tau = beta*(v'*x) */ + for (p = Vp [i] ; p < Vp [i+1] ; p++) /* x = x - v*tau */ + { + x [Vi [p]] -= Vx [p] * tau ; + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_house.c b/OpenDSSC/klusolve/CSparse/Source/cs_house.c new file mode 100644 index 0000000..ef7f50c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_house.c @@ -0,0 +1,23 @@ +#include "cs.h" +/* create a Householder reflection [v,beta,s]=house(x), overwrite x with v, + * where (I-beta*v*v')*x = s*e1. See Algo 5.1.1, Golub & Van Loan, 3rd ed. */ +double cs_house (double *x, double *beta, int n) +{ + double s, sigma = 0 ; + int i ; + if (!x || !beta) return (-1) ; /* check inputs */ + for (i = 1 ; i < n ; i++) sigma += x [i] * x [i] ; + if (sigma == 0) + { + s = fabs (x [0]) ; /* s = |x(0)| */ + (*beta) = (x [0] <= 0) ? 2 : 0 ; + x [0] = 1 ; + } + else + { + s = sqrt (x [0] * x [0] + sigma) ; /* s = norm (x) */ + x [0] = (x [0] <= 0) ? (x [0] - s) : (-sigma / (x [0] + s)) ; + (*beta) = -1. / (s * x [0]) ; + } + return (s) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_ipvec.c b/OpenDSSC/klusolve/CSparse/Source/cs_ipvec.c new file mode 100644 index 0000000..7daac5b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_ipvec.c @@ -0,0 +1,9 @@ +#include "cs.h" +/* x(p) = b, for dense vectors x and b; p=NULL denotes identity */ +int cs_ipvec (const int *p, const double *b, double *x, int n) +{ + int k ; + if (!x || !b) return (0) ; /* check inputs */ + for (k = 0 ; k < n ; k++) x [p ? p [k] : k] = b [k] ; + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_leaf.c b/OpenDSSC/klusolve/CSparse/Source/cs_leaf.c new file mode 100644 index 0000000..7619762 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_leaf.c @@ -0,0 +1,22 @@ +#include "cs.h" +/* consider A(i,j), node j in ith row subtree and return lca(jprev,j) */ +int cs_leaf (int i, int j, const int *first, int *maxfirst, int *prevleaf, + int *ancestor, int *jleaf) +{ + int q, s, sparent, jprev ; + if (!first || !maxfirst || !prevleaf || !ancestor || !jleaf) return (-1) ; + *jleaf = 0 ; + if (i <= j || first [j] <= maxfirst [i]) return (-1) ; /* j not a leaf */ + maxfirst [i] = first [j] ; /* update max first[j] seen so far */ + jprev = prevleaf [i] ; /* jprev = previous leaf of ith subtree */ + prevleaf [i] = j ; + *jleaf = (jprev == -1) ? 1: 2 ; /* j is first or subsequent leaf */ + if (*jleaf == 1) return (i) ; /* if 1st leaf, q = root of ith subtree */ + for (q = jprev ; q != ancestor [q] ; q = ancestor [q]) ; + for (s = jprev ; s != q ; s = sparent) + { + sparent = ancestor [s] ; /* path compression */ + ancestor [s] = q ; + } + return (q) ; /* q = least common ancester (jprev,j) */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_load.c b/OpenDSSC/klusolve/CSparse/Source/cs_load.c new file mode 100644 index 0000000..b03cd09 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_load.c @@ -0,0 +1,15 @@ +#include "cs.h" +/* load a triplet matrix from a file */ +cs *cs_load (FILE *f) +{ + int i, j ; + double x ; + cs *T ; + if (!f) return (NULL) ; /* check inputs */ + T = cs_spalloc (0, 0, 1, 1, 1) ; /* allocate result */ + while (fscanf (f, "%d %d %lg\n", &i, &j, &x) == 3) + { + if (!cs_entry (T, i, j, x)) return (cs_spfree (T)) ; + } + return (T) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_lsolve.c b/OpenDSSC/klusolve/CSparse/Source/cs_lsolve.c new file mode 100644 index 0000000..6fa305e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_lsolve.c @@ -0,0 +1,18 @@ +#include "cs.h" +/* solve Lx=b where x and b are dense. x=b on input, solution on output. */ +int cs_lsolve (const cs *L, double *x) +{ + int p, j, n, *Lp, *Li ; + double *Lx ; + if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ + n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; + for (j = 0 ; j < n ; j++) + { + x [j] /= Lx [Lp [j]] ; + for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) + { + x [Li [p]] -= Lx [p] * x [j] ; + } + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_ltsolve.c b/OpenDSSC/klusolve/CSparse/Source/cs_ltsolve.c new file mode 100644 index 0000000..561e82b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_ltsolve.c @@ -0,0 +1,18 @@ +#include "cs.h" +/* solve L'x=b where x and b are dense. x=b on input, solution on output. */ +int cs_ltsolve (const cs *L, double *x) +{ + int p, j, n, *Lp, *Li ; + double *Lx ; + if (!CS_CSC (L) || !x) return (0) ; /* check inputs */ + n = L->n ; Lp = L->p ; Li = L->i ; Lx = L->x ; + for (j = n-1 ; j >= 0 ; j--) + { + for (p = Lp [j]+1 ; p < Lp [j+1] ; p++) + { + x [j] -= Lx [p] * x [Li [p]] ; + } + x [j] /= Lx [Lp [j]] ; + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_lu.c b/OpenDSSC/klusolve/CSparse/Source/cs_lu.c new file mode 100644 index 0000000..4368aa5 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_lu.c @@ -0,0 +1,86 @@ +#include "cs.h" +/* [L,U,pinv]=lu(A, [q lnz unz]). lnz and unz can be guess */ +csn *cs_lu (const cs *A, const css *S, double tol) +{ + cs *L, *U ; + csn *N ; + double pivot, *Lx, *Ux, *x, a, t ; + int *Lp, *Li, *Up, *Ui, *pinv, *xi, *q, n, ipiv, k, top, p, i, col, lnz,unz; + if (!CS_CSC (A) || !S) return (NULL) ; /* check inputs */ + n = A->n ; + q = S->q ; lnz = S->lnz ; unz = S->unz ; + x = cs_malloc (n, sizeof (double)) ; /* get double workspace */ + xi = cs_malloc (2*n, sizeof (int)) ; /* get int workspace */ + N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ + if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ; + N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* allocate result L */ + N->U = U = cs_spalloc (n, n, unz, 1, 0) ; /* allocate result U */ + N->pinv = pinv = cs_malloc (n, sizeof (int)) ; /* allocate result pinv */ + if (!L || !U || !pinv) return (cs_ndone (N, NULL, xi, x, 0)) ; + Lp = L->p ; Up = U->p ; + for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */ + for (i = 0 ; i < n ; i++) pinv [i] = -1 ; /* no rows pivotal yet */ + for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */ + lnz = unz = 0 ; + for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */ + { + /* --- Triangular solve --------------------------------------------- */ + Lp [k] = lnz ; /* L(:,k) starts here */ + Up [k] = unz ; /* U(:,k) starts here */ + if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) || + (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n))) + { + return (cs_ndone (N, NULL, xi, x, 0)) ; + } + Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ; + col = q ? (q [k]) : k ; + top = cs_spsolve (L, A, col, xi, x, pinv, 1) ; /* x = L\A(:,col) */ + /* --- Find pivot --------------------------------------------------- */ + ipiv = -1 ; + a = -1 ; + for (p = top ; p < n ; p++) + { + i = xi [p] ; /* x(i) is nonzero */ + if (pinv [i] < 0) /* row i is not yet pivotal */ + { + if ((t = fabs (x [i])) > a) + { + a = t ; /* largest pivot candidate so far */ + ipiv = i ; + } + } + else /* x(i) is the entry U(pinv[i],k) */ + { + Ui [unz] = pinv [i] ; + Ux [unz++] = x [i] ; + } + } + if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ; + if (pinv [col] < 0 && fabs (x [col]) >= a*tol) ipiv = col ; + /* --- Divide by pivot ---------------------------------------------- */ + pivot = x [ipiv] ; /* the chosen pivot */ + Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */ + Ux [unz++] = pivot ; + pinv [ipiv] = k ; /* ipiv is the kth pivot row */ + Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */ + Lx [lnz++] = 1 ; + for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */ + { + i = xi [p] ; + if (pinv [i] < 0) /* x(i) is an entry in L(:,k) */ + { + Li [lnz] = i ; /* save unpermuted row in L */ + Lx [lnz++] = x [i] / pivot ; /* scale pivot column */ + } + x [i] = 0 ; /* x [0..n-1] = 0 for next k */ + } + } + /* --- Finalize L and U ------------------------------------------------- */ + Lp [n] = lnz ; + Up [n] = unz ; + Li = L->i ; /* fix row indices of L for final pinv */ + for (p = 0 ; p < lnz ; p++) Li [p] = pinv [Li [p]] ; + cs_sprealloc (L, 0) ; /* remove extra space from L and U */ + cs_sprealloc (U, 0) ; + return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_lusol.c b/OpenDSSC/klusolve/CSparse/Source/cs_lusol.c new file mode 100644 index 0000000..46cf013 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_lusol.c @@ -0,0 +1,26 @@ +#include "cs.h" +/* x=A\b where A is unsymmetric; b overwritten with solution */ +int cs_lusol (int order, const cs *A, double *b, double tol) +{ + double *x ; + css *S ; + csn *N ; + int n, ok ; + if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ + n = A->n ; + S = cs_sqr (order, A, 0) ; /* ordering and symbolic analysis */ + N = cs_lu (A, S, tol) ; /* numeric LU factorization */ + x = cs_malloc (n, sizeof (double)) ; /* get workspace */ + ok = (S && N && x) ; + if (ok) + { + cs_ipvec (N->pinv, b, x, n) ; /* x = b(p) */ + cs_lsolve (N->L, x) ; /* x = L\x */ + cs_usolve (N->U, x) ; /* x = U\x */ + cs_ipvec (S->q, x, b, n) ; /* b(q) = x */ + } + cs_free (x) ; + cs_sfree (S) ; + cs_nfree (N) ; + return (ok) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_malloc.c b/OpenDSSC/klusolve/CSparse/Source/cs_malloc.c new file mode 100644 index 0000000..f2e95c0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_malloc.c @@ -0,0 +1,35 @@ +#include "cs.h" +#ifdef MATLAB_MEX_FILE +#define malloc mxMalloc +#define free mxFree +#define realloc mxRealloc +#define calloc mxCalloc +#endif + +/* wrapper for malloc */ +void *cs_malloc (int n, size_t size) +{ + return (malloc (CS_MAX (n,1) * size)) ; +} + +/* wrapper for calloc */ +void *cs_calloc (int n, size_t size) +{ + return (calloc (CS_MAX (n,1), size)) ; +} + +/* wrapper for free */ +void *cs_free (void *p) +{ + if (p) free (p) ; /* free p if it is not already NULL */ + return (NULL) ; /* return NULL to simplify the use of cs_free */ +} + +/* wrapper for realloc */ +void *cs_realloc (void *p, int n, size_t size, int *ok) +{ + void *pnew ; + pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ + *ok = (pnew != NULL) ; /* realloc fails if pnew is NULL */ + return ((*ok) ? pnew : p) ; /* return original p if failure */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_maxtrans.c b/OpenDSSC/klusolve/CSparse/Source/cs_maxtrans.c new file mode 100644 index 0000000..81ed288 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_maxtrans.c @@ -0,0 +1,92 @@ +#include "cs.h" +/* find an augmenting path starting at column k and extend the match if found */ +static void cs_augment (int k, const cs *A, int *jmatch, int *cheap, int *w, + int *js, int *is, int *ps) +{ + int found = 0, p, i = -1, *Ap = A->p, *Ai = A->i, head = 0, j ; + js [0] = k ; /* start with just node k in jstack */ + while (head >= 0) + { + /* --- Start (or continue) depth-first-search at node j ------------- */ + j = js [head] ; /* get j from top of jstack */ + if (w [j] != k) /* 1st time j visited for kth path */ + { + w [j] = k ; /* mark j as visited for kth path */ + for (p = cheap [j] ; p < Ap [j+1] && !found ; p++) + { + i = Ai [p] ; /* try a cheap assignment (i,j) */ + found = (jmatch [i] == -1) ; + } + cheap [j] = p ; /* start here next time j is traversed*/ + if (found) + { + is [head] = i ; /* column j matched with row i */ + break ; /* end of augmenting path */ + } + ps [head] = Ap [j] ; /* no cheap match: start dfs for j */ + } + /* --- Depth-first-search of neighbors of j ------------------------- */ + for (p = ps [head] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; /* consider row i */ + if (w [jmatch [i]] == k) continue ; /* skip jmatch [i] if marked */ + ps [head] = p + 1 ; /* pause dfs of node j */ + is [head] = i ; /* i will be matched with j if found */ + js [++head] = jmatch [i] ; /* start dfs at column jmatch [i] */ + break ; + } + if (p == Ap [j+1]) head-- ; /* node j is done; pop from stack */ + } /* augment the match if path found: */ + if (found) for (p = head ; p >= 0 ; p--) jmatch [is [p]] = js [p] ; +} + +/* find a maximum transveral */ +int *cs_maxtrans (const cs *A, int seed) /*[jmatch [0..m-1]; imatch [0..n-1]]*/ +{ + int i, j, k, n, m, p, n2 = 0, m2 = 0, *Ap, *jimatch, *w, *cheap, *js, *is, + *ps, *Ai, *Cp, *jmatch, *imatch, *q ; + cs *C ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + n = A->n ; m = A->m ; Ap = A->p ; Ai = A->i ; + w = jimatch = cs_calloc (m+n, sizeof (int)) ; /* allocate result */ + if (!jimatch) return (NULL) ; + for (k = 0, j = 0 ; j < n ; j++) /* count nonempty rows and columns */ + { + n2 += (Ap [j] < Ap [j+1]) ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + w [Ai [p]] = 1 ; + k += (j == Ai [p]) ; /* count entries already on diagonal */ + } + } + if (k == CS_MIN (m,n)) /* quick return if diagonal zero-free */ + { + jmatch = jimatch ; imatch = jimatch + m ; + for (i = 0 ; i < k ; i++) jmatch [i] = i ; + for ( ; i < m ; i++) jmatch [i] = -1 ; + for (j = 0 ; j < k ; j++) imatch [j] = j ; + for ( ; j < n ; j++) imatch [j] = -1 ; + return (cs_idone (jimatch, NULL, NULL, 1)) ; + } + for (i = 0 ; i < m ; i++) m2 += w [i] ; + C = (m2 < n2) ? cs_transpose (A,0) : ((cs *) A) ; /* transpose if needed */ + if (!C) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, NULL, 0)) ; + n = C->n ; m = C->m ; Cp = C->p ; + jmatch = (m2 < n2) ? jimatch + n : jimatch ; + imatch = (m2 < n2) ? jimatch : jimatch + m ; + w = cs_malloc (5*n, sizeof (int)) ; /* get workspace */ + if (!w) return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 0)) ; + cheap = w + n ; js = w + 2*n ; is = w + 3*n ; ps = w + 4*n ; + for (j = 0 ; j < n ; j++) cheap [j] = Cp [j] ; /* for cheap assignment */ + for (j = 0 ; j < n ; j++) w [j] = -1 ; /* all columns unflagged */ + for (i = 0 ; i < m ; i++) jmatch [i] = -1 ; /* nothing matched yet */ + q = cs_randperm (n, seed) ; /* q = random permutation */ + for (k = 0 ; k < n ; k++) /* augment, starting at column q[k] */ + { + cs_augment (q ? q [k]: k, C, jmatch, cheap, w, js, is, ps) ; + } + cs_free (q) ; + for (j = 0 ; j < n ; j++) imatch [j] = -1 ; /* find row match */ + for (i = 0 ; i < m ; i++) if (jmatch [i] >= 0) imatch [jmatch [i]] = i ; + return (cs_idone (jimatch, (m2 < n2) ? C : NULL, w, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_multiply.c b/OpenDSSC/klusolve/CSparse/Source/cs_multiply.c new file mode 100644 index 0000000..373bd1e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_multiply.c @@ -0,0 +1,35 @@ +#include "cs.h" +/* C = A*B */ +cs *cs_multiply (const cs *A, const cs *B) +{ + int p, j, nz = 0, anz, *Cp, *Ci, *Bp, m, n, bnz, *w, values, *Bi ; + double *x, *Bx, *Cx ; + cs *C ; + if (!CS_CSC (A) || !CS_CSC (B)) return (NULL) ; /* check inputs */ + if (A->n != B->m) return (NULL) ; + m = A->m ; anz = A->p [A->n] ; + n = B->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; bnz = Bp [n] ; + w = cs_calloc (m, sizeof (int)) ; /* get workspace */ + values = (A->x != NULL) && (Bx != NULL) ; + x = values ? cs_malloc (m, sizeof (double)) : NULL ; /* get workspace */ + C = cs_spalloc (m, n, anz + bnz, values, 0) ; /* allocate result */ + if (!C || !w || (values && !x)) return (cs_done (C, w, x, 0)) ; + Cp = C->p ; + for (j = 0 ; j < n ; j++) + { + if (nz + m > C->nzmax && !cs_sprealloc (C, 2*(C->nzmax)+m)) + { + return (cs_done (C, w, x, 0)) ; /* out of memory */ + } + Ci = C->i ; Cx = C->x ; /* C->i and C->x may be reallocated */ + Cp [j] = nz ; /* column j of C starts here */ + for (p = Bp [j] ; p < Bp [j+1] ; p++) + { + nz = cs_scatter (A, Bi [p], Bx ? Bx [p] : 1, w, x, j+1, C, nz) ; + } + if (values) for (p = Cp [j] ; p < nz ; p++) Cx [p] = x [Ci [p]] ; + } + Cp [n] = nz ; /* finalize the last column of C */ + cs_sprealloc (C, 0) ; /* remove extra space from C */ + return (cs_done (C, w, x, 1)) ; /* success; free workspace, return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_norm.c b/OpenDSSC/klusolve/CSparse/Source/cs_norm.c new file mode 100644 index 0000000..8cf75be --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_norm.c @@ -0,0 +1,15 @@ +#include "cs.h" +/* 1-norm of a sparse matrix = max (sum (abs (A))), largest column sum */ +double cs_norm (const cs *A) +{ + int p, j, n, *Ap ; + double *Ax, norm = 0, s ; + if (!CS_CSC (A) || !A->x) return (-1) ; /* check inputs */ + n = A->n ; Ap = A->p ; Ax = A->x ; + for (j = 0 ; j < n ; j++) + { + for (s = 0, p = Ap [j] ; p < Ap [j+1] ; p++) s += fabs (Ax [p]) ; + norm = CS_MAX (norm, s) ; + } + return (norm) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_permute.c b/OpenDSSC/klusolve/CSparse/Source/cs_permute.c new file mode 100644 index 0000000..432bac0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_permute.c @@ -0,0 +1,25 @@ +#include "cs.h" +/* C = A(p,q) where p and q are permutations of 0..m-1 and 0..n-1. */ +cs *cs_permute (const cs *A, const int *pinv, const int *q, int values) +{ + int t, j, k, nz = 0, m, n, *Ap, *Ai, *Cp, *Ci ; + double *Cx, *Ax ; + cs *C ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + C = cs_spalloc (m, n, Ap [n], values && Ax != NULL, 0) ; /* alloc result */ + if (!C) return (cs_done (C, NULL, NULL, 0)) ; /* out of memory */ + Cp = C->p ; Ci = C->i ; Cx = C->x ; + for (k = 0 ; k < n ; k++) + { + Cp [k] = nz ; /* column k of C is column q[k] of A */ + j = q ? (q [k]) : k ; + for (t = Ap [j] ; t < Ap [j+1] ; t++) + { + if (Cx) Cx [nz] = Ax [t] ; /* row i of A is row pinv[i] of C */ + Ci [nz++] = pinv ? (pinv [Ai [t]]) : Ai [t] ; + } + } + Cp [n] = nz ; /* finalize the last column of C */ + return (cs_done (C, NULL, NULL, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_pinv.c b/OpenDSSC/klusolve/CSparse/Source/cs_pinv.c new file mode 100644 index 0000000..5142e67 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_pinv.c @@ -0,0 +1,11 @@ +#include "cs.h" +/* pinv = p', or p = pinv' */ +int *cs_pinv (int const *p, int n) +{ + int k, *pinv ; + if (!p) return (NULL) ; /* p = NULL denotes identity */ + pinv = cs_malloc (n, sizeof (int)) ; /* allocate result */ + if (!pinv) return (NULL) ; /* out of memory */ + for (k = 0 ; k < n ; k++) pinv [p [k]] = k ;/* invert the permutation */ + return (pinv) ; /* return result */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_post.c b/OpenDSSC/klusolve/CSparse/Source/cs_post.c new file mode 100644 index 0000000..c1d03cf --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_post.c @@ -0,0 +1,24 @@ +#include "cs.h" +/* post order a forest */ +int *cs_post (const int *parent, int n) +{ + int j, k = 0, *post, *w, *head, *next, *stack ; + if (!parent) return (NULL) ; /* check inputs */ + post = cs_malloc (n, sizeof (int)) ; /* allocate result */ + w = cs_malloc (3*n, sizeof (int)) ; /* get workspace */ + if (!w || !post) return (cs_idone (post, NULL, w, 0)) ; + head = w ; next = w + n ; stack = w + 2*n ; + for (j = 0 ; j < n ; j++) head [j] = -1 ; /* empty linked lists */ + for (j = n-1 ; j >= 0 ; j--) /* traverse nodes in reverse order*/ + { + if (parent [j] == -1) continue ; /* j is a root */ + next [j] = head [parent [j]] ; /* add j to list of its parent */ + head [parent [j]] = j ; + } + for (j = 0 ; j < n ; j++) + { + if (parent [j] != -1) continue ; /* skip j if it is not a root */ + k = cs_tdfs (j, k, head, next, post, stack) ; + } + return (cs_idone (post, NULL, w, 1)) ; /* success; free w, return post */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_print.c b/OpenDSSC/klusolve/CSparse/Source/cs_print.c new file mode 100644 index 0000000..2c9873f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_print.c @@ -0,0 +1,36 @@ +#include "cs.h" +/* print a sparse matrix */ +int cs_print (const cs *A, int brief) +{ + int p, j, m, n, nzmax, nz, *Ap, *Ai ; + double *Ax ; + if (!A) { printf ("(null)\n") ; return (0) ; } + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + nzmax = A->nzmax ; nz = A->nz ; + printf ("CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, + CS_SUBSUB, CS_DATE, CS_COPYRIGHT) ; + if (nz < 0) + { + printf ("%d-by-%d, nzmax: %d nnz: %d, 1-norm: %g\n", m, n, nzmax, + Ap [n], cs_norm (A)) ; + for (j = 0 ; j < n ; j++) + { + printf (" col %d : locations %d to %d\n", j, Ap [j], Ap [j+1]-1); + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + printf (" %d : %g\n", Ai [p], Ax ? Ax [p] : 1) ; + if (brief && p > 20) { printf (" ...\n") ; return (1) ; } + } + } + } + else + { + printf ("triplet: %d-by-%d, nzmax: %d nnz: %d\n", m, n, nzmax, nz) ; + for (p = 0 ; p < nz ; p++) + { + printf (" %d %d : %g\n", Ai [p], Ap [p], Ax ? Ax [p] : 1) ; + if (brief && p > 20) { printf (" ...\n") ; return (1) ; } + } + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_pvec.c b/OpenDSSC/klusolve/CSparse/Source/cs_pvec.c new file mode 100644 index 0000000..bf18f2f --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_pvec.c @@ -0,0 +1,9 @@ +#include "cs.h" +/* x = b(p), for dense vectors x and b; p=NULL denotes identity */ +int cs_pvec (const int *p, const double *b, double *x, int n) +{ + int k ; + if (!x || !b) return (0) ; /* check inputs */ + for (k = 0 ; k < n ; k++) x [k] = b [p ? p [k] : k] ; + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_qr.c b/OpenDSSC/klusolve/CSparse/Source/cs_qr.c new file mode 100644 index 0000000..0e5747b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_qr.c @@ -0,0 +1,73 @@ +#include "cs.h" +/* sparse QR factorization [V,beta,pinv,R] = qr (A) */ +csn *cs_qr (const cs *A, const css *S) +{ + double *Rx, *Vx, *Ax, *x, *Beta ; + int i, k, p, m, n, vnz, p1, top, m2, len, col, rnz, *s, *leftmost, *Ap, *Ai, + *parent, *Rp, *Ri, *Vp, *Vi, *w, *pinv, *q ; + cs *R, *V ; + csn *N ; + if (!CS_CSC (A) || !S) return (NULL) ; + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + q = S->q ; parent = S->parent ; pinv = S->pinv ; m2 = S->m2 ; + vnz = S->lnz ; rnz = S->unz ; leftmost = S->leftmost ; + w = cs_malloc (m2+n, sizeof (int)) ; /* get int workspace */ + x = cs_malloc (m2, sizeof (double)) ; /* get double workspace */ + N = cs_calloc (1, sizeof (csn)) ; /* allocate result */ + if (!w || !x || !N) return (cs_ndone (N, NULL, w, x, 0)) ; + s = w + m2 ; /* s is size n */ + for (k = 0 ; k < m2 ; k++) x [k] = 0 ; /* clear workspace x */ + N->L = V = cs_spalloc (m2, n, vnz, 1, 0) ; /* allocate result V */ + N->U = R = cs_spalloc (m2, n, rnz, 1, 0) ; /* allocate result R */ + N->B = Beta = cs_malloc (n, sizeof (double)) ; /* allocate result Beta */ + if (!R || !V || !Beta) return (cs_ndone (N, NULL, w, x, 0)) ; + Rp = R->p ; Ri = R->i ; Rx = R->x ; + Vp = V->p ; Vi = V->i ; Vx = V->x ; + for (i = 0 ; i < m2 ; i++) w [i] = -1 ; /* clear w, to mark nodes */ + rnz = 0 ; vnz = 0 ; + for (k = 0 ; k < n ; k++) /* compute V and R */ + { + Rp [k] = rnz ; /* R(:,k) starts here */ + Vp [k] = p1 = vnz ; /* V(:,k) starts here */ + w [k] = k ; /* add V(k,k) to pattern of V */ + Vi [vnz++] = k ; + top = n ; + col = q ? q [k] : k ; + for (p = Ap [col] ; p < Ap [col+1] ; p++) /* find R(:,k) pattern */ + { + i = leftmost [Ai [p]] ; /* i = min(find(A(i,q))) */ + for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up to k */ + { + s [len++] = i ; + w [i] = k ; + } + while (len > 0) s [--top] = s [--len] ; /* push path on stack */ + i = pinv [Ai [p]] ; /* i = permuted row of A(:,col) */ + x [i] = Ax [p] ; /* x (i) = A(:,col) */ + if (i > k && w [i] < k) /* pattern of V(:,k) = x (k+1:m) */ + { + Vi [vnz++] = i ; /* add i to pattern of V(:,k) */ + w [i] = k ; + } + } + for (p = top ; p < n ; p++) /* for each i in pattern of R(:,k) */ + { + i = s [p] ; /* R(i,k) is nonzero */ + cs_happly (V, i, Beta [i], x) ; /* apply (V(i),Beta(i)) to x */ + Ri [rnz] = i ; /* R(i,k) = x(i) */ + Rx [rnz++] = x [i] ; + x [i] = 0 ; + if (parent [i] == k) vnz = cs_scatter (V, i, 0, w, NULL, k, V, vnz); + } + for (p = p1 ; p < vnz ; p++) /* gather V(:,k) = x */ + { + Vx [p] = x [Vi [p]] ; + x [Vi [p]] = 0 ; + } + Ri [rnz] = k ; /* R(k,k) = norm (x) */ + Rx [rnz++] = cs_house (Vx+p1, Beta+k, vnz-p1) ; /* [v,beta]=house(x) */ + } + Rp [n] = rnz ; /* finalize R */ + Vp [n] = vnz ; /* finalize V */ + return (cs_ndone (N, NULL, w, x, 1)) ; /* success */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_qrsol.c b/OpenDSSC/klusolve/CSparse/Source/cs_qrsol.c new file mode 100644 index 0000000..b9568fd --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_qrsol.c @@ -0,0 +1,53 @@ +#include "cs.h" +/* x=A\b where A can be rectangular; b overwritten with solution */ +int cs_qrsol (int order, const cs *A, double *b) +{ + double *x ; + css *S ; + csn *N ; + cs *AT = NULL ; + int k, m, n, ok ; + if (!CS_CSC (A) || !b) return (0) ; /* check inputs */ + n = A->n ; + m = A->m ; + if (m >= n) + { + S = cs_sqr (order, A, 1) ; /* ordering and symbolic analysis */ + N = cs_qr (A, S) ; /* numeric QR factorization */ + x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ + ok = (S && N && x) ; + if (ok) + { + cs_ipvec (S->pinv, b, x, m) ; /* x(0:m-1) = b(p(0:m-1) */ + for (k = 0 ; k < n ; k++) /* apply Householder refl. to x */ + { + cs_happly (N->L, k, N->B [k], x) ; + } + cs_usolve (N->U, x) ; /* x = R\x */ + cs_ipvec (S->q, x, b, n) ; /* b(q(0:n-1)) = x(0:n-1) */ + } + } + else + { + AT = cs_transpose (A, 1) ; /* Ax=b is underdetermined */ + S = cs_sqr (order, AT, 1) ; /* ordering and symbolic analysis */ + N = cs_qr (AT, S) ; /* numeric QR factorization of A' */ + x = cs_calloc (S ? S->m2 : 1, sizeof (double)) ; /* get workspace */ + ok = (AT && S && N && x) ; + if (ok) + { + cs_pvec (S->q, b, x, m) ; /* x(q(0:m-1)) = b(0:m-1) */ + cs_utsolve (N->U, x) ; /* x = R'\x */ + for (k = m-1 ; k >= 0 ; k--) /* apply Householder refl. to x */ + { + cs_happly (N->L, k, N->B [k], x) ; + } + cs_pvec (S->pinv, x, b, n) ; /* b(0:n-1) = x(p(0:n-1)) */ + } + } + cs_free (x) ; + cs_sfree (S) ; + cs_nfree (N) ; + cs_spfree (AT) ; + return (ok) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_randperm.c b/OpenDSSC/klusolve/CSparse/Source/cs_randperm.c new file mode 100644 index 0000000..1acfaa2 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_randperm.c @@ -0,0 +1,22 @@ +#include "cs.h" +/* return a random permutation vector, the identity perm, or p = n-1:-1:0. + * seed = -1 means p = n-1:-1:0. seed = 0 means p = identity. otherwise + * p = random permutation. */ +int *cs_randperm (int n, int seed) +{ + int *p, k, j, t ; + if (seed == 0) return (NULL) ; /* return p = NULL (identity) */ + p = cs_malloc (n, sizeof (int)) ; /* allocate result */ + if (!p) return (NULL) ; /* out of memory */ + for (k = 0 ; k < n ; k++) p [k] = n-k-1 ; + if (seed == -1) return (p) ; /* return reverse permutation */ + srand (seed) ; /* get new random number seed */ + for (k = 0 ; k < n ; k++) + { + j = k + (rand ( ) % (n-k)) ; /* j = rand int in range k to n-1 */ + t = p [j] ; /* swap p[k] and p[j] */ + p [j] = p [k] ; + p [k] = t ; + } + return (p) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_reach.c b/OpenDSSC/klusolve/CSparse/Source/cs_reach.c new file mode 100644 index 0000000..a579309 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_reach.c @@ -0,0 +1,19 @@ +#include "cs.h" +/* xi [top...n-1] = nodes reachable from graph of G*P' via nodes in B(:,k). + * xi [n...2n-1] used as workspace */ +int cs_reach (cs *G, const cs *B, int k, int *xi, const int *pinv) +{ + int p, n, top, *Bp, *Bi, *Gp ; + if (!CS_CSC (G) || !CS_CSC (B) || !xi) return (-1) ; /* check inputs */ + n = G->n ; Bp = B->p ; Bi = B->i ; Gp = G->p ; + top = n ; + for (p = Bp [k] ; p < Bp [k+1] ; p++) + { + if (!CS_MARKED (Gp, Bi [p])) /* start a dfs at unmarked node i */ + { + top = cs_dfs (Bi [p], G, top, xi, xi+n, pinv) ; + } + } + for (p = top ; p < n ; p++) CS_MARK (Gp, xi [p]) ; /* restore G */ + return (top) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_scatter.c b/OpenDSSC/klusolve/CSparse/Source/cs_scatter.c new file mode 100644 index 0000000..16f5c0b --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_scatter.c @@ -0,0 +1,22 @@ +#include "cs.h" +/* x = x + beta * A(:,j), where x is a dense vector and A(:,j) is sparse */ +int cs_scatter (const cs *A, int j, double beta, int *w, double *x, int mark, + cs *C, int nz) +{ + int i, p, *Ap, *Ai, *Ci ; + double *Ax ; + if (!CS_CSC (A) || !w || !CS_CSC (C)) return (-1) ; /* check inputs */ + Ap = A->p ; Ai = A->i ; Ax = A->x ; Ci = C->i ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; /* A(i,j) is nonzero */ + if (w [i] < mark) + { + w [i] = mark ; /* i is new entry in column j */ + Ci [nz++] = i ; /* add i to pattern of C(:,j) */ + if (x) x [i] = beta * Ax [p] ; /* x(i) = beta*A(i,j) */ + } + else if (x) x [i] += beta * Ax [p] ; /* i exists in C(:,j) already */ + } + return (nz) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_scc.c b/OpenDSSC/klusolve/CSparse/Source/cs_scc.c new file mode 100644 index 0000000..dd446d0 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_scc.c @@ -0,0 +1,41 @@ +#include "cs.h" +/* find the strongly connected components of a square matrix */ +csd *cs_scc (cs *A) /* matrix A temporarily modified, then restored */ +{ + int n, i, k, b, nb = 0, top, *xi, *pstack, *p, *r, *Ap, *ATp, *rcopy, *Blk ; + cs *AT ; + csd *D ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + n = A->n ; Ap = A->p ; + D = cs_dalloc (n, 0) ; /* allocate result */ + AT = cs_transpose (A, 0) ; /* AT = A' */ + xi = cs_malloc (2*n+1, sizeof (int)) ; /* get workspace */ + if (!D || !AT || !xi) return (cs_ddone (D, AT, xi, 0)) ; + Blk = xi ; rcopy = pstack = xi + n ; + p = D->p ; r = D->r ; ATp = AT->p ; + top = n ; + for (i = 0 ; i < n ; i++) /* first dfs(A) to find finish times (xi) */ + { + if (!CS_MARKED (Ap, i)) top = cs_dfs (i, A, top, xi, pstack, NULL) ; + } + for (i = 0 ; i < n ; i++) CS_MARK (Ap, i) ; /* restore A; unmark all nodes*/ + top = n ; + nb = n ; + for (k = 0 ; k < n ; k++) /* dfs(A') to find strongly connnected comp */ + { + i = xi [k] ; /* get i in reverse order of finish times */ + if (CS_MARKED (ATp, i)) continue ; /* skip node i if already ordered */ + r [nb--] = top ; /* node i is the start of a component in p */ + top = cs_dfs (i, AT, top, p, pstack, NULL) ; + } + r [nb] = 0 ; /* first block starts at zero; shift r up */ + for (k = nb ; k <= n ; k++) r [k-nb] = r [k] ; + D->nb = nb = n-nb ; /* nb = # of strongly connected components */ + for (b = 0 ; b < nb ; b++) /* sort each block in natural order */ + { + for (k = r [b] ; k < r [b+1] ; k++) Blk [p [k]] = b ; + } + for (b = 0 ; b <= nb ; b++) rcopy [b] = r [b] ; + for (i = 0 ; i < n ; i++) p [rcopy [Blk [i]]++] = i ; + return (cs_ddone (D, AT, xi, 1)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_schol.c b/OpenDSSC/klusolve/CSparse/Source/cs_schol.c new file mode 100644 index 0000000..65ed9b1 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_schol.c @@ -0,0 +1,26 @@ +#include "cs.h" +/* ordering and symbolic analysis for a Cholesky factorization */ +css *cs_schol (int order, const cs *A) +{ + int n, *c, *post, *P ; + cs *C ; + css *S ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + n = A->n ; + S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ + if (!S) return (NULL) ; /* out of memory */ + P = cs_amd (order, A) ; /* P = amd(A+A'), or natural */ + S->pinv = cs_pinv (P, n) ; /* find inverse permutation */ + cs_free (P) ; + if (order && !S->pinv) return (cs_sfree (S)) ; + C = cs_symperm (A, S->pinv, 0) ; /* C = spones(triu(A(P,P))) */ + S->parent = cs_etree (C, 0) ; /* find etree of C */ + post = cs_post (S->parent, n) ; /* postorder the etree */ + c = cs_counts (C, S->parent, post, 0) ; /* find column counts of chol(C) */ + cs_free (post) ; + cs_spfree (C) ; + S->cp = cs_malloc (n+1, sizeof (int)) ; /* allocate result S->cp */ + S->unz = S->lnz = cs_cumsum (S->cp, c, n) ; /* find column pointers for L */ + cs_free (c) ; + return ((S->lnz >= 0) ? S : cs_sfree (S)) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_spsolve.c b/OpenDSSC/klusolve/CSparse/Source/cs_spsolve.c new file mode 100644 index 0000000..e8b08ba --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_spsolve.c @@ -0,0 +1,28 @@ +#include "cs.h" +/* solve Gx=b(:,k), where G is either upper (lo=0) or lower (lo=1) triangular */ +int cs_spsolve (cs *G, const cs *B, int k, int *xi, double *x, const int *pinv, + int lo) +{ + int j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ; + double *Gx, *Bx ; + if (!CS_CSC (G) || !CS_CSC (B) || !xi || !x) return (-1) ; + Gp = G->p ; Gi = G->i ; Gx = G->x ; n = G->n ; + Bp = B->p ; Bi = B->i ; Bx = B->x ; + top = cs_reach (G, B, k, xi, pinv) ; /* xi[top..n-1]=Reach(B(:,k)) */ + for (p = top ; p < n ; p++) x [xi [p]] = 0 ; /* clear x */ + for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */ + for (px = top ; px < n ; px++) + { + j = xi [px] ; /* x(j) is nonzero */ + J = pinv ? (pinv [j]) : j ; /* j maps to col J of G */ + if (J < 0) continue ; /* column J is empty */ + x [j] /= Gx [lo ? (Gp [J]) : (Gp [J+1]-1)] ;/* x(j) /= G(j,j) */ + p = lo ? (Gp [J]+1) : (Gp [J]) ; /* lo: L(j,j) 1st entry */ + q = lo ? (Gp [J+1]) : (Gp [J+1]-1) ; /* up: U(j,j) last entry */ + for ( ; p < q ; p++) + { + x [Gi [p]] -= Gx [p] * x [j] ; /* x(i) -= G(i,j) * x(j) */ + } + } + return (top) ; /* return top of stack */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_sqr.c b/OpenDSSC/klusolve/CSparse/Source/cs_sqr.c new file mode 100644 index 0000000..bff358e --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_sqr.c @@ -0,0 +1,88 @@ +#include "cs.h" +/* compute nnz(V) = S->lnz, S->pinv, S->leftmost, S->m2 from A and S->parent */ +static int cs_vcount (const cs *A, css *S) +{ + int i, k, p, pa, n = A->n, m = A->m, *Ap = A->p, *Ai = A->i, *next, *head, + *tail, *nque, *pinv, *leftmost, *w, *parent = S->parent ; + S->pinv = pinv = cs_malloc (m+n, sizeof (int)) ; /* allocate pinv, */ + S->leftmost = leftmost = cs_malloc (m, sizeof (int)) ; /* and leftmost */ + w = cs_malloc (m+3*n, sizeof (int)) ; /* get workspace */ + if (!pinv || !w || !leftmost) + { + cs_free (w) ; /* pinv and leftmost freed later */ + return (0) ; /* out of memory */ + } + next = w ; head = w + m ; tail = w + m + n ; nque = w + m + 2*n ; + for (k = 0 ; k < n ; k++) head [k] = -1 ; /* queue k is empty */ + for (k = 0 ; k < n ; k++) tail [k] = -1 ; + for (k = 0 ; k < n ; k++) nque [k] = 0 ; + for (i = 0 ; i < m ; i++) leftmost [i] = -1 ; + for (k = n-1 ; k >= 0 ; k--) + { + for (p = Ap [k] ; p < Ap [k+1] ; p++) + { + leftmost [Ai [p]] = k ; /* leftmost[i] = min(find(A(i,:)))*/ + } + } + for (i = m-1 ; i >= 0 ; i--) /* scan rows in reverse order */ + { + pinv [i] = -1 ; /* row i is not yet ordered */ + k = leftmost [i] ; + if (k == -1) continue ; /* row i is empty */ + if (nque [k]++ == 0) tail [k] = i ; /* first row in queue k */ + next [i] = head [k] ; /* put i at head of queue k */ + head [k] = i ; + } + S->lnz = 0 ; + S->m2 = m ; + for (k = 0 ; k < n ; k++) /* find row permutation and nnz(V)*/ + { + i = head [k] ; /* remove row i from queue k */ + S->lnz++ ; /* count V(k,k) as nonzero */ + if (i < 0) i = S->m2++ ; /* add a fictitious row */ + pinv [i] = k ; /* associate row i with V(:,k) */ + if (--nque [k] <= 0) continue ; /* skip if V(k+1:m,k) is empty */ + S->lnz += nque [k] ; /* nque [k] is nnz (V(k+1:m,k)) */ + if ((pa = parent [k]) != -1) /* move all rows to parent of k */ + { + if (nque [pa] == 0) tail [pa] = tail [k] ; + next [tail [k]] = head [pa] ; + head [pa] = next [i] ; + nque [pa] += nque [k] ; + } + } + for (i = 0 ; i < m ; i++) if (pinv [i] < 0) pinv [i] = k++ ; + cs_free (w) ; + return (1) ; +} + +/* symbolic ordering and analysis for QR or LU */ +css *cs_sqr (int order, const cs *A, int qr) +{ + int n, k, ok = 1, *post ; + css *S ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + n = A->n ; + S = cs_calloc (1, sizeof (css)) ; /* allocate result S */ + if (!S) return (NULL) ; /* out of memory */ + S->q = cs_amd (order, A) ; /* fill-reducing ordering */ + if (order && !S->q) return (cs_sfree (S)) ; + if (qr) /* QR symbolic analysis */ + { + cs *C = order ? cs_permute (A, NULL, S->q, 0) : ((cs *) A) ; + S->parent = cs_etree (C, 1) ; /* etree of C'*C, where C=A(:,q) */ + post = cs_post (S->parent, n) ; + S->cp = cs_counts (C, S->parent, post, 1) ; /* col counts chol(C'*C) */ + cs_free (post) ; + ok = C && S->parent && S->cp && cs_vcount (C, S) ; + if (ok) for (S->unz = 0, k = 0 ; k < n ; k++) S->unz += S->cp [k] ; + ok = ok && S->lnz >= 0 && S->unz >= 0 ; /* int overflow guard */ + if (order) cs_spfree (C) ; + } + else + { + S->unz = 4*(A->p [n]) + n ; /* for LU factorization only, */ + S->lnz = S->unz ; /* guess nnz(L) and nnz(U) */ + } + return (ok ? S : cs_sfree (S)) ; /* return result S */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_symperm.c b/OpenDSSC/klusolve/CSparse/Source/cs_symperm.c new file mode 100644 index 0000000..0cd0114 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_symperm.c @@ -0,0 +1,39 @@ +#include "cs.h" +/* C = A(p,p) where A and C are symmetric the upper part stored; pinv not p */ +cs *cs_symperm (const cs *A, const int *pinv, int values) +{ + int i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w ; + double *Cx, *Ax ; + cs *C ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + C = cs_spalloc (n, n, Ap [n], values && (Ax != NULL), 0) ; /* alloc result*/ + w = cs_calloc (n, sizeof (int)) ; /* get workspace */ + if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ + Cp = C->p ; Ci = C->i ; Cx = C->x ; + for (j = 0 ; j < n ; j++) /* count entries in each column of C */ + { + j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + if (i > j) continue ; /* skip lower triangular part of A */ + i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ + w [CS_MAX (i2, j2)]++ ; /* column count of C */ + } + } + cs_cumsum (Cp, w, n) ; /* compute column pointers of C */ + for (j = 0 ; j < n ; j++) + { + j2 = pinv ? pinv [j] : j ; /* column j of A is column j2 of C */ + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + if (i > j) continue ; /* skip lower triangular part of A*/ + i2 = pinv ? pinv [i] : i ; /* row i of A is row i2 of C */ + Ci [q = w [CS_MAX (i2, j2)]++] = CS_MIN (i2, j2) ; + if (Cx) Cx [q] = Ax [p] ; + } + } + return (cs_done (C, w, NULL, 1)) ; /* success; free workspace, return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_tdfs.c b/OpenDSSC/klusolve/CSparse/Source/cs_tdfs.c new file mode 100644 index 0000000..16686c9 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_tdfs.c @@ -0,0 +1,24 @@ +#include "cs.h" +/* depth-first search and postorder of a tree rooted at node j */ +int cs_tdfs (int j, int k, int *head, const int *next, int *post, int *stack) +{ + int i, p, top = 0 ; + if (!head || !next || !post || !stack) return (-1) ; /* check inputs */ + stack [0] = j ; /* place j on the stack */ + while (top >= 0) /* while (stack is not empty) */ + { + p = stack [top] ; /* p = top of stack */ + i = head [p] ; /* i = youngest child of p */ + if (i == -1) + { + top-- ; /* p has no unordered children left */ + post [k++] = p ; /* node p is the kth postordered node */ + } + else + { + head [p] = next [i] ; /* remove i from children of p */ + stack [++top] = i ; /* start dfs on child node i */ + } + } + return (k) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_transpose.c b/OpenDSSC/klusolve/CSparse/Source/cs_transpose.c new file mode 100644 index 0000000..2700e68 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_transpose.c @@ -0,0 +1,25 @@ +#include "cs.h" +/* C = A' */ +cs *cs_transpose (const cs *A, int values) +{ + int p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w ; + double *Cx, *Ax ; + cs *C ; + if (!CS_CSC (A)) return (NULL) ; /* check inputs */ + m = A->m ; n = A->n ; Ap = A->p ; Ai = A->i ; Ax = A->x ; + C = cs_spalloc (n, m, Ap [n], values && Ax, 0) ; /* allocate result */ + w = cs_calloc (m, sizeof (int)) ; /* get workspace */ + if (!C || !w) return (cs_done (C, w, NULL, 0)) ; /* out of memory */ + Cp = C->p ; Ci = C->i ; Cx = C->x ; + for (p = 0 ; p < Ap [n] ; p++) w [Ai [p]]++ ; /* row counts */ + cs_cumsum (Cp, w, m) ; /* row pointers */ + for (j = 0 ; j < n ; j++) + { + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + Ci [q = w [Ai [p]]++] = j ; /* place A(i,j) as entry C(j,i) */ + if (Cx) Cx [q] = Ax [p] ; + } + } + return (cs_done (C, w, NULL, 1)) ; /* success; free w and return C */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_updown.c b/OpenDSSC/klusolve/CSparse/Source/cs_updown.c new file mode 100644 index 0000000..556389c --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_updown.c @@ -0,0 +1,37 @@ +#include "cs.h" +/* sparse Cholesky update/downdate, L*L' + sigma*w*w' (sigma = +1 or -1) */ +int cs_updown (cs *L, int sigma, const cs *C, const int *parent) +{ + int n, p, f, j, *Lp, *Li, *Cp, *Ci ; + double *Lx, *Cx, alpha, beta = 1, delta, gamma, w1, w2, *w, beta2 = 1 ; + if (!CS_CSC (L) || !CS_CSC (C) || !parent) return (0) ; /* check inputs */ + Lp = L->p ; Li = L->i ; Lx = L->x ; n = L->n ; + Cp = C->p ; Ci = C->i ; Cx = C->x ; + if ((p = Cp [0]) >= Cp [1]) return (1) ; /* return if C empty */ + w = cs_malloc (n, sizeof (double)) ; /* get workspace */ + if (!w) return (0) ; /* out of memory */ + f = Ci [p] ; + for ( ; p < Cp [1] ; p++) f = CS_MIN (f, Ci [p]) ; /* f = min (find (C)) */ + for (j = f ; j != -1 ; j = parent [j]) w [j] = 0 ; /* clear workspace w */ + for (p = Cp [0] ; p < Cp [1] ; p++) w [Ci [p]] = Cx [p] ; /* w = C */ + for (j = f ; j != -1 ; j = parent [j]) /* walk path f up to root */ + { + p = Lp [j] ; + alpha = w [j] / Lx [p] ; /* alpha = w(j) / L(j,j) */ + beta2 = beta*beta + sigma*alpha*alpha ; + if (beta2 <= 0) break ; /* not positive definite */ + beta2 = sqrt (beta2) ; + delta = (sigma > 0) ? (beta / beta2) : (beta2 / beta) ; + gamma = sigma * alpha / (beta2 * beta) ; + Lx [p] = delta * Lx [p] + ((sigma > 0) ? (gamma * w [j]) : 0) ; + beta = beta2 ; + for (p++ ; p < Lp [j+1] ; p++) + { + w1 = w [Li [p]] ; + w [Li [p]] = w2 = w1 - alpha * Lx [p] ; + Lx [p] = delta * Lx [p] + gamma * ((sigma > 0) ? w1 : w2) ; + } + } + cs_free (w) ; + return (beta2 > 0) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_usolve.c b/OpenDSSC/klusolve/CSparse/Source/cs_usolve.c new file mode 100644 index 0000000..f09e4d4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_usolve.c @@ -0,0 +1,18 @@ +#include "cs.h" +/* solve Ux=b where x and b are dense. x=b on input, solution on output. */ +int cs_usolve (const cs *U, double *x) +{ + int p, j, n, *Up, *Ui ; + double *Ux ; + if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ + n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; + for (j = n-1 ; j >= 0 ; j--) + { + x [j] /= Ux [Up [j+1]-1] ; + for (p = Up [j] ; p < Up [j+1]-1 ; p++) + { + x [Ui [p]] -= Ux [p] * x [j] ; + } + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_util.c b/OpenDSSC/klusolve/CSparse/Source/cs_util.c new file mode 100644 index 0000000..32d9a31 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_util.c @@ -0,0 +1,119 @@ +#include "cs.h" +/* allocate a sparse matrix (triplet form or compressed-column form) */ +cs *cs_spalloc (int m, int n, int nzmax, int values, int triplet) +{ + cs *A = cs_calloc (1, sizeof (cs)) ; /* allocate the cs struct */ + if (!A) return (NULL) ; /* out of memory */ + A->m = m ; /* define dimensions and nzmax */ + A->n = n ; + A->nzmax = nzmax = CS_MAX (nzmax, 1) ; + A->nz = triplet ? 0 : -1 ; /* allocate triplet or comp.col */ + A->p = cs_malloc (triplet ? nzmax : n+1, sizeof (int)) ; + A->i = cs_malloc (nzmax, sizeof (int)) ; + A->x = values ? cs_malloc (nzmax, sizeof (double)) : NULL ; + return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A) ; +} + +/* change the max # of entries sparse matrix */ +int cs_sprealloc (cs *A, int nzmax) +{ + int ok, oki, okj = 1, okx = 1 ; + if (!A) return (0) ; + if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz ; + A->i = cs_realloc (A->i, nzmax, sizeof (int), &oki) ; + if (CS_TRIPLET (A)) A->p = cs_realloc (A->p, nzmax, sizeof (int), &okj) ; + if (A->x) A->x = cs_realloc (A->x, nzmax, sizeof (double), &okx) ; + ok = (oki && okj && okx) ; + if (ok) A->nzmax = nzmax ; + return (ok) ; +} + +/* free a sparse matrix */ +cs *cs_spfree (cs *A) +{ + if (!A) return (NULL) ; /* do nothing if A already NULL */ + cs_free (A->p) ; + cs_free (A->i) ; + cs_free (A->x) ; + return ((cs *) cs_free (A)) ; /* free the cs struct and return NULL */ +} + +/* free a numeric factorization */ +csn *cs_nfree (csn *N) +{ + if (!N) return (NULL) ; /* do nothing if N already NULL */ + cs_spfree (N->L) ; + cs_spfree (N->U) ; + cs_free (N->pinv) ; + cs_free (N->B) ; + return ((csn *) cs_free (N)) ; /* free the csn struct and return NULL */ +} + +/* free a symbolic factorization */ +css *cs_sfree (css *S) +{ + if (!S) return (NULL) ; /* do nothing if S already NULL */ + cs_free (S->pinv) ; + cs_free (S->q) ; + cs_free (S->parent) ; + cs_free (S->cp) ; + cs_free (S->leftmost) ; + return ((css *) cs_free (S)) ; /* free the css struct and return NULL */ +} + +/* allocate a cs_dmperm or cs_scc result */ +csd *cs_dalloc (int m, int n) +{ + csd *D ; + D = cs_calloc (1, sizeof (csd)) ; + if (!D) return (NULL) ; + D->p = cs_malloc (m, sizeof (int)) ; + D->r = cs_malloc (m+6, sizeof (int)) ; + D->q = cs_malloc (n, sizeof (int)) ; + D->s = cs_malloc (n+6, sizeof (int)) ; + return ((!D->p || !D->r || !D->q || !D->s) ? cs_dfree (D) : D) ; +} + +/* free a cs_dmperm or cs_scc result */ +csd *cs_dfree (csd *D) +{ + if (!D) return (NULL) ; /* do nothing if D already NULL */ + cs_free (D->p) ; + cs_free (D->q) ; + cs_free (D->r) ; + cs_free (D->s) ; + return ((csd *) cs_free (D)) ; /* free the csd struct and return NULL */ +} + +/* free workspace and return a sparse matrix result */ +cs *cs_done (cs *C, void *w, void *x, int ok) +{ + cs_free (w) ; /* free workspace */ + cs_free (x) ; + return (ok ? C : cs_spfree (C)) ; /* return result if OK, else free it */ +} + +/* free workspace and return int array result */ +int *cs_idone (int *p, cs *C, void *w, int ok) +{ + cs_spfree (C) ; /* free temporary matrix */ + cs_free (w) ; /* free workspace */ + return (ok ? p : (int *) cs_free (p)) ; /* return result, or free it */ +} + +/* free workspace and return a numeric factorization (Cholesky, LU, or QR) */ +csn *cs_ndone (csn *N, cs *C, void *w, void *x, int ok) +{ + cs_spfree (C) ; /* free temporary matrix */ + cs_free (w) ; /* free workspace */ + cs_free (x) ; + return (ok ? N : cs_nfree (N)) ; /* return result if OK, else free it */ +} + +/* free workspace and return a csd result */ +csd *cs_ddone (csd *D, cs *C, void *w, int ok) +{ + cs_spfree (C) ; /* free temporary matrix */ + cs_free (w) ; /* free workspace */ + return (ok ? D : cs_dfree (D)) ; /* return result if OK, else free it */ +} diff --git a/OpenDSSC/klusolve/CSparse/Source/cs_utsolve.c b/OpenDSSC/klusolve/CSparse/Source/cs_utsolve.c new file mode 100644 index 0000000..c725eec --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Source/cs_utsolve.c @@ -0,0 +1,18 @@ +#include "cs.h" +/* solve U'x=b where x and b are dense. x=b on input, solution on output. */ +int cs_utsolve (const cs *U, double *x) +{ + int p, j, n, *Up, *Ui ; + double *Ux ; + if (!CS_CSC (U) || !x) return (0) ; /* check inputs */ + n = U->n ; Up = U->p ; Ui = U->i ; Ux = U->x ; + for (j = 0 ; j < n ; j++) + { + for (p = Up [j] ; p < Up [j+1]-1 ; p++) + { + x [j] -= Ux [p] * x [Ui [p]] ; + } + x [j] /= Ux [Up [j+1]-1] ; + } + return (1) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Tcov/Makefile b/OpenDSSC/klusolve/CSparse/Tcov/Makefile new file mode 100644 index 0000000..3998b61 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/Makefile @@ -0,0 +1,103 @@ +# To run with valgrind: +V = +# V = valgrind -q + +# Linux test coverage +CC = gcc +CFLAGS = -O -g -fprofile-arcs -ftest-coverage \ + -Wall -W -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ + -Wredundant-decls -Wnested-externs -Wdisabled-optimization -ansi \ + -Wno-unused-parameter -Werror -I../Include -I../Demo + +run: all run1 runbook run3 runtest + ./covall + +all: cs_demo1 cs_demo2 cs_demo3 cstcov_test + +CS = cs_add.o cs_amd.o cs_chol.o cs_cholsol.o cs_counts.o cs_cumsum.o \ + cs_droptol.o cs_dropzeros.o cs_dupl.o cs_entry.o \ + cs_etree.o cs_fkeep.o cs_gaxpy.o cs_happly.o cs_house.o cs_ipvec.o \ + cs_lsolve.o cs_ltsolve.o cs_lu.o cs_lusol.o cs_util.o cs_multiply.o \ + cs_permute.o cs_pinv.o cs_post.o cs_pvec.o cs_qr.o cs_qrsol.o \ + cs_scatter.o cs_schol.o cs_sqr.o cs_symperm.o cs_tdfs.o \ + cs_transpose.o cs_compress.o cs_usolve.o cs_scc.o cs_maxtrans.o \ + cs_dmperm.o cs_updown.o cs_print.o cs_norm.o cs_load.o cs_dfs.o \ + cstcov_malloc_test.o cs_utsolve.o cs_reach.o cs_spsolve.o cs_ereach.o \ + cs_leaf.o cs_randperm.o + +$(CS): ../Include/cs.h cstcov_malloc_test.h + +.PRECIOUS: cs_%.c cs_dem%.c + +cs_dem%.c: + - ln -s ../Demo/$@ + +cs_%.c: + - ln -s ../Source/$@ + +cs_demo1: $(CS) cs_demo1.c + $(CC) $(CFLAGS) -o cs_demo1 cs_demo1.c $(CS) -lm + +cs_demo2: $(CS) cs_demo2.c cs_demo.c + $(CC) $(CFLAGS) -o cs_demo2 cs_demo2.c cs_demo.c $(CS) -lm + +cs_demo3: $(CS) cs_demo3.c cs_demo.c + $(CC) $(CFLAGS) -o cs_demo3 cs_demo3.c cs_demo.c $(CS) -lm + +cstcov_test: $(CS) cstcov_test.c cs_demo.c + $(CC) $(CFLAGS) -o cstcov_test cstcov_test.c cs_demo.c $(CS) -lm + +# tiny tests +run1: all + - $(V) ./cs_demo1 < nil + - $(V) ./cs_demo1 < zero + - $(V) ./cs_demo2 < nil + - $(V) ./cs_demo2 < zero + - $(V) ./cs_demo3 < nil + +# test coverage for book: +runbook: all + - $(V) ./cs_demo1 < ../Matrix/t1 + - $(V) ./cs_demo2 < ../Matrix/bcsstk01 + - $(V) ./cs_demo2 < ../Matrix/fs_183_1 + - $(V) ./cs_demo2 < ../Matrix/mbeacxc + - $(V) ./cs_demo2 < ../Matrix/west0067 + - $(V) ./cs_demo2 < ../Matrix/lp_afiro + - $(V) ./cs_demo3 < ../Matrix/bcsstk16 + +# other tests +run3: all + - $(V) ./cs_demo2 < ../Matrix/t1 + - $(V) ./cs_demo2 < ../Matrix/ash219 + - $(V) ./cs_demo3 < ../Matrix/bcsstk01 + - $(V) ./cs_demo2 < ../Matrix/bcsstk16 + - $(V) ./cs_demo2 < ../Matrix/ibm32a + - $(V) ./cs_demo2 < ../Matrix/ibm32b + +# exhaustive memory tests +runtest: all + - $(V) ./cstcov_test nil > test_nil.out + - $(V) ./cstcov_test zero > test_zero.out + - $(V) ./cstcov_test ../Matrix/t1 > test_t1.out + - $(V) ./cstcov_test ../Matrix/bcsstk01 > test_k1.out + - $(V) ./cstcov_test ../Matrix/fs_183_1 > test_fs.out + - $(V) ./cstcov_test ../Matrix/west0067 > test_we.out + - $(V) ./cstcov_test ../Matrix/ash219 > test_ash.out + - $(V) ./cstcov_test ../Matrix/lp_afiro > test_afiro.out + +readhb: readhb.f + f77 -o readhb readhb.f + +readhb.f: + - ln -s readhb.f + +clean: + - $(RM) *.o *.bbg *.da *.gcov *.gcda *.gcno + +purge: distclean + +# remove everything for distribution, including all symbolic links +distclean: clean + - $(RM) cs_demo1 cs_demo2 readhb *.out *.a cs_demo3 cstcov_test cov.sort + - $(RM) cs_*.c + - $(RM) -r *.dSYM diff --git a/OpenDSSC/klusolve/CSparse/Tcov/README.txt b/OpenDSSC/klusolve/CSparse/Tcov/README.txt new file mode 100644 index 0000000..74df39d --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/README.txt @@ -0,0 +1,13 @@ +CSparse/Tcov: comprehensive test coverage for CSparse. Requires Linux. +Type "make" to compile, and then "make run" to run the tests. +The test coverage is in cover.out. The test output is +printed on stdout, except for cs_test (which prints its output in various +*.out files). + +If the test is successful, the last line printed should be +"statements not yet tested: 0", and all printed residuals should be small. + +Note that you will get warnings about unused parameters for some functions. +These warnings can be safely ignored. They are parameters for functions that +are passed to cs_fkeep, and all functions used in this manner must have the +same calling sequence, even if some of the parameters are not used. diff --git a/OpenDSSC/klusolve/CSparse/Tcov/cov.awk b/OpenDSSC/klusolve/CSparse/Tcov/cov.awk new file mode 100644 index 0000000..23db564 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/cov.awk @@ -0,0 +1,17 @@ +/cannot/ + +/function/ { f = $8 } + +/file/ { f = $8 } + +/lines/ { + + k = match ($1, "%") ; + p = substr ($1, 1, k-1) ; + + if ((p+0) != 100) + { + printf "%8s %s\n", p, f + } +} + diff --git a/OpenDSSC/klusolve/CSparse/Tcov/covall b/OpenDSSC/klusolve/CSparse/Tcov/covall new file mode 100644 index 0000000..855c538 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/covall @@ -0,0 +1,7 @@ +#!/bin/csh + ./gcovs cs*.c |& awk -f cov.awk | sort -n > cov.out + sort -n cov.out > cov.sort + ./covs > covs.out + echo -n "statments not yet tested: " + grep "#####" *gcov | wc -l + ./cover *v > cover.out diff --git a/OpenDSSC/klusolve/CSparse/Tcov/covall.linux b/OpenDSSC/klusolve/CSparse/Tcov/covall.linux new file mode 100644 index 0000000..855c538 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/covall.linux @@ -0,0 +1,7 @@ +#!/bin/csh + ./gcovs cs*.c |& awk -f cov.awk | sort -n > cov.out + sort -n cov.out > cov.sort + ./covs > covs.out + echo -n "statments not yet tested: " + grep "#####" *gcov | wc -l + ./cover *v > cover.out diff --git a/OpenDSSC/klusolve/CSparse/Tcov/covall.sol b/OpenDSSC/klusolve/CSparse/Tcov/covall.sol new file mode 100644 index 0000000..0061ae4 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/covall.sol @@ -0,0 +1,5 @@ +#!/bin/csh + tcov -x cm.profile cs*.c >& /dev/null + echo -n "statments not yet tested: " + ./covs > covs.out + grep "#####" *tcov | wc -l diff --git a/OpenDSSC/klusolve/CSparse/Tcov/cover b/OpenDSSC/klusolve/CSparse/Tcov/cover new file mode 100644 index 0000000..a9281dd --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/cover @@ -0,0 +1,9 @@ +#!/bin/csh +# usage: cover files +echo '=================================================================' +foreach file ($argv[1-]) + echo $file + echo '=================================================================' + grep "#####" -A5 -B5 $file + echo '=================================================================' + end diff --git a/OpenDSSC/klusolve/CSparse/Tcov/covs b/OpenDSSC/klusolve/CSparse/Tcov/covs new file mode 100644 index 0000000..c184189 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/covs @@ -0,0 +1,7 @@ +#!/bin/csh +echo '=================================================================' +foreach file (*.?cov) + echo $file + grep "#####" $file + echo '=================================================================' + end diff --git a/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.c b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.c new file mode 100644 index 0000000..bb203df --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.c @@ -0,0 +1,34 @@ +#include "cstcov_malloc_test.h" +int malloc_count = INT_MAX ; + +/* wrapper for malloc */ +void *cs_malloc (int n, size_t size) +{ + if (--malloc_count < 0) return (NULL) ; /* pretend to fail */ + return (malloc (CS_MAX (n,1) * size)) ; +} + +/* wrapper for calloc */ +void *cs_calloc (int n, size_t size) +{ + if (--malloc_count < 0) return (NULL) ; /* pretend to fail */ + return (calloc (CS_MAX (n,1), size)) ; +} + +/* wrapper for free */ +void *cs_free (void *p) +{ + if (p) free (p) ; /* free p if it is not already NULL */ + return (NULL) ; /* return NULL to simplify the use of cs_free */ +} + +/* wrapper for realloc */ +void *cs_realloc (void *p, int n, size_t size, int *ok) +{ + void *pnew ; + *ok = 0 ; + if (--malloc_count < 0) return (p) ; /* pretend to fail */ + pnew = realloc (p, CS_MAX (n,1) * size) ; /* realloc the block */ + *ok = (pnew != NULL) ; + return ((*ok) ? pnew : p) ; /* return original p if failure */ +} diff --git a/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.h b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.h new file mode 100644 index 0000000..5bf6d75 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_malloc_test.h @@ -0,0 +1,5 @@ +#include "cs.h" +#ifndef EXTERN +#define EXTERN extern +#endif +EXTERN int malloc_count ; diff --git a/OpenDSSC/klusolve/CSparse/Tcov/cstcov_test.c b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_test.c new file mode 100644 index 0000000..58195fb --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/cstcov_test.c @@ -0,0 +1,30 @@ +#include "cs_demo.h" +/* cs_test: read a matrix and run cs_demo2 and cs_demo3, using malloc tests. */ + +#include "cstcov_malloc_test.h" + +int main (int argc, char **argv) +{ + FILE *f ; + problem *Prob ; + int trials, ok, demo ; + if (argc < 2) return (-1) ; + printf ("cs_test, file: %s\n", argv [1]) ; + for (demo = 2 ; demo <= 3 ; demo++) + { + printf ("demo: %d\n", demo) ; + for (trials = 0 ; trials < 4000 ; trials++) + { + malloc_count = trials ; + f = fopen (argv [1], "r") ; + if (!f) return (-1) ; + Prob = get_problem (f, (demo == 2) ? 1e-14 : 0) ; + fclose (f) ; + if (Prob) ok = (demo == 2) ? demo2 (Prob) : demo3 (Prob) ; + free_problem (Prob) ; + if (malloc_count > 0) break ; + } + printf ("demo %d # trials: %d\n", demo, trials) ; + } + return (0) ; +} diff --git a/OpenDSSC/klusolve/CSparse/Tcov/gcovs b/OpenDSSC/klusolve/CSparse/Tcov/gcovs new file mode 100644 index 0000000..ea32176 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/gcovs @@ -0,0 +1,6 @@ +# usage: gcovs files +echo '=================================================================' +foreach file ($argv[1-]) + gcov -f $file + echo '=================================================================' + end diff --git a/OpenDSSC/klusolve/CSparse/Tcov/nil b/OpenDSSC/klusolve/CSparse/Tcov/nil new file mode 100644 index 0000000..e69de29 diff --git a/OpenDSSC/klusolve/CSparse/Tcov/zero b/OpenDSSC/klusolve/CSparse/Tcov/zero new file mode 100644 index 0000000..a5c7b77 --- /dev/null +++ b/OpenDSSC/klusolve/CSparse/Tcov/zero @@ -0,0 +1 @@ +0 0 0 diff --git a/OpenDSSC/klusolve/CZSparse/Include/csz.h b/OpenDSSC/klusolve/CZSparse/Include/csz.h new file mode 100644 index 0000000..ae004bb --- /dev/null +++ b/OpenDSSC/klusolve/CZSparse/Include/csz.h @@ -0,0 +1,17 @@ +/* ------------------------------------------------------------------------- */ +/* CZSparse, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ +cs *csz_spalloc (int m, int n, int nzmax, int values, int triplet); + +int csz_sprealloc (cs *A, int nzmax); +cs *csz_compress (const cs *T); +int csz_dupl (cs *A); +int csz_gaxpy (const cs *A, const double *x, double *y); +int csz_entry (cs *T, int i, int j, double re, double im); +int csz_print (const cs *A, int brief); +cs *csz_transpose (const cs *A, int values); +cs *csz_spalloc (int m, int n, int nzmax, int values, int triplet); +int csz_dropzeros (cs *A); +int csz_fkeep (cs *A, int (*fkeep) (int, int, double, double, void *), void *other); +double csz_norm (const cs *A); diff --git a/OpenDSSC/klusolve/CZSparse/Makefile b/OpenDSSC/klusolve/CZSparse/Makefile new file mode 100644 index 0000000..be925ec --- /dev/null +++ b/OpenDSSC/klusolve/CZSparse/Makefile @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------ +# CZSparse Makefile +#------------------------------------------------------------------------------ + +default: C + +include ../UFconfig/UFconfig.mk + +C: + ( cd Lib ; $(MAKE) ) + +all: C + +library: + ( cd Lib ; $(MAKE) ) + +clean: + ( cd Lib ; $(MAKE) clean ) + +purge: + ( cd Lib ; $(MAKE) purge ) + +distclean: purge + +# do not install CZSparse +install: + +# uninstall CZSparse: do nothing +uninstall: + diff --git a/OpenDSSC/klusolve/CZSparse/Source/csz_stuff.c b/OpenDSSC/klusolve/CZSparse/Source/csz_stuff.c new file mode 100644 index 0000000..b0cfd3a --- /dev/null +++ b/OpenDSSC/klusolve/CZSparse/Source/csz_stuff.c @@ -0,0 +1,284 @@ +/* ------------------------------------------------------------------------- */ +/* CZSparse, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ + +/* These are complex versions of selected functions from the CSparse package + * by Timothy A. Davis. The purpose is to compile on Windows without a C99 + * compiler. A->x stores alternate real/imaginary values. + */ + +#include "cs.h" +#include "csz.h" + +/* allocate a sparse matrix (triplet form or compressed-column form) */ +cs *csz_spalloc (int m, int n, int nzmax, int values, int triplet) +{ + cs *A = cs_calloc (1, sizeof (cs)); /* allocate the cs struct */ + if (!A) return (NULL); /* out of memory */ + A->m = m; /* define dimensions and nzmax */ + A->n = n; + A->nzmax = nzmax = CS_MAX (nzmax, 1); + A->nz = triplet ? 0 : -1; /* allocate triplet or comp.col */ + A->p = cs_malloc (triplet ? nzmax : n+1, sizeof (int)); + A->i = cs_malloc (nzmax, sizeof (int)); + A->x = values ? cs_malloc (2*nzmax, sizeof (double)) : NULL; + return ((!A->p || !A->i || (values && !A->x)) ? cs_spfree (A) : A); +} + +/* change the max # of entries sparse matrix */ +int csz_sprealloc (cs *A, int nzmax) +{ + int ok, oki, okj = 1, okx = 1; + if (!A) return (0); + if (nzmax <= 0) nzmax = (CS_CSC (A)) ? (A->p [A->n]) : A->nz; + A->i = cs_realloc (A->i, nzmax, sizeof (int), &oki); + if (CS_TRIPLET (A)) A->p = cs_realloc (A->p, nzmax, sizeof (int), &okj); + if (A->x) A->x = cs_realloc (A->x, 2*nzmax, sizeof (double), &okx); + ok = (oki && okj && okx); + if (ok) A->nzmax = nzmax; + return (ok); +} + +/* add an entry to a triplet matrix; return 1 if ok, 0 otherwise */ +int csz_entry (cs *T, int i, int j, double re, double im) +{ + int k; + if (!CS_TRIPLET (T) || i < 0 || j < 0) return (0); /* check inputs */ + if (T->nz >= T->nzmax && !csz_sprealloc (T,2*(T->nzmax))) return (0); + if (T->x) { + k = 2 * T->nz; + T->x [k] = re; + T->x [k+1] = im; + } + T->i [T->nz] = i; + T->p [T->nz++] = j; + T->m = CS_MAX (T->m, i+1); + T->n = CS_MAX (T->n, j+1); + return (1); +} + +/* print a sparse matrix */ +int csz_print (const cs *A, int brief) +{ + int p, j, m, n, nzmax, nz, *Ap, *Ai; + double *Ax; + + if (!A) { printf ("(null)\n"); return (0); } + m = A->m; n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; + nzmax = A->nzmax; nz = A->nz; + printf ("CSparse Version %d.%d.%d, %s. %s\n", CS_VER, CS_SUBVER, + CS_SUBSUB, CS_DATE, CS_COPYRIGHT); + if (nz < 0) { + printf ("%d-by-%d, nzmax: %d nnz: %d, 1-norm: %g\n", m, n, nzmax, + Ap [n], csz_norm (A)); + for (j = 0; j < n; j++) { + printf (" col %d : locations %d to %d\n", j, Ap [j], Ap [j+1]-1); + for (p = Ap [j]; p < Ap [j+1]; p++) { + printf (" %d : %g + j%g\n", + Ai [p], Ax ? Ax [2*p] : 1, Ax ? Ax [2*p + 1] : 1); + if (brief && p > 20) { printf (" ...\n"); return (1); } + } + } + } else { + printf ("triplet: %d-by-%d, nzmax: %d nnz: %d\n", m, n, nzmax, nz); + for (p = 0; p < nz; p++) { + printf (" %d %d : %g + j%g\n", + Ai [p], Ap [p], Ax ? Ax [2*p] : 1, Ax ? Ax [2*p + 1] : 1); + if (brief && p > 20) { printf (" ...\n"); return (1); } + } + } + return (1); +} + +/* C = A' */ +cs *csz_transpose (const cs *A, int values) +{ + int p, q, j, *Cp, *Ci, n, m, *Ap, *Ai, *w; + double *Cx, *Ax; + cs *C; + int p1, q1; + + if (!CS_CSC (A)) return (NULL); /* check inputs */ + m = A->m; n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; + C = csz_spalloc (n, m, Ap [n], values && Ax, 0); /* allocate result */ + w = cs_calloc (m, sizeof (int)); /* get workspace */ + if (!C || !w) return (cs_done (C, w, NULL, 0)); /* out of memory */ + Cp = C->p; Ci = C->i; Cx = C->x; + for (p = 0; p < Ap [n]; p++) w [Ai [p]]++; /* row counts */ + cs_cumsum (Cp, w, m); /* row pointers */ + for (j = 0; j < n; j++) { + for (p = Ap [j]; p < Ap [j+1]; p++) { + Ci [q = w [Ai [p]]++] = j; /* place A(i,j) as entry C(j,i) */ + if (Cx) { + q1 = 2 * q; + p1 = 2 * p; + Cx [q1] = Ax [p1]; + Cx [q1 + 1] = Ax [p1 + 1]; + } + } + } + return (cs_done (C, w, NULL, 1)); /* success; free w and return C */ +} + +static int csz_nonzero (int i, int j, double re, double im, void *other) +{ + return (re != 0.0 || im != 0.0); +} + +int csz_dropzeros (cs *A) +{ + return (csz_fkeep (A, &csz_nonzero, NULL)); /* keep all nonzero entries */ +} + +/* drop entries for which fkeep(A(i,j)) is false; return nz if OK, else -1 */ +int csz_fkeep (cs *A, int (*fkeep) (int, int, double, double, void *), void *other) +{ + int j, p, nz = 0, n, *Ap, *Ai; + double *Ax; + double re, im; + int p1, p2, z1; + + if (!CS_CSC (A) || !fkeep) return (-1); /* check inputs */ + n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; + for (j = 0; j < n; j++) { + p = Ap [j]; /* get current location of col j */ + Ap [j] = nz; /* record new location of col j */ + for (; p < Ap [j+1]; p++) { + p1 = 2 * p; + p2 = p1 + 1; + if (Ax) { + re = Ax[p1]; + im = Ax[p2]; + } else { + re = im = 0.0; + } + if (fkeep (Ai [p], j, re, im, other)) { + if (Ax) { + z1 = 2 * nz; + Ax [z1] = Ax [p1]; /* keep A(i,j) */ + Ax [z1 + 1] = Ax [p2]; + } + Ai [nz++] = Ai [p]; + } else { + re = im; + } + } + } + Ap [n] = nz; /* finalize A */ + csz_sprealloc (A, 0); /* remove extra space from A */ + return (nz); +} + +/* remove duplicate entries from A */ +int csz_dupl (cs *A) +{ + int i, j, p, q, nz = 0, n, m, *Ap, *Ai, *w; + double *Ax; + int p1, p2, w1, z1; + + if (!CS_CSC (A)) return (0); /* check inputs */ + m = A->m; n = A->n; Ap = A->p; Ai = A->i; Ax = A->x; + w = cs_malloc (m, sizeof (int)); /* get workspace */ + if (!w) return (0); /* out of memory */ + for (i = 0; i < m; i++) w [i] = -1; /* row i not yet seen */ + for (j = 0; j < n; j++) { + q = nz; /* column j will start at q */ + for (p = Ap [j]; p < Ap [j+1]; p++) { + p1 = 2 * p; + p2 = p1 + 1; + i = Ai [p]; /* A(i,j) is nonzero */ + if (w [i] >= q) { + w1 = 2 * w[i]; + Ax [w1] += Ax [p1]; /* A(i,j) is a duplicate */ + Ax [w1+1] += Ax [p2]; + } else { + w [i] = nz; /* record where row i occurs */ + z1 = 2 * nz; /* keep A(i,j) */ + Ax [z1] = Ax [p1]; + Ax [z1+1] = Ax [p2]; + Ai [nz++] = i; + } + } + Ap [j] = q; /* record start of column j */ + } + Ap [n] = nz; /* finalize A */ + cs_free (w); /* free workspace */ + return (csz_sprealloc (A, 0)); /* remove extra space from A */ +} + +/* C = compressed-column form of a triplet matrix T */ +cs *csz_compress (const cs *T) +{ + int m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj; + double *Cx, *Tx; + cs *C; + int p1, k1; + + if (!CS_TRIPLET (T)) return (NULL); /* check inputs */ + m = T->m; n = T->n; Ti = T->i; Tj = T->p; Tx = T->x; nz = T->nz; + C = csz_spalloc (m, n, nz, Tx != NULL, 0); /* allocate result */ + w = cs_calloc (n, sizeof (int)); /* get workspace */ + if (!C || !w) return (cs_done (C, w, NULL, 0)); /* out of memory */ + Cp = C->p; Ci = C->i; Cx = C->x; + for (k = 0; k < nz; k++) w [Tj [k]]++; /* column counts */ + cs_cumsum (Cp, w, n); /* column pointers */ + for (k = 0; k < nz; k++) { + Ci [p = w [Tj [k]]++] = Ti [k]; /* A(i,j) is the pth entry in C */ + if (Cx) { + p1 = 2 * p; + k1 = 2 * k; + Cx [p1] = Tx [k1]; + Cx [p1+1] = Tx [k1+1]; + } + } + return (cs_done (C, w, NULL, 1)); /* success; free w and return C */ +} + +/* 1-norm of a sparse matrix = max (sum (abs (A))), largest column sum */ +double csz_norm (const cs *A) +{ + int p, j, n, *Ap; + double *Ax, norm = 0, s; + double re, im; + int p1; + + if (!CS_CSC (A) || !A->x) return (-1); /* check inputs */ + n = A->n; Ap = A->p; Ax = A->x; + for (j = 0; j < n; j++) { + for (s = 0, p = Ap [j]; p < Ap [j+1]; p++) { + p1 = 2 * p; + re = Ax [p1]; + im = Ax [p1+1]; + s += (re * re + im * im); + } + norm = CS_MAX (norm, s); + } + return (sqrt (norm)); +} + +/* y = A*x+y for complex numbers, interleaved Re and Im parts */ +int csz_gaxpy (const cs *A, const double *x, double *y) +{ + int p, j, n, *Ap, *Ai; + double *Ax; + int i1, j1, p1; + double Are, Aim, Xre, Xim; + + if (!CS_CSC (A) || !x || !y) return (0); /* check inputs */ + n = A->n; Ap = A->p; Ai = A->i ; Ax = A->x; + for (j = 0; j < n; j++) { + j1 = 2 * j; + for (p = Ap [j]; p < Ap [j+1]; p++) { + p1 = 2 * p; + i1 = 2 * Ai[p]; + Are = Ax[p1]; + Aim = Ax[p1+1]; + Xre = x[j1]; + Xim = x[j1+1]; + y [i1] += (Are * Xre - Aim * Xim); + y [i1+1] += (Are * Xim + Aim * Xre); + } + } + return (1); +} diff --git a/OpenDSSC/klusolve/KLU/Demo/Makefile b/OpenDSSC/klusolve/KLU/Demo/Makefile new file mode 100644 index 0000000..734be48 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Demo/Makefile @@ -0,0 +1,65 @@ +# KLU Demo Makefile. The klu_simple demo is stand-alone. The other demos +# require CHOLMOD. + +default: all + +include ../../UFconfig/UFconfig.mk + +LIB = ../Lib/libklu.a ../../BTF/Lib/libbtf.a \ + ../../AMD/Lib/libamd.a ../../COLAMD/Lib/libcolamd.a + +CHOLMOD = ../../CHOLMOD/Lib/libcholmod.a + +I = -I../../UFconfig -I../../AMD/Include -I../../COLAMD/Include \ + -I../../BTF/Include -I../Include -I../../CHOLMOD/Include + +all: $(LIB) klu_simple $(CHOLMOD) kludemo kluldemo + - ./klu_simple + - ./kludemo < ../Matrix/1c.mtx + - ./kludemo < ../Matrix/arrowc.mtx + - ./kludemo < ../Matrix/arrow.mtx + - ./kludemo < ../Matrix/impcol_a.mtx + - ./kludemo < ../Matrix/w156.mtx + - ./kludemo < ../Matrix/ctina.mtx + - ./kluldemo < ../Matrix/1c.mtx + - ./kluldemo < ../Matrix/arrowc.mtx + - ./kluldemo < ../Matrix/arrow.mtx + - ./kluldemo < ../Matrix/impcol_a.mtx + - ./kluldemo < ../Matrix/w156.mtx + - ./kluldemo < ../Matrix/ctina.mtx + +../Lib/libklu.a: + ( cd ../Lib ; $(MAKE) ) + +../../BTF/Lib/libbtf.a: + ( cd ../../BTF ; $(MAKE) library ) + +../../AMD/Lib/libamd.a: + ( cd ../../AMD ; $(MAKE) library ) + +../../COLAMD/Lib/libcolamd.a: + ( cd ../../COLAMD ; $(MAKE) library ) + +../../CHOLMOD/Lib/libcholmod.a: + ( cd ../../CHOLMOD ; $(MAKE) library ) +# ( cd ../../CAMD ; $(MAKE) ) +# ( cd ../../CCOLAMD ; $(MAKE) ) +# ( cd ../../metis-4.0 ; $(MAKE) ) + +purge: distclean + +distclean: clean + - $(RM) kludemo kluldemo klu_simple + +clean: + - $(RM) $(CLEAN) + +kludemo: kludemo.c Makefile $(LIB) + $(CC) $(CFLAGS) $(I) kludemo.c -o kludemo $(LIB) $(CHOLMOD) -lm + +kluldemo: kludemo.c Makefile $(LIB) + $(CC) $(CFLAGS) $(I) kluldemo.c -o kluldemo $(LIB) $(CHOLMOD) -lm + +klu_simple: klu_simple.c Makefile $(LIB) + $(CC) $(CFLAGS) $(I) klu_simple.c -o klu_simple $(LIB) -lm + - ./klu_simple diff --git a/OpenDSSC/klusolve/KLU/Demo/klu_simple.c b/OpenDSSC/klusolve/KLU/Demo/klu_simple.c new file mode 100644 index 0000000..72c4379 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Demo/klu_simple.c @@ -0,0 +1,27 @@ +/* klu_simple: a simple KLU demo */ + +#include +#include "klu.h" + +int n = 5 ; +int Ap [ ] = {0, 2, 5, 9, 10, 12} ; +int Ai [ ] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4} ; +double Ax [ ] = {2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1.} ; +double b [ ] = {8., 45., -3., 3., 19.} ; + +int main (void) +{ + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + int i ; + klu_defaults (&Common) ; + Symbolic = klu_analyze (n, Ap, Ai, &Common) ; + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; + klu_solve (Symbolic, Numeric, 5, 1, b, &Common) ; + klu_free_symbolic (&Symbolic, &Common) ; + klu_free_numeric (&Numeric, &Common) ; + for (i = 0 ; i < n ; i++) printf ("x [%d] = %g\n", i, b [i]) ; + return (0) ; +} + diff --git a/OpenDSSC/klusolve/KLU/Demo/kludemo.c b/OpenDSSC/klusolve/KLU/Demo/kludemo.c new file mode 100644 index 0000000..1efa47d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Demo/kludemo.c @@ -0,0 +1,326 @@ +/* ========================================================================== */ +/* === KLU DEMO ============================================================= */ +/* ========================================================================== */ + +/* Read in a Matrix Market matrix (using CHOLMOD) and solve a linear system. */ + +#include +#include +#include "klu.h" + +/* for handling complex matrices */ +#define REAL(X,i) (X [2*(i)]) +#define IMAG(X,i) (X [2*(i)+1]) +#define CABS(X,i) (sqrt (REAL (X,i) * REAL (X,i) + IMAG (X,i) * IMAG (X,i))) + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* ========================================================================== */ +/* === klu_backslash ======================================================== */ +/* ========================================================================== */ + +static int klu_backslash /* return 1 if successful, 0 otherwise */ +( + /* --- input ---- */ + int n, /* A is n-by-n */ + int *Ap, /* size n+1, column pointers */ + int *Ai, /* size nz = Ap [n], row indices */ + double *Ax, /* size nz, numerical values */ + int isreal, /* nonzero if A is real, 0 otherwise */ + double *B, /* size n, right-hand-side */ + + /* --- output ---- */ + double *X, /* size n, solution to Ax=b */ + double *R, /* size n, residual r = b-A*x */ + + /* --- scalar output --- */ + int *lunz, /* nnz (L+U+F) */ + double *rnorm, /* norm (b-A*x,1) / norm (A,1) */ + + /* --- workspace - */ + + klu_common *Common /* default parameters and statistics */ +) +{ + double anorm = 0, asum ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + int i, j, p ; + + if (!Ap || !Ai || !Ax || !B || !X || !B) return (0) ; + + /* ---------------------------------------------------------------------- */ + /* symbolic ordering and analysis */ + /* ---------------------------------------------------------------------- */ + + Symbolic = klu_analyze (n, Ap, Ai, Common) ; + if (!Symbolic) return (0) ; + + if (isreal) + { + + /* ------------------------------------------------------------------ */ + /* factorization */ + /* ------------------------------------------------------------------ */ + + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, Common) ; + if (!Numeric) + { + klu_free_symbolic (&Symbolic, Common) ; + return (0) ; + } + + /* ------------------------------------------------------------------ */ + /* statistics (not required to solve Ax=b) */ + /* ------------------------------------------------------------------ */ + + klu_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + klu_condest (Ap, Ax, Symbolic, Numeric, Common) ; + klu_rcond (Symbolic, Numeric, Common) ; + klu_flops (Symbolic, Numeric, Common) ; + *lunz = Numeric->lnz + Numeric->unz - n + + ((Numeric->Offp) ? (Numeric->Offp [n]) : 0) ; + + /* ------------------------------------------------------------------ */ + /* solve Ax=b */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < n ; i++) + { + X [i] = B [i] ; + } + klu_solve (Symbolic, Numeric, n, 1, X, Common) ; + + /* ------------------------------------------------------------------ */ + /* compute residual, rnorm = norm(b-Ax,1) / norm(A,1) */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < n ; i++) + { + R [i] = B [i] ; + } + for (j = 0 ; j < n ; j++) + { + asum = 0 ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + /* R (i) -= A (i,j) * X (j) */ + R [Ai [p]] -= Ax [p] * X [j] ; + asum += fabs (Ax [p]) ; + } + anorm = MAX (anorm, asum) ; + } + *rnorm = 0 ; + for (i = 0 ; i < n ; i++) + { + *rnorm = MAX (*rnorm, fabs (R [i])) ; + } + + /* ------------------------------------------------------------------ */ + /* free numeric factorization */ + /* ------------------------------------------------------------------ */ + + klu_free_numeric (&Numeric, Common) ; + + } + else + { + + /* ------------------------------------------------------------------ */ + /* statistics (not required to solve Ax=b) */ + /* ------------------------------------------------------------------ */ + + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, Common) ; + if (!Numeric) + { + klu_free_symbolic (&Symbolic, Common) ; + return (0) ; + } + + /* ------------------------------------------------------------------ */ + /* statistics */ + /* ------------------------------------------------------------------ */ + + klu_z_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + klu_z_condest (Ap, Ax, Symbolic, Numeric, Common) ; + klu_z_rcond (Symbolic, Numeric, Common) ; + klu_z_flops (Symbolic, Numeric, Common) ; + *lunz = Numeric->lnz + Numeric->unz - n + + ((Numeric->Offp) ? (Numeric->Offp [n]) : 0) ; + + /* ------------------------------------------------------------------ */ + /* solve Ax=b */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < 2*n ; i++) + { + X [i] = B [i] ; + } + klu_z_solve (Symbolic, Numeric, n, 1, X, Common) ; + + /* ------------------------------------------------------------------ */ + /* compute residual, rnorm = norm(b-Ax,1) / norm(A,1) */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < 2*n ; i++) + { + R [i] = B [i] ; + } + for (j = 0 ; j < n ; j++) + { + asum = 0 ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + /* R (i) -= A (i,j) * X (j) */ + i = Ai [p] ; + REAL (R,i) -= REAL(Ax,p) * REAL(X,j) - IMAG(Ax,p) * IMAG(X,j) ; + IMAG (R,i) -= IMAG(Ax,p) * REAL(X,j) + REAL(Ax,p) * IMAG(X,j) ; + asum += CABS (Ax, p) ; + } + anorm = MAX (anorm, asum) ; + } + *rnorm = 0 ; + for (i = 0 ; i < n ; i++) + { + *rnorm = MAX (*rnorm, CABS (R, i)) ; + } + + /* ------------------------------------------------------------------ */ + /* free numeric factorization */ + /* ------------------------------------------------------------------ */ + + klu_z_free_numeric (&Numeric, Common) ; + } + + /* ---------------------------------------------------------------------- */ + /* free symbolic analysis, and residual */ + /* ---------------------------------------------------------------------- */ + + klu_free_symbolic (&Symbolic, Common) ; + return (1) ; +} + + +/* ========================================================================== */ +/* === klu_demo ============================================================= */ +/* ========================================================================== */ + +/* Given a sparse matrix A, set up a right-hand-side and solve X = A\b */ + +static void klu_demo (int n, int *Ap, int *Ai, double *Ax, int isreal) +{ + double rnorm ; + klu_common Common ; + double *B, *X, *R ; + int i, lunz ; + + printf ("KLU: %s, version: %d.%d.%d\n", KLU_DATE, KLU_MAIN_VERSION, + KLU_SUB_VERSION, KLU_SUBSUB_VERSION) ; + + /* ---------------------------------------------------------------------- */ + /* set defaults */ + /* ---------------------------------------------------------------------- */ + + klu_defaults (&Common) ; + + /* ---------------------------------------------------------------------- */ + /* create a right-hand-side */ + /* ---------------------------------------------------------------------- */ + + if (isreal) + { + /* B = 1 + (1:n)/n */ + B = klu_malloc (n, sizeof (double), &Common) ; + X = klu_malloc (n, sizeof (double), &Common) ; + R = klu_malloc (n, sizeof (double), &Common) ; + if (B) + { + for (i = 0 ; i < n ; i++) + { + B [i] = 1 + ((double) i+1) / ((double) n) ; + } + } + } + else + { + /* real (B) = 1 + (1:n)/n, imag(B) = (n:-1:1)/n */ + B = klu_malloc (n, 2 * sizeof (double), &Common) ; + X = klu_malloc (n, 2 * sizeof (double), &Common) ; + R = klu_malloc (n, 2 * sizeof (double), &Common) ; + if (B) + { + for (i = 0 ; i < n ; i++) + { + REAL (B, i) = 1 + ((double) i+1) / ((double) n) ; + IMAG (B, i) = ((double) n-i) / ((double) n) ; + } + } + } + + /* ---------------------------------------------------------------------- */ + /* X = A\b using KLU and print statistics */ + /* ---------------------------------------------------------------------- */ + + if (!klu_backslash (n, Ap, Ai, Ax, isreal, B, X, R, &lunz, &rnorm, &Common)) + { + printf ("KLU failed\n") ; + } + else + { + printf ("n %d nnz(A) %d nnz(L+U+F) %d resid %g\n" + "recip growth %g condest %g rcond %g flops %g\n", + n, Ap [n], lunz, rnorm, Common.rgrowth, Common.condest, + Common.rcond, Common.flops) ; + } + + /* ---------------------------------------------------------------------- */ + /* free the problem */ + /* ---------------------------------------------------------------------- */ + + if (isreal) + { + klu_free (B, n, sizeof (double), &Common) ; + klu_free (X, n, sizeof (double), &Common) ; + klu_free (R, n, sizeof (double), &Common) ; + } + else + { + klu_free (B, 2*n, sizeof (double), &Common) ; + klu_free (X, 2*n, sizeof (double), &Common) ; + klu_free (R, 2*n, sizeof (double), &Common) ; + } + printf ("peak memory usage: %g bytes\n\n", (double) (Common.mempeak)) ; +} + + +/* ========================================================================== */ +/* === main ================================================================= */ +/* ========================================================================== */ + +/* Read in a sparse matrix in Matrix Market format using CHOLMOD, and then + * solve Ax=b with KLU. Note that CHOLMOD is only used to read the matrix. */ + +#include "cholmod.h" + +int main (void) +{ + cholmod_sparse *A ; + cholmod_common ch ; + cholmod_start (&ch) ; + A = cholmod_read_sparse (stdin, &ch) ; + if (A) + { + if (A->nrow != A->ncol || A->stype != 0 + || (!(A->xtype == CHOLMOD_REAL || A->xtype == CHOLMOD_COMPLEX))) + { + printf ("invalid matrix\n") ; + } + else + { + klu_demo (A->nrow, A->p, A->i, A->x, A->xtype == CHOLMOD_REAL) ; + } + cholmod_free_sparse (&A, &ch) ; + } + cholmod_finish (&ch) ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/KLU/Demo/kludemo.out b/OpenDSSC/klusolve/KLU/Demo/kludemo.out new file mode 100644 index 0000000..c619e86 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Demo/kludemo.out @@ -0,0 +1,78 @@ +./klu_simple +x [0] = 1 +x [1] = 2 +x [2] = 3 +x [3] = 4 +x [4] = 5 +./kludemo < ../Matrix/1c.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 1 nnz(A) 1 nnz(L+U+F) 1 resid 0 +recip growth 1 condest 1 rcond 1 flops 0 +peak memory usage: 492 bytes + +./kludemo < ../Matrix/arrowc.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 100 nnz(A) 298 nnz(L+U+F) 298 resid 1.68007e-14 +recip growth 0.019999 condest 295.99 rcond 0.019999 flops 297 +peak memory usage: 32244 bytes + +./kludemo < ../Matrix/arrow.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 100 nnz(A) 298 nnz(L+U+F) 298 resid 1.77636e-15 +recip growth 0.0204082 condest 303 rcond 0.0204082 flops 297 +peak memory usage: 20412 bytes + +./kludemo < ../Matrix/impcol_a.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 207 nnz(A) 572 nnz(L+U+F) 615 resid 6.98492e-10 +recip growth 0.00957447 condest 4.35093e+07 rcond 4.5277e-05 flops 259 +peak memory usage: 34276 bytes + +./kludemo < ../Matrix/w156.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 156 nnz(A) 362 nnz(L+U+F) 396 resid 6.23816e-08 +recip growth 0.00889922 condest 1.79787e+09 rcond 0.000124785 flops 175 +peak memory usage: 39516 bytes + +./kludemo < ../Matrix/ctina.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 11 nnz(A) 36 nnz(L+U+F) 45 resid 4.44089e-16 +recip growth 1 condest 56 rcond 1 flops 73 +peak memory usage: 4268 bytes + +./kluldemo < ../Matrix/1c.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 1 nnz(A) 1 nnz(L+U+F) 1 resid 0 +recip growth 1 condest 1 rcond 1 flops 0 +peak memory usage: 600 bytes + +./kluldemo < ../Matrix/arrowc.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 100 nnz(A) 298 nnz(L+U+F) 298 resid 1.68007e-14 +recip growth 0.019999 condest 295.99 rcond 0.019999 flops 297 +peak memory usage: 39000 bytes + +./kluldemo < ../Matrix/arrow.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 100 nnz(A) 298 nnz(L+U+F) 298 resid 1.77636e-15 +recip growth 0.0204082 condest 303 rcond 0.0204082 flops 297 +peak memory usage: 29584 bytes + +./kluldemo < ../Matrix/impcol_a.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 207 nnz(A) 572 nnz(L+U+F) 615 resid 6.98492e-10 +recip growth 0.00957447 condest 4.35093e+07 rcond 4.5277e-05 flops 259 +peak memory usage: 44800 bytes + +./kluldemo < ../Matrix/w156.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 156 nnz(A) 362 nnz(L+U+F) 396 resid 6.23816e-08 +recip growth 0.00889922 condest 1.79787e+09 rcond 0.000124785 flops 175 +peak memory usage: 47480 bytes + +./kluldemo < ../Matrix/ctina.mtx +KLU: Nov 1, 2007, version: 1.0.1 +n 11 nnz(A) 36 nnz(L+U+F) 45 resid 4.44089e-16 +recip growth 1 condest 56 rcond 1 flops 73 +peak memory usage: 5144 bytes + diff --git a/OpenDSSC/klusolve/KLU/Demo/kluldemo.c b/OpenDSSC/klusolve/KLU/Demo/kluldemo.c new file mode 100644 index 0000000..69d9ebb --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Demo/kluldemo.c @@ -0,0 +1,329 @@ +/* ========================================================================== */ +/* === KLU DEMO (long integer version) ====================================== */ +/* ========================================================================== */ + +/* Read in a Matrix Market matrix (using CHOLMOD) and solve a linear system. + * UF_long is normally a "long", but it becomes "_int64" on Windows 64. */ + +#include +#include +#include "klu.h" + +/* for handling complex matrices */ +#define REAL(X,i) (X [2*(i)]) +#define IMAG(X,i) (X [2*(i)+1]) +#define CABS(X,i) (sqrt (REAL (X,i) * REAL (X,i) + IMAG (X,i) * IMAG (X,i))) + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* ========================================================================== */ +/* === klu_l_backslash ====================================================== */ +/* ========================================================================== */ + +static UF_long klu_l_backslash /* return 1 if successful, 0 otherwise */ +( + /* --- input ---- */ + UF_long n, /* A is n-by-n */ + UF_long *Ap, /* size n+1, column pointers */ + UF_long *Ai, /* size nz = Ap [n], row indices */ + double *Ax, /* size nz, numerical values */ + UF_long isreal, /* nonzero if A is real, 0 otherwise */ + double *B, /* size n, right-hand-side */ + + /* --- output ---- */ + double *X, /* size n, solution to Ax=b */ + double *R, /* size n, residual r = b-A*x */ + + /* --- scalar output --- */ + UF_long *lunz, /* nnz (L+U+F) */ + double *rnorm, /* norm (b-A*x,1) / norm (A,1) */ + + /* --- workspace - */ + + klu_l_common *Common /* default parameters and statistics */ +) +{ + double anorm = 0, asum ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + UF_long i, j, p ; + + if (!Ap || !Ai || !Ax || !B || !X || !B) return (0) ; + + /* ---------------------------------------------------------------------- */ + /* symbolic ordering and analysis */ + /* ---------------------------------------------------------------------- */ + + Symbolic = klu_l_analyze (n, Ap, Ai, Common) ; + if (!Symbolic) return (0) ; + + if (isreal) + { + + /* ------------------------------------------------------------------ */ + /* factorization */ + /* ------------------------------------------------------------------ */ + + Numeric = klu_l_factor (Ap, Ai, Ax, Symbolic, Common) ; + if (!Numeric) + { + klu_l_free_symbolic (&Symbolic, Common) ; + return (0) ; + } + + /* ------------------------------------------------------------------ */ + /* statistics (not required to solve Ax=b) */ + /* ------------------------------------------------------------------ */ + + klu_l_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + klu_l_condest (Ap, Ax, Symbolic, Numeric, Common) ; + klu_l_rcond (Symbolic, Numeric, Common) ; + klu_l_flops (Symbolic, Numeric, Common) ; + *lunz = Numeric->lnz + Numeric->unz - n + + ((Numeric->Offp) ? (Numeric->Offp [n]) : 0) ; + + /* ------------------------------------------------------------------ */ + /* solve Ax=b */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < n ; i++) + { + X [i] = B [i] ; + } + klu_l_solve (Symbolic, Numeric, n, 1, X, Common) ; + + /* ------------------------------------------------------------------ */ + /* compute residual, rnorm = norm(b-Ax,1) / norm(A,1) */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < n ; i++) + { + R [i] = B [i] ; + } + for (j = 0 ; j < n ; j++) + { + asum = 0 ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + /* R (i) -= A (i,j) * X (j) */ + R [Ai [p]] -= Ax [p] * X [j] ; + asum += fabs (Ax [p]) ; + } + anorm = MAX (anorm, asum) ; + } + *rnorm = 0 ; + for (i = 0 ; i < n ; i++) + { + *rnorm = MAX (*rnorm, fabs (R [i])) ; + } + + /* ------------------------------------------------------------------ */ + /* free numeric factorization */ + /* ------------------------------------------------------------------ */ + + klu_l_free_numeric (&Numeric, Common) ; + + } + else + { + + /* ------------------------------------------------------------------ */ + /* statistics (not required to solve Ax=b) */ + /* ------------------------------------------------------------------ */ + + Numeric = klu_zl_factor (Ap, Ai, Ax, Symbolic, Common) ; + if (!Numeric) + { + klu_l_free_symbolic (&Symbolic, Common) ; + return (0) ; + } + + /* ------------------------------------------------------------------ */ + /* statistics */ + /* ------------------------------------------------------------------ */ + + klu_zl_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + klu_zl_condest (Ap, Ax, Symbolic, Numeric, Common) ; + klu_zl_rcond (Symbolic, Numeric, Common) ; + klu_zl_flops (Symbolic, Numeric, Common) ; + *lunz = Numeric->lnz + Numeric->unz - n + + ((Numeric->Offp) ? (Numeric->Offp [n]) : 0) ; + + /* ------------------------------------------------------------------ */ + /* solve Ax=b */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < 2*n ; i++) + { + X [i] = B [i] ; + } + klu_zl_solve (Symbolic, Numeric, n, 1, X, Common) ; + + /* ------------------------------------------------------------------ */ + /* compute residual, rnorm = norm(b-Ax,1) / norm(A,1) */ + /* ------------------------------------------------------------------ */ + + for (i = 0 ; i < 2*n ; i++) + { + R [i] = B [i] ; + } + for (j = 0 ; j < n ; j++) + { + asum = 0 ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + /* R (i) -= A (i,j) * X (j) */ + i = Ai [p] ; + REAL (R,i) -= REAL(Ax,p) * REAL(X,j) - IMAG(Ax,p) * IMAG(X,j) ; + IMAG (R,i) -= IMAG(Ax,p) * REAL(X,j) + REAL(Ax,p) * IMAG(X,j) ; + asum += CABS (Ax, p) ; + } + anorm = MAX (anorm, asum) ; + } + *rnorm = 0 ; + for (i = 0 ; i < n ; i++) + { + *rnorm = MAX (*rnorm, CABS (R, i)) ; + } + + /* ------------------------------------------------------------------ */ + /* free numeric factorization */ + /* ------------------------------------------------------------------ */ + + klu_zl_free_numeric (&Numeric, Common) ; + } + + /* ---------------------------------------------------------------------- */ + /* free symbolic analysis, and residual */ + /* ---------------------------------------------------------------------- */ + + klu_l_free_symbolic (&Symbolic, Common) ; + return (1) ; +} + + +/* ========================================================================== */ +/* === klu_l_demo =========================================================== */ +/* ========================================================================== */ + +/* Given a sparse matrix A, set up a right-hand-side and solve X = A\b */ + +static void klu_l_demo (UF_long n, UF_long *Ap, UF_long *Ai, double *Ax, + UF_long isreal) +{ + double rnorm ; + klu_l_common Common ; + double *B, *X, *R ; + UF_long i, lunz ; + + printf ("KLU: %s, version: %d.%d.%d\n", KLU_DATE, KLU_MAIN_VERSION, + KLU_SUB_VERSION, KLU_SUBSUB_VERSION) ; + + /* ---------------------------------------------------------------------- */ + /* set defaults */ + /* ---------------------------------------------------------------------- */ + + klu_l_defaults (&Common) ; + + /* ---------------------------------------------------------------------- */ + /* create a right-hand-side */ + /* ---------------------------------------------------------------------- */ + + if (isreal) + { + /* B = 1 + (1:n)/n */ + B = klu_l_malloc (n, sizeof (double), &Common) ; + X = klu_l_malloc (n, sizeof (double), &Common) ; + R = klu_l_malloc (n, sizeof (double), &Common) ; + if (B) + { + for (i = 0 ; i < n ; i++) + { + B [i] = 1 + ((double) i+1) / ((double) n) ; + } + } + } + else + { + /* real (B) = 1 + (1:n)/n, imag(B) = (n:-1:1)/n */ + B = klu_l_malloc (n, 2 * sizeof (double), &Common) ; + X = klu_l_malloc (n, 2 * sizeof (double), &Common) ; + R = klu_l_malloc (n, 2 * sizeof (double), &Common) ; + if (B) + { + for (i = 0 ; i < n ; i++) + { + REAL (B, i) = 1 + ((double) i+1) / ((double) n) ; + IMAG (B, i) = ((double) n-i) / ((double) n) ; + } + } + } + + /* ---------------------------------------------------------------------- */ + /* X = A\b using KLU and print statistics */ + /* ---------------------------------------------------------------------- */ + + if (!klu_l_backslash (n, Ap, Ai, Ax, isreal, B, X, R, &lunz, &rnorm, + &Common)) + { + printf ("KLU failed\n") ; + } + else + { + printf ("n %d nnz(A) %d nnz(L+U+F) %d resid %g\n" + "recip growth %g condest %g rcond %g flops %g\n", + n, Ap [n], lunz, rnorm, Common.rgrowth, Common.condest, + Common.rcond, Common.flops) ; + } + + /* ---------------------------------------------------------------------- */ + /* free the problem */ + /* ---------------------------------------------------------------------- */ + + if (isreal) + { + klu_l_free (B, n, sizeof (double), &Common) ; + klu_l_free (X, n, sizeof (double), &Common) ; + klu_l_free (R, n, sizeof (double), &Common) ; + } + else + { + klu_l_free (B, 2*n, sizeof (double), &Common) ; + klu_l_free (X, 2*n, sizeof (double), &Common) ; + klu_l_free (R, 2*n, sizeof (double), &Common) ; + } + printf ("peak memory usage: %g bytes\n\n", (double) (Common.mempeak)) ; +} + + +/* ========================================================================== */ +/* === main ================================================================= */ +/* ========================================================================== */ + +/* Read in a sparse matrix in Matrix Market format using CHOLMOD, and then + * solve Ax=b with KLU. Note that CHOLMOD is only used to read the matrix. */ + +#include "cholmod.h" + +int main (void) +{ + cholmod_sparse *A ; + cholmod_common ch ; + cholmod_l_start (&ch) ; + A = cholmod_l_read_sparse (stdin, &ch) ; + if (A) + { + if (A->nrow != A->ncol || A->stype != 0 + || (!(A->xtype == CHOLMOD_REAL || A->xtype == CHOLMOD_COMPLEX))) + { + printf ("invalid matrix\n") ; + } + else + { + klu_l_demo (A->nrow, A->p, A->i, A->x, A->xtype == CHOLMOD_REAL) ; + } + cholmod_l_free_sparse (&A, &ch) ; + } + cholmod_l_finish (&ch) ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/KLU/Doc/ChangeLog b/OpenDSSC/klusolve/KLU/Doc/ChangeLog new file mode 100644 index 0000000..26ab332 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Doc/ChangeLog @@ -0,0 +1,51 @@ +Nov 1, 2007, version 1.0.1 + + * minor lint cleanup + +May 31, 2007, version 1.0 + + * Overview: this is the first clean release of KLU. Only one bug was + fixed since in the last pre-1.0 version (see below). This release adds + a 64-bit version, a better Demo, a 100% statement coverage test, new + parameters and statistics in the KLU Common object, reduced memory + usage, a method for limiting worst-case work in the BTF ordering, and a + completely redesigned MATLAB interface. + + * scaling default changed from no scaling, to max row scaling + + * C-callable API modified for klu_malloc, klu_free, klu_realloc, klu_rcond, + klu_rgrowth, klu_condest. API of other user-callable KLU functions not + modified. + + * user ordering function prototype modified (final argument is now + klu_common, not Common->user_data) + + * User Guide added. + + * KLU Demo completely rewritten. Now depends on CHOLMOD to read in its + matrices, in Matrix Market format. + + * port to 64-bit version + + * reduction in memory usage, particularly when the BTF form results in + many small diagonal blocks + + * new Common parameter (maxwork) and statistics (work, memusage, mempeak) + + * Makefile and object files (*.o) now placed in KLU/Lib, not KLU/Source + + * added klu_install.m, klu_demo.m, klu_make.m to KLU/MATLAB. + + * klu mexFunction now returns a struct for LU, not a lengthy list of + matrices. MATLAB interface completely rewritten. + + * Tcov tests completely rewritten + + * bug fix in complex klu_z_refactor, when both btf and scaling are in use + + * bug fix in klu_rgrowth, when the matrix is scaled + +Dec 12, 2006: version 0.11 + + * minor MATLAB cleanup + diff --git a/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.bib b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.bib new file mode 100644 index 0000000..e69f199 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.bib @@ -0,0 +1,132 @@ +%------------------------------------------------------------------------------- + +@string{TOMS = "{ACM} Trans. Math. Software"} +@string{SIAMJSSC = "{SIAM} J. Sci. Statist. Comput."} +@string{SIMAX = "{SIAM} J. Matrix Anal. Appl."} +@string{SICOMP= "{SIAM} J. Comput."} +@string{SIAMJSC = "{SIAM} J. Sci. Comput."} + +@techreport{NagelPederson, + author={Nagel, L. W and Pederson, D. O.}, + title={{SPICE} (Simulation Program with Integrated Circuit Emphasis)}, + number={Memorandum No. ERL-M382}, + address={University of California, Berkeley}, year={1973}} + +@incollection{Kundert86, + author={Kundert, K. S.}, + year={1986}, + title={Sparse Matrix Techniques and Their Applications to Circuit Simulation}, + editor={Ruehli, A. E.}, + booktitle={Circuit Analysis, Simulation and Design}, + publisher={New York: North-Holland}} + +@techreport{KundertSangiovanniVincentelli85, + author={Kundert, K. S. and Sangiovanni-Vincentelli, A.}, + month={Oct.}, + year={1985}, + title={User's Guide: Sparse1.2}, + institution={Dept.~of EE and CS, UC Berkeley}, + keywords={ 31 Sparse1.2 software package direct methods}} + +@phdthesis{Quarles:M89/42, + Author = {Thomas L. Quarles}, + Title = {Analysis of Performance and Convergence Issues for Circuit Simulation}, + School = {EECS Department, University of California, Berkeley}, + Year = {1989}, + URL = {http://www.eecs.berkeley.edu/Pubs/TechRpts/1989/1216.html}, + Number = {UCB/ERL M89/42}} + +@book{Davis06book, + author={T. A. Davis}, + title={Direct Methods for Sparse Linear Systems}, + publisher={SIAM}, year={2006}, address={Philadelphia, PA}} + +@article{GilbertPeierls88, + author={Gilbert, J. R. and Peierls, T.}, + year={1988}, + title={Sparse Partial Pivoting in Time Proportional to Arithmetic Operations}, + journal=SIAMJSSC, volume={9}, pages={862-874}} + +@article{Duff78a, + author={Duff, I. S. and Reid, J. K.}, + year={1978}, + title={An Implementation of {Tarjan}'s Algorithm for the Block Triangularization of a Matrix}, + journal=TOMS, volume={4}, pages={137-147}} + +@article{Duff81, + author={Duff, I. S.}, + year={1981}, + title={On Algorithms for Obtaining a Maximum Transversal}, + journal=TOMS, volume={7}, pages={315-330}} + +@article{AmestoyDavisDuff96, + author={Amestoy, P. R. and Davis, T. A. and Duff, I. S.}, + title={An approximate minimum degree ordering algorithm}, + journal=SIMAX, year={1996}, volume={17}, pages={886--905}} + +@article{AmestoyDavisDuff03, + author={Amestoy, P. R. and Davis, T. A. and Duff, I. S.}, + title={Algorithm 837: {AMD}, an approximate minimum degree ordering algorithm}, + journal=TOMS, year={2004}, volume={30}, pages={381-388}} + +@article{Tarjan72, + author={Tarjan, R. E.}, + title={Depth first search and linear graph algorithms}, + journal=SICOMP, year={1972}, volume={1}, pages={146--160}} + +@article{DavisGilbertLarimoreNg00, + author={Davis, T. A. and Gilbert, J. R. and Larimore, S. I. and Ng, E. G.}, + title={A column approximate minimum degree ordering algorithm}, + journal=TOMS, year={2004}, volume={30}, pages={353-376}} + +@article{DavisGilbertLarimoreNg00_algo, + author={Davis, T. A. and Gilbert, J. R. and Larimore, S. I. and Ng, E. G.}, + title={Algorithm 836: {COLAMD}, a column approximate minimum degree ordering algorithm}, + journal=TOMS, year={2004}, volume={30}, pages={377-380}} + +@article{ChenDavisHagerRajamanickam06, + author={Chen, Y. and Davis, T. A. and Hager, W. W. and Rajamanickam, S.}, + title={Algorithm 8xx: {CHOLMOD}, supernodal sparse {Cholesky} factorization and update/downdate}, + journal=TOMS, note={(submitted)}, year={2006}} + +@article{KarypisKumar98e, + author={Karypis, G. and Kumar, V.}, + title={A fast and high quality multilevel scheme for partitioning irregular graphs}, + journal=SIAMJSC, year={1998}, volume={20}} + +@article{ACM679a, + author={Dongarra, J. J. and {Du Croz}, J. and Duff, I. S. and Hammarling, S.}, + title={A set of level-3 basic linear algebra subprograms}, + journal=TOMS, year={1990}, volume={16}, pages={1--17}} + +@article{SuperLU99, + author={Demmel, J. W. and Eisenstat, S. C. and Gilbert, J. R. and Li, X. S. and Liu, J. W. H.}, + title={A supernodal approach to sparse partial pivoting}, + journal=SIMAX, year={1999}, volume={20}, pages={720-755} } + +@article{Davis03, + author={Davis, T. A.}, + title={A column pre-ordering strategy for the unsymmetric-pattern multifrontal method}, + journal=TOMS, year={2004}, volume={30}, pages={165--195}} + +@article{Davis03_algo, + author={Davis, T. A.}, + title={Algorithm 832: {UMFPACK V4.3}, an unsymmetric-pattern multifrontal method}, + journal=TOMS, year={2002}, volume={30}, pages={196--199}} + +@article{Hager84, + author={Hager, W. W.}, + title={Condition estimates}, + journal=SIAMJSSC, year={1984},volume={5}, pages={311-316}} + +@article{HighamTisseur00, + author={Higham, N. J. and Tisseur, F.}, + title={A block algorithm for matrix 1-norm estimation with an application to 1-norm pseudospectra}, + journal=SIMAX, year={2000},volume={21},pages={1185--1201} } + +@techreport{Palamadai05, + author={Palamadai, E.}, + title={{KLU} - a high performance sparse linear system solver for + circuit simulation problems}, + note={M.S. Thesis}, + address={CISE Department, Univ. of Florida}} diff --git a/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.pdf b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.pdf new file mode 100644 index 0000000..8d98c23 Binary files /dev/null and b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.pdf differ diff --git a/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.tex b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.tex new file mode 100644 index 0000000..9a70a8c --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Doc/KLU_UserGuide.tex @@ -0,0 +1,1329 @@ +\documentclass[11pt]{article} + +\newcommand{\m}[1]{{\bf{#1}}} % for matrices and vectors +\newcommand{\tr}{^{\sf T}} % transpose + +\topmargin 0in +\textheight 9in +\oddsidemargin 0pt +\evensidemargin 0pt +\textwidth 6.5in + +%------------------------------------------------------------------------------ +\begin{document} +%------------------------------------------------------------------------------ + +\title{User Guide for KLU Version 1.0.1 and BTF Version 1.0.1} +\author{ +Timothy A. Davis\thanks{ +Dept.~of Computer and Information Science and Engineering, +Univ.~of Florida, Gainesville, FL, USA. +email: davis@cise.ufl.edu. +http://www.cise.ufl.edu/$\sim$davis. +This work was supported by Sandia National Labs, and the National +Science Foundation. +Portions of the work were done while on sabbatical at Stanford University +and Lawrence Berkeley National Laboratory (with funding from Stanford +University and the SciDAC program). +} +\and Eka Palamadai} + +\date{Nov 1, 2007} +\maketitle + +%------------------------------------------------------------------------------ +\begin{abstract} +KLU is a set of routines for solving sparse linear systems of equations. +It is particularly well-suited to matrices arising in SPICE-like circuit +simulation applications. +It relies on a permutation to block triangular form (BTF), several methods +for finding a fill-reducing ordering (variants of approximate minimum degree, +and nested dissection), and a sparse left-looking LU factorization method +to factorize each block. A MATLAB interface is included. +\end{abstract} +%------------------------------------------------------------------------------ + +\newpage +\tableofcontents +\newpage + +%------------------------------------------------------------------------------ +\section{License and Copyright} +%------------------------------------------------------------------------------ + +KLU Version 1.0.1, Copyright\copyright 2007 University of Florida. +All Rights Reserved. +KLU is available under alternate licenses; contact T. Davis for details. + +{\bf KLU License:} + Your use or distribution of KLU or any modified version of + KLU implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + +{\bf Availability:} + + {\tt http://www.cise.ufl.edu/research/sparse/klu} + + {\tt http://www.cise.ufl.edu/research/sparse/btf} + +{\bf Acknowledgments:} + + This work was supported by Sandia National Laboratories (Mike Heroux) + and the National Science Foundation under grants 0203270 and 0620286. + + +%------------------------------------------------------------------------------ +\newpage +\section{Overview} +%------------------------------------------------------------------------------ + +KLU is a set of routines for solving sparse linear systems of equations. It +first permutes the matrix into upper block triangular form, via the BTF +package. This is done by first finding a permutation for a zero-free diagonal +(a maximum transversal) \cite{Duff81}. If there is no such permutation, then +the matrix is structurally rank-deficient, and is numerically singular. Next, +Tarjan's method \cite{Duff78a,Tarjan72} is used to find the strongly-connected +components of the graph. The block triangular form is essentially unique; any +method will lead to the same number and sizes of blocks, although the ordering +of the blocks may vary (consider a diagonal matrix, for example). Assuming the +matrix has full structural rank, the permuted matrix has the following form: +\[ +PAQ = +\left[ +\begin{array}{ccc} +A_{11} & \cdots & A_{1k} \\ + & \ddots & \vdots \\ + & & A_{kk} \\ +\end{array} +\right], +\] +where each diagonal block is square with a zero-free diagonal. + +Next, each diagonal block is factorized with a sparse left-looking method +\cite{GilbertPeierls88}. The kernel of this factorization method is an +efficient method for solving $Lx=b$ when $L$, $x$, and $b$ are all sparse. +This kernel is used to compute each column of $L$ and $U$, one column at a time. +The total work performed by this method is always proportional to the number of +floating-point operations, something that is not true of any other sparse LU +factorization method. + +Prior to factorizing each diagonal block, the blocks are ordered to reduce +fill-in. By default, the symmetric approximate minimum degree (AMD) ordering +is used on $A_{ii}+A_{ii}^T$ \cite{AmestoyDavisDuff96,AmestoyDavisDuff03}. +Another ordering option is to find a column ordering via COLAMD +\cite{DavisGilbertLarimoreNg00_algo,DavisGilbertLarimoreNg00}. +Alternatively, a permutation can be provided by the user, or a pointer to +a user-provided ordering function can be passed, which is then used to order +each block. + +Only the diagonal blocks need to be factorized. Consider a linear system where +the matrix is permuted into three blocks, for example: +\[ +\left[ +\begin{array}{ccc} +A_{11} & A_{12} & A_{13} \\ + & A_{22} & A_{23} \\ + & & A_{33} \\ +\end{array} +\right] +\left[ +\begin{array}{c} +x_{1} \\ +x_{2} \\ +x_{3} \\ +\end{array} +\right] += +\left[ +\begin{array}{c} +b_{1} \\ +b_{2} \\ +b_{3} \\ +\end{array} +\right]. +\] + +The non-singular system $A_{33} x_{3} = b_{3}$ can first be solved for $x_{3}$. +After a block back substitution, the resulting system becomes +\[ +\left[ +\begin{array}{cc} +A_{11} & A_{12} \\ + & A_{22} \\ +\end{array} +\right] +\left[ +\begin{array}{c} +x_{1} \\ +x_{2} \\ +\end{array} +\right] += +\left[ +\begin{array}{c} +b_{1} - A_{13} x_{3}\\ +b_{2} - A_{23} x_{3}\\ +\end{array} +\right] += +\left[ +\begin{array}{c} +b'_{1} \\ +b'_{2} \\ +\end{array} +\right] +\] +and the $A_{22} x_{2} = b'_{2}$ system can be solved for $x_{2}$. The primary +advantage of this method is that no fill-in occurs in the off-diagonal blocks +($A_{12}$, $A_{13}$, and $A_{23}$). This is particular critical for sparse +linear systems arising in SPICE-like circuit simulation +\cite{Kundert86,KundertSangiovanniVincentelli85,NagelPederson,Quarles:M89/42}. +Circuit matrices are typically permutable into block triangular form, with many +singletons (1-by-1 blocks). They also often have a handful of rows and columns +with many nonzero entries, due to voltage and current sources. These rows and +columns are pushed into the upper block triangular form, and related to the +singleton blocks (for example, $A_{33}$ in the above system is 1-by-1, and the +column in $A_{13}$ and $A_{23}$ has many nonzero entries). Since these +nearly-dense rows and columns do not appear in the LU factorization of the +diagonal blocks, they cause no fill-in. + +The structural rank of a matrix is based solely on the pattern of its entries, +not their numerical values. With random entries, the two ranks are equal with +probability one. The structural rank of any matrix is an upper bound on the +numerical rank. The maximum transversal algorithm in the BTF package is useful +in determining if a matrix is structurally rank deficient, and if so, it +reveals a (non-unique) set of rows and columns that contribute to that rank +deficiency. This is useful in determining what parts of a circuit are poorly +formulated (such as dangling components). + +When ordered and factorized with KLU, very little fill-in occurs in the +resulting LU factors, which means that there is little scope for use of the +BLAS \cite{ACM679a}. Sparse LU factorization methods that use the BLAS (such +as SuperLU \cite{SuperLU99} amd UMFPACK \cite{Davis03_algo,Davis03}) are slower +than KLU when applied to sparse matrices arising in circuit simulation. Both +KLU and SuperLU are based on Gilbert and Peierl's left-looking method +\cite{GilbertPeierls88}. SuperLU uses supernodes, but KLU does not; thus the +name {\em KLU} refers to a ``Clark Kent'' LU factorization algorithm (what +SuperLU was before it became Super). + +For details of the permutation to block triangular form, left-looking sparse +LU factorization, and approximate minimum degree, refer to \cite{Davis06book}. +Concise versions of these methods can be found in the CSparse package. KLU is +also the topic of a Master's thesis by Palamadai \cite{Palamadai05}; a copy of +the thesis can be found in the {\tt KLU/Doc} directory. It includes a +description of an earlier version of KLU; some of the function names and +parameter lists have changed in this version. The descriptions of the methods +used still applies to the current version of KLU, however. + +%------------------------------------------------------------------------------ +\section{Availability} +%------------------------------------------------------------------------------ + +KLU and its required ordering packages (BTF, COLAMD, AMD, and UFconfig) are +available at \newline {\tt http://www.cise.ufl.edu/research/sparse.} In +addition, KLU can make use of any user-provided ordering function. One such +function is included, which provides KLU with an interface to the ordering +methods used in CHOLMOD \cite{ChenDavisHagerRajamanickam06}, such as METIS, a +nested dissection method \cite{KarypisKumar98e}. After permutation to block +triangular form, circuit matrices have very good node separators, and are thus +excellent candidates for nested dissection. The METIS ordering takes much more +time to compute than the AMD ordering, but if the ordering is reused many times +(typical in circuit simulation) the better-quality ordering can pay off in +lower total simulation time. + +To use KLU, you must obtain the KLU, BTF, UFconfig, AMD, and COLAMD packages +in the SuiteSparse suite of sparse matrix libraries. See +{\tt http://www.cise.ufl.edu/research/sparse} for each of these packages. +They are also all contained within the single {\tt SuiteSparse.zip} or +{\tt SuiteSparse.tar.gz} distribution. + +%------------------------------------------------------------------------------ +\section{Using KLU and BTF in MATLAB} +%------------------------------------------------------------------------------ + +KLU has a single MATLAB interface which provides several options for factorizing +a matrix and/or using the factors to solve a linear system. The following is +a synopsis of its use. For more details, type {\tt help klu} in MATLAB. + +{\footnotesize +\begin{verbatim} + LU = klu (A) factorizes R\A(p,q) into L*U+F, returning a struct + x = klu (A,'\',b) x = A\b + x = klu (b,'/',A) x = b/A + x = klu (LU,'\',b) x = A\b, where LU = klu(A) + x = klu (b,'/',LU) x = b/A, where LU = klu(A) +\end{verbatim} +} + +With a single input {\tt klu(A)} returns a MATLAB struct containing the LU +factors. The factorization is in the form \verb'L*U + F = R \ A(p,q)' +where {\tt L*U} is the LU factorization of just the diagonal blocks of the +block triangular form, {\tt F} is a sparse matrix containing the entries in +the off-diagonal blocks, {\tt R} is a diagonal matrix containing the row +scale factors, and {\tt p} and {\tt q} are permutation vectors. The {\tt LU} +struct also contains a vector {\tt r} which describes the block boundaries +(the same as the third output parameter of {\tt dmperm}). The {\tt k}th +block consists of rows and columns {\tt r(k)} to {\tt r(k+1)-1} in the +permuted matrix {\tt A(p,q)} and the factors {\tt L} and {\tt U}. + +An optional final input argument ({\tt klu(A,opts)} for example) provides a +way of modifying KLU's user-definable parameters, including a partial pivoting +tolerance and ordering options. A second output argument +({\tt [LU,info] = klu ( ... )}) provides statistics on the factorization. + +The BTF package includes three user-callable MATLAB functions which replicate +most of features of the MATLAB built-in {\tt dmperm} function, and provide an +additional option which can significantly limit the worst-case time taken by +{\tt dmperm}. For more details, type {\tt help btf}, {\tt help maxtrans}, +and {\tt help strongcomp} in MATLAB. Additional information about how +these functions work can be found in \cite{Davis06book}. + +{\footnotesize +\begin{verbatim} + [p,q,r] = btf (A) similar to [p,q,r] = dmperm (A) + q = maxtrans (A) similar to q = dmperm (A') + [p,r] = strongcomp (A) similar to [p,q,r] = dmperm (A + speye(n)) +\end{verbatim} +} + +Both {\tt btf} and {\tt maxtrans} include a second option input, {\tt maxwork}, +which limits the total work performed in the maximum transversal to +{\tt maxwork * nnz(A)}. The worst-case time taken by the algorithm is +$O$ ({\tt n * nnz(A)}), where the matrix {\tt A} is {\tt n}-by-{\tt n}, but +this worst-case time is rarely reached in practice. + +To use the KLU and BTF functions in MATLAB, you must first compile and install +them. In the {\tt BTF/MATLAB} directory, type {\tt btf\_install}, and then +type {\tt klu\_install} in the {\tt KLU/MATLAB} directory. Alternatively, if +you have the entire SuiteSparse, simply run the {\tt SuiteSparse\_install} +function in the {\tt SuiteSparse} directory. To use METIS 4.0.1 with KLU (and +CHOLMOD, another part of SuiteSparse) you must first download it from {\tt +http://glaros.dtc.umn.edu/gkhome/views/metis} and place the {\tt metis-4.0} +directory in the {\tt SuiteSparse} directory, alongside the {\tt KLU} and {\tt +BTF} directories. + +After running the installation scripts, type {\tt pathtool} and save your path +for future MATLAB sessions. If you cannot save your path because of file +permissions, edit your {\tt startup.m} by adding {\tt addpath} commands (type +{\tt doc startup} and {\tt doc addpath} for more information). + +%------------------------------------------------------------------------------ +\section{Using KLU and BTF in a C program} +\label{Cversion} +%------------------------------------------------------------------------------ + +KLU and BTF include the following C-callable functions. Each function is +available in two or four versions: with {\tt int} or {\tt long} integers, and +(for functions that deal with numerical values), with {\tt double} or complex +{\tt double} values. The {\tt long} integer is actually a {\tt UF\_long}, +which is typically a {\tt long}, defined with a {\tt \#define} statement. It +becomes an {\tt \_\_int64} on Microsoft Windows 64, however. + +The usage of real and complex, and {\tt int} and {\tt UF\_long}, must not be +mixed, except that some functions can be used for both real and complex cases. + +%------------------------------------------------------------------------------ +\subsection{KLU Common object} +%------------------------------------------------------------------------------ + +The {\tt klu\_common} object ({\tt klu\_l\_common} for the {\tt UF\_long} +version) contains user-definable parameters and statistics returned from +KLU functions. This object appears in every KLU function as the last +parameter. Details are given in the {\tt klu.h} include file, which also +appears below in Section~\ref{klu_include}. Primary parameters and statistics +are summarized below. The defaults are chosen specifically for circuit +simulation matrices. + +\begin{itemize} +\item {\tt tol}: partial pivoting tolerance. If the diagonal entry has a +magnitude greater than or equal to {\tt tol} times the largest magnitude +of entries in the pivot column, then the diagonal entry is chosen. +Default value: 0.001. + +\item {\tt ordering}: which fill-reducing ordering to use: 0 for AMD, +1 for COLAMD, 2 for a user-provided permutation {\tt P} and {\tt Q} +(or a natural ordering if {\tt P} and {\tt Q} are NULL), or 3 for +the {\tt user\_order} function. Default: 0 (AMD). + +\item {\tt scale}: whether or not the matrix should be scaled. +If {\tt scale < 0}, then no scaling is performed and the input matrix +is not checked for errors. If {\tt scale >= 0}, the input matrix is +check for errors. +If {\tt scale=0}, then no scaling is performed. +If {\tt scale=1}, then each row of {\tt A} is divided by the sum of +the absolute values in that row. +If {\tt scale=2}, then each row of {\tt A} is divided by the maximum +absolute value in that row. Default: 2. + +\item {\tt btf}: if nonzero, then BTF is used to permute the input matrix +into block upper triangular form. This step is skipped if {\tt Common.btf} +is zero. Default: 1. + +\item {\tt maxwork}: sets an upper limit on the amount of work performed in +{\tt btf\_maxtrans} to \newline {\tt maxwork*nnz(A)}. If the limit is reached, +a partial zero-free diagonal might be found. This has no effect on whether or +not the matrix can be factorized, since the matrix can be factorized with no +BTF pre-ordering at all. This option provides a tradeoff between the +effectiveness of the BTF ordering and the cost to compute it. A partial result +can result in fewer, and larger, blocks in the BTF form, resulting to more work +required to factorize the matrix. No limit is enforced if {\tt maxwork <= 0}. +Default: 0. + +\item {\tt user\_order}: a pointer to a function that can be provided by the +application that uses KLU, to redefine the fill-reducing ordering used by KLU +for each diagonal block. The {\tt int} and {\tt UF\_long} prototypes must be +as follows: + +{\footnotesize +\begin{verbatim} +int my_ordering_function (int n, int Ap [ ], int Ai [ ], int Perm [ ], klu_common *Common) ; + + +UF_long my_long_ordering_function (UF_long n, UF_long Ap [ ], UF_long Ai [ ], + UF_long Perm [ ], klu_l_common *Common); +\end{verbatim} +} + +The function should return 0 if an error occurred, and either -1 or a positive +(nonzero) value if no error occurred. If greater than zero, then the return +value is interpreted by KLU as an estimate of the number of nonzeros in $L$ or +$U$ (whichever is greater), when the permuted matrix is factorized. Only an +estimate is possible, since partial pivoting with row interchanges is performed +during numerical factorization. The input matrix is provided to the function +in the parameters {\tt n}, {\tt Ap}, and {\tt Ai}, in compressed-column form. +The matrix {\tt A} is {\tt n}-by-{\tt n}. The {\tt Ap} array is of size {\tt +n+1}; the {\tt j}th column of {\tt A} has row indices {\tt Ai[Ap[j] ... +Ap[j+1]-1]}. The {\tt Ai} array is of size {\tt Ap[n]}. The first column +pointer {\tt Ap[0]} is zero. The row indices might not appear sorted in each +column, but no duplicates will appear. + +The output permutation is to be passed back in the {\tt Perm} array, where +{\tt Perm[k]=j} means that row and column {\tt j} of {\tt A} will appear as +the {\tt k}th row and column of the permuted matrix factorized by KLU. The +{\tt Perm} array is already allocated when it is passed to the user function. + +The user function may use, and optionally modify, the contents of the {\tt +klu\_common Common} object. In particular, prior to calling KLU, the user +application can set both {\tt Common.user\_order} and {\tt Common.user\_data}. +The latter is a {\tt void *} pointer that KLU does not use, except to pass to +the user ordering function pointed to by {\tt Common.user\_order}. This is a +mechanism for passing additional arguments to the user function. + +An example user function is provided in the {\tt KLU/User} directory, which +provides an interface to the ordering method in CHOLMOD. + +\end{itemize} + +%------------------------------------------------------------------------------ +\subsection{KLU Symbolic object} +%------------------------------------------------------------------------------ + +KLU performs its sparse LU factorization in two steps. The first is purely +symbolic, and does not depend on the numerical values. This analysis returns a +{\tt klu\_symbolic} object ({\tt klu\_l\_symbolic} in the {\tt UF\_long} +version). The {\tt Symbolic} object contains a pre-ordering which combines the +block triangular form with the fill-reducing ordering, and an estimate of the +number of nonzeros in the factors of each block. Its size is thus modest, only +proportional to {\tt n}, the dimension of {\tt A}. It can be reused multiple +times for the factorization of a sequence of matrices with identical nonzero +pattern. Note: a {\em nonzero} in this sense is an entry present in the data +structure of {\tt A}; such entries may in fact be numerically zero. + +%------------------------------------------------------------------------------ +\subsection{KLU Numeric object} +%------------------------------------------------------------------------------ + +The {\tt Numeric} object contains the numeric sparse LU factorization, including +the final pivot permutations. To solve a linear system, both the {\tt Symbolic} +and {\tt Numeric} objects are required. + +%------------------------------------------------------------------------------ +\subsection{A sparse matrix in KLU} +%------------------------------------------------------------------------------ + +% From here on, only the {\tt int} version is described. In the {\tt UF\_long} +% version, the function names change slightly ({\tt klu\_factor} becomes +% {\tt klu\_l\_factor}, and the {\tt int}/complex version {\tt klu\_z\_factor} +% becomes {\tt klu\_zl\_factor}, for example). For more details on the +% {\tt UF\_long} version, refer to Section~\ref{klu_include}. + +The input matrix provided to KLU is in sparse compressed-column form, which is +the same data structure used internally in MATLAB, except that the version used +here allows for the row indices to appear in any ordering, and this version +also allows explicit zero entries to appear in the data structure. The same +data structure is used in CSparse, which is fully documented in +\cite{Davis06book}. If you wish to use a simpler input data structure, +consider creating a triplet matrix in CSparse (or CXSparse if you use the long +and/or complex versions of KLU), and then convert this data structure into a +sparse compressed-column data structure, using the CSparse {\tt cs\_compress} +and {\tt cs\_dupl} functions. Similar functions are available in CHOLMOD +{\tt cholmod\_triplet\_to\_sparse}. + +The matrix is described with four parameters: + +\begin{itemize} +\item {\tt n}: an integer scalar. The matrix is {\tt n}-by-{\tt n}. Note that +KLU only operates on square matrices. + +\item {\tt Ap}: an integer array of size {\tt n+1}. The first entry is {\tt +Ap[0]=0}, and the last entry {\tt nz=Ap[n]} is equal to the number of entries +in the matrix. + +\item {\tt Ai}: an integer array of size {\tt nz = Ap[n]}. +The row indices of entries in column {\tt j} of {\tt A} are located in +{\tt Ai [Ap [j] ... Ap [j+1]-1]}. The matrix is zero-based; row and column +indices are in the range 0 to {\tt n-1}. + +\item {\tt Ax}: a {\tt double} array of size {\tt nz} for the real case, or +{\tt 2*nz} for the complex case. For the complex case, the real and imaginary +parts are interleaved, compatible with Fortran and the ANSI C99 Complex data +type. KLU does not rely on the ANSI C99 data type, however, for portability +reasons. The numerical values in column {\tt j} of a real matrix are located +in {\tt Ax [Ap [j] ... Ap [j+1]-1]}. For a complex matrix, they appear in {\tt +Ax [2*Ap [j] ... 2*Ap [j+1]-1]}, as real/imaginary pairs (the real part appears +first, followed by the imaginary part). + +\end{itemize} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_defaults}: set default parameters} +%------------------------------------------------------------------------------- + +This function sets the default parameters for KLU and clears the statistics. +It may be used for either the real or complex cases. A value of 0 is returned +if an error occurs, 1 otherwise. This function {\bf must} be called before +any other KLU function can be called. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok ; + klu_common Common ; + ok = klu_defaults (&Common) ; /* real or complex */ + + + #include "klu.h" + UF_long ok ; + klu_l_common Common ; + ok = klu_l_defaults (&Common) ; /* real or complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_analyze}: order and analyze a matrix} +%------------------------------------------------------------------------------- + +The following usage returns a {\tt Symbolic} object that contains the +fill-reducing ordering needed to factorize the matrix {\tt A}. A NULL pointer +is returned if a failure occurs. The error status for this function, and all +others, is returned in {\tt Common.status}. These functions may be used for +both real and complex cases. The AMD ordering is used if {\tt Common.ordering += 0}, COLAMD is used if it is 1, the natural ordering is used if it is 2, and +the user-provided {\tt Common.user\_ordering} is used if it is 3. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int n, Ap [n+1], Ai [nz] ; + klu_symbolic *Symbolic ; + klu_common Common ; + Symbolic = klu_analyze (n, Ap, Ai, &Common) ; /* real or complex */ + + + #include "klu.h" + UF_long n, Ap [n+1], Ai [nz] ; + klu_l_symbolic *Symbolic ; + klu_l_common Common ; + Symbolic = klu_l_analyze (n, Ap, Ai, &Common) ; /* real or complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_analyze\_given}: order and analyze a matrix} +%------------------------------------------------------------------------------- + +In this routine, the fill-reducing ordering is provided by the user ({\tt +Common.ordering} is ignored). Instead, the row permutation {\tt P} and column +permutation {\tt Q} are used. These are integer arrays of size {\tt n}. If +NULL, a natural ordering is used (so to provide just a column ordering, pass +{\tt Q} as non-NULL and {\tt P} as NULL). A NULL pointer is returned if an +error occurs. These functions may be used for both real and complex cases. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int n, Ap [n+1], Ai [nz], P [n], Q [n] ; + klu_symbolic *Symbolic ; + klu_common Common ; + Symbolic = klu_analyze_given (n, Ap, Ai, P, Q, &Common) ; /* real or complex */ + + + #include "klu.h" + UF_long n, Ap [n+1], Ai [nz], P [n], Q [n] ; + klu_l_symbolic *Symbolic ; + klu_l_common Common ; + Symbolic = klu_l_analyze_given (n, Ap, Ai, P, Q, &Common) ; /* real or complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_factor}: numerical factorization} +%------------------------------------------------------------------------------- + +The {\tt klu\_factor} function factorizes a matrix, using a sparse left-looking +method with threshold partial pivoting. The inputs {\tt Ap} and {\tt Ai} must +be unchanged from the previous call to {\tt klu\_analyze} that created the {\tt +Symbolic} object. A NULL pointer is returned if an error occurs. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; /* real */ + Numeric = klu_z_factor (Ap, Ai, Az, Symbolic, &Common) ; /* complex */ + + + #include "klu.h" + UF_long Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + Numeric = klu_l_factor (Ap, Ai, Ax, Symbolic, &Common) ; /* real */ + Numeric = klu_zl_factor (Ap, Ai, Az, Symbolic, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_solve}: solve a linear system} +%------------------------------------------------------------------------------- + +Solves the linear system $Ax=b$, using the {\tt Symbolic} and {\tt Numeric} +objects. The right-hand side {\tt B} is overwritten with the solution on +output. The array {\tt B} is stored in column major order, with a leading +dimension of {\tt ldim}, and {\tt nrhs} columns. Thus, the real entry $b_{ij}$ +is stored in {\tt B [i+j*ldim]}, where {\tt ldim >= n} must hold. A complex +entry $b_{ij}$ is stored in {\tt B [2*(i+j*ldim)]} and {\tt B [2*(i+j*ldim)+1]} +(for the real and imaginary parts, respectively). Returns 1 if successful, +0 if an error occurs. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ldim, nrhs, ok ; + double B [ldim*nrhs], Bz [2*ldim*nrhs] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_solve (Symbolic, Numeric, ldim, nrhs, B, &Common) ; /* real */ + ok = klu_z_solve (Symbolic, Numeric, ldim, nrhs, Bz, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ldim, nrhs, ok ; + double B [ldim*nrhs], Bz [2*ldim*nrhs] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_l_solve (Symbolic, Numeric, ldim, nrhs, B, &Common) ; /* real */ + ok = klu_zl_solve (Symbolic, Numeric, ldim, nrhs, Bz, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_tsolve}: solve a transposed linear system} +%------------------------------------------------------------------------------- + +Solves the linear system $A^Tx=b$ or $A^Hx=b$. The {\tt conj\_solve} input +is 0 for $A^Tx=b$, or nonzero for $A^Hx=b$. Otherwise, the function is +identical to {\tt klu\_solve}. + + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ldim, nrhs, ok ; + double B [ldim*nrhs], Bz [2*ldim*nrhs] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_tsolve (Symbolic, Numeric, ldim, nrhs, B, &Common) ; /* real */ + ok = klu_z_tsolve (Symbolic, Numeric, ldim, nrhs, Bz, conj_solve, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ldim, nrhs, ok ; + double B [ldim*nrhs], Bz [2*ldim*nrhs] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_l_tsolve (Symbolic, Numeric, ldim, nrhs, B, &Common) ; /* real */ + ok = klu_zl_tsolve (Symbolic, Numeric, ldim, nrhs, Bz, conj_solve, &Common) ; /* complex */ +\end{verbatim} +} + + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_refactor}: numerical refactorization} +%------------------------------------------------------------------------------- + +The {\tt klu\_refactor} function takes as input the {\tt Numeric} object +created by {\tt klu\_factor} (or as modified by a previous call to {\tt +klu\_refactor}). It factorizes a new matrix with the same nonzero pattern as +that given to the call to {\tt klu\_factor} which created it. The same pivot +order is used. Since this can lead to numeric instability, the use of {\tt +klu\_rcond}, {\tt klu\_rgrowth}, or {\tt klu\_condest} is recommended to check +the accuracy of the resulting factorization. The inputs {\tt Ap} and {\tt Ai} +must be unmodified since the call to {\tt klu\_factor} that first created the +{\tt Numeric} object. This is function is much faster than {\tt klu\_factor}, +and requires no dynamic memory allocation. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok, Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_refactor (Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok, Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_refactor (Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_free\_symbolic}: destroy the {\tt Symbolic} object} +%------------------------------------------------------------------------------- + +It is the user's responsibility to destroy the {\tt Symbolic} object when it is +no longer needed, or else a memory leak will occur. It is safe to pass a NULL +{\tt Symbolic} pointer. These functions may be used for both real and complex +cases. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + klu_symbolic *Symbolic ; + klu_common Common ; + klu_free_symbolic (&Symbolic, &Common) ; /* real or complex */ + + + #include "klu.h" + klu_l_symbolic *Symbolic ; + klu_l_common Common ; + klu_l_free_symbolic (&Symbolic, &Common) ; /* real or complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_free\_numeric}: destroy the {\tt Numeric} object} +%------------------------------------------------------------------------------- + +It is the user's responsibility to destroy the {\tt Numeric} object when it is +no longer needed, or else a memory leak will occur. It is safe to pass a NULL +{\tt Numeric} pointer. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + klu_numeric *Numeric ; + klu_common Common ; + klu_free_numeric (&Numeric, &Common) ; /* real */ + klu_z_free_numeric (&Numeric, &Common) ; /* complex */ + + + #include "klu.h" + klu_l_numeric *Numeric ; + klu_l_common Common ; + klu_l_free_numeric (&Numeric, &Common) ; /* real */ + klu_zl_free_numeric (&Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_sort}: sort the columns of L and U} +%------------------------------------------------------------------------------- + +The {\tt klu\_factor} function creates a {\tt Numeric} object with factors +{\tt L} and {\tt U} stored in a compressed-column form (not the same data +structure as {\tt A}, but similar). The columns typically contain lists of +row indices in unsorted order. This function sorts these indices, for two +purposes: (1) to return {\tt L} and {\tt U} to MATLAB, which expects its +sparse matrices to have sorted columns, and (2) to slightly improve the +performance of subsequent calls to {\tt klu\_solve} and {\tt klu\_tsolve}. +Except within a MATLAB mexFunction (see {\tt KLU/MATLAB/klu\_mex.c}, the use +of this function is optional. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_sort (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_sort (Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_sort (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_sort (Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_flops}: determine the flop count} +%------------------------------------------------------------------------------- + +This function determines the number of floating-point operations performed +when the matrix was factorized by {\tt klu\_factor} or {\tt klu\_refactor}. +The result is returned in {\tt Common.flops}. + + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_flops (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_flops (Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_flops (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_flops (Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_rgrowth}: determine the pivot growth} +%------------------------------------------------------------------------------- + +Computes the reciprocal pivot growth, +$\mbox{\em rgrowth} = \min_j (( \max_i |c_{ij}| ) / ( \max_i |u_{ij}| ))$, +where $c_{ij}$ is a scaled entry in a diagonal block of the block triangular +form. In MATLAB notation: +\begin{verbatim} + rgrowth = min (max (abs (R\A(p,q) - F)) ./ max (abs (U))) +\end{verbatim} +where the factorization is \verb'L*U + F = R \ A(p,q)'. +This function returns 0 if an error occurred, 1 otherwise. If {\tt rgrowth} is +very small, an inaccurate factorization may have been performed. The inputs +{\tt Ap}, {\tt Ai}, and {\tt Ax} ({\tt Az} in the complex case) must be +unchanged since the last call to {\tt klu\_factor} or {\tt klu\_refactor}. The +result is returned in {\tt Common.rgrowth}. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok, Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_rgrowth (Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok, Ap [n+1], Ai [nz] ; + double Ax [nz], Az [2*nz] ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_rgrowth (Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_condest}: accurate condition number estimation} +%------------------------------------------------------------------------------- + +This function is essentially the same as the MATLAB {\tt condest} function. It +computes an estimate of the 1-norm condition number, using Hager's method +\cite{Hager84} and the generalization by Higham and Tisseur +\cite{HighamTisseur00}. The inputs {\tt Ap}, and {\tt Ax} ({\tt Az} in the +complex case) must be unchanged since the last call to {\tt klu\_factor} or +{\tt klu\_refactor}. The result is returned in {\tt Common.condest}. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok, Ap [n+1] ; + double Ax [nz], Az [2*nz] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_condest (Ap, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_condest (Ap, Az, Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok, Ap [n+1] ; + double Ax [nz], Az [2*nz] ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_condest (Ap, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_condest (Ap, Az, Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_rcond}: cheap reciprocal condition number estimation} +%------------------------------------------------------------------------------- + +This function returns the smallest diagonal entry of {\tt U} divided by the +largest, which is a very crude estimate of the reciprocal of the condition +number of the matrix {\tt A}. It is very cheap to compute, however. +In MATLAB notation, {\tt rcond = min(abs(diag(U))) / max(abs(diag(U)))}. +If the matrix is singular, {\tt rcond} will be zero. The result is returned +in {\tt Common.rcond}. + + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_rcond (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_rcond (Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_rcond (Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_rcond (Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_scale}: scale and check a sparse matrix} +%------------------------------------------------------------------------------- + +This function computes the row scaling factors of a matrix and checks to see if +it is a valid sparse matrix. It can perform two kinds of scaling, computing +either the largest magnitude in each row, or the sum of the magnitudes of the +entries each row. KLU calls this function itself, depending upon the {\tt +Common.scale} parameter, where {\tt scale < 0} means no scaling, {\tt scale=1} +means the sum, and {\tt scale=2} means the maximum. That is, in MATLAB +notation, {\tt Rs = sum(abs(A'))} or {\tt Rs = max(abs(A'))}. KLU then divides +each row of {\tt A} by its corresponding scale factor. The function returns 0 +if the matrix is invalid, or 1 otherwise. A valid sparse matrix must meet the +following conditions: + +\begin{enumerate} +\item {\tt n > 0}. Note that KLU does not handle empty (0-by-0) matrices. +\item {\tt Ap}, {\tt Ai}, and {\tt Ax} ({\tt Az} for the complex case) must not be NULL. +\item {\tt Ap[0]=0}, and {\tt Ap [j] <= Ap [j+1]} for all {\tt j} in the range 0 to {\tt n-1}. +\item The row indices in each column, {\tt Ai [Ap [j] ... Ap [j+1]-1]}, must be in +the range 0 to {\tt n-1}, and no duplicates can appear. If the workspace {\tt W} is +NULL on input, the check for duplicate entries is skipped. +\end{enumerate} + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int scale, ok, n, Ap [n+1], Ai [nz], W [n] ; + double Ax [nz], Az [2*nz], Rs [n] ; + klu_common Common ; + ok = klu_scale (scale, n, Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_z_scale (scale, n, Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ + + + #include "klu.h" + UF_long scale, ok, n, Ap [n+1], Ai [nz], W [n] ; + double Ax [nz], Az [2*nz], Rs [n] ; + klu_l_common Common ; + ok = klu_l_scale (scale, n, Ap, Ai, Ax, Symbolic, Numeric, &Common) ; /* real */ + ok = klu_zl_scale (scale, n, Ap, Ai, Az, Symbolic, Numeric, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_extract}: extract the LU factorization} +%------------------------------------------------------------------------------- + +This function extracts the LU factorization into a set of data structures +suitable for passing back to MATLAB, with matrices in conventional +compressed-column form. The {\tt klu\_sort} function should be called first if +the row indices should be returned sorted. The factorization is returned in +caller-provided arrays; if any of them are NULL, that part of the factorization +is not extracted (this is not an error). Returns 1 if successful, 0 otherwise. + +The sizes of {\tt Li}, {\tt Lx}, and {\tt Lz} are {\tt Numeric->lnz}, +{\tt Ui}, {\tt Ux}, and {\tt Uz} are of size {\tt Numeric->unz}, and +{\tt Fi}, {\tt Fx}, and {\tt Fz} are of size {\tt Numeric->nzoff}. +Note that in the complex versions, the real and imaginary parts are returned +in separate arrays, to be compatible with how MATLAB stores complex matrices. + +This function is not required to solve a linear system with KLU. KLU does not +itself make use of the extracted LU factorization returned by this function. +It is only provided to simplify the MATLAB interface to KLU, and it may be of +use to the end user who wishes to examine the contents of the LU factors. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + int ok, Lp [n+1], Li [lnz], Up [n+1], Ui [unz], Fp [n+1], Fi [nzoff], P [n], Q [n], R [n] ; + double Lx [lnz], Lz [lnz], Ux [unz], Uz [unz], Fx [nzoff], Fz [nzoff], Rs [n] ; + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + ok = klu_extract (Numeric, Symbolic, + Lp, Li, Lx, Up, Ui, Ux, Fp, Fi, Fx, P, Q, Rs, R, &Common) ; /* real */ + ok = klu_z_extract (Numeric, Symbolic, + Lp, Li, Lx, Lz, Up, Ui, Ux, Uz, Fp, Fi, Fx, Fz, P, Q, Rs, R, &Common) ; /* complex */ + + + #include "klu.h" + UF_long ok, Lp [n+1], Li [lnz], Up [n+1], Ui [unz], Fp [n+1], Fi [nzoff], P [n], Q [n], R [n] ; + double Lx [lnz], Lz [lnz], Ux [unz], Uz [unz], Fx [nzoff], Fz [nzoff], Rs [n] ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + ok = klu_l_extract (Numeric, Symbolic, + Lp, Li, Lx, Up, Ui, Ux, Fp, Fi, Fx, P, Q, Rs, R, &Common) ; /* real */ + ok = klu_zl_extract (Numeric, Symbolic, + Lp, Li, Lx, Lz, Up, Ui, Ux, Uz, Fp, Fi, Fx, Fz, P, Q, Rs, R, &Common) ; /* complex */ +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt klu\_malloc}, {\tt klu\_free}, {\tt klu\_realloc}: +memory management} +%------------------------------------------------------------------------------- + +KLU uses a set of wrapper routines for {\tt malloc}, {\tt free}, and {\tt +realloc}. By default, these wrapper routines call the ANSI C versions of these +functions. However, pointers to functions in {\tt Common} can be modified +after calling {\tt klu\_defaults} to allow the use of other memory management +functions (such as the MATLAB {\tt mxMalloc}, {\tt mxFree}, and {\tt +mxRealloc}. These wrapper functions keep track of the current and peak memory +usage of KLU. They can be called by the user. + +{\tt klu\_malloc} is essentially the same as {\tt p = malloc (n * sizeof +(size))}, {\tt klu\_free} is essentially the same as {\tt free(p)} except that +{\tt klu\_free} returns NULL which can then be assigned to {\tt p}. {\tt +klu\_realloc} is similar to {\tt realloc}, except that if the reallocation +fails, {\tt p} is returned unchanged. Failure conditions are returned in {\tt +Common.status}. + +{\footnotesize +\begin{verbatim} + #include "klu.h" + size_t n, nnew, nold, size ; + void *p ; + klu_common Common ; + p = klu_malloc (n, size, &Common) ; + p = klu_free (p, n, size, &Common) ; + p = klu_realloc (nnew, nold, size, p, &Common) ; + + + #include "klu.h" + size_t n, nnew, nold, size ; + void *p ; + klu_l_common Common ; + p = klu_l_malloc (n, size, &Common) ; + p = klu_l_free (p, n, size, &Common) ; + p = klu_l_realloc (nnew, nold, size, p, &Common) ; + \end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt btf\_maxtrans}: maximum transversal} +%------------------------------------------------------------------------------- + +The BTF package includes three user-callable functions (each with {\tt int} +and {\tt UF\_long} versions). They do not need to be called directly by an +application that uses KLU. KLU will call these functions to perform the +permutation into upper block triangular form. + +The {\tt btf\_maxtrans} function finds a column permutation {\tt Q} that gives +{\tt A*Q} a zero-free diagonal, if one exists. If row {\tt i} is matched to +column {\tt j}, then {\tt Match[i]=j}. If the matrix is structurally singular, +there will be some unmatched rows. If row {\tt i} is unmatched, then {\tt +Match[i]=-1}. If the matrix is square and structurally non-singular, then {\tt +Q=Match} is the column permutation. The {\tt btf\_maxtrans} function can +accept as input a rectangular matrix; it operates on the bipartite graph of +{\tt A}. It returns the number of columns matched. Unlike the KLU +user-callable functions, the BTF functions do not check its inputs at all; a +segmentation fault will occur if any input pointers are NULL, for example. + +The function can require up to $O$({\tt n*nnz(A)}) time (excluding the {\em +cheap match} phase, which takes another $O$({\tt nnz(A)}) time. If {\tt +maxwork > 0} on input, the work is limited to $O$({\tt maxwork*nnz(A)}) +(excluding the cheap match), but the maximum transversal might not be found if +the limit is reached. + +The {\tt Work} array is workspace required by the methods; its contents +are undefined on input and output. + +{\footnotesize +\begin{verbatim} + int nrow, ncol, Ap [ncol+1], Ai [nz], Match [nrow], Work [5*ncol], nmatch ; + double maxwork, work ; + nmatch = btf_maxtrans (nrow, ncol, Ap, Ai, maxwork, &work, Match, Work) ; + + + UF_long nrow, ncol, Ap [ncol+1], Ai [nz], Match [nrow], Work [5*ncol], nmatch ; + double maxwork, work ; + nmatch = btf_l_maxtrans (nrow, ncol, Ap, Ai, maxwork, &work, Match, Work) ; +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt btf\_strongcomp}: strongly connected components} +%------------------------------------------------------------------------------- + +The {\tt btf\_strongcomp} function finds the strongly connected components of a +directed graph, returning a symmetric permutation {\tt P}. The matrix {\tt A} +must be square. The diagonal of {\tt A} (or {\tt A*Q} if a column permutation +is given on input) is ignored. If {\tt Q} is NULL on input, the matrix +{\tt P*A*P'} is in upper block triangular form. Otherwise, {\tt Q} is modified +on output so that {\tt P*A*Q} is in upper block triangular form. The vector +{\tt R} gives the block boundaries, where the {\tt k}th block consists of +rows and columns {\tt R[k]} through {\tt R[k+1]-1} in the permuted matrix. +The function returns the number of strongly connected components found +(the diagonal blocks in the block triangular form). + +{\footnotesize +\begin{verbatim} + int n, Ap [n+1], Ai [nz], Q [n], P [n], R [n+1], Work [4*n], ncomp ; + ncomp = btf_strongcomp (n, Ap, Ai, Q, P, R, Work) ; + + + UF_long n, Ap [n+1], Ai [nz], Q [n], P [n], R [n+1], Work [4*n], ncomp ; + ncomp = btf_l_strongcomp (n, Ap, Ai, Q, P, R, Work) ; +\end{verbatim} +} + +%------------------------------------------------------------------------------- +\subsection{{\tt btf\_order}: permutation to block triangular form} +%------------------------------------------------------------------------------- + + +The {\tt btf\_order} function combines the above two functions, first finding a +maximum transversal and then permuting the resulting matrix into upper block +triangular form. Unlike {\tt dmperm} in MATLAB, it always reveals the maximum +matching along the diagonal, even if the matrix is structurally singular. + +On output, {\tt P} and {\tt Q} are the row and column permutations, where +{\tt i = P[k]} if row {\tt i} of {\tt A} is the {\tt k}th row of {\tt P*A*Q}, +and {\tt j = BTF\_UNFLIP(Q[k])} if column {\tt j} of {\tt A} is the {\tt k}th +column of {\tt P*A*Q}. If {\tt Q[k] < 0}, then the {\tt (k,k)}th entry in +{\tt P*A*Q} is structurally zero. The vector {\tt R}, and the return value, +are the same as {\tt btf\_strongcomp}. + +{\footnotesize +\begin{verbatim} + int n, Ap [n+1], Ai [nz], P [n], Q [n], R [n+1], nfound, Work [5*n], ncomp, nfound ; + double maxwork, work ; + ncomp = btf_order (n, Ap, Ai, maxwork, &work, P, Q, R, &nfound, Work) ; + + + UF_long n, Ap [n+1], Ai [nz], P [n], Q [n], R [n+1], nfound, Work [5*n], ncomp, nfound ; + double maxwork, work ; + ncomp = btf_l_order (n, Ap, Ai, maxwork, &work, P, Q, R, &nfound, Work) ; +\end{verbatim} +} + +%------------------------------------------------------------------------------ +\subsection{Sample C programs that use KLU} +%------------------------------------------------------------------------------ + +Here is a simple main program, {\tt klu\_simple.c}, that illustrates the basic +usage of KLU. It uses KLU, and indirectly makes use of BTF and AMD. COLAMD is +required to compile the demo, but it is not called by this example. It uses +statically defined global variables for the sparse matrix {\tt A}, which would +not be typical of a complete application. It just makes for a simpler example. + +{\footnotesize +\input{klu_simple_c.tex} +} + +The {\tt Ap}, {\tt Ai}, and {\tt Ax} arrays represent the matrix +\[ +A = \left[ +\begin{array}{ccccc} + 2 & 3 & 0 & 0 & 0 \\ + 3 & 0 & 4 & 0 & 6 \\ + 0 & -1 & -3 & 2 & 0 \\ + 0 & 0 & 1 & 0 & 0 \\ + 0 & 4 & 2 & 0 & 1 \\ +\end{array} +\right]. +\] +The solution to $Ax=b$ is $x = [1 \, 2 \, 3 \, 4 \, 5]^T$. The program +uses default control settings (no scaling, permutation to block triangular +form, and the AMD ordering). It ignores the error codes in the return values +and {\tt Common.status}. + +The block triangular form found by {\tt btf\_order} for this matrix is +given below +\[ +PAQ = \left[ +\begin{array}{c|ccc|c} +2 & 0 & 0 & -1 & -3 \\ +\hline + & 2 & 0 & 3 & 0 \\ + & 3 & 6 & 0 & 4 \\ + & 0 & 1 & 4 & 1 \\ +\hline + & & & & 1 \\ +\end{array} +\right]. +\] +This ordering is not modified by the AMD ordering because the 3-by-3 matrix +$A_{22} + A_{22}^T$ happens to be a dense matrix. No partial pivoting happens +to occur during LU factorization; all pivots are selected along the diagonal of +each block. The matrix contains two singletons, which are the original entries +$a_{34}=2$ and $a_{43}=1$, and one 3-by-3 diagonal block (in which a single +fill-in entry occurs during factorization: the $u_{23}$ entry of this 3-by-3 +matrix). + +For a more complete program that uses KLU, see {\tt KLU/Demo/kludemo.c} for an +{\tt int} version, and {\tt KLU/Demo/kluldemo.c} for a version that uses {\tt +UF\_long} instead. The top-level main routine uses CHOLMOD to read in a +compressed-column sparse matrix from a Matrix Market file, because KLU does not +include such a function. Otherwise, no CHOLMOD functions are used. Unlike +{\tt klu\_simple.c}, CHOLMOD is required to run the {\tt kludemo.c} and {\tt +kluldemo.c} programs. + +%------------------------------------------------------------------------------ +\section{Installation} +\label{Install} +%------------------------------------------------------------------------------ + +Installation of the C-callable interface requires the {\tt make} utility, in +Linux/Unix. Alternatively, you can use the Cygwin {\tt make} in Windows. +The MATLAB installation in any platform, including Windows is simple; just +type {\tt klu\_install} to compile and install KLU, BTF, AMD, and COLAMD. + +For {\tt make}, system-dependent configurations are in the {\tt +../UFconfig/UFconfig.mk} file. You can edit that file to customize the +compilation. The default settings will work on most systems. Sample +configuration files are provided for Linux, Sun Solaris, SGI IRIX, IBM AIX, and +the DEC/Compaq Alpha. + +To compile and install the C-callable KLU, BTF, AMD, and COLAMD libraries, go +to the {\tt KLU} directory and type {\tt make}. The KLU and BTF libraries are +placed in {\tt KLU/Lib/libklu.a} and {\tt BTF/Lib/libbtf.a}. Two KLU demo +programs will be compiled and tested in the {\tt KLU/Demo} directory. You can +compare the output of {\tt make} with the results in the KLU distribution, {\tt +kludemo.out}. + +Typing {\tt make clean} will remove all but the final compiled libraries and +demo programs. Typing {\tt make purge} or {\tt make distclean} removes all +files not in the original distribution. If you compile KLU or BTF and then +later change the {\tt ../UFconfig/UFconfig.mk} file then you should type {\tt +make purge} and then {\tt make} to recompile. + +When you compile your program that uses the C-callable KLU library, you need to +add the {\tt KLU/Lib/libklu.a}, {\tt BTF/Lib/libbtf.a}, {\tt AMD/Lib/libamd.a}, +and {\tt COLAMD/Lib/libamd.a} libraries, a nd you need to tell your compiler to +look in the {\tt KLU/Include} and {\tt BTF/Include} directory for include +files. + +If all you want to use is the KLU mexFunction in MATLAB, you can skip the use +of the {\tt make} command entirely. Simply type {\tt klu\_install} in the +MATLAB command window while in the {\tt KLU/MATLAB} directory. This works on +any system with MATLAB, including Windows. Alternately, type {\tt make} in the +{\tt KLU/MATLAB} directory. + +If you have MATLAB 7.2 or earlier, you must first edit UFconfig/UFconfig.h to +remove the {\tt -largeArrayDims} option from the {\tt MEX} command, prior to +{\tt make mex} or {\tt make} in the MATLAB directory (or just use {\tt +klu\_install.m} inside MATLAB, which handles this case). + +%------------------------------------------------------------------------------ +\newpage +\section{The KLU routines} +\label{klu_include} +%------------------------------------------------------------------------------ + +The file {\tt KLU/Include/klu.h} listed below describes each user-callable +routine in the C version of KLU, and gives details on their use. + +{\footnotesize +\input{klu_h.tex} +} + +%------------------------------------------------------------------------------ +\newpage +\section{The BTF routines} +\label{btf_include} +%------------------------------------------------------------------------------ + +The file {\tt BTF/Include/btf.h} listed below describes each user-callable +routine in the C version of BTF, and gives details on their use. + +{\footnotesize +\input{btf_h.tex} +} + +%------------------------------------------------------------------------------ +\newpage +% References +%------------------------------------------------------------------------------ + +\bibliographystyle{plain} +\bibliography{KLU_UserGuide} + +\end{document} diff --git a/OpenDSSC/klusolve/KLU/Doc/Makefile b/OpenDSSC/klusolve/KLU/Doc/Makefile new file mode 100644 index 0000000..daa0c1e --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Doc/Makefile @@ -0,0 +1,44 @@ +#------------------------------------------------------------------------------ +# KLU Makefile for creating the user guide +#------------------------------------------------------------------------------ + +default: dist + +include ../../UFconfig/UFconfig.mk + +#------------------------------------------------------------------------------ +# Remove all but the files in the original distribution +#------------------------------------------------------------------------------ + +clean: + - $(RM) $(CLEAN) + +purge: distclean + +distclean: clean + - $(RM) *.aux *.bbl *.blg *.log *.toc + +#------------------------------------------------------------------------------ +# Create the User Guide and Quick Start Guide +#------------------------------------------------------------------------------ + +KLU_UserGuide.pdf: KLU_UserGuide.tex KLU_UserGuide.bib \ + ../Include/klu.h ../../BTF/Include/btf.h + echo '\begin{verbatim}' > klu_h.tex + expand -8 ../Include/klu.h >> klu_h.tex + echo '\end{verbatim}' >> klu_h.tex + echo '\begin{verbatim}' > btf_h.tex + expand -8 ../../BTF/Include/btf.h >> btf_h.tex + echo '\end{verbatim}' >> btf_h.tex + echo '\begin{verbatim}' > klu_simple_c.tex + expand -8 ../Demo/klu_simple.c >> klu_simple_c.tex + echo '\end{verbatim}' >> klu_simple_c.tex + pdflatex KLU_UserGuide + bibtex KLU_UserGuide + pdflatex KLU_UserGuide + pdflatex KLU_UserGuide + +dist: KLU_UserGuide.pdf + - $(RM) *.aux *.bbl *.blg *.log *.toc + - $(RM) klu_simple_c.tex klu_h.tex btf_h.tex + diff --git a/OpenDSSC/klusolve/KLU/Doc/lesser.txt b/OpenDSSC/klusolve/KLU/Doc/lesser.txt new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/OpenDSSC/klusolve/KLU/Doc/palamadai_e.pdf b/OpenDSSC/klusolve/KLU/Doc/palamadai_e.pdf new file mode 100644 index 0000000..6896e0e Binary files /dev/null and b/OpenDSSC/klusolve/KLU/Doc/palamadai_e.pdf differ diff --git a/OpenDSSC/klusolve/KLU/Include/klu.h b/OpenDSSC/klusolve/KLU/Include/klu.h new file mode 100644 index 0000000..867ed42 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Include/klu.h @@ -0,0 +1,831 @@ +/* ========================================================================== */ +/* === klu include file ===================================================== */ +/* ========================================================================== */ + +/* Include file for user programs that call klu_* routines */ + +#ifndef _KLU_H +#define _KLU_H + +/* make it easy for C++ programs to include KLU */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "amd.h" +#include "colamd.h" +#include "btf.h" + +/* -------------------------------------------------------------------------- */ +/* Symbolic object - contains the pre-ordering computed by klu_analyze */ +/* -------------------------------------------------------------------------- */ + +typedef struct +{ + /* A (P,Q) is in upper block triangular form. The kth block goes from + * row/col index R [k] to R [k+1]-1. The estimated number of nonzeros + * in the L factor of the kth block is Lnz [k]. + */ + + /* only computed if the AMD ordering is chosen: */ + double symmetry ; /* symmetry of largest block */ + double est_flops ; /* est. factorization flop count */ + double lnz, unz ; /* estimated nz in L and U, including diagonals */ + double *Lnz ; /* size n, but only Lnz [0..nblocks-1] is used */ + + /* computed for all orderings: */ + int + n, /* input matrix A is n-by-n */ + nz, /* # entries in input matrix */ + *P, /* size n */ + *Q, /* size n */ + *R, /* size n+1, but only R [0..nblocks] is used */ + nzoff, /* nz in off-diagonal blocks */ + nblocks, /* number of blocks */ + maxblock, /* size of largest block */ + ordering, /* ordering used (AMD, COLAMD, or GIVEN) */ + do_btf ; /* whether or not BTF preordering was requested */ + + /* only computed if BTF preordering requested */ + int structural_rank ; /* 0 to n-1 if the matrix is structurally rank + * deficient. -1 if not computed. n if the matrix has + * full structural rank */ + +} klu_symbolic ; + +typedef struct /* 64-bit version (otherwise same as above) */ +{ + double symmetry, est_flops, lnz, unz ; + double *Lnz ; + UF_long n, nz, *P, *Q, *R, nzoff, nblocks, maxblock, ordering, do_btf, + structural_rank ; + +} klu_l_symbolic ; + +/* -------------------------------------------------------------------------- */ +/* Numeric object - contains the factors computed by klu_factor */ +/* -------------------------------------------------------------------------- */ + +typedef struct +{ + /* LU factors of each block, the pivot row permutation, and the + * entries in the off-diagonal blocks */ + + int n ; /* A is n-by-n */ + int nblocks ; /* number of diagonal blocks */ + int lnz ; /* actual nz in L, including diagonal */ + int unz ; /* actual nz in U, including diagonal */ + int max_lnz_block ; /* max actual nz in L in any one block, incl. diag */ + int max_unz_block ; /* max actual nz in U in any one block, incl. diag */ + int *Pnum ; /* size n. final pivot permutation */ + int *Pinv ; /* size n. inverse of final pivot permutation */ + + /* LU factors of each block */ + int *Lip ; /* size n. pointers into LUbx[block] for L */ + int *Uip ; /* size n. pointers into LUbx[block] for U */ + int *Llen ; /* size n. Llen [k] = # of entries in kth column of L */ + int *Ulen ; /* size n. Ulen [k] = # of entries in kth column of U */ + void **LUbx ; /* L and U indices and entries (excl. diagonal of U) */ + size_t *LUsize ; /* size of each LUbx [block], in sizeof (Unit) */ + void *Udiag ; /* diagonal of U */ + + /* scale factors; can be NULL if no scaling */ + double *Rs ; /* size n. Rs [i] is scale factor for row i */ + + /* permanent workspace for factorization and solve */ + size_t worksize ; /* size (in bytes) of Work */ + void *Work ; /* workspace */ + void *Xwork ; /* alias into Numeric->Work */ + int *Iwork ; /* alias into Numeric->Work */ + + /* off-diagonal entries in a conventional compressed-column sparse matrix */ + int *Offp ; /* size n+1, column pointers */ + int *Offi ; /* size nzoff, row indices */ + void *Offx ; /* size nzoff, numerical values */ + int nzoff ; + +} klu_numeric ; + +typedef struct /* 64-bit version (otherwise same as above) */ +{ + UF_long n, nblocks, lnz, unz, max_lnz_block, max_unz_block, *Pnum, *Pinv, + *Lip, *Uip, *Llen, *Ulen ; + void **LUbx ; + size_t *LUsize ; + void *Udiag ; + double *Rs ; + size_t worksize ; + void *Work, *Xwork ; + UF_long *Iwork ; + UF_long *Offp, *Offi ; + void *Offx ; + UF_long nzoff ; + +} klu_l_numeric ; + +/* -------------------------------------------------------------------------- */ +/* KLU control parameters and statistics */ +/* -------------------------------------------------------------------------- */ + +/* Common->status values */ +#define KLU_OK 0 +#define KLU_SINGULAR (1) /* status > 0 is a warning, not an error */ +#define KLU_OUT_OF_MEMORY (-2) +#define KLU_INVALID (-3) +#define KLU_TOO_LARGE (-4) /* integer overflow has occured */ + +typedef struct klu_common_struct +{ + + /* ---------------------------------------------------------------------- */ + /* parameters */ + /* ---------------------------------------------------------------------- */ + + double tol ; /* pivot tolerance for diagonal preference */ + double memgrow ; /* realloc memory growth size for LU factors */ + double initmem_amd ; /* init. memory size with AMD: c*nnz(L) + n */ + double initmem ; /* init. memory size: c*nnz(A) + n */ + double maxwork ; /* maxwork for BTF, <= 0 if no limit */ + + int btf ; /* use BTF pre-ordering, or not */ + int ordering ; /* 0: AMD, 1: COLAMD, 2: user P and Q, + * 3: user function */ + int scale ; /* row scaling: -1: none (and no error check), + * 0: none, 1: sum, 2: max */ + + /* memory management routines */ + void *(*malloc_memory) (size_t) ; /* pointer to malloc */ + void *(*realloc_memory) (void *, size_t) ; /* pointer to realloc */ + void (*free_memory) (void *) ; /* pointer to free */ + void *(*calloc_memory) (size_t, size_t) ; /* pointer to calloc */ + + /* pointer to user ordering function */ + int (*user_order) (int, int *, int *, int *, struct klu_common_struct *) ; + + /* pointer to user data, passed unchanged as the last parameter to the + * user ordering function (optional, the user function need not use this + * information). */ + void *user_data ; + + int halt_if_singular ; /* how to handle a singular matrix: + * FALSE: keep going. Return a Numeric object with a zero U(k,k). A + * divide-by-zero may occur when computing L(:,k). The Numeric object + * can be passed to klu_solve (a divide-by-zero will occur). It can + * also be safely passed to klu_refactor. + * TRUE: stop quickly. klu_factor will free the partially-constructed + * Numeric object. klu_refactor will not free it, but will leave the + * numerical values only partially defined. This is the default. */ + + /* ---------------------------------------------------------------------- */ + /* statistics */ + /* ---------------------------------------------------------------------- */ + + int status ; /* KLU_OK if OK, < 0 if error */ + int nrealloc ; /* # of reallocations of L and U */ + + int structural_rank ; /* 0 to n-1 if the matrix is structurally rank + * deficient (as determined by maxtrans). -1 if not computed. n if the + * matrix has full structural rank. This is computed by klu_analyze + * if a BTF preordering is requested. */ + + int numerical_rank ; /* First k for which a zero U(k,k) was found, + * if the matrix was singular (in the range 0 to n-1). n if the matrix + * has full rank. This is not a true rank-estimation. It just reports + * where the first zero pivot was found. -1 if not computed. + * Computed by klu_factor and klu_refactor. */ + + int singular_col ; /* n if the matrix is not singular. If in the + * range 0 to n-1, this is the column index of the original matrix A that + * corresponds to the column of U that contains a zero diagonal entry. + * -1 if not computed. Computed by klu_factor and klu_refactor. */ + + int noffdiag ; /* # of off-diagonal pivots, -1 if not computed */ + + double flops ; /* actual factorization flop count, from klu_flops */ + double rcond ; /* crude reciprocal condition est., from klu_rcond */ + double condest ; /* accurate condition est., from klu_condest */ + double rgrowth ; /* reciprocal pivot rgrowth, from klu_rgrowth */ + double work ; /* actual work done in BTF, in klu_analyze */ + + size_t memusage ; /* current memory usage, in bytes */ + size_t mempeak ; /* peak memory usage, in bytes */ + +} klu_common ; + +typedef struct klu_l_common_struct /* 64-bit version (otherwise same as above)*/ +{ + + double tol, memgrow, initmem_amd, initmem, maxwork ; + UF_long btf, ordering, scale ; + void *(*malloc_memory) (size_t) ; + void *(*realloc_memory) (void *, size_t) ; + void (*free_memory) (void *) ; + void *(*calloc_memory) (size_t, size_t) ; + UF_long (*user_order) (UF_long, UF_long *, UF_long *, UF_long *, + struct klu_l_common_struct *) ; + void *user_data ; + UF_long halt_if_singular ; + UF_long status, nrealloc, structural_rank, numerical_rank, singular_col, + noffdiag ; + double flops, rcond, condest, rgrowth, work ; + size_t memusage, mempeak ; + +} klu_l_common ; + +/* -------------------------------------------------------------------------- */ +/* klu_defaults: sets default control parameters */ +/* -------------------------------------------------------------------------- */ + +int klu_defaults +( + klu_common *Common +) ; + +UF_long klu_l_defaults (klu_l_common *Common) ; + +/* -------------------------------------------------------------------------- */ +/* klu_analyze: orders and analyzes a matrix */ +/* -------------------------------------------------------------------------- */ + +/* Order the matrix with BTF (or not), then order each block with AMD, COLAMD, + * a natural ordering, or with a user-provided ordering function */ + +klu_symbolic *klu_analyze +( + /* inputs, not modified */ + int n, /* A is n-by-n */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + klu_common *Common +) ; + +klu_l_symbolic *klu_l_analyze (UF_long, UF_long *, UF_long *, + klu_l_common *Common) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_analyze_given: analyzes a matrix using given P and Q */ +/* -------------------------------------------------------------------------- */ + +/* Order the matrix with BTF (or not), then use natural or given ordering + * P and Q on the blocks. P and Q are interpretted as identity + * if NULL. */ + +klu_symbolic *klu_analyze_given +( + /* inputs, not modified */ + int n, /* A is n-by-n */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + int P [ ], /* size n, user's row permutation (may be NULL) */ + int Q [ ], /* size n, user's column permutation (may be NULL) */ + klu_common *Common +) ; + +klu_l_symbolic *klu_l_analyze_given (UF_long, UF_long *, UF_long *, UF_long *, + UF_long *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_factor: factors a matrix using the klu_analyze results */ +/* -------------------------------------------------------------------------- */ + +klu_numeric *klu_factor /* returns KLU_OK if OK, < 0 if error */ +( + /* inputs, not modified */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], /* size nz, numerical values */ + klu_symbolic *Symbolic, + klu_common *Common +) ; + +klu_numeric *klu_z_factor /* returns KLU_OK if OK, < 0 if error */ +( + /* inputs, not modified */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], /* size 2*nz, numerical values (real,imag pairs) */ + klu_symbolic *Symbolic, + klu_common *Common +) ; + +/* long / real version */ +klu_l_numeric *klu_l_factor (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_common *) ; + +/* long / complex version */ +klu_l_numeric *klu_zl_factor (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_solve: solves Ax=b using the Symbolic and Numeric objects */ +/* -------------------------------------------------------------------------- */ + +int klu_solve +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + int ldim, /* leading dimension of B */ + int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size ldim*nrhs */ + klu_common *Common +) ; + +int klu_z_solve +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + int ldim, /* leading dimension of B */ + int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size 2*ldim*nrhs */ + klu_common *Common +) ; + +UF_long klu_l_solve (klu_l_symbolic *, klu_l_numeric *, UF_long, UF_long, + double *, klu_l_common *) ; + +UF_long klu_zl_solve (klu_l_symbolic *, klu_l_numeric *, UF_long, UF_long, + double *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_tsolve: solves A'x=b using the Symbolic and Numeric objects */ +/* -------------------------------------------------------------------------- */ + +int klu_tsolve +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + int ldim, /* leading dimension of B */ + int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size ldim*nrhs */ + klu_common *Common +) ; + +int klu_z_tsolve +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + int ldim, /* leading dimension of B */ + int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size 2*ldim*nrhs */ + int conj_solve, /* TRUE: conjugate solve, FALSE: solve A.'x=b */ + klu_common *Common + +) ; + +UF_long klu_l_tsolve (klu_l_symbolic *, klu_l_numeric *, UF_long, UF_long, + double *, klu_l_common *) ; + +UF_long klu_zl_tsolve (klu_l_symbolic *, klu_l_numeric *, UF_long, UF_long, + double *, UF_long, klu_l_common * ) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_refactor: refactorizes matrix with same ordering as klu_factor */ +/* -------------------------------------------------------------------------- */ + +int klu_refactor /* return TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], /* size nz, numerical values */ + klu_symbolic *Symbolic, + /* input, and numerical values modified on output */ + klu_numeric *Numeric, + klu_common *Common +) ; + +int klu_z_refactor /* return TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], /* size 2*nz, numerical values */ + klu_symbolic *Symbolic, + /* input, and numerical values modified on output */ + klu_numeric *Numeric, + klu_common *Common +) ; + +UF_long klu_l_refactor (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_numeric *, klu_l_common *) ; + +UF_long klu_zl_refactor (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_numeric *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_free_symbolic: destroys the Symbolic object */ +/* -------------------------------------------------------------------------- */ + +int klu_free_symbolic +( + klu_symbolic **Symbolic, + klu_common *Common +) ; + +UF_long klu_l_free_symbolic (klu_l_symbolic **, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_free_numeric: destroys the Numeric object */ +/* -------------------------------------------------------------------------- */ + +/* Note that klu_free_numeric and klu_z_free_numeric are identical; each can + * free both kinds of Numeric objects (real and complex) */ + +int klu_free_numeric +( + klu_numeric **Numeric, + klu_common *Common +) ; + +int klu_z_free_numeric +( + klu_numeric **Numeric, + klu_common *Common +) ; + +UF_long klu_l_free_numeric (klu_l_numeric **, klu_l_common *) ; +UF_long klu_zl_free_numeric (klu_l_numeric **, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_sort: sorts the columns of the LU factorization */ +/* -------------------------------------------------------------------------- */ + +/* this is not needed except for the MATLAB interface */ + +int klu_sort +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + /* input/output */ + klu_numeric *Numeric, + klu_common *Common +) ; + +int klu_z_sort +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + /* input/output */ + klu_numeric *Numeric, + klu_common *Common +) ; + +UF_long klu_l_sort (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; +UF_long klu_zl_sort (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_flops: determines # of flops performed in numeric factorzation */ +/* -------------------------------------------------------------------------- */ + +int klu_flops +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + /* input/output */ + klu_common *Common +) ; + +int klu_z_flops +( + /* inputs, not modified */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + /* input/output */ + klu_common *Common +) ; + +UF_long klu_l_flops (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; +UF_long klu_zl_flops (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; + + + +/* -------------------------------------------------------------------------- */ +/* klu_rgrowth : compute the reciprocal pivot growth */ +/* -------------------------------------------------------------------------- */ + +/* Pivot growth is computed after the input matrix is permuted, scaled, and + * off-diagonal entries pruned. This is because the LU factorization of each + * block takes as input the scaled diagonal blocks of the BTF form. The + * reciprocal pivot growth in column j of an LU factorization of a matrix C + * is the largest entry in C divided by the largest entry in U; then the overall + * reciprocal pivot growth is the smallest such value for all columns j. Note + * that the off-diagonal entries are not scaled, since they do not take part in + * the LU factorization of the diagonal blocks. + * + * In MATLAB notation: + * + * rgrowth = min (max (abs ((R \ A(p,q)) - F)) ./ max (abs (U))) */ + +int klu_rgrowth +( + int Ap [ ], + int Ai [ ], + double Ax [ ], + klu_symbolic *Symbolic, + klu_numeric *Numeric, + klu_common *Common /* Common->rgrowth = reciprocal pivot growth */ +) ; + +int klu_z_rgrowth +( + int Ap [ ], + int Ai [ ], + double Ax [ ], + klu_symbolic *Symbolic, + klu_numeric *Numeric, + klu_common *Common /* Common->rgrowth = reciprocal pivot growth */ +) ; + +UF_long klu_l_rgrowth (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_numeric *, klu_l_common *) ; + +UF_long klu_zl_rgrowth (UF_long *, UF_long *, double *, klu_l_symbolic *, + klu_l_numeric *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_condest */ +/* -------------------------------------------------------------------------- */ + +/* Computes a reasonably accurate estimate of the 1-norm condition number, using + * Hager's method, as modified by Higham and Tisseur (same method as used in + * MATLAB's condest */ + +int klu_condest +( + int Ap [ ], /* size n+1, column pointers, not modified */ + double Ax [ ], /* size nz = Ap[n], numerical values, not modified*/ + klu_symbolic *Symbolic, /* symbolic analysis, not modified */ + klu_numeric *Numeric, /* numeric factorization, not modified */ + klu_common *Common /* result returned in Common->condest */ +) ; + +int klu_z_condest +( + int Ap [ ], + double Ax [ ], /* size 2*nz */ + klu_symbolic *Symbolic, + klu_numeric *Numeric, + klu_common *Common /* result returned in Common->condest */ +) ; + +UF_long klu_l_condest (UF_long *, double *, klu_l_symbolic *, klu_l_numeric *, + klu_l_common *) ; + +UF_long klu_zl_condest (UF_long *, double *, klu_l_symbolic *, klu_l_numeric *, + klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_rcond: compute min(abs(diag(U))) / max(abs(diag(U))) */ +/* -------------------------------------------------------------------------- */ + +int klu_rcond +( + klu_symbolic *Symbolic, /* input, not modified */ + klu_numeric *Numeric, /* input, not modified */ + klu_common *Common /* result in Common->rcond */ +) ; + +int klu_z_rcond +( + klu_symbolic *Symbolic, /* input, not modified */ + klu_numeric *Numeric, /* input, not modified */ + klu_common *Common /* result in Common->rcond */ +) ; + +UF_long klu_l_rcond (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; + +UF_long klu_zl_rcond (klu_l_symbolic *, klu_l_numeric *, klu_l_common *) ; + + + +/* -------------------------------------------------------------------------- */ +/* klu_scale */ +/* -------------------------------------------------------------------------- */ + +int klu_scale /* return TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + int scale, /* <0: none, no error check; 0: none, 1: sum, 2: max */ + int n, + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], + /* outputs, not defined on input */ + double Rs [ ], + /* workspace, not defined on input or output */ + int W [ ], /* size n, can be NULL */ + klu_common *Common +) ; + +int klu_z_scale /* return TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + int scale, /* <0: none, no error check; 0: none, 1: sum, 2: max */ + int n, + int Ap [ ], /* size n+1, column pointers */ + int Ai [ ], /* size nz, row indices */ + double Ax [ ], + /* outputs, not defined on input */ + double Rs [ ], + /* workspace, not defined on input or output */ + int W [ ], /* size n, can be NULL */ + klu_common *Common +) ; + +UF_long klu_l_scale (UF_long, UF_long, UF_long *, UF_long *, double *, + double *, UF_long *, klu_l_common *) ; + +UF_long klu_zl_scale (UF_long, UF_long, UF_long *, UF_long *, double *, + double *, UF_long *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* klu_extract */ +/* -------------------------------------------------------------------------- */ + +int klu_extract /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + klu_numeric *Numeric, + klu_symbolic *Symbolic, + + /* outputs, either allocated on input, or ignored otherwise */ + + /* L */ + int *Lp, /* size n+1 */ + int *Li, /* size Numeric->lnz */ + double *Lx, /* size Numeric->lnz */ + + /* U */ + int *Up, /* size n+1 */ + int *Ui, /* size Numeric->unz */ + double *Ux, /* size Numeric->unz */ + + /* F */ + int *Fp, /* size n+1 */ + int *Fi, /* size Numeric->nzoff */ + double *Fx, /* size Numeric->nzoff */ + + /* P, row permutation */ + int *P, /* size n */ + + /* Q, column permutation */ + int *Q, /* size n */ + + /* Rs, scale factors */ + double *Rs, /* size n */ + + /* R, block boundaries */ + int *R, /* size Symbolic->nblocks+1 (nblocks is at most n) */ + + klu_common *Common +) ; + + +int klu_z_extract /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + klu_numeric *Numeric, + klu_symbolic *Symbolic, + + /* outputs, all of which must be allocated on input */ + + /* L */ + int *Lp, /* size n+1 */ + int *Li, /* size nnz(L) */ + double *Lx, /* size nnz(L) */ + double *Lz, /* size nnz(L) for the complex case, ignored if real */ + + /* U */ + int *Up, /* size n+1 */ + int *Ui, /* size nnz(U) */ + double *Ux, /* size nnz(U) */ + double *Uz, /* size nnz(U) for the complex case, ignored if real */ + + /* F */ + int *Fp, /* size n+1 */ + int *Fi, /* size nnz(F) */ + double *Fx, /* size nnz(F) */ + double *Fz, /* size nnz(F) for the complex case, ignored if real */ + + /* P, row permutation */ + int *P, /* size n */ + + /* Q, column permutation */ + int *Q, /* size n */ + + /* Rs, scale factors */ + double *Rs, /* size n */ + + /* R, block boundaries */ + int *R, /* size Symbolic->nblocks+1 (nblocks is at most n) */ + + klu_common *Common +) ; + +UF_long klu_l_extract (klu_l_numeric *, klu_l_symbolic *, + UF_long *, UF_long *, double *, + UF_long *, UF_long *, double *, + UF_long *, UF_long *, double *, + UF_long *, UF_long *, double *, UF_long *, klu_l_common *) ; + +UF_long klu_zl_extract (klu_l_numeric *, klu_l_symbolic *, + UF_long *, UF_long *, double *, double *, + UF_long *, UF_long *, double *, double *, + UF_long *, UF_long *, double *, double *, + UF_long *, UF_long *, double *, UF_long *, klu_l_common *) ; + + +/* -------------------------------------------------------------------------- */ +/* KLU memory management routines */ +/* -------------------------------------------------------------------------- */ + +void *klu_malloc /* returns pointer to the newly malloc'd block */ +( + /* ---- input ---- */ + size_t n, /* number of items */ + size_t size, /* size of each item */ + /* --------------- */ + klu_common *Common +) ; + +void *klu_free /* always returns NULL */ +( + /* ---- in/out --- */ + void *p, /* block of memory to free */ + size_t n, /* number of items */ + size_t size, /* size of each item */ + /* --------------- */ + klu_common *Common +) ; + +void *klu_realloc /* returns pointer to reallocated block */ +( + /* ---- input ---- */ + size_t nnew, /* requested # of items in reallocated block */ + size_t nold, /* current size of block, in # of items */ + size_t size, /* size of each item */ + /* ---- in/out --- */ + void *p, /* block of memory to realloc */ + /* --------------- */ + klu_common *Common +) ; + +void *klu_l_malloc (size_t, size_t, klu_l_common *) ; +void *klu_l_free (void *, size_t, size_t, klu_l_common *) ; +void *klu_l_realloc (size_t, size_t, size_t, void *, klu_l_common *) ; + + +/* ========================================================================== */ +/* === KLU version ========================================================== */ +/* ========================================================================== */ + +/* All versions of KLU include these definitions. + * As an example, to test if the version you are using is 1.2 or later: + * + * if (KLU_VERSION >= KLU_VERSION_CODE (1,2)) ... + * + * This also works during compile-time: + * + * #if (KLU >= KLU_VERSION_CODE (1,2)) + * printf ("This is version 1.2 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + */ + +#define KLU_DATE "Nov 1, 2007" +#define KLU_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define KLU_MAIN_VERSION 1 +#define KLU_SUB_VERSION 0 +#define KLU_SUBSUB_VERSION 1 +#define KLU_VERSION KLU_VERSION_CODE(KLU_MAIN_VERSION,KLU_SUB_VERSION) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OpenDSSC/klusolve/KLU/Include/klu_internal.h b/OpenDSSC/klusolve/KLU/Include/klu_internal.h new file mode 100644 index 0000000..da73bc4 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Include/klu_internal.h @@ -0,0 +1,243 @@ +/* ========================================================================== */ +/* === KLU/Include/klu_internal.h =========================================== */ +/* ========================================================================== */ + +/* For internal use in KLU routines only, not for user programs */ + +#ifndef _KLU_INTERNAL_H +#define _KLU_INTERNAL_H + +#include "klu.h" +#include "btf.h" +#include "klu_version.h" + +/* ========================================================================== */ +/* make sure debugging and printing is turned off */ + +#ifndef NDEBUG +#define NDEBUG +#endif +#ifndef NPRINT +#define NPRINT +#endif + +/* To enable debugging and assertions, uncomment this line: + #undef NDEBUG + */ + +/* To enable diagnostic printing, uncomment this line: + #undef NPRINT + */ + +/* ========================================================================== */ + +#include +#include +#include +#include +#include + +#undef ASSERT +#ifndef NDEBUG +#define ASSERT(a) assert(a) +#else +#define ASSERT(a) +#endif + +#define SCALAR_IS_NAN(x) ((x) != (x)) + +/* true if an integer (stored in double x) would overflow (or if x is NaN) */ +#define INT_OVERFLOW(x) ((!((x) * (1.0+1e-8) <= (double) INT_MAX)) \ + || SCALAR_IS_NAN (x)) + +#undef TRUE +#undef FALSE +#undef MAX +#undef MIN +#undef PRINTF +#undef FLIP + +#ifndef NPRINT +#define PRINTF(s) { printf s ; } ; +#else +#define PRINTF(s) +#endif + +#define TRUE 1 +#define FALSE 0 +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* FLIP is a "negation about -1", and is used to mark an integer i that is + * normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY + * is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i + * for all integers i. UNFLIP (i) is >= EMPTY. */ +#define EMPTY (-1) +#define FLIP(i) (-(i)-2) +#define UNFLIP(i) (((i) < EMPTY) ? FLIP (i) : (i)) + + +size_t KLU_kernel /* final size of LU on output */ +( + /* input, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers for A */ + Int Ai [ ], /* size nz = Ap [n], row indices for A */ + Entry Ax [ ], /* size nz, values of A */ + Int Q [ ], /* size n, optional input permutation */ + size_t lusize, /* initial size of LU */ + + /* output, not defined on input */ + Int Pinv [ ], /* size n */ + Int P [ ], /* size n */ + Unit **p_LU, /* size lusize on input, size Uxp[n] on output*/ + Entry Udiag [ ], /* size n, diagonal of U */ + Int Llen [ ], /* size n, column length of L */ + Int Ulen [ ], /* size n, column length of U */ + Int Lip [ ], /* size n+1 */ + Int Uip [ ], /* size n+1 */ + Int *lnz, /* size of L */ + Int *unz, /* size of U */ + + /* workspace, not defined on input */ + Entry X [ ], /* size n, zero on output */ + + /* workspace, not defined on input or output */ + Int Stack [ ], /* size n */ + Int Flag [ ], /* size n */ + Int adj_pos [ ], /* size n */ + + /* workspace for pruning only */ + Int Lpend [ ], /* size n workspace */ + + /* inputs, not modified on output */ + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ], /* inverse of P from symbolic factorization */ + double Rs [ ], /* scale factors for A */ + + /* inputs, modified on output */ + Int Offp [ ], /* off-diagonal matrix (modified by this routine) */ + Int Offi [ ], + Entry Offx [ ], + KLU_common *Common /* the control input/output structure */ +) ; + + +size_t KLU_kernel_factor /* 0 if failure, size of LU if OK */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n. n must be > 0. */ + Int Ap [ ], /* size n+1, column pointers for A */ + Int Ai [ ], /* size nz = Ap [n], row indices for A */ + Entry Ax [ ], /* size nz, values of A */ + Int Q [ ], /* size n, optional column permutation */ + double Lsize, /* initial size of L and U */ + + /* outputs, not defined on input */ + Unit **p_LU, /* row indices and values of L and U */ + Entry Udiag [ ], /* size n, diagonal of U */ + Int Llen [ ], /* size n, column length of L */ + Int Ulen [ ], /* size n, column length of U */ + Int Lip [ ], /* size n+1, column pointers of L */ + Int Uip [ ], /* size n+1, column pointers of U */ + Int P [ ], /* row permutation, size n */ + Int *lnz, /* size of L */ + Int *unz, /* size of U */ + + /* workspace, undefined on input */ + Entry *X, /* size n entries. Zero on output */ + Int *Work, /* size 5n Int's */ + + /* inputs, not modified on output */ + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ], /* inverse of P from symbolic factorization */ + double Rs [ ], /* scale factors for A */ + + /* inputs, modified on output */ + Int Offp [ ], /* off-diagonal matrix (modified by this routine) */ + Int Offi [ ], + Entry Offx [ ], + KLU_common *Common /* the control input/output structure */ +) ; + +void KLU_lsolve +( + /* inputs, not modified: */ + Int n, + Int Lp [ ], + Int Li [ ], + Unit LU [ ], + Int nrhs, + /* right-hand-side on input, solution to Lx=b on output */ + Entry X [ ] +) ; + +void KLU_ltsolve +( + /* inputs, not modified: */ + Int n, + Int Lp [ ], + Int Li [ ], + Unit LU [ ], + Int nrhs, +#ifdef COMPLEX + Int conj_solve, +#endif + /* right-hand-side on input, solution to L'x=b on output */ + Entry X [ ] +) ; + + +void KLU_usolve +( + /* inputs, not modified: */ + Int n, + Int Up [ ], + Int Ui [ ], + Unit LU [ ], + Entry Udiag [ ], + Int nrhs, + /* right-hand-side on input, solution to Ux=b on output */ + Entry X [ ] +) ; + +void KLU_utsolve +( + /* inputs, not modified: */ + Int n, + Int Up [ ], + Int Ui [ ], + Unit LU [ ], + Entry Udiag [ ], + Int nrhs, +#ifdef COMPLEX + Int conj_solve, +#endif + /* right-hand-side on input, solution to U'x=b on output */ + Entry X [ ] +) ; + +Int KLU_valid +( + Int n, + Int Ap [ ], + Int Ai [ ], + Entry Ax [ ] +) ; + +Int KLU_valid_LU +( + Int n, + Int flag_test_start_ptr, + Int Xip [ ], + Int Xlen [ ], + Unit LU [ ] +); + +size_t KLU_add_size_t (size_t a, size_t b, Int *ok) ; + +size_t KLU_mult_size_t (size_t a, size_t k, Int *ok) ; + +KLU_symbolic *KLU_alloc_symbolic (Int n, Int *Ap, Int *Ai, KLU_common *Common) ; + +#endif diff --git a/OpenDSSC/klusolve/KLU/Include/klu_version.h b/OpenDSSC/klusolve/KLU/Include/klu_version.h new file mode 100644 index 0000000..13fde51 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Include/klu_version.h @@ -0,0 +1,694 @@ +#ifndef _KLU_VERSION_H +#define _KLU_VERSION_H + +#ifdef DLONG +#define Int UF_long +#define Int_id UF_long_id +#define Int_MAX UF_long_max +#else +#define Int int +#define Int_id "%d" +#define Int_MAX INT_MAX +#endif + +#define NPRINT + +#define BYTES(type,n) (sizeof (type) * (n)) +#define CEILING(b,u) (((b)+(u)-1) / (u)) +#define UNITS(type,n) (CEILING (BYTES (type,n), sizeof (Unit))) +#define DUNITS(type,n) (ceil (BYTES (type, (double) n) / sizeof (Unit))) + +#define GET_I_POINTER(LU, Xip, Xi, k) \ +{ \ + Xi = (Int *) (LU + Xip [k]) ; \ +} + +#define GET_X_POINTER(LU, Xip, Xlen, Xx, k) \ +{ \ + Xx = (Entry *) (LU + Xip [k] + UNITS (Int, Xlen [k])) ; \ +} + +#define GET_POINTER(LU, Xip, Xlen, Xi, Xx, k, xlen) \ +{ \ + Unit *xp = LU + Xip [k] ; \ + xlen = Xlen [k] ; \ + Xi = (Int *) xp ; \ + Xx = (Entry *) (xp + UNITS (Int, xlen)) ; \ +} + +/* function names */ +#ifdef COMPLEX + +#ifdef DLONG + +#define KLU_scale klu_zl_scale +#define KLU_solve klu_zl_solve +#define KLU_tsolve klu_zl_tsolve +#define KLU_free_numeric klu_zl_free_numeric +#define KLU_factor klu_zl_factor +#define KLU_refactor klu_zl_refactor +#define KLU_kernel_factor klu_zl_kernel_factor +#define KLU_lsolve klu_zl_lsolve +#define KLU_ltsolve klu_zl_ltsolve +#define KLU_usolve klu_zl_usolve +#define KLU_utsolve klu_zl_utsolve +#define KLU_kernel klu_zl_kernel +#define KLU_valid klu_zl_valid +#define KLU_valid_LU klu_zl_valid_LU +#define KLU_sort klu_zl_sort +#define KLU_rgrowth klu_zl_rgrowth +#define KLU_rcond klu_zl_rcond +#define KLU_extract klu_zl_extract +#define KLU_condest klu_zl_condest +#define KLU_flops klu_zl_flops + +#else + +#define KLU_scale klu_z_scale +#define KLU_solve klu_z_solve +#define KLU_tsolve klu_z_tsolve +#define KLU_free_numeric klu_z_free_numeric +#define KLU_factor klu_z_factor +#define KLU_refactor klu_z_refactor +#define KLU_kernel_factor klu_z_kernel_factor +#define KLU_lsolve klu_z_lsolve +#define KLU_ltsolve klu_z_ltsolve +#define KLU_usolve klu_z_usolve +#define KLU_utsolve klu_z_utsolve +#define KLU_kernel klu_z_kernel +#define KLU_valid klu_z_valid +#define KLU_valid_LU klu_z_valid_LU +#define KLU_sort klu_z_sort +#define KLU_rgrowth klu_z_rgrowth +#define KLU_rcond klu_z_rcond +#define KLU_extract klu_z_extract +#define KLU_condest klu_z_condest +#define KLU_flops klu_z_flops + +#endif + +#else + +#ifdef DLONG + +#define KLU_scale klu_l_scale +#define KLU_solve klu_l_solve +#define KLU_tsolve klu_l_tsolve +#define KLU_free_numeric klu_l_free_numeric +#define KLU_factor klu_l_factor +#define KLU_refactor klu_l_refactor +#define KLU_kernel_factor klu_l_kernel_factor +#define KLU_lsolve klu_l_lsolve +#define KLU_ltsolve klu_l_ltsolve +#define KLU_usolve klu_l_usolve +#define KLU_utsolve klu_l_utsolve +#define KLU_kernel klu_l_kernel +#define KLU_valid klu_l_valid +#define KLU_valid_LU klu_l_valid_LU +#define KLU_sort klu_l_sort +#define KLU_rgrowth klu_l_rgrowth +#define KLU_rcond klu_l_rcond +#define KLU_extract klu_l_extract +#define KLU_condest klu_l_condest +#define KLU_flops klu_l_flops + +#else + +#define KLU_scale klu_scale +#define KLU_solve klu_solve +#define KLU_tsolve klu_tsolve +#define KLU_free_numeric klu_free_numeric +#define KLU_factor klu_factor +#define KLU_refactor klu_refactor +#define KLU_kernel_factor klu_kernel_factor +#define KLU_lsolve klu_lsolve +#define KLU_ltsolve klu_ltsolve +#define KLU_usolve klu_usolve +#define KLU_utsolve klu_utsolve +#define KLU_kernel klu_kernel +#define KLU_valid klu_valid +#define KLU_valid_LU klu_valid_LU +#define KLU_sort klu_sort +#define KLU_rgrowth klu_rgrowth +#define KLU_rcond klu_rcond +#define KLU_extract klu_extract +#define KLU_condest klu_condest +#define KLU_flops klu_flops + +#endif + +#endif + + +#ifdef DLONG + +#define KLU_analyze klu_l_analyze +#define KLU_analyze_given klu_l_analyze_given +#define KLU_alloc_symbolic klu_l_alloc_symbolic +#define KLU_free_symbolic klu_l_free_symbolic +#define KLU_defaults klu_l_defaults +#define KLU_free klu_l_free +#define KLU_malloc klu_l_malloc +#define KLU_realloc klu_l_realloc +#define KLU_add_size_t klu_l_add_size_t +#define KLU_mult_size_t klu_l_mult_size_t + +#define KLU_symbolic klu_l_symbolic +#define KLU_numeric klu_l_numeric +#define KLU_common klu_l_common + +#define BTF_order btf_l_order +#define BTF_strongcomp btf_l_strongcomp + +#define AMD_order amd_l_order +#define COLAMD colamd_l +#define COLAMD_recommended colamd_l_recommended + +#else + +#define KLU_analyze klu_analyze +#define KLU_analyze_given klu_analyze_given +#define KLU_alloc_symbolic klu_alloc_symbolic +#define KLU_free_symbolic klu_free_symbolic +#define KLU_defaults klu_defaults +#define KLU_free klu_free +#define KLU_malloc klu_malloc +#define KLU_realloc klu_realloc +#define KLU_add_size_t klu_add_size_t +#define KLU_mult_size_t klu_mult_size_t + +#define KLU_symbolic klu_symbolic +#define KLU_numeric klu_numeric +#define KLU_common klu_common + +#define BTF_order btf_order +#define BTF_strongcomp btf_strongcomp + +#define AMD_order amd_order +#define COLAMD colamd +#define COLAMD_recommended colamd_recommended + +#endif + + +/* -------------------------------------------------------------------------- */ +/* Numerical relop macros for correctly handling the NaN case */ +/* -------------------------------------------------------------------------- */ + +/* +SCALAR_IS_NAN(x): + True if x is NaN. False otherwise. The commonly-existing isnan(x) + function could be used, but it's not in Kernighan & Ritchie 2nd edition + (ANSI C). It may appear in , but I'm not certain about + portability. The expression x != x is true if and only if x is NaN, + according to the IEEE 754 floating-point standard. + +SCALAR_IS_ZERO(x): + True if x is zero. False if x is nonzero, NaN, or +/- Inf. + This is (x == 0) if the compiler is IEEE 754 compliant. + +SCALAR_IS_NONZERO(x): + True if x is nonzero, NaN, or +/- Inf. False if x zero. + This is (x != 0) if the compiler is IEEE 754 compliant. + +SCALAR_IS_LTZERO(x): + True if x is < zero or -Inf. False if x is >= 0, NaN, or +Inf. + This is (x < 0) if the compiler is IEEE 754 compliant. +*/ + +/* These all work properly, according to the IEEE 754 standard ... except on */ +/* a PC with windows. Works fine in Linux on the same PC... */ +#define SCALAR_IS_NAN(x) ((x) != (x)) +#define SCALAR_IS_ZERO(x) ((x) == 0.) +#define SCALAR_IS_NONZERO(x) ((x) != 0.) +#define SCALAR_IS_LTZERO(x) ((x) < 0.) + + +/* scalar absolute value macro. If x is NaN, the result is NaN: */ +#define SCALAR_ABS(x) ((SCALAR_IS_LTZERO (x)) ? -(x) : (x)) + +/* print a scalar (avoid printing "-0" for negative zero). */ +#ifdef NPRINT +#define PRINT_SCALAR(a) +#else +#define PRINT_SCALAR(a) \ +{ \ + if (SCALAR_IS_NONZERO (a)) \ + { \ + PRINTF ((" (%g)", (a))) ; \ + } \ + else \ + { \ + PRINTF ((" (0)")) ; \ + } \ +} +#endif + +/* -------------------------------------------------------------------------- */ +/* Real floating-point arithmetic */ +/* -------------------------------------------------------------------------- */ + +#ifndef COMPLEX + +typedef double Unit ; +#define Entry double + +#define SPLIT(s) (1) +#define REAL(c) (c) +#define IMAG(c) (0.) +#define ASSIGN(c,s1,s2,p,split) { (c) = (s1)[p] ; } +#define CLEAR(c) { (c) = 0. ; } +#define CLEAR_AND_INCREMENT(p) { *p++ = 0. ; } +#define IS_NAN(a) SCALAR_IS_NAN (a) +#define IS_ZERO(a) SCALAR_IS_ZERO (a) +#define IS_NONZERO(a) SCALAR_IS_NONZERO (a) +#define SCALE_DIV(c,s) { (c) /= (s) ; } +#define SCALE_DIV_ASSIGN(a,c,s) { a = c / s ; } +#define SCALE(c,s) { (c) *= (s) ; } +#define ASSEMBLE(c,a) { (c) += (a) ; } +#define ASSEMBLE_AND_INCREMENT(c,p) { (c) += *p++ ; } +#define DECREMENT(c,a) { (c) -= (a) ; } +#define MULT(c,a,b) { (c) = (a) * (b) ; } +#define MULT_CONJ(c,a,b) { (c) = (a) * (b) ; } +#define MULT_SUB(c,a,b) { (c) -= (a) * (b) ; } +#define MULT_SUB_CONJ(c,a,b) { (c) -= (a) * (b) ; } +#define DIV(c,a,b) { (c) = (a) / (b) ; } +#define RECIPROCAL(c) { (c) = 1.0 / (c) ; } +#define DIV_CONJ(c,a,b) { (c) = (a) / (b) ; } +#define APPROX_ABS(s,a) { (s) = SCALAR_ABS (a) ; } +#define ABS(s,a) { (s) = SCALAR_ABS (a) ; } +#define PRINT_ENTRY(a) PRINT_SCALAR (a) +#define CONJ(a,x) a = x + +/* for flop counts */ +#define MULTSUB_FLOPS 2. /* c -= a*b */ +#define DIV_FLOPS 1. /* c = a/b */ +#define ABS_FLOPS 0. /* c = abs (a) */ +#define ASSEMBLE_FLOPS 1. /* c += a */ +#define DECREMENT_FLOPS 1. /* c -= a */ +#define MULT_FLOPS 1. /* c = a*b */ +#define SCALE_FLOPS 1. /* c = a/s */ + +#else + +/* -------------------------------------------------------------------------- */ +/* Complex floating-point arithmetic */ +/* -------------------------------------------------------------------------- */ + +/* + Note: An alternative to this Double_Complex type would be to use a + struct { double r ; double i ; }. The problem with that method + (used by the Sun Performance Library, for example) is that ANSI C provides + no guarantee about the layout of a struct. It is possible that the sizeof + the struct above would be greater than 2 * sizeof (double). This would + mean that the complex BLAS could not be used. The method used here avoids + that possibility. ANSI C *does* guarantee that an array of structs has + the same size as n times the size of one struct. + + The ANSI C99 version of the C language includes a "double _Complex" type. + It should be possible in that case to do the following: + + #define Entry double _Complex + + and remove the Double_Complex struct. The macros, below, could then be + replaced with instrinsic operators. Note that the #define Real and + #define Imag should also be removed (they only appear in this file). + + For the MULT, MULT_SUB, MULT_SUB_CONJ, and MULT_CONJ macros, + the output argument c cannot be the same as any input argument. + +*/ + +typedef struct +{ + double component [2] ; /* real and imaginary parts */ + +} Double_Complex ; + +typedef Double_Complex Unit ; +#define Entry Double_Complex +#define Real component [0] +#define Imag component [1] + +/* for flop counts */ +#define MULTSUB_FLOPS 8. /* c -= a*b */ +#define DIV_FLOPS 9. /* c = a/b */ +#define ABS_FLOPS 6. /* c = abs (a), count sqrt as one flop */ +#define ASSEMBLE_FLOPS 2. /* c += a */ +#define DECREMENT_FLOPS 2. /* c -= a */ +#define MULT_FLOPS 6. /* c = a*b */ +#define SCALE_FLOPS 2. /* c = a/s or c = a*s */ + +/* -------------------------------------------------------------------------- */ + +/* real part of c */ +#define REAL(c) ((c).Real) + +/* -------------------------------------------------------------------------- */ + +/* imag part of c */ +#define IMAG(c) ((c).Imag) + +/* -------------------------------------------------------------------------- */ + +/* Return TRUE if a complex number is in split form, FALSE if in packed form */ +#define SPLIT(sz) ((sz) != (double *) NULL) + +/* c = (s1) + (s2)*i, if s2 is null, then X is in "packed" format (compatible + * with Entry and ANSI C99 double _Complex type). */ +/*#define ASSIGN(c,s1,s2,p,split) \ +{ \ + if (split) \ + { \ + (c).Real = (s1)[p] ; \ + (c).Imag = (s2)[p] ; \ + } \ + else \ + { \ + (c) = ((Entry *)(s1))[p] ; \ + } \ +}*/ + +/* -------------------------------------------------------------------------- */ +#define CONJ(a, x) \ +{ \ + a.Real = x.Real ; \ + a.Imag = -x.Imag ; \ +} + +/* c = 0 */ +#define CLEAR(c) \ +{ \ + (c).Real = 0. ; \ + (c).Imag = 0. ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* *p++ = 0 */ +#define CLEAR_AND_INCREMENT(p) \ +{ \ + p->Real = 0. ; \ + p->Imag = 0. ; \ + p++ ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* True if a == 0 */ +#define IS_ZERO(a) \ + (SCALAR_IS_ZERO ((a).Real) && SCALAR_IS_ZERO ((a).Imag)) + +/* -------------------------------------------------------------------------- */ + +/* True if a is NaN */ +#define IS_NAN(a) \ + (SCALAR_IS_NAN ((a).Real) || SCALAR_IS_NAN ((a).Imag)) + +/* -------------------------------------------------------------------------- */ + +/* True if a != 0 */ +#define IS_NONZERO(a) \ + (SCALAR_IS_NONZERO ((a).Real) || SCALAR_IS_NONZERO ((a).Imag)) + +/* -------------------------------------------------------------------------- */ + +/* a = c/s */ +#define SCALE_DIV_ASSIGN(a,c,s) \ +{ \ + a.Real = c.Real / s ; \ + a.Imag = c.Imag / s ; \ +} + +/* c /= s */ +#define SCALE_DIV(c,s) \ +{ \ + (c).Real /= (s) ; \ + (c).Imag /= (s) ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c *= s */ +#define SCALE(c,s) \ +{ \ + (c).Real *= (s) ; \ + (c).Imag *= (s) ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c += a */ +#define ASSEMBLE(c,a) \ +{ \ + (c).Real += (a).Real ; \ + (c).Imag += (a).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c += *p++ */ +#define ASSEMBLE_AND_INCREMENT(c,p) \ +{ \ + (c).Real += p->Real ; \ + (c).Imag += p->Imag ; \ + p++ ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c -= a */ +#define DECREMENT(c,a) \ +{ \ + (c).Real -= (a).Real ; \ + (c).Imag -= (a).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c = a*b, assert because c cannot be the same as a or b */ +#define MULT(c,a,b) \ +{ \ + ASSERT (&(c) != &(a) && &(c) != &(b)) ; \ + (c).Real = (a).Real * (b).Real - (a).Imag * (b).Imag ; \ + (c).Imag = (a).Imag * (b).Real + (a).Real * (b).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c = a*conjugate(b), assert because c cannot be the same as a or b */ +#define MULT_CONJ(c,a,b) \ +{ \ + ASSERT (&(c) != &(a) && &(c) != &(b)) ; \ + (c).Real = (a).Real * (b).Real + (a).Imag * (b).Imag ; \ + (c).Imag = (a).Imag * (b).Real - (a).Real * (b).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c -= a*b, assert because c cannot be the same as a or b */ +#define MULT_SUB(c,a,b) \ +{ \ + ASSERT (&(c) != &(a) && &(c) != &(b)) ; \ + (c).Real -= (a).Real * (b).Real - (a).Imag * (b).Imag ; \ + (c).Imag -= (a).Imag * (b).Real + (a).Real * (b).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c -= a*conjugate(b), assert because c cannot be the same as a or b */ +#define MULT_SUB_CONJ(c,a,b) \ +{ \ + ASSERT (&(c) != &(a) && &(c) != &(b)) ; \ + (c).Real -= (a).Real * (b).Real + (a).Imag * (b).Imag ; \ + (c).Imag -= (a).Imag * (b).Real - (a).Real * (b).Imag ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* c = a/b, be careful to avoid underflow and overflow */ +#ifdef MATHWORKS +#define DIV(c,a,b) \ +{ \ + (void) utDivideComplex ((a).Real, (a).Imag, (b).Real, (b).Imag, \ + &((c).Real), &((c).Imag)) ; \ +} +#else +/* This uses ACM Algo 116, by R. L. Smith, 1962. */ +/* c can be the same variable as a or b. */ +/* Ignore NaN case for double relop br>=bi. */ +#define DIV(c,a,b) \ +{ \ + double r, den, ar, ai, br, bi ; \ + br = (b).Real ; \ + bi = (b).Imag ; \ + ar = (a).Real ; \ + ai = (a).Imag ; \ + if (SCALAR_ABS (br) >= SCALAR_ABS (bi)) \ + { \ + r = bi / br ; \ + den = br + r * bi ; \ + (c).Real = (ar + ai * r) / den ; \ + (c).Imag = (ai - ar * r) / den ; \ + } \ + else \ + { \ + r = br / bi ; \ + den = r * br + bi ; \ + (c).Real = (ar * r + ai) / den ; \ + (c).Imag = (ai * r - ar) / den ; \ + } \ +} +#endif + +/* -------------------------------------------------------------------------- */ + +/* c = 1/c, be careful to avoid underflow and overflow */ +/* Not used if MATHWORKS is defined. */ +/* This uses ACM Algo 116, by R. L. Smith, 1962. */ +/* Ignore NaN case for double relop cr>=ci. */ +#define RECIPROCAL(c) \ +{ \ + double r, den, cr, ci ; \ + cr = (c).Real ; \ + ci = (c).Imag ; \ + if (SCALAR_ABS (cr) >= SCALAR_ABS (ci)) \ + { \ + r = ci / cr ; \ + den = cr + r * ci ; \ + (c).Real = 1.0 / den ; \ + (c).Imag = - r / den ; \ + } \ + else \ + { \ + r = cr / ci ; \ + den = r * cr + ci ; \ + (c).Real = r / den ; \ + (c).Imag = - 1.0 / den ; \ + } \ +} + + +/* -------------------------------------------------------------------------- */ + +/* c = a/conjugate(b), be careful to avoid underflow and overflow */ +#ifdef MATHWORKS +#define DIV_CONJ(c,a,b) \ +{ \ + (void) utDivideComplex ((a).Real, (a).Imag, (b).Real, (-(b).Imag), \ + &((c).Real), &((c).Imag)) ; \ +} +#else +/* This uses ACM Algo 116, by R. L. Smith, 1962. */ +/* c can be the same variable as a or b. */ +/* Ignore NaN case for double relop br>=bi. */ +#define DIV_CONJ(c,a,b) \ +{ \ + double r, den, ar, ai, br, bi ; \ + br = (b).Real ; \ + bi = (b).Imag ; \ + ar = (a).Real ; \ + ai = (a).Imag ; \ + if (SCALAR_ABS (br) >= SCALAR_ABS (bi)) \ + { \ + r = (-bi) / br ; \ + den = br - r * bi ; \ + (c).Real = (ar + ai * r) / den ; \ + (c).Imag = (ai - ar * r) / den ; \ + } \ + else \ + { \ + r = br / (-bi) ; \ + den = r * br - bi; \ + (c).Real = (ar * r + ai) / den ; \ + (c).Imag = (ai * r - ar) / den ; \ + } \ +} +#endif + +/* -------------------------------------------------------------------------- */ + +/* approximate absolute value, s = |r|+|i| */ +#define APPROX_ABS(s,a) \ +{ \ + (s) = SCALAR_ABS ((a).Real) + SCALAR_ABS ((a).Imag) ; \ +} + +/* -------------------------------------------------------------------------- */ + +/* exact absolute value, s = sqrt (a.real^2 + amag^2) */ +#ifdef MATHWORKS +#define ABS(s,a) \ +{ \ + (s) = utFdlibm_hypot ((a).Real, (a).Imag) ; \ +} +#else +/* Ignore NaN case for the double relops ar>=ai and ar+ai==ar. */ +#define ABS(s,a) \ +{ \ + double r, ar, ai ; \ + ar = SCALAR_ABS ((a).Real) ; \ + ai = SCALAR_ABS ((a).Imag) ; \ + if (ar >= ai) \ + { \ + if (ar + ai == ar) \ + { \ + (s) = ar ; \ + } \ + else \ + { \ + r = ai / ar ; \ + (s) = ar * sqrt (1.0 + r*r) ; \ + } \ + } \ + else \ + { \ + if (ai + ar == ai) \ + { \ + (s) = ai ; \ + } \ + else \ + { \ + r = ar / ai ; \ + (s) = ai * sqrt (1.0 + r*r) ; \ + } \ + } \ +} +#endif + +/* -------------------------------------------------------------------------- */ + +/* print an entry (avoid printing "-0" for negative zero). */ +#ifdef NPRINT +#define PRINT_ENTRY(a) +#else +#define PRINT_ENTRY(a) \ +{ \ + if (SCALAR_IS_NONZERO ((a).Real)) \ + { \ + PRINTF ((" (%g", (a).Real)) ; \ + } \ + else \ + { \ + PRINTF ((" (0")) ; \ + } \ + if (SCALAR_IS_LTZERO ((a).Imag)) \ + { \ + PRINTF ((" - %gi)", -(a).Imag)) ; \ + } \ + else if (SCALAR_IS_ZERO ((a).Imag)) \ + { \ + PRINTF ((" + 0i)")) ; \ + } \ + else \ + { \ + PRINTF ((" + %gi)", (a).Imag)) ; \ + } \ +} +#endif + +/* -------------------------------------------------------------------------- */ + +#endif /* #ifndef COMPLEX */ + +#endif diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Contents.m b/OpenDSSC/klusolve/KLU/MATLAB/Contents.m new file mode 100644 index 0000000..e8dcfd9 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Contents.m @@ -0,0 +1,16 @@ +% KLU: a "Clark Kent" LU factorization algorithm +% +% klu - sparse left-looking LU factorization, using a block triangular form. +% klu_install - compiles and installs the KLU, BTF, AMD, and COLAMD mexFunctions +% klu_demo - KLU demo +% klu_make - compiles the KLU mexFunctions +% +% Example: +% +% LU = klu (A) ; +% x = klu (A, '\', b) ; +% x = klu (LU, '\', b) ; +% +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% KLU Version 1.0. + diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Makefile b/OpenDSSC/klusolve/KLU/MATLAB/Makefile new file mode 100644 index 0000000..0be69ca --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Makefile @@ -0,0 +1,699 @@ +#=============================================================================== +# KLU/MATLAB/Makefile +#=============================================================================== + +default: all + +include ../../UFconfig/UFconfig.mk + +# with CHOLMOD and supporting functions (CAMD, CCOLAMD, METIS) +I = -I. -I../../AMD/Include -I../../COLAMD/Include \ + -I../Include -I../../UFconfig -I../../BTF/Include -I../User \ + -I../../CCOLAMD/Include -I../../CAMD/Include \ + -I$(METIS_PATH)/Lib -I../../CHOLMOD/Include + +all: klu + +MX = $(MEX) -DDLONG -DNLARGEFILE $(I) + +distclean: purge + +purge: clean + - $(RM) *.mex* rename.h + +clean: + - $(RM) $(CLEAN) + +#=============================================================================== + +AMD_INC = ../../AMD/Include/amd.h ../../AMD/Include/amd_internal.h + +AMD = \ + amd_1.o \ + amd_2.o \ + amd_aat.o \ + amd_control.o \ + amd_defaults.o \ + amd_dump.o \ + amd_global.o \ + amd_info.o \ + amd_order.o \ + amd_postorder.o \ + amd_post_tree.o \ + amd_preprocess.o \ + amd_valid.o + +$(AMD): $(AMD_INC) +amd_1.o: ../../AMD/Source/amd_1.c + $(MX) -c $< + +amd_2.o: ../../AMD/Source/amd_2.c + $(MX) -c $< + +amd_aat.o: ../../AMD/Source/amd_aat.c + $(MX) -c $< + +amd_control.o: ../../AMD/Source/amd_control.c + $(MX) -c $< + +amd_defaults.o: ../../AMD/Source/amd_defaults.c + $(MX) -c $< + +amd_dump.o: ../../AMD/Source/amd_dump.c + $(MX) -c $< + +amd_global.o: ../../AMD/Source/amd_global.c + $(MX) -c $< + +amd_info.o: ../../AMD/Source/amd_info.c + $(MX) -c $< + +amd_order.o: ../../AMD/Source/amd_order.c + $(MX) -c $< + +amd_postorder.o: ../../AMD/Source/amd_postorder.c + $(MX) -c $< + +amd_post_tree.o: ../../AMD/Source/amd_post_tree.c + $(MX) -c $< + +amd_preprocess.o: ../../AMD/Source/amd_preprocess.c + $(MX) -c $< + +amd_valid.o: ../../AMD/Source/amd_valid.c + $(MX) -c $< + +#=============================================================================== + +CAMD_INC = ../../CAMD/Include/camd.h ../../CAMD/Include/camd_internal.h + +CAMD = \ + camd_1.o \ + camd_2.o \ + camd_aat.o \ + camd_control.o \ + camd_defaults.o \ + camd_dump.o \ + camd_global.o \ + camd_info.o \ + camd_order.o \ + camd_postorder.o \ + camd_preprocess.o \ + camd_valid.o + +$(CAMD): $(CAMD_INC) + +camd_1.o: ../../CAMD/Source/camd_1.c + $(MX) -c $< + +camd_2.o: ../../CAMD/Source/camd_2.c + $(MX) -c $< + +camd_aat.o: ../../CAMD/Source/camd_aat.c + $(MX) -c $< + +camd_control.o: ../../CAMD/Source/camd_control.c + $(MX) -c $< + +camd_defaults.o: ../../CAMD/Source/camd_defaults.c + $(MX) -c $< + +camd_dump.o: ../../CAMD/Source/camd_dump.c + $(MX) -c $< + +camd_global.o: ../../CAMD/Source/camd_global.c + $(MX) -c $< + +camd_info.o: ../../CAMD/Source/camd_info.c + $(MX) -c $< + +camd_order.o: ../../CAMD/Source/camd_order.c + $(MX) -c $< + +camd_postorder.o: ../../CAMD/Source/camd_postorder.c + $(MX) -c $< + +camd_post_tree.o: ../../CAMD/Source/camd_post_tree.c + $(MX) -c $< + +camd_preprocess.o: ../../CAMD/Source/camd_preprocess.c + $(MX) -c $< + +camd_valid.o: ../../CAMD/Source/camd_valid.c + $(MX) -c $< + +#=============================================================================== + +COLAMD_INC = ../../COLAMD/Include/colamd.h + +COLAMD = colamd.o colamd_global.o + +$(COLAMD): $(COLAMD_INC) + +colamd.o: ../../COLAMD/Source/colamd.c + $(MX) -c $< + +colamd_global.o: ../../COLAMD/Source/colamd_global.c + $(MX) -c $< + +#=============================================================================== + +CCOLAMD_INC = ../../CCOLAMD/Include/ccolamd.h + +CCOLAMD = ccolamd.o ccolamd_global.o + +$(CCOLAMD): $(CCOLAMD_INC) + +ccolamd.o: ../../CCOLAMD/Source/ccolamd.c + $(MX) -c $< + +ccolamd_global.o: ../../CCOLAMD/Source/ccolamd_global.c + $(MX) -c $< + +#=============================================================================== + +# patch METIS 4.0.1 +rename.h: $(METIS_PATH)/Lib/rename.h + echo '/* do not edit this file; generated by KLU/MATLAB/Makefile */' > rename.h + echo '#undef log2' >> rename.h + echo '#include "$(METIS_PATH)/Lib/rename.h"' >> rename.h + echo '#undef log2' >> rename.h + echo '#define log2 METIS__log2' >> rename.h + echo '#include "mex.h"' >> rename.h + echo '#define malloc mxMalloc' >> rename.h + echo '#define free mxFree' >> rename.h + echo '#define calloc mxCalloc' >> rename.h + echo '#define realloc mxRealloc' >> rename.h + +METIS_INC = rename.h \ + $(METIS_PATH)/Lib/defs.h \ + $(METIS_PATH)/Lib/macros.h \ + $(METIS_PATH)/Lib/metis.h \ + $(METIS_PATH)/Lib/proto.h \ + $(METIS_PATH)/Lib/rename.h \ + $(METIS_PATH)/Lib/struct.h + +METIS = \ + balance.o \ + bucketsort.o \ + ccgraph.o \ + coarsen.o \ + compress.o \ + debug.o \ + estmem.o \ + fm.o \ + fortran.o \ + frename.o \ + graph.o \ + initpart.o \ + kmetis.o \ + kvmetis.o \ + kwayfm.o \ + kwayrefine.o \ + kwayvolfm.o \ + kwayvolrefine.o \ + match.o \ + mbalance2.o \ + mbalance.o \ + mcoarsen.o \ + memory.o \ + mesh.o \ + meshpart.o \ + mfm2.o \ + mfm.o \ + mincover.o \ + minitpart2.o \ + minitpart.o \ + mkmetis.o \ + mkwayfmh.o \ + mkwayrefine.o \ + mmatch.o \ + mmd.o \ + mpmetis.o \ + mrefine2.o \ + mrefine.o \ + mutil.o \ + myqsort.o \ + ometis.o \ + parmetis.o \ + pmetis.o \ + pqueue.o \ + refine.o \ + separator.o \ + sfm.o \ + srefine.o \ + stat.o \ + subdomains.o \ + timing.o \ + util.o + +$(METIS): $(METIS_INC) + +balance.o: $(METIS_PATH)/Lib/balance.c + $(MX) -c $< + +bucketsort.o: $(METIS_PATH)/Lib/bucketsort.c + $(MX) -c $< + +ccgraph.o: $(METIS_PATH)/Lib/ccgraph.c + $(MX) -c $< + +coarsen.o: $(METIS_PATH)/Lib/coarsen.c + $(MX) -c $< + +compress.o: $(METIS_PATH)/Lib/compress.c + $(MX) -c $< + +debug.o: $(METIS_PATH)/Lib/debug.c + $(MX) -c $< + +estmem.o: $(METIS_PATH)/Lib/estmem.c + $(MX) -c $< + +fm.o: $(METIS_PATH)/Lib/fm.c + $(MX) -c $< + +fortran.o: $(METIS_PATH)/Lib/fortran.c + $(MX) -c $< + +frename.o: $(METIS_PATH)/Lib/frename.c + $(MX) -c $< + +graph.o: $(METIS_PATH)/Lib/graph.c + $(MX) -c $< + +initpart.o: $(METIS_PATH)/Lib/initpart.c + $(MX) -c $< + +kmetis.o: $(METIS_PATH)/Lib/kmetis.c + $(MX) -c $< + +kvmetis.o: $(METIS_PATH)/Lib/kvmetis.c + $(MX) -c $< + +kwayfm.o: $(METIS_PATH)/Lib/kwayfm.c + $(MX) -c $< + +kwayrefine.o: $(METIS_PATH)/Lib/kwayrefine.c + $(MX) -c $< + +kwayvolfm.o: $(METIS_PATH)/Lib/kwayvolfm.c + $(MX) -c $< + +kwayvolrefine.o: $(METIS_PATH)/Lib/kwayvolrefine.c + $(MX) -c $< + +match.o: $(METIS_PATH)/Lib/match.c + $(MX) -c $< + +mbalance2.o: $(METIS_PATH)/Lib/mbalance2.c + $(MX) -c $< + +mbalance.o: $(METIS_PATH)/Lib/mbalance.c + $(MX) -c $< + +mcoarsen.o: $(METIS_PATH)/Lib/mcoarsen.c + $(MX) -c $< + +memory.o: $(METIS_PATH)/Lib/memory.c + $(MX) -c $< + +mesh.o: $(METIS_PATH)/Lib/mesh.c + $(MX) -c $< + +meshpart.o: $(METIS_PATH)/Lib/meshpart.c + $(MX) -c $< + +mfm2.o: $(METIS_PATH)/Lib/mfm2.c + $(MX) -c $< + +mfm.o: $(METIS_PATH)/Lib/mfm.c + $(MX) -c $< + +mincover.o: $(METIS_PATH)/Lib/mincover.c + $(MX) -c $< + +minitpart2.o: $(METIS_PATH)/Lib/minitpart2.c + $(MX) -c $< + +minitpart.o: $(METIS_PATH)/Lib/minitpart.c + $(MX) -c $< + +mkmetis.o: $(METIS_PATH)/Lib/mkmetis.c + $(MX) -c $< + +mkwayfmh.o: $(METIS_PATH)/Lib/mkwayfmh.c + $(MX) -c $< + +mkwayrefine.o: $(METIS_PATH)/Lib/mkwayrefine.c + $(MX) -c $< + +mmatch.o: $(METIS_PATH)/Lib/mmatch.c + $(MX) -c $< + +mmd.o: $(METIS_PATH)/Lib/mmd.c + $(MX) -c $< + +mpmetis.o: $(METIS_PATH)/Lib/mpmetis.c + $(MX) -c $< + +mrefine2.o: $(METIS_PATH)/Lib/mrefine2.c + $(MX) -c $< + +mrefine.o: $(METIS_PATH)/Lib/mrefine.c + $(MX) -c $< + +mutil.o: $(METIS_PATH)/Lib/mutil.c + $(MX) -c $< + +myqsort.o: $(METIS_PATH)/Lib/myqsort.c + $(MX) -c $< + +ometis.o: $(METIS_PATH)/Lib/ometis.c + $(MX) -c $< + +parmetis.o: $(METIS_PATH)/Lib/parmetis.c + $(MX) -c $< + +pmetis.o: $(METIS_PATH)/Lib/pmetis.c + $(MX) -c $< + +pqueue.o: $(METIS_PATH)/Lib/pqueue.c + $(MX) -c $< + +refine.o: $(METIS_PATH)/Lib/refine.c + $(MX) -c $< + +separator.o: $(METIS_PATH)/Lib/separator.c + $(MX) -c $< + +sfm.o: $(METIS_PATH)/Lib/sfm.c + $(MX) -c $< + +srefine.o: $(METIS_PATH)/Lib/srefine.c + $(MX) -c $< + +stat.o: $(METIS_PATH)/Lib/stat.c + $(MX) -c $< + +subdomains.o: $(METIS_PATH)/Lib/subdomains.c + $(MX) -c $< + +timing.o: $(METIS_PATH)/Lib/timing.c + $(MX) -c $< + +util.o: $(METIS_PATH)/Lib/util.c + $(MX) -c $< + +#=============================================================================== + +CHOLMOD_INC = \ + ../../CHOLMOD/Include/cholmod_blas.h \ + ../../CHOLMOD/Include/cholmod_cholesky.h \ + ../../CHOLMOD/Include/cholmod_complexity.h \ + ../../CHOLMOD/Include/cholmod_config.h \ + ../../CHOLMOD/Include/cholmod_core.h \ + ../../CHOLMOD/Include/cholmod.h \ + ../../CHOLMOD/Include/cholmod_internal.h \ + ../../CHOLMOD/Include/cholmod_io64.h \ + ../../CHOLMOD/Include/cholmod_partition.h \ + ../../CHOLMOD/Include/cholmod_template.h + +CHOLMOD = \ + cholmod_amd.o \ + cholmod_analyze.o \ + cholmod_colamd.o \ + cholmod_etree.o \ + cholmod_postorder.o \ + cholmod_rowcolcounts.o \ + cholmod_aat.o \ + cholmod_add.o \ + cholmod_band.o \ + cholmod_change_factor.o \ + cholmod_common.o \ + cholmod_complex.o \ + cholmod_copy.o \ + cholmod_dense.o \ + cholmod_error.o \ + cholmod_factor.o \ + cholmod_memory.o \ + cholmod_sparse.o \ + cholmod_transpose.o \ + cholmod_triplet.o \ + cholmod_camd.o \ + cholmod_ccolamd.o \ + cholmod_csymamd.o \ + cholmod_metis.o \ + cholmod_nesdis.o + +$(CHOLMOD): $(CHOLMOD_INC) + +CH = -DNSUPERNODAL -DNMODIFY -DNMATRIXOPS -DNCHECK + +cholmod_amd.o: ../../CHOLMOD/Cholesky/cholmod_amd.c + $(MX) $(CH) -c $< + +cholmod_analyze.o: ../../CHOLMOD/Cholesky/cholmod_analyze.c + $(MX) $(CH) -c $< + +cholmod_colamd.o: ../../CHOLMOD/Cholesky/cholmod_colamd.c + $(MX) $(CH) -c $< + +cholmod_etree.o: ../../CHOLMOD/Cholesky/cholmod_etree.c + $(MX) $(CH) -c $< + +cholmod_postorder.o: ../../CHOLMOD/Cholesky/cholmod_postorder.c + $(MX) $(CH) -c $< + +cholmod_rowcolcounts.o: ../../CHOLMOD/Cholesky/cholmod_rowcolcounts.c + $(MX) $(CH) -c $< + +cholmod_aat.o: ../../CHOLMOD/Core/cholmod_aat.c + $(MX) $(CH) -c $< + +cholmod_add.o: ../../CHOLMOD/Core/cholmod_add.c + $(MX) $(CH) -c $< + +cholmod_band.o: ../../CHOLMOD/Core/cholmod_band.c + $(MX) $(CH) -c $< + +cholmod_change_factor.o: ../../CHOLMOD/Core/cholmod_change_factor.c \ + ../../CHOLMOD/Core/t_cholmod_change_factor.c + $(MX) $(CH) -c $< + +cholmod_common.o: ../../CHOLMOD/Core/cholmod_common.c + $(MX) $(CH) -c $< + +cholmod_complex.o: ../../CHOLMOD/Core/cholmod_complex.c + $(MX) $(CH) -c $< + +cholmod_copy.o: ../../CHOLMOD/Core/cholmod_copy.c + $(MX) $(CH) -c $< + +cholmod_dense.o: ../../CHOLMOD/Core/cholmod_dense.c \ + ../../CHOLMOD/Core/t_cholmod_dense.c + $(MX) $(CH) -c $< + +cholmod_error.o: ../../CHOLMOD/Core/cholmod_error.c + $(MX) $(CH) -c $< + +cholmod_factor.o: ../../CHOLMOD/Core/cholmod_factor.c + $(MX) $(CH) -c $< + +cholmod_memory.o: ../../CHOLMOD/Core/cholmod_memory.c + $(MX) $(CH) -c $< + +cholmod_sparse.o: ../../CHOLMOD/Core/cholmod_sparse.c + $(MX) $(CH) -c $< + +cholmod_transpose.o: ../../CHOLMOD/Core/cholmod_transpose.c \ + ../../CHOLMOD/Core/t_cholmod_transpose.c + $(MX) $(CH) -c $< + +cholmod_triplet.o: ../../CHOLMOD/Core/cholmod_triplet.c \ + ../../CHOLMOD/Core/t_cholmod_triplet.c + $(MX) $(CH) -c $< + +cholmod_camd.o: ../../CHOLMOD/Partition/cholmod_camd.c + $(MX) $(CH) -c $< + +cholmod_ccolamd.o: ../../CHOLMOD/Partition/cholmod_ccolamd.c + $(MX) $(CH) -c $< + +cholmod_csymamd.o: ../../CHOLMOD/Partition/cholmod_csymamd.c + $(MX) $(CH) -c $< + +cholmod_metis.o: ../../CHOLMOD/Partition/cholmod_metis.c + $(MX) $(CH) -c $< + +cholmod_nesdis.o: ../../CHOLMOD/Partition/cholmod_nesdis.c + $(MX) $(CH) -c $< + +#=============================================================================== + +BTF_INC = ../../BTF/Include/btf.h ../../BTF/Include/btf_internal.h + +BTF = btf_maxtrans.o btf_order.o btf_strongcomp.o + +$(BTF): $(BTF_INC) + +btf_maxtrans.o: ../../BTF/Source/btf_maxtrans.c + $(MX) -c $< + +btf_order.o: ../../BTF/Source/btf_order.c + $(MX) -c $< + +btf_strongcomp.o: ../../BTF/Source/btf_strongcomp.c + $(MX) -c $< + +#=============================================================================== + +KLU_INC = ../Include/klu.h ../Include/klu_internal.h ../Include/klu_version.h \ + ../User/klu_cholmod.h + +KLU_L = klu_l.o klu_l_kernel.o klu_l_dump.o \ + klu_l_factor.o klu_l_free_numeric.o klu_l_solve.o \ + klu_l_scale.o klu_l_refactor.o \ + klu_l_tsolve.o klu_l_diagnostics.o klu_l_sort.o klu_l_extract.o + +KLU_ZL = klu_zl.o klu_zl_kernel.o klu_zl_dump.o \ + klu_zl_factor.o klu_zl_free_numeric.o klu_zl_solve.o \ + klu_zl_scale.o klu_zl_refactor.o \ + klu_zl_tsolve.o klu_zl_diagnostics.o klu_zl_sort.o klu_zl_extract.o + +COMMON = klu_free_symbolic.o klu_defaults.o klu_analyze_given.o \ + klu_analyze.o klu_memory.o + +USER = klu_l_cholmod.o + +KLU = $(COMMON) $(KLU_L) $(KLU_ZL) $(USER) + +$(KLU): $(KLU_INC) + +#------------------------------------------------------------------------------- + +klu_l.o: ../Source/klu.c + $(MX) -c $< + $(MV) klu.o $@ + +klu_zl.o: ../Source/klu.c + $(MX) -c -DCOMPLEX $< + $(MV) klu.o $@ + +klu_l_kernel.o: ../Source/klu_kernel.c + $(MX) -c $< + $(MV) klu_kernel.o $@ + +klu_zl_kernel.o: ../Source/klu_kernel.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_kernel.o $@ + +klu_l_sort.o: ../Source/klu_sort.c + $(MX) -c $< + $(MV) klu_sort.o $@ + +klu_zl_sort.o: ../Source/klu_sort.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_sort.o $@ + +klu_l_diagnostics.o: ../Source/klu_diagnostics.c + $(MX) -c $< + $(MV) klu_diagnostics.o $@ + +klu_zl_diagnostics.o: ../Source/klu_diagnostics.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_diagnostics.o $@ + +klu_l_dump.o: ../Source/klu_dump.c + $(MX) -c $< + $(MV) klu_dump.o $@ + +klu_zl_dump.o: ../Source/klu_dump.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_dump.o $@ + +klu_l_factor.o: ../Source/klu_factor.c + $(MX) -c $< + $(MV) klu_factor.o $@ + +klu_zl_factor.o: ../Source/klu_factor.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_factor.o $@ + +klu_l_free_numeric.o: ../Source/klu_free_numeric.c + $(MX) -c $< + $(MV) klu_free_numeric.o $@ + +klu_zl_free_numeric.o: ../Source/klu_free_numeric.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_free_numeric.o $@ + +klu_l_extract.o: ../Source/klu_extract.c + $(MX) -c $< + $(MV) klu_extract.o $@ + +klu_zl_extract.o: ../Source/klu_extract.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_extract.o $@ + +klu_l_refactor.o: ../Source/klu_refactor.c + $(MX) -c $< + $(MV) klu_refactor.o $@ + +klu_zl_refactor.o: ../Source/klu_refactor.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_refactor.o $@ + +klu_l_scale.o: ../Source/klu_scale.c + $(MX) -c $< + $(MV) klu_scale.o $@ + +klu_zl_scale.o: ../Source/klu_scale.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_scale.o $@ + +klu_l_solve.o: ../Source/klu_solve.c + $(MX) -c $< + $(MV) klu_solve.o $@ + +klu_zl_solve.o: ../Source/klu_solve.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_solve.o $@ + +klu_l_tsolve.o: ../Source/klu_tsolve.c + $(MX) -c $< + $(MV) klu_tsolve.o $@ + +klu_zl_tsolve.o: ../Source/klu_tsolve.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_tsolve.o $@ + +#------------------------------------------------------------------------------- + +klu_analyze.o: ../Source/klu_analyze.c + $(MX) -c $< + +klu_analyze_given.o: ../Source/klu_analyze_given.c + $(MX) -c $< + +klu_defaults.o: ../Source/klu_defaults.c + $(MX) -c $< + +klu_free_symbolic.o: ../Source/klu_free_symbolic.c + $(MX) -c $< + +klu_memory.o: ../Source/klu_memory.c + $(MX) -c $< + +#------------------------------------------------------------------------------- + +klu_l_cholmod.o: ../User/klu_l_cholmod.c + $(MX) $(CH) -c $< + +#=============================================================================== + +OBJ = $(AMD) $(CAMD) $(COLAMD) $(CCOLAMD) $(METIS) $(CHOLMOD) $(KLU) $(BTF) + +klu: klu_mex.c $(OBJ) + $(MX) -output klu klu_mex.c $(OBJ) + diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Makefile_no_CHOLMOD b/OpenDSSC/klusolve/KLU/MATLAB/Makefile_no_CHOLMOD new file mode 100644 index 0000000..9e30248 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Makefile_no_CHOLMOD @@ -0,0 +1,263 @@ +#=============================================================================== +# KLU/MATLAB/Makefile_no_CHOLMOD +#=============================================================================== + +# Makefile for klu mexFunction, without the use of CHOLMOD. Ordering options +# 3 and 4 for klu will not be available. See "help klu" in MATLAB for more +# details. Usage: +# +# make -f Makefile_no_CHOLMOD + +default: all + +include ../../UFconfig/UFconfig.mk + +# without CHOLMOD +I = -I. -I../../AMD/Include -I../../AMD/Source -I../../COLAMD/Include \ + -I../Include -I../../UFconfig -I../../BTF/Include + +all: klu + +MX = $(MEX) -DDLONG -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE $(I) + +distclean: purge + +purge: clean + - $(RM) *.mex* rename.h + +clean: + - $(RM) $(CLEAN) + +#=============================================================================== + +AMD_INC = ../../AMD/Include/amd.h ../../AMD/Include/amd_internal.h + +AMD = \ + amd_1.o \ + amd_2.o \ + amd_aat.o \ + amd_control.o \ + amd_defaults.o \ + amd_dump.o \ + amd_global.o \ + amd_info.o \ + amd_order.o \ + amd_postorder.o \ + amd_post_tree.o \ + amd_preprocess.o \ + amd_valid.o + +$(AMD): $(AMD_INC) +amd_1.o: ../../AMD/Source/amd_1.c + $(MX) -c $< + +amd_2.o: ../../AMD/Source/amd_2.c + $(MX) -c $< + +amd_aat.o: ../../AMD/Source/amd_aat.c + $(MX) -c $< + +amd_control.o: ../../AMD/Source/amd_control.c + $(MX) -c $< + +amd_defaults.o: ../../AMD/Source/amd_defaults.c + $(MX) -c $< + +amd_dump.o: ../../AMD/Source/amd_dump.c + $(MX) -c $< + +amd_global.o: ../../AMD/Source/amd_global.c + $(MX) -c $< + +amd_info.o: ../../AMD/Source/amd_info.c + $(MX) -c $< + +amd_order.o: ../../AMD/Source/amd_order.c + $(MX) -c $< + +amd_postorder.o: ../../AMD/Source/amd_postorder.c + $(MX) -c $< + +amd_post_tree.o: ../../AMD/Source/amd_post_tree.c + $(MX) -c $< + +amd_preprocess.o: ../../AMD/Source/amd_preprocess.c + $(MX) -c $< + +amd_valid.o: ../../AMD/Source/amd_valid.c + $(MX) -c $< + +#=============================================================================== + +COLAMD_INC = ../../COLAMD/Include/colamd.h + +COLAMD = colamd.o colamd_global.o + +$(COLAMD): $(COLAMD_INC) + +colamd.o: ../../COLAMD/Source/colamd.c + $(MX) -c $< + +colamd_global.o: ../../COLAMD/Source/colamd_global.c + $(MX) -c $< + +#=============================================================================== + +BTF_INC = ../../BTF/Include/btf.h ../../BTF/Include/btf_internal.h + +BTF = btf_maxtrans.o btf_order.o btf_strongcomp.o + +$(BTF): $(BTF_INC) + +btf_maxtrans.o: ../../BTF/Source/btf_maxtrans.c + $(MX) -c $< + +btf_order.o: ../../BTF/Source/btf_order.c + $(MX) -c $< + +btf_strongcomp.o: ../../BTF/Source/btf_strongcomp.c + $(MX) -c $< + +#=============================================================================== + +KLU_INC = ../Include/klu.h ../Include/klu_internal.h ../Include/klu_version.h + +KLU_L = klu_l.o klu_l_kernel.o klu_l_dump.o \ + klu_l_factor.o klu_l_free_numeric.o klu_l_solve.o \ + klu_l_scale.o klu_l_refactor.o \ + klu_l_tsolve.o klu_l_diagnostics.o klu_l_sort.o klu_l_extract.o + +KLU_ZL = klu_zl.o klu_zl_kernel.o klu_zl_dump.o \ + klu_zl_factor.o klu_zl_free_numeric.o klu_zl_solve.o \ + klu_zl_scale.o klu_zl_refactor.o \ + klu_zl_tsolve.o klu_zl_diagnostics.o klu_zl_sort.o klu_zl_extract.o + +COMMON = klu_free_symbolic.o klu_defaults.o klu_analyze_given.o \ + klu_analyze.o klu_memory.o + +KLU = $(COMMON) $(KLU_L) $(KLU_ZL) + +$(KLU): $(KLU_INC) + +#------------------------------------------------------------------------------- + +klu_l.o: ../Source/klu.c + $(MX) -c $< + $(MV) klu.o $@ + +klu_zl.o: ../Source/klu.c + $(MX) -c -DCOMPLEX $< + $(MV) klu.o $@ + +klu_l_kernel.o: ../Source/klu_kernel.c + $(MX) -c $< + $(MV) klu_kernel.o $@ + +klu_zl_kernel.o: ../Source/klu_kernel.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_kernel.o $@ + +klu_l_sort.o: ../Source/klu_sort.c + $(MX) -c $< + $(MV) klu_sort.o $@ + +klu_zl_sort.o: ../Source/klu_sort.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_sort.o $@ + +klu_l_diagnostics.o: ../Source/klu_diagnostics.c + $(MX) -c $< + $(MV) klu_diagnostics.o $@ + +klu_zl_diagnostics.o: ../Source/klu_diagnostics.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_diagnostics.o $@ + +klu_l_dump.o: ../Source/klu_dump.c + $(MX) -c $< + $(MV) klu_dump.o $@ + +klu_zl_dump.o: ../Source/klu_dump.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_dump.o $@ + +klu_l_factor.o: ../Source/klu_factor.c + $(MX) -c $< + $(MV) klu_factor.o $@ + +klu_zl_factor.o: ../Source/klu_factor.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_factor.o $@ + +klu_l_free_numeric.o: ../Source/klu_free_numeric.c + $(MX) -c $< + $(MV) klu_free_numeric.o $@ + +klu_zl_free_numeric.o: ../Source/klu_free_numeric.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_free_numeric.o $@ + +klu_l_extract.o: ../Source/klu_extract.c + $(MX) -c $< + $(MV) klu_extract.o $@ + +klu_zl_extract.o: ../Source/klu_extract.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_extract.o $@ + +klu_l_refactor.o: ../Source/klu_refactor.c + $(MX) -c $< + $(MV) klu_refactor.o $@ + +klu_zl_refactor.o: ../Source/klu_refactor.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_refactor.o $@ + +klu_l_scale.o: ../Source/klu_scale.c + $(MX) -c $< + $(MV) klu_scale.o $@ + +klu_zl_scale.o: ../Source/klu_scale.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_scale.o $@ + +klu_l_solve.o: ../Source/klu_solve.c + $(MX) -c $< + $(MV) klu_solve.o $@ + +klu_zl_solve.o: ../Source/klu_solve.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_solve.o $@ + +klu_l_tsolve.o: ../Source/klu_tsolve.c + $(MX) -c $< + $(MV) klu_tsolve.o $@ + +klu_zl_tsolve.o: ../Source/klu_tsolve.c + $(MX) -c -DCOMPLEX $< + $(MV) klu_tsolve.o $@ + +#------------------------------------------------------------------------------- + +klu_analyze.o: ../Source/klu_analyze.c + $(MX) -c $< + +klu_analyze_given.o: ../Source/klu_analyze_given.c + $(MX) -c $< + +klu_defaults.o: ../Source/klu_defaults.c + $(MX) -c $< + +klu_free_symbolic.o: ../Source/klu_free_symbolic.c + $(MX) -c $< + +klu_memory.o: ../Source/klu_memory.c + $(MX) -c $< + +#=============================================================================== + +OBJ = $(AMD) $(COLAMD) $(KLU) $(BTF) + +klu: klu_mex.c $(OBJ) + $(MX) -DNCHOLMOD -output klu klu_mex.c $(OBJ) + diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/klu_test.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/klu_test.m new file mode 100644 index 0000000..0574ed5 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/klu_test.m @@ -0,0 +1,19 @@ +function klu_test (nmat) +%klu_test KLU test +% Example: +% klu_test +% +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 1) + nmat = 500 ; +end + +test1 (nmat) ; +test2 (nmat) ; +test3 ; +test4 (nmat) ; +test5 ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/test1.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/test1.m new file mode 100644 index 0000000..ce3cf1b --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/test1.m @@ -0,0 +1,117 @@ +function test1 (nmat) +%test1: KLU test +% Example: +% test1 +% +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +clear functions +rand ('state', 0) ; + +index = UFget ; +f = find (index.nrows == index.ncols & index.isReal) ; +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +h = waitbar (0, 'KLU test 1 of 5') ; + +if (nargin < 1) + nmat = 500 ; +end +nmat = min (nmat, length (f)) ; + +% just use the first 100 matrices +nmat = min (nmat, 100) ; + +f = f (1:nmat) ; + +% f = 274 +% f = 101 ; % MATLAB condest is poor + +nmat = length (f) ; + +conds_klu = ones (1,nmat) ; +conds_matlab = ones (1,nmat) ; + +figure (1) +clf + +try + + for k = 1:nmat + + waitbar (k/nmat, h) ; + + i = f (k) ; + try + c = -1 ; + blocks = 0 ; + rho = 0 ; + c2 = 0 ; + r1 = 0 ; + r2 = 0 ; + err = 0 ; + + Prob = UFget (i,index) ; + A = Prob.A ; + c = condest (A) ; + % klu (A) + % [L,U,p,q,R,F,r,info] = klu (A) ; + + [LU, info, c2] = klu (A) ; + + L = LU.L ; + U = LU.U ; + p = LU.p ; + q = LU.q ; + R = LU.R ; + F = LU.F ; + r = LU.r ; + blocks = length (r) - 1 ; + + n = size (A,1) ; + b = rand (n,1) ; + x = klu (LU,'\',b) ; + err = norm (A*x-b,1) / norm (A,1) ; + + % info + rho = lu_normest (R\A(p,q) - F, L, U) ; + r1 = info.rcond ; + r2 = full (min (abs (diag (U))) / max (abs (diag (U)))) ; + + if (r1 ~= r2) + fprintf ('!\n') ; + pause + end + + conds_klu (k) = c2 ; + conds_matlab (k) = c ; + + catch + disp (lasterr) ; + end + + fprintf (... + 'blocks %6d err %8.2e condest %8.2e %8.2e rcond %8.2e %8.2e err %8.2e\n', ... + blocks, rho, c2, c, r1, r2, err) ; + + end + + k = nmat ; + plot (1:k, log10 (conds_klu (1:k) ./ conds_matlab (1:k)), 'o') ; + drawnow + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/test2.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/test2.m new file mode 100644 index 0000000..83cdd54 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/test2.m @@ -0,0 +1,184 @@ +function test2 (nmat) +%test2: KLU test +% Example: +% test2 +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +clear functions +rand ('state', 0) ; +% warning ('off', 'MATLAB:singularMatrix') ; +% warning ('off', 'MATLAB:nearlySingularMatrix') ; +% warning ('off', 'MATLAB:divideByZero') ; + +index = UFget ; +f = find (index.nrows == index.ncols) ; +[ignore i] = sort (index.nnz (f)) ; +f = f (i) ; + +if (nargin < 1) + nmat = 500 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +if (~isempty (strfind (computer, '64'))) + is64 = 1 ; +else + is64 = 0 ; +end + +Tklu = 1e-6 * ones (2*nmat,1) ; +Tmatlab = zeros (2*nmat,1) ; +Tcsparse = zeros (2*nmat,1) ; +LUnz = zeros (2*nmat, 1) ; +k = 0 ; + +h = waitbar (0, 'KLU test 2 of 5') ; + +figure (1) +clf + +try + + for kk = 1:nmat + + Prob = UFget (f (kk), index) ; + + waitbar (kk/nmat, h) ; + + disp (Prob) ; + if (isfield (Prob, 'kind')) + if (~isempty (strfind (Prob.kind, 'subsequent'))) + fprintf ('skip ...\n') ; + continue + end + end + A = Prob.A ; + + for do_complex = 0:1 + + k = k + 1 ; + if (do_complex) + A = sprand (A) + 1i * sprand (A) ; + end + + try + [L,U,p,q] = lu (A, 'vector') ; + catch + % older version of MATLAB, which doesn't have 'vector' option + [L,U,P,Q] = lu (A) ; + [p ignore1 ignore2] = find (P') ; + [q ignore1 ignore2] = find (Q) ; + clear ignore1 ignore2 P Q + end + + LU.L = L ; + LU.U = U ; + if (is64) + LU.p = int64 (p) ; + LU.q = int64 (q) ; + else + LU.p = int32 (p) ; + LU.q = int32 (q) ; + end + C = A (p,q) ; + LUnz (k) = nnz (L) + nnz (U) ; + + n = size (A,1) ; + + do_klu = (nnz (diag (U)) == n) ; + if (do_klu) + + fprintf ('klu...\n') ; + err = 0 ; + erc = 0 ; + er2 = 0 ; + for nrhs = 10:-1:1 + + b = rand (n,nrhs) ; + + tic ; + x = klu (LU,'\',b) ; + Tklu (k) = max (1e-6, toc) ; + + tic ; + y = U \ (L \ b (p,:)) ; + y (q,:) = y ; + Tmatlab (k) = max (1e-6, toc) ; + + if (nrhs == 1 & isreal (U) & isreal (L) & isreal (b)) %#ok + tic ; + z = cs_usolve (U, cs_lsolve (L, b (p))) ; + z (q) = z ; + Tcsparse (k) = max (1e-6, toc) ; + erc = norm (A*z-b,1) / norm (A,1) ; + end + + err = max (err, norm (A*x-b,1) / norm (A,1)) ; + er2 = max (er2, norm (A*y-b,1) / norm (A,1)) ; + if (err > 100*er2) + fprintf ('error %g %g\n', err, er2) ; + error ('?') ; + end + end + + fprintf ('klu... with randomized scaling for L\n') ; + er3 = 0 ; + er4 = 0 ; + D = spdiags (rand (n,1), 0, n, n) ; + LU.L = D * L ; + A2 = D * A (p,q) ; + if (is64) + LU.p = int64 (1:n) ; + LU.q = int64 (1:n) ; + else + LU.p = int32 (1:n) ; + LU.q = int32 (1:n) ; + end + for nrhs = 1:10 + b = rand (n,nrhs) ; + x = klu (LU,'\',b) ; + y = U \ (LU.L \ b) ; + er3 = max (er3, norm (A2*x-b,1) / norm (A,1)) ; + er4 = max (er4, norm (A2*y-b,1) / norm (A,1)) ; + if (er3 > 1e3*er4) + fprintf ('error %g %g\n', er3, er4) ; + error ('?') ; + end + end + + + else + err = Inf ; + er2 = Inf ; + er3 = Inf ; + er4 = Inf ; + erc = Inf ; + end + + lumax = max (LUnz (1:k)) ; + loglog (... + LUnz (1:k), Tmatlab (1:k) ./ Tklu (1:k), 'o', ... + LUnz (1:k), Tcsparse (1:k) ./ Tklu (1:k), 'x', ... + [20 lumax], [1 1], 'r-') ; + axis ([20 lumax .1 20]) ; + drawnow + + fprintf ('err %g %g %g\n', err, er2, erc) ; + end + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/test3.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/test3.m new file mode 100644 index 0000000..a8edbbb --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/test3.m @@ -0,0 +1,61 @@ +function test3 +%test3: KLU test +% Example: +% test3 +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +h = waitbar (1/12, 'KLU test 3 of 5') ; + +rand ('state', 0) ; + +load west0479 +A = west0479 ; +% A = sparse (rand (4)) ; +% A (3:4, 1:2) = 0 ; + +n = size (A,1) ; +b = rand (n,1) ; +spparms ('spumoni',2) +x = A\b ; +spparms ('spumoni',0) +fprintf ('MATLAB resid %g\n', norm (A*x-b,1)) ; + +[LU,info,cond_estimate] = klu (A) ; +fprintf ('\nLU = \n') ; disp (LU) ; +fprintf ('\ninfo = \n') ; disp (info) ; +fprintf ('KLU condest %g\n', cond_estimate) ; +matlab_condest = condest (A) ; +matlab_cond = cond (full (A)) ; +fprintf ('MATLAB condest %g cond %g\n', matlab_condest, matlab_cond) ; + +for nrhs = 1:10 + waitbar (nrhs/12, h) ; + b = rand (n,nrhs) ; + x = klu (LU,'\',b) ; + fprintf ('nrhs: %d resid: %g\n', ... + nrhs, norm (A*x-b,1) / norm (A,1)) ; +end + +[x,info,cond_estimate] = klu (A, '\', b) ; +fprintf ('\ninfo = \n') ; disp (info) ; +fprintf ('KLU cond_estimate %g\n', cond_estimate) ; + +waitbar (11/12, h) ; + +[x,info] = klu (A, '\', b, struct ('ordering',1)) ; +fprintf ('\ninfo = \n') ; disp (info) ; +[x,info,cond_estimate] = klu (A, '\', b, struct ('ordering',2)) ; +fprintf ('\ninfo = \n') ; disp (info) ; +try + [x,info,cond_estimate] = klu (A, '\', b, struct ('ordering',3)) ; + fprintf ('\ninfo = \n') ; disp (info) ; + [x,info,cond_estimate] = klu (A, '\', b, struct ('ordering',4)) ; + fprintf ('\ninfo = \n') ; disp (info) ; +catch + fprintf ('KLU test with CHOLMOD skipped (CHOLMOD not installed)\n') ; +end + +close (h) ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/test4.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/test4.m new file mode 100644 index 0000000..9ae5388 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/test4.m @@ -0,0 +1,221 @@ +function test4 (nmat) +%test4: KLU test +% Example: +% test4 +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +% rand ('state', 0) ; +% warning ('off', 'MATLAB:singularMatrix') ; +% warning ('off', 'MATLAB:nearlySingularMatrix') ; +% warning ('off', 'KLU:rcond') ; +% warning ('off', 'MATLAB:Axes:NegativeDataInLogAxis') ; + +index = UFget ; +f = find (index.nrows == index.ncols & index.isReal & index.amd_lnz > 0) ; +[ignore i] = sort (index.amd_lnz (f)) ; +f = f (i) ; +% f = f (1:100) ; + +if (nargin < 1) + nmat = 500 ; +end +nmat = min (nmat, length (f)) ; +f = f (1:nmat) ; + +if (1) + Tlu = -ones (nmat,1) ; + Tklu = -ones (nmat,1) ; + Tklu2 = -ones (nmat,1) ; + LUnz = -ones (nmat,1) ; + k = 0 ; +end + +if (~isempty (strfind (computer, '64'))) + is64 = 1 ; +else + is64 = 0 ; +end + +% 589: Sieber + +h = waitbar (0, 'KLU test 4 of 5') ; + +figure (1) +clf + +try + + for kk = 1:nmat + + Prob = UFget (f (kk), index) ; + + waitbar (kk/nmat, h) ; + + disp (Prob) ; + if (isfield (Prob, 'kind')) + if (~isempty (strfind (Prob.kind, 'subsequent'))) + fprintf ('skip ...\n') ; + continue + end + if (~isempty (strfind (Prob.kind, 'random'))) + fprintf ('skip ...\n') ; + continue + end + end + k = k + 1 ; + A = Prob.A ; + n = size (A,1) ; + err1 = 0 ; + err2 = 0 ; + err4 = 0 ; + terr1 = 0 ; + terr2 = 0 ; + terr4 = 0 ; + + + for do_imag = 0:1 + if (do_imag) + A = sprand (A) + 1i * sprand (A) ; + end + + % compare with UMFPACK + try + tic + [L,U,p,q,R1] = lu (A, 'vector') ; + t1 = max (1e-6, toc) ; + catch + % older version of MATLAB, which doesn't have 'vector' option + tic + [L,U,P,Q] = lu (A) ; + t1 = max (1e-6, toc) ; + [p ignore1 ignore2] = find (P') ; + [q ignore1 ignore2] = find (Q) ; + clear ignore1 ignore2 P Q + R1 = speye (n) ; + end + + if (Tlu (k) == -1) + Tlu (k) = t1 ; + LUnz (k) = nnz (L) + nnz (U) ; + end + + % note that the scaling R1 and R2 are different with KLU and UMFPACK + % UMFPACK: L*U-P*(R1\A)*Q + % KLU: L*U-R2\(P*A*Q) + % + % R1 and R2 are related, via P, where R2 = P*R*P', or equivalently + % R2 = R1 (p,p). + + rcond = min (abs (diag (U))) / max (abs (diag (U))) ; + if (rcond < 1e-15) + fprintf ('skip...\n') ; + break ; + end + + F.L = L ; + F.U = U ; + if (is64) + F.p = int64(p) ; + F.q = int64(q) ; + else + F.p = int32(p) ; + F.q = int32(q) ; + end + + F.R = R1(p,p) ; + b = rand (n,1) ; + x = klu (F, '\', b) ; + y = klu (b', '/', F) ; + + fprintf ('solve with klu %g\n', ... + norm (A*x-b,1)/norm(A,1)) ; + fprintf ('solve with klu %g transpose\n', ... + norm (y*A-b',1)/norm(A,1)) ; + + + for nrhs = 1:10 + for do_b_imag = 0:1 + b = rand (n, nrhs) ; + if (do_b_imag) + b = b + 1i * rand (n, nrhs) ; + end + + % KLU backslash + tic ; + x = klu (A,'\',b) ; + t2 = max (1e-6, toc) ; + + % KLU slash + xt = klu (b','/',A) ; + + % KLU backslash with precomputed LU + tic + LU = klu (A) ; + z = klu (LU,'\',b) ; + t4 = max (1e-6, toc) ; + + % KLU slash with precomputed LU + zt = klu (b','/',LU) ; + + % UMFPACK + tic + rb = R1 \ b ; + y = U \ (L \ rb (p,:)) ; + y (q,:) = y ; + t3 = max (1e-6, toc) ; + + yt = (L' \ (U' \ b (q,:))) ; + yt (p,:) = yt ; + yt = R1 \ yt ; + yt = yt' ; + + if (Tklu (k) == -1) + Tlu (k) = Tlu (k) + t3 ; + Tklu (k) = t2 ; + Tklu2 (k) = t4 ; + end + + err1 = max (err1, norm (A*x-b,1) / norm (A,1)) ; + err2 = max (err2, norm (A*y-b,1) / norm (A,1)) ; + err4 = max (err4, norm (A*z-b,1) / norm (A,1)) ; + + terr1 = max (terr1, norm (xt*A-b',1) / norm (A,1)) ; + terr2 = max (terr2, norm (yt*A-b',1) / norm (A,1)) ; + terr4 = max (terr4, norm (zt*A-b',1) / norm (A,1)) ; + end + end + end + + fprintf ('err %g %g %g\n', err1, err2, err4) ; + if (err1 > 1e4*err2 | err4 > 1e4*err2) %#ok + fprintf ('warning: KLU inaccurate!\n') + end + + fprintf ('terr %g %g %g\n', terr1, terr2, terr4) ; + if (terr1 > 1e4*terr2 | terr4 > 1e4*terr2) %#ok + fprintf ('warning: KLU T inaccurate!\n') + end + + lunzmax = max (LUnz (1:k)) ; + loglog ( ... + LUnz (1:k), Tklu (1:k) ./ Tlu (1:k), 'o', ... + LUnz (1:k), Tklu2 (1:k) ./ Tlu (1:k), 'x', ... + [10 lunzmax], [1 1], 'r-') ; + drawnow + + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/Test/test5.m b/OpenDSSC/klusolve/KLU/MATLAB/Test/test5.m new file mode 100644 index 0000000..e6aa618 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/Test/test5.m @@ -0,0 +1,180 @@ +function test5 +%test5: KLU test +% Example: +% test5 +% +% test circuit matrices in the UF sparse matrix collection. +% +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +do_diary = 0 ; + +if (do_diary) + diary off + s = date ; + t = clock ; + s = sprintf ('diary test5_%s_%d-%d-%d.txt\n', s, t (4), t(5), fix(t(6))); + eval (s) ; +end + +% ATandT frequency-domain circuits, exclude these: +freq = [ 283 284 285 286 ] ; + +% sorted in order of MATLAB 7.3 x=A\b time on storm +% (AMD Opteron, 64-bit, 8GB mem, 2 cores) +circ = [ +1195 % Rajat/rajat11 n: 135 nz 665 +1198 % Rajat/rajat14 n: 180 nz 1475 +1189 % Rajat/rajat05 n: 301 nz 1250 +1169 % Sandia/oscil_trans_01 n: 430 nz 1614 +1112 % Sandia/oscil_dcop_01 n: 430 nz 1544 +1346 % Rajat/rajat19 n: 1157 nz 3699 +1199 % Hamrle/Hamrle1 n: 32 nz 98 +1106 % Sandia/fpga_trans_01 n: 1220 nz 7382 +1188 % Rajat/rajat04 n: 1041 nz 8725 +1055 % Sandia/fpga_dcop_01 n: 1220 nz 5892 +1108 % Sandia/init_adder1 n: 1813 nz 11156 +1196 % Rajat/rajat12 n: 1879 nz 12818 +1053 % Sandia/adder_trans_01 n: 1814 nz 14579 +539 % Hamm/add20 n: 2395 nz 13151 +371 % Bomhof/circuit_2 n: 4510 nz 21199 +540 % Hamm/add32 n: 4960 nz 19848 +1186 % Rajat/rajat02 n: 1960 nz 11187 +466 % Grund/meg4 n: 5860 nz 25258 +465 % Grund/meg1 n: 2904 nz 58142 +370 % Bomhof/circuit_1 n: 2624 nz 35823 +1200 % Hamrle/Hamrle2 n: 5952 nz 22162 +1197 % Rajat/rajat13 n: 7598 nz 48762 +1187 % Rajat/rajat03 n: 7602 nz 32653 +372 % Bomhof/circuit_3 n: 12127 nz 48137 +1185 % Rajat/rajat01 n: 6833 nz 43250 +1183 % IBM_Austin/coupled n: 11341 nz 97193 +1376 % Rajat/rajat27 n: 20640 nz 97353 +543 % Hamm/memplus n: 17758 nz 99147 +1109 % Sandia/mult_dcop_01 n: 25187 nz 193276 +1371 % Rajat/rajat22 n: 39899 nz 195429 +1375 % Rajat/rajat26 n: 51032 nz 247528 +1414 % IBM_EDA/ckt11752_tr_0 n: 49702 nz 332807 +541 % Hamm/bcircuit n: 68902 nz 375558 +1413 % IBM_EDA/ckt11752_dc_1 n: 49702 nz 333029 +542 % Hamm/hcircuit n: 105676 nz 513072 +1316 % Rajat/rajat15 n: 37261 nz 443573 +1190 % Rajat/rajat06 n: 10922 nz 46983 +1191 % Rajat/rajat07 n: 14842 nz 63913 +1372 % Rajat/rajat23 n: 110355 nz 555441 +373 % Bomhof/circuit_4 n: 80209 nz 307604 +544 % Hamm/scircuit n: 170998 nz 958936 +1412 % AMD/G2_circuit n: 150102 nz 726674 is this solid state device? +1415 % Sandia/ASIC_100k n: 99340 nz 940621 +1416 % Sandia/ASIC_100ks n: 99190 nz 578890 +1420 % Sandia/ASIC_680ks n: 682712 nz 1693767 +1192 % Rajat/rajat08 n: 19362 nz 83443 +1193 % Rajat/rajat09 n: 24482 nz 105573 +1323 % IBM_EDA/trans4 n: 116835 nz 749800 +1320 % IBM_EDA/dc1 n: 116835 nz 766396 +1194 % Rajat/rajat10 n: 30202 nz 130303 +1418 % Sandia/ASIC_320ks n: 321671 nz 1316085 +1417 % Sandia/ASIC_320k n: 321821 nz 1931828 +1343 % Rajat/rajat16 n: 94294 nz 476766 +1345 % Rajat/rajat18 n: 94294 nz 479151 +1344 % Rajat/rajat17 n: 94294 nz 479246 +1377 % Rajat/rajat28 n: 87190 nz 606489 +1369 % Rajat/rajat20 n: 86916 nz 604299 +1374 % Rajat/rajat25 n: 87190 nz 606489 +1370 % Rajat/rajat21 n: 411676 nz 1876011 +1419 +1396 +1201 +1397 +1421 +1398 +1373 % Rajat/rajat24 n: 358172 nz 1946979 +]' ; + +fprintf ('Running KLU on %d circuits.\n', length (circ)) ; + +index = UFget ; + +opts_noscale.scale = -1 ; +opts_sum.scale = 1 ; +opts_max.scale = 2 ; % default scaling + +h = waitbar (0, 'KLU test 5 of 5') ; +nmat = length (circ) ; + +try + + for kk = 1:nmat + + k = circ (kk) ; + Prob = UFget (k, index) ; + + waitbar (kk/nmat, h) ; + + A = Prob.A ; + n = size (A,1) ; + b = rand (n,1) ; + fprintf ('\n%d : %s n: %d nz %d\n', k, Prob.name, n, nnz (A)) ; + + try + tic ; + x2 = klu (A, '\', b, opts_noscale) ; + t2 = toc ; + e2 = norm (A*x2-b) ; + catch + t2 = 0 ; + e2 = 0 ; + end + fprintf ('KLU no scale: err %8.2e t: %8.4f\n', e2, t2) ; + + try + tic ; + x4 = klu (A, '\', b, opts_max) ; + t4 = toc ; + e4 = norm (A*x4-b) ; + catch + t4 = 0 ; + e4 = 0 ; + end + fprintf ('KLU max scale: err %8.2e t: %8.4f\n', e4, t4) ; + + try + tic ; + x3 = klu (A, '\', b, opts_sum) ; + t3 = toc ; + e3 = norm (A*x3-b) ; + catch + t3 = 0 ; + e3 = 0 ; + end + fprintf ('KLU sum scale: err %8.2e t: %8.4f\n', e3, t3) ; + + tic + x1 = A\b ; + t1 = toc ; + e1 = norm (A*x1-b) ; + fprintf ('matlab: err %8.2e t: %8.4f\n', e1, t1) ; + + fprintf (' speedup %8.2f\n', t1 / t4) ; + clear Prob + + if (do_diary) + diary off + diary on + end + end + +catch + % out-of-memory is OK, other errors are not + disp (lasterr) ; + if (isempty (strfind (lasterr, 'Out of memory'))) + error (lasterr) ; %#ok + else + fprintf ('test terminated early, but otherwise OK\n') ; + end +end + +close (h) ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu.m b/OpenDSSC/klusolve/KLU/MATLAB/klu.m new file mode 100644 index 0000000..547c2bf --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu.m @@ -0,0 +1,71 @@ +function [LU_or_x,info,c] = klu (A,operation,b,opts) %#ok +%KLU sparse left-looking LU factorization, using a block triangular form. +% +% Example: +% LU = klu (A) factorizes R\A(p,q) into L*U+F, returning a struct +% x = klu (A,'\',b) x = A\b, using KLU +% x = klu (b,'/',A) x = b/A, using KLU +% x = klu (LU,'\',b) x = A\b, where LU = klu(A) +% x = klu (b,'/',LU) x = b/A, where LU = klu(A) +% +% KLU(A) factorizes a square sparse matrix, L*U+F = R\A(p,q), where L and U +% are the factors of the diagonal blocks of the block, F are the entries +% above the diagonal blocks. r corresponds to the 3rd output of dmperm; it +% specifies where the block boundaries are. The kth block consists of +% rows/columns r(k) to r(k+1)-1 of A(p,q). +% +% Note that the use of the scale factor R differs between KLU and UMFPACK +% (and the LU function, which is based on UMFPACK). In LU, the factorization +% is L*U = P*(R1\A)*Q; in KLU it is L*U+F = R2\(P*A*Q). R1 and R2 are related +% via R2 = P*R1*P', or equivalently R2 = R1(p,p). +% +% The LU output is a struct containing members L, U, p, q, R, F, and r. +% +% opts is an optional input struct which appears as the last input argument. +% Entries not present are set to their defaults: +% +% opts.tol 0.001 partial pivoting tolerance; valid range 0 to 1. +% opts.btf 1 use block triangular form (BTF) if nonzero +% opts.ordering 0 how each block is ordered: +% 0: AMD, 1: COLAMD, 2: natural, +% 3: CHOLMOD's ordering of (A'*A), +% 4: CHOLMOD's ordering of (A+A') +% opts.scale -1 1: R = diag(sum(abs(A)')), row-sum +% 2: R = diag(max(abs(A)')), max in each row +% otherwise: none (R=I) +% opts.maxwork 0 if > 0, limit work in BTF ordering to +% opts.maxwork*nnz(A); no limit if <= 0. +% +% The CHOLMOD ordering is to try AMD (for A+A') or COLAMD (for A'*A) +% first. If the fill-in with AMD or COLAMD is high, METIS is tried (on +% A+A' or A'*A), and the best ordering found is selected. CHOLMOD, METIS, +% CAMD, and CCOLAMD are required. If not available, only ordering options +% 0, 1, and 2 may be used (AMD and COLAMD are always required by KLU). +% +% Two optional outputs, [LU,info,c] = klu (A) or [x,info,c] = klu (A,'\',b) +% provide statistics about the factorization: +% +% info.noffdiag number of off-diagonal pivots chosen (after preordering) +% info.nrealloc number of memory reallocations of L and U +% info.rcond a very cheap estimate of 1/(condition number) +% info.rgrowth reciprocal pivot growth +% info.flops flop count +% info.nblocks # of blocks in BTF form (1 if not computed) +% info.ordering AMD, COLAMD, natural, cholmod(AA'), cholmod(A+A') +% info.scale scaling (<=0: none, 1: sum, 2: max) +% info.lnz nnz(L), including diagonal +% info.unz nnz(U), including diagonal +% info.offnz nnz(F) +% info.tol pivot tolerance used +% info.memory peak memory usage in bytes +% c the same as MATLAB's condest +% +% info and c are relevant only if the matrix is factorized (LU = klu (A), +% x = klu (A,'/',b), or x = klu (b,'/',A) usages). +% +% See also BTF, LU, DMPERM, CONDEST, CHOLMOD, AMD, COLAMD, CAMD, CCOLAMD. + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +error ('klu mexFunction not found') ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m b/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m new file mode 100644 index 0000000..6fdce1e --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m @@ -0,0 +1,79 @@ +function klu_demo +% KLU demo +% +% Example: +% klu_demo +% +% See also klu, btf + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida + +load west0479 +A = west0479 ; + +n = size (A,1) ; +b = rand (n,1) ; + +clf +subplot (2,2,1) ; +spy (A) +title ('west0479') ; + +subplot (2,2,2) ; +[p, q, r] = btf (A) ; +drawbtf (A, p, q, r) ; +title ('BTF form') ; + +[x,info,c] = klu (A, '\', b) ; +matlab_condest = condest (A) ; +matlab_cond = cond (full (A)) ; +fprintf ('MATLAB condest: %g KLU condest: %g cond: %g\n', ... + matlab_condest, c, matlab_cond) ; + +fprintf ('\nKLU with scaling, AMD ordering and condition number estimate:\n') ; +[LU,info] = klu (A, struct ('ordering',0, 'scale', 1)) ; +x = klu (LU, '\', b) ; +resid = norm (A*x-b,1) / norm (A,1) ; +rgrowth = full (min (max (abs ((LU.R \ A (LU.p,LU.q)) - LU.F)) ./ ... + max (abs (LU.U)))) ; +fprintf ('resid: %g KLU condest: %g rgrowth: %g\n', resid, c, rgrowth) ; +disp (info) ; + +subplot (2,2,3) ; +spy (LU.L + LU.U + LU.F) ; +title ('KLU+AMD factors') ; + +fprintf ('\nKLU with COLAMD ordering\n') ; +[LU,info] = klu (A, struct ('ordering',1)) ; +x = klu (LU, '\', b) ; +resid = norm (A*x-b,1) / norm (A,1) ; +fprintf ('resid: %g\n', resid) ; +disp (info) ; + +subplot (2,2,4) ; +spy (LU.L + LU.U + LU.F) ; +title ('KLU+COLAMD factors') ; + +fprintf ('\nKLU with natural ordering (lots of fillin)\n') ; +[x,info] = klu (A, '\', b, struct ('ordering',2)) ; +resid = norm (A*x-b,1) / norm (A,1) ; +fprintf ('resid: %g\n', resid) ; +disp (info) ; + +try + + fprintf ('\nKLU with CHOLMOD(A''*A) ordering\n') ; + [x,info] = klu (A, '\', b, struct ('ordering',3)) ; + resid = norm (A*x-b,1) / norm (A,1) ; + fprintf ('resid: %g\n', resid) ; + disp (info) ; + + fprintf ('\nKLU with CHOLMOD(A+A'') ordering\n') ; + [x,info] = klu (A, '\', b, struct ('ordering',4)) ; + resid = norm (A*x-b,1) / norm (A,1) ; + fprintf ('resid: %g\n', resid) ; + disp (info) ; + +catch + fprintf ('KLU test with CHOLMOD skipped (CHOLMOD not installed)\n') ; +end diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m.out b/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m.out new file mode 100644 index 0000000..c591adf --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu_demo.m.out @@ -0,0 +1,88 @@ +klu_demo +MATLAB condest: 1.42443e+12 KLU condest: 1.42443e+12 cond: 3.25816e+11 + +KLU with scaling, AMD ordering and condition number estimate: +resid: 3.88932e-13 KLU condest: 1.42443e+12 rgrowth: 1.85769e-05 + noffdiag: 12 + nrealloc: 0 + rcond: 7.1253e-09 + rgrowth: 1.8577e-05 + flops: 31592 + nblocks: 166 + ordering: 0 + scale: 1 + lnz: 1923 + unz: 1892 + offnz: 450 + tol: 1.0000e-03 + memory: 136748 + + +KLU with COLAMD ordering +resid: 1.00707e-11 + noffdiag: 14 + nrealloc: 0 + rcond: 9.1888e-10 + rgrowth: 4.3963e-08 + flops: 42513 + nblocks: 166 + ordering: 1 + scale: 2 + lnz: 1956 + unz: 2490 + offnz: 450 + tol: 1.0000e-03 + memory: 397692 + + +KLU with natural ordering (lots of fillin) +resid: 3.13025e-13 + noffdiag: 437 + nrealloc: 0 + rcond: 6.4525e-08 + rgrowth: 1.7654e-04 + flops: 328911 + nblocks: 2 + ordering: 2 + scale: 2 + lnz: 7846 + unz: 7332 + offnz: 40 + tol: 1.0000e-03 + memory: 453556 + + +KLU with CHOLMOD(A'*A) ordering +resid: 1.7568e-13 + noffdiag: 24 + nrealloc: 0 + rcond: 4.1814e-09 + rgrowth: 1.0676e-04 + flops: 36747 + nblocks: 166 + ordering: 3 + scale: 2 + lnz: 2020 + unz: 2227 + offnz: 450 + tol: 1.0000e-03 + memory: 191132 + + +KLU with CHOLMOD(A+A') ordering +resid: 5.1045e-13 + noffdiag: 13 + nrealloc: 0 + rcond: 3.9046e-11 + rgrowth: 2.4378e-06 + flops: 31925 + nblocks: 166 + ordering: 4 + scale: 2 + lnz: 2000 + unz: 1878 + offnz: 450 + tol: 1.0000e-03 + memory: 136044 + +diary off diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu_install.m b/OpenDSSC/klusolve/KLU/MATLAB/klu_install.m new file mode 100644 index 0000000..779c36d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu_install.m @@ -0,0 +1,59 @@ +function klu_install (with_cholmod) +%KLU_INSTALL compiles and installs the KLU, BTF, AMD, and COLAMD mexFunctions +% +% Example: +% klu_install % compiles KLU without CHOLMOD +% klu_install (1) % with CHOLMOD, CCAMD, CCOLAMD, and METIS +% +% KLU relies on AMD, COLAMD, and BTF for its ordering options, and can +% optionally use CHOLMOD, CCOLAMD, CAMD, and METIS as well. By default, +% CHOLMOD, CCOLAMD, CAMD, and METIS are not used. +% +% See http://www-users.cs.umn.edu/~karypis/metis for a copy of METIS 4.0.1. +% +% You must type the klu_install command while in the KLU/MATLAB directory. +% +% See also klu, btf + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida + +if (nargin < 1) + with_cholmod = 0 ; +end + +% compile KLU and add to the path +klu_make (with_cholmod) ; +klu_path = pwd ; +addpath (klu_path) + +fprintf ('\nNow compiling the AMD, COLAMD, and BTF mexFunctions:\n') ; + +% compile BTF and add to the path +cd ../../BTF/MATLAB +btf_make +btf_path = pwd ; +addpath (btf_path) + +% compile AMD and add to the path +cd ../../AMD/MATLAB +amd_make +amd_path = pwd ; +addpath (amd_path) + +% compile COLAMD and add to the path +cd ../../COLAMD/MATLAB +colamd_make +colamd_path = pwd ; +addpath (colamd_path) + +cd (klu_path) + +fprintf ('\nThe following paths have been added. You may wish to add them\n') ; +fprintf ('permanently, using the MATLAB pathtool command.\n') ; +fprintf ('%s\n', klu_path) ; +fprintf ('%s\n', amd_path) ; +fprintf ('%s\n', colamd_path) ; +fprintf ('%s\n', btf_path) ; + +fprintf ('\nTo try your new mexFunctions, cut-and-paste this command:\n') ; +fprintf ('klu_demo, btf_demo, amd_demo, colamd_demo\n') ; diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu_make.m b/OpenDSSC/klusolve/KLU/MATLAB/klu_make.m new file mode 100644 index 0000000..1afd42c --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu_make.m @@ -0,0 +1,368 @@ +function klu_make (with_cholmod) +%KLU_MAKE compiles the KLU mexFunctions +% +% Example: +% klu_make % compiles KLU without CHOLMOD +% klu_make (1) % with CHOLMOD, CCAMD, CCOLAMD, and METIS +% +% KLU relies on AMD, COLAMD, and BTF for its ordering options, and can +% optionally use CHOLMOD, CCOLAMD, CAMD, and METIS as well. By default, +% CHOLMOD, CCOLAMD, CAMD, and METIS are not used. +% +% See http://www-users.cs.umn.edu/~karypis/metis for a copy of METIS 4.0.1. +% +% You must type the klu_make command while in the KLU/MATLAB directory. +% +% See also klu + +% Copyright 2004-2007 Timothy A. Davis, Univ. of Florida +% http://www.cise.ufl.edu/research/sparse + +if (nargin < 1) + with_cholmod = 0 ; +end + +details = 0 ; % if 1, print details of each command + +% modify this if your copy of METIS is not in SuiteSparse/metis-4.0: +metis_path = '../../metis-4.0' ; + +d = '' ; +if (~isempty (strfind (computer, '64'))) + % 64-bit MATLAB + d = '-largeArrayDims' ; +end + +fprintf ('Compiling KLU ') ; +kk = 0 ; + +include = '-I. -I../../AMD/Include -I../../COLAMD/Include -I../Include -I../../UFconfig -I../../BTF/Include' ; + +if (with_cholmod) + include = [include ' -I../../CCOLAMD/Include -I../../CAMD/Include -I../../CHOLMOD/Include -I../../UFconfig -I' metis_path '/Lib -I../User'] ; +end + +% do not attempt to compile CHOLMOD with large file support (not needed) +include = [include ' -DNLARGEFILE'] ; + +% fix the METIS 4.0.1 rename.h file +if (with_cholmod) + fprintf ('with CHOLMOD, CCAMD, CCOLAMD, and METIS\n') ; + f = fopen ('rename.h', 'w') ; + if (f == -1) + error ('unable to create rename.h in current directory') ; + end + fprintf (f, '/* do not edit this file; generated by klu_make */\n') ; + fprintf (f, '#undef log2\n') ; + fprintf (f, '#include "%s/Lib/rename.h"\n', metis_path) ; + fprintf (f, '#undef log2\n') ; + fprintf (f, '#define log2 METIS__log2\n') ; + fprintf (f, '#include "mex.h"\n') ; + fprintf (f, '#define malloc mxMalloc\n') ; + fprintf (f, '#define free mxFree\n') ; + fprintf (f, '#define calloc mxCalloc\n') ; + fprintf (f, '#define realloc mxRealloc\n') ; + fclose (f) ; + include = ['-DNSUPERNODAL -DNMODIFY -DNMATRIXOPS -DNCHECK ' include] ; +else + fprintf ('without CHOLMOD, CCAMD, CCOLAMD, and METIS\n') ; + include = ['-DNCHOLMOD ' include] ; +end + +include = strrep (include, '/', filesep) ; + +amd_src = { ... + '../../AMD/Source/amd_1', ... + '../../AMD/Source/amd_2', ... + '../../AMD/Source/amd_aat', ... + '../../AMD/Source/amd_control', ... + '../../AMD/Source/amd_defaults', ... + '../../AMD/Source/amd_dump', ... + '../../AMD/Source/amd_global', ... + '../../AMD/Source/amd_info', ... + '../../AMD/Source/amd_order', ... + '../../AMD/Source/amd_postorder', ... + '../../AMD/Source/amd_post_tree', ... + '../../AMD/Source/amd_preprocess', ... + '../../AMD/Source/amd_valid' } ; + +camd_src = { ... + '../../CAMD/Source/camd_1', ... + '../../CAMD/Source/camd_2', ... + '../../CAMD/Source/camd_aat', ... + '../../CAMD/Source/camd_control', ... + '../../CAMD/Source/camd_defaults', ... + '../../CAMD/Source/camd_dump', ... + '../../CAMD/Source/camd_global', ... + '../../CAMD/Source/camd_info', ... + '../../CAMD/Source/camd_order', ... + '../../CAMD/Source/camd_postorder', ... + '../../CAMD/Source/camd_preprocess', ... + '../../CAMD/Source/camd_valid' } ; + +colamd_src = { + '../../COLAMD/Source/colamd', ... + '../../COLAMD/Source/colamd_global' } ; + +ccolamd_src = { + '../../CCOLAMD/Source/ccolamd', ... + '../../CCOLAMD/Source/ccolamd_global' } ; + +metis_src = { + 'Lib/balance', ... + 'Lib/bucketsort', ... + 'Lib/ccgraph', ... + 'Lib/coarsen', ... + 'Lib/compress', ... + 'Lib/debug', ... + 'Lib/estmem', ... + 'Lib/fm', ... + 'Lib/fortran', ... + 'Lib/frename', ... + 'Lib/graph', ... + 'Lib/initpart', ... + 'Lib/kmetis', ... + 'Lib/kvmetis', ... + 'Lib/kwayfm', ... + 'Lib/kwayrefine', ... + 'Lib/kwayvolfm', ... + 'Lib/kwayvolrefine', ... + 'Lib/match', ... + 'Lib/mbalance2', ... + 'Lib/mbalance', ... + 'Lib/mcoarsen', ... + 'Lib/memory', ... + 'Lib/mesh', ... + 'Lib/meshpart', ... + 'Lib/mfm2', ... + 'Lib/mfm', ... + 'Lib/mincover', ... + 'Lib/minitpart2', ... + 'Lib/minitpart', ... + 'Lib/mkmetis', ... + 'Lib/mkwayfmh', ... + 'Lib/mkwayrefine', ... + 'Lib/mmatch', ... + 'Lib/mmd', ... + 'Lib/mpmetis', ... + 'Lib/mrefine2', ... + 'Lib/mrefine', ... + 'Lib/mutil', ... + 'Lib/myqsort', ... + 'Lib/ometis', ... + 'Lib/parmetis', ... + 'Lib/pmetis', ... + 'Lib/pqueue', ... + 'Lib/refine', ... + 'Lib/separator', ... + 'Lib/sfm', ... + 'Lib/srefine', ... + 'Lib/stat', ... + 'Lib/subdomains', ... + 'Lib/timing', ... + 'Lib/util' } ; + +for i = 1:length (metis_src) + metis_src {i} = [metis_path '/' metis_src{i}] ; +end + +cholmod_src = { + '../../CHOLMOD/Core/cholmod_aat', ... + '../../CHOLMOD/Core/cholmod_add', ... + '../../CHOLMOD/Core/cholmod_band', ... + '../../CHOLMOD/Core/cholmod_change_factor', ... + '../../CHOLMOD/Core/cholmod_common', ... + '../../CHOLMOD/Core/cholmod_complex', ... + '../../CHOLMOD/Core/cholmod_copy', ... + '../../CHOLMOD/Core/cholmod_dense', ... + '../../CHOLMOD/Core/cholmod_error', ... + '../../CHOLMOD/Core/cholmod_factor', ... + '../../CHOLMOD/Core/cholmod_memory', ... + '../../CHOLMOD/Core/cholmod_sparse', ... + '../../CHOLMOD/Core/cholmod_transpose', ... + '../../CHOLMOD/Core/cholmod_triplet', ... + '../../CHOLMOD/Cholesky/cholmod_amd', ... + '../../CHOLMOD/Cholesky/cholmod_analyze', ... + '../../CHOLMOD/Cholesky/cholmod_colamd', ... + '../../CHOLMOD/Cholesky/cholmod_etree', ... + '../../CHOLMOD/Cholesky/cholmod_postorder', ... + '../../CHOLMOD/Cholesky/cholmod_rowcolcounts', ... + '../../CHOLMOD/Partition/cholmod_ccolamd', ... + '../../CHOLMOD/Partition/cholmod_csymamd', ... + '../../CHOLMOD/Partition/cholmod_camd', ... + '../../CHOLMOD/Partition/cholmod_metis', ... + '../../CHOLMOD/Partition/cholmod_nesdis' } ; + +btf_src = { + '../../BTF/Source/btf_maxtrans', ... + '../../BTF/Source/btf_order', ... + '../../BTF/Source/btf_strongcomp' } ; + +klu_src = { + '../Source/klu_free_symbolic', ... + '../Source/klu_defaults', ... + '../Source/klu_analyze_given', ... + '../Source/klu_analyze', ... + '../Source/klu_memory' } ; + +if (with_cholmod) + klu_src = [klu_src { '../User/klu_l_cholmod' }] ; %#ok +end + +klu_zlsrc = { + '../Source/klu', ... + '../Source/klu_kernel', ... + '../Source/klu_dump', ... + '../Source/klu_factor', ... + '../Source/klu_free_numeric', ... + '../Source/klu_solve', ... + '../Source/klu_scale', ... + '../Source/klu_refactor', ... + '../Source/klu_tsolve', ... + '../Source/klu_diagnostics', ... + '../Source/klu_sort', ... + '../Source/klu_extract', ... + } ; + +klu_lobj = { + 'klu_l', ... + 'klu_l_kernel', ... + 'klu_l_dump', ... + 'klu_l_factor', ... + 'klu_l_free_numeric', ... + 'klu_l_solve', ... + 'klu_l_scale', ... + 'klu_l_refactor', ... + 'klu_l_tsolve', ... + 'klu_l_diagnostics', ... + 'klu_l_sort', ... + 'klu_l_extract', ... + } ; + +klu_zlobj = { + 'klu_zl', ... + 'klu_zl_kernel', ... + 'klu_zl_dump', ... + 'klu_zl_factor', ... + 'klu_zl_free_numeric', ... + 'klu_zl_solve', ... + 'klu_zl_scale', ... + 'klu_zl_refactor', ... + 'klu_zl_tsolve', ... + 'klu_zl_diagnostics', ... + 'klu_zl_sort', ... + 'klu_zl_extract', ... + } ; + +try + % ispc does not appear in MATLAB 5.3 + pc = ispc ; +catch + % if ispc fails, assume we are on a Windows PC if it's not unix + pc = ~isunix ; +end + +if (pc) + % Windows does not have drand48 and srand48, required by METIS. Use + % drand48 and srand48 in CHOLMOD/MATLAB/Windows/rand48.c instead. + obj_extension = '.obj' ; + cholmod_src = [cholmod_src {'../../CHOLMOD/MATLAB/Windows/rand48'}] ; + include = [include ' -I../../CHOLMOD/MATLAB/Windows'] ; +else + obj_extension = '.o' ; +end + +% compile each library source file +obj = ' ' ; + +source = [amd_src btf_src klu_src colamd_src] ; +if (with_cholmod) + source = [metis_src ccolamd_src camd_src cholmod_src source] ; +end + +for f = source + fs = strrep (f {1}, '/', filesep) ; + slash = strfind (fs, filesep) ; + if (isempty (slash)) + slash = 1 ; + else + slash = slash (end) + 1 ; + end + o = fs (slash:end) ; + obj = [obj ' ' o obj_extension] ; %#ok + s = sprintf ('mex %s -DDLONG -O %s -c %s.c', d, include, fs) ; + kk = do_cmd (s, kk, details) ; +end + +for k = 1:length(klu_zlsrc) + ff = strrep (klu_zlsrc {k}, '/', filesep) ; + slash = strfind (ff, filesep) ; + if (isempty (slash)) + slash = 1 ; + else + slash = slash (end) + 1 ; + end + o = ff (slash:end) ; + s = sprintf ('mex %s -DDLONG -O %s -c %s.c', d, include, ff) ; + kk = do_cmd (s, kk, details) ; + lobj = klu_lobj {k} ; + obj = [obj ' ' lobj obj_extension] ; %#ok + mvfile ([o obj_extension], [lobj obj_extension]) ; + s = sprintf ('mex %s -DDLONG -DCOMPLEX -O %s -c %s.c', d, include, ff) ; + kk = do_cmd (s, kk, details) ; + zlobj = klu_zlobj {k} ; + obj = [obj ' ' zlobj obj_extension] ; %#ok + mvfile ([o obj_extension], [zlobj obj_extension]) ; +end + +% compile the KLU mexFunction +s = sprintf ('mex %s -DDLONG -O %s -output klu klu_mex.c', d, include) ; +s = [s obj] ; %#ok +kk = do_cmd (s, kk, details) ; + +% clean up +s = ['delete ' obj] ; +do_cmd (s, kk, details) ; + +fprintf ('\nKLU successfully compiled\n') ; + +%------------------------------------------------------------------------------- + +function rmfile (file) +% rmfile: delete a file, but only if it exists +if (length (dir (file)) > 0) %#ok + delete (file) ; +end + +%------------------------------------------------------------------------------- + +function cpfile (src, dst) +% cpfile: copy the src file to the filename dst, overwriting dst if it exists +rmfile (dst) +if (length (dir (src)) == 0) %#ok + fprintf ('File does not exist: %s\n', src) ; + error ('File does not exist') ; +end +copyfile (src, dst) ; + +%------------------------------------------------------------------------------- + +function mvfile (src, dst) +% mvfile: move the src file to the filename dst, overwriting dst if it exists +cpfile (src, dst) ; +rmfile (src) ; + +%------------------------------------------------------------------------------- +function kk = do_cmd (s, kk, details) +%DO_CMD: evaluate a command, and either print it or print a "." +if (details) + fprintf ('%s\n', s) ; +else + if (mod (kk, 60) == 0) + fprintf ('\n') ; + end + kk = kk + 1 ; + fprintf ('.') ; +end +eval (s) ; + diff --git a/OpenDSSC/klusolve/KLU/MATLAB/klu_mex.c b/OpenDSSC/klusolve/KLU/MATLAB/klu_mex.c new file mode 100644 index 0000000..89864ac --- /dev/null +++ b/OpenDSSC/klusolve/KLU/MATLAB/klu_mex.c @@ -0,0 +1,1979 @@ +/* ========================================================================== */ +/* === klu mexFunction ====================================================== */ +/* ========================================================================== */ + +/* KLU: a MATLAB interface to a "Clark Kent" sparse LU factorization algorithm. + + 3 or 4 input arguments: factorize and solve, returning the solution: + + x = klu (A, '\', b) + x = klu (A, '\', b, opts) + x = klu (b, '/', A) + x = klu (b, '/', A, opts) + + A can be the LU struct, instead: + + x = klu (LU, '\', b) + x = klu (LU, '\', b, opts) + x = klu (b, '/', LU) + x = klu (b, '/', LU, opts) + + where LU is a struct containing members: L, U, p, q, R, F, and r. Only L + and U are required. The factorization is L*U+F = R\A(p,q), where r defines + the block boundaries of the BTF form, and F contains the entries in the + upper block triangular part. + + with 1 or 2 input arguments: factorize, returning the LU struct: + + LU = klu (A) + LU = klu (A, opts) + + 2nd optional output: info, which is only meaningful if A was factorized. + + A must be square. b can be a matrix, but it cannot be sparse. + + Obscure options, mainly for testing: + + opts.memgrow 1.2 when L and U need to grow, inc. by this ratio. + valid range: 1 or more. + opts.imemamd 1.2 initial size of L and U with AMD or other + symmetric ordering is 1.2*nnz(L)+n; + valid range 1 or more. + opts.imem 10 initial size of L and U is 10*nnz(A)+n if a + symmetric ordering not used; valid range 1 or + more +*/ + +/* ========================================================================== */ + +#include "klu.h" +#include + +#ifndef NCHOLMOD +#include "klu_cholmod.h" +#endif + +#include "mex.h" +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define ABS(x) (((x) < 0) ? -(x) : (x)) +#define STRING_MATCH(s1,s2) (strcmp ((s1), (s2)) == 0) + +/* Complex division. This uses ACM Algo 116, by R. L. Smith, 1962. */ +/* Note that c cannot be the same variable as a or b */ +#define DIV(cx,cz,ax,az,bx,bz) \ +{ \ + double r, den ; \ + if (ABS (bx) >= ABS (bz)) \ + { \ + r = bz / bx ; \ + den = bx + r * bz ; \ + cx = (ax + az * r) / den ; \ + cz = (az - ax * r) / den ; \ + } \ + else \ + { \ + r = bx / bz ; \ + den = r * bx + bz ; \ + cx = (ax * r + az) / den ; \ + cz = (az * r - ax) / den ; \ + } \ +} + +/* complex multiply/subtract, c -= a*b */ +/* Note that c cannot be the same variable as a or b */ +#define MULT_SUB(cx,cz,ax,az,bx,bz) \ +{ \ + cx -= ax * bx - az * bz ; \ + cz -= az * bx + ax * bz ; \ +} + +/* complex multiply/subtract, c -= a*conj(b) */ +/* Note that c cannot be the same variable as a or b */ +#define MULT_SUB_CONJ(cx,cz,ax,az,bx,bz) \ +{ \ + cx -= ax * bx + az * bz ; \ + cz -= az * bx - ax * bz ; \ +} + +/* ========================================================================== */ +/* === klu mexFunction ====================================================== */ +/* ========================================================================== */ + +void mexFunction +( + int nargout, + mxArray *pargout [ ], + int nargin, + const mxArray *pargin [ ] +) +{ + double ukk, lkk, rs, s, lik, uik, x [4], offik, z, ukkz, lkkz, sz, wx, wz ; + double *X, *B, *Xz, *Xx, *Bx, *Bz, *A, *Ax, *Az, *Lx, *Ux, *Rs, *Offx, *Wx, + *Uz, *Lz, *Offz, *Wz, *W, *Xi, *Bi ; + UF_long *Ap, *Ai, *Lp, *Li, *Up, *Ui, *P, *Q, *R, *Rp, *Ri, *Offp, *Offi ; + char *operator ; + mxArray *L_matlab, *U_matlab, *p_matlab, *q_matlab, *R_matlab, *F_matlab, + *r_matlab, *field ; + const mxArray *A_matlab = NULL, *LU_matlab, *B_matlab = NULL, *opts_matlab ; + klu_l_symbolic *Symbolic ; + klu_l_numeric *Numeric ; + klu_l_common Common ; + UF_long n = 0, k, nrhs = 0, do_solve, do_factorize, symmetric, + A_complex = 0, B_complex, nz, do_transpose = 0, p, pend, nblocks, + R1 [2], chunk, nr, i, j, block, k1, k2, nk, bn = 0, ordering ; + int mx_int ; + static const char *fnames [ ] = { + "noffdiag", /* # of off-diagonal pivots */ + "nrealloc", /* # of memory reallocations */ + "rcond", /* cheap reciprocal number estimate */ + "rgrowth", /* reciprocal pivot growth */ + "flops", /* flop count */ + "nblocks", /* # of blocks in BTF form (1 if not computed) */ + "ordering", /* AMD, COLAMD, natural, cholmod(AA'), cholmod(A+A') */ + "scale", /* scaling (<=0: none, 1: sum, 2: max */ + "lnz", /* nnz(L), including diagonal */ + "unz", /* nnz(U), including diagonal */ + "offnz", /* nnz(F), including diagonal */ + "tol", /* pivot tolerance used */ + "memory" /* peak memory usage */ + }, + *LUnames [ ] = { "L", "U", "p", "q", "R", "F", "r" } ; + + /* ---------------------------------------------------------------------- */ + /* get inputs */ + /* ---------------------------------------------------------------------- */ + + if (nargin < 1 || nargin > 4 || nargout > 3) + { + mexErrMsgTxt ( + "Usage: x = klu(A,'\',b), x = klu(A,'/',b) or LU = klu(A)") ; + } + + /* return the solution x, or just do LU factorization */ + do_solve = (nargin > 2) ; + + /* determine size of the MATLAB integer */ + if (sizeof (UF_long) == sizeof (INT32_T)) + { + mx_int = mxINT32_CLASS ; + } + else + { + mx_int = mxINT64_CLASS ; + } + + if (do_solve) + { + + /* ------------------------------------------------------------------ */ + /* slash or backslash */ + /* ------------------------------------------------------------------ */ + + /* usage, where opts is the optional 4th input argument: + x = klu (A, '\', b) + x = klu (LU, '\', b) + x = klu (b, '/', A) + x = klu (b, '/', LU) + */ + + /* determine the operator, slash (/) or backslash (\) */ + if (!mxIsChar (pargin [1])) + { + mexErrMsgTxt ("invalid operator") ; + } + operator = mxArrayToString (pargin [1]) ; + if (STRING_MATCH (operator, "\\")) + { + do_transpose = 0 ; + A_matlab = pargin [0] ; + B_matlab = pargin [2] ; + nrhs = mxGetN (B_matlab) ; + bn = mxGetM (B_matlab) ; + } + else if (STRING_MATCH (operator, "/")) + { + do_transpose = 1 ; + A_matlab = pargin [2] ; + B_matlab = pargin [0] ; + nrhs = mxGetM (B_matlab) ; + bn = mxGetN (B_matlab) ; + } + else + { + mexErrMsgTxt ("invalid operator") ; + } + + if (mxIsSparse (B_matlab)) + { + mexErrMsgTxt ("B cannot be sparse") ; + } + + opts_matlab = (nargin > 3) ? pargin [3] : NULL ; + + /* determine if the factorization needs to be performed */ + do_factorize = !mxIsStruct (A_matlab) ; + if (do_factorize) + { + LU_matlab = NULL ; + } + else + { + LU_matlab = A_matlab ; + A_matlab = NULL ; + } + + } + else + { + + /* ------------------------------------------------------------------ */ + /* factorize A and return LU factorization */ + /* ------------------------------------------------------------------ */ + + /* usage, where opts in the optional 2nd input argument: + LU = klu (A) + */ + + LU_matlab = NULL ; + A_matlab = pargin [0] ; + B_matlab = NULL ; + opts_matlab = (nargin > 1) ? pargin [1] : NULL ; + do_factorize = 1 ; + if (mxIsStruct (A_matlab)) + { + mexErrMsgTxt ("invalid input, A must be a sparse matrix") ; + } + } + + /* ---------------------------------------------------------------------- */ + /* get options and set Common defaults */ + /* ---------------------------------------------------------------------- */ + + klu_l_defaults (&Common) ; + + /* memory management routines */ + Common.malloc_memory = mxMalloc ; + Common.calloc_memory = mxCalloc ; + Common.free_memory = mxFree ; + Common.realloc_memory = mxRealloc ; + + /* factorization options */ + if (opts_matlab != NULL && mxIsStruct (opts_matlab)) + { + if ((field = mxGetField (opts_matlab, 0, "tol")) != NULL) + { + Common.tol = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "memgrow")) != NULL) + { + Common.memgrow = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "imemamd")) != NULL) + { + Common.initmem_amd = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "imem")) != NULL) + { + Common.initmem = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "btf")) != NULL) + { + Common.btf = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "ordering")) != NULL) + { + Common.ordering = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "scale")) != NULL) + { + Common.scale = mxGetScalar (field) ; + } + if ((field = mxGetField (opts_matlab, 0, "maxwork")) != NULL) + { + Common.maxwork = mxGetScalar (field) ; + } + } + + if (Common.ordering < 0 || Common.ordering > 4) + { + mexErrMsgTxt ("invalid ordering option") ; + } + ordering = Common.ordering ; + +#ifndef NCHOLMOD + /* ordering option 3,4 becomes KLU option 3, with symmetric 0 or 1 */ + symmetric = (Common.ordering == 4) ; + if (symmetric) Common.ordering = 3 ; + Common.user_order = klu_l_cholmod ; + Common.user_data = &symmetric ; +#else + /* CHOLMOD, METIS, CAMD, CCOLAMD, not available */ + if (Common.ordering > 2) + { + mexErrMsgTxt ("invalid ordering option") ; + } +#endif + + if (Common.scale < 1 || Common.scale > 2) + { + Common.scale = -1 ; /* no scaling, and no error checking either */ + } + + /* ---------------------------------------------------------------------- */ + /* factorize, if needed */ + /* ---------------------------------------------------------------------- */ + + if (do_factorize) + { + + /* get input matrix A to factorize */ + n = mxGetN (A_matlab) ; + if (!mxIsSparse (A_matlab) || n != mxGetM (A_matlab) || n == 0) + { + mexErrMsgTxt ("A must be sparse, square, and non-empty") ; + } + + Ap = (UF_long *) mxGetJc (A_matlab) ; + Ai = (UF_long *) mxGetIr (A_matlab) ; + Ax = mxGetPr (A_matlab) ; + Az = mxGetPi (A_matlab) ; + nz = Ap [n] ; + A_complex = mxIsComplex (A_matlab) ; + + if (do_solve && (n != bn || nrhs == 0)) + { + mexErrMsgTxt ("B must be non-empty with same number of rows as A") ; + } + + /* ------------------------------------------------------------------ */ + /* analyze */ + /* ------------------------------------------------------------------ */ + + Symbolic = klu_l_analyze (n, Ap, Ai, &Common) ; + if (Symbolic == (klu_l_symbolic *) NULL) + { + mexErrMsgTxt ("klu symbolic analysis failed") ; + } + + /* ------------------------------------------------------------------ */ + /* factorize */ + /* ------------------------------------------------------------------ */ + + if (A_complex) + { + /* A is complex */ + A = mxMalloc (nz * 2 * sizeof (double)) ; + for (k = 0 ; k < nz ; k++) + { + A [2*k ] = Ax [k] ; /* real part */ + A [2*k+1] = Az [k] ; /* imaginary part */ + } + Numeric = klu_zl_factor (Ap, Ai, A, Symbolic, &Common) ; + if (nargout > 1) + { + /* flops and rgrowth, if requested */ + klu_zl_flops (Symbolic, Numeric, &Common) ; + klu_zl_rgrowth (Ap, Ai, A, Symbolic, Numeric, &Common) ; + } + mxFree (A) ; + } + else + { + /* A is real */ + Numeric = klu_l_factor (Ap, Ai, Ax, Symbolic, &Common) ; + if (nargout > 1) + { + /* flops, if requested */ + klu_l_flops (Symbolic, Numeric, &Common) ; + klu_l_rgrowth (Ap, Ai, Ax, Symbolic, Numeric, &Common) ; + } + } + if (Common.status != KLU_OK) + { + mexErrMsgTxt ("klu numeric factorization failed") ; + } + + /* ------------------------------------------------------------------ */ + /* compute cheap condition number estimate */ + /* ------------------------------------------------------------------ */ + + if (A_complex) + { + klu_zl_rcond (Symbolic, Numeric, &Common) ; + } + else + { + klu_l_rcond (Symbolic, Numeric, &Common) ; + } + + /* ------------------------------------------------------------------ */ + /* return info, if requested */ + /* ------------------------------------------------------------------ */ + +#define INFO(i,x) \ + mxSetFieldByNumber (pargout [1], 0, i, mxCreateScalarDouble (x)) + + if (nargout > 1) + { + pargout [1] = mxCreateStructMatrix (1, 1, 13, fnames) ; + INFO (0, Common.noffdiag) ; + INFO (1, Common.nrealloc) ; + INFO (2, Common.rcond) ; + INFO (3, Common.rgrowth) ; + INFO (4, Common.flops) ; + INFO (5, Symbolic->nblocks) ; + INFO (6, ordering) ; + INFO (7, Common.scale) ; + INFO (8, Numeric->lnz) ; + INFO (9, Numeric->unz) ; + INFO (10, Numeric->nzoff) ; + INFO (11, Common.tol) ; + INFO (12, Common.mempeak) ; + } + if (nargout > 2) + { + /* this is done separately, since it's costly */ + klu_l_condest (Ap, Ax, Symbolic, Numeric, &Common) ; + pargout [2] = mxCreateDoubleMatrix (1, 1, mxREAL) ; + Wx = mxGetPr (pargout [2]) ; + Wx [0] = Common.condest ; + } + + } + else + { + /* create an empty "info" and "condest" output */ + if (nargout > 1) + { + pargout [1] = mxCreateDoubleMatrix (0, 0, mxREAL) ; + } + if (nargout > 2) + { + pargout [2] = mxCreateDoubleMatrix (0, 0, mxREAL) ; + } + } + + /* ---------------------------------------------------------------------- */ + /* solve, or return LU factorization */ + /* ---------------------------------------------------------------------- */ + + if (do_solve) + { + + /* ------------------------------------------------------------------ */ + /* solve, x = klu ( ... ) usage */ + /* ------------------------------------------------------------------ */ + + B_complex = mxIsComplex (B_matlab) ; + + if (do_factorize) + { + + /* -------------------------------------------------------------- */ + /* solve using KLU factors computed above */ + /* -------------------------------------------------------------- */ + + /* klu (A,'\',b) or klu (b,'/',A) usage */ + + /* create X */ + if (do_transpose) + { + pargout [0] = mxCreateDoubleMatrix (nrhs, n, + (A_complex || B_complex) ? mxCOMPLEX : mxREAL) ; + } + else + { + pargout [0] = mxCreateDoubleMatrix (n, nrhs, + (A_complex || B_complex) ? mxCOMPLEX : mxREAL) ; + } + + if (A_complex) + { + + /* ---------------------------------------------------------- */ + /* A is complex, but B might be real */ + /* ---------------------------------------------------------- */ + + X = mxMalloc (n * nrhs * 2 * sizeof (double)) ; + Bx = mxGetPr (B_matlab) ; + Bz = mxGetPi (B_matlab) ; + + if (do_transpose) + { + + /* X = B', merge and transpose B */ + for (j = 0 ; j < nrhs ; j++) + { + for (i = 0 ; i < n ; i++) + { + X [2*(i+j*n) ] = Bx [j+i*nrhs] ; /* real */ + X [2*(i+j*n)+1] = Bz ? (-Bz [j+i*nrhs]) : 0 ; + } + } + + /* solve A'x=b (complex conjugate) */ + klu_zl_tsolve (Symbolic, Numeric, n, nrhs, X, 1, &Common) ; + + /* split and transpose the solution */ + Xx = mxGetPr (pargout [0]) ; + Xz = mxGetPi (pargout [0]) ; + for (j = 0 ; j < nrhs ; j++) + { + for (i = 0 ; i < n ; i++) + { + Xx [j+i*nrhs] = X [2*(i+j*n) ] ; /* real part */ + Xz [j+i*nrhs] = -X [2*(i+j*n)+1] ; /* imag part */ + } + } + + } + else + { + + /* X = B, but create merged X from a split B */ + for (k = 0 ; k < n*nrhs ; k++) + { + X [2*k ] = Bx [k] ; /* real part */ + X [2*k+1] = Bz ? (Bz [k]) : 0 ; /* imaginary part */ + } + + /* solve Ax=b */ + klu_zl_solve (Symbolic, Numeric, n, nrhs, X, &Common) ; + + /* split the solution into real and imaginary parts */ + Xx = mxGetPr (pargout [0]) ; + Xz = mxGetPi (pargout [0]) ; + for (k = 0 ; k < n*nrhs ; k++) + { + Xx [k] = X [2*k ] ; /* real part */ + Xz [k] = X [2*k+1] ; /* imaginary part */ + } + } + + mxFree (X) ; + } + else + { + + if (do_transpose) + { + + /* solve in chunks of 4 columns at a time */ + W = mxMalloc (n * MAX (nrhs,4) * sizeof (double)) ; + X = mxGetPr (pargout [0]) ; + B = mxGetPr (B_matlab) ; + Xi = mxGetPi (pargout [0]) ; + Bi = mxGetPi (B_matlab) ; + + for (chunk = 0 ; chunk < nrhs ; chunk += 4) + { + + /* A is real: real(X) = real(b) / real(A) */ + UF_long chunksize = MIN (nrhs - chunk, 4) ; + for (j = 0 ; j < chunksize ; j++) + { + for (i = 0 ; i < n ; i++) + { + W [i+j*n] = B [i*nrhs+j] ; + } + } + klu_l_tsolve (Symbolic, Numeric, n, chunksize, W, + &Common) ; + for (j = 0 ; j < chunksize ; j++) + { + for (i = 0 ; i < n ; i++) + { + X [i*nrhs+j] = W [i+j*n] ; + } + } + X += 4 ; + B += 4 ; + + if (B_complex) + { + /* B is complex: imag(X) = imag(B) / real(A) */ + + for (j = 0 ; j < chunksize ; j++) + { + for (i = 0 ; i < n ; i++) + { + W [i+j*n] = Bi [i*nrhs+j] ; + } + } + klu_l_tsolve (Symbolic, Numeric, n, chunksize, W, + &Common) ; + for (j = 0 ; j < chunksize ; j++) + { + for (i = 0 ; i < n ; i++) + { + Xi [i*nrhs+j] = W [i+j*n] ; + } + } + Xi += 4 ; + Bi += 4 ; + } + + } + mxFree (W) ; + + } + else + { + + /* A is real: real(X) = real(A) \ real(b) */ + X = mxGetPr (pargout [0]) ; + B = mxGetPr (B_matlab) ; + for (k = 0 ; k < n*nrhs ; k++) + { + X [k] = B [k] ; + } + klu_l_solve (Symbolic, Numeric, n, nrhs, X, &Common) ; + if (B_complex) + { + /* B is complex: imag(X) = real(A) \ imag(B) */ + X = mxGetPi (pargout [0]) ; + B = mxGetPi (B_matlab) ; + for (k = 0 ; k < n*nrhs ; k++) + { + X [k] = B [k] ; + } + klu_l_solve (Symbolic, Numeric, n, nrhs, X, &Common) ; + } + } + } + + /* -------------------------------------------------------------- */ + /* free Symbolic and Numeric objects */ + /* -------------------------------------------------------------- */ + + klu_l_free_symbolic (&Symbolic, &Common) ; + if (A_complex) + { + klu_zl_free_numeric (&Numeric, &Common) ; + } + else + { + klu_l_free_numeric (&Numeric, &Common) ; + } + + } + else + { + + /* -------------------------------------------------------------- */ + /* solve using LU struct given on input */ + /* -------------------------------------------------------------- */ + + /* the factorization is L*U+F = R\A(p,q), where L*U is block + diagonal, and F contains the entries in the upper block + triangular part */ + + L_matlab = mxGetField (LU_matlab, 0, "L") ; + U_matlab = mxGetField (LU_matlab, 0, "U") ; + p_matlab = mxGetField (LU_matlab, 0, "p") ; + q_matlab = mxGetField (LU_matlab, 0, "q") ; + R_matlab = mxGetField (LU_matlab, 0, "R") ; + F_matlab = mxGetField (LU_matlab, 0, "F") ; + r_matlab = mxGetField (LU_matlab, 0, "r") ; + + if (!L_matlab || !U_matlab || !mxIsSparse (L_matlab) || + !mxIsSparse (U_matlab)) + { + mexErrMsgTxt ("invalid LU struct") ; + } + + n = mxGetM (L_matlab) ; + if (n != mxGetN (L_matlab) || + n != mxGetM (U_matlab) || n != mxGetN (U_matlab) + /* ... */ + ) + { + mexErrMsgTxt ("invalid LU struct") ; + } + + if (n != bn || nrhs == 0) + { + mexErrMsgTxt ( + "B must be non-empty with same number of rows as L and U") ; + } + + /* get L */ + if (!mxIsSparse (L_matlab) || + n != mxGetM (L_matlab) || n != mxGetN (L_matlab)) + { + mexErrMsgTxt ("LU.L must be sparse and same size as A") ; + } + + Lp = (UF_long *) mxGetJc (L_matlab) ; + Li = (UF_long *) mxGetIr (L_matlab) ; + Lx = mxGetPr (L_matlab) ; + Lz = mxGetPi (L_matlab) ; + + /* get U */ + if (!mxIsSparse (U_matlab) || + n != mxGetM (U_matlab) || n != mxGetN (U_matlab)) + { + mexErrMsgTxt ("LU.U must be sparse and same size as A") ; + } + Up = (UF_long *) mxGetJc (U_matlab) ; + Ui = (UF_long *) mxGetIr (U_matlab) ; + Ux = mxGetPr (U_matlab) ; + Uz = mxGetPi (U_matlab) ; + + /* get p */ + if (p_matlab) + { + if (mxGetNumberOfElements (p_matlab) != n + || mxIsSparse (p_matlab) + || mxGetClassID (p_matlab) != mx_int) + { + mexErrMsgTxt ("P invalid") ; + } + P = (UF_long *) mxGetData (p_matlab) ; + for (k = 0 ; k < n ; k++) + { + if (P [k] < 1 || P [k] > n) mexErrMsgTxt ("P invalid") ; + } + } + else + { + /* no P, use identity instead */ + P = NULL ; + } + + /* get q */ + if (q_matlab) + { + if (mxGetNumberOfElements (q_matlab) != n + || mxIsSparse (q_matlab) + || mxGetClassID (q_matlab) != mx_int) + { + mexErrMsgTxt ("Q invalid") ; + } + Q = (UF_long *) mxGetData (q_matlab) ; + for (k = 0 ; k < n ; k++) + { + if (Q [k] < 1 || Q [k] > n) mexErrMsgTxt ("Q invalid.") ; + } + } + else + { + /* no Q, use identity instead */ + Q = NULL ; + } + + /* get r */ + R1 [0] = 1 ; + R1 [1] = n+1 ; + if (r_matlab) + { + nblocks = mxGetNumberOfElements (r_matlab) - 1 ; + if (nblocks < 1 || nblocks > n || mxIsSparse (r_matlab) + || mxGetClassID (r_matlab) != mx_int) + { + mexErrMsgTxt ("r invalid") ; + } + R = (UF_long *) mxGetData (r_matlab) ; + if (R [0] != 1) mexErrMsgTxt ("r invalid") ; + for (k = 1 ; k <= nblocks ; k++) + { + if (R [k] <= R [k-1] || R [k] > n+1) + { + mexErrMsgTxt ("rinvalid") ; + } + } + if (R [nblocks] != n+1) mexErrMsgTxt ("r invalid") ; + } + else + { + /* no r */ + nblocks = 1 ; + R = R1 ; + } + + /* get R, scale factors */ + if (R_matlab) + { + /* ensure R is sparse, real, and has the right size */ + if (!mxIsSparse (R_matlab) || + n != mxGetM (R_matlab) || n != mxGetN (R_matlab)) + { + mexErrMsgTxt ("LU.R must be sparse and same size as A") ; + } + Rp = (UF_long *) mxGetJc (R_matlab) ; + Rs = mxGetPr (R_matlab) ; + if (Rp [n] != n) + { + mexErrMsgTxt ("LU.R invalid, must be diagonal") ; + } + } + else + { + /* no scale factors */ + Rs = NULL ; + } + + /* get F, off diagonal entries */ + if (F_matlab) + { + if (!mxIsSparse (F_matlab) || + n != mxGetM (F_matlab) || n != mxGetN (F_matlab)) + { + mexErrMsgTxt ("LU.F must be sparse and same size as A") ; + } + Offp = (UF_long *) mxGetJc (F_matlab) ; + Offi = (UF_long *) mxGetIr (F_matlab) ; + Offx = mxGetPr (F_matlab) ; + Offz = mxGetPi (F_matlab) ; + } + else + { + /* no off-diagonal entries */ + Offp = NULL ; + Offi = NULL ; + Offx = NULL ; + Offz = NULL ; + } + + /* -------------------------------------------------------------- */ + /* solve */ + /* -------------------------------------------------------------- */ + + if (mxIsComplex (L_matlab) || mxIsComplex (U_matlab) || + (F_matlab && mxIsComplex (F_matlab)) || B_complex) + { + + /* ========================================================== */ + /* === complex case ========================================= */ + /* ========================================================== */ + + /* create X */ + if (do_transpose) + { + pargout [0] = mxCreateDoubleMatrix (nrhs, n, mxCOMPLEX) ; + } + else + { + pargout [0] = mxCreateDoubleMatrix (n, nrhs, mxCOMPLEX) ; + } + Xx = mxGetPr (pargout [0]) ; + Xz = mxGetPi (pargout [0]) ; + + Bx = mxGetPr (B_matlab) ; + Bz = mxGetPi (B_matlab) ; + + /* get workspace */ + Wx = mxMalloc (n * sizeof (double)) ; + Wz = mxMalloc (n * sizeof (double)) ; + + /* ---------------------------------------------------------- */ + /* do just one row/column of the right-hand-side at a time */ + /* ---------------------------------------------------------- */ + + if (do_transpose) + { + + for (chunk = 0 ; chunk < nrhs ; chunk++) + { + + /* -------------------------------------------------- */ + /* transpose and permute right hand side, W = Q'*B' */ + /* -------------------------------------------------- */ + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Wx [k] = Bx [i*nrhs] ; + Wz [k] = Bz ? (-Bz [i*nrhs]) : 0 ; + } + + /* -------------------------------------------------- */ + /* solve W = (L*U + Off)'\W */ + /* -------------------------------------------------- */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* ---------------------------------------------- */ + /* block of size nk, rows/columns k1 to k2-1 */ + /* ---------------------------------------------- */ + + k1 = R [block] - 1 ; /* R is 1-based */ + k2 = R [block+1] - 1 ; + nk = k2 - k1 ; + + /* ---------------------------------------------- */ + /* block back-substitution for off-diagonal-block */ + /* ---------------------------------------------- */ + + if (block > 0 && Offp != NULL) + { + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + /* W [k] -= W [i] * conj(Off [p]) ; */ + z = Offz ? Offz [p] : 0 ; + MULT_SUB_CONJ (Wx [k], Wz [k], + Wx [i], Wz [i], Offx [p], z) ; + } + } + } + + + /* solve the block system */ + if (nk == 1) + { + + /* W [k1] /= conj (L(k1,k1)) ; */ + p = Lp [k1] ; + s = Lx [p] ; + sz = Lz ? (-Lz [p]) : 0 ; + DIV (wx, wz, Wx [k1], Wz [k1], s, sz) ; + Wx [k1] = wx ; + Wz [k1] = wz ; + + /* W [k1] /= conj (U(k1,k1)) ; */ + p = Up [k1] ; + s = Ux [p] ; + sz = Uz ? (-Uz [p]) : 0 ; + DIV (wx, wz, Wx [k1], Wz [k1], s, sz) ; + Wx [k1] = wx ; + Wz [k1] = wz ; + + } + else + { + + /* ------------------------------------------ */ + /* W = U'\W and then W=L'\W */ + /* ------------------------------------------ */ + + /* W = U'\W */ + for (k = k1 ; k < k2 ; k++) + { + pend = Up [k+1] - 1 ; + /* w = W [k] */ + wx = Wx [k] ; + wz = Wz [k] ; + for (p = Up [k] ; p < pend ; p++) + { + i = Ui [p] ; + /* w -= W [i] * conj(U [p]) */ + z = Uz ? Uz [p] : 0 ; + MULT_SUB_CONJ (wx, wz, + Wx [i], Wz [i], Ux [p], z) ; + } + /* W [k] = w / conj(ukk) ; */ + ukk = Ux [pend] ; + ukkz = Uz ? (-Uz [pend]) : 0 ; + DIV (Wx [k], Wz [k], wx, wz, ukk, ukkz) ; + } + + /* W = L'\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + p = Lp [k] ; + pend = Lp [k+1] ; + /* w = W [k] */ + wx = Wx [k] ; + wz = Wz [k] ; + lkk = Lx [p] ; + lkkz = Lz ? (-Lz [p]) : 0 ; + for (p++ ; p < pend ; p++) + { + i = Li [p] ; + /* w -= W [i] * conj (Lx [p]) ; */ + z = Lz ? Lz [p] : 0 ; + MULT_SUB_CONJ (wx, wz, + Wx [i], Wz [i], Lx [p], z) ; + } + /* W [k] = w / conj(lkk) ; */ + DIV (Wx [k], Wz [k], wx, wz, lkk, lkkz) ; + } + } + } + + /* -------------------------------------------------- */ + /* scale, permute, and tranpose: X = (P*(R\W))' */ + /* -------------------------------------------------- */ + + if (Rs == NULL) + { + /* no scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Xx [i*nrhs] = Wx [k] ; + Xz [i*nrhs] = Wz ? (-Wz [k]) : 0 ; + } + } + else + { + /* with scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Xx [i*nrhs] = Wx [k] / rs ; + Xz [i*nrhs] = Wz ? (-Wz [k] / rs) : 0 ; + } + } + + /* -------------------------------------------------- */ + /* go to the next row of B and X */ + /* -------------------------------------------------- */ + + Xx++ ; + Xz++ ; + Bx++ ; + if (Bz) Bz++ ; + } + + } + else + { + + for (chunk = 0 ; chunk < nrhs ; chunk++) + { + + /* -------------------------------------------------- */ + /* scale and permute the right hand side, W = P*(R\B) */ + /* -------------------------------------------------- */ + + if (Rs == NULL) + { + /* no scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Wx [k] = Bx [i] ; + Wz [k] = Bz ? Bz [i] : 0 ; + } + } + else + { + /* with scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Wx [k] = Bx [i] / rs ; + Wz [k] = Bz ? (Bz [i] / rs) : 0 ; + } + } + + /* -------------------------------------------------- */ + /* solve W = (L*U + Off)\W */ + /* -------------------------------------------------- */ + + for (block = nblocks-1 ; block >= 0 ; block--) + { + + /* ---------------------------------------------- */ + /* block of size nk, rows/columns k1 to k2-1 */ + /* ---------------------------------------------- */ + + k1 = R [block] - 1 ; /* R is 1-based */ + k2 = R [block+1] - 1 ; + nk = k2 - k1 ; + + /* solve the block system */ + if (nk == 1) + { + + /* W [k1] /= L(k1,k1) ; */ + p = Lp [k1] ; + s = Lx [p] ; + sz = Lz ? Lz [p] : 0 ; + DIV (wx, wz, Wx [k1], Wz [k1], s, sz) ; + Wx [k1] = wx ; + Wz [k1] = wz ; + + /* W [k1] /= U(k1,k1) ; */ + p = Up [k1] ; + s = Ux [p] ; + sz = Uz ? Uz [p] : 0 ; + DIV (wx, wz, Wx [k1], Wz [k1], s, sz) ; + Wx [k1] = wx ; + Wz [k1] = wz ; + + } + else + { + + /* ------------------------------------------ */ + /* W = L\W and then W=U\W */ + /* ------------------------------------------ */ + + /* W = L\W */ + for (k = k1 ; k < k2 ; k++) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p] ; + lkkz = Lz ? Lz [p] : 0 ; + /* w = W [k] / lkk ; */ + DIV (wx, wz, Wx [k], Wz [k], lkk, lkkz) ; + Wx [k] = wx ; + Wz [k] = wz ; + for (p++ ; p < pend ; p++) + { + i = Li [p] ; + /* W [i] -= Lx [p] * w ; */ + z = Lz ? Lz [p] : 0 ; + MULT_SUB (Wx [i], Wz [i], Lx [p], z, + wx, wz) ; + } + } + + /* W = U\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + pend = Up [k+1] - 1 ; + ukk = Ux [pend] ; + ukkz = Uz ? Uz [pend] : 0 ; + /* w = W [k] / ukk ; */ + DIV (wx, wz, Wx [k], Wz [k], ukk, ukkz) ; + Wx [k] = wx ; + Wz [k] = wz ; + for (p = Up [k] ; p < pend ; p++) + { + i = Ui [p] ; + /* W [i] -= U [p] * w ; */ + z = Uz ? Uz [p] : 0 ; + MULT_SUB (Wx [i], Wz [i], Ux [p], z, + wx, wz) ; + } + } + } + + /* ---------------------------------------------- */ + /* block back-substitution for off-diagonal-block */ + /* ---------------------------------------------- */ + + if (block > 0 && Offp != NULL) + { + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + wx = Wx [k] ; + wz = Wz [k] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + /* W [Offi [p]] -= Offx [p] * w ; */ + z = Offz ? Offz [p] : 0 ; + MULT_SUB (Wx [i], Wz [i], Offx [p], z, + wx, wz) ; + } + } + } + } + + /* -------------------------------------------------- */ + /* permute the result, X = Q*W */ + /* -------------------------------------------------- */ + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Xx [i] = Wx [k] ; + Xz [i] = Wz [k] ; + } + + /* -------------------------------------------------- */ + /* go to the next column of B and X */ + /* -------------------------------------------------- */ + + Xx += n ; + Xz += n ; + Bx += n ; + if (Bz) Bz += n ; + } + } + + /* free workspace */ + mxFree (Wx) ; + mxFree (Wz) ; + + } + else + { + + /* ========================================================== */ + /* === real case ============================================ */ + /* ========================================================== */ + + /* create X */ + if (do_transpose) + { + pargout [0] = mxCreateDoubleMatrix (nrhs, n, mxREAL) ; + } + else + { + pargout [0] = mxCreateDoubleMatrix (n, nrhs, mxREAL) ; + } + + Xx = mxGetPr (pargout [0]) ; + Bx = mxGetPr (B_matlab) ; + + if (do_transpose) + { + + /* ------------------------------------------------------ */ + /* solve in chunks of one row at a time */ + /* ------------------------------------------------------ */ + + /* get workspace */ + Wx = mxMalloc (n * sizeof (double)) ; + + for (chunk = 0 ; chunk < nrhs ; chunk++) + { + + /* -------------------------------------------------- */ + /* transpose and permute right hand side, W = Q'*B' */ + /* -------------------------------------------------- */ + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Wx [k] = Bx [i*nrhs] ; + } + + /* -------------------------------------------------- */ + /* solve W = (L*U + Off)'\W */ + /* -------------------------------------------------- */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* ---------------------------------------------- */ + /* block of size nk, rows/columns k1 to k2-1 */ + /* ---------------------------------------------- */ + + k1 = R [block] - 1 ; /* R is 1-based */ + k2 = R [block+1] - 1 ; + nk = k2 - k1 ; + + /* ---------------------------------------------- */ + /* block back-substitution for off-diagonal-block */ + /* ---------------------------------------------- */ + + if (block > 0 && Offp != NULL) + { + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + for (p = Offp [k] ; p < pend ; p++) + { + Wx [k] -= Wx [Offi [p]] * Offx [p] ; + } + } + } + + /* solve the block system */ + if (nk == 1) + { + Wx [k1] /= Lx [Lp [k1]] ; + Wx [k1] /= Ux [Up [k1]] ; + } + else + { + + /* ------------------------------------------ */ + /* W = U'\W and then W=L'\W */ + /* ------------------------------------------ */ + + /* W = U'\W */ + for (k = k1 ; k < k2 ; k++) + { + pend = Up [k+1] - 1 ; + for (p = Up [k] ; p < pend ; p++) + { + Wx [k] -= Wx [Ui [p]] * Ux [p] ; + } + Wx [k] /= Ux [pend] ; + } + + /* W = L'\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p] ; + for (p++ ; p < pend ; p++) + { + Wx [k] -= Wx [Li [p]] * Lx [p] ; + } + Wx [k] /= lkk ; + } + } + } + + /* -------------------------------------------------- */ + /* scale, permute, and tranpose: X = (P*(R\W))' */ + /* -------------------------------------------------- */ + + if (Rs == NULL) + { + /* no scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Xx [i*nrhs] = Wx [k] ; + } + } + else + { + /* with scaling */ + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Xx [i*nrhs] = Wx [k] / rs ; + } + } + + /* -------------------------------------------------- */ + /* go to the next row of B and X */ + /* -------------------------------------------------- */ + + Xx++ ; + Bx++ ; + } + + } + else + { + + /* ------------------------------------------------------ */ + /* solve in chunks of 4 columns at a time */ + /* ------------------------------------------------------ */ + + /* get workspace */ + Wx = mxMalloc (n * MAX (4, nrhs) * sizeof (double)) ; + + for (chunk = 0 ; chunk < nrhs ; chunk += 4) + { + /* -------------------------------------------------- */ + /* get the size of the current chunk */ + /* -------------------------------------------------- */ + + nr = MIN (nrhs - chunk, 4) ; + + /* -------------------------------------------------- */ + /* scale and permute the right hand side, W = P*(R\B) */ + /* -------------------------------------------------- */ + + if (Rs == NULL) + { + + /* no scaling */ + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Wx [k] = Bx [i] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Wx [2*k ] = Bx [i ] ; + Wx [2*k + 1] = Bx [i + n ] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Wx [3*k ] = Bx [i ] ; + Wx [3*k + 1] = Bx [i + n ] ; + Wx [3*k + 2] = Bx [i + n*2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + Wx [4*k ] = Bx [i ] ; + Wx [4*k + 1] = Bx [i + n ] ; + Wx [4*k + 2] = Bx [i + n*2] ; + Wx [4*k + 3] = Bx [i + n*3] ; + } + break ; + } + + } + else + { + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Wx [k] = Bx [i] / rs ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Wx [2*k ] = Bx [i ] / rs ; + Wx [2*k + 1] = Bx [i + n ] / rs ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Wx [3*k ] = Bx [i ] / rs ; + Wx [3*k + 1] = Bx [i + n ] / rs ; + Wx [3*k + 2] = Bx [i + n*2] / rs ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = P ? (P [k] - 1) : k ; + rs = Rs [k] ; + Wx [4*k ] = Bx [i ] / rs ; + Wx [4*k + 1] = Bx [i + n ] / rs ; + Wx [4*k + 2] = Bx [i + n*2] / rs ; + Wx [4*k + 3] = Bx [i + n*3] / rs ; + } + break ; + } + } + + /* -------------------------------------------------- */ + /* solve W = (L*U + Off)\W */ + /* -------------------------------------------------- */ + + for (block = nblocks-1 ; block >= 0 ; block--) + { + + /* ---------------------------------------------- */ + /* block of size nk is rows/columns k1 to k2-1 */ + /* ---------------------------------------------- */ + + k1 = R [block] - 1 ; /* R is 1-based */ + k2 = R [block+1] - 1 ; + nk = k2 - k1 ; + + /* solve the block system */ + if (nk == 1) + { + + /* this is not done if L comes from KLU, since + in that case, L is unit lower triangular */ + s = Lx [Lp [k1]] ; + if (s != 1.0) switch (nr) + { + case 1: + Wx [k1] /= s ; + break ; + case 2: + Wx [2*k1] /= s ; + Wx [2*k1 + 1] /= s ; + break ; + case 3: + Wx [3*k1] /= s ; + Wx [3*k1 + 1] /= s ; + Wx [3*k1 + 2] /= s ; + break ; + case 4: + Wx [4*k1] /= s ; + Wx [4*k1 + 1] /= s ; + Wx [4*k1 + 2] /= s ; + Wx [4*k1 + 3] /= s ; + break ; + } + + s = Ux [Up [k1]] ; + if (s != 1.0) switch (nr) + { + case 1: + Wx [k1] /= s ; + break ; + case 2: + Wx [2*k1] /= s ; + Wx [2*k1 + 1] /= s ; + break ; + case 3: + Wx [3*k1] /= s ; + Wx [3*k1 + 1] /= s ; + Wx [3*k1 + 2] /= s ; + break ; + case 4: + Wx [4*k1] /= s ; + Wx [4*k1 + 1] /= s ; + Wx [4*k1 + 2] /= s ; + Wx [4*k1 + 3] /= s ; + break ; + } + + } + else + { + + /* ------------------------------------------ */ + /* W = L\W and then W=U\W */ + /* ------------------------------------------ */ + + switch (nr) + { + + case 1: + /* W = L\W */ + for (k = k1 ; k < k2 ; k++) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p++] ; + x [0] = Wx [k] / lkk ; + Wx [k] = x [0] ; + for ( ; p < pend ; p++) + { + Wx [Li [p]] -= Lx [p] * x [0] ; + } + } + + /* W = U\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + pend = Up [k+1] - 1 ; + ukk = Ux [pend] ; + x [0] = Wx [k] / ukk ; + Wx [k] = x [0] ; + for (p = Up [k] ; p < pend ; p++) + { + Wx [Ui [p]] -= Ux [p] * x [0] ; + } + } + break ; + + case 2: + + /* W = L\W */ + for (k = k1 ; k < k2 ; k++) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p++] ; + x [0] = Wx [2*k ] / lkk ; + x [1] = Wx [2*k + 1] / lkk ; + Wx [2*k ] = x [0] ; + Wx [2*k + 1] = x [1] ; + for ( ; p < pend ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + Wx [2*i ] -= lik * x [0] ; + Wx [2*i + 1] -= lik * x [1] ; + } + } + + /* W = U\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + pend = Up [k+1] - 1 ; + ukk = Ux [pend] ; + x [0] = Wx [2*k ] / ukk ; + x [1] = Wx [2*k + 1] / ukk ; + Wx [2*k ] = x [0] ; + Wx [2*k + 1] = x [1] ; + for (p = Up [k] ; p < pend ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + Wx [2*i ] -= uik * x [0] ; + Wx [2*i + 1] -= uik * x [1] ; + } + } + break ; + + case 3: + + /* W = L\W */ + for (k = k1 ; k < k2 ; k++) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p++] ; + x [0] = Wx [3*k ] / lkk ; + x [1] = Wx [3*k + 1] / lkk ; + x [2] = Wx [3*k + 2] / lkk ; + Wx [3*k ] = x [0] ; + Wx [3*k + 1] = x [1] ; + Wx [3*k + 2] = x [2] ; + for ( ; p < pend ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + Wx [3*i ] -= lik * x [0] ; + Wx [3*i + 1] -= lik * x [1] ; + Wx [3*i + 2] -= lik * x [2] ; + } + } + + /* W = U\W */ + for (k = k2-1 ; k >= k1 ; k--) + { + pend = Up [k+1] - 1 ; + ukk = Ux [pend] ; + x [0] = Wx [3*k ] / ukk ; + x [1] = Wx [3*k + 1] / ukk ; + x [2] = Wx [3*k + 2] / ukk ; + Wx [3*k ] = x [0] ; + Wx [3*k + 1] = x [1] ; + Wx [3*k + 2] = x [2] ; + for (p = Up [k] ; p < pend ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + Wx [3*i ] -= uik * x [0] ; + Wx [3*i + 1] -= uik * x [1] ; + Wx [3*i + 2] -= uik * x [2] ; + } + } + break ; + + case 4: + + /* W = L\W */ + for (k = k1 ; k < k2 ; k++) + { + p = Lp [k] ; + pend = Lp [k+1] ; + lkk = Lx [p++] ; + x [0] = Wx [4*k ] / lkk ; + x [1] = Wx [4*k + 1] / lkk ; + x [2] = Wx [4*k + 2] / lkk ; + x [3] = Wx [4*k + 3] / lkk ; + Wx [4*k ] = x [0] ; + Wx [4*k + 1] = x [1] ; + Wx [4*k + 2] = x [2] ; + Wx [4*k + 3] = x [3] ; + for ( ; p < pend ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + Wx [4*i ] -= lik * x [0] ; + Wx [4*i + 1] -= lik * x [1] ; + Wx [4*i + 2] -= lik * x [2] ; + Wx [4*i + 3] -= lik * x [3] ; + } + } + + /* Wx = U\Wx */ + for (k = k2-1 ; k >= k1 ; k--) + { + pend = Up [k+1] - 1 ; + ukk = Ux [pend] ; + x [0] = Wx [4*k ] / ukk ; + x [1] = Wx [4*k + 1] / ukk ; + x [2] = Wx [4*k + 2] / ukk ; + x [3] = Wx [4*k + 3] / ukk ; + Wx [4*k ] = x [0] ; + Wx [4*k + 1] = x [1] ; + Wx [4*k + 2] = x [2] ; + Wx [4*k + 3] = x [3] ; + for (p = Up [k] ; p < pend ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + Wx [4*i ] -= uik * x [0] ; + Wx [4*i + 1] -= uik * x [1] ; + Wx [4*i + 2] -= uik * x [2] ; + Wx [4*i + 3] -= uik * x [3] ; + } + } + break ; + } + } + + /* ---------------------------------------------- */ + /* block back-substitution for off-diagonal-block */ + /* ---------------------------------------------- */ + + if (block > 0 && Offp != NULL) + { + switch (nr) + { + + case 1: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = Wx [k] ; + for (p = Offp [k] ; p < pend ; p++) + { + Wx [Offi [p]] -= Offx[p] * x[0]; + } + } + break ; + + case 2: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = Wx [2*k ] ; + x [1] = Wx [2*k + 1] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + Wx [2*i ] -= offik * x [0] ; + Wx [2*i + 1] -= offik * x [1] ; + } + } + break ; + + case 3: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = Wx [3*k ] ; + x [1] = Wx [3*k + 1] ; + x [2] = Wx [3*k + 2] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + Wx [3*i ] -= offik * x [0] ; + Wx [3*i + 1] -= offik * x [1] ; + Wx [3*i + 2] -= offik * x [2] ; + } + } + break ; + + case 4: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = Wx [4*k ] ; + x [1] = Wx [4*k + 1] ; + x [2] = Wx [4*k + 2] ; + x [3] = Wx [4*k + 3] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + Wx [4*i ] -= offik * x [0] ; + Wx [4*i + 1] -= offik * x [1] ; + Wx [4*i + 2] -= offik * x [2] ; + Wx [4*i + 3] -= offik * x [3] ; + } + } + break ; + } + } + } + + /* -------------------------------------------------- */ + /* permute the result, X = Q*W */ + /* -------------------------------------------------- */ + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Xx [i] = Wx [k] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Xx [i ] = Wx [2*k ] ; + Xx [i + n ] = Wx [2*k + 1] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Xx [i ] = Wx [3*k ] ; + Xx [i + n ] = Wx [3*k + 1] ; + Xx [i + n*2] = Wx [3*k + 2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Q ? (Q [k] - 1) : k ; + Xx [i ] = Wx [4*k ] ; + Xx [i + n ] = Wx [4*k + 1] ; + Xx [i + n*2] = Wx [4*k + 2] ; + Xx [i + n*3] = Wx [4*k + 3] ; + } + break ; + } + + /* -------------------------------------------------- */ + /* go to the next chunk of B and X */ + /* -------------------------------------------------- */ + + Xx += n*4 ; + Bx += n*4 ; + } + } + + /* free workspace */ + mxFree (Wx) ; + } + + } + + } + else + { + + /* ------------------------------------------------------------------ */ + /* LU = klu (A) usage; extract factorization */ + /* ------------------------------------------------------------------ */ + + /* sort the row indices in each column of L and U */ + if (A_complex) + { + klu_zl_sort (Symbolic, Numeric, &Common) ; + } + else + { + klu_l_sort (Symbolic, Numeric, &Common) ; + } + + /* L */ + L_matlab = mxCreateSparse (n, n, Numeric->lnz, + A_complex ? mxCOMPLEX: mxREAL) ; + Lp = (UF_long *) mxGetJc (L_matlab) ; + Li = (UF_long *) mxGetIr (L_matlab) ; + Lx = mxGetPr (L_matlab) ; + Lz = mxGetPi (L_matlab) ; + + /* U */ + U_matlab = mxCreateSparse (n, n, Numeric->unz, + A_complex ? mxCOMPLEX: mxREAL) ; + Up = (UF_long *) mxGetJc (U_matlab) ; + Ui = (UF_long *) mxGetIr (U_matlab) ; + Ux = mxGetPr (U_matlab) ; + Uz = mxGetPi (U_matlab) ; + + /* p */ + p_matlab = mxCreateNumericMatrix (1, n, mx_int, mxREAL) ; + P = (UF_long *) mxGetData (p_matlab) ; + + /* q */ + q_matlab = mxCreateNumericMatrix (1, n, mx_int, mxREAL) ; + Q = (UF_long *) mxGetData (q_matlab) ; + + /* R, as a sparse diagonal matrix */ + R_matlab = mxCreateSparse (n, n, n+1, mxREAL) ; + Rp = (UF_long *) mxGetJc (R_matlab) ; + Ri = (UF_long *) mxGetIr (R_matlab) ; + Rs = mxGetPr (R_matlab) ; + for (k = 0 ; k <= n ; k++) + { + Rp [k] = k ; + Ri [k] = k ; + } + + /* F, off diagonal blocks */ + F_matlab = mxCreateSparse (n, n, Numeric->nzoff, + A_complex ? mxCOMPLEX: mxREAL) ; + Offp = (UF_long *) mxGetJc (F_matlab) ; + Offi = (UF_long *) mxGetIr (F_matlab) ; + Offx = mxGetPr (F_matlab) ; + Offz = mxGetPi (F_matlab) ; + + /* r, block boundaries */ + nblocks = Symbolic->nblocks ; + r_matlab = mxCreateNumericMatrix (1, nblocks+1, mx_int, mxREAL) ; + R = (UF_long *) mxGetData (r_matlab) ; + + /* extract the LU factorization from KLU Numeric and Symbolic objects */ + if (A_complex) + { + klu_zl_extract (Numeric, Symbolic, Lp, Li, Lx, Lz, Up, Ui, Ux, Uz, + Offp, Offi, Offx, Offz, P, Q, Rs, R, &Common) ; + } + else + { + klu_l_extract (Numeric, Symbolic, Lp, Li, Lx, Up, Ui, Ux, + Offp, Offi, Offx, P, Q, Rs, R, &Common) ; + } + + /* fix p and q for 1-based indexing */ + for (k = 0 ; k < n ; k++) + { + P [k]++ ; + Q [k]++ ; + } + + /* fix r for 1-based indexing */ + for (k = 0 ; k <= nblocks ; k++) + { + R [k]++ ; + } + + /* create output LU struct */ + pargout [0] = mxCreateStructMatrix (1, 1, 7, LUnames) ; + mxSetFieldByNumber (pargout [0], 0, 0, L_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 1, U_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 2, p_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 3, q_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 4, R_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 5, F_matlab) ; + mxSetFieldByNumber (pargout [0], 0, 6, r_matlab) ; + + /* ------------------------------------------------------------------ */ + /* free Symbolic and Numeric objects */ + /* ------------------------------------------------------------------ */ + + klu_l_free_symbolic (&Symbolic, &Common) ; + klu_l_free_numeric (&Numeric, &Common) ; + } +} diff --git a/OpenDSSC/klusolve/KLU/Makefile b/OpenDSSC/klusolve/KLU/Makefile new file mode 100644 index 0000000..65ee585 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Makefile @@ -0,0 +1,27 @@ +default: library + +include ../UFconfig/UFconfig.mk + +library: + ( cd Lib ; $(MAKE) ) +# ( cd Demo ; $(MAKE) ) + +clean: + ( cd Demo ; $(MAKE) clean ) + ( cd Lib ; $(MAKE) clean ) + ( cd Tcov ; $(MAKE) clean ) + +distclean: + ( cd Demo ; $(MAKE) distclean ) + ( cd Lib ; $(MAKE) distclean ) + ( cd Tcov ; $(MAKE) distclean ) + ( cd User ; $(MAKE) distclean ) + ( cd MATLAB ; $(MAKE) distclean ) + +mex: + ( cd MATLAB ; $(MAKE) ) + +purge: distclean + +cov: library + ( cd Tcov ; $(MAKE) ) diff --git a/OpenDSSC/klusolve/KLU/Matrix/1c.mtx b/OpenDSSC/klusolve/KLU/Matrix/1c.mtx new file mode 100644 index 0000000..b9da424 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/1c.mtx @@ -0,0 +1,3 @@ +%%MatrixMarket matrix coordinate complex general +1 1 1 +1 1 1 1 diff --git a/OpenDSSC/klusolve/KLU/Matrix/GD99_cc.mtx b/OpenDSSC/klusolve/KLU/Matrix/GD99_cc.mtx new file mode 100644 index 0000000..4f5baec --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/GD99_cc.mtx @@ -0,0 +1,152 @@ +%%MatrixMarket matrix coordinate complex general +% imaginary part is Pajek/GD99_c, real part is zero +105 105 149 +6 1 0 1 +5 2 0 1 +7 2 0 1 +4 3 0 1 +8 3 0 1 +5 4 0 1 +1 5 0 1 +24 6 0 1 +6 7 0 1 +7 8 0 1 +26 9 0 1 +105 10 0 1 +94 11 0 1 +40 12 0 1 +26 13 0 1 +16 14 0 1 +26 15 0 1 +26 16 0 1 +16 17 0 1 +16 19 0 1 +16 20 0 1 +57 21 0 1 +15 22 0 1 +31 22 0 1 +13 23 0 1 +15 24 0 1 +13 25 0 1 +9 26 0 1 +16 26 0 1 +57 26 0 1 +24 27 0 1 +85 28 0 1 +85 29 0 1 +32 30 0 1 +86 30 0 1 +22 31 0 1 +45 31 0 1 +57 31 0 1 +22 32 0 1 +85 32 0 1 +54 33 0 1 +88 33 0 1 +91 33 0 1 +91 34 0 1 +92 34 0 1 +95 35 0 1 +50 36 0 1 +98 37 0 1 +98 38 0 1 +38 39 0 1 +38 40 0 1 +102 41 0 1 +101 42 0 1 +103 43 0 1 +100 44 0 1 +104 44 0 1 +31 45 0 1 +93 45 0 1 +28 46 0 1 +50 47 0 1 +87 47 0 1 +100 47 0 1 +53 48 0 1 +99 48 0 1 +87 49 0 1 +89 49 0 1 +45 50 0 1 +94 50 0 1 +31 51 0 1 +104 51 0 1 +48 52 0 1 +90 52 0 1 +91 52 0 1 +89 53 0 1 +87 54 0 1 +90 54 0 1 +93 54 0 1 +99 55 0 1 +29 56 0 1 +18 57 0 1 +21 57 0 1 +26 57 0 1 +31 57 0 1 +95 58 0 1 +45 59 0 1 +103 59 0 1 +59 60 0 1 +102 61 0 1 +61 62 0 1 +61 63 0 1 +53 64 0 1 +64 65 0 1 +65 66 0 1 +64 67 0 1 +91 67 0 1 +92 67 0 1 +88 68 0 1 +97 69 0 1 +96 70 0 1 +97 70 0 1 +96 71 0 1 +92 72 0 1 +48 73 0 1 +64 73 0 1 +98 73 0 1 +40 74 0 1 +86 75 0 1 +96 76 0 1 +86 77 0 1 +82 78 0 1 +78 79 0 1 +82 79 0 1 +81 80 0 1 +84 80 0 1 +78 81 0 1 +33 82 0 1 +82 83 0 1 +83 84 0 1 +32 85 0 1 +30 86 0 1 +47 87 0 1 +54 87 0 1 +33 88 0 1 +97 88 0 1 +49 89 0 1 +99 89 0 1 +52 90 0 1 +55 90 0 1 +33 91 0 1 +67 91 0 1 +34 92 0 1 +50 93 0 1 +50 94 0 1 +95 94 0 1 +94 95 0 1 +70 96 0 1 +88 97 0 1 +73 98 0 1 +55 99 0 1 +89 99 0 1 +47 100 0 1 +101 100 0 1 +100 101 0 1 +102 101 0 1 +101 102 0 1 +59 103 0 1 +105 103 0 1 +105 104 0 1 +104 105 0 1 diff --git a/OpenDSSC/klusolve/KLU/Matrix/arrow.mtx b/OpenDSSC/klusolve/KLU/Matrix/arrow.mtx new file mode 100644 index 0000000..27419e4 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/arrow.mtx @@ -0,0 +1,300 @@ +%%MatrixMarket matrix coordinate integer general +100 100 298 +1 1 2 +2 1 1 +3 1 1 +4 1 1 +5 1 1 +6 1 1 +7 1 1 +8 1 1 +9 1 1 +10 1 1 +11 1 1 +12 1 1 +13 1 1 +14 1 1 +15 1 1 +16 1 1 +17 1 1 +18 1 1 +19 1 1 +20 1 1 +21 1 1 +22 1 1 +23 1 1 +24 1 1 +25 1 1 +26 1 1 +27 1 1 +28 1 1 +29 1 1 +30 1 1 +31 1 1 +32 1 1 +33 1 1 +34 1 1 +35 1 1 +36 1 1 +37 1 1 +38 1 1 +39 1 1 +40 1 1 +41 1 1 +42 1 1 +43 1 1 +44 1 1 +45 1 1 +46 1 1 +47 1 1 +48 1 1 +49 1 1 +50 1 1 +51 1 1 +52 1 1 +53 1 1 +54 1 1 +55 1 1 +56 1 1 +57 1 1 +58 1 1 +59 1 1 +60 1 1 +61 1 1 +62 1 1 +63 1 1 +64 1 1 +65 1 1 +66 1 1 +67 1 1 +68 1 1 +69 1 1 +70 1 1 +71 1 1 +72 1 1 +73 1 1 +74 1 1 +75 1 1 +76 1 1 +77 1 1 +78 1 1 +79 1 1 +80 1 1 +81 1 1 +82 1 1 +83 1 1 +84 1 1 +85 1 1 +86 1 1 +87 1 1 +88 1 1 +89 1 1 +90 1 1 +91 1 1 +92 1 1 +93 1 1 +94 1 1 +95 1 1 +96 1 1 +97 1 1 +98 1 1 +99 1 1 +100 1 1 +1 2 2 +2 2 1 +1 3 1 +3 3 1 +1 4 1 +4 4 1 +1 5 1 +5 5 1 +1 6 1 +6 6 1 +1 7 1 +7 7 1 +1 8 1 +8 8 1 +1 9 1 +9 9 1 +1 10 1 +10 10 1 +1 11 1 +11 11 1 +1 12 1 +12 12 1 +1 13 1 +13 13 1 +1 14 1 +14 14 1 +1 15 1 +15 15 1 +1 16 1 +16 16 1 +1 17 1 +17 17 1 +1 18 1 +18 18 1 +1 19 1 +19 19 1 +1 20 1 +20 20 1 +1 21 1 +21 21 1 +1 22 1 +22 22 1 +1 23 1 +23 23 1 +1 24 1 +24 24 1 +1 25 1 +25 25 1 +1 26 1 +26 26 1 +1 27 1 +27 27 1 +1 28 1 +28 28 1 +1 29 1 +29 29 1 +1 30 1 +30 30 1 +1 31 1 +31 31 1 +1 32 1 +32 32 1 +1 33 1 +33 33 1 +1 34 1 +34 34 1 +1 35 1 +35 35 1 +1 36 1 +36 36 1 +1 37 1 +37 37 1 +1 38 1 +38 38 1 +1 39 1 +39 39 1 +1 40 1 +40 40 1 +1 41 1 +41 41 1 +1 42 1 +42 42 1 +1 43 1 +43 43 1 +1 44 1 +44 44 1 +1 45 1 +45 45 1 +1 46 1 +46 46 1 +1 47 1 +47 47 1 +1 48 1 +48 48 1 +1 49 1 +49 49 1 +1 50 1 +50 50 1 +1 51 1 +51 51 1 +1 52 1 +52 52 1 +1 53 1 +53 53 1 +1 54 1 +54 54 1 +1 55 1 +55 55 1 +1 56 1 +56 56 1 +1 57 1 +57 57 1 +1 58 1 +58 58 1 +1 59 1 +59 59 1 +1 60 1 +60 60 1 +1 61 1 +61 61 1 +1 62 1 +62 62 1 +1 63 1 +63 63 1 +1 64 1 +64 64 1 +1 65 1 +65 65 1 +1 66 1 +66 66 1 +1 67 1 +67 67 1 +1 68 1 +68 68 1 +1 69 1 +69 69 1 +1 70 1 +70 70 1 +1 71 1 +71 71 1 +1 72 1 +72 72 1 +1 73 1 +73 73 1 +1 74 1 +74 74 1 +1 75 1 +75 75 1 +1 76 1 +76 76 1 +1 77 1 +77 77 1 +1 78 1 +78 78 1 +1 79 1 +79 79 1 +1 80 1 +80 80 1 +1 81 1 +81 81 1 +1 82 1 +82 82 1 +1 83 1 +83 83 1 +1 84 1 +84 84 1 +1 85 1 +85 85 1 +1 86 1 +86 86 1 +1 87 1 +87 87 1 +1 88 1 +88 88 1 +1 89 1 +89 89 1 +1 90 1 +90 90 1 +1 91 1 +91 91 1 +1 92 1 +92 92 1 +1 93 1 +93 93 1 +1 94 1 +94 94 1 +1 95 1 +95 95 1 +1 96 1 +96 96 1 +1 97 1 +97 97 1 +1 98 1 +98 98 1 +1 99 1 +99 99 1 +1 100 1 +100 100 1 diff --git a/OpenDSSC/klusolve/KLU/Matrix/arrowc.mtx b/OpenDSSC/klusolve/KLU/Matrix/arrowc.mtx new file mode 100644 index 0000000..bf4d3c5 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/arrowc.mtx @@ -0,0 +1,300 @@ +%%MatrixMarket matrix coordinate complex general +100 100 298 +1 1 0 1 +2 1 1 0 +3 1 1 0 +4 1 1 0 +5 1 1 0 +6 1 1 0 +7 1 1 0 +8 1 1 0 +9 1 1 0 +10 1 1 0 +11 1 1 0 +12 1 1 0 +13 1 1 0 +14 1 1 0 +15 1 1 0 +16 1 1 0 +17 1 1 0 +18 1 1 0 +19 1 1 0 +20 1 1 0 +21 1 1 0 +22 1 1 0 +23 1 1 0 +24 1 1 0 +25 1 1 0 +26 1 1 0 +27 1 1 0 +28 1 1 0 +29 1 1 0 +30 1 1 0 +31 1 1 0 +32 1 1 0 +33 1 1 0 +34 1 1 0 +35 1 1 0 +36 1 1 0 +37 1 1 0 +38 1 1 0 +39 1 1 0 +40 1 1 0 +41 1 1 0 +42 1 1 0 +43 1 1 0 +44 1 1 0 +45 1 1 0 +46 1 1 0 +47 1 1 0 +48 1 1 0 +49 1 1 0 +50 1 1 0 +51 1 1 0 +52 1 1 0 +53 1 1 0 +54 1 1 0 +55 1 1 0 +56 1 1 0 +57 1 1 0 +58 1 1 0 +59 1 1 0 +60 1 1 0 +61 1 1 0 +62 1 1 0 +63 1 1 0 +64 1 1 0 +65 1 1 0 +66 1 1 0 +67 1 1 0 +68 1 1 0 +69 1 1 0 +70 1 1 0 +71 1 1 0 +72 1 1 0 +73 1 1 0 +74 1 1 0 +75 1 1 0 +76 1 1 0 +77 1 1 0 +78 1 1 0 +79 1 1 0 +80 1 1 0 +81 1 1 0 +82 1 1 0 +83 1 1 0 +84 1 1 0 +85 1 1 0 +86 1 1 0 +87 1 1 0 +88 1 1 0 +89 1 1 0 +90 1 1 0 +91 1 1 0 +92 1 1 0 +93 1 1 0 +94 1 1 0 +95 1 1 0 +96 1 1 0 +97 1 1 0 +98 1 1 0 +99 1 1 0 +100 1 1 0 +1 2 2 0 +2 2 1 0 +1 3 1 0 +3 3 1 0 +1 4 1 0 +4 4 1 0 +1 5 1 0 +5 5 1 0 +1 6 1 0 +6 6 1 0 +1 7 1 0 +7 7 1 0 +1 8 1 0 +8 8 1 0 +1 9 1 0 +9 9 1 0 +1 10 1 0 +10 10 1 0 +1 11 1 0 +11 11 1 0 +1 12 1 0 +12 12 1 0 +1 13 1 0 +13 13 1 0 +1 14 1 0 +14 14 1 0 +1 15 1 0 +15 15 1 0 +1 16 1 0 +16 16 1 0 +1 17 1 0 +17 17 1 0 +1 18 1 0 +18 18 1 0 +1 19 1 0 +19 19 1 0 +1 20 1 0 +20 20 1 0 +1 21 1 0 +21 21 1 0 +1 22 1 0 +22 22 1 0 +1 23 1 0 +23 23 1 0 +1 24 1 0 +24 24 1 0 +1 25 1 0 +25 25 1 0 +1 26 1 0 +26 26 1 0 +1 27 1 0 +27 27 1 0 +1 28 1 0 +28 28 1 0 +1 29 1 0 +29 29 1 0 +1 30 1 0 +30 30 1 0 +1 31 1 0 +31 31 1 0 +1 32 1 0 +32 32 1 0 +1 33 1 0 +33 33 1 0 +1 34 1 0 +34 34 1 0 +1 35 1 0 +35 35 1 0 +1 36 1 0 +36 36 1 0 +1 37 1 0 +37 37 1 0 +1 38 1 0 +38 38 1 0 +1 39 1 0 +39 39 1 0 +1 40 1 0 +40 40 1 0 +1 41 1 0 +41 41 1 0 +1 42 1 0 +42 42 1 0 +1 43 1 0 +43 43 1 0 +1 44 1 0 +44 44 1 0 +1 45 1 0 +45 45 1 0 +1 46 1 0 +46 46 1 0 +1 47 1 0 +47 47 1 0 +1 48 1 0 +48 48 1 0 +1 49 1 0 +49 49 1 0 +1 50 1 0 +50 50 1 0 +1 51 1 0 +51 51 1 0 +1 52 1 0 +52 52 1 0 +1 53 1 0 +53 53 1 0 +1 54 1 0 +54 54 1 0 +1 55 1 0 +55 55 1 0 +1 56 1 0 +56 56 1 0 +1 57 1 0 +57 57 1 0 +1 58 1 0 +58 58 1 0 +1 59 1 0 +59 59 1 0 +1 60 1 0 +60 60 1 0 +1 61 1 0 +61 61 1 0 +1 62 1 0 +62 62 1 0 +1 63 1 0 +63 63 1 0 +1 64 1 0 +64 64 1 0 +1 65 1 0 +65 65 1 0 +1 66 1 0 +66 66 1 0 +1 67 1 0 +67 67 1 0 +1 68 1 0 +68 68 1 0 +1 69 1 0 +69 69 1 0 +1 70 1 0 +70 70 1 0 +1 71 1 0 +71 71 1 0 +1 72 1 0 +72 72 1 0 +1 73 1 0 +73 73 1 0 +1 74 1 0 +74 74 1 0 +1 75 1 0 +75 75 1 0 +1 76 1 0 +76 76 1 0 +1 77 1 0 +77 77 1 0 +1 78 1 0 +78 78 1 0 +1 79 1 0 +79 79 1 0 +1 80 1 0 +80 80 1 0 +1 81 1 0 +81 81 1 0 +1 82 1 0 +82 82 1 0 +1 83 1 0 +83 83 1 0 +1 84 1 0 +84 84 1 0 +1 85 1 0 +85 85 1 0 +1 86 1 0 +86 86 1 0 +1 87 1 0 +87 87 1 0 +1 88 1 0 +88 88 1 0 +1 89 1 0 +89 89 1 0 +1 90 1 0 +90 90 1 0 +1 91 1 0 +91 91 1 0 +1 92 1 0 +92 92 1 0 +1 93 1 0 +93 93 1 0 +1 94 1 0 +94 94 1 0 +1 95 1 0 +95 95 1 0 +1 96 1 0 +96 96 1 0 +1 97 1 0 +97 97 1 0 +1 98 1 0 +98 98 1 0 +1 99 1 0 +99 99 1 0 +1 100 1 0 +100 100 1 0 diff --git a/OpenDSSC/klusolve/KLU/Matrix/ctina.mtx b/OpenDSSC/klusolve/KLU/Matrix/ctina.mtx new file mode 100644 index 0000000..3773ee1 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/ctina.mtx @@ -0,0 +1,39 @@ +%%MatrixMarket matrix coordinate complex general +% complex matrix with same nonzero pattern as Pajek/Tina_AskCog +11 11 36 +3 1 0 1 +6 1 0 1 +10 1 0 1 +1 2 0 1 +3 2 0 1 +5 2 0 1 +6 2 0 1 +8 2 0 1 +9 2 0 1 +10 2 0 1 +1 3 0 1 +6 3 0 1 +10 3 0 1 +2 4 0 1 +6 4 0 1 +7 4 0 1 +8 4 0 1 +11 4 0 1 +6 5 0 1 +10 5 0 1 +5 6 0 1 +11 6 0 1 +4 7 0 1 +6 7 0 1 +9 7 0 1 +2 8 0 1 +4 8 0 1 +5 8 0 1 +6 8 0 1 +7 8 0 1 +9 8 0 1 +11 8 0 1 +7 9 0 1 +3 10 0 1 +5 10 0 1 +8 11 0 1 diff --git a/OpenDSSC/klusolve/KLU/Matrix/impcol_a.mtx b/OpenDSSC/klusolve/KLU/Matrix/impcol_a.mtx new file mode 100644 index 0000000..49952a6 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/impcol_a.mtx @@ -0,0 +1,586 @@ +%%MatrixMarket matrix coordinate real general +%------------------------------------------------------------------------------- +% UF Sparse Matrix Collection, Tim Davis +% http://www.cise.ufl.edu/research/sparse/matrices/HB/impcol_a +% name: HB/impcol_a +% [UNSYMMETRIC MATRIX - HEAT EXCHANGER NETWORK (CHEM ENG) ,1982] +% id: 171 +% date: 1982 +% author: D. Bogle +% ed: I. Duff, R. Grimes, J. Lewis +% fields: title A name id date author ed kind +% kind: chemical process simulation problem +%------------------------------------------------------------------------------- +207 207 572 +5 1 -1 +6 1 -1 +8 1 -1 +11 1 .0662129 +12 1 .1634 +1 2 1 +2 2 1 +11 2 -.579712 +12 2 -.422521 +3 3 1 +4 3 1 +10 3 -1 +11 3 17.8775 +12 3 44.1179 +5 4 -1 +65 4 1 +66 4 .5 +1 5 -1 +62 5 -1 +3 6 -1 +64 6 -1 +6 7 680 +7 8 1 +9 9 1 +8 10 1 +14 10 -1 +17 10 .00297937 +18 10 .0247819 +12 11 1 +17 11 -.220568 +18 11 -.808841 +10 12 1 +16 12 -1 +17 12 .804429 +18 12 6.69112 +11 13 .0708967 +12 13 -.0706236 +13 14 -1 +17 14 -.0323714 +18 14 -.00352409 +23 14 -1 +24 14 -1 +17 15 -.779432 +18 15 -.191159 +19 15 1 +20 15 1 +15 16 -1 +17 16 -7.57491 +18 16 -.824638 +21 16 1 +22 16 1 +13 17 1 +31 17 -1 +33 17 -150 +17 18 1 +33 18 -234 +15 19 1 +32 19 -1 +14 20 1 +34 20 -1 +36 20 -126.8 +16 21 1 +17 22 .104857 +18 22 -.0908757 +23 23 -1 +26 23 -1 +29 23 -.0311679 +30 23 -.103571 +19 24 -1 +29 24 -.757389 +30 24 -.625946 +21 25 -1 +28 25 -1 +29 25 -10.7841 +30 25 -35.8356 +24 26 580 +25 27 1 +27 28 1 +26 29 1 +31 29 -1 +33 29 -142.6 +28 30 1 +29 31 -.0979613 +30 31 .0483804 +31 32 1 +33 32 145.6 +33 33 580 +32 34 1 +34 35 -1 +36 35 -161 +38 35 1 +35 36 -1 +40 36 1 +34 37 -1 +36 37 -152.2 +203 37 1 +205 38 1 +34 39 -1 +36 39 -136.3 +197 39 1 +199 40 1 +34 41 -1 +36 41 -108.6 +98 41 1 +100 42 1 +34 43 -1 +36 43 -120.7 +67 43 1 +69 44 1 +34 45 1 +36 45 128 +95 45 1 +96 45 .2 +36 46 680 +92 46 -1 +35 47 1 +94 47 -1 +38 48 -1 +41 48 1.65272 +42 48 2.82163 +47 48 -1 +41 49 -.607865 +42 49 -.263986 +43 49 -1 +40 50 -1 +41 50 36.3599 +42 50 62.0759 +45 50 -1 +37 51 1 +39 52 1 +41 53 .559606 +42 53 -.677581 +47 54 1 +48 54 .7 +53 54 -1 +44 55 -1 +49 55 -1 +46 56 -1 +51 56 -1 +47 57 -1 +48 57 -1 +203 57 -1 +206 57 .478232 +207 57 1.21868 +43 58 1 +44 58 1 +206 58 -.330881 +207 58 -.280695 +45 59 1 +46 59 1 +205 59 -1 +206 59 21.9987 +207 59 56.0594 +48 60 68 +53 61 1 +54 61 .6 +59 61 -1 +50 62 -1 +55 62 -1 +52 63 -1 +57 63 -1 +53 64 -1 +54 64 -1 +197 64 -1 +200 64 .27161 +201 64 .629158 +49 65 1 +50 65 1 +200 65 -.561642 +201 65 -.382811 +51 66 1 +52 66 1 +199 66 -1 +200 66 24.7165 +201 66 57.2534 +54 67 159 +59 68 1 +60 68 .2 +65 68 -1 +56 69 -1 +61 69 -1 +58 70 -1 +63 70 -1 +59 71 -1 +60 71 -1 +98 71 -1 +101 71 .244371 +102 71 1.02444 +55 72 1 +56 72 1 +101 72 -.272351 +102 72 -.432602 +57 73 1 +58 73 1 +100 73 -1 +101 73 11.7298 +102 73 49.1733 +60 74 207 +65 75 -1 +66 75 -1 +67 75 -1 +71 75 .232813 +72 75 .061436 +61 76 1 +62 76 1 +71 76 -.573583 +72 76 -.869891 +63 77 1 +64 77 1 +69 77 -1 +71 77 47.4938 +72 77 12.5329 +66 78 411 +68 79 -1 +71 79 -.341668 +72 79 -.40286 +74 79 1 +70 80 -1 +71 80 -34.1668 +72 80 -40.286 +76 80 1 +68 81 1 +70 82 1 +71 83 -.0459958 +72 83 .0938315 +73 84 -1 +77 84 .179968 +78 84 .0328426 +83 84 -1 +84 84 -1 +77 85 -.53763 +78 85 -.943234 +79 85 1 +80 85 1 +75 86 -1 +77 86 36.7135 +78 86 6.69988 +81 86 1 +82 86 1 +74 87 -1 +77 87 -.311136 +78 87 -.186857 +164 87 1 +76 88 -1 +77 88 -31.1136 +78 88 -18.6857 +166 88 1 +73 89 1 +109 89 -1 +111 89 -201 +75 90 1 +77 91 -.012899 +78 91 .026314 +83 92 1 +84 92 .4 +89 92 -1 +80 93 -1 +85 93 -1 +82 94 -1 +87 94 -1 +83 95 -1 +131 95 -1 +134 95 .0222685 +135 95 .0916503 +79 96 -1 +134 96 -.852598 +135 96 -.686678 +81 97 -1 +133 97 -1 +134 97 6.30198 +135 97 25.937 +84 98 487 +89 99 1 +90 99 .1 +95 99 -1 +86 100 -1 +91 100 -1 +88 101 -1 +93 101 -1 +89 102 -1 +90 102 -1 +104 102 -1 +107 102 .306796 +108 102 1.72865 +85 103 1 +86 103 1 +107 103 -.953179 +108 103 -.478015 +87 104 1 +88 104 1 +106 104 -1 +107 104 14.7262 +108 104 82.9751 +90 105 535 +95 106 -1 +96 106 -1 +122 106 1 +123 106 .6 +91 107 1 +92 107 1 +119 107 -1 +93 108 1 +94 108 1 +121 108 -1 +96 109 680 +97 110 -1 +101 110 -.312836 +102 110 -.082762 +103 110 1 +99 111 -1 +101 111 -31.2836 +102 111 -8.2762 +105 111 1 +97 112 1 +99 113 1 +101 114 .409192 +102 114 -.852483 +104 115 1 +109 115 -1 +111 115 -273.9 +106 116 1 +107 117 .147934 +108 117 -.0810126 +109 118 -1 +111 118 -176.9 +131 118 1 +110 119 -1 +133 119 1 +109 120 -1 +111 120 -209.1 +125 120 1 +127 121 1 +109 122 -1 +111 122 -193 +113 122 1 +111 123 -54 +117 123 1 +115 124 1 +109 125 1 +111 125 197 +161 125 1 +162 125 .6 +111 126 680 +158 126 -1 +110 127 1 +160 127 -1 +113 128 -1 +116 128 .250032 +117 128 .597517 +122 128 -1 +116 129 -.585577 +117 129 -.406865 +118 129 -1 +115 130 -1 +116 130 13.5017 +117 130 32.2659 +120 130 -1 +112 131 1 +202 131 -1 +206 131 -.419796 +207 131 -.122705 +114 132 1 +204 132 -1 +206 132 -41.9796 +207 132 -12.2705 +116 133 .239041 +117 133 -.242126 +122 134 -1 +123 134 -1 +125 134 -1 +128 134 .158767 +129 134 .340658 +118 135 1 +119 135 1 +128 135 -.588216 +129 135 -.353609 +120 136 1 +121 136 1 +127 136 -1 +128 136 14.4478 +129 136 30.9999 +123 137 145 +124 138 -1 +128 138 -.307616 +129 138 -.130446 +190 138 1 +128 139 -.411784 +129 139 -.646391 +194 139 1 +126 140 -1 +128 140 -30.7616 +129 140 -13.0446 +192 140 1 +124 141 1 +196 141 -1 +200 141 -.562373 +201 141 -.225697 +126 142 1 +198 142 -1 +200 142 -56.2373 +201 142 -22.5697 +128 143 .10564 +129 143 -.116088 +130 144 -1 +134 144 -.276727 +135 144 -.171445 +140 144 -1 +141 144 -1 +134 145 -.147402 +135 145 -.313322 +136 145 1 +137 145 1 +132 146 -1 +134 146 -28.7796 +135 146 -17.8303 +138 146 1 +139 146 1 +130 147 1 +154 147 -1 +156 147 -193.6 +132 148 1 +155 148 -1 +134 149 .087773 +135 149 -.0322558 +140 150 -1 +143 150 -1 +146 150 -.0323781 +147 150 -.0683179 +136 151 -1 +146 151 -.60537 +147 151 -.349597 +138 152 -1 +145 152 -1 +146 152 -12.1741 +147 152 -25.6875 +141 153 480 +142 154 1 +144 155 1 +143 156 1 +149 156 -1 +152 156 -.00472003 +153 156 -.0317473 +147 157 1 +152 157 -.934841 +153 157 -.792495 +145 158 1 +151 158 -1 +152 158 -1.77473 +153 158 -11.937 +146 159 -.0203625 +147 159 .0218773 +148 160 1 +150 161 1 +149 162 1 +154 162 -1 +156 162 -198 +153 163 1 +156 163 -376 +151 164 1 +152 165 -.0366465 +153 165 .00813435 +154 166 1 +156 166 197.2 +155 167 1 +161 168 -1 +162 168 -1 +163 168 -1 +167 168 .0165562 +168 168 .00408216 +157 169 1 +158 169 1 +167 169 -.832633 +168 169 -.729721 +159 170 1 +160 170 1 +165 170 -1 +167 170 7.21849 +168 170 1.77982 +161 171 -1 +191 171 -1 +194 171 .00193333 +195 171 .0781847 +157 172 -1 +194 172 -.995803 +195 172 -.705952 +159 173 -1 +193 173 -1 +194 173 .471732 +195 173 19.0771 +162 174 680 +164 175 -1 +167 175 -.0379488 +168 175 -.16853 +170 175 1 +167 176 -.167367 +168 176 -.270279 +174 176 1 +166 177 -1 +167 177 -3.79488 +168 177 -16.853 +172 177 1 +163 178 1 +185 178 -1 +188 178 .0406846 +189 178 .100421 +165 179 1 +187 179 -1 +188 179 17.7385 +189 179 43.7834 +167 180 -.0235888 +168 180 .102847 +169 181 -1 +173 181 .123883 +174 181 .0243372 +191 181 1 +171 182 -1 +173 182 30.2273 +174 182 5.93828 +193 182 1 +170 183 -1 +173 183 -.242234 +174 183 -.211144 +176 183 1 +173 184 -.3775 +174 184 -.0788991 +180 184 1 +172 185 -1 +173 185 -24.2234 +174 185 -21.1144 +178 185 1 +169 186 1 +181 186 -1 +183 186 -281.7 +171 187 1 +182 187 -1 +173 188 -.0173768 +174 188 .0423995 +175 189 -1 +179 189 .0149554 +180 189 .00262203 +181 189 1 +183 189 291 +179 190 -.825997 +180 190 -.904947 +183 190 680 +177 191 -1 +179 191 10.1696 +180 191 1.78298 +182 191 1 +175 192 1 +177 193 1 +179 194 -.00696415 +180 194 .0362189 +181 195 -1 +183 195 -296 +185 195 1 +187 196 1 +184 197 1 +188 198 1 +186 199 1 +188 200 .0382256 +189 200 -.0306734 +194 201 .00264546 +195 201 -.000781169 +196 202 1 +198 203 1 +200 204 .229712 +201 204 -.25243 +202 205 1 +204 206 1 +206 207 .27097 +207 207 -.589066 diff --git a/OpenDSSC/klusolve/KLU/Matrix/one.mtx b/OpenDSSC/klusolve/KLU/Matrix/one.mtx new file mode 100644 index 0000000..ef09891 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/one.mtx @@ -0,0 +1,6 @@ +%%MatrixMarket matrix coordinate real general +2 2 4 +1 1 0 +1 2 0 +2 1 0 +2 2 0 diff --git a/OpenDSSC/klusolve/KLU/Matrix/onec.mtx b/OpenDSSC/klusolve/KLU/Matrix/onec.mtx new file mode 100644 index 0000000..59c8534 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/onec.mtx @@ -0,0 +1,6 @@ +%%MatrixMarket matrix coordinate complex general +2 2 4 +1 1 0 0 +1 2 0 0 +2 1 0 0 +2 2 0 0 diff --git a/OpenDSSC/klusolve/KLU/Matrix/two.mtx b/OpenDSSC/klusolve/KLU/Matrix/two.mtx new file mode 100644 index 0000000..7457e81 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/two.mtx @@ -0,0 +1,3 @@ +%%MatrixMarket matrix coordinate real general +2 2 1 +1 1 3 diff --git a/OpenDSSC/klusolve/KLU/Matrix/w156.mtx b/OpenDSSC/klusolve/KLU/Matrix/w156.mtx new file mode 100644 index 0000000..658309c --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Matrix/w156.mtx @@ -0,0 +1,365 @@ +%%MatrixMarket matrix coordinate complex general +% complex matrix with the same real part, and same pattern, as HB/west0156 +156 156 362 +147 1 1 -89.00615831818635 +148 2 1 19.968263502718298 +149 2 -.1632648 -21.370801333956592 +59 3 -1.16206 -56.926762937042156 +134 3 -.8122999 -63.520075069490886 +149 3 1 -84.64919515773938 +52 4 1 -98.51526079522304 +53 5 1 57.75659925548426 +54 5 -.2166122 -96.44247397535688 +54 6 1 75.58829308886945 +59 6 -.1 -29.491646321365707 +118 7 1 44.42795357432983 +119 8 1 93.69016787815801 +120 8 -.2113848 -68.86640328523129 +59 9 1 -67.40889160696356 +105 9 .699017 -37.32052633277537 +120 9 1 -94.12369035075191 +150 10 1.009263 -28.474976610167545 +151 10 11.46533 -94.56192034360119 +150 11 .9908224 58.733403730195796 +152 11 -.5284282 99.84615089171123 +153 11 -.4980997 -77.95229509053108 +156 11 -.06675177 24.520231739121968 +152 12 1 -73.48563095366146 +153 13 1 -37.99404220990422 +155 13 -.8429148 -73.0424624342159 +154 14 1 -55.33473746935735 +156 14 -.0344062 -20.690642338915623 +155 15 1 -72.97130102560114 +156 15 -.00102006 -51.78826211728082 +134 16 5.047402 85.50322996314317 +156 16 1 -21.779825201968972 +138 17 -1.052632 2.25255469346175 +141 17 -.6666667 -81.42077676767339 +141 18 1 -95.66021714041189 +143 18 -.4480102 -68.09303466517918 +143 19 -2.988037 68.90318876644317 +143 20 1 75.83069648519695 +145 20 1 -62.60209482759951 +146 20 -1 98.26098380691137 +2 21 -.0535949 42.4059682333364 +144 21 2 74.27292331881648 +131 22 1 -4.0737630474247055 +133 22 -.9965392 -.7990146886149518 +132 23 1 -42.493627158378786 +133 23 -.003460798 -87.811709810653 +133 24 1 -47.506459158247225 +135 24 1 -62.747796590550934 +134 25 1 83.41795736466501 +135 25 1 -75.34426113632455 +137 26 .07513964 -97.31092337989851 +138 26 1 -26.06185629381749 +144 27 -5.47842 39.72822166458327 +145 27 -3.3405 77.86944264650091 +142 28 1 18.754103827151415 +146 28 -1 -68.66182065372685 +121 29 1.006185 -36.66211626227418 +122 29 10.73614 -53.320902834444595 +121 30 .9938532 -98.31558725078405 +123 30 -.5209677 -20.61924162618064 +124 30 -.4971525 29.973626118500405 +127 30 -.07339495 -82.99987875707477 +123 31 1 53.761900651751795 +124 32 1 93.94034099433995 +126 32 -.8391701 42.95944637524101 +125 33 1 56.39236839209942 +127 33 -.0258101 -52.4869835919564 +126 34 1 -60.85384724334488 +127 34 -.00199955 -47.357216964877104 +105 35 -5.396799 42.757012919227776 +127 35 1 95.51994788712943 +109 36 -.5263158 27.42438816918027 +112 36 -.3333333 9.184831019804385 +112 37 1 69.61144488338648 +114 37 -1.265049 60.41953169602192 +114 38 -1.778183 33.66128201334357 +114 39 1 34.19652679396956 +116 39 1 64.12873645714785 +117 39 -1 94.09447492182123 +2 40 -.0535949 -2.615000891619801 +115 40 2 63.49370710939066 +102 41 1 28.314233569200088 +104 41 -.9965392 -38.73012809722005 +103 42 1 32.186426447893 +104 42 -.003460798 -28.396577322438276 +104 43 1 87.63988602024271 +106 43 1 -2.4666050470267376 +105 44 1 -81.8019284512067 +106 44 1 34.7668233724147 +108 45 .1709599 2.976063797565698 +109 45 1 -55.68413072287828 +115 46 -5.47842 45.001874190444255 +116 46 -3.3405 -86.35067780598133 +113 47 1 92.82485367450755 +117 47 -1 -58.46868232626774 +55 48 -1 -67.77635488972467 +111 48 -1 27.644276518549617 +120 48 -1 -99.9543654216764 +118 49 -.5238095 -32.87341132956595 +120 49 -2.325233 -44.9800357067578 +55 50 -.2113848 -91.09449592159396 +56 50 1 -81.22070048053217 +101 50 -1 -18.000520045594502 +120 50 -.2113848 63.37846389879085 +4 51 -1 74.1034143618639 +17 51 -1 -95.48897590879422 +19 51 3.328735e-12 45.435396739586366 +20 51 1 69.60188961279125 +5 52 -1 45.72003820360473 +23 52 1 91.01972665502697 +24 52 1 31.27022211937156 +15 53 -1 48.46102670181145 +17 53 -.2113848 -31.006797219415848 +18 53 1 76.80438993503029 +61 54 -1 -30.551182700157376 +102 54 1 -88.10466389149548 +103 54 1 43.682918215884015 +110 54 -1 91.64285858148136 +117 54 1 -68.63302698512894 +63 55 -1 -16.72937877072226 +107 55 -1 -81.19302620544275 +66 56 -1 -10.010709210238765 +99 56 -1 73.83048511517521 +102 56 1.009514 -21.676555467798853 +113 56 -1.008042 -49.443269787795316 +67 57 -1 -29.123614686250242 +100 57 -1 48.59559363996606 +103 57 106.1112 30.166404491500764 +113 57 -.1547227 87.9586081050228 +60 58 1 66.5598249196907 +76 58 -1 -6.004426629012382 +139 58 1 25.973121452632107 +62 59 1 -88.36243043738105 +136 59 1 8.437479459481146 +64 60 1 -8.854807545659217 +76 60 -.9795877 72.61737844345258 +128 60 1 71.03939394472891 +65 61 1 -5.548863487187949 +76 61 -3.145565 57.38487793395959 +129 61 1 31.19642765119832 +34 62 -.008064516 -99.99202208021522 +36 63 1.974212 -73.75256764965177 +37 63 -.8416949 -1.0250487994832636 +37 64 1 -92.33336856681214 +38 64 -.008525207 -54.512838099295834 +38 65 1 -34.42340854356044 +39 65 -1 79.89375753843836 +47 65 -1 -37.25390248725466 +39 66 1 -49.66479762290302 +40 66 -1 -13.402173664778449 +40 67 1.895931 68.47644730738057 +41 67 -.9987282 -63.10220167747585 +41 68 1 1.6358424738914135 +42 68 2.087875 -9.552066657022863 +42 69 -1 -34.88311211669629 +46 69 -1 -23.984738606508827 +43 70 5.616771 77.29599272885395 +44 70 7.392325 52.252152063678636 +44 71 1 76.75326698731126 +45 71 7.20301 -8.51874880007002 +45 72 -1 59.84045826963149 +46 72 -.3258084 -73.18457603806863 +2 73 -2.146936 -86.93726233197341 +46 73 1 -24.971068398888395 +1 74 -6.821893 -25.29540601492628 +47 74 1 -3.1955205789929164 +91 75 2.431413 93.89184641063227 +93 75 -1 -31.58778114773145 +91 76 -2.431413 -49.4621487710556 +92 76 1 16.977383351584187 +93 77 1 4.740718882261197 +94 77 -1.26 -67.31619071487106 +2 78 -.8858734 -2.7203702821855025 +94 78 2 -.7878501044749853 +95 79 1 68.63881664718761 +96 79 -1 61.23964308235974 +1 80 -.02308312 71.5571192607996 +96 80 1 21.950827565571494 +82 81 1 13.146073550568627 +84 81 .9638 22.379704330589135 +97 81 1 -79.40469554532865 +84 82 .9905759 -68.33681654633787 +98 82 1 -17.27002806448744 +5 83 1.068219 12.082089707594035 +16 83 -1 -46.26454171200754 +6 84 9.305934e-22 56.85083285313337 +7 84 -.19106 -22.425843053832928 +8 84 -.3460553 -93.8032758232799 +7 85 1 17.10036588328181 +9 85 -.2113848 11.711705644935023 +9 86 1 -59.860885505008746 +10 86 -1 -82.51562297274859 +14 86 -1 86.64597186070104 +10 87 1 -48.124005287383966 +11 87 -1 -59.165721082767206 +12 88 1 -90.15831162239165 +13 88 -5.165179 21.23218795450579 +11 89 2.109794 9.269748032162251 +12 89 -.4423309 -80.83251277071686 +2 90 -1.200652 27.39912937614759 +13 90 1 -11.410334391483856 +1 91 -2.151087 -86.72360822705714 +14 91 1 -25.141483188003487 +7 92 -3.221332 -50.17945514204103 +8 92 -.08256881 84.9750583295307 +16 92 1.030078 25.899858515648553 +68 93 .00729927 75.66175530017894 +69 94 .009933775 28.334886205187427 +70 95 2.109489 59.67812719925334 +71 96 1.923841 -12.994792290221335 +72 97 1 96.2280502631985 +76 97 -.9703559 -80.80844033399066 +73 98 1 5.496479792736464 +76 98 -.02964405 9.129164943297008 +74 99 1 -43.131448638051594 +77 99 -.9703559 -25.83946813902346 +75 100 1 -87.06147957359738 +77 100 -.02964405 8.961812886476107 +76 101 1 67.27512065071366 +77 101 1 -70.93560166316104 +79 101 1 -65.69594863822117 +78 102 .009933775 -86.39056354840274 +79 102 -.3 64.80230680396102 +79 103 -3.333333 -73.2058484284056 +81 103 1 76.95725769618616 +2 104 -.3581659 2.947479893374072 +80 104 .9144476 92.7271192399364 +80 105 -2.355064 -75.90106649225966 +81 105 -2.599699 -90.342023563869 +1 106 1 -23.969599224575187 +3 106 -.5 -17.441756388313255 +2 107 1 -19.721740669438702 +3 107 -.5 -15.800573906372883 +3 108 1 -24.609261720375176 +110 109 1 81.46730529244041 +131 109 -.9431611 34.03242893843479 +132 109 -.5 92.36770491956567 +139 109 -1 -67.40413278123356 +146 109 1 49.72988179123301 +107 110 1 -25.186855192188627 +136 110 -1 -9.152697748159888 +99 111 1 -92.28786082587108 +128 111 -1 12.486401290146553 +131 111 -.9521341 -25.537570672597443 +142 111 -1.008042 58.55674146933576 +100 112 1 59.046194569800136 +129 112 -1 -23.417105544732607 +132 112 -53.05558 -49.44203913337082 +142 112 -.1547227 -31.414428806369965 +4 113 1 93.56089866913022 +9 113 -1.098983 -4.038321887840279 +111 113 1 -26.334487417080844 +127 113 -1.006101 52.91343104779358 +15 114 1 -24.570205949318236 +101 114 1 80.06124313084004 +127 114 -.2126745 -63.313589410507554 +17 115 3.875969e-8 -26.336536744115246 +19 115 -1 83.49140785169018 +21 116 -.9939418 3.183211228849636 +23 117 -1 -81.93854756530253 +17 118 2.727302e-20 47.06229753702564 +18 118 -1 -99.05756753456353 +17 119 1 20.62462338921529 +20 119 -1 91.37333280835817 +25 119 -1 -20.513614148643057 +27 119 .9972523 46.310157066657176 +28 119 1.02473 36.92776530123669 +22 120 -.9939418 95.70060448966404 +29 120 1 -59.24296668628066 +30 120 1 18.66056780239591 +24 121 -1 90.31250335814364 +31 121 1 -47.94551850968427 +32 121 1 2.9355241818408873 +17 122 .2113848 27.26637973052666 +25 122 -.2113848 -19.808178764946284 +26 122 1 -2.677737852379014 +19 123 5453728 50.091622636210076 +20 123 -.2113848 -74.7606532733799 +25 124 .9 -91.38750367809608 +27 124 -1 -25.812131278013382 +140 124 -1 38.66042415449142 +156 124 -1.009619 87.16498856941061 +29 125 -1 -4.484878166369444 +153 125 -.5019003 -74.17998047268341 +156 125 -.2294135 -3.2337575851525746 +31 126 -1 89.11943234297857 +137 126 -1 -26.45117330526361 +151 126 1 -34.30288621503337 +25 127 .1897236 54.575096067325134 +26 127 -1 -40.54519558973049 +130 127 -1 -64.42912801819011 +156 127 -.2128317 38.15983229583313 +25 128 .1 -47.211028939720535 +28 128 -1 -8.452188579330155 +33 128 1 68.73848491242163 +38 128 -1.007626 76.29973210306002 +30 129 -1 40.00399128013372 +36 129 -1 51.13819898638041 +38 129 -.2680827 94.90296027698403 +32 130 -1 -19.569463307138236 +34 130 1 -73.74427235921586 +25 131 .02166122 44.94677740033393 +35 131 1 79.903641471542 +38 131 -.2182642 -65.85973708326853 +27 132 .234872 -91.3942617588595 +28 132 -2.113848 -4.168155014702535 +55 133 .9 -81.21274304896602 +140 133 1 30.009966330192217 +149 133 -.7744864 90.45550778420308 +57 134 1.052135 -8.457460121512772 +137 134 .9248604 7.376129401205689 +55 135 .1897236 -86.70257083968079 +130 135 1 -1.2259832834904283 +149 135 -.1632648 -16.491805524055003 +33 136 -1 -41.548589946331724 +48 136 1 -42.06721249302474 +35 137 -1 50.769199337537785 +51 137 1 -80.6408576103972 +48 138 -1 -84.6165978311754 +54 138 -1 44.18300600646185 +55 138 .1 52.982301945926324 +49 139 -1 31.588984823676935 +52 139 -.5238095 62.08170441145384 +54 139 -2.382735 -25.151381648928016 +50 140 -.991453 -38.7537048036034 +58 140 1.06422 -25.86008018285866 +51 141 -1 41.34942373575503 +54 141 -.2166122 -66.32674228356838 +55 141 .02166122 62.744201350248474 +50 142 -.06837607 -6.7543369226229055 +60 143 -1 44.45713521489259 +85 143 175966.4 98.97378279407572 +86 143 -1 -27.499396494334206 +91 143 -2.431413 46.16562887690614 +95 143 -1 29.933482992494255 +69 144 .9900662 36.26781509331472 +70 144 -1.091241 -98.47761599001427 +76 144 -13 30.829860743864714 +78 144 .9900662 89.04702870503172 +87 144 1 22.65420709853554 +88 144 1 56.585595081575036 +62 145 -1 -99.36930257401184 +89 145 1 59.39156971639217 +90 145 -1 28.363331197466945 +64 146 -1 -64.30427579759511 +82 146 -1 5.880145934392633 +84 146 -.9638 -56.25129719765649 +95 146 -1.009514 9.61048763756911 +97 146 -1 -88.35252745679256 +65 147 -1 17.51741912019611 +85 147 1.8672e7 -16.77928832091964 +92 147 -106.1112 -62.7109528243285 +86 148 .7396663 -87.21785589638561 +87 149 -1 -85.04344448822249 +89 150 -.6169444 -37.992508436142 +82 151 .9905759 88.81698357390519 +83 152 1 96.14532626091892 +85 153 -175966.4 11.023098151583245 +86 153 .2603337 97.70512729352296 +88 154 -1 38.311980523494384 +90 155 1 -51.66782743196781 +84 156 .9905759 61.96273642788614 diff --git a/OpenDSSC/klusolve/KLU/README.txt b/OpenDSSC/klusolve/KLU/README.txt new file mode 100644 index 0000000..510a439 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/README.txt @@ -0,0 +1,139 @@ +KLU Version 1.0, May 31, 2007, by Timothy A. Davis and Ekanathan Palamadai. +Copyright (C) 2004-2007, University of Florida +KLU is also available under other licenses; contact authors for details. +http://www.cise.ufl.edu/research/sparse + +Requires the AMD, COLAMD, and BTF libraries, in ../AMD, ../COLAMD, and ../BTF, +respectively. Requires the ../UFconfig/UFconfig.mk configuration file. +Optionally uses CHOLMOD (KLU/User example ordering). The Tcov tests and +the Demo both require CHOLMOD. + +To compile the libklu.a library, type "make". The compiled library is located +in KLU/Lib/libklu.a. Compile code that uses KLU with -IKLU/Include. + +Type "make clean" to remove all but the compiled library, and "make distclean" +to remove all files not in the original distribution. + +-------------------------------------------------------------------------------- + +KLU is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This Module is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +-------------------------------------------------------------------------------- + +A full text of the license is in Doc/lesser.txt. + +Files in this distribution: + + Demo example programs that use KLU (requires CHOLMOD) + Doc documentation + Include include files + Lib compiled library + Makefile top-level Makefile + MATLAB MATLAB interface + Matrix test matrices + README.txt this file + Source source code + Tcov exhaustive test of KLU and BTF + User example user ordering function (interface to CHOLMOD) + +./Demo: + kludemo.c KLU demo (int version) + kludemo.out output of "make" in this directory + kluldemo.c KLU demo (UF_long version) + Makefile Makefile for compiling the demo + +./Doc: + ChangeLog + KLU_UserGuide.bib Bibiography + KLU_UserGuide.pdf PDF version of KLU User Guide + KLU_UserGuide.tex TEX source of KLU User Guide + lesser.txt license (LGPL) + Makefile Makefile for creating the User Guide + palamadai_e.pdf Eka Palamadai's MS thesis + +./Include: + klu.h user include file + klu_internal.h internal include file, not needed by the user + klu_version.h internal include file, not needed by the user + +./Lib: + Makefile Makefile for compiling the KLU C-callable library + +./MATLAB: + Contents.m list of MATLAB functions in KLU + klu_demo.m MATLAB demo + klu_demo.m.out output of MATLAB demo + klu_install.m compiles and installs KLU for use in MATLAB, runs demo + klu.m MATLAB help for KLU + klu_make.m compiles KLU for use in MATLAB + klu_mex.c MATLAB mexFunction interface for KLU + Makefile Makefile for KLU mexFunction, with CHOLMOD + Makefile_no_CHOLMOD Makefile for KLU mexFunction, without CHOLMOD + Test MATLAB tests + +./MATLAB/Test: KLU tests, requires UFget + test1.m + test2.m + test3.m + test4.m + test5.m + +./Matrix: test matrices for programs in ./Demo and ./Tcov + 1c.mtx + arrowc.mtx + arrow.mtx + ctina.mtx + GD99_cc.mtx + impcol_a.mtx + onec.mtx + one.mtx + two.mtx + w156.mtx + +./Source: + klu_analyze.c klu_analyze and supporting functions + klu_analyze_given.c klu_analyze_given and supporting functions + klu.c kernel factor/solve functions, not user-callable + klu_defaults.c klu_defaults function + klu_diagnostics.c klu_rcond, klu_condest, klu_rgrowth, kluflops + klu_dump.c debugging functions + klu_extract.c klu_extract + klu_factor.c klu_factor and supporting functions + klu_free_numeric.c klu_free_numeric function + klu_free_symbolic.c klu_free_symbolic function + klu_kernel.c kernel factor functions, not user-callable + klu_memory.c klu_malloc, klu_free, klu_realloc, and supporing func. + klu_refactor.c klu_refactor function + klu_scale.c klu_scale function + klu_solve.c klu_solve function + klu_sort.c klu_sort and supporting functions + klu_tsolve.c klu_tsovle function + +./Tcov: exhaustive test suite; requires Linux/Unix + coverage determine statement coverage + klultests KLU UF_long tests + klutest.c KLU test program + klutests KLU int tests + Makefile Makefile for compiling and running the tests + README.txt README file for Tcov + vklutests KLU int tests, using valgrind + vklultests KLU UF_long tests, using valgrind + +./User: + klu_cholmod.c sample KLU user ordering function (int version) + klu_cholmod.h include file for klu_cholmod and klu_l_cholmod + klu_l_cholmod.c sample KLU user ordering function (UF_long version) + Makefile Makefile for compiling the user ordering functions + README.txt README for User directory diff --git a/OpenDSSC/klusolve/KLU/Source/klu.c b/OpenDSSC/klusolve/KLU/Source/klu.c new file mode 100644 index 0000000..8b58008 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu.c @@ -0,0 +1,773 @@ +/* ========================================================================== */ +/* === klu ================================================================== */ +/* ========================================================================== */ + +/* KLU: factorizes P*A into L*U, using the Gilbert-Peierls algorithm [1], with + * optional symmetric pruning by Eisenstat and Liu [2]. The code is by Tim + * Davis. This algorithm is what appears as the default sparse LU routine in + * MATLAB version 6.0, and still appears in MATLAB 6.5 as [L,U,P] = lu (A). + * Note that no column ordering is provided (see COLAMD or AMD for suitable + * orderings). SuperLU is based on this algorithm, except that it adds the + * use of dense matrix operations on "supernodes" (adjacent columns with + * identical). This code doesn't use supernodes, thus its name ("Kent" LU, + * as in "Clark Kent", in contrast with Super-LU...). This algorithm is slower + * than SuperLU and UMFPACK for large matrices with lots of nonzeros in their + * factors (such as for most finite-element problems). However, for matrices + * with very sparse LU factors, this algorithm is typically faster than both + * SuperLU and UMFPACK, since in this case there is little chance to exploit + * dense matrix kernels (the BLAS). + * + * Only one block of A is factorized, in the BTF form. The input n is the + * size of the block; k1 is the first row and column in the block. + * + * NOTE: no error checking is done on the inputs. This version is not meant to + * be called directly by the user. Use klu_factor instead. + * + * No fill-reducing ordering is provided. The ordering quality of + * klu_kernel_factor is the responsibility of the caller. The input A must + * pre-permuted to reduce fill-in, or fill-reducing input permutation Q must + * be provided. + * + * The input matrix A must be in compressed-column form, with either sorted + * or unsorted row indices. Row indices for column j of A is in + * Ai [Ap [j] ... Ap [j+1]-1] and the same range of indices in Ax holds the + * numerical values. No duplicate entries are allowed. + * + * Copyright 2004-2007, Tim Davis. All rights reserved. See the README + * file for details on permitted use. Note that no code from The MathWorks, + * Inc, or from SuperLU, or from any other source appears here. The code is + * written from scratch, from the algorithmic description in Gilbert & Peierls' + * and Eisenstat & Liu's journal papers [1,2]. + * + * If an input permutation Q is provided, the factorization L*U = A (P,Q) + * is computed, where P is determined by partial pivoting, and Q is the input + * ordering. If the pivot tolerance is less than 1, the "diagonal" entry that + * KLU attempts to choose is the diagonal of A (Q,Q). In other words, the + * input permutation is applied symmetrically to the input matrix. The output + * permutation P includes both the partial pivoting ordering and the input + * permutation. If Q is NULL, then it is assumed to be the identity + * permutation. Q is not modified. + * + * [1] Gilbert, J. R. and Peierls, T., "Sparse Partial Pivoting in Time + * Proportional to Arithmetic Operations," SIAM J. Sci. Stat. Comp., + * vol 9, pp. 862-874, 1988. + * [2] Eisenstat, S. C. and Liu, J. W. H., "Exploiting Structural Symmetry in + * Unsymmetric Sparse Symbolic Factorization," SIAM J. Matrix Analysis & + * Applic., vol 13, pp. 202-211, 1992. + */ + +/* ========================================================================== */ + +#include "klu_internal.h" + +size_t KLU_kernel_factor /* 0 if failure, size of LU if OK */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n. n must be > 0. */ + Int Ap [ ], /* size n+1, column pointers for A */ + Int Ai [ ], /* size nz = Ap [n], row indices for A */ + Entry Ax [ ], /* size nz, values of A */ + Int Q [ ], /* size n, optional column permutation */ + double Lsize, /* estimate of number of nonzeros in L */ + + /* outputs, not defined on input */ + Unit **p_LU, /* row indices and values of L and U */ + Entry Udiag [ ], /* size n, diagonal of U */ + Int Llen [ ], /* size n, column length of L */ + Int Ulen [ ], /* size n, column length of U */ + Int Lip [ ], /* size n, column pointers for L */ + Int Uip [ ], /* size n, column pointers for U */ + Int P [ ], /* row permutation, size n */ + Int *lnz, /* size of L */ + Int *unz, /* size of U */ + + /* workspace, undefined on input */ + Entry *X, /* size n double's, zero on output */ + Int *Work, /* size 5n Int's */ + + /* inputs, not modified on output */ + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ], /* inverse of P from symbolic factorization */ + double Rs [ ], /* scale factors for A */ + + /* inputs, modified on output */ + Int Offp [ ], /* off-diagonal matrix (modified by this routine) */ + Int Offi [ ], + Entry Offx [ ], + /* --------------- */ + KLU_common *Common +) +{ + double maxlnz, dunits ; + Unit *LU ; + Int *Pinv, *Lpend, *Stack, *Flag, *Ap_pos, *W ; + Int lsize, usize, anz, ok ; + size_t lusize ; + ASSERT (Common != NULL) ; + + /* ---------------------------------------------------------------------- */ + /* get control parameters, or use defaults */ + /* ---------------------------------------------------------------------- */ + + n = MAX (1, n) ; + anz = Ap [n+k1] - Ap [k1] ; + + if (Lsize <= 0) + { + Lsize = -Lsize ; + Lsize = MAX (Lsize, 1.0) ; + lsize = Lsize * anz + n ; + } + else + { + lsize = Lsize ; + } + + usize = lsize ; + + lsize = MAX (n+1, lsize) ; + usize = MAX (n+1, usize) ; + + maxlnz = (((double) n) * ((double) n) + ((double) n)) / 2. ; + maxlnz = MIN (maxlnz, ((double) INT_MAX)) ; + lsize = MIN (maxlnz, lsize) ; + usize = MIN (maxlnz, usize) ; + + PRINTF (("Welcome to klu: n %d anz %d k1 %d lsize %d usize %d maxlnz %g\n", + n, anz, k1, lsize, usize, maxlnz)) ; + + /* ---------------------------------------------------------------------- */ + /* allocate workspace and outputs */ + /* ---------------------------------------------------------------------- */ + + /* return arguments are not yet assigned */ + *p_LU = (Unit *) NULL ; + + /* these computations are safe from size_t overflow */ + W = Work ; + Pinv = (Int *) W ; W += n ; + Stack = (Int *) W ; W += n ; + Flag = (Int *) W ; W += n ; + Lpend = (Int *) W ; W += n ; + Ap_pos = (Int *) W ; W += n ; + + dunits = DUNITS (Int, lsize) + DUNITS (Entry, lsize) + + DUNITS (Int, usize) + DUNITS (Entry, usize) ; + lusize = (size_t) dunits ; + ok = !INT_OVERFLOW (dunits) ; + LU = ok ? KLU_malloc (lusize, sizeof (Unit), Common) : NULL ; + if (LU == NULL) + { + /* out of memory, or problem too large */ + Common->status = KLU_OUT_OF_MEMORY ; + lusize = 0 ; + return (lusize) ; + } + + /* ---------------------------------------------------------------------- */ + /* factorize */ + /* ---------------------------------------------------------------------- */ + + /* with pruning, and non-recursive depth-first-search */ + lusize = KLU_kernel (n, Ap, Ai, Ax, Q, lusize, + Pinv, P, &LU, Udiag, Llen, Ulen, Lip, Uip, lnz, unz, + X, Stack, Flag, Ap_pos, Lpend, + k1, PSinv, Rs, Offp, Offi, Offx, Common) ; + + /* ---------------------------------------------------------------------- */ + /* return LU factors, or return nothing if an error occurred */ + /* ---------------------------------------------------------------------- */ + + if (Common->status < KLU_OK) + { + LU = KLU_free (LU, lusize, sizeof (Unit), Common) ; + lusize = 0 ; + } + *p_LU = LU ; + PRINTF ((" in klu noffdiag %d\n", Common->noffdiag)) ; + return (lusize) ; +} + + +/* ========================================================================== */ +/* === KLU_lsolve =========================================================== */ +/* ========================================================================== */ + +/* Solve Lx=b. Assumes L is unit lower triangular and where the unit diagonal + * entry is NOT stored. Overwrites B with the solution X. B is n-by-nrhs + * and is stored in ROW form with row dimension nrhs. nrhs must be in the + * range 1 to 4. */ + +void KLU_lsolve +( + /* inputs, not modified: */ + Int n, + Int Lip [ ], + Int Llen [ ], + Unit LU [ ], + Int nrhs, + /* right-hand-side on input, solution to Lx=b on output */ + Entry X [ ] +) +{ + Entry x [4], lik ; + Int *Li ; + Entry *Lx ; + Int k, p, len, i ; + + switch (nrhs) + { + + case 1: + for (k = 0 ; k < n ; k++) + { + x [0] = X [k] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + /* unit diagonal of L is not stored*/ + for (p = 0 ; p < len ; p++) + { + /* X [Li [p]] -= Lx [p] * x [0] ; */ + MULT_SUB (X [Li [p]], Lx [p], x [0]) ; + } + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + x [0] = X [2*k ] ; + x [1] = X [2*k + 1] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + MULT_SUB (X [2*i], lik, x [0]) ; + MULT_SUB (X [2*i + 1], lik, x [1]) ; + } + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + x [0] = X [3*k ] ; + x [1] = X [3*k + 1] ; + x [2] = X [3*k + 2] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + MULT_SUB (X [3*i], lik, x [0]) ; + MULT_SUB (X [3*i + 1], lik, x [1]) ; + MULT_SUB (X [3*i + 2], lik, x [2]) ; + } + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + x [0] = X [4*k ] ; + x [1] = X [4*k + 1] ; + x [2] = X [4*k + 2] ; + x [3] = X [4*k + 3] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; + lik = Lx [p] ; + MULT_SUB (X [4*i], lik, x [0]) ; + MULT_SUB (X [4*i + 1], lik, x [1]) ; + MULT_SUB (X [4*i + 2], lik, x [2]) ; + MULT_SUB (X [4*i + 3], lik, x [3]) ; + } + } + break ; + + } +} + +/* ========================================================================== */ +/* === KLU_usolve =========================================================== */ +/* ========================================================================== */ + +/* Solve Ux=b. Assumes U is non-unit upper triangular and where the diagonal + * entry is NOT stored. Overwrites B with the solution X. B is n-by-nrhs + * and is stored in ROW form with row dimension nrhs. nrhs must be in the + * range 1 to 4. */ + +void KLU_usolve +( + /* inputs, not modified: */ + Int n, + Int Uip [ ], + Int Ulen [ ], + Unit LU [ ], + Entry Udiag [ ], + Int nrhs, + /* right-hand-side on input, solution to Ux=b on output */ + Entry X [ ] +) +{ + Entry x [4], uik, ukk ; + Int *Ui ; + Entry *Ux ; + Int k, p, len, i ; + + switch (nrhs) + { + + case 1: + + for (k = n-1 ; k >= 0 ; k--) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + /* x [0] = X [k] / Udiag [k] ; */ + DIV (x [0], X [k], Udiag [k]) ; + X [k] = x [0] ; + for (p = 0 ; p < len ; p++) + { + /* X [Ui [p]] -= Ux [p] * x [0] ; */ + MULT_SUB (X [Ui [p]], Ux [p], x [0]) ; + + } + } + + break ; + + case 2: + + for (k = n-1 ; k >= 0 ; k--) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + ukk = Udiag [k] ; + /* x [0] = X [2*k ] / ukk ; + x [1] = X [2*k + 1] / ukk ; */ + DIV (x [0], X [2*k], ukk) ; + DIV (x [1], X [2*k + 1], ukk) ; + + X [2*k ] = x [0] ; + X [2*k + 1] = x [1] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + /* X [2*i ] -= uik * x [0] ; + X [2*i + 1] -= uik * x [1] ; */ + MULT_SUB (X [2*i], uik, x [0]) ; + MULT_SUB (X [2*i + 1], uik, x [1]) ; + } + } + + break ; + + case 3: + + for (k = n-1 ; k >= 0 ; k--) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + ukk = Udiag [k] ; + + DIV (x [0], X [3*k], ukk) ; + DIV (x [1], X [3*k + 1], ukk) ; + DIV (x [2], X [3*k + 2], ukk) ; + + X [3*k ] = x [0] ; + X [3*k + 1] = x [1] ; + X [3*k + 2] = x [2] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + MULT_SUB (X [3*i], uik, x [0]) ; + MULT_SUB (X [3*i + 1], uik, x [1]) ; + MULT_SUB (X [3*i + 2], uik, x [2]) ; + } + } + + break ; + + case 4: + + for (k = n-1 ; k >= 0 ; k--) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + ukk = Udiag [k] ; + + DIV (x [0], X [4*k], ukk) ; + DIV (x [1], X [4*k + 1], ukk) ; + DIV (x [2], X [4*k + 2], ukk) ; + DIV (x [3], X [4*k + 3], ukk) ; + + X [4*k ] = x [0] ; + X [4*k + 1] = x [1] ; + X [4*k + 2] = x [2] ; + X [4*k + 3] = x [3] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; + uik = Ux [p] ; + + MULT_SUB (X [4*i], uik, x [0]) ; + MULT_SUB (X [4*i + 1], uik, x [1]) ; + MULT_SUB (X [4*i + 2], uik, x [2]) ; + MULT_SUB (X [4*i + 3], uik, x [3]) ; + } + } + + break ; + + } +} + + +/* ========================================================================== */ +/* === KLU_ltsolve ========================================================== */ +/* ========================================================================== */ + +/* Solve L'x=b. Assumes L is unit lower triangular and where the unit diagonal + * entry is NOT stored. Overwrites B with the solution X. B is n-by-nrhs + * and is stored in ROW form with row dimension nrhs. nrhs must in the + * range 1 to 4. */ + +void KLU_ltsolve +( + /* inputs, not modified: */ + Int n, + Int Lip [ ], + Int Llen [ ], + Unit LU [ ], + Int nrhs, +#ifdef COMPLEX + Int conj_solve, +#endif + /* right-hand-side on input, solution to L'x=b on output */ + Entry X [ ] +) +{ + Entry x [4], lik ; + Int *Li ; + Entry *Lx ; + Int k, p, len, i ; + + switch (nrhs) + { + + case 1: + + for (k = n-1 ; k >= 0 ; k--) + { + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + x [0] = X [k] ; + for (p = 0 ; p < len ; p++) + { +#ifdef COMPLEX + if (conj_solve) + { + /* x [0] -= CONJ (Lx [p]) * X [Li [p]] ; */ + MULT_SUB_CONJ (x [0], X [Li [p]], Lx [p]) ; + } + else +#endif + { + /*x [0] -= Lx [p] * X [Li [p]] ;*/ + MULT_SUB (x [0], Lx [p], X [Li [p]]) ; + } + } + X [k] = x [0] ; + } + break ; + + case 2: + + for (k = n-1 ; k >= 0 ; k--) + { + x [0] = X [2*k ] ; + x [1] = X [2*k + 1] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (lik, Lx [p]) ; + } + else +#endif + { + lik = Lx [p] ; + } + MULT_SUB (x [0], lik, X [2*i]) ; + MULT_SUB (x [1], lik, X [2*i + 1]) ; + } + X [2*k ] = x [0] ; + X [2*k + 1] = x [1] ; + } + break ; + + case 3: + + for (k = n-1 ; k >= 0 ; k--) + { + x [0] = X [3*k ] ; + x [1] = X [3*k + 1] ; + x [2] = X [3*k + 2] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (lik, Lx [p]) ; + } + else +#endif + { + lik = Lx [p] ; + } + MULT_SUB (x [0], lik, X [3*i]) ; + MULT_SUB (x [1], lik, X [3*i + 1]) ; + MULT_SUB (x [2], lik, X [3*i + 2]) ; + } + X [3*k ] = x [0] ; + X [3*k + 1] = x [1] ; + X [3*k + 2] = x [2] ; + } + break ; + + case 4: + + for (k = n-1 ; k >= 0 ; k--) + { + x [0] = X [4*k ] ; + x [1] = X [4*k + 1] ; + x [2] = X [4*k + 2] ; + x [3] = X [4*k + 3] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + i = Li [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (lik, Lx [p]) ; + } + else +#endif + { + lik = Lx [p] ; + } + MULT_SUB (x [0], lik, X [4*i]) ; + MULT_SUB (x [1], lik, X [4*i + 1]) ; + MULT_SUB (x [2], lik, X [4*i + 2]) ; + MULT_SUB (x [3], lik, X [4*i + 3]) ; + } + X [4*k ] = x [0] ; + X [4*k + 1] = x [1] ; + X [4*k + 2] = x [2] ; + X [4*k + 3] = x [3] ; + } + break ; + } +} + + +/* ========================================================================== */ +/* === KLU_utsolve ========================================================== */ +/* ========================================================================== */ + +/* Solve U'x=b. Assumes U is non-unit upper triangular and where the diagonal + * entry is stored (and appears last in each column of U). Overwrites B + * with the solution X. B is n-by-nrhs and is stored in ROW form with row + * dimension nrhs. nrhs must be in the range 1 to 4. */ + +void KLU_utsolve +( + /* inputs, not modified: */ + Int n, + Int Uip [ ], + Int Ulen [ ], + Unit LU [ ], + Entry Udiag [ ], + Int nrhs, +#ifdef COMPLEX + Int conj_solve, +#endif + /* right-hand-side on input, solution to Ux=b on output */ + Entry X [ ] +) +{ + Entry x [4], uik, ukk ; + Int k, p, len, i ; + Int *Ui ; + Entry *Ux ; + + switch (nrhs) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + x [0] = X [k] ; + for (p = 0 ; p < len ; p++) + { +#ifdef COMPLEX + if (conj_solve) + { + /* x [0] -= CONJ (Ux [p]) * X [Ui [p]] ; */ + MULT_SUB_CONJ (x [0], X [Ui [p]], Ux [p]) ; + } + else +#endif + { + /* x [0] -= Ux [p] * X [Ui [p]] ; */ + MULT_SUB (x [0], Ux [p], X [Ui [p]]) ; + } + } +#ifdef COMPLEX + if (conj_solve) + { + CONJ (ukk, Udiag [k]) ; + } + else +#endif + { + ukk = Udiag [k] ; + } + DIV (X [k], x [0], ukk) ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + x [0] = X [2*k ] ; + x [1] = X [2*k + 1] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (uik, Ux [p]) ; + } + else +#endif + { + uik = Ux [p] ; + } + MULT_SUB (x [0], uik, X [2*i]) ; + MULT_SUB (x [1], uik, X [2*i + 1]) ; + } +#ifdef COMPLEX + if (conj_solve) + { + CONJ (ukk, Udiag [k]) ; + } + else +#endif + { + ukk = Udiag [k] ; + } + DIV (X [2*k], x [0], ukk) ; + DIV (X [2*k + 1], x [1], ukk) ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + x [0] = X [3*k ] ; + x [1] = X [3*k + 1] ; + x [2] = X [3*k + 2] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (uik, Ux [p]) ; + } + else +#endif + { + uik = Ux [p] ; + } + MULT_SUB (x [0], uik, X [3*i]) ; + MULT_SUB (x [1], uik, X [3*i + 1]) ; + MULT_SUB (x [2], uik, X [3*i + 2]) ; + } +#ifdef COMPLEX + if (conj_solve) + { + CONJ (ukk, Udiag [k]) ; + } + else +#endif + { + ukk = Udiag [k] ; + } + DIV (X [3*k], x [0], ukk) ; + DIV (X [3*k + 1], x [1], ukk) ; + DIV (X [3*k + 2], x [2], ukk) ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + x [0] = X [4*k ] ; + x [1] = X [4*k + 1] ; + x [2] = X [4*k + 2] ; + x [3] = X [4*k + 3] ; + for (p = 0 ; p < len ; p++) + { + i = Ui [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (uik, Ux [p]) ; + } + else +#endif + { + uik = Ux [p] ; + } + MULT_SUB (x [0], uik, X [4*i]) ; + MULT_SUB (x [1], uik, X [4*i + 1]) ; + MULT_SUB (x [2], uik, X [4*i + 2]) ; + MULT_SUB (x [3], uik, X [4*i + 3]) ; + } +#ifdef COMPLEX + if (conj_solve) + { + CONJ (ukk, Udiag [k]) ; + } + else +#endif + { + ukk = Udiag [k] ; + } + DIV (X [4*k], x [0], ukk) ; + DIV (X [4*k + 1], x [1], ukk) ; + DIV (X [4*k + 2], x [2], ukk) ; + DIV (X [4*k + 3], x [3], ukk) ; + } + break ; + } +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_analyze.c b/OpenDSSC/klusolve/KLU/Source/klu_analyze.c new file mode 100644 index 0000000..ecc715b --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_analyze.c @@ -0,0 +1,488 @@ +/* ========================================================================== */ +/* === klu_analyze ========================================================== */ +/* ========================================================================== */ + +/* Order the matrix using BTF (or not), and then AMD, COLAMD, the natural + * ordering, or the user-provided-function on the blocks. Does not support + * using a given ordering (use klu_analyze_given for that case). */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === analyze_worker ======================================================= */ +/* ========================================================================== */ + +static Int analyze_worker /* returns KLU_OK or < 0 if error */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + Int nblocks, /* # of blocks */ + Int Pbtf [ ], /* BTF row permutation */ + Int Qbtf [ ], /* BTF col permutation */ + Int R [ ], /* size n+1, but only Rbtf [0..nblocks] is used */ + Int ordering, /* what ordering to use (0, 1, or 3 for this routine) */ + + /* output only, not defined on input */ + Int P [ ], /* size n */ + Int Q [ ], /* size n */ + double Lnz [ ], /* size n, but only Lnz [0..nblocks-1] is used */ + + /* workspace, not defined on input or output */ + Int Pblk [ ], /* size maxblock */ + Int Cp [ ], /* size maxblock+1 */ + Int Ci [ ], /* size MAX (nz+1, Cilen) */ + Int Cilen, /* nz+1, or COLAMD_recommend(nz,n,n) for COLAMD */ + Int Pinv [ ], /* size maxblock */ + + /* input/output */ + KLU_symbolic *Symbolic, + KLU_common *Common +) +{ + double amd_Info [AMD_INFO], lnz, lnz1, flops, flops1 ; + Int k1, k2, nk, k, block, oldcol, pend, newcol, result, pc, p, newrow, + maxnz, nzoff, cstats [COLAMD_STATS], ok, err = KLU_INVALID ; + + /* ---------------------------------------------------------------------- */ + /* initializations */ + /* ---------------------------------------------------------------------- */ + + /* compute the inverse of Pbtf */ +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + P [k] = EMPTY ; + Q [k] = EMPTY ; + Pinv [k] = EMPTY ; + } +#endif + for (k = 0 ; k < n ; k++) + { + ASSERT (Pbtf [k] >= 0 && Pbtf [k] < n) ; + Pinv [Pbtf [k]] = k ; + } +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) ASSERT (Pinv [k] != EMPTY) ; +#endif + nzoff = 0 ; + lnz = 0 ; + maxnz = 0 ; + flops = 0 ; + Symbolic->symmetry = EMPTY ; /* only computed by AMD */ + + /* ---------------------------------------------------------------------- */ + /* order each block */ + /* ---------------------------------------------------------------------- */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* ------------------------------------------------------------------ */ + /* the block is from rows/columns k1 to k2-1 */ + /* ------------------------------------------------------------------ */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("BLOCK %d, k1 %d k2-1 %d nk %d\n", block, k1, k2-1, nk)) ; + + /* ------------------------------------------------------------------ */ + /* construct the kth block, C */ + /* ------------------------------------------------------------------ */ + + Lnz [block] = EMPTY ; + pc = 0 ; + for (k = k1 ; k < k2 ; k++) + { + newcol = k-k1 ; + Cp [newcol] = pc ; + oldcol = Qbtf [k] ; + pend = Ap [oldcol+1] ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + newrow = Pinv [Ai [p]] ; + if (newrow < k1) + { + nzoff++ ; + } + else + { + /* (newrow,newcol) is an entry in the block */ + ASSERT (newrow < k2) ; + newrow -= k1 ; + Ci [pc++] = newrow ; + } + } + } + Cp [nk] = pc ; + maxnz = MAX (maxnz, pc) ; + ASSERT (KLU_valid (nk, Cp, Ci, NULL)) ; + + /* ------------------------------------------------------------------ */ + /* order the block C */ + /* ------------------------------------------------------------------ */ + + if (nk <= 3) + { + + /* -------------------------------------------------------------- */ + /* use natural ordering for tiny blocks (3-by-3 or less) */ + /* -------------------------------------------------------------- */ + + for (k = 0 ; k < nk ; k++) + { + Pblk [k] = k ; + } + lnz1 = nk * (nk + 1) / 2 ; + flops1 = nk * (nk - 1) / 2 + (nk-1)*nk*(2*nk-1) / 6 ; + ok = TRUE ; + + } + else if (ordering == 0) + { + + /* -------------------------------------------------------------- */ + /* order the block with AMD (C+C') */ + /* -------------------------------------------------------------- */ + + result = AMD_order (nk, Cp, Ci, Pblk, NULL, amd_Info) ; + ok = (result >= AMD_OK) ; + if (result == AMD_OUT_OF_MEMORY) + { + err = KLU_OUT_OF_MEMORY ; + } + + /* account for memory usage in AMD */ + Common->mempeak = MAX (Common->mempeak, + Common->memusage + amd_Info [AMD_MEMORY]) ; + + /* get the ordering statistics from AMD */ + lnz1 = (Int) (amd_Info [AMD_LNZ]) + nk ; + flops1 = 2 * amd_Info [AMD_NMULTSUBS_LU] + amd_Info [AMD_NDIV] ; + if (pc == maxnz) + { + /* get the symmetry of the biggest block */ + Symbolic->symmetry = amd_Info [AMD_SYMMETRY] ; + } + + } + else if (ordering == 1) + { + + /* -------------------------------------------------------------- */ + /* order the block with COLAMD (C) */ + /* -------------------------------------------------------------- */ + + /* order (and destroy) Ci, returning column permutation in Cp. + * COLAMD "cannot" fail since the matrix has already been checked, + * and Ci allocated. */ + + ok = COLAMD (nk, nk, Cilen, Ci, Cp, NULL, cstats) ; + lnz1 = EMPTY ; + flops1 = EMPTY ; + + /* copy the permutation from Cp to Pblk */ + for (k = 0 ; k < nk ; k++) + { + Pblk [k] = Cp [k] ; + } + + } + else + { + + /* -------------------------------------------------------------- */ + /* pass the block to the user-provided ordering function */ + /* -------------------------------------------------------------- */ + + lnz1 = (Common->user_order) (nk, Cp, Ci, Pblk, Common) ; + flops1 = EMPTY ; + ok = (lnz1 != 0) ; + } + + if (!ok) + { + return (err) ; /* ordering method failed */ + } + + /* ------------------------------------------------------------------ */ + /* keep track of nnz(L) and flops statistics */ + /* ------------------------------------------------------------------ */ + + Lnz [block] = lnz1 ; + lnz = (lnz == EMPTY || lnz1 == EMPTY) ? EMPTY : (lnz + lnz1) ; + flops = (flops == EMPTY || flops1 == EMPTY) ? EMPTY : (flops + flops1) ; + + /* ------------------------------------------------------------------ */ + /* combine the preordering with the BTF ordering */ + /* ------------------------------------------------------------------ */ + + PRINTF (("Pblk, 1-based:\n")) ; + for (k = 0 ; k < nk ; k++) + { + ASSERT (k + k1 < n) ; + ASSERT (Pblk [k] + k1 < n) ; + Q [k + k1] = Qbtf [Pblk [k] + k1] ; + } + for (k = 0 ; k < nk ; k++) + { + ASSERT (k + k1 < n) ; + ASSERT (Pblk [k] + k1 < n) ; + P [k + k1] = Pbtf [Pblk [k] + k1] ; + } + } + + PRINTF (("nzoff %d Ap[n] %d\n", nzoff, Ap [n])) ; + ASSERT (nzoff >= 0 && nzoff <= Ap [n]) ; + + /* return estimates of # of nonzeros in L including diagonal */ + Symbolic->lnz = lnz ; /* EMPTY if COLAMD used */ + Symbolic->unz = lnz ; + Symbolic->nzoff = nzoff ; + Symbolic->est_flops = flops ; /* EMPTY if COLAMD or user-ordering used */ + return (KLU_OK) ; +} + + +/* ========================================================================== */ +/* === order_and_analyze ==================================================== */ +/* ========================================================================== */ + +/* Orders the matrix with or with BTF, then orders each block with AMD, COLAMD, + * or the user ordering function. Does not handle the natural or given + * ordering cases. */ + +static KLU_symbolic *order_and_analyze /* returns NULL if error, or a valid + KLU_symbolic object if successful */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + /* --------------------- */ + KLU_common *Common +) +{ + double work ; + KLU_symbolic *Symbolic ; + double *Lnz ; + Int *Qbtf, *Cp, *Ci, *Pinv, *Pblk, *Pbtf, *P, *Q, *R ; + Int nblocks, nz, block, maxblock, k1, k2, nk, do_btf, ordering, k, Cilen, + *Work ; + + /* ---------------------------------------------------------------------- */ + /* allocate the Symbolic object, and check input matrix */ + /* ---------------------------------------------------------------------- */ + + Symbolic = KLU_alloc_symbolic (n, Ap, Ai, Common) ; + if (Symbolic == NULL) + { + return (NULL) ; + } + P = Symbolic->P ; + Q = Symbolic->Q ; + R = Symbolic->R ; + Lnz = Symbolic->Lnz ; + nz = Symbolic->nz ; + + ordering = Common->ordering ; + if (ordering == 1) + { + /* COLAMD */ + Cilen = COLAMD_recommended (nz, n, n) ; + } + else if (ordering == 0 || (ordering == 3 && Common->user_order != NULL)) + { + /* AMD or user ordering function */ + Cilen = nz+1 ; + } + else + { + /* invalid ordering */ + Common->status = KLU_INVALID ; + KLU_free_symbolic (&Symbolic, Common) ; + return (NULL) ; + } + + /* AMD memory management routines */ + amd_malloc = Common->malloc_memory ; + amd_free = Common->free_memory ; + amd_calloc = Common->calloc_memory ; + amd_realloc = Common->realloc_memory ; + + /* ---------------------------------------------------------------------- */ + /* allocate workspace for BTF permutation */ + /* ---------------------------------------------------------------------- */ + + Pbtf = KLU_malloc (n, sizeof (Int), Common) ; + Qbtf = KLU_malloc (n, sizeof (Int), Common) ; + if (Common->status < KLU_OK) + { + KLU_free (Pbtf, n, sizeof (Int), Common) ; + KLU_free (Qbtf, n, sizeof (Int), Common) ; + KLU_free_symbolic (&Symbolic, Common) ; + return (NULL) ; + } + + /* ---------------------------------------------------------------------- */ + /* get the common parameters for BTF and ordering method */ + /* ---------------------------------------------------------------------- */ + + do_btf = Common->btf ; + do_btf = (do_btf) ? TRUE : FALSE ; + Symbolic->ordering = ordering ; + Symbolic->do_btf = do_btf ; + Symbolic->structural_rank = EMPTY ; + + /* ---------------------------------------------------------------------- */ + /* find the block triangular form (if requested) */ + /* ---------------------------------------------------------------------- */ + + Common->work = 0 ; + + if (do_btf) + { + Work = KLU_malloc (5*n, sizeof (Int), Common) ; + if (Common->status < KLU_OK) + { + /* out of memory */ + KLU_free (Pbtf, n, sizeof (Int), Common) ; + KLU_free (Qbtf, n, sizeof (Int), Common) ; + KLU_free_symbolic (&Symbolic, Common) ; + return (NULL) ; + } + + nblocks = BTF_order (n, Ap, Ai, Common->maxwork, &work, Pbtf, Qbtf, R, + &(Symbolic->structural_rank), Work) ; + Common->structural_rank = Symbolic->structural_rank ; + Common->work += work ; + + KLU_free (Work, 5*n, sizeof (Int), Common) ; + + /* unflip Qbtf if the matrix does not have full structural rank */ + if (Symbolic->structural_rank < n) + { + for (k = 0 ; k < n ; k++) + { + Qbtf [k] = BTF_UNFLIP (Qbtf [k]) ; + } + } + + /* find the size of the largest block */ + maxblock = 1 ; + for (block = 0 ; block < nblocks ; block++) + { + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("block %d size %d\n", block, nk)) ; + maxblock = MAX (maxblock, nk) ; + } + } + else + { + /* BTF not requested */ + nblocks = 1 ; + maxblock = n ; + R [0] = 0 ; + R [1] = n ; + for (k = 0 ; k < n ; k++) + { + Pbtf [k] = k ; + Qbtf [k] = k ; + } + } + + Symbolic->nblocks = nblocks ; + + PRINTF (("maxblock size %d\n", maxblock)) ; + Symbolic->maxblock = maxblock ; + + /* ---------------------------------------------------------------------- */ + /* allocate more workspace, for analyze_worker */ + /* ---------------------------------------------------------------------- */ + + Pblk = KLU_malloc (maxblock, sizeof (Int), Common) ; + Cp = KLU_malloc (maxblock + 1, sizeof (Int), Common) ; + Ci = KLU_malloc (MAX (Cilen, nz+1), sizeof (Int), Common) ; + Pinv = KLU_malloc (n, sizeof (Int), Common) ; + + /* ---------------------------------------------------------------------- */ + /* order each block of the BTF ordering, and a fill-reducing ordering */ + /* ---------------------------------------------------------------------- */ + + if (Common->status == KLU_OK) + { + PRINTF (("calling analyze_worker\n")) ; + Common->status = analyze_worker (n, Ap, Ai, nblocks, Pbtf, Qbtf, R, + ordering, P, Q, Lnz, Pblk, Cp, Ci, Cilen, Pinv, Symbolic, Common) ; + PRINTF (("analyze_worker done\n")) ; + } + + /* ---------------------------------------------------------------------- */ + /* free all workspace */ + /* ---------------------------------------------------------------------- */ + + KLU_free (Pblk, maxblock, sizeof (Int), Common) ; + KLU_free (Cp, maxblock+1, sizeof (Int), Common) ; + KLU_free (Ci, MAX (Cilen, nz+1), sizeof (Int), Common) ; + KLU_free (Pinv, n, sizeof (Int), Common) ; + KLU_free (Pbtf, n, sizeof (Int), Common) ; + KLU_free (Qbtf, n, sizeof (Int), Common) ; + + /* ---------------------------------------------------------------------- */ + /* return the symbolic object */ + /* ---------------------------------------------------------------------- */ + + if (Common->status < KLU_OK) + { + KLU_free_symbolic (&Symbolic, Common) ; + } + return (Symbolic) ; +} + + +/* ========================================================================== */ +/* === KLU_analyze ========================================================== */ +/* ========================================================================== */ + +KLU_symbolic *KLU_analyze /* returns NULL if error, or a valid + KLU_symbolic object if successful */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + /* -------------------- */ + KLU_common *Common +) +{ + + /* ---------------------------------------------------------------------- */ + /* get the control parameters for BTF and ordering method */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (NULL) ; + } + Common->status = KLU_OK ; + Common->structural_rank = EMPTY ; + + /* ---------------------------------------------------------------------- */ + /* order and analyze */ + /* ---------------------------------------------------------------------- */ + + if (Common->ordering == 2) + { + /* natural ordering */ + return (KLU_analyze_given (n, Ap, Ai, NULL, NULL, Common)) ; + } + else + { + /* order with P and Q */ + return (order_and_analyze (n, Ap, Ai, Common)) ; + } +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_analyze_given.c b/OpenDSSC/klusolve/KLU/Source/klu_analyze_given.c new file mode 100644 index 0000000..002b1cb --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_analyze_given.c @@ -0,0 +1,369 @@ +/* ========================================================================== */ +/* === klu_analyze_given ==================================================== */ +/* ========================================================================== */ + +/* Given an input permutation P and Q, create the Symbolic object. BTF can + * be done to modify the user's P and Q (does not perform the max transversal; + * just finds the strongly-connected components). */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === klu_alloc_symbolic =================================================== */ +/* ========================================================================== */ + +/* Allocate Symbolic object, and check input matrix. Not user callable. */ + +KLU_symbolic *KLU_alloc_symbolic +( + Int n, + Int *Ap, + Int *Ai, + KLU_common *Common +) +{ + KLU_symbolic *Symbolic ; + Int *P, *Q, *R ; + double *Lnz ; + Int nz, i, j, p, pend ; + + if (Common == NULL) + { + return (NULL) ; + } + Common->status = KLU_OK ; + + /* A is n-by-n, with n > 0. Ap [0] = 0 and nz = Ap [n] >= 0 required. + * Ap [j] <= Ap [j+1] must hold for all j = 0 to n-1. Row indices in Ai + * must be in the range 0 to n-1, and no duplicate entries can be present. + * The list of row indices in each column of A need not be sorted. + */ + + if (n <= 0 || Ap == NULL || Ai == NULL) + { + /* Ap and Ai must be present, and n must be > 0 */ + Common->status = KLU_INVALID ; + return (NULL) ; + } + + nz = Ap [n] ; + if (Ap [0] != 0 || nz < 0) + { + /* nz must be >= 0 and Ap [0] must equal zero */ + Common->status = KLU_INVALID ; + return (NULL) ; + } + + for (j = 0 ; j < n ; j++) + { + if (Ap [j] > Ap [j+1]) + { + /* column pointers must be non-decreasing */ + Common->status = KLU_INVALID ; + return (NULL) ; + } + } + P = KLU_malloc (n, sizeof (Int), Common) ; + if (Common->status < KLU_OK) + { + /* out of memory */ + Common->status = KLU_OUT_OF_MEMORY ; + return (NULL) ; + } + for (i = 0 ; i < n ; i++) + { + P [i] = EMPTY ; + } + for (j = 0 ; j < n ; j++) + { + pend = Ap [j+1] ; + for (p = Ap [j] ; p < pend ; p++) + { + i = Ai [p] ; + if (i < 0 || i >= n || P [i] == j) + { + /* row index out of range, or duplicate entry */ + KLU_free (P, n, sizeof (Int), Common) ; + Common->status = KLU_INVALID ; + return (NULL) ; + } + /* flag row i as appearing in column j */ + P [i] = j ; + } + } + + /* ---------------------------------------------------------------------- */ + /* allocate the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + Symbolic = KLU_malloc (sizeof (KLU_symbolic), 1, Common) ; + if (Common->status < KLU_OK) + { + /* out of memory */ + KLU_free (P, n, sizeof (Int), Common) ; + Common->status = KLU_OUT_OF_MEMORY ; + return (NULL) ; + } + + Q = KLU_malloc (n, sizeof (Int), Common) ; + R = KLU_malloc (n+1, sizeof (Int), Common) ; + Lnz = KLU_malloc (n, sizeof (double), Common) ; + + Symbolic->n = n ; + Symbolic->nz = nz ; + Symbolic->P = P ; + Symbolic->Q = Q ; + Symbolic->R = R ; + Symbolic->Lnz = Lnz ; + + if (Common->status < KLU_OK) + { + /* out of memory */ + KLU_free_symbolic (&Symbolic, Common) ; + Common->status = KLU_OUT_OF_MEMORY ; + return (NULL) ; + } + + return (Symbolic) ; +} + + +/* ========================================================================== */ +/* === KLU_analyze_given ==================================================== */ +/* ========================================================================== */ + +KLU_symbolic *KLU_analyze_given /* returns NULL if error, or a valid + KLU_symbolic object if successful */ +( + /* inputs, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + Int Puser [ ], /* size n, user's row permutation (may be NULL) */ + Int Quser [ ], /* size n, user's column permutation (may be NULL) */ + /* -------------------- */ + KLU_common *Common +) +{ + KLU_symbolic *Symbolic ; + double *Lnz ; + Int nblocks, nz, block, maxblock, *P, *Q, *R, nzoff, p, pend, do_btf, k ; + + /* ---------------------------------------------------------------------- */ + /* determine if input matrix is valid, and get # of nonzeros */ + /* ---------------------------------------------------------------------- */ + + Symbolic = KLU_alloc_symbolic (n, Ap, Ai, Common) ; + if (Symbolic == NULL) + { + return (NULL) ; + } + P = Symbolic->P ; + Q = Symbolic->Q ; + R = Symbolic->R ; + Lnz = Symbolic->Lnz ; + nz = Symbolic->nz ; + + /* ---------------------------------------------------------------------- */ + /* Q = Quser, or identity if Quser is NULL */ + /* ---------------------------------------------------------------------- */ + + if (Quser == (Int *) NULL) + { + for (k = 0 ; k < n ; k++) + { + Q [k] = k ; + } + } + else + { + for (k = 0 ; k < n ; k++) + { + Q [k] = Quser [k] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* get the control parameters for BTF and ordering method */ + /* ---------------------------------------------------------------------- */ + + do_btf = Common->btf ; + do_btf = (do_btf) ? TRUE : FALSE ; + Symbolic->ordering = 2 ; + Symbolic->do_btf = do_btf ; + + /* ---------------------------------------------------------------------- */ + /* find the block triangular form, if requested */ + /* ---------------------------------------------------------------------- */ + + if (do_btf) + { + + /* ------------------------------------------------------------------ */ + /* get workspace for BTF_strongcomp */ + /* ------------------------------------------------------------------ */ + + Int *Pinv, *Work, *Bi, k1, k2, nk, oldcol ; + + Work = KLU_malloc (4*n, sizeof (Int), Common) ; + Pinv = KLU_malloc (n, sizeof (Int), Common) ; + if (Puser != (Int *) NULL) + { + Bi = KLU_malloc (nz+1, sizeof (Int), Common) ; + } + else + { + Bi = Ai ; + } + + if (Common->status < KLU_OK) + { + /* out of memory */ + KLU_free (Work, 4*n, sizeof (Int), Common) ; + KLU_free (Pinv, n, sizeof (Int), Common) ; + if (Puser != (Int *) NULL) + { + KLU_free (Bi, nz+1, sizeof (Int), Common) ; + } + KLU_free_symbolic (&Symbolic, Common) ; + Common->status = KLU_OUT_OF_MEMORY ; + return (NULL) ; + } + + /* ------------------------------------------------------------------ */ + /* B = Puser * A */ + /* ------------------------------------------------------------------ */ + + if (Puser != (Int *) NULL) + { + for (k = 0 ; k < n ; k++) + { + Pinv [Puser [k]] = k ; + } + for (p = 0 ; p < nz ; p++) + { + Bi [p] = Pinv [Ai [p]] ; + } + } + + /* ------------------------------------------------------------------ */ + /* find the strongly-connected components */ + /* ------------------------------------------------------------------ */ + + /* modifies Q, and determines P and R */ + nblocks = BTF_strongcomp (n, Ap, Bi, Q, P, R, Work) ; + + /* ------------------------------------------------------------------ */ + /* P = P * Puser */ + /* ------------------------------------------------------------------ */ + + if (Puser != (Int *) NULL) + { + for (k = 0 ; k < n ; k++) + { + Work [k] = Puser [P [k]] ; + } + for (k = 0 ; k < n ; k++) + { + P [k] = Work [k] ; + } + } + + /* ------------------------------------------------------------------ */ + /* Pinv = inverse of P */ + /* ------------------------------------------------------------------ */ + + for (k = 0 ; k < n ; k++) + { + Pinv [P [k]] = k ; + } + + /* ------------------------------------------------------------------ */ + /* analyze each block */ + /* ------------------------------------------------------------------ */ + + nzoff = 0 ; /* nz in off-diagonal part */ + maxblock = 1 ; /* size of the largest block */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* -------------------------------------------------------------- */ + /* the block is from rows/columns k1 to k2-1 */ + /* -------------------------------------------------------------- */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("BLOCK %d, k1 %d k2-1 %d nk %d\n", block, k1, k2-1, nk)) ; + maxblock = MAX (maxblock, nk) ; + + /* -------------------------------------------------------------- */ + /* scan the kth block, C */ + /* -------------------------------------------------------------- */ + + for (k = k1 ; k < k2 ; k++) + { + oldcol = Q [k] ; + pend = Ap [oldcol+1] ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + if (Pinv [Ai [p]] < k1) + { + nzoff++ ; + } + } + } + + /* fill-in not estimated */ + Lnz [block] = EMPTY ; + } + + /* ------------------------------------------------------------------ */ + /* free all workspace */ + /* ------------------------------------------------------------------ */ + + KLU_free (Work, 4*n, sizeof (Int), Common) ; + KLU_free (Pinv, n, sizeof (Int), Common) ; + if (Puser != (Int *) NULL) + { + KLU_free (Bi, nz+1, sizeof (Int), Common) ; + } + + } + else + { + + /* ------------------------------------------------------------------ */ + /* BTF not requested */ + /* ------------------------------------------------------------------ */ + + nzoff = 0 ; + nblocks = 1 ; + maxblock = n ; + R [0] = 0 ; + R [1] = n ; + Lnz [0] = EMPTY ; + + /* ------------------------------------------------------------------ */ + /* P = Puser, or identity if Puser is NULL */ + /* ------------------------------------------------------------------ */ + + for (k = 0 ; k < n ; k++) + { + P [k] = (Puser == NULL) ? k : Puser [k] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* return the symbolic object */ + /* ---------------------------------------------------------------------- */ + + Symbolic->nblocks = nblocks ; + Symbolic->maxblock = maxblock ; + Symbolic->lnz = EMPTY ; + Symbolic->unz = EMPTY ; + Symbolic->nzoff = nzoff ; + + return (Symbolic) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_defaults.c b/OpenDSSC/klusolve/KLU/Source/klu_defaults.c new file mode 100644 index 0000000..8f4ce6d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_defaults.c @@ -0,0 +1,60 @@ +/* ========================================================================== */ +/* === KLU_defaults ========================================================= */ +/* ========================================================================== */ + +/* Sets default parameters for KLU */ + +#include "klu_internal.h" + +Int KLU_defaults +( + KLU_common *Common +) +{ + if (Common == NULL) + { + return (FALSE) ; + } + + /* parameters */ + Common->tol = 0.001 ; /* pivot tolerance for diagonal */ + Common->memgrow = 1.2; /* realloc size ratio increase for LU factors */ + Common->initmem_amd = 1.2 ; /* init. mem with AMD: c*nnz(L) + n */ + Common->initmem = 10 ; /* init. mem otherwise: c*nnz(A) + n */ + Common->btf = TRUE ; /* use BTF pre-ordering, or not */ + Common->maxwork = 0 ; /* no limit to work done by btf_order */ + Common->ordering = 0 ; /* 0: AMD, 1: COLAMD, 2: user-provided P and Q, + * 3: user-provided function */ + Common->scale = 2 ; /* scale: -1: none, and do not check for errors + * in the input matrix in KLU_refactor. + * 0: none, but check for errors, + * 1: sum, 2: max */ + Common->halt_if_singular = TRUE ; /* quick halt if matrix is singular */ + + /* memory management routines */ + Common->malloc_memory = malloc ; + Common->calloc_memory = calloc ; + Common->free_memory = free ; + Common->realloc_memory = realloc ; + + /* user ordering function and optional argument */ + Common->user_order = NULL ; + Common->user_data = NULL ; + + /* statistics */ + Common->status = KLU_OK ; + Common->nrealloc = 0 ; + Common->structural_rank = EMPTY ; + Common->numerical_rank = EMPTY ; + Common->noffdiag = EMPTY ; + Common->flops = EMPTY ; + Common->rcond = EMPTY ; + Common->condest = EMPTY ; + Common->rgrowth = EMPTY ; + Common->work = 0 ; /* work done by btf_order */ + + Common->memusage = 0 ; + Common->mempeak = 0 ; + + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_diagnostics.c b/OpenDSSC/klusolve/KLU/Source/klu_diagnostics.c new file mode 100644 index 0000000..a65442f --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_diagnostics.c @@ -0,0 +1,570 @@ +/* ========================================================================== */ +/* === KLU_diagnostics ====================================================== */ +/* ========================================================================== */ + +/* Linear algebraic diagnostics: + * KLU_rgrowth: reciprocal pivot growth, takes O(|A|+|U|) time + * KLU_condest: condition number estimator, takes about O(|A|+5*(|L|+|U|)) time + * KLU_flops: compute # flops required to factorize A into L*U + * KLU_rcond: compute a really cheap estimate of the reciprocal of the + * condition number, min(abs(diag(U))) / max(abs(diag(U))). + * Takes O(n) time. + */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === KLU_rgrowth ========================================================== */ +/* ========================================================================== */ + +/* Compute the reciprocal pivot growth factor. In MATLAB notation: + * + * rgrowth = min (max (abs ((R \ A (p,q)) - F))) ./ max (abs (U))) + */ + +Int KLU_rgrowth /* return TRUE if successful, FALSE otherwise */ +( + Int *Ap, + Int *Ai, + double *Ax, + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + KLU_common *Common +) +{ + double temp, max_ai, max_ui, min_block_rgrowth ; + Entry aik ; + Int *Q, *Ui, *Uip, *Ulen, *Pinv ; + Unit *LU ; + Entry *Aentry, *Ux, *Ukk ; + double *Rs ; + Int i, newrow, oldrow, k1, k2, nk, j, oldcol, k, pend, len ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + + if (Symbolic == NULL || Ap == NULL || Ai == NULL || Ax == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + + if (Numeric == NULL) + { + /* treat this as a singular matrix */ + Common->rgrowth = 0 ; + Common->status = KLU_SINGULAR ; + return (TRUE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* compute the reciprocal pivot growth */ + /* ---------------------------------------------------------------------- */ + + Aentry = (Entry *) Ax ; + Pinv = Numeric->Pinv ; + Rs = Numeric->Rs ; + Q = Symbolic->Q ; + Common->rgrowth = 1 ; + + for (i = 0 ; i < Symbolic->nblocks ; i++) + { + k1 = Symbolic->R[i] ; + k2 = Symbolic->R[i+1] ; + nk = k2 - k1 ; + if (nk == 1) + { + continue ; /* skip singleton blocks */ + } + LU = (Unit *) Numeric->LUbx[i] ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + Ukk = ((Entry *) Numeric->Udiag) + k1 ; + min_block_rgrowth = 1 ; + for (j = 0 ; j < nk ; j++) + { + max_ai = 0 ; + max_ui = 0 ; + oldcol = Q[j + k1] ; + pend = Ap [oldcol + 1] ; + for (k = Ap [oldcol] ; k < pend ; k++) + { + oldrow = Ai [k] ; + newrow = Pinv [oldrow] ; + if (newrow < k1) + { + continue ; /* skip entry outside the block */ + } + ASSERT (newrow < k2) ; + if (Rs != NULL) + { + /* aik = Aentry [k] / Rs [oldrow] */ + SCALE_DIV_ASSIGN (aik, Aentry [k], Rs [newrow]) ; + } + else + { + aik = Aentry [k] ; + } + /* temp = ABS (aik) */ + ABS (temp, aik) ; + if (temp > max_ai) + { + max_ai = temp ; + } + } + + GET_POINTER (LU, Uip, Ulen, Ui, Ux, j, len) ; + for (k = 0 ; k < len ; k++) + { + /* temp = ABS (Ux [k]) */ + ABS (temp, Ux [k]) ; + if (temp > max_ui) + { + max_ui = temp ; + } + } + /* consider the diagonal element */ + ABS (temp, Ukk [j]) ; + if (temp > max_ui) + { + max_ui = temp ; + } + + /* if max_ui is 0, skip the column */ + if (SCALAR_IS_ZERO (max_ui)) + { + continue ; + } + temp = max_ai / max_ui ; + if (temp < min_block_rgrowth) + { + min_block_rgrowth = temp ; + } + } + + if (min_block_rgrowth < Common->rgrowth) + { + Common->rgrowth = min_block_rgrowth ; + } + } + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === KLU_condest ========================================================== */ +/* ========================================================================== */ + +/* Estimate the condition number. Uses Higham and Tisseur's algorithm + * (A block algorithm for matrix 1-norm estimation, with applications to + * 1-norm pseudospectra, SIAM J. Matrix Anal. Appl., 21(4):1185-1201, 2000. + */ + +Int KLU_condest /* return TRUE if successful, FALSE otherwise */ +( + Int Ap [ ], + double Ax [ ], + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + KLU_common *Common +) +{ + double xj, Xmax, csum, anorm, ainv_norm, est_old, est_new, abs_value ; + Entry *Udiag, *Aentry, *X, *S ; + Int *R ; + Int nblocks, i, j, jmax, jnew, pend, n ; +#ifndef COMPLEX + Int unchanged ; +#endif + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + if (Symbolic == NULL || Ap == NULL || Ax == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + abs_value = 0 ; + if (Numeric == NULL) + { + /* treat this as a singular matrix */ + Common->condest = 1 / abs_value ; + Common->status = KLU_SINGULAR ; + return (TRUE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* get inputs */ + /* ---------------------------------------------------------------------- */ + + n = Symbolic->n ; + nblocks = Symbolic->nblocks ; + R = Symbolic->R ; + Udiag = Numeric->Udiag ; + + /* ---------------------------------------------------------------------- */ + /* check if diagonal of U has a zero on it */ + /* ---------------------------------------------------------------------- */ + + for (i = 0 ; i < n ; i++) + { + ABS (abs_value, Udiag [i]) ; + if (SCALAR_IS_ZERO (abs_value)) + { + Common->condest = 1 / abs_value ; + Common->status = KLU_SINGULAR ; + return (TRUE) ; + } + } + + /* ---------------------------------------------------------------------- */ + /* compute 1-norm (maximum column sum) of the matrix */ + /* ---------------------------------------------------------------------- */ + + anorm = 0.0 ; + Aentry = (Entry *) Ax ; + for (i = 0 ; i < n ; i++) + { + pend = Ap [i + 1] ; + csum = 0.0 ; + for (j = Ap [i] ; j < pend ; j++) + { + ABS (abs_value, Aentry [j]) ; + csum += abs_value ; + } + if (csum > anorm) + { + anorm = csum ; + } + } + + /* ---------------------------------------------------------------------- */ + /* compute estimate of 1-norm of inv (A) */ + /* ---------------------------------------------------------------------- */ + + /* get workspace (size 2*n Entry's) */ + X = Numeric->Xwork ; /* size n space used in KLU_solve, tsolve */ + X += n ; /* X is size n */ + S = X + n ; /* S is size n */ + + for (i = 0 ; i < n ; i++) + { + CLEAR (S [i]) ; + CLEAR (X [i]) ; + REAL (X [i]) = 1.0 / ((double) n) ; + } + jmax = 0 ; + + ainv_norm = 0.0 ; + for (i = 0 ; i < 5 ; i++) + { + if (i > 0) + { + /* X [jmax] is the largest entry in X */ + for (j = 0 ; j < n ; j++) + { + /* X [j] = 0 ;*/ + CLEAR (X [j]) ; + } + REAL (X [jmax]) = 1 ; + } + + KLU_solve (Symbolic, Numeric, n, 1, (double *) X, Common) ; + est_old = ainv_norm ; + ainv_norm = 0.0 ; + + for (j = 0 ; j < n ; j++) + { + /* ainv_norm += ABS (X [j]) ;*/ + ABS (abs_value, X [j]) ; + ainv_norm += abs_value ; + } + +#ifndef COMPLEX + unchanged = TRUE ; + + for (j = 0 ; j < n ; j++) + { + double s = (X [j] >= 0) ? 1 : -1 ; + if (s != (Int) REAL (S [j])) + { + S [j] = s ; + unchanged = FALSE ; + } + } + + if (i > 0 && (ainv_norm <= est_old || unchanged)) + { + break ; + } +#else + for (j = 0 ; j < n ; j++) + { + if (IS_NONZERO (X [j])) + { + ABS (abs_value, X [j]) ; + SCALE_DIV_ASSIGN (S [j], X [j], abs_value) ; + } + else + { + CLEAR (S [j]) ; + REAL (S [j]) = 1 ; + } + } + + if (i > 0 && ainv_norm <= est_old) + { + break ; + } +#endif + + for (j = 0 ; j < n ; j++) + { + X [j] = S [j] ; + } + +#ifndef COMPLEX + /* do a transpose solve */ + KLU_tsolve (Symbolic, Numeric, n, 1, X, Common) ; +#else + /* do a conjugate transpose solve */ + KLU_tsolve (Symbolic, Numeric, n, 1, (double *) X, 1, Common) ; +#endif + + /* jnew = the position of the largest entry in X */ + jnew = 0 ; + Xmax = 0 ; + for (j = 0 ; j < n ; j++) + { + /* xj = ABS (X [j]) ;*/ + ABS (xj, X [j]) ; + if (xj > Xmax) + { + Xmax = xj ; + jnew = j ; + } + } + if (i > 0 && jnew == jmax) + { + /* the position of the largest entry did not change + * from the previous iteration */ + break ; + } + jmax = jnew ; + } + + /* ---------------------------------------------------------------------- */ + /* compute another estimate of norm(inv(A),1), and take the largest one */ + /* ---------------------------------------------------------------------- */ + + for (j = 0 ; j < n ; j++) + { + CLEAR (X [j]) ; + if (j % 2) + { + REAL (X [j]) = 1 + ((double) j) / ((double) (n-1)) ; + } + else + { + REAL (X [j]) = -1 - ((double) j) / ((double) (n-1)) ; + } + } + + KLU_solve (Symbolic, Numeric, n, 1, (double *) X, Common) ; + + est_new = 0.0 ; + for (j = 0 ; j < n ; j++) + { + /* est_new += ABS (X [j]) ;*/ + ABS (abs_value, X [j]) ; + est_new += abs_value ; + } + est_new = 2 * est_new / (3 * n) ; + ainv_norm = MAX (est_new, ainv_norm) ; + + /* ---------------------------------------------------------------------- */ + /* compute estimate of condition number */ + /* ---------------------------------------------------------------------- */ + + Common->condest = ainv_norm * anorm ; + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === KLU_flops ============================================================ */ +/* ========================================================================== */ + +/* Compute the flop count for the LU factorization (in Common->flops) */ + +Int KLU_flops /* return TRUE if successful, FALSE otherwise */ +( + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + KLU_common *Common +) +{ + double flops = 0 ; + Int *R, *Ui, *Uip, *Llen, *Ulen ; + Unit **LUbx ; + Unit *LU ; + Int k, ulen, p, n, nk, block, nblocks, k1 ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + Common->flops = EMPTY ; + if (Numeric == NULL || Symbolic == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + n = Symbolic->n ; + R = Symbolic->R ; + nblocks = Symbolic->nblocks ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Numeric object */ + /* ---------------------------------------------------------------------- */ + + LUbx = (Unit **) Numeric->LUbx ; + + /* ---------------------------------------------------------------------- */ + /* compute the flop count */ + /* ---------------------------------------------------------------------- */ + + for (block = 0 ; block < nblocks ; block++) + { + k1 = R [block] ; + nk = R [block+1] - k1 ; + if (nk > 1) + { + Llen = Numeric->Llen + k1 ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + LU = LUbx [block] ; + for (k = 0 ; k < nk ; k++) + { + /* compute kth column of U, and update kth column of A */ + GET_I_POINTER (LU, Uip, Ui, k) ; + ulen = Ulen [k] ; + for (p = 0 ; p < ulen ; p++) + { + flops += 2 * Llen [Ui [p]] ; + } + /* gather and divide by pivot to get kth column of L */ + flops += Llen [k] ; + } + } + } + Common->flops = flops ; + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === KLU_rcond ============================================================ */ +/* ========================================================================== */ + +/* Compute a really cheap estimate of the reciprocal of the condition number, + * condition number, min(abs(diag(U))) / max(abs(diag(U))). If U has a zero + * pivot, or a NaN pivot, rcond will be zero. Takes O(n) time. + */ + +Int KLU_rcond /* return TRUE if successful, FALSE otherwise */ +( + KLU_symbolic *Symbolic, /* input, not modified */ + KLU_numeric *Numeric, /* input, not modified */ + KLU_common *Common /* result in Common->rcond */ +) +{ + double ukk, umin = 0, umax = 0 ; + Entry *Udiag ; + Int j, n ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + if (Symbolic == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + if (Numeric == NULL) + { + Common->rcond = 0 ; + Common->status = KLU_SINGULAR ; + return (TRUE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* compute rcond */ + /* ---------------------------------------------------------------------- */ + + n = Symbolic->n ; + Udiag = Numeric->Udiag ; + for (j = 0 ; j < n ; j++) + { + /* get the magnitude of the pivot */ + ABS (ukk, Udiag [j]) ; + if (SCALAR_IS_NAN (ukk) || SCALAR_IS_ZERO (ukk)) + { + /* if NaN, or zero, the rcond is zero */ + Common->rcond = 0 ; + Common->status = KLU_SINGULAR ; + return (TRUE) ; + } + if (j == 0) + { + /* first pivot entry */ + umin = ukk ; + umax = ukk ; + } + else + { + /* subsequent pivots */ + umin = MIN (umin, ukk) ; + umax = MAX (umax, ukk) ; + } + } + + Common->rcond = umin / umax ; + if (SCALAR_IS_NAN (Common->rcond) || SCALAR_IS_ZERO (Common->rcond)) + { + /* this can occur if umin or umax are Inf or NaN */ + Common->rcond = 0 ; + Common->status = KLU_SINGULAR ; + } + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_dump.c b/OpenDSSC/klusolve/KLU/Source/klu_dump.c new file mode 100644 index 0000000..b625fda --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_dump.c @@ -0,0 +1,142 @@ +/* ========================================================================== */ +/* === KLU_dump ============================================================= */ +/* ========================================================================== */ + +/* Debug routines for klu. Only used when NDEBUG is not defined at + * compile-time. + */ + +#include "klu_internal.h" + +#ifndef NDEBUG + +/* ========================================================================== */ +/* === KLU_valid ============================================================ */ +/* ========================================================================== */ + +/* Check if a column-form matrix is valid or not. The matrix A is + * n-by-n. The row indices of entries in column j are in + * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are: + * + * n >= 0 + * nz = Ap [n_col] >= 0 number of entries in the matrix + * Ap [0] == 0 + * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col. + * row indices in Ai [Ap [j] ... Ap [j+1]-1] + * must be in the range 0 to n_row-1, + * and no duplicate entries can exist (duplicates not checked here). + * + * Not user-callable. Only used when debugging. + */ + +Int KLU_valid (Int n, Int Ap [ ], Int Ai [ ], Entry Ax [ ]) +{ + Int nz, j, p1, p2, i, p ; + PRINTF (("\ncolumn oriented matrix, n = %d\n", n)) ; + if (n <= 0) + { + PRINTF (("n must be >= 0: %d\n", n)) ; + return (FALSE) ; + } + nz = Ap [n] ; + if (Ap [0] != 0 || nz < 0) + { + /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */ + PRINTF (("column 0 pointer bad or nz < 0\n")) ; + return (FALSE) ; + } + for (j = 0 ; j < n ; j++) + { + p1 = Ap [j] ; + p2 = Ap [j+1] ; + PRINTF (("\nColumn: %d p1: %d p2: %d\n", j, p1, p2)) ; + if (p1 > p2) + { + /* column pointers must be ascending */ + PRINTF (("column %d pointer bad\n", j)) ; + return (FALSE) ; + } + for (p = p1 ; p < p2 ; p++) + { + i = Ai [p] ; + PRINTF (("row: %d", i)) ; + if (i < 0 || i >= n) + { + /* row index out of range */ + PRINTF (("index out of range, col %d row %d\n", j, i)) ; + return (FALSE) ; + } + if (Ax != (Entry *) NULL) + { + PRINT_ENTRY (Ax [p]) ; + } + PRINTF (("\n")) ; + } + } + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === KLU_valid_LU ========================================================= */ +/* ========================================================================== */ + +/* This function does the same validity tests as KLU_valid but for the + * LU factor storage format. The flag flag_test_start_ptr is used to + * test if Xip [0] = 0. This is not applicable for U. So when calling this + * function for U, the flag should be set to false. Only used when debugging. + */ + +Int KLU_valid_LU (Int n, Int flag_test_start_ptr, Int Xip [ ], + Int Xlen [ ], Unit LU [ ]) +{ + Int *Xi ; + Entry *Xx ; + Int j, p1, p2, i, p, len ; + + PRINTF (("\ncolumn oriented matrix, n = %d\n", n)) ; + if (n <= 0) + { + PRINTF (("n must be >= 0: %d\n", n)) ; + return (FALSE) ; + } + if (flag_test_start_ptr && Xip [0] != 0) + { + /* column pointers must start at Xip [0] = 0*/ + PRINTF (("column 0 pointer bad\n")) ; + return (FALSE) ; + } + + for (j = 0 ; j < n ; j++) + { + p1 = Xip [j] ; + p2 = Xip [j+1] ; + PRINTF (("\nColumn: %d p1: %d p2: %d\n", j, p1, p2)) ; + if (p1 > p2) + { + /* column pointers must be ascending */ + PRINTF (("column %d pointer bad\n", j)) ; + return (FALSE) ; + } + GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ; + for (p = 0 ; p < len ; p++) + { + i = Xi [p] ; + PRINTF (("row: %d", i)) ; + if (i < 0 || i >= n) + { + /* row index out of range */ + PRINTF (("index out of range, col %d row %d\n", j, i)) ; + return (FALSE) ; + } + if (Xx != (Entry *) NULL) + { + PRINT_ENTRY (Xx [p]) ; + } + PRINTF (("\n")) ; + } + } + + return (TRUE) ; +} +#endif diff --git a/OpenDSSC/klusolve/KLU/Source/klu_extract.c b/OpenDSSC/klusolve/KLU/Source/klu_extract.c new file mode 100644 index 0000000..5a44aa0 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_extract.c @@ -0,0 +1,290 @@ +/* ========================================================================== */ +/* === KLU_extract ========================================================== */ +/* ========================================================================== */ + +/* Extract KLU factorization into conventional compressed-column matrices. + * If any output array is NULL, that part of the LU factorization is not + * extracted (this is not an error condition). + * + * nnz(L) = Numeric->lnz, nnz(U) = Numeric->unz, and nnz(F) = Numeric->Offp [n] + */ + +#include "klu_internal.h" + +Int KLU_extract /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs: */ + KLU_numeric *Numeric, + KLU_symbolic *Symbolic, + + /* outputs, all of which must be allocated on input */ + + /* L */ + Int *Lp, /* size n+1 */ + Int *Li, /* size nnz(L) */ + double *Lx, /* size nnz(L) */ +#ifdef COMPLEX + double *Lz, /* size nnz(L) for the complex case, ignored if real */ +#endif + + /* U */ + Int *Up, /* size n+1 */ + Int *Ui, /* size nnz(U) */ + double *Ux, /* size nnz(U) */ +#ifdef COMPLEX + double *Uz, /* size nnz(U) for the complex case, ignored if real */ +#endif + + /* F */ + Int *Fp, /* size n+1 */ + Int *Fi, /* size nnz(F) */ + double *Fx, /* size nnz(F) */ +#ifdef COMPLEX + double *Fz, /* size nnz(F) for the complex case, ignored if real */ +#endif + + /* P, row permutation */ + Int *P, /* size n */ + + /* Q, column permutation */ + Int *Q, /* size n */ + + /* Rs, scale factors */ + double *Rs, /* size n */ + + /* R, block boundaries */ + Int *R, /* size nblocks+1 */ + + KLU_common *Common +) +{ + Int *Lip, *Llen, *Uip, *Ulen, *Li2, *Ui2 ; + Unit *LU ; + Entry *Lx2, *Ux2, *Ukk ; + Int i, k, block, nblocks, n, nz, k1, k2, nk, len, kk, p ; + + if (Common == NULL) + { + return (FALSE) ; + } + + if (Symbolic == NULL || Numeric == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + + Common->status = KLU_OK ; + n = Symbolic->n ; + nblocks = Symbolic->nblocks ; + + /* ---------------------------------------------------------------------- */ + /* extract scale factors */ + /* ---------------------------------------------------------------------- */ + + if (Rs != NULL) + { + if (Numeric->Rs != NULL) + { + for (i = 0 ; i < n ; i++) + { + Rs [i] = Numeric->Rs [i] ; + } + } + else + { + /* no scaling */ + for (i = 0 ; i < n ; i++) + { + Rs [i] = 1 ; + } + } + } + + /* ---------------------------------------------------------------------- */ + /* extract block boundaries */ + /* ---------------------------------------------------------------------- */ + + if (R != NULL) + { + for (block = 0 ; block <= nblocks ; block++) + { + R [block] = Symbolic->R [block] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* extract final row permutation */ + /* ---------------------------------------------------------------------- */ + + if (P != NULL) + { + for (k = 0 ; k < n ; k++) + { + P [k] = Numeric->Pnum [k] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* extract column permutation */ + /* ---------------------------------------------------------------------- */ + + if (Q != NULL) + { + for (k = 0 ; k < n ; k++) + { + Q [k] = Symbolic->Q [k] ; + } + } + + /* ---------------------------------------------------------------------- */ + /* extract each block of L */ + /* ---------------------------------------------------------------------- */ + + if (Lp != NULL && Li != NULL && Lx != NULL +#ifdef COMPLEX + && Lz != NULL +#endif + ) + { + nz = 0 ; + for (block = 0 ; block < nblocks ; block++) + { + k1 = Symbolic->R [block] ; + k2 = Symbolic->R [block+1] ; + nk = k2 - k1 ; + if (nk == 1) + { + /* singleton block */ + Lp [k1] = nz ; + Li [nz] = k1 ; + Lx [nz] = 1 ; +#ifdef COMPLEX + Lz [nz] = 0 ; +#endif + nz++ ; + } + else + { + /* non-singleton block */ + LU = Numeric->LUbx [block] ; + Lip = Numeric->Lip + k1 ; + Llen = Numeric->Llen + k1 ; + for (kk = 0 ; kk < nk ; kk++) + { + Lp [k1+kk] = nz ; + /* add the unit diagonal entry */ + Li [nz] = k1 + kk ; + Lx [nz] = 1 ; +#ifdef COMPLEX + Lz [nz] = 0 ; +#endif + nz++ ; + GET_POINTER (LU, Lip, Llen, Li2, Lx2, kk, len) ; + for (p = 0 ; p < len ; p++) + { + Li [nz] = k1 + Li2 [p] ; + Lx [nz] = REAL (Lx2 [p]) ; +#ifdef COMPLEX + Lz [nz] = IMAG (Lx2 [p]) ; +#endif + nz++ ; + } + } + } + } + Lp [n] = nz ; + ASSERT (nz == Numeric->lnz) ; + } + + /* ---------------------------------------------------------------------- */ + /* extract each block of U */ + /* ---------------------------------------------------------------------- */ + + if (Up != NULL && Ui != NULL && Ux != NULL +#ifdef COMPLEX + && Uz != NULL +#endif + ) + { + nz = 0 ; + for (block = 0 ; block < nblocks ; block++) + { + k1 = Symbolic->R [block] ; + k2 = Symbolic->R [block+1] ; + nk = k2 - k1 ; + Ukk = ((Entry *) Numeric->Udiag) + k1 ; + if (nk == 1) + { + /* singleton block */ + Up [k1] = nz ; + Ui [nz] = k1 ; + Ux [nz] = REAL (Ukk [0]) ; +#ifdef COMPLEX + Uz [nz] = IMAG (Ukk [0]) ; +#endif + nz++ ; + } + else + { + /* non-singleton block */ + LU = Numeric->LUbx [block] ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + for (kk = 0 ; kk < nk ; kk++) + { + Up [k1+kk] = nz ; + GET_POINTER (LU, Uip, Ulen, Ui2, Ux2, kk, len) ; + for (p = 0 ; p < len ; p++) + { + Ui [nz] = k1 + Ui2 [p] ; + Ux [nz] = REAL (Ux2 [p]) ; +#ifdef COMPLEX + Uz [nz] = IMAG (Ux2 [p]) ; +#endif + nz++ ; + } + /* add the diagonal entry */ + Ui [nz] = k1 + kk ; + Ux [nz] = REAL (Ukk [kk]) ; +#ifdef COMPLEX + Uz [nz] = IMAG (Ukk [kk]) ; +#endif + nz++ ; + } + } + } + Up [n] = nz ; + ASSERT (nz == Numeric->unz) ; + } + + /* ---------------------------------------------------------------------- */ + /* extract the off-diagonal blocks, F */ + /* ---------------------------------------------------------------------- */ + + if (Fp != NULL && Fi != NULL && Fx != NULL +#ifdef COMPLEX + && Fz != NULL +#endif + ) + { + for (k = 0 ; k <= n ; k++) + { + Fp [k] = Numeric->Offp [k] ; + } + nz = Fp [n] ; + for (k = 0 ; k < nz ; k++) + { + Fi [k] = Numeric->Offi [k] ; + } + for (k = 0 ; k < nz ; k++) + { + Fx [k] = REAL (((Entry *) Numeric->Offx) [k]) ; +#ifdef COMPLEX + Fz [k] = IMAG (((Entry *) Numeric->Offx) [k]) ; +#endif + } + } + + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_factor.c b/OpenDSSC/klusolve/KLU/Source/klu_factor.c new file mode 100644 index 0000000..84af42c --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_factor.c @@ -0,0 +1,545 @@ +/* ========================================================================== */ +/* === KLU_factor =========================================================== */ +/* ========================================================================== */ + +/* Factor the matrix, after ordering and analyzing it with KLU_analyze + * or KLU_analyze_given. + */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === KLU_factor2 ========================================================== */ +/* ========================================================================== */ + +static void factor2 +( + /* inputs, not modified */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + Entry Ax [ ], + KLU_symbolic *Symbolic, + + /* inputs, modified on output: */ + KLU_numeric *Numeric, + KLU_common *Common +) +{ + double lsize ; + double *Lnz, *Rs ; + Int *P, *Q, *R, *Pnum, *Offp, *Offi, *Pblock, *Pinv, *Iwork, + *Lip, *Uip, *Llen, *Ulen ; + Entry *Offx, *X, s, *Udiag ; + Unit **LUbx ; + Int k1, k2, nk, k, block, oldcol, pend, oldrow, n, lnz, unz, p, newrow, + nblocks, poff, nzoff, lnz_block, unz_block, scale, max_lnz_block, + max_unz_block ; + + /* ---------------------------------------------------------------------- */ + /* initializations */ + /* ---------------------------------------------------------------------- */ + + /* get the contents of the Symbolic object */ + n = Symbolic->n ; + P = Symbolic->P ; + Q = Symbolic->Q ; + R = Symbolic->R ; + Lnz = Symbolic->Lnz ; + nblocks = Symbolic->nblocks ; + nzoff = Symbolic->nzoff ; + + Pnum = Numeric->Pnum ; + Offp = Numeric->Offp ; + Offi = Numeric->Offi ; + Offx = (Entry *) Numeric->Offx ; + + Lip = Numeric->Lip ; + Uip = Numeric->Uip ; + Llen = Numeric->Llen ; + Ulen = Numeric->Ulen ; + LUbx = (Unit **) Numeric->LUbx ; + Udiag = Numeric->Udiag ; + + Rs = Numeric->Rs ; + Pinv = Numeric->Pinv ; + X = (Entry *) Numeric->Xwork ; /* X is of size n */ + Iwork = Numeric->Iwork ; /* 5*maxblock for KLU_factor */ + /* 1*maxblock for Pblock */ + Pblock = Iwork + 5*((size_t) Symbolic->maxblock) ; + Common->nrealloc = 0 ; + scale = Common->scale ; + max_lnz_block = 1 ; + max_unz_block = 1 ; + + /* compute the inverse of P from symbolic analysis. Will be updated to + * become the inverse of the numerical factorization when the factorization + * is done, for use in KLU_refactor */ +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + Pinv [k] = EMPTY ; + } +#endif + for (k = 0 ; k < n ; k++) + { + ASSERT (P [k] >= 0 && P [k] < n) ; + Pinv [P [k]] = k ; + } +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) ASSERT (Pinv [k] != EMPTY) ; +#endif + + lnz = 0 ; + unz = 0 ; + Common->noffdiag = 0 ; + Offp [0] = 0 ; + + /* ---------------------------------------------------------------------- */ + /* optionally check input matrix and compute scale factors */ + /* ---------------------------------------------------------------------- */ + + if (scale >= 0) + { + /* use Pnum as workspace. NOTE: scale factors are not yet permuted + * according to the final pivot row ordering, so Rs [oldrow] is the + * scale factor for A (oldrow,:), for the user's matrix A. Pnum is + * used as workspace in KLU_scale. When the factorization is done, + * the scale factors are permuted according to the final pivot row + * permutation, so that Rs [k] is the scale factor for the kth row of + * A(p,q) where p and q are the final row and column permutations. */ + KLU_scale (scale, n, Ap, Ai, (double *) Ax, Rs, Pnum, Common) ; + if (Common->status < KLU_OK) + { + /* matrix is invalid */ + return ; + } + } + +#ifndef NDEBUG + if (scale > 0) + { + for (k = 0 ; k < n ; k++) PRINTF (("Rs [%d] %g\n", k, Rs [k])) ; + } +#endif + + /* ---------------------------------------------------------------------- */ + /* factor each block using klu */ + /* ---------------------------------------------------------------------- */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* ------------------------------------------------------------------ */ + /* the block is from rows/columns k1 to k2-1 */ + /* ------------------------------------------------------------------ */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("FACTOR BLOCK %d, k1 %d k2-1 %d nk %d\n", block, k1,k2-1,nk)) ; + + if (nk == 1) + { + + /* -------------------------------------------------------------- */ + /* singleton case */ + /* -------------------------------------------------------------- */ + + poff = Offp [k1] ; + oldcol = Q [k1] ; + pend = Ap [oldcol+1] ; + CLEAR (s) ; + + if (scale <= 0) + { + /* no scaling */ + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + newrow = Pinv [oldrow] ; + if (newrow < k1) + { + Offi [poff] = oldrow ; + Offx [poff] = Ax [p] ; + poff++ ; + } + else + { + ASSERT (newrow == k1) ; + PRINTF (("singleton block %d", block)) ; + PRINT_ENTRY (Ax [p]) ; + s = Ax [p] ; + } + } + } + else + { + /* row scaling. NOTE: scale factors are not yet permuted + * according to the pivot row permutation, so Rs [oldrow] is + * used below. When the factorization is done, the scale + * factors are permuted, so that Rs [newrow] will be used in + * klu_solve, klu_tsolve, and klu_rgrowth */ + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + newrow = Pinv [oldrow] ; + if (newrow < k1) + { + Offi [poff] = oldrow ; + /* Offx [poff] = Ax [p] / Rs [oldrow] ; */ + SCALE_DIV_ASSIGN (Offx [poff], Ax [p], Rs [oldrow]) ; + poff++ ; + } + else + { + ASSERT (newrow == k1) ; + PRINTF (("singleton block %d ", block)) ; + PRINT_ENTRY (Ax[p]) ; + SCALE_DIV_ASSIGN (s, Ax [p], Rs [oldrow]) ; + } + } + } + + Udiag [k1] = s ; + + if (IS_ZERO (s)) + { + /* singular singleton */ + Common->status = KLU_SINGULAR ; + Common->numerical_rank = k1 ; + Common->singular_col = oldcol ; + if (Common->halt_if_singular) + { + return ; + } + } + + Offp [k1+1] = poff ; + Pnum [k1] = P [k1] ; + lnz++ ; + unz++ ; + + } + else + { + + /* -------------------------------------------------------------- */ + /* construct and factorize the kth block */ + /* -------------------------------------------------------------- */ + + if (Lnz [block] < 0) + { + /* COLAMD was used - no estimate of fill-in */ + /* use 10 times the nnz in A, plus n */ + lsize = -(Common->initmem) ; + } + else + { + lsize = Common->initmem_amd * Lnz [block] + nk ; + } + + /* allocates 1 arrays: LUbx [block] */ + Numeric->LUsize [block] = KLU_kernel_factor (nk, Ap, Ai, Ax, Q, + lsize, &LUbx [block], Udiag + k1, Llen + k1, Ulen + k1, + Lip + k1, Uip + k1, Pblock, &lnz_block, &unz_block, + X, Iwork, k1, Pinv, Rs, Offp, Offi, Offx, Common) ; + + if (Common->status < KLU_OK || + (Common->status == KLU_SINGULAR && Common->halt_if_singular)) + { + /* out of memory, invalid inputs, or singular */ + return ; + } + + PRINTF (("\n----------------------- L %d:\n", block)) ; + ASSERT (KLU_valid_LU (nk, TRUE, Lip+k1, Llen+k1, LUbx [block])) ; + PRINTF (("\n----------------------- U %d:\n", block)) ; + ASSERT (KLU_valid_LU (nk, FALSE, Uip+k1, Ulen+k1, LUbx [block])) ; + + /* -------------------------------------------------------------- */ + /* get statistics */ + /* -------------------------------------------------------------- */ + + lnz += lnz_block ; + unz += unz_block ; + max_lnz_block = MAX (max_lnz_block, lnz_block) ; + max_unz_block = MAX (max_unz_block, unz_block) ; + + if (Lnz [block] == EMPTY) + { + /* revise estimate for subsequent factorization */ + Lnz [block] = MAX (lnz_block, unz_block) ; + } + + /* -------------------------------------------------------------- */ + /* combine the klu row ordering with the symbolic pre-ordering */ + /* -------------------------------------------------------------- */ + + PRINTF (("Pnum, 1-based:\n")) ; + for (k = 0 ; k < nk ; k++) + { + ASSERT (k + k1 < n) ; + ASSERT (Pblock [k] + k1 < n) ; + Pnum [k + k1] = P [Pblock [k] + k1] ; + PRINTF (("Pnum (%d + %d + 1 = %d) = %d + 1 = %d\n", + k, k1, k+k1+1, Pnum [k+k1], Pnum [k+k1]+1)) ; + } + + /* the local pivot row permutation Pblock is no longer needed */ + } + } + ASSERT (nzoff == Offp [n]) ; + PRINTF (("\n------------------- Off diagonal entries:\n")) ; + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + + Numeric->lnz = lnz ; + Numeric->unz = unz ; + Numeric->max_lnz_block = max_lnz_block ; + Numeric->max_unz_block = max_unz_block ; + + /* compute the inverse of Pnum */ +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + Pinv [k] = EMPTY ; + } +#endif + for (k = 0 ; k < n ; k++) + { + ASSERT (Pnum [k] >= 0 && Pnum [k] < n) ; + Pinv [Pnum [k]] = k ; + } +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) ASSERT (Pinv [k] != EMPTY) ; +#endif + + /* permute scale factors Rs according to pivotal row order */ + if (scale > 0) + { + for (k = 0 ; k < n ; k++) + { + REAL (X [k]) = Rs [Pnum [k]] ; + } + for (k = 0 ; k < n ; k++) + { + Rs [k] = REAL (X [k]) ; + } + } + + PRINTF (("\n------------------- Off diagonal entries, old:\n")) ; + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + + /* apply the pivot row permutations to the off-diagonal entries */ + for (p = 0 ; p < nzoff ; p++) + { + ASSERT (Offi [p] >= 0 && Offi [p] < n) ; + Offi [p] = Pinv [Offi [p]] ; + } + + PRINTF (("\n------------------- Off diagonal entries, new:\n")) ; + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + +#ifndef NDEBUG + { + PRINTF (("\n ############# KLU_BTF_FACTOR done, nblocks %d\n",nblocks)); + Entry ss, *Udiag = Numeric->Udiag ; + for (block = 0 ; block < nblocks && Common->status == KLU_OK ; block++) + { + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("\n======================KLU_factor output: k1 %d k2 %d nk %d\n",k1,k2,nk)) ; + if (nk == 1) + { + PRINTF (("singleton ")) ; + /* ENTRY_PRINT (singleton [block]) ; */ + ss = Udiag [k1] ; + PRINT_ENTRY (ss) ; + } + else + { + Int *Lip, *Uip, *Llen, *Ulen ; + Unit *LU ; + Lip = Numeric->Lip + k1 ; + Llen = Numeric->Llen + k1 ; + LU = (Unit *) Numeric->LUbx [block] ; + PRINTF (("\n---- L block %d\n", block)); + ASSERT (KLU_valid_LU (nk, TRUE, Lip, Llen, LU)) ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + PRINTF (("\n---- U block %d\n", block)) ; + ASSERT (KLU_valid_LU (nk, FALSE, Uip, Ulen, LU)) ; + } + } + } +#endif +} + + + +/* ========================================================================== */ +/* === KLU_factor =========================================================== */ +/* ========================================================================== */ + +KLU_numeric *KLU_factor /* returns NULL if error, or a valid + KLU_numeric object if successful */ +( + /* --- inputs --- */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + double Ax [ ], + KLU_symbolic *Symbolic, + /* -------------- */ + KLU_common *Common +) +{ + Int n, nzoff, nblocks, maxblock, k, ok = TRUE ; + Int *R ; + KLU_numeric *Numeric ; + size_t n1, nzoff1, s, b6, n3 ; + + if (Common == NULL) + { + return (NULL) ; + } + Common->status = KLU_OK ; + Common->numerical_rank = EMPTY ; + Common->singular_col = EMPTY ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + /* check for a valid Symbolic object */ + if (Symbolic == NULL) + { + Common->status = KLU_INVALID ; + return (NULL) ; + } + + n = Symbolic->n ; + nzoff = Symbolic->nzoff ; + nblocks = Symbolic->nblocks ; + maxblock = Symbolic->maxblock ; + R = Symbolic->R ; + PRINTF (("KLU_factor: n %d nzoff %d nblocks %d maxblock %d\n", + n, nzoff, nblocks, maxblock)) ; + + /* ---------------------------------------------------------------------- */ + /* get control parameters and make sure they are in the proper range */ + /* ---------------------------------------------------------------------- */ + + Common->initmem_amd = MAX (1.0, Common->initmem_amd) ; + Common->initmem = MAX (1.0, Common->initmem) ; + Common->tol = MIN (Common->tol, 1.0) ; + Common->tol = MAX (0.0, Common->tol) ; + Common->memgrow = MAX (1.0, Common->memgrow) ; + + /* ---------------------------------------------------------------------- */ + /* allocate the Numeric object */ + /* ---------------------------------------------------------------------- */ + + /* this will not cause size_t overflow (already checked by KLU_symbolic) */ + n1 = ((size_t) n) + 1 ; + nzoff1 = ((size_t) nzoff) + 1 ; + + Numeric = KLU_malloc (sizeof (KLU_numeric), 1, Common) ; + if (Common->status < KLU_OK) + { + /* out of memory */ + Common->status = KLU_OUT_OF_MEMORY ; + return (NULL) ; + } + Numeric->n = n ; + Numeric->nblocks = nblocks ; + Numeric->nzoff = nzoff ; + Numeric->Pnum = KLU_malloc (n, sizeof (Int), Common) ; + Numeric->Offp = KLU_malloc (n1, sizeof (Int), Common) ; + Numeric->Offi = KLU_malloc (nzoff1, sizeof (Int), Common) ; + Numeric->Offx = KLU_malloc (nzoff1, sizeof (Entry), Common) ; + + Numeric->Lip = KLU_malloc (n, sizeof (Int), Common) ; + Numeric->Uip = KLU_malloc (n, sizeof (Int), Common) ; + Numeric->Llen = KLU_malloc (n, sizeof (Int), Common) ; + Numeric->Ulen = KLU_malloc (n, sizeof (Int), Common) ; + + Numeric->LUsize = KLU_malloc (nblocks, sizeof (size_t), Common) ; + + Numeric->LUbx = KLU_malloc (nblocks, sizeof (Unit *), Common) ; + if (Numeric->LUbx != NULL) + { + for (k = 0 ; k < nblocks ; k++) + { + Numeric->LUbx [k] = NULL ; + } + } + + Numeric->Udiag = KLU_malloc (n, sizeof (Entry), Common) ; + + if (Common->scale > 0) + { + Numeric->Rs = KLU_malloc (n, sizeof (double), Common) ; + } + else + { + /* no scaling */ + Numeric->Rs = NULL ; + } + + Numeric->Pinv = KLU_malloc (n, sizeof (Int), Common) ; + + /* allocate permanent workspace for factorization and solve. Note that the + * solver will use an Xwork of size 4n, whereas the factorization codes use + * an Xwork of size n and integer space (Iwork) of size 6n. KLU_condest + * uses an Xwork of size 2n. Total size is: + * + * n*sizeof(Entry) + max (6*maxblock*sizeof(Int), 3*n*sizeof(Entry)) + */ + s = KLU_mult_size_t (n, sizeof (Entry), &ok) ; + n3 = KLU_mult_size_t (n, 3 * sizeof (Entry), &ok) ; + b6 = KLU_mult_size_t (maxblock, 6 * sizeof (Int), &ok) ; + Numeric->worksize = KLU_add_size_t (s, MAX (n3, b6), &ok) ; + Numeric->Work = KLU_malloc (Numeric->worksize, 1, Common) ; + Numeric->Xwork = Numeric->Work ; + Numeric->Iwork = (Int *) ((Entry *) Numeric->Xwork + n) ; + if (!ok || Common->status < KLU_OK) + { + /* out of memory or problem too large */ + Common->status = ok ? KLU_OUT_OF_MEMORY : KLU_TOO_LARGE ; + KLU_free_numeric (&Numeric, Common) ; + return (NULL) ; + } + + /* ---------------------------------------------------------------------- */ + /* factorize the blocks */ + /* ---------------------------------------------------------------------- */ + + factor2 (Ap, Ai, (Entry *) Ax, Symbolic, Numeric, Common) ; + + /* ---------------------------------------------------------------------- */ + /* return or free the Numeric object */ + /* ---------------------------------------------------------------------- */ + + if (Common->status < KLU_OK) + { + /* out of memory or inputs invalid */ + KLU_free_numeric (&Numeric, Common) ; + } + else if (Common->status == KLU_SINGULAR) + { + if (Common->halt_if_singular) + { + /* Matrix is singular, and the Numeric object is only partially + * defined because we halted early. This is the default case for + * a singular matrix. */ + KLU_free_numeric (&Numeric, Common) ; + } + } + else if (Common->status == KLU_OK) + { + /* successful non-singular factorization */ + Common->numerical_rank = n ; + Common->singular_col = n ; + } + return (Numeric) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_free_numeric.c b/OpenDSSC/klusolve/KLU/Source/klu_free_numeric.c new file mode 100644 index 0000000..304da61 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_free_numeric.c @@ -0,0 +1,71 @@ +/* ========================================================================== */ +/* === KLU_free_numeric ===================================================== */ +/* ========================================================================== */ + +/* Free the KLU Numeric object. */ + +#include "klu_internal.h" + +Int KLU_free_numeric +( + KLU_numeric **NumericHandle, + KLU_common *Common +) +{ + KLU_numeric *Numeric ; + Unit **LUbx ; + size_t *LUsize ; + Int block, n, nzoff, nblocks ; + + if (Common == NULL) + { + return (FALSE) ; + } + if (NumericHandle == NULL || *NumericHandle == NULL) + { + return (TRUE) ; + } + + Numeric = *NumericHandle ; + + n = Numeric->n ; + nzoff = Numeric->nzoff ; + nblocks = Numeric->nblocks ; + LUsize = Numeric->LUsize ; + + LUbx = (Unit **) Numeric->LUbx ; + if (LUbx != NULL) + { + for (block = 0 ; block < nblocks ; block++) + { + KLU_free (LUbx [block], LUsize ? LUsize [block] : 0, + sizeof (Unit), Common) ; + } + } + + KLU_free (Numeric->Pnum, n, sizeof (Int), Common) ; + KLU_free (Numeric->Offp, n+1, sizeof (Int), Common) ; + KLU_free (Numeric->Offi, nzoff+1, sizeof (Int), Common) ; + KLU_free (Numeric->Offx, nzoff+1, sizeof (Entry), Common) ; + + KLU_free (Numeric->Lip, n, sizeof (Int), Common) ; + KLU_free (Numeric->Llen, n, sizeof (Int), Common) ; + KLU_free (Numeric->Uip, n, sizeof (Int), Common) ; + KLU_free (Numeric->Ulen, n, sizeof (Int), Common) ; + + KLU_free (Numeric->LUsize, nblocks, sizeof (size_t), Common) ; + + KLU_free (Numeric->LUbx, nblocks, sizeof (Unit *), Common) ; + + KLU_free (Numeric->Udiag, n, sizeof (Entry), Common) ; + + KLU_free (Numeric->Rs, n, sizeof (double), Common) ; + KLU_free (Numeric->Pinv, n, sizeof (Int), Common) ; + + KLU_free (Numeric->Work, Numeric->worksize, 1, Common) ; + + KLU_free (Numeric, 1, sizeof (KLU_numeric), Common) ; + + *NumericHandle = NULL ; + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_free_symbolic.c b/OpenDSSC/klusolve/KLU/Source/klu_free_symbolic.c new file mode 100644 index 0000000..5dad960 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_free_symbolic.c @@ -0,0 +1,34 @@ +/* ========================================================================== */ +/* === KLU_free_symbolic ==================================================== */ +/* ========================================================================== */ + +/* Free the KLU Symbolic object. */ + +#include "klu_internal.h" + +Int KLU_free_symbolic +( + KLU_symbolic **SymbolicHandle, + KLU_common *Common +) +{ + KLU_symbolic *Symbolic ; + Int n ; + if (Common == NULL) + { + return (FALSE) ; + } + if (SymbolicHandle == NULL || *SymbolicHandle == NULL) + { + return (TRUE) ; + } + Symbolic = *SymbolicHandle ; + n = Symbolic->n ; + KLU_free (Symbolic->P, n, sizeof (Int), Common) ; + KLU_free (Symbolic->Q, n, sizeof (Int), Common) ; + KLU_free (Symbolic->R, n+1, sizeof (Int), Common) ; + KLU_free (Symbolic->Lnz, n, sizeof (double), Common) ; + KLU_free (Symbolic, 1, sizeof (KLU_symbolic), Common) ; + *SymbolicHandle = NULL ; + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_kernel.c b/OpenDSSC/klusolve/KLU/Source/klu_kernel.c new file mode 100644 index 0000000..88611ee --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_kernel.c @@ -0,0 +1,1009 @@ +/* ========================================================================== */ +/* === KLU_kernel =========================================================== */ +/* ========================================================================== */ + +/* Sparse left-looking LU factorization, with partial pivoting. Based on + * Gilbert & Peierl's method, with a non-recursive DFS and with Eisenstat & + * Liu's symmetric pruning. No user-callable routines are in this file. + */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === dfs ================================================================== */ +/* ========================================================================== */ + +/* Does a depth-first-search, starting at node j. */ + +static Int dfs +( + /* input, not modified on output: */ + Int j, /* node at which to start the DFS */ + Int k, /* mark value, for the Flag array */ + Int Pinv [ ], /* Pinv [i] = k if row i is kth pivot row, or EMPTY if + * row i is not yet pivotal. */ + Int Llen [ ], /* size n, Llen [k] = # nonzeros in column k of L */ + Int Lip [ ], /* size n, Lip [k] is position in LU of column k of L */ + + /* workspace, not defined on input or output */ + Int Stack [ ], /* size n */ + + /* input/output: */ + Int Flag [ ], /* Flag [i] == k means i is marked */ + Int Lpend [ ], /* for symmetric pruning */ + Int top, /* top of stack on input*/ + Unit LU [], + Int *Lik, /* Li row index array of the kth column */ + Int *plength, + + /* other, not defined on input or output */ + Int Ap_pos [ ] /* keeps track of position in adj list during DFS */ +) +{ + Int i, pos, jnew, head, l_length ; + Int *Li ; + + l_length = *plength ; + + head = 0 ; + Stack [0] = j ; + ASSERT (Flag [j] != k) ; + + while (head >= 0) + { + j = Stack [head] ; + jnew = Pinv [j] ; + ASSERT (jnew >= 0 && jnew < k) ; /* j is pivotal */ + + if (Flag [j] != k) /* a node is not yet visited */ + { + /* first time that j has been visited */ + Flag [j] = k ; + PRINTF (("[ start dfs at %d : new %d\n", j, jnew)) ; + /* set Ap_pos [head] to one past the last entry in col j to scan */ + Ap_pos [head] = + (Lpend [jnew] == EMPTY) ? Llen [jnew] : Lpend [jnew] ; + } + + /* add the adjacent nodes to the recursive stack by iterating through + * until finding another non-visited pivotal node */ + Li = (Int *) (LU + Lip [jnew]) ; + for (pos = --Ap_pos [head] ; pos >= 0 ; --pos) + { + i = Li [pos] ; + if (Flag [i] != k) + { + /* node i is not yet visited */ + if (Pinv [i] >= 0) + { + /* keep track of where we left off in the scan of the + * adjacency list of node j so we can restart j where we + * left off. */ + Ap_pos [head] = pos ; + + /* node i is pivotal; push it onto the recursive stack + * and immediately break so we can recurse on node i. */ + Stack [++head] = i ; + break ; + } + else + { + /* node i is not pivotal (no outgoing edges). */ + /* Flag as visited and store directly into L, + * and continue with current node j. */ + Flag [i] = k ; + Lik [l_length] = i ; + l_length++ ; + } + } + } + + if (pos == -1) + { + /* if all adjacent nodes of j are already visited, pop j from + * recursive stack and push j onto output stack */ + head-- ; + Stack[--top] = j ; + PRINTF ((" end dfs at %d ] head : %d\n", j, head)) ; + } + } + + *plength = l_length ; + return (top) ; +} + + +/* ========================================================================== */ +/* === lsolve_symbolic ====================================================== */ +/* ========================================================================== */ + +/* Finds the pattern of x, for the solution of Lx=b */ + +static Int lsolve_symbolic +( + /* input, not modified on output: */ + Int n, /* L is n-by-n, where n >= 0 */ + Int k, /* also used as the mark value, for the Flag array */ + Int Ap [ ], + Int Ai [ ], + Int Q [ ], + Int Pinv [ ], /* Pinv [i] = k if i is kth pivot row, or EMPTY if row i + * is not yet pivotal. */ + + /* workspace, not defined on input or output */ + Int Stack [ ], /* size n */ + + /* workspace, defined on input and output */ + Int Flag [ ], /* size n. Initially, all of Flag [0..n-1] < k. After + * lsolve_symbolic is done, Flag [i] == k if i is in + * the pattern of the output, and Flag [0..n-1] <= k. */ + + /* other */ + Int Lpend [ ], /* for symmetric pruning */ + Int Ap_pos [ ], /* workspace used in dfs */ + + Unit LU [ ], /* LU factors (pattern and values) */ + Int lup, /* pointer to free space in LU */ + Int Llen [ ], /* size n, Llen [k] = # nonzeros in column k of L */ + Int Lip [ ], /* size n, Lip [k] is position in LU of column k of L */ + + /* ---- the following are only used in the BTF case --- */ + + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ] /* inverse of P from symbolic factorization */ +) +{ + Int *Lik ; + Int i, p, pend, oldcol, kglobal, top, l_length ; + + top = n ; + l_length = 0 ; + Lik = (Int *) (LU + lup); + + /* ---------------------------------------------------------------------- */ + /* BTF factorization of A (k1:k2-1, k1:k2-1) */ + /* ---------------------------------------------------------------------- */ + + kglobal = k + k1 ; /* column k of the block is col kglobal of A */ + oldcol = Q [kglobal] ; /* Q must be present for BTF case */ + pend = Ap [oldcol+1] ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + i = PSinv [Ai [p]] - k1 ; + if (i < 0) continue ; /* skip entry outside the block */ + + /* (i,k) is an entry in the block. start a DFS at node i */ + PRINTF (("\n ===== DFS at node %d in b, inew: %d\n", i, Pinv [i])) ; + if (Flag [i] != k) + { + if (Pinv [i] >= 0) + { + top = dfs (i, k, Pinv, Llen, Lip, Stack, Flag, + Lpend, top, LU, Lik, &l_length, Ap_pos) ; + } + else + { + /* i is not pivotal, and not flagged. Flag and put in L */ + Flag [i] = k ; + Lik [l_length] = i ; + l_length++; + } + } + } + + /* If Llen [k] is zero, the matrix is structurally singular */ + Llen [k] = l_length ; + return (top) ; +} + + +/* ========================================================================== */ +/* === construct_column ===================================================== */ +/* ========================================================================== */ + +/* Construct the kth column of A, and the off-diagonal part, if requested. + * Scatter the numerical values into the workspace X, and construct the + * corresponding column of the off-diagonal matrix. */ + +static void construct_column +( + /* inputs, not modified on output */ + Int k, /* the column of A (or the column of the block) to get */ + Int Ap [ ], + Int Ai [ ], + Entry Ax [ ], + Int Q [ ], /* column pre-ordering */ + + /* zero on input, modified on output */ + Entry X [ ], + + /* ---- the following are only used in the BTF case --- */ + + /* inputs, not modified on output */ + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ], /* inverse of P from symbolic factorization */ + double Rs [ ], /* scale factors for A */ + Int scale, /* 0: no scaling, nonzero: scale the rows with Rs */ + + /* inputs, modified on output */ + Int Offp [ ], /* off-diagonal matrix (modified by this routine) */ + Int Offi [ ], + Entry Offx [ ] +) +{ + Entry aik ; + Int i, p, pend, oldcol, kglobal, poff, oldrow ; + + /* ---------------------------------------------------------------------- */ + /* Scale and scatter the column into X. */ + /* ---------------------------------------------------------------------- */ + + kglobal = k + k1 ; /* column k of the block is col kglobal of A */ + poff = Offp [kglobal] ; /* start of off-diagonal column */ + oldcol = Q [kglobal] ; + pend = Ap [oldcol+1] ; + + if (scale <= 0) + { + /* no scaling */ + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + i = PSinv [oldrow] - k1 ; + aik = Ax [p] ; + if (i < 0) + { + /* this is an entry in the off-diagonal part */ + Offi [poff] = oldrow ; + Offx [poff] = aik ; + poff++ ; + } + else + { + /* (i,k) is an entry in the block. scatter into X */ + X [i] = aik ; + } + } + } + else + { + /* row scaling */ + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + i = PSinv [oldrow] - k1 ; + aik = Ax [p] ; + SCALE_DIV (aik, Rs [oldrow]) ; + if (i < 0) + { + /* this is an entry in the off-diagonal part */ + Offi [poff] = oldrow ; + Offx [poff] = aik ; + poff++ ; + } + else + { + /* (i,k) is an entry in the block. scatter into X */ + X [i] = aik ; + } + } + } + + Offp [kglobal+1] = poff ; /* start of the next col of off-diag part */ +} + + +/* ========================================================================== */ +/* === lsolve_numeric ======================================================= */ +/* ========================================================================== */ + +/* Computes the numerical values of x, for the solution of Lx=b. Note that x + * may include explicit zeros if numerical cancelation occurs. L is assumed + * to be unit-diagonal, with possibly unsorted columns (but the first entry in + * the column must always be the diagonal entry). */ + +static void lsolve_numeric +( + /* input, not modified on output: */ + Int Pinv [ ], /* Pinv [i] = k if i is kth pivot row, or EMPTY if row i + * is not yet pivotal. */ + Unit *LU, /* LU factors (pattern and values) */ + Int Stack [ ], /* stack for dfs */ + Int Lip [ ], /* size n, Lip [k] is position in LU of column k of L */ + Int top, /* top of stack on input */ + Int n, /* A is n-by-n */ + Int Llen [ ], /* size n, Llen [k] = # nonzeros in column k of L */ + + /* output, must be zero on input: */ + Entry X [ ] /* size n, initially zero. On output, + * X [Ui [up1..up-1]] and X [Li [lp1..lp-1]] + * contains the solution. */ + +) +{ + Entry xj ; + Entry *Lx ; + Int *Li ; + Int p, s, j, jnew, len ; + + /* solve Lx=b */ + for (s = top ; s < n ; s++) + { + /* forward solve with column j of L */ + j = Stack [s] ; + jnew = Pinv [j] ; + ASSERT (jnew >= 0) ; + xj = X [j] ; + GET_POINTER (LU, Lip, Llen, Li, Lx, jnew, len) ; + ASSERT (Lip [jnew] <= Lip [jnew+1]) ; + for (p = 0 ; p < len ; p++) + { + /*X [Li [p]] -= Lx [p] * xj ; */ + MULT_SUB (X [Li [p]], Lx [p], xj) ; + } + } +} + + +/* ========================================================================== */ +/* === lpivot =============================================================== */ +/* ========================================================================== */ + +/* Find a pivot via partial pivoting, and scale the column of L. */ + +static Int lpivot +( + Int diagrow, + Int *p_pivrow, + Entry *p_pivot, + double *p_abs_pivot, + double tol, + Entry X [ ], + Unit *LU, /* LU factors (pattern and values) */ + Int Lip [ ], + Int Llen [ ], + Int k, + Int n, + + Int Pinv [ ], /* Pinv [i] = k if row i is kth pivot row, or EMPTY if + * row i is not yet pivotal. */ + + Int *p_firstrow, + KLU_common *Common +) +{ + Entry x, pivot, *Lx ; + double abs_pivot, xabs ; + Int p, i, ppivrow, pdiag, pivrow, *Li, last_row_index, firstrow, len ; + + pivrow = EMPTY ; + if (Llen [k] == 0) + { + /* matrix is structurally singular */ + if (Common->halt_if_singular) + { + return (FALSE) ; + } + for (firstrow = *p_firstrow ; firstrow < n ; firstrow++) + { + PRINTF (("check %d\n", firstrow)) ; + if (Pinv [firstrow] < 0) + { + /* found the lowest-numbered non-pivotal row. Pick it. */ + pivrow = firstrow ; + PRINTF (("Got pivotal row: %d\n", pivrow)) ; + break ; + } + } + ASSERT (pivrow >= 0 && pivrow < n) ; + CLEAR (pivot) ; + *p_pivrow = pivrow ; + *p_pivot = pivot ; + *p_abs_pivot = 0 ; + *p_firstrow = firstrow ; + return (FALSE) ; + } + + pdiag = EMPTY ; + ppivrow = EMPTY ; + abs_pivot = EMPTY ; + i = Llen [k] - 1 ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + last_row_index = Li [i] ; + + /* decrement the length by 1 */ + Llen [k] = i ; + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + + /* look in Li [0 ..Llen [k] - 1 ] for a pivot row */ + for (p = 0 ; p < len ; p++) + { + /* gather the entry from X and store in L */ + i = Li [p] ; + x = X [i] ; + CLEAR (X [i]) ; + + Lx [p] = x ; + /* xabs = ABS (x) ; */ + ABS (xabs, x) ; + + /* find the diagonal */ + if (i == diagrow) + { + pdiag = p ; + } + + /* find the partial-pivoting choice */ + if (xabs > abs_pivot) + { + abs_pivot = xabs ; + ppivrow = p ; + } + } + + /* xabs = ABS (X [last_row_index]) ;*/ + ABS (xabs, X [last_row_index]) ; + if (xabs > abs_pivot) + { + abs_pivot = xabs ; + ppivrow = EMPTY ; + } + + /* compare the diagonal with the largest entry */ + if (last_row_index == diagrow) + { + if (xabs >= tol * abs_pivot) + { + abs_pivot = xabs ; + ppivrow = EMPTY ; + } + } + else if (pdiag != EMPTY) + { + /* xabs = ABS (Lx [pdiag]) ;*/ + ABS (xabs, Lx [pdiag]) ; + if (xabs >= tol * abs_pivot) + { + /* the diagonal is large enough */ + abs_pivot = xabs ; + ppivrow = pdiag ; + } + } + + if (ppivrow != EMPTY) + { + pivrow = Li [ppivrow] ; + pivot = Lx [ppivrow] ; + /* overwrite the ppivrow values with last index values */ + Li [ppivrow] = last_row_index ; + Lx [ppivrow] = X [last_row_index] ; + } + else + { + pivrow = last_row_index ; + pivot = X [last_row_index] ; + } + CLEAR (X [last_row_index]) ; + + *p_pivrow = pivrow ; + *p_pivot = pivot ; + *p_abs_pivot = abs_pivot ; + ASSERT (pivrow >= 0 && pivrow < n) ; + + if (IS_ZERO (pivot) && Common->halt_if_singular) + { + /* numerically singular case */ + return (FALSE) ; + } + + /* divide L by the pivot value */ + for (p = 0 ; p < Llen [k] ; p++) + { + /* Lx [p] /= pivot ; */ + DIV (Lx [p], Lx [p], pivot) ; + } + + return (TRUE) ; +} + + +/* ========================================================================== */ +/* === prune ================================================================ */ +/* ========================================================================== */ + +/* Prune the columns of L to reduce work in subsequent depth-first searches */ +static void prune +( + /* input/output: */ + Int Lpend [ ], /* Lpend [j] marks symmetric pruning point for L(:,j) */ + + /* input: */ + Int Pinv [ ], /* Pinv [i] = k if row i is kth pivot row, or EMPTY if + * row i is not yet pivotal. */ + Int k, /* prune using column k of U */ + Int pivrow, /* current pivot row */ + + /* input/output: */ + Unit *LU, /* LU factors (pattern and values) */ + + /* input */ + Int Uip [ ], /* size n, column pointers for U */ + Int Lip [ ], /* size n, column pointers for L */ + Int Ulen [ ], /* size n, column length of U */ + Int Llen [ ] /* size n, column length of L */ +) +{ + Entry x ; + Entry *Lx, *Ux ; + Int *Li, *Ui ; + Int p, i, j, p2, phead, ptail, llen, ulen ; + + /* check to see if any column of L can be pruned */ + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ; + for (p = 0 ; p < ulen ; p++) + { + j = Ui [p] ; + ASSERT (j < k) ; + PRINTF (("%d is pruned: %d. Lpend[j] %d Lip[j+1] %d\n", + j, Lpend [j] != EMPTY, Lpend [j], Lip [j+1])) ; + if (Lpend [j] == EMPTY) + { + /* scan column j of L for the pivot row */ + GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ; + for (p2 = 0 ; p2 < llen ; p2++) + { + if (pivrow == Li [p2]) + { + /* found it! This column can be pruned */ +#ifndef NDEBUG + PRINTF (("==== PRUNE: col j %d of L\n", j)) ; + { + Int p3 ; + for (p3 = 0 ; p3 < Llen [j] ; p3++) + { + PRINTF (("before: %i pivotal: %d\n", Li [p3], + Pinv [Li [p3]] >= 0)) ; + } + } +#endif + + /* partition column j of L. The unit diagonal of L + * is not stored in the column of L. */ + phead = 0 ; + ptail = Llen [j] ; + while (phead < ptail) + { + i = Li [phead] ; + if (Pinv [i] >= 0) + { + /* leave at the head */ + phead++ ; + } + else + { + /* swap with the tail */ + ptail-- ; + Li [phead] = Li [ptail] ; + Li [ptail] = i ; + x = Lx [phead] ; + Lx [phead] = Lx [ptail] ; + Lx [ptail] = x ; + } + } + + /* set Lpend to one past the last entry in the + * first part of the column of L. Entries in + * Li [0 ... Lpend [j]-1] are the only part of + * column j of L that needs to be scanned in the DFS. + * Lpend [j] was EMPTY; setting it >= 0 also flags + * column j as pruned. */ + Lpend [j] = ptail ; + +#ifndef NDEBUG + { + Int p3 ; + for (p3 = 0 ; p3 < Llen [j] ; p3++) + { + if (p3 == Lpend [j]) PRINTF (("----\n")) ; + PRINTF (("after: %i pivotal: %d\n", Li [p3], + Pinv [Li [p3]] >= 0)) ; + } + } +#endif + + break ; + } + } + } + } +} + + +/* ========================================================================== */ +/* === KLU_kernel =========================================================== */ +/* ========================================================================== */ + +size_t KLU_kernel /* final size of LU on output */ +( + /* input, not modified */ + Int n, /* A is n-by-n */ + Int Ap [ ], /* size n+1, column pointers for A */ + Int Ai [ ], /* size nz = Ap [n], row indices for A */ + Entry Ax [ ], /* size nz, values of A */ + Int Q [ ], /* size n, optional input permutation */ + size_t lusize, /* initial size of LU on input */ + + /* output, not defined on input */ + Int Pinv [ ], /* size n, inverse row permutation, where Pinv [i] = k if + * row i is the kth pivot row */ + Int P [ ], /* size n, row permutation, where P [k] = i if row i is the + * kth pivot row. */ + Unit **p_LU, /* LU array, size lusize on input */ + Entry Udiag [ ], /* size n, diagonal of U */ + Int Llen [ ], /* size n, column length of L */ + Int Ulen [ ], /* size n, column length of U */ + Int Lip [ ], /* size n, column pointers for L */ + Int Uip [ ], /* size n, column pointers for U */ + Int *lnz, /* size of L*/ + Int *unz, /* size of U*/ + /* workspace, not defined on input */ + Entry X [ ], /* size n, undefined on input, zero on output */ + + /* workspace, not defined on input or output */ + Int Stack [ ], /* size n */ + Int Flag [ ], /* size n */ + Int Ap_pos [ ], /* size n */ + + /* other workspace: */ + Int Lpend [ ], /* size n workspace, for pruning only */ + + /* inputs, not modified on output */ + Int k1, /* the block of A is from k1 to k2-1 */ + Int PSinv [ ], /* inverse of P from symbolic factorization */ + double Rs [ ], /* scale factors for A */ + + /* inputs, modified on output */ + Int Offp [ ], /* off-diagonal matrix (modified by this routine) */ + Int Offi [ ], + Entry Offx [ ], + /* --------------- */ + KLU_common *Common +) +{ + Entry pivot ; + double abs_pivot, xsize, nunits, tol, memgrow ; + Entry *Ux ; + Int *Li, *Ui ; + Unit *LU ; /* LU factors (pattern and values) */ + Int k, p, i, j, pivrow = 0, kbar, diagrow, firstrow, lup, top, scale, len ; + size_t newlusize ; + +#ifndef NDEBUG + Entry *Lx ; +#endif + + ASSERT (Common != NULL) ; + scale = Common->scale ; + tol = Common->tol ; + memgrow = Common->memgrow ; + *lnz = 0 ; + *unz = 0 ; + CLEAR (pivot) ; + + /* ---------------------------------------------------------------------- */ + /* get initial Li, Lx, Ui, and Ux */ + /* ---------------------------------------------------------------------- */ + + PRINTF (("input: lusize %d \n", lusize)) ; + ASSERT (lusize > 0) ; + LU = *p_LU ; + + /* ---------------------------------------------------------------------- */ + /* initializations */ + /* ---------------------------------------------------------------------- */ + + firstrow = 0 ; + lup = 0 ; + + for (k = 0 ; k < n ; k++) + { + /* X [k] = 0 ; */ + CLEAR (X [k]) ; + Flag [k] = EMPTY ; + Lpend [k] = EMPTY ; /* flag k as not pruned */ + } + + /* ---------------------------------------------------------------------- */ + /* mark all rows as non-pivotal and determine initial diagonal mapping */ + /* ---------------------------------------------------------------------- */ + + /* PSinv does the symmetric permutation, so don't do it here */ + for (k = 0 ; k < n ; k++) + { + P [k] = k ; + Pinv [k] = FLIP (k) ; /* mark all rows as non-pivotal */ + } + /* initialize the construction of the off-diagonal matrix */ + Offp [0] = 0 ; + + /* P [k] = row means that UNFLIP (Pinv [row]) = k, and visa versa. + * If row is pivotal, then Pinv [row] >= 0. A row is initially "flipped" + * (Pinv [k] < EMPTY), and then marked "unflipped" when it becomes + * pivotal. */ + +#ifndef NDEBUG + for (k = 0 ; k < n ; k++) + { + PRINTF (("Initial P [%d] = %d\n", k, P [k])) ; + } +#endif + + /* ---------------------------------------------------------------------- */ + /* factorize */ + /* ---------------------------------------------------------------------- */ + + for (k = 0 ; k < n ; k++) + { + + PRINTF (("\n\n==================================== k: %d\n", k)) ; + + /* ------------------------------------------------------------------ */ + /* determine if LU factors have grown too big */ + /* ------------------------------------------------------------------ */ + + /* (n - k) entries for L and k entries for U */ + nunits = DUNITS (Int, n - k) + DUNITS (Int, k) + + DUNITS (Entry, n - k) + DUNITS (Entry, k) ; + + /* LU can grow by at most 'nunits' entries if the column is dense */ + PRINTF (("lup %d lusize %g lup+nunits: %g\n", lup, (double) lusize, + lup+nunits)); + xsize = ((double) lup) + nunits ; + if (xsize > (double) lusize) + { + /* check here how much to grow */ + xsize = (memgrow * ((double) lusize) + 4*n + 1) ; + if (INT_OVERFLOW (xsize)) + { + PRINTF (("Matrix is too large (Int overflow)\n")) ; + Common->status = KLU_TOO_LARGE ; + return (lusize) ; + } + newlusize = memgrow * lusize + 2*n + 1 ; + /* Future work: retry mechanism in case of malloc failure */ + LU = KLU_realloc (newlusize, lusize, sizeof (Unit), LU, Common) ; + Common->nrealloc++ ; + *p_LU = LU ; + if (Common->status == KLU_OUT_OF_MEMORY) + { + PRINTF (("Matrix is too large (LU)\n")) ; + return (lusize) ; + } + lusize = newlusize ; + PRINTF (("inc LU to %d done\n", lusize)) ; + } + + /* ------------------------------------------------------------------ */ + /* start the kth column of L and U */ + /* ------------------------------------------------------------------ */ + + Lip [k] = lup ; + + /* ------------------------------------------------------------------ */ + /* compute the nonzero pattern of the kth column of L and U */ + /* ------------------------------------------------------------------ */ + +#ifndef NDEBUG + for (i = 0 ; i < n ; i++) + { + ASSERT (Flag [i] < k) ; + /* ASSERT (X [i] == 0) ; */ + ASSERT (IS_ZERO (X [i])) ; + } +#endif + + top = lsolve_symbolic (n, k, Ap, Ai, Q, Pinv, Stack, Flag, + Lpend, Ap_pos, LU, lup, Llen, Lip, k1, PSinv) ; + +#ifndef NDEBUG + PRINTF (("--- in U:\n")) ; + for (p = top ; p < n ; p++) + { + PRINTF (("pattern of X for U: %d : %d pivot row: %d\n", + p, Stack [p], Pinv [Stack [p]])) ; + ASSERT (Flag [Stack [p]] == k) ; + } + PRINTF (("--- in L:\n")) ; + Li = (Int *) (LU + Lip [k]); + for (p = 0 ; p < Llen [k] ; p++) + { + PRINTF (("pattern of X in L: %d : %d pivot row: %d\n", + p, Li [p], Pinv [Li [p]])) ; + ASSERT (Flag [Li [p]] == k) ; + } + p = 0 ; + for (i = 0 ; i < n ; i++) + { + ASSERT (Flag [i] <= k) ; + if (Flag [i] == k) p++ ; + } +#endif + + /* ------------------------------------------------------------------ */ + /* get the column of the matrix to factorize and scatter into X */ + /* ------------------------------------------------------------------ */ + + construct_column (k, Ap, Ai, Ax, Q, X, + k1, PSinv, Rs, scale, Offp, Offi, Offx) ; + + /* ------------------------------------------------------------------ */ + /* compute the numerical values of the kth column (s = L \ A (:,k)) */ + /* ------------------------------------------------------------------ */ + + lsolve_numeric (Pinv, LU, Stack, Lip, top, n, Llen, X) ; + +#ifndef NDEBUG + for (p = top ; p < n ; p++) + { + PRINTF (("X for U %d : ", Stack [p])) ; + PRINT_ENTRY (X [Stack [p]]) ; + } + Li = (Int *) (LU + Lip [k]) ; + for (p = 0 ; p < Llen [k] ; p++) + { + PRINTF (("X for L %d : ", Li [p])) ; + PRINT_ENTRY (X [Li [p]]) ; + } +#endif + + /* ------------------------------------------------------------------ */ + /* partial pivoting with diagonal preference */ + /* ------------------------------------------------------------------ */ + + /* determine what the "diagonal" is */ + diagrow = P [k] ; /* might already be pivotal */ + PRINTF (("k %d, diagrow = %d, UNFLIP (diagrow) = %d\n", + k, diagrow, UNFLIP (diagrow))) ; + + /* find a pivot and scale the pivot column */ + if (!lpivot (diagrow, &pivrow, &pivot, &abs_pivot, tol, X, LU, Lip, + Llen, k, n, Pinv, &firstrow, Common)) + { + /* matrix is structurally or numerically singular */ + Common->status = KLU_SINGULAR ; + if (Common->numerical_rank == EMPTY) + { + Common->numerical_rank = k+k1 ; + Common->singular_col = Q [k+k1] ; + } + if (Common->halt_if_singular) + { + /* do not continue the factorization */ + return (lusize) ; + } + } + + /* we now have a valid pivot row, even if the column has NaN's or + * has no entries on or below the diagonal at all. */ + PRINTF (("\nk %d : Pivot row %d : ", k, pivrow)) ; + PRINT_ENTRY (pivot) ; + ASSERT (pivrow >= 0 && pivrow < n) ; + ASSERT (Pinv [pivrow] < 0) ; + + /* set the Uip pointer */ + Uip [k] = Lip [k] + UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ; + + /* move the lup pointer to the position where indices of U + * should be stored */ + lup += UNITS (Int, Llen [k]) + UNITS (Entry, Llen [k]) ; + + Ulen [k] = n - top ; + + /* extract Stack [top..n-1] to Ui and the values to Ux and clear X */ + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + for (p = top, i = 0 ; p < n ; p++, i++) + { + j = Stack [p] ; + Ui [i] = Pinv [j] ; + Ux [i] = X [j] ; + CLEAR (X [j]) ; + } + + /* position the lu index at the starting point for next column */ + lup += UNITS (Int, Ulen [k]) + UNITS (Entry, Ulen [k]) ; + + /* U(k,k) = pivot */ + Udiag [k] = pivot ; + + /* ------------------------------------------------------------------ */ + /* log the pivot permutation */ + /* ------------------------------------------------------------------ */ + + ASSERT (UNFLIP (Pinv [diagrow]) < n) ; + ASSERT (P [UNFLIP (Pinv [diagrow])] == diagrow) ; + + if (pivrow != diagrow) + { + /* an off-diagonal pivot has been chosen */ + Common->noffdiag++ ; + PRINTF ((">>>>>>>>>>>>>>>>> pivrow %d k %d off-diagonal\n", + pivrow, k)) ; + if (Pinv [diagrow] < 0) + { + /* the former diagonal row index, diagrow, has not yet been + * chosen as a pivot row. Log this diagrow as the "diagonal" + * entry in the column kbar for which the chosen pivot row, + * pivrow, was originally logged as the "diagonal" */ + kbar = FLIP (Pinv [pivrow]) ; + P [kbar] = diagrow ; + Pinv [diagrow] = FLIP (kbar) ; + } + } + P [k] = pivrow ; + Pinv [pivrow] = k ; + +#ifndef NDEBUG + for (i = 0 ; i < n ; i++) { ASSERT (IS_ZERO (X [i])) ;} + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, len) ; + for (p = 0 ; p < len ; p++) + { + PRINTF (("Column %d of U: %d : ", k, Ui [p])) ; + PRINT_ENTRY (Ux [p]) ; + } + GET_POINTER (LU, Lip, Llen, Li, Lx, k, len) ; + for (p = 0 ; p < len ; p++) + { + PRINTF (("Column %d of L: %d : ", k, Li [p])) ; + PRINT_ENTRY (Lx [p]) ; + } +#endif + + /* ------------------------------------------------------------------ */ + /* symmetric pruning */ + /* ------------------------------------------------------------------ */ + + prune (Lpend, Pinv, k, pivrow, LU, Uip, Lip, Ulen, Llen) ; + + *lnz += Llen [k] + 1 ; /* 1 added to lnz for diagonal */ + *unz += Ulen [k] + 1 ; /* 1 added to unz for diagonal */ + } + + /* ---------------------------------------------------------------------- */ + /* finalize column pointers for L and U, and put L in the pivotal order */ + /* ---------------------------------------------------------------------- */ + + for (p = 0 ; p < n ; p++) + { + Li = (Int *) (LU + Lip [p]) ; + for (i = 0 ; i < Llen [p] ; i++) + { + Li [i] = Pinv [Li [i]] ; + } + } + +#ifndef NDEBUG + for (i = 0 ; i < n ; i++) + { + PRINTF (("P [%d] = %d Pinv [%d] = %d\n", i, P [i], i, Pinv [i])) ; + } + for (i = 0 ; i < n ; i++) + { + ASSERT (Pinv [i] >= 0 && Pinv [i] < n) ; + ASSERT (P [i] >= 0 && P [i] < n) ; + ASSERT (P [Pinv [i]] == i) ; + ASSERT (IS_ZERO (X [i])) ; + } +#endif + + /* ---------------------------------------------------------------------- */ + /* shrink the LU factors to just the required size */ + /* ---------------------------------------------------------------------- */ + + newlusize = lup ; + ASSERT ((size_t) newlusize <= lusize) ; + + /* this cannot fail, since the block is descreasing in size */ + LU = KLU_realloc (newlusize, lusize, sizeof (Unit), LU, Common) ; + *p_LU = LU ; + return (newlusize) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l.c b/OpenDSSC/klusolve/KLU/Source/klu_l.c new file mode 100644 index 0000000..3b9244b --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_analyze.c b/OpenDSSC/klusolve/KLU/Source/klu_l_analyze.c new file mode 100644 index 0000000..3282408 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_analyze.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_analyze.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_analyze_given.c b/OpenDSSC/klusolve/KLU/Source/klu_l_analyze_given.c new file mode 100644 index 0000000..d879e77 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_analyze_given.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_analyze_given.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_defaults.c b/OpenDSSC/klusolve/KLU/Source/klu_l_defaults.c new file mode 100644 index 0000000..44dde29 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_defaults.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_defaults.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_diagnostics.c b/OpenDSSC/klusolve/KLU/Source/klu_l_diagnostics.c new file mode 100644 index 0000000..7b0854a --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_diagnostics.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_diagnostics.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_dump.c b/OpenDSSC/klusolve/KLU/Source/klu_l_dump.c new file mode 100644 index 0000000..546b700 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_dump.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_dump.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_extract.c b/OpenDSSC/klusolve/KLU/Source/klu_l_extract.c new file mode 100644 index 0000000..15064c4 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_extract.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_extract.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_factor.c b/OpenDSSC/klusolve/KLU/Source/klu_l_factor.c new file mode 100644 index 0000000..6ac383d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_factor.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_factor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_free_numeric.c b/OpenDSSC/klusolve/KLU/Source/klu_l_free_numeric.c new file mode 100644 index 0000000..60afdfa --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_free_numeric.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_free_numeric.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_free_symbolic.c b/OpenDSSC/klusolve/KLU/Source/klu_l_free_symbolic.c new file mode 100644 index 0000000..ff07d92 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_free_symbolic.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_free_symbolic.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_kernel.c b/OpenDSSC/klusolve/KLU/Source/klu_l_kernel.c new file mode 100644 index 0000000..904ef0c --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_kernel.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_kernel.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_memory.c b/OpenDSSC/klusolve/KLU/Source/klu_l_memory.c new file mode 100644 index 0000000..1de30f3 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_memory.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_memory.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_refactor.c b/OpenDSSC/klusolve/KLU/Source/klu_l_refactor.c new file mode 100644 index 0000000..6199a50 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_refactor.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_refactor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_scale.c b/OpenDSSC/klusolve/KLU/Source/klu_l_scale.c new file mode 100644 index 0000000..8988d0b --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_scale.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_scale.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_solve.c b/OpenDSSC/klusolve/KLU/Source/klu_l_solve.c new file mode 100644 index 0000000..4df58e4 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_solve.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_solve.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_sort.c b/OpenDSSC/klusolve/KLU/Source/klu_l_sort.c new file mode 100644 index 0000000..4c6242d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_sort.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_sort.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_l_tsolve.c b/OpenDSSC/klusolve/KLU/Source/klu_l_tsolve.c new file mode 100644 index 0000000..362f491 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_l_tsolve.c @@ -0,0 +1,2 @@ +#define DLONG 1 +#include "klu_tsolve.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_memory.c b/OpenDSSC/klusolve/KLU/Source/klu_memory.c new file mode 100644 index 0000000..a4fa3b8 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_memory.c @@ -0,0 +1,225 @@ +/* ========================================================================== */ +/* === KLU_memory =========================================================== */ +/* ========================================================================== */ + +/* KLU memory management routines: + * + * KLU_malloc malloc wrapper + * KLU_free free wrapper + * KLU_realloc realloc wrapper + */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === KLU_add_size_t ======================================================= */ +/* ========================================================================== */ + +/* Safely compute a+b, and check for size_t overflow */ + +size_t KLU_add_size_t (size_t a, size_t b, Int *ok) +{ + (*ok) = (*ok) && ((a + b) >= MAX (a,b)) ; + return ((*ok) ? (a + b) : ((size_t) -1)) ; +} + +/* ========================================================================== */ +/* === KLU_mult_size_t ====================================================== */ +/* ========================================================================== */ + +/* Safely compute a*k, where k should be small, and check for size_t overflow */ + +size_t KLU_mult_size_t (size_t a, size_t k, Int *ok) +{ + size_t i, s = 0 ; + for (i = 0 ; i < k ; i++) + { + s = KLU_add_size_t (s, a, ok) ; + } + return ((*ok) ? s : ((size_t) -1)) ; +} + +/* ========================================================================== */ +/* === KLU_malloc =========================================================== */ +/* ========================================================================== */ + +/* Wrapper around malloc routine (mxMalloc for a mexFunction). Allocates + * space of size MAX(1,n)*size, where size is normally a sizeof (...). + * + * This routine and KLU_realloc do not set Common->status to KLU_OK on success, + * so that a sequence of KLU_malloc's or KLU_realloc's can be used. If any of + * them fails, the Common->status will hold the most recent error status. + * + * Usage, for a pointer to Int: + * + * p = KLU_malloc (n, sizeof (Int), Common) + * + * Uses a pointer to the malloc routine (or its equivalent) defined in Common. + */ + +void *KLU_malloc /* returns pointer to the newly malloc'd block */ +( + /* ---- input ---- */ + size_t n, /* number of items */ + size_t size, /* size of each item */ + /* --------------- */ + KLU_common *Common +) +{ + void *p ; + size_t s ; + Int ok = TRUE ; + + if (Common == NULL) + { + p = NULL ; + } + else if (size == 0) + { + /* size must be > 0 */ + Common->status = KLU_INVALID ; + p = NULL ; + } + else if (n >= INT_MAX) + { + /* object is too big to allocate; p[i] where i is an Int will not + * be enough. */ + Common->status = KLU_TOO_LARGE ; + p = NULL ; + } + else + { + /* call malloc, or its equivalent */ + s = KLU_mult_size_t (MAX (1,n), size, &ok) ; + p = ok ? ((Common->malloc_memory) (s)) : NULL ; + if (p == NULL) + { + /* failure: out of memory */ + Common->status = KLU_OUT_OF_MEMORY ; + } + else + { + Common->memusage += s ; + Common->mempeak = MAX (Common->mempeak, Common->memusage) ; + } + } + return (p) ; +} + + +/* ========================================================================== */ +/* === KLU_free ============================================================= */ +/* ========================================================================== */ + +/* Wrapper around free routine (mxFree for a mexFunction). Returns NULL, + * which can be assigned to the pointer being freed, as in: + * + * p = KLU_free (p, n, sizeof (int), Common) ; + */ + +void *KLU_free /* always returns NULL */ +( + /* ---- in/out --- */ + void *p, /* block of memory to free */ + /* ---- input --- */ + size_t n, /* size of block to free, in # of items */ + size_t size, /* size of each item */ + /* --------------- */ + KLU_common *Common +) +{ + size_t s ; + Int ok = TRUE ; + if (p != NULL && Common != NULL) + { + /* only free the object if the pointer is not NULL */ + /* call free, or its equivalent */ + (Common->free_memory) (p) ; + s = KLU_mult_size_t (MAX (1,n), size, &ok) ; + Common->memusage -= s ; + } + /* return NULL, and the caller should assign this to p. This avoids + * freeing the same pointer twice. */ + return (NULL) ; +} + + +/* ========================================================================== */ +/* === KLU_realloc ========================================================== */ +/* ========================================================================== */ + +/* Wrapper around realloc routine (mxRealloc for a mexFunction). Given a + * pointer p to a block allocated by KLU_malloc, it changes the size of the + * block pointed to by p to be MAX(1,nnew)*size in size. It may return a + * pointer different than p. This should be used as (for a pointer to Int): + * + * p = KLU_realloc (nnew, nold, sizeof (Int), p, Common) ; + * + * If p is NULL, this is the same as p = KLU_malloc (...). + * A size of nnew=0 is treated as nnew=1. + * + * If the realloc fails, p is returned unchanged and Common->status is set + * to KLU_OUT_OF_MEMORY. If successful, Common->status is not modified, + * and p is returned (possibly changed) and pointing to a large block of memory. + * + * Uses a pointer to the realloc routine (or its equivalent) defined in Common. + */ + +void *KLU_realloc /* returns pointer to reallocated block */ +( + /* ---- input ---- */ + size_t nnew, /* requested # of items in reallocated block */ + size_t nold, /* old # of items */ + size_t size, /* size of each item */ + /* ---- in/out --- */ + void *p, /* block of memory to realloc */ + /* --------------- */ + KLU_common *Common +) +{ + void *pnew ; + size_t snew, sold ; + Int ok = TRUE ; + + if (Common == NULL) + { + p = NULL ; + } + else if (size == 0) + { + /* size must be > 0 */ + Common->status = KLU_INVALID ; + p = NULL ; + } + else if (p == NULL) + { + /* A fresh object is being allocated. */ + p = KLU_malloc (nnew, size, Common) ; + } + else if (nnew >= INT_MAX) + { + /* failure: nnew is too big. Do not change p */ + Common->status = KLU_TOO_LARGE ; + } + else + { + /* The object exists, and is changing to some other nonzero size. */ + /* call realloc, or its equivalent */ + snew = KLU_mult_size_t (MAX (1,nnew), size, &ok) ; + sold = KLU_mult_size_t (MAX (1,nold), size, &ok) ; + pnew = ok ? ((Common->realloc_memory) (p, snew)) : NULL ; + if (pnew == NULL) + { + /* Do not change p, since it still points to allocated memory */ + Common->status = KLU_OUT_OF_MEMORY ; + } + else + { + /* success: return the new p and change the size of the block */ + Common->memusage += (snew - sold) ; + Common->mempeak = MAX (Common->mempeak, Common->memusage) ; + p = pnew ; + } + } + return (p) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_refactor.c b/OpenDSSC/klusolve/KLU/Source/klu_refactor.c new file mode 100644 index 0000000..1415788 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_refactor.c @@ -0,0 +1,478 @@ +/* ========================================================================== */ +/* === KLU_refactor ========================================================= */ +/* ========================================================================== */ + +/* Factor the matrix, after ordering and analyzing it with KLU_analyze, and + * factoring it once with KLU_factor. This routine cannot do any numerical + * pivoting. The pattern of the input matrix (Ap, Ai) must be identical to + * the pattern given to KLU_factor. + */ + +#include "klu_internal.h" + + +/* ========================================================================== */ +/* === KLU_refactor ========================================================= */ +/* ========================================================================== */ + +Int KLU_refactor /* returns TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + double Ax [ ], + KLU_symbolic *Symbolic, + + /* input/output */ + KLU_numeric *Numeric, + KLU_common *Common +) +{ + Entry ukk, ujk, s ; + Entry *Offx, *Lx, *Ux, *X, *Az, *Udiag ; + double *Rs ; + Int *P, *Q, *R, *Pnum, *Offp, *Offi, *Ui, *Li, *Pinv, *Lip, *Uip, *Llen, + *Ulen ; + Unit **LUbx ; + Unit *LU ; + Int k1, k2, nk, k, block, oldcol, pend, oldrow, n, p, newrow, scale, + nblocks, poff, i, j, up, ulen, llen, maxblock, nzoff ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + Common->status = KLU_OK ; + + if (Numeric == NULL) + { + /* invalid Numeric object */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + + Common->numerical_rank = EMPTY ; + Common->singular_col = EMPTY ; + + Az = (Entry *) Ax ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + n = Symbolic->n ; + P = Symbolic->P ; + Q = Symbolic->Q ; + R = Symbolic->R ; + nblocks = Symbolic->nblocks ; + maxblock = Symbolic->maxblock ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Numeric object */ + /* ---------------------------------------------------------------------- */ + + Pnum = Numeric->Pnum ; + Offp = Numeric->Offp ; + Offi = Numeric->Offi ; + Offx = (Entry *) Numeric->Offx ; + + LUbx = (Unit **) Numeric->LUbx ; + + scale = Common->scale ; + if (scale > 0) + { + /* factorization was not scaled, but refactorization is scaled */ + if (Numeric->Rs == NULL) + { + Numeric->Rs = KLU_malloc (n, sizeof (double), Common) ; + if (Common->status < KLU_OK) + { + Common->status = KLU_OUT_OF_MEMORY ; + return (FALSE) ; + } + } + } + else + { + /* no scaling for refactorization; ensure Numeric->Rs is freed. This + * does nothing if Numeric->Rs is already NULL. */ + Numeric->Rs = KLU_free (Numeric->Rs, n, sizeof (double), Common) ; + } + Rs = Numeric->Rs ; + + Pinv = Numeric->Pinv ; + X = (Entry *) Numeric->Xwork ; + Common->nrealloc = 0 ; + Udiag = Numeric->Udiag ; + nzoff = Symbolic->nzoff ; + + /* ---------------------------------------------------------------------- */ + /* check the input matrix compute the row scale factors, Rs */ + /* ---------------------------------------------------------------------- */ + + /* do no scale, or check the input matrix, if scale < 0 */ + if (scale >= 0) + { + /* check for out-of-range indices, but do not check for duplicates */ + if (!KLU_scale (scale, n, Ap, Ai, Ax, Rs, NULL, Common)) + { + return (FALSE) ; + } + } + + /* ---------------------------------------------------------------------- */ + /* clear workspace X */ + /* ---------------------------------------------------------------------- */ + + for (k = 0 ; k < maxblock ; k++) + { + /* X [k] = 0 */ + CLEAR (X [k]) ; + } + + poff = 0 ; + + /* ---------------------------------------------------------------------- */ + /* factor each block */ + /* ---------------------------------------------------------------------- */ + + if (scale <= 0) + { + + /* ------------------------------------------------------------------ */ + /* no scaling */ + /* ------------------------------------------------------------------ */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* -------------------------------------------------------------- */ + /* the block is from rows/columns k1 to k2-1 */ + /* -------------------------------------------------------------- */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + + if (nk == 1) + { + + /* ---------------------------------------------------------- */ + /* singleton case */ + /* ---------------------------------------------------------- */ + + oldcol = Q [k1] ; + pend = Ap [oldcol+1] ; + CLEAR (s) ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + newrow = Pinv [Ai [p]] - k1 ; + if (newrow < 0 && poff < nzoff) + { + /* entry in off-diagonal block */ + Offx [poff] = Az [p] ; + poff++ ; + } + else + { + /* singleton */ + s = Az [p] ; + } + } + Udiag [k1] = s ; + + } + else + { + + /* ---------------------------------------------------------- */ + /* construct and factor the kth block */ + /* ---------------------------------------------------------- */ + + Lip = Numeric->Lip + k1 ; + Llen = Numeric->Llen + k1 ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + LU = LUbx [block] ; + + for (k = 0 ; k < nk ; k++) + { + + /* ------------------------------------------------------ */ + /* scatter kth column of the block into workspace X */ + /* ------------------------------------------------------ */ + + oldcol = Q [k+k1] ; + pend = Ap [oldcol+1] ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + newrow = Pinv [Ai [p]] - k1 ; + if (newrow < 0 && poff < nzoff) + { + /* entry in off-diagonal block */ + Offx [poff] = Az [p] ; + poff++ ; + } + else + { + /* (newrow,k) is an entry in the block */ + X [newrow] = Az [p] ; + } + } + + /* ------------------------------------------------------ */ + /* compute kth column of U, and update kth column of A */ + /* ------------------------------------------------------ */ + + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ; + for (up = 0 ; up < ulen ; up++) + { + j = Ui [up] ; + ujk = X [j] ; + /* X [j] = 0 */ + CLEAR (X [j]) ; + Ux [up] = ujk ; + GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ; + for (p = 0 ; p < llen ; p++) + { + /* X [Li [p]] -= Lx [p] * ujk */ + MULT_SUB (X [Li [p]], Lx [p], ujk) ; + } + } + /* get the diagonal entry of U */ + ukk = X [k] ; + /* X [k] = 0 */ + CLEAR (X [k]) ; + /* singular case */ + if (IS_ZERO (ukk)) + { + /* matrix is numerically singular */ + Common->status = KLU_SINGULAR ; + if (Common->numerical_rank == EMPTY) + { + Common->numerical_rank = k+k1 ; + Common->singular_col = Q [k+k1] ; + } + if (Common->halt_if_singular) + { + /* do not continue the factorization */ + return (FALSE) ; + } + } + Udiag [k+k1] = ukk ; + /* gather and divide by pivot to get kth column of L */ + GET_POINTER (LU, Lip, Llen, Li, Lx, k, llen) ; + for (p = 0 ; p < llen ; p++) + { + i = Li [p] ; + DIV (Lx [p], X [i], ukk) ; + CLEAR (X [i]) ; + } + + } + } + } + + } + else + { + + /* ------------------------------------------------------------------ */ + /* scaling */ + /* ------------------------------------------------------------------ */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* -------------------------------------------------------------- */ + /* the block is from rows/columns k1 to k2-1 */ + /* -------------------------------------------------------------- */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + + if (nk == 1) + { + + /* ---------------------------------------------------------- */ + /* singleton case */ + /* ---------------------------------------------------------- */ + + oldcol = Q [k1] ; + pend = Ap [oldcol+1] ; + CLEAR (s) ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + newrow = Pinv [oldrow] - k1 ; + if (newrow < 0 && poff < nzoff) + { + /* entry in off-diagonal block */ + /* Offx [poff] = Az [p] / Rs [oldrow] */ + SCALE_DIV_ASSIGN (Offx [poff], Az [p], Rs [oldrow]) ; + poff++ ; + } + else + { + /* singleton */ + /* s = Az [p] / Rs [oldrow] */ + SCALE_DIV_ASSIGN (s, Az [p], Rs [oldrow]) ; + } + } + Udiag [k1] = s ; + + } + else + { + + /* ---------------------------------------------------------- */ + /* construct and factor the kth block */ + /* ---------------------------------------------------------- */ + + Lip = Numeric->Lip + k1 ; + Llen = Numeric->Llen + k1 ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + LU = LUbx [block] ; + + for (k = 0 ; k < nk ; k++) + { + + /* ------------------------------------------------------ */ + /* scatter kth column of the block into workspace X */ + /* ------------------------------------------------------ */ + + oldcol = Q [k+k1] ; + pend = Ap [oldcol+1] ; + for (p = Ap [oldcol] ; p < pend ; p++) + { + oldrow = Ai [p] ; + newrow = Pinv [oldrow] - k1 ; + if (newrow < 0 && poff < nzoff) + { + /* entry in off-diagonal part */ + /* Offx [poff] = Az [p] / Rs [oldrow] */ + SCALE_DIV_ASSIGN (Offx [poff], Az [p], Rs [oldrow]); + poff++ ; + } + else + { + /* (newrow,k) is an entry in the block */ + /* X [newrow] = Az [p] / Rs [oldrow] */ + SCALE_DIV_ASSIGN (X [newrow], Az [p], Rs [oldrow]) ; + } + } + + /* ------------------------------------------------------ */ + /* compute kth column of U, and update kth column of A */ + /* ------------------------------------------------------ */ + + GET_POINTER (LU, Uip, Ulen, Ui, Ux, k, ulen) ; + for (up = 0 ; up < ulen ; up++) + { + j = Ui [up] ; + ujk = X [j] ; + /* X [j] = 0 */ + CLEAR (X [j]) ; + Ux [up] = ujk ; + GET_POINTER (LU, Lip, Llen, Li, Lx, j, llen) ; + for (p = 0 ; p < llen ; p++) + { + /* X [Li [p]] -= Lx [p] * ujk */ + MULT_SUB (X [Li [p]], Lx [p], ujk) ; + } + } + /* get the diagonal entry of U */ + ukk = X [k] ; + /* X [k] = 0 */ + CLEAR (X [k]) ; + /* singular case */ + if (IS_ZERO (ukk)) + { + /* matrix is numerically singular */ + Common->status = KLU_SINGULAR ; + if (Common->numerical_rank == EMPTY) + { + Common->numerical_rank = k+k1 ; + Common->singular_col = Q [k+k1] ; + } + if (Common->halt_if_singular) + { + /* do not continue the factorization */ + return (FALSE) ; + } + } + Udiag [k+k1] = ukk ; + /* gather and divide by pivot to get kth column of L */ + GET_POINTER (LU, Lip, Llen, Li, Lx, k, llen) ; + for (p = 0 ; p < llen ; p++) + { + i = Li [p] ; + DIV (Lx [p], X [i], ukk) ; + CLEAR (X [i]) ; + } + } + } + } + } + + /* ---------------------------------------------------------------------- */ + /* permute scale factors Rs according to pivotal row order */ + /* ---------------------------------------------------------------------- */ + + if (scale > 0) + { + for (k = 0 ; k < n ; k++) + { + REAL (X [k]) = Rs [Pnum [k]] ; + } + for (k = 0 ; k < n ; k++) + { + Rs [k] = REAL (X [k]) ; + } + } + +#ifndef NDEBUG + ASSERT (Offp [n] == poff) ; + ASSERT (Symbolic->nzoff == poff) ; + PRINTF (("\n------------------- Off diagonal entries, new:\n")) ; + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + if (Common->status == KLU_OK) + { + PRINTF (("\n ########### KLU_BTF_REFACTOR done, nblocks %d\n",nblocks)); + for (block = 0 ; block < nblocks ; block++) + { + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (( + "\n================KLU_refactor output: k1 %d k2 %d nk %d\n", + k1, k2, nk)) ; + if (nk == 1) + { + PRINTF (("singleton ")) ; + PRINT_ENTRY (Udiag [k1]) ; + } + else + { + Lip = Numeric->Lip + k1 ; + Llen = Numeric->Llen + k1 ; + LU = (Unit *) Numeric->LUbx [block] ; + PRINTF (("\n---- L block %d\n", block)) ; + ASSERT (KLU_valid_LU (nk, TRUE, Lip, Llen, LU)) ; + Uip = Numeric->Uip + k1 ; + Ulen = Numeric->Ulen + k1 ; + PRINTF (("\n---- U block %d\n", block)) ; + ASSERT (KLU_valid_LU (nk, FALSE, Uip, Ulen, LU)) ; + } + } + } +#endif + + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_scale.c b/OpenDSSC/klusolve/KLU/Source/klu_scale.c new file mode 100644 index 0000000..8a65ce0 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_scale.c @@ -0,0 +1,159 @@ +/* ========================================================================== */ +/* === KLU_scale ============================================================ */ +/* ========================================================================== */ + +/* Scale a matrix and check to see if it is valid. Can be called by the user. + * This is called by KLU_factor and KLU_refactor. Returns TRUE if the input + * matrix is valid, FALSE otherwise. If the W input argument is non-NULL, + * then the input matrix is checked for duplicate entries. + * + * scaling methods: + * <0: no scaling, do not compute Rs, and do not check input matrix. + * 0: no scaling + * 1: the scale factor for row i is sum (abs (A (i,:))) + * 2 or more: the scale factor for row i is max (abs (A (i,:))) + */ + +#include "klu_internal.h" + +Int KLU_scale /* return TRUE if successful, FALSE otherwise */ +( + /* inputs, not modified */ + Int scale, /* 0: none, 1: sum, 2: max */ + Int n, + Int Ap [ ], /* size n+1, column pointers */ + Int Ai [ ], /* size nz, row indices */ + double Ax [ ], + /* outputs, not defined on input */ + double Rs [ ], /* size n, can be NULL if scale <= 0 */ + /* workspace, not defined on input or output */ + Int W [ ], /* size n, can be NULL */ + /* --------------- */ + KLU_common *Common +) +{ + double a ; + Entry *Az ; + Int row, col, p, pend, check_duplicates ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + Common->status = KLU_OK ; + + if (scale < 0) + { + /* return without checking anything and without computing the + * scale factors */ + return (TRUE) ; + } + + Az = (Entry *) Ax ; + + if (n <= 0 || Ap == NULL || Ai == NULL || Az == NULL || + (scale > 0 && Rs == NULL)) + { + /* Ap, Ai, Ax and Rs must be present, and n must be > 0 */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + if (Ap [0] != 0 || Ap [n] < 0) + { + /* nz = Ap [n] must be >= 0 and Ap [0] must equal zero */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + for (col = 0 ; col < n ; col++) + { + if (Ap [col] > Ap [col+1]) + { + /* column pointers must be non-decreasing */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + } + + /* ---------------------------------------------------------------------- */ + /* scale */ + /* ---------------------------------------------------------------------- */ + + if (scale > 0) + { + /* initialize row sum or row max */ + for (row = 0 ; row < n ; row++) + { + Rs [row] = 0 ; + } + } + + /* check for duplicates only if W is present */ + check_duplicates = (W != (Int *) NULL) ; + if (check_duplicates) + { + for (row = 0 ; row < n ; row++) + { + W [row] = EMPTY ; + } + } + + for (col = 0 ; col < n ; col++) + { + pend = Ap [col+1] ; + for (p = Ap [col] ; p < pend ; p++) + { + row = Ai [p] ; + if (row < 0 || row >= n) + { + /* row index out of range, or duplicate entry */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + if (check_duplicates) + { + if (W [row] == col) + { + /* duplicate entry */ + Common->status = KLU_INVALID ; + return (FALSE) ; + } + /* flag row i as appearing in column col */ + W [row] = col ; + } + /* a = ABS (Az [p]) ;*/ + ABS (a, Az [p]) ; + if (scale == 1) + { + /* accumulate the abs. row sum */ + Rs [row] += a ; + } + else if (scale > 1) + { + /* find the max abs. value in the row */ + Rs [row] = MAX (Rs [row], a) ; + } + } + } + + if (scale > 0) + { + /* do not scale empty rows */ + for (row = 0 ; row < n ; row++) + { + /* matrix is singular */ + PRINTF (("Rs [%d] = %g\n", row, Rs [row])) ; + + if (Rs [row] == 0.0) + { + PRINTF (("Row %d of A is all zero\n", row)) ; + Rs [row] = 1.0 ; + } + } + } + + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_solve.c b/OpenDSSC/klusolve/KLU/Source/klu_solve.c new file mode 100644 index 0000000..d725152 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_solve.c @@ -0,0 +1,396 @@ +/* ========================================================================== */ +/* === KLU_solve ============================================================ */ +/* ========================================================================== */ + +/* Solve Ax=b using the symbolic and numeric objects from KLU_analyze + * (or KLU_analyze_given) and KLU_factor. Note that no iterative refinement is + * performed. Uses Numeric->Xwork as workspace (undefined on input and output), + * of size 4n Entry's (note that columns 2 to 4 of Xwork overlap with + * Numeric->Iwork). + */ + +#include "klu_internal.h" + +Int KLU_solve +( + /* inputs, not modified */ + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + Int d, /* leading dimension of B */ + Int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size n*nrhs, in column-oriented form, with + * leading dimension d. */ + /* --------------- */ + KLU_common *Common +) +{ + Entry x [4], offik, s ; + double rs, *Rs ; + Entry *Offx, *X, *Bz, *Udiag ; + Int *Q, *R, *Pnum, *Offp, *Offi, *Lip, *Uip, *Llen, *Ulen ; + Unit **LUbx ; + Int k1, k2, nk, k, block, pend, n, p, nblocks, chunk, nr, i ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + if (Numeric == NULL || Symbolic == NULL || d < Symbolic->n || nrhs < 0 || + B == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + Bz = (Entry *) B ; + n = Symbolic->n ; + nblocks = Symbolic->nblocks ; + Q = Symbolic->Q ; + R = Symbolic->R ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Numeric object */ + /* ---------------------------------------------------------------------- */ + + ASSERT (nblocks == Numeric->nblocks) ; + Pnum = Numeric->Pnum ; + Offp = Numeric->Offp ; + Offi = Numeric->Offi ; + Offx = (Entry *) Numeric->Offx ; + + Lip = Numeric->Lip ; + Llen = Numeric->Llen ; + Uip = Numeric->Uip ; + Ulen = Numeric->Ulen ; + LUbx = (Unit **) Numeric->LUbx ; + Udiag = Numeric->Udiag ; + + Rs = Numeric->Rs ; + X = (Entry *) Numeric->Xwork ; + + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + + /* ---------------------------------------------------------------------- */ + /* solve in chunks of 4 columns at a time */ + /* ---------------------------------------------------------------------- */ + + for (chunk = 0 ; chunk < nrhs ; chunk += 4) + { + + /* ------------------------------------------------------------------ */ + /* get the size of the current chunk */ + /* ------------------------------------------------------------------ */ + + nr = MIN (nrhs - chunk, 4) ; + + /* ------------------------------------------------------------------ */ + /* scale and permute the right hand side, X = P*(R\B) */ + /* ------------------------------------------------------------------ */ + + if (Rs == NULL) + { + + /* no scaling */ + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + X [k] = Bz [Pnum [k]] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + X [2*k ] = Bz [i ] ; + X [2*k + 1] = Bz [i + d ] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + X [3*k ] = Bz [i ] ; + X [3*k + 1] = Bz [i + d ] ; + X [3*k + 2] = Bz [i + d*2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + X [4*k ] = Bz [i ] ; + X [4*k + 1] = Bz [i + d ] ; + X [4*k + 2] = Bz [i + d*2] ; + X [4*k + 3] = Bz [i + d*3] ; + } + break ; + } + + } + else + { + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + SCALE_DIV_ASSIGN (X [k], Bz [Pnum [k]], Rs [k]) ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (X [2*k], Bz [i], rs) ; + SCALE_DIV_ASSIGN (X [2*k + 1], Bz [i + d], rs) ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (X [3*k], Bz [i], rs) ; + SCALE_DIV_ASSIGN (X [3*k + 1], Bz [i + d], rs) ; + SCALE_DIV_ASSIGN (X [3*k + 2], Bz [i + d*2], rs) ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (X [4*k], Bz [i], rs) ; + SCALE_DIV_ASSIGN (X [4*k + 1], Bz [i + d], rs) ; + SCALE_DIV_ASSIGN (X [4*k + 2], Bz [i + d*2], rs) ; + SCALE_DIV_ASSIGN (X [4*k + 3], Bz [i + d*3], rs) ; + } + break ; + } + } + + /* ------------------------------------------------------------------ */ + /* solve X = (L*U + Off)\X */ + /* ------------------------------------------------------------------ */ + + for (block = nblocks-1 ; block >= 0 ; block--) + { + + /* -------------------------------------------------------------- */ + /* the block of size nk is from rows/columns k1 to k2-1 */ + /* -------------------------------------------------------------- */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("solve %d, k1 %d k2-1 %d nk %d\n", block, k1,k2-1,nk)) ; + + /* solve the block system */ + if (nk == 1) + { + s = Udiag [k1] ; + switch (nr) + { + + case 1: + DIV (X [k1], X [k1], s) ; + break ; + + case 2: + DIV (X [2*k1], X [2*k1], s) ; + DIV (X [2*k1 + 1], X [2*k1 + 1], s) ; + break ; + + case 3: + DIV (X [3*k1], X [3*k1], s) ; + DIV (X [3*k1 + 1], X [3*k1 + 1], s) ; + DIV (X [3*k1 + 2], X [3*k1 + 2], s) ; + break ; + + case 4: + DIV (X [4*k1], X [4*k1], s) ; + DIV (X [4*k1 + 1], X [4*k1 + 1], s) ; + DIV (X [4*k1 + 2], X [4*k1 + 2], s) ; + DIV (X [4*k1 + 3], X [4*k1 + 3], s) ; + break ; + + } + } + else + { + KLU_lsolve (nk, Lip + k1, Llen + k1, LUbx [block], nr, + X + nr*k1) ; + KLU_usolve (nk, Uip + k1, Ulen + k1, LUbx [block], + Udiag + k1, nr, X + nr*k1) ; + } + + /* -------------------------------------------------------------- */ + /* block back-substitution for the off-diagonal-block entries */ + /* -------------------------------------------------------------- */ + + if (block > 0) + { + switch (nr) + { + + case 1: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [k] ; + for (p = Offp [k] ; p < pend ; p++) + { + MULT_SUB (X [Offi [p]], Offx [p], x [0]) ; + } + } + break ; + + case 2: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [2*k ] ; + x [1] = X [2*k + 1] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + MULT_SUB (X [2*i], offik, x [0]) ; + MULT_SUB (X [2*i + 1], offik, x [1]) ; + } + } + break ; + + case 3: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [3*k ] ; + x [1] = X [3*k + 1] ; + x [2] = X [3*k + 2] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + MULT_SUB (X [3*i], offik, x [0]) ; + MULT_SUB (X [3*i + 1], offik, x [1]) ; + MULT_SUB (X [3*i + 2], offik, x [2]) ; + } + } + break ; + + case 4: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [4*k ] ; + x [1] = X [4*k + 1] ; + x [2] = X [4*k + 2] ; + x [3] = X [4*k + 3] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; + offik = Offx [p] ; + MULT_SUB (X [4*i], offik, x [0]) ; + MULT_SUB (X [4*i + 1], offik, x [1]) ; + MULT_SUB (X [4*i + 2], offik, x [2]) ; + MULT_SUB (X [4*i + 3], offik, x [3]) ; + } + } + break ; + } + } + } + + /* ------------------------------------------------------------------ */ + /* permute the result, Bz = Q*X */ + /* ------------------------------------------------------------------ */ + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + Bz [Q [k]] = X [k] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + Bz [i ] = X [2*k ] ; + Bz [i + d ] = X [2*k + 1] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + Bz [i ] = X [3*k ] ; + Bz [i + d ] = X [3*k + 1] ; + Bz [i + d*2] = X [3*k + 2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + Bz [i ] = X [4*k ] ; + Bz [i + d ] = X [4*k + 1] ; + Bz [i + d*2] = X [4*k + 2] ; + Bz [i + d*3] = X [4*k + 3] ; + } + break ; + } + + /* ------------------------------------------------------------------ */ + /* go to the next chunk of B */ + /* ------------------------------------------------------------------ */ + + Bz += d*4 ; + } + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_sort.c b/OpenDSSC/klusolve/KLU/Source/klu_sort.c new file mode 100644 index 0000000..5405b4f --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_sort.c @@ -0,0 +1,156 @@ +/* ========================================================================== */ +/* === KLU_sort ============================================================= */ +/* ========================================================================== */ + +/* sorts the columns of L and U so that the row indices appear in strictly + * increasing order. + */ + +#include "klu_internal.h" + +/* ========================================================================== */ +/* === sort ================================================================= */ +/* ========================================================================== */ + +/* Sort L or U using a double-transpose */ + +static void sort (Int n, Int *Xip, Int *Xlen, Unit *LU, Int *Tp, Int *Tj, + Entry *Tx, Int *W) +{ + Int *Xi ; + Entry *Xx ; + Int p, i, j, len, nz, tp, xlen, pend ; + + ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ; + + /* count the number of entries in each row of L or U */ + for (i = 0 ; i < n ; i++) + { + W [i] = 0 ; + } + for (j = 0 ; j < n ; j++) + { + GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ; + for (p = 0 ; p < len ; p++) + { + W [Xi [p]]++ ; + } + } + + /* construct the row pointers for T */ + nz = 0 ; + for (i = 0 ; i < n ; i++) + { + Tp [i] = nz ; + nz += W [i] ; + } + Tp [n] = nz ; + for (i = 0 ; i < n ; i++) + { + W [i] = Tp [i] ; + } + + /* transpose the matrix into Tp, Ti, Tx */ + for (j = 0 ; j < n ; j++) + { + GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ; + for (p = 0 ; p < len ; p++) + { + tp = W [Xi [p]]++ ; + Tj [tp] = j ; + Tx [tp] = Xx [p] ; + } + } + + /* transpose the matrix back into Xip, Xlen, Xi, Xx */ + for (j = 0 ; j < n ; j++) + { + W [j] = 0 ; + } + for (i = 0 ; i < n ; i++) + { + pend = Tp [i+1] ; + for (p = Tp [i] ; p < pend ; p++) + { + j = Tj [p] ; + GET_POINTER (LU, Xip, Xlen, Xi, Xx, j, len) ; + xlen = W [j]++ ; + Xi [xlen] = i ; + Xx [xlen] = Tx [p] ; + } + } + + ASSERT (KLU_valid_LU (n, FALSE, Xip, Xlen, LU)) ; +} + + +/* ========================================================================== */ +/* === KLU_sort ============================================================= */ +/* ========================================================================== */ + +Int KLU_sort +( + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + KLU_common *Common +) +{ + Int *R, *W, *Tp, *Ti, *Lip, *Uip, *Llen, *Ulen ; + Entry *Tx ; + Unit **LUbx ; + Int n, nk, nz, block, nblocks, maxblock, k1 ; + size_t m1 ; + + if (Common == NULL) + { + return (FALSE) ; + } + Common->status = KLU_OK ; + + n = Symbolic->n ; + R = Symbolic->R ; + nblocks = Symbolic->nblocks ; + maxblock = Symbolic->maxblock ; + + Lip = Numeric->Lip ; + Llen = Numeric->Llen ; + Uip = Numeric->Uip ; + Ulen = Numeric->Ulen ; + LUbx = (Unit **) Numeric->LUbx ; + + m1 = ((size_t) maxblock) + 1 ; + + /* allocate workspace */ + nz = MAX (Numeric->max_lnz_block, Numeric->max_unz_block) ; + W = KLU_malloc (maxblock, sizeof (Int), Common) ; + Tp = KLU_malloc (m1, sizeof (Int), Common) ; + Ti = KLU_malloc (nz, sizeof (Int), Common) ; + Tx = KLU_malloc (nz, sizeof (Entry), Common) ; + + PRINTF (("\n======================= Start sort:\n")) ; + + if (Common->status == KLU_OK) + { + /* sort each block of L and U */ + for (block = 0 ; block < nblocks ; block++) + { + k1 = R [block] ; + nk = R [block+1] - k1 ; + if (nk > 1) + { + PRINTF (("\n-------------------block: %d nk %d\n", block, nk)) ; + sort (nk, Lip + k1, Llen + k1, LUbx [block], Tp, Ti, Tx, W) ; + sort (nk, Uip + k1, Ulen + k1, LUbx [block], Tp, Ti, Tx, W) ; + } + } + } + + PRINTF (("\n======================= sort done.\n")) ; + + /* free workspace */ + KLU_free (W, maxblock, sizeof (Int), Common) ; + KLU_free (Tp, m1, sizeof (Int), Common) ; + KLU_free (Ti, nz, sizeof (Int), Common) ; + KLU_free (Tx, nz, sizeof (Entry), Common) ; + return (Common->status == KLU_OK) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_tsolve.c b/OpenDSSC/klusolve/KLU/Source/klu_tsolve.c new file mode 100644 index 0000000..c06b5b2 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_tsolve.c @@ -0,0 +1,465 @@ +/* ========================================================================== */ +/* === KLU_tsolve =========================================================== */ +/* ========================================================================== */ + +/* Solve A'x=b using the symbolic and numeric objects from KLU_analyze + * (or KLU_analyze_given) and KLU_factor. Note that no iterative refinement is + * performed. Uses Numeric->Xwork as workspace (undefined on input and output), + * of size 4n Entry's (note that columns 2 to 4 of Xwork overlap with + * Numeric->Iwork). + */ + +#include "klu_internal.h" + +Int KLU_tsolve +( + /* inputs, not modified */ + KLU_symbolic *Symbolic, + KLU_numeric *Numeric, + Int d, /* leading dimension of B */ + Int nrhs, /* number of right-hand-sides */ + + /* right-hand-side on input, overwritten with solution to Ax=b on output */ + double B [ ], /* size n*nrhs, in column-oriented form, with + * leading dimension d. */ +#ifdef COMPLEX + Int conj_solve, /* TRUE for conjugate transpose solve, FALSE for + * array transpose solve. Used for the complex + * case only. */ +#endif + /* --------------- */ + KLU_common *Common +) +{ + Entry x [4], offik, s ; + double rs, *Rs ; + Entry *Offx, *X, *Bz, *Udiag ; + Int *Q, *R, *Pnum, *Offp, *Offi, *Lip, *Uip, *Llen, *Ulen ; + Unit **LUbx ; + Int k1, k2, nk, k, block, pend, n, p, nblocks, chunk, nr, i ; + + /* ---------------------------------------------------------------------- */ + /* check inputs */ + /* ---------------------------------------------------------------------- */ + + if (Common == NULL) + { + return (FALSE) ; + } + if (Numeric == NULL || Symbolic == NULL || d < Symbolic->n || nrhs < 0 || + B == NULL) + { + Common->status = KLU_INVALID ; + return (FALSE) ; + } + Common->status = KLU_OK ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Symbolic object */ + /* ---------------------------------------------------------------------- */ + + Bz = (Entry *) B ; + n = Symbolic->n ; + nblocks = Symbolic->nblocks ; + Q = Symbolic->Q ; + R = Symbolic->R ; + + /* ---------------------------------------------------------------------- */ + /* get the contents of the Numeric object */ + /* ---------------------------------------------------------------------- */ + + ASSERT (nblocks == Numeric->nblocks) ; + Pnum = Numeric->Pnum ; + Offp = Numeric->Offp ; + Offi = Numeric->Offi ; + Offx = (Entry *) Numeric->Offx ; + + Lip = Numeric->Lip ; + Llen = Numeric->Llen ; + Uip = Numeric->Uip ; + Ulen = Numeric->Ulen ; + LUbx = (Unit **) Numeric->LUbx ; + Udiag = Numeric->Udiag ; + + Rs = Numeric->Rs ; + X = (Entry *) Numeric->Xwork ; + ASSERT (KLU_valid (n, Offp, Offi, Offx)) ; + + /* ---------------------------------------------------------------------- */ + /* solve in chunks of 4 columns at a time */ + /* ---------------------------------------------------------------------- */ + + for (chunk = 0 ; chunk < nrhs ; chunk += 4) + { + + /* ------------------------------------------------------------------ */ + /* get the size of the current chunk */ + /* ------------------------------------------------------------------ */ + + nr = MIN (nrhs - chunk, 4) ; + + /* ------------------------------------------------------------------ */ + /* permute the right hand side, X = Q'*B */ + /* ------------------------------------------------------------------ */ + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + X [k] = Bz [Q [k]] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + X [2*k ] = Bz [i ] ; + X [2*k + 1] = Bz [i + d ] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + X [3*k ] = Bz [i ] ; + X [3*k + 1] = Bz [i + d ] ; + X [3*k + 2] = Bz [i + d*2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Q [k] ; + X [4*k ] = Bz [i ] ; + X [4*k + 1] = Bz [i + d ] ; + X [4*k + 2] = Bz [i + d*2] ; + X [4*k + 3] = Bz [i + d*3] ; + } + break ; + + } + + /* ------------------------------------------------------------------ */ + /* solve X = (L*U + Off)'\X */ + /* ------------------------------------------------------------------ */ + + for (block = 0 ; block < nblocks ; block++) + { + + /* -------------------------------------------------------------- */ + /* the block of size nk is from rows/columns k1 to k2-1 */ + /* -------------------------------------------------------------- */ + + k1 = R [block] ; + k2 = R [block+1] ; + nk = k2 - k1 ; + PRINTF (("tsolve %d, k1 %d k2-1 %d nk %d\n", block, k1,k2-1,nk)) ; + + /* -------------------------------------------------------------- */ + /* block back-substitution for the off-diagonal-block entries */ + /* -------------------------------------------------------------- */ + + if (block > 0) + { + switch (nr) + { + + case 1: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + for (p = Offp [k] ; p < pend ; p++) + { +#ifdef COMPLEX + if (conj_solve) + { + MULT_SUB_CONJ (X [k], X [Offi [p]], + Offx [p]) ; + } + else +#endif + { + MULT_SUB (X [k], Offx [p], X [Offi [p]]) ; + } + } + } + break ; + + case 2: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [2*k ] ; + x [1] = X [2*k + 1] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (offik, Offx [p]) ; + } + else +#endif + { + offik = Offx [p] ; + } + MULT_SUB (x [0], offik, X [2*i]) ; + MULT_SUB (x [1], offik, X [2*i + 1]) ; + } + X [2*k ] = x [0] ; + X [2*k + 1] = x [1] ; + } + break ; + + case 3: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [3*k ] ; + x [1] = X [3*k + 1] ; + x [2] = X [3*k + 2] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ (offik, Offx [p]) ; + } + else +#endif + { + offik = Offx [p] ; + } + MULT_SUB (x [0], offik, X [3*i]) ; + MULT_SUB (x [1], offik, X [3*i + 1]) ; + MULT_SUB (x [2], offik, X [3*i + 2]) ; + } + X [3*k ] = x [0] ; + X [3*k + 1] = x [1] ; + X [3*k + 2] = x [2] ; + } + break ; + + case 4: + + for (k = k1 ; k < k2 ; k++) + { + pend = Offp [k+1] ; + x [0] = X [4*k ] ; + x [1] = X [4*k + 1] ; + x [2] = X [4*k + 2] ; + x [3] = X [4*k + 3] ; + for (p = Offp [k] ; p < pend ; p++) + { + i = Offi [p] ; +#ifdef COMPLEX + if (conj_solve) + { + CONJ(offik, Offx [p]) ; + } + else +#endif + { + offik = Offx [p] ; + } + MULT_SUB (x [0], offik, X [4*i]) ; + MULT_SUB (x [1], offik, X [4*i + 1]) ; + MULT_SUB (x [2], offik, X [4*i + 2]) ; + MULT_SUB (x [3], offik, X [4*i + 3]) ; + } + X [4*k ] = x [0] ; + X [4*k + 1] = x [1] ; + X [4*k + 2] = x [2] ; + X [4*k + 3] = x [3] ; + } + break ; + } + } + + /* -------------------------------------------------------------- */ + /* solve the block system */ + /* -------------------------------------------------------------- */ + + if (nk == 1) + { +#ifdef COMPLEX + if (conj_solve) + { + CONJ (s, Udiag [k1]) ; + } + else +#endif + { + s = Udiag [k1] ; + } + switch (nr) + { + + case 1: + DIV (X [k1], X [k1], s) ; + break ; + + case 2: + DIV (X [2*k1], X [2*k1], s) ; + DIV (X [2*k1 + 1], X [2*k1 + 1], s) ; + break ; + + case 3: + DIV (X [3*k1], X [3*k1], s) ; + DIV (X [3*k1 + 1], X [3*k1 + 1], s) ; + DIV (X [3*k1 + 2], X [3*k1 + 2], s) ; + break ; + + case 4: + DIV (X [4*k1], X [4*k1], s) ; + DIV (X [4*k1 + 1], X [4*k1 + 1], s) ; + DIV (X [4*k1 + 2], X [4*k1 + 2], s) ; + DIV (X [4*k1 + 3], X [4*k1 + 3], s) ; + break ; + + } + } + else + { + KLU_utsolve (nk, Uip + k1, Ulen + k1, LUbx [block], + Udiag + k1, nr, +#ifdef COMPLEX + conj_solve, +#endif + X + nr*k1) ; + KLU_ltsolve (nk, Lip + k1, Llen + k1, LUbx [block], nr, +#ifdef COMPLEX + conj_solve, +#endif + X + nr*k1) ; + } + } + + /* ------------------------------------------------------------------ */ + /* scale and permute the result, Bz = P'(R\X) */ + /* ------------------------------------------------------------------ */ + + if (Rs == NULL) + { + + /* no scaling */ + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + Bz [Pnum [k]] = X [k] ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + Bz [i ] = X [2*k ] ; + Bz [i + d ] = X [2*k + 1] ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + Bz [i ] = X [3*k ] ; + Bz [i + d ] = X [3*k + 1] ; + Bz [i + d*2] = X [3*k + 2] ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + Bz [i ] = X [4*k ] ; + Bz [i + d ] = X [4*k + 1] ; + Bz [i + d*2] = X [4*k + 2] ; + Bz [i + d*3] = X [4*k + 3] ; + } + break ; + } + + } + else + { + + switch (nr) + { + + case 1: + + for (k = 0 ; k < n ; k++) + { + SCALE_DIV_ASSIGN (Bz [Pnum [k]], X [k], Rs [k]) ; + } + break ; + + case 2: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (Bz [i], X [2*k], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d], X [2*k + 1], rs) ; + } + break ; + + case 3: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (Bz [i], X [3*k], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d], X [3*k + 1], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d*2], X [3*k + 2], rs) ; + } + break ; + + case 4: + + for (k = 0 ; k < n ; k++) + { + i = Pnum [k] ; + rs = Rs [k] ; + SCALE_DIV_ASSIGN (Bz [i], X [4*k], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d], X [4*k + 1], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d*2], X [4*k + 2], rs) ; + SCALE_DIV_ASSIGN (Bz [i + d*3], X [4*k + 3], rs) ; + } + break ; + } + } + + /* ------------------------------------------------------------------ */ + /* go to the next chunk of B */ + /* ------------------------------------------------------------------ */ + + Bz += d*4 ; + } + return (TRUE) ; +} diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z.c b/OpenDSSC/klusolve/KLU/Source/klu_z.c new file mode 100644 index 0000000..5bf5d7e --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_diagnostics.c b/OpenDSSC/klusolve/KLU/Source/klu_z_diagnostics.c new file mode 100644 index 0000000..344c975 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_diagnostics.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_diagnostics.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_dump.c b/OpenDSSC/klusolve/KLU/Source/klu_z_dump.c new file mode 100644 index 0000000..ef7bb2d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_dump.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_dump.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_extract.c b/OpenDSSC/klusolve/KLU/Source/klu_z_extract.c new file mode 100644 index 0000000..d44ee97 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_extract.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_extract.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_factor.c b/OpenDSSC/klusolve/KLU/Source/klu_z_factor.c new file mode 100644 index 0000000..3271f0e --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_factor.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_factor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_free_numeric.c b/OpenDSSC/klusolve/KLU/Source/klu_z_free_numeric.c new file mode 100644 index 0000000..220164d --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_free_numeric.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_free_numeric.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_kernel.c b/OpenDSSC/klusolve/KLU/Source/klu_z_kernel.c new file mode 100644 index 0000000..90a981f --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_kernel.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_kernel.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_refactor.c b/OpenDSSC/klusolve/KLU/Source/klu_z_refactor.c new file mode 100644 index 0000000..a81fd64 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_refactor.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_refactor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_scale.c b/OpenDSSC/klusolve/KLU/Source/klu_z_scale.c new file mode 100644 index 0000000..c8bd42a --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_scale.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_scale.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_solve.c b/OpenDSSC/klusolve/KLU/Source/klu_z_solve.c new file mode 100644 index 0000000..abe38bc --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_solve.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_solve.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_sort.c b/OpenDSSC/klusolve/KLU/Source/klu_z_sort.c new file mode 100644 index 0000000..fdff748 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_sort.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_sort.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_z_tsolve.c b/OpenDSSC/klusolve/KLU/Source/klu_z_tsolve.c new file mode 100644 index 0000000..40c1ffc --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_z_tsolve.c @@ -0,0 +1,2 @@ +#define COMPLEX 1 +#include "klu_tsolve.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl.c b/OpenDSSC/klusolve/KLU/Source/klu_zl.c new file mode 100644 index 0000000..c3544ca --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_diagnostics.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_diagnostics.c new file mode 100644 index 0000000..f8a1700 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_diagnostics.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_diagnostics.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_dump.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_dump.c new file mode 100644 index 0000000..9367cb7 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_dump.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_dump.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_extract.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_extract.c new file mode 100644 index 0000000..e3e8e20 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_extract.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_extract.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_factor.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_factor.c new file mode 100644 index 0000000..45a0388 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_factor.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_factor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_free_numeric.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_free_numeric.c new file mode 100644 index 0000000..26126fb --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_free_numeric.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_free_numeric.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_kernel.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_kernel.c new file mode 100644 index 0000000..15ca1d8 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_kernel.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_kernel.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_refactor.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_refactor.c new file mode 100644 index 0000000..eb82f07 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_refactor.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_refactor.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_scale.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_scale.c new file mode 100644 index 0000000..655cec9 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_scale.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_scale.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_solve.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_solve.c new file mode 100644 index 0000000..21d6975 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_solve.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_solve.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_sort.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_sort.c new file mode 100644 index 0000000..26ab857 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_sort.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_sort.c" diff --git a/OpenDSSC/klusolve/KLU/Source/klu_zl_tsolve.c b/OpenDSSC/klusolve/KLU/Source/klu_zl_tsolve.c new file mode 100644 index 0000000..a451c2e --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Source/klu_zl_tsolve.c @@ -0,0 +1,3 @@ +#define COMPLEX 1 +#define DLONG 1 +#include "klu_tsolve.c" diff --git a/OpenDSSC/klusolve/KLU/Tcov/Makefile b/OpenDSSC/klusolve/KLU/Tcov/Makefile new file mode 100644 index 0000000..a4fc665 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/Makefile @@ -0,0 +1,420 @@ +# If the libraries (AMD, COLAMD, CAMD, CCOLAMD, metis, and CHOLMOD) are not +# yet built, use "make libs" first. Then "make" to compile and run all tests. + +default: all + +include ../../UFconfig/UFconfig.mk + +# CFLAGS = -Wall -W -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ +# -Wredundant-decls -Wnested-externs -Wdisabled-optimization \ +# -pedantic -ansi -O3 -pg + +# for statement coverage, picky tests +CFLAGS = -Wall -W -Werror -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ + -Wredundant-decls -Wnested-externs -Wdisabled-optimization \ + -ansi -g -ftest-coverage -fprofile-arcs -fexceptions + +C = $(CC) $(CFLAGS) + +LIB = ../../AMD/Lib/libamd.a ../../COLAMD/Lib/libcolamd.a \ + ../../CHOLMOD/Lib/libcholmod.a \ + ../../CAMD/Lib/libcamd.a ../../CCOLAMD/Lib/libccolamd.a \ + ../../metis-4.0/libmetis.a \ + -lm + +I = -I../../UFconfig -I../../AMD/Include -I../../COLAMD/Include \ + -I../../BTF/Include -I../../CHOLMOD/Include -I../../CAMD/Include \ + -I../../CCOLAMD/Include -I../../metis-4.0/Lib -I../Include -I../User + +PRETTY = grep -v "^\#" | indent -bl -nce -ss -bli0 -i4 -sob + +all: purge libs klutest klultest + - ./klultests > klultests.out + - ./klutests > klutests.out + - ./coverage + +valgrind: purge klutest klultest + - ./vklutests > klutests.out + - ./vklultests > klultests.out + - ./coverage + +libs: + ( cd ../../AMD ; $(MAKE) library ) + ( cd ../../COLAMD ; $(MAKE) library ) + ( cd ../../CAMD ; $(MAKE) library ) + ( cd ../../CCOLAMD ; $(MAKE) library ) + ( cd ../../metis-4.0 ; $(MAKE) ) + ( cd ../../CHOLMOD ; $(MAKE) library ) + +purge: distclean + +distclean: clean + - $(RM) klutest klultest *.c.gcov *.out *.a cov_*.c *.gcda *.gcno + +clean: + - $(RM) $(CLEAN) + +INC = \ + ../Include/klu.h \ + ../Include/klu_internal.h \ + ../Include/klu_version.h + +BTFOBJ = \ + cov_btf_order.o \ + cov_btf_maxtrans.o \ + cov_btf_strongcomp.o \ + +BTFLOBJ = \ + cov_btf_l_order.o \ + cov_btf_l_maxtrans.o \ + cov_btf_l_strongcomp.o + +KLUOBJ = \ + cov_klu_analyze.o \ + cov_klu_analyze_given.o \ + cov_klu_defaults.o \ + cov_klu_free_symbolic.o \ + cov_klu_memory.o \ + cov_klu_d.o \ + cov_klu_d_diagnostics.o \ + cov_klu_d_dump.o \ + cov_klu_d_factor.o \ + cov_klu_d_free_numeric.o \ + cov_klu_d_kernel.o \ + cov_klu_d_extract.o \ + cov_klu_d_refactor.o \ + cov_klu_d_scale.o \ + cov_klu_d_solve.o \ + cov_klu_d_tsolve.o \ + cov_klu_z.o \ + cov_klu_z_diagnostics.o \ + cov_klu_z_dump.o \ + cov_klu_z_factor.o \ + cov_klu_z_free_numeric.o \ + cov_klu_z_kernel.o \ + cov_klu_z_extract.o \ + cov_klu_z_refactor.o \ + cov_klu_z_scale.o \ + cov_klu_z_solve.o \ + cov_klu_z_tsolve.o + +KLULOBJ = \ + cov_klu_l_analyze.o \ + cov_klu_l_analyze_given.o \ + cov_klu_l_defaults.o \ + cov_klu_l_free_symbolic.o \ + cov_klu_l_memory.o \ + cov_klu_l.o \ + cov_klu_l_diagnostics.o \ + cov_klu_l_dump.o \ + cov_klu_l_factor.o \ + cov_klu_l_free_numeric.o \ + cov_klu_l_kernel.o \ + cov_klu_l_extract.o \ + cov_klu_l_refactor.o \ + cov_klu_l_scale.o \ + cov_klu_l_solve.o \ + cov_klu_l_tsolve.o \ + cov_klu_zl.o \ + cov_klu_zl_diagnostics.o \ + cov_klu_zl_dump.o \ + cov_klu_zl_factor.o \ + cov_klu_zl_free_numeric.o \ + cov_klu_zl_kernel.o \ + cov_klu_zl_extract.o \ + cov_klu_zl_refactor.o \ + cov_klu_zl_scale.o \ + cov_klu_zl_solve.o \ + cov_klu_zl_tsolve.o + +KLUCHOLMODOBJ = cov_klu_cholmod.o + +KLUCHOLMODLOBJ = cov_klu_l_cholmod.o + +OBJ = $(BTFOBJ) $(KLUOBJ) $(KLUCHOLMODOBJ) + +LOBJ = $(BTFLOBJ) $(KLULOBJ) $(KLUCHOLMODLOBJ) + +$(OBJ): $(INC) + +$(LOBJ): $(INC) + +klutest: $(OBJ) klutest.c + $(C) $(I) klutest.c -o klutest $(OBJ) $(LIB) + +klultest: $(LOBJ) klutest.c + $(C) -DDLONG $(I) klutest.c -o klultest $(LOBJ) $(LIB) + +.c.o: + $(C) -c $(I) $*.c + +#------------------------------------------------------------------------------- + +cov_klu_d.o: ../Source/klu.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d.c + $(C) -c $(I) cov_klu_d.c + +cov_klu_z.o: ../Source/klu.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z.c + $(C) -c $(I) cov_klu_z.c + +cov_klu_d_kernel.o: ../Source/klu_kernel.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_kernel.c + $(C) -c $(I) cov_klu_d_kernel.c + +cov_klu_z_kernel.o: ../Source/klu_kernel.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_kernel.c + $(C) -c $(I) cov_klu_z_kernel.c + +cov_klu_d_diagnostics.o: ../Source/klu_diagnostics.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_diagnostics.c + $(C) -c $(I) cov_klu_d_diagnostics.c + +cov_klu_z_diagnostics.o: ../Source/klu_diagnostics.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_diagnostics.c + $(C) -c $(I) cov_klu_z_diagnostics.c + +cov_klu_d_dump.o: ../Source/klu_dump.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_dump.c + $(C) -c $(I) cov_klu_d_dump.c + +cov_klu_z_dump.o: ../Source/klu_dump.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_dump.c + $(C) -c $(I) cov_klu_z_dump.c + +cov_klu_d_factor.o: ../Source/klu_factor.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_factor.c + $(C) -c $(I) cov_klu_d_factor.c + +cov_klu_z_factor.o: ../Source/klu_factor.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_factor.c + $(C) -c $(I) cov_klu_z_factor.c + +cov_klu_d_free_numeric.o: ../Source/klu_free_numeric.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_free_numeric.c + $(C) -c $(I) cov_klu_d_free_numeric.c + +cov_klu_z_free_numeric.o: ../Source/klu_free_numeric.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_free_numeric.c + $(C) -c $(I) cov_klu_z_free_numeric.c + +cov_klu_d_extract.o: ../Source/klu_extract.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_extract.c + $(C) -c $(I) cov_klu_d_extract.c + +cov_klu_z_extract.o: ../Source/klu_extract.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_extract.c + $(C) -c $(I) cov_klu_z_extract.c + +cov_klu_d_refactor.o: ../Source/klu_refactor.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_refactor.c + $(C) -c $(I) cov_klu_d_refactor.c + +cov_klu_z_refactor.o: ../Source/klu_refactor.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_refactor.c + $(C) -c $(I) cov_klu_z_refactor.c + +cov_klu_d_scale.o: ../Source/klu_scale.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_scale.c + $(C) -c $(I) cov_klu_d_scale.c + +cov_klu_z_scale.o: ../Source/klu_scale.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_scale.c + $(C) -c $(I) cov_klu_z_scale.c + +cov_klu_d_solve.o: ../Source/klu_solve.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_solve.c + $(C) -c $(I) cov_klu_d_solve.c + +cov_klu_z_solve.o: ../Source/klu_solve.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_solve.c + $(C) -c $(I) cov_klu_z_solve.c + +cov_klu_d_tsolve.o: ../Source/klu_tsolve.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_d_tsolve.c + $(C) -c $(I) cov_klu_d_tsolve.c + +cov_klu_z_tsolve.o: ../Source/klu_tsolve.c + $(C) -E $(I) -DCOMPLEX $< | $(PRETTY) > cov_klu_z_tsolve.c + $(C) -c $(I) cov_klu_z_tsolve.c + +#------------------------------------------------------------------------------- + +cov_klu_analyze.o: ../Source/klu_analyze.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_analyze.c + $(C) -c $(I) cov_klu_analyze.c + +cov_klu_analyze_given.o: ../Source/klu_analyze_given.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_analyze_given.c + $(C) -c $(I) cov_klu_analyze_given.c + +cov_klu_defaults.o: ../Source/klu_defaults.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_defaults.c + $(C) -c $(I) cov_klu_defaults.c + +cov_klu_free_symbolic.o: ../Source/klu_free_symbolic.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_free_symbolic.c + $(C) -c $(I) cov_klu_free_symbolic.c + +cov_klu_memory.o: ../Source/klu_memory.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_memory.c + $(C) -c $(I) cov_klu_memory.c + +#------------------------------------------------------------------------------- + +cov_btf_order.o: ../../BTF/Source/btf_order.c + $(C) -E $(I) $< | $(PRETTY) > cov_btf_order.c + $(C) -c $(I) cov_btf_order.c + +cov_btf_maxtrans.o: ../../BTF/Source/btf_maxtrans.c + $(C) -E $(I) $< | $(PRETTY) > cov_btf_maxtrans.c + $(C) -c $(I) cov_btf_maxtrans.c + +cov_btf_strongcomp.o: ../../BTF/Source/btf_strongcomp.c + $(C) -E $(I) $< | $(PRETTY) > cov_btf_strongcomp.c + $(C) -c $(I) cov_btf_strongcomp.c + +#------------------------------------------------------------------------------- + +cov_klu_cholmod.o: ../User/klu_cholmod.c + $(C) -E $(I) $< | $(PRETTY) > cov_klu_cholmod.c + $(C) -c $(I) cov_klu_cholmod.c + + + + + + + +#------------------------------------------------------------------------------- + +cov_klu_l.o: ../Source/klu.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l.c + $(C) -c $(I) cov_klu_l.c + +cov_klu_zl.o: ../Source/klu.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl.c + $(C) -c $(I) cov_klu_zl.c + +cov_klu_l_kernel.o: ../Source/klu_kernel.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_kernel.c + $(C) -c $(I) cov_klu_l_kernel.c + +cov_klu_zl_kernel.o: ../Source/klu_kernel.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_kernel.c + $(C) -c $(I) cov_klu_zl_kernel.c + +cov_klu_l_diagnostics.o: ../Source/klu_diagnostics.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_diagnostics.c + $(C) -c $(I) cov_klu_l_diagnostics.c + +cov_klu_zl_diagnostics.o: ../Source/klu_diagnostics.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_diagnostics.c + $(C) -c $(I) cov_klu_zl_diagnostics.c + +cov_klu_l_dump.o: ../Source/klu_dump.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_dump.c + $(C) -c $(I) cov_klu_l_dump.c + +cov_klu_zl_dump.o: ../Source/klu_dump.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_dump.c + $(C) -c $(I) cov_klu_zl_dump.c + +cov_klu_l_factor.o: ../Source/klu_factor.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_factor.c + $(C) -c $(I) cov_klu_l_factor.c + +cov_klu_zl_factor.o: ../Source/klu_factor.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_factor.c + $(C) -c $(I) cov_klu_zl_factor.c + +cov_klu_l_free_numeric.o: ../Source/klu_free_numeric.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_free_numeric.c + $(C) -c $(I) cov_klu_l_free_numeric.c + +cov_klu_zl_free_numeric.o: ../Source/klu_free_numeric.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_free_numeric.c + $(C) -c $(I) cov_klu_zl_free_numeric.c + +cov_klu_l_extract.o: ../Source/klu_extract.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_extract.c + $(C) -c $(I) cov_klu_l_extract.c + +cov_klu_zl_extract.o: ../Source/klu_extract.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_extract.c + $(C) -c $(I) cov_klu_zl_extract.c + +cov_klu_l_refactor.o: ../Source/klu_refactor.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_refactor.c + $(C) -c $(I) cov_klu_l_refactor.c + +cov_klu_zl_refactor.o: ../Source/klu_refactor.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_refactor.c + $(C) -c $(I) cov_klu_zl_refactor.c + +cov_klu_l_scale.o: ../Source/klu_scale.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_scale.c + $(C) -c $(I) cov_klu_l_scale.c + +cov_klu_zl_scale.o: ../Source/klu_scale.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_scale.c + $(C) -c $(I) cov_klu_zl_scale.c + +cov_klu_l_solve.o: ../Source/klu_solve.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_solve.c + $(C) -c $(I) cov_klu_l_solve.c + +cov_klu_zl_solve.o: ../Source/klu_solve.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_solve.c + $(C) -c $(I) cov_klu_zl_solve.c + +cov_klu_l_tsolve.o: ../Source/klu_tsolve.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_tsolve.c + $(C) -c $(I) cov_klu_l_tsolve.c + +cov_klu_zl_tsolve.o: ../Source/klu_tsolve.c + $(C) -E $(I) -DDLONG -DCOMPLEX $< | $(PRETTY) > cov_klu_zl_tsolve.c + $(C) -c $(I) cov_klu_zl_tsolve.c + +#------------------------------------------------------------------------------- + +cov_klu_l_analyze.o: ../Source/klu_analyze.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_analyze.c + $(C) -c $(I) cov_klu_l_analyze.c + +cov_klu_l_analyze_given.o: ../Source/klu_analyze_given.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_analyze_given.c + $(C) -c $(I) cov_klu_l_analyze_given.c + +cov_klu_l_defaults.o: ../Source/klu_defaults.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_defaults.c + $(C) -c $(I) cov_klu_l_defaults.c + +cov_klu_l_free_symbolic.o: ../Source/klu_free_symbolic.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_free_symbolic.c + $(C) -c $(I) cov_klu_l_free_symbolic.c + +cov_klu_l_memory.o: ../Source/klu_memory.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_memory.c + $(C) -c $(I) cov_klu_l_memory.c + +#------------------------------------------------------------------------------- + +cov_btf_l_order.o: ../../BTF/Source/btf_order.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_btf_l_order.c + $(C) -c $(I) cov_btf_l_order.c + +cov_btf_l_maxtrans.o: ../../BTF/Source/btf_maxtrans.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_btf_l_maxtrans.c + $(C) -c $(I) cov_btf_l_maxtrans.c + +cov_btf_l_strongcomp.o: ../../BTF/Source/btf_strongcomp.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_btf_l_strongcomp.c + $(C) -c $(I) cov_btf_l_strongcomp.c + +#------------------------------------------------------------------------------- + +cov_klu_l_cholmod.o: ../User/klu_l_cholmod.c + $(C) -E $(I) -DDLONG $< | $(PRETTY) > cov_klu_l_cholmod.c + $(C) -c $(I) cov_klu_l_cholmod.c + diff --git a/OpenDSSC/klusolve/KLU/Tcov/README.txt b/OpenDSSC/klusolve/KLU/Tcov/README.txt new file mode 100644 index 0000000..8ecec0a --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/README.txt @@ -0,0 +1,5 @@ +Test suite for KLU + +To compile and run the test suite, first type "make" in the Linux/Unix shell. +The libraries must be compiled first (if they aren't use "make libs"). +"make clean" or "make distclean" will remove all unnecessary files. diff --git a/OpenDSSC/klusolve/KLU/Tcov/coverage b/OpenDSSC/klusolve/KLU/Tcov/coverage new file mode 100644 index 0000000..c081588 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/coverage @@ -0,0 +1,4 @@ +#!/bin/csh +gcov cov*.c >& /dev/null +echo -n 'statements not covered: ' +grep "#####" *.c.gcov | wc -l diff --git a/OpenDSSC/klusolve/KLU/Tcov/klultests b/OpenDSSC/klusolve/KLU/Tcov/klultests new file mode 100644 index 0000000..98f2734 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/klultests @@ -0,0 +1,31 @@ +#!/bin/csh + +# 57 unique statements: +./klultest < ../Matrix/impcol_a.mtx + +# 20: +./klultest < ../Matrix/GD99_cc.mtx + +# 17: +./klultest < ../Matrix/two.mtx + +# 10: +./klultest < ../Matrix/w156.mtx + +# 3, xsize memgrow in klu_kernel +./klultest < ../Matrix/arrow.mtx + +# 3, xsize memgrow in klu_kernel, 1 in klu_z_condest, +./klultest < ../Matrix/arrowc.mtx + +# 2 in klu_z_kernel (if pivot == 0 and halt_if_singular, and in complex divide) +./klultest < ../Matrix/onec.mtx + +# 1 in klu_kernel (if pivot == 0 and halt if singular) +./klultest < ../Matrix/one.mtx + +# 1 in klu_z_condest: +./klultest < ../Matrix/1c.mtx + +# 1 in klu_z_condest: +./klultest < ../Matrix/ctina.mtx diff --git a/OpenDSSC/klusolve/KLU/Tcov/klutest.c b/OpenDSSC/klusolve/KLU/Tcov/klutest.c new file mode 100644 index 0000000..ea8b491 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/klutest.c @@ -0,0 +1,1377 @@ +/* ========================================================================== */ +/* === KLU test ============================================================= */ +/* ========================================================================== */ + +/* Exhaustive test for KLU and BTF (int, long, real, and complex versions) */ + +#include +#include "cholmod.h" +#include "klu_cholmod.h" +#include "klu_internal.h" + +#define ID Int_id + +#define NRHS 6 + +#define HALT { fprintf (stderr, "Test failure: %d\n", __LINE__) ; abort () ; } +#define OK(a) { if (!(a)) HALT ; } +#define FAIL(a) { if (a) HALT ; } + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + + +#ifdef DLONG + +#define klu_z_scale klu_zl_scale +#define klu_z_solve klu_zl_solve +#define klu_z_tsolve klu_zl_tsolve +#define klu_z_free_numeric klu_zl_free_numeric +#define klu_z_factor klu_zl_factor +#define klu_z_refactor klu_zl_refactor +#define klu_z_lsolve klu_zl_lsolve +#define klu_z_ltsolve klu_zl_ltsolve +#define klu_z_usolve klu_zl_usolve +#define klu_z_utsolve klu_zl_utsolve +#define klu_z_defaults klu_zl_defaults +#define klu_z_rgrowth klu_zl_rgrowth +#define klu_z_rcond klu_zl_rcond +#define klu_z_extract klu_zl_extract +#define klu_z_condest klu_zl_condest +#define klu_z_flops klu_zl_flops + +#define klu_scale klu_l_scale +#define klu_solve klu_l_solve +#define klu_tsolve klu_l_tsolve +#define klu_free_numeric klu_l_free_numeric +#define klu_factor klu_l_factor +#define klu_refactor klu_l_refactor +#define klu_lsolve klu_l_lsolve +#define klu_ltsolve klu_l_ltsolve +#define klu_usolve klu_l_usolve +#define klu_utsolve klu_l_utsolve +#define klu_defaults klu_l_defaults +#define klu_rgrowth klu_l_rgrowth +#define klu_rcond klu_l_rcond +#define klu_extract klu_l_extract +#define klu_condest klu_l_condest +#define klu_flops klu_l_flops + +#define klu_analyze klu_l_analyze +#define klu_analyze_given klu_l_analyze_given +#define klu_malloc klu_l_malloc +#define klu_free klu_l_free +#define klu_realloc klu_l_realloc +#define klu_free_symbolic klu_l_free_symbolic +#define klu_free_numeric klu_l_free_numeric +#define klu_defaults klu_l_defaults + +#define klu_cholmod klu_l_cholmod + +#endif + + +#ifdef DLONG + +#define CHOLMOD_print_sparse cholmod_l_print_sparse +#define CHOLMOD_print_dense cholmod_l_print_dense +#define CHOLMOD_copy_sparse cholmod_l_copy_sparse +#define CHOLMOD_copy_dense cholmod_l_copy_dense +#define CHOLMOD_transpose cholmod_l_transpose +#define CHOLMOD_sdmult cholmod_l_sdmult +#define CHOLMOD_norm_dense cholmod_l_norm_dense +#define CHOLMOD_norm_sparse cholmod_l_norm_sparse +#define CHOLMOD_free_sparse cholmod_l_free_sparse +#define CHOLMOD_free_dense cholmod_l_free_dense +#define CHOLMOD_start cholmod_l_start +#define CHOLMOD_read_sparse cholmod_l_read_sparse +#define CHOLMOD_allocate_dense cholmod_l_allocate_dense +#define CHOLMOD_finish cholmod_l_finish + +#else + +#define CHOLMOD_print_sparse cholmod_print_sparse +#define CHOLMOD_print_dense cholmod_print_dense +#define CHOLMOD_copy_sparse cholmod_copy_sparse +#define CHOLMOD_copy_dense cholmod_copy_dense +#define CHOLMOD_transpose cholmod_transpose +#define CHOLMOD_sdmult cholmod_sdmult +#define CHOLMOD_norm_dense cholmod_norm_dense +#define CHOLMOD_norm_sparse cholmod_norm_sparse +#define CHOLMOD_free_sparse cholmod_free_sparse +#define CHOLMOD_free_dense cholmod_free_dense +#define CHOLMOD_start cholmod_start +#define CHOLMOD_read_sparse cholmod_read_sparse +#define CHOLMOD_allocate_dense cholmod_allocate_dense +#define CHOLMOD_finish cholmod_finish + +#endif + +/* ========================================================================== */ +/* === random numbers ======================================================= */ +/* ========================================================================== */ + +#define MY_RAND_MAX 32767 + +static unsigned long next = 1 ; + +static Int my_rand (void) +{ + next = next * 1103515245 + 12345 ; + return ((unsigned)(next/65536) % (MY_RAND_MAX+1)) ; +} + +static void my_srand (unsigned seed) +{ + next = seed ; +} + +/* ========================================================================== */ +/* === memory management ==================================================== */ +/* ========================================================================== */ + +void *my_malloc (size_t size) ; +void *my_calloc (size_t n, size_t size) ; +void *my_realloc (void *p, size_t size) ; + +Int my_tries = -1 ; + +void *my_malloc (size_t size) +{ + if (my_tries == 0) return (NULL) ; /* pretend to fail */ + if (my_tries > 0) my_tries-- ; + return (malloc (size)) ; +} + +void *my_calloc (size_t n, size_t size) +{ + if (my_tries == 0) return (NULL) ; /* pretend to fail */ + if (my_tries > 0) my_tries-- ; + return (calloc (n, size)) ; +} + +void *my_realloc (void *p, size_t size) +{ + if (my_tries == 0) return (NULL) ; /* pretend to fail */ + if (my_tries > 0) my_tries-- ; + return (realloc (p, size)) ; +} + +static void normal_memory_handler (KLU_common *Common) +{ + Common->malloc_memory = malloc ; + Common->calloc_memory = calloc ; + Common->realloc_memory = realloc ; + Common->free_memory = free ; + my_tries = -1 ; +} + +static void test_memory_handler (KLU_common *Common) +{ + Common->malloc_memory = my_malloc ; + Common->calloc_memory = my_calloc ; + Common->realloc_memory = my_realloc ; + Common->free_memory = free ; + my_tries = -1 ; +} + + +/* ========================================================================== */ +/* === print_sparse ========================================================= */ +/* ========================================================================== */ + +/* print a sparse matrix */ + +static void print_sparse (Int n, Int isreal, Int *Ap, Int *Ai, double *Ax, + double *Az) +{ + double ax, az ; + Int i, j, p ; + for (j = 0 ; j < n ; j++) + { + printf ("column "ID":\n", j) ; + for (p = Ap [j] ; p < Ap [j+1] ; p++) + { + i = Ai [p] ; + if (isreal) + { + ax = Ax [p] ; + az = 0 ; + } + else if (Az) + { + /* split complex */ + ax = Ax [p] ; + az = Az [p] ; + } + else + { + /* merged complex */ + ax = Ax [2*p ] ; + az = Ax [2*p+1] ; + } + printf (" row "ID" : %g", i, ax) ; + if (!isreal) + { + printf (" + (%g)i", az) ; + } + printf ("\n") ; + } + } + fflush (stdout) ; +} + + +/* ========================================================================== */ +/* === print_int ============================================================ */ +/* ========================================================================== */ + +/* print an Int vector */ + +static void print_int (Int n, Int *P) +{ + Int j ; + for (j = 0 ; j < n ; j++) + { + printf (" "ID" : "ID"\n", j, P [j]) ; + } + fflush (stdout) ; +} + + +/* ========================================================================== */ +/* === print_double ========================================================= */ +/* ========================================================================== */ + +/* print a double vector */ + +static void print_double (Int n, double *X) +{ + Int j ; + for (j = 0 ; j < n ; j++) + { + printf (" "ID" : %g\n", j, X [j]) ; + } + fflush (stdout) ; +} + + +/* ========================================================================== */ +/* === ludump =============================================================== */ +/* ========================================================================== */ + +/* extract and print the LU factors */ + +static void ludump (KLU_symbolic *Symbolic, KLU_numeric *Numeric, Int isreal, + cholmod_common *ch, KLU_common *Common) +{ + Int *Lp, *Li, *Up, *Ui, *Fp, *Fi, *P, *Q, *R ; + double *Lx, *Ux, *Fx, *Lz, *Uz, *Fz, *Rs ; + Int n, lnz, unz, fnz, nb, result ; + + if (Symbolic == NULL || Numeric == NULL) + { + return ; + } + + n = Symbolic->n ; + lnz = Numeric->lnz ; + unz = Numeric->unz ; + fnz = Numeric->Offp [n] ; + nb = Symbolic->nblocks ; + + printf ("n "ID" lnz "ID" unz "ID" fnz "ID" nblocks "ID" isreal "ID"\n", + n, lnz, unz, fnz, nb, isreal) ; + fflush (stdout) ; + + Lp = malloc ((n+1) * sizeof (Int)) ; + Li = malloc (lnz * sizeof (Int)) ; + Lx = malloc (lnz * sizeof (double)) ; + Lz = malloc (lnz * sizeof (double)) ; + + Up = malloc ((n+1) * sizeof (Int)) ; + Ui = malloc (unz * sizeof (Int)) ; + Ux = malloc (unz * sizeof (double)) ; + Uz = malloc (unz * sizeof (double)) ; + + Fp = malloc ((n+1) * sizeof (Int)) ; + Fi = malloc (fnz * sizeof (Int)) ; + Fx = malloc (fnz * sizeof (double)) ; + Fz = malloc (fnz * sizeof (double)) ; + + P = malloc (n * sizeof (Int)) ; + Q = malloc (n * sizeof (Int)) ; + Rs = malloc (n * sizeof (double)) ; + R = malloc ((nb+1) * sizeof (double)) ; + + if (isreal) + { + result = klu_extract (Numeric, Symbolic, Lp, Li, Lx, + Up, Ui, Ux, Fp, Fi, Fx, P, Q, Rs, R, Common) ; + } + else + { + result = klu_z_extract (Numeric, Symbolic, Lp, Li, Lx, Lz, + Up, Ui, Ux, Uz, Fp, Fi, Fx, Fz, P, Q, Rs, R, Common) ; + } + + if (my_tries != 0) OK (result) ; + + if (ch->print >= 5) + { + printf ("------ L:\n") ; print_sparse (n, isreal, Lp, Li, Lx, Lz) ; + printf ("------ U:\n") ; print_sparse (n, isreal, Up, Ui, Ux, Uz) ; + printf ("------ F:\n") ; print_sparse (n, isreal, Fp, Fi, Fx, Fz) ; + printf ("------ P:\n") ; print_int (n, P) ; + printf ("------ Q:\n") ; print_int (n, Q) ; + printf ("------ Rs:\n") ; print_double (n, Rs) ; + printf ("------ R:\n") ; print_int (nb+1, R) ; + } + + free (Lp) ; + free (Li) ; + free (Lx) ; + free (Lz) ; + + free (Up) ; + free (Ui) ; + free (Ux) ; + free (Uz) ; + + free (Fp) ; + free (Fi) ; + free (Fx) ; + free (Fz) ; + + free (P) ; + free (Q) ; + free (Rs) ; + free (R) ; +} + + +/* ========================================================================== */ +/* === randperm ============================================================= */ +/* ========================================================================== */ + +/* return a random permutation vector */ + +static Int *randperm (Int n, Int seed) +{ + Int *p, k, j, t ; + p = malloc (n * sizeof (Int)) ; + for (k = 0 ; k < n ; k++) + { + p [k] = k ; + } + my_srand (seed) ; /* get new random number seed */ + for (k = 0 ; k < n ; k++) + { + j = k + (my_rand ( ) % (n-k)) ; /* j = my_rand in range k to n-1 */ + t = p [j] ; /* swap p[k] and p[j] */ + p [j] = p [k] ; + p [k] = t ; + } + return (p) ; +} + + +/* ========================================================================== */ +/* === do_1_solve =========================================================== */ +/* ========================================================================== */ + +static double do_1_solve (cholmod_sparse *A, cholmod_dense *B, + cholmod_dense *Xknown, Int *Puser, Int *Quser, + KLU_common *Common, cholmod_common *ch, Int *nan) +{ + Int *Ai, *Ap ; + double *Ax, *Bx, *Xknownx, *Xx, *Ax2, *Axx ; + KLU_symbolic *Symbolic = NULL ; + KLU_numeric *Numeric = NULL ; + cholmod_dense *X = NULL, *R = NULL ; + cholmod_sparse *AT = NULL, *A2 = NULL, *AT2 = NULL ; + double one [2], minusone [2], + rnorm, anorm, bnorm, xnorm, relresid, relerr, err = 0. ; + Int i, j, nrhs2, isreal, n, nrhs, transpose, step, k, save, tries ; + + printf ("\ndo_1_solve: btf "ID" maxwork %g scale "ID" ordering "ID" user: " + ID" P,Q: %d halt: "ID"\n", + Common->btf, Common->maxwork, Common->scale, Common->ordering, + Common->user_data ? (*((Int *) Common->user_data)) : -1, + (Puser != NULL || Quser != NULL), Common->halt_if_singular) ; + fflush (stdout) ; + fflush (stderr) ; + + CHOLMOD_print_sparse (A, "A", ch) ; + CHOLMOD_print_dense (B, "B", ch) ; + + Ap = A->p ; + Ai = A->i ; + Ax = A->x ; + n = A->nrow ; + isreal = (A->xtype == CHOLMOD_REAL) ; + Bx = B->x ; + Xknownx = Xknown->x ; + nrhs = B->ncol ; + + one [0] = 1 ; + one [1] = 0 ; + + minusone [0] = -1 ; + minusone [1] = 0 ; + + /* ---------------------------------------------------------------------- */ + /* symbolic analysis */ + /* ---------------------------------------------------------------------- */ + + Symbolic = NULL ; + my_tries = 0 ; + for (tries = 0 ; Symbolic == NULL && my_tries == 0 ; tries++) + { + my_tries = tries ; + if (Puser != NULL || Quser != NULL) + { + Symbolic = klu_analyze_given (n, Ap, Ai, Puser, Quser, Common) ; + } + else + { + Symbolic = klu_analyze (n, Ap, Ai, Common) ; + } + } + printf ("sym try "ID" btf "ID" ordering "ID"\n", + tries, Common->btf, Common->ordering) ; + if (Symbolic == NULL) + { + printf ("Symbolic is null\n") ; + return (998) ; + } + my_tries = -1 ; + + /* create a modified version of A */ + + A2 = CHOLMOD_copy_sparse (A, ch) ; + Ax2 = A2->x ; + my_srand (42) ; + for (k = 0 ; k < Ap [n] * (isreal ? 1:2) ; k++) + { + Ax2 [k] = Ax [k] * + (1 + 1e-4 * ((double) my_rand ( )) / ((double) MY_RAND_MAX)) ; + } + + AT = isreal ? NULL : CHOLMOD_transpose (A, 1, ch) ; + AT2 = isreal ? NULL : CHOLMOD_transpose (A2, 1, ch) ; + + /* ---------------------------------------------------------------------- */ + /* factorize then solve */ + /* ---------------------------------------------------------------------- */ + + for (step = 1 ; step <= 3 ; step++) + { + printf ("step: "ID"\n", step) ; + fflush (stdout) ; + + /* ------------------------------------------------------------------ */ + /* factorization or refactorization */ + /* ------------------------------------------------------------------ */ + + /* step 1: factor + step 2: refactor with same A + step 3: refactor with modified A, and scaling forced on + and solve each time + */ + + if (step == 1) + { + /* numeric factorization */ + + Numeric = NULL ; + my_tries = 0 ; + for (tries = 0 ; Numeric == NULL && my_tries == 0 ; tries++) + { + my_tries = tries ; + if (isreal) + { + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, Common) ; + } + else + { + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, Common) ; + } + } + printf ("num try "ID" btf "ID"\n", tries, Common->btf) ; + my_tries = -1 ; + + if (Common->status == KLU_OK || + (Common->status == KLU_SINGULAR && !Common->halt_if_singular)) + { + OK (Numeric) ; + } + else + { + FAIL (Numeric) ; + } + + if (Common->status < KLU_OK) + { + printf ("factor failed: "ID"\n", Common->status) ; + } + + } + else if (step == 2) + { + + /* numeric refactorization with same values, same scaling */ + if (isreal) + { + klu_refactor (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + } + else + { + klu_z_refactor (Ap, Ai, Ax, Symbolic, Numeric, Common) ; + } + + } + else + { + + /* numeric refactorization with different values */ + save = Common->scale ; + if (Common->scale == 0) + { + Common->scale = 1 ; + } + for (tries = 0 ; tries <= 1 ; tries++) + { + my_tries = tries ; + if (isreal) + { + klu_refactor (Ap, Ai, Ax2, Symbolic, Numeric, Common) ; + } + else + { + klu_z_refactor (Ap, Ai, Ax2, Symbolic, Numeric, Common) ; + } + } + my_tries = -1 ; + Common->scale = save ; + } + + if (Common->status == KLU_SINGULAR) + { + printf ("# singular column : "ID"\n", Common->singular_col) ; + } + + /* ------------------------------------------------------------------ */ + /* diagnostics */ + /* ------------------------------------------------------------------ */ + + Axx = (step == 3) ? Ax2 : Ax ; + + if (isreal) + { + klu_rgrowth (Ap, Ai, Axx, Symbolic, Numeric, Common) ; + klu_condest (Ap, Axx, Symbolic, Numeric, Common) ; + klu_rcond (Symbolic, Numeric, Common) ; + klu_flops (Symbolic, Numeric, Common) ; + } + else + { + klu_z_rgrowth (Ap, Ai, Axx, Symbolic, Numeric, Common) ; + klu_z_condest (Ap, Axx, Symbolic, Numeric, Common) ; + klu_z_rcond (Symbolic, Numeric, Common) ; + klu_z_flops (Symbolic, Numeric, Common) ; + } + + printf ("growth %g condest %g rcond %g flops %g\n", + Common->rgrowth, Common->condest, Common->rcond, Common->flops) ; + + ludump (Symbolic, Numeric, isreal, ch, Common) ; + + if (Numeric == NULL || Common->status < KLU_OK) + { + continue ; + } + + /* ------------------------------------------------------------------ */ + /* solve */ + /* ------------------------------------------------------------------ */ + + /* forward/backsolve to solve A*X=B or A'*X=B */ + for (transpose = (isreal ? 0 : -1) ; transpose <= 1 ; transpose++) + { + + for (nrhs2 = 1 ; nrhs2 <= nrhs ; nrhs2++) + { + /* mangle B so that it has only nrhs2 columns */ + B->ncol = nrhs2 ; + + X = CHOLMOD_copy_dense (B, ch) ; + CHOLMOD_print_dense (X, "X before solve", ch) ; + Xx = X->x ; + + if (isreal) + { + if (transpose) + { + /* solve A'x=b */ + klu_tsolve (Symbolic, Numeric, n, nrhs2, Xx, Common) ; + } + else + { + /* solve A*x=b */ + klu_solve (Symbolic, Numeric, n, nrhs2, Xx, Common) ; + } + } + else + { + if (transpose) + { + /* solve A'x=b (if 1) or A.'x=b (if -1) */ + klu_z_tsolve (Symbolic, Numeric, n, nrhs2, Xx, + (transpose == 1), Common) ; + } + else + { + /* solve A*x=b */ + klu_z_solve (Symbolic, Numeric, n, nrhs2, Xx, Common) ; + } + } + + CHOLMOD_print_dense (X, "X", ch) ; + + /* compute the residual, R = B-A*X, B-A'*X, or B-A.'*X */ + R = CHOLMOD_copy_dense (B, ch) ; + if (transpose == -1) + { + /* R = B-A.'*X (use A.' explicitly) */ + CHOLMOD_sdmult ((step == 3) ? AT2 : AT, + 0, minusone, one, X, R, ch) ; + } + else + { + /* R = B-A*X or B-A'*X */ + CHOLMOD_sdmult ((step == 3) ? A2 :A, + transpose, minusone, one, X, R, ch) ; + } + + CHOLMOD_print_dense (R, "R", ch) ; + + /* compute the norms of R, A, X, and B */ + rnorm = CHOLMOD_norm_dense (R, 1, ch) ; + anorm = CHOLMOD_norm_sparse ((step == 3) ? A2 : A, 1, ch) ; + xnorm = CHOLMOD_norm_dense (X, 1, ch) ; + bnorm = CHOLMOD_norm_dense (B, 1, ch) ; + + CHOLMOD_free_dense (&R, ch) ; + + /* relative residual = norm (r) / (norm (A) * norm (x)) */ + relresid = rnorm ; + if (anorm > 0) + { + relresid /= anorm ; + } + if (xnorm > 0) + { + relresid /= xnorm ; + } + + if (SCALAR_IS_NAN (relresid)) + { + *nan = TRUE ; + } + else + { + err = MAX (err, relresid) ; + } + + /* relative error = norm (x - xknown) / norm (xknown) */ + /* overwrite X with X - Xknown */ + if (transpose || step == 3) + { + /* not computed */ + relerr = -1 ; + } + else + { + for (j = 0 ; j < nrhs2 ; j++) + { + for (i = 0 ; i < n ; i++) + { + if (isreal) + { + Xx [i+j*n] -= Xknownx [i+j*n] ; + } + else + { + Xx [2*(i+j*n) ] -= Xknownx [2*(i+j*n) ] ; + Xx [2*(i+j*n)+1] -= Xknownx [2*(i+j*n)+1] ; + } + } + } + relerr = CHOLMOD_norm_dense (X, 1, ch) ; + xnorm = CHOLMOD_norm_dense (Xknown, 1, ch) ; + if (xnorm > 0) + { + relerr /= xnorm ; + } + + if (SCALAR_IS_NAN (relerr)) + { + *nan = TRUE ; + } + else + { + err = MAX (relerr, err) ; + } + + } + + CHOLMOD_free_dense (&X, ch) ; + + printf (ID" "ID" relresid %10.3g relerr %10.3g %g\n", + transpose, nrhs2, relresid, relerr, err) ; + + B->ncol = nrhs ; /* restore B */ + } + } + } + + /* ---------------------------------------------------------------------- */ + /* free factorization and temporary matrices, and return */ + /* ---------------------------------------------------------------------- */ + + klu_free_symbolic (&Symbolic, Common) ; + if (isreal) + { + klu_free_numeric (&Numeric, Common) ; + } + else + { + klu_z_free_numeric (&Numeric, Common) ; + } + CHOLMOD_free_sparse (&A2, ch) ; + CHOLMOD_free_sparse (&AT, ch) ; + CHOLMOD_free_sparse (&AT2, ch) ; + fflush (stdout) ; + fflush (stderr) ; + return (err) ; +} + + +/* ========================================================================== */ +/* === do_solves ============================================================ */ +/* ========================================================================== */ + +/* test KLU with many options */ + +static double do_solves (cholmod_sparse *A, cholmod_dense *B, cholmod_dense *X, + Int *Puser, Int *Quser, KLU_common *Common, cholmod_common *ch, Int *nan) +{ + double err, maxerr = 0 ; + Int n = A->nrow, sflag ; + *nan = FALSE ; + + /* ---------------------------------------------------------------------- */ + /* test KLU with the system A*X=B and default options */ + /* ---------------------------------------------------------------------- */ + + maxerr = do_1_solve (A, B, X, NULL, NULL, Common, ch, nan) ; + + /* ---------------------------------------------------------------------- */ + /* test with non-default options */ + /* ---------------------------------------------------------------------- */ + + Common->user_order = klu_cholmod ; + for (Common->btf = 0 ; Common->btf <= 2 ; Common->btf++) + { + Common->maxwork = (Common->btf == 2) ? 0.001 : 0 ; + + for (Common->halt_if_singular = 0 ; Common->halt_if_singular <= 1 ; + Common->halt_if_singular++) + { + for (Common->scale = 0 ; Common->scale <= 2 ; Common->scale++) + + { + fprintf (stderr, ".") ; + fflush (stderr) ; + + /* orderings: 0: AMD, 1: COLAMD, 2: natural, 3: user function */ + for (Common->ordering = 0 ; Common->ordering <= 3 ; + Common->ordering++) + { + err = do_1_solve (A, B, X, NULL, NULL, Common, ch, nan) ; + maxerr = MAX (maxerr, err) ; + } + + /* user-ordering, unsymmetric case */ + Common->ordering = 3 ; + Common->user_data = &sflag ; + sflag = 0 ; + err = do_1_solve (A, B, X, NULL, NULL, Common, ch, nan) ; + maxerr = MAX (maxerr, err) ; + Common->user_data = NULL ; + + /* Puser and Quser, but only for small matrices */ + Common->ordering = 2 ; + if (n < 200) + { + err = do_1_solve (A, B, X, Puser, Quser, Common, ch, nan) ; + maxerr = MAX (maxerr, err) ; + } + } + } + } + + /* restore defaults */ + Common->btf = TRUE ; + Common->maxwork = 0 ; + Common->ordering = 0 ; + Common->scale = -1 ; + Common->halt_if_singular = TRUE ; + Common->user_order = NULL ; + + my_tries = -1 ; + return (maxerr) ; +} + + +/* ========================================================================== */ +/* === main ================================================================= */ +/* ========================================================================== */ + +int main (void) +{ + KLU_common Common ; + cholmod_sparse *A, *A2 ; + cholmod_dense *X, *B ; + cholmod_common ch ; + Int *Ap, *Ai, *Puser, *Quser, *Gunk ; + double *Ax, *Bx, *Xx, *A2x ; + double one [2], zero [2], xsave, maxerr ; + Int n, i, j, nz, save, isreal, k, nan ; + KLU_symbolic *Symbolic, *Symbolic2 ; + KLU_numeric *Numeric ; + + one [0] = 1 ; + one [1] = 0 ; + zero [0] = 0 ; + zero [1] = 0 ; + + printf ("klu test: -------------------------------------------------\n") ; + OK (klu_defaults (&Common)) ; + CHOLMOD_start (&ch) ; + ch.print = 0 ; + normal_memory_handler (&Common) ; + + /* ---------------------------------------------------------------------- */ + /* read in a sparse matrix from stdin */ + /* ---------------------------------------------------------------------- */ + + A = CHOLMOD_read_sparse (stdin, &ch) ; + + if (A->nrow != A->ncol || A->stype != 0) + { + fprintf (stderr, "error: only square unsymmetric matrices handled\n") ; + CHOLMOD_free_sparse (&A, &ch) ; + return (0) ; + } + if (!(A->xtype == CHOLMOD_REAL || A->xtype == CHOLMOD_COMPLEX)) + { + fprintf (stderr, "error: only real or complex matrices hanlded\n") ; + CHOLMOD_free_sparse (&A, &ch) ; + return (0) ; + } + + n = A->nrow ; + Ap = A->p ; + Ai = A->i ; + Ax = A->x ; + nz = Ap [n] ; + isreal = (A->xtype == CHOLMOD_REAL) ; + + /* ---------------------------------------------------------------------- */ + /* construct random permutations */ + /* ---------------------------------------------------------------------- */ + + Puser = randperm (n, n) ; + Quser = randperm (n, n) ; + + /* ---------------------------------------------------------------------- */ + /* select known solution to Ax=b */ + /* ---------------------------------------------------------------------- */ + + X = CHOLMOD_allocate_dense (n, NRHS, n, A->xtype, &ch) ; + Xx = X->x ; + for (j = 0 ; j < NRHS ; j++) + { + for (i = 0 ; i < n ; i++) + { + if (isreal) + { + Xx [i] = 1 + ((double) i) / ((double) n) + j * 100; + } + else + { + Xx [2*i ] = 1 + ((double) i) / ((double) n) + j * 100 ; + Xx [2*i+1] = - ((double) i+1) / ((double) n + j) ; + if (j == NRHS-1) + { + Xx [2*i+1] = 0 ; /* zero imaginary part */ + } + else if (j == NRHS-2) + { + Xx [2*i] = 0 ; /* zero real part */ + } + } + } + Xx += isreal ? n : 2*n ; + } + + /* B = A*X */ + B = CHOLMOD_allocate_dense (n, NRHS, n, A->xtype, &ch) ; + CHOLMOD_sdmult (A, 0, one, zero, X, B, &ch) ; + Bx = B->x ; + + /* ---------------------------------------------------------------------- */ + /* test KLU */ + /* ---------------------------------------------------------------------- */ + + test_memory_handler (&Common) ; + maxerr = do_solves (A, B, X, Puser, Quser, &Common, &ch, &nan) ; + + /* ---------------------------------------------------------------------- */ + /* basic error checking */ + /* ---------------------------------------------------------------------- */ + + FAIL (klu_defaults (NULL)) ; + + FAIL (klu_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_extract (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_analyze (0, NULL, NULL, NULL)) ; + FAIL (klu_analyze (0, NULL, NULL, &Common)) ; + + FAIL (klu_analyze_given (0, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_analyze_given (0, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_cholmod (0, NULL, NULL, NULL, NULL)) ; + + FAIL (klu_factor (NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_factor (NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_factor (NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_factor (NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_refactor (NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_refactor (NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_refactor (NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_refactor (NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_rgrowth (NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_rgrowth (NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_rgrowth (NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_rgrowth (NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_condest (NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_condest (NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_condest (NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_condest (NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_flops (NULL, NULL, NULL)) ; + FAIL (klu_flops (NULL, NULL, &Common)) ; + + FAIL (klu_z_flops (NULL, NULL, NULL)) ; + FAIL (klu_z_flops (NULL, NULL, &Common)) ; + + FAIL (klu_rcond (NULL, NULL, NULL)) ; + FAIL (klu_rcond (NULL, NULL, &Common)) ; + + FAIL (klu_z_rcond (NULL, NULL, NULL)) ; + FAIL (klu_z_rcond (NULL, NULL, &Common)) ; + + FAIL (klu_free_symbolic (NULL, NULL)) ; + OK (klu_free_symbolic (NULL, &Common)) ; + + FAIL (klu_free_numeric (NULL, NULL)) ; + OK (klu_free_numeric (NULL, &Common)) ; + + FAIL (klu_z_free_numeric (NULL, NULL)) ; + OK (klu_z_free_numeric (NULL, &Common)) ; + + FAIL (klu_scale (0, 0, NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_scale (0, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ; + OK (klu_scale (-1, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_z_scale (0, 0, NULL, NULL, NULL, NULL, NULL, NULL)) ; + FAIL (klu_z_scale (0, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ; + OK (klu_z_scale (-1, 0, NULL, NULL, NULL, NULL, NULL, &Common)) ; + + FAIL (klu_solve (NULL, NULL, 0, 0, NULL, NULL)) ; + FAIL (klu_solve (NULL, NULL, 0, 0, NULL, &Common)) ; + + FAIL (klu_z_solve (NULL, NULL, 0, 0, NULL, NULL)) ; + FAIL (klu_z_solve (NULL, NULL, 0, 0, NULL, &Common)) ; + + FAIL (klu_tsolve (NULL, NULL, 0, 0, NULL, NULL)) ; + FAIL (klu_tsolve (NULL, NULL, 0, 0, NULL, &Common)) ; + + FAIL (klu_z_tsolve (NULL, NULL, 0, 0, NULL, 0, NULL)) ; + FAIL (klu_z_tsolve (NULL, NULL, 0, 0, NULL, 0, &Common)) ; + + FAIL (klu_malloc (0, 0, NULL)) ; + FAIL (klu_malloc (0, 0, &Common)) ; + FAIL (klu_malloc (Int_MAX, 1, &Common)) ; + + FAIL (klu_realloc (0, 0, 0, NULL, NULL)) ; + FAIL (klu_realloc (0, 0, 0, NULL, &Common)) ; + FAIL (klu_realloc (Int_MAX, 1, 0, NULL, &Common)) ; + Gunk = (Int *) klu_realloc (1, 0, sizeof (Int), NULL, &Common) ; + OK (Gunk) ; + OK (klu_realloc (Int_MAX, 1, sizeof (Int), Gunk, &Common)) ; + OK (Common.status == KLU_TOO_LARGE) ; + klu_free (Gunk, 1, sizeof (Int), &Common) ; + + /* ---------------------------------------------------------------------- */ + /* mangle the matrix, and other error checking */ + /* ---------------------------------------------------------------------- */ + + printf ("\nerror handling:\n") ; + Symbolic = klu_analyze (n, Ap, Ai, &Common) ; + OK (Symbolic) ; + + Xx = X->x ; + if (nz > 0) + { + + /* ------------------------------------------------------------------ */ + /* row index out of bounds */ + /* ------------------------------------------------------------------ */ + + save = Ai [0] ; + Ai [0] = -1 ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + if (isreal) + { + FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + else + { + FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + Ai [0] = save ; + + /* ------------------------------------------------------------------ */ + /* row index out of bounds */ + /* ------------------------------------------------------------------ */ + + save = Ai [0] ; + Ai [0] = Int_MAX ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + if (isreal) + { + FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + else + { + FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + Ai [0] = save ; + + /* ------------------------------------------------------------------ */ + /* column pointers mangled */ + /* ------------------------------------------------------------------ */ + + save = Ap [n] ; + Ap [n] = -1 ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + if (isreal) + { + FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + else + { + FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + Ap [n] = save ; + + /* ------------------------------------------------------------------ */ + /* column pointers mangled */ + /* ------------------------------------------------------------------ */ + + save = Ap [n] ; + Ap [n] = Ap [n-1] - 1 ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + if (isreal) + { + FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + else + { + FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + Ap [n] = save ; + + /* ------------------------------------------------------------------ */ + /* duplicates */ + /* ------------------------------------------------------------------ */ + + if (n > 1 && Ap [1] - Ap [0] > 1) + { + save = Ai [1] ; + Ai [1] = Ai [0] ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + if (isreal) + { + FAIL (klu_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + else + { + FAIL (klu_z_scale (1, n, Ap, Ai, Ax, Xx, Puser, &Common)) ; + } + Ai [1] = save ; + } + + /* ------------------------------------------------------------------ */ + /* invalid ordering */ + /* ------------------------------------------------------------------ */ + + save = Common.ordering ; + Common.ordering = 42 ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + Common.ordering = save ; + + /* ------------------------------------------------------------------ */ + /* invalid ordering (klu_cholmod, with NULL user_ordering) */ + /* ------------------------------------------------------------------ */ + + save = Common.ordering ; + Common.user_order = NULL ; + Common.ordering = 3 ; + FAIL (klu_analyze (n, Ap, Ai, &Common)) ; + Common.ordering = save ; + } + + /* ---------------------------------------------------------------------- */ + /* tests with valid symbolic factorization */ + /* ---------------------------------------------------------------------- */ + + Common.halt_if_singular = FALSE ; + Common.scale = 0 ; + Numeric = NULL ; + + if (nz > 0) + { + + /* ------------------------------------------------------------------ */ + /* Int overflow */ + /* ------------------------------------------------------------------ */ + + if (n == 100) + { + Common.ordering = 2 ; + Symbolic2 = klu_analyze (n, Ap, Ai, &Common) ; + OK (Symbolic2) ; + Common.memgrow = Int_MAX ; + if (isreal) + { + Numeric = klu_factor (Ap, Ai, Ax, Symbolic2, &Common) ; + } + else + { + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic2, &Common) ; + } + Common.memgrow = 1.2 ; + Common.ordering = 0 ; + klu_free_symbolic (&Symbolic2, &Common) ; + klu_free_numeric (&Numeric, &Common) ; + } + + /* ------------------------------------------------------------------ */ + /* Int overflow again */ + /* ------------------------------------------------------------------ */ + + Common.initmem = Int_MAX ; + Common.initmem_amd = Int_MAX ; + if (isreal) + { + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; + } + else + { + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ; + } + Common.initmem = 10 ; + Common.initmem_amd = 1.2 ; + klu_free_numeric (&Numeric, &Common) ; + + /* ------------------------------------------------------------------ */ + /* mangle the matrix */ + /* ------------------------------------------------------------------ */ + + save = Ai [0] ; + Ai [0] = -1 ; + + if (isreal) + { + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; + } + else + { + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ; + } + FAIL (Numeric) ; + Ai [0] = save ; + + /* ------------------------------------------------------------------ */ + /* nan and inf handling */ + /* ------------------------------------------------------------------ */ + + xsave = Ax [0] ; + Ax [0] = one [0] / zero [0] ; + if (isreal) + { + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; + klu_rcond (Symbolic, Numeric, &Common) ; + klu_condest (Ap, Ax, Symbolic, Numeric, &Common) ; + } + else + { + Numeric = klu_z_factor (Ap, Ai, Ax, Symbolic, &Common) ; + klu_z_rcond (Symbolic, Numeric, &Common) ; + klu_z_condest (Ap, Ax, Symbolic, Numeric, &Common) ; + } + printf ("Nan case: rcond %g condest %g\n", + Common.rcond, Common.condest) ; + OK (Numeric) ; + Ax [0] = xsave ; + + /* ------------------------------------------------------------------ */ + /* mangle the matrix again */ + /* ------------------------------------------------------------------ */ + + save = Ai [0] ; + Ai [0] = -1 ; + if (isreal) + { + FAIL (klu_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common)) ; + } + else + { + FAIL (klu_z_refactor (Ap, Ai, Ax, Symbolic, Numeric, &Common)) ; + } + Ai [0] = save ; + + /* ------------------------------------------------------------------ */ + /* all zero */ + /* ------------------------------------------------------------------ */ + + A2 = CHOLMOD_copy_sparse (A, &ch) ; + A2x = A2->x ; + for (k = 0 ; k < nz * (isreal ? 1:2) ; k++) + { + A2x [k] = 0 ; + } + for (Common.halt_if_singular = 0 ; Common.halt_if_singular <= 1 ; + Common.halt_if_singular++) + { + for (Common.scale = -1 ; Common.scale <= 2 ; Common.scale++) + { + if (isreal) + { + klu_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ; + klu_condest (Ap, A2x, Symbolic, Numeric, &Common) ; + } + else + { + klu_z_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ; + klu_z_condest (Ap, A2x, Symbolic, Numeric, &Common) ; + } + OK (Common.status = KLU_SINGULAR) ; + } + } + CHOLMOD_free_sparse (&A2, &ch) ; + + /* ------------------------------------------------------------------ */ + /* all one, or all 1i for complex case */ + /* ------------------------------------------------------------------ */ + + A2 = CHOLMOD_copy_sparse (A, &ch) ; + A2x = A2->x ; + for (k = 0 ; k < nz ; k++) + { + if (isreal) + { + A2x [k] = 1 ; + } + else + { + A2x [2*k ] = 0 ; + A2x [2*k+1] = 1 ; + } + } + Common.halt_if_singular = 0 ; + Common.scale = 0 ; + if (isreal) + { + klu_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ; + klu_condest (Ap, A2x, Symbolic, Numeric, &Common) ; + } + else + { + klu_z_refactor (Ap, Ai, A2x, Symbolic, Numeric, &Common) ; + klu_z_condest (Ap, A2x, Symbolic, Numeric, &Common) ; + } + OK (Common.status = KLU_SINGULAR) ; + CHOLMOD_free_sparse (&A2, &ch) ; + } + + klu_free_symbolic (&Symbolic, &Common) ; + if (isreal) + { + klu_free_numeric (&Numeric, &Common) ; + } + else + { + klu_z_free_numeric (&Numeric, &Common) ; + } + + /* ---------------------------------------------------------------------- */ + /* free problem and quit */ + /* ---------------------------------------------------------------------- */ + + CHOLMOD_free_dense (&X, &ch) ; + CHOLMOD_free_dense (&B, &ch) ; + CHOLMOD_free_sparse (&A, &ch) ; + free (Puser) ; + free (Quser) ; + CHOLMOD_finish (&ch) ; + fprintf (stderr, " maxerr %10.3e", maxerr) ; + printf (" maxerr %10.3e", maxerr) ; + if (maxerr < 1e-8) + { + fprintf (stderr, " test passed") ; + printf (" test passed") ; + } + else + { + fprintf (stderr, " test FAILED") ; + printf (" test FAILED") ; + } + if (nan) + { + fprintf (stderr, " *") ; + printf (" *") ; + } + fprintf (stderr, "\n") ; + printf ("\n-----------------------------------------------------------\n") ; + return (0) ; +} diff --git a/OpenDSSC/klusolve/KLU/Tcov/klutests b/OpenDSSC/klusolve/KLU/Tcov/klutests new file mode 100644 index 0000000..9b110bd --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/klutests @@ -0,0 +1,31 @@ +#!/bin/csh + +# 57 unique statements: +./klutest < ../Matrix/impcol_a.mtx + +# 20: +./klutest < ../Matrix/GD99_cc.mtx + +# 17: +./klutest < ../Matrix/two.mtx + +# 10: +./klutest < ../Matrix/w156.mtx + +# 3, xsize memgrow in klu_kernel +./klutest < ../Matrix/arrow.mtx + +# 3, xsize memgrow in klu_kernel, 1 in klu_z_condest, +./klutest < ../Matrix/arrowc.mtx + +# 2 in klu_z_kernel (if pivot == 0 and halt_if_singular, and in complex divide) +./klutest < ../Matrix/onec.mtx + +# 1 in klu_kernel (if pivot == 0 and halt if singular) +./klutest < ../Matrix/one.mtx + +# 1 in klu_z_condest: +./klutest < ../Matrix/1c.mtx + +# 1 in klu_z_condest: +./klutest < ../Matrix/ctina.mtx diff --git a/OpenDSSC/klusolve/KLU/Tcov/vklultests b/OpenDSSC/klusolve/KLU/Tcov/vklultests new file mode 100644 index 0000000..8aa8dcf --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/vklultests @@ -0,0 +1,31 @@ +#!/bin/csh + +# 57 unique statements: +valgrind ./klultest < ../Matrix/impcol_a.mtx + +# 20: +valgrind ./klultest < ../Matrix/GD99_cc.mtx + +# 17: +valgrind ./klultest < ../Matrix/two.mtx + +# 10: +valgrind ./klultest < ../Matrix/w156.mtx + +# 3, xsize memgrow in klu_kernel +valgrind ./klultest < ../Matrix/arrow.mtx + +# 3, xsize memgrow in klu_kernel, 1 in klu_z_condest, +valgrind ./klultest < ../Matrix/arrowc.mtx + +# 2 in klu_z_kernel (if pivot == 0 and halt_if_singular, and in complex divide) +valgrind ./klultest < ../Matrix/onec.mtx + +# 1 in klu_kernel (if pivot == 0 and halt if singular) +valgrind ./klultest < ../Matrix/one.mtx + +# 1 in klu_z_condest: +valgrind ./klultest < ../Matrix/1c.mtx + +# 1 in klu_z_condest: +valgrind ./klultest < ../Matrix/ctina.mtx diff --git a/OpenDSSC/klusolve/KLU/Tcov/vklutests b/OpenDSSC/klusolve/KLU/Tcov/vklutests new file mode 100644 index 0000000..7dfada9 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/Tcov/vklutests @@ -0,0 +1,31 @@ +#!/bin/csh + +# 57 unique statements: +valgrind ./klutest < ../Matrix/impcol_a.mtx + +# 20: +valgrind ./klutest < ../Matrix/GD99_cc.mtx + +# 17: +valgrind ./klutest < ../Matrix/two.mtx + +# 10: +valgrind ./klutest < ../Matrix/w156.mtx + +# 3, xsize memgrow in klu_kernel +valgrind ./klutest < ../Matrix/arrow.mtx + +# 3, xsize memgrow in klu_kernel, 1 in klu_z_condest, +valgrind ./klutest < ../Matrix/arrowc.mtx + +# 2 in klu_z_kernel (if pivot == 0 and halt_if_singular, and in complex divide) +valgrind ./klutest < ../Matrix/onec.mtx + +# 1 in klu_kernel (if pivot == 0 and halt if singular) +valgrind ./klutest < ../Matrix/one.mtx + +# 1 in klu_z_condest: +valgrind ./klutest < ../Matrix/1c.mtx + +# 1 in klu_z_condest: +valgrind ./klutest < ../Matrix/ctina.mtx diff --git a/OpenDSSC/klusolve/KLU/User/Makefile b/OpenDSSC/klusolve/KLU/User/Makefile new file mode 100644 index 0000000..faf6173 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/User/Makefile @@ -0,0 +1,26 @@ +default: all + +include ../../UFconfig/UFconfig.mk + +all: libklu_cholmod.a + +I = -I../../CHOLMOD/Include -I../../UFconfig -I../Include -I../../AMD/Include \ + -I../../BTF/Include -I../../COLAMD + +libklu_cholmod.a: library klu_cholmod.c klu_cholmod.h + $(CC) $(CFLAGS) $(I) -c klu_cholmod.c + $(AR) libklu_cholmod.a klu_cholmod.o + $(RANLIB) libklu_cholmod.a + +distclean: purge + +purge: clean + - $(RM) *.o *.a + +clean: + - $(RM) $(CLEAN) + +library: + ( cd ../../AMD ; $(MAKE) library ) + ( cd ../../COLAMD ; $(MAKE) library ) + ( cd ../../CHOLMOD/Lib ; $(MAKE) ) diff --git a/OpenDSSC/klusolve/KLU/User/README.txt b/OpenDSSC/klusolve/KLU/User/README.txt new file mode 100644 index 0000000..e3249d3 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/User/README.txt @@ -0,0 +1,2 @@ +This directory contains a sample user-ordering function, klu_cholmod. +Its use (and the use of CHOLMOD) is optional. diff --git a/OpenDSSC/klusolve/KLU/User/klu_cholmod.c b/OpenDSSC/klusolve/KLU/User/klu_cholmod.c new file mode 100644 index 0000000..8b16118 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/User/klu_cholmod.c @@ -0,0 +1,114 @@ +/* ========================================================================== */ +/* === klu_cholmod ========================================================== */ +/* ========================================================================== */ + +/* klu_cholmod: user-defined ordering function to interface KLU to CHOLMOD. + * + * This routine is an example of a user-provided ordering function for KLU. + * Its return value is klu_cholmod's estimate of max (nnz(L),nnz(U)): + * 0 if error, + * -1 if OK, but estimate of max (nnz(L),nnz(U)) not computed + * > 0 if OK and estimate computed. + * + * This function can be assigned to KLU's Common->user_order function pointer. + */ + +#include "klu_cholmod.h" +#include "cholmod.h" +#define TRUE 1 +#define FALSE 0 + +int klu_cholmod +( + /* inputs */ + int n, /* A is n-by-n */ + int Ap [ ], /* column pointers */ + int Ai [ ], /* row indices */ + /* outputs */ + int Perm [ ], /* fill-reducing permutation */ + /* user-defined */ + klu_common *Common /* user-defined data is in Common->user_data */ +) +{ + double one [2] = {1,0}, zero [2] = {0,0}, lnz = 0 ; + cholmod_sparse Amatrix, *A, *AT, *S ; + cholmod_factor *L ; + cholmod_common cm ; + int *P ; + int k, symmetric ; + + if (Ap == NULL || Ai == NULL || Perm == NULL || n < 0) + { + /* invalid inputs */ + return (0) ; + } + + /* start CHOLMOD */ + cholmod_start (&cm) ; + cm.supernodal = CHOLMOD_SIMPLICIAL ; + cm.print = 0 ; + + /* use KLU memory management routines for CHOLMOD */ + cm.malloc_memory = Common->malloc_memory ; + cm.realloc_memory = Common->realloc_memory ; + cm.calloc_memory = Common->calloc_memory ; + cm.free_memory = Common->free_memory ; + + /* construct a CHOLMOD version of the input matrix A */ + A = &Amatrix ; + A->nrow = n ; /* A is n-by-n */ + A->ncol = n ; + A->nzmax = Ap [n] ; /* with nzmax entries */ + A->packed = TRUE ; /* there is no A->nz array */ + A->stype = 0 ; /* A is unsymmetric */ + A->itype = CHOLMOD_INT ; + A->xtype = CHOLMOD_PATTERN ; + A->dtype = CHOLMOD_DOUBLE ; + A->nz = NULL ; + A->p = Ap ; /* column pointers */ + A->i = Ai ; /* row indices */ + A->x = NULL ; /* no numerical values */ + A->z = NULL ; + A->sorted = FALSE ; /* columns of A are not sorted */ + + /* get the user_data; default is symmetric if user_data is NULL */ + symmetric = (Common->user_data == NULL) ? TRUE : + (((int *) (Common->user_data)) [0] != 0) ; + + /* AT = pattern of A' */ + AT = cholmod_transpose (A, 0, &cm) ; + if (symmetric) + { + /* S = the symmetric pattern of A+A' */ + S = cholmod_add (A, AT, one, zero, FALSE, FALSE, &cm) ; + cholmod_free_sparse (&AT, &cm) ; + if (S != NULL) + { + S->stype = 1 ; + } + } + else + { + /* S = A'. CHOLMOD will order S*S', which is A'*A */ + S = AT ; + } + + /* order and analyze S or S*S' */ + L = cholmod_analyze (S, &cm) ; + + /* copy the permutation from L to the output */ + if (L != NULL) + { + P = L->Perm ; + for (k = 0 ; k < n ; k++) + { + Perm [k] = P [k] ; + } + lnz = cm.lnz ; + } + + cholmod_free_sparse (&S, &cm) ; + cholmod_free_factor (&L, &cm) ; + cholmod_finish (&cm) ; + return (lnz) ; +} diff --git a/OpenDSSC/klusolve/KLU/User/klu_cholmod.h b/OpenDSSC/klusolve/KLU/User/klu_cholmod.h new file mode 100644 index 0000000..e9c4d27 --- /dev/null +++ b/OpenDSSC/klusolve/KLU/User/klu_cholmod.h @@ -0,0 +1,8 @@ +#include "klu.h" +#include "UFconfig.h" + +int klu_cholmod (int n, int Ap [ ], int Ai [ ], int Perm [ ], klu_common *) ; + +UF_long klu_l_cholmod (UF_long n, UF_long Ap [ ], UF_long Ai [ ], + UF_long Perm [ ], klu_l_common *) ; + diff --git a/OpenDSSC/klusolve/KLU/User/klu_l_cholmod.c b/OpenDSSC/klusolve/KLU/User/klu_l_cholmod.c new file mode 100644 index 0000000..c04577b --- /dev/null +++ b/OpenDSSC/klusolve/KLU/User/klu_l_cholmod.c @@ -0,0 +1,114 @@ +/* ========================================================================== */ +/* === klu_cholmod ========================================================== */ +/* ========================================================================== */ + +/* klu_l_cholmod: user-defined ordering function to interface KLU to CHOLMOD. + * + * This routine is an example of a user-provided ordering function for KLU. + * Its return value is klu_l_cholmod's estimate of max (nnz(L),nnz(U)): + * 0 if error, + * -1 if OK, but estimate of max (nnz(L),nnz(U)) not computed + * > 0 if OK and estimate computed. + * + * This function can be assigned to KLU's Common->user_order function pointer. + */ + +#include "klu_cholmod.h" +#include "cholmod.h" +#define TRUE 1 +#define FALSE 0 + +UF_long klu_l_cholmod +( + /* inputs */ + UF_long n, /* A is n-by-n */ + UF_long Ap [ ], /* column pointers */ + UF_long Ai [ ], /* row indices */ + /* outputs */ + UF_long Perm [ ], /* fill-reducing permutation */ + /* user-defined */ + klu_l_common *Common /* user-defined data is in Common->user_data */ +) +{ + double one [2] = {1,0}, zero [2] = {0,0}, lnz = 0 ; + cholmod_sparse Amatrix, *A, *AT, *S ; + cholmod_factor *L ; + cholmod_common cm ; + UF_long *P ; + UF_long k, symmetric ; + + if (Ap == NULL || Ai == NULL || Perm == NULL || n < 0) + { + /* invalid inputs */ + return (0) ; + } + + /* start CHOLMOD */ + cholmod_l_start (&cm) ; + cm.supernodal = CHOLMOD_SIMPLICIAL ; + cm.print = 0 ; + + /* use KLU memory management routines for CHOLMOD */ + cm.malloc_memory = Common->malloc_memory ; + cm.realloc_memory = Common->realloc_memory ; + cm.calloc_memory = Common->calloc_memory ; + cm.free_memory = Common->free_memory ; + + /* construct a CHOLMOD version of the input matrix A */ + A = &Amatrix ; + A->nrow = n ; /* A is n-by-n */ + A->ncol = n ; + A->nzmax = Ap [n] ; /* with nzmax entries */ + A->packed = TRUE ; /* there is no A->nz array */ + A->stype = 0 ; /* A is unsymmetric */ + A->itype = CHOLMOD_INT ; + A->xtype = CHOLMOD_PATTERN ; + A->dtype = CHOLMOD_DOUBLE ; + A->nz = NULL ; + A->p = Ap ; /* column pointers */ + A->i = Ai ; /* row indices */ + A->x = NULL ; /* no numerical values */ + A->z = NULL ; + A->sorted = FALSE ; /* columns of A are not sorted */ + + /* get the user_data; default is symmetric if user_data is NULL */ + symmetric = (Common->user_data == NULL) ? TRUE : + (((UF_long *) (Common->user_data)) [0] != 0) ; + + /* AT = pattern of A' */ + AT = cholmod_l_transpose (A, 0, &cm) ; + if (symmetric) + { + /* S = the symmetric pattern of A+A' */ + S = cholmod_l_add (A, AT, one, zero, FALSE, FALSE, &cm) ; + cholmod_l_free_sparse (&AT, &cm) ; + if (S != NULL) + { + S->stype = 1 ; + } + } + else + { + /* S = A'. CHOLMOD will order S*S', which is A'*A */ + S = AT ; + } + + /* order and analyze S or S*S' */ + L = cholmod_l_analyze (S, &cm) ; + + /* copy the permutation from L to the output */ + if (L != NULL) + { + P = L->Perm ; + for (k = 0 ; k < n ; k++) + { + Perm [k] = P [k] ; + } + lnz = cm.lnz ; + } + + cholmod_l_free_sparse (&S, &cm) ; + cholmod_l_free_factor (&L, &cm) ; + cholmod_l_finish (&cm) ; + return (lnz) ; +} diff --git a/OpenDSSC/klusolve/KLUSolve/Demo/Makefile b/OpenDSSC/klusolve/KLUSolve/Demo/Makefile new file mode 100644 index 0000000..b3c72df --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Demo/Makefile @@ -0,0 +1,45 @@ +# KLUSolve Demo Makefile. + +CC = g++ + +default: all + +include ../../UFconfig/UFconfig.mk + +LIB = ../Lib/libklusolve.a ../../KLU/Lib/libklu.a ../../BTF/Lib/libbtf.a \ + ../../AMD/Lib/libamd.a ../../COLAMD/Lib/libcolamd.a \ + ../../CSparse/Lib/libcsparse.a ../../CZSparse/Lib/libczsparse.a + +I = -I../../UFconfig -I../../AMD/Include -I../../COLAMD/Include \ + -I../../BTF/Include -I../../CSparse/Include -I../../CZSparse/Include \ + -I../../KLU/Include -I../Include + +all: $(LIB) klusolve_demo + - ./klusolve_demo + +../Lib/libklusolve.a: + ( cd ../Lib ; $(MAKE) ) + +../../KLU/Lib/libklu.a: + ( cd ../../KLU ; $(MAKE) library ) + +../../BTF/Lib/libbtf.a: + ( cd ../../BTF ; $(MAKE) library ) + +../../AMD/Lib/libamd.a: + ( cd ../../AMD ; $(MAKE) library ) + +../../COLAMD/Lib/libcolamd.a: + ( cd ../../COLAMD ; $(MAKE) library ) + +purge: distclean + +distclean: clean + - $(RM) klusolve_demo + +clean: + - $(RM) $(CLEAN) + +klusolve_demo: Makefile $(LIB) + $(CC) $(CFLAGS) $(I) klusolve_demo.cpp -o klusolve_demo $(LIB) -lm + - ./klusolve_demo diff --git a/OpenDSSC/klusolve/KLUSolve/Demo/klusolve_demo.cpp b/OpenDSSC/klusolve/KLUSolve/Demo/klusolve_demo.cpp new file mode 100644 index 0000000..d454b6e --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Demo/klusolve_demo.cpp @@ -0,0 +1,39 @@ +/* klusolve_demo: a simple KLUSolve demo */ + +#include +#include +#include "klusolve.h" +/* +int n = 5 ; +int Ap [ ] = {0, 2, 5, 9, 10, 12} ; +int Ai [ ] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4} ; +double Ax [ ] = {2., 3., 3., -1., 4., 4., -3., 1., 2., 2., 6., 1.} ; +double b [ ] = {8., 45., -3., 3., 19.} ; +*/ +int main (void) +{ + printf("KLUSolve Demo\n"); + + uintptr_t hSparse = NewSparseSet(3); +/* + unsigned int size = 0; + GetSize(hSparse, &size); + printf("Size: %d", size); +*/ + //DeleteSparseSet(hSparse); +/* + klu_symbolic *Symbolic ; + klu_numeric *Numeric ; + klu_common Common ; + int i ; + klu_defaults (&Common) ; + Symbolic = klu_analyze (n, Ap, Ai, &Common) ; + Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ; + klu_solve (Symbolic, Numeric, 5, 1, b, &Common) ; + klu_free_symbolic (&Symbolic, &Common) ; + klu_free_numeric (&Numeric, &Common) ; + for (i = 0 ; i < n ; i++) printf ("x [%d] = %g\n", i, b [i]) ; +*/ + return (0) ; +} + diff --git a/OpenDSSC/klusolve/KLUSolve/Include/klusolve.h b/OpenDSSC/klusolve/KLUSolve/Include/klusolve.h new file mode 100644 index 0000000..ce39a70 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Include/klusolve.h @@ -0,0 +1,91 @@ +/* ------------------------------------------------------------------------- */ +/* KLUSolve, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ + +#ifndef klusolve_included +#define klusolve_included + +#ifndef _COMPLEX_DEFINED +#define _COMPLEX_DEFINED +typedef struct _complex {double x, y;} complex; +#endif + +#include + +#ifndef KLUSOLVE_IMPORTS +#define KLUSOLVE_CONVENTION +#define KLUSOLVE_DLL +#else + // KLUSOLVE_IMPORTS is defined: + #define KLUSOLVE_CONVENTION __stdcall + #if KLUSOLVE_IMPORTS + // We need to import our functions: + #define KLUSOLVE_DLL __declspec(dllimport) + #else + // We need to export our functions: + #define KLUSOLVE_DLL __declspec(dllexport) + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* klusparseset_t; + +// return handle of new sparse set, 0 if error +// be sure to DeleteSparseSet using the returned handle +KLUSOLVE_DLL klusparseset_t KLUSOLVE_CONVENTION NewSparseSet (unsigned int nBus); + +// return 1 if successful, 0 if not +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION ZeroSparseSet (klusparseset_t hSparse); + +// return 1 if successful, 2 if singular, 0 if other error +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION FactorSparseMatrix (klusparseset_t hSparse); + +/* + input: current injections in zero-based _acxB + output: node voltages in zero-based _acxX + no provision for voltage sources +*/ +// return 1 if successful, 2 if singular, 0 if other error +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION SolveSparseSet (klusparseset_t hSparse, complex *_acxX, complex *_acxB); + +// return 1 if successful, 0 if not +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION DeleteSparseSet (klusparseset_t hSparse); + +/* i and j are 1-based for these */ +// return 1 if successful, 0 if not +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION AddMatrixElement (klusparseset_t hSparse, unsigned int i, unsigned int j, complex *pcxVal); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetMatrixElement (klusparseset_t hSparse, unsigned int i, unsigned int j, complex *pcxVal); +// Sets a specific cell within the YBus matrix +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION SetMatrixElement(klusparseset_t hSparse, unsigned int i, unsigned int j, complex* pcxVal); + +// new functions +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetSize (klusparseset_t hSparse, unsigned int *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetNNZ (klusparseset_t hSparse, unsigned int *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetSparseNNZ (klusparseset_t hSparse, unsigned int *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetRCond (klusparseset_t hSparse, double *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetRGrowth (klusparseset_t hSparse, double *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetCondEst (klusparseset_t hSparse, double *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetFlops (klusparseset_t hSparse, double *pResult); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetSingularCol (klusparseset_t hSparse, unsigned int *pResult); + +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION AddPrimitiveMatrix (klusparseset_t hSparse, unsigned int nOrder, + unsigned int *pNodes, complex *pcY); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetCompressedMatrix (klusparseset_t hSparse, unsigned int nColP, + unsigned int nNZ, unsigned int *pColP, + unsigned int *pRowIdx, complex *pcY); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION GetTripletMatrix (klusparseset_t hSparse, unsigned int nNZ, + unsigned int *pRows, unsigned int *pCols, complex *pcY); +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION FindIslands (klusparseset_t hSparse, unsigned int nOrder, unsigned int *pNodes); + +// iAction = 0 to close, 1 to rewrite, 2 to append +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION SetLogFile (const char *path, unsigned int iAction); + +#ifdef __cplusplus +} +#endif + +#endif // klusolve_included diff --git a/OpenDSSC/klusolve/KLUSolve/Include/klusystem.h b/OpenDSSC/klusolve/KLUSolve/Include/klusystem.h new file mode 100644 index 0000000..3b34fc8 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Include/klusystem.h @@ -0,0 +1,119 @@ +/* ------------------------------------------------------------------------- */ +/* KLUSolve, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ + +#ifndef klusystem_included +#define klusystem_included + +extern "C" { +#include "cs.h" +#include "csz.h" +#include "klu.h" +} + +struct matrix_complex { + complex *acx; + unsigned nRow, nCol; + complex get_acx (unsigned i, unsigned j) { + return acx[i*nCol+j]; + } +}; + +/* Kron reduction not supported, this version just solves + +|Y22| * |V| = |I| + +KLU manages complex values as interleaved real/imag in double arrays +KLU arrays are zero-based +*/ + +class KLUSystem +{ +private: + complex *acx; + + // admittance matrix blocks in compressed-column storage, like Matlab + cs *Y22; + + // admittance matrix blocks in triplet storage + cs *T22; + + klu_symbolic *Symbolic; + klu_numeric *Numeric; + + unsigned int m_nBus; // number of nodes + unsigned int m_nX; // number of unknown voltages, hardwired to m_nBus + unsigned int m_NZpre; // number of non-zero entries before factoring + unsigned int m_NZpost; // number of non-zero entries after factoring + unsigned int m_fltBus; // row number of a bus causing singularity + + void InitDefaults (); + void clear (); + void zero_indices (); + void null_pointers (); + cs *process_triplet (cs **T); + void compress_partitions (); + +protected: + +public: + KLUSystem (); + KLUSystem (unsigned nBus, unsigned nV = 0, unsigned nI = 0); + ~KLUSystem (); + + bool bFactored; // system has been factored + + int FactorSystem (); + int SolveSystem (complex *_acxX, complex *_acxB); + // this resets and reinitializes the sparse matrix, nI = nBus + int Initialize (unsigned nBus, unsigned nV = 0, unsigned nI = 0); + unsigned int GetSize () {return m_nBus;} + + // metrics + unsigned int GetSparseNNZ () {return m_NZpost;} + unsigned int GetNNZ () {return m_NZpre;} + double GetRCond (); + double GetRGrowth (); + double GetCondEst (); + double GetFlops (); + unsigned int GetSingularCol () {return m_fltBus;} + + // bSum is ignored + void AddMatrix (unsigned /*far*/ *aidBus, matrix_complex *pcxm, int bSum); + + // returns 1 for success, -1 for a singular matrix + // returns 0 for another KLU error, most likely the matrix is too large for int32 + int Factor (); + + // input: acxVbus[0] is ground voltage + // acxVbus[1..nBus] are current injections + // output: acxVbus[1..nBus] are solved voltages + void Solve (complex *acxVbus); + + // returns the number of connected components (cliques) in the whole system graph + // (i.e., considers Y11, Y12, and Y21 in addition to Y22) + // store the island number (1-based) for each node in idClique + unsigned FindIslands (unsigned *idClique); + + // returns the row > 0 if a zero appears on the diagonal + // calls Factor if necessary + // note: the EMTP terminology is "floating subnetwork" + unsigned FindDisconnectedSubnetwork (); + + // The following were added for ESolv32: + // maintains allocations, zeros matrix values + void zero(); + // bSum is ignored + void AddElement(unsigned iRow, unsigned iCol, complex &cpxVal, int bSum); + // return the sum of elements at 1-based [iRow, iCol] + void GetElement(unsigned iRow, unsigned iCol, complex &cpxVal); + // for OpenDSS, return 1 for success + unsigned AddPrimitiveMatrix (unsigned nOrder, unsigned *pNodes, complex *pMat); + // return in compressed triplet form, return 1 for success, 0 for a size mismatch + unsigned GetCompressedMatrix (unsigned nColP, unsigned nNZ, unsigned *pColP, + unsigned *pRowIdx, complex *pMat); + unsigned GetTripletMatrix (unsigned nNZ, unsigned *pRows, unsigned *pCols, complex *pMat); +}; + +#endif // klusystem_included diff --git a/OpenDSSC/klusolve/KLUSolve/Makefile b/OpenDSSC/klusolve/KLUSolve/Makefile new file mode 100644 index 0000000..c03fa7f --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Makefile @@ -0,0 +1,32 @@ + +VERSION = 1.1.0 + +default: library + +include ../UFconfig/UFconfig.mk + +all: library + +library: + ( cd Lib ; $(MAKE) ) + +clean: + ( cd Lib ; $(MAKE) clean ) + +purge: + ( cd Lib ; $(MAKE) purge ) + +distclean: purge + +# install KLUSolve +install: + $(CP) Lib/libklusolve.a $(INSTALL_LIB)/libklusolve.$(VERSION).a + ( cd $(INSTALL_LIB) ; ln -sf libklusolve.$(VERSION).a libklusolve.a ) + $(CP) Include/klusolve.h $(INSTALL_INCLUDE) + chmod 644 $(INSTALL_LIB)/libklusolve*.a + chmod 644 $(INSTALL_INCLUDE)/klusolve.h + +# uninstall KLUSolve +uninstall: + $(RM) $(INSTALL_LIB)/libklusolve*.a + $(RM) $(INSTALL_INCLUDE)/klusolve.h diff --git a/OpenDSSC/klusolve/KLUSolve/ReadMe.txt b/OpenDSSC/klusolve/KLUSolve/ReadMe.txt new file mode 100644 index 0000000..aedd865 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/ReadMe.txt @@ -0,0 +1,40 @@ +======================================================================== + DYNAMIC LINK LIBRARY : KLUSolve Project Overview +======================================================================== + +AppWizard has created this KLUSolve DLL for you. +This file contains a summary of what you will find in each of the files that +make up your KLUSolve application. + + +KLUSolve.vcproj + This is the main project file for VC++ projects generated using an Application Wizard. + It contains information about the version of Visual C++ that generated the file, and + information about the platforms, configurations, and project features selected with the + Application Wizard. + +KLUSolve.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named KLUSolve.pch and a precompiled types file named StdAfx.obj. + +///////////////////////////////////////////////////////////////////////////// +Other notes: + +AppWizard uses "TODO:" comments to indicate parts of the source code you +should add to or customize. + +///////////////////////////////////////////////////////////////////////////// diff --git a/OpenDSSC/klusolve/KLUSolve/Source/KLUSolve.cpp b/OpenDSSC/klusolve/KLUSolve/Source/KLUSolve.cpp new file mode 100644 index 0000000..b96ea16 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Source/KLUSolve.cpp @@ -0,0 +1,369 @@ +/* ------------------------------------------------------------------------- */ +/* KLUSolve, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ + +// KLUSolve.cpp : Defines the entry point for the DLL application. +// + +//#include "stdafx.h" +#include +#include +#include + +#include "klusolve.h" +#include "klusystem.h" + +#define SYMMETRIC_MATRIX + +static FILE *lfp = NULL; + +static void write_lfp (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + + if (lfp) { + vfprintf (lfp, fmt, args); + fflush (lfp); + } + + va_end (args); +} + +// iAction = 0 to close, 1 to rewrite, 2 to append +unsigned int KLUSOLVE_CONVENTION SetLogFile (const char *path, unsigned int iAction) +{ + unsigned int rc = 1; + if (iAction == 0) { + if (lfp) fclose (lfp); + } else if (iAction == 1) { + if (lfp) fclose (lfp); + lfp = fopen (path, "w"); + if (!lfp) rc = 0; + } else if (iAction == 2) { + if (lfp) fclose (lfp); + lfp = fopen (path, "a"); + if (!lfp) rc = 0; + } else { + rc = 0; + } + return rc; +} +/* +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + break; + case DLL_PROCESS_DETACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + return TRUE; +} +*/ +// exported function definitions + +klusparseset_t KLUSOLVE_CONVENTION NewSparseSet (unsigned int nBus) +{ + klusparseset_t rc = 0; + + write_lfp ("NewSparseSet %u\n", nBus); + + KLUSystem *pSys = new KLUSystem (); + if (pSys) { + pSys->Initialize(nBus, 0, nBus); + rc = static_cast (pSys); + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION ZeroSparseSet (klusparseset_t hSparse) +{ + unsigned int rc = 0; + + write_lfp ("ZeroSparseSet\n"); + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + pSys->zero(); + pSys->bFactored = false; + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION FactorSparseMatrix (klusparseset_t hSparse) +{ + unsigned int rc = 0; + + write_lfp ("FactorSparseMatrix\n"); + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + if (pSys->FactorSystem() == 0) { // success + rc = 1; + } else { // singular + rc = 2; + } + } + return rc; +} + +/* + input: current injections in zero-based _acxB + output: node voltages in zero-based _acxX + no provision for voltage sources +*/ +unsigned int KLUSOLVE_CONVENTION SolveSparseSet(klusparseset_t hSparse, complex *_acxX, complex *_acxB) +{ + unsigned int rc = 0; + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + if (pSys->bFactored == false) { + pSys->FactorSystem(); + } + if (pSys->bFactored) { + pSys->SolveSystem (_acxX, _acxB); + rc = 1; + } else { + rc = 2; + } + } + write_lfp ("SolveSparseSet returning %u\n", rc); + + return rc; +} + +unsigned int KLUSOLVE_CONVENTION DeleteSparseSet(klusparseset_t hSparse) +{ + unsigned int rc = 0; + + write_lfp ("DeleteSparseSet %u\n", hSparse); + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + delete pSys; + rc = 1; + } + + return rc; +} + +/* i and j are 1-based for these */ +unsigned int KLUSOLVE_CONVENTION AddMatrixElement(klusparseset_t hSparse, unsigned int i, unsigned int j, complex *pcxVal) +{ + unsigned int rc = 0; + + write_lfp ("AddMatrixElement [%u,%u] = %G + j%G\n", i, j, pcxVal->x, pcxVal->y); + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + pSys->AddElement (i, j, *pcxVal, 1); +#ifdef SYMMETRIC_MATRIX + if (i != j) pSys->AddElement (j, i, *pcxVal, 1); +#endif + pSys->bFactored = false; + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetMatrixElement(klusparseset_t hSparse, unsigned int i, unsigned int j, complex *pcxVal) +{ + unsigned int rc = 0; + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + pSys->GetElement (i, j, *pcxVal); + rc = 1; + } + return rc; +} + +// Fills the cell specified with the given value, no adding involved +KLUSOLVE_DLL unsigned int KLUSOLVE_CONVENTION SetMatrixElement(klusparseset_t hSparse, unsigned int i, unsigned int j, complex* pcxVal) +{ + unsigned int rc = 0; + + write_lfp("SetMatrixElement [%u,%u] = %G + j%G\n", i, j, pcxVal->x, pcxVal->y); + + KLUSystem* pSys = static_cast (hSparse); + if (pSys) + { + pSys->AddElement(i, j, *pcxVal, 1); + pSys->bFactored = false; + rc = 1; + } + return rc; +} + +// new functions +unsigned int KLUSOLVE_CONVENTION GetSize (klusparseset_t hSparse, unsigned int *pResult) +{ + unsigned int rc = 0; + *pResult = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetSize(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetNNZ (klusparseset_t hSparse, unsigned int *pResult) +{ + unsigned int rc = 0; + *pResult = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetNNZ(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetSparseNNZ (klusparseset_t hSparse, unsigned int *pResult) +{ + unsigned int rc = 0; + *pResult = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetSparseNNZ(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetRCond (klusparseset_t hSparse, double *pResult) +{ + unsigned int rc = 0; + *pResult = 0.0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetRCond(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetRGrowth (klusparseset_t hSparse, double *pResult) +{ + unsigned int rc = 0; + *pResult = 0.0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetRGrowth(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetCondEst (klusparseset_t hSparse, double *pResult) +{ + unsigned int rc = 0; + *pResult = 0.0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetCondEst(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetFlops (klusparseset_t hSparse, double *pResult) +{ + unsigned int rc = 0; + *pResult = 0.0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetFlops(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetSingularCol (klusparseset_t hSparse, unsigned int *pResult) +{ + unsigned int rc = 0; + *pResult = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + *pResult = pSys->GetSingularCol(); + rc = 1; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION AddPrimitiveMatrix (klusparseset_t hSparse, unsigned int nOrder, + unsigned int *pNodes, complex *pcY) +{ + unsigned int rc = 0; + + if (lfp) { + write_lfp ("AddPrimitiveMatrix, nOrder = %u\n", nOrder); + for (unsigned i = 0; i < nOrder; i++) { + unsigned idx = i; + for (unsigned j = 0; j < nOrder; j++) { + write_lfp ("\tLocal [%u,%u] System [%u,%u] Val(%u) = %G + j%G\n", + i, j, pNodes[i], pNodes[j], idx, pcY[idx].x, pcY[idx].y); + idx += nOrder; + } + } + } + + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + rc = pSys->AddPrimitiveMatrix (nOrder, pNodes, pcY); + pSys->bFactored = false; + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetCompressedMatrix (klusparseset_t hSparse, unsigned int nColP, unsigned int nNZ, + unsigned int *pColP, unsigned int *pRowIdx, complex *pcY) +{ + unsigned int rc = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + if (pSys->GetCompressedMatrix (nColP, nNZ, pColP, pRowIdx, pcY)) { + rc = 1; + } else { // probably a size mismatch + rc = 2; + } + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION GetTripletMatrix (klusparseset_t hSparse, unsigned int nNZ, + unsigned int *pRows, unsigned int *pCols, complex *pcY) +{ + unsigned int rc = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys) { + if (pSys->GetTripletMatrix (nNZ, pRows, pCols, pcY)) { + rc = 1; + } else { // probably a size mismatch + rc = 2; + } + } + return rc; +} + +unsigned int KLUSOLVE_CONVENTION FindIslands (klusparseset_t hSparse, unsigned int nOrder, unsigned int *pNodes) +{ + unsigned int rc = 0; + KLUSystem *pSys = static_cast (hSparse); + if (pSys && nOrder >= pSys->GetSize()) { + rc = pSys->FindIslands (pNodes); + } + return rc; +} diff --git a/OpenDSSC/klusolve/KLUSolve/Source/KLUSystem.cpp b/OpenDSSC/klusolve/KLUSolve/Source/KLUSystem.cpp new file mode 100644 index 0000000..5303207 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/Source/KLUSystem.cpp @@ -0,0 +1,523 @@ +/* ------------------------------------------------------------------------- */ +/* KLUSolve, Copyright (c) 2008, EnerNex Corporation. All rights reserved. */ +/* Licensed under the GNU Lesser General Public License (LGPL) v 2.1 */ +/* ------------------------------------------------------------------------- */ + +//#include "stdafx.h" +#include +#include + +#include "klusolve.h" +#include "klusystem.h" + +complex czero = {0.0, 0.0}; +static klu_common Common; +static int common_init = 0; + +KLUSystem::KLUSystem() +{ + InitDefaults (); +} + +KLUSystem::KLUSystem (unsigned nBus, unsigned nV, unsigned nI) +{ + InitDefaults (); + Initialize (nBus, nV, nI); +} + +KLUSystem::~KLUSystem() +{ + clear (); +} + +void KLUSystem::zero_indices () +{ + m_nBus = m_nX = 0; + m_NZpre = m_NZpost = 0; + m_fltBus = 0; +} + +void KLUSystem::null_pointers () +{ + Y22 = NULL; + T22 = NULL; + Numeric = NULL; + Symbolic = NULL; + acx = NULL; +} + +void KLUSystem::InitDefaults () +{ + m_nBus = 0; + bFactored = false; + acx = NULL; + zero_indices (); + null_pointers (); + if (!common_init) { + klu_defaults (&Common); + Common.halt_if_singular = 0; + common_init = 1; + } +} + +void KLUSystem::clear() +{ + if (Y22) cs_spfree (Y22); + + if (T22) cs_spfree (T22); + + if (acx) delete [] acx; + + if (Numeric) klu_z_free_numeric (&Numeric, &Common); + if (Symbolic) klu_free_symbolic (&Symbolic, &Common); + + zero_indices (); + null_pointers (); +} + +int KLUSystem::Initialize (unsigned nBus, unsigned nV, unsigned nI) +{ + clear (); + + m_nBus = m_nX = nBus; + + if (m_nX > 0) { + T22 = csz_spalloc (m_nX, m_nX, 2 * m_nX, 1, 1); + } + if (acx) delete [] acx; + acx = new complex [m_nBus + 1]; + return 0; +} + +int KLUSystem::FactorSystem() +{ + bFactored = false; + + int rc = Factor(); + + if (rc == 1) { + bFactored = true; + return 0; + } + return 1; +} + +int KLUSystem::SolveSystem (complex *_acxX, complex *_acxB) +{ + int rc = 0; + unsigned i; + + acx[0] = czero; + for (i = 0; i < m_nBus; i++) { + acx[i+1] = _acxB[i]; + } + + Solve (acx); + + for (i = 0; i < m_nBus; i++) { + _acxX[i] = acx[i+1]; + } + + return rc; +} + +unsigned KLUSystem::AddPrimitiveMatrix (unsigned nOrder, unsigned *pNodes, complex *pMat) +{ + unsigned i, j, idRow, idCol, idVal; + double re, im; + + // check the node numbers + for (i = 0; i < nOrder; i++) { + if (pNodes[i] > m_nBus) return 0; + } + + // add the matrix transposed + for (i = 0; i < nOrder; i++) { + if (pNodes[i] < 1) continue; // skip ground + idVal = i; + idRow = pNodes[i] - 1; // convert to zero-based + for (j = 0; j < nOrder; j++) { + if (pNodes[j]) { + idCol = pNodes[j] - 1; + re = pMat[idVal].x; + im = pMat[idVal].y; + if (re != 0.0 || im != 0.0) { + // stuff this value into the correct partition, transposed + csz_entry (T22, idCol, idRow, re, im); + } + } + // always step through values, even if we don't use them + idVal += nOrder; + } + } + return 1; +} + +void KLUSystem::AddMatrix (unsigned *aidBus, matrix_complex *pcxm, int) +{ + unsigned i, j; + unsigned idRow, idCol; + unsigned nDim = pcxm->nRow; + complex val; + double re, im; + + // add the full primitive matrix, transposed, since csz_compress called later + // bus id 0 is reference node, but KLU indices are zero-based + for (i = 0; i < nDim; i++) { + idRow = aidBus[i]; + if (idRow < 1) continue; + --idRow; + for (j = 0; j < nDim; j++) { + idCol = aidBus[j]; + if (idCol < 1) continue; + --idCol; + val = pcxm->get_acx (i, j); + re = val.x; + im = val.y; + if (re == 0.0 && im == 0.0) { + continue; + } + + // stuff this value into the correct partition, transposed + csz_entry (T22, idCol, idRow, re, im); + } + } +} + +cs *KLUSystem::process_triplet (cs **T) +{ + cs *C, *A = NULL; + + if (!*T) return NULL; + + if ((*T)->nz > 0) { +// csz_print (*T, 0); + C = csz_compress (*T); + csz_dupl (C); + csz_dropzeros (C); + A = csz_transpose (C, 1); + cs_spfree (C); + m_NZpre += A->p[A->n]; +// csz_print (A, 0); + } + + cs_spfree (*T); + *T = NULL; + return A; +} + +void KLUSystem::compress_partitions () +{ + Y22 = process_triplet (&T22); +} + +int KLUSystem::Factor() +{ + // first convert the triplets to column-compressed form, and prep the columns + if (T22) { + compress_partitions (); + } else { // otherwise, compression and factoring has already been done + if (m_fltBus) return -1; // was found singular before + return 1; // was found okay before + } + + // then factor Y22 + if (Numeric) klu_z_free_numeric (&Numeric, &Common); + if (Symbolic) klu_free_symbolic (&Symbolic, &Common); + Numeric = NULL; + Symbolic = NULL; + + if (Y22) { + Symbolic = klu_analyze (Y22->n, Y22->p, Y22->i, &Common); + Numeric = klu_z_factor (Y22->p, Y22->i, Y22->x, Symbolic, &Common); + m_fltBus = Common.singular_col; + if (Common.singular_col < Y22->n) { + ++m_fltBus; // for 1-based NexHarm row numbers + m_fltBus += 0; // skip over the voltage source buses + } else { + m_fltBus = 0; // no singular submatrix was found + } + if (Common.status == KLU_OK) { + // compute size of the factorization + m_NZpost += (Numeric->lnz + Numeric->unz - Numeric->n + + ((Numeric->Offp) ? (Numeric->Offp [Numeric->n]) : 0)); + return 1; + } else if (Common.status == KLU_SINGULAR) { + return -1; + } else { // KLU_OUT_OF_MEMORY, KLU_INVALID, or KLU_TOO_LARGE + if (!m_fltBus) { + m_fltBus = 1; // this is the flag for unsuccessful factorization + } + return 0; + } + } + + return 1; +} + +void KLUSystem::Solve (complex *acxVbus) +{ + double *rhs = NULL; + unsigned i, i1, offset; + + if (m_nX < 1) return; // nothing to do + + // load current injections into RHS + rhs = (double *) cs_malloc (2 * m_nX, sizeof (double)); + offset = 1; + for (i = 0; i < m_nX; i++) { + i1 = 2 * i; + rhs[i1] = acxVbus[i+offset].x; + rhs[i1+1] = acxVbus[i+offset].y; + } + + // solve and copy voltages into the output vector + // relying on Y22->n == m_nX from T22 creation by csz_spalloc + klu_z_solve (Symbolic, Numeric, Y22->n, 1, rhs, &Common); + + offset = 1; + for (i = 0; i < m_nX; i++) { + i1 = 2 * i; + acxVbus[i+offset].x = rhs[i1]; + acxVbus[i+offset].y = rhs[i1+1]; + } + + cs_free (rhs); +} + +double KLUSystem::GetRCond () +{ + klu_z_rcond (Symbolic, Numeric, &Common); + return Common.rcond; +} + +double KLUSystem::GetRGrowth () +{ + if (Y22 == NULL) return 0.0; + klu_z_rgrowth (Y22->p, Y22->i, Y22->x, Symbolic, Numeric, &Common); + return Common.rgrowth; +} + +double KLUSystem::GetCondEst () +{ + if (Y22 == NULL) return 0.0; + if (Y22->n > 1) klu_z_condest (Y22->p, Y22->x, Symbolic, Numeric, &Common); + return Common.condest; +} + +double KLUSystem::GetFlops () +{ + klu_z_flops (Symbolic, Numeric, &Common); + return Common.flops; +} + +unsigned int KLUSystem::FindDisconnectedSubnetwork() +{ + Factor (); + + return m_fltBus; +} + +static void augment_column (int *Ai, cs *y, unsigned j, int offset, unsigned *p, int *count) +{ + int *yp = y->p; + int *yi = y->i; + int k; + + for (k = yp[j]; k < yp[j+1]; k++) { + Ai[*p] = yi[k] + offset; + *count += 1; + *p += 1; + } +} + +// stack-based DFS from Sedgewick +static int *stack = NULL; +static int stk_p = 0; +static void push (int v) {stack[stk_p++] = v;} +static int pop () {return stack[--stk_p];} +static void stackfree () {cs_free (stack);} +static int stackempty () {return !stk_p;} +static void stackinit (int size) +{ + stackfree (); + stack = (int *) cs_malloc (size + 1, sizeof (int)); + stk_p = 0; +} + +static void mark_dfs (unsigned j, int cnt, int *Ap, int *Ai, int *clique) +{ + int i, k; + + push (j); + while (!stackempty()) { + j = pop(); + clique[j] = cnt; + for (k = Ap[j]; k < Ap[j+1]; k++) { + i = Ai[k]; + if (clique[i] == 0) { + push (i); + clique[i] = -1; // to only push once + } + } + } +} + +// The KLU factorization might have some information about cliques in Y22 only, +// but we want to consider the whole system, so this function +// performs a new DFS on the compressed non-zero pattern +// This function could behave differently than before, +// since the compression process removes numerical zero elements +unsigned int KLUSystem::FindIslands(unsigned int *idClique) +{ + Factor (); + + int *clique = (int *) cs_malloc (m_nBus, sizeof (int)); + int *Ap = Y22->p; + int *Ai = Y22->i; + unsigned j; + + // DFS down the columns + int cnt = 0; + for (j = 0; j < m_nBus; j++) clique[j] = cnt; // use to mark the nodes with clique # + stackinit (m_nBus); + for (j = 0; j < m_nBus; j++) { + if (clique[j] == 0) { // have not visited this column yet + ++cnt; + mark_dfs (j, cnt, Ap, Ai, clique); + } + } + + for (j = 0; j < m_nBus; j++) idClique[j] = clique[j]; + + // if there is more than one clique, stuff the row numbers (+1) into island lists + // unsigned i, p; + /* used to return allocated lists of nodes in each island + if (cnt > 1) { + *paaidBus = new unsigned * [cnt]; + unsigned **aaidBus = *paaidBus; + + for (i = 0; i < cnt; i++) { + p = 0; + for (j = 0; j < m_nBus; j++) { // count nodes in this clique + if (clique[j] == i+1) ++p; + } + aaidBus[i] = new unsigned [p + 1]; + aaidBus[i][0] = p; + p = 1; + for (j = 0; j < m_nBus; j++) { + if (clique[j] == i+1) { + aaidBus[i][p++] = j + 1; + } + } + } + } else { + paaidBus = NULL; + } + */ + + cs_free (clique); + + return cnt; +} + + +// added for ESolv32 +void KLUSystem::zero() +{ + Initialize (m_nBus, 0, m_nBus); +} + +void KLUSystem::AddElement (unsigned iRow, unsigned iCol, complex &cpxVal, + int bSum) // bSum ignored +{ + if (iRow > m_nBus || iCol > m_nBus) return; + if (iRow <= 0 || iCol <= 0) return; + --iRow; + --iCol; + + double re = cpxVal.x; + double im = cpxVal.y; + + if (re == 0.0 && im == 0.0) { + return; + } + + // stuff this value into the correct partition, transposed + csz_entry (T22, iCol, iRow, re, im); +} + +void KLUSystem::GetElement (unsigned iRow, unsigned iCol, complex &cpxVal) +{ + cpxVal = czero; + if (iRow > m_nBus || iCol > m_nBus) return; + if (--iRow < 0) return; + if (--iCol < 0) return; + + double *Ax; + int *Ap, *Ai; + int i, p; + + if (T22) { // have to search the triplet storage, which is not sorted + Ax = T22->x; + Ap = T22->p; + Ai = T22->i; + for (i = 0; i < T22->nz; i++) { + if (Ap[i] == iCol && Ai[i] == iRow) { + cpxVal.x += Ax[2*i]; + cpxVal.y += Ax[2*i + 1]; + } + } + } else if (Y22) { // faster, duplicates already summed and elements are sorted + Ax = Y22->x; + Ap = Y22->p; + Ai = Y22->i; + for (p = Ap[iCol]; p < Ap[iCol+1]; ++p) { + if (Ai[p] == iRow) { + cpxVal.x = Ax[2*p]; + cpxVal.y = Ax[2*p + 1]; + return; + } + } + } +} + +// return in compressed column form, return m_NZpre for success, 0 for a failure +unsigned KLUSystem::GetCompressedMatrix (unsigned nColP, unsigned nNZ, unsigned *pColP, unsigned *pRowIdx, complex *pMat) +{ + unsigned int rc = 0; + + if (T22) Factor(); + if (Y22 && nNZ >= m_NZpre && nColP > m_nBus) { + rc = m_NZpre; + if (rc > 0) { + memcpy (pMat, Y22->x, m_NZpre * sizeof (complex)); + memcpy (pColP, Y22->p, (m_nBus + 1) * sizeof (unsigned)); + memcpy (pRowIdx, Y22->i, m_NZpre * sizeof (unsigned)); + } + } + return rc; +} + +unsigned KLUSystem::GetTripletMatrix (unsigned nNZ, unsigned *pRows, unsigned *pCols, complex *pMat) +{ + unsigned int rc = 0; + + if (T22) Factor(); + if (Y22 && nNZ >= m_NZpre) { + rc = m_NZpre; + if (rc > 0) { + memcpy (pMat, Y22->x, m_NZpre * sizeof (complex)); + int *Ap = Y22->p; + int *Ai = Y22->i; + for (unsigned j = 0; j < m_nBus; j++) { + for (int p = Ap[j]; p < Ap[j+1]; p++) { + pRows[p] = Ai[p]; + pCols[p] = j; + } + } + } + } + return rc; +} + diff --git a/OpenDSSC/klusolve/KLUSolve/klusolve.def b/OpenDSSC/klusolve/KLUSolve/klusolve.def new file mode 100644 index 0000000..893f381 --- /dev/null +++ b/OpenDSSC/klusolve/KLUSolve/klusolve.def @@ -0,0 +1,26 @@ +; klusolve.def : Declares the module parameters for the DLL. + +LIBRARY "KLUSolve" + +EXPORTS + ; Explicit exports can go here + NewSparseSet @1 + GetFlops @2 + ZeroSparseSet @3 + FactorSparseMatrix @4 + SolveSparseSet @5 + DeleteSparseSet @6 + AddMatrixElement @7 + GetSize @8 + SetLogFile @9 + GetNNZ @10 + GetSparseNNZ @11 + GetSingularCol @12 + GetRCond @13 + GetRGrowth @14 + GetCondEst @15 + GetMatrixElement @16 + AddPrimitiveMatrix @17 + GetCompressedMatrix @18 + GetTripletMatrix @19 + FindIslands @20 \ No newline at end of file diff --git a/OpenDSSC/klusolve/License.txt b/OpenDSSC/klusolve/License.txt new file mode 100644 index 0000000..3a0da2e --- /dev/null +++ b/OpenDSSC/klusolve/License.txt @@ -0,0 +1,19 @@ +KLUSolve 1.0, Copyright (c) 2008, EnerNex Corporation +All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, +Boston, MA 02110-1301 USA + + diff --git a/OpenDSSC/klusolve/Makefile b/OpenDSSC/klusolve/Makefile new file mode 100644 index 0000000..1872f36 --- /dev/null +++ b/OpenDSSC/klusolve/Makefile @@ -0,0 +1,84 @@ +#------------------------------------------------------------------------------- +# Makefile for all KLUSolve packages +#------------------------------------------------------------------------------- + +include UFconfig/UFconfig.mk + +# Compile the default rules for each package +default: + - ( cd UFconfig/xerbla && $(MAKE) ) + - ( cd UFconfig && $(MAKE) ) +# - ( cd metis-4.0 && $(MAKE) ) + - ( cd AMD && $(MAKE) ) + - ( cd COLAMD && $(MAKE) ) + - ( cd BTF && $(MAKE) ) + - ( cd KLU && $(MAKE) ) + - ( cd CSparse && $(MAKE) ) + - ( cd CZSparse && $(MAKE) ) + - ( cd KLUSolve && $(MAKE) ) + +# install all packages in /usr/local/lib and /usr/local/include +install: + - ( cd UFconfig && $(MAKE) install ) + - ( cd AMD && $(MAKE) install ) + - ( cd COLAMD && $(MAKE) install ) + - ( cd BTF && $(MAKE) install ) + - ( cd KLU && $(MAKE) install ) + - ( cd CZSparse && $(MAKE) install ) + - ( cd KLUSolve && $(MAKE) install ) + +# uninstall all packages +uninstall: + - ( cd UFconfig && $(MAKE) uninstall ) + - ( cd AMD && $(MAKE) uninstall ) + - ( cd COLAMD && $(MAKE) uninstall ) + - ( cd BTF && $(MAKE) uninstall ) + - ( cd KLU && $(MAKE) uninstall ) + - ( cd CZSparse && $(MAKE) uninstall ) + - ( cd KLUSolve && $(MAKE) uninstall ) + +library: + - ( cd UFconfig/xerbla && $(MAKE) ) + - ( cd UFconfig && $(MAKE) ) +# - ( cd metis-4.0 && $(MAKE) ) + - ( cd AMD && $(MAKE) library ) + - ( cd BTF && $(MAKE) library ) + - ( cd COLAMD && $(MAKE) library ) + - ( cd KLU && $(MAKE) library ) + - ( cd CSparse && $(MAKE) library ) + - ( cd CZSparse && $(MAKE) library ) + - ( cd KLUSolve && $(MAKE) library ) + +# Remove all files not in the original distribution +purge: + - ( cd UFconfig/xerbla && $(MAKE) purge ) + - ( cd UFconfig && $(MAKE) purge ) +# - ( cd metis-4.0 && $(MAKE) realclean ) + - ( cd AMD && $(MAKE) purge ) + - ( cd COLAMD && $(MAKE) purge ) + - ( cd BTF && $(MAKE) purge ) + - ( cd KLU && $(MAKE) purge ) + - ( cd CSparse && $(MAKE) purge ) + - ( cd CZSparse && $(MAKE) purge ) + - ( cd KLUSolve && $(MAKE) purge ) + +# Remove all files not in the original distribution, but keep the libraries +clean: + - ( cd UFconfig/xerbla && $(MAKE) clean ) + - ( cd UFconfig && $(MAKE) clean ) +# - ( cd metis-4.0 && $(MAKE) clean ) + - ( cd AMD && $(MAKE) clean ) + - ( cd COLAMD && $(MAKE) clean ) + - ( cd BTF && $(MAKE) clean ) + - ( cd KLU && $(MAKE) clean ) + - ( cd CSparse && $(MAKE) clean ) + - ( cd CZSparse && $(MAKE) clean ) + - ( cd KLUSolve && $(MAKE) clean ) + +distclean: purge + +# statement coverage (Linux only); this requires a lot of time. +# The umfpack tcov requires a lot of disk space +cov: + - ( cd CSparse && $(MAKE) cov ) + - ( cd KLU && $(MAKE) cov ) diff --git a/OpenDSSC/klusolve/Readme.txt b/OpenDSSC/klusolve/Readme.txt new file mode 100644 index 0000000..1e9e1c6 --- /dev/null +++ b/OpenDSSC/klusolve/Readme.txt @@ -0,0 +1,53 @@ +KLUSolve 1.0, Copyright (c) 2008, EnerNex Corporation +All rights reserved. + +KLU Version 1.0, May 31, 2007, by Timothy A. Davis and Ekanathan Palamadai. +Copyright (C) 2004-2007, University of Florida + +CSparse: a Concise Sparse Matrix package. +Version 2.2.0, Copyright (c) 2006-2007, Timothy A. Davis, Mar 31, 2007. + +AMD Version 2.2, Copyright (c) 2007 by Timothy A. +Davis, Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved. + +BTF Version 1.0, May 31, 2007, by Timothy A. Davis +Copyright (C) 2004-2007, University of Florida + +CZSparse, Copyright (c) 2008, EnerNex Corporation. All rights reserved. + +========================================================================== + +KLUSolve is a complex sparse matrix library tailored to electric power +systems, licensed under LGPL version 2.1 (see files License.txt and +lgpl_2_1.txt in this directory). For an example of use, see the OpenDSS +project at www.sourceforge.net/projects/electricdss + +Contact: Tom McDermott, tom at enernex dot com, or + + Tom McDermott + EnerNex Corporation + 90 Clairton Boulevard, Suite A + Pittsburgh, PA 15236 + 1-412-653-0407 + +========================================================================== + +KLUSolve is based on the KLU, CSparse, and supporting libraries developed +by Timothy A. Davis and his students, which are also licensed under LGPL +version 2.1. All source files used in KLUSolve are included in the +SourceForge SVN repository for KLUSolve + +Current versions: http://www.cise.ufl.edu/research/sparse + +Contact: davis at cise dot ufl dot edu, or + + Tim Davis, Professor + Room E338 CSE Building + P.O. Box 116120 + University of Florida + Gainesville, FL 32611-6120 + 1-352-392-1481 + +Reference Book: "Direct Methods for Sparse Linear Systems," Timothy A. Davis, +SIAM, Philadelphia, 2006. + diff --git a/OpenDSSC/klusolve/UFconfig/Makefile b/OpenDSSC/klusolve/UFconfig/Makefile new file mode 100644 index 0000000..cce5110 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/Makefile @@ -0,0 +1,41 @@ +#------------------------------------------------------------------------------- +# UFconfig Makefile +#------------------------------------------------------------------------------- + +VERSION = 3.7.1 + +default: ccode + +include UFconfig.mk + +ccode: libufconfig.a + +all: libufconfig.a + +libufconfig.a: UFconfig.c UFconfig.h + $(CC) $(CF) -c UFconfig.c + $(ARCHIVE) libufconfig.a UFconfig.o + $(RANLIB) libufconfig.a + - $(RM) UFconfig.o + +distclean: purge + +purge: clean + - $(RM) *.o *.a + +clean: + - $(RM) -r $(CLEAN) + +# install UFconfig +install: + $(CP) libufconfig.a $(INSTALL_LIB)/libufconfig.$(VERSION).a + ( cd $(INSTALL_LIB) ; ln -sf libufconfig.$(VERSION).a libufconfig.a ) + $(CP) UFconfig.h $(INSTALL_INCLUDE) + chmod 644 $(INSTALL_LIB)/libufconfig*.a + chmod 644 $(INSTALL_INCLUDE)/UFconfig.h + +# uninstall UFconfig +uninstall: + $(RM) $(INSTALL_LIB)/libufconfig*.a + $(RM) $(INSTALL_INCLUDE)/UFconfig.h + diff --git a/OpenDSSC/klusolve/UFconfig/README.txt b/OpenDSSC/klusolve/UFconfig/README.txt new file mode 100644 index 0000000..d9edc23 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/README.txt @@ -0,0 +1,35 @@ +UFconfig contains configuration settings for all many of the software packages +that I develop or co-author. Note that older versions of some of these packages +do not require UFconfig. + + Package Description + ------- ----------- + AMD approximate minimum degree ordering + CAMD constrained AMD + COLAMD column approximate minimum degree ordering + CCOLAMD constrained approximate minimum degree ordering + UMFPACK sparse LU factorization, with the BLAS + CXSparse int/long/real/complex version of CSparse + CHOLMOD sparse Cholesky factorization, update/downdate + KLU sparse LU factorization, BLAS-free + BTF permutation to block triangular form + LDL concise sparse LDL' + LPDASA LP Dual Active Set Algorithm + SuiteSparseQR sparse QR factorization + +UFconfig is not required by: + + CSparse a Concise Sparse matrix package + RBio read/write files in Rutherford/Boeing format + UFcollection tools for managing the UF Sparse Matrix Collection + LINFACTOR simple m-file to show how to use LU and CHOL to solve Ax=b + MESHND 2D and 3D mesh generation and nested dissection ordering + MATLAB_Tools misc collection of m-files + SSMULT sparse matrix times sparse matrix, for use in MATLAB + +In addition, the xerbla/ directory contains Fortan and C versions of the +BLAS/LAPACK xerbla routine, which is called when an invalid input is passed to +the BLAS or LAPACK. The xerbla provided here does not print any message, so +the entire Fortran I/O library does not need to be linked into a C application. +Most versions of the BLAS contain xerbla, but those from K. Goto do not. Use +this if you need too. diff --git a/OpenDSSC/klusolve/UFconfig/UFconfig.c b/OpenDSSC/klusolve/UFconfig/UFconfig.c new file mode 100644 index 0000000..8b8d45e --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/UFconfig.c @@ -0,0 +1,71 @@ +/* ========================================================================== */ +/* === UFconfig ============================================================= */ +/* ========================================================================== */ + +/* Copyright (c) 2009, University of Florida. No licensing restrictions + * apply to this file or to the UFconfig directory. Author: Timothy A. Davis. + */ + +#include "UFconfig.h" + +/* -------------------------------------------------------------------------- */ +/* UFmalloc: malloc wrapper */ +/* -------------------------------------------------------------------------- */ + +void *UFmalloc /* pointer to allocated block of memory */ +( + size_t nitems, /* number of items to malloc (>=1 is enforced) */ + size_t size_of_item, /* sizeof each item */ + int *ok, /* TRUE if successful, FALSE otherwise */ + UFconfig *config /* SuiteSparse-wide configuration */ +) +{ + void *p ; + if (nitems < 1) nitems = 1 ; + if (nitems * size_of_item != ((double) nitems) * size_of_item) + { + /* Int overflow */ + *ok = 0 ; + return (NULL) ; + } + if (!config || config->malloc_memory == NULL) + { + /* use malloc by default */ + p = (void *) malloc (nitems * size_of_item) ; + } + else + { + /* use the pointer to malloc in the config */ + p = (void *) (config->malloc_memory) (nitems * size_of_item) ; + } + *ok = (p != NULL) ; + return (p) ; +} + + +/* -------------------------------------------------------------------------- */ +/* UFfree: free wrapper */ +/* -------------------------------------------------------------------------- */ + +void *UFfree /* always returns NULL */ +( + void *p, /* block to free */ + UFconfig *config /* SuiteSparse-wide configuration */ +) +{ + if (p) + { + if (!config || config->free_memory == NULL) + { + /* use free by default */ + free (p) ; + } + else + { + /* use the pointer to free in the config */ + (config->free_memory) (p) ; + } + } + return (NULL) ; +} + diff --git a/OpenDSSC/klusolve/UFconfig/UFconfig.h b/OpenDSSC/klusolve/UFconfig/UFconfig.h new file mode 100644 index 0000000..d3aa407 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/UFconfig.h @@ -0,0 +1,151 @@ +/* ========================================================================== */ +/* === UFconfig.h =========================================================== */ +/* ========================================================================== */ + +/* Configuration file for SuiteSparse: a Suite of Sparse matrix packages + * (AMD, COLAMD, CCOLAMD, CAMD, CHOLMOD, UMFPACK, CXSparse, and others). + * + * UFconfig.h provides the definition of the long integer. On most systems, + * a C program can be compiled in LP64 mode, in which long's and pointers are + * both 64-bits, and int's are 32-bits. Windows 64, however, uses the LLP64 + * model, in which int's and long's are 32-bits, and long long's and pointers + * are 64-bits. + * + * SuiteSparse packages that include long integer versions are + * intended for the LP64 mode. However, as a workaround for Windows 64 + * (and perhaps other systems), the long integer can be redefined. + * + * If _WIN64 is defined, then the __int64 type is used instead of long. + * + * The long integer can also be defined at compile time. For example, this + * could be added to UFconfig.mk: + * + * CFLAGS = -O -D'UF_long=long long' -D'UF_long_max=9223372036854775801' \ + * -D'UF_long_idd="lld"' + * + * This file defines UF_long as either long (on all but _WIN64) or + * __int64 on Windows 64. The intent is that a UF_long is always a 64-bit + * integer in a 64-bit code. ptrdiff_t might be a better choice than long; + * it is always the same size as a pointer. + * + * This file also defines the SUITESPARSE_VERSION and related definitions. + * + * Copyright (c) 2007, University of Florida. No licensing restrictions + * apply to this file or to the UFconfig directory. Author: Timothy A. Davis. + */ + +#ifndef _UFCONFIG_H +#define _UFCONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* ========================================================================== */ +/* === UF_long ============================================================== */ +/* ========================================================================== */ + +#ifndef UF_long + +#ifdef _WIN64 + +#define UF_long __int64 +#define UF_long_max _I64_MAX +#define UF_long_idd "I64d" + +#else + +#define UF_long long +#define UF_long_max LONG_MAX +#define UF_long_idd "ld" + +#endif +#define UF_long_id "%" UF_long_idd +#endif + +/* ========================================================================== */ +/* === UFconfig parameters and functions ==================================== */ +/* ========================================================================== */ + +/* SuiteSparse-wide parameters will be placed in this struct. So far, they + are only used by RBio. */ + +typedef struct UFconfig_struct +{ + void *(*malloc_memory) (size_t) ; /* pointer to malloc */ + void *(*realloc_memory) (void *, size_t) ; /* pointer to realloc */ + void (*free_memory) (void *) ; /* pointer to free */ + void *(*calloc_memory) (size_t, size_t) ; /* pointer to calloc */ + +} UFconfig ; + +void *UFmalloc /* pointer to allocated block of memory */ +( + size_t nitems, /* number of items to malloc (>=1 is enforced) */ + size_t size_of_item, /* sizeof each item */ + int *ok, /* TRUE if successful, FALSE otherwise */ + UFconfig *config /* SuiteSparse-wide configuration */ +) ; + +void *UFfree /* always returns NULL */ +( + void *p, /* block to free */ + UFconfig *config /* SuiteSparse-wide configuration */ +) ; + + +/* ========================================================================== */ +/* === SuiteSparse version ================================================== */ +/* ========================================================================== */ + +/* SuiteSparse is not a package itself, but a collection of packages, some of + * which must be used together (UMFPACK requires AMD, CHOLMOD requires AMD, + * COLAMD, CAMD, and CCOLAMD, etc). A version number is provided here for the + * collection itself. The versions of packages within each version of + * SuiteSparse are meant to work together. Combining one packge from one + * version of SuiteSparse, with another package from another version of + * SuiteSparse, may or may not work. + * + * SuiteSparse Version 3.7.1 contains the following packages: + * + * UFconfig version 3.7.1 (version always the same as SuiteSparse) + * AMD version 2.2.4 + * CAMD version 2.2.4 + * CCOLAMD version 2.7.4 + * COLAMD version 2.7.4 + * BTF version 1.1.3 + * CHOLMOD version 1.7.4 + * CSparse3 version 3.0.2 + * CSparse version 2.2.6 + * CXSparse version 2.2.6 + * KLU version 1.1.4 + * LDL version 2.0.4 + * RBio version 2.0.2 + * SPQR version 1.2.3 (also called SuiteSparseQR) + * UFcollection version 1.6.1 + * UMFPACK version 5.5.2 + * SSMULT version 2.0.3 + * spqr_rank version 1.0.0 + * MATLAB_Tools various packages & M-files. No specific version number. + * + * Other package dependencies: + * BLAS required by CHOLMOD and UMFPACK + * LAPACK required by CHOLMOD + * METIS 4.0.1 required by CHOLMOD (optional) and KLU (optional) + */ + +#define SUITESPARSE_DATE "May 15, 2012" +#define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) +#define SUITESPARSE_MAIN_VERSION 3 +#define SUITESPARSE_SUB_VERSION 7 +#define SUITESPARSE_SUBSUB_VERSION 1 +#define SUITESPARSE_VERSION \ + SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/OpenDSSC/klusolve/UFconfig/UFconfig.mk b/OpenDSSC/klusolve/UFconfig/UFconfig.mk new file mode 100644 index 0000000..e417a22 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/UFconfig.mk @@ -0,0 +1,408 @@ +#=============================================================================== +# UFconfig.mk: common configuration file for the SuiteSparse +#=============================================================================== + +# This file contains all configuration settings for all packages authored or +# co-authored by Tim Davis at the University of Florida: +# +# Package Version Description +# ------- ------- ----------- +# AMD 1.2 or later approximate minimum degree ordering +# COLAMD 2.4 or later column approximate minimum degree ordering +# CCOLAMD 1.0 or later constrained column approximate minimum degree ordering +# CAMD any constrained approximate minimum degree ordering +# UMFPACK 4.5 or later sparse LU factorization, with the BLAS +# CHOLMOD any sparse Cholesky factorization, update/downdate +# KLU 0.8 or later sparse LU factorization, BLAS-free +# BTF 0.8 or later permutation to block triangular form +# LDL 1.2 or later concise sparse LDL' +# LPDASA any linear program solve (dual active set algorithm) +# CXSparse any extended version of CSparse (int/long, real/complex) +# SuiteSparseQR any sparse QR factorization +# +# By design, this file is NOT included in the CSparse / CSparse3 makefiles. +# Those packages are fully stand-alone. +# +# The UFconfig directory and the above packages should all appear in a single +# directory, in order for the Makefile's within each package to find this file. +# +# To enable an option of the form "# OPTION = ...", edit this file and +# delete the "#" in the first column of the option you wish to use. +# +# The use of METIS 4.0.1 is optional. To exclude METIS, you must compile with +# CHOLMOD_CONFIG set to -DNPARTITION. See below for details. + +#------------------------------------------------------------------------------ +# Generic configuration +#------------------------------------------------------------------------------ + +# Using standard definitions from the make environment, typically: +# +# CC cc C compiler +# CXX g++ C++ compiler +# CFLAGS [ ] flags for C and C++ compiler +# CPPFLAGS [ ] flags for C and C++ compiler +# TARGET_ARCH [ ] target architecture +# FFLAGS [ ] flags for Fortran compiler +# RM rm -f delete a file +# AR ar create a static *.a library archive +# ARFLAGS rv flags for ar +# MAKE make make itself (sometimes called gmake) +# +# You can redefine them here, but by default they are used from the +# default make environment. +CC = g++ +CFLAGS = -fpermissive + +# C and C++ compiler flags. The first three are standard for *.c and *.cpp +CF = $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -O3 -fexceptions -fPIC + +# ranlib, and ar, for generating libraries. If you don't need ranlib, +# just change it to RANLAB = echo +RANLIB = ranlib +ARCHIVE = $(AR) $(ARFLAGS) + +# copy, delete, and rename a file +CP = cp -f +MV = mv -f +# RM = rm -f + +# Fortran compiler (not required for 'make' or 'make library') +F77 = gfortran +F77FLAGS = $(FFLAGS) -O +F77LIB = + +# C and Fortran libraries +LIB = -lm + +# For "make install" +INSTALL_LIB = /usr/local/lib +INSTALL_INCLUDE = /usr/local/include + +# For compiling MATLAB mexFunctions (MATLAB 7.5 or later) +MEX = mex -O -largeArrayDims -lmwlapack -lmwblas + +# For compiling MATLAB mexFunctions (MATLAB 7.3 and 7.4) +# MEX = mex -O -largeArrayDims -lmwlapack + +# For MATLAB 7.2 or earlier, you must use one of these options: +# MEX = mex -O -lmwlapack +# MEX = mex -O + +# Which version of MAKE you are using (default is "make") +# MAKE = make +# MAKE = gmake + +#------------------------------------------------------------------------------ +# BLAS and LAPACK configuration: +#------------------------------------------------------------------------------ + +# UMFPACK and CHOLMOD both require the BLAS. CHOLMOD also requires LAPACK. +# See Kazushige Goto's BLAS at http://www.cs.utexas.edu/users/flame/goto/ or +# http://www.tacc.utexas.edu/~kgoto/ for the best BLAS to use with CHOLMOD. +# LAPACK is at http://www.netlib.org/lapack/ . You can use the standard +# Fortran LAPACK along with Goto's BLAS to obtain very good performance. +# CHOLMOD gets a peak numeric factorization rate of 3.6 Gflops on a 3.2 GHz +# Pentium 4 (512K cache, 4GB main memory) with the Goto BLAS, and 6 Gflops +# on a 2.5Ghz dual-core AMD Opteron. + +# These settings will probably not work, since there is no fixed convention for +# naming the BLAS and LAPACK library (*.a or *.so) files. + +# This is probably slow ... it might connect to the Standard Reference BLAS: +BLAS = -lblas -lgfortran +LAPACK = -llapack + +# NOTE: this next option for the "Goto BLAS" has nothing to do with a "goto" +# statement. Rather, the Goto BLAS is written by Dr. Kazushige Goto. +# Using the Goto BLAS: +# BLAS = -lgoto -lgfortran -lgfortranbegin + +# Using non-optimized versions: +# BLAS = -lblas_plain -lgfortran -lgfortranbegin +# LAPACK = -llapack_plain + +# BLAS = -lblas_plain -lgfortran -lgfortranbegin +# LAPACK = -llapack + +# The BLAS might not contain xerbla, an error-handling routine for LAPACK and +# the BLAS. Also, the standard xerbla requires the Fortran I/O library, and +# stops the application program if an error occurs. A C version of xerbla +# distributed with this software (UFconfig/xerbla/libcerbla.a) includes a +# Fortran-callable xerbla routine that prints nothing and does not stop the +# application program. This is optional. +# XERBLA = ../../UFconfig/xerbla/libcerbla.a + +# If you wish to use the XERBLA in LAPACK and/or the BLAS instead, +# use this option: +XERBLA = + +# If you wish to use the Fortran UFconfig/xerbla/xerbla.f instead, use this: +# XERBLA = ../../UFconfig/xerbla/libxerbla.a + +#------------------------------------------------------------------------------ +# METIS, optionally used by CHOLMOD +#------------------------------------------------------------------------------ + +# If you do not have METIS, or do not wish to use it in CHOLMOD, you must +# compile CHOLMOD with the -DNPARTITION flag. + +# The path is relative to where it is used, in CHOLMOD/Lib, CHOLMOD/MATLAB, etc. +# You may wish to use an absolute path. METIS is optional. Compile +# CHOLMOD with -DNPARTITION if you do not wish to use METIS. +METIS_PATH = ../../metis-4.0 +METIS = ../../metis-4.0/libmetis.a + +#------------------------------------------------------------------------------ +# UMFPACK configuration: +#------------------------------------------------------------------------------ + +# Configuration flags for UMFPACK. See UMFPACK/Source/umf_config.h for details. +# +# -DNBLAS do not use the BLAS. UMFPACK will be very slow. +# -D'LONGBLAS=long' or -DLONGBLAS='long long' defines the integers used by +# LAPACK and the BLAS (defaults to 'int') +# -DNSUNPERF do not use the Sun Perf. Library (default is use it on Solaris) +# -DNPOSIX do not use POSIX routines sysconf and times. +# -DGETRUSAGE use getrusage +# -DNO_TIMER do not use any timing routines +# -DNRECIPROCAL do not multiply by the reciprocal +# -DNO_DIVIDE_BY_ZERO do not divide by zero +# -DNCHOLMOD do not use CHOLMOD as a ordering method. If -DNCHOLMOD is +# included in UMFPACK_CONFIG, then UMFPACK does not rely on +# CHOLMOD, CAMD, CCOLAMD, COLAMD, and METIS. + +UMFPACK_CONFIG = + +# uncomment this line to compile UMFPACK without CHOLMOD: +# UMFPACK_CONFIG = -DNCHOLMOD + +#------------------------------------------------------------------------------ +# CHOLMOD configuration +#------------------------------------------------------------------------------ + +# CHOLMOD Library Modules, which appear in libcholmod.a: +# Core requires: none +# Check requires: Core +# Cholesky requires: Core, AMD, COLAMD. optional: Partition, Supernodal +# MatrixOps requires: Core +# Modify requires: Core +# Partition requires: Core, CCOLAMD, METIS. optional: Cholesky +# Supernodal requires: Core, BLAS, LAPACK +# +# CHOLMOD test/demo Modules (all are GNU GPL, do not appear in libcholmod.a): +# Tcov requires: Core, Check, Cholesky, MatrixOps, Modify, Supernodal +# optional: Partition +# Valgrind same as Tcov +# Demo requires: Core, Check, Cholesky, MatrixOps, Supernodal +# optional: Partition +# +# Configuration flags: +# -DNCHECK do not include the Check module. License GNU LGPL +# -DNCHOLESKY do not include the Cholesky module. License GNU LGPL +# -DNPARTITION do not include the Partition module. License GNU LGPL +# also do not include METIS. +# -DNGPL do not include any GNU GPL Modules in the CHOLMOD library: +# -DNMATRIXOPS do not include the MatrixOps module. License GNU GPL +# -DNMODIFY do not include the Modify module. License GNU GPL +# -DNSUPERNODAL do not include the Supernodal module. License GNU GPL +# +# -DNPRINT do not print anything. +# -D'LONGBLAS=long' or -DLONGBLAS='long long' defines the integers used by +# LAPACK and the BLAS (defaults to 'int') +# -DNSUNPERF for Solaris only. If defined, do not use the Sun +# Performance Library + +CHOLMOD_CONFIG = + +# uncomment this line to compile CHOLMOD without METIS: +# CHOLMOD_CONFIG = -DNPARTITION + +#------------------------------------------------------------------------------ +# SuiteSparseQR configuration: +#------------------------------------------------------------------------------ + +# The SuiteSparseQR library can be compiled with the following options: +# +# -DNPARTITION do not include the CHOLMOD partition module +# -DNEXPERT do not include the functions in SuiteSparseQR_expert.cpp +# -DTIMING enable timing and flop counts +# -DHAVE_TBB enable the use of Intel's Threading Building Blocks (TBB) + +# default, without timing, without TBB: +SPQR_CONFIG = +# with timing and TBB: +# SPQR_CONFIG = -DTIMING -DHAVE_TBB +# with timing +# SPQR_CONFIG = -DTIMING + +# This is needed for IBM AIX: (but not for and C codes, just C++) +# SPQR_CONFIG = -DBLAS_NO_UNDERSCORE + +# with TBB, you must select this: +# TBB = -ltbb +# without TBB: +TBB = + +# with timing, you must include the timing library: +# RTLIB = -lrt +# without timing +RTLIB = + +#------------------------------------------------------------------------------ +# Linux +#------------------------------------------------------------------------------ + +# Using default compilers: +# CC = gcc +# CFLAGS = -O3 -fexceptions + +# alternatives: +# CFLAGS = -g -fexceptions \ + -Wall -W -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ + -Wredundant-decls -Wnested-externs -Wdisabled-optimization -ansi \ + -funit-at-a-time +# CFLAGS = -O3 -fexceptions \ + -Wall -W -Werror -Wshadow -Wmissing-prototypes -Wstrict-prototypes \ + -Wredundant-decls -Wnested-externs -Wdisabled-optimization -ansi +# CFLAGS = -O3 -fexceptions -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE +# CFLAGS = -O3 +# CFLAGS = -O3 -g -fexceptions +# CFLAGS = -g -fexceptions \ + -Wall -W -Wshadow \ + -Wredundant-decls -Wdisabled-optimization -ansi + +# consider: +# -fforce-addr -fmove-all-movables -freduce-all-givs -ftsp-ordering +# -frename-registers -ffast-math -funroll-loops + +# Using the Goto BLAS: +# BLAS = -lgoto -lfrtbegin -lg2c $(XERBLA) -lpthread + +# Using Intel's icc and ifort compilers: +# (does not work for mexFunctions unless you add a mexopts.sh file) +# F77 = ifort +# CC = icc +# CFLAGS = -O3 -xN -vec_report=0 +# CFLAGS = -g +# old (broken): CFLAGS = -ansi -O3 -ip -tpp7 -xW -vec_report0 + +# 64bit: +# F77FLAGS = -O -m64 +# CFLAGS = -O3 -fexceptions -m64 +# BLAS = -lgoto64 -lfrtbegin -lg2c -lpthread $(XERBLA) +# LAPACK = -llapack64 + + +# SUSE Linux 10.1, AMD Opteron, with GOTO Blas +# F77 = gfortran +# BLAS = -lgoto_opteron64 -lgfortran + +# SUSE Linux 10.1, Intel Pentium, with GOTO Blas +# F77 = gfortran +# BLAS = -lgoto -lgfortran + +#------------------------------------------------------------------------------ +# Mac +#------------------------------------------------------------------------------ + +# As recommended by macports, http://suitesparse.darwinports.com/ +# I've tested them myself on Mac OSX 10.6.1 (Snow Leopard), on my MacBook Air. +# F77 = gfortran +# CFLAGS = -O3 -fno-common -no-cpp-precomp -fexceptions +# BLAS = -framework Accelerate +# LAPACK = -framework Accelerate + +# Using netlib.org LAPACK and BLAS compiled by gfortran, with and without +# optimzation: +# BLAS = -lblas_plain -lgfortran +# LAPACK = -llapack_plain +# BLAS = -lblas_optimized -lgfortran +# LAPACK = -llapack_optimized + +#------------------------------------------------------------------------------ +# Solaris +#------------------------------------------------------------------------------ + +# 32-bit +# CFLAGS = -KPIC -dalign -xc99=%none -Xc -xlibmieee -xO5 -xlibmil -m32 + +# 64-bit +# CFLAGS = -fast -KPIC -xc99=%none -xlibmieee -xlibmil -m64 -Xc + +# FFLAGS = -fast -KPIC -dalign -xlibmil -m64 + +# The Sun Performance Library includes both LAPACK and the BLAS: +# BLAS = -xlic_lib=sunperf +# LAPACK = + + +#------------------------------------------------------------------------------ +# Compaq Alpha +#------------------------------------------------------------------------------ + +# 64-bit mode only +# CFLAGS = -O2 -std1 +# BLAS = -ldxml +# LAPACK = + +#------------------------------------------------------------------------------ +# Macintosh +#------------------------------------------------------------------------------ + +# CC = gcc +# CFLAGS = -O3 -fno-common -no-cpp-precomp -fexceptions +# LIB = -lstdc++ +# BLAS = -framework Accelerate +# LAPACK = -framework Accelerate + +#------------------------------------------------------------------------------ +# IBM RS 6000 +#------------------------------------------------------------------------------ + +# BLAS = -lessl +# LAPACK = + +# 32-bit mode: +# CFLAGS = -O4 -qipa -qmaxmem=16384 -qproto +# F77FLAGS = -O4 -qipa -qmaxmem=16384 + +# 64-bit mode: +# CFLAGS = -O4 -qipa -qmaxmem=16384 -q64 -qproto +# F77FLAGS = -O4 -qipa -qmaxmem=16384 -q64 +# AR = ar -X64 + +#------------------------------------------------------------------------------ +# SGI IRIX +#------------------------------------------------------------------------------ + +# BLAS = -lscsl +# LAPACK = + +# 32-bit mode +# CFLAGS = -O + +# 64-bit mode (32 bit int's and 64-bit long's): +# CFLAGS = -64 +# F77FLAGS = -64 + +# SGI doesn't have ranlib +# RANLIB = echo + +#------------------------------------------------------------------------------ +# AMD Opteron (64 bit) +#------------------------------------------------------------------------------ + +# BLAS = -lgoto_opteron64 -lg2c +# LAPACK = -llapack_opteron64 + +# SUSE Linux 10.1, AMD Opteron +# F77 = gfortran +# BLAS = -lgoto_opteron64 -lgfortran +# LAPACK = -llapack_opteron64 + +#------------------------------------------------------------------------------ +# remove object files and profile output +#------------------------------------------------------------------------------ + +CLEAN = *.o *.obj *.ln *.bb *.bbg *.da *.tcov *.gcov gmon.out *.bak *.d *.gcda *.gcno diff --git a/OpenDSSC/klusolve/UFconfig/xerbla/Makefile b/OpenDSSC/klusolve/UFconfig/xerbla/Makefile new file mode 100644 index 0000000..efadb48 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/xerbla/Makefile @@ -0,0 +1,33 @@ +# Makefile for null-output xerbla + +default: ccode + +include ../UFconfig.mk + +ccode: libcerbla.a + +fortran: libxerbla.a + +all: libxerbla.a libcerbla.a + +# Fortran version: +libxerbla.a: xerbla.f + $(F77) $(F77FLAGS) -c xerbla.f + $(ARCHIVE) libxerbla.a xerbla.o + - $(RANLIB) libxerbla.a + - $(RM) xerbla.o + +# C version: +libcerbla.a: xerbla.c xerbla.h + $(CC) $(CF) -c xerbla.c + $(ARCHIVE) libcerbla.a xerbla.o + - $(RANLIB) libcerbla.a + - $(RM) xerbla.o + +distclean: purge + +purge: clean + - $(RM) *.o *.a + +clean: + - $(RM) $(CLEAN) diff --git a/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.c b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.c new file mode 100644 index 0000000..5107f03 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.c @@ -0,0 +1,12 @@ + +void xerbla_ (char *srname, int *info) +{ + /* do nothing */ ; +} + + +void xerbla (char *srname, int *info) +{ + /* do nothing */ ; +} + diff --git a/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.f b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.f new file mode 100644 index 0000000..4272004 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.f @@ -0,0 +1,46 @@ + SUBROUTINE XERBLA( SRNAME, INFO ) +* +* -- LAPACK auxiliary routine (version 3.0) -- +* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., +* Courant Institute, Argonne National Lab, and Rice University +* September 30, 1994 +* +* .. Scalar Arguments .. + CHARACTER*6 SRNAME + INTEGER INFO +* .. +* +* Purpose +* ======= +* +* XERBLA is an error handler for the LAPACK routines. +* It is called by an LAPACK routine if an input parameter has an +* invalid value. A message is printed and execution stops. +* +* Installers may consider modifying the STOP statement in order to +* call system-specific exception-handling facilities. +* +* Arguments +* ========= +* +* SRNAME (input) CHARACTER*6 +* The name of the routine which called XERBLA. +* +* INFO (input) INTEGER +* The position of the invalid parameter in the parameter list +* of the calling routine. +* +* ===================================================================== +* +* .. Executable Statements .. +* +***** WRITE( *, FMT = 9999 )SRNAME, INFO +* +***** STOP +* +***** 9999 FORMAT( ' ** On entry to ', A6, ' parameter number ', I2, ' had ', +***** $ 'an illegal value' ) +* +* End of XERBLA +* + END diff --git a/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.h b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.h new file mode 100644 index 0000000..b332eb3 --- /dev/null +++ b/OpenDSSC/klusolve/UFconfig/xerbla/xerbla.h @@ -0,0 +1,2 @@ +void xerbla_ (char *srname, int *info) ; +void xerbla (char *srname, int *info) ; diff --git a/OpenDSSC/klusolve/lgpl_2_1.txt b/OpenDSSC/klusolve/lgpl_2_1.txt new file mode 100644 index 0000000..5ab7695 --- /dev/null +++ b/OpenDSSC/klusolve/lgpl_2_1.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + +